Branch and tag freedv 1.2.2 and codec2 0.7.
authorhobbes1069 <hobbes1069@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 18 Jul 2017 14:11:40 +0000 (14:11 +0000)
committerhobbes1069 <hobbes1069@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 18 Jul 2017 14:11:40 +0000 (14:11 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3307 01035d8c-6547-0410-b346-abe4f91aad63

1033 files changed:
codec2-dev/CMakeLists.txt
codec2/branches/0.7/CMakeLists.txt [new file with mode: 0644]
codec2/branches/0.7/COPYING [new file with mode: 0644]
codec2/branches/0.7/INSTALL [new file with mode: 0644]
codec2/branches/0.7/README [new file with mode: 0644]
codec2/branches/0.7/README_fdmdv.txt [new file with mode: 0644]
codec2/branches/0.7/README_fsk.txt [new file with mode: 0644]
codec2/branches/0.7/cmake/GetDependencies.cmake.in [new file with mode: 0644]
codec2/branches/0.7/cmake/config.h.in [new file with mode: 0644]
codec2/branches/0.7/codec2.pc.in [new file with mode: 0644]
codec2/branches/0.7/debian/changelog [new file with mode: 0644]
codec2/branches/0.7/debian/codec2.doc-base.EX [new file with mode: 0644]
codec2/branches/0.7/debian/codec2.install [new file with mode: 0644]
codec2/branches/0.7/debian/codec21.dirs [new file with mode: 0644]
codec2/branches/0.7/debian/codec21.install [new file with mode: 0644]
codec2/branches/0.7/debian/compat [new file with mode: 0644]
codec2/branches/0.7/debian/control [new file with mode: 0644]
codec2/branches/0.7/debian/copyright [new file with mode: 0644]
codec2/branches/0.7/debian/docs [new file with mode: 0644]
codec2/branches/0.7/debian/libcodec2-dev.dirs [new file with mode: 0644]
codec2/branches/0.7/debian/libcodec2-dev.install [new file with mode: 0644]
codec2/branches/0.7/debian/libcodec2.install [new file with mode: 0644]
codec2/branches/0.7/debian/rules [new file with mode: 0755]
codec2/branches/0.7/debian/source/format [new file with mode: 0644]
codec2/branches/0.7/octave/2400ab_frame_design.ods [new file with mode: 0644]
codec2/branches/0.7/octave/H2064_516_sparse.mat [new file with mode: 0644]
codec2/branches/0.7/octave/HRA_112_112.txt [new file with mode: 0644]
codec2/branches/0.7/octave/HRA_112_56.txt [new file with mode: 0644]
codec2/branches/0.7/octave/HRA_56_28.txt [new file with mode: 0644]
codec2/branches/0.7/octave/HRA_56_56.txt [new file with mode: 0644]
codec2/branches/0.7/octave/Mat2Hrows.m [new file with mode: 0644]
codec2/branches/0.7/octave/adc_plot_spec.m [new file with mode: 0755]
codec2/branches/0.7/octave/adc_sfdr_ut.m [new file with mode: 0644]
codec2/branches/0.7/octave/adcres.m [new file with mode: 0644]
codec2/branches/0.7/octave/autotest.m [new file with mode: 0644]
codec2/branches/0.7/octave/av_imp.m [new file with mode: 0644]
codec2/branches/0.7/octave/bandpasssampling.m [new file with mode: 0644]
codec2/branches/0.7/octave/bfq19ssa.m [new file with mode: 0644]
codec2/branches/0.7/octave/bpf.m [new file with mode: 0644]
codec2/branches/0.7/octave/bpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/c2wideband_batch.m [new file with mode: 0644]
codec2/branches/0.7/octave/c2wideband_const.m [new file with mode: 0644]
codec2/branches/0.7/octave/c2wideband_fbf.m [new file with mode: 0644]
codec2/branches/0.7/octave/cbphase.m [new file with mode: 0644]
codec2/branches/0.7/octave/cellmodem.m [new file with mode: 0644]
codec2/branches/0.7/octave/ciccomp.m [new file with mode: 0644]
codec2/branches/0.7/octave/cma.m [new file with mode: 0644]
codec2/branches/0.7/octave/cml.patch [new file with mode: 0644]
codec2/branches/0.7/octave/codec2_demo.m [new file with mode: 0644]
codec2/branches/0.7/octave/cohpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/cohpsk_demod_plot.m [new file with mode: 0644]
codec2/branches/0.7/octave/cohpsk_frame_design.ods [new file with mode: 0644]
codec2/branches/0.7/octave/cohpsk_plots.m [new file with mode: 0644]
codec2/branches/0.7/octave/crc16.m [new file with mode: 0644]
codec2/branches/0.7/octave/cspec.m [new file with mode: 0644]
codec2/branches/0.7/octave/dacres.m [new file with mode: 0644]
codec2/branches/0.7/octave/df_mixer.m [new file with mode: 0644]
codec2/branches/0.7/octave/diff_codec.m [new file with mode: 0644]
codec2/branches/0.7/octave/doppler_spread.m [new file with mode: 0644]
codec2/branches/0.7/octave/doppler_spread_ut.m [new file with mode: 0644]
codec2/branches/0.7/octave/estsnr.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_demod.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_demod_c.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_demod_coh.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_mod.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_sweep.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_ut.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_ut_coh.m [new file with mode: 0644]
codec2/branches/0.7/octave/fdmdv_ut_freq_off.m [new file with mode: 0644]
codec2/branches/0.7/octave/fm.m [new file with mode: 0644]
codec2/branches/0.7/octave/fm_radio_filt_model.txt [new file with mode: 0644]
codec2/branches/0.7/octave/fmfsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk4.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk_basic.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk_cont_phase.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk_eme.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk_horus.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk_horus_2fsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/fsk_horus_stream.m [new file with mode: 0755]
codec2/branches/0.7/octave/fsk_lib.m [new file with mode: 0644]
codec2/branches/0.7/octave/fskdemodgui.py [new file with mode: 0644]
codec2/branches/0.7/octave/fuzzy_gray.m [new file with mode: 0644]
codec2/branches/0.7/octave/gen_complex_short.m [new file with mode: 0644]
codec2/branches/0.7/octave/gen_rn_coeffs.m [new file with mode: 0644]
codec2/branches/0.7/octave/glottal.m [new file with mode: 0644]
codec2/branches/0.7/octave/gmsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/gp_interleaver.m [new file with mode: 0644]
codec2/branches/0.7/octave/hackrf_dc.m [new file with mode: 0644]
codec2/branches/0.7/octave/hackrf_twotone.m [new file with mode: 0644]
codec2/branches/0.7/octave/hackrf_uc.m [new file with mode: 0644]
codec2/branches/0.7/octave/hf_modem_curves.m [new file with mode: 0644]
codec2/branches/0.7/octave/hf_sim.m [new file with mode: 0644]
codec2/branches/0.7/octave/hfper.m [new file with mode: 0644]
codec2/branches/0.7/octave/horus_high_speed.bin [new file with mode: 0644]
codec2/branches/0.7/octave/horus_msg.txt [new file with mode: 0644]
codec2/branches/0.7/octave/horus_payload_rtty.txt [new file with mode: 0644]
codec2/branches/0.7/octave/horus_tx_bits_binary.txt [new file with mode: 0644]
codec2/branches/0.7/octave/hp_filt.m [new file with mode: 0644]
codec2/branches/0.7/octave/impulse_noise.m [new file with mode: 0644]
codec2/branches/0.7/octave/kmeans2.m [new file with mode: 0644]
codec2/branches/0.7/octave/kmeans_tests.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpc.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpc_fsk_lib.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpc_gen_h_file.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpc_qpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpc_short.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpcdec.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpcenc.m [new file with mode: 0644]
codec2/branches/0.7/octave/ldpcut.m [new file with mode: 0644]
codec2/branches/0.7/octave/linreg.m [new file with mode: 0644]
codec2/branches/0.7/octave/load_comp.m [new file with mode: 0644]
codec2/branches/0.7/octave/load_hackrf.m [new file with mode: 0644]
codec2/branches/0.7/octave/load_raw.m [new file with mode: 0644]
codec2/branches/0.7/octave/lpcauto.m [new file with mode: 0644]
codec2/branches/0.7/octave/lpcpf.m [new file with mode: 0644]
codec2/branches/0.7/octave/lsp.m [new file with mode: 0644]
codec2/branches/0.7/octave/lsp_pdf.m [new file with mode: 0644]
codec2/branches/0.7/octave/lspvar.m [new file with mode: 0644]
codec2/branches/0.7/octave/lspwarp.m [new file with mode: 0644]
codec2/branches/0.7/octave/mag_to_phase.m [new file with mode: 0644]
codec2/branches/0.7/octave/make_hilb.m [new file with mode: 0644]
codec2/branches/0.7/octave/make_ssbfilt.m [new file with mode: 0644]
codec2/branches/0.7/octave/mancyfsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/melstats.m [new file with mode: 0644]
codec2/branches/0.7/octave/melvq.m [new file with mode: 0644]
codec2/branches/0.7/octave/mfsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/newamp.m [new file with mode: 0644]
codec2/branches/0.7/octave/newamp1_batch.m [new file with mode: 0644]
codec2/branches/0.7/octave/newamp1_compare.m [new file with mode: 0644]
codec2/branches/0.7/octave/newamp1_fbf.m [new file with mode: 0644]
codec2/branches/0.7/octave/newamp_batch.m [new file with mode: 0644]
codec2/branches/0.7/octave/newamp_fbf.m [new file with mode: 0644]
codec2/branches/0.7/octave/nf_from_gr.m [new file with mode: 0644]
codec2/branches/0.7/octave/ofdm_dev.m [new file with mode: 0644]
codec2/branches/0.7/octave/ofdm_lib.m [new file with mode: 0644]
codec2/branches/0.7/octave/ofdm_load_const.m [new file with mode: 0644]
codec2/branches/0.7/octave/ofdm_rs.m [new file with mode: 0644]
codec2/branches/0.7/octave/ofdm_rx.m [new file with mode: 0644]
codec2/branches/0.7/octave/ofdm_tx.m [new file with mode: 0644]
codec2/branches/0.7/octave/oqpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/phase.m [new file with mode: 0644]
codec2/branches/0.7/octave/phase2.m [new file with mode: 0644]
codec2/branches/0.7/octave/phasesecord.m [new file with mode: 0644]
codec2/branches/0.7/octave/pitch_test.m [new file with mode: 0644]
codec2/branches/0.7/octave/pl.m [new file with mode: 0644]
codec2/branches/0.7/octave/pl2.m [new file with mode: 0644]
codec2/branches/0.7/octave/plamp.m [new file with mode: 0644]
codec2/branches/0.7/octave/plinterp.m [new file with mode: 0644]
codec2/branches/0.7/octave/pllpcpf.m [new file with mode: 0644]
codec2/branches/0.7/octave/pllsp.m [new file with mode: 0644]
codec2/branches/0.7/octave/pllspdt.m [new file with mode: 0644]
codec2/branches/0.7/octave/plnlp.m [new file with mode: 0644]
codec2/branches/0.7/octave/plot_specgram.m [new file with mode: 0644]
codec2/branches/0.7/octave/plphase.m [new file with mode: 0644]
codec2/branches/0.7/octave/plpitch.m [new file with mode: 0644]
codec2/branches/0.7/octave/plppe.m [new file with mode: 0644]
codec2/branches/0.7/octave/plsub.m [new file with mode: 0644]
codec2/branches/0.7/octave/plvoicing.m [new file with mode: 0644]
codec2/branches/0.7/octave/png.m [new file with mode: 0644]
codec2/branches/0.7/octave/postfilter.m [new file with mode: 0644]
codec2/branches/0.7/octave/pulse.m [new file with mode: 0644]
codec2/branches/0.7/octave/qpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/rfdesign.m [new file with mode: 0644]
codec2/branches/0.7/octave/s_param_rf.m [new file with mode: 0644]
codec2/branches/0.7/octave/sample_clock_offset.m [new file with mode: 0644]
codec2/branches/0.7/octave/save_array_c_header.m [new file with mode: 0644]
codec2/branches/0.7/octave/save_raw.m [new file with mode: 0644]
codec2/branches/0.7/octave/sd.m [new file with mode: 0644]
codec2/branches/0.7/octave/spec.m [new file with mode: 0644]
codec2/branches/0.7/octave/tcohpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/telem_upload.py [new file with mode: 0644]
codec2/branches/0.7/octave/test_cohpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_cohpsk_ch.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_dqpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_dqpsk2.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_dsss.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_dsss_pilot.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_fec.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_foff.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_ftrack.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_ldpc_fsk_lib.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_ml.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_pilot.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_qpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_qpsk2.m [new file with mode: 0644]
codec2/branches/0.7/octave/test_qpsk3.m [new file with mode: 0644]
codec2/branches/0.7/octave/tfdmdv.m [new file with mode: 0644]
codec2/branches/0.7/octave/tfmfsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/tfsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/tfsk_2400a.m [new file with mode: 0644]
codec2/branches/0.7/octave/tget_spec.m [new file with mode: 0644]
codec2/branches/0.7/octave/tlinreg.m [new file with mode: 0644]
codec2/branches/0.7/octave/tnewamp1.m [new file with mode: 0644]
codec2/branches/0.7/octave/tofdm.m [new file with mode: 0644]
codec2/branches/0.7/octave/tpapr.m [new file with mode: 0644]
codec2/branches/0.7/octave/tqpsk.m [new file with mode: 0644]
codec2/branches/0.7/octave/trellis.m [new file with mode: 0644]
codec2/branches/0.7/octave/twomixer.m [new file with mode: 0644]
codec2/branches/0.7/octave/twotone.m [new file with mode: 0644]
codec2/branches/0.7/octave/twotone1.m [new file with mode: 0644]
codec2/branches/0.7/octave/tximage.m [new file with mode: 0644]
codec2/branches/0.7/octave/undersample.m [new file with mode: 0644]
codec2/branches/0.7/octave/vhf_pa.m [new file with mode: 0644]
codec2/branches/0.7/octave/vq [new file with mode: 0644]
codec2/branches/0.7/octave/vq_pager.m [new file with mode: 0644]
codec2/branches/0.7/octave/xormixer.m [new file with mode: 0644]
codec2/branches/0.7/octave/yafsk.m [new file with mode: 0644]
codec2/branches/0.7/raw/b0067.raw [new file with mode: 0644]
codec2/branches/0.7/raw/cq_ref.raw [new file with mode: 0644]
codec2/branches/0.7/raw/cross.raw [new file with mode: 0644]
codec2/branches/0.7/raw/cross_melp2400.raw [new file with mode: 0644]
codec2/branches/0.7/raw/f2400.raw [new file with mode: 0644]
codec2/branches/0.7/raw/forig.raw [new file with mode: 0644]
codec2/branches/0.7/raw/forig_ambe2000.raw [new file with mode: 0644]
codec2/branches/0.7/raw/forig_g729a.raw [new file with mode: 0644]
codec2/branches/0.7/raw/forig_gsm13k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/forig_speex_8k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/g3plx.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts1.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts1a.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts1a_ambe2000.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts1a_g729a.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts1a_gsm13k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts1a_melp.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts1a_speex_8k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts2.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts2a.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts2a_ambe2000.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts2a_g729a.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts2a_gsm13k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts2a_melp.raw [new file with mode: 0644]
codec2/branches/0.7/raw/hts2a_speex_8k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/k6hx.raw [new file with mode: 0644]
codec2/branches/0.7/raw/kristoff.raw [new file with mode: 0644]
codec2/branches/0.7/raw/m2400.raw [new file with mode: 0644]
codec2/branches/0.7/raw/mmt1.raw [new file with mode: 0644]
codec2/branches/0.7/raw/mmt1_ambe2000.raw [new file with mode: 0644]
codec2/branches/0.7/raw/mmt1_g729a.raw [new file with mode: 0644]
codec2/branches/0.7/raw/mmt1_gsm13k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/mmt1_speex_8k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/morig.raw [new file with mode: 0644]
codec2/branches/0.7/raw/morig_ambe2000.raw [new file with mode: 0644]
codec2/branches/0.7/raw/morig_g729a.raw [new file with mode: 0644]
codec2/branches/0.7/raw/morig_gsm13k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/morig_speex_8k.raw [new file with mode: 0644]
codec2/branches/0.7/raw/sine1k_2Hz_spread.raw [new file with mode: 0644]
codec2/branches/0.7/raw/sine1k_2ms_delay_2Hz_spread.raw [new file with mode: 0644]
codec2/branches/0.7/raw/ve9qrp.raw [new file with mode: 0644]
codec2/branches/0.7/raw/ve9qrp_10s.raw [new file with mode: 0644]
codec2/branches/0.7/raw/vk5qi.raw [new file with mode: 0644]
codec2/branches/0.7/script/menu.sh [new file with mode: 0755]
codec2/branches/0.7/script/playraw.sh [new file with mode: 0755]
codec2/branches/0.7/script/raw2wav.sh [new file with mode: 0755]
codec2/branches/0.7/script/separate_all.sh [new file with mode: 0755]
codec2/branches/0.7/script/wav2raw.sh [new file with mode: 0755]
codec2/branches/0.7/src/CMakeLists.txt [new file with mode: 0644]
codec2/branches/0.7/src/H2064_516_sparse.h [new file with mode: 0644]
codec2/branches/0.7/src/HRA_112_112.h [new file with mode: 0644]
codec2/branches/0.7/src/_kiss_fft_guts.h [new file with mode: 0644]
codec2/branches/0.7/src/ampexp.c [new file with mode: 0644]
codec2/branches/0.7/src/ampexp.h [new file with mode: 0644]
codec2/branches/0.7/src/bpf.h [new file with mode: 0644]
codec2/branches/0.7/src/bpfb.h [new file with mode: 0644]
codec2/branches/0.7/src/c2dec.c [new file with mode: 0644]
codec2/branches/0.7/src/c2demo.c [new file with mode: 0644]
codec2/branches/0.7/src/c2enc.c [new file with mode: 0644]
codec2/branches/0.7/src/c2sim.c [new file with mode: 0644]
codec2/branches/0.7/src/codebook.c [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp10.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp4.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp5.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp6.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp7.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp8.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/dlsp9.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/gecb.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp10.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp4.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp5.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp6.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp7.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp8.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp8910.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lsp9.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt1-10.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt10.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt4.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt5.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt6.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt7.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt8.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspdt9.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspjvm1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspjvm2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspjvm3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspmelvq1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspmelvq2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspmelvq3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspres_bw1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspres_bw2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspres_centre1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspres_centre2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspvqanssi1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspvqanssi2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspvqanssi3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspvqanssi4.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspvqexp1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspvqexp2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/lspvqexp3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/mel1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/mel2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/mel3.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/mel4.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/mel5.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/mel6.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/newamp1_energy_q.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/train_120_1.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebook/train_120_2.txt [new file with mode: 0644]
codec2/branches/0.7/src/codebookd.c [new file with mode: 0644]
codec2/branches/0.7/src/codebookdt.c [new file with mode: 0644]
codec2/branches/0.7/src/codebookge.c [new file with mode: 0644]
codec2/branches/0.7/src/codebookjvm.c [new file with mode: 0644]
codec2/branches/0.7/src/codebooknewamp1.c [new file with mode: 0644]
codec2/branches/0.7/src/codebooknewamp1_energy.c [new file with mode: 0644]
codec2/branches/0.7/src/codebookres.c [new file with mode: 0644]
codec2/branches/0.7/src/codebookvq.c [new file with mode: 0644]
codec2/branches/0.7/src/codec2.c [new file with mode: 0644]
codec2/branches/0.7/src/codec2.h [new file with mode: 0644]
codec2/branches/0.7/src/codec2_cohpsk.h [new file with mode: 0644]
codec2/branches/0.7/src/codec2_fdmdv.h [new file with mode: 0644]
codec2/branches/0.7/src/codec2_fft.c [new file with mode: 0644]
codec2/branches/0.7/src/codec2_fft.h [new file with mode: 0644]
codec2/branches/0.7/src/codec2_fifo.h [new file with mode: 0644]
codec2/branches/0.7/src/codec2_fm.h [new file with mode: 0644]
codec2/branches/0.7/src/codec2_internal.h [new file with mode: 0644]
codec2/branches/0.7/src/codec2_ofdm.h [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk.c [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk_ch.c [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk_defs.h [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk_demod.c [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk_get_test_bits.c [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk_internal.h [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk_mod.c [new file with mode: 0644]
codec2/branches/0.7/src/cohpsk_put_test_bits.c [new file with mode: 0644]
codec2/branches/0.7/src/comp.h [new file with mode: 0644]
codec2/branches/0.7/src/comp_prim.h [new file with mode: 0644]
codec2/branches/0.7/src/defines.h [new file with mode: 0644]
codec2/branches/0.7/src/drs232.c [new file with mode: 0644]
codec2/branches/0.7/src/drs232_ldpc.c [new file with mode: 0755]
codec2/branches/0.7/src/dump.c [new file with mode: 0644]
codec2/branches/0.7/src/dump.h [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv.c [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv_channel.c [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv_demod.c [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv_get_test_bits.c [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv_interleave.c [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv_internal.h [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv_mod.c [new file with mode: 0644]
codec2/branches/0.7/src/fdmdv_put_test_bits.c [new file with mode: 0644]
codec2/branches/0.7/src/fec_dec.c [new file with mode: 0644]
codec2/branches/0.7/src/fec_enc.c [new file with mode: 0644]
codec2/branches/0.7/src/fifo.c [new file with mode: 0644]
codec2/branches/0.7/src/fm.c [new file with mode: 0644]
codec2/branches/0.7/src/fm_demod.c [new file with mode: 0644]
codec2/branches/0.7/src/fm_fir_coeff.h [new file with mode: 0644]
codec2/branches/0.7/src/fmfsk.c [new file with mode: 0644]
codec2/branches/0.7/src/fmfsk.h [new file with mode: 0644]
codec2/branches/0.7/src/fmfsk_demod.c [new file with mode: 0644]
codec2/branches/0.7/src/fmfsk_mod.c [new file with mode: 0644]
codec2/branches/0.7/src/fq20.sh [new file with mode: 0755]
codec2/branches/0.7/src/freedv_api.c [new file with mode: 0644]
codec2/branches/0.7/src/freedv_api.h [new file with mode: 0644]
codec2/branches/0.7/src/freedv_api_internal.h [new file with mode: 0644]
codec2/branches/0.7/src/freedv_data_channel.c [new file with mode: 0644]
codec2/branches/0.7/src/freedv_data_channel.h [new file with mode: 0644]
codec2/branches/0.7/src/freedv_rx.c [new file with mode: 0644]
codec2/branches/0.7/src/freedv_tx.c [new file with mode: 0644]
codec2/branches/0.7/src/freedv_vhf_framing.c [new file with mode: 0644]
codec2/branches/0.7/src/freedv_vhf_framing.h [new file with mode: 0644]
codec2/branches/0.7/src/fsk.c [new file with mode: 0644]
codec2/branches/0.7/src/fsk.h [new file with mode: 0644]
codec2/branches/0.7/src/fsk_demod.c [new file with mode: 0644]
codec2/branches/0.7/src/fsk_get_test_bits.c [new file with mode: 0644]
codec2/branches/0.7/src/fsk_mod.c [new file with mode: 0644]
codec2/branches/0.7/src/fsk_put_test_bits.c [new file with mode: 0644]
codec2/branches/0.7/src/generate_codebook.c [new file with mode: 0644]
codec2/branches/0.7/src/golay23.c [new file with mode: 0644]
codec2/branches/0.7/src/golay23.h [new file with mode: 0644]
codec2/branches/0.7/src/golaydectable.h [new file with mode: 0644]
codec2/branches/0.7/src/golayenctable.h [new file with mode: 0644]
codec2/branches/0.7/src/hanning.h [new file with mode: 0644]
codec2/branches/0.7/src/horus_l2.c [new file with mode: 0644]
codec2/branches/0.7/src/horus_l2.h [new file with mode: 0644]
codec2/branches/0.7/src/ht_coeff.h [new file with mode: 0644]
codec2/branches/0.7/src/insert_errors.c [new file with mode: 0644]
codec2/branches/0.7/src/interp.c [new file with mode: 0644]
codec2/branches/0.7/src/interp.h [new file with mode: 0644]
codec2/branches/0.7/src/kiss_fft.c [new file with mode: 0644]
codec2/branches/0.7/src/kiss_fft.h [new file with mode: 0644]
codec2/branches/0.7/src/kiss_fftr.c [new file with mode: 0644]
codec2/branches/0.7/src/kiss_fftr.h [new file with mode: 0644]
codec2/branches/0.7/src/ldpc_dec.c [new file with mode: 0644]
codec2/branches/0.7/src/ldpc_enc.c [new file with mode: 0644]
codec2/branches/0.7/src/linreg.c [new file with mode: 0644]
codec2/branches/0.7/src/linreg.h [new file with mode: 0644]
codec2/branches/0.7/src/listensim.sh [new file with mode: 0755]
codec2/branches/0.7/src/lpc.c [new file with mode: 0644]
codec2/branches/0.7/src/lpc.h [new file with mode: 0644]
codec2/branches/0.7/src/lsp.c [new file with mode: 0644]
codec2/branches/0.7/src/lsp.h [new file with mode: 0644]
codec2/branches/0.7/src/machdep.h [new file with mode: 0644]
codec2/branches/0.7/src/mbest.c [new file with mode: 0644]
codec2/branches/0.7/src/mbest.h [new file with mode: 0644]
codec2/branches/0.7/src/modem_probe.c [new file with mode: 0644]
codec2/branches/0.7/src/modem_probe.h [new file with mode: 0644]
codec2/branches/0.7/src/modem_stats.c [new file with mode: 0644]
codec2/branches/0.7/src/modem_stats.h [new file with mode: 0644]
codec2/branches/0.7/src/mpdecode_core.c [new file with mode: 0644]
codec2/branches/0.7/src/mpdecode_core.h [new file with mode: 0644]
codec2/branches/0.7/src/newamp1.c [new file with mode: 0644]
codec2/branches/0.7/src/newamp1.h [new file with mode: 0644]
codec2/branches/0.7/src/nlp.c [new file with mode: 0644]
codec2/branches/0.7/src/nlp.h [new file with mode: 0644]
codec2/branches/0.7/src/noise_samples.h [new file with mode: 0644]
codec2/branches/0.7/src/octave.c [new file with mode: 0644]
codec2/branches/0.7/src/octave.h [new file with mode: 0644]
codec2/branches/0.7/src/ofdm.c [new file with mode: 0644]
codec2/branches/0.7/src/ofdm_internal.h [new file with mode: 0644]
codec2/branches/0.7/src/os.h [new file with mode: 0644]
codec2/branches/0.7/src/pack.c [new file with mode: 0644]
codec2/branches/0.7/src/phase.c [new file with mode: 0644]
codec2/branches/0.7/src/phase.h [new file with mode: 0644]
codec2/branches/0.7/src/phaseexp.c [new file with mode: 0644]
codec2/branches/0.7/src/phaseexp.h [new file with mode: 0644]
codec2/branches/0.7/src/pilot_coeff.h [new file with mode: 0644]
codec2/branches/0.7/src/pilots_coh.h [new file with mode: 0644]
codec2/branches/0.7/src/postfilter.c [new file with mode: 0644]
codec2/branches/0.7/src/postfilter.h [new file with mode: 0644]
codec2/branches/0.7/src/quantise.c [new file with mode: 0644]
codec2/branches/0.7/src/quantise.h [new file with mode: 0644]
codec2/branches/0.7/src/resample.c [new file with mode: 0644]
codec2/branches/0.7/src/rn.h [new file with mode: 0644]
codec2/branches/0.7/src/rn_coh.h [new file with mode: 0644]
codec2/branches/0.7/src/rxdec_coeff.h [new file with mode: 0644]
codec2/branches/0.7/src/sim.sh [new file with mode: 0755]
codec2/branches/0.7/src/sine.c [new file with mode: 0644]
codec2/branches/0.7/src/sine.h [new file with mode: 0644]
codec2/branches/0.7/src/ssbfilt_coeff.h [new file with mode: 0644]
codec2/branches/0.7/src/tdma.h [new file with mode: 0644]
codec2/branches/0.7/src/test_bits.h [new file with mode: 0644]
codec2/branches/0.7/src/test_bits_coh.h [new file with mode: 0644]
codec2/branches/0.7/src/test_bits_ofdm.h [new file with mode: 0644]
codec2/branches/0.7/src/varicode.c [new file with mode: 0644]
codec2/branches/0.7/src/varicode.h [new file with mode: 0644]
codec2/branches/0.7/src/varicode_table.h [new file with mode: 0644]
codec2/branches/0.7/src/vhf_deframe_c2.c [new file with mode: 0644]
codec2/branches/0.7/src/vhf_frame_c2.c [new file with mode: 0644]
codec2/branches/0.7/stm32/MENU.txt [new file with mode: 0644]
codec2/branches/0.7/stm32/Makefile [new file with mode: 0644]
codec2/branches/0.7/stm32/README.txt [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/debugblinky.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/gdb_stdio.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/iir_duc.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/iir_tuner.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/menu.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/morse.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/new_i2c.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/sfx.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/si53xx.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/sine.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/sm1000_leds_switches.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/sounds.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/stm32f4_adc.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/stm32f4_adc_tuner.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/stm32f4_dac.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/stm32f4_dacduc.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/stm32f4_usb_vcp.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/stm32f4_vrom.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/stm32f4xx_conf.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/tm_stm32f4_gpio.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/tm_stm32f4_mco_output.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/tone.h [new file with mode: 0644]
codec2/branches/0.7/stm32/inc/tot.h [new file with mode: 0644]
codec2/branches/0.7/stm32/src/adc_rec.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/adc_rec_usb.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/adc_sd.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/adc_sfdr_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/adcdac_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/codec2_profile.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/dac_it.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/dac_play.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/dac_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/dac_ut_fast.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/debugblinky.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/fast_dac_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/fdmdv_dump_rt.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/fdmdv_profile.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/fft_test.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/freedv_rx_profile.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/freedv_tx_profile.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/gdb_stdio.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/iir_duc.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/iir_tuner.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/init.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/mco_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/menu.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/morse.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/new_i2c.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/power_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sfx.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/si5351_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/si53xx.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sine.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sm1000_leds_switches.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sm1000_leds_switches_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sm1000_main.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sm2000_adc_dump.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sm2000_rxdemo.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sm2000_stw.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/sounds.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/startup_stm32f4xx.s [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_adc.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_adc_tuner.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_dac.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_dacduc.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_dacloduc.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_machdep.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_pwm.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_usb_vcp.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/stm32f4_vrom.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/system_stm32f4xx.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/timer_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/tm_stm32f4_gpio.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/tm_stm32f4_mco_output.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/tone.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/tot.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/tuner_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/usb_vcp_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/src/usb_vsp_ut.c [new file with mode: 0644]
codec2/branches/0.7/stm32/stlink/elfsym.c [new file with mode: 0644]
codec2/branches/0.7/stm32/stlink/elfsym.h [new file with mode: 0644]
codec2/branches/0.7/stm32/stlink/stlink.patch [new file with mode: 0644]
codec2/branches/0.7/stm32/stm32_flash.ld [new file with mode: 0644]
codec2/branches/0.7/stm32/stm32_ram.ld [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_conf/usb_bsp.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_conf/usb_bsp.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_conf/usb_conf.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_conf/usbd_conf.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_conf/usbd_desc.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_conf/usbd_desc.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_conf/usbd_usr.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_core.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_core.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_vcp.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_vcp.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_core.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_core.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_def.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_ioreq.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_ioreq.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_req.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_req.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/core/usbd_usr.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_core.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_core.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd_int.c [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd_int.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_defines.h [new file with mode: 0644]
codec2/branches/0.7/stm32/usb_lib/otg/usb_regs.h [new file with mode: 0644]
codec2/branches/0.7/unittest/CMakeLists.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/Makefile.am [new file with mode: 0644]
codec2/branches/0.7/unittest/Makefile.in [new file with mode: 0644]
codec2/branches/0.7/unittest/README [new file with mode: 0644]
codec2/branches/0.7/unittest/c2validate.c [new file with mode: 0644]
codec2/branches/0.7/unittest/c2validate.h [new file with mode: 0644]
codec2/branches/0.7/unittest/create_interleaver.c [new file with mode: 0644]
codec2/branches/0.7/unittest/de.c [new file with mode: 0644]
codec2/branches/0.7/unittest/dvdongle2.c [new file with mode: 0644]
codec2/branches/0.7/unittest/extract.c [new file with mode: 0644]
codec2/branches/0.7/unittest/fdmdv_mem.c [new file with mode: 0644]
codec2/branches/0.7/unittest/ge_train.c [new file with mode: 0644]
codec2/branches/0.7/unittest/genampdata.c [new file with mode: 0644]
codec2/branches/0.7/unittest/genlsp.c [new file with mode: 0644]
codec2/branches/0.7/unittest/genphdata.c [new file with mode: 0644]
codec2/branches/0.7/unittest/genres.c [new file with mode: 0644]
codec2/branches/0.7/unittest/hts1a.h [new file with mode: 0644]
codec2/branches/0.7/unittest/hts1a_1300.h [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp1.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp10.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp2.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp3.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp4.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp45678910.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp5.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp6.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp7.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp8.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lsp9.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lspd456.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lspd678910.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lspd78.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lspd910.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/lspjnd5-10.txt [new file with mode: 0644]
codec2/branches/0.7/unittest/mksine.c [new file with mode: 0644]
codec2/branches/0.7/unittest/polar2rect.c [new file with mode: 0644]
codec2/branches/0.7/unittest/pre.c [new file with mode: 0644]
codec2/branches/0.7/unittest/raw2h.c [new file with mode: 0644]
codec2/branches/0.7/unittest/run_tests.sh [new file with mode: 0644]
codec2/branches/0.7/unittest/scalarlsptest.c [new file with mode: 0644]
codec2/branches/0.7/unittest/sd.c [new file with mode: 0644]
codec2/branches/0.7/unittest/sd.h [new file with mode: 0644]
codec2/branches/0.7/unittest/speexlsptest.c [new file with mode: 0644]
codec2/branches/0.7/unittest/speexnoisesup.c [new file with mode: 0644]
codec2/branches/0.7/unittest/t16_8.c [new file with mode: 0644]
codec2/branches/0.7/unittest/t16_8_short.c [new file with mode: 0644]
codec2/branches/0.7/unittest/t48_8.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tcodec2.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tcohpsk.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tcontphase.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tdec.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tdeframer.c [new file with mode: 0644]
codec2/branches/0.7/unittest/test_cohpsk_ch.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tfdmdv.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tfifo.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tfmfsk.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tfreedv_data_channel.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tfsk.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tinterp.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tlininterp.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tlspsens.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tnewamp1.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tnlp.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tofdm.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tprede.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tquant.c [new file with mode: 0644]
codec2/branches/0.7/unittest/tsrc.c [new file with mode: 0644]
codec2/branches/0.7/unittest/vq_train_jvm.c [new file with mode: 0755]
codec2/branches/0.7/unittest/vqtrain.c [new file with mode: 0644]
codec2/branches/0.7/wav/all.wav [new file with mode: 0644]
codec2/branches/0.7/wav/cross.wav [new file with mode: 0644]
codec2/branches/0.7/wav/cross_melp2400.wav [new file with mode: 0644]
codec2/branches/0.7/wav/f2400.wav [new file with mode: 0644]
codec2/branches/0.7/wav/forig.wav [new file with mode: 0644]
codec2/branches/0.7/wav/forig_ambe2000.wav [new file with mode: 0644]
codec2/branches/0.7/wav/forig_speex_8k.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts1a.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts1a_ambe2000.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts1a_c2_v0.1.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts1a_c2_v0.1a.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts1a_g729a.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts1a_lpc10.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts1a_speex_8k.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts2a.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts2a_ambe2000.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts2a_c2_v0.1.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts2a_c2_v0.1a.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts2a_g729a.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts2a_lpc10.wav [new file with mode: 0644]
codec2/branches/0.7/wav/hts2a_speex_8k.wav [new file with mode: 0644]
codec2/branches/0.7/wav/m2400.wav [new file with mode: 0644]
codec2/branches/0.7/wav/mmt1.wav [new file with mode: 0644]
codec2/branches/0.7/wav/mmt1_ambe2000.wav [new file with mode: 0644]
codec2/branches/0.7/wav/mmt1_c2_v01a.wav [new file with mode: 0644]
codec2/branches/0.7/wav/mmt1_lpc10.wav [new file with mode: 0644]
codec2/branches/0.7/wav/mmt1_speex_8k.wav [new file with mode: 0644]
codec2/branches/0.7/wav/morig.wav [new file with mode: 0644]
codec2/branches/0.7/wav/morig_ambe2000.wav [new file with mode: 0644]
codec2/branches/0.7/wav/morig_speex_8k.wav [new file with mode: 0644]
codec2/branches/0.7/wav/ve9qrp.wav [new file with mode: 0644]
codec2/branches/0.7/wav/vk5qi.wav [new file with mode: 0644]
codec2/branches/0.7/wav/x200_ext.wav [new file with mode: 0644]
codec2/branches/0.7/wav/x200_int.wav [new file with mode: 0644]
freedv/branches/1.2/CMakeLists.txt
freedv/branches/1.2/README.txt
freedv/branches/1.2/RELEASE_NOTES.txt [new file with mode: 0644]
freedv/branches/1.2/USER_MANUAL.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/.clang/.gitignore [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/CMakeLists.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/COPYING [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/README.osx [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/README.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/RELEASE_NOTES.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/USER_MANUAL.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/BuildCodec2.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/BuildHamlib.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/BuildPortaudio.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/BuildSamplerate.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/BuildSndfile.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/BuildSpeex.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/BuildWxWidgets.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/FindPortaudio.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/GetDependencies.cmake.in [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/MinGW.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/config.h.in [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/soxconfig.h.in [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/cmake/version.h.in [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/CMakeLists.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/LICENSE [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv.desktop [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv.ico [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv.rc [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv128x128.png [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv256x256.png [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv48x48.png [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv64x64.png [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/contrib/freedv_screenshot.png [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/credits.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/current [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/format [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/fs-type [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/fsfs.conf [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/min-unpacked-rev [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/rep-cache.db [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/revprops/0/0 [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/revprops/0/1 [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/revs/0/0 [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/revs/0/1 [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/transactions/.gitignore [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/txn-current [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/txn-current-lock [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/txn-protorevs/.gitignore [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/uuid [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/db/write-lock [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/debian/changelog [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/debian/compat [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/debian/control [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/debian/copyright [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/debian/docs [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/debian/format [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/debian/rules [new file with mode: 0755]
freedv/branches/1.2/freedv-dev/script/spot.sh [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/CMakeLists.txt [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/Makefile.win32 [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/afreedvplugin.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/comp.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_audiooptions.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_audiooptions.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_filter.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_filter.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_options.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_options.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_plugin.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_plugin.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_ptt.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/dlg_ptt.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_defines.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_main.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_main.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_pa_wrapper.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_pa_wrapper.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scalar.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scalar.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scatter.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scatter.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_spectrum.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_spectrum.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_waterfall.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_waterfall.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/freedv.icns [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/hamlib.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/hamlib.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/info.plist [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/serialport.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/serialport.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/band.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/biquad.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/biquad.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/biquads.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/effects.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/effects.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/effects_i.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/formats_i.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/libsox.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/sox.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/sox_i.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/soxomp.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/util.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/xmalloc.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox/xmalloc.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox_biquad.c [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/sox_biquad.h [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/topFrame.cpp [new file with mode: 0644]
freedv/branches/1.2/freedv-dev/src/topFrame.h [new file with mode: 0644]
freedv/branches/1.2/src/CMakeLists.txt
freedv/branches/1.2/src/dlg_options.cpp
freedv/branches/1.2/src/dlg_options.h
freedv/branches/1.2/src/dlg_ptt.cpp
freedv/branches/1.2/src/dlg_ptt.h
freedv/branches/1.2/src/fdmdv2_main.cpp
freedv/branches/1.2/src/fdmdv2_main.h
freedv/branches/1.2/src/hamlib.cpp
freedv/branches/1.2/src/hamlib.h
freedv/branches/1.2/src/serialport.cpp [new file with mode: 0644]
freedv/branches/1.2/src/serialport.h [new file with mode: 0644]
freedv/branches/1.2/src/topFrame.cpp
freedv/tags/1.2.2/.clang/.gitignore [new file with mode: 0644]
freedv/tags/1.2.2/CMakeLists.txt [new file with mode: 0644]
freedv/tags/1.2.2/COPYING [new file with mode: 0644]
freedv/tags/1.2.2/README.osx [new file with mode: 0644]
freedv/tags/1.2.2/README.txt [new file with mode: 0644]
freedv/tags/1.2.2/RELEASE_NOTES.txt [new file with mode: 0644]
freedv/tags/1.2.2/USER_MANUAL.txt [new file with mode: 0644]
freedv/tags/1.2.2/cmake/BuildCodec2.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/BuildHamlib.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/BuildPortaudio.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/BuildSamplerate.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/BuildSndfile.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/BuildSpeex.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/BuildWxWidgets.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/FindPortaudio.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/GetDependencies.cmake.in [new file with mode: 0644]
freedv/tags/1.2.2/cmake/MinGW.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/Toolchain-Ubuntu-mingw32.cmake [new file with mode: 0644]
freedv/tags/1.2.2/cmake/config.h.in [new file with mode: 0644]
freedv/tags/1.2.2/cmake/soxconfig.h.in [new file with mode: 0644]
freedv/tags/1.2.2/cmake/version.h.in [new file with mode: 0644]
freedv/tags/1.2.2/contrib/CMakeLists.txt [new file with mode: 0644]
freedv/tags/1.2.2/contrib/LICENSE [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv.desktop [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv.ico [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv.rc [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv128x128.png [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv256x256.png [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv48x48.png [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv64x64.png [new file with mode: 0644]
freedv/tags/1.2.2/contrib/freedv_screenshot.png [new file with mode: 0644]
freedv/tags/1.2.2/credits.txt [new file with mode: 0644]
freedv/tags/1.2.2/db/current [new file with mode: 0644]
freedv/tags/1.2.2/db/format [new file with mode: 0644]
freedv/tags/1.2.2/db/fs-type [new file with mode: 0644]
freedv/tags/1.2.2/db/fsfs.conf [new file with mode: 0644]
freedv/tags/1.2.2/db/min-unpacked-rev [new file with mode: 0644]
freedv/tags/1.2.2/db/rep-cache.db [new file with mode: 0644]
freedv/tags/1.2.2/db/revprops/0/0 [new file with mode: 0644]
freedv/tags/1.2.2/db/revprops/0/1 [new file with mode: 0644]
freedv/tags/1.2.2/db/revs/0/0 [new file with mode: 0644]
freedv/tags/1.2.2/db/revs/0/1 [new file with mode: 0644]
freedv/tags/1.2.2/db/transactions/.gitignore [new file with mode: 0644]
freedv/tags/1.2.2/db/txn-current [new file with mode: 0644]
freedv/tags/1.2.2/db/txn-current-lock [new file with mode: 0644]
freedv/tags/1.2.2/db/txn-protorevs/.gitignore [new file with mode: 0644]
freedv/tags/1.2.2/db/uuid [new file with mode: 0644]
freedv/tags/1.2.2/db/write-lock [new file with mode: 0644]
freedv/tags/1.2.2/debian/changelog [new file with mode: 0644]
freedv/tags/1.2.2/debian/compat [new file with mode: 0644]
freedv/tags/1.2.2/debian/control [new file with mode: 0644]
freedv/tags/1.2.2/debian/copyright [new file with mode: 0644]
freedv/tags/1.2.2/debian/docs [new file with mode: 0644]
freedv/tags/1.2.2/debian/format [new file with mode: 0644]
freedv/tags/1.2.2/debian/rules [new file with mode: 0755]
freedv/tags/1.2.2/freedv-dev/.clang/.gitignore [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/CMakeLists.txt [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/COPYING [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/README.osx [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/README.txt [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/RELEASE_NOTES.txt [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/USER_MANUAL.txt [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/BuildCodec2.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/BuildHamlib.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/BuildPortaudio.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/BuildSamplerate.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/BuildSndfile.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/BuildSpeex.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/BuildWxWidgets.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/FindPortaudio.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/GetDependencies.cmake.in [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/MinGW.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/config.h.in [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/soxconfig.h.in [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/cmake/version.h.in [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/CMakeLists.txt [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/LICENSE [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv.desktop [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv.ico [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv.rc [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv128x128.png [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv256x256.png [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv48x48.png [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv64x64.png [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/contrib/freedv_screenshot.png [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/credits.txt [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/current [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/format [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/fs-type [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/fsfs.conf [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/min-unpacked-rev [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/rep-cache.db [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/revprops/0/0 [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/revprops/0/1 [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/revs/0/0 [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/revs/0/1 [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/transactions/.gitignore [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/txn-current [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/txn-current-lock [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/txn-protorevs/.gitignore [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/uuid [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/db/write-lock [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/debian/changelog [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/debian/compat [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/debian/control [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/debian/copyright [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/debian/docs [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/debian/format [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/debian/rules [new file with mode: 0755]
freedv/tags/1.2.2/freedv-dev/script/spot.sh [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/CMakeLists.txt [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/Makefile.win32 [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/afreedvplugin.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/comp.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_audiooptions.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_audiooptions.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_filter.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_filter.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_options.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_options.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_plugin.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_plugin.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_ptt.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/dlg_ptt.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_defines.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_main.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_main.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_pa_wrapper.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_pa_wrapper.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scalar.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scalar.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scatter.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scatter.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_spectrum.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_spectrum.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_waterfall.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_waterfall.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/freedv.icns [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/hamlib.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/hamlib.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/info.plist [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/serialport.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/serialport.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/band.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/biquad.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/biquad.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/biquads.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/effects.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/effects.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/effects_i.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/formats_i.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/libsox.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/sox.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/sox_i.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/soxomp.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/util.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/xmalloc.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox/xmalloc.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox_biquad.c [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/sox_biquad.h [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/topFrame.cpp [new file with mode: 0644]
freedv/tags/1.2.2/freedv-dev/src/topFrame.h [new file with mode: 0644]
freedv/tags/1.2.2/script/spot.sh [new file with mode: 0644]
freedv/tags/1.2.2/src/CMakeLists.txt [new file with mode: 0644]
freedv/tags/1.2.2/src/Makefile.win32 [new file with mode: 0644]
freedv/tags/1.2.2/src/afreedvplugin.c [new file with mode: 0644]
freedv/tags/1.2.2/src/comp.h [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_audiooptions.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_audiooptions.h [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_filter.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_filter.h [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_options.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_options.h [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_plugin.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_plugin.h [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_ptt.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/dlg_ptt.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_defines.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_main.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_main.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_pa_wrapper.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_pa_wrapper.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_scalar.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_scalar.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_scatter.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_scatter.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_spectrum.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_spectrum.h [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_waterfall.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/fdmdv2_plot_waterfall.h [new file with mode: 0644]
freedv/tags/1.2.2/src/freedv.icns [new file with mode: 0644]
freedv/tags/1.2.2/src/hamlib.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/hamlib.h [new file with mode: 0644]
freedv/tags/1.2.2/src/info.plist [new file with mode: 0644]
freedv/tags/1.2.2/src/serialport.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/serialport.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/band.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/biquad.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/biquad.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/biquads.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/effects.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/effects.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/effects_i.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/formats_i.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/libsox.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/sox.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/sox_i.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/soxomp.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/util.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/xmalloc.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox/xmalloc.h [new file with mode: 0644]
freedv/tags/1.2.2/src/sox_biquad.c [new file with mode: 0644]
freedv/tags/1.2.2/src/sox_biquad.h [new file with mode: 0644]
freedv/tags/1.2.2/src/topFrame.cpp [new file with mode: 0644]
freedv/tags/1.2.2/src/topFrame.h [new file with mode: 0644]

index ebf8fff1c0073e951e8d4181d92baf15bdddead1..80f741127295233dd9d53cc167bcf70999b5aa27 100644 (file)
@@ -35,7 +35,7 @@ endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
 # file at some point.
 #
 set(CODEC2_VERSION_MAJOR 0)
-set(CODEC2_VERSION_MINOR 6)
+set(CODEC2_VERSION_MINOR 7)
 # Set to patch level if needed, otherwise leave FALSE.
 set(CODEC2_VERSION_PATCH FALSE)
 set(CODEC2_VERSION "${CODEC2_VERSION_MAJOR}.${CODEC2_VERSION_MINOR}")
diff --git a/codec2/branches/0.7/CMakeLists.txt b/codec2/branches/0.7/CMakeLists.txt
new file mode 100644 (file)
index 0000000..45cc887
--- /dev/null
@@ -0,0 +1,244 @@
+#
+# Codec2 - Next-Generation Digital Voice for Two-Way Radio
+#
+# CMake configuration contributed by Richard Shaw (KF5OIM)
+# Please report questions, comments, problems, or patches to the freetel
+# mailing list: https://lists.sourceforge.net/lists/listinfo/freetel-codec2
+#
+project(codec2 C)
+
+cmake_minimum_required(VERSION 2.8)
+
+include(GNUInstallDirs)
+mark_as_advanced(CLEAR
+    CMAKE_INSTALL_BINDIR
+    CMAKE_INSTALL_INCLUDEDIR
+    CMAKE_INSTALL_LIBDIR
+)
+
+#
+# Prevent in-source builds
+# If an in-source build is attempted, you will still need to clean up a few
+# files manually.
+#
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
+if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+  message(FATAL_ERROR "In-source builds in ${CMAKE_BINARY_DIR} are not "
+   "allowed, please remove ./CMakeCache.txt and ./CMakeFiles/, create a "
+   "separate build directory and run cmake from there.")
+endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+
+
+#
+# Set project version information. This should probably be done via external
+# file at some point.
+#
+set(CODEC2_VERSION_MAJOR 0)
+set(CODEC2_VERSION_MINOR 7)
+# Set to patch level if needed, otherwise leave FALSE.
+set(CODEC2_VERSION_PATCH FALSE)
+set(CODEC2_VERSION "${CODEC2_VERSION_MAJOR}.${CODEC2_VERSION_MINOR}")
+# Patch level version bumps should not change API/ABI.
+set(SOVERSION "${CODEC2_VERSION_MAJOR}.${CODEC2_VERSION_MINOR}")
+if(CODEC2_VERSION_PATCH)
+    set(CODEC2_VERSION "${CODEC2_VERSION}.${CODEC2_VERSION_PATCH}")
+endif()
+message(STATUS "codec2 version: ${CODEC2_VERSION}")
+
+# Set default build type
+if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Release")
+endif()
+
+# Set default C++ flags.
+include(CheckCCompilerFlag)
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -O3")
+CHECK_C_COMPILER_FLAG("-std=gnu11" COMPILER_SUPPORTS_GNU11)
+if(CMAKE_C_STANDARD_COMPUTED_DEFAULT EQUAL "90")
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
+endif()
+# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
+
+set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS}")
+set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS}")
+
+# -fPIC is implied on MinGW...
+if(NOT WIN32)
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
+endif()
+
+message(STATUS "Build type is: " ${CMAKE_BUILD_TYPE})
+string(TOUPPER ${CMAKE_BUILD_TYPE} _FLAGS)
+if(NOT _FLAGS STREQUAL "NONE")
+    set(BUILD_FLAGS "${CMAKE_C_FLAGS_${_FLAGS}}")
+endif()
+message(STATUS "Compiler Flags: " ${BUILD_FLAGS})
+
+#
+# Setup Windows/MinGW specifics here.
+#
+if(MINGW)
+    message(STATUS "System is MinGW.")
+endif(MINGW)
+
+
+#
+# Find the svn revision if this is a working copy.
+# WORK IN PROGRESS
+# Works ok if it is a working copy but errors out if not.
+#
+#find_package(Subversion)
+#if(Subversion_FOUND)
+#   Subversion_WC_INFO(${CMAKE_CURRENT_SOURCE_DIR} CODEC2)
+#   message(STATUS "codec2 svn revision: ${CODEC2_WC_REVISION}")
+#else(SUBVERSION_FOUND)
+#   message(WARNING "Subversion not found. Can not determine svn revision.")
+#endif(SUBVERSION_FOUND)
+
+
+#
+# Default options
+#
+option(BUILD_SHARED_LIBS
+    "Build shared library. Set to OFF for static library." ON)
+# Unittest should be on for dev builds and off for releases.
+if(CMAKE_BUILD_TYPE MATCHES "Release")
+    option(UNITTEST "Build unittest binaries." OFF)
+else()
+    option(UNITTEST "Build unittest binaries." ON)
+endif()
+option(INSTALL_EXAMPLES "Install example code." OFF)
+if(INSTALL_EXAMPLES)
+    install(DIRECTORY octave raw script wav
+        USE_SOURCE_PERMISSIONS
+        DESTINATION ${CMAKE_INSTALL_DATADIR}/codec2)
+endif()
+
+
+# Math library is automatic on windows
+if(UNIX)
+    set(CMAKE_REQUIRED_INCLUDES math.h)
+    set(CMAKE_REQUIRED_LIBRARIES m)
+endif(UNIX)
+
+include(CheckIncludeFiles)
+check_include_files("stdlib.h" HAVE_STDLIB_H)
+check_include_files("string.h" HAVE_STRING_H)
+
+include(CheckFunctionExists)
+check_function_exists(floor  HAVE_FLOOR)
+check_function_exists(ceil   HAVE_CEIL)
+check_function_exists(pow    HAVE_POW)
+check_function_exists(sqrt   HAVE_SQRT)
+check_function_exists(sin    HAVE_SIN)
+check_function_exists(cos    HAVE_COS)
+check_function_exists(atan2  HAVE_ATAN2)
+check_function_exists(log10  HAVE_LOG10)
+check_function_exists(round  HAVE_ROUND)
+check_function_exists(getopt HAVE_GETOPT)
+
+configure_file ("${PROJECT_SOURCE_DIR}/cmake/config.h.in"
+                "${PROJECT_BINARY_DIR}/config.h" )
+include_directories(${PROJECT_BINARY_DIR})
+
+# CMake Package setup
+#include(CMakePackageConfigHelpers)
+#configure_package_config_file(cmake/codec2-config.cmake.in
+#    ${CMAKE_CURRENT_BINARY_DIR}/codec2-config.cmake
+#    INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/codec2
+#    PATH_VARS CMAKE_INSTALL_INCLUDEDIR
+#)
+
+#
+# codec2 library
+#
+add_subdirectory(src)
+
+if(UNITTEST)
+    # Pthread Library
+    find_package(Threads REQUIRED)
+    message(STATUS "Threads library flags: ${CMAKE_THREAD_LIBS_INIT}")
+
+    #
+    # Find speex library
+    #
+    message(STATUS "Looking for Speex DSP library.")
+    find_path(SPEEXDSP_INCLUDE_DIR speex/speex.h)
+    find_library(SPEEXDSP_LIBRARY speexdsp)
+    message(STATUS "  Speex DSP headers: ${SPEEXDSP_INCLUDE_DIR}")
+    message(STATUS "  Speex DSP library: ${SPEEXDSP_LIBRARY}")
+    if(NOT SPEEXDSP_INCLUDE_DIR AND NOT SPEEXDSP_LIBRARY)
+        message(FATAL_ERROR "Speex DSP library not found!")
+    endif()
+
+    #
+    # Samplerate Library
+    #
+    message(STATUS "Looking for samplerate...")
+    find_library(LIBSAMPLERATE samplerate)
+    find_path(LIBSAMPLERATE_INCLUDE_DIR samplerate.h)
+    message(STATUS "  samplerate headers: ${LIBSAMPLERATE_INCLUDE_DIR}")
+    message(STATUS "  samplerate library: ${LIBSAMPLERATE}")
+    if(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        list(APPEND FREEDV_LINK_LIBS ${CMAKE_REQUIRED_LIBRARIES})
+        include_directories(${LIBSAMPLERATE_INCLUDE_DIR})
+    else(LIBSTAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        message(FATAL_ERROR "samplerate library not found.
+On Linux systems try installing:
+    samplerate-devel  (RPM based systems)
+    libsamplerate-dev (DEB based systems)")
+    endif(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+
+    add_subdirectory(unittest)
+endif(UNITTEST)
+
+#
+# Cpack NSIS installer configuration for Windows.
+# See: http://nsis.sourceforge.net/Download
+#
+# *nix systems should use "make install" and/or appropriate
+# distribution packaging tools.
+#
+if(WIN32)
+    # Detect if we're doing a 32-bit or 64-bit windows build.
+    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+        set(CMAKE_CL_64 TRUE)
+    endif()
+    configure_file(cmake/GetDependencies.cmake.in cmake/GetDependencies.cmake
+        @ONLY
+    )
+    install(SCRIPT ${CMAKE_BINARY_DIR}/cmake/GetDependencies.cmake)
+    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Next-Generation Digital Voice for Two-Way Radio")
+    set(CPACK_PACKAGE_VENDOR "CMake")
+    set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
+    set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
+    set(CPACK_PACKAGE_VERSION_MAJOR ${CODEC2_VERSION_MAJOR})
+    set(CPACK_PACKAGE_VERSION_MINOR ${CODEC2_VERSION_MINOR})
+    if(CODEC2_VERSION_PATCH)
+        set(CPACK_PACKAGE_VERSION_PATCH ${CODEC2_VERSION_PATCH})
+    else()
+        set(CPACK_PACKAGE_VERSION_PATCH 0)
+    endif()
+    set(CPACK_PACKAGE_INSTALL_DIRECTORY "Codec2")
+    set(CPACK_CREATE_DESKTOP_LINKS "")
+    set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+    set(CPACK_NSIS_URL_INFO_ABOUT "http://codec2.org")
+    set(CPACK_NSIS_MODIFY_PATH ON)
+    include(CPack)
+endif(WIN32)
+
+########################################################################
+# Create Pkg Config File
+########################################################################
+configure_file(
+    ${CMAKE_CURRENT_SOURCE_DIR}/codec2.pc.in
+    ${CMAKE_CURRENT_BINARY_DIR}/codec2.pc
+    @ONLY
+)
+
+install(
+    FILES ${CMAKE_CURRENT_BINARY_DIR}/codec2.pc
+    DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
+    COMPONENT "codec2_devel"
+)
diff --git a/codec2/branches/0.7/COPYING b/codec2/branches/0.7/COPYING
new file mode 100644 (file)
index 0000000..cc40a46
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, see 
+    <http://www.gnu.org/licenses/>. 
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/codec2/branches/0.7/INSTALL b/codec2/branches/0.7/INSTALL
new file mode 100644 (file)
index 0000000..bcdcf4c
--- /dev/null
@@ -0,0 +1,52 @@
+==========================
+ Building and Installing
+==========================
+
+NOTES:
+  - Builds against system libraries by default.
+  - Has NSIS packaing support for Windows (WIN32) targets. *nix systems should
+    rely on 'make install' as the packages (RPM & DEB) created by CPack are
+    questionable.
+
+To compile codec2, the packages build-essential and cmake are required.
+If they are not installed, at a command prompt, type
+
+$ sudo apt-get install build-essential cmake 
+
+To test the cmake build make a directory anywhere underneath (or outside of)
+the source directory.
+
+Linux command line example:
+
+$ cd /path/to/codec2
+$ mkdir build_linux
+$ cd build_linux
+$ cmake ../ 
+
+Install prefix defaults to /usr/local, use CMAKE_INSTALL_PREFIX to override.
+
+(if no errors)
+$ make
+(as root)
+$ make install
+
+=====================
+ Windows
+=====================
+
+Unlike FreeDV (fdmdv2), codec2 is not currently provided as a separate
+installer, instead the windows version uses a static build of codec2.
+
+Additionally, while MSYS2+MinGW should work, windows builds are produces by 
+cross compiling from linux.
+
+Install MinGW & the mysys shell
+   + pwd -W prints true Win32 directory
+   + I also installed emacs, "tortise svn", and "cmake", and built and installed speex
+
+$ cd codec2-dev
+$ mkdir build_win32
+$ cd build_win32
+$ cmake -DSPEEXDSP_INCLUDE_DIR=/usr/local/include/ -G "MSYS Makefiles" ..
+$ make
+$ make package
diff --git a/codec2/branches/0.7/README b/codec2/branches/0.7/README
new file mode 100644 (file)
index 0000000..7f9d831
--- /dev/null
@@ -0,0 +1,157 @@
+Codec 2 README
+--------------
+
+Codec 2 is an open source (LGPL 2.1) low bit rate speech codec:
+
+    http://rowetel.com/codec2.html
+
+Also included:
+
+  + FDMDV modem (README_fdmdv.txt) for HF channels
+  + Coherent PSK (cohpsk) for HF channels
+  + FSK modem (README_fsk.txt) for VHF channels
+  + an OFDM modem for HF channels (ofdm)
+  + the FreeDV API - a library for embedding FreeDV in other programs
+
+SVN Repository
+--------------
+
+Check out the latest (development branch) code using:
+
+  $ svn co https://svn.code.sf.net/p/freetel/code/codec2-dev codec2-dev
+
+There are unauthorised 3rd party GIT mirrors of Codec 2.
+
+  GIT IS NOT SUPPORTED!!!
+
+All patches, support questions etc, need to be against the SVN
+repository above.
+
+Quickstart
+----------
+
+Also see INSTALL for more general building and installing instructions. 
+
+1/ Listen to Codec 2:
+
+   $ cd codec2-dev
+   $ mkdir build_linux
+   $ cd build_linux
+   $ cmake ..
+   $ make
+   $ ./src/c2demo ../raw/hts1a.raw hts1a_c2.raw
+   $ play -t raw -r 8000 -e signed-integer -b 16 ../raw/hts1a.raw
+   $ play -t raw -r 8000 -e signed-integer -b 16 ./hts1a_c2.raw
+
+2/ Compress, Decompress and then play a file:
+
+   using 2400 bps bit rate encoding
+
+   $ ./src/c2enc 2400 ../raw/hts1a.raw hts1a_c2.bit
+   $ ./src/c2dec 2400 hts1a_c2.bit hts1a_c2_2400.raw 
+
+   which can be played with
+
+   $ play -t raw -r 8000 -e signed-integer -b 16 ./hts1a_c2_2400.raw
+
+   using 700 bps bit rate encoding
+
+   $ ./src/c2enc 700 ../raw/hts1a.raw hts1a_c2.bit
+   $ ./src/c2dec 700 hts1a_c2.bit hts1a_c2_700.raw
+
+   which can be played with
+
+   $ play -t raw -r 8000 -e signed-integer -b 16 ./hts1a_c2_700.raw
+
+3/ Same thing with pipes:
+
+   $ ./src/c2enc 1300 ../raw/hts1a.raw - | ./src/c2dec 1300 - - | play -t raw -r 8000 -s -2 -
+
+Embedded FreeDV API
+-------------------
+
+See freedv_api.h and freedv_api.c, and the demo programs freedv_tx &
+freedv_rx.  Quickstart:
+
+  $ ./freedv_tx 1600 ../../raw/hts1.raw - | ./freedv_rx 1600 - - | play -t raw -r 8000 -s -2 -q -
+  $ cat freedv_rx_log.txt
+
+Programs
+--------
+1/ c2demo encodes a file of speech samples, then decodes them and
+saves the result.
+
+2/ c2enc encodes a file of speech samples to a compressed file of
+encoded bits.
+
+3/ c2dec decodes a compressed file of bits to a file of speech
+samples.
+
+4/ c2sim is a simulation/development version of Codec 2.  It allows
+selective use of the various Codec 2 algorithms.  For example
+switching phase modelling or LSP quantisation on and off.
+
+Debugging
+---------
+
+1/ To compile with debug symbols for using gdb:
+
+  $ cd ~/codec2
+  $ rm -Rf build_linux && mkdir build_linux
+  $ cd build_linux
+  $ CFLAGS=-g cmake ..
+  $ make
+
+2/ For dump file support:
+
+  $ cd ~/codec2
+  $ rm -Rf build_linux && mkdir build_linux
+  $ cd build_linux
+  $ CFLAGS=-DDUMP cmake ..
+  $ make
+
+Building Unit Tests
+-------------------
+
+The unittests are no longer built by default.  They require
+libsamplerate and Speex.
+
+To build them:
+
+  $ cd ~/codec2
+  $ rm -Rf build_linux && mkdir build_linux
+  $ cd build_linux
+  $ cmake -DCMAKE_BUILD_TYPE=Debug ..
+  $ make
+
+Directories
+-----------
+
+  cmake       - cmake support files
+  octave      - Octave scripts used to support development
+  script      - shell scripts for playing and converting raw files
+  src         - C source code for Codec 2, FDMDV modem, COHPSK modem, FreeDV API
+  raw         - speech files in raw format (16 bits signed linear 8 kHz)
+  stm32       - STM32F4 microcontroller and SM1000 FreeDV Adaptor
+  unittest    - unit test source code
+  wav         - speech files in wave file format
+
+Octave Packages
+---------------
+
+To run the Octave scripts the following libraries are required:
+
+Package Name  | Version | Installation directory
+--------------+---------+-----------------------
+     control *|   2.6.2 | /usr/share/octave/packages/control-2.6.2
+     general *|   1.3.4 | /usr/share/octave/packages/general-1.3.4
+    parallel *|   2.2.0 | /usr/share/octave/packages/parallel-2.2.0
+        plot *|   1.1.0 | /usr/share/octave/packages/plot-1.1.0
+      signal *|   1.2.2 | /usr/share/octave/packages/signal-1.2.2
+     specfun *|   1.1.0 | /usr/share/octave/packages/specfun-1.1.0
+
+These can be installed using your systems package management system or
+the Octave package management system.  The version number of each
+package is not important.
+
diff --git a/codec2/branches/0.7/README_fdmdv.txt b/codec2/branches/0.7/README_fdmdv.txt
new file mode 100644 (file)
index 0000000..eb0c0df
--- /dev/null
@@ -0,0 +1,201 @@
+
+README_fdmdv.txt
+David Rowe
+Created March 2012
+
+Introduction
+------------
+
+A 1400 bit/s (nominal) Frequency Division Multiplexed Digital Voice
+(FDMDV) modem based on [1].  Used for digital audio over HF SSB.
+
+The FDMDV modem was first implemented in GNU Octave, then ported to C.
+Algorithm development is generally easier in Octave, but for real time
+work we need the C version.  Automated units tests ensure the
+operation of the Octave and C versions are identical.
+
+Quickstart
+----------
+
+Built as part of codec2-dev, see README for build instructions.
+
+1. Generate some test bits and modulate them:
+
+    $ ./fdmdv_get_test_bits test.c2 1400
+    $ ./fdmdv_mod test.c2 test.raw
+    $ play -r 8000 -s -2 test.raw
+
+2. Two seconds of test frame data modulated and sent out of sound device:
+
+    $ ./fdmdv_get_test_bits - 2800 | ./fdmdv_mod - - | play -t raw -r 8000 -s -2 -
+
+3. Send 14000 modulated bits (10 seconds) to the demod and count errors:
+
+    $  ./fdmdv_get_test_bits - 14000 | ./fdmdv_mod - - | ./fdmdv_demod - - 14 demod_dump.txt | ./fdmdv_put_test_bits -
+
+    Use Octave to look at plots of 1 second (1400 bits) of modem operation:
+
+    $ cd ../octave
+    $ octave
+    octave:1> fdmdv_demod_c("../src/demod_dump.txt",1400)
+
+4. Run Octave simulation of entire modem and AWGN channel:
+
+    $ cd ../octave
+    $ octave
+    octave:1> fdmdv_ut
+
+5. NOTE: If you would like to play modem samples over the air please
+   convert the 8 kHz samples to 48 kHz.  Many PC sound cards have
+   wildly inaccurate sample clock rates when set to 8 kHz, but seem to
+   perform OK when set for 48 kHz.  If playing and recording files you
+   can use the sox utility:
+
+   $ sox -r 8000 -s -2 modem_sample_8kHz.raw -r 48000 modem_sample_48kHz.wav
+
+   For real time applications, the fdmdv.[ch] library includes functions to
+   convert between 48 and 8 kHz sample rates.
+
+6. Send 20 seconds at 2000 bit/s (20 carriers) to demod and count errors:
+
+   $ ./fdmdv_get_test_bits - 20000 20 | ./fdmdv_mod - - 20 | ./fdmdv_demod - - 20 | ./fdmdv_put_test_bits - 20
+
+References
+----------
+
+[1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf
+[2] http://n1su.com/fdmdv/
+[3] http://www.rowetel.com/blog/?p=2433 "Testing a FDMDV Modem"
+[4] http://www.rowetel.com/blog/?p=2458 "FDMDV Modem Page" on David's web site
+
+C Code
+------
+
+src/fdmdv_mod.c - C version of modulator that takes a file of bits and
+                  converts it to a raw file of modulated samples.
+
+src/fdmdv_demod.c - C version of demodulator that takes a raw file of
+                    modulated samples and outputs a file of bits.
+                    Optionally dumps demod states to a text file which
+                    can be plotted using the Octave script
+                    fdmdv_demod_c.m
+
+src/fdmdv.h - Header file that exposes FDMDV C API functions.  Include
+              this file in your application program.
+
+src/fdmdv.c - C functions that implement the FDMDV modem.
+
+src/fdmdv-internal.h - internal states and constants for FDMDV modem,
+                       shouldn't be exposed to application program.
+
+
+unittest/tfdmdv.c - Used to conjunction with unittest/tfdmdv.m to
+                    automatically test C FDMDV functions against
+                    Octave versions.
+
+Octave Scripts
+--------------
+
+(Note these require some Octave packages to be installed, see
+octave/README.txt).
+
+fdmdv.m - Functions and variables that implement the Octave version of
+          the FDMDV modem.
+
+fdmdv_ut.m - Unit test for fdmdv Octave code, useful while
+             developing algorithm.  Includes tx/rx plus basic channel
+             simulation.
+
+             Typical run:
+
+               octave:6> fdmdv_ut
+               Eb/No (meas): 7.30 (8.29) dB
+               bits........: 2464
+               errors......: 20
+               BER.........: 0.0081
+               PAPR........: 13.54 dB
+               SNR.........: 4.0 dB
+
+               It also outputs lots of nice plots that show the
+              operation of the modem.
+
+               For a 1400 bit/s DQPSK modem we expect about 1% BER for
+               Eb/No = 7.3dB, which corresponds to SNR = 4dB (3kHz
+               noise BW). The extra dB of measured power is due to the
+               DBPSK pilot. Currently the noise generation code
+               doesn't take the pilot power into account, so in this
+               example the real SNR is actually 5dB.
+
+fdmdv_mod.m - Octave version of modulator that outputs a raw file.
+              The modulator is driven by a test frame of bits.  This
+              can then be played over a real channel or through a
+              channel simulator like PathSim.  The sample rate can be
+              changed using "sox" to simulate differences in tx/rx
+              sample clocks.
+
+             To generate 10 seconds of modulated signal:
+
+                octave:8> fdmdv_mod("test.raw",1400*10);
+
+fdmdv_demod.m - Demodulator program that takes a raw file as input,
+                and works out the bit error rate using the known test
+                frame.  Can be used to test the demod performs with
+                off-air signals, or signals that have been passed
+                through a channel simulator.
+
+               To demodulate 2 seconds of the test.raw file generated
+               above:
+
+                octave:9> fdmdv_demod("test.raw",1400*2);
+                2464 bits  0 errors  BER: 0.0000
+
+                It also produces several plots showing the internal
+               states of the demod.  Useful for debugging and
+               observing what happens with various channels.
+
+fdmdv_demod_c.m - Takes an output text file from the C demod
+                  fdmdv_demod.c and produces plots and measures BER.
+                  Useful for evaluating fdmdv_demod.c performance.
+                  The plots produced are identical to the Octave
+                  version fdmdv_demod.m, allowing direct comparison of
+                  the C and Octave versions.
+
+tfdmdv.m - Automatic tests that compare the Octave and C versions of
+           the FDMDV modem functions.  First run unittest/tfdmdv, this
+           will generate a text file with test vectors from the C
+           version.  Then run the Octave script tfdmdv and it will
+           generate Octave versions of the test vectors and compare
+           each vector with the C equivalent.  Its plots the vectors
+           and and errors (green).  Its also produces an automatic
+           check list based on test results.  If the Octave or C modem
+           code is changed, this script should be used to ensure the
+           C and Octave versions remain identical.
+
+Modelling sample clock errors using sox
+---------------------------------------
+
+This introduces a simulated 1000ppm error:
+
+  sox -r 8000 -s -2 mod_dqpsk.raw -s -2 mod_dqpsk_8008hz.raw rate -h 8008
+
+TODO
+----
+
+[ ] implement ppm measurements in fdmdv_get_demod_stats()
+[ ] try interfering sine wave
+    + maybe swept
+    + does modem fall over?
+[ ] try non-flat channel, e.g. 3dB difference between hi and low tones
+    + make sure all estimators keep working
+[ ] test rx level sensitivity, i.e. 0 to 20dB attenuation
+[ ] make fine freq indep of amplitude
+    + use angle rather than imag coord
+[ ] document use of fdmdv_ut and fdmdv_demod + PathSim
+[ ] more positive form of sync reqd for DV frames?
+    + like using coarse_fine==1 to decode valid DV frame bit?
+    + when should we start decoding?
+[ ] more robust track/acquite state machine?
+    + e.g. hang on thru the fades?
+[ ] PAPR idea
+    + automatically tweak phases to reduce PAPR, e.g. slow variations in freq...
+[ ] why is pilot noise_est twice as big as other carriers
diff --git a/codec2/branches/0.7/README_fsk.txt b/codec2/branches/0.7/README_fsk.txt
new file mode 100644 (file)
index 0000000..4638566
--- /dev/null
@@ -0,0 +1,82 @@
+
+README_fsk.txt
+David Rowe
+Created Jan 2016
+
+A FSK modem with a non-coherent demodulator.  Performance is within a
+fraction of a dB of ideal.  The demodulator automagically estimates
+the tone frequencies and tracks frequency drift.
+
+Credits
+-------
+
+The Octave version of the modem was developed by David Rowe.  Brady
+O'Brien ported the modem to C, and wrote the C/Octave tests.
+
+Quickstart
+----------
+
+Built as part of codec2-dev, see README for build instructions.
+
+1. Using 1000 test bits, generate 2FSK using a 8000 Hz sample rate, at
+   100 symbols/s (== 100 bit/s for 2FSK), with two frequencies of 1200
+   and 2400 Hz, and stream via stdout to "play" out speaker:
+    
+    $ cd build_linux/src
+    $ ./fsk_get_test_bits - 1000 | ./fsk_mod 2 8000 100 1200 1200 - - | play -t raw -r 8000 -s -2 -
+
+    The low tone frequency is 1200Hz, and the upper tone 1200 + 1200 = 2400Hz.
+
+2. Measure the bit error rate over 10,000 bits of 100 bit/s 2FSK:
+
+    $ ./fsk_get_test_bits - 10000 | ./fsk_mod 2 8000 100 1200 100 - - | ./fsk_demod -l 2 8000 100 - - | ./fsk_put_test_bits -
+    FSK BER 0.000000, bits tested 9800, bit errors 0
+
+    In this example the two tones are at 1200 and 1200+100 = 1300Hz.
+    A shift of 100Hz is the minimum possible for an incoherent FSK
+    demodulator that is running at 100 symbols/s. Note that -l or --lbr
+    initalizes the demodulator in 'low bit rate' mode. In low bit rate
+    mode, incoming samples are processed in 1 second chunks, giving a 
+    very wide window for frequency and timing estimaton. Low speed mode
+    is well suited to applications that can tolerate long latency, such
+    as balloon telemetry.
+
+    The demod and test frame logic takes a few frames to sync up, so
+    although we sent 10,000 bits, only 9800 are received.  However
+    there were no errors in those received bits.
+
+3. Measure the bit error rate of 5000 bits at 1200 bits/s, using a
+   sample rate of 9600 Hz:
+
+    $ ./fsk_get_test_bits - 5000 | ./fsk_mod 2 9600 1200 1200 1200 - - | ./fsk_demod -p 8 2 9600 1200 - - | ./fsk_put_test_bits -
+    FSK BER 0.000000, bits tested 4900, bit errors 0
+
+    In this example, the -l and --lbr options are left out setting the modem
+    up in "high speed" mode. In this mode, the demodulator operates on blocks of
+    24 symbols at a time. In modes with a higher bitrate, this allows the modem
+    to operate with a much lower bit rate. High speed mode is well suited to 
+    applications without much tolerance for latency or with limited processing
+    power and memory, such as PTT digital voice.
+    
+    In this example, the -p (or --conv) option is used. This specifies the
+    downconverted symbol size. The symbol period (Ts) must be divisible by
+    the supplied P parameter. In this case, Fs is 9600 and Rs is 1200, so Ts
+    is Fs/Rs, which is 8. In this case, 8 is the maximum P value allowed, 
+    though 4 and 2 would also work. If P is not divisible by Ts, a failed
+    assert will fire and fsk_demod will exit. If -p is not supplied, it 
+    will default to match Ts. In general, lower values of P result in less
+    memory use and CPU time spend, but may result in worse modem preformance.
+    P should be left alone unless CPU and memory usage needs to be lowered
+    for the application.
+
+    (TODO, make this easier to understand, perhaps with figure)
+
+4.  (TODO High bit rate example like 115k project Horus)
+
+5. Automatically check C implementation against Octave using a variety of test conditions and 
+   channel impairments.
+
+    $ cd octave
+    $ octave
+    octave:1> tfsk
+
diff --git a/codec2/branches/0.7/cmake/GetDependencies.cmake.in b/codec2/branches/0.7/cmake/GetDependencies.cmake.in
new file mode 100644 (file)
index 0000000..0d25f67
--- /dev/null
@@ -0,0 +1,24 @@
+# As this script is run in a new cmake instance, it does not have access to
+# the existing cache variables. Pass them in via the configure_file command.
+set(CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@)
+set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@)
+set(UNIX @UNIX@)
+set(WIN32 @WIN32@)
+set(CMAKE_CROSSCOMPILING @CMAKE_CROSSCOMPILING@)
+set(CMAKE_FIND_LIBRARY_SUFFIXES @CMAKE_FIND_LIBRARY_SUFFIXES@)
+set(CMAKE_FIND_LIBRARY_PREFIXES @CMAKE_FIND_LIBRARY_PREFIXES@)
+set(CMAKE_SYSTEM_LIBRARY_PATH @CMAKE_SYSTEM_LIBRARY_PATH@)
+set(CMAKE_FIND_ROOT_PATH @CMAKE_FIND_ROOT_PATH@)
+set(CODEC2_DLL ${CMAKE_BINARY_DIR}/src/libcodec2.dll)
+
+include(${CMAKE_SOURCE_DIR}/cmake/GetPrerequisites.cmake)
+get_prerequisites(${CODEC2_DLL} _deps 1 0 "" "")
+foreach(_runtime ${_deps})
+    message("Looking for ${_runtime}")
+    find_library(RUNTIME_${_runtime} ${_runtime})
+    message("${RUNTIME_${_runtime}}")
+    if(RUNTIME_${_runtime})
+        file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
+        TYPE EXECUTABLE FILES "${RUNTIME_${_runtime}}")
+    endif()
+endforeach()
diff --git a/codec2/branches/0.7/cmake/config.h.in b/codec2/branches/0.7/cmake/config.h.in
new file mode 100644 (file)
index 0000000..60ee7d6
--- /dev/null
@@ -0,0 +1,23 @@
+/*--------------------------------------------------------------------------
+ ** This file is autogenerated from config.h.in 
+ ** during the cmake configuration of your project. If you need to make changes
+ ** edit the original file NOT THIS FILE.
+ ** --------------------------------------------------------------------------*/
+#ifndef _CONFIGURATION_HEADER_GUARD_H_
+#define _CONFIGURATION_HEADER_GUARD_H_
+
+#define SIZEOF_INT @SIZEOF_INT@
+#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@
+#cmakedefine HAVE_STRING_H @HAVE_STRING_H@
+#cmakedefine HAVE_FLOOR    @HAVE_FLOOR@
+#cmakedefine HAVE_CEIL     @HAVE_CEIL@
+#cmakedefine HAVE_MEMSET   @HAVE_MEMSET@
+#cmakedefine HAVE_POW      @HAVE_POW@
+#cmakedefine HAVE_SQRT     @HAVE_SQRT@
+#cmakedefine HAVE_SIN      @HAVE_SIN@
+#cmakedefine HAVE_COS      @HAVE_COS@
+#cmakedefine HAVE_ATAN2    @HAVE_ATAN2@
+#cmakedefine HAVE_LOG10    @HAVE_LOG10@
+#cmakedefine HAVE_ROUND    @HAVE_ROUND@
+#cmakedefine HAVE_GETOPT   @HAVE_GETOPT@
+#endif
diff --git a/codec2/branches/0.7/codec2.pc.in b/codec2/branches/0.7/codec2.pc.in
new file mode 100644 (file)
index 0000000..deb9dd0
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_LIBDIR@
+includedir=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_INCLUDEDIR@/
+
+Name: codec2
+Description: A speech codec for 2400 bit/s and below
+Requires: 
+Version: @CODEC2_VERSION@
+Libs: -L${libdir} -lcodec2
+Cflags: -I${includedir} 
diff --git a/codec2/branches/0.7/debian/changelog b/codec2/branches/0.7/debian/changelog
new file mode 100644 (file)
index 0000000..214efcf
--- /dev/null
@@ -0,0 +1,5 @@
+codec2 (0.4-150830) unstable; urgency=low
+
+  * Subversion snapshot of tag 0.4.
+
+ -- Stuart Longland <stuartl@longlandclan.yi.org>  Sun, 30 Aug 2015 08:57:09 +1000
diff --git a/codec2/branches/0.7/debian/codec2.doc-base.EX b/codec2/branches/0.7/debian/codec2.doc-base.EX
new file mode 100644 (file)
index 0000000..5836087
--- /dev/null
@@ -0,0 +1,20 @@
+Document: codec2
+Title: Debian codec2 Manual
+Author: <insert document author here>
+Abstract: This manual describes what codec2 is
+ and how it can be used to
+ manage online manuals on Debian systems.
+Section: unknown
+
+Format: debiandoc-sgml
+Files: /usr/share/doc/codec2/codec2.sgml.gz
+
+Format: postscript
+Files: /usr/share/doc/codec2/codec2.ps.gz
+
+Format: text
+Files: /usr/share/doc/codec2/codec2.text.gz
+
+Format: HTML
+Index: /usr/share/doc/codec2/html/index.html
+Files: /usr/share/doc/codec2/html/*.html
diff --git a/codec2/branches/0.7/debian/codec2.install b/codec2/branches/0.7/debian/codec2.install
new file mode 100644 (file)
index 0000000..1df36c6
--- /dev/null
@@ -0,0 +1 @@
+usr/bin/*
diff --git a/codec2/branches/0.7/debian/codec21.dirs b/codec2/branches/0.7/debian/codec21.dirs
new file mode 100644 (file)
index 0000000..6845771
--- /dev/null
@@ -0,0 +1 @@
+usr/lib
diff --git a/codec2/branches/0.7/debian/codec21.install b/codec2/branches/0.7/debian/codec21.install
new file mode 100644 (file)
index 0000000..d0dbfd1
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/lib*.so.*
diff --git a/codec2/branches/0.7/debian/compat b/codec2/branches/0.7/debian/compat
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/codec2/branches/0.7/debian/control b/codec2/branches/0.7/debian/control
new file mode 100644 (file)
index 0000000..de9aa3b
--- /dev/null
@@ -0,0 +1,36 @@
+Source: codec2
+Priority: optional
+Maintainer: Stuart Longland <stuartl@longlandclan.yi.org>
+Build-Depends: debhelper (>= 9), cmake, libspeexdsp-dev
+Standards-Version: 3.9.5
+Section: libs
+Homepage: http://www.freedv.org
+
+Package: libcodec2-dev
+Section: libdevel
+Architecture: any
+Depends: libcodec2 (= ${binary:Version}), ${misc:Depends}
+Description: Codec 2: ultra-low bitrate voice codec.  Headers.
+ Codec 2 is an ultra-low bitrate (sub 4kbps) voice codec
+ for use in radio frequency communications applications.
+ .
+ This package provides the headers.
+
+Package: libcodec2
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libspeexdsp1
+Description: Codec 2: ultra-low bitrate voice codec.  Library.
+ Codec 2 is an ultra-low bitrate (sub 4kbps) voice codec
+ for use in radio frequency communications applications.
+ .
+ This package provides the runtime library.
+
+Package: codec2
+Architecture: any
+Depends: libcodec2 (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends}
+Description: Codec 2: ultra-low bitrate voice codec.  Utilities.
+ Codec 2 is an ultra-low bitrate (sub 4kbps) voice codec
+ for use in radio frequency communications applications.
+ .
+ This package provides some command line utilities for encoding
+ and decoding codec2.
diff --git a/codec2/branches/0.7/debian/copyright b/codec2/branches/0.7/debian/copyright
new file mode 100644 (file)
index 0000000..598dd85
--- /dev/null
@@ -0,0 +1,38 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: codec2
+Source: <url://example.com>
+
+Files: *
+Copyright: <years> <put author's name and email here>
+           <years> <likewise for another author>
+License: <special license>
+ <Put the license of the package here indented by 1 space>
+ <This follows the format of Description: lines in control file>
+ .
+ <Including paragraphs>
+
+# If you want to use GPL v2 or later for the /debian/* files use 
+# the following clauses, or change it to suit. Delete these two lines
+Files: debian/*
+Copyright: 2015 unknown <stuartl@unknown>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid to pick license terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/codec2/branches/0.7/debian/docs b/codec2/branches/0.7/debian/docs
new file mode 100644 (file)
index 0000000..8e229a3
--- /dev/null
@@ -0,0 +1,6 @@
+NEWS
+README
+README_fdmdv.txt
+AUTHORS
+ChangeLog
+INSTALL
diff --git a/codec2/branches/0.7/debian/libcodec2-dev.dirs b/codec2/branches/0.7/debian/libcodec2-dev.dirs
new file mode 100644 (file)
index 0000000..4418816
--- /dev/null
@@ -0,0 +1,2 @@
+usr/lib
+usr/include
diff --git a/codec2/branches/0.7/debian/libcodec2-dev.install b/codec2/branches/0.7/debian/libcodec2-dev.install
new file mode 100644 (file)
index 0000000..41a1414
--- /dev/null
@@ -0,0 +1 @@
+usr/include/*
diff --git a/codec2/branches/0.7/debian/libcodec2.install b/codec2/branches/0.7/debian/libcodec2.install
new file mode 100644 (file)
index 0000000..f1d0181
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/*
diff --git a/codec2/branches/0.7/debian/rules b/codec2/branches/0.7/debian/rules
new file mode 100755 (executable)
index 0000000..c6cdbe7
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/make -f
+# See debhelper(7) (uncomment to enable)
+# output every command that modifies files on the build system.
+#DH_VERBOSE = 1
+
+# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/default.mk
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
+# package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+
+# main packaging script based on dh7 syntax
+%:
+       dh $@ --buildsystem=cmake
+
+
diff --git a/codec2/branches/0.7/debian/source/format b/codec2/branches/0.7/debian/source/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/codec2/branches/0.7/octave/2400ab_frame_design.ods b/codec2/branches/0.7/octave/2400ab_frame_design.ods
new file mode 100644 (file)
index 0000000..015fc6b
Binary files /dev/null and b/codec2/branches/0.7/octave/2400ab_frame_design.ods differ
diff --git a/codec2/branches/0.7/octave/H2064_516_sparse.mat b/codec2/branches/0.7/octave/H2064_516_sparse.mat
new file mode 100644 (file)
index 0000000..e684c2e
--- /dev/null
@@ -0,0 +1,7231 @@
+# Created by Octave 3.8.1, Wed Mar 23 13:59:47 2016 ACDT <bill@hereford2>
+# name: HRA
+# type: sparse matrix
+# nnz: 7223
+# rows: 516
+# columns: 2580
+208 1 1
+296 1 1
+368 1 1
+242 2 1
+323 2 1
+362 2 1
+84 3 1
+150 3 1
+437 3 1
+114 4 1
+211 4 1
+409 4 1
+314 5 1
+361 5 1
+372 5 1
+135 6 1
+261 6 1
+270 6 1
+349 7 1
+422 7 1
+481 7 1
+90 8 1
+167 8 1
+300 8 1
+64 9 1
+212 9 1
+407 9 1
+57 10 1
+195 10 1
+253 10 1
+26 11 1
+50 11 1
+55 11 1
+52 12 1
+317 12 1
+488 12 1
+16 13 1
+406 13 1
+487 13 1
+142 14 1
+372 14 1
+470 14 1
+120 15 1
+360 15 1
+429 15 1
+244 16 1
+314 16 1
+431 16 1
+167 17 1
+399 17 1
+402 17 1
+164 18 1
+203 18 1
+259 18 1
+133 19 1
+136 19 1
+404 19 1
+179 20 1
+211 20 1
+257 20 1
+22 21 1
+56 21 1
+101 21 1
+180 22 1
+195 22 1
+243 22 1
+413 23 1
+436 23 1
+463 23 1
+161 24 1
+229 24 1
+487 24 1
+224 25 1
+489 25 1
+514 25 1
+121 26 1
+295 26 1
+496 26 1
+57 27 1
+101 27 1
+150 27 1
+22 28 1
+109 28 1
+358 28 1
+394 29 1
+487 29 1
+504 29 1
+17 30 1
+184 30 1
+234 30 1
+9 31 1
+87 31 1
+490 31 1
+54 32 1
+279 32 1
+511 32 1
+84 33 1
+233 33 1
+240 33 1
+20 34 1
+399 34 1
+415 34 1
+98 35 1
+176 35 1
+412 35 1
+311 36 1
+470 36 1
+484 36 1
+322 37 1
+433 37 1
+490 37 1
+308 38 1
+364 38 1
+416 38 1
+86 39 1
+197 39 1
+252 39 1
+91 40 1
+115 40 1
+472 40 1
+77 41 1
+194 41 1
+489 41 1
+41 42 1
+314 42 1
+478 42 1
+110 43 1
+423 43 1
+493 43 1
+192 44 1
+246 44 1
+381 44 1
+18 45 1
+98 45 1
+139 45 1
+11 46 1
+401 46 1
+480 46 1
+210 47 1
+291 47 1
+511 47 1
+133 48 1
+268 48 1
+362 48 1
+248 49 1
+272 49 1
+293 49 1
+276 50 1
+357 50 1
+466 50 1
+389 51 1
+458 51 1
+503 51 1
+100 52 1
+298 52 1
+359 52 1
+37 53 1
+327 53 1
+342 53 1
+4 54 1
+21 54 1
+142 54 1
+239 55 1
+298 55 1
+326 55 1
+15 56 1
+299 56 1
+369 56 1
+32 57 1
+225 57 1
+304 57 1
+15 58 1
+220 58 1
+320 58 1
+7 59 1
+272 59 1
+364 59 1
+10 60 1
+51 60 1
+486 60 1
+109 61 1
+177 61 1
+261 61 1
+82 62 1
+93 62 1
+105 62 1
+19 63 1
+84 63 1
+316 63 1
+50 64 1
+403 64 1
+471 64 1
+137 65 1
+150 65 1
+476 65 1
+278 66 1
+336 66 1
+430 66 1
+43 67 1
+275 67 1
+460 67 1
+181 68 1
+236 68 1
+379 68 1
+89 69 1
+476 69 1
+484 69 1
+206 70 1
+243 70 1
+253 70 1
+113 71 1
+261 71 1
+446 71 1
+285 72 1
+373 72 1
+400 72 1
+10 73 1
+330 73 1
+447 73 1
+95 74 1
+248 74 1
+373 74 1
+12 75 1
+310 75 1
+472 75 1
+180 76 1
+365 76 1
+490 76 1
+23 77 1
+155 77 1
+272 77 1
+93 78 1
+240 78 1
+401 78 1
+100 79 1
+144 79 1
+158 79 1
+124 80 1
+276 80 1
+471 80 1
+200 81 1
+229 81 1
+328 81 1
+130 82 1
+292 82 1
+417 82 1
+81 83 1
+99 83 1
+312 83 1
+149 84 1
+175 84 1
+344 84 1
+6 85 1
+101 85 1
+331 85 1
+251 86 1
+317 86 1
+429 86 1
+181 87 1
+365 87 1
+383 87 1
+227 88 1
+297 88 1
+341 88 1
+156 89 1
+404 89 1
+501 89 1
+215 90 1
+260 90 1
+361 90 1
+194 91 1
+333 91 1
+410 91 1
+284 92 1
+417 92 1
+480 92 1
+206 93 1
+462 93 1
+477 93 1
+177 94 1
+434 94 1
+492 94 1
+171 95 1
+474 95 1
+508 95 1
+174 96 1
+444 96 1
+482 96 1
+40 97 1
+119 97 1
+332 97 1
+136 98 1
+309 98 1
+336 98 1
+187 99 1
+261 99 1
+429 99 1
+89 100 1
+260 100 1
+310 100 1
+98 101 1
+344 101 1
+369 101 1
+156 102 1
+435 102 1
+460 102 1
+44 103 1
+80 103 1
+291 103 1
+30 104 1
+123 104 1
+346 104 1
+48 105 1
+257 105 1
+365 105 1
+78 106 1
+183 106 1
+392 106 1
+349 107 1
+358 107 1
+402 107 1
+126 108 1
+197 108 1
+452 108 1
+56 109 1
+78 109 1
+120 109 1
+3 110 1
+16 110 1
+430 110 1
+212 111 1
+264 111 1
+301 111 1
+43 112 1
+260 112 1
+419 112 1
+111 113 1
+459 113 1
+462 113 1
+183 114 1
+195 114 1
+406 114 1
+63 115 1
+390 115 1
+410 115 1
+54 116 1
+147 116 1
+342 116 1
+35 117 1
+217 117 1
+493 117 1
+63 118 1
+467 118 1
+500 118 1
+333 119 1
+353 119 1
+390 119 1
+158 120 1
+165 120 1
+498 120 1
+96 121 1
+120 121 1
+378 121 1
+100 122 1
+151 122 1
+230 122 1
+270 123 1
+335 123 1
+403 123 1
+38 124 1
+83 124 1
+188 124 1
+97 125 1
+106 125 1
+443 125 1
+4 126 1
+28 126 1
+258 126 1
+139 127 1
+326 127 1
+505 127 1
+163 128 1
+252 128 1
+499 128 1
+67 129 1
+70 129 1
+148 129 1
+251 130 1
+298 130 1
+508 130 1
+139 131 1
+182 131 1
+485 131 1
+42 132 1
+153 132 1
+241 132 1
+214 133 1
+300 133 1
+382 133 1
+117 134 1
+260 134 1
+289 134 1
+26 135 1
+122 135 1
+264 135 1
+98 136 1
+111 136 1
+182 136 1
+132 137 1
+143 137 1
+455 137 1
+105 138 1
+302 138 1
+481 138 1
+13 139 1
+135 139 1
+264 139 1
+61 140 1
+235 140 1
+451 140 1
+330 141 1
+362 141 1
+489 141 1
+223 142 1
+236 142 1
+483 142 1
+183 143 1
+232 143 1
+485 143 1
+95 144 1
+287 144 1
+365 144 1
+295 145 1
+371 145 1
+376 145 1
+95 146 1
+309 146 1
+447 146 1
+55 147 1
+248 147 1
+301 147 1
+29 148 1
+248 148 1
+382 148 1
+65 149 1
+176 149 1
+278 149 1
+35 150 1
+215 150 1
+237 150 1
+75 151 1
+169 151 1
+409 151 1
+130 152 1
+183 152 1
+285 152 1
+8 153 1
+155 153 1
+168 153 1
+98 154 1
+140 154 1
+292 154 1
+344 155 1
+446 155 1
+463 155 1
+46 156 1
+91 156 1
+290 156 1
+239 157 1
+277 157 1
+482 157 1
+155 158 1
+263 158 1
+339 158 1
+131 159 1
+234 159 1
+323 159 1
+75 160 1
+126 160 1
+376 160 1
+246 161 1
+376 161 1
+386 161 1
+3 162 1
+335 162 1
+495 162 1
+44 163 1
+162 163 1
+286 163 1
+260 164 1
+490 164 1
+502 164 1
+199 165 1
+398 165 1
+450 165 1
+21 166 1
+182 166 1
+322 166 1
+99 167 1
+105 167 1
+115 167 1
+118 168 1
+378 168 1
+390 168 1
+76 169 1
+469 169 1
+483 169 1
+8 170 1
+159 170 1
+370 170 1
+87 171 1
+119 171 1
+426 171 1
+271 172 1
+457 172 1
+461 172 1
+257 173 1
+292 173 1
+441 173 1
+171 174 1
+249 174 1
+406 174 1
+98 175 1
+108 175 1
+162 175 1
+44 176 1
+59 176 1
+73 176 1
+255 177 1
+451 177 1
+506 177 1
+17 178 1
+20 178 1
+256 178 1
+276 179 1
+362 179 1
+511 179 1
+91 180 1
+228 180 1
+507 180 1
+50 181 1
+57 181 1
+107 181 1
+21 182 1
+306 182 1
+498 182 1
+90 183 1
+459 183 1
+491 183 1
+262 184 1
+301 184 1
+323 184 1
+118 185 1
+208 185 1
+274 185 1
+208 186 1
+329 186 1
+478 186 1
+214 187 1
+357 187 1
+516 187 1
+35 188 1
+82 188 1
+337 188 1
+140 189 1
+396 189 1
+450 189 1
+159 190 1
+279 190 1
+304 190 1
+58 191 1
+137 191 1
+183 191 1
+277 192 1
+396 192 1
+502 192 1
+158 193 1
+272 193 1
+285 193 1
+180 194 1
+202 194 1
+249 194 1
+53 195 1
+396 195 1
+420 195 1
+93 196 1
+282 196 1
+427 196 1
+58 197 1
+120 197 1
+349 197 1
+264 198 1
+308 198 1
+386 198 1
+40 199 1
+389 199 1
+508 199 1
+98 200 1
+287 200 1
+353 200 1
+4 201 1
+43 201 1
+413 201 1
+284 202 1
+311 202 1
+500 202 1
+183 203 1
+371 203 1
+375 203 1
+24 204 1
+59 204 1
+304 204 1
+7 205 1
+326 205 1
+485 205 1
+123 206 1
+125 206 1
+410 206 1
+133 207 1
+223 207 1
+484 207 1
+57 208 1
+190 208 1
+306 208 1
+223 209 1
+285 209 1
+353 209 1
+124 210 1
+134 210 1
+431 210 1
+156 211 1
+348 211 1
+377 211 1
+202 212 1
+219 212 1
+239 212 1
+34 213 1
+74 213 1
+156 213 1
+324 214 1
+343 214 1
+438 214 1
+67 215 1
+72 215 1
+402 215 1
+452 216 1
+455 216 1
+499 216 1
+63 217 1
+367 217 1
+503 217 1
+123 218 1
+179 218 1
+200 218 1
+303 219 1
+368 219 1
+458 219 1
+303 220 1
+395 220 1
+419 220 1
+169 221 1
+267 221 1
+490 221 1
+40 222 1
+227 222 1
+230 222 1
+32 223 1
+59 223 1
+203 223 1
+24 224 1
+225 224 1
+397 224 1
+32 225 1
+65 225 1
+73 225 1
+5 226 1
+21 226 1
+436 226 1
+220 227 1
+300 227 1
+398 227 1
+218 228 1
+310 228 1
+326 228 1
+103 229 1
+266 229 1
+293 229 1
+222 230 1
+259 230 1
+363 230 1
+113 231 1
+362 231 1
+416 231 1
+111 232 1
+168 232 1
+497 232 1
+100 233 1
+104 233 1
+458 233 1
+30 234 1
+69 234 1
+250 234 1
+146 235 1
+344 235 1
+443 235 1
+266 236 1
+417 236 1
+460 236 1
+4 237 1
+47 237 1
+60 237 1
+195 238 1
+335 238 1
+476 238 1
+14 239 1
+103 239 1
+227 239 1
+55 240 1
+126 240 1
+392 240 1
+145 241 1
+394 241 1
+494 241 1
+37 242 1
+41 242 1
+352 242 1
+40 243 1
+122 243 1
+422 243 1
+18 244 1
+166 244 1
+383 244 1
+184 245 1
+313 245 1
+468 245 1
+188 246 1
+265 246 1
+344 246 1
+267 247 1
+438 247 1
+443 247 1
+38 248 1
+118 248 1
+199 248 1
+116 249 1
+265 249 1
+425 249 1
+35 250 1
+204 250 1
+417 250 1
+60 251 1
+316 251 1
+496 251 1
+53 252 1
+439 252 1
+452 252 1
+133 253 1
+142 253 1
+472 253 1
+58 254 1
+90 254 1
+396 254 1
+9 255 1
+180 255 1
+246 255 1
+296 256 1
+440 256 1
+449 256 1
+63 257 1
+281 257 1
+458 257 1
+57 258 1
+392 258 1
+395 258 1
+30 259 1
+312 259 1
+398 259 1
+17 260 1
+210 260 1
+283 260 1
+86 261 1
+137 261 1
+253 261 1
+157 262 1
+189 262 1
+391 262 1
+105 263 1
+240 263 1
+307 263 1
+29 264 1
+247 264 1
+268 264 1
+73 265 1
+240 265 1
+337 265 1
+285 266 1
+320 266 1
+501 266 1
+122 267 1
+251 267 1
+269 267 1
+9 268 1
+157 268 1
+499 268 1
+31 269 1
+324 269 1
+409 269 1
+199 270 1
+208 270 1
+408 270 1
+347 271 1
+415 271 1
+434 271 1
+73 272 1
+245 272 1
+365 272 1
+55 273 1
+180 273 1
+264 273 1
+135 274 1
+262 274 1
+407 274 1
+86 275 1
+94 275 1
+267 275 1
+2 276 1
+141 276 1
+150 276 1
+42 277 1
+191 277 1
+253 277 1
+67 278 1
+110 278 1
+254 278 1
+119 279 1
+165 279 1
+269 279 1
+21 280 1
+165 280 1
+185 280 1
+351 281 1
+361 281 1
+434 281 1
+35 282 1
+61 282 1
+306 282 1
+213 283 1
+488 283 1
+508 283 1
+173 284 1
+378 284 1
+510 284 1
+61 285 1
+138 285 1
+287 285 1
+176 286 1
+178 286 1
+347 286 1
+194 287 1
+229 287 1
+318 287 1
+109 288 1
+396 288 1
+439 288 1
+72 289 1
+157 289 1
+235 289 1
+77 290 1
+168 290 1
+307 290 1
+273 291 1
+397 291 1
+503 291 1
+133 292 1
+266 292 1
+281 292 1
+244 293 1
+289 293 1
+303 293 1
+90 294 1
+240 294 1
+468 294 1
+313 295 1
+347 295 1
+366 295 1
+220 296 1
+299 296 1
+415 296 1
+27 297 1
+84 297 1
+434 297 1
+192 298 1
+451 298 1
+480 298 1
+63 299 1
+133 299 1
+368 299 1
+299 300 1
+391 300 1
+497 300 1
+208 301 1
+469 301 1
+500 301 1
+202 302 1
+324 302 1
+504 302 1
+3 303 1
+137 303 1
+195 303 1
+66 304 1
+116 304 1
+188 304 1
+14 305 1
+60 305 1
+125 305 1
+19 306 1
+365 306 1
+502 306 1
+127 307 1
+207 307 1
+496 307 1
+68 308 1
+200 308 1
+475 308 1
+348 309 1
+472 309 1
+492 309 1
+246 310 1
+450 310 1
+481 310 1
+26 311 1
+428 311 1
+501 311 1
+87 312 1
+330 312 1
+407 312 1
+75 313 1
+139 313 1
+309 313 1
+20 314 1
+159 314 1
+302 314 1
+215 315 1
+223 315 1
+372 315 1
+93 316 1
+217 316 1
+442 316 1
+212 317 1
+330 317 1
+357 317 1
+180 318 1
+245 318 1
+464 318 1
+149 319 1
+234 319 1
+436 319 1
+114 320 1
+238 320 1
+249 320 1
+133 321 1
+418 321 1
+429 321 1
+48 322 1
+391 322 1
+493 322 1
+235 323 1
+367 323 1
+412 323 1
+17 324 1
+308 324 1
+340 324 1
+247 325 1
+291 325 1
+385 325 1
+257 326 1
+304 326 1
+489 326 1
+42 327 1
+67 327 1
+172 327 1
+149 328 1
+244 328 1
+353 328 1
+57 329 1
+288 329 1
+322 329 1
+363 330 1
+382 330 1
+477 330 1
+75 331 1
+130 331 1
+439 331 1
+334 332 1
+461 332 1
+509 332 1
+67 333 1
+335 333 1
+490 333 1
+97 334 1
+118 334 1
+311 334 1
+29 335 1
+187 335 1
+478 335 1
+109 336 1
+334 336 1
+364 336 1
+241 337 1
+324 337 1
+450 337 1
+59 338 1
+441 338 1
+448 338 1
+332 339 1
+462 339 1
+479 339 1
+15 340 1
+112 340 1
+372 340 1
+228 341 1
+445 341 1
+463 341 1
+6 342 1
+59 342 1
+495 342 1
+186 343 1
+214 343 1
+312 343 1
+81 344 1
+230 344 1
+269 344 1
+271 345 1
+372 345 1
+425 345 1
+31 346 1
+44 346 1
+341 346 1
+103 347 1
+106 347 1
+501 347 1
+122 348 1
+167 348 1
+415 348 1
+150 349 1
+181 349 1
+193 349 1
+105 350 1
+211 350 1
+225 350 1
+110 351 1
+193 351 1
+481 351 1
+92 352 1
+148 352 1
+437 352 1
+277 353 1
+409 353 1
+433 353 1
+213 354 1
+264 354 1
+281 354 1
+358 355 1
+364 355 1
+509 355 1
+37 356 1
+353 356 1
+428 356 1
+100 357 1
+174 357 1
+278 357 1
+129 358 1
+263 358 1
+509 358 1
+46 359 1
+283 359 1
+458 359 1
+367 360 1
+406 360 1
+506 360 1
+118 361 1
+312 361 1
+481 361 1
+26 362 1
+349 362 1
+509 362 1
+115 363 1
+118 363 1
+463 363 1
+211 364 1
+455 364 1
+504 364 1
+3 365 1
+181 365 1
+209 365 1
+77 366 1
+259 366 1
+415 366 1
+217 367 1
+323 367 1
+510 367 1
+23 368 1
+175 368 1
+347 368 1
+24 369 1
+33 369 1
+246 369 1
+145 370 1
+152 370 1
+388 370 1
+70 371 1
+299 371 1
+307 371 1
+48 372 1
+141 372 1
+237 372 1
+68 373 1
+320 373 1
+472 373 1
+179 374 1
+314 374 1
+407 374 1
+112 375 1
+131 375 1
+318 375 1
+30 376 1
+62 376 1
+228 376 1
+110 377 1
+235 377 1
+441 377 1
+177 378 1
+335 378 1
+417 378 1
+14 379 1
+231 379 1
+467 379 1
+97 380 1
+340 380 1
+469 380 1
+68 381 1
+244 381 1
+457 381 1
+66 382 1
+425 382 1
+515 382 1
+103 383 1
+169 383 1
+324 383 1
+105 384 1
+311 384 1
+402 384 1
+83 385 1
+497 385 1
+510 385 1
+231 386 1
+241 386 1
+254 386 1
+29 387 1
+37 387 1
+112 387 1
+383 388 1
+436 388 1
+470 388 1
+45 389 1
+117 389 1
+345 389 1
+64 390 1
+184 390 1
+463 390 1
+42 391 1
+294 391 1
+302 391 1
+32 392 1
+157 392 1
+378 392 1
+201 393 1
+350 393 1
+416 393 1
+269 394 1
+301 394 1
+312 394 1
+67 395 1
+94 395 1
+241 395 1
+9 396 1
+162 396 1
+381 396 1
+149 397 1
+273 397 1
+327 397 1
+3 398 1
+13 398 1
+94 398 1
+34 399 1
+182 399 1
+207 399 1
+86 400 1
+101 400 1
+335 400 1
+373 401 1
+486 401 1
+498 401 1
+51 402 1
+341 402 1
+343 402 1
+409 403 1
+434 403 1
+476 403 1
+130 404 1
+322 404 1
+427 404 1
+39 405 1
+74 405 1
+444 405 1
+80 406 1
+144 406 1
+351 406 1
+177 407 1
+284 407 1
+414 407 1
+118 408 1
+139 408 1
+186 408 1
+34 409 1
+111 409 1
+178 409 1
+248 410 1
+403 410 1
+457 410 1
+175 411 1
+214 411 1
+459 411 1
+50 412 1
+52 412 1
+460 412 1
+37 413 1
+323 413 1
+333 413 1
+76 414 1
+327 414 1
+471 414 1
+14 415 1
+172 415 1
+334 415 1
+7 416 1
+227 416 1
+389 416 1
+122 417 1
+230 417 1
+398 417 1
+49 418 1
+208 418 1
+327 418 1
+262 419 1
+277 419 1
+315 419 1
+27 420 1
+221 420 1
+504 420 1
+79 421 1
+120 421 1
+481 421 1
+102 422 1
+409 422 1
+437 422 1
+295 423 1
+339 423 1
+386 423 1
+113 424 1
+123 424 1
+431 424 1
+26 425 1
+223 425 1
+488 425 1
+111 426 1
+252 426 1
+442 426 1
+135 427 1
+209 427 1
+241 427 1
+10 428 1
+237 428 1
+356 428 1
+356 429 1
+429 429 1
+471 429 1
+97 430 1
+295 430 1
+402 430 1
+21 431 1
+253 431 1
+424 431 1
+2 432 1
+35 432 1
+433 432 1
+129 433 1
+162 433 1
+287 433 1
+451 434 1
+454 434 1
+459 434 1
+140 435 1
+243 435 1
+298 435 1
+60 436 1
+199 436 1
+463 436 1
+42 437 1
+295 437 1
+322 437 1
+191 438 1
+385 438 1
+458 438 1
+33 439 1
+360 439 1
+386 439 1
+152 440 1
+241 440 1
+464 440 1
+25 441 1
+170 441 1
+232 441 1
+279 442 1
+390 442 1
+492 442 1
+99 443 1
+175 443 1
+285 443 1
+22 444 1
+402 444 1
+441 444 1
+124 445 1
+198 445 1
+227 445 1
+168 446 1
+288 446 1
+292 446 1
+305 447 1
+397 447 1
+405 447 1
+34 448 1
+275 448 1
+377 448 1
+104 449 1
+330 449 1
+336 449 1
+224 450 1
+267 450 1
+466 450 1
+154 451 1
+161 451 1
+441 451 1
+50 452 1
+341 452 1
+513 452 1
+71 453 1
+283 453 1
+350 453 1
+97 454 1
+193 454 1
+276 454 1
+60 455 1
+62 455 1
+142 455 1
+209 456 1
+258 456 1
+492 456 1
+73 457 1
+162 457 1
+176 457 1
+57 458 1
+254 458 1
+404 458 1
+10 459 1
+259 459 1
+286 459 1
+322 460 1
+374 460 1
+437 460 1
+159 461 1
+408 461 1
+483 461 1
+375 462 1
+415 462 1
+474 462 1
+104 463 1
+268 463 1
+446 463 1
+17 464 1
+54 464 1
+291 464 1
+273 465 1
+312 465 1
+323 465 1
+374 466 1
+424 466 1
+474 466 1
+81 467 1
+302 467 1
+463 467 1
+121 468 1
+342 468 1
+414 468 1
+160 469 1
+376 469 1
+496 469 1
+157 470 1
+172 470 1
+231 470 1
+411 471 1
+453 471 1
+493 471 1
+88 472 1
+214 472 1
+491 472 1
+236 473 1
+281 473 1
+464 473 1
+166 474 1
+379 474 1
+484 474 1
+88 475 1
+447 475 1
+448 475 1
+53 476 1
+170 476 1
+191 476 1
+164 477 1
+434 477 1
+441 477 1
+135 478 1
+230 478 1
+258 478 1
+36 479 1
+121 479 1
+296 479 1
+375 480 1
+423 480 1
+497 480 1
+291 481 1
+305 481 1
+381 481 1
+211 482 1
+441 482 1
+484 482 1
+4 483 1
+276 483 1
+419 483 1
+233 484 1
+244 484 1
+318 484 1
+84 485 1
+121 485 1
+125 485 1
+94 486 1
+110 486 1
+222 486 1
+47 487 1
+461 487 1
+487 487 1
+29 488 1
+323 488 1
+516 488 1
+10 489 1
+151 489 1
+285 489 1
+306 490 1
+309 490 1
+502 490 1
+54 491 1
+431 491 1
+449 491 1
+183 492 1
+202 492 1
+294 492 1
+16 493 1
+200 493 1
+211 493 1
+128 494 1
+329 494 1
+384 494 1
+42 495 1
+210 495 1
+358 495 1
+86 496 1
+352 496 1
+451 496 1
+96 497 1
+164 497 1
+414 497 1
+488 498 1
+503 498 1
+509 498 1
+31 499 1
+113 499 1
+135 499 1
+109 500 1
+126 500 1
+241 500 1
+150 501 1
+231 501 1
+444 501 1
+42 502 1
+152 502 1
+392 502 1
+332 503 1
+454 503 1
+474 503 1
+110 504 1
+311 504 1
+469 504 1
+315 505 1
+433 505 1
+444 505 1
+44 506 1
+86 506 1
+203 506 1
+321 507 1
+449 507 1
+500 507 1
+82 508 1
+130 508 1
+282 508 1
+109 509 1
+231 509 1
+350 509 1
+235 510 1
+262 510 1
+286 510 1
+80 511 1
+189 511 1
+231 511 1
+212 512 1
+290 512 1
+478 512 1
+35 513 1
+288 513 1
+365 513 1
+128 514 1
+429 514 1
+465 514 1
+80 515 1
+143 515 1
+467 515 1
+215 516 1
+311 516 1
+472 516 1
+7 517 1
+70 517 1
+497 517 1
+115 518 1
+226 518 1
+484 518 1
+44 519 1
+451 519 1
+513 519 1
+102 520 1
+277 520 1
+513 520 1
+281 521 1
+362 521 1
+455 521 1
+86 522 1
+134 522 1
+242 522 1
+27 523 1
+51 523 1
+502 523 1
+79 524 1
+81 524 1
+385 524 1
+280 525 1
+343 525 1
+504 525 1
+33 526 1
+171 526 1
+358 526 1
+227 527 1
+466 527 1
+479 527 1
+142 528 1
+149 528 1
+390 528 1
+113 529 1
+194 529 1
+407 529 1
+104 530 1
+310 530 1
+416 530 1
+102 531 1
+119 531 1
+266 531 1
+281 532 1
+315 532 1
+330 532 1
+161 533 1
+186 533 1
+206 533 1
+238 534 1
+300 534 1
+412 534 1
+197 535 1
+469 535 1
+471 535 1
+106 536 1
+349 536 1
+496 536 1
+111 537 1
+427 537 1
+498 537 1
+72 538 1
+123 538 1
+380 538 1
+163 539 1
+168 539 1
+325 539 1
+76 540 1
+117 540 1
+159 540 1
+41 541 1
+174 541 1
+219 541 1
+58 542 1
+144 542 1
+504 542 1
+4 543 1
+224 543 1
+447 543 1
+46 544 1
+116 544 1
+340 544 1
+45 545 1
+173 545 1
+383 545 1
+122 546 1
+198 546 1
+416 546 1
+281 547 1
+457 547 1
+475 547 1
+219 548 1
+287 548 1
+373 548 1
+52 549 1
+147 549 1
+410 549 1
+53 550 1
+65 550 1
+486 550 1
+45 551 1
+258 551 1
+368 551 1
+66 552 1
+272 552 1
+501 552 1
+264 553 1
+499 553 1
+511 553 1
+69 554 1
+315 554 1
+413 554 1
+37 555 1
+81 555 1
+91 555 1
+16 556 1
+186 556 1
+278 556 1
+138 557 1
+168 557 1
+257 557 1
+221 558 1
+341 558 1
+486 558 1
+176 559 1
+316 559 1
+369 559 1
+176 560 1
+190 560 1
+506 560 1
+98 561 1
+178 561 1
+214 561 1
+42 562 1
+291 562 1
+402 562 1
+75 563 1
+232 563 1
+430 563 1
+92 564 1
+280 564 1
+348 564 1
+80 565 1
+174 565 1
+476 565 1
+158 566 1
+260 566 1
+333 566 1
+163 567 1
+242 567 1
+331 567 1
+71 568 1
+226 568 1
+441 568 1
+26 569 1
+181 569 1
+204 569 1
+49 570 1
+120 570 1
+187 570 1
+109 571 1
+113 571 1
+450 571 1
+108 572 1
+138 572 1
+194 572 1
+70 573 1
+294 573 1
+382 573 1
+85 574 1
+106 574 1
+224 574 1
+378 575 1
+481 575 1
+497 575 1
+186 576 1
+287 576 1
+411 576 1
+178 577 1
+377 577 1
+462 577 1
+9 578 1
+104 578 1
+252 578 1
+12 579 1
+125 579 1
+275 579 1
+4 580 1
+383 580 1
+457 580 1
+74 581 1
+234 581 1
+446 581 1
+25 582 1
+369 582 1
+415 582 1
+65 583 1
+289 583 1
+502 583 1
+207 584 1
+348 584 1
+413 584 1
+8 585 1
+52 585 1
+121 585 1
+339 586 1
+389 586 1
+515 586 1
+5 587 1
+239 587 1
+485 587 1
+45 588 1
+219 588 1
+476 588 1
+205 589 1
+344 589 1
+353 589 1
+163 590 1
+378 590 1
+381 590 1
+234 591 1
+338 591 1
+488 591 1
+14 592 1
+418 592 1
+480 592 1
+56 593 1
+137 593 1
+385 593 1
+77 594 1
+363 594 1
+425 594 1
+62 595 1
+116 595 1
+314 595 1
+185 596 1
+207 596 1
+224 596 1
+55 597 1
+335 597 1
+383 597 1
+89 598 1
+449 598 1
+506 598 1
+19 599 1
+202 599 1
+280 599 1
+228 600 1
+358 600 1
+515 600 1
+117 601 1
+216 601 1
+388 601 1
+113 602 1
+134 602 1
+422 602 1
+80 603 1
+319 603 1
+386 603 1
+9 604 1
+100 604 1
+396 604 1
+8 605 1
+11 605 1
+408 605 1
+38 606 1
+265 606 1
+329 606 1
+74 607 1
+233 607 1
+340 607 1
+10 608 1
+172 608 1
+371 608 1
+112 609 1
+267 609 1
+359 609 1
+32 610 1
+45 610 1
+138 610 1
+205 611 1
+256 611 1
+431 611 1
+8 612 1
+23 612 1
+200 612 1
+242 613 1
+318 613 1
+361 613 1
+142 614 1
+221 614 1
+393 614 1
+119 615 1
+169 615 1
+189 615 1
+26 616 1
+245 616 1
+436 616 1
+158 617 1
+306 617 1
+411 617 1
+28 618 1
+281 618 1
+319 618 1
+148 619 1
+181 619 1
+316 619 1
+54 620 1
+289 620 1
+478 620 1
+69 621 1
+116 621 1
+293 621 1
+28 622 1
+173 622 1
+390 622 1
+81 623 1
+346 623 1
+422 623 1
+91 624 1
+327 624 1
+414 624 1
+142 625 1
+194 625 1
+445 625 1
+78 626 1
+205 626 1
+232 626 1
+158 627 1
+326 627 1
+503 627 1
+49 628 1
+345 628 1
+397 628 1
+66 629 1
+201 629 1
+443 629 1
+45 630 1
+111 630 1
+296 630 1
+179 631 1
+448 631 1
+493 631 1
+249 632 1
+366 632 1
+374 632 1
+91 633 1
+399 633 1
+432 633 1
+90 634 1
+293 634 1
+430 634 1
+219 635 1
+222 635 1
+493 635 1
+153 636 1
+170 636 1
+206 636 1
+339 637 1
+358 637 1
+437 637 1
+90 638 1
+442 638 1
+477 638 1
+14 639 1
+19 639 1
+295 639 1
+56 640 1
+187 640 1
+352 640 1
+60 641 1
+159 641 1
+492 641 1
+392 642 1
+456 642 1
+509 642 1
+9 643 1
+299 643 1
+375 643 1
+162 644 1
+206 644 1
+214 644 1
+274 645 1
+290 645 1
+314 645 1
+102 646 1
+169 646 1
+430 646 1
+79 647 1
+253 647 1
+283 647 1
+89 648 1
+412 648 1
+467 648 1
+206 649 1
+252 649 1
+491 649 1
+114 650 1
+202 650 1
+350 650 1
+365 651 1
+377 651 1
+421 651 1
+2 652 1
+331 652 1
+499 652 1
+232 653 1
+497 653 1
+499 653 1
+172 654 1
+203 654 1
+511 654 1
+36 655 1
+313 655 1
+367 655 1
+8 656 1
+115 656 1
+125 656 1
+14 657 1
+255 657 1
+379 657 1
+317 658 1
+373 658 1
+482 658 1
+173 659 1
+364 659 1
+476 659 1
+65 660 1
+237 660 1
+505 660 1
+2 661 1
+245 661 1
+411 661 1
+37 662 1
+291 662 1
+446 662 1
+112 663 1
+269 663 1
+507 663 1
+273 664 1
+342 664 1
+390 664 1
+38 665 1
+54 665 1
+264 665 1
+179 666 1
+218 666 1
+290 666 1
+107 667 1
+269 667 1
+419 667 1
+244 668 1
+373 668 1
+460 668 1
+9 669 1
+170 669 1
+474 669 1
+173 670 1
+256 670 1
+414 670 1
+67 671 1
+270 671 1
+422 671 1
+141 672 1
+213 672 1
+317 672 1
+265 673 1
+305 673 1
+327 673 1
+156 674 1
+288 674 1
+437 674 1
+96 675 1
+203 675 1
+422 675 1
+102 676 1
+315 676 1
+404 676 1
+158 677 1
+238 677 1
+320 677 1
+77 678 1
+87 678 1
+416 678 1
+96 679 1
+192 679 1
+242 679 1
+331 680 1
+334 680 1
+362 680 1
+2 681 1
+26 681 1
+429 681 1
+102 682 1
+127 682 1
+366 682 1
+302 683 1
+352 683 1
+399 683 1
+94 684 1
+240 684 1
+438 684 1
+23 685 1
+277 685 1
+293 685 1
+93 686 1
+114 686 1
+245 686 1
+92 687 1
+102 687 1
+448 687 1
+408 688 1
+432 688 1
+461 688 1
+95 689 1
+139 689 1
+390 689 1
+229 690 1
+332 690 1
+415 690 1
+2 691 1
+278 691 1
+356 691 1
+25 692 1
+128 692 1
+482 692 1
+326 693 1
+411 693 1
+504 693 1
+62 694 1
+91 694 1
+284 694 1
+82 695 1
+317 695 1
+428 695 1
+166 696 1
+296 696 1
+378 696 1
+185 697 1
+265 697 1
+268 697 1
+7 698 1
+343 698 1
+400 698 1
+170 699 1
+291 699 1
+308 699 1
+15 700 1
+217 700 1
+468 700 1
+30 701 1
+124 701 1
+416 701 1
+216 702 1
+350 702 1
+393 702 1
+93 703 1
+220 703 1
+394 703 1
+94 704 1
+242 704 1
+405 704 1
+186 705 1
+220 705 1
+355 705 1
+24 706 1
+62 706 1
+408 706 1
+124 707 1
+233 707 1
+438 707 1
+268 708 1
+300 708 1
+323 708 1
+36 709 1
+190 709 1
+424 709 1
+108 710 1
+393 710 1
+401 710 1
+156 711 1
+445 711 1
+483 711 1
+448 712 1
+513 712 1
+516 712 1
+65 713 1
+478 713 1
+493 713 1
+134 714 1
+346 714 1
+362 714 1
+356 715 1
+375 715 1
+424 715 1
+79 716 1
+131 716 1
+372 716 1
+91 717 1
+99 717 1
+234 717 1
+165 718 1
+272 718 1
+515 718 1
+63 719 1
+160 719 1
+386 719 1
+30 720 1
+355 720 1
+382 720 1
+123 721 1
+279 721 1
+500 721 1
+56 722 1
+112 722 1
+314 722 1
+164 723 1
+305 723 1
+402 723 1
+97 724 1
+107 724 1
+425 724 1
+348 725 1
+403 725 1
+460 725 1
+262 726 1
+336 726 1
+456 726 1
+72 727 1
+109 727 1
+172 727 1
+294 728 1
+322 728 1
+501 728 1
+3 729 1
+143 729 1
+247 729 1
+33 730 1
+371 730 1
+495 730 1
+36 731 1
+147 731 1
+173 731 1
+143 732 1
+204 732 1
+492 732 1
+79 733 1
+192 733 1
+226 733 1
+31 734 1
+308 734 1
+476 734 1
+158 735 1
+180 735 1
+439 735 1
+124 736 1
+279 736 1
+346 736 1
+46 737 1
+127 737 1
+293 737 1
+131 738 1
+194 738 1
+353 738 1
+115 739 1
+145 739 1
+317 739 1
+103 740 1
+239 740 1
+435 740 1
+33 741 1
+124 741 1
+152 741 1
+280 742 1
+288 742 1
+487 742 1
+22 743 1
+24 743 1
+119 743 1
+69 744 1
+177 744 1
+348 744 1
+80 745 1
+191 745 1
+424 745 1
+343 746 1
+433 746 1
+499 746 1
+386 747 1
+429 747 1
+494 747 1
+295 748 1
+308 748 1
+495 748 1
+107 749 1
+270 749 1
+469 749 1
+39 750 1
+136 750 1
+251 750 1
+122 751 1
+330 751 1
+501 751 1
+18 752 1
+73 752 1
+401 752 1
+215 753 1
+469 753 1
+516 753 1
+78 754 1
+302 754 1
+308 754 1
+166 755 1
+274 755 1
+457 755 1
+136 756 1
+221 756 1
+280 756 1
+163 757 1
+246 757 1
+454 757 1
+222 758 1
+393 758 1
+440 758 1
+5 759 1
+328 759 1
+432 759 1
+405 760 1
+431 760 1
+470 760 1
+196 761 1
+454 761 1
+497 761 1
+253 762 1
+391 762 1
+399 762 1
+401 763 1
+426 763 1
+451 763 1
+78 764 1
+269 764 1
+344 764 1
+138 765 1
+434 765 1
+487 765 1
+184 766 1
+329 766 1
+432 766 1
+190 767 1
+245 767 1
+439 767 1
+131 768 1
+149 768 1
+516 768 1
+5 769 1
+151 769 1
+278 769 1
+141 770 1
+338 770 1
+461 770 1
+91 771 1
+328 771 1
+462 771 1
+84 772 1
+299 772 1
+313 772 1
+10 773 1
+433 773 1
+475 773 1
+210 774 1
+374 774 1
+386 774 1
+184 775 1
+230 775 1
+233 775 1
+171 776 1
+202 776 1
+396 776 1
+39 777 1
+472 777 1
+475 777 1
+20 778 1
+177 778 1
+439 778 1
+283 779 1
+360 779 1
+424 779 1
+92 780 1
+402 780 1
+495 780 1
+337 781 1
+387 781 1
+431 781 1
+257 782 1
+316 782 1
+434 782 1
+172 783 1
+181 783 1
+433 783 1
+160 784 1
+418 784 1
+436 784 1
+28 785 1
+52 785 1
+456 785 1
+134 786 1
+198 786 1
+403 786 1
+170 787 1
+174 787 1
+341 787 1
+18 788 1
+20 788 1
+423 788 1
+110 789 1
+197 789 1
+359 789 1
+108 790 1
+110 790 1
+296 790 1
+85 791 1
+294 791 1
+324 791 1
+21 792 1
+268 792 1
+309 792 1
+62 793 1
+123 793 1
+480 793 1
+122 794 1
+151 794 1
+508 794 1
+23 795 1
+43 795 1
+435 795 1
+10 796 1
+87 796 1
+144 796 1
+128 797 1
+250 797 1
+478 797 1
+161 798 1
+237 798 1
+401 798 1
+152 799 1
+247 799 1
+358 799 1
+156 800 1
+233 800 1
+287 800 1
+65 801 1
+143 801 1
+484 801 1
+249 802 1
+367 802 1
+512 802 1
+124 803 1
+231 803 1
+443 803 1
+191 804 1
+339 804 1
+367 804 1
+282 805 1
+381 805 1
+459 805 1
+139 806 1
+141 806 1
+452 806 1
+220 807 1
+233 807 1
+445 807 1
+238 808 1
+355 808 1
+468 808 1
+24 809 1
+204 809 1
+316 809 1
+60 810 1
+225 810 1
+271 810 1
+66 811 1
+382 811 1
+514 811 1
+41 812 1
+208 812 1
+388 812 1
+196 813 1
+224 813 1
+448 813 1
+185 814 1
+206 814 1
+474 814 1
+68 815 1
+159 815 1
+413 815 1
+72 816 1
+87 816 1
+307 816 1
+51 817 1
+80 817 1
+86 817 1
+121 818 1
+275 818 1
+293 818 1
+12 819 1
+103 819 1
+320 819 1
+218 820 1
+365 820 1
+433 820 1
+13 821 1
+33 821 1
+302 821 1
+101 822 1
+374 822 1
+394 822 1
+89 823 1
+117 823 1
+222 823 1
+93 824 1
+145 824 1
+414 824 1
+298 825 1
+332 825 1
+344 825 1
+293 826 1
+368 826 1
+456 826 1
+197 827 1
+309 827 1
+356 827 1
+201 828 1
+297 828 1
+475 828 1
+332 829 1
+421 829 1
+468 829 1
+36 830 1
+63 830 1
+456 830 1
+128 831 1
+212 831 1
+426 831 1
+160 832 1
+213 832 1
+494 832 1
+182 833 1
+373 833 1
+428 833 1
+42 834 1
+107 834 1
+339 834 1
+19 835 1
+249 835 1
+288 835 1
+53 836 1
+247 836 1
+494 836 1
+259 837 1
+318 837 1
+448 837 1
+116 838 1
+242 838 1
+270 838 1
+331 839 1
+464 839 1
+504 839 1
+131 840 1
+312 840 1
+507 840 1
+84 841 1
+164 841 1
+381 841 1
+125 842 1
+240 842 1
+405 842 1
+43 843 1
+103 843 1
+379 843 1
+285 844 1
+328 844 1
+498 844 1
+79 845 1
+345 845 1
+469 845 1
+112 846 1
+262 846 1
+489 846 1
+66 847 1
+160 847 1
+247 847 1
+66 848 1
+209 848 1
+354 848 1
+288 849 1
+401 849 1
+445 849 1
+93 850 1
+325 850 1
+500 850 1
+93 851 1
+249 851 1
+467 851 1
+158 852 1
+186 852 1
+217 852 1
+87 853 1
+201 853 1
+277 853 1
+104 854 1
+112 854 1
+385 854 1
+134 855 1
+250 855 1
+318 855 1
+131 856 1
+262 856 1
+513 856 1
+156 857 1
+215 857 1
+218 857 1
+58 858 1
+70 858 1
+253 858 1
+33 859 1
+473 859 1
+483 859 1
+6 860 1
+170 860 1
+249 860 1
+42 861 1
+126 861 1
+325 861 1
+16 862 1
+143 862 1
+161 862 1
+130 863 1
+211 863 1
+351 863 1
+182 864 1
+313 864 1
+505 864 1
+354 865 1
+370 865 1
+475 865 1
+141 866 1
+183 866 1
+440 866 1
+12 867 1
+220 867 1
+229 867 1
+65 868 1
+174 868 1
+412 868 1
+60 869 1
+388 869 1
+461 869 1
+1 870 1
+346 870 1
+371 870 1
+169 871 1
+351 871 1
+427 871 1
+175 872 1
+182 872 1
+377 872 1
+82 873 1
+173 873 1
+439 873 1
+44 874 1
+48 874 1
+338 874 1
+82 875 1
+214 875 1
+473 875 1
+108 876 1
+370 876 1
+500 876 1
+17 877 1
+163 877 1
+292 877 1
+69 878 1
+92 878 1
+167 878 1
+28 879 1
+95 879 1
+315 879 1
+29 880 1
+228 880 1
+230 880 1
+80 881 1
+134 881 1
+261 881 1
+145 882 1
+461 882 1
+464 882 1
+25 883 1
+251 883 1
+294 883 1
+66 884 1
+398 884 1
+407 884 1
+88 885 1
+205 885 1
+226 885 1
+14 886 1
+282 886 1
+406 886 1
+64 887 1
+372 887 1
+488 887 1
+290 888 1
+363 888 1
+426 888 1
+160 889 1
+348 889 1
+432 889 1
+46 890 1
+83 890 1
+515 890 1
+113 891 1
+321 891 1
+511 891 1
+1 892 1
+175 892 1
+421 892 1
+251 893 1
+265 893 1
+489 893 1
+55 894 1
+160 894 1
+439 894 1
+61 895 1
+252 895 1
+282 895 1
+185 896 1
+479 896 1
+515 896 1
+199 897 1
+340 897 1
+483 897 1
+153 898 1
+257 898 1
+325 898 1
+13 899 1
+64 899 1
+323 899 1
+237 900 1
+285 900 1
+462 900 1
+150 901 1
+419 901 1
+443 901 1
+269 902 1
+369 902 1
+491 902 1
+5 903 1
+23 903 1
+377 903 1
+100 904 1
+196 904 1
+384 904 1
+126 905 1
+283 905 1
+349 905 1
+243 906 1
+286 906 1
+491 906 1
+312 907 1
+327 907 1
+353 907 1
+56 908 1
+97 908 1
+226 908 1
+219 909 1
+411 909 1
+420 909 1
+203 910 1
+331 910 1
+495 910 1
+156 911 1
+184 911 1
+428 911 1
+144 912 1
+297 912 1
+409 912 1
+164 913 1
+325 913 1
+473 913 1
+161 914 1
+284 914 1
+461 914 1
+87 915 1
+341 915 1
+357 915 1
+236 916 1
+245 916 1
+473 916 1
+203 917 1
+302 917 1
+371 917 1
+10 918 1
+294 918 1
+343 918 1
+216 919 1
+231 919 1
+360 919 1
+13 920 1
+247 920 1
+398 920 1
+166 921 1
+319 921 1
+500 921 1
+239 922 1
+404 922 1
+465 922 1
+19 923 1
+190 923 1
+401 923 1
+141 924 1
+180 924 1
+319 924 1
+51 925 1
+491 925 1
+513 925 1
+284 926 1
+441 926 1
+483 926 1
+61 927 1
+147 927 1
+216 927 1
+11 928 1
+303 928 1
+405 928 1
+75 929 1
+148 929 1
+424 929 1
+205 930 1
+291 930 1
+473 930 1
+31 931 1
+350 931 1
+455 931 1
+128 932 1
+471 932 1
+516 932 1
+49 933 1
+197 933 1
+235 933 1
+2 934 1
+396 934 1
+476 934 1
+33 935 1
+187 935 1
+308 935 1
+5 936 1
+92 936 1
+248 936 1
+135 937 1
+201 937 1
+281 937 1
+100 938 1
+269 938 1
+482 938 1
+194 939 1
+200 939 1
+244 939 1
+78 940 1
+264 940 1
+481 940 1
+154 941 1
+250 941 1
+407 941 1
+245 942 1
+338 942 1
+345 942 1
+51 943 1
+104 943 1
+309 943 1
+321 944 1
+470 944 1
+506 944 1
+121 945 1
+379 945 1
+417 945 1
+160 946 1
+248 946 1
+485 946 1
+114 947 1
+168 947 1
+363 947 1
+74 948 1
+271 948 1
+320 948 1
+44 949 1
+113 949 1
+192 949 1
+113 950 1
+146 950 1
+470 950 1
+59 951 1
+205 951 1
+231 951 1
+259 952 1
+267 952 1
+513 952 1
+6 953 1
+71 953 1
+246 953 1
+49 954 1
+296 954 1
+299 954 1
+144 955 1
+221 955 1
+447 955 1
+6 956 1
+385 956 1
+467 956 1
+22 957 1
+153 957 1
+163 957 1
+214 958 1
+347 958 1
+510 958 1
+171 959 1
+482 959 1
+498 959 1
+98 960 1
+252 960 1
+337 960 1
+181 961 1
+339 961 1
+417 961 1
+225 962 1
+453 962 1
+491 962 1
+368 963 1
+390 963 1
+457 963 1
+8 964 1
+289 964 1
+422 964 1
+274 965 1
+284 965 1
+340 965 1
+154 966 1
+229 966 1
+422 966 1
+262 967 1
+269 967 1
+298 967 1
+234 968 1
+263 968 1
+273 968 1
+21 969 1
+167 969 1
+301 969 1
+19 970 1
+27 970 1
+447 970 1
+352 971 1
+369 971 1
+449 971 1
+9 972 1
+80 972 1
+356 972 1
+165 973 1
+243 973 1
+374 973 1
+20 974 1
+432 974 1
+436 974 1
+90 975 1
+230 975 1
+299 975 1
+85 976 1
+153 976 1
+225 976 1
+255 977 1
+280 977 1
+452 977 1
+367 978 1
+397 978 1
+468 978 1
+174 979 1
+239 979 1
+490 979 1
+29 980 1
+380 980 1
+403 980 1
+145 981 1
+208 981 1
+432 981 1
+43 982 1
+244 982 1
+387 982 1
+1 983 1
+8 983 1
+38 983 1
+3 984 1
+72 984 1
+277 984 1
+153 985 1
+271 985 1
+340 985 1
+10 986 1
+354 986 1
+514 986 1
+280 987 1
+328 987 1
+485 987 1
+77 988 1
+233 988 1
+355 988 1
+221 989 1
+224 989 1
+253 989 1
+12 990 1
+297 990 1
+400 990 1
+11 991 1
+297 991 1
+389 991 1
+142 992 1
+204 992 1
+460 992 1
+370 993 1
+461 993 1
+492 993 1
+143 994 1
+190 994 1
+356 994 1
+116 995 1
+259 995 1
+300 995 1
+145 996 1
+151 996 1
+400 996 1
+223 997 1
+306 997 1
+404 997 1
+330 998 1
+375 998 1
+404 998 1
+36 999 1
+195 999 1
+498 999 1
+9 1000 1
+189 1000 1
+369 1000 1
+157 1001 1
+304 1001 1
+330 1001 1
+99 1002 1
+155 1002 1
+273 1002 1
+271 1003 1
+279 1003 1
+311 1003 1
+88 1004 1
+232 1004 1
+248 1004 1
+291 1005 1
+352 1005 1
+491 1005 1
+49 1006 1
+123 1006 1
+126 1006 1
+89 1007 1
+177 1007 1
+216 1007 1
+47 1008 1
+339 1008 1
+495 1008 1
+94 1009 1
+401 1009 1
+449 1009 1
+394 1010 1
+493 1010 1
+505 1010 1
+344 1011 1
+384 1011 1
+407 1011 1
+305 1012 1
+376 1012 1
+380 1012 1
+38 1013 1
+340 1013 1
+425 1013 1
+30 1014 1
+38 1014 1
+246 1014 1
+39 1015 1
+171 1015 1
+437 1015 1
+6 1016 1
+79 1016 1
+153 1016 1
+129 1017 1
+161 1017 1
+211 1017 1
+1 1018 1
+78 1018 1
+256 1018 1
+242 1019 1
+340 1019 1
+387 1019 1
+268 1020 1
+293 1020 1
+515 1020 1
+200 1021 1
+238 1021 1
+297 1021 1
+298 1022 1
+465 1022 1
+507 1022 1
+182 1023 1
+191 1023 1
+440 1023 1
+297 1024 1
+435 1024 1
+480 1024 1
+175 1025 1
+179 1025 1
+361 1025 1
+27 1026 1
+244 1026 1
+412 1026 1
+117 1027 1
+387 1027 1
+395 1027 1
+135 1028 1
+184 1028 1
+431 1028 1
+108 1029 1
+211 1029 1
+412 1029 1
+246 1030 1
+307 1030 1
+371 1030 1
+60 1031 1
+352 1031 1
+506 1031 1
+38 1032 1
+342 1032 1
+435 1032 1
+225 1033 1
+316 1033 1
+421 1033 1
+48 1034 1
+196 1034 1
+462 1034 1
+12 1035 1
+351 1035 1
+504 1035 1
+124 1036 1
+353 1036 1
+483 1036 1
+229 1037 1
+445 1037 1
+472 1037 1
+55 1038 1
+69 1038 1
+436 1038 1
+50 1039 1
+97 1039 1
+507 1039 1
+311 1040 1
+368 1040 1
+370 1040 1
+70 1041 1
+180 1041 1
+183 1041 1
+133 1042 1
+274 1042 1
+485 1042 1
+119 1043 1
+136 1043 1
+330 1043 1
+151 1044 1
+275 1044 1
+389 1044 1
+199 1045 1
+342 1045 1
+381 1045 1
+73 1046 1
+189 1046 1
+473 1046 1
+70 1047 1
+75 1047 1
+272 1047 1
+98 1048 1
+395 1048 1
+449 1048 1
+26 1049 1
+145 1049 1
+364 1049 1
+76 1050 1
+147 1050 1
+192 1050 1
+99 1051 1
+205 1051 1
+345 1051 1
+154 1052 1
+185 1052 1
+312 1052 1
+112 1053 1
+222 1053 1
+252 1053 1
+76 1054 1
+218 1054 1
+333 1054 1
+236 1055 1
+413 1055 1
+501 1055 1
+273 1056 1
+297 1056 1
+388 1056 1
+22 1057 1
+374 1057 1
+491 1057 1
+109 1058 1
+144 1058 1
+246 1058 1
+206 1059 1
+453 1059 1
+507 1059 1
+61 1060 1
+372 1060 1
+393 1060 1
+34 1061 1
+138 1061 1
+355 1061 1
+146 1062 1
+302 1062 1
+358 1062 1
+292 1063 1
+316 1063 1
+367 1063 1
+132 1064 1
+237 1064 1
+417 1064 1
+254 1065 1
+356 1065 1
+499 1065 1
+42 1066 1
+46 1066 1
+81 1066 1
+1 1067 1
+40 1067 1
+516 1067 1
+121 1068 1
+339 1068 1
+494 1068 1
+310 1069 1
+343 1069 1
+490 1069 1
+33 1070 1
+184 1070 1
+228 1070 1
+41 1071 1
+242 1071 1
+480 1071 1
+49 1072 1
+125 1072 1
+367 1072 1
+168 1073 1
+216 1073 1
+427 1073 1
+226 1074 1
+345 1074 1
+387 1074 1
+247 1075 1
+305 1075 1
+349 1075 1
+459 1076 1
+477 1076 1
+510 1076 1
+47 1077 1
+148 1077 1
+349 1077 1
+211 1078 1
+214 1078 1
+411 1078 1
+187 1079 1
+199 1079 1
+321 1079 1
+41 1080 1
+303 1080 1
+449 1080 1
+58 1081 1
+306 1081 1
+315 1081 1
+8 1082 1
+123 1082 1
+307 1082 1
+388 1083 1
+440 1083 1
+458 1083 1
+359 1084 1
+404 1084 1
+490 1084 1
+129 1085 1
+292 1085 1
+462 1085 1
+83 1086 1
+210 1086 1
+323 1086 1
+129 1087 1
+328 1087 1
+406 1087 1
+190 1088 1
+350 1088 1
+452 1088 1
+55 1089 1
+210 1089 1
+456 1089 1
+189 1090 1
+337 1090 1
+357 1090 1
+48 1091 1
+94 1091 1
+153 1091 1
+258 1092 1
+309 1092 1
+359 1092 1
+60 1093 1
+408 1093 1
+503 1093 1
+58 1094 1
+151 1094 1
+375 1094 1
+13 1095 1
+76 1095 1
+352 1095 1
+205 1096 1
+276 1096 1
+385 1096 1
+263 1097 1
+266 1097 1
+392 1097 1
+232 1098 1
+325 1098 1
+442 1098 1
+151 1099 1
+482 1099 1
+485 1099 1
+96 1100 1
+155 1100 1
+260 1100 1
+77 1101 1
+332 1101 1
+445 1101 1
+31 1102 1
+254 1102 1
+423 1102 1
+53 1103 1
+209 1103 1
+512 1103 1
+64 1104 1
+321 1104 1
+410 1104 1
+174 1105 1
+297 1105 1
+361 1105 1
+197 1106 1
+243 1106 1
+396 1106 1
+200 1107 1
+355 1107 1
+421 1107 1
+25 1108 1
+259 1108 1
+514 1108 1
+93 1109 1
+164 1109 1
+300 1109 1
+191 1110 1
+221 1110 1
+412 1110 1
+139 1111 1
+453 1111 1
+487 1111 1
+217 1112 1
+361 1112 1
+489 1112 1
+5 1113 1
+15 1113 1
+19 1113 1
+117 1114 1
+338 1114 1
+352 1114 1
+51 1115 1
+357 1115 1
+447 1115 1
+212 1116 1
+289 1116 1
+347 1116 1
+72 1117 1
+240 1117 1
+321 1117 1
+28 1118 1
+149 1118 1
+400 1118 1
+2 1119 1
+249 1119 1
+394 1119 1
+236 1120 1
+263 1120 1
+284 1120 1
+114 1121 1
+219 1121 1
+510 1121 1
+320 1122 1
+447 1122 1
+508 1122 1
+35 1123 1
+434 1123 1
+502 1123 1
+106 1124 1
+261 1124 1
+281 1124 1
+74 1125 1
+300 1125 1
+459 1125 1
+28 1126 1
+159 1126 1
+177 1126 1
+425 1127 1
+479 1127 1
+483 1127 1
+282 1128 1
+342 1128 1
+388 1128 1
+49 1129 1
+93 1129 1
+399 1129 1
+132 1130 1
+213 1130 1
+379 1130 1
+2 1131 1
+57 1131 1
+180 1131 1
+82 1132 1
+141 1132 1
+186 1132 1
+47 1133 1
+177 1133 1
+209 1133 1
+143 1134 1
+335 1134 1
+502 1134 1
+142 1135 1
+410 1135 1
+418 1135 1
+100 1136 1
+315 1136 1
+326 1136 1
+25 1137 1
+188 1137 1
+214 1137 1
+79 1138 1
+166 1138 1
+432 1138 1
+43 1139 1
+223 1139 1
+274 1139 1
+24 1140 1
+307 1140 1
+401 1140 1
+23 1141 1
+354 1141 1
+413 1141 1
+399 1142 1
+492 1142 1
+512 1142 1
+92 1143 1
+170 1143 1
+322 1143 1
+97 1144 1
+187 1144 1
+264 1144 1
+290 1145 1
+453 1145 1
+513 1145 1
+31 1146 1
+195 1146 1
+239 1146 1
+69 1147 1
+127 1147 1
+501 1147 1
+109 1148 1
+349 1148 1
+464 1148 1
+165 1149 1
+410 1149 1
+419 1149 1
+83 1150 1
+151 1150 1
+259 1150 1
+41 1151 1
+207 1151 1
+418 1151 1
+98 1152 1
+130 1152 1
+306 1152 1
+84 1153 1
+147 1153 1
+307 1153 1
+195 1154 1
+216 1154 1
+319 1154 1
+319 1155 1
+417 1155 1
+484 1155 1
+347 1156 1
+439 1156 1
+512 1156 1
+222 1157 1
+369 1157 1
+453 1157 1
+37 1158 1
+83 1158 1
+363 1158 1
+39 1159 1
+461 1159 1
+508 1159 1
+104 1160 1
+326 1160 1
+454 1160 1
+5 1161 1
+406 1161 1
+424 1161 1
+196 1162 1
+381 1162 1
+450 1162 1
+207 1163 1
+227 1163 1
+275 1163 1
+47 1164 1
+126 1164 1
+270 1164 1
+4 1165 1
+270 1165 1
+301 1165 1
+223 1166 1
+258 1166 1
+260 1166 1
+141 1167 1
+394 1167 1
+512 1167 1
+32 1168 1
+108 1168 1
+161 1168 1
+47 1169 1
+331 1169 1
+494 1169 1
+81 1170 1
+228 1170 1
+323 1170 1
+96 1171 1
+333 1171 1
+346 1171 1
+31 1172 1
+72 1172 1
+189 1172 1
+68 1173 1
+95 1173 1
+348 1173 1
+101 1174 1
+209 1174 1
+376 1174 1
+145 1175 1
+319 1175 1
+345 1175 1
+177 1176 1
+351 1176 1
+464 1176 1
+85 1177 1
+346 1177 1
+421 1177 1
+129 1178 1
+379 1178 1
+381 1178 1
+271 1179 1
+284 1179 1
+342 1179 1
+334 1180 1
+392 1180 1
+464 1180 1
+224 1181 1
+315 1181 1
+359 1181 1
+36 1182 1
+191 1182 1
+455 1182 1
+117 1183 1
+147 1183 1
+492 1183 1
+56 1184 1
+463 1184 1
+470 1184 1
+70 1185 1
+95 1185 1
+359 1185 1
+410 1186 1
+486 1186 1
+505 1186 1
+212 1187 1
+415 1187 1
+465 1187 1
+87 1188 1
+167 1188 1
+343 1188 1
+298 1189 1
+324 1189 1
+420 1189 1
+361 1190 1
+377 1190 1
+435 1190 1
+160 1191 1
+390 1191 1
+428 1191 1
+164 1192 1
+375 1192 1
+510 1192 1
+34 1193 1
+410 1193 1
+478 1193 1
+19 1194 1
+92 1194 1
+193 1194 1
+52 1195 1
+354 1195 1
+419 1195 1
+66 1196 1
+106 1196 1
+380 1196 1
+310 1197 1
+364 1197 1
+414 1197 1
+4 1198 1
+106 1198 1
+181 1198 1
+105 1199 1
+370 1199 1
+394 1199 1
+40 1200 1
+132 1200 1
+266 1200 1
+180 1201 1
+193 1201 1
+396 1201 1
+137 1202 1
+396 1202 1
+491 1202 1
+263 1203 1
+321 1203 1
+395 1203 1
+37 1204 1
+134 1204 1
+192 1204 1
+73 1205 1
+119 1205 1
+421 1205 1
+237 1206 1
+393 1206 1
+404 1206 1
+29 1207 1
+327 1207 1
+507 1207 1
+135 1208 1
+195 1208 1
+456 1208 1
+20 1209 1
+506 1209 1
+512 1209 1
+7 1210 1
+30 1210 1
+251 1210 1
+336 1211 1
+341 1211 1
+384 1211 1
+197 1212 1
+253 1212 1
+442 1212 1
+68 1213 1
+233 1213 1
+421 1213 1
+2 1214 1
+82 1214 1
+334 1214 1
+131 1215 1
+283 1215 1
+384 1215 1
+28 1216 1
+55 1216 1
+317 1216 1
+60 1217 1
+207 1217 1
+320 1217 1
+88 1218 1
+301 1218 1
+391 1218 1
+94 1219 1
+430 1219 1
+477 1219 1
+58 1220 1
+167 1220 1
+171 1220 1
+83 1221 1
+248 1221 1
+336 1221 1
+38 1222 1
+163 1222 1
+273 1222 1
+218 1223 1
+475 1223 1
+500 1223 1
+7 1224 1
+77 1224 1
+446 1224 1
+1 1225 1
+218 1225 1
+414 1225 1
+71 1226 1
+124 1226 1
+340 1226 1
+296 1227 1
+367 1227 1
+484 1227 1
+149 1228 1
+176 1228 1
+306 1228 1
+355 1229 1
+415 1229 1
+453 1229 1
+146 1230 1
+426 1230 1
+445 1230 1
+179 1231 1
+188 1231 1
+327 1231 1
+64 1232 1
+380 1232 1
+405 1232 1
+2 1233 1
+58 1233 1
+406 1233 1
+418 1234 1
+488 1234 1
+506 1234 1
+155 1235 1
+209 1235 1
+236 1235 1
+127 1236 1
+170 1236 1
+491 1236 1
+76 1237 1
+164 1237 1
+371 1237 1
+348 1238 1
+354 1238 1
+508 1238 1
+54 1239 1
+134 1239 1
+471 1239 1
+83 1240 1
+212 1240 1
+446 1240 1
+251 1241 1
+334 1241 1
+501 1241 1
+48 1242 1
+255 1242 1
+290 1242 1
+27 1243 1
+220 1243 1
+366 1243 1
+185 1244 1
+349 1244 1
+507 1244 1
+32 1245 1
+110 1245 1
+250 1245 1
+84 1246 1
+288 1246 1
+394 1246 1
+4 1247 1
+227 1247 1
+403 1247 1
+89 1248 1
+350 1248 1
+458 1248 1
+107 1249 1
+201 1249 1
+266 1249 1
+360 1250 1
+406 1250 1
+509 1250 1
+257 1251 1
+319 1251 1
+351 1251 1
+29 1252 1
+442 1252 1
+493 1252 1
+54 1253 1
+117 1253 1
+252 1253 1
+318 1254 1
+330 1254 1
+510 1254 1
+56 1255 1
+228 1255 1
+456 1255 1
+95 1256 1
+148 1256 1
+176 1256 1
+295 1257 1
+424 1257 1
+440 1257 1
+51 1258 1
+267 1258 1
+419 1258 1
+45 1259 1
+155 1259 1
+378 1259 1
+47 1260 1
+452 1260 1
+506 1260 1
+24 1261 1
+161 1261 1
+399 1261 1
+256 1262 1
+345 1262 1
+442 1262 1
+173 1263 1
+217 1263 1
+319 1263 1
+92 1264 1
+474 1264 1
+514 1264 1
+154 1265 1
+179 1265 1
+462 1265 1
+63 1266 1
+208 1266 1
+275 1266 1
+255 1267 1
+328 1267 1
+459 1267 1
+321 1268 1
+367 1268 1
+378 1268 1
+132 1269 1
+254 1269 1
+350 1269 1
+76 1270 1
+173 1270 1
+226 1270 1
+116 1271 1
+210 1271 1
+494 1271 1
+92 1272 1
+259 1272 1
+430 1272 1
+308 1273 1
+458 1273 1
+494 1273 1
+20 1274 1
+296 1274 1
+394 1274 1
+52 1275 1
+277 1275 1
+486 1275 1
+178 1276 1
+206 1276 1
+442 1276 1
+292 1277 1
+296 1277 1
+381 1277 1
+87 1278 1
+162 1278 1
+233 1278 1
+216 1279 1
+480 1279 1
+500 1279 1
+275 1280 1
+430 1280 1
+504 1280 1
+16 1281 1
+183 1281 1
+504 1281 1
+152 1282 1
+202 1282 1
+308 1282 1
+151 1283 1
+268 1283 1
+494 1283 1
+165 1284 1
+263 1284 1
+366 1284 1
+226 1285 1
+274 1285 1
+353 1285 1
+276 1286 1
+312 1286 1
+469 1286 1
+36 1287 1
+374 1287 1
+439 1287 1
+1 1288 1
+96 1288 1
+463 1288 1
+333 1289 1
+445 1289 1
+516 1289 1
+30 1290 1
+66 1290 1
+109 1290 1
+428 1291 1
+463 1291 1
+473 1291 1
+17 1292 1
+321 1292 1
+473 1292 1
+136 1293 1
+250 1293 1
+343 1293 1
+11 1294 1
+204 1294 1
+383 1294 1
+192 1295 1
+194 1295 1
+435 1295 1
+45 1296 1
+129 1296 1
+282 1296 1
+40 1297 1
+78 1297 1
+509 1297 1
+34 1298 1
+342 1298 1
+420 1298 1
+268 1299 1
+485 1299 1
+514 1299 1
+68 1300 1
+289 1300 1
+333 1300 1
+292 1301 1
+387 1301 1
+450 1301 1
+54 1302 1
+67 1302 1
+307 1302 1
+85 1303 1
+119 1303 1
+477 1303 1
+120 1304 1
+256 1304 1
+375 1304 1
+116 1305 1
+241 1305 1
+398 1305 1
+206 1306 1
+341 1306 1
+466 1306 1
+92 1307 1
+110 1307 1
+382 1307 1
+99 1308 1
+215 1308 1
+479 1308 1
+213 1309 1
+276 1309 1
+452 1309 1
+91 1310 1
+226 1310 1
+283 1310 1
+15 1311 1
+186 1311 1
+285 1311 1
+14 1312 1
+276 1312 1
+495 1312 1
+43 1313 1
+266 1313 1
+482 1313 1
+112 1314 1
+198 1314 1
+425 1314 1
+305 1315 1
+331 1315 1
+430 1315 1
+319 1316 1
+455 1316 1
+505 1316 1
+157 1317 1
+167 1317 1
+322 1317 1
+136 1318 1
+232 1318 1
+444 1318 1
+76 1319 1
+89 1319 1
+503 1319 1
+25 1320 1
+355 1320 1
+497 1320 1
+141 1321 1
+166 1321 1
+449 1321 1
+95 1322 1
+336 1322 1
+486 1322 1
+82 1323 1
+147 1323 1
+338 1323 1
+11 1324 1
+397 1324 1
+440 1324 1
+32 1325 1
+167 1325 1
+355 1325 1
+41 1326 1
+260 1326 1
+488 1326 1
+74 1327 1
+175 1327 1
+413 1327 1
+49 1328 1
+282 1328 1
+352 1328 1
+301 1329 1
+465 1329 1
+513 1329 1
+122 1330 1
+265 1330 1
+331 1330 1
+128 1331 1
+178 1331 1
+333 1331 1
+338 1332 1
+453 1332 1
+506 1332 1
+94 1333 1
+189 1333 1
+423 1333 1
+129 1334 1
+132 1334 1
+183 1334 1
+265 1335 1
+273 1335 1
+361 1335 1
+71 1336 1
+202 1336 1
+474 1336 1
+11 1337 1
+132 1337 1
+461 1337 1
+109 1338 1
+209 1338 1
+409 1338 1
+22 1339 1
+62 1339 1
+425 1339 1
+328 1340 1
+400 1340 1
+411 1340 1
+13 1341 1
+397 1341 1
+481 1341 1
+105 1342 1
+114 1342 1
+397 1342 1
+22 1343 1
+225 1343 1
+470 1343 1
+196 1344 1
+299 1344 1
+332 1344 1
+240 1345 1
+288 1345 1
+395 1345 1
+198 1346 1
+259 1346 1
+343 1346 1
+7 1347 1
+228 1347 1
+298 1347 1
+146 1348 1
+149 1348 1
+159 1348 1
+181 1349 1
+319 1349 1
+476 1349 1
+115 1350 1
+160 1350 1
+512 1350 1
+62 1351 1
+327 1351 1
+398 1351 1
+61 1352 1
+406 1352 1
+444 1352 1
+218 1353 1
+411 1353 1
+516 1353 1
+64 1354 1
+217 1354 1
+505 1354 1
+170 1355 1
+374 1355 1
+499 1355 1
+222 1356 1
+286 1356 1
+397 1356 1
+15 1357 1
+229 1357 1
+421 1357 1
+99 1358 1
+236 1358 1
+271 1358 1
+36 1359 1
+129 1359 1
+130 1359 1
+31 1360 1
+232 1360 1
+424 1360 1
+258 1361 1
+403 1361 1
+456 1361 1
+69 1362 1
+266 1362 1
+270 1362 1
+41 1363 1
+432 1363 1
+463 1363 1
+56 1364 1
+189 1364 1
+431 1364 1
+60 1365 1
+115 1365 1
+334 1365 1
+129 1366 1
+338 1366 1
+397 1366 1
+33 1367 1
+120 1367 1
+399 1367 1
+103 1368 1
+342 1368 1
+509 1368 1
+57 1369 1
+197 1369 1
+335 1369 1
+21 1370 1
+248 1370 1
+341 1370 1
+103 1371 1
+310 1371 1
+443 1371 1
+127 1372 1
+269 1372 1
+392 1372 1
+165 1373 1
+298 1373 1
+509 1373 1
+13 1374 1
+79 1374 1
+338 1374 1
+39 1375 1
+156 1375 1
+284 1375 1
+328 1376 1
+453 1376 1
+468 1376 1
+105 1377 1
+325 1377 1
+382 1377 1
+228 1378 1
+468 1378 1
+477 1378 1
+107 1379 1
+116 1379 1
+443 1379 1
+120 1380 1
+246 1380 1
+331 1380 1
+86 1381 1
+210 1381 1
+455 1381 1
+98 1382 1
+438 1382 1
+445 1382 1
+27 1383 1
+43 1383 1
+169 1383 1
+54 1384 1
+256 1384 1
+296 1384 1
+205 1385 1
+378 1385 1
+511 1385 1
+167 1386 1
+294 1386 1
+491 1386 1
+244 1387 1
+398 1387 1
+408 1387 1
+74 1388 1
+84 1388 1
+427 1388 1
+238 1389 1
+366 1389 1
+408 1389 1
+38 1390 1
+122 1390 1
+318 1390 1
+89 1391 1
+311 1391 1
+405 1391 1
+5 1392 1
+174 1392 1
+182 1392 1
+120 1393 1
+346 1393 1
+392 1393 1
+329 1394 1
+377 1394 1
+390 1394 1
+37 1395 1
+320 1395 1
+488 1395 1
+37 1396 1
+111 1396 1
+219 1396 1
+278 1397 1
+309 1397 1
+368 1397 1
+24 1398 1
+243 1398 1
+369 1398 1
+140 1399 1
+162 1399 1
+384 1399 1
+118 1400 1
+329 1400 1
+372 1400 1
+127 1401 1
+165 1401 1
+336 1401 1
+203 1402 1
+307 1402 1
+399 1402 1
+23 1403 1
+229 1403 1
+502 1403 1
+106 1404 1
+266 1404 1
+515 1404 1
+286 1405 1
+305 1405 1
+356 1405 1
+243 1406 1
+267 1406 1
+486 1406 1
+72 1407 1
+94 1407 1
+325 1407 1
+152 1408 1
+230 1408 1
+293 1408 1
+86 1409 1
+454 1409 1
+504 1409 1
+61 1410 1
+131 1410 1
+162 1410 1
+22 1411 1
+72 1411 1
+451 1411 1
+11 1412 1
+50 1412 1
+295 1412 1
+6 1413 1
+209 1413 1
+339 1413 1
+34 1414 1
+199 1414 1
+220 1414 1
+256 1415 1
+283 1415 1
+471 1415 1
+269 1416 1
+329 1416 1
+421 1416 1
+158 1417 1
+178 1417 1
+351 1417 1
+175 1418 1
+400 1418 1
+433 1418 1
+211 1419 1
+236 1419 1
+334 1419 1
+317 1420 1
+388 1420 1
+392 1420 1
+253 1421 1
+423 1421 1
+465 1421 1
+50 1422 1
+127 1422 1
+303 1422 1
+50 1423 1
+190 1423 1
+418 1423 1
+27 1424 1
+287 1424 1
+306 1424 1
+130 1425 1
+175 1425 1
+316 1425 1
+454 1426 1
+477 1426 1
+515 1426 1
+41 1427 1
+274 1427 1
+317 1427 1
+250 1428 1
+314 1428 1
+438 1428 1
+267 1429 1
+465 1429 1
+482 1429 1
+144 1430 1
+389 1430 1
+454 1430 1
+303 1431 1
+410 1431 1
+475 1431 1
+11 1432 1
+350 1432 1
+370 1432 1
+104 1433 1
+131 1433 1
+459 1433 1
+63 1434 1
+263 1434 1
+496 1434 1
+18 1435 1
+108 1435 1
+505 1435 1
+124 1436 1
+201 1436 1
+384 1436 1
+104 1437 1
+127 1437 1
+185 1437 1
+58 1438 1
+130 1438 1
+172 1438 1
+140 1439 1
+468 1439 1
+497 1439 1
+25 1440 1
+59 1440 1
+171 1440 1
+151 1441 1
+223 1441 1
+281 1441 1
+58 1442 1
+148 1442 1
+400 1442 1
+239 1443 1
+341 1443 1
+418 1443 1
+286 1444 1
+336 1444 1
+499 1444 1
+155 1445 1
+414 1445 1
+436 1445 1
+217 1446 1
+235 1446 1
+391 1446 1
+27 1447 1
+36 1447 1
+108 1447 1
+182 1448 1
+288 1448 1
+468 1448 1
+10 1449 1
+171 1449 1
+280 1449 1
+398 1450 1
+405 1450 1
+422 1450 1
+65 1451 1
+111 1451 1
+313 1451 1
+190 1452 1
+395 1452 1
+467 1452 1
+81 1453 1
+271 1453 1
+398 1453 1
+69 1454 1
+122 1454 1
+464 1454 1
+119 1455 1
+154 1455 1
+167 1455 1
+78 1456 1
+150 1456 1
+254 1456 1
+20 1457 1
+164 1457 1
+168 1457 1
+136 1458 1
+403 1458 1
+448 1458 1
+106 1459 1
+460 1459 1
+465 1459 1
+51 1460 1
+374 1460 1
+505 1460 1
+188 1461 1
+213 1461 1
+471 1461 1
+200 1462 1
+208 1462 1
+312 1462 1
+350 1463 1
+464 1463 1
+467 1463 1
+303 1464 1
+310 1464 1
+418 1464 1
+133 1465 1
+143 1465 1
+403 1465 1
+53 1466 1
+356 1466 1
+374 1466 1
+73 1467 1
+204 1467 1
+470 1467 1
+15 1468 1
+81 1468 1
+459 1468 1
+158 1469 1
+273 1469 1
+347 1469 1
+262 1470 1
+314 1470 1
+468 1470 1
+150 1471 1
+287 1471 1
+395 1471 1
+192 1472 1
+380 1472 1
+425 1472 1
+10 1473 1
+16 1473 1
+19 1473 1
+289 1474 1
+410 1474 1
+472 1474 1
+162 1475 1
+313 1475 1
+510 1475 1
+362 1476 1
+385 1476 1
+456 1476 1
+234 1477 1
+410 1477 1
+428 1477 1
+232 1478 1
+406 1478 1
+495 1478 1
+16 1479 1
+23 1479 1
+75 1479 1
+225 1480 1
+240 1480 1
+255 1480 1
+334 1481 1
+370 1481 1
+467 1481 1
+294 1482 1
+373 1482 1
+465 1482 1
+6 1483 1
+416 1483 1
+425 1483 1
+105 1484 1
+355 1484 1
+512 1484 1
+125 1485 1
+204 1485 1
+387 1485 1
+68 1486 1
+176 1486 1
+426 1486 1
+72 1487 1
+187 1487 1
+335 1487 1
+176 1488 1
+329 1488 1
+453 1488 1
+239 1489 1
+357 1489 1
+474 1489 1
+20 1490 1
+292 1490 1
+487 1490 1
+163 1491 1
+282 1491 1
+480 1491 1
+353 1492 1
+384 1492 1
+462 1492 1
+118 1493 1
+212 1493 1
+344 1493 1
+117 1494 1
+273 1494 1
+511 1494 1
+170 1495 1
+202 1495 1
+207 1495 1
+90 1496 1
+262 1496 1
+309 1496 1
+258 1497 1
+385 1497 1
+419 1497 1
+50 1498 1
+198 1498 1
+419 1498 1
+45 1499 1
+191 1499 1
+395 1499 1
+88 1500 1
+402 1500 1
+424 1500 1
+87 1501 1
+230 1501 1
+272 1501 1
+128 1502 1
+266 1502 1
+346 1502 1
+85 1503 1
+179 1503 1
+382 1503 1
+4 1504 1
+389 1504 1
+460 1504 1
+62 1505 1
+210 1505 1
+352 1505 1
+34 1506 1
+165 1506 1
+169 1506 1
+268 1507 1
+375 1507 1
+442 1507 1
+258 1508 1
+261 1508 1
+476 1508 1
+183 1509 1
+287 1509 1
+404 1509 1
+25 1510 1
+302 1510 1
+473 1510 1
+146 1511 1
+471 1511 1
+511 1511 1
+85 1512 1
+250 1512 1
+330 1512 1
+44 1513 1
+144 1513 1
+196 1513 1
+133 1514 1
+284 1514 1
+334 1514 1
+107 1515 1
+279 1515 1
+329 1515 1
+140 1516 1
+277 1516 1
+438 1516 1
+87 1517 1
+382 1517 1
+438 1517 1
+64 1518 1
+118 1518 1
+503 1518 1
+18 1519 1
+65 1519 1
+255 1519 1
+70 1520 1
+126 1520 1
+481 1520 1
+76 1521 1
+235 1521 1
+500 1521 1
+95 1522 1
+158 1522 1
+420 1522 1
+309 1523 1
+354 1523 1
+472 1523 1
+147 1524 1
+150 1524 1
+509 1524 1
+34 1525 1
+53 1525 1
+394 1525 1
+308 1526 1
+331 1526 1
+450 1526 1
+19 1527 1
+68 1527 1
+255 1527 1
+237 1528 1
+280 1528 1
+472 1528 1
+21 1529 1
+51 1529 1
+373 1529 1
+217 1530 1
+219 1530 1
+365 1530 1
+115 1531 1
+432 1531 1
+488 1531 1
+49 1532 1
+90 1532 1
+305 1532 1
+177 1533 1
+236 1533 1
+496 1533 1
+201 1534 1
+213 1534 1
+418 1534 1
+88 1535 1
+137 1535 1
+193 1535 1
+149 1536 1
+289 1536 1
+368 1536 1
+163 1537 1
+256 1537 1
+305 1537 1
+5 1538 1
+366 1538 1
+508 1538 1
+325 1539 1
+469 1539 1
+495 1539 1
+455 1540 1
+484 1540 1
+494 1540 1
+96 1541 1
+125 1541 1
+199 1541 1
+52 1542 1
+289 1542 1
+420 1542 1
+77 1543 1
+454 1543 1
+514 1543 1
+24 1544 1
+49 1544 1
+450 1544 1
+152 1545 1
+155 1545 1
+201 1545 1
+130 1546 1
+392 1546 1
+496 1546 1
+207 1547 1
+221 1547 1
+238 1547 1
+67 1548 1
+181 1548 1
+264 1548 1
+220 1549 1
+238 1549 1
+411 1549 1
+36 1550 1
+137 1550 1
+358 1550 1
+18 1551 1
+85 1551 1
+229 1551 1
+48 1552 1
+222 1552 1
+287 1552 1
+88 1553 1
+105 1553 1
+493 1553 1
+40 1554 1
+228 1554 1
+346 1554 1
+148 1555 1
+351 1555 1
+409 1555 1
+179 1556 1
+380 1556 1
+489 1556 1
+6 1557 1
+22 1557 1
+102 1557 1
+155 1558 1
+379 1558 1
+480 1558 1
+19 1559 1
+322 1559 1
+413 1559 1
+138 1560 1
+409 1560 1
+435 1560 1
+74 1561 1
+215 1561 1
+290 1561 1
+39 1562 1
+234 1562 1
+317 1562 1
+51 1563 1
+174 1563 1
+303 1563 1
+198 1564 1
+275 1564 1
+348 1564 1
+141 1565 1
+356 1565 1
+376 1565 1
+142 1566 1
+182 1566 1
+314 1566 1
+106 1567 1
+212 1567 1
+422 1567 1
+103 1568 1
+272 1568 1
+297 1568 1
+67 1569 1
+203 1569 1
+343 1569 1
+111 1570 1
+194 1570 1
+250 1570 1
+107 1571 1
+426 1571 1
+513 1571 1
+186 1572 1
+215 1572 1
+466 1572 1
+68 1573 1
+279 1573 1
+290 1573 1
+37 1574 1
+234 1574 1
+289 1574 1
+166 1575 1
+279 1575 1
+431 1575 1
+28 1576 1
+388 1576 1
+503 1576 1
+94 1577 1
+164 1577 1
+451 1577 1
+289 1578 1
+318 1578 1
+516 1578 1
+15 1579 1
+219 1579 1
+328 1579 1
+126 1580 1
+205 1580 1
+305 1580 1
+121 1581 1
+152 1581 1
+427 1581 1
+43 1582 1
+74 1582 1
+361 1582 1
+108 1583 1
+304 1583 1
+307 1583 1
+117 1584 1
+242 1584 1
+469 1584 1
+128 1585 1
+136 1585 1
+341 1585 1
+406 1586 1
+440 1586 1
+476 1586 1
+71 1587 1
+304 1587 1
+371 1587 1
+333 1588 1
+466 1588 1
+489 1588 1
+39 1589 1
+238 1589 1
+328 1589 1
+38 1590 1
+347 1590 1
+355 1590 1
+69 1591 1
+201 1591 1
+310 1591 1
+313 1592 1
+373 1592 1
+437 1592 1
+267 1593 1
+275 1593 1
+515 1593 1
+17 1594 1
+325 1594 1
+402 1594 1
+249 1595 1
+364 1595 1
+386 1595 1
+40 1596 1
+362 1596 1
+403 1596 1
+351 1597 1
+393 1597 1
+412 1597 1
+40 1598 1
+103 1598 1
+357 1598 1
+202 1599 1
+394 1599 1
+440 1599 1
+138 1600 1
+365 1600 1
+486 1600 1
+262 1601 1
+359 1601 1
+448 1601 1
+105 1602 1
+338 1602 1
+399 1602 1
+324 1603 1
+332 1603 1
+337 1603 1
+75 1604 1
+322 1604 1
+514 1604 1
+267 1605 1
+369 1605 1
+426 1605 1
+123 1606 1
+270 1606 1
+478 1606 1
+141 1607 1
+216 1607 1
+506 1607 1
+156 1608 1
+363 1608 1
+462 1608 1
+78 1609 1
+135 1609 1
+360 1609 1
+112 1610 1
+353 1610 1
+466 1610 1
+408 1611 1
+460 1611 1
+496 1611 1
+97 1612 1
+157 1612 1
+279 1612 1
+173 1613 1
+282 1613 1
+397 1613 1
+91 1614 1
+402 1614 1
+479 1614 1
+99 1615 1
+414 1615 1
+428 1615 1
+239 1616 1
+393 1616 1
+505 1616 1
+25 1617 1
+196 1617 1
+421 1617 1
+376 1618 1
+403 1618 1
+461 1618 1
+25 1619 1
+178 1619 1
+257 1619 1
+254 1620 1
+294 1620 1
+437 1620 1
+185 1621 1
+276 1621 1
+418 1621 1
+157 1622 1
+193 1622 1
+315 1622 1
+15 1623 1
+282 1623 1
+440 1623 1
+61 1624 1
+217 1624 1
+498 1624 1
+71 1625 1
+86 1625 1
+337 1625 1
+113 1626 1
+234 1626 1
+387 1626 1
+237 1627 1
+351 1627 1
+490 1627 1
+237 1628 1
+433 1628 1
+437 1628 1
+48 1629 1
+337 1629 1
+466 1629 1
+29 1630 1
+64 1630 1
+220 1630 1
+89 1631 1
+236 1631 1
+500 1631 1
+1 1632 1
+184 1632 1
+479 1632 1
+79 1633 1
+423 1633 1
+470 1633 1
+41 1634 1
+64 1634 1
+218 1634 1
+3 1635 1
+362 1635 1
+380 1635 1
+24 1636 1
+241 1636 1
+431 1636 1
+13 1637 1
+210 1637 1
+243 1637 1
+187 1638 1
+247 1638 1
+396 1638 1
+96 1639 1
+483 1639 1
+492 1639 1
+52 1640 1
+298 1640 1
+443 1640 1
+30 1641 1
+122 1641 1
+507 1641 1
+137 1642 1
+191 1642 1
+373 1642 1
+70 1643 1
+243 1643 1
+477 1643 1
+82 1644 1
+245 1644 1
+395 1644 1
+1 1645 1
+46 1645 1
+188 1645 1
+47 1646 1
+458 1646 1
+496 1646 1
+34 1647 1
+278 1647 1
+366 1647 1
+444 1648 1
+447 1648 1
+457 1648 1
+146 1649 1
+311 1649 1
+422 1649 1
+63 1650 1
+326 1650 1
+336 1650 1
+47 1651 1
+360 1651 1
+376 1651 1
+59 1652 1
+71 1652 1
+450 1652 1
+154 1653 1
+224 1653 1
+391 1653 1
+115 1654 1
+354 1654 1
+494 1654 1
+129 1655 1
+148 1655 1
+245 1655 1
+298 1656 1
+360 1656 1
+384 1656 1
+61 1657 1
+74 1657 1
+77 1657 1
+3 1658 1
+6 1658 1
+44 1658 1
+64 1659 1
+215 1659 1
+478 1659 1
+85 1660 1
+290 1660 1
+438 1660 1
+75 1661 1
+374 1661 1
+454 1661 1
+244 1662 1
+313 1662 1
+407 1662 1
+12 1663 1
+200 1663 1
+285 1663 1
+47 1664 1
+185 1664 1
+508 1664 1
+101 1665 1
+116 1665 1
+198 1665 1
+103 1666 1
+133 1666 1
+457 1666 1
+7 1667 1
+28 1667 1
+261 1667 1
+169 1668 1
+224 1668 1
+322 1668 1
+125 1669 1
+467 1669 1
+492 1669 1
+213 1670 1
+357 1670 1
+482 1670 1
+271 1671 1
+291 1671 1
+338 1671 1
+378 1672 1
+473 1672 1
+512 1672 1
+271 1673 1
+379 1673 1
+405 1673 1
+100 1674 1
+388 1674 1
+420 1674 1
+126 1675 1
+188 1675 1
+312 1675 1
+134 1676 1
+246 1676 1
+464 1676 1
+131 1677 1
+340 1677 1
+416 1677 1
+31 1678 1
+67 1678 1
+80 1678 1
+32 1679 1
+240 1679 1
+412 1679 1
+16 1680 1
+144 1680 1
+249 1680 1
+310 1681 1
+475 1681 1
+501 1681 1
+222 1682 1
+314 1682 1
+412 1682 1
+95 1683 1
+193 1683 1
+452 1683 1
+12 1684 1
+179 1684 1
+505 1684 1
+154 1685 1
+215 1685 1
+426 1685 1
+89 1686 1
+150 1686 1
+379 1686 1
+391 1687 1
+423 1687 1
+451 1687 1
+205 1688 1
+360 1688 1
+479 1688 1
+8 1689 1
+192 1689 1
+387 1689 1
+27 1690 1
+102 1690 1
+137 1690 1
+1 1691 1
+159 1691 1
+340 1691 1
+85 1692 1
+127 1692 1
+507 1692 1
+192 1693 1
+204 1693 1
+483 1693 1
+85 1694 1
+154 1694 1
+459 1694 1
+117 1695 1
+168 1695 1
+203 1695 1
+140 1696 1
+423 1696 1
+453 1696 1
+127 1697 1
+373 1697 1
+420 1697 1
+132 1698 1
+172 1698 1
+358 1698 1
+35 1699 1
+48 1699 1
+84 1699 1
+31 1700 1
+140 1700 1
+499 1700 1
+12 1701 1
+327 1701 1
+503 1701 1
+263 1702 1
+292 1702 1
+408 1702 1
+121 1703 1
+358 1703 1
+443 1703 1
+6 1704 1
+221 1704 1
+350 1704 1
+81 1705 1
+426 1705 1
+515 1705 1
+65 1706 1
+154 1706 1
+200 1706 1
+71 1707 1
+101 1707 1
+295 1707 1
+78 1708 1
+331 1708 1
+376 1708 1
+88 1709 1
+337 1709 1
+442 1709 1
+140 1710 1
+235 1710 1
+369 1710 1
+85 1711 1
+102 1711 1
+423 1711 1
+227 1712 1
+251 1712 1
+346 1712 1
+347 1713 1
+409 1713 1
+420 1713 1
+68 1714 1
+238 1714 1
+445 1714 1
+50 1715 1
+283 1715 1
+456 1715 1
+7 1716 1
+151 1716 1
+465 1716 1
+44 1717 1
+307 1717 1
+337 1717 1
+215 1718 1
+278 1718 1
+475 1718 1
+128 1719 1
+357 1719 1
+438 1719 1
+26 1720 1
+247 1720 1
+258 1720 1
+2 1721 1
+484 1721 1
+506 1721 1
+96 1722 1
+229 1722 1
+377 1722 1
+55 1723 1
+152 1723 1
+364 1723 1
+66 1724 1
+69 1724 1
+185 1724 1
+54 1725 1
+311 1725 1
+321 1725 1
+22 1726 1
+241 1726 1
+305 1726 1
+161 1727 1
+225 1727 1
+282 1727 1
+258 1728 1
+388 1728 1
+509 1728 1
+7 1729 1
+230 1729 1
+301 1729 1
+13 1730 1
+140 1730 1
+321 1730 1
+124 1731 1
+146 1731 1
+398 1731 1
+101 1732 1
+370 1732 1
+456 1732 1
+265 1733 1
+429 1733 1
+511 1733 1
+21 1734 1
+26 1734 1
+465 1734 1
+83 1735 1
+134 1735 1
+281 1735 1
+233 1736 1
+466 1736 1
+516 1736 1
+203 1737 1
+240 1737 1
+450 1737 1
+274 1738 1
+372 1738 1
+435 1738 1
+59 1739 1
+197 1739 1
+286 1739 1
+354 1740 1
+389 1740 1
+416 1740 1
+99 1741 1
+145 1741 1
+475 1741 1
+59 1742 1
+136 1742 1
+254 1742 1
+139 1743 1
+176 1743 1
+393 1743 1
+13 1744 1
+187 1744 1
+469 1744 1
+377 1745 1
+400 1745 1
+414 1745 1
+107 1746 1
+264 1746 1
+429 1746 1
+102 1747 1
+221 1747 1
+460 1747 1
+23 1748 1
+366 1748 1
+389 1748 1
+184 1749 1
+446 1749 1
+478 1749 1
+32 1750 1
+311 1750 1
+492 1750 1
+115 1751 1
+364 1751 1
+503 1751 1
+61 1752 1
+186 1752 1
+453 1752 1
+169 1753 1
+404 1753 1
+444 1753 1
+320 1754 1
+363 1754 1
+393 1754 1
+27 1755 1
+101 1755 1
+467 1755 1
+171 1756 1
+243 1756 1
+294 1756 1
+293 1757 1
+400 1757 1
+420 1757 1
+57 1758 1
+120 1758 1
+157 1758 1
+62 1759 1
+146 1759 1
+279 1759 1
+46 1760 1
+389 1760 1
+513 1760 1
+58 1761 1
+203 1761 1
+497 1761 1
+147 1762 1
+190 1762 1
+204 1762 1
+139 1763 1
+278 1763 1
+444 1763 1
+235 1764 1
+300 1764 1
+514 1764 1
+52 1765 1
+260 1765 1
+348 1765 1
+46 1766 1
+196 1766 1
+459 1766 1
+375 1767 1
+430 1767 1
+454 1767 1
+46 1768 1
+106 1768 1
+270 1768 1
+218 1769 1
+260 1769 1
+413 1769 1
+319 1770 1
+367 1770 1
+440 1770 1
+368 1771 1
+436 1771 1
+494 1771 1
+61 1772 1
+222 1772 1
+434 1772 1
+29 1773 1
+359 1773 1
+465 1773 1
+174 1774 1
+433 1774 1
+505 1774 1
+172 1775 1
+417 1775 1
+429 1775 1
+83 1776 1
+184 1776 1
+384 1776 1
+325 1777 1
+371 1777 1
+514 1777 1
+29 1778 1
+301 1778 1
+466 1778 1
+200 1779 1
+275 1779 1
+486 1779 1
+198 1780 1
+336 1780 1
+475 1780 1
+18 1781 1
+111 1781 1
+510 1781 1
+303 1782 1
+428 1782 1
+436 1782 1
+114 1783 1
+129 1783 1
+437 1783 1
+173 1784 1
+304 1784 1
+434 1784 1
+213 1785 1
+303 1785 1
+457 1785 1
+35 1786 1
+73 1786 1
+516 1786 1
+102 1787 1
+224 1787 1
+454 1787 1
+20 1788 1
+449 1788 1
+473 1788 1
+35 1789 1
+175 1789 1
+332 1789 1
+211 1790 1
+255 1790 1
+433 1790 1
+46 1791 1
+446 1791 1
+479 1791 1
+180 1792 1
+326 1792 1
+499 1792 1
+99 1793 1
+123 1793 1
+405 1793 1
+301 1794 1
+315 1794 1
+482 1794 1
+250 1795 1
+315 1795 1
+497 1795 1
+208 1796 1
+223 1796 1
+503 1796 1
+178 1797 1
+327 1797 1
+411 1797 1
+93 1798 1
+161 1798 1
+351 1798 1
+30 1799 1
+194 1799 1
+199 1799 1
+76 1800 1
+97 1800 1
+380 1800 1
+52 1801 1
+201 1801 1
+216 1801 1
+165 1802 1
+309 1802 1
+420 1802 1
+159 1803 1
+383 1803 1
+387 1803 1
+372 1804 1
+407 1804 1
+426 1804 1
+225 1805 1
+302 1805 1
+450 1805 1
+278 1806 1
+326 1806 1
+404 1806 1
+138 1807 1
+209 1807 1
+370 1807 1
+136 1808 1
+324 1808 1
+447 1808 1
+145 1809 1
+198 1809 1
+386 1809 1
+231 1810 1
+356 1810 1
+452 1810 1
+79 1811 1
+107 1811 1
+135 1811 1
+44 1812 1
+88 1812 1
+253 1812 1
+137 1813 1
+189 1813 1
+482 1813 1
+50 1814 1
+276 1814 1
+416 1814 1
+55 1815 1
+247 1815 1
+276 1815 1
+119 1816 1
+144 1816 1
+171 1816 1
+125 1817 1
+339 1817 1
+419 1817 1
+39 1818 1
+320 1818 1
+420 1818 1
+138 1819 1
+221 1819 1
+288 1819 1
+101 1820 1
+169 1820 1
+241 1820 1
+25 1821 1
+140 1821 1
+474 1821 1
+166 1822 1
+226 1822 1
+391 1822 1
+23 1823 1
+118 1823 1
+368 1823 1
+192 1824 1
+379 1824 1
+488 1824 1
+18 1825 1
+333 1825 1
+365 1825 1
+39 1826 1
+69 1826 1
+400 1826 1
+178 1827 1
+300 1827 1
+363 1827 1
+116 1828 1
+262 1828 1
+354 1828 1
+28 1829 1
+218 1829 1
+274 1829 1
+178 1830 1
+265 1830 1
+415 1830 1
+59 1831 1
+257 1831 1
+345 1831 1
+188 1832 1
+251 1832 1
+376 1832 1
+198 1833 1
+310 1833 1
+467 1833 1
+16 1834 1
+27 1834 1
+138 1834 1
+96 1835 1
+265 1835 1
+479 1835 1
+46 1836 1
+227 1836 1
+295 1836 1
+186 1837 1
+369 1837 1
+391 1837 1
+108 1838 1
+220 1838 1
+382 1838 1
+59 1839 1
+146 1839 1
+483 1839 1
+255 1840 1
+412 1840 1
+444 1840 1
+199 1841 1
+265 1841 1
+446 1841 1
+258 1842 1
+272 1842 1
+390 1842 1
+252 1843 1
+286 1843 1
+304 1843 1
+88 1844 1
+286 1844 1
+510 1844 1
+118 1845 1
+229 1845 1
+507 1845 1
+134 1846 1
+283 1846 1
+385 1846 1
+383 1847 1
+395 1847 1
+452 1847 1
+150 1848 1
+209 1848 1
+216 1848 1
+5 1849 1
+372 1849 1
+457 1849 1
+139 1850 1
+290 1850 1
+472 1850 1
+239 1851 1
+488 1851 1
+498 1851 1
+228 1852 1
+293 1852 1
+438 1852 1
+38 1853 1
+184 1853 1
+408 1853 1
+227 1854 1
+360 1854 1
+388 1854 1
+263 1855 1
+342 1855 1
+368 1855 1
+43 1856 1
+194 1856 1
+498 1856 1
+67 1857 1
+132 1857 1
+464 1857 1
+175 1858 1
+313 1858 1
+462 1858 1
+97 1859 1
+290 1859 1
+466 1859 1
+188 1860 1
+448 1860 1
+508 1860 1
+63 1861 1
+385 1861 1
+515 1861 1
+147 1862 1
+162 1862 1
+321 1862 1
+189 1863 1
+232 1863 1
+375 1863 1
+17 1864 1
+31 1864 1
+337 1864 1
+154 1865 1
+270 1865 1
+448 1865 1
+62 1866 1
+271 1866 1
+273 1866 1
+370 1867 1
+383 1867 1
+455 1867 1
+219 1868 1
+318 1868 1
+435 1868 1
+1 1869 1
+242 1869 1
+380 1869 1
+198 1870 1
+251 1870 1
+354 1870 1
+22 1871 1
+157 1871 1
+254 1871 1
+56 1872 1
+79 1872 1
+242 1872 1
+90 1873 1
+119 1873 1
+324 1873 1
+318 1874 1
+421 1874 1
+489 1874 1
+15 1875 1
+401 1875 1
+477 1875 1
+20 1876 1
+178 1876 1
+245 1876 1
+171 1877 1
+231 1877 1
+427 1877 1
+45 1878 1
+152 1878 1
+195 1878 1
+100 1879 1
+207 1879 1
+508 1879 1
+30 1880 1
+55 1880 1
+187 1880 1
+126 1881 1
+163 1881 1
+210 1881 1
+131 1882 1
+274 1882 1
+328 1882 1
+234 1883 1
+313 1883 1
+498 1883 1
+11 1884 1
+125 1884 1
+145 1884 1
+207 1885 1
+251 1885 1
+485 1885 1
+254 1886 1
+256 1886 1
+304 1886 1
+299 1887 1
+468 1887 1
+493 1887 1
+349 1888 1
+385 1888 1
+392 1888 1
+120 1889 1
+329 1889 1
+507 1889 1
+196 1890 1
+227 1890 1
+324 1890 1
+21 1891 1
+272 1891 1
+400 1891 1
+26 1892 1
+317 1892 1
+419 1892 1
+170 1893 1
+196 1893 1
+430 1893 1
+114 1894 1
+427 1894 1
+439 1894 1
+77 1895 1
+466 1895 1
+513 1895 1
+8 1896 1
+96 1896 1
+432 1896 1
+57 1897 1
+216 1897 1
+417 1897 1
+190 1898 1
+449 1898 1
+496 1898 1
+11 1899 1
+14 1899 1
+364 1899 1
+214 1900 1
+441 1900 1
+474 1900 1
+212 1901 1
+333 1901 1
+511 1901 1
+345 1902 1
+484 1902 1
+493 1902 1
+179 1903 1
+363 1903 1
+435 1903 1
+225 1904 1
+383 1904 1
+487 1904 1
+64 1905 1
+303 1905 1
+366 1905 1
+114 1906 1
+155 1906 1
+364 1906 1
+80 1907 1
+172 1907 1
+455 1907 1
+185 1908 1
+188 1908 1
+384 1908 1
+66 1909 1
+348 1909 1
+359 1909 1
+138 1910 1
+169 1910 1
+195 1910 1
+149 1911 1
+256 1911 1
+329 1911 1
+43 1912 1
+199 1912 1
+263 1912 1
+190 1913 1
+193 1913 1
+349 1913 1
+127 1914 1
+188 1914 1
+248 1914 1
+3 1915 1
+455 1915 1
+486 1915 1
+3 1916 1
+86 1916 1
+371 1916 1
+153 1917 1
+161 1917 1
+166 1917 1
+222 1918 1
+235 1918 1
+257 1918 1
+210 1919 1
+247 1919 1
+471 1919 1
+11 1920 1
+288 1920 1
+339 1920 1
+56 1921 1
+135 1921 1
+380 1921 1
+104 1922 1
+344 1922 1
+357 1922 1
+53 1923 1
+427 1923 1
+437 1923 1
+153 1924 1
+381 1924 1
+441 1924 1
+130 1925 1
+148 1925 1
+191 1925 1
+56 1926 1
+261 1926 1
+443 1926 1
+83 1927 1
+128 1927 1
+268 1927 1
+71 1928 1
+193 1928 1
+197 1928 1
+274 1929 1
+287 1929 1
+444 1929 1
+95 1930 1
+221 1930 1
+306 1930 1
+74 1931 1
+347 1931 1
+363 1931 1
+121 1932 1
+155 1932 1
+160 1932 1
+106 1933 1
+172 1933 1
+346 1933 1
+173 1934 1
+204 1934 1
+345 1934 1
+16 1935 1
+334 1935 1
+376 1935 1
+114 1936 1
+255 1936 1
+401 1936 1
+270 1937 1
+380 1937 1
+479 1937 1
+33 1938 1
+189 1938 1
+195 1938 1
+53 1939 1
+241 1939 1
+243 1939 1
+267 1940 1
+277 1940 1
+514 1940 1
+49 1941 1
+226 1941 1
+481 1941 1
+332 1942 1
+448 1942 1
+489 1942 1
+306 1943 1
+413 1943 1
+445 1943 1
+68 1944 1
+81 1944 1
+432 1944 1
+35 1945 1
+441 1945 1
+451 1945 1
+28 1946 1
+223 1946 1
+460 1946 1
+32 1947 1
+162 1947 1
+252 1947 1
+213 1948 1
+429 1948 1
+443 1948 1
+24 1949 1
+292 1949 1
+332 1949 1
+113 1950 1
+205 1950 1
+283 1950 1
+40 1951 1
+146 1951 1
+416 1951 1
+18 1952 1
+439 1952 1
+502 1952 1
+9 1953 1
+110 1953 1
+140 1953 1
+89 1954 1
+114 1954 1
+164 1954 1
+294 1955 1
+304 1955 1
+415 1955 1
+250 1956 1
+261 1956 1
+359 1956 1
+256 1957 1
+378 1957 1
+470 1957 1
+70 1958 1
+88 1958 1
+90 1958 1
+208 1959 1
+278 1959 1
+411 1959 1
+291 1960 1
+386 1960 1
+425 1960 1
+91 1961 1
+123 1961 1
+422 1961 1
+82 1962 1
+226 1962 1
+352 1962 1
+314 1963 1
+329 1963 1
+344 1963 1
+39 1964 1
+165 1964 1
+501 1964 1
+7 1965 1
+83 1965 1
+386 1965 1
+181 1966 1
+295 1966 1
+335 1966 1
+78 1967 1
+213 1967 1
+458 1967 1
+13 1968 1
+408 1968 1
+449 1968 1
+301 1969 1
+355 1969 1
+478 1969 1
+405 1970 1
+414 1970 1
+480 1970 1
+112 1971 1
+336 1971 1
+477 1971 1
+316 1972 1
+440 1972 1
+487 1972 1
+156 1973 1
+366 1973 1
+413 1973 1
+393 1974 1
+409 1974 1
+444 1974 1
+12 1975 1
+142 1975 1
+244 1975 1
+110 1976 1
+153 1976 1
+157 1976 1
+48 1977 1
+168 1977 1
+451 1977 1
+73 1978 1
+128 1978 1
+423 1978 1
+166 1979 1
+470 1979 1
+480 1979 1
+39 1980 1
+266 1980 1
+297 1980 1
+17 1981 1
+82 1981 1
+284 1981 1
+132 1982 1
+280 1982 1
+495 1982 1
+204 1983 1
+428 1983 1
+431 1983 1
+104 1984 1
+250 1984 1
+384 1984 1
+63 1985 1
+360 1985 1
+418 1985 1
+62 1986 1
+238 1986 1
+363 1986 1
+1 1987 1
+99 1987 1
+325 1987 1
+45 1988 1
+53 1988 1
+245 1988 1
+393 1989 1
+424 1989 1
+447 1989 1
+5 1990 1
+176 1990 1
+313 1990 1
+115 1991 1
+285 1991 1
+485 1991 1
+47 1992 1
+263 1992 1
+436 1992 1
+18 1993 1
+212 1993 1
+391 1993 1
+248 1994 1
+268 1994 1
+357 1994 1
+16 1995 1
+316 1995 1
+512 1995 1
+272 1996 1
+377 1996 1
+490 1996 1
+75 1997 1
+335 1997 1
+487 1997 1
+317 1998 1
+387 1998 1
+417 1998 1
+84 1999 1
+168 1999 1
+512 1999 1
+70 2000 1
+144 2000 1
+324 2000 1
+342 2001 1
+428 2001 1
+496 2001 1
+207 2002 1
+326 2002 1
+366 2002 1
+14 2003 1
+132 2003 1
+152 2003 1
+191 2004 1
+232 2004 1
+452 2004 1
+77 2005 1
+252 2005 1
+343 2005 1
+154 2006 1
+300 2006 1
+361 2006 1
+12 2007 1
+51 2007 1
+389 2007 1
+107 2008 1
+146 2008 1
+254 2008 1
+230 2009 1
+308 2009 1
+446 2009 1
+132 2010 1
+371 2010 1
+471 2010 1
+280 2011 1
+486 2011 1
+502 2011 1
+42 2012 1
+279 2012 1
+399 2012 1
+23 2013 1
+275 2013 1
+485 2013 1
+147 2014 1
+370 2014 1
+395 2014 1
+149 2015 1
+223 2015 1
+345 2015 1
+17 2016 1
+33 2016 1
+474 2016 1
+18 2017 1
+304 2017 1
+337 2017 1
+8 2018 1
+296 2018 1
+481 2018 1
+174 2019 1
+217 2019 1
+249 2019 1
+73 2020 1
+442 2020 1
+510 2020 1
+261 2021 1
+360 2021 1
+458 2021 1
+197 2022 1
+280 2022 1
+514 2022 1
+72 2023 1
+75 2023 1
+90 2023 1
+4 2024 1
+354 2024 1
+362 2024 1
+15 2025 1
+182 2025 1
+463 2025 1
+34 2026 1
+139 2026 1
+347 2026 1
+163 2027 1
+397 2027 1
+477 2027 1
+159 2028 1
+236 2028 1
+257 2028 1
+136 2029 1
+442 2029 1
+489 2029 1
+12 2030 1
+361 2030 1
+405 2030 1
+36 2031 1
+45 2031 1
+143 2031 1
+196 2032 1
+233 2032 1
+259 2032 1
+3 2033 1
+193 2033 1
+286 2033 1
+40 2034 1
+479 2034 1
+495 2034 1
+167 2035 1
+206 2035 1
+382 2035 1
+71 2036 1
+153 2036 1
+224 2036 1
+101 2037 1
+121 2037 1
+177 2037 1
+111 2038 1
+299 2038 1
+446 2038 1
+100 2039 1
+201 2039 1
+260 2039 1
+237 2040 1
+255 2040 1
+427 2040 1
+300 2041 1
+426 2041 1
+438 2041 1
+32 2042 1
+318 2042 1
+434 2042 1
+76 2043 1
+286 2043 1
+511 2043 1
+9 2044 1
+54 2044 1
+187 2044 1
+14 2045 1
+143 2045 1
+383 2045 1
+137 2046 1
+302 2046 1
+423 2046 1
+6 2047 1
+57 2047 1
+193 2047 1
+53 2048 1
+148 2048 1
+430 2048 1
+202 2049 1
+320 2049 1
+427 2049 1
+71 2050 1
+231 2050 1
+447 2050 1
+52 2051 1
+218 2051 1
+435 2051 1
+148 2052 1
+377 2052 1
+487 2052 1
+219 2053 1
+498 2053 1
+502 2053 1
+17 2054 1
+206 2054 1
+338 2054 1
+299 2055 1
+359 2055 1
+407 2055 1
+41 2056 1
+238 2056 1
+323 2056 1
+108 2057 1
+235 2057 1
+407 2057 1
+48 2058 1
+379 2058 1
+387 2058 1
+143 2059 1
+160 2059 1
+166 2059 1
+65 2060 1
+391 2060 1
+512 2060 1
+316 2061 1
+381 2061 1
+473 2061 1
+133 2062 1
+261 2062 1
+310 2062 1
+142 2063 1
+297 2063 1
+457 2063 1
+92 2064 1
+277 2064 1
+490 2064 1
+1 2065 1
+2 2065 1
+2 2066 1
+3 2066 1
+3 2067 1
+4 2067 1
+4 2068 1
+5 2068 1
+5 2069 1
+6 2069 1
+6 2070 1
+7 2070 1
+7 2071 1
+8 2071 1
+8 2072 1
+9 2072 1
+9 2073 1
+10 2073 1
+10 2074 1
+11 2074 1
+11 2075 1
+12 2075 1
+12 2076 1
+13 2076 1
+13 2077 1
+14 2077 1
+14 2078 1
+15 2078 1
+15 2079 1
+16 2079 1
+16 2080 1
+17 2080 1
+17 2081 1
+18 2081 1
+18 2082 1
+19 2082 1
+19 2083 1
+20 2083 1
+20 2084 1
+21 2084 1
+21 2085 1
+22 2085 1
+22 2086 1
+23 2086 1
+23 2087 1
+24 2087 1
+24 2088 1
+25 2088 1
+25 2089 1
+26 2089 1
+26 2090 1
+27 2090 1
+27 2091 1
+28 2091 1
+28 2092 1
+29 2092 1
+29 2093 1
+30 2093 1
+30 2094 1
+31 2094 1
+31 2095 1
+32 2095 1
+32 2096 1
+33 2096 1
+33 2097 1
+34 2097 1
+34 2098 1
+35 2098 1
+35 2099 1
+36 2099 1
+36 2100 1
+37 2100 1
+37 2101 1
+38 2101 1
+38 2102 1
+39 2102 1
+39 2103 1
+40 2103 1
+40 2104 1
+41 2104 1
+41 2105 1
+42 2105 1
+42 2106 1
+43 2106 1
+43 2107 1
+44 2107 1
+44 2108 1
+45 2108 1
+45 2109 1
+46 2109 1
+46 2110 1
+47 2110 1
+47 2111 1
+48 2111 1
+48 2112 1
+49 2112 1
+49 2113 1
+50 2113 1
+50 2114 1
+51 2114 1
+51 2115 1
+52 2115 1
+52 2116 1
+53 2116 1
+53 2117 1
+54 2117 1
+54 2118 1
+55 2118 1
+55 2119 1
+56 2119 1
+56 2120 1
+57 2120 1
+57 2121 1
+58 2121 1
+58 2122 1
+59 2122 1
+59 2123 1
+60 2123 1
+60 2124 1
+61 2124 1
+61 2125 1
+62 2125 1
+62 2126 1
+63 2126 1
+63 2127 1
+64 2127 1
+64 2128 1
+65 2128 1
+65 2129 1
+66 2129 1
+66 2130 1
+67 2130 1
+67 2131 1
+68 2131 1
+68 2132 1
+69 2132 1
+69 2133 1
+70 2133 1
+70 2134 1
+71 2134 1
+71 2135 1
+72 2135 1
+72 2136 1
+73 2136 1
+73 2137 1
+74 2137 1
+74 2138 1
+75 2138 1
+75 2139 1
+76 2139 1
+76 2140 1
+77 2140 1
+77 2141 1
+78 2141 1
+78 2142 1
+79 2142 1
+79 2143 1
+80 2143 1
+80 2144 1
+81 2144 1
+81 2145 1
+82 2145 1
+82 2146 1
+83 2146 1
+83 2147 1
+84 2147 1
+84 2148 1
+85 2148 1
+85 2149 1
+86 2149 1
+86 2150 1
+87 2150 1
+87 2151 1
+88 2151 1
+88 2152 1
+89 2152 1
+89 2153 1
+90 2153 1
+90 2154 1
+91 2154 1
+91 2155 1
+92 2155 1
+92 2156 1
+93 2156 1
+93 2157 1
+94 2157 1
+94 2158 1
+95 2158 1
+95 2159 1
+96 2159 1
+96 2160 1
+97 2160 1
+97 2161 1
+98 2161 1
+98 2162 1
+99 2162 1
+99 2163 1
+100 2163 1
+100 2164 1
+101 2164 1
+101 2165 1
+102 2165 1
+102 2166 1
+103 2166 1
+103 2167 1
+104 2167 1
+104 2168 1
+105 2168 1
+105 2169 1
+106 2169 1
+106 2170 1
+107 2170 1
+107 2171 1
+108 2171 1
+108 2172 1
+109 2172 1
+109 2173 1
+110 2173 1
+110 2174 1
+111 2174 1
+111 2175 1
+112 2175 1
+112 2176 1
+113 2176 1
+113 2177 1
+114 2177 1
+114 2178 1
+115 2178 1
+115 2179 1
+116 2179 1
+116 2180 1
+117 2180 1
+117 2181 1
+118 2181 1
+118 2182 1
+119 2182 1
+119 2183 1
+120 2183 1
+120 2184 1
+121 2184 1
+121 2185 1
+122 2185 1
+122 2186 1
+123 2186 1
+123 2187 1
+124 2187 1
+124 2188 1
+125 2188 1
+125 2189 1
+126 2189 1
+126 2190 1
+127 2190 1
+127 2191 1
+128 2191 1
+128 2192 1
+129 2192 1
+129 2193 1
+130 2193 1
+130 2194 1
+131 2194 1
+131 2195 1
+132 2195 1
+132 2196 1
+133 2196 1
+133 2197 1
+134 2197 1
+134 2198 1
+135 2198 1
+135 2199 1
+136 2199 1
+136 2200 1
+137 2200 1
+137 2201 1
+138 2201 1
+138 2202 1
+139 2202 1
+139 2203 1
+140 2203 1
+140 2204 1
+141 2204 1
+141 2205 1
+142 2205 1
+142 2206 1
+143 2206 1
+143 2207 1
+144 2207 1
+144 2208 1
+145 2208 1
+145 2209 1
+146 2209 1
+146 2210 1
+147 2210 1
+147 2211 1
+148 2211 1
+148 2212 1
+149 2212 1
+149 2213 1
+150 2213 1
+150 2214 1
+151 2214 1
+151 2215 1
+152 2215 1
+152 2216 1
+153 2216 1
+153 2217 1
+154 2217 1
+154 2218 1
+155 2218 1
+155 2219 1
+156 2219 1
+156 2220 1
+157 2220 1
+157 2221 1
+158 2221 1
+158 2222 1
+159 2222 1
+159 2223 1
+160 2223 1
+160 2224 1
+161 2224 1
+161 2225 1
+162 2225 1
+162 2226 1
+163 2226 1
+163 2227 1
+164 2227 1
+164 2228 1
+165 2228 1
+165 2229 1
+166 2229 1
+166 2230 1
+167 2230 1
+167 2231 1
+168 2231 1
+168 2232 1
+169 2232 1
+169 2233 1
+170 2233 1
+170 2234 1
+171 2234 1
+171 2235 1
+172 2235 1
+172 2236 1
+173 2236 1
+173 2237 1
+174 2237 1
+174 2238 1
+175 2238 1
+175 2239 1
+176 2239 1
+176 2240 1
+177 2240 1
+177 2241 1
+178 2241 1
+178 2242 1
+179 2242 1
+179 2243 1
+180 2243 1
+180 2244 1
+181 2244 1
+181 2245 1
+182 2245 1
+182 2246 1
+183 2246 1
+183 2247 1
+184 2247 1
+184 2248 1
+185 2248 1
+185 2249 1
+186 2249 1
+186 2250 1
+187 2250 1
+187 2251 1
+188 2251 1
+188 2252 1
+189 2252 1
+189 2253 1
+190 2253 1
+190 2254 1
+191 2254 1
+191 2255 1
+192 2255 1
+192 2256 1
+193 2256 1
+193 2257 1
+194 2257 1
+194 2258 1
+195 2258 1
+195 2259 1
+196 2259 1
+196 2260 1
+197 2260 1
+197 2261 1
+198 2261 1
+198 2262 1
+199 2262 1
+199 2263 1
+200 2263 1
+200 2264 1
+201 2264 1
+201 2265 1
+202 2265 1
+202 2266 1
+203 2266 1
+203 2267 1
+204 2267 1
+204 2268 1
+205 2268 1
+205 2269 1
+206 2269 1
+206 2270 1
+207 2270 1
+207 2271 1
+208 2271 1
+208 2272 1
+209 2272 1
+209 2273 1
+210 2273 1
+210 2274 1
+211 2274 1
+211 2275 1
+212 2275 1
+212 2276 1
+213 2276 1
+213 2277 1
+214 2277 1
+214 2278 1
+215 2278 1
+215 2279 1
+216 2279 1
+216 2280 1
+217 2280 1
+217 2281 1
+218 2281 1
+218 2282 1
+219 2282 1
+219 2283 1
+220 2283 1
+220 2284 1
+221 2284 1
+221 2285 1
+222 2285 1
+222 2286 1
+223 2286 1
+223 2287 1
+224 2287 1
+224 2288 1
+225 2288 1
+225 2289 1
+226 2289 1
+226 2290 1
+227 2290 1
+227 2291 1
+228 2291 1
+228 2292 1
+229 2292 1
+229 2293 1
+230 2293 1
+230 2294 1
+231 2294 1
+231 2295 1
+232 2295 1
+232 2296 1
+233 2296 1
+233 2297 1
+234 2297 1
+234 2298 1
+235 2298 1
+235 2299 1
+236 2299 1
+236 2300 1
+237 2300 1
+237 2301 1
+238 2301 1
+238 2302 1
+239 2302 1
+239 2303 1
+240 2303 1
+240 2304 1
+241 2304 1
+241 2305 1
+242 2305 1
+242 2306 1
+243 2306 1
+243 2307 1
+244 2307 1
+244 2308 1
+245 2308 1
+245 2309 1
+246 2309 1
+246 2310 1
+247 2310 1
+247 2311 1
+248 2311 1
+248 2312 1
+249 2312 1
+249 2313 1
+250 2313 1
+250 2314 1
+251 2314 1
+251 2315 1
+252 2315 1
+252 2316 1
+253 2316 1
+253 2317 1
+254 2317 1
+254 2318 1
+255 2318 1
+255 2319 1
+256 2319 1
+256 2320 1
+257 2320 1
+257 2321 1
+258 2321 1
+258 2322 1
+259 2322 1
+259 2323 1
+260 2323 1
+260 2324 1
+261 2324 1
+261 2325 1
+262 2325 1
+262 2326 1
+263 2326 1
+263 2327 1
+264 2327 1
+264 2328 1
+265 2328 1
+265 2329 1
+266 2329 1
+266 2330 1
+267 2330 1
+267 2331 1
+268 2331 1
+268 2332 1
+269 2332 1
+269 2333 1
+270 2333 1
+270 2334 1
+271 2334 1
+271 2335 1
+272 2335 1
+272 2336 1
+273 2336 1
+273 2337 1
+274 2337 1
+274 2338 1
+275 2338 1
+275 2339 1
+276 2339 1
+276 2340 1
+277 2340 1
+277 2341 1
+278 2341 1
+278 2342 1
+279 2342 1
+279 2343 1
+280 2343 1
+280 2344 1
+281 2344 1
+281 2345 1
+282 2345 1
+282 2346 1
+283 2346 1
+283 2347 1
+284 2347 1
+284 2348 1
+285 2348 1
+285 2349 1
+286 2349 1
+286 2350 1
+287 2350 1
+287 2351 1
+288 2351 1
+288 2352 1
+289 2352 1
+289 2353 1
+290 2353 1
+290 2354 1
+291 2354 1
+291 2355 1
+292 2355 1
+292 2356 1
+293 2356 1
+293 2357 1
+294 2357 1
+294 2358 1
+295 2358 1
+295 2359 1
+296 2359 1
+296 2360 1
+297 2360 1
+297 2361 1
+298 2361 1
+298 2362 1
+299 2362 1
+299 2363 1
+300 2363 1
+300 2364 1
+301 2364 1
+301 2365 1
+302 2365 1
+302 2366 1
+303 2366 1
+303 2367 1
+304 2367 1
+304 2368 1
+305 2368 1
+305 2369 1
+306 2369 1
+306 2370 1
+307 2370 1
+307 2371 1
+308 2371 1
+308 2372 1
+309 2372 1
+309 2373 1
+310 2373 1
+310 2374 1
+311 2374 1
+311 2375 1
+312 2375 1
+312 2376 1
+313 2376 1
+313 2377 1
+314 2377 1
+314 2378 1
+315 2378 1
+315 2379 1
+316 2379 1
+316 2380 1
+317 2380 1
+317 2381 1
+318 2381 1
+318 2382 1
+319 2382 1
+319 2383 1
+320 2383 1
+320 2384 1
+321 2384 1
+321 2385 1
+322 2385 1
+322 2386 1
+323 2386 1
+323 2387 1
+324 2387 1
+324 2388 1
+325 2388 1
+325 2389 1
+326 2389 1
+326 2390 1
+327 2390 1
+327 2391 1
+328 2391 1
+328 2392 1
+329 2392 1
+329 2393 1
+330 2393 1
+330 2394 1
+331 2394 1
+331 2395 1
+332 2395 1
+332 2396 1
+333 2396 1
+333 2397 1
+334 2397 1
+334 2398 1
+335 2398 1
+335 2399 1
+336 2399 1
+336 2400 1
+337 2400 1
+337 2401 1
+338 2401 1
+338 2402 1
+339 2402 1
+339 2403 1
+340 2403 1
+340 2404 1
+341 2404 1
+341 2405 1
+342 2405 1
+342 2406 1
+343 2406 1
+343 2407 1
+344 2407 1
+344 2408 1
+345 2408 1
+345 2409 1
+346 2409 1
+346 2410 1
+347 2410 1
+347 2411 1
+348 2411 1
+348 2412 1
+349 2412 1
+349 2413 1
+350 2413 1
+350 2414 1
+351 2414 1
+351 2415 1
+352 2415 1
+352 2416 1
+353 2416 1
+353 2417 1
+354 2417 1
+354 2418 1
+355 2418 1
+355 2419 1
+356 2419 1
+356 2420 1
+357 2420 1
+357 2421 1
+358 2421 1
+358 2422 1
+359 2422 1
+359 2423 1
+360 2423 1
+360 2424 1
+361 2424 1
+361 2425 1
+362 2425 1
+362 2426 1
+363 2426 1
+363 2427 1
+364 2427 1
+364 2428 1
+365 2428 1
+365 2429 1
+366 2429 1
+366 2430 1
+367 2430 1
+367 2431 1
+368 2431 1
+368 2432 1
+369 2432 1
+369 2433 1
+370 2433 1
+370 2434 1
+371 2434 1
+371 2435 1
+372 2435 1
+372 2436 1
+373 2436 1
+373 2437 1
+374 2437 1
+374 2438 1
+375 2438 1
+375 2439 1
+376 2439 1
+376 2440 1
+377 2440 1
+377 2441 1
+378 2441 1
+378 2442 1
+379 2442 1
+379 2443 1
+380 2443 1
+380 2444 1
+381 2444 1
+381 2445 1
+382 2445 1
+382 2446 1
+383 2446 1
+383 2447 1
+384 2447 1
+384 2448 1
+385 2448 1
+385 2449 1
+386 2449 1
+386 2450 1
+387 2450 1
+387 2451 1
+388 2451 1
+388 2452 1
+389 2452 1
+389 2453 1
+390 2453 1
+390 2454 1
+391 2454 1
+391 2455 1
+392 2455 1
+392 2456 1
+393 2456 1
+393 2457 1
+394 2457 1
+394 2458 1
+395 2458 1
+395 2459 1
+396 2459 1
+396 2460 1
+397 2460 1
+397 2461 1
+398 2461 1
+398 2462 1
+399 2462 1
+399 2463 1
+400 2463 1
+400 2464 1
+401 2464 1
+401 2465 1
+402 2465 1
+402 2466 1
+403 2466 1
+403 2467 1
+404 2467 1
+404 2468 1
+405 2468 1
+405 2469 1
+406 2469 1
+406 2470 1
+407 2470 1
+407 2471 1
+408 2471 1
+408 2472 1
+409 2472 1
+409 2473 1
+410 2473 1
+410 2474 1
+411 2474 1
+411 2475 1
+412 2475 1
+412 2476 1
+413 2476 1
+413 2477 1
+414 2477 1
+414 2478 1
+415 2478 1
+415 2479 1
+416 2479 1
+416 2480 1
+417 2480 1
+417 2481 1
+418 2481 1
+418 2482 1
+419 2482 1
+419 2483 1
+420 2483 1
+420 2484 1
+421 2484 1
+421 2485 1
+422 2485 1
+422 2486 1
+423 2486 1
+423 2487 1
+424 2487 1
+424 2488 1
+425 2488 1
+425 2489 1
+426 2489 1
+426 2490 1
+427 2490 1
+427 2491 1
+428 2491 1
+428 2492 1
+429 2492 1
+429 2493 1
+430 2493 1
+430 2494 1
+431 2494 1
+431 2495 1
+432 2495 1
+432 2496 1
+433 2496 1
+433 2497 1
+434 2497 1
+434 2498 1
+435 2498 1
+435 2499 1
+436 2499 1
+436 2500 1
+437 2500 1
+437 2501 1
+438 2501 1
+438 2502 1
+439 2502 1
+439 2503 1
+440 2503 1
+440 2504 1
+441 2504 1
+441 2505 1
+442 2505 1
+442 2506 1
+443 2506 1
+443 2507 1
+444 2507 1
+444 2508 1
+445 2508 1
+445 2509 1
+446 2509 1
+446 2510 1
+447 2510 1
+447 2511 1
+448 2511 1
+448 2512 1
+449 2512 1
+449 2513 1
+450 2513 1
+450 2514 1
+451 2514 1
+451 2515 1
+452 2515 1
+452 2516 1
+453 2516 1
+453 2517 1
+454 2517 1
+454 2518 1
+455 2518 1
+455 2519 1
+456 2519 1
+456 2520 1
+457 2520 1
+457 2521 1
+458 2521 1
+458 2522 1
+459 2522 1
+459 2523 1
+460 2523 1
+460 2524 1
+461 2524 1
+461 2525 1
+462 2525 1
+462 2526 1
+463 2526 1
+463 2527 1
+464 2527 1
+464 2528 1
+465 2528 1
+465 2529 1
+466 2529 1
+466 2530 1
+467 2530 1
+467 2531 1
+468 2531 1
+468 2532 1
+469 2532 1
+469 2533 1
+470 2533 1
+470 2534 1
+471 2534 1
+471 2535 1
+472 2535 1
+472 2536 1
+473 2536 1
+473 2537 1
+474 2537 1
+474 2538 1
+475 2538 1
+475 2539 1
+476 2539 1
+476 2540 1
+477 2540 1
+477 2541 1
+478 2541 1
+478 2542 1
+479 2542 1
+479 2543 1
+480 2543 1
+480 2544 1
+481 2544 1
+481 2545 1
+482 2545 1
+482 2546 1
+483 2546 1
+483 2547 1
+484 2547 1
+484 2548 1
+485 2548 1
+485 2549 1
+486 2549 1
+486 2550 1
+487 2550 1
+487 2551 1
+488 2551 1
+488 2552 1
+489 2552 1
+489 2553 1
+490 2553 1
+490 2554 1
+491 2554 1
+491 2555 1
+492 2555 1
+492 2556 1
+493 2556 1
+493 2557 1
+494 2557 1
+494 2558 1
+495 2558 1
+495 2559 1
+496 2559 1
+496 2560 1
+497 2560 1
+497 2561 1
+498 2561 1
+498 2562 1
+499 2562 1
+499 2563 1
+500 2563 1
+500 2564 1
+501 2564 1
+501 2565 1
+502 2565 1
+502 2566 1
+503 2566 1
+503 2567 1
+504 2567 1
+504 2568 1
+505 2568 1
+505 2569 1
+506 2569 1
+506 2570 1
+507 2570 1
+507 2571 1
+508 2571 1
+508 2572 1
+509 2572 1
+509 2573 1
+510 2573 1
+510 2574 1
+511 2574 1
+511 2575 1
+512 2575 1
+512 2576 1
+513 2576 1
+513 2577 1
+514 2577 1
+514 2578 1
+515 2578 1
+515 2579 1
+516 2579 1
+516 2580 1
+
+
diff --git a/codec2/branches/0.7/octave/HRA_112_112.txt b/codec2/branches/0.7/octave/HRA_112_112.txt
new file mode 100644 (file)
index 0000000..e774640
--- /dev/null
@@ -0,0 +1,119 @@
+# Created by Octave 3.8.1, Wed Mar 15 17:24:05 2017 ACDT <david@penetrator>
+# name: HRA_112_112
+# type: matrix
+# rows: 112
+# columns: 224
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
+ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
+
+
diff --git a/codec2/branches/0.7/octave/HRA_112_56.txt b/codec2/branches/0.7/octave/HRA_112_56.txt
new file mode 100644 (file)
index 0000000..1df20d8
--- /dev/null
@@ -0,0 +1,63 @@
+# Created by Octave 3.8.1, Wed Mar 15 17:59:13 2017 ACDT <david@penetrator>
+# name: HRA_112_56
+# type: matrix
+# rows: 56
+# columns: 168
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
+ 0 0 0 0 1 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
+
+
diff --git a/codec2/branches/0.7/octave/HRA_56_28.txt b/codec2/branches/0.7/octave/HRA_56_28.txt
new file mode 100644 (file)
index 0000000..ae76248
--- /dev/null
@@ -0,0 +1,35 @@
+# Created by Octave 3.8.1, Wed Mar 15 18:20:20 2017 ACDT <david@penetrator>
+# name: HRA_56_28
+# type: matrix
+# rows: 28
+# columns: 84
+ 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
+ 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
+
+
diff --git a/codec2/branches/0.7/octave/HRA_56_56.txt b/codec2/branches/0.7/octave/HRA_56_56.txt
new file mode 100644 (file)
index 0000000..8a18f2d
--- /dev/null
@@ -0,0 +1,63 @@
+# Created by Octave 3.8.1, Wed Mar 15 18:12:09 2017 ACDT <david@penetrator>
+# name: HRA_56_56
+# type: matrix
+# rows: 56
+# columns: 112
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0
+ 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0
+ 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1
+
+
diff --git a/codec2/branches/0.7/octave/Mat2Hrows.m b/codec2/branches/0.7/octave/Mat2Hrows.m
new file mode 100644 (file)
index 0000000..99db4f8
--- /dev/null
@@ -0,0 +1,26 @@
+function [Hrows Hcols] = Mat2Hrows(HRA); 
+
+H = full(HRA); 
+[Nr Nc] = size(H); 
+
+H= H(:,1:Nc-Nr); 
+[Nr Nc] = size(H); 
+
+
+
+Max_colwt = max(sum(H));
+Max_rowwt = max(sum(H')); 
+Hcols = zeros(Nc, Max_colwt); 
+Hrows = zeros(Nr, Max_rowwt); 
+
+for i = 1:Nr
+    nz = find(H(i,:)); 
+    Hrows(i,1:length(nz)) = nz; 
+end
+
+H = H'; 
+for i = 1:Nc
+    nz = find(H(i,:)); 
+    Hcols(i,1:length(nz)) = nz; 
+end
+    
diff --git a/codec2/branches/0.7/octave/adc_plot_spec.m b/codec2/branches/0.7/octave/adc_plot_spec.m
new file mode 100755 (executable)
index 0000000..2bc3805
--- /dev/null
@@ -0,0 +1,51 @@
+#!/usr/bin/env octave
+% Plot the spectrum and waveform coming off of the ADC
+
+% Author: Brady O'Brien 28 June 2016
+
+%   Copyright 2016 Brady O'Brien
+%  
+%  All rights reserved.
+%
+%  This program is free software; you can redistribute it and/or modify
+%  it under the terms of the GNU Lesser General Public License version 2, as
+%  published by the Free Software Foundation.  This program is
+%  distributed in the hope that it will be useful, but WITHOUT ANY
+%  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+%  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+%  License for more details.
+%
+%  You should have received a copy of the GNU Lesser General Public License
+%  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+%adc_file_name = '/home/baobrien/workspace/freetel-code/codec2-dev/stm32/adc_samp'
+adc_file_name = '/dev/ttyACM0'
+%adc_file_name = 'infifo';
+fs = 96000
+sampsize = 19200
+%graphics_toolkit('gnuplot')
+
+fin = fopen(adc_file_name,'r')
+first = 1
+cont = 0
+sampinc = (1/sampsize)*fs
+
+[samps cont] = fread(fin,sampsize,'short');
+y = (1:(sampsize/2));
+yp = (1:sampsize/2)*(fs/(sampsize/2));
+pltdat = plot(10*log10(abs(fft(samps)(y))));
+pltx = 10*log10(abs(fft(samps)(y)));
+axis([0 fs 30 80])
+set (pltdat, "ydatasource", "pltx"); 
+set (pltdat, "xdatasource", "yp"); 
+%set (pltdat, "ydatasource", "y"); 
+
+while(first || cont==sampsize)
+       first = 0;
+       %sleep(.001);
+       [samps cont] = fread(fin,sampsize,'short');
+       pltx = 10*log10(abs(fft(samps)(y)));
+       refreshdata
+       refresh
+endwhile
diff --git a/codec2/branches/0.7/octave/adc_sfdr_ut.m b/codec2/branches/0.7/octave/adc_sfdr_ut.m
new file mode 100644 (file)
index 0000000..06fcf30
--- /dev/null
@@ -0,0 +1,34 @@
+% adc_sfdr_ut.m
+% David Rowe Aug 2015
+%
+% Processes data collected from STM32F4 or SFDR testing of ADC
+
+s = load_raw("~/stlink/adc.raw");
+Fs = 2E6;
+N = 1024;
+num_frames = length(s)/N;
+h = hanning(N);
+XdB = zeros(N/2,1);
+
+for i=1:num_frames
+  x = s((i-1)*N+1:i*N);
+  X = fft(x .* h);
+  XdB += 20*log10(abs(X(1:N/2)));
+end
+
+XdB /= num_frames;
+XdB -= max(20*log10(N));
+
+figure(1)
+clf
+plot((0:N/2-1)*Fs/(1000*N), XdB)
+grid
+ylabel('Amplitude dB')
+xlabel('Frequency (kHz)');
+axis([0 Fs/(2*1000) -30 80])
+
+figure(2)
+clf
+plot(s)
+
+
diff --git a/codec2/branches/0.7/octave/adcres.m b/codec2/branches/0.7/octave/adcres.m
new file mode 100644 (file)
index 0000000..69dae0d
--- /dev/null
@@ -0,0 +1,56 @@
+% adcres.m
+% David Rowe 18 Feb 2015
+%
+% ADC resamping simulation, IIR tuner development.
+
+% [ ] quantisation of ADC
+% [ ] SNR at ADC input, SNR at resampler output
+% [X] decimation to 50 kHz
+% [X] 40dB ish rejection (test)
+% [X] visualise pass band flatness
+
+graphics_toolkit ("gnuplot");
+
+fs = 2E6;
+f1 = 500E3;
+f2 = f1 + 8E3;
+f3 = f1 - 7E3;
+f4 = f1 - 207E3;
+t = (0:(fs-1));
+M = 45;
+beta1 = 0.999;
+beta2 = 1 - (1-beta1)*M;
+
+s1 = [fs zeros(1,fs-1)];       % noise floor, continuous interferers 
+s2 = 100*4*cos(t*2*pi*f2/fs);  % wanted signal 40dB above interferers
+s3 = 100*2*cos(t*2*pi*f3/fs);
+s4 = 100*2*cos(t*2*pi*f4/fs);  % interferer at same level
+s = s1 + s2 + s3 + s4;
+
+s2 = filter(1,[1 0 beta1],s);  % BPF at fs/4
+s3 = s2(1:M:length(s2));       % decimate 
+s4 = filter([1 0 beta2],1,s3); % flatten filter response again
+
+figure(1)
+subplot(211)
+plot(20*log10(abs(fft(s)/fs)))
+grid
+axis([0 fs/2 -10 50])
+title('Input to ADC');
+subplot(212)
+plot(20*log10(abs(fft(s2/fs))))
+grid
+axis([0 fs/2 -10 70])
+title('After BPF');
+
+figure(2)
+subplot(211)
+plot(20*log10(abs(fft(s3)/fs)))
+grid
+axis([0 fs/2/M -10 50])
+title('After Decimation');
+subplot(212)
+plot(20*log10(abs(fft(s4)/fs)))
+grid
+title('After Equaliser');
+axis([0 fs/2/M -10 50])
diff --git a/codec2/branches/0.7/octave/autotest.m b/codec2/branches/0.7/octave/autotest.m
new file mode 100644 (file)
index 0000000..7a83184
--- /dev/null
@@ -0,0 +1,114 @@
+% autotest.m
+% David Rowe Mar 2015
+%
+% Helper functions to plot output of C verson and difference between Octave and C versions
+
+1;
+
+function stem_sig_and_error(plotnum, subplotnum, sig, error, titlestr, axisvec)
+  global no_plot_list;
+
+  if find(no_plot_list == plotnum)
+    return;
+  end
+  figure(plotnum)
+  subplot(subplotnum)
+  stem(sig,'g;Octave version;');
+  hold on;
+  stem(error,'r;Octave - C version (hopefully 0);');
+  hold off;
+  if nargin == 6
+    axis(axisvec);
+  end
+  title(titlestr);
+endfunction
+
+
+function plot_sig_and_error(plotnum, subplotnum, sig, error, titlestr, axisvec)
+  global no_plot_list;
+
+  if find(no_plot_list == plotnum)
+    return;
+  end
+
+  figure(plotnum)
+  subplot(subplotnum)
+  plot(sig,'g;Octave version;');
+  hold on;
+  plot(error,'r;Octave - C version (hopefully 0);');
+  hold off;
+  if nargin == 6
+    axis(axisvec);
+  end
+  title(titlestr);
+endfunction
+
+
+function check(a, b, test_name, tol, its_an_angle = 0)
+  global passes;
+  global fails;
+
+  if nargin == 3
+    tol = 1E-3;
+  end
+
+  [m n] = size(a);
+  if m > n
+    ll = m;
+  else
+    ll = n;
+  end
+
+  printf("%s", test_name);
+  for i=1:(25-length(test_name))
+    printf(".");
+  end
+  printf(": ");  
+  
+  if its_an_angle
+    % take into account pi is close to -pi for angles in rads
+    e = sum(sum(abs(exp(j*a) - exp(j*b)))/ll);
+  else
+    e = sum(sum(abs(a - b))/ll);
+  end
+
+  if e < tol
+    printf("OK\n");
+    passes++;
+  else
+    printf("FAIL (%f)\n",e);
+    fails++;
+  end
+endfunction
+
+function check_no_abs(a, b, test_name)
+  global passes;
+  global fails;
+
+  tol = 1E-3;
+
+  [m n] = size(a);
+  if m > n
+    ll = m;
+  else
+    ll = n;
+  end
+
+  printf("%s", test_name);
+  for i=1:(25-length(test_name))
+    printf(".");
+  end
+  printf(": ");  
+  
+  e = sum(sum(a - b)/ll);
+
+  if e < tol
+    printf("OK\n");
+    passes++;
+  else
+    printf("FAIL (%f)\n",e);
+    fails++;
+  end
+endfunction
+
+
diff --git a/codec2/branches/0.7/octave/av_imp.m b/codec2/branches/0.7/octave/av_imp.m
new file mode 100644 (file)
index 0000000..8b7fa60
--- /dev/null
@@ -0,0 +1,43 @@
+% av_imp.m
+% David Rowe Aug 2012
+% Averages the impulse response samples
+
+function imp = av_imp(imp_filename, period_in_secs, st, en)
+  f = fopen(imp_filename,"rb");
+  s = fread(f, Inf, "short")';
+
+  Fs = 8000;
+  n = period_in_secs * Fs;
+
+  [r c] = size(s);
+
+  imp = zeros(1,n);
+  for i=1:n:c-n
+    imp = imp + s(i:i+n-1);
+  endfor
+  
+  % user supplies start and end samples after viweing plot
+
+  if (nargin == 4)
+    imp = imp(st:en);
+  end
+
+  % normalise
+
+  imp /= sqrt(sum(imp .^ 2));
+
+  [h w] = freqz(imp, 1, 4000);
+
+  figure(1);
+  clf;
+  plot(imp);
+
+  figure(2);
+  clf;
+  subplot(211)
+  plot(10*log10(abs(h)))
+  subplot(212)
+  plot(angle(h))
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/bandpasssampling.m b/codec2/branches/0.7/octave/bandpasssampling.m
new file mode 100644 (file)
index 0000000..9a2a4ef
--- /dev/null
@@ -0,0 +1,34 @@
+% bandpasssampling.m
+% David Rowe 23 Feb 2015
+%
+% Band pass sampling example
+
+graphics_toolkit ("gnuplot");
+
+t = 0:1E-3:1-1E-3;
+f1 = 5;
+f2 = 105;
+
+x = 1:10:length(s1);
+
+s1 = cos(2*pi*f1*t);
+s1_sampled = s1(x);
+
+s2 = cos(2*pi*f2*t);
+s2_sampled = s2(x);
+
+figure(1)
+subplot(211)
+plot(t,s1)
+title('5Hz signal sampled at 100 Hz');
+subplot(212)
+stem(x*1E-3, s1_sampled,'r')
+xlabel('Time (s)');
+
+figure(2)
+subplot(211)
+plot(t,s2)
+title('105Hz signal sampled at 100 Hz');
+subplot(212)
+stem(x*1E-3, s2_sampled,'r')
+xlabel('Time (s)');
diff --git a/codec2/branches/0.7/octave/bfq19ssa.m b/codec2/branches/0.7/octave/bfq19ssa.m
new file mode 100644 (file)
index 0000000..b5dbf2b
--- /dev/null
@@ -0,0 +1,83 @@
+% bfq19ssa.m
+%
+% David Rowe Dec 2015
+%
+% Working for 100mW class A small signal amp using the BFQ19
+
+rfdesign;
+
+w = 2*pi*150E6;
+
+% BFQ19 Vce=10V Ic=50mA 100MHz
+
+S11 = 0.251*exp(j*(-142.7)*pi/180);
+S21 = 20.28*exp(j*(103.1)*pi/180);
+S12 = 0.030*exp(j*(72.9)*pi/180);
+S22 = 0.290*exp(j*(-61.9)*pi/180);
+
+% Lets check stability
+
+Ds = S11*S22-S12*S21;
+Knum = 1 + abs(Ds)^2 - abs(S11)^2 - abs(S22)^2;
+Kden = 2*abs(S21)*abs(S12);
+K = Knum/Kden
+figure(1);
+clf
+scCreate;
+
+if K < 1
+  C1 = S11 - Ds*conj(S22);
+  C2 = S22 - Ds*conj(S11);
+  rs1 = conj(C1)/(abs(S11)^2-abs(Ds)^2);           % centre of input stability circle
+  ps1 = abs(S12*S21/(abs(S11)^2-abs(Ds)^2));       % radius of input stability circle
+  rs2 = conj(C2)/(abs(S22)^2-abs(Ds)^2);           % centre of input stability circle
+  ps2 = abs(S12*S21/(abs(S22)^2-abs(Ds)^2));       % radius of input stability circle
+
+  s(1,1)=S11; s(1,2)=S12; s(2,1)=S21; s(2,2)=S22;
+  plotStabilityCircles(s)
+end
+
+% determine collector load Rl for our desired power output
+
+P = 0.1;
+Irms = 0.02;
+Rl = P/(Irms*Irms);
+
+% choose gammaL based on Rl
+
+zo = Rl/50;
+[magL,angleL] = ztog(zo);
+gammaL = magL*exp(j*angleL*pi/180);
+
+% calculate gammaS and Zi and plot
+
+gammaS = conj(S11 + ((S12*S21*gammaL)/(1 - (gammaL*S22))));
+[zi Zi] = gtoz(abs(gammaS), angle(gammaS)*180/pi,50);
+
+scAddPoint(zi);
+scAddPoint(zo);
+
+% Design ouput matching network
+
+Ro = 50;
+[Xs Xp] = z_match(Ro, Rl)
+Cos = 1/(w*Xs);
+Lop  = Xp/w;
+
+printf("Output Matching:\n");
+printf("  Rl = %3.1f  Ro = %3.1f\n", Rl, Ro);
+printf("  Xp = %3.1f Xs = %3.1f\n", Xp, Xs);
+printf("  Cos = %3.1f pF Lop = %3.1f nH\n", Cos*1E12, Lop*1E9);
+
+% design input matching network between 50 ohms source and 10 ohms at base
+
+Rb = real(Zi); Rs = 50;
+
+[Xs Xp] = z_match(Rb, Rs);
+
+Lip = Xp/w;
+Cis = 1/(w*Xs);
+
+printf("Input Matching:\n");
+printf("  Xs = %3.1f Xp = %3.1f\n", Xs, Xp);
+printf("  Lp = %3.1f nH Cs = %3.1f pF\n", Lip*1E9, Cis*1E12);
diff --git a/codec2/branches/0.7/octave/bpf.m b/codec2/branches/0.7/octave/bpf.m
new file mode 100644 (file)
index 0000000..9e0af8f
--- /dev/null
@@ -0,0 +1,31 @@
+% bpf.m
+% David Rowe April 2015
+%
+% Design 400-2600 Hz BPF and save coeffs 
+
+1;
+
+function write_c_array(filename, arrayname, vec)
+
+  m = length(vec);
+
+  f=fopen(filename,"wt");
+  fprintf(f,"#define %s_N %d\n\n", toupper(arrayname), m);
+  fprintf(f,"float %s[]={\n", arrayname);
+  for r=1:m
+    if r < m
+      fprintf(f, "  %f,\n", vec(r));
+    else
+      fprintf(f, "  %f\n};", vec(r));
+    end
+  end
+
+  fclose(f);
+endfunction
+
+b=firls(100,[0 250 300 2600 2700 4000]/4000,[0.01 0.01 1 1 0.01 0.01]);
+freqz(b)
+write_c_array("../src/bpfb.h", "bpfb", b)
+
+% C header file of noise samples so C version gives extacly the same results
+
diff --git a/codec2/branches/0.7/octave/bpsk.m b/codec2/branches/0.7/octave/bpsk.m
new file mode 100644 (file)
index 0000000..91dfbc1
--- /dev/null
@@ -0,0 +1,284 @@
+% bpsk.m
+% David Rowe Mar 2017
+%
+% Simulate BPSK and DPSK with varoous phase detection schemes
+
+1;
+
+% Differential BPSK detector (m=2)
+% ML detection which gains about 0.5dB (m=3, m=4)
+%
+% Based on JPL publication 89-38 "Multiple Symbol Differential
+% Detection of Uncoded and Trellis Coded MPSK" by Divsalar, Simon,
+% Shahshahani.  Thanks Johhn Gibbs NN7F for advice.
+
+function rx_symb = dbpsk_demod(m, r)
+  tx_set = [1 -1];
+
+  if m == 2
+
+    % regular DBPSK detection
+
+    rx_symb(i) = r(1) * r(2)'/(abs(r(2)));
+
+  else
+
+    % ML DBPSK detection
+
+    max_eta = 0;  rx_symb(i) = tx_set(1);
+
+    for k=1:2
+      for k_1=1:2
+        for k_2=1:2
+
+          if m == 3
+            eta = abs(r(3) + r(1)*tx_set(k)'*tx_set(k_1)' + r(2)*tx_set(k_1)')^2;
+          end
+
+          if m == 4
+            eta = abs(r(4) + r(1)*tx_set(k)'*tx_set(k_1)'*tx_set(k_2)' + r(2)*tx_set(k_1)'*tx_set(k_2)' + r(3)*tx_set(k_2)')^2;
+          end
+
+          %printf("  %d %d %f \n", k_1, k, eta);
+
+          if eta > max_eta
+            max_eta = eta;
+            rx_symb(i) = tx_set(k);
+          end
+
+        end
+      end
+    end
+  end
+endfunction
+
+
+function sim_out = run_sim(sim_in)
+  Rs = 50;
+
+  Nbits = sim_in.Nbits;
+  EbNodB = sim_in.EbNodB;
+  dbpsk = sim_in.dbpsk;
+  verbose = sim_in.verbose;
+  m = sim_in.m;
+  phase_est_mem = sim_in.phase_est_mem;
+  assert(mod(phase_est_mem,2) == 1, "phase_est_mem must be odd");
+  phase_est_delay = floor(phase_est_mem/2);
+  printf("phase_est_mem: %d phase_est_delay: %d\n", phase_est_mem, phase_est_delay);
+
+  woffset = 2*pi*sim_in.freq_offset_hz/Rs;
+
+  
+  for nn=1:length(EbNodB)
+    EbNo = 10 .^ (EbNodB(nn)/10);
+    variance = 1/(EbNo/2);
+    noise = sqrt(variance)*(0.5*randn(1,Nbits) + j*0.5*randn(1,Nbits));
+
+    tx = zeros(1,Nbits);
+    rx = zeros(1,Nbits);
+    tx_bits = rand(1,Nbits) > 0.5;
+    prev_tx = 1;
+    prev_rx = 1;
+    r = ones(1,max(4,phase_est_mem));
+    phase_amb = 0;
+    phase_offset = sim_in.phase_offset
+
+    phase_offset_log = zeros(1,Nbits);
+    phase_amb_log = zeros(1,Nbits);
+    phase_est_stripped = zeros(1,Nbits);
+    phase_est = zeros(1,Nbits);
+
+    Nerrs = 0;
+    for i=1:Nbits
+      if dbpsk
+        tx(i) = prev_tx * exp(j*pi*tx_bits(i));
+        prev_tx = tx(i);
+      else
+        tx(i) = 1 - 2*tx_bits(i);
+      end
+
+      rx(i) = tx(i)*exp(j*phase_offset) + noise(i);
+      phase_offset_log(i) = phase_offset;
+      phase_offset += woffset;
+      if (phase_offset > pi)
+        phase_offset -= 2*pi;
+      end
+
+      r(2:phase_est_mem) = r(1:phase_est_mem-1);
+      r(1) = rx(i);
+
+      if dbpsk
+        rx_symb(i) = dbpsk_demod(m, r);
+      else
+        rx_symb(i) = rx(i);
+        
+        if phase_est_mem 
+
+          if i >= phase_est_mem
+
+            % demod symbol at centre of phase est window
+
+            centre = i - phase_est_delay;
+
+            % modulation strip
+
+            stripped = r(1:phase_est_mem) .^ 2;
+
+            phase_est_stripped(centre) = angle(sum(stripped))/2;
+
+            % determine if phase has jumped from - -> +  
+  
+            if (phase_est_stripped(centre-1) < -pi/4) && (phase_est_stripped(centre) > pi/4)
+              %printf("- -> +\n");
+              phase_amb -= pi;
+              if (phase_amb < -pi)
+                phase_amb += 2*pi;
+              end
+            end
+
+            % determine if phase has jumped from + -> -    
+
+            if (phase_est_stripped(centre-1) > pi/4) && (phase_est_stripped(centre) < -pi/4)
+              %printf("+ -> -\n");
+              phase_amb += pi;
+              if (phase_amb > pi)
+                phase_amb -= 2*pi;
+              end
+            end
+
+            phase_amb_log(centre) = phase_amb; 
+            phase_est(centre) = phase_est_stripped(centre) + phase_amb;
+
+            % keep phase est in range of -pi .. pi to aid plotting
+
+            if (phase_est(centre) < -pi)
+              phase_est(centre) += 2*pi;
+            end
+            if (phase_est(centre) > pi)
+              phase_est(centre) -= 2*pi;
+            end
+
+            rx_symb(centre) *= exp(-j*phase_est(centre));
+          end
+        end
+      end
+    end
+
+    % if using block based phase est, strip off first few and last few
+    % symbols where phase ests are invalid
+    
+    st = phase_est_delay+1;
+    %en = Nbits-phase_est_delay;
+    en = 50;
+    rx_bits = real(rx_symb) < 0;
+    errors = xor(tx_bits, rx_bits);
+    Nerrs = sum(errors(st:en));                                         
+    printf("EbNodB: %3.2f BER: %4.3f Nbits: %d Nerrs: %d\n", EbNodB(nn), Nerrs/(en-st+1), (en-st+1), Nerrs);
+
+    if verbose
+      figure(1); clf; 
+      plot(rx_symb(st:en),'+');
+      axis([-2 2 -2 2]);
+      figure(2); clf; 
+      plot(phase_offset_log(st:en),'b+;phase offset;', 'markersize', 10);
+      hold on;
+      plot(phase_amb_log(st:en),'c-;phase amb;');
+      plot(phase_est_stripped(st:en),'ro;phase est stripped;');
+      plot(phase_est(st:en),'g*;phase est;');
+      hold off;
+      axis([1 en-st+1 -pi pi])
+      legend('boxoff');
+      figure(3); clf; 
+      plot(errors(st:en),'+');
+      axis([1 en-st+1 -0.5 1.5]);
+    end
+
+    sim_out.ber(nn) = Nerrs/Nbits;
+  end
+endfunction
+
+
+function run_curves
+  sim_in.verbose = 0;
+  sim_in.Nbits = 10000;
+  sim_in.EbNodB = 0:6;
+  sim_in.dbpsk = 0;
+  sim_in.m = 2;
+  sim_in.phase_est_mem = 0;
+  sim_in.phase_offset = 0;
+
+  bpsk_out = run_sim(sim_in);
+
+  sim_in.phase_offset = pi/4;
+  sim_in.phase_est_mem = 5;
+  bpsk_out_5 = run_sim(sim_in);
+  sim_in.phase_est_mem = 10;
+  bpsk_out_10 = run_sim(sim_in);
+  sim_in.phase_est_mem = 20;
+  bpsk_out_20 = run_sim(sim_in);
+
+  figure(3); clf;
+  semilogy(sim_in.EbNodB, bpsk_out.ber,'b+-;BPSK;');
+  hold on;
+  semilogy(sim_in.EbNodB, bpsk_out_5.ber,'g+-;BPSK 5 pt phase est;');
+  semilogy(sim_in.EbNodB, bpsk_out_10.ber,'c+-;BPSK 10 pt phase est;');
+  semilogy(sim_in.EbNodB, bpsk_out_20.ber,'k+-;BPSK 20 pt phase est;');
+  hold off;
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid;
+  legend('boxoff');
+  title('Coherent Modn Stripped BPSK');
+  print -depsc bpsk_coherent.eps
+
+#{
+  sim_in.dbpsk = 1;
+  dbpsk_out_2 = run_sim(sim_in);
+
+  sim_in.m = 3;
+  dbpsk_out_3 = run_sim(sim_in);
+  sim_in.m = 4;
+  dbpsk_out_4 = run_sim(sim_in);
+
+  figure(4); clf;
+  semilogy(sim_in.EbNodB, bpsk_out.ber,'b+-;BPSK;');
+  hold on;
+  semilogy(sim_in.EbNodB, dbpsk_out_2.ber,'g+-;DBPSK m=2;');
+  semilogy(sim_in.EbNodB, dbpsk_out_3.ber,'c+-;DBPSK m=3;');
+  semilogy(sim_in.EbNodB, dbpsk_out_4.ber,'k+-;DBPSK m=4;');
+  hold off;
+  print -depsc dbpsk_ml.eps
+
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid;
+  legend('boxoff');
+  title('ML DBPSK');
+#}
+end
+
+
+function run_single
+  sim_in.Nbits = 1000;
+  sim_in.EbNodB = 4;
+  sim_in.dbpsk = 0;
+  sim_in.m = 2;
+  sim_in.phase_est_mem = 11;
+  sim_in.verbose = 1;
+  sim_in.phase_offset = 0;
+  sim_in.freq_offset_hz = 1;
+
+  run_sim(sim_in);
+end
+
+
+format;
+more off;
+rand('seed',1);
+randn('seed',1);
+
+run_single
+%run_curves
+
+
+
diff --git a/codec2/branches/0.7/octave/c2wideband_batch.m b/codec2/branches/0.7/octave/c2wideband_batch.m
new file mode 100644 (file)
index 0000000..c4ba714
--- /dev/null
@@ -0,0 +1,316 @@
+% c2wideband_batch.m
+%
+% Copyright David Rowe 2017
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+
+#{
+
+  Octave script to batch process model parameters for wideband Codec 2.
+
+  Outputs a set of model parameters that can be fed to c2sim for
+  listening tests.  The companion c2wideband_fbf.m script is used to
+  visualise the processing frame by frame
+  c2sim -> dump files -> c2wideband_batch.m -> output model params -> c2sim -> play
+  Usage:
+
+    Build codec2 with -DDUMP (see codec2-dev/README), then generate dump files:
+
+      ~/codec2-dev/build_linux/src$ ./c2sim ~/Desktop/c2_hd/speech_orig_16k.wav --Fs 16000 --dump speech
+
+    Start Octave and generate the map file, this only needs to be done once:
+
+      $ cd ~/codec2-dev/octave
+      $ octave
+      octave:1> c2wideband_batch("../build_linux/src/speech", "mode", "generate map")
+
+    Then to run batch simulation and generate output speech:
+   
+       octave:1> c2wideband_batch("../build_linux/src/speech");
+
+      ~/codec2-dev/build_linux/src$ ./c2sim ~/Desktop/c2_hd/speech_orig_16k.wav --Fs 16000 --phase0 --postfilter --amread speech_am.out --hmread speech_hm.out -o | play -t raw -r 16000 -s -2 - 
+#}
+
+
+function [surface mean_f] = c2wideband_batch(input_prefix, varargin)
+  newamp;
+  more off;
+
+  max_amp = 160;
+  mean_f = [];
+
+  % defaults
+
+  synth_phase = output = 1;
+  output_prefix = input_prefix;
+  fit_order = 0;
+  mode = "dct2";
+
+  % parse variable argument list
+
+  if (length (varargin) > 0)
+
+    ind = arg_exists(varargin, "mode");
+    if ind
+      mode =  varargin{ind+1};
+    end
+
+    % check for the "output_prefix" option
+
+    ind = arg_exists(varargin, "output_prefix");
+    if ind
+      output_prefix =  varargin{ind+1};
+    end
+
+    ind = arg_exists(varargin, "no_output");
+    if ind
+      output = 0;
+      synth_phase = 0;
+    end
+  end
+
+  if output && !strcmp(mode,"generate map")
+    printf("output_prefix: %s\n",  output_prefix);
+  end
+  
+  model_name = strcat(input_prefix,"_model.txt");
+  model = load(model_name);
+  [frames nc] = size(model);
+
+  % Choose experiment to run test here -----------------------
+
+  if strcmp(mode, "generate map")
+    generate_map(model, K=30, "c2wideband_map");
+    output = 0;
+  end
+  if strcmp(mode, "dct2")
+    [model_ surface] = experiment_rate_K_dct2(model, 1);
+    frames_out = rows(model_);
+  end
+
+  % ----------------------------------------------------
+
+  if output
+    Am_out_name = sprintf("%s_am.out", output_prefix);
+    fam  = fopen(Am_out_name,"wb"); 
+    if synth_phase
+      Hm_out_name = sprintf("%s_hm.out", output_prefix);
+      fhm = fopen(Hm_out_name,"wb"); 
+    end
+
+    for f=1:frames_out
+      %printf("%d ", f);   
+      Wo = model_(f,1); L = min([model_(f,2) max_amp-1]); Am = model_(f,3:(L+2));
+      if Wo*L > pi
+        printf("Problem: %d  Wo*L > pi\n", f);   
+      end
+
+      Am_ = zeros(1,max_amp); Am_(2:L) = Am(1:L-1); fwrite(fam, Am_, "float32");
+
+      if synth_phase
+
+        % synthesis phase spectra from magnitiude spectra using minimum phase techniques
+
+        fft_enc = 256;
+        phase = determine_phase(model_, f, fft_enc);
+        assert(length(phase) == fft_enc);
+
+        % sample phase at centre of each harmonic, not 1st entry Hm[1] in octave Hm[0] in C
+        % is not used
+
+        Hm = zeros(1, 2*max_amp);
+        for m=1:L
+          b = round(m*Wo*fft_enc/(2*pi));
+          Hm(2*m) = cos(phase(b));
+          Hm(2*m+1) = -sin(phase(b));
+        end
+        fwrite(fhm, Hm, "float32");    
+      end
+    end
+
+    fclose(fam);
+    if synth_phase
+      fclose(fhm);
+    end
+  end % if output .....
+  printf("\n")
+
+endfunction
+
+function ind = arg_exists(v, str) 
+   ind = 0;
+   for i=1:length(v)
+      if strcmp(v{i}, str)
+        ind = i;
+      end     
+    end
+endfunction
+
+
+% Create "map" from a training database.  The map tells us which order
+% to read out and quantise DCT coeffs.  Could be approximated by a
+% zig-zag pattern. 
+%
+% Example 3x3 map in a zig-zag pattern, so (1,1) is first coeff, (1,2)
+% 2nd ....
+% 
+%  1 2 6 
+%  2 5 7
+%  4 8 9
+%
+% TODO: [ ] Come up with a better name than 
+%       [ ] Script to convert this to a C header file.
+
+function generate_map(model, K, map_filename)
+  newamp; 
+  c2wideband_const;
+
+  [frames nc] = size(model);
+  surface = resample_const_rate_f_mel(model, K, Fs);
+  [nr nc] = size(surface);
+  asurf = surface(1:dec:nr,:);
+  [map rms_map mx mx_ind unwrapped_dcts] = create_map_rms(asurf, Nt, K);
+
+  %printf("non zero coeffs: %d\n", sum(sum(map == 1)));
+  figure(2); clf;
+  mesh(map);
+  printf("generating map file: %s\n", map_filename);
+  save("-ascii", map_filename, "map");
+endfunction
+
+
+% ---------------------------------------------------------------------------------------
+% rate K mel-resampling, high end correction, and DCT experiment workhorse
+
+function [model_ rate_K_surface] = experiment_rate_K_dct2(model, plots=1)
+  newamp;
+  c2wideband_const;
+
+  [frames nc] = size(model);
+
+  % break into blocks of (Nt time samples) x (K freq samples)
+
+  Nblocks = floor(frames/(Nt*dec));
+  %printf("frames: %d Nblocks: %d\n", frames, Nblocks);
+
+  % map that defines order we read out and quantise DCT coeffs
+  % TODO: for C port we need an Octave function to write Map to a C
+  % include file
+
+  map = load("c2wideband_map");
+
+  % create arrays to reverse map quantiser_num to r,c Luts
+
+  rmap = cmap = zeros(1,Nt*K);
+  for r=1:Nt
+    for c=1:K
+       quantiser_num = map(r,c);
+       rmap(quantiser_num) = r;
+       cmap(quantiser_num) = c;
+    end
+  end
+
+  % per-block processing ----------------------------------------------------
+
+  % init a bunch of output variables
+
+  rate_K_surface_ = zeros(Nblocks*Nt*dec, K);  
+  sumnz = zeros(1,Nblocks);
+  dct2_sd = zeros(1,Nblocks);
+  model_ = [];
+
+  for n=1:Nblocks
+    st = (n-1)*dec*Nt+1; en = st + dec*Nt - 1;
+    %printf("st: %d en: %d\n", st, en);
+
+    [model_block_ adct2_sd qn rate_K_surface_block rate_K_surface_block_] = wideband_enc_dec(model(st:en,:), rmap, cmap);
+
+    model_ = [model_; model_block_];
+
+    % log these for plotting/development
+
+    rate_K_surface(st:en,:) = rate_K_surface_block;
+    rate_K_surface_(st:en,:) = rate_K_surface_block_;
+    dct2_sd(n) = adct2_sd;
+    sumnz(n) = qn;
+  end
+
+  if plots
+    figure(4); clf; plot(sumnz); hold on; 
+    plot([1 length(sumnz)],[mean(sumnz) mean(sumnz)]); hold off; title('Non Zero');
+    figure(5); clf; plot(dct2_sd); title('DCT SD');
+  end
+  printf("average dct spectral distortion: %3.2f dB\n", mean(dct2_sd));
+  printf("mean number of coeffs/DCT: %3.2f/%d\n", mean(sumnz), Nt*K);
+  printf("coeffs/second: %3.2f\n", mean(sumnz)/(Nt*Tf*dec));
+  printf("bits/s: %3.2f\n", 2.9*mean(sumnz)/(Nt*Tf*dec));
+
+  % this measure just works on 20ms frames, not sure if that's correct
+
+  dist = std((rate_K_surface_(1:dec:Nblocks*Nt*dec,:) - rate_K_surface(1:dec:Nblocks*Nt*dec,:))');
+  
+  if plots
+    figure(1); clf; plot(dist); title('Rate K SD');
+    printf("Rate K spectral distortion mean: %3.2f dB var: %3.2f\n", mean(dist), var(dist));
+  end
+endfunction
+
+
+% Encode/decoder a 160ms block of model parameters
+% TODO: (i) quantisation of DCT coeffs (ii) break into separate encoder and decoder functions
+
+function [model_block_ dct2_sd qn rate_K_surface_block rate_K_surface_block_] = wideband_enc_dec(model_block, rmap, cmap)
+    c2wideband_const;
+
+    sim_quant = 1; % used to simulate quantisation, set to 1,2,4, etc
+    dist_dB   = 2; % use enough coefficients to get this distortion ond DCT coeffs
+
+    % Resample variable rate L vectors to fixed length rate K.  We have
+    % left high end correction out for now, this is less of an issue
+    % with a higher K
+
+    [rate_K_surface_block rate_K_sample_freqs_kHz] = resample_const_rate_f_mel(model_block, K, Fs);
+
+    % decimate down to 20ms time resolution, and DCT
+
+    D = dct2(rate_K_surface_block(1:dec:Nt*dec,:));
+
+    % So D is the 2D block of DCT coeffs at the encoder.  We want to
+    % create a quantised version at the "decoder" E.  This loop copies
+    % DCTs coeffs from D to E, until we get beneath a distortion
+    % threshold.
+
+    % This is essentially variable rate quantisation, but gives us
+    % some idea of the final bit rate.  In practice we will also need
+    % to constrain the total number of bits (ie bit rate), and
+    % quantise each coefficient.
+
+    % Turns out than mean SD (across many blocks/frames) is about the
+    % same in the DCT domain as the rate K domain.  So we can just
+    % measure MSE between D and E to estimate mean SD of the rate K
+    % vectors after quantisation.
+
+    E = mapped = zeros(Nt,K);
+
+    qn = 0;
+    adct2_sd = mean(std(D-E));
+    while adct2_sd > dist_dB
+      qn++;
+      E(rmap(qn), cmap(qn)) = sim_quant*round(D(rmap(qn), cmap(qn))/sim_quant);
+      adct2_sd = mean(std(D-E));
+      %printf("qn %d %f\n", qn, adct2_sd);
+    end
+
+    % note neat trick to interpolate to 10ms frames despite dec to 20ms, this means
+    % we don't need a separate decode side interpolator.
+
+    dct2_sd = mean(std(D-E));
+    rate_K_surface_block_ = idct2([sqrt(dec)*E; zeros(Nt*(dec-1), K)]);
+    model_block_ = resample_rate_L(model_block, rate_K_surface_block_, rate_K_sample_freqs_kHz, Fs);
+endfunction
diff --git a/codec2/branches/0.7/octave/c2wideband_const.m b/codec2/branches/0.7/octave/c2wideband_const.m
new file mode 100644 (file)
index 0000000..891fbb4
--- /dev/null
@@ -0,0 +1,25 @@
+% c2wideband_const.m
+% David Rowe July 2017
+%
+% Constants for wideband Codec 2, bit like #define for C
+
+Fs = 16000;  % sampel rate in Hz
+K = 30;      % number of Mel spaced amplitude samples
+
+Tf = 0.01;   % frame period in seconds
+
+dec = 2;     % decimation factor.  10ms update of the core
+             % sinusuodial codec is rather fast and reducing it to
+             % 20ms makes very little difference in quality, but
+             % halves the data going into the DCT/quantisation.
+             % While the DCT should encode highly correlated data
+             % like 10ms frame efficiently, there is some noise in
+             % the core paraneters estimation so nice to use a lower
+             % frame rate if possible.
+
+Nt = 8;      % number of blocks in time.  Trade off between latency
+             % and coding efficiency.  If the DCT has larger blocks to
+             % play with it can remove more correlation, up to a limit
+             % where the data is no longer correlated in time or freq.
+             % Also set to match LDPC code frame size
+
diff --git a/codec2/branches/0.7/octave/c2wideband_fbf.m b/codec2/branches/0.7/octave/c2wideband_fbf.m
new file mode 100644 (file)
index 0000000..4d68704
--- /dev/null
@@ -0,0 +1,92 @@
+% c2wideband_fbf.m
+%
+% Copyright David Rowe 2017
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+% Interactive Octave script to explore frame by frame operation of
+% wideband Codc 2.
+
+#{
+     Make sure codec2-dev is compiled with the -DDUMP option - see README for
+     instructions.
+
+     Usage:
+      ~/codec2-dev/build_linux/src$ ./c2sim ~/Desktop/c2_hd/speech_orig_16k.wav --Fs 16000 --dump speech
+
+      $ cd ~/codec2-dev/octave
+      $ octave
+      octave:1> c2wideband_fbf("../build_linux/src/speech")
+#}
+
+function c2wideband_fbf(samname, f=70, varargin)
+  more off;
+  newamp;
+
+  Fs = 16000; Fs2 = Fs/2; K = 30;
+
+  % load up text files dumped from c2sim ---------------------------------------
+
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+  [frames tmp] = size(model);
+
+  % Keyboard loop --------------------------------------------------------------
+
+  k = ' ';
+  do 
+    s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+    figure(1); clf; plot(s); axis([1 length(s) -20000 20000]);
+
+    Wo = model(f,1); L = model(f,2); Am = model(f,3:(L+2)); AmdB = 20*log10(Am);
+    Am_freqs_kHz = (1:L)*Wo*Fs2/(1000*pi);
+
+    [rate_K_vec rate_K_sample_freqs_kHz] = resample_const_rate_f_mel(model(f,:), K, Fs);
+
+    % plots ----------------------------------
+  
+    figure(2); clf; 
+    plot((1:L)*Wo*Fs2/pi, AmdB,";AmdB;g+-");
+    axis([1 Fs2 -20 80]);
+    hold on;
+    stem(rate_K_sample_freqs_kHz*1000, rate_K_vec, ";rate K;b+-");
+
+    [model_ AmdB_] = resample_rate_L(model(f,:), rate_K_vec, rate_K_sample_freqs_kHz, Fs);
+    AmdB_ = AmdB_(1:L);
+
+    plot((1:L)*Wo*Fs2/pi, AmdB_,";AmdB;r+-");
+    hold off;
+
+    % interactive menu ------------------------------------------
+
+    printf("\rframe: %d  menu: n-next  b-back  q-quit [%d]", f);
+    fflush(stdout);
+    k = kbhit();
+
+    if k == 'n'
+      f = f + 1;
+    endif
+    if k == 'b'
+      f = f - 1;
+    endif
+  until (k == 'q')
+  printf("\n");
+
+endfunction
+
+function ind = arg_exists(v, str) 
+   ind = 0;
+   for i=1:length(v)
+      if strcmp(v{i}, str)
+        ind = i;
+      end     
+    end
+endfunction
+
+
diff --git a/codec2/branches/0.7/octave/cbphase.m b/codec2/branches/0.7/octave/cbphase.m
new file mode 100644 (file)
index 0000000..8e82da1
--- /dev/null
@@ -0,0 +1,98 @@
+% cbphase.m
+% David Rowe Aug 2012
+% Used to experiment with critical band phase perception and smoothing
+
+function cbphase
+
+  Wo = 100.0*pi/4000;
+  L = floor(pi/Wo);
+
+  A = zeros(1,L);
+  phi = zeros(1,L);
+
+  % three harmonics in this band
+
+  b = 4; a = b-1; c = b+1;
+
+  % set up phases and mags for 2nd order system (see phasesecord.m)
+   
+  wres = b*Wo;
+  phi(a) = 3*pi/4 + wres;
+  phi(b) = pi/2 + wres;
+  phi(c) = pi/4 + wres;
+
+  A(a) = 0.707;
+  A(b) = 1;
+  A(c) = 0.707;
+
+  % add linear component
+
+  phi(1) = pi;
+  phi(2:L) = phi(2:L) + (2:L)*phi(1);
+  phi = phi - 2*pi*(floor(phi/(2*pi)) + 0.5);
+
+  N = 16000;
+  Nplot = 250;
+  s = zeros(1,N);
+
+  for m=a:c
+    s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m));
+    s = s + s_m;
+  endfor
+
+  figure(2);
+  clf;
+  subplot(211)
+  plot((1:L)*Wo*4000/pi, A,'+');
+  subplot(212)
+  plot((1:L)*Wo*4000/pi, phi,'+');
+
+  %v = A(a)*exp(j*phi(a)) + A(b)*exp(j*phi(b)) + A(c)*exp(j*phi(c));
+  %compass(v,"r")
+  %hold off;
+  
+  % est phi1
+
+  diff = phi(b) - phi(a)
+  sumi = sin(diff);
+  sumr = cos(diff);
+  diff = phi(c) - phi(b)
+  sumi += sin(diff);
+  sumr += cos(diff);
+  phi1_ = atan2(sumi, sumr)
+  s_v = cos(Wo*(0:(N-1)) + phi1_);
+
+  figure(1);
+  clf;
+  subplot(211)
+  plot(s(1:Nplot));
+  hold on;
+  plot(s_v(1:Nplot),"r");
+  hold off;
+
+  % build (hopefully) perceptually similar phase
+
+  phi_(a) = a*phi1_;
+  phi_(b) = b*phi1_;
+  phi_(c) = c*phi1_;
+
+  s_ = zeros(1,N);
+
+  for m=a:c
+    s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi_(m));
+    s_ = s_ + s_m;
+  endfor
+  subplot(212)
+  plot(s_(1:Nplot));
+  
+  gain = 8000;
+  fs=fopen("orig_ph.raw","wb");
+  fwrite(fs,gain*s,"short");
+  fclose(fs);
+  fs=fopen("mod_ph.raw","wb");
+  fwrite(fs,gain*s_,"short");
+  fclose(fs);
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/cellmodem.m b/codec2/branches/0.7/octave/cellmodem.m
new file mode 100644 (file)
index 0000000..3700539
--- /dev/null
@@ -0,0 +1,137 @@
+% cellmodem.m
+% David Rowe May 2005
+%
+% Simulation of modem for low rate date through a cell phone codec
+%
+% Ideas:
+%   + insert low rate codec
+%   + generate bunch of symbols, run through codec, measure MSE, choose best set
+%   + measure probablility of error, "distance" from other symbols
+%   + can we use VQ training algorithm for this?  Start with 2 symbols,
+%     pass through channel, measure MSE, split again?
+%   + start with cmd line version of codec, frame synchronous
+%   + add symbol timing estimator later
+%   + try different frame rates
+%   + simulate impairments like HP/LP filtering.  Can we correct for this?
+%   + pilots symbols so we can use energy as well?
+%   + set of F0 as well
+%   + LSP quantisers preferrentially preserve peaks, so three peaks is a
+%     reasonable signal set.  Modulate position and bandwidth to creat 
+%     symbol set.  Maybe 50 or 100 Hz grid for LSPs, evaluate that some how.
+
+graphics_toolkit ("gnuplot");
+rand('state',1);
+lsp;
+
+% given a vector of LSP symbols, constructs a synthesised speech signals
+% anfd runs it through a codec
+
+function [w__log mse] = run_sim(sim_in, w_log)
+  N         = sim_in.N;
+  Wo        = sim_in.Wo;
+  frames    = sim_in.frames;
+  lpc_order = sim_in.lpc_order;
+
+  s      = [];
+  w__log = [];
+  L      = floor(pi/Wo);
+  phi    = zeros(1,L);
+
+  for f=1:frames
+
+    % synthesise speech signal
+
+    a=lsptoa(w_log(f,:));
+
+    ex = zeros(1,N);
+    for m=1:L
+      phi(m) += Wo*m*N;
+      ex += cos(phi(m) + Wo*m*(0:N-1));
+    end
+
+    s = [s filter(1, a, ex)];
+  end
+
+  % play through codec
+
+  s *= sim_in.gain;
+  f=fopen("in.raw","wb");
+  fwrite(f,s,"short");
+  fclose(f);
+  system(sim_in.codec_cmd);
+  f=fopen("out.raw","rb");
+  s_ = fread(f,Inf,"short");
+  fclose(f);
+
+  % extract received symbols from channel and evaluate
+
+  mse = zeros(1,frames);
+  for f=1:frames
+    a_ = lpcauto(s_((f-1)*sim_in.N+1:f*N), lpc_order);
+    w_ = atolsp(a_);
+    w__log = [w__log; w_];
+    error = w__log(f,:) - w_log(f,:);
+    mse(f) = error*error';
+  end
+endfunction
+
+% constants -----------------------------------------------------
+
+sim_in.codec_cmd = "speexenc --bitrate 4000 in.raw - | speexdec - out.raw";
+
+lpc_order   = sim_in.lpc_order = 6;
+Fs          = sim_in.Fs = 8000;
+              sim_in.Fo = 100;             % pitch frequency of voice 
+              sim_in.Wo = 2*pi*Fo/Fs;      % pitch in rads
+N           = sim_in.N  = Fs*0.04;         % frame length
+frames      = sim_in.frames = 1000;        % frames to play through codec
+              sim_in.gain = 100;
+Nsym        = 8;                           % number of symbols to find
+
+% start with some LSP random vectors
+% for stable filter most be monotonically increasing on 0..pi
+
+w_log = [];
+for f=1:frames;
+  w = sort(rand(1,lpc_order)*pi);
+  w_log = [w_log; w];
+end
+[w__log mse] = run_sim(sim_in, w_log);
+
+% sort by MSE to get the best symbols
+
+[sort_mse sort_ind] = sort(mse);
+symbols = w_log(sort_ind(1:Nsym),:)
+
+% Play these symbols through the codec in random order
+
+w_log = [];
+symb_ind = [];
+for f=1:frames
+  symb_ind(f) = floor(1 + rand(1,1)*Nsym);
+  w_log = [w_log; symbols(symb_ind,:)];
+end
+
+[w__log mse] = run_sim(sim_in, w_log);
+
+% now see if we can "detect" them
+
+for f=1:frames
+
+  % check received symbol against codebook of symbols
+
+  min_e = 1E6;
+  for i=1:Nsym
+    e = w__log(f,:)*symbols(i,:)';
+    if e < min_e
+      min_e = e;
+      min_ind = i;
+    end
+  end
+
+  symb_ind_out(f) = min_ind;
+end
+
+figure(1)
+clf
+plot(symb_ind,'g',symb_ind_out,'r');
diff --git a/codec2/branches/0.7/octave/ciccomp.m b/codec2/branches/0.7/octave/ciccomp.m
new file mode 100644 (file)
index 0000000..936a101
--- /dev/null
@@ -0,0 +1,70 @@
+% ciccomp.m
+% Brady O'Brien 9 Mar 2015
+% CIC Filter compensation helper
+
+graphics_toolkit ("gnuplot");
+
+cicn = 10;                       %delay for CIC filter
+N = 10;                         %input interpolation rate
+csf = 256;                  %scaling factor for CIC filter conversion
+fd = 80e3;                       %DAC frequency
+fs = fd/N;                   %Input sampling frequency
+fi= fd;                     %freq of DSP
+fc1 = fi/4;                     %Frequency of initial upconversion
+ciccb=[-0.029626    0.252638   -2.304683   16.332166   -2.304683    0.252638   -0.029626];
+%ciccb = ciccb(1:2:length(ciccb))
+t = (1:fs);
+
+fdin = zeros(1,length(t));
+fdin(1)=1;
+fdin=fdin+sin(pi*t*(2000/fs));
+%fdin = filter(b,1,fdin);
+
+figure(4)
+plot(20*log10(abs(fft(fdin))))
+fdcout = zeros(1,length(t));
+fdin = int64(fdin*1024);
+
+combout1=0;
+combout2=0;
+combout3=0;
+%combout4=0;
+ccbuf1=zeros(1,cicn/N);
+ccbuf2=zeros(1,cicn/N);
+ccbuf3=zeros(1,cicn/N);
+%ccbuf4=zeros(1,cicn);
+
+for ii=1:length(fdin)
+       combout1 = fdin(ii) - ccbuf1(end);
+       combout2 = combout1 - ccbuf2(end);
+       combout3 = combout2 - ccbuf3(end);
+       %combout4 = combout3 - ccbuf4(end);
+       ccbuf1(2:end)=ccbuf1(1:end-1);
+       ccbuf2(2:end)=ccbuf2(1:end-1);
+       ccbuf3(2:end)=ccbuf3(1:end-1);
+       %ccbuf4(2:end)=ccbuf4(1:end-1);
+       ccbuf1(1)=fdin(ii);
+       ccbuf2(1)=combout1;
+       ccbuf3(1)=combout2;
+       %ccbuf4(1)=combout3;
+       fdcout(ii)=combout3;
+end
+
+intout1=0;
+intout2=0;
+intout3=0;
+%intout4=0;
+fdnext = zeros(1,length(t)*N);
+fdnext(1:N:length(t)*N) = fdcout; %Interpolate
+fdi1 = fdnext;
+
+for ii=1:length(fdnext)
+       intout1 = fdnext(ii) + intout1;
+       intout2 = intout1 + intout2;
+       intout3 = intout2 + intout3;
+       %intout4 = intout3 + intout4;
+       fdnext(ii)=intout3;
+end
+
+figure(5)
+plot(20*log10(abs(fft(fdnext))))
diff --git a/codec2/branches/0.7/octave/cma.m b/codec2/branches/0.7/octave/cma.m
new file mode 100644 (file)
index 0000000..a5a2195
--- /dev/null
@@ -0,0 +1,114 @@
+% cma.m
+%
+% Constant modulus equaliser example from:
+%
+% http://dsp.stackexchange.com/questions/23540/matlab-proper-estimation-of-weights-and-how-to-calculate-mse-for-qpsk-signal-f
+%
+% Adapted to run bpsk and fsk signals
+
+    rand('seed',1);
+    randn('seed',1);
+
+    N = 5000;           % # symbols
+    h = [1 0 0 0 0 0 0.0 0.5];  % simulation of HF multipath channel impulse response
+    h = h/norm(h);
+    Le = 20;            % equalizer length
+    mu = 1E-3;          % step size
+    snr = 30;           % snr in dB
+    M = 10;             % oversample rate, e.g. Rs=400Hz at Fs=8000Hz
+
+    tx_type = "fsk";   % select modulation type here "bpsk" or "fsk"
+
+    if strcmp(tx_type, "bpsk")
+      s0 = round( rand(N,1) )*2 - 1;     % BPSK signal
+      s0M = zeros(N*M,1);                % oversampled BPSK signal
+      k = 1;
+      for i=1:M:N*M
+       s0M(i:i+M-1) = s0(k);
+        k ++;
+      end
+    end
+
+    if strcmp(tx_type, "fsk")
+      tx_bits = round(rand(1,N));
+
+      % continuous phase FSK modulator
+
+      w1 = pi/4;
+      w2 = pi/2;
+      tx_phase = 0;
+      tx = zeros(M*N,1);
+
+      for i=1:N
+        for k=1:M
+          if tx_bits(i)
+            tx_phase += w2;
+          else
+            tx_phase += w1;
+          end
+          tx((i-1)*M+k) = exp(j*tx_phase);
+        end
+      end
+
+      s0M = tx;
+    end
+
+    s = filter(h,1,s0M);                % filtered signal
+
+    % add Gaussian noise at desired snr
+
+    n = randn(N*M,1);
+    vs = var(s);
+    vn = vs*10^(-snr/10);
+    n = sqrt(vn)*n;
+    r = s + n;          % received signal
+
+    e = zeros(N*M,1);   % error
+    w = zeros(Le,1);    % equalizer coefficients
+    w(Le)=1;            % actual filter taps are flipud(w)!
+
+    yd = zeros(N*M,1);
+
+    for i = 1:N*M-Le,
+        x = r(i:Le+i-1);
+        y = w'*x;
+        yd(i)=y;
+        e(i) = abs(y).^2 - 1;
+        w = w - mu * e(i) * real(conj(y) * x);
+    end
+
+    np = 100;           % # sybmols to plot (last np will be plotted); np < N!
+
+    figure(1); clf;
+    %subplot(211), plot( 1:np, e(N-np+1-Le+1:N-Le+1).*e(N-np+1-Le+1:N-Le+1)), title('error')
+    subplot(211), plot(e.*e), title('error');
+    subplot(212), stem(conv(flipud(w),h)), title('equalized channel impulse response')
+
+    figure(2); clf;
+    subplot(311)
+    plot(1:np, s0M(N-np+1:N))
+    title('transmitted, received, and equalized signal')
+    subplot(312)
+    plot(1:np, r(N-np+1:N))
+    subplot(313)
+    plot(1:np, yd(N-np+1-Le+1:N-Le+1))
+
+    figure(3); clf;
+    h1 = freqz(h);
+    h2 = freqz(flipud(w));
+    h3 = freqz(conv(flipud(w),h));
+    subplot(311); plot(20*log10(abs(h1)));
+    title('channel, equaliser, combined freq resp')
+    subplot(312); plot(20*log10(abs(h2)));
+    subplot(313); plot(20*log10(abs(h3)));
+
+    figure(4);
+    subplot(211)
+    plot(20*log10(abs(fft(s0M))))
+    axis([1 length(s0M) 0 80]);
+    grid;
+    subplot(212)
+    plot(20*log10(abs(fft(s))))
+    axis([1 length(s0M) 0 80]);
+    grid;
+
diff --git a/codec2/branches/0.7/octave/cml.patch b/codec2/branches/0.7/octave/cml.patch
new file mode 100644 (file)
index 0000000..cb517a4
--- /dev/null
@@ -0,0 +1,31 @@
+--- cml-orig/CmlStartup.m      2007-09-08 23:12:26.000000000 +0930
++++ cml/CmlStartup.m   2016-09-19 10:30:08.673767127 +0930
+@@ -20,7 +20,7 @@
+     addpath( strcat( cml_home, '\mex'), ...\r
+         strcat( cml_home, '\mat'), ...\r
+         strcat( cml_home, '\matalt' ), ...\r
+-        strcat( cml_home, '\mexhelp'), ...\r
++        %strcat( cml_home, '\mexhelp'), ...\r
+         strcat( cml_home, '\demos' ), ...\r
+         strcat( cml_home, '\scenarios'), ...\r
+         strcat( cml_home, '\localscenarios'),...\r
+@@ -41,7 +41,7 @@
+     addpath( strcat( cml_home, '/mex'), ...\r
+         strcat( cml_home, '/mat'), ...\r
+         strcat( cml_home, '/matalt' ), ...\r
+-        strcat( cml_home, '/mexhelp'), ...\r
++        %strcat( cml_home, '/mexhelp'), ...\r
+         strcat( cml_home, '/demos' ), ...\r
+         strcat( cml_home, '/scenarios'), ...\r
+         strcat( cml_home, '/localscenarios'),...\r
+@@ -59,4 +59,4 @@
+     save_directory = strcat( cml_home, '/scenarios/CmlHome.mat' );\r
+ end\r
\r
+-save( save_directory, save_flag, 'cml_home' );
+\ No newline at end of file
++save( save_directory, save_flag, 'cml_home' );\r
+--- cml-orig/source/matrix.h   1970-01-01 09:30:00.000000000 +0930
++++ cml/source/matrix.h        2016-09-19 10:25:58.009761169 +0930
+@@ -0,0 +1 @@
++#include <mex.h>
diff --git a/codec2/branches/0.7/octave/codec2_demo.m b/codec2/branches/0.7/octave/codec2_demo.m
new file mode 100644 (file)
index 0000000..0f3950b
--- /dev/null
@@ -0,0 +1,108 @@
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% codec2_demo.m
+
+% Designed as an educational tool to explain the operation of Codec 2
+% for conference and user group presentations on a projector.  An
+% alternative to static overhead slides.
+%
+% Derived from codec2-dev/octave/plamp.m
+%
+% usage:
+%   octave:1> plamp("../src/hts2a",40)
+%
+% Then press:
+%   c - to cycle through the wavform being displayed on the figure
+%   n - next frame
+%   b - back one frame
+%
+%   tip: hold down n or b to animate the display
+%
+% The text files used as input are generated using c2sim:
+%
+%   /codec2-dev/src$ c2sim ../raw/hts2a.raw --dump hts2a
+%
+% The Codec 2 README explains how to build c2sim with dump files
+% enabled.
+
+function codec2_demo(samname, f)
+  
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+  
+  figure(1);
+
+  k = ' ';
+  wf = "Sn";
+  do 
+   
+    if strcmp(wf,"Sn")
+      clf;
+      s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+      plot(s);
+      axis([1 length(s) -20000 20000]);
+    end
+
+    if (strcmp(wf,"Sw"))
+      clf;
+      plot((0:255)*4000/256, Sw(f,:),";Sw;");
+    end
+  
+    if strcmp(wf,"SwAm")
+      Wo = model(f,1);
+      L = model(f,2);
+      Am = model(f,3:(L+2));
+      plot((0:255)*4000/256, Sw(f,:),";Sw;");
+      hold on;
+      plot((1:L)*Wo*4000/pi, 20*log10(Am),"+;Am;r");
+      axis([1 4000 -10 80]);
+      hold off;
+    end
+
+    if strcmp(wf,"Am")
+      Wo = model(f,1);
+      L = model(f,2);
+      Am = model(f,3:(L+2));
+      plot((1:L)*Wo*4000/pi, 20*log10(Am),"+;Am;r");
+      axis([1 4000 -10 80]);
+    end
+
+    % interactive menu
+
+    printf("\rframe: %d  menu: n-next  b-back  w-cycle window  q-quit", f);
+    fflush(stdout);
+    k = kbhit();
+    if (k == 'n')
+      f = f + 1;
+    end
+    if (k == 'b')
+      f = f - 1;
+    end
+    if (k == 'w') 
+      if strcmp(wf,"Sn")
+        next_wf = "Sw";
+      end
+      if strcmp(wf,"Sw")
+        next_wf = "SwAm";
+      end
+      if strcmp(wf,"SwAm")
+        next_wf = "Am";
+      end
+      if strcmp(wf,"Am")
+        next_wf = "Sn";
+      end
+      wf = next_wf;
+    end
+
+  until (k == 'q')
+  printf("\n");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/cohpsk.m b/codec2/branches/0.7/octave/cohpsk.m
new file mode 100644 (file)
index 0000000..34abfa7
--- /dev/null
@@ -0,0 +1,992 @@
+% cohpsk.m
+% David Rowe Mar 2015
+%
+% Coherent PSK modem functions, with support for LDPC and DSSS
+% (diversity).
+
+1;
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+
+% init function for symbol rate processing --------------------------------------------------------
+
+function sim_in = symbol_rate_init(sim_in)
+    sim_in.Fs = Fs = 8000;
+
+    modulation       = sim_in.modulation;
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+
+    Rs               = sim_in.Rs;
+    Nc               = sim_in.Nc;
+
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_mag_only      = sim_in.hf_mag_only;
+
+    Nd               = sim_in.Nd;     % diveristy
+    Ns               = sim_in.Ns;     % step size between pilots
+    ldpc_code        = sim_in.ldpc_code;
+    rate             = sim_in.ldpc_code_rate; 
+
+    sim_in.bps = bps = 2;
+
+    sim_in.Nsymb         = Nsymb            = framesize/bps;
+    sim_in.Nsymbrow      = Nsymbrow         = Nsymb/Nc;
+    sim_in.Npilotsframe  = Npilotsframe     = 2;
+    sim_in.Nsymbrowpilot = Nsymbrowpilot    = Nsymbrow + Npilotsframe;
+    
+    if verbose == 2
+      printf("Each frame contains %d data bits or %d data symbols, transmitted as %d symbols by %d carriers.", framesize, Nsymb, Nsymbrow, Nc);
+      printf("  There are %d pilot symbols in each carrier together at the start of each frame, then %d data symbols.", Npilotsframe, Ns); 
+      printf("  Including pilots, the frame is %d symbols long by %d carriers.\n\n", Nsymbrowpilot, Nc);
+    end
+
+    sim_in.prev_sym_tx = qpsk_mod([0 0])*ones(1,Nc*Nd);
+    sim_in.prev_sym_rx = qpsk_mod([0 0])*ones(1,Nc*Nd);
+
+    sim_in.rx_symb_buf  = zeros(3*Nsymbrow, Nc*Nd);
+    sim_in.rx_pilot_buf = zeros(3*Npilotsframe,Nc*Nd);
+    sim_in.tx_bits_buf  = zeros(1,2*framesize);
+
+    % pilot sequence is used for phase and amplitude estimation, and frame sync
+
+    pilot = 1 - 2*(rand(Npilotsframe,Nc) > 0.5);
+    sim_in.pilot = pilot;
+    sim_in.tx_pilot_buf = [pilot; pilot; pilot];
+    if sim_in.do_write_pilot_file
+      write_pilot_file(pilot, Nsymbrowpilot, Ns, Nsymbrow, Npilotsframe, Nc);
+    end
+
+    % we use first 2 pilots of next frame to help with frame sync and fine freq
+
+    sim_in.Nct_sym_buf = 2*Nsymbrowpilot + 2;
+    sim_in.ct_symb_buf = zeros(sim_in.Nct_sym_buf, Nc*Nd);
+
+    sim_in.ff_phase = 1;
+
+    sim_in.ct_symb_ff_buf = zeros(Nsymbrowpilot + 2, Nc*Nd);
+
+    % Init LDPC --------------------------------------------------------------------
+
+    if ldpc_code
+        % Start CML library
+
+        currentdir = pwd;
+        addpath '/home/david/tmp/cml/mat'    % assume the source files stored here
+        cd /home/david/tmp/cml
+        CmlStartup                           % note that this is not in the cml path!
+        cd(currentdir)
+  
+        % Our LDPC library
+
+        ldpc;
+
+        mod_order = 4; 
+        modulation2 = 'QPSK';
+        mapping = 'gray';
+
+        sim_in.demod_type = 0;
+        sim_in.decoder_type = 0;
+        sim_in.max_iterations = 100;
+
+        code_param = ldpc_init(rate, framesize, modulation2, mod_order, mapping);
+        code_param.code_bits_per_frame = framesize;
+        code_param.symbols_per_frame = framesize/bps;
+        sim_in.code_param = code_param;
+    else
+        sim_in.rate = 1;
+        sim_in.code_param = [];
+    end
+endfunction
+
+
+% Symbol rate processing for tx side (modulator) -------------------------------------------------------
+
+% legacy DQPSK mod for comparative testing
+
+function [tx_symb prev_tx_symb] = bits_to_dqpsk_symbols(sim_in, tx_bits, prev_tx_symb)
+    Nc         = sim_in.Nc;
+    Nsymbrow   = sim_in.Nsymbrow;
+
+    tx_symb = zeros(Nsymbrow,Nc);
+
+    for c=1:Nc
+      for r=1:Nsymbrow
+        i = (c-1)*Nsymbrow + r;
+        tx_symb(r,c) = qpsk_mod(tx_bits(2*(i-1)+1:2*i));  
+        tx_symb(r,c) *= prev_tx_symb(c);
+        prev_tx_symb(c) = tx_symb(r,c);
+      end
+    end
+              
+endfunction
+
+
+% legacy DQPSK demod for comparative testing
+
+function [rx_symb rx_bits rx_symb_linear prev_rx_symb] = dqpsk_symbols_to_bits(sim_in, rx_symb, prev_rx_symb)
+    Nc         = sim_in.Nc;
+    Nsymbrow   = sim_in.Nsymbrow;
+
+    tx_symb = zeros(Nsymbrow,Nc);
+
+    for c=1:Nc
+      for r=1:Nsymbrow
+        tmp = rx_symb(r,c);
+        rx_symb(r,c) *= conj(prev_rx_symb(c))/abs(prev_rx_symb(c));
+        prev_rx_symb(c) = tmp;
+        i = (c-1)*Nsymbrow + r;
+        rx_symb_linear(i) = rx_symb(r,c);
+        rx_bits((2*(i-1)+1):(2*i)) = qpsk_demod(rx_symb(r,c));
+      end
+    end 
+              
+endfunction
+
+
+function [tx_symb tx_bits] = bits_to_qpsk_symbols(sim_in, tx_bits, code_param)
+    ldpc_code     = sim_in.ldpc_code;
+    rate          = sim_in.ldpc_code_rate;
+    framesize     = sim_in.framesize;
+    Nsymbrow      = sim_in.Nsymbrow;
+    Nsymbrowpilot = sim_in.Nsymbrowpilot;
+    Nc            = sim_in.Nc;
+    Npilotsframe  = sim_in.Npilotsframe;
+    Ns            = sim_in.Ns;
+    modulation    = sim_in.modulation;
+    pilot         = sim_in.pilot;
+    Nd            = sim_in.Nd;
+
+    if ldpc_code
+        [tx_bits, tmp] = ldpc_enc(tx_bits, code_param);
+    end
+
+    % modulate --------------------------------------------
+
+    % organise symbols into a Nsymbrow rows by Nc cols
+    % data and parity bits are on separate carriers
+
+    tx_symb = zeros(Nsymbrow,Nc);
+    
+    for c=1:Nc
+      for r=1:Nsymbrow
+        i = (c-1)*Nsymbrow + r;
+        tx_symb(r,c) = qpsk_mod(tx_bits(2*(i-1)+1:2*i));
+      end
+    end
+    
+    % insert pilots at start of frame
+    
+    tx_symb = [pilot(1,:); pilot(2,:); tx_symb;];
+
+    % copy to other carriers (diversity)
+
+    tmp = tx_symb;
+    for d=1:Nd-1
+      tmp = [tmp tx_symb];
+    end
+    tx_symb = tmp;
+
+    % ensures energy/symbol is normalised with diversity
+
+    tx_symb = tx_symb/sqrt(Nd);
+end
+
+
+% Symbol rate processing for rx side (demodulator) -------------------------------------------------------
+
+function [rx_symb rx_bits rx_symb_linear amp_ phi_ sig_rms noise_rms cohpsk] = qpsk_symbols_to_bits(cohpsk, ct_symb_buf)
+    framesize     = cohpsk.framesize;
+    Nsymb         = cohpsk.Nsymb;
+    Nsymbrow      = cohpsk.Nsymbrow;
+    Nsymbrowpilot = cohpsk.Nsymbrowpilot;
+    Nc            = cohpsk.Nc;
+    Nd            = cohpsk.Nd;
+    Npilotsframe  = cohpsk.Npilotsframe;
+    pilot         = cohpsk.pilot;
+    verbose       = cohpsk.verbose;
+    coh_en        = cohpsk.coh_en;
+
+    % Use pilots to get phase and amplitude estimates We assume there
+    % are two samples at the start of each frame and two at the end
+    % Note: correlation (averging) method was used initially, but was
+    % poor at tracking fast phase changes that we experience on fading
+    % channels.  Linear regression (fitting a straight line) works
+    % better on fading channels, but increases BER slighlty for AWGN
+    % channels.
+
+    sampling_points = [1 2 cohpsk.Nsymbrow+3 cohpsk.Nsymbrow+4];
+    pilot2 = [cohpsk.pilot(1,:); cohpsk.pilot(2,:); cohpsk.pilot(1,:); cohpsk.pilot(2,:);];
+    phi_ = zeros(Nsymbrow, Nc*Nd);
+    amp_ = zeros(Nsymbrow, Nc*Nd);
+    
+    for c=1:Nc*Nd
+      %corr = pilot2(:,c)' * ct_symb_buf(sampling_points,c);      
+      %phi_(:, c) = angle(corr);
+     
+      y = ct_symb_buf(sampling_points,c) .* pilot2(:,c-Nc*floor((c-1)/Nc));
+      [m b] = linreg(sampling_points, y, length(sampling_points));
+      yfit = m*[3 4 5 6] + b;
+      phi_(:, c) = angle(yfit);
+      %for r=1:Nsymbrow
+      %  printf("  %f", phi_(r,c));
+      %end
+      %printf("\n");
+      mag  = sum(abs(ct_symb_buf(sampling_points,c)));
+      amp_(:, c) = mag/length(sampling_points);
+    end
+
+    % now correct phase of data symbols
+
+    rx_symb = zeros(Nsymbrow, Nc);
+    rx_symb_linear = zeros(1, Nsymbrow*Nc*Nd);
+    rx_bits = zeros(1, framesize);
+    for c=1:Nc*Nd
+      for r=1:Nsymbrow
+        if coh_en == 1
+          rx_symb(r,c) = ct_symb_buf(2+r,c)*exp(-j*phi_(r,c));
+        else
+          rx_symb(r,c) = ct_symb_buf(2+r,c);
+        end
+        i = (c-1)*Nsymbrow + r;
+        rx_symb_linear(i) = rx_symb(r,c);
+        %printf("phi_ %d %d %f %f\n", r,c,real(exp(-j*phi_(r,c))), imag(exp(-j*phi_(r,c))));
+      end
+    end
+
+    % and finally optional diversity combination and make decn on bits
+
+    for c=1:Nc
+      for r=1:Nsymbrow
+        i = (c-1)*Nsymbrow + r;
+        div_symb = rx_symb(r,c);
+        for d=1:Nd-1
+          div_symb += rx_symb(r,c + Nc*d);
+        end
+        rx_bits((2*(i-1)+1):(2*i)) = qpsk_demod(div_symb);
+      end
+    end
+
+    % Estimate noise power from demodulated symbols.  One method is to
+    % calculate the distance of each symbol from the average symbol
+    % position. However this is complicated by fading, which means the
+    % amplitude of the symbols is constantly changing.
+    
+    % Now the scatter diagram in a fading channel is a X or cross
+    % shape.  The noise can be resolved into two components at right
+    % angles to each other.  The component along the the "thickness"
+    % of the arms is proportional to the noise power and not affected
+    % by fading.  We only use points further along the real axis than
+    % the mean amplitude so we keep out of the central nosiey blob
+        
+    sig_rms = mean(abs(rx_symb_linear));
+   
+    sum_x = 0;
+    sum_xx = 0;
+    n = 0;
+    for i=1:Nsymb*Nd
+      s = rx_symb_linear(i);
+      if abs(real(s)) > sig_rms
+        sum_x  += imag(s);
+        sum_xx += imag(s)*imag(s);
+        n++;
+      end
+    end
+   
+    noise_var = 0;
+    if n > 1
+      noise_var = (n*sum_xx - sum_x*sum_x)/(n*(n-1));
+    end
+    noise_rms = sqrt(noise_var);
+      
+endfunction
+
+
+% Compression, John Gibbs pointed out it's best to perform non-linear
+% operations on an oversampled signals as they tend to generate
+% broadband noise that will be aliased into passband if bandwidth is
+% too low
+
+function y = compress(x, power)
+
+  % oversample by a factor of M
+
+  M = 4;
+  Ntap = 47;
+  n = length(x);  
+
+  b = fir1(Ntap,1/M);
+  xM = zeros(1,M*n);
+  for i=1:n
+    xM(i*M) = M*x(i);
+  end
+  
+  xM = filter(b,1,xM);
+
+  % non linearity
+
+  yM = sign(xM).*(abs(xM) .^ power);
+
+  % decimate by a factor of M
+
+  yM = filter(b,1,yM);
+  y  = yM(1:M:n*M);
+    
+endfunction
+
+
+% Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+function [spread spread_2ms hf_gain] = init_hf_model(Fs, nsam)
+
+    % convert "spreading" samples from 1kHz carrier at Fss to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; Fss = 8000;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fss)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fss)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fss);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+   
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % change output samples so they are at rate Fs reqd by caller
+    
+    spread = resample(spread, Fs, Fss);
+    spread_2ms = resample(spread_2ms, Fs, Fss);
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread(1:nsam))+var(spread_2ms(1:nsam)));
+endfunction
+
+
+function write_pilot_file(pilot, Nsymbrowpilot, Ns, Nsymrow, Npilotsframe, Nc);
+
+  filename = sprintf("../src/cohpsk_defs.h", Npilotsframe, Nc);
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by write_pilot_file() Octave function */\n\n");
+  fprintf(f,"#define NSYMROW      %d   /* number of data symbols on each row (i.e. each carrier) */\n", Nsymrow);
+  fprintf(f,"#define NS           %d   /* number of data symbols between pilots                   */\n", Ns);
+  fprintf(f,"#define NPILOTSFRAME %d   /* number of pilot symbols on each row                     */\n", Npilotsframe);
+  fprintf(f,"#define PILOTS_NC    %d   /* number of carriers                                      */\n\n", Nc);
+  fprintf(f,"#define NSYMROWPILOT %d   /* length of row after pilots inserted                     */\n\n", Nsymbrowpilot);
+  fclose(f);
+
+  filename = sprintf("../src/pilots_coh.h", Npilotsframe, Nc);
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by write_pilot_file() Octave function */\n\n");
+  fprintf(f,"float pilots_coh[][PILOTS_NC]={\n");
+  for r=1:Npilotsframe
+    fprintf(f, "  {");
+    for c=1:Nc-1
+      fprintf(f, "  %f,", pilot(r, c));
+    end
+    if r < Npilotsframe
+      fprintf(f, "  %f},\n", pilot(r, Nc));
+    else
+      fprintf(f, "  %f}\n};", pilot(r, Nc));
+    end
+  end
+  fclose(f);
+endfunction
+
+
+% Save test bits frame to a text file in the form of a C array
+
+function test_bits_coh_file(test_bits_coh)
+
+  f=fopen("../src/test_bits_coh.h","wt");
+  fprintf(f,"/* Generated by test_bits_coh_file() Octave function */\n\n");
+  fprintf(f,"const int test_bits_coh[]={\n");
+  for m=1:length(test_bits_coh)-1
+    fprintf(f,"  %d,\n",test_bits_coh(m));
+  endfor
+  fprintf(f,"  %d\n};\n",test_bits_coh(length(test_bits_coh)));
+  fclose(f);
+
+endfunction
+
+
+function [ch_symb rx_timing rx_filt rx_baseband afdmdv f_est] = rate_Fs_rx_processing(afdmdv, ch_fdm_frame, f_est, nsymb, nin, freq_track)
+    M = afdmdv.M;
+    
+    rx_baseband = [];
+    rx_filt = [];
+    rx_timing = [];
+
+    ch_fdm_frame_index = 1;
+
+    for r=1:nsymb
+      % shift signal to nominal baseband, this will put Nc/2 carriers either side of 0 Hz
+
+      [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame(ch_fdm_frame_index:ch_fdm_frame_index + nin - 1), -f_est, afdmdv.Fs, afdmdv.fbb_phase_rx);
+      ch_fdm_frame_index += nin;
+
+      % downconvert each FDM carrier to Nc separate baseband signals
+
+      [arx_baseband afdmdv] = fdm_downconvert(afdmdv, rx_fdm_frame_bb, nin);
+      [arx_filt afdmdv] = rx_filter(afdmdv, arx_baseband, nin);
+      [rx_onesym arx_timing env afdmdv] = rx_est_timing(afdmdv, arx_filt, nin);     
+
+      rx_baseband = [rx_baseband arx_baseband];
+      rx_filt     = [rx_filt arx_filt];
+      rx_timing    = [rx_timing arx_timing];
+      
+      ch_symb(r,:) = rx_onesym;
+
+      % we only allow a timing shift on one symbol per frame
+
+      if nin != M
+        nin = M;
+      end
+
+      % freq tracking, see test_ftrack.m for unit test.  Placed in
+      % this function as it needs to work on a symbol by symbol basis
+      % rather than frame by frame.  This means the control loop
+      % operates at a sample rate of Rs = 50Hz for say 1 Hz/s drift.
+
+      if freq_track
+        beta = 0.005;
+        g = 0.2;
+
+        % combine difference on phase from last symbol over Nc carriers
+
+        mod_strip = 0;
+        for c=1:afdmdv.Nc+1
+          adiff = rx_onesym(c) .* conj(afdmdv.prev_rx_symb(c));
+          afdmdv.prev_rx_symb(c) = rx_onesym(c);
+
+          % 4th power strips QPSK modulation, by multiplying phase by 4
+          % Using the abs value of the real coord was found to help 
+          % non-linear issues when noise power was large
+
+          amod_strip = adiff.^4;
+          amod_strip = abs(real(amod_strip)) + j*imag(amod_strip);
+          mod_strip += amod_strip;
+        end
+        %plot(mod_strip)
+        %printf("modstrip: %f %f\n", real(mod_strip), imag(mod_strip));
+
+        % loop filter made up of 1st order IIR plus integrator.  Integerator
+        % was found to be reqd 
+        
+        afdmdv.filt = (1-beta)*afdmdv.filt + beta*angle(mod_strip);
+        f_est += g*afdmdv.filt;
+        %printf("filt: %f angle: %f\n", afdmdv.filt, angle(mod_strip));
+
+      end
+    end
+endfunction
+
+
+function ct_symb_buf = update_ct_symb_buf(ct_symb_buf, ch_symb, Nct_sym_buf, Nsymbrowpilot)
+
+  % update memory in symbol buffer
+
+  for r=1:Nct_sym_buf-Nsymbrowpilot
+    ct_symb_buf(r,:) = ct_symb_buf(r+Nsymbrowpilot,:);
+  end
+  i = 1;
+  for r=Nct_sym_buf-Nsymbrowpilot+1:Nct_sym_buf
+    ct_symb_buf(r,:) = ch_symb(i,:);
+    i++;
+  end
+endfunction
+
+
+% returns index of start of frame and fine freq offset
+
+function [next_sync cohpsk] = frame_sync_fine_freq_est(cohpsk, ch_symb, sync, next_sync)
+  ct_symb_buf   = cohpsk.ct_symb_buf;
+  Nct_sym_buf   = cohpsk.Nct_sym_buf;
+  Rs            = cohpsk.Rs;
+  Nsymbrowpilot = cohpsk.Nsymbrowpilot;
+  Nc            = cohpsk.Nc;
+  Nd            = cohpsk.Nd;
+
+  ct_symb_buf = update_ct_symb_buf(ct_symb_buf, ch_symb, Nct_sym_buf, Nsymbrowpilot);
+  cohpsk.ct_symb_buf = ct_symb_buf;
+  % sample pilots at start of this frame and start of next frame 
+
+  sampling_points = [1 2 cohpsk.Nsymbrow+3 cohpsk.Nsymbrow+4];
+  pilot2 = [ cohpsk.pilot(1,:); cohpsk.pilot(2,:); cohpsk.pilot(1,:); cohpsk.pilot(2,:);];
+
+  if sync == 0
+
+    % sample correlation over 2D grid of time and fine freq points
+
+    max_corr = 0;
+    for f_fine=-20:0.25:20
+%    for f_fine=-1:0.25:1
+      f_fine_rect = exp(-j*f_fine*2*pi*sampling_points/Rs)'; % note: this could be pre-computed at init or compile time
+      for t=0:cohpsk.Nsymbrowpilot-1
+        corr = 0; mag = 0;
+        for c=1:Nc*Nd
+          f_corr_vec = f_fine_rect .* ct_symb_buf(t+sampling_points,c); % note: this could be pre-computed at init or compile time
+          acorr = 0.0;
+          for p=1:length(sampling_points)
+            acorr += pilot2(p,c-Nc*floor((c-1)/Nc)) * f_corr_vec(p);
+            mag   += abs(f_corr_vec(p));
+          end
+          corr += abs(acorr);
+        end
+        %printf("  f: %f  t: %d corr: %f mag: %f ratio: %f\n", f_fine, t, corr, mag, corr/mag);
+        if corr >= max_corr
+          max_corr = corr;
+          max_mag = mag;
+          cohpsk.ct = t;
+          cohpsk.f_fine_est = f_fine;
+          cohpsk.ff_rect = exp(-j*f_fine*2*pi/Rs);
+        end
+      end
+    end
+    
+    printf("  [%d]   fine freq f: %f max_ratio: %f ct: %d\n", cohpsk.frame, cohpsk.f_fine_est, abs(max_corr)/max_mag, cohpsk.ct);
+    if abs(max_corr/max_mag) > 0.9
+      printf("  [%d]   encouraging sync word! ratio: %f\n", cohpsk.frame, abs(max_corr/max_mag));
+      cohpsk.sync_timer = 0;
+      next_sync = 1;
+    else
+      next_sync = 0;
+      %printf("  [%d] back to coarse freq offset est...\n", cohpsk.frame) ;
+    end
+    cohpsk.ratio = abs(max_corr/max_mag);
+  end
+  
+  % single point correlation just to see if we are still in sync
+
+  if sync == 1
+    corr = 0; mag = 0;
+    f_fine_rect = exp(-j*cohpsk.f_fine_est*2*pi*sampling_points/Rs)';
+    for c=1:Nc*Nd
+      f_corr_vec = f_fine_rect .* ct_symb_buf(cohpsk.ct+sampling_points,c);
+      acorr = 0;
+      for p=1:length(sampling_points)
+        acorr += pilot2(p, c-Nc*floor((c-1)/Nc)) * f_corr_vec(p);
+        mag  += abs(f_corr_vec(p));
+      end
+      corr += abs(acorr);
+    end
+    cohpsk.ratio = abs(corr)/mag;
+    %printf("f_fine_est: %f ratio: %f\n", cohpsk.f_fine_est, cohpsk.ratio);
+  end
+
+endfunction
+
+
+% misc sync state machine code, just wanted it in a function
+
+function [sync cohpsk] = sync_state_machine(cohpsk, sync, next_sync)
+
+  if sync == 1
+
+    % check that sync is still good, fall out of sync on consecutive bad frames */
+
+    if cohpsk.ratio < 0.8
+      cohpsk.sync_timer++;
+    else
+      cohpsk.sync_timer = 0;            
+    end
+    % printf("  ratio: %f  sync timer: %d\n", cohpsk.ratio, cohpsk.sync_timer);
+
+    if cohpsk.sync_timer == 10
+      printf("  [%d] lost sync ....\n", cohpsk.frame);
+      next_sync = 0;
+    end
+  end
+
+  sync = next_sync;
+endfunction
+
+
+% Rate Rs BER tests ------------------------------------------------------------------------------
+
+function sim_out = ber_test(sim_in)
+    sim_in = symbol_rate_init(sim_in);
+
+    Fs               = sim_in.Fs;
+    Rs               = sim_in.Rs;
+    Ntrials          = sim_in.Ntrials;
+    verbose          = sim_in.verbose;
+    plot_scatter     = sim_in.plot_scatter;
+    framesize        = sim_in.framesize;
+    bps              = sim_in.bps;
+
+    Esvec            = sim_in.Esvec;
+    ldpc_code        = sim_in.ldpc_code;
+    rate             = sim_in.ldpc_code_rate;
+    code_param       = sim_in.code_param;
+    tx_bits_buf      = sim_in.tx_bits_buf;
+    Nsymb            = sim_in.Nsymb;
+    Nsymbrow         = sim_in.Nsymbrow;
+    Nsymbrowpilot    = sim_in.Nsymbrowpilot;
+    Nc               = sim_in.Nc;
+    Npilotsframe     = sim_in.Npilotsframe;
+    Ns               = sim_in.Ns;
+    Np               = sim_in.Np;
+    Nd               = sim_in.Nd;
+    modulation       = sim_in.modulation;
+    pilot            = sim_in.pilot;
+    prev_sym_tx      = sim_in.prev_sym_tx;
+    prev_sym_rx      = sim_in.prev_sym_rx;
+    rx_symb_buf      = sim_in.rx_symb_buf;
+    tx_pilot_buf     = sim_in.tx_pilot_buf;
+    rx_pilot_buf     = sim_in.rx_pilot_buf;
+
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_mag_only      = sim_in.hf_mag_only;
+    f_off            = sim_in.f_off;
+    div_time_shift   = sim_in.div_timeshift;
+
+    [spread spread_2ms hf_gain] = init_hf_model(Rs, Nsymbrowpilot*(Ntrials+2));
+
+    if strcmp(modulation,'dqpsk')
+      Nsymbrowpilot = Nsymbrow;
+    end
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+        if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        s_ch_tx_log      = [];
+        rx_symb_log      = [];
+        noise_log        = [];
+        errors_log       = [];
+        Nerrs_log        = [];
+        phi_log          = [];
+        amp_log          = [];
+        EsNo__log        = [];
+
+        ldpc_errors_log = []; ldpc_Nerrs_log = [];
+
+        Terrsldpc = Tbitsldpc = Ferrsldpc = 0;
+
+        % init HF channel
+
+        hf_n = 1;
+
+        phase_offset_rect = 1;
+        w_offset      = 2*pi*f_off/Rs;
+        w_offset_rect = exp(j*w_offset);
+
+        ct_symb_buf = zeros(2*Nsymbrowpilot, Nc*Nd);
+        prev_tx_symb = prev_rx_symb = ones(1, Nc*Nd);
+
+        % simulation starts here-----------------------------------
+        for nn = 1:Ntrials+2
+                  
+            if ldpc_code
+              tx_bits = round(rand(1,framesize*rate));                       
+            else
+              tx_bits = round(rand(1,framesize));                       
+            end
+
+            if strcmp(modulation,'qpsk')
+
+              [tx_symb tx_bits] = bits_to_qpsk_symbols(sim_in, tx_bits, code_param);
+
+              % one frame delay on bits for qpsk
+
+              tx_bits_buf(1:framesize) = tx_bits_buf(framesize+1:2*framesize);
+              tx_bits_buf(framesize+1:2*framesize) = tx_bits;
+
+            end
+            if strcmp(modulation, 'dqpsk')
+              [tx_symb prev_tx_symb] = bits_to_dqpsk_symbols(sim_in, tx_bits, prev_tx_symb);
+              tx_bits_buf(1:framesize) = tx_bits;
+            end
+
+            s_ch = tx_symb;
+
+            % HF channel simulation  ------------------------------------
+            
+            hf_fading = ones(1,Nsymb);
+            if hf_sim
+
+                % separation between carriers.  Note this effectively
+                % under samples at Rs, I dont think this matters.
+                % Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                hf_model(hf_n, :) = zeros(1,Nc*Nd);
+                
+                for r=1:Nsymbrowpilot
+                  for c=1:Nd*Nc
+                    if c > Nc 
+                      time_shift = sim_in.div_timeshift;
+                    else
+                      time_shift = 1;
+                    end
+                    ahf_model = hf_gain*(spread(hf_n+time_shift) + exp(-j*c*wsep*nhfdelay)*spread_2ms(hf_n+time_shift));
+                    
+                    if hf_mag_only
+                      s_ch(r,c) *= abs(ahf_model);
+                    else
+                      s_ch(r,c) *= ahf_model;
+                    end
+                    hf_model(hf_n, c) = ahf_model;
+                  end
+                  hf_n++;
+                end
+            end
+           
+            % keep a record of each tx symbol so we can check average power
+
+            for r=1:Nsymbrow
+              for c=1:Nd*Nc
+                 s_ch_tx_log = [s_ch_tx_log s_ch(r,c)];
+              end
+            end
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(Nsymbrowpilot,Nc*Nd) + j*randn(Nsymbrowpilot,Nc*Nd));
+            noise_log = [noise_log noise];
+
+            for r=1:Nsymbrowpilot
+              s_ch(r,:) *= phase_offset_rect;
+              phase_offset_rect *= w_offset_rect;
+            end
+            s_ch += noise;
+
+            ct_symb_buf(1:Nsymbrowpilot,:) = ct_symb_buf(Nsymbrowpilot+1:2*Nsymbrowpilot,:);
+            ct_symb_buf(Nsymbrowpilot+1:2*Nsymbrowpilot,:) = s_ch;
+
+            if strcmp(modulation,'qpsk')
+              [rx_symb rx_bits rx_symb_linear amp_ phi_ EsNo_ sim_in] = qpsk_symbols_to_bits(sim_in, ct_symb_buf(1:Nsymbrowpilot+Npilotsframe,:));                                 
+              phi_log = [phi_log; phi_];
+              amp_log = [amp_log; amp_];
+            end
+            if strcmp(modulation,'dqpsk')
+              [rx_symb rx_bits rx_symb_linear prev_rx_symb] = dqpsk_symbols_to_bits(sim_in, s_ch, prev_rx_symb);                                 
+            end
+                        
+            % Wait until we have enough frames to do pilot assisted phase estimation
+
+            if nn > 1
+              rx_symb_log = [rx_symb_log rx_symb_linear];
+              %EsNo__log = [EsNo__log EsNo_];
+
+              % Measure BER
+
+              error_positions = xor(rx_bits, tx_bits_buf(1:framesize));
+              Nerrs = sum(error_positions);
+              Terrs += Nerrs;
+              Tbits += length(tx_bits);
+              errors_log = [errors_log error_positions];
+              Nerrs_log = [Nerrs_log Nerrs];
+
+              % Optionally LDPC decode
+            
+              if ldpc_code
+                detected_data = ldpc_dec(code_param, sim_in.max_iterations, sim_in.demod_type, sim_in.decoder_type, ...
+                                         rx_symb_linear, min(100,EsNo_), amp_linear);
+                error_positions = xor( detected_data(1:framesize*rate), tx_bits_buf(1:framesize*rate) );
+                Nerrs = sum(error_positions);
+                ldpc_Nerrs_log = [ldpc_Nerrs_log Nerrs];
+                ldpc_errors_log = [ldpc_errors_log error_positions];
+                if Nerrs
+                    Ferrsldpc++;
+                end
+                Terrsldpc += Nerrs;
+                Tbitsldpc += framesize*rate;
+              end
+            end
+          end
+           
+          TERvec(ne) = Terrs;
+          BERvec(ne) = Terrs/Tbits;
+
+            if verbose 
+              av_tx_pwr = (s_ch_tx_log * s_ch_tx_log')/length(s_ch_tx_log);
+
+              printf("EsNo (dB): %3.1f Terrs: %d Tbits: %d BER %5.3f QPSK BER theory %5.3f av_tx_pwr: %3.2f",
+                     EsNodB, Terrs, Tbits,
+                       Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
+              if ldpc_code
+                  printf("\n LDPC: Terrs: %d BER: %4.2f Ferrs: %d FER: %4.2f", 
+                         Terrsldpc, Terrsldpc/Tbitsldpc, Ferrsldpc, Ferrsldpc/Ntrials);
+              end
+              printf("\n");
+            end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    sim_out.errors_log      = errors_log;
+    sim_out.ldpc_errors_log = ldpc_errors_log;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+        a = 1.5*max(real(scat)); b = 1.5*max(imag(scat));
+        axis([-a a -b b]);
+
+        if hf_sim
+          figure(3);
+          clf;
+        
+          y = 1:(hf_n-1);
+          x = 1:Nc*Nd;
+          EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+          EsNodBSurface(find(EsNodBSurface < -5)) = -5;
+          EsNodBSurface(find(EsNodBSurface > 25)) = 25;
+          mesh(x,y,EsNodBSurface);
+          grid
+          axis([1 Nc*Nd 1 Rs*5 -5 25])
+          title('HF Channel Es/No');
+
+          if verbose 
+            [m n] = size(hf_model);
+            av_hf_pwr = sum(sum(abs(hf_model(:,:)).^2))/(m*n);
+            printf("average HF power: %3.2f over %d symbols\n", av_hf_pwr, m*n);
+          end
+
+       end
+
+       if strcmp(modulation,'qpsk')
+          % set up time axis to include gaps for pilots
+
+         [m1 n1] = size(phi_log);
+         phi_x = [];
+         phi_x_counter = 1;
+         p = Ns;
+         for r=1:m1
+           if p == Ns
+             phi_x_counter += Npilotsframe;
+             p = 0;
+           end
+           p++;
+           phi_x = [phi_x phi_x_counter++];        
+         end
+
+         phi_x -= Nsymbrowpilot; % account for delay in pilot buffer
+
+         figure(5);
+         clf
+         subplot(211)
+         [m n] = size(phi_log);
+         plot(phi_x, phi_log(:,2),'r+;Estimated HF channel phase;')
+         if hf_sim
+           hold on;
+           [m n] = size(hf_model);
+           plot(angle(hf_model(1:m,2)),'g;HF channel phase;')
+           hold off;
+         end
+         ylabel('Phase (rads)');
+         legend('boxoff');
+         axis([1 m -1.1*pi 1.1*pi])
+
+         subplot(212)
+         plot(phi_x, amp_log(:,2),'r+;Estimated HF channel amp;')
+         if hf_sim
+           hold on;
+           plot(abs(hf_model(1:m,2)))
+           hold off;
+         end
+         ylabel('Amplitude');
+         xlabel('Time (symbols)');
+         legend('boxoff');
+         axis([1 m 0 3])
+       end
+
+       figure(4)
+       clf
+       stem(Nerrs_log)
+       axis([1 length(Nerrs_log) 0 max(Nerrs_log)+1])
+   end
+
+endfunction
+
+
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.do_write_pilot_file = 0;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 50; 
+  sim_in.Ntrials          = 30;
+  sim_in.framesize        = 2;
+  sim_in.Rs               = 50;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 0;
+
+  sim_in.Nd            = 1;
+endfunction
diff --git a/codec2/branches/0.7/octave/cohpsk_demod_plot.m b/codec2/branches/0.7/octave/cohpsk_demod_plot.m
new file mode 100644 (file)
index 0000000..44376ba
--- /dev/null
@@ -0,0 +1,159 @@
+% cohpsk_demod_plot.m
+% David Rowe May 2015
+%
+% Plot Octave outputs from cohpsk_demod, c2dec, to visualise whats going on
+% when errors hit the system
+
+% $ ./c2enc 700 ../../raw/ve9qrp_10s.raw - | ./cohpsk_mod - - | ./cohpsk_ch - - -60 50 1 1 | ./cohpsk_demod - - cohpsk_demod.txt | ./c2dec 700 - - --dump ve9qrp | play -t raw -r 8000 -s -2 - -q
+
+% ./c2enc 700 ../../raw/ve9qrp_10s.raw - | ./cohpsk_mod - - | ./cohpsk_ch - - -30 50 1 1 | ./cohpsk_demod - - cohpsk_demod.txt | ./c2dec 700 - - --dump ve9qrp_snr3 | play -t raw -r 8000 -s -2 - -q
+
+graphics_toolkit ("gnuplot");
+
+Nc=7; Nd=2; Ns=6;
+
+load ../build_linux/src/cohpsk_demod.txt
+load ../build_linux/src/cohpsk_put_test_bits.txt
+load ../build_linux/src/ve9qrp_lsp_.txt
+load ../build_linux/src/ve9qrp_snr3_lsp_.txt
+load ../build_linux/src/ve9qrp_ak_.txt
+load ../build_linux/src/ve9qrp_snr3_ak_.txt
+load ../build_linux/src/ve9qrp_model.txt
+load ../build_linux/src/ve9qrp_snr3_model.txt
+load ../build_linux/src/ve9qrp_snr3_softdec.txt
+
+Ncf = 50;     % number of codec frames to plot
+Nmf = Ncf/2;  % number of modem frames to plot
+Nms = Nmf*Ns; % number of modem symbols to plot
+
+figure(1)
+clf;
+
+% plot combined signals to show diversity gains
+
+combined = rx_symb_log_c(:,1:Nc);
+for d=2:Nd
+  combined += rx_symb_log_c(:, (d-1)*Nc+1:d*Nc);
+end
+plot(combined*exp(j*pi/4)/sqrt(Nd),'+')
+title('Scatter');
+axis([-2 2 -2 2])
+
+figure(2)
+clf;
+subplot(211)
+plot(rx_phi_log_c(1:Nms,:))
+title('phase')
+axis([1 Nms -pi pi])
+subplot(212)
+plot(rx_amp_log_c(1:Nms,:))
+title('amplitude')
+axis([1 Nms 0 1])
+
+figure(3)
+subplot(211)
+plot(rx_timing_log_c)
+title('rx timing');
+subplot(212)
+stem(ratio_log_c)
+title('Sync ratio');
+
+figure(4);
+clf;
+plot(nerr_log_c(1:Ncf));
+title('Bit Errors');
+xlabel('Codec Frame')
+
+figure(5);
+clf;
+plot(error_positions_hist_c);
+title('Error Position Histogram');
+
+figure(6)
+y = 1:Nms;
+x = 1:Nc*Nd;
+z = 20*log10(rx_amp_log_c(1:Nms,:));
+mesh(x,y,z);
+grid
+title('Channel Amplitude dB');
+a = min(min(z));
+b = max(max(z));
+axis([1 Nc*Nd 1 Nms a b])
+
+% work out alignment, as they sync at different times
+
+min_e = 1E6;
+for i=1:10
+  l1 = length(ve9qrp_lsp_);
+  l2 = length(ve9qrp_snr3_lsp_);
+  st = i; en = min(l1+i-1,l2);
+  d = ve9qrp_lsp_(st:en, 1:6) - ve9qrp_snr3_lsp_(1:en-st+1, 1:6);
+  e = sum(sum(abs(d)));
+  if e < min_e
+    min_e = e;
+    min_i = i;
+  end
+end
+printf("time offset between clean and 3dB is %d codec frames\n", min_i);
+
+% LSP trajectories
+
+figure(7)
+clf
+st = min_i; en = 50;
+plot(ve9qrp_snr3_lsp_(1:en-st+1, 1:6),'r--')
+hold on
+plot(ve9qrp_lsp_(st:en, 1:6),'g')
+hold off
+
+% Spectral distortion of LPCs
+
+figure(8)
+clf;
+f1=1./fft(ve9qrp_ak_(st:en,:)',128);
+f2=1./fft(ve9qrp_snr3_ak_(1:en-st+1,:)',128);
+%d = (20*log10(abs(f1)) - 20*log10(abs(f2)));
+d = 20*log10(abs(f2));
+sdsq = mean(d.^2);
+plot(sdsq)
+title('spectral distortion clean and channel SNR=3dB')
+
+figure(9)
+clf;
+y = 1:en-st+1;
+x = 1:40;
+%mesh(y,x,-20*log10(abs(f2(1:40,:))));
+mesh(y,x,d(x,:));
+grid
+title('Synthesis filter difference between clean and channel SNR=3dB');
+xlabel('Time (codec frames)')
+ylabel('Frequency 0 to 2500Hz');
+zlabel('Difference (dB)');
+
+% map soft decn information to LSPs
+
+mel1 = ve9qrp_snr3_softdec(:,10:12);
+mel2 = ve9qrp_snr3_softdec(:,13:14);
+mel3 = ve9qrp_snr3_softdec(:,15:18);
+mel4 = ve9qrp_snr3_softdec(:,19:21);
+mel5 = ve9qrp_snr3_softdec(:,22:24);
+mel6 = ve9qrp_snr3_softdec(:,25:26);
+softdec_mel = [sum(mel1'.^2); sum(mel2'.^2); sum(mel3'.^2); sum(mel4'.^2); sum(mel5'.^2); sum(mel6'.^2)];
+
+figure(10)
+clf;
+y = 1:en-st+1;
+x = 1:6;
+%mesh(y,x,-20*log10(abs(f2(1:40,:))));
+mesh(y, x, softdec_mel(:,y));
+grid
+xlabel('Codec frame')
+ylabel('LSP')
+zlabel('Power')
+%axis([1 (en-st+1) 1 6 -10 5])
+
+% plot symbol energy against SD
+
+figure(11)
+semilogx(mean(softdec_mel(:,1:en-st+1)), sdsq,'+')
+grid
diff --git a/codec2/branches/0.7/octave/cohpsk_frame_design.ods b/codec2/branches/0.7/octave/cohpsk_frame_design.ods
new file mode 100644 (file)
index 0000000..915ea08
Binary files /dev/null and b/codec2/branches/0.7/octave/cohpsk_frame_design.ods differ
diff --git a/codec2/branches/0.7/octave/cohpsk_plots.m b/codec2/branches/0.7/octave/cohpsk_plots.m
new file mode 100644 (file)
index 0000000..9fc9a11
--- /dev/null
@@ -0,0 +1,141 @@
+% cohpsk_plots.m
+% David Rowe Feb 2017
+%
+% Generate some plots for chps modem blog post
+
+rand("seed",1);
+
+% Multipath with simple unfiltered BPSK signal
+
+N = 100;  % number of symbols
+M = 4;    % oversample rate
+
+tx_bits = rand(1,N) > 0.5;
+tx_symbols = 2*tx_bits - 1;
+tx = zeros(1,N*M);
+
+for i=1:N
+  tx((i-1)*M+1:i*M) = tx_symbols(i);
+end
+
+h = [0 0 0 0 0.5];   % model of second path
+
+rx1 = tx;
+rx2 = filter(h,1,tx);
+rx = rx1 + rx2;
+
+% Multipath in time domain
+
+figure(1); clf;
+subplot(311)
+plot(rx1, "linewidth", 4)
+axis([0 10*M+1 -2 2]);
+subplot(312)
+plot(rx2, "linewidth", 4)
+axis([0 10*M+1 -2 2]);
+subplot(313)
+plot(rx, "linewidth", 4)
+axis([0 10*M+1 -2 2]);
+xlabel('Time');
+print("cohpsk_multipath_time.png", "-dpng", "-S600,440", "-F:8")
+
+% Multipath channel magnitude and phase response against frequency
+
+h = [1 0 0 0 0.5];   % model of two path multipath channel
+H = freqz(h,1,100);
+
+figure(2); clf;
+subplot(211)
+plot(20*log10(abs(H)), "linewidth", 4)
+title('Amplitude (dB)');
+subplot(212)
+plot(angle(H), "linewidth", 4)
+title('Phase (rads)');
+%axis([0 500 -2 2]);
+xlabel('Frequency');
+print("cohpsk_multipath_channel.png", "-dpng", "-S600,440", "-F:8")
+
+% Effective of 1 sample multipath for different symbols lengths
+
+h = [1 0 0 0 0.5];   % model of two path multipath channel
+M1 = 2;
+M2 = 20;
+tx1 = zeros(1,N*M1);
+tx2 = zeros(1,N*M2);
+for i=1:N
+  tx1((i-1)*M1+1:i*M1) = tx_symbols(i);
+  tx2((i-1)*M2+1:i*M2) = tx_symbols(i);
+end
+
+rx1 = filter(h,1,tx1);
+rx2 = filter(h,1,tx2);
+
+figure(3); clf;
+subplot(211)
+plot(rx1, "linewidth", 4)
+axis([0 10*M1+1 -2 2]);
+title('1ms multipath with 2ms symbols')
+subplot(212)
+plot(rx2, "linewidth", 4)
+axis([0 10*M2+1 -2 2]);
+title('1ms multipath with 20ms symbols')
+xlabel('Time');
+print("cohpsk_multipath_symbol_length.png", "-dpng", "-S600,440", "-F:8")
+
+% DBPSK --------------------------------------------------
+
+N = 10;
+tx_bits = rand(1,N) > 0.5;
+bpsk = 2*tx_bits - 1;
+prev_bpsk = 1;
+for i=1:N
+
+  % BPSK -> DBPSK
+
+  dbpsk(i) = bpsk(i) * (-prev_bpsk);
+  prev_bpsk = bpsk(i);
+
+  % oversampling
+
+  tx_bpsk((i-1)*M+1:i*M) = bpsk(i);
+  tx_dbpsk((i-1)*M+1:i*M) = dbpsk(i);
+end
+
+figure(4); clf;
+subplot(211);
+plot(tx_bpsk, "linewidth", 4)
+axis([0 10*M+1 -2 2]);
+title('Tx BPSK');
+subplot(212);
+plot(tx_dbpsk, "linewidth", 4)
+axis([0 10*M+1 -2 2]);
+title('Tx DBPSK');
+print("cohpsk_dbpsk1.png", "-dpng", "-S600,440", "-F:8")
+
+dbpsk *= -1;
+
+prev_rx = 1;
+for i=1:N
+
+  % rx DBPSK -> PSK
+
+  bpsk(i) = dbpsk(i) * (prev_rx);
+  prev_rx = bpsk(i);
+
+  % oversampling
+
+  rx_bpsk((i-1)*M+1:i*M) = bpsk(i);
+  rx_dbpsk((i-1)*M+1:i*M) = dbpsk(i);
+end
+
+figure(5); clf;
+subplot(211);
+plot(rx_dbpsk, "linewidth", 4)
+axis([0 10*M+1 -2 2]);
+title('Rx DBPSK with 180 deg phase shift');
+subplot(212);
+plot(rx_bpsk, "linewidth", 4)
+axis([0 10*M+1 -2 2]);
+title('Rx BPSK');
+print("cohpsk_dbpsk2.png", "-dpng", "-S600,440", "-F:8")
+
diff --git a/codec2/branches/0.7/octave/crc16.m b/codec2/branches/0.7/octave/crc16.m
new file mode 100644 (file)
index 0000000..aafc432
--- /dev/null
@@ -0,0 +1,55 @@
+% crc16.m\r
+%\r
+%The CRC calculation is based on following generator polynomial:\r
+%G(x) = x16 + x12 + x5 + 1\r
+%\r
+%The register initial value of the implementation is: 0xFFFF\r
+%\r
+%used data = string -> 1 2 3 4 5 6 7 8 9\r
+%\r
+% Online calculator to check the script:\r
+%http://www.lammertbies.nl/comm/info/crc-calculation.html\r
+%\r
+%\r
+\r
+function crc = crc16(data)\r
+\r
+  % crc look up table\r
+\r
+  Crc_ui16LookupTable=[0,4129,8258,12387,16516,20645,24774,28903,33032,37161,41290,45419,49548,...\r
+    53677,57806,61935,4657,528,12915,8786,21173,17044,29431,25302,37689,33560,45947,41818,54205,...\r
+    50076,62463,58334,9314,13379,1056,5121,25830,29895,17572,21637,42346,46411,34088,38153,58862,...\r
+    62927,50604,54669,13907,9842,5649,1584,30423,26358,22165,18100,46939,42874,38681,34616,63455,...\r
+    59390,55197,51132,18628,22757,26758,30887,2112,6241,10242,14371,51660,55789,59790,63919,35144,...\r
+    39273,43274,47403,23285,19156,31415,27286,6769,2640,14899,10770,56317,52188,64447,60318,39801,...\r
+    35672,47931,43802,27814,31879,19684,23749,11298,15363,3168,7233,60846,64911,52716,56781,44330,...\r
+    48395,36200,40265,32407,28342,24277,20212,15891,11826,7761,3696,65439,61374,57309,53244,48923,...\r
+    44858,40793,36728,37256,33193,45514,41451,53516,49453,61774,57711,4224,161,12482,8419,20484,...\r
+    16421,28742,24679,33721,37784,41979,46042,49981,54044,58239,62302,689,4752,8947,13010,16949,...\r
+    21012,25207,29270,46570,42443,38312,34185,62830,58703,54572,50445,13538,9411,5280,1153,29798,...\r
+    25671,21540,17413,42971,47098,34713,38840,59231,63358,50973,55100,9939,14066,1681,5808,26199,...\r
+    30326,17941,22068,55628,51565,63758,59695,39368,35305,47498,43435,22596,18533,30726,26663,6336,...\r
+    2273,14466,10403,52093,56156,60223,64286,35833,39896,43963,48026,19061,23124,27191,31254,2801,6864,...\r
+    10931,14994,64814,60687,56684,52557,48554,44427,40424,36297,31782,27655,23652,19525,15522,11395,...\r
+    7392,3265,61215,65342,53085,57212,44955,49082,36825,40952,28183,32310,20053,24180,11923,16050,3793,7920];\r
+\r
+  ui16RetCRC16 = hex2dec('FFFF');\r
+  for I=1:length(data)\r
+    ui8LookupTableIndex = bitxor(data(I),uint8(bitshift(ui16RetCRC16,-8)));\r
+    ui16RetCRC16 = bitxor(Crc_ui16LookupTable(double(ui8LookupTableIndex)+1),mod(bitshift(ui16RetCRC16,8),65536));\r
+  end\r
+  crc=dec2hex(ui16RetCRC16);\r
+\r
+endfunction\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/codec2/branches/0.7/octave/cspec.m b/codec2/branches/0.7/octave/cspec.m
new file mode 100644 (file)
index 0000000..e0ca15b
--- /dev/null
@@ -0,0 +1,54 @@
+% cspec.m
+% David Rowe Aug 2012
+% Used to compare spectromgrams while experimenting with phase
+
+function cspec(s1,s2)
+  f1 = fopen(s1,"rb");
+  s1 = fread(f1,Inf,"short");
+  f2 = fopen(s2,"rb");
+  s2 = fread(f2,Inf,"short");
+
+  Fs = 8000;
+  spec_win = 512;
+
+  state = 's1';
+  do 
+    if strcmp(state,'s1')
+      spec(s1,Fs,spec_win);
+      %title(s1);
+    end
+    if strcmp(state,'s2')
+      spec(s2,Fs,spec_win);
+      %title(s2);
+    end
+    if strcmp(state,'diff')
+      spec(s1-s2,Fs,spec_win);
+      %title("difference");
+    end
+
+    printf("\rstate: %s  space-toggle d-diff q-quit", state);
+    fflush(stdout);
+    k = kbhit();
+    
+    if k == ' '
+      if strcmp(state,"diff")
+        next_state = 's1';
+      end
+      if strcmp(state,"s1")
+        next_state = 's2';
+      end
+      if strcmp(state,'s2')
+        next_state = 's1';
+      end
+    end
+
+    if k == 'd'
+      next_state = 'diff';
+    end
+
+    state = next_state;
+  until (k == 'q')
+
+  printf("\n");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/dacres.m b/codec2/branches/0.7/octave/dacres.m
new file mode 100644 (file)
index 0000000..6d42936
--- /dev/null
@@ -0,0 +1,165 @@
+% dacres.m
+% David Rowe 18 Feb 2015
+% Brady O'Brien 5 Mar 2015
+% DAC upconversion simulation
+
+graphics_toolkit ("gnuplot");
+
+cicn = 5;                       %delay for CIC filter
+N = 5;                         %input interpolation rate
+M = 25;                         %dac interpolation rate
+csf = 1024;                  %scaling factor for CIC filter conversion
+fd = 2E6;                       %DAC frequency
+fs = 2E6/M/N;                   %Input sampling frequency
+fi = 2E6/M;                     %freq of first interpolation
+fb = 7E5;                       %Bandpass frequency
+fc1 = fi/4;                     %Frequency of initial upconversion
+ciccb=[-0.029626    0.252638   -2.304683   16.332166   -2.304683    0.252638   -0.029626]; %CIC Compensation FIR
+pcicfb = fir1(41,.5); %Interpolation LPF Fir
+s1fir = filter(ciccb,1,pcicfb); %Combine compensation and LPF
+%s1fir = [-0.00000215, -0.00008715, 0.00073915, -0.00674415, 0.05618415, 0.01629015, -0.19074815, -0.04231615, 0.53620515, 0.09933915, -1.32978715, -0.38797815, 3.97887715, 6.70888315, 3.97887715, -0.38797815, -1.32978715, 0.09933915, 0.53620515, -0.04231615, -0.19074815, ];
+
+t = (1:fs/2);
+scpin = e.^(i*(t*pi*2*(3000/8000)));       % initial complex input
+%scpin = zeros(1,length(t));
+scpin(1) = 1+i;
+
+intstage1 = zeros(1,2*length(scpin));   %First stage of interpolation, 2x
+intstage1(1:2:2*length(scpin))=scpin;
+
+scireal = int32(filter(s1fir,1,real(intstage1))*csf);       %separate input into real and imiginary and apply pre-distortion
+sciimag = int32(filter(s1fir,1,imag(intstage1))*csf);       % also convert to integer. CIC integrator needs integer to work properly
+
+%Apply 3 stage comb to real
+fdin = scireal;
+combout1=0;
+combout2=0;
+combout3=0;
+combout4=0;
+ccbuf1=zeros(1,cicn/N);
+ccbuf2=zeros(1,cicn/N);
+ccbuf3=zeros(1,cicn/N);
+ccbuf4=zeros(1,cicn/N);
+
+for ii=1:length(fdin)
+       combout1 = fdin(ii) - ccbuf1(end);
+       combout2 = combout1 - ccbuf2(end);
+       combout3 = combout2 - ccbuf3(end);
+       combout4 = combout3 - ccbuf4(end);
+       ccbuf1(2:end)=ccbuf1(1:end-1);
+       ccbuf2(2:end)=ccbuf2(1:end-1);
+       ccbuf3(2:end)=ccbuf3(1:end-1);
+       ccbuf4(2:end)=ccbuf4(1:end-1);
+       ccbuf1(1)=fdin(ii);
+       ccbuf2(1)=combout1;
+       ccbuf3(1)=combout2;
+       ccbuf4(1)=combout3;
+       fdcout(ii)=combout4;
+end
+
+intout1=0;
+intout2=0;
+intout3=0;
+intout4=0;
+fdnext = zeros(1,length(fdcout)*N);
+fdnext(1:N:length(fdcout)*N) = fdcout; %Interpolate
+
+for ii=1:length(fdnext)
+       intout1 = fdnext(ii) + intout1;
+       intout2 = intout1 + intout2;
+       intout3 = intout2 + intout3;
+       intout4 = intout3 + intout4;
+       fdnext(ii)=intout4;
+end
+scoreal=single(fdnext/(2**20));
+
+fdin=sciimag;
+
+%Apply 3 stage comb to imag
+combout1=0;
+combout2=0;
+combout3=0;
+combout4=0;
+ccbuf1=zeros(1,cicn/N);
+ccbuf2=zeros(1,cicn/N);
+ccbuf3=zeros(1,cicn/N);
+ccbuf4=zeros(1,cicn/N);
+
+for ii=1:length(fdin)
+       combout1 = fdin(ii) - ccbuf1(end);
+       combout2 = combout1 - ccbuf2(end);
+       combout3 = combout2 - ccbuf3(end);
+       combout4 = combout3 - ccbuf4(end);
+       ccbuf1(2:end)=ccbuf1(1:end-1);
+       ccbuf2(2:end)=ccbuf2(1:end-1);
+       ccbuf3(2:end)=ccbuf3(1:end-1);
+       ccbuf4(2:end)=ccbuf4(1:end-1);
+       ccbuf1(1)=fdin(ii);
+       ccbuf2(1)=combout1;
+       ccbuf3(1)=combout2;
+       ccbuf4(1)=combout3;
+       fdcout(ii)=combout4;
+end
+
+intout1=0;
+intout2=0;
+intout3=0;
+intout4=0;
+fdnext = zeros(1,length(fdcout)*N);
+fdnext(1:N:length(fdcout)*N) = fdcout; %Interpolate
+
+for ii=1:length(fdnext)
+       intout1 = fdnext(ii) + intout1;
+       intout2 = intout1 + intout2;
+       intout3 = intout2 + intout3;
+       intout4 = intout3 + intout4;
+       fdnext(ii)=intout4;
+end
+scoimag=single(fdnext/(2**20));
+
+%Convert complex to real and shift up to Fs/4
+ssout = scoreal.*cos(pi*.5*(1:length(scoreal))) + scoimag.*sin(pi*.5*(1:length(scoimag)));
+
+
+t = (0:(fi-1));
+
+beta1 = 0.999;
+b1x = -2*sqrt(beta1)*cos(2*pi*(fb/fd))
+beta2 = beta1 - (1-beta1)*M;
+
+sducin = ssout;
+%sducin = cos(pi*.5*t);
+
+sduceq = filter([1 0 beta2],1,sducin);  %pre interpolation notch filter to equalize bandpass after interpolation
+sducinterp = zeros(1,length(sduceq)*M);    %interpolate by zero-stuffing
+sducinterp(1:M:length(sduceq)*M) = sduceq;
+sdac = filter(1,[1 b1x beta1],sducinterp); %select wanted signal
+
+sdac = sdac + median(sdac);  %Center above zero
+sdac = sdac / max(sdac);     %normalize
+sdac = int32(sdac*2000);     %integerize
+sdac = sdac + sdac .^ 5;
+
+figure(1)
+subplot(211)
+plot(20*log10(abs(fft(sducin)/fi)))
+grid
+axis([0 fi/2 -20 50])
+title('Output from modem');
+subplot(212)
+plot(20*log10(abs(fft(sduceq/fi))))
+grid
+axis([0 fi/2 -20 70])
+title('After Pre-eq');
+
+figure(2)
+subplot(211)
+plot(20*log10(abs(fft(sducinterp)/fd)))
+grid
+axis([0 (fd/2) -20 80])
+title('After interpolation');
+subplot(212)
+plot(20*log10(abs(fft(sdac)/fd)))
+grid
+title('After bandpass');
+%axis([0 (fd/2) -20 80])
diff --git a/codec2/branches/0.7/octave/df_mixer.m b/codec2/branches/0.7/octave/df_mixer.m
new file mode 100644 (file)
index 0000000..9f744ed
--- /dev/null
@@ -0,0 +1,272 @@
+% df_mixer.m
+%
+% David Rowe October 2015
+%
+% Experimental direction finding using a mixer to FDM signals from two
+% antennas.  This simulation tests estimation of phase and freq of 
+% mixer LO.
+%
+% [X] built in hackrf_dc
+% [X] test mode
+% [X] compass needle
+% [X] real time operation (or close to it)
+
+fm;
+
+% Generate a FM modulated signal for testing ----------------------------------
+
+function tx = fm_mod(Fs, fmod)
+  fm_states.Fs = Fs;  
+  fm_states.fm_max = 3E3;
+  fm_states.fd = 5E3;
+  fm_states.fc = 48E3;
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = 0;
+  fm_states.Ts = 1;
+  fm_states.output_filter = 1;
+  fm_states = analog_fm_init(fm_states);
+
+  nsam = fm_states.Fs/2;
+  t = 0:(nsam-1);
+  wmod = 2*pi*fmod/fm_states.Fs;
+  mod = sin(wmod*t);
+  tx = analog_fm_mod(fm_states, mod);
+endfunction
+
+
+% Check Filters -------------------------------------------------------------
+
+% Run some test signals through all three filters.  Real signals used
+% for convenience, also works with complex.  If another set of filter
+% is used you need to prove net reponse is a delay.  Fig 2
+% subplot(211) must be a straight line.
+
+function check_filters(bcentre, Fs, f, bw, w, wlo, t)
+  x = cos(w*t) + cos((w-wlo)*t) + cos((w-wlo)*t); 
+  ycenter = filter(bcentre,1,x);
+  ylow    = exp(-j*wlo*t) .* filter(bcentre, 1, x .* exp(j*wlo*t));
+  yhigh   = exp(j*wlo*t) .* filter(bcentre, 1, x .* exp(-j*wlo*t));
+  y = ycenter + ylow + yhigh;
+
+  figure(1)
+  clf
+  h=freqz(bcentre,1,Fs/2);
+  plot(20*log10(abs(h)))
+  hold on;
+  plot([f-bw/2 f-bw/2 f+bw/2 f+bw/2],[-60 -3 -3 -60],'r');
+  hold off;
+  axis([f-bw f+bw -60 0])
+  title('Centre BPF');
+  grid;
+
+  figure(2)
+  clf;
+  Ns = 200;
+  Np = 200;
+
+  % y should be a delayed version of x
+
+  subplot(211)
+  plot(x(Ns:Ns+Np-1))
+  hold on;
+  plot(y(Ns:Ns+Np-1),'g')
+  hold off;
+  title('Filter Check');
+
+  % should see a straight line on this plot
+
+  subplot(212)
+  plot(x(Ns:Ns+Np-1), y(Ns:Ns+Np-1))
+end
+
+
+% Constants -------------------------------------------------------------------
+
+randn('state',1);
+more off;
+format short
+
+f     = 48E3;          % signal frequency
+flo   = 32.768E3;      % LO frequency
+m     = 10^(-0/20);    % modulation index of our mixer, how far each 
+                       % sideband is down wrt carrier (0.1 == 20dB)
+                       % note: not FM modulation index
+bw    = 16E3;          % signal bandwidth
+
+phi   = 0.5;           % phase difference between antennas - 
+                       % ->> what we are trying to estimate
+
+theta = 0;             % phase term constant to ant1 and ant2
+alpha = 0;             % LO phase
+
+Fs    = 200E3;         % sample rate
+Fshrf = 10E6;          % HackRF sample rate
+CNodB = 100;           % C/No of carrier, which dominates power
+                       % Around C/No = 50dB is min for FM (12dB-ish SINAD)
+fmod  = 0;             % Audio modulation on FM signal (0 for carrier)
+N     = Fs/2;          % processing block size
+
+% BW is Fs Hz.  No=(total noise power Nt)/Fs. N=noise power=variance of noise source
+% C = carrier power = 1
+% CNo = C/No = 1/(Nt/Fs), therefore var = Nt = Fs/CNo
+
+CNo = 10^(CNodB/10);
+var = Fs/CNo;
+
+w   = 2*pi*f/Fs;
+wlo = 2*pi*flo/Fs;
+wbw = 2*pi*bw/Fs;
+
+% FIR filter BPF for centre signal.  Use a 15kHz cut off to catch
+% energy from FM signals.  Important: we need identical phase response
+% for each BPF.  I couldn't work out how to design these filter using
+% the built-in Octave functions.  So I use a bunch of freq shifts at
+% run time instead, so we use the centre BPF for all three filters.
+
+bcentre  = fir2(200, [0, f-bw/2, f, f+bw/2, Fs/2]/(Fs/2), [0 0 1 0 0]);
+
+%check_filters(bcentre, Fs, f, bw, w, wlo, t); xx
+
+% Main -------------------------------------------------------------------------
+
+mode = "sample";
+finished = 0;
+while !finished
+
+  if strcmp(mode, "simulate")
+    % Simulate rx signal ---------------------------------------------------------
+
+    t=0:N-1;
+
+    % tx signal
+
+    tx = fm_mod(Fs, fmod); 
+
+    % simulate rx signals at antenna 1 and 2 by adding noise.  Note signal
+    % at antenna 2 is phase shifted phi due to path difference. Both signals
+    % experience a time of flight path different theta.
+
+    n = sqrt(var/2)*randn(1,N) + j*sqrt(var/2)*randn(1,N);
+    ant1 = tx*exp(j*(theta+phi)) + n;
+    ant2 = tx*exp(j*(theta)) + n;
+
+    % ant2 passed through mixer with local osc frequency wlo and phase alpha
+
+    ant2_mix = 2.0*m*(ant2 .* cos(t*wlo + alpha));
+
+    % The SDR receives the sum of the two signals
+
+    rx = ant1 + ant2_mix;
+  end
+
+  if strcmp(mode,"file") || strcmp(mode,"sample")
+    % Off air signal from HackRF stored in file ----------------------------------------------
+
+    if strcmp(mode,"sample")
+      [status output] = system("hackrf_transfer -r df1.iq -f 439000000  -n 10000000 -l 20 -g 40");
+    end
+    s1 = load_hackrf("df1.iq");
+    rx = downsample(rot90(s1), Fshrf/Fs)/127;
+    t = 1:length(rx);  
+  end
+
+  Rx = (1/N)*fft(rx,N);
+
+  % BPF each signal
+
+  sam1 = filter(bcentre,1,rx);
+  sam2 = exp( j*wlo*t) .* filter(bcentre, 1, rx .* exp(-j*wlo*t));
+  sam3 = exp(-j*wlo*t) .* filter(bcentre, 1, rx .* exp( j*wlo*t));
+
+  % Do the math on phases using rect math
+
+  two_phi_est_rect = conj(sam2.*sam3) .* (sam1.^2);
+  phi_est = angle(two_phi_est_rect)/2;
+
+  phi_est_av = angle(mean(two_phi_est_rect))/2;
+
+  printf("phi_est : %3.2f rads %3.1f degrees\n", phi_est_av, phi_est_av*180/pi);
+
+  % some plots ....
+
+  figs = 0x1 + 0x2 + 0x20;
+
+  if bitand(figs, 0x1)
+    figure(1);
+    clf;
+    plot((1:N)*Fs/N, 20*log10(abs(Rx)),'markersize', 10, 'linewidth', 2);
+    axis([1 Fs -80 0])
+    title('Rx signal at SDR input');
+  end
+
+  if bitand(figs, 0x2)
+    figure(2)
+    clf
+    Sam1 = (1/N)*fft(sam1,N);
+    Sam2 = (1/N)*fft(sam2,N);
+    Sam3 = (1/N)*fft(sam3,N);
+    subplot(311)
+    plot((1:N)*Fs/N, 20*log10(abs(Sam1)),'markersize', 10, 'linewidth', 2);
+    axis([f-bw/2 f+bw/2 -60 0])
+    title('Band Pass filtered signals');
+    subplot(312)
+    plot((1:N)*Fs/N, 20*log10(abs(Sam2)),'markersize', 10, 'linewidth', 2);
+    axis([f+flo-bw/2 f+flo+bw/2 -60 0])
+    subplot(313)
+    plot((1:N)*Fs/N, 20*log10(abs(Sam3)),'markersize', 10, 'linewidth', 2);
+    axis([f-flo-bw/2 f-flo+bw/2 -60 0])
+  end
+
+  if bitand(figs, 0x4)
+    figure(3)
+    Np = 1000;
+    subplot(311)
+    plot(real(sam1(1:Np)))
+    title('Band Pass filtered signals');
+    subplot(312)
+    plot(real(sam2(1:Np)))
+    subplot(313)
+    plot(real(sam3(1:Np)))
+  end
+
+  if bitand(figs, 0x8)
+    figure(4)
+    clf;
+    hist2d([real(two_phi_est_rect)' imag(two_phi_est_rect)'],50)
+    xmax = 2*mean(abs(two_phi_est_rect));
+    axis([-xmax xmax -xmax xmax])
+    title('Scatter Plot');
+  end
+
+  if bitand(figs, 0x10)
+    figure(5)
+    clf;
+    subplot(211)
+    plot(real(two_phi_est_rect(1:Np)))
+    subplot(212)
+    plot(imag(two_phi_est_rect(1:Np)))
+    title('two phi est rect')
+  end
+
+  if bitand(figs, 0x20)
+    figure(6)
+    clf
+    [r theta] = hist([angle(two_phi_est_rect)/2 -pi/2 pi/2],100);
+    polar([theta pi+theta],[r r])
+  end
+
+  if bitand(figs, 0x40)
+    figure(7)
+    clf
+    plot(phi_est)
+    axis([0 length(phi_est(1:Np)) -pi/2 pi/2]);
+    title('phi est')
+  end
+
+  % when sampling hit any key to finish, finish after one pass in other modes
+
+  finished = 1;
+  if strcmp(mode, "sample")
+    finished = length(kbhit(1));
+  end
+end
diff --git a/codec2/branches/0.7/octave/diff_codec.m b/codec2/branches/0.7/octave/diff_codec.m
new file mode 100644 (file)
index 0000000..2ad204f
--- /dev/null
@@ -0,0 +1,96 @@
+% diff_codec.m
+%
+% Plots differences between two states in two runs of the codec,
+% e.g. x86 and embedded.
+%
+% Copyright David Rowe 2013
+%
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+
+function diff_codec(samname1, samname2, model1_prefix, model2_prefix)
+  
+  fs1=fopen(samname1,"rb");
+  s1=fread(fs1,Inf,"short");
+  fs2=fopen(samname2,"rb");
+  s2=fread(fs2,Inf,"short");
+
+  st = 1;
+  en = length(s1);
+
+  figure(1);
+  clf;
+  subplot(211);
+  l1 = strcat("r;",samname1,";");
+  plot(s1(st:en), l1);
+  axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+  subplot(212);
+  l2 = strcat("r;",samname2,";");
+  plot(s2(st:en),l2);
+  axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+  figure(2)
+  plot(s1(st:en)-s2(st:en));
+  max(s1(st:en)-s2(st:en));
+  
+  model_name1 = strcat(model1_prefix,"_model.txt");
+  model1 = load(model_name1);
+  model_name1q = strcat(model1_prefix,"_qmodel.txt");
+  model1q = load(model_name1q);
+
+  model_name2 = strcat(model2_prefix,"_model.txt");
+  model2 = load(model_name2);
+  model_name2q = strcat(model2_prefix,"_qmodel.txt");
+  model2q = load(model_name2q);
+
+  Wo1 = model1(:,1);
+  L1 = model1(:,2);
+  Am1 = model1(:,3:82);
+  Wo1q = model1q(:,1);
+  L1q = model1q(:,2);
+  Am1q = model1q(:,3:82);
+
+  Wo2 = model2(:,1);
+  L2 = model2(:,2);
+  Am2 = model2(:,3:82);
+  Wo2q = model2q(:,1);
+  L2q = model2q(:,2);
+  Am2q = model2q(:,3:82);
+
+  figure(3)
+  subplot(211)
+  plot(Wo1)
+  title('Wo1');
+  subplot(212)
+  plot(Wo1-Wo2)
+  figure(4)
+  subplot(211)
+  plot(Wo1q)
+  title('Wo1q');
+  subplot(212)
+  plot(Wo1q-Wo2q)
+
+  figure(5)
+  subplot(211)
+  plot(L1)
+  title('L1');
+  subplot(212)
+  plot(L1-L2)
+  figure(6)
+  subplot(211)
+  plot(L1q)
+  title('L1q');
+  subplot(212)
+  plot(L1q-L2q)
+  
+  figure(7)
+  l=length(L1q);
+  sm=zeros(1,l);
+  for f=1:l
+    %printf("f %d L1q %d L2q %d\n",f,L1q(f),L2q(f));  
+    sm(f) = sum(10*log10(Am1q(f,1:L1q(f))) - 10*log10(Am2q(f,1:L2q(f))));
+  end
+  plot(sm)
+  title('Am1q - Am2q');
+
+endfunction
diff --git a/codec2/branches/0.7/octave/doppler_spread.m b/codec2/branches/0.7/octave/doppler_spread.m
new file mode 100644 (file)
index 0000000..4bc6c62
--- /dev/null
@@ -0,0 +1,37 @@
+% doppler_spread.m
+% David Rowe Jan 2016
+%
+% Returns gausssian filtered doppler spreading function samples for HF channel
+% modelling.  Used PathSim technical guide as a reference - thanks Moe!
+
+function [spread_FsHz states] = doppler_spread(dopplerSpreadHz, FsHz, Nsam)
+
+  % start with low Fs so we can work with a reasonable filter length
+
+  sigma = dopplerSpreadHz/2;
+  lowFs = 10*dopplerSpreadHz;
+  Ntaps = 100;
+  Nsam_low = Nsam*lowFs/FsHz + Ntaps; % fill filter memory
+
+  % generate gaussian freq response and design filter
+
+  x = 0:0.1:lowFs/2;
+  y = (1/(sigma*sqrt(2*pi)))*exp(-(x.^2)/(2*sigma*sigma));
+  b = fir2(Ntaps-1, x/(lowFs/2), y);
+
+  % generate the spreading samples
+
+  spread_lowFs = filter(b,1,randn(1,Nsam_low) + j*randn(1,Nsam_low));
+
+  % resample to FsHz, scaling for desired spreadFreqHz
+
+  spread_FsHz = resample(spread_lowFs(Ntaps+1:Nsam_low), FsHz, lowFs);
+
+  % return some states for optional unit testing
+  states.x = x;
+  states.y = y;
+  states.b = b;
+
+endfunction
+
+
diff --git a/codec2/branches/0.7/octave/doppler_spread_ut.m b/codec2/branches/0.7/octave/doppler_spread_ut.m
new file mode 100644 (file)
index 0000000..f7d96b0
--- /dev/null
@@ -0,0 +1,51 @@
+% doppler_spread_ut.m
+% David Rowe Jan 2016
+%
+% Unit test script for doppler_spread
+
+f = 1;
+Fs = 8000;
+N  = Fs*10;
+
+[spread states] = doppler_spread(f, Fs, N);
+
+% use spreading samples to modulate 1000Hz sine wave
+% You can listen to this with: sine1k_1Hz.raw
+
+%   $ play -t raw -r 8000 -s -2 
+s = cos(2*pi*(1:N)*1000/Fs);
+s = s .* spread;
+s = real(s)*5000;
+fs = fopen("sine1k_1Hz.raw","wb"); fwrite(fs,s,"short"); fclose(fs);
+
+% Some plots
+
+x = states.x; y = states.y; b = states.b;
+
+H = freqz(b,1,x);
+
+figure(1)
+clf
+subplot(211)
+plot(x,y,';target;')
+title('Gaussian Filter Freq Resp Lin');
+legend('boxoff');
+subplot(212)
+plot(x,20*log10(y),';target;')
+hold on;
+plot(x,20*log10(y),'g+;actual;')
+hold off;
+axis([0 f*10/2 -60 0])
+title('Gaussian Filter Freq Resp dB');
+xlabel('Freq (Hz)');
+legend('boxoff');
+
+figure(2);
+subplot(211)
+plot(abs(spread))
+title('Spreading Function Magnitude');
+subplot(212)
+plot(s)
+title('1000Hz Sine Wave');
+xlabel('Time (samples)')
+
diff --git a/codec2/branches/0.7/octave/estsnr.m b/codec2/branches/0.7/octave/estsnr.m
new file mode 100644 (file)
index 0000000..5a00bd8
--- /dev/null
@@ -0,0 +1,65 @@
+% estsnr.m
+% David Rowe May 2017
+%
+% estimate SNR of a sinewave in noise
+
+function snr_dB = estsnr(x, Fs=8000, Nbw = 3000)
+
+  [nr nc] = size(x);
+  if nr == 1
+    x = x';
+  end
+
+  % find peak in +ve side of spectrum, ignoring DC
+
+  L = length(x);
+  X = abs(fft(x));
+  st = floor(0.05*L);  en = floor(0.45*L);
+  [A mx_ind]= max(X(st:en));
+  mx_ind += st;
+
+  % signal energy might be spread by doppler, so sum energy
+  % in frequencies +/- 1%
+
+  s_st = floor(mx_ind*0.99); s_en = floor(mx_ind*1.01); 
+  S = sum(X(s_st:s_en).^2);
+
+  % real signal, so -ve power is the same
+
+  S = 2*S;
+  SdB = 10*log10(S);
+
+  printf("Signal Power S: %3.2f dB\n", SdB);
+
+  % locate a band of noise next to it and find power in band
+
+  st = floor(mx_ind+0.05*(L/2));
+  en = st + floor(0.1*(L/2));
+  
+  N = sum(X(st:en).^2);
+
+  % scale this to obtain total noise power across total bandwidth
+
+  N *= L/(en-st);
+  NdB = 10*log10(N);
+  printf("Noise Power N: %3.2f dB\n", NdB);
+
+  % scale noise to designed noise bandwidth /2 fudge factor as its a
+  % real signal, wish I had a better way to explain that!
+
+  NodB = NdB - 10*log10(Fs/2);
+  NscaleddB = NodB + 10*log10(Nbw);
+  snr_dB = SdB - NscaleddB;
+
+  figure(1); clf;
+  plot(20*log10(X(1:L/2)),'b');
+  hold on;
+  plot([s_st s_en], [NdB NdB]- 10*log10(L), 'r');
+  plot([st en], [NdB NdB]- 10*log10(L), 'r');
+  hold off;
+  top = 10*ceil(SdB/10);
+  bot = NodB - 20;
+  axis([1 L/2 bot top]);
+  grid
+  grid("minor")
+endfunction
diff --git a/codec2/branches/0.7/octave/fdmdv.m b/codec2/branches/0.7/octave/fdmdv.m
new file mode 100644 (file)
index 0000000..a7965b3
--- /dev/null
@@ -0,0 +1,1164 @@
+% fdmdv.m
+%
+% Functions that implement a Frequency Divison Multiplexed Modem for
+% Digital Voice (FDMDV) over HF channels.
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% TODO:
+%   [X] refactor with states
+%   [X] remove commented out globals
+%   [X] tfdmdv works
+%   [ ] fdmdv_ut works
+% reqd to make sure we get same random bits at mod and demod
+
+rand('state',1); 
+randn('state',1);
+
+% Functions ----------------------------------------------------
+
+
+function f = fdmdv_init
+    Fs   = f.Fs = 8000;      % sample rate in Hz
+    T    = f.T  = 1/Fs;      % sample period in seconds
+    Rs   = f.Rs = 50;        % symbol rate in Hz
+    Nc   = f.Nc = 14;
+    Nb   = f.Nb = 2;         % Bits/symbol for PSK modulation
+    Rb   = f.Rb = Nc*Rs*Nb;  % bit rate
+    M    = f.M  = Fs/Rs;     % oversampling factor
+    Nsym = f.Nsym  = 6;      % number of symbols to filter over
+
+    Fsep    = f.Fsep = 75;             % Separation between carriers (Hz)
+    Fcenter = f.Fcentre = 1500;        % Centre frequency, Nc/2 carriers below this, 
+                                       % Nc/2 carriers above (Hz)
+    Nt      = f.Nt = 5;                % number of symbols we estimate timing over
+    P       = f.P = 4;                 % oversample factor used for rx symbol filtering
+    Nfilter = f.Nfilter = Nsym*M;
+
+    Nfiltertiming = f.Nfiltertiming = M+Nfilter+M;
+
+    Nsync_mem = f.Nsync_mem = 6;
+    f.sync_uw = [1 -1 1 -1 1 -1];
+
+    alpha = 0.5;
+    f.gt_alpha5_root = gen_rn_coeffs(alpha, T, Rs, Nsym, M);
+
+    f.pilot_bit = 0;                   % current value of pilot bit
+
+    f.tx_filter_memory = zeros(Nc+1, Nfilter);
+    f.rx_filter_memory = zeros(Nc+1, Nfilter);
+    f.rx_fdm_mem = zeros(1,Nfilter+M);
+
+    f.snr_coeff = 0.9;        % SNR est averaging filter coeff
+
+    % phasors used for up and down converters
+
+    f.freq = zeros(Nc+1,1);
+    f.freq_pol = zeros(Nc+1,1);
+
+    for c=1:Nc/2
+      carrier_freq = (-Nc/2 - 1 + c)*Fsep;
+      f.freq_pol(c)   = 2*pi*carrier_freq/Fs;
+      f.freq(c)       = exp(j*f.freq_pol(c));
+    end
+
+    for c=floor(Nc/2)+1:Nc
+      carrier_freq = (-Nc/2 + c)*Fsep;
+      f.freq_pol(c)  = 2*pi*carrier_freq/Fs;
+      f.freq(c)      = exp(j*f.freq_pol(c));
+    end
+
+    f.freq_pol(Nc+1)  = 2*pi*0/Fs;
+    f.freq(Nc+1) = exp(j*f.freq_pol(Nc+1));
+
+    f.fbb_rect = exp(j*2*pi*f.Fcentre/Fs);
+    f.fbb_phase_tx = 1;
+    f.fbb_phase_rx = 1;
+
+    % Spread initial FDM carrier phase out as far as possible.  This
+    % helped PAPR for a few dB.  We don't need to adjust rx phase as DQPSK
+    % takes care of that.
+
+    f.phase_tx = ones(Nc+1,1);
+    f.phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1));
+    f.phase_rx = ones(Nc+1,1);
+
+    % decimation filter
+
+    f.Nrxdec = 31;
+    % fir1() output appears to have changed from when coeffs used in C port were used
+    %f.rxdec_coeff = fir1(f.Nrxdec-1, 0.25);
+    f.rxdec_coeff = [-0.00125472 -0.00204605   -0.0019897  0.000163906  0.00490937 0.00986375  ...
+                      0.0096718  -0.000480351  -0.019311  -0.0361822   -0.0341251  0.000827866 ...
+                      0.0690577   0.152812      0.222115   0.249004     0.222115   0.152812    ...
+                      0.0690577   0.000827866  -0.0341251 -0.0361822   -0.019311  -0.000480351 ...
+                      0.0096718   0.00986375    0.00490937 0.000163906 -0.0019897 -0.00204605  ...
+                      -0.00125472];
+
+    f.rxdec_lpf_mem = zeros(1,f.Nrxdec-1+M);
+    f.Q=M/4;
+
+    % freq offset estimation
+
+    f.Mpilotfft      = 256;
+    f.Npilotcoeff    = 30;                              
+
+    % here's how to make this filter from scratch, however it appeared to change over different
+    % octave versions so have hard coded to version used for C port
+    %f.pilot_coeff    = fir1(f.Npilotcoeff-1, 200/(Fs/2))'; % 200Hz LPF
+    f.pilot_coeff    = [0.00223001 0.00301037 0.00471258 0.0075934 0.0118145 0.0174153 ...
+                       0.0242969  0.0322204  0.0408199 0.0496286  0.0581172 0.0657392 ...
+                       0.0719806  0.0764066  0.0787022 0.0787022  0.0764066 0.0719806 ...
+                       0.0657392  0.0581172  0.0496286 0.0408199  0.0322204 0.0242969 ...
+                       0.0174153  0.0118145  0.0075934 0.00471258 0.00301037 0.00223001];
+
+    f.Npilotbaseband = f.Npilotcoeff + M + M/P;            % number of pilot baseband samples 
+    f.Npilotlpf      = 4*M;                                % reqd for pilot LPF
+                                                           % number of symbols we DFT pilot over
+                                                           % pilot est window
+
+    % pilot LUT, used for copy of pilot at rx
+  
+    f.pilot_lut = generate_pilot_lut(f);
+    f.pilot_lut_index = 1;
+    f.prev_pilot_lut_index = 3*M+1;
+
+    % Freq offset estimator states 
+
+    f.pilot_baseband1 = zeros(1, f.Npilotbaseband);        % pilot baseband samples
+    f.pilot_baseband2 = zeros(1, f.Npilotbaseband);        % pilot baseband samples
+    f.pilot_lpf1 = zeros(1, f.Npilotlpf);                  % LPF pilot samples
+    f.pilot_lpf2 = zeros(1, f.Npilotlpf);                  % LPF pilot samples
+
+    % Timing estimator states
+
+    f.rx_filter_mem_timing = zeros(Nc+1, Nt*P);
+    f.rx_baseband_mem_timing = zeros(Nc+1, f.Nfiltertiming);
+
+    % Test bit stream state variables
+
+    f = init_test_bits(f);
+endfunction
+
+
+% generate Nc+1 PSK symbols from vector of (1,Nc*Nb) input bits.  The
+% Nc+1 symbol is the +1 -1 +1 .... BPSK sync carrier
+
+function [tx_symbols f] = bits_to_psk(f, prev_tx_symbols, tx_bits)
+  Nc = f.Nc; Nb = f.Nb;
+  m4_gray_to_binary = [
+    bin2dec("00") 
+    bin2dec("01")
+    bin2dec("11")
+    bin2dec("10")
+  ];
+  m8_gray_to_binary = [
+    bin2dec("000")
+    bin2dec("001")
+    bin2dec("011")
+    bin2dec("010")
+    bin2dec("111")
+    bin2dec("110")
+    bin2dec("100")
+    bin2dec("101")
+  ];
+
+  assert(length(tx_bits) == Nc*Nb, "Incorrect number of bits");
+
+  m = 2 .^ Nb;
+  assert((m == 4) || (m == 8));
+
+  for c=1:Nc
+
+    % extract bits for this symbol
+
+    bits_binary = tx_bits((c-1)*Nb+1:c*Nb); 
+    bits_decimal = sum(bits_binary .* 2.^(Nb-1:-1:0)); 
+
+    % determine phase shift using gray code mapping    
+
+    if m == 4
+       phase_shift = (2*pi/m)*m4_gray_to_binary(bits_decimal+1);
+    else
+       phase_shift = (2*pi/m)*m8_gray_to_binary(bits_decimal+1);
+    end
+
+    % apply phase shift from previous symbol
+
+    tx_symbols(c) = exp(j*phase_shift) * prev_tx_symbols(c);
+  end
+
+  % +1 -1 +1 -1 BPSK sync carrier, once filtered becomes two spectral
+  % lines at +/- Rs/2
+  if f.pilot_bit
+     tx_symbols(Nc+1) = -prev_tx_symbols(Nc+1);
+  else
+     tx_symbols(Nc+1) = prev_tx_symbols(Nc+1);
+  end
+  if f.pilot_bit 
+    f.pilot_bit = 0;
+  else
+    f.pilot_bit = 1;
+  end
+
+endfunction
+
+
+% Given Nc symbols construct M samples (1 symbol) of Nc filtered
+% symbols streams
+
+function [tx_baseband fdmdv] = tx_filter(fdmdv, tx_symbols)
+  Nc = fdmdv.Nc;
+  M = fdmdv.M;
+  tx_filter_memory = fdmdv.tx_filter_memory;
+  Nfilter = fdmdv.Nfilter;
+  gt_alpha5_root = fdmdv.gt_alpha5_root;
+
+  tx_baseband = zeros(Nc+1,M);
+
+  % tx filter each symbol, generate M filtered output samples for each symbol.
+  % Efficient polyphase filter techniques used as tx_filter_memory is sparse
+  
+  tx_filter_memory(:,Nfilter) = sqrt(2)/2*tx_symbols;
+
+  for i=1:M
+    tx_baseband(:,i) = M*tx_filter_memory(:,M:M:Nfilter) * gt_alpha5_root(M-i+1:M:Nfilter)';
+  end
+  tx_filter_memory(:,1:Nfilter-M) = tx_filter_memory(:,M+1:Nfilter);
+  tx_filter_memory(:,Nfilter-M+1:Nfilter) = zeros(Nc+1,M);
+
+  fdmdv.tx_filter_memory = tx_filter_memory;
+endfunction
+
+
+% Construct FDM signal by frequency shifting each filtered symbol
+% stream.  Returns complex signal so we can apply frequency offsets
+% easily.
+
+function [tx_fdm fdmdv] = fdm_upconvert(fdmdv, tx_filt)
+  Fs = fdmdv.Fs;
+  M = fdmdv.M;
+  Nc = fdmdv.Nc;
+  Fsep = fdmdv.Fsep;
+  phase_tx = fdmdv.phase_tx;
+  freq = fdmdv.freq;
+  fbb_rect = fdmdv.fbb_rect;
+  fbb_phase_tx = fdmdv.fbb_phase_tx;
+
+  tx_fdm = zeros(1,M);
+
+  % Nc+1 tones
+  
+  for c=1:Nc+1
+      for i=1:M
+        phase_tx(c) = phase_tx(c) * freq(c);
+       tx_fdm(i) = tx_fdm(i) + tx_filt(c,i)*phase_tx(c);
+      end
+  end
+  % shift up to carrier freq
+
+  for i=1:M
+    fbb_phase_tx *= fbb_rect;
+    tx_fdm(i)     = tx_fdm(i) * fbb_phase_tx;  
+  end
+
+  % Scale such that total Carrier power C of real(tx_fdm) = Nc.  This
+  % excludes the power of the pilot tone.
+  % We return the complex (single sided) signal to make frequency
+  % shifting for the purpose of testing easier
+
+  tx_fdm = 2*tx_fdm;
+
+  % normalise digital oscillators as the magnitude can drift over time
+
+  for c=1:Nc+1
+    mag = abs(phase_tx(c));
+    phase_tx(c) /= mag;
+  end
+  mag = abs(fbb_phase_tx);
+  fbb_phase_tx /= mag;
+
+  fdmdv.fbb_phase_tx = fbb_phase_tx;
+  fdmdv.phase_tx = phase_tx;
+endfunction
+
+
+% Frequency shift each modem carrier down to Nc+1 baseband signals
+
+function [rx_baseband fdmdv] = fdm_downconvert(fdmdv, rx_fdm, nin)
+  Fs = fdmdv.Fs;
+  M = fdmdv.M;
+  Nc = fdmdv.Nc;
+  phase_rx = fdmdv.phase_rx;
+  freq = fdmdv.freq;
+
+  rx_baseband = zeros(Nc+1,nin);
+  
+  for c=1:Nc+1
+      for i=1:nin
+        phase_rx(c) = phase_rx(c) * freq(c);
+       rx_baseband(c,i) = rx_fdm(i)*phase_rx(c)';
+      end
+  end
+
+  for c=1:Nc+1
+    mag = abs(phase_rx(c));
+    phase_rx(c) /= mag;
+  end
+
+  fdmdv.phase_rx = phase_rx;
+endfunction
+
+
+% Receive filter each baseband signal at oversample rate P
+
+function [rx_filt fdmdv] = rx_filter(fdmdv, rx_baseband, nin)
+  Nc = fdmdv.Nc;
+  M = fdmdv.M;
+  P = fdmdv.P;
+  rx_filter_memory = fdmdv.rx_filter_memory;
+  Nfilter = fdmdv.Nfilter;
+  gt_alpha5_root = fdmdv.gt_alpha5_root;
+
+  rx_filt = zeros(Nc+1,nin*P/M);
+
+  % rx filter each symbol, generate P filtered output samples for each symbol.
+  % Note we keep memory at rate M, it's just the filter output at rate P
+
+  N=M/P;
+  j=1;
+  for i=1:N:nin
+    rx_filter_memory(:,Nfilter-N+1:Nfilter) = rx_baseband(:,i:i-1+N);
+    rx_filt(:,j) = rx_filter_memory * gt_alpha5_root';
+    rx_filter_memory(:,1:Nfilter-N) = rx_filter_memory(:,1+N:Nfilter);
+    j+=1;
+  end
+
+  fdmdv.rx_filter_memory = rx_filter_memory;
+endfunction
+
+
+% LP filter +/- 1000 Hz, allows us to perfrom rx filtering at a lower rate saving CPU
+
+function [rx_fdm_filter fdmdv] = rxdec_filter(fdmdv, rx_fdm, nin)
+  M = fdmdv.M;
+  Nrxdec = fdmdv.Nrxdec;
+  rxdec_coeff = fdmdv.rxdec_coeff;
+  rxdec_lpf_mem = fdmdv.rxdec_lpf_mem;
+  rxdec_lpf_mem(1:Nrxdec-1+M-nin) = rxdec_lpf_mem(nin+1:Nrxdec-1+M);
+  rxdec_lpf_mem(Nrxdec-1+M-nin+1:Nrxdec-1+M) = rx_fdm(1:nin);
+
+  rx_fdm_filter = zeros(1,nin);
+  for i=1:nin
+    rx_fdm_filter(i) = rxdec_lpf_mem(i:Nrxdec-1+i) * rxdec_coeff';
+  end
+
+  fdmdv.rxdec_lpf_mem = rxdec_lpf_mem;
+end
+
+
+% Combined down convert and rx filter, more memory efficient but less intuitive design
+% TODO: Decimate mem update and downconversion, this will save some more CPU and memory
+%       note phase would have to advance 4 times as fast
+
+function [rx_filt fdmdv] = down_convert_and_rx_filter(fdmdv, rx_fdm, nin, dec_rate)
+  Nc = fdmdv.Nc;
+  M = fdmdv.M;
+  P = fdmdv.P;
+  rx_fdm_mem = fdmdv.rx_fdm_mem;
+  phase_rx = fdmdv.phase_rx;
+  freq = fdmdv.freq;
+  freq_pol = fdmdv.freq_pol;
+  Nfilter = fdmdv.Nfilter;
+  gt_alpha5_root = fdmdv.gt_alpha5_root;
+  Q = fdmdv.Q;
+
+  % update memory of rx_fdm
+
+  rx_fdm_mem(1:Nfilter+M-nin) = rx_fdm_mem(nin+1:Nfilter+M);
+  rx_fdm_mem(Nfilter+M-nin+1:Nfilter+M) = rx_fdm(1:nin);
+
+  for c=1:Nc+1
+
+     % now downconvert using current freq offset to get Nfilter+nin
+     % baseband samples.
+     % 
+     %           Nfilter              nin
+     % |--------------------------|---------|
+     %                             |
+     %                         phase_rx(c)
+     %
+     % This means winding phase(c) back from this point
+     % to ensure phase continuity
+
+     wind_back_phase = -freq_pol(c)*Nfilter;
+     phase_rx(c)     =  phase_rx(c)*exp(j*wind_back_phase);
+    
+     % down convert all samples in buffer
+
+     rx_baseband = zeros(1,Nfilter+M);
+     st  = Nfilter+M;      % end of buffer
+     st -= nin-1;          % first new sample
+     st -= Nfilter;        % first sample used in filtering
+     
+     f_rect = freq(c) .^ dec_rate;
+
+     for i=st:dec_rate:Nfilter+M
+        phase_rx(c) = phase_rx(c) * f_rect;
+       rx_baseband(i) = rx_fdm_mem(i)*phase_rx(c)';
+     end
+     % now we can filter this carrier's P symbols.  Due to filtering of rx_fdm we can filter at rate at rate M/Q
+
+     N=M/P; k = 1;
+     for i=1:N:nin
+       rx_filt(c,k) = (M/Q)*rx_baseband(st+i-1:dec_rate:st+i-1+Nfilter-1) * gt_alpha5_root(1:dec_rate:length(gt_alpha5_root))';
+       k+=1;
+     end
+  end
+
+  fdmdv.phase_rx   = phase_rx;
+  fdmdv.rx_fdm_mem = rx_fdm_mem;
+endfunction
+
+
+% LPF and peak pick part of freq est, put in a function as we call it twice
+
+function [foff imax pilot_lpf_out S] = lpf_peak_pick(f, pilot_baseband, pilot_lpf, nin, do_fft)
+  M = f.M;
+  Npilotlpf = f.Npilotlpf;
+  Npilotbaseband = f.Npilotbaseband;
+  Npilotcoeff = f.Npilotcoeff;
+  Fs = f.Fs;
+  Mpilotfft = f.Mpilotfft;
+  pilot_coeff = f.pilot_coeff;
+
+  % LPF cutoff 200Hz, so we can handle max +/- 200 Hz freq offset
+
+  pilot_lpf(1:Npilotlpf-nin) = pilot_lpf(nin+1:Npilotlpf);
+  k = Npilotbaseband-nin+1;;
+  for i = Npilotlpf-nin+1:Npilotlpf
+    pilot_lpf(i) = pilot_baseband(k-Npilotcoeff+1:k) * pilot_coeff';
+    k++;
+  end
+  
+  imax = 0;
+  foff = 0;
+  S = zeros(1, Mpilotfft);
+
+  if do_fft
+    % decimate to improve DFT resolution, window and DFT
+
+    Mpilot = Fs/(2*200);  % calc decimation rate given new sample rate is twice LPF freq
+    h = hanning(Npilotlpf);
+    s = pilot_lpf(1:Mpilot:Npilotlpf) .* h(1:Mpilot:Npilotlpf)';
+    s = [s zeros(1,Mpilotfft-Npilotlpf/Mpilot)];
+    S = fft(s, Mpilotfft);
+
+    % peak pick and convert to Hz
+
+    [imax ix] = max(abs(S));
+    r = 2*200/Mpilotfft;     % maps FFT bin to frequency in Hz
+  
+    if ix > Mpilotfft/2
+      foff = (ix - Mpilotfft - 1)*r;
+    else
+      foff = (ix - 1)*r;
+    endif
+  end
+
+  pilot_lpf_out = pilot_lpf;
+
+endfunction
+
+
+% Estimate frequency offset of FDM signal using BPSK pilot.  This is quite
+% sensitive to pilot tone level wrt other carriers
+
+function [foff S1 S2 f] = rx_est_freq_offset(f, rx_fdm, pilot, pilot_prev, nin, do_fft)
+  M = f.M;
+  Npilotbaseband = f.Npilotbaseband;
+  pilot_baseband1 = f.pilot_baseband1;
+  pilot_baseband2 = f.pilot_baseband2;
+  pilot_lpf1 = f.pilot_lpf1;
+  pilot_lpf2 = f.pilot_lpf2;
+
+  % down convert latest nin samples of pilot by multiplying by ideal
+  % BPSK pilot signal we have generated locally.  The peak of the DFT
+  % of the resulting signal is sensitive to the time shift between the
+  % received and local version of the pilot, so we do it twice at
+  % different time shifts and choose the maximum.
+  pilot_baseband1(1:Npilotbaseband-nin) = pilot_baseband1(nin+1:Npilotbaseband);
+  pilot_baseband2(1:Npilotbaseband-nin) = pilot_baseband2(nin+1:Npilotbaseband);
+  for i=1:nin
+    pilot_baseband1(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot(i)); 
+    pilot_baseband2(Npilotbaseband-nin+i) = rx_fdm(i) * conj(pilot_prev(i)); 
+  end
+
+  [foff1 max1 pilot_lpf1 S1] = lpf_peak_pick(f, pilot_baseband1, pilot_lpf1, nin, do_fft);
+  [foff2 max2 pilot_lpf2 S2] = lpf_peak_pick(f, pilot_baseband2, pilot_lpf2, nin, do_fft);
+
+  if max1 > max2
+    foff = foff1;
+  else
+    foff = foff2;
+  end  
+
+  f.pilot_baseband1 = pilot_baseband1;
+  f.pilot_baseband2 = pilot_baseband2;
+  f.pilot_lpf1 = pilot_lpf1;
+  f.pilot_lpf2 = pilot_lpf2;
+endfunction
+
+
+% Estimate optimum timing offset, re-filter receive symbols
+
+function [rx_symbols rx_timing_M env fdmdv] = rx_est_timing(fdmdv, rx_filt, nin)
+  M = fdmdv.M;
+  Nt = fdmdv.Nt;
+  Nc = fdmdv.Nc;
+  rx_filter_mem_timing = fdmdv.rx_filter_mem_timing;
+  P = fdmdv.P;
+  Nfilter = fdmdv.Nfilter;
+  Nfiltertiming = fdmdv.Nfiltertiming;
+
+  % nin  adjust 
+  % --------------------------------
+  % 120  -1 (one less rate P sample)
+  % 160   0 (nominal)
+  % 200   1 (one more rate P sample)
+
+  adjust = P - nin*P/M;
+
+  % update buffer of Nt rate P filtered symbols
+
+  rx_filter_mem_timing(:,1:(Nt-1)*P+adjust) = rx_filter_mem_timing(:,P+1-adjust:Nt*P);
+  rx_filter_mem_timing(:,(Nt-1)*P+1+adjust:Nt*P) = rx_filt(:,:);
+
+  % sum envelopes of all carriers
+
+  env = sum(abs(rx_filter_mem_timing(:,:))); % use all Nc+1 carriers for timing
+  %env = abs(rx_filter_mem_timing(Nc+1,:));  % just use BPSK pilot
+  [n m] = size(env);
+
+  % The envelope has a frequency component at the symbol rate.  The
+  % phase of this frequency component indicates the timing.  So work out
+  % single DFT at frequency 2*pi/P
+
+  x = env * exp(-j*2*pi*(0:m-1)/P)';
+  
+  norm_rx_timing = angle(x)/(2*pi);
+  rx_timing = norm_rx_timing*P + P/4;
+  if (rx_timing > P)
+     rx_timing -= P;
+  end
+  if (rx_timing < -P)
+     rx_timing += P;
+  end
+
+  % rx_filter_mem_timing contains Nt*P samples (Nt symbols at rate P),
+  % where Nt is odd.  Lets use linear interpolation to resample in the
+  % centre of the timing estimation window
+
+  rx_timing += floor(Nt/2)*P;
+  low_sample = floor(rx_timing);
+  fract = rx_timing - low_sample;
+  high_sample = ceil(rx_timing);
+  %printf("rx_timing: %f low_sample: %f high_sample: %f fract: %f\n", rx_timing, low_sample, high_sample, fract);
+  
+  rx_symbols = rx_filter_mem_timing(:,low_sample)*(1-fract) + rx_filter_mem_timing(:,high_sample)*fract;
+  % rx_symbols = rx_filter_mem_timing(:,high_sample+1);
+
+  rx_timing_M = norm_rx_timing*M;
+
+  fdmdv.rx_filter_mem_timing = rx_filter_mem_timing;
+endfunction
+
+
+% Experimental "feed forward" phase estimation function - estimates
+% phase over a windows of Nph (e.g. Nph = 9) symbols.  May not work
+% well on HF channels but lets see.  Has a phase ambiguity of m(pi/4)
+% where m=0,1,2 which needs to be corrected outside of this function
+
+function [phase_offsets ferr f] = rx_est_phase(f, rx_symbols)
+  global rx_symbols_mem;
+  global prev_phase_offsets;
+  global phase_amb;
+  Nph = f.Nph;
+  Nc = f.Nc;
+
+  % keep record of Nph symbols
+
+  rx_symbols_mem(:,1:Nph-1) = rx_symbols_mem(:,2:Nph);
+  rx_symbols_mem(:,Nph) = rx_symbols;
+  % estimate and correct phase offset based of modulation stripped samples
+
+  phase_offsets = zeros(Nc+1,1);
+  for c=1:Nc+1
+
+    % rotate QPSK constellation to a single point
+    mod_stripped = abs(rx_symbols_mem(c,:)) .* exp(j*4*angle(rx_symbols_mem(c,:)));
+    
+    % find average phase offset, which will be on -pi/4 .. pi/4
+    sum_real = sum(real(mod_stripped));
+    sum_imag = sum(imag(mod_stripped));
+    phase_offsets(c) = atan2(sum_imag, sum_real)/4;
+
+    % determine if phase has jumped from - -> +    
+    if (prev_phase_offsets(c) < -pi/8) && (phase_offsets(c) > pi/8)
+      phase_amb(c) -= pi/2;
+      if (phase_amb(c) < -pi)
+        phase_amb(c) += 2*pi;
+      end
+    end
+    
+    % determine if phase has jumped from + -> -    
+    if (prev_phase_offsets(c) > pi/8) && (phase_offsets(c) < -pi/8)
+      phase_amb(c) += pi/2;
+      if (phase_amb(c) > pi)
+        phase_amb(c) -= 2*pi;
+      end
+    end
+  end
+
+  ferr = mean(phase_offsets - prev_phase_offsets);
+  prev_phase_offsets = phase_offsets;
+
+endfunction
+
+
+% convert symbols back to an array of bits
+
+function [rx_bits sync_bit f_err phase_difference] = psk_to_bits(f, prev_rx_symbols, rx_symbols, modulation)
+  Nc = f.Nc;
+  Nb = f.Nb;
+
+  m4_binary_to_gray = [
+    bin2dec("00") 
+    bin2dec("01")
+    bin2dec("11")
+    bin2dec("10")
+  ];
+
+  m8_binary_to_gray = [
+    bin2dec("000")
+    bin2dec("001")
+    bin2dec("011")
+    bin2dec("010")
+    bin2dec("110")
+    bin2dec("111")
+    bin2dec("101")
+    bin2dec("100")
+  ];
+
+  m = 2 .^ Nb;
+  assert((m == 4) || (m == 8));
+
+  phase_difference = zeros(Nc+1,1);
+  for c=1:Nc 
+     norm = 1/(1E-6+abs(prev_rx_symbols(c)));  
+     phase_difference(c) = rx_symbols(c) .* conj(prev_rx_symbols(c)) * norm;
+  end
+
+  for c=1:Nc
+    phase_difference(c) *= exp(j*pi/4);
+
+    if m == 4
+
+        % to get a good match between C and Octave during start up use same as C code
+
+        d = phase_difference(c);
+        if (real(d) >= 0) && (imag(d) >= 0)
+          msb = 0; lsb = 0;
+        end
+        if (real(d) < 0) && (imag(d) >= 0)
+          msb = 0; lsb = 1;
+        end
+        if (real(d) < 0) && (imag(d) < 0)
+          msb = 1; lsb = 1;
+        end
+        if (real(d) >= 0) && (imag(d) < 0)
+          msb = 1; lsb = 0;
+        end
+          
+        rx_bits(2*(c-1)+1) = msb;
+        rx_bits(2*c) = lsb;
+    else
+      % determine index of constellation point received 0,1,...,m-1
+
+      index = floor(angle(phase_difference(c))*m/(2*pi) + 0.5);
+
+      if index < 0
+        index += m;
+      end
+
+      % map to decimal version of bits encoded in symbol
+
+      if m == 4
+        bits_decimal = m4_binary_to_gray(index+1);
+      else
+        bits_decimal = m8_binary_to_gray(index+1);
+      end
+    
+      % convert back to an array of received bits
+
+      for i=1:Nb
+        if bitand(bits_decimal, 2.^(Nb-i))
+          rx_bits((c-1)*Nb+i) = 1;
+        else
+          rx_bits((c-1)*Nb+i) = 0;
+        end
+      end
+    end
+  end
+
+  assert(length(rx_bits) == Nc*Nb);
+
+  % Extract DBPSK encoded Sync bit
+
+  norm = 1/(1E-6+abs(prev_rx_symbols(Nc+1)));
+  phase_difference(Nc+1) = rx_symbols(Nc+1) * conj(prev_rx_symbols(Nc+1)) * norm;
+  if (real(phase_difference(Nc+1)) < 0)
+    sync_bit = 1;
+    f_err = imag(phase_difference(Nc+1))*norm;  % make f_err magnitude insensitive
+  else
+    sync_bit = 0;
+    f_err = -imag(phase_difference(Nc+1))*norm;
+  end
+
+  % extra pi/4 rotation as we need for snr_update and scatter diagram
+  
+  phase_difference(Nc+1) *= exp(j*pi/4);
+  
+endfunction
+
+
+% given phase differences update estimates of signal and noise levels
+
+function [sig_est noise_est] = snr_update(f, sig_est, noise_est, phase_difference)
+    snr_coeff = f.snr_coeff;
+    Nc = f.Nc;
+
+    % mag of each symbol is distance from origin, this gives us a
+    % vector of mags, one for each carrier.
+
+    s = abs(phase_difference);
+    
+    % signal mag estimate for each carrier is a smoothed version
+    % of instantaneous magntitude, this gives us a vector of smoothed
+    % mag estimates, one for each carrier.
+    
+    sig_est = snr_coeff*sig_est + (1 - snr_coeff)*s;
+
+    %printf("s: %f sig_est: %f snr_coeff: %f\n", s(1), sig_est(1), snr_coeff);
+
+    % noise mag estimate is distance of current symbol from average
+    % location of that symbol.  We reflect all symbols into the first
+    % quadrant for convenience.
+    
+    refl_symbols = abs(real(phase_difference)) + j*abs(imag(phase_difference));    
+    n = abs(exp(j*pi/4)*sig_est - refl_symbols);
+     
+    % noise mag estimate for each carrier is a smoothed version of
+    % instantaneous noise mag, this gives us a vector of smoothed
+    % noise power estimates, one for each carrier.
+
+    noise_est = snr_coeff*noise_est + (1 - snr_coeff)*n;
+
+endfunction
+
+
+% calculate current sig estimate for eeach carrier
+
+function snr_dB = calc_snr(f, sig_est, noise_est)
+  Rs = f.Rs;
+
+  % find total signal power by summing power in all carriers
+
+  S = sum(sig_est .^2);
+  SdB = 10*log10(S);
+
+  % Average noise mag across all carriers and square to get an average
+  % noise power.  This is an estimate of the noise power in Rs = 50Hz of
+  % BW (note for raised root cosine filters Rs is the noise BW of the
+  % filter)
+
+  N50 = mean(noise_est).^2;
+  N50dB = 10*log10(N50);
+
+  % Now multiply by (3000 Hz)/(50 Hz) to find the total noise power in
+  % 3000 Hz
+
+  N3000dB = N50dB + 10*log10(3000/Rs);
+
+  snr_dB = SdB - N3000dB;
+
+endfunction
+
+
+% sets up test bits system.  make sure rand('state', 1) has just beed called
+% so we generate the right test_bits pattern!
+
+function f = init_test_bits(f)
+  f.Ntest_bits  = f.Nc*f.Nb*4;                % length of test sequence
+  f.test_bits = rand(1,f.Ntest_bits) > 0.5;   % test pattern of bits
+  f.current_test_bit = 1;
+  f.rx_test_bits_mem = zeros(1,f.Ntest_bits);
+endfunction
+
+
+% returns nbits from a repeating sequence of random data
+
+function [bits f] = get_test_bits(f, nbits)
+
+  for i=1:nbits
+    bits(i) = f.test_bits(f.current_test_bit++);
+    
+    if (f.current_test_bit > f.Ntest_bits)
+      f.current_test_bit = 1;
+    endif
+  end
+endfunction
+
+
+% Accepts nbits from rx and attempts to sync with test_bits sequence.
+% if sync OK measures bit errors
+
+function [sync bit_errors error_pattern f] = put_test_bits(f, test_bits, rx_bits)
+  Ntest_bits = f.Ntest_bits;      
+  rx_test_bits_mem = f.rx_test_bits_mem;
+
+  % Append to our memory
+
+  [m n] = size(rx_bits);
+  f.rx_test_bits_mem(1:f.Ntest_bits-n) = freedv.rx_test_bits_mem(n+1:f.Ntest_bits);
+  f.rx_test_bits_mem(f.Ntest_bits-n+1:f.Ntest_bits) = rx_bits;
+
+  % see how many bit errors we get when checked against test sequence
+
+  error_pattern = xor(test_bits, f.rx_test_bits_mem);
+  bit_errors = sum(error_pattern);
+
+  % if less than a thresh we are aligned and in sync with test sequence
+
+  ber = bit_errors/f.Ntest_bits;
+  
+  sync = 0;
+  if (ber < 0.2)
+    sync = 1;
+  endif
+endfunction
+
+% Generate M samples of DBPSK pilot signal for Freq offset estimation
+
+function [pilot_fdm bit symbol filter_mem phase] = generate_pilot_fdm(f, bit, symbol, filter_mem, phase, freq)
+  M = f.M;
+  Nfilter = f.Nfilter;
+  gt_alpha5_root = f.gt_alpha5_root;
+
+  % +1 -1 +1 -1 DBPSK sync carrier, once filtered becomes two spectral
+  % lines at +/- Rs/2
+  if bit
+     symbol = -symbol;
+  else
+     symbol = symbol;
+  end
+  if bit 
+    bit = 0;
+  else
+    bit = 1;
+  end
+
+  % filter DPSK symbol to create M baseband samples
+
+  filter_mem(Nfilter) = (sqrt(2)/2)*symbol;
+  for i=1:M
+    tx_baseband(i) = M*filter_mem(M:M:Nfilter) * gt_alpha5_root(M-i+1:M:Nfilter)';
+  end
+  filter_mem(1:Nfilter-M) = filter_mem(M+1:Nfilter);
+  filter_mem(Nfilter-M+1:Nfilter) = zeros(1,M);
+
+  % upconvert
+
+  for i=1:M
+    phase = phase * freq;
+    pilot_fdm(i) = sqrt(2)*2*tx_baseband(i)*phase;
+  end
+
+endfunction
+
+
+% Generate a 4M sample vector of DBPSK pilot signal.  As the pilot signal
+% is periodic in 4M samples we can then use this vector as a look up table
+% for pilot signal generation in the demod.
+
+function pilot_lut = generate_pilot_lut(f)
+  Nc = f.Nc;
+  Nfilter = f.Nfilter;
+  M = f.M;
+  freq = f.freq;
+
+  % pilot states
+
+  pilot_rx_bit = 0;
+  pilot_symbol = sqrt(2);
+  pilot_freq = freq(Nc+1);
+  pilot_phase = 1;
+  pilot_filter_mem = zeros(1, Nfilter);
+  %prev_pilot = zeros(M,1);
+
+  pilot_lut = [];
+
+  F=8;
+
+  for fr=1:F
+    [pilot pilot_rx_bit pilot_symbol pilot_filter_mem pilot_phase] = generate_pilot_fdm(f, pilot_rx_bit, pilot_symbol, pilot_filter_mem, pilot_phase, pilot_freq);
+    %prev_pilot = pilot;
+    pilot_lut = [pilot_lut pilot];
+  end
+
+  % discard first 4 symbols as filter memory is filling, just keep last
+  % four symbols
+
+  pilot_lut = pilot_lut(4*M+1:M*F);
+
+endfunction
+
+
+% grab next pilot samples for freq offset estimation at demod
+
+function [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(f, pilot_lut_index, prev_pilot_lut_index, nin)
+  M = f.M;
+  pilot_lut = f.pilot_lut;
+
+  for i=1:nin
+    pilot(i) = pilot_lut(pilot_lut_index);
+    pilot_lut_index++;
+    if pilot_lut_index > 4*M
+      pilot_lut_index = 1;
+    end
+    prev_pilot(i) = pilot_lut(prev_pilot_lut_index);
+    prev_pilot_lut_index++;
+    if prev_pilot_lut_index > 4*M
+      prev_pilot_lut_index = 1;
+    end
+  end
+endfunction
+
+
+% freq offset state machine.  Moves between acquire and track states based
+% on BPSK pilot sequence.  Freq offset estimator occasionally makes mistakes
+% when used continuously.  So we use it until we have acquired the BPSK pilot,
+% then switch to a more robust tracking algorithm.  If we lose sync we switch
+% back to acquire mode for fast-requisition.
+
+function [sync reliable_sync_bit state timer sync_mem] = freq_state(f, sync_bit, state, timer, sync_mem)
+  Nsync_mem = f.Nsync_mem;
+  sync_uw = f.sync_uw;
+
+  % look for 6 symbol (120ms) 010101 of sync sequence
+
+  unique_word = 0;
+  for i=1:Nsync_mem-1
+    sync_mem(i) = sync_mem(i+1);
+  end
+  sync_mem(Nsync_mem) = 1 - 2*sync_bit;
+  corr = 0;
+  for i=1:Nsync_mem
+    corr += sync_mem(i)*sync_uw(i);
+  end
+  if abs(corr) == Nsync_mem
+    unique_word = 1;
+  end
+  reliable_sync_bit = (corr == Nsync_mem);
+  
+  % iterate state machine
+
+  next_state = state;
+  if state == 0
+    if unique_word
+      next_state = 1;
+      timer = 0;
+    end        
+  end
+  if state == 1
+    if unique_word
+      timer++;
+      if timer == 25       % sync has been good for 500ms
+        next_state = 2;
+      end
+    else 
+      next_state = 0;
+    end        
+  end
+  if state == 2            % good sync state
+    if unique_word == 0
+      timer = 0;
+      next_state = 3;
+    end
+  end
+  if state == 3            % tenative bad  state, but could be a fade
+    if unique_word
+      next_state = 2;
+    else 
+      timer++;
+      if timer == 50       % wait for 1000ms in case sync comes back  
+        next_state = 0;
+      end
+    end        
+  end
+
+  %printf("corr: % -d state: %d next_state: %d uw: %d timer: %d\n", corr, state, next_state, unique_word, timer);
+  state = next_state;
+
+  if state
+    sync = 1;
+  else
+    sync = 0;
+  end
+endfunction
+
+
+% complex freq shifting helper function
+
+function [out phase] = freq_shift(in, freqHz, Fs, phase)
+  freq_rect = exp(j*2*pi*freqHz/Fs);
+
+  out = zeros(1, length(in));
+  for r=1:length(in)
+    phase *= freq_rect;
+    out(r) = in(r)*phase;
+  end
+
+  mag = abs(phase);
+  phase /= mag;
+endfunction
+
+
+% Save test bits to a text file in the form of a C array
+
+function test_bits_file(filename)
+  global test_bits;
+  global Ntest_bits;
+
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by test_bits_file() Octave function */\n\n");
+  fprintf(f,"const int test_bits[]={\n");
+  for m=1:Ntest_bits-1
+    fprintf(f,"  %d,\n",test_bits(m));
+  endfor
+  fprintf(f,"  %d\n};\n",test_bits(Ntest_bits));
+  fclose(f);
+endfunction
+
+
+% Saves RN filter coeffs to a text file in the form of a C array
+
+function rn_file(gt_alpha5_root, filename)
+  Nfilter = length(gt_alpha5_root);
+
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by rn_file() Octave function */\n\n");
+  fprintf(f,"const float gt_alpha5_root[]={\n");
+  for m=1:Nfilter-1
+    fprintf(f,"  %g,\n",gt_alpha5_root(m));
+  endfor
+  fprintf(f,"  %g\n};\n",gt_alpha5_root(Nfilter));
+  fclose(f);
+endfunction
+
+
+% Saves rx decimation filter coeffs to a text file in the form of a C array
+
+function rxdec_file(fdmdv, filename)
+  rxdec_coeff = fdmdv.rxdec_coeff;
+  Nrxdec = fdmdv.Nrxdec;
+
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by rxdec_file() Octave function */\n\n");
+  fprintf(f,"const float rxdec_coeff[]={\n");
+  for m=1:Nrxdec-1
+    fprintf(f,"  %g,\n",rxdec_coeff(m));
+  endfor
+  fprintf(f,"  %g\n};\n",rxdec_coeff(Nrxdec));
+  fclose(f);
+endfunction
+
+
+function pilot_coeff_file(fdmdv, filename)
+  pilot_coeff = fdmdv.pilot_coeff;
+  Npilotcoeff = fdmdv.Npilotcoeff;
+
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by pilot_coeff_file() Octave function */\n\n");
+  fprintf(f,"const float pilot_coeff[]={\n");
+  for m=1:Npilotcoeff-1
+    fprintf(f,"  %g,\n",pilot_coeff(m));
+  endfor
+  fprintf(f,"  %g\n};\n",pilot_coeff(Npilotcoeff));
+  fclose(f);
+endfunction
+
+
+% Saves hanning window coeffs to a text file in the form of a C array
+
+function hanning_file(fdmdv, filename)
+  Npilotlpf = fdmdv.Npilotlpf;
+
+  h = hanning(Npilotlpf);
+
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by hanning_file() Octave function */\n\n");
+  fprintf(f,"const float hanning[]={\n");
+  for m=1:Npilotlpf-1
+    fprintf(f,"  %g,\n", h(m));
+  endfor
+  fprintf(f,"  %g\n};\n", h(Npilotlpf));
+  fclose(f);
+endfunction
+
+
+function png_file(fig, pngfilename)
+  figure(fig);
+
+  pngname = sprintf("%s.png",pngfilename);
+  print(pngname, '-dpng', "-S500,500")
+  pngname = sprintf("%s_large.png",pngfilename);
+  print(pngname, '-dpng', "-S800,600")
+endfunction
+
+
+% dump rx_bits in hex
+
+function dump_bits(rx_bits)
+
+    % pack into bytes, MSB first
+
+    packed = zeros(1,floor(length(rx_bits)+7)/8);
+    bit = 7; byte = 1;
+    for i=1:length(rx_bits)
+        packed(byte) = bitor(packed(byte), bitshift(rx_bits(i),bit));
+        bit--;
+        if (bit < 0)
+            bit = 7;
+            byte++;
+        end 
+    end
+
+    for i=1:length(packed)
+        printf("0x%02x ", packed(i)); 
+    end
+    printf("\n");
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/fdmdv_demod.m b/codec2/branches/0.7/octave/fdmdv_demod.m
new file mode 100644 (file)
index 0000000..6b5c0a2
--- /dev/null
@@ -0,0 +1,353 @@
+% fdmdv_demod.m
+%
+% Demodulator function for FDMDV modem (Octave version).  Requires
+% 8kHz sample rate raw files as input
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+function fdmdv_demod(rawfilename, nbits, NumCarriers, errorpatternfilename, symbolfilename)
+
+  fdmdv; % include modem code
+  
+  modulation = 'dqpsk';
+
+  fin = fopen(rawfilename, "rb");
+  gain = 1000;
+  frames = nbits/(Nc*Nb);
+
+  prev_rx_symbols = ones(Nc+1,1);
+  foff_phase_rect = 1;
+
+  % BER stats
+
+  total_bit_errors = 0;
+  total_bits = 0;
+  bit_errors_log = [];
+  sync_log = [];
+  test_frame_sync_log = [];
+  test_frame_sync_state = 0;
+  error_pattern_log = [];
+
+  % SNR states
+
+  sig_est = zeros(Nc+1,1);
+  noise_est = zeros(Nc+1,1);
+
+  % logs of various states for plotting
+
+  rx_symbols_log = [];
+  rx_timing_log = [];
+  foff_coarse_log = [];
+  foff_log = [];
+  rx_fdm_log = [];
+  snr_est_log = [];
+
+  % misc states
+
+  nin = M;                 % timing correction for sample rate differences
+  foff = 0;
+
+  fest_state = 0;
+  fest_timer = 0;
+  sync_mem = zeros(1,Nsync_mem);
+  sync = 0;
+  sync_log = [];
+
+  % spectrum states
+
+  Nspec=1024;
+  spec_mem=zeros(1,Nspec);
+  SdB = zeros(1,Nspec);
+
+  % optionally save output symbols 
+
+  if nargin == 5
+    fm = fopen(symbolfilename,"wb");
+    dual_rx_symbols = zeros(1, 2*Nc);
+    dual_rx_bits = zeros(1,2*Nc*Nb);
+  end
+
+  % Main loop ----------------------------------------------------
+
+  for f=1:frames
+    
+    % obtain nin samples of the test input signal
+    
+    for i=1:nin
+      rx_fdm(i) = fread(fin, 1, "short")/gain;
+    end
+    
+    rx_fdm_log = [rx_fdm_log rx_fdm(1:nin)];
+
+    % update spectrum
+
+    l=length(rx_fdm);
+    spec_mem(1:Nspec-l) = spec_mem(l+1:Nspec);
+    spec_mem(Nspec-l+1:Nspec) = rx_fdm;
+    S=fft(spec_mem.*hanning(Nspec)',Nspec);
+    SdB = 0.9*SdB + 0.1*20*log10(abs(S));
+
+    % shift down to complex baseband
+
+    for i=1:nin
+      fbb_phase_rx = fbb_phase_rx*fbb_rect';
+      rx_fdm(i) = rx_fdm(i)*fbb_phase_rx;
+    end
+    mag = abs(fbb_phase_rx);
+    fbb_phase_rx /= mag;
+
+    % frequency offset estimation and correction
+
+    [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
+    [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin, !sync );
+    
+    if sync == 0
+      foff  = foff_coarse;
+    end
+    foff_coarse_log = [foff_coarse_log foff_coarse];
+
+    foff_rect = exp(j*2*pi*foff/Fs);
+
+    for i=1:nin
+      foff_phase_rect *= foff_rect';
+      rx_fdm_fcorr(i) = rx_fdm(i)*foff_phase_rect;
+    end
+
+    % baseband processing
+
+    rx_fdm_filter = rxdec_filter(rx_fdm_fcorr, nin);
+    rx_filt = down_convert_and_rx_filter(rx_fdm_filter, nin, M/Q);
+    [rx_symbols rx_timing] = rx_est_timing(rx_filt, nin);
+    rx_timing_log = [rx_timing_log rx_timing];
+
+    nin = M;
+    if rx_timing > 2*M/P
+       nin += M/P;
+    end
+    if rx_timing < 0;
+       nin -= M/P;
+    end
+
+    rx_symbols_log = [rx_symbols_log rx_symbols.*conj(prev_rx_symbols./abs(prev_rx_symbols))*exp(j*pi/4)];
+    [rx_bits sync_bit f_err pd] = psk_to_bits(prev_rx_symbols, rx_symbols, modulation);
+
+    % optionally save output symbols 
+
+    if (nargin == 5)
+
+      % this free runs, and is reset by an "entered sync" state
+
+      if (sync_track == 0)
+         sync_track = 1;
+      else
+         sync_track = 0; 
+      end
+      
+      if (track == 1) && (sync_track == 1)
+          dual_rx_symbols(Nc+1:2*Nc) = rx_symbols(1:Nc).*conj(prev_rx_symbols(1:Nc)./abs(prev_rx_symbols(1:Nc)));
+          dual_rx_symbols_float32 = []; k = 1;
+          for i=1:2*Nc
+              dual_rx_symbols_float32(k++) = real(dual_rx_symbols(i));
+              dual_rx_symbols_float32(k++) = imag(dual_rx_symbols(i));
+          end
+          fwrite(fm, dual_rx_symbols_float32, "float32");
+          dual_rx_bits(Nc*Nb+1:2*Nc*Nb) = rx_bits;
+          %dump_bits(dual_rx_bits);
+      else
+          dual_rx_symbols(1:Nc) = rx_symbols(1:Nc).*conj(prev_rx_symbols(1:Nc)./abs(prev_rx_symbols(1:Nc)));
+          dual_rx_bits(1:Nc*Nb) = rx_bits;
+      end
+    end
+
+    % update some states
+
+    prev_rx_symbols = rx_symbols;
+    [sig_est noise_est] = snr_update(sig_est, noise_est, pd);
+    snr_est = calc_snr(sig_est, noise_est);
+    snr_est_log = [snr_est_log snr_est];
+    foff -= 0.5*f_err;
+    foff_log = [foff_log foff];
+
+    % freq est state machine
+
+    [sync reliable_sync_bit fest_state fest_timer sync_mem] = freq_state(sync_bit, fest_state, fest_timer, sync_mem);
+    sync_log = [sync_log sync];
+
+    % count bit errors if we find a test frame
+
+    [test_frame_sync bit_errors error_pattern] = put_test_bits(test_bits, rx_bits);
+    if (test_frame_sync == 1)
+      total_bit_errors = total_bit_errors + bit_errors;
+      total_bits = total_bits + Ntest_bits;
+      bit_errors_log = [bit_errors_log bit_errors/Ntest_bits];
+    else
+      bit_errors_log = [bit_errors_log 0];
+    end
+
+    % test frame sync state machine, just for more informative plots
+    
+    next_test_frame_sync_state = test_frame_sync_state;
+    if (test_frame_sync_state == 0)
+      if (test_frame_sync == 1)      
+        next_test_frame_sync_state = 1;
+       test_frame_count = 0;
+      end
+    end
+
+    if (test_frame_sync_state == 1)
+      % we only expect another test_frame_sync pulse every 4 symbols
+      test_frame_count++;
+      if (test_frame_count == 4)
+        test_frame_count = 0;
+        if ((test_frame_sync == 0))      
+          next_test_frame_sync_state = 0;
+        else
+          error_pattern_log = [error_pattern_log error_pattern];
+        end
+      end
+    end
+
+    test_frame_sync_state = next_test_frame_sync_state;
+    test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
+  end
+  if nargin == 5
+    fclose(fm);
+    etfilename = strcat(strtok(symbolfilename,"."),"_et.bin");
+    fet = fopen(etfilename, "wb");
+    fwrite(fet, entered_track_log, "short");
+    fclose(fet);
+  end
+
+  % ---------------------------------------------------------------------
+  % Print Stats
+  % ---------------------------------------------------------------------
+
+  % Peak to Average Power Ratio calcs from http://www.dsplog.com
+
+  papr = max(rx_fdm_log.*conj(rx_fdm_log)) / mean(rx_fdm_log.*conj(rx_fdm_log));
+  papr_dB = 10*log10(papr);
+
+  ber = total_bit_errors / total_bits;
+  printf("%d bits  %d errors  BER: %1.4f PAPR(rx): %1.2f dB\n",total_bits, total_bit_errors, ber, papr_dB);
+
+  % ---------------------------------------------------------------------
+  % Plots
+  % ---------------------------------------------------------------------
+
+  xt = (1:frames)/Rs;
+  secs = frames/Rs;
+
+  figure(1)
+  clf;
+  [n m] = size(rx_symbols_log);
+  plot(real(rx_symbols_log(1:Nc+1,15:m)),imag(rx_symbols_log(1:Nc+1,15:m)),'+')
+  axis([-2 2 -2 2]);
+  title('Scatter Diagram');
+
+  figure(2)
+  clf;
+  subplot(211)
+  plot(xt, rx_timing_log)
+  title('timing offset (samples)');
+  subplot(212)
+  plot(xt, foff_log, '-;freq offset;')
+  hold on;
+  plot(xt, sync_log*75, 'r;course-fine;');
+  hold off;
+  title('Freq offset (Hz)');
+  grid
+
+  figure(3)
+  clf;
+  spec(rx_fdm_log,8000);
+
+  figure(4)
+  clf;
+  subplot(311)
+  stem(xt, sync_log)
+  axis([0 secs 0 1.5]);
+  title('BPSK Sync')
+  subplot(312)
+  stem(xt, bit_errors_log);
+  title('Bit Errors for test frames')
+  subplot(313)
+  plot(xt, test_frame_sync_log);
+  axis([0 secs 0 1.5]);
+  title('Test Frame Sync')
+
+  figure(5)
+  clf;
+  subplot(211);
+  plot(xt, snr_est_log);
+  title('SNR Estimates')
+  subplot(212)
+  snrdB_pc = 20*log10(sig_est(1:Nc+1)) - 20*log10(noise_est(1:Nc+1));
+  bar(snrdB_pc(1:Nc) - mean(snrdB_pc(1:Nc)))
+  axis([0 Nc+1 -3 3]);
+
+  figure(6)
+  clf;
+  hold on;
+  lep = length(error_pattern_log);
+  if lep != 0 
+    for p=1:Nc
+      plot(p + 0.25*error_pattern_log((p-1)*2+1:Nc*Nb:lep));
+      plot(0.30 + p + 0.25*error_pattern_log(p*2:Nc*Nb:lep),'r')
+    end
+    hold off;
+    axis([1 lep/(Nc*Nb) 0 Nc])
+  end
+
+  figure(7)
+  clf;
+  subplot(211)
+  [a b] = size(rx_fdm_log);
+  xt1 = (1:b)/Fs;
+  plot(xt1, rx_fdm_log);
+  title('Rx FDM Signal');
+  subplot(212)
+  plot((0:Nspec/2-1)*Fs/Nspec, SdB(1:Nspec/2) - 20*log10(Nspec/2))
+  axis([0 Fs/2 -40 0])
+  grid
+  title('FDM Rx Spectrum');
+
+if 0
+  % interleaving tests
+
+  load ../unittest/inter560.txt
+  lep = length(error_pattern_log);
+  lep = floor(lep/560)*560;
+  error_pattern_log_inter = zeros(1,lep);
+  for i=1:560:lep
+    for j=1:560
+      %printf("i: %4d j: %4d inter560(j): %4d\n", i,j,inter560(j));
+      index = inter560(j);
+      error_pattern_log_inter(i-1+index+1) = error_pattern_log(i-1+j);
+    end
+  end
+
+  figure(8)
+  clf;
+  hold on;
+  for p=1:Nc
+    plot(p + 0.25*error_pattern_log_inter((p-1)*2+1:Nc*Nb:lep));
+    plot(0.30 + p + 0.25*error_pattern_log_inter(p*2:Nc*Nb:lep),'r')
+  end
+  hold off;
+  axis([1 lep/(Nc*Nb) 0 Nc])
+end
+
+  % optionally save error pattern file
+
+  if nargin == 4
+    fout = fopen(errorpatternfilename, "wb");
+    fwrite(fout, error_pattern_log, "short");
+    fclose(fout);
+  end
+
+
+endfunction
diff --git a/codec2/branches/0.7/octave/fdmdv_demod_c.m b/codec2/branches/0.7/octave/fdmdv_demod_c.m
new file mode 100644 (file)
index 0000000..b5c7533
--- /dev/null
@@ -0,0 +1,132 @@
+% fdmdv_demod_c.m
+%
+% Plots Octave dump file information from C FDMDV demodulator program,
+% to give a similar set of plots to fdmdv_demod.m.  Useful for off
+% line analysis of demod performance.
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+function fdmdv_demod_c(dumpfilename, bits, NumCarriers)
+  fdmdv; % include modem code
+
+  frames = bits/(Nc*Nb);
+
+  load(dumpfilename);
+
+  % BER stats
+
+  total_bit_errors = 0;
+  total_bits = 0;
+  bit_errors_log = [];
+  sync_log = [];
+  test_frame_sync_log = [];
+  test_frame_sync_state = 0;
+
+  % Run thru received bits to look for test pattern
+
+  bits_per_frame = Nc*Nb;
+
+  for f=1:frames
+
+    rx_bits = rx_bits_log_c((f-1)*bits_per_frame+1:f*bits_per_frame);
+
+    % count bit errors if we find a test frame
+
+    [test_frame_sync bit_errors] = put_test_bits(test_bits, rx_bits);
+    if (test_frame_sync == 1)
+      total_bit_errors = total_bit_errors + bit_errors;
+      total_bits = total_bits + Ntest_bits;
+      bit_errors_log = [bit_errors_log bit_errors/Ntest_bits];
+    else
+      bit_errors_log = [bit_errors_log 0];
+    end
+
+    % test frame sync state machine, just for more informative plots
+    
+    next_test_frame_sync_state = test_frame_sync_state;
+    if (test_frame_sync_state == 0)
+      if (test_frame_sync == 1)      
+        next_test_frame_sync_state = 1;
+       test_frame_count = 0;
+      end
+    end
+
+    if (test_frame_sync_state == 1)
+      % we only expect another test_frame_sync pulse every 4 symbols
+      test_frame_count++;
+      if (test_frame_count == 4)
+        test_frame_count = 0;
+        if ((test_frame_sync == 0))      
+          next_test_frame_sync_state = 0;
+        end
+      end
+    end
+    test_frame_sync_state = next_test_frame_sync_state;
+    test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
+  end
+
+  ber = total_bit_errors / total_bits;
+  printf("%d bits  %d errors  BER: %1.4f\n",total_bits, total_bit_errors, ber);
+
+  % ---------------------------------------------------------------------
+  % Plots
+  % ---------------------------------------------------------------------
+
+  xt = (1:frames)/Rs;
+  secs = frames/Rs;
+
+  figure(1)
+  clf;
+  plot(real(rx_symbols_log_c(1:Nc+1,15:frames)),imag(rx_symbols_log_c(1:Nc+1,15:frames)),'+')
+  %plot(real(rx_symbols_log_c(Nc+1,15:frames)),imag(rx_symbols_log_c(Nc+1,15:frames)),'+')
+  axis([-2 2 -2 2]);
+  title('Scatter Diagram');
+
+  figure(2)
+  clf;
+  subplot(211)
+  plot(xt, rx_timing_log_c(1:frames))
+  title('timing offset (samples)');
+  subplot(212)
+  plot(xt, foff_log_c(1:frames), '-;freq offset;')
+  hold on;
+  plot(xt, sync_log_c(1:frames)*75, 'r;course-fine;');
+  hold off;
+  title('Freq offset (Hz)');
+  grid
+
+  figure(3)
+  clf;
+  subplot(211)
+  b = M*frames;
+  xt1 = (1:b)/Fs;
+  plot(xt1, rx_fdm_log_c(1:b));
+  title('Rx FDM Signal');
+  subplot(212)
+  spec(rx_fdm_log_c(1:b),8000);
+  title('FDM Rx Spectrogram');
+
+  figure(4)
+  clf;
+  subplot(311)
+  stem(xt, sync_bit_log_c(1:frames))
+  axis([0 secs 0 1.5]);
+  title('BPSK Sync')
+  subplot(312)
+  stem(xt, bit_errors_log);
+  title('Bit Errors for test frames')
+  subplot(313)
+  plot(xt, test_frame_sync_log);
+  axis([0 secs 0 1.5]);
+  title('Test Frame Sync')
+
+  figure(5)
+  clf;
+  plot(xt, snr_est_log_c(1:frames));
+  title('SNR Estimates')
+
+endfunction
diff --git a/codec2/branches/0.7/octave/fdmdv_demod_coh.m b/codec2/branches/0.7/octave/fdmdv_demod_coh.m
new file mode 100644 (file)
index 0000000..94b0880
--- /dev/null
@@ -0,0 +1,253 @@
+% fdmdv_demod_coh.m
+%
+% Demodulator function for FDMDV modem (Octave version).  Requires
+% 8kHz sample rate raw files as input.  This version uses experimental
+% psuedo coherent demodulation.
+%
+% Copyright David Rowe 2013
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+function fdmdv_demod_coh(rawfilename, nbits, pngname)
+
+  fdmdv; % include modem code
+
+  modulation = 'dqpsk';
+
+  fin = fopen(rawfilename, "rb");
+  gain = 1000;
+  frames = nbits/(Nc*Nb);
+
+  prev_rx_symbols = ones(Nc+1,1);
+  foff_phase = 1;
+
+  % BER stats
+
+  total_bit_errors = 0;
+  total_bits = 0;
+  bit_errors_log = [];
+  sync_log = [];
+  test_frame_sync_log = [];
+  test_frame_sync_state = 0;
+
+  % SNR states
+
+  sig_est = zeros(Nc+1,1);
+  noise_est = zeros(Nc+1,1);
+
+  % logs of various states for plotting
+
+  rx_symbols_log = [];
+  rx_timing_log = [];
+  foff_log = [];
+  rx_fdm_log = [];
+  snr_est_log = [];
+
+  % misc states
+
+  nin = M; % timing correction for sample rate differences
+  foff = 0;
+  track_log = [];
+  track = 0;
+  fest_state = 0;
+
+  % psuedo coherent demod states
+
+  rx_symbols_ph_log = [];
+  prev_rx_symbols_ph = ones(Nc+1,1);
+  rx_phase_offsets_log = [];
+  phase_amb_log = [];
+
+  % Main loop ----------------------------------------------------
+
+  for f=1:frames
+    
+    % obtain nin samples of the test input signal
+    
+    for i=1:nin
+      rx_fdm(i) = fread(fin, 1, "short")/gain;
+    end
+    
+    rx_fdm_log = [rx_fdm_log rx_fdm(1:nin)];
+
+    % frequency offset estimation and correction
+
+    [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, nin);
+    [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, nin);
+    
+    if track == 0
+      foff  = foff_coarse;
+    end
+    foff_log = [ foff_log foff ];
+    foff_rect = exp(j*2*pi*foff/Fs);
+
+    for i=1:nin
+      foff_phase *= foff_rect';
+      rx_fdm(i) = rx_fdm(i)*foff_phase;
+    end
+
+    % baseband processing
+
+    rx_baseband = fdm_downconvert(rx_fdm, nin);
+    rx_filt = rx_filter(rx_baseband, nin);
+
+    [rx_symbols rx_timing] = rx_est_timing(rx_filt, rx_baseband, nin);    
+    rx_timing_log = [rx_timing_log rx_timing];
+
+    nin = M;
+    if rx_timing > 2*M/P
+       nin += M/P;
+    end
+    if rx_timing < 0;
+       nin -= M/P;
+    end
+
+    rx_symbols_log = [rx_symbols_log rx_symbols.*(conj(prev_rx_symbols)./abs(prev_rx_symbols))*exp(j*pi/4)];
+
+    % coherent phase offset estimation ------------------------------------
+
+    [rx_phase_offsets ferr] = rx_est_phase(rx_symbols);
+    rx_phase_offsets_log = [rx_phase_offsets_log rx_phase_offsets];
+    phase_amb_log = [phase_amb_log phase_amb];
+    rx_symbols_ph = rx_symbols_mem(:,floor(Nph/2)+1) .* exp(-j*(rx_phase_offsets + phase_amb));
+    rx_symbols_ph_log = [rx_symbols_ph_log rx_symbols_ph .* exp(j*pi/4)];
+    rx_symbols_ph = -1 + 2*(real(rx_symbols_ph .* exp(j*pi/4)) > 0) + j*(-1 + 2*(imag(rx_symbols_ph .* exp(j*pi/4)) > 0));
+
+    % Std differential (used for freq offset est and BPSK sync) and psuedo coherent detection -----------------------
+
+    [rx_bits_unused sync        f_err       pd       ] = qpsk_to_bits(prev_rx_symbols, rx_symbols, modulation);
+    [rx_bits        sync_unused ferr_unused pd_unused] = qpsk_to_bits(prev_rx_symbols_ph, rx_symbols_ph, 'dqpsk');
+    foff -= 0.5*f_err;
+    prev_rx_symbols = rx_symbols;
+    prev_rx_symbols_ph = rx_symbols_ph;
+    sync_log = [sync_log sync];
+
+    [sig_est noise_est] = snr_update(sig_est, noise_est, pd);
+    snr_est = calc_snr(sig_est, noise_est);
+    snr_est_log = [snr_est_log snr_est];
+
+    % freq est state machine
+
+    [track fest_state] = freq_state(sync, fest_state);
+    track_log = [track_log track];
+
+    % count bit errors if we find a test frame
+
+    [test_frame_sync bit_errors] = put_test_bits(test_bits, rx_bits);
+    if (test_frame_sync == 1)
+      total_bit_errors = total_bit_errors + bit_errors;
+      total_bits = total_bits + Ntest_bits;
+      bit_errors_log = [bit_errors_log bit_errors/Ntest_bits];
+    else
+      bit_errors_log = [bit_errors_log 0];
+    end
+
+    % test frame sync state machine, just for more informative plots
+    
+    next_test_frame_sync_state = test_frame_sync_state;
+    if (test_frame_sync_state == 0)
+      if (test_frame_sync == 1)      
+        next_test_frame_sync_state = 1;
+       test_frame_count = 0;
+      end
+    end
+
+    if (test_frame_sync_state == 1)
+      % we only expect another test_frame_sync pulse every 4 symbols
+      test_frame_count++;
+      if (test_frame_count == 4)
+        test_frame_count = 0;
+        if ((test_frame_sync == 0))      
+          next_test_frame_sync_state = 0;
+        end
+      end
+    end
+    test_frame_sync_state = next_test_frame_sync_state;
+    test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
+
+  end
+  
+  % ---------------------------------------------------------------------
+  % Print Stats
+  % ---------------------------------------------------------------------
+
+  ber = total_bit_errors / total_bits;
+
+  printf("%d bits  %d errors  BER: %1.4f\n",total_bits, total_bit_errors, ber);
+
+  % ---------------------------------------------------------------------
+  % Plots
+  % ---------------------------------------------------------------------
+
+  xt = (1:frames)/Rs;
+  secs = frames/Rs;
+
+  figure(1)
+  clf;
+  [n m] = size(rx_symbols_log);
+  plot(real(rx_symbols_log(1:Nc+1,15:m)),imag(rx_symbols_log(1:Nc+1,15:m)),'+')
+  axis([-2 2 -2 2]);
+  title('Scatter Diagram');
+
+  figure(2)
+  clf;
+  subplot(211)
+  plot(xt, rx_timing_log)
+  title('timing offset (samples)');
+  subplot(212)
+  plot(xt, foff_log, '-;freq offset;')
+  hold on;
+  plot(xt, track_log*75, 'r;course-fine;');
+  hold off;
+  title('Freq offset (Hz)');
+  grid
+
+  figure(3)
+  clf;
+  subplot(211)
+  [a b] = size(rx_fdm_log);
+  xt1 = (1:b)/Fs;
+  plot(xt1, rx_fdm_log);
+  title('Rx FDM Signal');
+  subplot(212)
+  spec(rx_fdm_log,8000);
+  title('FDM Rx Spectrogram');
+
+  figure(4)
+  clf;
+  subplot(311)
+  stem(xt, sync_log)
+  axis([0 secs 0 1.5]);
+  title('BPSK Sync')
+  subplot(312)
+  stem(xt, bit_errors_log);
+  title('Bit Errors for test frames')
+  subplot(313)
+  plot(xt, test_frame_sync_log);
+  axis([0 secs 0 1.5]);
+  title('Test Frame Sync')
+
+  figure(5)
+  clf;
+  plot(xt, snr_est_log);
+  title('SNR Estimates')
+  figure(6)
+  clf;
+  [n m] = size(rx_symbols_ph_log);
+  plot(real(rx_symbols_ph_log(1:Nc+1,15:m)),imag(rx_symbols_ph_log(1:Nc+1,15:m)),'+')
+  %plot(real(rx_symbols_ph_log(2,15:m)),imag(rx_symbols_ph_log(2,15:m)),'+')
+  axis([-2 2 -2 2]);
+  title('Scatter Diagram - after phase correction');
+
+  figure(7)
+  clf;
+  subplot(211)
+  plot(rx_phase_offsets_log(1,:))
+  subplot(212)
+  plot(phase_amb_log(1,:))
+  title('Rx Phase Offset Est')
+
+endfunction
diff --git a/codec2/branches/0.7/octave/fdmdv_mod.m b/codec2/branches/0.7/octave/fdmdv_mod.m
new file mode 100644 (file)
index 0000000..8d13226
--- /dev/null
@@ -0,0 +1,32 @@
+% fdmdv_mod.m
+%
+% Modulator function for FDMDV modem, uses test frames as input and
+% outputs a raw file of 16 bit shorts at a sample rate of 8 kHz.
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+function tx_fdm = fdmdv_mod(rawfilename, nbits)
+
+  fdmdv; % include modem code
+
+  frames = floor(nbits/(Nc*Nb))
+  tx_fdm = [];
+  gain = 1000; % Scale up to 16 bit shorts
+  prev_tx_symbols = ones(Nc+1,1); prev_tx_symbols(Nc+1) = 2;
+
+  for i=1:frames
+    tx_bits = get_test_bits(Nc*Nb);
+    tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits,'dqpsk');
+    prev_tx_symbols = tx_symbols;
+    tx_baseband = tx_filter(tx_symbols);
+    tx_fdm = [tx_fdm real(fdm_upconvert(tx_baseband))];
+  end
+
+  tx_fdm *= gain;
+  fout = fopen(rawfilename,"wb");
+  fwrite(fout, tx_fdm, "short");
+  fclose(fout);
+endfunction
diff --git a/codec2/branches/0.7/octave/fdmdv_sweep.m b/codec2/branches/0.7/octave/fdmdv_sweep.m
new file mode 100644 (file)
index 0000000..fd61743
--- /dev/null
@@ -0,0 +1,30 @@
+% fdmdv_sweep.m
+% David Rowe Feb 2013
+% Produces a raw file that sweeps between 1000 and 2000 Hz to test freq
+% response of transmitters.
+
+secs=10;
+fmin=1000;
+fmax=2000;
+Fs=8000;
+rms = 4200;  % roughly RMS value of fdmdv signal
+amp = sqrt(2)*rms;
+nsamples=Fs*secs;
+theta = 0;
+s=zeros(1,nsamples);
+
+for i=1:nsamples
+  f(i) = fmin + i*(fmax-fmin)/nsamples;
+  w = 2*pi*f(i)/Fs;  
+  theta += w;
+  theta -= 2*pi*floor(theta/(2*pi));
+  s(i) = amp*cos(theta);  
+end
+
+figure(1)
+clf
+plot(s(1:100));
+fout = fopen("1k_2k_sweep.raw", "wb");
+fwrite(fout, s, "short");
+fclose(fout);
+
diff --git a/codec2/branches/0.7/octave/fdmdv_ut.m b/codec2/branches/0.7/octave/fdmdv_ut.m
new file mode 100644 (file)
index 0000000..3ee5b4d
--- /dev/null
@@ -0,0 +1,352 @@
+% fdmdv_ut.m
+%
+% Unit Test program for FDMDV modem.  Useful for general development as it has
+% both tx and rx sides, and basic AWGN channel simulation.
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+fdmdv;               % load modem code
+% Simulation Parameters --------------------------------------
+
+frames = 100;
+EbNo_dB = 6.3;
+Foff_hz = -100;
+modulation = 'dqpsk';
+hpa_clip = 150;
+
+% ------------------------------------------------------------
+
+more off;
+tx_filt = zeros(Nc,M);
+rx_symbols_log = [];
+rx_phase_log = 0;
+rx_timing_log = 0;
+tx_pwr = 0;
+noise_pwr = 0;
+rx_fdm_log = [];
+rx_baseband_log = [];
+rx_bits_offset = zeros(Nc*Nb*2);
+prev_tx_symbols = ones(Nc+1,1); prev_tx_symbols(Nc+1) = 2;
+prev_rx_symbols = ones(Nc+1,1);
+ferr = 0;
+foff = 0;
+foff_log = [];
+tx_baseband_log = [];
+tx_fdm_log = [];
+
+% BER stats
+
+total_bit_errors = 0;
+total_bits = 0;
+bit_errors_log = [];
+sync_bit_log = [];
+test_frame_sync_log = [];
+test_frame_sync_state = 0;
+
+% SNR estimation states
+
+sig_est = zeros(Nc+1,1);
+noise_est = zeros(Nc+1,1);
+
+% fixed delay simuation
+
+Ndelay = M+20;
+rx_fdm_delay = zeros(Ndelay,1);
+
+% ---------------------------------------------------------------------
+% Eb/No calculations.  We need to work out Eb/No for each FDM carrier.
+% Total power is sum of power in all FDM carriers
+% ---------------------------------------------------------------------
+
+C = 1; % power of each FDM carrier (energy/sample).  Total Carrier power should = Nc*C = Nc
+N = 1; % total noise power (energy/sample) of noise source across entire bandwidth
+
+% Eb  = Carrier power * symbol time / (bits/symbol)
+%     = C *(1/Rs) / Nb
+Eb_dB = 10*log10(C) - 10*log10(Rs) - 10*log10(Nb);
+
+No_dBHz = Eb_dB - EbNo_dB;
+
+% Noise power = Noise spectral density * bandwidth
+% Noise power = Noise spectral density * Fs/2 for real signals
+N_dB = No_dBHz + 10*log10(Fs/2);
+Ngain_dB = N_dB - 10*log10(N);
+Ngain = 10^(Ngain_dB/20);
+
+% C/No = Carrier Power/noise spectral density
+%      = power per carrier*number of carriers / noise spectral density
+CNo_dB = 10*log10(C)  + 10*log10(Nc) - No_dBHz;
+
+% SNR in equivalent 3000 Hz SSB channel
+
+B = 3000;
+SNR = CNo_dB - 10*log10(B);
+
+% freq offset simulation states
+
+phase_offset = 1;
+freq_offset = exp(j*2*pi*Foff_hz/Fs);
+foff_phase = 1;
+t = 0;
+foff = 0;
+fest_state = 0;
+fest_timer = 0;
+sync_mem = zeros(1,Nsync_mem);
+sync = 0;
+sync_log = [];
+
+snr_log = [];
+
+Nspec=1024;
+spec_mem=zeros(1,Nspec);
+SdB = zeros(1,Nspec);
+
+% ---------------------------------------------------------------------
+% Main loop 
+% ---------------------------------------------------------------------
+
+for f=1:frames
+
+  % -------------------
+  % Modulator
+  % -------------------
+
+  tx_bits = get_test_bits(Nc*Nb);
+  tx_symbols = bits_to_psk(prev_tx_symbols, tx_bits, modulation);
+  prev_tx_symbols = tx_symbols;
+  tx_baseband = tx_filter(tx_symbols);
+  tx_baseband_log = [tx_baseband_log tx_baseband];
+  tx_fdm = fdm_upconvert(tx_baseband);
+  tx_pwr = 0.9*tx_pwr + 0.1*real(tx_fdm)*real(tx_fdm)'/(M);
+
+  % -------------------
+  % Channel simulation
+  % -------------------
+
+  % frequency offset
+
+  %Foff_hz += 1/Rs;
+  Foff = Foff_hz;
+  for i=1:M
+    % Time varying freq offset
+    %Foff = Foff_hz + 100*sin(t*2*pi/(300*Fs));
+    %t++;
+    freq_offset = exp(j*2*pi*Foff/Fs);
+    phase_offset *= freq_offset;
+    tx_fdm(i) = phase_offset*tx_fdm(i);
+  end
+
+  tx_fdm = real(tx_fdm);
+
+  % HPA non-linearity
+
+  tx_fdm(find(abs(tx_fdm) > hpa_clip)) = hpa_clip;
+  tx_fdm_log = [tx_fdm_log tx_fdm];
+
+  rx_fdm = tx_fdm;
+
+  % AWGN noise
+
+  noise = Ngain*randn(1,M);
+  noise_pwr = 0.9*noise_pwr + 0.1*noise*noise'/M;
+  rx_fdm += noise;
+  rx_fdm_log = [rx_fdm_log rx_fdm];
+
+  % update spectrum
+
+  l=length(rx_fdm);
+  spec_mem(1:Nspec-l) = spec_mem(l+1:Nspec);
+  spec_mem(Nspec-l+1:Nspec) = rx_fdm;
+  S=fft(spec_mem.*hanning(Nspec)',Nspec);
+  SdB = 0.9*SdB + 0.1*20*log10(abs(S));
+
+  % -------------------
+  % Demodulator
+  % -------------------
+
+  % shift down to complex baseband
+
+  for i=1:M
+    fbb_phase_rx = fbb_phase_rx*fbb_rect';
+    rx_fdm(i) = rx_fdm(i)*fbb_phase_rx;
+  end
+  mag = abs(fbb_phase_rx);
+  fbb_phase_rx /= mag;
+
+  % frequency offset estimation and correction, need to call rx_est_freq_offset even in sync
+  % mode to keep states updated
+  
+  [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, M);
+  [foff_coarse S1 S2] = rx_est_freq_offset(rx_fdm, pilot, prev_pilot, M, !sync);
+
+  if sync == 0
+    foff = foff_coarse;
+  end
+  
+  foff_log = [ foff_log foff ];
+  foff_rect = exp(j*2*pi*foff/Fs);
+  
+  for i=1:M
+    foff_phase *= foff_rect';
+    rx_fdm(i) = rx_fdm(i)*foff_phase;
+  end
+
+  rx_fdm_filter = rxdec_filter(rx_fdm, M);
+  rx_filt = down_convert_and_rx_filter(rx_fdm_filter, M, M/Q);
+
+  [rx_symbols rx_timing] = rx_est_timing(rx_filt, M);
+  rx_timing_log = [rx_timing_log rx_timing];
+
+  %rx_phase = rx_est_phase(rx_symbols);
+  %rx_phase_log = [rx_phase_log rx_phase];
+  %rx_symbols = rx_symbols*exp(j*rx_phase);
+
+  [rx_bits sync_bit foff_fine pd] = psk_to_bits(prev_rx_symbols, rx_symbols, modulation);
+  if strcmp(modulation,'dqpsk')
+    rx_symbols_log = [rx_symbols_log pd];
+  else
+    rx_symbols_log = [rx_symbols_log rx_symbols];
+  endif
+  foff -= 0.5*foff_fine;
+  
+  prev_rx_symbols = rx_symbols;
+  sync_bit_log = [sync_bit_log sync_bit];
+  
+  % freq est state machine
+
+  [sync reliable_sync_bit fest_state fest_timer sync_mem] = freq_state(sync_bit, fest_state, fest_timer, sync_mem);
+  sync_log = [sync_log sync];
+
+  % Update SNR est
+
+  [sig_est noise_est] = snr_update(sig_est, noise_est, pd);
+  snr_log = [snr_log calc_snr(sig_est, noise_est)];
+
+  % count bit errors if we find a test frame
+  % Allow 15 frames for filter memories to fill and time est to settle
+
+  [test_frame_sync bit_errors] = put_test_bits(test_bits, rx_bits);
+  
+  if test_frame_sync == 1
+    total_bit_errors = total_bit_errors + bit_errors;
+    total_bits = total_bits + Ntest_bits;
+    bit_errors_log = [bit_errors_log bit_errors];
+    else
+      bit_errors_log = [bit_errors_log 0];
+  end
+  % test frame sync state machine, just for more informative plots
+    
+  next_test_frame_sync_state = test_frame_sync_state;
+  if (test_frame_sync_state == 0)
+    if (test_frame_sync == 1)      
+      next_test_frame_sync_state = 1;
+      test_frame_count = 0;
+    end
+  end
+
+  if (test_frame_sync_state == 1)
+    % we only expect another test_frame_sync pulse every 4 symbols
+    test_frame_count++;
+    if (test_frame_count == 4)
+      test_frame_count = 0;
+      if ((test_frame_sync == 0))      
+        next_test_frame_sync_state = 0;
+      end
+    end
+  end
+  test_frame_sync_state = next_test_frame_sync_state;
+  test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
+end
+
+% ---------------------------------------------------------------------
+% Print Stats
+% ---------------------------------------------------------------------
+
+ber = total_bit_errors / total_bits;
+
+% Peak to Average Power Ratio calcs from http://www.dsplog.com
+
+papr = max(tx_fdm_log.*conj(tx_fdm_log)) / mean(tx_fdm_log.*conj(tx_fdm_log));
+papr_dB = 10*log10(papr);
+
+% Note Eb/No set point is for Nc data carriers only, excluding pilot.
+% This is convenient for testing BER versus Eb/No.  Measured SNR &
+% Eb/No includes power of pilot.  Similar for SNR, first number is SNR
+% excluding pilot pwr for Eb/No set point, 2nd value is measured SNR
+% which will be a little higher as pilot power is included. Note current SNR
+% est algorithm only works for QPSK, gives silly values for 8PSK.
+
+printf("Bits/symbol.: %d\n", Nb);
+printf("Num carriers: %d\n", Nc);
+printf("Bit Rate....: %d bits/s\n", Rb);
+printf("Eb/No (meas): %2.2f (%2.2f) dB\n", EbNo_dB, 10*log10(0.25*tx_pwr*Fs/(Rs*Nc*noise_pwr)));
+printf("bits........: %d\n", total_bits);
+printf("errors......: %d\n", total_bit_errors);
+printf("BER.........: %1.4f\n",  ber);
+printf("PAPR........: %1.2f dB\n", papr_dB);
+printf("SNR...(meas): %2.2f (%2.2f) dB\n", SNR, calc_snr(sig_est, noise_est));
+
+% ---------------------------------------------------------------------
+% Plots
+% ---------------------------------------------------------------------
+
+figure(1)
+clf;
+[n m] = size(rx_symbols_log);
+plot(real(rx_symbols_log(1:Nc+1,15:m)),imag(rx_symbols_log(1:Nc+1,15:m)),'+')
+axis([-3 3 -3 3]);
+title('Scatter Diagram');
+
+figure(2)
+clf;
+subplot(211)
+plot(rx_timing_log)
+title('timing offset');
+subplot(212)
+plot(foff_log, '-;freq offset;')
+hold on;
+plot(sync_log*75, 'r;Sync State & course(0) fine(1) freq tracking;');
+hold off;
+title('Freq offset (Hz)');
+
+figure(3)
+clf;
+subplot(211)
+plot(real(tx_fdm_log));
+title('FDM Tx Signal');
+subplot(212)
+plot((0:Nspec/2-1)*Fs/Nspec, SdB(1:Nspec/2) - 20*log10(Nspec/2))
+axis([0 Fs/2 -40 0])
+grid
+title('FDM Rx Spectrum');
+
+figure(4)
+clf;
+subplot(311)
+stem(sync_bit_log)
+axis([0 frames 0 1.5]);
+title('BPSK Sync')
+subplot(312)
+stem(bit_errors_log);
+title('Bit Errors for test frames')
+subplot(313)
+plot(test_frame_sync_log);
+axis([0 frames 0 1.5]);
+title('Test Frame Sync')
+
+figure(5)
+clf
+subplot(211)
+plot(snr_log)
+subplot(212)
+%plot(20*log10(sig_est(1:Nc))-20*log10(sig_est(Nc+1))+6)
+%axis([1 Nc -6 6]);
+sdB_pc = 20*log10(sig_est(1:Nc+1));
+bar(sdB_pc(1:Nc) - mean(sdB_pc(1:Nc)))
+axis([0 Nc+1 -3 3]);
diff --git a/codec2/branches/0.7/octave/fdmdv_ut_coh.m b/codec2/branches/0.7/octave/fdmdv_ut_coh.m
new file mode 100644 (file)
index 0000000..a159887
--- /dev/null
@@ -0,0 +1,341 @@
+% fdmdv_ut_coh.m
+%
+
+% Unit Test program for coherent version of FDMDV modem.  Used to
+% build up the ability to test coherent demodulation of FDMDV
+% signals sampled off air.  These signals are differentially encoded
+% but we can treat the symbols after the diff encoder as PSK symbols.
+%
+% We keep most of the existing DPSK modem to handle acquisition, frame sync,
+% and just the the PSK demo in parallel.  The goal here is to measure the BER
+% of the test data using coherent PSK, it's not actually a practical modem.
+
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+fdmdv;               % load modem code
+% Simulation Parameters --------------------------------------
+
+frames = 200;
+EbNo_dB = 7;
+Foff_hz = -100;
+hpa_clip = 150;
+
+% ------------------------------------------------------------
+
+tx_filt = zeros(Nc,M);
+rx_symbols_log = [];
+rx_phase_log = 0;
+rx_timing_log = 0;
+tx_pwr = 0;
+noise_pwr = 0;
+rx_fdm_log = [];
+rx_baseband_log = [];
+rx_bits_offset = zeros(Nc*Nb*2);
+prev_tx_symbols = ones(Nc+1,1);
+prev_rx_symbols = ones(Nc+1,1);
+ferr = 0;
+foff = 0;
+foff_log = [];
+tx_baseband_log = [];
+tx_fdm_log = [];
+
+% BER stats
+
+total_bit_errors = 0;
+total_bits = 0;
+bit_errors_log = [];
+sync_log = [];
+test_frame_sync_log = [];
+test_frame_sync_state = 0;
+
+% SNR estimation states
+
+sig_est = zeros(Nc+1,1);
+noise_est = zeros(Nc+1,1);
+
+% fixed delay simuation
+
+Ndelay = M+20;
+rx_fdm_delay = zeros(Ndelay,1);
+
+% ---------------------------------------------------------------------
+% Eb/No calculations.  We need to work out Eb/No for each FDM carrier.
+% Total power is sum of power in all FDM carriers
+% ---------------------------------------------------------------------
+
+C = 1; % power of each FDM carrier (energy/sample).  Total Carrier power should = Nc*C = Nc
+N = 1; % total noise power (energy/sample) of noise source across entire bandwidth
+
+% Eb  = Carrier power * symbol time / (bits/symbol)
+%     = C *(1/Rs) / 2
+Eb_dB = 10*log10(C) - 10*log10(Rs) - 10*log10(2);
+
+No_dBHz = Eb_dB - EbNo_dB;
+
+% Noise power = Noise spectral density * bandwidth
+% Noise power = Noise spectral density * Fs/2 for real signals
+N_dB = No_dBHz + 10*log10(Fs/2);
+Ngain_dB = N_dB - 10*log10(N);
+Ngain = 10^(Ngain_dB/20);
+
+% C/No = Carrier Power/noise spectral density
+%      = power per carrier*number of carriers / noise spectral density
+CNo_dB = 10*log10(C)  + 10*log10(Nc) - No_dBHz;
+
+% SNR in equivalent 3000 Hz SSB channel
+
+B = 3000;
+SNR = CNo_dB - 10*log10(B);
+
+% freq offset simulation states
+
+phase_offset = exp(j*0);
+freq_offset = exp(j*2*pi*Foff_hz/Fs);
+foff_phase = 1;
+t = 0;
+foff = 0;
+fest_state = 0;
+track = 0;
+track_log = [];
+
+snr_log = [];
+
+rx_symbols_ph_log = [];
+prev_rx_symbols_ph = ones(Nc+1,1);
+rx_phase_offsets_log = [];
+phase_amb_log = [];
+
+% ---------------------------------------------------------------------
+% Main loop 
+% ---------------------------------------------------------------------
+
+for f=1:frames
+
+  % -------------------
+  % Modulator
+  % -------------------
+
+  tx_bits = get_test_bits(Nc*Nb);
+  tx_symbols = bits_to_qpsk(prev_tx_symbols, tx_bits, 'dqpsk');
+  prev_tx_symbols = tx_symbols;
+  tx_baseband = tx_filter(tx_symbols);
+  tx_baseband_log = [tx_baseband_log tx_baseband];
+  tx_fdm = fdm_upconvert(tx_baseband);
+  tx_pwr = 0.9*tx_pwr + 0.1*real(tx_fdm)*real(tx_fdm)'/(M);
+
+  % -------------------
+  % Channel simulation
+  % -------------------
+
+  % frequency offset
+
+  %Foff_hz += 1/Rs;
+  Foff = Foff_hz;
+  for i=1:M
+    % Time varying freq offset
+    %Foff = Foff_hz + 100*sin(t*2*pi/(300*Fs));
+    %t++;
+    freq_offset = exp(j*2*pi*Foff/Fs);
+    phase_offset *= freq_offset;
+    tx_fdm(i) = phase_offset*tx_fdm(i);
+  end
+
+  tx_fdm = real(tx_fdm);
+
+  % HPA non-linearity
+
+  tx_fdm(find(abs(tx_fdm) > hpa_clip)) = hpa_clip;
+  tx_fdm_log = [tx_fdm_log tx_fdm];
+
+  rx_fdm = tx_fdm;
+
+  % AWGN noise
+
+  noise = Ngain*randn(1,M);
+  noise_pwr = 0.9*noise_pwr + 0.1*noise*noise'/M;
+  rx_fdm += noise;
+  rx_fdm_log = [rx_fdm_log rx_fdm];
+
+  % Delay
+
+  %rx_fdm_delay(1:Ndelay-M) = rx_fdm_delay(M+1:Ndelay);
+  %rx_fdm_delay(Ndelay-M+1:Ndelay) = rx_fdm;
+  rx_fdm_delay = rx_fdm;
+
+  % -------------------
+  % Demodulator
+  % -------------------
+
+  % frequency offset estimation and correction, need to call
+  % rx_est_freq_offset even in track mode to keep states updated
+
+  [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = get_pilot(pilot_lut_index, prev_pilot_lut_index, M);
+  [foff_course S1 S2] = rx_est_freq_offset(rx_fdm_delay, pilot, prev_pilot, M);
+  if track == 0
+    foff = foff_course;
+  end
+
+  %foff = 0; % disable for now
+
+  foff_log = [ foff_log foff ];
+  foff_rect = exp(j*2*pi*foff/Fs);
+
+  for i=1:M
+    foff_phase *= foff_rect';
+    rx_fdm_delay(i) = rx_fdm_delay(i)*foff_phase;
+  end
+
+  % baseband processing
+
+  rx_baseband = fdm_downconvert(rx_fdm_delay(1:M), M);
+  rx_baseband_log = [rx_baseband_log rx_baseband];
+  rx_filt = rx_filter(rx_baseband, M);
+
+  [rx_symbols rx_timing] = rx_est_timing(rx_filt, rx_baseband, M);
+  rx_symbols_log = [rx_symbols_log rx_symbols.*(conj(prev_rx_symbols)./abs(prev_rx_symbols))*exp(j*pi/4)];
+  rx_timing_log = [rx_timing_log rx_timing];
+
+  % coherent phase offset estimation ------------------------------------
+
+  [rx_phase_offsets ferr] = rx_est_phase(rx_symbols);
+  rx_phase_offsets_log = [rx_phase_offsets_log rx_phase_offsets];
+  phase_amb_log = [phase_amb_log phase_amb];
+  rx_symbols_ph = rx_symbols_mem(:,floor(Nph/2)+1) .* exp(-j*(rx_phase_offsets + phase_amb));
+  rx_symbols_ph_log = [rx_symbols_ph_log rx_symbols_ph .* exp(j*pi/4)];
+  rx_symbols_ph = -1 + 2*(real(rx_symbols_ph .* exp(j*pi/4)) > 0) + j*(-1 + 2*(imag(rx_symbols_ph .* exp(j*pi/4)) > 0));
+
+  % Std differential (used for freq offset est and BPSK sync) and psuedo coherent detection -----------------------
+
+  [rx_bits_unused sync        ferr        pd] = qpsk_to_bits(prev_rx_symbols, rx_symbols, 'dqpsk');
+  [rx_bits        sync_unused ferr_unused pd] = qpsk_to_bits(prev_rx_symbols_ph, rx_symbols_ph, 'dqpsk');
+
+  %----------------------------------------------------------------------
+
+  foff -= 0.5*ferr;
+  prev_rx_symbols = rx_symbols;
+  prev_rx_symbols_ph = rx_symbols_ph;
+  sync_log = [sync_log sync];
+  
+  % freq est state machine
+
+  [track fest_state] = freq_state(sync, fest_state);
+  track_log = [track_log track];
+
+  % Update SNR est
+
+  [sig_est noise_est] = snr_update(sig_est, noise_est, pd);
+  snr_log = [snr_log calc_snr(sig_est, noise_est)];
+
+  % count bit errors if we find a test frame
+
+  [test_frame_sync bit_errors] = put_test_bits(test_bits, rx_bits);
+
+  if (test_frame_sync == 1) && (f > 15)
+    total_bit_errors = total_bit_errors + bit_errors;
+    total_bits = total_bits + Ntest_bits;
+    bit_errors_log = [bit_errors_log bit_errors];
+    else
+      bit_errors_log = [bit_errors_log 0];
+  end
+  % test frame sync state machine, just for more informative plots
+    
+  next_test_frame_sync_state = test_frame_sync_state;
+  if (test_frame_sync_state == 0)
+    if (test_frame_sync == 1)      
+      next_test_frame_sync_state = 1;
+      test_frame_count = 0;
+    end
+  end
+
+  if (test_frame_sync_state == 1)
+    % we only expect another test_frame_sync pulse every 4 symbols
+    test_frame_count++;
+    if (test_frame_count == 4)
+      test_frame_count = 0;
+      if ((test_frame_sync == 0))      
+        next_test_frame_sync_state = 0;
+      end
+    end
+  end
+  test_frame_sync_state = next_test_frame_sync_state;
+  test_frame_sync_log = [test_frame_sync_log test_frame_sync_state];
+end
+
+% ---------------------------------------------------------------------
+% Print Stats
+% ---------------------------------------------------------------------
+
+ber = total_bit_errors / total_bits;
+
+% Note Eb/No set point is for Nc data carriers only, excluding pilot.
+% This is convenient for testing BER versus Eb/No.  Measured Eb/No
+% includes power of pilot.  Similar for SNR, first number is SNR excluding
+% pilot pwr for Eb/No set point, 2nd value is measured SNR which will be a little
+% higher as pilot power is included.
+
+printf("\n");
+printf("Eb/No (meas): %2.2f (%2.2f) dB\n", EbNo_dB, 10*log10(0.25*tx_pwr*Fs/(Rs*Nc*noise_pwr)));
+printf("SNR...(meas): %2.2f (%2.2f) dB\n", SNR, calc_snr(sig_est, noise_est));
+printf("\nDPSK\n");
+printf("  bits......: %d\n", total_bits);
+printf("  errors....: %d\n", total_bit_errors);
+printf("  BER.......: %1.4f\n",  ber);
+
+% ---------------------------------------------------------------------
+% Plots
+% ---------------------------------------------------------------------
+
+figure(1)
+clf;
+[n m] = size(rx_symbols_log);
+plot(real(rx_symbols_log(1:Nc+1,15:m)),imag(rx_symbols_log(1:Nc+1,15:m)),'+')
+%plot(real(rx_symbols_log(2,15:m)),imag(rx_symbols_log(2,15:m)),'+')
+axis([-3 3 -3 3]);
+title('Scatter Diagram');
+
+figure(2)
+clf;
+subplot(211)
+plot(rx_timing_log)
+title('timing offset (samples)');
+subplot(212)
+plot(foff_log, '-;freq offset;')
+hold on;
+plot(track_log*75, 'r;course-fine;');
+hold off;
+title('Freq offset (Hz)');
+
+figure(3)
+clf;
+subplot(311)
+stem(sync_log)
+axis([0 frames 0 1.5]);
+title('BPSK Sync')
+subplot(312)
+stem(bit_errors_log);
+title('Bit Errors for test frames')
+subplot(313)
+plot(test_frame_sync_log);
+axis([0 frames 0 1.5]);
+title('Test Frame Sync')
+
+figure(4)
+clf;
+[n m] = size(rx_symbols_ph_log);
+plot(real(rx_symbols_ph_log(1:Nc+1,15:m)),imag(rx_symbols_ph_log(1:Nc+1,15:m)),'+')
+%plot(real(rx_symbols_ph_log(2,15:m)),imag(rx_symbols_ph_log(2,15:m)),'+')
+axis([-3 3 -3 3]);
+title('Scatter Diagram - after phase correction');
+
+figure(5)
+clf;
+subplot(211)
+plot(rx_phase_offsets_log(1,:))
+subplot(212)
+plot(phase_amb_log(1,:))
+title('Rx Phase Offset Est')
diff --git a/codec2/branches/0.7/octave/fdmdv_ut_freq_off.m b/codec2/branches/0.7/octave/fdmdv_ut_freq_off.m
new file mode 100644 (file)
index 0000000..395bcc5
--- /dev/null
@@ -0,0 +1,489 @@
+% fdmdv_ut_freq_off.m
+% David Rowe 17 June 2014
+%
+% Unit Test program for freq offset estimation in FDMDV modem.  
+%
+% Copyright David Rowe 2012 This program is
+% distributed under the terms of the GNU General Public License
+% Version 2
+
+% [ ] sweep of different delays
+% [ ] sweep of Eb/No
+% [ ] sweep of freq offsets
+% [ ] step change in foff
+%     + time to respond
+% [ ] plot/print pass fail/relevant stats
+%      + variance
+%      + histogram of freq ests?
+
+fdmdv;  % load modem code
+hf_sim; % load hf sim code
+
+% ---------------------------------------------------------------------
+% Eb/No calculations.  We need to work out Eb/No for each FDM carrier.
+% Total power is sum of power in all FDM carriers.  These calcs set the
+% Eb/No of the data carriers, Eb/No of pilot will be higher.
+% ---------------------------------------------------------------------
+
+function [Nsd SNR] = calc_Nsd_from_EbNo(EbNo_dB)
+  global Rs;
+  global Nb;
+  global Nc;
+  global Fs;
+
+  C = 1; % power of each FDM carrier (energy/sample).  Total Carrier power should = Nc*C = Nc
+  N = 1; % total noise power (energy/sample) of noise source across entire bandwidth
+
+  % Eb  = Carrier power * symbol time / (bits/symbol)
+  %     = C *(1/Rs) / Nb
+  Eb_dB = 10*log10(C) - 10*log10(Rs) - 10*log10(Nb);
+
+  No_dBHz = Eb_dB - EbNo_dB;
+
+  % Noise power = Noise spectral density * bandwidth
+  % Noise power = Noise spectral density * Fs/2 for real signals
+  N_dB = No_dBHz + 10*log10(Fs/2);
+  Ngain_dB = N_dB - 10*log10(N);
+  Nsd = 10^(Ngain_dB/20);
+
+  % C/No = Carrier Power/noise spectral density
+  %      = power per carrier*number of carriers / noise spectral density
+  CNo_dB = 10*log10(C) + 10*log10(Nc) - No_dBHz;
+
+  % SNR in equivalent 3000 Hz SSB channel, adding extra power for pilot to get
+  % true SNR.
+
+  B = 3000;
+  SNR = CNo_dB - 10*log10(B) + 10*log10((Nc+4)/Nc);
+end
+
+% we keep a m sample buffer in sample_memory
+% update sample_memory with n samples each time this function is called
+% outputs one nfft2 slice of spectrogram in dB.  Good idea to make nfft2 a power of 2
+
+function [S, states_out] = spectrogram_update(samples, n, states_in)
+  sample_memory = states_in.sample_memory;
+  m             = states_in.m;
+  nfft2         = states_in.nfft2;
+  lower_clip_dB = states_in.lower_clip_dB;
+  dec           = states_in.dec;
+
+  sample_memory(1:m-n)   = sample_memory(n+1:m);
+  sample_memory(m-n+1:m) = samples;
+
+  F = fft(sample_memory .* hanning(m)', 2*nfft2);
+  S = 20*log10(abs(F(1:dec:nfft2))/(nfft2));
+  S(find(S < lower_clip_dB)) = lower_clip_dB;    % clip lower limit
+
+  states_out = states_in;
+  states_out.sample_memory = sample_memory;
+end
+
+% ------------------------------------------------------------
+
+function sim_out = freq_off_est_test(sim_in)
+  global Nc;
+  global Nb;
+  global M;
+  global Fs;
+  global pilot_lut_index;
+  global prev_pilot_lut_index;
+  global pilot_lpf1;
+  global Npilotlpf;
+  global spread;
+  global spread_2ms;
+  global hf_gain;
+
+  EbNovec   = sim_in.EbNovec;
+  Ndelay    = sim_in.delay;
+  frames    = sim_in.frames;
+  startup_delay = sim_in.startup_delay;
+  allowable_error = sim_in.allowable_error;
+  foff_hz   = sim_in.foff_hz;
+  hf_sim    = sim_in.hf_sim;
+  hf_delay  = floor(sim_in.hf_delay_ms*Fs/1000);
+  plot_type = sim_in.plot_type;
+
+  % work out gain for HF model
+  % e = sum((g*s)^2) = g*g*sum(s^2) = N, g = sqrt(N/sum(s^2))
+  % compute so e=N
+
+  s1 = spread(1:frames*M);
+  s2 = [zeros(hf_delay,1); spread_2ms(1:frames*M)];
+  s2 = s2(1:frames*M);
+
+  p = (s1+s2)'*(s1+s2);
+  hf_gain = sqrt(frames*M/p);
+  p2 = (hf_gain*(s1+s2))'*(hf_gain*(s1+s2));
+
+  if hf_sim
+    channel_model = "HF";
+  else
+    channel_model = "AWGN";
+  end
+
+  % spectrogram states
+
+  spec_states.m             = 8*M;
+  spec_states.nfft2         = 2 ^ ceil(log2(spec_states.m/2));
+  spec_states.dec           = 4;
+  spec_states.sample_memory = zeros(1, spec_states.m);
+  spec_states.lower_clip_dB = -30;
+
+  printf("\n%s\n", sim_in.test_name);
+  printf("  Channel EbNo SNR(calc) SNR(meas) SD(Hz) Hits Hits(%%) Result\n");
+
+  % ---------------------------------------------------------------------
+  % Main loop 
+  % ---------------------------------------------------------------------
+
+  for ne = 1:length(EbNovec)
+    EbNo_dB = EbNovec(ne);
+    [Nsd SNR] = calc_Nsd_from_EbNo(EbNo_dB);
+    hits = 0;
+
+    tx_filt = zeros(Nc,M);
+    prev_tx_symbols = ones(Nc+1,1);
+
+    tx_fdm_log = [];
+    rx_fdm_log = [];
+    pilot_lpf1_log = [];
+    S1_log = [];
+    rx_fdm_delay = zeros(M+Ndelay,1);
+
+    % freq offset simulation states
+
+    phase_offset = 1;
+    Nmedian = 20;
+    foff_median=zeros(1,Nmedian);
+
+    % hf sim states
+    
+    path2 = zeros(1,hf_delay+M);
+    sum_sig   = 0;
+    sum_noise = 0;
+
+    % state machine
+    state = 0;
+    fest_current = 0;
+    fdelta = 5;
+    candidate_thresh = 10;
+    foff_est_thresh_prev = 0;
+
+    for f=1:frames
+
+      % ------------------- Modulator -------------------
+
+      tx_bits = get_test_bits(Nc*Nb); 
+      tx_symbols = bits_to_psk(prev_tx_symbols, tx_bits, 'dqpsk'); 
+
+      % simulate BPF filtering of +/- 200 Hz
+      % tx_symbols(1:6) = 0; tx_symbols(9:Nc) = 0;
+
+      prev_tx_symbols = tx_symbols; 
+      tx_baseband = tx_filter(tx_symbols); 
+      tx_fdm = fdm_upconvert(tx_baseband);
+      tx_fdm_log = [tx_fdm_log real(tx_fdm)];
+
+      % ------------------- Channel simulation -------------------
+
+      % frequency offset
+
+      for i=1:M 
+        freq_offset = exp(j*2*pi*foff_hz(f)/Fs);
+        phase_offset *= freq_offset; 
+        tx_fdm(i) = phase_offset*tx_fdm(i); 
+      end
+
+      % optional HF channel sim
+
+      if hf_sim
+        path1 = tx_fdm .* conj(spread(f*M+1:f*M+M)');
+
+        path2(1:hf_delay) = path2(M+1:hf_delay+M);
+        path2(hf_delay+1:hf_delay+M) = tx_fdm .* conj(spread_2ms(f*M+1:f*M+M)');
+
+        tx_fdm = hf_gain*(path1 + path2(1:M));
+      end
+      sum_sig += tx_fdm * tx_fdm';
+      
+      rx_fdm = real(tx_fdm);
+
+      % AWGN noise
+
+      noise = Nsd*randn(1,M); 
+      sum_noise += noise * noise';
+      rx_fdm += noise; 
+      rx_fdm_log = [rx_fdm_log rx_fdm];
+
+      % Fixed Delay
+
+      rx_fdm_delay(1:Ndelay) = rx_fdm_delay(M+1:M+Ndelay);
+      rx_fdm_delay(Ndelay+1:M+Ndelay) = rx_fdm; 
+
+      % ------------------- Freq Offset Est -------------------
+
+      % frequency offset estimation and correction, need to call
+      % rx_est_freq_offset even in track mode to keep states updated
+
+      [pilot prev_pilot pilot_lut_index prev_pilot_lut_index] = ...
+          get_pilot(pilot_lut_index, prev_pilot_lut_index, M); 
+      [foff_est S1 S2] = rx_est_freq_offset(rx_fdm_delay, pilot, prev_pilot, M);
+      pilot_lpf1_log = [pilot_lpf1_log pilot_lpf1(Npilotlpf-M+1:Npilotlpf)];
+      S1_log(f,:) = fftshift(S1);
+      S2_log(f,:) = fftshift(S2);
+     
+      % raw estimate
+      
+      foff_log(ne,f) = foff_est;
+      maxS1_log(ne,f) = max(S1.*conj(S1)/(S1*S1'));
+      maxS2_log(ne,f) = max(S2.*conj(S2)/(S2*S2'));
+
+      % median filter post-processed
+
+      foff_median(1:Nmedian-1) = foff_median(2:Nmedian);
+      foff_median(Nmedian) = foff_est;
+      foff_median_log(ne,f) = foff_coarse = median(foff_median);
+
+      % state machine post-processed
+
+      next_state = state;
+      if state == 0
+        if abs(foff_est - fest_current) > fdelta
+          fest_candidate = foff_est;
+          candidate_count = 0; 
+          next_state = 1;
+        end
+      end
+      if state == 1
+         if abs(foff_est - fest_candidate) > fdelta
+           next_state = 0;
+         end
+        candidate_count++; 
+         if candidate_count > candidate_thresh
+           fest_current = fest_candidate;
+           next_state = 0;
+        end
+      end
+      state = next_state;
+      foff_statemach_log(ne,f) = fest_current;
+
+      % threshold post processed
+
+      if (maxS1_log(ne,f) > 0.06) || (maxS2_log(ne,f) > 0.06)
+      %if (maxS1_log(ne,f) > 0.08)
+         foff_thresh_log(ne,f) = foff_est;
+      else   
+         foff_thresh_log(ne,f) = foff_est_thresh_prev;
+      end
+      foff_est_thresh_prev = foff_thresh_log(ne,f);
+
+      % hit/miss stats
+      fest_current = foff_statemach_log(ne,f);
+      if (f > startup_delay) && (abs(fest_current - foff_hz(f)) < allowable_error)
+        hits++;
+      end
+
+      if length(EbNovec) == 1
+        [spectrogram(f,:) spec_states] = spectrogram_update(rx_fdm, M, spec_states);
+      end
+    end
+
+    % results for this EbNo value
+
+    sim_out.foff_sd(ne) = std(foff_log(ne,startup_delay:frames));
+    sim_out.hits = hits;
+    sim_out.hits_percent = 100*sim_out.hits/(frames-startup_delay);
+    sim_out.SNRvec(ne) = SNR;
+    sim_out.tx_fdm_log = tx_fdm_log;
+    sim_out.rx_fdm_log = rx_fdm_log;
+
+    % noise we have measures is 4000 Hz wide, we want noise in 3000 Hz BW
+
+    snr_meas = 10*log10(sum_sig/(sum_noise*4000/3000));
+
+    printf("  %6s %5.2f % -5.2f     % -5.2f     %3.2f   %d  %3.2f  ", ...
+           channel_model, EbNo_dB, SNR, snr_meas, sim_out.foff_sd(ne), sim_out.hits, sim_out.hits_percent);
+    if sim_out.hits_percent == 100
+      printf("PASS\n");
+    else
+      printf("FAIL\n");
+      figure(5)
+      clf
+      plot(abs(foff_statemach_log(ne,:) - foff_hz < allowable_error));
+    end
+
+    % plots if single dimension vector
+
+    if length(EbNovec) == 1
+      fmin = -200; fmax = 200;
+      figure(1)
+      clf;
+      subplot(411)
+      plot(foff_log(ne,:))
+      axis([1 frames fmin fmax]);
+      ylabel("Foff raw")
+      subplot(412)
+      plot(foff_median_log(ne,:))
+      axis([1 frames fmin fmax]);
+      ylabel("Foff median")
+      subplot(413)
+      plot(foff_statemach_log(ne,:),'g')
+      ylabel("Foff state")
+      axis([1 frames fmin fmax]);
+      subplot(414)
+      plot(foff_thresh_log(ne,:))
+      ylabel("Foff thresh")
+      axis([1 frames fmin fmax]);
+      xlabel("Frames")
+      grid;
+
+      figure(2)
+      clf;
+      plot(maxS1_log(ne,:));
+      axis([1 frames 0 0.2]);
+      xlabel("Frames")
+      ylabel("max(abs(S1/S2))")
+      grid;
+      hold on;
+      plot(maxS2_log(ne,:),'g');
+      hold off;
+
+      figure(3)
+      [n m] = size(S1_log);
+      if strcmp(plot_type,"mesh")
+        mesh(-200+400*(0:m-1)/256,1:n,abs(S1_log(:,:)));
+        xlabel('Freq (Hz)'); ylabel('Frame num'); zlabel("max(abs(S1))")
+      else
+        imagesc(1:n,-200+400*(0:(m-1))/m,abs(S1_log(:,:))');
+        set(gca,'YDir','normal')
+        ylabel('Freq (Hz)'); xlabel('Frame num');
+        axis([1 n -200 200])
+      end  
+
+      figure(4)
+      clf
+      [n m] = size(spectrogram);
+      if strcmp(plot_type,"mesh")
+        mesh((4000/m)*(1:m),1:n,spectrogram);
+        xlabel('Freq (Hz)'); ylabel('Frame num'); zlabel('Amplitude (dB)');
+      else
+        imagesc(1:n,(4000/m)*(1:m),spectrogram')
+        set(gca,'YDir','normal')
+        ylabel('Freq (Hz)'); xlabel('Frame num');
+        axis([1 n 500 2500])
+      end
+
+      sim_out.spec = spectrogram;
+      sim_out.tx_fdm_log = spectrogram;
+    end
+  end
+end
+
+% ---------------------------------------------------------------------
+% Run Automated Tests
+% ---------------------------------------------------------------------
+
+more off;
+
+function test1
+  global M;
+  global Rs;
+
+  sim_in.test_name = "Test 1: range of Eb/No (SNRs) in AWGN channel";
+  sim_in.EbNovec = [3:10 99];
+  sim_in.delay = M/2;
+  sim_in.frames = Rs*3;
+  sim_in.foff_hz(1:sim_in.frames) = 50;
+  sim_in.startup_delay = 0.5*Rs;
+  sim_in.allowable_error = 5;
+  sim_in.hf_sim = 0;
+  sim_in.hf_delay_ms = 2;
+  sim_in.delay = M/2;
+  sim_in.plot_type = "waterfall";
+
+  sim_out = freq_off_est_test(sim_in);
+
+  figure(5)
+  clf
+  subplot(211)
+  plot(sim_in.EbNovec, sim_out.foff_sd)
+  hold on;
+  plot(sim_in.EbNovec, sim_out.foff_sd,'+')
+  hold off;
+  xlabel("Eb/No (dB)")
+  ylabel("Std Dev (Hz)")
+  axis([(min(sim_in.EbNovec)-1) (max(sim_in.EbNovec)+1) -1 10]);
+
+  subplot(212)
+  plot(sim_out.SNRvec,sim_out.foff_sd)
+  hold on;
+  plot(sim_out.SNRvec,sim_out.foff_sd,'+')
+  hold off;
+  xlabel("SNR (dB)")
+  ylabel("Std Dev (Hz)")
+  axis([(min(sim_out.SNRvec)-1)  (max(sim_out.SNRvec)+1) -1 10]);
+end
+
+
+function test2
+  sim_in.test_name = "Test 2: range of Eb/No (SNRs) in HF multipath channel"
+  sim_in.EbNovec = 0:10;
+  sim_in.delay = 2;
+  sim_in.hf_sim = 1;
+  sim_in.hf_delay_ms = 2;
+  sim_in.frames = Rs*2;
+  sim_in.foff_hz = 0;
+  sim_in.startup_delay = Rs/2;
+  sim_in.allowable_error = 5;
+
+  sim_out = freq_off_est_test(sim_in);
+
+  figure(5)
+  clf
+  subplot(211)
+  plot(sim_in.EbNovec,sim_out.foff_sd)
+  hold on;
+  plot(sim_in.EbNovec,sim_out.foff_sd,'+')
+  hold off;
+  xlabel("Eb/No (dB)")
+  ylabel("Std Dev")
+  axis([(min(sim_in.EbNovec)-1) (max(sim_in.EbNovec)+1) -1 10]);
+end
+
+function test3
+  global M;
+  global Rs;
+
+  sim_in.test_name = "Test 3: 30 Seconds in HF multipath channel at 0dB-ish SNR";
+  sim_in.EbNovec = 13;
+  sim_in.hf_sim = 0;
+  sim_in.hf_delay_ms = 2;
+  sim_in.delay = M/2;
+  sim_in.frames = Rs;
+  sim_in.foff_hz(1:sim_in.frames) = -50;
+  sim_in.startup_delay = Rs; % allow 1 second in heavily faded channels      
+  sim_in.allowable_error = 5;
+  sim_in.plot_type = "mesh";
+  sim_out = freq_off_est_test(sim_in);
+endfunction
+
+function animated_gif
+  figure(4)
+  for i=5:5:360
+    view(i,45)
+    filename=sprintf('fdmdv_fig%05d.png',i);
+    print(filename);
+  end
+  if 0
+  for i=90:-5:-270
+    view(45,i)
+    filename=sprintf('fdmdv_fig%05d.png',i);
+    print(filename);
+  end
+  end
+endfunction
+
+test3;
+
diff --git a/codec2/branches/0.7/octave/fm.m b/codec2/branches/0.7/octave/fm.m
new file mode 100644 (file)
index 0000000..0c9e349
--- /dev/null
@@ -0,0 +1,469 @@
+% fm.m
+% David Rowe Dec 2014
+%
+% Analog FM Octave simulation functions.
+
+1;
+
+graphics_toolkit ("gnuplot");
+
+function fm_states = analog_fm_init(fm_states)
+
+  % FM modulator constants
+
+  Fs = fm_states.Fs; FsOn2 = Fs/2;  
+  fm_max = fm_states.fm_max;                 % max modulation freq
+  fd = fm_states.fd;                         % (max) deviation
+  fm_states.m = fd/fm_max;                   % modulation index
+  fm_states.Bfm = Bfm = 2*(fd+fm_max);       % Carson's rule for FM signal bandwidth
+  fm_states.tc = tc = 50E-6;
+  fm_states.prede = [1 -(1 - 1/(tc*Fs))];    % pre/de emp filter coeffs
+  fm_states.ph_dont_limit = 0;               % Limit rx delta-phase
+  
+  % Select length of filter to be an integer number of symbols to
+  % assist with "fine" timing offset estimation.  Set Ts to 1 for
+  % analog modulation.
+
+  Ts = fm_states.Ts;
+  desired_ncoeffs = 200;
+  ncoeffs = floor(desired_ncoeffs/Ts+1)*Ts;
+
+  % "coarse" timing offset is half filter length, we have two filters.
+  % This is the delay the two filters introduce, so we need to adjust
+  % for this when comparing tx to trx bits for BER calcs.
+
+  fm_states.nsym_delay = ncoeffs/Ts;
+
+  % input filter gets rid of excess noise before demodulator, as too much
+  % noise causes atan2() to jump around, e.g. -pi to pi.  However this
+  % filter can cause harmonic distortion at very high SNRs, as it knocks out
+  % some of the FM signal spectra.  This filter isn't really required for high
+  % SNRs > 20dB.
+
+  fc = (Bfm/2)/(FsOn2);
+  fm_states.bin  = firls(ncoeffs,[0 fc*(1-0.05) fc*(1+0.05) 1],[1 1 0.01 0.01]);
+
+  % demoduator output filter to limit us to fm_max (e.g. 3kHz)
+
+  fc = fm_max/(FsOn2);
+  fm_states.bout = firls(ncoeffs,[0 0.95*fc 1.05*fc 1], [1 1 0.01 0.01]);
+endfunction
+
+
+function fm_fir_coeff_file(fm_states, filename)
+  global gt_alpha5_root;
+  global Nfilter;
+
+  f=fopen(filename,"wt");
+
+  fprintf(f,"/* Generated by fm_fir_coeff_file() Octave function in fm.m */\n\n");
+  fprintf(f,"const float bin[]={\n");
+  for m=1:length(fm_states.bin)-1
+    fprintf(f,"  %g,\n", fm_states.bin(m));
+  endfor
+  fprintf(f,"  %g\n};\n\n", fm_states.bin(length(fm_states.bin)));
+
+  fprintf(f,"const float bout[]={\n");
+  for m=1:length(fm_states.bout)-1
+    fprintf(f,"  %g,\n", fm_states.bout(m));
+  endfor
+  fprintf(f,"  %g\n};\n", fm_states.bout(length(fm_states.bout)));
+
+  fclose(f);
+endfunction
+
+
+function tx = analog_fm_mod(fm_states, mod)
+  Fs = fm_states.Fs;
+  fc = fm_states.fc; wc = 2*pi*fc/Fs;
+  fd = fm_states.fd; wd = 2*pi*fd/Fs;
+  nsam = length(mod);
+
+  if fm_states.pre_emp
+    mod = filter(fm_states.prede,1,mod);
+    mod = mod/max(mod);           % AGC to set deviation
+  end
+
+  tx_phase = 0;
+  tx = zeros(1,nsam);
+
+  for i=0:nsam-1
+    w = wc + wd*mod(i+1);
+    tx_phase = tx_phase + w;
+    tx_phase = tx_phase - floor(tx_phase/(2*pi))*2*pi;
+    tx(i+1) = exp(j*tx_phase);
+  end
+endfunction
+
+
+function [rx_out rx_bb] = analog_fm_demod(fm_states, rx)
+  Fs = fm_states.Fs;
+  fc = fm_states.fc; wc = 2*pi*fc/Fs;
+  fd = fm_states.fd; wd = 2*pi*fd/Fs;
+  nsam = length(rx);
+  t = 0:(nsam-1);
+
+  rx_bb = rx .* exp(-j*wc*t);      % down to complex baseband
+  rx_bb = filter(fm_states.bin,1,rx_bb);
+
+  % differentiate first, in rect domain, then find angle, this puts
+  % signal on the positive side of the real axis
+
+  rx_bb_diff = [ 1 rx_bb(2:nsam) .* conj(rx_bb(1:nsam-1))];
+  rx_out = atan2(imag(rx_bb_diff),real(rx_bb_diff));
+
+  % limit maximum phase jumps, to remove static type noise at low SNRs
+  if !fm_states.ph_dont_limit
+    rx_out(find(rx_out > wd)) = wd;
+    rx_out(find(rx_out < -wd)) = -wd;
+  end
+  rx_out *= (1/wd);
+
+  if fm_states.output_filter
+    rx_out = filter(fm_states.bout,1,rx_out);
+  end
+  if fm_states.de_emp
+    rx_out = filter(1,fm_states.prede,rx_out);
+  end
+endfunction
+
+
+function sim_out = analog_fm_test(sim_in)
+  nsam      = sim_in.nsam;
+  CNdB      = sim_in.CNdB;
+  verbose   = sim_in.verbose;
+
+  Fs = fm_states.Fs = 96000;  
+  fm_max = fm_states.fm_max = 3E3;
+  fd = fm_states.fd = 5E3;
+  fm_states.fc = 24E3;
+
+  fm_states.pre_emp = pre_emp = sim_in.pre_emp;
+  fm_states.de_emp  = de_emp = sim_in.de_emp;
+  fm_states.Ts = 1;
+  fm_states.output_filter = 1;
+  fm_states = analog_fm_init(fm_states);
+  sim_out.Bfm = fm_states.Bfm;
+
+  Bfm = fm_states.Bfm;
+  m = fm_states.m; tc = fm_states.tc;
+  t = 0:(nsam-1);
+
+  fm = 1000; wm = 2*pi*fm/fm_states.Fs;
+  
+  % start simulation
+
+  for ne = 1:length(CNdB)
+
+    % work out the variance we need to obtain our C/N in the bandwidth
+    % of the FM demod.  The gaussian generator randn() generates noise
+    % with a bandwidth of Fs
+
+    aCNdB = CNdB(ne);
+    CN = 10^(aCNdB/10);
+    variance = Fs/(CN*Bfm);
+     
+    % FM Modulator -------------------------------
+
+    mod = sin(wm*t);
+    tx = analog_fm_mod(fm_states, mod);
+    
+    % Channel ---------------------------------
+
+    noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+    rx = tx + noise;
+
+    % FM Demodulator
+
+    [rx_out rx_bb] = analog_fm_demod(fm_states, rx);
+
+    % notch out test tone
+
+    w = 2*pi*fm/Fs; beta = 0.99;
+    rx_notch = filter([1 -2*cos(w) 1],[1 -2*beta*cos(w) beta*beta], rx_out);
+
+    % measure power with and without test tone to determine S+N and N
+
+    settle = 1000;             % filter settling time, to avoid transients
+    nsettle = nsam - settle;
+
+    sinad = (rx_out(settle:nsam) * rx_out(settle:nsam)')/nsettle;
+    nad = (rx_notch(settle:nsam) * rx_notch(settle:nsam)')/nsettle;
+
+    snr = (sinad-nad)/nad;
+    sim_out.snrdB(ne) = 10*log10(snr);
+   
+    % Theory from FMTutorial.pdf, Lawrence Der, Silicon labs paper
+
+    snr_theory_dB = aCNdB + 10*log10(3*m*m*(m+1));
+    fx = 1/(2*pi*tc); W = fm_max;
+    I = (W/fx)^3/(3*((W/fx) - atan(W/fx)));
+    I_dB = 10*log10(I);
+
+    sim_out.snr_theorydB(ne) = snr_theory_dB;
+    sim_out.snr_theory_pre_dedB(ne) = snr_theory_dB + I_dB;
+   
+    if verbose > 1
+      printf("modn index: %2.1f Bfm: %.0f Hz\n", m, Bfm);
+    end
+
+    if verbose > 0
+      printf("C/N: %4.1f SNR: %4.1f dB THEORY: %4.1f dB or with pre/de: %4.1f dB\n", 
+      aCNdB, 10*log10(snr), snr_theory_dB, snr_theory_dB+I_dB);
+    end
+
+    if verbose > 1
+      figure(1)
+      subplot(211)
+      plot(20*log10(abs(fft(rx))))
+      title('FM Modulator Output Spectrum');
+      axis([1 length(tx) 0 100]);
+      subplot(212)
+      Rx_bb = 20*log10(abs(fft(rx_bb)));
+      plot(Rx_bb)
+      axis([1 length(tx) 0 100]);
+      title('FM Demodulator (baseband) Input Spectrum');
+
+      figure(2)
+      subplot(211)
+      plot(rx_out(settle:nsam))
+      axis([1 4000 -1 1]) 
+      subplot(212)
+      Rx = 20*log10(abs(fft(rx_out(settle:nsam))));
+      plot(Rx(1:10000))
+      axis([1 10000 0 100]);
+   end
+
+  end
+
+endfunction
+
+
+function run_fm_curves
+  sim_in.nsam    = 96000;
+  sim_in.verbose = 1;
+  sim_in.pre_emp = 0;
+  sim_in.de_emp  = 0;
+  sim_in.CNdB = -4:2:20;
+
+  sim_out = analog_fm_test(sim_in);
+
+  figure(1)
+  clf
+  plot(sim_in.CNdB, sim_out.snrdB,"r;FM Simulated;");
+  hold on;
+  plot(sim_in.CNdB, sim_out.snr_theorydB,"g;FM Theory;");
+  plot(sim_in.CNdB, sim_in.CNdB,"b; SSB Theory;");
+  hold off;
+  grid("minor");
+  xlabel("FM demod input C/N (dB)");
+  ylabel("FM demod output S/N (dB)");
+  legend("boxoff");
+
+  % C/No curves
+
+  Bfm_dB = 10*log10(sim_out.Bfm);
+  Bssb_dB = 10*log10(3000);
+
+  figure(2)
+  clf
+  plot(sim_in.CNdB + Bfm_dB, sim_out.snrdB,"r;FM Simulated;");
+  hold on;
+  plot(sim_in.CNdB + Bfm_dB, sim_out.snr_theorydB,"g;FM Theory;");
+  plot(sim_in.CNdB + Bssb_dB, sim_in.CNdB,"b; SSB Theory;");
+  hold off;
+  grid("minor");
+  xlabel("FM demod input C/No (dB)");
+  ylabel("FM demod output S/N (dB)");
+  legend("boxoff");
+
+endfunction
+
+
+function run_fm_single
+  sim_in.nsam    = 96000;
+  sim_in.verbose = 2;
+  sim_in.pre_emp = 0;
+  sim_in.de_emp  = 0;
+
+  sim_in.CNdB   = 20;
+  sim_out = analog_fm_test(sim_in);
+end
+
+
+function fm_mod_file(file_name_out)
+  fm_states.Fs = 48000;  
+  fm_states.fm_max = 3E3;
+  fm_states.fd = 5E3;
+  fm_states.fc = fm_states.Fs/4;
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = 0;
+  fm_states.Ts = 1;
+  fm_states.output_filter = 1;
+  fm_states = analog_fm_init(fm_states);
+
+  nsam = fm_states.Fs * 10;
+  t = 0:(nsam-1);
+  fm = 1000; wm = 2*pi*fm/fm_states.Fs;
+  mod = sin(wm*t);
+  tx = analog_fm_mod(fm_states, mod);
+
+  tx_out = tx*16384;
+  fout = fopen(file_name_out,"wb");
+  fwrite(fout, tx_out, "short");
+  fclose(fout);
+endfunction
+
+
+function fm_demod_file(file_name_out, file_name_in)
+  fin = fopen(file_name_in,"rb");
+  rx = fread(fin,"short")'; 
+  rx = rx(100000:length(rx)); % strip of wave header
+  fclose(fin);
+
+  Fs = fm_states.Fs = 48000;  
+  fm_max = fm_states.fm_max = 3E3;
+  fd = fm_states.fd = 5E3;
+  fm_states.fc = 12E3;
+
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = 1;
+  fm_states.Ts = 1;
+  fm_states.output_filter = 1;
+  fm_states = analog_fm_init(fm_states);
+
+  [rx_out rx_bb] = analog_fm_demod(fm_states, rx);
+
+  rx_out *= 20000;
+  fout = fopen(file_name_out,"wb");
+  fwrite(fout, rx_out, "short");
+  fclose(fout);
+
+  figure(1)
+  subplot(211)
+  plot(rx)
+  subplot(212)
+  plot(20*log10(abs(fft(rx))))
+  title('FM Dmodulator Intput Spectrum');
+
+  figure(2)
+  subplot(211)
+  Rx_bb = 20*log10(abs(fft(rx_bb)));
+  plot(Rx_bb)
+  title('FM Demodulator (baseband) Input Spectrum');
+
+  subplot(212)
+  plot(20*log10(abs(fft(rx_out))))
+  title('FM Dmodulator Output Spectrum');
+
+  figure(3)
+  plot(rx_out)
+  title('FM Dmodulator Output');
+
+  % estimate SNR, C/No etc
+
+  npower_window = 1024;
+  rx_power = conv(rx.^2,ones(1,npower_window))/(npower_window);
+  rx_power_dB = 10*log10(rx_power);
+  figure;
+  subplot(211)
+  plot(rx);
+  subplot(212)
+  plot(rx_power_dB);
+  axis([1 length(rx_power) max(rx_power_dB)-9 max(rx_power_dB)+1])
+  grid("minor")
+
+  % estimate FM demod output SNR if a 1000 Hz tone is present
+
+  w = 2*pi*1000/Fs; beta = 0.99;
+  rx_notch = filter([1 -2*cos(w) 1],[1 -2*beta*cos(w) beta*beta], rx_out);
+
+  rx_out_power = conv(rx_out.^2,ones(1,npower_window))/(npower_window);
+  rx_out_power_dB = 10*log10(rx_out_power);
+  rx_notch_power = conv(rx_notch.^2,ones(1,npower_window))/(npower_window);
+  rx_notch_power_dB = 10*log10(rx_notch_power);
+  figure;
+  plot(rx_out_power_dB,'r;FM demod output power;');
+  hold on;
+  plot(rx_notch_power_dB,'b;1000 Hz notch filter output power;');
+  plot(rx_out_power_dB-rx_notch_power_dB,'g;1000 Hz tone SNR;');
+  hold off;
+  legend("boxoff");
+  ylabel('dB');
+  xlabel('Time (samples)');
+  grid("minor")
+
+endfunction
+
+
+% generate filter coeffs for C implementation of FM demod
+
+function make_coeff_file
+  fm_states.Fs = 44400;  
+  fm_states.fm_max = 3E3;
+  fm_states.fd = 5E3;
+  fm_states.fc = fm_states.Fs/4;
+
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = 0;
+  fm_states.Ts = 1;
+  fm_states.output_filter = 1;
+  fm_states = analog_fm_init(fm_states);
+
+  fm_fir_coeff_file(fm_states, "fm_fir_coeff.h")
+endfunction
+
+function test_fm_modulator
+  fm_states.Fs = 48000;  
+  fm_states.fm_max = 3E3;
+  fm_states.fd = 5E3;
+  %fm_states.fc = fm_states.Fs/4;
+  fm_states.fc = 0;   
+
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = 0;
+  fm_states.Ts = 1;
+  fm_states.output_filter = 1;
+  fm_states = analog_fm_init(fm_states);
+  
+  test_t = [1:(fm_states.Fs*10)];
+  test_freq1 = 2*pi*3000/fm_states.Fs;
+  test_freq2 = 2*pi*1000/fm_states.Fs;
+
+  test_sig = .5*sin(test_t*test_freq1) + .5*sin(test_t*test_freq2);
+  %test_sig = zeros(1,length(test_t));
+  %test_sig = ones(1,length(test_t));
+
+  ftsig = fopen("fm_test_sig.raw","wb");
+  fwrite(ftsig,test_sig*16384,"short");
+  fclose(ftsig);
+  
+  system("../fm_test fm_test_sig.raw fm_test_out.raw");
+  ftmod = fopen("fm_test_out.raw","r");
+  test_mod_p = rot90(fread(ftmod,"short"))/16384;
+  test_mod_r = test_mod_p(1:2:length(test_mod_p));
+  test_mod_i = test_mod_p(2:2:length(test_mod_p));
+  test_mod = test_mod_r .+ i*test_mod_i;
+  fclose(ftmod);
+  
+  comp_mod = analog_fm_mod(fm_states,test_sig);
+  
+  figure(1)
+  comp_mod_real = real(comp_mod);
+  size(comp_mod_real)
+  size(test_mod)
+  mod_diff = zeros(1,length(test_mod));
+  mod_diff = test_mod .- comp_mod;
+  plot(test_t,real(test_mod .- comp_mod),test_t,imag(test_mod .- comp_mod));
+
+endfunction
+
+more off;
+
+%run_fm_curves
+%fm_demod_file("ssb_fm_out.raw","~/Desktop/ssb_fm.wav")
+%fm_demod_file("ssb25_fm_de.raw", "~/Desktop/ssb25db.wav")
+%run_fm_single
+%make_coeff_file
+%fm_mod_file("fm_1000.raw");
+%test_fm_modulator
diff --git a/codec2/branches/0.7/octave/fm_radio_filt_model.txt b/codec2/branches/0.7/octave/fm_radio_filt_model.txt
new file mode 100644 (file)
index 0000000..368f7e2
--- /dev/null
@@ -0,0 +1,8 @@
+# Created by Octave 4.0.0, Wed Feb 10 20:14:16 2016 CST <baobrien@baobrien-d-desktop>
+# name: filt
+# type: matrix
+# rows: 1
+# columns: 1001
+ 4.111934884608988e-05 4.529266752036107e-05 5.012294778018435e-05 5.387673663540811e-05 5.656595617636202e-05 5.754247327156636e-05 5.745029328387444e-05 5.810382275274602e-05 6.038440324493526e-05 6.151519405194188e-05 5.995001465356246e-05 5.965124091807071e-05 5.894036887788694e-05 5.282714911187688e-05 4.16286613756742e-05 2.733281113424976e-05 1.151301392357209e-05 -5.011952829637155e-06 -2.038060526743049e-05 -2.88950898384027e-05 -3.140205230802841e-05 -2.680377848432233e-05 -1.425766597021347e-05 2.754137907668088e-06 2.533067638032289e-05 5.098405707491412e-05 7.524935743597888e-05 9.490108720790089e-05 0.0001114408649087926 0.0001232907290105822 0.0001298558067129026 0.0001314146843973354 0.000126874153326206 0.0001211256678148737 0.0001128586850331393 0.0001021842594143064 9.340521285980458e-05 8.465588232787989e-05 7.602754602719386e-05 7.476083494605245e-05 7.795597606716329e-05 8.085052742218461e-05 8.855370570715267e-05 9.993747197784049e-05 0.0001100627878797455 0.0001157727179778551 0.0001211159686312227 0.0001276193402990368 0.0001274951568358215 0.0001237937282219144 0.0001199864757482567 0.0001145773485240607 0.0001078643622955885 9.949247921871633e-05 9.282321723585223e-05 8.670764514445847e-05 8.236867203976522e-05 8.178131856442866e-05 8.653490906422325e-05 9.474089964535933e-05 0.0001046664881685255 0.0001171407871684955 0.0001284375906324497 0.0001435371988464706 0.0001538019728144609 0.000157821986861445 0.0001617032194688335 0.000161139381508245 0.0001573044997290387 0.0001505912434581831 0.0001444545226667355 0.0001371895926370354 0.0001282916901414378 0.0001164777490003531 0.0001017868860228118 8.38857960955751e-05 6.397168698635467e-05 4.505424718694719e-05 2.609404178225459e-05 9.390120446350423e-06 -6.139147851498066e-06 -1.74535589572342e-05 -2.432568386408825e-05 -2.719609151945925e-05 -2.559556014458576e-05 -1.629614429158625e-05 -1.3631941893713e-06 1.383091083546116e-05 3.467670361993851e-05 6.180780852724694e-05 8.838658249276322e-05 0.0001119097915371812 0.0001372537482217498 0.0001573246833069575 0.0001685794934648446 0.0001736521706833196 0.0001743894362264053 0.000170440134727034 0.0001570034141396783 0.0001415291461137907 0.0001293030383250257 0.0001170129681552746 0.0001056747747162765 9.587608125739278e-05 8.209630166614193e-05 6.930393501059805e-05 6.085367944553192e-05 5.275816447026444e-05 4.194241650880381e-05 3.420239452264183e-05 3.304591574725996e-05 3.024288241806293e-05 3.012154305643325e-05 3.738917134601837e-05 4.770388200482866e-05 5.781977436721907e-05 7.420695272211161e-05 8.723833080263831e-05 9.505250826889752e-05 0.0001065158066456628 0.0001104312822684124 0.0001098275912662366 0.000107206024810334 0.0001025516069602837 9.894340278646091e-05 9.407503918864603e-05 8.7319365554045e-05 8.141197975598374e-05 8.422482885728253e-05 9.626406072217444e-05 0.0001047837385634293 0.0001197702730190546 0.0001441800101209614 0.000160456934552367 0.0001774138786603596 0.0001926926553236415 0.0001984206468214209 0.0001945597427125206 0.0001836754090288533 0.0001644147124457892 0.0001450923278130216 0.000131637876080013 0.0001194268883117051 0.0001142849115928036 0.0001090067194513346 0.0001167532618894625 0.0001293962113881341 0.0001304604164937581 0.0001310955784948294 0.0001353721674033472 0.0001341681487126995 0.0001198264422032539 0.0001012747411089002 7.153140827090248e-05 4.191084339680094e-05 2.303431628630918e-05 1.138159045954137e-05 1.214910078795732e-05 2.029103100753587e-05 3.914274819454478e-05 7.436668389413293e-05 0.0001131985409445768 0.0001541458098186209 0.0001981874567952984 0.0002293068332902554 0.0002574810386944711 0.0002797524248574673 0.000280098997160137 0.0002691199306180641 0.0002483396512410882 0.0002130987320308693 0.0001696438030090705 0.0001233684249499195 8.43926061428125e-05 5.198681974621152e-05 3.567320177887548e-05 4.949705291163776e-05 7.787515033943651e-05 0.0001300149878038 0.0002020713027294515 0.0002783857988869775 0.0003565185832637648 0.0004241895316775589 0.000479626912439881 0.0005159892932585141 0.0005326203262494115 0.0005366426137323655 0.0005240387399286967 0.0005041051313799223 0.0004864550530904512 0.0004727638664349475 0.0004645950604270155 0.0004548102499574072 0.000455527247961606 0.0004612992161328969 0.0004674556394527062 0.0004716258022734013 0.0004668087315020519 0.0004622641649603435 0.0004465585690774155 0.000425258701401412 0.00039751658715728 0.0003635800988525798 0.0003328960310700836 0.0003048849901663823 0.0002810007495450609 0.0002673721567286335 0.0002702604512501591 0.0002862572870604029 0.0003084406671027542 0.0003355248671444351 0.0003761847353904122 0.0004148377173810094 0.0004485558688712593 0.0004800892227209435 0.0005013700140284393 0.0005138034260364562 0.000523675449512398 0.0005317635475002124 0.0005322207128124348 0.0005292033760978139 0.0005269773541343302 0.0005175977188382754 0.0004993895797658196 0.0004858979454010794 0.0004684001252653537 0.0004587034220581103 0.0004638037190751786 0.0004761823498486873 0.0004885372867673723 0.0005043751480265481 0.0005446800229664075 0.0005890158012063288 0.0006231865628459465 0.0006616542116343469 0.0006972231165628774 0.0007040149509799145 0.000712178888077443 0.0007101214361108593 0.0006931453291674526 0.0006924927262763824 0.0006853703272953059 0.0007004172297637321 0.0007466476213180197 0.00080183074513318 0.0008653125079193471 0.000932413333045206 0.0009780458869915588 0.001000137248327646 0.0009991649016365171 0.0009565650123854935 0.0008785166874477056 0.0007712153995398795 0.0006440612144425213 0.0005014886072902373 0.0003647207877911045 0.0002314452035966864 0.0001215619643926978 5.102070582077005e-05 3.53881850929961e-06 5.024961716295417e-06 4.952203678213442e-05 0.0001260092656341149 0.0002274300947131321 0.0003513571295408856 0.0004918678731923972 0.0006212972022330388 0.0007279470267812717 0.0008134213275591345 0.000856084224659261 0.0008367582390177951 0.0007963231371937705 0.0007308920792511363 0.0006278320617335954 0.0005155411192978977 0.0004049366284488046 0.0003146483534597321 0.000232809201512697 0.0001611481391302676 0.0001276356087955276 0.0001258477694353633 0.000148410784426943 0.0001791264427517458 0.0002152831436118296 0.0002722059220446592 0.0003148588847685937 0.0003235563379009122 0.0003234961169067191 0.0003141523386480817 0.0002970986813756301 0.0002753731712067278 0.0002391073092942144 0.0002217724458095815 0.0002500563490184254 0.0002860821491880679 0.0003319979542964821 0.0004127132318400748 0.0005101781526047186 0.0006116301200159012 0.0007154307983328388 0.0008127224793692451 0.0008838704404048489 0.0009291650300966136 0.0009480193252716987 0.0009397344198433433 0.0009095689814133252 0.0008547924134192681 0.0007841007737282723 0.0007018037456432335 0.0006005948006725787 0.0005078784471340359 0.0004406418213749735 0.0003714124757418396 0.0003264057688551507 0.0003047322000871897 0.0002906911596356952 0.0002861738822980829 0.0002743316277907311 0.0002636405310368626 0.0002526665586205466 0.000226716276058895 0.0001875320324724495 0.0001636750239487869 0.0001372388125105794 0.0001222573562860838 0.0001269254248804013 0.0001139495649892648 0.0001106414381361491 0.0001196292706110303 0.0001189746129582091 0.0001112327955701268 0.0001296685790607515 0.0001643819608291414 0.0001878863422254414 0.0002344588678557017 0.0003203860709214426 0.0004064572654023451 0.0004940737860301076 0.000596014360602431 0.0006749848938371238 0.0007389096824511 0.0007792584703839535 0.0007965798134060041 0.0008056540909816971 0.0007849711152884964 0.000736062831596933 0.0006709962921592219 0.000603317655045247 0.0005383093164802969 0.0004900142937176716 0.0004551531490340078 0.000449534106387221 0.0004708650906301616 0.0004934795110626268 0.0005345974954791178 0.0006078660984573032 0.000702762715896311 0.0007775394691744047 0.0008818221619807017 0.001000679407785467 0.001092707546060794 0.001210613677564552 0.001312089019158298 0.001405270807169912 0.001490114661507714 0.001531394363834887 0.001555410794560944 0.001543704930528568 0.001470479573974331 0.001389350245308104 0.00128125012918577 0.001130987351527693 0.001007863016474597 0.0008564828937716682 0.0007074501288004987 0.0006213523466697201 0.0005713540643662852 0.0005583807693821872 0.0006196820100433617 0.0007361817663542591 0.0008554464717298295 0.0009758354537658702 0.001030406744297961 0.001035680319931336 0.001012121155964727 0.0009548313236383478 0.0008790095856581987 0.0008222269458738788 0.0007806888647762658 0.00070288663268893 0.0006454619358970265 0.0006054134743706602 0.000585536509799107 0.0005761856239940797 0.0005868746914752406 0.0006209602772533917 0.0006504193524742758 0.0006871616100603014 0.0007025287393104163 0.0007171995117985032 0.0007172937860848917 0.0006961439382863224 0.0006718024855287201 0.0006254758975065462 0.0005416137326971845 0.0004555547815183704 0.0003867779579310328 0.0003290178707355808 0.0002953031361596086 0.000255119760230264 0.0002488539502124204 0.0002677640501578254 0.0002652005008809371 0.0002906090024497945 0.0003166398471483209 0.0003089920401697223 0.0003114866028324989 0.0003133184110010134 0.0002840418132516435 0.0002386702280686958 0.0001892280180500572 0.0001115506030916713 1.983929251944428e-07 -0.0001282921891725907 -0.0002827272707108253 -0.0004368740799478221 -0.0005848618113809967 -0.0007194441046966012 -0.0008196524633909468 -0.0009048202133206396 -0.0009695404302984057 -0.00101680303425177 -0.00104331484535875 -0.001044670960196941 -0.001096308220052877 -0.001198928001528127 -0.001307622162194671 -0.001475710104821832 -0.001686034525628763 -0.001932017480014 -0.002224364121912755 -0.002509340882950428 -0.002795659773184621 -0.00309134921771924 -0.003339621248074061 -0.003527096039668997 -0.003713374797631359 -0.003865457109591278 -0.003984544055673171 -0.004135912398823348 -0.004315826807472575 -0.004496951439455919 -0.004688515788482826 -0.004898735004401356 -0.005110796780538788 -0.005339127441411028 -0.00553035210769078 -0.005705695069882694 -0.005870819376498557 -0.006004875496650137 -0.006110777442311181 -0.006164210930893388 -0.00618756905448379 -0.006096936349455484 -0.005939592020122337 -0.005693193052915928 -0.005354094079859258 -0.005027974684133828 -0.004692376525298168 -0.004435709093992968 -0.004274376328604747 -0.004208157300760209 -0.004223103959974963 -0.004327093561393999 -0.004497183833286816 -0.004613763151773346 -0.004718655531703288 -0.00476162995946275 -0.004733215833039038 -0.004717818557505252 -0.004685430263054647 -0.004754957289104762 -0.004977412914427918 -0.005345713165123564 -0.005956911360135976 -0.006682313612074329 -0.007507498625754038 -0.008207774465767762 -0.008390747806307929 -0.007774338884105022 -0.005813672313667084 -0.002020675163340676 0.003934699513891164 0.01218867179800687 0.0227189593674642 0.03474656425430857 0.0474559430852135 0.05969919927081149 0.06940044807963783 0.07690251527634465 0.08229165974889782 0.07690251527634465 0.06940044807963783 0.05969919927081149 0.04745594308521349 0.03474656425430857 0.02271895936746419 0.01218867179800687 0.003934699513891165 -0.002020675163340676 -0.005813672313667083 -0.007774338884105022 -0.008390747806307929 -0.008207774465767762 -0.007507498625754038 -0.006682313612074331 -0.005956911360135976 -0.005345713165123564 -0.004977412914427918 -0.004754957289104762 -0.004685430263054647 -0.004717818557505251 -0.004733215833039039 -0.00476162995946275 -0.004718655531703288 -0.004613763151773345 -0.004497183833286817 -0.004327093561393998 -0.004223103959974966 -0.004208157300760209 -0.004274376328604745 -0.00443570909399297 -0.004692376525298168 -0.005027974684133829 -0.00535409407985926 -0.005693193052915932 -0.005939592020122337 -0.006096936349455483 -0.006187569054483791 -0.006164210930893387 -0.006110777442311182 -0.006004875496650137 -0.005870819376498557 -0.005705695069882694 -0.00553035210769078 -0.005339127441411028 -0.005110796780538787 -0.004898735004401356 -0.004688515788482826 -0.004496951439455919 -0.004315826807472577 -0.004135912398823348 -0.003984544055673172 -0.003865457109591278 -0.00371337479763136 -0.003527096039668997 -0.003339621248074061 -0.00309134921771924 -0.00279565977318462 -0.002509340882950424 -0.002224364121912757 -0.001932017480014 -0.001686034525628767 -0.001475710104821831 -0.001307622162194672 -0.001198928001528127 -0.001096308220052873 -0.001044670960196942 -0.00104331484535875 -0.001016803034251772 -0.0009695404302984054 -0.00090482021332064 -0.0008196524633909476 -0.0007194441046966014 -0.0005848618113809963 -0.000436874079947822 -0.0002827272707108247 -0.0001282921891725906 1.9839292519393e-07 0.0001115506030916713 0.0001892280180500569 0.0002386702280686963 0.0002840418132516444 0.0003133184110010132 0.0003114866028324986 0.0003089920401697223 0.0003166398471483207 0.0002906090024497948 0.0002652005008809363 0.000267764050157825 0.0002488539502124205 0.0002551197602302644 0.000295303136159608 0.0003290178707355802 0.0003867779579310346 0.0004555547815183697 0.0005416137326971845 0.000625475897506546 0.0006718024855287199 0.0006961439382863226 0.0007172937860848909 0.0007171995117985036 0.0007025287393104162 0.0006871616100603015 0.000650419352474276 0.0006209602772533919 0.0005868746914752408 0.0005761856239940797 0.0005855365097991073 0.0006054134743706607 0.0006454619358970264 0.0007028866326889299 0.0007806888647762659 0.000822226945873879 0.0008790095856581987 0.0009548313236383482 0.001012121155964728 0.001035680319931336 0.001030406744297961 0.0009758354537658703 0.0008554464717298296 0.0007361817663542591 0.0006196820100433625 0.0005583807693821864 0.000571354064366285 0.0006213523466697193 0.0007074501288005006 0.0008564828937716656 0.001007863016474597 0.001130987351527696 0.001281250129185769 0.001389350245308103 0.001470479573974332 0.001543704930528569 0.001555410794560944 0.001531394363834887 0.001490114661507714 0.001405270807169912 0.001312089019158298 0.001210613677564552 0.001092707546060794 0.001000679407785467 0.0008818221619807018 0.0007775394691744045 0.0007027627158963109 0.0006078660984573031 0.000534597495479118 0.0004934795110626265 0.0004708650906301616 0.0004495341063872209 0.0004551531490340077 0.0004900142937176715 0.0005383093164802969 0.000603317655045247 0.0006709962921592213 0.0007360628315969327 0.0007849711152884964 0.0008056540909816968 0.0007965798134060039 0.000779258470383954 0.0007389096824511003 0.0006749848938371232 0.0005960143606024314 0.00049407378603011 0.0004064572654023451 0.000320386070921443 0.0002344588678557023 0.0001878863422254417 0.0001643819608291412 0.0001296685790607518 0.0001112327955701267 0.0001189746129582092 0.0001196292706110302 0.0001106414381361493 0.000113949564989265 0.0001269254248804011 0.000122257356286084 0.0001372388125105794 0.0001636750239487874 0.0001875320324724492 0.0002267162760588951 0.0002526665586205469 0.0002636405310368628 0.000274331627790731 0.0002861738822980834 0.0002906911596356955 0.0003047322000871902 0.0003264057688551512 0.0003714124757418389 0.0004406418213749726 0.0005078784471340354 0.000600594800672577 0.0007018037456432339 0.0007841007737282728 0.0008547924134192688 0.0009095689814133239 0.0009397344198433432 0.0009480193252716988 0.0009291650300966141 0.0008838704404048497 0.0008127224793692449 0.0007154307983328389 0.0006116301200159011 0.0005101781526047185 0.0004127132318400751 0.0003319979542964823 0.0002860821491880682 0.0002500563490184256 0.0002217724458095814 0.0002391073092942146 0.0002753731712067281 0.0002970986813756304 0.0003141523386480819 0.0003234961169067191 0.0003235563379009124 0.0003148588847685941 0.0002722059220446591 0.0002152831436118294 0.0001791264427517463 0.0001484107844269434 0.0001258477694353638 0.0001276356087955284 0.0001611481391302664 0.0002328092015126938 0.0003146483534597321 0.0004049366284488059 0.000515541119297898 0.0006278320617335942 0.0007308920792511362 0.0007963231371937704 0.0008367582390177949 0.000856084224659261 0.0008134213275591343 0.0007279470267812722 0.0006212972022330388 0.0004918678731923973 0.0003513571295408855 0.0002274300947131321 0.000126009265634115 4.952203678213429e-05 5.024961716295127e-06 3.538818509299518e-06 5.102070582076996e-05 0.0001215619643926977 0.0002314452035966865 0.0003647207877911044 0.0005014886072902379 0.0006440612144425216 0.0007712153995398789 0.0008785166874477058 0.0009565650123854939 0.0009991649016365179 0.001000137248327646 0.0009780458869915582 0.0009324133330452072 0.0008653125079193493 0.0008018307451331798 0.000746647621318018 0.0007004172297637317 0.0006853703272953076 0.0006924927262763831 0.0006931453291674521 0.0007101214361108594 0.0007121788880774427 0.000704014950979915 0.0006972231165628779 0.000661654211634347 0.0006231865628459464 0.0005890158012063288 0.0005446800229664074 0.0005043751480265481 0.0004885372867673724 0.0004761823498486873 0.0004638037190751788 0.0004587034220581102 0.0004684001252653539 0.0004858979454010797 0.0004993895797658201 0.0005175977188382752 0.0005269773541343305 0.0005292033760978143 0.0005322207128124349 0.0005317635475002128 0.000523675449512398 0.000513803426036456 0.0005013700140284385 0.0004800892227209432 0.0004485558688712597 0.0004148377173810098 0.0003761847353904126 0.0003355248671444355 0.0003084406671027549 0.0002862572870604022 0.000270260451250159 0.0002673721567286339 0.0002810007495450609 0.000304884990166382 0.0003328960310700833 0.00036358009885258 0.0003975165871572802 0.000425258701401412 0.0004465585690774157 0.0004622641649603433 0.0004668087315020517 0.0004716258022734012 0.0004674556394527063 0.0004612992161328973 0.0004555272479616062 0.000454810249957407 0.0004645950604270157 0.0004727638664349478 0.000486455053090451 0.0005041051313799224 0.0005240387399286972 0.0005366426137323651 0.0005326203262494113 0.0005159892932585147 0.0004796269124398812 0.0004241895316775592 0.0003565185832637645 0.0002783857988869775 0.0002020713027294521 0.0001300149878038001 7.787515033943645e-05 4.94970529116387e-05 3.567320177887565e-05 5.198681974621122e-05 8.439260614281255e-05 0.0001233684249499196 0.0001696438030090706 0.0002130987320308694 0.0002483396512410884 0.000269119930618064 0.0002800989971601369 0.0002797524248574673 0.0002574810386944714 0.0002293068332902553 0.0001981874567952985 0.0001541458098186209 0.0001131985409445768 7.436668389413293e-05 3.914274819454482e-05 2.02910310075359e-05 1.214910078795737e-05 1.138159045954142e-05 2.303431628630914e-05 4.191084339680085e-05 7.153140827090229e-05 0.0001012747411089004 0.0001198264422032543 0.0001341681487126989 0.0001353721674033473 0.0001310955784948295 0.0001304604164937583 0.0001293962113881343 0.0001167532618894624 0.0001090067194513343 0.0001142849115928038 0.0001194268883117053 0.0001316378760800131 0.0001450923278130218 0.0001644147124457893 0.0001836754090288532 0.0001945597427125205 0.000198420646821421 0.0001926926553236415 0.0001774138786603597 0.0001604569345523672 0.0001441800101209615 0.0001197702730190544 0.0001047837385634294 9.626406072217448e-05 8.422482885728265e-05 8.141197975598381e-05 8.7319365554045e-05 9.4075039188646e-05 9.894340278646086e-05 0.0001025516069602838 0.0001072060248103339 0.0001098275912662369 0.0001104312822684126 0.000106515806645663 9.505250826889828e-05 8.723833080263867e-05 7.420695272211161e-05 5.781977436721884e-05 4.770388200482809e-05 3.7389171346018e-05 3.012154305643296e-05 3.024288241806269e-05 3.30459157472601e-05 3.42023945226418e-05 4.194241650880383e-05 5.275816447026444e-05 6.085367944553199e-05 6.930393501059805e-05 8.209630166614197e-05 9.587608125739296e-05 0.0001056747747162764 0.0001170129681552745 0.0001293030383250257 0.0001415291461137908 0.0001570034141396783 0.0001704401347270341 0.0001743894362264053 0.0001736521706833197 0.0001685794934648447 0.0001573246833069577 0.00013725374822175 0.0001119097915371812 8.838658249276298e-05 6.180780852724682e-05 3.467670361993845e-05 1.383091083546099e-05 -1.363194189371131e-06 -1.629614429158657e-05 -2.559556014458577e-05 -2.719609151945906e-05 -2.432568386408844e-05 -1.745355895723421e-05 -6.139147851498011e-06 9.390120446350515e-06 2.609404178225465e-05 4.505424718694725e-05 6.397168698635465e-05 8.388579609557507e-05 0.0001017868860228118 0.0001164777490003533 0.0001282916901414377 0.0001371895926370353 0.0001444545226667357 0.0001505912434581831 0.0001573044997290388 0.0001611393815082451 0.0001617032194688336 0.0001578219868614449 0.000153801972814461 0.0001435371988464706 0.0001284375906324499 0.0001171407871684956 0.0001046664881685255 9.474089964535937e-05 8.653490906422336e-05 8.178131856442878e-05 8.236867203976517e-05 8.670764514445867e-05 9.282321723585233e-05 9.949247921871623e-05 0.0001078643622955885 0.0001145773485240607 0.0001199864757482572 0.0001237937282219144 0.0001274951568358209 0.0001276193402990368 0.0001211159686312227 0.0001157727179778552 0.0001100627878797457 9.993747197784049e-05 8.855370570715271e-05 8.085052742218457e-05 7.795597606716331e-05 7.47608349460523e-05 7.602754602719387e-05 8.465588232787989e-05 9.340521285980456e-05 0.0001021842594143064 0.0001128586850331394 0.0001211256678148737 0.0001268741533262061 0.0001314146843973354 0.0001298558067129026 0.0001232907290105823 0.0001114408649087925 9.490108720790098e-05 7.524935743597891e-05 5.098405707491407e-05 2.533067638032283e-05 2.754137907668097e-06 -1.425766597021359e-05 -2.680377848432208e-05 -3.140205230802843e-05 -2.889508983840295e-05 -2.038060526743043e-05 -5.011952829637147e-06 1.151301392357218e-05 2.733281113424968e-05 4.16286613756742e-05 5.28271491118769e-05 5.894036887788697e-05 5.965124091807064e-05 5.995001465356243e-05 6.151519405194192e-05 6.038440324493523e-05 5.810382275274606e-05 5.745029328387439e-05 5.754247327156637e-05 5.656595617636194e-05 5.387673663540817e-05 5.012294778018432e-05 4.529266752036116e-05 4.11193488460899e-05
+
+
diff --git a/codec2/branches/0.7/octave/fmfsk.m b/codec2/branches/0.7/octave/fmfsk.m
new file mode 100644 (file)
index 0000000..4b3cc91
--- /dev/null
@@ -0,0 +1,346 @@
+%
+% fmfsk.m
+% Author: Brady O'Brien 3 Feb 2016
+%   Copyright 2016 David Rowe
+%  
+%  All rights reserved.
+%
+%  This program is free software; you can redistribute it and/or modify
+%  it under the terms of the GNU Lesser General Public License veRbion 2, as
+%  published by the Free Software Foundation.  This program is
+%  distributed in the hope that it will be useful, but WITHOUT ANY
+%  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+%  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+%  License for more details.
+%
+%  You should have received a copy of the GNU Lesser General Public License
+%  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+% mancyfsk.m modem, extracted and made suitable for C implementation
+
+fm;
+pkg load signal;
+pkg load parallel;
+1;
+
+% Init fmfsk modem
+%Fs is sample frequency
+%Rb is pre-manchester bit rate
+function states = fmfsk_init(Fs,Rb)
+    assert(mod(Fs,Rb*2)==0);
+    
+    %Current fixed processing buffer size, in non-ME bits
+    nbit = 96;
+    
+    states.Rb = Rb;
+    states.Rs = Rb*2;   % Manchester-encoded bitrate
+    states.Fs = Fs;
+    states.Ts = Fs/states.Rs;
+    states.N = nbit*2*states.Ts;     
+    states.nin = states.N;          % Samples in the next demod cycle
+    states.nstash = states.Ts*2;    % How many samples to stash away between proc cycles for timing adjust
+    states.nmem =  states.N+(4*states.Ts);
+    states.nsym = nbit*2;
+    states.nbit = nbit;
+    
+    %tates.nsym = floor(states.Rs*.080);
+    %states.nbit = floor(states.Rb*.080)
+    %Old sample memory
+    
+    states.oldsamps = zeros(1,states.nmem);
+    
+    %Last sampled-stream output, for odd bitstream generation
+    states.lastint = 0;
+    
+    %Some stats
+    states.norm_rx_timing = 0;
+    
+endfunction
+
+%Generate a stream of manchester-coded bits to be sent
+% to any ordinary FM modulator or VCO or something
+function tx = fmfsk_mod(states,inbits)
+    Ts = states.Ts;
+    tx = zeros(1,length(inbits)*2);
+    for ii = 1:length(inbits)
+        st = 1 + (ii-1)*Ts*2;
+        md = st+Ts-1;
+        en = md+Ts;
+        if inbits(ii)==0
+            tx(st:md)   = -ones(1,Ts);
+            tx(md+1:en) =  ones(1,Ts);
+        else
+            tx(st:md)   =  ones(1,Ts);
+            tx(md+1:en) = -ones(1,Ts);
+        end
+    end
+endfunction
+
+%Demodulate a bag of bits from the output of an FM demodulator
+% This function produces nbits output bits and takes states.nin samples
+function [rx_bits states] = fmfsk_demod(states,rx)
+    Ts = states.Ts;
+    Fs = states.Fs;
+    Rs = states.Rs;
+    nin = states.nin;
+    N = states.N;
+    nsym = states.nsym;
+    nbits = states.nsym/2;
+    nmem = states.nmem;
+    nstash = states.nstash;
+    
+    nold = nmem-nin;
+    ssamps = states.oldsamps;
+    
+    
+    %Shift in nin samples
+    ssamps(1:nold) = ssamps(nmem-nold+1:nmem);
+    ssamps(nold+1:nmem) = rx;
+    states.oldsamps = ssamps;
+    
+    rx_filt = zeros(1,(nsym+1)*Ts);
+    %Integrate Ts input samples at every offset
+    %This is the same thing as filtering with a filter of all ones
+    % out to Ts.
+    % It's implemented like this for ease of C-porting
+    for ii=(1:(nsym+1)*Ts)
+        st = ii;
+        en = st+Ts-1;
+        rx_filt(ii) = sum(ssamps(st:en));
+    end
+    states.rx_filt = rx_filt;
+    % Fine timing estimation ------------------------------------------------------
+
+    % Estimate fine timing using line at Rs/2 that Manchester encoding provides
+    % We need this to sync up to Manchester codewords. 
+    Np = length(rx_filt);
+    w = 2*pi*(Rs)/Fs;
+    x = (rx_filt .^ 2) * exp(-j*w*(0:Np-1))';
+    norm_rx_timing = angle(x)/(2*pi)-.42;
+     
+    rx_timing = round(norm_rx_timing*Ts);
+    
+    %If rx timing is too far out, ask for more or less sample the next time
+    % around to even it all out
+    next_nin = N;
+    if norm_rx_timing > -.2;
+       next_nin += Ts/2;
+    end
+    if norm_rx_timing < -.65;
+       next_nin -= Ts/2;
+    end
+
+    states.nin = next_nin;
+    states.norm_rx_timing = norm_rx_timing;
+    %'Even' and 'Odd' manchester bitstream.
+    % We'll figure out which to produce later
+    rx_even = zeros(1,nbits);
+    rx_odd = zeros(1,nbits);
+    apeven = 0;
+    apodd = 0;
+
+    sample_offset = (Ts/2)+Ts+rx_timing-1;
+    
+    symsamp = zeros(1,nsym);
+    
+    % Figure out the bits of the 'even' and 'odd' ME streams
+    % Also sample rx_filt offset by what fine timing determined along the way
+    % Note: ii is a zero-indexed array pointer, for less mind-breaking c portage
+    lastv = states.lastint;
+    for ii = (0:nsym-1)
+        currv = rx_filt(sample_offset+(ii*Ts)+1);
+        mdiff = lastv-currv;
+        lastv = currv;
+        mbit = mdiff>0;
+        symsamp(ii+1) = currv;
+        if mod(ii,2)==1
+            apeven += abs(mdiff);
+            rx_even( floor(ii/2)+1 ) = mbit;
+        else
+            apodd  += abs(mdiff);
+            rx_odd(  floor(ii/2)+1 ) = mbit;
+        end
+    end
+    states.symsamp = symsamp;
+    % Decide on the correct ME alignment
+    if(apeven>apodd)
+        rx_bits = rx_even;
+    else
+        rx_bits = rx_odd;
+    end
+
+    states.lastint = lastv;
+endfunction
+
+% run_sim copypasted from fsk_horus.m
+% simulation of tx and rx side, add noise, channel impairments ----------------------
+
+function fmfsk_run_sim(EbNodB,timing_offset=0,de=0,of=0,hpf=0)
+  test_frame_mode = 2;
+  frames = 70;
+  %EbNodB = 3;
+  %timing_offset = 0.0; % see resample() for clock offset below
+  %fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+  df     = 0;          % tx tone freq drift in Hz/s
+  dA     = 1;          % amplitude imbalance of tones (note this affects Eb so not a gd idea)
+
+  more off
+  rand('state',1); 
+  randn('state',1);
+  
+  Fs = 48000;
+  Rbit = 2400;
+
+  % ----------------------------------------------------------------------
+
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = de;
+  fm_states.Ts      = Fs/(Rbit*2);
+  fm_states.Fs      = Fs; 
+  fm_states.fc      = Fs/4; 
+  fm_states.fm_max  = 3E3;
+  fm_states.fd      = 5E3;
+  fm_states.output_filter = of;
+  fm_states = analog_fm_init(fm_states);
+
+  % ----------------------------------------------------------------------
+  
+  states = fmfsk_init(Fs,Rbit);
+
+  states.verbose = 0x1;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  Fs = states.Fs;
+  nbit = states.nbit;
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rb*EbNo);
+
+  % set up tx signal with payload bits based on test mode
+
+  if test_frame_mode == 1
+     % test frame of bits, which we repeat for convenience when BER testing
+    test_frame = round(rand(1, states.nbit));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, states.nbit*(frames+1)));
+  end
+  if test_frame_mode == 3
+    % repeating sequence of all symbols
+    % great for initial test of demod if nothing else works, 
+    % look for this pattern in rx_bits
+
+       % ...10101...
+      tx_bits = zeros(1, states.nbit*(frames+1));
+      tx_bits(1:2:length(tx_bits)) = 1;
+
+  end
+  
+  load fm_radio_filt_model.txt
+
+  [b, a] = cheby1(4, 1, 300/Fs, 'high');   % 300Hz HPF to simulate FM radios
+  
+  tx_pmod = fmfsk_mod(states, tx_bits);
+  tx = analog_fm_mod(fm_states, tx_pmod);
+  
+  tx = tx(10:length(tx));
+
+  if(timing_offset>0)
+    tx = resample(tx, 1000,1001); % simulated 1000ppm sample clock offset
+  end
+  
+
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise';
+  
+  %Demod by analog fm
+  rx    = analog_fm_demod(fm_states, rx);
+  
+  %High-pass filter to simulate the FM radios
+  if hpf>0
+    printf("high-pass filtering!\n")
+    rx = filter(b,a,rx);
+  end
+  rx = filter(filt,1,rx);
+  
+  figure(4)
+  title("Spectrum of rx-ed signal after FM demod and FM radio channel");
+  plot(20*log10(abs(fft(rx))))
+  figure(5)
+  title("Time domain of rx-ed signal after FM demod and FM radio channel");
+  plot(rx)
+  %rx = real(rx);
+  %b1 = fir2(100, [0 4000 5200 48000]/48000, [1 1 0.5 0.5]);
+  %rx = filter(b1,1,rx);
+  %[b a] = cheby2(6,40,[3000 6000]/(Fs/2));
+  %rx = filter(b,a,rx);
+  %rx = sign(rx);
+  %rx(find (rx > 1)) = 1;
+  %rx(find (rx < -1)) = -1;
+
+  % dump simulated rx file
+
+  timing_offset_samples = round(timing_offset*states.Ts);
+  st = 1 + timing_offset_samples;
+  rx_bits_buf = zeros(1,2*nbit);
+  x_log = [];
+  timing_nl_log = [];
+  norm_rx_timing_log = [];
+  f_int_resample_log = [];
+  f_log = [];
+  EbNodB_log = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+
+  for f=1:frames
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    en = st + states.nin - 1;
+    sf = rx(st:en);
+    st += nin;
+
+    % demodulate to stream of bits
+
+    [rx_bits states] = fmfsk_demod(states, sf);
+
+    rx_bits_buf(1:nbit) = rx_bits_buf(nbit+1:2*nbit);
+    rx_bits_buf(nbit+1:2*nbit) = rx_bits;
+    rx_bits_log = [rx_bits_log rx_bits];
+
+  end
+
+  ber = 1;
+  ox = 1;
+  rx_bits = rx_bits_log;
+  bitcnt = length(tx_bits);
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),tx_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  figure(3);
+  plot(xor(rx_bits(ox:length(rx_bits)),tx_bits(1:length(rx_bits)+1-ox)))
+  
+  printf("BER: %f Errors: %d Bits:%d\n",ber,best_nerr,bitcnt-offset);
+  
+ endfunction
+
+
+% demodulate a file of 8kHz 16bit short samples --------------------------------
+
+
+
+
diff --git a/codec2/branches/0.7/octave/fsk.m b/codec2/branches/0.7/octave/fsk.m
new file mode 100644 (file)
index 0000000..d91ba30
--- /dev/null
@@ -0,0 +1,251 @@
+% fsk.m
+% David Rowe Nov 2014
+
+% Simulation to test FSK demod
+%
+% TODO
+%   [X] Code up mod/non-coh demod/AWGN channel simulation
+%   [X] Eb/No verses BER curves
+%   [X] test analog FM with pre/de-emphahsis 
+%       + this will introduce delay, use fir filter, group delay
+%   [X] channel simulation of HT/FM radio
+%       + filtering, varying modulation index
+%   [ ] GMSK
+%   [X] refactor to plot analog FM demod curves
+%   [X] SSB curves
+%   [-] different modn index beta curves, 
+%       + not really important for now
+%   [ ] plot to illustrate harmonic dist, 
+%   [X] integration with AFSK, AFSK-FM, v AFSK-SSB (ie FSK)
+%   [-] fine timing offset for pre/de filters?
+%       + do we need interpolation as well?
+%       + might leave this as pre/de not significant now
+%   [X] C/No curves?
+%   [X] spectrum plots or analog FM and FSK
+%   [ ] figures
+
+rand('state',1); 
+randn('state',1);
+graphics_toolkit ("gnuplot");
+
+fm;
+
+function sim_out = fsk_ber_test(sim_in)
+  Fs        = 96000;
+  fmark     = sim_in.fmark;
+  fspace    = sim_in.fspace;
+  Rs        = sim_in.Rs;
+  Ts        = Fs/Rs;
+  emphasis  = 50E-6;
+  verbose   = sim_in.verbose;
+
+  nsym      = sim_in.nsym;
+  nsam      = nsym*Ts;
+  EbNodB    = sim_in.EbNodB;
+
+  fm        = sim_in.fm;
+
+  if fm
+    fm_states.pre_emp = 0;
+    fm_states.de_emp  = 0;
+    fm_states.Ts      = Ts;
+    fm_states.Fs      = Fs; 
+    fm_states.fc      = Fs/4; 
+    fm_states.fm_max  = 3E3;
+    fm_states.fd      = 5E3;
+    fm_states.output_filter = 1;
+    fm_states = analog_fm_init(fm_states);
+  end
+
+  % simulate over a range of Eb/No values
+
+  for ne = 1:length(EbNodB)
+    Nerrs = Terrs = Tbits = 0;
+
+    % randn() generates noise spread across the entire Fs bandwidth.
+    % The power (aka variance) of this noise is N = NoFs, or No =
+    % N/Fs.  The power of each bit is C=1, so the energy of each bit
+    % is Eb=1/Rs.  We want to find N as a function of Eb/No, so:
+
+    % Eb/No = (1/Rs)/(N/Fs) = Fs/(RsN)
+    %     N = Fs/(Rs(Eb/No))
+
+    aEbNodB = EbNodB(ne);
+    EbNo = 10^(aEbNodB/10);
+    variance = Fs/(Rs*EbNo);
+
+    % Modulator -------------------------------
+
+    tx_bits = round(rand(1, nsym));
+    tx = zeros(1,nsam);
+    tx_phase = 0;
+
+    for i=1:nsym
+      for k=1:Ts
+        if tx_bits(i) == 1
+          tx_phase += 2*pi*fmark/Fs;
+        else
+          tx_phase += 2*pi*fspace/Fs;
+        end
+        tx_phase = tx_phase - floor(tx_phase/(2*pi))*2*pi;
+        tx((i-1)*Ts+k) = exp(j*tx_phase);
+      end
+    end
+
+    % Optional AFSK over FM modulator
+
+    if sim_in.fm
+      % FM mod takes real input; +/- 1 for correct deviation
+      tx = analog_fm_mod(fm_states, real(tx));
+    end
+  
+    % Channel ---------------------------------
+
+    % We use complex (single sided) channel simulation, as it's convenient
+    % for the FM simulation.
+
+    noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+    rx    = tx + noise;
+    if verbose > 1
+      printf("EbNo: %f Eb: %f var No: %f EbNo (meas): %f\n", 
+      EbNo, var(tx)*Ts/Fs, var(noise)/Fs, (var(tx)*Ts/Fs)/(var(noise)/Fs));
+    end
+    save fsk tx_bits rx
+
+    % Optional AFSK over FM demodulator
+
+    if sim_in.fm
+      % scaling factor for convenience to match pure FSK
+      rx_bb = 2*analog_fm_demod(fm_states, rx);
+    else
+      rx_bb = rx;
+    end
+
+    % Demodulator -----------------------------
+
+    % non-coherent FSK demod
+
+    mark_dc  = rx_bb .* exp(-j*(0:nsam-1)*2*pi*fmark/Fs);
+    space_dc = rx_bb .* exp(-j*(0:nsam-1)*2*pi*fspace/Fs);
+
+    rx_bits = zeros(1, nsym);
+    for i=1:nsym
+      st = (i-1)*Ts+1;
+      en = st+Ts-1;
+      mark_int(i)  = sum(mark_dc(st:en));
+      space_int(i) = sum(space_dc(st:en));
+      rx_bits(i) = abs(mark_int(i)) > abs(space_int(i));
+    end
+  
+    if fm
+      d = fm_states.nsym_delay;
+      error_positions = xor(rx_bits(1+d:nsym), tx_bits(1:(nsym-d)));
+    else
+      error_positions = xor(rx_bits, tx_bits);
+    end
+    Nerrs = sum(error_positions);
+    Terrs += Nerrs;
+    Tbits += length(error_positions);
+
+    TERvec(ne) = Terrs;
+    BERvec(ne) = Terrs/Tbits;
+
+    if verbose > 1
+      figure(2)
+      clf
+      Rx = 10*log10(abs(fft(rx)));
+      plot(Rx(1:Fs/2));
+      axis([1 Fs/2 0 50]);
+
+      figure(3)
+      clf;
+      subplot(211)
+      plot(real(rx_bb(1:Ts*20)))
+      subplot(212)
+      Rx_bb = 10*log10(abs(fft(rx_bb)));
+      plot(Rx_bb(1:3000));
+      axis([1 3000 0 50]);
+
+      figure(4);
+      subplot(211)
+      stem(abs(mark_int(1:100)));
+      subplot(212)
+      stem(abs(space_int(1:100)));   
+    end
+
+    if verbose
+      printf("EbNo (db): %3.2f Terrs: %d BER: %3.2f \n", aEbNodB, Terrs, Terrs/Tbits);
+    end
+  end
+
+  sim_out.TERvec = TERvec;
+  sim_out.BERvec = BERvec;
+endfunction
+
+
+function run_fsk_curves
+  sim_in.fmark     = 1200;
+  sim_in.fspace    = 2200;
+  sim_in.Rs        = 1200;
+  sim_in.nsym      = 12000;
+  sim_in.EbNodB    = 0:2:20;
+  sim_in.fm        = 0;
+  sim_in.verbose   = 1;
+
+  EbNo  = 10 .^ (sim_in.EbNodB/10);
+  fsk_theory.BERvec = 0.5*exp(-EbNo/2); % non-coherent BFSK demod
+  fsk_sim = fsk_ber_test(sim_in);
+
+  sim_in.fm  = 1;
+  fsk_fm_sim = fsk_ber_test(sim_in);
+
+  % BER v Eb/No curves
+
+  figure(1); 
+  clf;
+  semilogy(sim_in.EbNodB, fsk_theory.BERvec,'r;FSK theory;')
+  hold on;
+  semilogy(sim_in.EbNodB, fsk_sim.BERvec,'g;FSK sim;')
+  semilogy(sim_in.EbNodB, fsk_fm_sim.BERvec,'b;FSK over FM sim;')
+  hold off;
+  grid("minor");
+  axis([min(sim_in.EbNodB) max(sim_in.EbNodB) 1E-4 1])
+  legend("boxoff");
+  xlabel("Eb/No (dB)");
+  ylabel("Bit Error Rate (BER)")
+
+  % BER v C/No (1 Hz noise BW and Eb=C/Rs=1/Rs)
+  % Eb/No = (C/Rs)/(1/(N/B))
+  % C/N   = (Eb/No)*(Rs/B)
+
+  RsOnB_dB = 10*log10(sim_in.Rs/1);
+  figure(2); 
+  clf;
+  semilogy(sim_in.EbNodB+RsOnB_dB, fsk_theory.BERvec,'r;FSK theory;')
+  hold on;
+  semilogy(sim_in.EbNodB+RsOnB_dB, fsk_sim.BERvec,'g;FSK sim;')
+  semilogy(sim_in.EbNodB+RsOnB_dB, fsk_fm_sim.BERvec,'b;FSK over FM sim;')
+  hold off;
+  grid("minor");
+  axis([min(sim_in.EbNodB+RsOnB_dB) max(sim_in.EbNodB+RsOnB_dB) 1E-4 1])
+  legend("boxoff");
+  xlabel("C/No for Rs=1200 bit/s and 1 Hz noise bandwidth (dB)");
+  ylabel("Bit Error Rate (BER)")
+end
+
+function run_fsk_single
+  sim_in.fmark     = 1000;
+  sim_in.fspace    = 2000;
+  sim_in.Rs        = 1000;
+  sim_in.nsym      = 2000;
+  sim_in.EbNodB    = 7;
+  sim_in.fm        = 0;
+  sim_in.verbose   = 1;
+
+  fsk_sim = fsk_ber_test(sim_in);
+endfunction
+
+
+%run_fsk_curves
+run_fsk_single
+
diff --git a/codec2/branches/0.7/octave/fsk4.m b/codec2/branches/0.7/octave/fsk4.m
new file mode 100644 (file)
index 0000000..8891a45
--- /dev/null
@@ -0,0 +1,540 @@
+% fsk4.m
+%
+% Brady O'Brien October 2015
+%
+% 4FSK modem attempt from the DMR spec
+
+graphics_toolkit("gnuplot");
+
+fm; % analog FM modulator functions
+
+pkg load signal;
+
+% Init function for modem ------------------------------------------------------------
+
+function fsk4_states = fsk4_init(fsk4_states,fsk4_info)
+    Fs = fsk4_states.Fs = 48000;  %Sample rate
+    Rs = fsk4_states.Rs = fsk4_info.rs;     %Symbol rate
+    M = fsk4_states.M = fsk4_states.Fs/fsk4_states.Rs; %Samples per symbol
+    
+    % Set up 4FSK raised cosine filter. This probably screws up perf if we were using
+    % optimal mod and dmeods but helps performance when using nasty old analog FM mods
+    % and demods
+
+    empty_filter = [zeros(1,99) 1];
+
+    rf = (0:(Fs/2));
+    %If there's no filter with this modem configuration, don't bother generating one
+    if fsk4_info.no_filter
+      fsk4_states.tx_filter = empty_filter;
+      fsk4_states.rx_filter = empty_filter;
+    else
+      fsk4_states.tx_filter = fir2(400 ,rf/(Fs/2),fsk4_info.tx_filt_resp(rf));
+      fsk4_states.rx_filter = fir2(400 ,rf/(Fs/2),fsk4_info.rx_filt_resp(rf));
+    endif
+
+    %fsk4_states.tx_filter = fsk4_states.rx_filter = [zeros(1,99) 1];
+    %Set up the 4FSK symbols
+    fsk4_states.symmap = fsk4_info.syms / fsk4_info.max_dev;
+    
+    fm_states.Ts = M;
+    fm_states.Fs = Fs;
+    fm_states.fc = 0;
+    fm_states.fm_max = fsk4_info.max_dev*2;
+    fm_states.fd = fsk4_info.max_dev;
+    fm_states.pre_emp = fm_states.de_emp = 0;
+    fm_states.output_filter = 0;
+    fm_states.ph_dont_limit = 1;
+    fsk4_states.fm_states = analog_fm_init(fm_states);
+    fsk4_states.modinfo = fsk4_info;
+    fsk4_states.verbose = 0;
+endfunction 
+
+%Integrate over data and dump every M samples
+function d = idmp(data, M)
+    d = zeros(1,length(data)/M);
+    for i = 1:length(d)
+      d(i) = sum(data(1+(i-1)*M:i*M));
+    end
+endfunction
+
+
+% DMR modulator ----------------------------------------------------------
+
+function [tx, tx_filt, tx_stream] = fsk4_mod(fsk4_states, tx_bits)
+  verbose = fsk4_states.verbose
+
+  hbits = tx_bits(1:2:length(tx_bits));
+  lbits = tx_bits(2:2:length(tx_bits));
+  %Pad odd bit lengths
+  if(length(hbits)!=length(lbits))
+    lbits = [lbits 0];
+  end
+  tx_symbols = lbits + hbits*2 + 1;
+  M = fsk4_states.M;
+  nsym = length(tx_symbols);
+  nsam = nsym*M;
+
+  tx_stream = zeros(1,nsam);
+  for i=1:nsym
+    tx_stream(1+(i-1)*M:i*M) = fsk4_states.symmap(tx_symbols(i));
+  end
+  tx_filt = filter(fsk4_states.tx_filter, 1, tx_stream);
+  tx = analog_fm_mod(fsk4_states.fm_states, tx_filt);
+
+  if verbose
+    figure(10);
+    plot(20*log10(abs(fft(tx))))
+    title("Spectrum of modulated 4FSK")
+  endif
+
+endfunction
+
+
+% Integrate and Dump 4FSK demod ----------------------------------------------------
+
+function bits = fsk4_demod_thing(fsk4_states, rx)
+
+  M = fsk4_states.M;
+  Fs = fsk4_states.Fs;
+  verbose = fsk4_states.verbose;
+  t = (0:length(rx)-1);
+  symup = fsk4_states.modinfo.syms;
+  
+  % Integrator is like an FIR filter with rectangular window coeffs.
+  % This has some nasty side lobes so lets limit the overall amount
+  % of noise getting in.  tx filter just happens to work, but I imagine
+  % other LPF would as well.
+  Fs = fsk4_states.Fs;
+  rf = (0:(Fs/2));
+  rx_filter_a = fir1(100 ,.2);
+  rx_filter_b = fsk4_states.rx_filter;
+  rx_filter_n = [zeros(1,99) 1];
+
+  rx = filter(rx_filter_b, 1, rx);
+
+  sym1m = exp(-j*2*pi*(symup(1)/Fs)*t).*rx;
+  sym2m = exp(-j*2*pi*(symup(2)/Fs)*t).*rx;
+  sym3m = exp(-j*2*pi*(symup(3)/Fs)*t).*rx;
+  sym4m = exp(-j*2*pi*(symup(4)/Fs)*t).*rx;
+
+  % this puppy found by experiment between 1 and M. Will vary with different
+  % filter impulse responses, as delay will vary.  f you add M to it coarse
+  % timing will adjust by 1.
+
+  fine_timing = 54;
+
+  sym1m = idmp(sym1m(fine_timing:length(sym1m)),M); sym1m = (real(sym1m).^2+imag(sym1m).^2);
+  sym2m = idmp(sym2m(fine_timing:length(sym2m)),M); sym2m = (real(sym2m).^2+imag(sym2m).^2);
+  sym3m = idmp(sym3m(fine_timing:length(sym3m)),M); sym3m = (real(sym3m).^2+imag(sym3m).^2);
+  sym4m = idmp(sym4m(fine_timing:length(sym4m)),M); sym4m = (real(sym4m).^2+imag(sym4m).^2);
+
+  
+  figure(2);
+  nsym = 500;
+  %subplot(411); plot(sym1m(1:nsym))
+  %subplot(412); plot(sym2m(1:nsym))
+  %subplot(413); plot(sym3m(1:nsym))
+  %subplot(414); plot(sym4m(1:nsym))
+  plot((1:nsym),sym1m(1:nsym),(1:nsym),sym2m(1:nsym),(1:nsym),sym3m(1:nsym),(1:nsym),sym4m(1:nsym))
+  
+  [x iv] = max([sym1m; sym2m; sym3m; sym4m;]);
+  bits = zeros(1,length(iv*2));
+  figure(3);
+  hist(iv);
+  for i=1:length(iv)
+    bits(1+(i-1)*2:i*2) = [[0 0];[0 1];[1 0];[1 1]](iv(i),(1:2));
+  end
+endfunction
+
+function dat = bitreps(in,M)
+  dat = zeros(1,length(in)*M);
+  for i=1:length(in)
+    dat(1+(i-1)*M:i*M) = in(i);
+  end
+endfunction
+
+% Minimal Running Disparity, 4 symbol encoder
+% This is a simple 1 bit to 1 symbol encoding for 4fsk modems built
+% on old fashoned FM radios.
+function syms = mrd4(bits)
+  syms = zeros(1,length(bits));
+  rd=0;
+  lastsym=0;
+  for n = (1:length(bits))
+    bit = bits(n);
+    sp = [1 3](bit+1); %Map a bit to a +1 or +3
+    [x,v] = min(abs([rd+sp rd-sp])); %Select +n or -n, whichever minimizes disparity
+    ssel = [sp -sp](v);
+    if(ssel == lastsym)ssel = -ssel;endif %never run 2 of the same syms in a row
+    syms(n) = ssel; %emit the symbol
+    rd = rd + ssel; %update running disparity
+    lastsym = ssel; %remember this symbol for next time
+  end
+endfunction
+
+% Minimal Running Disparity, 8 symbol encoder
+% This is a simple 2 bit to 1 symbol encoding for 8fsk modems built
+% on old fashoned FM radios.
+function syms = mrd8(bits)
+  bitlen = length(bits);
+  if mod(bitlen,2) == 1
+    bits = [bits 0]
+  endif
+
+  syms = zeros(1,length(bits)*.5);
+  rd=0;
+  lastsym=0;
+  for n = (1:2:length(bits))
+    bit = (bits(n)*2)+bits(n+1);
+    sp = [1 3 7 5](bit+1); %Map a bit to a +1 or +3
+    [x,v] = min(abs([rd+sp rd-sp])); %Select +n or -n, whichever minimizes disparity
+    ssel = [sp -sp](v);
+    if(ssel == lastsym)ssel = -ssel;endif %never run 2 of the same syms in a row
+    syms((n+1)/2) = ssel; %emit the symbol
+    rd = rd + ssel; %update running disparity
+    lastsym = ssel; %remember this symbol for next time
+  end
+endfunction
+
+% "Manchester 4" encoding
+function syms = mane4(bits)
+    syms = zeros(1,floor(bits/2)*2);
+    for n = (1:2:length(bits))
+      bit0 = bits(n);
+      bit1 = bits(n+1);
+      sel = 2*bit0+bit1+1;
+      syms(n:n+1) = [[3 -3];[-3 3];[1 -1];[-1 1]]( sel,(1:2) );
+    end
+endfunction
+
+function out = fold_sum(in,l)
+  sublen = floor(length(in)/l);
+  out = zeros(1,l);
+  for i=(1:sublen)
+    v = in(1+(i-1)*l:i*l);
+    out = out + v;
+  end
+endfunction
+
+function [bits err rxphi] = fsk4_demod_fmrid(fsk4_states, rx, enable_fine_timing = 0)
+  %Demodulate fsk signal with an analog fm demod
+  rxd = analog_fm_demod(fsk4_states.fm_states,rx);
+
+  M = fsk4_states.M;
+  verbose = fsk4_states.verbose;
+  %This is the ideal fine timing, assuming the same offset in nfbert
+  fine_timing = 61;
+
+  %This is meant to be adjusted by the fine timing estimator. comment out for
+  %ideal timing
+  %fine_timing = 59;
+  
+  %RRC filter to get rid of some of the noise
+  rxd = filter(fsk4_states.rx_filter, 1, rxd);
+
+  %Try and figure out where sampling should happen over 30 symbol periods
+  diffsel = fold_sum(abs(diff( rxd(3001:3001+(M*30)) )),10);
+  if verbose
+    figure(11);
+    plot(diffsel);
+    title("Fine timing estimation");
+  endif
+
+  %adjust fine timing
+  [v iv] = min(diffsel);
+  if enable_fine_timing
+    fine_timing = 59 + iv;
+  endif
+  rxphi = iv;
+
+  %sample symbols
+  sym = rxd(fine_timing:M:length(rxd));
+
+  if verbose
+    figure(4)
+    plot(sym(1:1000));
+    title("Sampled symbols")
+  endif
+  %eyediagram(afsym,2);
+  % Demod symbol map. I should probably figure a better way to do this.
+  % After sampling, the furthest symbols tend to be distributed about .80
+
+  % A little cheating to demap the symbols
+  % Take a histogram of the sampled symbols, find the center of the largest distribution,
+  % and correct the symbol map to match it
+  [a b] = hist(abs(sym),50);
+  [a ii] = max(a);
+  %grmax = abs(b(ii));
+  %grmax = (grmax<.65)*.65 + (grmax>=.65)*grmax;
+  grmax = .84;
+  dmsyms = rot90(fsk4_states.symmap*grmax)
+  (dmsyms(2)+dmsyms(1))/2
+
+  if verbose
+    figure(2)
+    hist(abs(sym),200);
+    title("Sampled symbol histogram")
+  endif
+
+  %demap the symbols
+  [err, symout] = min(abs(sym-dmsyms));
+  
+  if verbose
+    figure(3)
+    hist(symout);
+    title("De-mapped symbols")
+  endif
+
+  bits = zeros(1,length(symout)*2);
+  %Translate symbols back into bits
+
+  for i=1:length(symout)
+    bits(1+(i-1)*2:i*2) = [[1 1];[1 0];[0 1];[0 0]](symout(i),(1:2));
+  end
+endfunction
+
+% Frequency response of the DMR raised cosine filter 
+% from ETSI TS 102 361-1 V2.2.1 page 111
+dmr.tx_filt_resp = @(f) sqrt(1.0*(f<=1920) - cos((pi*f)/1920).*1.0.*(f>1920 & f<=2880));
+dmr.rx_filt_resp = dmr.tx_filt_resp;
+dmr.max_dev = 1944;
+dmr.syms = [-1944 -648 1944 648];
+dmr.rs = 4800;
+dmr.no_filter = 0;
+dmr.demod_fx = @fsk4_demod_fmrid;
+global dmr_info = dmr;
+
+
+% No-filter 4FSK 'ideal' parameters
+nfl.tx_filt_resp = @(f) 1;
+nfl.rx_filt_resp = nfl.tx_filt_resp;
+nfl.max_dev = 7200;
+%nfl.syms = [-3600 -1200 1200 3600];
+nfl.syms = [-7200,-2400,2400,7200];
+nfl.rs = 4800;
+nfl.no_filter = 1;
+nfl.demod_fx = @fsk4_demod_thing;
+global nflt_info = nfl;
+
+%Some parameters for the NXDN filters
+nxdn_al = .2;
+nxdn_T = 416.7e-6;
+nxdn_fl = ((1-nxdn_al)/(2*nxdn_T));
+nxdn_fh = ((1+nxdn_al)/(2*nxdn_T));
+
+%Frequency response of the NXDN filters
+% from NXDN TS 1-A V1.3 page 13
+% Please note : NXDN not fully implemented or tested
+nxdn_H = @(f) 1.0*(f<nxdn_fl) + cos( (nxdn_T/(4*nxdn_al))*(2*pi*f-(pi*(1-nxdn_al)/nxdn_T)) ).*(f<=nxdn_fh & f>nxdn_fl);
+nxdn_P = @(f) (f<=nxdn_fh & f>0).*((sin(pi*f*nxdn_T))./(.00001+(pi*f*nxdn_T))) + 1.0*(f==0);
+nxdn_D = @(f) (f<=nxdn_fh & f>0).*((pi*f*nxdn_T)./(.00001+sin(pi*f*nxdn_T))) + 1.0*(f==0);
+
+nxdn.tx_filt_resp = @(f) nxdn_H(f).*nxdn_P(f);
+nxdn.rx_filt_resp = @(f) nxdn_H(f).*nxdn_D(f);
+nxdn.rs = 4800;
+nxdn.max_dev = 1050;
+nxdn.no_filter = 0;
+nxdn.syms = [-1050,-350,350,1050];
+nxdn.demod_fx = @fsk4_demod_fmrid;
+global nxdn_info = nxdn;
+
+% Bit error rate test ----------------------------------------------------------
+% Params - aEsNodB - EbNo in decibels
+%        - timing_offset - how far the fine timing is offset
+%        - bitcnt - how many bits to check
+%        - demod_fx - demodulator function
+% Returns - ber - teh measured BER
+%         - thrcoh - theory BER of a coherent demod
+%         - thrncoh - theory BER of non-coherent demod
+function [ber thrcoh thrncoh] = nfbert(aEsNodB,modem_config, bitcnt=100000, timing_offset = 10)
+
+  rand('state',1); 
+  randn('state',1);
+  
+  %How many bits should this test run?
+  bitcnt = 120000;
+  
+  test_bits = [zeros(1,100) rand(1,bitcnt)>.5]; %Random bits. Pad with zeros to prime the filters
+  fsk4_states.M = 1;
+  fsk4_states = fsk4_init(fsk4_states,modem_config);
+  
+  %Set this to 0 to cut down on the plotting
+  fsk4_states.verbose = 1; 
+  Fs = fsk4_states.Fs;
+  Rb = fsk4_states.Rs * 2;  % Multiply symbol rate by 2, since we have 2 bits per symbol
+  
+  tx = fsk4_mod(fsk4_states,test_bits);
+
+  %add noise here
+  %shamelessly copied from gmsk.m
+  EsNo = 10^(aEsNodB/10);
+  EbNo = EsNo
+  variance = Fs/(Rb*EbNo);
+  nsam = length(tx);
+  noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+  rx    = tx*exp(j*pi/2) + noise;
+
+  rx    = rx(timing_offset:length(rx));
+
+  rx_bits = modem_config.demod_fx(fsk4_states,rx);
+  ber = 1;
+  
+  %thing to account for offset from input data to output data
+  %No preamble detection yet
+  ox = 1;
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),test_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  printf("\ncoarse timing: %d nerr: %d\n", offset, best_nerr);
+
+  % Coherent BER theory
+  thrcoh = erfc(sqrt(EbNo));
+
+  % non-coherent BER theory calculation
+  % It was complicated, so I broke it up
+
+  ms = 4;
+  ns = (1:ms-1);
+  as = (-1).^(ns+1);
+  bs = (as./(ns+1));
+  
+  cs = ((ms-1)./ns);
+
+  ds = ns.*log2(ms);
+  es = ns+1;
+  fs = exp( -(ds./es)*EbNo );
+  
+  thrncoh = ((ms/2)/(ms-1)) * sum(bs.*((ms-1)./ns).*exp( -(ds./es)*EbNo ));
+
+endfunction
+
+% RX fine timing estimation playground
+function rxphi = fine_ex(timing_offset = 1)
+  global dmr_info;
+  global nxdn_info;
+  global nflt_info;
+
+  rand('state',1); 
+  randn('state',1);
+
+  bitcnt = 12051;
+  test_bits = [zeros(1,100) rand(1,bitcnt)>.5]; %Random bits. Pad with zeros to prime the filters
+  t_vec = [0 0 1 1];
+  %test_bits = repmat(t_vec,1,ceil(24000/length(t_vec)));
+
+
+  fsk4_states.M = 1;
+  fsk4_states = fsk4_init(fsk4_states,dmr_info);
+  Fs = fsk4_states.Fs;
+  Rb = fsk4_states.Rs * 2;  %Multiply symbol rate by 2, since we have 2 bits per symbol
+  
+  tx = fsk4_mod(fsk4_states,test_bits);
+
+  %add noise here
+  %shamelessly copied from gmsk.m
+  %EsNo = 10^(aEsNodB/10);
+  %EbNo = EsNo
+  %variance = Fs/(Rb*EbNo);
+  %nsam = length(tx);
+  %noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+  %rx    = tx*exp(j*pi/2) + noise;
+  rx    = tx;
+  rx    = rx(timing_offset:length(rx));
+
+  [rx_bits biterr rxphi] = fsk4_demod_fmrid(fsk4_states,rx);
+  ber = 1;
+  
+  %thing to account for offset from input data to output data
+  %No preamble detection yet
+  ox = 1;
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),test_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  printf("\ncoarse timing: %d nerr: %d\n", offset, best_nerr);
+
+endfunction
+
+%Run over a wide range of offsets and make sure fine timing makes sense
+function fsk4_rx_phi(socket)
+  %pkg load parallel
+  offrange = [100:200];
+  [a b c phi] = pararrayfun(1.25*nproc(),@nfbert,10*length(offrange),offrange);
+  
+  close all;
+  figure(1);
+  clf;
+  plot(offrange,phi);
+endfunction
+
+
+% Run this function to compare the theoretical 4FSK modem performance
+% with our DMR modem simulation
+
+function fsk4_ber_curves
+  global dmr_info;
+  global nxdn_info;
+  global nflt_info;
+
+  EbNodB = 1:20;
+  bers_tco = bers_real = bers_tnco = bers_idealsim = ones(1,length(EbNodB));
+
+  %vectors of the same param to pass into pararrayfun
+  dmr_infos = repmat(dmr_info,1,length(EbNodB));
+  nflt_infos = repmat(nflt_info,1,length(EbNodB));
+  thing = @fsk4_demod_thing;
+
+  % Lovely innovation by Brady to use all cores and really speed up the simulation
+
+  %try
+    pkg load parallel
+    bers_idealsim = pararrayfun(floor(1.25*nproc()),@nfbert,EbNodB,nflt_infos);
+    [bers_real,bers_tco,bers_tnco] = pararrayfun(floor(1.25*nproc()),@nfbert,EbNodB,dmr_infos);
+  %catch
+  %  printf("You should install package parallel. It'll make this run way faster\n");
+  %  for ii=(1:length(EbNodB));
+      %[bers_real(ii),bers,tco(ii),bers_tnco(ii)] = nfbert(EbNodB(ii));
+  %  end
+  %end_try_catch
+
+  close all
+  figure(1);
+  clf;
+  semilogy(EbNodB, bers_tnco,'r;4FSK non-coherent theory;')
+  hold on;
+
+  semilogy(EbNodB, bers_tco,'b;4FSK coherent theory;')
+  semilogy(EbNodB, bers_real ,'g;4FSK DMR simulation;')
+  semilogy(EbNodB, bers_idealsim, 'v;FSK4 Ideal Non-coherent simulation;')
+  hold off;
+  grid("minor");
+  axis([min(EbNodB) max(EbNodB) 1E-5 1])
+  legend("boxoff");
+  xlabel("Eb/No (dB)");
+  ylabel("Bit Error Rate (BER)")
+
+endfunction
+
+
+
+
+
+
+
+
diff --git a/codec2/branches/0.7/octave/fsk_basic.m b/codec2/branches/0.7/octave/fsk_basic.m
new file mode 100644 (file)
index 0000000..1b06cd8
--- /dev/null
@@ -0,0 +1,60 @@
+% fsk_basic.m
+% David Rowe 30 sep 2016
+%
+% Basic non-coherence FSK modem simulation to illustrate principles
+% and compare to ideal
+
+rand('seed',1);
+randn('seed',1);
+
+Fs = 9600;     % sample rate
+f1 = 1200;
+f2 = 2400;
+Rs = 1200;     % symbol rate
+Ts = Fs/Rs;    % length of each symbol in samples
+Nbits = 10000;
+EbNodB = 9;    
+
+tx_bits = round(rand(1,Nbits));
+
+% continuous phase FSK modulator
+
+w1 = 2*pi*f1/Fs;
+w2 = 2*pi*f2/Fs;
+tx_phase = 0;
+tx = zeros(1,Ts*Nbits);
+
+for i=1:Nbits
+  for k=1:Ts
+    if tx_bits(i)
+      tx_phase += w2;
+    else
+      tx_phase += w1;
+    end
+    tx((i-1)*Ts+k) = exp(j*tx_phase);
+  end
+end
+
+% AWGN channel noise
+
+EbNo = 10^(EbNodB/10);
+variance = Fs/(Rs*EbNo);
+noise = sqrt(variance/2)*(randn(1,Nbits*Ts) + j*randn(1,Nbits*Ts));
+rx = tx + noise;
+
+% integrate and dump demodulator
+
+rx_bits = zeros(1,Nbits);
+for i=1:Nbits
+  arx_symb = rx((i-1)*Ts + (1:Ts));
+  filt1 = sum(exp(-j*w1*(1:Ts)) .* arx_symb);
+  filt2 = sum(exp(-j*w2*(1:Ts)) .* arx_symb);
+  rx_bits(i) = filt2 > filt1;
+end
+
+Nerrors = sum(xor(tx_bits, rx_bits));
+ber = Nerrors/Nbits;
+printf("EbNodB: %4.1f  Nerrors: %d BER: %1.3f\n", EbNodB, Nerrors, ber);
+
+
+
diff --git a/codec2/branches/0.7/octave/fsk_cont_phase.m b/codec2/branches/0.7/octave/fsk_cont_phase.m
new file mode 100644 (file)
index 0000000..d6b4e9d
--- /dev/null
@@ -0,0 +1,85 @@
+% fsk_cont_phase.m
+% David Rowe Feb 2016
+%
+% Looking at tx spectrum of FSK signal with and without continuous phase in the
+% modulator.
+
+1;
+
+function tx  = fsk_mod(states, tx_bits)
+
+    M  = states.M;
+    Ts = states.Ts;
+    Fs = states.Fs;
+    ftx = states.ftx;
+    phase_cont = states.phase_cont;
+
+    num_bits = length(tx_bits);
+    num_symbols = num_bits;
+    tx = zeros(states.Ts*num_symbols,1);
+    tx_phase = 0;
+    s = 1;
+
+    for i=1:num_bits
+
+      % map bits to tone number
+
+      tone = tx_bits(i) + 1;
+      if phase_cont
+        tx_phase_vec = tx_phase + (1:Ts)*2*pi*ftx(tone)/Fs;
+        tx_phase = tx_phase_vec(Ts) - floor(tx_phase_vec(Ts)/(2*pi))*2*pi;
+      else
+        tx_phase_vec = (1:Ts)*2*pi*ftx(tone)/Fs;
+      end
+
+      tx((s-1)*Ts+1:s*Ts) = 2.0*cos(tx_phase_vec);
+      s++;
+      %printf("phase_cont: %d tx_phase_vec(Ts): %f\n", phase_cont, tx_phase_vec(Ts));
+
+    end
+endfunction
+
+
+states.Fs  = 8000;
+states.Rs  = 100;
+states.Ts  = states.Fs/states.Rs;
+states.M   = 2;
+states.ftx = [1200 1305];  % need to choose these carefullto get disc phase
+
+Nbits = 1024;
+
+tx_bits = rand(1,Nbits) > 0.5;
+%tx_bits = [0 1 0];
+
+states.phase_cont = 1;
+tx_cont  = fsk_mod(states, tx_bits);
+
+states.phase_cont = 0;
+tx_disc  = fsk_mod(states, tx_bits);
+
+figure(1)
+clf
+plot(tx_cont(1:states.Ts*4))
+hold on;
+plot(tx_disc(1:states.Ts*4),'g')
+hold off;
+title('Time Domain')
+
+figure(2)
+clf
+subplot(211)
+Tx_cont = fft(tx_cont);
+Tx_cont_dB = 20*log10(abs(Tx_cont));
+plot(Tx_cont_dB)
+axis([1 length(Tx_cont_dB)/2 0 100]);
+grid
+title('Cont Phase Spectra')
+
+Tx_disc = fft(tx_disc);
+Tx_disc_dB = 20*log10(abs(Tx_disc));
+subplot(212)
+plot(Tx_disc_dB,'g')
+axis([1 length(Tx_cont_dB)/2 0 100]);
+grid
+title('Disc Cont Phase Spectra')
diff --git a/codec2/branches/0.7/octave/fsk_eme.m b/codec2/branches/0.7/octave/fsk_eme.m
new file mode 100644 (file)
index 0000000..47e57a2
--- /dev/null
@@ -0,0 +1,377 @@
+% fsk_eme.m
+% David Rowe July 2017
+%
+% FSK modem for digital voice over 1296 MHz Earth-Moon-Earth (EME) links
+
+fsk_lib;
+
+function run_sim(frames = 10, EbNodB = 100)
+  Fs = 8000; Rs = 8; M = 16; Fsep = 50;
+
+  timing_offset = 0.0; % see resample() for clock offset below
+  fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+  df     = 0;          % tx tone freq drift in Hz/s
+  dA     = 1;          % amplitude imbalance of tones (note this affects Eb so not a gd idea)
+
+  more off
+  rand('state',1); 
+  randn('state',1);
+
+  states = fsk_init(Fs, 50, M);
+
+  states.ftx = 1000 + Fsep*(-M/2:M/2-1);
+
+  % ----------------------------------------------------------------------
+
+  states.verbose = 0x1;
+  M = states.M;
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  nbit = states.nbit;
+  Fs = states.Fs;
+  states.df(1:M) = df;
+  states.dA(1:M) = dA;
+
+  % optional noise.  Useful for testing performance of waveforms from real world modulators
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rs*EbNo*states.bitspersymbol);
+
+  % test frame of bits, which we repeat for convenience when BER testing
+
+  states.ntestframebits = states.nbit;
+  test_frame = round(rand(1, states.ntestframebits));
+  tx_bits = [];
+  for i=1:frames+1
+    tx_bits = [tx_bits test_frame];
+  end
+
+
+  tx = fsk_mod(states, tx_bits);
+
+  %tx = resample(tx, 1000, 1001); % simulated 1000ppm sample clock offset
+
+  if fading
+     ltx = length(tx);
+     tx = tx .* (1.1 + cos(2*pi*2*(0:ltx-1)/Fs))'; % min amplitude 0.1, -20dB fade, max 3dB
+  end
+
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise;
+  printf("SNRdB meas: %4.1f\n", 10*log10(var(tx)/var(noise)));
+
+  % dump simulated rx file
+
+  g = 1000; 
+  ftx=fopen("fsk_horus_tx.raw","wb"); txg = tx*g; fwrite(ftx, txg, "short"); fclose(ftx);
+  frx=fopen("fsk_horus_rx.raw","wb"); rxg = rx*g; fwrite(frx, rxg, "short"); fclose(frx);
+
+  timing_offset_samples = round(timing_offset*states.Ts);
+  st = 1 + timing_offset_samples;
+  rx_bits_buf = zeros(1,nbit+states.ntestframebits);
+  x_log = [];
+  timing_nl_log = [];
+  norm_rx_timing_log = [];
+  f_int_resample_log = [];
+  f_log = [];
+  EbNodB_log = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+
+  % main loop ---------------------------------------------------------------
+
+  run_frames = floor(length(rx)/N)-1;
+  for f=1:run_frames
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    en = st + states.nin - 1;
+
+    if en < length(rx) % due to nin variations its possible to overrun buffer
+      sf = rx(st:en);
+      st += nin;
+
+      % demodulate to stream of bits
+
+      states = est_freq(states, sf, states.M);
+      states.f = states.ftx;
+      [rx_bits states] = fsk_demod(states, sf);
+
+      rx_bits_buf(1:states.ntestframebits) = rx_bits_buf(nbit+1:states.ntestframebits+nbit);
+      rx_bits_buf(states.ntestframebits+1:states.ntestframebits+nbit) = rx_bits;
+      %rx_bits_buf(1:nbit) = rx_bits_buf(nbit+1:2*nbit);
+      %rx_bits_buf(nbit+1:2*nbit) = rx_bits;
+
+      rx_bits_log = [rx_bits_log rx_bits];
+      rx_bits_sd_log = [rx_bits_sd_log states.rx_bits_sd];
+
+      norm_rx_timing_log = [norm_rx_timing_log states.norm_rx_timing];
+      x_log = [x_log states.x];
+      timing_nl_log = [timing_nl_log states.timing_nl];
+      f_int_resample_log = [f_int_resample_log abs(states.f_int_resample(:,:))];
+      f_log = [f_log; states.f];
+      EbNodB_log = [EbNodB_log states.EbNodB];
+
+      states = ber_counter(states, test_frame, rx_bits_buf);
+    end
+  end
+
+  % print stats, count errors, decode packets  ------------------------------------------
+
+  printf("frames: %d EbNo: %3.2f Tbits: %d Terrs: %d BER %4.3f\n", frames, EbNodB, states.Tbits,states. Terrs, states.Terrs/states.Tbits);
+
+  figure(1);
+  plot(f_int_resample_log','+')
+  hold off;
+
+  figure(2)
+  clf
+  m = max(abs(x_log));
+  plot(x_log,'+')
+  axis([-m m -m m])
+  title('fine timing metric')
+
+  figure(3)
+  clf
+  subplot(211)
+  plot(norm_rx_timing_log);
+  axis([1 run_frames -1 1])
+  title('norm fine timing')
+  subplot(212)
+  plot(states.nerr_log)
+  title('num bit errors each frame')
+
+  figure(4)
+  clf
+  subplot(211)
+  one_sec_rx = rx(1:min(Fs,length(rx)));
+  plot(one_sec_rx)
+  title('rx signal at demod input')
+  subplot(212)
+  plot(abs(fft(one_sec_rx)))
+
+  figure(5)
+  clf
+  plot(f_log,'+')
+  title('tone frequencies')
+  axis([1 run_frames 0 Fs/2])
+
+  figure(6)
+  clf
+  plot(EbNodB_log);
+  title('Eb/No estimate')
+
+  figure(7)
+  clf
+  subplot(211)
+  X = abs(fft(timing_nl_log));
+  plot(X(1:length(X)/2))
+  subplot(212)
+  plot(abs(timing_nl_log(1:100)))
+
+ endfunction
+
+
+% demodulate a file of 8kHz 16bit short samples --------------------------------
+
+function rx_bits_log = demod_file(filename, test_frame_mode, noplot=0, EbNodB=100)
+  fin = fopen(filename,"rb"); 
+  more off;
+
+  %states = fsk_horus_init(96000, 1200);
+
+  if test_frame_mode == 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 100, 2);
+    uwstates = fsk_horus_init_rtty_uw(states);
+    states.ntestframebits = states.nbits;
+  end
+                               
+  if test_frame_mode == 5
+    % horus binary config ---------------------
+    states = fsk_horus_init(8000, 50, 4);
+    uwstates = fsk_horus_init_binary_uw;
+    states.ntestframebits = states.nbits;
+  end
+
+  states.verbose = 0x1 + 0x8;
+
+  if test_frame_mode == 6
+    % Horus high speed config --------------
+    states = fsk_horus_init_hbr(9600, 8, 1200, 2, 16);
+    states.tx_bits_file = "horus_high_speed.bin";
+    states.verbose += 0x4;
+    ftmp = fopen(states.tx_bits_file, "rb"); test_frame = fread(ftmp,Inf,"char")'; fclose(ftmp);
+    states.ntestframebits = length(test_frame);
+    printf("length test frame: %d\n", states.ntestframebits);
+  end
+
+  if test_frame_mode == 7
+    % 800XA 4FSK modem --------------
+    states = fsk_horus_init_hbr(8000, 10, 400, 4, 256);
+    states.tx_bits_file = "horus_high_speed.bin";
+    states.verbose += 0x4;
+    ftmp = fopen(states.tx_bits_file, "rb"); test_frame = fread(ftmp,Inf,"char")'; fclose(ftmp);
+    states.ntestframebits = length(test_frame);
+    printf("length test frame: %d\n", states.ntestframebits);
+  end
+
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  nbit = states.nbit;
+
+  frames = 0;
+  rx = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+  norm_rx_timing_log = [];
+  f_int_resample_log = [];
+  EbNodB_log = [];
+  ppm_log = [];
+  f_log = [];
+  rx_bits_buf = zeros(1,nbit + states.ntestframebits);
+
+  % optional noise.  Useful for testing performance of waveforms from real world modulators
+
+  EbNo = 10^(EbNodB/10);
+  ftmp = fopen(filename,"rb"); s = fread(ftmp,Inf,"short"); fclose(ftmp); tx_pwr = var(s);
+  variance = (tx_pwr/2)*states.Fs/(states.Rs*EbNo*states.bitspersymbol);
+
+  % First extract raw bits from samples ------------------------------------------------------
+
+  printf("demod of raw bits....\n");
+
+  finished = 0;
+  while (finished == 0)
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    [sf count] = fread(fin, nin, "short");
+    rx = [rx; sf];
+    
+    % add optional noise
+
+    if count
+      noise = sqrt(variance)*randn(count,1);
+      sf += noise;
+    end
+
+    if count == nin
+      frames++;
+
+      % demodulate to stream of bits
+
+      states = est_freq(states, sf, states.M);
+      %states.f = [1450 1590 1710 1850];
+      [rx_bits states] = fsk_horus_demod(states, sf);
+
+      rx_bits_buf(1:states.ntestframebits) = rx_bits_buf(nbit+1:states.ntestframebits+nbit);
+      rx_bits_buf(states.ntestframebits+1:states.ntestframebits+nbit) = rx_bits;
+
+      rx_bits_log = [rx_bits_log rx_bits];
+      rx_bits_sd_log = [rx_bits_sd_log states.rx_bits_sd];
+      norm_rx_timing_log = [norm_rx_timing_log states.norm_rx_timing];
+      f_int_resample_log = [f_int_resample_log abs(states.f_int_resample)];
+      EbNodB_log = [EbNodB_log states.EbNodB];
+      ppm_log = [ppm_log states.ppm];
+      f_log = [f_log; states.f];
+
+      if test_frame_mode == 1
+        states = ber_counter(states, test_frame, rx_bits_buf);
+        if states.ber_state == 1
+          states.verbose = 0;
+        end
+      end
+      if test_frame_mode == 6
+        states = ber_counter_packet(states, test_frame, rx_bits_buf);
+      end
+     else      
+      finished = 1;
+    end
+  end
+  fclose(fin);
+
+  if noplot == 0
+    printf("plotting...\n");
+
+    figure(1);
+    plot(f_log);
+    hold off;
+
+    figure(2);
+    plot(f_int_resample_log','+')
+
+    figure(3)
+    clf
+    subplot(211)
+    plot(norm_rx_timing_log)
+    axis([1 frames -0.5 0.5])
+    title('norm fine timing')
+    grid
+    subplot(212)
+    plot(states.nerr_log)
+    title('num bit errors each frame')
+    figure(4)
+    clf
+    plot(EbNodB_log);
+    title('Eb/No estimate')
+
+    figure(5)
+    clf
+    rx_nowave = rx(1000:length(rx));
+    subplot(211)
+    plot(rx_nowave(1:states.Fs));
+    title('input signal to demod (1 sec)')
+    xlabel('Time (samples)');
+    axis([1 states.Fs -35000 35000])
+
+    % normalise spectrum to 0dB full scale with a 32767 sine wave input
+
+    subplot(212)
+    RxdBFS = 20*log10(abs(fft(rx_nowave(1:states.Fs)))) - 20*log10((states.Fs/2)*32767);
+    plot(RxdBFS)
+    axis([1 states.Fs/2 -80 0])
+    xlabel('Frequency (Hz)');
+
+    figure(6);
+    clf
+    plot(ppm_log)
+    title('Sample clock (baud rate) offset in PPM');
+  end
+
+  if (test_frame_mode == 1) || (test_frame_mode == 6)
+    printf("frames: %d Tbits: %d Terrs: %d BER %4.3f EbNo: %3.2f\n", frames, states.Tbits,states. Terrs, states.Terrs/states.Tbits, mean(EbNodB_log));
+  end
+
+  % we can decode both protocols at the same time
+
+  if (test_frame_mode == 4) || (test_frame_mode == 5)
+    extract_and_print_rtty_packets(states, rx_bits_log, rx_bits_sd_log)
+    corr_log = extract_and_decode_binary_packets(states, rx_bits_log);
+
+    figure(8);
+    clf
+    plot(corr_log);
+    hold on;
+    plot([1 length(corr_log)],[states.binary.uw_thresh states.binary.uw_thresh],'g');
+    hold off;
+    title('UW correlation');
+  end
+
+endfunction
+
+
+% Start simulations here -------------------------------------------------------------
+
+more off; format;
+
+%run_sim(1, 2, 100, 9);
+run_sim(10, 20);
diff --git a/codec2/branches/0.7/octave/fsk_horus.m b/codec2/branches/0.7/octave/fsk_horus.m
new file mode 100644 (file)
index 0000000..eb44fda
--- /dev/null
@@ -0,0 +1,803 @@
+% fsk_horus.m
+% David Rowe 10 Oct 2015
+%
+% Project Horus High Altitude Balloon (HAB) FSK demodulator
+% See blog write up "All your modems are belong to us"
+%   http://www.rowetel.com/?p=4629
+
+
+fsk_lib;
+
+
+function states = fsk_horus_init(Fs,Rs,M=2)
+
+  states = fsk_init(Fs,Rs,M);
+  states.rtty = fsk_horus_init_rtty_uw(states);
+  states.binary = fsk_horus_init_binary_uw;
+
+  % Freq. estimator limits - keep these narrow to stop errors with low SNR 4FSK
+
+  states.fest_fmin = 800;
+  states.fest_fmax = 2500;
+  states.fest_min_spacing = 200;
+
+endfunction
+
+
+% init rtty protocol specifc states
+
+function rtty = fsk_horus_init_rtty_uw(states)
+  % Generate unque word that correlates against the ASCII "$$$$$" that
+  % is at the start of each frame.
+  % $ -> 36 decimal -> 0 1 0 0 1 0 0 binary 
+
+  dollar_bits = fliplr([0 1 0 0 1 0 0]);
+  mapped_db = 2*dollar_bits - 1;
+  sync_bits = [1 1 0];
+  mapped_sb = 2*sync_bits - 1;
+  %mapped_sb = [ 0 0 0 ];
+
+  mapped = [mapped_db mapped_sb];
+  npad = rtty.npad = 3;     % one start and two stop bits between 7 bit ascii chars
+  nfield = rtty.nfield = 7; % length of ascii character field
+
+  rtty.uw = [mapped mapped mapped mapped mapped];
+  rtty.uw_thresh = length(rtty.uw) - 2; % allow a few bit errors when looking for UW
+  rtty.max_packet_len = 1000;
+endfunction
+
+
+% I think this is the binary protocol work from Jan 2016
+
+function binary = fsk_horus_init_binary_uw
+  % Generate 16 bit "$$" unique word that is at the front of every horus binary
+  % packet
+
+  dollar_bits = [0 0 1 0 0 1 0 0];
+  mapped_db = 2*dollar_bits - 1;
+
+  binary.uw = [mapped_db mapped_db];
+  binary.uw_thresh = length(binary.uw)-2;   % no bit errors when looking for UW
+
+  binary.max_packet_len = 360;
+endfunction
+
+
+% Look for unique word and return index of first UW bit, or -1 if no
+% UW found Sometimes there may be several matches, returns the
+% position of the best match to UW.
+
+function [uw_start best_corr corr] = find_uw(states, start_bit, rx_bits)
+  uw = states.uw;
+
+  mapped_rx_bits = 2*rx_bits - 1;
+  best_corr = 0;
+  uw_start = -1;
+  found_uw = 0;
+
+  % first first UW in buffer that exceeds threshold
+  
+  for i=start_bit:length(rx_bits) - length(uw)
+    corr(i)  = mapped_rx_bits(i:i+length(uw)-1) * uw';
+    if (found_uw == 0) && (corr(i) >= states.uw_thresh)
+      uw_start = i;
+      best_corr = corr;
+      found_uw = 1;
+    end
+  end
+
+endfunction
+
+
+% Extract ASCII string from a Horus frame of bits
+
+function [str crc_ok] = extract_ascii(states, rx_bits_buf, uw_loc)
+  nfield = states.nfield;
+  npad = states.npad;
+
+  str = []; str_dec = []; nstr = 0; ptx_crc = 1; rx_crc = "";
+  endpacket = 0;
+
+  st = uw_loc + length(states.uw);  % first bit of first char
+  en = uw_loc + states.max_packet_len - nfield;
+  %printf("\nst: %d en: %d len: %d\n", st, en, length(rx_bits_buf));
+
+  for i=st:nfield+npad:en
+    field = rx_bits_buf(i:i+nfield-1);
+    ch_dec = field * (2.^(0:nfield-1))';
+
+    % filter out unlikely characters that bit errors may introduce, and ignore \n
+
+    if (ch_dec > 31) && (ch_dec < 91)
+      str = [str char(ch_dec)];
+    else 
+      str = [str char(32)]; % space is "not sure"
+    end
+    nstr++;
+
+    % build up array for CRC16 check
+
+    if !endpacket && (ch_dec == 42)
+      endpacket = 1; 
+      rx_crc = crc16(str_dec);      % found a '*' so that's the end of the string for CRC calculations
+      ptx_crc = nstr+1;             % this is where the transmit CRC starts
+    end
+    if !endpacket
+      str_dec = [str_dec ch_dec];
+    end
+  end
+
+  if (ptx_crc+3) <= length(str)
+    tx_crc = str(ptx_crc:ptx_crc+3);
+    crc_ok = strcmp(tx_crc, rx_crc);
+  else
+    crc_ok = 0;
+  end
+
+  str = str(1:ptx_crc-2);
+
+endfunction
+
+
+% Use soft decision information to find bits most likely in error.  I think
+% this is some form of maximum likelihood decoding.
+
+function [str crc_ok rx_bits_log_flipped] = sd_bit_flipping(states, rx_bits_log, rx_bits_sd_log, st, en);
+
+  % force algorithm to ignore rs232 sync bits by marking them as "very likely", they have
+  % no input to crc algorithm
+
+  nfield = states.nfield;
+  npad = states.npad;
+  for i=st:nfield+npad:en
+    rx_bits_sd_log(i+nfield:i+nfield+npad-1) = 1E6;
+  end
+
+  % make a list of bits with smallest soft decn values
+
+  [dodgy_bits_mag dodgy_bits_index] = sort(abs(rx_bits_sd_log(st+length(states.uw):en)));
+  dodgy_bits_index += length(states.uw) + st - 1;
+  nbits = 6;
+  ntries = 2^nbits;
+  str = "";
+  crc_ok = 0;
+  
+  % try various combinations of these bits
+
+  for i=1:ntries-1
+    error_mask = zeros(1, length(rx_bits_log));
+    for b=1:nbits
+      x = bitget(i,b);
+      bit_to_flip = dodgy_bits_index(b);
+      error_mask(bit_to_flip) = x;
+      %printf("st: %d i: %d b: %d x: %d index: %d\n", st, i,b,x,bit_to_flip);
+    end
+    rx_bits_log_flipped = xor(rx_bits_log, error_mask);
+    [str_flipped crc_ok_flipped] = extract_ascii(states, rx_bits_log_flipped, st);
+    if crc_ok_flipped
+      %printf("Yayy we fixed a packet by flipping with pattern %d\n", i);
+      str = str_flipped;
+      crc_ok = crc_ok_flipped;
+    end
+  end
+endfunction
+
+
+% Extract as many ASCII packets as we can from a great big buffer of bits
+
+function extract_and_print_rtty_packets(states, rx_bits_log, rx_bits_sd_log)
+
+  % use UWs to delimit start and end of data packets
+
+  bit = 1;
+  nbits = length(rx_bits_log);
+  nfield = states.rtty.nfield;
+  npad = states.rtty.npad;
+
+  uw_loc = find_uw(states.rtty, bit, rx_bits_log, states.verbose);
+  
+  while (uw_loc != -1)
+
+    if (uw_loc + states.rtty.max_packet_len) < nbits
+      % Now start picking out 7 bit ascii chars from frame.  It has some
+      % structure so we can guess where fields are.  I hope we don't get
+      % RS232 idle bits stuck into it anywhere, ie "bit fields" don't
+      % change dynamically.
+
+      % dump msg bits so we can use them as a test signal
+      %msg = rx_bits_log(st:uw_loc-1);
+      %save -ascii horus_msg.txt msg
+
+      % simulate bit error for testing
+      %rx_bits_log(st+200) = xor(rx_bits_log(st+100),1);
+      %rx_bits_sd_log(st+100) = 0;
+      
+      [str crc_ok] = extract_ascii(states.rtty, rx_bits_log, uw_loc);
+
+      if crc_ok == 0
+        [str_flipped crc_flipped_ok rx_bits_log] = sd_bit_flipping(states.rtty, rx_bits_log, rx_bits_sd_log, uw_loc, uw_loc+states.rtty.max_packet_len); 
+      end
+
+      % update memory of previous packet, we use this to guess where errors may be
+      if crc_ok || crc_flipped_ok
+        states.prev_pkt = rx_bits_log(uw_loc+length(states.rtty.uw):uw_loc+states.rtty.max_packet_len);
+      end
+
+      if crc_ok
+        str = sprintf("%s CRC OK", str);
+      else
+        if crc_flipped_ok
+          str = sprintf("%s fixed", str_flipped);
+        else
+          str = sprintf("%s CRC BAD", str);
+        end
+      end
+      printf("%s\n", str);
+    end
+
+    % look for next packet
+
+    bit = uw_loc + length(states.rtty.uw);
+    uw_loc = find_uw(states.rtty, bit, rx_bits_log, states.verbose);
+
+  endwhile
+endfunction
+
+% Extract as many binary packets as we can from a great big buffer of bits,
+% and send them to the C decoder for FEC decoding.
+% horus_l2 can be compiled a bunch of different ways.  You need to
+% compile with:
+%   codec2-dev/src$ gcc horus_l2.c -o horus_l2 -Wall -DDEC_RX_BITS -DHORUS_L2_RX
+
+function corr_log = extract_and_decode_binary_packets(states, rx_bits_log)
+  corr_log = [];
+
+  % use UWs to delimit start and end of data packets
+
+  bit = 1;
+  nbits = length(rx_bits_log);
+
+  [uw_loc best_corr corr] = find_uw(states.binary, bit, rx_bits_log, states.verbose);
+  corr_log = [corr_log corr];
+
+  while (uw_loc != -1)
+
+    if (uw_loc+states.binary.max_packet_len) < nbits
+      % printf("uw_loc: %d best_corr: %d\n", uw_loc, best_corr);
+
+      % OK we have a packet delimited by two UWs.  Lets convert the bit
+      % stream into bytes and save for decoding
+
+      pin = uw_loc;    
+      for i=1:45
+        rx_bytes(i) = rx_bits_log(pin:pin+7) * (2.^(7:-1:0))';
+        pin += 8;
+        %printf("%d 0x%02x\n", i, rx_bytes(i));
+      end
+
+      f=fopen("horus_rx_bits_binary.bin","wb");
+      fwrite(f, rx_bytes, "uchar");
+      fclose(f);
+
+      % optionally write packet to disk to use as horus_tx_bits_binary.txt
+      f=fopen("horus_rx_bits_binary.txt","wt");
+      for i=uw_loc:uw_loc+45*8-1
+        fprintf(f, "%d ", rx_bits_log(i));
+      end
+      fclose(f);
+
+      system("../src/horus_l2");  % compile instructions above
+    end
+
+    bit = uw_loc + length(states.binary.uw);
+    [uw_loc best_corr corr] = find_uw(states.binary, bit, rx_bits_log, states.verbose);
+    corr_log = [corr_log corr];
+   
+  endwhile
+endfunction
+
+% simulation of tx and rx side, add noise, channel impairments ----------------------
+%
+% test_frame_mode     Description
+% 1                   BER testing using known test frames
+% 2                   random bits
+% 3                   repeating sequence of all symbols
+% 4                   Horus RTTY
+% 5                   Horus Binary
+% 6                   Horus High Speed: A 8x oversampled modem, e.g. Fs=9600, Rs=1200
+%                     which is the same as Fs=921600 Rs=115200
+%                     Uses packet based BER counter
+
+function run_sim(test_frame_mode, M=2, frames = 10, EbNodB = 100)
+  timing_offset = 0.0; % see resample() for clock offset below
+  fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+  df     = 0;          % tx tone freq drift in Hz/s
+  dA     = 1;          % amplitude imbalance of tones (note this affects Eb so not a gd idea)
+
+  more off
+  rand('state',1); 
+  randn('state',1);
+
+  % ----------------------------------------------------------------------
+
+  % sm2000 config ------------------------
+  %states = fsk_horus_init(96000, 1200);
+  %states.f1_tx = 4000;
+  %states.f2_tx = 5200;
+
+  if test_frame_mode < 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 50, M);
+    %states = fsk_horus_init_hbr(8000, 10, 400, 4); % EME
+  end
+
+  if test_frame_mode == 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 100);
+    states.tx_bits_file = "horus_tx_bits_rtty.txt"; % Octave file of bits we FSK modulate
+  end
+                               
+  if test_frame_mode == 5
+    % horus binary config ---------------------
+    states = fsk_horus_init(8000, 50, 4);
+    states.tx_bits_file = "horus_tx_bits_binary.txt"; % Octave file of bits we FSK modulate
+  end
+
+  if test_frame_mode == 6
+    % horus high speed ---------------------
+    states = fsk_horus_init_hbr(9600, 8, 1200, 2, 16);
+    states.tx_bits_file = "horus_high_speed.bin";
+  end
+
+  % Tones must be at least Rs apart for ideal non-coherent FSK
+
+  #{
+  if states.M == 2
+    states.ftx = 1200 + [ 0 2*states.Rs ];
+  else
+    states.ftx = 1200 + 2*states.Rs*(1:4);
+    %states.ftx = 200 + states.Rs*(1:4); % EME
+  end
+  #}
+  states.ftx = 900 + 2*states.Rs*(1:states.M);
+
+  % ----------------------------------------------------------------------
+
+  states.verbose = 0x1;
+  M = states.M;
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  nbit = states.nbit;
+  Fs = states.Fs;
+  states.df(1:M) = df;
+  states.dA(1:M) = dA;
+
+  % optional noise.  Useful for testing performance of waveforms from real world modulators
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rs*EbNo*states.bitspersymbol);
+
+  % set up tx signal with payload bits based on test mode
+
+  if (test_frame_mode == 1)
+    % test frame of bits, which we repeat for convenience when BER testing
+    states.ntestframebits = states.nbit;
+    test_frame = round(rand(1, states.ntestframebits));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, states.nbit*(frames+1)));
+  end
+
+  if test_frame_mode == 3
+    % repeating sequence of all symbols
+    % great for initial test of demod if nothing else works, 
+    % look for this pattern in rx_bits
+    if M == 2
+       % ...10101...
+      tx_bits = zeros(1, states.nbit*(frames+1));
+      tx_bits(1:2:length(tx_bits)) = 1;
+    else
+      % repeat each possible 4fsk symbol
+      pattern = [0 0 0 1 1 0 1 1];
+      %pattern = [0 0 0 1 1 1 1 0];
+      nrepeats = states.nbit*(frames+1)/length(pattern);
+      tx_bits = [];
+      for b=1:nrepeats
+        tx_bits = [tx_bits pattern];
+      end   
+      %tx_bits = zeros(1, states.nbit*(frames+1));
+    end
+  end
+  if (test_frame_mode == 4) || (test_frame_mode == 5)
+
+    % load up a horus msg from disk and modulate that
+
+    test_frame = load(states.tx_bits_file);
+    ltf = length(test_frame);
+    ntest_frames = ceil((frames+1)*nbit/ltf);
+    tx_bits = [];
+    for i=1:ntest_frames
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+
+  if test_frame_mode == 6
+    states.verbose += 0x4;
+    ftmp = fopen(states.tx_bits_file, "rb"); test_frame = fread(ftmp,Inf,"char")'; fclose(ftmp);
+    states.ntestframebits = length(test_frame);
+    printf("length test frame: %d\n", states.ntestframebits);
+    %test_frame = rand(1,states.ntestframebits) > 0.5;
+
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+
+  tx = fsk_mod(states, tx_bits);
+
+  %tx = resample(tx, 1000, 1001); % simulated 1000ppm sample clock offset
+
+  if fading
+     ltx = length(tx);
+     tx = tx .* (1.1 + cos(2*pi*2*(0:ltx-1)/Fs))'; % min amplitude 0.1, -20dB fade, max 3dB
+  end
+
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise;
+  printf("SNRdB meas: %4.1f\n", 10*log10(var(tx)/var(noise)));
+
+  % dump simulated rx file
+
+  ftx=fopen("fsk_horus.raw","wb"); rxg = rx*1000; fwrite(ftx, rxg, "short"); fclose(ftx);
+
+  timing_offset_samples = round(timing_offset*states.Ts);
+  st = 1 + timing_offset_samples;
+  rx_bits_buf = zeros(1,nbit+states.ntestframebits);
+  x_log = [];
+  timing_nl_log = [];
+  norm_rx_timing_log = [];
+  f_int_resample_log = [];
+  f_log = [];
+  EbNodB_log = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+
+  % main loop ---------------------------------------------------------------
+
+  run_frames = floor(length(rx)/N)-1;
+  for f=1:run_frames
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    en = st + states.nin - 1;
+
+    if en < length(rx) % due to nin variations its possible to overrun buffer
+      sf = rx(st:en);
+      st += nin;
+
+      % demodulate to stream of bits
+
+      states = est_freq(states, sf, states.M);
+      states.f = 900 + 2*states.Rs*(1:states.M);
+      %states.f = [1200 1400 1600 1800];
+      [rx_bits states] = fsk_demod(states, sf);
+
+      rx_bits_buf(1:states.ntestframebits) = rx_bits_buf(nbit+1:states.ntestframebits+nbit);
+      rx_bits_buf(states.ntestframebits+1:states.ntestframebits+nbit) = rx_bits;
+      %rx_bits_buf(1:nbit) = rx_bits_buf(nbit+1:2*nbit);
+      %rx_bits_buf(nbit+1:2*nbit) = rx_bits;
+
+      rx_bits_log = [rx_bits_log rx_bits];
+      rx_bits_sd_log = [rx_bits_sd_log states.rx_bits_sd];
+
+      norm_rx_timing_log = [norm_rx_timing_log states.norm_rx_timing];
+      x_log = [x_log states.x];
+      timing_nl_log = [timing_nl_log states.timing_nl];
+      f_int_resample_log = [f_int_resample_log abs(states.f_int_resample(:,:))];
+      f_log = [f_log; states.f];
+      EbNodB_log = [EbNodB_log states.EbNodB];
+
+      if test_frame_mode == 1
+        states = ber_counter(states, test_frame, rx_bits_buf);
+      end
+      if test_frame_mode == 6
+        states = ber_counter_packet(states, test_frame, rx_bits_buf);
+      end
+   end
+  end
+
+  % print stats, count errors, decode packets  ------------------------------------------
+
+  if (test_frame_mode == 1) || (test_frame_mode == 6)
+    printf("frames: %d EbNo: %3.2f Tbits: %d Terrs: %d BER %4.3f\n", frames, EbNodB, states.Tbits,states. Terrs, states.Terrs/states.Tbits);
+  end
+
+  if test_frame_mode == 4
+    extract_and_print_rtty_packets(states, rx_bits_log, rx_bits_sd_log)
+  end
+
+  if test_frame_mode == 5
+    extract_and_decode_binary_packets(states, rx_bits_log);
+  end
+
+  figure(1);
+  plot(f_int_resample_log','+')
+  hold off;
+
+  figure(2)
+  clf
+  m = max(abs(x_log));
+  plot(x_log,'+')
+  axis([-m m -m m])
+  title('fine timing metric')
+
+  figure(3)
+  clf
+  subplot(211)
+  plot(norm_rx_timing_log);
+  axis([1 run_frames -1 1])
+  title('norm fine timing')
+  subplot(212)
+  plot(states.nerr_log)
+  title('num bit errors each frame')
+
+  figure(4)
+  clf
+  subplot(211)
+  one_sec_rx = rx(1:min(Fs,length(rx)));
+  plot(one_sec_rx)
+  title('rx signal at demod input')
+  subplot(212)
+  plot(abs(fft(one_sec_rx)))
+
+  figure(5)
+  clf
+  plot(f_log,'+')
+  title('tone frequencies')
+  axis([1 run_frames 0 Fs/2])
+
+  figure(6)
+  clf
+  plot(EbNodB_log);
+  title('Eb/No estimate')
+
+  figure(7)
+  clf
+  subplot(211)
+  X = abs(fft(timing_nl_log));
+  plot(X(1:length(X)/2))
+  subplot(212)
+  plot(abs(timing_nl_log(1:100)))
+
+ endfunction
+
+
+% demodulate a file of 8kHz 16bit short samples --------------------------------
+
+function rx_bits_log = demod_file(filename, test_frame_mode, noplot=0, EbNodB=100)
+  fin = fopen(filename,"rb"); 
+  more off;
+
+  %states = fsk_horus_init(96000, 1200);
+
+  if test_frame_mode == 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 100, 2);
+    uwstates = fsk_horus_init_rtty_uw(states);
+    states.ntestframebits = states.nbits;
+  end
+                               
+  if test_frame_mode == 5
+    % horus binary config ---------------------
+    states = fsk_horus_init(8000, 50, 4);
+    uwstates = fsk_horus_init_binary_uw;
+    states.ntestframebits = states.nbits;
+  end
+
+  states.verbose = 0x1 + 0x8;
+
+  if test_frame_mode == 6
+    % Horus high speed config --------------
+    states = fsk_horus_init_hbr(9600, 8, 1200, 2, 16);
+    states.tx_bits_file = "horus_high_speed.bin";
+    states.verbose += 0x4;
+    ftmp = fopen(states.tx_bits_file, "rb"); test_frame = fread(ftmp,Inf,"char")'; fclose(ftmp);
+    states.ntestframebits = length(test_frame);
+    printf("length test frame: %d\n", states.ntestframebits);
+  end
+
+  if test_frame_mode == 7
+    % 800XA 4FSK modem --------------
+    states = fsk_horus_init_hbr(8000, 10, 400, 4, 256);
+    states.tx_bits_file = "horus_high_speed.bin";
+    states.verbose += 0x4;
+    ftmp = fopen(states.tx_bits_file, "rb"); test_frame = fread(ftmp,Inf,"char")'; fclose(ftmp);
+    states.ntestframebits = length(test_frame);
+    printf("length test frame: %d\n", states.ntestframebits);
+  end
+
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  nbit = states.nbit;
+
+  frames = 0;
+  rx = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+  norm_rx_timing_log = [];
+  f_int_resample_log = [];
+  EbNodB_log = [];
+  ppm_log = [];
+  f_log = [];
+  rx_bits_buf = zeros(1,nbit + states.ntestframebits);
+
+  % optional noise.  Useful for testing performance of waveforms from real world modulators
+
+  EbNo = 10^(EbNodB/10);
+  ftmp = fopen(filename,"rb"); s = fread(ftmp,Inf,"short"); fclose(ftmp); tx_pwr = var(s);
+  variance = (tx_pwr/2)*states.Fs/(states.Rs*EbNo*states.bitspersymbol);
+
+  % First extract raw bits from samples ------------------------------------------------------
+
+  printf("demod of raw bits....\n");
+
+  finished = 0;
+  while (finished == 0)
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    [sf count] = fread(fin, nin, "short");
+    rx = [rx; sf];
+    
+    % add optional noise
+
+    if count
+      noise = sqrt(variance)*randn(count,1);
+      sf += noise;
+    end
+
+    if count == nin
+      frames++;
+
+      % demodulate to stream of bits
+
+      states = est_freq(states, sf, states.M);
+      %states.f = [1450 1590 1710 1850];
+      [rx_bits states] = fsk_horus_demod(states, sf);
+
+      rx_bits_buf(1:states.ntestframebits) = rx_bits_buf(nbit+1:states.ntestframebits+nbit);
+      rx_bits_buf(states.ntestframebits+1:states.ntestframebits+nbit) = rx_bits;
+
+      rx_bits_log = [rx_bits_log rx_bits];
+      rx_bits_sd_log = [rx_bits_sd_log states.rx_bits_sd];
+      norm_rx_timing_log = [norm_rx_timing_log states.norm_rx_timing];
+      f_int_resample_log = [f_int_resample_log abs(states.f_int_resample)];
+      EbNodB_log = [EbNodB_log states.EbNodB];
+      ppm_log = [ppm_log states.ppm];
+      f_log = [f_log; states.f];
+
+      if test_frame_mode == 1
+        states = ber_counter(states, test_frame, rx_bits_buf);
+        if states.ber_state == 1
+          states.verbose = 0;
+        end
+      end
+      if test_frame_mode == 6
+        states = ber_counter_packet(states, test_frame, rx_bits_buf);
+      end
+     else      
+      finished = 1;
+    end
+  end
+  fclose(fin);
+
+  if noplot == 0
+    printf("plotting...\n");
+
+    figure(1);
+    plot(f_log);
+    hold off;
+
+    figure(2);
+    plot(f_int_resample_log','+')
+
+    figure(3)
+    clf
+    subplot(211)
+    plot(norm_rx_timing_log)
+    axis([1 frames -0.5 0.5])
+    title('norm fine timing')
+    grid
+    subplot(212)
+    plot(states.nerr_log)
+    title('num bit errors each frame')
+    figure(4)
+    clf
+    plot(EbNodB_log);
+    title('Eb/No estimate')
+
+    figure(5)
+    clf
+    rx_nowave = rx(1000:length(rx));
+    subplot(211)
+    plot(rx_nowave(1:states.Fs));
+    title('input signal to demod (1 sec)')
+    xlabel('Time (samples)');
+    axis([1 states.Fs -35000 35000])
+
+    % normalise spectrum to 0dB full scale with a 32767 sine wave input
+
+    subplot(212)
+    RxdBFS = 20*log10(abs(fft(rx_nowave(1:states.Fs)))) - 20*log10((states.Fs/2)*32767);
+    plot(RxdBFS)
+    axis([1 states.Fs/2 -80 0])
+    xlabel('Frequency (Hz)');
+
+    figure(6);
+    clf
+    plot(ppm_log)
+    title('Sample clock (baud rate) offset in PPM');
+  end
+
+  if (test_frame_mode == 1) || (test_frame_mode == 6)
+    printf("frames: %d Tbits: %d Terrs: %d BER %4.3f EbNo: %3.2f\n", frames, states.Tbits,states. Terrs, states.Terrs/states.Tbits, mean(EbNodB_log));
+  end
+
+  % we can decode both protocols at the same time
+
+  if (test_frame_mode == 4) || (test_frame_mode == 5)
+    extract_and_print_rtty_packets(states, rx_bits_log, rx_bits_sd_log)
+    corr_log = extract_and_decode_binary_packets(states, rx_bits_log);
+
+    figure(8);
+    clf
+    plot(corr_log);
+    hold on;
+    plot([1 length(corr_log)],[states.binary.uw_thresh states.binary.uw_thresh],'g');
+    hold off;
+    title('UW correlation');
+  end
+
+endfunction
+
+
+% run test functions from here during development
+
+if exist("fsk_horus_as_a_lib") == 0
+  run_sim(1, 2, 100, 9);
+  %rx_bits = demod_file("~/Desktop/115.wav",6,0,90);
+  %rx_bits = demod_file("fsk_horus.raw",5);
+  %rx_bits = demod_file("~/Desktop/4FSK_Binary_NoLock.wav",4);
+  %rx_bits = demod_file("~/Desktop/phorus_binary_ascii.wav",4);
+  %rx_bits = demod_file("~/Desktop/binary/horus_160102_binary_rtty_2.wav",4);
+  %rx_bits = demod_file("~/Desktop/horus_160102_vk5ei_capture2.wav",4);
+  %rx_bits = demod_file("~/Desktop/horus_rtty_binary.wav",4);
+  %rx_bits = demod_file("~/Desktop/FSK_4FSK.wav",4);
+  %rx_bits = demod_file("t.raw",5);
+  %rx_bits = demod_file("~/Desktop/fsk_horus_10dB_1000ppm.wav",4);
+  %rx_bits = demod_file("~/Desktop/fsk_horus_6dB_0ppm.wav",4);
+  %rx_bits = demod_file("test.raw",1,1);
+  %rx_bits = demod_file("/dev/ttyACM0",1);
+  %rx_bits = demod_file("fsk_horus_rx_1200_96k.raw",1);
+  %rx_bits = demod_file("mp.raw",4);
+  %rx_bits = demod_file("~/Desktop/launchbox_v2_landing_8KHz_final.wav",4);
+  %rx_bits = demod_file("~/Desktop/bench_test_003.wav",7);
+end
diff --git a/codec2/branches/0.7/octave/fsk_horus_2fsk.m b/codec2/branches/0.7/octave/fsk_horus_2fsk.m
new file mode 100644 (file)
index 0000000..4b92a00
--- /dev/null
@@ -0,0 +1,979 @@
+% fsk_horus.m
+% David Rowe 10 Oct 2015
+%
+% Experimental near space balloon FSK demodulator
+% Assume high SNR, but fades near end of mission can wipe out a few bits
+% So low SNR perf not a huge issue
+%
+% [X] processing buffers of 1 second
+%     + 8000 samples input
+%     + keep 30 second sliding window to extract packet from
+%     + do fine timing on this
+%     [X] estimate frequency of two tones
+%         + this way we cope with variable shift and drift
+%         + starts to lose it at 8 Eb/No = 8db.  Maybe wider window?
+%     [X] estimate amplitudes and equalise, or limit
+%         + not needed - tones so close in freq unlikely to be significant ampl diff
+%           across SSB rx filter
+% [X] Eb/No point 8dB, 2% ish
+% [X] fine timing and sample slips, +/- 1000ppm (0.1%) clock offset test
+% [ ] bit flipping against CRC
+% [ ] implement CRC
+% [X] frame sync
+% [X] compare to fldigi
+%     + in AWGN channel 3-4dB improvement.  In my tests fldigi can't decode  
+%       with fading model, requires Eb/No > 40dB, this demo useable at Eb/No = 20dB
+% [X] test over range of f1/f2, shifts, timing offsets, clock offsets, Eb/No
+%     [X] +/- 1000ppm clock offset OK at Eb/No = 10dB, starts to lose it at 8dB
+%     [X] tone freq est starts to lose it at 8dB in awgn.  Maybe wider window?
+% [ ] low snr detection of $$$$$$
+%     + we might be able to pick up a "ping" at very low SNRs to help find baloon on ground
+% [ ] streaming, indicator of audio freq, i.e. speaker output?
+
+% horus binary:
+% [ ] BER estimate/found/corrected
+
+1;
+
+function states = fsk_horus_init(Fs,Rs)
+  states.Ndft = 2.^ceil(log2(Fs)); % find nearest power of 2 for effcient FFT
+  states.Fs = Fs;
+  N = states.N = Fs;             % processing buffer size, nice big window for f1,f2 estimation
+  states.Rs = Rs;
+  Ts = states.Ts = Fs/Rs;
+  assert(Ts == floor(Ts), "Fs/Rs must be an integer");
+  states.nsym = N/Ts;            % number of symbols in one procesing frame
+  Nmem = states.Nmem  = N+2*Ts;  % two symbol memory in down converted signals to allow for timing adj
+  states.f1_dc = zeros(1,Nmem);
+  states.f2_dc = zeros(1,Nmem);
+  states.P = 8;                  % oversample rate out of filter
+  assert(Ts/states.P == floor(Ts/states.P), "Ts/P must be an integer");
+
+  states.nin = N;                % can be N +/- Ts/P samples to adjust for sample clock offsets
+  states.verbose = 0;
+  states.phi1 = 0;               % keep down converter osc phase continuous
+  states.phi2 = 0;
+
+  printf("Fs: %d Rs: %d Ts: %d nsym: %d\n", states.Fs, states.Rs, states.Ts, states.nsym);
+
+  % BER stats 
+
+  states.ber_state = 0;
+  states.Tbits = 0;
+  states.Terrs = 0;
+  states.nerr_log = 0;
+
+  states.df = 0;
+  states.f1 = 0;
+  states.f2 = 0;
+  states.norm_rx_timing = 0;
+  states.ppm = 0;
+  states.prev_pkt = [];
+
+  % protocol specific states
+
+  states.rtty = fsk_horus_init_rtty_uw(states);
+  states.binary = fsk_horus_init_binary_uw;
+endfunction
+
+
+% init rtty protocol specifc states
+
+function rtty = fsk_horus_init_rtty_uw(states)
+  % Generate unque word that correlates against the ASCII "$$$$$" that
+  % is at the start of each frame.
+
+  dollar_bits = fliplr([0 1 0 0 1 0 0]);
+  mapped_db = 2*dollar_bits - 1;
+  sync_bits = [1 1 0];
+  mapped_sb = 2*sync_bits - 1;
+  %mapped_sb = [ 0 0 0 ];
+
+  mapped = [mapped_db mapped_sb];
+  npad = rtty.npad = 3;     % one start and two stop bits between 7 bit ascii chars
+  nfield = rtty.nfield = 7; % length of ascii character field
+
+  rtty.uw = [mapped mapped mapped mapped mapped];
+
+  rtty.uw_thresh = length(rtty.uw) - 8; % allow a few bit errors when looking for UW
+
+  rtty.max_packet_len = 1000;
+endfunction
+
+
+
+function binary = fsk_horus_init_binary_uw
+  % Generate 16 bit "$$" unique word that is at the front of every horus binary
+  % packet
+
+  dollar_bits = [0 0 1 0 0 1 0 0];
+  mapped_db = 2*dollar_bits - 1;
+
+  binary.uw = [mapped_db mapped_db];
+  binary.uw_thresh = length(binary.uw);   % no bit errors when looking for UW
+
+  binary.max_packet_len = 400;
+endfunction
+
+
+% test modulator function
+
+function tx  = fsk_horus_mod(states, tx_bits)
+    tx = zeros(states.Ts*length(tx_bits),1);
+    tx_phase = 0;
+    Ts = states.Ts;
+    Fs = states.Fs;
+    f1 = states.f1_tx;  f2 = states.f2_tx;
+    df = states.df; % tone freq change in Hz/s
+    dA = states.dA;
+
+    for i=1:length(tx_bits)
+      if tx_bits(i) == 0
+        tx_phase_vec = tx_phase + (1:Ts)*2*pi*f1/Fs;
+        tx((i-1)*Ts+1:i*Ts) = dA*2.0*cos(tx_phase_vec);
+      else
+        tx_phase_vec = tx_phase + (1:Ts)*2*pi*f2/Fs;
+        tx((i-1)*Ts+1:i*Ts) = 2.0*cos(tx_phase_vec);
+      end
+      tx_phase = tx_phase_vec(Ts) - floor(tx_phase_vec(Ts)/(2*pi))*2*pi;
+      f1 += df*Ts/Fs; f2 += df*Ts/Fs;
+    end
+endfunction
+
+
+% Given a buffer of nin input Rs baud FSK samples, returns nsym bits.
+%
+% Automagically estimates the frequency of the two tones, or
+% looking at it another way, the frequency offset and shift
+%
+% nin is the number of input samples required by demodulator.  This is
+% time varying.  It will nominally be N (8000), and occasionally N +/- 
+% Ts/2 (e.g. 8080 or 7920).  This is how we compensate for differences between the
+% remote tx sample clock and our sample clock.  This function always returns
+% N/Ts (50) demodulated bits.  Variable number of input samples, constant number
+% of output bits.
+
+function [rx_bits states] = fsk_horus_demod(states, sf)
+  N = states.N;
+  Ndft = states.Ndft;
+  Fs = states.Fs;
+  Rs = states.Rs;
+  Ts = states.Ts;
+  nsym = states.nsym;
+  P = states.P;
+  nin = states.nin;
+  verbose = states.verbose;
+  Nmem = states.Nmem;
+
+  assert(length(sf) == nin);
+
+  % find tone frequency and amplitudes ---------------------------------------------
+
+  h = hanning(nin);
+  Sf = fft(sf .* h, Ndft);
+  [m1 m1_index] = max(Sf(1:Ndft/2));
+
+  % zero out region 100Hz either side of max so we can find second highest peak
+
+  Sf2 = Sf;
+  st = m1_index - floor(100*Ndft/Fs);
+  if st < 1
+    st = 1;
+  end
+  en = m1_index + floor(100*Ndft/Fs);
+  if en > Ndft/2
+    en = Ndft/2;
+  end
+  Sf2(st:en) = 0;
+
+  [m2 m2_index] = max(Sf2(1:Ndft/2));
+  
+  % f1 always the lower tone
+
+  if m1_index < m2_index
+    f1 = (m1_index-1)*Fs/Ndft;
+    f2 = (m2_index-1)*Fs/Ndft;
+    twist = 20*log10(m1/m2);
+  else
+    f1 = (m2_index-1)*Fs/Ndft;
+    f2 = (m1_index-1)*Fs/Ndft;
+    twist = 20*log10(m2/m1);
+  end
+
+  states.f1 = f1;
+  states.f2 = f2;
+
+  if bitand(verbose,0x1)
+    printf("centre: %4.0f shift: %4.0f twist: %3.1f dB\n", (f2+f1)/2, f2-f1, twist);
+  end
+  if bitand(verbose,0x8)
+    printf("f1: %4.0f Hz f2: %4.0f Hz a1: %f a2: %f\n", f1, f2, 2.0*abs(m1)/Ndft, 2.0*abs(m2)/Ndft);
+  end
+
+  % down convert and filter at rate P ------------------------------
+
+  % update filter (integrator) memory by shifting in nin samples
+  
+  nold = Nmem-nin; % number of old samples we retain
+
+  f1_dc = states.f1_dc; 
+  f1_dc(1:nold) = f1_dc(Nmem-nold+1:Nmem);
+  f2_dc = states.f2_dc; 
+  f2_dc(1:nold) = f2_dc(Nmem-nold+1:Nmem);
+
+  % shift down to around DC, ensuring continuous phase from last frame
+
+  phi1_vec = states.phi1 + (1:nin)*2*pi*f1/Fs;
+  phi2_vec = states.phi2 + (1:nin)*2*pi*f2/Fs;
+
+  f1_dc(nold+1:Nmem) = sf' .* exp(-j*phi1_vec);
+  f2_dc(nold+1:Nmem) = sf' .* exp(-j*phi2_vec);
+
+  states.phi1  = phi1_vec(nin);
+  states.phi1 -= 2*pi*floor(states.phi1/(2*pi));
+  states.phi2  = phi2_vec(nin);
+  states.phi2 -= 2*pi*floor(states.phi2/(2*pi));
+
+  % save filter (integrator) memory for next time
+
+  states.f1_dc = f1_dc;
+  states.f2_dc = f2_dc;
+
+  % integrate over symbol period, which is effectively a LPF, removing
+  % the -2Fc frequency image.  Can also be interpreted as an ideal
+  % integrate and dump, non-coherent demod.  We run the integrator at
+  % rate P (1/P symbol offsets) to get outputs at a range of different
+  % fine timing offsets.  We calculate integrator output over nsym+1
+  % symbols so we have extra samples for the fine timing re-sampler at either
+  % end of the array.
+
+  rx_bits = zeros(1, (nsym+1)*P);
+  for i=1:(nsym+1)*P
+    st = 1 + (i-1)*Ts/P;
+    en = st+Ts-1;
+    f1_int(i) = sum(f1_dc(st:en));
+    f2_int(i) = sum(f2_dc(st:en));
+  end
+  states.f1_int = f1_int;
+  states.f2_int = f2_int;
+
+  % fine timing estimation -----------------------------------------------
+
+  % Non linearity has a spectral line at Rs, with a phase
+  % related to the fine timing offset.  See:
+  %   http://www.rowetel.com/blog/?p=3573 
+  % We have sampled the integrator output at Fs=P samples/symbol, so
+  % lets do a single point DFT at w = 2*pi*f/Fs = 2*pi*Rs/(P*Rs)
+  Np = length(f1_int);
+  w = 2*pi*(Rs)/(P*Rs);
+  x = ((abs(f1_int)-abs(f2_int)).^2) * exp(-j*w*(0:Np-1))';
+  norm_rx_timing = angle(x)/(2*pi);
+  rx_timing = norm_rx_timing*P;
+
+  states.x = x;
+  states.rx_timing = rx_timing;
+  prev_norm_rx_timing = states.norm_rx_timing;
+  states.norm_rx_timing = norm_rx_timing;
+
+  % estimate sample clock offset in ppm
+  % d_norm_timing is fraction of symbol period shift over nsym symbols
+
+  d_norm_rx_timing = norm_rx_timing - prev_norm_rx_timing;
+
+  % filter out big jumps due to nin changes
+
+  if abs(d_norm_rx_timing) < 0.2
+    appm = 1E6*d_norm_rx_timing/nsym;
+    states.ppm = 0.9*states.ppm + 0.1*appm;
+  end
+
+  % work out how many input samples we need on the next call. The aim
+  % is to keep angle(x) away from the -pi/pi (+/- 0.5 fine timing
+  % offset) discontinuity.  The side effect is to track sample clock
+  % offsets
+
+  next_nin = N;
+  if norm_rx_timing > 0.25
+     next_nin += Ts/2;
+  end
+  if norm_rx_timing < -0.25;
+     next_nin -= Ts/2;
+  end
+  states.nin = next_nin;
+
+  % Re-sample integrator outputs using fine timing estimate and linear interpolation
+
+  low_sample = floor(rx_timing);
+  fract = rx_timing - low_sample;
+  high_sample = ceil(rx_timing);
+
+  if bitand(verbose,0x2)
+    printf("rx_timing: %3.2f low_sample: %d high_sample: %d fract: %3.3f nin_next: %d\n", rx_timing, low_sample, high_sample, fract, next_nin);
+  end
+
+  f1_int_resample = zeros(1,nsym);
+  f2_int_resample = zeros(1,nsym);
+  rx_bits = zeros(1,nsym);
+  rx_bits_sd = zeros(1,nsym);
+  for i=1:nsym
+    st = i*P+1;
+    f1_int_resample(i) = f1_int(st+low_sample)*(1-fract) + f1_int(st+high_sample)*fract;
+    f2_int_resample(i) = f2_int(st+low_sample)*(1-fract) + f2_int(st+high_sample)*fract;
+    %f1_int_resample(i) = f1_int(st+1);
+    %f2_int_resample(i) = f2_int(st+1);
+    rx_bits(i) = abs(f2_int_resample(i)) > abs(f1_int_resample(i));
+    rx_bits_sd(i) = abs(f2_int_resample(i)) - abs(f1_int_resample(i));
+ end
+
+  states.f1_int_resample = f1_int_resample;
+  states.f2_int_resample = f2_int_resample;
+  states.rx_bits_sd = rx_bits_sd;
+
+  % Eb/No estimation
+
+  x = abs(abs(f1_int_resample) - abs(f2_int_resample));
+  states.EbNodB = 20*log10(1E-6+mean(x)/(1E-6+std(x)));
+endfunction
+
+
+% Look for unique word and return index of first UW bit, or -1 if no
+% UW found Sometimes there may be several matches, returns the
+% position of the best match to UW.
+
+function uw_start = find_uw(states, start_bit, rx_bits)
+  uw = states.uw;
+
+  mapped_rx_bits = 2*rx_bits - 1;
+  best_corr = 0;
+  uw_start = -1;
+
+  for i=start_bit:length(rx_bits) - length(uw)
+    corr  = mapped_rx_bits(i:i+length(uw)-1) * uw';
+    if (corr >= states.uw_thresh) && (corr > best_corr)
+      uw_start = i;
+      best_corr = corr;
+    end
+  end
+endfunction
+
+
+% Extract ASCII string from a Horus frame of bits
+
+function [str crc_ok] = extract_ascii(states, rx_bits_buf, uw_loc)
+  nfield = states.nfield;
+  npad = states.npad;
+
+  str = []; str_dec = []; nstr = 0; ptx_crc = 1; rx_crc = "";
+  endpacket = 0;
+
+  st = uw_loc + length(states.uw);  % first bit of first char
+  en = uw_loc + states.max_packet_len - nfield;
+  %printf("\nst: %d en: %d len: %d\n", st, en, length(rx_bits_buf));
+
+  for i=st:nfield+npad:en
+    field = rx_bits_buf(i:i+nfield-1);
+    ch_dec = field * (2.^(0:nfield-1))';
+
+    % filter out unlikely characters that bit errors may introduce, and ignore \n
+
+    if (ch_dec > 31) && (ch_dec < 91)
+      str = [str char(ch_dec)];
+    else 
+      str = [str char(32)]; % space is "not sure"
+    end
+    nstr++;
+
+    % build up array for CRC16 check
+
+    if !endpacket && (ch_dec == 42)
+      endpacket = 1; 
+      rx_crc = crc16(str_dec);      % found a '*' so that's the end of the string for CRC calculations
+      ptx_crc = nstr+1;             % this is where the transmit CRC starts
+    end
+    if !endpacket
+      str_dec = [str_dec ch_dec];
+    end
+  end
+
+  if (ptx_crc+3) <= length(str)
+    tx_crc = str(ptx_crc:ptx_crc+3);
+    crc_ok = strcmp(tx_crc, rx_crc);
+  else
+    crc_ok = 0;
+  end
+
+  str = str(1:ptx_crc-2);
+
+endfunction
+
+
+% Use soft decision information to find bits most likely in error.  I think
+% this is some form of maximum likelihood decoding.
+
+function [str crc_ok rx_bits_log_flipped] = sd_bit_flipping(states, rx_bits_log, rx_bits_sd_log, st, en);
+
+  % force algorithm to ignore rs232 sync bits by marking them as "very likely", they have
+  % no input to crc algorithm
+
+  nfield = states.nfield;
+  npad = states.npad;
+  for i=st:nfield+npad:en
+    rx_bits_sd_log(i+nfield:i+nfield+npad-1) = 1E6;
+  end
+
+  % make a list of bits with smallest soft decn values
+
+  [dodgy_bits_mag dodgy_bits_index] = sort(abs(rx_bits_sd_log(st+length(states.uw):en)));
+  dodgy_bits_index += length(states.uw) + st - 1;
+  nbits = 6;
+  ntries = 2^nbits;
+  str = "";
+  crc_ok = 0;
+  
+  % try various combinations of these bits
+
+  for i=1:ntries-1
+    error_mask = zeros(1, length(rx_bits_log));
+    for b=1:nbits
+      x = bitget(i,b);
+      bit_to_flip = dodgy_bits_index(b);
+      error_mask(bit_to_flip) = x;
+      %printf("st: %d i: %d b: %d x: %d index: %d\n", st, i,b,x,bit_to_flip);
+    end
+    rx_bits_log_flipped = xor(rx_bits_log, error_mask);
+    [str_flipped crc_ok_flipped] = extract_ascii(states, rx_bits_log_flipped, st);
+    if crc_ok_flipped
+      %printf("Yayy we fixed a packet by flipping with pattern %d\n", i);
+      str = str_flipped;
+      crc_ok = crc_ok_flipped;
+    end
+  end
+endfunction
+
+
+% Extract as many ASCII packets as we can from a great big buffer of bits
+
+function extract_and_print_rtty_packets(states, rx_bits_log, rx_bits_sd_log)
+
+  % use UWs to delimit start and end of data packets
+
+  bit = 1;
+  nbits = length(rx_bits_log);
+  nfield = states.rtty.nfield;
+  npad = states.rtty.npad;
+
+  uw_loc = find_uw(states.rtty, bit, rx_bits_log);
+
+  while (uw_loc != -1)
+
+    if (uw_loc + states.rtty.max_packet_len) < nbits
+      % Now start picking out 7 bit ascii chars from frame.  It has some
+      % structure so we can guess where fields are.  I hope we don't get
+      % RS232 idle bits stuck into it anywhere, ie "bit fields" don't
+      % change dynamically.
+
+      % dump msg bits so we can use them as a test signal
+      %msg = rx_bits_log(st:uw_loc-1);
+      %save -ascii horus_msg.txt msg
+
+      % simulate bit error for testing
+      %rx_bits_log(st+200) = xor(rx_bits_log(st+100),1);
+      %rx_bits_sd_log(st+100) = 0;
+      
+      [str crc_ok] = extract_ascii(states.rtty, rx_bits_log, uw_loc);
+
+      if crc_ok == 0
+        [str_flipped crc_flipped_ok rx_bits_log] = sd_bit_flipping(states.rtty, rx_bits_log, rx_bits_sd_log, uw_loc, uw_loc+states.rtty.max_packet_len); 
+        if crc_flipped_ok
+          str = sprintf("%s fixed", str_flipped);
+        end
+      end
+
+      % update memory of previous packet, we use this to guess where errors may be
+      if crc_ok || crc_flipped_ok
+        states.prev_pkt = rx_bits_log(uw_loc+length(states.rtty.uw):uw_loc+states.rtty.max_packet_len);
+      end
+      if crc_ok
+        str = sprintf("%s CRC OK", str);
+      else
+        str = sprintf("%s CRC BAD", str);
+      end
+      printf("%s\n", str);
+    end
+
+    % look for next packet
+
+    bit = uw_loc + length(states.rtty.uw);
+    uw_loc = find_uw(states.rtty, bit, rx_bits_log);
+
+  endwhile
+endfunction
+
+% Extract as many ASCII packets as we can from a great big buffer of bits,
+% and send them to the C decoder for FEC decoding.
+% horus_l2 can be compiled a bunch of different ways.  You need to
+% compile with:
+%   codec2-dev/src$ gcc horus_l2.c -o horus_l2 -Wall -DDEC_RX_BITS -DHORUS_L2_RX
+
+function extract_and_decode_binary_packets(states, rx_bits_log)
+
+  % use UWs to delimit start and end of data packets
+
+  bit = 1;
+  nbits = length(rx_bits_log);
+
+  uw_loc = find_uw(states.binary, bit, rx_bits_log);
+
+  while (uw_loc != -1)
+
+    if (uw_loc+states.binary.max_packet_len) < nbits
+      %printf("st: %d uw_loc: %d\n", st, uw_loc);
+
+      % OK we have a packet delimited by two UWs.  Lets convert the bit
+      % stream into bytes and save for decoding
+
+      pin = uw_loc;    
+      for i=1:45
+        rx_bytes(i) = rx_bits_log(pin:pin+7) * (2.^(7:-1:0))';
+        pin += 8;
+        %printf("%d 0x%02x\n", i, rx_bytes(i));
+      end
+
+      f=fopen("horus_rx_bits_binary.txt","wt");
+      fwrite(f, rx_bytes, "uchar");
+      fclose(f);
+
+      system("../src/horus_l2");  % compile instructions above
+    end
+
+    bit = uw_loc + length(states.binary.uw);
+    uw_loc = find_uw(states.binary, bit, rx_bits_log);
+   
+  endwhile
+endfunction
+
+% BER counter and test frame sync logic
+
+function states = ber_counter(states, test_frame, rx_bits_buf)
+  nsym = states.nsym;
+  state = states.ber_state;
+  next_state = state;
+
+  if state == 0
+
+    % try to sync up with test frame
+
+    nerrs_min = nsym;
+    for i=1:nsym
+      error_positions = xor(rx_bits_buf(i:nsym+i-1), test_frame);
+      nerrs = sum(error_positions);
+      if nerrs < nerrs_min
+        nerrs_min = nerrs;
+        states.coarse_offset = i;
+      end
+    end
+    if nerrs_min/nsym < 0.05 
+      next_state = 1;
+    end
+    if bitand(states.verbose,0x4)
+      printf("coarse offset: %d nerrs_min: %d next_state: %d\n", states.coarse_offset, nerrs_min, next_state);
+    end
+  end
+
+  if state == 1  
+
+    % we're synced up, lets measure bit errors
+
+    error_positions = xor(rx_bits_buf(states.coarse_offset:states.coarse_offset+nsym-1), test_frame);
+    nerrs = sum(error_positions);
+    if nerrs/nsym > 0.1
+      next_state = 0;
+    else
+      states.Terrs += nerrs;
+      states.Tbits += nsym;
+      states.nerr_log = [states.nerr_log nerrs];
+    end
+  end
+
+  states.ber_state = next_state;
+endfunction
+
+
+% simulation of tx and rx side, add noise, channel impairments ----------------------
+
+function run_sim(test_frame_mode)
+  frames = 60;
+  EbNodB = 10;
+  timing_offset = 0.0; % see resample() for clock offset below
+  fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+  df     = 0;          % tx tone freq drift in Hz/s
+  dA     = 1;          % amplitude imbalance of tones (note this affects Eb so not a gd idea)
+
+  more off
+  rand('state',1); 
+  randn('state',1);
+
+  % ----------------------------------------------------------------------
+
+  % sm2000 config ------------------------
+  %states = fsk_horus_init(96000, 1200);
+  %states.f1_tx = 4000;
+  %states.f2_tx = 5200;
+
+  if test_frame_mode == 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 100);
+    states.f1_tx = 1200;
+    states.f2_tx = 1600;
+    states.tx_bits_file = "horus_tx_bits_rtty.txt"; % Octave file of bits we FSK modulate
+  end
+                               
+  if test_frame_mode == 5
+    % horus binary config ---------------------
+    states = fsk_horus_init(8000, 100);
+    states.f1_tx = 1200;
+    states.f2_tx = 1600;
+    states.tx_bits_file = "horus_tx_bits_binary.txt"; % Octave file of bits we FSK modulate
+  end
+
+  % ----------------------------------------------------------------------
+
+  states.verbose = 0x1;
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  Fs = states.Fs;
+  states.df = df;
+  states.dA = dA;
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rs*EbNo);
+
+  % set up tx signal with payload bits based on test mode
+
+  if test_frame_mode == 1
+     % test frame of bits, which we repeat for convenience when BER testing
+    test_frame = round(rand(1, states.nsym));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, states.nsym*(frames+1)));
+  end
+  if test_frame_mode == 3
+    % ...10101... sequence
+    tx_bits = zeros(1, states.nsym*(frames+1));
+    tx_bits(1:2:length(tx_bits)) = 1;
+  end
+  if (test_frame_mode == 4) || (test_frame_mode == 5)
+
+    % load up a horus msg from disk and modulate that
+
+    test_frame = load(states.tx_bits_file);
+    ltf = length(test_frame);
+    ntest_frames = ceil((frames+1)*nsym/ltf);
+    tx_bits = [];
+    for i=1:ntest_frames
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+
+  tx = fsk_horus_mod(states, tx_bits);
+
+  %tx = resample(tx, 1000, 1001); % simulated 1000ppm sample clock offset
+
+  if fading
+     ltx = length(tx);
+     tx = tx .* (1.1 + cos(2*pi*2*(0:ltx-1)/Fs))'; % min amplitude 0.1, -20dB fade, max 3dB
+  end
+
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise;
+  %rx = real(rx);
+  %b1 = fir2(100, [0 4000 5200 48000]/48000, [1 1 0.5 0.5]);
+  %rx = filter(b1,1,rx);
+  %[b a] = cheby2(6,40,[3000 6000]/(Fs/2));
+  %rx = filter(b,a,rx);
+  %rx = sign(rx);
+  %rx(find (rx > 1)) = 1;
+  %rx(find (rx < -1)) = -1;
+
+  % dump simulated rx file
+  ftx=fopen("fsk_horus_100bd_binary.raw","wb"); rxg = rx*1000; fwrite(ftx, rxg, "short"); fclose(ftx);
+
+  timing_offset_samples = round(timing_offset*states.Ts);
+  st = 1 + timing_offset_samples;
+  rx_bits_buf = zeros(1,2*nsym);
+  x_log = [];
+  norm_rx_timing_log = [];
+  f1_int_resample_log = [];
+  f2_int_resample_log = [];
+  f1_log = f2_log = [];
+  EbNodB_log = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+
+  for f=1:frames
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    en = st + states.nin - 1;
+    sf = rx(st:en);
+    st += nin;
+
+    % demodulate to stream of bits
+
+    [rx_bits states] = fsk_horus_demod(states, sf);
+    rx_bits_buf(1:nsym) = rx_bits_buf(nsym+1:2*nsym);
+    rx_bits_buf(nsym+1:2*nsym) = rx_bits;
+    rx_bits_log = [rx_bits_log rx_bits];
+    rx_bits_sd_log = [rx_bits_sd_log states.rx_bits_sd];
+
+    norm_rx_timing_log = [norm_rx_timing_log states.norm_rx_timing];
+    x_log = [x_log states.x];
+    f1_int_resample_log = [f1_int_resample_log abs(states.f1_int_resample)];
+    f2_int_resample_log = [f2_int_resample_log abs(states.f2_int_resample)];
+    f1_log = [f1_log states.f1];
+    f2_log = [f2_log states.f2];
+    EbNodB_log = [EbNodB_log states.EbNodB];
+
+    if test_frame_mode == 1
+       states = ber_counter(states, test_frame, rx_bits_buf);
+    end
+  end
+
+  if test_frame_mode == 1
+    printf("frames: %d Tbits: %d Terrs: %d BER %4.3f\n", frames, states.Tbits,states. Terrs, states.Terrs/states.Tbits);
+  end
+
+  if test_frame_mode == 4
+    extract_and_print_rtty_packets(states, rx_bits_log, rx_bits_sd_log)
+  end
+
+  if test_frame_mode == 5
+    extract_and_decode_binary_packets(states, rx_bits_log);
+  end
+
+  figure(1);
+  plot(f1_int_resample_log,'+')
+  hold on;
+  plot(f2_int_resample_log,'g+')
+  hold off;
+
+  figure(2)
+  clf
+  m = max(abs(x_log));
+  plot(x_log,'+')
+  axis([-m m -m m])
+  title('fine timing metric')
+
+  figure(3)
+  clf
+  subplot(211)
+  plot(norm_rx_timing_log);
+  axis([1 frames -1 1])
+  title('norm fine timing')
+  subplot(212)
+  plot(states.nerr_log)
+  title('num bit errors each frame')
+
+  figure(4)
+  clf
+  subplot(211)
+  plot(real(rx(1:Fs)))
+  title('rx signal at demod input')
+  subplot(212)
+  plot(abs(fft(rx(1:Fs))))
+
+  figure(5)
+  clf
+  plot(f1_log)
+  hold on;
+  plot(f2_log,'g');
+  hold off;
+  title('tone frequencies')
+  axis([1 frames 0 Fs/2])
+
+  figure(6)
+  clf
+  plot(EbNodB_log);
+  title('Eb/No estimate')
+
+endfunction
+
+
+% demodulate a file of 8kHz 16bit short samples --------------------------------
+
+function rx_bits_log = demod_file(filename, test_frame_mode, noplot)
+  fin = fopen(filename,"rb"); 
+  more off;
+
+  %states = fsk_horus_init(96000, 1200);
+
+  if test_frame_mode == 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 100);
+    uwstates = fsk_horus_init_rtty_uw(states);
+  end
+                               
+  if test_frame_mode == 5
+    % horus binary config ---------------------
+    states = fsk_horus_init(8000, 100);
+    uwstates = fsk_horus_init_binary_uw;
+  end
+
+  states.verbose = 0x1 + 0x8;
+
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  rand('state',1); 
+  test_frame = round(rand(1, states.nsym));
+
+  frames = 0;
+  rx = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+  norm_rx_timing_log = [];
+  f1_int_resample_log = [];
+  f2_int_resample_log = [];
+  EbNodB_log = [];
+  ppm_log = [];
+  rx_bits_buf = zeros(1,2*nsym);
+
+  % First extract raw bits from samples ------------------------------------------------------
+
+  printf("demod of raw bits....\n");
+
+  finished = 0;
+  while (finished == 0)
+
+    % hit any key to finish (useful for real time streaming)
+
+    %x = kbhit(1);
+    %if length(x)
+    %  finished = 1;
+    %end
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    [sf count] = fread(fin, nin, "short");
+    rx = [rx; sf];
+
+    if count == nin
+      frames++;
+
+      % demodulate to stream of bits
+
+      [rx_bits states] = fsk_horus_demod(states, sf);
+      rx_bits_buf(1:nsym) = rx_bits_buf(nsym+1:2*nsym);
+      rx_bits_buf(nsym+1:2*nsym) = rx_bits; % xor(rx_bits,ones(1,nsym));
+      rx_bits_log = [rx_bits_log rx_bits];
+      rx_bits_sd_log = [rx_bits_sd_log states.rx_bits_sd];
+      norm_rx_timing_log = [norm_rx_timing_log states.norm_rx_timing];
+      f1_int_resample_log = [f1_int_resample_log abs(states.f1_int_resample)];
+      f2_int_resample_log = [f2_int_resample_log abs(states.f2_int_resample)];
+      EbNodB_log = [EbNodB_log states.EbNodB];
+      ppm_log = [ppm_log states.ppm];
+
+      if test_frame_mode == 1
+        states = ber_counter(states, test_frame, rx_bits_buf);
+        if states.ber_state == 1
+          states.verbose = 0;
+        end
+      end
+    else
+      finished = 1;
+    end
+  end
+  fclose(fin);
+
+  if exist("noplot") == 0
+    printf("plotting...\n");
+
+    figure(1);
+    plot(f1_int_resample_log,'+')
+    hold on;
+    plot(f2_int_resample_log,'g+')
+    hold off;
+
+    figure(2)
+    clf
+    subplot(211)
+    plot(norm_rx_timing_log)
+    axis([1 frames -0.5 0.5])
+    title('norm fine timing')
+    grid
+    subplot(212)
+    plot(states.nerr_log)
+    title('num bit errors each frame')
+    figure(3)
+    clf
+    plot(EbNodB_log);
+    title('Eb/No estimate')
+
+    figure(4)
+    clf
+    subplot(211)
+    plot(rx(1:states.Fs));
+    title('input signal to demod (1 sec)')
+    xlabel('Time (samples)');
+    axis([1 states.Fs -35000 35000])
+
+    % normalise spectrum to 0dB full scale witha 32767 sine wave input
+
+    subplot(212)
+    RxdBFS = 20*log10(abs(fft(rx(1:states.Fs)))) - 20*log10((states.Fs/2)*32767);
+    plot(RxdBFS)
+    axis([1 states.Fs/2 -80 0])
+    xlabel('Frequency (Hz)');
+
+    figure(5);
+    clf
+    plot(ppm_log)
+    title('Sample clock (baud rate) offset in PPM');
+  end
+
+  if test_frame_mode == 1
+    printf("frames: %d Tbits: %d Terrs: %d BER %4.3f EbNo: %3.2f\n", frames, states.Tbits,states. Terrs, states.Terrs/states.Tbits, mean(EbNodB_log));
+  end
+
+  % we can decode both protocols at the same time
+
+  if (test_frame_mode == 4) || (test_frame_mode == 5)
+    extract_and_print_rtty_packets(states, rx_bits_log, rx_bits_sd_log)
+    extract_and_decode_binary_packets(states, rx_bits_log);
+  end
+endfunction
+
+
+% run test functions from here during development
+
+if exist("fsk_horus_as_a_lib") == 0
+  %run_sim(5);
+  %rx_bits = demod_file("horus.raw",4);
+  %rx_bits = demod_file("fsk_horus_100bd_binary.raw",5);
+  rx_bits = demod_file("~/Desktop/phorus_binary_ascii.wav",4);
+  %rx_bits = demod_file("~/Desktop/horus_rtty_binary.wav",4);
+  %rx_bits = demod_file("t.raw",5);
+  %rx_bits = demod_file("~/Desktop/fsk_horus_10dB_1000ppm.wav",4);
+  %rx_bits = demod_file("~/Desktop/fsk_horus_6dB_0ppm.wav",4);
+  %rx_bits = demod_file("test.raw",1,1);
+  %rx_bits = demod_file("/dev/ttyACM0",1);
+  %rx_bits = demod_file("fsk_horus_rx_1200_96k.raw",1);
+  %rx_bits = demod_file("mp.raw",4);
+  %rx_bits = demod_file("~/Desktop/launchbox_v2_landing_8KHz_final.wav",4);
+end
diff --git a/codec2/branches/0.7/octave/fsk_horus_stream.m b/codec2/branches/0.7/octave/fsk_horus_stream.m
new file mode 100755 (executable)
index 0000000..4158104
--- /dev/null
@@ -0,0 +1,227 @@
+#!/usr/bin/octave -qf
+
+% fsk_horus_stream.m
+% David Rowe 13 Oct 2015
+%
+% Experimental real time near space balloon FSK demodulator, takes
+% 8kHz 16 bit samples from stdin, output txt string on stdout
+%
+% usage:
+%
+%   $ chmod 777 fsk_horus_stream.m
+%   $ rec -t raw -r 8000 -s -2 -c 1 - -q | ./fsk_horus_stream.m 2 100
+%
+% Or with pulseaudio you can decode two different waveforms at the
+% same time.  In two different shells start:
+%
+%   $ arecord -D pulse -r 8000 -c 1 -f S16_LE - | ./fsk_horus_stream.m 2 100
+%   $ arecord -D pulse -r 8000 -c 1 -f S16_LE - | ./fsk_horus_stream.m 4 50
+%
+% 'pavucontrol' utility can be used to select a sound device for arecord.
+%
+% To test with a stored file (8kHz 16-bit shorts):
+%
+%   $ cat ~/Desktop/vk5arg-3.wav | ./fsk_horus_stream.m 2 100
+%
+
+% command line arguments
+
+arg_list = argv ();
+if nargin == 0
+  printf("\nusage: %s [mFSKtones] [SymbolRateHz]\n\n", program_name());
+  printf("Horus RTTY 2FSK 100 baud:\n\n");
+  printf("  %s 2 100\n\n", program_name()); 
+  printf("Horus Binary 4FSK 50 baud\n\n");
+  printf("  %s 4 50\n\n", program_name()); 
+  exit(0);
+end
+
+mFSK = str2num(arg_list{1});
+Rs = str2num(arg_list{2});
+telem_upload_enabled = false;
+if nargin == 3
+  % Optionally upload Telemetry to Habitat (http://tracker.habhub.org/)
+  if strcmp(arg_list{3}, "telem")
+    telem_upload_enabled = true;
+  end
+end
+printf ("\nmFSK: %d Rs: %d nargin: %d telem: %d\n", mFSK, Rs, nargin, telem_upload_enabled);
+
+% include modem library
+
+fsk_horus_as_a_lib = 1; % make sure calls to test functions at bottom are disabled
+fsk_horus;  
+
+gps_log = "~/Desktop/gps_log.txt"
+system_command = "echo -n \"/home/david/Desktop/gps_log.txt\" | nc -u -q1 127.0.0.1 21234";
+
+% Update this command with your own callsign.
+telem_upload_command = "python telem_upload.py -c vk5dgr_Octave";
+
+more off;
+states = fsk_horus_init(8000, Rs, mFSK);
+uwstates = fsk_horus_init_rtty_uw(states);
+N = states.N;
+Rs = states.Rs;
+nsym = states.nsym;
+nin = states.nin;
+nfield = states.rtty.nfield;
+npad = states.rtty.npad;
+EbNo = 0;
+SNR = 0;
+
+rx = [];
+rx_bits_buf = [];
+rx_bits_sd_buf = [];
+
+[s,c] = fread(stdin, N, "short");
+
+while c
+
+  rx = [rx s'];
+  % demodulate samples to bit stream
+
+  while length(rx) > nin
+    states = est_freq(states, rx(1:nin)', states.M);
+    [rx_bits states] = fsk_horus_demod(states, rx(1:nin)');
+    rx_bits_buf = [rx_bits_buf rx_bits];
+    rx_bits_sd_buf = [rx_bits_sd_buf states.rx_bits_sd];
+    rx = rx(nin+1:length(rx));
+    nin = states.nin;
+    EbNo = 0.9*EbNo + 0.1*states.EbNodB;
+    SNR = EbNo + 10*log10(states.Rs/3000);
+    %printf("nin: %d length(rx): %d length(rx_bits_buf): %d \n", nin, length(rx), length(rx_bits_buf));
+  endwhile
+  f = states.f(1);
+  printf("max: %d f1: %d ppm: %d Eb/No: %3.1f SNR: %3.1f bits: %d\r", max(s), f, states.ppm, EbNo, SNR, length(rx_bits_buf));
+
+  packet_found = 0;
+
+  % Look for complete Horus RTTY frame -------------------------------------------------------------------
+
+  nbits = length(rx_bits_buf);
+  uw_loc = find_uw(states.rtty, 1, rx_bits_buf);
+
+  if uw_loc != -1
+    packet_found = 1;
+
+    if (uw_loc + states.rtty.max_packet_len) < nbits
+      %printf("\n%d nbits: %d\n",uw_loc + states.rtty.max_packet_len, nbits);
+
+      [str crc_ok] = extract_ascii(states.rtty, rx_bits_buf, uw_loc);
+
+      if crc_ok == 0
+        [str_flipped crc_flipped_ok] = sd_bit_flipping(states.rtty, rx_bits_buf, rx_bits_sd_buf, uw_loc, uw_loc+states.rtty.max_packet_len); 
+        if crc_flipped_ok
+          str = sprintf("%s fixed", str_flipped);
+          crc_ok = 1;
+        end
+      end
+      
+      if crc_ok
+        if telem_upload_enabled
+          % Upload to Habitat.
+          ascii_upload_cmd = sprintf("%s %s",telem_upload_command,str);
+          printf("Uploading ASCII to Habitat...\n");
+          system(ascii_upload_cmd,false,"async");
+        end
+
+        strok = sprintf("%s CRC OK", str);
+      else
+        strok = sprintf("%s CRC BAD", str);
+      end
+      printf("\n  %s         \n", strok);
+      
+      % throw out used bits in buffer.  We're not sure where the next packet starts
+      % so lets remove everything up to just after the UW we just used to force
+      % a search for the next UW.
+
+      rx_bits_buf    = rx_bits_buf(uw_loc+length(states.rtty.uw):length(rx_bits_buf));
+      rx_bits_sd_buf = rx_bits_sd_buf(uw_loc+length(states.rtty.uw):length(rx_bits_sd_buf));
+
+      if crc_ok
+        % extract GPS coords and save to log file for mapping software
+
+        str_split = strsplit(str,",");
+        if length(str_split) > 4
+          lat = str_split{1,4}; long = str_split{1,5};
+          f = fopen(gps_log,"at");
+          fprintf(f,"%s,%s\n", lat, long);
+          fclose(f);
+        end
+
+        % TODO: thin out log file to max_points to lighten plotting load
+
+        % tell foxtrotGPS to plot track
+
+        system(system_command);
+      end
+    end
+  end
+
+  % Look for complete Horus BINARY frame -------------------------------------------------------------------
+
+  nbits = length(rx_bits_buf);
+  uw_loc = find_uw(states.binary, 1, rx_bits_buf);
+
+  if uw_loc != -1
+    packet_found = 1;
+
+    if (uw_loc + states.binary.max_packet_len) < nbits
+     
+      pin = uw_loc; 
+      nbytes = states.binary.max_packet_len/8;
+      for i=1:nbytes
+        if (pin+7) > nbits
+          pin
+          nbits
+          uw_loc
+          states.binary.max_packet_len
+        end
+        rx_bytes(i) = rx_bits_buf(pin:pin+7) * (2.^(7:-1:0))';
+        pin += 8;
+        %printf("%d 0x%02x\n", i, rx_bytes(i));
+      end
+
+      printf("\n  ");
+      f=fopen("horus_rx_bits_binary.bin","wt");
+      fwrite(f, rx_bytes, "uchar");
+      fclose(f);
+
+      % horus_l2 can be compiled a bunch of different ways.  You need to
+      % compile with:
+      %   codec2-dev/src$ gcc horus_l2.c -o horus_l2 -Wall -DDEC_RX_BITS -DHORUS_L2_RX
+
+      system("../src/horus_l2");
+      if telem_upload_enabled
+        % Upload binary payload data to Habitat.
+        binary_upload_addition = "`cat horus_rx_bits_hex.txt`";
+        binary_upload_cmd = sprintf("%s %s",telem_upload_command,binary_upload_addition);
+        printf("Uploading Binary to Habitat...\n");
+        system(binary_upload_cmd,type="async");
+      end
+
+      % throw out used bits in buffer.  We're not sure where the next packet starts
+      % so lets remove everything up to just after the UW we just used to force
+      % a search for the next UW.
+
+      rx_bits_buf    = rx_bits_buf(uw_loc+length(states.binary.uw):length(rx_bits_buf));
+      rx_bits_sd_buf = rx_bits_sd_buf(uw_loc+length(states.binary.uw):length(rx_bits_sd_buf));
+    end
+  end
+
+  % Truncate buffers if no UW found so they don't grow endlessly with no signal.
+  % Keep very end of it as it may have part of a UW in it
+
+  if packet_found == 0
+    max_len = states.rtty.max_packet_len*4;
+    if length(rx_bits_buf) > max_len
+      rx_bits_buf = rx_bits_buf(length(rx_bits_buf)-states.rtty.max_packet_len:length(rx_bits_buf));
+      rx_bits_sd_buf = rx_bits_sd_buf(length(rx_bits_sd_buf)-states.rtty.max_packet_len:length(rx_bits_sd_buf));
+    end
+  end
+
+  [s,c] = fread(stdin, N, "short");
+
+endwhile
diff --git a/codec2/branches/0.7/octave/fsk_lib.m b/codec2/branches/0.7/octave/fsk_lib.m
new file mode 100644 (file)
index 0000000..8725242
--- /dev/null
@@ -0,0 +1,476 @@
+% fsk_lib.m
+% David Rowe Oct 2015 - present
+%
+% mFSK modem, started out life as RTTY demodulator for Project
+% Horus High Altitude Ballon (HAB) telemetry, also used for:
+%
+% FreeDV 2400A: 4FSK UHF/UHF digital voice
+% Wenet.......: 100 kbit/s HAB High Def image telemetry
+%
+% Handles frequency offsets, performance right on ideal, C implementation
+% in codec2-dev/src
+
+% NOTE: DR is in the process of refactoring this Octave code, pls email me 
+%       if something is broken
+
+1;
+
+function states = fsk_init(Fs, Rs, M=2)
+  states.M = M;                    
+  states.bitspersymbol = log2(M);
+  states.Fs = Fs;
+  states.Rs = Rs;
+
+  states.nsym = 50;                               % need enough symbols for good timing and freq offset est
+  Ts = states.Ts = Fs/Rs;                         % number of samples per symbol
+  assert(Ts == floor(Ts), "Fs/Rs must be an integer");
+
+  N = states.N = Ts*states.nsym;                  % processing buffer size, nice big window for timing est
+  states.Ndft = min(1024, 2.^ceil(log2(N)));      % find nearest power of 2 for efficient FFT
+  states.nbit = states.nsym*states.bitspersymbol; % number of bits per processing frame
+
+  Nmem = states.Nmem  = N+2*Ts;                   % two symbol memory in down converted signals to allow for timing adj
+
+  states.Sf = zeros(states.Ndft/2,1); % current memory of dft mag samples
+  states.f_dc = zeros(M,Nmem);
+  states.P = 8;                                   % oversample rate out of filter
+  assert(Ts/states.P == floor(Ts/states.P), "Ts/P must be an integer");
+
+  states.nin = N;                                 % can be N +/- Ts/P samples to adjust for sample clock offsets
+  states.verbose = 0;
+  states.phi = zeros(1, M);                       % keep down converter osc phase continuous
+
+  %printf("M: %d Fs: %d Rs: %d Ts: %d nsym: %d nbit: %d\n", states.M, states.Fs, states.Rs, states.Ts, states.nsym, states.nbit);
+
+  % BER stats 
+
+  states.ber_state = 0;
+  states.Tbits = 0;
+  states.Terrs = 0;
+  states.nerr_log = 0;
+
+  % extra simulation parameters
+
+  states.tx_real = 1;
+  states.dA(1:M) = 1;
+  states.df(1:M) = 0;
+  states.f(1:M) = 0;
+  states.norm_rx_timing = 0;
+  states.ppm = 0;
+  states.prev_pkt = [];
+  % Freq. estimator limits - keep these narrow to stop errors with low SNR 4FSK
+  % todo: make this Fs indep
+
+  states.fest_fmin = 800;
+  states.fest_fmax = 2500;
+  states.fest_min_spacing = 200;
+endfunction
+
+
+% Alternative init function, useful for high speed (non telemetry) modems
+%   Allows fine grained control of decimation P
+%   Small, processing window nsym rather than nsym=Fs (1 second window)
+%   Wider freq est limits
+
+function states = fsk_init_hbr(Fs,P,Rs,M=2,nsym=48)
+    
+  states.M = M;                    
+  states.bitspersymbol = log2(M);
+  states.Fs = Fs;
+  states.Rs = Rs;
+  Ts = states.Ts = Fs/Rs;
+  assert(Ts == floor(Ts), "Fs/Rs must be an integer");
+  N = states.N = Ts*nsym;        % processing buffer nsym wide
+  states.nsym = N/Ts;            % number of symbols in one processing frame
+  states.nbit = states.nsym*states.bitspersymbol; % number of bits per processing frame
+
+  states.Ndft = (2.^ceil(log2(N)))/2;  % find nearest power of 2 for efficient FFT
+
+  Nmem = states.Nmem  = N+2*Ts;  % two symbol memory in down converted signals to allow for timing adj
+
+  states.Sf = zeros(states.Ndft/2,1); % currentmemory of dft mag samples
+  states.f_dc = zeros(M,Nmem);
+  states.P = P;                  % oversample rate out of filter
+  assert(Ts/states.P == floor(Ts/states.P), "Ts/P must be an integer");
+
+  states.nin = N;                % can be N +/- Ts/P samples to adjust for sample clock offsets
+  states.verbose = 0;
+  states.phi = zeros(1, M);      % keep down converter osc phase continuous
+
+  %printf("M: %d Fs: %d Rs: %d Ts: %d nsym: %d nbit: %d\n", states.M, states.Fs, states.Rs, states.Ts, states.nsym, states.nbit);
+
+  % Freq estimator limits
+
+  states.fest_fmax = (Fs/2)-Rs;
+  states.fest_fmin = Rs/2;
+  states.fest_min_spacing = 2*(Rs-(Rs/5));
+
+  % BER stats 
+
+  states.ber_state = 0;
+  states.Tbits = 0;
+  states.Terrs = 0;
+  states.nerr_log = 0;
+
+  states.tx_real = 1;
+  states.dA(1:M) = 1;
+  states.df(1:M) = 0;
+  states.f(1:M) = 0;
+  states.norm_rx_timing = 0;
+  states.ppm = 0;
+  states.prev_pkt = [];
+  #{ 
+  TODO: fix me to ressuect fks_horus RTTY stuff, maybe call from 
+  % protocol specific states
+
+  states.rtty = fsk_horus_init_rtty_uw(states);
+  states.binary = fsk_horus_init_binary_uw;
+  #}
+
+endfunction
+
+
+% modulator function
+
+function tx  = fsk_mod(states, tx_bits)
+
+    M  = states.M;
+    Ts = states.Ts;
+    Fs = states.Fs;
+    ftx  = states.ftx;
+    df = states.df; % tone freq change in Hz/s
+    dA = states.dA; % amplitude of each tone
+
+    num_bits = length(tx_bits);
+    num_symbols = num_bits/states.bitspersymbol;
+    tx = zeros(states.Ts*num_symbols,1);
+    tx_phase = 0;
+    s = 1;
+
+    for i=1:states.bitspersymbol:num_bits
+
+      % map bits to FSK symbol (tone number)
+
+      K = states.bitspersymbol;
+      tone = tx_bits(i:i+(K-1)) * (2.^(K-1:-1:0))' + 1;
+      
+      tx_phase_vec = tx_phase + (1:Ts)*2*pi*ftx(tone)/Fs;
+      tx_phase = tx_phase_vec(Ts) - floor(tx_phase_vec(Ts)/(2*pi))*2*pi;
+      if states.tx_real
+        tx((s-1)*Ts+1:s*Ts) = dA(tone)*2.0*cos(tx_phase_vec);
+      else
+        tx((s-1)*Ts+1:s*Ts) = dA(tone)*exp(j*tx_phase_vec);
+      end
+      s++;
+
+      % freq drift
+
+      ftx += df*Ts/Fs;
+    end
+    states.ftx = ftx;
+endfunction
+
+
+% Estimate the frequency of the FSK tones.  In some applications (such
+% as balloon telemtry) these may not be well controlled by the
+% transmitter, so we have to try to estimate them.
+
+function states = est_freq(states, sf, ntones)
+  N = states.N;
+  Ndft = states.Ndft;
+  Fs = states.Fs;
+  
+  % This assumption is OK for balloon telemetry but may not be true in
+  % general
+
+  min_tone_spacing = states.fest_min_spacing;
+  
+  % set some limits to search range, which will mean some manual re-tuning
+
+  fmin = states.fest_fmin;
+  fmax = states.fest_fmax;
+  st = floor(fmin*Ndft/Fs);
+  en = floor(fmax*Ndft/Fs);
+
+  % scale averaging time constant based on number of samples 
+
+  tc = 0.95*Ndft/Fs;
+  %tc = .95;
+  % Update mag DFT  ---------------------------------------------
+
+  numffts = floor(length(sf)/Ndft);
+  h = hanning(Ndft);
+  for i=1:numffts
+    a = (i-1)*Ndft+1; b = i*Ndft;
+    Sf = abs(fft(sf(a:b) .* h, Ndft));
+    Sf(1:st) = 0; Sf(en:Ndft/2) = 0;
+    states.Sf = (1-tc)*states.Sf + tc*Sf(1:Ndft/2);
+  end
+
+  f = []; a = [];
+  Sf = states.Sf;
+
+  %figure(8)
+  %clf
+  %plot(Sf(1:Ndft/2));
+
+  % Search for each tone --------------------------------------------------------
+
+  for m=1:ntones
+    [tone_amp tone_index] = max(Sf(1:Ndft/2));
+
+    f = [f (tone_index-1)*Fs/Ndft];
+    a = [a tone_amp];
+
+    % zero out region min_tone_spacing/2 either side of max so we can find next highest peak
+    % closest spacing for non-coh mFSK is Rs
+
+    st = tone_index - floor((min_tone_spacing/2)*Ndft/Fs);
+    st = max(1,st);
+    en = tone_index + floor((min_tone_spacing/2)*Ndft/Fs);
+    en = min(Ndft/2,en);
+    Sf(st:en) = 0;
+  end
+
+  states.f = sort(f);
+end
+
+
+% ------------------------------------------------------------------------------------
+% Given a buffer of nin input Rs baud FSK samples, returns nsym bits.
+%
+% nin is the number of input samples required by demodulator.  This is
+% time varying.  It will nominally be N (8000), and occasionally N +/- 
+% Ts/2 (e.g. 8080 or 7920).  This is how we compensate for differences between the
+% remote tx sample clock and our sample clock.  This function always returns
+% N/Ts (e.g. 50) demodulated bits.  Variable number of input samples, constant number
+% of output bits.
+
+function [rx_bits states] = fsk_demod(states, sf)
+  M = states.M;
+  N = states.N;
+  Ndft = states.Ndft;
+  Fs = states.Fs;
+  Rs = states.Rs;
+  Ts = states.Ts;
+  nsym = states.nsym;
+  P = states.P;
+  nin = states.nin;
+  verbose = states.verbose;
+  Nmem = states.Nmem;
+  f = states.f;
+
+  assert(length(sf) == nin);
+
+  % down convert and filter at rate P ------------------------------
+
+  % update filter (integrator) memory by shifting in nin samples
+  
+  nold = Nmem-nin; % number of old samples we retain
+
+  f_dc = states.f_dc; 
+  f_dc(:,1:nold) = f_dc(:,Nmem-nold+1:Nmem);
+
+  % freq shift down to around DC, ensuring continuous phase from last frame
+
+  for m=1:M
+    phi_vec = states.phi(m) + (1:nin)*2*pi*f(m)/Fs;
+    f_dc(m,nold+1:Nmem) = sf .* exp(j*phi_vec)';
+    states.phi(m)  = phi_vec(nin);
+    states.phi(m) -= 2*pi*floor(states.phi(m)/(2*pi));
+  end
+
+  % save filter (integrator) memory for next time
+
+  states.f_dc = f_dc;
+
+  % integrate over symbol period, which is effectively a LPF, removing
+  % the -2Fc frequency image.  Can also be interpreted as an ideal
+  % integrate and dump, non-coherent demod.  We run the integrator at
+  % rate P*Rs (1/P symbol offsets) to get outputs at a range of
+  % different fine timing offsets.  We calculate integrator output
+  % over nsym+1 symbols so we have extra samples for the fine timing
+  % re-sampler at either end of the array.
+
+  for i=1:(nsym+1)*P
+    st = 1 + (i-1)*Ts/P;
+    en = st+Ts-1;
+    for m=1:M
+      f_int(m,i) = sum(f_dc(m,st:en));
+    end
+  end
+  states.f_int = f_int;
+
+  % fine timing estimation -----------------------------------------------
+
+  % Non linearity has a spectral line at Rs, with a phase
+  % related to the fine timing offset.  See:
+  %   http://www.rowetel.com/blog/?p=3573 
+  % We have sampled the integrator output at Fs=P samples/symbol, so
+  % lets do a single point DFT at w = 2*pi*f/Fs = 2*pi*Rs/(P*Rs)
+  %
+  % Note timing non-lineariry derived by experiment.  Not quite sure what I'm doing here.....
+  % but it gives 0dB impl loss for 2FSK Eb/No=9dB, testmode 1:
+  %   Fs: 8000 Rs: 50 Ts: 160 nsym: 50
+  %   frames: 200 Tbits: 9700 Terrs: 93 BER 0.010
+
+  Np = length(f_int(1,:));
+  w = 2*pi*(Rs)/(P*Rs);
+  timing_nl = sum(abs(f_int(:,:)).^2);
+  x = timing_nl * exp(-j*w*(0:Np-1))';
+  norm_rx_timing = angle(x)/(2*pi);
+  rx_timing = norm_rx_timing*P;
+
+  states.x = x;
+  states.timing_nl = timing_nl;
+  states.rx_timing = rx_timing;
+  prev_norm_rx_timing = states.norm_rx_timing;
+  states.norm_rx_timing = norm_rx_timing;
+
+  % estimate sample clock offset in ppm
+  % d_norm_timing is fraction of symbol period shift over nsym symbols
+
+  d_norm_rx_timing = norm_rx_timing - prev_norm_rx_timing;
+
+  % filter out big jumps due to nin changes
+
+  if abs(d_norm_rx_timing) < 0.2
+    appm = 1E6*d_norm_rx_timing/nsym;
+    states.ppm = 0.9*states.ppm + 0.1*appm;
+  end
+
+  % work out how many input samples we need on the next call. The aim
+  % is to keep angle(x) away from the -pi/pi (+/- 0.5 fine timing
+  % offset) discontinuity.  The side effect is to track sample clock
+  % offsets
+
+  next_nin = N;
+  if norm_rx_timing > 0.25
+     next_nin += Ts/2;
+  end
+  if norm_rx_timing < -0.25;
+     next_nin -= Ts/2;
+  end
+  states.nin = next_nin;
+
+  % Now we know the correct fine timing offset, Re-sample integrator
+  % outputs using fine timing estimate and linear interpolation, then
+  % extract the demodulated bits
+
+  low_sample = floor(rx_timing);
+  fract = rx_timing - low_sample;
+  high_sample = ceil(rx_timing);
+
+  if bitand(verbose,0x2)
+    printf("rx_timing: %3.2f low_sample: %d high_sample: %d fract: %3.3f nin_next: %d\n", rx_timing, low_sample, high_sample, fract, next_nin);
+  end
+
+  f_int_resample = zeros(M,nsym);
+  rx_bits = zeros(1,nsym*states.bitspersymbol);
+  tone_max = rx_bits_sd = zeros(1,nsym);
+
+  for i=1:nsym
+    st = i*P+1;
+    f_int_resample(:,i) = f_int(:,st+low_sample)*(1-fract) + f_int(:,st+high_sample)*fract;
+
+    % Largest amplitude tone is the winner.  Map this FSK "symbol" back to a bunch-o-bits,
+    % depending on M.
+
+    [tone_max(i) tone_index] = max(f_int_resample(:,i));
+    st = (i-1)*states.bitspersymbol + 1;
+    en = st + states.bitspersymbol-1;
+    arx_bits = dec2bin(tone_index - 1, states.bitspersymbol) - '0';
+    rx_bits(st:en) = arx_bits;
+  end
+
+  states.f_int_resample = f_int_resample;
+  states.rx_bits_sd = rx_bits_sd;
+
+  % Eb/No estimation (todo: this needs some work, like calibration, low Eb/No perf)
+
+  tone_max = abs(tone_max);
+  states.EbNodB = -6 + 20*log10(1E-6+mean(tone_max)/(1E-6+std(tone_max)));
+endfunction
+
+
+% BER counter and test frame sync logic -------------------------------------------
+
+function states = ber_counter(states, test_frame, rx_bits_buf)
+  nbit = states.nbit;
+  state = states.ber_state;
+  next_state = state;
+
+  if state == 0
+
+    % try to sync up with test frame
+
+    nerrs_min = nbit;
+    for i=1:nbit
+      error_positions = xor(rx_bits_buf(i:nbit+i-1), test_frame);
+      nerrs = sum(error_positions);
+      if nerrs < nerrs_min
+        nerrs_min = nerrs;
+        states.coarse_offset = i;
+      end
+    end
+    if nerrs_min/nbit < 0.05 
+      next_state = 1;
+    end
+    if bitand(states.verbose,0x4)
+      printf("coarse offset: %d nerrs_min: %d next_state: %d\n", states.coarse_offset, nerrs_min, next_state);
+    end
+  end
+
+  if state == 1  
+
+    % we're synced up, lets measure bit errors
+
+    error_positions = xor(rx_bits_buf(states.coarse_offset:states.coarse_offset+nbit-1), test_frame);
+    nerrs = sum(error_positions);
+    if nerrs/nbit > 0.1
+      next_state = 0;
+    else
+      states.Terrs += nerrs;
+      states.Tbits += nbit;
+      states.nerr_log = [states.nerr_log nerrs];
+    end
+  end
+
+  states.ber_state = next_state;
+endfunction
+
+
+% Alternative stateless BER counter that works on packets that may have gaps between them
+
+function states = ber_counter_packet(states, test_frame, rx_bits_buf)
+  ntestframebits = states.ntestframebits;
+  nbit = states.nbit;
+
+  % look for offset with min errors
+
+  nerrs_min = ntestframebits; coarse_offset = 1;
+  for i=1:nbit
+    error_positions = xor(rx_bits_buf(i:ntestframebits+i-1), test_frame);
+    nerrs = sum(error_positions);
+    %printf("i: %d nerrs: %d\n", i, nerrs);
+    if nerrs < nerrs_min
+      nerrs_min = nerrs;
+      coarse_offset = i;
+    end
+  end
+
+  % if less than threshold count errors
+
+  if nerrs_min/ntestframebits < 0.05 
+    states.Terrs += nerrs_min;
+    states.Tbits += ntestframebits;
+    states.nerr_log = [states.nerr_log nerrs_min];
+    if bitand(states.verbose, 0x4)
+      printf("coarse_offset: %d nerrs_min: %d\n", coarse_offset, nerrs_min);
+    end
+  end
+endfunction
+
+
diff --git a/codec2/branches/0.7/octave/fskdemodgui.py b/codec2/branches/0.7/octave/fskdemodgui.py
new file mode 100644 (file)
index 0000000..0ee182a
--- /dev/null
@@ -0,0 +1,189 @@
+#!/usr/bin/env python
+#
+#      fsk_demod Statistics GUI
+#      Accepts the stats output from fsk_demod on stdin, and plots it.
+#
+#      Mark Jessop 2016-03-13 <vk5qi@rfhead.net>
+#
+#      NOTE: This is intended to be run on a 'live' stream of samples, and hence expects
+#      updates at about 10Hz. Anything faster will fill up the input queue and be discarded.
+#
+#      Call using: 
+#      <producer>| ./fsk_demod 2X 8 923096 115387 - - S 2> >(python ~/Dev/codec2-dev/octave/fskdemodgui.py) | <consumer>
+#
+#
+import sys, time, json, Queue, argparse
+from threading import Thread
+from pyqtgraph.Qt import QtGui, QtCore
+import numpy as np
+import pyqtgraph as pg
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--wide", action="store_true", default=False, help="Alternate wide arrangement of widgets, for placement at bottom of 4:3 screen.")
+args = parser.parse_args()
+
+# Some settings...
+update_rate = 2 # Hz
+history_size = 100 # 10 seconds at 10Hz...
+history_scale = np.linspace((-1*history_size+1)/float(update_rate),0,history_size)
+
+# Input queue
+in_queue = Queue.Queue(1) # 1-element FIFO... 
+
+win = pg.GraphicsWindow()
+win.setWindowTitle('FSK Demodulator Modem Statistics')
+
+
+# Plot objects
+ebno_plot = win.addPlot(title="Eb/No")
+ppm_plot = win.addPlot(title="Sample Clock Offset")
+if args.wide == False:
+       win.nextRow()
+else:
+       win.resize(1024,200)
+fest_plot =pg.PlotItem() # win.addPlot(title="Tone Frequency Estimation")
+eye_plot = win.addPlot(title="Eye Diagram")
+# Disable auto-ranging on eye plot and fix axes for a big speedup...
+spec_plot = win.addPlot(title="Spectrum")
+spec_plot.setYRange(0,40)
+spec_plot.setLabel('left','SNR (dB)')
+spec_plot.setLabel('bottom','FFT Bin')
+# Configure plot labels and scales.
+ebno_plot.setLabel('left','Eb/No (dB)')
+ebno_plot.setLabel('bottom','Time (seconds)')
+ebno_plot.setYRange(0,25)
+ppm_plot.setLabel('left','Clock Offset (ppm)')
+ppm_plot.setLabel('bottom','Time (seconds)')
+fest_plot.setLabel('left','Frequency (Hz)')
+fest_plot.setLabel('bottom','Time (seconds)')
+eye_plot.disableAutoRange()
+eye_plot.setYRange(0,1)
+eye_plot.setXRange(0,15)
+eye_xr = 15
+
+# Data arrays...
+ebno_data = np.zeros(history_size)*np.nan
+ppm_data = np.zeros(history_size)*np.nan
+fest_data = np.zeros((4,history_size))*np.nan
+
+# Curve objects, so we can update them...
+spec_curve = spec_plot.plot([0])
+ebno_curve = ebno_plot.plot(x=history_scale,y=ebno_data)
+ppm_curve = ppm_plot.plot(x=history_scale,y=ppm_data)
+fest1_curve = fest_plot.plot(x=history_scale,y=fest_data[0,:],pen='r') # f1 = Red
+fest2_curve = fest_plot.plot(x=history_scale,y=fest_data[1,:],pen='g') # f2 = Blue
+fest3_curve = fest_plot.plot(x=history_scale,y=fest_data[2,:],pen='b') # f3 = Greem
+fest4_curve = fest_plot.plot(x=history_scale,y=fest_data[3,:],pen='m') # f4 = Magenta
+
+# Plot update function. Reads from queue, processes and updates plots.
+def update_plots():
+       global timeout,timeout_counter,eye_plot,ebno_curve, ppm_curve, fest1_curve, fest2_curve, ebno_data, ppm_data, fest_data, in_queue, eye_xr, spec_curve
+
+       try:
+               if in_queue.empty():
+                       return
+               in_data = in_queue.get_nowait()
+               in_data = json.loads(in_data)
+       except Exception as e:
+
+               sys.stderr.write(str(e))
+               return
+
+       # Roll data arrays
+       ebno_data[:-1] = ebno_data[1:]
+       ppm_data[:-1] = ppm_data[1:]
+       fest_data = np.roll(fest_data,-1,axis=1)
+
+
+       # Try reading in the new data points from the dictionary.
+       try:
+               new_ebno = in_data['EbNodB']
+               new_ppm = in_data['ppm']
+               new_fest1 = in_data['f1_est']
+               new_fest2 = in_data['f2_est']
+               new_spec = in_data['samp_fft']
+       except Exception as e:
+               print("ERROR reading dict: %s" % e)
+
+       # Try reading in the other 2 tones.
+       try:
+               new_fest3 = in_data['f3_est']
+               new_fest4 = in_data['f4_est']
+               fest_data[2,-1] = new_fest3
+               fest_data[3,-1] = new_fest4
+       except:
+               # If we can't read these tones out of the dict, fill with NaN
+               fest_data[2,-1] = np.nan
+               fest_data[3,-1] = np.nan
+
+       # Add in new data points
+       ebno_data[-1] = new_ebno
+       ppm_data[-1] = new_ppm
+       fest_data[0,-1] = new_fest1
+       fest_data[1,-1] = new_fest2
+
+       # Update plots
+       spec_data_log = 20*np.log10(np.array(new_spec)+0.01)
+       spec_curve.setData(spec_data_log)
+       spec_plot.setYRange(spec_data_log.max()-50,spec_data_log.max()+10)
+       ebno_curve.setData(x=history_scale,y=ebno_data)
+       ppm_curve.setData(x=history_scale,y=ppm_data)
+       fest1_curve.setData(x=history_scale,y=fest_data[0,:],pen='r') # f1 = Red
+       fest2_curve.setData(x=history_scale,y=fest_data[1,:],pen='g') # f2 = Blue
+       fest3_curve.setData(x=history_scale,y=fest_data[2,:],pen='b') # f3 = Green
+       fest4_curve.setData(x=history_scale,y=fest_data[3,:],pen='m') # f4 = Magenta
+
+       #Now try reading in and plotting the eye diagram
+       try:
+               eye_data = np.array(in_data['eye_diagram'])
+
+               #eye_plot.disableAutoRange()
+               eye_plot.clear()
+               col_index = 0
+               for line in eye_data:
+                       eye_plot.plot(line,pen=(col_index,eye_data.shape[0]))
+                       col_index += 1
+               #eye_plot.autoRange()
+               
+               #Quick autoranging for x-axis to allow for differing P and Ts values
+               if eye_xr != len(eye_data[0]) - 1:
+                       eye_xr = len(eye_data[0]) - 1
+                       eye_plot.setXRange(0,len(eye_data[0])-1)
+                       
+       except Exception as e:
+               pass
+
+
+timer = pg.QtCore.QTimer()
+timer.timeout.connect(update_plots)
+timer.start(1000/update_rate)
+
+
+# Thread to read from stdin and push into a queue to be processed.
+def read_input():
+       global in_queue
+
+       while True:
+               in_line = sys.stdin.readline()
+
+               # Only push actual data into the queue...
+               # This stops sending heaps of empty strings into the queue when fsk_demod closes.
+               if in_line == "":
+                       time.sleep(0.1)
+                       continue
+
+               if not in_queue.full():
+                       in_queue.put_nowait(in_line)
+
+read_thread = Thread(target=read_input)
+read_thread.daemon = True # Set as daemon, so when all other threads die, this one gets killed too.
+read_thread.start()
+
+## Start Qt event loop unless running in interactive mode or using pyside.
+if __name__ == '__main__':
+       import sys
+       if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
+               try:
+                       QtGui.QApplication.instance().exec_()
+               except KeyboardInterrupt:
+                       sys.exit(0)
diff --git a/codec2/branches/0.7/octave/fuzzy_gray.m b/codec2/branches/0.7/octave/fuzzy_gray.m
new file mode 100644 (file)
index 0000000..425f8d7
--- /dev/null
@@ -0,0 +1,586 @@
+% fuzzy_gray.m
+% David Rowe
+% 10 April 2014
+%
+% Various experiments in fuzzy gray codes and quantising and
+% transmitting scalars. 
+
+1;
+
+% fuzzy gray coding idea: use an extra parity bit, if we get a single
+% bit error the value will be "close: to the original, so effect of
+% error will be soft.  Unlike data we don't need 0 bit errors. I
+% struggled to extend this to larger m.
+
+function three_bit_code
+    m=4;
+    log2_m=2;
+    value_to_codeword = ["000"; "001"; "101"; "111"];
+    codeword_to_value = [0 1 1 2 1 2 2 3 3];
+
+    printf("tx_value tx_codeword rx_codeword rx_value distance\n");
+    for i=1:m
+        tx_codeword = bin2dec(value_to_codeword(i,:));
+        tx_codeword_bin = value_to_codeword(i,:);
+        rx_value = codeword_to_value(tx_codeword+1);
+        distance = abs((i-1) - rx_value);
+        printf("%8d %11s %11s %8d %8d\n", i-1, tx_codeword_bin, tx_codeword_bin, ...
+               rx_value, distance );
+    end
+    printf("\n");
+    for i=1:m
+        tx_codeword = bin2dec(value_to_codeword(i,:));
+        tx_codeword_bin = value_to_codeword(i,:);
+        for j=1:(log2_m+1)
+            rx_codeword = bitxor(tx_codeword, bitset(0,j));
+            rx_codeword_bin = dec2bin(rx_codeword, 3);
+            rx_value = codeword_to_value(rx_codeword+1);
+            distance = abs((i-1) - rx_value);
+            printf("%8d %11s %11s %8d %8d\n", i-1, tx_codeword_bin, rx_codeword_bin, ...
+                   rx_value, distance );
+       end
+    end
+endfunction
+
+% regular natural binary quantiser
+
+function index = quantise_value(value, min_value, max_value, num_levels)
+    norm = (value - min_value)/(max_value - min_value);
+    index = floor(num_levels * norm + 0.5);
+    if (index < 0 ) 
+        index = 0;
+    end
+    if (index > (num_levels-1)) 
+        index = num_levels-1;
+    end
+endfunction
+
+function value = unquantise_value(index, min_value, max_value, num_levels)
+    step  = (max_value - min_value)/num_levels;
+    value = min_value + step*(index);
+endfunction
+
+% converting natural binary to gray
+
+function gray = binary_to_gray(natural)
+    gray = bitxor(bitshift(natural,-1),natural);
+endfunction
+
+function natural = gray_to_binary(gray)
+    for i=1:length(gray)
+        mask = bitshift(gray(i),-1);
+        num = gray(i);
+        while(mask)
+            num = bitxor(num, mask);
+            mask = bitshift(mask,-1);
+        end
+        natural(i) = num;
+    end
+endfunction
+
+function sim_out = test_baseline_uncoded(Ebvec, Nbits, Ntrials, enable_error_log, enable_gray)
+    Nlevels = 2.^ Nbits; powersOfTwo = 2 .^ fliplr(0:(Nbits-1));
+    Nsymb   = Nbits;
+
+    sim_out.qnoise_log = zeros(length(Ebvec),Ntrials);
+    sim_out.error_log  = [];
+
+    for ne = 1:length(Ebvec)
+        EbNodB = Ebvec(ne);
+        EbNo = 10^(EbNodB/10);
+    
+        variance = 1/EbNo;
+        
+        Terrs = 0;  Tbits = 0;
+        qsignal = qnoise = 0;
+        for nn = 1:Ntrials
+                  
+            tx_value = rand(1,1);
+            tx_index = quantise_value(tx_value, 0, 1, Nlevels);
+            if enable_gray
+                tx_index = binary_to_gray(tx_index);
+            end
+            tx_bits = dec2bin(tx_index, Nbits) - '0';
+            tx_symbols = -1 + 2*tx_bits; 
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb) + j*randn(1,Nsymb));
+            rx_symbols = tx_symbols + noise;
+
+            rx_bits = rx_symbols > 0;
+
+            error_positions = xor(rx_bits, tx_bits);
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += length(tx_bits);
+            if enable_error_log
+                sim_out.error_log  = [sim_out.error_log error_positions];
+            end
+
+            rx_index = (powersOfTwo  * rx_bits');
+            if enable_gray
+                rx_index = gray_to_binary(rx_index);
+            end
+            rx_value = unquantise_value(rx_index, 0, 1, Nlevels);
+
+            qsignal += tx_value*tx_value;
+            qnoise  += (tx_value - rx_value) .^ 2;
+            sim_out.qnoise_log(ne,nn) = tx_value - rx_value;
+        end
+
+        sim_out.TERvec(ne) = Terrs;
+        sim_out.BERvec(ne) = Terrs/Tbits;
+        sim_out.QSNRvec(ne) = 10*log10(qsignal/qnoise);
+        printf("EbNo (dB): %3.2f  Terrs: %6d BER %1.4f QSNR (dB): %3.2f\n", 
+        EbNodB, Terrs, Terrs/Tbits, 10*log10(qsignal/qnoise));
+    end
+
+endfunction
+
+function sim_out = test_varpower(Ebvec, Nbits, Ntrials, amps, enable_error_log)
+    Nlevels = 2.^ Nbits; powersOfTwo = 2 .^ fliplr(0:(Nbits-1));
+    Nsymb   = Nbits;
+
+    sim_out.qnoise_log = zeros(length(Ebvec), Ntrials);
+    sim_out.error_log  = [];
+
+    for ne = 1:length(Ebvec)
+        EbNodB = Ebvec(ne);
+        EbNo = 10^(EbNodB/10);
+    
+        variance = 1/EbNo;
+        
+        Terrs = 0;  Tbits = 0;
+        qsignal = qnoise = 0;
+        for nn = 1:Ntrials
+                  
+            tx_value = rand(1,1);
+            tx_index = quantise_value(tx_value, 0, 1, Nlevels);
+            tx_bits = dec2bin(tx_index, Nbits) - '0';
+            tx_symbols = (-1 + 2*tx_bits) .* amps;
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb) + j*randn(1,Nsymb));
+            rx_symbols = tx_symbols + noise;
+
+            rx_bits = rx_symbols > 0;
+
+            error_positions = xor(rx_bits, tx_bits);
+            if enable_error_log
+                sim_out.error_log  = [sim_out.error_log error_positions];
+            end
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += length(tx_bits);
+
+            rx_index = (powersOfTwo  * rx_bits');
+            rx_value = unquantise_value(rx_index, 0, 1, Nlevels);
+
+            qsignal += tx_value*tx_value;
+            qnoise  += (tx_value - rx_value) .^ 2;
+            sim_out.qnoise_log(ne,nn) = tx_value - rx_value;
+        end
+
+        sim_out.TERvec(ne) = Terrs;
+        sim_out.BERvec(ne) = Terrs/Tbits;
+        sim_out.QSNRvec(ne) = 10*log10(qsignal/qnoise);
+        printf("EbNo (dB): %3.2f  Terrs: %6d BER %1.4f QSNR (dB): %3.2f\n", 
+        EbNodB, Terrs, Terrs/Tbits, 10*log10(qsignal/qnoise));
+    end
+
+endfunction
+
+% gray codes with specified number of data and parity bits.  Soft
+% decision decoding.  Didn't really work out.
+
+function valid_codewords = fuzzy_code_create(ndata,nparity)
+    Nbits = ndata + nparity;
+    Nvalid = 2 .^ ndata;
+    codewords = binary_to_gray(0:(2 .^ Nbits)-1);
+    valid_codewords = dec2bin(codewords(1:2:(2 .^ Nbits)), Nbits) - '0';
+
+    % check all valid codewords have a hamming distance of at least 2^nparity    
+
+    bad_distance = 0;
+    for i=1:Nvalid
+        for k=i+1:Nvalid
+            distance = sum(bitxor(valid_codewords(i,:), valid_codewords(k,:)));
+            if distance < 2
+                bad_distance++;
+            end
+        end
+    end
+    if bad_distance != 0
+       printf("Error: Nvalid: %d bad_distance: %d\n", Nvalid, bad_distance);
+       return;
+    end
+
+endfunction
+
+function tx_codeword = fuzzy_code_encode(codewords, value)
+    tx_codeword = codewords(value+1,:);
+endfunction
+
+function [value, best_codeword] = fuzzy_code_decode(codewords, rx_symbols)
+    max_corr = 0;
+    value = 0;
+    [rows,cols] = size(codewords);
+    for i=1:rows    
+        corr = (-1 + 2*codewords(i,:)) * transpose(rx_symbols);
+        if (corr > max_corr)
+            max_corr = corr;
+            value = i-1;
+            best_codeword = codewords(i,:);
+        end 
+    end
+endfunction
+
+
+function sim_out = test_fuzzy_code(Ebvec, Ndata, Nparity, Ntrials)
+    Nbits   = Ndata + Nparity;
+    Nlevels = 2 .^ Ndata;
+    Nsymb   = Nbits;
+    powersOfTwo = 2 .^ fliplr(0:(Nbits-1));
+
+    codewords = fuzzy_code_create(Ndata,Nparity);
+    sim_out.qnoise_log = zeros(length(Ebvec), Ntrials);
+
+    for ne = 1:length(Ebvec)
+        EbNodB = Ebvec(ne);
+        EbNo = 10^(EbNodB/10);
+    
+        variance = 1/EbNo;
+        
+        Terrs = 0; Terrs_coded = 0; Tbits = 0;
+        Nsingle = Nsingle_corrected = 0;
+        qsignal = qnoise = 0;
+        for nn = 1:Ntrials
+                  
+            tx_value = rand(1,1);
+            tx_index = quantise_value(tx_value, 0, 1, Nlevels);
+            tx_codeword = fuzzy_code_encode(codewords, tx_index);
+            tx_symbols = -1 + 2*tx_codeword; 
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb) + j*randn(1,Nsymb));
+            rx_symbols = tx_symbols + noise;
+
+            % uncoded BER
+
+            rx_bits = rx_symbols > 0;
+            error_positions = xor(rx_bits(1:Ndata), tx_codeword(1:Ndata));
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += Ndata;
+            
+            % decode and determine QSNR
+            [rx_index, rx_codeword] = fuzzy_code_decode(codewords, rx_symbols);     
+            rx_value = unquantise_value(rx_index, 0, 1, Nlevels);
+            qsignal += tx_value*tx_value;
+            qnoise  += (tx_value - rx_value) .^ 2;
+            sim_out.qnoise_log(ne,nn) = tx_value - rx_value;
+
+            % coded BER
+
+            error_positions = xor(rx_codeword(1:Ndata), tx_codeword(1:Ndata));
+            Nerrs_coded = sum(error_positions);
+            if Nerrs == 1
+                Nsingle++;
+                if Nerrs_coded == 0
+                    Nsingle_corrected++;
+                end
+            end
+            Terrs_coded += Nerrs_coded;
+        end
+
+        sim_out.BERvec(ne) = Terrs/Tbits;
+        sim_out.BERvec_coded(ne) = Terrs_coded/Tbits;
+        sim_out.Nsingle(ne) = Nsingle;
+        sim_out.Nsingle_corrected(ne) = Nsingle_corrected;
+
+        sim_out.QSNRvec(ne) = 10*log10(qsignal/qnoise);
+        printf("EbNo (dB): %3.2f  Terrs: %6d BER %1.4f Terrs_coded: %6d BER_coded %1.4f QSNR (dB): %3.2f", 
+        EbNodB, Terrs, Terrs/Tbits, Terrs_coded, Terrs_coded/Tbits, sim_out.QSNRvec(ne));
+        printf(" Nsingle: %d Nsingle_corrected: %d corrected: %3.1f\n", Nsingle,  Nsingle_corrected, Nsingle_corrected*100/Nsingle);
+    end
+endfunction
+
+function compare_baseline_fuzzy
+    Ebvec   = 0:3;
+    Ntrials = 5000;
+    Nbits   = 4; Nparity = 1;
+
+    baseline = test_baseline_uncoded(Ebvec, Nbits, Ntrials, 0, 0);
+    fuzzy = test_fuzzy_code(Ebvec, Nbits, Nparity, Ntrials);
+
+    figure(1);
+    clf;
+    semilogy(Ebvec, baseline.BERvec)
+    xlabel('Eb/N0')
+    ylabel('BER')
+    grid("minor")
+
+    figure(2);
+    clf;
+    plot(Ebvec, baseline.QSNRvec,'b;baseline;')
+    hold on;
+    plot(Ebvec, fuzzy.QSNRvec,'r;fuzzy;')
+    hold off;
+    xlabel('Eb/N0')
+    ylabel('SNR')
+    grid("minor")
+
+    figure(3);
+    subplot(211)
+    hist(baseline.qnoise_log(4,:),50);
+    subplot(212)
+    hist(fuzzy.qnoise_log(4,:),50);
+
+    figure(4)
+    subplot(211)
+    plot(baseline.qnoise_log(4,1:250),'b;baseline;')
+    subplot(212)
+    plot(fuzzy.qnoise_log(4,1:250),'r;fuzzy;')
+endfunction
+
+% compare baseline and variable power schemes and make plots
+
+function compare_baseline_varpower_plot
+    Ebvec   = -2:5;
+    Ntrials = 5000;
+    Nbits   = 5;
+
+    baseline = test_baseline_uncoded(Ebvec, Nbits, Ntrials, 0, 0);
+    amps = [2 1.5 1.0 0.5 0.5];
+    av_pwr = (amps*amps')/length(amps);
+    amps_norm = amps/sqrt(av_pwr);
+    varpower = test_varpower(Ebvec, Nbits, Ntrials,  amps_norm, 0);
+
+    figure(1);
+    clf;
+    semilogy(Ebvec, baseline.BERvec)
+    xlabel('Eb/No (dB)')
+    ylabel('BER')
+    grid("minor")
+    title('BER versus Eb/No')
+
+    figure(2);
+    clf;
+    plot(Ebvec, baseline.QSNRvec,'b;baseline;')
+    hold on;
+    plot(Ebvec, varpower.QSNRvec,'r;varpower;')
+    hold off;
+    xlabel('Eb/No (dB)')
+    ylabel('SNR (dB)')
+    grid("minor")
+    title('Quantiser SNR versus Eb/No')
+
+    figure(3);
+    subplot(211)
+    hist(baseline.qnoise_log(1,:),50);
+    title('Baseline and Variable Power Error Histograms')
+    subplot(212)
+    hist(varpower.qnoise_log(1,:),50);
+
+    figure(4)
+    subplot(211)
+    plot(baseline.qnoise_log(1,1:250),'b;baseline;')
+    title('Baseline and Variable Power Error plots for Eb/No = -2dB')
+    subplot(212)
+    plot(varpower.qnoise_log(1,1:250),'r;varpower;')
+endfunction
+
+% Compare baseline and variable power schemes and make error pattern
+% files for inserting into codec bit stream so we can listen to
+% result.
+
+function compare_baseline_varpower_error_files
+    Ebvec   = -2;
+    Fs      = 25;         % number of samples per second
+    Nsec    = 15;         % seconds to simulate
+    Ntrials = Fs*Nsec;
+    Nbits   = 5;
+    bits_per_frame = 52;
+    bits_per_frame_rounded = ceil(bits_per_frame/8)*8; % c2enc uses integer number of bytes/frame
+    start_bit = 12;                                    % first energy bit (after 4 voicing, 7 Wo bits)
+
+    baseline = test_baseline_uncoded(Ebvec, Nbits, Ntrials, 1, 0);
+    amps = [2 1.5 1.0 0.5 0.5];
+    av_pwr = (amps*amps')/length(amps);
+    amps_norm = amps/sqrt(av_pwr);
+    varpower = test_varpower(Ebvec, Nbits, Ntrials, amps_norm, 1);
+
+    % construct error patterns to apply to c2enc bit stream
+
+    baseline_errors = [];
+    for i=1:Ntrials
+        error_positions = baseline.error_log(Nbits*(i-1)+1:Nbits*i);
+        baseline_errors = [baseline_errors zeros(1,start_bit-1) error_positions ...
+                           zeros(1, bits_per_frame_rounded - Nbits - (start_bit-1))];
+    end
+    varpower_errors = [];
+    for i=1:Ntrials
+        error_positions = varpower.error_log(Nbits*(i-1)+1:Nbits*i);
+        varpower_errors = [varpower_errors zeros(1,start_bit-1) error_positions ...
+                           zeros(1, bits_per_frame_rounded - Nbits - (start_bit-1))];
+    end
+    % save error patterns
+
+    fep=fopen("energy_errors_baseline.bin","wb"); fwrite(fep, baseline_errors, "short"); fclose(fep);
+    fep=fopen("energy_errors_varpower.bin","wb"); fwrite(fep, varpower_errors, "short"); fclose(fep);
+endfunction
+
+% compare natural and gray coding and make plots
+
+function compare_natural_gray_plot
+    Ebvec   = -2:10;
+    Ntrials = 5000;
+    Nbits   = 7;
+
+    natural = test_baseline_uncoded(Ebvec, Nbits, Ntrials, 0, 0);
+    gray    = test_baseline_uncoded(Ebvec, Nbits, Ntrials, 0, 1);
+
+    figure(1);
+    clf;
+    semilogy(Ebvec, natural.BERvec)
+    xlabel('Eb/No (dB)')
+    ylabel('BER')
+    grid("minor")
+    title('BER versus Eb/No')
+
+    figure(2);
+    clf;
+    plot(Ebvec, natural.QSNRvec,'b;natural;')
+    hold on;
+    plot(Ebvec, gray.QSNRvec,'r;gray;')
+    hold off;
+    xlabel('Eb/No (dB)')
+    ylabel('SNR (dB)')
+    grid("minor")
+    title('Quantiser SNR versus Eb/No')
+
+    figure(3);
+    subplot(211)
+    hist(natural.qnoise_log(1,:),50);
+    title('Natural and Gray coded Error Histograms')
+    subplot(212)
+    hist(gray.qnoise_log(1,:),50);
+
+    figure(4)
+    subplot(211)
+    plot(natural.qnoise_log(1,1:250),'b;natural;')
+    axis([0 250 -1 1])
+    title('Natural and Gray coded Error plots for Eb/No = -2dB')
+    subplot(212)
+    plot(gray.qnoise_log(1,1:250),'r;gray;')
+    axis([0 250 -1 1])
+endfunction
+
+% compare natural at different Eb/No and Nbitsmake plots
+
+function compare_natural_nbit_plot
+    Ebvec   = -2:10;
+    Ntrials = 5000;
+
+    figure(1);
+    clf;
+    for n = 2:7
+        natural = test_baseline_uncoded(Ebvec, n, Ntrials, 0, 0);
+        plot(Ebvec, natural.QSNRvec)
+        if n == 2
+            hold on;
+        end
+   end
+   hold off;
+
+   xlabel('Eb/No (dB)')
+   ylabel('SNR (dB)')
+   grid("minor")
+   title('Quantiser SNR versus Eb/No')
+endfunction
+
+function generate_varpower_error_files(EbNo, start_bit, end_bit, amps, error_file_name)
+    Fs      = 25;         % number of samples per second
+    Nsec    = 3;         % seconds to simulate
+    Ntrials = Fs*Nsec;
+    Nbits   = end_bit - start_bit + 1;
+    bits_per_frame = 52;
+    bits_per_frame_rounded = ceil(bits_per_frame/8)*8; % c2enc uses integer number of bytes/frame
+                                                       % first energy bit (after 4 voicing, 7 Wo bits)
+
+    % normalise powers and run test
+
+    av_pwr = (amps*amps')/length(amps);
+    amps_norm = amps/sqrt(av_pwr);
+    av_pwr2 = (amps_norm*amps_norm')/length(amps_norm)
+    varpower = test_varpower(EbNo, Nbits, Ntrials, amps_norm, 1);
+
+    % construct error patterns to apply to c2enc bit stream
+
+    varpower_errors = [];
+    for i=1:Ntrials
+        error_positions = varpower.error_log(Nbits*(i-1)+1:Nbits*i);
+
+        if 0
+        % reset single errors to tes effect of ideal single bit error correcting code
+        for i=1:7
+          st = 4*(i-1)+1
+          en = 4*i
+          if sum(error_positions(st:en)) == 1
+            error_positions(st:en) = 0;
+          end
+        end
+        for i=1:2
+          st = 7*4+3*(i-1)+1 
+          en = 7*4+3*i
+          if sum(error_positions(st:en)) == 1
+            error_positions(st:en) = 0;
+          end
+        end
+        st = 7*4+3*2+1 
+        en = 7*4+3*2+2
+          if sum(error_positions(st:en)) == 1
+            error_positions(st:en) = 0;
+          end
+        end
+
+        num_errors(i) = sum(error_positions);
+        varpower_errors = [varpower_errors zeros(1,start_bit-1) error_positions ...
+                           zeros(1, bits_per_frame_rounded - Nbits - (start_bit-1))];
+    end
+    % save error pattern to file
+
+    fep=fopen(error_file_name,"wb"); fwrite(fep, varpower_errors, "short"); fclose(fep);
+
+    figure(1)
+    clf
+    hist(num_errors)
+endfunction
+
+more off;
+
+%generate_varpower_error_files(0, 17, 52, ones(1,36), "lsp_baseline_errors_0dB.bin")
+%amps = [1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 ];
+%generate_varpower_error_files(0, 17, 52, amps, "lsp_varpower_errors_0dB.bin")
+
+%compare_natural_nbit_plot
+%compare_natural_gray_plot
+%compare_baseline_varpower_plot
+%compare_baseline_varpower_error_files
+
+compare_baseline_fuzzy
+%fuzzy_code_create(3,1)
diff --git a/codec2/branches/0.7/octave/gen_complex_short.m b/codec2/branches/0.7/octave/gen_complex_short.m
new file mode 100644 (file)
index 0000000..2513f05
--- /dev/null
@@ -0,0 +1,18 @@
+% gen_complex_short.m
+%
+% David Rowe Feb 2017
+%
+% Generates a complex short signal for HackRF testing.
+
+Fs = 8E3;
+T = 10;
+A = 32000;
+f = 1000;
+
+N = T*Fs;
+t = 0:N-1;
+s = A*exp(j*2*pi*t*f/Fs);
+scomp = zeros(1,2*N);
+scomp(1:2:2*N) = real(s);
+scomp(2:2:2*N) = imag(s);
+save_raw("twotone.iq16",scomp);
diff --git a/codec2/branches/0.7/octave/gen_rn_coeffs.m b/codec2/branches/0.7/octave/gen_rn_coeffs.m
new file mode 100644 (file)
index 0000000..bfc214e
--- /dev/null
@@ -0,0 +1,40 @@
+% gen_rn_coeffs.m
+% David Rowe 13 april 2012
+%
+% Generate root raised cosine (Root Nyquist) filter coefficients
+% thanks http://www.dsplog.com/db-install/wp-content/uploads/2008/05/raised_cosine_filter.m
+
+function coeffs = gen_rn_coeffs(alpha, T, Rs, Nsym, M)
+
+  Ts = 1/Rs;
+
+  n = -Nsym*Ts/2:T:Nsym*Ts/2;
+  Nfilter = Nsym*M;
+  Nfiltertiming = M+Nfilter+M;
+
+  sincNum = sin(pi*n/Ts); % numerator of the sinc function
+  sincDen = (pi*n/Ts);    % denominator of the sinc function
+  sincDenZero = find(abs(sincDen) < 10^-10);
+  sincOp = sincNum./sincDen;
+  sincOp(sincDenZero) = 1; % sin(pix/(pix) =1 for x =0
+
+  cosNum = cos(alpha*pi*n/Ts);
+  cosDen = (1-(2*alpha*n/Ts).^2);
+  cosDenZero = find(abs(cosDen)<10^-10);
+  cosOp = cosNum./cosDen;
+  cosOp(cosDenZero) = pi/4;
+  gt_alpha5 = sincOp.*cosOp;
+  Nfft = 4096;
+  GF_alpha5 = fft(gt_alpha5,Nfft)/M;
+
+  % sqrt causes stop band to be amplified, this hack pushes it down again
+
+  for i=1:Nfft
+    if (abs(GF_alpha5(i)) < 0.02)
+      GF_alpha5(i) *= 0.001;
+    endif
+  end
+  GF_alpha5_root = sqrt(abs(GF_alpha5)) .* exp(j*angle(GF_alpha5));
+  ifft_GF_alpha5_root = ifft(GF_alpha5_root);
+  coeffs = real((ifft_GF_alpha5_root(1:Nfilter)));
+endfunction
diff --git a/codec2/branches/0.7/octave/glottal.m b/codec2/branches/0.7/octave/glottal.m
new file mode 100644 (file)
index 0000000..46675e7
--- /dev/null
@@ -0,0 +1,29 @@
+% glottal.m
+% David Rowe 12 Sep 2009
+% Matlab script to generate the phase spectra of a glottal pulse
+
+% lpc10 pulse from spandsp.  When the file glottal.c was used as a part of the
+% excitation phase component in phase.c, phase_synth_zero_order(), no difference 
+% in speech quality was apparent.  So left out of code for now.
+
+sh=12
+kexc = [ 8,  -16,   26, -48,  86, -162, 294, -502, 718, -728, 184 672, -610, -672, 184, 728,  718, 502,  294, 162,   86,  48, 26, 16, 8];
+kexc = shift(kexc,sh);
+kexc = [kexc(1:sh) zeros(1,512-25) kexc(sh+1:25)];
+figure(1)
+clf
+plot(kexc)
+figure(2)
+G = fft(kexc);
+subplot(211)
+plot((1:256)*(4000/256),unwrap(angle(G(1:256))))
+subplot(212)
+plot(20*log10(abs(G)))
+
+f=fopen("glottal.c","wt");
+fprintf(f,"const float glottal[]={\n");
+for m=1:255
+  fprintf(f,"  %f,\n",angle(G(m)));
+endfor
+fprintf(f,"  %f};\n",angle(G(256)));
+fclose(f);
diff --git a/codec2/branches/0.7/octave/gmsk.m b/codec2/branches/0.7/octave/gmsk.m
new file mode 100644 (file)
index 0000000..5f07d44
--- /dev/null
@@ -0,0 +1,1021 @@
+% gmsk.m
+% David Rowe Dec 2014
+%
+% GMSK modem implementation and simulations to test
+
+%
+% [X] plot eye diagram
+% [X] BER curves with reas match to theoretical
+% [X] fine timing estimator
+%     [X] test with fine timing error by resampling
+% [X] phase/freq estimator
+%     + need initial acquisition and tracking
+%     [X] test with different freq offsets
+% [X] coarse timing estimator (sync up to known test frames)
+%     [X] test with different coarse timing offsets
+% [ ] file read/write interface
+%     [ ] refactor into tx/rx functions
+% [X] modify for 1200 (or any) bit/s operation
+%     + ie GMSK filter coeff generation
+%     + or just re-sampling? e.g. ratio of Fs to Rs?
+% [ ] way to measure input SNR to demod
+%     + Maybe based on test tone/carrier from the other side?
+%     + think about process ... total signal plus noise power?  Increase power until S+N doubles?
+% [X] generate curves for baseline modem and with sync algorithms
+%     [X] used coarse sync code to remove need for knowing delays
+% [X] demod level indep
+%     + scaled OK +/- 20dB same BER
+% [X] effect of DC signals from SDRs
+%     + simulated effect of general interferer at -1500Hz, at an amplitude of 4
+%       (12 dB above GMSK signal), it started to affect BER e.g. 0.007 to 0.009
+%       Line appeared about 30dB above top of GMSK signal.
+% [ ] effect of quantisation noise
+
+% Filter coeffs From:
+% https://github.com/on1arf/gmsk/blob/master/gmskmodem_codec2/API/a_dspstuff.h,
+% which is in turn from Jonathan G4KLX.  The demod coeffs low pass filter noise
+
+global gmsk_mod_coeff = [...
+ 6.455906007234699e-014, 1.037067381285011e-012, 1.444835156335346e-011,...
+1.745786683011439e-010, 1.829471305298363e-009, 1.662729407135958e-008,...
+1.310626978701910e-007, 8.959797186410516e-007, 5.312253663302771e-006,...
+2.731624380156465e-005, 1.218217140199093e-004, 4.711833994209542e-004,...
+1.580581180127418e-003, 4.598383433830095e-003, 1.160259430889949e-002,...
+2.539022692626253e-002, 4.818807833062393e-002, 7.931844341164322e-002,...
+1.132322945270602e-001, 1.401935338024111e-001, 1.505383695578516e-001,...
+1.401935338024111e-001, 1.132322945270601e-001, 7.931844341164328e-002,...
+4.818807833062393e-002, 2.539022692626253e-002, 1.160259430889949e-002,...
+4.598383433830090e-003, 1.580581180127420e-003, 4.711833994209542e-004,...
+1.218217140199093e-004, 2.731624380156465e-005, 5.312253663302753e-006,...
+8.959797186410563e-007, 1.310626978701910e-007, 1.662729407135958e-008,...
+1.829471305298363e-009, 1.745786683011426e-010, 1.444835156335356e-011,...
+1.037067381285011e-012, 6.455906007234699e-014];
+
+global gmsk_demod_coeff = [...
+-0.000153959924563, 0.000000000000000, 0.000167227768379, 0.000341615513437,...
+0.000513334449696, 0.000667493753523, 0.000783901543032, 0.000838293462576,...
+0.000805143268199, 0.000661865814384, 0.000393913058926, -0.000000000000000,...
+-0.000503471198655, -0.001079755887508, -0.001671728086040, -0.002205032425392,...
+-0.002594597675000, -0.002754194565297, -0.002608210441859, -0.002104352817854,...
+-0.001225654870420, 0.000000000000000, 0.001494548041184, 0.003130012785731,...
+0.004735238379172, 0.006109242742194, 0.007040527007323, 0.007330850462455,...
+0.006821247169795, 0.005417521811131, 0.003112202160626, -0.000000000000000,...
+-0.003715739376345, -0.007727358782391, -0.011638713107503, -0.014992029537478,...
+-0.017304097563429, -0.018108937286588, -0.017003180218569, -0.013689829477969,...
+-0.008015928769710, 0.000000000000000, 0.010154104792614, 0.022059114281395,...
+0.035162729807337, 0.048781621388364, 0.062148583345584, 0.074469032280094,...
+0.084982001723750, 0.093020219991183, 0.098063819576269, 0.099782731268437,...
+0.098063819576269, 0.093020219991183, 0.084982001723750, 0.074469032280094,...
+0.062148583345584, 0.048781621388364, 0.035162729807337, 0.022059114281395,...
+0.010154104792614, 0.000000000000000, -0.008015928769710, -0.013689829477969,...
+-0.017003180218569, -0.018108937286588, -0.017304097563429, -0.014992029537478,...
+-0.011638713107503, -0.007727358782391, -0.003715739376345, -0.000000000000000,...
+0.003112202160626, 0.005417521811131, 0.006821247169795, 0.007330850462455,...
+0.007040527007323, 0.006109242742194, 0.004735238379172, 0.003130012785731,...
+0.001494548041184, 0.000000000000000, -0.001225654870420, -0.002104352817854,...
+-0.002608210441859, -0.002754194565297, -0.002594597675000, -0.002205032425392,...
+-0.001671728086040, -0.001079755887508, -0.000503471198655, -0.000000000000000,...
+0.000393913058926, 0.000661865814384, 0.000805143268199, 0.000838293462576,...
+0.000783901543032, 0.000667493753523, 0.000513334449696, 0.000341615513437,...
+0.000167227768379, 0.000000000000000, -0.000153959924563];
+
+rand('state',1); 
+randn('state',1);
+graphics_toolkit ("gnuplot");
+fm;
+close all;
+
+%
+% Functions that implement the GMSK modem ------------------------------------------------------
+%
+
+function gmsk_states = gmsk_init(gmsk_states, Rs)
+
+  % general 
+
+  verbose = gmsk_states.verbose;
+  gmsk_states.Fs = 48000;
+  gmsk_states.Rs = Rs;
+  M = gmsk_states.M = gmsk_states.Fs/gmsk_states.Rs;
+  global gmsk_mod_coeff;
+  global gmsk_demod_coeff;
+  gmsk_states.mod_coeff = (Rs/4800)*resample(gmsk_mod_coeff, 4800, Rs);
+
+  if verbose > 1
+    figure;
+    plot(gmsk_mod_coeff,'r;original 4800;')
+    hold on;
+    plot(gmsk_states.mod_coeff,'g;interpolated;')
+    hold off;
+    title('GMSK pulse shaping filter')
+  end
+
+  % set up FM modulator
+
+  fm_states.Fs = gmsk_states.Fs;  
+  fm_states.fc = 0;  
+  fm_max = fm_states.fm_max = Rs/2;
+  fd = fm_states.fd = Rs/4;
+  fm_states.Ts = gmsk_states.M;  
+  fm_states.pre_emp = fm_states.de_emp = 0;
+  fm_states.output_filter = 1;
+  gmsk_states.fm_states = analog_fm_init(fm_states);
+
+endfunction
+
+
+function [tx tx_filt tx_symbols] = gmsk_mod(gmsk_states, tx_bits)
+  M = gmsk_states.M;
+  nsym = length(tx_bits);
+  nsam = nsym*M;
+  verbose = gmsk_states.verbose;
+
+  % NRZ sequence of symbols
+
+  tx_symbols = zeros(1,nsam);
+  for i=1:nsym
+    tx_symbols(1+(i-1)*M:i*M) = -1 + 2*tx_bits(i);
+  end
+
+  tx_filt = filter(gmsk_states.mod_coeff, 1, tx_symbols);
+  
+  if verbose > 1
+    figure;
+    clf
+    plot(tx_filt(1:M*10))
+    title('tx signal after filtering, before FM mod')
+  end
+
+  tx = analog_fm_mod(gmsk_states.fm_states, tx_filt);
+endfunction
+
+
+function [rx_bits rx_int rx_filt] = gmsk_demod(gmsk_states, rx)
+  M = gmsk_states.M;
+  Rs = gmsk_states.Rs;
+  Fs = gmsk_states.Fs;
+  nsam = length(rx);
+  nsym = floor(nsam/M);
+  global gmsk_demod_coeff;
+  wd = 2*pi*gmsk_states.fm_states.fd/gmsk_states.Fs;
+  timing_angle_log = zeros(1,length(rx));
+  rx_int = zeros(1,length(rx));
+
+  if gmsk_states.coherent_demod
+
+    % See IEEE Trans on Comms, Muroyta et al, 1981, "GSM Modulation
+    % for Digital Radio Telephony" Fig 8:
+
+    % matched filter
+
+    rx_filt = filter(gmsk_states.mod_coeff, 1, rx);
+
+    % Property of MSK that re and im arms are sequences of 2T
+    % long symbols, can be demodulated like QPSK with matched filter
+    % and integrate and dump.
+
+    % integrate energy in symbols 2T long in re and im arms
+    % note this could be combined with matched filter
+
+    rx_int = conv(rx_filt,ones(1,2*M));
+
+    % phase and fine frequency tracking and correction ------------------------
+
+    if gmsk_states.phase_track
+      % DCO design from "Introduction To Phase-Lock Loop System Modeling", Wen Li
+      % http://www.ece.ualberta.ca/~ee401/parts/data/PLLIntro.pdf
+
+      eta = 0.707;
+      wn = 2*pi*10*(Rs/4800);  % (Rs/4800) -> found reducing the BW benifical with falling Rs
+      Ts = 1/Fs;
+      g1 = 1 - exp(-2*eta*wn*Ts);
+      g2 = 1 + exp(-2*eta*wn*Ts) - 2*exp(-eta*wn*Ts)*cos(wn*Ts*sqrt(1-eta*eta));
+      Gpd = 2/pi;
+      Gvco = 1;
+      G1 = g1/(Gpd*Gvco);  G2 = g2/(Gpd*Gvco);
+      %printf("g1: %e g2: %e G1: %e G2: %e\n", g1, g2, G1, G2);
+
+      filt_prev = dco = lower = ph_err_filt = ph_err = 0;
+      dco_log = filt_log = zeros(1,nsam);
+
+      % w is the ref sine wave at the timing clock frequency
+      % tw is the length of the window used to estimate timing
+
+      k = 1;
+      tw = 200*M;
+      xr_log = []; xi_log = [];
+      w_log = [];
+      timing_clock_phase = 0;
+      timing_angle = 0;
+      timing_angle_log = zeros(1,nsam);
+
+      for i=1:nsam
+
+        % update sample timing estimate every tw samples
+
+        if mod(i,tw) == 0
+          l = i - tw+1;
+          xr = abs(real(rx_int(l:l+tw-1)));
+          xi = abs(imag(rx_int(l:l+tw-1)));
+          w = exp(j*(l:l+tw-1)*2*pi*(Rs/2)/Fs);
+          X = xr * w';
+          timing_clock_phase = timing_angle = angle(X);
+          k++;
+          xr_log = [xr_log xr];
+          xi_log = [xi_log xi];
+          w_log = [w_log w];
+        else
+          timing_clock_phase += (2*pi)/(2*M);
+        end
+        timing_angle_log(i) = timing_angle;
+
+        rx_int(i) *= exp(-j*dco);
+        ph_err = sign(real(rx_int(i))*imag(rx_int(i)))*cos(timing_clock_phase);
+        lower = ph_err*G2 + lower;
+        filt  = ph_err*G1 + lower;
+        dco   = dco + filt;
+        filt_log(i) = filt;
+        dco_log(i) = dco;
+      end
+      
+      figure;
+      clf
+      subplot(211);
+      plot(filt_log);
+      title('PLL filter')
+      subplot(212);
+      plot(dco_log/pi);
+      title('PLL DCO phase');
+      %axis([1 nsam -0.5 0.5])
+    end
+
+    % sample integrator output at correct timing instant
+    
+    timing_adj = timing_angle_log*2*M/(2*pi);
+    timing_adj_uw = unwrap(timing_angle_log)*2*M/(2*pi);
+    % Toff = floor(2*M+timing_adj);
+    Toff = floor(timing_adj_uw+0.5);
+    k = 1;
+    re_syms = im_syms = zeros(1,nsym/2);
+  
+    for i=2*M:2*M:nsam
+      if (i-Toff(i)+M) < nsam
+        re_syms(k) = real(rx_int(i-Toff(i)));
+        im_syms(k) = imag(rx_int(i-Toff(i)+M));
+      end
+      %re_syms(k) = real(rx_int(i-10));
+      %im_syms(k) = imag(rx_int(i+M-10));
+      k++;
+    end
+
+    figure
+    subplot(211)
+    stem(re_syms)
+    subplot(211)
+    stem(im_syms)
+    
+    figure;
+    clf
+    subplot(211)
+    plot(timing_adj);
+    title('Timing est');
+    subplot(212)
+    plot(Toff);
+    title('Timing est unwrap');
+
+    % XORs/adders on the RHS of Muroyta et al Fig 8 (a) and (b).  We
+    % simulate digital logic bit stream at clock rate Rs, even though
+    % we sample integrators at rate Rs/2.  I can't explain how and why
+    % this logic works/is required.  I think it can be worked out from
+    % comparing to MSK/OQPSK demod designs.
+
+    l = length(re_syms);
+    l2 = 2*l;
+    re_bits = zeros(1,l2);
+    im_bits = zeros(1,l2);
+    clk_bits = zeros(1,l2);
+    for i=1:l-1
+      re_bits(2*(i-1)+1)  = re_syms(i) > 0;
+      re_bits(2*(i-1)+2)  = re_syms(i) > 0;
+      im_bits(2*(i-1)+2)  = im_syms(i) > 0;
+      im_bits(2*(i-1)+3)  = im_syms(i) > 0;
+      clk_bits(2*(i-1)+1) = 0;
+      clk_bits(2*(i-1)+2) = 1;
+    end
+
+    rx_bits = bitxor(bitxor(re_bits,im_bits),  clk_bits);
+    rx_bits = rx_bits(2:length(rx_bits)-1);
+  else
+    % non-coherent demod
+
+    % filter to get rid of most of noise before FM demod, but doesnt
+    % introduce any ISI
+
+    fc = Rs/(Fs/2);
+    bin  = firls(200,[0 fc*(1-0.05) fc*(1+0.05) 1],[1 1 0.01 0.01]);
+    rx_filt = filter(bin, 1, rx);
+
+    % FM demod
+
+    rx_diff = [ 1 rx_filt(2:nsam) .* conj(rx_filt(1:nsam-1))];
+    rx_filt = (1/wd)*atan2(imag(rx_diff),real(rx_diff));
+
+    % low pass filter, trade off betwen ISI and removing noise
+
+    rx_filt = filter(gmsk_demod_coeff, 1, rx_filt);  
+    Toff = 7;
+    rx_bits = real(rx_filt(1+Toff:M:length(rx_filt)) > 0);
+
+   end
+
+endfunction
+
+
+% Initial frequency offset estimation. Look for line a centre
+% frequency, which is the strongest component when ...101010... is
+% used to modulate the GMSK signal.  Note just searching for a single
+% line will get false lock on random sine waves but that's OK for a
+% PoC.  It could be improved by checking for other lines, or
+% demodulating the preamble and checking for bit errors.
+  
+function [freq_offset_est ratio] = gmsk_est_freq_offset(gmsk_states, rx, verbose)
+  Fs = gmsk_states.Fs;
+  Rs = gmsk_states.Rs;
+
+  % Suggest Rs/10 symbols of preamble (100ms), this works OK at
+  % Rs=4800 and Es/No = 6dB.  The large, Fs sample FFT size is used
+  % for convenience (the bin resolution is 1 Hz), for real time we
+  % would decimate and use smaller FFT to save CPU and memory.
+  
+  ndft = Fs;
+  f = fft(rx .* hanning(length(rx))', ndft);
+  f = fftshift(f);
+
+  start_bin = 1 + Fs/2-Rs/4; 
+  stop_bin = start_bin + Rs/2;
+  [max_val max_bin] = max(abs(f(start_bin:stop_bin)));
+  
+  max_bin -= Rs/4 + 1;
+  if verbose > 1
+    printf("ndft: %d start_bin: %d stop_bin: %d max_bin: %d\n", ndft, start_bin, stop_bin, max_bin);
+  end
+
+  % calc ratio of line energy to total energy.  For a valid preamble
+  % this was measured as about 0.20 to 0.25 depending on noise.
+
+  sum_sq = sum(abs(f(start_bin:stop_bin)) .^ 2);
+  ratio = sqrt(max_val*max_val/sum_sq);
+
+  % map max_bin to frequency offset
+
+  freq_offset_est = max_bin;  
+
+  if verbose > 1
+    printf("freq_offset_est: %f  pk/rms ratio: %f \n", freq_offset_est, ratio);
+    figure;
+    clf
+    subplot(211)
+    plot(rx,'+')
+    title('rx signal on complex plane')
+    subplot(212)
+    plot(-Rs/4:Rs/4, 20*log10(abs(f(start_bin:stop_bin))));
+    axis([-Rs/4 Rs/4 0 80]);
+    title('spectrum of rx signal');
+  end
+
+endfunction
+
+%
+%  Functions for Testing the GMSK modem --------------------------------------------------------
+%
+
+function sim_out = gmsk_test(sim_in)
+  nsym =  sim_in.nsym;
+  EbNodB = sim_in.EbNodB;
+  verbose = sim_in.verbose;
+  Rs = 4800;
+
+  gmsk_states.verbose = verbose;
+  gmsk_states.coherent_demod = sim_in.coherent_demod;
+  gmsk_states.phase_track = 0;
+  gmsk_states = gmsk_init(gmsk_states, Rs);
+  M = gmsk_states.M;
+  Fs = gmsk_states.Fs;
+  Rs = gmsk_states.Rs;
+  Bfm = gmsk_states.fm_states.Bfm;
+  for ne = 1:length(EbNodB)
+    aEbNodB = EbNodB(ne);
+    EbNo = 10^(aEbNodB/10);
+    variance = Fs/(Rs*EbNo);
+
+    tx_bits = round(rand(1, nsym));
+    %tx_bits = ones(1, nsym);
+    %tx_bits = zeros(1, nsym);
+    %tx_bits(1:2:nsym) = 0;
+    [tx tx_filt tx_symbols] = gmsk_mod(gmsk_states, tx_bits);
+    nsam = length(tx);
+    
+    noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+    rx    = tx*exp(j*pi/2) + noise;
+
+    [rx_bits rx_out rx_filt] = gmsk_demod(gmsk_states, rx(1:length(rx)));
+
+    % search for frame location over a range
+
+    Nerrs_min = nsym; Nbits_min = nsym; l = length(rx_bits);
+    for i=1:100;
+      Nerrs = sum(xor(rx_bits(i:l), tx_bits(1:l-i+1)));
+      if Nerrs < Nerrs_min
+        Nerrs_min = Nerrs;
+        Nbits_min = l;
+      end
+    end
+    TERvec(ne) = Nerrs_min;
+    BERvec(ne) = Nerrs_min/Nbits_min;
+    
+    if verbose > 0
+      printf("EbNo dB: %3.1f Nerrs: %d BER: %f BER Theory: %f\n", aEbNodB, Nerrs_min, BERvec(ne), 0.5*erfc(sqrt(0.75*EbNo)));
+    end
+
+    if verbose > 1
+
+      if gmsk_states.coherent_demod == 0
+        Toff = 0; dsam = M*30;
+        figure;
+        clf
+        eyesyms = 2;
+        plot(rx_filt(dsam+1+Toff:dsam+eyesyms*M+Toff))
+        hold on;
+        for i=1:10
+          st = dsam+1+Toff+i*eyesyms*M;
+          en = st + eyesyms*M;
+          plot(rx_filt(st:en))
+        end
+        hold off;
+        %axis([dsam dsam+eyesyms*M -2 2]);
+        title('Eye Diagram');
+      else
+        figure;
+        nplot = 16;
+        clf;
+        subplot(211)
+        plot(real(rx_filt(1:nplot*M)))
+        axis([1 nplot*M -1 1])
+        title('Matched Filter');
+        subplot(212)
+        plot(imag(rx_filt(1:nplot*M)))
+        axis([1 nplot*M -1 1])
+
+        figure;
+        nplot = 16;
+        clf;
+        subplot(211)
+        plot(real(rx_out(1:nplot*M))/(2*M))
+        title('Integrator');
+        axis([1 nplot*M -1 1])
+        subplot(212)
+        plot(imag(rx_out(1:nplot*M)/(2*M)))
+        axis([1 nplot*M -1 1])
+     end
+
+      figure;
+      clf
+      subplot(211)
+      stem(tx_bits(1:20))
+      title('Tx Bits')
+      subplot(212)
+      stem(rx_bits(1:20))
+      title('Rx Bits')
+
+      figure;
+      clf
+      subplot(211);
+      f = fft(rx);
+      Tx = 20*log10(abs(f));
+      plot(Tx)
+      grid;
+      title('GMSK Demodulator Input Spectrum');
+      axis([1 5000 0 80])
+
+      subplot(212)
+      f = fft(tx);
+      f = f(1:length(f)/2);
+      cs = cumsum(abs(f).^2);
+      plot(cs)
+      hold on;
+      x = 0.99;
+      tots = x*sum(abs(f).^2);
+      xpercent_pwr = find(cs > tots);
+      bw = 2*xpercent_pwr(1);
+      plot([1 Fs/2],[tots tots],'r')
+      plot([bw/2 bw/2],[0 tots],'r')
+      hold off;  
+      title("Cumulative Power");
+      grid;
+      axis([1 5000 0 max(cs)])
+
+      printf("Bfm: %4.0fHz %3.0f%% power bandwidth %4.0fHz = %3.2f*Rb\n", Bfm, x*100, bw, bw/Rs);
+
+    end
+  end
+
+  sim_out.TERvec = TERvec;
+  sim_out.BERvec = BERvec;
+  sim_out.Rs = gmsk_states.Rs;
+endfunction
+
+
+function run_gmsk_single
+  sim_in.coherent_demod = 0;
+  sim_in.nsym = 4800;
+  sim_in.EbNodB = 10;
+  sim_in.verbose = 2;
+
+  sim_out = gmsk_test(sim_in);
+endfunction
+
+
+% Generate a bunch of BER versus Eb/No curves for various demods
+
+function run_gmsk_curves
+  sim_in.coherent_demod = 1;
+  sim_in.nsym = 48000;
+  sim_in.EbNodB = 2:10;
+  sim_in.verbose = 1;
+
+  gmsk_coh = gmsk_test(sim_in);
+
+  sim_in.coherent_demod = 0;
+  gmsk_noncoh = gmsk_test(sim_in);
+
+  Rs = gmsk_coh.Rs;
+  EbNo  = 10 .^ (sim_in.EbNodB/10);
+  alpha = 0.75; % guess for BT=0.5 GMSK
+  gmsk_theory.BERvec = 0.5*erfc(sqrt(alpha*EbNo));
+
+  % BER v Eb/No curves
+
+  figure;
+  clf;
+  semilogy(sim_in.EbNodB, gmsk_theory.BERvec,'r;GMSK theory;')
+  hold on;
+  semilogy(sim_in.EbNodB, gmsk_coh.BERvec,'g;GMSK sim coherent;')
+  semilogy(sim_in.EbNodB, gmsk_noncoh.BERvec,'b;GMSK sim non-coherent;')
+  hold off;
+  grid("minor");
+  axis([min(sim_in.EbNodB) max(sim_in.EbNodB) 1E-4 1])
+  legend("boxoff");
+  xlabel("Eb/No (dB)");
+  ylabel("Bit Error Rate (BER)")
+
+  % BER v C/No (1 Hz noise BW and Eb=C/Rs=1/Rs)
+  % Eb/No = (C/Rs)/(1/(N/B))
+  % C/N   = (Eb/No)*(Rs/B)
+
+  RsOnB_dB = 10*log10(Rs/1);
+  figure;
+  clf;
+  semilogy(sim_in.EbNodB+RsOnB_dB, gmsk_theory.BERvec,'r;GMSK theory;')
+  hold on;
+  semilogy(sim_in.EbNodB+RsOnB_dB, gmsk_coh.BERvec,'g;GMSK sim coherent;')
+  semilogy(sim_in.EbNodB+RsOnB_dB, gmsk_noncoh.BERvec,'b;GMSK sim non-coherent;')
+  hold off;
+  grid("minor");
+  axis([min(sim_in.EbNodB+RsOnB_dB) max(sim_in.EbNodB+RsOnB_dB) 1E-4 1])
+  legend("boxoff");
+  xlabel("C/No for Rs=4800 bit/s and 1 Hz noise bandwidth (dB)");
+  ylabel("Bit Error Rate (BER)")
+
+endfunction
+
+
+function [preamble_location freq_offset_est] = find_preamble(gmsk_states, M, npreamble, rx)
+  verbose = gmsk_states.verbose;
+
+  % look through rx buffer and determine if there is a valid preamble.  Use steps of half the
+  % preamble size in samples to try to bracket the pre-amble.
+
+  preamble_step = npreamble*M/2;
+  ratio = 0; freq_offset_est = 0; preamble_location = 0;
+  ratio_log = [];
+  for i=1:preamble_step:length(rx)-preamble_step
+    [afreq_offset_est aratio] = gmsk_est_freq_offset(gmsk_states, rx(i:i+preamble_step-1), verbose);
+    ratio_log = [ratio_log aratio];
+    if aratio > ratio
+      preamble_location = i;
+      ratio = aratio;
+      freq_offset_est = afreq_offset_est;
+    end
+  end
+  if verbose
+    printf("preamble location: %2.1f seconds est f_off: %5.1f Hz ratio: %3.2f\n", 
+    preamble_location/gmsk_states.Fs, freq_offset_est, ratio);   
+    figure;
+    plot(ratio_log);
+    title('Preamble ratio');
+  end
+endfunction
+
+
+% attempt to perform "coarse sync" sync with the received frames, we
+% check each frame for the best coarse sync position.  Brute force
+% approach, that would be changed for a real demod which has some
+% sort of unique word.  Start looking for valid frames 1 frame
+% after start of pre-amble to give PLL time to lock
+
+function [total_errors total_bits Nerrs_log Nerrs_all_log errors_log] = coarse_sync_ber(nframes_rx, tx_frame, rx_bits)
+
+  Nerrs_log = zeros(1, nframes_rx);
+  Nerrs_all_log = zeros(1, nframes_rx);
+  total_errors = 0;
+  total_bits   = 0;
+  framesize = length(tx_frame);
+  errors_log = [];
+
+  for f=2:nframes_rx-1
+    Nerrs_min = framesize;
+    for i=1:framesize;
+      st = (f-1)*framesize+i; en = st+framesize-1;
+      errors = xor(rx_bits(st:en), tx_frame); 
+      Nerrs = sum(errors);
+      if Nerrs < Nerrs_min
+        Nerrs_min = Nerrs;
+        errors_min = errors;
+      end
+    end
+    Nerrs_all_log(f) = Nerrs_min;
+    if Nerrs_min/framesize < 0.1
+      errors_log = [errors_log errors_min];
+      Nerrs_log(f) = Nerrs_min;
+      total_errors += Nerrs_min;
+      total_bits   += framesize;
+    end
+  end
+endfunction
+
+function plot_spectrum(gmsk_states, rx, preamble_location, title_str)
+  Fs = gmsk_states.Fs;
+  st = preamble_location + gmsk_states.npreamble*gmsk_states.M;
+  sig = rx(st:st+Fs*0.5);
+  h = hanning(length(sig))';
+  Rx=20*log10(abs(fftshift(fft(sig .* h, Fs))));
+  figure;
+  plot(-Fs/2:Fs/2-1,Rx);
+  grid("minor");
+  xlabel('Hz');
+  ylabel('dB');
+  topy = ceil(max(Rx)/10)*10;
+  axis([-4000 4000 topy-50 topy+10])
+  title(title_str);
+endfunction
+
+% Give the demod a hard time: frequency, phase, time offsets, sample clock difference
+   
+function run_test_channel_impairments
+  Rs = 1200;
+  verbose = 1;
+  aEbNodB = 6;
+  phase_offset = pi/2;
+  freq_offset  = -104;
+  timing_offset = 100E3;
+  sample_clock_offset_ppm = -500;
+  interferer_freq = -1500;
+  interferer_amp  = 0;
+  nsym = 4800*2;
+  npreamble = 480;
+
+  gmsk_states.npreamble = npreamble;
+  gmsk_states.verbose = verbose;
+  gmsk_states.coherent_demod = 1;
+  gmsk_states.phase_track    = 1;
+  gmsk_states = gmsk_init(gmsk_states, Rs);
+  Fs = gmsk_states.Fs;
+  Rs = gmsk_states.Rs;
+  M  = gmsk_states.M;
+
+  % A frame consists of nsym random data bits.  Some experimentation
+  % has shown they must be random-ish data (not say 11001100...) for
+  % timing estimator to work.  However initial freq offset estimation
+  % is a lot easier with a 01010 type sequence, so we construct a 
+  % frame with a pre-amble followed by frames of random data.
+
+  framesize = 480;
+  nframes = floor(nsym/framesize);
+  tx_frame = round(rand(1, framesize));
+  tx_bits = zeros(1,npreamble);
+  tx_bits(1:2:npreamble) = 1;
+  for i=1:nframes
+    tx_bits = [tx_bits tx_frame];
+  end
+
+  [tx tx_filt tx_symbols] = gmsk_mod(gmsk_states, tx_bits);
+
+  tx = resample(tx, 1E6, 1E6-sample_clock_offset_ppm);
+  tx = [zeros(1,timing_offset) tx];
+  nsam = length(tx);
+
+  if verbose > 1
+    figure;
+    subplot(211)
+    st = timing_offset; en = st+M*10;
+    plot(real(tx(st:en)))
+    title('Real part of tx');
+    subplot(212)
+    plot(imag(tx(st:en)))
+    title('Imag part of tx');
+  end
+
+  EbNo = 10^(aEbNodB/10);
+  variance = Fs/(Rs*EbNo);
+  noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+  w  = (0:nsam-1)*2*pi*freq_offset/Fs + phase_offset;
+  interferer = interferer_amp*exp(j*interferer_freq*(2*pi/Fs)*(0:nsam-1));
+
+  rx = sqrt(2)*tx.*exp(j*w) + noise + interferer;
+  
+  % optional dump to file
+
+  if 1
+    fc = 1500; gain = 10000;
+    wc = 2*pi*fc/Fs;
+    w1 = exp(j*wc*(1:nsam));
+    rx1 = gain*real(rx .* w1);
+    fout = fopen("rx_6dB.raw","wb");
+    fwrite(fout, rx1, "short");
+    fclose(fout);
+  end
+
+  rx = rx1 .* conj(w1);
+
+  [preamble_location freq_offset_est] = find_preamble(gmsk_states, M, npreamble, rx);
+  w_est  = (0:nsam-1)*2*pi*freq_offset_est/Fs;
+  rx = rx.*exp(-j*w_est);
+
+  plot_spectrum(gmsk_states, rx, preamble_location, "GMSK rx just after preamble");
+
+  % printf("ntx: %d nrx: %d ntx_bits: %d\n", length(tx), length(rx), length(tx_bits));
+
+  [rx_bits rx_out rx_filt] = gmsk_demod(gmsk_states, rx(preamble_location+framesize:nsam));
+  nframes_rx = length(rx_bits)/framesize;
+
+  % printf("ntx: %d nrx: %d ntx_bits: %d nrx_bits: %d\n", length(tx), length(rx), length(tx_bits), length(rx_bits));
+
+  [total_errors total_bits Nerrs_log Nerrs_all_log] = coarse_sync_ber(nframes_rx, tx_frame, rx_bits);
+
+  ber = total_errors/total_bits;
+
+  printf("Eb/No: %3.1f f_off: %4.1f ph_off: %4.3f Nframes: %d Nbits: %d Nerrs: %d BER: %f\n", 
+         aEbNodB, freq_offset, phase_offset, nframes_rx, total_bits, total_errors, ber);
+
+  figure;
+  clf
+  subplot(211)
+  plot(Nerrs_log,'r;errors/frame counted for BER;');
+  hold on;
+  plot(Nerrs_all_log,'g;all errors/frame;');
+  hold off;
+  legend("boxoff");
+  title('Bit Errors')
+  subplot(212)
+  stem(real(cumsum(Nerrs_log)))
+  title('Cumulative Bit Errors')
+
+endfunction
+    
+
+% Generates a Fs=48kHz raw file of 16 bit samples centred on 1500Hz,
+% Suitable for transmitting with a SSB tx
+
+function gmsk_tx(tx_file_name)
+  rand('state',1); 
+  Rs = 1200;
+  nsym =  Rs*4;
+  framesize = 480;
+  npreamble = 480;
+  gain      = 10000;
+  fc        = 1500;
+
+  gmsk_states.verbose = 0;
+  gmsk_states.coherent_demod = 1;
+  gmsk_states.phase_track    = 1;
+  gmsk_states = gmsk_init(gmsk_states, Rs);
+  Fs = gmsk_states.Fs;
+  Rs = gmsk_states.Rs;
+  M  = gmsk_states.M;
+
+  % generate frame with preamble
+
+  nframes = floor(nsym/framesize)
+  tx_frame = round(rand(1, framesize));
+  tx_bits = zeros(1,npreamble);
+  tx_bits(1:2:npreamble) = 1;
+  for i=1:nframes
+    tx_bits = [tx_bits tx_frame];
+  end
+  
+  [tx tx_filt tx_symbols] = gmsk_mod(gmsk_states, tx_bits);
+  nsam = length(tx);
+
+  wc = 2*pi*fc/Fs;
+  w = exp(j*wc*(1:nsam));
+  tx = gain*real(tx .* w);
+  figure;
+  plot(tx(1:4000))
+  fout = fopen(tx_file_name,"wb");
+  fwrite(fout, tx, "short");
+  fclose(fout);
+
+endfunction
+
+
+% Reads a file of Fs=48kHz 16 bit samples centred on 1500Hz, and
+% measures the BER.
+
+function gmsk_rx(rx_file_name, err_file_name)
+  rand('state',1); 
+
+  Rs = 1200;
+  framesize = 480;
+  npreamble = 480;
+  fc        = 1500;
+
+  gmsk_states.npreamble = npreamble;
+  gmsk_states.verbose = 1;
+  gmsk_states.coherent_demod = 1;
+  gmsk_states.phase_track    = 1;
+  gmsk_states = gmsk_init(gmsk_states, Rs);
+  Fs = gmsk_states.Fs;
+  Rs = gmsk_states.Rs;
+  M  = gmsk_states.M;
+
+  tx_frame = round(rand(1, framesize));
+
+  % get real signal at fc offset and convert to baseband complex
+  % signal
+  
+  fin = fopen(rx_file_name,"rb");
+  rx = fread(fin,"short")';
+  fclose(fin);
+  rx = filter([1 -0.999],[1 -0.99],rx);
+  nsam = length(rx);
+  wc = 2*pi*fc/Fs;
+  w = exp(-j*wc*(1:nsam));
+  rxbb = rx .* w;
+  figure;
+  plot(rx);
+
+  % find preamble
+
+  [preamble_location freq_offset_est] = find_preamble(gmsk_states, M, npreamble, rxbb);
+
+  % power of signal, averaged over window
+  % TODO: remove wave file header, scale of actual level
+  %       filter so we measure only energy in our passband
+  %       work out noise BW of filter.  Use GMSK filter?
+
+  [b a] = cheby2(6,40,[200 3000]/(Fs/2));
+  %bpwr_lp  = fir2([200,4000/(Fs/2));
+  noise_bw = var(filter(b,a,randn(1,1E6)));
+
+  rx_filt = filter(b, a, rx(1000:length(rx)));
+  npower_window = 200*M;
+  rx_power = conv(rx_filt.^2,ones(1,npower_window))/(npower_window);
+  rx_power_dB = 10*log10(rx_power);
+  figure;
+  subplot(211)
+  plot(rx_filt(1000:length(rx_filt)));
+  title('GMSK Power (narrow filter)');
+  subplot(212)
+  plot(rx_power_dB);
+  axis([1 length(rx_power) max(rx_power_dB)-29 max(rx_power_dB)+1])
+  grid("minor")
+
+  % Work out where to sample N, and S+N
+
+  noise_end = preamble_location - 2*npreamble*M;
+  noise_start = noise_end - Fs;
+  if noise_start < 1
+    printf("Hmm, we really need >1 second of noise only before preamble to measure noise!\n");
+  else
+    noise = mean(rx_power_dB(noise_start:noise_end));
+    signal_noise_start = preamble_location + 2*npreamble*M;
+    signal_noise_end = signal_noise_start + Fs;
+    signal_noise = mean(rx_power_dB(signal_noise_start:signal_noise_end));
+    hold on;
+    plot([noise_start noise_end],[noise noise],'color','r','linewidth',5);
+    plot([signal_noise_start signal_noise_end],[signal_noise signal_noise],'color','r','linewidth',5);
+
+    % determine SNR
+  
+    noise_lin = 10 ^ (noise/10);
+    signal_noise_lin = 10 ^ (signal_noise/10);
+    signal_lin = signal_noise_lin - noise_lin;
+    signal = 10*log10(signal_lin);
+    snr = signal - noise;
+    fudge_factor = 3;                           % 3dB for single/double sided noise adjustment?  Just a guess
+    CNo = snr + 10*log10(Fs*noise_bw) - fudge_factor;
+    EbNo = CNo - 10*log10(Rs);  
+
+    EbNo_lin  = 10 .^ (EbNo/10);
+    alpha = 0.75;                             % guess for BT=0.5 GMSK
+    ber_theory = 0.5*erfc(sqrt(alpha*EbNo_lin));
+
+    printf("Estimated S: %3.1f N: %3.1f Nbw: %4.0f Hz SNR: %3.1f CNo: %3.1f EbNo: %3.1f BER theory: %f\n",
+           signal, noise, Fs*noise_bw, snr, CNo, EbNo, ber_theory);
+
+  % FM signal is centred on 12 kHz and 16 kHz wide so lets also work out noise there
+
+  [b a] = cheby2(6,40,[12000-8000 12000+8000]/(Fs/2));
+  noise_bw_fm = var(filter(b,a,randn(1,1E6)));
+
+  rx_filt_fm = filter(b, a, rx(1000:length(rx)));
+  rx_power_fm = conv(rx_filt_fm.^2,ones(1,npower_window))/(npower_window);
+  rx_power_dB_fm = 10*log10(rx_power_fm);
+  
+  noise = mean(rx_power_dB_fm(noise_start:noise_end))*ones(1, length(rx_power_fm));
+  noise_lin = 10 .^ (noise/10);
+
+  signal_lin = rx_power_fm - noise_lin;
+  signal = 10*log10(abs(signal_lin) + 1E-6);
+  snr = signal - noise;
+
+  CNo = snr + 10*log10(Fs*noise_bw_fm) - fudge_factor;
+
+  figure
+  plot(rx_power_dB_fm,'r;signal plus noise;');
+  hold on;
+  plot(CNo,'g;C/No;');
+  hold off;
+  top_fm = ceil(max(CNo)/10)*10;
+  axis([1 length(rx_power_dB_fm) 20 top_fm])
+  grid("minor")
+  legend("boxoff");
+  title('FM C/No');
+  end
+
+  % spectrum of a chunk of GMSK signal just after preamble
+
+  plot_spectrum(gmsk_states, rx, preamble_location, "GMSK rx just after preamble");
+
+  % correct freq offset and demodulate
+
+  w_est  = (0:nsam-1)*2*pi*freq_offset_est/Fs;
+  rxbb = rxbb.*exp(-j*w_est);
+  st = preamble_location+npreamble*M; 
+  %en = min(nsam,st + 4*framesize*M); 
+  en = nsam;
+  gmsk_statres.verbose = 2;
+  [rx_bits rx_out rx_filt] = gmsk_demod(gmsk_states, rxbb(st:en));
+  nframes_rx = length(rx_bits)/framesize;
+
+  % count errors
+
+  [total_errors total_bits Nerrs_log Nerrs_all_log errors_log] = coarse_sync_ber(nframes_rx, tx_frame, rx_bits);
+
+  ber = total_errors/total_bits;
+
+  printf("Nframes: %d Nbits: %d Nerrs: %d BER: %f\n", 
+         nframes_rx, total_bits, total_errors, ber);
+
+  % Optionally save a file of bit errors so we can simulate the effect on Codec 2
+
+  if nargin == 2
+
+    % To simulate effects of these errors on Codec 2:
+    %   $  ~/codec2-dev/octave$ ../build_linux/src/c2enc 1300 ../raw/hts1raw - | ../build_linux/src/insert_errors - - ssb7dbSNR.err 52 | ../build_linux/src/c2dec 1300 - - | play -t raw -r 8000 -s -2 -
+    % Note in this example I'm using the 1300 bit/s codec, it's sig more robust that 1200 bit/s, 
+    % if we ran the GMSK modem at 1300 bit/s there would be a 10*log10(1300/1200) = 0.35dB SNR penalty 
+
+    fep=fopen(err_file_name,"wb"); fwrite(fep, errors_log, "short"); fclose(fep);
+  end
+
+  figure;
+  clf
+  subplot(211)
+  plot(Nerrs_log,'r;errors/frame counted for BER;');
+  hold on;
+  plot(Nerrs_all_log,'g;all errors/frame;');
+  hold on;
+  title('Bit Errors')
+  legend("boxoff");
+  subplot(212)
+  stem(real(cumsum(Nerrs_log)))
+  title('Cumulative Bit Errors')
+endfunction
+
+
+%run_gmsk_single
+%run_gmsk_curves
+%run_gmsk_init
+%run_test_channel_impairments
+gmsk_tx("test_gmsk.raw")
+gmsk_rx("test_gmsk.raw")
+%gmsk_rx("ssb25db.wav")
+%gmsk_rx("~/Desktop/ssb_fm_gmsk_high.wav")
+%gmsk_rx("~/Desktop/test_gmsk_28BER.raw")
+%gmsk_rx("~/Desktop/gmsk_rec_reverse.wav")
+
diff --git a/codec2/branches/0.7/octave/gp_interleaver.m b/codec2/branches/0.7/octave/gp_interleaver.m
new file mode 100644 (file)
index 0000000..1ee0ee3
--- /dev/null
@@ -0,0 +1,46 @@
+% gp_interleaver.m
+%
+% David Rowe May 2017
+%
+% Golden Prime Interleaver. My interprestation of "On the Analysis and
+% Design of Good Algebraic Interleavers", Xie et al,eq (5).
+
+1;
+
+% Choose b for Golden Prime Interleaver.  b is chosen to be the
+% closest integer, which is relatively prime to N, to the Golden
+% section of N.
+
+function b = choose_interleaver_b(Nbits)
+
+  p = primes(Nbits);
+  i = 1;
+  while(p(i) < Nbits/1.62)
+    i++;
+  end
+  b = p(i);
+  assert(gcd(b,Nbits) == 1, "b and Nbits must be co-prime");
+end
+
+
+function interleaved_frame = gp_interleave(frame)
+  Nbits = length(frame);
+  b = choose_interleaver_b(Nbits);
+  interleaved_frame = zeros(1,Nbits);
+  for i=1:Nbits
+    j = mod((b*(i-1)), Nbits);
+    interleaved_frame(j+1) = frame(i);
+  end
+endfunction
+
+
+function frame = gp_deinterleave(interleaved_frame)
+  Nbits = length(interleaved_frame);
+  b = choose_interleaver_b(Nbits);
+  frame = zeros(1,Nbits);
+  for i=1:Nbits
+    j = mod((b*(i-1)), Nbits);
+    frame(i) = interleaved_frame(j+1);
+  end
+endfunction
+
diff --git a/codec2/branches/0.7/octave/hackrf_dc.m b/codec2/branches/0.7/octave/hackrf_dc.m
new file mode 100644 (file)
index 0000000..a204e70
--- /dev/null
@@ -0,0 +1,26 @@
+% hackrf_dc.m
+%
+% David Rowe Nov 2015
+%
+% Downconverts a HackRF IQ sample file to a lower sample rate
+%
+% To sample a -60dB signal:
+%   $ hackrf_transfer -r df1.iq -f 439200000  -n 10000000 -l 20 -g 40play file at 10.7MHz used:
+%   octave:25> d = hackrf_dc("df1.iq")
+
+function d = hackrf_dc(infilename)
+  Fs1 = 10E6;   % input sample rate to HackRF
+  Fs2 = 96E3;   % output sample rate
+  fc  = 700E3;  % offset to shift input by, HackRF doesn't like signals in the centre
+  
+  s1 = load_hackrf(infilename);
+  ls1 = length(s1);
+  ls1 = 20*Fs1;
+  t = 0:ls1-1;
+
+  % shift down to baseband from Fc, not sure of rot90 rather than trasnpose operator '
+  % to avoid unwanted complex conj
+
+  s2 = rot90(s1(1:ls1)) .* exp(-j*2*pi*t*fc/Fs1);
+  d = resample(s2, Fs2, Fs1);
+end
diff --git a/codec2/branches/0.7/octave/hackrf_twotone.m b/codec2/branches/0.7/octave/hackrf_twotone.m
new file mode 100644 (file)
index 0000000..1d5aa02
--- /dev/null
@@ -0,0 +1,24 @@
+% hackrf_twotone.m
+%
+% David Rowe Nov 2015
+%
+% Generates a two tone test signal that can be played out of HackRF
+%
+% To play file at 10.7MHz used:
+%   $ hackrf_transfer -t ../octave/twotone.iq -f 10000000 -a 0 -x 47
+%
+% However 2nd harmonic at 21.4 was only -32dBC so not really useful for my application
+% in testing an ADC
+
+Fs = 8E6;
+fc = 2E6;
+f1 = fc;
+f2 = fc+1E3;
+A = 127;
+T = 2;
+
+N = T*Fs;
+t = 0:N-1;
+%s = A*exp(j*2*pi*t*f1/Fs) + A*exp(j*2*pi*t*f2/Fs);
+s = A*exp(j*2*pi*t*f2/Fs);
+save_hackrf("twotone.iq",s);
diff --git a/codec2/branches/0.7/octave/hackrf_uc.m b/codec2/branches/0.7/octave/hackrf_uc.m
new file mode 100644 (file)
index 0000000..0f55bd1
--- /dev/null
@@ -0,0 +1,47 @@
+% hackrf_uc.m
+%
+% David Rowe Nov 2015
+%
+% Upconverts a real baseband sample file to a file suitable for input into a HackRF
+%
+% To play file at 10.7MHz used:
+%   octave:25> hackrf_uc("fsk_10M.iq","fsk_horus_rx_1200_96k.raw")
+%   $ hackrf_transfer -t ../octave/fsk_10M.iq -f 10000000 -a 1 -x 40
+
+function hackrf_uc(outfilename, infilename)
+  pkg load signal;
+  Fs1 = 48E3;  % input sample rate
+  Fs2 = 10E6;  % output sample rate to HackRF
+  fc = 700E3-24E3;  % offset to shift to, HackRF doesn't like signals in the centre
+  A  = 100;    % amplitude of signal after upc-nversion (max 127)
+  N  = Fs1*20;
+  
+  fin = fopen(infilename,"rb");
+  printf("1\n");
+  s1 = fread(fin,"short");
+  printf("1\n");
+  fclose(fin);
+  printf("1\n");
+  ls1 = length(s1);
+  printf("1\n");
+  N = ls1;
+  % single sided freq shifts, we don't want DSB
+  printf("1\n");
+  s1 = hilbert(s1(1:N)); 
+
+  % upsample to Fs2
+
+  M = Fs2/Fs1;
+  s2 = resample(s1(1:N),Fs2,Fs1);
+  ls2 = length(s2);
+  mx = max(abs(s2));
+  t = 0:ls2-1;
+  printf("2\n");
+  % shift up to Fc, note use of rot90 rather than trasnpose operator '
+  % as we don't want complex conj, that would shift down in freq
+
+  sout = rot90((A/mx)*s2) .* exp(j*2*pi*t*fc/Fs2);
+
+  save_hackrf(outfilename,sout);
+  
+end
diff --git a/codec2/branches/0.7/octave/hf_modem_curves.m b/codec2/branches/0.7/octave/hf_modem_curves.m
new file mode 100644 (file)
index 0000000..094802e
--- /dev/null
@@ -0,0 +1,272 @@
+% hf_modem_curves
+% David Rowe Feb 2017
+%
+% Ideal implementations of a bunch of different HF modems, used to
+% generate plots for a blog post.
+
+#{
+  [X] ideal AWGN/HF curves
+  [X] exp AWGN QPSK curves
+  [X] exp AWGN DQPSK curves
+  [X] exp HF channel model
+  [ ] diversity
+  [ ] COHPSK frames
+      + would require multiple carriers
+      + filtering or OFDM
+#}
+
+1;
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+
+% Rate Rs modem simulation model -------------------------------------------------------
+
+function sim_out = ber_test(sim_in)
+    bps     = 2;     % two bits/symbol for QPSK
+    Rs      = 50;    % symbol rate (needed for HF model)
+    
+    verbose = sim_in.verbose;
+    EbNovec = sim_in.EbNovec;
+    hf_en   = sim_in.hf_en;
+
+    % user can supply number of bits per point to get good results
+    % at high Eb/No
+
+    if length(sim_in.nbits) > 1
+      nbitsvec = sim_in.nbits;
+      nbitsvec += 100 - mod(nbitsvec,100);  % round up to nearest 100
+    else
+      nbitsvec(1:length(EbNovec)) = sim_in.nbits;
+    end
+
+    % init HF model
+
+    if hf_en
+
+      % some typical values
+
+      dopplerSpreadHz = 1.0; path_delay = 1E-3*Rs;
+
+      nsymb = max(nbitsvec)/2;
+      spread1 = doppler_spread(dopplerSpreadHz, Rs, nsymb);
+      spread2 = doppler_spread(dopplerSpreadHz, Rs, nsymb);
+      hf_gain = 1.0/sqrt(var(spread1)+var(spread2));
+      % printf("nsymb: %d lspread1: %d\n", nsymb, length(spread1));
+    end
+
+    for ne = 1:length(EbNovec)
+
+        % work out noise power -------------
+
+        EbNodB = EbNovec(ne);
+        EsNodB = EbNodB + 10*log10(bps);
+        EsNo = 10^(EsNodB/10);
+        variance = 1/EsNo;
+        nbits = nbitsvec(ne);
+        nsymb = nbits/bps;
+
+        % modulator ------------------------
+
+        tx_bits = rand(1,nbits) > 0.5;        
+        tx_symb = [];
+        prev_tx_symb = 1;
+        for s=1:nsymb
+          atx_symb = qpsk_mod(tx_bits(2*s-1:2*s));
+          if sim_in.dqpsk
+            atx_symb *= prev_tx_symb;
+            prev_tx_symb = atx_symb;
+          end
+          tx_symb = [tx_symb atx_symb];
+        end
+
+        % channel ---------------------------
+
+        rx_symb = tx_symb;
+
+        if hf_en
+
+          % simplified rate Rs simulation model that doesn't include
+          % ISI, just freq filtering.  We assume perfect phase estimation
+          % so it's just amplitude distortion.
+
+          hf_model1 = hf_model2 = zeros(1, nsymb);
+          for s=1:nsymb 
+            hf_model1(s) = hf_gain*(spread1(s) + exp(-j*path_delay)*spread2(s));
+            hf_model     = abs(hf_model1(s));
+
+            if sim_in.diversity
+              % include amplitude information from another frequency in channel model
+              w1 = 7*2*pi;
+              hf_model2(s) = hf_gain*(spread1(s) + exp(-j*w1*path_delay)*spread2(s));
+              hf_model     = 0.5*abs(hf_model1(s)) + 0.5*abs(hf_model2(s));
+            end
+
+            rx_symb(s) = rx_symb(s).*hf_model;
+          end
+        end
+
+        % variance is noise power, which is divided equally between real and
+        % imag components of noise
+
+        noise = sqrt(variance*0.5)*(randn(1,nsymb) + j*randn(1,nsymb));
+        rx_symb += noise;
+
+        % demodulator ------------------------------------------
+
+        % demodulate rx symbols to bits
+        rx_bits = [];
+        prev_rx_symb = 1;
+        for s=1:nsymb
+          arx_symb = rx_symb(s);
+          if sim_in.dqpsk
+            tmp = arx_symb;
+            arx_symb *= prev_rx_symb';
+            prev_rx_symb = tmp;
+          end
+          two_bits = qpsk_demod(arx_symb);
+          rx_bits = [rx_bits two_bits];
+        end
+        
+        % count errors -----------------------------------------
+
+        error_pattern = xor(tx_bits, rx_bits);
+        nerrors = sum(error_pattern);
+        bervec(ne) = nerrors/nbits;
+        if verbose
+          printf("EbNodB: % 3.1f nbits: %5d nerrors: %5d ber: %4.3f\n", EbNodB, nbits, nerrors, bervec(ne));
+          if verbose == 2
+            figure(2); clf;
+            plot(rx_symb*exp(j*pi/4),'+','markersize', 10);
+            mx = max(abs(rx_symb));
+            axis([-mx mx -mx mx]);
+            if sim_in.diversity && sim_in.hf_en 
+              figure(3);
+              plot(1:nsymb, abs(hf_model1), 1:nsymb, abs(hf_model2), 'linewidth', 2);
+            end
+          end
+        end
+    end
+
+    sim_out.bervec = bervec;
+endfunction
+
+
+% -------------------------------------------------------------
+
+
+function run_single
+    sim_in.verbose   = 2;
+    sim_in.nbits     = 1000;
+    sim_in.EbNovec   = 4;
+    sim_in.dqpsk     = 0;
+    sim_in.hf_en     = 0;
+    sim_in.diversity = 0;
+
+    sim_qpsk = ber_test(sim_in);
+endfunction
+
+
+function run_curves
+    max_nbits = 1E5;
+    sim_in.verbose = 1;
+    sim_in.EbNovec = 0:10;
+    sim_in.dqpsk   = 0;
+    sim_in.hf_en   = 0;
+    sim_in.diversity = 0;
+
+    % AWGN -----------------------------
+
+    ber_awgn_theory = 0.5*erfc(sqrt(10.^(sim_in.EbNovec/10)));
+    sim_in.nbits    = min(max_nbits, floor(500 ./ ber_awgn_theory));
+
+    sim_qpsk = ber_test(sim_in);
+    sim_in.dqpsk = 1;
+    sim_dqpsk = ber_test(sim_in);
+       
+    % HF -----------------------------
+
+    hf_sim_in = sim_in; hf_sim_in.dqpsk = 0; hf_sim_in.hf_en = 1;
+    hf_sim_in.EbNovec = 0:16;
+
+    EbNoLin = 10.^(hf_sim_in.EbNovec/10);
+    ber_hf_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));
+
+    hf_sim_in.nbits = min(max_nbits, floor(500 ./ ber_hf_theory));
+    sim_qpsk_hf = ber_test(hf_sim_in);
+
+    hf_sim_in.dqpsk = 1; 
+    sim_dqpsk_hf = ber_test(hf_sim_in);
+
+    hf_sim_in.dqpsk = 0; 
+    hf_sim_in.diversity = 1;
+    sim_qpsk_hf_div = ber_test(hf_sim_in);
+
+    % Plot results --------------------
+
+    close all;
+    figure (1, 'position', [100, 10, 600, 400]); clf;
+
+    semilogy(sim_in.EbNovec, ber_awgn_theory,'r+-;QPSK AWGN theory;', 'linewidth', 2)
+    xlabel('Eb/No (dB)')
+    ylabel('BER')
+    grid("minor")
+    axis([min(sim_in.EbNovec) max(sim_in.EbNovec) 1E-3 1])
+    hold on;
+    
+    semilogy([0 4 4], [ber_awgn_theory(5) ber_awgn_theory(5) 1E-3],'k--', 'linewidth', 2);
+    hold off;
+
+    figure (2, 'position', [300, 10, 600, 400]); clf;
+    semilogy(sim_in.EbNovec, ber_awgn_theory,'r+-;QPSK AWGN theory;','markersize', 10, 'linewidth', 2)
+    hold on;
+    semilogy(sim_in.EbNovec, sim_qpsk.bervec,'g+-;QPSK AWGN simulated;','markersize', 10, 'linewidth', 2)
+    semilogy(sim_in.EbNovec, sim_dqpsk.bervec,'b+-;DQPSK AWGN simulated;','markersize', 10, 'linewidth', 2)
+    xlabel('Eb/No (dB)')
+    ylabel('BER')
+    grid("minor")
+    axis([min(sim_in.EbNovec) max(sim_in.EbNovec) 1E-3 1])
+
+    figure (3, 'position', [400, 10, 600, 400]); clf;
+    semilogy(sim_in.EbNovec, ber_awgn_theory,'r+-;QPSK AWGN theory;','markersize', 10, 'linewidth', 2)
+    hold on;
+    semilogy(sim_in.EbNovec, sim_qpsk.bervec,'g+-;QPSK AWGN simulated;','markersize', 10, 'linewidth', 2)
+    semilogy(sim_in.EbNovec, sim_dqpsk.bervec,'b+-;DQPSK AWGN simulated;','markersize', 10, 'linewidth', 2)
+    semilogy(hf_sim_in.EbNovec, ber_hf_theory,'r+-;QPSK HF theory;','markersize', 10, 'linewidth', 2)
+    semilogy(hf_sim_in.EbNovec, sim_dqpsk_hf.bervec,'b+-;DQPSK HF simulated;','markersize', 10, 'linewidth', 2)
+    semilogy(hf_sim_in.EbNovec, sim_qpsk_hf.bervec,'g+-;QPSK HF simulated;','markersize', 10, 'linewidth', 2)
+    semilogy(hf_sim_in.EbNovec, sim_qpsk_hf_div.bervec,'c+-;QPSK Diversity HF simulated;','markersize', 10, 'linewidth', 2)
+    hold off;
+    xlabel('Eb/No (dB)')
+    ylabel('BER')
+    grid("minor")
+    axis([min(hf_sim_in.EbNovec) max(hf_sim_in.EbNovec) 1E-3 1])
+
+endfunction
+
+% -------------------------------------------------------------
+
+more off;
+rand('seed',1); randn('seed', 1);
+%run_curves
+run_single
diff --git a/codec2/branches/0.7/octave/hf_sim.m b/codec2/branches/0.7/octave/hf_sim.m
new file mode 100644 (file)
index 0000000..c9105c0
--- /dev/null
@@ -0,0 +1,78 @@
+% hf_sim.m
+% David Rowe March 2014
+%
+% Two path CCIR poor HF channel simulation, with apaologies to PathSim
+
+% Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+global spread;
+global spread_2ms;
+global hf_gain;
+
+% convert "spreading" samples from 1kHz carrier at Fs to complex
+% baseband, generated by passing a 1kHz sine wave through PathSim with
+% the ccir-poor model, enabling one path at a time.  Because I'm too
+% lazy to generate my own spreading signals
+    
+Fc = 1000; Fs=8000;
+fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+spread1k = fread(fspread, "int16")/10000;
+fclose(fspread);
+fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+spread1k_2ms = fread(fspread, "int16")/10000;
+fclose(fspread);
+
+% down convert to complex baseband
+
+spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+% remove -2000 Hz image
+
+b = fir1(50, 5/Fs);
+spread = filter(b,1,spreadbb);
+spread_2ms = filter(b,1,spreadbb_2ms);
+
+% discard first 1000 samples as these were near 0, probably as
+% PathSim states were ramping up
+
+spread     = spread(1000:length(spread));
+spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+% This function simulates the HF channel at 8kHz for real signals.  A
+% good use case is passing a vector of speech samples through it to
+% simulate SSB over HF.  There's a really good reason for the 300 -
+% 3000 Hz filter that escapes me right now :-)
+
+function [sim_out snr3kHz_measured ] = hf_sim_real(sim_in, snr3kHz)
+
+    % 300 - 3000 Hz filter
+
+    b = fir1(100,[300/4000, 3000/4000], 'pass');
+    
+    % det power of unit variance noise passed through this filter
+    
+    filter_var = var(filter(b,1,randn(1000,1)));
+    
+    % Start simulation
+
+    s = hilbert(filter(b,1,sim_in));
+    n1 = length(s); n2 = length(spread);
+    n = min(n1,n2);
+    path1 = s(1:n) .* spread(1:n);
+    path2 = s(1:n) .* spread_2ms(1:n);
+    delay = floor(0.002*Fs);
+
+    combined = path1(delay+1:n) + path2(1:n-delay);
+
+    snr = 10 .^ (snr3kHz/10);
+    variance = (combined'*combined)/(snr*n);
+    noise = sqrt(variance*0.5/filter_var)*(randn(n-delay,1) + j*randn(n-delay,1));
+    filtered_noise = filter(b,1,noise);
+    sim_out = real(combined+filtered_noise);
+    snr3kHz_measured = 10*log10(var(real(combined))/var(real(filtered_noise)));
+endfunction
+
diff --git a/codec2/branches/0.7/octave/hfper.m b/codec2/branches/0.7/octave/hfper.m
new file mode 100644 (file)
index 0000000..b339634
--- /dev/null
@@ -0,0 +1,57 @@
+% hfper.m
+% David Rowe 2 June 2014
+% Quick and dirty HF PER calculator/simulator
+
+function hfper(ber, nbits, ntrials)
+
+  % Raw PER with no FEC --------------------------------------
+
+  nper = 0;
+  for i=1:ntrials
+      nerr = sum(rand(1,nbits) < ber);
+      if nerr >0
+          nper++;
+      end
+  end
+  printf("Raw PER..................: %0.3f\n", nper/ntrials);
+
+  % Half rate block code, e.g. Golay (23,12) with 3 bit error
+  % correcting capability
+
+  % Golay (23,12) that can correct 3 errors (fails at 4) ------
+
+  ncodeword = 23;
+  ncorrect = 3;
+  nper = 0;
+  for i=1:ntrials
+      nerr = sum(rand(1,ncodeword) < ber);
+      if nerr > ncorrect
+          nper++;
+      end
+  end
+  printf("One Golay codeword.......: %0.3f\n", nper/ntrials);
+
+  % Several Golay codewords concatenated ----------------------
+
+  m = floor(nbits/12);        % number of codewords
+
+  nper = 0;
+  for i=1:ntrials
+
+    % test each codeword in packet, if any of the codewords has > 4
+    % errors, entire packet is a dud
+
+    no_errors = 1;
+    for k=1:m
+      nerr = sum(rand(1,ncodeword) < ber);
+      if (nerr > ncorrect) && no_errors
+          nper++;
+          no_errors = 0;
+      end
+    end
+
+  end
+  printf("Packet protected by Golay: %0.3f\n", nper/ntrials);
+  
+endfunction
diff --git a/codec2/branches/0.7/octave/horus_high_speed.bin b/codec2/branches/0.7/octave/horus_high_speed.bin
new file mode 100644 (file)
index 0000000..8d5b1f3
Binary files /dev/null and b/codec2/branches/0.7/octave/horus_high_speed.bin differ
diff --git a/codec2/branches/0.7/octave/horus_msg.txt b/codec2/branches/0.7/octave/horus_msg.txt
new file mode 100644 (file)
index 0000000..882a9b3
--- /dev/null
@@ -0,0 +1 @@
+ 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00
diff --git a/codec2/branches/0.7/octave/horus_payload_rtty.txt b/codec2/branches/0.7/octave/horus_payload_rtty.txt
new file mode 100644 (file)
index 0000000..882a9b3
--- /dev/null
@@ -0,0 +1 @@
+ 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 1.00000000e+00 0.00000000e+00 0.00000000e+00 0.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 1.00000000e+00 0.00000000e+00
diff --git a/codec2/branches/0.7/octave/horus_tx_bits_binary.txt b/codec2/branches/0.7/octave/horus_tx_bits_binary.txt
new file mode 100644 (file)
index 0000000..61e52d9
--- /dev/null
@@ -0,0 +1 @@
+0 0 1 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 1 0 1 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0 0 1 0 1 0 0 1 0 0 0 0 1 1 0 1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0 1 0 0 0 0 1 0 1 0 0 1 0 1 0 1 1 0 0 1 1 0 1 1 0 0 1 1 0 0 1 0 1 0 0 1 0 0 1 1 1 1 1 1 0 0 1 0 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 1 1 0 1 0 1 1 0 1 1 1 1 0 0 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 0 0 0 1 0 0 1 1 1 1 1 0 0 0 1 0 0 1 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 1 0 0 0 
\ No newline at end of file
diff --git a/codec2/branches/0.7/octave/hp_filt.m b/codec2/branches/0.7/octave/hp_filt.m
new file mode 100644 (file)
index 0000000..1087bb9
--- /dev/null
@@ -0,0 +1,12 @@
+% hp_filt.m
+% David Rowe 20 Feb 2012
+
+function hp_filt(in_file, out_file)
+  fin = fopen(in_file,"rb");
+  s = fread(fin,Inf,"short");
+  b = fir1(256, 300/4000, "high");
+  freqz(b);
+  s_hpf = filter(b,1,s);
+  fout = fopen(out_file,"wb");
+  fwrite(fout, s_hpf, "short");
+endfunction
diff --git a/codec2/branches/0.7/octave/impulse_noise.m b/codec2/branches/0.7/octave/impulse_noise.m
new file mode 100644 (file)
index 0000000..dee5c5d
--- /dev/null
@@ -0,0 +1,122 @@
+% impulse_noise
+% David Rowe May 2017
+%
+% Experiments with impulsive noise and HF radio
+
+format;
+more off;
+rand('seed',1)
+
+% DFT function ------------------------------------------------
+% note k is on 0..K-1 format, unlike Octave fft() which is 1..K
+
+function H = calc_H(k, K, a, d)
+  L = length(d);
+  H = 0;
+  for i=1:L
+    H += a(i)*exp(-j*2*pi*k*d(i)/K);
+  end
+endfunction
+
+% -----------------------------------------
+% PWM noise simulation
+% -----------------------------------------
+
+function pwm_noise
+
+  Fs   = 10E6;   % sample rate of simulation
+  Fsig = 1E6;    % frequency of our wanted signal
+  Fpwm = 255E3;  % switcher PWM frequency
+  T    = 1;      % length of simulations in seconds
+  Nsam = T*Fs;  
+  Nsamplot = 200;
+  Apwm = 0.1;
+  Asig = -40;    % attenuation of wanted signal in dB
+
+  % generate an impulse train with jitter to simulate switcher noise
+
+  pwm = zeros(1,Fs);
+  Tpwm = floor(Fs/Fpwm);
+  pulse_positions_pwm = Tpwm*(1:T*Fpwm) + round(rand(1,T*Fpwm));
+
+  h_pwm = zeros(1,Nsam);
+  h_pwm(pulse_positions_pwm) = Apwm;
+  h_pwm = h_pwm(1:Nsam);
+  % add in wanted signal and computer amplitude spectrum
+
+  s = 10^(Asig/20)*cos(2*pi*Fsig*(1:Nsam)/Fs);
+
+  h = h_pwm+s;
+  H = fft(h);
+  Hdb = 20*log10(abs(H)) - 20*log10(Nsam/2);
+
+  figure(1); clf;
+  subplot(211)
+  plot(h(1:Nsamplot));
+  subplot(212)
+  plot(Hdb(1:Nsam/2));
+  axis([0 T*2E6 -120 0]); xlabel('Frequency Hz'); ylabel('Amplityude dBV'); grid;
+
+  printf("pwm rms: %f signal rms: %f noise rms\n", std(h_pwm), std(s));
+endfunction
+
+% -----------------------------------------
+% Single pulse noise simulation
+% -----------------------------------------
+
+function pulse_noise
+
+  % set up short pulse in wide window, consisting of two samples next
+  % to each other
+
+  K = 1024;
+  a(1) = a(2) = 1; d(1) = 10; d(2) = d(1)+1;
+  h = zeros(1,K);
+  h(d(1)) = a(1);
+  h(d(2)) = a(2);
+
+  % mag and phase spectrum, mag spectrum changes slowly
+
+  figure(2); clf;
+  Hfft = fft(h);
+  subplot(311)
+  stem(h(1:100));
+  axis([1 100 -0.2 1.2]);
+  subplot(312)  
+  plot(abs(Hfft(1:K/2)),'+');
+  title('Magnitude');
+  subplot(313)
+  plot(angle(Hfft(1:K/2)),'+');
+  title('Phase');
+
+  % simple test to estimate H(k+1) from H(k) --------------------
+
+  % brute force calculation
+
+  k = 300;
+  H = zeros(1,K);
+  H(k-1) = calc_H(k-1, K, a, d);
+  H(k)   = calc_H(k, K, a, d);
+  H(k+1) = calc_H(k+1, K, a, d);
+
+  % calculation of k+1 from k using approximation that {d(i)} are
+  % close together compared to M, i.e it's a narrow pulse (assumes we
+  % can estimate d using other means)
+
+  Hk1_ = exp(-j*2*pi*d(1)/K)*H(k);
+
+  % plot zoomed in version around k to compare
+
+  figure(3); clf;
+  plot(H(k-1:k+1),'b+','markersize', 10, 'linewidth', 2);
+  hold on; plot(Hk1_,'g+','markersize', 10, 'linewidth', 2); hold off;
+  title('H(k-1) .... H(k+1)');
+  printf("H(k+1) match: %f dB\n", 20*log10(abs(H(k+1) - Hk1_)));
+endfunction
+
+% Run various simulations here ---------------------------------------------
+
+%pwm_noise
+pulse_noise
+
diff --git a/codec2/branches/0.7/octave/kmeans2.m b/codec2/branches/0.7/octave/kmeans2.m
new file mode 100644 (file)
index 0000000..501ef0a
--- /dev/null
@@ -0,0 +1,198 @@
+## Copyright (C) 2011 Soren Hauberg
+## Copyright (C) 2012 Daniel Ward
+##
+## This program is free software; you can redistribute it and/or modify it under
+## the terms of the GNU General Public License as published by the Free Software
+## Foundation; either version 3 of the License, or (at your option) any later
+## version.
+##
+## This program is distributed in the hope that it will be useful, but WITHOUT
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+## details.
+##
+## You should have received a copy of the GNU General Public License along with
+## this program; if not, see .
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{idx}, @var{centers}] =} kmeans2 (@var{data}, @var{k}, @var{param1}, @var{value1}, @dots{})
+## K-means clustering.
+##
+## @seealso{linkage}
+## @end deftypefn
+
+function [classes, centers, sumd, D] = kmeans2 (data, k, varargin)
+
+  [reg, prop] = parseparams (varargin);
+
+  ## defaults for options
+
+  emptyaction = "error";
+  start       = "sample";
+
+  # used for getting the number of samples
+
+  nRows = rows (data);
+
+  ## used to hold the distances from each sample to each class
+
+  D = zeros (nRows, k);
+
+  # used for convergence of the centroids
+
+  err = 1;
+
+  # initial sum of distances
+
+  sumd = Inf;
+
+  # default search function, can  be over-ridden by user supplied function
+
+  search_func = @vq_search_mse;
+
+  ## Input checking, validate the matrix and k
+
+  if (!isnumeric (data) || !ismatrix (data) || !isreal (data))
+    error ("kmeans: first input argument must be a DxN real data matrix");
+  elseif (!isscalar (k))
+    error ("kmeans: second input argument must be a scalar");
+  endif
+
+  if (length (varargin) > 0)
+
+    ## check for the ‘emptyaction’ property
+
+    found = find (strcmpi (prop, "emptyaction") == 1);
+    if found 
+      switch (lower (prop{found+1}))
+        case "singleton"
+          emptyaction = "singleton";
+        otherwise
+          error ("kmeans: unsupported empty cluster action parameter");
+      endswitch
+    end
+
+    ## check for the ‘search_func’ property, user defined vq_search function
+
+    found = find (strcmpi (prop, "search_func") == 1);
+    if found
+      search_func = prop{found+1};
+    end
+
+    ## check for the ‘start’ property
+
+    found = find (strcmpi (prop, "start") == 1);
+    if found
+      switch (lower (prop{found+1}))
+        case "sample"
+          idx = randperm (nRows) (1:k);
+          centers = data (idx, :);
+        case "first"
+          centers = data (1:k, :);
+        otherwise
+          error ("kmeans: unsupported initial clustering parameter");
+      endswitch
+    end
+  end
+
+  ## Run the algorithm
+
+  while err > .001
+    classes = feval(search_func, centers, data);
+
+    ## Calculate new centroids
+
+    for i = 1:k
+
+      ## Get binary vector indicating membership in cluster i
+
+      membership = (classes == i);
+
+      ## Check for empty clusters
+
+      if (sum (membership) == 0)
+        switch emptyaction
+
+          ## if ‘singleton’, then find the point that is the
+          ## farthest and add it to the empty cluster
+
+          case 'singleton'
+           idx=maxCostSampleIndex (data, centers(i,:));
+           classes(idx) = i;
+           membership(idx)=1;
+         ## if ‘error’ then throw the error
+          otherwise
+            error ("kmeans: empty cluster created");
+        endswitch
+      endif ## end check for empty clusters
+
+      ## update the centroids
+
+      members = data(membership, :);
+      centers(i, :) = sum(members,1)/size(members,1);
+    endfor
+
+    ## calculate the difference in the sum of distances
+
+    err  = sumd - objCost (data, classes, centers);
+
+    ## update the current sum of distances
+
+    sumd = objCost (data, classes, centers);
+
+  endwhile
+endfunction
+
+
+function idx = vq_search_mse(vq, data)
+    [nVec nCols] = size(vq);
+    nRows = length(data);
+
+    error = zeros(1,nVec);
+    idx = zeros(1, nRows);
+
+    for f=1:nRows
+      target = data(f,:);
+      for i=1:nVec
+        diff = target - vq(i,:);
+        error(i) = diff * diff';
+      end
+      [mn min_ind] = min(error);
+      idx(f) = min_ind;
+     end
+endfunction
+
+
+## calculate the sum of distances
+
+function obj = objCost (data, classes, centers)
+  obj = 0;
+    for i=1:rows (data)
+      obj = obj + sumsq (data(i,:) - centers(classes(i),:));
+    endfor
+endfunction
+
+function idx = maxCostSampleIndex (data, centers)
+  cost = 0;
+  for idx = 1:rows (data)
+    if cost < sumsq (data(idx,:) - centers)
+      cost = sumsq (data(idx,:) - centers);
+    endif
+  endfor
+endfunction
+
+%!demo
+%! ## Generate a two-cluster problem
+%! C1 = randn (100, 2) + 1;
+%! C2 = randn (100, 2) – 1;
+%! data = [C1; C2];
+%!
+%! ## Perform clustering
+%! [idx, centers] = kmeans (data, 2);
+%!
+%! ## Plot the result
+%! figure
+%! plot (data (idx==1, 1), data (idx==1, 2), ‘ro’);
+%! hold on
+%! plot (data (idx==2, 1), data (idx==2, 2), ‘bs’);
+%! plot (centers (:, 1), centers (:, 2), ‘kv’, ‘markersize’, 10);
+%! hold off
diff --git a/codec2/branches/0.7/octave/kmeans_tests.m b/codec2/branches/0.7/octave/kmeans_tests.m
new file mode 100644 (file)
index 0000000..9b4d883
--- /dev/null
@@ -0,0 +1,765 @@
+% kmeans_tests.m
+%
+% David Rowe June 2017
+%
+%
+% Trying a few variations on the kmeans algorithm for quantisation of
+% spectral envelope
+
+1;
+
+%----------------------------------------------------------------------
+%
+% User defined search functions
+%
+%----------------------------------------------------------------------
+
+%----------------------------------------------------------------------
+% standard mean squared error search
+
+function [idx contrib errors test_ g mg sl] = vq_search_mse(vq, data)
+  [nVec nCols] = size(vq);
+  nRows = rows(data);
+  
+  error = zeros(1,nVec);
+  errors = zeros(1, nRows);
+  idx = zeros(1, nRows);
+  contrib = zeros(nRows, nCols);
+  test_ = zeros(nVec, nCols);
+
+  for f=1:nRows
+    target = data(f,:);
+    for i=1:nVec
+      diff = target - vq(i,:);
+      error(i) = diff * diff';
+    end
+    [mn min_ind] = min(error);
+    errors(f) = mn; idx(f) = min_ind; contrib(f,:) = vq(min_ind,:);
+    test_(f,:) = vq(min_ind,:);
+  end
+
+  g = 0; mg = 1; sl = 0; % dummys for this function
+endfunction
+
+
+%----------------------------------------------------------------------
+% abs() search with a linear gain term
+
+function [idx contrib errors test_ g mg sl] = vq_search_gain(vq, data)
+  
+  [nVec nCols] = size(vq);
+  nRows = rows(data);
+
+  error = zeros(1,nVec);
+  g = zeros(nRows, nVec);
+  diff  = zeros(nVec, nCols);
+  errors = zeros(1, nRows);
+  idx = zeros(1, nRows);
+  contrib = zeros(nRows, nCols);
+  test_ = zeros(nVec, nCols);
+
+  for f=1:nRows
+    target = data(f,:);
+    for i=1:nVec
+      % work out gain for best match
+
+      g(f, i) = (sum(target) - sum(vq(i,:)))/nCols;
+      diff(i,:) = target - vq(i,:) - g(f, i);
+
+      % abs in dB is MSE in linear
+
+      error(i) = mean(abs(diff(i,:)));
+
+      %printf("f: %d i: %d g: %f error: %f\n", f, i, g(f, i), error(i));
+    end
+    [mn min_ind] = min(error);
+
+    idx(f) = min_ind;
+
+    errors(f) = mn; 
+    contrib(f,:) = test_(f,:) = vq(min_ind,:) + g(f,min_ind);
+  end
+  mg = 1; sl = 0;
+endfunction
+
+
+%----------------------------------------------------------------------
+% abs() search with a linear plus ampl scaling term
+
+function [idx contrib errors test_ g mg sl] = vq_search_mag(vq, data)
+  [nVec nCols] = size(vq);
+  nRows = rows(data);
+  
+  g = mg = zeros(nRows, nVec);
+  diff  = zeros(nVec, nCols);
+  errors = zeros(1, nRows);
+  idx = error = zeros(1, nVec);
+  contrib = zeros(nRows, nCols);
+  test_ = zeros(nVec, nCols);
+
+  weights = ones(1,nCols);
+  %weights(1) = 0;
+
+  for f=1:nRows
+    target = data(f,:);
+    %target = 2*vq(1,:)+1;
+
+    for i=1:nVec
+      % work out gain and amp scaling for best match
+
+      A = [sum(vq(i,:)) nCols; vq(i,:)*vq(i,:)' sum(vq(i,:))];
+      c = [sum(target) target*vq(i,:)']';
+      b = inv(A)*c;
+
+      g(f,i) = b(2);  mg(f,i) = b(1);
+      diff(i,:) = target - (mg(f,i)*vq(i,:) + g(f,i));
+      diff(i,:) .* weights;
+
+      % abs in dB is MSE in linear
+
+      error(i) = mean(abs(diff(i,:)));
+
+      %printf("f: %d i: %d mg: %f g: %f error: %f\n", f, i, mg(f,i), g(f,i), error(i));
+    end
+    
+    [mn min_ind] = min(error);
+    errors(f) = mn; 
+    idx(f) = min_ind;
+
+    contrib(f,:) = test_(f,:) = mg(f,min_ind) * vq(min_ind,:) + g(f,min_ind);
+  end
+  sl = 0;
+endfunction
+
+
+%----------------------------------------------------------------------
+% abs() search with a linear, ampl scaling, and slope term
+
+function [idx contrib errors test_ g mg sl] = vq_search_slope(vq, data)
+  [nVec nCols] = size(vq);
+  nRows = rows(data);
+  
+  g = mg = sl = zeros(nRows, nVec);
+  diff  = zeros(nVec, nCols);
+  errors = zeros(1, nRows);
+  idx = error = zeros(1, nVec);
+  contrib = zeros(nRows, nCols);
+  test_ = zeros(nVec, nCols);
+
+  weights = ones(1,nCols);
+
+  for f=1:nRows
+    target = data(f,:);
+    %target = 2*vq(1,:)+1;
+
+    for i=1:nVec
+      % work out gain, amp and slope for best match, 3 unknowns, 3 equations
+
+      A = [sum(vq(i,:))      nCols        sum(1:nCols); ...
+          vq(i,:)*vq(i,:)'   sum(vq(i,:)) (1:nCols)*vq(i,:)'; ...
+          (1:nCols)*vq(i,:)' sum(1:nCols) (1:nCols)*(1:nCols)'];
+      c = [sum(target) target*vq(i,:)' target*(1:nCols)']';
+      b = inv(A)*c;
+
+      mg(f,i) = b(1); g(f,i) = b(2); sl(f,i) = b(3);
+      diff(i,:) = target - (mg(f,i)*vq(i,:) + g(f,i) + sl(f,i)*(1:nCols));
+      diff(i,:) .* weights;
+
+      % abs in dB is MSE in linear
+
+      error(i) = mean(abs(diff(i,:)));
+
+      %printf("f: %d i: %d mg: %f g: %f sl: %f error: %f\n", f, i, mg(f,i), g(f,i), sl(f,i), error(i));
+    end
+    
+    [mn min_ind] = min(error);
+    errors(f) = mn; 
+    idx(f) = min_ind;
+
+    contrib(f,:) = test_(f,:) = mg(f,min_ind)*vq(min_ind,:) + g(f,min_ind) + sl(f,min_ind)*(1:nCols);
+  end
+
+endfunction
+
+
+%----------------------------------------------------------------------
+%
+% Functions to support simulation of different VQ training and testing
+%
+%----------------------------------------------------------------------
+
+% evaluate database test using vq, with selectable search function.  Can be operated in
+% GUI mode to analyse in fine detail or batch mode to evaluate lots of data.
+
+function sd_per_frame = run_test(vq, test, nVec, search_func, gui_en = 0)
+
+  % Test VQ using test data -----------------------
+
+  % Each test must output:
+  %   errors: - error for best vector
+  %   idx...: - index of best vector
+  %   test_.: - best approximation of target test database
+  
+  [nRows nCols] = size(test);
+
+  [idx contrib errors test_ g mg sl] = feval(search_func, vq, test);
+
+  % sd over time
+  sd_per_frame = zeros(nRows,1);
+  for i=1:nRows
+    sd_per_frame(i) = mean(abs(test(i,:) - test_(i,:)));
+  end
+
+  printf("average sd: %3.2f\n", mean(sd_per_frame));
+  %printf("%18s nVec: %d SD: %3.2f dB\n", search_func, nVec, mean(sd_per_frame));
+  
+  % Optional GUI with U to anlayse VQ perf ---------------------------------------------------
+
+  if gui_en
+    gui_mode = "sort";     % "sort" or "fbf"
+    sort_order = "worst";  % "worst" or "best"
+    f = 1;
+
+    % plots sd over time and histogram
+
+    figure(1); clf; subplot(211); plot(sd_per_frame); title('SD'); 
+    subplot(212); [yy xx] = hist(sd_per_frame); plot(xx,yy,'+-');
+  end
+
+  while gui_en
+
+    % display m frames, printing some stats, plotting vector to give visual idea of match
+
+    figure(2); clf;
+
+    % try this in 'ascend' or 'descend' mode to best or worst frames
+
+    if strcmp(gui_mode, "sort")
+      if strcmp(sort_order, "best")
+        [errors_dec frame_dec] = sort(errors, "ascend");
+      end
+      if strcmp(sort_order, "worst")
+        [errors_dec frame_dec] = sort(errors, "descend");
+      end
+       m = 4;
+    else
+      m = 1;
+      errors_dec = errors(f); frame_dec(1) = f;
+    end
+
+    for i=1:m
+
+      % build up VQ legend
+
+      af = frame_dec(i); aind = idx(af);
+
+      ag = 0; amg = 1; asl = 0;
+      if strcmp(search_func, "vq_search_gain")
+        ag = g(af,aind);
+        l3 = sprintf("g: %3.2f", ag);
+      end
+      if strcmp(search_func, "vq_search_mag")
+        ag = g(af,aind);
+        amg = mg(af,aind);
+        l3  = sprintf("g: %3.2f mg: %3.2f", ag, amg);
+      end
+      if strcmp(search_func, "vq_search_slope")
+        ag = g(af,aind);
+        amg = mg(af,aind);
+        asl = sl(af,aind);
+        l3 = sprintf("g: %3.2f mg: %3.2f sl: %3.2f", ag, amg, asl);
+      end
+
+      % plot target 
+
+      subplot(sqrt(m), sqrt(m),i);
+      l1 = sprintf("b-;fr %d sd: %3.2f;", af, errors_dec(m));
+      plot(test(af,:), l1); 
+
+      % plot vq vector and modified version
+
+      hold on; 
+      l2 = sprintf("g-+;ind %d;", aind); 
+      plot(vq(aind, :), l2); 
+      l3 = sprintf("g-o;%s;",l3);
+      plot(amg*vq(aind, :) + ag + asl*(1:nCols), l3); 
+      hold off;
+      axis([1 nCols -10 40]);
+    end
+
+    % interactive menu ------------------------------------------
+
+    if strcmp(gui_mode, "sort")
+      printf("\rmenu: m-mode[%s] o-order[%s] q-quit", gui_mode, sort_order);
+    end
+    if strcmp(gui_mode, "fbf")
+      printf("\rmenu: m-mode[%s] frame: %d  n-next  b-back  q-quit", gui_mode, f);
+    end
+    fflush(stdout);
+    k = kbhit();
+    
+    if k == 'm'
+      if strcmp(gui_mode, "sort")
+        gui_mode = "fbf"; f = frame_dec(1); 
+      else
+        gui_mode = "sort";
+      end;
+    end
+    if k == 'o'
+       if strcmp(sort_order, "worst")
+         sort_order = "best"; 
+       else
+         sort_order = "worst";
+      end;
+    end
+    if k == 'n', f = f + 1; endif;
+    if k == 'b', f = f - 1; endif;
+    if k == 'q', gui_en = 0; printf("\n"); endif;
+  end  
+  
+endfunction
+
+
+function search_func = get_search_func(short_name)
+  if strcmp(short_name, "mse")
+    search_func = 'vq_search_mse';
+  end
+  if strcmp(short_name, "gain")
+    search_func = 'vq_search_gain';
+  end
+  if strcmp(short_name, "mag")
+    search_func = 'vq_search_mag';
+  end
+  if strcmp(short_name, "slope")
+    search_func = 'vq_search_slope';
+  end
+end
+
+
+%----------------------------------------------------------------------
+% Train up a  VQ and run one or mode tests
+
+function [sd des] = train_vq_and_run_tests(sim_in)
+  Nvec = sim_in.Nvec;
+
+  train_func = get_search_func(sim_in.train_func_short);
+  printf("    Nvec %d kmeans start\n", Nvec);
+  [idx vq] = feval(sim_in.kmeans,
+                   sim_in.trainvec, Nvec, 
+                   "start", "sample", 
+                   "emptyaction", "singleton",
+                   "search_func", train_func);
+  printf("    Nvec %d kmeans end\n", Nvec);
+
+  sd = []; des = []; tests = sim_in.tests;
+  for t=1:length(cellstr(tests))
+    test_func_short = char(cellstr(tests)(t));
+    test_func = get_search_func(test_func_short);
+    asd = run_test(vq, sim_in.testvec, Nvec, test_func); 
+    sd = [sd asd];
+    ades.Nvec = Nvec; 
+    ades.train_func_short = sim_in.train_func_short;
+    ades.test_func_short  = test_func_short;
+    ades_str = sprintf("Nvec: %3d train: %-5s test: %-5s", 
+                       ades.Nvec, ades.train_func_short, ades.test_func_short); 
+    des = [des ades];
+    printf("    %s SD: %3.2f\n", ades_str, mean(asd));
+  end
+
+endfunction
+
+% Search for test that matchs train/test and any Nvec and constructs points for error bar plot
+
+function [y x leg] = search_tests(sd, desc, train, test)
+  nTests = length(desc)
+  x = []; y = []; leg = [];
+  for i=1:nTests
+    if strcmp(desc(i).train_func_short, train) && strcmp(desc(i).test_func_short, test)
+      printf("i: %2d Nvec: %3d train: %5s test: %5s\n", i, desc(i).Nvec, desc(i).train_func_short, desc(i).test_func_short);
+      x = [x; log2(desc(i).Nvec)];
+      y = [y; mean(sd(:,i)) std(sd(:,i))];
+    end
+  end
+endfunction
+
+
+function plot_sd_results(fg, title_str, sd, desc, train_list, test_list)
+  figure(fg); clf;  
+
+  nlines = 0; inc = -0.1;
+  for i=1:length(cellstr(train_list))
+    train_func_short = char(cellstr(train_list)(i));
+    for j=1:length(cellstr(test_list))
+      test_func_short = char(cellstr(test_list)(j));
+      [y x] = search_tests(sd, desc, train_func_short, test_func_short);
+      leg = sprintf("o-%d;train: %5s test: %5s;", nlines, train_func_short, test_func_short);
+      if nlines, hold on; end;
+      x += inc; inc += 0.1;            % separate x coords a bit to make errors bars legible
+      errorbar(x, y(:,1), y(:,2), leg);
+      nlines++;
+    end
+    if nlines>1, hold off; end;
+  end
+
+  xlabel('VQ size (bits)')
+  ylabel('mean SD (dB)');
+  title(title_str);
+endfunction
+
+
+% Search for test that matches all fields for histogram plots
+
+function testNum = search_tests_Nvec(sd, desc, train, test, Nvec)
+  nTests = length(desc);
+  testNum = 0;
+  for i=1:nTests
+    if strcmp(desc(i).train_func_short, train) && strcmp(desc(i).test_func_short, test) && desc(i).Nvec == Nvec
+      printf("i: %2d Nvec: %3d train: %5s test: %5s\n", i, desc(i).Nvec, desc(i).train_func_short, desc(i).test_func_short);
+      testNum = i;
+    end
+  end
+endfunction
+
+%----------------------------------------------------------------------
+%
+% Plot histograms of SDs for comparison. Each col of sd_per_frame
+% has the results of one test, number of cols % is number of tests.  leg
+% is a col vector with one legend string for each test.
+
+function compare_hist(fg, atitle, sd, desc)
+  figure(fg); clf;
+  [nRows nCols] = size(sd);
+  for c=1:nCols
+    [yy, xx] = hist(sd(:, c));
+    if c == 2, hold on; end;
+    leg = sprintf("o-%d;train: %5s test: %5s;", c-1, desc(c).train_func_short, desc(c).test_func_short);
+    plot(xx, yy, leg);
+  end
+  if nCols > 1, hold off; end;
+  title(atitle)
+end
+
+%----------------------------------------------------------------------
+% Run a bunch of long tests in parallel and plot results
+%
+
+% This test tries a bunch of training and test search combinations on
+% the first 1kHz to see if there is any advantage in using the higher
+% order search techniques in the VQ training.  So far it appears
+% not....  However the higher order search routines do give great
+% results compared to a basic MSE (or oder) search.
+
+function [sd desc] = long_tests_1_10(quick_check=0)
+  num_cores = 4;
+  K = 10;
+  load surf_train_120_hpf150; load surf_all_hpf150;
+
+  if quick_check
+    NtrainVec = 1000;
+    NtestVec = 100;
+  else
+    NtrainVec = length(surf_train_120_hpf150);
+    NtestVec = length(surf_all_hpf150);
+  end
+
+  trainvec = surf_train_120_hpf150(1:NtrainVec,1:K);
+  testvec = surf_all_hpf150(1:NtestVec,1:K);
+
+  % build up a big array of tests to run ------------------------
+
+  sim_in.trainvec = trainvec; sim_in.testvec = testvec;
+  sim_in.kmeans = "kmeans2";  % slow but supports different search functions
+  sim_in.Nvec = 64; 
+  sim_in.train_func_short = "mse"; 
+  sim_in.tests = ["mse"; "gain"; "mag"; "slope"];
+
+  % Test1: mse training, 64, 128, 256
+
+  sim_in_vec(1:3) = sim_in;
+  sim_in_vec(2).Nvec = 128; sim_in_vec(3).Nvec = 256;
+
+  test_list = sim_in_vec;
+
+  % Test2: gain training, 64, 128, 256
+
+  for i=1:3, sim_in_vec(i).train_func_short = "gain"; end;
+  test_list = [test_list sim_in_vec];
+
+  % Test3: mag training, 64, 128, 256
+
+  for i=1:3, sim_in_vec(i).train_func_short = "mag"; end;
+  test_list = [test_list sim_in_vec];
+
+  % Test4: slope training, 64, 128, 256
+
+  for i=1:3, sim_in_vec(i).train_func_short = "slope"; end;
+  test_list = [test_list sim_in_vec];
+
+  % run test list in parallel
+
+  [sd desc] =  pararrayfun(num_cores, @train_vq_and_run_tests, test_list);
+  %train_vq_and_run_tests(test_list(1));
+  
+  % Plot results -----------------------------------------------
+
+  fg = 1;
+  plot_sd_results(fg++, "MSE Training", sd, desc, "mse", ["mse"; "gain"; "mag"; "slope"]);
+  plot_sd_results(fg++, "Gain Training", sd, desc, "gain", ["mse"; "gain"; "mag"; "slope"]);
+  plot_sd_results(fg++, "Mag Training", sd, desc, "mag", ["mse"; "gain"; "mag"; "slope"]);
+  plot_sd_results(fg++, "Slope Training", sd, desc, "slope", ["mse"; "gain"; "mag"; "slope"]);
+  plot_sd_results(fg++, "Slope Searching", sd, desc, ["mse"; "gain"; "mag"; "slope"], "slope");
+
+  % histogram of results from Nvec=64, all training methods, slope search
+
+  testnum = search_tests_Nvec(sd, desc, "mse", "slope", 64);
+  hist_sd = sd(:,testnum); hist_desc = desc(testnum);
+  testnum = search_tests_Nvec(sd, desc, "gain", "slope", 64);
+  hist_sd = [hist_sd sd(:,testnum)]; hist_desc = [hist_desc desc(testnum)];
+  testnum = search_tests_Nvec(sd, desc, "mag", "slope", 64);
+  hist_sd = [hist_sd sd(:,testnum)]; hist_desc = [hist_desc desc(testnum)];
+  testnum = search_tests_Nvec(sd, desc, "slope", "slope", 64);
+  hist_sd = [hist_sd sd(:,testnum)]; hist_desc = [hist_desc desc(testnum)];
+  compare_hist(fg, "Histogram of SDs Nvec=64", hist_sd, hist_desc);
+
+endfunction
+
+
+%----------------------------------------------------------------------
+% This test tries some test combinations on the 1000 to 3000 Hz range.
+%
+% Based on our results with long_test_1_10() we just use MSE training
+
+function [sd desc] = long_tests_11_40(quick_check=0)
+  num_cores = 4;
+  K = 20; st = 11; en = 40;
+  load surf_train_120_hpf150; load surf_all_hpf150;
+
+  if quick_check
+    NtrainVec = 1000;
+    NtestVec = 100;
+  else
+    NtrainVec = length(surf_train_120_hpf150);
+    NtestVec = length(surf_all_hpf150);
+  end
+
+  trainvec = surf_train_120_hpf150(1:NtrainVec,st:en);
+  testvec = surf_all_hpf150(1:NtestVec,st:en);
+
+  % build up an array of tests to run ------------------------
+
+  sim_in.kmeans = "kmeans";
+  sim_in.trainvec = trainvec; sim_in.testvec = testvec; 
+  sim_in.Nvec = 64; 
+  sim_in.train_func_short = "mse"; 
+  sim_in.tests = ["slope"];
+
+  % Test1: mse training, 64, 128, 256, 512
+
+  sim_in_vec(1:4) = sim_in;
+  sim_in_vec(2).Nvec = 128; sim_in_vec(3).Nvec = 256; sim_in_vec(4).Nvec = 512;
+
+  test_list = sim_in_vec;
+
+  % run test list in parallel
+
+  [sd desc] =  pararrayfun(num_cores, @train_vq_and_run_tests, test_list);
+  %[sd desc] =  train_vq_and_run_tests(sim_in_vec(4));
+
+  % Plot results -----------------------------------------------
+
+  fg = 2;
+  plot_sd_results(fg++, "MSE Training 10..30", sd, desc, "mse", "slope");
+
+#{
+  % histogram of results from Nvec=64, all training methods, slope search
+
+  testnum = search_tests_Nvec(sd, desc, "mse", "slope", 64);
+  hist_sd = sd(:,testnum); hist_desc = desc(testnum);
+  testnum = search_tests_Nvec(sd, desc, "gain", "slope", 64);
+  hist_sd = [hist_sd sd(:,testnum)]; hist_desc = [hist_desc desc(testnum)];
+  testnum = search_tests_Nvec(sd, desc, "mag", "slope", 64);
+  hist_sd = [hist_sd sd(:,testnum)]; hist_desc = [hist_desc desc(testnum)];
+  testnum = search_tests_Nvec(sd, desc, "slope", "slope", 64);
+  hist_sd = [hist_sd sd(:,testnum)]; hist_desc = [hist_desc desc(testnum)];
+  compare_hist(fg, "Histogram of SDs Nvec=64", hist_sd, hist_desc);
+#}
+endfunction
+
+
+function vq = detailed_test(Nvec=64, st=1, en=10, quick_check=1, test_func = "vq_search_slope")
+  K = en-st+1;
+  load surf_train_120_hpf150;
+  load surf_all_hpf150;
+  if quick_check
+    NtrainVec = 1000;
+    NtestVec = 100;
+  else
+    NtrainVec = length(surf_train_120_hpf150);
+    NtestVec = length(surf_all_hpf150);
+    NtestVec = 100;
+  end
+
+  trainvec = surf_train_120_hpf150(1:NtrainVec,st:en);
+  testvec = surf_all_hpf150(1:NtestVec,st:en);
+
+  [idx vq]  = kmeans(trainvec, Nvec,
+                     "start", "sample", 
+                     "emptyaction", "singleton");
+
+  run_test(vq, testvec, Nvec, test_func, gui_en=1);
+endfunction
+
+
+% ------------------------------------------------------------------
+%
+% Following test_* functions have some contrived examples to test VQ
+% training with each training method.  However the longtest_1_10
+% results suggest these training methds don't provide any improvement
+% over standard MSE kmeans.
+
+function test_training_mse
+  K = 3; NtrainVec = 10; Nvec = 2;  
+
+  trainvec = ones(NtrainVec,K);
+  trainvec(2:2:NtrainVec,:) = -1;
+  
+  [idx vq]  = kmeans2(trainvec, Nvec,
+                      "start", "first", 
+                      "emptyaction", "singleton",
+                      "search_func", "vq_search_mse");
+
+  ok = find(vq == [1 1 1]) && (find(vq == [-1 -1 -1]));
+  printf("ok: %d\n", ok);
+endfunction
+
+
+function test_training_gain
+  K = 3; NtrainVec = 10; Nvec = 2;  
+
+  % Vectors that are the same, but offset from each other via a linear
+  % term. Training algorithm should map these all to the "same"
+  % vector.
+
+  trainvec = ones(NtrainVec,K);
+  for v=2:NtrainVec/2
+   trainvec(v,:) += v*ones(1,1:K);
+  end
+
+  % Second set of "identical" vectors  except for gain offset
+
+  for v=NtrainVec/2+1:NtrainVec
+   trainvec(v,:) = [1 0 -1] + (v-NtrainVec/2-1)*ones(1,1:K);
+  end
+
+  [idx vq]  = kmeans2(trainvec, Nvec, 
+                      "start", "sample", 
+                      "emptyaction", "singleton", 
+                      "search_func", "vq_search_gain");
+
+  % check we get a vq table of two vectors that are linear offset [1 1 1] and [1 0 -1]
+
+  tol = 0.001; ok = 0;
+  for i=1:Nvec
+    diff = vq(i,:) - [1 1 1];
+    if std(diff) < tol, ok++; end;
+    diff = vq(i,:) - [1 0 -1];
+    if std(diff) < tol, ok++; end;
+  end
+  if ok == 2, printf("gain: OK\n"); end;
+endfunction
+
+
+function test_training_mag
+  K = 3; NtrainVec = 10; Nvec = 2;  
+
+  % Given a vector x, create a set of training data y = m*x + c, with x
+  % modified by a magnitude and linear term.  Each vector has a
+  % different mag and linear term.
+
+  trainvec = zeros(NtrainVec,K);
+  for v=1:2:NtrainVec
+    trainvec(v,:) = v*[1 2 3] + 2*v;
+  end
+
+  % another set of "identical" vectors, mapped by different magnitude and linear terms,
+  % alternated with the frist set so we can use the "start:first" to populate the VQ
+
+  for v=2:2:NtrainVec
+    trainvec(v,:) = cos(v)*[2 -1 2] -2*v;
+  end
+
+  trainvec
+
+  [idx vq]  = kmeans2(trainvec, Nvec, 
+                      "start", "first", 
+                      "search_func", "vq_search_mag");
+
+  vq
+
+  % todo: how to auto test?  Need to solve same euqations?
+#}
+  tol = 0.001; ok = 0;
+  for i=1:Nvec
+    diff = vq(i,:) - [1 1 1];
+    if std(diff) < tol, ok++; end;
+    diff = vq(i,:) - [1 0 -1];
+    if std(diff) < tol, ok++; end;
+  end
+  if ok == 2, printf("gain: OK\n"); end;
+#}
+endfunction
+
+
+function test_training_slope
+  K = 40; NtrainVec = 5; Nvec = 1;  
+
+  % Given a vector x, create a set of training data y = m*x + c + sl, where:
+  %  x is a vector
+  %  c is a constant offset
+  %  m is a magnitude multiplier on all elements of x
+  %  sl is a linear slope vector
+
+  load surf_all;
+  prototype = surf_all(73,:);
+  trainvec = zeros(NtrainVec,K);
+  for v=1:NtrainVec
+    trainvec(v,:) = 2*prototype + 1 + v*(1:K);
+   end
+  figure(1); clf; plot(trainvec');
+
+  [idx vq]  = kmeans2(trainvec, Nvec, 
+                      "start", "first", 
+                      "search_func", "vq_search_slope");
+
+  
+  [idx contrib errors test_ g mg sl] = vq_search_slope(prototype, trainvec)
+  
+  % todo: how to auto test?  Need to solve same euqations?
+#{
+  tol = 0.001; ok = 0;
+  for i=1:Nvec
+    diff = vq(i,:) - [1 1 1];
+    if std(diff) < tol, ok++; end;
+    diff = vq(i,:) - [1 0 -1];
+    if std(diff) < tol, ok++; end;
+  end
+  if ok == 2, printf("gain: OK\n"); end;
+#}
+endfunction
+
+% ---------------------------------------------------------
+
+format; more off;
+rand('seed',1);    % kmeans using rand for initial population,
+                   % we want same results on every run
+
+% choose one of these to run
+
+detailed_test(64, 1, 20, quick_check=1);
+%[sd desc] = long_tests_1_10(quick_check=1);
+%[sd desc] = long_tests_11_40(quick_check=0);
+%test_training_slope
+
+
+
diff --git a/codec2/branches/0.7/octave/ldpc.m b/codec2/branches/0.7/octave/ldpc.m
new file mode 100644 (file)
index 0000000..3cbf7fe
--- /dev/null
@@ -0,0 +1,143 @@
+% ldpc.m
+%
+% David Rowe 2013
+% Octave functions to help us use the CML LDPC code.
+%
+% Installing CML library
+% ----------------------
+%
+% $ sudo apt-get install liboctave-dev
+% $ wget http://www.iterativesolutions.com/user/image/cml.1.10.zip
+% $ unzip cml.1.10.zip
+% $ patch -p0 < ~/codec2-dev/octave/cml.patch
+% $ cd cml/source
+% $ octave
+% octave:> make
+% (you'll see a few warnings but hopefully no errors)
+
+1;
+
+% NOTE: You will need to set the CML path in the call to init_cml() below
+%       for you CML install.  See lpdc.m for instructions on how to install 
+%       CML library
+
+function init_cml(path_to_cml)
+  currentdir = pwd;
+  
+  if exist(path_to_cml, 'dir') == 7
+    cd(path_to_cml)
+    CmlStartup      
+    cd(currentdir); 
+  else
+    printf("\n---------------------------------------------------\n");
+    printf("Can't start CML in path: %s\n", path_to_cml);
+    printf("See CML path instructions at top of this script\n");
+    printf("-----------------------------------------------------\n\n");
+    assert(0);
+  end
+end
+
+% init using built in WiMax code
+
+function code_param = ldpc_init_wimax(rate, framesize, modulation, mod_order, mapping)
+    [code_param.H_rows, code_param.H_cols, code_param.P_matrix] = InitializeWiMaxLDPC( rate, framesize,  0 );
+    code_param.data_bits_per_frame = length(code_param.H_cols) - length( code_param.P_matrix );
+    code_param.S_matrix = CreateConstellation( modulation, mod_order, mapping );
+    code_param.bits_per_symbol = log2(mod_order);
+    code_param.code_bits_per_frame = framesize;
+    code_param.symbols_per_frame = framesize/code_param.bits_per_symbol;
+endfunction
+
+
+% init using user supplied code
+
+function [code_param framesize rate] = ldpc_init_user(HRA, modulation, mod_order, mapping)
+    [Nr Nc] = size(HRA);  
+    rate = (Nc-Nr)/Nc;
+    framesize = Nc;
+    [H_rows, H_cols] = Mat2Hrows(HRA); 
+    code_param.H_rows = H_rows; 
+    code_param.H_cols = H_cols;
+    code_param.P_matrix = [];
+    code_param.data_bits_per_frame = length(code_param.H_cols) - length(code_param.P_matrix); 
+    code_param.S_matrix = CreateConstellation( modulation, mod_order, mapping );
+    code_param.bits_per_symbol = log2(mod_order);
+    code_param.code_bits_per_frame = framesize;
+    code_param.symbols_per_frame = framesize/code_param.bits_per_symbol;
+endfunction
+
+
+function [codeword s] = ldpc_enc(data, code_param)
+    codeword = LdpcEncode( data, code_param.H_rows, code_param.P_matrix );
+    s = Modulate( codeword, code_param.S_matrix );
+endfunction
+
+
+function detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, r, EsNo, fading)
+    if nargin == 6
+      fading = ones(1, length(r));
+    end
+
+    symbol_likelihood = Demod2D( r, code_param.S_matrix, EsNo, fading);
+         
+    % initialize the extrinsic decoder input
+
+    input_somap_c = zeros(1, code_param.code_bits_per_frame );
+    bit_likelihood = Somap( symbol_likelihood, demod_type, input_somap_c );
+        
+    input_decoder_c = bit_likelihood(1:code_param.code_bits_per_frame);
+        
+    x_hat= MpDecode( -input_decoder_c, code_param.H_rows, code_param.H_cols, ...
+                     max_iterations, decoder_type, 1, 1);
+    detected_data = x_hat(max_iterations,:);
+endfunction
+
+
+% Packs a binary array into an array of 8 bit bytes, MSB first
+
+function packed = packmsb(unpacked)
+    packed = zeros(1,floor(length(unpacked)+7)/8);
+    bit = 7; byte = 1;
+    for i=1:length(unpacked)
+        packed(byte) = bitor(packed(byte), bitshift(unpacked(i),bit));
+        bit--;
+        if (bit < 0)
+            bit = 7;
+            byte++;
+        end 
+    end
+endfunction
+
+
+% unpacks an array of 8 bit bytes into a binary array of unpacked bits, MSB first
+
+function unpacked = unpackmsb(packed)
+    bit = 7; byte = 1;
+    for i=1:length(packed)*8
+        unpacked(i) = bitand(bitshift(packed(byte), -bit), 1);
+        bit--;
+        if (bit < 0)
+            bit = 7;
+            byte++;
+        end 
+    end
+endfunction
+
+
+% symbol interleaver that acts on bits 2 at a time
+
+function y = interleave_bits(interleaver, x)
+    y =  zeros(1,length(x));
+    for i = 1:length(interleaver)
+        dst = interleaver(i);
+        y(2*(dst-1)+1:2*dst) = x(2*(i-1)+1:2*(i));
+    end
+endfunction
+
+% symbol de-interleaver
+
+function x = deinterleave_symbols(interleaver, y)
+    for i = 1:length(interleaver)
+        x(i) = y(interleaver(i));
+    end
+endfunction
diff --git a/codec2/branches/0.7/octave/ldpc_fsk_lib.m b/codec2/branches/0.7/octave/ldpc_fsk_lib.m
new file mode 100644 (file)
index 0000000..661758d
--- /dev/null
@@ -0,0 +1,269 @@
+% lpdc_fsk_lib.m\r
+% April 2015\r
+%\r
+% Library version of ldpc4.m written by vk5dsp.  Application is high bit rate\r
+% balloon telemtry\r
+%\r
+% LDPC demo\r
+% Call the CML routines and simulate one set of SNRs.  \r
+% This fucntion is an updated version of ldpc3() which uses less \r
+% of the CML functions \r
+%\r
+% sim_in the input parameter structure\r
+% sim_out contains BERs and other stats for each value of SNR\r
+% resfile is the result file\r
+%\r
+\r
+1;\r
+\r
+function sim_out = ldpc5(sim_in, resfile, testmode, genie_Es, logging=0);\r
+\r
+    if nargin<4, testmode = 0; end\r
+    estEsN0 = 0; \r
+\r
+    HRA       = sim_in.HRA;\r
+    framesize = sim_in.framesize;\r
+    rate      = sim_in.rate;\r
+    mod_order = sim_in.mod_order;\r
+\r
+    Lim_Ferrs = sim_in.Lim_Ferrs;\r
+    Ntrials   = sim_in.Ntrials;\r
+    Esvec     = sim_in.Esvec;\r
+\r
+    demod_type = 0;\r
+    decoder_type = 0;\r
+    max_iterations = 100;\r
+    code_param = ldpc_init(HRA, mod_order);\r
+    bps = code_param.bits_per_symbol;\r
+\r
+\r
+    if (logging) \r
+       fod = fopen('decode.log', 'w'); \r
+       fwrite(fod, 'Es estEs Its  secs \n'); \r
+    end \r
+\r
+\r
+    for ne = 1:length(Esvec)\r
+        Es = Esvec(ne);\r
+        EsNo = 10^(Es/10);\r
+\r
+\r
+        Terrs = 0;  Tbits =0;  Ferrs =0;\r
+        for nn = 1: Ntrials\r
+\r
+          data = round( rand( 1, code_param.data_bits_per_frame ) );\r
+          codeword = ldpc_encode(code_param, data);\r
+\r
+          code_param.code_bits_per_frame = length( codeword );\r
+          Nsymb = code_param.code_bits_per_frame/bps;\r
+\r
+            if testmode==1\r
+               f1 = fopen("dat_in2064.txt", "w");\r
+               for k=1:length(data);  fprintf(f1, "%u\n", data(k)); end\r
+               fclose(f1); \r
+               system("./ra_enc"); \r
+\r
+               load("dat_op2064.txt"); \r
+               pbits = codeword(length(data)+1:end);   %   print these to compare with C code \r
+               dat_op2064(1:16)', pbits(1:16)  \r
+               differences_in_parity =  sum(abs(pbits - dat_op2064'))\r
+               pause;  \r
+            end\r
+\r
+\r
+            % modulate\r
+            % s = Modulate( codeword, code_param.S_matrix );\r
+            s= 1 - 2 * codeword;   \r
+            code_param.symbols_per_frame = length( s );\r
+\r
+            variance = 1/(2*EsNo);\r
+            noise = sqrt(variance)* randn(1,code_param.symbols_per_frame); \r
+            %  +  j*randn(1,code_param.symbols_per_frame) );\r
+            r = s + noise;\r
+            Nr = length(r);  \r
+\r
+            [detected_data Niters] = ldpc_decode(r, code_param, max_iterations, decoder_type);\r
+\r
+            error_positions = xor( detected_data(1:code_param.data_bits_per_frame), data );\r
+            Nerrs = sum( error_positions);\r
+\r
+            t = clock;   t =  fix(t(5)*60+t(6)); \r
+            if (logging)  \r
+              fprintf(fod, ' %3d  %4d\n', Niters, t); \r
+              end \r
+\r
+            if Nerrs>0, fprintf(1,'x'),  else fprintf(1,'.'),  end\r
+            if (rem(nn, 50)==0),  fprintf(1,'\n'),  end\r
+\r
+            if Nerrs>0,  Ferrs = Ferrs +1;  end\r
+            Terrs = Terrs + Nerrs;\r
+            Tbits = Tbits + code_param.data_bits_per_frame;\r
+\r
+            if Ferrs > Lim_Ferrs, disp(['exit loop with #cw errors = ' ...\r
+                    num2str(Ferrs)]);  break,  end\r
+        end\r
+\r
+        TERvec(ne) = Terrs;\r
+        FERvec(ne) = Ferrs;\r
+        BERvec(ne) = Terrs/ Tbits;\r
+        Ebvec = Esvec - 10*log10(code_param.bits_per_symbol * rate);\r
+\r
+        cparams= [code_param.data_bits_per_frame  code_param.symbols_per_frame ...\r
+            code_param.code_bits_per_frame];\r
+\r
+        sim_out.BERvec = BERvec;\r
+        sim_out.Ebvec = Ebvec;\r
+        sim_out.FERvec = FERvec;\r
+        sim_out.TERvec  = TERvec;\r
+        sim_out.cpumins = cputime/60;\r
+\r
+        if nargin > 2\r
+            save(resfile,  'sim_in',  'sim_out',  'cparams');\r
+            disp(['Saved results to ' resfile '  at Es =' num2str(Es) 'dB']);\r
+        end\r
+      end\r
+end\r
+\r
+\r
+function code_param = ldpc_init(HRA, mod_order)\r
+  code_param.bits_per_symbol = log2(mod_order);\r
+  [H_rows, H_cols] = Mat2Hrows(HRA); \r
+  code_param.H_rows = H_rows; \r
+  code_param.H_cols = H_cols;\r
+  code_param.P_matrix = [];\r
+  code_param.data_bits_per_frame = length(code_param.H_cols) - length( code_param.P_matrix ); \r
+  code_param.symbols_per_frame = length(HRA);\r
+end\r
+\r
+\r
+function codeword = ldpc_encode(code_param, data)\r
+      codeword = LdpcEncode( data, code_param.H_rows, code_param.P_matrix );\r
+endfunction\r
+\r
+\r
+% Takes soft decision symbols (e.g. output of 2fsk demod) and converts\r
+% them to LLRs.  Note we calculate mean and var manually instead of\r
+% using internal functions.  This was required to get a bit exact\r
+% results against the C code.\r
+\r
+function llr = sd_to_llr(sd)\r
+    sd = sd / mean(abs(sd));\r
+    x = sd - sign(sd);\r
+    sumsq = sum(x.^2);\r
+    summ = sum(x);\r
+    mn = summ/length(sd);\r
+    estvar = sumsq/length(sd) - mn*mn; \r
+    estEsN0 = 1/(2* estvar + 1E-3); \r
+    llr = 4 * estEsN0 * sd;\r
+endfunction\r
+\r
+\r
+% LDPC decoder - note it estimates EsNo from received symbols\r
+\r
+function [detected_data Niters] = ldpc_decode(r, code_param, max_iterations, decoder_type)\r
+  % in the binary case the LLRs are just a scaled version of the rx samples ..\r
+\r
+ #{\r
+  r = r / mean(abs(r));       % scale for signal unity signal  \r
+  estvar = var(r-sign(r)); \r
+  estEsN0 = 1/(2* estvar + 1E-3); \r
+  input_decoder_c = 4 * estEsN0 * r;\r
+ #}\r
+  llr = sd_to_llr(r);\r
+\r
+  [x_hat, PCcnt] = MpDecode(llr, code_param.H_rows, code_param.H_cols, ...\r
+                            max_iterations, decoder_type, 1, 1);         \r
+  Niters = sum(PCcnt!=0);\r
+  detected_data = x_hat(Niters,:);\r
+  \r
+  if isfield(code_param, "c_include_file")\r
+    ldpc_gen_h_file(code_param, max_iterations, decoder_type, llr, x_hat, detected_data);\r
+  end\r
+end\r
+\r
+\r
+% One application of FSK LDPC work is SSTV.  This function generates a\r
+% simulated frame for testing\r
+\r
+function frame_rs232 = gen_sstv_frame\r
+  load('H2064_516_sparse.mat');\r
+  HRA = full(HRA);  \r
+  mod_order = 2;\r
+  code_param = ldpc_init(HRA, mod_order);\r
+\r
+  % generate payload data bytes and checksum\r
+\r
+  data = floor(rand(1,256)*256);\r
+  %data = zeros(1,256);\r
+  checksum = crc16(data);\r
+  data = [data hex2dec(checksum(3:4)) hex2dec(checksum(1:2))];\r
+\r
+  % unpack bytes to bits and LPDC encode\r
+\r
+  mask = 2.^(7:-1:0);       % MSB to LSB unpacking to match python tx code.\r
+  unpacked_data = [];\r
+  for b=1:length(data)\r
+    unpacked_data = [unpacked_data bitand(data(b), mask) > 0];\r
+  end\r
+  codeword = [ldpc_encode(code_param, unpacked_data) 0 0 0 0];  % pad with 0s to get integer number of bytes\r
+\r
+  % pack back into bytes to match python code \r
+\r
+  lpacked_codeword = length(codeword)/8;\r
+  packed_codeword = zeros(1,lpacked_codeword);\r
+  for b=1:lpacked_codeword\r
+    st = (b-1)*8 + 1;\r
+    packed_codeword(b) = sum(codeword(st:st+7) .* mask);\r
+  end\r
+\r
+  % generate header bits\r
+\r
+  header = [hex2dec('55')*ones(1,16) hex2dec('ab') hex2dec('cd') hex2dec('ef') hex2dec('01')];\r
+\r
+  % now construct entire unpacked frame\r
+\r
+  packed_frame = [header packed_codeword];\r
+  mask = 2.^(0:7);        % LSB to MSB packing for header\r
+  lpacked_frame = length(packed_frame);\r
+  frame = [];\r
+  for b=1:lpacked_frame\r
+    frame = [frame bitand(packed_frame(b), mask) > 0];\r
+  end\r
+\r
+  % insert rs232 framing bits\r
+\r
+  frame_rs232 = [];\r
+  for b=1:8:length(frame)\r
+    frame_rs232 = [frame_rs232 0 frame(b:b+7) 1];\r
+  end\r
+\r
+  %printf("codeword: %d unpacked_header: %d frame: %d frame_rs232: %d \n", length(codeword), length(unpacked_header), length(frame), length(frame_rs232));\r
+endfunction\r
+\r
+\r
+% calculates and compares the checksum of a SSTV frame, that has RS232\r
+% start and stop bits\r
+\r
+function checksum_ok = sstv_checksum(frame_rs232)\r
+  l = length(frame_rs232);\r
+  expected_l = (256+2)*10;\r
+  assert(l == expected_l);\r
+\r
+  % extract rx bytes\r
+\r
+  rx_data = zeros(1,256);\r
+  mask = 2.^(0:7);          % LSB to MSB\r
+  k = 1;\r
+  for i=1:10:expected_l\r
+    rx_bits = frame_rs232(i+1:i+8);\r
+    rx_data(k) = sum(rx_bits .* mask); \r
+    k++;\r
+  end\r
+\r
+  % calc rx checksum and extract tx checksum\r
+\r
+  rx_checksum = crc16(rx_data(1:256));\r
+  tx_checksum = sprintf("%02X%02X", rx_data(258), rx_data(257));\r
+  %printf("tx_checksum: %s rx_checksum: %s\n", tx_checksum, rx_checksum);\r
+  checksum_ok = strcmp(tx_checksum, rx_checksum);\r
+endfunction\r
diff --git a/codec2/branches/0.7/octave/ldpc_gen_h_file.m b/codec2/branches/0.7/octave/ldpc_gen_h_file.m
new file mode 100644 (file)
index 0000000..edda815
--- /dev/null
@@ -0,0 +1,72 @@
+% ldpc_gen_h_file.m
+% David Rowe Sep 2015
+%
+% Create a C include file for use in mpdecode.c C cmd line LDPC decoder
+
+function ldpc_gen_h_file(code_param, max_iterations, decoder_type, input_decoder_c, x_hat, detected_data)
+       
+  f = fopen(code_param.c_include_file, "wt");
+
+  fprintf(f, "/*\n  FILE....: %s\n\n  Static arrays for LDPC codec, generated", code_param.c_include_file);
+  fprintf(f, "\n  ldpc_gen_h_file.m.\n\n*/\n\n");
+   
+  fprintf(f,"#define NUMBERPARITYBITS %d\n", rows(code_param.H_rows));
+  fprintf(f,"#define MAX_ROW_WEIGHT %d\n", columns(code_param.H_rows));
+  fprintf(f,"#define CODELENGTH %d\n", code_param.symbols_per_frame);
+  fprintf(f,"#define NUMBERROWSHCOLS %d\n", rows(code_param.H_cols));
+  fprintf(f,"#define MAX_COL_WEIGHT %d\n", columns(code_param.H_cols));
+  fprintf(f,"#define DEC_TYPE %d\n", decoder_type);
+  fprintf(f,"#define MAX_ITER %d\n", max_iterations);
+
+  fprintf(f,"\ndouble H_rows[] = {\n");
+     
+  % clock out 2D array to linear C array in row order ....
+
+  [r c] = size(code_param.H_rows);
+  for j=1:c
+    for i=1:r
+      fprintf(f, "%d", code_param.H_rows(i,j));
+      if (i == r) && (j ==c)
+        fprintf(f,"\n};\n");
+      else
+        fprintf(f,", ");
+      end
+    end
+  end
+
+  fprintf(f,"\ndouble H_cols[] = {\n");
+  [r c] = size(code_param.H_cols);
+  for j=1:c
+    for i=1:r
+      fprintf(f, "%d", code_param.H_cols(i,j));
+      if (i == r) && (j == c)
+        fprintf(f,"\n};\n");
+      else
+        fprintf(f,", ");
+      end
+    end
+  end
+
+  fprintf(f,"\ndouble input[] = {\n");
+  for i=1:length(input_decoder_c)
+    fprintf(f, "%.17g", input_decoder_c(i));
+    if i == length(input_decoder_c)
+      fprintf(f,"\n};\n");
+    else
+      fprintf(f,", ");            
+    end
+  end
+
+  fprintf(f,"\nchar detected_data[] = {\n");
+  for i=1:length(detected_data)
+    fprintf(f, "%d", detected_data(i));
+    if i == length(detected_data)
+      fprintf(f,"\n};\n");
+    else
+      fprintf(f,", ");            
+    end
+  end
+
+  fclose(f);
+end
+
diff --git a/codec2/branches/0.7/octave/ldpc_qpsk.m b/codec2/branches/0.7/octave/ldpc_qpsk.m
new file mode 100644 (file)
index 0000000..4124b45
--- /dev/null
@@ -0,0 +1,458 @@
+% ldpc_qpsk.m
+%
+% David Rowe 18 Dec 2013
+%
+% Similar to ldpc_short.m, but derived from ldpcut.m and uses QPSK and
+% CML 2D functunctions and QPSK.  Probably should combine this and
+% ldpc_short.m some day.
+
+% Our LDPC library
+
+ldpc;
+qpsk;
+gp_interleaver;
+
+
+function sim_out = run_simulation(sim_in)
+
+  % Note this is effective Eb/No of payload data bits, sorta thing we
+  % plot on BER versus Eb/No graphs of decoded data.  So if we have a
+  % rate 1/2 code, each codeword bit will have Eb/No - 3dB.
+
+  EbNodBvec = sim_in.EbNodBvec;
+
+  % for wimax code frame size specifies code
+
+  if isfield(sim_in, "framesize")
+    framesize = sim_in.framesize;
+    rate = sim_in.rate; 
+  end
+
+  Ntrials = sim_in.Ntrials;
+  verbose = sim_in.verbose;
+  if isfield(sim_in, "hf_en")
+    hf_en = sim_in.hf_en;
+  else
+    hf_en = 0;
+  end
+  ldpc_code = sim_in.ldpc_code;
+  interleave_en = sim_in.interleave_en;
+
+  % Init LDPC code ------------------------------------
+
+  mod_order = 4; bps = 2;
+  modulation = 'QPSK';
+  mapping = 'gray';
+
+  demod_type = 0;
+  decoder_type = 0;
+  max_iterations = 100;
+
+  if ldpc_code == 1
+    code_param = ldpc_init_wimax(rate, framesize, modulation, mod_order, mapping);
+  end
+  if ldpc_code == 0
+    load HRA_112_112.txt
+    [code_param framesize rate] = ldpc_init_user(HRA_112_112, modulation, mod_order, mapping);
+  end
+  if ldpc_code == 2
+    load('H2064_516_sparse.mat');
+    HRA = full(HRA);  
+    [code_param framesize rate] = ldpc_init_user(HRA, modulation, mod_order, mapping);
+  end 
+  if ldpc_code == 3
+    load('h0p25d.mat');
+    %HRA = full(HRA);  
+    [code_param framesize rate] = ldpc_init_user(H, modulation, mod_order, mapping);
+  end
+
+  % set up optional HF (multipath) model ------------------------------------
+
+  % signal is arranged as Nc parallel carriers.  Nc is chosen such
+  % that payload data rate is 700 bits/s.  So for higher rate codes Nc
+  % will be smaller.
+
+  Rs = 50;
+  vocoder_bps = 700; raw_bps = vocoder_bps/rate;  
+  Nc = round(raw_bps/(Rs*bps));
+  Tp = (framesize/Nc)/Rs; Tp_codec2 = 0.04;
+  fading = ones(1,Ntrials*code_param.code_bits_per_frame/bps);
+
+  printf("framesize: %d  rate: %3.2f  Nc: %d\n", framesize, rate, Nc);
+
+  if hf_en
+
+    % We assume symbols spread acroos Nc OFDM carriers
+
+    dopplerSpreadHz = 1.0; path_delay = 1E-3*Rs;
+
+    if isfield(sim_in, "dopplerSpreadHz") 
+      dopplerSpreadHz = sim_in.dopplerSpreadHz;
+    end
+    if isfield(sim_in, "path_delay") 
+      path_delay = sim_in.path_delay;
+    end
+    printf("Doppler Spread: %3.2f Hz Path Delay: %3.2f symbols\n", dopplerSpreadHz, path_delay);
+
+    % reset seed so we get same fading channel on every simulation
+
+    randn('seed',1);
+
+    Ns = Ntrials*code_param.code_bits_per_frame/bps;
+    Nr = ceil(Ns/Nc);
+    hf_model = zeros(Nr,Nc); 
+
+    % note we ask for 10% more samples than we need, as
+    % doppler_spread() function can sometimes return slightly less
+    % than we need due to round off
+
+    spread1 = doppler_spread(dopplerSpreadHz, Rs, Nr*1.1);
+    spread2 = doppler_spread(dopplerSpreadHz, Rs, Nr*1.1);
+    spread1 = spread1(1:Nr); 
+    spread2 = spread2(1:Nr);
+    hf_gain = 1.0/sqrt(var(spread1)+var(spread2));
+  end
+
+  % ----------------------------------
+  % run simulation at each Eb/No point
+  % ----------------------------------
+
+  for ne = 1:length(EbNodBvec)
+    randn('seed',1);
+    rand('seed',1);
+
+    % Given Eb/No of payload data bits, work out Es/No we need to
+    % apply to each channel symbol:
+    %
+    % i) Each codeword bit gets noise: Eb/No - 3 (for a rate 1/2 code)
+    % ii) QPSK means two bits/symbol.: Es/No = Eb/No + 3
+    %
+    % -> which neatly cancel out ...... (at least for rate 1/2)
+
+    EsNodB = EbNodBvec(ne) + 10*log10(rate) + 10*log10(bps);
+    EsNo = 10^(EsNodB/10);
+    variance = 1/EsNo;
+    hf_r = 1;
+    
+    Tbits = Terrs = Ferrs = Terrs_raw = Tbits_raw = 0;
+    
+    tx_bits = [];
+    tx_symbols = []; 
+    rx_symbols = [];
+
+    % Encode a bunch of frames
+
+    for nn=1:Ntrials        
+      atx_bits = round(rand( 1, code_param.data_bits_per_frame));
+      tx_bits = [tx_bits atx_bits];
+      [tx_codeword atx_symbols] = ldpc_enc(atx_bits, code_param);
+      if interleave_en
+        atx_symbols = gp_interleave(atx_symbols);
+      end
+      tx_symbols = [tx_symbols atx_symbols];
+    end
+    
+    rx_symbols = tx_symbols;
+
+    % Optional HF (multipath) channel model
+
+    if hf_en
+
+      % Simplified rate Rs OFDM simulation model that doesn't
+      % include ISI, just freq filtering.  We assume perfect phase
+      % estimation so it's just amplitude distortion.  We distribute
+      % symbols across Nc carriers
+
+      Ns = length(tx_symbols);
+      w = (1:Nc)*2*pi;  
+      rx_symbols = [rx_symbols zeros(1,Nr*Nc-Ns)];  % pad out to integer number of rows
+
+      for r=1:Nr
+        for c=1:Nc
+          hf_model(hf_r,c) = hf_gain*(spread1(hf_r) + exp(-j*w(c)*path_delay)*spread2(hf_r));
+          rx_symbols(Nc*(r-1)+c) *= abs(hf_model(hf_r,c));
+          fading(Nc*(r-1)+c) = abs(hf_model(hf_r,c));
+        end
+        hf_r++;
+      end
+      rx_symbols = rx_symbols(1:Ns); % remove padding
+    end
+
+    % Add AWGN noise, 0.5 factor splits power evenly between Re & Im
+
+    noise = sqrt(variance*0.5)*(randn(1,length(tx_symbols)) + j*randn(1,length(tx_symbols)));
+    rx_symbols += noise;
+
+    % Decode a bunch of frames
+
+    rx_bits_log = []; error_positions_log = [];
+    Nerrs_raw_log = [];
+
+    for nn = 1: Ntrials        
+      st = (nn-1)*code_param.symbols_per_frame + 1;
+      en = (nn)*code_param.symbols_per_frame;
+
+      % coded 
+
+      arx_symbols = rx_symbols(st:en);
+      afading = fading(st:en);
+      if interleave_en
+        arx_symbols = gp_deinterleave(arx_symbols);
+        afading = gp_deinterleave(afading);
+      end
+
+      arx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, arx_symbols, EsNo, afading);
+      st = (nn-1)*code_param.data_bits_per_frame + 1;
+      en = (nn)*code_param.data_bits_per_frame;
+      arx_bits = arx_codeword(1:code_param.data_bits_per_frame);
+      error_positions = xor(arx_bits, tx_bits(st:en));
+      error_positions_log = [error_positions_log error_positions];
+      Nerrs = sum( error_positions);
+      rx_bits_log = [rx_bits_log arx_bits];
+        
+      % uncoded - to est raw BER compare first half or received frame to tx_bits as code is systematic
+      
+      raw_rx_bits = [];
+      for s=1:code_param.symbols_per_frame*rate
+        raw_rx_bits = [raw_rx_bits qpsk_demod(arx_symbols(s))];
+      end
+      Nerrs_raw = sum(xor(raw_rx_bits, tx_bits(st:en)));
+      Nbits_raw = code_param.data_bits_per_frame;
+      Nerrs_raw_log = [Nerrs_raw_log Nerrs_raw];
+
+      if verbose == 2
+        % print "." if frame decoded without errors, 'x' if we can't decode
+
+        if Nerrs > 0, printf('x'),  else printf('.'),  end
+        if (rem(nn, 50)==0),  printf('\n'),  end    
+      end
+
+      if Nerrs > 0,  Ferrs = Ferrs + 1;  end
+      Terrs     += Nerrs;
+      Tbits     += code_param.data_bits_per_frame;        
+      Terrs_raw += Nerrs_raw;
+      Tbits_raw += Nbits_raw;
+    end
+
+    % Alternative Codec 2 packet rate measurement indep of framesize
+
+    Nerrs_codec2_log = []; Ncodecpacketsize = 28;
+    Perrs = 0; Npackets = floor(length(tx_bits)/Ncodecpacketsize);
+    for p=1:Ncodecpacketsize:Npackets*Ncodecpacketsize
+      Nerrs = sum(xor(tx_bits(p:p+Ncodecpacketsize-1), rx_bits_log(p:p+Ncodecpacketsize-1)));
+      if Nerrs
+        Perrs++;
+      end
+      Nerrs_codec2_log = [Nerrs_codec2_log Nerrs];
+    end
+
+    if verbose
+      printf("\nCoded EbNodB: %3.2f BER: %4.3f Tbits: %6d Terrs: %6d FER: %4.3f Tframes: %d Ferrs: %d\n",
+             EbNodBvec(ne), Terrs/Tbits, Tbits, Terrs,  Ferrs/Ntrials, Ntrials, Ferrs);
+      EbNodB_raw = EbNodBvec(ne) + 10*log10(rate);
+      printf("Raw EbNodB..: %3.2f BER: %4.3f Tbits: %6d Terrs: %6d\n", 
+             EbNodB_raw, Terrs_raw/Tbits_raw, Tbits_raw, Terrs_raw);
+      printf("Codec 2 PER: %5.4f Npackets: %d Perrs: %d\n", Perrs/Npackets, Npackets, Perrs);
+    end
+
+    sim_out.rate = rate;
+    sim_out.BER(ne) = Terrs/Tbits;
+    sim_out.PER(ne) = Perrs/Npackets;
+    sim_out.error_positions = error_positions_log;
+
+    if hf_en && (verbose > 1)
+      figure(2); clf;
+      plot(real(rx_symbols(Ns/2:Ns)), imag(rx_symbols(Ns/2:Ns)), '+');
+      axis([-2 2 -2 2]);
+      title('Scatter')
+
+      figure(3); clf;
+      subplot(211);
+      stem((1:Ntrials)*Tp, Nerrs_raw_log);
+      subplot(212);
+      stem((1:Npackets)*Tp_codec2, Nerrs_codec2_log);
+
+      figure(4); clf;
+
+      % limit mesh plot to Np points to plot quickly
+      
+      Np = 500;
+      step = ceil(hf_r/Np);
+      mesh(1:Nc, (1:step:hf_r-1)/Rs, abs(hf_model(1:step:hf_r-1,:)))
+      title('HF channel amplitude');
+      xlabel('Carrier');
+      ylabel('Time (s)');
+
+      figure(5)
+      subplot(211); plot((1:hf_r-1)/Rs, abs(spread1(1:hf_r-1)));
+      subplot(212); plot((1:hf_r-1)/Rs, abs(spread2(1:hf_r-1)));
+      title('HF spreading function amplitudes')
+    end
+  end
+
+endfunction
+
+
+% ---------------------------------------------------------------------------------
+% Run a bunch of trials at just one EbNo point
+% ---------------------------------------------------------------------------------
+
+function run_single(Nbits=700*10, EbNodB=9, hf_en=0, ldpc_code=1, framesize=576, interleave_en=0, error_pattern_filename)
+  sim_in.ldpc_code = ldpc_code;
+
+  if sim_in.ldpc_code == 0
+    % Our HRA short LDPC code
+    sim_in.rate=0.5;
+    sim_in.framesize=448*4+448; 
+  end
+  if sim_in.ldpc_code == 1
+    % CML wimax codes
+    sim_in.rate = 0.5; 
+    sim_in.framesize = framesize;
+  end
+  if sim_in.ldpc_code == 2
+    sim_in.rate=0.8;
+    sim_in.framesize=2064+516; 
+  end 
+  if sim_in.ldpc_code == 3
+    sim_in.rate=0.25;
+    sim_in.framesize=2064+516; 
+  end 
+
+  sim_in.verbose = 2;
+  sim_in.Ntrials = ceil(Nbits/(sim_in.framesize*sim_in.rate));
+  sim_in.EbNodBvec = EbNodB;
+  sim_in.hf_en = hf_en;
+  sim_in.interleave_en = interleave_en;
+
+  sim_out = run_simulation(sim_in);
+
+  if nargin == 7
+    fep = fopen(error_pattern_filename, "wb");
+    fwrite(fep, sim_out.error_positions, "short");
+    fclose(fep);
+  end
+
+end
+
+% ---------------------------------------------------------------------------------
+% Lets draw some Eb/No versus BER curves 
+% ---------------------------------------------------------------------------------
+
+function plot_curves(Nbits=700*60)
+  sim_in.EbNodBvec = -2:12;
+  sim_in.verbose = 2;
+  sim_in.interleave_en = 1;
+
+  % Low rate 0.25 VK5DSP code
+
+  sim_in.ldpc_code = 3;
+  sim_in.rate = 0.25;
+  sim_in.framesize = 448*4+448;  
+  sim_in.Ntrials = floor(Nbits/(sim_in.framesize*sim_in.rate));
+
+  sim_in.hf_en = 0; sim_out_awgn_low = run_simulation(sim_in);
+  sim_in.hf_en = 1; sim_out_hf_low = run_simulation(sim_in);
+
+  % Wimax code
+
+  sim_in.ldpc_code = 1;
+  sim_in.rate = 0.5; 
+  sim_in.framesize = 576*4;
+  sim_in.Ntrials = floor(Nbits/(sim_in.framesize*sim_in.rate));
+
+  sim_in.hf_en = 0; sim_out_awgn_wimax = run_simulation(sim_in);
+  sim_in.hf_en = 1; sim_out_hf_wimax = run_simulation(sim_in);
+
+  % Our short code from VK5DSP
+
+  sim_in.ldpc_code = 0;
+  sim_in.rate = 0.5;
+  sim_in.framesize = 224;  
+  sim_in.Ntrials = floor(Nbits/(sim_in.framesize*sim_in.rate));
+
+  sim_in.hf_en = 0; sim_out_awgn_short = run_simulation(sim_in);
+  sim_in.hf_en = 1; sim_out_hf_short = run_simulation(sim_in);
+
+  % Rate 0.8 Wenet code from VK5DSP
+
+  sim_in.ldpc_code = 2;
+  sim_in.rate = 0.8;
+  sim_in.framesize = 2064+512;  
+  sim_in.Ntrials = floor(Nbits/(sim_in.framesize*sim_in.rate));
+
+  sim_in.hf_en = 0; sim_out_awgn_wenet = run_simulation(sim_in);
+  sim_in.hf_en = 1; sim_out_hf_wenet = run_simulation(sim_in);
+
+  % plots -------------------------
+
+  EbNodB = sim_in.EbNodBvec;
+  uncoded_awgn_ber_theory = 0.5*erfc(sqrt(10.^(EbNodB/10)));
+
+  EbNoLin = 10.^(EbNodB/10);
+  uncoded_hf_ber_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));
+
+  figure(1)
+  clf
+  semilogy(EbNodB, uncoded_awgn_ber_theory,'r-+;AWGN Uncoded;','markersize', 10, 'linewidth', 2)
+  hold on;
+  semilogy(EbNodB, uncoded_hf_ber_theory,'r-o;HF Uncoded;','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_wimax.BER+1E-10,'g-+;AWGN LDPC (2304,1152);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_wimax.BER+1E-10,'g-o;HF LDPC (2304,1152);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_short.BER+1E-10,'b-+;AWGN LDPC (224,112);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_short.BER+1E-10,'b-o;HF LDPC (224,112);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_wenet.BER+1E-10,'c-+;AWGN LDPC (2576,2064);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_wenet.BER+1E-10,'c-o;HF LDPC (2576,2064);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_low.BER+1E-10,'k-+;AWGN LDPC (1792,448);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_low.BER+1E-10,'k-o;HF LDPC (1792,448);','markersize', 10, 'linewidth', 2);
+  hold off;
+  grid('minor')
+  xlabel('Eb/No (dB)')
+  ylabel('BER')
+  axis([min(EbNodB) max(EbNodB) 1E-3 5E-1])
+  legend('boxoff')
+  epsname = sprintf("ldpc_qpsk_ber.eps");
+  print('-deps', '-color', epsname)
+
+  uncoded_awgn_per_theory = 1 - (1-uncoded_awgn_ber_theory).^28;
+  uncoded_hf_per_theory = 1 - (1-uncoded_hf_ber_theory).^28;
+
+  figure(2)
+  clf
+  semilogy(EbNodB, uncoded_awgn_per_theory,'r-+;AWGN Uncoded;','markersize', 10, 'linewidth', 2)
+  hold on;
+  semilogy(EbNodB, uncoded_hf_per_theory,'r-o;HF Uncoded;','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_wimax.PER+1E-10,'g-+;AWGN LDPC (2304,1152);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_wimax.PER+1E-10,'g-o;HF LDPC (2304,1152);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_short.PER+1E-10,'b-+;AWGN LDPC (224,112);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_short.PER+1E-10,'b-o;HF LDPC (224,112);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_wenet.PER+1E-10,'c-+;AWGN LDPC (2576,2064);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_wenet.PER+1E-10,'c-o;HF LDPC (2576,2064);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_awgn_low.PER+1E-10,'k-+;AWGN LDPC (1792,448);','markersize', 10, 'linewidth', 2);
+  semilogy(EbNodB, sim_out_hf_low.PER+1E-10,'k-o;HF LDPC (1792,448);','markersize', 10, 'linewidth', 2);
+   hold off;
+  grid('minor')
+  xlabel('Eb/No (dB)')
+  ylabel('PER')
+  axis([min(EbNodB) max(EbNodB) 1E-2 1])
+  legend('boxoff')
+  legend("location", "southwest");
+  epsname = sprintf("ldpc_qpsk_per.eps");
+  print('-deps', '-color', epsname)
+end
+
+
+% ---------------------------------------------------------------------------------
+% Start simulations here
+% ---------------------------------------------------------------------------------
+
+more off;
+format;
+
+init_cml('/home/david/Desktop/cml/');
+
+%run_single(Nbits=700*5, EbNo=6, hf_en=1, ldpc_code=3, framesize=576*4, 1)
+plot_curves(700*60);
+
+
+
diff --git a/codec2/branches/0.7/octave/ldpc_short.m b/codec2/branches/0.7/octave/ldpc_short.m
new file mode 100644 (file)
index 0000000..38f4545
--- /dev/null
@@ -0,0 +1,558 @@
+% ldpc_short.m\r
+%\r
+% David Rowe Mar 2017\r
+% Based on Bill Cowley's LDPC simulations\r
+%\r
+% Octave simulation of BPSK with short LDPC codes developed by Bill.  First step\r
+% in use of LDPC codes with FreeDV and Codec 2 700C.  BPSK makes life a bits easier\r
+% for simulation\r
+%\r
+% NOTE: You will need to set the CML path in the call to init_cml() below\r
+%       for you CML install.  See lpdc.m for instructions on how to install \r
+%       CML library\r
+\r
+1;\r
+\r
+gp_interleaver;\r
+\r
+function init_cml(path_to_cml)\r
+  currentdir = pwd;\r
+  \r
+  if exist(path_to_cml, 'dir') == 7\r
+    cd(path_to_cml)\r
+    CmlStartup      \r
+    cd(currentdir); \r
+  else\r
+    printf("\n---------------------------------------------------\n");\r
+    printf("Can't start CML in path: %s\n", path_to_cml);\r
+    printf("See CML path instructions at top of this script\n");\r
+    printf("-----------------------------------------------------\n\n");\r
+    assert(0);\r
+  end\r
+end\r
+\r
+\r
+function sim_out = run_sim(sim_in, HRA, Ntrials)\r
+\r
+  rand('seed',1);\r
+  randn('seed',1);\r
+\r
+  % Note this is effective Eb/No of payload data bits, sorta thing we\r
+  % plot on BER versus Eb/No graphs of decoded data.  So if we have a\r
+  % rate 1/2 code, each codeword bit will have Eb/No - 3dB.\r
+\r
+  EbNovec     = sim_in.EbNovec;\r
+\r
+  genie_Es    = sim_in.genie_Es;\r
+  code        = sim_in.code;\r
+  hf_en       = sim_in.hf_en;\r
+  verbose     = sim_in.verbose;\r
+\r
+  if isfield(sim_in, "interleave_en") \r
+    interleave_en = sim_in.interleave_en;\r
+    interleave_frames = sim_in.interleave_frames;\r
+  else\r
+    interleave_en = 0;\r
+    interleave_frames = 1;\r
+  end\r
+\r
+  % default number of carriers for HF model, we fiddle with this a bit\r
+  % for different FEC schemes\r
+\r
+  Nc = 28;\r
+\r
+  % set up for different FEC, get roughly the same frame size so for\r
+  % HF channels the simulation runs over roughly the same time\r
+\r
+  if strcmp(code, 'ldpc')\r
+    [numr numc] = size(HRA);\r
+    rate = (numc-numr)/numc;\r
+    modulation = 'BPSK';\r
+    demod_type = 0;\r
+    decoder_type = 0;\r
+    max_iterations = 100;\r
+    [H_rows, H_cols] = Mat2Hrows(HRA); \r
+    code_param.H_rows = H_rows; \r
+    code_param.H_cols = H_cols;\r
+    code_param.P_matrix = [];\r
+    code_param.data_bits_per_frame = length(code_param.H_cols) - length( code_param.P_matrix ); \r
+    code_param.code_bits_per_frame = numc;\r
+    Ncodewordsperframe = interleave_frames*224/numc;\r
+    framesize = Ncodewordsperframe*numc;\r
+  end\r
+\r
+  if strcmp(code, 'golay')\r
+    rate = 0.5;\r
+    code_param.data_bits_per_frame = 12;\r
+    code_param.code_bits_per_frame = 24;\r
+\r
+    % one Golay (24,12) codeword per row\r
+\r
+    Nc = 24;   \r
+    Ncodewordsperframe = 9;\r
+    framesize = Nc*Ncodewordsperframe;\r
+  end\r
+\r
+  if strcmp(code, 'diversity')\r
+    rate = 0.5;\r
+    code_param.data_bits_per_frame = Nc/2;\r
+    code_param.code_bits_per_frame = Nc;\r
+    Ncodewordsperframe = 8;\r
+    framesize = Nc*Ncodewordsperframe;\r
+  end\r
+\r
+  Rs = 50; Tp = (framesize/Nc)/Rs; Tp_codec2 = 0.04;\r
+\r
+  % we are using BPSK here\r
+\r
+  mod_order = 2; \r
+  bps = code_param.bits_per_symbol = log2(mod_order);\r
+\r
+  % init HF model\r
+\r
+  if hf_en\r
+\r
+    % some typical values, assume symbols spread across Nc OFDM carriers\r
+\r
+    dopplerSpreadHz = 1; path_delay = 1E-3*Rs;\r
+\r
+    nsymb = Ntrials*framesize*bps;\r
+    spread1 = doppler_spread(dopplerSpreadHz, Rs, 1.1*ceil(nsymb/Nc));\r
+    spread2 = doppler_spread(dopplerSpreadHz, Rs, 1.1*ceil(nsymb/Nc));\r
+    hf_gain = 1.0/sqrt(var(spread1)+var(spread2));\r
+    % printf("nsymb: %d lspread1: %d\n", nsymb, length(spread1));\r
+    hf_model = zeros(ceil(nsymb/Nc),Nc);\r
+  end\r
+\r
+  % --------------------------------------------------------------------\r
+  % Sun a simulation for every EbNovec point\r
+  %---------------------------------------------------------------------\r
+\r
+  for ne = 1:length(EbNovec)\r
+\r
+    % Given Eb/No of payload data bits, work out Es/No we need to\r
+    % apply to each codeword symbol, e.g. for rate 1/2 code:\r
+    %\r
+    % Es/No = Eb/No - 3 dB\r
+\r
+    EbNodB = EbNovec(ne);\r
+    EsNodB = EbNodB + 10*log10(code_param.bits_per_symbol*rate);\r
+    EsNo = 10^(EsNodB/10);\r
+\r
+    % reset Hf channel index here so each run gets exactly the same HF channel\r
+\r
+    hf_r = 1;\r
+\r
+    % bunch of counters and logs\r
+\r
+    Terrs = 0;  Tbits = 0;  Ferrs = 0;  Terrs_raw = Tbits_raw = 0;\r
+    r_log = []; Nerrs_log = []; Nerrs_raw_log = [];\r
+    tx_bits_log = rx_bits_log = [];\r
+\r
+    for nn = 1: Ntrials        \r
+\r
+      % Each trial is one complete frame - OK first set up frame to tx\r
+\r
+      codeword = tx_bits = [];\r
+\r
+      if strcmp(code, 'ldpc')\r
+        for f=1:Ncodewordsperframe\r
+          data = round( rand( 1, code_param.data_bits_per_frame ) );\r
+          tx_bits = [tx_bits data];\r
+          codeword = [codeword LdpcEncode(data, code_param.H_rows, code_param.P_matrix) ];\r
+        end\r
+        if interleave_en\r
+          codeword = gp_interleave(codeword);\r
+        end\r
+      end\r
+\r
+      if strcmp(code, 'golay')\r
+        for f=1:Ncodewordsperframe\r
+          data = round( rand( 1, code_param.data_bits_per_frame ) );\r
+          tx_bits = [tx_bits data];\r
+          codeword = [codeword egolayenc(data)];\r
+        end\r
+      end\r
+\r
+      if strcmp(code, 'diversity')\r
+        for f=1:Ncodewordsperframe\r
+          data = round( rand( 1, code_param.data_bits_per_frame ) );\r
+          tx_bits = [tx_bits data];\r
+          codeword = [codeword data data];\r
+        end\r
+      end\r
+\r
+      tx_bits_log = [tx_bits_log tx_bits];\r
+\r
+      Nsymb = code_param.code_bits_per_frame/bps;      \r
+       \r
+      % modulate\r
+\r
+      s = 1 - 2 * codeword;   \r
+      Ns = code_param.symbols_per_frame = length(s);\r
+              \r
+      if hf_en\r
+\r
+        % Simplified rate Rs OFDM simulation model that doesn't\r
+        % include ISI, just freq filtering.  We assume perfect phase\r
+        % estimation so it's just amplitude distortion.  We distribute\r
+        % symbols across Nc carriers\r
+\r
+        Nr = ceil(length(s)/Nc);\r
+        w = (1:Nc)*2*pi;  \r
+        s = [s zeros(1,Nr*Nc-Ns)];  % pad out to integer number of rows\r
+\r
+        for r=1:Nr\r
+          for c=1:Nc\r
+            hf_model(hf_r,c) = hf_gain*(spread1(hf_r) + exp(-j*w(c)*path_delay)*spread2(hf_r));\r
+            s(Nc*(r-1)+c) *= abs(hf_model(hf_r,c));\r
+          end\r
+          hf_r++;\r
+        end\r
+        s = s(1:Ns); % remove padding\r
+      end\r
+      \r
+      variance = 1/(EsNo);\r
+      noise = sqrt(variance/2)*(randn(1,Ns) + j*randn(1,Ns));\r
+      r = s + noise;\r
+\r
+      Nr = length(r);  \r
+      r_log = [r_log r];\r
+\r
+      % raw BER\r
+\r
+      detected_data = real(r) < 0;\r
+      error_positions = xor(detected_data, codeword);\r
+\r
+      Nerrs_raw = sum(error_positions);\r
+      Terrs_raw += Nerrs_raw;\r
+      Tbits_raw += length(codeword);\r
+      Nerrs_raw_log = [Nerrs_raw_log Nerrs_raw];\r
+\r
+      % FEC decoder\r
+\r
+      rx_bits = [];\r
+\r
+      if strcmp(code, 'ldpc')\r
+        if interleave_en\r
+          r = gp_deinterleave(r);\r
+        end\r
+\r
+        % in the binary case the LLRs are just a scaled version of the rx samples ...\r
+        % if the EsNo is known -- use the following \r
+\r
+        if (genie_Es) \r
+         input_decoder_c = 4 * EsNo * r;   \r
+        else\r
+          r = r / mean(abs(r));       % scale for signal unity signal  \r
+         estvar = var(r-sign(r)); \r
+         estEsN0 = 1/(2* estvar); \r
+         input_decoder_c = 4 * estEsN0 * r;\r
+        end\r
+\r
+        for f=1:Ncodewordsperframe\r
+          st = (f-1)*code_param.code_bits_per_frame + 1;\r
+          en = st + code_param.code_bits_per_frame - 1;\r
+          [x_hat, PCcnt] = MpDecode(input_decoder_c(st:en), code_param.H_rows, code_param.H_cols, ...\r
+                                   max_iterations, decoder_type, 1, 1);\r
+          Niters = sum(PCcnt!=0);\r
+          arx_bits = x_hat(Niters,:);\r
+          rx_bits = [rx_bits arx_bits(1:code_param.data_bits_per_frame)];\r
+\r
+          #{\r
+            if isfield(sim_in, "c_include_file") \r
+\r
+            % optionally dump code and unit test data to a C header file\r
+\r
+            code_param.c_include_file = sim_in.c_include_file;\r
+            ldpc_gen_h_file(code_param, max_iterations, decoder_type, input_decoder_c, x_hat, detected_data);\r
+          #}\r
+        end\r
+\r
+        detected_data = detected_data(1:code_param.data_bits_per_frame);\r
+      end\r
+\r
+      if strcmp(code, 'golay')\r
+        for f=1:Ncodewordsperframe\r
+          st = (f-1)*code_param.code_bits_per_frame+1; en=st+code_param.code_bits_per_frame-1;\r
+          arx_codeword = egolaydec(real(r(st:en)) < 0);\r
+          rx_bits = [rx_bits arx_codeword(code_param.data_bits_per_frame+1:code_param.code_bits_per_frame)];\r
+        end\r
+      end\r
+\r
+      if strcmp(code, 'diversity')\r
+        for f=1:Ncodewordsperframe\r
+          st = (f-1)*Nc+1;\r
+          r_combined = r(st:st+Nc/2-1) + r(st+Nc/2:st+Nc-1);\r
+          arx_data = real(r_combined) < 0;\r
+          rx_bits = [rx_bits arx_data];\r
+        end\r
+\r
+        #{\r
+        % simulate low rate code to mop up errors\r
+\r
+        error_positions = xor(rx_bits, tx_bits);\r
+        Nerrs = sum(error_positions);\r
+        if Nerrs < 6\r
+          rx_bits = tx_bits;\r
+        end        \r
+        #}\r
+      end\r
+\r
+      rx_bits_log = [rx_bits_log rx_bits];\r
+\r
+      error_positions = xor(rx_bits, tx_bits);\r
+      Nerrs = sum(error_positions);\r
+      Nerrs_log = [Nerrs_log Nerrs];\r
+      \r
+      if Nerrs>0,  Ferrs += 1;  end\r
+      Terrs = Terrs + Nerrs;\r
+      Tbits = Tbits + code_param.data_bits_per_frame*Ncodewordsperframe;\r
+    end\r
+      \r
+    % Alternative Codec 2 packet rate measurement indep of framesize\r
+\r
+    Nerrs_codec2_log = [];\r
+    Ncodecpacketsize = 28;\r
+    Perrs = 0; Npackets = floor(length(tx_bits_log)/Ncodecpacketsize);\r
+    for p=1:Ncodecpacketsize:Npackets*Ncodecpacketsize\r
+      Nerrs = sum(xor(tx_bits_log(p:p+Ncodecpacketsize-1), rx_bits_log(p:p+Ncodecpacketsize-1)));\r
+      if Nerrs\r
+        Perrs++;\r
+      end\r
+      Nerrs_codec2_log = [Nerrs_codec2_log Nerrs];\r
+    end\r
+\r
+    printf("Coded EbNo: %3.1f dB BER: %5.4f PER: %5.4f Nbits: %4d Nerrs: %4d Tpackets: %4d Perr: %4d\n", \r
+            EbNodB, Terrs/Tbits, Ferrs/ Ntrials, Tbits, Terrs, Ntrials, Ferrs);\r
+    EbNodB_raw = EsNodB - 10*log10(code_param.bits_per_symbol);\r
+    printf("Raw EbNo..: %3.1f dB BER: %5.4f Nbits: %4d Nerrs: %4d\n", EbNodB_raw, \r
+            Terrs_raw/Tbits_raw, Tbits_raw, Terrs_raw);\r
+    printf("Codec 2 PER: %5.4f Npackets: %d Perrs: %d\n", Perrs/Npackets, Npackets, Perrs);\r
+    \r
+    BERvec(ne) = Terrs/Tbits;\r
+    PERvec(ne) = Perrs/Npackets;\r
+\r
+    sim_out.BERvec = BERvec;\r
+    sim_out.PERvec = PERvec;\r
+\r
+    error_positions = xor(tx_bits_log, rx_bits_log);\r
+    sim_out.error_positions = error_positions;\r
+\r
+    if verbose\r
+      figure(3); clf;\r
+      plot(real(r_log),imag(r_log),'+')\r
+      axis([-2 2 -2 2])\r
+      title('Scatter');\r
+\r
+      figure(4); clf;\r
+      subplot(211);\r
+      stem((1:Ntrials)*Tp, Nerrs_raw_log);\r
+      subplot(212);\r
+      stem((1:Npackets)*Tp_codec2, Nerrs_codec2_log);\r
+\r
+      if hf_en\r
+        figure(6); clf;\r
+\r
+        % limit mesh plot to Np points to plot quickly\r
+      \r
+        Np = 500;\r
+        step = ceil(hf_r/Np);\r
+        mesh(1:Nc, (1:step:hf_r-1)/Rs, abs(hf_model(1:step:hf_r-1,:)))\r
+        title('HF channel amplitude');\r
+        xlabel('Carrier');\r
+        ylabel('Time (s)');\r
+      end\r
+\r
+    end\r
+  end\r
+endfunction\r
+\r
+\r
+function plot_curves(Ntrials=100, hf_en=0)\r
+\r
+  if hf_en\r
+    epslabel = 'hf';\r
+  else\r
+    epslabel = 'awgn';\r
+  end\r
+\r
+  sim_in.genie_Es    = 1;\r
+  sim_in.code        = 'ldpc';\r
+  sim_in.hf_en       = hf_en;\r
+  sim_in.verbose     = 0;\r
+\r
+  if hf_en\r
+    EbNovec = 2:0.5:10; \r
+  else\r
+    EbNovec = 0:0.5:8; \r
+  end\r
+  sim_in.EbNovec = EbNovec;\r
+\r
+  load HRA_112_112.txt\r
+  load HRA_112_56.txt\r
+  load HRA_56_56.txt\r
+  load HRA_56_28.txt\r
+\r
+  printf("HRA_112_112-------------\n");\r
+  sim_out1 = run_sim(sim_in, HRA_112_112, Ntrials);\r
+\r
+#{\r
+  printf("HRA_112_56-------------\n");\r
+  sim_out2 = run_sim(sim_in, HRA_112_56 , Ntrials);\r
+#}\r
+\r
+  printf("HRA_56_56-------------\n");\r
+  sim_out3 = run_sim(sim_in, HRA_56_56  , Ntrials*2);\r
+#{\r
+  printf("HRA_56_28-------------\n");\r
+  sim_out4 = run_sim(sim_in, HRA_56_28  , Ntrials*2);\r
+\r
+  printf("Golay -------------\n");\r
+  sim_in.code = 'golay';\r
+  sim_out5 = run_sim(sim_in, [], Ntrials);\r
+  \r
+#}\r
+  printf("Diversity -------------\n");\r
+  sim_in.code = 'diversity';\r
+  sim_out6 = run_sim(sim_in, [], Ntrials);\r
+\r
+  if hf_en\r
+    Ebvec_theory = 2:0.5:12;\r
+    EbNoLin = 10.^(Ebvec_theory/10);\r
+    uncoded_BER_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));\r
+  else\r
+    Ebvec_theory = 0:0.5:8;\r
+    uncoded_BER_theory = 0.5*erfc(sqrt(10.^(Ebvec_theory/10)));\r
+  end\r
+\r
+  % need standard packet size to compare\r
+  % packet error if bit 0, or bit 1, or bit 2 .....\r
+  %              or bit 0 and bit 1\r
+  % no packet error if all bits ok (1-p(0))*(1-p(1))\r
+  % P(packet error) = p(0)+p(1)+....\r
+\r
+  uncoded_PER_theory = 1 - (1-uncoded_BER_theory).^28;\r
+\r
+  figure(1); clf;\r
+  semilogy(Ebvec_theory,  uncoded_BER_theory, 'b+-;BPSK theory;','markersize', 10, 'linewidth', 2)\r
+  hold on;\r
+  semilogy(EbNovec, sim_out1.BERvec, 'g+-;rate 1/2 HRA 112 112;','markersize', 10, 'linewidth', 2)\r
+  %semilogy(EbNovec, sim_out2.BERvec, 'r+-;rate 2/3 HRA 112 56;','markersize', 10, 'linewidth', 2)\r
+  semilogy(EbNovec, sim_out3.BERvec, 'c+-;rate 1/2 HRA 56 56;','markersize', 10, 'linewidth', 2)\r
+  %semilogy(EbNovec, sim_out4.BERvec, 'k+-;rate 2/3 HRA 56 28;','markersize', 10, 'linewidth', 2)\r
+  %semilogy(EbNovec, sim_out5.BERvec, 'm+-;rate 1/2 Golay (24,12);','markersize', 10, 'linewidth', 2)\r
+  semilogy(EbNovec, sim_out6.BERvec, 'go-;rate 1/2 Diversity;','markersize', 10, 'linewidth', 2)\r
+  hold off;\r
+  xlabel('Eb/No')\r
+  ylabel('BER')\r
+  grid\r
+  legend("boxoff");\r
+  axis([min(Ebvec_theory) max(Ebvec_theory) 1E-3 2E-1]);\r
+  epsname = sprintf("ldpc_short_%s_ber.eps", epslabel);\r
+  print('-deps', '-color', epsname)\r
+\r
+  figure(2); clf;\r
+  semilogy(Ebvec_theory,  uncoded_PER_theory, 'b+-;BPSK theory;','markersize', 10, 'linewidth', 2)\r
+  hold on;\r
+  semilogy(EbNovec, sim_out1.PERvec, 'g+-;rate 1/2 HRA 112 112;','markersize', 10, 'linewidth', 2)\r
+  %semilogy(EbNovec, sim_out2.PERvec, 'r+-;rate 2/3 HRA 112 56;','markersize', 10, 'linewidth', 2)\r
+  semilogy(EbNovec, sim_out3.PERvec, 'c+-;rate 1/2 HRA 56 56;','markersize', 10, 'linewidth', 2)\r
+  %semilogy(EbNovec, sim_out4.PERvec, 'k+-;rate 2/3 HRA 56 28;','markersize', 10, 'linewidth', 2)\r
+  %semilogy(EbNovec, sim_out5.PERvec, 'm+-;rate 1/2 Golay (24,12);','markersize', 10, 'linewidth', 2)\r
+  semilogy(EbNovec, sim_out6.PERvec, 'go-;rate 1/2 Diversity;','markersize', 10, 'linewidth', 2)\r
+  hold off;\r
+  xlabel('Eb/No')\r
+  ylabel('PER')\r
+  grid\r
+  legend("boxoff");\r
+  if hf_en\r
+    legend("location", "southwest");\r
+  end\r
+  axis([min(Ebvec_theory) max(Ebvec_theory) 1E-2 1]);\r
+  epsname = sprintf("ldpc_short_%s_per.eps", epslabel);\r
+  print('-deps', '-color', epsname)\r
+endfunction\r
+\r
+\r
+function run_single(bits, code = 'ldpc', channel = 'awgn', EbNodB, interleave=0, error_pattern_filename)\r
+\r
+  sim_in.code = code;\r
+  load HRA_112_112.txt\r
+  HRA = HRA_112_112;\r
+\r
+  sim_in.genie_Es = 1;\r
+\r
+  sim_in.EbNovec = EbNodB;\r
+  if strcmp(channel, 'awgn')\r
+    sim_in.hf_en = 0;\r
+  else\r
+    sim_in.hf_en = 1;\r
+  end\r
+\r
+  if interleave\r
+    sim_in.interleave_en = 1;\r
+    sim_in.interleave_frames = interleave;\r
+  else\r
+    sim_in.interleave_frames = 1;\r
+  end\r
+  Ntrials = floor(bits/(112*sim_in.interleave_frames));\r
+  sim_in.verbose = 1;\r
+  sim_out = run_sim(sim_in, HRA, Ntrials);\r
+\r
+  if nargin == 6\r
+    fep = fopen(error_pattern_filename, "wb");\r
+    fwrite(fep, sim_out.error_positions, "short");\r
+    fclose(fep);\r
+  end\r
+\r
+endfunction\r
+\r
+\r
+% Used to generate C header file for C port\r
+\r
+function run_c_header\r
+\r
+  sim_in.code = 'ldpc';\r
+  load HRA_112_112.txt\r
+  data_bits_per_frame = 112;\r
+  rate = 0.5;\r
+  bits = data_bits_per_frame;\r
+  Ntrials = bits/data_bits_per_frame;\r
+  sim_in.genie_Es    = 1;\r
+  sim_in.hf_en = 0;\r
+  sim_in.Esvec = 2;\r
+  sim_in.c_include_file = "../src/HRA_112_112.h";\r
+\r
+  sim_out = run_sim(sim_in, HRA_112_112, Ntrials);\r
+endfunction\r
+\r
+\r
+% Start simulation here ----------------------------------------------\r
+\r
+% change this path for your CML installation\r
+\r
+init_cml('/home/david/Desktop/cml');\r
+\r
+more off;\r
+format;\r
+\r
+% simple single point test\r
+\r
+run_single(700*60, 'ldpc', 'hf', 6, 32)\r
+\r
+% plotting curves (may take a while)\r
+\r
+%plot_curves(0);\r
+%plot_curves(500,1);\r
+\r
+% generating error files \r
+\r
+%run_single(700*10, 'ldpc', 'awgn', 3, 0, 'awgn_3dB_ldpc.err')\r
+%run_single(700*10, 'diversity', 'awgn', 3, 0, 'awgn_3dB_diversity.err')\r
+%run_single(700*10, 'ldpc', 'hf', 10, 0, 'hf_10dB_ldpc.err')\r
+%run_single(700*10, 'diversity', 'hf', 10, 0, 'hf_10dB_diversity.err')\r
+\r
+% generate C header for C port of code\r
+\r
+%run_c_header\r
diff --git a/codec2/branches/0.7/octave/ldpcdec.m b/codec2/branches/0.7/octave/ldpcdec.m
new file mode 100644 (file)
index 0000000..2607766
--- /dev/null
@@ -0,0 +1,300 @@
+% ldpcdec.m
+% David Rowe 31 Dec 2013
+% 
+% LDPC decoder test program, given a file of QPSK symbols (IQIQ floats), 
+% performs frame sync, decodes, and measures BER.
+
+function ldpcdec(filename, Eprob)
+
+  % Start CML library
+
+  currentdir = pwd;
+  addpath '/home/david/tmp/cml/mat'    % assume the source files stored here
+  cd /home/david/tmp/cml
+  CmlStartup                           % note that this is not in the cml path!
+  cd(currentdir)
+
+  % Our LDPC library
+
+  ldpc;
+
+  % Start simulation
+
+  rand('state',1);
+
+  rate = 3/4; 
+  framesize = 576;  
+
+  mod_order = 4; 
+  modulation = 'QPSK';
+  mapping = 'gray';
+
+  demod_type = 0;
+  decoder_type = 0;
+  max_iterations = 100;
+  EsNo = 4;
+  if (nargin == 1)
+    Eprob = 0.0;
+  end
+
+  nbitspervocoderframe = 52;
+  nvocoderframes = 8;
+  nbitspermodemframe = 72;
+
+  code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);
+  code_param.code_bits_per_frame = 576;
+
+  data = [];
+  r = []; 
+  load interleaver.txt
+  interleaver = interleaver + 1;
+
+  Nframes = 100;
+  uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];
+
+  Nc = 18;
+
+  % repeat same simulated vocoder data to ease testing
+
+  vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) );
+
+  % Decoder: Sync with LDPC frames, de-interleave, LDPC decode, strip off UW, measure BER -------
+
+  mcwfilename = strcat(filename,"_modcodeword.bin");
+  fm=fopen(mcwfilename,"rb");
+  etfilename = strcat(filename,"_modcodeword_et.bin");
+  fet=fopen(etfilename ,"rb");
+  epfilename = strcat(filename,".err");
+  fep=fopen(epfilename ,"wb");
+  printf("Input QPSK symbols: %s\n", mcwfilename);
+  if (fet == -1)
+    printf("Input entered track file: none\n");
+  else
+    printf("Input entered track file: %s\n", etfilename);
+  end
+  printf("Output error pattern file: %s\n", epfilename);
+
+  mod_uw = build_mod_uw(uw, 2*length(vd)/length(uw));
+
+  mod_codeword = zeros(1, code_param.code_bits_per_frame/2);
+  lmod_codeword = code_param.code_bits_per_frame/2;
+
+  Terrs = 0; Trawerrs = 0; Ferrs = 0; Tbits = 0; Tframes = 0; nerr = []; nrawerr = [];
+  corr = []; n = 0;
+  sync_state = 0; sync_count = 0;
+  mod_unpackedmodem_log = [];
+  sync_state_log = [];
+  entered_track_log = [];
+  sig_pwr_log = [];
+
+  symbols = erasures = 0;
+
+  [mod_unpackedmodem_float32, count] = fread(fm,nbitspermodemframe, "float32");
+  if (fet == -1)
+      entered_track = 0;
+  else
+     entered_track = fread(fet, 1, "int");
+  end
+
+  while (count == nbitspermodemframe)
+      n++;
+
+      mod_unpackedmodem = mod_unpackedmodem_float32(1:2:nbitspermodemframe) + j*mod_unpackedmodem_float32(2:2:nbitspermodemframe);
+      mod_unpackedmodem_log = [mod_unpackedmodem_log mod_unpackedmodem];
+      %erasures = rand(1,length(mod_unpackedmodem)) < Eprob; 
+      %mod_unpackedmodem(erasures) = 0;
+
+      % keep buffer of one entire codeword
+
+      mod_codeword(1:lmod_codeword-length(mod_unpackedmodem)) = mod_codeword(length(mod_unpackedmodem)+1:lmod_codeword);
+      mod_codeword(lmod_codeword-length(mod_unpackedmodem)+1:lmod_codeword) = mod_unpackedmodem;
+
+      [uw_sync corr(n)] = look_for_uw(mod_codeword(1:length(mod_uw)), mod_uw);
+
+      next_sync_state = sync_state;
+      if ((sync_state == 0) && (uw_sync == 1))
+        next_sync_state = 1;
+        sync_count = 0;
+      end
+      if ((sync_state == 1) && (entered_track != 0))
+        next_sync_state = 0;
+      end
+      sync_state = next_sync_state;
+      sync_state_log = [sync_state_log sync_state];
+      entered_track_log = [entered_track_log entered_track];
+
+      if (sync_state && (sync_count == 0))
+          Tframes++;
+
+          % remove UW symbols
+
+          mod_codeword_no_uw = remove_uw_symbols(mod_codeword, code_param.data_bits_per_frame/2 - length(uw)/2, length(uw)/2);
+          mod_codeword_no_uw = [mod_codeword_no_uw mod_codeword((code_param.data_bits_per_frame/2+1):code_param.code_bits_per_frame/2)];
+
+          % de-interleave
+
+          tmp = deinterleave_symbols(interleaver, mod_codeword_no_uw);
+        
+          % insert known symbols at end of data
+
+          mod_codeword_deinter = [ tmp(1:(code_param.data_bits_per_frame/2 - length(uw)/2)) ...
+                                 ones(1,length(uw)/2) * qpsk_mod([0 0]) ...
+                                 tmp((code_param.data_bits_per_frame/2 - length(uw)/2+1):length(tmp)) ];
+          % determine BER stats of raw data before decoding
+
+          raw_bits = zeros(1, code_param.data_bits_per_frame - length(uw));
+          for i=1:(code_param.data_bits_per_frame - length(uw))/2
+              raw_bits(2*(i-1)+1:2*i) = qpsk_demod(mod_codeword_deinter(i));
+          end
+          error_positions = xor(vd, raw_bits);
+          Nerrs = sum(error_positions);
+          Trawerrs += Nerrs;
+          nrawerr(Tframes) = Nerrs;
+
+          % Determine Es/N for each carrier. For this codeword we assume
+          % across codeword (currently 320ms) signal is stationary.
+          % So for each carrier signal level is constant, so we can
+          % average across all symols of that carrier to get a better
+          % estimate of the carrier power.  The spectral noise density
+          % No will be the same for the bandwidth of each carrier.  So
+          % we can use noise samples from all symbols together to get
+          % a better estimate of the noise power.
+          
+          sig_pwr(Tframes,:) = zeros(1,Nc);
+          noise_samples = [];
+          for n=1:Nc
+
+            % extract a vector of one carrier's symbols for this codeword
+            % rotate so that decision boundaries are now real and imag axis
+
+            r = mod_codeword(n:Nc:length(mod_codeword)) .* exp(j*pi/4);
+
+            sig_est = mean(abs(r));
+
+            % The noise is the variance of symbols (samples) about the actual symbol position
+            % we reflect all symbols into the first quadrant to simplify things, as the actual
+            % received symbol isn't matter, just the noise around it.  We model the received
+            % symbol based on the estimated signal level.
+
+            refl_symbols = abs(real(r)) + j*abs(imag(r));    
+            est_symbols = exp(j*pi/4)*sig_est*ones(1,length(r));
+            noise_samples = [ noise_samples (est_symbols - refl_symbols)];
+                       
+            sig_pwr(Tframes,n) = sig_est .^ 2;
+          end
+          noise_pwr(Tframes) = var(noise_samples);
+          %plot(real(refl_symbols), imag(refl_symbols), '+');
+          %hold on;
+          %plot(real(exp(j*pi/4)*sig_est*ones(1,length(r))), imag(exp(j*pi/4)*sig_est*ones(1,length(r))), 'r+');
+          %hold off;
+          %printf("SNR: %f\n", 10*log10(sig_est*sig_est/noise_pwr(Tframes)));
+          % Set erasures for carrier beneath a certain Es/N
+          
+          for n=1:Nc
+              symbols++;
+              EsN(n) = 10*log10(sig_pwr(Tframes,n)/noise_pwr(Tframes));
+              if (EsN(n) < 1)
+                 %mod_codeword(n:Nc:length(mod_codeword)) = 0;    
+                 %printf("Tframes: %d n: %d EsN = %3.2fdB\n", Tframes, n, EsN(n)); 
+                 erasures++;                                     
+              end
+          end
+
+          % De-interleave again with erasures set ----------------------
+
+          % remove UW symbols
+
+          mod_codeword_no_uw = remove_uw_symbols(mod_codeword, code_param.data_bits_per_frame/2 - length(uw)/2, length(uw)/2);
+          mod_codeword_no_uw = [mod_codeword_no_uw mod_codeword((code_param.data_bits_per_frame/2+1):code_param.code_bits_per_frame/2)];
+
+          tmp = deinterleave_symbols(interleaver, mod_codeword_no_uw);
+        
+          % insert known symbols at end of data
+
+          mod_codeword_deinter = [ tmp(1:(code_param.data_bits_per_frame/2 - length(uw)/2)) ...
+                                 ones(1,length(uw)/2) * qpsk_mod([0 0]) ...
+                                 tmp((code_param.data_bits_per_frame/2 - length(uw)/2+1):length(tmp)) ];
+
+          % LDPC decode ------------------------------------------------
+
+          detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, mod_codeword_deinter, EsNo);
+
+          % unpack payload data, removing UW
+
+          vd_rx = detected_data(1:(code_param.data_bits_per_frame - length(uw)));
+
+          % measure coded BER
+
+          error_positions = xor(vd, vd_rx);
+          Nerrs = sum(error_positions);
+          if Nerrs>0, fprintf(1,'x'); Ferrs++; ,  else fprintf(1,'.'),  end
+          Tbits += length(vd);
+          Terrs += Nerrs;
+          nerr(Tframes) = Nerrs;
+
+          % save error patterns is simulated vocoder data to disk
+
+          fwrite(fep, error_positions, "short");
+          
+      end
+
+      if (sync_state)
+          sync_count++;
+          if (sync_count == 8)
+              sync_count = 0;
+          end
+      end
+
+      % read in one modulated modem frame at a time
+
+      [mod_unpackedmodem_float32, count] = fread(fm, nbitspermodemframe, "float32");
+      if (fet == -1)
+          entered_track = 0;
+      else
+          entered_track = fread(fet, 1, "int");
+      end
+  end
+
+  fclose(fep);
+
+  printf("\nFrames: %d bits: %d errors: %d Raw BER = %f Coded BER = %f FER = %f\n", Tframes, Tbits, Terrs, Trawerrs/Tbits, Terrs/Tbits, Ferrs/Tframes);
+  printf("Symbols: %d Erasures: %d  %f\n", symbols, erasures, erasures/symbols);
+  figure(8)
+  clf;
+  [n m] = size(mod_unpackedmodem_log);
+  plot( real(mod_unpackedmodem_log), imag(mod_unpackedmodem_log), '+')
+  axis([-2 2 -2 2]);
+  title('Scatter Diagram');
+
+  figure(9)
+  subplot(311)
+  plot(sync_state_log);
+  subplot(312)
+  plot(nrawerr);
+  subplot(313)
+  plot(nerr);
+
+  figure(10);
+  plot(10*log10(sig_pwr(:,3)./noise_pwr(:)),'b');
+  hold on;
+  plot(10+10*log10(noise_pwr(:)));
+  plot(10+10*log10(sig_pwr(:,3)),'r');
+%  for n=2:Nc
+%    plot(n*10+10*log10(sig_pwr(:,n)./noise_pwr(:,n)));
+%    plot(n*10+10*log10(sig_pwr(:,n)),'r');
+%  end
+  hold off;
+
+  y = 1:Tframes;
+  x = 1:Nc;
+  z = 10*log10(sig_pwr(:,:)./((noise_pwr(:)*ones(1, Nc))));
+  %printf("mean SNR = %3.2fdB\n", mean(z));
+  figure(11);
+  imagesc(x,y,z);
+  figure(12);
+  mesh(x,y,z);
+  axis([1 Nc 1 Tframes 5 15]);
+
+endfunction
diff --git a/codec2/branches/0.7/octave/ldpcenc.m b/codec2/branches/0.7/octave/ldpcenc.m
new file mode 100644 (file)
index 0000000..87df284
--- /dev/null
@@ -0,0 +1,125 @@
+% ldpcenc.m
+% David Rowe 20 Dec 2013
+% 
+% LDPC encoder function. Takes a random data pattern, LDPC Encodes and
+% inserts Unique Word (UW) sync bits and ouputs this as a packed
+% binary file suitable for the Nc=18 carrier FDMDV modulator,
+% fdmdv_mod.  Also produces a "modulated" output file of QPSK
+% symbols, suitable for feeding into ldpcdec for testing.
+
+function ldpcenc(filename)
+
+  % Start CML library
+
+  currentdir = pwd;
+  addpath '/home/david/tmp/cml/mat'    % assume the source files stored here
+  cd /home/david/tmp/cml
+  CmlStartup                           % note that this is not in the cml path!
+  cd(currentdir)
+  
+  % Our LDPC library
+
+  ldpc;
+
+  % Start simulation
+
+  rand('state',1);
+
+  rate = 3/4; 
+  framesize = 576;  
+
+  mod_order = 4; 
+  modulation = 'QPSK';
+  mapping = 'gray';
+
+  demod_type = 0;
+  decoder_type = 0;
+  max_iterations = 100;
+
+  nbitspervocoderframe = 52;
+  nvocoderframes = 8;
+  nbitspermodemframe = 72;
+
+  code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);
+
+  data = [];
+  r = []; 
+  load interleaver.txt
+  interleaver = interleaver + 1;
+
+  % Encoder: Generate simulated vocoder data
+  %          LPDC encode
+  %          interleave           
+  %          insert UW bits
+
+  Nframes = 100;
+  uw = [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0];
+
+  % repeat same simulated vocoder data to ease testing
+
+  vd = round( rand( 1, nbitspervocoderframe*nvocoderframes) );
+
+  % pad data with zeros the size of UW
+
+  vdpad = [vd zeros(1, length(uw))];
+
+  % LDPC encode
+
+  [codewordpad, s] = ldpc_enc(vdpad, code_param);
+  code_param.code_bits_per_frame = length(codewordpad);
+  code_param.symbols_per_frame = length(s);
+
+  % remove padded zeros after encoding to leave room for UW bits (code
+  % is systematic)
+
+  codeword = [ codewordpad(1:length(vd)) codewordpad((length(vd)+length(uw)+1):length(codewordpad)) ];
+
+  % interleave, insert UW bits, and pack bits (as C modulator likes packed bits)
+
+  codeword_interleaved = interleave_bits(interleaver, codeword);
+  codeword_interleaved_uw = [insert_uw(codeword_interleaved(1:length(vd)), uw) codeword_interleaved(length(vd)+1:length(codeword_interleaved)) ];
+  packedcodeword = packmsb(codeword_interleaved_uw);
+
+  cwfilename = strcat(filename,"_codeword.bin");
+  fc=fopen(cwfilename,"wb");
+  for nn = 1: Nframes        
+      fwrite(fc,packedcodeword,"uchar");
+  end
+  fclose(fc);
+
+  %printf("framesize: %d data_bits_per_frame: %d code_bits_per_frame: %d\n", ...
+  %        framesize, code_param.data_bits_per_frame,  code_param.code_bits_per_frame);
+
+  printf("Encoded %d LDPC codewords, saved in packed file: %s\n", Nframes, cwfilename);
+
+  % Modulator: Modulate to QPSK symbols ------------------------------------------
+
+  nbytespackedcodeword=length(packedcodeword);
+  fc=fopen(cwfilename,"rb");
+  mcwfilename = strcat(filename,"_modcodeword.bin");
+  fm=fopen(mcwfilename,"wb");
+  nbytespackedmodemframe = nbitspermodemframe/8;
+  n = 0;
+
+  [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar");
+  while (count == nbytespackedmodemframe)
+      n++;
+      unpackedmodem = unpackmsb(packedmodem);
+
+      ii = 1;
+      for i=1:2:length(unpackedmodem)
+          mod_unpackedmodem(ii) = qpsk_mod(unpackedmodem(i:i+1));
+          mod_unpackedmodem_float32(i) = real(mod_unpackedmodem(ii));
+          mod_unpackedmodem_float32(i+1) = imag(mod_unpackedmodem(ii));
+          ii += 1;
+      end
+
+      fwrite(fm, mod_unpackedmodem_float32, "float32");
+      [packedmodem, count] = fread(fc,nbytespackedmodemframe,"uchar");
+  end
+  fclose(fc);
+  fclose(fm);
+  printf("Modulated %d modem frames to file: %s\n", n, mcwfilename);
+endfunction
+
+
diff --git a/codec2/branches/0.7/octave/ldpcut.m b/codec2/branches/0.7/octave/ldpcut.m
new file mode 100644 (file)
index 0000000..cf45bd2
--- /dev/null
@@ -0,0 +1,221 @@
+% ldpcut.m
+%
+% David Rowe 18 Dec 2013
+%
+% Octave LDPC unit test script using CML library, based on simulation
+% by Bill Cowley VK5DSP
+
+% Libraries we need
+
+ldpc;
+qpsk;
+
+function sim_out = run_simulation(sim_in)
+
+  % Note this is effective Eb/No of payload data bits, sorta thing we
+  % plot on BER versus Eb/No graphs of decoded data.  So if we have a
+  % rate 1/2 code, each codeword bit will have Eb/No - 3dB.
+
+  EbNodBvec = sim_in.EbNodBvec;
+
+  framesize = sim_in.framesize;
+  rate = sim_in.rate; 
+  Ntrials = sim_in.Ntrials;
+  verbose = sim_in.verbose;
+
+  % Init LDPC code ------------------------------------
+
+  mod_order = 4; bps = 2;
+  modulation = 'QPSK';
+  mapping = 'gray';
+
+  demod_type = 0;
+  decoder_type = 0;
+  max_iterations = 100;
+
+  code_param = ldpc_init_wimax(rate, framesize, modulation, mod_order, mapping);
+
+  % ----------------------------------
+  % run simulation at each Eb/No point
+  % ----------------------------------
+
+  for ne = 1:length(EbNodBvec)
+    randn('seed',1);
+    rand('seed',1);
+
+    % Given Eb/No of payload data bits, work out Es/No we need to
+    % apply to each channel symbol:
+    %
+    % i) Each codeword bit gets noise: Eb/No - 3 (for a rate 1/2 code)
+    % ii) QPSK means two bits/symbol.: Es/No = Eb/No + 3
+    %
+    % -> which neatly cancel out ...... (at least for rate 1/2)
+
+    EsNodB = EbNodBvec(ne) + 10*log10(rate) + 10*log10(bps);
+    EsNo = 10^(EsNodB/10);
+    variance = 1/EsNo;
+    
+    Tbits = Terrs = Ferrs = Terrs_raw = Tbits_raw = 0;
+    
+    tx_bits = [];
+    tx_symbols = []; 
+    rx_symbols = [];
+
+    % Encode a bunch of frames
+
+    for nn=1:Ntrials        
+      atx_bits = round(rand( 1, code_param.data_bits_per_frame));
+      tx_bits = [tx_bits atx_bits];
+      [tx_codeword atx_symbols] = ldpc_enc(atx_bits, code_param);
+      tx_symbols = [tx_symbols atx_symbols];
+    end
+    
+    rx_symbols = tx_symbols;
+
+    % Add AWGN noise, 0.5 factor splits power evenly between Re & Im
+
+    noise = sqrt(variance*0.5)*(randn(1,length(tx_symbols)) + j*randn(1,length(tx_symbols)));
+    rx_symbols += noise;
+
+    % Decode a bunch of frames
+
+    rx_bits_log = [];
+
+    for nn = 1: Ntrials        
+      st = (nn-1)*code_param.symbols_per_frame + 1;
+      en = (nn)*code_param.symbols_per_frame;
+
+      % coded 
+
+      arx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, rx_symbols(st:en), EsNo);
+      st = (nn-1)*code_param.data_bits_per_frame + 1;
+      en = (nn)*code_param.data_bits_per_frame;
+      error_positions = xor(arx_codeword(1:code_param.data_bits_per_frame), tx_bits(st:en));
+      Nerrs = sum( error_positions);
+      rx_bits_log = [rx_bits_log arx_codeword(1:code_param.data_bits_per_frame)];
+        
+      % uncoded - to est raw BER compare first half or received frame to tx_bits as code is systematic
+      
+      raw_rx_bits = [];
+      for s=1:code_param.symbols_per_frame*rate
+        raw_rx_bits = [raw_rx_bits qpsk_demod(rx_symbols(st+s-1))];
+      end
+      Nerrs_raw = sum(xor(raw_rx_bits, tx_bits(st:en)));
+      Nbits_raw = code_param.data_bits_per_frame;
+
+      if verbose == 2
+        % print "." if frame decoded without errors, 'x' if we can't decode
+
+        if Nerrs > 0, printf('x'),  else printf('.'),  end
+        if (rem(nn, 50)==0),  printf('\n'),  end    
+      end
+
+      if Nerrs > 0,  Ferrs = Ferrs + 1;  end
+      Terrs     += Nerrs;
+      Tbits     += code_param.data_bits_per_frame;        
+      Terrs_raw += Nerrs_raw;
+      Tbits_raw += Nbits_raw;
+    end
+
+    if verbose
+      printf("\nCoded EbNodB: %3.2f BER: %4.3f Tbits: %6d Terrs: %6d FER: %4.3f Tframes: %d Ferrs: %d\n",
+             EsNodB, Terrs/Tbits, Tbits, Terrs,  Ferrs/Ntrials, Ntrials, Ferrs);
+      EbNodB_raw = EbNodBvec(ne) + 10*log10(rate);
+      printf("Raw EbNodB..: %3.2f BER: %4.3f Tbits: %6d Terrs: %6d\n", 
+             EbNodB_raw, Terrs_raw/Tbits_raw, Tbits_raw, Terrs_raw);
+    end
+
+    sim_out.rate = rate;
+    sim_out.BER(ne)   = Terrs/Tbits;
+    sim_out.PER(ne)   = Ferrs/Ntrials;
+  end
+
+endfunction
+
+% --------------------------------------------------------------------------------
+% START SIMULATIONS
+% --------------------------------------------------------------------------------
+
+more off;
+format;
+
+% ---------------------------------------------------------------------------------
+% Start CML library (see CML set up instructions in ldpc.m)
+% ---------------------------------------------------------------------------------
+
+currentdir = pwd;
+addpath '/home/david/Desktop/cml/mat' % assume the source files stored here
+cd /home/david/Desktop/cml
+CmlStartup                            % note that this is not in the cml path!
+cd(currentdir)
+
+
+% ---------------------------------------------------------------------------------
+% 1/ Simplest possible one frame simulation
+% ---------------------------------------------------------------------------------
+
+printf("\nTest 1\n------\n");
+
+mod_order = 4; 
+modulation = 'QPSK';
+mapping = 'gray';
+demod_type = 0;
+decoder_type = 0;
+max_iterations = 100;
+
+framesize = 576*2;       % CML library has a bunch of different framesizes available
+rate = 1/2;
+code_param = ldpc_init_wimax(rate, framesize, modulation, mod_order, mapping);
+
+EsNo = 10;               % decoder needs an estimated channel EsNo (linear ratio, not dB)
+
+tx_bits = round(rand(1, code_param.data_bits_per_frame));
+[tx_codeword, qpsk_symbols] = ldpc_enc(tx_bits, code_param);
+rx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, qpsk_symbols, EsNo);
+
+errors_positions = xor(tx_bits, rx_codeword(1:framesize*rate));
+Nerr = sum(errors_positions);
+printf("Nerr: %d\n\n", Nerr);
+
+
+% ---------------------------------------------------------------------------------
+% 2/ Run a bunch of trials at just one EsNo point
+% ---------------------------------------------------------------------------------
+
+printf("Test 2\n------\n");
+
+% these are inputs for Wimax mode, e.g. framesize defines code used
+
+sim_in.rate = 0.5; 
+sim_in.framesize = 576*4;  % long codes smooth over fades but increase latency
+
+sim_in.verbose = 2;
+sim_in.Ntrials = 100;
+sim_in.EbNodBvec = 9;
+run_simulation(sim_in);
+
+
+% ---------------------------------------------------------------------------------
+% 3/ Lets draw some Eb/No versus BER curves 
+% ---------------------------------------------------------------------------------
+
+printf("\n\nTest 3\n------\n");
+
+sim_in.EbNodBvec = -2:10;
+sim_out = run_simulation(sim_in);
+
+EbNodB = sim_in.EbNodBvec;
+uncoded_awgn_ber_theory = 0.5*erfc(sqrt(10.^(EbNodB/10)));
+
+figure(1)
+clf
+semilogy(EbNodB, uncoded_awgn_ber_theory,'r-+;AWGN;')
+hold on;
+semilogy(EbNodB, sim_out.BER+1E-10,'g-+;AWGN LDPC;');
+hold off;
+grid('minor')
+xlabel('Eb/No (dB)')
+ylabel('BER')
+axis([min(EbNodB) max(EbNodB) 1E-3 1])
+legend('boxoff')
+
diff --git a/codec2/branches/0.7/octave/linreg.m b/codec2/branches/0.7/octave/linreg.m
new file mode 100644 (file)
index 0000000..666b65c
--- /dev/null
@@ -0,0 +1,35 @@
+% linreg.m
+% David Rowe April 2015
+%
+% Based on:
+%    http://stackoverflow.com/questions/5083465/fast-efficient-least-squares-fit-algorithm-in-c
+%
+% finds y = mx + b to best fit n points x and y
+
+function [m b] = linreg(x,y,n)
+  sumx = 0.0;   % sum of x
+  sumx2 = 0.0;  % sum of x^2
+  sumxy = 0.0;  % sum of x * y
+  sumy = 0.0;   % sum of y
+  sumy2 = 0.0;  % sum of y**2
+
+  for i=1:n   
+    sumx  += x(i);       
+    sumx2 += x(i)^2;  
+    sumxy += x(i) * y(i);
+    sumy  += y(i);      
+    sumy2 += y(i)^2; 
+  end 
+
+  denom = (n * sumx2 - sumx*sumx);
+
+  if denom == 0
+    % singular matrix. can't solve the problem.
+    m = 0;
+    b = 0;
+  else
+    m = (n * sumxy  -  sumx * sumy) / denom;
+    b = (sumy * sumx2  -  sumx * sumxy) / denom;
+  end
+
+endfunction
diff --git a/codec2/branches/0.7/octave/load_comp.m b/codec2/branches/0.7/octave/load_comp.m
new file mode 100644 (file)
index 0000000..b9fa686
--- /dev/null
@@ -0,0 +1,9 @@
+% load_comp.m
+% David Rowe Sep 2015
+
+function s = load_comp(fn)
+  fs=fopen(fn,"rb");
+  s = fread(fs,Inf,"float32");
+  ls = length(s);
+  s = s(1:2:ls) + j*s(2:2:ls);
+endfunction
diff --git a/codec2/branches/0.7/octave/load_hackrf.m b/codec2/branches/0.7/octave/load_hackrf.m
new file mode 100644 (file)
index 0000000..85bfb73
--- /dev/null
@@ -0,0 +1,11 @@
+% load_hackrf.m
+%
+% David Rowe Oct 2015
+
+function s = load_hackrf(fn)
+  fs = fopen(fn,"rb");
+  iq = fread(fs,Inf,"schar");
+  fclose(fs);
+  l = length(iq);
+  s =  iq(1:2:l) + j*iq(2:2:l);
+endfunction
diff --git a/codec2/branches/0.7/octave/load_raw.m b/codec2/branches/0.7/octave/load_raw.m
new file mode 100644 (file)
index 0000000..1f7868d
--- /dev/null
@@ -0,0 +1,8 @@
+% load_raw.m
+% David Rowe 7 Oct 2009
+
+function s = load_raw(fn)
+  fs=fopen(fn,"rb");
+  s = fread(fs,Inf,"short");
+  plot(s)
+endfunction
diff --git a/codec2/branches/0.7/octave/lpcauto.m b/codec2/branches/0.7/octave/lpcauto.m
new file mode 100644 (file)
index 0000000..7a5e89e
--- /dev/null
@@ -0,0 +1,116 @@
+function [ar,e,k]=lpcauto(s,p,t)
+%LPCAUTO  performs autocorrelation LPC analysis [AR,E,K]=(S,P,T)
+%  Inputs:
+%     s(ns)   is the input signal
+%         p       is the order (default: 12)
+%         t(nf,3) specifies the frames size details: each row specifies
+%                 up to three values per frame: [len anal skip] where:
+%                         len     is the length of the frame (default: length(s))
+%                         anal    is the analysis length (default: len)
+%                         skip    is the number of samples to skip at the beginning (default: 0)
+%                 If t contains only one row, it will be used repeatedly
+%                 until there are no more samples left in s.
+%
+% Outputs:
+%          ar(nf,p+1) are the AR coefficients with ar(1) = 1
+%          e(nf)      is the energy in the residual.
+%                     sqrt(e) is often called the 'gain' of the filter.
+%          k(nf,2)    gives the first and last sample of the analysis interval
+
+% Notes:
+%
+% (1) The first frame always starts at sample s(1) and the analysis window starts at s(t(1,3)+1).
+% (2) The elements of t need not be integers.
+% (3) The analysis interval is always multiplied by a hamming window
+% (4) As an example, if p=3 and t=[10 5 2], then the illustration below shows
+%     successive frames labelled a, b, c, ... with capitals for the
+%     analysis regions. Note that the first frame starts at s(1)
+%
+%        a a A A A A A a a a b b B B B B B b b b c c C C C C C c c c d ...
+%
+%     For speech processing, it can be advantageous to restrict the analysis regions
+%     to time intervals when the glottis is closed.
+%
+% (5) Frames can overlap: e.g. t=[10 20] will use analysis frames of
+%     length 20 overlapped by 10 samples.
+% (6) For speech processing p should be at least 2*f*l/c where f is the sampling
+%     frequency, l the vocal tract length and c the speed of sound. For a typical
+%     male (l=17 cm) this gives f/1000.
+
+%      Copyright (C) Mike Brookes 1997
+%      Version: $Id: lpcauto.m 713 2011-10-16 14:45:43Z dmb $
+%
+%   VOICEBOX is a MATLAB toolbox for speech processing.
+%   Home page: http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.html
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%   This program is free software; you can redistribute it and/or modify
+%   it under the terms of the GNU General Public License as published by
+%   the Free Software Foundation; either version 2 of the License, or
+%   (at your option) any later version.
+%
+%   This program is distributed in the hope that it will be useful,
+%   but WITHOUT ANY WARRANTY; without even the implied warranty of
+%   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+%   GNU General Public License for more details.
+%
+%   You can obtain a copy of the GNU General Public License from
+%   http://www.gnu.org/copyleft/gpl.html or by writing to
+%   Free Software Foundation, Inc.,675 Mass Ave, Cambridge, MA 02139, USA.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+s = s(:); % make it a column vector
+if nargin < 2 p=12; end;
+if nargin < 3 t=length(s); end;
+%if nargin < 4 w='ham'; end;
+[nf,ng]=size(t);
+if ng<2 t=[t t]; end;
+if ng<3 t=[t zeros(nf,1)]; end;
+if nf==1
+    nf=floor(1+(length(s)-t(2)-t(3))/t(1));
+    tr=0;
+else
+    tr=1;
+end;
+
+ar=zeros(nf,p+1);
+ar(:,1)=1;
+e=zeros(nf,1);
+
+t1=1;
+it=1;
+nw=-1;
+zp=zeros(1,p);
+r=(0:p);
+for jf=1:nf
+    k(jf,1) = ceil(t1+t(it,3));
+    k(jf,2) = ceil(t1+t(it,3)+t(it,2)-1);
+    cs = (k(jf,1):k(jf,2)).';
+    nc = length(cs);
+    pp=min(p,nc);
+    dd=s(cs);
+    if nc~=nw
+        % possibly we should have a window whose square integral equals unity
+        ww=hamming(nc); nw=nc;
+        y=zeros(1,nc+p);
+        c=(1:nc)';
+    end
+    wd=dd(:).*ww;        % windowed data vector
+    y(1:nc)=wd;          % data vector with p appended zeros
+    z=zeros(nc,pp+1);    % data matrix
+    %  was previously  z(:)=y(c(:,ones(1,pp+1))+r(ones(nc,1),1:pp+1));
+    z(:)=y(repmat(c,1,pp+1)+repmat(r,nc,1));
+    rr=wd'*z;
+    rm=toeplitz(rr(1:pp));
+    rk=rank(rm);
+    if rk
+        if rk<pp
+            rm=rm(1:rk,1:rk);
+        end
+        ar(jf,2:rk+1)=-rr(2:rk+1)/rm;
+    end
+    e(jf)=rr*ar(jf,1:pp+1)';
+    t1=t1+t(it,1);
+    it=it+tr;
+end
+
diff --git a/codec2/branches/0.7/octave/lpcpf.m b/codec2/branches/0.7/octave/lpcpf.m
new file mode 100644 (file)
index 0000000..f1e0982
--- /dev/null
@@ -0,0 +1,46 @@
+% lpcpf.m
+% David Rowe Aug 27 2012
+% Experiments with LPC post filtering
+
+function lpcpf(ak_filename, f)
+  aks = load(ak_filename);
+        
+  ak = aks(f,:);
+  [tmp p] = size(ak);
+  p -= 1;
+
+  A = freqz(1,ak, 4000);        
+  AdB = 20*log10(abs(A));
+
+  gamma = 0.5;
+  gammas = gamma .^ (0:p);
+  W = freqz(ak .* gammas,1, 4000);
+  WdB = 20*log10(abs(W));
+
+  beta = 0.2;
+  R = abs(freqz(ak .* gammas, ak, 4000));
+  %P = (R/max(R)) .^ beta;
+  P = R .^ beta;
+  AP = abs(A) .* P;
+
+  eA = sum(abs(A) .^ 2);
+  eAP = sum(AP .^ 2);
+  gain = sqrt(eA/eAP)
+  AP *= gain;
+
+  PdB = 20*log10(P);
+
+  APdB = 20*log10(AP);
+  10*log10(sum(AP .^ 2))/10*log10(sum(abs(A) .^ 2))
+
+  figure(1);
+  clf;
+  plot(AdB);
+  hold on;
+  plot(WdB,'g');
+  plot(PdB,'r');
+  plot(APdB,'b.');
+  hold off;
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/lsp.m b/codec2/branches/0.7/octave/lsp.m
new file mode 100644 (file)
index 0000000..3c8518b
--- /dev/null
@@ -0,0 +1,54 @@
+%
+% Given input AR filter coefficients, this function calculates
+% the corresponding Line spectral pair (LSP) parameters.
+%
+% Author : Madhukar Budagavi
+%
+
+1;
+
+function w=atolsp(a)
+
+  [m,n] = size(a);
+  if m > n
+    a = a';
+  end
+  m = length(a)-1;
+  pz = [a,0] - [0 fliplr(a)];
+  qz = [a,0] + [0 fliplr(a)];
+  angpz = sort(angle(roots(pz)));
+  angpz = angpz(find(angpz > 0));
+  angqz = sort(angle(roots(qz)));
+  angqz = angqz(find(angqz > 0 & angqz < pi));
+  w = zeros(1,m);
+  j = 1:(m/2);
+  w(2*j) = angpz';
+  w(2*j-1) = angqz';
+endfunction
+
+%
+% Given input Line spectral pair (LSP) parameters of an AR filter,
+% this function calculates the corresponding AR filter parameters
+%
+% Author : Madhukar Budagavi
+%
+
+function a=lsptoa(w)
+
+  [m,n] = size(w);
+  if m > n
+    w = w';
+  end
+  m = length(w);
+  pz = 1;
+  qz = 1;
+  for j = 1:(m/2),
+    pz = conv(pz,[1 -2*cos(w(2*j)) 1]);
+    qz = conv(qz,[1 -2*cos(w(2*j-1)) 1]);
+  end
+  pz = conv([1 -1],pz);
+  qz = conv([1 1],qz);
+  a = (pz+qz)/2;
+  a = a(1:(m+1));
+
+endfunction
diff --git a/codec2/branches/0.7/octave/lsp_pdf.m b/codec2/branches/0.7/octave/lsp_pdf.m
new file mode 100644 (file)
index 0000000..4fc1359
--- /dev/null
@@ -0,0 +1,91 @@
+% lsp_pdf.m
+% David Rowe 2 Oct 2009
+% Plots histograms (PDF estimates) of LSP training data
+
+function lsp_pdf(lsp)
+  [r,c] = size(lsp);
+
+  % LSPs
+
+  figure(1);
+  clf;
+  [x,y] = hist(lsp(:,1),100);
+  plot(y*4000/pi,x,"+;1;");
+  hold on;
+  for i=2:5
+    [x,y] = hist(lsp(:,i),100);
+    legend = sprintf("+%d;%d;",i,i);
+    plot(y*4000/pi,x,legend);
+  endfor
+  for i=6:c
+    [x,y] = hist(lsp(:,i),100);
+    legend = sprintf("+%d;%d;",i-5,i);
+    plot(y*4000/pi,x,legend);
+  endfor
+  hold off;
+  grid;
+
+  % LSP differences
+
+  figure(2);
+  clf;
+  subplot(211)
+  [x,y] = hist(lsp(:,1),100);
+  plot(y*4000/pi,x,"1;1;");
+  hold on;
+  for i=2:5
+    [x,y] = hist(lsp(:,i) - lsp(:,i-1),100);
+    legend = sprintf("%d;%d;",i,i);
+    plot(y*4000/pi,x,legend);
+  endfor
+  hold off;
+  grid;
+
+  subplot(212)
+  [x,y] = hist(lsp(:,6)-lsp(:,5),100);
+  plot(y*4000/pi,x,"1;6;");
+  hold on;
+  for i=7:c
+    [x,y] = hist(lsp(:,i) - lsp(:,i-1),100);
+    legend = sprintf("%d;%d;",i-5,i);
+    plot(y*4000/pi,x,legend);
+  endfor
+  hold off;
+  grid;
+
+  % LSP differences delta from last frame
+
+  lspd(:,1) = lsp(:,1);
+  lspd(:,2:10) = lsp(:,2:10) - lsp(:,1:9);
+
+  [m,n] = size(lspd);
+  lspdd = lspd(5:m,:) -  lspd(1:m-4,:);
+  
+  figure(3);
+  clf;
+  subplot(211)
+  for i=1:5
+    [x,y] = hist(lspdd(:,i),100);
+    legend = sprintf("%d;%d;",i,i);
+    plot(y*4000/pi,x,legend);
+    hold on;
+  endfor
+  hold off;
+  grid;
+  axis([-200 200 0 35000]);
+
+  subplot(212)
+  for i=6:10
+    [x,y] = hist(lspdd(:,i),100);
+    legend = sprintf("%d;%d;",i-5,i);
+    plot(y*4000/pi,x,legend);
+    hold on;
+  endfor
+  hold off;
+  grid;
+  axis([-200 200 0 16000]);
+
+  figure(4);
+  clf;
+  plot((4000/pi)*(lsp(2:r,3)-lsp(1:r-1,3)))
+endfunction
diff --git a/codec2/branches/0.7/octave/lspvar.m b/codec2/branches/0.7/octave/lspvar.m
new file mode 100644 (file)
index 0000000..aa4e245
--- /dev/null
@@ -0,0 +1,57 @@
+% lspvar.m
+% David Rowe 8 Feb 2015
+%
+% Experiments in reducing LSP variance in order to make quantisation easier
+
+lsp;
+close all;
+graphics_toolkit ("gnuplot");
+
+function v = det_var(s)
+  p = 10;
+  ak=lpcauto(s,p,[160 80]);
+  [rows cols] = size(ak);
+  w = zeros(rows,p);
+  for r=1:rows
+    w(r,:) = atolsp(ak(r,:));
+  end
+  v = sum(var(w));
+  figure;
+  plot(w)
+end
+
+s=load_raw("../raw/cq_ref.raw");
+det_var(s)
+
+if 1
+ Fs = 8000;
+ [b a] = cheby2(6,40,[300 2600]/(Fs/2));
+ s1 = filter(b,a,s);
+ det_var(s1)
+end
+
+% + Equalise to remove spectral slope, this reduces variance of spectral 
+%   envelope
+% + Can probably get rid of energy for many vectors too, except flat ones?
+% + Or have some sort of correlation of gain with peakiness of vectors?
+% + Once flattened try slicing out low energy harmonics, like post filter.  How 
+%   does this sound?  Any artefacts of harmonics coming and going near 
+%   thresholds?
+% + BPF as well, it's all abt minimal information.
+% + What's left?  Look at it.  How can it be represented?  Look at tol distort,
+%   what quantiser will deliver that?  Just position of clipped peaks?
+% + fall back HF mode, no energy, voicing, just spectral information.  Diveristy
+%   compared to FEC?  Test with simulation of ideal code.  Aux carrier with 
+%   extra information to get 1300-ish quality.  Coherent, pilot assisted demod.
+%   Low PAPR as extra carriers at lower power level.  Essentially for free in
+%   terms of TX power.
+% + What is a viable plan to get this going in a mon month or so?
+%   + Octave equlaisation of input files
+%   + take model files, simulate quantisation, back to C for synth?
+%   + Coherent FDM modem port to C
+
+
+
+
+
+
diff --git a/codec2/branches/0.7/octave/lspwarp.m b/codec2/branches/0.7/octave/lspwarp.m
new file mode 100644 (file)
index 0000000..2d2f2c9
--- /dev/null
@@ -0,0 +1,40 @@
+% lspwarp.m
+% David Rowe Sep 2012
+%
+% Experimenting with non-linear LSP frequency axis for LSP quantisation
+% Plots a scaled mel axis.
+
+1;
+
+function mel = freq2mel(f)
+  mel = 70*log10(1 + f/700);
+endfunction
+
+function freq = mel2freq(m)
+  freq = 700*(10 ^ (m/70) - 1);
+endfunction
+
+x = []; y = [];
+
+for freq = 100:25:4000
+  mel = freq2mel(freq);
+  x = [x freq];
+  y = [y mel];
+end
+
+plot(x,y)
+grid
+
+mel_start = floor(freq2mel(100));
+mel_end = floor(freq2mel(4000));
+
+x = []; y = [];
+for mel=mel_start:mel_end
+  freq = mel2freq(mel);
+  x = [x freq];
+  y = [y mel];
+end
+
+hold on;
+plot(x,y, '+')
+hold off;
diff --git a/codec2/branches/0.7/octave/mag_to_phase.m b/codec2/branches/0.7/octave/mag_to_phase.m
new file mode 100644 (file)
index 0000000..c81ed08
--- /dev/null
@@ -0,0 +1,62 @@
+% mag_to_phase.m
+% 
+% David Rowe Sep 2015
+%
+% Slighly modified version of http://www.dsprelated.com/showcode/20.php
+%
+% Given a magnitude spectrum in dB, returns a minimum-phase phase
+% spectra.  Both must be sampled at a Nfft. My understanding of this
+% is rather dim, but a working example is good place to start!
+
+
+function [phase s] = mag_to_phase(Gdbfk, Nfft = 512, verbose_en = 0)
+
+  Ns = length(Gdbfk); if Ns~=Nfft/2+1, error("confusion"); end
+  Sdb = [Gdbfk,Gdbfk(Ns-1:-1:2)]; % install negative-frequencies
+
+  S = 10 .^ (Sdb/20); % convert to linear magnitude
+  s = ifft(S);        % desired impulse response
+  s = real(s);        % any imaginary part is quantization noise
+  tlerr = 100*norm(s(round(0.9*Ns:1.1*Ns)))/norm(s);
+  if verbose_en
+    disp(sprintf(['  Time-limitedness check: Outer 20%% of impulse ' ...
+               'response is %0.2f %% of total rms'],tlerr));
+  end
+  % = 0.02 percent
+
+  if verbose_en
+    if tlerr>1.0 % arbitrarily set 1% as the upper limit allowed
+      disp('  Increase Nfft and/or smooth Sdb\n');
+    end
+  end
+
+  c = ifft(Sdb); % compute real cepstrum from log magnitude spectrum
+  % Check aliasing of cepstrum (in theory there is always some):
+
+  caliaserr = 100*norm(c(round(Ns*0.9:Ns*1.1)))/norm(c);
+  if verbose_en
+    disp(sprintf(['  Cepstral time-aliasing check: Outer 20%% of ' ...
+                 'cepstrum holds %0.2f %% of total rms\n'],caliaserr));
+  end
+
+  if verbose_en
+    if caliaserr>1.0 % arbitrary limit
+      disp('  Increase Nfft and/or smooth Sdb to shorten cepstrum\n');
+    end
+  end
+
+  % Fold cepstrum to reflect non-min-phase zeros inside unit circle:
+
+  cf = [c(1), c(2:Ns-1)+c(Nfft:-1:Ns+1), c(Ns), zeros(1,Nfft-Ns)];
+
+  Cf = fft(cf); % = dB_magnitude + j * minimum_phase
+
+  % The maths says we are meant to be using log(x), not 20*log10(x),
+  % so we need to scale the phase to account for this:
+  % log(x) = 20*log10(x)/scale;
+
+  scale = (20/log(10));
+  phase = imag(Cf)/scale;
+endfunction
+
diff --git a/codec2/branches/0.7/octave/make_hilb.m b/codec2/branches/0.7/octave/make_hilb.m
new file mode 100644 (file)
index 0000000..35d4e55
--- /dev/null
@@ -0,0 +1,51 @@
+% make_hilb.m
+% David Rowe May 2015
+%
+% creates Hilber Transformer FIR coeffs
+
+graphics_toolkit ("gnuplot");
+
+ht_n = 100;
+imp = [1 zeros(1,ht_n-1)];
+ht_coeff = fftshift(hilbert(imp)) .* hanning(ht_n)';
+
+figure(1)
+subplot(211)
+plot(real(ht_coeff))
+subplot(212)
+plot(imag(ht_coeff))
+
+figure(2)
+plot(20*log10(abs(fft(ht_coeff))))
+
+% test it
+
+n=1:8000;
+w = 2*pi/4;
+x = cos(n*w);
+figure(3)
+y = filter(ht_coeff,1,x);
+figure(3)
+subplot(211)
+plot(y(800:8000))
+subplot(212)
+plot(20*log10(abs(fft(y(800:8000)))))
+
+% save coeffs to a C header file
+
+f=fopen("../src/ht_coeff.h","wt");
+fprintf(f,"/* Hilbert Transform FIR filter coeffs */\n");
+fprintf(f,"/* Generated by make_hilb Octave script */\n");
+
+fprintf(f,"\n#define HT_N %d\n\n", ht_n);
+
+fprintf(f,"COMP ht_coeff[]={\n");
+for r=1:ht_n
+  if r < ht_n
+    fprintf(f, "  {%f,%f},\n",  real(ht_coeff(r)), imag(ht_coeff(r)));
+  else
+    fprintf(f, "  {%f,%f}\n};", real(ht_coeff(r)), imag(ht_coeff(r)));
+  end
+end
+
+fclose(f);
diff --git a/codec2/branches/0.7/octave/make_ssbfilt.m b/codec2/branches/0.7/octave/make_ssbfilt.m
new file mode 100644 (file)
index 0000000..b1bb347
--- /dev/null
@@ -0,0 +1,36 @@
+% make_ssbfilt.m
+% David Rowe May 2015
+%
+% creates SSB filter FIR coeffs
+
+graphics_toolkit ("gnuplot");
+
+ssbfilt_n = 100;
+Fs = 8000;
+
+ssbfilt_coeff  = fir2(ssbfilt_n,[0 400 600 2200 2600 4000]/(Fs/2),[0.001 0.001 1 1 0.001 0.001]);
+
+figure(1)
+clf;
+h = freqz(ssbfilt_coeff,1,Fs/2);
+plot(20*log10(abs(h)))
+grid minor
+
+% save coeffs to a C header file
+
+f=fopen("../src/ssbfilt_coeff.h","wt");
+fprintf(f,"/* 600 - 2600 Hz FIR filter coeffs */\n");
+fprintf(f,"/* Generated by make_ssbfilt Octave script */\n");
+
+fprintf(f,"\n#define SSBFILT_N %d\n\n", ssbfilt_n);
+
+fprintf(f,"float ssbfilt_coeff[]={\n");
+for r=1:ssbfilt_n
+  if r < ssbfilt_n
+    fprintf(f, "  %f,\n",  ssbfilt_coeff(r));
+  else
+    fprintf(f, "  %f\n};", ssbfilt_coeff(r));
+  end
+end
+
+fclose(f);
diff --git a/codec2/branches/0.7/octave/mancyfsk.m b/codec2/branches/0.7/octave/mancyfsk.m
new file mode 100644 (file)
index 0000000..a5ac8cc
--- /dev/null
@@ -0,0 +1,500 @@
+% mancyfsk.m
+% David Rowe October 2015
+%
+% Manchester encoded 2FSK & 4FSK simulation.
+%
+% Attempt to design a FSK waveform that can pass through legacy FM
+% radios but still be optimally demodulated by SDRs. It doesn't have
+% to be optimally demodulated by legacy radios.  Trick is getting it
+% to pass through 300-3000Hz audio filters in legacy radios.
+%
+% [X] code up modulator
+%     [X] manchester two bit symbols
+%     [X] plot spectrum
+% [X] demodulate using analog FM and ideal demods
+% [X] measure BER compared to ideal coherent FSK
+
+1;
+
+fm; % analog FM library
+
+
+function states = legacyfsk_init(M,Rs)
+  Fs = states.Fs = 96000;
+  states.Rs = Rs;                              % symbol rate over channel
+  Ts = states.Ts = Fs/Rs;                      % symbol period in samples
+  states.M  = M;                               % mFSK, either 2 or 4
+  bpsym = state.Rb  = log2(M);                 % bits per symbol over channel
+  rate = states.rate = 0.5;                    % Manchester code rate
+  nbits = 100;
+  nbits = states.nbits = 100;                  % number of payload data symbols/frame
+  nbits2 = states.nbits2 = nbits/rate;         % number of symbols/frame over channel after manchester encoding
+  nsym  = states.nsym = nbits2/log2(M);        % number of symbols per frame
+  nsam = states.nsam = nsym*Ts;
+
+  %printf("  Rs: %d M: %d bpsym: %d nbits: %d nbits2: %d nsym: %d nsam: %d\n", Rs, M, bpsym, nbits, nbits2, nsym, nsam);
+
+  states.fc = states.Fs/4;
+  if states.M == 2
+    states.f(1) = states.fc - Rs/2;
+    states.f(2) = states.fc + Rs/2;
+  else
+    states.f(1) = states.fc - 3*Rs/2;
+    states.f(2) = states.fc - Rs/2;
+    states.f(3) = states.fc + Rs/2;
+    states.f(4) = states.fc + 3*Rs/2;   
+  end
+endfunction
+
+
+% test modulator function
+
+function tx = legacyfsk_mod(states, tx_bits)
+    Fs = states.Fs;
+    Ts = states.Ts;
+    Rs = states.Rs;
+    f  = states.f;
+    M  = states.M;
+    nsym = states.nsym;
+
+    tx = zeros(Ts*length(tx_bits)/log2(M),1);
+    tx_phase = 0;
+
+    step = log2(M);
+    k = 1;
+    for i=1:step:length(tx_bits)
+      if M == 2
+        tone = tx_bits(i) + 1;
+      else
+        tone = (tx_bits(i:i+1) * [2 1]') + 1;
+      end
+      tx_phase_vec = tx_phase + (1:Ts)*2*pi*f(tone)/Fs;
+      tx((k-1)*Ts+1:k*Ts) = 2.0*cos(tx_phase_vec); k++;
+      tx_phase = tx_phase_vec(Ts) - floor(tx_phase_vec(Ts)/(2*pi))*2*pi;
+    end
+   
+endfunction
+
+
+function run_sim(sim_in)
+
+  frames = sim_in.frames;
+  test_frame_mode = sim_in.test_frame_mode;
+  M = sim_in.M;
+  Rs =  sim_in.Rs;
+  demod = sim_in.demod;
+  EbNodB = sim_in.EbNodB;
+  timing_offset = sim_in.timing_offset;
+
+  % rx timing has been adjusted experimentally
+
+  if Rs == 4800
+    if demod == 1
+      rx_timing = 4;
+    else
+      rx_timing = 0;
+    end
+  end
+  if Rs == 2400
+    if demod == 1
+      rx_timing = 40;
+    else
+      rx_timing = 0;
+    end
+  end
+
+  % init fsk modem
+
+  more off
+  rand('state',1); 
+  randn('state',1);
+  states = legacyfsk_init(M,Rs);
+  Fs = states.Fs;
+  nbits = states.nbits;
+  nbits2 = states.nbits2;
+  Ts = states.Ts;
+  nsam = states.nsam;
+  rate = states.rate;
+
+  % init analog FM modem
+
+  fm_states.Fs = Fs;  
+  fm_max = fm_states.fm_max = 3E3;
+  fd = fm_states.fd = 5E3;
+  fm_states.fc = states.fc;
+
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = 1;
+  fm_states.Ts = 1;
+  fm_states.output_filter = 1;
+  fm_states = analog_fm_init(fm_states);
+  [b, a] = cheby1(4, 1, 300/Fs, 'high');   % 300Hz HPF to simulate FM radios
+
+  % init sim states
+
+  rx_bits_buf = zeros(1,2*nbits2);
+  Terrs = Tbits = 0;
+  state = 0;
+  nerr_log = [];
+
+  % set up the channel noise.  We have log(M)*rate payload bits/symbol
+  % we have log2(M) bits/symbol, and rate bits per payload symbol 
+  % TODO: explain this better as Im confused!
+  
+  EbNo = 10^(EbNodB/10);
+  EsNo = EbNo*rate*log2(M);               
+  variance = states.Fs/((states.Rs)*EsNo);  
+  %printf("EbNodB: %3.1f EbNo: %3.2f EsNo: %3.2f\n", EbNodB, EbNo, EsNo);
+
+  % set up the input bits
+
+  if test_frame_mode == 1
+    % test frame of bits, which we repeat for convenience when BER testing
+    test_frame = round(rand(1, nbits));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, nbits*(frames+1)));
+  end
+  if test_frame_mode == 3
+    % ...10101... sequence
+    tx_bits = zeros(1, nbits*(frames+1));
+    tx_bits(1:2:length(tx_bits)) = 1;
+  end
+
+  % Manchester Encoding -----------------------------------------------------------
+
+  % Manchester encoding, which removes DC term in baseband signal,
+  % making the waveform friendly to old-school legacy FM radios with
+  % voiceband filtering.  The "code rate" is 0.5, which means we have
+  % encode one input bit into 2 output bits.  The 2FSK encoder takes
+  % one input bit, the 4FSK encoder two input bits.
+
+  tx_bits_encoded = zeros(1,length(tx_bits)*2);
+  fsk2_enc = [[1 0]; [0 1]];
+  %           -1.5 1.5    1.5 -1.5  -0.5 0.5    0.5 -0.5
+  %              0   3      3   0      1   2      2   1
+  fsk4_enc = [[0 0 1 1]; [1 1 0 0]; [0 1 1 0]; [1 0 0 1]];
+  k=1;
+  if M == 2
+    for i=1:2:length(tx_bits_encoded)
+      input_bit = tx_bits(k); k++;
+      tx_bits_encoded(i:i+1) = fsk2_enc(input_bit+1,:);
+    end
+  else
+    for i=1:4:length(tx_bits_encoded)
+      input_bits = tx_bits(k:k+1) * [2 1]'; k+=2;
+      tx_bits_encoded(i:i+3) = fsk4_enc(input_bits+1,:);
+    end
+  end
+  
+  % FSK Modulator --------------------------------------------------------------
+
+  % use ideal FSK modulator (note: need to try using analog FM modulator)
+
+  tx = legacyfsk_mod(states, tx_bits_encoded);
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise;
+  timing_offset_samples = round(timing_offset*Ts);
+  rx = [zeros(timing_offset_samples,1); rx];
+
+  % Demodulator ----------------------------------------------------------------------------
+
+  if demod == 1
+    % use analog FM demodulator, aka a $40 Baofeng
+
+    [rx_out rx_bb] = analog_fm_demod(fm_states, rx');
+    if sim_in.hpf
+      rx_out_hp = filter(b,a,rx_out);
+    else
+      rx_out_hp = rx_out;
+    end
+    rx_filt = filter(ones(1,Ts),1,rx_out_hp);
+    rx_timing_sig = rx_filt;
+
+    % TODO: for 4FSK determine amplitude/decn boundaries, choose closest to demod each symbol
+
+  end
+
+  if demod == 2
+
+    % optimal non-coherent demod at Rs
+
+    rx_timing_sig = zeros(1,length(rx));
+    for m=1:M
+      phi_vec = (1:length(rx))*2*pi*states.f(m)/Fs;
+      dc = rx' .* exp(-j*phi_vec);
+      rx_filt(m,:) = abs(filter(ones(1,Ts),1,dc));
+      rx_timing_sig = rx_timing_sig + rx_filt(m,1:length(rx));
+    end 
+  end
+
+  % Fine timing estimation ------------------------------------------------------
+
+  % Estimate fine timing using line at Rs/2 that Manchester encoding provides
+  % We need this to sync up to Manchester codewords.  TODO plot signal and 
+  % timing "line" we extract
+  
+  Np = length(rx_timing_sig);
+  w = 2*pi*(Rs)/Fs;
+  x = (rx_timing_sig .^ 2) * exp(-j*w*(0:Np-1))';
+  norm_rx_timing = angle(x)/(2*pi) - 0.42;
+  %rx_timing = round(norm_rx_timing*Ts);
+  %printf("norm_rx_timing: %4.4f rx_timing: %d\n", norm_rx_timing,  rx_timing);
+
+  % Max likelihood decoding of Manchester encoded symbols.  Search
+  % through all ML possibilities to extract bits.  Use energy (filter
+  % output sq)
+
+  % Manchester Decoding --------------------------------------------------------
+
+  if M == 2
+    if demod == 1
+
+      % sample at optimum instant
+
+      [tmp l] = size(rx_filt);
+      rx_filt_dec = rx_filt(:, Ts+rx_timing:Ts:l);
+
+      [tmp l] = size(rx_filt_dec);
+      rx_bits = zeros(1,l);
+      k = 1;
+      for i=1:2:l-1
+        ml = [rx_filt_dec(i)-rx_filt_dec(i+1) -rx_filt_dec(i)+rx_filt_dec(i+1)];
+        [mx mx_ind] = max(ml);
+        rx_bits(k) = mx_ind-1; k++;
+      end
+    end 
+
+    if demod == 2
+
+      % sample at optimum instant
+
+      [tmp l] = size(rx_filt);
+      rx_filt_dec = rx_filt(:, Ts+rx_timing:Ts:l);
+
+      [tmp l] = size(rx_filt_dec);
+      rx_bits = zeros(1,l);
+      k = 1;
+      for i=1:2:l-1
+        %ml = [rx_filt_dec(2,i)*rx_filt_dec(1,i+1) rx_filt_dec(1,i)*rx_filt_dec(2,i+1)];
+        ml = [rx_filt_dec(2,i)+rx_filt_dec(1,i+1) rx_filt_dec(1,i)+rx_filt_dec(2,i+1)];
+        [mx mx_ind] = max(ml);
+        rx_bits(k) = mx_ind-1; k++;
+      end
+    end 
+  else % M == 4
+    if demod == 1
+      % TODO: 4FSK version of demod
+      rx_bits=tx_bits;
+    end
+    if demod == 2
+      % sample at optimal instant
+
+     [tmp l] = size(rx_filt);
+     rx_filt_dec = rx_filt(:, Ts+rx_timing:Ts:l);
+     [tmp l] = size(rx_filt_dec);
+     rx_bits = zeros(1,l);
+
+     k = 1;
+      fsk4_dec = [[0 0]; [0 1]; [1 0]; [1 1]];
+      for i=1:2:l-1
+        %ml = [rx_filt_dec(1,i)*rx_filt_dec(4,i+1) rx_filt_dec(4,i)*rx_filt_dec(1,i+1) rx_filt_dec(2,i)*rx_filt_dec(3,i+1) rx_filt_dec(3,i)*rx_filt_dec(2,i+1)];
+        ml = [(rx_filt_dec(1,i)+rx_filt_dec(4,i+1)) (rx_filt_dec(4,i)+rx_filt_dec(1,i+1)) (rx_filt_dec(2,i)+rx_filt_dec(3,i+1)) (rx_filt_dec(3,i)+rx_filt_dec(2,i+1))];
+        [mx mx_ind] = max(ml);
+        rx_bits(k:k+1) = fsk4_dec(mx_ind,:); k+=2;
+      end
+    end 
+  end
+
+  % useful for getting decoding right
+  %tx_bits(1:20)
+  %rx_bits(1:20)
+
+  % Frame sync and BER logic  -------------------------------------------------------------
+
+  st = 1;
+  for f=1:frames
+
+    % extract nin bits
+
+    nin = nbits;
+    en = st + nin - 1;
+
+    rx_bits_buf(1:nbits) = rx_bits_buf(nbits+1:2*nbits);
+    rx_bits_buf(nbits+1:2*nbits) = rx_bits(st:en);
+
+    st += nin;
+
+    % frame sync based on min BER
+
+    if test_frame_mode == 1
+      nerrs_min = nbits;
+      next_state = state;
+      if state == 0
+        for i=1:nbits
+          error_positions = xor(rx_bits_buf(i:nbits+i-1), test_frame);
+          nerrs = sum(error_positions);
+          %printf("i: %d nerrs: %d nerrs_min: %d \n", i, nerrs, nerrs_min);
+          if nerrs < nerrs_min
+            nerrs_min = nerrs;
+            coarse_offset = i;
+          end
+        end
+        if nerrs_min < 3
+          next_state = 1;
+          %printf("%d %d\n", coarse_offset, nerrs_min);
+        end
+      end
+
+      if state == 1  
+        error_positions = xor(rx_bits_buf(coarse_offset:coarse_offset+nbits-1), test_frame);
+        nerrs = sum(error_positions);
+        Terrs += nerrs;
+        Tbits += nbits;
+        nerr_log = [nerr_log nerrs];
+      end
+
+      state = next_state;
+
+    end 
+  end
+
+  if test_frame_mode == 1
+    if sim_in.verbose
+      printf("  demod: %d frames: %d EbNodB: %3.1f Tbits: %d Terrs: %d BER %4.3f\n", demod, frames, EbNodB, Tbits, Terrs, Terrs/Tbits);
+    else
+      printf("  EbNodB: %3.1f BER %4.3f\n", EbNodB, Terrs/Tbits);
+    end
+  end
+
+  % Bunch O'plots --------------------------------------------------------------
+
+  close all;
+
+  st = 1; en=20;
+
+  Tx=fft(tx, Fs);
+  TxdB = 20*log10(abs(Tx(1:Fs/2)));
+  figure(1)
+  clf;
+  plot(TxdB)
+  axis([1 Fs/2 (max(TxdB)-100) max(TxdB)])
+  title('Tx Spectrum');
+
+  figure(2)
+  clf
+  if demod == 1
+    subplot(211)
+    plot(rx_filt(st*Ts:en*Ts));
+    title('After integrator');
+    subplot(212)
+    plot(rx_filt_dec(st:en),'+');
+    title('Decimated output');
+  end
+  if demod == 2
+    subplot(211);
+    plot(rx_filt(1,st*Ts:en*Ts));
+    hold on;
+    plot(rx_filt(2,st*Ts:en*Ts),'g');
+    if M == 4
+      plot(rx_filt(3,st*Ts:en*Ts),'c');
+      plot(rx_filt(4,st*Ts:en*Ts),'r');          
+    end
+    hold off;
+    title('Output of each filter');
+    subplot(212);
+    plot(rx_filt_dec(1,st:en),'+');
+    hold on;
+    plot(rx_filt_dec(2,st:en),'g+');
+    if M == 4
+      plot(rx_filt_dec(3,st:en),'c+');
+      plot(rx_filt_dec(4,st:en),'r+');          
+    end
+    hold off;
+    title('Decimated output of each filter');
+  end
+
+  figure(3)
+  clf;  
+  subplot(211)
+  plot(rx_timing_sig(st*Ts:en*Ts).^2)
+  title('rx-timing-sig')
+  subplot(212)
+  F = abs(fft(rx_timing_sig(1:Fs)));
+  plot(F(100:8000))
+  title('FFT of rx-timing-sig')
+
+  if demod == 1
+    figure(4);
+    clf;
+    h = fft(rx_out, Fs);
+    hdB = 20*log10(abs(h));
+    plot(hdB(1:4000))
+    title('Spectrum of baseband modem signal after analog FM demod');
+    axis([1 4000 (max(hdB)-40) max(hdB)])
+  end
+  if demod == 1
+    figure(5)
+    clf;
+    subplot(211)
+    plot(rx_out(st*Ts:en*Ts));
+    title('baseband modem signal after analog FM demod');
+    subplot(212)
+    plot(rx_out_hp(st*Ts:en*Ts));
+    title('baseband modem signal after 300Hz filter');
+  end
+end
+
+
+% Run various permutations of simulation here ---------------------------------------
+
+function run_single
+
+  sim_in.frames = 100;
+  sim_in.test_frame_mode = 1;
+  sim_in.M = 2;
+  sim_in.Rs = 2400;
+  sim_in.demod = 1;
+  sim_in.EbNodB = 15;
+  sim_in.timing_offset = 0.0;
+  sim_in.hpf = 1;
+  sim_in.verbose = 1;
+
+  run_sim(sim_in);
+endfunction
+
+
+function run_lots
+
+  % adjusted a few scenarios for about 2% BER so we can compare
+
+  sim_in.frames = 100;
+  sim_in.test_frame_mode = 1;
+  sim_in.M = 2;
+  sim_in.Rs = 4800;
+  sim_in.demod = 1;
+  sim_in.EbNodB = 12;
+  sim_in.timing_offset = 0.0;
+  sim_in.hpf = 1;
+  sim_in.verbose = 0;
+
+  printf("Rs=4800 2FSK ideal demod\n");
+    sim_in.EbNodB = 8.5; sim_in.demod = 2; run_sim(sim_in); 
+  printf("Rs=4800 2FSK analog FM demod, not too shabby and pushes 2400bit/s thru a $40 HT!\n");
+    sim_in.EbNodB = 12; sim_in.demod = 1; run_sim(sim_in); 
+  printf("Rs=2400 2FSK analog FM demod, needs more power for same BER!  Che?\n");
+    sim_in.Rs = 2400; sim_in.EbNodB = 15; run_sim(sim_in);
+  printf("Hmm, doesnt improve with no 300Hz HPF, maybe due to less deviation?\n");
+    sim_in.hpf = 0; run_sim(sim_in);
+  printf("Rs=2400 4FSK ideal demod, nice low Eb/No!\n");
+    sim_in.demod = 2; sim_in.M = 4; sim_in.Rs = 2400; sim_in.EbNodB = 6; run_sim(sim_in);
+endfunction
+
+%run_single;
+run_lots;
diff --git a/codec2/branches/0.7/octave/melstats.m b/codec2/branches/0.7/octave/melstats.m
new file mode 100644 (file)
index 0000000..d373559
--- /dev/null
@@ -0,0 +1,49 @@
+% melstats.m
+% David Rowe April 2015
+% 
+% plots some stats of mel/lsp quantisers
+
+function melstats(filename)
+
+  mel = load(filename);
+  [m n] = size(mel);
+  nbins = 10;
+
+  % histograms of each value
+
+  figure(1)
+  clf
+  subplot(211)
+  [h x] = hist(mel(:,1),nbins);
+  plot(x,h,"1");
+  hold on
+
+  for i=2:n
+    [h x] = hist(mel(:,i),nbins);
+    colour = sprintf("%d",i);
+    plot(x,h,colour);
+  end
+  hold off
+
+  % histograms differences
+
+  subplot(212)
+  [h x] = hist(mel(:,1),nbins);
+  plot(x,h,"1");
+  hold on
+
+  for i=2:n
+    [h x] = hist(mel(:,i)-mel(:,i-1),nbins);
+    colour = sprintf("%d",i);
+    plot(x,h, colour);
+  end
+  hold off
+
+  figure(2)
+  plot(mel(:,1),mel(:,2),'r+')
+  hold on;
+  plot(mel(:,3),mel(:,4),'g+')
+  plot(mel(:,5),mel(:,6),'b+')
+  hold off;
+
+endfunction
diff --git a/codec2/branches/0.7/octave/melvq.m b/codec2/branches/0.7/octave/melvq.m
new file mode 100644 (file)
index 0000000..ca91503
--- /dev/null
@@ -0,0 +1,168 @@
+% melvq.m
+% David Rowe Aug 2015
+%
+% Experimenting with VQ design for mel LSPs
+
+% todo:
+% [ ] Sorting inside search what happens if we get a order issue, fix and calc SD
+% [ ] Search to avoid a worst case error rather than average?  This could be included
+%     in training.
+% [ ] nested/staged search
+
+1;
+
+% train up multi-stage VQ
+% ~/codec2-dev/build_linux/src$ sox -r 8000 -s -2 ../../wav/all.wav -t raw -r 8000 -s -2 - sinc 300 sinc -2600 | ./c2sim - --lpc 6 --lpcpf --lspmel --dump all  -o - | play -t raw -r 8000 -s -2 - vol 3
+%
+% octave:> load ../build_linux/src/all_mel.txt
+% octave:> melvq; vq = trainvq(all_mel, 64, 3);
+% octave:> save vq
+
+function vq = trainvq(training_data, Nvec, stages)
+
+  vq = [];
+  for i=1:stages
+    [idx centers] = kmeans(training_data, Nvec);
+    quant_error = centers(idx,:) - training_data;
+    printf("mse stage %d: %f\n", i, mean(std(quant_error)));
+    training_data = quant_error;
+    vq(:,:,i) = centers;
+  end
+
+end
+
+
+function [mse_list index_list] = search_vq(vq, target, m)
+
+  [Nvec order] = size(vq);
+
+  mse = zeros(1, Nvec);
+  % find mse for each vector
+
+  for i=1:Nvec
+     mse(i) = sum((target - vq(i,:)) .^2);
+  end
+
+  % sort and keep top m matches
+
+  [mse_list index_list ] = sort(mse);
+
+  mse_list = mse_list(1:m);
+  index_list = index_list(1:m);
+
+endfunction
+
+
+% Search multi-stage VQ, retaining m best candidates at each stage
+
+function [res output_vecs ind] = mbest(vqset, input_vecs, m)
+
+  [Nvec order stages] = size(vqset);
+  [Ninput tmp] = size(input_vecs);
+
+  res = [];         % residual error after VQ
+  output_vecs = []; % quantised ouput vectors
+  ind = [];         % index of vqs
+  
+  for i=1:Ninput
+  
+    % first stage, find mbest candidates
+
+    [mse_list index_list] = search_vq(vqset(:,:,1), input_vecs(i,:), m);
+    cand_list = [mse_list' index_list'];
+    cand_list = sortrows(cand_list,1);
+
+    % subsequent stages ...........
+
+    for s=2:stages
+
+      % compute m targets for next stage, and update path
+
+      prev_indexes = zeros(m,s-1);
+      for t=1:m
+        target(t,:) = input_vecs(i,:);
+        for v=1:s-1
+          target(t,:) -= vqset(cand_list(t,v+1),:,v);
+        end
+        prev_indexes(t,:) = cand_list(t,2:s);
+      end
+      
+      % search stage s using m targets from stage s-1
+      % with m targets, we do m searches which return the m best possibilities
+      % so we get a matrix with one row per candidate, m*m rows total
+      % prev_indexes provides us with the path through the VQs for each candidate row
+
+      avq = vqset(:,:,s);
+      cand_list = [];
+      for t=1:m
+        [mse_list index_list] = search_vq(avq, target(t,:), m);
+        x = ones(m,1)*prev_indexes(t,:);
+        cand_row = [mse_list' x index_list'];
+        cand_list = [cand_list; cand_row];
+      end
+
+      % sort into m best rows
+     
+      cand_list = sortrows(cand_list,1);
+      cand_list = cand_list(1:m,:);
+
+    end
+
+    % final residual
+    target(1,:) = input_vecs(i,:);
+    out = zeros(1,order);
+    for v=1:stages
+      target(1,:) -= vqset(cand_list(1,v+1),:,v);
+      out += vqset(cand_list(1,v+1),:,v);
+    end
+    res  = [res; target(1,:)];
+    output_vecs  = [output_vecs; out];
+    ind  = [ind; cand_list(1,2:1+stages)];
+  end
+
+endfunction
+
+
+% Quantises a set of mel-lsps and saves back to disk so they can be read in by c2sim
+% assumes we have a vq saved to disk called vq
+%
+% ~/codec2-dev/build_linux/src$ sox -r 8000 -s -2 ../../wav/vk5qi.wav -t raw -r 8000 -s -2 - sinc 300 sinc -2600 | ./c2sim - --lpc 6 --lpcpf --lspmel --dump vk5qi  -o - | play -t raw -r 8000 -s -2 - vol 3
+%
+% octave:> test_run("vk5qi")
+%
+% ~/codec2-dev/build_linux/src$ sox -r 8000 -s -2 ../../wav/vk5qi.wav -t raw -r 8000 -s -2 - sinc 300 sinc -2600 | ./c2sim - --lpc 6 --lpcpf --phase0 --dec 4 --postfilter --lspmel --lspmelread ../../octave/vk5qi_mel_.out -o - | play -t raw -r 8000 -s -2 - vol 3
+
+function ind = test_run(samplename)
+
+  more off;
+  input_vecs_name = sprintf("../build_linux/src/%s_mel.txt", samplename);
+  input_vecs_name
+  mel = load(input_vecs_name);
+  load vq;
+  [res mel_ ind] = mbest(vq, mel, 5);
+  mean(std(res))
+
+  output_vecs_name = sprintf("%s_mel_.out", samplename);
+  fmel_ = fopen(output_vecs_name,"wb"); 
+  [r c] = size(mel_);
+  for i=1:r
+    fwrite(fmel_, mel_(i,:), "float32"); 
+  end
+  fclose(fmel_);
+end
+
+%ind = test_run("hts1a");
+
+%load "../build_linux/src/all_mel.txt"
+%vq = trainvq(all_mel, 64, 3);
+%save vq;
+
+% [X] save text file of "vq quantised mels"
+% [X] load back into c2sim at run time
+% [X] train on continuous mels
+% [X] sorting/stability
+% [X] see how it sounds
+% [X] Goal is to get VQ sounding OK, similar to UQ at 20 or 40ms dec,
+% [X] sig better than current 700
+% [X] check all indexes used with hist
diff --git a/codec2/branches/0.7/octave/mfsk.m b/codec2/branches/0.7/octave/mfsk.m
new file mode 100644 (file)
index 0000000..0414b5e
--- /dev/null
@@ -0,0 +1,199 @@
+% mfsk.m
+% David Rowe Nov 2015
+
+% Simulation to test m=2 and m=4 FSK demod
+
+
+1;
+
+function sim_out = fsk_ber_test(sim_in)
+  Fs        = 96000;
+  M         = sim_in.M;
+  Rs        = sim_in.Rs;
+  Ts        = Fs/Rs;
+  verbose   = sim_in.verbose;
+
+  nbits     = sim_in.nbits;
+  nsym      = sim_in.nbits*2/M;
+  nsam      = nsym*Ts;
+  EsNodB    = sim_in.EbNodB + 10*log10(M/2);
+
+  % printf("M: %d nbits: %d nsym: %d\n", M, nbits, nsym);
+
+  if M == 2
+    f(1) = -Rs/2;
+    f(2) =  Rs/2;
+  end
+  if M == 4
+    f(1) = -3*Rs/2;
+    f(2) = -Rs/2;
+    f(3) =  Rs/2;
+    f(4) =  3*Rs/2;
+  end
+
+  % simulate over a range of Eb/No values
+
+  for ne = 1:length(EsNodB)
+    Nerrs = Terrs = Tbits = 0;
+
+    aEsNodB = EsNodB(ne);
+    EsNo = 10^(aEsNodB/10);
+    variance = Fs/(Rs*EsNo);
+
+    % Modulator -------------------------------
+
+    tx_bits = round(rand(1, nbits));
+    tx = zeros(1,nsam);
+    tx_phase = 0;
+
+    for i=1:nsym
+      if M == 2
+        tone = tx_bits(i) + 1;
+      else
+        tone = (tx_bits(2*(i-1)+1:2*i) * [2 1]') + 1;
+      end
+
+      tx_phase_vec = tx_phase + (1:Ts)*2*pi*f(tone)/Fs;
+      tx((i-1)*Ts+1:i*Ts) = exp(j*tx_phase_vec);
+      tx_phase = tx_phase_vec(Ts) - floor(tx_phase_vec(Ts)/(2*pi))*2*pi;
+    end
+  
+    % Channel ---------------------------------
+
+    % We use complex (single sided) channel simulation, as it's convenient
+    % for the FM simulation.
+
+    noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+    rx    = tx + noise;
+    if verbose > 1
+      printf("EbNo: %f Eb: %f var No: %f EbNo (meas): %f\n", 
+      EbNo, var(tx)*Ts/Fs, var(noise)/Fs, (var(tx)*Ts/Fs)/(var(noise)/Fs));
+    end
+    % Demodulator -----------------------------
+
+    % non-coherent FSK demod
+
+    rx_bb = rx;
+    dc = zeros(M,nsam);
+    for m=1:M
+      dc(m,:) = rx_bb .* exp(-j*(0:nsam-1)*2*pi*f(m)/Fs);
+    end
+
+    rx_bits = zeros(1, nsym);
+    for i=1:nsym
+      st = (i-1)*Ts+1;
+      en = st+Ts-1;
+      for m=1:M
+        int(m,i) = abs(sum(dc(m,st:en)));
+      end
+      if m == 2
+        rx_bits(i) = int(1,i) < int(2,i);
+      else
+        [max_amp tone] = max([int(1,i) int(2,i) int(3,i) int(4,i)]);
+        if tone == 1
+          rx_bits(2*(i-1)+1:2*i) = [0 0];
+        end
+        if tone == 2
+          rx_bits(2*(i-1)+1:2*i) = [0 1];
+        end
+        if tone == 3
+          rx_bits(2*(i-1)+1:2*i) = [1 0];
+        end
+        if tone == 4
+          rx_bits(2*(i-1)+1:2*i) = [1 1];
+        end
+     end
+    end
+  
+    error_positions = xor(rx_bits, tx_bits);
+    Nerrs = sum(error_positions);
+    Terrs += Nerrs;
+    Tbits += length(error_positions);
+
+    TERvec(ne) = Terrs;
+    BERvec(ne) = Terrs/Tbits;
+
+    if verbose > 1
+      figure(2)
+      clf
+      Rx = 10*log10(abs(fft(rx)));
+      plot(Rx(1:Fs/2));
+      axis([1 Fs/2 0 50]);
+
+      figure(3)
+      clf;
+      subplot(211)
+      plot(real(rx_bb(1:Ts*20)))
+      subplot(212)
+      Rx_bb = 10*log10(abs(fft(rx_bb)));
+      plot(Rx_bb(1:3000));
+      axis([1 3000 0 50]);
+
+      figure(4);
+      subplot(211)
+      stem(abs(mark_int(1:100)));
+      subplot(212)
+      stem(abs(space_int(1:100)));   
+    end
+
+    if verbose
+      printf("EbNo (db): %3.2f Terrs: %d BER: %4.3f \n", aEsNodB - 10*log10(M/2), Terrs, Terrs/Tbits);
+    end
+  end
+
+  sim_out.TERvec = TERvec;
+  sim_out.BERvec = BERvec;
+endfunction
+
+
+function run_fsk_curves
+  sim_in.M         = 2;
+  sim_in.Rs        = 1200;
+  sim_in.nbits     = 12000;
+  sim_in.EbNodB    = 0:2:20;
+  sim_in.verbose   = 1;
+  
+  EbNo  = 10 .^ (sim_in.EbNodB/10);
+  fsk_theory.BERvec = 0.5*exp(-EbNo/2); % non-coherent BFSK demod
+  fsk2_sim = fsk_ber_test(sim_in);
+
+  sim_in.M = 4;
+  fsk4_sim = fsk_ber_test(sim_in);
+
+  % BER v Eb/No curves
+
+  figure(1); 
+  clf;
+  semilogy(sim_in.EbNodB, fsk_theory.BERvec,'r;2FSK theory;')
+  hold on;
+  semilogy(sim_in.EbNodB, fsk2_sim.BERvec,'g;2FSK sim;')
+  semilogy(sim_in.EbNodB, fsk4_sim.BERvec,'b;4FSK sim;')
+  hold off;
+  grid("minor");
+  axis([min(sim_in.EbNodB) max(sim_in.EbNodB) 1E-4 1])
+  legend("boxoff");
+  xlabel("Eb/No (dB)");
+  ylabel("Bit Error Rate (BER)")
+
+end
+
+
+function run_fsk_single
+  sim_in.M         = 4;
+  sim_in.Rs        = 1200;
+  sim_in.nbits     = 5000;
+  sim_in.EbNodB    = 8;
+  sim_in.verbose   = 1;
+
+  fsk_sim = fsk_ber_test(sim_in);
+endfunction
+
+
+rand('state',1); 
+randn('state',1);
+graphics_toolkit ("gnuplot");
+
+run_fsk_curves
+%run_fsk_single
+
diff --git a/codec2/branches/0.7/octave/newamp.m b/codec2/branches/0.7/octave/newamp.m
new file mode 100644 (file)
index 0000000..805282b
--- /dev/null
@@ -0,0 +1,1691 @@
+% newamp.m
+%
+% Copyright David Rowe 2015
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Library of Octave functions to explore new ideas in amplitude
+% (spectral envelope) modelling.  See newamp_fby (frame by frame
+% analysis) and newamp_batch (batch processing for listening tests)
+%
+% Code here to support a bunch of experimental ideas, many that didn't work out.
+
+1;
+melvq; % mbest VQ functions
+
+% --------------------------------------------------------------------------------
+% Functions used by rate K mel work
+% --------------------------------------------------------------------------------
+
+% General 2nd order parabolic interpolator.  Used splines orginally,
+% but this is much simpler and we don't need much accuracy.  Given two
+% vectors of points xp and yp, find interpolated values y at points x
+%
+
+% If a point in x is less than the smallest point in xp, we linearly
+% interpolate down to (0,0).  If a point in x is greater than the
+% greatest value in xp, we linearly interpolate down to (xp_max, 0)
+
+function y = interp_para(xp, yp, xp_max, x)
+  assert( (length(xp) >=3) && (length(yp) >= 3) );
+
+  y = zeros(1,length(x));
+  k = 1;
+  for i=1:length(x)
+    xi = x(i);
+
+    % k is index into xp of where we start 3 points used to form parabola
+
+    while (xp(k) < xi) && (k < length(xp)) 
+      k++;
+    end
+    
+    %printf("xi: %f k = %d\n", xi, k);
+    if k == 1
+      % linear interpolation at low end
+      x1 = 0; y1 = 0;
+      x2 = xp(k); y2 = yp(k); 
+      b = (y2-y1)/(x2-x1);
+      y(i) = b*(xi-x2) + y2;
+      %printf("lin1 k: %d i: %d xi: %f x1: %f y1: %f\n", k, i, xi, x1, y1);
+    elseif k < length(xp)
+      % parabolic interpolation
+      x1 = xp(k-1); y1 = yp(k-1); 
+      x2 = xp(k); y2 = yp(k); 
+      x3 = xp(k+1); y3 = yp(k+1);
+      a = ((y3-y2)/(x3-x2)-(y2-y1)/(x2-x1))/(x3-x1);
+      b = ((y3-y2)/(x3-x2)*(x2-x1)+(y2-y1)/(x2-x1)*(x3-x2))/(x3-x1);
+      y(i) = a*(xi-x2)^2 + b*(xi-x2) + y2;
+      %printf("para1 k: %d i: %d xi: %f x1: %f y1: %f\n", k, i, xi, x1, y1);
+    elseif (k == length(xp)) && (xi < xp(k))
+      % parabolic interpolation, but shift xp points back by 1
+      x1 = xp(k-2); y1 = yp(k-2); 
+      x2 = xp(k-1); y2 = yp(k-1); 
+      x3 = xp(k); y3 = yp(k);
+      a = ((y3-y2)/(x3-x2)-(y2-y1)/(x2-x1))/(x3-x1);
+      b = ((y3-y2)/(x3-x2)*(x2-x1)+(y2-y1)/(x2-x1)*(x3-x2))/(x3-x1);
+      y(i) = a*(xi-x2)^2 + b*(xi-x2) + y2;
+      %printf("para2 k: %d i: %d xi: %f x1: %f y1: %f\n", k, i, xi, x1, y1);
+    elseif k == length(xp)
+      % linear interpolation at high end
+      x1 = xp(k); y1 = yp(k); 
+      x2 = xp_max; y2 = 0;
+      b = (y2-y1)/(x2-x1);
+      y(i) = b*(xi-x1) + y1;
+      %printf("lin2 k: %d i: %d xi: %f x1: %f y1: %f\n", k, i, xi, x1, y1);
+    end
+
+  end
+endfunction
+
+
+% choose largest sample in band, idea is we care more about finding
+% peaks, can handle some error in frequency. x are non linear
+% (arbitrary) sampling points in kHz
+
+function y = interp_largest(f0_Hz, AmdB, x_kHz)
+  L = length(AmdB);
+  x = x_kHz*1000;
+  y = zeros(1,length(x));
+  bw = x(2) - x(1);
+  k = 1;
+
+  for i=1:length(x)
+
+    % determine limits of this band
+
+    if i>1
+      bw = x(i) - x(i-1);
+    end
+    band_low = x(i) - bw/2; band_high = x(i) + bw/2;
+
+    % map band limits to harmonics    
+    if x(i) < f0_Hz
+      m_low = m_high = 1;
+    else
+      m_low = round(band_low/f0_Hz); m_high = round(band_high/f0_Hz)-1;
+      m_low = max(1, m_low); m_high = min(L, m_high); m_high = max(m_low, m_high);
+    end
+
+    printf("L: %d f0: %f i: %d band_low: %f band_high: %f m_low: %d m_high: %d\n",L, f0_Hz, i, band_low, band_high, m_low, m_high);
+    % find max in band
+
+    y(i) = max(AmdB(m_low:m_high));
+  end
+
+endfunction
+
+% simple linear interpolator
+
+function y = interp_linear(xp, yp, x)
+  assert( (length(xp) == 2) && (length(yp) == 2) );
+
+  m = (yp(2) - yp(1))/(xp(2) - xp(1));
+  c = yp(1) - m*xp(1);
+
+  y = zeros(1,length(x));
+  for i=1:length(x)
+    y(i) = m*x(i) + c;
+  end
+endfunction
+
+
+% quantise input sample to nearest value in table, optionally return binary code
+
+function [quant_out best_i bits] = quantise(levels, quant_in)
+
+  % find closest quantiser level
+
+  best_se = 1E32;
+  for i=1:length(levels)
+    se = (levels(i) - quant_in)^2;
+    if se < best_se
+      quant_out = levels(i);
+      best_se = se;
+      best_i = i;
+    end
+  end
+
+  % convert index to binary bits
+
+  numbits = ceil(log2(length(levels)));
+  bits = zeros(1, numbits);
+  for b=1:numbits
+    bits(b) = bitand(best_i-1,2^(numbits-b)) != 0;
+  end
+
+endfunction
+
+
+% Quantisation functions for Wo in log freq domain
+
+function index = encode_log_Wo(Wo, bits)
+    Wo_levels = 2.^bits;
+    Wo_min = 2*pi/160;
+    Wo_max = 2*pi/20;
+
+    norm = (log10(Wo) - log10(Wo_min))/(log10(Wo_max) - log10(Wo_min));
+    index = floor(Wo_levels * norm + 0.5);
+    index = max(index, 0);
+    index = min(index, Wo_levels-1);
+endfunction
+
+
+function Wo = decode_log_Wo(index, bits)
+    Wo_levels = 2.^bits;
+    Wo_min = 2*pi/160;
+    Wo_max = 2*pi/20;
+
+    step = (log10(Wo_max) - log10(Wo_min))/Wo_levels;
+    Wo   = log10(Wo_min) + step*index;
+
+    Wo = 10 .^ Wo;
+endfunction
+
+
+% convert index to binary bits
+
+function bits = index_to_bits(value, numbits)
+  levels = 2.^numbits;
+  bits = zeros(1, numbits);
+  for b=1:numbits
+    bits(b) = bitand(value,2^(numbits-b)) != 0;
+  end
+end
+
+
+function value = bits_to_index(bits, numbits)
+  value = 2.^(numbits-1:-1:0) * bits;
+endfunction
+
+
+% generate a zig-zag linear to square mapping matrix
+
+function map = create_zigzag_map(nr,nc)
+  map = zeros(nr, nc);
+
+  state = 'zig';
+  r = c = 1;
+
+  for i=1:nr*nc
+
+    printf("%s r: %d c: %d i %d\n", state, r, c, i);
+    map(r,c) = i;
+
+    next_state = state;
+    if state == 'zig'
+      % move SE
+      c -= 1; r += 1;
+      if r > nr
+        r = nr; c+=2;
+        next_state = 'zag';
+      end
+      if c < 1
+        c = 1;
+        next_state = 'zag';
+      end
+    end
+
+    if state == 'zag'
+      % move SE
+      r -= 1; c +=1;
+      if c > nc
+        c = nc; r+=2;
+        next_state = 'zig';
+      end
+      if r < 1
+        r = 1;
+        next_state = 'zig';
+      end
+    end
+    state = next_state;
+  end
+endfunction
+
+
+% reshape matrix m as a vector v by reading out elements in zig-zag pattern
+
+function v = mtov_zigzag(m)
+  [nr nc] = size(m);
+  map = zigzag(nr,nc)
+  v = zeros(1,nr*nc);
+  for r=1:nr
+    for c=1:nc
+      v(map(r,c)) = m(r,c);
+    end
+  end
+endfunction
+
+
+% extracts DCT information for rate K surface
+
+function unwrapped_dcts = dct_blocks(surf, Nt=16)
+  [frames K] = size(surf);
+
+  % break into 160ms blocks, 2D DCT, truncate, IDCT
+
+  Nblocks = floor(frames/Nt);
+  unwrapped_dcts = zeros(Nblocks,Nt*K);
+
+  for n=1:Nblocks
+    st = (n-1)*Nt+1; en = st + Nt - 1;
+    D = dct2(surf(st:en,:));
+    unwrapped_dcts(n,:) = reshape(D',1,Nt*K);
+  end
+endfunction
+
+
+% Determines a map for quantising 2D DCT coeffs in order of rms value
+% (ie std dev) of each coeff.  Those coeffs with the greatest change
+% need the most bits to quantise
+
+function [map rms_map mx mx_ind unwrapped_dcts] = create_map_rms(rate_K_surface, nr, nc)
+  unwrapped_dcts = dct_blocks(rate_K_surface, nr);
+  [mx mx_ind] = sort(std(unwrapped_dcts));
+  mx_ind = fliplr(mx_ind); mx = fliplr(mx);
+  map = rms_map = zeros(nr,nc);
+  for i=1:nr*nc
+    r = floor((mx_ind(i)-1)/nc) + 1;
+    c = mx_ind(i) - (r-1)*nc;
+    %printf("%d %d %d\n", i, r, c);
+    map(r,c) = i;
+    rms_map(r,c) = mx(i);
+  end
+endfunction
+
+
+% plot histogram of each 2D DCT coeff, so we can get a feel for
+% quantiser design
+
+function plot_dct2_hists(rate_K_surface, nr, nc)
+  [map rms_map mx mx_ind unwrapped_dcts] = create_map_rms(rate_K_surface, nr, nc);
+  Ncoeff = nr*nc;
+  fign = 1; subplotn = 1;
+  close all; figure(fign); clf;
+  Nplot = 60;
+  for i=1:Nplot   
+    subplot(5,4,subplotn);
+    d = unwrapped_dcts(:,mx_ind(i));
+    d = round(d/4);
+    hist(d);
+    subplotn++;
+    if (subplotn > 20) && (i != Nplot)
+      subplotn = 1;
+      fign++;
+      figure(fign); clf;
+    end
+  end
+endfunction
+
+
+% Gather run length data for each 2D DCT coeff, to see if run length encoding
+% can help
+
+function [run_length d]= plot_run_length(rate_K_surface, nr, nc)
+  [map rms_map mx mx_ind unwrapped_dcts] = create_map_rms(rate_K_surface, nr, nc);
+  Ncoeff = nr*nc;
+  [Nblocks tmp] = size(unwrapped_dcts);
+
+  % first get histogram of DCT values -----------------------------------
+
+  % some mild quantisation
+
+  unwrapped_dcts = round(unwrapped_dcts/4);
+
+  % note we only consider first half of DCT coeffs, unlikely to use all 
+
+  d = [];
+  for i=1:Nblocks
+    d = [d unwrapped_dcts(i,mx_ind(1:Ncoeff/2))]; 
+  end
+
+  % note we remove outliers from plot as very low prob symbols
+
+  d = d(find(abs(d)<10));
+  figure(1); clf; [Wi, ii] = hist(d,-10:10,1); plot(ii,Wi);
+  length(d)
+  Wi = Wi(find(Wi > 0));
+  %sum(Wi)
+  %-log2(Wi)
+  %-Wi .* log2(Wi)
+  printf("bits/symbol: %2.2f\n", sum(-Wi .* log2(Wi)));
+
+  % now measure run lengths --------------------------------------------
+  
+  run_length = zeros(21,Ncoeff);
+  state = 'idle';
+
+  for i=2:length(d)
+
+    next_state = state;
+
+    if state == 'idle'
+      if d(i-1) == d(i)
+        next_state = 'trac';
+        arun_length = 2;
+      else
+        run_length(d(i)+10, 1)++;
+      end
+    end
+
+    if state == 'trac'
+      if d(i-1) == d(i)
+        arun_length++;
+      else
+        next_state = 'idle';
+        run_length(d(i-1)+10, arun_length)++;
+      end
+    end
+
+    state = next_state;
+
+  end
+
+  figure(2); clf; mesh(run_length(:,1:10));
+endfunction
+
+
+% Design kmeans quantisers for each DCT coeff.  This didn't work very well.
+
+function [quantisers nbits] = design_quantisters_kmeans(rate_K_surface, nr, nc, nbits_max)
+  [map rms_map mx unwrapped_dcts] = create_map_rms(rate_K_surface, nr, nc);
+  nq = nr*nc;
+  quantisers = zeros(nq, 2^nbits_max); nbits = zeros(nq,1);
+  for i=1:nq
+
+    % work out number of levels for this quantiser such that it is a
+    % power of 2 for integer number of bits
+
+    nlevels = (2^nbits_max);
+    nbits(i) = round(log2(nlevels));
+    nlevels = 2 .^ nbits(i);
+
+    if i <= 100
+      printf("%d %d\n", i, nlevels);
+      [idx, centers] = kmeans(unwrapped_dcts(:,i), nlevels);
+      quantisers(i,1:nlevels) = sort(centers);
+    end
+  end
+endfunction
+
+
+% Uniform quantisers designed to fit limits of each DCT coeff
+
+function [quantisers nlevels] = design_quantisters_uniform(rate_K_surface, nr, nc, nlevels_max)
+  [map rms_map mx mx_ind unwrapped_dcts] = create_map_rms(rate_K_surface, nr, nc);
+  
+  nq = nr*nc;
+  quantisers = zeros(nq, nlevels_max); nlevels = zeros(nq, 1);
+
+  for i=1:nq
+    d = unwrapped_dcts(:,mx_ind(i));
+    d = floor(d/16);
+    q_min = floor(min(d));
+    q_max = ceil(max(d));
+    nlevels(i) = q_max-q_min+1;
+    quantisers(i,1:nlevels(i)) = 16*(q_min:q_max);
+  end
+endfunction
+
+
+% Determine a phase spectra from a magnitude spectra
+% from http://www.dsprelated.com/showcode/20.php
+% Haven't _quite_ figured out how this works but have to start somewhere ....
+%
+% TODO: we may be able to sample at a lower rate, like mWo
+%       but start with something that works
+function [phase Gdbfk s Aw] = determine_phase(model, f, Nfft=512, ak)
+  Fs      = 8000;
+  max_amp = 80;
+  L       = min([model(f,2) max_amp-1]);
+  Wo      = model(f,1);
+
+  sample_freqs_kHz = (Fs/1000)*[0:Nfft/2]/Nfft;           % fft frequency grid (nonneg freqs)
+  Am = model(f,3:(L+2));
+  AmdB = 20*log10(Am);
+  rate_L_sample_freqs_kHz = (1:L)*Wo*4/pi;
+  Gdbfk = interp_para(rate_L_sample_freqs_kHz, AmdB, Fs/(2*1000), sample_freqs_kHz);    
+
+  % Gdbfk = resample_mask(model, f, mask_sample_freqs_kHz);
+
+  % optional input of aks for testing
+
+  if nargin == 4
+    Aw = 1 ./ fft(ak,Nfft);
+    Gdbfk = 20*log10(abs(Aw(1:Nfft/2+1)));
+  end
+
+  [phase s] = mag_to_phase(Gdbfk, Nfft);
+
+endfunction
+
+
+% Non linear sampling of frequency axis, reducing the "rate" is a
+% first step before VQ
+
+function mel = ftomel(fHz)
+  mel = floor(2595*log10(1+fHz/700)+0.5);
+endfunction
+
+
+function rate_K_sample_freqs_kHz = mel_sample_freqs_kHz(K, fstart_hz=100, fend_hz=0.95*4000)
+  mel_start = ftomel(fstart_hz); mel_end = ftomel(fend_hz); 
+  step = (mel_end-mel_start)/(K-1);
+  mel = mel_start:step:mel_end;
+  rate_K_sample_freqs_Hz = 700*((10 .^ (mel/2595)) - 1);
+  rate_K_sample_freqs_kHz = rate_K_sample_freqs_Hz/1000;
+endfunction
+
+
+function plot_mel_sample_freqs(K, f_start_hz, f_end_hz)
+  rate_K_sample_freqs_kHz = mel_sample_freqs_kHz(K, f_start_hz, f_end_hz);
+  figure(1); clf;
+  plot(rate_K_sample_freqs_kHz,'+');
+endfunction
+
+function [rate_K_surface rate_K_sample_freqs_kHz] = resample_const_rate_f_mel(model, K, Fs=8000) 
+  rate_K_sample_freqs_kHz = mel_sample_freqs_kHz(K, 100, 0.95*Fs/2);
+  rate_K_surface = resample_const_rate_f(model, rate_K_sample_freqs_kHz, Fs);
+endfunction
+
+
+% Resample Am from time-varying rate L=floor(pi/Wo) to fixed rate K.  This can be viewed
+% as a 3D surface with time, freq, and ampitude axis.
+
+function [rate_K_surface rate_K_sample_freqs_kHz] = resample_const_rate_f(model, rate_K_sample_freqs_kHz, Fs)
+
+  % convert rate L=pi/Wo amplitude samples to fixed rate K
+
+  max_amp = 160;
+  [frames col] = size(model);
+  K = length(rate_K_sample_freqs_kHz);
+  rate_K_surface = zeros(frames, K);
+
+  for f=1:frames
+    Wo = model(f,1);
+    L = min([model(f,2) max_amp-1]);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+
+    clip_en = 0;
+    if clip_en
+      % clip between peak and peak -50dB, to reduce dynamic range
+
+      AmdB_peak = max(AmdB);
+      AmdB(find(AmdB < (AmdB_peak-50))) = AmdB_peak-50;
+    end
+
+    rate_L_sample_freqs_kHz = (1:L)*Wo*Fs/(2000*pi);
+    
+    rate_K_surface(f,:) = interp1([0 rate_L_sample_freqs_kHz (Fs/2000)], [AmdB(1) AmdB AmdB(L)], rate_K_sample_freqs_kHz, "spline");
+    %rate_K_surface(f,:)  = interp_para(rate_L_sample_freqs_kHz, AmdB, Fs/(2*1000), rate_K_sample_freqs_kHz);    
+
+    %printf("%d\n", f);
+  end
+  %printf("\n");
+endfunction
+
+
+function [rate_K_vec_corrected orig_error error nasty_error_log nasty_error_m_log] = correct_rate_K_vec(rate_K_vec, rate_K_sample_freqs_kHz, AmdB, AmdB_, K, Wo, L, Fs)
+
+    % aliasing correction --------------------------------------
+
+    % The mel sample rate decreases as frequency increases. Look for
+    % any regions above 1000Hz where we have missed definition of a
+    % spectral peak (formant) due to aliasing.  Adjust the rate K
+    % sample levels to restore peaks.  Theory is that correct
+    % definition of a formant is less important than the frequency of
+    % the formant.  As long as we define a formant in that general
+    % frequency area it will sound OK.
+
+    Am_freqs_kHz = (1:L)*Wo*4/pi;
+
+    % Lets see where we have made an error
+
+    error = orig_error = AmdB - AmdB_;
+
+    Ncorrections = 3;      % maximum number of rate K samples to correct
+    error_thresh = 3;      % only worry about errors larger than thresh
+
+    start_m = floor(L*1000/(Fs/2));
+    error(1:start_m) = 0;  % first 1000Hz is densly sampled so ignore
+    nasty_error_m_log = []; nasty_error_log = [];
+
+
+    rate_K_vec_corrected = rate_K_vec;
+    for i=1:Ncorrections
+      [mx mx_m] = max(error);
+
+      if mx > error_thresh
+        nasty_error_log = [nasty_error_log mx];
+        nasty_error_m_log = [nasty_error_m_log mx_m];
+
+        % find closest rate K sample to nasty error
+
+        nasty_error_freq = mx_m*Wo*Fs/(2*pi*1000);
+        [tmp closest_k] = min(abs(rate_K_sample_freqs_kHz - nasty_error_freq));
+        rate_K_vec_corrected(closest_k) = AmdB(mx_m);
+
+        % zero out error in this region and look for another large error region
+
+        k = max(1, closest_k-1); 
+        rate_K_prev_sample_kHz = rate_K_sample_freqs_kHz(k);
+        k = min(K, closest_k+1); 
+        rate_K_next_sample_kHz = rate_K_sample_freqs_kHz(k);
+
+        [tmp st_m] = min(abs(Am_freqs_kHz - rate_K_prev_sample_kHz));
+        [tmp en_m] = min(abs(Am_freqs_kHz - rate_K_next_sample_kHz));
+        if closest_k == K
+         en_m = L;
+        end 
+        error(st_m:en_m) = 0;
+      end
+    end
+endfunction
+
+
+% Take a rate K surface and convert back to time varying rate L
+
+function [model_ AmdB_] = resample_rate_L(model, rate_K_surface, rate_K_sample_freqs_kHz, Fs=8000, pad_end=0)
+  max_amp = 160; K = columns(rate_K_surface);
+  [frames col] = size(model);
+
+  AmdB_ = zeros(frames, max_amp);
+  model_ = zeros(frames, max_amp+2);
+  for f=1:frames
+    Wo = model(f,1);
+    L = model(f,2);
+    rate_L_sample_freqs_kHz = (1:L)*Wo*Fs/(2000*pi);
+    
+    % back down to rate L
+
+    % dealing with end effects is an ongoing issue.....need a better solution
+
+    if pad_end
+      AmdB_(f,1:L) = interp1([0 rate_K_sample_freqs_kHz Fs/2000], 
+                             [rate_K_surface(f,1) rate_K_surface(f,:) rate_K_surface(f,K)], 
+                             rate_L_sample_freqs_kHz, 
+                             "spline");
+    else
+      AmdB_(f,1:L) = interp1([0 rate_K_sample_freqs_kHz], 
+                             [rate_K_surface(f,1) rate_K_surface(f,:)], 
+                             rate_L_sample_freqs_kHz, 
+                             "spline");
+    end
+
+    %AmdB_(f,1:L) = interp_para(rate_K_sample_freqs_kHz, rate_K_surface(f,:), Fs/(2*1000), rate_L_sample_freqs_kHz);
+    %printf("f: %d %f %f %f\n", f, rate_K_sample_freqs_kHz(1), rate_L_sample_freqs_kHz(1), AmdB_(1));
+    model_(f,1) = Wo; model_(f,2) = L; model_(f,3:(L+2)) = 10 .^ (AmdB_(f, 1:L)/20);
+   end
+endfunction
+
+
+% PostFilter, has a big impact on speech quality after VQ.  When used
+% on a mean removed rate K vector, it raises formants, and supresses
+% anti-formants.  As it manipulates amplitudes, we normalise energy to
+% prevent clipping or large level variations.  pf_gain of 1.2 to 1.5
+% (dB) seems to work OK.  Good area for further investigations and
+% improvements in speech quality.
+
+function vec = post_filter(vec, sample_freq_kHz, pf_gain = 1.5, voicing)
+    % vec is rate K vector describing spectrum of current frame
+    % lets pre-emp before applying PF. 20dB/dec over 300Hz
+    
+    pre = 20*log10(sample_freq_kHz/0.3);
+    vec += pre;
+
+    levels_before_linear = 10 .^ (vec/20);
+    e_before = sum(levels_before_linear .^2);
+
+    vec *= pf_gain;
+   
+    levels_after_linear = 10 .^ (vec/20);
+    e_after = sum(levels_after_linear .^2);
+    gain = e_after/e_before;
+    gaindB = 10*log10(gain);
+    vec -= gaindB;
+
+    vec -= pre;
+endfunction
+
+
+% construct energy quantiser table, and save to text file to include in C
+
+function energy_q = create_energy_q
+    energy_q = 10 + 40/16*(0:15);
+endfunction
+
+function save_energy_q(fn)
+  energy_q = create_energy_q;
+  f = fopen(fn, "wt");
+  fprintf(f, "1 %d\n", length(energy_q));
+  for n=1:length(energy_q)
+    fprintf(f, "%f\n", energy_q(n));
+  end
+  fclose(f);
+endfunction
+
+
+% save's VQ in format that can be compiled by Codec 2 build system
+
+function save_vq(vqset, filenameprefix)
+  [Nvec order stages] = size(vqset);
+  for s=1:stages
+    fn = sprintf("%s_%d.txt", filenameprefix, s);
+    f = fopen(fn, "wt");
+    fprintf(f, "%d %d\n", order, Nvec);
+    for n=1:Nvec
+      for k=1:order
+        fprintf(f, "% 8.4f ", vqset(n,k,s));
+      end
+      fprintf(f, "\n");
+    end
+    fclose(f);
+  end
+endfunction
+
+
+% Decoder side interpolation of Wo and voicing, to go from 25 Hz
+% sample rate used over channel to 100Hz internal sample rate of Codec
+% 2.
+
+function [Wo_ voicing_] = interp_Wo_v(Wo1, Wo2, voicing1, voicing2)
+    M = 4;
+    max_amp = 80;
+
+    Wo_ = zeros(1,M); 
+    voicing_ = zeros(1,M);
+    if !voicing1 && !voicing2
+       Wo_(1:M) = 2*pi/100;
+    end
+
+    if voicing1 && !voicing2
+       Wo_(1:M/2) = Wo1;
+       Wo_(M/2+1:M) = 2*pi/100;
+       voicing_(1:M/2) = 1;
+    end
+
+    if !voicing1 && voicing2
+       Wo_(1:M/2) = 2*pi/100;
+       Wo_(M/2+1:M) = Wo2;
+       voicing_(M/2+1:M) = 1;
+    end
+
+    if voicing1 && voicing2
+      Wo_samples = [Wo1 Wo2];
+      Wo_(1:M) = interp_linear([1 M+1], Wo_samples, 1:M);
+      voicing_(1:M) = 1;
+    end
+
+    #{
+    printf("f: %d f+M/2: %d Wo: %f %f (%f %%) v: %d %d \n", f, f+M/2, model(f,1), model(f+M/2,1), 100*abs(model(f,1) - model(f+M/2,1))/model(f,1), voicing(f), voicing(f+M/2));
+    for i=f:f+M/2-1
+      printf("  f: %d v: %d v_: %d Wo: %f Wo_: %f\n", i, voicing(i), voicing_(i), model(i,1),  model_(i,1));
+    end
+    #}
+endfunction
+
+
+function [diff_weighted weights error g min_ind] = search_vq_weighted(target, vq, weight_gain)
+  [vq_rows vq_cols] = size(vq);
+
+  weight_gain = 0.1; % I like this vairable name as it is funny
+
+  % find mse for each vector
+
+  error = g = zeros(1, vq_rows);
+  diff = weights = diff_weighted = zeros(vq_rows, vq_cols);
+
+  weights = max(0.1, weight_gain .* (target + 20));
+
+  for i=1:vq_rows
+
+    % work out gain for best match
+
+    g(i) = sum((target - vq(i,:)).*weights)/vq_cols;
+
+    % Find weighted difference.  This allocated more importance
+    % (error) to samples with higher energy, and stops really low
+    % level harmonics from having any impact.  Note addition in dB
+    % is multiplication in linear
+
+    diff(i,:) = target - vq(i,:) - g(i);
+    diff_weighted(i,:) = diff(i,:) .* weights;
+
+    % abs in dB is MSE in linear
+
+    error(i) = mean(abs(diff_weighted(i,:)));
+  end
+
+  [mn min_ind] = min(error);
+  
+endfunction
+
+
+% --------------------------------------------------------------------------------
+% Experimental functions used for masking, piecewise models, not part of newamp1
+% --------------------------------------------------------------------------------
+
+
+function [maskdB_ maskdB_cyclic Dabs dk_ D1_ ind] = decimate_in_freq(maskdB, cyclic=1, k=7, vq)
+
+    % Lets try to come up with a smoothed, cyclic model.  Replace
+    % points from 3500 Hz to 4000Hz with a sequence that joins without
+    % a step to points at the 0Hz end of the spectrum.  This will make
+    % it more cyclical and make the DFT happier, less high freq
+    % energy.  Yes, happier is an extremely technical term.
+
+    L = length(maskdB);
+    anchor = floor(7*L/8);
+    xpts = [ anchor-1 anchor L+1 L+2];
+    ypts = [ maskdB(anchor-1) maskdB(anchor) maskdB(1) maskdB(2)];
+    mask_pp = splinefit(xpts, ypts, 1);
+    maskdB_cyclic = [maskdB(1:anchor) ppval(mask_pp, anchor+1:L)];
+
+    % Now DFT, truncating DFT coeffs to undersample
+
+    if cyclic
+      D = fft(maskdB_cyclic)/L;
+    else
+      D = fft(maskdB)/L;
+    end
+    Dabs = abs(D);                        % this returned for plotting
+
+    % truncate D to rate k, convert to 2k length real vector for quantisation and transmission
+
+    Dk = [0 D(2:k-1) real(D(k)) D(L-k+1:L)]; 
+    dk = real(ifft(Dk));
+    D1 = D(1);
+       
+    % quantisation
+
+    if nargin == 4
+       [res tmp vq_ind] = mbest(vq, dk, 4);
+       D1_tab = 0:(60/15):60;
+       assert(length(D1_tab) == 16);
+       [tmp D1_ind] = quantise(D1_tab, D1);
+       ind = [vq_ind D1_ind];
+       [dk_ D1_] = index_to_params(ind, vq);
+       %std(dk_ - dk)
+    else
+       dk_ = dk;
+       D1_ = D1;
+    end
+
+    maskdB_ = params_to_mask(L, k, dk_, D1_);
+endfunction
+
+
+
+function [dk_ D1_] = index_to_params(ind, vq)
+    [Nvec order stages] = size(vq);
+    dk_ = zeros(1,order);
+    for s=1:stages
+      dk_ = dk_ + vq(ind(s),:,s);
+    end
+    D1_tab = 0:(60/15):60;
+    D1_ = D1_tab(ind(stages+1));
+endfunction
+
+
+% decoder side
+
+function maskdB_ = params_to_mask(L, k, dk_, D1_)
+
+    anchor = floor(7*L/8);
+
+    % convert quantised dk back to rate L magnitude spectrum
+
+    Dk_ = fft(dk_);
+    D_ = zeros(1,L);
+    D_(1) = D1_;                      % energy seperately quantised
+    D_(2:k-1) = Dk_(2:k-1);
+    D_(L-k+1:L) = Dk_(k+1:2*k);
+    d_ = L*ifft(D_);                  % back to spectrum at rate L
+    maskdB_ = real(d_);
+    
+    % Finally fix up last 500Hz, taper down 10dB at 4000Hz
+
+    xpts = [ anchor-1 anchor L];
+    ypts = [ maskdB_(anchor-1) maskdB_(anchor) (maskdB_(anchor)-10)];
+    mask_pp = splinefit(xpts, ypts, 1);
+    maskdB_ = [maskdB_(1:anchor) ppval(mask_pp, anchor+1:L)];
+endfunction
+
+
+
+% determine cumulative mask, using amplitude of each harmonic.  Mask is
+% sampled across L points in the linear domain
+
+function maskdB = determine_mask(masker_amps_dB, masker_freqs_kHz, mask_sample_freqs_kHz, bark_model=1)
+
+    % calculate and plot masking curve
+
+    maskdB = -20*ones(1,length(mask_sample_freqs_kHz));
+    for m=1:length(masker_freqs_kHz)
+      maskdB = max(maskdB, schroeder(masker_freqs_kHz(m), mask_sample_freqs_kHz, bark_model) + masker_amps_dB(m)); 
+      %maskdB = max(maskdB, parabolic_resonator(masker_freqs_kHz(m), mask_sample_freqs_kHz) + masker_amps_dB(m)); 
+    end
+end
+
+
+% Sample mask as model for Am
+
+function [maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L, bark_model=1)
+
+    Am_freqs_kHz = (1:L)*Wo*4/pi;
+    maskdB = determine_mask(AmdB, Am_freqs_kHz, Am_freqs_kHz, bark_model);
+endfunction
+
+
+%
+% Masking functions from http://www.perceptualentropy.com/coder.html#C
+% Thanks Jon Boley!
+%
+
+% Calculate the Schroeder masking spectrum for a given frequency and SPL
+
+function maskdB = schroeder(freq_tone_kHz, mask_sample_freqs_kHz, bark_model=1)
+  f_kHz = mask_sample_freqs_kHz;
+  f_Hz = f_kHz*1000;
+
+  % Schroeder Spreading Function
+
+  if bark_model == 0
+    dz = bark(freq_tone_kHz*1000)-bark(f_Hz);
+  end
+
+  if bark_model == 1
+
+    % Modification by DR: Piecewise linear model that makes bands
+    % beneath 1.5kHz wider to match the width of F1 and
+    % "fill in" the spectra better for UV sounds.
+
+    %x1 = 0.5; x2 = 2;
+    %y1 = 0.5; y2 = 1;
+    x1 = 0.5; x2 = 3;
+    y1 = 1; y2 = 3;
+
+    grad  = (y2 - y1)/(x2 - x1);
+    y_int = y1 - grad*x1;
+
+    if freq_tone_kHz <= x1
+      y = y1;
+    end
+    if (freq_tone_kHz > x1) && (freq_tone_kHz < x2)
+      y = grad*freq_tone_kHz + y_int;
+    end
+    if freq_tone_kHz >= x2
+      y = y2;
+    end
+    dz = y*(bark(freq_tone_kHz*1000) - bark(f_Hz));
+  end
+
+  if bark_model == 2
+
+    % constant bandwidth model, useful for bg noise and UV
+
+    %dz = bark(freq_tone_kHz*1000) - bark(f_Hz);
+    dz = 0.2*bark(freq_tone_kHz*1000-f_Hz);
+  end
+
+  maskdB = 15.81 + 7.5*(dz+0.474) - 17.5*sqrt(1 + (dz+0.474).^2);
+endfunction
+
+
+% Converts frequency to bark scale
+% Frequency should be specified in Hertz
+
+function b=bark(f)
+  b = 13*atan(0.76*f/1000) + 3.5*atan((f/7500).^2); 
+endfunction
+
+
+% Alternative mask function that has a gentler slope than schroeder.
+% Idea is to get sharp formant definition, but also fill in gaps so we
+% dont get chunks of spectrum coming and going
+
+function [maskdB pp] = resonator(freq_tone_kHz, mask_sample_freqs_kHz)
+  % note all frequencies in kHz
+
+  f1  = 0.1; f2  = 3;
+  bw1 = 0.1; bw2 = 0.1; 
+  m = (bw2-bw1)/(log10(f2)-log10(f1));
+  c = bw1 - m*log10(f1);
+
+  Fs    = 8;
+  slope = -12;     % filter falls off by this slope/octave
+
+  maskdB = zeros(1, length(mask_sample_freqs_kHz));
+
+  % frequency dependant bandwidth
+
+  bw = m*log10(freq_tone_kHz) + c;
+  printf("freq_tone_kHz: %f bw: %f\n", freq_tone_kHz, bw);
+
+  % Design spline to set shape based on current bandwidth
+
+  x = [-Fs/2 -bw/2 0 +bw/2 +Fs/2];
+  delta = slope*log2(Fs/bw);                 % gain is delta down from -3dB to Fs/2
+  y = [-3 + delta, -3, 0, -3, -3 + delta];
+  pp = splinefit(x, y, 4);
+  maskdB = ppval(pp, mask_sample_freqs_kHz - freq_tone_kHz);
+endfunction
+
+
+function maskdB = resonator_fast(freq_tone_kHz, mask_sample_freqs_kHz)
+
+  % note all frequencies on kHz
+
+  #{
+  max_ind = length(pp_bw);
+  ind = round(freq_tone_kHz/0.1);
+  ind = min(ind, max_ind);
+  ind = max(ind, 1);
+  #}
+  %printf("freq_tone_kHz: %f ind: %d\n", freq_tone_kHz, ind);
+  [maskdB_res1 pp] = resonator(0.5, mask_sample_freqs_kHz);
+
+  maskdB = ppval(pp, mask_sample_freqs_kHz - freq_tone_kHz);
+  %maskdB = ppval(pp_bw(ind), mask_sample_freqs_kHz - freq_tone_kHz);
+endfunction
+
+
+% Alternative mask function that uses parabolas for fast computation
+
+function maskdB = parabolic_resonator(freq_tone_kHz, mask_sample_freqs_kHz)
+
+  % note all frequencies in kHz
+
+  % bandwidth as a function of log(f)
+
+  f1  = 0.5; f2  = 3;
+  bw1 = 0.1; bw2 = 0.3; 
+  m = (bw2-bw1)/(log10(f2)-log10(f1));
+  c = bw1 - m*log10(f1);
+
+  Fs = 8;
+  slope = -18;
+
+  % frequency dependant bandwidth
+
+  if freq_tone_kHz < f1
+    bw = bw1;
+  else
+    bw = m*log10(freq_tone_kHz) + c;
+  end
+  %printf("freq_tone_kHz: %f bw: %f\n", freq_tone_kHz, bw);
+
+  % Design parabola to fit bandwidth
+
+  a = -3/((bw/2)^2);
+  %printf("freq_tone_kHz: %f bw: %f a: %f\n", freq_tone_kHz, bw, a);
+
+  % Design straight line to fit slope
+  delta = slope*log2(Fs/bw);                 % gain is delta down from -3dB to Fs/2
+  m1 = 2*delta/Fs;
+
+  maskdB_par  = a*((mask_sample_freqs_kHz - freq_tone_kHz).^2);
+  maskdB_line = m1*abs(mask_sample_freqs_kHz - freq_tone_kHz) - 10;
+  %indx = find(mask_sample_freqs_kHz < freq_tone_kHz);
+  %maskdB_line(indx) = -50;
+
+  maskdB = max(maskdB_par, maskdB_line);
+endfunction
+
+
+% sampling the mask in one frame using an arbitrary set of samplng frequencies
+
+function maskdB = resample_mask(model, f, mask_sample_freqs_kHz)
+  max_amp = 80;
+
+  Wo = model(f,1);
+  L = min([model(f,2) max_amp-1]);
+  Am = model(f,3:(L+2));
+  AmdB = 20*log10(Am);
+  masker_freqs_kHz = (1:L)*Wo*4/pi;
+  maskdB = determine_mask(AmdB, masker_freqs_kHz, mask_sample_freqs_kHz);
+endfunction
+
+
+% decimate frame rate of mask, use linear interpolation in the log domain 
+
+function maskdB_ = decimate_frame_rate(model, decimate, f, frames)
+    max_amp = 80;
+
+    Wo = model(f,1);
+    L = min([model(f,2) max_amp]);
+
+    % determine frames that bracket the one we need to interp
+
+    left_f = decimate*floor((f-1)/decimate)+1; 
+    right_f = left_f + decimate;
+    if right_f > frames
+      right_f = left_f;
+    end
+
+    % determine fraction of each frame to use
+
+    left_fraction  = 1 - mod((f-1),decimate)/decimate;
+    right_fraction = 1 - left_fraction;
+
+    printf("f: %d left_f: %d right_f: %d left_fraction: %3.2f right_fraction: %3.2f \n", f, left_f, right_f, left_fraction, right_fraction)
+
+    % fit splines to left and right masks
+
+    left_Wo = model(left_f,1);
+    left_L = min([model(left_f,2) max_amp]);
+    left_AmdB = 20*log10(model(left_f,3:(left_L+2)));
+    left_sample_freqs_kHz = (1:left_L)*left_Wo*4/pi;
+
+    right_Wo = model(right_f,1);
+    right_L = min([model(right_f,2) max_amp]);
+    right_AmdB = 20*log10(model(right_f,3:(right_L+2)));
+    right_sample_freqs_kHz = (1:right_L)*right_Wo*4/pi;
+
+    % determine mask for left and right frames, sampling at Wo for this frame
+
+    sample_freqs_kHz = (1:L)*Wo*4/pi;
+    maskdB_left = interp1(left_sample_freqs_kHz, left_AmdB, sample_freqs_kHz, "extrap");
+    maskdB_right = interp1(right_sample_freqs_kHz, right_AmdB, sample_freqs_kHz, "extrap");
+
+    maskdB_ = left_fraction*maskdB_left + right_fraction*maskdB_right;
+endfunction
+
+
+% plot some masking curves, used for working on masking filter changes
+
+function plot_masking(bark_model=0);
+  Fs = 8000;
+
+  figure(1)
+  mask_sample_freqs_kHz = 0.1:0.025:(Fs/1000)/2;
+  %maskdB_s0 = schroeder(0.5, mask_sample_freqs_kHz, 0);
+  %plot(mask_sample_freqs_kHz, maskdB_s0,';schroeder 0;');
+  maskdB_s1 = schroeder(0.5, mask_sample_freqs_kHz, bark_model);
+  plot(mask_sample_freqs_kHz, maskdB_s1,'g;schroeder 1;');
+  #{
+  maskdB_res = parabolic_resonator(0.5, mask_sample_freqs_kHz);
+  plot(mask_sample_freqs_kHz, maskdB_res,'r;resonator;');
+  #}
+  hold on;
+
+  for f=0.5:0.5:3
+    %maskdB_s0 = schroeder(f, mask_sample_freqs_kHz, 0);
+    %plot(mask_sample_freqs_kHz, maskdB_s0);
+    maskdB_s1 = schroeder(f, mask_sample_freqs_kHz, bark_model);
+    plot(mask_sample_freqs_kHz, maskdB_s1,'g');
+    #{
+    maskdB_res = parabolic_resonator(f, mask_sample_freqs_kHz);
+    plot(mask_sample_freqs_kHz, maskdB_res,'r;resonator;');
+    #}
+  end
+  hold off;
+
+  axis([0.1 4 -30 0])
+  grid
+
+  #{
+  %pp_bw = gen_pp_bw;
+  figure(2)
+  clf;
+  maskdB_res = resonator(0.5, mask_sample_freqs_kHz);
+  plot(mask_sample_freqs_kHz, maskdB_res);  
+  hold on;
+  maskdB_res_fast = resonator_fast(0.5, mask_sample_freqs_kHz);
+  plot(mask_sample_freqs_kHz, maskdB_res_fast, "g");  
+  maskdB_par = parabolic_resonator(0.5, mask_sample_freqs_kHz);
+  plot(mask_sample_freqs_kHz, maskdB_par, "r");  
+  hold off;
+  axis([0 4 -80 0]);
+  grid
+  #}
+endfunction
+
+
+% produce a scatter diagram of amplitudes
+
+function amp_scatter(samname)
+  
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+  [frames nc] = size(model);
+  max_amp = 80;
+
+  Am_out_name = sprintf("%s_am.out", samname);
+  freqs = [];
+  ampsdB = [];
+
+  for f=1:frames
+    
+    L = min([model(f,2) max_amp-1]);
+    Wo = model(f,1);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+
+    maskdB = mask_model(AmdB, Wo, L);
+    mask_sample_freqs_kHz = (1:L)*Wo*4/pi;
+    [newmaskdB local_maxima] = make_newmask(maskdB, AmdB, Wo, L, mask_sample_freqs_kHz);
+
+    [nlm tmp] = size(local_maxima);
+    freqs = [freqs (local_maxima(1:min(4,nlm),2)*Wo*4000/pi)'];
+    an_ampsdB = local_maxima(1:min(4,nlm),1)';
+    ampsdB = [ampsdB an_ampsdB-mean(an_ampsdB)];
+  end
+
+  figure(1)
+  plot(freqs, ampsdB,'+');
+  figure(2)
+  subplot(211)
+  hist(freqs,20)
+  subplot(212)
+  hist(ampsdB,20)
+endfunction
+
+
+
+% AbyS returns f & a, this function plots values so we can consider quantisation
+
+function plot_f_a_stats(f,a)
+
+  % freq pdfs
+
+  [fsrt fsrt_ind] = sort(f,2);
+  fsrt /= 1000;
+  figure(1)
+  for i=1:4
+    subplot(2,2,i)
+    hist(fsrt(:,i),50)
+    printf("%d min: %d max: %d\n", i, min(fsrt(:,i)), max(fsrt(:,i)))
+    an_axis = axis;
+    axis([0 4 an_axis(3) an_axis(4)])
+  end
+
+  % freq diff pdfs
+
+  figure(2)
+  for i=1:4
+    subplot(2,2,i)
+    if i == 1
+      hist(fsrt(:,i),50)
+    else
+      hist(fsrt(:,i) - fsrt(:,i-1),50)
+    end
+    an_axis = axis;
+    axis([0 4 an_axis(3) an_axis(4)])
+  end
+
+  % amplitude PDFs
+
+  l = length(a);
+  for i=1:l
+    asrt(i,:) = a(i, fsrt_ind(i,:));
+  end
+  
+  figure(3)
+  for i=1:4
+    subplot(2,2,i)
+    hist(asrt(:,i) - mean(asrt(:,:),2))
+    an_axis = axis;
+    axis([-40 40 an_axis(3) an_axis(4)])
+  end
+  
+  % find straight line fit
+
+  for i=1:l
+    [gradient intercept] = linreg(1000*fsrt(i,:), asrt(i,:), 4);
+    alinreg(i,:) = gradient*1000*fsrt(i,:) + intercept;
+    alinregres(i,:) = asrt(i,:) - alinreg(i,:);
+    m(i) = gradient; c(i) = intercept;
+  end
+
+  figure(4)
+  for i=1:4
+    subplot(2,2,i)
+    hist(alinregres(:,i))
+    an_axis = axis;
+    axis([-40 40 an_axis(3) an_axis(4)])
+  end
+  
+  figure(5)
+  subplot(211)
+  m = m(find(m>-0.05));
+  m = m(find(m<0.03));
+  hist(m,50)
+  title('gradient');
+  subplot(212)
+  c = c(find(c>0));
+  hist(c,50)
+  title('y-int');
+
+endfunction
+
+function D1_log = decode_from_bit_stream(samname, ber = 0, bit_error_mask = ones(28,1))
+  max_amp = 80;
+  bits_per_param = [6 1 8 8 4 1];
+  assert(sum(bits_per_param) == 28);
+  load vq;
+  k = 10;
+  dec_in_time = 1;
+  train = 0;
+  decimate = 4;
+  synth_phase = 1;
+
+  Am_out_name = sprintf("%s_am.out", samname);
+  Aw_out_name = sprintf("%s_aw.out", samname);
+  bit_stream_name = strcat(samname,".bit");
+  faw = fopen(Aw_out_name,"wb"); 
+  fam  = fopen(Am_out_name,"wb"); 
+  faw = fopen(Aw_out_name,"wb"); 
+
+  Wo_out_name = sprintf("%s_Wo.out", samname);
+  fWo  = fopen(Wo_out_name,"wb"); 
+
+  % read in bit stream and convert to ind_log[]
+
+  ind_log = [];
+  fbit  = fopen(bit_stream_name, "rb"); 
+  bits_per_frame = sum(bits_per_param);
+  nind = length(bits_per_param);
+  nerr = 0; nbits = 0;
+  [frame nread] = fread(fbit, sum(bits_per_param), "uchar");
+  while (nread == bits_per_frame)
+
+    % optionally introduce bit errors
+
+    error_bits = rand(sum(bits_per_param), 1) < ber;
+    error_bits_masked = bitand(error_bits, bit_error_mask);
+    frame = bitxor(frame, error_bits_masked);
+    nerr += sum(error_bits_masked);
+    nbits += sum(bits_per_param);
+
+    % read a frame, convert to indexes
+
+    nbit = 1;
+    ind = [];
+    for i=1:nind
+      field = frame(nbit:nbit+bits_per_param(i)-1);
+      nbit += bits_per_param(i);
+      ind = [ind bits_to_index(field, bits_per_param(i))];
+    end
+    ind_log = [ind_log; ind];
+    [frame nread] = fread(fbit, sum(bits_per_param), "uchar");
+  endwhile
+  fclose(fbit);
+  printf("nerr: %d nbits: %d %f\n", nerr, nbits, nerr/nbits);
+  
+  % convert ind_log to modem params
+
+  frames = 4*length(ind_log);
+  model_ = zeros(frames, max_amp+2);
+  v      = zeros(frames,1);
+  D1_log = [];
+
+  fdec = 1;
+  for f=1:4:frames
+    ind_Wo = ind_log(fdec,1);
+
+    Wo = decode_log_Wo(ind_Wo, 6);
+    L = floor(pi/Wo);
+    L = min([L max_amp-1]);
+    model_(f,1) = Wo;
+    model_(f,2) = L;
+    
+    v1 = ind_log(fdec,2); 
+    if (fdec+1) < length(ind_log)
+      v5 = ind_log(fdec+1,2);
+    else
+      v5 = 0;
+    end
+    v(f:f+3) = est_voicing_bits(v1, v5);
+
+    ind_vq = ind_log(fdec,3:5) + 1;
+    [dk_ D1_] = index_to_params(ind_vq, vq);
+    D1_log = [D1_log; D1_];
+    maskdB_ = params_to_mask(L, k, dk_, D1_);
+    Am_ = zeros(1,max_amp);
+    Am_ = 10 .^ (maskdB_(1:L)/20); 
+    model_(f,3:(L+2)) = Am_;
+
+    fdec += 1;
+  end
+
+  % decoder loop -----------------------------------------------------
+
+  if train
+    % short circuit decoder
+    frames = 0;
+  end
+
+  % run post filter ahead of time so dec in time has post filtered frames to work with
+
+  for f=1:frames
+    model_(f,:) = post_filter(model_(f,:));
+  end
+
+  for f=1:frames
+    %printf("frame: %d\n", f);
+    L = min([model_(f,2) max_amp-1]);
+    Wo = model_(f,1);
+    Am_ = model_(f,3:(L+2));
+
+    maskdB_ = 20*log10(Am_);
+
+    if dec_in_time
+      % decimate mask samples in time
+
+      [maskdB_ Wo L] = decimate_frame_rate2(model_, decimate, f, frames);
+      model_(f,1) = Wo;
+      model_(f,2) = L;
+    end
+
+    Am_ = zeros(1,max_amp);
+    Am_(2:L) = 10 .^ (maskdB_(1:L-1)/20);  % C array doesnt use A[0]
+    fwrite(fam, Am_, "float32");
+    fwrite(fWo, Wo, "float32");
+
+    if synth_phase
+
+      % synthesis phase spectra from magnitiude spectra using minimum phase techniques
+
+      fft_enc = 512;
+      model_(f,3:(L+2)) = 10 .^ (maskdB_(1:L)/20);
+      phase = determine_phase(model_, f);
+      assert(length(phase) == fft_enc);
+      Aw = zeros(1, fft_enc*2); 
+      Aw(1:2:fft_enc*2) = cos(phase);
+      Aw(2:2:fft_enc*2) = -sin(phase);
+      fwrite(faw, Aw, "float32");    
+    end
+  end
+
+  fclose(fam);
+  fclose(fWo);
+  if synth_phase
+    fclose(faw);
+  end
+
+  % save voicing file
+  
+  v_out_name = sprintf("%s_v.txt", samname);
+  fv  = fopen(v_out_name,"wt"); 
+  for f=1:length(v)
+    fprintf(fv,"%d\n", v(f));
+  end
+  fclose(fv);
+
+endfunction
+
+
+
+% decimate frame rate of mask, use linear interpolation in the log domain 
+
+function [maskdB_ Wo L] = decimate_frame_rate2(model, decimate, f, frames)
+    max_amp = 80;
+
+    % determine frames that bracket the one we need to interp
+
+    left_f = decimate*floor((f-1)/decimate)+1; 
+    right_f = left_f + decimate;
+    if right_f > frames
+      right_f = left_f;
+    end
+
+    % determine fraction of each frame to use
+
+    left_fraction  = 1 - mod((f-1),decimate)/decimate;
+    right_fraction = 1 - left_fraction;
+
+    % printf("f: %d left_f: %d right_f: %d left_fraction: %3.2f right_fraction: %3.2f \n", f, left_f, right_f, left_fraction, right_fraction)
+
+    % fit splines to left and right masks
+
+    left_Wo = model(left_f,1);
+    left_L = min([model(left_f,2) max_amp]);
+    left_AmdB = 20*log10(model(left_f,3:(left_L+2)));
+    left_mask_sample_freqs_kHz = (1:left_L)*left_Wo*4/pi;
+    
+    right_Wo = model(right_f,1);
+    right_L = min([model(right_f,2) max_amp]);
+    right_AmdB = 20*log10(model(right_f,3:(right_L+2)));
+    right_mask_sample_freqs_kHz = (1:right_L)*right_Wo*4/pi;
+
+    % printf("  right_Wo: %f left_Wo: %f  right_L: %d  left_L %d\n",right_Wo,left_Wo,right_L,left_L);
+    printf("%f %f\n", left_AmdB(left_L), right_AmdB(right_L));
+
+    maskdB_left_pp = splinefit(left_mask_sample_freqs_kHz, left_AmdB, left_L);
+    maskdB_right_pp = splinefit(right_mask_sample_freqs_kHz, right_AmdB, right_L);
+
+    % determine mask for left and right frames, sampling at Wo for this frame
+
+    Wo = left_fraction*left_Wo + right_fraction*right_Wo;
+    L = floor(pi/Wo);
+    %Wo = model(f,1); L = model(f,2);
+
+    mask_sample_freqs_kHz = (1:L)*Wo*4/pi;
+    maskdB_left = ppval(maskdB_left_pp, mask_sample_freqs_kHz);
+    maskdB_right = ppval(maskdB_right_pp, mask_sample_freqs_kHz);
+
+    maskdB_ = left_fraction*maskdB_left + right_fraction*maskdB_right;
+endfunction
+
+#{
+function amodel = post_filter(amodel)
+    max_amp = 80;
+
+    % post filter 
+
+    L = min([amodel(2) max_amp-1]);
+    Wo = amodel(1);
+    Am_ = amodel(3:(L+2));
+    AmdB_ = 20*log10(Am_);
+    AmdB_pf = AmdB_*1.5;
+    AmdB_pf += max(AmdB_) - max(AmdB_pf);
+    amodel(3:(L+2)) = 10 .^ (AmdB_pf(1:L)/20);
+endfunction
+#}
+
+
+% Given a matrix with indexes on each row, convert to a bit stream and
+% write to file.  We only write every 4th frame due to DIT
+
+function write_bit_stream_file(fn, ind_log, bits_per_param)
+  fbit  = fopen(fn,"wb"); 
+  decimate = 4;
+
+  % take a row of quantiser indexes, convert to bits, save to file
+
+  [frames nind] = size(ind_log);
+  for f=1:decimate:frames
+    frame_of_bits = [];
+    arow = ind_log(f,:);
+    for i=1:nind
+      %printf("i: %d bits_per_param: %d\n", i, bits_per_param(i));
+      some_bits = index_to_bits(arow(i), bits_per_param(i));
+      frame_of_bits = [frame_of_bits some_bits];
+    end
+    fwrite(fbit, frame_of_bits, "uchar");
+  end
+  fclose(fbit);
+endfunction
+
+
+
+% determine 4 voicing bits based on 2 decimated voicing bits
+
+function [v] = est_voicing_bits(v1, v5)
+  if v1 == v5
+    v(1:4) = v1;
+  else
+    v(1:2) = v1;
+    v(3:4) = v5;
+  end
+endfunction
+
+
+function [AmdB_ residual fvec fvec_ amps] = piecewise_model(AmdB, Wo, vq, vq_m) 
+    L = length(AmdB);
+    l1000 = floor(L/4);     
+    AmdB_ = ones(1,L);
+    mask_sample_freqs_kHz = (1:L)*Wo*4/pi;
+
+    % fit a resonator to max of first 300 - 1000 Hz
+
+    fmin = 0.150;
+    lmin = floor(L*fmin/4);
+    [mx mx_ind] = max(AmdB(lmin+1:l1000));
+    amp(1) = mx;
+    mx_ind += lmin;
+    AmdB_ = parabolic_resonator(mx_ind*Wo*4/pi, mask_sample_freqs_kHz) + mx;  
+    fr1 = mx_ind*Wo*4/pi;
+
+    % fit a 2nd resonator, must be above 1000Hz
+
+    fmin = 1;
+    lmin = round(fmin*L/4);
+
+    [mx mx_ind] = max(AmdB(lmin+1:L));
+    amp(2) = mx;
+    mx_ind += lmin;
+    AmdB_ = max(AmdB_, parabolic_resonator(mx_ind*Wo*4/pi, mask_sample_freqs_kHz) + mx);  
+    fr2 = mx_ind*Wo*4/pi;
+
+    % fit a third resonator, must be +/- 300 Hz after 2nd resonator
+
+    residual = AmdB - AmdB_;
+    keep_out = [1:lmin];
+    lmax = round(L*3500/4000);
+    keep_out = [1:lmin lmax:L];
+    residual(keep_out) = -40;
+
+    fr2 = mx_ind*Wo*4/pi;
+    fmin = fr2 - 0.300;
+    fmax = fr2 + 0.300;   
+    lmin = max(1, round(L*fmin/4));
+    lmax = min(L, round(L*fmax/4));
+    keep_out = [keep_out lmin:lmax];
+
+    residual = AmdB;
+    residual(keep_out) = -40;
+
+    if 0
+    figure(3); clf;
+    subplot(211)
+    plot(mask_sample_freqs_kHz, residual);
+    end
+
+    [mx mx_ind] = max(residual);
+    amp(3) = AmdB(mx_ind);
+    AmdB_ = max(AmdB_, parabolic_resonator(mx_ind*Wo*4/pi, mask_sample_freqs_kHz) + amp(3));  
+    fr3 = mx_ind*Wo*4/pi;
+
+    % 4th resonator 
+
+    fmin = fr3 - 0.300;
+    fmax = fr3 + 0.300;
+    
+    lmin = max(1, round(L*fmin/4));
+    lmax = min(L, round(L*fmax/4));
+    keep_out = [keep_out lmin:lmax];
+
+    residual = AmdB - AmdB_;
+    residual(keep_out) = -40;
+
+    [mx mx_ind] = max(residual);
+    amp(4) = AmdB(mx_ind);
+    AmdB_ = max(AmdB_, parabolic_resonator(mx_ind*Wo*4/pi, mask_sample_freqs_kHz) + amp(4));  
+    fr4 = mx_ind*Wo*4/pi;
+
+    if 0
+    subplot(212)
+    plot(mask_sample_freqs_kHz, residual);
+    end
+
+    printf("\nfr1: %f fr2: %f fr3: %f fr4: %f\n", fr1, fr2, fr3, fr4);
+    [fvec fvec_ind] = sort([fr1 fr2 fr3 fr4]);
+    amps = amp(fvec_ind(1:4));
+
+    fvec_ = zeros(1, 4);
+
+    #{
+    % optional VQ of frequencies
+    if nargin == 4
+      AmdB_ = ones(1,L);
+      [mes fvec_ ind] = mbest(vq, fvec, vq_m);
+      for i=1:4
+        an_amp = amp(fvec_ind(i));
+        AmdB_ = max(AmdB_, parabolic_resonator(fvec_(i), mask_sample_freqs_kHz) + an_amp);
+      end
+    end
+    #}
+
+    % optional VQ of amplitudes
+    if nargin == 4
+      AmdB_ = ones(1,L);
+      %amps_(1) = amps(1);
+      %[mes tmp ind] = mbest(vq,  amps(2:4) -  amps_(1), vq_m);
+      %amps_(2:4) = amps_(1) + tmp;
+      [mes amps_ ind] = mbest(vq,  amps, vq_m);
+      amps-amps_
+      for i=1:4
+        AmdB_ = max(AmdB_, parabolic_resonator(fvec(i), mask_sample_freqs_kHz) + amps_(i));
+      end
+    end
+
+    %amps = amps(2:4) - amps(1);
+endfunction
+
+
+% find best place for resonator by closed loop min MSE search
+
+function lmin = abys(AmdB_, AmdB, Wo, L, mask_sample_freqs_kHz)
+  lstart = round(L/4);
+  lmin = lstart;
+  emin = 1E6;
+
+  printf("lstart: %d L: %d\n", lstart, L);
+
+  figure(3);
+  subplot(211)
+  plot(mask_sample_freqs_kHz*1000, AmdB,'r+-');
+  
+  e = zeros(1,L);
+  for l=lstart:L
+
+    % calc mse
+
+    f_l = l*Wo*4/pi;
+    AmdB_l = max(AmdB_, parabolic_resonator(f_l, mask_sample_freqs_kHz) + AmdB(l));
+    hold on;
+    if l == 23
+      plot(mask_sample_freqs_kHz*1000, AmdB_l,'c');
+    end
+    hold off;
+    e(l) = sum((AmdB_l - AmdB) .^ 2);
+    %printf("l: %5d f_l: %4.3f e: %4.0f emin: %4.0f lmin: %5d\n", l, f_l, emin, lmin);
+    printf("l: %5d f_l: %4.3f e: %4.0f emin: %4.0f lmin: %5d\n", l, f_l, e(l), emin, lmin);
+    if e(l) < emin
+       emin = e(l);
+       lmin = l;
+    end
+  end
+
+  subplot(212)
+  plot(mask_sample_freqs_kHz*1000, e)
+endfunction
+
+
+function rate_K_surface_no_slope = remove_slope(rate_K_surface)
+  [frames K] = size(rate_K_surface);
+  rate_K_surface_no_slope = zeros(frames,K);
+  for f=1:frames
+    [gradient intercept] = linreg(1:K, rate_K_surface(f,:), K);
+    printf("f: %d gradient: %f intercept: %f\n", f, gradient, intercept);
+    rate_K_surface_no_slope(f,:) = rate_K_surface(f,:) - (intercept + gradient*(1:K));
+  end
+endfunction
diff --git a/codec2/branches/0.7/octave/newamp1_batch.m b/codec2/branches/0.7/octave/newamp1_batch.m
new file mode 100644 (file)
index 0000000..cc56894
--- /dev/null
@@ -0,0 +1,1384 @@
+% newamp1_batch.m
+%
+% Copyright David Rowe 2016
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+
+#{
+
+  Octave script to batch process model parameters using the new
+  amplitude model, version 1.  Outputs another set of model parameters
+  that can be fed to c2sim for listening tests.  The companion
+  newamp1_fbf.m script is used to visualise the processing frame by frame
+  c2sim -> dump files -> newamp1_batch.m -> output model params -> c2sim -> play
+  The newamp1_xxx scripts have evolved to (i) resample {Am} using a
+  mel frequency axis, (ii) 2 stage VQ the mean removed vector.  Seems to work
+  OK at 700 bit/s, comparable to 1300.
+
+  Usage:
+
+    build codec2 with -DDUMP - see codec2-dev/README, then:
+
+    ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --dump hts1a
+    $ cd ~/codec2-dev/octave
+    octave:14> newamp1_batch("../build_linux/src/hts1a")
+    ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --amread hts1a_am.out -o - | play -t raw -r 8000 -s -2 -
+  Or with a little more processing, first dump energy and voicing, the
+  import Wo, voicing, phase spectra which simulates all the decoder
+  DSP.  We switch on lpc 10 just to dump voicing.
+
+    $ ./c2sim ../../raw/vk5qi.raw --phase0 --postfilter --dump vk5qi --lpc 10 --dump_pitch_e vk5qi_pitche.txt
+    octave:14> newamp1_batch("../build_linux/src/vk5qi", "../build_linux/src/vk5qi.out");
+    $ ./c2sim ../../raw/vk5qi.raw --phase0 --postfilter --amread vk5qi_am.out --hmread vk5qi_hm.out --Woread vk5qi_Wo.out --hand_voicing vk5qi_v.txt -o - | play -q -t raw -r 8000 -s -2 -
+
+#}
+
+
+% In general, this function processes a bunch of amplitudes, we then
+% use c2sim to hear the results.  Bunch of different experiments below
+
+function [surface mean_f] = newamp1_batch(input_prefix, varargin)
+  newamp;
+  more off;
+
+  max_amp = 160;
+  mean_f = [];
+
+  % defaults
+
+  synth_phase = output = 1;
+  output_prefix = input_prefix;
+  vq_type = "";
+  vq_filename = ""; 
+  vq_search = "mse";
+  mode = "const";
+  fit_order = 0;
+
+  % parse variable argument list
+
+  if (length (varargin) > 0)
+
+    % check for the "output_prefix" option
+
+    ind = arg_exists(varargin, "output_prefix");
+    if ind
+      output_prefix =  varargin{ind+1};
+    end
+    ind = arg_exists(varargin, "mode");
+    if ind
+      mode =  varargin{ind+1};
+    end
+    ind = arg_exists(varargin, "vq_search");
+    if ind
+      vq_search = varargin{ind+1};
+    end
+    ind = arg_exists(varargin, "vq");
+    if ind
+      vq_type = varargin{ind};
+      vq_filename = varargin{ind+1};
+      printf("vq_type: %s vq_filename: %s vq_search: %s\n", vq_type, vq_filename, vq_search);
+    end
+    ind = arg_exists(varargin, "vqh");
+    if ind
+      vq_type = varargin{ind};
+      vq_filename = varargin{ind+1};
+      printf("vq_type: %s vq_filename: %s vq_search: %s\n", vq_type, vq_filename, vq_search);
+    end
+    ind = arg_exists(varargin, "vql");
+    if ind
+      vq_type = varargin{ind};
+      vq_filename = varargin{ind+1};
+      printf("vq_type: %s vq_filename: %s vq_search: %s\n", vq_type, vq_filename, vq_search);
+    end
+    ind = arg_exists(varargin, "no_output");
+    if ind
+      output = 0;
+      synth_phase = 0;
+    end
+  end
+
+  printf("output: %d\n", output);
+  if (output)
+    printf("output_prefix: %s\n",  output_prefix);
+  end
+  
+  model_name = strcat(input_prefix,"_model.txt");
+  model = load(model_name);
+  [frames nc] = size(model);
+
+  voicing_name = strcat(input_prefix,"_pitche.txt");
+  voicing = zeros(1,frames);
+  
+  if exist(voicing_name, "file") == 2
+    pitche = load(voicing_name);
+    voicing = pitche(:, 3);
+  end
+
+  % Choose experiment to run test here -----------------------
+
+  if strcmp(mode, 'dct2')
+    [model_ surface] = experiment_rate_K_dct2(model, 0, 1, voicing);
+  end
+  if strcmp(mode, 'mel')
+    [model_ surface] = experiment_mel_freq(model, 0, 1, voicing);
+  end
+  if strcmp(mode, 'const')
+    [model_ surface] = experiment_const_freq(model, vq_type, vq_filename, vq_search);
+  end
+  if strcmp(mode, 'piecewise')
+    model_ = experiment_piecewise(model);
+  end
+  if strcmp(mode, 'dct')
+    model_ = experiment_dct(model);
+  end
+
+  % ----------------------------------------------------
+
+  if output
+    Am_out_name = sprintf("%s_am.out", output_prefix);
+    fam  = fopen(Am_out_name,"wb"); 
+    Wo_out_name = sprintf("%s_Wo.out", output_prefix);
+    fWo  = fopen(Wo_out_name,"wb"); 
+  
+    if synth_phase
+      Hm_out_name = sprintf("%s_hm.out", output_prefix);
+      fhm = fopen(Hm_out_name,"wb"); 
+    end
+
+    for f=1:frames
+      %printf("%d ", f);   
+      Wo = model_(f,1); L = min([model_(f,2) max_amp-1]); Am = model_(f,3:(L+2));
+      if Wo*L > pi
+        printf("Problem: %d  Wo*L > pi\n", f);   
+      end
+
+      Am_ = zeros(1,max_amp); Am_(2:L) = Am(1:L-1); fwrite(fam, Am_, "float32");
+      fwrite(fWo, Wo, "float32");
+
+      if synth_phase
+
+        % synthesis phase spectra from magnitiude spectra using minimum phase techniques
+
+        fft_enc = 256;
+        phase = determine_phase(model_, f, fft_enc);
+        assert(length(phase) == fft_enc);
+
+        % sample phase at centre of each harmonic, not 1st entry Hm[1] in octave Hm[0] in C
+        % is not used
+
+        Hm = zeros(1, 2*max_amp);
+        for m=1:L
+          b = round(m*Wo*fft_enc/(2*pi));
+          Hm(2*m) = cos(phase(b));
+          Hm(2*m+1) = -sin(phase(b));
+        end
+        fwrite(fhm, Hm, "float32");    
+      end
+    end
+   fclose(fam);
+   fclose(fWo);
+   if synth_phase
+     fclose(fhm);
+   end
+
+   % save voicing file
+  
+   if exist("voicing_", "var")
+     v_out_name = sprintf("%s_v.txt", output_prefix);
+     fv  = fopen(v_out_name,"wt"); 
+     for f=1:length(voicing_)
+       fprintf(fv,"%d\n", voicing_(f));
+     end
+     fclose(fv);
+    end
+  end
+
+  for f=1:frames
+    surface(f,:) -= mean(surface(f,:));
+  end
+
+  printf("\n")
+
+endfunction
+
+function surface = slope_and_mean_removal(surface)
+  [frames K] = size(surface);
+  for f=1:frames
+    v = surface(f,:);
+    [m b] = linreg(1:K, v, K);
+    v -= m*(1:K) + b;
+    surface(f,:) = v;
+  end
+endfunction
+
+
+function ind = arg_exists(v, str) 
+   ind = 0;
+   for i=1:length(v)
+      if strcmp(v{i}, str)
+        ind = i;
+      end     
+    end
+endfunction
+
+
+% Basic unquantised rate K linear sampling then back to rate L.  Used for generating 
+% training vectors and testing vector quntisers.
+
+function [model_ rate_K_surface] = experiment_const_freq(model, vq_type, vq_filename, vq_search="mse")
+  melvq;
+  [frames nc] = size(model);
+  Fs = 8000;
+  fg = 1;
+  quant_en = 0;
+
+  rate_K_sample_freqs_kHz = [0.1:0.1:4];
+  K = length(rate_K_sample_freqs_kHz);
+
+  % optional full band VQ
+
+  if strcmp(vq_type, "vq")
+    quant_en = 1;
+    x = load(vq_filename); vq = x.vq;
+    [vq_rows vq_cols] = size(vq); vq_st = 1; vq_en = vq_cols;
+  end
+  if strcmp(vq_type, "vql")
+    quant_en = 1;
+    x = load(vq_filename); vq = x.vq;
+    [vq_rows vq_cols] = size(vq); vq_st = 1; vq_en = vq_st + vq_cols - 1;
+  end
+
+  if strcmp(vq_type, "vqh")
+    quant_en = 1;
+    x = load(vq_filename); vq = x.vq;
+    [vq_rows vq_cols] = size(vq); vq_st = 11; vq_en = K;
+  end
+
+  energy = zeros(1,frames);
+  for f=1:frames
+    L = model(f,2);
+    energy(f) = 10*log10(sum( model(f,3:(L+2)) .^ 2 ));
+  end
+
+  rate_K_surface = resample_const_rate_f(model, rate_K_sample_freqs_kHz, Fs);
+
+  rate_K_surface_fit = zeros(frames,K);
+  b = zeros(1,frames);
+
+  for f=1:frames
+    b(f) = mean(rate_K_surface(f,:));
+    rate_K_surface_fit(f,:) = rate_K_surface(f,:) - b(f);
+  end
+  % optional vector quantise
+  
+  if quant_en
+    rate_K_surface_fit_ = rate_K_surface_fit;
+    res = zeros(frames, vq_cols); ind = [];
+
+    for f=1:frames
+      target = rate_K_surface_fit(f, vq_st:vq_en);
+
+      if strcmp(vq_search, "mse")
+        [idx contrib errors test_ g mg sl] = vq_search_mse(vq, target);
+        rate_K_surface_fit_(f, vq_st:vq_en) = contrib;
+      end
+
+      if strcmp(vq_search, "slope")
+        [idx contrib errors test_ g mg sl] = vq_search_slope(vq, target);
+        rate_K_surface_fit_(f, vq_st:vq_en) = contrib;
+      end
+      
+      res(f, vq_st:vq_en) = target - contrib;
+      ind = [ind idx];
+    end
+    
+    figure(fg++); clf; mesh(res);
+    sd_per_frame = std(res(:,vq_st:vq_en)');
+    figure(fg++); subplot(211); plot(energy); subplot(212); plot(sd_per_frame);
+    figure(fg++); subplot(211); hist(sd_per_frame); subplot(212); hist(ind,100);
+    printf("VQ rms SD: %3.2f\n", mean(sd_per_frame));
+  else
+    rate_K_surface_fit_ = rate_K_surface_fit;
+  end
+
+  for f=1:frames
+    rate_K_surface_(f,:) = rate_K_surface_fit_(f,:) + b(f);
+  end
+
+  [model_ AmdB_] = resample_rate_L(model, rate_K_surface_, rate_K_sample_freqs_kHz, Fs);
+
+  % Measure distortion between AmdB and AmdB_, ths includes distortion
+  % in the rate K <-> L transition.  Can optionally plot distorted
+  % frames
+
+  plot_sd_thresh = 5;
+  sd = zeros(1,frames);
+  for f=1:frames
+    Wo = model(f,1);
+    L = model(f,2);
+    AmdB = 20*log10(model(f,3:(L+2)));
+    sd(f) = std(AmdB(1:L) - AmdB_(f,1:L));
+    if (sd(f) > plot_sd_thresh) && (fg < 10)
+      printf("fg: %d f: %d\n", fg, f);
+      figure(fg++); clf; plot((1:L)*Wo*4/pi, AmdB(1:L),'b+-'); hold on; plot((1:L)*Wo*4/pi, AmdB_(f,1:L),'r+-');
+      plot(rate_K_sample_freqs_kHz, rate_K_surface_(f,:), 'c+-'); hold off;
+     end
+  end
+  printf("rate K resampling SD: %3.2f\n", mean(sd));
+  figure(fg++); clf; subplot(211); plot(energy); subplot(212); plot(sd); title('sdL');
+  figure(fg++); clf; hist(sd);
+endfunction
+
+
+function model_ = experiment_dct(model)
+
+  [frames tmp] = size(model); max_amp = 160;
+
+  for f=1:frames
+    printf("%d ", f);   
+    Wo = model(f,1);
+    L = min([model(f,2) max_amp-1]);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+
+    % fit model
+
+    D = dct(AmdB);
+    E = zeros(1,L);
+    E(1:min(20,L)) = D(1:min(20,L));
+    AmdB_ = idct(D);
+
+    model_(f,1) = Wo; model_(f,2) = L; model_(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
+  end
+
+endfunction
+
+
+% -----------------------------------------------------------------------------------------
+% Linear decimator/interpolator that operates at rate K, includes VQ, post filter, and Wo/E
+% quantisation.  Evolved from abys decimator below.  Simulates the entire encoder/decoder.
+
+function [model_ voicing_ indexes] = experiment_rate_K_dec(model, voicing)
+  max_amp = 80;
+  [frames nc] = size(model);
+  model_ = zeros(frames, max_amp+3);
+  indexes = zeros(frames,4);
+
+  M = 4;
+  % create frames x K surface.  TODO make all of this operate frame by
+  % frame, or at least M/2=4 frames rather than one big chunk
+
+  K = 20; 
+  [surface sample_freqs_kHz] = resample_const_rate_f_mel(model, K);
+  target_surface = surface;
+
+  figure(1);
+  mesh(surface);
+
+  % VQ rate K surface.  TODO: If we are decimating by M/2=4 we really
+  % only need to do this every 4th frame.
+
+  melvq;
+  load train_120_vq; m=5;
+       
+  for f=1:frames
+    mean_f(f) = mean(surface(f,:));
+    surface_no_mean(f,:) = surface(f,:) - mean_f(f);
+  end
+  figure(2);
+  mesh(surface_no_mean);
+
+  [res surface_no_mean_ ind] = mbest(train_120_vq, surface_no_mean, m);
+  indexes(:,1:2) = ind;
+
+  for f=1:frames
+    surface_no_mean_(f,:) = post_filter(surface_no_mean_(f,:), sample_freqs_kHz, 1.5);
+  end
+  figure(3);
+  mesh(surface_no_mean_);
+    
+  surface_ = zeros(frames, K);
+  energy_q = create_energy_q;
+  for f=1:frames   
+    [mean_f_ indx] = quantise(energy_q, mean_f(f));
+    indexes(f,3) = indx - 1;
+    %mean_f_ = mean_f(f);
+    surface_(f,:) = surface_no_mean_(f,:) + mean_f_;
+  end
+
+  figure();
+  mesh(surface_);
+
+  % break into segments of M frames.  We have 3 samples in M frame
+  % segment spaced M/2 apart and interpolate the rest.  This evolved
+  % from AbyS scheme below but could be simplified to simple linear
+  % interpolation, or using 3 or 4 points but shift of M/2=4 frames.
+  
+  interpolated_surface_ = zeros(frames, K);
+  for f=1:M:frames-M
+    left_vec = surface_(f,:);
+    right_vec = surface_(f+M,:);
+    sample_points = [f f+M];
+    resample_points = f:f+M-1;
+    for k=1:K
+      interpolated_surface_(resample_points,k) = interp_linear(sample_points, [left_vec(k) right_vec(k)], resample_points);
+    end    
+  end
+
+  % break into segments for purposes of Wo interpolation
+
+  for f=1:M:frames
+    % quantise Wo
+
+    % UV/V flag is coded using a zero index for Wo, this means we need to
+    % adjust Wo index slightly for the lowest Wo V frames
+
+    if voicing(f)
+      index = encode_log_Wo(model(f,1), 6);
+      if index == 0
+        index = 1;
+      end
+      indexes(f,4) = index;
+      model_(f,1) = decode_log_Wo(indexes(f,4), 6);
+    else
+      indexes(f,4) = 0;
+      model_(f,1) = 2*pi/100;
+    end
+  end      
+
+
+  voicing_ = zeros(1, frames);
+  for f=1:M:frames-M
+
+    Wo1_ = model_(f,1);
+    Wo2_ = model_(f+M,1);
+
+    % uncomment to use unquantised values
+    %Wo1_ = model(f,1);
+    %Wo2_ = model(f+M,1);
+
+    if !voicing(f) && !voicing(f+M)
+       model_(f:f+M-1,1) = 2*pi/100;
+    end
+
+    if voicing(f) && !voicing(f+M)
+       model_(f:f+M/2-1,1) = Wo1_;
+       model_(f+M/2:f+M-1,1) = 2*pi/100;
+       voicing_(f:f+M/2-1) = 1;
+    end
+
+    if !voicing(f) && voicing(f+M)
+       model_(f:f+M/2-1,1) = 2*pi/100;
+       model_(f+M/2:f+M-1,1) = Wo2_;
+       voicing_(f+M/2:f+M-1) = 1;
+    end
+
+    if voicing(f) && voicing(f+M)
+      Wo_samples = [Wo1_ Wo2_];
+      model_(f:f+M-1,1) = interp1([f f+M], Wo_samples, f:f+M-1, "linear", 0);
+      voicing_(f:f+M-1) = 1;
+    end
+
+    #{
+    printf("f: %d f+M/2: %d Wo: %f %f (%f %%) v: %d %d \n", f, f+M/2, model(f,1), model(f+M/2,1), 100*abs(model(f,1) - model(f+M/2,1))/model(f,1), voicing(f), voicing(f+M/2));
+    for i=f:f+M/2-1
+      printf("  f: %d v: %d v_: %d Wo: %f Wo_: %f\n", i, voicing(i), voicing_(i), model(i,1),  model_(i,1));
+    end
+    #}
+  end
+  model_(frames-M:frames,1) = pi/100; % set end frames to something sensible
+
+  % enable these to use original (non interpolated) voicing and Wo
+  %voicing_ = voicing;
+  %model_(:,1) = model(:,1);
+
+  model_(:,2) = floor(pi ./ model_(:,1)); % calculate L for each interpolated Wo
+  model_ = resample_rate_L(model_, interpolated_surface_, sample_freqs_kHz);
+
+endfunction
+
+
+% ---------------------------------------------------------------------------------------
+% Stand alone decoder that takes indexes and creates model_, models
+% decoder and an important step in proving everything works
+function [model_ voicing_] = model_from_indexes(indexes)
+  max_amp = 80;  K = 20;  M = 4;
+
+  [frames nc] = size(indexes);
+  model = model_ = zeros(frames, max_amp+3);
+  sample_freqs_kHz = mel_sample_freqs_kHz(K);
+  energy_q = 10 + 40/16*(0:15);
+
+  melvq;
+  load train_120_vq;
+
+  % decode vector quantised surface
+
+  surface_no_mean_ = zeros(frames,K);
+  surface_ = zeros(frames, K);
+  for f=1:M:frames
+    surface_no_mean_(f,:) = train_120_vq(indexes(f,1),:,1) + train_120_vq(indexes(f,2),:,2);
+    surface_no_mean_(f,:) = post_filter(surface_no_mean_(f,:), sample_freqs_kHz, 1.5);
+    mean_f_ = energy_q(indexes(f,3)+1);
+    surface_(f,:) = surface_no_mean_(f,:) + mean_f_;
+  end
+    
+  % break into segments of M frames.  We have 2 samples spaced M apart
+  % and interpolate the rest.
+  
+  interpolated_surface_ = zeros(frames, K);
+  for f=1:M:frames-M
+    left_vec = surface_(f,:);
+    right_vec = surface_(f+M,:);
+    sample_points = [f f+M];
+    resample_points = f:f+M-1;
+    for k=1:K
+      interpolated_surface_(resample_points,k) = interp_linear(sample_points, [left_vec(k) right_vec(k)], resample_points);
+    end    
+  end
+
+  % recover Wo and voicing
+
+  voicing = zeros(1, frames);
+  for f=1:M:frames
+    if indexes(f,4) == 0
+      voicing(f) = 0;
+      model(f,1) = 2*pi/100;
+    else
+      voicing(f) = 1;
+      model(f,1) = decode_log_Wo(indexes(f,4), 6);
+    end
+  end
+
+  % break into M segments for purposes of Wo interpolation
+
+  voicing_ = zeros(1, frames);
+  for f=1:M:frames-M
+
+    Wo1_ = model(f,1);
+    Wo2_ = model(f+M,1);
+
+    if !voicing(f) && !voicing(f+M)
+       model_(f:f+M-1,1) = 2*pi/100;
+    end
+
+    if voicing(f) && !voicing(f+M)
+       model_(f:f+M/2-1,1) = Wo1_;
+       model_(f+M/2:f+M-1,1) = 2*pi/100;
+       voicing_(f:f+M/2-1) = 1;
+    end
+
+    if !voicing(f) && voicing(f+M)
+       model_(f:f+M/2-1,1) = 2*pi/100;
+       model_(f+M/2:f+M-1,1) = Wo2_;
+       voicing_(f+M/2:f+M-1) = 1;
+    end
+
+    if voicing(f) && voicing(f+M)
+      Wo_samples = [Wo1_ Wo2_];
+      model_(f:f+M-1,1) = interp_linear([f f+M], Wo_samples, f:f+M-1);
+      voicing_(f:f+M-1) = 1;
+    end
+
+    #{
+    printf("f: %d f+M/2: %d Wo: %f %f (%f %%) v: %d %d \n", f, f+M/2, model(f,1), model(f+M/2,1), 100*abs(model(f,1) - model(f+M/2,1))/model(f,1), voicing(f), voicing(f+M/2));
+    for i=f:f+M/2-1
+      printf("  f: %d v: %d v_: %d Wo: %f Wo_: %f\n", i, voicing(i), voicing_(i), model(i,1),  model_(i,1));
+    end
+    #}
+  end
+  model_(frames-M:frames,1) = pi/100; % set end frames to something sensible
+
+  % enable these to use original (non interpolated) voicing and Wo
+  %voicing_ = voicing;
+  %model_(:,1) = model(:,1);
+
+  model_(:,2) = floor(pi ./ model_(:,1)); % calculate L for each interpolated Wo
+  model_ = resample_rate_L(model_, interpolated_surface_, sample_freqs_kHz);
+
+endfunction
+
+
+% ---------------------------------------------------------------------------------------
+% Stand alone decoder that takes indexes and creates model_, just like 
+% model_from_indexes above. This version is refactored to perform frame by frame
+% processing, as a stepping stone to C.
+
+function [model_ voicing_] = model_from_indexes_fbf(indexes)
+  max_amp = 80;  K = 20;  M = 4;
+
+  [frames nc] = size(indexes);
+  model = model_ = zeros(frames, max_amp+3);
+  sample_freqs_kHz = mel_sample_freqs_kHz(K);
+  energy_q = 10 + 40/16*(0:15);
+
+  melvq;
+  load train_120_vq;
+
+  surface_no_mean_ = zeros(frames,K);
+  surface_ = zeros(frames, K);
+  interpolated_surface_ = zeros(frames, K);
+  voicing = zeros(1, frames);
+  voicing_ = zeros(1, frames);
+
+  for f=1:M:frames
+    % decode vector quantised surface
+
+    surface_no_mean_(f,:) = train_120_vq(indexes(f,1),:,1) + train_120_vq(indexes(f,2),:,2);
+    surface_no_mean_(f,:) = post_filter(surface_no_mean_(f,:), sample_freqs_kHz, 1.5);
+    mean_f_ = energy_q(indexes(f,3)+1);
+    surface_(f,:) = surface_no_mean_(f,:) + mean_f_;
+
+    % break into segments of M frames.  We have 2 samples spaced M apart
+    % and interpolate the rest.
+
+    if f > M
+      left_vec = surface_(f-M,:);
+      right_vec = surface_(f,:);
+      sample_points = [f-M f];
+      resample_points = f-M:f-1;
+      for k=1:K
+        interpolated_surface_(resample_points,k) = interp_linear(sample_points, [left_vec(k) right_vec(k)], resample_points);
+      end    
+    end
+
+    % recover Wo and voicing
+
+    if indexes(f,4) == 0
+      voicing(f) = 0;
+      model(f,1) = 2*pi/100;
+    else
+      voicing(f) = 1;
+      model(f,1) = decode_log_Wo(indexes(f,4), 6);
+    end
+
+    if f > M
+      Wo1 = model(f-M,1);
+      Wo2 = model(f,1);
+
+      [Wo_ avoicing_] = interp_Wo_v(Wo1, Wo2, voicing(f-M), voicing(f));
+      model_(f-M:f-1,1) = Wo_;
+      voicing_(f-M:f-1) = avoicing_;
+      model_(f-M:f-1,2) = floor(pi ./ model_(f-M:f-1,1)); % calculate L for each interpolated Wo
+    end
+
+  end
+  
+  model_(frames-M:frames,1) = pi/100; % set end frames to something sensible
+  model_(frames-M:frames,2) = floor(pi ./ model_(frames-M:frames,1));
+
+  model_ = resample_rate_L(model_, interpolated_surface_, sample_freqs_kHz);
+
+endfunction
+
+
+
+% ---------------------------------------------------------------------------------------
+% Various experiments tried during development
+
+% rate K mel-resampling, high end correction, and DCT experiment workhorse
+
+function [model_ rate_K_surface] = experiment_rate_K_dct2(model, vq_en=0, plots=1, voicing)
+  [frames nc] = size(model);
+  K = 20; Fs = 8000; correct_rate_K_en = 1;
+
+  %quantisers = load("dct2quant.txt"); 
+  %nlevels = load("dct2quantnlevels.txt");
+  %map = load("dct2map.txt");
+
+  for f=1:frames
+    Wo = model(f,1);
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+    Am_freqs_kHz = (1:L)*Wo*4/pi;
+    [rate_K_vec rate_K_sample_freqs_kHz] = resample_const_rate_f_mel(model(f,:), K);
+    if correct_rate_K_en
+      [tmp_ AmdB_] = resample_rate_L(model(f,:), rate_K_vec, rate_K_sample_freqs_kHz);
+      [rate_K_vec_corrected orig_error error nasty_error_log nasty_error_m_log] = correct_rate_K_vec(rate_K_vec, rate_K_sample_freqs_kHz, AmdB, AmdB_, K, Wo, L, Fs);
+      rate_K_surface(f,:) = rate_K_vec_corrected;
+    else
+      rate_K_surface(f,:) = rate_K_vec;
+    end
+  end
+
+  % break into 160ms blocks, 2D DCT, truncate, IDCT
+
+  Tf = 0.01;   % frame period in seconds
+  Nt = 16;     % number of 10ms frames blocks in time
+  dec = 2;     % decimation factor
+  dist_dB = 2; % use enough coefficients to get this distortion ond DCT coeffs
+
+  Nblocks = floor(frames/(Nt*dec));
+  printf("frames: %d Nblocks: %d\n", frames, Nblocks);
+
+  unwrapped_dcts = zeros(Nblocks,Nt*K);
+  rate_K_surface_ = zeros(frames, K);
+  
+  % create map on the fly from train database
+
+  asurf = load("all_surf.txt"); [nr nc] = size(asurf);
+  asurf = asurf(1:dec:nr,:);
+  [map rms_map mx mx_ind unwrapped_dcts] = create_map_rms(asurf, Nt, K);
+  %map = create_zigzag_map(Nt,K);
+
+  %printf("non zero coeffs: %d\n", sum(sum(map == 1)));
+  figure(2); clf;
+  mesh(map);
+  sumnz = zeros(1,Nblocks);
+  dct2_sd = zeros(1,Nblocks);
+
+  % create quantiser_num to r,c Luts
+
+  rmap = cmap = zeros(1,Nt*K);
+  for r=1:Nt
+    for c=1:K
+       quantiser_num = map(r,c);
+       rmap(quantiser_num) = r;
+       cmap(quantiser_num) = c;
+    end
+  end
+
+  for n=1:Nblocks
+    st = (n-1)*dec*Nt+1; en = st + dec*Nt - 1;
+    %printf("st: %d en: %d\n", st, en);
+    D = dct2(rate_K_surface(st:dec:en,:));
+
+    % move over surface and work out quantiser
+    % quantise, replace on map
+
+    E = mapped = zeros(Nt,K);
+    #{
+    for r=1:Nt
+      for c=1:K
+        quantiser_num = map(r,c);
+        if quantiser_num <= 40
+          %printf("r %d c %d quantiser_num %d nlevels %d ", r, c, quantiser_num, nlevels(quantiser_num));
+          %levels = quantisers(quantiser_num, 1:nlevels(quantiser_num));
+          %quant_out = quantise(levels, D(r,c));
+          E(r,c) = D(r,c);
+          if E(r,c)
+            mapped(r,c) = 1;
+            sumnz(n)++;
+          end
+        end
+      end
+    end
+    #}
+
+    qn = 0;
+    adct2_sd = mean(std(D-E));
+    while adct2_sd > dist_dB
+      qn++;
+      E(rmap(qn), cmap(qn)) = 1*round(D(rmap(qn), cmap(qn))/1);
+      adct2_sd = mean(std(D-E));
+      %printf("qn %d %f\n", qn, adct2_sd);
+    end
+    sumnz(n) = qn;
+
+    % note neat trick to interpolate to 10ms frames despite dec
+
+    #{
+    energy = sum(sum(E));
+    Edc = E(1,1);
+    E = E*1.2;
+    E(1,1) = Edc/1.2;
+    #}
+    %E *= energy/sum(sum(E));
+    rate_K_surface_(st:en,:) = idct2([sqrt(dec)*E; zeros(Nt*(dec-1), K)]);
+
+    dct2_sd(n) = mean(std(D-E));
+  end
+
+  % figure(3); clf; mesh(mapped);
+  figure(4); clf; plot(sumnz); hold on; plot([1 length(sumnz)],[mean(sumnz) mean(sumnz)]); hold off; title('Non Zero');
+  figure(5); clf; plot(dct2_sd); title('DCT SD');
+  printf("average dct spectral distortion: %3.2f dB\n", mean(dct2_sd));
+  printf("mean number of coeffs/DCT: %3.2f/%d\n", mean(sumnz), Nt*K);
+  printf("coeffs/second: %3.2f\n", mean(sumnz)/(Nt*Tf*dec));
+  printf("bits/s: %3.2f\n", 2.9*mean(sumnz)/(Nt*Tf*dec));
+
+  % optional 700C style post filter
+
+  post_filter_en = 0;
+  if post_filter_en
+    for f=1:Nt*Nblocks
+      mn = mean(rate_K_surface_(f,:));
+      rate_K_surface_no_mean_(f,:) =  rate_K_surface_(f,:) - mn;
+      rate_K_surface_(f,:) = mn + post_filter(rate_K_surface_no_mean_(f,:), rate_K_sample_freqs_kHz);
+    end
+  end
+
+  % prevent /0 errors at end of run
+
+  rate_K_surface_(dec*Nt*Nblocks+1:frames,:) = rate_K_surface(dec*Nt*Nblocks+1:frames,:); 
+  model_ = resample_rate_L(model, rate_K_surface_, rate_K_sample_freqs_kHz);
+  
+  dist = std((rate_K_surface_(1:dec:frames,:) - rate_K_surface(1:dec:frames,:))');
+  figure(1); clf; plot(dist); title('Rate K SD');
+  printf("Rate K spectral distortion mean: %3.2f dB var: %3.2f\n", mean(dist), var(dist));
+endfunction
+
+
+% Basic unquantised rate K mel-sampling then back to rate L.  Now with "high end correction"
+
+function [model_ rate_K_surface] = experiment_mel_freq(model, vq_en=0, plots=1, voicing)
+  [frames nc] = size(model);
+  K = 20; Fs = 16000; correct_rate_K_en = 0;
+
+  for f=1:frames
+    Wo = model(f,1);
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+    Am_freqs_kHz = (1:L)*Wo*Fs/(2000*pi);
+    [rate_K_vec rate_K_sample_freqs_kHz] = resample_const_rate_f_mel(model(f,:), K, Fs);
+    if correct_rate_K_en
+      [tmp_ AmdB_] = resample_rate_L(model(f,:), rate_K_vec, rate_K_sample_freqs_kHz, Fs);
+      [rate_K_vec_corrected orig_error error nasty_error_log nasty_error_m_log] = correct_rate_K_vec(rate_K_vec, rate_K_sample_freqs_kHz, AmdB, AmdB_, K, Wo, L, Fs);
+      rate_K_surface(f,:) = rate_K_vec_corrected;
+    else
+      rate_K_surface(f,:) = rate_K_vec;
+    end
+  end
+
+  model_ = resample_rate_L(model, rate_K_surface, rate_K_sample_freqs_kHz, Fs);
+endfunction
+
+
+
+% mel spaced sampling, differential in time VQ.  Curiously, couldn't
+% get very good results out of this, I suspect a bug
+
+function [model_ rate_K_surface_diff] = experiment_mel_diff_freq(model, vq_en=0)
+  [frames nc] = size(model);
+  K = 20; 
+  [rate_K_surface rate_K_sample_freqs_kHz] = resample_const_rate_f_mel(model, K);
+  
+  if vq_en
+    melvq;
+    load surface_diff_vq; m=5;
+  end
+
+  for f=1:frames
+    mean_f(f,:) = mean(rate_K_surface(f,:));
+    rate_K_surface_no_mean(f,:) = rate_K_surface(f,:) - mean_f(f,:);
+  end
+
+  rate_K_surface_no_mean_ = zeros(frames, K);
+  rate_K_surface_no_mean_diff = zeros(frames, K);
+  rate_K_surface_(1,:) = rate_K_surface_diff(1,:) = zeros(1, K);
+
+  for f=2:frames
+    rate_K_surface_diff(f,:) = rate_K_surface_no_mean(f,:) - 0.8*rate_K_surface_no_mean_(f-1,:);
+    if vq_en
+      [res arate_K_surface_diff_ ind] = mbest(surface_diff_vq, rate_K_surface_diff(f,:), m);
+      rate_K_surface_diff_(f,:) = arate_K_surface_diff_;
+    else
+      rate_K_surface_diff_(f,:) = rate_K_surface_diff(f,:);
+    end
+    rate_K_surface_no_mean_(f,:) = 0.8*rate_K_surface_no_mean_(f-1,:) + rate_K_surface_diff_(f,:);
+  end
+  
+  for f=1:frames
+    rate_K_surface_(f,:) = rate_K_surface_no_mean_(f,:) + mean_f(f,:);
+  end
+
+  model_ = resample_rate_L(model, rate_K_surface_, rate_K_sample_freqs_kHz);
+
+endfunction
+
+
+% try vq with open and closed loop mean removal, turns out they give
+% identical results lol
+
+function [model_ rate_K_surface] = experiment_closed_loop_mean(model)
+  [frames nc] = size(model);
+  K = 15; 
+  mel_start = ftomel(300); mel_end = ftomel(3000); 
+  step = (mel_end-mel_start)/(K-1);
+  mel = mel_start:step:mel_end;
+  rate_K_sample_freqs_Hz = 700*((10 .^ (mel/2595)) - 1);
+  rate_K_sample_freqs_kHz = rate_K_sample_freqs_Hz/1000;
+
+  rate_K_surface = resample_const_rate_f(model, rate_K_sample_freqs_kHz);
+  
+  load surface_vq; m=1;
+   
+  for f=1:frames
+    amean = mean(rate_K_surface(f,:));
+    rate_K_target_no_mean = rate_K_surface(f,:) - amean;
+    mse_open_loop(f) = search_vq2(surface_vq(:,:,1), rate_K_target_no_mean, m, 0);
+    mse_closed_loop(f) = search_vq2(surface_vq(:,:,1), rate_K_surface(f,:), m, 1);
+  end
+
+  printf("rms open loop..: %f\nrms closed loop: %f\n", sqrt(mean(mse_open_loop)), sqrt(mean(mse_closed_loop)));
+
+  % just return model_ as we have to so nothing breaks, it's not actually useful
+
+  model_ = resample_rate_L(model, rate_K_surface, rate_K_sample_freqs_kHz);
+    
+endfunction
+
+
+% Experiment with 10ms update rate for energy but 40ms update for spectrum,
+% using linear interpolation for spectrum.
+
+function model_c = experiment_energy_rate_linear(model, vq_en, plot_en)
+  max_amp = 80;
+  [frames nc] = size(model);
+
+  % 10ms mel freq modelling and VQ
+
+  model_ = experiment_mel_freq(model, vq_en, plot_en);
+
+  % Remove energy.  Hmmmm, this is done on Ams rather than surface but that's
+  % similar I guess
+
+  e = zeros(1,frames);
+  model_a = zeros(frames,max_amp+3);
+  for f=1:frames
+    L = min([model_(f,2) max_amp-1]);
+    Am_ = model_(f,3:(L+2));
+    AmdB_ = 20*log10(Am_);
+    mean_f(f) = mean(AmdB_);
+    AmdB_ -= mean_f(f);
+    model_a(f,1) = model_(f,1); model_a(f,2) = L; model_a(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
+  end
+
+  % linear interp after removing energy (mean AmdB)
+
+  model_b = experiment_dec_linear(model_a);
+
+  % add back in energy
+
+  model_c = zeros(frames,max_amp+3);
+  for f=1:frames
+    L = min([model_b(f,2) max_amp-1]);
+    Am_ = model_b(f,3:(L+2));
+    AmdB_ = 20*log10(Am_);
+    AmdB_ += mean_f(f);
+    model_c(f,1) = model_b(f,1); model_c(f,2) = L; model_c(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
+  end
+
+endfunction
+
+
+% conventional decimation in time without any filtering, then linear
+% interpolation.  Linear interpolation is a two-tap (weak) form of fir
+% filtering that may have problems with signals with high freq
+% components, for example after quantisation noise is added.  Need to
+% look into this some more.
+function model_ = experiment_dec_linear(model)
+  newamp;
+  max_amp = 80;
+
+  [frames nc] = size(model);
+  model_ = zeros(frames, max_amp+3);
+  decimate = 4;
+  for f=1:frames    
+    AmdB_ = decimate_frame_rate(model, decimate, f, frames);
+    L = length(AmdB_);
+    model_(f,1) = model(f,1); model_(f,2) = L; model_(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
+  end
+endfunction
+
+
+
+% Experimental AbyS decimator that chooses best frames to match
+% surface based on AbyS approach.  Can apply post filter at different
+% points, and optionally do fixed decimation, at rate K.  Didn't
+% produce anything spectacular in AbyS mode, suggest another look with
+% some sort of fbf display to see what's going on internally.
+function model_ = experiment_dec_abys(model, M=8, vq_en=0, pf_en=1, fixed_dec=0, voicing)
+  max_amp = 80;
+  [frames nc] = size(model);
+  model_ = zeros(frames, max_amp+3);
+
+  printf("M: %d vq_en: %d pf_en: %d fixed_dec: %d\n", M, vq_en, pf_en, fixed_dec)
+
+  % create frames x K surface
+
+  K = 20; 
+  [surface sample_freqs_kHz] = resample_const_rate_f_mel(model, K);
+  target_surface = surface;
+
+  % optionaly VQ surface
+
+  if vq_en
+    melvq;
+    load train_120_vq; m=5;
+       
+    for f=1:frames
+      mean_f(f) = mean(surface(f,:));
+      rate_K_surface_no_mean(f,:) = surface(f,:) - mean_f(f);
+    end
+
+    [res rate_K_surface_ ind] = mbest(train_120_vq, rate_K_surface_no_mean, m);
+
+    if pf_en == 1
+      for f=1:frames
+        rate_K_surface_(f,:) = post_filter(rate_K_surface_(f,:), sample_freqs_kHz, 1.5, voicing(f));
+      end
+    end
+    
+    for f=1:frames
+      rate_K_surface_(f,:) += mean_f(f);
+    end
+
+    surface = rate_K_surface_;
+  end
+
+  % break into segments of M frames.  Fix end points, that two of the
+  % frames we sample.  Then find best choice in between
+
+  surface_ = zeros(frames, K);
+  best_surface_ = zeros(frames, K);
+
+  for f=1:M:frames-M
+
+    left_vec = surface(f,:);
+    right_vec = surface(f+M,:);
+    resample_points = f:f+M-1;
+    best_mse = 1E32;
+    best_m = f+1;
+    
+
+    if fixed_dec
+      m = f+M/2;
+      printf("%d %d %d\n", f, m, M+f);
+      centre_vec = surface(m,:);
+      sample_points = [f m f+M];
+      for k=1:K
+        best_surface_(resample_points,k)  = interp1(sample_points, [left_vec(k) centre_vec(k) right_vec(k)], resample_points, "spline", 0);
+      end 
+    else
+      printf("%d %d\n", f, M+f);
+      for m=f+1:M+f-2
+
+        % Use interpolation to construct candidate surface_ segment 
+        % using just threee samples
+
+        centre_vec = surface(m,:);
+        sample_points = [f m f+M];
+        mse = 0;
+        for k=1:K
+          surface_(resample_points,k)  = interp1(sample_points, [left_vec(k) centre_vec(k) right_vec(k)], resample_points, "spline", 0);
+          mse += sum((target_surface(resample_points,k) - surface_(resample_points,k)).^2);
+        end 
+
+        % compare synthesised candidate to orginal and chose min ased on MSE
+
+        if mse < best_mse
+          best_mse = mse;
+          best_m = m;
+          best_surface_(resample_points,:) = surface_(resample_points,:);
+        end
+
+        printf("  m: %d mse: %f best_mse: %f best_m: %d\n", m, mse, best_mse, best_m);
+      end
+    end
+  end
+
+  if pf_en == 2
+
+    % Optionally apply pf after interpolation, theory is interpolation
+    % smooths spectrum in time so post filtering afterwards may be
+    % useful.  Note we remove mean, this tends to move formats up and
+    % anti-formants down when we multiply by a constant
+
+    for f=1:frames
+      mean_f = mean(best_surface_(f,:));
+      rate_K_vec_no_mean = best_surface_(f,:) - mean_f;
+      rate_K_vec_no_mean *= 1.2;
+      best_surface_(f,:) = rate_K_vec_no_mean + mean_f;
+    end
+  end
+
+  model_ = resample_rate_L(model, best_surface_, sample_freqs_kHz);
+  figure(5);
+  plot(mean_f,'+-')
+  figure(6)
+  hist(mean_f)
+endfunction
+
+
+#{ 
+  Filtering time axis or surface, as a first step before decimation.
+  So given surface, lets look at spectral content and see if we can
+  reduce it while maintaining speech quality.  First step is to dft
+  across time and plot.
+
+  This just has one filtering step, which may help quantisation.  In practice
+  we may need filtering before decimation and at the inerpolation stage
+#}
+
+function model_ =  experiment_filter(model)
+  [frames nc] = size(model);
+  K = 40; rate_K_sample_freqs_kHz = (1:K)*4/K;
+  [rate_K_surface rate_K_sample_freqs_kHz] = resample_const_rate_f(model, rate_K_sample_freqs_kHz);
+  
+  Nf = 4; Nf2 = 6;
+  [b a]= cheby1(4, 1, 0.20);
+  %Nf = 20; Nf2 = 10;
+  %b = fir1(Nf, 0.25); a = [1 zeros(1, Nf)];
+  %Nf = 1; Nf2 = 1;
+  %b = 1; a = [1 zeros(1, Nf)];
+
+  %Nf = 2; Nf2 = 1;
+  %beta = 0.99; w = pi/4;
+  %b = [1 -2*beta*cos(w) beta*beta]; a = [1 zeros(1, Nf)];
+  %Nf = 10; Nf2 = 10;
+  %b = fir2(10, [0 0.2 0.3 1], [1 1 0.1 0.1]); a = [1 zeros(1, Nf)];
+
+  %Nf = 1; Nf2 = 1;
+  dft_surface = zeros(frames,K);
+  rate_K_surface_filt = zeros(frames,K);
+  dft_surface_filt = zeros(frames,K);
+  for k=1:K
+    dft_surface(:,k) = fft(rate_K_surface(:,k).*hanning(frames));
+    %rate_K_surface_filt(:,k) = filter(b, a, rate_K_surface(:,k));
+    rate_K_surface_filt(:,k) = filter(b, a,  rate_K_surface(:,k));
+    dft_surface_filt(:,k) = fft(rate_K_surface_filt(:,k).*hanning(frames));
+  end
+  figure(1); clf;
+  mesh(abs(dft_surface))
+  figure(2); clf;
+  mesh(abs(dft_surface_filt))
+
+  Fs = 100; Ts = 1/Fs;
+  figure(3);
+  subplot(211);
+  h = freqz(b,a,Fs/2);
+  plot(1:Fs/2, 20*log10(abs(h)))
+  axis([1 Fs/2 -40 0])
+  ylabel('Gain (dB)')
+  grid;
+  subplot(212)
+  [g w] = grpdelay(b,a);
+  plot(w*Fs/pi, 1000*g*Ts)
+  %axis([1 Fs/2 0 0.5])
+  xlabel('Frequency (Hz)');
+  ylabel('Delay (ms)')
+  grid
+
+  figure(4); clf; stem(filter(b,a,[1 zeros(1,20)]))
+  
+  % adjust for time offset due to filtering
+
+  rate_K_surface_filt = [rate_K_surface_filt(Nf2:frames,:); zeros(Nf2, K)];
+
+  % back down to rate L
+
+  model_ = resample_rate_L(model, rate_K_surface_filt, rate_K_sample_freqs_kHz);
+endfunction
+
+
+% filter, decimate, zero insert, filter, simulates decimation and re-interpolation, as
+% an alternative to simple linear interpolation.
+
+function model_ =  experiment_filter_dec_filter(model)
+  [frames nc] = size(model);
+
+  % rate K surface
+
+  K = 40; rate_K_sample_freqs_kHz = (1:K)*4/K;
+  [rate_K_surface rate_K_sample_freqs_kHz] = resample_const_rate_f(model, rate_K_sample_freqs_kHz);
+  
+  % filter, not we run across each of the K bins, treating them as a 1-D sequence
+
+  Nf = 4; filter_delay = 12;
+  [b a]= cheby1(4, 1, 0.20);
+  %Nf = 10; Nf2 = Nf/2; filter_delay = Nf2*2;
+  %b = fir1(Nf, 0.25); a = [1 zeros(1, Nf)];
+  %Nf = 10; Nf2 = 2; filter_delay = 2*Nf2;
+  %b = fir2(10, [0 0.2 0.3 1], [1 1 0.1 0.1]); a = [1 zeros(1, Nf)];
+
+  rate_K_surface_filt = zeros(frames,K);
+  for k=1:K
+    rate_K_surface_filt(:,k) = filter(b, a, rate_K_surface(:,k));
+  end
+
+  % decimate from 100 to 25Hz, and zero pad, which we simulate by
+  % setting all K samples in 3 out of 4 time-samples to zero
+
+  M = 4;
+
+  for f=1:frames
+    if mod(f,M)
+      rate_K_surface_filt(f,:) = zeros(1,K);
+    end
+  end
+
+  % filter to reconstruct 100 Hz frame rate
+
+  rate_K_surface_filt_recon = zeros(frames,K);
+  for k=1:K
+    rate_K_surface_filt_recon(:,k) = filter(b, a, M*rate_K_surface_filt(:,k));
+  end
+
+  figure(1); clf;
+  mesh(rate_K_surface_filt)
+  figure(2); clf;
+  mesh(rate_K_surface_filt_recon)
+
+  % adjust for time offset due to 2 lots of filtering
+
+  rate_K_surface_filt_recon = [rate_K_surface_filt_recon(filter_delay:frames,:); zeros(filter_delay, K)];
+
+  % back down to rate L
+
+  model_ = resample_rate_L(model, rate_K_surface_filt_recon, rate_K_sample_freqs_kHz);
+endfunction
+
+
+% smoothing using masking functions
+
+function model_ = experiment_smoothed(model, bark_model=1)
+  [frames nc] = size(model);
+
+  model_ = model;
+
+  for f=1:frames
+    Wo = model(f,1);
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+    [AmdB_ Am_freqs_kHz] = mask_model(AmdB, Wo, L, bark_model);
+    model_(f,3:(L+2)) = 10 .^ ((AmdB_)/20);
+  end
+
+endfunction
+
+#{
+  
+  My original idea was to used a 3-4 "resonators" to construct a
+  piecewise model of the spectrum.  Kind of got distracted by the
+  surface and mel sampling that ended up working OK.  This method was
+  working OK, soem issues with background noise but rather easy to
+  quantise.
+
+  todo: get this working again
+#}
+
+function model_ = experiment_piecewise(model)
+
+  [frames tmp] = size(model); max_amp = 160;
+
+  fvec_log = []; amps_log = [];
+
+  for f=1:frames
+    printf("%d ", f);   
+    Wo = model(f,1);
+    L = min([model(f,2) max_amp-1]);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+    e(f) = sum(AmdB)/L;
+
+    % fit model
+
+    [AmdB_ res fvec fvec_ amps] = piecewise_model(AmdB, Wo);
+    fvec_log = [fvec_log; fvec];
+    amps_log = [amps_log; amps];
+
+    model_(f,1) = Wo; model_(f,2) = L; model_(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
+  end
+
+endfunction
+
+
+% early test, devised to test rate K<->L changes along frequency axis
+
+function model_ = resample_half_frame_offset(model, rate_K_surface, rate_K_sample_freqs_kHz)
+  max_amp = 80;
+  [frames col] = size(model);
+
+  % Check distortion by shifting half a frame and returning model for
+  % synthesis Hmm how to handle Wo?  Well lets assume it's OK and
+  % average it.  If it sounds OK then it must be OK as well and Am
+  % interpolation.  If not then will do some more thinking.
+
+  model_ = zeros(frames, max_amp+3);
+  for f=1:frames-1
+    Wo = (model(f,1) + model(f+1,1))/2;
+    L = min(pi/Wo, max_amp-1);
+    rate_L_sample_freqs_kHz = (1:L)*Wo*4/pi;
+    
+    % interpolate at half frame offset
+
+    half = 0.5*rate_K_surface(f,:) + 0.5*rate_K_surface(f+1,:);
+    
+    % back down to rate L
+
+    AmdB_ = interp1(rate_K_sample_freqs_kHz, half, rate_L_sample_freqs_kHz, "spline", "extrap");
+
+    % todo a way to save all model params ... Am, Wo, L, (v?)  Start with current facility then
+    % make it better
+
+    model_(f,1) = Wo; model_(f,2) = L; model_(f,3:(L+2)) = 10 .^ (AmdB_(1:L)/20);
+   end
+endfunction
+
+
+% vq search with optional closed loop mean estimation, turns out this gives
+% identical results to extracting the mean externally
+
+function [mse_list index_list] = search_vq2(vq, target, m, closed_loop_dc = 0)
+
+  [Nvec order] = size(vq);
+
+  mse = zeros(1, Nvec);
+
+  % find mse for each vector
+
+  for i=1:Nvec
+     if closed_loop_dc
+       sum(target - vq(i,:))
+       g = sum(target - vq(i,:))/order;
+       mse(i) = sum((target - vq(i,:) - g) .^2);
+     else
+       mse(i) = sum((target - vq(i,:)) .^2);
+    end
+  end
+
+  % sort and keep top m matches
+
+  [mse_list index_list ] = sort(mse);
+
+  mse_list = mse_list(1:m);
+  index_list = index_list(1:m);
+
+endfunction
+
+
+% helper function to plot surfaces
+
+function plot_dft_surface(surface)
+  [frames K] = size(surface);
+
+  dft_surface = zeros(frames,K);
+  for k=1:K
+    dft_surface(:,k) = fft(surface(:,k).*hanning(frames));
+  end
+
+  % Set up a meaninful freq axis.  We only need real side. Sample rate
+  % (frame rate) Fs=100Hz 
+
+  Fs = 100; dF = Fs/frames;
+  mesh(1:K, (1:frames/2)*dF, 20*log10(abs(dft_surface(1:frames/2,:,:))));
+endfunction
+
diff --git a/codec2/branches/0.7/octave/newamp1_compare.m b/codec2/branches/0.7/octave/newamp1_compare.m
new file mode 100644 (file)
index 0000000..eac9ecd
--- /dev/null
@@ -0,0 +1,56 @@
+% newamp1_compare.m
+%
+% Copyright David Rowe 2016
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Compare model, Wo, and voicing files, used for checking refactoring and C port
+
+
+function newamp1_compare(prefixa, prefixb)
+  autotest;
+
+  frames = 100;
+  a = load_params(prefixa, frames);
+  b = load_params(prefixb, frames);
+  check(a.Am, b.Am, 'Am');
+  check(a.Hm, b.Hm, 'Hm');
+  check(a.Wo, b.Wo, 'Wo');
+  check(a.v, b.v, 'v');
+
+  figure(1); clf; plot(a.v); hold on; plot(a.v-b.v,'r'); hold off;
+endfunction
+
+
+function params = load_params(prefix, frames)
+  max_amp = 80;
+  fft_enc = 512;
+
+  Am_out_name = sprintf("%s_am.out", prefix);
+  fam  = fopen(Am_out_name,"rb");
+  Wo_out_name = sprintf("%s_Wo.out", prefix);
+  fWo  = fopen(Wo_out_name,"rb"); 
+  Hm_out_name = sprintf("%s_hm.out", prefix);
+  fhm = fopen(Hm_out_name,"rb"); 
+
+  % load up values from binary files
+
+  params.Am = zeros(frames, max_amp);
+  params.Wo = zeros(frames, 1);
+  params.v = zeros(frames, 1);
+  params.Hm = zeros(frames, max_amp);
+  for f=1:frames
+    params.Am(f,:) = fread(fam, max_amp, "float32");
+    params.Wo(f)   = fread(fWo, 1, "float32");
+    params.Hm(f,:) = fread(fhm, max_amp, "float32");
+  end
+
+  fclose(fam); fclose(fWo); fclose(fhm);
+
+  % voicing is a text file
+
+  v_out_name = sprintf("%s_v.txt", prefix);
+  params.v = load(v_out_name);
+
+endfunction
diff --git a/codec2/branches/0.7/octave/newamp1_fbf.m b/codec2/branches/0.7/octave/newamp1_fbf.m
new file mode 100644 (file)
index 0000000..82c9818
--- /dev/null
@@ -0,0 +1,178 @@
+% newamp1_fbf.m
+%
+% Copyright David Rowe 2016
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Interactive Octave script to explore frame by frame operation of new amplitude
+% modelling model.
+%
+% Usage:
+%   Make sure codec2-dev is compiled with the -DDUMP option - see README for
+%    instructions.
+%   ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --dump hts1a
+%   $ cd ~/codec2-dev/octave
+%   octave:14> newamp1_fbf("../build_linux/src/hts1a",50)
+
+
+function newamp1_fbf(samname, f=73, varargin)
+  more off;
+
+  newamp;
+  melvq;
+
+  Fs = 8000; rate_K_sample_freqs_kHz = [0.1:0.1:4]; K = length(rate_K_sample_freqs_kHz);
+  quant_en = 0; vq_search = "mse";
+
+  % optional full band VQ
+
+  ind = arg_exists(varargin, "vq");
+  if ind
+    quant_en = 1;
+    vq_filename = varargin{ind+1};
+    x = load(vq_filename); vq = x.vq;
+    [vq_rows vq_cols] = size(vq); vq_st = 1; vq_en = vq_cols;
+  end
+  
+  % optional split VQ low freq quantiser
+
+  ind = arg_exists(varargin, "vql");
+  if ind
+    quant_en = 1;
+    vq_filename = varargin{ind+1};
+    x = load(vq_filename); vq = x.vq;
+    [vq_rows vq_cols] = size(vq); vq_st = 1; vq_en = vq_st + vq_cols - 1;
+  end
+  
+  % optional split VQ high freq quantiser
+
+  ind = arg_exists(varargin, "vqh");
+  if ind
+    quant_en = 1;
+    vq_filename = varargin{ind+1};
+    x = load(vq_filename); vq = x.vq;
+    [vq_rows vq_cols] = size(vq); vq_st = 11; vq_en = K;
+  end
+
+  % different vq search algorithms
+
+  ind = arg_exists(varargin, "vq_search");
+  if ind
+    vq_search = varargin{ind+1};
+  end
+
+  fit_order = 0;
+  ind = arg_exists(varargin, "noslope");
+  if ind
+    fit_order = 1;
+  end
+
+  if quant_en
+    printf("quant_en: %d vq_filename: %s vq_st: %d vq_en: %d vq_search: %s\n", 
+           quant_en, vq_filename, vq_st, vq_en, vq_search);
+  end
+
+  % load up text files dumped from c2sim ---------------------------------------
+
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+  [frames tmp] = size(model);
+
+  % Keyboard loop --------------------------------------------------------------
+
+  k = ' ';
+  do 
+    s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+    figure(1); clf; plot(s); axis([1 length(s) -20000 20000]);
+
+    Wo = model(f,1); L = model(f,2); Am = model(f,3:(L+2)); AmdB = 20*log10(Am);
+    Am_freqs_kHz = (1:L)*Wo*4/pi;
+
+    % remove constant gain term
+
+    rate_K_vec = resample_const_rate_f(model(f,:), rate_K_sample_freqs_kHz, Fs);
+    if fit_order == 0
+      slope = 0; b = mean(rate_K_vec); 
+      rate_K_vec_fit = rate_K_vec - b;
+    end
+
+    % plots ----------------------------------
+  
+    figure(2); clf; 
+    plot((1:L)*Wo*4000/pi, AmdB,";AmdB;g+-");
+    axis([1 4000 -20 80]);
+    hold on;
+    plot(rate_K_sample_freqs_kHz*1000, rate_K_vec, ";rate K;b+-");
+
+    if quant_en
+      target = rate_K_vec_fit(vq_st:vq_en);
+      
+      if strcmp(vq_search, "mse")
+        [idx contrib errors test_ g mg sl] = vq_search_mse(vq, target);
+        rate_K_surface_fit_(f, vq_st:vq_en) = contrib;
+      end
+
+      if strcmp(vq_search, "slope")
+        [idx contrib errors test_ g mg sl] = vq_search_slope(vq, target);
+        rate_K_surface_fit_(f, vq_st:vq_en) = contrib;
+      end
+
+      rate_K_vec_ = rate_K_vec_fit; rate_K_vec_(vq_st:vq_en) = contrib;
+      rate_K_vec_ += b;
+      [model_ AmdB_] = resample_rate_L(model(f,:), rate_K_vec_, rate_K_sample_freqs_kHz, Fs);
+      AmdB_ = AmdB_(1:L);
+
+      sdL = std(AmdB - AmdB_);
+      %printf("f: %d mn_ind: %d g: %3.2f sdK: %3.2f sdL: %3.2f\n", 
+      %       f, mn_ind, g(mn_ind), error(mn_ind), sdL);
+
+      plot(rate_K_sample_freqs_kHz(vq_st:vq_en)*1000, target - contrib, ";diff;k+-");
+      plot((1:L)*Wo*4000/pi, AmdB_,";AmdB bar;r+-");
+      hold off;
+
+    end
+
+    % interactive menu ------------------------------------------
+
+    printf("\rframe: %d  menu: n-next  b-back  q-quit  m-show_quant[%d]", f, quant_en);
+    fflush(stdout);
+    k = kbhit();
+
+    if k == 'm'
+      quant_en++;
+      if quant_en == 2
+        quant_en = 0;
+      end
+    endif
+    if k == 'n'
+      f = f + 1;
+    endif
+    if k == 'b'
+      f = f - 1;
+    endif
+    if k == 'o'
+      fit_order++;
+      if fit_order == 2
+        fit_order = 0;
+      end
+    endif
+  until (k == 'q')
+  printf("\n");
+
+endfunction
+
+function ind = arg_exists(v, str) 
+   ind = 0;
+   for i=1:length(v)
+      if strcmp(v{i}, str)
+        ind = i;
+      end     
+    end
+endfunction
+
+
diff --git a/codec2/branches/0.7/octave/newamp_batch.m b/codec2/branches/0.7/octave/newamp_batch.m
new file mode 100644 (file)
index 0000000..72fd837
--- /dev/null
@@ -0,0 +1,112 @@
+% newamp_batch.m
+%
+% Copyright David Rowe 2015
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Octave script to batch process model parameters using the new
+% amplitude model.  Used for generating samples we can listen to.
+%
+% Usage:
+%   ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --dump hts1a
+%   $ cd ~/codec2-dev/octave
+%   octave:14> newamp_batch("../build_linux/src/hts1a")
+%   ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --amread hts1a_am.out -o - | play -t raw -r 8000 -s -2 -
+% Or with a little more processing:
+%   codec2-dev/build_linux/src$ ./c2sim ../../raw/hts2a.raw --amread hts2a_am.out --awread hts2a_aw.out --phase0 --postfilter --Woread hts2a_Wo.out -o - | play -q -t raw -r 8000 -s -2 -
+
+
+% process a whole file and write results
+
+function [dk_log D1_log] = newamp_batch(samname, optional_Am_out_name, optional_Aw_out_name)
+  newamp;
+  more off;
+
+  max_amp = 80;
+  k = 10;
+  decimate = 4;
+  dec_in_time = 1;
+  dec_in_freq = 1;
+  decimate = 4;
+  synth_phase = 1;
+  vq_en = 1;
+  dk_log = []; D1_log = [];
+  train = 0;
+  Wo_quant = 1;
+  ind_log = [];
+
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+  [frames nc] = size(model);
+  model_ = zeros(frames, nc);
+  non_masked_m = zeros(frames,max_amp);
+
+  voicing_name = strcat(samname,"_pitche.txt");
+  voicing = zeros(1,frames);
+  if exist(voicing_name, "file") == 2
+    pitche = load(voicing_name);
+    voicing = pitche(:, 3);
+  end
+
+  if vq_en
+    load vq;
+  end
+
+  % encoder loop ------------------------------------------------------
+
+  sd_sum = 0;
+  for f=1:frames
+    printf("%d ", f);   
+
+    Wo = model(f,1);
+    L = min([model(f,2) max_amp-1]);
+
+    if Wo_quant
+      ind_Wo = encode_log_Wo(Wo, 6);    
+      Wo = decode_log_Wo(ind_Wo, 6);
+      L = floor(pi/Wo);
+      L = min([L max_amp-1]);
+    end
+
+    model_(f,1) = Wo;
+    model_(f,2) = L;
+    model_(f,3:(L+2)) = Am = model(f,3:(L+2));
+
+    AmdB = 20*log10(Am);
+
+    % find mask
+
+    mask_sample_freqs_kHz = (1:L)*Wo*4/pi;
+    maskdB = mask_model(AmdB, Wo, L);
+
+    maskdB_ = maskdB;
+    if dec_in_freq
+      if vq_en
+        [maskdB_ tmp1 D dk_ D1_ ind_vq] = decimate_in_freq(maskdB, 1, k, vq);
+      else
+        [maskdB_ tmp1 D dk_ D1_] = decimate_in_freq(maskdB, 1, k);
+      end
+      dk_log = [dk_log; dk_];
+      D1_log = [D1_log; D1_];
+    end
+    %maskdB_pf = maskdB_*1.5;
+    %maskdB_pf += max(maskdB_) - max(maskdB_pf);
+
+    % log info for bit stream
+
+    ind_log = [ind_log; ind_Wo voicing(f) (ind_vq-1) 0];
+
+    %sd_sum += sum(maskdB_ - maskdB);
+
+    Am_ = zeros(1,max_amp);
+    Am_ = 10 .^ (maskdB_(1:L)/20); 
+    model_(f,3:(L+2)) = Am_;
+  end
+
+  bit_stream_name = strcat(samname,".bit");
+  bits_per_param = [6 1 8 8 4 1];
+  write_bit_stream_file(bit_stream_name, ind_log, bits_per_param);
+  decode_from_bit_stream(samname);
+
+endfunction
+  
diff --git a/codec2/branches/0.7/octave/newamp_fbf.m b/codec2/branches/0.7/octave/newamp_fbf.m
new file mode 100644 (file)
index 0000000..c3d1bb6
--- /dev/null
@@ -0,0 +1,207 @@
+% newamp_fbf.m
+%
+% Copyright David Rowe 2015
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Interactive Octave script to explore frame by frame operation of new amplitude
+% modelling model.
+%
+% Usage:
+%   Make sure codec2-dev is compiled with the -DDUMP option - see README for
+%    instructions.
+%   ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --dump hts1a
+%   $ cd ~/codec2-dev/octave
+%   octave:14> newamp_fbf("../build_linux/src/hts1a",50)
+
+
+
+function newamp_fbf(samname, f=10)
+  newamp;
+  more off;
+  plot_spectrum = 1;
+  dec_in_freq = 1;
+  dec_in_time = 0;
+  vq_en = 0;
+  mask_en = 0;
+
+  % load up text files dumped from c2sim ---------------------------------------
+
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+  [frames tmp] = size(model);
+
+  load vq;
+
+  % Keyboard loop --------------------------------------------------------------
+
+  k = ' ';
+  do 
+    figure(1);
+    clf;
+    s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+    size(s);
+    plot(s);
+    axis([1 length(s) -20000 20000]);
+
+    figure(2);
+    clf;
+    Wo = model(f,1);
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    AmdB = 20*log10(Am);
+
+    axis([1 4000 -20 80]);
+    hold on;
+    if plot_spectrum
+      plot((1:L)*Wo*4000/pi, AmdB,";Am;r");
+      plot((1:L)*Wo*4000/pi, AmdB,"r+");
+    end
+
+    [maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L);
+    %a_non_masked_m = find(AmdB > maskdB);
+    %maskdB = maskdB - 6;
+    %maskdB(a_non_masked_m) = maskdB(a_non_masked_m) + 6;
+    %plot(Am_freqs_kHz*1000, maskdB, ';mask;g');
+
+    if mask_en
+      AmdB_ = maskdB;
+    else
+      AmdB_ = AmdB;
+    end
+    if dec_in_freq
+      [tmp1 tmp2 D] = decimate_in_freq(AmdB, 0);
+      if vq_en
+        [AmdB_ AmdB_cyclic D_cyclic dk_] = decimate_in_freq(AmdB, 1, 10, vq);
+      else
+        [AmdB_ AmdB_cyclic D_cyclic dk_] = decimate_in_freq(AmdB_, 1, 10);
+      end
+
+      plot(Am_freqs_kHz*1000, AmdB_cyclic, ';mask cyclic;b');
+      plot(Am_freqs_kHz*1000, AmdB_, ';mask trunc;c');
+      AmdB_pf = AmdB_*(1.5);
+      AmdB_pf += mean(AmdB) - mean(AmdB_pf);
+      %max(AmdB_pf)-max(AmdB_)
+      %AmdB_pf -= max(AmdB_pf)-max(AmdB_);
+    end
+
+    %AmdB_pf = AmdB_*(1.5);
+    %AmdB_pf += mean(AmdB) - mean(AmdB_pf);
+    AmdB_pf = AmdB_;
+    plot(Am_freqs_kHz*1000, AmdB_pf, ';mask trunc pf;g');
+
+    % Optional decimated parameters
+    %   need to general model_ parameters either side
+    
+    if dec_in_time
+      decimate = 4;
+      model_ = set_up_model_(model, f, decimate, vq_en, vq);    
+      maskdB_dit = decimate_frame_rate(model_, decimate, f, frames, Am_freqs_kHz);
+      plot(Am_freqs_kHz*1000, maskdB_dit, ';mask dit;b');
+    end
+
+    hold off;
+
+    if dec_in_freq
+      % lets get a feel for the "spectrum" of the smoothed spectral envelope
+      % this will give us a feel for how hard it is to code, ideally we would like
+      % just a few coefficents to be non-zero
+
+      figure(3)
+      clf
+
+      en = L/2+1;
+      stem(D(2:en),'g')
+      hold on;
+      stem(D_cyclic(2:en),'b')
+      hold off;
+
+      % let plot the cumulative amount of energy in each DFT
+
+      figure(4)
+      clf
+      plot(cumsum(D(2:en)/sum(D(2:en))),';cumsum;g');
+      hold on;
+      plot(cumsum(D_cyclic(2:en)/sum(D_cyclic(2:en))),';cumsum cyclic;b');
+      hold off;
+      axis([1 L 0 1])
+
+      figure(5)
+      clf
+      stem(dk_)
+    end
+
+    % interactive menu ------------------------------------------
+
+    printf("\rframe: %d  menu: n-next  b-back  q-quit  m-mask_en", f);
+    fflush(stdout);
+    k = kbhit();
+
+    if (k == 'm')
+      if mask_en
+        mask_en = 0;
+      else
+        mask_en = 1; 
+      end
+    endif
+    if (k == 'n')
+      f = f + 1;
+    endif
+    if (k == 'b')
+      f = f - 1;
+    endif
+  until (k == 'q')
+  printf("\n");
+
+endfunction
+
+function model_ = set_up_model_(model, f, decimate, vq_en, vq)
+    [frames nc] = size(model);
+    model_ = zeros(frames, nc); 
+    left_f = decimate*floor((f-1)/decimate)+1;
+    right_f = left_f + decimate;
+
+    model_(left_f,:) = set_up_maskdB_(model, left_f, vq_en, vq); 
+    model_(right_f,:) = set_up_maskdB_(model, right_f, vq_en, vq); 
+
+    model_(f,1) = model(f,1);  % Wo
+    model_(f,2) = model(f,2);  % L
+endfunction
+
+
+function amodel_row = set_up_maskdB_(model, f, vq_en, vq) 
+  [frames nc] = size(model);
+  max_amp = 80;
+
+  Wo = model(f,1);
+  L = model(f,2);
+  Am = model(f,3:(L+2));
+  AmdB = 20*log10(Am);
+
+  [maskdB Am_freqs_kHz] = mask_model(AmdB, Wo, L);
+  a_non_masked_m = find(AmdB > maskdB);
+  maskdB = maskdB - 6;
+  maskdB(a_non_masked_m) = maskdB(a_non_masked_m) + 6;
+
+  if 0
+  if vq_en
+    maskdB_ = decimate_in_freq(maskdB, 1, 7, vq);
+  else
+    maskdB_ = decimate_in_freq(maskdB, 1);
+  end
+  end
+
+  maskdB_ = maskdB;
+  
+  amodel_row = zeros(1,nc);
+  amodel_row(1) = Wo;
+  amodel_row(2) = L;
+  Am_ = zeros(1,max_amp);
+  Am_ = 10 .^ (maskdB_(1:L)/20); 
+  amodel_row(3:(L+2)) = Am_;
+endfunction
diff --git a/codec2/branches/0.7/octave/nf_from_gr.m b/codec2/branches/0.7/octave/nf_from_gr.m
new file mode 100644 (file)
index 0000000..3f441fc
--- /dev/null
@@ -0,0 +1,113 @@
+% nf_from_gr.m
+% David Rowe Mar 2016
+%
+% Calculate NF from GNU Radio output samples in 
+% ...IQIQ... (32 bit float) sample files
+%
+% 1/ Take one sample with a -100dBm input carrier
+% 2/ Take another sample with no signal (just rx noise)
+% 3/ Set Fs, adjust st and en to use a chunk of spectrum without too
+%     many birdies.
+
+1;
+
+function det_nf(p_filename, n_filename, title, Fs, st, en, Pin_dB, real_file=0)
+
+  if real_file
+    % real samples files of 16 bit shorts
+    fs=fopen(p_filename,"rb");
+    p = fread(fs,Inf,"short");
+    fclose(fs);
+    fs=fopen(n_filename,"rb");
+    pn = fread(fs,Inf,"short");
+    fclose(fs);
+  else
+    % GNU radio complex file input
+    p =  load_comp(p_filename);
+    pn = load_comp(n_filename);
+  end
+
+  P = fft(p(1:Fs));
+  N = fft(pn(1:Fs));
+
+  PdB = 10*log10(abs(P));
+  NdB = 10*log10(abs(N));
+
+  figure;
+  clf;
+
+  subplot(211)
+  plot(st:en, PdB(st:en));
+  
+  subplot(212)
+  plot(st:en, NdB(st:en));
+
+  #{ 
+  ------------------------------------------------------------------------
+
+  From Wikipedia: The Noise Figure is the difference in decibels
+     (dB) between the noise output of the actual receiver to the noise
+     output of an “ideal” receiver
+  
+  An ideal receiver would have an output noise power of:
+    Nout_dB = 10log10(B) -174 + G_dB
+  The -174 dBm/Hz figure is the thermal noise density at 25C, for
+  every 1Hz of bandwidth your will get -174dBm of noise power.  It's
+  the lower limit set by the laws of physics.  G_dB is the Rx gain. The
+  10log10(B) term takes into account the bandwidth of the Rx.  A wider
+  bandwidth means more total noise power.
+
+  So if you have a 1Hz bandwidth, and a gain of 100dB, you would
+  expect Nout_NdB = 0 -174 + 100 = -74dBm at the rx output with no
+  signal.  If you have a 1000Hz bandwidth receiver you would have NdB_out
+  = 20 -174 + 100 = -44dBm of noise power at the output.
+
+  To determine Noise Figure:
+    1) Sample the Rx output first with a test signal and then with noise only.
+    2) Find the Rx gain using the test signal.
+    3) Find the noise output power, then using the gain we can find the noise
+       input power. 
+    4) Normalise the noise input power to 1Hz noise bandwidth and
+       compare to the thermal noise floor.
+
+  ---------------------------------------------------------------------------- 
+  #}
+
+  % variance is the power of a sampled signal
+
+  Pout_dB = 10*log10(var(P(st:en)));           % Rx output power with test signal
+  G_dB    = Pout_dB - Pin_dB;                  % Gain of Rx                           
+  Nout_dB = 10*log10(var(N(st:en)));           % Rx output power with noise
+  Nin_dB  = Nout_dB - G_dB;                    % Rx input power with noise
+  No_dB   = Nin_dB - 10*log10(en-st);          % Rx input power with noise in 1Hz bandwidth
+  NF_dB   = No_dB + 174;                       % compare to thermal noise to get NF
+  printf("%10s: Pin: %4.1f  Pout: %4.1f  G: %4.1f  NF: %3.1f dB\n", title, Pin_dB, Pout_dB, G_dB, NF_dB);
+endfunction
+
+close all;
+
+% HackRF --------------------------
+
+p_filename = "~/Desktop/nf/hackrf_100dbm_4MHz.bin";
+n_filename = "~/Desktop/nf/hackrf_nosignal_4MHz.bin";
+det_nf(p_filename, n_filename, "HackRF", 4E6, 180E3, 600E3, -100);
+
+% RTL-SDR --------------------------
+
+p_filename = "~/Desktop/nf/neg100dBm_2MHz.bin";
+n_filename = "~/Desktop/nf/nosignal_2MHz.bin";
+det_nf(p_filename, n_filename, "RTL-SDR", 2E6, 100E3, 300E3, -100);
+
+% AirSpy -------------------------
+
+p_filename = "~/Desktop/nf/airspy_100dbm_2.5MSPS.bin";
+n_filename = "~/Desktop/nf/airspy_nosig_2.5MSPS.bin";
+det_nf(p_filename, n_filename, "AirSpy", 2.5E6, 100E3, 300E3, -100);
+
+% Fun Cube Dongle Pro Plus -------------------------
+
+p_filename = "~/Desktop/nf/fcdpp_100dbm_192khz.bin";
+n_filename = "~/Desktop/nf/fcdpp_nosig_192khz.bin";
+det_nf(p_filename, n_filename, "FunCube PP", 192E3, 25E3, 125E3, -100);
diff --git a/codec2/branches/0.7/octave/ofdm_dev.m b/codec2/branches/0.7/octave/ofdm_dev.m
new file mode 100644 (file)
index 0000000..bb35675
--- /dev/null
@@ -0,0 +1,997 @@
+% ofdm_dev.m
+% David Rowe April 2017
+%
+% Simulations used for development and testing of Rate Fs BPSK/QPSK
+% OFDM modem.
+
+ofdm_lib;
+gp_interleaver;
+ldpc;
+
+#{
+  TODO: 
+    [ ] compute SNR and PAPR
+    [ ] SSB bandpass filtering
+    [ ] way to simulate aquisition and demod
+    [ ] testframe based, maybe repeat every 10 seconds
+        + work out which pattern we match to sync up
+    [ ] acquisition curves
+        + plot error versus freq and timing offset
+        + plot pro acquisition versus freq offset, timing and freq sep and together
+        + plot total acquist prob at various SNRs ... maybe mean number of frames to sync?
+    [ ] replace genie EsNo est used for ldpc dec
+    [ ] clean up text 
+#}
+
+function [sim_out rx states] = run_sim(sim_in)
+
+  % set up core modem constants
+
+  states = ofdm_init(sim_in.bps, sim_in.Rs, sim_in.Tcp, sim_in.Ns, sim_in.Nc);
+  ofdm_load_const;
+  Nbitspervocframe = 28;
+
+  % simulation parameters and flags
+
+  woffset = 2*pi*sim_in.foff_hz/Fs;
+  dwoffset = 0;
+  if isfield(sim_in, "dfoff_hz_per_sec")
+    dwoffset = 2*pi*sim_in.dfoff_hz_per_sec/(Fs*Fs);
+  end
+  EbNodB  = sim_in.EbNodB;
+  verbose = states.verbose = sim_in.verbose;
+  hf_en   = sim_in.hf_en;
+
+  timing_en = states.timing_en = sim_in.timing_en;
+  states.foff_est_en = foff_est_en = sim_in.foff_est_en;
+  states.phase_est_en = phase_est_en = sim_in.phase_est_en;
+  if hf_en
+    assert(phase_est_en == 1, "\nNo point running HF simulation without phase est!!\n");
+  end
+  if isfield(sim_in, "diversity_en")
+    diversity_en = sim_in.diversity_en;
+  else
+    diversity_en = 0;
+  end
+
+  if verbose == 2
+    printf("Rs:..........: %4.2f\n", Rs);
+    printf("M:...........: %d\n", M);
+    printf("Ncp:.........: %d\n", Ncp);
+    printf("bps:.........: %d\n", bps);
+    printf("Nbitsperframe: %d\n", Nbitsperframe);
+    printf("Nrowsperframe: %d\n", Nrowsperframe);
+    printf("Nsamperframe.: %d\n", Nsamperframe);
+  end
+  
+  % Important to define run time in seconds so HF model will evolve the same way
+  % for different pilot insertion rates.  So lets work backwards from approx
+  % seconds in run to get Nbits, the total number of payload data bits
+
+  Nrows = sim_in.Nsec*Rs;
+  Nframes = floor((Nrows-1)/Ns);
+
+  % if we are interleaving over multiple frames, adjust Nframes so we have an integer number
+  % of interleaver frames in simulation
+
+  interleave_en = 0;
+  if isfield(sim_in, "interleave_frames") 
+    interleave_frames = sim_in.interleave_frames;
+    Nframes = interleave_frames*round(Nframes/interleave_frames);
+    interleave_en = 1;
+  end
+
+  Nbits = Nframes * Nbitsperframe;    % number of payload data bits
+
+  Nr = Nbits/(Nc*bps);                % Number of data rows to get Nbits total
+
+  % double check if Nbits fit neatly into carriers
+
+  assert(Nbits/(Nc*bps) == floor(Nbits/(Nc*bps)), "Nbits/(Nc*bps) must be an integer");
+
+  Nrp = Nr + Nframes + 1;  % number of rows once pilots inserted
+                           % extra row of pilots at end
+
+  if verbose == 2
+    printf("Nc...........: %d\n", Nc);
+    printf("Ns...........: %d (step size for pilots, Ns-1 data symbols between pilots)\n", Ns);
+    printf("Nr...........: %d\n", Nr);
+    printf("Nbits........: %d\n", Nbits);
+    printf("Nframes......: %d\n", Nframes);
+    if interleave_en
+      printf("Interleave fr: %d\n", interleave_frames);
+    end
+    printf("Nrp..........: %d (number of rows including pilots)\n", Nrp);
+  end
+
+  % Optional LPDC code -----------------------------------------------
+
+  ldpc_en = states.ldpc_en = sim_in.ldpc_en;
+  if sim_in.ldpc_en 
+    assert(bps == 2, "Only QPSK supported for LDPC so far.....");
+    HRA = sim_in.ldpc_code;
+    [aNr aNc] = size(HRA);
+    rate = states.rate = (aNc-aNr)/aNc;
+    assert(aNc == Nbitsperframe, "Dude: Num cols of LDPC HRA must == Nbitsperframe");
+    [H_rows, H_cols] = Mat2Hrows(HRA); 
+    code_param.H_rows = H_rows; 
+    code_param.H_cols = H_cols;
+    code_param.P_matrix = [];
+    code_param.data_bits_per_frame = length(code_param.H_cols) - length( code_param.P_matrix ); 
+    code_param.code_bits_per_frame = aNc;
+    assert(aNr == Nbitsperframe*rate);
+
+    modulation = states.ldpc_modulation = 'QPSK';
+    mapping = states.ldpc_mapping = 'gray';
+    demod_type = states.ldpc_demod_type = 0;
+    decoder_type = states.ldpc_decoder_type = 0;
+    max_iterations = states.ldpc_max_iterations = 100;
+
+    code_param.S_matrix = CreateConstellation( modulation, 4, mapping );
+
+    states.code_param = code_param;
+  elseif diversity_en
+    rate = 0.5;    
+  else
+    rate = 1;
+  end
+
+  % set up HF model ---------------------------------------------------------------
+
+  if hf_en
+
+    % some typical values, or replace with user supplied
+
+    dopplerSpreadHz = 1.0; path_delay_ms = 1;
+
+    if isfield(sim_in, "dopplerSpreadHz") 
+      dopplerSpreadHz = sim_in.dopplerSpreadHz;
+    end
+    if isfield(sim_in, "path_delay_ms") 
+      path_delay_ms = sim_in.path_delay_ms;
+    end
+    path_delay_samples = path_delay_ms*Fs/1000;
+    printf("Doppler Spread: %3.2f Hz Path Delay: %3.2f ms %d samples\n", dopplerSpreadHz, path_delay_ms, path_delay_samples);
+
+    % generate same fading pattern for every run
+
+    randn('seed',1);
+
+    spread1 = doppler_spread(dopplerSpreadHz, Fs, Nrp*(M+Ncp)*1.1);
+    spread2 = doppler_spread(dopplerSpreadHz, Fs, Nrp*(M+Ncp)*1.1);
+
+    % sometimes doppler_spread() doesn't return exactly the number of samples we need
+    assert(length(spread1) >= Nrp*(M+Ncp), "not enough doppler spreading samples");
+    assert(length(spread2) >= Nrp*(M+Ncp), "not enough doppler spreading samples");
+  end
+  % ------------------------------------------------------------------
+  % simulate for each Eb/No point 
+  % ------------------------------------------------------------------
+
+  for nn=1:length(EbNodB)
+    rand('seed',1);
+    randn('seed',1);
+
+    EsNo = rate * bps * (10 .^ (EbNodB(nn)/10));
+    variance = 1/(M*EsNo/2);
+
+    Nsam = Nrp*(M+Ncp);
+
+    % generate tx bits, optionaly LDPC encode, and modulate as QPSK symbols
+    % note for reasons unknown LdpcEncode() returns garbage if we use > 0.5 rather than round()
+
+    tx_data_bits = round(rand(1,Nbits*rate));
+
+    tx_bits = []; tx_symbols = [];
+    for f=1:Nframes
+      st = (f-1)*Nbitsperframe*rate+1; en = st + Nbitsperframe*rate - 1;
+      if ldpc_en
+        codeword = LdpcEncode(tx_data_bits(st:en), code_param.H_rows, code_param.P_matrix);
+      elseif diversity_en
+        % Nc carriers, so Nc*bps bits/row coded, or Nc*bps*rate data bits that we repeat
+        codeword = [];
+        for rr=1:Ns-1
+          st1 = st + (rr-1)*Nc*bps*rate; en1 = st1 + Nc*bps*rate - 1;
+          codeword = [codeword tx_data_bits(st1:en1) tx_data_bits(st1:en1)];
+        end
+        assert(length(codeword) == Nbitsperframe);
+      else
+        % uncoded mode
+        codeword = tx_data_bits(st:en);
+      end
+      tx_bits = [tx_bits codeword];
+      for b=1:2:Nbitsperframe
+        tx_symbols = [tx_symbols qpsk_mod(codeword(b:b+1))];
+      end
+    end
+
+    % optional interleaving over multiple frames
+
+    if interleave_en
+      for f=1:interleave_frames:Nframes
+       st = (f-1)*Nbitsperframe/bps+1; en = st + Nbitsperframe*interleave_frames/bps - 1;
+       tx_symbols(st:en) = gp_interleave(tx_symbols(st:en));
+      end 
+    end
+
+    % OFDM transmitter
+
+    tx = []; 
+    for f=1:Nframes
+      st = (f-1)*Nbitsperframe/bps+1; en = st + Nbitsperframe/bps - 1;
+      tx = [tx ofdm_txframe(states, tx_symbols(st:en))];
+    end
+    
+    % add extra row of pilots at end, to allow one frame simulations,
+    % useful for development
+
+    st = Nsamperframe*(Nframes-1)+1; en = st+Ncp+M-1;
+    tx = [tx tx(st:en)];
+    assert(length(tx) == Nsam);
+
+    % channel simulation ---------------------------------------------------------------
+    
+    if isfield(sim_in, "sample_clock_offset_ppm") 
+      % todo: this only works for large ppm like 500, runs out of memory
+      %       for small ppm
+
+      if sim_in.sample_clock_offset_ppm
+        timebase = floor(abs(1E6/sim_in.sample_clock_offset_ppm));
+        if sim_in.sample_clock_offset_ppm > 0
+          tx = resample(tx, timebase+1, timebase);
+        else
+          tx = resample(tx, timebase, timebase+1);
+        end
+
+        % make sure length is correct for rest of simulation
+
+        tx = [tx zeros(1,Nsam-length(tx))];
+        tx = tx(1:Nsam);
+      end
+    end
+
+    rx = tx;    
+
+    if hf_en
+
+      rx  = tx(1:Nsam) .* spread1(1:Nsam);
+      rx += [zeros(1,path_delay_samples) tx(1:Nsam-path_delay_samples)] .* spread2(1:Nsam);
+
+      % normalise rx power to same as tx
+
+      nom_rx_pwr = 2/(Ns*(M*M)) + Nc/(M*M);
+      rx_pwr = var(rx);
+      rx *= sqrt(nom_rx_pwr/rx_pwr);
+    end
+
+    phase_offset = woffset*(1:Nsam) + 0.5*dwoffset*((1:Nsam).^2);
+    rx = rx .* exp(j*phase_offset);
+   
+    noise = sqrt(variance)*(0.5*randn(1,Nsam) + j*0.5*randn(1,Nsam));
+    snrdB = 10*log10(var(rx)/var(noise)) + 10*log10(8000) - 10*log10(3000);
+    rx += noise;
+
+    % some spare samples at end to avoid overflow as est windows may poke into the future a bit
+
+    rx = [rx zeros(1,Nsamperframe)];
+    
+    % bunch of logs
+
+    phase_est_pilot_log = [];
+    delta_t_log = []; 
+    timing_est_log = [];
+    foff_est_hz_log = [];
+    Nerrs_log = []; Nerrs_coded_log = [];
+    rx_bits = []; rx_np = []; rx_amp = [];
+
+    % reset some states for each EbNo simulation point
+
+    states.sample_point = states.timing_est = 1;
+    if timing_en == 0
+      states.sample_point = Ncp;
+    end
+    states.nin = Nsamperframe;
+    states.foff_est_hz = 0;    
+
+    % for this simulation we "prime" buffer to allow one frame runs during development
+
+    prx = 1;
+    states.rxbuf(M+Ncp+2*Nsamperframe+1:Nrxbuf) = rx(prx:Nsamperframe+2*(M+Ncp));
+    prx += Nsamperframe+2*(M+Ncp);
+
+    for f=1:Nframes
+
+      % insert samples at end of buffer, set to zero if no samples
+      % available to disable phase estimation on future pilots on last
+      % frame of simulation
+
+      lnew = min(Nsam-prx,states.nin);
+      rxbuf_in = zeros(1,states.nin);
+
+      if lnew
+        rxbuf_in(1:lnew) = rx(prx:prx+lnew-1);
+      end
+      prx += states.nin;
+
+      [arx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
+
+      rx_bits = [rx_bits arx_bits]; rx_np = [rx_np arx_np]; rx_amp = [rx_amp arx_amp];
+      timing_est_log = [timing_est_log states.timing_est];
+      delta_t_log = [delta_t_log states.delta_t];
+      foff_est_hz_log = [foff_est_hz_log states.foff_est_hz];
+      phase_est_pilot_log = [phase_est_pilot_log; aphase_est_pilot_log];
+    end
+
+    assert(length(rx_bits) == Nbits);
+
+    % Optional de-interleave on rx QPSK symbols
+
+    if interleave_en
+      for f=1:interleave_frames:Nframes
+       st = (f-1)*Nbitsperframe/bps+1; en = st + Nbitsperframe*interleave_frames/bps - 1;
+       rx_np(st:en) = gp_deinterleave(rx_np(st:en));
+       rx_amp(st:en) = gp_deinterleave(rx_amp(st:en));
+      end 
+    end
+
+    % Calculate raw BER/PER stats, after pilots extracted.  As we may
+    % have used interleaving, we qpsk_demod() here rather than using
+    % rx_bits from ofdm_demod()
+
+    rx_bits = zeros(1, Nbits);
+    for s=1:Nbits/bps
+      rx_bits(2*(s-1)+1:2*s) = qpsk_demod(rx_np(s));
+    end
+
+    errors = xor(tx_bits, rx_bits);
+    Terrs = sum(errors);
+
+    Tpackets = Tpacketerrs = 0;
+    Nvocframes = floor(Nbits/Nbitspervocframe);
+    for fv=1:Nvocframes
+      st = (fv-1)*Nbitspervocframe + 1;
+      en = st + Nbitspervocframe - 1;
+      Nvocpacketerrs = sum(xor(tx_bits(st:en), rx_bits(st:en)));
+      if Nvocpacketerrs
+        Tpacketerrs++;
+      end
+      Tpackets++;
+    end
+    % Per-modem frame error log and optional LDPC/diversity error stats
+
+    Terrs_coded = 0; Tpackets_coded = 0; Tpacketerrs_coded = 0; sim_out.error_positions = [];
+    for f=1:Nframes
+      st = (f-1)*Nbitsperframe+1; en = st + Nbitsperframe - 1;
+      Nerrs_log(f) = sum(xor(tx_bits(st:en), rx_bits(st:en)));
+
+      st = (f-1)*Nbitsperframe/bps + 1;
+      en = st + Nbitsperframe/bps - 1;
+      r = rx_np(st:en); fade = rx_amp(st:en);
+
+      % optional LDPC decode
+     
+      if ldpc_en
+        % note we put ceiling on EsNo as decoder misbehaives with high EsNo
+
+        rx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, r, min(EsNo,30), fade);
+      end
+
+      % optional diversity demod
+
+      if diversity_en
+        rx_codeword = [];
+        for rr=1:Ns-1
+          for c=1:Nc/2
+            s = (rr-1)*Nc + c;
+            rx_codeword = [rx_codeword qpsk_demod(r(s)+r(s+Nc/2))];
+          end
+        end
+        assert(length(rx_codeword) == Nbitsperframe*rate);
+      end
+
+      % running coded BER calcs
+
+      if ldpc_en || diversity_en
+
+        st = (f-1)*Nbitsperframe*rate + 1;
+        en = st + Nbitsperframe*rate - 1;
+        errors = xor(tx_data_bits(st:en), rx_codeword(1:Nbitsperframe*rate));
+        Nerrs_coded = sum(errors);
+        Nerrs_coded_log(f) = Nerrs_coded;
+        Terrs_coded += Nerrs_coded;
+        sim_out.error_positions = [sim_out.error_positions errors];
+
+        % PER based on vocoder packet size, not sure it makes much
+        % difference compared to using all bits in LDPC code for
+        % packet
+
+        atx_data_bits = tx_data_bits(st:en);
+        Nvocframes = Nbitsperframe*rate/Nbitspervocframe;
+        for fv=1:Nvocframes
+          st = (fv-1)*Nbitspervocframe + 1;
+          en = st + Nbitspervocframe - 1;
+          Nvocpacketerrs = sum(xor(atx_data_bits(st:en), rx_codeword(st:en)));
+          if Nvocpacketerrs
+            Tpacketerrs_coded++;
+          end
+          Tpackets_coded++;
+        end
+      end
+    end
+
+    % print results of this simulation point to the console
+
+    if ldpc_en || diversity_en
+      printf("Coded EbNodB: % -4.1f BER: %5.4f Tbits: %5d Terrs: %5d PER: %5.4f Tpackets: %5d Tpacket_errs: %5d\n", 
+              EbNodB(nn), Terrs_coded/(Nbits*rate), Nbits*rate, Terrs_coded, 
+              Tpacketerrs_coded/Tpackets_coded, Tpackets_coded, Tpacketerrs_coded);
+    end
+    EbNodB_raw = EbNodB(nn) + 10*log10(rate);
+    printf("Raw EbNodB..: % -4.1f BER: %5.4f Tbits: %5d Terrs: %5d PER: %5.4f Tpackets: %5d Tpacket_errs: %5d\n", 
+           EbNodB_raw, Terrs/Nbits, Nbits, Terrs,
+           Tpacketerrs/Tpackets, Tpackets, Tpacketerrs);
+
+    % returns results for plotting curves
+
+    if ldpc_en || diversity_en
+      sim_out.ber(nn) = Terrs_coded/(Nbits*rate); 
+      sim_out.per(nn) = Tpacketerrs_coded/Tpackets_coded; 
+    else
+      sim_out.ber(nn) = Terrs/Nbits; 
+      sim_out.per(nn) = Tpacketerrs/Tpackets; 
+    end
+
+    % Optional plots, mostly used with run-single
+
+    if verbose
+
+      figure(1); clf; 
+      plot(rx_np,'+');
+      %axis([-2 2 -2 2]);
+      title('Scatter');
+      
+      figure(2); clf;
+      plot(phase_est_pilot_log,'g+', 'markersize', 5); 
+      title('Phase est');
+      axis([1 Nrp -pi pi]);  
+
+      figure(3); clf;
+      subplot(211)
+      stem(delta_t_log)
+      title('delta t');
+      subplot(212)
+      plot(timing_est_log);
+      title('timing est');
+
+      figure(4); clf;
+      plot(foff_est_hz_log)
+      axis([1 max(Nframes,2) -3 3]);
+      title('Fine Freq');
+
+      figure(5); clf;
+      if ldpc_en
+        subplot(211)
+        stem(Nerrs_log/Nbitsperframe);
+        title("Uncoded BER/frame");
+        subplot(212)
+        stem(Nerrs_coded_log/(Nbitsperframe*rate));
+        title("Coded BER/frame");
+     else
+        title("BER/frame");
+        stem(Nerrs_log/Nbitsperframe);
+      end
+
+      figure(6)
+      Tx = abs(fft(tx(1:Nsam).*hanning(Nsam)'));
+      Tx_dB = 20*log10(Tx);
+      dF = Fs/Nsam;
+      plot((1:Nsam)*dF, Tx_dB);
+      mx = max(Tx_dB);
+      axis([0 Fs/2 mx-60 mx])
+
+     
+#{
+      if hf_en
+        figure(4); clf; 
+        subplot(211)
+        plot(abs(spread1(1:Nsam)));
+        %hold on; plot(abs(spread2(1:Nsam)),'g'); hold off;
+        subplot(212)
+        plot(angle(spread1(1:Nsam)));
+        title('spread1 amp and phase');
+      end
+#}
+      
+#{
+      % todo, work out a way to plot rate Fs hf model phase
+      if sim_in.hf_en
+        plot(angle(hf_model(:,2:Nc+1)));
+      end
+#}
+
+
+    end
+
+  end
+endfunction
+
+
+function run_single(EbNodB = 100, error_pattern_filename);
+  Ts = 0.018; 
+  sim_in.Tcp = 0.002; 
+  sim_in.Rs = 1/Ts; sim_in.bps = 2; sim_in.Nc = 16; sim_in.Ns = 8;
+
+  sim_in.Nsec = (sim_in.Ns+1)/sim_in.Rs;  % one frame, make sure sim_in.interleave_frames = 1
+  %sim_in.Nsec = 1;
+
+  sim_in.EbNodB = EbNodB;
+  sim_in.verbose = 2;
+  sim_in.hf_en = 0;
+  sim_in.foff_hz = 0;
+  sim_in.dfoff_hz_per_sec = 0.00;
+  sim_in.sample_clock_offset_ppm = 0;
+
+  sim_in.timing_en = 1;
+  sim_in.foff_est_en = 1;
+  sim_in.phase_est_en = 1;
+
+  load HRA_112_112.txt
+  sim_in.ldpc_code = HRA_112_112;
+  sim_in.ldpc_en = 1;
+
+  sim_in.interleave_frames = 1;
+
+  %sim_in.diversity_en = 1;
+
+  sim_out = run_sim(sim_in);
+
+  if nargin == 2
+    fep = fopen(error_pattern_filename, "wb");
+    fwrite(fep, sim_out.error_positions, "short");
+    fclose(fep);
+  end
+
+end
+
+
+% Plot BER and PER curves for AWGN and HF:
+%
+% i) BER/PER against Eb/No for various coding schemes
+% ii) BER/PER against Eb/No showing Pilot/CP overhead
+% iii) BER/PER against SNR, with pilot/CP overhead, comparing 700C
+
+function run_curves
+
+  % waveform
+
+  Ts = 0.018; sim_in.Tcp = 0.002; 
+  sim_in.Rs = 1/Ts; sim_in.bps = 2; sim_in.Nc = 16; sim_in.Ns = 8;
+
+  pilot_overhead = (sim_in.Ns-1)/sim_in.Ns;
+  cp_overhead = Ts/(Ts+sim_in.Tcp);
+  overhead_dB = -10*log10(pilot_overhead*cp_overhead);
+
+  % simulation parameters
+
+  sim_in.verbose = 0;
+  sim_in.foff_hz = 0;
+  sim_in.timing_en = 1;
+  sim_in.foff_est_en = 1;
+  sim_in.phase_est_en = 1;
+  load HRA_112_112.txt
+  sim_in.ldpc_code = HRA_112_112;
+  sim_in.ldpc_en = 0;
+  sim_in.hf_en = 0;
+
+  sim_in.Nsec = 20;
+  sim_in.EbNodB = 0:8;
+  awgn_EbNodB = sim_in.EbNodB;
+
+  awgn_theory = 0.5*erfc(sqrt(10.^(sim_in.EbNodB/10)));
+  awgn = run_sim(sim_in);
+  sim_in.ldpc_en = 1; awgn_ldpc = run_sim(sim_in);
+
+  % Note for HF sim you really need >= 60 seconds (at Rs-50) to get sensible results c.f. theory
+
+  sim_in.hf_en = 1; sim_in.ldpc_en = 0; 
+  sim_in.Nsec = 60;
+  sim_in.EbNodB = 4:2:14;
+
+  EbNoLin = 10.^(sim_in.EbNodB/10);
+  hf_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));
+
+  hf = run_sim(sim_in);
+  sim_in.diversity_en = 1; hf_diversity = run_sim(sim_in); sim_in.diversity_en = 0; 
+  sim_in.ldpc_en = 1;  hf_ldpc = run_sim(sim_in);
+
+  % try a few interleavers
+
+  sim_in.interleave_frames = 1; hf_ldpc_1 = run_sim(sim_in);
+  sim_in.interleave_frames = 8; hf_ldpc_8 = run_sim(sim_in);
+  sim_in.interleave_frames = 16; hf_ldpc_16 = run_sim(sim_in);
+  sim_in.interleave_frames = 32; hf_ldpc_32 = run_sim(sim_in);
+  
+  % Rate Fs modem BER curves of various coding schemes
+
+  figure(1); clf;
+  semilogy(awgn_EbNodB, awgn_theory,'b+-;AWGN theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_theory,'b+-;HF theory;');
+  semilogy(awgn_EbNodB, awgn.ber,'r+-;AWGN;');
+  semilogy(sim_in.EbNodB, hf.ber,'r+-;HF;');
+  semilogy(sim_in.EbNodB, hf_diversity.ber,'ro-;HF diversity;');
+  semilogy(awgn_EbNodB, awgn_ldpc.ber,'c+-;AWGN LDPC (224,112);');
+  semilogy(sim_in.EbNodB, hf_ldpc.ber,'c+-;HF LDPC (224,112);');
+  semilogy(sim_in.EbNodB, hf_ldpc_1.ber,'m+-;HF LDPC (224,112) interleave 1;');
+  semilogy(sim_in.EbNodB, hf_ldpc_8.ber,'g+-;HF LDPC (224,112) interleave 8;');
+  semilogy(sim_in.EbNodB, hf_ldpc_16.ber,'k+-;HF LDPC (224,112) interleave 16;');
+  semilogy(sim_in.EbNodB, hf_ldpc_32.ber,'k+-;HF LDPC (224,112) interleave 32;');
+  hold off;
+  axis([0 14 1E-3 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  legend("location", "southwest");
+  title('Rate Fs modem BER for various FEC coding schemes');
+  print('-deps', '-color', "ofdm_dev_ber_coding.eps")
+
+  awgn_per_theory = 1 - (1-awgn_theory).^28;
+  hf_per_theory = 1 - (1-hf_theory).^28;
+
+  % Rate Fs modem PER curves of various coding schemes
+
+  figure(2); clf;
+  semilogy(awgn_EbNodB, awgn_per_theory,'b+-;AWGN theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_per_theory,'b+-;HF theory;');
+  semilogy(awgn_EbNodB, awgn.per,'r+-;AWGN;');
+  semilogy(sim_in.EbNodB, hf.per,'r+-;HF sim;');
+  semilogy(sim_in.EbNodB, hf_diversity.per,'ro-;HF diversity;');
+  semilogy(awgn_EbNodB, awgn_ldpc.per,'c+-;AWGN LDPC (224,112);');
+  semilogy(sim_in.EbNodB, hf_ldpc.per,'c+-;HF LDPC (224,112);');
+  semilogy(sim_in.EbNodB, hf_ldpc_1.per,'m+-;HF LDPC (224,112) interleave 1;');
+  semilogy(sim_in.EbNodB, hf_ldpc_8.per,'g+-;HF LDPC (224,112) interleave 8;');
+  semilogy(sim_in.EbNodB, hf_ldpc_16.per,'ko-;HF LDPC (224,112) interleave 16;');
+  semilogy(sim_in.EbNodB, hf_ldpc_32.per,'k+-;HF LDPC (224,112) interleave 32;');
+  hold off;
+  axis([0 14 1E-2 1])
+  xlabel('Eb/No (dB)');
+  ylabel('PER');
+  grid; grid minor on;
+  legend('boxoff');
+  legend("location", "southwest");
+  title('Rate Fs modem PER for various FEC coding schemes');
+  print('-deps', '-color', "ofdm_dev_per_coding.eps")
+
+  % Rate Fs modem pilot/CP overhead BER curves
+
+  figure(3); clf;
+  semilogy(awgn_EbNodB, awgn_theory,'b+-;AWGN theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_theory,'b+-;HF theory;');
+  semilogy(awgn_EbNodB+overhead_dB, awgn_theory,'g+-;AWGN lower bound pilot + CP;');
+  semilogy(sim_in.EbNodB+overhead_dB, hf_theory,'g+-;HF lower bound pilot + CP;');
+  semilogy(awgn_EbNodB+overhead_dB, awgn.ber,'r+-;AWGN sim;');
+  semilogy(sim_in.EbNodB+overhead_dB, hf.ber,'r+-;HF sim;');
+  hold off;
+  axis([0 14 1E-3 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  legend("location", "southwest");
+  title('Rate Fs modem BER Pilot/Cyclic Prefix overhead');
+  print('-deps', '-color', "ofdm_dev_ber_overhead.eps")
+
+  % Rate Fs modem pilot/CP overhead PER curves
+
+  figure(4); clf;
+  semilogy(awgn_EbNodB, awgn_per_theory,'b+-;AWGN theory;','markersize', 10, 'linewidth', 2);
+  hold on;
+  semilogy(sim_in.EbNodB, hf_per_theory,'b+-;HF theory;','markersize', 10, 'linewidth', 2);
+  semilogy(awgn_EbNodB+overhead_dB, awgn_per_theory,'g+-;AWGN lower bound pilot + CP;','markersize', 10, 'linewidth', 2);
+  semilogy(sim_in.EbNodB+overhead_dB, hf_per_theory,'g+-;HF lower bound pilot + CP;','markersize', 10, 'linewidth', 2);
+  semilogy(awgn_EbNodB+overhead_dB, awgn.per,'r+-;AWGN sim;','markersize', 10, 'linewidth', 2);
+  semilogy(sim_in.EbNodB+overhead_dB, hf.per,'r+-;HF sim;','markersize', 10, 'linewidth', 2);
+  hold off;
+  axis([0 14 1E-2 1])
+  xlabel('Eb/No (dB)');
+  ylabel('PER');
+  grid; grid minor on;
+  legend('boxoff');
+  legend("location", "southwest");
+  title('Rate Fs modem PER Pilot/Cyclic Prefix overhead');
+  print('-deps', '-color', "ofdm_dev_per_overhead.eps")
+
+  % SNR including pilots, CP, and 700C est
+
+  snr_awgn_theory = awgn_EbNodB + 10*log10(700/3000);
+  snr_hf_theory   = sim_in.EbNodB + 10*log10(700/3000);
+  snr_awgn        = snr_awgn_theory + overhead_dB;
+  snr_hf          = sim_in.EbNodB + 10*log10(700/3000) + overhead_dB;
+
+  % est 700C: 2/6 symbols are pilots, 1dB implementation loss
+
+  snr_awgn_700c   = awgn_EbNodB + 10*log10(700/3000) + 10*log10(6/4) + 1;
+  snr_hf_700c     = sim_in.EbNodB + 10*log10(700/3000) + 10*log10(6/4) + 1;
+
+  figure(5); clf;
+  semilogy(snr_awgn_theory, awgn_theory,'b+-;AWGN theory;','markersize', 10, 'linewidth', 2);
+  hold on;
+  semilogy(snr_awgn_700c, awgn_theory,'g+-;AWGN 700C;','markersize', 10, 'linewidth', 2);
+  semilogy(snr_hf_700c, hf_diversity.ber,'go-;HF 700C;','markersize', 10, 'linewidth', 2);
+  semilogy(snr_hf_theory, hf_theory,'b+-;HF theory;','markersize', 10, 'linewidth', 2);
+  semilogy(snr_awgn, awgn_ldpc.ber,'c+-;AWGN LDPC (224,112);','markersize', 10, 'linewidth', 2);
+  semilogy(snr_hf, hf_ldpc.ber,'c+-;HF LDPC (224,112);','markersize', 10, 'linewidth', 2);
+  semilogy(snr_hf, hf_diversity.ber,'bo-;HF diversity;','markersize', 10, 'linewidth', 2);
+  semilogy(snr_hf, hf_ldpc_16.ber,'k+-;HF LDPC (224,112) interleave 16;','markersize', 10, 'linewidth', 2);
+  hold off;
+  axis([-5 8 1E-3 2E-1])
+  xlabel('SNR (3000Hz noise BW) (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  legend("location", "southwest");
+  title('Rate Fs modem BER versus SNR including pilot/CP overhead');
+  print('-deps', '-color', "ofdm_dev_ber_snr.eps")
+
+end
+
+
+% Plot BER and PER curves for AWGN and HF with various estimators
+
+function run_curves_estimators
+
+  Nsec_awgn = 20;
+  Nsec_hf = 60;
+
+  % waveform
+
+  Ts = 0.018; sim_in.Tcp = 0.002; 
+  sim_in.Rs = 1/Ts; sim_in.bps = 2; sim_in.Nc = 16; sim_in.Ns = 8;
+
+  % simulation parameters
+
+  sim_in.verbose = 0; sim_in.foff_hz = 0; sim_in.ldpc_en = 0;
+
+  sim_in.phase_est_en = 1;
+  sim_in.timing_en = sim_in.foff_est_en = 0;
+
+  % AWGN simulations
+
+  sim_in.hf_en = 0; sim_in.Nsec = Nsec_awgn; sim_in.EbNodB = 0:2:6;
+  sim_in.timing_en = sim_in.foff_est_en = 0;
+
+  awgn_EbNodB = sim_in.EbNodB;
+  awgn_theory = 0.5*erfc(sqrt(10.^(sim_in.EbNodB/10)));
+  awgn = run_sim(sim_in);
+  sim_in.timing_en = 1; awgn_timing = run_sim(sim_in);
+  sim_in.foff_est_en = 1; awgn_foff_est = run_sim(sim_in);
+
+  sim_in.dfoff_hz_per_sec = 0.02; awgn_dfoff = run_sim(sim_in);
+
+  % HF simulations
+
+  sim_in.hf_en = 1; sim_in.Nsec = Nsec_hf; sim_in.EbNodB = 4:2:8;
+  sim_in.timing_en = sim_in.foff_est_en = 0;
+
+  EbNoLin = 10.^(sim_in.EbNodB/10);
+  hf_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));
+
+  hf = run_sim(sim_in);
+  sim_in.timing_en = 1; hf_timing = run_sim(sim_in);
+  sim_in.timing_en = 0; sim_in.foff_est_en = 1; hf_foff_est = run_sim(sim_in);
+  sim_in.timing_en = 1; hf_timing_foff_est = run_sim(sim_in);
+
+  sim_in.dfoff_hz_per_sec = 0.02; hf_dfoff = run_sim(sim_in); sim_in.dfoff_hz_per_sec = 0.0;
+
+  figure(1); clf;
+  semilogy(awgn_EbNodB, awgn_theory,'b+-;AWGN theory;');
+  hold on;
+  semilogy(awgn_EbNodB, awgn.ber,'r+-;AWGN phase;');
+  semilogy(awgn_EbNodB, awgn_timing.ber,'go-;AWGN phase+timing;');
+  semilogy(awgn_EbNodB, awgn_foff_est.ber,'d+-;AWGN phase+timing+foff_est;');
+  semilogy(awgn_EbNodB, awgn_dfoff.ber,'m+-;AWGN all + 0.02Hz/s drift;');
+  semilogy(sim_in.EbNodB, hf_theory,'b+-;HF theory;');
+  semilogy(sim_in.EbNodB, hf.ber,'r+-;HF phase;');
+  semilogy(sim_in.EbNodB, hf_timing.ber,'go-;HF phase+timing;');
+  semilogy(sim_in.EbNodB, hf_timing_foff_est.ber,'kd-;HF phase+foff_est;');
+  semilogy(sim_in.EbNodB, hf_foff_est.ber,'c+-;HF phase+timing+foff_est;');
+  semilogy(sim_in.EbNodB, hf_dfoff.ber,'m+-;HF + 0.02Hz/s drift;');
+  hold off;
+  axis([0 8 5E-3 1E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  legend("location", "southeast");
+  title('Rate Fs modem BER with estimators');
+  print('-deps', '-color', "ofdm_dev_estimators.eps")
+
+  % Simulate different HF path delays
+
+  sim_in.hf_en = 1; sim_in.Nsec = Nsec_hf; sim_in.EbNodB = 4:2:8;
+  sim_in.timing_en = sim_in.foff_est_en = 0;
+
+  sim_in.path_delay_ms = 0; hf0 = run_sim(sim_in);
+  sim_in.path_delay_ms = 0.5; hf500us = run_sim(sim_in);
+  sim_in.path_delay_ms = 1; hf1ms = run_sim(sim_in);
+  sim_in.path_delay_ms = 2; hf2ms = run_sim(sim_in);
+
+  figure(2); clf;
+  semilogy(sim_in.EbNodB, hf_theory,'b+-;HF theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf0.ber,'r+-;HF phase 0 ms;');
+  semilogy(sim_in.EbNodB, hf500us.ber,'g+-;HF phase 0.5 ms;');
+  semilogy(sim_in.EbNodB, hf1ms.ber,'c+-;HF phase 1 ms;');
+  semilogy(sim_in.EbNodB, hf2ms.ber,'k+-;HF phase 2 ms;');
+  hold off;
+  axis([3 9 1E-2 1E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  legend("location", "southeast");
+  title('Rate Fs modem BER across HF path delay');
+  print('-deps', '-color', "ofdm_dev_estimators.eps")
+end
+
+
+% Run an acquisition test, returning vectors of estimation errors
+
+function [delta_ct delta_foff] = acquisition_test(Ntests=10, EbNodB=100, foff_hz=0, hf_en=0, fine_en=0)
+
+  Ts = 0.018; 
+  sim_in.Tcp = 0.002; 
+  sim_in.Rs = 1/Ts; sim_in.bps = 2; sim_in.Nc = 16; sim_in.Ns = 8;
+
+  sim_in.Nsec = Ntests*(sim_in.Ns+1)/sim_in.Rs;
+
+  sim_in.EbNodB = EbNodB;
+  sim_in.verbose = 2;
+  sim_in.hf_en = hf_en;
+  sim_in.foff_hz = foff_hz; 
+  sim_in.timing_en = 0;
+  sim_in.foff_est_en = 0;
+  sim_in.phase_est_en = 0;
+
+  [sim_out rx states] = run_sim(sim_in);
+
+  % set up acquistion 
+
+  Nsamperframe = states.Nsamperframe;
+  rate_fs_pilot_samples = states.rate_fs_pilot_samples;
+
+  % test fine or acquisition over test signal
+  #{
+    fine: - start with coarse timing instant
+          - on each frame est timing a few samples about that point
+          - update timing instant
+
+    corr: - where is best plcase to sample
+          - just before end of symbol?
+          - how long should sequence be?
+          - add extra?
+          - aim for last possible moment?
+          - man I hope IL isn't too big.....
+  #}
+
+  delta_ct = []; delta_foff = [];
+
+  if fine_en
+
+    window_width = 5;                   % search +/-2 samples from current timing instant
+    timing_instant = Nsamperframe+1;    % start at correct instant for AWGN
+                                        % start at second frame so we can search -2 ... +2
+
+    while timing_instant < (length(rx) - (Nsamperframe + length(rate_fs_pilot_samples) + window_width))
+      st = timing_instant - ceil(window_width/2); 
+      en = st + Nsamperframe-1 + length(rate_fs_pilot_samples) + window_width-1;
+      [ft_est foff_est] = coarse_sync(states, rx(st:en), rate_fs_pilot_samples);
+      printf("ft_est: %d timing_instant %d %d\n", ft_est, timing_instant, mod(timing_instant, Nsamperframe));
+      timing_instant += Nsamperframe + ft_est - ceil(window_width/2);
+      delta_t = [delta_ft ft_est - ceil(window_width/2)];
+    end
+  else
+    % for coarse simulation we just use contant window shifts
+
+    st = 0.5*Nsamperframe; 
+    en = 2.5*Nsamperframe - 1;
+    ct_target = Nsamperframe/2;
+
+    for w=1:Nsamperframe:length(rx)-3*Nsamperframe
+      %st = w+0.5*Nsamperframe; en = st+2*Nsamperframe-1;
+      %[ct_est foff_est] = coarse_sync(states, rx(st:en), rate_fs_pilot_samples);
+      [ct_est foff_est] = coarse_sync(states, rx(w+st:w+en), rate_fs_pilot_samples);
+      if states.verbose
+        printf("ct_est: %4d foff_est: %3.1f\n", ct_est, foff_est);
+      end
+
+      % valid coarse timing ests are modulo Nsamperframe
+
+      delta_ct = [delta_ct ct_est-ct_target];
+      delta_foff = [delta_foff (foff_est-foff_hz)];
+    end
+  end
+
+endfunction
+
+
+% Run some tests for various acquisition conditions. Probability of
+% acquistion is what matters, e.g. if it's 50% we can expect sync
+% within 2 frames
+%                 P(t)/P(f)  P(t)/P(f)
+%          Eb/No  AWGN       HF
+% +/- 25Hz -1/3   1.0/0.3    0.96/0.3 
+% +/-  5Hz -1/3   1.0/0.347  0.96/0.55 
+% +/- 25Hz  10/10 1.00/0.92  0.99/0.77
+
+function acquisition_histograms(fine_en = 0)
+  Fs = 8000;
+  Ntests = 100;
+
+  % allowable tolerance for acquistion
+
+  ftol_hz = 2.0;            % fine freq can track this out
+  ttol_samples = 0.002*Fs;  % 2ms, ie CP length
+
+  % AWGN channel operating point
+
+  [dct dfoff] = acquisition_test(Ntests, -1, -20, 0, fine_en);
+
+  % Probability of acquistion is what matters, e.g. if it's 50% we can
+  % expect sync within 2 frames
+
+  printf("AWGN P(time offset acq) = %3.2f\n", length(find (abs(dct) < ttol_samples))/length(dct));
+  if fine_en == 0
+    printf("AWGN P(freq offset acq) = %3.2f\n", length(find (abs(dfoff) < ftol_hz))/length(dfoff));
+  end
+
+  figure(1)
+  hist(dct(find (abs(dct) < ttol_samples)))
+  title('Coarse Timing error AWGN')
+  if fine_en == 0
+    figure(2)
+    hist(dfoff)
+  title('Coarse Freq error AWGN')
+  end
+
+  % HF channel operating point
+
+  [dct dfoff] = acquisition_test(Ntests, 3, -20, 1, fine_en);
+
+  printf("HF P(time offset acq) = %3.2f\n", length(find (abs(dct) < ttol_samples))/length(dct));
+  if fine_en == 0
+    printf("HF P(freq offset acq) = %3.2f\n", length(find (abs(dfoff) < ftol_hz))/length(dfoff));
+  end
+
+  figure(3)
+  hist(dct(find (abs(dct) < ttol_samples)))
+  title('Coarse Timing error HF')
+  if fine_en == 0
+    figure(4)
+    hist(dfoff)
+    title('Coarse Freq error HF')
+  end
+
+endfunction
+
+
+% ---------------------------------------------------------
+% choose simulation to run here 
+% ---------------------------------------------------------
+
+format;
+more off;
+
+init_cml('/home/david/Desktop/cml/');
+
+run_single(6) 
+%run_curves
+%run_curves_estimators
+%acquisition_histograms
+%acquisition_test
diff --git a/codec2/branches/0.7/octave/ofdm_lib.m b/codec2/branches/0.7/octave/ofdm_lib.m
new file mode 100644 (file)
index 0000000..32dd02f
--- /dev/null
@@ -0,0 +1,456 @@
+% ofdm_lib.m
+% David Rowe Mar 2017
+
+#{
+  Library of functions that implement a BPSK/QPSK OFDM modem.  Rate Fs
+  verison of ofdm_rs.m with OFDM based up and down conversion, and all
+  those nasty real-world details like fine freq, timing.  
+#}
+
+
+1;
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function out = freq_shift(in, foff, Fs)
+  foff_rect = exp(j*2*pi*foff/Fs);
+  foff_phase_rect = exp(j*0);
+  
+  for r=1:length(in)
+    foff_phase_rect *= foff_rect;
+    out(r) = in(r)*foff_phase_rect;
+  end
+endfunction
+
+% Correlates the OFDM pilot symbol samples with a window of received
+% samples to determine the most likely timing offset.  Combines two
+% frames pilots so we need at least Nsamperframe+M+Ncp samples in rx.
+% Also determines frequency offset at maximimum correlation.  Can be
+% used for acquisition (coarse timing a freq offset), and fine timing
+
+#{
+  TODO: 
+    [ ] attempt to speed up sync
+        + tis rather stateless, this current demod, which is nice
+        [ ] 0.5Hz grid and measure BER
+            + so run demod a bunch of times at different offsets
+            + Hmm cld also try +/- 20Hz multiples as it's aliased?
+            + might to use 
+            + need metric for sync, could be callback.
+        [ ] or refine freq offset using pilots
+        [ ] different error measure that 10% maybe soft dec
+            + 10% very high BER
+    [ ] simpler CPU/DFT for freq offset estimation
+        + more suitable for real time implementation
+#}
+
+function [t_est foff_est] = coarse_sync(states, rx, rate_fs_pilot_samples)
+    Nsamperframe = states.Nsamperframe; Fs = states.Fs;
+    Npsam = length(rate_fs_pilot_samples);
+    verbose  = states.verbose;
+
+    Ncorr = length(rx) - (Nsamperframe+Npsam) + 1;
+    assert(Ncorr > 0);
+    corr = zeros(1,Ncorr);
+    for i=1:Ncorr
+      corr(i)   = abs(rx(i:i+Npsam-1) * rate_fs_pilot_samples');
+      corr(i)  += abs(rx(i+Nsamperframe:i+Nsamperframe+Npsam-1) * rate_fs_pilot_samples');
+    end
+
+    [mx t_est] = max(abs(corr));
+
+    C  = abs(fft(rx(t_est:t_est+Npsam-1) .* conj(rate_fs_pilot_samples), Fs));
+    C += abs(fft(rx(t_est+Nsamperframe:t_est+Nsamperframe+Npsam-1) .* conj(rate_fs_pilot_samples), Fs));
+
+    fmax = 30;
+    [mx_pos foff_est_pos] = max(C(1:fmax));
+    [mx_neg foff_est_neg] = max(C(Fs-fmax+1:Fs));
+
+    if mx_pos > mx_neg
+      foff_est = foff_est_pos - 1;
+    else
+      foff_est = foff_est_neg - fmax - 1;
+    end
+
+    if verbose > 1
+      %printf("t_est: %d\n", t_est);
+      figure(7); clf;
+      plot(abs(corr))
+      figure(8)
+      plot(C)
+      axis([0 200 0 0.4])
+    end
+endfunction
+
+
+%-------------------------------------------------------------
+% ofdm_init
+%-------------------------------------------------------------
+
+#{
+  Frame has Ns-1 data symbols between pilots, e.g. for Ns=3: 
+  
+    PPP
+    DDD
+    DDD
+    PPP
+#}
+
+function states = ofdm_init(bps, Rs, Tcp, Ns, Nc)
+  states.Fs = 8000;
+  states.bps = bps;
+  states.Rs = Rs;
+  states.Tcp = Tcp;
+  states.Ns = Ns;       % step size for pilots
+  states.Nc = Nc;       % Number of cols, aka number of carriers
+  states.M  = states.Fs/Rs;
+  states.Ncp = Tcp*states.Fs;
+  states.Nbitsperframe = (Ns-1)*Nc*bps;
+  states.Nrowsperframe = states.Nbitsperframe/(Nc*bps);
+  states.Nsamperframe =  (states.Nrowsperframe+1)*(states.M+states.Ncp);
+
+  % generate same pilots each time
+
+  rand('seed',1);
+  states.pilots = 1 - 2*(rand(1,Nc+2) > 0.5);
+
+  % carrier tables for up and down conversion
+
+  fcentre = 1500;
+  Nlower = floor((fcentre - Rs*Nc/2)/Rs);
+  w = (Nlower:Nlower+Nc+1)*2*pi*Rs/states.Fs;
+  W = zeros(Nc+2,states.M);
+  for c=1:Nc+2
+    W(c,:) = exp(j*w(c)*(0:states.M-1));
+  end
+  states.w = w;
+  states.W = W;
+
+  % fine timing search +/- window_width/2 from current timing instant
+
+  states.ftwindow_width = 11; 
+  % Receive buffer: D P DDD P DDD P DDD P D
+  %                         ^
+  % also see ofdm_demod() ...
+
+  states.Nrxbuf = 3*states.Nsamperframe+states.M+states.Ncp + 2*(states.M + states.Ncp);
+  states.rxbuf = zeros(1, states.Nrxbuf);
+  % default settings on a bunch of options and states
+
+  states.verbose = 0;
+  states.timing_en = 1;
+  states.foff_est_en = 1;
+  states.phase_est_en = 1;
+
+  states.foff_est_gain = 0.01;
+  states.foff_est_hz = 0;
+  states.sample_point = states.timing_est = 1;
+  states.nin = states.Nsamperframe;
+
+  % generate OFDM pilot symbol, used for timing and freq offset est
+
+  rate_fs_pilot_samples = states.pilots * W/states.M;
+  states.rate_fs_pilot_samples = [rate_fs_pilot_samples(states.M-states.Ncp+1:states.M) rate_fs_pilot_samples];
+  
+  % LDPC code is optionally enabled
+
+  states.rate = 1.0;
+  states.ldpc_en = 0;
+
+endfunction
+
+
+
+% --------------------------------------
+% ofdm_mod - modulates one frame of bits
+% --------------------------------------
+
+function tx = ofdm_mod(states, tx_bits)
+  ofdm_load_const;
+  assert(length(tx_bits) == Nbitsperframe);
+
+  % map to symbols in linear array
+
+  if bps == 1
+    tx_sym_lin = 2*tx_bits - 1;
+  end
+  if bps == 2
+    for s=1:Nbitsperframe/bps
+      tx_sym_lin(s) = qpsk_mod(tx_bits(2*(s-1)+1:2*s));
+    end
+  end
+
+  tx = ofdm_txframe(states, tx_sym_lin);
+endfunction
+
+% -----------------------------------------
+% ofdm_tx - modulates one frame of symbols
+% ----------------------------------------
+
+#{ 
+   Each carrier amplitude is 1/M.  There are two edge carriers that
+   are just tx-ed for pilots plus plus Nc continuous carriers. So
+   power is:
+
+     p = 2/(Ns*(M*M)) + Nc/(M*M)
+
+   e.g. Ns=8, Nc=16, M=144 
+   
+     p = 2/(8*(144*144)) + 16/(144*144) = 7.84-04
+
+#}
+
+function tx = ofdm_txframe(states, tx_sym_lin)
+  ofdm_load_const;
+  assert(length(tx_sym_lin) == Nbitsperframe/bps);
+
+  % place symbols in multi-carrier frame with pilots and boundary carriers
+
+  tx_sym = []; s = 1;
+  aframe = zeros(Ns,Nc+2);
+  aframe(1,:) = pilots;
+  for r=1:Nrowsperframe
+    arowofsymbols = tx_sym_lin(s:s+Nc-1);
+    s += Nc;
+    aframe(r+1,2:Nc+1) = arowofsymbols;
+  end
+  tx_sym = [tx_sym; aframe];
+
+  % OFDM upconvert symbol by symbol so we can add CP
+
+  tx = [];
+  for r=1:Ns
+    asymbol = tx_sym(r,:) * W/M;
+    asymbol_cp = [asymbol(M-Ncp+1:M) asymbol];
+    tx = [tx asymbol_cp];
+  end
+endfunction
+
+
+% ------------------------------------------
+% ofdm_demod - Demodulates one frame of bits
+% ------------------------------------------
+
+#{ 
+
+  For phase estimation we need to maintain buffer of 3 frames plus
+  one pilot, so we have 4 pilots total. '^' is the start of current
+  frame that we are demodulating.
+           
+  P DDD P DDD P DDD P
+        ^
+    
+  Then add one symbol either side to account for movement in
+  sampling instant due to sample clock differences:
+
+  D P DDD P DDD P DDD P D
+          ^
+#}
+
+function [rx_bits states aphase_est_pilot_log rx_np rx_amp] = ofdm_demod(states, rxbuf_in)
+  ofdm_load_const;
+
+  % insert latest input samples into rxbuf
+
+  rxbuf(1:Nrxbuf-states.nin) = rxbuf(states.nin+1:Nrxbuf);
+  rxbuf(Nrxbuf-states.nin+1:Nrxbuf) = rxbuf_in;
+
+  % get latest freq offset estimate
+
+  woff_est = 2*pi*foff_est_hz/Fs;
+
+  % update timing estimate --------------------------------------------------
+
+  delta_t = 0;
+  if timing_en
+    % update timing at start of every frame
+
+    st = M+Ncp + Nsamperframe + 1 - floor(ftwindow_width/2) + (timing_est-1);
+    en = st + Nsamperframe-1 + M+Ncp + ftwindow_width-1;
+          
+    ft_est = coarse_sync(states, rxbuf(st:en) .* exp(-j*woff_est*(st:en)), rate_fs_pilot_samples);
+    timing_est = timing_est + ft_est - ceil(ftwindow_width/2);
+
+    if verbose > 1
+      printf("  ft_est: %2d timing_est: %2d sample_point: %2d\n", ft_est, timing_est, sample_point);
+    end
+
+    % Black magic to keep sample_point inside cyclic prefix.  Or something like that.
+
+    delta_t = ft_est - ceil(ftwindow_width/2);
+    sample_point = max(timing_est+Ncp/4, sample_point);
+    sample_point = min(timing_est+Ncp, sample_point);
+  end
+
+  % down convert at current timing instant----------------------------------
+
+  % todo: this cld be more efficent, as pilot r becomes r-Ns on next frame
+
+  rx_sym = zeros(1+Ns+1+1, Nc+2);
+
+  % previous pilot
+  
+  st = M+Ncp + Nsamperframe + (-Ns)*(M+Ncp) + 1 + sample_point; en = st + M - 1;
+
+  for c=1:Nc+2
+    acarrier = rxbuf(st:en) .* exp(-j*woff_est*(st:en)) .* conj(W(c,:));
+    rx_sym(1,c) = sum(acarrier);
+  end
+
+  % pilot - this frame - pilot
+
+  for rr=1:Ns+1 
+    st = M+Ncp + Nsamperframe + (rr-1)*(M+Ncp) + 1 + sample_point; en = st + M - 1;
+    for c=1:Nc+2
+      acarrier = rxbuf(st:en) .* exp(-j*woff_est*(st:en)) .* conj(W(c,:));
+      rx_sym(rr+1,c) = sum(acarrier);
+    end
+  end
+
+  % next pilot
+
+  st = M+Ncp + Nsamperframe + (2*Ns)*(M+Ncp) + 1 + sample_point; en = st + M - 1;
+  for c=1:Nc+2
+    acarrier = rxbuf(st:en) .* exp(-j*woff_est*(st:en)) .* conj(W(c,:));
+    rx_sym(Ns+3,c) = sum(acarrier);
+  end
+      
+  % est freq err based on all carriers ------------------------------------
+      
+  if foff_est_en
+    freq_err_rect = sum(rx_sym(2,:))' * sum(rx_sym(2+Ns,:));
+
+    % prevent instability in atan(im/re) when real part near 0 
+
+    freq_err_rect += 1E-6;
+
+    %printf("freq_err_rect: %f %f angle: %f\n", real(freq_err_rect), imag(freq_err_rect), angle(freq_err_rect));
+    freq_err_hz = angle(freq_err_rect)*Rs/(2*pi*Ns);
+    foff_est_hz = foff_est_hz + foff_est_gain*freq_err_hz;
+  end
+
+  % OK - now estimate and correct phase  ----------------------------------
+
+  aphase_est_pilot = 10*ones(1,Nc+2);
+  aamp_est_pilot = zeros(1,Nc+2);
+  for c=2:Nc+1
+
+    % estimate phase using average of 6 pilots in a rect 2D window centred
+    % on this carrier
+    % PPP
+    % DDD
+    % DDD
+    % PPP
+          
+    cr = c-1:c+1;
+    aphase_est_pilot_rect = sum(rx_sym(2,cr)*pilots(cr)') + sum(rx_sym(2+Ns,cr)*pilots(cr)');
+
+    % use next step of pilots in past and future
+
+    aphase_est_pilot_rect += sum(rx_sym(1,cr)*pilots(cr)');
+    aphase_est_pilot_rect += sum(rx_sym(2+Ns+1,cr)*pilots(cr)');
+
+    aphase_est_pilot(c) = angle(aphase_est_pilot_rect);
+    aamp_est_pilot(c) = abs(aphase_est_pilot_rect/12);
+  end
+  % correct phase offset using phase estimate, and demodulate
+  % bits, separate loop as it runs across cols (carriers) to get
+  % frame bit ordering correct
+
+  aphase_est_pilot_log = [];
+  rx_bits = []; rx_np = []; rx_amp = [];
+  for rr=1:Ns-1
+    for c=2:Nc+1
+      if phase_est_en
+        rx_corr = rx_sym(rr+2,c) * exp(-j*aphase_est_pilot(c));
+      else
+        rx_corr = rx_sym(rr+2,c);
+      end
+      rx_np = [rx_np rx_corr];
+      rx_amp = [rx_amp aamp_est_pilot(c)];
+      if bps == 1
+        abit = real(rx_corr) > 0;
+      end
+      if bps == 2
+        abit = qpsk_demod(rx_corr);
+      end
+      rx_bits = [rx_bits abit];
+    end % c=2:Nc+1
+    aphase_est_pilot_log = [aphase_est_pilot_log; aphase_est_pilot(2:Nc+1)];
+  end 
+
+  % Adjust nin to take care of sample clock offset
+
+  nin = Nsamperframe;
+  if timing_en
+    thresh = (M+Ncp)/8;
+    tshift = (M+Ncp)/4;
+    if timing_est > thresh
+      nin = Nsamperframe+tshift;
+      timing_est -= tshift;
+      sample_point -= tshift;
+    end
+    if timing_est < -thresh
+      nin = Nsamperframe-tshift;
+      timing_est += tshift;
+      sample_point += tshift;
+    end
+  end
+
+  states.rx_sym = rx_sym;
+  states.rxbuf = rxbuf;
+  states.nin = nin;
+  states.timing_est = timing_est;
+  states.sample_point = sample_point;
+  states.delta_t = delta_t;
+  states.foff_est_hz = foff_est_hz;
+endfunction
+
+
+% Save test bits frame to a text file in the form of a C array
+% 
+% usage:
+%   ofdm_lib; test_bits_ofdm_file
+%
+
+function test_bits_ofdm_file
+
+  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
+  states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
+  ofdm_load_const;
+
+  rand('seed',1);
+  test_bits_ofdm = round(rand(1,Nbitsperframe));
+
+  f=fopen("../src/test_bits_ofdm.h","wt");
+  fprintf(f,"/* Generated by test_bits_ofdm_file() Octave function */\n\n");
+  fprintf(f,"const int test_bits_ofdm[]={\n");
+  for m=1:length(test_bits_ofdm)-1
+    fprintf(f,"  %d,\n",test_bits_ofdm(m));
+  endfor
+  fprintf(f,"  %d\n};\n",test_bits_ofdm(length(test_bits_ofdm)));
+  fclose(f);
+
+endfunction
diff --git a/codec2/branches/0.7/octave/ofdm_load_const.m b/codec2/branches/0.7/octave/ofdm_load_const.m
new file mode 100644 (file)
index 0000000..db66d6d
--- /dev/null
@@ -0,0 +1,46 @@
+% make like C #define for ofdm modem
+
+Fs = states.Fs;
+bps = states.bps;
+Rs = states.Rs;
+Tcp = states.Tcp;
+Ns = states.Ns;
+Nc = states.Nc;
+M = states.M;
+Ncp = states.Ncp;
+bps = states.bps;
+Nbitsperframe = states.Nbitsperframe;
+Nrowsperframe = states.Nrowsperframe;
+Nsamperframe = states.Nsamperframe;
+
+W = states.W;
+w = states.w;
+
+timing_est = states.timing_est;
+sample_point = states.sample_point;
+ftwindow_width = states.ftwindow_width;
+
+Nrxbuf = states.Nrxbuf;
+rxbuf = states.rxbuf;
+
+pilots = states.pilots;
+rate_fs_pilot_samples = states.rate_fs_pilot_samples;
+
+foff_est_gain = states.foff_est_gain;
+foff_est_hz = states.foff_est_hz;
+
+timing_en = states.timing_en;
+foff_est_en = states.foff_est_en;
+phase_est_en = states.phase_est_en;
+
+rate = states.rate;
+ldpc_en = states.ldpc_en;
+if ldpc_en
+  code_param = states.code_param;
+  max_iterations = states.ldpc_max_iterations;
+  demod_type = states.ldpc_demod_type;
+  decoder_type = states.ldpc_decoder_type;
+end
+
+verbose = states.verbose;
+
diff --git a/codec2/branches/0.7/octave/ofdm_rs.m b/codec2/branches/0.7/octave/ofdm_rs.m
new file mode 100644 (file)
index 0000000..4c89a50
--- /dev/null
@@ -0,0 +1,795 @@
+% ofdm_rs.m
+% David Rowe Mar 2017
+%
+% Rate Rs BPSK/QPSK simulation to explore techniques for
+% phase estimation over multiple carriers in HF channel.  Rate
+% Rs version of ofdm_fs.m
+
+#{
+ TODO:
+   [X] sim pilot based phase est using known symbols
+   [X] test AWGN BER with averaging pilots from adj carriers
+   [X] refactor to insert pilot rows
+   [X] add border cols, not used for data
+   [X] centre est on current carrier, extend to > 3
+   [X] test single points
+       + 1dB IL @ 6dB HF, 0.4 dB @ 2dB AWGN
+   [X] try linear interpolation
+   [X] try longer time windows
+   [X] try combining mod stripping phase est inside frame
+   [X] curves taking into account pilot losses
+   [ ] remove border carriers, interpolate edge carrier
+   [X] modify for QPSK
+#}
+
+1;
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+
+function sim_out = run_sim(sim_in)
+  Rs = 100;
+
+  bps = sim_in.bps;
+  EbNodB = sim_in.EbNodB;
+  verbose = sim_in.verbose;
+  hf_en = sim_in.hf_en;
+  hf_phase = sim_in.hf_phase;
+  phase_offset = sim_in.phase_offset;
+
+  Ns = sim_in.Ns;          % step size for pilots
+  Nc = sim_in.Nc;          % Number of cols, aka number of carriers
+
+  Nbitsperframe = (Ns-1)*Nc*bps;
+  Nrowsperframe = Nbitsperframe/(Nc*bps);
+  if verbose
+    printf("bps:.........: %d\n", bps);
+    printf("Nbitsperframe: %d\n", Nbitsperframe);
+    printf("Nrowsperframe: %d\n", Nrowsperframe);
+  end
+
+  % Important to define run time in seconds so HF model will evolve the same way
+  % for different pilot insertion rates.  So lets work backwards from approx
+  % seconds in run to get Nbits, the total number of payload data bits
+
+  % frame has Ns-1 data symbols between pilots, e.g. for Ns=3: 
+  %
+  % PPP
+  % DDD
+  % DDD
+  % PPP
+
+  Nrows = sim_in.Nsec*Rs;
+  Nframes = floor((Nrows-1)/Ns);
+  Nbits = Nframes * Nbitsperframe;    % number of payload data bits
+
+  Nr = Nbits/(Nc*bps);                % Number of data rows to get Nbits total
+
+  if verbose
+    printf("Nc.....: %d\n", Nc);
+    printf("Ns.....: %d (step size for pilots, Ns-1 data symbols between pilots)\n", Ns);
+    printf("Nr.....: %d\n", Nr);
+    printf("Nbits..: %d\n", Nbits);
+  end
+
+  % double check if Nbits fit neatly into carriers
+
+  assert(Nbits/(Nc*bps) == floor(Nbits/(Nc*bps)), "Nbits/(Nc*bps) must be an integer");
+  printf("Nframes: %d\n", Nframes);
+
+  Nrp = Nr + Nframes + 1;  % number of rows once pilots inserted
+                           % extra row of pilots at end
+  printf("Nrp....: %d (number of rows including pilots)\n", Nrp);
+  
+  % set up HF model
+
+  if hf_en
+
+    % some typical values, or replace with user supplied
+
+    dopplerSpreadHz = 1.0; path_delay = 1E-3*Rs;
+
+    if isfield(sim_in, "dopplerSpreadHz") 
+      dopplerSpreadHz = sim_in.dopplerSpreadHz;
+    end
+    if isfield(sim_in, "path_delay") 
+      path_delay = sim_in.path_delay;
+    end
+    printf("Doppler Spread: %3.2f Hz Path Delay: %3.2f symbols\n", dopplerSpreadHz, path_delay);
+    randn('seed',1);
+    spread1 = doppler_spread(dopplerSpreadHz, Rs, sim_in.Nsec*Rs*1.1);
+    spread2 = doppler_spread(dopplerSpreadHz, Rs, sim_in.Nsec*Rs*1.1);
+
+    % sometimes doppler_spread() doesn't return exactly the number of samples we need
+    assert(length(spread1) >= Nrp, "not enough doppler spreading samples");
+    assert(length(spread2) >= Nrp, "not enough doppler spreading samples");
+  end
+  
+  % construct an artificial phase countour for testing, linear across freq and time
+
+  if sim_in.phase_test
+    phase_test = ones(Nrp, Nc+2);
+    for r=1:Nrp
+      for c=1:Nc+2
+        phase_test(r,c) = -pi/2 + c*pi/(Nc+2) + r*0.01*2*pi;
+        phase_test(r,c) = phase_test(r,c) - 2*pi*floor((phase_test(r,c)+pi)/(2*pi));
+      end
+    end
+  end
+
+  % simulate for each Eb/No point ------------------------------------
+
+  for nn=1:length(EbNodB)
+    rand('seed',1);
+    randn('seed',1);
+
+    EsNo = bps * (10 .^ (EbNodB(nn)/10));
+    variance = 1/(EsNo/2);
+    noise = sqrt(variance)*(0.5*randn(Nrp,Nc+2) + j*0.5*randn(Nrp,Nc+2));
+
+    % generate tx bits
+
+    tx_bits = rand(1,Nbits) > 0.5;
+
+    % map to symbols 
+
+    if bps == 1
+      tx_symb = 2*tx_bits - 1;
+    end
+    if bps == 2
+      for s=1:Nbits/bps
+        tx_symb(s) = qpsk_mod(tx_bits(2*(s-1)+1:2*s));
+      end
+    end
+
+    % place symbols in multi-carrier frame with pilots and boundary carriers
+
+    tx = []; s = 1;
+    for f=1:Nframes
+      aframe = zeros(Nrowsperframe,Nc+2);
+      aframe(1,:) = 1;
+      for r=1:Nrowsperframe
+        arowofsymbols = tx_symb(s:s+Nc-1);
+        s += Nc;
+        aframe(r+1,2:Nc+1) = arowofsymbols;
+      end
+      tx = [tx; aframe];
+    end      
+    tx = [tx; ones(1,Nc+2)];  % final row of pilots
+    [nr nc] = size(tx);
+    assert(nr == Nrp);
+    
+    rx = tx * exp(j*phase_offset);
+
+    if sim_in.phase_test
+      rx = rx .* exp(j*phase_test);
+    end
+
+    if hf_en
+
+      % simplified rate Rs simulation model that doesn't include
+      % ISI, just freq filtering.
+      
+      % Note Rs carrier spacing, sample rate is Rs
+
+      hf_model = zeros(Nr,Nc+2); phase_est = zeros(Nr,Nc);
+      for r=1:Nrp
+        for c=1:Nc+2
+          w = 2*pi*c*Rs/Rs; 
+          hf_model(r,c) = spread1(r) + exp(-j*w*path_delay)*spread2(r);
+        end
+        
+        if hf_phase
+          rx(r,:) = rx(r,:) .* hf_model(r,:);
+        else
+          rx(r,:) = rx(r,:) .* abs(hf_model(r,:));
+        end
+      end
+
+      % normalise power over HF simulation run
+
+      p = sum(var(rx));
+      rx *= sqrt(Nc/p);
+    end
+
+    rx += noise;
+
+    % pilot based phase est, we use known tx symbols as pilots ----------
+
+    rx_corr = rx;
+
+    if sim_in.pilot_phase_est
+
+      % est phase from pilots either side of data symbols
+      % adjust phase of data symbol
+      % demodulate and count errors of just data
+      phase_est_pilot_log = 10*ones(Nrp,Nc+2);
+      phase_est_stripped_log = 10*ones(Nrp,Nc+2);
+      phase_est_log = 10*ones(Nrp,Nc+2);
+      for c=2:Nc+1
+        for r=1:Ns:Nrp-Ns
+
+          % estimate phase using average of 6 pilots in a rect 2D window centred
+          % on this carrier
+          % PPP
+          % DDD
+          % DDD
+          % PPP
+          
+          cr = c-1:c+1;
+          aphase_est_pilot_rect1 = sum(rx(r,cr)*tx(r,cr)');
+          aphase_est_pilot_rect2 = sum(rx(r+Ns,cr)*tx(r+Ns,cr)');
+
+          % optionally use next step of pilots in past and future
+
+          if sim_in.pilot_wide
+            if r > Ns+1
+              aphase_est_pilot_rect1 += sum(rx(r-Ns,cr)*tx(r-Ns,cr)');
+            end
+            if r < Nrp - 2*Ns
+              aphase_est_pilot_rect2 += sum(rx(r+2*Ns,cr)*tx(r+2*Ns,cr)');
+            end
+          end
+
+          % correct phase offset using phase estimate
+
+          for rr=r+1:r+Ns-1
+            a = b = 1;
+            if sim_in.pilot_interp
+              b = (rr-r)/Ns; a = 1 - b;
+            end
+            %printf("rr: %d a: %4.3f b: %4.3f\n", rr, a, b);
+            aphase_est_pilot = angle(a*aphase_est_pilot_rect1 + b*aphase_est_pilot_rect2);
+            phase_est_pilot_log(rr,c) = aphase_est_pilot;
+            rx_corr(rr,c) = rx(rr,c) * exp(-j*aphase_est_pilot);
+          end
+
+          if sim_in.stripped_phase_est
+            % Optional modulation stripping feed fwd phase estimation, to refine
+            % pilot-based phase estimate.  Doing it after pilot based phase estimation
+            % means we don't need to deal with ambiguity, which is difficult to handle
+            % in low SNR channels.
+
+            % Use vector of 7 symbols around current data symbol.  We could use a 2D
+            % window if we can work out how best to correct with pilot-est and avoid
+            % ambiguities
+
+            for rr=r+1:r+Ns-1
+
+              % extract a matrix of nearby samples with pilot-based offset removed
+              amatrix = rx(max(1,rr-3):min(Nrp,rr+3),c) .* exp(-j*aphase_est_pilot);
+
+              % modulation strip and est phase
+
+              stripped = abs(amatrix) .* exp(j*2*angle(amatrix));
+              aphase_est_stripped = angle(sum(sum(stripped)))/2;
+              phase_est_stripped_log(rr,c) = aphase_est_stripped;
+
+              % correct rx symbols based on both phase ests
+
+              phase_est_log(rr,c) = angle(exp(j*(aphase_est_pilot+aphase_est_stripped)));
+              rx_corr(rr,c) = rx(rr,c) * exp(-j*phase_est_log(rr,c));
+            end       
+          end % sim_in.stripped_phase_est
+
+        end % r=1:Ns:Nrp-Ns
+
+      end % c=2:Nc+1
+    end % sim_in.pilot_phase_est
+
+
+    if isfield(sim_in, "ml_pd") && sim_in.ml_pd
+
+      % Bill's ML with pilots phase detector, does phase est and demodulation 
+
+      rx_bits = []; rx_np = [];
+      aframeofbits = zeros(Ns-1, Nc);
+      for r=1:Ns:Nrp-Ns
+
+        % demodulate this frame, ML operates carrier by carrier 
+
+        for c=2:Nc+1
+          arxcol = rx(r:r+Ns, c);
+          arxcol(1) = rx(r, c-1) + rx(r, c+1);
+          arxcol(Ns+1) = rx(r+Ns, c-1) + rx(r+Ns, c+1);
+          [acolofbits aphase_est] = ml_pd(rot90(arxcol),  bps, [1 Ns+1]);
+          aframeofbits(:,c-1) = xor(acolofbits, ones(1,Ns-1));
+          rx_np = [rx_np rot90(arxcol) .* exp(-j*aphase_est)];
+        end
+        
+        % unpack from frame into linear array of bits
+
+        for rr=1:Ns-1
+          rx_bits = [rx_bits aframeofbits(rr,:)];
+        end
+      end
+    else
+
+      % remove pilots to give us just data symbols and demodulate
+      
+      rx_bits = []; rx_np = [];
+      for r=1:Nrp
+        if mod(r-1,Ns) != 0
+          arowofsymbols = rx_corr(r,2:Nc+1);
+          rx_np = [rx_np arowofsymbols];
+          if bps == 1
+            arowofbits = real(arowofsymbols) > 0;
+          end
+          if bps == 2
+            arowofbits = zeros(1,Nc);
+            for c=1:Nc
+              arowofbits((c-1)*2+1:c*2) = qpsk_demod(arowofsymbols(c));
+            end
+          end
+          rx_bits = [rx_bits arowofbits];
+        end
+      end
+    end
+    %tx_bits
+    %rx_bits
+    assert(length(rx_bits) == Nbits);
+
+    %phase_test
+    %phase_est_log
+
+    % calculate BER stats as a block, after pilots extracted
+
+    errors = xor(tx_bits, rx_bits);
+    Nerrs = sum(errors);
+
+    printf("EbNodB: %3.2f BER: %5.4f Nbits: %d Nerrs: %d\n", EbNodB(nn), Nerrs/Nbits, Nbits, Nerrs);
+
+    if verbose
+      figure(1); clf; 
+      plot(rx_np,'+');
+      axis([-2 2 -2 2]);
+
+      if hf_en
+        figure(2); clf; 
+        plot(abs(hf_model(:,2:Nc+1)));
+      end
+
+      if sim_in.pilot_phase_est
+        figure(3); clf;
+        plot(phase_est_log(:,2:Nc+1),'+', 'markersize', 10); 
+        hold on; 
+        plot(phase_est_pilot_log(:,2:Nc+1),'g+', 'markersize', 5); 
+        if sim_in.stripped_phase_est
+          plot(phase_est_stripped_log(:,2:Nc+1),'ro', 'markersize', 5); 
+        end
+        if sim_in.hf_en && sim_in.hf_phase
+          plot(angle(hf_model(:,2:Nc+1)));
+        end
+        if sim_in.phase_test
+          plot(phase_test(:,2:Nc+1));
+        end
+        axis([1 Nrp -pi pi]);
+      end
+    end
+
+    sim_out.ber(nn) = sum(Nerrs)/Nbits; 
+    sim_out.pilot_overhead = 10*log10(Ns/(Ns-1));
+  end
+endfunction
+
+
+% Plot BER against Eb/No curves at various pilot insertion rates Ns
+% using the HF multipath channel.  Second set of curves includes Eb/No
+% loss for pilot insertion, so small Ns means better tracking of phase
+% but large pilot insertion loss
+
+% Target operating point Eb/No is 6dB, as this is where our rate 1/2
+% LDPC code gives good results (10% PER, 1% BER).  However this means
+% the Eb/No at the input is 10*log(1/2) or 3dB less, so we need to
+% make sure phase est works at Eb/No = 6 - 3 = 3dB
+
+function run_curves_hf
+  sim_in.Nc = 7;
+  sim_in.Ns = 5;
+  sim_in.Nsec = 240;
+  sim_in.EbNodB = 1:8;
+  sim_in.verbose = 0;
+  sim_in.pilot_phase_est = 0;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 0;
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 1;
+  sim_in.hf_phase = 0;
+
+  sim_in.Ns = 5;
+  hf_ref_Ns_5_no_phase = run_sim(sim_in);
+  sim_in.Ns = 9;
+  hf_ref_Ns_9_no_phase = run_sim(sim_in);
+
+  sim_in.hf_phase = 1;
+  sim_in.pilot_phase_est = 1;
+
+  sim_in.Ns = 5;
+  hf_Ns_5 = run_sim(sim_in);
+
+  sim_in.Ns = 9;
+  hf_Ns_9 = run_sim(sim_in);
+
+  sim_in.Ns = 17;
+  hf_Ns_17 = run_sim(sim_in);
+
+  figure(4); clf;
+  semilogy(sim_in.EbNodB, hf_ref_Ns_5_no_phase.ber,'b+-;Ns=5 HF ref no phase;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_ref_Ns_9_no_phase.ber,'c+-;Ns=9 HF ref no phase;');
+  semilogy(sim_in.EbNodB, hf_Ns_5.ber,'g+--;Ns=5;');
+  semilogy(sim_in.EbNodB + hf_Ns_5.pilot_overhead, hf_Ns_5.ber,'go-;Ns=5 with pilot overhead;');
+  semilogy(sim_in.EbNodB, hf_Ns_9.ber,'r+--;Ns=9;');
+  semilogy(sim_in.EbNodB + hf_Ns_9.pilot_overhead, hf_Ns_9.ber,'ro-;Ns=9 with pilot overhead;');
+  semilogy(sim_in.EbNodB, hf_Ns_17.ber,'k+--;Ns=17;');
+  semilogy(sim_in.EbNodB + hf_Ns_17.pilot_overhead, hf_Ns_17.ber,'ko-;Ns=17 with pilot overhead;');
+  hold off;
+  axis([1 8 4E-2 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  title('HF Multipath 1Hz Doppler 1ms delay');
+
+end
+
+
+% Generate HF curves for some alternative, experimental methods tested
+% during development, such as interpolation, refinements using
+% modulation stripping, narrow window.
+
+function run_curves_hf_alt
+  sim_in.Nc = 7;
+  sim_in.Ns = 5;
+  sim_in.Nsec = 60;
+  sim_in.EbNodB = 1:8;
+  sim_in.verbose = 0;
+  sim_in.pilot_phase_est = 0;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 0;
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 1;
+  sim_in.hf_phase = 0;
+
+  sim_in.Ns = 9;
+  hf_ref_Ns_9_no_phase = run_sim(sim_in);
+
+  sim_in.hf_phase = 1;
+  sim_in.pilot_phase_est = 1;
+  hf_Ns_9 = run_sim(sim_in);
+
+  sim_in.stripped_phase_est = 1;
+  hf_Ns_9_stripped = run_sim(sim_in);
+
+  sim_in.stripped_phase_est = 0;
+  sim_in.pilot_wide = 0;
+  hf_Ns_9_narrow = run_sim(sim_in);
+
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 1;
+  hf_Ns_9_interp = run_sim(sim_in);
+
+  figure(6); clf;
+  semilogy(sim_in.EbNodB, hf_ref_Ns_9_no_phase.ber,'c+-;Ns=9 HF ref no phase;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_Ns_9.ber,'r+--;Ns=9;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_stripped.ber,'g+--;Ns=9 stripped refinement;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_narrow.ber,'b+--;Ns=9 narrow;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_interp.ber,'k+--;Ns=9 interp;');
+  hold off;
+  axis([1 8 4E-2 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  title('HF Multipath 1Hz Doppler 1ms delay');
+
+end
+
+
+% Generate HF curves for fixed Ns but different HF channels.
+
+function run_curves_hf_channels
+  sim_in.Nc = 7;
+  sim_in.Ns = 9;
+  sim_in.Nsec = 240;
+  sim_in.EbNodB = 1:8;
+  sim_in.verbose = 0;
+  sim_in.pilot_phase_est = 0;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 0;
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 1;
+  sim_in.hf_phase = 0;
+
+  hf_Ns_9_1hz_1ms_no_phase = run_sim(sim_in);
+
+  sim_in.hf_phase = 1;
+  sim_in.pilot_phase_est = 1;
+  hf_Ns_9_1hz_1ms = run_sim(sim_in);
+
+  Rs = 100;
+
+  sim_in.dopplerSpreadHz = 1.0; 
+  sim_in.path_delay = 500E-6*Rs;
+  hf_Ns_9_1hz_500us = run_sim(sim_in);
+
+  sim_in.dopplerSpreadHz = 1.0; 
+  sim_in.path_delay = 2E-3*Rs;
+  hf_Ns_9_1hz_2ms = run_sim(sim_in);
+
+  sim_in.dopplerSpreadHz = 2.0; 
+  sim_in.path_delay = 1E-3*Rs;
+  hf_Ns_9_2hz_1ms = run_sim(sim_in);
+
+  sim_in.dopplerSpreadHz = 2.0; 
+  sim_in.path_delay = 1E-3*Rs;
+  hf_Ns_9_2hz_2ms = run_sim(sim_in);
+
+  sim_in.dopplerSpreadHz = 2.0; 
+  sim_in.path_delay = 2E-3*Rs;
+  hf_Ns_9_2hz_2ms = run_sim(sim_in);
+
+  sim_in.dopplerSpreadHz = 4.0; 
+  sim_in.path_delay = 1E-3*Rs;
+  hf_Ns_9_4hz_1ms = run_sim(sim_in);
+
+  figure(6); clf;
+  semilogy(sim_in.EbNodB, hf_Ns_9_1hz_1ms_no_phase.ber,'c+-;Ns=9 1Hz 1ms ref no phase;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_Ns_9_1hz_500us.ber,'k+-;Ns=9 1Hz 500us;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_1hz_1ms.ber,'r+-;Ns=9 1Hz 1ms;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_1hz_2ms.ber,'bo-;Ns=9 1Hz 2ms;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_2hz_1ms.ber,'g+-;Ns=9 2Hz 1ms;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_2hz_2ms.ber,'mo-;Ns=9 2Hz 2ms;');
+  semilogy(sim_in.EbNodB, hf_Ns_9_4hz_1ms.ber,'c+-;Ns=9 4Hz 1ms;');
+  hold off;
+  axis([1 8 4E-2 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  title('HF Multipath Ns = 9');
+
+end
+
+
+% AWGN curves for BPSK and QPSK.  Coded Eb/No operating point is 2dB,
+% so raw BER for rate 1/2 will be -1dB
+
+function run_curves_awgn_bpsk_qpsk
+  sim_in.Nc = 7;
+  sim_in.Ns = 7;
+  sim_in.Nsec = 30;
+  sim_in.verbose = 0;
+  sim_in.pilot_phase_est = 0;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 1;
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 0;
+  sim_in.hf_phase = 0;
+
+  sim_in.EbNodB = -3:5;
+
+  ber_awgn_theory = 0.5*erfc(sqrt(10.^(sim_in.EbNodB/10)));
+
+  sim_in.bps = 1;
+  awgn_bpsk = run_sim(sim_in);
+  sim_in.bps = 2;
+  awgn_qpsk = run_sim(sim_in);
+
+  figure(5); clf;
+  semilogy(sim_in.EbNodB, ber_awgn_theory,'b+-;AWGN Theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, awgn_bpsk.ber,'g+-;Ns=7 BPSK;');
+  semilogy(sim_in.EbNodB + awgn_bpsk.pilot_overhead, awgn_bpsk.ber,'go-;Ns=7 BPSK with pilot overhead;');
+  semilogy(sim_in.EbNodB, awgn_qpsk.ber,'r+-;Ns=7 QPSK;');
+  semilogy(sim_in.EbNodB + awgn_qpsk.pilot_overhead, awgn_qpsk.ber,'ro-;Ns=7 QPSK with pilot overhead;');
+  hold off;
+  axis([-3 5 4E-3 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  title('AWGN');
+end
+
+
+% HF multipath curves for BPSK and QPSK.  Coded operating point is about 3dB
+
+function run_curves_hf_bpsk_qpsk
+  sim_in.Nc = 7;
+  sim_in.Ns = 7;
+  sim_in.Nsec = 120;
+  sim_in.verbose = 0;
+  sim_in.pilot_phase_est = 1;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 0;
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 1;
+  sim_in.hf_phase = 1;
+
+  sim_in.EbNodB = 1:8;
+
+  EbNoLin = 10.^(sim_in.EbNodB/10);
+  hf_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));
+
+  sim_in.bps = 1;
+  hf_bpsk = run_sim(sim_in);
+  sim_in.bps = 2;
+  hf_qpsk = run_sim(sim_in);
+
+  figure(5); clf;
+  semilogy(sim_in.EbNodB, hf_theory,'b+-;HF Theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_bpsk.ber,'g+-;Ns=7 BPSK;');
+  semilogy(sim_in.EbNodB + hf_bpsk.pilot_overhead, hf_bpsk.ber,'go-;Ns=7 BPSK with pilot overhead;');
+  semilogy(sim_in.EbNodB, hf_qpsk.ber,'r+-;Ns=7 QPSK;');
+  semilogy(sim_in.EbNodB + hf_qpsk.pilot_overhead, hf_qpsk.ber,'ro-;Ns=7 QPSK with pilot overhead;');
+  hold off;
+  axis([1 8 4E-3 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  title('HF Multipath');
+end
+
+
+% AWGN curves for BPSK using 3 carrier 2D matrix pilot and ML pilot
+
+function run_curves_awgn_ml
+  sim_in.bps = 1;
+  sim_in.Nc = 7;
+  sim_in.Ns = 7;
+  sim_in.Nsec = 10;
+  sim_in.verbose = 0;
+  sim_in.pilot_phase_est = 1;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 1;
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 0;
+  sim_in.hf_phase = 0;
+
+  sim_in.EbNodB = -3:5;
+
+  ber_awgn_theory = 0.5*erfc(sqrt(10.^(sim_in.EbNodB/10)));
+
+  awgn_2d = run_sim(sim_in);
+  sim_in.pilot_phase_est = 0;
+  sim_in.ml_pd = 1;
+  awgn_ml = run_sim(sim_in);
+
+  figure(5); clf;
+  semilogy(sim_in.EbNodB, ber_awgn_theory,'b+-;AWGN Theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, awgn_2d.ber,'g+-;Ns=7 3 carrier pilot BPSK;');
+  semilogy(sim_in.EbNodB, awgn_ml.ber,'ro-;Ns=7 ML pilot BPSK;');
+  hold off;
+  axis([-3 5 4E-3 5E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  title('AWGN');
+end
+
+
+% HF multipath curves for ML
+
+function run_curves_hf_ml
+  sim_in.bps = 1;
+  sim_in.Nc = 7;
+  sim_in.Ns = 14;
+  sim_in.Nsec = 120;
+  sim_in.verbose = 0;
+  sim_in.pilot_phase_est = 1;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 0;
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 1;
+  sim_in.hf_phase = 1;
+
+  sim_in.EbNodB = 1:8;
+
+  EbNoLin = 10.^(sim_in.EbNodB/10);
+  hf_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));
+
+  hf_2d = run_sim(sim_in);
+  sim_in.pilot_phase_est = 0;
+  sim_in.ml_pd = 1;
+  hf_ml = run_sim(sim_in);
+
+  figure(7); clf;
+  semilogy(sim_in.EbNodB, hf_theory,'b+-;HF Theory;');
+  hold on;
+  semilogy(sim_in.EbNodB, hf_2d.ber,'g+-;Ns=7 3 carrier pilot BPSK;');
+  semilogy(sim_in.EbNodB, hf_ml.ber,'ro-;Ns=7 ML pilot BPSK;');
+  hold off;
+  axis([1 8 4E-3 2E-1])
+  xlabel('Eb/No (dB)');
+  ylabel('BER');
+  grid; grid minor on;
+  legend('boxoff');
+  title('HF Multipath');
+end
+
+
+
+function run_single
+  sim_in.bps = 2;
+  sim_in.Nsec = 60;
+  sim_in.Nc = 16;
+  sim_in.Ns = 8;
+  sim_in.EbNodB = 6;
+  sim_in.verbose = 1;
+
+  sim_in.pilot_phase_est = 1;
+  sim_in.pilot_wide = 1;
+  sim_in.pilot_interp = 0;
+  sim_in.stripped_phase_est = 0;
+  sim_in.ml_pd = 0;
+
+  sim_in.phase_offset = 0;
+  sim_in.phase_test = 0;
+  sim_in.hf_en = 1;
+  sim_in.hf_phase = 1;
+  sim_in.path_delay = 0;
+
+  run_sim(sim_in);
+
+  EbNoLin = 10.^(sim_in.EbNodB/10);
+  hf_theory = 0.5.*(1-sqrt(EbNoLin./(EbNoLin+1)));
+  printf("HF theory: %5.4f\n", hf_theory);
+end
+
+
+format;
+more off;
+
+run_single
+%run_curves_hf_bpsk_qpsk
+%run_curves_hf_channels
+%run_curves_hf_ml
+
+
+
+
diff --git a/codec2/branches/0.7/octave/ofdm_rx.m b/codec2/branches/0.7/octave/ofdm_rx.m
new file mode 100644 (file)
index 0000000..d108181
--- /dev/null
@@ -0,0 +1,295 @@
+% ofdm_rx.m
+% David Rowe April 2017
+%
+% OFDM file based rx.
+
+#{
+  TODO: 
+    [ ] proper EsNo estimation
+    [ ] some sort of real time GUI display to watch signal evolving
+    [ ] est SNR or Eb/No of recieved signal
+    [ ] way to fall out of sync
+#}
+
+function ofdm_rx(filename, interleave_frames = 1, error_pattern_filename)
+  ofdm_lib;
+  ldpc;
+  gp_interleaver;
+  more off;
+
+  % init modem
+
+  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
+  states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
+  ofdm_load_const;
+  states.verbose = 1;
+
+  % Set up LDPC code
+
+  mod_order = 4; bps = 2; modulation = 'QPSK'; mapping = 'gray';
+  demod_type = 0; decoder_type = 0; max_iterations = 100;
+
+  EsNo = 10; % TODO: fixme
+
+  init_cml('/home/david/Desktop/cml/');
+  load HRA_112_112.txt
+  [code_param framesize rate] = ldpc_init_user(HRA_112_112, modulation, mod_order, mapping);
+  assert(Nbitsperframe == code_param.code_bits_per_frame);
+
+  % load real samples from file
+
+  Ascale= 2E5*1.1491;
+  frx=fopen(filename,"rb"); rx = 2*fread(frx, Inf, "short")/4E5; fclose(frx);
+  Nsam = length(rx); Nframes = floor(Nsam/Nsamperframe);
+  prx = 1;
+
+  % buffers for interleaved frames
+
+  Nsymbolsperframe = code_param.code_bits_per_frame/bps
+  Nsymbolsperinterleavedframe = interleave_frames*Nsymbolsperframe
+  rx_np = zeros(1, Nsymbolsperinterleavedframe);
+  rx_amp = zeros(1, Nsymbolsperinterleavedframe);
+
+  % OK generate tx frame for BER calcs
+
+  rand('seed', 100);
+  tx_bits = []; tx_codewords = [];
+  for f=1:interleave_frames
+    atx_bits = round(rand(1,code_param.data_bits_per_frame));
+    tx_bits = [tx_bits atx_bits];
+    acodeword = LdpcEncode(atx_bits, code_param.H_rows, code_param.P_matrix);
+    tx_codewords = [tx_codewords acodeword];
+  end
+
+  % used for rx frame sync on interleaved symbols - we demod the
+  % entire interleaved frame to raw bits
+
+  tx_symbols = [];
+  for s=1:Nsymbolsperinterleavedframe
+    tx_symbols = [tx_symbols qpsk_mod( tx_codewords(2*(s-1)+1:2*s) )];
+  end
+
+  tx_symbols = gp_interleave(tx_symbols);
+
+  tx_bits_raw = [];
+  for s=1:Nsymbolsperinterleavedframe
+    tx_bits_raw = [tx_bits_raw qpsk_demod(tx_symbols(s))];
+  end
+
+  % init logs and BER stats
+
+  rx_bits = []; rx_np_log = []; timing_est_log = []; delta_t_log = []; foff_est_hz_log = [];
+  phase_est_pilot_log = [];
+  Terrs = Tbits = Terrs_coded = Tbits_coded = Tpackets = Tpacketerrs = 0;
+  Nbitspervocframe = 28;
+  Nerrs_coded_log = Nerrs_log = [];
+  error_positions = [];
+
+  % 'prime' rx buf to get correct coarse timing (for now)
+
+  prx = 1;
+  nin = Nsamperframe+2*(M+Ncp);
+  states.rxbuf(Nrxbuf-nin+1:Nrxbuf) = rx(prx:nin);
+  prx += nin;
+
+  state = 'searching'; frame_count = 0;
+
+  % main loop ----------------------------------------------------------------
+
+  for f=1:Nframes
+
+    % insert samples at end of buffer, set to zero if no samples
+    % available to disable phase estimation on future pilots on last
+    % frame of simulation
+
+    lnew = min(Nsam-prx,states.nin);
+    rxbuf_in = zeros(1,states.nin);
+
+    if lnew
+      rxbuf_in(1:lnew) = rx(prx:prx+lnew-1);
+    end
+    prx += states.nin;
+
+    [rx_bits_raw states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
+    frame_count++;
+
+    % update sliding windows of rx-ed symbols and symbol amplitudes
+
+    rx_np(1:Nsymbolsperinterleavedframe-Nsymbolsperframe) = rx_np(Nsymbolsperframe+1:Nsymbolsperinterleavedframe);
+    rx_np(Nsymbolsperinterleavedframe-Nsymbolsperframe+1:Nsymbolsperinterleavedframe) = arx_np;
+    rx_amp(1:Nsymbolsperinterleavedframe-Nsymbolsperframe) = rx_amp(Nsymbolsperframe+1:Nsymbolsperinterleavedframe);
+    rx_amp(Nsymbolsperinterleavedframe-Nsymbolsperframe+1:Nsymbolsperinterleavedframe) = arx_amp;
+
+    printf("f: %d state: %s frame_count: %d\n", f, state, frame_count);
+
+    % 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.
+
+      for ff=1:interleave_frames
+        st = (ff-1)*Nbitsperframe+1; en = st + Nbitsperframe - 1;
+        errors = xor(tx_bits_raw(st:en), rx_bits_raw);
+        Nerrs = sum(errors); 
+        printf("  ff: %d Nerrs: %d\n", ff, Nerrs);
+        if Nerrs/Nbitsperframe < 0.1
+          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
+          frame_count = ff - interleave_frames;
+        end
+      end
+    end
+
+    if strcmp(state,'synced')  
+      if Nerrs/Nbitsperframe > 0.2
+        %next_state = 'searching';
+      end
+    end
+
+    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
+
+      states.sample_point = states.timing_est = 1;
+      states.foff_est_hz = foff_est;
+    end
+    
+    if strcmp(state,'synced')
+
+      % we are in sync so log states
+
+      rx_np_log = [rx_np_log arx_np];
+      timing_est_log = [timing_est_log states.timing_est];
+      delta_t_log = [delta_t_log states.delta_t];
+      foff_est_hz_log = [foff_est_hz_log states.foff_est_hz];
+      phase_est_pilot_log = [phase_est_pilot_log; aphase_est_pilot_log];
+    end
+
+    if strcmp(state,'synced') && (frame_count == interleave_frames)
+
+      % de-interleave QPSK symbols
+
+      arx_np = gp_deinterleave(rx_np);
+      arx_amp = gp_deinterleave(rx_amp);
+
+      % measure uncoded bit errors per modem frame
+
+      rx_bits_raw = [];
+      for s=1:Nsymbolsperinterleavedframe
+        rx_bits_raw = [rx_bits_raw qpsk_demod(rx_np(s))];
+      end
+      for ff=1:interleave_frames
+        st = (ff-1)*Nbitsperframe+1; en = st+Nbitsperframe-1;
+        errors = xor(tx_bits_raw(st:en), rx_bits_raw(st:en));
+        Nerrs = sum(errors);
+        if Nerrs/Nbitsperframe < 0.2
+          Terrs += Nerrs;
+          Nerrs_log = [Nerrs_log Nerrs];
+          Tbits += Nbitsperframe;
+        end
+      end
+
+      % LDPC decode
+
+      rx_bits = [];
+      for ff=1:interleave_frames
+        st = (ff-1)*Nbitsperframe/bps+1; en = st + Nbitsperframe/bps - 1;
+        rx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, arx_np(st:en), min(EsNo,30), arx_amp(st:en));
+        rx_bits = [rx_bits rx_codeword(1:code_param.data_bits_per_frame)];
+      end
+
+      errors_coded = xor(tx_bits, rx_bits);
+      Nerrs_coded = sum(errors_coded);
+      if Nerrs/Nbitsperframe < 0.2
+        Terrs_coded += Nerrs_coded;
+        Tbits_coded += code_param.data_bits_per_frame*interleave_frames;
+        error_positions = [error_positions errors_coded];
+
+        % measure packet errors based on Codec 2 packet size
+
+        Nvocframes = floor(code_param.data_bits_per_frame*interleave_frames/Nbitspervocframe);
+        for fv=1:Nvocframes
+          st = (fv-1)*Nbitspervocframe + 1;
+          en = st + Nbitspervocframe - 1;
+          Nvocpacketerrs = sum(xor(tx_bits(st:en), rx_bits(st:en)));
+          if Nvocpacketerrs
+            Tpacketerrs++;
+          end
+          Tpackets++;
+          Nerrs_coded_log = [Nerrs_coded_log Nvocpacketerrs];
+        end
+      end
+      printf("  Nerrs_coded: %d\n", Nerrs_coded);
+
+      frame_count = 0;
+    end
+  end
+
+  printf("Coded BER: %5.4f Tbits: %5d Terrs: %5d PER: %5.4f Tpacketerrs: %5d Tpackets: %5d\n", 
+         Terrs_coded/Tbits_coded, Tbits_coded, Terrs_coded, Tpacketerrs/Tpackets, Tpacketerrs, Tpackets);
+  printf("Raw BER..: %5.4f Tbits: %5d Terrs: %5d\n", Terrs/Tbits, Tbits, Terrs);
+
+  figure(1); clf; 
+  plot(rx_np_log,'+');
+  mx = max(abs(rx_np_log))
+  axis([-mx mx -mx mx]);
+  title('Scatter');
+
+  figure(2); clf;
+  plot(phase_est_pilot_log(:,2:Nc+1),'g+', 'markersize', 5); 
+  title('Phase est');
+  axis([1 length(phase_est_pilot_log) -pi pi]);  
+
+  figure(3); clf;
+  subplot(211)
+  stem(delta_t_log)
+  title('delta t');
+  subplot(212)
+  plot(timing_est_log);
+  title('timing est');
+
+  figure(4); clf;
+  plot(foff_est_hz_log)
+  mx = max(abs(foff_est_hz_log));
+  axis([1 max(Nframes,2) -mx mx]);
+  title('Fine Freq');
+  ylabel('Hz')
+
+  figure(5); clf;
+  subplot(211)
+  stem(Nerrs_log);
+  title('Uncoded errrors/modem frame')
+  axis([1 length(Nerrs_log) 0 Nbitsperframe*rate/2]);
+  subplot(212)
+  stem(Nerrs_coded_log);
+  title('Coded errrors/vocoder frame')
+  axis([1 length(Nerrs_coded_log) 0 Nbitspervocframe/2]);
+
+  if nargin == 3
+    fep = fopen(error_pattern_filename, "wb");
+    fwrite(fep, error_positions, "short");
+    fclose(fep);
+  end
+endfunction
diff --git a/codec2/branches/0.7/octave/ofdm_tx.m b/codec2/branches/0.7/octave/ofdm_tx.m
new file mode 100644 (file)
index 0000000..e057998
--- /dev/null
@@ -0,0 +1,189 @@
+% ofdm_tx.m
+% David Rowe April 2017
+%
+% File based ofdm tx.  Generate a file of ofdm samples, inclduing
+% optional channel simulation.
+
+#{
+  Examples:
+  i) 4 frame interleaver, 10 seconds, AWGN channel at Eb/No=3dB
+
+    octave:4> ofdm_tx('awgn_ebno_3dB_700d.raw',4, 10,3);
+
+  ii) 4 frame interleaver, 10 seconds, HF channel at Eb/No=6dB
+
+    ofdm_tx('hf_ebno_6dB_700d.raw', 4, 10, 6, 'hf');
+#}
+
+
+#{
+  TODO: 
+    [ ] measure and report raw and coded BER
+    [ ] maybe 10s worth of frames, sync up to any one automatically
+        + or start with maybe 10 frames
+        + measure BER match on each one
+    [ ] model clipping/PA compression
+    [ ] sample clock offsets
+    [ ] compare with same SNR from pathsim
+    [ ] How to pack arbitrary frames into ofdm frame and codec 2 frames
+        + integer number of ofdm frames?
+        + how to sync at other end
+#}
+
+function ofdm_tx(filename, Nsec, interleave_frames = 1, EbNodB=100, channel='awgn', freq_offset_Hz=0)
+  ofdm_lib;
+  ldpc;
+  gp_interleaver;
+
+  % init modem
+
+  Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
+  states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
+  ofdm_load_const;
+
+  % Set up LDPC code
+
+  mod_order = 4; bps = 2; modulation = 'QPSK'; mapping = 'gray';
+
+  init_cml('/home/david/Desktop/cml/');
+  load HRA_112_112.txt
+  [code_param framesize rate] = ldpc_init_user(HRA_112_112, modulation, mod_order, mapping);
+  assert(Nbitsperframe == code_param.code_bits_per_frame);
+
+  % Generate fixed test frame of tx bits and run OFDM modulator
+
+  Nrows = Nsec*Rs;
+  Nframes = floor((Nrows-1)/Ns);
+
+  % Adjust Nframes so we have an integer number of interleaver frames
+  % in simulation
+
+  Nframes = interleave_frames*round(Nframes/interleave_frames);
+
+  % OK generate an interleaver frame of codewords from random data bits
+
+  rand('seed', 100);
+  tx_bits = tx_symbols = [];
+  for f=1:interleave_frames
+    atx_bits = round(rand(1,code_param.data_bits_per_frame));
+    tx_bits = [tx_bits atx_bits];
+    codeword = LdpcEncode(atx_bits, code_param.H_rows, code_param.P_matrix);
+    for b=1:2:Nbitsperframe
+      tx_symbols = [tx_symbols qpsk_mod(codeword(b:b+1))];
+    end
+  end
+  tx_symbols = gp_interleave(tx_symbols);
+  
+  atx = [];
+  for f=1:interleave_frames
+    st = (f-1)*Nbitsperframe/bps+1; en = st + Nbitsperframe/bps-1;
+    atx = [atx ofdm_txframe(states, tx_symbols(st:en))];
+  end
+  tx = [];
+  for f=1:Nframes/interleave_frames
+    tx = [tx atx];
+  end
+
+  % not very pretty way to process analog signals with exactly the same channel
+  % todo: work out a cleaner way
+
+  analog_hack = 0; rx_filter = 0;
+  if analog_hack || rx_filter
+
+    % simulated SSB tx filter
+
+    [b, a] = cheby1(4, 3, [600, 2600]/(Fs/2));
+    h = freqz(b,a,(600:2600)/(Fs/(2*pi)));
+    filt_gain = (2600-600)/sum(abs(h) .^ 2);   % ensures power after filter == before filter
+  end
+
+  if analog_hack
+    % load analog signal and convert to complex
+
+    s = load_raw('../raw/ve9qrp_10s.raw')';
+    tx = hilbert(s);
+
+    % ssb tx filter
+
+    tx = filter(b,a,sqrt(filt_gain)*tx);
+
+    % normalise power to same as ofdm tx
+
+    nom_tx_pwr = 2/(Ns*(M*M)) + Nc/(M*M);
+    tx_pwr = var(tx);
+    tx *= sqrt(nom_tx_pwr/tx_pwr);
+  end
+
+  Nsam = length(tx);
+
+  % channel simulation
+
+  EsNo = rate * bps * (10 .^ (EbNodB/10));
+  variance = 1/(M*EsNo/2);
+  woffset = 2*pi*freq_offset_Hz/Fs;
+
+  SNRdB = EbNodB + 10*log10(700/3000);
+  printf("EbNo: %3.1f dB  SNR(3k) est: %3.1f dB  foff: %3.1fHz ", EbNodB, SNRdB, freq_offset_Hz);
+
+  % set up HF model ---------------------------------------------------------------
+
+  if strcmp(channel, 'hf')
+    randn('seed',1);
+
+    % some typical values, or replace with user supplied
+
+    dopplerSpreadHz = 1; path_delay_ms = 1;
+
+    path_delay_samples = path_delay_ms*Fs/1000;
+    printf("Doppler Spread: %3.2f Hz Path Delay: %3.2f ms %d samples\n", dopplerSpreadHz, path_delay_ms, path_delay_samples);
+
+    % generate same fading pattern for every run
+
+    randn('seed',1);
+
+    spread1 = doppler_spread(dopplerSpreadHz, Fs, (Nsec*(M+Ncp)/M)*Fs*1.1);
+    spread2 = doppler_spread(dopplerSpreadHz, Fs, (Nsec*(M+Ncp)/M)*Fs*1.1);
+
+    % sometimes doppler_spread() doesn't return exactly the number of samples we need
+    assert(length(spread1) >= Nsam, "not enough doppler spreading samples");
+    assert(length(spread2) >= Nsam, "not enough doppler spreading samples");
+  end
+
+  rx = tx;
+
+  if strcmp(channel, 'hf')
+    rx  = tx(1:Nsam) .* spread1(1:Nsam);
+    rx += [zeros(1,path_delay_samples) tx(1:Nsam-path_delay_samples)] .* spread2(1:Nsam);
+
+    % normalise rx power to same as tx
+
+    nom_rx_pwr = 2/(Ns*(M*M)) + Nc/(M*M);
+    rx_pwr = var(rx);
+    rx *= sqrt(nom_rx_pwr/rx_pwr);
+  end
+
+  rx = rx .* exp(j*woffset*(1:Nsam));
+
+  % note variance/2 as we are using real() operator, mumble,
+  % reflection of -ve freq to +ve, mumble, hand wave
+
+  noise = sqrt(variance/2)*0.5*randn(1,Nsam);
+  rx = real(rx) + noise;
+  printf("measured SNR: %3.2f dB\n", 10*log10(var(real(tx))/var(noise))+10*log10(4000) - 10*log10(3000));
+
+  if rx_filter
+    % ssb rx filter
+    rx = filter(b,a,sqrt(filt_gain)*rx);
+  end
+
+  % adjusted by experiment to match rms power of early test signals
+
+  Ascale = 2E5*1.1491;
+
+  frx=fopen(filename,"wb"); fwrite(frx, Ascale*rx, "short"); fclose(frx);
+endfunction
diff --git a/codec2/branches/0.7/octave/oqpsk.m b/codec2/branches/0.7/octave/oqpsk.m
new file mode 100644 (file)
index 0000000..49f54ce
--- /dev/null
@@ -0,0 +1,521 @@
+% oqpsk.m
+% David Rowe Jan 2017
+%
+% Unfiltered OQPSK modem implementation and simulations to test,
+% derived from GMSK modem in gmsk.m
+%
+% Usage: see "choose one of these to run" at the end of this file.
+
+rand('state',1); 
+randn('state',1);
+graphics_toolkit ("gnuplot");
+format
+more off;
+
+% init modem states
+
+function oqpsk_states = oqpsk_init(oqpsk_states, Rs)
+
+  % general 
+
+  verbose = oqpsk_states.verbose;
+  oqpsk_states.Fs  = 4*Rs;
+  oqpsk_states.Rs  = Rs;
+  oqpsk_states.bps = 2;              % two bit/symbol for QPSK    
+
+  M = oqpsk_states.M = oqpsk_states.Fs/oqpsk_states.Rs;
+  assert(floor(M) == M, "oversampling factor M must be an integer");
+  assert(floor(M/2) == M/2, "(oversampling factor M)/2 must be an integer to offset QPSK");
+endfunction
+
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+
+% Unfiltered OQPSK modulator 
+
+function [tx tx_symb] = oqpsk_mod(oqpsk_states, tx_bits)
+  M = oqpsk_states.M;
+  bps = oqpsk_states.bps;
+  nsym = length(tx_bits)/bps;
+  nsam = nsym*M;
+  verbose = oqpsk_states.verbose;
+
+  % Map bits to Gray coded QPSK symbols
+
+  tx_symb = zeros(1,nsym);
+
+  for i=1:nsym
+    tx_symb(i) = qpsk_mod(tx_bits(2*i-1:2*i))*exp(j*pi/4);
+  end
+  
+  % Oversample by M (sample and hold) to create unfiltered QPSK
+
+  tx = zeros(1, nsam);
+  for i=1:nsym
+    tx((i-1)*M+1:(i*M)) = tx_symb(i);
+  end
+  
+  % delay Q arm by half of a symbol to make OQPSK
+
+  tx = [real(tx) zeros(1,M/2)] + j*[zeros(1,M/2) imag(tx)];
+endfunction
+
+
+#{ 
+
+  Unfiltered OQPSK demodulator function, with (optional) phase and
+  timing estimation.  Adapted from Fig 8 of [1].  See also gmsk.m and
+  [2].
+
+  Note demodulator returns phase corrected symbols sampled at ideal
+  timing instant.  These symbols may have a m*pi/2 phase ambiguity due
+  to properties of phase tracking loop.  The caller is responsible for
+  determining this ambiguity and recovering the actual bits.
+
+  [1] GMSK demodulator in IEEE Trans on Comms, Muroyta et al, 1981,
+  "GSM Modulation for Digital Radio Telephony".
+
+  [2] GMSK Modem Simulation, http://www.rowetel.com/?p=3824
+
+#}
+
+
+function [rx_symb rx_int filt_log dco_log timing_adj Toff] = oqpsk_demod(oqpsk_states, rx)
+  M = oqpsk_states.M;
+  Rs = oqpsk_states.Rs;
+  Fs = oqpsk_states.Fs;
+  nsam = length(rx);
+  nsym = floor(nsam/M);
+  verbose = oqpsk_states.verbose;
+
+  timing_angle_log = zeros(1,length(rx));
+  rx_int = zeros(1,length(rx));
+  dco_log = filt_log = zeros(1,nsam);
+
+  % Unfiltered PSK - integrate energy in symbols M long in re and im arms
+
+  rx_int = conv(rx,ones(1,M))/M;
+
+  % phase and fine frequency tracking and correction ------------------------
+
+  if oqpsk_states.phase_est
+      % DCO design from "Introduction To Phase-Lock Loop System Modeling", Wen Li
+      % http://www.ece.ualberta.ca/~ee401/parts/data/PLLIntro.pdf
+
+      eta = 0.707;
+      wn = 2*pi*10*(Rs/4800);  % (Rs/4800) -> found reducing the BW benefical with falling Rs
+      Ts = 1/Fs;
+      g1 = 1 - exp(-2*eta*wn*Ts);
+      g2 = 1 + exp(-2*eta*wn*Ts) - 2*exp(-eta*wn*Ts)*cos(wn*Ts*sqrt(1-eta*eta));
+      Gpd = 2/pi;
+      Gvco = 1;
+      G1 = g1/(Gpd*Gvco);  G2 = g2/(Gpd*Gvco);
+      %printf("g1: %e g2: %e G1: %e G2: %e\n", g1, g2, G1, G2);
+  
+      filt_prev = dco = lower = ph_err_filt = ph_err = 0;
+  end
+
+  if  oqpsk_states.timing_est    
+      % w is the ref sine wave at the timing clock frequency
+      % tw is the length of the window used to estimate timing
+
+      tw = 200*M;
+      k = 1;
+      xr_log = []; xi_log = [];
+      w_log = [];
+      timing_clock_phase = 0;
+      timing_angle = 0;
+      timing_angle_log = zeros(1,nsam);
+  end
+
+  % Sample by sample processing loop for timing and phase est.  Note
+  % this operates at sample rate Fs, unlike many PSK modems that
+  % operate at the symbol rate Rs
+
+  for i=1:nsam
+
+    if oqpsk_states.timing_est
+
+      % update sample timing estimate every tw samples, free wheel
+      % rest of the time
+
+      if mod(i,tw) == 0
+        l = i - tw+1;
+        xr = abs(real(rx_int(l:l+tw-1)));
+        xi = abs(imag(rx_int(l:l+tw-1)));
+        w = exp(j*(l:l+tw-1)*2*pi*Rs/Fs);
+        X = xr * w';
+        timing_clock_phase = timing_angle = angle(X);
+        k++;
+        xr_log = [xr_log xr];
+        xi_log = [xi_log xi];
+        w_log = [w_log w];
+      else
+        timing_clock_phase += (2*pi)/M;
+      end
+      timing_angle_log(i) = timing_angle;
+    end
+
+    if oqpsk_states.phase_est
+
+      % PLL per-sample processing
+
+      rx_int(i) *= exp(-j*dco);
+      ph_err = sign(real(rx_int(i))*imag(rx_int(i)))*cos(timing_clock_phase);
+      lower = ph_err*G2 + lower;
+      filt  = ph_err*G1 + lower;
+      dco_log(i) = dco; 
+      dco   = dco + filt;
+      filt_log(i) = filt;
+
+    end
+  
+  end
+
+  % final adjustment of timing output to take into account slowly
+  % moving estimates due to sample clock offset.  Unwrap ensures that
+  % when timing angle jumps from -pi to pi we move to the next symbol
+  % and frame sync isn't broken
+
+  timing_adj = timing_angle_log*M/(2*pi); 
+  timing_adj_uw = unwrap(timing_angle_log)*M/(2*pi); 
+  % Toff = floor(2*M+timing_adj);
+  Toff = floor(timing_adj_uw+0.5);
+
+  % sample integrator output at correct timing instant
+    
+  k = 1;
+  re_syms = im_syms = zeros(1,nsym);  
+  rx_symb = [];
+  for i=M:M:nsam
+    if i-Toff(i)+M/2 <= nsam
+      re_syms(k) = real(rx_int(i-Toff(i)));
+      im_syms(k) = imag(rx_int(i-Toff(i)+M/2));
+      %re_syms(k) = real(rx_int(i));
+      %im_syms(k) = imag(rx_int(i));
+      rx_symb = [rx_symb re_syms(k) + j*im_syms(k)];
+      k++;
+    end
+  end
+  
+endfunction
+
+
+% Test modem over a range Eb/No points in an AWGN channel.  Can
+% simulate a variety of channel impairments and performs ambiguity
+% resolution.
+
+function sim_out = oqpsk_test(sim_in)
+  bitspertestframe =  sim_in.bitspertestframe;
+  nbits =  sim_in.nbits;
+  EbNodB = sim_in.EbNodB;
+  verbose = sim_in.verbose;
+  Rs = 4800;
+
+  oqpsk_states.verbose = verbose;
+  oqpsk_states.coherent_demod = sim_in.coherent_demod;
+  oqpsk_states.phase_est     = sim_in.phase_est;
+  oqpsk_states.timing_est    = sim_in.timing_est;
+  oqpsk_states = oqpsk_init(oqpsk_states, Rs);
+  M = oqpsk_states.M;
+  Fs = oqpsk_states.Fs;
+  Rs = oqpsk_states.Rs;
+  sample_clock_offset_ppm = sim_in.sample_clock_offset_ppm;
+
+  tx_testframe = round(rand(1, bitspertestframe));
+  ntestframes = floor(nbits/bitspertestframe);
+  tx_bits = [];
+  for i=1:ntestframes
+    tx_bits = [tx_bits tx_testframe];
+  end
+
+  for ne = 1:length(EbNodB)
+    aEbNodB = EbNodB(ne);
+    EbNo = 10^(aEbNodB/10);
+    variance = Fs/(Rs*EbNo*oqpsk_states.bps);
+
+    [tx tx_symb] = oqpsk_mod(oqpsk_states, tx_bits);
+    if sample_clock_offset_ppm
+       tx = resample(tx, 1E6, 1E6-sample_clock_offset_ppm);
+    end
+    nsam = length(tx);
+    
+    phi = sim_in.phase_offset + 2*pi*sim_in.freq_offset*(1:nsam)/M;
+
+    noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+    st = 1+sim_in.timing_offset; en = length(tx);
+    rx = tx(st:en).*exp(j*phi(st:en)) + noise(st:en);
+
+    [rx_symb rx_int filt_log dco_log timing_adj Toff] = oqpsk_demod(oqpsk_states, rx);
+    
+    % OK so the phase and timing estimators get us close (e.g. a good
+    % scatter diagram), but no banana just yet.  One problem is the
+    % PLL can lock up on mulitples of pi/2.  Combinations of phase
+    % offsets can confuse the timing estimator. One tricky example is a
+    % phase offset of pi/2 which swaps I & Q, and with OQPSK (unlike
+    % MSK and friends) we can't easily tell which is I and which is Q
+    % after a phase rotation, e.g. could be IQIQIQI or QIQIQIQ
+
+    % So we need to determine the ambiguities:
+    %   a) could be m*pi/2 rotations of phase
+    %   b) could be I and Q swapped by timing est
+    %   c) time alignment of test frame
+      
+    nsymb = bitspertestframe/oqpsk_states.bps;
+    nrx_symb = length(rx_symb);
+    rx_bits = zeros(1, bitspertestframe);
+    atx_symb = tx_symb(1:nsymb);
+
+    % Treat I and Q as separate sequences, each with their own unique
+    % word.  In our case the UW is the whole test frame.  Correlate rx
+    % sequence with tx sequence at each possible offset through the
+    % received symbols to find the test frames.  Note we also
+    % correlate I of tx with Q of rx to trap any IQ swaps.
+    
+    % The sign of the I and Q correlation lets us sort out the pi/2
+    % phase rotation issue.
+
+    nerrs_tot = 0; nbits_tot = 0;
+
+    max_corr = real(atx_symb) * real(atx_symb)';
+    for offset=2:nrx_symb-nsymb+1
+      corr_ii(offset) = real(atx_symb) * real(rx_symb(offset:offset+nsymb-1))'/max_corr;
+      corr_qq(offset) = imag(atx_symb) * imag(rx_symb(offset:offset+nsymb-1))'/max_corr;
+      corr_iq(offset) = real(atx_symb) * imag(rx_symb(offset:offset+nsymb-1))'/max_corr;
+      corr_qi(offset) = imag(atx_symb) * real(rx_symb(offset:offset+nsymb-1))'/max_corr;
+      %printf("offset: %2d ii: % 5f qq: % 5f iq: % 5f qi: % 5f\n", 
+      %offset, corr_ii(offset), corr_qq(offset), corr_iq(offset), corr_qi(offset));
+
+      if abs(corr_ii(offset)) > 0.8
+
+        % no IQ swap, or time offset
+
+        i_sign = sign(corr_ii(offset));
+        q_sign = sign(corr_qq(offset));
+        arx_symb = i_sign*real(rx_symb(offset:offset+nsymb-1)) + j*q_sign*imag(rx_symb(offset:offset+nsymb-1));
+
+        for i=1:nsymb
+          rx_bits(2*i-1:2*i) = qpsk_demod(arx_symb(i)*exp(-j*pi/4));
+        end
+        nerrs = sum(xor(tx_testframe, rx_bits));
+        if verbose > 2
+          printf("offset: %5d swap: %d i_sign: % 2.1f q_sign: % 2.1f nerr: %d\n", 
+          offset, 0, i_sign, q_sign, nerrs);
+        end
+        nerrs_tot += nerrs;
+        nbits_tot += bitspertestframe;
+      end
+
+      if abs(corr_qi(offset)) > 0.8
+
+        % IQ swap, I part in Q part of symbol before
+
+        i_sign = sign(corr_iq(offset-1));
+        q_sign = sign(corr_qi(offset));
+        arx_symb = i_sign*imag(rx_symb(offset-1:offset+nsymb-2)) + j*q_sign*real(rx_symb(offset:offset+nsymb-1));
+
+        for i=1:nsymb
+          rx_bits(2*i-1:2*i) = qpsk_demod(arx_symb(i)*exp(-j*pi/4));
+        end
+        nerrs = sum(xor(tx_testframe, rx_bits));
+        if verbose > 1
+          printf("offset: %5d swap: %d i_sign: % 2.1f q_sign: % 2.1f nerr: %d\n", 
+                 offset, 1, i_sign, q_sign, nerrs);
+        end
+        nerrs_tot += nerrs;
+        nbits_tot += bitspertestframe;
+      end
+    end
+
+    TERvec(ne) = nerrs_tot;
+    BERvec(ne) = nerrs_tot/nbits_tot;
+    
+    if verbose > 0
+      printf("EbNo dB: %3.1f Nbits: %d Nerrs: %d BER: %4.3f BER Theory: %4.3f\n", 
+      aEbNodB, nbits_tot, nerrs_tot, BERvec(ne), 0.5*erfc(sqrt(EbNo)));
+    end
+
+    if find(sim_in.plots == 1)
+      figure(1); clf;
+      subplot(211)
+      stem(real(tx))
+      title('Tx samples');
+      ylabel('Inphase');
+      subplot(212)
+      stem(imag(tx))
+      ylabel('Quadrature');
+    end
+
+    if find(sim_in.plots == 2)
+      figure(2); clf;
+      f = fftshift(fft(rx));
+      Tx = 20*log10(abs(f));
+      plot((1:length(f))*Fs/length(f) - Fs/2, Tx)
+      grid;
+      title('OQPSK Demodulator Input Spectrum');
+    end
+
+    if find(sim_in.plots == 3)
+      figure(3); clf;
+      nplot = min(16, nbits/oqpsk_states.bps);
+      title('Rx Integrator');
+      subplot(211)
+      stem(real(rx_int(1:nplot*M)))
+      axis([1 nplot*M -1 1])
+      subplot(212)
+      stem(imag(rx_int(1:nplot*M)))
+      axis([1 nplot*M -1 1])
+    end
+
+    if find(sim_in.plots == 4)
+      figure(4); clf;
+      subplot(211);
+      plot(filt_log);
+      title('PLL filter')
+      subplot(212);
+      plot(dco_log);
+      title('PLL DCO phase');
+    end
+
+    if find(sim_in.plots == 5)
+      figure(5); clf;
+      subplot(211)
+      plot(timing_adj);
+      title('Timing est');
+      subplot(212)
+      plot(Toff);
+      title('Timing est unwrap');
+    end
+
+    if find(sim_in.plots == 6)
+      figure(6); clf;
+      st = floor(0.5*nrx_symb);
+      plot(rx_symb(st:nrx_symb), '+');
+      title('Scatter Diagram');
+      axis([-1.5 1.5 -1.5 1.5])
+    end
+
+    if find(sim_in.plots == 7)
+      figure(7); clf;
+      subplot(211)
+      plot(corr_ii);
+      axis([1 length(corr_ii) -1.2 1.2]);
+      title('corr ii');
+      subplot(212)
+      plot(corr_qi);
+      axis([1 length(corr_ii) -1.2 1.2]);
+      title('corr qi');
+    end
+
+    if find(sim_in.plots == 8)
+      figure(8); clf;
+      subplot(211);
+      stem(real(arx_symb));
+      title('Rx symbols')
+      subplot(212);
+      stem(imag(arx_symb));
+    end
+
+    if find(sim_in.plots == 9)
+      figure(9); clf;
+      subplot(211)
+      stem(tx_testframe(1:min(20,length(rx_bits))))
+      title('Tx Bits')
+      subplot(212)
+      stem(rx_bits(1:min(20,length(rx_bits))))
+      title('Rx Bits')
+    end
+  end
+
+  sim_out.TERvec = TERvec;
+  sim_out.BERvec = BERvec;
+  sim_out.Rs = oqpsk_states.Rs;
+endfunction
+
+
+function run_oqpsk_single
+  sim_in.coherent_demod   = 1;
+  sim_in.phase_est        = 1;
+  sim_in.timing_est       = 1;
+  sim_in.bitspertestframe = 100;
+  sim_in.nbits            = 10000;
+  sim_in.EbNodB           = 4;
+  sim_in.verbose          = 1;
+  sim_in.phase_offset     = 3*pi/4;  % in radians
+  sim_in.timing_offset    = 4;       % in samples 0..M-1
+  sim_in.freq_offset      = 0.001;   % fraction of Symbol Rate
+  sim_in.plots            = [1 2 4 5 6 7];
+  sim_in.sample_clock_offset_ppm = 100;
+
+  sim_out = oqpsk_test(sim_in);
+endfunction
+
+
+% Generate a bunch of BER versus Eb/No curves for various demods
+
+function run_oqpsk_curves
+  sim_in.coherent_demod = 1;
+  sim_in.EbNodB = 2:8;
+  sim_in.verbose = 1;
+  sim_in.phase_est        = 1;
+  sim_in.timing_est       = 1;
+  sim_in.bitspertestframe = 100;
+  sim_in.nbits            = 50000;
+  sim_in.phase_offset     = 3*pi/4;  % in radians
+  sim_in.timing_offset    = 4;       % in samples 0..M-1
+  sim_in.freq_offset      = 0.001;   % fraction of Symbol Rate
+  sim_in.plots            = [];
+  sim_in.sample_clock_offset_ppm = 0;
+
+  oqpsk_coh = oqpsk_test(sim_in);
+
+  Rs = oqpsk_coh.Rs;
+  EbNo  = 10 .^ (sim_in.EbNodB/10);
+  oqpsk_theory.BERvec = 0.5*erfc(sqrt(EbNo));
+
+  % BER v Eb/No curves
+
+  figure;
+  clf;
+  semilogy(sim_in.EbNodB, oqpsk_theory.BERvec,'r+-;OQPSK theory;')
+  hold on;
+  semilogy(sim_in.EbNodB, oqpsk_coh.BERvec,'g+-;OQPSK sim;')
+  hold off;
+  grid("minor");
+  axis([min(sim_in.EbNodB) max(sim_in.EbNodB) 1E-4 1])
+  legend("boxoff");
+  xlabel("Eb/No (dB)");
+  ylabel("Bit Error Rate (BER)")
+endfunction
+
+
+% Choose one of these to run ------------------------------------------
+
+run_oqpsk_single
+%run_oqpsk_curves
+
diff --git a/codec2/branches/0.7/octave/phase.m b/codec2/branches/0.7/octave/phase.m
new file mode 100644 (file)
index 0000000..f973590
--- /dev/null
@@ -0,0 +1,56 @@
+% phase.m
+% David Rowe August 2009
+% experiments with phase for sinusoidal codecs
+
+function phase(samname, F0, png)
+  Wo=2*pi*F0/8000;
+  P=2*pi/Wo;
+  L = floor(pi/Wo);
+  Nsam = 16000;
+  N = 80;
+  F = Nsam/N;
+  A = 10000/L;
+  phi = zeros(1,L);
+  s = zeros(1,Nsam);
+  
+  for m=floor(L/2):L
+    phi_off(m) = -m*Wo*8;
+  end
+
+  for f=1:F
+    phi(1) = phi(1) + Wo*N;
+    phi(1) = mod(phi(1),2*pi);
+  
+    for m=1:L
+      phi(m) = m*phi(1);
+    end
+
+    x = zeros(1,N);
+    for m=1:L
+      x = x + A*cos(m*Wo*(0:(N-1)) + phi(m));
+    endfor
+    s((f-1)*N+1:f*N) = x;
+  endfor
+
+  figure(1);
+  clf;
+  plot(s(1:250));
+
+  fs=fopen(samname,"wb");
+  fwrite(fs,s,"short");
+  fclose(fs);
+
+  if (nargin == 3)
+      % small image to fit blog
+
+      __gnuplot_set__ terminal png size 450,300
+      ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname);
+      eval(ss)
+      replot;
+
+      % for some reason I need this to stop large plot getting wiped
+      __gnuplot_set__ output "/dev/null"
+  endif
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/phase2.m b/codec2/branches/0.7/octave/phase2.m
new file mode 100644 (file)
index 0000000..5c148f3
--- /dev/null
@@ -0,0 +1,57 @@
+% phase2.m
+% David Rowe Sep 2009
+% experiments with phase for sinusoidal codecs, looking at phase
+% of excitation with real Am samples from hts1
+
+function phase2(samname, png)
+  N = 16000;
+
+  f=43;
+  model = load("../src/hts1a_phase_model.txt");
+  phase = load("../src/hts1a_phase_phase.txt");
+  Wo = model(f,1);
+  P=2*pi/Wo;
+  L = model(f,2);
+  A = model(f,3:(L+2));
+  phi = phase(f,1:L);
+  phi = zeros(1,L);
+  phi(3) = -pi/2;
+  phi(4) = -pi/4;
+  phi(5) = pi/2;
+
+  s = zeros(1,N);
+
+  for m=3:5
+    s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m));
+    s = s + s_m;
+  endfor
+
+  figure(1);
+  clf;
+  plot(s(1:250));
+
+  figure(2);
+  clf;
+  subplot(211)
+  plot((1:L)*Wo*4000/pi, 20*log10(A),'+');
+  subplot(212)
+  plot((1:L)*Wo*4000/pi, phi,'+');
+
+  fs=fopen(samname,"wb");
+  fwrite(fs,s,"short");
+  fclose(fs);
+
+  if (nargin == 2)
+      % small image to fit blog
+
+      __gnuplot_set__ terminal png size 450,300
+      ss = sprintf("__gnuplot_set__ output \"%s.png\"", samname);
+      eval(ss)
+      replot;
+
+      % for some reason I need this to stop large plot getting wiped
+      __gnuplot_set__ output "/dev/null"
+  endif
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/phasesecord.m b/codec2/branches/0.7/octave/phasesecord.m
new file mode 100644 (file)
index 0000000..a3cf251
--- /dev/null
@@ -0,0 +1,47 @@
+% phasesecord.m
+% David Rowe Aug 2012
+% Used to experiment with aproximations of phase of 2nd order systems
+
+function phasesecord(w,beta)
+
+  a = [1 -2*cos(w)*beta beta*beta];
+  b = 1;
+
+  [h w1] = freqz(b,a);
+
+  figure(1)
+  subplot(211)
+  plot(abs(h))
+  subplot(212)
+  plot(angle(h))
+
+  % for beta close to 1, we approximate 3 dB points as 1-beta above
+  % and below the resonance freq. Note this fails if w=0 as there is a
+  % double pole.  Lets sample the freq response at the 3dB points and
+  % w:
+
+  ws = [w-(1-beta) w w+(1-beta)];
+  [h w1] = freqz(b,a,ws);
+
+  % gain as a fraction of max, should be 3dB. Within 1.3 dB or for w > pi/8,
+  % gets innacurate near w=0 due to 2nd pole
+
+  printf("mag measured...:"); printf("% 4.3f ", abs(h)/max(abs(h)));
+
+  % measured angle, 45 deg from angle at w
+
+  printf("\nangle measured.: "); printf("% 5.3f ", angle(h));
+
+  % Our estimate of angle, (pi+w) is phase at resonance, at lower 3dB
+  % phase is pi/4 ahead, at upper 3B pi/4 behind.  -pi/2 is contribution of
+  % other pole at at -w to phase
+
+  ph_lower = (pi+w) + pi/4 - pi/2;
+  ph_res   =(pi+w) - pi/2;
+  ph_upper = (pi+w) - pi/4 - pi/2;
+  ph_ests = [ph_lower ph_res ph_upper];
+  ph_ests = ph_ests - 2*pi*(floor(ph_ests/(2*pi)) + 0.5);
+  printf("\nangle estimated:"); printf("% 5.3f ", ph_ests);
+  printf("\n");
+endfunction
+
diff --git a/codec2/branches/0.7/octave/pitch_test.m b/codec2/branches/0.7/octave/pitch_test.m
new file mode 100644 (file)
index 0000000..3fe0d1a
--- /dev/null
@@ -0,0 +1,39 @@
+% pitch_test.m
+% David Rowe Sep 2009
+% Constructs a sequence to test the pitch estimator
+
+function pitch_test(samname)
+  M=320;
+  F=200;
+
+  fs=fopen(samname,"wb");
+
+  f0 = 100;
+  for f=1:200
+    Wo=2*pi*f0/8000;
+    P=2*pi/Wo;
+    L = floor(pi/Wo);
+    A = 10000/L;
+    phi = zeros(1,L);
+    s = zeros(1,M);
+
+    for m=1:L
+      s = s + A*cos(m*Wo*(0:(M-1)) + phi(m));
+    endfor
+
+    figure(1);
+    clf;
+    plot(s);
+
+    fwrite(fs,s,"short");
+
+    f0 = f0 + 5;
+    if (f0 > 400)
+      f0 = 100;    
+    endif
+  endfor
+
+  fclose(fs);
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/pl.m b/codec2/branches/0.7/octave/pl.m
new file mode 100644 (file)
index 0000000..0d54788
--- /dev/null
@@ -0,0 +1,45 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plots a raw speech sample file, you can optionally specify the start and end
+% samples and create a large and small PNGs
+
+function pl(samname1, start_sam, end_sam, pngname)
+  
+  fs=fopen(samname1,"rb");
+  s=fread(fs,Inf,"short");
+
+  st = 1;
+  en = length(s);
+  if (nargin >= 2)
+    st = start_sam;
+  endif
+  if (nargin >= 3)
+    en = end_sam;
+  endif
+
+  figure(1);
+  clf;
+  plot(s(st:en));
+  axis([1 en-st 1.1*min(s) 1.1*max(s)]);
+  if (nargin == 4)
+
+    % small image
+
+    __gnuplot_set__ terminal png size 420,300
+    ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
+    eval(ss)
+    replot;
+
+    % larger image
+
+    __gnuplot_set__ terminal png size 800,600
+    ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
+    eval(ss)
+    replot;
+
+  endif
+
+endfunction
diff --git a/codec2/branches/0.7/octave/pl2.m b/codec2/branches/0.7/octave/pl2.m
new file mode 100644 (file)
index 0000000..c7af10c
--- /dev/null
@@ -0,0 +1,44 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+
+function pl2(samname1, samname2, start_sam, end_sam, offset)
+  
+  fs1=fopen(samname1,"rb");
+  s1=fread(fs1,Inf,"short");
+  fs2=fopen(samname2,"rb");
+  s2=fread(fs2,Inf,"short");
+
+  st1 = st2 = 1;
+  en1 = en2 = length(s1);
+  if (nargin >= 3)
+    st1 = st2 = start_sam;
+  endif
+  if (nargin >= 4)
+    en1 = en2 = end_sam;
+  endif
+
+  if (nargin == 5)
+    st2 += offset        
+    en2 += offset        
+  endif
+
+  figure(1);
+  clf;
+  subplot(211);
+  l1 = strcat("r;",samname1,";");
+  plot(s1(st1:en1), l1);
+  axis([1 en1-st1 min(s1(st1:en1)) max(s1(st1:en1))]);
+  subplot(212);
+  l2 = strcat("r;",samname2,";");
+  plot(s2(st2:en2),l2);
+  axis([1 en2-st2 min(s1(st2:en2)) max(s1(st2:en2))]);
+  figure(2)
+  plot(s1(st1:en1)-s2(st2:en2));
+  
+  f=fopen("diff.raw","wb");
+  d = s1(st1:en1)-s2(st2:en2);
+  fwrite(f,d,"short");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/plamp.m b/codec2/branches/0.7/octave/plamp.m
new file mode 100644 (file)
index 0000000..62b6893
--- /dev/null
@@ -0,0 +1,197 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plot ampltiude modelling information from dump files.
+
+function plamp(samname, f, samname2)
+  
+  % switch some stuff off to unclutter display
+
+  plot_lsp = 0;
+  plot_snr = 0;
+  plot_vsnr = 0;
+  plot_sw = 0;
+  plot_pw = 0;
+
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+
+  sw__name = strcat(samname,"_sw_.txt");
+  if (file_in_path(".",sw__name))
+    Sw_ = load(sw__name);
+  endif
+
+  ew_name = strcat(samname,"_ew.txt");
+  if (file_in_path(".",ew_name))
+    Ew = load(ew_name);
+  endif
+
+  rk_name = strcat(samname,"_rk.txt");
+  if (file_in_path(".",rk_name))
+    Rk = load(rk_name);
+  endif
+
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+
+  modelq_name = strcat(samname,"_qmodel.txt");
+  if (file_in_path(".",modelq_name))
+    modelq = load(modelq_name);
+  endif
+
+  pw_name = strcat(samname,"_pw.txt");
+  if (file_in_path(".",pw_name))
+    Pw = load(pw_name);
+  endif
+
+  lsp_name = strcat(samname,"_lsp.txt");
+  if (file_in_path(".",lsp_name))
+    lsp = load(lsp_name);
+  endif
+
+  phase_name = strcat(samname,"_phase.txt");
+  if (file_in_path(".",phase_name))
+    phase = load(phase_name);
+  endif
+
+  phase_name_ = strcat(samname,"_phase_.txt");
+  if (file_in_path(".",phase_name_))
+    phase_ = load(phase_name_);
+  endif
+
+  snr_name = strcat(samname,"_snr.txt");
+  if (file_in_path(".",snr_name))
+    snr = load(snr_name);
+  endif
+
+  % optional second file, for exploring post filter
+
+  model2q_name = " ";
+  if nargin == 3
+    model2q_name = strcat(samname2,"_qmodel.txt");
+    if file_in_path(".",modelq_name)
+      model2q = load(model2q_name);
+    end
+  end
+
+  Ew_on = 1;
+  k = ' ';
+  do 
+    figure(1);
+    clf;
+%    s = [ Sn(2*(f-2)-1,:) Sn(2*(f-2),:) ];
+    s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+    size(s);
+    plot(s);
+    axis([1 length(s) -20000 20000]);
+
+    figure(2);
+    Wo = model(f,1);
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;r");
+    axis([1 4000 -10 80]);
+    hold on;
+    if plot_sw
+      plot((0:255)*4000/256, Sw(f,:),";Sw;");
+    end
+    if (file_in_path(".",modelq_name))
+      Amq = modelq(f,3:(L+2));
+      plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;g" );
+      if (file_in_path(".",pw_name) && plot_pw)
+        plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;c");
+      endif    
+      signal = Am * Am';
+      noise = (Am-Amq) * (Am-Amq)'; 
+      snr1 = 10*log10(signal/noise);
+      Am_err_label = sprintf(";Am error SNR %4.2f dB;m",snr1);
+      plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am), Am_err_label);
+    endif
+
+    if file_in_path(".",model2q_name)
+      Amq2 = model2q(f,3:(L+2));
+      plot((1:L)*Wo*4000/pi, 20*log10(Amq2),";Amq2;m" );
+    end
+
+    if (file_in_path(".",snr_name) && plot_vsnr)
+      snr_label = sprintf(";Voicing SNR %4.2f dB;",snr(f));
+      plot(1,1,snr_label);
+    endif
+
+    % phase model - determine SNR and error spectrum for phase model 1
+
+    if (file_in_path(".",phase_name_))
+      orig  = Am.*exp(j*phase(f,1:L));
+      synth = Am.*exp(j*phase_(f,1:L));
+      signal = orig * orig';
+      noise = (orig-synth) * (orig-synth)';
+      snr_phase = 10*log10(signal/noise);
+
+      %phase_err_label = sprintf(";phase_err SNR %4.2f dB;",snr_phase);
+      %plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label);
+    endif
+
+    if (file_in_path(".",lsp_name) && plot_lsp)
+      for l=1:10
+        plot([lsp(f,l)*4000/pi lsp(f,l)*4000/pi], [60 80], 'r');
+      endfor
+    endif
+
+    hold off;
+
+    %if (file_in_path(".",phase_name))
+      %figure(3);
+      %plot((1:L)*Wo*4000/pi, phase(f,1:L), ";phase;");
+      %axis;
+      %if (file_in_path(".",phase_name_))
+        %hold on;
+        %plot((1:L)*Wo*4000/pi, phase_(f,1:L), ";phase_;");
+       %hold off;
+      %endif
+      %figure(2);
+    %endif
+
+    % interactive menu
+
+    printf("\rframe: %d  menu: n-next  b-back  p-png  q-quit e-toggle Ew", f);
+    fflush(stdout);
+    k = kbhit();
+    if (k == 'n')
+      f = f + 1;
+    endif
+    if (k == 'b')
+      f = f - 1;
+    endif
+    if (k == 'e')
+       if (Ew_on == 1)
+           Ew_on = 0;
+        else
+           Ew_on = 1;
+        endif
+    endif
+
+    % optional print to PNG
+
+    if (k == 'p')
+      figure(1);
+      pngname = sprintf("%s_%d_sn.png",samname,f);
+      print(pngname, '-dpng', "-S500,500")
+      pngname = sprintf("%s_%d_sn_large.png",samname,f);
+      print(pngname, '-dpng', "-S800,600")
+
+      figure(2);
+      pngname = sprintf("%s_%d_sw.png",samname,f);
+      print(pngname, '-dpng', "-S500,500")
+      pngname = sprintf("%s_%d_sw_large.png",samname,f);
+      print(pngname, '-dpng', "-S1200,800")
+    endif
+
+  until (k == 'q')
+  printf("\n");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/plinterp.m b/codec2/branches/0.7/octave/plinterp.m
new file mode 100644 (file)
index 0000000..794a085
--- /dev/null
@@ -0,0 +1,11 @@
+load ../unittest/tinterp_prev.txt;
+load ../unittest/tinterp_interp.txt;
+load ../unittest/tinterp_next.txt;
+
+clf;
+plot(tinterp_prev(:,1), 20.0*log10(tinterp_prev(:,2)),";prev;")
+hold on;
+plot(tinterp_interp(:,1), 20.0*log10(tinterp_interp(:,2)),'g+-;interp;')
+plot(tinterp_next(:,1), 20.0*log10(tinterp_next(:,2)),'ro-;next;')
+hold off;
+axis([0 pi 0 80])
diff --git a/codec2/branches/0.7/octave/pllpcpf.m b/codec2/branches/0.7/octave/pllpcpf.m
new file mode 100644 (file)
index 0000000..924e045
--- /dev/null
@@ -0,0 +1,150 @@
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plot amplitude modelling information from dump files to test and develop
+% LPC post filter.
+
+function pllpcpf(samname, f)
+  
+  % switch some stuff off to unclutter display
+
+  plot_Am = 0;
+  plot_Amq = 0;
+  plot_err = 0;
+  plot_lsp = 0;
+  plot_snr = 0;
+  plot_vsnr = 0;
+  plot_sw = 0;
+  plot_pw = 1;
+  plot_pwb = 1;
+  plot_rw = 1;
+
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+
+  sw__name = strcat(samname,"_sw_.txt");
+  if (file_in_path(".",sw__name))
+    Sw_ = load(sw__name);
+  endif
+
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+
+  modelq_name = strcat(samname,"_qmodel.txt");
+  if (file_in_path(".",modelq_name))
+    modelq = load(modelq_name);
+  endif
+
+  % Pw (LPC synth filter spectrum) before post filter
+
+  pwb_name = strcat(samname,"_pwb.txt");
+  if (file_in_path(".",pwb_name))
+    Pwb = load(pwb_name);
+  endif
+
+  % Rw (Post filter spectrum)
+
+  rw_name = strcat(samname,"_rw.txt");
+  if (file_in_path(".",rw_name))
+    Rw = load(rw_name);
+  endif
+
+  % Pw (LPC synth filter spectrum) after post filter
+
+  pw_name = strcat(samname,"_pw.txt");
+  if (file_in_path(".",pw_name))
+    Pw = load(pw_name);
+  endif
+
+
+  Ew_on = 1;
+  k = ' ';
+  do 
+    figure(1);
+    clf;
+    s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+    size(s);
+    plot(s);
+    axis([1 length(s) -20000 20000]);
+
+    figure(2);
+    clf;
+    Wo = model(f,1);
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    if plot_Am
+      plot((1:L)*Wo*4000/pi, 20*log10(Am),";Am;r");
+    end
+    axis([1 4000 -10 80]);
+    hold on;
+    if plot_sw
+      plot((0:255)*4000/256, Sw(f,:),";Sw;");
+    end
+    if (file_in_path(".",modelq_name))
+
+      Amq = modelq(f,3:(L+2));
+      if plot_Amq
+        plot((1:L)*Wo*4000/pi, 20*log10(Amq),";Amq;g" );
+      end
+
+      if (file_in_path(".",pwb_name) && plot_pwb)
+        plot((0:255)*4000/256, 10*log10(Pwb(f,:)),";Pwb;r");
+      endif    
+
+      if (file_in_path(".",rw_name) && plot_rw)
+        plot((0:255)*4000/256, 10*log10(Rw(f,:)),";Rw;b");
+      endif    
+
+      if (file_in_path(".",pw_name) && plot_pw)
+        plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;g.");
+      endif    
+
+      signal = Am * Am';
+      noise = (Am-Amq) * (Am-Amq)'; 
+      snr1 = 10*log10(signal/noise);
+      Am_err_label = sprintf(";Am error SNR %4.2f dB;m",snr1);
+      if plot_err
+        plot((1:L)*Wo*4000/pi, 20*log10(Amq) - 20*log10(Am), Am_err_label);
+      end
+    endif
+
+
+    hold off;
+
+    % interactive menu
+
+    printf("\rframe: %d  menu: n-next  b-back  p-png  q-quit", f);
+    fflush(stdout);
+    k = kbhit();
+    if (k == 'n')
+      f = f + 1;
+    endif
+    if (k == 'b')
+      f = f - 1;
+    endif
+
+    % optional print to PNG
+
+    if (k == 'p')
+      figure(1);
+      pngname = sprintf("%s_%d_sn.png",samname,f);
+      print(pngname, '-dpng', "-S500,500")
+      pngname = sprintf("%s_%d_sn_large.png",samname,f);
+      print(pngname, '-dpng', "-S800,600")
+
+      figure(2);
+      pngname = sprintf("%s_%d_sw.png",samname,f);
+      print(pngname, '-dpng', "-S500,500")
+      pngname = sprintf("%s_%d_sw_large.png",samname,f);
+      print(pngname, '-dpng', "-S1200,800")
+    endif
+
+  until (k == 'q')
+  printf("\n");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/pllsp.m b/codec2/branches/0.7/octave/pllsp.m
new file mode 100644 (file)
index 0000000..0606d3c
--- /dev/null
@@ -0,0 +1,46 @@
+% Copyright David Rowe 2010
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plots a bunch of information related to LSP quantisation:
+%   - speech file 
+%   - LSPs before and after quantisation
+%   - SNR for each frame
+%
+% Note: there is a 160 sample (two frame delay) from the when a sample
+% enters the input buffer until it is at the centre of the analysis window
+
+function pllsp(rawfile, 
+              dumpfile_prefix_lpc_only, 
+               dumpfile_prefix_lsp, 
+               start_f, end_f)
+  
+  fs=fopen(rawfile,"rb");
+  s=fread(fs,Inf,"short");
+
+  lpc_snr_name = strcat(dumpfile_prefix_lpc_only,"_lpc_snr.txt");
+  lpc10_snr = load(lpc_snr_name);
+  lpc_snr_name = strcat(dumpfile_prefix_lsp,"_lpc_snr.txt");
+  lsp_snr = load(lpc_snr_name);
+
+  lsp_name = strcat(dumpfile_prefix_lsp,"_lsp.txt");
+  lsps = load(lsp_name);
+  [m,n]=size(lsps);
+  lsp  = lsps(1:2:m,:);
+  lsp_ = lsps(2:2:m,:);
+
+  figure(1);
+  clf;
+  subplot(211);
+  sp = s((start_f-2)*80:(end_f-2)*80);
+  plot(sp);
+
+  subplot(212);
+  plot(lpc10_snr((start_f+1):end_f)-lsp_snr((start_f+1):end_f));
+
+  figure(2);
+  plot((4000/pi)*lsp((start_f+1):end_f,:));
+  hold on;
+  plot((4000/pi)*lsp_((start_f+1):end_f,:),'+-');
+  hold off;
+endfunction
diff --git a/codec2/branches/0.7/octave/pllspdt.m b/codec2/branches/0.7/octave/pllspdt.m
new file mode 100644 (file)
index 0000000..c711aa4
--- /dev/null
@@ -0,0 +1,27 @@
+% pllspdt.m
+% Copyright David Rowe 2010
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Test script to plot differences in LSps between frames
+
+function pllspdt(rawfile,dumpfile_prefix_lsp,lspn, start_f, end_f)
+  
+  fs=fopen(rawfile,"rb");
+  s=fread(fs,Inf,"short");
+
+  lsp_name = strcat(dumpfile_prefix_lsp,"_lsp.txt");
+  lsps = load(lsp_name);
+  [m,n]=size(lsps);
+  lsp  = lsps(1:2:m,:);
+  lsp_ = lsps(2:2:m,:);
+  lspdt = lsp(2:m/2,:) - lsp(1:m/2-1,:);
+
+  figure(1);
+  clf;
+  sp = s((start_f-2)*80:(end_f-2)*80);
+  plot(sp);
+
+  figure(2);
+  plot((4000/pi)*lspdt((start_f+1):end_f,lspn));
+endfunction
diff --git a/codec2/branches/0.7/octave/plnlp.m b/codec2/branches/0.7/octave/plnlp.m
new file mode 100644 (file)
index 0000000..01b4931
--- /dev/null
@@ -0,0 +1,134 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plot NLP states from dump files.
+
+function plnlp(samname, f)
+  
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+
+  fw_name = strcat(samname,"_fw.txt");
+  if (file_in_path(".",fw_name))
+    fw = load(fw_name);
+  endif
+
+  e_name = strcat(samname,"_e.txt");
+  if (file_in_path(".",e_name))
+    e = load(e_name);
+  endif
+
+  p_name = strcat(samname,".p");
+  if (file_in_path(".",p_name))
+    p = load(p_name);
+  endif
+
+  sq_name = strcat(samname,"_sq.txt");
+  if (file_in_path(".",sq_name))
+    sq = load(sq_name);
+  endif
+
+  dec_name = strcat(samname,"_dec.txt");
+  if (file_in_path(".",dec_name))
+    dec = load(dec_name);
+  endif
+
+  do 
+    figure(1);
+    clf;
+    s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+    plot(s, ";Sn;");
+    grid
+    axis([1 length(s) -20000 20000]);
+
+    figure(2);
+    plot((0:255)*4000/256, Sw(f,:),";Sw;");
+    grid
+    axis([1 4000 -10 80]);
+    hold on;
+
+    f0 = 8000/p(f);
+    Wo = 2*pi/p(f);
+    L = floor(pi/Wo);
+    f0_label = sprintf("b;P=%3.1f F0=%3.0f;",p(f),f0);
+    for m=1:L-1
+      plot([ m*Wo*4000/pi m*Wo*4000/pi], [10 60], 'b');
+    endfor
+    plot([ L*Wo*4000/pi L*Wo*4000/pi], [10 60], f0_label);
+
+    hold off;
+
+    if (file_in_path(".",fw_name))
+      figure(3);
+      if (file_in_path(".",e_name))
+         subplot(211);
+      endif
+      plot((0:255)*800/256, fw(f,:)/max(fw(f,:)), ";Fw;");
+      axis([1 400 0 1]);
+      if (file_in_path(".",e_name))
+        subplot(212);
+        e_concat = [ e(2*f-1,:) e(2*f,:) ];
+        plot(e_concat(1:400)/max(e_concat(1:400)), "+;MBE E(f);");
+        axis([1 400 0 1]);
+      endif
+    endif
+
+    if (file_in_path(".",sq_name))
+      figure(4);
+      sq_concat = [ sq(2*f-1,:) sq(2*f,:) ];
+      axis
+      plot(sq_concat, ";sq;");
+    endif
+
+    if (file_in_path(".",dec_name))
+      figure(5);
+      plot(dec(f,:), ";dec;");
+    endif
+    
+    figure(2);
+
+    % interactive menu
+
+    printf("\rframe: %d  menu: n-next  b-back  p-png  q-quit ", f);
+    fflush(stdout);
+    k = kbhit();
+    if (k == 'n')
+      f = f + 1;
+    endif
+    if (k == 'b')
+      f = f - 1;
+    endif
+
+    % optional print to PNG
+
+    if (k == 'p')
+    
+      pngname = sprintf("%s_%d",samname,f);
+
+      % small image
+
+      __gnuplot_set__ terminal png size 420,300
+      ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
+      eval(ss)
+      replot;
+
+      % larger image
+
+      __gnuplot_set__ terminal png size 800,600
+      ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
+      eval(ss)
+      replot;
+
+      % for some reason I need this to stop large plot getting wiped
+      __gnuplot_set__ output "/dev/null"
+
+    endif
+
+  until (k == 'q')
+  printf("\n");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/plot_specgram.m b/codec2/branches/0.7/octave/plot_specgram.m
new file mode 100644 (file)
index 0000000..480253e
--- /dev/null
@@ -0,0 +1,30 @@
+% plot_specgram.m
+% David Rowe May 2017
+%
+% As the name suggests.....
+
+
+function S = plot_specgram(x)
+
+  % set step size so we end up with an aray of pixels that is square.  Otherwise
+  % imagesc will only use a ribbon on the figure.
+
+  Fs = 8000;
+  l = length(x);
+
+  Nfft = 512; Nfft2 = Nfft/2; window = 512; nstep = window/2;
+  nsamples = floor(l/nstep) - 1;
+  S = zeros(nsamples,Nfft);
+  h = hanning(Nfft);
+  for i=1:nsamples
+    st = (i-1)*nstep+1; en = st+window-1;
+    %printf("i: %d st: %d en: %d l: %d\n", i, st, en, l);
+    S(i,:) = 20*log10(abs(fft(x(st:en).*h')));
+  end
+  mx = ceil(max(max(S))/10)*10;
+  S = max(S,mx-30);
+  mesh((1:Nfft2)*4000/Nfft2, (1:nsamples)*nstep, S(:,1:Nfft2));
+  view(90,-90);
+  %xlabel('Frequency (Hz)');
+  %ylabel('Sample');
+en
diff --git a/codec2/branches/0.7/octave/plphase.m b/codec2/branches/0.7/octave/plphase.m
new file mode 100644 (file)
index 0000000..c12422e
--- /dev/null
@@ -0,0 +1,198 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plot phase modelling information from dump files.
+
+function plphase(samname, f)
+  
+  sn_name = strcat(samname,"_sn.txt");
+  Sn = load(sn_name);
+
+  sw_name = strcat(samname,"_sw.txt");
+  Sw = load(sw_name);
+
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+
+  sw__name = strcat(samname,"_sw_.txt");
+  if (file_in_path(".",sw__name))
+    Sw_ = load(sw__name);
+  endif
+
+  pw_name = strcat(samname,"_pw.txt");
+  if (file_in_path(".",pw_name))
+    Pw = load(pw_name);
+  endif
+
+  ak_name = strcat(samname,"_ak.txt");
+  if (file_in_path(".",ak_name))
+    ak = load(ak_name);
+  endif
+
+  phase_name = strcat(samname,"_phase.txt");
+  if (file_in_path(".",phase_name))
+    phase = load(phase_name);
+  endif
+
+  phase_name_ = strcat(samname,"_phase_.txt");
+  if (file_in_path(".",phase_name_))
+    phase_ = load(phase_name_);
+  endif
+
+  snr_name = strcat(samname,"_snr.txt");
+  if (file_in_path(".",snr_name))
+    snr = load(snr_name);
+  endif
+
+  sn_name_ = strcat(samname,".raw");
+  if (file_in_path(".",sn_name_))
+    fs_ = fopen(sn_name_,"rb");
+    sn_  = fread(fs_,Inf,"short");
+  endif
+
+  k = ' ';
+  do 
+    figure(1);
+    clf;
+    s = [ Sn(2*f-1,:) Sn(2*f,:) ];
+    plot(s);
+    grid;
+    axis([1 length(s) -20000 20000]);
+    if (k == 'p')
+       pngname = sprintf("%s_%d_sn",samname,f);
+       png(pngname);
+    endif
+
+    figure(2);
+    Wo = model(f,1);
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    plot((1:L)*Wo*4000/pi, 20*log10(Am),"r;Am;");
+    axis([1 4000 -10 80]);
+    hold on;
+    plot((0:255)*4000/256, Sw(f,:),";Sw;");
+    grid;
+
+    if (file_in_path(".",sw__name))
+      plot((0:255)*4000/256, Sw_(f,:),"g;Sw_;");
+    endif      
+
+    if (file_in_path(".",pw_name))
+       plot((0:255)*4000/256, 10*log10(Pw(f,:)),";Pw;");
+    endif      
+
+    if (file_in_path(".",snr_name))
+      snr_label = sprintf(";phase SNR %4.2f dB;",snr(f));
+      plot(1,1,snr_label);
+    endif
+
+    % phase model - determine SNR and error spectrum for phase model 1
+
+    if (file_in_path(".",phase_name_))
+      orig  = Am.*exp(j*phase(f,1:L));
+      synth = Am.*exp(j*phase_(f,1:L));
+      signal = orig * orig';
+      noise = (orig-synth) * (orig-synth)';
+      snr_phase = 10*log10(signal/noise);
+
+      phase_err_label = sprintf("g;phase_err SNR %4.2f dB;",snr_phase);
+      plot((1:L)*Wo*4000/pi, 20*log10(orig-synth), phase_err_label);
+    endif
+
+    hold off;
+    if (k == 'p')
+       pngname = sprintf("%s_%d_sw",samname,f);
+       png(pngname);
+    endif
+
+    if (file_in_path(".",phase_name))
+      figure(3);
+      plot((1:L)*Wo*4000/pi, phase(f,1:L)*180/pi, "-o;phase;");
+      axis;
+      if (file_in_path(".", phase_name_))
+        hold on;
+        plot((1:L)*Wo*4000/pi, phase_(f,1:L)*180/pi, "g;phase after;");
+       grid
+       hold off;
+      endif
+      if (k == 'p')
+        pngname = sprintf("%s_%d_phase",samname,f);
+        png(pngname);
+      endif
+    endif
+
+    % synthesised speech 
+
+    if (file_in_path(".",sn_name_))
+      figure(4);
+      s_ = sn_((f-3)*80+1:(f+1)*80);
+      plot(s_);
+      axis([1 length(s_) -20000 20000]);
+      if (k == 'p')
+        pngname = sprintf("%s_%d_sn_",samname,f)
+        png(pngname);
+      endif
+    endif
+
+    if (file_in_path(".",ak_name))
+      figure(5);
+      axis;
+      akw = ak(f,:);
+      weight = 1.0 .^ (0:length(akw)-1);
+      akw = akw .* weight;
+      H = 1./fft(akw,8000);
+      subplot(211);
+      plot(20*log10(abs(H(1:4000))),";LPC mag spec;");
+      grid;    
+      subplot(212);
+      plot(angle(H(1:4000))*180/pi,";LPC phase spec;");
+      grid;
+      if (k == 'p')
+        % stops multimode errors from gnuplot, I know not why...
+        figure(2);
+        figure(5);
+
+        pngname = sprintf("%s_%d_lpc",samname,f);
+        png(pngname);
+      endif
+    endif
+
+
+    % autocorrelation function to research voicing est
+    
+    %M = length(s);
+    %sw = s .* hanning(M)';
+    %for k=0:159
+    %  R(k+1) = sw(1:320-k) * sw(1+k:320)';
+    %endfor
+    %figure(4);
+    %R_label = sprintf(";R(k) %3.2f;",max(R(20:159))/R(1));
+    %plot(R/R(1),R_label);
+    %grid
+
+    figure(2);
+
+    % interactive menu
+
+    printf("\rframe: %d  menu: n-next  b-back  p-png  q-quit ", f);
+    fflush(stdout);
+    k = kbhit();
+    if (k == 'n')
+      f = f + 1;
+    endif
+    if (k == 'b')
+      f = f - 1;
+    endif
+
+    % optional print to PNG
+
+    if (k == 'p')
+       pngname = sprintf("%s_%d",samname,f);
+       png(pngname);
+    endif
+
+  until (k == 'q')
+  printf("\n");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/plpitch.m b/codec2/branches/0.7/octave/plpitch.m
new file mode 100644 (file)
index 0000000..69ad533
--- /dev/null
@@ -0,0 +1,36 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% plpitch.m
+% Plots two pitch tracks on top of each other, used for comparing pitch
+% estimators
+
+function plpitch(pitch1_name, pitch2_name, start_fr, end_fr)
+  
+  pitch1 = load(pitch1_name);
+  pitch2 = load(pitch2_name);
+
+  st = 1;
+  en = length(pitch1);
+  if (nargin >= 3)
+    st = start_fr;
+  endif
+  if (nargin >= 4)
+    en = end_fr;
+  endif
+
+  figure(1);
+  clf;
+  l1 = strcat("r;",pitch1_name,";")
+  l1 
+  st
+  en
+  plot(pitch1(st:en), l1);
+  axis([1 en-st 20 160]);
+  l2 = strcat("g;",pitch2_name,";");
+  hold on;
+  plot(pitch2(st:en),l2);
+  hold off;
+endfunction
+
diff --git a/codec2/branches/0.7/octave/plppe.m b/codec2/branches/0.7/octave/plppe.m
new file mode 100644 (file)
index 0000000..cbc5b56
--- /dev/null
@@ -0,0 +1,65 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plot two sparse phase prediction error text files.
+% Generate data from print_pred_error, print_pred_error_sparse_wo_correction1 etc
+
+function plppe(ppe1_file, ppe2_file, f)
+  
+  ppe1 = load(ppe1_file);
+  ppe2 = load(ppe2_file);
+
+  std1 = std(nonzeros(ppe1(:,40:80)));
+  std2 = std(nonzeros(ppe2(:,40:80)));
+
+  printf("std dev for %s is %4.3f\n", ppe1_file, std1);
+  printf("std dev for %s is %4.3f\n", ppe2_file, std2);
+  figure(1);
+  clf;
+  subplot(211)
+  hist(nonzeros(ppe1(:,40:80)),20);
+  subplot(212)
+  hist(nonzeros(ppe2(:,40:80)),20);
+  
+  k = ' ';
+  do 
+    figure(2);
+    clf;
+    subplot(211)
+    L = length(nonzeros(ppe1(f,:)));
+    x = (1:L)*4000/L;
+    std1 = std(nonzeros(ppe1(f,:)));
+    legend = sprintf(";std dev %4.3f;", std1);
+    plot(x, nonzeros(ppe1(f,:)),legend);
+    axis([0 4000 -pi pi]);
+    subplot(212)
+    std2 = std(nonzeros(ppe2(f,:)));
+    legend = sprintf(";std dev %4.3f;", std2);
+    plot(x, nonzeros(ppe2(f,:)),legend);
+    axis([0 4000 -pi pi]);
+
+    % interactive menu
+
+    printf("\rframe: %d  menu: n-next  b-back  p-png  q-quit ", f);
+    fflush(stdout);
+    k = kbhit();
+    if (k == 'n')
+      f = f + 1;
+    endif
+    if (k == 'b')
+      f = f - 1;
+    endif
+
+    % optional print to PNG
+
+    if (k == 'p')
+       pngname = sprintf("%s_%d",samname,f);
+       png(pngname);
+    endif
+
+  until (k == 'q')
+  printf("\n");
+
+endfunction
diff --git a/codec2/branches/0.7/octave/plsub.m b/codec2/branches/0.7/octave/plsub.m
new file mode 100644 (file)
index 0000000..6e2bc1e
--- /dev/null
@@ -0,0 +1,35 @@
+% Copyright David Rowe 2010
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+% plots the difference of two files
+
+function plsub(samname1, samname2, start_sam, end_sam, pngname)
+  
+  fs1=fopen(samname1,"rb");
+  s1=fread(fs1,Inf,"short");
+  fs2=fopen(samname2,"rb");
+  s2=fread(fs2,Inf,"short");
+
+  st = 1;
+  en = length(s1);
+  if (nargin >= 3)
+    st = start_sam;
+  endif
+  if (nargin >= 4)
+    en = end_sam;
+  endif
+
+  figure(1);
+  clf;
+  l1 = strcat("r;",samname1,";");
+  plot(s1(st:en) - s2(st:en), l1);
+  %axis([1 en-st min(s1(st:en)) max(s1(st:en))]);
+  if (nargin == 5)
+    pngname = sprintf("%s.png",pngname);
+    print(pngname, '-dpng', "-S500,500")
+    pngname = sprintf("%s_large.png",pngname);
+    print(pngname, '-dpng', "-S800,600")
+  endif
+
+endfunction
diff --git a/codec2/branches/0.7/octave/plvoicing.m b/codec2/branches/0.7/octave/plvoicing.m
new file mode 100644 (file)
index 0000000..a531747
--- /dev/null
@@ -0,0 +1,89 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plot voicing information from sample and dump files.
+%
+% samfilename is the raw source file, e.g. "../raw/hts1a.raw"
+% samname is the dumpfile prefix, e.g. "../src/hts1a"
+%
+% There is a 160 sample (two frame delay) from the when a sample
+% enters the input buffer until it is at the centre of the analysis window
+
+function plvoicing(samfilename, samname, start_f, end_f, pngname)
+  
+  fs=fopen(samfilename,"rb");
+  s=fread(fs,Inf,"short");
+
+  snr_name = strcat(samname,"_snr.txt");
+  snr = load(snr_name);
+  model_name = strcat(samname,"_model.txt");
+  model = load(model_name);
+
+  Wo  = model((start_f+1):end_f,1);
+  F0  = Wo*4000/pi;
+  dF0 = F0(1:length(Wo)-1) - F0(2:length(Wo));
+
+  % work out LP and HP energy
+
+  for f=(start_f+1):end_f
+    L = model(f,2);
+    Am = model(f,3:(L+2));
+    L2 = floor(L/2);
+    elow = Am(1:L2) * Am(1:L2)';
+    ehigh = Am(L2:L) * Am(L2:L)';
+    erat(f-(start_f+1)+1) = 10*log10(elow/ehigh);
+  endfor
+
+  figure(1);
+  clf;
+  sp = s((start_f-2)*80:(end_f-2)*80);
+  plot(sp);
+  hold on;
+  vhigh = snr((start_f+1):end_f) > 7;
+  vlow = snr((start_f+1):end_f) > 4;
+
+  % test correction based on erat
+
+  vlowadj = vlow;
+
+  for f=1:length(erat)-1
+    if (vlow(f) == 0)
+      if (erat(f) > 10)
+        vlowadj(f) = 1;
+      endif
+    endif
+    if (vlow(f) == 1)
+      if (erat(f) < -10)
+        vlowadj(f) = 0;
+      endif
+      if (abs(dF0(f)) > 15)
+        vlowadj(f) = 0;
+      endif
+    endif
+  endfor
+
+  x = 1:(end_f-start_f);
+  plot(x*80,snr((start_f+1):end_f)*1000,';SNRdB x 1000;g+');
+  plot(x*80,-8000 + vhigh*2000,';7dB thresh;g');
+  plot(x*80,-11000 + vlowadj*2000,';vlow with corr;g');
+  plot(x*80,erat*1000,';elow/ehigh in dB;r');
+  plot(x*80,-14000 + vlow*2000,';4dB thresh;r');
+  hold off; 
+  grid
+  if (nargin == 5)
+      print(pngname, "-dpng", "-S500,500")
+  endif
+    
+  figure(2)
+  Wo  = model((start_f+1):end_f,1);
+  F0  = Wo*4000/pi;
+  dF0 = F0(1:length(Wo)-1) - F0(2:length(Wo));
+  %plot(dF0,'+--')
+  %hold on;
+  %plot([ 1 length(dF0) ], [10 10] ,'r')
+  %plot([ 1 length(dF0) ], [-10 -10] ,'r')
+  %axis([1 length(dF0) -50 50])
+  %hold off;
+  plot(F0,'+--')
+endfunction
diff --git a/codec2/branches/0.7/octave/png.m b/codec2/branches/0.7/octave/png.m
new file mode 100644 (file)
index 0000000..09a7996
--- /dev/null
@@ -0,0 +1,25 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Replot current plot as a png, generates small and large versions
+
+function png(pngname)
+     % small image
+
+     __gnuplot_set__ terminal png size 420,300
+     ss = sprintf("__gnuplot_set__ output \"%s.png\"", pngname);
+     eval(ss)
+     replot;
+
+     % larger image
+
+     __gnuplot_set__ terminal png size 800,600
+     ss = sprintf("__gnuplot_set__ output \"%s_large.png\"", pngname);
+     eval(ss)
+     replot;
+
+     % for some reason I need this to stop large plot getting wiped
+     __gnuplot_set__ output "/dev/null"
+
+endfunction
diff --git a/codec2/branches/0.7/octave/postfilter.m b/codec2/branches/0.7/octave/postfilter.m
new file mode 100644 (file)
index 0000000..84f7dfc
--- /dev/null
@@ -0,0 +1,24 @@
+% Copyright David Rowe 2009
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+% Plot postfilter doing its thing
+
+function postfilter(samname)    
+    p = load(samname);
+    figure(1);
+    plot(p(:,1),";energy;");
+    hold on;
+    plot(p(:,2),";bg_est;");
+    hold off;
+    grid;
+    pngname=sprintf("%s_postfilter_1", samname);
+    png(pngname);
+
+    figure(2);
+    plot(p(:,3),";% unvoiced;");
+    grid;    
+    pngname=sprintf("%s_postfilter_2", samname);
+    png(pngname);
+endfunction
+  
diff --git a/codec2/branches/0.7/octave/pulse.m b/codec2/branches/0.7/octave/pulse.m
new file mode 100644 (file)
index 0000000..223389e
--- /dev/null
@@ -0,0 +1,37 @@
+% pulse.m
+% David Rowe August 2009
+%
+% Experiments with human pulse perception for sinusoidal codecs
+
+function pulse(samname)
+
+  A = 1000;
+  K = 16000;
+  N = 80;
+  frames = K/N;
+  s = zeros(1,K);
+
+  for f=1:frames
+    % lets try placing np random pulses in every frame
+
+    P = 20 + (160-20)*rand(1,1);
+    Wo = 2*pi/P;
+    L = floor(pi/Wo);
+    sf = zeros(1,N);
+    for m=1:L/2:L
+      pos = floor(rand(1,1)*N)+1;
+      %pos = 50;
+      for l=m:m+L/2-1
+        sf = sf + A*cos(l*Wo*((f-1)*N+1:f*N) - pos*l*Wo);
+      endfor
+    endfor
+    s((f-1)*N+1:f*N) = sf;
+  endfor
+
+  plot(s(1:250));
+
+  fs=fopen(samname,"wb");
+  fwrite(fs,s,"short");
+  fclose(fs);
+endfunction
+
diff --git a/codec2/branches/0.7/octave/qpsk.m b/codec2/branches/0.7/octave/qpsk.m
new file mode 100644 (file)
index 0000000..b502e16
--- /dev/null
@@ -0,0 +1,140 @@
+% qpsk.m
+%
+% David Rowe Sep 2015
+%
+% Octave functions to implement a QPSK modem
+
+1;
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+
+% Inserts pilot symbols a frame of symbols.  The pilot symbols are
+% spread evenly throughout the input frame.
+
+function frameout = insert_pilots(framein, pilots, Npilotstep)
+
+    lpilots = length(pilots);
+    lframein = length(framein);
+    frameout = zeros(1, lframein + lpilots);
+
+    pin = 1; pout = 1; ppilots = 1;
+    while (lpilots)
+        %printf("pin %d pout %d ppilots %d lpilots %d\n", pin, pout, ppilots, lpilots);
+        frameout(pout:pout+Npilotstep-1) = framein(pin:pin+Npilotstep-1);
+        pin  += Npilotstep; 
+        pout += Npilotstep;
+        frameout(pout:pout) = pilots(ppilots);
+        ppilots++;
+        pout++;
+        lpilots--;
+    end
+endfunction
+
+
+% Removes the pilots symbols from a frame of symbols.
+
+function frameout = remove_pilots(framein, pilots, Npilotstep)
+
+    frameout = [];
+    lpilots = length(pilots);
+
+    pin = 1; pout = 1;
+    while (lpilots)
+        %printf("pin %d pout %d lpilots %d  ", pin, pout, lpilots);
+        %printf("pin+spacing-1 %d lvd %d lframein: %d\n", pin+spacing-1, lvd, length(framein));
+        frameout(pout:pout+Npilotstep-1) = framein(pin:pin+Npilotstep-1);
+        pin  += Npilotstep+1;
+        pout += Npilotstep;
+        lpilots--;
+    end
+
+endfunction
+
+
+% Estimate and correct phase offset using a window of Np pilots around
+% current symbol
+
+function symbpilot_rx = correct_phase_offset(aqpsk, symbpilot_rx)
+  rx_pilot_buf = aqpsk.rx_pilot_buf;
+  Npilotstep   = aqpsk.Npilotstep;
+  Nsymb        = aqpsk.Nsymb;
+
+  for ns=1:Npilotstep+1:Nsymb
+
+    % update buffer of recent pilots, note we need past ones
+
+    rx_pilot_buf(1) = rx_pilot_buf(2);
+    next_pilot_index = ceil(ns/(Npilotstep+1))*(Npilotstep+1);
+    rx_pilot_buf(2) = symbpilot_rx(next_pilot_index);
+
+    % average pilot symbols to get estimate of phase
+
+    phase_est = angle(sum(rx_pilot_buf));
+
+    %printf("next_pilot_index: %d phase_est: %f\n", next_pilot_index, phase_est);
+
+    % now correct the phase of each symbol
+
+    for s=ns:ns+Npilotstep
+      symbpilot_rx(s) *= exp(-j*phase_est);     
+    end
+  end
+
+  aqpsk.rx_pilot_buf = rx_pilot_buf;
+endfunction
+
+
+% builds up a sparse QPSK modulated version version of the UW for use
+% in UW sync at the rx
+
+function mod_uw = build_mod_uw(uw, spacing)
+    luw = length(uw);
+
+    mod_uw = [];
+
+    pout = 1; puw = 1;
+    while (luw)
+        %printf("pin %d pout %d puw %d luw %d\n", pin, pout, puw, luw);
+        pout += spacing/2;
+        mod_uw(pout) = qpsk_mod(uw(puw:puw+1));
+        puw += 2;
+        pout += 1;
+        luw -= 2;
+    end
+endfunction
+
+
+% Uses the UW to determine when we have a full codeword ready for decoding
+
+function [found_uw corr] = look_for_uw(mem_rx_symbols, mod_uw)
+    sparse_mem_rx_symbols = mem_rx_symbols(find(mod_uw));
+
+    % correlate with ref UW
+
+    num = (mem_rx_symbols * mod_uw') .^ 2;
+    den = (sparse_mem_rx_symbols * sparse_mem_rx_symbols') * (mod_uw * mod_uw');
+    
+    corr = abs(num/(den+1E-6));
+    found_uw = corr > 0.8;
+endfunction
+
diff --git a/codec2/branches/0.7/octave/rfdesign.m b/codec2/branches/0.7/octave/rfdesign.m
new file mode 100644 (file)
index 0000000..bc75b6e
--- /dev/null
@@ -0,0 +1,77 @@
+% rfdesign.m
+%
+% David Rowe Nov 2015
+%
+% Helper functions for RF Design
+
+1;
+
+
+% convert a parallel R/X to a series R/X
+
+function Zs = zp_to_zs(Zp)
+  Xp = j*imag(Zp); Rp = real(Zp);
+  Zs = Xp*Rp/(Xp+Rp);
+endfunction
+
+
+% convert a series R/X to a parallel R/X
+
+function Zp = zs_to_zp(Zs)
+  Xs = imag(Zs); Rs = real(Zs);
+  Q = Xs/Rs;       
+  Rp = (Q*Q+1)*Rs;
+  Xp = Rp/Q;
+  Zp = Rp + j*Xp;
+endfunction
+
+
+% Design a Z match network with a parallel and series reactance
+% to match between a low and high resistance.  Note Xp and Xs
+% must be implemented as opposite sign, ie one a inductor, one
+% a capacitor (your choice).
+%
+%  /--Xs--+---\
+%  |      |   |
+% Rlow   Xp  Rhigh
+%  |      |   |
+%  \------+---/
+%        
+
+function [Xs Xp] = z_match(Rlow, Rhigh)
+  assert(Rlow < Rhigh, "Rlow must be < Rhigh");
+  Q = sqrt(Rhigh/Rlow -1);
+  Xs = Q*Rlow;
+  Xp = Rhigh/Q;
+endfunction
+
+
+% Design an air core inductor, Example 1-5 "RF Circuit Design"
+
+function Nturns = design_inductor(L_uH, diameter_mm)
+  Nturns = sqrt(29*L_uH/(0.394*(diameter_mm*0.1/2)));
+endfunction
+
+
+% Work out series resistance Rl of series resonant inductor.  Connect
+% tracking generator to spec-an input, the series LC to ground.  V is
+% the ref TG level (e.g. with perfect 50 ohm term) in volts, Vmin is the
+% minumum at series res freq.
+%
+%  /-50-+---+
+%  |    |   |
+%  TG   C   50 spec-an
+%  |    |   |
+%  |    L   |
+%  |    |   |
+%  |    Rl  |
+%  |    |   |
+%  \----+---/
+
+function Rl = find_rl(V,Vmin)
+  % at series resonance effect of C and L goes away and we are left with
+  % parallel combination of Ls and spec-an 50 ohm input impedance
+
+  Rp = Vmin*50/(2*V*(1-Vmin/(2*V)));
+  Rl = 1/(1/Rp - 1/50)
+endfunction
diff --git a/codec2/branches/0.7/octave/s_param_rf.m b/codec2/branches/0.7/octave/s_param_rf.m
new file mode 100644 (file)
index 0000000..8c5186a
--- /dev/null
@@ -0,0 +1,206 @@
+% s_param_rf.m
+%
+% David Rowe Nov 2015
+%
+% Working for small signal VHF amplifier design using
+% S-param techniques from "RF Circuit Design" by Chris Bowick
+
+rfdesign; % library of helped functions
+
+more off;
+
+Ic = 0.014;
+
+% BRF92 VCE=5V Ic=5mA 100MHz
+if Ic == 0.005
+  S11 = 0.727*exp(j*(-43)*pi/180);
+  S12 = 0.028*exp(j*(69.6)*pi/180);
+  S21 = 12.49*exp(j*(147)*pi/180);
+  S22 = 0.891*exp(j*(-16)*pi/180);
+end
+
+% BRF92 VCE=10V Ic=14mA 100MHz
+
+if Ic == 0.02
+  S11 = 0.548*exp(j*(-56.8)*pi/180);
+  S12 = 0.020*exp(j*(67.8)*pi/180);
+  S21 = 20.43*exp(j*(133.7)*pi/180);
+  S22 = 0.796*exp(j*(-18.5)*pi/180);
+end
+
+% Stability
+
+Ds = S11*S22-S12*S21;
+Knum = 1 + abs(Ds)^2 - abs(S11)^2 - abs(S22)^2;
+Kden = 2*abs(S21)*abs(S12);
+K = Knum/Kden                                    % If > 1 unconditionally stable
+                                                 % If < 1 panic
+figure(1);
+clf
+scCreate;
+
+if K < 1
+  C1 = S11 - Ds*conj(S22);
+  C2 = S22 - Ds*conj(S11);
+  rs1 = conj(C1)/(abs(S11)^2-abs(Ds)^2);           % centre of input stability circle
+  ps1 = abs(S12*S21/(abs(S11)^2-abs(Ds)^2));       % radius of input stability circle
+  rs2 = conj(C2)/(abs(S22)^2-abs(Ds)^2);           % centre of input stability circle
+  ps2 = abs(S12*S21/(abs(S22)^2-abs(Ds)^2));       % radius of input stability circle
+
+  s(1,1)=S11; s(1,2)=S12; s(2,1)=S21; s(2,2)=S22;
+  plotStabilityCircles(s)
+end
+
+% Gain circle
+
+D2 = abs(S22)^2-abs(Ds)^2;
+C2 = S22 - Ds*conj(S11);
+GdB = 20; Glin = 10^(GdB/10);                                         % lets shoot for 20dB gain
+G = Glin/(abs(S21)^2);
+r0 = G*conj(C2)/(1+D2*G);                                             % centre of gain circle
+p0 = sqrt(1 - 2*K*abs(S12*S21)*G + (abs(S12*S21)^2)*(G^2))/(1+D2*G);  % radius of gain circle
+
+scAddCircle(abs(r0),angle(r0)*180/pi,p0,'g')
+printf("Green is the %3.1f dB constant gain circle for gammaL\n",GdB);
+
+% Note different design procedures for different operating points
+
+if Ic == 0.005
+  % Choose a gammaL on the gain circle
+
+  gammaL = 0.8 - 0.4*j;
+
+  % Caclulate gammaS and make sure it's stable by visual inspection
+  % compared to stability circle.
+
+  gammaS = conj(S11 + ((S12*S21*gammaL)/(1 - (gammaL*S22))));
+end
+
+if Ic == 0.014
+
+  % lets set zo (normalised Zo) based on Pout and get gammaL from that
+
+  Pout = 0.01;
+  Irms = 0.002;
+  Zo = Pout/(Irms*Irms);
+  zo = Zo/50;
+  [magL,angleL] = ztog(zo);
+  gammaL = magL*exp(j*angleL*pi/180);
+
+  % calculate gammaS
+
+  gammaS = conj(S11 + ((S12*S21*gammaL)/(1 - (gammaL*S22))));
+
+end
+
+[zo Zo] = gtoz(abs(gammaL), angle(gammaL)*180/pi,50);
+[zi Zi] = gtoz(abs(gammaS), angle(gammaS)*180/pi,50);
+
+scAddPoint(zi);
+scAddPoint(zo);
+
+% Transducer gain
+
+Gt_num = (abs(S21)^2)*(1-abs(gammaS)^2)*(1-abs(gammaL)^2);
+Gt_den = abs((1-S11*gammaS)*(1-S22*gammaL) - S12*S21*gammaL*gammaS)^2;
+Gt = Gt_num/Gt_den;
+
+if Ic == 0.005
+
+  % Lets design the z match for the input ------------------------------
+
+  % put input impedance in parallel form
+
+  Zip = zs_to_zp(Zi);
+
+  % first match real part of impedance
+
+  Rs = 50; Rl = real(Zip);
+  [Xs Xp] = z_match(Rs,Rl);
+  
+  % Modify Xp so transistor input sees conjugate match to Zi
+  % Lets make Xp a capacitor, so negative sign
+
+  Xp_match = -Xp - imag(Zip);
+
+  % Now convert to real component values
+
+  w = 2*pi*150E6;
+  Ls = Xs/w; diameter_mm = 6.25; 
+  Ls_turns = design_inductor(Ls*1E6, diameter_mm);
+  Cp = 1/(w*(-Xp_match));
+
+  printf("Transducer gain: %3.1f dB\n", 10*log10(Gt));
+  printf("Input: Zi = %3.1f + %3.1fj ohms\n", real(Zi), imag(Zi));
+  printf("       In parallel form Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), imag(Zip));
+  printf("       So for a conjugate match transistor input wants to see:\n         Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), -imag(Zip));
+  printf("       Rs = %3.1f to Rl = %3.1f ohm matching network Xs = %3.1fj Xp = %3.1fj\n", Rs, Rl, Xs, Xp);
+  printf("       with conj match to Zi Xs = %3.1fj Xp = %3.1fj\n", Xs, Xp_match);
+  printf("       matching components Ls = %5.3f uH Cp = %4.1f pF\n", Ls*1E6, Cp*1E12);
+  printf("       Ls can be made from %3.1f turns on a %4.2f mm diameter air core\n", Ls_turns, diameter_mm);
+
+  % Now Z match for output -------------------------------------
+
+  Lo = -imag(Zo)/w;
+  Lo_turns = design_inductor(Lo*1E6, diameter_mm);
+  printf("Output: Zo = %3.1f + %3.1fj ohms\n", real(Zo), imag(Zo));
+  printf("        So for a conjugate match transistor output wants to see:\n          Rl = %3.1f Xl = %3.1fj ohms\n", real(Zo), -imag(Zo));
+  printf("        Which is a series inductor Lo = %5.3f uH\n", Lo*1E6);
+  printf("        Lo can be made from %3.1f turns on a %4.2f mm diameter air core\n", Lo_turns, diameter_mm);
+end
+
+
+if Ic == 0.014
+  printf("Transducer gain: %3.1f dB\n", 10*log10(Gt));
+
+  % Lets design the z match for the input ------------------------------
+
+  % put input impedance in parallel form
+
+  Zip = zs_to_zp(Zi);
+
+  % first match real part of impedance
+
+  Rs = 50; Rl = real(Zip);
+  [Xs Xp] = z_match(Rl,Rs);
+  
+  % Lets make Xs a capacitir to block DC, so Xp is an inductor.
+  % Modify Xs so transistor input sees conjugate match to Zi. Xs is a
+  % capacitor, so reactance is negative
+
+  Xs_match = -Xs - imag(Zip);
+
+  % Now convert to real component values
+
+  w = 2*pi*150E6; diameter_mm = 6.25; 
+  Li = Xp/w;
+  Li_turns = design_inductor(Li*1E6, diameter_mm);
+  Ci = 1/(w*(-Xs_match));
+
+  printf("Input: Zi = %3.1f + %3.1fj ohms\n", real(Zi), imag(Zi));
+  printf("       In parallel form Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), imag(Zip));
+  printf("       So for a conjugate match transistor input wants to see:\n         Rp = %3.1f Xp = %3.1fj ohms\n", real(Zip), -imag(Zip));
+  printf("       Rs = %3.1f to Rl = %3.1f ohm matching network Xs = %3.1fj Xp = %3.1fj\n", Rs, Rl, Xs, Xp);
+  printf("         with Xs a capacitor, and Xp and inductor Xs = %3.1fj Xp = %3.1fj\n", -Xs, Xp);
+  printf("       With a conj match to Zi Xs = %3.1fj Xp = %3.1fj\n", Xs_match, Xp);
+  printf("       matching components Li = %5.3f uH Ci = %4.1f pF\n", Li*1E6, Ci*1E12);
+  printf("       Li can be made from %3.1f turns on a %4.2f mm diameter air core\n", Li_turns, diameter_mm);
+
+  % Design output Z match ----------------------------------------------
+
+  Rs = real(Zo);  Rl = 50;
+  [Xs Xp] = z_match(Rl,Rs);
+
+  % Lets make XP an inductor so it can double as a RF choke, and Xp as
+  % a capacitor will give us a convenient DC block
+
+  w = 2*pi*150E6; diameter_mm = 6.25;
+  Lo = Xp/w; Lo_turns = design_inductor(Lo*1E6, diameter_mm);
+  Co = 1/(w*Xs);
+  printf("Output: Zo = %3.1f + %3.1fj ohms\n", real(Zo), imag(Zo));
+  printf("        matching network Xp = %3.1f X = %3.1f ohms\n", Xp, Xs);
+  printf("        which is parallel Lo = %5.3f uH and series Co = %4.1f pF\n", Lo*1E6, Co*1E12);
+  printf("        Lo can be made from %3.1f turns on a %4.2f mm diameter air core\n", Lo_turns, diameter_mm);
+end
+
diff --git a/codec2/branches/0.7/octave/sample_clock_offset.m b/codec2/branches/0.7/octave/sample_clock_offset.m
new file mode 100644 (file)
index 0000000..5169178
--- /dev/null
@@ -0,0 +1,21 @@
+% sample_clock_offset.m
+%
+% David Rowe June 2017
+%
+% To simulate a sample clock offset we resample by a small amount
+% using linear interpolation
+
+function rx = sample_clock_offset(tx, sample_clock_offset_ppm)
+  tin=1;
+  tout=1;
+  rx = zeros(1,length(tx));
+  while tin < length(tx)
+      t1 = floor(tin);
+      t2 = ceil(tin);
+      f = tin - t1;
+      rx(tout) = (1-f)*tx(t1) + f*tx(t2);
+      tout += 1;
+      tin  += 1+sample_clock_offset_ppm/1E6;
+  end
+end
+  
diff --git a/codec2/branches/0.7/octave/save_array_c_header.m b/codec2/branches/0.7/octave/save_array_c_header.m
new file mode 100644 (file)
index 0000000..0a6800d
--- /dev/null
@@ -0,0 +1,14 @@
+% save_array_c_header.m
+%
+% David Rowe Sep 2015
+
+function save_array_c_header(array, array_name, filename)
+  f=fopen(filename,"wt");
+  fprintf(f,"/* Generated by save_array_c_header.m Octave function */\n\n");
+  fprintf(f,"const int %s[]={\n", array_name);
+  for m=1:length(array)-1
+    fprintf(f,"  %f,\n",array(m));
+  endfor
+  fprintf(f,"  %f\n};\n",array(length(array)));
+  fclose(f);
+endfunction
diff --git a/codec2/branches/0.7/octave/save_raw.m b/codec2/branches/0.7/octave/save_raw.m
new file mode 100644 (file)
index 0000000..7f17277
--- /dev/null
@@ -0,0 +1,7 @@
+% save_raw.m
+% David Rowe 9 Feb 2015
+
+function s = save_raw(fn,s)
+  fs=fopen(fn,"wb");
+  fwrite(fs,s,"short");
+endfunction
diff --git a/codec2/branches/0.7/octave/sd.m b/codec2/branches/0.7/octave/sd.m
new file mode 100644 (file)
index 0000000..a535292
--- /dev/null
@@ -0,0 +1,170 @@
+% sd.m
+% David Rowe Aug 2012
+% Plots the spectal distorion between twofiles of LPCs.  Used for LSP 
+% quantisation tuning.
+
+function sd(raw_filename, dump_file_prefix, f)
+
+  graphics_toolkit ("gnuplot");
+
+  e_filename = sprintf("%s_E.txt", dump_file_prefix);
+  e = load(e_filename);
+  ak1_filename = sprintf("%s_ak.txt", dump_file_prefix);
+  ak2_filename = sprintf("%s_ak_.txt", dump_file_prefix);
+  ak1 = load(ak1_filename);
+  ak2 = load(ak2_filename);
+  
+  [ak1_r, ak1_c] = size(ak1)
+  [ak2_r, ak2_c] = size(ak2)
+
+  frames = max([ak1_r ak2_r]); printf("%d frames\n", frames);
+  sd = zeros(1,frames);
+  Ndft = 512;
+  A1 = zeros(frames, Ndft);
+  A2 = zeros(frames, Ndft);
+
+  % initial helicopter view of all frames
+
+  spec_err = zeros(1, Ndft);
+  for i = 1:frames
+    A1(i,:) = -20*log10(abs(fft(ak1(i,:),Ndft)));
+    A2(i,:) = -20*log10(abs(fft(ak2(i,:),Ndft)));
+    sd(i) = sum((A1(i,:) - A2(i,:)).^2)/Ndft;
+    spec_err += (A1(i,:) - A2(i,:)).^2;
+  end
+  spec_err /= frames;
+  printf("sd av %3.2f dB*dB\n", sum(sd)/frames);
+
+  % work out worst frames with sig energy
+  
+  ind = find(e < 0);
+  sd(ind) = 0;
+  [largest largest_ind] = sort(sd,"descend");
+  printf("largest SD frames....: %3.2f\n", largest(1:5));
+  printf("largest SD frames ind: %d\n", largest_ind(1:5));
+  
+  figure(1);
+  clf;
+  subplot(211)
+  fs=fopen(raw_filename,"rb");
+  s = fread(fs,Inf,"short");
+  plot(s);
+  axis([1 length(s) -20E3 20E3])
+  subplot(212)
+  [a b c] = plotyy(1:frames, sd, 1:frames, e);
+  %axis(a, [1 frames 0 10])
+
+  lsp1_filename = sprintf("%s_lsp.txt", dump_file_prefix);
+  lsp2_filename = sprintf("%s_lsp_.txt", dump_file_prefix);
+  lsp1 = load(lsp1_filename);
+  lsp2 = load(lsp2_filename);
+
+  mel_filename = sprintf("%s_mel.txt", dump_file_prefix);
+  mel = load(mel_filename);
+
+  weights_filename = sprintf("%s_weights.txt", dump_file_prefix); 
+  if file_in_path(".",weights_filename)
+    weights = load(weights_filename);
+  end
+
+  figure(4)
+  plot(e,sd,'+')
+  axis([0 50 0 10])
+  xlabel('LPC energy dB')
+  ylabel('SD dB*dB');
+
+  figure(5)
+  subplot(211)
+  ind = find(e > 0);
+  hist(sd(ind))
+  title('Histogram of SD');
+  subplot(212)
+  plot((1:Ndft)*8000/Ndft, spec_err)
+  axis([300 3000 0 max(spec_err)])
+  title('Average error across spectrum')
+
+  mel_indexes_filename = sprintf("%s_mel_indexes.txt", dump_file_prefix);
+  if 0 %file_in_path(".", mel_indexes_filename)
+    mel_indexes = load(mel_indexes_filename);
+    figure(6)
+    bins = [15, 7, 15, 7, 7, 7];
+    ind = find(e > 5); % ignore silence frames
+    for i=1:6
+      subplot(3,2,i)
+      hist(mel_indexes(ind,i),0:bins(i))
+      ylab = sprintf("index %d", i);
+      ylabel(ylab);
+    end
+  end
+
+  % now enter single step mode so we can analyse each frame
+  k = ' ';
+  largest_mode = 0;
+  do 
+    if largest_mode
+      fr = largest_ind(f);
+    else
+      fr = f; 
+    endif
+
+    figure(2);
+    clf;
+    plot((4000/pi)*lsp1((fr-2:fr+2),:));
+    hold on;
+    plot((4000/pi)*lsp2((fr-2:fr+2),:),'+-');
+    hold off;
+
+    figure(3);
+    clf;
+
+    plot((1:Ndft/2)*4000/(Ndft/2), A1(fr,1:(Ndft/2)),";A enc;r");
+    axis([1 4000 -20 40]);
+    hold on;
+    plot((1:Ndft/2)*4000/(Ndft/2), A2(fr,1:(Ndft/2)),";A dec;");
+    if file_in_path(".",weights_filename)
+      plot(lsp1(fr,:)*4000/pi, weights(fr,:),";weights;g+");
+    end
+
+    printf("\n");
+    for l=1:10
+        plot([lsp1(fr,l)*4000/pi lsp1(fr,l)*4000/pi], [0  -10], 'r');
+        plot([lsp2(fr,l)*4000/pi lsp2(fr,l)*4000/pi], [-10 -20], 'b');
+        plot([mel(fr,l) mel(fr,l)], [0 10], 'g');
+        printf("%d  ", mel(fr,l));
+    endfor
+    printf("\n");
+    
+    plot(0,0,';lsp enc;r');
+    plot(0,0,';lsp dec;b');
+    plot(0,0,';mel dec;g');
+    sd_str = sprintf(";sd %3.2f dB*dB;", sd(f));
+    plot(0,0,sd_str);
+   
+    hold off;
+
+    % interactive menu
+
+    printf("\rframe: %d  menu: n-next  b-back  l-largest mode  q-quit", fr);
+    fflush(stdout);
+    k = kbhit();
+    if (k == 'n')
+      f = f + 1;
+    endif
+    if (k == 'b')
+      f = f - 1;
+    endif
+
+    if (k == 'l')
+      if largest_mode
+        largest_mode = 0;
+      else
+        largest_mode = 1;
+        f = 1;
+      endif
+    endif
+
+  until (k == 'q')
+  printf("\n");
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/spec.m b/codec2/branches/0.7/octave/spec.m
new file mode 100644 (file)
index 0000000..d556b90
--- /dev/null
@@ -0,0 +1,86 @@
+% spec.m
+% Jean Marc Valin
+%
+% Spectrogram function for Octave 
+%
+%   Copyright (c) John-Marc Valin 2012
+%
+%   Redistribution and use in source and binary forms, with or without
+%   modification, are permitted provided that the following conditions
+%   are met:
+%   
+%   - Redistributions of source code must retain the above copyright
+%   notice, this list of conditions and the following disclaimer.
+%   
+%   - Redistributions in binary form must reproduce the above copyright
+%   notice, this list of conditions and the following disclaimer in the
+%   documentation and/or other materials provided with the distribution.
+%   
+%   - Neither the name of Jean Marc Valin nor the names of its
+%   contributors may be used to endorse or promote products derived from
+%   this software without specific prior written permission.
+%   
+%   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+%   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+%   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+%   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+%   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+%   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+%   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+%   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+%   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+%   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+%   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function X = spec(x, Fs, framesize, start, stop)
+
+
+gr=[zeros(1024,1),[0:1023]'/1023,.68*[0:1023]'/1023];
+
+%gr=[.4*[0:1023]'/1023,[0:1023]'/1023,.68*[0:1023]'/1023];
+
+%t=[0:1023]'/1023;
+%t=(1+.25*t-cos(pi*t))/2.25;
+%gr = [zeros(1024,1),t,.68*t];
+
+
+%colormap(gr);
+
+if nargin < 2 || isempty(Fs)
+   Fs = 44100;
+end
+
+if nargin < 3 || isempty(framesize)
+   framesize = 2048;
+endif
+
+offset = framesize/8;
+
+X = 20*log10(abs(specgram(x, framesize, 48000, blackmanharris(framesize)', framesize-offset)));
+
+XM=max(max(X));
+X = max(XM-30,X);
+%size(X)
+F = -[framesize/2-1:-1:0]/framesize*Fs;
+%F = [0:127]/128*24000;
+T=[1:size(X,2)]/Fs*offset;
+%imagesc(X(end:-1:1,:));
+
+if nargin < 4 || isempty(start)
+   istart=1;
+else
+   istart = round(start*Fs/offset);
+end
+
+if nargin < 5 || isempty(stop)
+   istop = size(X,2);
+else
+   istop = round(stop*Fs/offset);
+endif
+
+istart = max(1,istart);
+istop = min(istop, size(X,2));
+
+imagesc(T(1+istart:istop), F, X(end:-1:1,1+istart:istop));
+
+X = X(:,1+istart:istop);
diff --git a/codec2/branches/0.7/octave/tcohpsk.m b/codec2/branches/0.7/octave/tcohpsk.m
new file mode 100644 (file)
index 0000000..59ddae0
--- /dev/null
@@ -0,0 +1,753 @@
+% tcohpsk.m
+% David Rowe Oct 2014
+%
+% Octave coherent PSK modem script that hs two modes:
+%
+% i) tests the C port of the coherent PSK modem.  This script loads
+%    the output of unittest/tcohpsk.c and compares it to the output of
+%    the reference versions of the same modem written in Octave.
+%
+
+% (ii) Runs the Octave version of the cohpsk modem to tune and develop
+%      it, including extensive channel simulations such as AWGN noise,
+%      fading/HF, frequency offset, frequency drift, and tx/rx sample
+%      rate differences.
+
+%  TODO:
+%
+%  [X] Test
+%      [X] AWGN channel
+%      [X] freq offset
+%      [X] fading channel
+%      [X] freq drift
+%      [X] timing drift
+%  [X] tune perf/impl loss to get closer to ideal
+%      [X] linear interp of phase for better fading perf
+%  [X] freq offset/drift feedback loop 
+%  [X] PAPR measurement and reduction
+%  [X] false sync
+%      [X] doesn't sync up on noise (used EsNo = -12)
+%      [X] similar but invalid signal like huge f off
+%  [X] ability to "unsync" when signal dissapears
+%  [ ] some calibrated tests against FreeDV 1600
+%      + compare sound quality at various Es/Nos
+%  [ ] sync
+%      + set some req & implement
+%      [ ] way to handle eom w/o nasties
+%          + like mute ouput when signal has gone or v low snr
+%          + instantaneous snr
+%  [X] ssb tx filter with 3dB passband ripple
+%      + diverisity helped for AWGN BER 0.024 down to 0.016
+%      + Only a small change in fading perf with filter on/off
+%      + however other filters may have other effects, should test this, 
+%        e.g. scatter plots, some sort of BER metric?
+%  [X] EsNo estimation
+%  [ ] filter reqd with compression?
+%      + make sure not too much noise passed into noise floor
+%  [X] different diversity combination
+%      + taking largest symbol didn't help
+%  [X] histogram of bit errors
+%      + lot of data
+%      + ssb filter
+%      + compression
+%      + make sure it's flat with many errors
+
+graphics_toolkit ("gnuplot");
+more off;
+
+cohpsk;
+fdmdv;
+autotest;
+
+rand('state',1); 
+randn('state',1);
+
+% select which test  ----------------------------------------------------------
+
+test = 'compare to c';
+%test = 'awgn';
+%test = 'fading';
+
+% some parameters that can be over ridden, e.g. to disable parts of modem
+
+initial_sync = 0;  % setting this to 1 put us straight into sync w/o freq offset est
+ftrack_en    = 1;  % set to 1 to enable freq tracking
+ssb_tx_filt  = 0;  % set to 1 to to simulate SSB tx filter with passband ripple
+Fs           = 7500;
+
+% predefined tests ....
+
+if strcmp(test, 'compare to c')
+  frames = 100;
+  foff =  58.7;
+  dfoff = -0.5/Fs;
+  EsNodB = 8;
+  fading_en = 0;
+  hf_delay_ms = 2;
+  compare_with_c = 1;
+  sample_rate_ppm = -1500;
+  ssb_tx_filt  = 0;
+end
+
+% should be BER around 0.015 to 0.02
+
+if strcmp(test, 'awgn')
+  frames = 100;
+  foff =  58.7;
+  dfoff = -0.5/Fs;
+  EsNodB = 8;
+  fading_en = 0;
+  hf_delay_ms = 2;
+  compare_with_c = 0;
+  sample_rate_ppm = 0;
+end
+
+% Similar to AWGN - should be BER around 0.015 to 0.02
+
+if strcmp(test, 'fading');
+  frames = 100;
+  foff = -25;
+  dfoff = 0.5/Fs;
+  EsNodB = 12;
+  fading_en = 1;
+  hf_delay_ms = 2;
+  compare_with_c = 0;
+  sample_rate_ppm = 0;
+end
+
+EsNo = 10^(EsNodB/10);
+
+% modem constants ----------------------------------------------------------
+
+Rs = 75;               % symbol rate in Hz
+Nc = 7;                % number of carriers
+Nd = 2;                % diveristy factor
+framesize = 56;        % number of payload data bits in the frame
+
+Nsw = 4;               % 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 = 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
+
+% FDMDV init ---------------------------------------------------------------
+
+afdmdv.Fs = Fs;
+afdmdv.Nc = Nd*Nc-1;
+afdmdv.Rs = Rs;
+if Fs/afdmdv.Rs != floor(Fs/afdmdv.Rs)
+  printf("\n  Oops, Fs/Rs must be an integer!\n\n");
+  return
+end
+
+M = afdmdv.M  = afdmdv.Fs/afdmdv.Rs;
+afdmdv.Nfilter = afdmdv.Nsym*M;
+afdmdv.tx_filter_memory = zeros(afdmdv.Nc+1, afdmdv.Nfilter);
+excess_bw = 0.5;
+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);
+% 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;
+
+afdmdv.fbb_rect = exp(j*2*pi*Fcentre/Fs);
+afdmdv.fbb_phase_tx = 1;
+afdmdv.fbb_phase_rx = 1;
+
+afdmdv.Nrxdec = 31;
+afdmdv.rxdec_coeff = fir1(afdmdv.Nrxdec-1, 0.25)';
+afdmdv.rxdec_lpf_mem = zeros(1,afdmdv.Nrxdec-1+afdmdv.M);
+
+P = afdmdv.P = 4;
+afdmdv.phase_rx = ones(afdmdv.Nc+1,1);
+afdmdv.Nfilter = afdmdv.Nsym*afdmdv.M;
+afdmdv.rx_fdm_mem = zeros(1,afdmdv.Nfilter + afdmdv.M);
+Q = afdmdv.Q = afdmdv.M/4;
+if Q != floor(Q)
+  printf("\n  Yeah .... if (Fs/Rs)/4 = M/4 isn't an integer we will just go and break things.\n\n");
+end
+
+afdmdv.rx_filter_mem_timing = zeros(afdmdv.Nc+1, afdmdv.Nt*afdmdv.P);
+afdmdv.Nfiltertiming = afdmdv.M + afdmdv.Nfilter + afdmdv.M;
+
+afdmdv.rx_filter_memory = zeros(afdmdv.Nc+1, afdmdv.Nfilter);
+
+afdmdv.filt = 0;
+afdmdv.prev_rx_symb = ones(1,afdmdv.Nc+1);
+
+% COHPSK Init --------------------------------------------------------
+
+acohpsk = standard_init();
+acohpsk.framesize        = framesize;
+acohpsk.ldpc_code        = 0;
+acohpsk.ldpc_code_rate   = 1;
+acohpsk.Nc               = Nc;
+acohpsk.Rs               = Rs;
+acohpsk.Ns               = 4;
+acohpsk.coh_en           = 1;
+acohpsk.Nd               = Nd;
+acohpsk.modulation       = 'qpsk';
+acohpsk.do_write_pilot_file = 1;      % enable this to dump pilot symbols to C .h file, e.g. if frame params change
+acohpsk = symbol_rate_init(acohpsk);
+acohpsk.Ndft = 1024;
+acohpsk.f_est = afdmdv.Fcentre;
+
+ch_fdm_frame_buf = zeros(1, Nsw*acohpsk.Nsymbrowpilot*afdmdv.M);
+
+% -----------------------------------------------------------
+
+tx_bits_log = [];
+tx_symb_log = [];
+rx_amp_log = [];
+rx_phi_log = [];
+ch_symb_log = [];
+rx_symb_log = [];
+rx_bits_log = [];
+tx_bits_prev_log = [];
+uvnoise_log = [];
+nerr_log = [];
+tx_baseband_log = [];
+tx_fdm_frame_log = [];
+ch_fdm_frame_log = [];
+rx_fdm_frame_bb_log = [];
+rx_filt_log = [];
+rx_fdm_filter_log = [];
+rx_baseband_log = [];
+rx_fdm_frame_log = [];
+ct_symb_ff_log = [];
+rx_timing_log = [];
+ratio_log = [];
+foff_log = [];
+f_est_log = [];
+sig_rms_log = [];
+noise_rms_log = [];           
+noise_rms_filt_log = [];
+
+% Channel modeling and BER measurement ----------------------------------------
+
+rand('state',1); 
+tx_bits_coh = round(rand(1,framesize*10));
+ptx_bits_coh = 1;
+
+Nerrs = Tbits = 0;
+prev_tx_bits = prev_tx_bits2 = [];
+error_positions_hist = zeros(1,framesize);
+
+phase_ch = 1;
+sync = initial_sync;
+acohpsk.f_est = Fcentre;
+acohpsk.f_fine_est = 0;
+acohpsk.ct = 4;
+acohpsk.ftrack_en = ftrack_en;
+
+[spread spread_2ms hf_gain] = init_hf_model(Fs, frames*acohpsk.Nsymbrowpilot*afdmdv.M);
+hf_n = 1;
+nhfdelay = floor(hf_delay_ms*Fs/1000);
+ch_fdm_delay = zeros(1, acohpsk.Nsymbrowpilot*M + nhfdelay);
+
+% simulated SSB tx filter
+
+[b, a] = cheby1(4, 3, [600, 2600]/(Fs/2));
+[y filt_states] = filter(b,a,0);
+h = freqz(b,a,(600:2600)/(Fs/(2*pi)));
+filt_gain = (2600-600)/sum(abs(h) .^ 2);   % ensures power after filter == before filter
+
+noise_rms_filt = 0;
+
+% main loop --------------------------------------------------------------------
+
+% run mod and channel as aseparate loop so we can resample to simulate sample rate differences
+
+for f=1:frames
+  tx_bits = tx_bits_coh(ptx_bits_coh:ptx_bits_coh+framesize-1);
+  ptx_bits_coh += framesize;
+  if ptx_bits_coh > length(tx_bits_coh)
+    ptx_bits_coh = 1;
+  end
+
+  tx_bits_log = [tx_bits_log tx_bits];
+
+  [tx_symb tx_bits] = bits_to_qpsk_symbols(acohpsk, tx_bits, [], []);
+  tx_symb_log = [tx_symb_log; tx_symb];
+  
+  tx_fdm_frame = [];
+  for r=1:acohpsk.Nsymbrowpilot
+    tx_onesymb = tx_symb(r,:);
+    [tx_baseband afdmdv] = tx_filter(afdmdv, tx_onesymb);
+    tx_baseband_log = [tx_baseband_log tx_baseband];
+    [tx_fdm afdmdv] = fdm_upconvert(afdmdv, tx_baseband);
+    tx_fdm_frame = [tx_fdm_frame tx_fdm];
+  end
+
+  % clipping, which along with non-linear carrier spacing, improves PAPR
+  % The value of clip is a function of Nc and is adjusted experimentally
+  % such that the BER hit over no clipping at Es/No=8dB is small.
+
+  ind = find(abs(tx_fdm_frame) > clip);
+  tx_fdm_frame(ind) = clip*exp(j*angle(tx_fdm_frame(ind)));
+
+  tx_fdm_frame_log = [tx_fdm_frame_log tx_fdm_frame];
+
+  %
+  % Channel --------------------------------------------------------------------
+  %
+
+  % simulate tx SSB filter with ripple
+
+  if ssb_tx_filt
+    [tx_fdm_frame filt_states] = filter(b,a,sqrt(filt_gain)*tx_fdm_frame, filt_states);
+  end
+
+  % frequency offset and frequency drift
+
+  ch_fdm_frame = zeros(1,acohpsk.Nsymbrowpilot*M);
+  for i=1:acohpsk.Nsymbrowpilot*M
+    foff_rect = exp(j*2*pi*foff/Fs);
+    foff += dfoff;
+    phase_ch *= foff_rect;
+    ch_fdm_frame(i) = tx_fdm_frame(i) * phase_ch;
+  end
+  foff_log = [foff_log foff];
+  phase_ch /= abs(phase_ch);
+  % printf("foff: %f  ", foff);
+
+  % optional fading
+
+  if fading_en
+    ch_fdm_delay(1:nhfdelay) = ch_fdm_delay(acohpsk.Nsymbrowpilot*M+1:nhfdelay+acohpsk.Nsymbrowpilot*M);
+    ch_fdm_delay(nhfdelay+1:nhfdelay+acohpsk.Nsymbrowpilot*M) = ch_fdm_frame;
+
+    for i=1:acohpsk.Nsymbrowpilot*M
+      ahf_model = hf_gain*(spread(hf_n)*ch_fdm_frame(i) + spread_2ms(hf_n)*ch_fdm_delay(i));
+      ch_fdm_frame(i) = ahf_model;
+      hf_n++;
+    end
+  end
+
+  % each carrier has power = 2, total power 2Nc, total symbol rate NcRs, noise BW B=Fs
+  % Es/No = (C/Rs)/(N/B), N = var = 2NcFs/NcRs(Es/No) = 2Fs/Rs(Es/No)
+
+  variance = 2*Fs/(acohpsk.Rs*EsNo);
+  uvnoise = sqrt(0.5)*(randn(1,acohpsk.Nsymbrowpilot*M) + j*randn(1,acohpsk.Nsymbrowpilot*M));
+  uvnoise_log = [uvnoise_log uvnoise];
+  noise = sqrt(variance)*uvnoise;
+
+  ch_fdm_frame += noise;
+
+  ch_fdm_frame_log = [ch_fdm_frame_log ch_fdm_frame];
+end
+
+% simulate difference in sample clocks
+
+%ch_fdm_frame_log = resample(ch_fdm_frame_log, (1E6 + sample_rate_ppm), 1E6);
+
+tin=1;
+tout=1;
+ch_fdm_frame_log_out = zeros(1,length(ch_fdm_frame_log));
+while tin < length(ch_fdm_frame_log)
+      t1 = floor(tin);
+      t2 = ceil(tin);
+      f = tin - t1;
+      ch_fdm_frame_log_out(tout) = (1-f)*ch_fdm_frame_log(t1) + f*ch_fdm_frame_log(t2);
+      tout += 1;
+      tin  += 1+sample_rate_ppm/1E6;
+      %printf("tin: %f tout: %f f: %f\n", tin, tout, f);
+end
+ch_fdm_frame_log = ch_fdm_frame_log_out(1:tout-1);
+%ch_fdm_frame_log *= 5000;
+
+%ch_fdm_frame_log = real(ch_fdm_frame_log);
+
+% Now run demod ----------------------------------------------------------------
+
+%ch_fdm_frame_log = load_raw("~/fdmdv2-dev/build_linux/tmp.raw");
+%ch_fdm_frame_log = ch_fdm_frame_log(M:length(ch_fdm_frame_log));
+%ch_fdm_frame_log /= 5000;
+
+%frames = floor(acohpsk.Nsymbrowpilot*M);
+
+ch_fdm_frame_log_index = 1;
+nin = M;
+f = 0;
+nin_frame = acohpsk.Nsymbrowpilot*M;
+
+%while (ch_fdm_frame_log_index + acohpsk.Nsymbrowpilot*M+M/P) < length(ch_fdm_frame_log)
+for f=1:frames;
+  acohpsk.frame = f;
+
+  ch_fdm_frame = ch_fdm_frame_log(ch_fdm_frame_log_index:ch_fdm_frame_log_index + nin_frame - 1);
+  ch_fdm_frame_log_index += nin_frame;
+
+  %
+  % Demod ----------------------------------------------------------------------
+  %
+
+  % store two frames of received samples so we can rewind if we get a good candidate
+
+  ch_fdm_frame_buf(1:Nsw*acohpsk.Nsymbrowpilot*M-nin_frame) = ch_fdm_frame_buf(nin_frame+1:Nsw*acohpsk.Nsymbrowpilot*M);
+  ch_fdm_frame_buf(Nsw*acohpsk.Nsymbrowpilot*M-nin_frame+1:Nsw*acohpsk.Nsymbrowpilot*M) = ch_fdm_frame;
+
+  next_sync = sync;
+
+  % if out of sync do Initial Freq offset estimation over NSW frames to flush out memories
+
+  if (sync == 0)
+
+    % we can test +/- 20Hz, so we break this up into 3 tests to cover +/- 60Hz
+
+    max_ratio = 0;
+    for acohpsk.f_est = Fcentre-40:40:Fcentre+40
+%    for acohpsk.f_est = Fcentre
+        
+      printf("  [%d] acohpsk.f_est: %f +/- 20\n", f, acohpsk.f_est);
+
+      % we are out of sync so reset f_est and process two frames to clean out memories
+
+      [ch_symb rx_timing rx_filt rx_baseband afdmdv acohpsk.f_est] = rate_Fs_rx_processing(afdmdv, ch_fdm_frame_buf, acohpsk.f_est, Nsw*acohpsk.Nsymbrowpilot, nin, 0);
+      rx_baseband_log = [rx_baseband_log rx_baseband];
+      
+      rx_filt_log = [rx_filt_log rx_filt];
+      ch_symb_log = [ch_symb_log; ch_symb];
+      rx_timing_log = [rx_timing_log rx_timing];
+
+      for i=1:Nsw-1
+        acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb((i-1)*acohpsk.Nsymbrowpilot+1:i*acohpsk.Nsymbrowpilot,:), acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+      end
+      [anext_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb((Nsw-1)*acohpsk.Nsymbrowpilot+1:Nsw*acohpsk.Nsymbrowpilot,:), sync, next_sync);
+
+      if anext_sync == 1
+        %printf("  [%d] acohpsk.ratio: %f\n", f, acohpsk.ratio);
+        if acohpsk.ratio > max_ratio
+          max_ratio   = acohpsk.ratio;
+          f_est       = acohpsk.f_est - acohpsk.f_fine_est;
+          next_sync   = anext_sync;
+        end
+      end
+    end
+
+    if next_sync == 1
+
+      % we've found a sync candidate!
+      % re-process last two frames with adjusted f_est then check again
+
+      acohpsk.f_est = f_est;
+
+      printf("  [%d] trying sync and f_est: %f\n", f, acohpsk.f_est);
+
+      [ch_symb rx_timing rx_filt rx_baseband afdmdv f_est] = rate_Fs_rx_processing(afdmdv, ch_fdm_frame_buf, acohpsk.f_est, Nsw*acohpsk.Nsymbrowpilot, nin, 0);
+      rx_baseband_log = [rx_baseband_log rx_baseband];
+      rx_filt_log = [rx_filt_log rx_filt];
+      ch_symb_log = [ch_symb_log; ch_symb];
+      rx_timing_log = [rx_timing_log rx_timing];
+
+      for i=1:Nsw-1
+        acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb((i-1)*acohpsk.Nsymbrowpilot+1:i*acohpsk.Nsymbrowpilot,:), acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+      end
+      [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb((Nsw-1)*acohpsk.Nsymbrowpilot+1:Nsw*acohpsk.Nsymbrowpilot,:), sync, next_sync);
+      if abs(acohpsk.f_fine_est) > 2
+        printf("  [%d] Hmm %f is a bit big so back to coarse est ...\n", f, acohpsk.f_fine_est);
+        next_sync = 0;
+      end
+
+      if acohpsk.ratio < 0.9
+        next_sync = 0;
+      end
+      if next_sync == 1
+        % OK we are in sync!
+        % demodulate first frame (demod completed below)
+
+        printf("  [%d] in sync! f_est: %f ratio: %f \n", f, f_est, acohpsk.ratio);
+        acohpsk.ct_symb_ff_buf(1:acohpsk.Nsymbrowpilot+2,:) = acohpsk.ct_symb_buf(acohpsk.ct+1:acohpsk.ct+acohpsk.Nsymbrowpilot+2,:);
+      end
+    end  
+  end
+
+  % If in sync just do sample rate processing on latest frame
+
+  if sync == 1
+    [ch_symb rx_timing rx_filt rx_baseband afdmdv acohpsk.f_est] = rate_Fs_rx_processing(afdmdv, ch_fdm_frame, acohpsk.f_est, acohpsk.Nsymbrowpilot, nin, acohpsk.ftrack_en);
+    [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb, sync, next_sync);
+
+    acohpsk.ct_symb_ff_buf(1:2,:) = acohpsk.ct_symb_ff_buf(acohpsk.Nsymbrowpilot+1:acohpsk.Nsymbrowpilot+2,:);
+    acohpsk.ct_symb_ff_buf(3:acohpsk.Nsymbrowpilot+2,:) = acohpsk.ct_symb_buf(acohpsk.ct+3:acohpsk.ct+acohpsk.Nsymbrowpilot+2,:);
+
+    rx_baseband_log = [rx_baseband_log rx_baseband];
+    rx_filt_log = [rx_filt_log rx_filt];
+    ch_symb_log = [ch_symb_log; ch_symb];     
+    rx_timing_log = [rx_timing_log rx_timing];
+    f_est_log = [f_est_log acohpsk.f_est];
+    %printf("%f\n", acohpsk.f_est);
+  end
+
+  % if we are in sync complete demodulation with symbol rate processing
+
+  if (next_sync == 1) || (sync == 1)
+    [rx_symb rx_bits rx_symb_linear amp_ phi_ sig_rms noise_rms] = qpsk_symbols_to_bits(acohpsk, acohpsk.ct_symb_ff_buf);
+    rx_symb_log = [rx_symb_log; rx_symb];
+    rx_amp_log = [rx_amp_log; amp_];
+    rx_phi_log = [rx_phi_log; phi_];
+    rx_bits_log = [rx_bits_log rx_bits];
+    tx_bits_prev_log = [tx_bits_prev_log prev_tx_bits2];
+    ratio_log = [ratio_log acohpsk.ratio];
+    ct_symb_ff_log = [ct_symb_ff_log; acohpsk.ct_symb_ff_buf(1:acohpsk.Nsymbrowpilot,:)];
+    sig_rms_log = [sig_rms_log sig_rms];
+    noise_rms_log = [noise_rms_log noise_rms];
+    noise_rms_filt = 0.9*noise_rms_filt + 0.1*noise_rms;
+    noise_rms_filt_log = [noise_rms_filt_log noise_rms_filt];
+
+    % BER stats
+
+    if f > 2
+      error_positions = xor(tx_bits_log((f-3)*framesize+1:(f-2)*framesize), rx_bits);
+      Nerrs  += sum(error_positions);
+      nerr_log = [nerr_log sum(error_positions)];
+      Tbits += length(error_positions);
+      error_positions_hist += error_positions;
+    end
+    printf("\r  [%d]", f);
+  end
+
+  % reset BER stats if we lose sync
+
+  if sync == 1
+    %Nerrs = 0;
+    %Tbits = 0;
+    %nerr_log = [];
+  end
+
+  [sync acohpsk] = sync_state_machine(acohpsk, sync, next_sync);
+
+  % work out how many samples we need for next time
+
+  nin = M;
+  if sync == 1
+    if rx_timing(length(rx_timing)) > M/P
+      nin = M + M/P;
+    end
+    if rx_timing(length(rx_timing)) < -M/P
+      nin = M - M/P;
+    end
+  end
+  nin_frame = (acohpsk.Nsymbrowpilot-1)*M + nin;
+  %printf("%f %d %d\n", rx_timing(length(rx_timing)), nin, nin_frame);
+
+  prev_tx_bits2 = prev_tx_bits;
+  prev_tx_bits = tx_bits;
+
+end
+
+ber = Nerrs/Tbits;
+printf("\nOctave EsNodB: %4.1f ber..: %4.3f Nerrs..: %d Tbits..: %d\n", EsNodB, ber, Nerrs, Tbits);
+
+if compare_with_c
+
+  % Output vectors from C port ---------------------------------------------------
+
+  load ../build_linux/unittest/tcohpsk_out.txt
+
+  % Determine bit error rate
+
+  
+  sz = length(rx_bits_log_c);
+  Nerrs_c = sum(xor(tx_bits_log(1:sz-framesize), rx_bits_log_c(framesize+1:sz)));
+  Tbits_c = length(tx_bits_prev_log);
+  ber_c = Nerrs_c/Tbits_c;
+  printf("C EsNodB.....: %4.1f ber_c: %4.3f Nerrs_c: %d Tbits_c: %d\n", EsNodB, ber_c, Nerrs_c, Tbits_c);
+  
+  stem_sig_and_error(1, 111, tx_bits_log_c, tx_bits_log - tx_bits_log_c, 'tx bits', [1 length(tx_bits_log) -1.5 1.5])
+  
+  stem_sig_and_error(2, 211, real(tx_symb_log_c), real(tx_symb_log - tx_symb_log_c), 'tx symb re', [1 length(tx_symb_log_c) -1.5 1.5])
+  stem_sig_and_error(2, 212, imag(tx_symb_log_c), imag(tx_symb_log - tx_symb_log_c), 'tx symb im', [1 length(tx_symb_log_c) -1.5 1.5])
+
+  stem_sig_and_error(3, 211, real(tx_fdm_frame_log_c), real(tx_fdm_frame_log - tx_fdm_frame_log_c), 'tx fdm frame re', [1 length(tx_fdm_frame_log) -10 10])
+  stem_sig_and_error(3, 212, imag(tx_fdm_frame_log_c), imag(tx_fdm_frame_log - tx_fdm_frame_log_c), 'tx fdm frame im', [1 length(tx_fdm_frame_log) -10 10])
+  stem_sig_and_error(4, 211, real(ch_fdm_frame_log_c), real(ch_fdm_frame_log - ch_fdm_frame_log_c), 'ch fdm frame re', [1 length(ch_fdm_frame_log) -10 10])
+  stem_sig_and_error(4, 212, imag(ch_fdm_frame_log_c), imag(ch_fdm_frame_log - ch_fdm_frame_log_c), 'ch fdm frame im', [1 length(ch_fdm_frame_log) -10 10])
+
+  c = 1;
+  stem_sig_and_error(5, 211, real(rx_baseband_log_c(c,:)), real(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'rx baseband re', [1 length(rx_baseband_log) -10 10])
+  stem_sig_and_error(5, 212, imag(rx_baseband_log_c(c,:)), imag(rx_baseband_log(c,:) - rx_baseband_log_c(c,:)), 'rx baseband im', [1 length(rx_baseband_log) -10 10])
+  stem_sig_and_error(6, 211, real(rx_filt_log_c(c,:)), real(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'rx filt re', [1 length(rx_filt_log) -1 1])
+  stem_sig_and_error(6, 212, imag(rx_filt_log_c(c,:)), imag(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'rx filt im', [1 length(rx_filt_log) -1 1])
+
+  [n m] = size(ch_symb_log);
+  stem_sig_and_error(7, 211, real(ch_symb_log_c), real(ch_symb_log - ch_symb_log_c), 'ch symb re', [1 n -1.5 1.5])
+  stem_sig_and_error(7, 212, imag(ch_symb_log_c), imag(ch_symb_log - ch_symb_log_c), 'ch symb im', [1 n -1.5 1.5])
+
+  [n m] = size(rx_symb_log);
+  stem_sig_and_error(8, 211, rx_amp_log_c, rx_amp_log - rx_amp_log_c, 'Amp Est', [1 n -1.5 1.5])
+  phi_log_diff = rx_phi_log - rx_phi_log_c;
+  phi_log_diff(find(phi_log_diff > pi)) -= 2*pi;
+  phi_log_diff(find(phi_log_diff < -pi)) += 2*pi;
+  stem_sig_and_error(8, 212, rx_phi_log_c, phi_log_diff, 'Phase Est', [1 n -4 4])
+  stem_sig_and_error(9, 211, real(rx_symb_log_c), real(rx_symb_log - rx_symb_log_c), 'rx symb re', [1 n -1.5 1.5])
+  stem_sig_and_error(9, 212, imag(rx_symb_log_c), imag(rx_symb_log - rx_symb_log_c), 'rx symb im', [1 n -1.5 1.5])
+
+  stem_sig_and_error(10, 111, rx_bits_log_c, rx_bits_log - rx_bits_log_c, 'rx bits', [1 length(rx_bits_log) -1.5 1.5])
+  stem_sig_and_error(11, 111, f_est_log_c - Fcentre - foff, f_est_log - f_est_log_c, 'f est', [1 length(f_est_log) -5 5])
+  stem_sig_and_error(12, 111, rx_timing_log_c, rx_timing_log_c - rx_timing_log, 'rx timing', [1 length(rx_timing_log) -M M])
+
+  check(tx_bits_log, tx_bits_log_c, 'tx_bits');
+  check(tx_symb_log, tx_symb_log_c, 'tx_symb');
+  check(tx_fdm_frame_log, tx_fdm_frame_log_c, 'tx_fdm_frame',0.01);
+  check(ch_fdm_frame_log, ch_fdm_frame_log_c, 'ch_fdm_frame',0.01);
+  %check(rx_fdm_frame_bb_log, rx_fdm_frame_bb_log_c, 'rx_fdm_frame_bb', 0.01);
+
+  check(ch_symb_log, ch_symb_log_c, 'ch_symb',0.05);
+  %check(ct_symb_ff_log, ct_symb_ff_log_c, 'ct_symb_ff',0.01);
+  check(rx_amp_log, rx_amp_log_c, 'rx_amp_log',0.01);
+  check(phi_log_diff, zeros(length(phi_log_diff), Nc*Nd), 'rx_phi_log',0.1);
+  check(rx_symb_log, rx_symb_log_c, 'rx_symb',0.01);
+  check(rx_timing_log, rx_timing_log_c, 'rx_timing',0.005);
+  check(rx_bits_log, rx_bits_log_c, 'rx_bits');
+  check(f_est_log, f_est_log_c, 'f_est');
+  check(sig_rms_log, sig_rms_log_c, 'sig_rms');
+  check(noise_rms_log, noise_rms_log_c, 'noise_rms');
+  
+
+else
+  
+  papr = max(tx_fdm_frame_log.*conj(tx_fdm_frame_log)) / mean(tx_fdm_frame_log.*conj(tx_fdm_frame_log));
+  papr_dB = 10*log10(papr);
+  printf("av tx pwr: %4.2f PAPR: %4.2f av rx pwr: %4.2f\n", var(tx_fdm_frame_log), papr_dB, var(ch_fdm_frame_log));
+
+  % some other useful plots
+
+  figure(1)
+  clf
+  subplot(211)
+  plot(real(tx_fdm_frame_log))
+  title('tx fdm real');
+  subplot(212)
+  plot(imag(tx_fdm_frame_log))
+  title('tx fdm imag');
+
+  figure(2)
+  clf
+  spec = 20*log10(abs(fft(tx_fdm_frame_log)));
+  l = length(spec);
+  plot((Fs/l)*(1:l), spec)
+  axis([1 Fs/2 0 max(spec)]);
+  title('tx spectrum');
+  ylabel('Amplitude (dB)')
+  xlabel('Frequency (Hz)')
+  grid;
+
+  figure(3)
+  clf;
+  % plot combined signals to show diversity gains
+  combined = rx_symb_log(:,1:Nc);
+  for d=2:Nd
+    combined += rx_symb_log(:, (d-1)*Nc+1:d*Nc);
+  end
+  plot(combined*exp(j*pi/4)/sqrt(Nd),'+')
+  title('Scatter');
+  ymax = abs(max(max(combined)));
+  axis([-ymax ymax -ymax ymax])
+
+  figure(4)
+  clf;
+  subplot(211)
+  plot(rx_phi_log)
+  subplot(212)
+  plot(rx_amp_log)
+
+  figure(5)
+  clf;
+  subplot(211)
+  plot(rx_timing_log)
+  title('rx timing');
+  subplot(212)
+  stem(ratio_log)
+  title('Sync ratio');
+
+  figure(6)
+  clf;
+  subplot(211)
+  stem(nerr_log)
+  title('Bit Errors');
+  subplot(212)
+  plot(noise_rms_filt_log,'r', sig_rms_log,'g');
+  title('Est rms signal and noise')
+
+  figure(7);
+  clf;
+  subplot(211)
+  plot(foff_log,';freq offset;');
+  hold on;
+  plot(f_est_log - Fcentre,'g;freq offset est;');
+  hold off;
+  title('freq offset');
+  legend("boxoff");  
+  subplot(212)
+  plot(foff_log(1:length(f_est_log)) - f_est_log + Fcentre)
+  title('freq offset estimation error');
+
+  figure(8)
+  clf
+  h = freqz(b,a,Fs/2);
+  plot(20*log10(abs(h)))
+  axis([1 Fs/2 -20 0])
+  grid
+  title('SSB tx filter')
+
+  figure(9)
+  clf
+  plot(error_positions_hist)    
+  title('histogram of bit errors')                               
+
+  
+end
+
+
+% function to write C header file of noise samples so C version gives
+% extactly the same results
+
+function write_noise_file(uvnoise_log)
+
+  m = length(uvnoise_log);
+
+  filename = sprintf("../unittest/noise_samples.h");
+  f=fopen(filename,"wt");
+  fprintf(f,"/* unit variance complex noise samples */\n\n");
+  fprintf(f,"/* Generated by write_noise_file() Octave function */\n\n");
+  fprintf(f,"COMP noise[]={\n");
+  for r=1:m
+    if r < m
+      fprintf(f, "  {%f,%f},\n", real(uvnoise_log(r)), imag(uvnoise_log(r)));
+    else
+      fprintf(f, "  {%f,%f}\n};", real(uvnoise_log(r)), imag(uvnoise_log(r)));
+    end
+  end
+
+  fclose(f);
+endfunction
+
+
+% function to write float fading samples for use by C programs
+
+function write_noise_file(raw_file_name, Fs, len_samples)
+  [spread spread_2ms hf_gain] = init_hf_model(Fs, len_samples);
+ hf_gain
+  % interleave real imag samples
+
+  inter = zeros(1,len_samples*4);
+  inter(1:4) = hf_gain;
+  for i=1:len_samples
+    inter(i*4+1) = real(spread(i));
+    inter(i*4+2) = imag(spread(i));
+    inter(i*4+3) = real(spread_2ms(i));
+    inter(i*4+4) = imag(spread_2ms(i));
+  end
+  f = fopen(raw_file_name,"wb");
+  fwrite(f, inter, "float32");
+  fclose(f);
+endfunction
diff --git a/codec2/branches/0.7/octave/telem_upload.py b/codec2/branches/0.7/octave/telem_upload.py
new file mode 100644 (file)
index 0000000..ada35a7
--- /dev/null
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#
+#   Horus Binary (and oldschool) Telemetry Uploader
+#
+#   Mark Jessop 2015-12-31
+#   <vk5qi@rfhead.net>
+#
+#   This script takes either a hex representation of the binary payload, or 
+#   a 'classic' ASCII sentence, and uploads it to Habitat.
+#
+#   Currently this script tells the two apart by looking for 'HORUS' at the start
+#   of the argument to determine if it's an ASCII sentence.
+#   
+#   It's designed to be called from fsk_horus_stream.m, and is tailored for it's output.
+#
+#   Dependencies:
+#   - Python 2.7 (Will probably break in Python 3)
+#   - crcmod (pip install crcmod)
+#
+
+import time, struct, json, socket, httplib, crcmod, argparse, sys
+from base64 import b64encode
+from hashlib import sha256
+from datetime import datetime
+
+def crc16_ccitt(data):
+    """
+    Calculate the CRC16 CCITT checksum of *data*.
+    
+    (CRC16 CCITT: start 0xFFFF, poly 0x1021)
+    """
+    crc16 = crcmod.predefined.mkCrcFun('crc-ccitt-false')
+    return crc16(data)
+
+# Binary packet format, from https://github.com/darksidelemm/PicoHorusBinary/tree/master/PicoPayloadGPS
+# struct TBinaryPacket
+# {
+# uint8_t       PayloadID;
+# uint16_t  Counter;
+# uint8_t       Hours;
+# uint8_t       Minutes;
+# uint8_t       Seconds;
+# float     Latitude;
+# float     Longitude;
+# uint16_t      Altitude;
+# uint8_t   Speed; // Speed in Knots (1-255 knots)
+# uint8_t   Sats;
+# int8_t   Temp; // Twos Complement Temp value.
+# uint8_t   BattVoltage; // 0 = 0.5v, 255 = 2.0V, linear steps in-between.
+# uint16_t Checksum; // CRC16-CCITT Checksum.
+# };  //  __attribute__ ((packed));
+
+def decode_horus_binary_telemetry(payload):
+
+    horus_format_struct = "<BHBBBffHBBbBH"
+    try:
+        unpacked = struct.unpack(horus_format_struct, payload)
+    except:
+        print "Wrong string length. Packet contents:"
+        print ":".join("{:02x}".format(ord(c)) for c in payload)
+        sys.exit(1)
+
+    telemetry = {}
+    telemetry['payload_id'] = unpacked[0]
+    telemetry['counter'] = unpacked[1]
+    telemetry['time'] = "%02d:%02d:%02d" % (unpacked[2],unpacked[3],unpacked[4])
+    telemetry['latitude'] = unpacked[5]
+    telemetry['longitude'] = unpacked[6]
+    telemetry['altitude'] = unpacked[7]
+    telemetry['speed'] = unpacked[8]
+    telemetry['sats'] = unpacked[9]
+    telemetry['temp'] = unpacked[10]
+    telemetry['batt_voltage_raw'] = unpacked[11]
+    telemetry['checksum'] = unpacked[12]
+
+    # Convert some of the fields into more useful units.
+    telemetry['batt_voltage'] = 0.5 + 1.5*telemetry['batt_voltage_raw']/255.0
+
+    return telemetry
+
+# Compatible with Habitat Payload ID 55f39c02e518bdd2885c8aac7d1cdd7c
+def telemetry_to_sentence(telemetry):
+    sentence = "$$PICOHORUSBINARY,%d,%s,%.5f,%.5f,%d,%d,%d,%d,%.2f" % (telemetry['counter'],telemetry['time'],telemetry['latitude'],
+        telemetry['longitude'],telemetry['altitude'],telemetry['speed'],telemetry['sats'],telemetry['temp'],telemetry['batt_voltage'])
+
+    checksum = hex(crc16_ccitt(sentence[2:]))[2:].upper().zfill(4)
+    output = sentence + "*" + checksum + "\n"
+    return output
+
+# Habitat Upload Functions
+def habitat_upload_sentence(sentence, callsign="N0CALL"):
+
+    sentence_b64 = b64encode(sentence)
+
+    date = datetime.utcnow().isoformat("T") + "Z"
+
+    data = {
+        "type": "payload_telemetry",
+        "data": {
+            "_raw": sentence_b64
+            },
+        "receivers": {
+            callsign: {
+                "time_created": date,
+                "time_uploaded": date,
+                },
+            },
+    }
+    try:
+        c = httplib.HTTPConnection("habitat.habhub.org",timeout=4)
+        c.request(
+            "PUT",
+            "/habitat/_design/payload_telemetry/_update/add_listener/%s" % sha256(sentence_b64).hexdigest(),
+            json.dumps(data),  # BODY
+            {"Content-Type": "application/json"}  # HEADERS
+            )
+
+        response = c.getresponse()
+        sys.exit(0)
+    except Exception as e:
+        print("Failed to upload to Habitat.")
+        sys.exit(1)
+
+parser = argparse.ArgumentParser()
+parser.add_argument("raw_data", help="Raw Data, either hex binary data, or ASCII payload string.")
+parser.add_argument("-c","--callsign",default="N0CALL",help="Habitat Upload Callsign")
+args = parser.parse_args()
+
+
+uploader_callsign = args.callsign
+raw_data = args.raw_data
+print(raw_data)
+
+if raw_data.startswith("AX5ARG"):
+    # Assume the data is a standard telemetry string and just upload it.
+    # Append a Newline and checksum (if not alread there) to the end, and "$$"'s to the start.
+    if not '*' in raw_data:
+        # Assume there is no checksum on the end of the string, and add one.
+        checksum = hex(crc16_ccitt(raw_data))[2:].upper().zfill(4)
+        raw_data = raw_data + "*" + checksum
+    if raw_data[:-1] != '\n':
+        raw_data = "$$" + raw_data + '\n'
+
+    habitat_upload_sentence(raw_data, callsign = uploader_callsign)
+else:
+    # Attempt to decode some hex data.
+    data = raw_data.decode("hex")
+    telem = decode_horus_binary_telemetry(data)
+    # Only convert and upload if checksum passes.
+    if(crc16_ccitt(data[:-2]) != telem['checksum']):
+        print("Checksum Failed!")
+        sys.exit(1)
+
+    sentence = telemetry_to_sentence(telem)
+    print("Uploading: %s"%(sentence))
+    habitat_upload_sentence(sentence, callsign = uploader_callsign)
+
diff --git a/codec2/branches/0.7/octave/test_cohpsk.m b/codec2/branches/0.7/octave/test_cohpsk.m
new file mode 100644 (file)
index 0000000..6864488
--- /dev/null
@@ -0,0 +1,563 @@
+% test_cohpsk.m
+% David Rowe Oct 2014
+%
+
+% Bunch of simulations to test coherent FDM QPSK with pilot based
+% coherent detection, DSSS (diversity), and rate 1/2 LDPC
+
+% TODO
+%   [X] Nc carriers, 588 bit frames
+%   [X] FEC
+%   [X] pilot insertion and removal
+%   [ ] delay on parity carriers
+%   [X] pilot based phase est
+%   [ ] uncoded and coded frame sync
+%   [X] timing estimation, RN filtering, carrier FDM
+%   [ ] this file getting too big - refactor
+%   [ ] robust coarse timing
+%   [ ] Np knob on GUI
+%   [ ] experimental tuning on EnNo_, fading[], to optimise LDPC dec perf
+% reqd to make sure we can repeat tests exactly
+
+rand('state',1); 
+randn('state',1);
+graphics_toolkit ("gnuplot");
+
+cohpsk;
+
+function test_curves
+     
+  sim_in = standard_init();
+  sim_in.do_write_pilot_file = 0;
+
+  % single test point ---------------------------------------
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 20; 
+  sim_in.framesize        = 32;
+  sim_in.Ntrials          = 400;
+  sim_in.Rs               = 50;
+  sim_in.Nc               = 4;
+  sim_in.Np               = 2;
+  sim_in.Ns               = 4;
+  sim_in.Nd               = 1;
+  sim_in.modulation       = 'qpsk';
+  sim_in.ldpc_code_rate   = 1;
+  sim_in.ldpc_code        = 0;
+  sim_in.coh_en           = 1;
+
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 0;
+  sim_in.f_off            = 0;
+  sim_in.div_timeshift    = 1;
+
+  sim_qpsk                = ber_test(sim_in);
+
+  % AWGN curves ----------------------------------------------------
+
+  sim_in.Ntrials          = 400;
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 5:10; 
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+  
+  sim_in.modulation       = 'dqpsk';
+  sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+
+  sim_in.modulation       = 'qpsk';
+  sim_qpsk_pilot          = ber_test(sim_in, 'qpsk');
+
+  % HF curves ----------------------------------------------------
+
+  sim_in.Ntrials          = 400;
+  sim_in.hf_sim           = 1;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 5:20; 
+  sim_in.modulation       = 'dqpsk';
+  sim_dqpsk_hf            = ber_test(sim_in, 'dqpsk');
+
+  sim_in.modulation       = 'qpsk';
+  sim_in.coh_en           = 0;
+  sim_in.hf_mag_only      = 1;
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+
+  sim_in.coh_en           = 1;
+  sim_in.hf_mag_only      = 0;
+  sim_qpsk_pilot_hf       = ber_test(sim_in, 'qpsk');
+
+  sim_in.Nd               = 2;
+  sim_in.div_timeshift    = 1;
+  sim_qpsk_pilot_hf_div   = ber_test(sim_in, 'qpsk');
+
+  sim_in.div_timeshift    = sim_in.Rs;
+  sim_qpsk_pilot_hf_div2  = ber_test(sim_in, 'qpsk');
+
+  sim_in.modulation       = 'qpsk';
+  sim_in.coh_en           = 0;
+  sim_in.hf_mag_only      = 1;
+  sim_in.div_timeshift    = 1;
+  sim_qpsk_hf_div         = ber_test(sim_in, 'qpsk');
+
+  % plot results ---------------------------------------------------
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+
+  semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'c;DQPSK AWGN;')
+  semilogy(sim_qpsk_pilot.Ebvec, sim_qpsk_pilot.BERvec,'b;QPSK pilot AWGN;')
+
+  semilogy(sim_qpsk_hf.Ebvec, sim_qpsk_hf.BERvec,'r;QPSK HF ideal;')
+  semilogy(sim_qpsk_hf_div.Ebvec, sim_qpsk_hf_div.BERvec,'r;QPSK HF ideal div;')
+  semilogy(sim_qpsk_pilot_hf.Ebvec, sim_qpsk_pilot_hf.BERvec,'b;QPSK pilot HF;')
+  semilogy(sim_qpsk_pilot_hf_div.Ebvec, sim_qpsk_pilot_hf_div.BERvec,'g;QPSK pilot Nd=2 HF;')
+  semilogy(sim_qpsk_pilot_hf_div2.Ebvec, sim_qpsk_pilot_hf_div2.BERvec,'g;QPSK pilot Nd=2 Rs HF;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'c;DQPSK HF;')
+
+  hold off;
+
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(sim_qpsk_hf.Ebvec) max(sim_qpsk_hf.Ebvec) 1E-3 1])
+  legend("boxoff");
+endfunction
+
+
+function test_single
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.framesize        = 32;
+  sim_in.Nc               = 4;
+  sim_in.Rs               = 50;
+  sim_in.Ns               = 4;
+  sim_in.Np               = 2;
+  sim_in.Nd               = 2;
+  sim_in.ldpc_code_rate   = 1;
+  sim_in.ldpc_code        = 0;
+
+  sim_in.Ntrials          = 400;
+  sim_in.Esvec            = 12; 
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 0;
+  sim_in.modulation       = 'qpsk';
+  sim_in.coh_en           = 1;
+  sim_in.f_off            = 0;
+
+  sim_in.div_timeshift    = 1;
+
+  %sim_in.modulation      = 'dqpsk';
+
+  sim_qpsk_hf             = ber_test(sim_in);
+
+  %fep=fopen("errors_450.bin","wb"); fwrite(fep, sim_qpsk_hf.ldpc_errors_log, "short"); fclose(fep);
+endfunction
+
+
+% Rate Fs test funcs -----------------------------------------------------------
+
+function rate_Fs_tx(tx_filename)
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.framesize        = 160;
+  sim_in.Nc               = 4;
+  sim_in.Rs               = 50;
+  sim_in.Ns               = 4;
+  sim_in.Np               = 2;
+  sim_in.Nchip            = 1;
+  sim_in.ldpc_code_rate   = 1;
+  sim_in.ldpc_code        = 0;
+
+  sim_in.Ntrials          = 20;
+  sim_in.Esvec            = 7; 
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 0;
+  sim_in.modulation       = 'qpsk';
+
+  sim_in = symbol_rate_init(sim_in);
+
+  prev_sym_tx             = sim_in.prev_sym_tx;
+  code_param              = sim_in.code_param;
+  tx_bits_buf             = sim_in.tx_bits_buf;
+  framesize               = sim_in.framesize;
+  rate                    = sim_in.ldpc_code_rate;
+  Ntrials                 = sim_in.Ntrials;
+  Rs                      = sim_in.Rs;
+  Fs                      = sim_in.Fs;
+  Nc                      = sim_in.Nc;
+
+  M = Fs/Rs;
+
+  EsNodB = sim_in.Esvec(1);
+  EsNo = 10^(EsNodB/10);
+  rx_symb_log = []; av_tx_pwr = [];
+
+  rn_coeff = gen_rn_coeffs(0.5, 1/Fs, Rs, 6, M);
+  tx_symb_buf = [];
+
+  tx_bits = round(rand(1,framesize*rate));                       
+
+  for nn=1:Ntrials+2
+
+    [tx_symb tx_bits_out prev_sym_tx] = symbol_rate_tx(sim_in, tx_bits, code_param, prev_sym_tx);
+    tx_bits_buf(1:framesize) = tx_bits_buf(framesize+1:2*framesize);
+    tx_bits_buf(framesize+1:2*framesize) = tx_bits_out;
+    tx_symb_buf = [tx_symb_buf; tx_symb];
+  end
+  % zero pad and tx filter
+
+  [m n] = size(tx_symb_buf);
+  zp = [];
+  for i=1:m
+    zrow = M*tx_symb_buf(i,:);
+    zp = [zp; zrow; zeros(M-1,Nc)];
+  end
+
+  for c=1:Nc
+    tx_filt(:,c) = filter(rn_coeff, 1, zp(:,c));
+  end
+
+  % upconvert to real IF and save to disk
+
+  [m n] = size(tx_filt);
+  tx_fdm = zeros(1,m);
+  Fc = 1500;
+  for c=1:Nc
+    freq(c) = exp(j*2*pi*(Fc - c*Rs*1.5)/Fs);
+  end
+  phase_tx = ones(1,Nc);
+  %phase_tx = exp(j*2*pi*(0:Nc)/(Nc+1));
+
+  for c=1:Nc
+    for i=1:m
+      phase_tx(c) = phase_tx(c) * freq(c);
+      tx_fdm(i) = tx_fdm(i) + tx_filt(i,c)*phase_tx(c);
+    end
+  end
+
+  tx_fdm = real(tx_fdm);
+
+  %tx_fdm = compress(tx_fdm, 0.4);
+  %tx_fdm = sign(tx_fdm) .* (abs(tx_fdm) .^ 0.4); 
+  %hpa_clip = max(abs(tx_fdm))*0.8
+  %tx_fdm(find(abs(tx_fdm) > hpa_clip)) = hpa_clip;
+
+  papr = max(tx_fdm.*conj(tx_fdm)) / mean(tx_fdm.*conj(tx_fdm));
+  papr_dB = 10*log10(papr);
+  printf("PAPR: %4.2f dB\n", papr_dB);
+
+  Ascale = 2000;
+  figure(1);
+  clf;
+  plot(Ascale*tx_fdm(1:8000))
+
+  ftx=fopen(tx_filename,"wb"); fwrite(ftx, Ascale*real(tx_fdm), "short"); fclose(ftx);
+
+endfunction
+
+
+function rate_Fs_rx(rx_filename)
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.framesize        = 160;
+  sim_in.Nc               = 4;
+  sim_in.Rs               = 50;
+  sim_in.Ns               = 4;
+  sim_in.Np               = 4;
+  sim_in.Nchip            = 1;
+  sim_in.ldpc_code_rate   = 1;
+  sim_in.ldpc_code        = 0;
+
+  sim_in.Ntrials          = 10;
+  sim_in.Esvec            = 40; 
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 0;
+  sim_in.modulation       = 'qpsk';
+
+  sim_in = symbol_rate_init(sim_in);
+
+  prev_sym_tx             = sim_in.prev_sym_tx;
+  prev_sym_rx             = sim_in.prev_sym_rx;
+  code_param              = sim_in.code_param;
+  tx_bits_buf             = sim_in.tx_bits_buf;
+  framesize               = sim_in.framesize;
+  rate                    = sim_in.ldpc_code_rate;
+  Ntrials                 = sim_in.Ntrials;
+  Rs                      = sim_in.Rs;
+  Fs                      = sim_in.Fs;
+  Nc                      = sim_in.Nc;
+  Nsymbrowpilot           = sim_in.Nsymbrowpilot;
+  pilot                   = sim_in.pilot;
+  Ns                      = sim_in.Ns;
+  Npilotsframe            = sim_in.Npilotsframe;
+
+  M = Fs/Rs;
+
+  EsNodB = sim_in.Esvec(1);
+  EsNo = 10^(EsNodB/10);
+  phi_log = []; amp_log = []; EsNo__log = [];
+  rx_symb_log = []; av_tx_pwr = [];
+  Terrs = Tbits = 0;
+  errors_log = []; Nerrs_log = []; 
+  ldpc_Nerrs_log = []; ldpc_errors_log = [];
+  Ferrsldpc = Terrsldpc = Tbitsldpc = 0;
+
+  rn_coeff = gen_rn_coeffs(0.5, 1/Fs, Rs, 6, M);
+
+  tx_bits = round(rand(1,framesize*rate));                       
+
+  % read from disk
+
+  Ascale = 2000;
+  frx=fopen(rx_filename,"rb"); rx_fdm = fread(frx, "short")/Ascale; fclose(frx);
+
+  rx_fdm=sqrt(2)*rx_fdm;
+
+  if 0 
+    % optionally add AWGN noise for testing calibration of Es//No measurement
+
+    snr_3000Hz_dB = -9;
+    snr_4000Hz_lin = 10 ^ (snr_3000Hz_dB/10);
+    snr_4000Hz_lin *= (3000/4000);
+    variance = var(rx_fdm)/snr_4000Hz_lin;
+    rx_fdm += sqrt(variance)*randn(length(rx_fdm),1);
+  end
+
+  figure(1)
+  plot(rx_fdm(800:1200));
+
+  % freq offset estimation
+
+  printf("Freq offset and coarse timing est...\n");
+  [f_max max_s_Fs] = test_freq_off_est(rx_filename, 1,5*6400);
+  f_max = 0; max_s_Fs = 4;
+  max_s = floor(max_s_Fs/M + 6);
+
+  printf("Downconverting...\n");
+
+  [m n] = size(rx_fdm);
+  rx_symb = zeros(m,Nc);
+  Fc = 1500;
+  for c=1:Nc
+    freq(c) = exp(-j*2*pi*(f_max + Fc - c*Rs*1.5)/Fs);
+  end
+  phase_rx = ones(1,Nc);
+  rx_bb = zeros(m,Nc);
+
+  for c=1:Nc
+    for i=1:m
+      phase_rx(c) = phase_rx(c) * freq(c);
+      rx_bb(i,c) = rx_fdm(i)*phase_rx(c);
+    end
+  end
+
+  printf("Filtering...\n");
+  for c=1:Nc
+    rx_filt(:,c) = filter(rn_coeff, 1, rx_bb(:,c));
+  end
+
+  %subplot(211);
+  %plot(real(rx_filt(1:10*M,9)));
+  %subplot(212);
+  %plot(imag(rx_filt(1:10*M,9)));
+
+  % Fine timing estimation and decimation to symbol rate Rs. Break rx
+  % signal into ft sample blocks.  If clock offset is 1000ppm,
+  % that's one more/less sample over Ft samples at Fs=8000 Hz.
+
+  printf("Fine timing estimation....\n");
+  ft = M*10;
+  [nsam m] = size(rx_filt);
+  rx_symb_buf = []; rx_timing_log = [];
+  
+  for st=1:ft:floor(nsam/ft - 1)*ft
+    % fine timing and decimation
+
+    env = zeros(ft,1);
+    for c=1:Nc
+      env = env + abs(rx_filt(st:st+ft-1,c));
+    end
+
+    % The envelope has a frequency component at the symbol rate.  The
+    % phase of this frequency component indicates the timing.  So work out
+    % single DFT at frequency 2*pi/M
+
+    x = exp(-j*2*pi*(0:ft-1)/M) * env;
+  
+    norm_rx_timing = angle(x)/(2*pi);
+    %norm_rx_timing = -0.4;
+    if norm_rx_timing < 0
+      rx_timing = -floor(norm_rx_timing*M+0.5) + M;
+    else
+      rx_timing = -floor(norm_rx_timing*M+0.5) + 2*M;
+    end
+    rx_timing_log = [rx_timing_log norm_rx_timing];
+
+    % printf("%d %d\n", st+rx_timing, st+rx_timing+ft-1);
+    rx_symb_buf = [rx_symb_buf; rx_filt(st+rx_timing:M:st+rx_timing+ft-1,:)];
+  end
+  
+  figure(2)
+  clf;
+  plot(rx_timing_log)
+  axis([1 length(rx_timing_log) -0.5 0.5 ])
+  title('fine timing')
+    
+  printf("Symbol rate demodulation....\n");
+  phase_off = 1;
+  Ntrials = floor((nsam/M)/Nsymbrowpilot) - 2;
+  %max_s = 6;
+
+  for nn=1:Ntrials
+
+    s_ch = rx_symb_buf((nn-1)*Nsymbrowpilot+max_s:nn*Nsymbrowpilot+max_s-1,:);
+    [rx_symb rx_bits rx_symb_linear amp_linear amp_ phi_ EsNo_ prev_sym_rx sim_in] = symbol_rate_rx(sim_in, s_ch, prev_sym_rx);
+        
+    rx_symb_log = [rx_symb_log rx_symb_linear];
+    phi_log = [phi_log; phi_];
+    amp_log = [amp_log; amp_];
+
+    if nn > 1
+      EsNo__log = [EsNo__log EsNo_];
+
+      % Measure BER
+
+      error_positions = xor(rx_bits(1:framesize*rate), tx_bits(1:framesize*rate));
+      Nerrs = sum(error_positions);
+      Terrs += Nerrs;
+      Tbits += framesize*rate;
+      errors_log = [errors_log error_positions];
+      Nerrs_log = [Nerrs_log Nerrs];
+
+      if sim_in.ldpc_code
+        % LDPC decode
+            
+        detected_data = ldpc_dec(code_param, sim_in.max_iterations, sim_in.demod_type, sim_in.decoder_type, ...
+                                 rx_symb_linear, min(100,EsNo_), amp_linear);
+        error_positions = xor(detected_data(1:framesize*rate), tx_bits(1:framesize*rate) );
+        Nerrs = sum(error_positions);
+        ldpc_Nerrs_log = [ldpc_Nerrs_log Nerrs];
+        ldpc_errors_log = [ldpc_errors_log error_positions];
+        if Nerrs
+          Ferrsldpc++;
+        end
+        Terrsldpc += Nerrs;
+        Tbitsldpc += framesize*rate;
+      end
+    end
+  end
+
+  EsNo_av = mean(10*log10(EsNo__log));
+  printf("EsNo est (dB): %3.1f SNR est: %3.2f Terrs: %d BER %4.2f QPSK BER theory %4.2f av_tx_pwr: %3.2f", 
+         EsNo_av, mean(EsNo_to_SNR(10*log10(EsNo__log))),
+         Terrs,
+         Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
+  if sim_in.ldpc_code
+    printf("\n LDPC: Terrs: %d BER: %4.2f Ferrs: %d FER: %4.2f\n", 
+           Terrsldpc, Terrsldpc/Tbitsldpc, Ferrsldpc, Ferrsldpc/Ntrials);
+  end
+
+  figure(3);
+  clf;
+  scat = rx_symb_log .* exp(j*pi/4);
+  scat = scat((framesize):length(scat));
+  plot(real(scat), imag(scat),'+');
+  title('Scatter plot');
+        
+  figure(4)
+  clf
+  subplot(211)
+  stem(Nerrs_log)
+  axis([0 Ntrials+1 0 max(Nerrs_log)+1])
+  title('Uncoded Errors/Frame');
+  if sim_in.ldpc_code
+    subplot(212)
+    stem(ldpc_Nerrs_log)
+    axis([0 Ntrials+1 0 max(ldpc_Nerrs_log)+1])
+    title('Coded Errors/Frame');
+  end
+
+  figure(5)
+  clf
+  [m1 n1] = size(phi_log);
+  phi_x = [];
+  phi_x_counter = 1;
+  p = Ns;
+  for r=1:m1
+    if p == Ns
+      phi_x_counter++;
+      p = 0;
+    end
+    p++;
+    phi_x = [phi_x phi_x_counter++];        
+  end
+          
+  subplot(211)
+  plot(phi_x, phi_log(:,1),'r+;Estimated HF channel phase;')
+  ylabel('Phase (rads)');
+  legend('boxoff');
+
+  subplot(212)
+  plot(phi_x, amp_log(:,1),'r+;Estimated HF channel amp;')
+  ylabel('Amplitude');
+  xlabel('Time (symbols)');
+  legend('boxoff');
+
+  figure(6);
+  clf
+  plot(EsNo_to_SNR(10*log10(EsNo__log)));
+  title('SNR est (dB)')
+
+  fep=fopen("errors_450.bin","wb"); fwrite(fep, ldpc_errors_log, "short"); fclose(fep);
+
+endfunction
+
+
+
+
+function snr = EsNo_to_SNR(EsNo)
+  snr = interp1([20 11.8 9.0 6.7 4.9 3.3 -10], [ 3 3 0 -3 -6 -9 -9], EsNo);
+endfunction
+
+
+function gen_test_bits()
+  sim_in = standard_init();
+  framesize = 32*10;
+  tx_bits = round(rand(1,framesize));
+  test_bits_coh_file(tx_bits);
+endfunction
+
+
+
+
+% Start simulations ---------------------------------------
+
+more off;
+%close all;
+%test_curves();
+test_single();
+%rate_Fs_tx("tx_zero.raw");
+%rate_Fs_tx("tx.raw");
+%rate_Fs_rx("tx_-4dB.wav")
+%rate_Fs_rx("tx.raw")
+%gen_test_bits();
+
diff --git a/codec2/branches/0.7/octave/test_cohpsk_ch.m b/codec2/branches/0.7/octave/test_cohpsk_ch.m
new file mode 100644 (file)
index 0000000..19634dd
--- /dev/null
@@ -0,0 +1,21 @@
+% test_cohpsk_ch.m
+% David Rowe May 2015
+%
+% Plot outputs from test_coh_psk_ch.c
+
+Nc=7; Nd=2;
+
+load ../build_linux/src/test_cohpsk_ch_out.txt
+  
+figure(3)
+clf;
+
+% plot combined signals to show diversity gains
+
+combined = rx_symb_log_c(:,1:Nc);
+for d=2:Nd
+  combined += rx_symb_log_c(:, (d-1)*Nc+1:d*Nc);
+end
+plot(combined*exp(j*pi/4)/sqrt(Nd),'+')
+title('Scatter');
+axis([-2 2 -2 2])
diff --git a/codec2/branches/0.7/octave/test_dqpsk.m b/codec2/branches/0.7/octave/test_dqpsk.m
new file mode 100644 (file)
index 0000000..9db9d12
--- /dev/null
@@ -0,0 +1,394 @@
+% test_dqpsk.m
+% David Rowe March 2014
+%
+% Single sample/symbol DQPSK modem simulation to test modulating modem
+% tx power based on speech energy.
+
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_phase_only    = sim_in.hf_phase_only;
+    hf_mag_only      = sim_in.hf_mag_only;
+    Nc               = sim_in.Nc;
+    symbol_amp       = sim_in.symbol_amp;
+
+    bps              = 2;
+    Nsymb            = framesize/bps;
+    for k=1:Nc
+      prev_sym_tx(k) = qpsk_mod([0 0]);
+      prev_sym_rx(k) = qpsk_mod([0 0]);
+    end
+
+    rate = 1;
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        tx_symb_log        = [];
+        rx_symb_log        = [];
+        noise_log          = [];
+        sim_out.errors_log = [];
+
+        % init HF channel
+
+        hf_n = 1;
+        hf_angle_log = [];
+        hf_fading = ones(1,Nsymb);             % default input for ldpc dec
+        hf_model = ones(Ntrials*Nsymb/Nc, Nc); % defaults for plotting surface
+
+        sim_out.errors_log = [];
+        sim_out.Nerrs = [];
+        sim_out.snr_log = [];
+        sim_out.hf_model_pwr = [];
+
+        symbol_amp_index = 1;
+
+        for nn = 1: Ntrials
+                  
+            tx_bits = round( rand( 1, framesize*rate ) );
+            % modulate --------------------------------------------
+
+            s = zeros(1, Nsymb);
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                tx_symb = qpsk_mod(tx_bits(2*(i-1+k-1)+1:2*(i+k-1)));
+                tx_symb *= prev_sym_tx(k);
+                prev_sym_tx(k) = tx_symb;
+                s(i+k-1) = symbol_amp(symbol_amp_index)*tx_symb;
+              end
+            end
+            s_ch = s;
+            symbol_amp_index++;
+
+            % HF channel simulation  ------------------------------------
+            
+            if hf_sim
+
+                % separation between carriers.  Note this is
+                % effectively under samples at Rs, I dont think this
+                % matters.  Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                if Nsymb/Nc != floor(Nsymb/Nc)
+                    printf("Error: Nsymb/Nc must be an integrer\n")
+                    return;
+                end
+
+                % arrange symbols in Nsymb/Nc by Nc matrix
+
+                for i=1:Nc:Nsymb
+
+                    % Determine HF channel at each carrier for this symbol
+
+                    for k=1:Nc
+                        hf_model(hf_n, k) = hf_gain*(spread(hf_n) + exp(-j*k*wsep*nhfdelay)*spread_2ms(hf_n));
+                        hf_fading(i+k-1) = abs(hf_model(hf_n, k));
+                        if hf_mag_only
+                             s_ch(i+k-1) *= abs(hf_model(hf_n, k));
+                        else
+                             s_ch(i+k-1) *= hf_model(hf_n, k);
+                        end
+                    end
+                    hf_n++;
+                end
+            end
+            
+            tx_symb_log = [tx_symb_log s_ch];
+
+            % "genie" SNR estimate 
+            
+            snr = (s_ch*s_ch')/(Nsymb*variance);
+            sim_out.snr_log = [sim_out.snr_log snr];
+            sim_out.hf_model_pwr = [sim_out.hf_model_pwr mean(hf_fading.^2)];
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb) + j*randn(1,Nsymb));
+            noise_log = [noise_log noise];
+            % organise into carriers to apply frequency and phase offset
+
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                 s_ch(i+k-1) = s_ch(i+k-1)*exp(j*phase_offset) + noise(i+k-1);
+              end 
+              phase_offset += w_offset;
+            end
+               
+            % de-modulate
+
+            rx_bits = zeros(1, framesize);
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                rx_symb = s_ch(i+k-1);
+                tmp = rx_symb;
+                rx_symb *= conj(prev_sym_rx(k)/abs(prev_sym_rx(k)));
+                prev_sym_rx(k) = tmp;
+                rx_bits((2*(i-1+k-1)+1):(2*(i+k-1))) = qpsk_demod(rx_symb);
+                rx_symb_log = [rx_symb_log rx_symb];
+              end
+            end
+
+            error_positions = xor(rx_bits, tx_bits);
+            Nerrs = sum(error_positions);
+            sim_out.Nerrs = [sim_out.Nerrs Nerrs];
+            Terrs += Nerrs;
+            Tbits += length(tx_bits);
+            
+            sim_out.errors_log = [sim_out.errors_log error_positions];
+        end
+
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+
+        if verbose 
+            printf("EsNo (dB): %f  Terrs: %d BER %f ", EsNodB, Terrs, Terrs/Tbits);
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, var(tx_symb_log), var(noise_log),
+                   var(tx_symb_log), var(noise_log), var(tx_symb_log)/var(noise_log));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+
+    sim_out.BERvec = BERvec;
+    sim_out.Ebvec  = Ebvec;
+    sim_out.TERvec = TERvec;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+
+        figure(3);
+        clf;        
+        y = 1:Rs*2;
+        x = 1:Nc;
+        EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+        mesh(x,y,EsNodBSurface);
+        grid
+        title('HF Channel Es/No');
+
+        if 0 
+        figure(4);
+        clf;
+        subplot(211)
+        plot(y,abs(hf_model(y,1)))
+        title('HF Channel Carrier 1 Mag');
+        subplot(212)
+        plot(y,angle(hf_model(y,1)))
+        title('HF Channel Carrier 1 Phase');
+        end
+    end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5:15; 
+  sim_in.Ntrials          = 100;
+  sim_in.framesize        = 64;
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_phase_only    = 0;
+  sim_in.hf_mag_only      = 0;
+endfunction
+
+function awgn_hf_ber_curves()
+  sim_in = standard_init();
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+
+  dpsk_awgn = ber_test(sim_in);
+  sim_in.hf_sim           = 1;
+  dpsk_hf   = ber_test(sim_in);
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(dpsk_awgn.Ebvec, dpsk_awgn.BERvec,'g;DQPSK;')
+  semilogy(dpsk_hf.Ebvec, dpsk_hf.BERvec,'g;DQPSK HF;')
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+end
+
+sim_in = standard_init();
+
+% energy file sampled every 10ms
+
+load ../src/ve9qrp.txt
+pdB=10*log10(ve9qrp);
+for i=1:length(pdB)
+  if pdB(i) < 0
+    pdB(i) = 0;
+  end
+end
+
+% Down sample to 40ms rate used for 1300 bit/s codec, every 4th sample is transmitted
+
+pdB = pdB(4:4:length(pdB));
+
+% Use linear mapping function in dB domain to map to symbol power
+
+power_map_x  = [ 0 20 24 40 50 ];
+power_map_y  = [-6 -6  0 6  6];
+mapped_pdB = interp1(power_map_x, power_map_y, pdB);
+
+%sim_in.symbol_amp = 10 .^ (mapped_pdB/20);
+sim_in.symbol_amp = ones(1,length(pdB));
+sim_in.plot_scatter = 1;
+sim_in.verbose      = 2;
+sim_in.hf_sim       = 1;
+sim_in.Esvec        = 10;
+sim_in.Ntrials      = 400;
+
+dqpsk_pwr_hf = ber_test(sim_in);
+
+% note: need way to test that power is aligned with speech
+
+figure(4)
+clf;
+plot((1:sim_in.Ntrials)*80*4, pdB(1:sim_in.Ntrials));
+hold on;
+plot((1:sim_in.Ntrials)*80*4, mapped_pdB(1:sim_in.Ntrials),'r');
+hold off;
+
+figure(5)
+clf;
+
+s = load_raw("../raw/ve9qrp.raw");
+M=320; M_on_2 = M/2; % processing delay between input speech and centre of analysis window
+plot(M_on_2:(M_on_2-1+sim_in.Ntrials*M),s(1:sim_in.Ntrials*M))
+hold on;
+plot((1:sim_in.Ntrials)*M, 5000*sim_in.symbol_amp(1:sim_in.Ntrials),'r');
+hold off;
+axis([1 sim_in.Ntrials*M -3E4 3E4]);
+
+figure(6)
+clf;
+plot((1:sim_in.Ntrials)*M, 20*log10(sim_in.symbol_amp(1:sim_in.Ntrials)),'b;Es (dB);');
+hold on;
+plot((1:sim_in.Ntrials)*M, 10*log10(dqpsk_pwr_hf.hf_model_pwr),'g;Fading (dB);');
+plot((1:sim_in.Ntrials)*M, 10*log10(dqpsk_pwr_hf.snr_log),'r;Es/No (dB);');
+
+ber = dqpsk_pwr_hf.Nerrs/sim_in.framesize;
+ber_clip = ber;
+ber_clip(find(ber > 0.2)) = 0.2;
+plot((1:sim_in.Ntrials)*M, -20+100*ber_clip,'k;BER (0-20%);');
+hold off;
+axis([1 sim_in.Ntrials*M -20 20])
+
+fep=fopen("dqpsk_errors_pwr.bin","wb"); fwrite(fep, dqpsk_pwr_hf.errors_log, "short"); fclose(fep);
+fber=fopen("ber.bin","wb"); fwrite(fber, ber, "float"); fclose(fber);
diff --git a/codec2/branches/0.7/octave/test_dqpsk2.m b/codec2/branches/0.7/octave/test_dqpsk2.m
new file mode 100644 (file)
index 0000000..d421d62
--- /dev/null
@@ -0,0 +1,465 @@
+% test_dqpsk2.m
+% David Rowe April 2014
+%
+% DQPSK modem simulation inclduing filtering to test modulating modem
+% tx power based on speech energy.  Unlike test_dpsk runs at sample
+% rate Fs.
+
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    Nhfdelay         = floor(sim_in.hf_delay_ms*Fs/1000);
+    Nc               = sim_in.Nc;
+    symbol_amp       = sim_in.symbol_amp;
+
+    bps              = 2;
+    Nsymb            = framesize/bps;
+    for k=1:Nc
+      prev_sym_tx(k) = qpsk_mod([0 0]);
+      prev_sym_rx(k) = qpsk_mod([0 0]);
+    end
+
+    % design root nyquist (root raised cosine) filter and init tx and rx filter states
+
+    alpha = 0.5; T=1/Fs; Nfiltsym=7; M=Fs/Rs;
+    if floor(Fs/Rs) != Fs/Rs
+        printf("oversampling ratio must be an integer\n");
+        return;
+    end
+    hrn = gen_rn_coeffs(alpha, T, Rs, Nfiltsym, M);
+    Nfilter = length(hrn);
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up.  Transpose for convenience
+
+    spread     = transpose(spread(1000:length(spread)));
+    spread_2ms = transpose(spread_2ms(1000:length(spread_2ms)));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+        
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = Fs/(Rs*EsNo);
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        tx_symb_log             = [];
+        rx_symb_log             = [];
+        noise_log               = [];
+        sim_out.errors_log      = [];
+        sim_out.tx_baseband_log = [];
+        sim_out.rx_filt_log     = [];
+        symbol_amp_index        = 1;
+       
+        % init filter memories and LOs
+
+        tx_filter_memory  = zeros(Nc, Nfilter);
+        rx_filter_memory  = zeros(Nc, Nfilter);
+        s_delay_line_filt = zeros(Nc, Nfiltsym);
+        phase_tx = ones(1,Nc);
+        phase_rx = ones(1,Nc);
+        Fcentre = 1500; Fsep = (1+alpha)*Rs;
+        freq = Fcentre + Fsep*((-Nc/2+0.5):(Nc/2-0.5));
+        freq = exp(j*freq*2*pi/Fs);
+
+        % init HF channel
+
+        sc = 1; hf_n = 1;
+        hf_sim_delay_line = zeros(1,M+Nhfdelay);
+        freq_sample_hz = Fcentre + ((Fsep*(-Nc/2)):50:(Fsep*(Nc/2)));
+        freq_sample_rads = (2*pi/Fs)*freq_sample_hz;
+        hf_model = ones(Ntrials*Nsymb/Nc, length(freq_sample_rads));   % defaults for plotting surface
+
+        % bunch of outputs we log for graphing
+
+        sim_out.errors_log = [];
+        sim_out.Nerrs = [];
+        sim_out.snr_log = [];
+        sim_out.hf_model_pwr = [];
+        sim_out.tx_fdm_log = [];
+        C_log = [];
+
+        for nn = 1: Ntrials
+                  
+            tx_bits = round( rand( 1, framesize ) );
+            % modulate --------------------------------------------
+
+            s = zeros(1, Nsymb);
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                tx_symb = qpsk_mod(tx_bits(2*(i-1+k-1)+1:2*(i+k-1)));
+                s_qpsk(i+k-1) = tx_symb;
+                tx_symb *= prev_sym_tx(k);
+                prev_sym_tx(k) = tx_symb;
+                s(i+k-1) = symbol_amp(symbol_amp_index)*tx_symb;
+              end
+            end
+            symbol_amp_index++;
+            s_ch = s;
+
+            % Now we start processing frame Nc symbols at a time to model parallel carriers
+
+            tx_fdm_sym_log = [];
+            for i=1:Nc:Nsymb
+
+                % Delay tx symbols to match delay due to filters. qpsk
+                % (rather than dqpsk) symbols used for convenience as
+                % it's easy to shift symbols than pairs of bits
+
+                s_delay_line_filt(:,1:Nfiltsym-1) = s_delay_line_filt(:,2:Nfiltsym);
+                s_delay_line_filt(:,Nfiltsym) = s_qpsk(i:i+Nc-1);
+                s_qpsk(i:i+Nc-1) = s_delay_line_filt(:,1);  
+                for k=1:Nc
+                    tx_bits(2*(i-1+k-1)+1:2*(i+k-1)) = qpsk_demod(s_qpsk(i+k-1));
+                end
+
+                % tx filter
+
+                tx_baseband = zeros(Nc,M);
+
+                % tx filter each symbol, generate M filtered output samples for each symbol.
+                % Efficient polyphase filter techniques used as tx_filter_memory is sparse
+
+                tx_filter_memory(:,Nfilter) = s(i:i+Nc-1);
+
+                for k=1:M
+                    tx_baseband(:,k) = M*tx_filter_memory(:,M:M:Nfilter) * hrn(M-k+1:M:Nfilter)';
+                end
+                tx_filter_memory(:,1:Nfilter-M) = tx_filter_memory(:,M+1:Nfilter);
+                tx_filter_memory(:,Nfilter-M+1:Nfilter) = zeros(Nc,M);
+
+                sim_out.tx_baseband_log = [sim_out.tx_baseband_log  tx_baseband];
+
+                % upconvert
+                tx_fdm = zeros(1,M);
+
+                for c=1:Nc
+                    for k=1:M
+                        phase_tx(c) = phase_tx(c) * freq(c);
+                       tx_fdm(k) = tx_fdm(k) + tx_baseband(c,k)*phase_tx(c);
+                    end
+                end
+                sim_out.tx_fdm_log = [sim_out.tx_fdm_log tx_fdm];
+                % HF channel
+                
+                if hf_sim
+                   hf_sim_delay_line(1:Nhfdelay) = hf_sim_delay_line(M+1:M+Nhfdelay);
+                   hf_sim_delay_line(Nhfdelay+1:M+Nhfdelay) = tx_fdm;
+
+                   tx_fdm = tx_fdm.*spread(sc:sc+M-1) + hf_sim_delay_line(1:M).*spread_2ms(sc:sc+M-1);
+                   tx_fdm *= hf_gain;
+
+                   % sample HF channel spectrum in middle of this symbol for plotting
+
+                   hf_model(hf_n,:) = hf_gain*(spread(sc+M/2) + exp(-j*freq_sample_rads*Nhfdelay)*spread_2ms(sc+M/2));
+
+                   sc += M;
+                   hf_n++;
+                end
+
+                tx_fdm_sym_log = [tx_fdm_sym_log tx_fdm ];
+
+                % AWGN noise and phase/freq offset channel simulation
+                % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+                noise = sqrt(variance*0.5)*(randn(1,M) + j*randn(1,M));
+                noise_log = [noise_log noise];
+
+                % apply frequency and phase offset and noise
+
+                for k=1:M
+                    rx_fdm(k) = tx_fdm(k)*exp(j*phase_offset) + noise(k);
+                    phase_offset += w_offset;
+                end
+
+                % downconvert
+
+                rx_baseband = zeros(Nc,M);
+                for c=1:Nc
+                    for k=1:M
+                        phase_rx(c) = phase_rx(c) * freq(c);
+                       rx_baseband(c,k) = rx_fdm(k)*phase_rx(c)';
+                    end
+                end
+
+                % rx filter
+
+                rx_filter_memory(:,Nfilter-M+1:Nfilter) = rx_baseband;
+                rx_filt = rx_filter_memory * hrn';
+                rx_filter_memory(:,1:Nfilter-M) = rx_filter_memory(:,1+M:Nfilter);
+                sim_out.rx_filt_log = [sim_out.rx_filt_log rx_filt];
+
+                s_ch(i:i+Nc-1) = rx_filt;
+            end
+
+            % est HF model power for entire code frame (which could be several symbols)
+
+            if hf_sim
+              frame_hf_model = reshape(hf_model(hf_n-Nsymb/Nc:hf_n-1,:),1,(Nsymb/Nc)*length(freq_sample_hz));                       
+              sim_out.hf_model_pwr = [sim_out.hf_model_pwr mean(abs(frame_hf_model).^2)];
+            else 
+              sim_out.hf_model_pwr = [sim_out.hf_model_pwr 1];
+            end
+
+            % "genie" SNR estimate 
+            
+            snr = (tx_fdm_sym_log*tx_fdm_sym_log')/(M*variance);
+            sim_out.snr_log = [sim_out.snr_log snr];
+  
+            % de-modulate
+
+            rx_bits = zeros(1, framesize);
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                rx_symb = s_ch(i+k-1);
+                tmp = rx_symb;
+                rx_symb *= conj(prev_sym_rx(k)/abs(prev_sym_rx(k)));
+                prev_sym_rx(k) = tmp;
+                rx_bits((2*(i-1+k-1)+1):(2*(i+k-1))) = qpsk_demod(rx_symb);
+                rx_symb_log = [rx_symb_log rx_symb];
+              end
+            end
+
+            % ignore data until we have enough frames to fill filter memory
+            % then count errors
+
+            if nn > ceil(Nfiltsym/(Nsymb/Nc))
+                error_positions = xor(rx_bits, tx_bits);
+                sim_out.errors_log = [sim_out.errors_log error_positions];
+                Nerrs = sum(error_positions);
+                sim_out.Nerrs = [sim_out.Nerrs Nerrs];
+                Terrs += Nerrs;
+                Tbits += length(tx_bits);
+            end
+
+        end
+
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+
+        if verbose 
+            printf("EsNo (dB): %f  Terrs: %d BER %f ", EsNodB, Terrs, Terrs/Tbits);
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, var(sim_out.tx_fdm_log), var(noise_log),
+                   var(sim_out.tx_fdm_log)/(Nc*Rs), var(noise_log)/Fs, (var(sim_out.tx_fdm_log)/(Nc*Rs))/(var(noise_log)/Fs));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+
+    sim_out.BERvec = BERvec;
+    sim_out.Ebvec  = Ebvec;
+    sim_out.TERvec = TERvec;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log(Nfiltsym*Nc:length(rx_symb_log)) .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+
+        figure(3);
+        clf;        
+        y = 1:Rs*2;
+        EsNodBSurface = 20*log10(abs(hf_model(y,:))) + EsNodB;
+        mesh(1:length(freq_sample_hz),y,EsNodBSurface);
+        grid
+        title('HF Channel Es/No');
+    end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5:15; 
+  sim_in.Ntrials          = 100;
+  sim_in.framesize        = 64;
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_phase_only    = 0;
+  sim_in.hf_mag_only      = 0;
+endfunction
+
+function awgn_hf_ber_curves()
+  sim_in = standard_init();
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+
+  dpsk_awgn = ber_test(sim_in);
+  sim_in.hf_sim           = 1;
+  dpsk_hf   = ber_test(sim_in);
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(dpsk_awgn.Ebvec, dpsk_awgn.BERvec,'g;DQPSK;')
+  semilogy(dpsk_hf.Ebvec, dpsk_hf.BERvec,'g;DQPSK HF;')
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+end
+
+sim_in = standard_init();
+
+% energy file sampled every 10ms
+
+load ../src/ve9qrp.txt
+pdB=10*log10(ve9qrp);
+for i=1:length(pdB)
+  if pdB(i) < 0
+    pdB(i) = 0;
+  end
+end
+
+% Down sample to 40ms rate used for 1300 bit/s codec, every 4th sample is transmitted
+
+pdB = pdB(4:4:length(pdB));
+
+% Use linear mapping function in dB domain to map to symbol power
+
+%power_map_x  = [ 0 20 24 40 50 ];
+%power_map_y  = [--6 -6  0  6  6];
+power_map_x  = [ 0 50 ];
+power_map_y  = [ -15 12];
+mapped_pdB = interp1(power_map_x, power_map_y, pdB);
+
+sim_in.symbol_amp = 10 .^ (mapped_pdB/20);
+%sim_in.symbol_amp = ones(1,length(pdB));
+sim_in.plot_scatter = 1;
+sim_in.verbose      = 2;
+sim_in.hf_delay_ms  = 2;
+sim_in.hf_sim       = 1;
+sim_in.Esvec        = 10;
+sim_in.Ntrials      = 400;
+
+dqpsk_pwr_hf = ber_test(sim_in);
+
+% note: need way to test that power is aligned with speech
+
+figure(4)
+clf;
+plot((1:sim_in.Ntrials)*80*4, pdB(1:sim_in.Ntrials));
+hold on;
+plot((1:sim_in.Ntrials)*80*4, mapped_pdB(1:sim_in.Ntrials),'r');
+hold off;
+
+figure(5)
+clf;
+s = load_raw("../raw/ve9qrp.raw");
+M=320; M_on_2 = M/2; % processing delay between input speech and centre of analysis window
+subplot(211)
+plot(M_on_2:(M_on_2-1+sim_in.Ntrials*M),s(1:sim_in.Ntrials*M))
+hold on;
+plot((1:sim_in.Ntrials)*M, 5000*sim_in.symbol_amp(1:sim_in.Ntrials),'r');
+hold off;
+axis([1 sim_in.Ntrials*M -3E4 3E4]);
+subplot(212)
+plot(real(dqpsk_pwr_hf.tx_fdm_log));
+
+
+figure(6)
+clf;
+plot((1:sim_in.Ntrials)*M, 20*log10(sim_in.symbol_amp(1:sim_in.Ntrials)),'b;Es (dB);');
+hold on;
+plot((1:sim_in.Ntrials)*M, 10*log10(dqpsk_pwr_hf.hf_model_pwr),'g;Fading (dB);');
+plot((1:sim_in.Ntrials)*M, 10*log10(dqpsk_pwr_hf.snr_log),'r;Es/No (dB);');
+
+ber = dqpsk_pwr_hf.Nerrs/sim_in.framesize;
+ber_clip = ber;
+ber_clip(find(ber > 0.2)) = 0.2;
+plot((1:length(ber_clip))*M, -20+100*ber_clip,'k;BER (0-20%);');
+hold off;
+axis([1 sim_in.Ntrials*M -20 20])
+
+fep=fopen("dqpsk_errors_pwr.bin","wb"); fwrite(fep, dqpsk_pwr_hf.errors_log, "short"); fclose(fep);
+fber=fopen("ber.bin","wb"); fwrite(fber, ber, "float"); fclose(fber);
diff --git a/codec2/branches/0.7/octave/test_dsss.m b/codec2/branches/0.7/octave/test_dsss.m
new file mode 100644 (file)
index 0000000..78ed90b
--- /dev/null
@@ -0,0 +1,410 @@
+% test_dsss.m
+% David Rowe Oct 2014
+%
+
+% Simulation to test FDM QPSK combined with DSSS.  A low rate Codec
+% (e.g. 450 bit/s) is transmitted on Nc=4 FDM carriers.  This same
+% information is repeated Nchip=4 times on bocks of carriers that are
+% delayed by up to Rs symbols.  It's like spread spectrum with a
+% spreading code of 1111.  Turns out this goes a long way to
+% converting a fading channel into an AWGN one.  Good scatter diagram
+% and BER curve results.  Disadvantage is more bandwidth is required.
+
+% When output error files used to simulate codec provided a few dB
+% drop to 1dB SNR for intelligable speech for 450 codec combined with
+% DSSS compared with legacy 1600 bit/s mode that has FEC.  Improvement
+% not as great as hoped as 1600 codec can cope with higher BER.
+  
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_mag_only      = sim_in.hf_mag_only;
+    Nchip            = sim_in.Nchip;
+
+    bps              = 2;
+    Nc = Nsymb       = framesize/bps;
+    prev_sym_tx      = qpsk_mod([0 0])*ones(1,Nc*Nchip);
+    prev_sym_rx      = qpsk_mod([0 0])*ones(1,Nc*Nchip);
+
+    tx_bits_buf = zeros(1,2*framesize);
+    rx_bits_buf = zeros(1,2*framesize);
+    rx_symb_buf = zeros(1,2*Nsymb);
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+   
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        tx_symb_log      = [];
+        rx_symb_log      = [];
+        noise_log        = [];
+        errors_log       = [];
+        Nerrs_log        = [];
+
+        % init HF channel
+
+        hf_n = 1;
+
+        % simulation starts here-----------------------------------
+        for nn = 1: Ntrials
+                  
+            tx_bits = round( rand( 1, framesize) );                       
+
+            % modulate --------------------------------------------
+
+            tx_symb=zeros(1,Nc*Nchip);
+
+            for i=1:Nc
+                tx_symb(i) = qpsk_mod(tx_bits(2*(i-1)+1:2*i));
+            end
+
+            % Optionally copy to other carriers (spreading)
+
+            for i=Nc+1:Nc:Nc*Nchip
+                tx_symb(i:i+Nc-1) = tx_symb(1:Nc);
+            end
+            % Optionally DQPSK encode
+            if strcmp(modulation,'dqpsk')
+              for i=1:Nc*Nchip
+                tx_symb(i) *= prev_sym_tx(i);
+                prev_sym_tx(i) = tx_symb(i);
+              end 
+            end
+
+            s_ch = tx_symb/sqrt(Nchip);
+
+            % HF channel simulation  ------------------------------------
+            
+            if hf_sim
+
+                % separation between carriers.  Note this effectively
+                % under samples at Rs, I dont think this matters.
+                % Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                hf_model(hf_n, :) = zeros(1,Nc);
+
+                for i=1:Nchip
+                    time_shift = floor(i*Rs/4);
+                    for k=1:Nc
+                        ahf_model = hf_gain*(spread(hf_n+time_shift) + exp(-j*k*wsep*nhfdelay)*spread_2ms(hf_n+time_shift));
+                        if hf_mag_only
+                             s_ch((i-1)*Nc+k) *= abs(ahf_model);
+                        else
+                             s_ch((i-1)*Nc+k) *= ahf_model;
+                        end
+                        hf_model(hf_n, k) += ahf_model/Nchip;
+                    end
+                end
+                hf_n++;
+            end
+           
+            tx_symb_log = [tx_symb_log s_ch];
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb*Nchip) + j*randn(1,Nsymb*Nchip));
+            noise_log = [noise_log noise];
+
+            s_ch = s_ch + noise;
+
+            % de-modulate
+
+            for i=1:Nc*Nchip
+                rx_symb(i) = s_ch(i);
+                if strcmp(modulation,'dqpsk')
+                    tmp = rx_symb(i);
+                    rx_symb(i) *= conj(prev_sym_rx(i)/abs(prev_sym_rx(i)));
+                    prev_sym_rx(i) = tmp;
+                end
+            end
+
+            % de-spread
+
+            for i=Nc+1:Nc:Nchip*Nc
+              rx_symb(1:Nc) = rx_symb(1:Nc) + rx_symb(i:i+Nc-1);
+            end
+
+            % demodulate
+
+            rx_bits = zeros(1, framesize);
+            for i=1:Nc
+              rx_bits((2*(i-1)+1):(2*i)) = qpsk_demod(rx_symb(i));
+            end
+            rx_symb_log = [rx_symb_log rx_symb(1:Nc)];
+
+            % Measure BER
+
+            error_positions = xor(rx_bits, tx_bits);
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += length(tx_bits);
+            errors_log = [errors_log error_positions];
+            Nerrs_log = [Nerrs_log Nerrs];
+        end
+    
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+
+        if verbose 
+            av_tx_pwr = (tx_symb_log * tx_symb_log')/length(tx_symb_log);
+
+            printf("EsNo (dB): %f  Terrs: %d BER %4.2f QPSK BER theory %4.2f av_tx_pwr: %3.2f", EsNodB, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f BER theory %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), var(tx_symb_log), var(noise_log),
+                   var(tx_symb_log), var(noise_log), var(tx_symb_log)/var(noise_log));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    sim_out.errors_log      = errors_log;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+
+        if hf_sim
+          figure(3);
+          clf;
+        
+          y = 1:(hf_n-1);
+          x = 1:Nc;
+          EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+          EsNodBSurface(find(EsNodBSurface < -5)) = -5;
+          mesh(x,y,EsNodBSurface);
+          grid
+          axis([1 Nc 1 Rs*5 -5 15])
+          title('HF Channel Es/No');
+
+          if verbose 
+            av_hf_pwr = sum(abs(hf_model(y)).^2)/(hf_n-1);
+            printf("average HF power: %3.2f over %d symbols\n", av_hf_pwr, hf_n-1);
+          end
+        end
+
+        figure(4)
+        clf
+        stem(Nerrs_log)
+   end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+  sim_in.framesize        = 8;
+  sim_in.Rs               = 50;
+  sim_in.Nc               = 4;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 0;
+
+  sim_in.Nchip            = 1;
+endfunction
+
+function test_curves
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 50; 
+  sim_in.hf_sim           = 0;
+  sim_in.Ntrials          = 1000;
+
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 5:15; 
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+  sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 1;
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+  sim_dqpsk_hf            = ber_test(sim_in, 'dqpsk');
+  sim_in.Nchip            = 4;
+  sim_dqpsk_hf_dsss       = ber_test(sim_in, 'dqpsk');
+  sim_in.hf_mag_only      = 1;
+  sim_qpsk_hf_dsss        = ber_test(sim_in, 'qpsk');
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'c;DQPSK AWGN;')
+  semilogy(sim_qpsk_hf.Ebvec, sim_qpsk_hf.BERvec,'b;QPSK HF;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'k;DQPSK HF;')
+  semilogy(sim_dqpsk_hf_dsss.Ebvec, sim_dqpsk_hf_dsss.BERvec,'g;DQPSK DSSS HF;')
+  semilogy(sim_qpsk_hf_dsss.Ebvec, sim_qpsk_hf_dsss.BERvec,'r;QPSK DSSS HF;')
+  hold off;
+
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+endfunction
+
+function test_single
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 10; 
+  sim_in.hf_sim           = 1;
+  sim_in.Nchip            = 4;
+  sim_in.Ntrials          = 500;
+  
+  sim_qpsk_hf             = ber_test(sim_in, 'dqpsk');
+endfunction
+
+function test_1600_v_450
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+  sim_in.Ntrials          = 500;
+  sim_in.hf_sim           = 1;
+
+  sim_in.framesize        = 32;
+  sim_in.Nc               = 16;
+  sim_in.Esvec            = 7; 
+  sim_in.Nchip            = 1;
+  
+  sim_dqpsk_hf_1600        = ber_test(sim_in, 'dqpsk');
+
+  sim_in.framesize        = 8;
+  sim_in.Nc               = 4;
+  sim_in.Esvec            = sim_in.Esvec + 10*log10(1600/450); 
+  sim_in.Nchip            = 4;
+  
+  sim_dqpsk_hf_450         = ber_test(sim_in, 'dqpsk');
+  
+  fep=fopen("errors_1600.bin","wb"); fwrite(fep, sim_dqpsk_hf_1600.errors_log, "short"); fclose(fep);
+  fep=fopen("errors_450.bin","wb"); fwrite(fep, sim_dqpsk_hf_450.errors_log, "short"); fclose(fep);
+
+endfunction
+
+
+% Start simulations ---------------------------------------
+
+more off;
+
+%test_1600_v_450();
+test_curves();
diff --git a/codec2/branches/0.7/octave/test_dsss_pilot.m b/codec2/branches/0.7/octave/test_dsss_pilot.m
new file mode 100644 (file)
index 0000000..1d3ec16
--- /dev/null
@@ -0,0 +1,437 @@
+% test_dsss_pilot.m
+% David Rowe Oct 2014
+%
+
+% Simulation to test FDM QPSK with pilot based coherent detection
+% combined with DSSS.
+  
+% reqd to make sure we can repeat tests exactly
+
+rand('state',1); 
+randn('state',1);
+
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_mag_only      = sim_in.hf_mag_only;
+    Nchip            = sim_in.Nchip;
+    Np               = sim_in.Np;
+    Ns               = sim_in.Ns;
+
+    bps              = 2;
+    Nc = Nsymb       = framesize/bps;
+
+    prev_sym_tx      = qpsk_mod([0 0])*ones(1,Nc*Nchip);
+    prev_sym_rx      = qpsk_mod([0 0])*ones(1,Nc*Nchip);
+
+    tx_bits_mem = zeros(Np*Ns+1, framesize);
+    tx_symb_mem = zeros(Np*Ns+1, Nc*Nchip);
+    s_ch_mem    = zeros(Np*Ns+1, Nc*Nchip);
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+   
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread(1:Ntrials))+var(spread_2ms(1:Ntrials)));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        s_ch_tx_log      = [];
+        rx_symb_log      = [];
+        noise_log        = [];
+        errors_log       = [];
+        Nerrs_log        = [];
+
+        % init HF channel
+
+        hf_n = 1;
+        phi_ = zeros(Ntrials+Np*Ns, Nc*Nchip);
+
+        phase_offset = 0;
+        w_offset     = 0;
+
+        % simulation starts here-----------------------------------
+        for nn = 1:Ntrials+Np*Ns
+                  
+            tx_bits = round( rand( 1, framesize) );                       
+            tx_bits_mem(1:Np*Ns,:) = tx_bits_mem(2:Np*Ns+1,:);
+            for b=1:framesize
+              tx_bits_mem(Np*Ns+1,b) = tx_bits(b);
+            end
+
+            % modulate --------------------------------------------
+
+            tx_symb = zeros(1,Nc*Nchip);
+
+            for i=1:Nc
+                tx_symb(i) = qpsk_mod(tx_bits(2*(i-1)+1:2*i));
+            end
+
+            % Optionally copy to other carriers (spreading)
+
+            for i=Nc+1:Nc:Nc*Nchip
+                tx_symb(i:i+Nc-1) = tx_symb(1:Nc);
+            end
+            % Optionally DQPSK encode
+            if strcmp(modulation,'dqpsk')
+              for c=1:Nc*Nchip
+                tx_symb(c) *= prev_sym_tx(c);
+                prev_sym_tx(c) = tx_symb(c);
+              end               
+            end
+
+            tx_symb_mem(1:Np*Ns,:) = tx_symb_mem(2:Np*Ns+1,:);
+            for c=1:Nc*Nchip
+              tx_symb_mem(Np*Ns+1,c) = tx_symb(c);
+            end
+
+            s_ch = tx_symb/sqrt(Nchip);
+
+            % HF channel simulation  ------------------------------------
+            
+            if hf_sim
+
+                % separation between carriers.  Note this effectively
+                % under samples at Rs, I dont think this matters.
+                % Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                hf_model(hf_n, :) = zeros(1,Nc*Nchip);
+
+                for i=1:Nchip
+                    time_shift = floor(i*Rs/4);
+                    for k=1:Nc
+                        ahf_model = hf_gain*(spread(hf_n+time_shift) + exp(-j*k*wsep*nhfdelay)*spread_2ms(hf_n+time_shift));
+                        if hf_mag_only
+                             s_ch((i-1)*Nc+k) *= abs(ahf_model);
+                        else
+                             s_ch((i-1)*Nc+k) *= ahf_model;
+                        end
+                        hf_model(hf_n, (i-1)*Nc+k) = ahf_model;
+                    end
+                end
+                hf_n++;
+            end
+           
+            s_ch_tx_log = [s_ch_tx_log s_ch];
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb*Nchip) + j*randn(1,Nsymb*Nchip));
+            noise_log = [noise_log noise];
+
+            s_ch = s_ch.*exp(j*phase_offset) + noise;
+            phase_offset += w_offset;
+
+            s_ch_mem(1:Np*Ns,:) = s_ch_mem(2:Np*Ns+1,:);
+            for c=1:Nc*Nchip
+              s_ch_mem(Np*Ns+1,c) = s_ch(c);
+            end
+            
+            % pilot based phase estimation and correction
+            
+            if Np
+               for c=1:Nc*Nchip
+                 pilots = tx_symb_mem(:,c);
+                 pilots(floor(Np*Ns/2)+1) = 0;
+                 phi_(nn,c) = angle(pilots(1:Ns:Np*Ns+1)'*s_ch_mem(1:Ns:Np*Ns+1,c));
+                end
+            end
+
+            % demodulate stage 1
+
+            for c=1:Nc*Nchip
+                rx_symb(c) = s_ch_mem(floor(Np*Ns/2)+1,c) *exp(-j*phi_(nn,c));
+                if strcmp(modulation,'dqpsk')
+                    tmp = rx_symb(c);
+                    rx_symb(c) *= conj(prev_sym_rx(c)/abs(prev_sym_rx(c)));
+                    prev_sym_rx(c) = tmp;
+                end
+            end
+
+            % de-spread
+
+            for i=Nc+1:Nc:Nchip*Nc
+              rx_symb(1:Nc) = rx_symb(1:Nc) + rx_symb(i:i+Nc-1);
+            end
+
+            % demodulate stage 2 (start when we have Np*Ns symbols in memories)
+
+            if nn > Np*Ns
+              rx_bits = zeros(1, framesize);
+              for c=1:Nc
+                rx_bits((2*(c-1)+1):(2*c)) = qpsk_demod(rx_symb(c));
+                tx_bits((2*(c-1)+1):(2*c)) = tx_bits_mem(floor(Np*Ns/2)+1,(2*(c-1)+1):(2*c));
+              end
+              rx_symb_log = [rx_symb_log rx_symb(1:Nc)];
+
+              % Measure BER
+
+              error_positions = xor(rx_bits, tx_bits);
+              Nerrs = sum(error_positions);
+              Terrs += Nerrs;
+              Tbits += length(tx_bits);
+              errors_log = [errors_log error_positions];
+              Nerrs_log = [Nerrs_log Nerrs];
+            end
+        end
+    
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+        if verbose 
+            av_tx_pwr = (s_ch_tx_log * s_ch_tx_log')/length(s_ch_tx_log);
+
+            printf("EsNo (dB): %3.1f Terrs: %d BER %4.2f QPSK BER theory %4.2f av_tx_pwr: %3.2f", EsNodB, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f BER theory %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), var(tx_symb_log), var(noise_log),
+                   var(tx_symb_log), var(noise_log), var(tx_symb_log)/var(noise_log));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    sim_out.errors_log      = errors_log;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+
+        if hf_sim
+          figure(3);
+          clf;
+        
+          y = 1:(hf_n-1);
+          x = 1:Nc*Nchip;
+          EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+          EsNodBSurface(find(EsNodBSurface < -5)) = -5;
+          mesh(x,y,EsNodBSurface);
+          grid
+          axis([1 (Nc+1)*Nchip 1 Rs*5 -5 15])
+          title('HF Channel Es/No');
+
+          if verbose 
+            [m n] = size(hf_model);
+            av_hf_pwr = sum(sum(abs(hf_model(:,:)).^2))/(m*n);
+            printf("average HF power: %3.2f over %d symbols\n", av_hf_pwr, m*n);
+          end
+
+          figure(5);
+          clf
+          subplot(211)
+          [m n] = size(hf_model);
+          plot(angle(hf_model(1:m,1)),'g;HF channel phase;')
+          hold on;
+          lphi_ = length(phi_);
+          plot(phi_(1+floor(Ns*Np/2):lphi_),'r+;Estimated HF channel phase;')
+          ylabel('Phase (rads)');
+          subplot(212)
+          plot(abs(hf_model(1:m,1)))
+          ylabel('Amplitude');
+          xlabel('Time (symbols)');
+        end
+
+        figure(4)
+        clf
+        stem(Nerrs_log)
+   end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+  sim_in.framesize        = 2;
+  sim_in.Rs               = 50;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 0;
+
+  sim_in.Nchip            = 1;
+endfunction
+
+function test_curves
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 10; 
+  sim_in.hf_sim           = 1;
+  sim_in.Ntrials          = 1000;
+  sim_in.Rs               = 200;
+  sim_in.Np               = 4;
+  sim_in.Ns               = 8;
+  sim_in.Nchip            = 1;
+
+  sim_qpsk                = ber_test(sim_in, 'qpsk');
+
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 10:20; 
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+
+  sim_in.Np               = 0;
+  sim_in.Nchip            = 1;
+
+  sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 1;
+  sim_qpsk_hf_ideal       = ber_test(sim_in, 'qpsk');
+  sim_in.hf_mag_only      = 0;
+  sim_dqpsk_hf            = ber_test(sim_in, 'dqpsk');
+  sim_in.Np               = 6;
+  sim_qpsk_hf_pilot       = ber_test(sim_in, 'qpsk');
+  sim_in.Nchip            = 2;
+  sim_qpsk_hf_pilot_dsss  = ber_test(sim_in, 'qpsk');
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'c;DQPSK AWGN;')
+  semilogy(sim_qpsk_hf_ideal.Ebvec, sim_qpsk_hf_ideal.BERvec,'b;QPSK HF ideal;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'k;DQPSK HF;')
+  semilogy(sim_qpsk_hf_pilot.Ebvec, sim_qpsk_hf_pilot.BERvec,'r;QPSK Np=6 HF;')
+  semilogy(sim_qpsk_hf_pilot_dsss.Ebvec, sim_qpsk_hf_pilot_dsss.BERvec,'g;QPSK Np=6 Nchip=2 HF;')
+  hold off;
+
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+endfunction
+
+function test_single
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Ntrials          = 1000;
+  sim_in.Esvec            = 2; 
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 0;
+  sim_in.Nchip            = 2;
+  sim_in.Np               = 6;
+  sim_in.Ns               = 8;
+  sim_in.Rs               = 200;
+  
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+endfunction
+
+
+% Start simulations ---------------------------------------
+
+more off;
+test_curves();
+%test_single();
diff --git a/codec2/branches/0.7/octave/test_fec.m b/codec2/branches/0.7/octave/test_fec.m
new file mode 100644 (file)
index 0000000..710ec49
--- /dev/null
@@ -0,0 +1,406 @@
+% test_fec.m
+% David Rowe Oct 2014
+%
+
+% Simulation to test FDM QPSK combined with FEC.  A low rate Codec
+% (e.g. 450 bit/s) is transmitted on Nc=4 FDM carriers.  FEC parity
+% bits are repeated on a seperate block of 4 carriers that is delayed
+% in time by Rs symbols (1 second).  A (n,k) Read Solomon code that can
+% correct (n-k)/2 errors is simulated.
+  
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_mag_only      = sim_in.hf_mag_only;
+    n                = sim_in.n;
+    k                = sim_in.k;  % k message bits 
+    Nc               = sim_in.Nc; % number of carriers
+
+    bps              = 2;
+    Nsymb            = n/bps;      % total number of symbols
+    Nb               = Nsymb/Nc;   % length of block of symbols 
+    assert(Nb == floor(Nb), "Nb must be an integer");
+
+    Nck              = (k/n)*Nc;      % Number of carriers for data symbols
+    Ncp              = ((n-k)/n)*Nc;  % Number of carriers for parity symbols 
+    assert(Nck == floor(Nck), "Number of carriers for data symbols must be an integer");
+    assert(Ncp == floor(Ncp), "Number of carriers for parity symbols must be an integer");
+
+    printf("(n,k)=(%d,%d) Nsymb: %d Nc: %d Nb: %d Nck: %d Ncp: %d\n",n,k,Nsymb,Nc,Nb,Nck,Ncp);
+
+    prev_sym_tx      = qpsk_mod([0 0])*ones(1,Nc);
+    prev_sym_rx      = qpsk_mod([0 0])*ones(1,Nc);
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+   
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        tx_symb_log      = [];
+        rx_symb_log      = [];
+        errors_log       = [];
+        Nerrs_log        = [];
+
+        % init HF channel
+
+        hf_n = 1;
+
+        % simulation starts here-----------------------------------
+        for nn = 1: Ntrials
+                  
+            tx_bits = round(rand(1,n));                       
+
+            % modulate --------------------------------------------
+
+            tx_symb=zeros(Nc,Nb);
+
+            for b=1:Nb
+              for c=1:Nc
+                  i = (b-1)*Nc + c;
+                  tx_symb(c,b) = qpsk_mod(tx_bits(2*(i-1)+1:2*i));
+                  if strcmp(modulation,'dqpsk')
+                    tx_symb(c,b) *= prev_sym_tx(c);
+                    prev_sym_tx(c) = tx_symb(c,b);
+                  end
+              end
+            end
+            s_ch = tx_symb;
+
+            % HF channel simulation  ------------------------------------
+            
+            if hf_sim
+
+                % separation between carriers.  Note this effectively
+                % under samples at Rs, I dont think this matters.
+                % Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                for b=1:Nb
+
+                    % apply HF model to data symbol carriers
+
+                    for c=1:Nck
+                        ahf_model = hf_gain*(spread(hf_n) + exp(-j*k*wsep*nhfdelay)*spread_2ms(hf_n));
+                        if hf_mag_only
+                             s_ch(c,b) *= abs(ahf_model);
+                        else
+                             s_ch(c,b) *= ahf_model;
+                        end
+                        hf_model(hf_n, c) = ahf_model;
+                    end
+
+                    % apply HF model (time shifted into the future) to parity symbol carriers 
+
+                    for c=1:Ncp
+                        ahf_model = hf_gain*(spread(hf_n+Rs) + exp(-j*k*wsep*nhfdelay)*spread_2ms(hf_n+Rs));
+                        if hf_mag_only
+                             s_ch(Nck+c,b) *= abs(ahf_model);
+                        else
+                             s_ch(Nck+c,b) *= ahf_model;
+                        end
+                        hf_model(hf_n, Nck+c) = ahf_model;
+                   end
+
+                    hf_n++;
+                end
+            end
+           
+            for b=1:Nb
+              for c=1:Nc
+                tx_symb_log = [tx_symb_log s_ch(c,b)];
+              end
+            end
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(Nc,Nb) + j*randn(Nc,Nb));
+
+            s_ch = s_ch + noise;
+
+            % de-modulate
+
+            rx_bits = zeros(1, n);
+            for b=1:Nb
+              for c=1:Nc
+                rx_symb(c,b) = s_ch(c,b);
+                if strcmp(modulation,'dqpsk')
+                    tmp = rx_symb(c,b);
+                    rx_symb(c,b) *= conj(prev_sym_rx(c)/abs(prev_sym_rx(c)));
+                    prev_sym_rx(c) = tmp;
+                end
+                i = (b-1)*Nc + c;
+                rx_bits((2*(i-1)+1):(2*i)) = qpsk_demod(rx_symb(c,b));
+                rx_symb_log = [rx_symb_log rx_symb(c,b)];
+              end
+            end
+
+            % Measure BER
+
+            error_positions = xor(rx_bits, tx_bits);
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += length(tx_bits);
+            errors_log = [errors_log error_positions];
+            Nerrs_log = [Nerrs_log Nerrs];
+        end
+    
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+
+        if verbose 
+            av_tx_pwr = (tx_symb_log * tx_symb_log')/length(tx_symb_log)
+
+            printf("EsNo (dB): %3.1f  Terrs: %d BER %4.3f QPSK BER theory %4.3f av_tx_pwr: %3.2f", EsNodB, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f BER theory %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), var(tx_symb_log), var(noise_log),
+                   var(tx_symb_log), var(noise_log), var(tx_symb_log)/var(noise_log));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    sim_out.errors_log      = errors_log;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+
+        if hf_sim
+          figure(3);
+          clf;
+        
+          y = 1:(hf_n-1);
+          x = 1:Nc;
+          EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+          EsNodBSurface(find(EsNodBSurface < -5)) = -5;
+          mesh(x,y,EsNodBSurface);
+          grid
+          axis([1 Nc 1 Rs*5 -5 15])
+          title('HF Channel Es/No');
+
+          if verbose 
+            av_hf_pwr = sum(abs(hf_model(y)).^2)/(hf_n-1);
+            printf("average HF power: %3.2f over %d symbols\n", av_hf_pwr, hf_n-1);
+          end
+        end
+
+        figure(4)
+        clf
+        stem(Nerrs_log)
+   end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+  sim_in.Rs               = 50;
+  sim_in.Nc               = 8;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 0;
+endfunction
+
+function test_curves
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 50; 
+  sim_in.hf_sim           = 0;
+  sim_in.Ntrials          = 1000;
+
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 5:15; 
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+  sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 1;
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+  sim_in.hf_mag_only      = 0;
+  sim_dqpsk_hf            = ber_test(sim_in, 'dqpsk');
+  sim_in.Nchip            = 4;
+  sim_dqpsk_hf_dsss       = ber_test(sim_in, 'dqpsk');
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'c;DQPSK AWGN;')
+  semilogy(sim_qpsk_hf.Ebvec, sim_qpsk_hf.BERvec,'b;QPSK HF;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'k;DQPSK HF;')
+  semilogy(sim_dqpsk_hf_dsss.Ebvec, sim_dqpsk_hf_dsss.BERvec,'g;DQPSK DSSS HF;')
+  hold off;
+
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+endfunction
+
+function test_1600_v_450
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+  sim_in.Ntrials          = 500;
+  sim_in.hf_sim           = 1;
+
+  sim_in.framesize        = 32;
+  sim_in.Nc               = 16;
+  sim_in.Esvec            = 7; 
+  sim_in.Nchip            = 1;
+  
+  sim_dqpsk_hf_1600        = ber_test(sim_in, 'dqpsk');
+
+  sim_in.framesize        = 8;
+  sim_in.Nc               = 4;
+  sim_in.Esvec            = sim_in.Esvec + 10*log10(1600/450); 
+  sim_in.Nchip            = 4;
+  
+  sim_dqpsk_hf_450         = ber_test(sim_in, 'dqpsk');
+  
+  fep=fopen("errors_1600.bin","wb"); fwrite(fep, sim_dqpsk_hf_1600.errors_log, "short"); fclose(fep);
+  fep=fopen("errors_450.bin","wb"); fwrite(fep, sim_dqpsk_hf_450.errors_log, "short"); fclose(fep);
+
+endfunction
+
+function test_single
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.n                = 48*8;
+  sim_in.k                = 24*8;
+  snr                     = 1;
+  sim_in.Esvec            = snr + 10*log10(3000/400); 
+  sim_in.hf_sim           = 1;
+  sim_in.Ntrials          = 100;
+  
+  sim_qpsk_hf             = ber_test(sim_in, 'dqpsk');
+endfunction
+
+
+% Start simulations ---------------------------------------
+
+more off;
+
+%test_1600_v_450();
+%test_curves();
+test_single();
diff --git a/codec2/branches/0.7/octave/test_foff.m b/codec2/branches/0.7/octave/test_foff.m
new file mode 100644 (file)
index 0000000..34afed3
--- /dev/null
@@ -0,0 +1,402 @@
+% test_foff.m
+% David Rowe April 2015
+%
+% Octave script for testing the cohpsk freq offset estimator
+
+graphics_toolkit ("gnuplot");
+more off;
+
+cohpsk;
+fdmdv;
+autotest;
+
+rand('state',1); 
+randn('state',1);
+
+% Core function for testing frequency offset estimator.  Performs one test
+
+function sim_out = freq_off_est_test(sim_in)
+  global Nfilter;
+  global M;
+
+  Rs = 100;
+  Nc = 4;
+  Nd = 2;
+  framesize = 32;
+  Fs = 8000;
+  Fcentre = 1500;
+  
+  Nsw = 3; % numbers of sync window frames we process over.  Set based
+           % on Nsym to flush filter memory by final frame in windw
+
+  afdmdv.Nsym = 5;
+  afdmdv.Nt = 5;
+
+  afdmdv.Fs = 8000;
+  afdmdv.Nc = Nd*Nc-1;
+  afdmdv.Rs = Rs;
+  M = afdmdv.M  = afdmdv.Fs/afdmdv.Rs;
+  afdmdv.Nfilter = afdmdv.Nsym*M;
+  afdmdv.tx_filter_memory = zeros(afdmdv.Nc+1, afdmdv.Nfilter);
+  excess_bw = 0.5;
+  afdmdv.gt_alpha5_root = gen_rn_coeffs(excess_bw, 1/Fs, Rs, afdmdv.Nsym, afdmdv.M);
+  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.1 );
+  afdmdv.freq_pol = 2*pi*freq_hz/Fs;
+  afdmdv.freq = exp(j*afdmdv.freq_pol);
+  afdmdv.Fcentre = 1500;
+
+  afdmdv.fbb_rect = exp(j*2*pi*Fcentre/Fs);
+  afdmdv.fbb_phase_tx = 1;
+  afdmdv.fbb_phase_rx = 1;
+  %afdmdv.phase_rx = ones(afdmdv.Nc+1,1);
+  afdmdv.phase_rx = 1 - 2*(mod(1:Nc*Nd,2));
+  nin = M;
+
+  P = afdmdv.P = 4;
+  afdmdv.Nfilter = afdmdv.Nsym*afdmdv.M;
+  afdmdv.rx_filter_mem_timing = zeros(afdmdv.Nc+1, afdmdv.Nt*afdmdv.P);
+  afdmdv.Nfiltertiming = afdmdv.M + afdmdv.Nfilter + afdmdv.M;
+  afdmdv.rx_filter_memory = zeros(afdmdv.Nc+1, afdmdv.Nfilter);
+
+  acohpsk = standard_init();
+  acohpsk.framesize        = framesize;
+  acohpsk.ldpc_code        = 0;
+  acohpsk.ldpc_code_rate   = 1;
+  acohpsk.Nc               = Nc;
+  acohpsk.Rs               = Rs;
+  acohpsk.Ns               = 4;
+  acohpsk.Nd               = Nd;
+  acohpsk.modulation       = 'qpsk';
+  acohpsk.do_write_pilot_file = 0;
+  acohpsk = symbol_rate_init(acohpsk);
+  acohpsk.Ncm  = 10*acohpsk.Nsymbrowpilot*M;
+  acohpsk.coarse_mem  = zeros(1,acohpsk.Ncm);
+  acohpsk.Ndft = 2^(ceil(log2(acohpsk.Ncm)));
+  ch_fdm_frame_buf = zeros(1, Nsw*acohpsk.Nsymbrowpilot*M);
+
+  frames    = sim_in.frames;
+  EsNodB    = sim_in.EsNodB;
+  foff      = sim_in.foff;
+  dfoff     = sim_in.dfoff;
+  fading_en = sim_in.fading_en;
+
+  EsNo = 10^(EsNodB/10);
+  hf_delay_ms = 2;
+  phase_ch = 1;
+
+  rand('state',1); 
+  tx_bits_coh = round(rand(1,framesize*10));
+  ptx_bits_coh = 1;
+  [spread spread_2ms hf_gain] = init_hf_model(Fs, frames*acohpsk.Nsymbrowpilot*afdmdv.M);
+
+  hf_n = 1;
+  nhfdelay = floor(hf_delay_ms*Fs/1000);
+  ch_fdm_delay = zeros(1, acohpsk.Nsymbrowpilot*M + nhfdelay);
+  
+  sync = 0; next_sync = 1;
+  sync_start = 1;
+  freq_offset_log = [];
+  sync_time_log = [];
+  ch_fdm_frame_log = [];
+  ch_symb_log = [];
+  tx_fdm_frame_log = [];
+  ratio_log = [];
+
+  for f=1:frames
+
+    acohpsk.frame = f;
+
+    %
+    % Mod --------------------------------------------------------------------
+    %
+
+    tx_bits = tx_bits_coh(ptx_bits_coh:ptx_bits_coh+framesize-1);
+    ptx_bits_coh += framesize;
+    if ptx_bits_coh > length(tx_bits_coh)
+      ptx_bits_coh = 1;
+    end 
+
+    [tx_symb tx_bits] = bits_to_qpsk_symbols(acohpsk, tx_bits, [], []);
+
+    tx_fdm_frame = [];
+    for r=1:acohpsk.Nsymbrowpilot
+      tx_onesymb = tx_symb(r,:);
+      [tx_baseband afdmdv] = tx_filter(afdmdv, tx_onesymb);
+      [tx_fdm afdmdv] = fdm_upconvert(afdmdv, tx_baseband);
+      tx_fdm_frame = [tx_fdm_frame tx_fdm];
+    end
+    tx_fdm_frame_log = [tx_fdm_frame_log tx_fdm_frame];
+
+    %
+    % Channel --------------------------------------------------------------------
+    %
+
+    ch_fdm_frame = zeros(1,acohpsk.Nsymbrowpilot*M);
+    for i=1:acohpsk.Nsymbrowpilot*M
+      foff_rect = exp(j*2*pi*foff/Fs);
+      foff += dfoff;
+      phase_ch *= foff_rect;
+      ch_fdm_frame(i) = tx_fdm_frame(i) * phase_ch;
+    end
+    phase_ch /= abs(phase_ch);
+
+    if fading_en
+      ch_fdm_delay(1:nhfdelay) = ch_fdm_delay(acohpsk.Nsymbrowpilot*M+1:nhfdelay+acohpsk.Nsymbrowpilot*M);
+      ch_fdm_delay(nhfdelay+1:nhfdelay+acohpsk.Nsymbrowpilot*M) = ch_fdm_frame;
+
+      for i=1:acohpsk.Nsymbrowpilot*M
+        ahf_model = hf_gain*(spread(hf_n)*ch_fdm_frame(i) + spread_2ms(hf_n)*ch_fdm_delay(i));
+        ch_fdm_frame(i) = ahf_model;
+        hf_n++;
+      end
+    end
+
+    % each carrier has power = 2, total power 2Nc, total symbol rate NcRs, noise BW B=Fs
+    % Es/No = (C/Rs)/(N/B), N = var = 2NcFs/NcRs(Es/No) = 2Fs/Rs(Es/No)
+
+    variance = 2*Fs/(acohpsk.Rs*EsNo);
+    uvnoise = sqrt(0.5)*(randn(1,acohpsk.Nsymbrowpilot*M) + j*randn(1,acohpsk.Nsymbrowpilot*M));
+    noise = sqrt(variance)*uvnoise;
+
+    ch_fdm_frame += noise;
+    ch_fdm_frame_log = [ch_fdm_frame_log ch_fdm_frame];
+
+    %
+    % Try to achieve sync --------------------------------------------------------------------
+    %
+
+    % store Nsw frames so we can rewind if we get a good candidate
+
+    ch_fdm_frame_buf(1:(Nsw-1)*acohpsk.Nsymbrowpilot*M) = ch_fdm_frame_buf(acohpsk.Nsymbrowpilot*M+1:Nsw*acohpsk.Nsymbrowpilot*M);
+    ch_fdm_frame_buf((Nsw-1)*acohpsk.Nsymbrowpilot*M+1:Nsw*acohpsk.Nsymbrowpilot*M) = ch_fdm_frame;
+
+    next_sync = sync;
+    sync = 0;
+
+    if sync == 0
+
+      % we can test +/- 20Hz, so we break this up into 3 tests to cover +/- 60Hz
+
+      max_ratio = 0;
+      for acohpsk.f_est = Fcentre-40:40:Fcentre+40
+      %for acohpsk.f_est = Fcentre
+        
+        printf("  [%d] acohpsk.f_est: %f +/- 20\n", f, acohpsk.f_est);
+        [ch_symb rx_timing rx_filt rx_baseband afdmdv acohpsk.f_est ] = rate_Fs_rx_processing(afdmdv, ch_fdm_frame_buf, acohpsk.f_est, Nsw*acohpsk.Nsymbrowpilot, nin, 0);
+
+        % coarse timing (frame sync) and initial fine freq est ---------------------------------------------
+  
+        for i=1:Nsw-1
+          acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb((i-1)*acohpsk.Nsymbrowpilot+1:i*acohpsk.Nsymbrowpilot,:), acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+        end
+        [anext_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb((Nsw-1)*acohpsk.Nsymbrowpilot+1:Nsw*acohpsk.Nsymbrowpilot,:), sync, next_sync);
+
+        if anext_sync == 1
+          printf("  [%d] acohpsk.ratio: %f\n", f, acohpsk.ratio);
+          if acohpsk.ratio > max_ratio
+            max_ratio   = acohpsk.ratio;
+            f_est       = acohpsk.f_est - acohpsk.f_fine_est;
+            next_sync   = anext_sync;
+          end
+        end
+      end
+    end
+
+    % we've found a sync candidate
+
+    if (next_sync == 1)
+
+       % rewind and re-process last few frames with f_est
+
+       acohpsk.f_est = f_est;
+       printf("  [%d] trying sync and f_est: %f\n", f, acohpsk.f_est);
+       [ch_symb rx_timing rx_filt rx_baseband afdmdv acohpsk.f_est] = rate_Fs_rx_processing(afdmdv, ch_fdm_frame_buf, acohpsk.f_est, Nsw*acohpsk.Nsymbrowpilot, nin, 0);
+       ch_symb_log = ch_symb;
+       for i=1:Nsw-1
+         acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb((i-1)*acohpsk.Nsymbrowpilot+1:i*acohpsk.Nsymbrowpilot,:), acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+       end
+       [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb((Nsw-1)*acohpsk.Nsymbrowpilot+1:Nsw*acohpsk.Nsymbrowpilot,:), sync, next_sync);
+       if abs(acohpsk.f_fine_est) > 2
+         printf("  [%d] Hmm %f is a bit big so back to coarse est ...\n", f, acohpsk.f_fine_est);
+         next_sync = 0;
+       end
+
+       % candidate checks out so log stats
+
+       if (next_sync == 1)
+         printf("  [%d] in sync!\n", f);
+         freq_offset_log = [freq_offset_log Fcentre+foff-acohpsk.f_est];
+         sync_time_log = [sync_time_log f-sync_start];
+         ratio_log = [ratio_log max_ratio];
+         next_sync = 0; sync_start = f;
+       end
+    end
+
+    %printf("f: %d sync: %d next_sync: %d\n", f, sync, next_sync);
+    [sync acohpsk] = sync_state_machine(acohpsk, sync, next_sync);
+
+  end
+
+  % ftx=fopen("coarse_tx.raw","wb"); fwrite(ftx, 1000*ch_fdm_frame_log, "short"); fclose(ftx);
+
+  sim_out.freq_offset_log = freq_offset_log;
+  sim_out.sync_time_log = sync_time_log;
+  sim_out.ch_fdm_frame_log = ch_fdm_frame_log;
+  sim_out.ch_symb_log = ch_symb_log;
+  sim_out.tx_fdm_frame_log = tx_fdm_frame_log;
+  sim_out.ratio_log = ratio_log;
+endfunction
+
+
+function freq_off_est_test_single
+  sim_in.frames    = 5;
+  sim_in.EsNodB    = 120;
+  sim_in.foff      = 0;
+  sim_in.dfoff     = 0;
+  sim_in.fading_en = 0;
+
+  sim_out = freq_off_est_test(sim_in);
+
+  figure(1)
+  subplot(211)
+  plot(sim_out.freq_offset_log)
+  ylabel('f est error')
+  xlabel('time')
+
+  subplot(212)
+  if length(sim_out.freq_offset_log) > 0
+    hist(sim_out.freq_offset_log)
+    xlabel('f est error')
+    ylabel('histogram');
+  end
+
+  figure(2)
+  subplot(211)
+  plot(sim_out.sync_time_log)
+  ylabel('time to sync (frames)')
+  subplot(212)
+  if length(sim_out.sync_time_log) > 0
+    hist(sim_out.sync_time_log)
+    xlabel('time to sync (frames)')
+    ylabel('histogram')
+  end
+
+  figure(3)
+  subplot(211)
+  plot(real(sim_out.tx_fdm_frame_log(1:2*960)))
+  grid;
+  subplot(212)
+  plot(real(sim_out.ch_symb_log),'+')
+  grid;
+
+  figure(4)
+  clf;
+  plot(sim_out.ch_symb_log,'+')
+
+  figure(5)
+  clf;
+  plot(sim_out.ratio_log)
+  xlabel('time')
+  ylabel('ratio for sync')
+endfunction
+
+
+function [freq_off_log EsNodBSet] = freq_off_est_test_curves
+  EsNodBSet = [20 12 8];
+
+  sim_in.frames    = 100;
+  sim_in.foff      = -40;
+  sim_in.dfoff     = 0;
+  sim_in.fading_en = 1;
+  freq_off_log = 1E6*ones(sim_in.frames, length(EsNodBSet) );
+  sync_time_log = 1E6*ones(sim_in.frames, length(EsNodBSet) );
+
+  for i=1:length(EsNodBSet)
+    sim_in.EsNodB = EsNodBSet(i);
+    printf("%f\n", sim_in.EsNodB);
+
+    sim_out = freq_off_est_test(sim_in);
+    freq_off_log(1:length(sim_out.freq_offset_log),i) = sim_out.freq_offset_log;
+    sync_time_log(1:length(sim_out.sync_time_log),i) = sim_out.sync_time_log;
+  end
+
+  figure(1)
+  clf
+  hold on;
+  for i=1:length(EsNodBSet)
+    data = freq_off_log(find(freq_off_log(:,i) < 1E6),i);
+    s = std(data);
+    m = mean(data);
+    stdbar = [m-s; m+s];
+    plot(EsNodBSet(i), data, '+')
+    plot([EsNodBSet(i) EsNodBSet(i)]+0.5, stdbar,'+-')
+  end
+  hold off
+
+  axis([6 22 -25 25])
+  if sim_in.fading_en
+    title_str = sprintf('foff = %d Hz Fading', sim_in.foff);
+  else
+    title_str = sprintf('foff = %d Hz AWGN', sim_in.foff);
+  end
+  title(title_str);
+  xlabel('Es/No (dB)')
+  ylabel('freq offset error (Hz)');
+  figure(2)
+  clf
+  hold on;
+  for i=1:length(EsNodBSet)
+    leg = sprintf("%d;%d dB;", i, EsNodBSet(i));
+    plot(freq_off_log(find(freq_off_log(:,i) < 1E6),i),leg)
+  end
+  hold off;
+  title(title_str);
+  xlabel('test');
+  ylabel('freq offset error (Hz)');
+  legend('boxoff');
+
+  figure(3)
+  clf
+  hold on;
+  for i=1:length(EsNodBSet)
+    data = sync_time_log(find(sync_time_log(:,i) < 1E6),i);
+    if length(data) 
+      s = std(data);
+      m = mean(data);
+      stdbar = [m-s; m+s];
+      plot(EsNodBSet(i), data, '+')
+      plot([EsNodBSet(i) EsNodBSet(i)]+0.5, stdbar,'+-')
+    end
+  end 
+  hold off;
+  axis([6 22 0 10])
+  ylabel('sync time (frames)')
+  xlabel('Es/No (dB)');
+  title(title_str);
+
+  figure(4)
+  clf
+  hold on;
+  for i=1:length(EsNodBSet)
+    leg = sprintf("%d;%d dB;", i, EsNodBSet(i));
+    plot(sync_time_log(find(sync_time_log(:,i) < 1E6),i),leg)
+  end
+  hold off;
+  title(title_str);
+  xlabel('test');
+  ylabel('sync time (frames)');
+  legend('boxoff');
+
+endfunction
+
+
+% select on of these to run:
+
+freq_off_est_test_single;
+%freq_off_est_test_curves;
+
diff --git a/codec2/branches/0.7/octave/test_ftrack.m b/codec2/branches/0.7/octave/test_ftrack.m
new file mode 100644 (file)
index 0000000..5082c44
--- /dev/null
@@ -0,0 +1,197 @@
+% test_ftrack.m
+%
+% David Rowe May 2015
+%
+% Octave script that to test and develop symbol rate frequency offset
+% tracking
+%
+% [X] add Es/No noise and measure BER
+% [X] QPSK mod of random symbols
+% [X] tracking 1 Hz/s freq drift shiel staying in lock
+% [X] simulate R/N filter delay through filter
+
+rand('state',1); 
+randn('state',1);
+graphics_toolkit ("gnuplot");
+
+Fs = 8000;        % sample rate
+Rs = 50;          % QPSK modem symbol rate
+Nbits = 5000;     % number of bits to simulute over
+Nsymb = Nbits/2;  
+foff = 1;         % initial freq offset
+dfoff = -1/Fs;    % rate of change of frequency offset in Hz/sample
+M = Fs/Rs;        % oversampling rate
+
+EsNodB = 8;       % noise level
+EsNo = 10^(EsNodB/10);    
+variance = 1/EsNo;
+
+Nsym = 5;         % simulated delay of root nyquist filter in symbols
+
+% control system constants, these can be tweaked
+
+beta = 0.005;
+g    = 0.2;
+
+% init state variables
+
+phase_ch = 1;
+prev_rx_symb = 1;
+ftrack = 0;
+filt = 0;
+
+%  QPSK symbols ------> x -------> x ----------G(z) ------------\
+%                       |          |                            |
+%               exp(j*w_off*n)     |                            |
+%                                  |                            |
+%                         exp(-j*w_track*n)                     |
+%                                  \____________________________/
+%
+% for small phase/freq errors, where phase/freq detector is linear:
+%
+%              -1           beta               1            1
+%  G(z) = 1 - z     g  ---------------      --------     -------
+%                                     -1          -1           -1
+%                      1 - (1-beta)z         1 - z        1 - z 
+%
+%          (1)              (2)               (3)          (4)
+%
+% (1) - differentiator that gives us an error based on frequency difference
+% (2) - first order IIR loop filter  
+% (3) - integrator I added so loop could track ramp inputs (i.e. freq drift)
+% (4) - frequency to phase integrator implicit in VCO
+%
+% Note (1) and (3) cancel out, H(z) = 1, so we get a 2nd order loop.  We need to keep (1)
+% in the time domain implementation to make the modulation stripper work, it likes angles
+% near 0.
+%        
+% Transfer function, derived with pencil and paper:
+% 
+%     G(z)         g*beta
+% ------------ = ----------  * ------------------------------------
+% 1 + G(z)H(z)   1 + g*beta         2 - beta   -1    1 - beta    -2
+%                              1 - ---------- z   + ----------- z
+%                                  1 + g*beta        1 + g*beta
+
+% Second order IIR filter coeffs
+
+a1 = (2-beta)/(1+g*beta);
+a2 = (1-beta)/(1+g*beta);
+
+% Which can be used to work out the polar coordinates of the pole
+
+gamma = sqrt(a2);           % radius (distance from origin)
+w = acos(a1/(2*gamma));     % angular frequency
+
+printf("2nd order loop w: %f   gamma: %f\n", w, gamma);
+
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+
+% modulator
+
+tx_bits = rand(1, Nbits) > 0.5;
+tx_symb = zeros(1, Nsymb);
+for i=1:Nsymb
+  tx_symb(i) = qpsk_mod(tx_bits(2*(i-1)+1:2*i));
+end
+
+% run rest of simulation symbol by symbol 
+
+rx_symb = zeros(1, Nsymb);
+rx_filt = zeros(1,Nsym);
+
+diff_log = [];
+foff_log = [];
+ftrack_log = [];
+mod_strip_log = [];
+
+for i=1:Nsymb
+
+  % channel
+
+  foff_rect = exp(j*2*pi*(foff-ftrack)*M/Fs);
+  foff += M*dfoff;
+  phase_ch *= foff_rect;
+  rx_symb(i) = tx_symb(i) * phase_ch;
+  noise = sqrt(variance*0.5)*(randn(1,1) + j*randn(1, 1));
+  rx_symb(i) += noise;
+
+  % simulate delay of root nyquist filter
+
+  rx_filt(1:Nsym-1) = rx_filt(2:Nsym);
+  rx_filt(Nsym) = rx_symb(i);
+
+  % freq tracking loop
+
+  diff = rx_filt(1) .* conj(prev_rx_symb);
+  prev_rx_symb = rx_filt(1);
+
+  % 4th power strips QPSK modulation, by multiplying phase by 4
+  % Using the abs value of the real coord was found to help 
+  % non-linear issues when noise power was large
+
+  mod_strip = diff.^4;
+  mod_strip = abs(real(mod_strip)) + j*imag(mod_strip);
+
+  % loop filter made up of 1st order IIR plus integrator plus gain
+  % term.  Integrator was found to be reqd to track ramp inputs
+  % (i.e. freq drift)
+
+  filt = ((1-beta)*filt + beta*angle(mod_strip));
+  ftrack += g*filt;
+
+  diff_log = [diff_log diff];
+  foff_log = [foff_log foff];
+  ftrack_log = [ftrack_log ftrack];
+  mod_strip_log = [mod_strip_log mod_strip];
+end
+
+% plot results
+
+figure(1)
+clf
+plot(angle(mod_strip_log))
+title('mod stripping phase');
+
+figure(2);
+clf
+plot(mod_strip_log,'+')
+axis([-2 2 -2 2])
+title('mod stripping scatter');
+
+figure(3)
+clf
+subplot(211)
+plot(real(mod_strip_log))
+title('mod stripping real and imag');
+subplot(212)
+plot(imag(mod_strip_log))
+
+figure(4)
+clf
+subplot(211)
+plot(foff_log,';foff;')
+hold on
+plot(ftrack_log,'g+;ftrack;')
+hold off;
+legend("boxoff");  
+ylabel('Freq Offset Hz');
+
+subplot(212)
+plot(foff_log-ftrack_log,';foff-ftrack;' )
+ylabel('Freq Offset Tracking Error Hz');
+xlabel('symbols')
+legend("boxoff");  
+
+figure(5)
+freqz(g*beta/(1+g*beta), [1 -2*gamma*cos(w) gamma*gamma])
diff --git a/codec2/branches/0.7/octave/test_ldpc_fsk_lib.m b/codec2/branches/0.7/octave/test_ldpc_fsk_lib.m
new file mode 100644 (file)
index 0000000..4a6148a
--- /dev/null
@@ -0,0 +1,851 @@
+% test_ldpc_fsk_lib\r
+% David Rowe 16 April 2016\r
+%\r
+% A series of tests for ldpc_fsk_lib, and C versions ldpc_enc and ldpc_dec.\r
+% Gradually builds up complete C command line for SSTV balloon system,\r
+% using Octave versions of LDPC and FSK modem as reference points.\r
+\r
+1;\r
+\r
+% encodes and decodes one frame, also writes codeword.bin for testing\r
+% decode_from_file() below, and can optionally generate include file for\r
+% C version of decoder.\r
+\r
+function [data code_param] = simple_ut(c_include_file)\r
+  load('H2064_516_sparse.mat');\r
+  HRA = full(HRA);  \r
+  max_iterations = 100;\r
+  decoder_type = 0;\r
+  EsNodB = 3;\r
+  mod_order = 2;\r
+\r
+  code_param = ldpc_init(HRA, mod_order);\r
+  data = round( rand( 1, code_param.data_bits_per_frame ) );\r
+  codeword = ldpc_encode(code_param, data);\r
+  f = fopen("codeword.bin","wt"); fwrite(f, codeword, "uint8"); fclose(f);\r
+  s = 1 - 2 * codeword;   \r
+  code_param.symbols_per_frame = length( s );\r
+\r
+  EsNo = 10^(EsNodB/10);\r
+  variance = 1/(2*EsNo);\r
+  noise = sqrt(variance)* randn(1,code_param.symbols_per_frame); \r
+  rx = s + noise;\r
+  \r
+  if nargin == 1\r
+    code_param.c_include_file = c_include_file;\r
+  end\r
+  [detected_data Niters] = ldpc_decode(rx, code_param, max_iterations, decoder_type);\r
+  \r
+  error_positions = xor(detected_data(1:code_param.data_bits_per_frame), data);\r
+  Nerrs = sum(error_positions);\r
+\r
+  printf("Nerrs = %d\n", Nerrs);\r
+end\r
+\r
+\r
+% This version decodes from a file of bits\r
+\r
+function detected_data = decode_from_file(filename)\r
+  max_iterations = 100;\r
+  decoder_type = 0;\r
+  load('H2064_516_sparse.mat');\r
+  HRA = full(HRA);  \r
+  mod_order = 2;\r
+\r
+  f = fopen(filename,"rb"); codeword = fread(f, "uint8")'; fclose(f);\r
+  r = 1 - 2 * codeword;   \r
+  code_param = ldpc_init(HRA, mod_order);\r
+  [detected_data Niters] = ldpc_decode(r, code_param, max_iterations, decoder_type);\r
+end\r
+\r
+\r
+% plots a BER curve for the LDPC decoder.  Takes a while to run, uses parallel cores\r
+\r
+function plot_curve\r
+  num_cores = 4;              % set this to the number of cores you have\r
+\r
+  load('H2064_516_sparse.mat');\r
+  HRA = full(HRA);  \r
+  [Nr Nc] = size(HRA); \r
+  sim_in.rate = (Nc-Nr)/Nc;\r
+\r
+  sim_in.HRA            = HRA;\r
+  sim_in.mod_order      = 2;\r
+  sim_in.framesize      = Nc;\r
+  sim_in.mod_order      = 2; \r
+  sim_in.Lim_Ferrs      = 100;\r
+\r
+  % note we increase number of trials as BER goes down\r
+\r
+  Esvec   = [   0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 ]; \r
+  Ntrials = [ 1E4 1E4 1E4 1E4 1E5 1E5 1E5 1E5 1E5 ];\r
+  num_runs = length(Esvec)\r
+\r
+  sim_in_vec(1:num_runs) = sim_in;\r
+  for i = 1:num_runs\r
+    sim_in_vec(i).Esvec   = Esvec(i);\r
+    sim_in_vec(i).Ntrials = Ntrials(i);\r
+  end\r
+\r
+  %sim_out = ldpc5(sim_in_vec(1));\r
+  tstart = time();\r
+  sim_out = pararrayfun(num_cores, @ldpc5, sim_in_vec);\r
+  tend = time();\r
+\r
+  total_bits = sum(Ntrials)*sim_in.framesize;\r
+  total_secs = tend - tstart;\r
+  printf("%d bits in %4.1f secs, or %5f bits/s\n", total_bits, total_secs, total_bits/total_secs);\r
+\r
+  for i=1:num_runs\r
+    Ebvec(i)  = sim_out(i).Ebvec;\r
+    BERvec(i) = sim_out(i).BERvec;\r
+  end\r
+  semilogy(Ebvec,  BERvec, '+-')\r
+  xlabel('Eb/N0')\r
+  ylabel('BER')\r
+  title(['H2064 516 sparse.mat' ' ' date])\r
+\r
+end\r
+\r
+\r
+% Test C encoder\r
+\r
+function test_c_encoder\r
+  load('H2064_516_sparse.mat');\r
+  HRA = full(HRA);  \r
+  max_iterations = 100;\r
+  decoder_type = 0;\r
+  EsNodB = 3;\r
+  mod_order = 2;\r
+  frames = 100;\r
+\r
+  EsNo = 10^(EsNodB/10);\r
+  variance = 1/(2*EsNo);\r
+\r
+  code_param = ldpc_init(HRA, mod_order);\r
+\r
+  data = round(rand(1,frames*code_param.data_bits_per_frame));\r
+  f = fopen("data.bin","wt"); fwrite(f, data, "uint8"); fclose(f);\r
+\r
+  % Outboard C encoder\r
+\r
+  system("../src/ldpc_enc data.bin codewords.bin"); \r
+\r
+  % Test with Octave decoder\r
+\r
+  f = fopen("codewords.bin","rb"); codewords = fread(f, "uint8")'; fclose(f);\r
+  \r
+  Nerrs = 0;\r
+  for i=1:frames\r
+    st = (i-1)*code_param.symbols_per_frame+1; en = st+code_param.symbols_per_frame-1;\r
+    tx = 1 - 2 * codewords(st:en);   \r
+\r
+    noise = sqrt(variance)*randn(1,code_param.symbols_per_frame); \r
+    rx = tx + noise;\r
+\r
+    [detected_data Niters] = ldpc_decode(rx, code_param, max_iterations, decoder_type);\r
+\r
+    st = (i-1)*code_param.data_bits_per_frame+1; en = st+code_param.data_bits_per_frame-1;\r
+    error_positions = xor(detected_data(1:code_param.data_bits_per_frame), data(st:en));\r
+    Nerrs += sum(error_positions);\r
+  end\r
+\r
+  printf("Nerrs = %d\n", Nerrs);\r
+end\r
+\r
+\r
+function test_c_decoder\r
+  load('H2064_516_sparse.mat');\r
+  HRA = full(HRA);  \r
+  max_iterations = 100;\r
+  decoder_type = 0;\r
+  mod_order = 2;\r
+  frames = 10;\r
+  EsNodB = 2;\r
+  sdinput = 1;\r
+\r
+  EsNo = 10^(EsNodB/10);\r
+  variance = 1/(2*EsNo);\r
+\r
+  code_param = ldpc_init(HRA, mod_order);\r
+  data = round(rand(1,code_param.data_bits_per_frame*frames));\r
+  \r
+  f = fopen("data.bin","wt"); fwrite(f, data, "uint8"); fclose(f);\r
+  system("../src/ldpc_enc data.bin codewords.bin"); \r
+  f = fopen("codewords.bin","rb"); codewords = fread(f, "uint8")'; fclose(f);\r
+\r
+  s = 1 - 2 * codewords;   \r
+  noise = sqrt(variance)*randn(1,code_param.symbols_per_frame*frames); \r
+  r = s + noise;\r
+\r
+  % calc LLRs frame by frame\r
+\r
+  for i=1:frames\r
+    st = (i-1)*code_param.symbols_per_frame+1;\r
+    en = st + code_param.symbols_per_frame-1;\r
+    llr(st:en) = sd_to_llr(r(st:en));    \r
+  end\r
+\r
+  % Outboard C decoder\r
+\r
+  if sdinput\r
+    f = fopen("sd.bin","wb"); fwrite(f, r, "double"); fclose(f);\r
+    system("../src/ldpc_dec sd.bin data_out.bin --sd"); \r
+  else\r
+    f = fopen("llr.bin","wb"); fwrite(f, llr, "double"); fclose(f);\r
+    system("../src/ldpc_dec llr.bin data_out.bin"); \r
+  end\r
+\r
+  f = fopen("data_out.bin","rb"); data_out = fread(f, "uint8")'; fclose(f);\r
+  \r
+  Nerrs = Nerrs2 = zeros(1,frames);\r
+  for i=1:frames\r
+\r
+    % Check C decoder\r
+    \r
+    data_st = (i-1)*code_param.data_bits_per_frame+1;\r
+    data_en = data_st+code_param.data_bits_per_frame-1;\r
+    st = (i-1)*code_param.symbols_per_frame+1;\r
+    en = st+code_param.data_bits_per_frame-1;\r
+    data_out_c = data_out(st:en);\r
+    error_positions = xor(data_out_c, data(data_st:data_en));\r
+    Nerrs(i) = sum(error_positions);\r
+\r
+    % Octave decoder \r
+\r
+    st = (i-1)*code_param.symbols_per_frame+1; en = st+code_param.symbols_per_frame-1;\r
+    [detected_data Niters] = ldpc_decode(r(st:en), code_param, max_iterations, decoder_type);\r
+    st = (i-1)*code_param.data_bits_per_frame+1; en = st+code_param.data_bits_per_frame-1;\r
+    data_out_octave = detected_data(1:code_param.data_bits_per_frame);\r
+    error_positions = xor(data_out_octave, data(st:en));\r
+    Nerrs2(i) = sum(error_positions);\r
+    %printf("%4d ", Niters);\r
+  end\r
+  printf("Errors per frame:\nC.....:");\r
+  for i=1:frames\r
+    printf("%4d ", Nerrs(i));\r
+  end\r
+  printf("\nOctave:");\r
+  for i=1:frames\r
+    printf("%4d ", Nerrs2(i));\r
+  end\r
+  printf("\n");\r
+\r
+end\r
+\r
+% Saves a complex vector s to a file "filename" of IQ unsigned 8 bit\r
+% chars, same as RTLSDR format.\r
+\r
+function save_rtlsdr(filename, s)\r
+  mx = max(abs(s));\r
+  re = real(s); im = imag(s);\r
+  l = length(s);\r
+  iq = zeros(1,2*l);\r
+  %iq(1:2:2*l) = 127 + re*(127/mx); \r
+  %iq(2:2:2*l) = 127 + im*(127/mx); \r
+  iq(1:2:2*l) = 127 + 32*re; \r
+  iq(2:2:2*l) = 127 + 32*im; \r
+  figure(3); clf; plot(iq); title('simulated IQ signal from RTL SDR');\r
+  fs = fopen(filename,"wb");\r
+  fwrite(fs,iq,"uchar");\r
+  fclose(fs);\r
+endfunction\r
+\r
+\r
+% Oversamples by a factor of 2 using Octaves resample() function then\r
+% uses linear interpolation to achive fractional sample rate\r
+\r
+function rx_resample_fract = fractional_resample(rx, resample_rate);\r
+    assert(resample_rate < 2, "keep resample_rate between 0 and 2");\r
+    rx_resample2 = resample(rx, 2, 1);\r
+    l = length(rx_resample2);\r
+    rx_resample_fract = zeros(1,l);\r
+    k = 1;\r
+    step = 2/resample_rate;\r
+    for i=1:step:l-1\r
+      i_low = floor(i);\r
+      i_high = ceil(i);\r
+      f = i - i_low;\r
+      rx_resample_fract(k) = (1-f)*rx_resample2(i_low) + f*rx_resample2(i_high); \r
+      %printf("i: %f i_low: %d i_high: %d f: %f\n", i, i_low, i_high, f);\r
+      k++;\r
+    end\r
+    rx_resample_fract = rx_resample_fract(1:k-1);\r
+endfunction\r
+\r
+\r
+% Using simulated SSTV packet, generate complex fsk mod signals, 8-bit\r
+% unsigned IQ for feeding into C demod chain.  Can also be used to\r
+% generate BER curves.  Found bugs in UW size and our use of csdr\r
+% re-sampler using this function, and by gradually and carefully\r
+% building up the C command line.\r
+\r
+#{\r
+todo: [X] uncoded BER\r
+          [X] octave fsk demod\r
+          [X] use C demod\r
+      [X] compare uncoded BER to unsigned 8 bit IQ to regular 16-bit\r
+          [X] generate complex rx signal with noise\r
+          [X] used cmd line utils to drive demod\r
+      [X] test with resampler\r
+      [X] measure effect on PER with coding\r
+#}\r
+\r
+function [n_uncoded_errs n_uncoded_bits] = run_sstv_sim(sim_in, EbNodB)\r
+\r
+  frames = sim_in.frames;\r
+  demod_type = sim_in.demod_type;\r
+\r
+  % init LDPC code\r
+\r
+  load('H2064_516_sparse.mat');\r
+  HRA = full(HRA);  \r
+  max_iterations = 100;\r
+  decoder_type = 0;\r
+  mod_order = 2;\r
+\r
+  code_param = ldpc_init(HRA, mod_order);\r
+\r
+  % note fixed frame of bits used for BER testing\r
+\r
+  tx_codeword = gen_sstv_frame;\r
+  \r
+  % init FSK modem\r
+\r
+  fsk_horus_as_a_lib = 1;\r
+  fsk_horus;\r
+  states         = fsk_horus_init_hbr(9600, 8, 1200, 2, length(tx_codeword));\r
+  states.df(1:states.M) = 0;\r
+  states.dA(1:states.M) = 1;\r
+  states.tx_real = 0;  % Octave fsk_mod generates complex valued output\r
+                       % so we can simulate rtl_sdr complex ouput\r
+\r
+  % Set up simulated tx tones to sit in the middle of cdsr passband\r
+\r
+  filt_low_norm = 0.1; filt_high_norm = 0.4;\r
+  fc = states.Fs*(filt_low_norm + filt_high_norm)/2;\r
+  %fc = 1800;\r
+  f1 = fc - states.Rs/2;\r
+  f2 = fc + states.Rs/2;\r
+  states.ftx = [f1 f2];\r
+\r
+  % set up AWGN channel \r
+\r
+  EbNo = 10^(EbNodB/10);\r
+  variance = states.Fs/(states.Rs*EbNo*states.bitspersymbol);\r
+\r
+  % start simulation ----------------------------------------\r
+\r
+  tx_bit_stream = [];\r
+  for i=1:frames\r
+    % uncomment for different data on each frame\r
+    %tx_codeword = gen_sstv_frame;\r
+    tx_bit_stream = [tx_bit_stream tx_codeword];\r
+  end\r
+\r
+  printf("%d bits at %d bit/s is a %3.1f second run\n", length(tx_bit_stream), 115200,length(tx_bit_stream)/115200);\r
\r
+  % modulate and channel model\r
+\r
+  tx = fsk_horus_mod(states, tx_bit_stream);\r
+  noise_real = sqrt(variance)*randn(length(tx),1);\r
+  noise_complex = sqrt(variance/2)*(randn(length(tx),1) + j*randn(length(tx),1));\r
+\r
+  % demodulate -----------------------------------------------------\r
+\r
+  if demod_type == 1\r
+\r
+    % Octave demod\r
+\r
+    if states.tx_real\r
+      rx = tx + noise_real;\r
+    else\r
+      rx = tx + noise_complex;\r
+    end\r
+    SNRdB = 10*log10(var(tx)/var(noise_complex));\r
+\r
+    % demodulate frame by frame using Octave demod\r
+\r
+    st = 1;\r
+    run_frames = floor(length(rx)/states.N);\r
+    rx_bit_stream = [];\r
+    rx_sd_stream = [];\r
+    for f=1:run_frames\r
+\r
+      % extract nin samples from rx sample stream\r
+\r
+      nin = states.nin;\r
+      en = st + states.nin - 1;\r
+\r
+      if en <= length(rx) % due to nin variations its possible to overrun buffer\r
+        sf = rx(st:en);\r
+        st += nin;\r
+\r
+        % demodulate to stream of bits\r
+\r
+        states.f = [f1 f2]; % note that for Octave demod we cheat and use known tone frequencies\r
+                            % allows us to determine if freq offset estimation in C demod is a problem\r
+\r
+        [rx_bits states] = fsk_horus_demod(states, sf);\r
+        rx_bit_stream = [rx_bit_stream rx_bits];\r
+        rx_sd_stream = [rx_sd_stream states.rx_bits_sd];\r
+      end\r
+    end\r
+  end\r
+\r
+  if demod_type == 2\r
+    % baseline C demod\r
+\r
+    if states.tx_real\r
+      rx = tx + noise_real;\r
+    else\r
+      rx = 2*real(tx) + noise_real;\r
+    end\r
+    SNRdB = 10*log10(var(tx)/var(noise_real));\r
+    rx_scaled = 1000*real(rx);\r
+    f = fopen("fsk_demod.raw","wb"); fwrite(f, rx_scaled, "short"); fclose(f);\r
+    system("../build_linux/src/fsk_demod 2X 8 9600 1200 fsk_demod.raw fsk_demod.bin");\r
+    f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+  end\r
+\r
+  if demod_type == 3\r
+    % C demod driven by csdr command line kung fu\r
+\r
+    assert(states.tx_real == 0, "need complex signal for this test");\r
+    rx = tx + noise_complex;\r
+    SNRdB = 10*log10(var(tx)/var(noise_real));\r
+    save_rtlsdr("fsk_demod.iq", rx);\r
+    system("cat fsk_demod.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+    f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+  end\r
+\r
+  if demod_type == 4\r
+    % C demod with resampler ....... getting closer to Mark's real time cmd line\r
+\r
+    assert(states.tx_real == 0, "need complex signal for this test");\r
+    rx = tx + noise_complex;\r
+    SNRdB = 10*log10(var(tx)/var(noise_real));\r
+    \r
+    printf("resampling ...\n");\r
+    rx_resample_fract = fractional_resample(rx, 1.08331);\r
+    %rx_resample_fract = fractional_resample(rx_resample_fract, 1/1.08331);\r
+    save_rtlsdr("fsk_demod_resample.iq", rx_resample_fract);\r
+\r
+    printf("run C cmd line chain ...\n");\r
+%    system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+    system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../unittest/tsrc - - 0.9230968 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+%    system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr fractional_decimator_ff 1.08331 | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin");\r
+    f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+  end\r
+\r
+\r
+  if demod_type == 5\r
+\r
+    % C demod with resampler and use C code to measure PER, in this\r
+    % test we don't need to run state machine below as C code gives us\r
+    % the ouputs we need\r
+\r
+    assert(states.tx_real == 0, "need complex signal for this test");\r
+    rx = tx + noise_complex;\r
+    SNRdB = 10*log10(var(tx)/var(noise_real));\r
+    \r
+    printf("fract resampling ...\n");\r
+    rx_resample_fract = fractional_resample(rx, 1.08331);\r
+    save_rtlsdr("fsk_demod_resample.iq", rx_resample_fract);\r
+\r
+    % useful for HackRF\r
+    %printf("10X resampling ...\n");\r
+    %rx_resample_10M = resample(rx_resample_fract, 10, 1);\r
+    %save_rtlsdr("fsk_demod_10M.iq", rx_resample_10M);\r
+\r
+    printf("run C cmd line chain - uncoded PER\n");\r
+    system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../unittest/tsrc - - 0.9230968 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - - | ../src/drs232 - /dev/null -v");\r
+\r
+    printf("run C cmd line chain - LDPC coded PER\n");\r
+    system("cat fsk_demod_resample.iq | csdr convert_u8_f | csdr bandpass_fir_fft_cc 0.1 0.4 0.05 | csdr realpart_cf | csdr convert_f_s16 | ../unittest/tsrc - - 0.9230968 | ../build_linux/src/fsk_demod 2XS 8 9600 1200 - - | ../src/drs232_ldpc - /dev/null -v");\r
+  end\r
+\r
+  if demod_type == 6\r
+    % C demod with complex input driven simplfied csdr command line, just measure BER of demod\r
+\r
+    assert(states.tx_real == 0, "need complex signal for this test");\r
+    rx = tx + noise_complex;\r
+    SNRdB = 10*log10(var(tx)/var(noise_real));\r
+    save_rtlsdr("fsk_demod.iq", rx);\r
+    system("cat fsk_demod.iq | csdr convert_u8_f | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin C");\r
+\r
+    f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+  end\r
+\r
+  if demod_type == 7\r
+    % C demod with complex input, measure uncoded and uncoded PER\r
+\r
+    assert(states.tx_real == 0, "need complex signal for this test");\r
+    rx = tx + noise_complex;\r
+    SNRdB = 10*log10(var(tx)/var(noise_real));\r
+    save_rtlsdr("fsk_demod.iq", rx);\r
+\r
+    printf("run C cmd line chain - uncoded PER\n");\r
+    system("cat fsk_demod.iq | csdr convert_u8_f | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2X 8 9600 1200 - - C | ../src/drs232 - /dev/null -v");\r
+\r
+    printf("run C cmd line chain - LDPC coded PER\n");\r
+    %system("cat fsk_demod.iq | csdr convert_u8_f | csdr convert_f_s16 | ../build_linux/src/fsk_demod 2XS 8 9600 1200 - - C | ../src/drs232_ldpc - /dev/null -v");\r
+    system("cat fsk_demod.iq | ../build_linux/src/fsk_demod 2XS 8 9600 1200 - - CU8 | ../src/drs232_ldpc - /dev/null -v");\r
+  end\r
+\r
+  if (demod_type != 5) && (demod_type != 7)\r
+    % state machine. Look for SSTV UW.  When found count bit errors over one frame of bits\r
+\r
+    state = "wait for uw";\r
+    start_uw_ind = 16*10+1; end_uw_ind = start_uw_ind + 5*10 - 1;\r
+    uw_rs232 = tx_codeword(start_uw_ind:end_uw_ind); luw = length(uw_rs232);\r
+    start_frame_ind =  end_uw_ind + 1;\r
+    nbits = length(rx_bit_stream);\r
+    uw_thresh = 5;\r
+    n_uncoded_errs = 0;\r
+    n_uncoded_bits = 0;\r
+    n_packets_rx = 0;\r
+    last_i = 0;\r
+\r
+    % might as well include RS232 framing bits in uncoded error count\r
+\r
+    nbits_frame = code_param.data_bits_per_frame*10/8;  \r
+\r
+    uw_errs = zeros(1, nbits);\r
+    for i=luw:nbits\r
+      uw_errs(i) = sum(xor(rx_bit_stream(i-luw+1:i), uw_rs232));\r
+    end\r
+\r
+    for i=luw:nbits\r
+      next_state = state;\r
+      if strcmp(state, 'wait for uw')\r
+        if uw_errs(i) <= uw_thresh\r
+          next_state = 'count errors';\r
+          tx_frame_ind = start_frame_ind;\r
+          rx_frame_ind = i + 1;\r
+          n_uncoded_errs_this_frame = 0;\r
+          %printf("%d %s %s\n", i, state, next_state);\r
+          if last_i\r
+            printf("i: %d i-last_i: %d ", i, i-last_i);\r
+          end\r
+        end\r
+      end\r
+      if strcmp(state, 'count errors')\r
+        n_uncoded_errs_this_frame += xor(rx_bit_stream(i), tx_codeword(tx_frame_ind));\r
+        n_uncoded_bits++;\r
+        tx_frame_ind++;\r
+        if tx_frame_ind == (start_frame_ind+nbits_frame)\r
+          n_uncoded_errs += n_uncoded_errs_this_frame;\r
+          printf("n_uncoded_errs_this_frame: %d\n", n_uncoded_errs_this_frame);\r
+          frame_rx232_rx = rx_bit_stream(rx_frame_ind:rx_frame_ind+nbits_frame-1);\r
+          %tx_codeword(start_frame_ind+1:start_frame_ind+10)\r
+          %frame_rx232_rx(1:10)\r
+          sstv_checksum(frame_rx232_rx);\r
+          last_i = i;\r
+          n_packets_rx++;\r
+          next_state = 'wait for uw';\r
+        end\r
+      end\r
+      state = next_state;\r
+    end\r
+\r
+    uncoded_ber = n_uncoded_errs/n_uncoded_bits;\r
+    printf("EbNodB: %4.1f SNRdB: %4.1f pkts: %d bits: %d errs: %d BER: %4.3f\n", \r
+            EbNodB, SNRdB, n_packets_rx, n_uncoded_bits, n_uncoded_errs, uncoded_ber);  \r
+\r
+    figure(2);\r
+    plot(uw_errs);\r
+    title('Unique Word Hamming Distance')\r
+  end\r
+\r
+endfunction\r
+\r
+\r
+% Function to test flight mode software.  Takes a rx stream of\r
+% demodulated bits, and locates frames using UW detection.  Extracts\r
+% data and parity bits.  Uses data bits to generate parity bits here\r
+% and compare.\r
+\r
+function compare_parity_bits(rx_bit_stream)\r
+    nframes = 500;\r
+\r
+    % init LDPC code\r
+\r
+    load('H2064_516_sparse.mat');\r
+    HRA = full(HRA);  \r
+    max_iterations = 100;\r
+    decoder_type = 0;\r
+    mod_order = 2;\r
+\r
+    code_param = ldpc_init(HRA, mod_order);\r
+\r
+    % generate frame, this will have random bits not related to\r
+    % rx_stream, however we just use it for the UW\r
+\r
+    tx_codeword = gen_sstv_frame;\r
+    l = length(tx_codeword);\r
+    printf("expected rs232 frames codeword length: %d\n", l);\r
+\r
+    % state machine. Look for SSTV UW.  When found count bit errors over one frame of bits\r
+\r
+    state = "wait for uw";\r
+    start_uw_ind = 16*10+1; end_uw_ind = start_uw_ind + 4*10 - 1;\r
+    uw_rs232 = tx_codeword(start_uw_ind:end_uw_ind); luw = length(uw_rs232);\r
+    start_frame_ind =  end_uw_ind + 1;\r
+    nbits = nframes*l;\r
+    uw_thresh = 5;\r
+    n_uncoded_errs = 0;\r
+    n_uncoded_bits = 0;\r
+    n_packets_rx = 0;\r
+    last_i = 0;\r
+\r
+    % might as well include RS232 framing bits in uncoded error count\r
+\r
+    uw_errs = luw*ones(1, nbits);\r
+    for i=luw:nbits\r
+      uw_errs(i) = sum(xor(rx_bit_stream(i-luw+1:i), uw_rs232));\r
+    end\r
+\r
+    frame_start = find(uw_errs < 2)+1;\r
+    nframes = length(frame_start)\r
+    for i=1:nframes\r
+\r
+      % double check UW OK\r
+\r
+      st_uw = frame_start(i) - luw; en_uw = frame_start(i) - 1;\r
+      uw_err_check = sum(xor(rx_bit_stream(st_uw:en_uw), uw_rs232));\r
+      %printf("uw_err_check: %d\n", uw_err_check);\r
+\r
+      % strip off rs232 start/stop bits\r
+\r
+      nbits_rs232 = (256+2+65)*10;\r
+      nbits = (256+2+65)*8;\r
+      nbits_byte = 10;\r
+      rx_codeword = zeros(1,nbits);\r
+      pdb = 1;\r
+\r
+      for k=1:nbits_byte:nbits_rs232\r
+        for l=1:8\r
+          rx_codeword(pdb) = rx_bit_stream(frame_start(i)-1+k+l);\r
+          pdb++;\r
+        end\r
+      end\r
+      assert(pdb == (nbits+1));\r
+      \r
+      data_bits = rx_codeword(1:256*8);\r
+      checksum_bits = rx_codeword(256*8+1:258*8);\r
+      parity_bits = rx_codeword(258*8+1:258*8+516);\r
+      padding_bits = rx_codeword(258*8+516+1:258*8+516+1);\r
+\r
+      % stopped here as we found bug lol!\r
+    end\r
+\r
+    figure(1); clf;\r
+    plot(uw_errs);\r
+    title('Unique Word Hamming Distance')\r
+    figure(2); clf;\r
+    lframe_start = length(frame_start);\r
+    plot(frame_start(2:lframe_start)-frame_start(1:lframe_start-1));\r
+    %title('Unique Word Hamming Distance')\r
+\r
+endfunction\r
+\r
+\r
+% Start simulation --------------------------------------------------------\r
+\r
+more off;\r
+currentdir = pwd;\r
+thiscomp = computer;\r
+\r
+if strcmpi(thiscomp, 'MACI64')==1\r
+   if exist('CMLSimulate')==0\r
+        cd '/Users/bill/Current/Projects/DLR_FSO/Visit2013_FSO_GEO/cml'\r
+        addpath '../'    % assume the source files stored here\r
+        CmlStartup       % note that this is not in the cml path!\r
+        disp('added MACI64 path and run CmlStartup')\r
+    end\r
+end\r
+\r
+if strfind(thiscomp, 'pc-linux-gnu')==8 \r
+   if exist('LdpcEncode')==0, \r
+        cd '~/tmp/cml'\r
+        CmlStartup \r
+        disp('CmlStartup has been run')\r
+       % rmpath '/home/bill/cml/mexhelp'  % why is this needed? \r
+       % maybe different path order in octave cf matlab ? \r
+    end\r
+end\r
+\r
+cd(currentdir)\r
+\r
+ldpc_fsk_lib;\r
+randn('state',1);\r
+rand('state',1);\r
+\r
+% ------------------ select which demo/test to run here ---------------\r
+\r
+demo = 12;\r
+\r
+if demo == 1\r
+  printf("simple_ut....\n");\r
+  data = simple_ut;\r
+end\r
+\r
+if demo == 2\r
+  printf("generate C header file....\n");\r
+  data = simple_ut("../src/H2064_516_sparse.h");\r
+end\r
+\r
+if demo == 3\r
+  printf("decode_from_file ......\n");\r
+  data = simple_ut;\r
+  detected_data = decode_from_file("codeword.bin");\r
+  error_positions = xor( detected_data(1:length(data)), data );\r
+  Nerrs = sum(error_positions);\r
+  printf("  Nerrs = %d\n", Nerrs);\r
+end\r
+\r
+if demo == 4\r
+  printf("plot a curve....\n");\r
+  plot_curve;\r
+end\r
+\r
+if demo == 5\r
+\r
+  % generate test data and save to disk\r
+\r
+  [data code_param] = simple_ut;\r
+  f = fopen("dat_in2064.bin","wb"); fwrite(f, data, "uint8"); fclose(f);\r
+\r
+  % Outboard C encoder\r
+\r
+  system("../src/ldpc_enc dat_in2064.bin dat_op2064.bin"); \r
+\r
+  % Test with Octave decoder\r
+\r
+  detected_data = decode_from_file("dat_op2064.bin");\r
+  error_positions = xor(detected_data(1:length(data)), data);\r
+  Nerrs = sum(error_positions);\r
+  printf("Nerrs = %d\n", Nerrs);\r
+end\r
+\r
+if demo == 6\r
+  test_c_encoder;\r
+end\r
+\r
+if demo == 7\r
+  test_c_decoder;\r
+end\r
+\r
+% generates simulated demod soft decision symbols to drive C ldpc decoder with\r
+\r
+if demo == 8\r
+  frames = 100;\r
+  EsNodB = 3;\r
+  EsNo = 10^(EsNodB/10);\r
+  variance = 1/(2*EsNo);\r
+\r
+  frame_rs232 = [];\r
+  for i=1:frames\r
+    frame_rs232 = [frame_rs232 gen_sstv_frame];\r
+  end\r
+\r
+  % write hard decn version to disk file, useful for fsk_mod input\r
+\r
+  f = fopen("sstv.bin","wb"); fwrite(f, frame_rs232, "char"); fclose(f);\r
+\r
+  % soft decision version (with noise)\r
+\r
+  s = 1 - 2*frame_rs232;\r
+  noise = sqrt(variance)*randn(1,length(frame_rs232)); \r
+  r = s + noise;\r
+  f = fopen("sstv_sd.bin","wb"); fwrite(f, r, "float32"); fclose(f);\r
+end\r
+\r
+\r
+if demo == 9\r
+  frames = 100;\r
+  EbNodB = 11;\r
+\r
+  frame_rs232 = [];\r
+  for i=1:frames\r
+    frame_rs232 = [frame_rs232 gen_sstv_frame];\r
+  end\r
+\r
+  % Use C FSK modulator to generate modulated signal\r
+\r
+  f = fopen("sstv.bin","wb"); fwrite(f, frame_rs232, "char"); fclose(f);\r
+  system("../build_linux/src/fsk_mod 2 9600 1200 1200 2400 sstv.bin fsk_mod.raw");\r
+\r
+  % Add some channel noise here in Octave\r
+\r
+  f = fopen("fsk_mod.raw","rb"); tx = fread(f, "short")'; fclose(f); tx_pwr = var(tx);\r
+  Fs = 9600; Rs=1200; EbNolin = 10 ^ (EbNodB/10);\r
+  variance = (tx_pwr/2)*states.Fs/(states.Rs*EbNolin*states.bitspersymbol);\r
+  noise = sqrt(variance)*randn(1,length(tx)); \r
+  SNRdB = 10*log10(var(tx)/var(noise));\r
+  rx = tx + noise;\r
+  f = fopen("fsk_demod.raw","wb"); tx = fwrite(f, rx, "short"); fclose(f);\r
\r
+  % Demodulate using C modem and C de-framer/LDPC decoder\r
+\r
+  system("../build_linux/src/fsk_demod 2XS 8 9600 1200 fsk_demod.raw - | ../src/drs232_ldpc - dummy_out.bin");\r
+end\r
+\r
+\r
+% Plots uncoded BER curves for two different SSTV simulations.  Used\r
+% to compare results with different processing steps as we build up C\r
+% command line.  BER curves are powerful ways to confirm system is\r
+% operating as expected, several bugs were found using this system.\r
+\r
+if demo == 10\r
+  sim_in.frames = 10;\r
+  EbNodBvec = 7:10;\r
+\r
+  sim_in.demod_type = 3;\r
+  ber_test1 = [];\r
+  for i = 1:length(EbNodBvec)\r
+    [n_uncoded_errs n_uncoded_bits] = run_sstv_sim(sim_in, EbNodBvec(i));\r
+    ber_test1(i) = n_uncoded_errs/n_uncoded_bits;\r
+  end\r
+  \r
+  sim_in.demod_type = 4;\r
+  ber_c = [];\r
+  for i = 1:length(EbNodBvec)\r
+    [n_uncoded_errs n_uncoded_bits] = run_sstv_sim(sim_in, EbNodBvec(i));\r
+    ber_test2(i) = n_uncoded_errs/n_uncoded_bits;\r
+  end\r
+\r
+  figure(1);\r
+  clf;\r
+  semilogy(EbNodBvec,  ber_test1, '+-;first test;')\r
+  grid;\r
+  xlabel('Eb/No (dB)')\r
+  ylabel('BER')\r
+\r
+  hold on;\r
+  semilogy(EbNodBvec,  ber_test2, 'g+-;second test;')\r
+  legend("boxoff");\r
+  hold off;\r
+  \r
+end\r
+\r
+% Measure PER of complete coded and uncoded system\r
+\r
+if demo == 11\r
+  sim_in.frames = 10;\r
+  EbNodB = 9;\r
+  sim_in.demod_type = 7;\r
+  run_sstv_sim(sim_in, EbNodB);\r
+end\r
+\r
+\r
+% Compare parity bits from an off-air stream of demodulated bits\r
+% Use something like:\r
+%   cat ~/Desktop/923096fs_wenet.iq | ../build_linux/src/fsk_demod 2X 8 9600 1200 - fsk_demod.bin CU8\r
+% (note not soft dec mode)\r
+if demo == 12\r
+  f = fopen("fsk_demod.bin","rb"); rx_bit_stream = fread(f, "uint8")'; fclose(f);\r
+\r
+  compare_parity_bits(rx_bit_stream);\r
+end\r
diff --git a/codec2/branches/0.7/octave/test_ml.m b/codec2/branches/0.7/octave/test_ml.m
new file mode 100644 (file)
index 0000000..a735264
--- /dev/null
@@ -0,0 +1,361 @@
+% test_ml.m
+% David Rowe Oct 2014
+%
+
+% Simulation to test FDM DQPSK with maximum likelihood detection on
+% fading channels.  Based on JPL publication 89-38 "Multiple Symbol
+% Differential Detection of Uncoded and Trellis Coded MPSK" by
+% Divsalar, Simon, Shahshahani.  Thanks Johhn Gibbs NN7F for advice.
+  
+% reqd to make sure we can repeat tests exactly
+
+rand('state',1); 
+randn('state',1);
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_mag_only      = sim_in.hf_mag_only;
+    framesize        = sim_in.framesize;
+    ml               = sim_in.ml;
+
+    bps              = 2;
+    Nc = Nsymb       = framesize/bps;      % total number of symbols
+
+    prev_sym_tx      = qpsk_mod([0 0])*ones(1,Nc);
+    prev_sym_rx      = qpsk_mod([0 0])*ones(1,Nc);
+    r                = qpsk_mod([0 0])*ones(Nc,4);
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+   
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        tx_symb_log      = [];
+        rx_symb_log      = [];
+        errors_log       = [];
+        Nerrs_log        = [];
+
+        % init HF channel
+
+        hf_n = 1;
+
+        % simulation starts here-----------------------------------
+        for nn = 1: Ntrials
+                  
+            tx_bits = round(rand(1,framesize));                       
+
+            % modulate --------------------------------------------
+
+            for c=1:Nc
+              tx_symb(c) = qpsk_mod(tx_bits((2*(c-1)+1):(2*c)));
+              if strcmp(modulation,'dqpsk')
+                tx_symb(c) *= prev_sym_tx(c);
+                prev_sym_tx(c) = tx_symb(c);
+              end
+            end
+            s_ch = tx_symb;
+            
+            % HF channel simulation  ------------------------------------
+            
+            if hf_sim
+
+                % separation between carriers.  Note this effectively
+                % under samples at Rs, I dont think this matters.
+                % Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                for c=1:Nc
+                    ahf_model = hf_gain*(spread(hf_n) + exp(-j*c*wsep*nhfdelay)*spread_2ms(hf_n));
+                    if hf_mag_only
+                        s_ch(c) *= abs(ahf_model);
+                    else
+                        s_ch(c) *= ahf_model;
+                    end
+                    hf_model(hf_n, c) = ahf_model;
+                end
+                hf_n++;
+            end
+           
+            tx_symb_log = [tx_symb_log s_ch];
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nc) + j*randn(1,Nc));
+
+            s_ch = s_ch + noise;
+
+            % de-modulate
+
+            rx_bits = zeros(1, framesize);
+            for c=1:Nc
+
+                r(c,2:4) = r(c, 1:3);
+                r(c,1) = s_ch(c);
+  
+                rx_symb(c) = s_ch(c);
+                if strcmp(modulation,'dqpsk')
+                  tmp = rx_symb(c);
+                  rx_symb(c) *= conj(prev_sym_rx(c)/abs(prev_sym_rx(c)));
+                  prev_sym_rx(c) = tmp;
+                end
+
+                if ml == 0
+                  rx_bits((2*(c-1)+1):(2*c)) = qpsk_demod(rx_symb(c));
+                else
+                  tx = [1 j -j -1];
+                  max_eta = 0;  max_symb = tx(1);
+                  for k=1:4
+                    for k_1=1:4
+                      for k_2=1:4
+                        if ml == 3
+                          eta = abs(r(c,3) + r(c,1)*tx(k)'*tx(k_1)' + r(c,2)*tx(k_1)')^2;
+                        end
+                        if ml == 4
+                          eta = abs(r(c,4) + r(c,1)*tx(k)'*tx(k_1)'*tx(k_2)' + r(c,2)*tx(k_1)'*tx(k_2)' + r(c,3)*tx(k_2)')^2;
+                        end
+                        %printf("  %d %d %f \n", k_1, k, eta);
+                        if eta > max_eta
+                          max_eta = eta;
+                          max_symb = tx(k);
+                        end
+                      end
+                    end
+                  end
+                  rx_bits((2*(c-1)+1):(2*c)) = qpsk_demod(max_symb);      
+                end
+                rx_symb_log = [rx_symb_log rx_symb(c)];
+            end
+            
+            % Measure BER
+
+            error_positions = xor(rx_bits, tx_bits);
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += length(tx_bits);
+            errors_log = [errors_log error_positions];
+            Nerrs_log = [Nerrs_log Nerrs];
+        end
+    
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+
+        if verbose 
+            av_tx_pwr = (tx_symb_log * tx_symb_log')/length(tx_symb_log);
+
+            printf("EsNo (dB): %3.1f  Terrs: %d BER %4.3f QPSK BER theory %4.3f av_tx_pwr: %3.2f", EsNodB, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
+            printf("\n");
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    sim_out.errors_log      = errors_log;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+
+        if hf_sim
+          figure(3);
+          clf;
+        
+          y = 1:(hf_n-1);
+          x = 1:Nc;
+          EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+          EsNodBSurface(find(EsNodBSurface < -5)) = -5;
+          mesh(x,y,EsNodBSurface);
+          grid
+          axis([1 Nc 1 Rs*5 -5 15])
+          title('HF Channel Es/No');
+
+          if verbose 
+            av_hf_pwr = sum(abs(hf_model(y)).^2)/(hf_n-1);
+            printf("average HF power: %3.2f over %d symbols\n", av_hf_pwr, hf_n-1);
+          end
+        end
+
+        figure(4)
+        clf
+        stem(Nerrs_log)
+   end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+  sim_in.Rs               = 50;
+  sim_in.framesize        = 8;
+  sim_in.ml               = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 0;
+endfunction
+
+
+function test_curves
+
+  sim_in = standard_init();
+
+  sim_in.Ntrials          = 1000;
+
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 5:15; 
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+  sim_in.ml               = 0;
+  %sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+  sim_in.ml               = 3;  
+  %sim_dqpsk_ml3            = ber_test(sim_in, 'dqpsk');
+  sim_in.ml               = 4;  
+  %sim_dqpsk_ml4            = ber_test(sim_in, 'dqpsk');
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 1;
+  sim_in.ml               = 0;
+  sim_dqpsk_hf            = ber_test(sim_in, 'dqpsk');
+  sim_in.ml               = 4;  
+  sim_dqpsk_ml_hf3        = ber_test(sim_in, 'dqpsk');
+  sim_in.ml               = 4;  
+  sim_dqpsk_ml_hf4        = ber_test(sim_in, 'dqpsk');
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  %semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'c;DQPSK AWGN;')
+  %semilogy(sim_dqpsk_ml3.Ebvec, sim_dqpsk_ml3.BERvec,'k;DQPSK ML N=3 AWGN;')
+  %semilogy(sim_dqpsk_ml4.Ebvec, sim_dqpsk_ml4.BERvec,'g;DQPSK ML N=4 AWGN;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'c;DQPSK HF;')
+  semilogy(sim_dqpsk_ml_hf3.Ebvec, sim_dqpsk_ml_hf3.BERvec,'k;DQPSK ML N=3 HF;')
+  semilogy(sim_dqpsk_ml_hf4.Ebvec, sim_dqpsk_ml_hf4.BERvec,'g;DQPSK ML N=4 HF;')
+  hold off;
+
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+endfunction
+
+
+function test_single
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+  sim_in.Ntrials          = 500;
+
+  sim_in.hf_mag_only      = 0;
+  sim_in.hf_sim           = 0;
+  sim_in.ml               = 0;
+  sim_in.Esvec            = 10;
+
+  sim_qpsk_hf             = ber_test(sim_in, 'dqpsk');
+endfunction
+
+
+% Start simulations ---------------------------------------
+
+more off;
+
+test_curves();
+%test_single();
diff --git a/codec2/branches/0.7/octave/test_pilot.m b/codec2/branches/0.7/octave/test_pilot.m
new file mode 100644 (file)
index 0000000..0117541
--- /dev/null
@@ -0,0 +1,388 @@
+% test_pilot_.m
+% David Rowe Oct 2014
+%
+
+% Simulation to test pilot assisted coherent FDM QPSK.  QPSK performs
+% about 4dB better than DQPSK on HF fading channels, even half of that
+% would be very useful.
+  
+% reqd to make sure we can repeat tests exactly
+
+rand('state',1); 
+randn('state',1);
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_mag_only      = sim_in.hf_mag_only;
+    framesize        = sim_in.framesize;
+    Np               = sim_in.Np;
+    Ns               = sim_in.Ns;
+    coh              = sim_in.coh;
+
+    bps              = 2;
+    Nc = Nsymb       = framesize/bps;      % total number of symbols
+
+    prev_sym_tx      = qpsk_mod([0 0])*ones(1,Nc);
+    prev_sym_rx      = qpsk_mod([0 0])*ones(1,Nc);
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+   
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;
+
+        tx_symb_log      = [];
+        rx_symb_log      = [];
+        errors_log       = [];
+        Nerrs_log        = [];
+
+        % simulation starts here-----------------------------------
+        % generate all tx symbols and simulate on HF channel so we can
+        % use future and past samples for phase estimation.  We
+        % simulate Ntrials+Np so we have enough samples for looking
+        % forward and backwards for phase estimation
+
+        tx_bits = zeros(Ntrials+Np*Ns, framesize);
+        tx_symb = zeros(1, Nc);
+        s_ch = zeros(Ntrials+Np*Ns, Nc);
+
+        for nn = 1: Ntrials+Np*Ns
+            tx_bits(nn,:) = round(rand(1,framesize));                       
+
+            % modulate --------------------------------------------
+
+            for c=1:Nc
+              tx_symb(c) = qpsk_mod(tx_bits(nn,(2*(c-1)+1):(2*c)));
+              if strcmp(modulation,'dqpsk')
+                tx_symb(c) *= prev_sym_tx(c);
+                prev_sym_tx(c) = tx_symb(c);
+              end
+            end
+            s_ch(nn,:) = tx_symb;
+            tx_symb_log = [tx_symb_log tx_symb];
+
+            if hf_sim
+              % separation between carriers.  Note this effectively
+              % under samples at Rs, I dont think this matters.
+              % Equivalent to doing freq shift at Fs, then
+              % decimating to Rs.
+
+              wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+              for c=1:Nc
+                hf_model(nn,c) = hf_gain*(spread(nn) + exp(-j*c*wsep*nhfdelay)*spread_2ms(nn));
+                %hf_model(nn,c) = 1;
+                if hf_mag_only
+                  s_ch(nn,c) *= abs(hf_model(nn,c));
+                else
+                  s_ch(nn,c) *= hf_model(nn,c);
+                end
+              end
+            end         
+         end
+
+         % add channel noise
+                    
+         noise = sqrt(variance*0.5)*(randn(Ntrials+Np*Ns,Nc) + j*randn(Ntrials+Np*Ns,Nc));
+         s_ch += noise;
+         if hf_sim
+           hf_model_noise = hf_model + noise;
+         end
+
+         % phase estimation and demodulation
+
+         phi_ = zeros(Ntrials+Np*Ns, Nc);
+
+         for nn = floor(Np*Ns/2)+1:floor(Np*Ns/2)+Ntrials
+           
+           % pilot assisted phase estimation 
+
+           if coh 
+             for c=1:Nc
+               k = 1;
+               for i = -floor(Np*Ns/2):Ns:floor(Np*Ns/2)
+                 % ignore centre sample as that is the current symbol
+                 if i != 0
+                   phase_samples(k) = hf_model_noise(nn+i,c);
+                   %printf("i: %d symb phase: %f\n", i, angle(phase_samples(k)));
+                   k++;                     
+                 end
+               end    
+               phi_(nn,c) = angle(sum(phase_samples));
+               %printf("phi: %f phi_: %f\n", angle(hf_model(nn,c)), phi_(nn,c));
+               s_ch(nn,c) *= exp(-j*phi_(nn,c));
+             end
+           end
+          
+           % de-modulate
+
+           rx_bits = zeros(1, framesize);
+           for c=1:Nc
+             rx_symb(c) = s_ch(nn,c);
+             if strcmp(modulation,'dqpsk')
+               tmp = rx_symb(c);
+               rx_symb(c) *= conj(prev_sym_rx(c)/abs(prev_sym_rx(c)));
+               prev_sym_rx(c) = tmp;
+             end
+             rx_bits((2*(c-1)+1):(2*c)) = qpsk_demod(rx_symb(c));
+             rx_symb_log = [rx_symb_log rx_symb(c)];
+           end
+            
+           % Measure BER
+
+           error_positions = xor(rx_bits, tx_bits(nn,:));
+           Nerrs = sum(error_positions);
+           Terrs += Nerrs;
+           Tbits += framesize;
+           errors_log = [errors_log error_positions];
+           Nerrs_log = [Nerrs_log Nerrs];
+        end
+    
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+
+        if verbose 
+            av_tx_pwr = (tx_symb_log * tx_symb_log')/length(tx_symb_log);
+
+            printf("EsNo (dB): %3.1f  Terrs: %d BER %4.3f QPSK BER theory %4.3f av_tx_pwr: %3.2f", EsNodB, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), av_tx_pwr);
+            printf("\n");
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    sim_out.errors_log      = errors_log;
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+        title('Scatter plot');
+
+        if hf_sim
+          figure(3);
+          clf;
+        
+          y = 1:Ntrials+floor(Np/2);
+          x = 1:Nc;
+          EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+          EsNodBSurface(find(EsNodBSurface < -5)) = -5;
+          mesh(x,y,EsNodBSurface);
+          grid
+          axis([1 Nc 1 Rs*5 -5 15])
+          title('HF Channel Es/No');
+
+          if verbose 
+            [m n] = size(hf_model);
+            av_hf_pwr = sum(sum(abs(hf_model(:,:)).^2))/(m*n);
+            printf("average HF power: %3.2f over %d symbols\n", av_hf_pwr, m*n);
+          end
+
+          figure(5);
+          clf
+          subplot(211)
+          [m n] = size(hf_model);
+          plot(angle(hf_model(1:m,1)),'g;HF channel phase;')
+          hold on;
+          plot(phi_(1:m,1),'r+;Estimated HF channel phase;')
+          ylabel('Phase (rads)');
+          subplot(212)
+          plot(abs(hf_model(1:m,1)))
+          ylabel('Amplitude');
+          xlabel('Time (symbols)');
+        end
+
+        figure(4)
+        clf
+        stem(Nerrs_log)
+
+   end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+  sim_in.Rs               = 50;
+  sim_in.framesize        = 8;
+  sim_in.ml               = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 0;
+endfunction
+
+
+function test_curves
+
+  sim_in = standard_init();
+
+  sim_in.Ntrials          = 2000;
+
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 5:15; 
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+
+  sim_in.coh               = 0;
+  sim_in.Np                = 2;
+  sim_in.Ns                = 8;
+  sim_in.Rs                = 100;
+
+  sim_dqpsk                = ber_test(sim_in, 'dqpsk');
+  sim_in.hf_sim            = 1;
+  sim_dqpsk_hf             = ber_test(sim_in, 'dqpsk');
+
+  sim_in.hf_mag_only       = 1;
+  sim_qpsk_hf_ideal        = ber_test(sim_in, 'qpsk');
+  sim_in.hf_mag_only       = 0;
+  sim_in.coh               = 1;
+  sim_in.Np                = 2;
+  sim_in.Ns                = 4;
+  sim_in.Rs                = 100;
+  sim_qpsk_hf_coh1         = ber_test(sim_in, 'qpsk');
+  sim_in.Np                = 4;
+  sim_in.Ns                = 4;
+  sim_in.Rs                = 200;
+  sim_qpsk_hf_coh2         = ber_test(sim_in, 'qpsk');
+  sim_in.Np                = 4;
+  sim_in.Ns                = 8;
+  sim_in.Rs                = 200;
+  sim_qpsk_hf_coh3         = ber_test(sim_in, 'qpsk');
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'k;DQPSK AWGN;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'k;DQPSK HF;')
+  semilogy(sim_qpsk_hf_ideal.Ebvec, sim_qpsk_hf_ideal.BERvec,'c;QPSK HF ideal;')
+  semilogy(sim_qpsk_hf_coh1.Ebvec, sim_qpsk_hf_coh1.BERvec,'g;QPSK HF Rs=100 Np=2 Ns=4;')
+  semilogy(sim_qpsk_hf_coh2.Ebvec, sim_qpsk_hf_coh2.BERvec,'r;QPSK HF Rs=200 Np=4 Ns=4;')
+  semilogy(sim_qpsk_hf_coh3.Ebvec, sim_qpsk_hf_coh3.BERvec,'b;QPSK HF Rs=200 Np=4 Ns=8;')
+  hold off;
+
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+endfunction
+
+
+function test_single
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+  sim_in.Ntrials          = 1000;
+
+  sim_in.hf_mag_only      = 0;
+  sim_in.hf_sim           = 1;
+  sim_in.Esvec            = 10;
+  sim_in.coh              = 1;
+  sim_in.Rs               = 100;
+  sim_in.Np               = 2;
+  sim_in.Ns               = 1;
+
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+endfunction
+
+
+% Start simulations ---------------------------------------
+
+more off;
+
+test_curves();
+%test_single();
diff --git a/codec2/branches/0.7/octave/test_qpsk.m b/codec2/branches/0.7/octave/test_qpsk.m
new file mode 100644 (file)
index 0000000..453302b
--- /dev/null
@@ -0,0 +1,516 @@
+% test_qpsk.m
+% David Rowe Feb 2014
+%
+% QPSK modem simulation, initially based on code by Bill Cowley
+% Generates curves BER versus E/No curves for different modems.
+% Design to test coherent demodulation ideas on HF channels without
+% building a full blown modem.  Uses 'genie provided' estimates for
+% timing estimation, frame sync.
+%
+
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    phase_est        = sim_in.phase_est;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    Nhfdelay         = floor(sim_in.hf_delay_ms*1000/Fs);
+    hf_phase_only    = sim_in.hf_phase_only;
+    hf_mag_only      = sim_in.hf_mag_only;
+
+    bps              = 2;
+    Nsymb            = framesize/bps;
+    prev_sym_tx      = qpsk_mod([0 0]);
+    prev_sym_rx      = qpsk_mod([0 0]);
+    rx_symb_log      = [];
+
+    Np               = sim_in.Np;  % number of pilot symbols to use in phase est
+    Ns               = sim_in.Ns;  % spacing of pilot symbols, so (Nps-1) data symbols between every pilot
+    Nps              = Np*Ns;
+    r_delay_line     = zeros(1,Nps+1);
+    s_delay_line     = zeros(1,Nps+1);
+    spread_main_phi  = 0;
+    spread_delay_phi = 0;
+    spread_main_phi_log = [];
+
+    ldpc_code = sim_in.ldpc_code;
+
+    if ldpc_code
+        % Start CML library
+
+        currentdir = pwd;
+        addpath '/home/david/tmp/cml/mat'    % assume the source files stored here
+        cd /home/david/tmp/cml
+        CmlStartup                           % note that this is not in the cml path!
+        cd(currentdir)
+  
+        % Our LDPC library
+
+        ldpc;
+
+        rate = 3/4; 
+        mod_order = 4; 
+        modulation = 'QPSK';
+        mapping = 'gray';
+
+        demod_type = 0;
+        decoder_type = 0;
+        max_iterations = 100;
+
+        code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);
+        code_param.code_bits_per_frame = framesize;
+        code_param.symbols_per_frame = framesize/bps;
+    else
+        rate = 1;
+    end
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % design root nyquist (root raised cosine) filter and init tx and rx filter states
+
+    alpha = 0.5; T=1/Fs; Nfiltsym=7; M=Fs/Rs;
+    if floor(Fs/Rs) != Fs/Rs
+        printf("oversampling ratio must be an integer\n");
+        return;
+    end
+    hrn = gen_rn_coeffs(alpha, T, Rs, Nfiltsym, M);
+    Nfilter = length(hrn);
+    tx_filter_memory = zeros(1, Nfilter);
+    rx_filter_memory = zeros(1, Nfilter);
+    s_delay_line_filt = zeros(1,Nfiltsym);
+    tx_bits_delay_line_filt = zeros(1,Nfiltsym*bps);
+    hf_sim_delay_line = zeros(1,M+Nhfdelay);
+
+    for ne = 1:length(Esvec)
+        Es = Esvec(ne);
+        EsNo = 10^(Es/10);
+    
+        % Given Es/No, determine the variance of a normal noise source:
+        %
+        %   Es = C/Rs where C is carrier power (energy per unit time) and Rs is the symbole rate
+        %   N  = NoB where N is the total noise power, No is the Noise spectral density is W/Hz
+        %        and B is the bandwidth of the noise which is Fs
+        %   No = N/Fs
+        %
+        % equating Es/No we get:
+        %
+        %   Es/No = (C/Rs)/(No/Fs)
+        %   No    = CFs/(Rs(Es/No))
+
+        variance = Fs/(Rs*EsNo);
+        Terrs = 0;  Tbits = 0;  Terrsldpc = 0;  Tbitsldpc = 0; Ferrsldpc = 0;
+        if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", Es, EsNo, variance);
+        end
+        
+        % init HF channel
+        sc = 1;
+
+        tx_filt_log = [];
+        rx_filt_log = [];
+        rx_baseband_log = [];
+        tx_baseband_log = [];
+        noise_log = [];
+        hf_angle_log = [];
+        tx_phase = rx_phase = 0;
+        tx_data_buffer = zeros(1,2*framesize);
+        s_data_buffer = zeros(1,2*Nsymb);
+        C_log = [];
+
+        for nn = 1: Ntrials
+                  
+            tx_bits = round( rand( 1, framesize*rate ) );
+            %tx_bits = [1 0 zeros(1,framesize*rate-2)];
+
+            % modulate
+
+            if ldpc_code
+                [tx_bits, s] = ldpc_enc(tx_bits, code_param);
+                t2 = tx_bits;
+                s2 = s;
+            else
+                s = zeros(1, Nsymb);
+                for i=1:Nsymb
+                    tx_symb = qpsk_mod(tx_bits(2*(i-1)+1:2*i));
+                    %printf("shift: %f prev_sym: %f  ", tx_symb, prev_sym_tx);
+                    if strcmp(modulation,'dqpsk')
+                        tx_symb *= prev_sym_tx;
+                        %printf("tx_symb: %f\n", tx_symb);
+                        prev_sym_tx = tx_symb;
+                    end 
+                    s(i) = tx_symb;
+                end
+            end
+            s_ch = s;
+
+            % root nyquist filter symbols
+
+            for k=1:Nsymb
+
+               % tx filter symbols
+
+               tx_filt = zeros(1,M);
+
+               % tx filter each symbol, generate M filtered output samples for each symbol.
+               % Efficient polyphase filter techniques used as tx_filter_memory is sparse
+
+               tx_filter_memory(Nfilter) = s_ch(k);
+
+               for i=1:M
+                   tx_filt(i) = M*tx_filter_memory(M:M:Nfilter) * hrn(M-i+1:M:Nfilter)';
+               end
+               tx_filter_memory(1:Nfilter-M) = tx_filter_memory(M+1:Nfilter);
+               tx_filter_memory(Nfilter-M+1:Nfilter) = zeros(1,M);
+               
+               % HF channel simulation
+
+               if hf_sim
+
+                   hf_sim_delay_line(1:Nhfdelay) = hf_sim_delay_line(M+1:M+Nhfdelay);
+                   hf_sim_delay_line(Nhfdelay+1:M+Nhfdelay) = tx_filt;
+
+                   % disable as a wrap around will cause a nasty phase jump.  Best to generate
+                   % longer files
+                   %if ((sc+M) > length(spread)) || ((sc+M) > length(spread_2ms))
+                   %    sc =1 ;
+                   %end
+                   comb = conj(spread(sc:sc+M-1))' + conj(spread_2ms(sc:sc+M-1))';
+                   if hf_phase_only
+                        tx_filt = tx_filt.*exp(j*angle(comb));
+                   else
+                       if hf_mag_only
+                           comb = conj(spread(sc:sc+M-1))' + conj(spread_2ms(sc:sc+M-1))';
+                           tx_filt = tx_filt.*abs(comb);   
+                       else
+                           % regular HF channel sim
+                           tx_filt = tx_filt.*conj(spread(sc:sc+M-1))' + hf_sim_delay_line(1:M).*conj(spread_2ms(sc:sc+M-1))';
+                       end
+                   end
+                   sc += M;
+                   % normalise so average HF power C=1
+
+                   if hf_phase_only == 0   % C already 1 if we are just tweaking phase
+                       tx_filt *= hf_gain;
+                   end
+                   C_log = [C_log abs(comb)*hf_gain];
+               end
+               tx_filt_log = [tx_filt_log tx_filt];
+               hf_angle_log = [hf_angle_log angle(comb)];
+
+               % AWGN noise and phase/freq offset channel simulation
+               % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+               noise = sqrt(variance*0.5)*( randn(1,M) + j*randn(1,M) );
+               noise_log = [noise_log noise];
+               rx_baseband = tx_filt.*exp(j*phase_offset) + noise;
+               phase_offset += w_offset;
+               
+               % rx filter symbol
+
+               rx_filter_memory(Nfilter-M+1:Nfilter) = rx_baseband;
+               rx_filt = rx_filter_memory * hrn';
+               rx_filter_memory(1:Nfilter-M) = rx_filter_memory(1+M:Nfilter);
+               rx_filt_log = [rx_filt_log rx_filt];
+
+               % delay in tx symbols to compensate for filtering
+               % delay, as tx symbols are used as pilot symbols input
+               % to phase est
+
+               s_delay_line_filt(1:Nfiltsym-1) = s_delay_line_filt(2:Nfiltsym);
+               s_delay_line_filt(Nfiltsym) = s(k);
+               s(k) = s_delay_line_filt(1);  
+
+               % delay in tx bits to compensate for filtering delay
+
+               tx_bits_delay_line_filt(1:(Nfiltsym-1)*bps) = tx_bits_delay_line_filt(bps+1:Nfiltsym*bps);
+               tx_bits_delay_line_filt((Nfiltsym-1)*bps+1:Nfiltsym*bps) = tx_bits((k-1)*bps+1:k*bps);
+               tx_bits((k-1)*bps+1:k*bps) = tx_bits_delay_line_filt(1:bps);
+
+               s_ch(k) = rx_filt;               
+            end
+
+            % coherent demod phase estimation and correction using pilot symbols
+            % cheating a bit here, we use fact that all tx-ed symbols are known
+
+            if phase_est
+                for i=1:Nsymb
+
+                    % delay line for phase est window
+
+                    r_delay_line(1:Nps-1) = r_delay_line(2:Nps);
+                    r_delay_line(Nps) = s_ch(i);
+
+                    % delay in tx data to compensate data for phase est window
+
+                    s_delay_line(1:Nps-1) = s_delay_line(2:Nps);
+                    s_delay_line(Nps) = s(i);
+                    tx_bits(2*(i-1)+1:2*i) = qpsk_demod(s_delay_line(floor(Nps/2)+1));
+
+                    % estimate phase from surrounding known pilot symbols and correct
+
+                    corr = 0; centre = floor(Nps/2)+1;
+                    for k=1:Ns:(Nps+1)
+                        if (k != centre)
+                            corr += s_delay_line(k) * r_delay_line(k)';
+                        end
+                    end
+                    s_ch(i) = r_delay_line(centre).*exp(j*angle(corr));
+               end    
+               %printf("corr: %f angle: %f\n", corr, angle(corr));
+            end
+
+            % de-modulate
+
+            rx_bits = zeros(1, framesize);
+            for i=1:Nsymb
+                rx_symb = s_ch(i);
+                if strcmp(modulation,'dqpsk')
+                    tmp = rx_symb;
+                    rx_symb *= conj(prev_sym_rx/abs(prev_sym_rx));
+                    prev_sym_rx = tmp;
+                end
+                rx_bits((2*(i-1)+1):(2*i)) = qpsk_demod(rx_symb);
+                rx_symb_log = [rx_symb_log rx_symb];
+            end
+
+            % Measure BER
+
+            % discard bits from first 2*Nfiltsym+Nps+1 symbols as tx
+            % and rx filter and phase est memories not full
+
+            skip = bps*(2*Nfiltsym+1+Nps+1);
+            if nn == 1
+                tx_bits_tmp = tx_bits(skip:length(tx_bits));
+                rx_bits_tmp = rx_bits(skip:length(rx_bits));
+            else
+                tx_bits_tmp = tx_bits;
+                rx_bits_tmp = rx_bits;
+           end
+
+            error_positions = xor( rx_bits_tmp, tx_bits_tmp );
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += length(tx_bits_tmp);
+
+            % Optionally LDPC decode
+            
+            if ldpc_code
+                % filter memories etc screw up frame alignment so we need to buffer a frame
+
+                tx_data_buffer(1:framesize) = tx_data_buffer(framesize+1:2*framesize);
+                s_data_buffer(1:Nsymb) = s_data_buffer(Nsymb+1:2*Nsymb);
+                tx_data_buffer(framesize+1:2*framesize) = tx_bits;
+                s_data_buffer(Nsymb+1:2*Nsymb) = s_ch;
+
+                offset = Nfiltsym-1;
+                if (phase_est)
+                    offset += floor(Nps/2);
+                end
+                st_tx = offset*bps+1;
+                st_s = offset;
+
+                detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, ...
+                                s_data_buffer(st_s+1:st_s+Nsymb), min(100,EsNo));
+
+                % ignore first frame as filter, phase est memories filling up
+                if nn != 1
+                    error_positions = xor( detected_data(1:framesize*rate), ...
+                                           tx_data_buffer(st_tx:st_tx+framesize*rate-1) );
+                    Nerrs = sum(error_positions);
+                    if Nerrs
+                        Ferrsldpc++;
+                    end
+                    Terrsldpc += Nerrs;
+                    Tbitsldpc += framesize*rate;
+                end
+            end
+
+        end
+    
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+        if ldpc_code
+            TERldpcvec(ne) = Terrsldpc;
+            FERldpcvec(ne) = Ferrsldpc;
+            BERldpcvec(ne) = Terrsldpc/Tbitsldpc;
+        end
+
+        if verbose 
+            printf("EsNo (dB): %f  Terrs: %d BER %f BER theory %f", Es, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)));
+            if ldpc_code
+                printf(" LDPC: Terrs: %d BER: %f Ferrs: %d FER: %f", 
+                       Terrsldpc, Terrsldpc/Tbitsldpc, Ferrsldpc, Ferrsldpc/(Ntrials-1));
+            end
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f BER theory %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), var(tx_filt_log), var(noise_log),
+                   var(tx_filt_log)/Rs, var(noise_log)/Fs, (var(tx_filt_log)/Rs)/(var(noise_log)/Fs));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    if ldpc_code
+        sim_out.BERldpcvec  = BERldpcvec;
+        sim_out.TERldpcvec  = TERldpcvec;
+        sim_out.FERldpcvec  = FERldpcvec;
+    end
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log(2*Nfiltsym:length(rx_symb_log)) .* exp(j*pi/4);
+        plot(real(scat), imag(scat),'+');
+
+        figure(3);
+        clf;
+
+        subplot(211)
+        plot(C_log);
+        subplot(212)
+        plot(hf_angle_log);
+        axis([1 10000 min(hf_angle_log) max(hf_angle_log)])
+    end
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+% Start simulations ---------------------------------------
+
+more off;
+sim_in.verbose = 2;
+
+sim_in.Esvec            = 5; 
+sim_in.Ntrials          = 100;
+sim_in.framesize        = 100;
+sim_in.Rs               = 400;
+sim_in.phase_offset     = 0;
+sim_in.phase_est        = 0;
+sim_in.w_offset         = 0;
+sim_in.plot_scatter     = 1;
+sim_in.hf_delay_ms      = 2;
+sim_in.hf_sim           = 1;
+sim_in.Np               = 6;
+sim_in.Ns               = 5;
+sim_in.hf_phase_only    = 0;
+sim_in.hf_mag_only      = 1;
+sim_in.ldpc_code        = 0;
+
+Ebvec = sim_in.Esvec - 10*log10(2);
+BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+
+sim_qpsk           = ber_test(sim_in, 'qpsk');
+
+figure(1); 
+clf;
+semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+hold on;
+semilogy(sim_qpsk.Ebvec, sim_qpsk.BERvec,'g;QPSK;')
+hold off;
+xlabel('Eb/N0')
+ylabel('BER')
+grid("minor")
+
+
+if 0
+sim_in.hf_mag_only      = 1;
+sim_qpsk_mag            = ber_test(sim_in, 'qpsk');
+
+sim_in.hf_mag_only      = 0;
+sim_in.hf_phase_only    = 1;
+sim_in.phase_est        = 1;
+sim_qpsk_phase          = ber_test(sim_in, 'qpsk');
+
+sim_in.hf_phase_only    = 0;
+sim_qpsk_coh_6_5        = ber_test(sim_in, 'qpsk');
+
+sim_in.phase_est        = 0;
+sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+
+figure(1); 
+clf;
+semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+hold on;
+semilogy(sim_qpsk_mag.Ebvec, sim_qpsk_mag.BERvec,'g;QPSK CCIR poor mag;')
+semilogy(sim_qpsk_phase.Ebvec, sim_qpsk_phase.BERvec,'k;QPSK CCIR poor phase;')
+semilogy(sim_qpsk_coh_6_5.Ebvec, sim_qpsk_coh_6_5.BERvec,'c;QPSK CCIR poor Np=6 Ns=5;')
+semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'b;DQPSK CCIR poor;')
+%semilogy(sim_qpsk_coh_5_24.Ebvec, sim_qpsk_coh_5_24.BERvec,'k;QPSK Ns=5 Np=24;')
+%semilogy(sim_qpsk_coh_2_12.Ebvec, sim_qpsk_coh_2_12.BERvec,'c;QPSK Ns=2 Np=12;')
+hold off;
+xlabel('Eb/N0')
+ylabel('BER')
+grid("minor")
+axis([min(Ebvec)-1 max(Ebvec)+1 1E-2 1])
+end
diff --git a/codec2/branches/0.7/octave/test_qpsk2.m b/codec2/branches/0.7/octave/test_qpsk2.m
new file mode 100644 (file)
index 0000000..978abfa
--- /dev/null
@@ -0,0 +1,641 @@
+% test_qps2k.m
+% David Rowe Feb 2014
+%
+% QPSK modem simulation, version 2.  Simplifed version of
+% test_qpsk. initially based on code by Bill Cowley Generates curves
+% BER versus E/No curves for different modems.  Design to test
+% coherent demodulation ideas on HF channels without building a full
+% blown modem.  Uses 'genie provided' estimates for timing estimation,
+% frame sync.
+
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    phase_est        = sim_in.phase_est;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_phase_only    = sim_in.hf_phase_only;
+    hf_mag_only      = sim_in.hf_mag_only;
+    Nc               = sim_in.Nc;
+
+    bps              = 2;
+    Nsymb            = framesize/bps;
+    prev_sym_tx      = qpsk_mod([0 0]);
+    prev_sym_rx      = qpsk_mod([0 0]);
+
+    phase_est_method = sim_in.phase_est_method;
+    if phase_est_method == 1
+      Nps            = sim_in.Np; 
+    else
+      Np             = sim_in.Np;
+      Ns             = sim_in.Ns;
+      if Np/2 == floor(Np/2)
+        printf("Np must be odd\n");
+        return;
+      end
+      Nps            = (Np-1)*Ns+1; 
+    end
+    r_delay_line     = zeros(Nc, Nps);
+    s_delay_line     = zeros(Nc, Nps);
+    ph_est_log       = [];
+
+    phase_noise_amp  = sim_in.phase_noise_amp;
+
+    ldpc_code = sim_in.ldpc_code;
+
+    tx_bits_buf = zeros(1,2*framesize);
+    rx_bits_buf = zeros(1,2*framesize);
+    rx_symb_buf = zeros(1,2*Nsymb);
+
+    % Init LDPC --------------------------------------------------------------------
+
+    if ldpc_code
+        % Start CML library
+
+        currentdir = pwd;
+        addpath '/home/david/tmp/cml/mat'    % assume the source files stored here
+        cd /home/david/tmp/cml
+        CmlStartup                           % note that this is not in the cml path!
+        cd(currentdir)
+  
+        % Our LDPC library
+
+        ldpc;
+
+        rate = sim_in.ldpc_code_rate; 
+        mod_order = 4; 
+        modulation = 'QPSK';
+        mapping = 'gray';
+
+        demod_type = 0;
+        decoder_type = 0;
+        max_iterations = 100;
+
+        code_param = ldpc_init(rate, framesize, modulation, mod_order, mapping);
+        code_param.code_bits_per_frame = framesize;
+        code_param.symbols_per_frame = framesize/bps;
+    else
+        rate = 1;
+    end
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;  Terrsldpc = 0;  Tbitsldpc = 0; Ferrsldpc = 0;
+
+        tx_symb_log      = [];
+        rx_symb_log      = [];
+        noise_log        = [];
+        mod_strip_log    = [];
+
+        % init HF channel
+
+        hf_n = 1;
+        hf_angle_log = [];
+        hf_fading = ones(1,Nsymb);             % default input for ldpc dec
+        hf_model = ones(Ntrials*Nsymb/Nc, Nc); % defaults for plotting surface
+
+        for nn = 1: Ntrials
+                  
+            tx_bits = round( rand( 1, framesize*rate ) );
+            % modulate --------------------------------------------
+
+            if ldpc_code
+                [tx_bits, s] = ldpc_enc(tx_bits, code_param);
+            else
+                s = zeros(1, Nsymb);
+                for i=1:Nsymb
+                    tx_symb = qpsk_mod(tx_bits(2*(i-1)+1:2*i));
+                    if strcmp(modulation,'dqpsk')
+                        tx_symb *= prev_sym_tx;
+                        prev_sym_tx = tx_symb;
+                    end 
+                    s(i) = tx_symb;
+                end
+            end
+            tx_bits_buf(1:framesize) = tx_bits_buf(framesize+1:2*framesize);
+            tx_bits_buf(framesize+1:2*framesize) = tx_bits;
+            s_ch = s;
+
+            % HF channel simulation  ------------------------------------
+            
+            if hf_sim
+
+                % separation between carriers.  Note this is
+                % effectively under samples at Rs, I dont think this
+                % matters.  Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                if Nsymb/Nc != floor(Nsymb/Nc)
+                    printf("Error: Nsymb/Nc must be an integrer\n")
+                    return;
+                end
+
+                % arrange symbols in Nsymb/Nc by Nc matrix
+
+                for i=1:Nc:Nsymb
+
+                    % Determine HF channel at each carrier for this symbol
+
+                    for k=1:Nc
+                        hf_model(hf_n, k) = hf_gain*(spread(hf_n) + exp(-j*k*wsep*nhfdelay)*spread_2ms(hf_n));
+                        hf_fading(i+k-1) = abs(hf_model(hf_n, k));
+                        if hf_mag_only
+                             s_ch(i+k-1) *= abs(hf_model(hf_n, k));
+                        else
+                             s_ch(i+k-1) *= hf_model(hf_n, k);
+                        end
+                    end
+                    hf_n++;
+                end
+            end
+            
+            tx_symb_log = [tx_symb_log s_ch];
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb) + j*randn(1,Nsymb));
+            noise_log = [noise_log noise];
+            phase_noise = phase_noise_amp*(2.0*rand(1,Nsymb)-1.0);
+            % organise into carriers to apply frequency and phase offset
+
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                 s_ch(i+k-1) = s_ch(i+k-1)*exp(j*(phase_offset+phase_noise(i+k-1))) + noise(i+k-1);
+              end 
+              phase_offset += w_offset;
+            end
+               
+            % phase estimation
+            
+            ph_est = zeros(Nc,1);
+
+            if phase_est
+
+                % organise into carriers
+
+                for i=1:Nc:Nsymb
+
+                  for k=1:Nc
+                      centre = floor(Nps/2)+1;
+
+                      % delay line for phase est window
+
+                      r_delay_line(k,1:Nps-1) = r_delay_line(k,2:Nps);
+                      r_delay_line(k,Nps) = s_ch(i+k-1);
+
+                      % delay in tx data to compensate data for phase est window
+
+                      s_delay_line(k,1:Nps-1) = s_delay_line(k,2:Nps);
+                      s_delay_line(k,Nps) = s(i+k-1);
+                      %tx_bits(2*(i+k-1-1)+1:2*(i+k-1)) = qpsk_demod(s_delay_line(k,centre));
+                      if phase_est_method == 1
+                        % QPSK modulation strip and phase est
+
+                        mod_strip_pol  = angle(r_delay_line(k,:)) * 4;
+                        mod_strip_rect = exp(j*mod_strip_pol);
+
+                        ph_est_pol = atan2(sum(imag(mod_strip_rect)),sum(real(mod_strip_rect)))/4;
+                        ph_est(k)  = exp(j*ph_est_pol);
+
+                        s_ch(i+k-1) = r_delay_line(k,centre).*exp(-j*ph_est_pol);
+                      else
+
+                        % estimate phase from surrounding known pilot symbols and correct
+
+                        corr = 0;
+                        for m=1:Ns:Nps
+                          if (m != centre)
+                            corr += s_delay_line(k,m) * r_delay_line(k,m)';
+                          end
+                        end
+                        ph_est(k)  = conj(corr/(1E-6+abs(corr)));
+                        s_ch(i+k-1) = r_delay_line(k,centre).*exp(j*angle(corr));
+                      end
+
+                  end
+                  
+                  ph_est_log = [ph_est_log ph_est];
+               end    
+               %printf("corr: %f angle: %f\n", corr, angle(corr));
+            end
+
+            % de-modulate
+
+            rx_bits = zeros(1, framesize);
+            for i=1:Nsymb
+                rx_symb = s_ch(i);
+                if strcmp(modulation,'dqpsk')
+                    tmp = rx_symb;
+                    rx_symb *= conj(prev_sym_rx/abs(prev_sym_rx));
+                    prev_sym_rx = tmp;
+                end
+                rx_bits((2*(i-1)+1):(2*i)) = qpsk_demod(rx_symb);
+                rx_symb_log = [rx_symb_log rx_symb];
+            end
+
+            rx_bits_buf(1:framesize) = rx_bits_buf(framesize+1:2*framesize);
+            rx_bits_buf(framesize+1:2*framesize) = rx_bits;
+            rx_symb_buf(1:Nsymb) = rx_symb_buf(Nsymb+1:2*Nsymb);
+            rx_symb_buf(Nsymb+1:2*Nsymb) = s_ch;
+
+            % determine location of start and end of frame depending on processing delays
+
+            if phase_est
+              st_rx_bits = 1+(floor(Nps/2)+1-1)*Nc*2;
+              st_rx_symb = 1+(floor(Nps/2)+1-1)*Nc;
+           else
+              st_rx_bits = 1;
+              st_rx_symb = 1;
+            end
+            en_rx_bits = st_rx_bits+framesize-1;
+            en_rx_symb = st_rx_symb+Nsymb-1;
+
+            if nn > 1
+              % Measure BER
+
+              %printf("nn: %d centre: %d\n", nn, floor(Nps/2)+1);
+              %tx_bits_buf(1:20)
+              %rx_bits_buf(st_rx_bits:st_rx_bits+20-1)
+              error_positions = xor(rx_bits_buf(st_rx_bits:en_rx_bits), tx_bits_buf(1:framesize));
+              Nerrs = sum(error_positions);
+              Terrs += Nerrs;
+              Tbits += length(tx_bits);
+
+              % Optionally LDPC decode
+            
+              if ldpc_code
+                detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, rx_symb_buf(st_rx_symb:en_rx_symb), min(100,EsNo), hf_fading);
+                %for m=1:20
+                %  printf("%f ", qpsk_demod(rx_symb_buf(m)));
+                %end
+                %detected_data(1:19)
+                error_positions = xor( detected_data(1:framesize*rate), tx_bits_buf(1:framesize*rate) );
+                Nerrs = sum(error_positions);
+                if Nerrs
+                    Ferrsldpc++;
+                end
+                Terrsldpc += Nerrs;
+                Tbitsldpc += framesize*rate;
+              end
+            end
+        end
+    
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+        if ldpc_code
+            TERldpcvec(ne) = Terrsldpc;
+            FERldpcvec(ne) = Ferrsldpc;
+            BERldpcvec(ne) = Terrsldpc/Tbitsldpc;
+        end
+
+        if verbose 
+            printf("EsNo (dB): %f  Terrs: %d BER %f BER theory %f", EsNodB, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)));
+            if ldpc_code
+                printf(" LDPC: Terrs: %d BER: %f Ferrs: %d FER: %f", 
+                       Terrsldpc, Terrsldpc/Tbitsldpc, Ferrsldpc, Ferrsldpc/(Ntrials-1));
+            end
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f BER theory %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), var(tx_symb_log), var(noise_log),
+                   var(tx_symb_log), var(noise_log), var(tx_symb_log)/var(noise_log));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    if ldpc_code
+        sim_out.BERldpcvec  = BERldpcvec;
+        sim_out.TERldpcvec  = TERldpcvec;
+        sim_out.FERldpcvec  = FERldpcvec;
+    end
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat(Nps*Nc:length(scat))), imag(scat(Nps*Nc:length(scat))),'+');
+        title('Scatter plot');
+
+        figure(3);
+        clf;
+        
+        y = 1:Rs*2;
+        x = 1:Nc;
+        EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+        mesh(x,y,EsNodBSurface);
+        grid
+        %axis([1 Nc 1 Rs*2 -10 10])
+        title('HF Channel Es/No');
+
+        figure(4);
+        clf;
+        %mesh(x,y,unwrap(angle(hf_model(y,:))));
+        subplot(211)
+        plot(y,abs(hf_model(y,1)))
+        title('HF Channel Carrier 1 Mag');
+        subplot(212)
+        plot(y,angle(hf_model(y,1)))
+        title('HF Channel Carrier 1 Phase');
+
+        if phase_est
+          scat = ph_est_log(1,floor(Nps/2):Rs*2+floor(Nps/2)-1);
+          hold on;
+          plot(angle(scat),'r');
+          hold off;
+
+          figure(5)
+          clf;
+          scat = ph_est_log(1,y);
+          plot(real(scat), imag(scat),'+');
+          title('Carrier 1 Phase Est');
+          axis([-1 1 -1 1])
+        end
+if 0        
+        figure(5);
+        clf;
+        subplot(211)
+        plot(real(spread));
+        hold on;
+        plot(imag(spread),'g');     
+        hold off;   
+        subplot(212)
+        plot(real(spread_2ms));
+        hold on;
+        plot(imag(spread_2ms),'g');     
+        hold off;   
+
+        figure(6)
+        tmp = [];
+        for i = 1:hf_n-1
+            tmp = [tmp abs(hf_model(i,:))];
+        end
+        hist(tmp);
+end
+     end
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+  sim_in.framesize        = 576;
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_phase_only    = 0;
+  sim_in.hf_mag_only      = 1;
+
+  sim_in.phase_est        = 0;
+  sim_in.phase_est_method = 1;
+  sim_in.Np               = 5;
+  sim_in.Ns               = 5;
+
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+endfunction
+
+function ideal
+
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 5; 
+  sim_in.hf_sim           = 1;
+  sim_in.Ntrials          = 30;
+
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 2:10; 
+  sim_in.ldpc_code        = 0;
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+  sim_qpsk                = ber_test(sim_in, 'qpsk');
+  sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+
+  sim_in.hf_sim           = 1;
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+  sim_dqpsk_hf            = ber_test(sim_in, 'dqpsk');
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.hf_sim           = 0;
+  sim_qpsk_ldpc           = ber_test(sim_in, 'qpsk');
+
+  sim_in.hf_sim           = 1;
+  sim_qpsk_hf_ldpc        = ber_test(sim_in, 'qpsk');
+  sim_in.hf_mag_only      = 0;
+  sim_dqpsk_hf_ldpc       = ber_test(sim_in, 'dqpsk');
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(sim_qpsk.Ebvec, sim_qpsk.BERvec,'g;QPSK AWGN;')
+  semilogy(sim_qpsk_hf.Ebvec, sim_qpsk_hf.BERvec,'r;QPSK HF;')
+  semilogy(sim_qpsk_ldpc.Ebvec, sim_qpsk_ldpc.BERldpcvec,'bk;QPSK HF;')
+  semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'g;DQPSK AWGN;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'r;DQPSK HF;')
+  semilogy(sim_qpsk_hf_ldpc.Ebvec, sim_qpsk_hf_ldpc.BERldpcvec,'b;QPSK HF LDPC 1/2;')
+  semilogy(sim_dqpsk_hf_ldpc.Ebvec, sim_dqpsk_hf_ldpc.BERldpcvec,'b;DQPSK HF LDPC 1/2;')
+
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+endfunction
+
+function phase_noise
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 100; 
+  sim_in.Ntrials          = 30;
+
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.phase_noise_amp  = pi/16;
+  tmp                     = ber_test(sim_in, 'qpsk');
+
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 2:8; 
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+
+  sim_in.phase_noise_amp = 0;
+  sim_qpsk               = ber_test(sim_in, 'qpsk');
+  sim_in.phase_noise_amp = pi/8;
+  sim_qpsk_pn8           = ber_test(sim_in, 'qpsk');
+  sim_in.phase_noise_amp = pi/16;
+  sim_qpsk_pn16          = ber_test(sim_in, 'qpsk');
+  sim_in.phase_noise_amp = pi/32;
+  sim_qpsk_pn32          = ber_test(sim_in, 'qpsk');
+
+  figure(1); 
+  clf;
+  semilogy(sim_qpsk.Ebvec, sim_qpsk.BERvec,'g;QPSK phase noise 0;')
+  hold on;
+  semilogy(sim_qpsk_pn8.Ebvec, sim_qpsk_pn8.BERvec,'c;QPSK phase noise +/- pi/8;')
+  semilogy(sim_qpsk_pn16.Ebvec, sim_qpsk_pn16.BERvec,'b;QPSK phase noise +/- pi/16;')
+  semilogy(sim_qpsk_pn32.Ebvec, sim_qpsk_pn32.BERvec,'k;QPSK phase noise +/- pi/32;')
+
+  semilogy(sim_qpsk.Ebvec, sim_qpsk.BERldpcvec,'g;QPSK phase noise 0 ldpc;')
+  semilogy(sim_qpsk_pn8.Ebvec, sim_qpsk_pn8.BERldpcvec,'c;QPSK phase noise +/- pi/8 ldpc;')
+  semilogy(sim_qpsk_pn16.Ebvec, sim_qpsk_pn16.BERldpcvec,'b;QPSK phase noise +/- pi/16 ldpc;')
+  semilogy(sim_qpsk_pn32.Ebvec, sim_qpsk_pn32.BERldpcvec,'k;QPSK phase noise +/- pi/32 ldpc;')
+
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-2 1])
+endfunction
+
+function test_phase_est
+  sim_in = standard_init();
+
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.phase_est        = 1;
+  sim_in.phase_est_method = 2;
+  sim_in.Np               = 3;
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 0;
+
+  tmp                     = ber_test(sim_in, 'qpsk');
+
+endfunction
+
+% Start simulations ---------------------------------------
+
+more off;
+
+ideal();
diff --git a/codec2/branches/0.7/octave/test_qpsk3.m b/codec2/branches/0.7/octave/test_qpsk3.m
new file mode 100644 (file)
index 0000000..447a205
--- /dev/null
@@ -0,0 +1,957 @@
+% test_qps3k.m
+% David Rowe March 2014
+%
+% QPSK modem simulation, version 2.  Simplifed version of
+% test_qpsk. Initially based on code by Bill Cowley Generates curves
+% BER versus E/No curves for different modems.  Design to test
+% coherent demodulation ideas on HF channels without building a full
+% blown modem.  Uses 'genie provided' estimates for timing estimation,
+% frame sync.
+%
+% Compared to test_qsk2.m this version supports phase estimation
+% (coherent demod)
+
+1;
+
+% main test function 
+
+function sim_out = ber_test(sim_in, modulation)
+    Fs = 8000;
+
+    newldpc          = sim_in.newldpc;
+    verbose          = sim_in.verbose;
+    framesize        = sim_in.framesize;
+    Ntrials          = sim_in.Ntrials;
+    Esvec            = sim_in.Esvec;
+    phase_offset     = sim_in.phase_offset;
+    phase_est        = sim_in.phase_est;
+    w_offset         = sim_in.w_offset;
+    plot_scatter     = sim_in.plot_scatter;
+    Rs               = sim_in.Rs;
+    hf_sim           = sim_in.hf_sim;
+    nhfdelay         = sim_in.hf_delay_ms*Rs/1000;
+    hf_phase_only    = sim_in.hf_phase_only;
+    hf_mag_only      = sim_in.hf_mag_only;
+    Nc               = sim_in.Nc;
+    sim_coh_dpsk     = sim_in.sim_coh_dpsk;
+
+    bps              = 2;
+    Nsymb            = framesize/bps;
+    for k=1:Nc
+      prev_sym_tx(k) = qpsk_mod([0 0]);
+      prev_sym_rx(k) = qpsk_mod([0 0]);
+    end
+
+    phase_est_method = sim_in.phase_est_method;
+    if phase_est_method == 2
+      Np             = sim_in.Np;
+      Ns             = sim_in.Ns;
+      if Np/2 == floor(Np/2)
+        printf("Np must be odd\n");
+        return;
+      end
+      Nps            = (Np-1)*Ns+1; 
+    else
+      Nps            = sim_in.Np; 
+    end
+    r_delay_line     = zeros(Nc, Nps);
+    s_delay_line     = zeros(Nc, Nps);
+    ph_est_log       = [];
+
+    phase_noise_amp  = sim_in.phase_noise_amp;
+
+    ldpc_code = sim_in.ldpc_code;
+
+    tx_bits_buf = zeros(1,2*framesize);
+    rx_bits_buf = zeros(1,2*framesize);
+    rx_symb_buf = zeros(1,2*Nsymb);
+    hf_fading_buf = zeros(1,2*Nsymb);
+
+    % Init LDPC --------------------------------------------------------------------
+
+    if ldpc_code
+        % Start CML library
+
+        currentdir = pwd;
+        addpath '/home/david/tmp/cml/mat'    % assume the source files stored here
+        cd /home/david/tmp/cml
+        CmlStartup                           % note that this is not in the cml path!
+        cd(currentdir)
+  
+        % Our LDPC library
+
+        ldpc;
+
+        rate = sim_in.ldpc_code_rate; 
+        mod_order = 4; 
+        modulation2 = 'QPSK';
+        mapping = 'gray';
+
+        demod_type = 0;
+        decoder_type = 0;
+        max_iterations = 100;
+
+        code_param = ldpc_init(rate, framesize, modulation2, mod_order, mapping);
+        code_param.code_bits_per_frame = framesize;
+        code_param.symbols_per_frame = framesize/bps;
+    else
+        rate = 1;
+    end
+
+    % Init HF channel model from stored sample files of spreading signal ----------------------------------
+
+    % convert "spreading" samples from 1kHz carrier at Fs to complex
+    % baseband, generated by passing a 1kHz sine wave through PathSim
+    % with the ccir-poor model, enabling one path at a time.
+    
+    Fc = 1000; M = Fs/Rs;
+    fspread = fopen("../raw/sine1k_2Hz_spread.raw","rb");
+    spread1k = fread(fspread, "int16")/10000;
+    fclose(fspread);
+    fspread = fopen("../raw/sine1k_2ms_delay_2Hz_spread.raw","rb");
+    spread1k_2ms = fread(fspread, "int16")/10000;
+    fclose(fspread);
+
+    % down convert to complex baseband
+    spreadbb = spread1k.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k))');
+    spreadbb_2ms = spread1k_2ms.*exp(-j*(2*pi*Fc/Fs)*(1:length(spread1k_2ms))');
+
+    % remove -2000 Hz image
+    b = fir1(50, 5/Fs);
+    spread = filter(b,1,spreadbb);
+    spread_2ms = filter(b,1,spreadbb_2ms);
+
+    % discard first 1000 samples as these were near 0, probably as
+    % PathSim states were ramping up
+
+    spread    = spread(1000:length(spread));
+    spread_2ms = spread_2ms(1000:length(spread_2ms));
+
+    % decimate down to Rs
+
+    spread = spread(1:M:length(spread));
+    spread_2ms = spread_2ms(1:M:length(spread_2ms));
+
+    % Determine "gain" of HF channel model, so we can normalise
+    % carrier power during HF channel sim to calibrate SNR.  I imagine
+    % different implementations of ccir-poor would do this in
+    % different ways, leading to different BER results.  Oh Well!
+
+    hf_gain = 1.0/sqrt(var(spread)+var(spread_2ms));
+
+    % Start Simulation ----------------------------------------------------------------
+
+    for ne = 1:length(Esvec)
+        EsNodB = Esvec(ne);
+        EsNo = 10^(EsNodB/10);
+    
+        variance = 1/EsNo;
+         if verbose > 1
+            printf("EsNo (dB): %f EsNo: %f variance: %f\n", EsNodB, EsNo, variance);
+        end
+        
+        Terrs = 0;  Tbits = 0;  Terrsldpc = 0;  Tbitsldpc = 0; Ferrsldpc = 0;
+
+        tx_symb_log      = [];
+        rx_symb_log      = [];
+        noise_log        = [];
+        mod_strip_log    = [];
+        
+        % init HF channel
+
+        hf_n = 1;
+        hf_angle_log = [];
+        hf_fading = ones(1,Nsymb);             % default input for ldpc dec
+        hf_model = ones(Ntrials*Nsymb/Nc, Nc); % defaults for plotting surface
+
+        sim_out.errors_log = [];
+        sim_out.ldpc_errors_log = [];
+
+        for nn = 1: Ntrials
+                  
+            tx_bits = round( rand( 1, framesize*rate ) );
+            % modulate --------------------------------------------
+
+            if ldpc_code
+                [tx_bits, s] = ldpc_enc(tx_bits, code_param);
+            end
+            s = zeros(1, Nsymb);
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                tx_symb = qpsk_mod(tx_bits(2*(i-1+k-1)+1:2*(i+k-1)));
+                if strcmp(modulation,'dqpsk')
+                    tx_symb *= prev_sym_tx(k);
+                    prev_sym_tx(k) = tx_symb;
+                end 
+                s(i+k-1) = tx_symb;
+              end
+            end
+            tx_bits_buf(1:framesize) = tx_bits_buf(framesize+1:2*framesize);
+            tx_bits_buf(framesize+1:2*framesize) = tx_bits;
+            s_ch = s;
+
+            % HF channel simulation  ------------------------------------
+            
+            if hf_sim
+
+                % separation between carriers.  Note this is
+                % effectively under samples at Rs, I dont think this
+                % matters.  Equivalent to doing freq shift at Fs, then
+                % decimating to Rs.
+
+                wsep = 2*pi*(1+0.5);  % e.g. 75Hz spacing at Rs=50Hz, alpha=0.5 filters
+
+                if Nsymb/Nc != floor(Nsymb/Nc)
+                    printf("Error: Nsymb/Nc must be an integrer\n")
+                    return;
+                end
+
+                % arrange symbols in Nsymb/Nc by Nc matrix
+
+                for i=1:Nc:Nsymb
+
+                    % Determine HF channel at each carrier for this symbol
+
+                    for k=1:Nc
+                        hf_model(hf_n, k) = hf_gain*(spread(hf_n) + exp(-j*k*wsep*nhfdelay)*spread_2ms(hf_n));
+                        hf_fading(i+k-1) = abs(hf_model(hf_n, k));
+                        if hf_mag_only
+                             s_ch(i+k-1) *= abs(hf_model(hf_n, k));
+                        else
+                             s_ch(i+k-1) *= hf_model(hf_n, k);
+                        end
+                    end
+                    hf_n++;
+                end
+            end
+            
+            tx_symb_log = [tx_symb_log s_ch];
+
+            % AWGN noise and phase/freq offset channel simulation
+            % 0.5 factor ensures var(noise) == variance , i.e. splits power between Re & Im
+
+            noise = sqrt(variance*0.5)*(randn(1,Nsymb) + j*randn(1,Nsymb));
+            noise_log = [noise_log noise];
+            phase_noise = phase_noise_amp*(2.0*rand(1,Nsymb)-1.0);
+            % organise into carriers to apply frequency and phase offset
+
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                 s_ch(i+k-1) = s_ch(i+k-1)*exp(j*(phase_offset+phase_noise(i+k-1))) + noise(i+k-1);
+              end 
+              phase_offset += w_offset;
+            end
+               
+            % phase estimation
+            
+            ph_est = zeros(Nc,1);
+
+            if phase_est
+
+                % organise into carriers
+
+                for i=1:Nc:Nsymb
+
+                  for k=1:Nc
+                      centre = floor(Nps/2)+1;
+
+                      % delay line for phase est window
+
+                      r_delay_line(k,1:Nps-1) = r_delay_line(k,2:Nps);
+                      r_delay_line(k,Nps) = s_ch(i+k-1);
+
+                      % delay in tx data to compensate data for phase est window
+
+                      s_delay_line(k,1:Nps-1) = s_delay_line(k,2:Nps);
+                      s_delay_line(k,Nps) = s(i+k-1);
+                      if phase_est_method == 1
+                        % QPSK modulation strip and phase est
+
+                        mod_strip_pol  = angle(r_delay_line(k,:)) * 4;
+                        mod_strip_rect = exp(j*mod_strip_pol);
+
+                        ph_est_pol = atan2(sum(imag(mod_strip_rect)),sum(real(mod_strip_rect)))/4;
+                        ph_est(k)  = exp(j*ph_est_pol);
+
+                        s_ch(i+k-1) = r_delay_line(k,centre).*exp(-j*ph_est_pol);
+                        % s_ch(i+k-1) = r_delay_line(k,centre);
+                     end
+
+                     if phase_est_method == 3
+                        % QPSK modulation strip and phase est with original symbol mags
+
+                        mod_strip_pol  = angle(r_delay_line(k,:)) * 4;
+                        mod_strip_rect = abs(r_delay_line(k,:)) .* exp(j*mod_strip_pol);
+
+                        ph_est_pol = atan2(sum(imag(mod_strip_rect)),sum(real(mod_strip_rect)))/4;
+                        ph_est(k)  = exp(j*ph_est_pol);
+
+                        s_ch(i+k-1) = r_delay_line(k,centre).*exp(-j*ph_est_pol);
+                        % s_ch(i+k-1) = r_delay_line(k,centre);
+                     end
+
+                     if phase_est_method == 2
+
+                        % estimate phase from surrounding known pilot symbols and correct
+
+                        corr = 0;
+                        for m=1:Ns:Nps
+                          if (m != centre)
+                            corr += s_delay_line(k,m) * r_delay_line(k,m)';
+                          end
+                        end
+                         ph_est(k)  = conj(corr/(1E-6+abs(corr)));
+                         s_ch(i+k-1) = r_delay_line(k,centre).*exp(j*angle(corr));
+                         %s_ch(i+k-1) = r_delay_line(k,centre);
+                     end
+
+                 end
+                  
+                  ph_est_log = [ph_est_log ph_est];
+               end    
+               %printf("corr: %f angle: %f\n", corr, angle(corr));
+            end
+
+            % de-modulate
+
+            rx_bits = zeros(1, framesize);
+            for i=1:Nc:Nsymb
+              for k=1:Nc
+                rx_symb = s_ch(i+k-1);
+                if strcmp(modulation,'dqpsk')
+                    tmp = rx_symb;
+                    rx_symb *= conj(prev_sym_rx(k)/abs(prev_sym_rx(k)));
+                    if sim_coh_dpsk
+                      prev_sym_rx(k) = qpsk_mod(qpsk_demod(tmp));
+                    else
+                      prev_sym_rx(k) = tmp;
+                    end
+                    s_ch(i+k-1) = rx_symb;
+                end
+                rx_bits((2*(i-1+k-1)+1):(2*(i+k-1))) = qpsk_demod(rx_symb);
+                rx_symb_log = [rx_symb_log rx_symb];
+              end
+            end
+
+if newldpc
+            rx_bits_buf(1:framesize) = rx_bits_buf(framesize+1:2*framesize);
+            rx_bits_buf(framesize+1:2*framesize) = rx_bits;
+            rx_symb_buf(1:Nsymb) = rx_symb_buf(Nsymb+1:2*Nsymb);
+            rx_symb_buf(Nsymb+1:2*Nsymb) = s_ch;
+            hf_fading_buf(1:Nsymb) = hf_fading_buf(Nsymb+1:2*Nsymb);
+            hf_fading_buf(Nsymb+1:2*Nsymb) = hf_fading;
+
+            % determine location of start and end of frame depending on processing delays
+
+            if phase_est
+              st_rx_bits = 1+(floor(Nps/2)+1-1)*Nc*2;
+              st_rx_symb = 1+(floor(Nps/2)+1-1)*Nc;
+            else
+              st_rx_bits = 1;
+              st_rx_symb = 1;
+            end
+            en_rx_bits = st_rx_bits+framesize-1;
+            en_rx_symb = st_rx_symb+Nsymb-1;
+
+            if nn > 1
+              % Measure BER
+
+              %printf("nn: %d centre: %d\n", nn, floor(Nps/2)+1);
+              %tx_bits_buf(1:20)
+              %rx_bits_buf(st_rx_bits:st_rx_bits+20-1)
+              error_positions = xor(rx_bits_buf(st_rx_bits:en_rx_bits), tx_bits_buf(1:framesize));
+              Nerrs = sum(error_positions);
+              sim_out.errors_log = [sim_out.errors_log error_positions];
+              Terrs += Nerrs;
+              Tbits += length(tx_bits);
+
+              % Optionally LDPC decode
+            
+              if ldpc_code
+                detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, ...
+                                         rx_symb_buf(st_rx_symb:en_rx_symb), min(100,EsNo), hf_fading_buf(1:Nsymb));
+                error_positions = xor( detected_data(1:framesize*rate), tx_bits_buf(1:framesize*rate) );
+                %detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, s_ch, min(100,EsNo), hf_fading);
+                %error_positions = xor( detected_data(1:framesize*rate), tx_bits(1:framesize*rate) );
+                Nerrs = sum(error_positions);
+                sim_out.ldpc_errors_log = [sim_out.ldpc_errors_log error_positions];
+                if Nerrs
+                    Ferrsldpc++;
+                end
+                Terrsldpc += Nerrs;
+                Tbitsldpc += framesize*rate;
+              end
+            end
+
+else    
+            error_positions = xor(rx_bits, tx_bits);
+            Nerrs = sum(error_positions);
+            Terrs += Nerrs;
+            Tbits += length(tx_bits);
+
+            % Optionally LDPC decode
+            
+            if ldpc_code
+                detected_data = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, s_ch, min(100,EsNo), hf_fading);
+                error_positions = xor( detected_data(1:framesize*rate), tx_bits(1:framesize*rate) );
+                Nerrs = sum(error_positions);
+                if Nerrs
+                    Ferrsldpc++;
+                end
+                Terrsldpc += Nerrs;
+                Tbitsldpc += framesize*rate;
+
+            end
+        end
+end
+
+        TERvec(ne) = Terrs;
+        BERvec(ne) = Terrs/Tbits;
+        if ldpc_code
+            TERldpcvec(ne) = Terrsldpc;
+            FERldpcvec(ne) = Ferrsldpc;
+            BERldpcvec(ne) = Terrsldpc/Tbitsldpc;
+        end
+
+        if verbose 
+            printf("EsNo (dB): %f  Terrs: %d BER %f BER theory %f", EsNodB, Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)));
+            if ldpc_code
+                printf(" LDPC: Terrs: %d BER: %f Ferrs: %d FER: %f", 
+                       Terrsldpc, Terrsldpc/Tbitsldpc, Ferrsldpc, Ferrsldpc/(Ntrials-1));
+            end
+            printf("\n");
+        end
+        if verbose > 1
+            printf("Terrs: %d BER %f BER theory %f C %f N %f Es %f No %f Es/No %f\n\n", Terrs,
+                   Terrs/Tbits, 0.5*erfc(sqrt(EsNo/2)), var(tx_symb_log), var(noise_log),
+                   var(tx_symb_log), var(noise_log), var(tx_symb_log)/var(noise_log));
+        end
+    end
+    
+    Ebvec = Esvec - 10*log10(bps);
+
+    % account for extra power rqd for pilot symbols
+
+    if (phase_est_method == 2) && (phase_est)
+      Ebvec += 10*log10(Ns/(Ns-1));
+    end
+
+    sim_out.BERvec          = BERvec;
+    sim_out.Ebvec           = Ebvec;
+    sim_out.TERvec          = TERvec;
+    if ldpc_code
+        sim_out.BERldpcvec  = BERldpcvec;
+        sim_out.TERldpcvec  = TERldpcvec;
+        sim_out.FERldpcvec  = FERldpcvec;
+    end
+
+    if plot_scatter
+        figure(2);
+        clf;
+        scat = rx_symb_log .* exp(j*pi/4);
+        plot(real(scat(Nps*Nc:length(scat))), imag(scat(Nps*Nc:length(scat))),'+');
+        title('Scatter plot');
+
+        figure(3);
+        clf;
+        
+        y = 1:Rs*2;
+        x = 1:Nc;
+        EsNodBSurface = 20*log10(abs(hf_model(y,:))) - 10*log10(variance);
+        mesh(x,y,EsNodBSurface);
+        grid
+        %axis([1 Nc 1 Rs*2 -10 10])
+        title('HF Channel Es/No');
+
+        figure(4);
+        clf;
+        %mesh(x,y,unwrap(angle(hf_model(y,:))));
+        subplot(211)
+        plot(y,abs(hf_model(y,1)))
+        title('HF Channel Carrier 1 Mag');
+        subplot(212)
+        plot(y,angle(hf_model(y,1)))
+        title('HF Channel Carrier 1 Phase');
+
+        if phase_est
+          scat = ph_est_log(1,floor(Nps/2):Rs*2+floor(Nps/2)-1);
+          hold on;
+          plot(angle(scat),'r');
+          hold off;
+
+          figure(5)
+          clf;
+          scat = ph_est_log(1,y);
+          plot(real(scat), imag(scat),'+');
+          title('Carrier 1 Phase Est');
+          axis([-1 1 -1 1])
+        end
+if 0        
+        figure(5);
+        clf;
+        subplot(211)
+        plot(real(spread));
+        hold on;
+        plot(imag(spread),'g');     
+        hold off;   
+        subplot(212)
+        plot(real(spread_2ms));
+        hold on;
+        plot(imag(spread_2ms),'g');     
+        hold off;   
+
+        figure(6)
+        tmp = [];
+        for i = 1:hf_n-1
+            tmp = [tmp abs(hf_model(i,:))];
+        end
+        hist(tmp);
+end
+     end
+
+size(sim_out.errors_log)
+
+endfunction
+
+% Gray coded QPSK modulation function
+
+function symbol = qpsk_mod(two_bits)
+    two_bits_decimal = sum(two_bits .* [2 1]); 
+    switch(two_bits_decimal)
+        case (0) symbol =  1;
+        case (1) symbol =  j;
+        case (2) symbol = -j;
+        case (3) symbol = -1;
+    endswitch
+endfunction
+
+% Gray coded QPSK demodulation function
+
+function two_bits = qpsk_demod(symbol)
+    if isscalar(symbol) == 0
+        printf("only works with scalars\n");
+        return;
+    end
+    bit0 = real(symbol*exp(j*pi/4)) < 0;
+    bit1 = imag(symbol*exp(j*pi/4)) < 0;
+    two_bits = [bit1 bit0];
+endfunction
+
+function sim_in = standard_init
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+  sim_in.framesize        = 576;
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.phase_noise_amp  = 0;
+
+  sim_in.hf_delay_ms      = 2;
+  sim_in.hf_sim           = 0;
+  sim_in.hf_phase_only    = 0;
+  sim_in.hf_mag_only      = 1;
+
+  sim_in.phase_est        = 0;
+  sim_in.phase_est_method = 1;
+  sim_in.Np               = 5;
+  sim_in.Ns               = 5;
+
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+endfunction
+
+function ideal
+
+  sim_in = standard_init();
+
+  sim_in.sim_coh_dpsk     = 0;
+  sim_in.newldpc          = 1;
+  sim_in.verbose          = 2;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 5; 
+  sim_in.hf_sim           = 1;
+  sim_in.Ntrials          = 30;
+
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+
+  sim_in.hf_sim           = 0;
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 2:15; 
+  sim_in.ldpc_code        = 0;
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+  sim_qpsk                = ber_test(sim_in, 'qpsk');
+  sim_dqpsk               = ber_test(sim_in, 'dqpsk');
+
+  sim_in.hf_sim           = 1;
+  sim_in.Esvec            = 2:15; 
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+  sim_dqpsk_hf            = ber_test(sim_in, 'dqpsk');
+  sim_in.ldpc_code        = 1;
+  sim_in.ldpc_code_rate   = 3/4;
+  sim_qpsk_hf_ldpc1       = ber_test(sim_in, 'qpsk');
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_qpsk_hf_ldpc2       = ber_test(sim_in, 'qpsk');
+  sim_in.ldpc_code_rate   = 3/4;
+  sim_in.hf_sim           = 0;
+  sim_qpsk_awgn_ldpc      = ber_test(sim_in, 'qpsk');
+
+  figure(1); 
+  clf;
+  semilogy(Ebvec, BER_theory,'r;QPSK theory;')
+  hold on;
+  semilogy(sim_qpsk.Ebvec, sim_qpsk.BERvec,'g;QPSK AWGN;')
+  semilogy(sim_qpsk_hf.Ebvec, sim_qpsk_hf.BERvec,'r;QPSK HF;')
+  semilogy(sim_dqpsk.Ebvec, sim_dqpsk.BERvec,'c;DQPSK AWGN;')
+  semilogy(sim_dqpsk_hf.Ebvec, sim_dqpsk_hf.BERvec,'m;DQPSK HF;')
+  semilogy(sim_qpsk_hf_ldpc1.Ebvec, sim_qpsk_hf_ldpc1.BERldpcvec,'k;QPSK HF LDPC 3/4;')
+  semilogy(sim_qpsk_hf_ldpc2.Ebvec, sim_qpsk_hf_ldpc2.BERldpcvec,'b;QPSK HF LDPC 1/2;')
+  semilogy(sim_qpsk_awgn_ldpc.Ebvec, sim_qpsk_awgn_ldpc.BERldpcvec,'k;QPSK AWGN LDPC 3/4;')
+
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-3 1])
+endfunction
+
+function phase_noise
+  sim_in = standard_init();
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 100; 
+  sim_in.Ntrials          = 100;
+
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.phase_noise_amp  = pi/16;
+  tmp                     = ber_test(sim_in, 'qpsk');
+
+  sim_in.plot_scatter     = 0;
+  sim_in.Esvec            = 2:8; 
+  sim_qpsk_hf             = ber_test(sim_in, 'qpsk');
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+  BER_theory = 0.5*erfc(sqrt(10.^(Ebvec/10)));
+
+  sim_in.phase_noise_amp = 0;
+  sim_qpsk               = ber_test(sim_in, 'qpsk');
+  sim_in.phase_noise_amp = pi/8;
+  sim_qpsk_pn8           = ber_test(sim_in, 'qpsk');
+  sim_in.phase_noise_amp = pi/16;
+  sim_qpsk_pn16          = ber_test(sim_in, 'qpsk');
+  sim_in.phase_noise_amp = pi/32;
+  sim_qpsk_pn32          = ber_test(sim_in, 'qpsk');
+
+  figure(1); 
+  clf;
+  semilogy(sim_qpsk.Ebvec, sim_qpsk.BERvec,'g;QPSK phase noise 0;')
+  hold on;
+  semilogy(sim_qpsk_pn8.Ebvec, sim_qpsk_pn8.BERvec,'c;QPSK phase noise +/- pi/8;')
+  semilogy(sim_qpsk_pn16.Ebvec, sim_qpsk_pn16.BERvec,'b;QPSK phase noise +/- pi/16;')
+  semilogy(sim_qpsk_pn32.Ebvec, sim_qpsk_pn32.BERvec,'k;QPSK phase noise +/- pi/32;')
+
+  semilogy(sim_qpsk.Ebvec, sim_qpsk.BERldpcvec,'g;QPSK phase noise 0 ldpc;')
+  semilogy(sim_qpsk_pn8.Ebvec, sim_qpsk_pn8.BERldpcvec,'c;QPSK phase noise +/- pi/8 ldpc;')
+  semilogy(sim_qpsk_pn16.Ebvec, sim_qpsk_pn16.BERldpcvec,'b;QPSK phase noise +/- pi/16 ldpc;')
+  semilogy(sim_qpsk_pn32.Ebvec, sim_qpsk_pn32.BERldpcvec,'k;QPSK phase noise +/- pi/32 ldpc;')
+
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-2 1])
+endfunction
+
+function phase_est_hf
+  sim_in = standard_init();
+
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5:15; 
+  sim_in.Ntrials          = 100;
+
+  sim_in.newldpc          = 1;
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.phase_est        = 0;
+  sim_in.sim_coh_dpsk     = 0;
+  sim_in.phase_est_method = 2;
+  sim_in.Np               = 3;
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 1;
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+
+  baseline                = ber_test(sim_in, 'qpsk');
+
+  sim_in.hf_mag_only      = 0;
+  sim_in.phase_est_method = 2;
+  sim_in.phase_est        = 1;
+  sim_in.Np               = 3;
+  pilot_3                 = ber_test(sim_in, 'qpsk');
+  sim_in.Np               = 5;
+  pilot_5                 = ber_test(sim_in, 'qpsk');
+  sim_in.Np               = 7;
+  pilot_7                 = ber_test(sim_in, 'qpsk');
+
+if 1
+  sim_in.phase_est        = 0;
+  dqpsk                   = ber_test(sim_in, 'dqpsk');
+
+  figure(1); 
+  clf;
+  semilogy(baseline.Ebvec, baseline.BERvec,'r;QPSK CCIR poor;')
+  hold on;
+  semilogy(baseline.Ebvec, baseline.BERldpcvec,'r;QPSK CCIR poor ldpc;')
+  semilogy(pilot_3.Ebvec, pilot_3.BERvec,'b;QPSK CCIR poor ldpc pilot 3;')
+  semilogy(pilot_3.Ebvec, pilot_3.BERldpcvec,'b;QPSK CCIR poor ldpc pilot 3;')
+  semilogy(pilot_5.Ebvec, pilot_5.BERvec,'g;QPSK CCIR poor ldpc pilot 5;')
+  semilogy(pilot_5.Ebvec, pilot_5.BERldpcvec,'g;QPSK CCIR poor ldpc pilot 5;')
+  semilogy(pilot_7.Ebvec, pilot_7.BERvec,'m;QPSK CCIR poor ldpc pilot 7;')
+  semilogy(pilot_7.Ebvec, pilot_7.BERldpcvec,'m;QPSK CCIR poor ldpc pilot 7;')
+  semilogy(dqpsk.Ebvec, dqpsk.BERvec,'k;DQPSK CCIR poor ldpc;')
+  semilogy(dqpsk.Ebvec, dqpsk.BERldpcvec,'k;DQPSK CCIR poor ldpc;')
+
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-2 1])
+end
+endfunction
+
+function phase_est_awgn
+  sim_in = standard_init();
+
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 0:0.5:3; 
+  sim_in.Ntrials          = 30;
+
+  sim_in.newldpc          = 1;
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.phase_est        = 0;
+  sim_in.phase_est_method = 1;
+  sim_in.Np               = 3;
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 1;
+
+  ideal                   = ber_test(sim_in, 'qpsk');
+
+  sim_in.phase_est        = 1;
+  sim_in.Np               = 21;
+  sim_in.phase_est_method = 3;
+  strip_21_mag            = ber_test(sim_in, 'qpsk');
+
+  sim_in.Np               = 41;
+  strip_41_mag            = ber_test(sim_in, 'qpsk');
+
+  sim_in.phase_est_method = 1;
+  sim_in.Np               = 21;
+  strip_21                = ber_test(sim_in, 'qpsk');
+
+  sim_in.Np               = 41;
+  strip_41                = ber_test(sim_in, 'qpsk');
+
+  sim_in.Np               = 7;
+  sim_in.phase_est_method = 2;
+  pilot_7                 = ber_test(sim_in, 'qpsk');
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+
+  figure(1); 
+  clf;
+  semilogy(ideal.Ebvec, ideal.BERvec,'r;QPSK;')
+  hold on;
+  semilogy(ideal.Ebvec, ideal.BERldpcvec,'r;QPSK LDPC;')
+  semilogy(strip_21.Ebvec, strip_21.BERvec,'g;QPSK strip 21;')
+  semilogy(strip_21.Ebvec, strip_21.BERldpcvec,'g;QPSK LDPC strip 21;')
+  semilogy(strip_41.Ebvec, strip_41.BERvec,'b;QPSK strip 41;')
+  semilogy(strip_41.Ebvec, strip_41.BERldpcvec,'b;QPSK LDPC strip 41;')
+  semilogy(strip_21_mag.Ebvec, strip_21_mag.BERvec,'m;QPSK strip 21 mag;')
+  semilogy(strip_21_mag.Ebvec, strip_21_mag.BERldpcvec,'m;QPSK LDPC strip 21 mag;')
+  semilogy(strip_41_mag.Ebvec, strip_41_mag.BERvec,'c;QPSK strip 41 mag;')
+  semilogy(strip_41_mag.Ebvec, strip_41_mag.BERldpcvec,'c;QPSK LDPC strip 41 mag;')
+  semilogy(pilot_7.Ebvec, pilot_7.BERvec,'k;QPSK pilot 7;')
+  semilogy(pilot_7.Ebvec, pilot_7.BERldpcvec,'k;QPSK LDPC pilot 7;')
+
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-2 1])
+endfunction
+
+function test_dpsk
+  sim_in = standard_init();
+
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 8;
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 5; 
+  sim_in.Ntrials          = 30;
+
+  sim_in.newldpc          = 1;
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.phase_est        = 0;
+  sim_in.phase_est_method = 3;
+  sim_in.Np               = 41;
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.sim_coh_dpsk     = 0;
+
+  sim_in.hf_sim           = 0;
+  sim_in.hf_mag_only      = 1;
+
+  Ebvec = sim_in.Esvec - 10*log10(2);
+
+  baseline                = ber_test(sim_in, 'qpsk');
+  sim_in.phase_est        = 0;
+  dqpsk                   = ber_test(sim_in, 'dqpsk');
+
+  sim_in.phase_est        = 1;
+  sim_in.phase_est_method = 3;
+  sim_in.sim_coh_dpsk     = 1;
+  sim_in.Np               = 41;
+  dqpsk_strip_41          = ber_test(sim_in, 'dqpsk');
+  
+  figure(1); 
+  clf;
+  semilogy(baseline.Ebvec, baseline.BERvec,'r;QPSK CCIR poor;')
+  hold on;
+  semilogy(baseline.Ebvec, baseline.BERldpcvec,'r;QPSK CCIR poor ldpc;')
+  semilogy(dqpsk.Ebvec, dqpsk.BERvec,'c;DQPSK CCIR poor ldpc;')
+  semilogy(dqpsk.Ebvec, dqpsk.BERldpcvec,'c;DQPSK CCIR poor ldpc;')
+  semilogy(dqpsk_strip_41.Ebvec, dqpsk_strip_41.BERvec,'m;DQPSK CCIR poor ldpc strip 41;')
+  semilogy(dqpsk_strip_41.Ebvec, dqpsk_strip_41.BERldpcvec,'m;DQPSK CCIR poor ldpc strip 41;')
+
+  hold off;
+  xlabel('Eb/N0')
+  ylabel('BER')
+  grid("minor")
+  axis([min(Ebvec) max(Ebvec) 1E-2 1])
+
+endfunction
+
+function gen_error_pattern_qpsk()
+  sim_in = standard_init();
+
+  % model codec and uncoded streams as 1000 bit/s each
+
+  sim_in.Rs               = 100;
+  sim_in.Nc               = 4;
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 0;
+
+  sim_in.Esvec            = 10; % Eb/No=2dB
+  sim_in.Ntrials          = 30;
+
+  sim_in.newldpc          = 1;
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 1;
+
+  sim_in.phase_est        = 1;
+  sim_in.phase_est_method = 2;
+  sim_in.Np               = 5;
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.sim_coh_dpsk     = 0;
+
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 0;
+
+  qpsk                    = ber_test(sim_in, 'qpsk');
+  length(qpsk.errors_log) 
+  length(qpsk.ldpc_errors_log)
+  % multiplex errors into prot and unprot halves of 52 bit codec frames
+
+  error_pattern = [];
+  for i=1:26:length(qpsk.ldpc_errors_log)-52
+    error_pattern = [error_pattern qpsk.ldpc_errors_log(i:i+25) qpsk.errors_log(i:i+25)  zeros(1,4)];
+    %error_pattern = [error_pattern qpsk.ldpc_errors_log(i:i+25) zeros(1,26)  zeros(1,4)];
+    %error_pattern = [error_pattern zeros(1,26) qpsk.errors_log(i:i+25)  zeros(1,4)];
+  end
+
+  fep=fopen("qpsk_errors_2dB.bin","wb"); fwrite(fep, error_pattern, "short"); fclose(fep);
+
+endfunction
+
+function gen_error_pattern_dpsk()
+  sim_in = standard_init();
+
+  sim_in.Rs               = 50;
+  sim_in.Nc               = 16;
+
+  sim_in.verbose          = 1;
+  sim_in.plot_scatter     = 1;
+
+  sim_in.Esvec            = 10; % Eb/No=Es/No-3
+  sim_in.Ntrials          = 30;
+
+  sim_in.newldpc          = 1;
+  sim_in.ldpc_code_rate   = 1/2;
+  sim_in.ldpc_code        = 0;
+
+  sim_in.phase_est        = 0;
+  sim_in.phase_est_method = 3;
+  sim_in.Np               = 41;
+  sim_in.phase_offset     = 0;
+  sim_in.w_offset         = 0;
+  sim_in.sim_coh_dpsk     = 0;
+
+  sim_in.hf_sim           = 1;
+  sim_in.hf_mag_only      = 1;
+
+  dqpsk                    = ber_test(sim_in, 'dqpsk');
+  fep=fopen("dqpsk_errors_12dB.bin","wb"); fwrite(fep, dqpsk.errors_log, "short"); fclose(fep);
+
+endfunction
+
+% Start simulations ---------------------------------------
+
+more off;
+
+ideal();
+%phase_est_hf();
+%phase_est_awgn();
+%test_dpsk();
+%gen_error_pattern_qpsk
diff --git a/codec2/branches/0.7/octave/tfdmdv.m b/codec2/branches/0.7/octave/tfdmdv.m
new file mode 100644 (file)
index 0000000..c338fca
--- /dev/null
@@ -0,0 +1,306 @@
+% tfdmdv.m
+%
+% Octave script that tests the C port of the FDMDV modem.  This script loads
+% the output of unittest/tfdmdv.c and compares it to the output of the
+% reference versions of the same functions written in Octave.
+%
+% Usage:
+%
+%   1/ In codec2-dev/CMakeLists.txt, ensure set(CMAKE_BUILD_TYPE "Debug"), to
+%      enable building the C unittests.  Build codec2-dev as per 
+%      codec2-dev/README.
+%
+%   2/ Run the C side from the Octave directory:
+%
+%        codec2-dev/octave$ ../build_linux/unittest/tfdmdv
+%        codec2-dev/octave$ ls -l tfdmdv_out.txt
+%         -rw-rw-r-- 1 david david 3419209 Aug 27 10:05 tfdmdv_out.txt
+%
+%   3/ Run the Octave side (this script):
+%
+%        octave:1> tfdmdv
+%
+
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+more off
+format
+
+fdmdv;                 % load modem code
+autotest;              % automatic testing library
+
+
+% init fdmdv modem states and load up a few constants in this scope for convenience
+
+f = fdmdv_init;
+Nc = f.Nc;
+Nb = f.Nb;
+M  = f.M;
+Fs = f.Fs;
+P  = f.P;
+Q  = f.Q;
+
+% Generate reference vectors using Octave implementation of FDMDV modem
+
+global passes = fails = 0;
+frames = 35;
+prev_tx_symbols = ones(Nc+1,1); prev_tx_symbols(Nc+1) = 2;
+prev_rx_symbols = ones(Nc+1,1);
+foff_phase_rect = 1;
+channel = [];
+channel_count = 0;
+next_nin = M;
+sig_est = zeros(Nc+1,1);
+noise_est = zeros(Nc+1,1);
+
+sync = 0;
+fest_state = 0;
+fest_timer = 0;
+sync_mem = zeros(1,f.Nsync_mem);
+
+% Octave outputs we want to collect for comparison to C version
+
+tx_bits_log = [];
+tx_symbols_log = [];
+tx_baseband_log = [];
+tx_fdm_log = [];
+pilot_baseband1_log = [];
+pilot_baseband2_log = [];
+pilot_lpf1_log = [];
+pilot_lpf2_log = [];
+S1_log = [];
+S2_log = [];
+foff_coarse_log = [];
+foff_fine_log = [];
+foff_log = [];
+rx_fdm_filter_log = [];
+rx_filt_log = [];
+env_log = [];
+rx_timing_log = [];
+phase_difference_log = [];
+rx_symbols_log = [];
+rx_bits_log = []; 
+sync_bit_log = [];  
+sync_log = [];  
+nin_log = [];
+sig_est_log = [];
+noise_est_log = [];
+
+% adjust this if the screen is getting a bit cluttered
+
+global no_plot_list = [1 2 3 4 5 6 7 8 12 13 14 15 16];
+
+for fr=1:frames
+
+  % modulator
+
+  [tx_bits f] = get_test_bits(f, Nc*Nb);
+  tx_bits_log = [tx_bits_log tx_bits];
+  [tx_symbols f] = bits_to_psk(f, prev_tx_symbols, tx_bits, 'dqpsk');
+  prev_tx_symbols = tx_symbols;
+  tx_symbols_log = [tx_symbols_log tx_symbols];
+  [tx_baseband f] = tx_filter(f, tx_symbols);
+  tx_baseband_log = [tx_baseband_log tx_baseband];
+  [tx_fdm f] = fdm_upconvert(f, tx_baseband);
+  tx_fdm_log = [tx_fdm_log tx_fdm];
+
+  % channel
+
+  nin = next_nin;
+
+  % nin = M;  % when debugging good idea to uncomment this to "open loop"
+
+  channel = [channel real(tx_fdm)];
+  channel_count += M;
+  rx_fdm = channel(1:nin);
+  channel = channel(nin+1:channel_count);
+  channel_count -= nin;
+
+  % demodulator --------------------------------------------
+
+  % shift down to complex baseband
+
+  for i=1:nin
+    f.fbb_phase_rx = f.fbb_phase_rx*f.fbb_rect';
+    rx_fdm(i) = rx_fdm(i)*f.fbb_phase_rx;
+  end
+  mag = abs(f.fbb_phase_rx);
+  f.fbb_phase_rx /= mag;
+
+  % sync = 0; % when debugging good idea to uncomment this to "open loop"
+
+  [pilot prev_pilot f.pilot_lut_index f.prev_pilot_lut_index] = get_pilot(f, f.pilot_lut_index, f.prev_pilot_lut_index, nin);
+  [foff_coarse S1 S2 f] = rx_est_freq_offset(f, rx_fdm, pilot, prev_pilot, nin, !sync);
+
+  if sync == 0
+    foff = foff_coarse;
+  end
+  foff_coarse_log = [foff_coarse_log foff_coarse];
+
+  pilot_baseband1_log = [pilot_baseband1_log f.pilot_baseband1];
+  pilot_baseband2_log = [pilot_baseband2_log f.pilot_baseband2];
+  pilot_lpf1_log = [pilot_lpf1_log f.pilot_lpf1];
+  pilot_lpf2_log = [pilot_lpf2_log f.pilot_lpf2];
+  S1_log  = [S1_log S1];
+  S2_log  = [S2_log S2];
+
+  foff_rect = exp(j*2*pi*foff/Fs);
+
+  for i=1:nin
+    foff_phase_rect *= foff_rect';
+    rx_fdm_fcorr(i) = rx_fdm(i)*foff_phase_rect;
+  end
+
+  [rx_fdm_filter f] = rxdec_filter(f, rx_fdm_fcorr, nin);
+  [rx_filt f] = down_convert_and_rx_filter(f, rx_fdm_filter, nin, M/Q);
+  #{
+  for i=1:5
+    printf("[%d] rx_fdm_fcorr: %f %f rx_fdm_filter: %f %f\n", i,
+           real(rx_fdm_fcorr(i)), imag(rx_fdm_fcorr(i)), real(rx_fdm_filter(i)), imag(rx_fdm_filter(i)));
+  end
+  for i=1:5
+    printf("[%d] rx_fdm_fcorr: %f %f rxdec_lpf_mem: %f %f\n", i,
+           real(rx_fdm_fcorr(i)), imag(rx_fdm_fcorr(i)), real(f.rxdec_lpf_mem(i)), imag(f.rxdec_lpf_mem(i)));
+  end
+  #}
+  rx_filt_log = [rx_filt_log rx_filt];
+  rx_fdm_filter_log = [rx_fdm_filter_log rx_fdm_filter];
+
+  [rx_symbols rx_timing env f] = rx_est_timing(f, rx_filt, nin);
+  env_log = [env_log env];
+  rx_timing_log = [rx_timing_log rx_timing];
+  rx_symbols_log = [rx_symbols_log rx_symbols];
+
+  next_nin = M;
+  if rx_timing > 2*M/P
+     next_nin += M/P;
+  end
+  if rx_timing < 0;
+     next_nin -= M/P;
+  end
+  nin_log = [nin_log nin];
+
+  [rx_bits sync_bit foff_fine pd] = psk_to_bits(f, prev_rx_symbols, rx_symbols, 'dqpsk');
+  phase_difference_log = [phase_difference_log pd];
+
+  foff_fine_log = [foff_fine_log foff_fine];
+  foff -= 0.5*foff_fine;
+  foff_log = [foff_log foff];
+
+  [sig_est noise_est] = snr_update(f, sig_est, noise_est, pd);
+  sig_est_log = [sig_est_log sig_est];
+  noise_est_log = [noise_est_log noise_est];
+
+  prev_rx_symbols = rx_symbols;
+  rx_bits_log = [rx_bits_log rx_bits]; 
+  sync_bit_log = [sync_bit_log sync_bit];  
+
+  % freq est state machine
+
+  [sync reliable_sync_bit fest_state fest_timer sync_mem] = freq_state(f, sync_bit, fest_state, fest_timer, sync_mem);
+  sync_log = [sync_log sync];
+end
+
+% Compare to the output from the C version
+
+load tfdmdv_out.txt
+
+
+% ---------------------------------------------------------------------------------------
+% Plot output and test each C function
+% ---------------------------------------------------------------------------------------
+
+% fdmdv_get_test_bits() & bits_to_dqpsk_symbols()
+
+n = 28;
+stem_sig_and_error(1, 211, tx_bits_log_c(1:n), tx_bits_log(1:n) - tx_bits_log_c(1:n), 'tx bits', [1 n -1.5 1.5])
+stem_sig_and_error(1, 212, real(tx_symbols_log_c(1:n/2)), real(tx_symbols_log(1:n/2) - tx_symbols_log_c(1:n/2)), 'tx symbols real', [1 n/2 -1.5 1.5])
+
+% fdm_upconvert()
+
+plot_sig_and_error(3, 211, real(tx_fdm_log_c), real(tx_fdm_log - tx_fdm_log_c), 'tx fdm real')
+plot_sig_and_error(3, 212, imag(tx_fdm_log_c), imag(tx_fdm_log - tx_fdm_log_c), 'tx fdm imag')
+
+% generate_pilot_lut()
+
+plot_sig_and_error(4, 211, real(pilot_lut_c), real(f.pilot_lut - pilot_lut_c), 'pilot lut real')
+plot_sig_and_error(4, 212, imag(pilot_lut_c), imag(f.pilot_lut - pilot_lut_c), 'pilot lut imag')
+
+% rx_est_freq_offset()
+
+st=1;  en = 5*f.Npilotbaseband;
+plot_sig_and_error(5, 211, real(pilot_baseband1_log(st:en)), real(pilot_baseband1_log(st:en) - pilot_baseband1_log_c(st:en)), 'pilot baseband1 real' )
+plot_sig_and_error(5, 212, real(pilot_baseband2_log(st:en)), real(pilot_baseband2_log(st:en) - pilot_baseband2_log_c(st:en)), 'pilot baseband2 real' )
+
+st=1;  en = 5*f.Npilotlpf;
+plot_sig_and_error(6, 211, real(pilot_lpf1_log(st:en)), real(pilot_lpf1_log(st:en) - pilot_lpf1_log_c(st:en)), 'pilot lpf1 real' )
+plot_sig_and_error(6, 212, real(pilot_lpf2_log(st:en)), real(pilot_lpf2_log(st:en) - pilot_lpf2_log_c(st:en)), 'pilot lpf2 real' )
+
+plot_sig_and_error(7, 211, real(S1_log), real(S1_log - S1_log_c), 'S1 real' )
+plot_sig_and_error(7, 212, imag(S1_log), imag(S1_log - S1_log_c), 'S1 imag' )
+
+plot_sig_and_error(8, 211, real(S2_log), real(S2_log - S2_log_c), 'S2 real' )
+plot_sig_and_error(8, 212, imag(S2_log), imag(S2_log - S2_log_c), 'S2 imag' )
+
+plot_sig_and_error(9, 211, foff_coarse_log, foff_coarse_log - foff_coarse_log_c, 'Coarse Freq Offset' )
+plot_sig_and_error(9, 212, foff_fine_log, foff_fine_log - foff_fine_log_c, 'Fine Freq Offset' )
+
+plot_sig_and_error(10, 211, foff_log, foff_log - foff_log_c, 'Freq Offset' )
+plot_sig_and_error(10, 212, sync_log, sync_log - sync_log_c, 'Sync & Freq Est Coarse(0) Fine(1)', [1 frames -1.5 1.5] )
+
+plot_sig_and_error(11, 211, real(rx_fdm_filter_log), real(rx_fdm_filter_log - rx_fdm_filter_log_c), 'Rx dec filter real' )
+plot_sig_and_error(11, 212, imag(rx_fdm_filter_log), imag(rx_fdm_filter_log - rx_fdm_filter_log_c), 'Rx dec filter imag' )
+
+c=1;
+plot_sig_and_error(12, 211, real(rx_filt_log(c,:)), real(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt real' )
+plot_sig_and_error(12, 212, imag(rx_filt_log(c,:)), imag(rx_filt_log(c,:) - rx_filt_log_c(c,:)), 'Rx filt imag' )
+
+st=1*28;
+en = 3*28;
+plot_sig_and_error(14, 211, rx_timing_log, rx_timing_log - rx_timing_log_c, 'Rx Timing' )
+stem_sig_and_error(14, 212, sync_bit_log_c, sync_bit_log - sync_bit_log_c, 'Sync bit', [1 n -1.5 1.5])
+
+stem_sig_and_error(15, 211, rx_bits_log_c(st:en), rx_bits_log(st:en) - rx_bits_log_c(st:en), 'RX bits', [1 en-st -1.5 1.5])
+stem_sig_and_error(15, 212, nin_log_c, nin_log - nin_log_c, 'nin')
+
+c = 12;
+plot_sig_and_error(16, 211, sig_est_log(c,:), sig_est_log(c,:) - sig_est_log_c(c,:), 'sig est for SNR' )
+plot_sig_and_error(16, 212, noise_est_log(c,:), noise_est_log(c,:) - noise_est_log_c(c,:), 'noise est for SNR' )
+
+fr=12;
+
+stem_sig_and_error(13, 211, real(rx_symbols_log(:,fr)), real(rx_symbols_log(:,fr) - rx_symbols_log_c(:,fr)), 'rx symbols real' )
+stem_sig_and_error(13, 212, imag(rx_symbols_log(:,fr)), imag(rx_symbols_log(:,fr) - rx_symbols_log_c(:,fr)), 'rx symbols imag' )
+
+stem_sig_and_error(17, 211, real(phase_difference_log(:,fr)), real(phase_difference_log(:,fr) - phase_difference_log_c(:,fr)), 'phase difference real' )
+stem_sig_and_error(17, 212, imag(phase_difference_log(:,fr)), imag(phase_difference_log(:,fr) - phase_difference_log_c(:,fr)), 'phase difference imag' )
+
+
+check(tx_bits_log, tx_bits_log_c, 'tx_bits');
+check(tx_symbols_log,  tx_symbols_log_c, 'tx_symbols');
+check(tx_fdm_log, tx_fdm_log_c, 'tx_fdm');
+check(f.pilot_lut, pilot_lut_c, 'pilot_lut');
+check(f.pilot_coeff, pilot_coeff_c, 'pilot_coeff');
+check(pilot_baseband1_log, pilot_baseband1_log_c, 'pilot lpf1');
+check(pilot_baseband2_log, pilot_baseband2_log_c, 'pilot lpf2');
+check(S1_log, S1_log_c, 'S1');
+check(S2_log, S2_log_c, 'S2');
+check(foff_coarse_log, foff_coarse_log_c, 'foff_coarse');
+check(foff_fine_log, foff_fine_log_c, 'foff_fine');
+check(foff_log, foff_log_c, 'foff');
+check(rx_fdm_filter_log, rx_fdm_filter_log_c, 'rxdec filter');
+check(rx_filt_log, rx_filt_log_c, 'rx filt', 2E-3);
+check(env_log, env_log_c, 'env');
+check(rx_timing_log, rx_timing_log_c, 'rx_timing');
+check(rx_symbols_log, rx_symbols_log_c, 'rx_symbols', 2E-3);
+check(rx_bits_log, rx_bits_log_c, 'rx bits');
+check(sync_bit_log, sync_bit_log_c, 'sync bit');
+check(sync_log, sync_log_c, 'sync');
+check(nin_log, nin_log_c, 'nin');
+check(sig_est_log, sig_est_log_c, 'sig_est');
+check(noise_est_log, noise_est_log_c, 'noise_est');
+printf("\npasses: %d fails: %d\n", passes, fails);
diff --git a/codec2/branches/0.7/octave/tfmfsk.m b/codec2/branches/0.7/octave/tfmfsk.m
new file mode 100644 (file)
index 0000000..342f800
--- /dev/null
@@ -0,0 +1,497 @@
+% tfsk.m
+% Author: Brady O'Brien 8 February 2016
+
+
+
+%  Copyright 2016 David Rowe
+%  
+%  All rights reserved.
+%
+%  This program is free software; you can redistribute it and/or modify
+%  it under the terms of the GNU Lesser General Public License version 2, as
+%  published by the Free Software Foundation.  This program is
+%  distributed in the hope that it will be useful, but WITHOUT ANY
+%  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+%  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+%  License for more details.
+%
+%  You should have received a copy of the GNU Lesser General Public License
+%  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+% Octave script to check c port of  mancyfsk/fmfsk against the fmfsk.m
+%
+#{
+
+  FMFSK Modem automated test instructions:
+
+  1. Use cmake to build in debug mode to ensure unittest/tfsk is built:
+
+     $ cd ~/codec2
+     $ rm -Rf build_linux && mkdir build_linux
+     $ cd build_linux
+     $ cmake -DCMAKE_BUILD_TYPE=Debug ..
+     $ make
+
+  2 - Change tfsk_location below if required
+  3 - Ensure Octave packages signal and parallel are installed
+  4 - Start Octave and run tfsk.m. It will perform all tests automatically
+
+#}
+
+%tfsk executable path/file
+global tfsk_location = '../build_linux/unittest/tfmfsk';
+
+%Set to 1 for verbose printouts
+global print_verbose = 0;
+
+
+
+fmfsk
+pkg load signal;
+pkg load parallel;
+graphics_toolkit('gnuplot');
+
+
+global mod_pass_fail_maxdiff = 1e-3/5000;
+
+function mod = fmfsk_mod_c(Fs,Rs,bits)
+    global tfsk_location;
+    %command to be run by system to launch the modulator
+    command = sprintf('%s M %d %d fsk_mod_ut_bitvec fsk_mod_ut_modvec fmfsk_mod_ut_log.txt',tfsk_location,Fs,Rs);
+    %save input bits into a file
+    bitvecfile = fopen('fsk_mod_ut_bitvec','wb+');
+    fwrite(bitvecfile,bits,'uint8');
+    fclose(bitvecfile);
+    
+    %run the modulator
+    system(command);
+    
+    modvecfile = fopen('fsk_mod_ut_modvec','rb');
+    mod = fread(modvecfile,'single');
+    fclose(modvecfile);
+    
+endfunction
+
+
+%Compare 2 vectors, fail if they are not close enough
+function pass = vcompare(vc,voct,vname,tname,tol,pnum)
+    global print_verbose;
+    
+    %Get delta of vectors
+    dvec = abs(abs(vc)-abs(voct));     
+    
+    %Normalize difference
+    dvec = dvec ./ abs(max(abs(voct))+1e-8);
+    
+    maxdvec = abs(max(dvec));
+    pass = maxdvec<tol;
+    if print_verbose == 1
+        printf('  Comparing vectors %s in test %s. Diff is %f\n',vname,tname,maxdvec);
+    end
+    
+    if pass == 0
+        printf('\n*** vcompare failed %s in test %s. Diff: %f Tol: %f\n\n',vname,tname,maxdvec,tol);
+        
+        titlestr = sprintf('Diff between C and Octave of %s for %s',vname,tname)
+        figure(10+pnum*2)
+        plot(abs(dvec))
+        title(titlestr)
+        
+        figure(11+pnum*2)
+        plot((1:length(vc)),abs(vc),(1:length(voct)),abs(voct))
+    
+    end
+    
+endfunction
+
+function test_stats = fmfsk_demod_xt(Fs,Rs,mod,tname,M=2)
+    global tfsk_location;
+    
+    %Name of executable containing the modulator
+    modvecfilename = sprintf('fmfsk_demod_ut_modvec_%d',getpid());
+    bitvecfilename = sprintf('fmfsk_demod_ut_bitvec_%d',getpid());
+    tvecfilename = sprintf('fmfsk_demod_ut_tracevec_%d.txt',getpid());
+    
+    %command to be run by system to launch the demod
+    command = sprintf('%s D %d %d %s %s %s',tfsk_location,Fs,Rs,modvecfilename,bitvecfilename,tvecfilename);
+    
+    %save modulated input into a file
+    modvecfile = fopen(modvecfilename,'wb+');
+    fwrite(modvecfile,mod,'single');
+    fclose(modvecfile);
+    
+    %run the modulator
+    system(command);
+    
+    bitvecfile = fopen(bitvecfilename,'rb');
+    bits = fread(bitvecfile,'uint8');
+    fclose(bitvecfile);
+    bits = bits!=0;
+    
+    %Load test vec dump
+    load(tvecfilename);
+    
+    %Clean up files
+    delete(bitvecfilename);
+    delete(modvecfilename);
+    delete(tvecfilename);
+    
+    o_norm_rx_timing = [];
+    o_symsamp = [];
+    o_rx_filt = [];
+    
+    %Run octave demod, dump some test vectors
+    states = fmfsk_init(Fs,Rs);
+    Ts = states.Ts;
+    modin = mod;
+    obits = [];
+    while length(modin)>=states.nin
+        ninold = states.nin;
+        [bitbuf,states] = fmfsk_demod(states, modin(1:states.nin));
+        modin=modin(ninold+1:length(modin));
+        obits = [obits bitbuf];
+        
+        o_norm_rx_timing = [o_norm_rx_timing states.norm_rx_timing];
+        o_symsamp = [o_symsamp states.symsamp];
+        o_rx_filt = [o_rx_filt states.rx_filt];
+
+    end
+    
+    close all
+    pass = 1;
+    
+    % One part-per-thousand allowed on important parameters
+    
+    pass = vcompare(t_rx_filt,o_rx_filt,'rx filt',tname,.001,8) && pass;
+    pass = vcompare(t_norm_rx_timing,o_norm_rx_timing,'norm rx timing',tname,.001,9) && pass;
+    pass = vcompare(t_symsamp,o_symsamp,'symsamp',tname,.001,10) && pass;
+    
+    assert(pass);
+    diffpass = sum(xor(obits,bits'))<4;
+    diffbits = sum(xor(obits,bits'));
+    
+    
+    if diffpass==0
+        printf('\n***bitcompare test failed test %s diff %d\n\n',tname,sum(xor(obits,bits')))
+        figure(15)
+        plot(xor(obits,bits'))
+        title(sprintf('Bitcompare failure test %s',tname))
+    end
+    
+    pass = pass && diffpass;
+    
+    
+    test_stats.pass = pass;
+    test_stats.diff = sum(xor(obits,bits'));
+    test_stats.cbits = bits';
+    test_stats.obits = obits;
+    
+endfunction
+
+function [dmod,cmod,omod,pass] = fmfsk_mod_test(Fs,Rs,bits,tname,M=2)
+    global mod_pass_fail_maxdiff;
+    %Run the C modulator
+    cmod = fmfsk_mod_c(Fs,Rs,bits);
+    %Set up and run the octave modulator
+    states.M = M;
+    states = fmfsk_init(Fs,Rs);
+
+    
+    omod = fmfsk_mod(states,bits)';
+    
+    dmod = cmod-omod;
+    pass = max(dmod)<(mod_pass_fail_maxdiff*length(dmod));
+    if !pass
+        printf('Mod failed test %s!\n',tname);
+    end
+endfunction
+
+% Random bit modulator test
+% Pass random bits through the modulators and compare
+function pass = test_mod_fdvbcfg_randbits
+    rand('state',1); 
+    randn('state',1);
+    bits = rand(1,19200)>.5;
+    [dmod,cmod,omod,pass] = fmfsk_mod_test(48000,2400,bits,"mod fdvbcfg randbits");
+    
+    if(!pass)
+        figure(1)
+        plot(dmod)
+        title("Difference between octave and C mod impl");
+    end
+    
+endfunction
+
+% run_sim copypasted from fsk_horus.m
+% simulation of tx and rx side, add noise, channel impairments ----------------------
+
+function stats = tfmfsk_run_sim(EbNodB,timing_offset=0,de=0,of=0,hpf=0,df=0,M=2)
+  global print_verbose;
+  test_frame_mode = 2;
+  frames = 70;
+  %EbNodB = 3;
+  %timing_offset = 0.0; % see resample() for clock offset below
+  %fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+
+  more off
+  rand('state',1); 
+  randn('state',1);
+  
+  Fs = 48000;
+  Rbit = 2400;
+
+  % ----------------------------------------------------------------------
+
+  fm_states.pre_emp = 0;
+  fm_states.de_emp  = de;
+  fm_states.Ts      = Fs/(Rbit*2);
+  fm_states.Fs      = Fs; 
+  fm_states.fc      = Fs/4; 
+  fm_states.fm_max  = 3E3;
+  fm_states.fd      = 5E3;
+  fm_states.output_filter = of;
+  fm_states = analog_fm_init(fm_states);
+
+  % ----------------------------------------------------------------------
+  
+  states = fmfsk_init(Fs,Rbit);
+
+  states.verbose = 0x1;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  Fs = states.Fs;
+  nbit = states.nbit;
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rb*EbNo);
+
+  % set up tx signal with payload bits based on test mode
+
+  if test_frame_mode == 1
+     % test frame of bits, which we repeat for convenience when BER testing
+    test_frame = round(rand(1, states.nbit));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, states.nbit*(frames+1)));
+  end
+  if test_frame_mode == 3
+    % repeating sequence of all symbols
+    % great for initial test of demod if nothing else works, 
+    % look for this pattern in rx_bits
+
+       % ...10101...
+      tx_bits = zeros(1, states.nbit*(frames+1));
+      tx_bits(1:2:length(tx_bits)) = 1;
+
+  end
+
+  [b, a] = cheby1(4, 1, 300/Fs, 'high');   % 300Hz HPF to simulate FM radios
+  
+  tx_pmod = fmfsk_mod(states, tx_bits);
+  
+  tx = analog_fm_mod(fm_states, tx_pmod);
+  
+  if(timing_offset>0)
+    tx = resample(tx, 2000, 1999); % simulated 1000ppm sample clock offset
+  end
+  
+  %Add frequency drift
+  fdrift = df/Fs;
+  fshift = 2*pi*fdrift*(1:length(tx));
+  fshift = exp(j*(fshift.^2));
+  tx = tx.*fshift;
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise';
+  
+  %Demod by analog fm
+  rx    = analog_fm_demod(fm_states, rx);
+  
+  %High-pass filter to simulate the FM radios
+  if hpf>0
+    rx = filter(b,a,rx);
+  end
+
+  timing_offset_samples = round(timing_offset*states.Ts);
+  st = 1 + timing_offset_samples;
+  rx_bits_buf = zeros(1,2*nbit);
+
+  test_name = sprintf("tfmfsk run sim EbNodB:%d frames:%d timing_offset:%d df:%d",EbNodB,frames,timing_offset,df);
+  tstats = fmfsk_demod_xt(Fs,Rbit,rx',test_name,M); 
+
+  pass = tstats.pass;
+  obits = tstats.obits;
+  cbits = tstats.cbits;
+  
+  % Figure out BER of octave and C modems
+  bitcnt = length(tx_bits);
+  rx_bits = obits;
+  ber = 1;
+  ox = 1;
+  for offset = (1:400)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),tx_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  bero = ber;
+  ber = 1;
+  rx_bits = cbits;
+  ox = 1;
+  for offset = (1:400)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),tx_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  berc = ber;
+  
+  if print_verbose == 1
+    printf("C BER %f in test %s\n",berc,test_name);
+    printf("Oct BER %f in test %s\n",bero,test_name);
+  end
+  
+  stats.berc = berc;
+  stats.bero = bero;
+  stats.name = test_name;
+    % non-coherent BER theory calculation
+  % It was complicated, so I broke it up
+
+  ms = 2;
+  ns = (1:ms-1);
+  as = (-1).^(ns+1);
+  bs = (as./(ns+1));
+  
+  cs = ((ms-1)./ns);
+
+  ds = ns.*log2(ms);
+  es = ns+1;
+  fs = exp( -(ds./es)*EbNo );
+  
+  thrncoh = ((ms/2)/(ms-1)) * sum(bs.*((ms-1)./ns).*exp( -(ds./es)*EbNo ));
+  
+  stats.thrncoh = thrncoh;
+  stats.pass = pass;
+ endfunction
+
+
+function pass = ebno_battery_test(timing_offset,drift,hpf,deemp,outfilt)
+    global print_verbose;
+    %Range of EbNodB over which to test
+    ebnodbrange = (8:2:20);
+    ebnodbs = length(ebnodbrange);
+    
+    %Replication of other parameters for parcellfun
+    timingv     = repmat(timing_offset  ,1,ebnodbs);
+    driftv      = repmat(drift          ,1,ebnodbs);
+    hpfv        = repmat(hpf            ,1,ebnodbs);
+    deempv      = repmat(deemp          ,1,ebnodbs);
+    outfv       = repmat(outfilt        ,1,ebnodbs);
+    
+    statv = pararrayfun(floor(.75*nproc()),@tfmfsk_run_sim,ebnodbrange,timingv,deempv,outfv,hpfv,driftv);
+    %statv = arrayfun(@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,mv);
+
+    passv = zeros(1,length(statv));
+    for ii=(1:length(statv))
+        passv(ii)=statv(ii).pass;
+        if statv(ii).pass
+            printf("Test %s passed\n",statv(ii).name);
+        else
+            printf("Test %s failed\n",statv(ii).name);
+        end
+    end
+    
+    %All pass flags are '1'
+    pass = sum(passv)>=length(passv);
+    %and no tests died
+    pass = pass && length(passv)==ebnodbs;
+    passv;
+    assert(pass)
+endfunction
+
+%Test with and without sample clock offset
+function pass = test_timing_var(drift,hpf,deemp,outfilt)
+    pass = ebno_battery_test(1,drift,hpf,deemp,outfilt)
+    assert(pass)
+    pass = ebno_battery_test(0,drift,hpf,deemp,outfilt)
+    assert(pass)
+endfunction
+
+%Test with and without 1 Hz/S freq drift
+function pass = test_drift_var(hpf,deemp,outfilt)
+    pass = test_timing_var(1,hpf,deemp,outfilt)
+    assert(pass)
+    pass = pass && test_timing_var(0,hpf,deemp,outfilt)
+    assert(pass)
+endfunction
+
+function pass = test_fmfsk_battery()
+    pass = test_mod_fdvbcfg_randbits;
+    assert(pass)
+    pass = pass && test_drift_var(1,1,1);
+    assert(pass)
+    if pass
+        printf("***** All tests passed! *****\n");
+    end
+endfunction
+
+function plot_fmfsk_bers(M=2)
+    %Range of EbNodB over which to test
+    ebnodbrange = (8:14);
+    ebnodbs = length(ebnodbrange);
+    
+    %Replication of other parameters for parcellfun
+    %Turn on all of the impairments
+    timingv     = repmat(1  ,1,ebnodbs);
+    driftv      = repmat(1  ,1,ebnodbs);
+    hpfv        = repmat(1  ,1,ebnodbs);
+    deempv      = repmat(1  ,1,ebnodbs);
+    outfv       = repmat(1  ,1,ebnodbs);
+    
+    statv = pararrayfun(nproc(),@tfmfsk_run_sim,ebnodbrange,timingv,deempv,outfv,hpfv,driftv);    
+    %statv = arrayfun(@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,Mv);
+    
+    for ii = (1:length(statv))
+        stat = statv(ii);
+        berc(ii)=stat.berc;
+        bero(ii)=stat.bero;
+        berinc(ii)=stat.thrncoh;
+    end
+    clf;
+    figure(M)
+    
+    semilogy(ebnodbrange, berinc,sprintf('r;2FSK non-coherent theory;',M))
+    hold on;
+    semilogy(ebnodbrange, bero ,sprintf('g;Octave ME-FM-FSK Demod;',M))
+    semilogy(ebnodbrange, berc,sprintf('v;C ME-FM-FSK Demod;',M))
+    hold off;
+    grid("minor");
+    axis([min(ebnodbrange) max(ebnodbrange) 1E-5 1])
+    legend("boxoff");
+    xlabel("Eb/No (dB)");
+    ylabel("Bit Error Rate (BER)")
+endfunction
+
+xpass = test_fmfsk_battery
+plot_fmfsk_bers(2)
+
+if xpass
+    printf("***** All tests passed! *****\n");
+else
+    printf("***** Some test failed! Look back thorugh output to find failed test *****\n");
+end
diff --git a/codec2/branches/0.7/octave/tfsk.m b/codec2/branches/0.7/octave/tfsk.m
new file mode 100644 (file)
index 0000000..0f2d401
--- /dev/null
@@ -0,0 +1,630 @@
+% tfsk.m
+% Author: Brady O'Brien 8 January 2016
+
+
+
+%   Copyright 2016 David Rowe
+%  
+%  All rights reserved.
+%
+%  This program is free software; you can redistribute it and/or modify
+%  it under the terms of the GNU Lesser General Public License version 2, as
+%  published by the Free Software Foundation.  This program is
+%  distributed in the hope that it will be useful, but WITHOUT ANY
+%  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+%  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+%  License for more details.
+%
+%  You should have received a copy of the GNU Lesser General Public License
+%  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+% Octave script to check c port of fsk_horus against the fsk_horus.m
+%
+% [X] - Functions to wrap around fsk_mod and fsk_demod executables
+%     [X] - fsk_mod
+%     [X] - fsk_demod
+% [X] - Functions to wrap around octave and c implementations, pass
+%       same dataset, compare outputs, and give clear go/no-go
+%     [X] - fsk_mod_test
+%     [X] - fsk_demod_test
+% [X] - Port of run_sim and EbNodB curve test battery
+% [X] - Extract and compare more parameters from demod
+% [X] - Run some tests in parallel
+
+#{
+
+  FSK Modem automated test instructions:
+
+  1. Use cmake to build in debug mode to ensure unittest/tfsk is built:
+
+     $ cd ~/codec2
+     $ rm -Rf build_linux && mkdir build_linux
+     $ cd build_linux
+     $ cmake -DCMAKE_BUILD_TYPE=Debug ..
+     $ make
+
+  2 - Change tfsk_location below if required
+  3 - Ensure Octave packages signal and parallel are installed
+  4 - Start Octave and run tfsk.m. It will perform all tests automatically
+
+#}
+
+%tfsk executable path/file
+global tfsk_location = '../build_linux/unittest/tfsk';
+
+%Set to 1 for verbose printouts
+global print_verbose = 0;
+
+
+fsk_horus_as_a_lib = 1; % make sure calls to test functions at bottom are disabled
+%fsk_horus_2fsk;  
+fsk_horus
+pkg load signal;
+pkg load parallel;
+graphics_toolkit('gnuplot');
+
+
+global mod_pass_fail_maxdiff = 1e-3/5000;
+
+function mod = fsk_mod_c(Fs,Rs,f1,fsp,bits,M)
+    global tfsk_location;
+    %command to be run by system to launch the modulator
+    command = sprintf('%s M %d %d %d %d %d fsk_mod_ut_bitvec fsk_mod_ut_modvec fsk_mod_ut_log.txt',tfsk_location,M,f1,fsp,Fs,Rs);
+    %save input bits into a file
+    bitvecfile = fopen('fsk_mod_ut_bitvec','wb+');
+    fwrite(bitvecfile,bits,'uint8');
+    fclose(bitvecfile);
+    
+    %run the modulator
+    system(command);
+    
+    modvecfile = fopen('fsk_mod_ut_modvec','rb');
+    mod = fread(modvecfile,'single');
+    fclose(modvecfile);
+    
+endfunction
+
+
+%Compare 2 vectors, fail if they are not close enough
+function pass = vcompare(vc,voct,vname,tname,tol,pnum)
+    global print_verbose;
+    %Get delta of vectors
+    dvec = abs(abs(vc)-abs(voct));     
+    
+    %Normalize difference
+    dvec = dvec ./ abs(max(abs(voct))+1e-8);
+    
+    maxdvec = abs(max(dvec));
+    pass = maxdvec<tol;
+    if print_verbose == 1
+        printf('  Comparing vectors %s in test %s. Diff is %f\n',vname,tname,maxdvec);
+    end
+    if pass == 0
+        printf('\n*** vcompare failed %s in test %s. Diff: %f Tol: %f\n\n',vname,tname,maxdvec,tol);
+        
+        titlestr = sprintf('Diff between C and Octave of %s for %s',vname,tname)
+        figure(10+pnum*2)
+        plot(abs(dvec))
+        title(titlestr)
+        
+        figure(11+pnum*2)
+        plot((1:length(vc)),abs(vc),(1:length(voct)),abs(voct))
+    
+    end
+    
+endfunction
+
+function test_stats = fsk_demod_xt(Fs,Rs,f1,fsp,mod,tname,M=2)
+    global print_verbose;
+    global tfsk_location;
+    %Name of executable containing the modulator
+    fsk_demod_ex_file = '../build/unittest/tfsk';
+    modvecfilename = sprintf('fsk_demod_ut_modvec_%d',getpid());
+    bitvecfilename = sprintf('fsk_demod_ut_bitvec_%d',getpid());
+    tvecfilename = sprintf('fsk_demod_ut_tracevec_%d.txt',getpid());
+    
+    %command to be run by system to launch the demod
+    command = sprintf('%s D %d %d %d %d %d %s %s %s',tfsk_location,M,f1,fsp,Fs,Rs,modvecfilename,bitvecfilename,tvecfilename);
+    
+    %save modulated input into a file
+    modvecfile = fopen(modvecfilename,'wb+');
+    fwrite(modvecfile,mod,'single');
+    fclose(modvecfile);
+    
+    %run the modulator
+    system(command);
+    
+    bitvecfile = fopen(bitvecfilename,'rb');
+    bits = fread(bitvecfile,'uint8');
+    fclose(bitvecfile);
+    bits = bits!=0;
+    
+    %Load test vec dump
+    load(tvecfilename);
+    
+    %Clean up files
+    delete(bitvecfilename);
+    delete(modvecfilename);
+    delete(tvecfilename);
+    
+    o_f1_dc = [];
+    o_f2_dc = [];
+    o_f3_dc = [];
+    o_f4_dc = [];
+    o_f1_int = [];
+    o_f2_int = [];
+    o_f3_int = [];
+    o_f4_int = [];
+    o_f1 = [];
+    o_f2 = [];
+    o_f3 = [];
+    o_f4 = [];
+    o_EbNodB = [];
+    o_ppm = [];
+    o_Sf = [];
+    o_fest = [];
+    o_rx_timing = [];
+    o_norm_rx_timing = [];
+    o_nin = [];
+    %Run octave demod, dump some test vectors
+    states = fsk_horus_init(Fs,Rs,M);
+    Ts = states.Ts;
+    P = states.P;
+    states.ftx(1) = f1;
+    states.ftx(2) = f1+fsp;
+    states.ftx(3) = f1+fsp*2;
+    states.ftx(4) = f1+fsp*3;
+    states.dA = 1;
+    states.dF = 0;
+    modin = mod;
+    obits = [];
+    while length(modin)>=states.nin
+        ninold = states.nin;
+        states = est_freq(states, modin(1:states.nin), states.M);
+        [bitbuf,states] = fsk_horus_demod(states, modin(1:states.nin));
+        modin=modin(ninold+1:length(modin));
+        obits = [obits bitbuf];
+        
+        %Save other parameters
+        o_f1_dc = [o_f1_dc states.f_dc(1,1:states.Nmem-Ts/P)];
+        o_f2_dc = [o_f2_dc states.f_dc(2,1:states.Nmem-Ts/P)];
+        o_f1_int = [o_f1_int states.f_int(1,:)];
+        o_f2_int = [o_f2_int states.f_int(2,:)];
+        o_EbNodB = [o_EbNodB states.EbNodB];
+        o_ppm = [o_ppm states.ppm];
+        o_rx_timing = [o_rx_timing states.rx_timing];
+        o_norm_rx_timing = [o_norm_rx_timing states.norm_rx_timing];
+        o_Sf = [o_Sf states.Sf'];
+        o_f1 = [o_f1 states.f(1)];
+        o_f2 = [o_f1 states.f(2)];
+        o_fest = [o_fest states.f];
+        o_nin = [o_nin states.nin];
+        if M==4
+                       o_f3_dc = [o_f3_dc states.f_dc(3,1:states.Nmem-Ts/P)];
+                       o_f4_dc = [o_f4_dc states.f_dc(4,1:states.Nmem-Ts/P)];
+                       o_f3_int = [o_f3_int states.f_int(3,:)];
+                       o_f4_int = [o_f4_int states.f_int(4,:)];
+                       o_f3 = [o_f1 states.f(3)];
+                       o_f4 = [o_f1 states.f(4)];
+        end
+    end
+    
+    %close all
+    
+    % One part-per-thousand allowed on important parameters
+    pass = 1;
+    
+    pass = vcompare(o_Sf,  t_fft_est,'fft est',tname,.001,1) && pass;
+    pass = vcompare(o_fest,  t_f_est,'f est',tname,.001,2) && pass;
+    pass = vcompare(o_rx_timing,  t_rx_timing,'rx timing',tname,.02,3) && pass;
+    
+    if M==4
+        pass = vcompare(o_f3_dc,      t_f3_dc,    'f3 dc',    tname,.005,4) && pass;
+        pass = vcompare(o_f4_dc,      t_f4_dc,    'f4 dc',    tname,.005,5) && pass;
+        pass = vcompare(o_f3_int,     t_f3_int,   'f3 int',   tname,.005,6) && pass;
+        pass = vcompare(o_f4_int,     t_f4_int,   'f4 int',   tname,.005,7) && pass;
+    end
+    
+    pass = vcompare(o_f1_dc,      t_f1_dc,    'f1 dc',    tname,.005,8) && pass;
+    pass = vcompare(o_f2_dc,      t_f2_dc,    'f2 dc',    tname,.005,9) && pass;
+    pass = vcompare(o_f2_int,     t_f2_int,   'f2 int',   tname,.005,10) && pass;
+    pass = vcompare(o_f1_int,     t_f1_int,   'f1 int',   tname,.005,11) && pass;
+
+    % Much larger tolerances on unimportant statistics
+    pass = vcompare(o_ppm   ,     t_ppm,      'ppm',      tname,.02,12) && pass;
+    pass = vcompare(o_EbNodB,     t_EbNodB,'EbNodB',      tname,.02,13) && pass;
+    pass = vcompare(o_nin,        t_nin,      'nin',      tname,.0001,14) && pass;
+    pass = vcompare(o_norm_rx_timing,  t_norm_rx_timing,'norm rx timing',tname,.02,15) && pass;
+    
+    assert(pass);
+    diffpass = sum(xor(obits,bits'))<4;
+    diffbits = sum(xor(obits,bits'));
+    
+    
+    if diffpass==0
+        printf('\n***bitcompare test failed test %s diff %d\n\n',tname,sum(xor(obits,bits')))
+        figure(15)
+        plot(xor(obits,bits'))
+        title(sprintf('Bitcompare failure test %s',tname))
+    end
+    
+    pass = pass && diffpass;
+    
+    
+    test_stats.pass = pass;
+    test_stats.diff = sum(xor(obits,bits'));
+    test_stats.cbits = bits';
+    test_stats.obits = obits;
+    
+endfunction
+
+function [dmod,cmod,omod,pass] = fsk_mod_test(Fs,Rs,f1,fsp,bits,tname,M=2)
+    global mod_pass_fail_maxdiff;
+    %Run the C modulator
+    cmod = fsk_mod_c(Fs,Rs,f1,fsp,bits,M);
+    %Set up and run the octave modulator
+    states.M = M;
+    states = fsk_horus_init(Fs,Rs,M);
+    
+    states.ftx(1) = f1;
+    states.ftx(2) = f1+fsp;
+    
+    if states.M == 4
+               states.ftx(3) = f1+fsp*2;
+               states.ftx(4) = f1+fsp*3;
+    end
+    
+    states.dA = [1 1 1 1]; 
+    states.dF = 0;
+    omod = fsk_horus_mod(states,bits);
+    
+    dmod = cmod-omod;
+    pass = max(dmod)<(mod_pass_fail_maxdiff*length(dmod));
+    if !pass
+        printf('Mod failed test %s!\n',tname);
+    end
+endfunction
+
+% Random bit modulator test
+% Pass random bits through the modulators and compare
+function pass = test_mod_horuscfg_randbits
+    rand('state',1); 
+    randn('state',1);
+    bits = rand(1,10000)>.5;
+    [dmod,cmod,omod,pass] = fsk_mod_test(8000,100,1200,1600,bits,"mod horuscfg randbits");
+    
+    if(!pass)
+        figure(1)
+        plot(dmod)
+        title("Difference between octave and C mod impl");
+    end
+    
+endfunction
+
+% Random bit modulator test
+% Pass random bits through the modulators and compare
+function pass = test_mod_horuscfgm4_randbits
+    rand('state',1); 
+    randn('state',1);
+    bits = rand(1,10000)>.5;
+    [dmod,cmod,omod,pass] = fsk_mod_test(8000,100,1200,1600,bits,"mod horuscfg randbits",4);
+    
+    if(!pass)
+        figure(1)
+        plot(dmod)
+        title("Difference between octave and C mod impl");
+    end
+    
+endfunction
+
+% A big ol' channel impairment tester
+% Shamlessly taken from fsk_horus
+% This throws some channel imparment or another at the C and octave modem so they 
+% may be compared.
+function stats = tfsk_run_sim(test_frame_mode,EbNodB,timing_offset,fading,df,dA,M=2)
+  global print_verbose;
+  frames = 90;
+  %EbNodB = 10;
+  %timing_offset = 2.0; % see resample() for clock offset below
+  %fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+  %df     = 0;          % tx tone freq drift in Hz/s
+  %dA     = 1;          % amplitude imbalance of tones (note this affects Eb so not a gd idea)
+
+  more off
+  rand('state',1); 
+  randn('state',1);
+
+  % ----------------------------------------------------------------------
+
+  % sm2000 config ------------------------
+  %states = fsk_horus_init(96000, 1200);
+  %states.f1_tx = 4000;
+  %states.f2_tx = 5200;
+  
+  if test_frame_mode == 2
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 100, M);
+    states.f1_tx = 1200;
+    states.f2_tx = 1600;
+    
+  end
+
+  if test_frame_mode == 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init(8000, 100, M);
+    states.f1_tx = 1200;
+    states.f2_tx = 1600;
+    states.tx_bits_file = "horus_tx_bits_rtty.txt"; % Octave file of bits we FSK modulate
+    
+  end
+                               
+  if test_frame_mode == 5
+    % horus binary config ---------------------
+    states = fsk_horus_init(8000, 100, M);
+    states.f1_tx = 1200;
+    states.f2_tx = 1600;
+    %%%states.tx_bits_file = "horus_tx_bits_binary.txt"; % Octave file of bits we FSK modulate
+       states.tx_bits_file = "horus_payload_rtty.txt";
+  end
+
+  % ----------------------------------------------------------------------
+
+  states.verbose = 0;%x1;
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  Fs = states.Fs;
+  states.df = df;
+  states.dA = [dA dA dA dA];
+  states.M = M;
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rs*EbNo*states.bitspersymbol);
+
+  % set up tx signal with payload bits based on test mode
+
+  if test_frame_mode == 1
+     % test frame of bits, which we repeat for convenience when BER testing
+    test_frame = round(rand(1, states.nsym));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, states.nbit*(frames+1)));
+  end
+  if test_frame_mode == 3
+    % ...10101... sequence
+    tx_bits = zeros(1, states.nsym*(frames+1));
+    tx_bits(1:2:length(tx_bits)) = 1;
+  end
+  if (test_frame_mode == 4) || (test_frame_mode == 5)
+
+    % load up a horus msg from disk and modulate that
+
+    test_frame = load(states.tx_bits_file);
+    ltf = length(test_frame);
+    ntest_frames = ceil((frames+1)*nsym/ltf);
+    tx_bits = [];
+    for i=1:ntest_frames
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  
+  f1 = states.f1_tx;
+  fsp = states.f2_tx-f1;
+  states.dA = [dA dA dA dA];
+  states.ftx(1) = f1;
+  states.ftx(2) = f1+fsp;
+    
+  if states.M == 4
+       states.ftx(3) = f1+fsp*2;
+       states.ftx(4) = f1+fsp*3;
+  end
+
+  tx = fsk_horus_mod(states, tx_bits);
+
+  if timing_offset
+    tx = resample(tx, 1000, 1001); % simulated 1000ppm sample clock offset
+  end
+  
+  if fading
+     ltx = length(tx);
+     tx = tx .* (1.1 + cos(2*pi*2*(0:ltx-1)/Fs))'; % min amplitude 0.1, -20dB fade, max 3dB
+  end
+
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise;
+  
+  test_name = sprintf("tfsk run sim EbNodB:%d frames:%d timing_offset:%d fading:%d df:%d",EbNodB,frames,timing_offset,fading,df);
+  tstats = fsk_demod_xt(Fs,Rs,states.f1_tx,fsp,rx,test_name,M);
+  
+  pass = tstats.pass;
+  obits = tstats.obits;
+  cbits = tstats.cbits;
+  
+  % Figure out BER of octave and C modems
+  bitcnt = length(tx_bits);
+  rx_bits = obits;
+  ber = 1;
+  ox = 1;
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),tx_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  bero = ber;
+  ber = 1;
+  rx_bits = cbits;
+  ox = 1;
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),tx_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  berc = ber;
+  stats.berc = berc;
+  stats.bero = bero;
+  stats.name = test_name;
+  % coherent BER theory calculation
+  
+  stats.thrcoh = .5*(M-1)*erfc(sqrt( (log2(M)/2) * EbNo ));
+  
+  % non-coherent BER theory calculation
+  % It was complicated, so I broke it up
+
+  ms = M;
+  ns = (1:ms-1);
+  as = (-1).^(ns+1);
+  bs = (as./(ns+1));
+  
+  cs = ((ms-1)./ns);
+
+  ds = ns.*log2(ms);
+  es = ns+1;
+  fs = exp( -(ds./es)*EbNo );
+  
+  thrncoh = ((ms/2)/(ms-1)) * sum(bs.*((ms-1)./ns).*exp( -(ds./es)*EbNo ));
+  
+  stats.thrncoh = thrncoh;
+  stats.pass = pass;
+endfunction
+
+
+function pass = ebno_battery_test(timing_offset,fading,df,dA,M)
+    %Range of EbNodB over which to test
+    ebnodbrange = (5:2:13);
+    ebnodbs = length(ebnodbrange);
+    
+    mode = 2;
+    %Replication of other parameters for parcellfun
+    modev   = repmat(mode,1,ebnodbs);
+    timingv = repmat(timing_offset,1,ebnodbs);
+    fadingv = repmat(fading,1,ebnodbs);
+    dfv     = repmat(df,1,ebnodbs);
+    dav     = repmat(dA,1,ebnodbs);
+    mv      = repmat(M,1,ebnodbs);
+    statv = pararrayfun(floor(1.25*nproc()),@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,mv);
+    %statv = arrayfun(@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,mv);
+
+    passv = zeros(1,length(statv));
+    for ii=(1:length(statv))
+        passv(ii)=statv(ii).pass;
+        if statv(ii).pass
+            printf("Test %s passed\n",statv(ii).name);
+        else
+            printf("Test %s failed\n",statv(ii).name);
+        end
+    end
+    
+    %All pass flags are '1'
+    pass = sum(passv)>=length(passv);
+    %and no tests died
+    pass = pass && length(passv)==ebnodbs;
+    passv;
+    assert(pass)
+endfunction
+
+%Test with and without sample clock offset
+function pass = test_timing_var(df,dA,M)
+    pass = ebno_battery_test(1,0,df,dA,M)
+    assert(pass)
+    pass = pass && ebno_battery_test(0,0,df,dA,M)
+    assert(pass)
+endfunction
+
+%Test with and without 1 Hz/S freq drift
+function pass = test_drift_var(M)
+    pass = test_timing_var(1,1,M)
+    assert(pass)
+    pass = pass && test_timing_var(0,1,M)
+    assert(pass)
+endfunction
+
+function pass = test_fsk_battery()
+    pass = test_mod_horuscfg_randbits;
+    assert(pass)
+    pass = pass && test_mod_horuscfgm4_randbits;
+    assert(pass)
+    pass = pass && test_drift_var(4);
+    assert(pass)
+    pass = pass && test_drift_var(2);
+    assert(pass)
+    if pass
+        printf("***** All tests passed! *****\n");
+    end
+endfunction
+
+function plot_fsk_bers(M=2)
+    %Range of EbNodB over which to plot
+    ebnodbrange = (4:13);
+    
+    berc = ones(1,length(ebnodbrange));
+    bero = ones(1,length(ebnodbrange));
+    berinc = ones(1,length(ebnodbrange));
+    beric = ones(1,length(ebnodbrange));
+    ebnodbs = length(ebnodbrange)
+    mode = 2;
+    %Replication of other parameters for parcellfun
+    modev   = repmat(mode,1,ebnodbs);
+    timingv = repmat(1,1,ebnodbs);
+    fadingv = repmat(0,1,ebnodbs);
+    dfv     = repmat(1,1,ebnodbs);
+    dav     = repmat(1,1,ebnodbs);
+    Mv     = repmat(M,1,ebnodbs);
+    
+    
+    statv = pararrayfun(floor(nproc()),@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,Mv);
+    %statv = arrayfun(@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,Mv);
+    
+    for ii = (1:length(statv))
+        stat = statv(ii);
+        berc(ii)=stat.berc;
+        bero(ii)=stat.bero;
+        berinc(ii)=stat.thrncoh;
+        beric(ii) = stat.thrcoh;
+    end
+    clf;
+    figure(M)
+    
+    semilogy(ebnodbrange, berinc,sprintf('r;%dFSK non-coherent theory;',M))
+    hold on;
+    semilogy(ebnodbrange, beric ,sprintf('g;%dFSK coherent theory;',M))
+    semilogy(ebnodbrange, bero ,sprintf('b;Octave fsk horus %dFSK Demod;',M))
+    semilogy(ebnodbrange, berc,sprintf('+;C fsk horus %dFSK Demod;',M))
+    hold off;
+    grid("minor");
+    axis([min(ebnodbrange) max(ebnodbrange) 1E-5 1])
+    legend("boxoff");
+    xlabel("Eb/No (dB)");
+    ylabel("Bit Error Rate (BER)")
+endfunction
+
+
+xpass = test_fsk_battery
+%plot_fsk_bers(2)
+plot_fsk_bers(4)
+
+if xpass
+    printf("***** All tests passed! *****\n");
+else
+    printf("***** Some test failed! Look back thorugh output to find failed test *****\n");
+end
+
diff --git a/codec2/branches/0.7/octave/tfsk_2400a.m b/codec2/branches/0.7/octave/tfsk_2400a.m
new file mode 100644 (file)
index 0000000..a70044b
--- /dev/null
@@ -0,0 +1,648 @@
+% tfsk.m
+% Author: Brady O'Brien 8 January 2016
+
+
+
+%   Copyright 2016 David Rowe
+%  
+%  All rights reserved.
+%
+%  This program is free software; you can redistribute it and/or modify
+%  it under the terms of the GNU Lesser General Public License version 2, as
+%  published by the Free Software Foundation.  This program is
+%  distributed in the hope that it will be useful, but WITHOUT ANY
+%  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+%  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+%  License for more details.
+%
+%  You should have received a copy of the GNU Lesser General Public License
+%  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+
+% Octave script to check c port of fsk_horus against the fsk_horus.m
+%
+% [X] - Functions to wrap around fsk_mod and fsk_demod executables
+%     [X] - fsk_mod
+%     [X] - fsk_demod
+% [X] - Functions to wrap around octave and c implementations, pass
+%       same dataset, compare outputs, and give clear go/no-go
+%     [X] - fsk_mod_test
+%     [X] - fsk_demod_test
+% [X] - Port of run_sim and EbNodB curve test battery
+% [X] - Extract and compare more parameters from demod
+% [X] - Run some tests in parallel
+
+#{
+
+  FSK Modem automated test instructions:
+
+  1. Use cmake to build in debug mode to ensure unittest/tfsk is built:
+
+     $ cd ~/codec2
+     $ rm -Rf build_linux && mkdir build_linux
+     $ cd build_linux
+     $ cmake -DCMAKE_BUILD_TYPE=Debug ..
+     $ make
+
+  2 - Change tfsk_location below if required
+  3 - Ensure Octave packages signal and parallel are installed
+  4 - Start Octave and run tfsk_2400a.m. It will perform all tests automatically
+
+#}
+
+
+
+%tfsk executable path/file
+global tfsk_location = '../build_linux/unittest/tfsk';
+
+%Set to 1 for verbose printouts
+global print_verbose = 0;
+
+
+fsk_horus_as_a_lib = 1; % make sure calls to test functions at bottom are disabled
+%fsk_horus_2fsk;  
+fsk_horus
+pkg load signal;
+pkg load parallel;
+graphics_toolkit('gnuplot');
+
+
+global mod_pass_fail_maxdiff = 1e-3/5000;
+
+function mod = fsk_mod_c(Fs,Rs,f1,fsp,bits,M)
+    global tfsk_location;
+    %command to be run by system to launch the modulator
+    command = sprintf('%s MX %d %d %d %d %d fsk_mod_ut_bitvec fsk_mod_ut_modvec fsk_mod_ut_log.txt',tfsk_location,M,f1,fsp,Fs,Rs);
+    %save input bits into a file
+    bitvecfile = fopen('fsk_mod_ut_bitvec','wb+');
+    fwrite(bitvecfile,bits,'uint8');
+    fclose(bitvecfile);
+    
+    %run the modulator
+    system(command);
+    
+    modvecfile = fopen('fsk_mod_ut_modvec','rb');
+    mod = fread(modvecfile,'single');
+    fclose(modvecfile);
+    
+endfunction
+
+
+%Compare 2 vectors, fail if they are not close enough
+function pass = vcompare(vc,voct,vname,tname,tol,pnum)
+    global print_verbose;
+    %Get delta of vectors
+    dvec = abs(abs(vc)-abs(voct));     
+    
+    %Normalize difference
+    dvec = dvec ./ abs(max(abs(voct))+1e-8);
+    
+    maxdvec = abs(max(dvec));
+    pass = maxdvec<tol;
+    
+    if print_verbose == 1
+        printf('  Comparing vectors %s in test %s. Diff is %f\n',vname,tname,maxdvec);
+    end
+    
+    if pass == 0
+        printf('\n*** vcompare failed %s in test %s. Diff: %f Tol: %f\n\n',vname,tname,maxdvec,tol);
+        
+        titlestr = sprintf('Diff between C and Octave of %s for %s',vname,tname)
+        figure(10+pnum*2)
+        plot(abs(dvec))
+        title(titlestr)
+        
+        figure(11+pnum*2)
+        plot((1:length(vc)),abs(vc),(1:length(voct)),abs(voct))
+    
+    end
+    
+endfunction
+
+function test_stats = fsk_demod_xt(Fs,Rs,f1,fsp,mod,tname,M=2)
+    global tfsk_location;
+    global print_verbose;
+    %Name of executable containing the modulator
+    fsk_demod_ex_file = '../build/unittest/tfsk';
+    modvecfilename = sprintf('fsk_demod_ut_modvec_%d',getpid());
+    bitvecfilename = sprintf('fsk_demod_ut_bitvec_%d',getpid());
+    tvecfilename = sprintf('fsk_demod_ut_tracevec_%d.txt',getpid());
+    
+    %command to be run by system to launch the demod
+    command = sprintf('%s DX %d %d %d %d %d %s %s %s',tfsk_location,M,f1,fsp,Fs,Rs,modvecfilename,bitvecfilename,tvecfilename);
+    
+    %save modulated input into a file
+    modvecfile = fopen(modvecfilename,'wb+');
+    fwrite(modvecfile,mod,'single');
+    fclose(modvecfile);
+    
+    %run the modulator
+    system(command);
+    
+    bitvecfile = fopen(bitvecfilename,'rb');
+    bits = fread(bitvecfile,'uint8');
+    fclose(bitvecfile);
+    bits = bits!=0;
+    
+    %Load test vec dump
+    load(tvecfilename);
+    
+    %Clean up files
+    delete(bitvecfilename);
+    delete(modvecfilename);
+    delete(tvecfilename);
+    
+    o_f1_dc = [];
+    o_f2_dc = [];
+    o_f3_dc = [];
+    o_f4_dc = [];
+    o_f1_int = [];
+    o_f2_int = [];
+    o_f3_int = [];
+    o_f4_int = [];
+    o_f1 = [];
+    o_f2 = [];
+    o_f3 = [];
+    o_f4 = [];
+    o_EbNodB = [];
+    o_ppm = [];
+    o_Sf = [];
+    o_fest = [];
+    o_rx_timing = [];
+    o_norm_rx_timing = [];
+    o_nin = [];
+    %Run octave demod, dump some test vectors
+    states = fsk_horus_init_hbr(Fs,10,Rs,M);
+    Ts = states.Ts;
+    P = states.P;
+    states.ftx(1) = f1;
+    states.ftx(2) = f1+fsp;
+    states.ftx(3) = f1+fsp*2;
+    states.ftx(4) = f1+fsp*3;
+    states.dA = 1;
+    states.dF = 0;
+    modin = mod;
+    obits = [];
+    while length(modin)>=states.nin
+        ninold = states.nin;
+        states = est_freq(states, modin(1:states.nin), states.M);
+        [bitbuf,states] = fsk_horus_demod(states, modin(1:states.nin));
+        modin=modin(ninold+1:length(modin));
+        obits = [obits bitbuf];
+        
+        %Save other parameters
+        o_f1_dc = [o_f1_dc states.f_dc(1,1:states.Nmem-Ts/P)];
+        o_f2_dc = [o_f2_dc states.f_dc(2,1:states.Nmem-Ts/P)];
+        o_f1_int = [o_f1_int states.f_int(1,:)];
+        o_f2_int = [o_f2_int states.f_int(2,:)];
+        o_EbNodB = [o_EbNodB states.EbNodB];
+        o_ppm = [o_ppm states.ppm];
+        o_rx_timing = [o_rx_timing states.rx_timing];
+        o_norm_rx_timing = [o_norm_rx_timing states.norm_rx_timing];
+        o_Sf = [o_Sf states.Sf'];
+        o_f1 = [o_f1 states.f(1)];
+        o_f2 = [o_f1 states.f(2)];
+        o_fest = [o_fest states.f];
+        o_nin = [o_nin states.nin];
+        if M==4
+                       o_f3_dc = [o_f3_dc states.f_dc(3,1:states.Nmem-Ts/P)];
+                       o_f4_dc = [o_f4_dc states.f_dc(4,1:states.Nmem-Ts/P)];
+                       o_f3_int = [o_f3_int states.f_int(3,:)];
+                       o_f4_int = [o_f4_int states.f_int(4,:)];
+                       o_f3 = [o_f1 states.f(3)];
+                       o_f4 = [o_f1 states.f(4)];
+        end
+    end
+    
+    %close all
+    
+    pass = 1;
+    
+    pass = vcompare(o_Sf,  t_fft_est(1:length(o_Sf)),'fft est',tname,1,1) && pass;
+    pass = vcompare(o_fest,  t_f_est,'f est',tname,1,2) && pass;
+    pass = vcompare(o_rx_timing,  t_rx_timing,'rx timing',tname,1,3) && pass;
+    
+    if M==4
+        pass = vcompare(o_f3_dc,      t_f3_dc,    'f3 dc',    tname,1,4) && pass;
+        pass = vcompare(o_f4_dc,      t_f4_dc,    'f4 dc',    tname,1,5) && pass;
+        pass = vcompare(o_f3_int,     t_f3_int,   'f3 int',   tname,1,6) && pass;
+        pass = vcompare(o_f4_int,     t_f4_int,   'f4 int',   tname,1,7) && pass;
+    end
+    
+    pass = vcompare(o_f1_dc,      t_f1_dc,    'f1 dc',    tname,1,8) && pass;
+    pass = vcompare(o_f2_dc,      t_f2_dc,    'f2 dc',    tname,1,9) && pass;
+    pass = vcompare(o_f2_int,     t_f2_int,   'f2 int',   tname,1,10) && pass;
+    pass = vcompare(o_f1_int,     t_f1_int,   'f1 int',   tname,1,11) && pass;
+
+    pass = vcompare(o_ppm   ,     t_ppm,      'ppm',      tname,1,12) && pass;
+    pass = vcompare(o_EbNodB,     t_EbNodB,'EbNodB',      tname,1,13) && pass;
+    pass = vcompare(o_nin,        t_nin,      'nin',      tname,1,14) && pass;
+    pass = vcompare(o_norm_rx_timing,  t_norm_rx_timing,'norm rx timing',tname,1,15) && pass;
+    
+    
+    diffpass = sum(xor(obits,bits'))<5;
+    diffbits = sum(xor(obits,bits'));
+    
+    if print_verbose == 1
+        printf('%d bit diff in test %s\n',diffbits,tname);
+    end
+    if diffpass==0
+        printf('\n***bitcompare test failed test %s diff %d\n\n',tname,sum(xor(obits,bits')))
+        figure(15)
+        plot(xor(obits,bits'))
+        title(sprintf('Bitcompare failure test %s',tname))
+    end
+    
+    pass = pass && diffpass;
+    
+    assert(pass);
+    
+    test_stats.pass = pass;
+    test_stats.diff = sum(xor(obits,bits'));
+    test_stats.cbits = bits';
+    test_stats.obits = obits;
+    
+endfunction
+
+function [dmod,cmod,omod,pass] = fsk_mod_test(Fs,Rs,f1,fsp,bits,tname,M=2)
+    global mod_pass_fail_maxdiff;
+    %Run the C modulator
+    cmod = fsk_mod_c(Fs,Rs,f1,fsp,bits,M);
+    %Set up and run the octave modulator
+    states.M = M;
+    states = fsk_horus_init_hbr(Fs,10,Rs,M);
+    
+    states.ftx(1) = f1;
+    states.ftx(2) = f1+fsp;
+    
+    if states.M == 4
+               states.ftx(3) = f1+fsp*2;
+               states.ftx(4) = f1+fsp*3;
+    end
+    
+    states.dA = [1 1 1 1]; 
+    states.dF = 0;
+    omod = fsk_horus_mod(states,bits);
+    
+    dmod = cmod-omod;
+    pass = max(dmod)<(mod_pass_fail_maxdiff*length(dmod));
+    if !pass
+        printf('Mod failed test %s!\n',tname);
+    end
+endfunction
+
+% Random bit modulator test
+% Pass random bits through the modulators and compare
+function pass = test_mod_2400a_randbits
+    rand('state',1); 
+    randn('state',1);
+    bits = rand(1,96000)>.5;
+    [dmod,cmod,omod,pass] = fsk_mod_test(48000,1200,1200,1200,bits,"mod 2400a randbits",4);
+    
+    if(!pass)
+        figure(1)
+        plot(dmod)
+        title("Difference between octave and C mod impl");
+    end
+    
+endfunction
+
+
+% A big ol' channel impairment tester
+% Shamlessly taken from fsk_horus
+% This throws some channel imparment or another at the C and octave modem so they 
+% may be compared.
+function stats = tfsk_run_sim(test_frame_mode,EbNodB,timing_offset,fading,df,dA,M=2)
+  global print_verbose;
+  frames = 190;
+  %EbNodB = 10;
+  %timing_offset = 2.0; % see resample() for clock offset below
+  %fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+  %df     = 0;          % tx tone freq drift in Hz/s
+  %dA     = 1;          % amplitude imbalance of tones (note this affects Eb so not a gd idea)
+
+  more off
+  rand('state',10); 
+  randn('state',10);
+
+  % ----------------------------------------------------------------------
+
+  % sm2000 config ------------------------
+  %states = fsk_horus_init(96000, 1200);
+  %states.f1_tx = 4000;
+  %states.f2_tx = 5200;
+  
+  if test_frame_mode == 2
+    % 2400A config
+    states = fsk_horus_init_hbr(48000,10, 1200, M);
+    states.f1_tx = 1200;
+    states.f2_tx = 2400;
+    states.f3_tx = 3600;
+    states.f4_tx = 4800;
+    states.ftx(1) = 1200;
+    states.ftx(2) = 2400;
+    states.ftx(3) = 3600;
+    states.ftx(4) = 4800;
+    
+  end
+
+  if test_frame_mode == 4
+    % horus rtty config ---------------------
+    states = fsk_horus_init_hbr(48000,10, 1200, M);
+    states.f1_tx = 1200;
+    states.f2_tx = 2400;
+    states.f3_tx = 3600;
+    states.f4_tx = 4800;
+    states.ftx(1) = 1200;
+    states.ftx(2) = 2400;
+    states.ftx(3) = 3600;
+    states.ftx(4) = 4800;
+    
+    states.tx_bits_file = "horus_tx_bits_rtty.txt"; % Octave file of bits we FSK modulate
+    
+  end
+                               
+  if test_frame_mode == 5
+    % horus binary config ---------------------
+    states = fsk_horus_init_hbr(48000,10, 1200, M);
+    states.f1_tx = 1200;
+    states.f2_tx = 2400;
+    states.f3_tx = 3600;
+    states.f4_tx = 4800;
+    states.ftx(1) = 1200;
+    states.ftx(2) = 2400;
+    states.ftx(3) = 3600;
+    states.ftx(4) = 4800;
+    %%%states.tx_bits_file = "horus_tx_bits_binary.txt"; % Octave file of bits we FSK modulate
+       states.tx_bits_file = "horus_payload_rtty.txt";
+  end
+
+  % ----------------------------------------------------------------------
+
+  states.verbose = 0;%x1;
+  N = states.N;
+  P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym;
+  Fs = states.Fs;
+  states.df = df;
+  states.dA = [dA dA dA dA];
+  states.M = M;
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rs*EbNo*states.bitspersymbol);
+
+  % set up tx signal with payload bits based on test mode
+
+  if test_frame_mode == 1
+     % test frame of bits, which we repeat for convenience when BER testing
+    test_frame = round(rand(1, states.nsym));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, states.nbit*(frames+1)));
+  end
+  if test_frame_mode == 3
+    % ...10101... sequence
+    tx_bits = zeros(1, states.nsym*(frames+1));
+    tx_bits(1:2:length(tx_bits)) = 1;
+  end
+  if (test_frame_mode == 4) || (test_frame_mode == 5)
+
+    % load up a horus msg from disk and modulate that
+
+    test_frame = load(states.tx_bits_file);
+    ltf = length(test_frame);
+    ntest_frames = ceil((frames+1)*nsym/ltf);
+    tx_bits = [];
+    for i=1:ntest_frames
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  
+  
+  
+  f1 = states.f1_tx;
+  fsp = states.f2_tx-f1;
+  states.dA = [dA dA dA dA];
+  states.ftx(1) = f1;
+  states.ftx(2) = f1+fsp;
+    
+  if states.M == 4
+       states.ftx(3) = f1+fsp*2;
+       states.ftx(4) = f1+fsp*3;
+  end
+
+  tx = fsk_horus_mod(states, tx_bits);
+
+  if timing_offset
+    tx = resample(tx, 1000, 1001); % simulated 1000ppm sample clock offset
+  end
+  
+  if fading
+     ltx = length(tx);
+     tx = tx .* (1.1 + cos(2*pi*2*(0:ltx-1)/Fs))'; % min amplitude 0.1, -20dB fade, max 3dB
+  end
+
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise;
+  
+  test_name = sprintf("tfsk EbNodB:%d frames:%d timing_offset:%d fading:%d df:%d",EbNodB,frames,timing_offset,fading,df);
+  tstats = fsk_demod_xt(Fs,Rs,states.f1_tx,fsp,rx,test_name,M);
+  
+  pass = tstats.pass;
+  obits = tstats.obits;
+  cbits = tstats.cbits;
+  stats.name = test_name;
+  
+  if tstats.pass 
+    printf("Test %s passed\n",test_name);
+  else
+    printf("Test %s failed\n",test_name);
+  end
+  
+  % Figure out BER of octave and C modems
+  bitcnt = length(tx_bits);
+  rx_bits = obits;
+  ber = 1;
+  ox = 1;
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),tx_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  bero = ber;
+  ber = 1;
+  rx_bits = cbits;
+  ox = 1;
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),tx_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  berc = ber;
+  stats.berc = berc;
+  stats.bero = bero;
+  % coherent BER theory calculation
+  
+  if print_verbose == 1
+    printf("C BER: %f Oct BER: %f Test %s\n",berc,bero,test_name);
+  end
+  
+  stats.thrcoh = .5*(M-1)*erfc(sqrt( (log2(M)/2) * EbNo ));
+  
+  % non-coherent BER theory calculation
+  % It was complicated, so I broke it up
+
+  ms = M;
+  ns = (1:ms-1);
+  as = (-1).^(ns+1);
+  bs = (as./(ns+1));
+  
+  cs = ((ms-1)./ns);
+
+  ds = ns.*log2(ms);
+  es = ns+1;
+  fs = exp( -(ds./es)*EbNo );
+  
+  thrncoh = ((ms/2)/(ms-1)) * sum(bs.*((ms-1)./ns).*exp( -(ds./es)*EbNo ));
+  
+  stats.thrncoh = thrncoh;
+  stats.pass = pass;
+endfunction
+
+
+function pass = ebno_battery_test(timing_offset,fading,df,dA,M)
+    %Range of EbNodB over which to test
+    ebnodbrange = fliplr(5:2:13);
+    ebnodbs = length(ebnodbrange);
+    
+    mode = 2;
+    %Replication of other parameters for parcellfun
+    modev   = repmat(mode,1,ebnodbs);
+    timingv = repmat(timing_offset,1,ebnodbs);
+    fadingv = repmat(fading,1,ebnodbs);
+    dfv     = repmat(df,1,ebnodbs);
+    dav     = repmat(dA,1,ebnodbs);
+    mv      = repmat(M,1,ebnodbs);
+    statv = pararrayfun(floor(1.25*nproc()),@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,mv);
+    %statv = arrayfun(@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,mv);
+
+    passv = zeros(1,length(statv));
+    for ii=(1:length(statv))
+        passv(ii)=statv(ii).pass;
+        if statv(ii).pass
+            printf("Test %s passed\n",statv(ii).name);
+        else
+            printf("Test %s failed\n",statv(ii).name);
+        end
+            
+    end
+    
+    %All pass flags are '1'
+    pass = sum(passv)>=length(passv);
+    %and no tests died
+    pass = pass && length(passv)==ebnodbs;
+    passv;
+    assert(pass)
+endfunction
+
+%Test with and without sample clock offset
+function pass = test_timing_var(df,dA,M)
+    pass = ebno_battery_test(1,0,df,dA,M)
+    assert(pass)
+    pass = pass && ebno_battery_test(0,0,df,dA,M)
+    assert(pass)
+endfunction
+
+%Test with and without 1 Hz/S freq drift
+function pass = test_drift_var(M)
+    pass = test_timing_var(1,1,M)
+    assert(pass)
+    pass = pass && test_timing_var(0,1,M)
+    assert(pass)
+endfunction
+
+function pass = test_fsk_battery()
+    pass = 1;
+    pass = pass && test_mod_2400a_randbits;
+    assert(pass)
+    pass = pass && test_drift_var(4);
+    assert(pass)
+    if pass
+        printf("***** All tests passed! *****\n");
+    end
+endfunction
+
+function plot_fsk_bers(M=2)
+    %Range of EbNodB over which to plot
+    ebnodbrange = (4:13);
+    
+    berc = ones(1,length(ebnodbrange));
+    bero = ones(1,length(ebnodbrange));
+    berinc = ones(1,length(ebnodbrange));
+    beric = ones(1,length(ebnodbrange));
+    ebnodbs = length(ebnodbrange)
+    mode = 2;
+    %Replication of other parameters for parcellfun
+    modev   = repmat(mode,1,ebnodbs);
+    timingv = repmat(1,1,ebnodbs);
+    fadingv = repmat(0,1,ebnodbs);
+    dfv     = repmat(1,1,ebnodbs);
+    dav     = repmat(1,1,ebnodbs);
+    Mv     = repmat(M,1,ebnodbs);
+    
+    
+    statv = pararrayfun(floor(nproc()),@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,Mv);
+    %statv = arrayfun(@tfsk_run_sim,modev,ebnodbrange,timingv,fadingv,dfv,dav,Mv);
+    
+    for ii = (1:length(statv))
+        stat = statv(ii);
+        berc(ii)=stat.berc;
+        bero(ii)=stat.bero;
+        berinc(ii)=stat.thrncoh;
+        beric(ii) = stat.thrcoh;
+    end
+    clf;
+    figure(M)
+    
+    semilogy(ebnodbrange, berinc,sprintf('r;%dFSK non-coherent theory;',M))
+    hold on;
+    semilogy(ebnodbrange, beric ,sprintf('g;%dFSK coherent theory;',M))
+    semilogy(ebnodbrange, bero ,sprintf('b;Octave fsk horus %dFSK Demod;',M))
+    semilogy(ebnodbrange, berc,sprintf('+;C fsk horus %dFSK Demod;',M))
+    hold off;
+    grid("minor");
+    axis([min(ebnodbrange) max(ebnodbrange) 1E-5 1])
+    legend("boxoff");
+    xlabel("Eb/No (dB)");
+    ylabel("Bit Error Rate (BER)")
+endfunction
+
+
+xpass = test_fsk_battery
+%plot_fsk_bers(2)
+plot_fsk_bers(4)
+
+if xpass
+    printf("***** All tests passed! *****\n");
+else
+    printf("***** Some test failed! Look back thorugh output to find failed test *****\n");
+end
diff --git a/codec2/branches/0.7/octave/tget_spec.m b/codec2/branches/0.7/octave/tget_spec.m
new file mode 100644 (file)
index 0000000..e46c1ea
--- /dev/null
@@ -0,0 +1,49 @@
+% tget-spec.m
+%
+% Used in conjunction with src/fdmdv_demod to test the
+% fdmdv_get_rx_spectrum() function.
+%
+% codec2-dev/src$ ./fdmdv_demod fdmdv_mod.raw tmp.c2 dump.txt
+% octave:3> tget_spec("../src/dump.txt")
+%
+% Copyright David Rowe 2012
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+%
+
+function tfft_log(dumpfilename)
+
+  load(dumpfilename);
+
+  [rows cols] = size(rx_spec_log_c);
+  Fs = 8000; low_freq = 0; high_freq = 2500;
+  res = (Fs/2)/cols;
+  st_bin = low_freq/res + 1;
+  en_bin = high_freq/res;
+  xaxis = (st_bin:en_bin)*res;
+
+  f_start = 2; f_end = 100;
+  beta = 0.1;
+
+  av = zeros(f_end, en_bin-st_bin+1);
+  for r=f_start:f_end
+      x = (1-beta)*av(r-1,:) + beta*rx_spec_log_c(r,st_bin:en_bin);
+      av(r,:) = x;
+  end
+
+  % spectrogram (waterfall)
+
+  figure(1)
+  clf;
+  imagesc(av,[-40 0]);
+
+  % animated spectrum display
+
+  figure(2)
+  clf;
+  for r=f_start:f_end
+      plot(xaxis, av(r,:))
+      axis([ low_freq high_freq -40 0])
+      sleep(0.1)
+  end
+endfunction
diff --git a/codec2/branches/0.7/octave/tlinreg.m b/codec2/branches/0.7/octave/tlinreg.m
new file mode 100644 (file)
index 0000000..1cde350
--- /dev/null
@@ -0,0 +1,14 @@
+% tlinreg
+% David Rowe April 2015
+%
+% Unit test for linear regression
+
+x = [1 2 7 8];
+y = [ -0.70702 + 0.70708i 0.77314 - 0.63442i -0.98083 + 0.19511i 0.99508 - 0.09799i] .* [1 -1 1 -1];
+[m b] = linreg(x,y,4);
+x = [1 2 3 4 5 6 7 8];
+yFit = m * x + b;
+figure(1)
+plot(yFit,'r*')
+axis([-1.5 1.5 -1.5 1.5])
diff --git a/codec2/branches/0.7/octave/tnewamp1.m b/codec2/branches/0.7/octave/tnewamp1.m
new file mode 100644 (file)
index 0000000..be6788e
--- /dev/null
@@ -0,0 +1,237 @@
+% tnewamp1.m
+%
+% Copyright David Rowe 2017
+% This program is distributed under the terms of the GNU General Public License 
+% Version 2
+
+#{
+
+  Octave script to compare Octave and C versions of newamp1 processing, in order to test C port.
+
+  c2sim -> dump files -> $ ../build_linux/unittest/tnewamp1 -> octave:1> tnewamp1
+  Usage:
+
+    1/ build codec2 with -DDUMP - see codec2-dev/README
+
+    2/ Generate dump files using c2sim (just need to do this once)
+       $ cd codec2-dev/build_linux/src
+       $ ./c2sim ../../raw/hts1a.raw --phase0 --postfilter --dump hts1a --lpc 10 --dump_pitch_e hts1a_pitche.txt
+
+    3/ Run C version which generates a file of Octave test vectors as ouput:
+
+      $ cd codec2-dev/build_linux/unittest
+      $ ./tnewamp1 ../../raw/hts1a
+            
+    4/ Run Octave script to generate Octave test vectors and compare with C.
+
+      octave:1> tnewamp1("../build_linux/src/hts1a")
+
+    5/ Optionally listen to output
+
+     ~/codec2-dev/build_linux/src$ ./c2sim ../../raw/hts1a.raw --phase0 --postfilter \
+                                   --amread hts1a_am.out --hmread hts1a_hm.out \
+                                   --Woread hts1a_Wo.out --hand_voicing hts1a_v.txt -o - \
+                                      | play -q -t raw -r 8000 -s -2 -
+#}
+
+
+% In general, this function processes a bunch of amplitudes, we then
+% use c2sim to hear the results.  Bunch of different experiments below
+
+function tnewamp1(input_prefix)
+  newamp;
+  autotest;
+  more off;
+
+  max_amp = 80;
+  postfilter = 0;   % optional postfiler that runs on Am, not used atm
+  synth_phase = 1;
+
+  if nargin == 1
+    output_prefix = input_prefix;
+  end
+  model_name = strcat(input_prefix,"_model.txt");
+  model = load(model_name);
+  [frames nc] = size(model);
+
+  voicing_name = strcat(input_prefix,"_pitche.txt");
+  voicing = zeros(1,frames);
+  
+  if exist(voicing_name, "file") == 2
+    pitche = load(voicing_name);
+    voicing = pitche(:, 3);
+  end
+
+  % Load in C vectors and compare -----------------------------------------
+  load("../build_linux/unittest/tnewamp1_out.txt");
+  
+  K = 20;
+  [frames tmp] = size(rate_K_surface_c);
+  [rate_K_surface sample_freqs_kHz] = resample_const_rate_f_mel(model(1:frames,:), K);
+
+  melvq;
+  load train_120_vq; m=5;
+       
+  for f=1:frames
+    mean_f(f) = mean(rate_K_surface(f,:));
+    rate_K_surface_no_mean(f,:) = rate_K_surface(f,:) - mean_f(f);
+  end
+
+  [res rate_K_surface_no_mean_ ind] = mbest(train_120_vq, rate_K_surface_no_mean, m);
+
+  for f=1:frames
+    rate_K_surface_no_mean_(f,:) = post_filter(rate_K_surface_no_mean_(f,:), sample_freqs_kHz, 1.5);
+  end
+    
+  rate_K_surface_ = zeros(frames, K);
+  interpolated_surface_ = zeros(frames, K);
+  energy_q = create_energy_q;
+  M = 4;
+  for f=1:frames   
+    [mean_f_ indx] = quantise(energy_q, mean_f(f));
+    indexes(f,3) = indx - 1;
+    rate_K_surface_(f,:) = rate_K_surface_no_mean_(f,:) + mean_f_;
+  end
+
+  % simulated decoder
+  % break into segments of M frames.  We have 2 samples spaced M apart
+  % and interpolate the rest.
+
+  Nfft_phase = 128;  % note this needs to be 512 (FFT_ENC in codec2 if using --awread)
+                     % with --hmread 128 is preferred as less memory/CPU
+  model_ = zeros(frames, max_amp+2);
+  voicing_ = zeros(1,frames);
+  Aw = zeros(frames, Nfft_phase);
+  H = zeros(frames, max_amp);
+  model_(1,1) = Wo_left = 2*pi/100;
+  voicing_left = 0;
+  left_vec = zeros(1,K);
+
+  % decoder runs on every M-th frame, 25Hz frame rate, offset at
+  % start is to minimise processing delay (thanks Jeroen!)
+
+  for f=M:M:frames   
+
+    if voicing(f)
+      index = encode_log_Wo(model(f,1), 6);
+      if index == 0
+        index = 1;
+      end
+      model_(f,1) = decode_log_Wo(index, 6);
+    else
+      model_(f,1) = 2*pi/100;
+    end
+
+    Wo_right = model_(f,1);
+    voicing_right = voicing(f);
+    [Wo_ avoicing_] = interp_Wo_v(Wo_left, Wo_right, voicing_left, voicing_right);
+
+    if f > M
+      model_(f-M:f-1,1) = Wo_;
+      voicing_(f-M:f-1) = avoicing_;
+      model_(f-M:f-1,2) = floor(pi ./ model_(f-M:f-1,1)); % calculate L for each interpolated Wo
+    end
+
+    right_vec = rate_K_surface_(f,:);
+
+    if f > M
+      sample_points = [f-M f];
+      resample_points = f-M:f-1;
+      for k=1:K
+        interpolated_surface_(resample_points,k) = interp_linear(sample_points, [left_vec(k) right_vec(k)], resample_points);
+      end
+
+      for k=f-M:f-1
+        model_(k,:) = resample_rate_L(model_(k,:), interpolated_surface_(k,:), sample_freqs_kHz);
+        Aw(k,:) = determine_phase(model_, k, Nfft_phase);
+        for m=1:model_(k,2)
+          b = round(m*model_(k,1)*Nfft_phase/(2*pi));  % map harmonic centre to DFT bin
+          H(k,m) = exp(j*Aw(k, b+1));          
+        end     
+      end
+   end
+   
+   % update for next time
+
+   Wo_left = Wo_right;
+   voicing_left = voicing_right;
+   left_vec = right_vec;
+   
+  end
+  
+  figure(1); clf;
+  mesh(angle(H));
+  figure(2); clf;
+  mesh(angle(H_c));
+  figure(3); clf;
+  mesh(abs(H - H_c));
+
+  check(rate_K_surface, rate_K_surface_c, 'rate_K_surface', 0.01);
+  check(mean_f, mean_c, 'mean', 0.01);
+  check(rate_K_surface_, rate_K_surface__c, 'rate_K_surface_', 0.01);
+  check(interpolated_surface_, interpolated_surface__c, 'interpolated_surface_', 0.01);
+  check(model_(:,1), model__c(:,1), 'interpolated Wo_', 0.001);
+  check(voicing_, voicing__c, 'interpolated voicing');
+  check(model_(:,3:max_amp+2), model__c(:,3:max_amp+2), 'rate L Am surface ', 0.1);
+  check(H, H_c, 'phase surface');
+
+  % Save to disk to check synthesis is OK with c2sim  
+
+  output_prefix = input_prefix;
+  Am_out_name = sprintf("%s_am.out", output_prefix);
+  fam  = fopen(Am_out_name,"wb"); 
+
+  Wo_out_name = sprintf("%s_Wo.out", output_prefix);
+  fWo  = fopen(Wo_out_name,"wb"); 
+  
+  Aw_out_name = sprintf("%s_aw.out", output_prefix);
+  faw = fopen(Aw_out_name,"wb"); 
+
+  Hm_out_name = sprintf("%s_hm.out", output_prefix);
+  fhm = fopen(Hm_out_name,"wb"); 
+
+  printf("Generating files for c2sim: ");
+  for f=1:frames
+    printf(".", f);   
+    Wo = model_(f,1);
+    L = min([model_(f,2) max_amp-1]);
+    Am = model_(f,3:(L+2));
+
+    Am_ = zeros(1,max_amp);
+    Am_(2:L) = Am(1:L-1);
+
+    fwrite(fam, Am_, "float32");
+    fwrite(fWo, Wo, "float32");
+
+    % Note we send opposite phase as c2sim expects phase of LPC
+    % analysis filter, just a convention based on historical
+    % development of Codec 2
+
+    Aw1 = zeros(1, Nfft_phase*2); 
+    Aw1(1:2:Nfft_phase*2) = cos(Aw(f,:));
+    Aw1(2:2:Nfft_phase*2) = -sin(Aw(f,:));
+    fwrite(faw, Aw1, "float32");    
+
+    Hm = zeros(1, 2*max_amp);
+    for m=1:L
+        Hm(2*m+1) = real(H(f,m));
+        Hm(2*m+2) = imag(H(f,m));
+    end    
+    fwrite(fhm, Hm, "float32");    
+  end
+
+  fclose(fam); fclose(fWo); fclose(faw); fclose(fhm);
+
+  v_out_name = sprintf("%s_v.txt", output_prefix);
+  fv  = fopen(v_out_name,"wt"); 
+  for f=1:length(voicing__c)
+    fprintf(fv,"%d\n", voicing__c(f));
+  end
+  fclose(fv);
+
+  printf("\n")
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/tofdm.m b/codec2/branches/0.7/octave/tofdm.m
new file mode 100644 (file)
index 0000000..73b99fe
--- /dev/null
@@ -0,0 +1,159 @@
+% tofdm.m
+% David Rowe and Steve Sampson June 2017
+%
+% Octave script for comparing Octave and C versions of OFDZM modem
+
+% ------------------------------------------------------------------
+
+Nframes = 30;
+sample_clock_offset_ppm = 100;
+foff_hz = 0.5;
+
+more off; format;
+ofdm_lib;
+autotest;
+
+% ---------------------------------------------------------------------
+% Run Octave version 
+% ---------------------------------------------------------------------
+
+Ts = 0.018; Tcp = 0.002; Rs = 1/Ts; bps = 2; Nc = 16; Ns = 8;
+states = ofdm_init(bps, Rs, Tcp, Ns, Nc);
+ofdm_load_const;
+
+rand('seed',1);
+tx_bits = round(rand(1,Nbitsperframe));
+
+% Run tx loop
+
+tx_bits_log = []; tx_log = [];
+for f=1:Nframes
+  tx_bits_log = [tx_bits_log tx_bits];
+  tx_log = [tx_log ofdm_mod(states, tx_bits)];
+end
+
+% Channel simulation ----------------------------------------------
+
+rx_log = sample_clock_offset(tx_log, sample_clock_offset_ppm);
+rx_log = freq_shift(rx_log, foff_hz, Fs);
+
+% Rx ---------------------------------------------------------------
+
+% Init rx with ideal timing so we can test with timing estimation disabled
+
+Nsam = length(rx_log);
+prx = 1;
+nin = Nsamperframe+2*(M+Ncp);
+states.rxbuf(Nrxbuf-nin+1:Nrxbuf) = rx_log(prx:nin);
+prx += nin;
+
+rxbuf_log = []; rxbuf_in_log = []; rx_sym_log = []; foff_hz_log = []; 
+timing_est_log = []; sample_point_log = []; 
+phase_est_pilot_log = []; rx_amp_log = [];
+rx_np_log = []; rx_bits_log = [];
+
+states.timing_en = 1;
+states.foff_est_en = 1;
+states.phase_est_en = 1;
+
+if states.timing_en == 0
+  % manually set ideal timing instant
+  states.sample_point = Ncp;
+end
+
+for f=1:Nframes
+
+  % insert samples at end of buffer, set to zero if no samples
+  % available to disable phase estimation on future pilots on last
+  % frame of simulation
+  nin = states.nin;
+  lnew = min(Nsam-prx+1,nin);
+  rxbuf_in = zeros(1,nin);
+  %printf("nin: %d prx: %d lnew: %d\n", nin, prx, lnew);
+  if lnew
+    rxbuf_in(1:lnew) = rx_log(prx:prx+lnew-1);
+  end
+  prx += lnew;
+
+  [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in);
+
+  % log some states for comparison to C
+
+  rxbuf_in_log = [rxbuf_in_log rxbuf_in];
+  rxbuf_log = [rxbuf_log states.rxbuf];
+  rx_sym_log = [rx_sym_log; states.rx_sym];
+  phase_est_pilot_log = [phase_est_pilot_log; aphase_est_pilot_log];
+  rx_amp_log = [rx_amp_log arx_amp];
+  foff_hz_log = [foff_hz_log; states.foff_est_hz];
+  timing_est_log = [timing_est_log; states.timing_est];
+  sample_point_log = [sample_point_log; states.sample_point];
+  rx_np_log = [rx_np_log arx_np];
+  rx_bits_log = [rx_bits_log rx_bits];
+  
+end
+
+% ---------------------------------------------------------------------
+% Run C version and plot Octave and C states and differences 
+% ---------------------------------------------------------------------
+
+% Override default path by setting path_to_tofdm = "/your/path/to/tofdm"
+
+if exist("path_to_tofdm", "var") == 0
+   path_to_tofdm = "../build_linux/unittest/tofdm";
+end
+system(path_to_tofdm);
+
+load tofdm_out.txt;
+
+fg = 1;
+figure(fg++); clf; plot(rx_np_log,'+'); title('Octave Scatter Diagram'); axis([-1.5 1.5 -1.5 1.5]);
+figure(fg++); clf; plot(rx_np_log_c,'+'); title('C Scatter Diagram'); axis([-1.5 1.5 -1.5 1.5]);
+
+stem_sig_and_error(fg++, 111, tx_bits_log_c, tx_bits_log - tx_bits_log_c, 'tx bits', [1 length(tx_bits_log) -1.5 1.5])
+
+stem_sig_and_error(fg, 211, real(tx_log_c), real(tx_log - tx_log_c), 'tx re', [1 length(tx_log_c) -0.1 0.1])
+stem_sig_and_error(fg++, 212, imag(tx_log_c), imag(tx_log - tx_log_c), 'tx im', [1 length(tx_log_c) -0.1 0.1])
+
+stem_sig_and_error(fg, 211, real(rx_log_c), real(rx_log - rx_log_c), 'rx re', [1 length(rx_log_c) -0.1 0.1])
+stem_sig_and_error(fg++, 212, imag(rx_log_c), imag(rx_log - rx_log_c), 'rx im', [1 length(rx_log_c) -0.1 0.1])
+
+stem_sig_and_error(fg, 211, real(rxbuf_in_log_c), real(rxbuf_in_log - rxbuf_in_log_c), 'rxbuf in re', [1 length(rxbuf_in_log_c) -0.1 0.1])
+stem_sig_and_error(fg++, 212, imag(rxbuf_in_log_c), imag(rxbuf_in_log - rxbuf_in_log_c), 'rxbuf in im', [1 length(rxbuf_in_log_c) -0.1 0.1])
+
+stem_sig_and_error(fg, 211, real(rxbuf_log_c), real(rxbuf_log - rxbuf_log_c), 'rxbuf re', [1 length(rxbuf_log_c) -0.1 0.1])
+stem_sig_and_error(fg++, 212, imag(rxbuf_log_c), imag(rxbuf_log - rxbuf_log_c), 'rxbuf im', [1 length(rxbuf_log_c) -0.1 0.1])
+
+stem_sig_and_error(fg, 211, real(rx_sym_log_c), real(rx_sym_log - rx_sym_log_c), 'rx sym re', [1 length(rx_sym_log_c) -1.5 1.5])
+stem_sig_and_error(fg++, 212, imag(rx_sym_log_c), imag(rx_sym_log - rx_sym_log_c), 'rx sym im', [1 length(rx_sym_log_c) -1.5 1.5])
+
+% for angles pi and -pi are the same
+
+d = phase_est_pilot_log - phase_est_pilot_log_c; d = angle(exp(j*d));
+
+stem_sig_and_error(fg, 211, phase_est_pilot_log_c, d, 'phase est pilot', [1 length(phase_est_pilot_log_c) -1.5 1.5])
+stem_sig_and_error(fg++, 212, rx_amp_log_c, rx_amp_log - rx_amp_log_c, 'rx amp', [1 length(rx_amp_log_c) -1.5 1.5])
+
+stem_sig_and_error(fg++, 111, foff_hz_log_c, (foff_hz_log - foff_hz_log_c), 'foff hz', [1 length(foff_hz_log_c) -1.5 1.5])
+
+stem_sig_and_error(fg,   211, timing_est_log_c, (timing_est_log - timing_est_log_c), 'timing est', [1 length(timing_est_log_c) -1.5 1.5])
+stem_sig_and_error(fg++, 212, sample_point_log_c, (sample_point_log - sample_point_log_c), 'sample point', [1 length(sample_point_log_c) -1.5 1.5])
+
+stem_sig_and_error(fg++, 111, rx_bits_log_c, rx_bits_log - rx_bits_log_c, 'rx bits', [1 length(rx_bits_log) -1.5 1.5])
+
+% Run through checklist -----------------------------
+
+check_no_abs(W, W_c, 'W');
+check(tx_bits_log, tx_bits_log_c, 'tx_bits');
+check(tx_log, tx_log_c, 'tx');
+check(rx_log, rx_log_c, 'rx');
+check(rxbuf_in_log, rxbuf_in_log_c, 'rxbuf in');
+check(rxbuf_log, rxbuf_log_c, 'rxbuf');
+check(rx_sym_log, rx_sym_log_c, 'rx_sym');
+check(phase_est_pilot_log, phase_est_pilot_log_c, 'phase_est_pilot', tol=1E-3, its_an_angle=1);
+check(rx_amp_log, rx_amp_log_c, 'rx_amp');
+check(timing_est_log, timing_est_log_c, 'timing_est');
+check(sample_point_log, sample_point_log_c, 'sample_point');
+check(foff_hz_log, foff_hz_log_c, 'foff_est_hz');
+check(rx_bits_log, rx_bits_log_c, 'rx_bits');
+
diff --git a/codec2/branches/0.7/octave/tpapr.m b/codec2/branches/0.7/octave/tpapr.m
new file mode 100644 (file)
index 0000000..194d9a7
--- /dev/null
@@ -0,0 +1,35 @@
+% tpapr.m
+% David Rowe
+% 18 May 2015
+
+graphics_toolkit ("gnuplot");
+rand('state',1); 
+
+Fs = 8000;
+Rs = 50;
+Nc = 8;
+Fc = 1500;
+Fsep = ((1:Nc).^1.2)*75;
+%Fsep = (1:Nc)*75 + 5 - 20*rand(1,Nc)
+n  = 80000;
+t = 1:n;
+tx = zeros(1,n);
+phi = ones(1,Nc);
+
+figure(1)
+clf
+
+for m=1:Nc
+    s = cos(phi(m)+t*2*pi*(Rs/2 + Fc + Fsep(m))/Fs);
+    tx += s;
+    subplot(Nc,1,m);
+    plot(s)
+end
+
+figure(2)
+plot(tx)
+
+tx = tx(length(tx)*0.5:length(tx));
+papr = max(tx.*conj(tx)) / mean(tx.*conj(tx));
+papr_dB = 10*log10(papr);
+printf("PAPR: %4.2f dB\n", papr_dB);
diff --git a/codec2/branches/0.7/octave/tqpsk.m b/codec2/branches/0.7/octave/tqpsk.m
new file mode 100644 (file)
index 0000000..f6557c9
--- /dev/null
@@ -0,0 +1,230 @@
+% tqpsk.m
+%
+% David Rowe Sep 2015
+%
+% QPSK modem Octave test scripts
+
+% TODO:
+%   correct freq offset
+%   output tx frame to a file of bits for 3rd party modulator
+%   improve phase est impl loss using longer window
+%   separate into mod and demod functions
+%   generate filter coeffs, save to C header file
+%   fine timing estimator and meas IL
+%   coarse timing (frame sync)
+
+% make sure we get same random numbers every time
+
+more off;
+qpsk;
+ldpc;
+
+
+function [aqpsk code_param] = init_modem_ldpc
+
+  % Init modem ------------------------------------------------------------------------------
+
+  aqpsk.Rbdata        = 2400;                                % bit rate (Hz) of payload data
+  aqpsk.code_rate     = 0.5;
+  aqpsk.framesize     = 1152;                                % number of bits in LDPC encoded frame (data plus parity bits)
+  aqpsk.Ndatabits     = aqpsk.framesize*aqpsk.code_rate;
+  aqpsk.Rbcoded       = aqpsk.Rbdata/aqpsk.code_rate;        % bit rate (Hz) of LPDC coded data
+  aqpsk.Rf            = aqpsk.Rbcoded/aqpsk.framesize;       % frame rate (Hz)
+  aqpsk.bits_per_symb = 2;                                   % QPSK has two bits per symbol
+  aqpsk.Rscoded       = aqpsk.Rbcoded/aqpsk.bits_per_symb;   % symbol rate of LDPC coded data
+  aqpsk.Nsymb         = aqpsk.framesize/aqpsk.bits_per_symb; % number of coded data symbols/frame
+  aqpsk.Npilotstep    = 8;                                   % number of data symbols between each pilot symbol
+
+  aqpsk.Npilotsframe  = (aqpsk.framesize/aqpsk.bits_per_symb)/aqpsk.Npilotstep;
+  if aqpsk.Npilotsframe != floor(aqpsk.Npilotsframe)
+    error("Npilotsframe must be an integer");
+  end
+
+  aqpsk.Nsymbpilot    = aqpsk.Nsymb + aqpsk.Npilotsframe;   % total number of symbols per frame including pilots
+  aqpsk.Rs            = aqpsk.Rf*aqpsk.Nsymbpilot;          % total symbol rate (Hz)
+  aqpsk.pilots        = ones(1, aqpsk.Npilotsframe);
+  aqpsk.Np            = 2;                                  % number of pilots used for phase estimation
+  aqpsk.rx_pilot_buf  = zeros(1,aqpsk.Np);
+
+  % Init LDPC --------------------------------------------------------------------------
+
+  currentdir = pwd;
+  addpath '/home/david/tmp/cml/mat'    % assume the source files stored here
+  cd /home/david/tmp/cml
+  CmlStartup                           % note that this is not in the cml path!
+  cd(currentdir)
+
+  mod_order = 4; 
+  modulation = 'QPSK';
+  mapping = 'gray';
+  demod_type = 0;
+  decoder_type = 0;
+  max_iterations = 100;
+
+  code_param = ldpc_init(aqpsk.code_rate, aqpsk.framesize, modulation, mod_order, mapping);
+  assert(code_param.data_bits_per_frame == aqpsk.Ndatabits);
+
+endfunction
+
+
+function sim_out = run_simulation(sim_in)
+  Ntrials      = sim_in.Ntrials;
+  EsNodBvec    = sim_in.EsNodBvec;
+  verbose      = sim_in.verbose;
+  phase_offset = sim_in.phase_offset;
+  phase_est_en = sim_in.phase_est_en;
+  verbose      = sim_in.verbose;
+
+  rand('state',1); 
+  randn('state',1);
+
+  % Init modem and LPDC ----------------------------------------------------------------
+
+  [aqpsk code_param] = init_modem_ldpc;
+
+  Nsymb = aqpsk.Nsymb;
+  Nsymbpilot = aqpsk.Nsymbpilot;
+
+  % Start simulation -------------------------------------------------------------------
+
+  for ne = 1:length(EsNodBvec)
+    EsNodB = EsNodBvec(ne);
+    EsNo = 10^(EsNodB/10);
+    variance = 1/EsNo;
+
+    Tbits = Terrs_uc = Terrs = Ferrs = 0;
+
+    % Encode a bunch of frames
+
+    for nn = 1: Ntrials        
+      tx_bits = round(rand(1,  aqpsk.Ndatabits));
+      [tx_codeword, tx_coded_symb] = ldpc_enc(tx_bits, code_param);
+      symbpilot_tx = insert_pilots(tx_coded_symb, aqpsk.pilots, aqpsk.Npilotstep);
+
+      noise = sqrt(variance*0.5)*(randn(1,aqpsk.Nsymbpilot) + j*randn(1,aqpsk.Nsymbpilot));
+      symbpilot_rx = symbpilot_tx * exp(j*phase_offset) + noise;
+
+      if phase_est_en
+        symbpilot_rx = correct_phase_offset(aqpsk, symbpilot_rx);
+      end
+      rx_coded_symb = remove_pilots(symbpilot_rx, aqpsk.pilots, aqpsk.Npilotstep);
+      rx_codeword = ldpc_dec(code_param, max_iterations, demod_type, decoder_type, rx_coded_symb, EsNo);
+
+      % measure coded and uncoded errors
+
+      errors_positions = xor(tx_bits, rx_codeword(1:aqpsk.Ndatabits));
+      Nerrs = sum(errors_positions);
+
+      rx_bits_uncoded = zeros(1, aqpsk.Ndatabits);
+      for s=1:Nsymb*aqpsk.code_rate;
+         rx_bits_uncoded(2*(s-1)+1:2*s) = qpsk_demod(rx_coded_symb(s));
+      end
+      errors_positions = xor(tx_bits, rx_bits_uncoded);
+      Nerrs_uc = sum(errors_positions);
+
+      if verbose == 2
+        % print "." if frame decoded without errors, 'x' if we can't decode
+
+        if Nerrs > 0, printf('x'),  else printf('.'),  end
+        if (rem(nn, 50)==0),  printf('\n'),  end    
+      end
+
+      if Nerrs > 0,  Ferrs = Ferrs + 1;  end
+      Terrs = Terrs + Nerrs;
+      Terrs_uc = Terrs_uc + Nerrs_uc;
+      Tbits = Tbits + aqpsk.Ndatabits;        
+    end
+
+    if verbose
+      printf("EsNodB: %3.2f BER: %f Tbits: %d Terrs: %d Ferrs: %d Terrs_uc: %d\n", EsNodB, Terrs/Tbits, Tbits, Terrs,  Ferrs, Terrs_uc);
+    end
+
+    sim_out.Tbits(ne)     = Tbits;
+    sim_out.Terrs(ne)     = Terrs;
+    sim_out.Terrs_uc(ne)  = Terrs_uc;
+    sim_out.Ferrs(ne)     = Ferrs;
+    sim_out.BER(ne)       = Terrs/Tbits;
+    sim_out.FER(ne)       = Ferrs/Ntrials;
+    sim_out.BER_uc(ne)    = Terrs_uc/Tbits;
+  end
+
+  sim_out.code_rate = aqpsk.code_rate;
+end
+
+
+% ----------------------------------------------------------------------
+
+
+function symbol_rate_curves
+  sim_in.phase_est_en = 1;
+  sim_in.phase_offset = 0;
+  sim_in.verbose      = 1;
+  sim_in.EsNodBvec    = -2:10;
+  sim_in.Ntrials      = 10;
+
+  sim_out = run_simulation(sim_in);
+
+  EbNodB = sim_in.EsNodBvec - 10*log10(2);  % QPSK has two bits/symbol
+  uncoded_BER_theory = 0.5*erfc(sqrt(10.^(EbNodB/10)));
+
+  figure(1)
+  clf
+  semilogy(EbNodB, uncoded_BER_theory,'r;uncoded QPSK theory;')
+  hold on;
+  semilogy(EbNodB, sim_out.BER_uc,'r+;uncoded QPSK simulated;')
+  semilogy(EbNodB-10*log10(sim_out.code_rate), sim_out.BER+1E-10,'g;LDPC coded QPSK simulated;');
+  hold off;
+  grid('minor')
+  xlabel('Eb/No (dB)')
+  ylabel('BER')
+  axis([min(EbNodB) max(EbNodB) min(uncoded_BER_theory) 1])
+
+endfunction
+
+
+% We are using a 3rd party modulator, this function generates bits
+% that can be passed to it.  It's organised as a file of 8 bit bytes
+% MSB is sent first.  Each pair of bits is mapped to phases as:
+%
+% MSB LSB   Phase
+%   0   0       0
+%   0   1      90
+%   1   1     180
+%   1   0     270 
+
+function generate_modulator_input_file(filename, seconds)
+         
+  [aqpsk code_param] = init_modem_ldpc;
+
+  Nframes = floor(seconds/aqpsk.Rf);
+  Nsecs = Nframes*aqpsk.Rf;
+  Nbitsframe = aqpsk.Nsymbpilot*aqpsk.bits_per_symb;
+  Nbytesframe = Nbitsframe/8;
+
+  printf("Frames: %d Seconds: %3.1f QPSK Symb Rate: %5.2f\n", Nframes, Nsecs, aqpsk.Rs);
+  printf("Bit/frame: %d  Packed Bytes/frame: %4.1f\n", Nbitsframe, Nbytesframe);
+
+  fbit = fopen(filename,"wb"); 
+  for nn = 1:Nframes
+    tx_bits = round(rand(1,  aqpsk.Ndatabits));
+    [tx_codeword, tx_coded_symb] = ldpc_enc(tx_bits, code_param);
+    symbpilot_tx = insert_pilots(tx_coded_symb, aqpsk.pilots, aqpsk.Npilotstep);
+
+    % demodulate QPSK symbols back to bits
+   
+    tx_frame = zeros(1, aqpsk.Nsymbpilot*aqpsk.bits_per_symb);
+    for s=1:aqpsk.Nsymbpilot
+      tx_frame(2*(s-1)+1:2*s) = qpsk_demod(symbpilot_tx(s));
+    end
+    packed_tx_frame = packmsb(tx_frame);
+    fwrite(fbit, packed_tx_frame, "uchar");
+  end
+  
+  fclose(fbit);
+
+endfunction
+
+% ---------------------------------------------------------------------------------
+
+generate_modulator_input_file("modinputbits_v0.1.bin", 300)
diff --git a/codec2/branches/0.7/octave/trellis.m b/codec2/branches/0.7/octave/trellis.m
new file mode 100644 (file)
index 0000000..3838fd3
--- /dev/null
@@ -0,0 +1,523 @@
+% trellis.m
+% David Rowe June 2015
+%
+% Testing ideas for trellis decoding of codec parameters.  Uses
+% soft decision information, probablility of state transitions,
+% and left over redundancy to correct errors on codec parameter
+% reception.
+%
+% [X]  Add probability of transition
+% [X]  Will this mess up a perfectly received signal, i.e. all
+%      codewords perfectly received.  This should dominate prob
+%      calc (with small No)
+% [ ] can we measure erroneous decodes?  Whn it makes it worse?
+%     + like all FEC, at some point, it will get a poorer BER
+%     + can we drawa curve of coded versus uncoded errors?
+% [ ] test with actual data, add errors, see if it corrects any
+% [ ] can we draw a trellis with actual values?
+%
+% Note we need SD bits and natural binary order encoding, for example
+%   ./c2enc 700 ../../raw/ve9qrp_10s.raw ../../octave/ve9qrp_10s.bit --softdec --natural
+
+graphics_toolkit ("gnuplot");
+more off;
+randn('state',1);
+
+% Before I couldn't even sp3ll functional programmer.  Now I are one ;)
+
+function [bits_per_frame bit_fields] = codec2_700_bit_fields
+  bits_per_frame = 28;                % number of bits/frame for "700" mode
+  bit_fields = [1 5 3 3 2 4 3 3 2 2]; % number of bits in each field for "700" mode
+  % voiced, Wo, energy, LSP 1..6, 2 spare
+endfunction
+
+% builds a metric of trasnition probablilities for each codec field (model parameter)
+
+function [tp codewords] = build_tp(bitstream_filename)
+  [bits_per_frame bit_fields] = codec2_700_bit_fields;
+  nfields = length(bit_fields);
+
+  % load encoded speech file (one float per bit)
+
+  fbitstream = fopen(bitstream_filename, "rb"); 
+  bitstream = fread(fbitstream, "float32");
+  fclose(fbitstream);
+  nframes = floor(length(bitstream)/bits_per_frame);
+  bitstream = bitstream < 0;
+  
+  % extract each field (model parameter) for bit stream
+
+  codewords = zeros(nframes,nfields);
+  for f=1:nframes
+    aframe = bitstream((f-1)*bits_per_frame+1:f*bits_per_frame);
+    field = 1;
+    st = bit_fields(field);
+    for l=1:nfields
+      nbits = bit_fields(field);
+      %printf("st: %d %d\n", st, st+nbits-1);
+      codeword = aframe(st:st+nbits-1)';
+      %printf("codeword: %d\n", codeword);
+      codewords(f,l) = sum(codeword .* 2.^(nbits-1:-1:0));
+      %printf("nbits: %d lsp(%d, %d) = %d\n", nbits, f, l, codewords(f,l));
+      st += nbits;
+      field++;
+    end
+  end
+
+  % determine transition probablilities of each codeword
+  % state at time n, state a time n+1
+  % prob must add to 1
+  % so for every state, of every codeword, compute histogram of 
+  % transition probabilities
+
+  tp = zeros(32,32,nfields);
+  for f=1:nframes-1
+    for l=1:nfields
+      acodeword = codewords(f,l);
+      bcodeword = codewords(f+1,l);
+      %printf("%d %d %d %d\n", f, l, acodeword, bcodeword);
+      tp(acodeword+1,bcodeword+1,l)++;
+    end
+  end
+endfunction
+
+
+% converts a decimal vlaue to a soft dec binary value
+
+function c = dec2sd(dec, nbits)
+    
+    % convert to binary
+
+    c = zeros(1,nbits);
+    for j=0:nbits-1
+      mask = 2.^j;
+      if bitand(dec,mask)
+        c(nbits-j) = 1;
+      end
+    end
+
+    % map to +/- 1
+
+    c = 1 - 2*c;
+endfunction
+
+% y is vector of +/- 1 soft decision values for 0,1 transmitted bits
+
+function lnp = ln_prob_of_tx_codeword_c_given_rx_codeword_y(y)
+  nbits = length(y);
+  np    = 2.^nbits;
+
+  % work through all possible received codeworks and determine probability
+  % given a number of bits
+  
+  lnp = zeros(1,np);
+  for i=0:np-1
+
+    c = dec2sd(i,nbits);
+
+    % probability calculation for this i
+
+    lnp(i+1) = sum(y .* c);
+  end
+  
+endfunction
+
+
+% y is the received soft decision codedwords, each row is one codeword in time
+% tp is the transition probabilities, each row is the start state
+% returns the most likely transitted codeword c
+
+function c = find_most_likely_codeword(y, tp, nstages, verbose)
+    [ncodewords nbits] = size(y);
+    nstates = 2^nbits;
+    n = ones(1,nstages);
+    
+    lnp = zeros(nstages, nstates);
+    for s=1:nstages
+      lnp(s,:) = ln_prob_of_tx_codeword_c_given_rx_codeword_y(y(s,:));
+    end
+
+    if verbose
+      % printf received codewords
+
+      printf("rx_codewords:\n");
+      for r=1:ncodewords
+        for c=1:nbits
+          printf("%7.2f", y(r,c));
+        end
+        printf("\n");
+      end
+
+      % print probability of each rx codeword table
+
+      printf("\nProbability of each tx codeword:\n");
+      printf("tx_codeword      stage\n");
+      printf("bin dec  ");
+      for s=1:nstages
+        printf("    %9d", s);
+      end
+      printf("\n");
+
+      for i=1:nstates
+        printf("%3s  %2d  ", dec2bin(i-1,nbits), i-1);
+        for s=1:nstages
+          printf("    %9.2f", lnp(s, i));
+        end
+        printf("\n");
+      end
+      printf("\n");
+
+      printf("\nTransition Probability table:\n");
+      printf("state/next_state\n");
+      for r=1:nstates
+        for c=1:nstates
+          printf("%7.2f", tp(r,c));
+        end
+        printf("\n");
+      end
+      printf("\n");
+    end
+
+    % determine probability of each path
+    % (prob of start state)(prob of transition)(prob of next state)
+    % cycle through all possibilities of states
+    % state variable for possible state
+    % step through them exhaustively
+
+    if verbose
+      printf("Evaulation of all possible paths:\n");
+      printf("tx codewords\n");
+      printf("   n");
+      for s=1:nstages-1
+        printf(" n+%d", s);
+      end
+      printf("  ");
+      for s=1:nstages
+        printf("  lnp(%d) ", s-1);
+        if s < nstages
+          printf(" tp(%d,%d) ", s-1,s);
+        end
+      end
+      printf("     prob  max_prob\n");
+    end
+
+    max_prob = -100;
+
+    do
+
+      % add up probabilities for this path
+   
+      if verbose
+        for s=1:nstages
+          printf("%4d", n(s)-1);
+        end
+        printf("  ");
+      end
+
+      prob = 0;
+      for s=1:nstages
+         prob += lnp(s, n(s));
+         if verbose
+           printf("%8.2f ", lnp(s, n(s)));
+         end
+         if s < nstages
+           prob += tp(n(s),n(s+1));
+           if verbose
+             printf("%8.2f ", tp(n(s),n(s+1)));
+           end
+         end
+      end
+
+      if (prob > max_prob)
+        max_prob = prob;
+        max_n = n; 
+      end    
+    
+      if verbose
+        printf("%9.2f %9.2f\n", prob, max_prob);
+      end
+
+      % next path
+
+      s = nstages;
+      n(s)++;
+      while (s && (n(s) == (nstates+1))) 
+        n(s) = 1;
+        s--;
+        if s > 0
+          n(s)++;
+        end
+      end
+    until (sum(n) == nstages)
+
+    c = max_n((nstages+1)/2) - 1;
+    if verbose
+      printf("\nMost likely path....: ");
+      for s=1:nstages
+        printf("%4d", max_n(s)-1);
+      end
+      printf("\nMost likely codeword: %4d\n", c);
+    end
+endfunction
+
+
+% Simulations ---------------------------
+
+function [dec_hat dec_simple_hat dec_tx_codewords] = run_test(tx_codewords, transition_probabilities, nstages, var, verbose)
+  [frames nbits]    = size(tx_codewords);
+  nerrors           = 0;
+  nerrors_simple    = 0;
+  tbits             = 0;
+  nstates           = 2.^nbits;
+
+  rx_codewords = tx_codewords + sqrt(var)*randn(frames, nbits);
+  dec_hat = dec_simple_hat = dec_tx_codewords = zeros(1,frames);
+  
+  ns2 = floor(nstages/2);
+  for f=ns2+1:frames-ns2
+    tx_bits        = tx_codewords(f,:) < 0;
+    dec_tx_codewords(f) = sum(tx_bits .* 2.^(nbits-1:-1:0));
+    dec_hat(f)     = find_most_likely_codeword(rx_codewords(f-ns2:f+ns2,:)/(2*var),log(transition_probabilities+0.001), nstages, verbose);
+    rx_bits        = dec2sd(dec_hat(f), nbits) < 0;
+    rx_bits_simple = rx_codewords(f,:) < 0;
+    dec_simple_hat(f) = sum(rx_bits_simple .* 2.^(nbits-1:-1:0));
+
+    nerrors        += sum(xor(tx_bits, rx_bits));
+    nerrors_simple += sum(xor(tx_bits, rx_bits_simple));
+    if verbose
+      printf("[%d] %d %d\n", f, nerrors, nerrors_simple);
+    end
+    tbits += nbits;
+  end
+
+  EbNodB = 10*log10(1/(2*var));
+  printf("Eb/No: %3.2f dB nerrors %d %d BER: %3.2f %3.2f std dev: %3.2f %3.2f\n", 
+         EbNodB, nerrors, nerrors_simple, nerrors/tbits, nerrors_simple/tbits,
+         std(dec_tx_codewords - dec_hat), std(dec_tx_codewords - dec_simple_hat));
+  
+endfunction
+
+
+% Single point test, print out tables
+
+function test_single
+  tp       = [1 0 0 0; 1 0 0 0; 1 0 0 0; 1 0 0 0];
+  nstages  = 3;
+  var      = 0.5;
+  verbose  = 1;
+
+  tx_codewords = [1 1; 1 1; 1 1];
+  run_test(tx_codewords, tp, nstages, var, verbose);
+endfunction
+
+
+% plot a trajectory of codewords, to help test "distance" is better using trellis than simple decoding
+
+function test_traj(tx_codewords, tp, nstages, var, verbose)
+  [frames nbits] = size(tx_codewords);
+  nstates = 2.^nbits;
+
+  s = sum(tp+0.001,2);
+  [r c] = size(tp);
+  for i=1:r
+    tp(i,:) /= s(i);
+  end
+
+  [dec_hat dec_simple_hat dec_tx_codewords] = run_test(tx_codewords, tp, nstages, var, verbose);
+
+  figure(1);
+  subplot(211)
+  stem(dec_tx_codewords - dec_hat)
+  axis([1 frames -nstates/2 nstates/2]);
+  title('Trellis Decoding');
+  subplot(212)
+  stem(dec_tx_codewords - dec_simple_hat);
+  axis([1 frames -nstates/2 nstates/2]);
+  title('Simple Decoding');
+
+  figure(2)
+  tp
+  length(1:nstates)
+  mesh(1:nstates,1:nstates,tp)
+  ylabel('current state');
+  xlabel('next state');
+endfunction
+
+
+% A contrived trajectories to check out the idea
+
+function simple_traj
+  %tp      = [1 0 0 0; 1 0 0 0; 1 0 0 0; 1 0 0 0];
+  tp      = [0.5 0.25 0 0; 0.25 0.5 0.25 0; 0 0.25 0.5 0.25; 0 0 0.25 0.5];
+  nstages = 3;
+  var     = 0.5;
+  verbose = 0;
+  nbits   = 2;
+  frames  = 25;
+
+  tx_codewords = ones(frames, nbits);
+  test_traj(tx_codewords, tp, nstages, var, verbose)
+endfunction
+
+
+% Run through a trajectory, say from a different file to what we
+% trained with.  Plot trajectory before and after passing through
+% our decoder.  Try first with no noise, then with noise.
+
+function test_codec_model_parameter(bitstream_filename, model_param)
+  [bits_per_frame bit_fields] = codec2_700_bit_fields;
+
+  % load training data
+
+  printf("loading training database and generating tp .... ");
+  [tp codewords_train] = build_tp("hts.bit");
+  printf("done\n");
+
+  % load test data
+
+  printf("loading test database .... ");
+  [tp_test codewords_test] = build_tp(bitstream_filename);
+  printf("done\n");
+
+  % run test data through
+
+  nbits    = bit_fields(model_param);
+  nstates  = 2.^nbits;
+  nstages  = 3;
+  var      = 0.25;
+  verbose  = 0;
+  frames   = length(codewords_test);
+  %frames   = 100;
+
+  tx_codewords = zeros(frames, nbits);
+  for f=1:frames
+    dec = codewords_test(f, model_param);
+    tx_codewords(f,:) = dec2sd(dec, nbits);
+  end
+
+  test_traj(tx_codewords, tp(1:nstates,1:nstates,model_param), nstages, var, verbose);
+
+  figure(3)
+  plot(codewords_test(1:frames, model_param))
+
+if 0
+  figure(4);
+  fs=fopen("../raw/ve9qrp_10s.raw","rb");
+  s = fread(fs,Inf,"short");
+  plot(s(1:320*frames))
+  axis([1 320*frames -3E4 3E4 ])
+end
+endfunction
+
+
+% writes an output bitsream file with errors corrected
+% replay with something like:
+%   $ ./c2dec 700 ../../octave/ve9qrp_10s_trellis.bit - --softdec --natural | play -t raw -r 8000 -s -2 -
+
+function process_test_file(bitstream_filename)
+  [bits_per_frame bit_fields] = codec2_700_bit_fields;
+
+  % load training data
+
+  printf("loading training database and generating tp .... ");
+  [tp codewords_train] = build_tp("hts.bit");
+  printf("done\n");
+
+  % load test data
+
+  printf("loading test database .... ");
+  [tp_test codewords_test] = build_tp(bitstream_filename);
+  printf("done\n");
+
+  nstages  = 3;
+  var      = 0.5;
+  verbose  = 0;
+  frames   = length(codewords_test);
+  %frames   = 150;
+
+  % set up output frames
+
+  frames_out = zeros(1,frames*bits_per_frame);
+  frames_out_simple = zeros(1,frames*bits_per_frame);
+  % run test data through model and trellis decoder
+
+  % just pass these fields straight through
+
+  %for mp=1:10
+  for mp=[1 2 3 10]
+    nbits = bit_fields(mp);
+
+    % pack parameters in SD format into output frame
+
+    for i=1:frames      
+      en = (i-1)*bits_per_frame + sum(bit_fields(1:mp));
+      st = en - (nbits-1);
+      %printf("fr st: %d offset: %d st: %d en: %d\n", (i-1)*bits_per_frame, sum(bit_fields(1:mp)), st, en);
+      frames_out(st:en) = dec2sd(codewords_test(i, mp), nbits);
+      frames_out_simple(st:en) = dec2sd(codewords_test(i, mp), nbits);
+      %p += bit_fields(i);
+    end
+  end
+
+  
+  % trellis decode these fields
+
+  for mp=4:9
+    nbits    = bit_fields(mp);
+    nstates  = 2.^nbits;
+
+    printf("processing parameter: %d nbits: %d\n", mp, nbits);
+
+    % normalise transition probability rows
+
+    tpmp = tp(1:nstates,1:nstates, mp);
+    s = sum(tpmp+0.001,2);
+    [r c] = size(tpmp);
+    for i=1:r
+      tpmp(i,:) /= s(i);
+    end
+
+    tx_codewords = zeros(frames, nbits);
+    for f=1:frames
+      dec = codewords_test(f, mp);
+      tx_codewords(f,:) = dec2sd(dec, nbits);
+    end
+
+    [dec_hat dec_simple_hat dec_tx_codewords] = run_test(tx_codewords, tpmp, nstages, var, verbose);
+
+    % pack decoded parameter in SD format into output frame
+
+    for i=1:frames      
+      en = (i-1)*bits_per_frame + sum(bit_fields(1:mp));
+      st = en - (nbits-1);
+      frames_out(st:en) = dec2sd(dec_hat(i), nbits);
+      frames_out_simple(st:en) = dec2sd(dec_simple_hat(i), nbits);
+    end
+
+  end
+
+  % save frames out
+
+  [tok rem] = strtok(bitstream_filename,".");
+  fn_trellis = sprintf("%s_%3.2f_trellis%s",tok,var,rem);
+  fn_simple = sprintf("%s_%3.2f_simple%s",tok,var,rem);
+  printf("writing output files: %s %s for your listening pleasure!\n", fn_trellis, fn_simple);
+
+  fbitstream = fopen(fn_trellis,"wb");
+  fwrite(fbitstream, frames_out,"float32");
+  fclose(fbitstream);
+
+  fbitstream = fopen(fn_simple,"wb");
+  fwrite(fbitstream, frames_out_simple,"float32");
+  fclose(fbitstream);
+
+endfunction
+
+% uncomment one of the below to run a simulation
+
+%test_single
+%simple_traj;
+test_codec_model_parameter("ve9qrp_10s.bit", 6);
+%process_test_file("ve9qrp_10s.bit")
+
diff --git a/codec2/branches/0.7/octave/twomixer.m b/codec2/branches/0.7/octave/twomixer.m
new file mode 100644 (file)
index 0000000..0a718cb
--- /dev/null
@@ -0,0 +1,38 @@
+% twomixer.m
+% David Rowe Feb 2015
+%
+% test program for combining signals from two mixers
+
+fc=1024;
+Fs=8192;
+[b a] = cheby2(6,40,[200 3000]/(Fs/2));
+
+w1 = 2*pi*(fc/2)/(Fs/2);
+w2 = 2*pi*(3*fc/2)/(Fs/2);
+w3 = 2*pi*(5*fc/2)/(Fs/2);
+wc = 2*pi*fc/(Fs/2);
+
+t = 0:(Fs-1);
+s1 = cos(w1.*t);
+s2 = cos(w2.*t);
+s3 = cos(w3.*t);
+s = s1 + s2 + s3;
+
+lo1 = cos(wc*t);
+lo2 = cos(2*wc*t);
+out1 = filter(b,a,s .* lo1);
+out2 = filter(b,a,s .* lo2);
+
+S = fft(s);
+
+figure(1)
+subplot(211)
+plot(abs(S));
+subplot(212)
+plot(angle(S))
+
+figure(2)
+subplot(211)
+plot(abs(fft(out1)))
+subplot(212)
+plot(abs(fft(out2)))
diff --git a/codec2/branches/0.7/octave/twotone.m b/codec2/branches/0.7/octave/twotone.m
new file mode 100644 (file)
index 0000000..a20c5c5
--- /dev/null
@@ -0,0 +1,52 @@
+% twotone.m
+% David Rowe Aug 2012
+% Used to experiment with combining phase of two tones
+
+function cbphase
+
+  Wo = 100.0*pi/4000;
+  L = floor(pi/Wo);
+  phi = zeros(1,L);
+
+  % two harmonics 
+
+  a = 20; b = 21;
+
+  % set up phases to whatever
+   
+  phi(a) = -pi;
+  phi(b) = -pi/2;
+
+  % synthesis the two-tone signal
+
+  N = 16000;
+  Nplot = 250;
+  s = zeros(1,N);
+
+  for m=a:b
+    s_m = cos(m*Wo*(0:(N-1)) + phi(m));
+    s = s + s_m;
+  endfor
+
+  % now our theory says that this signal should be the same perceptually
+
+  phi_(a) = (phi(a) - phi(b))/2;
+  phi_(b) = (phi(b) - phi(a))/2;
+
+  s_ = zeros(1,N);
+  for m=a:b
+    s_m = cos(m*Wo*(0:(N-1)) + phi_(m));
+    s_ = s_ + s_m;
+  endfor
+
+  % plot them and see if envelope has the same phase, but "carriers"
+  % have different phase
+
+  figure(1);
+  clf;
+  subplot(211);
+  plot(s(1:Nplot));
+  subplot(212);
+  plot(s_(1:Nplot),'r');
+endfunction
+
diff --git a/codec2/branches/0.7/octave/twotone1.m b/codec2/branches/0.7/octave/twotone1.m
new file mode 100644 (file)
index 0000000..9f36c68
--- /dev/null
@@ -0,0 +1,76 @@
+% twotone1.m
+% David Rowe Aug 17 2012
+%
+% Used to experiment with combining phase of two tones.  This version
+% sets up a complete synthetic speech signal then tries to combine the
+% phase of high frequency tones.  Lets see if we can do this and keep perceptual 
+% nature of signal the same.
+
+function twotone1
+  % hts1a frame 47
+
+  Wo = 0.093168;
+  L = 33;
+  %A = [69.626907 460.218536 839.677429 2577.498047 972.647888 712.755066 489.048553 364.830536 409.230652 371.767487 489.112854       893.127014 2447.596680 752.878113 475.720520 234.452271 248.161606 232.171051 202.669891 323.914490 678.749451 362.958038 211.652512 170.764435 148.631790 169.261673 272.254150 176.872375 67.344391 99.022301 60.812035 34.319073 14.864757];
+  A  = zeros(1,L)*100;
+  phi = [1.560274 1.508063 -1.565184 1.289117 -2.547365        1.412528 -1.303992 3.121130 1.087573 -1.158161 -2.928007 0.995093 -2.614023 0.246136 -2.267406 2.143802 -0.273431 -2.266897 1.685171 -0.668712 2.699722 -1.151891 2.406379 -0.046192 -2.718611 0.761067 -2.305014 0.133172 -1.428978 1.492630 -1.668385 1.539734 -1.336615];
+  %phi = zeros(1,L);
+  st = floor(L/2);
+  %st = 1;
+
+  A(st:st+5) = 1000;
+
+  % now set up phase of signal with phase of upper frequency harmonic
+  % pairs combined
+
+  phi_ = phi;
+  for m=floor(L/2):2:L
+    phi_(m)   = (phi(m) - phi(m+1))/2;
+    phi_(m+1) = (phi(m+1) - phi(m))/2;
+    %phi_(m+1) = 0;
+  end
+
+  % synthesise the signals
+
+  N = 16000;
+  Nplot = 250;
+
+  s = zeros(1,N);
+  for m=st:L
+    s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi(m));
+    s = s + s_m;
+  endfor
+
+  s_ = zeros(1,N);
+  for m=st:L
+    s_m = A(m)*cos(m*Wo*(0:(N-1)) + phi_(m));
+    s_ = s_ + s_m;
+  endfor
+
+  % plot them, expect to see similar time domain waveforms
+
+  figure(1);
+  clf;
+  subplot(211);
+  plot(s(1:Nplot));
+  subplot(212);
+  plot(s_(1:Nplot),'r');
+
+  figure(2);
+  clf;
+  subplot(211);
+  plot(s(1:Nplot)-s_(1:Nplot));
+
+  % save to disk
+
+  gain = 1;
+  fs=fopen("twotone1_orig.raw","wb");
+  fwrite(fs,gain*s,"short");
+  fclose(fs);
+  fs=fopen("twotone1_comb.raw","wb");
+  fwrite(fs,gain*s_,"short");
+  fclose(fs);
+  
+endfunction
+
diff --git a/codec2/branches/0.7/octave/tximage.m b/codec2/branches/0.7/octave/tximage.m
new file mode 100644 (file)
index 0000000..f723e17
--- /dev/null
@@ -0,0 +1,40 @@
+% tximage.m
+% David Rpowe Sep 2015
+
+% Say we have two signals from a mixer, at f_lo +/- f_if
+% We attenuate one by 20dB with a BPF
+% We then pass through a non linear amp
+% Note non linearities are tricky to simulate as sign() gives
+% us a lot of HF harmonics that aliased back down.
+%
+% However, it does appear that non-linear PA(sign) only supresses image
+% by another 6dB.  So mixing up does have it's problems compared
+% to direct generation.  A softer limiter (sqrt) seems to do a better job.
+
+fs = 1E4;
+f_rf = 146;
+f_if = 10.7;
+f_lo = f_rf - f_if;
+
+f_rf1 = f_if + f_lo;
+f_rf2 = f_if - f_lo;
+
+a_rf1 = 1;
+a_rf2 = 0.1;
+
+t = 1:fs;
+
+sig_rf = a_rf1*cos(2*pi*t*f_rf1/fs) + a_rf2*cos(2*pi*t*f_rf2/fs);
+sig_rf_clip = sign(sig_rf).* sig_rf .^ 1/2;
+b = fir1(100, f_rf/fs);
+sig_rf_clip_filter = filter(b,1,sig_rf_clip);
+
+figure(1);
+subplot(211)
+plot(sig_rf(1:1000))
+subplot(212)
+plot(sig_rf_clip_filter(1:1000))
+figure(2)
+plot(20*log10(abs(fft(sig_rf_clip_filter))))
+axis([1 1000 0 80])
+grid
diff --git a/codec2/branches/0.7/octave/undersample.m b/codec2/branches/0.7/octave/undersample.m
new file mode 100644 (file)
index 0000000..1bfbf38
--- /dev/null
@@ -0,0 +1,26 @@
+% undersample.m
+% David Rowe 5 Nov 2012
+% Testing algorithms for plotting undersampled data for fdmdv2 waveform displays
+
+fs=fopen("../raw/hts1a.raw","rb");
+s = fread(fs,Inf,"short");
+
+Fs1=8000;
+Fs2=200;
+
+M=Fs1/Fs2;
+
+samples=length(s)/M;
+s1=zeros(1,2*samples);
+for b=1:samples
+    st = (b-1)*M + 1;
+    en = b*M;
+    s1(2*b-1) = max(s(st:en));
+    s1(2*b) = min(s(st:en));
+end
+
+subplot(211)
+plot(s)
+subplot(212)
+plot(s1);
+
diff --git a/codec2/branches/0.7/octave/vhf_pa.m b/codec2/branches/0.7/octave/vhf_pa.m
new file mode 100644 (file)
index 0000000..4b5486f
--- /dev/null
@@ -0,0 +1,111 @@
+% vhf_pa.m
+%
+% David Rowe Dec 2015
+%
+% Working for 0.5W VHF PA
+
+rfdesign;
+
+% BFQ19 Vce=5V Ic=50mA.  These are small signal S-params,
+% which (according to "RF Cicruit Design") are not valid.
+% However I need to start somewhere.
+
+S11 = 0.324*exp(j*(-158.1)*pi/180);
+S12 = 0.031*exp(j*(75.9)*pi/180);
+S21 = 19.693*exp(j*(102.7)*pi/180);
+S22 = 0.274*exp(j*(-74.6)*pi/180);
+
+% Lets check stability
+
+Ds = S11*S22-S12*S21;
+Knum = 1 + abs(Ds)^2 - abs(S11)^2 - abs(S22)^2;
+Kden = 2*abs(S21)*abs(S12);
+K = Knum/Kden
+figure(1);
+clf
+scCreate;
+
+if K < 1
+  C1 = S11 - Ds*conj(S22);
+  C2 = S22 - Ds*conj(S11);
+  rs1 = conj(C1)/(abs(S11)^2-abs(Ds)^2);           % centre of input stability circle
+  ps1 = abs(S12*S21/(abs(S11)^2-abs(Ds)^2));       % radius of input stability circle
+  rs2 = conj(C2)/(abs(S22)^2-abs(Ds)^2);           % centre of input stability circle
+  ps2 = abs(S12*S21/(abs(S22)^2-abs(Ds)^2));       % radius of input stability circle
+
+  s(1,1)=S11; s(1,2)=S12; s(2,1)=S21; s(2,2)=S22;
+  plotStabilityCircles(s)
+end
+
+
+% determine collector load Rl for our desired power output
+
+if 0
+P = 0.5;
+Vcc = 5;
+w = 2*pi*150E6;
+
+Rl = Vcc*Vcc/(2*P);
+end
+Rl = 10;
+
+% choose gammaL based on Rl
+
+zo = Rl/50;
+[magL,angleL] = ztog(zo);
+gammaL = magL*exp(j*angleL*pi/180);
+
+% calculate gammaS and Zi and plot
+
+gammaS = conj(S11 + ((S12*S21*gammaL)/(1 - (gammaL*S22))));
+[zi Zi] = gtoz(abs(gammaS), angle(gammaS)*180/pi,50);
+
+scAddPoint(zi);
+scAddPoint(zo);
+
+% design Pi network for matching Rl to Ro, where Ro > Rl
+%
+% /---+-Xs1-Xs2-+---\
+% |   |         |   |
+% Rl Xp1       Xp2  Ro
+% |   |         |   |
+% \---+---------+---/
+%
+% highest impedance used to define Q of pi network and determine R,
+% the "virtual" impedance at the centre of the network, whuch is smaller
+% than Rl and Ro
+
+Ro = 50;
+Q = 3;
+R = Ro/(Q*Q+1); 
+
+Xp2 = Ro/Q;
+Xs2 = Q*R;
+
+Q1 = sqrt(Rl/R - 1);
+Xp1 = Rl/Q1;
+Xs1 = Q1*R;
+
+Cp1 = 1/(w*Xp1);
+Cp2 = 1/(w*Xp2);
+Ls  = (Xs1+Xs2)/w;
+
+printf("Output Matching:\n");
+printf("  Rl = %3.1f  Ro = %3.1f\n", Rl, Ro);
+printf("  Q = %3.1f virtual R = %3.1f\n", Q, R);
+printf("  Xp1 = %3.1f Xs1 = %3.1f Xs2 = %3.1f Xp2 = %3.1f\n", Xp1, Xs1, Xs2, Xp2);
+printf("  Cp1 = %3.1f pF Ls = %3.1f nH Cp2 = %3.1f pF\n", Cp1*1E12, Ls*1E9, Cp2*1E12);
+
+% design input matching network between 50 ohms source and 10 ohms at base
+
+Rb = 10; Rs = 50;
+
+[Xs Xp] = z_match(Rb, Rs);
+
+Lp = Xp/w;
+Cs = 1/(w*Xs);
+
+printf("Input Matching:\n");
+printf("  Xs = %3.1f Xp = %3.1f\n", Xs, Xp);
+printf("  Lp = %3.1f nH Cs = %3.1f pF\n", Lp*1E9, Cs*1E12);
+
diff --git a/codec2/branches/0.7/octave/vq b/codec2/branches/0.7/octave/vq
new file mode 100644 (file)
index 0000000..d5ab591
--- /dev/null
@@ -0,0 +1,10247 @@
+# Created by Octave 3.8.1, Sat Apr 23 08:58:51 2016 AEST <david@penetrator>
+# name: vq
+# type: matrix
+# ndims: 3
+ 256 20 2
+ 1.085205426985832
+ -0.4260300009189197
+ 0.833577745236378
+ 1.798373960816606
+ 0.9935936444607169
+ 0.1239833582287509
+ 1.575157273987481
+ 0.9540245374175702
+ 0.3562009016948172
+ 1.585644452239723
+ 1.506294746166876
+ 0.2396183532805597
+ 1.367446280732269
+ 1.282223720216575
+ 1.162423214604796
+ 0.5244164469952718
+ 1.128835884692779
+ 1.058918853547902
+ 1.963632826547209
+ 0.5811484562442362
+ 1.120960795023191
+ 1.293247932196338
+ 0.8421615329424976
+ 1.327956700632984
+ 1.150131602897049
+ 1.32240186352708
+ 1.151653785065956
+ 0.4043141675059787
+ -0.605854891571997
+ 0.5664167394483143
+ -0.7537298690327013
+ 1.049449161804654
+ 0.5218464074650003
+ 1.494541250873327
+ 0.8342264875867933
+ 0.9206540524095941
+ 0.06472922157937634
+ 0.7198209111919989
+ 1.38273463666622
+ 1.369195704270166
+ 0.7200435399985342
+ 0.4728514924142588
+ 1.338670575504253
+ 0.901349771652351
+ 0.7221823774481055
+ 1.05531832867729
+ 1.122264649509382
+ 0.03480813187567571
+ 0.8704977954705367
+ 0.3118300343783649
+ 1.345816954855809
+ 0.9902369196859547
+ 1.630250359910498
+ 0.9962379680208187
+ 0.7860178377708859
+ 1.405072623711622
+ 0.04215045540948043
+ 1.100604952014984
+ 1.801940417320714
+ 1.672902158942722
+ 0.9189112275890299
+ 1.073606509430072
+ 0.7077106102247487
+ 1.351518501029729
+ 0.8198628050578108
+ 1.233747356047938
+ 1.867879182176302
+ 1.16871953438174
+ 0.5619271296279016
+ 1.377194835765386
+ -0.06310946462056462
+ 1.193115849982975
+ 0.3302970529535515
+ 1.128793026714063
+ 0.9728683717267995
+ 1.387587258338834
+ 1.244021687351402
+ 0.6683606936174704
+ 1.199485416480435
+ 0.5956899153219491
+ 0.3013694867793058
+ 0.8655341870443748
+ 0.2088344957654923
+ 1.1447496470614
+ 1.084164446118127
+ 1.003149200094682
+ 1.191560192626183
+ 0.07486858283563912
+ 0.7661458586347402
+ 0.4866127826256495
+ -0.1089155940953209
+ 1.23959659930226
+ 1.054183144345908
+ 0.2504451195646863
+ 0.8956884207647202
+ 1.119249454883628
+ 1.116978748635182
+ 0.9513183172426499
+ 0.1089893432612581
+ 0.6032927070356664
+ 1.223982221591883
+ 1.252308815173021
+ 0.5827306571168442
+ 1.421065953702404
+ 0.162963901404173
+ 1.196233511235407
+ 1.84581856021695
+ 0.9869956389787488
+ 0.1646961461119581
+ 0.9850201800243675
+ 1.429250808608257
+ 0.9923260772179757
+ 0.9590272370201224
+ 0.5825501483605714
+ 1.070845967907089
+ 1.175383240709347
+ 0.6499779705541643
+ 0.3320598410515813
+ 1.592125364047756
+ -0.3139251676378877
+ 0.2941683771906135
+ 1.678238614064441
+ -0.4402253102695204
+ 1.311626010101525
+ 1.230368944293766
+ 1.118969630404878
+ 0.4699109361369931
+ 0.5566459218624169
+ 0.3996167544525743
+ 1.063017424039592
+ 0.9065738165115017
+ 1.274194918558561
+ 1.226051793207517
+ 1.195335954727556
+ 0.5219409661767341
+ -0.3567210160579476
+ 0.2030643648479605
+ 1.385132588724635
+ 0.9158832967346469
+ 0.9322888042239789
+ 1.298607308549179
+ 0.6104336622079205
+ 1.112243563345926
+ 1.520623715949573
+ 0.9317177714797874
+ 0.7712367063105167
+ 1.340499022391671
+ 1.304764024159155
+ 0.4735061357092801
+ 0.9625427325458471
+ 1.136775254002388
+ 0.4261374335150909
+ 0.3337168222499328
+ 0.9646263375973135
+ 0.1382418388350582
+ 1.142845116548473
+ 0.8905004958914902
+ 0.6352197854178532
+ 0.5315973388091748
+ 0.2762672232170045
+ 0.7323883053221711
+ 1.069700009254771
+ 0.5773447972180785
+ 0.6265539300205094
+ 1.208723096926154
+ 1.373557618988817
+ 1.396848139856655
+ 1.22644909332404
+ 0.747423382879117
+ 0.1923928104579403
+ 0.2317151183086048
+ 1.195158636439779
+ 1.235985355812018
+ 0.9547800158843198
+ 0.8904454757455824
+ 1.143257875740302
+ 0.908286803400884
+ 0.1941688834036181
+ 0.3158243056857314
+ 0.6849987277815992
+ 0.6445369483172818
+ 1.05538088978711
+ 0.6030235309635322
+ 1.486202280215748
+ 1.396804660772058
+ 1.150704097309296
+ 0.6920213957251961
+ 1.582203495857851
+ 1.202025792169117
+ 1.374999251582953
+ 0.2288168689728823
+ 0.4329608518584964
+ 0.8464391637680514
+ 1.135844763204482
+ -0.1545900194782768
+ 0.9567819848531226
+ 1.374372950241175
+ 1.333415099532475
+ 1.200028477439384
+ -1.0208946912861
+ 1.334019146241362
+ 0.5691948095784971
+ 1.250417957983486
+ 0.1606069495457166
+ 1.351838776281039
+ 0.09518343481973855
+ 0.3320891202043986
+ 1.650452578645842
+ 1.569148456097603
+ -0.09071912653151751
+ 0.3264988095922111
+ 0.8375894641356687
+ 0.6559955317907418
+ 1.149364426104217
+ 0.8062962854345533
+ 0.9188276660142149
+ 0.3028421810952253
+ 1.566145006462622
+ 0.5822774136794752
+ 1.069120717715464
+ 1.721561396547623
+ 0.856831005984519
+ 0.5564137080731699
+ 0.7153678821180693
+ 0.853234505158737
+ 0.603185994785441
+ 1.186506259153193
+ 1.148948504058279
+ 0.6177590034489259
+ 0.5760949222380469
+ 1.855034211463561
+ 0.9121147355845477
+ 1.010718439207553
+ 1.549735365386854
+ 1.069655184913645
+ -0.7295454638452006
+ 0.8476706126547495
+ 1.045201963428327
+ 1.876209304797508
+ 1.100098125226684
+ 0.5449377727755268
+ 1.393285124315972
+ 0.3558090786406779
+ 0.9881025017683388
+ 1.093368419306702
+ 0.448706447264993
+ 0.911083453512061
+ 1.15800556561816
+ -0.4846742001392422
+ 0.5454789417356526
+ -0.02763772693410249
+ 0.7899662745198055
+ 1.086855284902688
+ 0.5083938014690804
+ 1.784614071563062
+ 0.4955810910707088
+ 0.6307896832511808
+ -0.34177101856323
+ 1.407977101362635
+ 0.01089753717535649
+ 0.8109156423843644
+ 0.02157571365906377
+ 0.7974501480560753
+ 1.161677104060995
+ 0.7449135184865795
+ 1.335922577995176
+ 1.618074115184736
+ 0.5036808860872769
+ 1.281621536264201
+ 1.496512222586918
+ 0.5656867946695433
+ 0.6635578371625578
+ 0.7769267716943143
+ 0.7863318705349102
+ -1.780978883369023
+ -0.0334354168623605
+ 0.6636862687063216
+ 1.31953372409462
+ 0.7679335906405473
+ 1.357765462325111
+ 1.002678487287578
+ 1.312437664849832
+ 0.8924926344549168
+ 0.4636383638860451
+ -0.4070912248841624
+ 0.3217800893580187
+ -0.05480191063438398
+ 0.5704105297752942
+ 0.5671989228695588
+ 1.265425897803026
+ 0.9479718237857699
+ 0.8777643997522284
+ 0.1431302574000071
+ 0.6515151863984949
+ 1.173472222357272
+ 1.362655064101474
+ 0.5580298125429235
+ 0.6418980270774041
+ 1.03039668193185
+ 0.3594537068522266
+ -0.04147042419107318
+ 1.455218010598134
+ 1.227033289641574
+ 0.06992318109090488
+ 0.3180324711899842
+ -0.1495786011244451
+ 0.9918971182481525
+ 0.8774198930235823
+ 1.721649383997356
+ 0.9281742007128928
+ 1.640992165953183
+ 1.269750130001307
+ 0.03069266092696008
+ 0.3789038439191283
+ 0.593613546633564
+ 1.111480012530088
+ 0.8286979077983071
+ 1.18404324241428
+ 0.7819017133615419
+ 1.184090438751563
+ 0.7659782497915133
+ 1.0270864532279
+ 1.828429658014905
+ 0.7901410673132826
+ 0.7366673489477884
+ 1.154988816261634
+ -0.5471812039524085
+ 0.934981740816867
+ 0.2371332570247094
+ 1.0250163450453
+ 1.27266423448643
+ 1.454333079552459
+ 0.5727768922154086
+ 0.9771845066546033
+ 0.9172197471647986
+ 1.075563145199177
+ 0.4384292666482437
+ 1.239092406693795
+ 0.210285117767336
+ 0.8733612055335693
+ 1.053824328003951
+ 1.140078195008836
+ 0.7905272592630922
+ 0.7828638574028199
+ 0.3800700405357779
+ 0.04386828899833825
+ 0.4448709339379409
+ 1.175831673476218
+ 0.5101567242836115
+ 0.09582478057635176
+ 0.5917407640130367
+ 1.188218565713065
+ 0.9963122522605247
+ 0.9296892601798483
+ 0.2641176647599591
+ 0.03959598133926203
+ 0.9551648406598405
+ 1.0764477050855
+ 0.1378738153867933
+ 1.23353768813546
+ -0.4889616350026407
+ 0.8333605392781226
+ 1.077043592755524
+ 0.4993903680346781
+ -0.1139168084620633
+ 0.7914997890435082
+ 1.061615511701903
+ 0.7068251156389007
+ 0.8895360567176563
+ 0.9221606578157804
+ 0.8720105612358751
+ 1.146999585796198
+ 0.2380133501973453
+ 0.5057686048644131
+ 1.479930515236531
+ 0.01015620544596672
+ 0.2431628777000853
+ 1.702530222152529
+ -0.6796910843532397
+ 1.032776572059292
+ 1.301342297641337
+ 0.8143336069861939
+ 0.7635151712808649
+ 0.6362377313700681
+ 0.4339276521621836
+ 0.4802842872208226
+ 0.3001502607473731
+ 1.106077237434545
+ 1.008263870942845
+ 1.365542441935153
+ 0.6790855740186382
+ -0.0837459219137099
+ 0.8732339782103199
+ 1.640876156222111
+ 0.9177915661396188
+ 1.104421107680557
+ 0.8853913828852079
+ 0.4571773916694294
+ 0.9094059065244827
+ 1.587617533587789
+ 0.1524648649046425
+ 0.3692382822458569
+ 1.242632785428377
+ 1.320666722021657
+ 0.6910286390838315
+ 0.8196657398334
+ 1.094117543461184
+ 1.050573062644234
+ -0.095843175006164
+ 0.8439478073229337
+ 0.01388520142811661
+ 0.8525313241450097
+ 0.7560187534936887
+ 0.7163589419339997
+ 0.48172955945087
+ 0.3191282594036909
+ 0.5887849395958622
+ 1.073048278856649
+ 0.6298813075484302
+ 0.8494144146160413
+ 1.119108071145198
+ 0.5041467048651576
+ 0.753953116677396
+ 1.415463825758381
+ 0.7543289699956602
+ 0.1886565605608594
+ 0.337384574159233
+ 0.997230623170282
+ 0.9040472605249359
+ 0.4907711273324722
+ 0.9061210546528722
+ 1.156437217107255
+ 0.4695398632675316
+ -0.00085808420372521
+ 0.1361669439466877
+ 0.789467312307312
+ 0.5997423085983093
+ 0.6901869245440042
+ 0.6159422966653133
+ 1.199854198628586
+ 0.8079953503366223
+ 0.468524121850383
+ 0.5324545493188838
+ 0.8344982497659503
+ 1.370319814607772
+ 1.44131066853247
+ 0.7407415623265214
+ 0.05393103628695976
+ 1.079745668684748
+ 0.5729519871321513
+ -0.1851074752298328
+ 0.992944720430734
+ 0.9115450331591136
+ 1.370626836759575
+ 0.4751961017836588
+ -0.6822887887799577
+ 1.355603094738513
+ 0.7582980444714997
+ 1.287305989858565
+ 0.3103196025488943
+ 1.421172024185723
+ -0.03865357392167217
+ 0.7292790541459703
+ 1.503226353587898
+ 0.5882138571631963
+ -0.6093718430332411
+ 0.1767394375474176
+ 1.276766057212127
+ 0.2680255519434074
+ 1.12370254387008
+ 0.398854116141619
+ 1.137373259085501
+ -0.3490926629910003
+ 1.624321880009409
+ 0.5226169241649171
+ 0.9044285339583492
+ 1.521669667354217
+ 0.7912102844944133
+ 0.4799761729696941
+ 0.007198768056136138
+ 1.118146053519841
+ 0.6123216140984202
+ 1.326185872147739
+ 0.9124790581806869
+ 0.04998935374131432
+ 0.197000146554438
+ 0.891152524397205
+ 0.5822353455552293
+ 0.3891121700178945
+ 1.593699066012701
+ 0.9369187911763287
+ -0.4173953205770336
+ 0.02815662236665207
+ 1.263074340857436
+ -0.4156518344072447
+ 0.9024061343598681
+ 0.08377464923872469
+ 1.738787817003506
+ 0.5177228046119318
+ 1.132147362693591
+ 1.279158205976386
+ 0.7202975064986489
+ 1.083485371159031
+ 1.243643218383548
+ -0.252741128821911
+ 0.7413435329819636
+ 0.4777693296936473
+ 0.8402990100436456
+ 1.01127993141735
+ 0.1533121344864636
+ 1.467708403340319
+ 0.491607387702562
+ 0.2813488729981752
+ -0.23309774437551
+ 0.8385025128809915
+ 0.3270048984513226
+ 0.8551646087377082
+ 0.0510931504452391
+ 0.2765658079493324
+ 1.19487687416751
+ 0.7330927106990655
+ 0.4039208562877936
+ 0.7509115681262256
+ 0.2929882944647805
+ 0.6622594713526353
+ 0.8716985336118284
+ 0.256385689857605
+ 0.5761648585763438
+ 0.5135305910284679
+ 0.7367357125025655
+ 1.893284660668191
+ -0.1812633458814429
+ 0.5535296184930434
+ 0.7110951260347793
+ 0.1472364235480178
+ 0.821249306261171
+ 0.4425183187837054
+ 1.099118632151938
+ 0.5697552691995635
+ 0.9103172272666007
+ -0.3505623944219689
+ 0.3038726147938779
+ 0.2766268157752633
+ 0.4633144824118865
+ 0.421873437147429
+ 1.403668123763734
+ 0.885456979305717
+ 0.4495998966673143
+ 0.1751816133102695
+ 0.1420572593236852
+ 1.023012905853923
+ 0.6073508208973148
+ 0.698487833169068
+ 0.6488088673841286
+ 0.5915845287078585
+ -0.05177700993234245
+ -0.2162361772648918
+ 1.095833420194178
+ 1.280856218535019
+ 0.1730234086711988
+ 0.1005129723860903
+ -0.2376144855255936
+ 0.4483192343799798
+ 1.104287886446522
+ 1.05196798440898
+ 1.422049575253155
+ 1.537352663766892
+ 0.7500419081327695
+ 0.03991494652899544
+ 0.1034867659806852
+ 0.4224085207772535
+ 0.3864210672817945
+ 0.3735747180645465
+ 0.7765915223589677
+ 0.3315281950696041
+ 0.5683741364769683
+ 0.2019063044164997
+ 1.034269555873555
+ 1.233685691705767
+ 0.09881214847988599
+ 0.2720142723998445
+ 0.6198100476916732
+ -0.4401429185734267
+ 0.2989412982646393
+ 0.1531713813109536
+ 0.6256149735005488
+ 0.2905363579030045
+ 1.397726502355438
+ 0.2616648818407552
+ 0.4490368449109646
+ 0.9163917663722386
+ 1.089257583951409
+ 0.5203423966116525
+ 0.8826668740057446
+ 0.5417175045725473
+ 1.090892214419326
+ 0.7454410916412249
+ 0.7525217841302803
+ 0.1226292710741966
+ 1.030237066837245
+ 0.2089646577463286
+ -0.06084684303132043
+ 0.9846655017994531
+ 0.5153646593337698
+ 0.2205181808919031
+ 0.2146525528107585
+ 0.4538487033213079
+ 0.3112177429774014
+ 0.6401051461257636
+ 0.2233938908298634
+ 0.2471328569943696
+ -0.3118132717953503
+ 1.011259948671065
+ 0.8180977557926039
+ 0.01109870254488479
+ 0.9295340611245301
+ -0.4471511869338353
+ 0.2186642118804684
+ 0.3410503815535691
+ 0.2961312366333129
+ -0.143295880948191
+ 0.6570058907728265
+ 0.3374478790259653
+ 0.7164972147498678
+ 0.4728493928151949
+ 0.6309390863530263
+ 0.9192287990009655
+ 0.5236244132628847
+ -0.01669515537818698
+ 0.7359536567719464
+ 0.7633933826108308
+ 0.1505084066165529
+ 0.03028416277848445
+ 1.085764033307612
+ -0.5202265832878327
+ 0.7875814498506806
+ 0.3028976076028166
+ 0.3041742281687709
+ 0.6305983965683244
+ 0.3863647299097199
+ 0.6091800798116837
+ 0.2766290594885096
+ -0.04164046469769212
+ 1.095085939499609
+ 0.7520161873439619
+ 0.6899692417334078
+ 0.722569043292997
+ 0.1692090038495222
+ 1.082199154298006
+ 1.581671334352642
+ 0.689404983899905
+ 0.6840779222017123
+ 0.8436653279709823
+ 0.2662908234016441
+ 0.981892759284849
+ 1.134640943038094
+ -0.2345715436513772
+ 0.6178212925489196
+ 0.4036932487417162
+ 0.7952702641381866
+ 0.5639573896008447
+ 0.5993645140406432
+ 0.7141580513604615
+ 1.014012316351468
+ -0.08744981314008972
+ 1.063873115437658
+ 0.1099034874188993
+ 0.9950519710874927
+ 0.1534889007169
+ 0.05631190168031441
+ 0.1748263357959901
+ 0.165560369417498
+ 0.4633308759715956
+ 1.188905400442834
+ 0.7731024403484956
+ 0.8423415798127308
+ 0.9718508042477025
+ 0.2297467466333339
+ -0.01320786123883487
+ 0.5873563449277251
+ 0.5910935104098086
+ 0.3635749528124803
+ 0.3343544719801193
+ 1.18648459924689
+ 0.4451694598362241
+ 0.1324333660623244
+ 1.084951896740999
+ 0.3960438506447841
+ 0.1749869325737155
+ 0.02208594803615767
+ 0.09245561966466478
+ 1.122532226331501
+ 0.4393539525729408
+ 0.4115588600754834
+ 0.2702758540323703
+ 1.011999371548518
+ 0.4948376043376667
+ 0.07072665059510284
+ 0.3109519530391471
+ 0.08833859645953668
+ 1.42027802339303
+ 0.9341542146532245
+ 0.4553619567468035
+ -0.1411301391868214
+ 1.056999637245755
+ 0.2473749868663636
+ -0.1674778939937979
+ 0.4949894843141263
+ 0.3037014956998224
+ 1.043405348612228
+ -0.02690205634125676
+ -0.4006218991582415
+ 0.7880313750703598
+ 0.8392053130898005
+ 0.8938116092151039
+ 0.4481197017943047
+ 1.044980745627303
+ 0.0633474328942642
+ 0.3676187329050571
+ 0.8260672972308953
+ 0.09198051118011895
+ -0.4135806176956385
+ 0.3550021274498011
+ 0.9113941029960042
+ 0.1252852590239979
+ 0.6630493499094094
+ 0.3076774479505871
+ 0.2015842344325611
+ -0.346834457601448
+ 0.8287973613110869
+ 0.2967238340679168
+ 1.249776900632627
+ 0.8378302025923385
+ 0.2601815719430856
+ 0.2421592762135072
+ -0.2792952167765571
+ 1.016400334668337
+ 0.0916798184791715
+ 0.4392572064535232
+ 0.4227332600248574
+ -0.1001271299425782
+ -0.001465314706970619
+ 0.2560201957554942
+ 0.3296530897657324
+ 0.1565518292519268
+ 1.261770984934702
+ 0.3885726181860199
+ -0.1954207667055181
+ -0.2052101948457193
+ 1.144868702233546
+ 1.298048107673848
+ 0.7249741552686874
+ -0.08176434161962366
+ 1.176339530411192
+ 0.6407595791199964
+ 0.8844590668365837
+ 0.6642328057538459
+ 0.848163608448612
+ 0.6932933316219306
+ 0.7959734189807569
+ -0.1667762824316838
+ 1.286512244363518
+ 0.6279406083841168
+ 0.8883628309026455
+ 0.9414864655393888
+ 0.2784164795536057
+ 0.7809719251837841
+ 0.3649021998185719
+ 0.1617608439534715
+ -0.1337007970435923
+ 0.05357396878826291
+ -0.4123475197060653
+ 0.6793419169334679
+ 0.0531435473951218
+ 0.08546646719549002
+ 0.8467171554056512
+ 0.2006091551971668
+ 0.02207625831547735
+ -0.2065546538260196
+ -0.1500903968350547
+ -0.1780567295704319
+ 0.1747860566134954
+ 0.02125819010347606
+ 0.2164826363626913
+ 0.1443591827454877
+ 0.9803964077859239
+ -1.780599153696266
+ 0.2055912305732803
+ 0.6887745530042322
+ -0.01050806541979735
+ -0.2426710690444304
+ 0.1410483568277712
+ -0.2006929997681248
+ 0.8833631850914567
+ 0.162520794689835
+ 0.5527779486354782
+ -0.3978712960120283
+ 0.3437758311462648
+ -0.007205974613345725
+ 0.1841357965531394
+ 0.09152585081054528
+ 1.286508701564548
+ 0.3655186020172489
+ 0.316716706042257
+ -0.3127458919964299
+ -0.2094498284541832
+ 0.7904908777949718
+ -0.01086593359251741
+ 0.8864233108894075
+ 0.4630987816902309
+ 0.3434295920993696
+ -0.2792796618186488
+ -0.2016090751399555
+ 0.4244685847407725
+ 1.262064526376716
+ -0.08544915908117247
+ 0.07717200318988543
+ -0.2904135750963075
+ 0.1095873134471235
+ 0.8385397295204448
+ 0.318490257369696
+ 1.235507037818786
+ 1.259099473202747
+ 0.3947007258433206
+ -0.008180057120502274
+ -0.0361143889651698
+ 0.4164480523231656
+ -0.02334847607833782
+ 0.06517205255138779
+ 0.1618198171183014
+ -0.2659533632859265
+ -0.01562677004495009
+ -0.1206358109498548
+ 1.002757776307379
+ 0.4986699392847478
+ -0.1371903112173145
+ -0.00344358633489329
+ -0.07996003153263954
+ -0.3379485137288289
+ -0.03806474899354377
+ 0.2683029250821991
+ 0.4100228415034203
+ -0.5108165651107379
+ 1.184539416771237
+ 0.1978249632565801
+ -0.09630232711143173
+ 0.5430847989065629
+ 0.4074670926797942
+ 0.4631484926382279
+ 0.1088129743911087
+ 0.6248848760480203
+ 1.335482560719826
+ 0.5155308620325403
+ 0.06752770884254551
+ -0.1248334783810167
+ 0.3963970410539291
+ -0.04969096370578793
+ -0.1216187484590646
+ 0.8689318195651347
+ 0.08578933212809549
+ 0.08798208804502958
+ 0.1239523977696128
+ 0.7575757543842648
+ -0.5595989732992216
+ 0.0622867847444411
+ -0.2926542381256442
+ 0.1580875827841728
+ -0.425556755299803
+ 1.289880604134823
+ 0.3535913221615343
+ -0.09873744696346339
+ 0.5035922557411745
+ -0.3769750284854071
+ -0.2740109377625299
+ 0.08237750806349588
+ 0.2263722622510267
+ -0.2518950618988852
+ 0.6067018699476547
+ -0.08611878074779186
+ 0.9899446712432615
+ 0.56646645492197
+ 0.1011353098063996
+ 0.6347240555798442
+ -0.195088801537368
+ -0.1654943782773581
+ 0.9426980842944602
+ 0.5010721927420557
+ -0.02065723337935632
+ -0.1873567752539188
+ 0.4389198390611936
+ -0.5307174645776235
+ 0.5103471895505917
+ -0.5719078828410628
+ 0.2149994092751085
+ 0.06942256938950482
+ -0.09480109603957031
+ 0.7856110736017079
+ 0.1262729905621497
+ -0.1242442642087571
+ 0.7375115728397422
+ 0.7289571746152353
+ -0.06700990897760298
+ 0.5820134850756077
+ 0.192612145157865
+ 0.4557109964282625
+ 1.51341697909097
+ 0.7253998697830548
+ 0.1460115103717501
+ 0.5642719127158798
+ 0.08625007759573282
+ 0.8566197096352928
+ 0.8364491248658364
+ -0.3513666162487823
+ 0.5432105555615571
+ -0.4289085218375293
+ 0.08484774382517647
+ 0.1045245386515451
+ 0.1566853648593213
+ 0.2079149196894243
+ 0.4077901486435228
+ 0.006353698137078662
+ 1.168997355279365
+ 0.1597654442842663
+ 1.237495342298039
+ -0.1510923183128803
+ -0.3458940525314884
+ -0.07979655864943636
+ -0.01560096750891377
+ 0.3022630572884595
+ 0.6470884583341112
+ 0.5607465349171387
+ 0.5874337534730686
+ 0.5187410585951379
+ 0.09923649517267127
+ -0.3903120574808259
+ -0.2248925641470509
+ 0.5022861897824493
+ 0.4374504749438747
+ 0.3313371562970333
+ 0.7814655560905704
+ 0.01544256774635527
+ -0.1346611555543178
+ 0.9649205799373766
+ -0.07399090242506197
+ 0.00216705002061529
+ 0.1458209566043037
+ 0.05173860838852241
+ 0.8507228862081294
+ 0.3320570498962878
+ 0.1655384932336358
+ -0.02728734826639537
+ 0.691336705496105
+ 0.3150476389121989
+ -0.03357036370806174
+ 0.1898216245312712
+ -0.1342540497391477
+ 0.7772548085734329
+ 0.03422543205667956
+ -0.05226192976806608
+ -0.1849123430625171
+ 0.3275105501377845
+ 0.04307605486698986
+ -0.131123603083785
+ 0.07487897523238661
+ 0.1296086875090163
+ 0.2501117652645889
+ -0.2469752436259501
+ -0.3544171354949975
+ 0.08169347749847211
+ 0.5339569458487908
+ -0.09703519674586708
+ 0.7488798079926938
+ 0.08679629241041764
+ -0.07072096977100872
+ -0.2971862572087856
+ 0.1263912615773313
+ -0.05568275635783676
+ -0.3822170484681757
+ 0.6091905020006767
+ 0.1930470707969421
+ 0.08467963438116037
+ 0.05249402872623965
+ 0.2494332525911941
+ -0.3320851228066722
+ -0.2403789133443307
+ 0.003345438942484604
+ 0.3176445946245712
+ 1.208968052226298
+ 0.1203616024566635
+ -0.1936304993502403
+ 0.2018677424059998
+ -0.3857096249615873
+ 0.4468458397728436
+ -0.2453648163093229
+ -0.4256714755667666
+ 0.1389267737056973
+ -0.01545153071922624
+ -0.1413233554768697
+ 0.147789392764825
+ 0.1156480357397888
+ 0.0266055205360948
+ 0.6561921889029468
+ 0.7010147506182437
+ -0.2516907836458909
+ 0.05665772882715631
+ 0.7190474056023438
+ -0.403927684259865
+ 0.6010008006167838
+ -0.1350583498082975
+ 0.4163660158163784
+ 0.5782030959359387
+ 0.3523975447901436
+ -0.347734778161943
+ 0.5127491719291808
+ -0.3351261666665789
+ 0.250711139193513
+ 0.04821676249691886
+ 0.9861395396684846
+ 0.2187220948755276
+ 0.3511444826916622
+ 0.4410497755064916
+ 0.4556123632934783
+ 0.1785487993615588
+ 0.2588746056146861
+ 0.2492336745272817
+ -0.1150533905185065
+ -0.4450561816044189
+ -0.06993355636454991
+ 0.09253844510767809
+ -0.1000610640420145
+ -0.0698313843763893
+ 0.937320563935966
+ -0.0467781576047443
+ -0.1681224604784059
+ -0.6348904503155944
+ -0.3255593080943681
+ -0.4085209807394772
+ -0.1973597162255788
+ -0.1207550566380952
+ 0.01052399285950291
+ -0.1848780649545811
+ 0.3931454951158443
+ 1.708587401263964
+ 0.1815742073568385
+ 0.3432258558580351
+ -0.3235036466031508
+ 0.1002580442394274
+ -0.1656183374822657
+ -0.5108101149367126
+ 0.7029226243217359
+ -0.1502954479250325
+ 0.05155446529395855
+ -0.3022605283953436
+ 0.5006594548808039
+ -0.1540169005448221
+ -0.0808246526473457
+ -0.06080349728458864
+ 1.237949063220778
+ 0.457988933458353
+ -0.1983797881327917
+ -0.1453660564807468
+ -0.3645458471204732
+ 0.6623087958585292
+ -0.5191638331056148
+ 0.730676729677982
+ 0.454354417807533
+ 0.244905553179521
+ -0.4545438372434316
+ -0.1777129740215161
+ -0.09666991424093212
+ 0.8612857352244105
+ -0.2867503905402772
+ 0.01147565153030176
+ -0.3327065762902315
+ -0.04614795914575914
+ 0.1769359982094564
+ -0.07447234559883557
+ 0.6946784329695896
+ 0.8512323210306233
+ 0.1273929508353219
+ -0.03714283970900223
+ -0.1163562140248569
+ 0.07905646190407437
+ -0.2586250581226313
+ 0.3106167704848445
+ -0.1873673582250238
+ -0.5676658815811136
+ -0.3809431196943583
+ 0.06176087555426465
+ 0.6575358337549088
+ -0.006769186530244102
+ -0.1203960737346448
+ -0.1094544844648559
+ 0.1531586841524122
+ -0.3214904782015948
+ -0.2921953670052535
+ 0.326382780315558
+ 0.2417348463238819
+ -0.5516588351271658
+ 1.066164073381822
+ 0.14324349480137
+ -0.2733021473763657
+ 0.206060754119072
+ -0.02257933747166856
+ 0.2768576353874935
+ -0.2579005608332602
+ 0.1801217548083397
+ 1.084353873711691
+ 0.3582093678938069
+ -0.2916869832915906
+ -0.3537129759545287
+ -0.09869695728672255
+ -0.1342763217983003
+ -0.1435248816361132
+ 0.538588215431827
+ -0.1648167859173915
+ -0.06048176695018438
+ 0.01708217866334022
+ 0.5826225897182519
+ -0.8955426379811293
+ -0.2145654505127193
+ -0.5702901567777114
+ 0.06182340425302407
+ -0.4727413815038695
+ 0.8668513674103833
+ -0.2782503430951879
+ -0.1368352825144238
+ 0.2666864101935165
+ -0.3559992263173706
+ -0.5413058149479931
+ -0.1907750299241658
+ 0.09113609665269655
+ -0.3366637410284195
+ 0.1974660169012988
+ -0.310940985712738
+ 0.7591977595514805
+ 0.6462592979786056
+ -0.1249380157468614
+ 0.1349792499000788
+ -0.40097352887511
+ -0.2663907703264866
+ 0.6431491233037089
+ 0.5477259895917688
+ -0.1387607052964635
+ -0.2325564654979926
+ -0.01989557145425267
+ -0.5983963836613112
+ 0.27513653485933
+ -0.8452115138518678
+ 0.05263917292841345
+ -0.1531721592418351
+ -0.2878930384944877
+ 0.4625364395796986
+ 0.02948229076842242
+ -0.1863083386357931
+ 0.5301844345548528
+ 0.4299777175923086
+ -0.357440209921069
+ 0.4446768916936731
+ 0.2061364228902275
+ -0.008035266959642419
+ 1.00567185628664
+ 0.6234505133315437
+ -0.1063755889918123
+ 0.213775422530152
+ 0.1716216539220448
+ 0.5969951111180575
+ 0.3515302459721952
+ -0.4956136864952044
+ 0.04742685940225402
+ -0.7257486741103216
+ -0.2310899485637471
+ -0.1499868791407927
+ -0.2112420300445047
+ -0.00566803311686644
+ 0.1889455471317475
+ 0.02645800593250528
+ 0.4402766676397445
+ 0.2016486637184166
+ 1.098692300417186
+ -0.3895102758514091
+ -0.5062551631617818
+ -0.09603580353709633
+ 0.148616169977114
+ 0.100593758335289
+ 0.1763413543551331
+ 0.3274952942433564
+ 0.8240464416796819
+ 0.3176467522397424
+ -0.03187377697036982
+ -0.623889657664299
+ -0.4860291478329514
+ 0.5281204436024102
+ 0.06702912108261062
+ 0.2380243775316523
+ 0.5437146177333005
+ -0.04966703248674136
+ -0.1810109555153837
+ 0.5573015738350131
+ -0.4083930320187065
+ -0.04320482925074265
+ 0.1645640721387698
+ 0.06119533902414419
+ 0.7425524922816565
+ 0.1299360824582844
+ -0.00884558853432627
+ -0.1015165767888688
+ 0.6068938884710866
+ -0.09923176919218805
+ -0.09297497927202424
+ 0.03586137208023404
+ -0.2786570728969295
+ 0.6649177733162734
+ -0.3535585321565478
+ -0.3390062989598818
+ -0.2086173775975975
+ -0.09920688041443682
+ -0.02341421167161965
+ -0.1471803450154052
+ -0.3161453029449265
+ 0.02391801391446054
+ -0.04373650519867519
+ -0.3397983188119051
+ -0.3666108066854937
+ -0.2162670349776072
+ 0.2132530233673774
+ -0.5116313544736404
+ 0.5354757508904081
+ -0.2877069810675497
+ -0.1315602000375319
+ -0.5317429707262271
+ 0.4238105116584094
+ -0.2146127374578656
+ -0.2904641996440634
+ 0.6841309250228275
+ -0.1734036669822675
+ 0.005484918036074342
+ -0.3094351754069787
+ 0.1344267232447092
+ -0.6602876216385007
+ -0.1758653406754312
+ -0.3571123654793031
+ 0.1814137431085418
+ 0.9650432304737308
+ -0.2398079143340615
+ -0.1022114709403531
+ 0.03833987493886366
+ -0.3376619943855572
+ 0.1669260746161754
+ -0.3955724827984012
+ -0.7739629842886803
+ -0.0266264690360493
+ -0.06371473601428168
+ -0.3384160982798863
+ -0.05691570711822313
+ 0.07058341334237343
+ -0.01760983935993179
+ 0.2081866155072211
+ 0.2984905798906045
+ -0.2593394298702862
+ 0.01981180292951551
+ 0.4216274320393357
+ 0.3486590169606297
+ -0.07631088265866229
+ -0.2152207410893138
+ 0.1740728055653103
+ 0.351290202185461
+ 0.04066787938431084
+ -0.7437385732488911
+ 0.6547699883537691
+ -0.8451054495912956
+ 0.2292264008553798
+ -0.0910354805579545
+ 1.087828336259904
+ -0.0444661460746549
+ -0.1193586278922212
+ 0.00836495372866819
+ 0.4149317943238018
+ -0.1581694414855725
+ 0.08022494337025025
+ 0.3714328091574364
+ -0.2005283438516713
+ -0.542568868853561
+ -0.6382264845260477
+ 0.2456136959769961
+ -0.1647019171280566
+ -0.1592900284421765
+ 0.9506598247249513
+ -0.1207854405852313
+ -0.2320709254975472
+ -0.6554658409277617
+ -0.588265612204362
+ -0.5559580747465549
+ -0.4149467836913759
+ -0.1721699893401752
+ -0.09271062009813449
+ -0.3065949565790526
+ 0.3610463992147586
+ -1.78045410986781
+ -0.3813604075130993
+ 0.2611315918154911
+ -0.207841246725757
+ 0.3654741734387875
+ -0.3644560512267753
+ -0.6258362695359259
+ -0.0945642246204438
+ -0.3941104951709534
+ -0.06527453859664278
+ -0.3584363686709794
+ 0.4315938791984615
+ -0.1953073467988072
+ -0.2190909953692586
+ -0.115021973890395
+ 0.5799855764499777
+ 0.4499280518089379
+ -0.5754623080981474
+ 0.531975657300825
+ -0.4917340256474008
+ 0.5072275379282593
+ -0.7153225605620414
+ 0.4846294110052394
+ 0.5671459824889488
+ 0.03992505321172374
+ -0.6354848713516034
+ -0.1867426422707893
+ -0.4303902770886434
+ 0.05275823539234827
+ -0.4461769419672343
+ -0.1229379590513772
+ -0.4236142668132394
+ 0.01106239915900415
+ -0.02154850438347221
+ -0.03911587016610428
+ 0.9569181342427248
+ -0.1128324858156322
+ -0.1695409319828666
+ -0.05347345920787545
+ -0.1795049898251221
+ 0.3169830183710285
+ -0.3858293237770161
+ 0.2037783992187152
+ -0.2794130633306701
+ -0.6069808533956208
+ -0.5405563985527269
+ -0.04436903747447773
+ -0.05993332426826255
+ -0.04974037829521032
+ -0.1947166630766153
+ -0.2516635983236469
+ 0.3346425156244562
+ -0.3918183728316629
+ -0.4036485461565948
+ 0.105743687571403
+ -0.07132399658671379
+ -0.5961395921676819
+ 0.4239921022177991
+ 0.05750311417620047
+ -0.5471088188113188
+ 0.1308358818651182
+ -0.3976010903399521
+ 0.1146153207182655
+ -0.4476997987535604
+ 0.01426975284128053
+ 1.003570984477288
+ 0.1452193440987051
+ -0.4920617589968798
+ -0.5690524190500713
+ -0.2134868635891582
+ -0.206170501706324
+ -0.04551872261921921
+ 0.8430678829372334
+ -0.3573183298914445
+ -0.05962991053493866
+ -0.1001963259200308
+ 0.2847204138826752
+ -1.067253762044989
+ -0.4326873724552786
+ -0.7130954442931835
+ -0.2365857079833269
+ -0.5591639722162693
+ 1.026305220224091
+ -0.5373489300732801
+ -0.1441161885568221
+ 0.3954713930918267
+ -0.2624003777474603
+ -0.6800973467876378
+ -0.3813540502920702
+ 0.02821904743041741
+ -0.3865876884501602
+ -0.08912517604637459
+ -0.4377488653601013
+ 0.7829160956965705
+ 0.5113482797258616
+ -0.285247669325678
+ -0.04442222555388487
+ -0.5576208874960122
+ -0.3505112609552292
+ 0.1994045086736325
+ 0.07125286146978603
+ -0.2208518845142651
+ -0.3202505459560078
+ -0.1275974934391475
+ -0.5368283548484399
+ -0.1480910631784682
+ -0.975609212789403
+ 0.01524830790131133
+ -0.3797981234106209
+ -0.5498579688739406
+ 0.5070616356581784
+ -0.001014036535875534
+ -0.2136852815281384
+ 0.5351705137754126
+ 0.08279981590377991
+ -0.4575661231955304
+ 0.5586819570966582
+ 0.1739043109215139
+ -0.1407498560001399
+ 0.04272868334967283
+ 0.2589469168022305
+ -0.138637126227741
+ 0.3913490250444416
+ 0.06068764895200751
+ 0.2879950589451611
+ -0.1776425990110019
+ -0.5470553498576566
+ -0.03406831478065626
+ -0.8856640480589015
+ -0.3461303344982883
+ -0.4023461757591711
+ -0.5967203343406117
+ -0.04762961620743728
+ 0.1634154696283311
+ 0.05156478889768506
+ 0.374891437163266
+ 0.2299621020330013
+ 1.01764078070525
+ -0.5542537884397342
+ -0.7868807188082098
+ -0.1262971870208869
+ 0.05216108980434844
+ -0.0722023109936355
+ 0.2268641079788984
+ 0.126409343375917
+ 0.3224594870190853
+ 0.5492181841314215
+ -0.1329315953862936
+ -0.7962834558222827
+ -0.6022961242698679
+ 0.4057523933407385
+ -0.1588419956916801
+ -0.1271202814589718
+ 0.580341660931135
+ -0.1631469874510582
+ -0.2844734846955352
+ 0.3520853860280144
+ -0.4708253576023849
+ -0.1477759737373208
+ 0.2000449434284807
+ 0.02390515810455116
+ 0.8398425001088277
+ -0.1637045561289333
+ -0.05200944806289531
+ -0.14638327980134
+ 0.3766178616028983
+ -0.5126500931342141
+ -0.2669373765010273
+ 0.02493733031875291
+ -0.2934717180120997
+ 0.824756983242672
+ -0.5509116165875499
+ -0.3916611609328474
+ -0.3230987657043287
+ -0.2514784111222529
+ -0.1763128799012259
+ -0.1933217809645003
+ -0.37408932417309
+ -0.1586106281388953
+ 0.133115414169056
+ -0.38928854969928
+ -0.3592629507256938
+ -0.3747091378581611
+ 0.004420574358069006
+ -0.6735642918324432
+ 0.4881412103038595
+ -0.06094400134750316
+ -0.1633112102906608
+ -0.734951957008667
+ 0.306838462713064
+ -0.2605132937858697
+ -0.3404126612988638
+ 0.3516440964860457
+ -0.4766602216916284
+ -0.05426675370681971
+ -0.4342439540358475
+ 0.0905079479202041
+ -0.752640192074215
+ -0.2411232653901751
+ -0.5183463379948153
+ 0.2126155799223657
+ 0.948355905720532
+ -0.251404012937978
+ -0.01864565836884751
+ -0.152745167675961
+ -0.3721405280381076
+ 0.007573265391428359
+ -0.6043799101486504
+ -0.8691910425416818
+ -0.165923299089091
+ -0.1757896034347677
+ -0.3015416522430929
+ -0.1333719889512778
+ 0.04745289842002288
+ -0.222624961467681
+ -0.1631402378169525
+ 0.0739691720732934
+ -0.1689965018755382
+ 0.005539011694333889
+ 0.6129557359718374
+ -0.4440599719271117
+ -0.3418145940577555
+ -0.293785222543304
+ 0.6078366804029476
+ 0.1906107547366269
+ 0.137547076884127
+ -0.943828539188439
+ 0.7542068635643424
+ -1.015740738824357
+ -0.2226812806909455
+ 0.09622791925686651
+ 0.6386974647154608
+ -0.1553697927018379
+ -0.2751948666931138
+ -0.1178172406670678
+ 0.1506741517475596
+ -0.2192374339679856
+ 0.0135607250263139
+ -0.004752347692954299
+ 0.005054603630500858
+ -0.4789227097538492
+ -0.3271859252645017
+ -0.1580288546184008
+ -0.08159157907690892
+ -0.2166292514303432
+ 0.5961321612150892
+ 0.3707747287391505
+ -0.2595670498573999
+ -0.5778442850297116
+ -0.6142482455949375
+ -0.7786208651206313
+ -0.5311628869128089
+ -0.2070242437373837
+ 0.2423429217005519
+ -0.09245807969026332
+ 0.02615242705254926
+ 1.942214456604149
+ 0.07208652198382035
+ 0.1504526940669746
+ -0.05671761665546045
+ -0.06677154272410081
+ -0.5413677077846294
+ -0.6400015435233035
+ -0.7474244708216383
+ -0.5783654785183465
+ 0.08554097884892409
+ -0.3741144811529576
+ 0.2892656903887446
+ -0.1525561886731615
+ -0.3020201241191387
+ -0.1405210702236058
+ -0.2410430005772214
+ -0.124156588480938
+ -0.4829678766533977
+ 0.7552798920589129
+ -0.5025719260091526
+ 0.04839544960622997
+ -0.7348360949421585
+ 0.4634060934266534
+ 0.1885051703879014
+ -0.3369733760555384
+ -0.6455485059546264
+ -0.1281979342578744
+ -0.4972877106215881
+ -0.2173002860186208
+ -0.4275808205441188
+ -0.08610192215690848
+ -0.4741005227561371
+ 0.05390825452802709
+ 0.02131214188614609
+ -0.03694598086610448
+ 0.4851014317380515
+ -0.3749988873268422
+ -0.2153080505518481
+ 0.005454571033644709
+ -0.06216789174860946
+ -0.05298547864825581
+ -0.3776317477238814
+ -0.2033939365053905
+ -0.2729618944782381
+ -0.617892763468474
+ -0.5639878821042957
+ -0.300527489898864
+ -0.6502440469005009
+ -0.1661282163318294
+ -0.1854846483129881
+ -0.006825468443105815
+ -0.1454399028385248
+ -0.3735116269659869
+ -0.5043072482481197
+ -0.09373620565476463
+ -0.3468495424275193
+ -0.4970941831883467
+ -0.1946564746342996
+ -0.0128130086532128
+ -0.5956489362061527
+ 0.2880632110527631
+ -0.339743804629175
+ 0.2302477552400708
+ -0.5155223897531509
+ 0.3230057499453503
+ 0.2443372096977281
+ 0.1857369124026829
+ -0.5216692991239195
+ -0.5302076887443022
+ -0.3336553073704617
+ -0.1643661678253931
+ 0.03181972875602657
+ 0.5721384201397109
+ -0.4072878610131206
+ -0.06375422981163069
+ -0.0662786403733346
+ 0.3134737792595582
+ -1.084549023715948
+ -0.5955791155606697
+ -0.8054529387630414
+ -0.1051827144574285
+ -0.6791187379527408
+ 0.6462816413821661
+ -0.5280350810192099
+ -0.1648132542036891
+ 0.526712757951232
+ -0.09628546759534155
+ -0.788958909796334
+ -0.4110895253730163
+ 0.02938766500826371
+ -0.3816012990976516
+ -0.2855459266116003
+ -0.3498999592906448
+ 0.7197165137063136
+ 0.525578745117918
+ -0.4399810046534121
+ -0.1176780637657514
+ -0.6574389741286525
+ -0.4059997477136861
+ -0.02724444073919859
+ -0.2410073835946322
+ -0.2825317206242124
+ -0.2876586024759145
+ -0.1298022304206394
+ -0.2049024513723418
+ -0.8038773122221586
+ -0.9975979347616613
+ -0.03281499261344051
+ -0.1940293767501099
+ -0.7860682768196964
+ 0.4543715285779033
+ -0.07209027658748152
+ -0.1446449097416507
+ -0.1868152497898727
+ -0.5881902819879754
+ -0.5321495288436316
+ 0.6425934220835628
+ 0.05838196677647711
+ -0.06241466981931418
+ -0.2258698606250561
+ 0.1637755188302492
+ -0.1268876669791284
+ 0.06679710616576874
+ -0.1745458432677706
+ -0.4748157857742784
+ -0.3874042266589584
+ -0.4659903196160114
+ 0.172659502462631
+ -0.9203095010657294
+ -0.4016074524432053
+ -0.2846290115047411
+ -0.688387086349787
+ 0.09400168903740208
+ 0.482718361588352
+ 0.1907900932278317
+ 0.6582303876744932
+ 0.367157062330624
+ 0.2690321364338947
+ -0.5779947927492164
+ -0.7309560554516883
+ -0.128657432304649
+ -0.09187162706370723
+ -0.1882842217449678
+ 0.40874401973777
+ -0.03130755302113058
+ -0.3412385797966293
+ 0.234304443341925
+ -0.2454741056646836
+ -0.8174339501665628
+ -0.4409480491605677
+ -0.003423790669959458
+ 0.03471918611582803
+ -0.1751602049742589
+ -0.0962699260609152
+ -0.3575486518148243
+ -0.2997772098928483
+ 0.5528427675133079
+ -0.4121011613286376
+ 0.04238504407094401
+ 0.2405879512685
+ -0.1012576708106302
+ 0.2279585778625073
+ -0.2863998298406531
+ -0.05219271166546807
+ -0.305340545950068
+ -0.1902978854849447
+ -0.523803810243433
+ -0.3461196904921145
+ 0.05097977700431616
+ -0.3051033284103351
+ 0.1209534532016621
+ -0.3118662592391754
+ -0.2471677289165367
+ -0.3125483853830653
+ -0.3104062832576036
+ -0.4092539943953493
+ -0.241651308123654
+ -0.379341148361141
+ -0.2501425531983235
+ -0.2518264578417332
+ -0.3966071359905799
+ -0.3240074369953281
+ -0.5662052753132578
+ -0.2093338097701624
+ -0.3654291491401669
+ 0.618226872646975
+ 0.01197486512055113
+ -0.3029674445530482
+ -0.6831754900066797
+ -0.2282876800713723
+ -0.1867473527777132
+ -0.1807807287112149
+ 0.01182529324308042
+ -0.5783718429461576
+ -0.05890433736285863
+ -0.4596359838036555
+ 0.06885394425402475
+ -0.6632254849218142
+ -0.1119292966104332
+ -0.3877424738160345
+ 0.2503909100523899
+ 0.1635842514715485
+ -0.3359498325708253
+ -0.1415028506256285
+ -0.283024730305682
+ -0.3154435107845465
+ 0.1277001905978781
+ -0.6027792371346498
+ -0.8613851761163197
+ -0.1716816907748511
+ -0.02833239581533218
+ 0.02422305156303762
+ -0.228209148920771
+ -0.07642839357270599
+ -0.3370520799134479
+ -0.5885763840417114
+ 0.1216933565689515
+ -0.08781274217183209
+ 0.0678691506744504
+ 0.8424386819484797
+ 0.1373254746392774
+ -0.01848687134635017
+ -0.2380789556814966
+ 0.3417536574220434
+ 0.4341107023035369
+ 0.3841811126078573
+ -0.8935118834612313
+ 0.01571764673947633
+ -1.042059171744363
+ -0.8365385347930292
+ 0.3401309333656257
+ -0.2915878882651581
+ 0.1051927749202422
+ -0.2901577020926721
+ 0.0618613740823458
+ 0.1533367066468448
+ -0.2252632609392385
+ -0.0003889279360040632
+ -0.574137609203859
+ 0.1966132976521402
+ -0.4753077034071311
+ -0.3572521744406706
+ -0.7600784837680594
+ 0.1047355703523071
+ -0.2638850591568736
+ 0.4206406658170802
+ 0.7805677897879814
+ -0.3590121499116142
+ -0.6126076017729987
+ -0.3302466011684718
+ -0.8327453653806592
+ -0.2046762646182836
+ -0.2275626429313998
+ 0.2320441691743063
+ 0.1401799332325747
+ -0.5970465754508761
+ -1.780599153696266
+ 0.07756987606041904
+ -0.3081400852234309
+ -0.4248968471027421
+ -0.2693592531484564
+ -0.5683078211876698
+ -0.5945883095431329
+ -0.8705911103661095
+ -0.5075128735422443
+ 0.4214597634040959
+ -0.2486203285499218
+ 0.1125025700369858
+ 0.225057411613186
+ -0.1430888696058143
+ -0.1429968851306541
+ -0.5604979110577604
+ -0.5351480260750218
+ 0.004678630466235922
+ 0.4320858695144522
+ -0.5161319662964049
+ -0.3630488095515725
+ -0.4527927889180065
+ 0.2031393281035178
+ -0.1607454270140085
+ -0.4966602900840969
+ -0.6582776894049744
+ -0.04318015066022519
+ -0.3635098083101613
+ -0.471579012273411
+ -0.1123145540876857
+ 0.05589509485996638
+ -0.4836089243064695
+ -0.06424757629741631
+ 0.3175334511103713
+ 0.06938305935798574
+ -0.3293119100959557
+ -0.6367383000612401
+ -0.2040734804354499
+ 0.04266999162404084
+ -0.04060325871850645
+ -0.3757511228832247
+ -0.3815103374201938
+ 0.05287483712614335
+ -0.09858223122449138
+ -0.5837487434671705
+ -0.4299966143237329
+ -0.2148995151424994
+ -0.8285804665265564
+ -0.4165323504967136
+ -0.1857809070418956
+ 0.3446712216799147
+ -0.4880118815776988
+ -0.1894365459451416
+ -0.4380478611667041
+ -0.0763717173429115
+ -0.4952954920935713
+ -0.5693328535465947
+ -0.4754685200172154
+ -0.1007641264668812
+ -0.3800576287270971
+ 0.284635942408415
+ -0.2709478490104187
+ 0.2334849156425411
+ -0.5605803775049333
+ 0.3945194182158658
+ -0.3357561736624433
+ 0.2253190472079402
+ -0.479571204852919
+ -0.5695138081165433
+ -0.3906093647055345
+ -0.1365679338739176
+ 0.05764066780159962
+ 0.08603301501314856
+ -0.2196888087093433
+ -0.1234972996007928
+ -0.0986833872951893
+ 0.3237792379812792
+ -0.8613525024878457
+ -0.5615509348870983
+ -0.7592446921472276
+ 0.1699980362800157
+ -0.4653118715861744
+ -0.2158006747055174
+ -0.2500944346872818
+ -0.1287854137025125
+ 0.128934571740776
+ -0.003526488785242154
+ -0.8399276712505523
+ -0.330399341517634
+ -0.01560115462140701
+ -0.352187401170877
+ -0.2560230975307909
+ -0.1958792003549243
+ 0.01514683254785584
+ 0.1089498658005297
+ -0.5585856462889451
+ 0.1480583418170258
+ -0.6789117454684233
+ -0.3929536172126375
+ 0.2071827027731075
+ -0.3573211252942662
+ -0.2629996235435352
+ 0.001391320378811444
+ -0.1169842512237953
+ 0.1198736272528314
+ -0.737587748318728
+ -0.9270430400979962
+ -0.3577244664949029
+ 0.1776867345474032
+ -0.6732144224554912
+ 0.08819573140103359
+ -0.06922081909004965
+ -0.1024104914371722
+ -0.6596795250648703
+ -0.8987836492684684
+ -0.6217412233252386
+ 0.5988427651116034
+ 0.1024886468185866
+ 0.2814267734258853
+ -0.440849302190123
+ 0.2833800216072526
+ -0.1857008106833104
+ -0.4790854306347693
+ -0.1410378587265264
+ -0.8097925772780029
+ -0.4025154663769632
+ -0.5350615369579589
+ 0.09176713893577661
+ -0.7769137755094272
+ -0.4436049473708966
+ 0.2343623787993738
+ -0.5701056042917206
+ -0.01064426636932409
+ 0.2954508823005327
+ 0.2358216485226806
+ 0.2181170324298531
+ 0.3495023267527235
+ -0.2927560280883714
+ -0.4162973994033312
+ -0.5906676988840915
+ -0.1222333382354282
+ 0.08664743597606636
+ -0.2651065135750781
+ 0.08935692622538703
+ 0.1381891885489051
+ -0.3560236805655786
+ -0.3290535692413685
+ -0.2352849906006602
+ -0.5946768609244922
+ -0.06981201403965386
+ -0.1493741410658145
+ 0.5328681676798306
+ -0.1803987177453212
+ -0.4656443892726355
+ -0.2449153482117758
+ -0.2656246175033493
+ 0.4126557393360887
+ -0.06970205768609888
+ 0.1689991496794057
+ 0.03521543088269639
+ -0.1734343633323954
+ -0.2564711009803666
+ -0.1574609723597054
+ 0.002429636388936149
+ -0.3187242454451427
+ -0.4410757545849738
+ -0.2359101417730298
+ -0.3100384590225302
+ 0.03471939488113072
+ -0.3296317688323425
+ -0.5098149823851663
+ 0.1115913721329731
+ 0.05544012386448133
+ -0.2966993802900029
+ -0.1209047751876421
+ -0.3866592490685754
+ -0.1826766095340182
+ -0.4171484883108832
+ -0.2055397286381209
+ -0.7338480244931559
+ -0.283080680774467
+ -0.2987096942708872
+ -0.7017857700949461
+ -0.250202168055706
+ 0.08381076909182114
+ 0.332480902185142
+ -0.4351887355398816
+ -0.3163994729811774
+ -0.4724570727667632
+ -0.4884225332146895
+ -0.4150732055937091
+ 0.07797318041408605
+ -0.03151408728005083
+ -0.6058452367039552
+ -0.07677053496821562
+ -0.1392373581209522
+ 0.0006927963515423502
+ -0.656714391695566
+ 0.2670241507563403
+ -0.2274640211730099
+ 0.1341297488331412
+ -0.3458294865065677
+ -0.2721745884432445
+ -0.1487729025880484
+ -0.4218555509077397
+ -0.2251641955182626
+ 0.458214894576395
+ -0.3824456598159615
+ -0.6264304719445675
+ -0.02818429183189752
+ 0.2873914589498447
+ -0.2338890229101601
+ -0.4467807308459597
+ -0.135648058213299
+ -0.200936807542687
+ -0.7314371257828245
+ -0.449482767223645
+ -0.1042173793885466
+ -0.09641920731737179
+ 0.6206538973634722
+ -0.4435485103285841
+ -0.003479203257694294
+ -0.05194601433788879
+ -0.1700149283501921
+ 0.5020815222136729
+ 0.0192417018483452
+ -0.6057225242512514
+ -0.2621997899297607
+ -0.8682309385078543
+ -1.043226215785034
+ 0.5722085366169893
+ -0.4789889334996213
+ 0.4311134707884468
+ -0.101731891758905
+ 0.2487426248174195
+ 0.01732784564969043
+ -0.3846973076070464
+ 0.06265948837716913
+ -0.7293727917649786
+ 0.3199024793730494
+ -0.2831940560390996
+ -0.198043463486127
+ -0.9064857416764353
+ 0.3022793558404221
+ -0.3038014268564736
+ 0.02765174351442887
+ 0.7054582590677552
+ -0.4053038671205914
+ -0.5922230756584481
+ 0.0907887262006568
+ -0.7964267323984823
+ 0.3489800291146762
+ -0.1950297082350069
+ -0.1181827315175544
+ -0.04118604247545288
+ -0.6400703568846832
+ 1.590408800181046
+ 0.1571280168753901
+ -0.4780752919448401
+ -0.6494939895635206
+ -0.05350493158024193
+ -0.329179308140593
+ -0.257915126993325
+ -0.8452967617689512
+ -0.1919436667441916
+ 0.08452274833016174
+ -0.1506276388393554
+ 0.01064368205982586
+ 0.378029109083333
+ -0.002957610086980191
+ -0.1433967042786035
+ -0.6681496213324567
+ -0.6965558583695808
+ 0.07571463971795134
+ 0.02660778153957135
+ -0.4866147033920999
+ -0.4676101780756626
+ -0.09402517136169601
+ -0.1326465655751625
+ -0.2803161262685953
+ -0.485866789551306
+ -0.6445031845162837
+ -0.06321898795230017
+ -0.1374206965699841
+ -0.4298840398853365
+ 0.3437860129195507
+ 0.1592555937562658
+ -0.2693761470584372
+ -0.1425018237827043
+ 0.3288224426709815
+ 0.0195566626478075
+ -0.654391449308484
+ -0.6664374747216034
+ -0.3510986932119884
+ 0.03509224374305035
+ -0.147292553679547
+ -0.7057787800957498
+ -0.4426942656955598
+ 0.01710547508556669
+ 0.3133941036713175
+ -0.06798168256159805
+ -0.07650107513124035
+ -0.1655639353152909
+ -0.9519765174331033
+ -0.3779128940251456
+ -0.2298855679561967
+ 0.2021331965923949
+ -0.4780967027784193
+ -0.09950319619920876
+ -0.4720304411565514
+ -0.1112782900500317
+ -0.3773567266591552
+ -0.5667222274309959
+ -0.5896218913169158
+ -0.1510458944758229
+ -0.04156115793996827
+ -0.03681408002395202
+ -0.4049332155526779
+ -0.02564108070178676
+ -0.6269657015590318
+ -0.01375084422072832
+ -0.7141367265552291
+ 0.006402219572510645
+ -0.1116813095085798
+ -0.6351424844998569
+ -0.3215358210264493
+ -0.1453723291787659
+ 0.05600993134507122
+ 0.03509606520352065
+ -0.2278840841918018
+ -0.09522467680281629
+ -0.228585377418122
+ 0.08195281332895714
+ -0.1842305797350325
+ -0.4984737766499143
+ -0.4774309346289708
+ -0.008274983605111122
+ -0.2823742909616017
+ -0.5074415497056384
+ -0.0601794615320619
+ -0.07871156883960556
+ -0.00377493693413423
+ -0.09820926355559258
+ -0.7688777294662257
+ -0.1374337098313828
+ -0.06543259074014873
+ 0.02158491328776586
+ 0.1396910922816859
+ -0.2860301223920511
+ -0.3672166937853523
+ -0.2510587610670307
+ -0.7060334798031539
+ 0.2515814693383551
+ -0.6614633043811741
+ -0.2949217675439889
+ 0.4303324168282956
+ -0.3135406019711567
+ -0.1993587358280154
+ 0.06932898965958072
+ 0.02217375067049907
+ 0.3213100649691303
+ -0.4335256262750316
+ -0.4281642139585038
+ -0.473963183933536
+ 0.2133249927104609
+ -0.4004653724469927
+ -0.151378714167807
+ -0.02945951951758842
+ -0.142659286076651
+ -0.7121306953654724
+ -0.8445663015726538
+ -0.2209021606614747
+ 0.512200415597961
+ 0.13769296313119
+ 0.5519345468118018
+ -0.5762499488813367
+ 0.3555599434085788
+ -0.305311940074022
+ -0.6351470680682418
+ -0.04196554042601083
+ -0.8998594993504928
+ -0.4535528189901826
+ -0.6777603265344038
+ -0.2887483673233799
+ -0.2831278318562285
+ -0.4127703587845231
+ 0.4146056042245125
+ -0.3064887161727025
+ -0.1141271356089437
+ -0.07834559455024592
+ 0.1277111151789827
+ -0.4689873231334128
+ 0.2541968472283095
+ -0.4181961051962566
+ -0.453338303251671
+ -0.497127561623368
+ -0.1288193178658342
+ 0.09946804927215061
+ -0.12091369625438
+ -0.396217561134134
+ 0.3894409469451128
+ -0.4567492349068292
+ -0.4467548413341039
+ -0.2729206784507691
+ -0.3992577023411391
+ -0.2573050411317117
+ -0.2067353367913678
+ 0.5553610595412475
+ 0.04538662696329159
+ -0.3803851835258086
+ -0.00259323383371598
+ -0.2350047786824387
+ -0.1829308873898255
+ 0.5419626222596291
+ -0.03811420635925365
+ -0.185960744657928
+ -0.2164678225760939
+ -0.4200307266349941
+ 0.0002546722747690633
+ -0.07481360739756698
+ -0.1625080928643031
+ -0.4125995043730831
+ 0.1502347487002705
+ -0.1108577175964447
+ 0.03345724174870192
+ -0.2647308458052282
+ -0.584897453222202
+ -0.2650084377370297
+ 0.3530167565089282
+ -0.1902048302092513
+ 0.1541529182310633
+ -0.1538034588366328
+ -0.08610237613014243
+ -0.4160826091813778
+ -0.09220729602744239
+ -0.8254781753596087
+ -0.1683985710011476
+ -0.1735331419808584
+ -0.7272198112431602
+ -0.2717276480951551
+ -0.2211317713624017
+ 0.05543300345384761
+ -0.6889324090807434
+ -0.1535171750177869
+ -0.1836087058263277
+ -0.3632190296038028
+ -0.4846933554914004
+ 0.2302330350816434
+ -0.102657421229265
+ -0.5803153691199542
+ -0.04487682653247512
+ 0.2462586672395643
+ -0.01417572099124056
+ -0.418053859829126
+ 0.2724431659469464
+ -0.4492959915335534
+ 0.05943425868649164
+ -0.5366000624281262
+ 0.06590299731818172
+ -0.1273034477604761
+ -0.3070846767492227
+ -0.197093048201637
+ 0.7219881824524234
+ -0.155631745676243
+ -0.04563653298760457
+ 0.09480141906801526
+ 0.3893130988045581
+ -0.4143033631645172
+ -0.5812985885040769
+ -0.1412033826050553
+ -0.1309092407210991
+ -0.7567019244018102
+ -0.653214702445443
+ -0.1231280865165363
+ -0.1867860070024334
+ 0.4687074101654123
+ -0.07346352365363995
+ -0.4513008291317256
+ 0.1414997796645397
+ -0.3930457399982226
+ 0.1631704198669574
+ -0.4001551301711788
+ 0.01042299058816831
+ -0.4046580574017991
+ -0.2040063920270557
+ -1.102677030407465
+ 0.3518882150110856
+ -0.6382891836101693
+ 0.3346394949630933
+ 0.3602337672832703
+ -0.05594881120170617
+ -0.1656607059035895
+ -0.5210339696533037
+ 0.1185495276223964
+ -0.340517133351099
+ 0.1902629384864901
+ 0.1621509275941509
+ -0.71835646970261
+ -0.8127341619973234
+ 0.4469372558920139
+ -0.3512253696851279
+ -0.457648781991237
+ 0.3527961760445964
+ -0.4035043205011868
+ -0.1225143340455787
+ 0.4983127024531727
+ -0.7183171201401464
+ 0.1876845817269912
+ -0.2093057835543573
+ -0.2019724687188628
+ -0.1713789561376335
+ -0.3952918491817058
+ -1.780978883369023
+ 0.2054842071086569
+ -0.4635030503835605
+ -0.2956284372493603
+ -0.001774898250552024
+ 0.1488280602474648
+ 0.1264226549129192
+ -0.8286877440999377
+ 0.2245515245693221
+ -0.3073731151894248
+ -0.06460709917175121
+ -0.07790419215112504
+ 0.007877119553052977
+ -0.09092231242175547
+ -0.1686780185257491
+ -0.765013763816823
+ -0.6871377717234923
+ -0.006594425772513775
+ -0.04806563673352361
+ -0.3037413570737171
+ -0.4753764674771662
+ -0.0379924271185581
+ -0.2571618251627662
+ -0.2459781214801
+ -0.4163424599886744
+ -0.4175941733527985
+ 0.01312125107172365
+ -0.02035363517690484
+ -0.02847920176124768
+ 0.5206458942302443
+ 0.1079314780400711
+ 0.0009521103246746602
+ -0.1253918872207877
+ -0.1693561910156049
+ -0.1016467216058956
+ -0.8184227805599097
+ -0.7299448618632853
+ -0.3707293502550358
+ 0.001252315368334842
+ -0.3326712945128822
+ -0.5176513739044207
+ -0.4375717545721807
+ -0.5399760187668166
+ 0.2186112767831467
+ 0.5257085521262155
+ -0.135808682835768
+ 0.0579250191708186
+ -0.5360367459179185
+ -0.2452683086022597
+ -0.2616003825821842
+ 0.05008352235535284
+ -0.1258846733544287
+ -0.1190667804258561
+ -0.660169922962523
+ -0.1080773298518675
+ -0.001930059900269921
+ -0.2254690900251465
+ -0.5199738071019793
+ -0.15368605110091
+ 0.382747030021245
+ -0.3399709960143961
+ -0.05185000718016074
+ -0.1809122102596091
+ -0.3344644883054311
+ -0.1577847536637051
+ -0.5534016355907267
+ -0.1609953751694373
+ 0.4180245105874469
+ -0.7122580027821085
+ 0.005350136450229161
+ -0.2130573081651347
+ 0.0547486758571803
+ -0.09144499173330059
+ -0.5043758693566643
+ -0.08137944512578063
+ -0.165721680075962
+ -0.2147303372558582
+ 0.1802639287302827
+ -0.2503409246424228
+ 0.008387856501332013
+ -0.1343322075075337
+ -0.1552770470090488
+ -0.4236960286618235
+ -0.1051338219795501
+ -0.07967984352968752
+ 0.06485908420979801
+ 0.01619844664292754
+ -0.6022687374535013
+ -0.1064542089149937
+ -0.1135033618750938
+ 0.3748822295642341
+ 0.3055917998483587
+ -0.3332077235466904
+ -0.5053144394121257
+ -0.4181511486753801
+ -0.5480040773026975
+ -0.1093613562713298
+ -0.5535666429787212
+ -0.1495924073026777
+ 0.3717905496599088
+ -0.07874312291855366
+ 0.0197351116593076
+ -0.1857099985425998
+ -0.04408574975722964
+ 0.6265704341874341
+ 0.0411248751029252
+ 0.2177664529664201
+ -0.463326466177071
+ -0.1155788520119949
+ 0.07627480780988947
+ -0.1154392196611928
+ -0.05354405147501572
+ -0.09449540109562496
+ -0.5771323721290285
+ -0.5184918414810038
+ 0.302546362799287
+ 0.0418575769084128
+ 0.134369023143456
+ 0.272872593738047
+ -0.451072112669163
+ 0.2222601662559372
+ -0.3671819292660506
+ -0.6668562782762132
+ 0.1268313211719089
+ -0.8644601868357874
+ -0.2605807864844837
+ -0.6512543457612744
+ -0.2815701835236822
+ 0.03980362031234853
+ -0.3384463768631267
+ 0.1358336920104301
+ 0.1764416948239552
+ 0.07118155278932202
+ -0.2955362599328757
+ -0.0620030852375667
+ -0.5535991388553626
+ 0.2081219248241339
+ -0.1849028896935379
+ -0.730857270559144
+ -0.06876572091017155
+ -0.130106666752676
+ 0.261837008192287
+ -0.1167673382119821
+ -0.3435751842616931
+ 0.2185022598636893
+ -0.2986719176606851
+ -0.3476349706604125
+ -0.3383069171226881
+ -0.4943657876494036
+ -0.3014395244202314
+ -0.1512277644792329
+ 0.2497477773393427
+ 0.3684965157080135
+ -0.03975557072904728
+ 0.1156069179951857
+ -0.07180650093159041
+ -0.2438028687998155
+ 0.4418684913637954
+ -0.1536875051000218
+ -0.05110101265443797
+ 0.04262054514314754
+ -0.5450020522064242
+ 0.06382102010754576
+ -0.2633338422159232
+ 0.03428998973366581
+ -0.3396396278171734
+ 0.2218785662937951
+ -0.1406035549058024
+ 0.009704001788654788
+ -0.2790755487712052
+ -0.3025930785630245
+ -0.5992507698826174
+ 0.3179612276310023
+ 0.003149844452743701
+ -0.01660386451206627
+ -0.03989765752844681
+ -0.1471733429454518
+ -0.3991178639965604
+ -0.2310807981650578
+ -0.6165195989948826
+ -0.2443863922497242
+ 0.1446641504619525
+ -0.7581687113193498
+ -0.1630934639146746
+ -0.1864094203189325
+ 0.007390622514341341
+ -0.4222623583706733
+ 0.06589276325146391
+ 0.3931121254033183
+ -0.05997993820942499
+ -0.6096833499924588
+ 0.2736455897344224
+ -0.1761486303371735
+ -0.5060751065354971
+ -0.02909222922175481
+ -0.01524255743558093
+ -0.1839560200807636
+ 0.04091625043667953
+ 0.1315026676092598
+ -0.4866903458965861
+ 0.1711047202539764
+ -0.4422489010456397
+ 0.001511426167088095
+ -0.04639869365802123
+ -0.07198601017677353
+ 0.01831033130226101
+ 0.5726396179628991
+ 0.1963252025856242
+ 0.09560035596270883
+ -0.07479006174482507
+ 0.2383236076594711
+ -0.6525137457339615
+ -0.5733500639054371
+ -0.09277279640447748
+ 0.2135053197475681
+ -0.5839706148374094
+ -0.5772042349178457
+ -0.02587418833276165
+ -0.1758147521967876
+ -0.02039002839069973
+ -0.4584890671511103
+ -0.3727776208085981
+ 0.2161430387505507
+ -0.33382871875445
+ -0.1018758948934526
+ -0.5155807499245789
+ 0.2230774657853115
+ -0.3842771617731814
+ 0.2765709669076771
+ -1.11437088776058
+ 0.1370290419361331
+ -0.6907121556971
+ -0.04739560124816106
+ 0.4945854676725926
+ -0.2518511238092139
+ -0.2090823881211713
+ -0.5826711045003965
+ 0.04548258606789699
+ -0.1853294453073051
+ 0.1542278754398604
+ 0.4641990825116425
+ -0.3355069922025304
+ -0.3325706576622386
+ 0.240999893509847
+ -0.3739549587971491
+ -0.7292391624211603
+ -0.1778788290675548
+ -0.32985631835857
+ 0.1773685507675661
+ 0.3143987682501025
+ -0.4241186269008492
+ -0.1196109874348598
+ -0.2703331487635954
+ 0.0646029191795594
+ -0.09293151587895067
+ 0.05867323189292146
+ 1.572152959310365
+ 0.0270851943823703
+ -0.3201605719329901
+ 0.03511290922165978
+ 0.1842220640356778
+ 0.4459288682235256
+ 0.2279510038651417
+ -0.6208225668217512
+ 0.2033200440448049
+ -0.4768920295949141
+ 0.05635444804434454
+ -0.1792207056397316
+ -0.05082725323384989
+ -0.116466160497955
+ -0.1646789310506677
+ -0.8546516345710713
+ -0.6863333032159274
+ 0.1251280715920445
+ -0.1954916256772424
+ -0.06330408849680744
+ -0.3614178746908751
+ 0.1110444058475385
+ -0.4441635474921972
+ 0.0421501215297819
+ -0.3563461749842403
+ -0.2847085013375505
+ -0.01885466908589918
+ -0.08714902937426544
+ 0.1108528108141068
+ 0.1868153364508421
+ -0.0782948091852478
+ -0.09368056609716874
+ -0.06796896435348695
+ -0.497680262528085
+ -0.1496864352033443
+ -0.7899711281536115
+ -0.6025616651729295
+ -0.3411802195266797
+ -0.04670556170928879
+ -0.3428166896726749
+ -0.2845726199256554
+ -0.4125870758047719
+ -0.3383725144380084
+ 0.04576291584876581
+ 0.4867574895058831
+ -0.1734111351515317
+ 0.4046916923000636
+ -0.0692196393810556
+ -0.364205893770604
+ -0.2551900009272337
+ 0.05737247351539661
+ 0.08039984007240546
+ -0.11299788125515
+ -0.4721938914488412
+ 0.04841770947422069
+ 0.2143597286200945
+ 0.1183004551578102
+ -0.363460031717068
+ -0.1907615130706292
+ 0.4028808348822922
+ -0.3171712423084697
+ 0.1974988994089932
+ -0.242326408426382
+ 0.06990657685043837
+ 0.03283291026075733
+ -0.4808273426038372
+ -0.353546190225623
+ 0.3814243035574654
+ -0.6407503423680718
+ 0.3096372846159585
+ -0.2214550425447073
+ -0.02287760645039265
+ -0.1304712309055208
+ -0.5079350855894919
+ -0.09170209542267782
+ -0.2564185760653225
+ -0.4122184566482636
+ 0.05779244757900356
+ 0.1355589819676707
+ 0.3286801707679867
+ -0.2242603117821102
+ 0.0335455361107912
+ -0.5371454248562983
+ 0.1317342409872321
+ -0.08379994681574615
+ -0.1375314996449098
+ 0.1556617156194927
+ -0.2608544997717424
+ -0.2488335162112193
+ -0.1214693826932154
+ 0.1554129338795171
+ -0.005680118626726197
+ -0.1059142855277008
+ -0.6238782668523944
+ -0.5963151157794544
+ -0.2148362270843856
+ -0.3258183472222976
+ -0.248606488482252
+ -0.09849441598768362
+ 0.1805113569718476
+ -0.04418818805519761
+ 0.3737371718874873
+ -0.1530315749338608
+ -0.2235354786574718
+ 0.7630667232166822
+ 0.2642022185562009
+ 0.3208451718589377
+ -0.4680450945273534
+ -0.171291712100384
+ 0.1519325249856672
+ 0.0864344929490222
+ -0.1192515192935129
+ -0.05985311789830235
+ -0.2929187491434199
+ -0.3373089593719307
+ 0.2738443816818401
+ -0.4459312647860724
+ 0.1019232205332759
+ 0.0505340192312996
+ -0.2868115385288292
+ -0.1693873008287598
+ -0.2983439658193252
+ -0.5193256213739745
+ 0.2007825339743431
+ -0.677732951503412
+ -0.09657284972081065
+ -0.4774623379542781
+ -0.01895688026804819
+ 0.1338266916968649
+ -0.1412708513186414
+ 0.138190548765444
+ 0.07912287981106435
+ 0.1137545407236712
+ -0.2905926167465767
+ -0.1433534307405324
+ -0.5789718450772364
+ 0.06703335477883755
+ -0.2909611390633863
+ -0.4768384780853501
+ 0.3468340324384735
+ -0.1242840480300472
+ 0.1628599665526195
+ -0.2098058380705283
+ -0.2650524620418804
+ -0.04530575041494886
+ 0.0742239161679762
+ -0.2315164120681402
+ -0.3974653743649324
+ -0.3949615742671702
+ 0.1431491502245915
+ -0.06100188175408954
+ 0.254619509251988
+ 0.2385636964554492
+ -0.0377979983973895
+ -0.08510487825699684
+ 0.07898195343477653
+ -0.3157876622138711
+ 0.3101460860926867
+ -0.2513762463139826
+ 0.02130796450574071
+ 0.2262271679854062
+ -0.5401435669147285
+ -0.3928044928834363
+ -0.2627404691172375
+ 0.1127320496462008
+ -0.3874823969145912
+ 0.01510115021532389
+ -0.2242313304610447
+ -0.03784015856384065
+ -0.231376614555029
+ -0.08660512547898351
+ -0.2163715339732224
+ 0.2014987297473436
+ 0.00183042504023886
+ -0.3018592518870045
+ -0.1481235804195503
+ -0.1354999653037391
+ -0.09485588183453179
+ -0.3306772971591763
+ -0.1183932030843847
+ -0.2962642578543512
+ 0.3651718826337273
+ -0.3648497928756702
+ -0.02235452262494591
+ 0.281071647808349
+ 0.1376248104624031
+ 0.04071968038686895
+ -0.0623331878745489
+ 0.5235593914018143
+ 0.1847146953260254
+ -0.5898320982543569
+ 0.07259131492753236
+ -0.07542503649687438
+ -0.3877343858715561
+ -0.07180098022627282
+ -0.2175881717960334
+ -0.261557164031689
+ 0.2491196222479528
+ 0.04101563216656046
+ -0.2394441282095503
+ 0.2637079765764338
+ -0.491673551927533
+ -0.3199563992575
+ 0.2237069053073689
+ -0.1916615770179255
+ 0.03207752718399837
+ 0.1150203537322834
+ 0.2999929701318548
+ 0.1594169188046992
+ -0.2518452325433932
+ 0.1315469323585451
+ -0.5568227828411216
+ -0.4552940231107597
+ -0.1225571536787343
+ 0.3087794611803037
+ -0.4073169324749234
+ -0.4018687778918577
+ 0.1001182006973928
+ -0.1233661035052116
+ -0.5311694950430884
+ -0.06244269889225383
+ -0.04191660189537352
+ 0.1652929995941863
+ -0.2685189742071611
+ -0.2022708955035912
+ -0.4994199663615731
+ 0.2949704313847821
+ -0.0413959778685745
+ 0.1839277872468872
+ -0.8877791188039712
+ 0.124646207202205
+ -0.5174491059310083
+ -0.1741877905242727
+ 0.2182184736194161
+ -0.1985385581553671
+ -0.1495612649704648
+ -0.5022711929891177
+ -0.03208153325427857
+ -0.3229429888774093
+ 0.1232233055373354
+ 0.2090266598930229
+ -0.565694282351267
+ 0.004313344182687162
+ -0.0508010608429796
+ -0.3660963789208949
+ -0.7893390105930082
+ -0.6141821686914091
+ -0.1735863843034059
+ 0.153064126764466
+ 0.2688441272796904
+ 0.01891955490740877
+ -0.03993908158052884
+ -0.2345909675961855
+ 0.0488287063273122
+ -0.1771437205453895
+ 0.07067450063965428
+ -1.781448255057624
+ 0.08491388308960003
+ -0.03810905788179736
+ -0.3085800186030186
+ 0.1155403599852064
+ 0.3749475045315057
+ 0.1361256280495673
+ -0.381924303711864
+ -0.0602324042427213
+ -0.4588384239011747
+ 0.2167459982336198
+ -0.3119731657244059
+ 0.09338490336141297
+ -0.00013580052025487
+ -0.1582682259768826
+ -0.8192320269381829
+ -0.5635562527794323
+ -0.1163258468853171
+ -0.1849412934159787
+ 0.2078265387141373
+ -0.1693054398482254
+ -0.1339753540407564
+ -0.5926870633174385
+ -0.2068659662318922
+ -0.4028693742414952
+ -0.1592433573791794
+ -0.03298466862338994
+ -0.2664711180239981
+ -0.6223670831098527
+ 0.2539463342474416
+ -0.2112463899073392
+ -0.06707021797068523
+ -0.2540933845523378
+ -0.5723527575894582
+ -0.2663211757105155
+ -0.559775271923221
+ -0.1669748156094223
+ -0.3391612146520647
+ -0.007304739959241142
+ -0.3714503942196212
+ 0.1978289085127442
+ -0.2994606800321042
+ 0.07648124144600604
+ 0.1120042552350718
+ 0.2106307826577676
+ 0.001842787583032354
+ 0.3002279075694899
+ -0.1444902776971541
+ -0.5616957465792392
+ -0.1711839811946715
+ -0.1908787083942699
+ -0.01413513841741283
+ 0.01441352600904396
+ -0.2493234142352183
+ 0.07187192025363083
+ 0.08250887000827953
+ 0.4622517571621938
+ -0.3484961403360574
+ -0.2500344340875087
+ 0.327055980519856
+ 0.01861793533271652
+ 0.1246782192478675
+ -0.3286139189108901
+ 0.3619715668980983
+ 0.2289805073568801
+ -0.7468191925568648
+ -0.5389303871852547
+ 0.14594117923781
+ -0.4542946657875223
+ 0.2432635170910493
+ -0.2263087899597126
+ -0.04143624459168473
+ -0.2929049223777545
+ -0.4249351946087646
+ -0.1945125584822932
+ -0.2787407752932843
+ -0.3020247629591156
+ 0.2550596994518242
+ 0.1787026603248639
+ 0.07429499669250805
+ -0.1636903109796274
+ 0.2187793428277464
+ -0.6477365560999034
+ 0.121753783403594
+ -0.1053863531423386
+ -0.439961013599136
+ 0.07622327403616731
+ -0.08556302169099331
+ -0.0008746784338009017
+ -0.1351544972756517
+ 0.1271525507074459
+ -0.2176602092416781
+ -0.01554345296761483
+ -0.5222439855642136
+ -0.7316171375860131
+ 0.2446548485233575
+ -0.1467291582369216
+ 0.1175902634457195
+ -0.1681546882107498
+ -0.04521157099650252
+ -0.2043091023341305
+ 0.4424845033373849
+ -0.02996202084625425
+ -0.4227659748562899
+ 0.5910684140400475
+ 0.1593138334345164
+ 0.3361204425311022
+ -0.1920805023816655
+ 0.09822228634348028
+ 0.09002368509893081
+ -0.1322447170189405
+ -0.2313654657212282
+ -0.1137904372765817
+ -0.1345582192042777
+ -0.5916468699011971
+ -0.1974399310317567
+ -0.7310498207769246
+ 0.0904490285916611
+ 0.2617952826851531
+ -0.6658800334079958
+ -0.2136383312489579
+ -0.2474050201719908
+ -0.37313985201887
+ -0.09261816710249975
+ -0.2226843760738902
+ -0.3276008787398033
+ -0.2650874794759996
+ 0.1107475747306679
+ 0.2261150250691746
+ 0.01410981678350486
+ 0.08656220760912722
+ -0.223291144823372
+ -0.04653183679472674
+ -0.0123189017563664
+ -0.1241550945158221
+ -0.5780305491792225
+ -0.2051679551218057
+ -0.6380321535686744
+ -0.2217327200028662
+ 0.1880702651678863
+ -0.1374455798500671
+ 0.07477579189264887
+ -0.230654246917585
+ -0.1460761228157335
+ -0.351748140673035
+ -0.009962655782386361
+ -0.4829335787134655
+ -0.4047193455733119
+ -0.08748337483917695
+ -0.03324537104327262
+ -0.2107543464561359
+ 0.04541561517782763
+ -0.1206787589924748
+ -0.3716068785062409
+ -0.3374418396412748
+ 0.1726760188136365
+ -0.3308066332358634
+ 0.255170315489397
+ -0.2759676806557681
+ -0.04273612238743313
+ 0.1552226463334661
+ -0.5278672766348809
+ -0.5171652498932222
+ -0.259448482300692
+ 0.07732678154058592
+ -0.5486383408282367
+ 0.314303831825362
+ -0.2208393588601793
+ -0.04410650703985628
+ -0.2222334863746301
+ -0.4153149275231512
+ 0.2285908136142874
+ 0.2151545018434103
+ 0.08146538307396635
+ -0.1900672020132375
+ -0.3466077795322671
+ 0.03569483143576228
+ 0.1384705152199227
+ -0.3207737890095315
+ -0.1944937775285996
+ -0.2662333462037326
+ 0.4404826946611061
+ 0.08773299284947769
+ -0.09194271179202586
+ 0.1281029509325907
+ -0.01978898548302627
+ -0.00775196992546068
+ -0.1741854317807355
+ 0.3259848025224046
+ 0.04401697403542181
+ -0.4975007188752522
+ 0.1436066122471584
+ -0.2219367402569576
+ -0.1000778091158833
+ -0.1266845224851695
+ -0.09121927167550367
+ -0.3601844598365169
+ 0.2486687523844783
+ -0.03584302241113982
+ -0.09127580032417015
+ -0.02447346217466925
+ -0.4224191129196516
+ -0.4131361763939417
+ 0.203067049236413
+ -0.3012140924559434
+ -0.01364892432756534
+ -0.4814532324701255
+ 0.3170718278420939
+ 0.1587410603006361
+ -0.216424363157273
+ -0.06895458529347577
+ -0.4016696264415105
+ -0.3622807926391333
+ -0.162427061007282
+ 0.1434223168812234
+ -0.3712616885015544
+ -0.5024324778723644
+ 0.2529794125252718
+ -0.1779998772475726
+ -0.7279837946956683
+ -0.4446830120824465
+ -0.1750441732422112
+ 0.1146496243364256
+ -0.4959298585253443
+ -0.163924280908683
+ -0.3573746569560586
+ 0.3814031678509575
+ 0.05951062074438399
+ 0.2997662033054271
+ -0.3855924523817795
+ 0.1029731263097956
+ -0.1208204919484131
+ 0.08569036493936666
+ -0.1509810931506685
+ -0.2073591495323373
+ -0.2151644795594506
+ -0.2827638203076263
+ -0.09764470321143262
+ -0.6350097962454752
+ 0.1677218152331212
+ 0.03991765426500021
+ -0.3740673754317914
+ -0.3755793000001317
+ -0.1420218531216212
+ -0.3745804350769871
+ -0.9402288793052358
+ -0.7371490179018136
+ -0.199320776234589
+ -0.1086466664003375
+ 0.2234300207129388
+ 0.4520090418359478
+ -0.1103738931205903
+ -0.2241078313420341
+ -0.3088597516010719
+ -0.5642512091492026
+ -0.4143577903162539
+ 1.585769903461108
+ -0.0928980419106312
+ -0.1639243683643334
+ -0.6609187513382873
+ -0.03370139779658248
+ 0.3998306293641981
+ 0.008523386283980328
+ -0.3397761104272032
+ 0.1596395829533195
+ -0.2321779744920058
+ 0.3470263743593928
+ -0.2987069271702892
+ 0.3727308282033386
+ -0.1411837021579574
+ -0.1765649647109546
+ -0.4840684675721143
+ -0.5546491976224101
+ -0.519672020666552
+ -0.07326886758992969
+ 0.2264171857621609
+ -0.3077200915977026
+ -0.5490934046857481
+ -0.6020907699945578
+ -0.6160437088271168
+ -0.2187029258141679
+ 0.1405764638862422
+ -0.093012829466791
+ -0.2969089595390227
+ -0.7501222899942074
+ 0.2866256906799098
+ -0.2387046251713708
+ 0.04525727454160814
+ -0.2667324397508992
+ -0.5717447658970759
+ -0.1781952509044608
+ -0.5443454325827244
+ -0.3391144945543338
+ -0.3844961989382008
+ 0.01499988326006704
+ -0.3258333496747647
+ -0.2592405706859131
+ -0.3504717802952628
+ -0.02668263132768721
+ -0.336942418143115
+ -0.008899326508741834
+ -0.4064724339785245
+ -0.12176728147033
+ -0.6585179601696123
+ -0.4894753878178747
+ -0.2442924820600981
+ -0.3920391396714519
+ -0.5221616690504185
+ 0.08143575493923301
+ -0.4243781097009219
+ -0.0783176392163677
+ -0.2195665841694698
+ 0.1850063913193356
+ -0.7196111874495446
+ -0.3179532141429242
+ -0.01565370585505655
+ 0.005846773803302997
+ 0.01335231182307772
+ -0.2718325851744277
+ 0.3462680224808091
+ -0.1959387716606182
+ -0.5438993329772722
+ -0.4787343953438634
+ -0.06678603417674459
+ -0.499921571639358
+ 0.09815744930648497
+ -0.2129229731611965
+ -0.07730212367128855
+ -0.5485743205851044
+ -0.5452923246924926
+ -0.3020803622176061
+ -0.1591960143215016
+ -0.04956358398817994
+ -0.0290568894388576
+ -0.008253192309295925
+ -0.1955745058619006
+ -0.04618583863778489
+ 0.1091612752012542
+ -0.4619001610364459
+ -0.3692202542164156
+ -0.09988786470240667
+ -0.4692197245166221
+ 0.1914676051407242
+ 0.2121749482849875
+ -0.1149307010526159
+ -0.1904478657477881
+ 0.2462014858522821
+ 0.001754223755763481
+ -0.08480309741901883
+ -0.2127612683438606
+ -0.5118184167687053
+ 0.382347513962762
+ 0.03808150938029006
+ 0.2518807181589469
+ 0.02154858415273547
+ -0.3893449322968922
+ -0.2167216909410216
+ 0.3860177129811224
+ -0.08499909511413424
+ -0.3887432617560126
+ 0.3708619457636211
+ -0.3120436016510948
+ -0.05299917601938802
+ -0.1099162929881584
+ 0.3817873712974926
+ 0.341076861738471
+ -0.5291531398780812
+ -0.3218978604160307
+ -0.1569871545851364
+ -0.3389052762012951
+ -0.8543496902114009
+ -0.4430601170393201
+ -0.822917007835629
+ 0.1578091180914681
+ 0.02356555643550554
+ -0.7311591075724099
+ -0.02046745063084701
+ -0.2556341900660989
+ -0.4334977374873441
+ -0.2172836075673819
+ -0.1004610402281179
+ -0.5995114010789439
+ -0.1580215576663957
+ -0.2700160753907077
+ -0.1791718769204184
+ 0.10433318172727
+ -0.2628705816799846
+ -0.1686570115607318
+ -0.3068685281060631
+ -0.09814630618918101
+ -0.1497385025023432
+ -0.4074351212448353
+ -0.3334924678781389
+ -0.6538958399570722
+ -0.300561782996361
+ 0.1822896782480434
+ -0.1139468491097467
+ 0.03539343147907053
+ -0.1550662450716123
+ -0.5397131238570544
+ -0.372181867218021
+ -0.4674203237608217
+ -0.6545563178051702
+ -0.4229395670115984
+ -0.04113516245428499
+ -0.5451085318148088
+ -0.511592875468121
+ -0.2840266659950414
+ 0.0106744015890542
+ -0.4554353508680534
+ -0.3388074378591223
+ 0.06221199312929226
+ -0.2740359519549297
+ -0.3067440885546456
+ -0.2550129301256622
+ -0.2390063345835033
+ -0.0006035686096761179
+ -0.605677444649717
+ -0.119793771027347
+ -0.2750243242962616
+ -0.04642902449794497
+ -0.6308490936483154
+ -0.01242161786196535
+ -0.07132997202448933
+ -0.0887428962759793
+ -0.2325238462713042
+ -0.9047463541424298
+ 0.01658182378927922
+ -0.00757330869321584
+ 0.1593916913105907
+ -0.30865992061819
+ -0.3331606028431572
+ 0.1263895129933455
+ 0.01961474297915897
+ -0.3470257833748221
+ -0.5424716805812152
+ -0.2009709154582145
+ 0.45758918922306
+ 0.2787925860775491
+ -0.2414443397955571
+ -0.315930801341089
+ -0.2764128272374969
+ -0.3745237272689381
+ -0.126159677981048
+ 0.4191869601185408
+ -0.6784266104832994
+ -0.5163194826192089
+ 0.05122030675741623
+ -0.3439245695363883
+ 0.1948868616089859
+ -0.195621240269816
+ -0.2138035569149919
+ -0.347389993572753
+ 0.339360043845781
+ 0.01605039416612359
+ -0.3309417321826002
+ -0.3241029873528691
+ -0.2576945702651006
+ -0.3775080322103062
+ 0.1443789467073577
+ -0.2115000012605343
+ -0.0632786938770744
+ -0.8588933711020734
+ 0.217274860245064
+ -0.3226043112026534
+ 0.01771453443535823
+ -0.2761564016940267
+ -0.3606438760377993
+ -0.4118506441057463
+ -0.2423832117304276
+ -0.0887804850759015
+ -0.5729156705116153
+ -0.6925410607046041
+ 0.5280927917298445
+ -0.2823300145568775
+ -0.9402331275720441
+ -0.1997246501346932
+ -0.6724763279724075
+ 0.06182904160979734
+ -0.708049809297232
+ -0.259721293167383
+ -0.3865451274527018
+ -0.1284111529569806
+ -0.3514575322321374
+ 0.08207950137162345
+ -0.09598541532096631
+ 0.147289309646151
+ -0.2497369372424541
+ 0.2156248484000855
+ -0.2658245768023106
+ -0.572600223736922
+ -0.2521990907983624
+ -0.4295099510742876
+ -0.04681170516341528
+ -0.7328427675174419
+ 0.1884437179260753
+ -0.04673741402675256
+ -0.7794252860778346
+ -0.6598692557606886
+ -0.1671782095543159
+ -0.3821492234558344
+ -0.9238147067806809
+ -0.6916296008663123
+ -0.3402834544006016
+ -0.578286567452837
+ -0.08526704879707259
+ 0.4962274795435372
+ -0.7861315151895858
+ -0.2066634650164923
+ -0.5337220378425992
+ -0.718410100444599
+ -0.504459492665439
+ -1.781827984730382
+ -0.009947068886489769
+ -0.4232115708025747
+ -0.5426458863517839
+ -0.5264455047333106
+ -0.02365578538253354
+ -0.3068997345092218
+ -0.5150887200116396
+ 0.19076241356687
+ -0.1554067325416549
+ 0.3969325754490018
+ -0.3676212471563032
+ 0.5257695833701596
+ -0.274742496467984
+ -0.1857001610880882
+ -0.1400976841123476
+ -0.3617743663956622
+ -0.6082153702179874
+ -0.03632788515964308
+ 0.02645797539322557
+ -0.4161029360544639
+ -0.7431684755220693
+ -0.664251865974368
+ -0.686806875659062
+ -0.1496536443263377
+ 0.190202432826203
+ -0.1443255792224843
+ -0.08102931935739026
+ -0.72094662197717
+ 0.004892581362082224
+ -0.299705529614719
+ -0.01696646447822541
+ -0.3272883990347764
+ -0.4905533145913219
+ -0.1813396174116535
+ -0.4071266089152618
+ -0.5655314771866083
+ -0.4955683794089641
+ -0.006248670385064545
+ -0.3033017414216436
+ -0.5888400949273649
+ -0.4074841816642161
+ -0.5959435509593141
+ -0.9107791944897182
+ -0.3349167971705578
+ -0.7373588861608363
+ -0.6026594024957698
+ -0.6107404965543706
+ -0.5003765155757252
+ -0.2098611070589861
+ -0.4021373027965684
+ -0.8970043375612039
+ 0.08397910064022965
+ -0.4382484290758023
+ -0.3301399368071711
+ -0.1242664808119831
+ -0.2566178601993747
+ -0.8580139120956334
+ -0.3507095368583322
+ -0.3811768675654083
+ -0.399773831124957
+ 0.1689071027451845
+ -0.1953723184008203
+ 0.3067860909489342
+ -0.5295403789461324
+ -0.462947842632857
+ -0.309595415132518
+ -0.4885207249855884
+ -0.3616981532296132
+ 0.1724954091130182
+ -0.2242279567779056
+ -0.1011815074360616
+ -0.6491739385864949
+ -0.586984527587308
+ -0.3778323314108448
+ -0.09455214175017755
+ -0.1417058751390151
+ -0.2992596095016197
+ -0.03766037803092157
+ -0.1127711321594186
+ -0.148458127618688
+ 0.2093510540750044
+ -0.4264534725673995
+ -0.5603598915878025
+ -0.1225630439665603
+ -0.4815789276416481
+ 0.1703550775539186
+ 0.08599999366535897
+ -0.4500855357806468
+ -0.299901613610683
+ -0.006269558339009458
+ 0.1243574071130169
+ -0.2346236097390691
+ -0.08636255906208028
+ -0.2229581332903815
+ 0.2823707262727844
+ -0.2397291346814265
+ 0.1680025127720532
+ 0.3012079184576376
+ -0.7086369232392157
+ -0.6408726543683755
+ 0.3433000709787449
+ -0.1575065203138797
+ -0.2867059557405419
+ 0.2773035145438126
+ -0.2150019370514253
+ -0.4243012461071846
+ -0.05769483473691139
+ -0.07319840475241103
+ 0.3170796895196715
+ -0.5671667329225263
+ -0.3613263866052935
+ -0.1833799785322691
+ -0.6008257845500781
+ -0.6653095750697096
+ -0.6002023243499531
+ -0.6657416600414023
+ 0.1797629486941266
+ -0.3595463967012169
+ -0.6608457903818953
+ -0.1399092453423791
+ -0.3320523822637252
+ -0.6346831609524493
+ -0.1126116635467497
+ -0.4430829785354419
+ -0.5485231708125181
+ 0.03204657762249968
+ -0.5301733635083953
+ -0.5816943497436409
+ 0.008806774026283262
+ -0.5491988821134777
+ 0.08435077825563157
+ -0.4249142318330439
+ -0.4528829190479355
+ -0.1372350565664413
+ -0.3979607906751999
+ -0.2736356445295965
+ -0.6591575170066557
+ -0.2028113340747752
+ 0.3093224396829657
+ -0.1191120114081912
+ -0.05310542061942999
+ -0.07089508746778765
+ -0.8108684520555332
+ -0.1785032426837721
+ -0.5999447934883962
+ -0.6111411990278564
+ -0.4186274799455245
+ -0.1996346316510463
+ -0.5072772867718675
+ -0.5085715229962611
+ -0.4783727689671217
+ 0.3888878648421634
+ -0.5018817073580097
+ -0.1710123961143074
+ -0.03440537061758202
+ -0.6307201710364533
+ -0.7624669294232587
+ -0.1576758872803966
+ -0.1730081850814273
+ -0.02625730250783562
+ -0.5651390390100943
+ -0.2542031839819762
+ -0.3311672194039363
+ -0.07320000952316806
+ -0.7051065686715809
+ -0.5397917702212847
+ -0.02024915602074184
+ -0.1898657938494608
+ -0.314988435251115
+ -1.106120080454726
+ -0.5480091149859121
+ -0.09145879212478093
+ 0.1440405642236308
+ -0.5120847002837695
+ -0.05440699605913334
+ 0.2362600119337995
+ -0.2498941318550015
+ -0.3758131420797248
+ -0.4106673983087781
+ -0.3363085217087289
+ 0.6044613757751727
+ 0.1122602238867986
+ -0.3170173832997
+ -0.2052360563028308
+ -0.3537423350446363
+ -0.3191986995735654
+ 0.01210117158462355
+ 0.2407197443137293
+ -1.131072648759672
+ -0.6094826423122511
+ 0.1481031201204994
+ -0.2816758046960969
+ 0.1752267227585191
+ -0.2742201391037056
+ -0.650284605760318
+ -0.4139406904977087
+ 0.3116073296461769
+ 0.09366767815532326
+ -0.6537020409696733
+ -0.5264410585863214
+ -0.6306669892186386
+ -0.2142258307113107
+ -0.2299817083155755
+ 0.06915493757999686
+ -0.1521691785608325
+ -1.141583345649978
+ -0.06592206427003312
+ -0.3126744427081004
+ 0.01693288377691876
+ -0.3528965617401257
+ -0.1314278329686176
+ -0.5596825145110919
+ -0.2598449364567456
+ -0.3186944506137265
+ -0.6657774294296043
+ -0.6689401126733523
+ 0.8424123812819385
+ -0.3009561611668924
+ -1.064671667809632
+ -0.5656834873141398
+ -0.7752133072999027
+ -0.1241937641920823
+ -0.6374480002381808
+ -0.4316929876739758
+ -0.5379254658864181
+ -0.1328429314433819
+ -0.5164809431613604
+ -0.2962416807611852
+ -0.1095985366281921
+ 0.1207874243767804
+ -0.6628900788488759
+ -0.1351168325674617
+ -0.2640325389261486
+ -0.8452106536516678
+ -0.3278363941281444
+ -0.5382437306891634
+ 0.0007679836840912218
+ -0.4236868179998368
+ 0.1319238561852083
+ -0.2514732603231891
+ 0.00682872503865941
+ -0.2460237822275235
+ -0.2149518213119463
+ -0.3853157704397552
+ -0.7518385681609683
+ -0.5661407784010941
+ -0.4055167927140272
+ -0.5343414090579431
+ -0.2868332194461589
+ 0.2708073279502483
+ -1.022867290643607
+ -0.2684839686071238
+ -0.4610225988546588
+ -0.6772542738231266
+ -0.3544382407374108
+ 1.740030988687096
+ -0.2402757352641925
+ -0.5008001701776205
+ -0.32203566623503
+ -0.420424818079375
+ -0.5527956962790427
+ -0.4165025225562441
+ -0.1934917831570036
+ -0.2564252939818574
+ -0.3979042505792373
+ 0.569503383874053
+ -0.3992567834737347
+ 0.5897134182343675
+ -0.4717142696950412
+ -0.1879011738315803
+ -0.3296751719897661
+ -0.04853534424595358
+ -0.3196629319664885
+ 0.01616278646428472
+ -0.02518437276958412
+ -0.5159949290714172
+ -0.4637381442910093
+ -0.7480603122998082
+ -0.593565034849613
+ -0.3443225637849446
+ 0.1915663217760353
+ -0.2208231019276707
+ -0.0229822183777675
+ -0.9744571245769105
+ -0.1626221200879218
+ -0.3515559219094913
+ 0.03383880333558515
+ -0.4688044937671148
+ -0.7618252549229642
+ -0.62682769836385
+ -0.5754922484276397
+ -0.2888300568057754
+ -0.572224317416559
+ 0.01053109933068843
+ -0.294445312607977
+ -0.7097400471505686
+ -0.3989451628754628
+ -0.7911465174554497
+ -0.8293220722254347
+ -0.2840166022341136
+ -0.5712601088393791
+ -0.4600099221423827
+ -0.28899931163757
+ -0.3643181064797407
+ -0.2225982521597181
+ -0.2438786397524137
+ -0.9357264224665949
+ 0.228355580792485
+ -0.1621760245473221
+ -0.3049375648757576
+ -0.02225913657565592
+ -0.1694873664214451
+ -0.7959264250443929
+ -0.4139968176207957
+ -0.4110033725326739
+ -0.7852385808451339
+ 0.1283921083206729
+ -0.1463796515185316
+ 0.2271431064471801
+ -0.5617095218394167
+ -0.7841145258499482
+ -0.2560159493630336
+ -0.5580690917179528
+ -0.04531553057782736
+ 0.3554651982974579
+ -0.2229454527347418
+ -0.1027446492423381
+ -0.6148578968220384
+ -0.3213478564924183
+ -0.4648935364962582
+ -0.1411256112089259
+ -0.5837217247480977
+ 0.147878190493986
+ 0.2097076500532646
+ -0.06846971738883641
+ -0.247471001276119
+ 0.5637195559861582
+ -0.8643569774815417
+ -0.5739224547249889
+ -0.1211870337370245
+ -0.6808082790534996
+ 0.0666681877316912
+ 0.06161818894203498
+ -0.6313891561168232
+ -0.4116426898980775
+ -0.1467126937197818
+ -0.2977466389072961
+ -0.3153989022423644
+ -0.5208853164006397
+ -0.3845323102999652
+ 0.280267202921041
+ -0.6839282700139054
+ 0.1757954743509033
+ 0.2795987531029381
+ -1.063435226925195
+ -0.7635577498452711
+ 0.4197159489910926
+ -0.04269171867875766
+ -0.1163816233067556
+ 0.3169323876707662
+ -0.3241239598066025
+ 0.02207212575000063
+ -0.02996874692232253
+ -0.4523229984245173
+ 0.01235470586480735
+ -0.4904427974491405
+ -0.3480502876861254
+ -0.1594231677310244
+ -0.6080547005840844
+ -0.1753453575408354
+ -0.4323488361306168
+ -0.505339485231958
+ 0.1550320090461448
+ -0.4788857991812676
+ -0.7416837536959027
+ -0.526284161501043
+ -0.3205144331745952
+ -0.6799907880853793
+ -0.0004602501180474434
+ -0.3553702825004848
+ -0.5628476691497847
+ 0.1831584813954614
+ -0.5833876316757762
+ -0.2385667806020592
+ -0.1435223220691675
+ -0.5862099375816562
+ -0.006706504552293172
+ -0.4107388300348321
+ -0.4971982875136436
+ -0.197366562155806
+ -0.7940342484313364
+ -0.1969251071604586
+ -0.9874351191383243
+ 0.07926008935697504
+ 0.1646474683723194
+ -0.1233008039743702
+ -0.02671002162957524
+ -0.1444779380085388
+ -0.8378694132281145
+ -0.3031219709420606
+ -0.4809574349308396
+ -0.5928992192700092
+ -0.4413021065317886
+ -0.04918086472912069
+ -0.1076738850473241
+ -0.3879281706209609
+ -0.5227018007203815
+ 0.3082199540555409
+ -0.8051717417915679
+ -0.1150540598055636
+ -0.1704053487569717
+ -0.8442359408404969
+ -0.7832043444645047
+ -0.1760183397472159
+ -0.03972588631436266
+ 0.1985375297124761
+ -0.3433438205288021
+ -0.6022461326730766
+ -0.3832753364025572
+ 0.02496989821628015
+ -0.7482856620325489
+ -0.676472325144241
+ -0.1995175329101491
+ -0.3055061345658232
+ -0.3525741657072834
+ -1.041952251483809
+ -0.4833379927283012
+ -0.1631391027722319
+ 0.08717001671536372
+ -0.5758173054151819
+ 0.2556821980832631
+ 0.2893202308655086
+ -0.3180363901873887
+ -0.3543792204057355
+ -0.1415516959141055
+ -0.3925201797698654
+ 0.8471840398193545
+ -0.007706221773311706
+ -0.1963279733293128
+ -0.06959797801059125
+ -0.3439763571075633
+ -0.1369718553100855
+ 0.08363263051704599
+ -0.08420122646260238
+ -0.9430659754739588
+ -0.4837684467461363
+ 0.108912306293059
+ -0.3097210873343849
+ 0.2073936141374547
+ -0.2969534935970397
+ -0.6893898771050506
+ -0.3805016869987031
+ -0.01829813528337139
+ -0.03519004420106402
+ -0.4904205191547068
+ -0.5237925240566278
+ -0.8873934736899731
+ -0.1647033558058378
+ -0.6895951797493588
+ 0.1969087071731084
+ -0.1431303983363662
+ -1.199648901972244
+ -0.2292936600652613
+ 0.1048424274021737
+ -0.211285411441128
+ -0.3412345589704287
+ 0.1421968005512652
+ -0.5929397675682737
+ -0.300151981810605
+ -0.3521789047934598
+ -0.512952562361777
+ -0.3186910232639853
+ 0.9687960781341542
+ -0.3247884445108192
+ -1.111584493802074
+ -0.3401393556610821
+ -0.4732730076001035
+ -0.2112119737469602
+ -0.6182892105283664
+ -0.5317519963536463
+ -0.5122297506852407
+ 0.1991472282966215
+ -0.3521110322185296
+ 0.07007926399907323
+ 0.1071993659132263
+ 0.08979388021070796
+ -0.6263631267375758
+ -0.3159070728631599
+ -0.621762198439926
+ -0.8270000722327756
+ -0.3211575912606422
+ -0.4743296938417983
+ -0.1040256616831242
+ -0.1049837439919935
+ 0.1657019051342271
+ -0.3762664671296157
+ -0.470896309465375
+ 0.1131506048092131
+ -0.2081354288090403
+ -0.3751672573201461
+ -0.7475183680699227
+ -0.3429889606103283
+ -0.3563272169382081
+ -0.193391652912252
+ -0.1531689089457126
+ 0.01097693395417735
+ -0.8701040648264207
+ -0.3143213515089616
+ -0.320219666872623
+ -0.592222215133461
+ -0.3119573320575327
+ -1.781973028558838
+ -0.5607983807665291
+ -0.5284186051541483
+ -0.2431205520419281
+ -0.3293907359360963
+ -0.844879692017794
+ -0.3785271889603082
+ -0.01566285948976559
+ -0.6479386231714839
+ -0.4968833348626299
+ 0.7222550173615462
+ -0.5314642510724801
+ 0.4308429549802154
+ -0.6232325490933887
+ -0.182016847791158
+ -0.8778392013648422
+ -0.1639641219509562
+ 0.03408601202469844
+ -0.01649806840710853
+ 0.08165899544008666
+ -0.7182053520196864
+ -0.0282191147370792
+ -0.5870543552588785
+ -0.3231940518303731
+ -0.5771586795985312
+ 0.3262405283444714
+ -0.2528153413391997
+ -0.4082394060139936
+ -0.7741023157948116
+ -0.1681944551198781
+ -0.409362942909045
+ 0.1675440584613964
+ -0.5640719656890355
+ -1.055730129940361
+ -1.098571488379675
+ -0.8975787973673068
+ -0.03772469550847653
+ -0.5642342418592303
+ 0.008230844877315392
+ -0.3339261354764625
+ -0.5514432759140413
+ -0.3581455261509393
+ -0.4072398822900626
+ -0.7505923501963231
+ -0.4133824271519346
+ -0.2502443089715727
+ -0.1859781500659672
+ -0.2507778584384046
+ -0.5768442401927268
+ -0.172494219696996
+ -0.1370585867667568
+ -0.7451345314503817
+ 0.3863714854580726
+ 0.08592667913501936
+ -0.224872090415018
+ -0.3867075059046672
+ -0.01995574410190462
+ -0.7792667864810917
+ -0.5139905686401676
+ -0.1542818303227253
+ -0.9569043036713922
+ -0.2697091330581493
+ -0.1987512335898944
+ -0.2010240181995746
+ -0.3898078563984238
+ -0.5728928421282474
+ -0.4898382537117549
+ -0.6661950745854164
+ 0.2316645697315715
+ 0.1451958537847786
+ -0.285186100538286
+ -0.1548825383639861
+ -0.3606243712905282
+ -0.04309501997003859
+ -0.5252121926059879
+ -0.08087819685630879
+ -0.8435507862497488
+ 0.4306854850221897
+ -0.08238840393192921
+ -0.05041650085296915
+ -0.01158433575335821
+ 0.6521341473703037
+ -1.047237039308981
+ -0.3746236902847343
+ -0.1082794913183117
+ -1.031700987750881
+ 0.1391159630165882
+ 0.1736528264501267
+ -0.6512238773038403
+ -0.4587991036038348
+ -0.1340821280386915
+ -0.7334583616678994
+ -0.4458441551671066
+ -0.837471432556554
+ -0.6672799757736255
+ 0.2448374172288726
+ -0.9024474589734426
+ 0.1023670755906258
+ 0.0292058596005524
+ -0.9520214971401303
+ -0.8268143038010669
+ 0.2972605217114852
+ 0.1453064233583261
+ -0.5232784383932808
+ 0.2086008331921708
+ -0.7627467577788207
+ 0.3941662642328789
+ -0.2286381155884264
+ -0.5870456814615304
+ 0.102084148967303
+ -0.4329515063089142
+ -0.3906233582382577
+ -0.1731692891447
+ -0.462936283622991
+ 0.2186150787660332
+ -0.5378741730398333
+ -0.5513110470695967
+ 0.08792702355002706
+ -0.5160325021276126
+ -0.8038774266202716
+ -0.8673068591619917
+ -0.2800402211052486
+ -0.5071812287055846
+ -0.245761552277381
+ -0.1131894656146579
+ -0.7111469043039585
+ 0.2949153372857375
+ -0.6125145957330751
+ 0.1333191507641706
+ -0.4143036664128203
+ -0.3881311020441194
+ -0.4536636134855772
+ -0.6501534428375323
+ -0.4587908045668875
+ -0.2262689907292591
+ -1.008930698162811
+ -0.2858199286034775
+ -1.097091975238689
+ 0.3349940031359749
+ -0.03397858581056419
+ -0.1115325585421367
+ -0.1536060218366431
+ -0.2472757970660318
+ -0.9552163802897028
+ -0.6360437725640494
+ -0.2415017541557331
+ -0.587043818741025
+ -0.4349002239176226
+ 0.05466084891586871
+ -0.08379992506168299
+ -0.4337862151309793
+ -0.3523864784159469
+ -0.2180967687295187
+ -0.8293383325079787
+ -0.3981414008486881
+ -0.3406100475235269
+ -0.9146022384063078
+ -0.4776784098582947
+ -0.2444239310349579
+ 0.02509980574020787
+ 0.01141825131356056
+ -0.4052794734982313
+ -0.4729987232950348
+ -0.4093980513685815
+ -0.00873726058681297
+ -0.7712260881429435
+ -0.7848996302391045
+ -0.4474293883176877
+ -0.4323587577203974
+ -0.3591563401798847
+ -0.9546891379024977
+ -0.4272933483664859
+ -0.06972562127096517
+ -0.02149647229712578
+ -0.770948698054748
+ -0.03291204158136948
+ 0.3803140241482079
+ -0.1873962583031693
+ -0.347983988323403
+ -0.1636512977496206
+ -0.3091525419691572
+ 0.8900416145331014
+ -0.1743739584560785
+ -0.2799925329935282
+ -0.2953298210434973
+ -0.450373929504557
+ -0.1897727562191744
+ 0.1512685793668392
+ -0.2564901069991625
+ -0.7598665348694464
+ -0.4516988612050298
+ 0.1068511089079621
+ -0.2808640885633978
+ 0.08429370500173265
+ -0.3006954281227031
+ -0.5940605997954104
+ -0.4359973149611513
+ -0.2442812926963645
+ -0.0329967553759234
+ -0.2558588863449351
+ -0.5317364343041211
+ -0.8531979377142996
+ -0.6747777970265376
+ -0.759844933067973
+ 0.0006778703703523043
+ -0.1294741974933304
+ -1.106916969987646
+ -0.1352047865966687
+ 0.08682798495941844
+ -0.5157487159470723
+ -0.3502479771286062
+ 0.3010730983680521
+ -0.5465252622325496
+ -0.3861814509901219
+ -0.460932413329754
+ -0.3924467851902882
+ -0.003125988376217017
+ 0.7091393647100384
+ -0.3071080884322199
+ -1.248602155389827
+ -0.6026747990886756
+ -0.151398152882901
+ -0.2826794853998861
+ -0.7794898241130669
+ -0.5593715976627073
+ -0.4852336979367511
+ 0.008309981183236928
+ -0.1021599316578544
+ 0.3411885873017287
+ 0.5081079556857369
+ 0.03733243284709165
+ -0.3308654045131658
+ -0.2466537274174862
+ -0.9377014554868648
+ -0.8369771035990859
+ -0.3451759856061667
+ -0.4415002397679108
+ -0.2260156389975992
+ -0.09391867372990505
+ 0.20536671518883
+ -0.3820615019536124
+ 0.8603809226716443
+ 0.04649318982692087
+ -0.158594619703022
+ -0.3744326803384477
+ -0.9125369928504006
+ -0.2378369680554814
+ -0.3006028796512427
+ -0.08976209282829463
+ 0.03878589158372698
+ -0.2571253410084418
+ -0.785713420861162
+ -0.3177862219631656
+ -0.2314554537666901
+ -0.3843821789143249
+ -0.4873158910290698
+ 1.867504138689031
+ -0.1400122810502813
+ -0.6753642256336548
+ -0.2131931662576885
+ -0.4222201678406883
+ -0.992839970337568
+ -0.3564598873179906
+ -0.1984565326015064
+ -0.8003576707711179
+ -0.4047668580826831
+ 0.7674033625513189
+ -0.5379221398723746
+ 0.3200337625725557
+ -0.6216122206835325
+ -0.1813225694221128
+ -1.087091976625574
+ -0.261186702356849
+ 0.01544308449351302
+ -0.2500519919860956
+ 0.1441280229092948
+ -0.9619638588218969
+ 0.1269707449510237
+ -0.6043244873826396
+ -0.1725858061112837
+ -0.6338179309763565
+ 0.3837868560834052
+ -0.1949495842806335
+ -0.758838935074038
+ -0.6577446655062089
+ -0.1066555349812738
+ -0.4665885207142938
+ 0.3969287809523685
+ -0.692421554516083
+ -0.8766299067088819
+ -1.222737098832862
+ -0.9412237269783912
+ -0.1783534432115874
+ -0.5793127719721858
+ 0.00198151099599386
+ -0.2914654072177844
+ -0.9132033195906868
+ -0.3403370434379572
+ -0.1868548302155974
+ -0.6710837117043588
+ -0.2454886164132825
+ -0.1241173018458294
+ -0.2881038463860114
+ -0.2303714358992366
+ -1.015450790887978
+ -0.103293216194567
+ -0.2492892148066009
+ -0.501306977223504
+ 0.5467538639021241
+ 0.2218582371860424
+ -0.2512560586044336
+ -0.7542107007949712
+ -0.02320318421047902
+ -0.8658572514826759
+ -0.5559053392767729
+ 0.02184836138294483
+ -1.020389550090781
+ -0.6871829233387893
+ -0.3082731594064871
+ -0.6241027114402874
+ -0.2269937410753727
+ -0.7018013596758071
+ -0.7708968870449653
+ -0.6888896844758244
+ 0.4445543856629801
+ -0.2511562352753987
+ -0.1454995404220746
+ -0.2401718120916491
+ -0.1373932587443327
+ 0.05750814917539201
+ -0.5077294001027047
+ 0.05337787197100174
+ -0.9368218187167636
+ 0.3094167643873372
+ -0.5086778642578426
+ 0.06744163899424491
+ 0.1149160751543754
+ 0.2772787764088001
+ -1.131635194925813
+ -0.24299331655764
+ -0.1048965486925691
+ -1.226254278840357
+ 0.2029837279627382
+ 0.1659767946555612
+ -0.7132139376091509
+ -0.4943209625346273
+ 0.05117485812238402
+ -0.9063858289101545
+ -0.4820357410883333
+ -0.9985494038759675
+ -0.6582131227198482
+ -0.1703380258281345
+ -0.9928703297273094
+ -0.114582736253507
+ -0.09210900657241534
+ -0.7078960436284223
+ -0.9469585751118496
+ 0.1005995272527878
+ 0.2414918171114861
+ -1.09964696711853
+ 0.1575427776842223
+ -0.8200464232382167
+ 0.333162096363932
+ -0.3821110116835941
+ -0.5101465687146329
+ 0.2144853276229104
+ -0.512968358020117
+ -0.488113300839539
+ -0.2231572929378784
+ -0.6201640114343301
+ 0.2779820537987536
+ -0.5104169196537974
+ -0.6104312516002482
+ -0.01020268160961942
+ -0.5220419351288996
+ -1.02325893573648
+ -1.128840855457466
+ -0.2799193428358276
+ -0.4285771894615326
+ -0.546634031813172
+ -0.1516111067465357
+ -0.8121415040333105
+ 0.4884931648429183
+ -0.6067981257056273
+ 0.1552447809247549
+ -0.559431567530568
+ -0.1767958055953588
+ -0.5082820086240474
+ -0.8587536693663146
+ -0.4448482480218933
+ -0.190572533645124
+ -0.9276026706789513
+ -0.3727380520268397
+ -1.022288134606446
+ 0.5338402697560298
+ 0.01606721260939164
+ -0.1198185494852305
+ -0.4219561200564114
+ -0.3629507087479318
+ -0.7933746066071081
+ -0.839387868910383
+ -0.2714587435270597
+ -0.6183725771998323
+ -0.4406180819036702
+ 0.120792154047767
+ -0.1751175420400254
+ -0.5428664166010159
+ -0.2268962176582445
+ -0.509221779962194
+ -0.8449037912845141
+ -0.6846059682233914
+ -0.3219151493929256
+ -1.034332439008274
+ -0.3900501572073875
+ -0.2413581968510067
+ -0.113597852135392
+ -0.3351205767677078
+ -0.6361979833288497
+ -0.1928292306697757
+ -0.43680298624963
+ -0.1887923567377331
+ -0.8025552691681482
+ -0.8822249286684164
+ -0.5173636867479294
+ -0.5396821401592674
+ -0.3784762859892659
+ -0.8448706219451347
+ -0.5234203882543
+ -0.02523284708004396
+ -0.03004488642002552
+ -0.5911414799190232
+ -0.5198729319281616
+ 0.3793210414752821
+ -0.04253283290772383
+ -0.3466682916964748
+ -0.2922567493223415
+ -0.1092012753827762
+ 0.7215290234431692
+ -0.3998376566347607
+ -0.3785129240010847
+ -0.534849131920757
+ -0.7159466788797467
+ -0.5158517564827039
+ 0.2191034254880796
+ -0.1687253454842232
+ -0.8006633752006649
+ -0.04233864925094758
+ 0.2140476332785622
+ -0.2296165453694349
+ -0.2915847379002629
+ -0.2888886891570239
+ -0.4784622980651279
+ -0.4467145960481185
+ -0.2256072700117347
+ -0.04297332735554762
+ -0.3004901990870193
+ -0.5309290473258421
+ -1.007158475659556
+ -1.111196509017678
+ -0.4529845320173796
+ -0.1409433732378824
+ 0.0222587276785431
+ -0.820032995490547
+ 0.007376701449273282
+ -0.09344757451430596
+ -0.6575287905493787
+ -0.3359023295164944
+ 0.5245680980769555
+ -0.6068177056063478
+ -0.4216118690137018
+ -0.5725608766120418
+ -0.4132240278745631
+ 0.06853942621820504
+ 0.3766986723601243
+ -0.2236264198419682
+ -1.155001748353813
+ 0.3835755738205138
+ -0.07269001608422644
+ -0.2961927238014648
+ -1.011602948583423
+ -0.5476932202465833
+ -0.4673703739609745
+ -0.1149249823172179
+ -0.3212341778145969
+ 0.251035724468793
+ 0.5090317567423607
+ -0.2018856400356364
+ -0.3026056454976902
+ -0.1696618457657907
+ -0.8511035584348059
+ -0.6360251499027173
+ -0.3479035685123237
+ -0.5099340626202971
+ -0.4260193709536283
+ 0.01391765724150718
+ 0.04716688284851223
+ -0.5193920652906535
+ 0.1336592645915052
+ -0.1157910297988457
+ -0.1209061571098737
+ -0.3175436010167856
+ -0.9144348098228305
+ -0.3985852511791289
+ -0.3255970899053792
+ -0.2155615860397035
+ 0.02576505316702601
+ -0.4311139406371869
+ -0.3922836136710843
+ -0.2706420873581653
+ -0.3149541713240933
+ -0.1009102613588649
+ -0.7589114696564203
+ -1.781827984730382
+ -0.3225388769638705
+ -0.6477950476558042
+ -0.1705397346900364
+ -0.4016639554119894
+ -0.9560729763139403
+ -0.1062869424071198
+ -0.3410653174718074
+ -0.6938947223719386
+ -0.2531015973304419
+ 0.5154964732046285
+ -0.4933817747571067
+ -0.103099497056752
+ -0.3720333613045235
+ -0.123252982762294
+ -1.055082572544018
+ -0.1092166843215198
+ -0.2198511401706685
+ -0.4913473463108912
+ 0.1099251875339939
+ -1.123872395689639
+ -0.02938743533917771
+ -0.5059274709014567
+ -0.2227055243212799
+ -0.4690992425341026
+ 0.3639924227658843
+ -0.02027030350821564
+ -0.7309819750094045
+ -0.7262974959532765
+ -0.06390253566339001
+ -0.3340042434091533
+ 0.597777278013657
+ -0.6949221865942922
+ -0.4493798828966502
+ -1.160855418373404
+ -0.7053072891484373
+ -0.699276484447522
+ -0.4376704852886505
+ -0.05167241028317913
+ -0.04077780340070988
+ -0.599338006731406
+ -0.1877316316037821
+ -0.2386115078344901
+ -0.3960026156101754
+ 0.07314693730402491
+ -0.0877385462508644
+ -0.3490784660286306
+ -0.3042342943000372
+ -1.04485869334051
+ -0.2133530210299411
+ -0.3146573130592388
+ -0.3321743102554562
+ 0.6536809804245225
+ 0.3356024170565902
+ -0.1934155285213567
+ -0.9308302814893227
+ -0.03611906779631877
+ -0.9231960135360759
+ -0.5094190712281376
+ -0.2368865955761142
+ -1.039908483654012
+ -0.8350780325527202
+ -0.4063549237358346
+ -0.7216287535653085
+ -0.283549014328219
+ -0.9303673883439546
+ -0.9378338521796289
+ -0.3743380151152271
+ 0.6652621891428373
+ -0.6261809288546966
+ 0.04919270649906123
+ -0.2000238336443852
+ -0.3805201612720025
+ 0.1070814407263242
+ -0.2373341039643005
+ 0.1680623173657377
+ -0.8636506670044971
+ 0.08496989766350729
+ -0.5964578505190108
+ 0.2616961079899485
+ 0.08564325237143779
+ -0.03076282855809052
+ -1.006776302453722
+ -0.4388848296833138
+ -0.02522913690806778
+ -1.237672975105699
+ 0.2268815798631884
+ 0.3284199476696821
+ -0.6537825551034893
+ -0.5222905782590661
+ 0.2957512926294534
+ -0.9733422277481359
+ -0.3595601174139009
+ -1.003688310960785
+ -0.5937017251294097
+ -0.4447872447259192
+ -0.8495306072401683
+ -0.2914004542718777
+ -0.02520211595957169
+ -0.5032552818223736
+ -0.8935797977110612
+ -0.1749640360389038
+ 0.2067588852205771
+ -1.361739084645942
+ 0.01607068850026597
+ -0.5986951376148295
+ -0.006364519784491229
+ -0.418312344602186
+ -0.3255628138534578
+ -0.05822691441876494
+ -0.5470615402964608
+ -0.4674344014256545
+ -0.166972824355683
+ -0.7266288134790206
+ 0.003911148183964989
+ -0.1107724574764601
+ -0.6388237463609426
+ -0.3195108977045384
+ -0.7914273227694385
+ -1.030707884301274
+ -1.347581155474584
+ -0.2335665650734107
+ -0.282266159456554
+ -0.6047644519379601
+ -0.2647827722254275
+ -0.7656455368948109
+ 0.6925461994067584
+ -0.3355196829331084
+ 0.05457413196311294
+ -0.6654809206432205
+ -0.1716090184197709
+ -0.1816043155841315
+ -0.8710697445735216
+ -0.655246440909579
+ -0.1038510359864993
+ -0.5753790585325803
+ -0.388110581745044
+ -0.7701068611951711
+ 0.5265629438784175
+ 0.1877246111858627
+ -0.07274151601928062
+ -0.5412953692036067
+ -0.4119734917352358
+ -0.5366763068137621
+ -0.789734438665066
+ -0.4938557305258537
+ -0.632044272904425
+ -0.05377693088462582
+ 0.3993417959047834
+ -0.2338366100911965
+ -0.4892118216335631
+ -0.4090155269574513
+ -0.7430633627590832
+ -0.8739827201153766
+ -0.6241417643999819
+ -0.3287665353236034
+ -0.9053857928987108
+ -0.5648028405516894
+ -0.3831278412321464
+ -0.2667834069307376
+ -0.4260095140851397
+ -0.5942808972698476
+ 0.06590664074879116
+ -0.399205686951896
+ -0.3525046922510404
+ -0.6482042707020442
+ -0.6884904318529738
+ -0.2322503571731199
+ -0.5186819183156427
+ -0.259992661918489
+ -0.5319560685499135
+ -0.5339174568628724
+ -0.3743326975744048
+ 0.01490145813696582
+ -0.2211962027111431
+ -0.5308552983355076
+ 0.2582853853062619
+ -0.04561453043301034
+ -0.3664513725843536
+ -0.431973756895839
+ 0.2651925127001253
+ 0.3946610267467467
+ -0.4687043765476729
+ -0.4124847689797652
+ -0.7568303916281496
+ -0.8018285259196836
+ -0.826153435156299
+ 0.2906615985251585
+ -0.03724746981708974
+ -0.8016310126139845
+ 0.4818981906977681
+ 0.2721103651715217
+ -0.360637480659132
+ -0.3872973663893723
+ -0.1495220514798854
+ -0.1864243586610831
+ -0.2102292448691494
+ -0.07317014262805463
+ -0.09662769112699954
+ -0.3378718456832781
+ -0.4576579062142558
+ -0.9075882353475503
+ -0.9219014718538876
+ -0.1920685081266685
+ -0.116875762912306
+ 0.2890653171322882
+ -0.4893731464572967
+ 0.03429173363179066
+ -0.09668863893128976
+ -0.7566245638496483
+ -0.2809460853315527
+ 0.516164339665746
+ -0.1102249908103984
+ -0.40935018207511
+ -0.4571520457708725
+ -0.3416521138433671
+ -0.06327507390117715
+ -0.09480691448373813
+ -0.02804242689107814
+ -0.8009299785593715
+ -0.5118264582900479
+ -0.2142006600809974
+ -0.1384804766152002
+ -0.8475682420452058
+ -0.5735110982901541
+ -0.3799754077955094
+ -0.4477211045778108
+ -0.6532779099630316
+ -0.03162730375362215
+ 0.1448841305296973
+ -0.2120341453962263
+ -0.4524362540144146
+ -0.356780235568433
+ -0.5381069203948087
+ -0.3039616033589326
+ -0.2984008579276916
+ -0.4473431779410559
+ -0.6485066001685057
+ 0.4410917197120264
+ -0.1458758574465191
+ -0.3815449557405615
+ 1.667218727796572
+ 0.06210318337388328
+ -0.02218373853791181
+ 0.3143943544532836
+ -0.3695653803667836
+ -0.3176914477891388
+ 0.05118959850659156
+ 0.09008013501068504
+ -0.006350069057788199
+ -0.01232797267804324
+ 0.203935684172132
+ 0.2330687614757996
+ -0.1624114630506737
+ 0.4307269245467064
+ -0.4004737420633673
+ 1.948549556721081
+ 0.3335890928151976
+ -0.04192142481248118
+ 0.2367004576456525
+ -0.1409107966175674
+ -0.3436863316219508
+ 0.3816399232737833
+ 0.007629740452386909
+ -0.05620962790570525
+ -0.009210520727384545
+ 0.04312762633207708
+ -0.1045037202332779
+ -0.7291590733833684
+ 0.275517453291411
+ 0.1064432317573884
+ -0.2697058202994626
+ 0.2235728075947489
+ -0.1292678701953861
+ -0.3588164388952433
+ 0.2089953707997088
+ -0.4268770803072862
+ 0.1658208426565521
+ -0.05874670210612977
+ -0.1252114055277611
+ 0.2118547821865102
+ 0.6627473287282948
+ 0.4459429401917344
+ -0.2771606877337046
+ -0.1775338519619086
+ -0.01473339359956204
+ 0.1495908131907566
+ 0.6746854718412869
+ -0.0901262206339789
+ 0.1370647022270746
+ -0.4456022646206545
+ -0.09722113324201812
+ -0.6545926777777892
+ 0.163677723514819
+ -0.0587339326604285
+ 0.5543693527837558
+ 0.4353403263900784
+ 0.5271708111732047
+ 0.01003765855487058
+ 0.1071942561920385
+ 0.3096140164305524
+ 0.3841871459387871
+ -0.09583582922239864
+ 0.01559603339907481
+ -0.3155942273850432
+ 0.09957052658816262
+ -0.1328321173322763
+ 0.3564622545695095
+ 0.6085146381009029
+ 0.5867399596143027
+ -0.02250972884758025
+ -0.4763015329738412
+ 0.1363186111626235
+ -0.2266561576288394
+ 0.06372520143932857
+ -0.2334396842365647
+ -0.3265031596549025
+ -0.5225730768617836
+ -0.2794768981321148
+ -0.3806046580723788
+ -0.2709384658505899
+ -0.3745368673442807
+ -0.4919386695331785
+ 0.1155843211204948
+ 0.9277339631772524
+ -0.8220383796531052
+ 0.4677961095284494
+ 0.1012249285417283
+ -0.5689958029104534
+ 0.3486579083308017
+ 0.3536085222332953
+ 0.327297536819787
+ -0.3524532775029237
+ 0.2478060497053853
+ -0.167875376600675
+ 0.4683052857569047
+ 0.04845777005968554
+ 0.151462095439388
+ -0.2954444421277257
+ -0.1202327210119957
+ 0.2654746711195042
+ -0.468234794883329
+ 0.3119278052564229
+ 0.6273311313018934
+ 0.2530745559027924
+ -0.06309058374995485
+ 0.4189488387699707
+ -0.4732279941849034
+ 0.2094095552707933
+ -0.4025186655027134
+ -0.1659355510438331
+ -0.3177972199941017
+ -0.2481462321985213
+ 0.006592088157052001
+ 0.268780447633735
+ -0.2073683427305351
+ -0.2106105744749099
+ -0.4509560351939277
+ 0.1834184809985726
+ -0.7661370276962249
+ -0.07903346079921088
+ 0.04676248215594855
+ 0.1237008920290094
+ -0.0126499125481814
+ -0.05835220431205906
+ -0.1588734042816966
+ -0.3299073260347327
+ 0.08167118119376097
+ 0.2478343554039025
+ -0.1452099065062266
+ 0.1326568406926738
+ 0.3491255078998559
+ -0.3934174673339707
+ -0.5960640115453083
+ -0.7910878843462008
+ -0.3020982053926454
+ -0.8838714860757471
+ 0.06568719607260053
+ 0.3369431365777982
+ -0.2198210057155472
+ 0.02881191399440781
+ -0.1501821522283808
+ 0.9675637896490875
+ 0.1967637389689453
+ 0.3815388218291317
+ -0.2548597206712573
+ -0.0560737578407515
+ 0.2869704311115486
+ -0.2854761498665436
+ -0.5950011402363669
+ 0.1513743013486433
+ -0.009470931824429152
+ -0.1739807982033399
+ -0.1466233207008622
+ 0.5357347876397437
+ 0.3074301522098216
+ 0.1270808780145465
+ -0.3704049340693402
+ -0.07042455885511463
+ 0.0405713279179636
+ -0.3815384053212412
+ -0.2997819510430044
+ -0.1114667378498817
+ 0.7258062829153872
+ 0.8700940416597699
+ 0.03826930388024562
+ -0.1790194202449966
+ -0.3616556505927438
+ -0.6152504762514582
+ -0.2677397580547463
+ 0.01079977629521155
+ 0.07883747390706719
+ -0.3624426716699543
+ -0.1527248418632322
+ -0.03702200314495983
+ -0.08732007815655742
+ -0.2271404016758612
+ -0.1883027115152028
+ 0.3416053441977727
+ 0.06418830949057062
+ -0.1998428761163998
+ 0.1306830477324872
+ 0.1391202979596478
+ 0.4529091731012134
+ -0.1446157003666682
+ 0.4358962341170605
+ 0.08644203357368854
+ -0.08867530401801563
+ -0.5120811340035706
+ 0.2381130654095968
+ 0.182322993378588
+ 0.05348965071702647
+ 0.1170819346874089
+ 0.08019216083419001
+ 0.07552243569663072
+ -0.0684438818084938
+ 0.8236200014683633
+ -0.1678402216367604
+ -0.04058297968371218
+ -0.2326005508457137
+ -0.3000381837143903
+ -0.6188481131311174
+ -0.3212977529986542
+ 0.3054848536615199
+ 0.02003101442925876
+ -0.003896575842105588
+ 1.191761661333273
+ 0.3339563486035031
+ -0.2411313538627305
+ -0.1368102385058602
+ 0.2099639721724371
+ 0.3302646100890316
+ 0.279735322187841
+ 0.1572125831554773
+ 0.1621614227576263
+ 0.1361991186281638
+ -0.2350784094731422
+ -0.2718929744151896
+ -0.04033994923534494
+ 0.1344402640829349
+ 0.08336221947186542
+ 0.632881462354837
+ -0.008140666772563247
+ 0.1272758672873934
+ 0.196510462374386
+ -0.298640402793001
+ 0.1041277340782838
+ 0.5678023283084099
+ 0.8473197976328795
+ 0.006957767088195686
+ 0.09493592588800308
+ 0.207316106352868
+ 0.1114048869767513
+ -0.562370393977032
+ 0.4970552468469591
+ -0.1555858172176586
+ 1.338651333090117
+ 0.003053498157229314
+ 0.1928128576865458
+ -0.2186155105026712
+ -0.3556388494918716
+ 0.02312630631403897
+ -0.2670535650055857
+ -0.5414662108847647
+ 0.01424970636943131
+ 0.2005908144610585
+ -0.4205355698145358
+ -0.1858662228644941
+ -0.4665512175475525
+ -0.03506163734660313
+ 0.2307098331622904
+ 0.004312729534306625
+ 0.2707557794007244
+ -0.4447926297528495
+ 0.9127134278553473
+ -0.2995522399174017
+ 0.1735995315903607
+ 0.4425718024777047
+ 0.4639329917160108
+ 0.08637960391492526
+ 1.264868773671721
+ 0.4464640301029854
+ 0.007233381035124405
+ 0.859917942528008
+ 0.8262969742469247
+ 0.04341658666399524
+ 0.8330641227804799
+ 0.909348690733269
+ 0.9999538158809214
+ 0.1665464753088647
+ 0.9694422871445725
+ 0.3922478417557296
+ -1.781448255057624
+ 0.03635886860908773
+ 0.8076620929999465
+ 0.8339334756445123
+ 0.3860128823332295
+ 0.6653047893610314
+ 0.9185296346976854
+ 0.6649787949751917
+ 0.7825902558010049
+ 0.2837037127269504
+ -0.3747990077395175
+ 0.4214443559395317
+ -1.019361892775693
+ 0.9171977008345442
+ 0.4222361559174124
+ 0.88407023912625
+ 0.627550531980175
+ 0.3566140855934134
+ -0.03223197651486596
+ 0.4444754817930365
+ 0.7198529871401895
+ 0.769543155492363
+ 0.4522789066520774
+ 0.1552051873408984
+ 1.087046685118705
+ 0.7110449593763254
+ 0.8551578745013462
+ 0.4445553463014242
+ 0.6336985233194055
+ -8.666585533623437e-05
+ 0.7481389904150876
+ 0.6099165356679989
+ 0.8441275807205756
+ 0.6746478056933407
+ 0.7710196583450366
+ 0.6015009959469434
+ -0.02078264166128433
+ 0.9139622734605635
+ 0.03649114793601069
+ 1.081362510467778
+ 1.294925438224664
+ 1.364399995326488
+ 0.470971101873399
+ 0.7400190105755877
+ 0.5699287605581952
+ 1.004010254105531
+ 0.3370758327320168
+ 0.6131293665130263
+ 1.066506465129122
+ 0.75007755748098
+ 0.2092889950274849
+ 1.188379584369206
+ 0.3927020524332166
+ 0.8976178226409594
+ 0.253591376201034
+ 0.4788474086715514
+ 0.5846703904079941
+ 0.7458621662241995
+ 0.9803193405410499
+ 0.1373088202715007
+ 0.7124319998825741
+ 0.001392091297370719
+ 0.005439118590977577
+ 0.262311652226433
+ -0.1294387395986635
+ 0.4247535343006393
+ 0.4684777559177688
+ 0.7152179782510809
+ 1.122769290452707
+ -0.556571539027084
+ 0.7158780094478909
+ 0.4802045073119096
+ -0.4895153647051178
+ 0.7811319855474181
+ 0.9588152497290688
+ 0.4196819710368834
+ 0.4150388135584117
+ 0.6482857515970342
+ 0.6148584162460666
+ 0.7321927360436169
+ 0.06685955368278976
+ 0.5237996850885736
+ 0.5458979798565589
+ 0.6853456078499774
+ 0.6057305714252021
+ 0.7063432420794981
+ 0.4090613901948583
+ 0.9384325755638672
+ 1.422475224972518
+ 0.7340220696204048
+ 0.3974070122287193
+ 0.4291073097870783
+ 1.005825244363131
+ 0.3983200619644611
+ 0.5215660680357879
+ 0.1392856995086938
+ 0.5911512297254349
+ 0.6914181916293677
+ 0.6381864477415636
+ 0.05556341432556314
+ 0.7827245647227641
+ -0.4785100388053652
+ 0.2664119832167832
+ 0.6996726492098401
+ -0.1791803178514642
+ 0.7268684014643656
+ 0.6467564449413579
+ 0.7068816095330724
+ 0.2160304367590288
+ 0.1248403590807845
+ -0.01822133643607303
+ 0.8960340501583953
+ 0.8322632672202777
+ 0.7877349704122448
+ 0.6127608453581013
+ 0.9125600228691853
+ 0.06050065398089624
+ -0.5814533023644182
+ -0.3861156330785092
+ 0.7708663019767132
+ 0.1414340489287589
+ 0.5450846421816883
+ 1.038949892081503
+ 0.4174288596040157
+ 0.6038789998183522
+ 0.8250064010704237
+ 1.11633891363245
+ 0.6408815696753317
+ 0.9088580805829342
+ 0.7197199404882286
+ 0.1852800172254349
+ 0.7500042345480682
+ 0.6006719336512956
+ -0.1501357023317271
+ 0.394046806730308
+ 0.5674422352507514
+ 0.1304522816363141
+ 0.5481581118181026
+ 0.6648882198575188
+ 0.4502490682344322
+ 0.4188941087144956
+ -0.008164313196871244
+ 0.4794370562070326
+ 0.7040197300011987
+ 0.1877608974045845
+ 0.1910932773547232
+ 0.7258251041884094
+ 1.338647325753172
+ 1.3061328441664
+ 0.6580938987572295
+ 0.3064888139023139
+ -0.1279381299652183
+ -0.1440544070168745
+ 0.6855176548603273
+ 0.8451296607375113
+ 0.6977692058261843
+ 0.3177587836652486
+ 0.6277976642860534
+ 0.6384007278203387
+ 0.1512017510970298
+ 0.1909791050629819
+ 0.3696613702906053
+ 0.5423921235811779
+ 0.8189746404472315
+ 0.1927059080312683
+ 1.122373108673155
+ 1.100572668977905
+ 1.091448881157351
+ 0.3864913664206477
+ 1.29530959251389
+ 0.8166113995733907
+ 0.7601671784301625
+ -0.2943511055448276
+ 0.4917982436421829
+ 0.6232040439503094
+ 0.8468610412307204
+ -0.05076225304297343
+ 0.4823821786251634
+ 0.9086852725808422
+ 0.7046377387435105
+ 1.242050893449605
+ -0.7175982302830722
+ 0.7622778304151561
+ 0.1487060867832971
+ 0.6084926229448413
+ -0.2617814820307586
+ 0.6290740543293295
+ 0.2531324541004852
+ 0.09820565686203631
+ 1.193013779567532
+ 1.494944274248078
+ 0.2742953038453484
+ 0.1402216542798266
+ 0.3435783831149599
+ 0.618862358885921
+ 0.9138941426379912
+ 0.7181690558115195
+ 0.4396937723365966
+ 0.4221474844300872
+ 0.9678478824954682
+ 0.1621521255176283
+ 0.5450861789392766
+ 1.068244577362342
+ 0.489124356812478
+ 0.330030433503413
+ 0.8970494954352911
+ 0.5013533174532329
+ 0.309797772279065
+ 0.6738041032434924
+ 0.6227668595077965
+ 0.5713027065599533
+ 0.684893885478556
+ 1.668225806816082
+ 0.6859151920623758
+ 0.8158011224900357
+ 1.024473169971108
+ 0.5605174526484484
+ -0.7576389300488497
+ 0.9096875215211347
+ 0.6175767372236864
+ -0.4161537577909997
+ 0.5088495346896563
+ 0.5476722851792211
+ 0.6339601342061658
+ -0.006306045422751316
+ 0.5799397740036482
+ 0.4713993384867219
+ -0.083403128637816
+ 0.4313779446126474
+ 0.6510757062085264
+ -0.3388413420791607
+ 0.2626113689451582
+ -0.3569649977516132
+ 0.50820676068601
+ 0.8229394466911507
+ 0.4958243200831756
+ 1.234369408535352
+ 0.09407623276619048
+ 0.16842663485555
+ 0.2002091519936368
+ -0.07338891003129742
+ 0.03331177114379679
+ 0.06963817063415607
+ -0.05666121342626853
+ 0.08655782188589418
+ -0.01629413987509927
+ -0.0332371260118988
+ -0.02941861722641498
+ 0.01738958082197578
+ 0.1508821012348263
+ -0.051592030018763
+ 0.2067810222519689
+ 0.05302820677562026
+ 0.01475648246371792
+ 0.03010009527862536
+ -0.1648663516653107
+ 0.0986444033843535
+ 0.02027653632157885
+ -0.05078959067312729
+ 0.04004260342727669
+ -0.2910429917514142
+ 0.009850227406214163
+ 0.1586227363125275
+ -0.08533163081359228
+ 0.1673847065407495
+ -0.0917935042165738
+ 0.1496801847004745
+ 0.05771147395976754
+ 0.0631735402019261
+ 0.02467558167012938
+ 0.1587463118517278
+ -0.03870559009042487
+ 0.05765655119519951
+ -0.05502951990483894
+ -0.3012790946012868
+ -0.1039280495160258
+ 0.1063983049323238
+ 0.1299338848245758
+ -0.003281233343411412
+ -0.06988172596811287
+ 0.02815284661452942
+ 0.0654020521108339
+ 0.226333928109976
+ -0.8343562552992259
+ -0.0002100803877835796
+ 0.02684384062962547
+ -0.1219953203155064
+ 0.06685253359104405
+ 0.1429352102978557
+ -0.005442904517195468
+ -0.09786802994119191
+ 0.1052384838435717
+ -0.03206215886241107
+ 0.2012229204149918
+ 0.07186077200532717
+ -0.05932874527873284
+ -0.04265924879392123
+ -0.005029992987120322
+ 0.1776225785436245
+ 0.03883419764649802
+ 0.08355110602415086
+ 0.05911197404941929
+ 0.02744318552902593
+ 0.03314821072530822
+ -0.1156332194681546
+ -0.07758888949702572
+ -0.1623300604236726
+ 0.0005639166436980795
+ -0.09556544175099256
+ 0.194410794896442
+ 0.1358244714355086
+ -0.01425257479015681
+ 0.09425253927267592
+ -0.07385767853002158
+ -0.3628988036168848
+ -0.2146645370879713
+ -0.0401558831442899
+ 0.2023585303653781
+ -0.09606575710809313
+ 0.04378813468096158
+ -0.02788479011315963
+ 0.3519728163930858
+ -0.0001313508494149237
+ 0.008423859760551206
+ -0.268183675166824
+ 0.2300554358278003
+ 0.001880330496123822
+ -0.1476457270882015
+ 0.01403761966618388
+ -0.0630537502894067
+ -0.2041918066761578
+ -0.04062467047844028
+ -0.1682476818663452
+ -0.1031124765729317
+ 0.02918936363321958
+ 0.05452945343404456
+ -0.1460370674413418
+ 0.01368646691490838
+ -0.1899527644748964
+ -0.01702910558237531
+ -0.1713812863587018
+ 0.07653604731612897
+ -0.06494812002629886
+ 0.01790638988306824
+ -0.163161299634012
+ 0.4186091936942767
+ 0.03277851788802352
+ -0.2322537030083748
+ 0.1982227211646411
+ -0.2272728848992447
+ -0.03318808364409243
+ 0.297722163180038
+ 0.1312673666716315
+ 0.02707837278671361
+ -0.1045740404142386
+ 0.06787272474274135
+ -0.0177580833569292
+ -0.05490839383191812
+ 0.1308294886719442
+ -0.2207755143605773
+ -0.1089692820110456
+ 0.04825438989315921
+ 0.09779390536555653
+ -0.159821320130119
+ -0.1159093358272197
+ 0.05504310471972555
+ -0.04369590214089984
+ 0.07073691346077766
+ -0.2665016984645774
+ 0.02388628555373233
+ -0.1331219373728809
+ -0.1315555893633195
+ -0.06908019445383771
+ 0.2312935793190567
+ -0.08531872120563737
+ 0.02223642415897086
+ 0.001315907955975409
+ -0.003219648225799025
+ 0.1870041029706274
+ 0.1245742096237773
+ 0.007212315883091193
+ 0.2933352247807992
+ -0.1566204420992092
+ -0.08010624272851696
+ 0.1786967634108413
+ -0.1574906964543311
+ 0.1441132851146465
+ -0.06408174708644622
+ 0.0717139431529894
+ 0.03420951895790216
+ 0.1331460517005429
+ 0.04490175496779899
+ -0.1682940088864579
+ -0.1606290462842259
+ -0.1095605690760876
+ 0.0703893083785119
+ 0.1301886675064558
+ -0.06285998139635339
+ 0.1072014485263314
+ 0.1864957025207911
+ 0.1656476217731681
+ -0.03771128064524416
+ 0.05275133711277115
+ -0.05914498255328498
+ -0.2412207759451671
+ -0.04341537955952204
+ 0.09853843308378572
+ 0.08483301958683054
+ -0.02168065306972378
+ -0.05806995455294194
+ -0.1079272844064938
+ -0.1402367825155833
+ -0.2052195370357991
+ -0.1461590008469454
+ 0.1674809774632851
+ -0.1171866023103899
+ 0.1770773086824776
+ 0.02092695476785725
+ -0.09157510795679843
+ 0.08314239556065293
+ -0.01217193864140235
+ 0.01153770504490583
+ 0.3140648343578761
+ 0.2396795677341494
+ 0.2249844623340858
+ -0.244831129540522
+ 0.1053719321222459
+ 0.09361168043526424
+ -0.02266110585285825
+ -0.06167914271045204
+ -0.03705363258744244
+ -0.005263490772896322
+ -0.09384491064174344
+ 0.03946683821921681
+ 0.01845952648647741
+ 0.06066962117487223
+ -0.02945166347639823
+ -0.004223972154107899
+ -0.1428458864404036
+ -0.08579148420848684
+ -0.3255186696508054
+ 0.04540112842836656
+ -0.05576060017284517
+ -0.01384273119247929
+ -0.07305402602545237
+ -0.100654644786767
+ 0.005329844548711019
+ 0.02934153184211075
+ -0.06984474286547115
+ -0.04122717181903108
+ 0.03290419475050719
+ -0.4133569367044335
+ 0.06775182474313729
+ 0.1772140735162707
+ 0.003248483255291397
+ 0.04296208909131485
+ 0.3431333654275189
+ -0.03871745538008486
+ 0.1766783407641636
+ 0.0460523110090707
+ -0.07520341094887323
+ 0.08284553027863532
+ 0.1740913079788215
+ 0.01809985546751373
+ -0.1094076772147493
+ -0.03925931024129927
+ 0.1017545885000872
+ 0.09301126508547274
+ 0.01796674827291573
+ -0.08422663634004003
+ 0.1314579050325454
+ 0.009934515128281765
+ 0.04736214721307783
+ 0.1611831029076925
+ 0.07469134378121381
+ -0.008688620866355658
+ 0.04282709599317566
+ 0.1323820885508907
+ -0.1107229385527645
+ -0.1133368256790011
+ -0.0459486059883938
+ 0.1114174586694786
+ 0.26349350716653
+ 0.09818252537678392
+ 0.03504037872886116
+ -0.1162312971726918
+ -0.1591063880725286
+ 0.1555748484065873
+ -0.154247216803497
+ 0.0490591323247089
+ 0.0929430548766054
+ 0.1178215250516526
+ -0.1134350274363533
+ 0.07244243910134429
+ 0.03998721194228382
+ 0.1052494456143171
+ -0.04262946624192485
+ -0.08725504193066186
+ 0.06265232603509548
+ -0.1557092102388964
+ 0.1753979955966792
+ -0.06733339913948581
+ 0.08715931476376157
+ 0.02948267836490326
+ -0.008909144763984772
+ 0.1563359655905267
+ -0.05026344163091333
+ -0.3099416532081774
+ -0.02252695372927473
+ -0.05322128241114864
+ -0.2313971425581751
+ -0.1376543196677307
+ -0.08065248195315032
+ -0.0335594557425421
+ -0.1087889341658553
+ 0.1941952195731843
+ 0.27335991085888
+ 0.03174973422505341
+ 0.1087183032023318
+ -0.07277191334214393
+ 0.1455907995382223
+ -0.2001838849645602
+ 0.03320370387695018
+ -0.06197912233764708
+ 0.01410195340752804
+ 0.01372864142911234
+ 0.07664842345475986
+ 0.03233615007575832
+ 0.04381621891927816
+ -0.09361364408696254
+ 0.006565063126730873
+ -0.02813253533513596
+ -0.002449654378479011
+ 0.2924301339635104
+ 0.1279139857807472
+ -0.1502568345185902
+ -0.07645015982645979
+ 0.09421012372930569
+ 0.3553212819567743
+ 0.2494348310081459
+ 0.0275948225891571
+ -0.1435876140693143
+ -0.05424799028852052
+ 0.2409457651046875
+ -0.1426719295706738
+ 0.1154469398619241
+ -0.05369085059805818
+ 0.01897320528268845
+ 0.01275747864292193
+ 0.003689019913332679
+ 0.02827455430048977
+ -0.07984699455104921
+ -0.06797394061366296
+ 0.1212564950450237
+ -0.1960618137453715
+ -0.09683425857490388
+ 0.1625091151723048
+ 0.05735260304386951
+ 0.0649558780618292
+ 0.05393729792221152
+ 0.05771647975747233
+ 0.112328277324155
+ 0.2010842151124908
+ 0.1299469560205206
+ 0.04705999169372613
+ -0.07344074375644771
+ 0.1731101441377517
+ -0.08521136720832667
+ 0.03103926449628581
+ -0.2369087256316569
+ -0.4057361910769023
+ -0.1802663568471768
+ -0.06830016428428791
+ 0.02065208732647386
+ 0.1304358199585746
+ 0.009291199244945198
+ 0.03131300120451403
+ 0.2614638361003256
+ 0.05726215855315517
+ 0.1008871314671699
+ 0.0776934461461917
+ 0.2411573591019756
+ -0.108961076734261
+ -0.03143384627224154
+ -0.08869558332854235
+ -0.02620386274025086
+ -0.1944154308886958
+ -0.1464571280866085
+ -0.08211537452518618
+ -0.04525100538866837
+ -0.01480706021524014
+ -0.02622405533125793
+ -0.03222492058576161
+ 0.05531493263417533
+ -0.09536230584591553
+ -0.2657933462823083
+ 0.003511554192852637
+ 0.1040045950633752
+ -0.0643319807725756
+ -0.02456055406858055
+ -0.1527368084273734
+ 0.2039156838377204
+ -0.04614595459571332
+ 0.1383953210780827
+ 0.15335789427913
+ -0.09469437658861783
+ -0.06939368529485657
+ 0.02259770448006768
+ 0.09063562523011133
+ -0.03506968044716959
+ 0.004689551738990857
+ 0.0701692225806361
+ 0.1524524551345627
+ -0.00887168264725475
+ 0.0612795715519656
+ -0.1880743639803473
+ -0.03419202920347694
+ -0.2205024044827757
+ 0.04316044181250382
+ -0.1860162859585104
+ -0.2952115152104636
+ -0.08086769540225973
+ 0.1271400705169667
+ 0.09997258260052364
+ -0.1484255014522047
+ -0.06001497231748486
+ -0.2055772052697093
+ -0.06461080274518102
+ -0.1154168540652843
+ 0.2450778606519572
+ -0.09774093966489961
+ 0.03361481812357046
+ 0.1274484861655066
+ 0.04658229224015976
+ 0.1682097468429917
+ 0.136374068518749
+ -0.06650469470777762
+ 0.1454777819236287
+ -0.0157773352449335
+ -0.09863551419750645
+ 0.4622932525711828
+ 0.04710157842102276
+ -0.03443272187990695
+ -0.2832439423713189
+ 0.1638567961588143
+ 0.09442389295231869
+ -0.007576265363466159
+ -0.2879655869659259
+ -0.0743581323142373
+ -0.05042343051430474
+ -0.1172837493064219
+ -0.02559801558175114
+ -0.07067220311485925
+ 0.1125519225973421
+ 0.07585188970971808
+ 0.2420419973543043
+ 0.179652579607638
+ -0.1280025305739423
+ 0.06818308740058765
+ 0.07556006179131504
+ -0.1940808202141242
+ 0.04345232351334239
+ 0.112443249129403
+ 0.0989908603263522
+ 0.02088908872875778
+ 0.05790370714827859
+ -0.01796710156257132
+ -0.2792180665172357
+ -0.210693400008256
+ 0.111017788230398
+ -0.0298717163527407
+ 0.003758143044481368
+ 0.03771808997590925
+ -0.07308416037773038
+ 0.07385573875491853
+ 0.2317103066600028
+ 0.04775874399765781
+ 0.0008162012429432146
+ 0.1167119728324198
+ 0.2494491214796501
+ 0.03502285208264171
+ -0.1993792192288653
+ -0.02992864390518694
+ -0.03988931355877789
+ -0.04845462260168403
+ -0.08525205846589816
+ 0.06458784740877944
+ -0.1457621300482446
+ 0.2372288490763193
+ 0.2315088860789077
+ -0.02906439075567777
+ 0.09043893831471891
+ 0.06806004901408956
+ 0.1773685381359586
+ -0.1002895339525629
+ -0.1030474940028186
+ -0.06685135721556766
+ -0.009494480748024404
+ -0.08233077107660457
+ -0.06795900382431448
+ 0.01984187301448656
+ 0.1879683707803882
+ -0.03264058325964003
+ -0.1029122265241363
+ -0.02568932697075629
+ -0.2521045791709349
+ 0.04317657967759692
+ -0.05645267796085152
+ 0.2238174134328292
+ 0.1057869088465305
+ -0.1028237655007978
+ 0.04697808684187352
+ -0.02692511781227247
+ 0.07514191727511906
+ -0.0325372214288146
+ -0.114105831706632
+ -0.1332982644144468
+ 0.143888682494877
+ 0.1923741971777899
+ -0.009441879578553006
+ -0.05305916645584323
+ 0.3655496397624907
+ -0.1047726696649691
+ 0.09839744252839218
+ 0.146262029875463
+ 0.04783809674776492
+ -0.05961764261014981
+ -0.2303543547302474
+ 0.1239376438255468
+ 0.0902998117749161
+ 0.1882512706033346
+ -0.06098355383884435
+ 0.03492676899891604
+ -0.1279398887896151
+ 0.07494299689706893
+ -0.06867091735070924
+ -0.1011853585030417
+ 0.002110145973569824
+ 0.1122651892907851
+ 0.2245176403570509
+ -0.06151859448723768
+ -0.1905807695250177
+ -0.1042842346187136
+ -0.06993332850885071
+ 0.04984860043000781
+ 0.04047400265423855
+ -0.01068933422058112
+ 0.04823808865646682
+ -0.1243800732412288
+ 0.2316511829482659
+ -0.008037639587616455
+ -0.1778516712913076
+ -0.2052946682411498
+ -0.1687083974501712
+ 0.03459655001895804
+ -0.006630064203240225
+ 0.1006584019709
+ -0.04244122159478375
+ 0.08159497935877594
+ -0.01266493479379308
+ -0.0288792121905993
+ 0.1682379198614404
+ 0.008728001158971396
+ -0.1555792526281528
+ 0.1635304848911861
+ 0.01630985404599713
+ -0.05296878016437333
+ -0.01537197781945606
+ -0.1207389398644774
+ 0.09168035008466739
+ 0.2925462203322529
+ -0.1598920960179509
+ 0.1746087338012031
+ -0.04144942997718663
+ 0.02055106366848109
+ -0.04187894692093149
+ -0.1177700554574433
+ -0.067864386769004
+ 0.04982664374529477
+ -0.03477383810396281
+ -0.1026457900365856
+ 0.02389394304207002
+ 0.1574495591570526
+ 0.09739512718297694
+ 0.1106261083233014
+ 0.00801404846251458
+ 0.1613322442360942
+ 0.08616735645223149
+ 0.1859789764165273
+ 0.2474742546739467
+ 0.06291682520729272
+ -0.2030437971549434
+ -0.05382540471511167
+ -0.03812255457064273
+ -0.02457863077762059
+ 0.1781307308649321
+ -0.01237139654450955
+ -0.00114844506680325
+ -0.1298759640158143
+ 0.05817115711263673
+ -0.3530874584580207
+ 0.1136046931567839
+ 0.03309808390053976
+ 0.08131867939377826
+ 0.1831587802279089
+ -0.2034076083246985
+ 0.04731554699004937
+ -0.02775319654121298
+ -0.1410403927210198
+ 0.06762738875729439
+ -0.1061971942924593
+ -0.05350723567508586
+ 0.07649038651118326
+ 0.08921996521851855
+ 0.04791840793953057
+ 0.2480402245018685
+ 0.06247923214066559
+ 0.1280832419886825
+ 0.1330282338987272
+ 0.06854235337126194
+ -0.03975494973853664
+ 0.02402641448972406
+ 0.145413219878447
+ -0.00350099405653656
+ -0.09810997341003236
+ -0.1500518919795678
+ -0.275020134408748
+ -0.07505396684635902
+ -0.1457041606386233
+ -0.3393187166056383
+ 0.1331571973328037
+ -0.110283055446299
+ -0.02562766355709294
+ -0.0558913701239514
+ -0.0540756304549689
+ 0.02139833868657917
+ 0.2205169077130332
+ -0.04415656578896279
+ -0.1615604785746199
+ 0.03657934722427986
+ -0.09425250958089726
+ -0.02845521308420071
+ -0.08266720616518415
+ -0.2489411019473962
+ 0.01551150807894458
+ -0.1277766426254786
+ -0.1691337461890193
+ -0.09273232958486907
+ 0.0845434590416053
+ -0.0817751520007895
+ 0.04361955426464188
+ -0.262435290409621
+ 0.1442086180490096
+ 0.07815467566285009
+ -0.2562333574160348
+ -0.2275846595756743
+ 0.1486191045161695
+ 0.2855672884338436
+ -0.1398290720386017
+ 0.1731883617890136
+ 0.009957407779010814
+ -0.09448514311850834
+ -0.1593999127820855
+ -0.03854423723202845
+ 0.2118057062761691
+ 0.01930063332334164
+ 0.1506572182847392
+ 0.2308755807189392
+ 0.1442402790078226
+ 0.0530624584100496
+ 0.04252502304683763
+ -0.1317695271211297
+ -0.05924126515106762
+ -0.1097744994715752
+ 0.004630728843213914
+ -0.106197543538807
+ -0.0998591148670562
+ -0.1604477184855824
+ 0.2646560396434452
+ 0.1480768751094904
+ -0.05162166226015313
+ 0.02309799163797649
+ -0.2814022399810224
+ -0.02969994659345677
+ -0.1395323233630525
+ -0.268298986889466
+ 0.4146699577137405
+ 0.1014612430879724
+ 0.1821610284707323
+ -0.03092092842970402
+ 0.07234289713535821
+ -0.01041232905007928
+ -0.1474829460290751
+ 0.03362189986808967
+ 0.03201243006072946
+ -0.06957364486403016
+ 0.0899445395012064
+ 0.1935554792783035
+ -0.1199422743478855
+ -0.06353686911752858
+ 0.1364805514280732
+ 0.05643413420523858
+ 0.03690107874732951
+ -0.3773551167868887
+ 0.05649944329596363
+ -0.07684561102210888
+ 0.04350290182599659
+ -0.07919882384150727
+ -0.2039564331696269
+ 0.05629593168269784
+ -0.0298110525392648
+ 0.1717338301460992
+ -0.01785708941003036
+ -0.2024444721638224
+ -0.07202577012263808
+ 0.07234709133240455
+ 0.06584590085102029
+ -0.1078776389011856
+ 0.1029176823718753
+ 0.06760606622634731
+ 0.05016141636702857
+ -0.00339974708292407
+ -0.03646702814256569
+ -0.04890538611847352
+ -0.009125287635034774
+ 0.05146855159228438
+ -0.1333717654033707
+ 0.08210873107533997
+ 0.29076471220691
+ -0.2153016200718147
+ -0.0584331067687738
+ 0.1027377358039736
+ 0.05707947341335337
+ 0.1667090660184277
+ 0.1976291448841175
+ 0.02705729925436348
+ 0.01796950700497731
+ 0.06239382005319734
+ -0.05082587991023677
+ 0.09761408457778654
+ -0.08940644377316814
+ -0.06202291503023948
+ -0.07776493497605269
+ -0.1336187903269319
+ -0.3230132731727937
+ 0.2026037072666919
+ 0.06478741284224945
+ -0.007670666588370619
+ 0.02412129735770062
+ 0.1549891824772819
+ -0.02400206066288015
+ -0.02870356578221772
+ 0.2000413014906103
+ 0.08609323070443986
+ -0.1638678325480539
+ 0.01214314996945172
+ 0.07249614106737805
+ 0.1439697415499205
+ -0.01725091313445289
+ -0.1469376673305392
+ 0.02595477068778226
+ 0.0656249719102938
+ 0.08198805995748196
+ 0.134772323868445
+ 0.01101929296878628
+ 0.002542188397544281
+ -0.08349254207437565
+ 0.1639297528158151
+ -0.3768610749072907
+ 0.1193802020527624
+ -0.7697569130806157
+ -0.2212924141519562
+ -0.1681963510971431
+ -0.3145464746558496
+ 0.06697730222334126
+ -0.03112173839743644
+ 0.02307491489955696
+ 0.1779478861056873
+ -0.1247043537880247
+ 0.1007967404580479
+ 0.2357077424255827
+ 0.06232940371195738
+ -0.2778913971415855
+ -0.2392497454953789
+ 0.08819940141049225
+ 0.03000924825976448
+ 0.332884041643997
+ -0.1303595676940465
+ 0.03196268480698171
+ -0.1167470328550719
+ 0.1892232447370581
+ -0.09112310014241388
+ 0.1042936618050788
+ -0.2723908567928376
+ -0.007807977398082571
+ 0.2543584458207669
+ 0.04754557711456058
+ -0.02702586450417269
+ -0.11247871762982
+ -0.09908603805634476
+ 0.1788009668591205
+ -0.1479500846715779
+ -0.1273106699193646
+ 0.01493238263591523
+ 0.006088374554609633
+ 0.20848851010708
+ 0.02960787768672649
+ -0.1871474654099734
+ -0.09261442327916931
+ 0.112615633171938
+ -0.0477977622372065
+ -0.06855526883756495
+ 0.09516219703305855
+ -0.03771138000669634
+ 0.06536359649796689
+ -0.213911711083961
+ -0.0184447990250914
+ -0.1661792336858582
+ 0.02508859994982515
+ 0.1692517069104558
+ 0.2603517069755765
+ -0.1611989560822039
+ -0.1185667809432909
+ 0.08500005984630972
+ -0.1794990547496751
+ 0.1082623427790162
+ 0.2439491750351128
+ 0.1222696381705514
+ 0.1972043484281278
+ -0.1028242609241676
+ -0.01791131640789705
+ 0.09985342344774374
+ -0.2370203511062225
+ 0.1084863755220742
+ 0.1243641419869446
+ 0.004428783435230674
+ 0.1166853829263854
+ 0.0006417599748490489
+ 0.07671629582011849
+ 0.3423576057170364
+ -0.1286038917737745
+ 0.01098050492101829
+ 0.1378661619571264
+ 0.03998660684459197
+ -0.01005031263122967
+ 0.1086828262986002
+ -0.01727507920194267
+ -0.06986219185448164
+ -0.01427371425125049
+ 0.0885045711825615
+ 0.009883819379971704
+ 0.1894430080463225
+ 0.03484655823368423
+ 0.214884581387276
+ -0.07130934093027447
+ -0.04340437887562161
+ -0.2022571389717478
+ -0.02501150279020167
+ -0.01278745513540494
+ 0.06716704213823628
+ 0.1851014372250321
+ -0.194051534415858
+ 0.1788158973775606
+ 0.03188963064137908
+ -0.08253812956052718
+ -0.06170568993328969
+ -0.05737790184588787
+ 0.03885178012826314
+ -0.01354704450405351
+ -0.05551526757755507
+ 0.0007761519328859751
+ 0.2757262930258098
+ 0.1703222680758462
+ 0.03583533982022052
+ -0.1184735909773455
+ -0.2484053745821439
+ -0.08398857949189971
+ 0.1018498084782536
+ 0.06636905895411564
+ 0.1124592143743815
+ -0.1347358818391486
+ 0.1518183767349677
+ -0.03562442174682971
+ 0.08418917643700233
+ -0.02920869049669517
+ -0.1745529973124222
+ 0.1037633610308533
+ -0.06235644863091044
+ -0.01196390537163998
+ 0.2731464249223822
+ -0.03804965905807817
+ -0.06399023174599729
+ 0.03547330035402781
+ -0.01804496861815282
+ -0.1024977563933929
+ -0.04501010768300148
+ -0.04910453547920961
+ -0.01728294054364678
+ 0.1572386315096017
+ -0.06734885497082059
+ 0.1443934100694797
+ -0.1436615543943069
+ -0.09466828377217448
+ -0.004330153042636131
+ 0.1913010148017029
+ -0.1368754415116969
+ -0.00208609509175319
+ -0.1312275937571549
+ 0.07444739943629684
+ -0.2329053404501217
+ -0.2353707836953204
+ -0.4670382295590909
+ 0.1676718329911781
+ 0.1256197734101599
+ -0.1527130733158328
+ 0.1394342797512396
+ 0.005729875436846226
+ 0.007173844000127672
+ -0.03541315470374997
+ 0.147206034049565
+ 0.272633085022892
+ 0.01253635783119945
+ 0.08281616319501042
+ 0.117315213179572
+ 0.106769320571199
+ 0.07978772367351653
+ -0.05038937449415107
+ 0.0364650804498464
+ -0.03399044141345221
+ 0.008989999415654336
+ -0.06135875114513663
+ 0.03701824757004867
+ 0.08834510093795316
+ -0.1278252370645362
+ 0.1574450128407891
+ 0.1655971666411339
+ 0.01154446735174964
+ 0.02891216529006158
+ -0.1510320590519443
+ 0.05204112594114344
+ -0.07593744680166088
+ -0.4138633883342974
+ 0.2971610789853015
+ 0.1032389457227845
+ 0.042722708165842
+ -0.07398693402250441
+ 0.04680673326062725
+ -0.1550704335285432
+ -0.02835355382795042
+ 0.001013562389351253
+ -0.03415613998520712
+ 0.1035506496875199
+ 0.009702094458653499
+ -0.03053279813549682
+ 0.01911176807061997
+ 0.2017057983970884
+ 0.1156356413096757
+ -0.1595455041757185
+ 0.09890136233921518
+ -0.1778554275110646
+ -0.001807292015045894
+ -0.1906967933769538
+ -0.07257211703374573
+ -0.06248519921819782
+ -0.01249856873485695
+ 0.09398110471902847
+ -0.02160325627512833
+ 0.1245407646495057
+ -0.05232644551298546
+ -0.1790765773523827
+ -0.01897172327316724
+ -0.01962115402213288
+ 0.2119706354113583
+ -0.151308906841208
+ 0.03418825523820215
+ 0.1537911475109066
+ -0.03595210444858842
+ -0.08491740445548025
+ 0.0327406120855941
+ 0.1256431957379078
+ 0.08999861349306743
+ 0.08760907484101546
+ -0.1039145574117216
+ 0.06398995044988803
+ 0.4298587134553199
+ -0.06102954219851842
+ -0.1014616362107472
+ 0.07713828412731696
+ -0.1444581254181776
+ 0.2307687752129999
+ 0.2334921997037168
+ -0.05998435740010866
+ 0.07889161262700368
+ 0.003578566114233683
+ 0.06149617990064773
+ 0.1811831206069739
+ 0.08757078068453107
+ 0.03400379089270179
+ -0.131330229422718
+ -0.1777631994598496
+ -0.3290570890762421
+ -0.02835966373002344
+ 0.03524444326120029
+ -0.1080349870804105
+ -0.01195764247083099
+ 0.04683810773614416
+ -0.02230029202487139
+ 0.1169618632296458
+ -0.08851404824049508
+ 0.04255511064689352
+ -0.1562474583322839
+ -0.08122905722240509
+ -0.1704179301914067
+ 0.08537830096966534
+ -0.009797310754328685
+ 0.1414731548451054
+ 0.04627016369924405
+ 0.1377370974472886
+ 0.2636392257951558
+ -0.2817031995233829
+ 0.09831748910435606
+ -0.06839020807394663
+ 0.1280549372926579
+ 0.148760866245911
+ 0.01898582240542632
+ 0.0933142153584746
+ -0.05057622296644462
+ -0.2832701052078901
+ -0.1028754888172324
+ 0.1403578542345698
+ -0.1833699674137213
+ 0.02141267876055514
+ -0.2998055512704632
+ -0.06539238256887613
+ 0.02530649266748932
+ 0.06850147636661247
+ -0.001889913437682705
+ -0.05283586200400071
+ 0.008108253139624917
+ 0.08240507879696403
+ 0.04560331658201312
+ -0.0699857999776398
+ 0.1086942793177416
+ -0.04494937655217514
+ 0.009100631658522327
+ -0.07290206367182554
+ 0.1438805512608022
+ -0.04704044584113247
+ -0.1711495592485757
+ -0.1122872098904535
+ 0.01936821183861987
+ 0.06438997344154014
+ 0.04255883302612039
+ 0.00973666537978766
+ 0.04875120868678354
+ 0.01188379936070664
+ 0.1177921661224317
+ 0.1475238640848043
+ -0.1295175158050947
+ -0.06133022169748133
+ 0.2547427913807691
+ 0.05325537204173097
+ 0.05816878790942419
+ 0.07433569920857755
+ 0.140841277859727
+ 0.08534630320085594
+ -0.03993419415585034
+ 0.07343852091749987
+ 0.1447256254233307
+ -0.05922094075484226
+ 0.06351622340299432
+ -0.2623012473648039
+ 0.03452007042708084
+ -0.1016908036134709
+ -0.001857342774820718
+ 0.08004858115146685
+ 0.2262818666995441
+ -0.06603100555720481
+ -0.2053596158294931
+ 0.05147830504666341
+ -0.1911422727890306
+ -0.09706700280155754
+ 0.05689820173409721
+ 0.4055416755968649
+ -0.06045015747968319
+ -0.07215582679990599
+ 0.09047104314226406
+ 0.08792909000318049
+ -0.1384239188079479
+ -0.07526870151890001
+ 0.05430573940157028
+ -0.03061862974998544
+ 0.1920483112105993
+ 0.01361571257424987
+ -0.2022986330679549
+ 0.08576621131137273
+ -0.1006769503700991
+ -0.04829909267755558
+ 0.07445329021491819
+ -0.05785914769218926
+ -0.000288026838702963
+ -0.06039200903907745
+ 0.04740370916698566
+ -0.09210572312764646
+ -0.008982897615944547
+ 0.2089714371613931
+ 0.003802995174447648
+ 0.1282832576030806
+ 0.07085126629284354
+ 0.2575779573336598
+ -0.003245695368985666
+ -0.04645043743831927
+ -0.03592711768097116
+ -0.01501835018022073
+ 0.01222520233100322
+ 0.05324069261113746
+ -0.007630051770320241
+ -0.06519217637440303
+ 0.2772122564727599
+ 0.05421092793840426
+ -0.1795493423378846
+ -0.1043030228048571
+ -0.2096157493654643
+ 0.03161970429654114
+ -0.162957657579994
+ -0.2029210829360478
+ -0.07873777224210178
+ 0.01549336902258435
+ 0.1195119318163313
+ 0.1628895010184224
+ -0.2331677475272382
+ -0.1179024507595966
+ -0.06601264399183283
+ 0.01218647724486012
+ 0.1246464607113467
+ 0.04651012132072902
+ -0.09122572593482157
+ 0.1304489894385491
+ 0.02460312741297827
+ 0.1498139448125036
+ 0.1294024976467686
+ 0.002203916297196569
+ 0.01400735487612577
+ -0.06904451846888261
+ 0.02244753505164843
+ -0.1572124025941077
+ 0.1379598358264871
+ -0.07694981373413404
+ 0.001838132802904508
+ 0.03666987814968007
+ -0.0410467125186896
+ 0.06264110288488313
+ 0.04978779246132818
+ 0.2266903342914401
+ 0.1355720700670011
+ 0.01580792019937535
+ 0.3992858367294341
+ -0.01517818093267168
+ -0.05642782056978031
+ 0.04389038142601238
+ 0.2769661938885635
+ -0.2094644741193975
+ -0.01666146892767501
+ -0.05902280139308708
+ -0.03686782691408207
+ -0.1997312222186776
+ -0.09509481309887594
+ -0.1845015267858572
+ 0.06017821034235248
+ 0.0803345684071237
+ -0.2231198267850516
+ 0.1196152587195683
+ 0.0006534887741532187
+ 0.0693280567312691
+ -0.0999848616946544
+ 0.04983856620229732
+ 0.1166291413501656
+ 0.01231080972420872
+ -0.1553107478114333
+ 0.05633787454245718
+ 0.0131816237445624
+ 0.1469588545322484
+ 0.004650806424363286
+ 0.08171864806490213
+ 0.007667240734114789
+ -0.2769519987192213
+ -0.07068737420795315
+ -0.01335151611115145
+ 0.07934103151738113
+ -0.05277150963284991
+ -0.2204514564377206
+ 0.06770385071557219
+ 0.01349377337296595
+ 0.06724870882152342
+ -0.07321971693821221
+ 0.0689815566096212
+ -0.06556822853459073
+ -0.3405769780780462
+ -0.2079202715642693
+ 0.06874620651005929
+ 0.1014448664188468
+ -0.0899575247326684
+ -0.008633996238676197
+ -0.1318760825377482
+ 0.0537456516068722
+ 0.04143429301499196
+ 0.05769910880675788
+ -0.02517423883738
+ -0.0243614922091839
+ -0.09878680065472323
+ -0.1673317736328157
+ 0.06266832909058168
+ 0.1621691492551542
+ -0.1143393628213833
+ -0.05096783041597443
+ -0.0329197429046467
+ -0.0235137527585709
+ -0.152886255965112
+ 0.05093560464103159
+ 0.0413186428856004
+ -0.1118916283589024
+ -0.1973663614814243
+ -0.04348765532040831
+ 0.06031361729075244
+ -0.05149962671389304
+ -0.1186287422520261
+ 0.07882155850965274
+ 0.05028301695623184
+ 0.1805170097025446
+ -0.03834334654557187
+ 0.008261548203595932
+ 0.1198297017706722
+ -0.1208120540244246
+ -0.06950348113101155
+ 0.1907045386237932
+ 0.08165601937573704
+ -0.01614123998677435
+ 0.117706334185299
+ -0.1244341417566289
+ 0.03239572909980223
+ 0.2268711577146954
+ 0.03526082219974716
+ -0.05546513529591963
+ 0.05958464319749743
+ -0.1265909351671086
+ 0.09675752816798573
+ -0.1207550094341743
+ 0.09779956939124441
+ 0.08801758535309609
+ 0.01280399571287237
+ 0.1082388938336093
+ 0.03515949888262818
+ 0.04812613344167038
+ -0.004193939645691374
+ 0.08946323725090613
+ -0.09631050033452093
+ 0.3075350177834638
+ -0.06634672135964825
+ 0.07925227109529463
+ -0.1409078912558518
+ 0.05056851836101016
+ -0.01700815625902306
+ -0.06037943269559536
+ 0.09892857925799212
+ 0.08207875678191826
+ 0.0401805078370504
+ -0.04691411048033799
+ -0.1662293308415775
+ -0.2386409089095987
+ 0.1586092106306007
+ -0.0204356756327099
+ 0.2627466381613962
+ -0.1157412604526542
+ -0.03923621018256393
+ 0.3193006336495912
+ -0.01181507447535234
+ 0.1254963820836255
+ -0.04696239711554804
+ 0.2112234161247342
+ 0.08163203374064897
+ 0.3712691614291372
+ 0.2283796358644019
+ 0.2420889510666089
+ -0.281673795428583
+ -0.1389834210322841
+ 0.2943637510606202
+ -0.1975271758184561
+ 0.1195817368993112
+ -0.2066886502902928
+ 0.1033015872255916
+ 0.1029312706874491
+ -0.02355045691314823
+ -0.03711032362622817
+ -0.049928013128906
+ 0.0146609823226943
+ 0.1068268367986153
+ -0.005238915606817294
+ -0.04449246861487063
+ 0.0739165699188737
+ 0.1175015099835593
+ -0.0243198957171463
+ 0.07690788118031312
+ 0.1096078461382219
+ 0.05853528842874703
+ -0.1919779200916936
+ -0.05562009028453184
+ -0.03235072832237598
+ -0.09081991578068289
+ 0.1105893907789839
+ 0.00280376974543959
+ -0.07294169392772441
+ 0.0593325025186879
+ -0.0829750906869218
+ 0.2424132404060261
+ -0.04390007976447648
+ -0.0873205133527018
+ 0.1913256250076217
+ -0.05789972447599219
+ 0.1191838521977546
+ 0.07900534964962966
+ 0.1129964413566027
+ 0.03845314612416371
+ -0.01317128353652406
+ -0.02754672704586516
+ 0.04604311801172246
+ -0.02687915964511522
+ 0.1191444452592128
+ -0.2392759431145069
+ 0.01014355816765817
+ 0.0580615715529177
+ 0.0914704018910612
+ -0.008884776013316038
+ -0.04174903019054066
+ 0.14955696141056
+ 0.1336423278175688
+ 0.02123406414716683
+ -0.1375520801272396
+ -0.1887516837003186
+ 0.05191888771528524
+ 0.2925449608997491
+ 0.03245073533332654
+ 0.02192667445428681
+ 0.1404058648788435
+ -0.02028972204692782
+ -0.04913767326933603
+ -0.002364782444934244
+ 0.00965292158421107
+ -0.04144962060783889
+ 0.09228770761422608
+ 0.04112390328947663
+ -0.3967713971507376
+ -0.03255896326177396
+ -0.09554414475173044
+ -0.05747590975060092
+ -0.05546432616814327
+ -0.000166187772064942
+ 0.1062606880514689
+ -0.01455756280987187
+ 0.08262341961431828
+ -0.219871104445319
+ 0.03597020818609064
+ 0.2315650637310843
+ -0.03958668798802647
+ 0.07855633440888411
+ 0.1030849307433538
+ 0.006127776655955027
+ -0.03728892565704994
+ -0.07241346010985282
+ -0.08780590558102311
+ -0.01740091800666538
+ 0.06585768438947309
+ -0.06094450606352605
+ -0.09395148275873738
+ 0.1026817079466833
+ 0.1932802332254911
+ 0.162764433792275
+ -0.01324235558117182
+ -0.2206420718282719
+ 0.009920626486896266
+ 0.006057614362890605
+ -0.1411360490903299
+ -0.2164550302726913
+ -0.06939873057915501
+ -0.498731101783119
+ -0.00385814543924401
+ 0.2153053789400234
+ -0.1669108972524112
+ -0.03539562399349915
+ -0.1272513348545094
+ -0.04215578131798401
+ 0.2145207734956126
+ 0.1331724101917932
+ -0.1098188629910101
+ -0.02168924754782288
+ -0.1106534730987053
+ 0.1085657570585296
+ 0.1251350262479071
+ 0.05778852887854908
+ -0.04742373437661727
+ 0.01797717897646522
+ 0.01645073086220431
+ 0.2664561481422336
+ -0.008392111472630187
+ -0.04528896930336532
+ -0.00216995855390202
+ -0.03916490066317626
+ 0.02198220012055105
+ 0.05555817935154898
+ 0.07599306511099609
+ 0.1362888427705322
+ 0.1554237734967745
+ -0.04551202934879932
+ 0.1069293564908843
+ 0.1180088398692217
+ -0.1133149481407102
+ 0.08121494920599147
+ 0.2646036558026292
+ -0.2680881726094901
+ -0.1947311428580881
+ 0.005697175228141779
+ -0.024058085666542
+ -0.09151138411650346
+ 0.2790377689348492
+ 0.00143556469283001
+ -0.01545180402031711
+ -0.1926163179636097
+ -0.07773657840772526
+ 0.03577573808018113
+ -0.04838235032545117
+ 0.03068462739239929
+ -0.1387770103835139
+ 0.01909701250847535
+ 0.01736687926195046
+ 0.01883761066448333
+ -0.1129357845163832
+ 0.09855311989182682
+ 0.004589081249278285
+ 0.18725128783944
+ 0.01550393360272544
+ 0.1093913651796013
+ 0.02628663360875518
+ -0.03829388673206289
+ -0.105746267779198
+ -0.142118170935968
+ 0.05449591018541769
+ -0.151018406625868
+ -0.153723790640134
+ -0.008451157597419039
+ 0.08925480787582508
+ 0.04699635773247333
+ -0.07590012352052174
+ 0.06014588467749803
+ -0.03237137826702115
+ -0.3183451703992329
+ 0.0875859134231752
+ 0.08964738038496677
+ 0.2821280918359231
+ 0.005662018097984336
+ 0.03056095026899291
+ -0.1882400506327246
+ -0.08449772351404176
+ 0.07991338212418417
+ -0.07326873742972478
+ -0.1863414254955279
+ -0.01319297352559068
+ -0.01449668152337194
+ -0.1261539684963731
+ -0.1883329468916585
+ 0.1423233693263666
+ -0.08255587111893474
+ -0.1141101550114962
+ 0.03695196019278594
+ -0.04072939643458205
+ -0.1816130657213404
+ 0.08586036121206912
+ 0.05124622044257115
+ -0.2251892885789057
+ -0.4797212360798791
+ -0.05549447976051809
+ -0.1733223006890926
+ -0.02810359722888719
+ 0.04877735500991873
+ -0.191666458982011
+ 0.05942958732370112
+ 0.1671513379397107
+ 0.1094287220875946
+ 0.1247558320833959
+ -0.06563015056961696
+ -0.05701115550338574
+ -0.03552623205876849
+ 0.02987451744304551
+ -0.171299712843539
+ 0.1255319518586041
+ 0.177864398040107
+ -0.0907314208486666
+ 0.07818614115408005
+ -0.02216558399800002
+ -0.1202248200307474
+ -0.03927548598722567
+ -0.06580683250926828
+ 0.04584251582050356
+ 0.2291711708987619
+ -0.2292464328148839
+ 0.005712488594544227
+ 0.001411987182642534
+ 0.1437168015077329
+ 0.2207250968630461
+ -0.03040152824312825
+ -0.09163135049325133
+ -0.05553346446533728
+ 0.2893526675049227
+ -0.04377551385726801
+ 0.2571736983640531
+ 0.0315288253194958
+ 0.07015499073129612
+ -0.05599623927470815
+ 0.04752956918115923
+ 0.1600765040849279
+ -0.005855937437852521
+ 0.1274030475061361
+ 0.1664775049021864
+ 0.01529660960014022
+ -0.06400075394324004
+ 0.02249443258044355
+ 0.007313269269809203
+ 0.06226120378549171
+ -0.06515344424510049
+ 0.1568628708771108
+ -0.1460478268205407
+ 0.003509720329546019
+ 0.3147860634711218
+ 0.1067427958971875
+ -0.01232217623658509
+ -0.117080571480174
+ 0.1114377531566743
+ 0.02986809717666046
+ 0.2917139776371681
+ 0.1488158375149453
+ -0.1020770229650464
+ -0.2724511974927713
+ -0.06846503524543952
+ -0.1216571076104225
+ -0.1563323908332596
+ 0.2482538139343893
+ -0.05330376867448976
+ 0.04077766875038313
+ 0.1289781526280537
+ -0.01950364386916388
+ -0.03131871028591678
+ -0.02393909763780365
+ -0.04003190736139422
+ 0.09177588796181167
+ -0.03135089689512027
+ 0.03817521828212919
+ 0.1550290015856702
+ 0.1491135104682224
+ -0.05776170485294529
+ -0.0606283708625731
+ 0.02420577837027465
+ 0.1096046698416483
+ -0.06832501046485764
+ -0.06025481187237652
+ -0.05713198949008493
+ -0.1115617925067333
+ 0.01732638989195593
+ -0.05138089165158981
+ -0.1726948431105822
+ 0.1561199121907351
+ -0.09347701987379298
+ 0.07120136997733857
+ -0.04899064095725596
+ 0.01018054910601599
+ 0.1420625571236766
+ -0.02194993127520828
+ 0.165452099447372
+ -0.01742395167695984
+ -0.05992497363119213
+ 0.1033815810803336
+ -0.05653441988631364
+ -0.0388155111464341
+ -0.0166015167043805
+ 0.0274138125074293
+ 0.101805240598185
+ -0.07729067099646124
+ -0.06188927731361168
+ -0.0100185248292066
+ 0.03460900093152912
+ 0.1226685406386579
+ -0.001757099748671331
+ -0.08839696288114754
+ 0.1588837040266128
+ 0.163601062828788
+ -0.13826633220042
+ -0.08152173912197842
+ 0.008506746394785361
+ 0.07042556131263193
+ -0.1828657545808618
+ -0.03848807844263183
+ 0.2606417611079284
+ -0.01265122240910012
+ -0.09397630781127818
+ -0.09748902091685237
+ 0.105866264912152
+ 0.01896539015218655
+ 0.03727952419280388
+ 0.1356579535941467
+ -0.2376481909952
+ -0.002655511764697968
+ -0.1743034157769036
+ -0.03230914849792802
+ -0.04919283048200387
+ 0.04992690302660464
+ -0.1289717379605334
+ 0.00102616320028599
+ 0.03478821231647943
+ -0.1769792199015237
+ 0.05763456781085124
+ -0.03671818539191991
+ 0.1008802439141509
+ 0.1136148027650005
+ -0.002567505373993753
+ -0.2756069303559292
+ -0.158115294759348
+ -0.1086499956201196
+ 0.002846788351640035
+ -0.1189305369308229
+ 0.0311792838299531
+ -0.2239770597758744
+ -0.08231036079318614
+ 0.08862385163541975
+ 0.131008945252178
+ 0.1907787404319429
+ 0.2709292772826193
+ -0.08307084287653484
+ 0.03446911300784438
+ 0.01750728010709182
+ 0.05835275312271333
+ -0.08604719696999655
+ 0.05547809569775107
+ -0.2553890780051052
+ 0.02715648753903925
+ 0.1507507653991545
+ 0.0519486834894145
+ -0.0210808836261286
+ 0.03290650143910099
+ -0.1270844254729972
+ 0.1132300562737093
+ 0.04159665516818557
+ -0.1948375096323234
+ 0.05739364360134825
+ 0.04914049978626839
+ -0.02422684163367515
+ 0.2950433175222979
+ 0.1519390042565463
+ -0.06276568150556379
+ -0.09561077032176436
+ -0.0008378532471674976
+ -0.1806188062236245
+ -0.2420778639017236
+ 0.06189512960544813
+ -0.03872342988893834
+ 0.2508174006510015
+ 0.1248760017255552
+ -0.1466699934890679
+ 0.06194452024505161
+ 0.07994076107156113
+ 0.1541741990563387
+ -0.008523247745018094
+ -0.3862841820194676
+ 0.06513823835110087
+ 0.06359201764578154
+ -0.0009936793314582546
+ 0.2027632786253278
+ -0.0827394422553194
+ -0.3187135152576908
+ 0.04662790662305236
+ -0.01161450013403172
+ -0.02961184580446037
+ 0.2670706588229759
+ 0.05214539555352883
+ -0.1203018171547773
+ -0.4478927277556519
+ 0.1427811915174739
+ -0.0009452916897276462
+ -0.05958411841878353
+ 0.03568905427264147
+ 0.1088453123567649
+ -0.0868523306888092
+ -0.01843269790782425
+ 0.02669644607712607
+ 0.1368932942382582
+ 0.03779970347539997
+ 0.02211521663639291
+ -0.08950440177402666
+ -0.07478127170514788
+ 0.07233690342985652
+ 0.02634823503006173
+ 0.1406981381324208
+ -0.2896216362595403
+ -0.1121983138388147
+ 0.07196330086151316
+ -0.1553042879140343
+ 0.03637390451718276
+ -0.05687159695765016
+ 0.06919151073825189
+ -0.01805904709167047
+ -0.01148728056394477
+ 0.1091348561167036
+ 0.006320162599893106
+ -0.2796085243257688
+ 0.04739100273532246
+ 0.09121740265040824
+ 0.02640660763106167
+ 0.1243318128016849
+ 0.0678073515026652
+ -0.01969988734011586
+ -0.1169717251247893
+ 0.09389876178033754
+ -0.1723059167997276
+ -0.03750938125555992
+ -0.05872270975314106
+ -0.06340521882151837
+ -0.1344028859715276
+ -0.1588560293136797
+ -0.1688707989086347
+ -0.1257175256489785
+ -0.125088715520732
+ 0.2054866846531306
+ -0.01506271934864957
+ -0.1193881940972365
+ 0.006854672134935615
+ 0.04752726548117205
+ 0.1124313047487734
+ -0.2345716043131754
+ -0.0966784526190799
+ -0.07068464232571015
+ 0.01736857233411952
+ 0.04488167006610325
+ -0.2843837732643927
+ 0.10716574280311
+ 0.1666004751499099
+ 0.2857988321304801
+ 0.122947875889353
+ -0.08663222981928188
+ 0.0212658468879969
+ -0.003613203808198238
+ -0.09128479640783342
+ -0.2531883278119825
+ 0.1815634810104498
+ 0.08845489272367121
+ -0.05233137768136104
+ 0.08031762182304369
+ -0.2155777146411779
+ -0.2564823595474058
+ -0.03019130441808567
+ -0.1797136818846594
+ 0.05377877052887539
+ 0.1096448138915206
+ -0.1479548314371374
+ -0.2690653689962727
+ -0.04255533440371613
+ 0.07790825620708147
+ 0.3199944979618799
+ -0.08049724751558474
+ 0.139398263929424
+ -0.03513301979550565
+ 0.1557230323367141
+ -0.1043800105403567
+ -0.04915709973821722
+ 0.1740392832053469
+ 0.07850578662337659
+ 0.06900135804453329
+ 0.1543174396321019
+ 0.1913021203470564
+ 0.03248262135533719
+ 0.1362352004509483
+ 0.03820012662259802
+ 0.02465376305200654
+ -0.07973176671490013
+ 0.06660671848250377
+ 0.18871219108177
+ -0.008093631404408198
+ -0.1767246417538758
+ 0.00990266015180156
+ -0.07132583087173691
+ 0.02628871489469766
+ -0.01151204088869364
+ 0.3209454112733626
+ -0.01572949438450685
+ -0.1179416333477361
+ 0.02767486872290684
+ -0.003196235972921697
+ -0.2018400719502092
+ -0.1443658218393715
+ 0.1409700805900654
+ -0.1374062844011678
+ 0.1566387766450519
+ -0.01464142325283152
+ -0.09386910081568539
+ 0.1940871551473544
+ -0.0009229305722659523
+ -0.1003453469074656
+ 0.08707272424241898
+ -0.04084866700580461
+ -0.00835848653063914
+ 0.1374031742323946
+ -0.05941076295697365
+ -0.05361274680393424
+ 0.06005774690231313
+ -0.08728264413619945
+ -0.03182871408833136
+ 0.07761623662150324
+ -0.005465534469940489
+ -0.1435986443157352
+ 0.2229362210983785
+ 0.165694452920798
+ -0.09733483826165971
+ -0.06192171203911068
+ -0.01201138599168869
+ -0.241464183207144
+ 0.01447397517722392
+ -0.1580508339638638
+ 0.1239975988161607
+ 0.01318763966961383
+ -0.02318521075282481
+ 0.1253227011275004
+ -0.09051730063913441
+ 0.1010992941034518
+ 0.07236374335157782
+ -0.06829558579670918
+ 0.08802095769461238
+ 0.02222150657255103
+ -0.1240027586042427
+ -0.1127318578300772
+ 0.01058998788801809
+ 0.09129799024348864
+ 0.08406216402634781
+ 0.01469513470310243
+ -0.09377037590621057
+ -0.02957921396339794
+ -0.02224655259628815
+ -0.1256856814296717
+ 0.0327859115036057
+ 0.01735739917724188
+ 0.2321654126178073
+ -0.05301387703579736
+ 0.02086166570938919
+ 0.1808990770867712
+ -0.01100092518093565
+ 0.1254107013013275
+ 0.07712432562303929
+ -0.1846333616553162
+ 0.0354631792700261
+ -0.1237949044698444
+ 0.267900287597566
+ 0.02569258517592024
+ -0.04495669809550676
+ -0.1168890230323697
+ 0.0336975646046045
+ 0.02125973110491677
+ -0.02677683817964055
+ 0.1197209867783265
+ -0.0777858807226266
+ -0.02425547448365667
+ -0.08487292490805882
+ 0.06291808994433309
+ -0.02204340304934895
+ 0.02377435051419018
+ -0.1718773573170014
+ -0.1011571579988193
+ -0.1208029255107849
+ -0.1441164927563105
+ -0.04633424809550369
+ -0.1422415093881239
+ 0.2088533311413101
+ -0.001853172596141906
+ -0.1295936882431212
+ -0.1282184353297419
+ -0.1794144878161049
+ -0.2040305688976426
+ 0.1399649813297814
+ -0.10764262620441
+ 0.0616301297066474
+ -0.1474197011387816
+ -0.05050426102121119
+ 0.1653477333539644
+ 0.06068948659719262
+ -0.05325459514810765
+ 0.1373242105620577
+ 0.03880137337106698
+ 0.06017715543512947
+ 0.06211813928644649
+ -0.04191313812532114
+ -0.04513341992023757
+ 0.01914286643644276
+ -0.04438971983871555
+ 0.1387577841756764
+ 0.05386357276079355
+ 0.1042718732060936
+ -0.07513626164669096
+ 0.1786960028553379
+ -0.05637216233733611
+ -0.03720214170877462
+ -0.1774340291717748
+ -0.2549011743869734
+ 0.186879844725118
+ 0.2833063725183637
+ -0.01880086739296004
+ 0.1769374720509577
+ 0.004564930889063233
+ -0.05798972499647807
+ -0.2747641741293661
+ 0.027553184454707
+ 0.2632412184052024
+ -0.1095551353914822
+ 0.06916048702527024
+ 0.03080355376703287
+ 0.2165981712802113
+ 0.1890893856843088
+ -0.08659995312896483
+ 0.1069192157133039
+ 0.0454950752455283
+ 0.14187715557712
+ 0.100672848815481
+ -0.124773924250272
+ -0.05335187514446071
+ 0.1547592109188055
+ 0.002641240342700039
+ 0.1258711227814993
+ 0.1206538733123445
+ -0.135791533512724
+ -0.130918815644207
+ -0.05396861570570471
+ -0.09140332872931331
+ 0.09794058035021644
+ 0.1588423831952299
+ -0.1616346066767531
+ -0.03167509234642521
+ 0.2413978277122087
+ 0.07297159339659552
+ -0.003991980625359775
+ -0.01341487228926374
+ 0.1968283025420433
+ -0.1106224029092038
+ -0.02915201476535762
+ 0.01299576259906967
+ 0.1763479829281023
+ 0.02034320445669416
+ -0.007975760651902569
+ -0.1878436437209434
+ -0.0511284052070836
+ -0.2054486303338899
+ 0.08939311648359854
+ 0.1069566349676425
+ -0.3163184448636494
+ 0.06701973428191561
+ 0.01615250637797392
+ 0.1795215061720997
+ 0.02017711076221559
+ -0.3561757064215255
+ 0.03738435948083851
+ -0.06283102722927891
+ 0.1113950871495966
+ 0.1520074264787128
+ -0.05117322488552872
+ -0.5240923053401126
+ -0.04551984233766806
+ 0.0596401451452126
+ -0.2693136769181011
+ 0.0703840776719498
+ -0.09642522868000397
+ 0.03163871728561705
+ -0.04684419890810169
+ 0.1078803552979049
+ 0.01765144204601502
+ 0.01842808628453179
+ -0.2247013264156105
+ -0.1572500241274349
+ -0.1543378466013791
+ 0.08844108358348482
+ -0.2226388530497707
+ -0.00802841258335605
+ -0.1282277729831008
+ 0.06727365881224892
+ 0.01015621985250618
+ -0.1004970234627534
+ 0.102732150328305
+ 0.1667404221737363
+ 0.1832359281510589
+ 0.1395964845806093
+ -0.193799724903005
+ 0.0191596749759875
+ -0.0583700053589912
+ -0.04116152622862413
+ -0.08204498601953146
+ 0.1714138796188239
+ 0.1756244579872559
+ 0.0390069765786883
+ 0.08129445383792273
+ -0.05658080254966814
+ 0.04682762892287125
+ -0.09957164218093659
+ -0.05143646723972818
+ -0.0480872450150412
+ -0.01121554980364516
+ -0.05096509640375396
+ -0.01891053018629413
+ 0.1746410924551564
+ -0.1545065355810867
+ -0.2141290021524509
+ -0.04098056720418834
+ -0.09707855006958718
+ -0.01746835336172641
+ -0.05827000757328446
+ -0.06903569742387033
+ -0.2576319419162038
+ 0.0556139976498211
+ 0.01293602538646877
+ 0.3203057499851356
+ 0.0727244748608836
+ 0.2165980582221478
+ -0.05750323110572632
+ -0.06969582175803714
+ -0.03590660607489582
+ -0.2687061807209369
+ 0.07258616839256866
+ 0.2460848343887318
+ 0.06489755354914239
+ 0.08224910815883786
+ 0.03288801465840412
+ 0.01926730455644425
+ 0.118500161428956
+ 0.213596783357284
+ -0.1274323690677871
+ 0.04630213557499899
+ -0.01416508956449309
+ 0.1685802397578535
+ 0.04117581547460621
+ -0.1347008843688866
+ -0.1925124798927196
+ -0.02819143318336916
+ -0.1353145214126829
+ 0.01537443611510884
+ 0.04182514849884943
+ -0.02488285487230305
+ -0.07523371621282608
+ 0.0456453497418188
+ 0.02320659688479692
+ -0.09184485017807738
+ -0.1021420570691875
+ -0.09019704903516369
+ -0.1115790792593659
+ 0.06726113707953835
+ -0.09485300922229126
+ 0.08202262147375204
+ -0.1951874480726342
+ 0.01751795456052687
+ -0.1731541700471953
+ -0.04642163512287122
+ -0.1274507602620129
+ 0.02694469481270243
+ 0.2510538147171613
+ -0.1473392223633127
+ -0.2314405061445512
+ 0.1459719401193021
+ -0.1136173010133768
+ 0.006868532856616406
+ 0.02400895591422874
+ -0.00140889397098312
+ 0.07962126481284934
+ 0.2570673940922909
+ 0.2279872117501605
+ 0.01066635433307934
+ -0.2524576715800825
+ 0.04402546277869483
+ -0.1891818569796238
+ 0.02491066047065214
+ -0.06917415231101073
+ 0.05843516739505776
+ -0.110344662084734
+ -0.004722266458798184
+ 0.1407029769762403
+ -0.0681792501302895
+ 0.0728679211868621
+ -0.09338393260688856
+ 0.08571355216912344
+ -0.2519953195513743
+ 0.04142534451424247
+ 0.1759653276726652
+ -0.1958231103718363
+ 0.03723831697901804
+ 0.2646310160443111
+ 0.1403640832729521
+ -0.1018280651378107
+ -0.1731322699109423
+ -0.05120455192347869
+ -0.001620598747993561
+ -0.216583888020244
+ -0.05044656277776705
+ 0.03362227898942541
+ 0.256463105846393
+ 0.1215738701026295
+ -0.005237128515646541
+ -0.01022664676506063
+ 0.1004277789860339
+ 0.07712816122879944
+ 0.1078374290208138
+ -0.007194865777990773
+ 0.1876551699642019
+ 0.001667350295852293
+ 0.02867937541054041
+ 0.04517293409604164
+ 0.0937114515641464
+ 0.04633236924123863
+ -0.1006494697492672
+ 0.0003997197461487522
+ -0.1220211830864603
+ -0.1356895851520392
+ -0.08619539425047287
+ -0.005520532485616399
+ -0.1622350543024395
+ 0.1329943913962352
+ -0.05133839832939446
+ 0.06049281304004884
+ -0.1380009534292445
+ -0.0307093703266272
+ -0.08189895899890301
+ -0.09582785752375117
+ -0.0133575494018252
+ 0.03102839653371089
+ 0.1113109805250389
+ 0.02820468239319545
+ -0.0905428916681274
+ -0.05018668575904902
+ -0.04851622012133064
+ -0.1322551094153764
+ 0.03595758536261508
+ 0.05241541823993601
+ 0.09172724805967761
+ -0.06604359102903488
+ -0.07165658896802339
+ 0.1102900466151579
+ -0.04752197349369227
+ -0.08734046422401183
+ 0.05591510956639406
+ 0.006237028274019086
+ 0.0857669005057204
+ 0.05031680710561896
+ -0.1452009830004442
+ -0.05728141241003363
+ -0.1012379336542239
+ -0.1854106056175622
+ 0.04013411401239173
+ -0.04897801504707037
+ -0.0637802936013028
+ 0.03357712506802858
+ 0.09828752550925135
+ -0.07136897380156022
+ 0.08090884282108722
+ -0.09502012443304242
+ -0.01161741856411765
+ 0.1226464776813545
+ 0.4485759372466924
+ -0.05015434808813306
+ -0.1744905663010217
+ -0.2358783567264802
+ 0.1040871860255075
+ -0.218228186542194
+ 0.05162613366267214
+ -0.5825444454694714
+ -0.01614290196515434
+ 0.07456015276006371
+ 0.1418633731961386
+ 0.1795583698412907
+ 0.03381238488305453
+ 0.0641206581459849
+ 0.001235302052984547
+ -0.006611515360967271
+ 0.1564581816138022
+ 0.141106710505395
+ -0.08431365731908896
+ -0.009499002919999685
+ 0.04644193436697899
+ 0.2307887457874641
+ 0.06050815293330995
+ 0.1143476769885243
+ 0.2110614716643876
+ -0.2520013744550498
+ -0.1146434935033729
+ -0.2128355272346812
+ 0.2014480460676106
+ 0.09181113139079973
+ -0.1056804973878586
+ 0.08361396201986253
+ 0.2518627168471895
+ 0.1044295499804132
+ -0.0406760446165754
+ -0.07860006405826045
+ 0.2528533561426618
+ -0.1517541335513065
+ -0.1025524098656186
+ 0.05673539907367186
+ 0.07782671150468863
+ 0.001871582368684291
+ -0.04449885254367604
+ -0.03126683895503429
+ -0.1051607436456349
+ -0.2244141685950463
+ -0.008170682034190205
+ 0.03879446505442504
+ -0.1628287294733831
+ 0.05642526266835852
+ -0.06253827842498424
+ 0.331488732904181
+ 0.001724232810947692
+ -0.3905681921687634
+ 0.05895642348297336
+ -0.1119125616668234
+ 0.1662986332997487
+ 0.1434946617819624
+ -0.07435548186449015
+ -0.743880033080766
+ -0.02644796415833742
+ 0.04367084422748885
+ -0.1834752372963459
+ -0.02560951051033576
+ -0.07631670614634718
+ -0.03255868057230467
+ -0.1167436877537004
+ -0.02272147536737479
+ 0.06411591472749349
+ -0.01711449495783932
+ -0.3044626495788554
+ -0.1025855568381658
+ -0.006429097263303756
+ 0.1276193682095619
+ -0.04285743679608941
+ 0.1192362093919868
+ -0.03412323380836676
+ -0.08479576892930732
+ 0.05299622364885363
+ -0.07586777001477925
+ 0.1309517244008993
+ 0.05149356145811348
+ 0.007873673151187054
+ 0.04735582667900365
+ -0.1654823590931954
+ 0.08008416420393097
+ -0.01715419516027902
+ -0.007799091890092146
+ -0.05088691456518094
+ 0.2452605269787489
+ 0.1546863842593431
+ -0.2897062969332454
+ 0.1188305054507049
+ -0.07850503665204994
+ -0.1006540439965697
+ -0.2558986811122662
+ 0.01548507621356168
+ 0.07329585410572076
+ -0.1370082978264821
+ 0.1387774740885949
+ 0.02955181581980287
+ 0.1444144371420732
+ 0.001837120217595092
+ -0.1578832986296675
+ 0.07882715158627783
+ 0.1928696950352308
+ 0.03224946199772585
+ 0.01341000025888617
+ -0.09598925318276851
+ -0.08435593451679063
+ 0.1228162643816339
+ 0.008015286774561025
+ 0.0228881821998962
+ 0.1570899536013809
+ 0.1095158523606059
+ 0.01446583578714654
+ -0.08895128018728235
+ -0.001236351104625074
+ -0.09216526425223315
+ -0.06910048027843081
+ 0.1502827463066932
+ -0.02645425706844879
+ -0.1538238485937606
+ -0.09373051983743103
+ 0.02993235896387325
+ 0.05922767058409489
+ 0.1931404783602182
+ -0.2580179446158961
+ 0.1319803253620105
+ -0.0610923011835895
+ 0.1136388376870395
+ 0.04235085121945019
+ 0.02087704833914409
+ -0.1097924577012104
+ 0.07209542544760648
+ -0.08731372091508521
+ -0.063858737454594
+ -0.1110311004225679
+ -0.03257993814386672
+ -0.09986316072865788
+ -0.05838994288214209
+ 0.06026660892265399
+ 0.06659362531488025
+ -0.03691176136829286
+ 0.1723615161788895
+ 0.09643056698971313
+ 0.06167212184878227
+ 0.06048632545906647
+ 0.106561067003565
+ -0.2359146628019494
+ -0.0856503881291492
+ -0.099643415633156
+ -0.1299553527488587
+ -0.1610609809668669
+ -0.04330429826958397
+ 0.07109263745939573
+ 0.09291327612335114
+ -0.1843812962021002
+ 0.1013587594778311
+ -0.03519803794281224
+ -0.1078463848683327
+ 0.0909954873993804
+ 0.02351873163478438
+ 0.08716975720936852
+ 0.09728441875793437
+ 0.1864120685550244
+ 0.09595823902078447
+ -0.1451589532866548
+ 0.01640819868298184
+ -0.0561591030940127
+ 0.1338230159271746
+ -0.01851799790476288
+ 0.07011706705491963
+ -0.01918525560968478
+ -0.08029296938813098
+ 0.07278078422728794
+ -0.1135486288809505
+ 0.02457002483323539
+ -0.0596770669792222
+ 0.2358769742082185
+ -0.2400165177972425
+ 0.08009438860952148
+ 0.2424825159792996
+ -0.008410432856421089
+ 0.02011138695890911
+ 0.1780224878404248
+ 0.1424454598257794
+ -0.05871314571253786
+ -0.09512264323598589
+ 0.1371897600998222
+ -0.09056466252358075
+ -0.1854181803259646
+ -0.2109512305338813
+ 0.09803982108185796
+ 0.03598251874938754
+ -0.04517478104099741
+ -0.04854246064512729
+ -0.06171789472616177
+ 0.07192616766614239
+ -0.03708658598751851
+ -0.01567456113454775
+ 0.03187402259986397
+ 0.05677710270208582
+ 0.08741110014562621
+ -0.2753834455814234
+ 0.0402215068984251
+ 0.001435929594174574
+ -0.03611589497412362
+ 0.007823493431096024
+ -0.003238811581184531
+ -0.2068030895775749
+ -0.2594894484833802
+ 0.2144522619103169
+ -0.1280545220519629
+ -0.134423044690689
+ 0.0913785824982643
+ -0.06794205571613246
+ 0.01436313583963213
+ -0.06666843135356472
+ 0.00838343184753052
+ 0.06888419434911967
+ 0.2325929290607184
+ 0.08681794826751776
+ 0.1593828431302552
+ -0.0971809489452081
+ -0.005808009595889368
+ -0.06696428436631012
+ 0.03116172093868571
+ 0.1198006010171893
+ 0.1584776439167764
+ -0.03353484654982301
+ 0.0926434116160393
+ 0.1045065496719981
+ 0.06503528577764309
+ -0.05100480215807208
+ 0.2010842588680187
+ -0.0726139584172765
+ 0.1975982144772545
+ 0.02064828836619831
+ 0.1142919992778068
+ -0.0463195959649861
+ 0.03451511108502742
+ -0.08986324087716212
+ -0.1767873512546086
+ -0.1247911188277607
+ -0.1398351533981865
+ -0.2721859928562543
+ -0.094640776176979
+ -0.05921379350247209
+ 0.2545959570106689
+ -0.1106979387583882
+ -0.180340863682782
+ 0.1531141947425265
+ -0.01814999583861644
+ 0.1670941187078815
+ -0.1504044341610136
+ 0.368068076988876
+ -0.1145625107919577
+ -0.1011895529635533
+ -0.1876994034146107
+ 0.2110545262545824
+ -0.06033059066490179
+ 0.04113581812067183
+ 0.2507545279143593
+ 0.1255650058849573
+ 0.1443145310492009
+ 0.1252464690064321
+ 0.1293592914089819
+ 0.09720477364753313
+ 0.1440814100814087
+ -0.1511182191743992
+ -0.0464273303555949
+ -0.03428424282005958
+ 0.1791273628939941
+ -0.08208633904799664
+ 0.04671543365037168
+ -0.01056477561293342
+ 0.3280100816934571
+ 0.06032636234666212
+ -0.01359310216640612
+ 0.1919570464308755
+ -0.0873620119777706
+ -0.02203560019350116
+ -0.09774582328771275
+ 0.1148398538982248
+ 0.07421430013508032
+ 0.003495306017029558
+ -0.2222163726228187
+ 0.08997589458793422
+ 0.1696783366534761
+ -0.1255260657153987
+ -0.007072320209895626
+ 0.1276347303962281
+ 0.1292982787448447
+ -0.05208297537677408
+ 0.1479841311882314
+ 0.04822554642615769
+ -0.131141197759718
+ 0.03471180741801515
+ -0.06440961118901059
+ -0.08722003818511585
+ -0.1441997814585887
+ -0.2274125474961627
+ -0.097169489440387
+ 0.02773088947569199
+ -0.1070466485408921
+ 0.06902503587091795
+ 0.1311954112343072
+ -0.141284481173385
+ -0.04546677580696161
+ 0.1097978230835506
+ -0.08057433169438499
+ 0.06757099048783766
+ 0.07174731709769074
+ -0.02851849012567256
+ -0.3757146075638175
+ 0.2328719117865827
+ -0.01005557396472817
+ -0.1243003275634562
+ -0.04595478016296822
+ -0.044100267647423
+ -0.138084140211752
+ -0.15511164224655
+ -0.2178613785661863
+ -0.01691927442642227
+ 0.07818793707265874
+ -0.1341944968282519
+ -0.05851098802706113
+ 0.1045252256364899
+ -0.0499496819284715
+ -0.1902526701601442
+ 0.07196166882139192
+ 0.004072779842996579
+ 0.0160270595289024
+ 0.04695225902353219
+ -0.04911191224655075
+ 0.191892831327582
+ -0.1444945058834267
+ -0.2202853904366343
+ 0.01006205721444285
+ -0.09504504271660796
+ 0.1401082316439268
+ -0.05821947588738329
+ 0.01428714349737697
+ -0.04498780531374046
+ 0.1007395382555364
+ 0.09608177306795511
+ -0.1427377335384288
+ 0.03727287969905327
+ -0.1777903785780568
+ -0.09485022788467795
+ -0.06500052025496814
+ 0.09284764092538193
+ 0.1299617494659396
+ -0.03042087319097689
+ 0.1796893932241038
+ -0.01073288538730337
+ -0.1049688058609258
+ 0.02829700538848619
+ -0.285330643098704
+ 0.1050696416419029
+ 0.1765518138946547
+ 0.08420673001179661
+ 0.06970816483959348
+ -0.1530962034710843
+ 0.01236764325505881
+ 0.07420243094544632
+ 0.08905349755618586
+ -0.1293428263821592
+ -0.0263365993699912
+ 0.0004047189157212132
+ 0.07588363274246439
+ -0.008464820354582242
+ 0.02020185026750284
+ 0.1244787239784793
+ 0.0159723831505977
+ -0.1982292587525092
+ -0.06697682688310315
+ -0.03613463148953804
+ -0.1652780548885115
+ 0.01438819929671103
+ 0.0436618379304702
+ 0.02491627491504792
+ 0.008404475967987952
+ 0.1148907444943133
+ 0.0311937852377651
+ 0.1303962606770908
+ 0.002384966791908356
+ 0.02716251179498693
+ 0.09946937530571996
+ 0.1321520060976324
+ -0.05438432657939025
+ -0.08340889495867501
+ 0.1640467519825544
+ -0.09103333261515581
+ -0.1638472616753343
+ -0.2122019615013457
+ 0.103203938253611
+ 0.2671611132079018
+ -0.01586821097307979
+ -0.07537445417268018
+ -0.1206608893246473
+ 0.2694225111514082
+ -0.2159889392117946
+ 0.1132074492364467
+ -0.1044352839100796
+ -0.1527095029381632
+ -0.0009496288578566223
+ -0.06634437061701783
+ -0.1224661849351588
+ -0.02970341668303083
+ -0.006863288596291386
+ 0.1175260476012279
+ 0.1070414474675595
+ 0.03480914513317275
+ 0.2048299438497757
+ -0.405880839130927
+ 0.06268356595061511
+ 0.01874398055316319
+ 0.04569425390720752
+ 0.09017430723950665
+ -0.02460268063576581
+ 0.05359884760024468
+ 0.1460005901313657
+ 0.05197464448943807
+ -0.03592257968612141
+ 0.31299478823909
+ -0.07515948363432123
+ 0.121321084016924
+ 0.01263599841656247
+ -0.14858359150611
+ 0.1195877374674842
+ -0.198524701721824
+ 0.1120248835720462
+ -0.04162710216587762
+ -0.05290302292867322
+ -0.02598187473458077
+ 0.07997285485503414
+ 0.03011143126414827
+ -0.06664724864047192
+ 0.04072436580352223
+ 0.2088715140920505
+ 0.04210225486461003
+ 0.07918849123899123
+ -0.01107329084409914
+ 0.131163883735306
+ -0.1444678082212088
+ -0.06088597297014842
+ -0.0919600166476546
+ 0.005007240825029527
+ -0.2956838950306138
+ -0.05916747318376518
+ 0.03896048279150401
+ -0.02436983603028851
+ 0.001561980004824293
+ -0.06762785302309214
+ -0.07194296837988168
+ -0.05202154642029872
+ 0.04532706723082909
+ 0.0473193172319981
+ -0.3924823907934017
+ 0.02590495826419959
+ 0.05103234693170136
+ -0.06220339572621125
+ -0.1128683942228634
+ 0.003621463285539008
+ -0.125072068400005
+ -0.2535233192296045
+ 0.2237082094153318
+ -0.1238662605915766
+ 0.2542353893090576
+ -0.1260957503641726
+ -0.04981271181918571
+ 0.04375474922843847
+ 0.01519398152190367
+ 0.0924876875703777
+ 0.04965081377876439
+ 0.3962923002924593
+ -0.03785891536828403
+ 0.09987244387398275
+ -0.2329998276014797
+ 0.06861596344868606
+ -0.1040800953732826
+ -0.003137478320763371
+ 0.1707473857482956
+ 0.1509218157310757
+ -0.06206676290586881
+ -0.05765075673333001
+ 0.1572077571817325
+ 0.01517142860401577
+ 0.01466221116289312
+ 0.3175028771696407
+ -0.020441517847501
+ 0.2053511851279294
+ -0.09067396104122771
+ 0.1236767207071872
+ -0.1986350982481705
+ 0.06298112666774777
+ 0.09385591886792403
+ -0.1223713511164094
+ -0.1147382813740545
+ -0.006883009107352202
+ -0.2168789477452491
+ 0.0524124558261823
+ 0.122901070985294
+ 0.3646057870511434
+ -0.06174545711317331
+ -0.2560780266664009
+ 0.09921395672527523
+ -0.04178700799421948
+ 0.1014635597977281
+ -0.1169927589196547
+ 0.3439174515523335
+ 0.01199432919263614
+ 0.1304317568047994
+ 0.07617103031021842
+ 0.1044847840807115
+ -0.03219950718320975
+ 0.0233797466830066
+ -0.5104169205393798
+ 0.1534422146750405
+ 0.05325027156780688
+ 0.07233797786357865
+ 0.03979979991638729
+ -0.0605452521243781
+ 0.2943625825384965
+ -0.02289376076416253
+ -0.1454518292546651
+ -0.005984339002386861
+ 0.2320380109932727
+ 0.01385619917191731
+ -0.05491483316000891
+ 0.05316412751874714
+ 0.1291916865339855
+ -0.07783323568050116
+ 0.01374474890451888
+ 0.08150744205473696
+ 0.03674178822386485
+ 0.1262867643310211
+ 0.08388804589784947
+ 0.07542899814341333
+ 0.05635966174022341
+ 0.1209635540242566
+ -0.2382066524199452
+ 0.01826229900511447
+ 0.1312058722121623
+ 0.05683785886574295
+ 0.03431733966086457
+ -0.1660524153169268
+ 0.2202586177883086
+ 0.1049052258434569
+ 0.1142853214472117
+ -0.1032444775412538
+ -0.0968140206878982
+ 0.1508012553582358
+ 0.002264266730459902
+ -0.007063442686006598
+ 0.0090916702830316
+ -0.1163386870841841
+ -0.07373009327495732
+ 0.03975460612836063
+ 0.009278149561383859
+ 0.1248891694484603
+ -0.006270014750222492
+ -0.1475526597316988
+ 0.09901729400060909
+ 0.1341875483226759
+ -0.1259743022982773
+ 0.05049364963162846
+ 0.03708603329314558
+ 0.02189707412706336
+ 0.2416443444012894
+ 0.2759794105981593
+ -0.02951365353365954
+ -0.05623552805001195
+ 0.1714076105551529
+ -0.03377215056195945
+ -0.179444129915509
+ 0.006621483580500045
+ -0.1737789320240277
+ 0.05809024247178902
+ 0.03678901531717126
+ 0.2776064805277152
+ -0.09322912720286203
+ 0.01334347063384463
+ -0.1053048191767229
+ -0.1604358264324766
+ -0.03182783823646951
+ 0.2033195668781748
+ 0.1951645181678192
+ 0.03528997505236636
+ 0.1158156322771727
+ 0.1134184255768755
+ -0.1202015647878645
+ -0.1186797026720517
+ 0.1227052012633174
+ -0.1855643716978661
+ 0.06526929159457916
+ -0.03972420017418311
+ 0.07309256877660195
+ -0.02977125684102818
+ -0.1960654571418668
+ 0.05010541748169863
+ -0.02077266288446909
+ 0.06825575668544
+ -0.1751993227568611
+ -0.01174347455288575
+ 0.1016835056137998
+ -0.1499648279313467
+ 0.07675604994186601
+ 0.1001469772779631
+ 0.01564105129620838
+ -0.08274643898747935
+ -0.08984432890622834
+ -0.3080101233397119
+ -0.2155884556106073
+ 0.1027420961564515
+ -0.0110173254277038
+ 0.03635824356612569
+ -0.1322111365643562
+ -0.1998777470782329
+ -0.06383138275761953
+ -0.07453898800212505
+ 0.1504701447139906
+ -0.02809264172900187
+ -0.126485832782059
+ -0.1156208284452664
+ -0.03486958474586161
+ 0.004898922209548031
+ 0.05571979584879586
+ 0.03497499654142802
+ -0.04493023236790567
+ -0.1265547423786091
+ 0.1024300437717925
+ 0.01267618383161958
+ -0.1192666895571647
+ -0.06480075713995874
+ -0.001726164340527923
+ -0.1743831685117497
+ 0.01053318863133042
+ 0.04032888011964177
+ 0.1266044601787064
+ 0.06838639787049788
+ -0.08669433632776707
+ -0.07699315754319193
+ 0.05121379958454336
+ 0.177834146977162
+ 0.1193533926516111
+ -0.1111876785928262
+ 0.07363127328126198
+ -0.001135007801882461
+ -0.2334147050506218
+ -0.2859990369490872
+ -0.04662617214043142
+ 0.04719597246866998
+ -0.06423162712809483
+ 0.1023702529027177
+ -0.05550149057601189
+ 0.2693097317610041
+ -0.2542442786389534
+ 0.05427865635843668
+ -0.02289077387644598
+ -0.06025298323649893
+ -0.1004826230504436
+ 0.06629417709563243
+ -0.03709967089572237
+ -0.0169610744075567
+ -0.002088483266166478
+ 0.1617962286550673
+ 0.2761238829078564
+ -0.07327915726179524
+ 0.1477834362060406
+ -0.5167831382879509
+ -0.050516045200913
+ -0.01625669977431896
+ -0.0659940405649726
+ 0.1069896895166956
+ -0.167874241219339
+ -0.07923803197233062
+ 0.1513999395028791
+ -0.02893003262506223
+ -0.02118220407176248
+ 0.01372312043503925
+ -0.1155447497524999
+ 0.1803012487250286
+ 0.0009191828994382826
+ -0.07906659895908262
+ 0.1529982630253779
+ -0.2459700679275017
+ 0.1745745175499034
+ -0.03473127916378869
+ -0.2494665077804605
+ 0.0942063728583513
+ -0.0212656179108913
+ -0.08824629408065333
+ -0.1727791494378021
+ -0.06116186083051743
+ 0.1092743183721836
+ -0.2118908450576671
+ 0.1091442326921763
+ 0.01762757150041668
+ 0.001492888773122969
+ -0.04467862159484848
+ 0.1945377072484118
+ 0.04372383237405544
+ -0.01633997278586273
+ -0.5664696917374411
+ 0.0900023222205014
+ 0.1024327770795413
+ 0.03174159051346814
+ 0.08168036960112228
+ -0.1044473530416468
+ -0.03258097577883422
+ 0.02656364864392141
+ 0.03960718729651969
+ -0.06902131912284072
+ -0.1923338759869059
+ 0.05724682232359244
+ 0.1291613069190952
+ 0.1402420313973408
+ -0.1743034410713866
+ -0.01142430155843352
+ 0.05379025830105558
+ -0.23426665939346
+ 0.1518271841478148
+ 0.08647099126854747
+ 0.2644879890017845
+ -0.1792884256069534
+ 0.06120768740122252
+ 0.03363621005698549
+ 0.06779670853307425
+ 0.1399725066900526
+ 0.07300773670183608
+ 0.1497455715168628
+ -0.04494168517881443
+ -0.1487789330622697
+ -0.123329993681653
+ 0.09304462616250117
+ -0.06260615465801572
+ -0.002204251665977467
+ 0.2241764656684518
+ -0.01380960288266653
+ -0.07683569365374116
+ -0.1830754405431468
+ 0.106624628845378
+ -0.2126703228672125
+ -0.05020566970742592
+ -0.1064108580225708
+ -0.1635788154299146
+ 0.04654217148564559
+ -0.08711541560158394
+ 0.06487354608901222
+ -0.3541464113397586
+ 0.08098879721239594
+ 0.2741172343682602
+ 0.2319837004703313
+ 0.01334847173582528
+ 0.3426867530573805
+ 0.03286313012828165
+ 0.1354787168702271
+ 0.1840121160671404
+ 0.2179747841712582
+ 0.0334435043309843
+ 0.04328905383699076
+ -0.3506744502335525
+ 0.1489702975138629
+ 0.1792090461456065
+ 0.06675010992872712
+ 0.3315298440973751
+ 0.07944857640654217
+ 0.08142924988923757
+ 0.1039971573427152
+ 0.02675596677429646
+ 0.0932807011511798
+ 0.001721874120625488
+ 0.2433885293844283
+ 0.1179481264819988
+ -0.01824308026406813
+ 0.04932863627365439
+ -0.01607871508351662
+ -0.4097972803841568
+ 0.1509001197272528
+ 0.09915526557508715
+ -0.1411358964162583
+ 0.00174289224332619
+ 0.1476208008607287
+ -0.149080629262399
+ -0.01223541789522891
+ 0.04344856097747963
+ -0.06739497831074694
+ -0.2958751909125948
+ 0.04468156708035222
+ 0.01699193206050237
+ 0.04294568184329499
+ 0.09625891514180991
+ -0.003331663309702944
+ 0.0394891310617719
+ 0.01484353007705631
+ 0.1893838285010545
+ -0.06588620690023483
+ 0.1192407653988873
+ -0.03377543229773004
+ 0.08055604468975913
+ -0.03876485921154274
+ -0.1998876806315399
+ 0.08351025978705078
+ 0.109838030443253
+ -0.08342925523216127
+ -0.1644979985086071
+ 0.03631522039718456
+ 0.1652052123374243
+ 0.06517262376922202
+ 0.02401161081769404
+ 0.2358921310858615
+ 0.2409577987266139
+ -0.0008723446223863749
+ -0.1051821186320413
+ 0.07279272083909501
+ -0.01892806487892615
+ -0.005655646006455291
+ -0.09895204107660432
+ 0.03993877776603263
+ 0.02003688466597598
+ -0.1455666492089054
+ 0.1508200186086192
+ 0.1066092633752345
+ 0.1408413121989664
+ 0.3237896257480205
+ -0.01988463626128929
+ 0.007512606264929994
+ -0.001569961135358605
+ 0.2901569209547472
+ -0.08937826325723433
+ 0.07575379524431722
+ 0.05750677176640619
+ -0.08419182154470206
+ 0.1415199704162118
+ -0.007489094542185645
+ 0.2833125760955886
+ -0.06330825782732212
+ -0.08038437758557827
+ 0.00335894671541253
+ -0.1651660867404519
+ 0.005274797456770841
+ 0.1451928119028927
+ 0.0112763569329058
+ 0.04349476330791319
+ 0.1755574189852512
+ -0.1004799935416272
+ -0.08857135678157048
+ 0.1016336458639318
+ 0.128089002707815
+ -0.2033716433497825
+ -0.06308347564939616
+ -0.0374340770790013
+ 0.1611866786641338
+ 0.06284520137338571
+ -0.1733160160414784
+ -0.01277000452815422
+ 0.05042123213034332
+ -0.07605669574193785
+ 0.1541596046567756
+ 0.100129475465233
+ 0.1502604053306998
+ -0.1815341230182427
+ 0.05781232623561872
+ -0.1404702374844343
+ 0.004316962777268882
+ -0.1229997303048702
+ -0.1008330870514547
+ -0.3862619069515442
+ 0.208386591312998
+ 0.00705287407151345
+ -0.1145430834370256
+ 0.03117859179772877
+ -0.1790100627788533
+ -0.317114755779024
+ -0.1465073188758438
+ -0.05678938881741846
+ -0.04631415161620381
+ -0.2602796885870445
+ -0.1609362113998376
+ -0.1564632165577046
+ -0.1888152536312644
+ -0.03969244829851229
+ 0.02612137771711488
+ -0.09543246562696969
+ -0.2183968199062007
+ 0.05932022007254949
+ 0.1119422932084073
+ -0.05863555273270557
+ -0.07311929300317055
+ -0.185054570373021
+ -0.08111145820914961
+ -0.08229595889898869
+ -0.08336248446315815
+ -0.03355480185186703
+ -0.0137739865574326
+ 0.01578423759247887
+ -0.134280858407766
+ -0.05979114807592321
+ -0.1359082924315047
+ 0.2251368739066763
+ 0.1284719551357331
+ -0.008720901210605873
+ -0.02170581118342002
+ 0.03098058198636323
+ -0.1516797189958598
+ -0.1182644098776825
+ -0.1585499139498735
+ -0.4004687252549597
+ -0.1083307051514876
+ -0.02477912039670704
+ -0.06401091446007764
+ -0.00465289972803625
+ -0.04593001902571633
+ -0.1553585199910524
+ -0.03401223036656075
+ 0.02175754426725177
+ 0.04032536711263271
+ 0.02332800491697365
+ -0.07758927803027214
+ 0.01505334199605501
+ 0.1159277332788187
+ 0.2246696640606345
+ 0.1821811913622563
+ 0.03372106411337247
+ 0.003076116559792473
+ -0.2321034140537513
+ -0.2014303771732046
+ -0.005825533774552373
+ 0.0003041051573775923
+ 0.04380826758018026
+ -0.06261541589566881
+ 0.09123212191409814
+ 0.03155889220687966
+ -0.1051582789554929
+ -0.019320322679914
+ -0.4296919773018761
+ -0.1267327090081997
+ 0.2460451494795493
+ -0.09815740987293466
+ -0.112065326760333
+ 0.04441953514823409
+ -0.1038860449114877
+ 0.0006600456433968109
+ 0.06011012798096176
+ -0.07961303018752405
+ 0.06889443179937985
+ -0.1722576091260162
+ 0.1272105046165272
+ -0.246875791317345
+ -0.1391520490300331
+ 0.1368616549424919
+ -0.2561672078639782
+ 0.101408160595333
+ 0.0632683649049635
+ 0.00183405543497394
+ 0.01030663525930626
+ 0.07710038204783168
+ 0.04191756022354327
+ -0.1945866467252047
+ -0.1956579413332658
+ 0.1495908114577365
+ 0.02566416481134048
+ 0.03281862995472427
+ 0.1750041255896567
+ -0.03072004489063606
+ -0.1180937560974679
+ 0.05465825796076283
+ -0.1293249330045187
+ -0.05106361463711692
+ -0.2154063873615947
+ -0.00929286894729823
+ 0.26662799813664
+ 0.2404808370652683
+ -0.1074050002949689
+ -0.0251094620755515
+ 0.06267698473230983
+ -0.04101375796257579
+ 0.06834772494667074
+ 0.08446323900121717
+ 0.0007030897104779825
+ -0.01788360140019017
+ 0.1075996994286616
+ 0.03829468072288923
+ 0.06483195079665234
+ 0.1428459774551653
+ 0.03807425408719391
+ 0.00172009335770463
+ 0.0852300086246448
+ -0.1436778649299378
+ 0.1547867246446074
+ 0.1686405197787893
+ 0.02386955669903841
+ -0.06969960445004166
+ 0.2056324130053931
+ 0.04415675901676435
+ -0.02879603819070192
+ -0.2174676885227549
+ 0.02320494759177774
+ -0.2064085939414105
+ -0.1115869662551407
+ -0.369623368937269
+ -0.2438690336665204
+ 0.01208375588372786
+ -0.05335290497420438
+ -0.08374412732522361
+ -0.002591990189751939
+ 0.06159414959258906
+ 0.1348096777210641
+ 0.2282425738739924
+ 0.1991950462659057
+ 0.1721361435316378
+ 0.03823591687534759
+ 0.04599802966822675
+ 0.1691568621964841
+ -0.08684860820319985
+ 0.002458687877128006
+ 0.1567772711376126
+ -0.6061634130980867
+ 0.08482804187365316
+ 0.09301007245418171
+ 0.02322821426035823
+ 0.08833443865908727
+ 0.1660776461897365
+ 0.02882327432218191
+ -0.01120870775886737
+ 0.108747179892392
+ 0.1909085004504499
+ 0.006521111454003459
+ -0.5798279730779259
+ 0.08115144774162875
+ 0.06379528850046974
+ 0.06597844236811323
+ -0.1150131081562423
+ -0.2595789720827441
+ -0.03921162143577954
+ -0.1889725044114855
+ -0.04946176534139222
+ -0.1332932698562622
+ -0.005483179351226585
+ -0.09406593199267928
+ 0.07027042011176331
+ 0.04140933885974341
+ -0.1220306059795954
+ -0.1784630885326045
+ -0.06183513688957735
+ -0.04620779652230963
+ 0.01208544382877731
+ -0.07593065279451829
+ 0.005310123626712982
+ -0.0537404178712245
+ 0.06509767254169235
+ 0.3095656335403331
+ 0.06644844505785756
+ 0.1046541918591089
+ -0.2943514782239701
+ -0.07184880984078473
+ -0.150286594575941
+ -0.05118008547225355
+ -0.02902023774849643
+ -0.01404467375295322
+ -0.2373670524378622
+ -0.07702324621789179
+ -0.04895588030861381
+ 0.06930851900854594
+ 0.06091788362428961
+ -0.0487272679060729
+ 0.1999840920560406
+ 0.2847516221314755
+ -0.006490807811043483
+ -0.1177768050221116
+ -0.003928377152762068
+ -0.06807953367482994
+ 0.00815797407149558
+ -0.05876264057938538
+ -0.002709513095030907
+ -0.01544309942595336
+ -0.1921996488157096
+ 0.1845996938092963
+ 0.08706799328370383
+ 0.08714351889716213
+ 0.1229346248358035
+ -0.3809247883884744
+ -0.02418657300916352
+ 0.0269583373305321
+ 0.1983369226201439
+ -0.2709090627460813
+ 0.1377633632128844
+ -0.07477915185102726
+ -0.1271397141138801
+ -0.04480297917247535
+ 0.003651388956419065
+ -0.07738439626008101
+ 0.02361201279791315
+ 0.09225393181949118
+ 0.05340439521830287
+ -0.06664910747875021
+ 0.07683235450873378
+ 0.008829235914813105
+ -0.1132187632823483
+ 0.03651116945295849
+ 0.0251097318352578
+ -0.08889740286853948
+ -0.1154001052002589
+ 0.1594637821987131
+ 0.03843906757654038
+ 0.1126844002169019
+ -0.02670792851573295
+ -0.002936827904473006
+ 0.1040632719247211
+ 0.1279576088824421
+ -0.08187550891668971
+ 0.01448635428902653
+ 0.07365691967003778
+ -0.128381333959134
+ 0.2507229622342359
+ 0.1428853588807213
+ 0.2112289983206825
+ 0.1112981412679344
+ 0.1236019560656137
+ -0.1095517469213071
+ -0.05610350103106206
+ -0.1287765694240627
+ -0.2204735393882981
+ -0.1947620806931097
+ 0.2661820493338552
+ -0.05727346964422059
+ -0.08777698515797741
+ 0.146862217082062
+ -0.1211727226851576
+ -0.2596105058855678
+ 0.03298028440934461
+ 0.01695093509570031
+ -0.1353865471488698
+ -0.2853070334978341
+ -0.1076480925415555
+ -0.01868969867909531
+ -0.2755694635705666
+ 0.08654685680010697
+ -0.06774074042738799
+ -0.04503361833983752
+ -0.2858509436932885
+ -0.006312798140391423
+ -0.1010457793245181
+ -0.02194637148278473
+ -0.1209844657919036
+ -0.09542887781864266
+ -0.1665141985613761
+ -0.02747941032078098
+ 0.06506225651289597
+ 0.03138345843500882
+ -0.08489390382410648
+ -0.001164325447961441
+ 0.003842815998187988
+ 0.188216079875226
+ -0.1172106582364393
+ 0.1588972143009124
+ 0.1376983275026621
+ 0.03625728163813317
+ -0.01756119064575194
+ -0.07975850805512234
+ -0.2525580915069717
+ 0.1225771086631814
+ -0.001084702257775424
+ -0.1828422228590859
+ -0.1557494369505046
+ 0.07795329534776511
+ 0.09472711027862084
+ -0.001833963694330049
+ -0.00898099402117189
+ -0.09376805496078298
+ -0.1661632022037644
+ 0.1609761058075417
+ 0.06938295032553456
+ 0.01499141464340691
+ -0.09033638416729012
+ 0.002273262915752048
+ 0.2752084675754887
+ 0.03188948749777691
+ -0.07466951045328889
+ 0.058957066698073
+ 0.007381213020779487
+ 0.1336484465438573
+ -0.1805294252205066
+ 0.01016316826432791
+ 0.02464567100390933
+ 0.02375319672877546
+ 0.09395357258690983
+ 0.1367843113114702
+ -0.09273687404562907
+ -0.1147744683144654
+ 0.004700225990019173
+ -0.2844801236877633
+ 0.02943023908257679
+ -0.01598638200216662
+ -0.141300900576971
+ 0.04039618734261058
+ -0.1639282340787453
+ 0.0765906998646597
+ -0.1713311368050122
+ -0.01092396053232519
+ 0.0114560370981295
+ -0.004751009039853939
+ -0.2087227424059737
+ 0.184480184554378
+ 0.001043298209004864
+ -0.1037353952645325
+ 0.05051265538013455
+ -0.1312447302270093
+ 0.1809881017891309
+ 0.1294350311522487
+ 0.07842999109776783
+ -0.0164205485729848
+ 0.0002513185691293265
+ 0.06300828324358586
+ -0.21952091989477
+ 0.1282120730099955
+ 0.09332454855351834
+ -0.07347927914594297
+ -0.05256809557858914
+ 0.02692370545350153
+ 0.01463401338307507
+ -0.2200433742206598
+ -0.1067900811897174
+ -0.1218573152310595
+ 0.1025261155401048
+ -0.4035504024103722
+ -0.1237795037065591
+ 0.1484483461691831
+ 0.2547497308795001
+ 0.02793250367947491
+ -0.03492943338759393
+ -0.1034132879006144
+ 0.05232615436444929
+ -0.1010810155523437
+ 0.03216142504305022
+ -0.2088791441861932
+ 0.1040330702029325
+ 0.05014918700639624
+ 0.07862518163601354
+ 0.05927749034429172
+ 0.02956841065647962
+ -0.2012967975789961
+ 0.003938353509400875
+ 0.09159030727319518
+ 0.09432302097877748
+ 0.08680770183530477
+ -0.04252292014899794
+ 0.03696641305128692
+ -0.1166550618014055
+ 0.01748073416192691
+ 0.04089595204065451
+ 0.01137504179012836
+ -0.05903219959174481
+ -0.01818124940614758
+ 0.04812882453035804
+ 0.2362286934568873
+ 0.02034513117836981
+ -0.02285896151518186
+ 0.005471949281347859
+ -0.06798392521056063
+ -0.1047102982122652
+ 0.3688688592810885
+ 0.03035280270697957
+ -0.03417058483170611
+ 0.0193786406183001
+ 0.1661469777636171
+ -0.07065347570250144
+ 0.007467038833007271
+ -0.1502546342421678
+ 0.083877329161976
+ -0.1661607003447915
+ -0.1074311013553391
+ 0.1661982342949016
+ 0.1979321484652738
+ -0.02043711751769698
+ 0.03682639398821854
+ 0.03644007402503712
+ -0.1111992055960391
+ 0.2790245162208053
+ 0.005369490324460527
+ -0.0314882128296991
+ -0.01417981232737644
+ 0.04828101676321944
+ 0.008977275006716955
+ 0.2043868592912931
+ 0.04365301879191937
+ 0.1305156044209719
+ -0.01794485993614705
+ -0.2384070578414621
+ 0.05744150678398646
+ -0.09762703357797536
+ -0.2678785778945201
+ 0.0346727597244921
+ -0.2780084831563379
+ -0.1499419512722171
+ 0.1038933245569644
+ 0.03440607454388061
+ 0.000274370782536458
+ 0.06111310170522111
+ 0.08608971642796071
+ 0.04987573262615801
+ -0.04626504059303834
+ 0.1698993704052897
+ -0.06281041299806465
+ 0.04528977818330598
+ -0.123392654940005
+ -0.0290676987885179
+ 0.107881616484137
+ -0.04178073164162893
+ -0.03764153500148977
+ -0.2824760561583472
+ -0.001557878213629696
+ -0.1640962383796669
+ 0.06850449820069332
+ 0.01804390116308751
+ -0.105628013732652
+ -0.1505808251628635
+ -0.08082331342730152
+ -0.2008307943952176
+ -0.02991474972227747
+ -0.04271818230162084
+ -0.120879166950042
+ 0.065444494307024
+ 0.1856453759031841
+ 0.04812894538925469
+ 0.04440193799295528
+ -0.007132304738937823
+ 0.02234193396576895
+ -0.09070804057526791
+ 0.0249839423657245
+ -0.01598184712240994
+ -0.002039125476166264
+ -0.2826860340094195
+ 0.1237698069602635
+ 0.005176355423163174
+ -0.0676378204351348
+ -0.102549818025726
+ 0.07228683717461937
+ -0.03231537860473729
+ -0.06025380539328302
+ -0.1067148913657218
+ -0.1832348624262625
+ -0.1186896551549737
+ 0.06534932782785902
+ -0.04148260038373607
+ -0.3297449271049483
+ 0.1638800049942212
+ -0.1047269438797595
+ 0.06573542409555815
+ 0.1721605583437557
+ -0.1604184367461875
+ 0.03905030110637008
+ 0.01086051951898515
+ -0.01894004518831463
+ 0.06860012102710784
+ 0.02071178364009996
+ -0.07564673142046621
+ 0.01194018131385199
+ -0.01809349589871487
+ 0.06818136240553006
+ -0.04702563798760495
+ 0.060462037871139
+ 0.005590683401130687
+ 0.01791891579467166
+ 0.05911651275922077
+ 0.05864473705533306
+ -0.02266784974209638
+ -0.06675284352905796
+ -0.2306891995624698
+ -0.008914613841774933
+ 0.08925315177057583
+ -0.02838669816570877
+ 0.1244219598355526
+ 0.1306714961625057
+ 0.1190050559289682
+ 0.136603365054152
+ -0.3123502047995758
+ -0.06066587616933178
+ -0.04621714114092183
+ -0.3003727436883856
+ 0.06131468434924262
+ 0.08072593320910279
+ 0.02622731489628235
+ 0.1359507126697057
+ -0.1439553612936746
+ 0.1419399686336321
+ 0.01657293197267144
+ 0.05013144712041896
+ -0.1174187439667581
+ -0.1229456383384699
+ -0.07021784461102953
+ 0.1760995872620846
+ -0.1398593474134106
+ 0.2287227549937715
+ -0.08096577250908631
+ -0.004426402139883642
+ -0.06228587044321769
+ -0.004607207370818548
+ -0.2171647049713261
+ -0.0637788403807322
+ -0.1596330784798335
+ 0.1641262828017135
+ -0.09976515128050771
+ -0.03789548774364188
+ 0.06395283979531464
+ 0.1600188622367744
+ 0.03074946009474685
+ -0.06847802141332188
+ 0.03237742488766973
+ 0.2120874115856863
+ 0.2028964080744353
+ 0.04566064630909031
+ -0.06389285204871999
+ 0.1158669133379179
+ -0.07485438195467638
+ -0.07265337877706275
+ -0.1705058405414504
+ 0.07519232883401432
+ 0.1138051560296518
+ -0.1563016357246378
+ -0.04385789255021381
+ -0.1160164439433906
+ -0.03769613232459991
+ 0.1767705713716731
+ -0.0563029003721063
+ 0.06358569294818638
+ -0.07699336081058232
+ 0.2111513303382762
+ -0.1106989508568593
+ 0.02360204026244463
+ -0.03494908146075507
+ -0.04116963449027391
+ 0.2216215630311471
+ 0.02908444897091008
+ -0.07156157776660475
+ -0.2366968827800979
+ -0.03163552380653103
+ 0.06905817727794072
+ -0.002536916526160523
+ -0.01466988290168243
+ 0.06242703809006644
+ -0.06243224614138568
+ 0.05271893755065048
+ 0.03307773593364672
+ -0.001177328042041443
+ -0.09278396139545916
+ 0.05035883368350171
+ 0.029819047035332
+ 0.1094461945652439
+ -0.3241135950284725
+ 0.004440857096820299
+ 0.04345434653676448
+ -0.2578424316428754
+ 0.1058005119317326
+ 0.01730233901439584
+ -0.01975958618579435
+ -0.07025976285183216
+ -0.1274311117652878
+ -0.09362778358797785
+ 0.09640837063806885
+ 0.2136431668073824
+ 0.0437555628860183
+ 0.06372522484508009
+ -0.1388022151894868
+ 0.1502159361592025
+ 0.1066471896792283
+ 0.1211316597583722
+ -0.006932933763685157
+ 0.0433171775255522
+ 0.0373504282424748
+ -0.10731333442803
+ 0.1505106288169171
+ -0.05859110059571048
+ -0.1658760038288777
+ -0.1434988650066946
+ -0.07485656307655052
+ -0.05611263479659877
+ -0.03785225140850908
+ -0.2146191449945687
+ -0.3329667488273335
+ -0.01473046367218078
+ -0.2292276084334722
+ -0.04867558711499703
+ -0.01335061491191113
+ -0.09277123822653682
+ 0.008395681804528488
+ -0.03271414188514318
+ -0.1724157876155324
+ 0.07512239612503882
+ -0.1679458986795618
+ 0.05823397020787569
+ -0.001364809187555237
+ 0.05736041145111728
+ -0.003497481747117358
+ 0.06560215237059054
+ 0.06151686689615499
+ -0.05588884299574574
+ -0.1634717399528579
+ 0.03258400693485732
+ -0.06196460148182169
+ 0.04743126116872873
+ 0.02444569123824265
+ 0.2544798947193593
+ -0.1394049754197734
+ -0.1468492562759236
+ 0.1637587461340966
+ -0.004307009767128407
+ 0.1401029151418366
+ -0.0351456964596356
+ -0.05604348444296517
+ 0.1874162088503692
+ 0.3927244262910226
+ 0.0290206574198427
+ 0.1080021675088202
+ -0.1162972538889056
+ -0.0699340844992085
+ -0.1194181050711391
+ 0.2290374918247552
+ -0.02681164614921138
+ 0.02383497831161389
+ 0.06831927803638151
+ -0.008059702069016163
+ 0.06104288327438496
+ -0.04632576978061029
+ -0.2150038743409605
+ 0.06406761077878008
+ -0.03298930021665651
+ -0.0984231714940946
+ 0.01546269795518636
+ -0.3237124964334551
+ 0.1349091243788539
+ 0.05457026197896756
+ 0.05992829615859915
+ -0.1010785172308407
+ 0.1369516495270364
+ -0.01252664320393353
+ 0.07598679622006517
+ -0.1786265303893693
+ -0.1419243011344121
+ 0.01485387875768312
+ -0.6192285232430708
+ -0.04985276818828194
+ 0.001997299065577684
+ -0.02759831723738511
+ -0.3096640531402383
+ 0.01003320099005055
+ -0.02979157180962045
+ -0.1177246713736268
+ 0.00709662118902067
+ -0.2168238201105701
+ -0.3026117749231387
+ 0.02963810853696305
+ 0.05494398422103806
+ 0.02529345646419047
+ -0.07776866290509794
+ 0.07175586594468458
+ 0.1165086935565908
+ 0.06424004949363959
+ 0.1902396429477159
+ 0.02635292144992934
+ 0.1245306728893237
+ 0.08408404293418334
+ -0.08548187456389662
+ -0.04378426766670829
+ -0.0954651786569372
+ -0.08472911189901509
+ -0.08527754766534512
+ 0.1090545784365619
+ 0.1076798762789478
+ 0.04082367620288804
+ -0.02901521821842885
+ -0.1330813856199282
+ -0.1030171681011061
+ -0.0406970532176619
+ -0.2796852145803527
+ 0.06635538073306607
+ -0.0625645705847102
+ -0.09147119235794353
+ 0.07438596014907495
+ 0.1210580719073444
+ 0.104745870946697
+ 0.1702391451066284
+ -0.1320146753106412
+ 0.0299064147546777
+ -0.0595403734608253
+ -0.01278921150453554
+ 0.06103256952223652
+ 0.1882550587124597
+ -0.1343668802104494
+ 0.0631129991253106
+ -0.07934019711958883
+ 0.01201513672380478
+ 0.1172233867072231
+ -0.04947633196342413
+ -0.07870281870516233
+ -0.1435487549226015
+ -0.2575348905012878
+ -0.03798459066131626
+ -0.2727538736801811
+ 0.2484974938214449
+ -0.05795337692219548
+ -0.1999913651242681
+ 0.2522798310967101
+ 0.02698128233420108
+ 0.0833028924986451
+ 0.06649185480315546
+ -0.2411451832821562
+ 0.01633080520325001
+ -0.07609859242188781
+ -0.04247559909162969
+ 0.07738309127212294
+ 0.00338504944113374
+ 0.02759211327553412
+ -0.062832083534875
+ 0.04143828656425674
+ 0.009073018473040258
+ 0.1419465999688319
+ 0.07128105459692202
+ -0.01848987171334482
+ -0.02259148678743529
+ 0.02491359839243191
+ 0.01783047751925651
+ -0.01442395569032092
+ -0.2027928721149563
+ -0.1598159994989173
+ 0.03842714305757287
+ -0.008384169377587621
+ -0.08880299076422628
+ 0.02079037965729929
+ -0.03671362409174479
+ 0.06973205315710705
+ 0.1063069775346068
+ 0.1007176612891763
+ -0.002547602650709032
+ -0.02700922622045116
+ -0.09703937804374069
+ 0.05950753545508661
+ 0.0507485771781551
+ 0.07985287074546485
+ 0.1817836436376768
+ -0.1725753188714505
+ 0.2018124545346996
+ -0.02125262992036267
+ -0.1389955022111425
+ -0.004821234830264484
+ -0.08821775432205033
+ -0.04411838609251255
+ 0.2264100411622824
+ 0.09577882771570714
+ 0.04386820998539865
+ -0.03487017916397868
+ -0.04453788418018581
+ 0.1268747270609243
+ 0.07437212842587976
+ -0.1334871846804367
+ -0.0724059218444012
+ -0.05608205535374374
+ 0.2326132060190554
+ 0.02994092587015976
+ -0.2089556167044889
+ 0.0307205569385052
+ 0.2100329072099038
+ 0.1470463822501148
+ -0.1108473213221753
+ 0.0180421233819202
+ 0.1926915008233758
+ 0.2834135240492412
+ 0.03981386172756802
+ -0.1353756782207221
+ -0.1316357648682679
+ 0.1251917445532366
+ -0.07122199797343048
+ -0.06843443883418815
+ -0.06471799506842645
+ 0.04920451919097584
+ -0.04966553488209532
+ 0.09030407907133559
+ -0.009032101019832373
+ 0.3329343599524694
+ 0.1077140326181361
+ 0.2116763535918749
+ 0.09572090976537226
+ 0.09690546083088047
+ 0.2116609787799568
+ -0.04686920855405804
+ 0.0218607548581237
+ 0.02399391243619535
+ -0.04534593475778261
+ 0.08112859651845519
+ 0.2334446290891323
+ -0.008582300947611097
+ -0.2305722476263238
+ -0.0413794517229276
+ -0.1110155935673876
+ 0.04846596644900134
+ 0.009376670702189865
+ 0.06371692643620697
+ -0.1262177887372313
+ 0.002243370830352344
+ 0.07522925987672718
+ 0.02981543502381082
+ -0.09688900661116427
+ 0.1187022634635514
+ 0.2121937407941616
+ 0.1160820564728878
+ -0.09145826358985815
+ 0.1265546134597996
+ 0.1239288672234961
+ -0.218873561315173
+ 0.06010108458356655
+ 0.09184133777890542
+ -0.0497281833890348
+ -0.0764646030507192
+ -0.05102912514365521
+ 0.02849400911861337
+ -0.05162216662868902
+ 0.1932424320654136
+ 0.1384606059076061
+ -0.08799270097847003
+ -0.1878590814284045
+ 0.04201339478566018
+ -0.0006645564187006181
+ 0.01683382078521371
+ 0.01262715095198261
+ -0.008313080897634438
+ 0.009995652060245303
+ -0.1694766390039859
+ -0.1915939699332303
+ -0.08648825821462656
+ -0.01825769682471006
+ -0.1798777902610145
+ -0.09917221514651982
+ -0.1076235449927981
+ 0.006472931840932583
+ -0.1167483437189565
+ 0.3296695003306915
+ -0.06228780364996593
+ -0.002629600483244642
+ -0.05191930452281279
+ -0.08694977269772103
+ -0.2010664198842678
+ -0.05648442893616653
+ -0.04522512093437937
+ -0.03900233986908162
+ 0.1111104382835447
+ -0.2126954149231985
+ 0.1129761193154164
+ 0.1494508746293761
+ -0.007458460909668881
+ -0.01605879162423225
+ 0.04782514952142372
+ 0.04590636480733407
+ -0.1875383910479731
+ -0.009154183090342357
+ 0.1349569418108101
+ -0.2276526472382224
+ -0.1071252008719458
+ 0.06749302105374287
+ 0.1622229300062252
+ -0.2781852298265187
+ -0.07887328124863414
+ 0.2694692883777759
+ 0.03607529710022215
+ 0.1481183486481567
+ -0.06184326053558836
+ -0.1730417754804224
+ 0.01525077970179209
+ 0.1561405994597077
+ 0.02678032513693529
+ -0.0008197120477443001
+ -0.1530898484847645
+ -0.001847636302208441
+ -0.05110614815450206
+ -0.008266118435312478
+ -0.02473667511525696
+ 0.05569216297511022
+ 0.08004609750215154
+ -0.1350936797929578
+ -0.03104008993202642
+ 0.05254690529371065
+ -0.07021698690263957
+ 0.1619352579102685
+ -0.04774013275971477
+ 0.08923569540698978
+ -0.1007475489639843
+ 0.135776142630528
+ 0.1150462916600388
+ 0.0322451299040322
+ -0.01112626971319132
+ -0.1604373055729276
+ 0.08640957224394968
+ 0.007749845426388811
+ 0.07092711464746372
+ -0.2288341889598747
+ -0.1111153620865373
+ 0.01284950736467663
+ 0.1917962362109962
+ -0.121350989274593
+ -0.1619193800434921
+ 0.009766252230125208
+ -0.2185447500102821
+ 0.06787029563053804
+ 0.05123133944641886
+ 0.1560039184081432
+ -0.008265993533776123
+ 0.05753488765027924
+ -0.08931515682119745
+ 0.1305485552418335
+ 0.08516739237231388
+ 0.04417580277271685
+ -0.2388817817062562
+ 0.01106863756299767
+ 0.05034403890828894
+ 0.06090714841574685
+ 0.07730723735143495
+ 0.1005535179537418
+ 0.04161994673567664
+ 0.1245826338715556
+ 0.02590296946129248
+ -0.008911236072077382
+ -0.1571295891427713
+ -0.06433320918472896
+ 0.06306623391009464
+ 0.02540275442119966
+ 0.3067717439195782
+ -0.1233173904652815
+ -0.2499425266245129
+ -0.1910383963171172
+ -0.06385514171998863
+ 0.03927738558934807
+ -0.2231381271681863
+ 0.07228567902119459
+ 0.04786253900927035
+ -0.06429441538918575
+ 0.1595981778299712
+ 0.08173468092895905
+ 0.09811294770320431
+ 0.2426138303451038
+ -0.05896816906302247
+ 0.08631485452582394
+ 0.1190720926354649
+ 0.02216332510794881
+ 0.08027285957578843
+ 0.2699765960020123
+ 0.1330179192577183
+ -0.0129612182607308
+ -0.06144857440814451
+ 0.1766057604623763
+ 0.3637656530206659
+ -0.1979580496373715
+ -0.1272743278008463
+ -0.07403992269645622
+ -0.1190820717998966
+ -0.05256178829659498
+ -0.01743017925042123
+ 0.1652132477967278
+ -0.08397210979863105
+ 0.08678607625537327
+ 0.2690269233578607
+ 0.004725727569335508
+ 0.03657725758925761
+ 0.03782683317786107
+ -0.01527115734314086
+ -0.03748412659968398
+ -0.05184529043462635
+ -0.08125696378463768
+ -0.2044036502827531
+ -0.02259796832914181
+ 0.2306125846856311
+ -0.05166341912758832
+ 0.1007686765701985
+ 0.02807602496517032
+ 0.195397975895692
+ 0.2477849475429904
+ -0.1578389390132202
+ -0.06778967285660908
+ -0.06310468894237677
+ 0.001152317090581645
+ -0.02847159285392959
+ -0.1644965691415145
+ -0.004422672654226657
+ -0.04582338763658627
+ -0.03368514007381852
+ 0.1036676916041419
+ 0.01633088436745846
+ -0.11428974481109
+ 0.06236689654186239
+ 0.01749034359008914
+ 0.02853137340479905
+ -0.007962212607277726
+ -0.07785215475867532
+ 0.0838684611198631
+ 0.1974969030295401
+ 0.1069244217460556
+ 0.02422108189175057
+ 0.0980456720803683
+ -0.03801602309734344
+ -0.06111899634518623
+ 0.02441623516867221
+ -0.2054311974185093
+ -0.08081305627872575
+ -0.1198518817220182
+ 0.04034362071064586
+ 0.05207350174491301
+ 0.1974377976085911
+ -0.06059255574100417
+ 0.04792259565886958
+ 0.05189266619617966
+ 0.06818538193969763
+ 0.04047283318606913
+ -0.1017936717913432
+ -0.04701905901973118
+ 0.1229816793201596
+ 0.1488015984903939
+ 0.09661098734906357
+ -0.1003106650446885
+ -0.01537647740384916
+ 0.1618204180858531
+ 0.1571893218096157
+ 0.01468400068843958
+ -0.04071898294540913
+ 0.1132891253111955
+ 0.07248743091201217
+ 0.01764528037644025
+ -0.0004762474921353839
+ -0.01498907130076845
+ 0.2068601544100429
+ -0.09063308846716889
+ 0.1941437247094625
+ 0.04467296204639865
+ -0.1302667460292818
+ -0.002833859865354921
+ 0.01285906215180063
+ -0.1416392433865714
+ 0.2047175011079203
+ -0.09382372305655916
+ -0.01313767646168318
+ 0.03970433934773066
+ 0.1328275751432367
+ 0.2134388558663492
+ 0.1225627402109581
+ 0.003451648640815798
+ 0.1401527089620881
+ -0.04527300235533499
+ -0.193054067465438
+ 0.1054238331143912
+ 0.01788711523261599
+ -0.04529521126883883
+ 0.06890198380905398
+ -0.05543757523542746
+ -0.0101991607043735
+ 0.01275825083093947
+ 0.02253753243187137
+ -0.1753126479363099
+ -0.1147822848040538
+ 0.1309585843547272
+ 0.1002556185812181
+ -0.2081086787839297
+ 0.2116069648173263
+ 0.09956651148127987
+ 0.1299743320765888
+ 0.4110092952243196
+ 0.07041684155765403
+ 0.3398905815046785
+ -0.1393176371776856
+ -0.06242973752869357
+ -0.1127541118411364
+ -0.163822215153077
+ -0.07486593810902091
+ -0.08925537517653959
+ -0.02519462318663325
+ -0.1019412998506228
+ 0.07656450942853596
+ 0.1009556665985779
+ -0.1472375712627065
+ -0.1343660250137771
+ -0.07228274980292933
+ -0.04125346885099707
+ 0.05371791686420851
+ 0.03709004327875337
+ -0.02518679780258256
+ 0.01816502010510537
+ -0.09333116525248154
+ -0.1540520976940997
+ -0.009677170015297052
+ 0.1086850257371473
+ -0.04767224853616402
+ -0.07866697277646326
+ -0.1026201482532858
+ -0.1248426643213241
+ -0.1058664708599378
+ 0.004276668663918654
+ 0.07863463576625816
+ 0.1989887810091926
+ -0.008590536044245594
+ -0.1580125299978173
+ 0.06894884671352351
+ -0.06498647477155509
+ -0.02366813942660665
+ 0.01980482410685396
+ 0.06270283885924051
+ -0.2245783208372042
+ 0.0368732303495489
+ 0.112917125763922
+ 0.02303314051507049
+ 0.07390193209570638
+ 0.01927270918394332
+ 0.003167073258190915
+ -0.2345794733410854
+ 0.04019276021469956
+ 0.1500701266292118
+ -0.1738201281370745
+ -0.1746023480455238
+ -0.1668196981209678
+ -0.3168850573353171
+ -0.1396166745089382
+ 0.02248267692289839
+ 0.08597907809480189
+ 0.07027696815144102
+ 0.06889223773757996
+ 0.08333731872108889
+ -0.2542789485294152
+ -0.1705164795265574
+ -0.1979238045369191
+ 0.0092751292395125
+ -0.1320156071506114
+ -0.08554660199135972
+ 0.1188459370298688
+ 0.09836029244114676
+ -0.1638474906793758
+ -0.04079028244245568
+ -0.04407160144056942
+ 0.05152213855672327
+ -0.08458460684698087
+ -0.0396813083410299
+ 0.1486263767638222
+ 0.01916837924119908
+ 0.1336541667410552
+ -0.05778739849011862
+ 0.2143770028388072
+ -0.05090937611490887
+ 0.2051024723887984
+ -0.06596109921606449
+ -0.03671618418312173
+ -0.009633899450427197
+ -0.0502357420293016
+ 0.03869518548670069
+ -0.06588109165496844
+ -0.0002372648040582653
+ -0.1344838837015011
+ 0.08824977120271739
+ 0.02023380208044043
+ -0.2607610166480336
+ -0.1896671057558585
+ -0.1161377337559699
+ 0.1078116990834769
+ -0.2539078495142086
+ 0.1390611389845949
+ 0.03025764989567766
+ 0.2441343358593851
+ -0.06075432376952496
+ 0.1638714927798439
+ 0.08333511621746084
+ 0.139341251156238
+ 0.08122900230200247
+ 0.04010435527965214
+ -0.1361093194232774
+ -0.009581375246758578
+ 0.05835068359510442
+ -0.0167803727525226
+ 0.1069419995219412
+ 0.07813798279419711
+ 0.00305496395478661
+ -0.04170405359485424
+ 0.04552324600228076
+ -0.1193735070676641
+ -0.04913753836685447
+ -0.1279944407660601
+ 0.08368520759372461
+ -0.0870273964516674
+ 0.2925564735493265
+ -0.04436631411929799
+ -0.4325624868472523
+ -0.2779225986835941
+ -0.006550820004269859
+ 0.06060604527500229
+ -0.07038280030614524
+ -0.08319353480795386
+ 0.07136178526293338
+ -0.04339465701308659
+ 0.204003248326082
+ -0.0009487078232958978
+ 0.01870845547751275
+ 0.2031705378869401
+ 0.2365902766993048
+ 0.06877991216878743
+ 0.1016398511557229
+ 0.1673681644207744
+ 0.04321705461509814
+ 0.07449929082525482
+ 0.1817454599348936
+ -0.01135984112934396
+ -0.03818437913488988
+ 0.1582163858452817
+ 0.3811016510116187
+ -0.1252250014542289
+ -0.09631212562334079
+ 0.01818618526493161
+ -0.05960662208571994
+ 0.007359280136234205
+ 0.1871558156783462
+ 0.07312331044671525
+ -0.1456346179766477
+ 0.2446716360324289
+ 0.1719708917792253
+ 0.01491675286930497
+ 0.07521955767763136
+ 0.02916786150315786
+ 0.1304426167592564
+ 0.03797090938346386
+ 0.01617510961590824
+ -0.04975631310943084
+ -0.1480946570044037
+ -0.02668346659829236
+ 0.381378370194814
+ 0.0298177070073709
+ 0.1179477222364818
+ -0.04400525973844824
+ 0.1085493338157537
+ 0.2288621661170312
+ -0.2757981230185004
+ -0.01523755673373449
+ -0.01431038207471042
+ 0.04826549588643518
+ 0.05453267363123064
+ -0.04269700127556757
+ 0.1229262179445883
+ -0.1920533368192765
+ -0.09461837022106229
+ 0.1426896986666275
+ 0.04224060119750231
+ -0.09154617518831577
+ 0.06779175164874031
+ 0.06389501613452804
+ -0.2202272341820416
+ -0.03527323064879302
+ 0.05008681334841851
+ 0.03915929346556274
+ 0.2466306441313898
+ 0.2175487276657447
+ -0.0702961195826572
+ -0.1133769134507895
+ 0.05712035664435332
+ -0.1468854598240673
+ -0.008127726597428714
+ -0.2111387012471612
+ -0.09534085316222254
+ -0.1179715420183408
+ 0.07478770331190493
+ -0.09543178656365206
+ 0.2573332836020102
+ 0.005664329361901663
+ 0.1970935773063416
+ 0.2555708058051488
+ 0.06714732326758449
+ -0.1050173840930746
+ -0.03910728643028964
+ -0.002382239357700849
+ 0.09196459553841493
+ 0.110266208869817
+ 0.02425982130926525
+ 0.09972451984193673
+ -0.05897572466172765
+ 0.0409776957910722
+ 0.01919657049756203
+ 0.09647129033428344
+ -0.04431197213438134
+ -0.05762749156366653
+ -0.1347091145517745
+ -0.01787318326952005
+ -0.1173107653450738
+ 0.09166620389002314
+ 0.2033492586980972
+ -0.02659322882004272
+ 0.3761971232577544
+ 0.1593763850604364
+ -0.2074397253590146
+ -0.2513758703019408
+ -0.06208733697230294
+ 0.1916760986268075
+ 0.4126562927340601
+ -0.1561244013434285
+ 0.02726361886418402
+ -0.06725813452732007
+ 0.1911862300418384
+ 0.1700206863909895
+ 0.1340245065273619
+ -0.05010860352551059
+ 0.1391517181263541
+ -0.05930793627674803
+ -0.306468854568941
+ -0.1765689501858524
+ 0.08174207562970164
+ 0.06599160790298092
+ -0.03493130193206551
+ 0.01347445796216553
+ -0.01652733799502618
+ -0.001956852260735469
+ -0.04080464255465879
+ -0.2103585828885884
+ -0.1368458087668891
+ 0.1210339853543174
+ 0.1849062331186146
+ -0.1678208112269515
+ 0.1336501455703188
+ -0.09033119301686199
+ 0.1588402005151534
+ 0.343835781720269
+ -0.08379391991734822
+ 0.2569230676782887
+ -0.07074417413607342
+ -0.001564406531799668
+ -0.2578841033850046
+ -0.153105248388453
+ -0.1124828554039798
+ -0.1322401275981956
+ -0.04426097420023839
+ -0.09413123070888091
+ 0.07107967680196152
+ -0.02634619189135535
+ -0.2643060713405422
+ -0.01763331333686636
+ -0.1270950852171641
+ -0.1079467603432847
+ 0.1783039333682823
+ 0.1207543271149685
+ -0.05059305161756707
+ 0.0500077937142913
+ 0.009541897202125463
+ -0.124412542234951
+ -0.01147436953372618
+ 0.07693826272523507
+ 0.1620249097734542
+ 0.1157966001753865
+ 0.1147717935299196
+ -0.08408124390959763
+ -0.1293298942019157
+ -0.04242673082866534
+ 0.1186902819058376
+ 0.2224321368384126
+ 0.07696883261632403
+ -0.1631116558892264
+ 0.1767479567279225
+ -0.07840055361446482
+ 0.02839505756422219
+ 0.07383972715911882
+ 0.08187559519447593
+ 0.04680154185353474
+ -0.1435376941711448
+ 0.02382519901674786
+ 0.07071963415796215
+ 0.1762296701831234
+ -0.09299753120355189
+ -0.1322024888472295
+ -0.2312114558839821
+ 0.02016332922095946
+ 0.1035458150369197
+ 0.04342529042108233
+ -0.1750804855071811
+ -0.3194078612121694
+ 0.1141719956452492
+ 0.2464973389765306
+ 0.1501184810740416
+ -0.09359455906567821
+ -0.02378597195736246
+ 0.05800560093682273
+ 0.2130382320837449
+ -0.05056426146108154
+ -0.00822209520044149
+ -0.2433323752339017
+ -0.2233756383058302
+ -0.2122944943525225
+ -0.0952959833859832
+ 0.1597547938803872
+ 0.1362445073546047
+ -0.05701316985566506
+ -0.1461995740541905
+ -0.1376034373361993
+ 0.008042496278329109
+ 0.03077801915443431
+ 0.01444762445200487
+ 0.06989371293157333
+ -0.1195582098625064
+ -0.0539595424483456
+ -0.09423675246358731
+ 0.1698144528273044
+ -0.02756024565984823
+ -0.2882468999634955
+ -0.1311759884758881
+ -0.01558802061199863
+ -0.0224457616778583
+ 0.02907233030836371
+ -0.05395799508370444
+ -0.1899445332674467
+ -0.02311089430760213
+ 0.007302109219061837
+ 0.2752915166647281
+ -0.01532451475347351
+ 0.217851116547316
+ -0.02338133499366784
+ -0.08171995479619482
+ -0.0004791226349764893
+ -0.2444101439153372
+ 0.1714245499183974
+ -0.008866540346702038
+ 0.08737048415801803
+ -0.02644242953561731
+ 0.1111536904065472
+ 0.08042910659688406
+ 0.156509008945293
+ 0.09430289405471341
+ -0.0173655864171539
+ -0.09619637023909541
+ -0.1687358810229567
+ 0.104454167400238
+ 0.1452731087699001
+ 0.1753857178410687
+ 0.04304210489835793
+ 0.09367395935134991
+ -0.1097771960461433
+ 0.09160458976252094
+ -0.1088914195400841
+ -0.01385401475268408
+ -0.08524650642317869
+ 0.08987358524852788
+ -0.155116293477577
+ 0.2141486159536096
+ 0.1492092829071457
+ -0.2873869227907061
+ -0.1694073747984203
+ 0.04449343078728286
+ 0.103115286333767
+ 0.06288168172684462
+ -0.2747744061605801
+ -0.02297056591049465
+ 0.08720444249778733
+ 0.08394416890633438
+ -0.1327623592578852
+ 0.04173458743571703
+ 0.152458237731526
+ 0.3461122323005446
+ -0.002875408825254615
+ -0.03282945612781632
+ 0.1320450754672017
+ 0.02048398137088825
+ -0.09582707087929924
+ 0.2512733449041238
+ 0.05158883104957444
+ -0.1141932960377029
+ 0.1042398783956235
+ 0.4884623213804156
+ -0.05533075061414328
+ -0.1117222866153927
+ 0.005044432789297027
+ -0.05612379379222953
+ 0.06294914832230025
+ 0.1941755675201401
+ 0.07906049237207202
+ -0.1258082157852301
+ 0.2708717596042585
+ -0.09760234025734112
+ -0.03242665155538724
+ 0.1879415201850468
+ 0.002820569798620299
+ 0.2518511716332236
+ 0.0803275582998389
+ 0.03773020974465757
+ -0.06680397033984264
+ 0.1283608406198464
+ 0.04153117115381175
+ 0.2979617105798933
+ -0.03793178634832229
+ -0.003891166632917274
+ -0.04639749128298016
+ 0.1002283441790767
+ 0.1168483832261361
+ -0.2667430533768174
+ -0.01367085281071653
+ 0.1019833281797639
+ 0.1039271660117523
+ -0.03527621991795535
+ -0.04624998419492884
+ 0.2980837918314331
+ -0.2854868315281638
+ -0.1598720881523751
+ 0.0387280564053207
+ 0.03636386449609316
+ 0.1232919644120742
+ 0.02436843026096497
+ 0.105029920398094
+ -0.04958909666485345
+ 0.1571536440104042
+ 0.09413394319090297
+ 0.02778480497282315
+ 0.242970079969737
+ 0.05254355219572528
+ -0.1491449572648123
+ -0.2470931260985709
+ -0.01228434964796932
+ 0.06355811607304208
+ -0.01801595088186521
+ -0.1910898859593492
+ 0.1710955844748312
+ -0.04559702767684875
+ -0.0575111478414921
+ -0.1488699793011382
+ 0.2160837867296408
+ -0.09833048311603559
+ 0.2740762243973532
+ 0.196460202462964
+ -0.04266482443068737
+ -0.2423002631251164
+ 0.1866997313613146
+ 0.05979064644694732
+ -0.01414401353868161
+ 0.08321797256258102
+ -0.06857585315923068
+ 0.1715112604644914
+ -0.0189034493966019
+ -0.07612876755441057
+ -0.04571124698200564
+ -0.02707626665785414
+ -0.06726814877846153
+ -0.07933713540823693
+ -0.2232363880387216
+ -0.1225110647427899
+ -0.07901557311162304
+ -0.2434038726792088
+ 0.04182391231946075
+ 0.02040372413535894
+ 0.2642931236104718
+ 0.065054883743249
+ -0.1934153114319666
+ -0.1062764570509464
+ 0.01285726935331507
+ -0.06215941491929874
+ 0.1678446925262784
+ -0.09865782692429458
+ 0.07530151382627132
+ -0.1013625340775283
+ 0.009583628919469565
+ 0.08935997037860935
+ 0.001550289089127295
+ -0.07335378231021988
+ 0.02747888374533144
+ -0.05307225774444272
+ -0.225229891765628
+ -0.2466469657963566
+ 0.0622060053526241
+ -0.01521296570200277
+ -0.1970300499474153
+ 0.1215176040584392
+ 0.03322006227892838
+ -0.04844281483073029
+ -0.08415868964479693
+ -0.2851960309152597
+ -0.02841991724320317
+ 0.004328912759733721
+ 0.1294844674217196
+ 0.02323963952147449
+ -0.08702828184693133
+ -0.1455058609075093
+ 0.1995832547453136
+ -0.0963625077337103
+ -0.1375888779685707
+ -0.005097603978441743
+ -0.0871715942930449
+ 0.2948677723918121
+ -0.1961953557700017
+ 0.05063085134576723
+ -0.05485224718210201
+ -0.02511095975751573
+ 0.0738554145551166
+ -0.09901626591372396
+ 0.06946042014560544
+ -0.07429564005875608
+ -0.2455272837770868
+ 0.03372532696013532
+ -0.08439936125553943
+ -0.1572832469890588
+ 0.1421293893193454
+ 0.1350828196257556
+ 0.01284495548336082
+ 0.02401257811824288
+ 0.2376645902786213
+ -0.04768422021523566
+ 0.008506985254358865
+ 0.09221586488938285
+ 0.1594568175859658
+ 0.2398227844303611
+ 0.2217887753200039
+ -0.01367038094914552
+ -0.06609246442513816
+ -0.2536997173938265
+ 0.08045561624986598
+ 0.1193326939600289
+ 0.04853212560949158
+ -0.04788513564622857
+ 0.09820725089378556
+ 0.01490145766813217
+ 0.09373763915343922
+ 0.0897072289251121
+ 0.09499907894080312
+ 0.272505682209672
+ -0.2857589771181943
+ 0.005304615118724173
+ 0.05316934366000153
+ 0.01670147793074279
+ -0.1685523439260301
+ -0.1047253643943811
+ -0.2014958780552916
+ -0.01753126891589298
+ 0.04638300742964078
+ 0.1865532167008373
+ -0.1041550692098078
+ -0.2857638552509695
+ -0.8394358504816395
+ 0.3330390755443413
+ 0.173604750818609
+ -0.1949895278003864
+ -0.11034922746134
+ 0.08305215006310965
+ 0.1910586669010612
+ 0.0624507135870807
+ 0.2033769226006744
+ -0.1332893388753211
+ -0.1665040500810019
+ -0.1583995945363945
+ -0.0928760555111864
+ 0.1046645926228185
+ 0.08948613255992462
+ 0.1390079420677361
+ -0.1168928404998971
+ -0.1222877571044974
+ 0.02071735304784578
+ 0.06101889198176324
+ 0.04341097822694753
+ -0.1040487411973801
+ -0.1930880413023381
+ -0.2651315941018598
+ -0.06857898767141712
+ 0.04354947542368268
+ 0.06072415507640783
+ -0.2081057198639228
+ -0.1170660072676494
+ 0.06315832519668199
+ -0.01618372455765315
+ -0.06229440929331015
+ -0.1567795831060125
+ -0.139993917471725
+ 0.06967841651494464
+ -0.01157645040402994
+ 0.2714731163939807
+ -0.09094984260662788
+ 0.1715229016506518
+ 0.1123678629388844
+ -0.0953055252276355
+ -0.2378751782795372
+ 0.01218028128948376
+ 0.1417061355775053
+ -0.09060031938931913
+ 0.03143406610038076
+ 0.06406970945828171
+ 0.00789120192992214
+ 0.08503060820804119
+ 0.06586642608064781
+ 0.01501737721700442
+ -0.05287204124357602
+ -0.04459814410608586
+ -0.2643918429045177
+ 0.08606248389917648
+ 0.2163985425078364
+ 0.2084730316286358
+ -0.009923413481752378
+ 0.1376473206377184
+ -0.1256474104629678
+ 0.1797438248182083
+ -0.0528458399648412
+ 0.06226020372455229
+ 0.007729067427583284
+ -0.08258941472058653
+ -0.1016452553720866
+ -0.003163777303716113
+ 0.1406984451120088
+ 0.06031349150870733
+ -0.03691463724772255
+ 0.105088024901643
+ 0.02358620124652299
+ 0.1201299972636165
+ -0.3475476490803814
+ -0.0742841930401084
+ 0.198497449725175
+ -0.0633362323960646
+ -0.1966852856580519
+ 0.08521942360899989
+ 0.1506537818464838
+ 0.2114699598939301
+ -0.01776267690472441
+ -0.04440858070327856
+ 0.003079306746925076
+ 0.007120375745703148
+ -0.217518055554508
+ 0.2750843488415229
+ 0.03434634955464149
+ -0.1756095706398672
+ 0.03544462957076241
+ 0.4709577299861736
+ -0.02746333873121611
+ -0.08733991476199504
+ 0.04348846502484977
+ -0.02695563459697091
+ 0.1007257842131707
+ 0.2036253770829468
+ 0.05487190823942002
+ 0.05536619806041074
+ 0.131265496918509
+ -0.2545897950563981
+ -0.1813137866248553
+ 0.1644956298879932
+ 0.03406397304977367
+ 0.2742647458265721
+ 0.03612786816975609
+ 0.05366755624078459
+ -0.002242693382883745
+ 0.3077909261259039
+ 0.07480294633403545
+ 0.1038367356579036
+ -0.05317065623529878
+ -0.03449087402103904
+ 0.06688730844735781
+ -0.02575597697681738
+ 0.03044747743062777
+ -0.1353819500594901
+ 0.002417498432139633
+ 0.1101825131866615
+ 0.0919828128933208
+ -0.1439948250968756
+ -0.1047273023889282
+ 0.166282388944002
+ -0.2020929261190566
+ -0.107451519642646
+ -0.05634226151267367
+ -0.01853034273477917
+ 0.1817293184379292
+ -0.003283480805546549
+ 0.03667594122847624
+ -0.06916593471154825
+ 0.307169001970326
+ 0.02469560769794513
+ 0.09469772985034791
+ 0.1867527749713585
+ -0.1230908802114091
+ -0.1909553472482549
+ -0.2204450052591909
+ -0.07092543100988956
+ 0.2294652216754263
+ 0.03816382623221562
+ -0.009400920012224982
+ 0.1915875431217992
+ 0.01820930314708271
+ -0.0619969906367219
+ -0.1565322933149482
+ 0.1157588638822702
+ -0.1751806538241918
+ 0.2295575250339776
+ -0.05884628955432975
+ -0.1097375186682496
+ -0.1781749429765534
+ 0.2162688496726471
+ 0.0225355614780918
+ -0.07849648776723586
+ -0.01547965292772258
+ -0.1153197350031277
+ 0.07895824076700365
+ 0.05065324858367866
+ -0.1085494286285821
+ -0.0379692199225021
+ -0.09879446437686498
+ -0.1253687360897433
+ -0.04399958723243259
+ -0.1327717233439862
+ -0.1891844271346936
+ 0.1365897278433574
+ -0.4072177659113166
+ -0.1423190421710968
+ 0.002569210771690537
+ 0.2874981836456109
+ -0.0451481065719694
+ -0.1254153236881238
+ 0.1173968851598019
+ 0.02373553294657881
+ 0.3662965379428074
+ 0.3346136570276884
+ -0.05717662342641277
+ 0.03293252356079885
+ -0.02784304467878897
+ -0.09214284097721631
+ -0.002668431416544305
+ -0.1347840225293861
+ -0.03883720970638058
+ 0.0002532185932718686
+ -0.04818120634933561
+ -0.2334561183354495
+ -0.1592639424552839
+ 0.02857859370708266
+ -0.1001967303563061
+ -0.1363043656655723
+ 0.1162742307337141
+ 0.06110858262281978
+ -0.04375289436171732
+ 0.0002603326247158308
+ -0.2556094979182465
+ 0.001616731568954928
+ -0.04893769491895026
+ 0.0963305594616868
+ 0.1536209272985045
+ -0.1935464003918078
+ -0.09095698386345863
+ 0.1534695823746832
+ -0.2571331879374995
+ -0.03247827224784545
+ -0.2176747306769753
+ -0.08464400767846247
+ 0.369657359737719
+ -0.02603595411742499
+ 0.1063412520548481
+ 0.004150612307143683
+ 0.1239008337604071
+ 0.1628892741047316
+ -0.07768359672987041
+ 0.06108909165579486
+ 0.003405857181209642
+ -0.07765376042059041
+ 0.003320485950160026
+ -0.01086861632902177
+ -0.122078218606576
+ 0.02393691286549908
+ 0.06713997366639572
+ 0.08898611607835161
+ -0.02379243913273671
+ 0.2949912814331299
+ 0.1350614374648974
+ 0.04881340104260548
+ 0.1313005175892898
+ -0.05043049072684099
+ 0.1997599225730803
+ 0.1331853724035849
+ 0.03310678334263119
+ -0.09492731892301552
+ 0.03823474521755243
+ -0.004415351525256783
+ 0.112180980330195
+ -0.03234104256631049
+ 0.1472018282967266
+ -0.09018514576631975
+ 0.07544746126523917
+ 0.1166113632468761
+ 0.08275494188757555
+ 0.07278778610114685
+ 0.2597969514123001
+ -0.1841205434537519
+ 0.06788021895957397
+ 0.002852335989421522
+ -0.2493773200438772
+ -0.1500862029925856
+ 0.03890592159244441
+ -0.07527513568205077
+ -0.0309070538452651
+ -0.0298841983279069
+ 0.1440875574115637
+ -0.05018906262328114
+ -0.06025221539547261
+ 0.21401768860684
+ 0.1493930142401384
+ 0.1333652585828323
+ -0.1644513860689316
+ -0.1073181293398727
+ 0.1917320319030454
+ 0.04211720043513827
+ -0.03325617410057424
+ 0.2358847962085744
+ -0.05531576552570384
+ 0.05270157556976172
+ -0.02204619127250945
+ -0.05606127005459256
+ 0.02982912792683756
+ -0.02712518468388254
+ 0.2952018668094087
+ -0.009964997687088591
+ -0.03046183918404762
+ 0.04857529176171757
+ 0.03043983288723968
+ 0.01194376398546001
+ -0.2067805618562731
+ -0.1427842314855997
+ -0.2869698997130766
+ -0.01754440457903484
+ -0.1189582216535462
+ 0.2111332403638705
+ -0.03105682135869399
+ -0.04749585051152591
+ 0.0946820396112875
+ -0.02623963438519194
+ -0.2913698748998487
+ -0.2527033466974923
+ -0.01292672680845454
+ 0.167227040710764
+ -0.1118497216760054
+ 0.1373157790798296
+ -0.1064750291744089
+ 0.25052084295729
+ 0.02332718041178225
+ -0.07064340503825219
+ -0.3456836491069989
+ 0.1611961252647666
+ 0.08760562437004332
+ -0.1662756750750775
+ 0.0526247766559812
+ 0.02529274647444501
+ -0.09326957765490271
+ 0.03959060965422974
+ -0.1348052647751649
+ -0.1002186676596551
+ -0.01269827705926385
+ -0.02411956016849976
+ -0.262654857829906
+ 0.02634585573229658
+ 0.03059574017434615
+ 0.1334453440583568
+ -0.1095658904969446
+ 0.1653660058320955
+ -0.1136809261605006
+ 0.1428038840878058
+ -0.05498598280404418
+ 0.2294913039841647
+ 0.03080683617387336
+ -0.3096504146489982
+ 0.05558356921026913
+ -0.2264985011241068
+ 0.03556299064781845
+ 0.3678144671983024
+ 0.0751761179683321
+ 0.08152764270123794
+ -0.06493472510581649
+ 0.1304829098615351
+ -0.1963527938965993
+ -0.07529733889630785
+ 0.1800076492009783
+ -0.1542377218219825
+ -0.1451314883212949
+ 0.08344166652972178
+ 0.05291208484804868
+ -0.007913258494954755
+ -0.03039124200121655
+ 0.04152829385599959
+ -0.07994400191575796
+ -0.02694551195409341
+ -0.2792023304016716
+ 0.182922872568378
+ -0.04793443758820662
+ -0.1988501180364287
+ -0.02313241602466044
+ 0.3806790349750098
+ -0.1087354764359422
+ -0.0235633636573383
+ 0.05543209692211608
+ -0.01119442471601603
+ 0.1495509220089313
+ 0.1731985277075746
+ 0.02608732062190484
+ 0.2286027832429134
+ -0.06109695995265021
+ -0.2236285563540323
+ -0.1926920427073123
+ -0.03794520281908435
+ 0.1075356138273536
+ 0.1363843578238267
+ 0.05236801337224944
+ 0.07315242602667636
+ 0.09120667067391078
+ 0.2673917413667651
+ -0.04928426751819683
+ -0.1242584633656258
+ -0.07351478269641104
+ 0.003555001656605677
+ 0.1865312501760474
+ -0.2478980546448966
+ 0.03891423303705837
+ 0.09271232658029689
+ 0.09990992167686555
+ 0.04975465166628711
+ 0.06237688864617102
+ -0.1618745567144718
+ -0.2072815728074243
+ 3.24320887345834e-05
+ -0.009324489084374568
+ 0.02516269431032846
+ -0.05100859800583433
+ -0.0671930965950919
+ -0.02951213277188766
+ -0.06777233683864496
+ -0.09339641768732099
+ -0.1972348870531456
+ 0.3439146165567926
+ -0.04434332484378644
+ 0.2407616698867662
+ 0.07362486219683421
+ -0.2782920205084793
+ -0.0877032592308811
+ -0.06949037920661379
+ -0.05722336869839895
+ 0.3020109799810665
+ 0.1845736443705813
+ 0.1639268362941793
+ 0.0007454141494778137
+ 0.1011307220756484
+ 0.05352505760522216
+ -0.1124356121406138
+ -0.006314398380578822
+ -0.1817709975861904
+ 0.07690033839008623
+ -0.06109448276466303
+ -0.1022404490233799
+ -0.02667620582706734
+ 0.09629110625137843
+ -0.02431260261297468
+ -0.07644195566754071
+ -0.1186587514424158
+ -0.1011749903692891
+ -0.1564408651720882
+ 0.08805601365843475
+ -0.07064913600645135
+ -0.02635840998600408
+ -0.1078314746964917
+ -0.1709695145951056
+ 0.01479845069411982
+ -0.01381638575244491
+ -0.1550512932185826
+ 0.2503777385827729
+ -0.2390248644176812
+ -0.2883893597409654
+ -0.06181291307901987
+ 0.1582364175796699
+ -0.02312071621553637
+ 0.00217638563547544
+ 0.3237854977363662
+ -0.03252544620611295
+ 0.003750133894739771
+ 0.009671642707881114
+ -0.009497472747113498
+ 0.07116666910192301
+ 0.08816537960315252
+ -0.06363471414932657
+ -0.09448929109059846
+ -0.1838435758631711
+ 0.03492670834095708
+ 0.04311774220442871
+ 0.01678837491608537
+ -0.08551317416391886
+ 0.01579603526355288
+ 0.04714940819834743
+ -0.06812683188087337
+ 0.04021687008946623
+ 0.06658770294854371
+ 0.04200650408334704
+ 0.02648272347175153
+ 0.1171065218544724
+ -0.1580241793274017
+ -0.04345466645506941
+ -0.05306499481440482
+ 0.07072616774249532
+ 0.2393715380477287
+ -0.1142803782761256
+ 0.007919304164271446
+ 0.03903245447045534
+ -0.1972537874679361
+ 0.1808024692666788
+ -0.1496471578524902
+ -0.03601188242560322
+ 0.2450678955523587
+ 0.1267384878365154
+ -0.01909164755778832
+ 0.01601852906118508
+
+
diff --git a/codec2/branches/0.7/octave/vq_pager.m b/codec2/branches/0.7/octave/vq_pager.m
new file mode 100644 (file)
index 0000000..f00de9e
--- /dev/null
@@ -0,0 +1,47 @@
+% vq_pager.m
+%
+% Interactive Octave script to inspect vectors, e.g. for newamp1.m vector quantisation
+%
+% Usage:
+%
+%   octave:14> vq_pager(vq)
+
+function vq_pager(vq)
+  grid_sz = 4;
+
+  [vq_rows vq_cols] = size(vq);
+  
+  r = 1;
+
+  % Keyboard loop 
+
+  k = ' ';
+  do 
+    figure(1); clf;
+    n_plot = min(grid_sz*grid_sz,vq_rows-r+1)
+    printf("r: %d n_plot: %d\n", r, n_plot);
+    for i = 1:n_plot;
+      subplot(grid_sz,grid_sz,i);
+      plot(vq(r+i-1,:));
+      axis([1 vq_cols -20 20]);
+    end
+
+    % interactive menu 
+
+    printf("\rr: %d  menu: n-next  b-back  q-quit", r);
+    fflush(stdout);
+    k = kbhit();
+
+    if k == 'n'
+      r = r + grid_sz*grid_sz;
+      r = min(r, vq_rows);
+    endif
+    if k == 'b'
+      r = r - grid_sz*grid_sz;
+      r = max(r,1);
+    endif
+  until (k == 'q')
+  printf("\n");
+
+endfunction
+
diff --git a/codec2/branches/0.7/octave/xormixer.m b/codec2/branches/0.7/octave/xormixer.m
new file mode 100644 (file)
index 0000000..c8caf79
--- /dev/null
@@ -0,0 +1,37 @@
+% xormixer.m
+% David Rowe Sep 2015
+%
+% Testing xor gate as a mixer for constant amplitude
+% modulation schemes
+
+n = 1024;
+carrier = modulation = zeros(1,n);
+
+Tc = 4; % carrier period
+for i=1:Tc:n
+  carrier(i:i+Tc/2-1) = 1;
+end
+
+Tm = 32; % modulation signal period
+for i=1:Tm:n
+  modulation(i:(i+Tm/2-1)) = 1;
+end
+
+%carrier = carrier .* hanning(n)';
+%modulation = modulation .* hanning(n)';
+mixer = xor(carrier,modulation) .* hanning(n)';
+
+figure(1);
+clf
+subplot(311)
+plot(abs(fft(carrier)))
+axis([1 n 0 n/2]);
+
+subplot(312)
+plot(abs(fft(modulation)))
+axis([1 n 0 n/2]);
+
+subplot(313)
+plot(abs(fft(mixer)))
+axis([1 n 0 n/2]);
+
diff --git a/codec2/branches/0.7/octave/yafsk.m b/codec2/branches/0.7/octave/yafsk.m
new file mode 100644 (file)
index 0000000..d38169c
--- /dev/null
@@ -0,0 +1,664 @@
+% yafsk.m
+% Yet-another-FSK
+% Brady O'Brien 20 October 2015
+%
+% This is a model for the first attempt at a C FSK modem. Based on fsk_horus and maybe a little fsk4.
+% First revision will just be 2fsk
+% [x] - Modem init and struct def
+% [x] - Direct SDR modulator, probably not FM based
+% [x] - Direct SDR non-coherent demodulator
+%    [x] - Core demodulation routine
+%    |o| - Timing offset estimation
+%    < >- Freq. offset estimation
+%    (+) - Bit slip, maybe
+% { } - Port sim from fsk_horus
+% [ ] - The C port
+% [ ] - Some stuff to verify the C port
+% [ ] - 4FSK variant
+%    ( ) - All of that other stuff, but for 4fsk
+%clear all;
+
+graphics_toolkit('gnuplot');
+%fm
+
+pkg load signal;
+
+%Basic parameters for a simple FSK modem
+fsk_setup_info.Rs = 4800;  % Symbol rate
+fsk_setup_info.nfsk = 2;      % Number of unique symbols. Must be 2.
+fsk_setup_info.P = 5;          %Something something fine timing est
+fsk_setup_info.Fs = 48000; % Sample frequency
+fsk_setup_info.timing_syms = 10; %How many symbols over which to figure fine timing
+fsk_setup_info.Fsym = fsk_setup_info.Rs; %Symbol spacing
+fsk_setup_info.txmap = @(bits) bits+1; %Map TX bits to 2fsk symbols
+fsk_setup_info.rxmap = @(syms) syms==1; %Map 2fsk RX symbols to bits
+global fsk_setup = fsk_setup_info
+
+function states = yafsk_init(fsk_config)
+  Fs = states.Fs = fsk_config.Fs;
+  Rs = states.Rs = fsk_config.Rs;
+  nfsk = states.nfsk = fsk_config.nfsk;
+  Ts = states.Ts = Fs/Rs;
+  Fsym = states.Fsym = fsk_config.Fsym;
+  states.config = fsk_config;
+  P = states.P = fsk_config.P;
+  timing_syms = states.timing_syms = fsk_config.timing_syms;
+  
+  if nfsk != 2
+    error("Gotta be 2fsk")
+  endif
+  %Symbol frequencies. Fixed to intervals of Fsym.
+  states.fsyms = [-(Fsym/2) (Fsym/2)];
+  states.tx_phase = 0;
+
+  states.dc = zeros(1,nfsk);
+  states.rx_phi = ones(1,nfsk);
+  states.isamp = 0;
+  states.ssamp = 0;
+  states.sums = zeros(1,nfsk);
+  states.ssums = zeros(1,nfsk);
+  timing_db1 = timing_db2 = zeros(1,timing_syms*(Ts/P))
+  states.timing_db1 = timing_db1;
+  states.timing_db2 = timing_db2;
+endfunction
+
+function [tx states] = yafsk_mod(states,bits)
+  Ts = states.Ts;
+  Fs = states.Fs;
+  fsyms = states.fsyms;
+  tx_phase = states.tx_phase;
+  %Map bits into symbols
+  syms = states.config.txmap(bits);
+  tx = zeros(1,Ts*length(syms));
+  
+  for ii = (1:length(syms))
+    cur_sym_f = fsyms(syms(ii));
+    tx_phase_i = tx_phase;
+    for jj = (1:Ts)
+        tx_phase_i = tx_phase + jj*2*pi*cur_sym_f/Fs;
+        tx((ii-1)*Ts+jj) = exp(j*tx_phase_i);   
+    end
+    tx_phase = tx_phase + Ts*2*pi*cur_sym_f/Fs;
+    if tx_phase>2*pi
+        tx_phase = tx_phase-2*pi;
+    elseif tx_phase<-2*pi
+        tx_phase = tx_phase+2*pi;
+    endif
+    %tx_phase_vec = tx_phase + (1:Ts)*2*pi*cur_sym_f/Fs;
+    %tx((ii-1)*Ts+1:ii*Ts) = exp(j*tx_phase_vec);
+  end
+  states.tx_phase = tx_phase;
+endfunction
+
+function d = idmp(data, M)
+    d = zeros(1,length(data)/M);
+    for i = 1:length(d)
+      d(i) = sum(data(1+(i-1)*M:i*M));
+    end
+endfunction
+
+function [bits states phis softsyms] = yafsk_demod_2a(states,rx)
+  fine_timing = 1;
+  Fs = states.Fs;
+  Rs = states.Rs;
+  Ts = states.Ts;
+  nfsk = states.nfsk;
+  P = 5;
+
+
+  phy_f1 = states.rx_phi(1);
+  phy_f2 = states.rx_phi(2);
+
+  dphase_f1 = exp(states.fsyms(1)*-j*2*pi/Fs);
+  dphase_f2 = exp(states.fsyms(2)*-j*2*pi/Fs);
+
+  sum_f1 = states.sums(1);
+  sum_f2 = states.sums(2);
+  
+  ssum_f1 = states.ssums(1);
+  ssum_f2 = states.ssums(2);
+  
+  timing_db1 = states.timing_db1;
+  timing_db2 = states.timing_db2;
+  
+  ssamp = states.ssamp;
+  isamp = states.isamp;
+  
+  symcnt = 1;
+  subcnt = 1;
+  syms = [0];
+  softsyms = [0];
+  sums1 = [0];
+  sums2 = [0];
+  phis = [0];
+  isamp = 1;
+  isub = 1;
+
+  ssum_f1 = 0;
+  ssum_f2 = 0;
+  ssamp=0;
+  timing_syms = states.timing_syms;
+  timing_nudge = .09; %How far to 'nudge' the sampling point
+                      %This really ought to be fixed somewhere else
+                      
+  timing_samps = timing_syms*(Ts/P);
+
+  for ii = (1:length(rx))
+    phy_f1 *= dphase_f1;   %Spin the oscillators
+    phy_f2 *= dphase_f2;
+
+    dcs_f1 = rx(ii)*phy_f1; %Figure out the DC
+    dcs_f2 = rx(ii)*phy_f2;
+
+    sum_f1 += dcs_f1; %Integrate
+    sum_f2 += dcs_f2;
+    ssum_f1 += dcs_f1;
+    ssum_f2 += dcs_f2;
+
+
+    %Frequency of timing tracking nonlinearity
+    w = (2*pi*Rs)/(Rs*P);
+
+    %increment symbol and timing sub-loop counters
+    ssamp += 1;
+    isamp += 1;
+    if isamp>=Ts %If it's time to take a sample and spit out a symbol..
+      syms(symcnt) = (abs(sum_f1)>abs(sum_f2))+1; %Spit out a symbol
+      softsyms(symcnt) = abs(sum_f1) - abs(sum_f2);
+      symcnt += 1;
+      
+      %Fine timing estimation and adjustment
+      %Re-integrate over entire symbol peiod and apply nonlinearity
+      %To-do - rewrite in more c-able loop
+      timing_phi = 0;
+      for jj=(1:(length(timing_db1)-P))
+           f1 = sum(timing_db1(jj:jj+P)); 
+        f2 = sum(timing_db2(jj:jj+P));
+        tdmd = (abs(f1)-abs(f2))^2; 
+        timing_phi += tdmd*exp(-j*w*jj);
+      end
+      
+      %Take angle of nonlinear spectral line
+      timing_phi = angle(timing_phi);
+      %get another number
+      norm_phi = timing_phi/(2*pi);
+      norm_timing = norm_phi*P;
+      
+      %Ideal fine timing point, determined experimentally
+      norm_tgt = -1.37;
+      
+      %move sampling point a bit forward or backward
+      if(norm_timing>norm_tgt && norm_timing<norm_tgt+2.5)
+          isamp += timing_nudge;
+          ssamp += timing_nudge;
+      else
+          isamp -= timing_nudge;
+          ssamp -= timing_nudge;
+      endif
+      
+      %save timing for debugging
+      phis(symcnt) = norm_timing;
+      
+      sum_f1 = 0;    %Reset integrators
+      sum_f2 = 0;
+      isamp -= Ts;    %Reset integrator count
+     
+      if(mod(symcnt,10000)==0)
+        ab_f1 = abs(phy_f1)
+        phy_f1 = phy_f1/ab_f1;
+        ab_f2 = abs(phy_f2)
+        phy_f2 = phy_f2/ab_f2;
+         endif
+
+    endif
+
+    if ssamp>= (Ts/P)
+    
+      %save timing samples
+      timing_db1(1:timing_samps-1)=timing_db1(2:timing_samps);
+      timing_db1(timing_samps) = ssum_f1;
+      timing_db2(1:timing_samps-1)=timing_db2(2:timing_samps);
+      timing_db2(timing_samps) = ssum_f2;
+
+
+      %Reset integrators and sampling counter
+      ssum_f1 = 0; 
+      ssum_f2 = 0;
+      ssamp -= Ts/P; 
+    endif
+
+  end
+
+  states.rx_phy(1) = phy_f1;
+  states.rx_phy(2) = phy_f2;
+  states.sums(1) = sum_f1;
+  states.sums(2) = sum_f2;
+
+  states.ssum(1) = ssum_f1;
+  states.ssum(2) = ssum_f2;
+
+  states.ssamp = ssamp;
+  states.isamp = isamp;
+  
+  states.timing_db1 = timing_db1;
+  states.timing_db2 = timing_db2;
+
+  bits = states.config.rxmap(syms);
+  
+  
+endfunction
+
+
+function [bits states] = yafsk_demod_2(states,rx)
+  fine_timing = 1;
+  Fs = states.Fs;
+  Rs = states.Rs;
+  Ts = states.Ts;
+  nfsk = states.nfsk;
+
+  rx = rx(fine_timing:length(rx));
+  sym_phases = (1:length(rx)).*rot90(states.fsyms)*2*pi/Fs;
+
+  sym_mixers = exp(-j*sym_phases);
+  rx_mixd = repmat(rx,nfsk,1).*sym_mixers;
+  
+  dc1 = abs(idmp(rx_mixd(1,1:length(rx_mixd)),Ts));
+  dc2 = abs(idmp(rx_mixd(2,1:length(rx_mixd)),Ts));
+
+  t=(1:length(dc1));
+  
+  plot(t,dc1,t,dc2)
+
+endfunction
+
+% Simulation thing, shamelessly taken from fsk_horus.m
+% simulation of tx and rx side, add noise, channel impairments ----------------------
+
+function run_sim
+  global fsk_setup;
+  frames = 10;
+  EbNodB = 26;
+  timing_offset = 0.0; % see resample() for clock offset below
+  test_frame_mode = 2;
+  fading = 0;          % modulates tx power at 2Hz with 20dB fade depth, 
+                       % to simulate balloon rotating at end of mission
+  df     = 0;          % tx tone freq drift in Hz/s
+
+  more off
+  rand('state',100); 
+  randn('state',100);
+  states = yafsk_init(fsk_setup);
+  N = states.N;
+  %P = states.P;
+  Rs = states.Rs;
+  nsym = states.nsym = 4096;
+  Fs = states.Fs;
+  states.df = df;
+
+  EbNo = 10^(EbNodB/10);
+  variance = states.Fs/(states.Rs*EbNo);
+
+  % set up tx signal with payload bits based on test mode
+
+  if test_frame_mode == 1
+     % test frame of bits, which we repeat for convenience when BER testing
+    test_frame = round(rand(1, states.nsym));
+    tx_bits = [];
+    for i=1:frames+1
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+  if test_frame_mode == 2
+    % random bits, just to make sure sync algs work on random data
+    tx_bits = round(rand(1, states.nsym*(frames+1)));
+  end
+  if test_frame_mode == 3
+    % ...10101... sequence
+    tx_bits = zeros(1, states.nsym*(frames+1));
+    tx_bits(1:2:length(tx_bits)) = 1;
+  end
+
+  if test_frame_mode == 4
+
+    % load up a horus msg from disk and modulate that
+
+    test_frame = load("horus_msg.txt");
+    ltf = length(test_frame);
+    ntest_frames = ceil((frames+1)*nsym/ltf);
+    tx_bits = [];
+    for i=1:ntest_frames
+      tx_bits = [tx_bits test_frame];
+    end
+  end
+
+  tx = yafsk_mod(states, tx_bits);
+
+  %tx = resample(tx, 1000, 1001); % simulated 1000ppm sample clock offset
+
+  if fading
+     ltx = length(tx);
+     tx = tx .* (1.1 + cos(2*pi*2*(0:ltx-1)/Fs))'; % min amplitude 0.1, -20dB fade, max 3dB
+  end
+
+  noise = sqrt(variance)*randn(length(tx),1);
+  rx    = tx + noise;
+  
+  % dump simulated rx file
+  ftx=fopen("ya_fsk_rx.raw","wb"); rxg = rx*1000; fwrite(ftx, rxg, "short"); fclose(ftx);
+
+  timing_offset_samples = round(timing_offset*states.Ts);
+  st = 1 + timing_offset_samples;
+  rx_bits_buf = zeros(1,2*nsym);
+  Terrs = Tbits = 0;
+  state = 0;
+  x_log = [];
+  norm_rx_timing_log = [];
+  nerr_log = [];
+  f1_int_resample_log = [];
+  f2_int_resample_log = [];
+  f1_log = f2_log = [];
+  EbNodB_log = [];
+  rx_bits_log = [];
+  rx_bits_sd_log = [];
+
+  for f=1:frames
+
+    % extract nin samples from input stream
+
+    nin = states.nin;
+    en = st + states.nin - 1;
+    sf = rx(st:en);
+    st += nin;
+
+    % demodulate to stream of bits
+
+    [rx_bits states] = yafsk_demod(states, sf);
+    rx_bits_buf(1:nsym) = rx_bits_buf(nsym+1:2*nsym);
+    rx_bits_buf(nsym+1:2*nsym) = rx_bits;
+    rx_bits_log = [rx_bits_log rx_bits];
+    rx_bits_sd_log = [rx_bits_sd_log states.rx_bits_sd];
+
+    norm_rx_timing_log = [norm_rx_timing_log states.norm_rx_timing];
+    x_log = [x_log states.x];
+    f1_int_resample_log = [f1_int_resample_log abs(states.f1_int_resample)];
+    f2_int_resample_log = [f2_int_resample_log abs(states.f2_int_resample)];
+    f1_log = [f1_log states.f1];
+    f2_log = [f2_log states.f2];
+    EbNodB_log = [EbNodB_log states.EbNodB];
+
+    % frame sync based on min BER
+
+    if test_frame_mode == 1
+      nerrs_min = nsym;
+      next_state = state;
+      if state == 0
+        for i=1:nsym
+          error_positions = xor(rx_bits_buf(i:nsym+i-1), test_frame);
+          nerrs = sum(error_positions);
+          if nerrs < nerrs_min
+            nerrs_min = nerrs;
+            coarse_offset = i;
+          end
+        end
+        if nerrs_min < 3
+          next_state = 1;
+          %printf("%d %d\n", coarse_offset, nerrs_min);
+        end
+      end
+
+      if state == 1  
+        error_positions = xor(rx_bits_buf(coarse_offset:coarse_offset+nsym-1), test_frame);
+        nerrs = sum(error_positions);
+        Terrs += nerrs;
+        Tbits += nsym;
+        nerr_log = [nerr_log nerrs];
+      end
+
+      state = next_state;
+    end
+  end
+
+  if test_frame_mode == 1
+    printf("frames: %d Tbits: %d Terrs: %d BER %4.3f\n", frames, Tbits, Terrs, Terrs/Tbits);
+  end
+
+  if test_frame_mode == 4
+    extract_and_print_packets(states, rx_bits_log, rx_bits_sd_log)
+  end
+
+  figure(1);
+  plot(f1_int_resample_log,'+')
+  hold on;
+  plot(f2_int_resample_log,'g+')
+  hold off;
+
+  figure(2)
+  clf
+  m = max(abs(x_log));
+  plot(x_log,'+')
+  axis([-m m -m m])
+  title('fine timing metric')
+
+  figure(3)
+  clf
+  subplot(211)
+  plot(norm_rx_timing_log);
+  axis([1 frames -1 1])
+  title('norm fine timing')
+  subplot(212)
+  plot(nerr_log)
+  title('num bit errors each frame')
+
+  figure(4)
+  clf
+  plot(real(rx(1:Fs)))
+  title('rx signal at demod input')
+
+  figure(5)
+  clf
+  plot(f1_log)
+  hold on;
+  plot(f2_log,'g');
+  hold off;
+  title('tone frequencies')
+  axis([1 frames 0 Fs/2])
+
+  figure(6)
+  clf
+  plot(EbNodB_log);
+  title('Eb/No estimate')
+
+endfunction
+
+% Bit error rate test ----------------------------------------------------------
+% Params - aEsNodB - EbNo in decibels
+%        - timing_offset - how far the fine timing is offset
+%        - bitcnt - how many bits to check
+%        - demod_fx - demodulator function
+% Returns - ber - teh measured BER
+%         - thrcoh - theory BER of a coherent demod
+%         - thrncoh - theory BER of non-coherent demod
+function [ber thrcoh thrncoh rxphis] = nfbert_2(aEsNodB,modem_config, bitcnt=12000, timing_offset = 1, freq_offset = 0, burst = 0,samp_clk_offset = 0)
+
+  rand('state',1); 
+  randn('state',1);
+  
+  %How many bits should this test run?
+  %bitcnt = 12000;
+  
+  framesync = []
+  framehdr = [1 0 1 0 1 0 1 0 0 1 1 1 0 1 0 0]
+  convhdr = framehdr;%[.5 -.5 .5 -.5 1 -1 1 -1 -1 1 1 1 -1 1 -1 -1];
+  %framehdr = [1 0 1 0 0 0 1 0 1 0 0 1]
+  test_bits = [framesync framehdr (rand(1,bitcnt)>.5)]; %Random bits. Pad with zeros to prime the filters
+  states.M = 1;
+  states = yafsk_init(modem_config);
+  
+  %Set this to 0 to cut down on the plotting
+  states.verbose = 1; 
+  Fs = states.Fs;
+  Rb = states.Rs;  % Multiply symbol rate by 2, since we have 2 bits per symbol
+  
+  tx = yafsk_mod(states,test_bits);
+
+  tx = resample(tx, 1000, 1000 + samp_clk_offset);
+  
+  %simulate a single frame in a pool of noise
+  if(burst)
+    tx = [zeros(1,Fs/2) tx zeros(1,Fs/2)];
+  end
+
+
+  %add noise here
+  %shamelessly copied from gmsk.m
+  EsNo = 10^(aEsNodB/10);
+  EbNo = EsNo
+  variance = Fs/(Rb*EbNo);
+  nsam = length(tx);
+  noise = sqrt(variance/2)*(randn(1,nsam) + j*randn(1,nsam));
+  rx    = tx*exp(j*pi/2) + noise;
+  t = (1:length(rx));
+  rx    = rx .* exp(t*2*pi*j*(freq_offset/Fs));
+  
+  rx    = rx(timing_offset:length(rx));
+  
+  [rx_bits states rxphis sbits] = yafsk_demod_2a(states,rx);
+  
+  
+  ber = 1;
+  
+  hsig = -1*fliplr((framehdr*2)-1);
+  figure(3);
+  corrfd = conv(hsig,sbits);
+  for ii = (1:length(corrfd)-length(hsig))
+    secte = sum(abs(sbits(ii:ii+length(hsig))).^2);
+       corrfd = corrfd(ii)/secte;
+  end
+  %thing to account for offset from input data to output data
+  %No preamble detection yet
+  figure(4);
+  plot(rxphis);
+  ox = 1;
+  
+  if(burst)
+    orange = (1:length(rx_bits)-length(test_bits)-1);
+  else
+    orange = (1:100)
+  end
+  for offset = orange
+    if(burst)
+      perr = xor(test_bits,rx_bits(offset:offset-1+length(test_bits)));
+      nerr = sum(perr);
+      bern = nerr / length(test_bits);
+       else
+         perr = xor(test_bits(offset:length(rx_bits)),rx_bits(1:length(rx_bits)+1-offset));
+      nerr = sum(perr);      
+      bern = nerr/(bitcnt-offset);
+    end
+    
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+      xerr = perr;
+    end
+    ber = min([ber bern]);
+  end
+  
+  %Try to find frame header
+  for offset = (1:length(rx_bits)-length(framehdr))
+       hd = sum(xor(framehdr,rx_bits(offset:offset-1+length(framehdr))));
+       if(hd<=2)
+               printf("Found possible header at offset %d\n",offset);
+       endif
+  end
+  
+  figure(5);
+  stairs(1.0*xerr);
+  
+  offset = ox;
+  printf("\ncoarse timing: %d nerr: %d\n", offset, best_nerr);
+
+  % Coherent BER theory
+  thrcoh = .5*erfc(sqrt(.5*EbNo));
+
+  % non-coherent BER theory calculation
+  % It was complicated, so I broke it up
+
+  ms = 2;
+  ns = (1:ms-1);
+  as = (-1).^(ns+1);
+  bs = (as./(ns+1));
+  
+  cs = ((ms-1)./ns);
+
+  ds = ns.*log2(ms);
+  es = ns+1;
+  fs = exp( -(ds./es)*EbNo );
+  
+  thrncoh = ((ms/2)/(ms-1)) * sum(bs.*((ms-1)./ns).*exp( -(ds./es)*EbNo ));
+
+endfunction
+
+
+function rxphi = fine_ex(timing_offset = 1,fsk_info)
+
+  rand('state',1); 
+  randn('state',1);
+
+  bitcnt = 12051;
+  test_bits = [zeros(1,100) rand(1,bitcnt)>.5]; %Random bits. Pad with zeros to prime the filters
+  t_vec = [0 0 1 1];
+  %test_bits = repmat(t_vec,1,ceil(24000/length(t_vec)));
+
+  states = yafsk_init(fsk_info);
+  Fs = states.Fs;
+  Rb = states.Rs; 
+  
+  tx = yafsk_mod(states,test_bits);
+
+  rx    = tx;
+  rx    = rx(timing_offset:length(rx));
+
+  [rx_bits states rxphi] = yafsk_demod_2a(states,rx);
+  ber = 1;
+  
+  %thing to account for offset from input data to output data
+  %No preamble detection yet
+  ox = 1;
+  for offset = (1:100)
+    nerr = sum(xor(rx_bits(offset:length(rx_bits)),test_bits(1:length(rx_bits)+1-offset)));
+    bern = nerr/(bitcnt-offset);
+    if(bern < ber)
+      ox = offset;
+      best_nerr = nerr;
+    end
+    ber = min([ber bern]);
+  end
+  offset = ox;
+  printf("\ncoarse timing: %d nerr: %d\n", offset, best_nerr);
+
+endfunction
+
+function phi=fine_2(aEsNodB,fsk_info,bits,offset,freq)
+  [ber coh ncoh phi] = nfbert_2(aEsNodB,fsk_info, bits, offset, freq)
+endfunction
+
+function yafsk_rx_phi
+  global fsk_setup
+  pkg load parallel
+  offrange = [1:2:101];
+
+  setups = repmat(fsk_setup,1,length(offrange));
+  phi = pararrayfun(nproc(),@fine_2,100,setups,1,offrange,0*ones(1,length(offrange)));
+  
+  close all;
+  figure(1);
+  clf;
+  plot(offrange,real(phi),offrange,imag(phi));
+  figure(2);
+  plotyy(offrange,angle(phi),offrange,abs(phi))
+endfunction
+
diff --git a/codec2/branches/0.7/raw/b0067.raw b/codec2/branches/0.7/raw/b0067.raw
new file mode 100644 (file)
index 0000000..3aea9cd
Binary files /dev/null and b/codec2/branches/0.7/raw/b0067.raw differ
diff --git a/codec2/branches/0.7/raw/cq_ref.raw b/codec2/branches/0.7/raw/cq_ref.raw
new file mode 100644 (file)
index 0000000..485703d
Binary files /dev/null and b/codec2/branches/0.7/raw/cq_ref.raw differ
diff --git a/codec2/branches/0.7/raw/cross.raw b/codec2/branches/0.7/raw/cross.raw
new file mode 100644 (file)
index 0000000..1b2af6a
Binary files /dev/null and b/codec2/branches/0.7/raw/cross.raw differ
diff --git a/codec2/branches/0.7/raw/cross_melp2400.raw b/codec2/branches/0.7/raw/cross_melp2400.raw
new file mode 100644 (file)
index 0000000..439012c
Binary files /dev/null and b/codec2/branches/0.7/raw/cross_melp2400.raw differ
diff --git a/codec2/branches/0.7/raw/f2400.raw b/codec2/branches/0.7/raw/f2400.raw
new file mode 100644 (file)
index 0000000..5f4427f
Binary files /dev/null and b/codec2/branches/0.7/raw/f2400.raw differ
diff --git a/codec2/branches/0.7/raw/forig.raw b/codec2/branches/0.7/raw/forig.raw
new file mode 100644 (file)
index 0000000..4ba294d
Binary files /dev/null and b/codec2/branches/0.7/raw/forig.raw differ
diff --git a/codec2/branches/0.7/raw/forig_ambe2000.raw b/codec2/branches/0.7/raw/forig_ambe2000.raw
new file mode 100644 (file)
index 0000000..9114357
Binary files /dev/null and b/codec2/branches/0.7/raw/forig_ambe2000.raw differ
diff --git a/codec2/branches/0.7/raw/forig_g729a.raw b/codec2/branches/0.7/raw/forig_g729a.raw
new file mode 100644 (file)
index 0000000..fbca567
Binary files /dev/null and b/codec2/branches/0.7/raw/forig_g729a.raw differ
diff --git a/codec2/branches/0.7/raw/forig_gsm13k.raw b/codec2/branches/0.7/raw/forig_gsm13k.raw
new file mode 100644 (file)
index 0000000..71cbe6f
Binary files /dev/null and b/codec2/branches/0.7/raw/forig_gsm13k.raw differ
diff --git a/codec2/branches/0.7/raw/forig_speex_8k.raw b/codec2/branches/0.7/raw/forig_speex_8k.raw
new file mode 100644 (file)
index 0000000..e95302e
Binary files /dev/null and b/codec2/branches/0.7/raw/forig_speex_8k.raw differ
diff --git a/codec2/branches/0.7/raw/g3plx.raw b/codec2/branches/0.7/raw/g3plx.raw
new file mode 100644 (file)
index 0000000..9970c3f
Binary files /dev/null and b/codec2/branches/0.7/raw/g3plx.raw differ
diff --git a/codec2/branches/0.7/raw/hts.raw b/codec2/branches/0.7/raw/hts.raw
new file mode 100644 (file)
index 0000000..79f869a
Binary files /dev/null and b/codec2/branches/0.7/raw/hts.raw differ
diff --git a/codec2/branches/0.7/raw/hts1.raw b/codec2/branches/0.7/raw/hts1.raw
new file mode 100644 (file)
index 0000000..3369387
Binary files /dev/null and b/codec2/branches/0.7/raw/hts1.raw differ
diff --git a/codec2/branches/0.7/raw/hts1a.raw b/codec2/branches/0.7/raw/hts1a.raw
new file mode 100644 (file)
index 0000000..7332f93
Binary files /dev/null and b/codec2/branches/0.7/raw/hts1a.raw differ
diff --git a/codec2/branches/0.7/raw/hts1a_ambe2000.raw b/codec2/branches/0.7/raw/hts1a_ambe2000.raw
new file mode 100644 (file)
index 0000000..ab72ba2
Binary files /dev/null and b/codec2/branches/0.7/raw/hts1a_ambe2000.raw differ
diff --git a/codec2/branches/0.7/raw/hts1a_g729a.raw b/codec2/branches/0.7/raw/hts1a_g729a.raw
new file mode 100644 (file)
index 0000000..130f1dd
Binary files /dev/null and b/codec2/branches/0.7/raw/hts1a_g729a.raw differ
diff --git a/codec2/branches/0.7/raw/hts1a_gsm13k.raw b/codec2/branches/0.7/raw/hts1a_gsm13k.raw
new file mode 100644 (file)
index 0000000..dd102f5
Binary files /dev/null and b/codec2/branches/0.7/raw/hts1a_gsm13k.raw differ
diff --git a/codec2/branches/0.7/raw/hts1a_melp.raw b/codec2/branches/0.7/raw/hts1a_melp.raw
new file mode 100644 (file)
index 0000000..a4040d2
Binary files /dev/null and b/codec2/branches/0.7/raw/hts1a_melp.raw differ
diff --git a/codec2/branches/0.7/raw/hts1a_speex_8k.raw b/codec2/branches/0.7/raw/hts1a_speex_8k.raw
new file mode 100644 (file)
index 0000000..9289e1c
Binary files /dev/null and b/codec2/branches/0.7/raw/hts1a_speex_8k.raw differ
diff --git a/codec2/branches/0.7/raw/hts2.raw b/codec2/branches/0.7/raw/hts2.raw
new file mode 100644 (file)
index 0000000..0bb9df1
Binary files /dev/null and b/codec2/branches/0.7/raw/hts2.raw differ
diff --git a/codec2/branches/0.7/raw/hts2a.raw b/codec2/branches/0.7/raw/hts2a.raw
new file mode 100644 (file)
index 0000000..6d9cf17
Binary files /dev/null and b/codec2/branches/0.7/raw/hts2a.raw differ
diff --git a/codec2/branches/0.7/raw/hts2a_ambe2000.raw b/codec2/branches/0.7/raw/hts2a_ambe2000.raw
new file mode 100644 (file)
index 0000000..7225f60
Binary files /dev/null and b/codec2/branches/0.7/raw/hts2a_ambe2000.raw differ
diff --git a/codec2/branches/0.7/raw/hts2a_g729a.raw b/codec2/branches/0.7/raw/hts2a_g729a.raw
new file mode 100644 (file)
index 0000000..9199b0a
Binary files /dev/null and b/codec2/branches/0.7/raw/hts2a_g729a.raw differ
diff --git a/codec2/branches/0.7/raw/hts2a_gsm13k.raw b/codec2/branches/0.7/raw/hts2a_gsm13k.raw
new file mode 100644 (file)
index 0000000..f0a5850
Binary files /dev/null and b/codec2/branches/0.7/raw/hts2a_gsm13k.raw differ
diff --git a/codec2/branches/0.7/raw/hts2a_melp.raw b/codec2/branches/0.7/raw/hts2a_melp.raw
new file mode 100644 (file)
index 0000000..5138e49
Binary files /dev/null and b/codec2/branches/0.7/raw/hts2a_melp.raw differ
diff --git a/codec2/branches/0.7/raw/hts2a_speex_8k.raw b/codec2/branches/0.7/raw/hts2a_speex_8k.raw
new file mode 100644 (file)
index 0000000..c421bb4
Binary files /dev/null and b/codec2/branches/0.7/raw/hts2a_speex_8k.raw differ
diff --git a/codec2/branches/0.7/raw/k6hx.raw b/codec2/branches/0.7/raw/k6hx.raw
new file mode 100644 (file)
index 0000000..35e6df7
Binary files /dev/null and b/codec2/branches/0.7/raw/k6hx.raw differ
diff --git a/codec2/branches/0.7/raw/kristoff.raw b/codec2/branches/0.7/raw/kristoff.raw
new file mode 100644 (file)
index 0000000..9b0b465
Binary files /dev/null and b/codec2/branches/0.7/raw/kristoff.raw differ
diff --git a/codec2/branches/0.7/raw/m2400.raw b/codec2/branches/0.7/raw/m2400.raw
new file mode 100644 (file)
index 0000000..1c0956d
Binary files /dev/null and b/codec2/branches/0.7/raw/m2400.raw differ
diff --git a/codec2/branches/0.7/raw/mmt1.raw b/codec2/branches/0.7/raw/mmt1.raw
new file mode 100644 (file)
index 0000000..40638a5
Binary files /dev/null and b/codec2/branches/0.7/raw/mmt1.raw differ
diff --git a/codec2/branches/0.7/raw/mmt1_ambe2000.raw b/codec2/branches/0.7/raw/mmt1_ambe2000.raw
new file mode 100644 (file)
index 0000000..e38955c
Binary files /dev/null and b/codec2/branches/0.7/raw/mmt1_ambe2000.raw differ
diff --git a/codec2/branches/0.7/raw/mmt1_g729a.raw b/codec2/branches/0.7/raw/mmt1_g729a.raw
new file mode 100644 (file)
index 0000000..196716e
Binary files /dev/null and b/codec2/branches/0.7/raw/mmt1_g729a.raw differ
diff --git a/codec2/branches/0.7/raw/mmt1_gsm13k.raw b/codec2/branches/0.7/raw/mmt1_gsm13k.raw
new file mode 100644 (file)
index 0000000..a9965af
Binary files /dev/null and b/codec2/branches/0.7/raw/mmt1_gsm13k.raw differ
diff --git a/codec2/branches/0.7/raw/mmt1_speex_8k.raw b/codec2/branches/0.7/raw/mmt1_speex_8k.raw
new file mode 100644 (file)
index 0000000..769a49c
Binary files /dev/null and b/codec2/branches/0.7/raw/mmt1_speex_8k.raw differ
diff --git a/codec2/branches/0.7/raw/morig.raw b/codec2/branches/0.7/raw/morig.raw
new file mode 100644 (file)
index 0000000..4af0e8f
Binary files /dev/null and b/codec2/branches/0.7/raw/morig.raw differ
diff --git a/codec2/branches/0.7/raw/morig_ambe2000.raw b/codec2/branches/0.7/raw/morig_ambe2000.raw
new file mode 100644 (file)
index 0000000..9964275
Binary files /dev/null and b/codec2/branches/0.7/raw/morig_ambe2000.raw differ
diff --git a/codec2/branches/0.7/raw/morig_g729a.raw b/codec2/branches/0.7/raw/morig_g729a.raw
new file mode 100644 (file)
index 0000000..636ecfd
Binary files /dev/null and b/codec2/branches/0.7/raw/morig_g729a.raw differ
diff --git a/codec2/branches/0.7/raw/morig_gsm13k.raw b/codec2/branches/0.7/raw/morig_gsm13k.raw
new file mode 100644 (file)
index 0000000..660368f
Binary files /dev/null and b/codec2/branches/0.7/raw/morig_gsm13k.raw differ
diff --git a/codec2/branches/0.7/raw/morig_speex_8k.raw b/codec2/branches/0.7/raw/morig_speex_8k.raw
new file mode 100644 (file)
index 0000000..ab667a1
Binary files /dev/null and b/codec2/branches/0.7/raw/morig_speex_8k.raw differ
diff --git a/codec2/branches/0.7/raw/sine1k_2Hz_spread.raw b/codec2/branches/0.7/raw/sine1k_2Hz_spread.raw
new file mode 100644 (file)
index 0000000..1b8ad9c
Binary files /dev/null and b/codec2/branches/0.7/raw/sine1k_2Hz_spread.raw differ
diff --git a/codec2/branches/0.7/raw/sine1k_2ms_delay_2Hz_spread.raw b/codec2/branches/0.7/raw/sine1k_2ms_delay_2Hz_spread.raw
new file mode 100644 (file)
index 0000000..4d3e09e
Binary files /dev/null and b/codec2/branches/0.7/raw/sine1k_2ms_delay_2Hz_spread.raw differ
diff --git a/codec2/branches/0.7/raw/ve9qrp.raw b/codec2/branches/0.7/raw/ve9qrp.raw
new file mode 100644 (file)
index 0000000..489e942
Binary files /dev/null and b/codec2/branches/0.7/raw/ve9qrp.raw differ
diff --git a/codec2/branches/0.7/raw/ve9qrp_10s.raw b/codec2/branches/0.7/raw/ve9qrp_10s.raw
new file mode 100644 (file)
index 0000000..0d3bd3b
Binary files /dev/null and b/codec2/branches/0.7/raw/ve9qrp_10s.raw differ
diff --git a/codec2/branches/0.7/raw/vk5qi.raw b/codec2/branches/0.7/raw/vk5qi.raw
new file mode 100644 (file)
index 0000000..fdfcd5d
Binary files /dev/null and b/codec2/branches/0.7/raw/vk5qi.raw differ
diff --git a/codec2/branches/0.7/script/menu.sh b/codec2/branches/0.7/script/menu.sh
new file mode 100755 (executable)
index 0000000..c0335d2
--- /dev/null
@@ -0,0 +1,80 @@
+#!/bin/bash
+# ./menu.sh
+#
+# David Rowe
+# Created August 2009
+#
+# Presents a menu of sound files, press 1 to play file1, 2 to play file2 etc
+#
+# The aim is to make comparing files with different processing easier than
+# using up-arrow on the command line.  Based on cdialog.
+#
+# usage:
+#   menu.sh file1.raw file2.raw ........ [-d playbackdevice]
+#
+# for example:
+#
+#   ../script/menu.sh hts1a.raw hts1a_uq.raw 
+#
+# or:
+#
+#   ../script/menu.sh hts1a.raw hts1a_uq.raw -d /dev/dsp1
+#
+
+#  Copyright (C) 2007 David Rowe
+# 
+#  All rights reserved.
+# 
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License version 2, as
+#  published by the Free Software Foundation.
+# 
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+# 
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+files=0
+items="Q-Quit\n"
+while [ ! -z "$1" ]
+do
+  case "$1" in
+    -d) dsp="${1} ${2}"; shift;;
+     *) files=`expr 1 + $files`;
+        new_file=$1;
+        file[$files]=$new_file;
+        items="${items} ${files}-${new_file}\n";;
+  esac
+  shift
+done
+
+echo -n -e "\r" $items"- "
+while true ; do
+  echo -n -e "\r -"
+  stty cbreak         # or stty raw. Stty uses file descriptor 0, not /dev/tty.
+  readchar=`dd bs=1 count=1 2>/dev/null`
+  stty -cbreak
+  if [ -n "$readchar" ] ; then
+    if [ x$readchar == 'xq' -o x$readchar == 'xQ' ] ; then
+      echo
+      exit 0
+    fi
+    if [ -z ${file[$readchar]} ] ; then
+        echo -n -e "\nUnknown input\n" $items"- "
+        continue
+    fi
+    if ( play --version ) >/dev/null 2>&1; then
+      play -r 8000 -s -2 ${file[$readchar]} $dsp 2> /dev/null
+    elif ( aplay --version ) > /dev/null 2>&1; then
+      aplay -r 8000 -f S16_LE ${file[$readchar]} 2> /dev/null
+    elif ( ossplay -f? ) > /dev/null 2>&1; then
+      ossplay -s8000 -fS16_LE ${file[$readchar]} 2> /dev/null
+    else
+      echo "could not find play, aplay or ossplay program"
+    fi
+  fi
+done
+echo
diff --git a/codec2/branches/0.7/script/playraw.sh b/codec2/branches/0.7/script/playraw.sh
new file mode 100755 (executable)
index 0000000..683cbaa
--- /dev/null
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Plays a raw file
+# usage:
+#   playraw file.raw
+#   playraw file.raw -d /dev/dsp1 (e.g. for USB headphones)
+play -r 8000 -s -2 $1 $2 $3
diff --git a/codec2/branches/0.7/script/raw2wav.sh b/codec2/branches/0.7/script/raw2wav.sh
new file mode 100755 (executable)
index 0000000..a05efb7
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+# Converts 16 bit signed short 8 kHz raw (headerless) files to wave
+sox -r 8000 -s -2 $1 $2
diff --git a/codec2/branches/0.7/script/separate_all.sh b/codec2/branches/0.7/script/separate_all.sh
new file mode 100755 (executable)
index 0000000..f1d775e
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+sox $1 hts1_$1.wav trim 0 3
+sox $1 hts2_$1.wav trim 3 3
+sox $1 morig_$1.wav trim 6 2
+sox $1 forig_$1.wav trim 8 2
+sox $1 ve9qrp_$1.wav trim 10 9.5
+sox $1 cq_ref_$1.wav trim 20 9
+sox $1 kristoff_$1.wav trim 29.5 4
+sox $1 vk5qi_$1.wav trim 33.5 13.5
+sox $1 vk5dgr_$1.wav trim 47 10
+
+
+
diff --git a/codec2/branches/0.7/script/wav2raw.sh b/codec2/branches/0.7/script/wav2raw.sh
new file mode 100755 (executable)
index 0000000..39c0f1a
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+# Converts wave files to raw (headerless) files
+sox $1 -t raw $2
diff --git a/codec2/branches/0.7/src/CMakeLists.txt b/codec2/branches/0.7/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7dc9e8c
--- /dev/null
@@ -0,0 +1,349 @@
+#
+# Generated sources
+#
+
+set(D ${CMAKE_CURRENT_SOURCE_DIR}/codebook)
+
+# lsp quantisers
+
+set(CODEBOOKS
+    ${D}/lsp1.txt
+    ${D}/lsp2.txt
+    ${D}/lsp3.txt
+    ${D}/lsp4.txt
+    ${D}/lsp5.txt
+    ${D}/lsp6.txt
+    ${D}/lsp7.txt
+    ${D}/lsp8.txt
+    ${D}/lsp9.txt
+    ${D}/lsp10.txt
+)
+
+# lspd quantisers
+
+set(CODEBOOKSD
+    ${D}/dlsp1.txt
+    ${D}/dlsp2.txt
+    ${D}/dlsp3.txt
+    ${D}/dlsp4.txt
+    ${D}/dlsp5.txt
+    ${D}/dlsp6.txt
+    ${D}/dlsp7.txt
+    ${D}/dlsp8.txt
+    ${D}/dlsp9.txt
+    ${D}/dlsp10.txt
+)
+
+set(CODEBOOKSJVM
+    ${D}/lspjvm1.txt
+    ${D}/lspjvm2.txt
+    ${D}/lspjvm3.txt
+)
+
+set(CODEBOOKSMEL
+    ${D}/mel1.txt
+    ${D}/mel2.txt
+    ${D}/mel3.txt
+    ${D}/mel4.txt
+    ${D}/mel5.txt
+    ${D}/mel6.txt
+)
+
+set(CODEBOOKSLSPMELVQ
+    ${D}/lspmelvq1.txt
+    ${D}/lspmelvq2.txt
+    ${D}/lspmelvq3.txt
+)
+
+set(CODEBOOKSGE ${D}/gecb.txt)
+
+set(CODEBOOKSNEWAMP1
+    ${D}/train_120_1.txt
+    ${D}/train_120_2.txt
+)
+
+set(CODEBOOKSNEWAMP1_ENERGY
+    ${D}/newamp1_energy_q.txt
+)
+
+# when crosscompiling we need a native executable
+if(CMAKE_CROSSCOMPILING)
+    include(ExternalProject)
+    ExternalProject_Add(codec2_native
+       SOURCE_DIR ${CMAKE_SOURCE_DIR}
+       BUILD_COMMAND $(MAKE) generate_codebook
+       INSTALL_COMMAND ${CMAKE_COMMAND} -E copy src/generate_codebook ${CMAKE_CURRENT_BINARY_DIR}
+    )
+    add_executable(generate_codebook IMPORTED)
+    set_target_properties(generate_codebook PROPERTIES
+        IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/generate_codebook)
+    add_dependencies(generate_codebook codec2_native)
+else(CMAKE_CROSSCOMPILING)
+# Build code generator binaries. These do not get installed.
+    # generate_codebook
+    add_executable(generate_codebook generate_codebook.c)
+    target_link_libraries(generate_codebook ${CMAKE_REQUIRED_LIBRARIES})
+    # Make native builds available for cross-compiling.
+    export(TARGETS generate_codebook
+        FILE ${CMAKE_BINARY_DIR}/ImportExecutables.cmake)
+endif(CMAKE_CROSSCOMPILING)
+
+
+# codebook.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebook.c
+    COMMAND generate_codebook lsp_cb ${CODEBOOKS} > ${CMAKE_CURRENT_BINARY_DIR}/codebook.c
+    DEPENDS generate_codebook ${CODEBOOKS}
+)
+
+# codebookd.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookd.c
+    COMMAND generate_codebook lsp_cbd ${CODEBOOKSD} > ${CMAKE_CURRENT_BINARY_DIR}/codebookd.c
+    DEPENDS generate_codebook ${CODEBOOKSD}
+)
+
+# codebookjvm.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookjvm.c
+    COMMAND generate_codebook lsp_cbjvm ${CODEBOOKSJVM} > ${CMAKE_CURRENT_BINARY_DIR}/codebookjvm.c
+    DEPENDS generate_codebook ${CODEBOOKSJVM}
+)
+
+
+# codebookmel.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookmel.c
+    COMMAND generate_codebook mel_cb ${CODEBOOKSMEL} > ${CMAKE_CURRENT_BINARY_DIR}/codebookmel.c
+    DEPENDS generate_codebook ${CODEBOOKSMEL}
+)
+
+# codebooklspmelvq.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebooklspmelvq.c
+    COMMAND generate_codebook lspmelvq_cb ${CODEBOOKSLSPMELVQ} > ${CMAKE_CURRENT_BINARY_DIR}/codebooklspmelvq.c
+    DEPENDS generate_codebook ${CODEBOOKSLSPMELVQ}
+)
+
+# codebookge.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookge.c
+    COMMAND generate_codebook ge_cb ${CODEBOOKSGE} > ${CMAKE_CURRENT_BINARY_DIR}/codebookge.c
+    DEPENDS generate_codebook ${CODEBOOKSGE}
+)
+
+# codebooknewamp1.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebooknewamp1.c
+    COMMAND generate_codebook newamp1vq_cb ${CODEBOOKSNEWAMP1} > ${CMAKE_CURRENT_BINARY_DIR}/codebooknewamp1.c
+    DEPENDS generate_codebook ${CODEBOOKSNEWAMP1}
+)
+
+# codebooknewamp1_energy.c
+add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebooknewamp1_energy.c
+    COMMAND generate_codebook newamp1_energy_cb ${CODEBOOKSNEWAMP1_ENERGY} > ${CMAKE_CURRENT_BINARY_DIR}/codebooknewamp1_energy.c
+    DEPENDS generate_codebook ${CODEBOOKSNEWAMP1_ENERGY}
+)
+
+#
+# codec2 library sources
+#
+
+set(CODEC2_SRCS
+    dump.c
+    lpc.c
+    nlp.c
+    postfilter.c
+    sine.c
+    codec2.c
+    codec2_fft.c
+    cohpsk.c
+    fifo.c
+    fdmdv.c
+    fm.c
+    fsk.c
+    fmfsk.c
+    kiss_fft.c
+    kiss_fftr.c
+    linreg.c
+    interp.c
+    lsp.c
+    mbest.c
+    newamp1.c
+    phase.c
+    quantise.c
+    pack.c
+    codebook.c
+    codebookd.c
+    codebookjvm.c
+    codebookmel.c
+    codebooklspmelvq.c
+    codebookge.c
+    codebooknewamp1.c
+    codebooknewamp1_energy.c
+    golay23.c
+    freedv_api.c
+    freedv_vhf_framing.c
+    freedv_data_channel.c
+    varicode.c
+    modem_stats.c
+)
+
+set(CODEC2_PUBLIC_HEADERS
+    golay23.h
+    codec2.h
+    codec2_fdmdv.h
+    codec2_cohpsk.h
+    codec2_fm.h
+    fsk.h
+    codec2_fifo.h
+    comp.h
+    comp_prim.h
+    modem_stats.h
+    kiss_fft.h
+    freedv_api.h
+    varicode.h
+    freedv_api_internal.h
+)
+
+#
+# Setup the codec2 library
+#
+add_library(codec2 ${CODEC2_SRCS})
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(codec2 ${CMAKE_REQUIRED_LIBRARIES})
+set_target_properties(codec2 PROPERTIES
+    SOVERSION ${SOVERSION}
+    PUBLIC_HEADER "${CODEC2_PUBLIC_HEADERS}"
+)
+
+add_executable(c2demo c2demo.c)
+target_link_libraries(c2demo ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(c2enc c2enc.c)
+target_link_libraries(c2enc ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(c2dec c2dec.c)
+target_link_libraries(c2dec ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(c2sim c2sim.c)
+target_link_libraries(c2sim ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fdmdv_get_test_bits fdmdv_get_test_bits.c fdmdv.c kiss_fft.c codec2_fft.c kiss_fftr.c)
+target_link_libraries(fdmdv_get_test_bits ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(fdmdv_mod fdmdv_mod.c fdmdv.c kiss_fft.c codec2_fft.c kiss_fftr.c)
+target_link_libraries(fdmdv_mod ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(fdmdv_demod fdmdv_demod.c fdmdv.c kiss_fft.c octave.c modem_stats.c codec2_fft.c kiss_fftr.c)
+target_link_libraries(fdmdv_demod ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(fdmdv_put_test_bits fdmdv_put_test_bits.c fdmdv.c kiss_fft.c codec2_fft.c kiss_fftr.c)
+target_link_libraries(fdmdv_put_test_bits ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(fdmdv_channel fdmdv_channel.c)
+target_link_libraries(fdmdv_channel ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fdmdv_interleave fdmdv_interleave.c)
+target_link_libraries(fdmdv_interleave ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(insert_errors insert_errors.c)
+target_link_libraries(insert_errors ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(fec_enc fec_enc.c golay23.c)
+target_link_libraries(fec_enc ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fec_dec fec_dec.c golay23.c)
+target_link_libraries(fec_dec ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(freedv_tx freedv_tx.c)
+target_link_libraries(freedv_tx ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(freedv_rx freedv_rx.c)
+target_link_libraries(freedv_rx ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fsk_mod fsk_mod.c)
+target_link_libraries(fsk_mod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fsk_demod fsk_demod.c modem_probe.c octave.c)
+target_link_libraries(fsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fsk_get_test_bits fsk_get_test_bits.c)
+target_link_libraries(fsk_get_test_bits ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fsk_put_test_bits fsk_put_test_bits.c)
+target_link_libraries(fsk_put_test_bits ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fm_demod fm_demod.c fm.c)
+target_link_libraries(fm_demod ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(cohpsk_mod cohpsk_mod.c)
+target_link_libraries(cohpsk_mod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fmfsk_mod fmfsk_mod.c)
+target_link_libraries(fmfsk_mod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(fmfsk_demod fmfsk_demod.c modem_probe.c octave.c)
+target_link_libraries(fmfsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(vhf_deframe_c2 vhf_deframe_c2.c)
+target_link_libraries(vhf_deframe_c2  ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(vhf_frame_c2 vhf_frame_c2.c)
+target_link_libraries(vhf_frame_c2  ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(cohpsk_demod cohpsk_demod.c octave.c)
+target_link_libraries(cohpsk_demod ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(cohpsk_get_test_bits cohpsk_get_test_bits.c)
+target_link_libraries(cohpsk_get_test_bits ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(cohpsk_put_test_bits cohpsk_put_test_bits.c octave.c)
+target_link_libraries(cohpsk_put_test_bits ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(cohpsk_ch cohpsk_ch.c)
+target_link_libraries(cohpsk_ch ${CMAKE_REQUIRED_LIBRARIES} codec2)
+
+add_executable(ldpc_enc ldpc_enc.c)
+target_link_libraries(ldpc_enc ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(ldpc_dec ldpc_dec.c mpdecode_core.c)
+target_link_libraries(ldpc_dec ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(drs232 drs232.c)
+target_link_libraries(drs232 ${CMAKE_REQUIRED_LIBRARIES})
+
+add_executable(drs232_ldpc drs232_ldpc.c mpdecode_core.c)
+target_link_libraries(drs232_ldpc ${CMAKE_REQUIRED_LIBRARIES})
+
+install(TARGETS codec2 EXPORT codec2-config
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/codec2
+)
+
+#install(EXPORT codec2-config
+#    DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/codec2
+#)
+
+install(TARGETS
+    c2demo
+    c2demo
+    c2enc
+    c2dec
+    c2sim
+    fdmdv_get_test_bits
+    fdmdv_mod fdmdv_demod
+    fm_demod
+    fsk_mod
+    fdmdv_put_test_bits
+    fdmdv_interleave
+    insert_errors
+    fec_enc
+    fec_dec
+    drs232
+    drs232_ldpc
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+)
diff --git a/codec2/branches/0.7/src/H2064_516_sparse.h b/codec2/branches/0.7/src/H2064_516_sparse.h
new file mode 100644 (file)
index 0000000..70e88ea
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+  FILE....: ../src/H2064_516_sparse.h
+
+  Static arrays for CML LDPC codec, generated
+  by test_ldpc_fsk.m:simple_ut().
+
+*/
+
+#define NUMBERPARITYBITS 516
+#define MAX_ROW_WEIGHT 12
+#define CODELENGTH 2580
+#define NUMBERROWSHCOLS 2064
+#define MAX_COL_WEIGHT 3
+#define DEC_TYPE 0
+#define MAX_ITER 10
+
+double H_rows[] = {
+870, 276, 110, 54, 226, 85, 59, 153, 31, 60, 46, 75, 139, 239, 56, 13, 30, 45, 63, 34, 54, 21, 77, 204, 441, 11, 297, 126, 148, 104, 269, 57, 369, 213, 117, 479, 53, 124, 405, 97, 42, 132, 67, 103, 389, 156, 237, 105, 418, 11, 60, 12, 195, 32, 11, 21, 10, 191, 176, 237, 140, 376, 115, 9, 149, 304, 129, 308, 234, 129, 453, 215, 176, 213, 151, 169, 41, 106, 421, 103, 83, 62, 124, 3, 574, 39, 31, 472, 69, 8, 40, 352, 62, 275, 74, 121, 125, 35, 83, 52, 21, 422, 229, 233, 62, 125, 181, 175, 28, 43, 113, 340, 71, 4, 40, 249, 134, 168, 97, 15, 26, 135, 104, 80, 206, 108, 307, 494, 358, 82, 159, 137, 19, 210, 6, 19, 65, 285, 45, 154, 276, 14, 137, 79, 241, 235, 116, 129, 84, 3, 122, 370, 132, 451, 77, 89, 262, 79, 170, 469, 24, 163, 128, 18, 120, 244, 8, 153, 151, 441, 95, 327, 284, 96, 84, 35, 61, 286, 20, 22, 68, 131, 106, 30, 280, 343, 99, 124, 262, 208, 277, 44, 349, 41, 10, 761, 39, 445, 165, 81, 393, 194, 18, 250, 589, 70, 307, 1, 365, 47, 4, 9, 283, 133, 90, 601, 117, 228, 212, 58, 420, 230, 142, 25, 57, 518, 88, 180, 24, 122, 379, 143, 33, 30, 140, 68, 150, 320, 55, 33, 132, 2, 22, 16, 272, 44, 264, 49, 174, 234, 86, 39, 10, 278, 177, 178, 20, 126, 18, 90, 6, 184, 158, 111, 246, 229, 221, 48, 267, 6, 172, 49, 291, 185, 67, 50, 157, 66, 32, 525, 257, 196, 260, 92, 72, 163, 144, 329, 134, 156, 47, 82, 49, 391, 26, 1, 88, 52, 56, 8, 111, 138, 219, 57, 447, 182, 263, 38, 98, 75, 36, 83, 245, 5, 419, 63, 12, 287, 603, 58, 507, 37, 2, 214, 539, 55, 53, 81, 186, 73, 85, 97, 91, 332, 123, 66, 188, 591, 158, 324, 88, 53, 214, 84, 389, 104, 271, 211, 7, 393, 281, 242, 119, 848, 705, 428, 50, 28, 52, 15, 5, 2, 230, 38, 76, 295, 217, 1, 56, 170, 145, 5, 72, 460, 203, 145, 211, 121, 68, 538, 44, 133, 87, 494, 325, 161, 781, 370, 51, 115, 262, 106, 614, 29, 220, 189, 224, 165, 17, 72, 46, 17, 64, 19, 447, 13, 9, 270, 4, 91, 471, 35, 23, 407, 34, 38, 82, 321, 112, 195, 651, 7, 43, 431, 249, 171, 196, 311, 15, 66, 16, 633, 37, 94, 102, 23, 3, 214, 252, 256, 173, 316, 125, 96, 341, 71, 73, 338, 256, 165, 140, 108, 471, 434, 137, 642, 172, 51, 113, 67, 172, 93, 23, 318, 514, 50, 118, 245, 169, 14, 64, 40, 859, 95, 308, 65, 93, 42, 339, 46, 7, 96, 142, 36, 131, 60, 13, 12, 25, 31, 183, 94, 43, 241, 162, 26, 232, 120, 128, 118, 89, 164, 51, 29, 127, 177, 180, 95, 332, 284, 32, 802, 452, 25, 382, 187, 892, 432, 162, 126, 587, 342, 205, 170, 255, 73, 605, 579, 398, 305, 58, 110, 178, 244, 306, 178, 166, 28, 368, 224, 582, 135, 420, 618, 264, 234, 346, 223, 439, 399, 150, 655, 242, 248, 750, 199, 242, 277, 112, 163, 545, 359, 487, 322, 570, 64, 402, 412, 252, 116, 147, 109, 27, 197, 204, 251, 282, 455, 118, 390, 225, 382, 215, 373, 554, 371, 568, 289, 225, 405, 160, 414, 290, 109, 524, 406, 344, 188, 385, 33, 791, 261, 171, 475, 100, 183, 156, 564, 78, 395, 144, 497, 334, 45, 167, 79, 27, 520, 239, 449, 138, 347, 667, 572, 61, 278, 136, 375, 231, 320, 167, 304, 389, 185, 171, 109, 468, 243, 206, 210, 305, 160, 682, 514, 433, 152, 375, 1064, 48, 522, 139, 98, 191, 557, 127, 189, 372, 54, 515, 406, 370, 950, 549, 352, 319, 27, 489, 440, 636, 941, 153, 102, 268, 120, 190, 719, 451, 175, 539, 477, 279, 474, 17, 232, 221, 476, 174, 415, 545, 357, 368, 149, 94, 409, 218, 76, 87, 136, 114, 245, 596, 408, 335, 246, 511, 560, 438, 298, 351, 91, 22, 813, 108, 546, 248, 218, 629, 212, 223, 569, 611, 93, 399, 185, 427, 260, 20, 111, 354, 187, 150, 702, 316, 666, 541, 227, 558, 486, 207, 450, 224, 568, 222, 341, 81, 222, 386, 441, 484, 159, 289, 142, 372, 534, 157, 78, 337, 522, 70, 293, 318, 161, 325, 74, 194, 797, 130, 128, 70, 386, 657, 611, 105, 456, 230, 100, 61, 274, 358, 135, 249, 236, 247, 264, 279, 123, 345, 59, 397, 645, 448, 80, 192, 149, 190, 564, 292, 508, 359, 202, 152, 459, 200, 446, 293, 512, 103, 154, 229, 492, 145, 256, 828, 55, 296, 133, 147, 314, 220, 190, 481, 208, 290, 198, 146, 100, 202, 259, 295, 16, 505, 251, 86, 375, 618, 266, 891, 166, 159, 269, 850, 127, 397, 759, 494, 141, 567, 339, 119, 336, 162, 98, 265, 770, 423, 380, 346, 116, 402, 101, 628, 623, 286, 309, 107, 453, 406, 496, 200, 865, 720, 429, 187, 107, 609, 439, 90, 48, 330, 59, 87, 632, 323, 219, 101, 865, 203, 14, 74, 466, 462, 160, 448, 168, 474, 980, 396, 148, 244, 904, 438, 198, 982, 601, 199, 119, 300, 240, 702, 241, 258, 192, 291, 227, 34, 698, 78, 107, 123, 89, 704, 114, 274, 461, 151, 115, 576, 323, 201, 468, 271, 231, 92, 592, 220, 909, 829, 243, 480, 466, 345, 763, 404, 356, 86, 110, 210, 688, 353, 271, 740, 226, 352, 247, 288, 758, 338, 426, 235, 405, 625, 155, 146, 475, 491, 189, 177, 216, 962, 503, 216, 726, 381, 219, 183, 102, 332, 113, 155, 440, 922, 450, 379, 294, 301, 36, 80, 75, 875, 462, 547, 69, 330, 186, 527, 92, 138, 157, 169, 69, 143, 401, 24, 283, 41, 37, 472, 309, 117, 747, 342, 251, 300, 182, 216, 202, 266, 192, 217, 302, 660, 360, 663, 130, 355, 367, 47, 1103, 519, 811, 586, 488, 983, 652, 303, 201, 759, 860, 416, 585, 268, 428, 928, 819, 821, 379, 340, 493, 260, 752, 599, 314, 182, 444, 612, 369, 692, 311, 523, 622, 335, 259, 499, 225, 526, 409, 188, 709, 356, 606, 777, 222, 541, 327, 201, 176, 551, 544, 1008, 372, 628, 181, 523, 549, 476, 464, 240, 593, 181, 254, 223, 305, 285, 595, 217, 887, 550, 552, 278, 381, 621, 517, 953, 538, 265, 581, 313, 540, 366, 626, 647, 511, 467, 508, 890, 63, 976, 275, 312, 885, 598, 254, 180, 687, 196, 398, 146, 675, 380, 101, 443, 122, 85, 531, 347, 463, 167, 536, 724, 710, 288, 351, 232, 387, 424, 650, 363, 544, 540, 248, 279, 121, 479, 267, 218, 445, 485, 240, 737, 692, 1017, 331, 716, 1130, 207, 602, 274, 750, 261, 572, 131, 435, 672, 253, 729, 542, 739, 1062, 731, 619, 328, 65, 769, 502, 898, 966, 158, 211, 289, 193, 314, 784, 533, 396, 567, 497, 280, 696, 348, 290, 383, 636, 526, 470, 622, 541, 411, 286, 378, 561, 374, 194, 349, 166, 143, 390, 697, 533, 570, 304, 615, 709, 476, 679, 454, 287, 114, 904, 535, 786, 270, 308, 828, 302, 506, 732, 626, 533, 584, 186, 456, 495, 350, 317, 672, 343, 315, 919, 367, 820, 548, 296, 614, 635, 209, 543, 350, 733, 239, 376, 287, 344, 470, 563, 607, 319, 323, 473, 428, 677, 212, 263, 386, 567, 435, 328, 616, 255, 729, 147, 320, 855, 267, 426, 261, 458, 977, 670, 173, 478, 366, 112, 71, 419, 968, 139, 606, 292, 275, 463, 344, 671, 810, 77, 465, 755, 579, 179, 353, 357, 442, 599, 354, 805, 453, 407, 193, 510, 285, 513, 583, 645, 325, 173, 621, 573, 423, 479, 912, 130, 300, 227, 184, 391, 293, 204, 673, 282, 371, 324, 313, 228, 334, 343, 655, 42, 532, 559, 658, 484, 921, 373, 944, 329, 184, 302, 861, 205, 414, 771, 606, 312, 652, 503, 413, 415, 238, 449, 781, 874, 586, 544, 402, 468, 525, 155, 845, 714, 295, 564, 197, 509, 863, 640, 209, 986, 808, 691, 317, 355, 789, 779, 281, 141, 594, 336, 105, 682, 360, 299, 559, 876, 608, 315, 401, 632, 480, 161, 577, 284, 657, 1012, 481, 330, 388, 1011, 524, 423, 1019, 812, 416, 168, 322, 258, 710, 703, 1027, 195, 447, 259, 633, 990, 710, 215, 410, 458, 760, 174, 312, 605, 269, 206, 617, 534, 554, 497, 296, 393, 236, 784, 483, 1189, 892, 602, 788, 709, 382, 831, 537, 695, 99, 563, 424, 759, 432, 281, 795, 319, 422, 684, 331, 866, 377, 638, 247, 501, 711, 463, 475, 631, 507, 310, 298, 252, 1059, 757, 364, 785, 410, 233, 411, 236, 487, 339, 341, 473, 1022, 527, 515, 700, 380, 388, 414, 253, 913, 466, 773, 238, 638, 335, 896, 298, 310, 658, 461, 207, 205, 550, 29, 425, 141, 76, 649, 442, 322, 832, 730, 307, 385, 401, 268, 301, 311, 306, 291, 364, 864, 560, 840, 199, 358, 385, 179, 1142, 520, 986, 600, 712, 1018, 661, 365, 237, 769, 953, 517, 605, 396, 459, 991, 867, 899, 415, 700, 556, 324, 788, 639, 778, 226, 743, 685, 706, 883, 362, 970, 785, 387, 376, 734, 392, 730, 448, 250, 731, 387, 665, 1015, 243, 812, 391, 795, 346, 588, 737, 1077, 874, 933, 412, 817, 585, 550, 491, 273, 640, 208, 542, 338, 436, 895, 694, 257, 899, 583, 629, 327, 815, 744, 573, 1226, 727, 272, 607, 331, 1050, 594, 754, 716, 515, 524, 695, 1086, 297, 1177, 400, 678, 1004, 648, 294, 555, 780, 316, 486, 689, 679, 430, 136, 717, 233, 400, 646, 383, 530, 263, 574, 749, 790, 336, 377, 409, 609, 499, 686, 518, 595, 601, 334, 531, 197, 485, 348, 424, 701, 579, 500, 1147, 797, 1085, 404, 738, 1200, 253, 714, 427, 756, 303, 610, 313, 1399, 770, 455, 732, 796, 824, 1230, 927, 929, 397, 276, 794, 741, 957, 1052, 1002, 213, 392, 566, 461, 832, 798, 433, 590, 723, 718, 755, 878, 446, 615, 669, 776, 608, 659, 565, 443, 457, 407, 577, 631, 255, 365, 399, 152, 766, 814, 556, 640, 1137, 1000, 767, 745, 733, 1194, 529, 238, 1034, 789, 1314, 436, 493, 853, 492, 654, 809, 885, 636, 596, 270, 848, 774, 364, 512, 832, 411, 516, 927, 700, 857, 588, 703, 756, 758, 315, 574, 810, 885, 416, 600, 690, 417, 501, 626, 707, 581, 377, 916, 660, 808, 587, 265, 395, 613, 906, 381, 661, 310, 799, 148, 632, 941, 750, 578, 277, 1065, 1242, 1018, 326, 551, 459, 134, 99, 510, 1097, 198, 673, 531, 450, 697, 394, 749, 948, 193, 664, 965, 818, 454, 419, 556, 721, 742, 473, 886, 647, 694, 209, 906, 433, 674, 620, 666, 464, 446, 634, 728, 430, 630, 990, 435, 371, 534, 394, 467, 928, 326, 723, 490, 816, 699, 490, 530, 384, 361, 772, 374, 554, 619, 672, 613, 924, 677, 1079, 404, 367, 337, 898, 228, 418, 844, 766, 317, 680, 690, 566, 680, 333, 726, 960, 942, 637, 607, 452, 664, 698, 235, 942, 736, 368, 584, 362, 650, 871, 683, 328, 1141, 988, 715, 915, 495, 1084, 919, 613, 179, 888, 355, 144, 1243, 655, 551, 582, 993, 730, 340, 548, 774, 643, 469, 651, 392, 843, 1196, 590, 573, 545, 1211, 593, 439, 1027, 869, 586, 442, 762, 502, 758, 822, 1048, 254, 628, 417, 683, 996, 752, 384, 725, 676, 842, 360, 374, 688, 353, 549, 661, 648, 584, 624, 348, 530, 250, 1135, 667, 1298, 1033, 623, 1102, 715, 594, 888, 871, 833, 321, 634, 491, 766, 505, 297, 1024, 388, 460, 707, 735, 1023, 444, 1098, 629, 505, 807, 581, 543, 687, 598, 337, 434, 806, 1111, 761, 521, 826, 547, 257, 434, 412, 688, 577, 363, 839, 1187, 1306, 648, 808, 504, 760, 429, 309, 916, 503, 777, 403, 1076, 512, 1127, 592, 351, 692, 711, 474, 587, 558, 487, 498, 326, 164, 902, 456, 471, 836, 748, 469, 480, 537, 553, 507, 347, 490, 498, 420, 1010, 598, 1022, 283, 362, 958, 553, 1156, 712, 1108, 718, 753, 1067, 681, 398, 483, 903, 956, 698, 612, 578, 489, 1294, 990, 920, 592, 1113, 862, 464, 1435, 835, 788, 280, 957, 795, 743, 1108, 425, 1026, 879, 488, 701, 931, 610, 741, 1061, 282, 830, 413, 983, 1159, 1067, 1071, 437, 843, 506, 610, 890, 1133, 1034, 954, 452, 925, 785, 836, 620, 597, 722, 258, 858, 342, 455, 927, 706, 299, 1104, 660, 811, 333, 1173, 878, 858, 1336, 816, 457, 948, 563, 1054, 678, 764, 733, 565, 555, 873, 1150, 485, 1303, 496, 796, 1218, 823, 634, 624, 878, 686, 684, 879, 1100, 454, 154, 1002, 357, 822, 676, 740, 578, 350, 1124, 834, 876, 500, 486, 426, 663, 529, 947, 656, 621, 823, 361, 615, 421, 585, 417, 538, 707, 656, 861, 1236, 831, 1087, 508, 768, 1269, 292, 786, 478, 1043, 593, 765, 408, 1439, 806, 528, 801, 912, 882, 1348, 1050, 1077, 528, 349, 996, 799, 976, 1265, 1100, 674, 470, 617, 540, 847, 862, 457, 757, 841, 973, 921, 969, 539, 646, 699, 959, 654, 670, 787, 872, 559, 744, 1276, 666, 273, 569, 833, 191, 775, 896, 576, 935, 1231, 1046, 923, 804, 949, 1201, 572, 303, 1162, 827, 1346, 897, 612, 937, 599, 675, 992, 930, 644, 1151, 301, 1103, 1086, 482, 831, 1130, 472, 753, 1007, 852, 1054, 635, 705, 955, 823, 425, 596, 962, 908, 445, 880, 867, 478, 509, 653, 775, 591, 510, 1055, 798, 1021, 740, 294, 427, 679, 973, 484, 686, 369, 836, 410, 802, 1245, 883, 649, 431, 1102, 1267, 1262, 557, 1092, 837, 164, 881, 726, 1120, 273, 697, 1097, 609, 708, 663, 838, 985, 552, 968, 1042, 1044, 483, 520, 691, 736, 756, 521, 895, 779, 914, 266, 1356, 548, 742, 964, 888, 481, 877, 685, 791, 437, 696, 991, 825, 643, 708, 969, 683, 1080, 1001, 1012, 617, 1030, 734, 792, 1069, 504, 394, 864, 595, 676, 782, 695, 837, 1154, 819, 1104, 437, 413, 383, 913, 627, 624, 987, 1394, 449, 839, 825, 1054, 1180, 378, 1211, 1090, 1114, 804, 897, 558, 1032, 746, 246, 1051, 870, 958, 725, 536, 702, 1035, 971, 356, 1195, 1061, 827, 1090, 526, 1092, 1250, 1025, 231, 947, 659, 272, 1284, 802, 826, 902, 1040, 870, 345, 658, 822, 715, 1012, 872, 575, 945, 1232, 805, 720, 580, 1215, 854, 603, 1074, 1056, 991, 528, 1218, 642, 1060, 1010, 1203, 288, 978, 884, 762, 1118, 763, 430, 786, 922, 928, 886, 529, 706, 403, 1104, 693, 868, 815, 670, 366, 546, 378, 1151, 901, 1522, 1107, 671, 1333, 745, 724, 1230, 1073, 911, 429, 646, 611, 889, 746, 403, 1032, 616, 637, 1382, 767, 1083, 451, 1212, 803, 1318, 849, 662, 955, 712, 971, 571, 496, 977, 1145, 1160, 931, 830, 580, 359, 805, 668, 770, 771, 390, 882, 1329, 1572, 851, 829, 535, 944, 535, 373, 930, 669, 828, 565, 1219, 620, 1308, 793, 361, 938, 859, 482, 946, 1186, 742, 591, 846, 221, 906, 641, 631, 1068, 780, 536, 517, 844, 652, 721, 552, 523, 627, 525, 1186, 944, 1039, 794, 498, 1076, 654, 1167, 856, 1264, 890, 768, 1225, 691, 729, 543, 936, 1016, 1210, 656, 604, 608, 1324, 1035, 1095, 639, 1311, 1281, 877, 1519, 923, 974, 431, 1057, 903, 809, 1137, 569, 1243, 1118, 880, 720, 1102, 1168, 821, 1193, 432, 999, 555, 1013, 1375, 1200, 1080, 495, 982, 519, 630, 1066, 1164, 1091, 1006, 1039, 943, 1195, 1103, 665, 894, 908, 329, 1081, 951, 641, 1060, 793, 719, 1232, 713, 847, 395, 1213, 1038, 1041, 1587, 984, 752, 1125, 929, 1095, 988, 940, 845, 603, 623, 875, 1158, 772, 1503, 506, 816, 1500, 1007, 638, 633, 936, 703, 704, 1173, 1171, 724, 175, 1051, 604, 1174, 682, 819, 854, 384, 1196, 1249, 1029, 509, 504, 537, 722, 571, 1121, 739, 838, 1027, 363, 743, 570, 818, 546, 721, 736, 842, 905, 1372, 932, 1178, 863, 840, 1334, 299, 855, 499, 1293, 1202, 1061, 689, 1516, 866, 614, 862, 955, 981, 1511, 1153, 1256, 768, 501, 1044, 1282, 985, 1455, 1235, 711, 1001, 627, 641, 889, 914, 644, 877, 913, 1149, 1138, 1188, 557, 871, 787, 1015, 727, 731, 868, 892, 560, 778, 1331, 1025, 318, 619, 864, 203, 911, 1052, 705, 1079, 1461, 1090, 994, 1023, 1050, 1535, 625, 999, 1344, 933, 1498, 1045, 939, 1249, 650, 910, 1294, 951, 649, 1163, 418, 1133, 1089, 493, 1116, 1309, 561, 857, 1073, 1112, 1223, 909, 807, 989, 1053, 997, 813, 976, 1074, 527, 1070, 966, 775, 511, 1004, 800, 717, 933, 1120, 900, 1389, 922, 684, 440, 704, 1106, 668, 767, 757, 847, 936, 835, 1293, 893, 895, 647, 1269, 1480, 1304, 782, 1166, 952, 566, 1124, 846, 1203, 354, 893, 1200, 952, 792, 667, 1164, 1003, 718, 1002, 1139, 1163, 1096, 685, 769, 1003, 977, 532, 1128, 905, 926, 443, 1405, 576, 835, 1116, 1145, 562, 1063, 737, 883, 639, 790, 1021, 967, 772, 995, 1165, 754, 1422, 1583, 1075, 997, 1082, 748, 827, 1197, 516, 465, 1451, 645, 879, 809, 739, 855, 1155, 948, 1117, 460, 465, 791, 1098, 693, 673, 1087, 1400, 532, 910, 829, 1171, 1214, 400, 1221, 1603, 1323, 834, 965, 787, 1045, 918, 589, 1074, 1171, 1116, 744, 905, 931, 1176, 1005, 589, 1238, 1107, 972, 1115, 600, 1181, 1609, 1105, 521, 1158, 1049, 306, 1389, 804, 963, 971, 1199, 917, 716, 668, 973, 998, 1174, 903, 590, 1130, 1472, 841, 811, 597, 1399, 956, 719, 1301, 1083, 1044, 622, 1446, 1097, 1206, 1119, 1345, 604, 1324, 920, 1129, 1340, 798, 444, 980, 997, 1232, 1087, 884, 1093, 422, 1135, 909, 1026, 1055, 824, 462, 678, 945, 1234, 1149, 1542, 1177, 675, 1421, 779, 1013, 1486, 1388, 1191, 514, 1219, 760, 974, 773, 477, 1190, 784, 674, 1428, 778, 1257, 477, 1252, 901, 1352, 1037, 1224, 970, 813, 1009, 1162, 519, 1088, 1157, 1409, 1182, 1089, 755, 438, 1076, 725, 869, 900, 436, 1148, 1421, 1588, 956, 978, 749, 950, 932, 516, 1046, 814, 865, 588, 1303, 713, 1614, 1024, 421, 959, 897, 518, 987, 1275, 765, 887, 893, 333, 925, 732, 635, 1169, 910, 1434, 575, 959, 653, 850, 728, 583, 1093, 542, 1316, 1031, 1059, 1122, 642, 1121, 891, 1209, 925, 1299, 896, 932, 1288, 934, 984, 580, 1113, 1413, 1224, 964, 643, 773, 1337, 1663, 1341, 657, 1357, 1473, 1292, 1551, 970, 1209, 792, 1339, 1141, 1140, 1320, 616, 1383, 1126, 980, 1014, 1146, 1245, 859, 1298, 513, 1182, 662, 1014, 1562, 1297, 1151, 502, 1139, 874, 1259, 1645, 1169, 1242, 1072, 1412, 1115, 1275, 1466, 1239, 1038, 1184, 458, 1094, 1440, 810, 1352, 1339, 830, 1354, 801, 848, 671, 1300, 1147, 1047, 1625, 1117, 1046, 1327, 1047, 1237, 1101, 1018, 1016, 745, 1066, 1132, 1221, 841, 1512, 522, 853, 1535, 1248, 975, 694, 1143, 824, 1009, 1185, 1288, 908, 200, 1308, 904, 1665, 687, 843, 943, 1199, 1198, 1379, 1168, 571, 789, 630, 846, 602, 1342, 1350, 995, 1114, 408, 1043, 1304, 945, 751, 793, 741, 1072, 1006, 1401, 1331, 1296, 1152, 856, 1337, 321, 881, 937, 1318, 1535, 1560, 806, 1696, 924, 625, 994, 1058, 996, 1649, 1183, 1442, 1118, 901, 1094, 1408, 1016, 1653, 1259, 800, 1317, 677, 815, 894, 1017, 1278, 957, 1109, 1284, 1321, 1220, 947, 1383, 860, 1220, 783, 873, 979, 1025, 1228, 1007, 1417, 1231, 735, 783, 872, 492, 1028, 1244, 852, 1144, 1645, 1172, 1088, 1110, 1204, 1622, 738, 1146, 1513, 1106, 1564, 1079, 1021, 1436, 776, 917, 1467, 1051, 814, 1217, 812, 1174, 1271, 863, 1187, 1461, 644, 1308, 1154, 1263, 1225, 1121, 867, 1110, 1157, 1139, 989, 1033, 1270, 1163, 1170, 1037, 880, 803, 1098, 807, 968, 1446, 1235, 1064, 1547, 979, 842, 500, 838, 1398, 939, 916, 953, 920, 946, 851, 1428, 1210, 960, 762, 1456, 1519, 1384, 898, 1361, 995, 1100, 1508, 856, 1284, 553, 1330, 1249, 1258, 1020, 764, 1165, 1179, 1047, 1056, 1285, 1266, 1286, 853, 1397, 1515, 987, 547, 1296, 1215, 965, 489, 1444, 800, 849, 1300, 1242, 662, 1085, 818, 918, 748, 954, 1024, 1022, 954, 1109, 1218, 821, 1431, 1587, 1315, 1081, 1140, 754, 943, 1371, 1003, 840, 1475, 722, 1081, 1033, 1216, 1254, 1175, 1122, 1203, 728, 488, 1189, 1377, 1136, 907, 1267, 1416, 751, 1169, 1101, 1289, 1241, 597, 1322, 1625, 1332, 961, 985, 915, 1128, 1069, 764, 1175, 1177, 1156, 889, 1075, 1088, 1251, 1031, 738, 1523, 1229, 994, 1489, 637, 1185, 1651, 1112, 680, 1608, 1197, 513, 1538, 978, 1040, 1000, 1432, 1030, 887, 833, 1057, 1094, 1565, 1190, 696, 1178, 1556, 1045, 1307, 1294, 1436, 1096, 747, 1485, 1128, 1430, 664, 1653, 1180, 1597, 1167, 1452, 776, 1341, 1305, 1142, 1418, 849, 562, 1247, 998, 1391, 1161, 941, 1387, 912, 1149, 1078, 1029, 1141, 1197, 582, 701, 961, 1423, 1195, 1674, 1205, 964, 1633, 929, 1127, 1571, 1581, 1291, 681, 1272, 781, 981, 783, 765, 1295, 974, 1015, 1516, 873, 1324, 482, 1262, 1371, 1648, 1101, 1240, 1115, 837, 1048, 1301, 763, 1260, 1229, 1426, 1316, 1208, 963, 1083, 1125, 992, 882, 1034, 467, 1176, 1429, 1610, 1452, 1376, 753, 1184, 1239, 777, 1291, 1264, 1223, 659, 1378, 797, 1632, 1071, 575, 1099, 926, 801, 1042, 1322, 1111, 1234, 1112, 979, 962, 993, 713, 1271, 1008, 1533, 653, 999, 746, 876, 751, 1123, 1319, 693, 1354, 1209, 1207, 1159, 1250, 1192, 1385, 1350, 952, 1543, 1020, 1067, 1632, 1119, 1635, 1165, 1161, 1483, 1347, 983, 669, 796, 1412, 1684, 1374, 886, 1468, 1479, 1594, 1781, 1113, 1274, 969, 1343, 1403, 1261, 1440, 681, 1424, 1216, 1207, 1210, 1172, 1325, 935, 1414, 1123, 1287, 1158, 1032, 1589, 1554, 1326, 562, 1313, 949, 1296, 1760, 1260, 1552, 1129, 1422, 1258, 1542, 1525, 1253, 1089, 1255, 1131, 1220, 1652, 869, 1410, 1351, 1266, 1518, 868, 884, 1302, 1486, 1362, 1185, 1652, 1172, 1205, 1388, 1479, 1270, 1224, 1297, 1138, 817, 1170, 1214, 1240, 1153, 1551, 817, 915, 1553, 1319, 1496, 717, 1194, 850, 1091, 1256, 1541, 1039, 561, 1358, 938, 1707, 1557, 1368, 1160, 1342, 1404, 1515, 1435, 727, 790, 1396, 854, 891, 1783, 1365, 1271, 1183, 1400, 1205, 1367, 1068, 794, 1006, 803, 1485, 1164, 1422, 1502, 1334, 1359, 1215, 1698, 1042, 1204, 1028, 1458, 1550, 1600, 1111, 1700, 1132, 992, 1134, 1430, 1049, 1731, 1323, 1555, 1228, 1456, 1099, 1545, 1091, 1685, 1445, 857, 1612, 735, 1126, 946, 1168, 1399, 1222, 1192, 1373, 1575, 1317, 1073, 1506, 1143, 1440, 1438, 1263, 1105, 1327, 1256, 1126, 1619, 1265, 924, 961, 1023, 866, 1070, 1437, 1132, 1487, 1675, 1333, 1423, 1182, 1295, 1683, 939, 1154, 1617, 1212, 1665, 1414, 1107, 1534, 1282, 1402, 1485, 1096, 1059, 1495, 981, 1235, 1381, 1017, 1240, 1534, 875, 1561, 1279, 1354, 1353, 1396, 1243, 1547, 1356, 1166, 1181, 1343, 1285, 1247, 1255, 1357, 975, 919, 1318, 988, 1477, 1521, 1358, 1206, 1549, 1146, 1117, 1305, 1019, 1406, 982, 942, 1014, 1075, 1004, 860, 1512, 1241, 1053, 858, 1620, 1527, 1415, 1251, 1497, 1108, 1166, 1667, 967, 1434, 665, 1335, 1313, 1406, 1283, 902, 1362, 1358, 1501, 1222, 1427, 1280, 1309, 984, 1647, 1573, 1449, 618, 1328, 1310, 1120, 844, 1739, 1424, 1246, 1474, 1561, 699, 1277, 826, 1386, 1257, 1227, 1056, 1189, 975, 1125, 1329, 917, 1464, 1784, 1405, 1152, 1153, 935, 1092, 1464, 1040, 907, 1592, 1428, 1136, 1063, 1420, 1390, 1251, 1217, 1268, 1143, 708, 1603, 1407, 1160, 1207, 1340, 1488, 998, 1315, 1344, 1300, 1365, 1134, 1401, 1629, 1366, 1008, 1013, 1211, 1179, 1188, 825, 1262, 1393, 1469, 1173, 1077, 1248, 1417, 1095, 907, 1654, 1320, 1065, 1598, 799, 1601, 1656, 1190, 714, 1754, 1595, 651, 1647, 1063, 1397, 1157, 1481, 1237, 1060, 1482, 1287, 1192, 1618, 1394, 1259, 1558, 1635, 1162, 1377, 1803, 1492, 1476, 774, 1626, 1420, 1504, 689, 1687, 1372, 1616, 1199, 1471, 934, 1342, 1351, 1261, 1442, 923, 723, 1361, 1084, 1450, 1233, 1011, 1389, 1338, 1186, 1340, 1110, 1327, 1225, 690, 1483, 1064, 1443, 1258, 1697, 1213, 966, 1687, 1161, 1314, 1605, 1877, 1477, 747, 1280, 1028, 1138, 820, 782, 1560, 1038, 1592, 1517, 894, 1586, 568, 1276, 1379, 1753, 1230, 1749, 1122, 1458, 1080, 1526, 1411, 1309, 1332, 1430, 1381, 1255, 1648, 1248, 1267, 1459, 914, 1085, 1184, 1180, 1459, 1629, 1463, 1378, 845, 1343, 1415, 1037, 1292, 1336, 1431, 734, 1426, 1193, 1688, 1279, 940, 1313, 1036, 1155, 1099, 1406, 1490, 1326, 1556, 1069, 1005, 1142, 1010, 1273, 1312, 1546, 761, 1624, 1065, 921, 1055, 1134, 1518, 839, 1435, 1234, 1244, 1238, 1297, 1254, 1494, 1484, 1145, 1604, 1404, 1289, 1645, 1131, 1658, 1198, 1392, 1557, 1667, 1082, 972, 918, 1432, 1701, 1637, 1312, 1579, 1680, 1864, 1825, 1194, 1457, 1370, 1411, 1479, 1398, 1510, 1049, 1447, 1576, 1252, 1290, 1360, 1679, 1070, 1506, 1699, 1359, 1204, 1222, 1818, 1596, 1363, 834, 1383, 1513, 1499, 1766, 1646, 1629, 1328, 1423, 1460, 1640, 1923, 1302, 1216, 1364, 1369, 1233, 1739, 1031, 1624, 1505, 1434, 1630, 1451, 1196, 1548, 1527, 1454, 1520, 1707, 1407, 1467, 1561, 1604, 1319, 1543, 1456, 1374, 881, 1453, 1323, 1735, 1246, 1660, 1381, 1188, 1709, 1391, 1532, 771, 1264, 851, 1219, 1322, 1639, 1144, 960, 1615, 1136, 1732, 1690, 1371, 1433, 1377, 1459, 1571, 1447, 1058, 1245, 1451, 1053, 949, 1894, 1531, 1305, 1253, 1493, 1303, 1380, 1581, 1330, 1082, 1036, 1541, 1520, 1437, 1585, 1359, 1425, 1410, 1857, 1465, 1239, 1208, 1585, 1642, 1807, 1743, 1710, 1167, 1135, 1465, 1513, 1175, 1759, 1524, 1655, 1348, 1471, 1150, 1581, 1917, 1694, 1545, 911, 1622, 852, 1348, 1191, 1261, 1410, 1491, 1237, 1401, 1822, 1325, 1457, 1668, 1236, 1449, 1698, 1270, 1392, 1418, 1486, 1133, 1797, 1503, 1041, 1198, 1392, 1041, 1632, 1621, 1311, 1638, 1832, 1364, 1452, 1499, 1472, 1913, 1295, 1208, 1766, 1369, 1780, 1541, 1462, 1545, 1336, 1569, 1693, 1385, 1276, 1547, 1266, 1338, 1505, 1029, 1493, 1670, 958, 1572, 1607, 1446, 1634, 1530, 1414, 1704, 1552, 1441, 1653, 1480, 1310, 1712, 1347, 1403, 1408, 951, 1360, 1213, 1562, 1710, 1419, 1528, 1589, 1443, 1345, 1636, 1071, 1637, 1026, 1644, 1030, 1638, 1221, 1119, 1570, 1712, 1253, 989, 1742, 1790, 1537, 1619, 1508, 1150, 1326, 1926, 1470, 1702, 940, 1733, 1362, 1429, 1299, 938, 1606, 1453, 1568, 1335, 1738, 1564, 1312, 1275, 1718, 1575, 1528, 937, 1491, 1415, 1179, 900, 1843, 1471, 1345, 1536, 1573, 930, 1301, 1020, 1482, 1412, 1274, 1105, 1347, 1344, 1764, 1729, 1062, 1563, 1843, 1532, 1228, 1302, 1273, 1397, 1591, 1391, 1052, 1662, 1470, 1181, 1425, 1427, 1578, 1263, 1395, 1292, 1317, 899, 1808, 1539, 1650, 1231, 1376, 1515, 1001, 1330, 1603, 1331, 1419, 1369, 1444, 1709, 1374, 1068, 1019, 1306, 1298, 1293, 1011, 1831, 1502, 1590, 1238, 1148, 1269, 1555, 1114, 1036, 1740, 1325, 1405, 1670, 1062, 1773, 1688, 1335, 1476, 1827, 1723, 820, 1748, 1072, 1536, 1398, 1732, 1587, 1400, 1529, 1355, 1304, 1651, 1722, 1268, 1673, 1800, 1178, 1503, 1847, 1656, 1497, 1595, 1689, 1576, 1740, 963, 1822, 1393, 1743, 1246, 1499, 1106, 1356, 1387, 1367, 1745, 1009, 780, 1458, 1206, 1673, 1250, 1662, 1611, 1555, 1193, 1353, 1597, 1559, 1445, 1187, 1677, 1155, 1464, 1497, 1713, 1357, 1450, 1696, 1257, 1339, 1685, 1894, 1615, 1733, 1315, 1364, 1363, 1418, 1123, 1738, 1445, 1620, 1660, 1156, 1599, 926, 1507, 1640, 1763, 1289, 1791, 1648, 1601, 1321, 1544, 1577, 1683, 1376, 1543, 1540, 1361, 1666, 1273, 1433, 1504, 993, 1265, 1288, 1454, 1482, 1736, 1481, 1439, 1286, 1467, 1461, 1474, 1510, 1489, 1681, 934, 1643, 1606, 1791, 1491, 1341, 1429, 1127, 1227, 1299, 1600, 1904, 1395, 1588, 1084, 1057, 1183, 1252, 1283, 1478, 1611, 1320, 1851, 1355, 1223, 1147, 1403, 1576, 1035, 1460, 1260, 1641, 1538, 1368, 1475, 1511, 1672, 1329, 1764, 1426, 1353, 1691, 1214, 1915, 1247, 1538, 1658, 1716, 1689, 1000, 986, 1884, 1975, 1730, 1899, 1623, 1834, 1981, 1952, 1473, 1490, 1529, 1557, 1748, 1544, 1617, 1720, 1690, 1667, 1630, 1641, 1678, 1750, 1367, 1525, 1786, 1447, 1395, 1390, 1826, 1598, 1427, 861, 1582, 1658, 1878, 1768, 1651, 1699, 1532, 1498, 1529, 1765, 1939, 1384, 1723, 1872, 1758, 1438, 1742, 1093, 1657, 1759, 1650, 1634, 1519, 1290, 1569, 1573, 1591, 1643, 1928, 1411, 1786, 1582, 1661, 1521, 1657, 1609, 1633, 972, 1468, 1644, 1776, 1388, 1692, 1409, 1278, 1812, 1631, 1873, 1310, 1272, 1109, 1333, 1522, 1722, 1612, 1048, 1741, 1674, 1755, 1711, 1568, 1437, 1484, 1567, 1746, 1583, 1148, 1307, 1570, 1314, 950, 1906, 1654, 1379, 1494, 1518, 1455, 1393, 1703, 1390, 1606, 1226, 1669, 1580, 1692, 1719, 1366, 1438, 1433, 1982, 1514, 1676, 1609, 1742, 1690, 1819, 1763, 1730, 1321, 1566, 2031, 1680, 1741, 1839, 1762, 1925, 1536, 1524, 1283, 1723, 1924, 1706, 1558, 1375, 1758, 1417, 1691, 1350, 1727, 1475, 1537, 1457, 1506, 1917, 1386, 1695, 1753, 1355, 1756, 1775, 1613, 1563, 1425, 1488, 1176, 1827, 1556, 1131, 1349, 1448, 1281, 1749, 1664, 1572, 1744, 1860, 1813, 1762, 1642, 1689, 1928, 1570, 1878, 1890, 1739, 1809, 1799, 1663, 1591, 1495, 1695, 1762, 1580, 1306, 1879, 1462, 1413, 1637, 1078, 1567, 1785, 1078, 1659, 1801, 1530, 1769, 1579, 1549, 1747, 1682, 1796, 1668, 1727, 1822, 1836, 1378, 1551, 1501, 1810, 1478, 1278, 1574, 1764, 1533, 1627, 1714, 1489, 1480, 1726, 1584, 1643, 1387, 1655, 1058, 1720, 1370, 1595, 1795, 1832, 1843, 1212, 1871, 1840, 1886, 1831, 1720, 1272, 1765, 1956, 1496, 1855, 1144, 1830, 1404, 1593, 1507, 967, 1768, 1671, 1842, 1469, 1829, 1593, 1621, 1516, 1763, 1612, 1982, 1124, 1613, 1715, 1375, 1311, 1844, 1509, 1448, 1542, 1660, 1005, 1490, 1408, 1620, 1707, 1277, 1568, 1373, 1887, 1827, 1778, 1510, 1782, 1886, 1537, 1424, 1402, 1282, 1496, 1681, 1649, 1286, 1858, 1566, 1622, 1972, 1562, 1868, 1316, 1754, 1725, 1559, 1086, 1873, 1594, 1792, 1351, 1579, 1889, 1043, 1380, 1789, 1588, 1481, 1487, 1650, 1717, 1602, 1413, 1226, 1370, 1368, 1346, 1493, 1902, 1554, 1713, 1564, 1244, 1432, 1597, 1328, 1285, 1828, 1484, 1466, 1719, 1550, 1909, 1854, 1582, 1596, 1903, 1751, 1530, 1905, 1227, 1771, 1605, 1807, 1777, 1738, 1592, 1460, 1507, 1708, 1745, 1385, 1686, 1869, 1277, 1517, 1867, 1776, 1846, 1809, 1803, 1674, 1748, 1191, 1837, 1420, 1754, 1274, 1644, 1201, 1366, 1450, 1402, 1757, 1140, 1500, 1465, 1509, 1793, 1352, 1804, 1702, 1560, 1431, 1549, 1679, 1769, 1615, 1229, 1740, 1775, 1534, 1498, 1757, 1416, 1567, 1711, 1360, 1472, 1705, 1923, 1782, 1746, 1767, 1575, 1531, 1628, 1772, 1868, 1771, 1628, 1719, 1287, 1623, 1900, 1709, 1703, 1840, 1382, 1841, 1808, 1860, 1788, 1652, 1687, 1810, 1488, 1661, 1867, 1476, 1785, 1646, 1468, 1611, 1159, 1492, 1291, 1463, 1716, 1778, 1669, 1448, 1539, 1633, 1511, 1523, 1672, 1821, 1718, 1349, 1875, 1659, 1835, 1558, 1520, 1670, 1639, 1540, 1885, 1779, 1972, 1531, 1874, 1627, 1202, 1639, 1553, 1540, 1539, 1646, 1439, 1856, 1444, 1279, 1241, 1952, 1701, 1280, 1616, 1332, 1692, 1664, 1373, 1781, 1733, 1995, 1571, 1777, 1593, 1578, 1869, 1233, 1916, 1504, 1849, 1704, 1729, 1896, 1953, 1449, 1899, 2007, 1744, 2003, 1875, 1935, 2016, 1993, 1527, 1788, 1734, 1726, 1823, 1636, 1619, 1734, 1755, 1829, 1773, 1799, 1700, 1947, 1938, 1647, 1789, 1550, 1396, 1590, 1964, 1951, 1634, 1066, 1856, 1717, 1988, 1791, 1664, 1977, 1544, 1715, 1563, 1801, 1988, 1725, 1815, 1921, 1897, 1442, 1831, 1217, 1752, 1866, 1861, 1659, 1706, 1724, 1678, 1714, 1724, 1958, 2036, 1487, 1978, 1657, 1997, 1800, 1895, 1708, 1811, 1678, 1705, 1962, 1927, 1699, 1694, 1625, 1501, 1844, 1686, 1958, 1614, 1307, 1129, 1407, 1683, 1835, 1800, 1152, 1793, 1879, 1820, 1747, 1598, 1922, 1553, 1768, 1811, 1838, 1290, 1953, 1781, 1610, 1626, 1936, 1751, 1665, 1584, 1823, 1816, 1758, 1932, 1454, 1793, 1436, 1817, 1675, 1697, 1927, 1655, 1546, 1677, 2003, 1666, 1735, 1811, 1808, 1813, 1834, 1850, 1821, 1565, 1975, 2045, 1816, 1809, 1951, 1862, 2048, 1911, 1686, 1441, 1878, 1976, 1865, 1906, 1608, 1871, 1469, 1803, 1932, 1798, 1862, 1881, 1577, 1802, 1979, 1455, 1977, 1820, 1495, 1816, 1907, 1784, 1774, 1789, 1743, 1533, 1830, 1684, 1201, 1548, 1566, 1334, 1776, 1724, 1752, 1880, 1908, 1863, 1898, 1925, 1693, 2033, 1799, 1910, 1893, 1928, 1833, 1841, 1706, 1801, 1599, 1737, 1934, 1688, 2035, 1885, 1796, 1807, 1881, 1419, 1901, 1948, 1137, 1685, 1848, 1624, 1829, 1868, 1630, 1819, 1772, 1946, 1787, 1805, 1941, 1854, 1554, 1722, 1729, 1877, 1863, 1736, 1626, 1918, 1631, 1628, 1986, 1616, 1679, 1820, 1869, 1756, 1662, 1876, 1380, 1815, 1914, 1680, 1956, 1870, 1947, 1421, 1886, 1936, 1911, 1918, 1728, 1346, 1769, 2021, 1601, 1912, 1548, 1835, 1502, 1605, 1927, 1372, 1865, 1673, 1891, 1494, 1882, 1779, 1814, 1940, 1806, 1759, 2011, 1441, 1623, 1846, 1514, 1663, 2033, 1552, 1819, 1574, 1850, 1671, 1702, 1757, 1756, 1836, 1384, 1980, 1640, 2038, 2006, 1794, 1805, 1785, 1955, 1580, 1930, 1583, 1526, 1523, 1833, 1725, 1462, 1883, 1682, 1794, 1995, 1892, 1874, 1349, 1818, 1730, 1604, 1170, 1890, 1777, 1806, 1701, 1589, 1911, 1254, 1526, 1942, 1825, 1514, 1966, 1780, 1864, 1671, 1817, 1677, 1443, 1855, 1569, 1922, 1934, 1712, 1931, 1765, 1888, 1463, 1627, 1505, 1492, 1870, 1590, 1565, 1922, 1698, 1956, 1985, 2006, 1635, 1931, 1899, 1600, 1973, 1268, 1823, 1710, 1867, 1916, 1804, 1642, 1466, 1767, 1832, 1996, 1672, 1824, 1921, 1924, 1838, 1904, 1908, 1861, 1960, 1998, 1728, 1760, 1394, 1993, 1546, 1974, 1525, 1847, 1202, 1613, 1453, 1602, 1826, 1875, 1594, 1596, 1753, 1970, 1478, 2055, 1853, 1713, 1474, 1797, 1682, 1943, 1745, 1830, 1814, 1897, 1621, 1817, 1802, 1617, 1649, 1978, 1500, 1483, 1804, 2040, 1983, 1775, 1893, 1636, 1896, 1774, 1784, 1903, 1782, 1783, 1852, 1894, 1770, 1924, 2020, 1926, 1929, 1714, 2009, 1989, 1865, 1898, 1737, 1945, 1847, 1696, 1767, 1907, 1715, 1849, 1967, 1694, 1747, 1337, 1608, 1363, 1676, 1734, 1859, 1755, 1470, 1584, 1957, 1919, 1528, 1788, 1900, 1741, 1508, 1971, 1749, 1937, 1970, 1941, 1794, 1693, 1721, 1991, 1915, 1997, 1824, 1942, 1996, 1236, 1669, 1887, 1654, 1982, 1898, 1761, 1883, 1700, 1521, 1681, 2011, 1751, 1281, 1684, 1607, 1845, 1860, 1524, 1844, 1901, 1999, 1760, 1940, 1705, 1736, 1987, 1721, 2033, 2024, 1990, 2047, 1965, 2018, 2044, 1473, 1920, 2030, 1968, 2045, 2025, 1995, 2054, 2017, 1559, 1876, 1891, 1871, 2013, 1949, 1821, 1892, 1834, 1946, 1778, 1880, 1864, 2042, 2016, 2026, 1945, 2031, 1574, 1853, 1980, 2034, 2056, 2012, 1912, 1812, 2031, 1836, 1992, 2058, 1941, 1814, 2007, 2051, 2048, 2044, 1880, 1926, 2047, 1761, 1839, 1365, 1772, 1986, 1985, 1905, 2060, 1909, 1857, 1944, 1826, 2000, 2050, 2023, 2020, 1931, 2023, 2043, 2005, 1967, 1872, 1907, 1944, 1981, 1965, 1999, 1711, 1916, 1517, 1958, 1954, 2023, 1961, 2064, 1798, 1577, 1930, 1896, 1859, 1382, 1987, 2039, 2037, 1787, 1666, 1984, 1602, 1933, 2008, 2057, 1338, 1976, 2038, 1971, 1950, 1954, 1991, 1828, 1695, 1845, 1873, 1889, 2037, 1641, 1961, 1731, 1884, 1881, 1914, 1978, 1783, 1925, 1882, 2010, 2062, 1846, 1921, 2029, 2046, 1910, 2026, 1953, 1607, 2063, 2059, 2000, 1884, 2008, 2014, 2052, 2015, 1848, 1716, 2003, 2036, 2006, 1932, 1973, 1976, 1522, 2028, 2059, 1917, 1947, 2027, 1954, 1964, 2059, 2035, 1999, 1910, 1893, 1877, 1933, 1934, 2019, 1858, 1990, 2037, 1876, 1903, 1792, 1966, 2025, 1509, 1853, 1908, 1837, 2044, 1914, 1938, 1913, 2004, 1824, 2047, 1856, 1938, 2032, 2022, 1870, 1912, 1779, 2039, 2049, 1761, 1983, 1950, 2054, 2002, 1959, 1848, 1919, 1790, 1993, 1967, 1900, 1718, 1897, 2019, 2051, 2053, 1838, 1930, 1918, 2015, 2036, 1904, 1962, 1890, 1852, 1845, 2009, 2050, 2004, 2032, 1883, 2057, 2028, 2040, 2056, 1851, 1737, 1939, 1872, 1939, 1975, 1988, 1676, 1919, 1994, 2019, 1984, 1885, 2005, 1812, 2008, 2040, 1957, 2028, 1842, 2032, 2039, 2062, 1828, 1992, 1746, 1841, 1980, 1940, 1994, 1416, 1937, 1866, 1996, 1866, 1929, 2013, 1815, 2064, 1959, 2012, 2022, 1735, 1727, 1950, 1981, 1991, 2043, 1929, 1920, 1578, 1859, 1960, 1949, 1852, 1955, 1966, 2018, 2063, 1656, 2055, 2041, 1969, 2046, 1905, 2017, 1726, 1943, 1717, 2009, 1802, 2062, 1750, 1675, 1990, 1963, 1795, 2061, 1998, 2042, 1770, 2049, 1862, 1668, 2056, 2000, 1987, 2002, 1797, 1882, 1963, 1512, 1708, 1949, 1901, 1935, 1997, 1971, 2017, 2054, 1920, 1691, 1585, 2001, 2005, 1963, 2015, 1933, 2026, 1909, 1913, 1704, 1798, 1962, 1610, 2024, 1969, 1810, 1994, 1703, 2055, 2021, 2030, 2024, 1986, 1906, 1825, 2002, 1770, 1855, 1837, 2014, 2010, 1849, 1697, 1661, 1863, 1935, 2052, 1957, 2058, 1937, 2061, 2035, 2045, 1984, 1888, 1965, 2058, 1854, 2007, 1842, 2060, 1888, 1989, 1599, 2014, 1638, 2027, 1731, 2012, 1891, 1936, 1614, 1618, 1806, 2030, 1586, 2057, 1968, 1974, 1477, 1959, 1840, 1973, 1970, 1955, 1951, 1998, 1985, 1892, 1818, 1874, 1961, 2046, 1989, 1960, 2041, 2049, 2001, 1948, 2048, 1983, 1944, 1790, 2042, 2051, 1992, 1923, 2041, 1952, 1972, 1945, 2029, 1948, 1974, 1943, 2038, 2050, 1942, 1968, 1805, 1977, 2004, 1752, 1787, 1915, 1732, 2063, 2021, 1766, 1946, 1618, 1858, 2025, 1857, 1773, 1895, 1833, 1887, 1744, 1979, 2010, 1850, 2061, 2016, 1780, 1586, 2027, 1969, 2034, 1979, 2018, 1813, 1839, 1902, 2013, 2011, 2052, 1851, 2029, 2064, 1386, 1750, 1902, 1771, 2034, 2001, 1795, 2053, 1792, 1631, 1964, 2053, 1796, 1409, 1774, 1721, 1889, 1879, 1728, 2020, 2043, 2060, 1895, 2022, 1861, 1786
+};
+
+double H_cols[] = {
+208, 242, 84, 114, 314, 135, 349, 90, 64, 57, 26, 52, 16, 142, 120, 244, 167, 164, 133, 179, 22, 180, 413, 161, 224, 121, 57, 22, 394, 17, 9, 54, 84, 20, 98, 311, 322, 308, 86, 91, 77, 41, 110, 192, 18, 11, 210, 133, 248, 276, 389, 100, 37, 4, 239, 15, 32, 15, 7, 10, 109, 82, 19, 50, 137, 278, 43, 181, 89, 206, 113, 285, 10, 95, 12, 180, 23, 93, 100, 124, 200, 130, 81, 149, 6, 251, 181, 227, 156, 215, 194, 284, 206, 177, 171, 174, 40, 136, 187, 89, 98, 156, 44, 30, 48, 78, 349, 126, 56, 3, 212, 43, 111, 183, 63, 54, 35, 63, 333, 158, 96, 100, 270, 38, 97, 4, 139, 163, 67, 251, 139, 42, 214, 117, 26, 98, 132, 105, 13, 61, 330, 223, 183, 95, 295, 95, 55, 29, 65, 35, 75, 130, 8, 98, 344, 46, 239, 155, 131, 75, 246, 3, 44, 260, 199, 21, 99, 118, 76, 8, 87, 271, 257, 171, 98, 44, 255, 17, 276, 91, 50, 21, 90, 262, 118, 208, 214, 35, 140, 159, 58, 277, 158, 180, 53, 93, 58, 264, 40, 98, 4, 284, 183, 24, 7, 123, 133, 57, 223, 124, 156, 202, 34, 324, 67, 452, 63, 123, 303, 303, 169, 40, 32, 24, 32, 5, 220, 218, 103, 222, 113, 111, 100, 30, 146, 266, 4, 195, 14, 55, 145, 37, 40, 18, 184, 188, 267, 38, 116, 35, 60, 53, 133, 58, 9, 296, 63, 57, 30, 17, 86, 157, 105, 29, 73, 285, 122, 9, 31, 199, 347, 73, 55, 135, 86, 2, 42, 67, 119, 21, 351, 35, 213, 173, 61, 176, 194, 109, 72, 77, 273, 133, 244, 90, 313, 220, 27, 192, 63, 299, 208, 202, 3, 66, 14, 19, 127, 68, 348, 246, 26, 87, 75, 20, 215, 93, 212, 180, 149, 114, 133, 48, 235, 17, 247, 257, 42, 149, 57, 363, 75, 334, 67, 97, 29, 109, 241, 59, 332, 15, 228, 6, 186, 81, 271, 31, 103, 122, 150, 105, 110, 92, 277, 213, 358, 37, 100, 129, 46, 367, 118, 26, 115, 211, 3, 77, 217, 23, 24, 145, 70, 48, 68, 179, 112, 30, 110, 177, 14, 97, 68, 66, 103, 105, 83, 231, 29, 383, 45, 64, 42, 32, 201, 269, 67, 9, 149, 3, 34, 86, 373, 51, 409, 130, 39, 80, 177, 118, 34, 248, 175, 50, 37, 76, 14, 7, 122, 49, 262, 27, 79, 102, 295, 113, 26, 111, 135, 10, 356, 97, 21, 2, 129, 451, 140, 60, 42, 191, 33, 152, 25, 279, 99, 22, 124, 168, 305, 34, 104, 224, 154, 50, 71, 97, 60, 209, 73, 57, 10, 322, 159, 375, 104, 17, 273, 374, 81, 121, 160, 157, 411, 88, 236, 166, 88, 53, 164, 135, 36, 375, 291, 211, 4, 233, 84, 94, 47, 29, 10, 306, 54, 183, 16, 128, 42, 86, 96, 488, 31, 109, 150, 42, 332, 110, 315, 44, 321, 82, 109, 235, 80, 212, 35, 128, 80, 215, 7, 115, 44, 102, 281, 86, 27, 79, 280, 33, 227, 142, 113, 104, 102, 281, 161, 238, 197, 106, 111, 72, 163, 76, 41, 58, 4, 46, 45, 122, 281, 219, 52, 53, 45, 66, 264, 69, 37, 16, 138, 221, 176, 176, 98, 42, 75, 92, 80, 158, 163, 71, 26, 49, 109, 108, 70, 85, 378, 186, 178, 9, 12, 4, 74, 25, 65, 207, 8, 339, 5, 45, 205, 163, 234, 14, 56, 77, 62, 185, 55, 89, 19, 228, 117, 113, 80, 9, 8, 38, 74, 10, 112, 32, 205, 8, 242, 142, 119, 26, 158, 28, 148, 54, 69, 28, 81, 91, 142, 78, 158, 49, 66, 45, 179, 249, 91, 90, 219, 153, 339, 90, 14, 56, 60, 392, 9, 162, 274, 102, 79, 89, 206, 114, 365, 2, 232, 172, 36, 8, 14, 317, 173, 65, 2, 37, 112, 273, 38, 179, 107, 244, 9, 173, 67, 141, 265, 156, 96, 102, 158, 77, 96, 331, 2, 102, 302, 94, 23, 93, 92, 408, 95, 229, 2, 25, 326, 62, 82, 166, 185, 7, 170, 15, 30, 216, 93, 94, 186, 24, 124, 268, 36, 108, 156, 448, 65, 134, 356, 79, 91, 165, 63, 30, 123, 56, 164, 97, 348, 262, 72, 294, 3, 33, 36, 143, 79, 31, 158, 124, 46, 131, 115, 103, 33, 280, 22, 69, 80, 343, 386, 295, 107, 39, 122, 18, 215, 78, 166, 136, 163, 222, 5, 405, 196, 253, 401, 78, 138, 184, 190, 131, 5, 141, 91, 84, 10, 210, 184, 171, 39, 20, 283, 92, 337, 257, 172, 160, 28, 134, 170, 18, 110, 108, 85, 21, 62, 122, 23, 10, 128, 161, 152, 156, 65, 249, 124, 191, 282, 139, 220, 238, 24, 60, 66, 41, 196, 185, 68, 72, 51, 121, 12, 218, 13, 101, 89, 93, 298, 293, 197, 201, 332, 36, 128, 160, 182, 42, 19, 53, 259, 116, 331, 131, 84, 125, 43, 285, 79, 112, 66, 66, 288, 93, 93, 158, 87, 104, 134, 131, 156, 58, 33, 6, 42, 16, 130, 182, 354, 141, 12, 65, 60, 1, 169, 175, 82, 44, 82, 108, 17, 69, 28, 29, 80, 145, 25, 66, 88, 14, 64, 290, 160, 46, 113, 1, 251, 55, 61, 185, 199, 153, 13, 237, 150, 269, 5, 100, 126, 243, 312, 56, 219, 203, 156, 144, 164, 161, 87, 236, 203, 10, 216, 13, 166, 239, 19, 141, 51, 284, 61, 11, 75, 205, 31, 128, 49, 2, 33, 5, 135, 100, 194, 78, 154, 245, 51, 321, 121, 160, 114, 74, 44, 113, 59, 259, 6, 49, 144, 6, 22, 214, 171, 98, 181, 225, 368, 8, 274, 154, 262, 234, 21, 19, 352, 9, 165, 20, 90, 85, 255, 367, 174, 29, 145, 43, 1, 3, 153, 10, 280, 77, 221, 12, 11, 142, 370, 143, 116, 145, 223, 330, 36, 9, 157, 99, 271, 88, 291, 49, 89, 47, 94, 394, 344, 305, 38, 30, 39, 6, 129, 1, 242, 268, 200, 298, 182, 297, 175, 27, 117, 135, 108, 246, 60, 38, 225, 48, 12, 124, 229, 55, 50, 311, 70, 133, 119, 151, 199, 73, 70, 98, 26, 76, 99, 154, 112, 76, 236, 273, 22, 109, 206, 61, 34, 146, 292, 132, 254, 42, 1, 121, 310, 33, 41, 49, 168, 226, 247, 459, 47, 211, 187, 41, 58, 8, 388, 359, 129, 83, 129, 190, 55, 189, 48, 258, 60, 58, 13, 205, 263, 232, 151, 96, 77, 31, 53, 64, 174, 197, 200, 25, 93, 191, 139, 217, 5, 117, 51, 212, 72, 28, 2, 236, 114, 320, 35, 106, 74, 28, 425, 282, 49, 132, 2, 82, 47, 143, 142, 100, 25, 79, 43, 24, 23, 399, 92, 97, 290, 31, 69, 109, 165, 83, 41, 98, 84, 195, 319, 347, 222, 37, 39, 104, 5, 196, 207, 47, 4, 223, 141, 32, 47, 81, 96, 31, 68, 101, 145, 177, 85, 129, 271, 334, 224, 36, 117, 56, 70, 410, 212, 87, 298, 361, 160, 164, 34, 19, 52, 66, 310, 4, 105, 40, 180, 137, 263, 37, 73, 237, 29, 135, 20, 7, 336, 197, 68, 2, 131, 28, 60, 88, 94, 58, 83, 38, 218, 7, 1, 71, 296, 149, 355, 146, 179, 64, 2, 418, 155, 127, 76, 348, 54, 83, 251, 48, 27, 185, 32, 84, 4, 89, 107, 360, 257, 29, 54, 318, 56, 95, 295, 51, 45, 47, 24, 256, 173, 92, 154, 63, 255, 321, 132, 76, 116, 92, 308, 20, 52, 178, 292, 87, 216, 275, 16, 152, 151, 165, 226, 276, 36, 1, 333, 30, 428, 17, 136, 11, 192, 45, 40, 34, 268, 68, 292, 54, 85, 120, 116, 206, 92, 99, 213, 91, 15, 14, 43, 112, 305, 319, 157, 136, 76, 25, 141, 95, 82, 11, 32, 41, 74, 49, 301, 122, 128, 338, 94, 129, 265, 71, 11, 109, 22, 328, 13, 105, 22, 196, 240, 198, 7, 146, 181, 115, 62, 61, 218, 64, 170, 222, 15, 99, 36, 31, 258, 69, 41, 56, 60, 129, 33, 103, 57, 21, 103, 127, 165, 13, 39, 328, 105, 228, 107, 120, 86, 98, 27, 54, 205, 167, 244, 74, 238, 38, 89, 5, 120, 329, 37, 37, 278, 24, 140, 118, 127, 203, 23, 106, 286, 243, 72, 152, 86, 61, 22, 11, 6, 34, 256, 269, 158, 175, 211, 317, 253, 50, 50, 27, 130, 454, 41, 250, 267, 144, 303, 11, 104, 63, 18, 124, 104, 58, 140, 25, 151, 58, 239, 286, 155, 217, 27, 182, 10, 398, 65, 190, 81, 69, 119, 78, 20, 136, 106, 51, 188, 200, 350, 303, 133, 53, 73, 15, 158, 262, 150, 192, 10, 289, 162, 362, 234, 232, 16, 225, 334, 294, 6, 105, 125, 68, 72, 176, 239, 20, 163, 353, 118, 117, 170, 90, 258, 50, 45, 88, 87, 128, 85, 4, 62, 34, 268, 258, 183, 25, 146, 85, 44, 133, 107, 140, 87, 64, 18, 70, 76, 95, 309, 147, 34, 308, 19, 237, 21, 217, 115, 49, 177, 201, 88, 149, 163, 5, 325, 455, 96, 52, 77, 24, 152, 130, 207, 67, 220, 36, 18, 48, 88, 40, 148, 179, 6, 155, 19, 138, 74, 39, 51, 198, 141, 142, 106, 103, 67, 111, 107, 186, 68, 37, 166, 28, 94, 289, 15, 126, 121, 43, 108, 117, 128, 406, 71, 333, 39, 38, 69, 313, 267, 17, 249, 40, 351, 40, 202, 138, 262, 105, 324, 75, 267, 123, 141, 156, 78, 112, 408, 97, 173, 91, 99, 239, 25, 376, 25, 254, 185, 157, 15, 61, 71, 113, 237, 237, 48, 29, 89, 1, 79, 41, 3, 24, 13, 187, 96, 52, 30, 137, 70, 82, 1, 47, 34, 444, 146, 63, 47, 59, 154, 115, 129, 298, 61, 3, 64, 85, 75, 244, 12, 47, 101, 103, 7, 169, 125, 213, 271, 378, 271, 100, 126, 134, 131, 31, 32, 16, 310, 222, 95, 12, 154, 89, 391, 205, 8, 27, 1, 85, 192, 85, 117, 140, 127, 132, 35, 31, 12, 263, 121, 6, 81, 65, 71, 78, 88, 140, 85, 227, 347, 68, 50, 7, 44, 215, 128, 26, 2, 96, 55, 66, 54, 22, 161, 258, 7, 13, 124, 101, 265, 21, 83, 233, 203, 274, 59, 354, 99, 59, 139, 13, 377, 107, 102, 23, 184, 32, 115, 61, 169, 320, 27, 171, 293, 57, 62, 46, 58, 147, 139, 235, 52, 46, 375, 46, 218, 319, 368, 61, 29, 174, 172, 83, 325, 29, 200, 198, 18, 303, 114, 173, 213, 35, 102, 20, 35, 211, 46, 180, 99, 301, 250, 208, 178, 93, 30, 76, 52, 165, 159, 372, 225, 278, 138, 136, 145, 231, 79, 44, 137, 50, 55, 119, 125, 39, 138, 101, 25, 166, 23, 192, 18, 39, 178, 116, 28, 178, 59, 188, 198, 16, 96, 46, 186, 108, 59, 255, 199, 258, 252, 88, 118, 134, 383, 150, 5, 139, 239, 228, 38, 227, 263, 43, 67, 175, 97, 188, 63, 147, 189, 17, 154, 62, 370, 219, 1, 198, 22, 56, 90, 318, 15, 20, 171, 45, 100, 30, 126, 131, 234, 11, 207, 254, 299, 349, 120, 196, 21, 26, 170, 114, 77, 8, 57, 190, 11, 214, 212, 345, 179, 225, 64, 114, 80, 185, 66, 138, 149, 43, 190, 127, 3, 3, 153, 222, 210, 11, 56, 104, 53, 153, 130, 56, 83, 71, 274, 95, 74, 121, 106, 173, 16, 114, 270, 33, 53, 267, 49, 332, 306, 68, 35, 28, 32, 213, 24, 113, 40, 18, 9, 89, 294, 250, 256, 70, 208, 291, 91, 82, 314, 39, 7, 181, 78, 13, 301, 405, 112, 316, 156, 393, 12, 110, 48, 73, 166, 39, 17, 132, 204, 104, 63, 62, 1, 45, 393, 5, 115, 47, 18, 248, 16, 272, 75, 317, 84, 70, 342, 207, 14, 191, 77, 154, 12, 107, 230, 132, 280, 42, 23, 147, 149, 17, 18, 8, 174, 73, 261, 197, 72, 4, 15, 34, 163, 159, 136, 12, 36, 196, 3, 40, 167, 71, 101, 111, 100, 237, 300, 32, 76, 9, 14, 137, 6, 53, 202, 71, 52, 148, 219, 17, 299, 41, 108, 48, 143, 65, 316, 133, 142, 92, 296, 323, 150, 211, 361, 261, 422, 167, 212, 195, 50, 317, 406, 372, 360, 314, 399, 203, 136, 211, 56, 195, 436, 229, 489, 295, 101, 109, 487, 184, 87, 279, 233, 399, 176, 470, 433, 364, 197, 115, 194, 314, 423, 246, 98, 401, 291, 268, 272, 357, 458, 298, 327, 21, 298, 299, 225, 220, 272, 51, 177, 93, 84, 403, 150, 336, 275, 236, 476, 243, 261, 373, 330, 248, 310, 365, 155, 240, 144, 276, 229, 292, 99, 175, 101, 317, 365, 297, 404, 260, 333, 417, 462, 434, 474, 444, 119, 309, 261, 260, 344, 435, 80, 123, 257, 183, 358, 197, 78, 16, 264, 260, 459, 195, 390, 147, 217, 467, 353, 165, 120, 151, 335, 83, 106, 28, 326, 252, 70, 298, 182, 153, 300, 260, 122, 111, 143, 302, 135, 235, 362, 236, 232, 287, 371, 309, 248, 248, 176, 215, 169, 183, 155, 140, 446, 91, 277, 263, 234, 126, 376, 335, 162, 490, 398, 182, 105, 378, 469, 159, 119, 457, 292, 249, 108, 59, 451, 20, 362, 228, 57, 306, 459, 301, 208, 329, 357, 82, 396, 279, 137, 396, 272, 202, 396, 282, 120, 308, 389, 287, 43, 311, 371, 59, 326, 125, 223, 190, 285, 134, 348, 219, 74, 343, 72, 455, 367, 179, 368, 395, 267, 227, 59, 225, 65, 21, 300, 310, 266, 259, 362, 168, 104, 69, 344, 417, 47, 335, 103, 126, 394, 41, 122, 166, 313, 265, 438, 118, 265, 204, 316, 439, 142, 90, 180, 440, 281, 392, 312, 210, 137, 189, 240, 247, 240, 320, 251, 157, 324, 208, 415, 245, 180, 262, 94, 141, 191, 110, 165, 165, 361, 61, 488, 378, 138, 178, 229, 396, 157, 168, 397, 266, 289, 240, 347, 299, 84, 451, 133, 391, 469, 324, 137, 116, 60, 365, 207, 200, 472, 450, 428, 330, 139, 159, 223, 217, 330, 245, 234, 238, 418, 391, 367, 308, 291, 304, 67, 244, 288, 382, 130, 461, 335, 118, 187, 334, 324, 441, 462, 112, 445, 59, 214, 230, 372, 44, 106, 167, 181, 211, 193, 148, 409, 264, 364, 353, 174, 263, 283, 406, 312, 349, 118, 455, 181, 259, 323, 175, 33, 152, 299, 141, 320, 314, 131, 62, 235, 335, 231, 340, 244, 425, 169, 311, 497, 241, 37, 436, 117, 184, 294, 157, 350, 301, 94, 162, 273, 13, 182, 101, 486, 341, 434, 322, 74, 144, 284, 139, 111, 403, 214, 52, 323, 327, 172, 227, 230, 208, 277, 221, 120, 409, 339, 123, 223, 252, 209, 237, 429, 295, 253, 35, 162, 454, 243, 199, 295, 385, 360, 241, 170, 390, 175, 402, 198, 288, 397, 275, 330, 267, 161, 341, 283, 193, 62, 258, 162, 254, 259, 374, 408, 415, 268, 54, 312, 424, 302, 342, 376, 172, 453, 214, 281, 379, 447, 170, 434, 230, 121, 423, 305, 441, 276, 244, 121, 110, 461, 323, 151, 309, 431, 202, 200, 329, 210, 352, 164, 503, 113, 126, 231, 152, 454, 311, 433, 86, 449, 130, 231, 262, 189, 290, 288, 429, 143, 311, 70, 226, 451, 277, 362, 134, 51, 81, 343, 171, 466, 149, 194, 310, 119, 315, 186, 300, 469, 349, 427, 123, 168, 117, 174, 144, 224, 116, 173, 198, 457, 287, 147, 65, 258, 272, 499, 315, 81, 186, 168, 341, 316, 190, 178, 291, 232, 280, 174, 260, 242, 226, 181, 120, 113, 138, 294, 106, 481, 287, 377, 104, 125, 383, 234, 369, 289, 348, 52, 389, 239, 219, 344, 378, 338, 418, 137, 363, 116, 207, 335, 449, 202, 358, 216, 134, 319, 100, 11, 265, 233, 172, 267, 45, 256, 23, 318, 221, 169, 245, 306, 281, 181, 289, 116, 173, 346, 327, 194, 205, 326, 345, 201, 111, 448, 366, 399, 293, 222, 170, 358, 442, 19, 187, 159, 456, 299, 206, 290, 169, 253, 412, 252, 202, 377, 331, 497, 203, 313, 115, 255, 373, 364, 237, 245, 291, 269, 342, 54, 218, 269, 373, 170, 256, 270, 213, 305, 288, 203, 315, 238, 87, 192, 334, 26, 127, 352, 240, 277, 114, 102, 432, 139, 332, 278, 128, 411, 91, 317, 296, 265, 343, 291, 217, 124, 350, 220, 242, 220, 62, 233, 300, 190, 393, 445, 513, 478, 346, 375, 131, 99, 272, 160, 355, 279, 112, 305, 107, 403, 336, 109, 322, 143, 371, 147, 204, 192, 308, 180, 279, 127, 194, 145, 239, 124, 288, 24, 177, 191, 433, 429, 308, 270, 136, 330, 73, 469, 302, 274, 221, 246, 393, 328, 431, 454, 391, 426, 269, 434, 329, 245, 149, 151, 338, 328, 299, 433, 374, 230, 202, 472, 177, 360, 402, 387, 316, 181, 418, 52, 198, 174, 20, 197, 110, 294, 268, 123, 151, 43, 87, 250, 237, 247, 233, 143, 367, 231, 339, 381, 141, 233, 355, 204, 225, 382, 208, 224, 206, 159, 87, 80, 275, 103, 365, 33, 374, 117, 145, 332, 368, 309, 297, 421, 63, 212, 213, 373, 107, 249, 247, 318, 242, 464, 312, 164, 240, 103, 328, 345, 262, 160, 209, 401, 325, 249, 186, 201, 112, 250, 262, 215, 70, 473, 170, 126, 143, 211, 313, 370, 183, 220, 174, 388, 346, 351, 182, 173, 48, 214, 370, 163, 92, 95, 228, 134, 461, 251, 398, 205, 282, 372, 363, 348, 83, 321, 175, 265, 160, 252, 479, 340, 257, 64, 285, 419, 369, 23, 196, 283, 286, 327, 97, 411, 331, 184, 297, 325, 284, 341, 245, 302, 294, 231, 247, 319, 404, 190, 180, 491, 441, 147, 303, 148, 291, 350, 471, 197, 396, 187, 92, 201, 269, 200, 264, 250, 338, 104, 470, 379, 248, 168, 271, 113, 146, 205, 267, 71, 296, 221, 385, 153, 347, 482, 252, 339, 453, 390, 289, 284, 229, 269, 263, 167, 27, 369, 80, 243, 432, 230, 153, 280, 397, 239, 380, 208, 244, 8, 72, 271, 354, 328, 233, 224, 297, 297, 204, 461, 190, 259, 151, 306, 375, 195, 189, 304, 155, 279, 232, 352, 123, 177, 339, 401, 493, 384, 376, 340, 38, 171, 79, 161, 78, 340, 293, 238, 465, 191, 435, 179, 244, 387, 184, 211, 307, 352, 342, 316, 196, 351, 353, 445, 69, 97, 368, 180, 274, 136, 275, 342, 189, 75, 395, 145, 147, 205, 185, 222, 218, 413, 297, 374, 144, 453, 372, 138, 302, 316, 237, 356, 46, 40, 339, 343, 184, 242, 125, 216, 345, 305, 477, 148, 214, 199, 303, 306, 123, 440, 404, 292, 210, 328, 350, 210, 337, 94, 309, 408, 151, 76, 276, 266, 325, 482, 155, 332, 254, 209, 321, 297, 243, 355, 259, 164, 221, 453, 361, 15, 338, 357, 289, 240, 149, 249, 263, 219, 447, 434, 261, 300, 159, 479, 342, 93, 213, 57, 141, 177, 335, 410, 315, 188, 166, 223, 307, 354, 492, 170, 187, 453, 195, 127, 349, 410, 151, 207, 130, 147, 216, 417, 439, 369, 83, 461, 326, 406, 381, 227, 126, 270, 258, 394, 108, 331, 228, 333, 72, 95, 209, 319, 351, 346, 379, 284, 392, 315, 191, 147, 463, 95, 486, 415, 167, 324, 377, 390, 375, 410, 92, 354, 106, 364, 106, 370, 132, 193, 396, 321, 134, 119, 393, 327, 195, 506, 30, 341, 253, 233, 82, 283, 55, 207, 301, 430, 167, 248, 163, 475, 77, 218, 124, 367, 176, 415, 426, 188, 380, 58, 488, 209, 170, 164, 354, 134, 212, 334, 255, 220, 349, 110, 288, 227, 350, 201, 406, 319, 442, 117, 330, 228, 148, 424, 267, 155, 452, 161, 345, 217, 474, 179, 208, 328, 367, 254, 173, 210, 259, 458, 296, 277, 206, 296, 162, 480, 430, 183, 202, 268, 263, 274, 312, 374, 96, 445, 66, 463, 321, 250, 204, 194, 129, 78, 342, 485, 289, 387, 67, 119, 256, 241, 341, 110, 215, 276, 226, 186, 276, 266, 198, 331, 455, 167, 232, 89, 355, 166, 336, 147, 397, 167, 260, 175, 282, 465, 265, 178, 453, 189, 132, 273, 202, 132, 209, 62, 400, 397, 114, 225, 299, 288, 259, 228, 149, 319, 160, 327, 406, 411, 217, 374, 286, 229, 236, 129, 232, 403, 266, 432, 189, 115, 338, 120, 342, 197, 248, 310, 269, 298, 79, 156, 453, 325, 468, 116, 246, 210, 438, 43, 256, 378, 294, 398, 84, 366, 122, 311, 174, 346, 377, 320, 111, 309, 243, 162, 329, 165, 307, 229, 266, 305, 267, 94, 230, 454, 131, 72, 50, 209, 199, 283, 329, 178, 400, 236, 388, 423, 127, 190, 287, 175, 477, 274, 314, 465, 389, 410, 350, 131, 263, 108, 201, 127, 130, 468, 59, 223, 148, 341, 336, 414, 235, 36, 288, 171, 405, 111, 395, 271, 122, 154, 150, 164, 403, 460, 374, 213, 208, 464, 310, 143, 356, 204, 81, 273, 314, 287, 380, 16, 410, 313, 385, 410, 406, 23, 240, 370, 373, 416, 355, 204, 176, 187, 329, 357, 292, 282, 384, 212, 273, 202, 262, 385, 198, 191, 402, 230, 266, 179, 389, 210, 165, 375, 261, 287, 302, 471, 250, 144, 284, 279, 277, 382, 118, 65, 126, 235, 158, 354, 150, 53, 331, 68, 280, 51, 219, 432, 90, 236, 213, 137, 289, 256, 366, 469, 484, 125, 289, 454, 49, 155, 392, 221, 181, 238, 137, 85, 222, 105, 228, 351, 380, 22, 379, 322, 409, 215, 234, 174, 275, 356, 182, 212, 272, 203, 194, 426, 215, 279, 234, 279, 388, 164, 318, 219, 205, 152, 74, 304, 242, 136, 440, 304, 466, 238, 347, 201, 373, 275, 325, 364, 362, 393, 103, 394, 365, 359, 338, 332, 322, 369, 270, 216, 363, 135, 353, 460, 157, 282, 402, 414, 393, 196, 403, 178, 294, 276, 193, 282, 217, 86, 234, 351, 433, 337, 64, 236, 184, 423, 64, 362, 241, 210, 247, 483, 298, 122, 191, 243, 245, 46, 458, 278, 447, 311, 326, 360, 71, 224, 354, 148, 360, 74, 6, 215, 290, 374, 313, 200, 185, 116, 133, 28, 224, 467, 357, 291, 473, 379, 388, 188, 246, 340, 67, 240, 144, 475, 314, 193, 179, 215, 150, 423, 360, 192, 102, 159, 127, 204, 154, 168, 423, 373, 172, 48, 140, 327, 292, 358, 221, 426, 154, 101, 331, 337, 235, 102, 251, 409, 238, 283, 151, 307, 278, 357, 247, 484, 229, 152, 69, 311, 241, 225, 388, 230, 140, 146, 370, 429, 26, 134, 466, 240, 372, 197, 389, 145, 136, 176, 187, 400, 264, 221, 366, 446, 311, 364, 186, 404, 363, 101, 243, 400, 120, 146, 389, 203, 190, 278, 300, 260, 196, 430, 106, 260, 367, 436, 222, 359, 433, 417, 184, 371, 301, 275, 336, 111, 428, 129, 304, 303, 73, 224, 449, 175, 255, 446, 326, 123, 315, 315, 223, 327, 161, 194, 97, 201, 309, 383, 407, 302, 326, 209, 324, 198, 356, 107, 88, 189, 276, 247, 144, 339, 320, 221, 169, 140, 226, 118, 379, 333, 69, 300, 262, 218, 265, 257, 251, 310, 27, 265, 227, 369, 220, 146, 412, 265, 272, 286, 286, 229, 283, 395, 209, 372, 290, 488, 293, 184, 360, 342, 194, 132, 313, 290, 448, 385, 162, 232, 31, 270, 271, 383, 318, 242, 251, 157, 79, 119, 421, 401, 178, 231, 152, 207, 55, 163, 274, 313, 125, 251, 256, 468, 385, 329, 227, 272, 317, 196, 427, 466, 96, 216, 449, 14, 441, 333, 484, 363, 383, 303, 155, 172, 188, 348, 169, 256, 199, 193, 188, 455, 86, 161, 235, 247, 288, 135, 344, 427, 381, 148, 261, 128, 193, 287, 221, 347, 155, 172, 204, 334, 255, 380, 189, 241, 277, 226, 448, 413, 81, 441, 223, 162, 429, 292, 205, 146, 439, 110, 114, 304, 261, 378, 88, 278, 386, 123, 226, 329, 165, 83, 295, 213, 408, 355, 414, 336, 440, 366, 409, 142, 153, 168, 128, 470, 266, 82, 280, 428, 250, 360, 238, 99, 53, 424, 176, 285, 263, 212, 268, 316, 377, 335, 387, 168, 144, 428, 326, 132, 232, 252, 300, 51, 146, 308, 371, 486, 279, 275, 370, 223, 33, 304, 296, 217, 442, 360, 280, 75, 354, 182, 139, 397, 236, 442, 361, 45, 233, 193, 479, 206, 153, 121, 299, 201, 255, 426, 318, 286, 54, 143, 302, 57, 148, 320, 231, 218, 377, 498, 206, 359, 238, 235, 379, 160, 391, 381, 261, 297, 277, 368, 362, 437, 409, 372, 270, 481, 300, 407, 253, 55, 488, 487, 470, 429, 431, 402, 259, 404, 257, 101, 243, 463, 487, 514, 496, 150, 358, 504, 234, 490, 511, 240, 415, 412, 484, 490, 416, 252, 472, 489, 478, 493, 381, 139, 480, 511, 362, 293, 466, 503, 359, 342, 142, 326, 369, 304, 320, 364, 486, 261, 105, 316, 471, 476, 430, 460, 379, 484, 253, 446, 400, 447, 373, 472, 490, 272, 401, 158, 471, 328, 417, 312, 344, 331, 429, 383, 341, 501, 361, 410, 480, 477, 492, 508, 482, 332, 336, 429, 310, 369, 460, 291, 346, 365, 392, 402, 452, 120, 430, 301, 419, 462, 406, 410, 342, 493, 500, 390, 498, 378, 230, 403, 188, 443, 258, 505, 499, 148, 508, 485, 241, 382, 289, 264, 182, 455, 481, 264, 451, 489, 483, 485, 365, 376, 447, 301, 382, 278, 237, 409, 285, 168, 292, 463, 290, 482, 339, 323, 376, 386, 495, 286, 502, 450, 322, 115, 390, 483, 370, 426, 461, 441, 406, 162, 73, 506, 256, 511, 507, 107, 498, 491, 323, 274, 478, 516, 337, 450, 304, 183, 502, 285, 249, 420, 427, 349, 386, 508, 353, 413, 500, 375, 304, 485, 410, 484, 306, 353, 431, 377, 239, 156, 438, 402, 499, 503, 200, 458, 419, 490, 230, 203, 397, 73, 436, 398, 326, 293, 363, 416, 497, 458, 250, 443, 460, 60, 476, 227, 392, 494, 352, 422, 383, 468, 344, 443, 199, 425, 417, 496, 452, 472, 396, 246, 449, 458, 395, 398, 283, 253, 391, 307, 268, 337, 501, 269, 499, 409, 408, 434, 365, 264, 407, 267, 150, 253, 254, 269, 185, 434, 306, 508, 510, 287, 347, 318, 439, 235, 307, 503, 281, 303, 468, 366, 415, 434, 480, 368, 497, 500, 504, 195, 188, 125, 502, 496, 475, 492, 481, 501, 407, 309, 302, 372, 442, 357, 464, 436, 249, 429, 493, 412, 340, 385, 489, 172, 353, 322, 477, 439, 509, 490, 311, 478, 364, 450, 448, 479, 372, 463, 495, 312, 269, 425, 341, 501, 415, 193, 225, 481, 437, 433, 281, 509, 428, 278, 509, 458, 506, 481, 509, 463, 504, 209, 415, 510, 347, 246, 388, 307, 237, 472, 407, 318, 228, 441, 417, 467, 469, 457, 515, 324, 402, 510, 254, 112, 470, 345, 463, 302, 378, 416, 312, 241, 381, 327, 94, 207, 335, 498, 343, 476, 427, 444, 351, 414, 186, 178, 457, 459, 460, 333, 471, 334, 389, 398, 327, 315, 504, 481, 437, 386, 431, 488, 442, 241, 356, 471, 402, 424, 433, 287, 459, 298, 463, 322, 458, 386, 464, 232, 492, 285, 441, 227, 292, 405, 377, 336, 466, 441, 513, 350, 276, 142, 492, 176, 404, 286, 437, 483, 474, 446, 291, 323, 474, 463, 414, 496, 231, 493, 491, 464, 484, 448, 191, 441, 258, 296, 497, 381, 484, 419, 318, 125, 222, 487, 516, 285, 502, 449, 294, 211, 384, 358, 451, 414, 509, 135, 241, 444, 392, 474, 469, 444, 203, 500, 282, 350, 286, 231, 478, 365, 465, 467, 472, 497, 484, 513, 513, 455, 242, 502, 385, 504, 358, 479, 390, 407, 416, 266, 330, 206, 412, 471, 496, 498, 380, 325, 159, 219, 504, 447, 340, 383, 416, 475, 373, 410, 486, 368, 501, 511, 413, 91, 278, 257, 486, 369, 506, 214, 402, 430, 348, 476, 333, 331, 441, 204, 187, 450, 194, 382, 224, 497, 411, 462, 252, 275, 457, 446, 415, 502, 413, 121, 515, 485, 476, 353, 381, 488, 480, 385, 425, 314, 224, 383, 506, 280, 515, 388, 422, 386, 396, 408, 329, 340, 371, 359, 138, 431, 200, 361, 393, 189, 436, 411, 319, 316, 478, 293, 390, 422, 414, 445, 232, 503, 397, 443, 296, 493, 374, 432, 430, 493, 206, 437, 477, 295, 352, 492, 509, 375, 214, 314, 430, 283, 467, 491, 350, 421, 499, 499, 511, 367, 125, 379, 482, 476, 505, 411, 446, 507, 390, 264, 290, 419, 460, 474, 414, 422, 317, 327, 437, 422, 404, 320, 416, 242, 362, 429, 366, 399, 438, 293, 245, 448, 461, 390, 415, 356, 482, 504, 284, 428, 378, 268, 400, 308, 468, 416, 393, 394, 405, 355, 408, 438, 323, 424, 401, 483, 516, 493, 362, 424, 372, 234, 515, 386, 382, 500, 314, 402, 425, 460, 456, 172, 501, 247, 495, 173, 492, 226, 476, 439, 346, 293, 353, 317, 435, 152, 487, 119, 348, 424, 499, 494, 495, 469, 251, 501, 401, 516, 308, 457, 280, 454, 440, 432, 470, 497, 399, 451, 344, 487, 432, 439, 516, 278, 461, 462, 313, 475, 386, 233, 396, 475, 439, 424, 495, 431, 434, 433, 436, 456, 403, 341, 423, 359, 296, 324, 309, 480, 508, 435, 144, 478, 401, 358, 287, 484, 512, 443, 367, 459, 452, 445, 468, 316, 271, 514, 388, 448, 474, 413, 307, 86, 293, 320, 433, 302, 394, 222, 414, 344, 456, 356, 475, 468, 456, 426, 494, 428, 339, 288, 494, 448, 270, 504, 507, 381, 405, 379, 498, 469, 489, 247, 354, 445, 500, 467, 217, 277, 385, 318, 513, 218, 253, 483, 249, 325, 161, 351, 505, 475, 440, 229, 412, 461, 371, 427, 377, 439, 338, 473, 500, 292, 167, 315, 230, 261, 464, 294, 407, 226, 406, 488, 426, 432, 515, 511, 421, 489, 439, 282, 515, 483, 325, 323, 462, 443, 491, 377, 384, 349, 491, 353, 226, 420, 495, 428, 409, 473, 461, 357, 473, 371, 343, 360, 398, 500, 465, 401, 319, 513, 483, 216, 405, 424, 473, 455, 516, 235, 476, 308, 248, 281, 482, 244, 481, 407, 345, 309, 506, 417, 485, 363, 320, 192, 470, 231, 513, 246, 299, 447, 467, 163, 510, 498, 337, 417, 491, 457, 422, 340, 422, 298, 273, 301, 447, 449, 356, 374, 436, 299, 225, 452, 468, 490, 403, 432, 387, 38, 277, 340, 514, 485, 355, 253, 400, 389, 460, 492, 356, 300, 400, 404, 404, 498, 369, 330, 273, 311, 248, 491, 126, 216, 495, 449, 505, 407, 380, 425, 246, 437, 153, 211, 256, 387, 515, 297, 507, 440, 480, 361, 412, 395, 431, 412, 371, 506, 435, 421, 462, 504, 483, 472, 436, 507, 370, 183, 485, 330, 389, 381, 473, 272, 449, 364, 192, 345, 312, 252, 333, 501, 388, 491, 246, 507, 393, 355, 358, 367, 417, 499, 81, 516, 494, 490, 228, 480, 367, 427, 387, 349, 510, 349, 411, 321, 449, 315, 307, 458, 490, 462, 323, 406, 452, 456, 357, 153, 359, 503, 375, 352, 385, 392, 442, 485, 260, 445, 423, 512, 410, 361, 396, 421, 514, 300, 412, 487, 489, 19, 352, 447, 347, 321, 400, 394, 284, 510, 508, 502, 281, 459, 177, 483, 388, 399, 379, 180, 186, 209, 502, 418, 326, 214, 432, 274, 401, 413, 512, 322, 264, 513, 239, 501, 464, 419, 259, 418, 306, 307, 319, 484, 512, 453, 363, 508, 454, 424, 450, 275, 270, 301, 260, 512, 161, 494, 323, 346, 189, 348, 376, 345, 464, 421, 381, 342, 464, 359, 455, 492, 470, 359, 505, 465, 343, 420, 435, 428, 510, 478, 193, 419, 380, 414, 181, 394, 266, 396, 491, 395, 192, 421, 404, 507, 456, 512, 251, 384, 442, 421, 334, 384, 317, 320, 391, 477, 171, 336, 273, 500, 446, 414, 340, 484, 306, 453, 445, 327, 405, 406, 506, 236, 491, 371, 508, 471, 446, 501, 290, 366, 507, 250, 394, 403, 458, 266, 509, 351, 493, 252, 510, 456, 176, 440, 419, 378, 506, 399, 442, 319, 514, 462, 275, 459, 378, 350, 226, 494, 430, 494, 394, 486, 442, 381, 233, 500, 504, 504, 308, 494, 366, 353, 469, 439, 463, 516, 109, 473, 473, 343, 383, 435, 282, 509, 420, 514, 333, 450, 307, 477, 375, 398, 466, 382, 479, 452, 283, 285, 495, 482, 425, 430, 505, 322, 444, 503, 497, 449, 486, 338, 440, 355, 488, 413, 352, 513, 331, 333, 506, 423, 183, 361, 474, 461, 409, 425, 411, 481, 397, 470, 332, 395, 343, 298, 159, 476, 512, 398, 444, 516, 505, 499, 397, 421, 271, 130, 424, 456, 270, 463, 431, 334, 397, 399, 509, 335, 341, 443, 392, 509, 338, 284, 468, 382, 477, 443, 331, 455, 445, 169, 296, 511, 491, 408, 427, 408, 318, 405, 182, 392, 390, 488, 219, 368, 369, 384, 372, 336, 399, 502, 515, 356, 486, 325, 293, 504, 162, 451, 295, 339, 220, 471, 421, 351, 433, 334, 392, 465, 303, 418, 306, 316, 515, 317, 438, 482, 454, 475, 370, 459, 496, 505, 384, 185, 172, 497, 171, 281, 400, 418, 499, 436, 391, 108, 468, 280, 422, 313, 467, 398, 464, 167, 254, 168, 448, 465, 505, 471, 312, 467, 418, 403, 374, 470, 459, 347, 468, 395, 425, 19, 472, 510, 456, 428, 495, 75, 255, 467, 465, 425, 512, 387, 426, 335, 453, 474, 487, 480, 462, 344, 511, 207, 309, 419, 419, 395, 424, 272, 346, 382, 460, 352, 169, 442, 476, 404, 473, 511, 330, 196, 334, 329, 438, 438, 503, 255, 481, 500, 420, 472, 509, 394, 450, 255, 472, 373, 365, 488, 305, 496, 418, 193, 368, 305, 508, 495, 494, 199, 420, 514, 450, 201, 496, 238, 264, 411, 358, 229, 287, 493, 346, 409, 489, 102, 480, 413, 435, 290, 317, 303, 348, 376, 314, 422, 297, 343, 250, 513, 466, 290, 289, 431, 503, 451, 516, 328, 305, 427, 361, 307, 469, 341, 476, 371, 489, 328, 355, 310, 437, 515, 402, 386, 403, 412, 357, 440, 486, 448, 399, 337, 514, 426, 478, 506, 462, 360, 466, 496, 279, 397, 479, 428, 505, 421, 461, 257, 437, 418, 315, 440, 498, 337, 387, 490, 437, 466, 220, 500, 479, 470, 218, 380, 431, 243, 396, 492, 443, 507, 373, 477, 395, 188, 496, 366, 457, 422, 336, 376, 450, 391, 494, 245, 384, 77, 44, 478, 438, 454, 407, 285, 508, 198, 457, 261, 322, 492, 482, 338, 512, 405, 420, 312, 464, 416, 80, 412, 249, 501, 412, 452, 505, 426, 379, 451, 479, 387, 137, 340, 507, 483, 459, 203, 453, 420, 358, 84, 499, 503, 408, 443, 350, 515, 200, 295, 376, 442, 369, 423, 346, 420, 445, 456, 465, 337, 475, 438, 258, 506, 377, 364, 185, 321, 305, 282, 509, 301, 321, 398, 456, 511, 465, 281, 516, 450, 435, 286, 416, 475, 254, 393, 469, 414, 429, 460, 389, 478, 492, 503, 453, 444, 393, 467, 294, 420, 157, 279, 513, 497, 204, 444, 514, 348, 459, 454, 270, 413, 440, 494, 434, 465, 505, 429, 384, 514, 466, 486, 475, 510, 436, 437, 434, 457, 516, 454, 473, 332, 433, 479, 499, 405, 482, 497, 503, 411, 351, 199, 380, 216, 420, 387, 426, 450, 404, 370, 447, 386, 452, 135, 253, 482, 416, 276, 171, 419, 420, 288, 241, 474, 391, 368, 488, 365, 400, 363, 354, 274, 415, 345, 376, 467, 138, 479, 295, 391, 382, 483, 444, 446, 390, 304, 510, 507, 385, 452, 216, 457, 472, 498, 438, 408, 388, 368, 498, 464, 462, 466, 508, 515, 321, 375, 337, 448, 273, 455, 435, 380, 354, 254, 242, 324, 489, 477, 245, 427, 195, 508, 187, 210, 328, 498, 145, 485, 304, 493, 392, 507, 324, 400, 419, 430, 439, 513, 432, 417, 496, 364, 474, 511, 493, 435, 487, 366, 364, 455, 384, 359, 195, 329, 263, 349, 248, 486, 371, 166, 257, 471, 339, 380, 357, 437, 441, 191, 443, 268, 197, 444, 306, 363, 160, 346, 345, 376, 401, 479, 195, 243, 514, 481, 489, 445, 432, 451, 460, 252, 443, 332, 283, 416, 502, 140, 164, 415, 359, 470, 90, 411, 425, 422, 352, 344, 501, 386, 335, 458, 449, 478, 480, 477, 487, 413, 444, 244, 157, 451, 423, 480, 297, 284, 495, 431, 384, 418, 363, 325, 245, 447, 313, 485, 436, 391, 357, 512, 490, 487, 417, 512, 324, 496, 366, 152, 452, 343, 361, 389, 254, 446, 471, 502, 399, 485, 395, 345, 474, 337, 481, 249, 510, 458, 514, 90, 362, 463, 347, 477, 257, 489, 405, 143, 259, 286, 495, 382, 224, 177, 446, 260, 427, 438, 434, 511, 187, 383, 423, 193, 430, 427, 447, 435, 487, 502, 338, 407, 323, 407, 387, 166, 512, 473, 310, 457, 490
+};
+
+double input[] = {
+-2.8588758611049867, -11.692946618257562, -2.0931111592429659, 11.110696212718175, 6.6118168080332342, 5.5228669775147967, -10.351976177615544, -6.2055936928533972, 15.766842028131405, 10.150684036103069, -8.459063190320423, 3.5621047687812557, -3.4741612771047636, 3.324748317571744, 8.996614205792751, -11.020291727957101, 12.081427681651697, -8.8928631203159583, -3.3519010114052263, 7.7902118547439443, 9.6608001848411806, -7.1066822779231593, -18.837368573809297, 6.7301895647238608, 6.7933629603091008, 5.9697810424393483, 8.344011991064086, 12.19791145343228, 9.4167774696594435, 7.423418316685729, 9.0291842080564226, 12.492983259925982, 7.1203329881309401, 9.8776999539720336, 7.3657220051725565, 5.4066464900536131, -12.553405951140983, -8.4918025628237199, -11.352365915823617, 14.756685666538061, -8.0938336502539876, -2.7071697789206022, -2.4795849849319289, 14.778716053676311, -12.149933491676437, -8.5931326392610909, -5.4147618905983697, 1.7095221079392837, -12.75286957597447, -6.560818125727109, 5.5288804134600262, -16.774264848727494, -10.397477377823613, -14.47470382199227, -12.095199384731899, -0.68504635593676977, 2.6623689185177528, 13.264791388391092, -15.654931986196731, 6.1276196890542334, 4.5068190091793028, -13.394637229913476, -6.9231832293793651, -12.113429033794846, 1.2142140703098925, 8.9363539352870394, -12.687063373304539, -3.3458614784673091, -3.4123481785186587, 17.559631253372945, 13.470764559481434, 5.3912902961422002, 8.0737946505557545, -12.755710856932868, -3.569697890412812, -6.2613535644882905, 0.068556269783912271, 6.2629797657916875, -9.2663011036090968, -4.4829975567184634, -9.6136989537403004, -8.7663852688801143, -13.974856274599134, 11.407302219619563, -10.302223327202944, -8.9771589068473983, -6.1388609170833384, 4.2370800072671333, 1.7760515525196516, -12.120232639630231, -12.958157445638765, 5.2985241644932541, -16.484657731002855, -6.3532421360393387, -9.0395804464700298, -7.2671128749847744, -12.616882711750195, -4.9350723080331012, -6.6905936282318637, 18.568407538602393, 12.530577696234687, -9.7889565176657243, -15.214958325061282, 7.215674131215513, -7.5394667988733808, 9.0137713371297465, 6.2553392643094785, 9.1953246360263154, -11.131787953429392, -5.4020937991353657, -4.0642543197135739, -0.44036236539366824, 8.0650609441874703, 0.85520780385748785, 7.2621337620159085, 0.29865166967486761, -9.2011814546979203, -10.330862011400864, -7.3191138151867943, -9.4852558149271111, 14.762260259194324, -5.0853268103463423, -11.2925794883785, 13.026909781206733, 7.9504343630905412, 10.148928930852414, -8.9032450603232327, 7.0914762951954913, 10.89340681888671, -12.705821222595254, 13.126012326275292, 9.4442919029362749, 5.0277440210736879, 0.21756213342494518, 12.710361373031621, 5.6453651213768019, -13.49634180382726, 6.4754225359227204, 9.6275804629486004, 5.8125840672452975, 9.7028326962213836, 6.1260130958734562, 3.3623596073706641, 10.736024757333299, 4.6569987032041826, -8.5021099021622799, -2.5832378575026125, 17.984880998940056, -13.974611077713172, -7.8550941092339874, -2.6917314432377575, 10.825283872831294, 11.217940706150642, 1.8301222470027103, 6.2062091666111812, -12.440863506480019, -19.955292055354317, -3.6699151522797462, 2.2154324244303956, -3.7363628672311142, -10.271027034445964, -9.2862432349117547, 9.7847963699436011, -5.9471830363214551, 11.139859339322513, -9.2599913694963618, 5.0422863933763367, -7.1141487133220043, 4.2177963601947308, 10.657785123505857, -5.7952000401674324, -6.826355874510365, 8.7268751949597245, -8.5906649209875745, 2.2758857640658201, -6.1665377492933358, -7.3104026599884433, -3.2424605164178031, 16.796591996286164, 15.671215006757382, -7.8445348658392806, 12.2589312976831, -2.5670307012079139, -11.537316744819945, -2.4858301794672331, 5.0542510171190438, -6.6860957990782133, -7.2619018024969462, -6.7329842279273242, -7.3146812058251234, 8.0821157274412183, 2.4005920765968378, 9.3157871935284753, -12.908851857280949, 5.2927115546650425, 9.9926730185778059, 3.9229860372333749, -5.5126846245121035, 12.313688019948762, 7.9681453222519041, 17.181368769149195, -8.962498225939207, -11.548950041024865, 12.014544817430894, 11.485639169870186, 11.939774664713912, -14.36069895314143, -11.812874687185857, 12.249194120883461, 4.8839501930831242, -10.540165871108648, -14.829380396239381, -6.4665012687326051, 4.7430459960995295, -7.1378949876943016, -15.357105375923917, 7.3351294975306445, -9.6095153441695373, 4.381145332149095, -9.2910048695861427, 4.894239034759102, 7.864879034656453, -8.3265429253416077, 10.497214061711553, -0.39338042557070996, -4.4611306847986816, 0.76940119561902198, 2.3535542193708272, 10.459438806533345, 9.4938186880252005, -6.4805717587307994, -13.457392617761585, -10.487085219177404, -9.8506932711478576, 11.274019685851906, -12.3031017274995, 8.3324030035106826, -2.3013116280481358, 8.3664075310158825, -10.402109920341072, -5.2924293563600742, -12.008098192077149, 10.992304106359162, -5.5591947469243506, -12.838234842015352, 8.1682577157065577, -6.4919177172949487, 13.568876091933316, 8.0352162745849594, 8.7834139460450125, -11.335870474093099, -10.790767171281415, -2.8875937626970223, 14.64505222675956, 11.436743007190451, -2.9337339836825955, -12.707240342338084, 16.661129912274529, -19.171798326126961, 12.280144746488103, 6.5975965145696174, -13.019719338217644, -3.4328503704209457, 4.822535491209953, -8.1340577921572415, 11.549182216506546, 9.6431724916100059, 5.5547407614902173, 15.019668995173307, -1.6514898426907461, 16.110709054474917, -10.9397931999944, 12.04576668183285, -8.4818868311872198, -6.103248438757908, 8.2975079067215702, 2.5480181038085412, 18.799878298920927, 16.231939791740228, -18.011602750805633, 3.7139764502467689, 12.751595841360283, -7.8718015936255812, -0.40802815212428428, -15.47812599016518, 3.2584854200798588, 14.976391986507007, 9.1367378814346782, 3.4155780056910059, -13.292285487599507, -12.855991908912157, 14.013291588644732, 9.6911017234399335, -5.8910196575740752, -2.2280612655108047, -11.219438047247786, -2.5955623953948517, -3.4460676112793136, 3.5682986120247073, -11.70300520092221, 11.99455548751415, 7.319096625369828, 8.400961847094683, 12.142806695044221, -3.6775894169196279, 8.3797255658565142, -12.156985373281584, -17.475193610019677, -14.228116929396922, 10.726007504360073, 15.267119384103992, 12.781072511062279, 8.0326533999697229, -17.51207194760946, -7.554034280962183, 10.066411068992132, 14.13799652436988, -6.7247334837075705, -11.112518294834185, -5.7326833292155523, 3.6877552031425131, 8.7105204152043516, 9.3857694378580963, 19.127569440965896, -3.8614826162666089, 7.9404471399280068, 6.3807591097483005, -6.8888859894612535, 10.317928637508684, 2.1736529765433783, 10.953222318849482, -7.6682531128958038, 5.0318286636058982, -6.9463690764775503, -3.0184853792276383, 9.6041512562391542, -0.88225262267439808, 6.4852292067129724, -2.3181001351577644, -13.197351056460056, -6.8047677874499586, 5.3843074707174692, 5.1196343577870644, -17.820822197855577, -12.257015718775355, 5.1913937352654651, -5.0162460867599536, 9.9461758050913041, -9.7414598652248081, 8.1378256819797858, 12.564281794378495, -5.6365288176451322, -9.1029468332924104, -5.6355130288814301, -13.719331548944416, -5.8613058178495017, -9.2573519867695815, 6.0620773131346706, 5.8947778726542905, 11.265652594812099, -11.760986024368906, -7.7447348268870124, 19.076436411627338, 14.505720191829832, -9.0750817120358054, -5.2025480400034789, -3.1960162333402482, -11.659437264119374, -7.9842387274926709, 8.5980388295231229, 14.858752059828165, 6.8639263237417376, 6.0631638589074024, 2.7093921939507379, -4.9581002755473795, 4.4179924464321392, -11.144868427484562, 12.546476704938177, 13.606433000436612, 4.0208619807458295, 6.2408832155761376, 3.0941528835943455, -11.347668662075096, 1.9313877794966201, 11.65105372954261, -14.681336156121709, 7.2969958167198605, 11.59264621157577, -8.831465763669156, -12.759130509205734, -9.0714254556796128, 8.9948895559776467, -8.3736028555285831, -13.115027308542444, -0.21628815052066303, 7.7132708674061705, 14.055053470061472, 13.370601410874029, 3.3283307501026052, -11.9653642849229, -5.6440590777489144, -4.2508984635752549, 13.005398229132568, -11.5296140873405, 11.286858942494266, 9.8110403874583074, -13.263569122014866, -6.4297799553106456, 7.9672918799786396, 2.1515462864377719, -8.490571668881163, 7.5548103934198929, -13.121628447449439, -5.7901204816768361, 7.5171762671769704, -5.4216710822831979, -0.95140907859749113, -5.6992105242986471, -0.91737830538166343, -8.2053563541920571, -4.9100295191078036, -8.650093905400162, 10.400080220873763, 7.2829351923330092, 5.3481291290736603, -9.5017802399357425, -9.8687523002255393, 11.82329840938681, -3.1919281246249707, -10.124868011353035, 6.8360355157042028, -14.032171223888698, 18.148403140529073, -9.5731633683674744, 4.0453611070899935, -4.114147796015585, -8.4912512496909898, -7.9968991599686872, 12.922672789580542, -6.7315939113482681, -16.414580925551139, 10.417406116722118, -9.5795995211441394, -7.974905790034116, -13.727944328842275, -15.024522822723423, 4.9026741637309703, -10.662764572620276, -19.122555879539242, 9.217115643469544, -2.9661166430929642, 13.154514394206242, 9.8788596316167272, 4.2669291411005252, 10.239868792823961, 0.50928446540137651, -6.9544644508051245, 2.9807945285095245, -8.2689690969205181, 3.5499295458600972, 12.732733620631645, 11.61935741986054, 8.4137329217700945, -13.703811206903364, 8.5347899814747166, 13.941804015126218, 11.213731601489895, 11.550008187296406, -10.885532785062049, -6.0320756476152395, -7.945602926688589, 18.178022024827495, 4.2378890109434684, -8.419937978328889, 14.273513193884424, -8.1801725060827586, 13.690183625733544, -17.518387733265431, -8.6392702216784656, -13.927446312699148, -8.651607062718659, -12.712917239643309, 15.009792996204254, 0.15853783962329626, -10.462310302523948, -12.535567399778486, 8.8192610919401329, 13.066656030822525, 18.005415525102343, -16.007576967175243, 11.052574245331391, -1.1810954342450888, -12.762633127175347, -11.427571726679494, -1.8068233566411038, -3.8651597939182674, 6.9028603232990591, -9.9188843352819767, -13.607089316301986, 5.8989769757503172, -10.266998033319117, 12.946619994251195, -7.3433271276853551, 13.594756446262442, -1.4802835189751626, 2.9459432512420887, 9.0127453411993006, 12.34274116102957, -0.99056567004691576, -1.0211228826859517, 10.87969885601588, -15.669877762479704, 16.01192464298973, 10.789218207135569, 6.1523737440350752, 10.844976713696601, -18.796538678004055, -7.3982730413954201, -6.5213519941388851, -18.571369340190397, -9.6913300045155282, 1.0175474995943568, -8.0705533615168754, 14.251221745808563, -14.054781652173469, -10.906074448438877, 9.9932114606110058, 9.2204934537976815, -11.102967677965665, -15.06146952578059, 11.282374133246716, -3.4111780254645643, 7.3857075662336609, 10.330601600777463, 5.6502615537426548, -7.2776853004382911, -12.041052757776699, -11.046289906579057, -2.8519140526114701, -14.358095698121817, 4.6207960341417813, -12.368837238636017, -7.2377430770905917, -7.1306536664479809, -10.374815173234571, 7.5287331560402384, -5.4660620697715716, -13.441122458297521, -6.5962962593129824, -8.4930653390556969, -5.473757203858737, -16.42318744504734, -7.678902139771755, -6.1724752873292612, 17.227224731420481, 2.7992443468423089, -11.010643413583562, -6.0460973993600238, -11.514094016830022, 7.2250024006000091, -7.8426213114387204, 10.647716150585898, 5.7539405508617296, 9.727218535739766, -10.217949794886991, -10.197658817694322, 1.4534950594678713, 12.10682632749001, -0.51088307163622715, 17.710760548825679, -7.7470194812395397, -24.372971692573486, -6.6052580469808717, 8.826482956514015, -6.7872955696686779, 3.6389619856040674, 9.9237321927880782, 12.100520790781362, -6.8842633676573595, 2.8844843405481937, 13.672108533544661, -5.6338295492883859, -7.1944131155704678, 6.9746870716875398, -8.2312590639291852, -10.25205738032861, 3.9564297173352139, -11.16342115946062, -8.4103856915642865, -3.86058459788803, 6.7693385059336668, -5.5093604081945458, 9.9112156966838256, -11.829917793796264, 12.06350448472004, -9.8908904770778552, -17.725516485129567, 5.0710728367340741, 2.3733785626266992, -12.373813495428958, -8.2010211819107539, -12.301300323962623, 10.576063861117305, -2.4429576335852246, -9.8126936984062763, 10.720987427999063, 5.3468144210345949, -7.436093608771988, -12.085562323273949, 9.616133130427178, -7.2337117418265358, 6.590012489497771, -12.933819456719151, 9.0992320680750058, -4.7115096872358144, -12.444448996962361, -9.2431835291508904, 8.9400870181220906, -14.84487535501597, 6.9572855730306786, 8.679259378600257, -11.728117564638417, 11.57774167266283, -11.089244669418909, 4.4545841055164113, -10.471036138424958, -7.9268850048012363, 10.006310688982033, 7.3307629546995496, -0.70086411051328346, 3.4399790497959652, 7.5780305602750353, 15.952535940468001, 1.1236075069228646, -10.56946563987197, -16.455271371728593, 14.943737550316991, 15.270538328279843, 1.8246123975329285, -11.861267836196021, -12.897409417413272, -8.0295182717849976, 2.5085092290718261, -2.997769928368061, 7.7106512520538253, -9.7986312114017196, 3.8597867083890951, 14.715042117673541, 3.6286772784703238, 4.6804229784596041, 10.468442660987332, 6.0309605373905297, -7.2836222700763322, 7.3372979832476464, -9.125874340732242, 12.431154776537063, -12.652059501141041, 8.520614267493885, -14.669291764198016, -5.4369263583494511, -6.9272239504642288, 14.411503339302335, -6.5090359387453871, -3.8249288367587844, 6.226877964919483, 5.4872378813688707, -12.071286274848809, -14.839631376528764, 14.929556186968613, -13.550466083272015, -17.79040452965922, 5.2176515285150078, -8.4073909354978511, 13.152357868676932, 11.880434179671278, -15.154722117187848, 3.3578570344364098, 3.7992951070371852, 12.544849221875657, 4.4664223998223864, -16.02563218730095, -16.858694781271584, 5.8423687431569373, 14.717494305248145, -6.3014233972716296, 7.8246512200173655, 0.2490959399462627, 10.09774947224876, 8.2302536611399972, -2.0230125836350608, -10.877543890130998, -10.315299910440396, -17.814418691884743, -4.7984509876179366, -10.569732541659832, 12.468245506360125, -8.1994351150315588, -8.4938440033843783, -15.646554844352739, 11.104862652426069, 5.4254710709054565, -7.075912451839514, -13.038488980503107, 8.6283602505517099, -0.1897762834069755, -15.926221800862628, -9.4620561439869952, 11.028601034997564, 6.2202218101379954, 13.01838761394424, 3.8814455959068872, -10.571348353520641, 9.3930545668475638, -7.4486485829571807, -15.896920034679038, -7.6634637506716583, -13.744383772875613, -16.289316553121051, 4.2240572521775093, -5.9728476753105495, 1.4435980912356212, -9.482201269588181, -7.1075995048298424, -8.4496788887326719, 5.5233585701859731, 8.8295065675835449, -6.8321409197770491, 14.622652588625614, 8.1030077299922656, -5.0997213512339847, 10.535820013561885, -11.687469584683409, 3.0547169868379771, 8.210959869395893, 10.201179428221021, -11.658463276051274, -13.563724058479169, 11.01039677555352, -7.1382476676607203, 14.955134349802455, -13.750666848543476, 10.162311270235616, 5.7884645703783697, 7.3371242692507819, -9.6841606635170585, 5.466449250298048, 8.4163518309029381, -7.1508542487337046, -6.6797959016182888, -4.7449989886325188, 2.4393509869405792, 8.654752655597532, 10.070879973393719, -13.17581052395726, 8.5470611298539545, 6.660259185215466, -6.0653871786400737, -6.5193717691612134, -12.615899043092323, 6.700881216282939, -4.8478946577189745, 5.1988868211607864, -12.549358461765644, -10.045744010088018, -12.380860324318006, -3.8616068170109248, -14.465705737907983, 0.4164829268257374, -17.143567612135136, 9.487366827722223, 12.652721901108753, 0.7645899772346989, -11.920812995054151, 5.348021509175628, 8.3879926788022008, -4.6246359904401313, 11.089899173175201, -3.8332542947304775, -13.36196018971258, 8.2464982273107097, 14.657515986404208, 10.904966172392774, 11.533578255944192, -13.982006985588614, -11.973821478795168, -16.592644946389242, 9.2836692767439004, -12.678645783087854, 10.730932446196368, 9.5849200107862327, 8.4498461340685918, -8.6907116625889529, 14.156816081594213, -2.5856081507256512, -9.2993749691896994, -3.6239666126178607, -1.8399557052395836, -9.9970546829752251, -11.017332480853435, -11.692178962270885, 6.3025733321249016, -16.175906955071767, -14.423994620868056, -14.689511946206805, -7.2353003125032167, -9.3660212630661839, -13.858073820033896, 4.7709918994882639, -6.7026088232668739, -10.527782639004828, 16.58828557927492, 15.050247187970289, -4.0564185563228934, -10.640020339068798, 5.0431846567205971, 10.934348304548614, 0.75988821460881439, -10.291366703091549, -13.942020188031572, 14.135017480152827, 11.151498767692816, -11.537353350061172, 10.343082453782436, 7.976541387752091, -3.5774431227145778, 6.7912849734238856, 1.8417106851238594, 8.8764923317563689, -14.359256236175909, -5.6171451890921933, 5.9817930874266256, 3.2031461221092781, -3.5231009274983971, -14.863876345356418, 13.612377512426715, -8.9030335281364348, 5.1285813990983709, 4.8771312118802621, -3.1813763041012044, -8.1658030154444532, 9.2635478384894121, -11.938316318486482, -10.581389864174858, -9.041740376889754, -11.289532586451648, 9.8541909326330934, -10.813754378648875, -10.992626098956032, -4.2128060145436059, -13.803513190675977, -3.4047166821717285, -14.699309096179331, -12.322199151029571, 1.9847013546589598, 3.443351936013523, -7.7412573332668169, -9.4014738152531816, -6.0936722951459252, 11.249057062872248, 5.3612317349290048, -6.0934505412619844, -10.329491262921293, -8.3782268065652321, 10.610705115588038, -7.7383153101209938, 8.5683043797354852, 9.5214421313463742, 9.4646448974772674, -15.945188235432587, 13.571842719150663, 9.1766386061343823, 3.9788060864638335, -16.400242920289237, -12.152955170027367, -11.743525499640301, -10.778431692576483, -9.560949750398839, -11.274506489189537, -10.497378072608422, -11.313774108583567, -8.6889440492171826, -16.999837953521492, 2.8463220500405759, -9.3414733746083147, 14.505309388696032, 7.2740770646355823, -15.216612609375215, -7.7754295642857443, -7.9668693810493751, -11.838336074962589, 9.3302243430363134, -6.1546909317578038, -11.643770269023584, -7.3067290482575826, -7.6586644572207598, 4.1554355791738411, 5.5784827988725025, -6.6788226812914591, -10.099712087346221, -6.812608788772855, -8.6942723276748133, -9.1414982497263626, -5.5404435688554674, 13.782301424897506, 6.4913332097552408, -14.843570407301076, 9.1090159582398744, -11.810479272023766, 10.734632284091132, 12.106233609286406, 1.2074129428018001, 9.05135706765188, 7.0513320487712221, 5.7063731455704252, 17.827025603920255, 8.2204534825947988, 6.859838386896449, -17.066087459633668, -10.546186910811119, 12.544407506754297, -10.501953033608231, 11.631217929282226, -7.3247345033456455, -0.30451282566541621, -8.8097804299616289, 12.580754884209387, -2.4535950387210703, 9.2528280654920945, -6.6762373246501507, 8.5487856314147361, -9.8862934311079176, -7.405954429775278, 11.460818356885351, 9.4241123506707218, -6.0650535086957591, 11.749931801221361, 13.45158323366806, 8.509266618399371, 3.0990921451133864, -11.845686618745093, 4.6809017476948664, -9.0788995203187035, -14.154172714949322, 11.436663871420148, -11.686823110591192, -10.466322347645878, -1.8093094588126659, -8.2842513297508678, 6.998530934794041, -2.8130875381789773, -4.7458503858358174, 14.892214325455083, -13.297630549395505, 14.137398522674463, -5.1741407656371132, 10.811880263388231, 7.6909240450423546, 1.2020066622797796, 8.3882554040760446, -13.296889605096078, -14.12122762385526, -0.86913405214011996, -1.7012640446050573, 12.135944269100591, 13.696947616128121, -4.5178290393967648, 11.379039879071998, -17.142332699109016, -6.2502893853176538, 14.551005043468933, -15.922443449630226, 7.9749887358427554, 7.5006183839537428, -10.731307185445075, 11.828405368248815, -11.242740313773945, 8.6857287401789396, -2.3357416563180076, -9.2522949403141723, 10.057172114119057, 4.2142804964077794, -7.25445812349398, -4.7859211707096279, 12.212717205630641, -0.68060465039856421, 8.3585750011161384, 9.4355684709667997, 5.8736217498953929, -10.357680904873, -15.182609723791906, -10.528438249903205, -10.728845332160351, 4.4271186570969041, -9.5459159618972773, 7.698786708464044, -5.7616256574906473, -6.74427916594568, 5.0713712230747952, 4.9757324493057258, -7.5822193975454732, 2.1521506074067127, 11.702619296651129, 2.475868836880037, -8.5152128927626887, -8.8176272081621523, -6.7396490012107382, -7.1103087325178862, -12.249044472908748, 5.7223187192045835, 6.0785970538718885, 13.311388408274434, -5.1967232459428514, 10.616058764924363, 4.1131834199366937, 9.1157637550044708, 5.0981827919094043, 3.9623438215809581, -5.1277684895200872, 10.717366089367347, -9.6119167010571456, -17.671933631733026, -0.93466484572541053, 9.4511618566836688, 0.51145591409598801, -7.4842698912260595, -12.965780155817985, -11.049283246505306, -9.4204398537725336, 14.713331608978752, 6.1294522089617445, 12.762571544243462, 4.2519976479727246, 11.581799865407062, 4.0540310044195316, 6.7583036711124178, -8.4596629969850596, -11.555561625120337, -13.223361797635503, -11.022881346403601, 7.820188150462851, 10.050313550691401, -2.8748772822692796, -3.975284267526737, 10.165011610963463, 8.361153496598952, 10.23454765876409, 6.9861352278001991, -14.063066120834387, 5.5703634980353156, 4.5720288674742182, -10.208336872812145, -3.8841964569917136, 15.871358616035476, -10.375333061106602, -17.028934392886523, 9.6095097993772214, 2.8612197492337277, 7.3984151374847418, 12.882442279479097, -3.8593872267618985, -3.3505651418910092, 9.1400352361857795, 3.4607159608677991, -11.802758101252648, 16.131696084668302, 4.3485520924992915, 4.9299693363247012, 10.20608409504235, 11.350181288635312, 0.71079817132091727, 7.1011529322063716, -9.9921413971440192, -5.8089676277937103, 21.431868331238753, -7.0747060210352215, 12.069527047899687, -9.4828998378865119, 10.122263948520756, -13.538606127789073, 9.6375976702501429, -4.4100604567201094, -11.99790766311845, -5.976372779813337, -8.272146596627568, -8.9450436886845743, 1.9542103075796229, -2.5876227697187235, -14.368094001362385, -2.985471188013614, -2.478307267502168, 2.7456040916726456, 12.581031236480218, -11.4758779722525, -15.599590155208737, -12.992869206559288, 9.953747866291776, -11.025999481843595, 9.7008748889831633, 9.4677048052865693, 6.0665148799454283, -11.021027787278838, 4.1148665510329865, 9.9715457939675805, -4.524015231428284, 18.833454602793879, 7.5018420072802252, 6.536477074456216, 10.39532612887518, -7.7192567198190574, -5.8633746049064728, -9.4739325485451946, -12.966876834521914, -4.8932353347242916, -7.50082678824488, 7.9240662467055403, 15.473285728117284, -7.874821177550495, 3.9913525758800343, -20.203393732375613, 13.177667766939793, -11.905585671112627, 8.76829420558043, -6.6904194950549218, -2.0990812946584643, 16.352167450942488, -8.6839871579774304, 0.65535704062993771, -9.0914298192610481, 6.226432112620512, 14.414606788199343, 5.3327990949329722, -9.2825422873145076, 5.2444348695624967, -13.52476436519694, -10.565017103537128, -7.9458267805510605, 6.2385267794539532, -10.620897086888419, -14.02491825647715, -17.249193736529822, 21.822546537373011, -14.525572761291961, -9.6352912168501117, 7.7923236942745477, -0.43905931375127905, -1.1677511335028592, 7.9195608711842009, -1.7261157613467151, 0.81574419315180335, -6.6258630940789853, 11.446710993602048, 10.423767215464459, 10.131515821910522, -4.0813762630157786, 5.3099875815632895, 15.005238483277349, 3.9458100113193013, 12.997541564501073, -13.401349640520106, 6.0898523220056484, 8.5430795315739463, -6.727566986421512, -6.0976964106078926, -1.5514248251358895, -6.9251342133096534, -5.0010498589221326, 19.36294632958224, -10.995748094036278, 6.8230876895289425, -8.9816761374312737, 19.252689002798032, 15.018231032342973, 0.75032883111291693, -10.512852145797988, 15.952636394768637, -13.876019658000088, 7.4282002133627536, -15.007337649734009, -20.867628639436518, -12.864466413292632, 12.282886216105501, 5.6117260976193588, 7.7243055425354985, 0.74537471606410499, -8.3753274103443793, 8.7297402808334041, -3.8752359373415373, -7.8660891683218042, -8.8027160564205786, 7.7988010166838881, -7.8129632889899385, -5.8353090570942738, 11.438552747844, -9.8854956847581263, 6.193488211617348, 5.7060858140643864, -5.8417400083956581, -7.1659403388854175, 8.8621684734697617, -13.828395956746165, 11.58722476958626, -8.7757625064865632, 9.7638601085689327, -13.63897121774294, 10.692146632523938, 9.1954815513953641, -9.7262358263602646, -3.0742135000084518, -11.831625275045802, 10.346151064081882, 13.860225574621548, 5.3434462647847401, -12.667486708061194, -7.6071393527596891, 10.497824234551809, 9.1398524858692305, -4.8312688599490299, -9.6866353191391568, -14.936854315955886, -4.5645292398393735, 10.306087472805107, 16.435616799434957, 9.7618939189542857, 7.3359442918945499, 5.4777235052650965, 12.827631906540597, -9.3557044067803972, -8.6207571310957753, -6.9067986860795303, 9.4266173165645881, 8.2700014055707438, -14.396299560527304, -9.1945433850102294, -5.0742673058143186, 5.9363570201246212, 9.1825801770474449, -14.26016478123667, -8.9647881473585791, -10.999991358949853, -5.2643587807317358, 17.966460043223208, 4.5038323715849113, -7.3643627119764705, -8.0021495622334466, -5.5012765171131761, -8.6385795076142866, 10.642859565399243, 16.418157809689014, -12.558310319227193, -5.6944436186565675, -16.620579134203229, 5.2993074909249556, -9.5535858720998252, -6.194850562303122, 7.9283758132069577, -4.3938243314441445, -16.08461551423154, -6.1053020627578558, -7.8156662613007883, -4.2010902685294225, -11.260598796472106, -17.361798229363732, 10.523477968271544, -9.2997205134904561, 4.7239785905440819, -16.55663724338849, 7.336212674126954, -6.9284736037251049, -5.9733477242286268, 16.958437027673817, -9.3688626284447736, 12.335069283139083, 4.4003768017589344, -9.6375650205771759, 4.3025216992304607, 8.1709809734149754, 6.0840979096543046, -1.7791701081822009, -9.7212268065403915, -6.3728373407996992, 9.4709301635928664, -9.8099415495718265, 10.216669472304444, -7.9089613940445638, 9.0133309428613888, 15.233159549099527, 14.443197589960937, 12.315849008505751, 15.22683390790605, -12.204208274855294, 8.0545420942912056, 11.261686524342778, -10.088714704911705, -14.758394330397744, -8.3506925495196622, -5.7190575904160488, -10.474095362096637, 6.7558531383042801, 10.839875782803038, 9.6223187492013871, 4.0011315315627671, 5.3452889051100145, 0.29628684358052387, 10.260560792716758, 10.010269925150098, 12.309818259037518, 8.3443036587520112, -5.4014577244395916, -12.309450717768483, 6.227119823086781, -0.90098300040336077, -5.9574142236058796, -6.5290358544134426, -7.443075641870017, 9.5718761708906559, 5.9045525168917088, -14.09287394192167, 8.537557668616758, -14.160598968888243, 5.8051719496039951, -6.239975019204187, 7.4524259174698209, -7.4731349725176219, -8.5239733925114809, 16.110254200184002, -10.257968713373153, 9.5898379203607735, 3.4675905258102322, 8.1300367938993361, 4.7762632339122959, -5.8974433337845085, -9.3140122423426206, 3.5847848816848376, -9.5355250106758724, 8.6839175133173008, -6.6948323819511488, 6.7933016290691377, -6.3800902026507824, 0.76093699061175468, 2.6435457529778015, 7.4138748481937027, 6.0247308500592567, 5.9280863177297123, -3.8920878288506016, -8.4621386416944677, -18.750651564949948, -7.6188990491921116, -2.1334205811758622, 8.7540093304816082, -9.8600851053842149, 16.342033110995256, -10.800872299968921, -13.998298573757474, -3.2934871871896396, 14.06180118603365, -9.271874228911658, -11.048285130582032, 6.1595626190926716, 8.0570216147192557, 0.66340001966893403, 6.5132884000227351, -5.4201122315987309, -9.7412562635013984, -7.0486139617141514, 16.981384687745692, -8.7022380510622721, 14.647877845477861, -8.0820055541788722, 7.2226523022245761, 5.3790569210687584, 13.728807132743302, 8.5317048523035623, -2.7316549253863927, 5.3846139594020226, 5.4103146460176523, -6.694268736004001, 8.7300406717059573, -13.347383859719848, -8.335174873152722, -10.945696086225201, -10.4875598953527, -6.2891459907155456, -9.3671321709341981, -11.585498988590738, 6.512870728010193, 6.33239714027453, 8.7682544573530521, -6.7439993019333704, 9.5026784978124166, -7.0246760343330656, 6.4372813340255446, 8.1945894173399711, 10.262887249545706, -7.5060931723177706, -14.674750300787338, -13.287289997793177, -8.4928309129257595, 7.4563888548291644, -4.5195874938690226, 8.5442291590063935, 9.7115273312730501, 15.092119744113154, -6.4263051953856785, 0.12831365323535676, 8.7640439297438597, -6.1460218943241305, -10.889755958467752, 13.67769695151666, 6.312988951937812, -13.227320725213115, -11.784825668882982, -7.6748667604861192, 7.7787450544407344, -9.3711259762266828, 13.023365017019263, -7.0200584128511876, 13.494925467734497, 4.2227722997626005, -13.760223253172747, 6.1777636365323456, 12.067306433588751, -9.9155428829691132, -6.5766064428842856, -15.151662906193899, 9.6988065214723864, -10.152731302282174, -8.5735676931961322, -9.9418795299730185, -6.2260760507460198, 9.447544122507308, -8.1319644337468215, -4.145324424570318, -3.5485961822808565, -13.467769122062073, -5.7514070303621585, 4.2372927865136871, 10.111694661148967, -7.4186471554037379, 11.430760000153063, 12.312843067890855, -12.810688665750249, -1.4448074235360808, 7.986361807585828, -1.7676683131382003, -14.521209725348982, -4.352705664193615, 18.914853195668275, -1.5113121651615482, -3.6397864185997131, -8.6196558356553385, 4.1199321080626019, -8.4888399293551817, 0.57614759104880209, -3.8170562650576274, 6.5118953364681147, 4.0953213386352472, -5.3421050165325257, -12.272356482934088, -3.0358640779517354, 4.2481637384966975, -2.7752337082527849, -8.0160326885318369, 9.5768553793879043, -1.8524775210440534, -11.009861394679287, 8.9742068648070266, 12.471334080830026, 9.9992644688047552, 8.0039800551702207, -8.7981872925635614, 6.6433407975833738, 6.5480704488332835, 7.2841246634294423, -6.3252439319780178, -6.0513426125451124, -6.3988334931556485, -17.469331458693546, -4.580254889517116, 8.9993454898016569, 3.2238207283793323, -7.7799510625287303, -13.803751678166556, 9.7121916487763045, -8.1746700971358059, -8.8126126733994941, -4.8155492973679186, -10.804453969532291, 7.0086143651800121, 3.1481410707654631, -12.810183673768677, 2.3362046780839187, 5.744619950986845, 3.8643342874084374, -13.249939418679734, 11.415744222471059, 12.554737671029878, 9.8333778447831257, 5.0957400772063437, -3.9991407502674661, 9.8345770583999279, -9.7368996360840274, -19.449417624721992, -7.5133274868764675, 6.0619042605430966, 7.197156700662827, -7.0063836107615485, -19.263860108465263, 13.028208109141358, 7.1331219897936977, 5.4720228485501652, -7.3579311406347925, 7.1801636071660138, 14.640572831964421, -3.8340913302192701, -3.3062445113231744, 17.400159670258972, -7.1681505547822413, -4.3542281808553351, -8.4546164816007607, 13.421193429578857, -14.905121149794782, 8.3143744117862095, 4.9730046756217972, 8.3532232015837344, -7.5969825424753346, 12.3177910080973, 8.7607875220531426, 8.5127047792303561, 3.5774587189097899, -9.6494548210828786, 7.5331539937229897, -7.4747114284701679, -8.6591660587053916, 7.3468316363038637, -3.622337543593344, 0.47384090625185044, -6.0463560480716252, 8.0499483448215017, 9.7022755442800293, -10.776004671468062, 8.3543427603924503, -5.5360568466131905, 6.0186808121336659, -7.3543970398820848, 9.2806086183805689, -12.230546104506987, 7.4673092848302733, 10.975472812952574, 6.7926415721593818, 4.8749321283736755, 9.5323516120815874, -3.0280886662753885, 5.5571898549900514, 10.226559964818154, -5.8034190385368811, 6.5444311969384019, -9.130374827280793, 15.819448485436817, 5.5538576215556326, 2.8637826501217618, 4.0706674231610558, 6.4597011042272623, -8.3735378854139135, -9.5667300995851061, -13.845901714228189, 12.714093428899416, -8.3628461969588557, 7.5987675327409425, 5.9272125723131186, 4.6950385206484189, -4.8195825770873233, -7.908711363482686, -6.0290697566338824, -8.6859336035752293, -4.5193059923378351, -4.5940077637319696, -4.3311584091869832, 5.3536488354562275, 1.9921280360174241, -9.4633153479117045, -6.6570051760469031, 14.208357863252012, 9.4845107231608647, -7.1832992233853066, -8.8475487049318655, -13.630287949249563, -6.0719107719352952, -14.274798405390152, -11.162105305503859, 13.054901490270078, 12.995371746588807, -13.146715820058548, 12.945646134893682, 3.0460739976722446, -12.155229015360904, 2.7412678887489506, 11.780611735174173, -5.3341954653614927, -10.032480770112713, -5.8447538785525053, 0.52725472542845364, 13.379456926012971, 9.6135830134952744, -1.944448284069229, 9.0502993001659355, -11.346127451101133, 4.2434870682337369, -9.5043367843183457, -2.9775157830606012, 5.4193649803215109, 5.9212605221007886, 6.8739591477125153, -9.3618138585411454, -11.34734301929147, -2.8580136600449677, 9.7314938797272301, 10.716957084696832, 2.261487615173849, -11.936472547545375, -11.596497065616539, 8.1683014049841454, -1.9741314291525349, -3.8079032870338203, -18.998387033650793, 14.785213606318443, -2.4675987407306512, -12.092457768834166, 8.3055089082183038, -9.8880041321383381, -12.17693749962149, -5.6119106856770609, 9.3346742365750952, 5.9978824704833622, 0.13754021975113387, -14.894732183908136, 14.747292229007831, -9.7097733323647439, 7.1041665937562009, 8.747982309638612, -1.1124715705618149, -1.3453533016361534, -7.2336827315963976, -3.3065754079116902, 10.610359888132521, 6.439770888743964, 11.42420401634142, 6.5388842458764689, -10.853598132676623, -15.353822721495742, -8.0675862924724751, 14.459019981256141, -12.566396596207603, 3.4205186262164231, 5.630487549883056, -8.073684341188935, 0.82126057392054652, 13.882060246971731, -11.094144048902541, -11.389801550560342, -10.3187260289045, 2.991571648758196, -6.4911734708363165, -11.245496138683489, 10.9851776336762, -13.130504876870628, 3.7733165504957942, 8.4076079303113911, 7.5529546967120051, 9.1048736341912768, 2.7287083950923141, -6.4019633593747214, -6.7703960792021753, -7.6283872602484184, -7.6359394699956251, -11.153289601654617, 4.0727793884727168, 8.3062884746691932, 15.72392064712384, 0.9811577968163786, -11.722310671012934, -11.342923130703641, 4.6538782013854689, -7.3739066993524025, -5.8947067956510093, 11.486762613574625, 12.413880145399126, 10.786268654735865, -14.830950842039924, -12.718664091764236, 11.838893611398694, 16.960744319691706, -0.90885433404131177, 11.805632469674961, 8.787147329142396, 7.4670599584679005, 13.783711428147573, 2.6889832573487715, 9.8277282208337393, -12.621979239155044, 11.900463485129047, 7.3974913674936378, 7.9790082301381764, -18.460977129782226, 9.6868989422260476, -7.4849707679692381, 2.791279213037106, 5.9072811103444005, 10.027746084723706, 5.481378194108391, 0.94657543605496242, 3.1638084348680802, -11.565804912112132, 8.1295825065418228, 6.2454385368905463, -8.7244225637155086, 9.2949740971114814, -15.413745662976126, -9.2767171742637053, 20.883637553321279, 2.1729042705598971, 5.2123425513190229, 11.260222333457566, 5.4759025599371576, 8.1537344500122764, -12.294121929916995, 8.802476739158374, -20.703918322925325, -9.4123075195898913, 14.838015503157582, 8.1809389421993437, -7.6381202529000944, 5.0731354695422288, -9.7523696522120105, -13.519239387616903, 7.7323479369959101, 12.148583040284464, 5.4807070910189717, 4.8696229713233139, 5.0087903276064836, 6.4402113569592467, 13.277426855835845, 9.6524651881369721, 10.826902095836219, 16.183489895274345, -9.6318043844967534, -1.373132442179763, -11.219593888898418, -15.004319828107285, 18.258393722812315, 3.7354456310459385, 8.0651749744359105, -6.5164044554554748, -12.565266643553137, -12.030885912645394, -8.5404810535779507, 12.314165209697041, 7.2947873166397219, -10.819275536058335, -8.0129408622894012, -3.8121662128657552, -7.6091124585846721, -8.4798365873122474, -3.9868453977970675, 11.38629202057937, 3.5714802941824, 2.9518831049273677, 6.3322250488086071, 11.580034774188221, 13.479927163429085, 2.0786137569475098, 7.9330224326080057, -3.6943001859225055, -3.2256160391289095, -12.811450358156192, 13.541505165687818, 2.6411149013180362, -6.3489619114245244, 13.373338952003571, 12.628299743258562, 1.0027687748564038, 9.2077227922659706, -13.768254699816865, 6.8324600540916247, -14.524379303203943, 9.2715316925285709, 8.7678396133255916, -7.7000840765938703, -7.6752994649649313, -6.9178464084480851, -2.824297046557938, -10.067962153214038, 9.8382780470022801, 9.8343360207768367, -10.442346656794413, -11.531825845771756, -5.6955603852302623, 7.9952115376447042, 7.2796481632297372, -3.9815702225402285, -13.888827599999129, -8.7028698626538308, -6.0635186121417952, -1.0917426165389645, -7.5444189349932813, -13.502585170286313, 5.3738984196649149, 5.1002418292985094, -2.2415640749653791, 8.3993581378656117, 17.872303247028064, -5.7930453662663712, -9.5610560588597515, 8.0594903059030294, 5.9955468570765671, -8.4016643820784811, 16.017479926774133, 12.457791465479348, 14.251050296430238, 13.550966058757862, -8.762120073439311, -19.568799520529904, 14.473633275887034, 4.7150108398434316, 17.622896812791758, 8.5532109821391256, -7.8861564007563967, 2.8018084587073706, 11.238281768369326, 19.036214400042667, -12.627994340787289, -3.229926146308185, -6.2106083456766665, -12.029815325633603, -12.732678066605525, 16.114114027765005, -8.8878875737603433, -9.1952288940063198, 2.9514348736209386, -14.875969949421576, 7.426537438524826, 4.0988218779588257, 5.1048469008081083, 8.3561664083509974, -7.1680838371486972, 0.079559302266173665, 7.234447616829998, 9.2153180384359938, 11.380502523658766, 3.7813665464468564, 9.3571471630839476, -5.6198950965916659, -2.6112846832626295, -13.074922193350705, 7.1458325396315745, -6.8553238201936848, 14.037347515845747, 6.1114574644258219, 2.6233447927944442, -6.6962191818230385, -15.054560815064955, -3.8509653059595634, 5.6193134186600444, 8.4632418525580135, 9.06084843255511, 8.7155312766304451, 14.146656363113056, 9.4485647712524159, -11.894790263269002, 6.3630883640874796, 6.0659222594215532, 9.3423771994935656, -11.56898779218068, -12.569317170483185, -3.1542401369229229, -14.317618053977442, -16.07713062656423, -13.866270731830225, 8.9731628045127234, -2.7568654754219311, 10.650056946180007, -0.38554919912492391, -19.636918428478758, -7.261084813408365, 18.261599502237281, 4.365909470450525, 9.4604701736004575, 9.3379768195852684, -5.9721332777841125, 1.8392337494849149, 12.236588220433115, 10.729755869202716, -5.0163355160529157, 7.8745146479874295, -12.210717308250283, 9.9053843786672573, 4.3176048616878999, -7.1321033170654076, 9.8376099896153644, 13.994875675654404, -11.800822210877568, -12.467732532409068, -4.8096053846346782, -15.806886200214143, -16.011053902031289, 3.3108259217896991, 9.3708906824355758, 4.9387906035182194, -7.2811664484622529, -7.2283659694812323, -4.3994107454794076, 13.986557692605393, 16.267589496305209, -12.5211237853249, -8.6162733581098614, 11.875897506788261, -5.7924040049014529, 9.60395357854315, -13.371234187638548, 7.4044876769030976, -9.9169764629346115, -11.960026798255779, -5.6929530819152605, -14.080996179546117, -4.9741440758010285, -7.2894457453898616, 1.7385165163304241, 10.659988023147882, -1.4616437274123262, -10.074637029156758, -17.086127613435742, 12.235716666711239, -7.9575522168496349, 5.807625236075423, -9.2779276010226894, -16.480345338445041, 9.5297786981975108, -12.287759229285887, -5.793455825490601, 11.046928184816098, 12.263531584491689, -15.868613864191206, 6.1089590101381299, 7.7043039642206841, 6.7725058819006509, 0.19765926454723443, -10.92190123421037, -8.6903416862217444, -3.604954070470813, 10.780882529813848, 7.6342821794581255, 1.819027960022801, 8.9622472070627612, -3.7731185676641705, 2.6511830669363676, -5.936256145443763, -3.5065708446633179, -1.6756694810431396, -9.4457045728120921, 5.1176087336867671, 9.0843869892318665, -4.9165468247185249, 9.6190501542416023, 5.7720688303614107, -8.8665231351704143, -16.776765049597191, 5.1935200585542409, -7.0317717992679913, 8.5952975711448651, 15.701379400382201, -5.1747900955843287, 6.644409479106538, -12.294043736596755, -15.483394542555223, -6.9161043885800755, -16.902160692468406, 13.140408586007654, 7.9585367038084494, -0.60142488467217781, -10.583573691246794, 7.6570812407643905, 10.488467203766263, -12.229594163883426, -12.105180821633089, -10.100333917660924, 10.582889173673999, -4.3524138084056574, 4.1598294177868027, -7.7208623056787218, 9.8373959423124191, -9.843437056863948, 9.2758547221503864, 13.917929858415311, 9.6348606573169207, 6.1603576344825903, 7.2761550553448275, -5.6132644264075031, 16.925921888188984, 13.099232943399601, -12.169951256692608, 8.0341465714582103, 9.5080586839310293, -8.9153040306547862, -6.2778930359354987, 0.65702865949253608, 6.1455975831103666, 3.4956736733487177, -13.101966614043903, -8.4917541060921486, -7.7703858331616402, 2.9540207920840338, -2.8250454453694225, 16.471572201031012, -8.3401753077338174, 8.5209392200398799, -8.4562622463700912, 5.3451445327350049, 8.3227551961577149, 9.5505384761710648, -9.6168853444985132, 7.8088619634040271, -10.010194534199005, 10.407541359870157, -12.730901681260953, 10.062237956980878, -8.301093581147164, -11.221782089013969, 5.0699226682185836, 6.8670809315755763, 9.5183305660198574, -12.477293633009369, -3.0829984725185011, 14.251075736126907, -0.50381312202666373, 1.3945668674871461, 4.4380349292124333, -8.4792849992484687, 15.740298722260704, 6.4916661990457039, 9.8781328856963952, 14.524311425947424, 8.623227064986775, 1.82594923740208, 8.1658888991281113, 19.519909829772214, -0.71626812905103776, 1.7182300090879543, -8.0056305624195137, 8.8667806307632393, -6.8903486607996696, 5.3931378831660304, -14.284745953661838, 11.800779205285183, 11.828892295047666, 11.579327959504184, 5.9644626407280574, -10.637566489206868, -6.3308930175168046, 10.362896991246821, -13.136681551103671, -10.69114929291889, -8.2804076555200332, -8.7620956793565572, -8.3349590113674843, 6.0390086996968186, -0.92206940007654714, 16.688147291793179, -7.7396944231238889, -10.556885976235911, -5.5034713893873217, 10.684323799177031, 10.164740010619706, -18.644906837500962, 7.8255279920941758, 7.1184183927575999, -8.5879829996361785, 10.058536284915368, -3.9577147638427337, -9.4390455070755355, -10.813502747434075, 3.1725069430189179, 14.646645070268773, -6.6958720302719321, 7.1891012020482057, 2.776770380964142, -5.3045752723276198, 11.024688310314966, -8.8716706651748609, -6.2182144207648875, 7.2174155723591822, 9.2363647659736916, -0.13811663085025644, -6.5095852199241193, 2.7850661520962201, 5.7288466875807895, 3.8404238060339386, -11.979694823507765, -8.1566218452888641, 8.4872181623141802, 4.0684730663558621, 9.433119896225687, 17.452359798566942, -9.1852211978356539, 3.7813711040017632, 13.687886395835575, 8.3110503099043083, -12.263855365231695, -0.29265821325473718, -5.7786710506977288, 0.32000221107421295, -13.152220176187292, -6.5995903240006717, -13.649334703564579, -7.5516513340805105, -15.16406327996164, -6.7664832291371457, 9.9511431024063146, -11.833825853245724, -11.726480937964023, -4.6960938337568416, 3.6909792826776235, -5.7241654435325771, 0.84009221550172219, 3.981445765587416, 8.3193977689219309, -14.855487044550641, -12.13768399449228, 8.2575189786919658, -12.482209307351347, 12.288265749008579, 12.92588605732125, -0.89651953932604156, -17.178851924529209, 13.465060130471429, -0.66179931634497746, -4.7361380949519907, -8.5915497494217874, 9.8633923545024036, -11.075503948766817, -11.521258634171812, -16.937563321814299, -8.4089961555477153, 10.316744468138424, 11.068755254870558, -12.812559137681774, -11.716000182253042, -10.794814834414403, -14.695829972179469, -5.7734367211811755, 19.281663549262714, -7.7079679114509911, 18.982133221850518, 6.7278265135517552, 9.4200950070653935, -5.0327780626629206, -1.1472749532062567, 8.9655615288611052, -10.289968622568939, -4.5317886320427014, -5.0717832150149214, -12.403158065152988, 16.054879478569319, 11.910769204629043, 8.8721630995550154, 12.946670225247273, -20.040326823281728, 15.061437997065909, 12.371159663686912, -5.2434241432319393, -6.539600733678907, 8.9759004731301122, 10.399696431036546, -9.7820158235043255, -1.8655127741351087, -7.2564512028104291, -9.2402317505484497, -15.743596514833451, 8.0518221334585913, 8.064389141916843, -5.1750464722524647, -1.2577099412771857, 11.088648050953193, 14.734664098438651, -8.7257834129372487, -4.9071340910761805, -7.2288497019818241, 11.368753439780507, 11.259515603467754, -0.9190234527098583, 10.508309728639846, 5.5014236641516137, -1.0062376510942861, 3.9510038373896794, -3.3772476520373296, -12.298064413396816, 1.1518807046710942, 9.8347990668982277, -9.6697877164226895, -5.1708006319540161, 10.90534178699129, 9.0780310964231923, -11.06717326378323, -10.193153698637712, 1.6370922062264599, -1.599701860652494, 7.4493340597532782, 10.079750519485344, 5.9817167134058051, -6.1883642950981734, -8.7859917448021054, 7.6925693496530796, -11.726693947959594, 1.5292664230077266, -3.7640503328337047, -9.2026303785959076, 8.3703384923817321, 9.2968574133785165, -9.0282964165522213, 14.082662142896044, 7.0391904432891064, -8.1892402659133481, -8.494960679412987, -8.3171594195215324, -4.1204583607408765, -12.464929795412097, -8.2800259108270922, 5.0158695467591343, 2.90504266938304, 5.5802620759772603, 9.6053945607379294, 7.4665086294967553, 7.2836197716168538, -6.0797636096551519, 5.9192672325212143, 4.3197502963078556, -2.5794586298505413, -8.3804827856018385, -5.7616389244014083, 7.5165636982133597, -3.7871806468757891, 2.6957388838195038, -3.0339814791522679, 7.7390014359139343, 1.0179611498135317, 0.57428282151728316, 9.2486809887277968, 8.9851820183067517, -12.322228892543235, 2.1846637256927366, -6.9268224211182101, -5.6465263096341207, -9.8609073169739414, -8.0437109222330996, -2.5924823061626299, 10.799267368908426, 9.5532367964485942, 2.1510949897407339, 0.72813586085734983, -7.6316236927774765, -6.6634161974825536, -7.6995131312161114, -2.6469146283491312, -7.8927242011683072, 7.9686594739655217, -8.0858268153723696, -11.113628935027652, -4.2312391545249435, 7.400536752330261, -15.878877108958942, 5.267992480772417, 11.16296673206628, -17.540164979801386, -14.801126830818111, -11.385201143366997, -14.508310090705075, 14.464207778841862, 11.215905228606482, 8.9532196390944634, 3.1058203222772014, 8.0753828772231113, 10.559485384240654, -8.2414912742823354, -11.714805939566189, 4.7281042573450431, 12.657353257890819, -6.3043093049399248, 5.067000914225444, -14.714628033981958, -7.7444814248447615, -2.5025562382741042, 13.564851064978582, -9.4328409951276662, 10.04126088038934, -10.570084081595921, 2.3444801610493466, 7.1831276221853866, 7.404162681313343, 1.1684082688282307, -8.8884680285241533, 1.9400943416397112, -13.196562462363692, -4.5705203572273359, 11.003636571194738, 11.468673888105736, -10.534610194739036, 4.4477979444487845, 7.3667611650061362, -12.044187016767467, -11.396051178941862, 3.9462512050906744, -12.988661501036244, 10.545881026800801, -8.0309289513402735, 9.9370741830104734, 13.654579804016825, 7.0469488853837321, -10.938942295813185, 5.1800344871423132, 10.882232153707738, 1.2710853105543087, -6.5661242949766816, 9.7776412282696459, 13.321850745505881, -8.1153422577009291, -2.2941713421233958, -8.7097542589155221, 2.2618606797252978, 3.1810406025700315, 4.829995467844082, -8.8230523342209999, -7.8350849175265527, -9.1156429568037076, -11.442019665347123, 2.2127249998070249, 18.018245968154236, 6.7919203279388967, 10.818120665998064, 15.957114328595093, 9.436472994391762, -15.0724442489973, 10.177531220212931, 8.7382348206500033, -7.4439716572652967, -10.135340539629416, -1.5478693068716267, -6.2520881203409369, 21.51870984833112, 6.7814496888686202, -5.4629593689724354, -1.0810664038442734, 11.680093350196586, -1.1684404824410481, -8.8192804660387161, 11.947180907432026, -11.865540708697406, -12.073158010228243, -9.3168616660647103, -10.855717378744718, 12.832277402471462, -15.233827235544979, 3.719489187613028, 12.974696537296685, -8.75959465422536, -2.4475947054420195, 11.313184053568827, 6.9182165488811229, 12.123675956468196, 9.6442923820443145, 10.799907622549545, 1.3696427348286129, 12.109212710737127, 2.6404947713803306, 9.5435762973738267, -5.4268755145327745, 10.974370356637689, 11.459181655827159, 10.228613791177938, -2.0376202581586202, 8.5519223504193267, -15.144108617549279, 10.208111627929036, -16.074632706297336, 9.535346082793712, 12.968894012265515, 4.2926497043948793, -7.6447760416419124, 7.3591604897068219, -6.294066487171917, 8.6661482650382133, 4.3524844886549072, -9.6284187314739373, -16.389868048898698, 14.370574991274481, -8.2963813089615268, 16.504114329831857, -8.4564658970066731, -6.3969858495492078, -7.0522130158545027, 16.328014713505098, 4.0676774938327931, -8.8805902890220576, -5.6438005548253818, 10.887856323753418, -13.497382772819085, -17.229682704447541, 10.177341730428909, -10.959196430060141, -15.892999214486872, -0.39312548358593402, 17.548662000796629, 8.138747505659067, -11.081466337015, 9.3549081143588229, -5.2668052531909293, 0.59145215464277101, 13.865804154173629, -6.7446135707105945, 10.591472647241186, -6.8775928522394087, 0.79035105716724385, -0.83434363179526505, 13.426811179256797, 13.480253964577903, 7.9579945693584886, 7.8687287842784803, -1.2711852125721312, -6.5831626138029433, -10.255988526378117, -9.3721646222445631, -4.5483019698635951, 12.654546996958775, -2.2845772848784054, -13.395748226685187, 10.227730333720137, -8.9275038607977386, 9.2096733075692399, -9.1994549499155589, -4.5768838702423018, 7.4336970353205523, 6.1990136188764922, 5.392562974045604, 6.8615159418299543, -9.9148725697134683, 10.272013543022926, -6.541146389868957, 6.1996539988491746, -8.5702789915391175, 6.0710850780527128, 0.41216255793753664, -6.8452494187073416, -7.3698306482120808, -4.3788198137924814, 5.254192997316685, 7.0651978737141468, -8.3496697717376325, -15.541186410630397, -13.361062248182593, 11.869712905857645, 8.8858662456220436, 2.315280646740792, 9.1370562156627635, 10.612212040886574, 15.723923545841364, 9.3000796832012966, -12.203790919241875, 9.5229433645020229, -11.332560886601259, -11.799762316157022, 8.6718707861873146, 3.4390494326490342, 10.948206478975262, 10.351083327208633, -2.3551385999606347, 3.6593868571158006, -10.912461508095474, 6.3601915796808566, 12.644105697007012, 8.0987317607631102, 6.8425116090817673, -7.8614337809266139, -16.777952262404956, -15.092829035089149, -10.867283176676434, 9.7617585972043095, 7.0699740006630494, -0.80345056050581032, 7.2341098943011026, -2.7901743760803868, -14.023920253719963, -8.6493250885626658, 12.119156062865828, -12.565363519164727, -6.6257256922764087, 9.9530063133378111, 6.2285641482405287, 8.5890710113124502, 10.901661163934543, 1.7011000225296526, 9.2328185698429888, -2.5151197107048353, -0.78814118951465995, -6.3782804075339934, 0.77016194990540299, 4.7860592575330942, -18.091131028655795, 6.6618347947308489, -4.5537746303503699, 12.906362988375243, 6.6637236513957019, 5.4194732758517778, -5.626683563346548, 4.8295291548347352, -11.904932030289029, 9.9944164460741938, -11.027348899069844, -0.014743410131345848, -7.3410368137184197, -12.558702052466645, -9.2966083471503538, -2.8582301845790048, 16.122229949617235, 6.0332133243788979, 9.4423884847579131, -6.7953848219405604, -8.640997496023326, 11.564755524473357, 7.7370575077503672, 11.178600690994582, 9.6609341268345741, -5.0924071871300569, 2.9472182219982841, 11.322674214116185, 17.636604816170465, -8.112421382991716, 5.7980976514734257, 10.587871354585735, -10.207529594090163, -13.012906685255201, 1.6439826301840548, 4.7959168408892552, -9.1817793609379343, 15.910744159295755, 11.988413488939839, 10.225499838967904, -2.1100999951643771, 7.7773391391119979, 4.2070274590049737, 3.1789918079199362, 11.389698381773869, -5.6797986359782069, -4.7261529062162424, -6.1926650154600731, 9.5097255166801595, -4.4005426737892748, 4.8284348550831577, -7.4035564503513553, -10.371755556185054, -11.138214834764621, -11.479591917367713, 7.3492465579271542, -8.6401023000535666, 2.4737379805053212, -8.4391176745455763, -3.5699286239866383, -8.1254703716775829, 11.948227614312263, 7.880462510583679, 1.8623842706739999, 7.3888689386136646, -1.2896033177393418, -8.2116493851785464, -9.0121076446113531, 2.6038276518722672, 7.9944375021940459, -4.3649859784435145, 5.1704186172538593, 7.7846827735959723, -0.51775021699396251, -13.814395914977867, 11.155615752700793, -4.0116122940272048
+};
+
+char detected_data[] = {
+0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1
+};
diff --git a/codec2/branches/0.7/src/HRA_112_112.h b/codec2/branches/0.7/src/HRA_112_112.h
new file mode 100644 (file)
index 0000000..8ae1c7c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+  FILE....: ../src/HRA_112_112.h
+
+  Static arrays for CML LDPC, generated by ldpc_gen_h_file.m.
+*/
+
+#define HRA_112_112_NUMBERPARITYBITS 112
+#define HRA_112_112_MAX_ROW_WEIGHT 3
+#define HRA_112_112_CODELENGTH 224
+#define HRA_112_112_NUMBERROWSHCOLS 112
+#define HRA_112_112_MAX_COL_WEIGHT 3
+#define HRA_112_112_DEC_TYPE 0
+#define HRA_112_112_MAX_ITER 100
+
+double HRA_112_112_H_rows[] = {
+22, 18, 15, 63, 16, 13, 1, 2, 29, 25, 28, 4, 36, 10, 38, 7, 60, 23, 11, 38, 28, 1, 12, 31, 57, 45, 57, 30, 23, 59, 67, 14, 16, 4, 14, 62, 15, 50, 7, 70, 64, 6, 42, 48, 9, 31, 19, 40, 49, 2, 25, 3, 41, 49, 36, 9, 29, 39, 31, 5, 17, 1, 29, 25, 11, 21, 18, 2, 8, 22, 39, 15, 8, 22, 13, 3, 19, 4, 21, 62, 34, 43, 6, 24, 17, 60, 8, 74, 6, 44, 60, 10, 33, 12, 26, 24, 45, 81, 69, 80, 41, 28, 23, 5, 10, 20, 52, 18, 13, 86, 3, 7, 59, 21, 65, 72, 34, 37, 26, 55, 47, 48, 34, 5, 44, 47, 68, 96, 82, 111, 61, 74, 30, 17, 55, 98, 81, 66, 89, 35, 74, 82, 91, 51, 55, 51, 30, 89, 61, 75, 40, 71, 73, 11, 56, 54, 19, 47, 94, 69, 64, 20, 64, 12, 54, 77, 42, 88, 36, 52, 90, 63, 70, 27, 32, 73, 91, 32, 56, 46, 9, 78, 51, 68, 88, 67, 20, 43, 40, 14, 66, 86, 39, 97, 38, 27, 50, 84, 54, 92, 61, 46, 67, 24, 58, 35, 58, 37, 98, 85, 73, 84, 48, 35, 57, 16, 26, 37, 65, 32, 72, 95, 107, 33, 77, 33, 85, 105, 106, 75, 56, 71, 79, 59, 52, 105, 79, 90, 93, 100, 88, 112, 86, 80, 65, 42, 106, 100, 93, 94, 99, 97, 93, 101, 111, 99, 83, 53, 85, 95, 108, 107, 41, 109, 84, 78, 104, 101, 69, 110, 98, 103, 80, 83, 77, 71, 76, 78, 87, 102, 104, 95, 96, 83, 87, 50, 110, 103, 112, 45, 58, 70, 94, 91, 89, 81, 101, 82, 63, 72, 100, 97, 76, 112, 53, 105, 49, 75, 109, 102, 66, 111, 68, 87, 92, 79, 96, 43, 90, 44, 110, 99, 102, 92, 103, 106, 62, 53, 27, 46, 108, 104, 107, 108, 109, 76
+};
+
+double HRA_112_112_H_cols[] = {
+7, 8, 52, 12, 12, 42, 16, 69, 45, 14, 19, 23, 6, 32, 3, 5, 22, 2, 45, 50, 2, 1, 18, 84, 10, 7, 62, 11, 9, 21, 24, 63, 2, 5, 28, 13, 6, 15, 58, 39, 39, 22, 76, 13, 26, 68, 9, 10, 49, 38, 32, 11, 34, 44, 8, 7, 25, 67, 1, 17, 19, 36, 4, 41, 3, 26, 31, 15, 45, 40, 8, 4, 41, 20, 6, 53, 1, 42, 9, 20, 25, 17, 33, 41, 3, 19, 55, 17, 27, 14, 31, 88, 15, 26, 36, 16, 28, 24, 27, 16, 30, 56, 48, 43, 4, 5, 38, 37, 40, 46, 18, 18, 22, 50, 76, 34, 60, 83, 39, 73, 56, 92, 42, 52, 75, 35, 37, 33, 61, 67, 47, 75, 66, 70, 29, 92, 51, 95, 84, 21, 57, 28, 46, 66, 93, 11, 94, 55, 96, 20, 71, 48, 53, 43, 82, 90, 66, 90, 14, 44, 54, 62, 34, 58, 81, 53, 23, 43, 27, 93, 10, 86, 37, 80, 60, 49, 21, 79, 74, 72, 48, 61, 40, 76, 64, 29, 38, 79, 51, 54, 13, 49, 72, 30, 50, 86, 35, 80, 61, 56, 36, 59, 65, 91, 25, 47, 58, 59, 78, 47, 32, 24, 44, 86, 64, 57, 12, 23, 109, 107, 85, 63, 31, 65, 62, 68, 111, 78, 104, 89, 112, 87, 69, 105, 65, 94, 109, 78, 72, 104, 85, 108, 77, 106, 79, 74, 103, 96, 64, 105, 105, 102, 63, 35, 59, 108, 112, 81, 102, 57, 106, 83, 81, 77, 101, 55, 94, 96, 97, 106, 46, 101, 83, 85, 71, 107, 104, 87, 33, 67, 103, 95, 30, 91, 89, 103, 75, 51, 107, 87, 91, 89, 99, 68, 52, 109, 99, 88, 84, 112, 54, 70, 92, 100, 98, 74, 60, 100, 98, 110, 90, 73, 71, 95, 70, 100, 29, 69, 110, 93, 82, 97, 98, 77, 73, 99, 101, 108, 82, 102, 111, 110, 111, 97, 88, 80
+};
+
+double HRA_112_112_input[] = {
+-5.7868467875518395, -6.340739523388657, 3.6654768375589399, 4.1452438183910827, -4.6746135252043111, -4.8353634065473701, -6.0729133999971285, 4.0335561282226271, -6.1114855315699135, 4.1029513876344916, -4.6481634503883624, 5.7650915278538646, 6.5567610490570312, 5.1810523550761207, 3.4789051916752669, 4.2678848515507122, 4.0314705275547089, 6.0297078342283799, 4.9101169653222163, -6.4577297598332324, -7.4273487270443095, 3.472130985267488, -6.5346233967202254, 7.5312028458762414, -5.2618748211985915, 6.4198074556254969, 3.7500207659511484, 5.4040878141701141, 5.7554260586578803, 3.3973620625026886, 7.1815269888532907, 5.0031747952824963, 5.1377243276145599, 5.385229914081755, -0.61384230253605643, 0.46954911161835722, 3.5182611493679663, 3.393698829567279, 6.147483866535171, 3.8374563885989228, 1.3663773773557015, -4.0917661778352352, -3.2968298202652835, -6.0371912041431148, -8.4279246895331781, -0.98556788606912304, -3.515442879601625, 4.2642476942514875, -5.5905016743156972, 3.6920101668161727, -4.035860013856472, 5.3290190966269995, -2.9729656070594057, -2.5054371041338537, 6.8683150013190115, -7.1109038108500098, 6.7301890172695158, 2.5782062882356374, 4.4161464916633282, 2.2692851122935322, -1.3682527221025034, 3.0794629981237631, -7.8655412763279973, 1.1479897597156494, 0.22370696314520414, 1.1222453403894148, -3.1335220808128219, -3.8352985265277089, -1.2463521619727009, 2.9511814015293218, -8.668811041413111, 3.0185610517830548, -6.9592962351476091, 3.9653416636625414, -3.9384322074229408, 1.6789027505247516, 2.9579632055145502, -2.1212672699995125, -3.8892168640945193, 7.516114544807583, -0.84285604179011253, 4.1295390817792512, 0.26093278495228162, -3.6071666499996047, -0.065323173773821908, -1.9146584862100915, 4.7951161310834367, 5.5440002982088803, 3.5917539980319364, -0.81416023563684481, -2.6588977758747721, -3.0404494660606227, 4.5389936536649662, 2.7870543501114082, 3.5622966707453889, 5.1982116994791161, 2.4775319712999302, 0.70541080068007755, 0.89622787904518464, 4.3789020039207758, -2.4976040580619445, -0.7201255450933205, 4.2071986295109394, -5.2418379271657001, -4.092365654835163, -4.3510198326542557, 3.7404138637596001, 1.2496890930262492, -7.1053909336149728, -4.8888279905256748, -6.3523901926735249, -1.8757980409249277, 3.6256343910366273, -3.6165398844758228, -0.38322352317510561, -0.84747550047769449, -1.2717892264620718, -2.3899810721111154, 4.1368500898628637, 3.0440159002314924, 3.4235543074310728, -2.146097053557551, -1.7537615307751735, -1.0280987119225686, 4.9009275359419204, 5.0046047156368116, -0.47700833783807428, -4.5989492891875567, 1.4154839158712684, 0.33410724822249849, -4.771937854508927, -1.1817007924012972, -2.5960865023249302, 0.30422629502493687, -2.2097849377516763, -4.343244940878872, 1.9464288912612249, -9.0976989032526809, -8.6454142547592685, -1.8164317522989997, 2.2780845702169961, -4.8775405042023356, -0.61834757216625769, -1.985554501661331, -0.87599558657596699, -8.0610201531782124, -5.9847574894882554, -10.365536404711067, 2.9782191161319376, -6.9443820217795169, 0.72935566343949876, -4.5326632961380664, 1.1307250622386897, -4.0853969692041314, 5.4926924507347596, 5.6722555096362042, -2.5069992226180222, 2.0460084066662092, 2.5375899018238197, -3.5264293517823679, 3.2103083878487557, 5.793713046583183, -2.7633653287377995, 6.482851815629938, -1.2471646528152021, 3.0010491047486085, 0.29072399293868856, -4.0686659405747738, -2.6253508133431289, -6.3896590677017171, 5.7054076607727886, 4.3053292399977092, 2.2372599539047151, -4.8975607398431897, 5.8124794005531406, -0.69648233429781359, 5.5509723605410004, 2.0900652762982923, -4.7944253330785118, -2.9224693872108287, 6.0218579796888303, 4.7027436964063387, -4.1564871824868659, -1.324779121305123, 0.38031612697724176, -0.69335927945709175, -0.4028295686263082, 2.0967669774299189, 2.7947186736855909, 2.1473880039026203, 6.368702510367898, -3.0691782325684049, 1.6125827087903837, 3.5925359669662518, 5.178224480471127, -2.5070763799556617, 4.4280512389456632, -6.5385259627250134, 2.8047951999607603, -3.0185715385981151, -0.33348983718789993, -4.3285127692183556, -7.9609407359365134, 7.064973172264966, 0.95714371675898213, -5.5481272272415545, -1.6024149180708045, -4.5740915350065992, -1.5117120929647263, 1.9996824689403947, 5.9527526663437724, 5.0239857792804967, 6.2677418491798784, -1.9758548902654505, 2.1709284879472324, 2.5054563138111572, 4.4483685492445115, 3.2098357106645676, -4.5306213859481099, 1.1291114493451548, 1.5827945023160555, -5.2733490015732292, 5.0664709821503457, 1.9652801880230106
+};
+
+char HRA_112_112_detected_data[] = {
+1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0
+};
diff --git a/codec2/branches/0.7/src/_kiss_fft_guts.h b/codec2/branches/0.7/src/_kiss_fft_guts.h
new file mode 100644 (file)
index 0000000..1c62a34
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+Copyright (c) 2003-2010, Mark Borgerding
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* kiss_fft.h
+   defines kiss_fft_scalar as either short or a float type
+   and defines
+   typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
+#include "kiss_fft.h"
+#include <limits.h>
+
+#define MAXFACTORS 32
+/* e.g. an fft of length 128 has 4 factors
+ as far as kissfft is concerned
+ 4*4*4*2
+ */
+
+struct kiss_fft_state{
+    int nfft;
+    int inverse;
+    int factors[2*MAXFACTORS];
+    kiss_fft_cpx twiddles[1];
+};
+
+/*
+  Explanation of macros dealing with complex math:
+
+   C_MUL(m,a,b)         : m = a*b
+   C_FIXDIV( c , div )  : if a fixed point impl., c /= div. noop otherwise
+   C_SUB( res, a,b)     : res = a - b
+   C_SUBFROM( res , a)  : res -= a
+   C_ADDTO( res , a)    : res += a
+ * */
+#ifdef FIXED_POINT
+#if (FIXED_POINT==32)
+# define FRACBITS 31
+# define SAMPPROD int64_t
+#define SAMP_MAX 2147483647
+#else
+# define FRACBITS 15
+# define SAMPPROD int32_t
+#define SAMP_MAX 32767
+#endif
+
+#define SAMP_MIN -SAMP_MAX
+
+#if defined(CHECK_OVERFLOW)
+#  define CHECK_OVERFLOW_OP(a,op,b)  \
+       if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
+               fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) );  }
+#endif
+
+
+#   define smul(a,b) ( (SAMPPROD)(a)*(b) )
+#   define sround( x )  (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
+
+#   define S_MUL(a,b) sround( smul(a,b) )
+
+#   define C_MUL(m,a,b) \
+      do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
+          (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
+
+#   define DIVSCALAR(x,k) \
+       (x) = sround( smul(  x, SAMP_MAX/k ) )
+
+#   define C_FIXDIV(c,div) \
+       do {    DIVSCALAR( (c).r , div);  \
+               DIVSCALAR( (c).i  , div); }while (0)
+
+#   define C_MULBYSCALAR( c, s ) \
+    do{ (c).r =  sround( smul( (c).r , s ) ) ;\
+        (c).i =  sround( smul( (c).i , s ) ) ; }while(0)
+
+#else  /* not FIXED_POINT*/
+
+#   define S_MUL(a,b) ( (a)*(b) )
+#define C_MUL(m,a,b) \
+    do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
+        (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
+#   define C_FIXDIV(c,div) /* NOOP */
+#   define C_MULBYSCALAR( c, s ) \
+    do{ (c).r *= (s);\
+        (c).i *= (s); }while(0)
+#endif
+
+#ifndef CHECK_OVERFLOW_OP
+#  define CHECK_OVERFLOW_OP(a,op,b) /* noop */
+#endif
+
+#define  C_ADD( res, a,b)\
+    do { \
+           CHECK_OVERFLOW_OP((a).r,+,(b).r)\
+           CHECK_OVERFLOW_OP((a).i,+,(b).i)\
+           (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i; \
+    }while(0)
+#define  C_SUB( res, a,b)\
+    do { \
+           CHECK_OVERFLOW_OP((a).r,-,(b).r)\
+           CHECK_OVERFLOW_OP((a).i,-,(b).i)\
+           (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i; \
+    }while(0)
+#define C_ADDTO( res , a)\
+    do { \
+           CHECK_OVERFLOW_OP((res).r,+,(a).r)\
+           CHECK_OVERFLOW_OP((res).i,+,(a).i)\
+           (res).r += (a).r;  (res).i += (a).i;\
+    }while(0)
+
+#define C_SUBFROM( res , a)\
+    do {\
+           CHECK_OVERFLOW_OP((res).r,-,(a).r)\
+           CHECK_OVERFLOW_OP((res).i,-,(a).i)\
+           (res).r -= (a).r;  (res).i -= (a).i; \
+    }while(0)
+
+
+#ifdef FIXED_POINT
+#  define KISS_FFT_COS(phase)  floorf(.5+SAMP_MAX * cosf (phase))
+#  define KISS_FFT_SIN(phase)  floorf(.5+SAMP_MAX * sinf (phase))
+#  define HALF_OF(x) ((x)>>1)
+#elif defined(USE_SIMD)
+#  define KISS_FFT_COS(phase) _mm_set1_ps( cosf(phase) )
+#  define KISS_FFT_SIN(phase) _mm_set1_ps( sinf(phase) )
+#  define HALF_OF(x) ((x)*_mm_set1_ps(.5))
+#else
+#  define KISS_FFT_COS(phase) (kiss_fft_scalar) cosf(phase)
+#  define KISS_FFT_SIN(phase) (kiss_fft_scalar) sinf(phase)
+#  define HALF_OF(x) ((x)*.5)
+#endif
+
+#define  kf_cexp(x,phase) \
+       do{ \
+               (x)->r = KISS_FFT_COS(phase);\
+               (x)->i = KISS_FFT_SIN(phase);\
+       }while(0)
+
+
+/* a debugging function */
+#define pcpx(c)\
+    fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
+
+
+#ifdef KISS_FFT_USE_ALLOCA
+// define this to allow use of alloca instead of malloc for temporary buffers
+// Temporary buffers are used in two case:
+// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
+// 2. "in-place" FFTs.  Notice the quotes, since kissfft does not really do an in-place transform.
+#include <alloca.h>
+#define  KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
+#define  KISS_FFT_TMP_FREE(ptr)
+#else
+#define  KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
+#define  KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
+#endif
diff --git a/codec2/branches/0.7/src/ampexp.c b/codec2/branches/0.7/src/ampexp.c
new file mode 100644 (file)
index 0000000..f98f84b
--- /dev/null
@@ -0,0 +1,1095 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: ampexp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 7 August 2012
+
+  Functions for experimenting with amplitude quantisation.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not,see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ampexp.h"
+
+
+#define PRED_COEFF 0.9
+
+/* states for amplitude experiments */
+
+struct codebook {
+    unsigned int        k;
+    unsigned int        log2m;
+    unsigned int        m;
+    float               *cb;
+    unsigned int         offset;
+};
+
+struct AEXP {
+    float            A_prev[MAX_AMP];
+    int              frames;
+    float            snr;
+    int              snr_n;
+    float            var;
+    int              var_n;
+    float            vq_var;
+    int              vq_var_n;
+    struct codebook *vq1,*vq2,*vq3,*vq4,*vq5;
+
+    int              indexes[5][3];
+    MODEL            model[3];
+    float            mag[3];
+    MODEL            model_uq[3];
+};
+
+
+/*---------------------------------------------------------------------------*\
+
+  Bruce Perens' funcs to load codebook files
+
+\*---------------------------------------------------------------------------*/
+
+
+static const char format[] =
+"The table format must be:\n"
+"\tTwo integers describing the dimensions of the codebook.\n"
+"\tThen, enough numbers to fill the specified dimensions.\n";
+
+static float get_float(FILE * in, const char * name, char * * cursor, char * buffer, int size)
+{
+  for ( ; ; ) {
+    char *     s = *cursor;
+    char       c;
+
+    while ( (c = *s) != '\0' && !isdigit(c) && c != '-' && c != '.' )
+      s++;
+
+    /* Comments start with "#" and continue to the end of the line. */
+    if ( c != '\0' && c != '#' ) {
+      char *   end = 0;
+      float    f = 0;
+
+      f = strtod(s, &end);
+
+      if ( end != s )
+        *cursor = end;
+      return f;
+    }
+
+    if ( fgets(buffer, size, in) == NULL ) {
+      fprintf(stderr, "%s: Format error. %s\n", name, format);
+      exit(1);
+    }
+    *cursor = buffer;
+  }
+}
+
+static struct codebook *load(const char * name)
+{
+    FILE               *file;
+    char               line[2048];
+    char               *cursor = line;
+    struct codebook    *b = malloc(sizeof(struct codebook));
+    int                        i;
+    int                        size;
+
+    file = fopen(name, "rt");
+    assert(file != NULL);
+
+    *cursor = '\0';
+
+    b->k = (int)get_float(file, name, &cursor, line, sizeof(line));
+    b->m = (int)get_float(file, name ,&cursor, line, sizeof(line));
+    size = b->k * b->m;
+
+    b->cb = (float *)malloc(size * sizeof(float));
+
+    for ( i = 0; i < size; i++ ) {
+       b->cb[i] = get_float(file, name, &cursor, line, sizeof(line));
+    }
+
+    fclose(file);
+
+    return b;
+}
+
+
+/*---------------------------------------------------------------------------* \
+
+  amp_experiment_create()
+
+  Inits states for amplitude quantisation experiments.
+
+\*---------------------------------------------------------------------------*/
+
+struct AEXP *amp_experiment_create() {
+    struct AEXP *aexp;
+    int i,j,m;
+
+    aexp = (struct AEXP *)malloc(sizeof(struct AEXP));
+    assert (aexp != NULL);
+
+    for(i=0; i<MAX_AMP; i++)
+       aexp->A_prev[i] = 1.0;
+    aexp->frames = 0;
+    aexp->snr = 0.0;
+    aexp->snr_n = 0;
+    aexp->var = 0.0;
+    aexp->var_n = 0;
+    aexp->vq_var = 0.0;
+    aexp->vq_var_n = 0;
+
+    //aexp->vq1 = load("amp_1_80_1024a.txt");
+    //aexp->vq1 = load("../unittest/st1_10_1024.txt");
+    //aexp->vq1 = load("../unittest/amp41_80_1024.txt");
+    //aexp->vq1->offset = 40;
+    aexp->vq1 = load("../unittest/amp1_10_1024.txt");
+    aexp->vq1->offset = 0;
+    aexp->vq2 = load("../unittest/amp11_20_1024.txt");
+    aexp->vq2->offset = 10;
+
+    aexp->vq3 = load("../unittest/amp21_40_1024.txt");
+    aexp->vq3->offset = 20;
+    aexp->vq4 = load("../unittest/amp41_60_1024.txt");
+    aexp->vq4->offset = 40;
+    aexp->vq5 = load("../unittest/amp61_80_256.txt");
+    aexp->vq5->offset = 60;
+
+    #ifdef CAND2_GS
+    //aexp->vq1 = load("../unittest/t1_amp1_20_1024.txt");
+    //aexp->vq1 = load("../unittest/t2_amp1_20_1024.txt");
+    aexp->vq1 = load("../unittest/amp1_20_1024.txt");
+    aexp->vq1->offset = 0;
+    aexp->vq2 = load("../unittest/amp21_40_1024.txt");
+    aexp->vq2->offset = 20;
+    aexp->vq3 = load("../unittest/amp41_60_1024.txt");
+    aexp->vq3->offset = 40;
+    aexp->vq4 = load("../unittest/amp61_80_32.txt");
+    aexp->vq4->offset = 60;
+    #endif
+
+    //#define CAND2_GS
+    #ifdef CAND2_GS
+    aexp->vq1 = load("../unittest/amp1_20_1024.txt");
+    aexp->vq2 = load("../unittest/amp21_40_1024.txt");
+    aexp->vq3 = load("../unittest/amp41_80_1024.txt");
+    aexp->vq4 = load("../unittest/amp61_80_32.txt");
+    aexp->vq1->offset = 0;
+    aexp->vq2->offset = 20;
+    aexp->vq3->offset = 40;
+    aexp->vq4->offset = 60;
+    #endif
+
+    //#define CAND1
+    #ifdef CAND1
+    aexp->vq1 = load("../unittest/amp1_10_128.txt");
+    aexp->vq2 = load("../unittest/amp11_20_512.txt");
+    aexp->vq3 = load("../unittest/amp21_40_1024.txt");
+    aexp->vq4 = load("../unittest/amp41_60_1024.txt");
+    aexp->vq5 = load("../unittest/amp61_80_32.txt");
+    aexp->vq1->offset = 0;
+    aexp->vq2->offset = 10;
+    aexp->vq3->offset = 20;
+    aexp->vq4->offset = 40;
+    aexp->vq5->offset = 60;
+    #endif
+
+    for(i=0; i<3; i++) {
+       for(j=0; j<5; j++)
+           aexp->indexes[j][i] = 0;
+       aexp->mag[i] = 1.0;
+       aexp->model[i].Wo = TWO_PI*100.0/8000.0;
+       aexp->model[i].L = floor(PI/aexp->model[i].Wo);
+       for(m=1; m<=MAX_AMP; m++)
+           aexp->model[i].A[m] = 10.0;
+       aexp->model_uq[i] = aexp->model[i];
+    }
+
+    return aexp;
+}
+
+
+/*---------------------------------------------------------------------------* \
+
+  amp_experiment_destroy()
+
+\*---------------------------------------------------------------------------*/
+
+void amp_experiment_destroy(struct AEXP *aexp) {
+    assert(aexp != NULL);
+    if (aexp->snr != 0.0)
+       printf("snr: %4.2f dB\n", aexp->snr/aexp->snr_n);
+    if (aexp->var != 0.0)
+       printf("var...: %4.3f  std dev...: %4.3f (%d amplitude samples)\n",
+              aexp->var/aexp->var_n, sqrt(aexp->var/aexp->var_n), aexp->var_n);
+    if (aexp->vq_var != 0.0)
+       printf("vq var: %4.3f  std dev...: %4.3f (%d amplitude samples)\n",
+              aexp->vq_var/aexp->vq_var_n, sqrt(aexp->vq_var/aexp->vq_var_n), aexp->vq_var_n);
+    free(aexp);
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  Various test and experimental functions ................
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Quantisation noise simulation.  Assume noise on amplitudes is a uniform
+  distribution, of +/- x dB.  This means x = sqrt(3)*sigma.
+
+  Note: for uniform distribution var = = sigma * sigma = (b-a)*(b-a)/12.
+*/
+
+static void add_quant_noise(struct AEXP *aexp, MODEL *model, int start, int end, float sigma_dB)
+{
+    int   m;
+    float x_dB;
+    float noise_sam_dB;
+    float noise_sam_lin;
+
+    x_dB = sqrt(3.0) * sigma_dB;
+
+    for(m=start; m<=end; m++) {
+       noise_sam_dB = x_dB*(1.0 - 2.0*rand()/RAND_MAX);
+       //printf("%f\n", noise_sam_dB);
+       noise_sam_lin = pow(10.0, noise_sam_dB/20.0);
+       model->A[m] *= noise_sam_lin;
+       aexp->var += noise_sam_dB*noise_sam_dB;
+       aexp->var_n++;
+    }
+
+}
+
+/*
+  void print_sparse_pred_error()
+
+  use to check pred error stats (e.g. of first 1kHz) in Octave:
+
+     $ ./c2sim ../raw/hts1a.raw --ampexp > amppe.txt
+
+     octave> load ../src/amppe.txt
+     octave> std(nonzeros(amppe(:,1:20)))
+     octave> hist(nonzeros(amppe(:,1:20)),20);
+
+ */
+
+
+static float frame_energy(MODEL *model, float *enormdB) {
+    int   m;
+    float e, edB;
+
+    e = 0.0;
+    for(m=1; m<=model->L; m++)
+       e += model->A[m]*model->A[m];
+    edB = 10*log10(e);
+
+    #define VER_E0
+
+    #ifdef VER_E0
+    *enormdB = 10*log10(e/model->L); /* make high and low pitches have similar amps */
+    #endif
+
+    #ifdef VER_E1
+    e = 0.0;
+    for(m=1; m<=model->L; m++)
+       e += 10*log10(model->A[m]*model->A[m]);
+    *enormdB = e;
+    #endif
+
+    #ifdef VER_E2
+    e = 0.0;
+    for(m=1; m<=model->L; m++)
+       e += 10*log10(model->A[m]*model->A[m]);
+    *enormdB = e/model->L;
+    #endif
+    //printf("%f\n", enormdB);
+
+    return edB;
+}
+
+static void print_sparse_amp_error(struct AEXP *aexp, MODEL *model, float edB_thresh)
+{
+    int    m, index;
+    float  edB, enormdB, error, dWo;
+    float  sparse_pe[MAX_AMP];
+
+    edB = frame_energy(model, &enormdB);
+    //printf("%f\n", enormdB);
+    dWo = fabs((aexp->model_uq[2].Wo - aexp->model_uq[1].Wo)/aexp->model_uq[2].Wo);
+
+    if ((edB > edB_thresh) && (dWo < 0.1)) {
+       for(m=0; m<MAX_AMP; m++) {
+           sparse_pe[m] = 0.0;
+       }
+
+       for(m=1; m<=model->L; m++) {
+           assert(model->A[m] > 0.0);
+           error = 20.0*log10(model->A[m]) - enormdB;
+
+           index = MAX_AMP*m*model->Wo/PI;
+           assert(index < MAX_AMP);
+           sparse_pe[index] = error;
+       }
+
+       /* dump sparse amp vector */
+
+       for(m=0; m<MAX_AMP; m++)
+           printf("%f ", sparse_pe[m]);
+       printf("\n");
+    }
+}
+
+
+int vq_amp(float cb[], float vec[], float weights[], int d, int e, float *se)
+{
+   float   error;      /* current error                */
+   int     besti;      /* best index so far            */
+   float   best_error; /* best error so far            */
+   int    i,j;
+   float   diff, metric, best_metric;
+
+   besti = 0;
+   best_metric = best_error = 1E32;
+   for(j=0; j<e; j++) {
+       metric = error = 0.0;
+       for(i=0; i<d; i++) {
+          if (vec[i] != 0.0) {
+              diff = (cb[j*d+i] - vec[i]);
+              error += diff*diff;
+              metric += weights[i]*diff*diff;
+          }
+       }
+       if (metric < best_metric) {
+          best_error = error;
+          best_metric = metric;
+          besti = j;
+       }
+   }
+
+   *se += best_error;
+
+   return(besti);
+}
+
+
+static int split_vq(float sparse_pe_out[], struct AEXP *aexp, struct codebook *vq, float weights[], float sparse_pe_in[])
+{
+    int i, j, non_zero, vq_ind;
+    float se;
+
+    vq_ind = vq_amp(vq->cb, &sparse_pe_in[vq->offset], &weights[vq->offset], vq->k, vq->m, &se);
+    printf("\n offset %d k %d m %d vq_ind %d j: ", vq->offset, vq->k, vq->m, vq_ind);
+
+    non_zero = 0;
+    for(i=0, j=vq->offset; i<vq->k; i++,j++) {
+       if (sparse_pe_in[j] != 0.0) {
+           printf("%d ", j);
+           sparse_pe_in[j]  -= vq->cb[vq->k * vq_ind + i];
+           sparse_pe_out[j] += vq->cb[vq->k * vq_ind + i];
+           non_zero++;
+       }
+    }
+    aexp->vq_var_n += non_zero;
+    return vq_ind;
+}
+
+#if 0
+static void print_sparse_pred_error(struct AEXP *aexp, MODEL *model, float mag_thresh)
+{
+    int    m, index;
+    float  mag, error;
+    float  sparse_pe[MAX_AMP];
+
+    mag = 0.0;
+    for(m=1; m<=model->L; m++)
+       mag += model->A[m]*model->A[m];
+    mag = 10*log10(mag/model->L);
+
+    if (mag > mag_thresh) {
+       for(m=0; m<MAX_AMP; m++) {
+           sparse_pe[m] = 0.0;
+       }
+
+       for(m=1; m<=model->L; m++) {
+           assert(model->A[m] > 0.0);
+           error = PRED_COEFF*20.0*log10(aexp->A_prev[m]) - 20.0*log10(model->A[m]);
+           //error = 20.0*log10(model->A[m]) - mag;
+
+           index = MAX_AMP*m*model->Wo/PI;
+           assert(index < MAX_AMP);
+           sparse_pe[index] = error;
+       }
+
+       /* dump sparse amp vector */
+
+       for(m=0; m<MAX_AMP; m++)
+           printf("%f ", sparse_pe[m]);
+       printf("\n");
+    }
+}
+
+
+static void sparse_vq_pred_error(struct AEXP *aexp,
+                                MODEL       *model
+)
+{
+    int    m, index;
+    float  error, amp_dB, edB, enormdB;
+    float  sparse_pe_in[MAX_AMP];
+    float  sparse_pe_out[MAX_AMP];
+    float  weights[MAX_AMP];
+
+    edB = frame_energy(model, &enormdB);
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_in[m] = 0.0;
+       sparse_pe_out[m] = 0.0;
+    }
+
+    for(m=1; m<=model->L; m++) {
+       assert(model->A[m] > 0.0);
+       error = PRED_COEFF*20.0*log10(aexp->A_prev[m]) - 20.0*log10(model->A[m]);
+
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       sparse_pe_in[index] = error;
+       weights[index] = model->A[m];
+    }
+
+    /* vector quantise */
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_out[m] = sparse_pe_in[m];
+    }
+
+    //#define SIM_VQ
+    #ifndef SIM_VQ
+    split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in);
+    #else
+    for(m=aexp->vq->offset; m<aexp->vq->offset+aexp->vq->k; m++) {
+       if (sparse_pe_in[m] != 0.0) {
+           float error = 8*(1.0 - 2.0*rand()/RAND_MAX);
+           aexp->vq_var += error*error;
+           aexp->vq_var_n++;
+           sparse_pe_out[m] = sparse_pe_in[m] + error;
+       }
+    }
+    #endif
+
+    if (edB > -100.0)
+       for(m=0; m<MAX_AMP; m++) {
+           if (sparse_pe_in[m] != 0.0)
+               aexp->vq_var += pow(sparse_pe_out[m] - sparse_pe_in[m], 2.0);
+       }
+
+    /* transform quantised amps back */
+
+    for(m=1; m<=model->L; m++) {
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       amp_dB = PRED_COEFF*20.0*log10(aexp->A_prev[m]) - sparse_pe_out[index];
+       //printf("in: %f  out: %f\n", sparse_pe_in[index], sparse_pe_out[index]);
+       //printf("amp_dB: %f A[m] (dB) %f\n", amp_dB, 20.0*log10(model->A[m]));
+       model->A[m] = pow(10.0, amp_dB/20.0);
+    }
+    //exit(0);
+}
+
+
+static void split_error(struct AEXP *aexp, struct codebook *vq, float sparse_pe_in[], int ind)
+{
+    int i, j;
+
+    for(i=0, j=vq->offset; i<vq->k; i++,j++) {
+       if (sparse_pe_in[j] != 0.0) {
+           sparse_pe_in[j] -= vq->cb[vq->k * ind + i];
+       }
+    }
+}
+
+#endif
+static void sparse_vq_amp(struct AEXP *aexp, MODEL *model)
+{
+    int    m, index;
+    float  error, amp_dB, enormdB;
+    float  sparse_pe_in[MAX_AMP];
+    float  sparse_pe_out[MAX_AMP];
+    float  weights[MAX_AMP];
+
+    frame_energy(model, &enormdB);
+
+    aexp->mag[2] = enormdB;
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_in[m] = 0.0;
+       sparse_pe_out[m] = 0.0;
+    }
+
+    for(m=1; m<=model->L; m++) {
+       assert(model->A[m] > 0.0);
+       error = 20.0*log10(model->A[m]) - enormdB;
+
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       sparse_pe_in[index] = error;
+       weights[index] = pow(model->A[m],0.8);
+    }
+
+    /* vector quantise */
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_out[m] = sparse_pe_in[m];
+    }
+
+    for(m=0; m<80; m++)
+       sparse_pe_out[m] = 0;
+
+    #define SPLIT
+    #ifdef SPLIT
+    aexp->indexes[0][2] = split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in);
+
+    aexp->indexes[1][2] = split_vq(sparse_pe_out, aexp, aexp->vq2, weights, sparse_pe_in);
+    aexp->indexes[2][2] = split_vq(sparse_pe_out, aexp, aexp->vq3, weights, sparse_pe_in);
+    aexp->indexes[3][2] = split_vq(sparse_pe_out, aexp, aexp->vq4, weights, sparse_pe_in);
+    aexp->indexes[4][2] = split_vq(sparse_pe_out, aexp, aexp->vq5, weights, sparse_pe_in);
+    #endif
+    //#define MULTISTAGE
+    #ifdef MULTISTAGE
+    aexp->indexes[0][2] = split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in);
+    aexp->indexes[1][2] = split_vq(sparse_pe_out, aexp, aexp->vq2, weights, sparse_pe_in);
+    aexp->indexes[2][2] = split_vq(sparse_pe_out, aexp, aexp->vq3, weights, sparse_pe_in);
+    //aexp->indexes[3][2] = split_vq(sparse_pe_out, aexp, aexp->vq4, weights, sparse_pe_in);
+    #endif
+
+    for(m=0; m<MAX_AMP; m++) {
+       if (sparse_pe_in[m] != 0.0)
+           aexp->vq_var += pow(sparse_pe_out[m] - sparse_pe_in[m], 2.0);
+    }
+
+    /* transform quantised amps back */
+
+    for(m=1; m<=model->L; m++) {
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       amp_dB = sparse_pe_out[index] + enormdB;
+       model->A[m] = pow(10.0, amp_dB/20.0);
+    }
+    //exit(0);
+}
+
+
+static void update_snr_calc(struct AEXP *aexp, MODEL *m1, MODEL *m2)
+{
+    int m;
+    float signal, noise, signal_dB;
+
+    assert(m1->L == m2->L);
+
+    signal = 0.0; noise = 1E-32;
+    for(m=1; m<=m1->L; m++) {
+       signal += m1->A[m]*m1->A[m];
+       noise  += pow(m1->A[m] - m2->A[m], 2.0);
+       //printf("%f %f\n", before[m], model->phi[m]);
+    }
+    signal_dB = 10*log10(signal);
+    if (signal_dB > -100.0) {
+       aexp->snr += 10.0*log10(signal/noise);
+       aexp->snr_n++;
+    }
+}
+
+
+/* gain/shape vq search.  Returns index of best gain.  Gain is additive (as we use log quantisers) */
+
+int gain_shape_vq_amp(float cb[], float vec[], float weights[], int d, int e, float *se, float *best_gain)
+{
+   float   error;      /* current error                */
+   int     besti;      /* best index so far            */
+   float   best_error; /* best error so far            */
+   int    i,j,m;
+   float   diff, metric, best_metric, gain, sumAm, sumCb;
+
+   besti = 0;
+   best_metric = best_error = 1E32;
+   for(j=0; j<e; j++) {
+
+       /* compute optimum gain */
+
+       sumAm = sumCb = 0.0;
+       m = 0;
+       for(i=0; i<d; i++) {
+          if (vec[i] != 0.0) {
+              m++;
+              sumAm += vec[i];
+              sumCb += cb[j*d+i];
+          }
+       }
+       gain = (sumAm - sumCb)/m;
+
+       /* compute error */
+
+       metric = error = 0.0;
+       for(i=0; i<d; i++) {
+          if (vec[i] != 0.0) {
+              diff = vec[i] - cb[j*d+i] - gain;
+              error += diff*diff;
+              metric += weights[i]*diff*diff;
+          }
+       }
+       if (metric < best_metric) {
+          best_error = error;
+          best_metric = metric;
+          *best_gain = gain;
+          besti = j;
+       }
+   }
+
+   *se += best_error;
+
+   return(besti);
+}
+
+
+static void gain_shape_split_vq(float sparse_pe_out[], struct AEXP *aexp, struct codebook *vq, float weights[], float sparse_pe_in[], float *best_gain)
+{
+    int i, j, non_zero, vq_ind;
+    float se;
+
+    vq_ind = gain_shape_vq_amp(vq->cb, &sparse_pe_in[vq->offset], &weights[vq->offset], vq->k, vq->m, &se, best_gain);
+    //printf("\n offset %d k %d m %d vq_ind %d gain: %4.2f j: ", vq->offset, vq->k, vq->m, vq_ind, *best_gain);
+
+    non_zero = 0;
+    for(i=0, j=vq->offset; i<vq->k; i++,j++) {
+       if (sparse_pe_in[j] != 0.0) {
+           //printf("%d ", j);
+           sparse_pe_out[j] = vq->cb[vq->k * vq_ind + i] + *best_gain;
+           non_zero++;
+       }
+    }
+    aexp->vq_var_n += non_zero;
+}
+
+
+static void gain_shape_sparse_vq_amp(struct AEXP *aexp, MODEL *model)
+{
+    int    m, index;
+    float  amp_dB, best_gain;
+    float  sparse_pe_in[MAX_AMP];
+    float  sparse_pe_out[MAX_AMP];
+    float  weights[MAX_AMP];
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_in[m] = 0.0;
+       sparse_pe_out[m] = 0.0;
+    }
+
+    for(m=1; m<=model->L; m++) {
+       assert(model->A[m] > 0.0);
+
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       sparse_pe_in[index] = 20.0*log10(model->A[m]);
+       weights[index] = model->A[m];
+    }
+
+    /* vector quantise */
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_out[m] = sparse_pe_in[m];
+    }
+
+    gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq1, weights, sparse_pe_in, &best_gain);
+    gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq2, weights, sparse_pe_in, &best_gain);
+    gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq3, weights, sparse_pe_in, &best_gain);
+    gain_shape_split_vq(sparse_pe_out, aexp, aexp->vq4, weights, sparse_pe_in, &best_gain);
+
+    for(m=0; m<MAX_AMP; m++) {
+       if (sparse_pe_in[m] != 0.0)
+           aexp->vq_var += pow(sparse_pe_out[m] - sparse_pe_in[m], 2.0);
+    }
+
+    /* transform quantised amps back */
+
+    for(m=1; m<=model->L; m++) {
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       amp_dB = sparse_pe_out[index];
+       model->A[m] = pow(10.0, amp_dB/20.0);
+    }
+    //exit(0);
+}
+
+
+static void interp_split_vq(float sparse_pe_out[], struct AEXP *aexp, struct codebook *vq, float sparse_pe_in[], int ind)
+{
+    int   i, j;
+    float amp_dB;
+
+    for(i=0, j=vq->offset; i<vq->k; i++,j++) {
+       if (sparse_pe_in[j] != 0.0) {
+           amp_dB  = 0.5*(aexp->mag[0] + vq->cb[vq->k * aexp->indexes[ind][0] + i]);
+           amp_dB += 0.5*(aexp->mag[2] + vq->cb[vq->k * aexp->indexes[ind][2] + i]);
+           sparse_pe_out[j] = amp_dB;
+       }
+    }
+}
+
+
+static void vq_interp(struct AEXP *aexp, MODEL *model, int on)
+{
+    int              i, j, m, index;
+    float            amp_dB;
+    //struct codebook *vq = aexp->vq1;
+    float  sparse_pe_in[MAX_AMP];
+    float  sparse_pe_out[MAX_AMP];
+
+    /* replace odd frames with interp */
+    /* once we get an even input frame we can interpolate and output odd */
+    /* using VQ to interpolate.  This assumes some correlation in
+       adjacent VQ samples */
+
+    memcpy(&aexp->model[2], model, sizeof(MODEL));
+
+    /* once we get an even input frame we have enough information to
+      replace prev odd frame with interpolated version */
+
+    if (on && ((aexp->frames % 2) == 0)) {
+
+       /* copy Wo, L, and phases */
+
+       memcpy(model, &aexp->model[1], sizeof(MODEL));
+       //printf("mags: %4.2f %4.2f %4.2f Am: \n", aexp->mag[0], aexp->mag[1], aexp->mag[2]);
+
+       /* now replace Am by interpolation, use similar design to VQ
+          to handle different bands  */
+
+       for(m=1; m<=model->L; m++) {
+           assert(model->A[m] > 0.0);
+
+           index = MAX_AMP*m*model->Wo/PI;
+           assert(index < MAX_AMP);
+           sparse_pe_in[index] = 20.0*log10(model->A[m]);
+       }
+
+       /* this can be used for when just testing partial interpolation */
+
+       for(m=0; m<MAX_AMP; m++) {
+           //sparse_pe_out[m] = sparse_pe_in[m];
+           sparse_pe_out[m] = 0;
+       }
+
+       interp_split_vq(sparse_pe_out, aexp, aexp->vq1, sparse_pe_in, 0);
+       interp_split_vq(sparse_pe_out, aexp, aexp->vq2, sparse_pe_in, 1);
+       interp_split_vq(sparse_pe_out, aexp, aexp->vq3, sparse_pe_in, 2);
+       interp_split_vq(sparse_pe_out, aexp, aexp->vq4, sparse_pe_in, 3);
+       interp_split_vq(sparse_pe_out, aexp, aexp->vq5, sparse_pe_in, 4);
+
+       for(m=1; m<=model->L; m++) {
+           index = MAX_AMP*m*model->Wo/PI;
+           assert(index < MAX_AMP);
+           amp_dB = sparse_pe_out[index];
+           //printf("  %4.2f", 10.0*log10(model->A[m]));
+           model->A[m] = pow(10.0, amp_dB/20.0);
+           //printf("  %4.2f\n", 10.0*log10(model->A[m]));
+       }
+
+        #ifdef INITIAL_VER
+
+       for(m=1; m<=model->L; m++) {
+           index = MAX_AMP*m*model->Wo/PI;
+           assert(index < MAX_AMP);
+
+           if (index < vq->k) {
+               amp_dB  = 0.5*(aexp->mag[0] + vq->cb[vq->k * aexp->indexes[0] + index]);
+               amp_dB += 0.5*(aexp->mag[2] + vq->cb[vq->k * aexp->indexes[2] + index]);
+               //printf("  %4.2f", 10.0*log10(model->A[m]));
+               //amp_dB = 10;
+               model->A[m] = pow(10.0, amp_dB/20.0);
+               printf("  %4.2f\n", 10.0*log10(model->A[m]));
+           }
+       }
+
+       #endif
+    }
+    else
+       memcpy(model, &aexp->model[1], sizeof(MODEL));
+
+    /* update memories */
+
+    for(i=0; i<2; i++) {
+       memcpy(&aexp->model[i], &aexp->model[i+1], sizeof(MODEL));
+       for(j=0; j<5; j++)
+           aexp->indexes[j][i] = aexp->indexes[j][i+1];
+       aexp->mag[i] = aexp->mag[i+1];
+    }
+
+}
+
+
+/*
+  This functions tests theory that some bands can be combined together
+  due to less frequency resolution at higher frequencies.  This will
+  reduce the amount of information we need to encode.
+*/
+
+void smooth_samples(struct AEXP *aexp, MODEL *model, int mode)
+{
+    int    m, i, j, index, step, nav, v, en;
+    float  sparse_pe_in[MAX_AMP], av, amp_dB;
+    float  sparse_pe_out[MAX_AMP];
+    float  smoothed[MAX_AMP], smoothed_out[MAX_AMP];
+    float  weights[MAX_AMP];
+    float  enormdB;
+
+    frame_energy(model, &enormdB);
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_in[m] = 0.0;
+       sparse_pe_out[m] = 0.0;
+    }
+
+    /* set up sparse array */
+
+    for(m=1; m<=model->L; m++) {
+       assert(model->A[m] > 0.0);
+
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       sparse_pe_out[index] = sparse_pe_in[index] = 20.0*log10(model->A[m]) - enormdB;
+    }
+
+    /* now combine samples at high frequencies to reduce dimension */
+
+    step=4;
+    for(i=MAX_AMP/2,v=0; i<MAX_AMP; i+=step,v++) {
+
+       /* average over one band */
+
+       av = 0.0; nav = 0;
+       en = i+step;
+       if (en > (MAX_AMP-1))
+           en = MAX_AMP-1;
+       for(j=i; j<en; j++) {
+           if (sparse_pe_in[j] != 0.0) {
+               av += sparse_pe_in[j];
+               nav++;
+           }
+       }
+       if (nav) {
+           av /= nav;
+           smoothed[v] = av;
+           weights[v] = pow(10.0,av/20.0);
+           //weights[v] = 1.0;
+       }
+       else
+           smoothed[v] = 0.0;
+
+    }
+
+    if (mode == 1) {
+       for(i=0; i<v; i++)
+           printf("%5.2f ", smoothed[i]);
+       printf("\n");
+    }
+
+    if (mode == 2) {
+       for(i=0; i<v; i++)
+           smoothed_out[i] = 0;
+       split_vq(smoothed_out, aexp, aexp->vq1, weights, smoothed);
+       for(i=0; i<v; i++)
+           smoothed[i] = smoothed_out[i];
+    }
+
+    /* set all samples to smoothed average */
+
+    step = 4;
+    for(i=MAX_AMP/2,v=0; i<MAX_AMP; i+=step,v++) {
+       en = i+step;
+       if (en > (MAX_AMP-1))
+           en = MAX_AMP-1;
+       for(j=i; j<en; j++)
+           sparse_pe_out[j] = smoothed[v];
+    }
+
+    /* convert back to Am */
+
+    for(m=1; m<=model->L; m++) {
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       amp_dB = sparse_pe_out[index] + enormdB;
+       //printf("%d %4.2f %4.2f\n", m, 10.0*log10(model->A[m]), amp_dB);
+       model->A[m] = pow(10.0, amp_dB/20.0);
+    }
+
+}
+
+#define MAX_BINS 40
+static float bins[] = {
+    /*1000.0, 1200.0, 1400.0, 1600.0, 1800,*/
+    2000.0, 2400.0, 2800.0,
+    3000.0, 3400.0, 3600.0, 4000.0};
+
+void smooth_amp(struct AEXP *aexp, MODEL *model) {
+    int    m, i;
+    int    nbins;
+    int    b;
+    float  f;
+    float  av[MAX_BINS];
+    int    nav[MAX_BINS];
+
+    nbins = sizeof(bins)/sizeof(float);
+
+    /* clear all bins */
+
+    for(i=0; i<MAX_BINS; i++) {
+       av[i] = 0.0;
+       nav[i] = 0;
+    }
+
+    /* add amps into each bin */
+
+    for(m=1; m<=model->L; m++) {
+       f = m*model->Wo*FS/TWO_PI;
+       if (f > bins[0]) {
+
+           /* find bin  */
+
+           b = MAX_BINS;
+           for(i=0; i<nbins; i++)
+               if ((f > bins[i]) && (f <= bins[i+1]))
+                   b = i;
+           assert(b < MAX_BINS);
+
+           av[b] += model->A[m]*model->A[m];
+           nav[b]++;
+       }
+
+    }
+
+    /* use averages to est amps */
+
+    for(m=1; m<=model->L; m++) {
+       f = m*model->Wo*FS/TWO_PI;
+       if (f > bins[0]) {
+
+           /* find bin */
+
+           b = MAX_BINS;
+           for(i=0; i<nbins; i++)
+               if ((f > bins[i]) && (f <= bins[i+1]))
+                   b = i;
+           assert(b < MAX_BINS);
+
+           /* add predicted phase error to this bin */
+
+           printf("L %d m %d f %4.f b %d\n", model->L, m, f, b);
+
+           printf(" %d: %4.3f -> ", m, 20*log10(model->A[m]));
+           model->A[m] = sqrt(av[b]/nav[b]);
+           printf("%4.3f\n", 20*log10(model->A[m]));
+       }
+    }
+    printf("\n");
+}
+
+/*---------------------------------------------------------------------------* \
+
+  amp_experiment()
+
+  Amplitude quantisation experiments.
+
+\*---------------------------------------------------------------------------*/
+
+void amp_experiment(struct AEXP *aexp, MODEL *model, char *arg) {
+    int m,i;
+
+    memcpy(&aexp->model_uq[2], model, sizeof(MODEL));
+
+    if (strcmp(arg, "qn") == 0) {
+       add_quant_noise(aexp, model, 1, model->L, 1);
+       update_snr_calc(aexp, &aexp->model_uq[2], model);
+   }
+
+    /* print training samples that can be > train.txt for training VQ */
+
+    if (strcmp(arg, "train") == 0)
+       print_sparse_amp_error(aexp, model, 00.0);
+
+    /* VQ of amplitudes, no interpolation (ie 10ms rate) */
+
+    if (strcmp(arg, "vq") == 0) {
+       sparse_vq_amp(aexp, model);
+       vq_interp(aexp, model, 0);
+       update_snr_calc(aexp, &aexp->model_uq[1], model);
+    }
+
+    /* VQ of amplitudes, interpolation (ie 20ms rate) */
+
+    if (strcmp(arg, "vqi") == 0) {
+       sparse_vq_amp(aexp, model);
+       vq_interp(aexp, model, 1);
+       update_snr_calc(aexp, &aexp->model_uq[1], model);
+    }
+
+    /* gain/shape VQ of amplitudes, 10ms rate (doesn't work that well) */
+
+    if (strcmp(arg, "gsvq") == 0) {
+       gain_shape_sparse_vq_amp(aexp, model);
+       vq_interp(aexp, model, 0);
+       update_snr_calc(aexp, &aexp->model_uq[1], model);
+    }
+
+    if (strcmp(arg, "smooth") == 0) {
+       smooth_samples(aexp, model, 0);
+       update_snr_calc(aexp, &aexp->model_uq[2], model);
+    }
+
+    if (strcmp(arg, "smoothtrain") == 0) {
+       smooth_samples(aexp, model, 1);
+       //update_snr_calc(aexp, &aexp->model_uq[2], model);
+    }
+
+    if (strcmp(arg, "smoothvq") == 0) {
+       smooth_samples(aexp, model, 2);
+       update_snr_calc(aexp, &aexp->model_uq[2], model);
+    }
+
+    if (strcmp(arg, "smoothamp") == 0) {
+       smooth_amp(aexp, model);
+       update_snr_calc(aexp, &aexp->model_uq[2], model);
+    }
+
+    /* update states */
+
+    for(m=1; m<=model->L; m++)
+       aexp->A_prev[m] = model->A[m];
+    aexp->frames++;
+    for(i=0; i<3; i++)
+       aexp->model_uq[i] = aexp->model_uq[i+1];
+}
+
diff --git a/codec2/branches/0.7/src/ampexp.h b/codec2/branches/0.7/src/ampexp.h
new file mode 100644 (file)
index 0000000..8954ea2
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: ampexp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: & August 2012
+
+  Functions for experimenting with amplitude quantisation.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not,see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __AMPEX__
+#define __AMPEXP__
+
+#include "defines.h"
+
+struct AEXP;
+
+struct AEXP *amp_experiment_create();
+void amp_experiment_destroy(struct AEXP *aexp);
+void amp_experiment(struct AEXP *aexp, MODEL *model, char *arg);
+
+#endif
diff --git a/codec2/branches/0.7/src/bpf.h b/codec2/branches/0.7/src/bpf.h
new file mode 100644 (file)
index 0000000..0b0a6e2
--- /dev/null
@@ -0,0 +1,106 @@
+#define BPF_N 101
+
+float bpf[]={
+  0.002174,
+  0.003245,
+  0.002147,
+  0.001866,
+  0.002764,
+  0.000567,
+  -0.001641,
+  -0.000565,
+  -0.002415,
+  -0.005837,
+  -0.003620,
+  -0.002828,
+  -0.006268,
+  -0.002787,
+  0.001963,
+  -0.001234,
+  0.001446,
+  0.009200,
+  0.005331,
+  0.003521,
+  0.011821,
+  0.006951,
+  -0.002015,
+  0.005137,
+  0.001828,
+  -0.013390,
+  -0.007058,
+  -0.003273,
+  -0.020458,
+  -0.014321,
+  0.001751,
+  -0.012891,
+  -0.009730,
+  0.018993,
+  0.008544,
+  0.000534,
+  0.035755,
+  0.029074,
+  -0.001192,
+  0.030852,
+  0.030983,
+  -0.029834,
+  -0.009550,
+  0.011945,
+  -0.081971,
+  -0.082875,
+  0.000423,
+  -0.133526,
+  -0.211778,
+  0.182628,
+  0.514906,
+  0.182628,
+  -0.211778,
+  -0.133526,
+  0.000423,
+  -0.082875,
+  -0.081971,
+  0.011945,
+  -0.009550,
+  -0.029834,
+  0.030983,
+  0.030852,
+  -0.001192,
+  0.029074,
+  0.035755,
+  0.000534,
+  0.008544,
+  0.018993,
+  -0.009730,
+  -0.012891,
+  0.001751,
+  -0.014321,
+  -0.020458,
+  -0.003273,
+  -0.007058,
+  -0.013390,
+  0.001828,
+  0.005137,
+  -0.002015,
+  0.006951,
+  0.011821,
+  0.003521,
+  0.005331,
+  0.009200,
+  0.001446,
+  -0.001234,
+  0.001963,
+  -0.002787,
+  -0.006268,
+  -0.002828,
+  -0.003620,
+  -0.005837,
+  -0.002415,
+  -0.000565,
+  -0.001641,
+  0.000567,
+  0.002764,
+  0.001866,
+  0.002147,
+  0.003245,
+  0.002174
+};
+
diff --git a/codec2/branches/0.7/src/bpfb.h b/codec2/branches/0.7/src/bpfb.h
new file mode 100644 (file)
index 0000000..73b1a69
--- /dev/null
@@ -0,0 +1,105 @@
+#define BPFB_N 101
+
+float bpfb[]={
+  0.003795,
+  0.006827,
+  0.002261,
+  0.002523,
+  0.005758,
+  -0.000264,
+  -0.000674,
+  0.003113,
+  -0.004144,
+  -0.004923,
+  0.000043,
+  -0.008017,
+  -0.008711,
+  -0.001802,
+  -0.010210,
+  -0.010428,
+  -0.000899,
+  -0.009413,
+  -0.009072,
+  0.003469,
+  -0.005335,
+  -0.004828,
+  0.010724,
+  0.000941,
+  0.000708,
+  0.018957,
+  0.007084,
+  0.004825,
+  0.025418,
+  0.010147,
+  0.004452,
+  0.027434,
+  0.007550,
+  -0.002861,
+  0.023483,
+  -0.001944,
+  -0.018138,
+  0.014122,
+  -0.017583,
+  -0.040768,
+  0.002598,
+  -0.036604,
+  -0.069541,
+  -0.004273,
+  -0.054876,
+  -0.107289,
+  0.010068,
+  -0.068052,
+  -0.200119,
+  0.207287,
+  0.597150,
+  0.207287,
+  -0.200119,
+  -0.068052,
+  0.010068,
+  -0.107289,
+  -0.054876,
+  -0.004273,
+  -0.069541,
+  -0.036604,
+  0.002598,
+  -0.040768,
+  -0.017583,
+  0.014122,
+  -0.018138,
+  -0.001944,
+  0.023483,
+  -0.002861,
+  0.007550,
+  0.027434,
+  0.004452,
+  0.010147,
+  0.025418,
+  0.004825,
+  0.007084,
+  0.018957,
+  0.000708,
+  0.000941,
+  0.010724,
+  -0.004828,
+  -0.005335,
+  0.003469,
+  -0.009072,
+  -0.009413,
+  -0.000899,
+  -0.010428,
+  -0.010210,
+  -0.001802,
+  -0.008711,
+  -0.008017,
+  0.000043,
+  -0.004923,
+  -0.004144,
+  0.003113,
+  -0.000674,
+  -0.000264,
+  0.005758,
+  0.002523,
+  0.002261,
+  0.006827,
+  0.003795
+};
\ No newline at end of file
diff --git a/codec2/branches/0.7/src/c2dec.c b/codec2/branches/0.7/src/c2dec.c
new file mode 100644 (file)
index 0000000..57f0815
--- /dev/null
@@ -0,0 +1,344 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: c2dec.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/8/2010
+
+  Decodes a file of bits to a file of raw speech samples using codec2.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+#include "dump.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <getopt.h>
+
+#define NONE          0  /* no bit errors                          */
+#define UNIFORM       1  /* random bit errors                      */
+#define TWO_STATE     2  /* Two state error model                  */
+#define UNIFORM_RANGE 3  /* random bit errors over a certain range */
+
+void print_help(const struct option *long_options, int num_opts, char* argv[]);
+
+int main(int argc, char *argv[])
+{
+    int            mode;
+    void          *codec2;
+    FILE          *fin;
+    FILE          *fout;
+    FILE          *fber = NULL;
+    short         *buf;
+    unsigned char *bits;
+    float         *softdec_bits;
+    int            nsam, nbit, nbyte, i, byte, frames, bits_proc, bit_errors, error_mode;
+    int            nstart_bit, nend_bit, bit_rate;
+    int            state, next_state;
+    float          ber, r, burst_length, burst_period, burst_timer, ber_est;
+    unsigned char  mask;
+    int            natural, softdec, bit, ret;
+#ifdef DUMP
+    int dump;
+#endif
+    int            report_energy;
+
+    char* opt_string = "h:";
+    struct option long_options[] = {
+        { "ber", required_argument, NULL, 0 },
+        { "startbit", required_argument, NULL, 0 },
+        { "endbit", required_argument, NULL, 0 },
+        { "berfile", required_argument, NULL, 0 },
+        { "natural", no_argument, &natural, 1 },
+        { "softdec", no_argument, &softdec, 1 },
+        #ifdef DUMP
+        { "dump", required_argument, &dump, 1 },
+        #endif
+       { "energy", no_argument, NULL, 0 },
+        { "help", no_argument, NULL, 'h' },
+        { NULL, no_argument, NULL, 0 }
+    };
+    int num_opts=sizeof(long_options)/sizeof(struct option);
+
+    if (argc < 4)
+        print_help(long_options, num_opts, argv);
+
+    if (strcmp(argv[1],"3200") == 0)
+       mode = CODEC2_MODE_3200;
+    else if (strcmp(argv[1],"2400") == 0)
+       mode = CODEC2_MODE_2400;
+    else if (strcmp(argv[1],"1600") == 0)
+       mode = CODEC2_MODE_1600;
+    else if (strcmp(argv[1],"1400") == 0)
+       mode = CODEC2_MODE_1400;
+    else if (strcmp(argv[1],"1300") == 0)
+       mode = CODEC2_MODE_1300;
+    else if (strcmp(argv[1],"1200") == 0)
+       mode = CODEC2_MODE_1200;
+    else if (strcmp(argv[1],"700") == 0)
+       mode = CODEC2_MODE_700;
+    else if (strcmp(argv[1],"700B") == 0)
+       mode = CODEC2_MODE_700B;
+     else if (strcmp(argv[1],"700C") == 0)
+       mode = CODEC2_MODE_700C;
+   else {
+       fprintf(stderr, "Error in mode: %s.  Must be 3200, 2400, 1600, 1400, 1300, 1200, 700, 700B or 700C\n", argv[1]);
+       exit(1);
+    }
+    bit_rate = atoi(argv[1]);
+
+    if (strcmp(argv[2], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[2],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input bit file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[3], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[3],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output speech file: %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    error_mode = NONE;
+    ber = 0.0;
+    burst_length = burst_period = 0.0;
+    burst_timer = 0.0;
+    natural = softdec = 0;
+    report_energy = 0;
+#ifdef DUMP
+    dump = 0;
+#endif
+
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    nbit = codec2_bits_per_frame(codec2);
+    buf = (short*)malloc(nsam*sizeof(short));
+    nbyte = (nbit + 7) / 8;
+    bits = (unsigned char*)malloc(nbyte*sizeof(char));
+    softdec_bits = (float*)malloc(nbit*sizeof(float));
+    frames = bit_errors = bits_proc = 0;
+    nstart_bit = 0;
+    nend_bit = nbit-1;
+
+    while(1) {
+        int option_index = 0;
+        int opt = getopt_long(argc, argv, opt_string,
+                    long_options, &option_index);
+        if (opt == -1)
+            break;
+
+        switch (opt) {
+        case 0:
+            if(strcmp(long_options[option_index].name, "ber") == 0) {
+                ber = atof(optarg);
+                error_mode = UNIFORM;
+            } else if(strcmp(long_options[option_index].name, "startbit") == 0) {
+               nstart_bit = atoi(optarg);
+            } else if(strcmp(long_options[option_index].name, "endbit") == 0) {
+               nend_bit = atoi(optarg);
+            } else if(strcmp(long_options[option_index].name, "berfile") == 0) {
+               if ((fber = fopen(optarg,"wt")) == NULL) {
+                   fprintf(stderr, "Error opening BER file: %s %s.\n",
+                            optarg, strerror(errno));
+                    exit(1);
+                }
+
+            }
+            #ifdef DUMP
+            else if(strcmp(long_options[option_index].name, "dump") == 0) {
+                if (dump)
+                   dump_on(optarg);
+            }
+            #endif
+           else if (strcmp(long_options[option_index].name, "energy") == 0) {
+               report_energy = 1;
+           }
+            break;
+
+        case 'h':
+            print_help(long_options, num_opts, argv);
+            break;
+
+        default:
+            /* This will never be reached */
+            break;
+        }
+    }
+    assert(nend_bit <= nbit);
+    codec2_set_natural_or_gray(codec2, !natural);
+    //printf("%d %d\n", nstart_bit, nend_bit);
+
+    //fprintf(stderr, "softdec: %d natural: %d\n", softdec, natural);
+    if (softdec)
+        ret = (fread(softdec_bits, sizeof(float), nbit, fin) == (size_t)nbit);
+    else
+        ret = (fread(bits, sizeof(char), nbyte, fin) == (size_t)nbyte);
+
+    while(ret) {
+       frames++;
+
+        // apply bit errors, MSB of byte 0 is bit 0 in frame, only works in packed mode
+
+       if ((error_mode == UNIFORM) || (error_mode == UNIFORM_RANGE)) {
+            assert(softdec == 0);
+           for(i=nstart_bit; i<nend_bit+1; i++) {
+               r = (float)rand()/RAND_MAX;
+               if (r < ber) {
+                   byte = i/8;
+                   //printf("nbyte %d nbit %d i %d byte %d bits[%d] 0x%0x ", nbyte, nbit, i, byte, byte, bits[byte]);
+                   mask = 1 << (7 - i + byte*8);
+                    bits[byte] ^= mask;
+                   //printf("shift: %d mask: 0x%0x bits[%d] 0x%0x\n", 7 - i + byte*8, mask, byte, bits[byte] );
+                   bit_errors++;
+               }
+                bits_proc++;
+           }
+       }
+
+       if (error_mode == TWO_STATE) {
+            assert(softdec == 0);
+            burst_timer += (float)nbit/bit_rate;
+            fprintf(stderr, "burst_timer: %f  state: %d\n", burst_timer, state);
+
+            next_state = state;
+            switch(state) {
+            case 0:
+
+                /* clear channel state - no bit errors */
+
+                if (burst_timer > (burst_period - burst_length))
+                    next_state = 1;
+                break;
+
+            case 1:
+
+                /* burst error state - 50% bit error rate */
+
+                for(i=nstart_bit; i<nend_bit+1; i++) {
+                    r = (float)rand()/RAND_MAX;
+                    if (r < 0.5) {
+                        byte = i/8;
+                        bits[byte] ^= 1 << (7 - i + byte*8);
+                        bit_errors++;
+                    }
+                    bits_proc++;
+               }
+
+                if (burst_timer > burst_period) {
+                    burst_timer = 0.0;
+                    next_state = 0;
+                }
+                break;
+
+           }
+
+            state = next_state;
+        }
+
+        if (fber != NULL) {
+            if (fread(&ber_est, sizeof(float), 1, fber) != 1) {
+                fprintf(stderr, "ran out of BER estimates!\n");
+                exit(1);
+            }
+            //fprintf(stderr, "ber_est: %f\n", ber_est);
+        }
+        else
+            ber_est = 0.0;
+
+        if (softdec) {
+            /* pack bits, MSB received first  */
+
+            bit = 7; byte = 0;
+            memset(bits, 0, nbyte);
+            for(i=0; i<nbit; i++) {
+                bits[byte] |= ((softdec_bits[i] < 0.0) << bit);
+                bit--;
+                if (bit < 0) {
+                    bit = 7;
+                    byte++;
+                }
+            }
+            codec2_set_softdec(codec2, softdec_bits);
+        }
+
+        if (report_energy)
+           fprintf(stderr, "Energy: %1.3f\n", codec2_get_energy(codec2, bits));
+
+       codec2_decode_ber(codec2, buf, bits, ber_est);
+       fwrite(buf, sizeof(short), nsam, fout);
+
+       //if this is in a pipeline, we probably don't want the usual
+        //buffering to occur
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+
+        if (softdec)
+            ret = (fread(softdec_bits, sizeof(float), nbit, fin) == (size_t)nbit);
+        else
+            ret = (fread(bits, sizeof(char), nbyte, fin) == (size_t)nbyte);
+    }
+
+    if (error_mode)
+       fprintf(stderr, "actual BER: %1.3f\n", (float)bit_errors/bits_proc);
+
+    codec2_destroy(codec2);
+
+    free(buf);
+    free(bits);
+    free(softdec_bits);
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
+
+void print_help(const struct option* long_options, int num_opts, char* argv[])
+{
+       int i;
+       char *option_parameters;
+       fprintf(stderr, "\nc2dec - Codec 2 decoder and bit error simulation program\n"
+               "usage: %s 3200|2400|1600|1400|1300|1200|700|700B InputFile OutputRawFile [OPTIONS]\n\n"
+                "Options:\n", argv[0]);
+        for(i=0; i<num_opts-1; i++) {
+               if(long_options[i].has_arg == no_argument) {
+                       option_parameters="";
+               } else if (strcmp("ber", long_options[i].name) == 0) {
+                       option_parameters = " BER";
+               } else if (strcmp("startbit", long_options[i].name) == 0) {
+                       option_parameters = " startBit";
+               } else if (strcmp("endbit", long_options[i].name) == 0) {
+                       option_parameters = " endBit";
+               } else if (strcmp("berfile", long_options[i].name) == 0) {
+                       option_parameters = " berFileName";
+               } else if (strcmp("dump", long_options[i].name) == 0) {
+                       option_parameters = " dumpFilePrefix";
+               } else {
+                       option_parameters = " <UNDOCUMENTED parameter>";
+               }
+               fprintf(stderr, "\t--%s%s\n", long_options[i].name, option_parameters);
+       }
+       exit(1);
+}
diff --git a/codec2/branches/0.7/src/c2demo.c b/codec2/branches/0.7/src/c2demo.c
new file mode 100644 (file)
index 0000000..9cd11d4
--- /dev/null
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: c2demo.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 15/11/2010
+
+  Encodes and decodes a file of raw speech samples using Codec 2.
+  Demonstrates use of Codec 2 function API.
+
+  Note to convert a wave file to raw and vice-versa:
+
+    $ sox file.wav -r 8000 -s -2 file.raw
+    $ sox -r 8000 -s -2 file.raw file.wav
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+#include "sine.h"
+#include "dump.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int main(int argc, char *argv[])
+{
+    struct CODEC2 *codec2;
+    FILE          *fin;
+    FILE          *fout;
+    short         *buf;
+    unsigned char *bits;
+    int            nsam, nbit, i, r;
+
+    for(i=0; i<10; i++) {
+        r = codec2_rand();
+        printf("[%d] r = %d\n", i, r);
+    }
+
+    if (argc != 3) {
+       printf("usage: %s InputRawSpeechFile OutputRawSpeechFile\n", argv[0]);
+       exit(1);
+    }
+
+    if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input speech file: %s: %s.\n",
+         argv[1], strerror(errno));
+       exit(1);
+    }
+
+    if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output speech file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    #ifdef DUMP
+    dump_on("c2demo");
+    #endif
+
+    /* Note only one set of Codec 2 states is required for an encoder
+       and decoder pair. */
+
+    codec2 = codec2_create(CODEC2_MODE_1300);
+    nsam = codec2_samples_per_frame(codec2);
+    buf = (short*)malloc(nsam*sizeof(short));
+    nbit = codec2_bits_per_frame(codec2);
+    bits = (unsigned char*)malloc(nbit*sizeof(char));
+
+    while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) {
+       codec2_encode(codec2, bits, buf);
+       codec2_decode(codec2, buf, bits);
+       fwrite(buf, sizeof(short), nsam, fout);
+    }
+
+    free(buf);
+    free(bits);
+    codec2_destroy(codec2);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/c2enc.c b/codec2/branches/0.7/src/c2enc.c
new file mode 100644 (file)
index 0000000..713ce2c
--- /dev/null
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: c2enc.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/8/2010
+
+  Encodes a file of raw speech samples using codec2 and outputs a file
+  of bits.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int main(int argc, char *argv[])
+{
+    int            mode;
+    void          *codec2;
+    FILE          *fin;
+    FILE          *fout;
+    short         *buf;
+    unsigned char *bits;
+    int            nsam, nbit, nbyte, gray, softdec;
+    float         *unpacked_bits;
+    int            bit, byte,i;
+
+    if (argc < 4) {
+       printf("usage: c2enc 3200|2400|1600|1400|1300|1200|700|700B|700C InputRawspeechFile OutputBitFile [--natural] [--softdec]\n");
+       printf("e.g    c2enc 1400 ../raw/hts1a.raw hts1a.c2\n");
+       printf("e.g    c2enc 1300 ../raw/hts1a.raw hts1a.c2 --natural\n");
+       exit(1);
+    }
+
+    if (strcmp(argv[1],"3200") == 0)
+       mode = CODEC2_MODE_3200;
+    else if (strcmp(argv[1],"2400") == 0)
+       mode = CODEC2_MODE_2400;
+    else if (strcmp(argv[1],"1600") == 0)
+       mode = CODEC2_MODE_1600;
+    else if (strcmp(argv[1],"1400") == 0)
+       mode = CODEC2_MODE_1400;
+    else if (strcmp(argv[1],"1300") == 0)
+       mode = CODEC2_MODE_1300;
+    else if (strcmp(argv[1],"1200") == 0)
+       mode = CODEC2_MODE_1200;
+    else if (strcmp(argv[1],"700") == 0)
+       mode = CODEC2_MODE_700;
+    else if (strcmp(argv[1],"700B") == 0)
+       mode = CODEC2_MODE_700B;
+    else if (strcmp(argv[1],"700C") == 0)
+       mode = CODEC2_MODE_700C;
+    else {
+       fprintf(stderr, "Error in mode: %s.  Must be 3200, 2400, 1600, 1400, 1300, 1200, 700, 700B or 700C\n", argv[1]);
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[2],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input speech file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[3], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[3],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output compressed bit file: %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    nbit = codec2_bits_per_frame(codec2);
+    buf = (short*)malloc(nsam*sizeof(short));
+    nbyte = (nbit + 7) / 8;
+
+    bits = (unsigned char*)malloc(nbyte*sizeof(char));
+    unpacked_bits = (float*)malloc(nbit*sizeof(float));
+
+    gray = 1;
+    softdec = 0;
+    for (i=4; i<argc; i++) {
+        if (strcmp(argv[i], "--natural") == 0) {
+            gray = 0;
+        }
+        if (strcmp(argv[i], "--softdec") == 0) {
+            softdec = 1;
+        }
+    }
+    codec2_set_natural_or_gray(codec2, gray);
+    //fprintf(stderr,"gray: %d softdec: %d\n", gray, softdec);
+
+    while(fread(buf, sizeof(short), nsam, fin) == (size_t)nsam) {
+
+       codec2_encode(codec2, bits, buf);
+
+       if (softdec) {
+            /* unpack bits, MSB first, send as soft decision float */
+
+            bit = 7; byte = 0;
+            for(i=0; i<nbit; i++) {
+                unpacked_bits[i] = 1.0 - 2.0*((bits[byte] >> bit) & 0x1);
+                bit--;
+                if (bit < 0) {
+                    bit = 7;
+                    byte++;
+                }
+            }
+            fwrite(unpacked_bits, sizeof(float), nbit, fout);
+        }
+        else
+            fwrite(bits, sizeof(char), nbyte, fout);
+
+       // if this is in a pipeline, we probably don't want the usual
+        // buffering to occur
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    codec2_destroy(codec2);
+
+    free(buf);
+    free(bits);
+    free(unpacked_bits);
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/c2sim.c b/codec2/branches/0.7/src/c2sim.c
new file mode 100644 (file)
index 0000000..f2d3751
--- /dev/null
@@ -0,0 +1,1003 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: c2sim.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 20/8/2010
+
+  Codec2 simulation.  Combines encoder and decoder and allows
+  switching in and out various algorithms and quantisation steps. Used
+  for algorithm development.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "defines.h"
+#include "sine.h"
+#include "nlp.h"
+#include "dump.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "quantise.h"
+#include "phase.h"
+#include "postfilter.h"
+#include "interp.h"
+#include "ampexp.h"
+#include "phaseexp.h"
+#include "bpf.h"
+#include "bpfb.h"
+#include "newamp1.h"
+
+void synth_one_frame(int n_samp, codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[], float Pn[], int prede, float *de_mem, float gain);
+void print_help(const struct option *long_options, int num_opts, char* argv[]);
+
+#define N_SAMP n_samp  /* quick fix for run time sample rate selection */
+
+/*---------------------------------------------------------------------------*\
+
+                               MAIN
+
+\*---------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+
+    int Fs = 8000;
+    int set_fs;
+
+    int orderi;
+    int lpc_model = 0, order = LPC_ORD;
+    int lsp = 0, lspd = 0, lspvq = 0;
+    int lspres = 0;
+    int lspjvm = 0, lspjnd = 0, lspmel = 0, lspmelvq = 0;
+    #ifdef __EXPERIMENTAL__
+    int lspanssi = 0,
+    #endif
+    int prede = 0;
+    int   postfilt;
+    int   hand_voicing = 0, phaseexp = 0, ampexp = 0, hi = 0, simlpcpf = 0, lspmelread = 0;
+    int   lpcpf = 0;
+    FILE *fvoicing = 0;
+    FILE *flspmel = 0;
+    int dec;
+    int decimate = 1;
+    int   amread, Woread;
+    int   awread;
+    int   hmread;
+    int   phase0 = 0;
+    int   scalar_quant_Wo_e = 0;
+    int   scalar_quant_Wo_e_low = 0;
+    int   vector_quant_Wo_e = 0;
+    int   dump_pitch_e = 0;
+    float gain = 1.0;
+    int   bpf_en = 0;
+    int   bpfb_en = 0;
+    FILE *fam = NULL, *fWo = NULL;
+    FILE *faw = NULL;
+    FILE *fhm = NULL;
+    FILE *fjvm = NULL;
+    #ifdef DUMP
+    int   dump;
+    #endif
+    char  ampexp_arg[MAX_STR];
+    char  phaseexp_arg[MAX_STR];
+    char  out_file[MAX_STR];
+    FILE *fout = NULL; /* output speech file */
+    int   mel_resampling = 0;
+    int   K = 20;
+
+    char* opt_string = "ho:";
+    struct option long_options[] = {
+        { "Fs", required_argument, &set_fs, 1 },
+        { "mel", required_argument, &mel_resampling, 1 },
+        { "lpc", required_argument, &lpc_model, 1 },
+        { "lspjnd", no_argument, &lspjnd, 1 },
+        { "lspmel", no_argument, &lspmel, 1 },
+        { "lspmelread", required_argument, &lspmelread, 1 },
+        { "lspmelvq", no_argument, &lspmelvq, 1 },
+        { "lsp", no_argument, &lsp, 1 },
+        { "lspd", no_argument, &lspd, 1 },
+        { "lspvq", no_argument, &lspvq, 1 },
+        { "lspres", no_argument, &lspres, 1 },
+        { "lspjvm", no_argument, &lspjvm, 1 },
+        #ifdef __EXPERIMENTAL__
+        { "lspanssi", no_argument, &lspanssi, 1 },
+        #endif
+        { "phase0", no_argument, &phase0, 1 },
+        { "phaseexp", required_argument, &phaseexp, 1 },
+        { "ampexp", required_argument, &ampexp, 1 },
+        { "postfilter", no_argument, &postfilt, 1 },
+        { "hand_voicing", required_argument, &hand_voicing, 1 },
+        { "dec", required_argument, &dec, 1 },
+        { "hi", no_argument, &hi, 1 },
+        { "simlpcpf", no_argument, &simlpcpf, 1 },
+        { "lpcpf", no_argument, &lpcpf, 1 },
+        { "prede", no_argument, &prede, 1 },
+        { "dump_pitch_e", required_argument, &dump_pitch_e, 1 },
+        { "sq_pitch_e", no_argument, &scalar_quant_Wo_e, 1 },
+        { "sq_pitch_e_low", no_argument, &scalar_quant_Wo_e_low, 1 },
+        { "vq_pitch_e", no_argument, &vector_quant_Wo_e, 1 },
+        { "rate", required_argument, NULL, 0 },
+        { "gain", required_argument, NULL, 0 },
+        { "bpf", no_argument, &bpf_en, 1 },
+        { "bpfb", no_argument, &bpfb_en, 1 },
+        { "amread", required_argument, &amread, 1 },
+        { "hmread", required_argument, &hmread, 1 },
+        { "awread", required_argument, &awread, 1 },
+        { "Woread", required_argument, &Woread, 1 },
+        #ifdef DUMP
+        { "dump", required_argument, &dump, 1 },
+        #endif
+        { "help", no_argument, NULL, 'h' },
+        { NULL, no_argument, NULL, 0 }
+    };
+    int num_opts=sizeof(long_options)/sizeof(struct option);
+
+    /*----------------------------------------------------------------*\
+
+                     Interpret Command Line Arguments
+
+    \*----------------------------------------------------------------*/
+
+    if (argc < 2) {
+        print_help(long_options, num_opts, argv);
+    }
+
+    while(1) {
+        int option_index = 0;
+        int opt = getopt_long(argc, argv, opt_string,
+                    long_options, &option_index);
+        if (opt == -1)
+            break;
+        switch (opt) {
+         case 0:
+            if(strcmp(long_options[option_index].name, "Fs") == 0) {
+                Fs= atoi(optarg);
+                if((Fs != 8000) && (Fs != 16000)) {
+                    fprintf(stderr, "Error Fs must be 8000 or 16000\n");
+                    exit(1);
+                }
+            } else if(strcmp(long_options[option_index].name, "mel") == 0) {
+                K = atoi(optarg);
+            } else if(strcmp(long_options[option_index].name, "lpc") == 0) {
+                orderi = atoi(optarg);
+                if((orderi < 4) || (orderi > order)) {
+                    fprintf(stderr, "Error in LPC order (4 to %d): %s\n", order, optarg);
+                    exit(1);
+                }
+                order = orderi;
+            #ifdef DUMP
+            } else if(strcmp(long_options[option_index].name, "dump") == 0) {
+                if (dump)
+                   dump_on(optarg);
+            #endif
+            } else if(strcmp(long_options[option_index].name, "lsp") == 0
+                  || strcmp(long_options[option_index].name, "lspd") == 0
+                  || strcmp(long_options[option_index].name, "lspvq") == 0) {
+               assert(order == LPC_ORD);
+            } else if(strcmp(long_options[option_index].name, "dec") == 0) {
+
+                decimate = atoi(optarg);
+               if ((decimate != 2) && (decimate != 3) && (decimate != 4)) {
+                   fprintf(stderr, "Error in --dec, must be 2, 3, or 4\n");
+                   exit(1);
+               }
+
+                if (!phase0) {
+                    printf("needs --phase0 to resample phase when using --dec\n");
+                    exit(1);
+                }
+                if (!lpc_model) {
+                    printf("needs --lpc [order] to resample amplitudes when using --dec\n");
+                    exit(1);
+                }
+
+            } else if(strcmp(long_options[option_index].name, "hand_voicing") == 0) {
+               if ((fvoicing = fopen(optarg,"rt")) == NULL) {
+                   fprintf(stderr, "Error opening voicing file: %s: %s.\n",
+                       optarg, strerror(errno));
+                    exit(1);
+                }
+            } else if(strcmp(long_options[option_index].name, "lspmelread") == 0) {
+               if ((flspmel = fopen(optarg,"rb")) == NULL) {
+                   fprintf(stderr, "Error opening float lspmel file: %s: %s.\n",
+                       optarg, strerror(errno));
+                    exit(1);
+                }
+            } else if(strcmp(long_options[option_index].name, "Woread") == 0) {
+               if ((fWo = fopen(optarg,"rb")) == NULL) {
+                   fprintf(stderr, "Error opening float Wo file: %s: %s.\n",
+                       optarg, strerror(errno));
+                    exit(1);
+                }
+            } else if(strcmp(long_options[option_index].name, "amread") == 0) {
+               if ((fam = fopen(optarg,"rb")) == NULL) {
+                   fprintf(stderr, "Error opening float Am file: %s: %s.\n",
+                       optarg, strerror(errno));
+                    exit(1);
+                }
+            } else if(strcmp(long_options[option_index].name, "hmread") == 0) {
+               if ((fhm = fopen(optarg,"rb")) == NULL) {
+                   fprintf(stderr, "Error opening float Hm file: %s: %s.\n",
+                       optarg, strerror(errno));
+                    exit(1);
+                }
+            } else if(strcmp(long_options[option_index].name, "awread") == 0) {
+               if ((faw = fopen(optarg,"rb")) == NULL) {
+                   fprintf(stderr, "Error opening float Aw file: %s: %s.\n",
+                            optarg, strerror(errno));
+                    exit(1);
+                }
+           } else if(strcmp(long_options[option_index].name, "dump_pitch_e") == 0) {
+               if ((fjvm = fopen(optarg,"wt")) == NULL) {
+                   fprintf(stderr, "Error opening pitch & energy dump file: %s: %s.\n",
+                       optarg, strerror(errno));
+                    exit(1);
+                }
+           } else if(strcmp(long_options[option_index].name, "phaseexp") == 0) {
+               strcpy(phaseexp_arg, optarg);
+           } else if(strcmp(long_options[option_index].name, "ampexp") == 0) {
+               strcpy(ampexp_arg, optarg);
+           } else if(strcmp(long_options[option_index].name, "gain") == 0) {
+               gain = atof(optarg);
+           } else if(strcmp(long_options[option_index].name, "rate") == 0) {
+                if(strcmp(optarg,"3200") == 0) {
+                   lpc_model = 1;
+                   scalar_quant_Wo_e = 1;
+                   lspd = 1;
+                   phase0 = 1;
+                   postfilt = 1;
+                   decimate = 1;
+                   lpcpf = 1;
+               } else if(strcmp(optarg,"2400") == 0) {
+                   lpc_model = 1;
+                   vector_quant_Wo_e = 1;
+                   lsp = 1;
+                   phase0 = 1;
+                   postfilt = 1;
+                   decimate = 2;
+                   lpcpf = 1;
+               } else if(strcmp(optarg,"1400") == 0) {
+                   lpc_model = 1;
+                   vector_quant_Wo_e = 1;
+                   lsp = 1;
+                   phase0 = 1;
+                   postfilt = 1;
+                   decimate = 4;
+                   lpcpf = 1;
+               } else if(strcmp(optarg,"1300") == 0) {
+                   lpc_model = 1;
+                   scalar_quant_Wo_e = 1;
+                   lsp = 1;
+                   phase0 = 1;
+                   postfilt = 1;
+                   decimate = 4;
+                   lpcpf = 1;
+               } else if(strcmp(optarg,"1200") == 0) {
+                   lpc_model = 1;
+                   scalar_quant_Wo_e = 1;
+                   lspjvm = 1;
+                   phase0 = 1;
+                   postfilt = 1;
+                   decimate = 4;
+                   lpcpf = 1;
+                } else {
+                    fprintf(stderr, "Error: invalid output rate (3200|2400|1400|1200) %s\n", optarg);
+                    exit(1);
+                }
+            }
+            break;
+
+         case 'h':
+            print_help(long_options, num_opts, argv);
+            break;
+
+         case 'o':
+            if (strcmp(optarg, "-") == 0) fout = stdout;
+            else if ((fout = fopen(optarg,"wb")) == NULL) {
+               fprintf(stderr, "Error opening output speech file: %s: %s.\n",
+                   optarg, strerror(errno));
+               exit(1);
+            }
+            strcpy(out_file,optarg);
+            break;
+
+         default:
+            /* This will never be reached */
+            break;
+        }
+    }
+
+    /* Input file */
+
+    FILE *fin;         /* input speech file                     */
+    if (strcmp(argv[optind], "-")  == 0) fin = stdin;
+    else if ((fin = fopen(argv[optind],"rb")) == NULL) {
+       fprintf(stderr, "Error opening input speech file: %s: %s.\n",
+               argv[optind], strerror(errno));
+       exit(1);
+    }
+
+    C2CONST c2const = c2const_create(Fs);
+    int   n_samp = c2const.n_samp;
+    int   m_pitch = c2const.m_pitch;
+
+    short buf[N_SAMP]; /* input/output buffer                   */
+    float buf_float[N_SAMP];
+    float Sn[m_pitch]; /* float input speech samples            */
+    float Sn_pre[m_pitch];     /* pre-emphasised input speech samples   */
+    COMP  Sw[FFT_ENC]; /* DFT of Sn[]                           */
+    codec2_fft_cfg  fft_fwd_cfg;
+    codec2_fftr_cfg  fftr_fwd_cfg;
+    codec2_fftr_cfg  fftr_inv_cfg;
+    float w[m_pitch];          /* time domain hamming window            */
+    COMP  W[FFT_ENC];  /* DFT of w[]                            */
+    MODEL model;
+    float Pn[2*N_SAMP];        /* trapezoidal synthesis window          */
+    float Sn_[2*N_SAMP];       /* synthesised speech */
+    int   i,m;         /* loop variable                         */
+    int   frames;
+    float prev_f0;
+    float pitch;
+    float snr;
+    float sum_snr;
+
+    float pre_mem = 0.0, de_mem = 0.0;
+    float ak[order];
+    // COMP  Sw_[FFT_ENC];
+    // COMP  Ew[FFT_ENC];
+
+    float ex_phase[MAX_AMP+1];
+
+    float bg_est = 0.0;
+
+
+    MODEL prev_model;
+    float lsps[order];
+    float e, prev_e;
+    int   lsp_indexes[order];
+    float lsps_[order];
+    float Woe_[2];
+
+    float lsps_dec[4][LPC_ORD], e_dec[4], weight, weight_inc, ak_dec[4][LPC_ORD];
+    MODEL model_dec[4], prev_model_dec;
+    float prev_lsps_dec[order], prev_e_dec;
+
+    void *nlp_states;
+    float hpf_states[2];
+    #if 0
+    struct PEXP *pexp = NULL;
+    struct AEXP *aexp = NULL;
+    #endif
+    float bpf_buf[BPF_N+N_SAMP];
+    float lspmelvq_mse = 0.0;
+
+    COMP Aw[FFT_ENC];
+    COMP H[MAX_AMP];
+
+    for(i=0; i<m_pitch; i++) {
+       Sn[i] = 1.0;
+       Sn_pre[i] = 1.0;
+    }
+    for(i=0; i<2*N_SAMP; i++)
+       Sn_[i] = 0;
+
+    prev_f0 = 1/P_MAX_S;
+
+    prev_model.Wo = c2const.Wo_max;
+    prev_model.L = floor(PI/prev_model.Wo);
+    for(i=1; i<=prev_model.L; i++) {
+       prev_model.A[i] = 0.0;
+       prev_model.phi[i] = 0.0;
+    }
+    for(i=1; i<=MAX_AMP; i++) {
+       //ex_phase[i] = (PI/3)*(float)rand()/RAND_MAX;
+       ex_phase[i] = 0.0;
+    }
+    e = prev_e = 1;
+    hpf_states[0] = hpf_states[1] = 0.0;
+
+    nlp_states = nlp_create(&c2const);
+
+    ex_phase[0] = 0;
+    Woe_[0] = Woe_[1] = 1.0;
+
+    /*
+      printf("lspd: %d lspdt: %d lspdt_mode: %d  phase0: %d postfilt: %d "
+          "decimate: %d dt: %d\n",lspd,lspdt,lspdt_mode,phase0,postfilt,
+          decimate,dt);
+    */
+
+    /* Initialise ------------------------------------------------------------*/
+
+    fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL);   /* fwd FFT,used in several places   */
+    fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL); /* fwd FFT,used in several places   */
+    fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL); /* inverse FFT, used just for synth */
+    codec2_fft_cfg phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 0, NULL, NULL);
+    codec2_fft_cfg phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 1, NULL, NULL);
+
+    make_analysis_window(&c2const, fft_fwd_cfg, w, W);
+    make_synthesis_window(&c2const, Pn);
+    quantise_init();
+
+    /* disabled for now while we convert to runtime n_samp */
+    #if 0
+    if (phaseexp)
+       pexp = phase_experiment_create();
+    if (ampexp)
+       aexp = amp_experiment_create();
+    #endif
+
+    if (bpfb_en)
+        bpf_en = 1;
+    if (bpf_en) {
+        for(i=0; i<BPF_N; i++)
+            bpf_buf[i] = 0.0;
+    }
+
+    for(i=0; i<LPC_ORD; i++) {
+        prev_lsps_dec[i] = i*PI/(LPC_ORD+1);
+    }
+    prev_e_dec = 1;
+    for(m=1; m<=MAX_AMP; m++)
+       prev_model_dec.A[m] = 0.0;
+    prev_model_dec.Wo = c2const.Wo_min;
+    prev_model_dec.L = PI/prev_model_dec.Wo;
+    prev_model_dec.voiced = 0;
+
+    /* mel resampling experiments */
+
+    float rate_K_sample_freqs_kHz[K];
+    if (mel_resampling) {
+        float mel_start = ftomel(100); 
+        float mel_end = ftomel(0.95*Fs/2);
+        mel_sample_freqs_kHz(rate_K_sample_freqs_kHz, K, mel_start, mel_end);
+        //for(i=0; i<K; i++)
+        //    fprintf(stderr, "%d %f\n", i, rate_K_sample_freqs_kHz[i]);
+    }
+
+    /*----------------------------------------------------------------* \
+
+                            Main Loop
+
+    \*----------------------------------------------------------------*/
+
+    frames = 0;
+    sum_snr = 0;
+    while(fread(buf,sizeof(short),N_SAMP,fin)) {
+       frames++;
+
+       for(i=0; i<N_SAMP; i++)
+           buf_float[i] = buf[i];
+
+       /* optionally filter input speech */
+
+        if (prede) {
+           pre_emp(Sn_pre, buf_float, &pre_mem, N_SAMP);
+           for(i=0; i<N_SAMP; i++)
+                buf_float[i] = Sn_pre[i];
+        }
+
+        if (bpf_en) {
+            /* filter input speech to create buf_float_bpf[], this is fed to the
+               LPC modelling.  Unfiltered speech in in buf_float[], which is
+               delayed to match that of the BPF */
+
+            /* BPF speech */
+
+            for(i=0; i<BPF_N; i++)
+                bpf_buf[i] =  bpf_buf[N_SAMP+i];
+            for(i=0; i<N_SAMP; i++)
+                bpf_buf[BPF_N+i] = buf_float[i];
+            if (bpfb_en)
+                inverse_filter(&bpf_buf[BPF_N], bpfb, N_SAMP, buf_float, BPF_N);
+            else
+                inverse_filter(&bpf_buf[BPF_N], bpf, N_SAMP, buf_float, BPF_N);
+        }
+
+        /* shift buffer of input samples, and insert new samples */
+
+       for(i=0; i<m_pitch-N_SAMP; i++) {
+           Sn[i] = Sn[i+N_SAMP];
+       }
+       for(i=0; i<N_SAMP; i++) {
+           Sn[i+m_pitch-N_SAMP] = buf_float[i];
+        }
+
+       /*------------------------------------------------------------*\
+
+                      Estimate Sinusoidal Model Parameters
+
+       \*------------------------------------------------------------*/
+
+        nlp(nlp_states, Sn, N_SAMP, &pitch, Sw, W, &prev_f0);
+       model.Wo = TWO_PI/pitch;
+
+        dft_speech(&c2const, fft_fwd_cfg, Sw, Sn, w);
+       two_stage_pitch_refinement(&c2const, &model, Sw);
+       estimate_amplitudes(&model, Sw, W, 1);
+
+        #ifdef DUMP
+        dump_Sn(m_pitch, Sn); dump_Sw(Sw); dump_model(&model);
+        #endif
+
+        #if 0
+       if (ampexp)
+           amp_experiment(aexp, &model, ampexp_arg);
+
+       if (phaseexp) {
+            #ifdef DUMP
+           dump_phase(&model.phi[0], model.L);
+            #endif
+           phase_experiment(pexp, &model, phaseexp_arg);
+            #ifdef DUMP
+           dump_phase_(&model.phi[0], model.L);
+            #endif
+       }
+        #endif
+
+       if (hi) {
+           int m;
+           for(m=1; m<model.L/2; m++)
+               model.A[m] = 0.0;
+           for(m=3*model.L/4; m<=model.L; m++)
+               model.A[m] = 0.0;
+       }
+
+       /*------------------------------------------------------------*\
+
+                            Mel scale resampling
+
+       \*------------------------------------------------------------*/
+
+        if (mel_resampling) {
+            float rate_K_vec[K];
+            resample_const_rate_f(&c2const, &model, rate_K_vec, rate_K_sample_freqs_kHz, K);
+            resample_rate_L(&c2const, &model, rate_K_vec, rate_K_sample_freqs_kHz, K);
+        }
+
+       /*------------------------------------------------------------*\
+
+                            Zero-phase modelling
+
+       \*------------------------------------------------------------*/
+
+       if (phase0) {
+            #ifdef DUMP
+           dump_phase(&model.phi[0], model.L);
+            #endif
+
+           /* determine voicing */
+
+           #if 0
+            snr = est_voicing_mbe(&c2const, &model, Sw, W, Sw_, Ew);
+            #else
+           snr = est_voicing_mbe(&c2const, &model, Sw, W);
+            #endif
+
+           if (dump_pitch_e)
+               fprintf(fjvm, "%f %f %d ", model.Wo, snr, model.voiced);
+
+           //printf("snr %3.2f v: %d Wo: %f prev_Wo: %f\n", snr, model.voiced,
+           //     model.Wo, prev_uq_Wo);
+            #ifdef DUMP
+           //dump_Sw_(Sw_);
+           //dump_Ew(Ew);
+           dump_snr(snr);
+            #endif
+
+           /* just to make sure we are not cheating - kill all phases */
+
+           for(i=0; i<=MAX_AMP; i++)
+               model.phi[i] = 0;
+
+           if (hand_voicing) {
+               int ret = fscanf(fvoicing,"%d\n",&model.voiced);
+                assert(ret == 1);
+           }
+       }
+
+       /*------------------------------------------------------------*\
+
+               LPC model amplitudes and LSP quantisation
+
+       \*------------------------------------------------------------*/
+
+       if (lpc_model) {
+
+            e = speech_to_uq_lsps(lsps, ak, Sn, w, m_pitch, order);
+            for(i=0; i<LPC_ORD; i++)
+                lsps_[i] = lsps[i];
+
+            #ifdef DUMP
+           dump_ak(ak, order);
+            dump_E(e);
+            #endif
+
+           /* tracking down -ve energy values with BW expansion */
+           /*
+           if (e < 0.0) {
+               int i;
+               FILE*f=fopen("x.txt","wt");
+               for(i=0; i<M_PITCH; i++)
+                   fprintf(f,"%f\n", Sn[i]);
+               fclose(f);
+               printf("e = %f frames = %d\n", e, frames);
+               for(i=0; i<order; i++)
+                   printf("%f ", ak[i]);
+               exit(0);
+           }
+           */
+
+           if (dump_pitch_e)
+               fprintf(fjvm, "%f\n", e);
+
+            #ifdef DUMP
+            dump_lsp(lsps);
+            #endif
+
+           /* various LSP quantisation schemes */
+
+           if (lsp) {
+               encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+               decode_lsps_scalar(lsps_, lsp_indexes, LPC_ORD);
+               bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
+               lsp_to_lpc(lsps_, ak, LPC_ORD);
+           }
+
+           if (lspd) {
+               encode_lspds_scalar(lsp_indexes, lsps, LPC_ORD);
+               decode_lspds_scalar(lsps_, lsp_indexes, LPC_ORD);
+               lsp_to_lpc(lsps_, ak, LPC_ORD);
+           }
+
+#ifdef __EXPERIMENTAL__
+           if (lspvq) {
+               lspvq_quantise(lsps, lsps_, LPC_ORD);
+               bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
+               lsp_to_lpc(lsps_, ak, LPC_ORD);
+           }
+#endif
+
+           if (lspjvm) {
+               /* Jean-Marc's multi-stage, split VQ */
+               lspjvm_quantise(lsps, lsps_, LPC_ORD);
+               {
+                   float lsps_bw[LPC_ORD];
+                   memcpy(lsps_bw, lsps_, sizeof(float)*LPC_ORD);
+                   bw_expand_lsps(lsps_bw, LPC_ORD, 50.0, 100.0);
+                   lsp_to_lpc(lsps_bw, ak, LPC_ORD);
+               }
+           }
+
+#ifdef __EXPERIMENTAL__
+           if (lspanssi) {
+               /*  multi-stage VQ from Anssi Ramo OH3GDD */
+
+               lspanssi_quantise(lsps, lsps_, LPC_ORD, 5);
+               bw_expand_lsps(lsps_, LPC_ORD, 50.0, 100.0);
+               lsp_to_lpc(lsps_, ak, LPC_ORD);
+           }
+#endif
+
+           /* experimenting with non-linear LSP spacing to see if
+              it's just noticable */
+
+           if (lspjnd) {
+               for(i=0; i<LPC_ORD; i++)
+                   lsps_[i] = lsps[i];
+               locate_lsps_jnd_steps(lsps_, LPC_ORD);
+               lsp_to_lpc(lsps_, ak, LPC_ORD);
+           }
+
+           /* Another experiment with non-linear LSP spacing, this
+              time using a scaled version of mel frequency axis
+              warping.  The scaling is such that the integer output
+              can be directly sent over the channel.
+           */
+
+           if (lspmel) {
+               float f, f_;
+               float mel[order];
+               int   mel_indexes[order];
+
+               for(i=0; i<order; i++) {
+                   f = (4000.0/PI)*lsps[i];
+                   mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5);
+               }
+
+                #define MEL_ROUND 25
+               for(i=1; i<order; i++) {
+                   if (mel[i] <= mel[i-1]+MEL_ROUND) {
+                       mel[i]+=MEL_ROUND/2;
+                       mel[i-1]-=MEL_ROUND/2;
+                        i = 1;
+                    }
+               }
+
+                #ifdef DUMP
+                dump_mel(mel, order);
+                #endif
+
+               encode_mels_scalar(mel_indexes, mel, 6);
+                #ifdef DUMP
+                dump_mel_indexes(mel_indexes, 6);
+                #endif
+               //decode_mels_scalar(mel, mel_indexes, 6);
+
+                /* read in VQed lsp-mels from octave/melvq.m */
+
+                if (lspmelread) {
+                    float mel_[order];
+                    int ret = fread(mel_, sizeof(float), order, flspmel);
+                    assert(ret == order);
+                    for(i=0; i<order; i++) {
+                        lspmelvq_mse += pow(mel[i] - mel_[i], 2.0);
+                        mel[i] = mel_[i];
+                    }
+                }
+
+                if (lspmelvq) {
+                    int indexes[3];
+                    //lspmelvq_mse += lspmelvq_quantise(mel, mel, order);
+                    lspmelvq_mse += lspmelvq_mbest_encode(indexes, mel, mel, order, 5);
+                }
+
+                /* ensure no unstable filters after quantisation */
+
+                #define MEL_ROUND 25
+               for(i=1; i<order; i++) {
+                   if (mel[i] <= mel[i-1]+MEL_ROUND) {
+                       mel[i]+=MEL_ROUND/2;
+                       mel[i-1]-=MEL_ROUND/2;
+                        i = 1;
+                    }
+               }
+
+               for(i=0; i<order; i++) {
+                   f_ = 700.0*( pow(10.0, mel[i]/2595.0) - 1.0);
+                   lsps_[i] = f_*(PI/4000.0);
+               }
+
+               lsp_to_lpc(lsps_, ak, order);
+
+           }
+
+           if (scalar_quant_Wo_e) {
+
+               e = decode_energy(encode_energy(e, E_BITS), E_BITS);
+                model.Wo = decode_Wo(&c2const, encode_Wo(&c2const, model.Wo, WO_BITS), WO_BITS);
+               model.L  = PI/model.Wo; /* if we quantise Wo re-compute L */
+           }
+
+           if (scalar_quant_Wo_e_low) {
+                int ind;
+               e = decode_energy(ind = encode_energy(e, 3), 3);
+                model.Wo = decode_log_Wo(&c2const, encode_log_Wo(&c2const, model.Wo, 5), 5);
+               model.L  = PI/model.Wo; /* if we quantise Wo re-compute L */
+           }
+
+           if (vector_quant_Wo_e) {
+
+               /* JVM's experimental joint Wo & LPC energy quantiser */
+
+               quantise_WoE(&c2const, &model, &e, Woe_);
+           }
+
+       }
+
+        if (amread) {
+            int ret = fread(model.A, sizeof(float), MAX_AMP, fam);
+            assert(ret == MAX_AMP);
+        }
+
+        if (Woread) {
+            int ret = fread(&model.Wo, sizeof(float), 1, fWo);
+            model.L = floor(PI/model.Wo);
+            assert(ret == 1);
+        }
+
+       /*------------------------------------------------------------*\
+
+          Synthesise and optional decimation to 20 or 40ms frame rate
+
+       \*------------------------------------------------------------*/
+
+        /*
+           if decimate == 2, we interpolate frame n from frame n-1 and n+1
+           if decimate == 4, we interpolate frames n, n+1, n+2, from frames n-1 and n+3
+
+           This is meant to give identical results to the implementations of various modes
+           in codec2.c
+        */
+
+        /* delay line to keep frame by frame voicing decisions */
+
+        for(i=0; i<decimate-1; i++)
+            model_dec[i] = model_dec[i+1];
+        model_dec[decimate-1] = model;
+
+        if ((frames % decimate) == 0) {
+            for(i=0; i<order; i++)
+                lsps_dec[decimate-1][i] = lsps_[i];
+            e_dec[decimate-1] = e;
+            model_dec[decimate-1] = model;
+
+            /* interpolate the model parameters */
+
+            weight_inc = 1.0/decimate;
+            for(i=0, weight=weight_inc; i<decimate-1; i++, weight += weight_inc) {
+                //model_dec[i].voiced = model_dec[decimate-1].voiced;
+                interpolate_lsp_ver2(&lsps_dec[i][0], prev_lsps_dec, &lsps_dec[decimate-1][0], weight, order);
+                interp_Wo2(&model_dec[i], &prev_model_dec, &model_dec[decimate-1], weight, c2const.Wo_min);
+                e_dec[i] = interp_energy2(prev_e_dec, e_dec[decimate-1],weight);
+            }
+
+            /* then recover spectral amplitudes and synthesise */
+
+            for(i=0; i<decimate; i++) {
+                if (lpc_model) {
+                    lsp_to_lpc(&lsps_dec[i][0], &ak_dec[i][0], order);
+                    aks_to_M2(fftr_fwd_cfg, &ak_dec[i][0], order, &model_dec[i], e_dec[i],
+                              &snr, 0, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw);
+                    apply_lpc_correction(&model_dec[i]);
+                    sum_snr += snr;
+                    #ifdef DUMP
+                    dump_lsp_(&lsps_dec[i][0]);
+                    dump_ak_(&ak_dec[i][0], order);
+                    dump_quantised_model(&model_dec[i]);
+                    #endif
+                }
+
+                if (phase0) {
+                    /* optionally read in Aw, replacing values generated using LPC */
+
+                    if (awread) {
+                        int ret = fread(Aw, sizeof(COMP), FFT_ENC, faw);
+                        assert(ret == FFT_ENC);
+                    }
+                    
+                    /* optionally read in Hm directly, bypassing sampling of Aw[] */
+
+                    if (hmread) {
+                        int ret = fread(H, sizeof(COMP), MAX_AMP, fhm);
+                        assert(ret == MAX_AMP);
+                    } else {
+                        determine_phase(&c2const, H, &model_dec[i], NEWAMP1_PHASE_NFFT, phase_fft_fwd_cfg, phase_fft_inv_cfg);
+                    }
+                    phase_synth_zero_order(n_samp, &model_dec[i], ex_phase, H);
+                }
+
+                
+                if (postfilt)
+                    postfilter(&model_dec[i], &bg_est);
+                synth_one_frame(n_samp, fftr_inv_cfg, buf, &model_dec[i], Sn_, Pn, prede, &de_mem, gain);
+                if (fout != NULL) fwrite(buf,sizeof(short),N_SAMP,fout);
+            }
+
+            /* update memories for next frame ----------------------------*/
+
+            prev_model_dec = model_dec[decimate-1];
+            prev_e_dec = e_dec[decimate-1];
+            for(i=0; i<LPC_ORD; i++)
+                prev_lsps_dec[i] = lsps_dec[decimate-1][i];
+       }
+
+    }
+
+    /*----------------------------------------------------------------*\
+
+                            End Main Loop
+
+    \*----------------------------------------------------------------*/
+
+    fclose(fin);
+
+    if (fout != NULL)
+       fclose(fout);
+
+    if (lpc_model) {
+       fprintf(stderr, "SNR av = %5.2f dB\n", sum_snr/frames);
+        if (lspmelvq || lspmelread)
+            fprintf(stderr, "lspmelvq std = %3.1f Hz\n", sqrt(lspmelvq_mse/frames));
+    }
+
+    #if 0
+    if (phaseexp)
+       phase_experiment_destroy(pexp);
+    if (ampexp)
+       amp_experiment_destroy(aexp);
+    #endif
+    #ifdef DUMP
+    if (dump)
+       dump_off();
+    #endif
+
+    if (hand_voicing)
+       fclose(fvoicing);
+
+    nlp_destroy(nlp_states);
+
+    return 0;
+}
+
+void synth_one_frame(int n_samp, codec2_fftr_cfg fftr_inv_cfg, short buf[], MODEL *model, float Sn_[],
+                     float Pn[], int prede, float *de_mem, float gain)
+{
+    int     i;
+
+    synthesise(n_samp, fftr_inv_cfg, Sn_, model, Pn, 1);
+    if (prede)
+        de_emp(Sn_, Sn_, de_mem, n_samp);
+
+    for(i=0; i<n_samp; i++) {
+       Sn_[i] *= gain;
+       if (Sn_[i] > 32767.0)
+           buf[i] = 32767;
+       else if (Sn_[i] < -32767.0)
+           buf[i] = -32767;
+       else
+           buf[i] = Sn_[i];
+    }
+
+}
+
+void print_help(const struct option* long_options, int num_opts, char* argv[])
+{
+       int i;
+       char *option_parameters;
+
+       fprintf(stderr, "\nCodec2 - low bit rate speech codec - Simulation Program\n"
+               "\thttp://rowetel.com/codec2.html\n\n"
+               "usage: %s [OPTIONS] <InputFile>\n\n"
+                "Options:\n"
+                "\t-o <OutputFile>\n", argv[0]);
+        for(i=0; i<num_opts-1; i++) {
+               if(long_options[i].has_arg == no_argument) {
+                       option_parameters="";
+               } else if (strcmp("lpc", long_options[i].name) == 0) {
+                       option_parameters = " <Order>";
+               } else if (strcmp("dec", long_options[i].name) == 0) {
+                       option_parameters = " <2|4>";
+               } else if (strcmp("hand_voicing", long_options[i].name) == 0) {
+                       option_parameters = " <VoicingFile>";
+               } else if (strcmp("dump_pitch_e", long_options[i].name) == 0) {
+                       option_parameters = " <Dump File>";
+               } else if (strcmp("rate", long_options[i].name) == 0) {
+                       option_parameters = " <3200|2400|1400|1300|1200>";
+               } else if (strcmp("dump", long_options[i].name) == 0) {
+                       option_parameters = " <DumpFilePrefix>";
+               } else {
+                       option_parameters = " <UNDOCUMENTED parameter>";
+               }
+               fprintf(stderr, "\t--%s%s\n", long_options[i].name, option_parameters);
+       }
+
+       exit(1);
+}
+
diff --git a/codec2/branches/0.7/src/codebook.c b/codec2/branches/0.7/src/codebook.c
new file mode 100644 (file)
index 0000000..0b491ee
--- /dev/null
@@ -0,0 +1,245 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* codebook/lsp1.txt */
+static const float codes0[] = {
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600
+};
+  /* codebook/lsp2.txt */
+static const float codes1[] = {
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700
+};
+  /* codebook/lsp3.txt */
+static const float codes2[] = {
+  500,
+  550,
+  600,
+  650,
+  700,
+  750,
+  800,
+  850,
+  900,
+  950,
+  1000,
+  1050,
+  1100,
+  1150,
+  1200,
+  1250
+};
+  /* codebook/lsp4.txt */
+static const float codes3[] = {
+  700,
+  800,
+  900,
+  1000,
+  1100,
+  1200,
+  1300,
+  1400,
+  1500,
+  1600,
+  1700,
+  1800,
+  1900,
+  2000,
+  2100,
+  2200
+};
+  /* codebook/lsp5.txt */
+static const float codes4[] = {
+  950,
+  1050,
+  1150,
+  1250,
+  1350,
+  1450,
+  1550,
+  1650,
+  1750,
+  1850,
+  1950,
+  2050,
+  2150,
+  2250,
+  2350,
+  2450
+};
+  /* codebook/lsp6.txt */
+static const float codes5[] = {
+  1100,
+  1200,
+  1300,
+  1400,
+  1500,
+  1600,
+  1700,
+  1800,
+  1900,
+  2000,
+  2100,
+  2200,
+  2300,
+  2400,
+  2500,
+  2600
+};
+  /* codebook/lsp7.txt */
+static const float codes6[] = {
+  1500,
+  1600,
+  1700,
+  1800,
+  1900,
+  2000,
+  2100,
+  2200,
+  2300,
+  2400,
+  2500,
+  2600,
+  2700,
+  2800,
+  2900,
+  3000
+};
+  /* codebook/lsp8.txt */
+static const float codes7[] = {
+  2300,
+  2400,
+  2500,
+  2600,
+  2700,
+  2800,
+  2900,
+  3000
+};
+  /* codebook/lsp9.txt */
+static const float codes8[] = {
+  2500,
+  2600,
+  2700,
+  2800,
+  2900,
+  3000,
+  3100,
+  3200
+};
+  /* codebook/lsp10.txt */
+static const float codes9[] = {
+  2900,
+  3100,
+  3300,
+  3500
+};
+
+const struct lsp_codebook lsp_cb[] = {
+  /* codebook/lsp1.txt */
+  {
+    1,
+    4,
+    16,
+    codes0
+  },
+  /* codebook/lsp2.txt */
+  {
+    1,
+    4,
+    16,
+    codes1
+  },
+  /* codebook/lsp3.txt */
+  {
+    1,
+    4,
+    16,
+    codes2
+  },
+  /* codebook/lsp4.txt */
+  {
+    1,
+    4,
+    16,
+    codes3
+  },
+  /* codebook/lsp5.txt */
+  {
+    1,
+    4,
+    16,
+    codes4
+  },
+  /* codebook/lsp6.txt */
+  {
+    1,
+    4,
+    16,
+    codes5
+  },
+  /* codebook/lsp7.txt */
+  {
+    1,
+    4,
+    16,
+    codes6
+  },
+  /* codebook/lsp8.txt */
+  {
+    1,
+    3,
+    8,
+    codes7
+  },
+  /* codebook/lsp9.txt */
+  {
+    1,
+    3,
+    8,
+    codes8
+  },
+  /* codebook/lsp10.txt */
+  {
+    1,
+    2,
+    4,
+    codes9
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebook/dlsp1.txt b/codec2/branches/0.7/src/codebook/dlsp1.txt
new file mode 100644 (file)
index 0000000..058d048
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
+725
+750
+775
+800
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp10.txt b/codec2/branches/0.7/src/codebook/dlsp10.txt
new file mode 100644 (file)
index 0000000..058d048
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
+725
+750
+775
+800
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp2.txt b/codec2/branches/0.7/src/codebook/dlsp2.txt
new file mode 100644 (file)
index 0000000..058d048
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
+725
+750
+775
+800
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp3.txt b/codec2/branches/0.7/src/codebook/dlsp3.txt
new file mode 100644 (file)
index 0000000..058d048
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
+725
+750
+775
+800
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp4.txt b/codec2/branches/0.7/src/codebook/dlsp4.txt
new file mode 100644 (file)
index 0000000..4a5e990
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+250
+300
+350
+400
+450
+500
+550
+600
+650
+700
+750
+800
+850
+900
+950
+1000
+1050
+1100
+1150
+1200
+1250
+1300
+1350
+1400
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp5.txt b/codec2/branches/0.7/src/codebook/dlsp5.txt
new file mode 100644 (file)
index 0000000..4a5e990
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+250
+300
+350
+400
+450
+500
+550
+600
+650
+700
+750
+800
+850
+900
+950
+1000
+1050
+1100
+1150
+1200
+1250
+1300
+1350
+1400
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp6.txt b/codec2/branches/0.7/src/codebook/dlsp6.txt
new file mode 100644 (file)
index 0000000..4a5e990
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+250
+300
+350
+400
+450
+500
+550
+600
+650
+700
+750
+800
+850
+900
+950
+1000
+1050
+1100
+1150
+1200
+1250
+1300
+1350
+1400
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp7.txt b/codec2/branches/0.7/src/codebook/dlsp7.txt
new file mode 100644 (file)
index 0000000..058d048
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
+725
+750
+775
+800
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp8.txt b/codec2/branches/0.7/src/codebook/dlsp8.txt
new file mode 100644 (file)
index 0000000..058d048
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
+725
+750
+775
+800
+
+
diff --git a/codec2/branches/0.7/src/codebook/dlsp9.txt b/codec2/branches/0.7/src/codebook/dlsp9.txt
new file mode 100644 (file)
index 0000000..058d048
--- /dev/null
@@ -0,0 +1,35 @@
+1 32
+25
+50
+75
+100
+125
+150
+175
+200
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
+725
+750
+775
+800
+
+
diff --git a/codec2/branches/0.7/src/codebook/gecb.txt b/codec2/branches/0.7/src/codebook/gecb.txt
new file mode 100644 (file)
index 0000000..bd3bb08
--- /dev/null
@@ -0,0 +1,257 @@
+2 256
+2.709998 12.018395
+0.046750 -2.738813
+0.120993 8.388947
+-1.580275 -0.892307
+1.193065 -1.915609
+0.187101 -3.276788
+0.332251 -7.664550
+-1.479436 31.246122
+1.527612 27.709463
+-0.524379 5.250122
+0.553330 7.438797
+-0.843451 -1.952987
+2.263885 8.610286
+0.143143 2.365493
+0.616506 1.284268
+-1.711327 22.096672
+1.008128 17.396519
+-0.106718 1.418905
+-0.136246 14.273605
+-1.709087 -20.531881
+1.657866 -3.391068
+0.138049 -4.957845
+0.536729 -1.943748
+0.196307 36.851948
+1.272479 22.556494
+-0.670219 -1.906045
+0.382092 6.401132
+-0.756911 -4.901017
+1.829313 4.613800
+0.318794 0.736830
+0.612815 -2.075045
+-0.410151 24.787077
+1.776016 13.190924
+0.106457 -0.104492
+0.192206 10.183844
+-1.824423 -7.715654
+0.931346 4.348355
+0.308813 -4.086001
+0.397143 -11.808859
+-0.048715 41.227314
+0.877342 35.850311
+-0.759794 0.476634
+0.978593 7.674673
+-1.195056 3.038826
+2.639894 -3.411063
+0.191127 3.603507
+0.402932 1.084298
+-2.152022 18.107616
+1.546802 8.322713
+-0.143089 -4.075922
+-0.150142 5.866741
+-1.408444 -3.250696
+1.566148 -10.413164
+0.178171 -10.226697
+0.362164 -0.028556
+-0.070125 24.390722
+0.594752 17.482765
+-0.286980 -6.904069
+0.464818 10.205451
+-1.006841 -14.357209
+2.329569 -3.691613
+0.335745 2.407139
+1.019658 -3.155647
+-1.259455 7.991899
+2.383695 19.680567
+-0.094947 -2.413742
+0.209330 6.664768
+-2.221034 1.379860
+1.292387 2.046333
+0.243626 -0.890741
+0.428773 -7.193658
+-1.113744 41.341354
+2.609799 31.140514
+-0.446468 2.534188
+0.490104 4.627575
+-1.117226 -3.241744
+1.791562 8.414926
+0.156012 0.183336
+0.532447 3.154545
+-0.764484 18.513958
+0.952395 11.771298
+-0.332567 0.346987
+0.202165 14.716752
+-2.129240 -15.558954
+1.353583 -1.926790
+-0.010963 -16.336386
+0.399053 -2.790569
+0.750657 31.148336
+0.655743 24.481859
+-0.453210 -0.735879
+0.286900 6.546703
+-0.715673 -12.357815
+1.548488 3.872171
+0.271874 0.802339
+0.502073 -4.854850
+-0.497037 17.761904
+1.191161 13.954446
+0.015630 1.331566
+0.341867 8.935369
+-2.316009 -5.395058
+0.758610 1.964505
+0.241320 -3.237686
+0.267151 -11.234388
+-0.273126 32.624771
+1.753523 40.431995
+-0.784011 3.045757
+0.705987 5.661178
+-1.386400 1.353557
+2.376458 1.674851
+0.242973 4.732178
+0.491227 0.354061
+-1.606762 8.658955
+1.167111 5.987103
+-0.137601 -12.041750
+-0.251375 10.397204
+-1.431514 -8.904108
+0.988280 -13.208963
+0.261484 -6.354970
+0.395932 -0.702529
+0.283704 26.899563
+0.420959 15.441778
+-0.355804 -13.727784
+0.527372 12.398515
+-1.169559 -15.998457
+1.906688 -5.816055
+0.354492 3.851572
+0.825760 -4.162642
+-0.490190 13.057229
+2.255773 13.526449
+-0.004956 -3.237127
+0.026709 7.866448
+-1.810372 -0.451183
+1.083827 -0.183620
+0.135836 -2.266582
+0.375812 -5.512248
+-1.966443 38.682854
+1.977988 24.565481
+-0.704656 6.358810
+0.480786 7.051749
+-0.976417 -2.422727
+2.502148 6.759346
+0.083588 3.258795
+0.543629 0.910013
+-1.231959 23.091507
+0.785492 14.807000
+-0.213554 1.688002
+0.004748 18.171820
+-1.547192 -16.116837
+1.501045 -3.281141
+0.080133 -4.634724
+0.476592 -2.180929
+0.442470 40.303989
+1.072766 27.592009
+-0.594738 -4.166807
+0.422480 7.616091
+-0.927521 -7.274406
+1.991623 1.296359
+0.291307 2.398781
+0.721081 -1.950625
+-0.804256 24.929474
+1.648388 19.119692
+0.060852 -0.590639
+0.266085 9.103249
+-1.957399 -2.884607
+1.116929 2.672397
+0.354580 -2.748541
+0.330733 -14.156131
+-0.527851 39.575626
+0.991152 43.194984
+-0.589619 1.269186
+0.787401 8.730713
+-1.013800 1.025075
+2.825403 1.895381
+0.240890 2.745566
+0.427195 2.544456
+-1.953109 12.243958
+1.448616 12.060747
+-0.210492 -3.379058
+-0.056713 10.204020
+-1.652370 -5.102737
+1.294748 -12.270802
+0.111608 -8.675921
+0.326634 -1.167627
+0.021781 31.125782
+0.455335 21.468430
+-0.375440 -3.371207
+0.393620 11.301987
+-0.851456 -19.414892
+2.107030 -2.228865
+0.373233 1.924056
+0.884438 -1.720581
+-0.975127 9.840128
+2.003303 17.395407
+-0.036915 -1.111372
+0.148456 5.399970
+-1.914412 4.773819
+1.447907 0.537122
+0.194979 -1.038179
+0.495771 -9.955025
+-1.058987 32.947052
+2.011222 32.454418
+-0.309650 4.719106
+0.436082 4.635524
+-1.237105 -1.254284
+2.022740 9.428345
+0.190342 1.460767
+0.479017 2.484788
+-1.078483 16.221748
+1.207642 9.654212
+-0.258087 -1.672358
+0.071852 13.415978
+-1.877228 -16.072031
+1.289568 -4.871185
+0.067713 -13.442700
+0.435551 -4.165503
+0.466140 30.589535
+0.904895 21.597990
+-0.518369 -2.532048
+0.337363 5.637264
+-0.554975 -17.400511
+1.691879 1.145742
+0.227934 0.889297
+0.587303 -5.729732
+-0.262133 18.666620
+1.395048 17.002878
+-0.019090 4.308379
+0.304235 12.669943
+-2.074059 -6.460845
+0.920546 1.212957
+0.284927 -1.785466
+0.209724 -16.023964
+-0.636067 31.576820
+1.349887 34.677502
+-0.971625 5.300859
+0.590249 4.449709
+-1.567867 3.602385
+2.145497 4.516663
+0.296022 4.120170
+0.445299 0.868772
+-1.441931 14.128431
+1.355752 6.007401
+-0.012814 -7.496573
+-0.430000 8.500124
+-1.204693 -7.113256
+1.101018 -6.836818
+0.196463 -6.234002
+0.436747 -1.129788
+0.141052 22.854876
+0.290821 18.811443
+-0.529536 -7.732510
+0.634280 10.789847
+-1.334721 -20.325773
+1.815645 -1.903316
+0.394778 3.797577
+0.732682 -8.183819
+-0.741244 11.768337
diff --git a/codec2/branches/0.7/src/codebook/lsp1.txt b/codec2/branches/0.7/src/codebook/lsp1.txt
new file mode 100644 (file)
index 0000000..d126be7
--- /dev/null
@@ -0,0 +1,17 @@
+1 16
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
diff --git a/codec2/branches/0.7/src/codebook/lsp10.txt b/codec2/branches/0.7/src/codebook/lsp10.txt
new file mode 100644 (file)
index 0000000..39aab7c
--- /dev/null
@@ -0,0 +1,6 @@
+1 4
+2900
+3100
+3300
+3500
+
diff --git a/codec2/branches/0.7/src/codebook/lsp2.txt b/codec2/branches/0.7/src/codebook/lsp2.txt
new file mode 100644 (file)
index 0000000..597f149
--- /dev/null
@@ -0,0 +1,17 @@
+1 16
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
diff --git a/codec2/branches/0.7/src/codebook/lsp3.txt b/codec2/branches/0.7/src/codebook/lsp3.txt
new file mode 100644 (file)
index 0000000..36a64b1
--- /dev/null
@@ -0,0 +1,17 @@
+1 16
+500
+550
+600
+650
+700
+750
+800
+850
+900
+950
+1000
+1050
+1100
+1150
+1200
+1250
diff --git a/codec2/branches/0.7/src/codebook/lsp4.txt b/codec2/branches/0.7/src/codebook/lsp4.txt
new file mode 100644 (file)
index 0000000..53a90bd
--- /dev/null
@@ -0,0 +1,17 @@
+1 16
+700
+800
+900
+1000
+1100
+1200
+1300
+1400
+1500
+1600
+1700
+1800
+1900
+2000
+2100
+2200
diff --git a/codec2/branches/0.7/src/codebook/lsp5.txt b/codec2/branches/0.7/src/codebook/lsp5.txt
new file mode 100644 (file)
index 0000000..94739b5
--- /dev/null
@@ -0,0 +1,19 @@
+1 16
+ 950
+1050
+1150
+1250
+1350
+1450
+1550
+1650
+1750
+1850
+1950
+2050
+2150
+2250
+2350
+2450
+
+
diff --git a/codec2/branches/0.7/src/codebook/lsp6.txt b/codec2/branches/0.7/src/codebook/lsp6.txt
new file mode 100644 (file)
index 0000000..992ea25
--- /dev/null
@@ -0,0 +1,19 @@
+1 16
+1100
+1200
+1300
+1400
+1500
+1600
+1700
+1800
+1900
+2000
+2100
+2200
+2300
+2400
+2500
+2600
+
+
diff --git a/codec2/branches/0.7/src/codebook/lsp7.txt b/codec2/branches/0.7/src/codebook/lsp7.txt
new file mode 100644 (file)
index 0000000..839cbfd
--- /dev/null
@@ -0,0 +1,19 @@
+1 16
+1500
+1600
+1700
+1800
+1900
+2000
+2100
+2200
+2300
+2400
+2500
+2600
+2700
+2800
+2900
+3000
+
+
diff --git a/codec2/branches/0.7/src/codebook/lsp8.txt b/codec2/branches/0.7/src/codebook/lsp8.txt
new file mode 100644 (file)
index 0000000..d9880c9
--- /dev/null
@@ -0,0 +1,11 @@
+1 8
+2300
+2400
+2500
+2600
+2700
+2800
+2900
+3000
+
+
diff --git a/codec2/branches/0.7/src/codebook/lsp8910.txt b/codec2/branches/0.7/src/codebook/lsp8910.txt
new file mode 100644 (file)
index 0000000..759136b
--- /dev/null
@@ -0,0 +1,65 @@
+3 64
+2.048073  2.534502  2.645915
+2.019670  2.269744  2.605462
+1.961101  2.329646  2.562857
+1.968573  2.532712  2.616918
+2.183480  2.514381  2.629582
+2.259379  2.516615  2.620410
+2.172791  2.462460  2.567064
+2.097666  2.303933  2.421685
+2.052990  2.353242  2.546992
+2.043642  2.232362  2.499262
+2.106151  2.393131  2.488401
+2.099167  2.437862  2.558655
+2.013877  2.422875  2.530071
+2.033848  2.483776  2.584598
+2.114474  2.516856  2.602372
+2.229214  2.584056  2.678855
+2.131151  2.584299  2.674845
+1.472721  2.477091  2.630241
+2.010907  2.598415  2.682989
+2.353653  2.524066  2.619773
+2.419897  2.623938  2.699605
+2.319080  2.602148  2.689044
+1.860342  2.503881  2.616576
+1.910517  2.386693  2.610126
+1.748689  2.371809  2.496542
+1.618495  2.403425  2.554956
+1.844073  2.437026  2.533443
+1.924810  2.388543  2.502698
+1.937227  2.258363  2.501697
+1.687554  2.209123  2.545239
+1.851950  2.278628  2.565632
+1.868154  2.330150  2.444883
+1.874180  2.213118  2.351940
+1.757311  2.030626  2.433836
+1.650306  2.152371  2.243421
+1.612794  1.884686  2.339313
+1.745431  2.278895  2.389449
+1.590923  2.304155  2.408510
+1.475982  2.275548  2.509897
+1.508695  2.045463  2.455520
+1.872054  2.061777  2.246202
+1.983947  2.159155  2.445535
+1.745180  2.483765  2.593698
+1.900116  2.079600  2.407479
+1.841672  2.167042  2.486827
+1.932912  2.148464  2.569850
+2.134174  2.363673  2.584252
+2.106094  2.450645  2.638417
+1.954135  2.460313  2.666512
+1.907634  2.573801  2.674025
+1.625579  2.539569  2.656363
+1.785866  2.572616  2.676082
+1.798447  2.376454  2.624298
+2.020033  2.397244  2.619868
+1.946581  2.468791  2.564185
+2.008920  2.342400  2.469132
+1.983846  2.271044  2.395408
+1.988039  2.154150  2.317920
+2.077197  2.216622  2.389101
+2.117255  2.283907  2.512242
+2.177233  2.334622  2.458268
+2.214655  2.425510  2.620013
+2.199931  2.390272  2.520731
+2.271755  2.448682  2.552649
diff --git a/codec2/branches/0.7/src/codebook/lsp9.txt b/codec2/branches/0.7/src/codebook/lsp9.txt
new file mode 100644 (file)
index 0000000..7e159af
--- /dev/null
@@ -0,0 +1,11 @@
+1 8
+2500
+2600
+2700
+2800
+2900
+3000
+3100
+3200
+
+
diff --git a/codec2/branches/0.7/src/codebook/lspdt.txt b/codec2/branches/0.7/src/codebook/lspdt.txt
new file mode 100644 (file)
index 0000000..3041c40
--- /dev/null
@@ -0,0 +1,1025 @@
+10 1024
+0.030214  0.087393  0.142625  0.204661  0.257804  -0.327911  -0.183571  -0.089661  -0.082036  0.025268
+-0.033840  -0.025382  -0.057646  -0.130479  -0.015028  0.079375  0.023958  -0.042556  0.025167  0.021076
+-0.073420  -0.085623  -0.081920  -0.021710  0.198196  0.213754  0.075391  0.063551  0.148094  0.083181
+-0.041674  -0.061116  0.004116  0.233349  0.204616  0.256279  0.009337  0.091744  0.269872  0.132698
+0.052679  0.067955  -0.025147  -0.235718  -0.347647  -0.215019  -0.083526  -0.130404  -0.047058  -0.054917
+0.092221  0.063837  -0.170673  -0.451538  -0.521231  -0.416413  -0.184510  -0.192721  -0.288125  -0.164375
+0.006250  0.010339  0.023315  0.024258  0.142234  -0.023847  -0.063944  -0.036040  -0.024266  -0.035798
+-0.020755  -0.016434  0.023770  0.104903  0.239031  0.135658  0.065827  0.089679  0.036949  0.038796
+0.001522  -0.000005  -0.007255  0.023717  0.061706  0.088603  0.132864  0.102913  0.070440  0.039429
+0.001258  0.000603  0.009813  -0.001694  0.005052  0.011061  0.010448  0.056755  0.026658  0.027529
+0.004858  0.005431  0.002243  0.029427  0.009784  -0.059830  -0.056032  -0.073592  -0.040853  -0.021115
+-0.002325  -0.002455  -0.001604  -0.003935  0.006266  -0.017584  -0.006597  -0.081987  -0.029412  -0.020403
+0.003736  0.007595  0.003562  0.002215  0.038401  0.037702  0.057607  0.034182  0.061992  0.048736
+0.004115  0.003260  0.006737  0.006828  0.006008  0.017779  0.052389  0.095893  0.035851  0.020458
+0.004843  0.003379  -0.002271  0.004288  -0.016977  -0.071627  0.001830  -0.009209  -0.058428  -0.015245
+0.003678  0.005406  -0.012417  -0.039528  -0.027589  -0.087800  -0.041500  -0.100739  -0.090422  -0.098089
+-0.006186  -0.001434  -0.000199  0.014062  -0.004642  -0.003832  -0.055350  -0.074491  -0.108642  -0.095712
+-0.062269  -0.084747  -0.093203  0.112714  0.168813  0.101357  -0.009236  0.035940  0.011374  0.010907
+-0.038490  -0.040302  -0.031450  0.072307  0.185540  0.151074  0.158257  0.172376  0.166965  0.130124
+0.024048  0.030137  0.067105  0.160669  0.280202  0.278831  -0.002242  -0.103298  -0.003234  -0.000831
+0.008185  -0.000241  -0.014130  -0.061306  -0.110704  -0.109917  -0.202806  -0.452824  -0.041963  -0.019083
+-0.033700  -0.101513  -0.377325  -0.378713  -0.270962  -0.241062  0.104950  0.068237  -0.095025  -0.089500
+-0.183828  -0.244672  -0.355586  -0.243172  -0.240034  -0.087034  0.217483  0.165276  -0.008586  0.016224
+0.060764  0.066368  0.055613  0.148443  0.151302  0.049670  -0.047198  -0.126028  0.102264  0.107377
+0.140469  0.157391  0.161672  0.291984  0.153641  0.206359  0.231297  -0.073781  -0.033312  0.032766
+0.037540  0.039307  0.047739  0.107267  0.132807  0.107693  0.042636  -0.020420  -0.007591  0.008364
+0.002125  0.003080  0.000635  0.016240  0.059410  -0.006820  -0.024315  0.045605  0.005290  0.013830
+0.001139  0.003902  -0.012139  -0.035295  -0.049090  -0.084221  -0.087992  0.088975  -0.009197  -0.025713
+0.001317  -0.001288  0.003646  -0.006079  -0.003929  -0.018558  -0.039808  -0.029046  -0.076413  -0.005992
+-0.001049  -0.001621  0.017015  -0.009393  -0.008427  0.037335  0.028549  0.022359  0.064850  0.021301
+0.002963  -0.003009  0.009769  0.088745  0.016440  0.046255  0.050722  0.016491  0.102227  0.050278
+0.000385  0.004489  -0.005224  0.040397  0.015902  -0.044661  -0.134052  -0.164920  -0.013437  0.018856
+0.000290  -0.014145  -0.104000  -0.098790  -0.086725  -0.130471  -0.147043  -0.075812  -0.148688  -0.129942
+0.003604  -0.001264  -0.025302  -0.034198  -0.106991  0.017613  0.131491  0.142840  -0.079925  -0.049736
+0.017871  0.046436  0.144657  0.014979  0.031321  0.118093  0.144907  0.171921  -0.007429  0.020121
+0.142113  0.303403  0.318919  -0.068887  0.044887  0.169177  0.174048  0.135839  0.202516  0.173113
+-0.029056  -0.028800  0.024667  0.151956  0.143322  0.182400  0.182489  0.061789  0.433122  0.337578
+-0.028250  -0.053393  -0.035536  0.350750  0.353500  -0.226571  -0.259464  0.038214  -0.015607  -0.023786
+0.046375  0.008135  -0.162187  -0.193417  0.024875  -0.111500  -0.262979  -0.088667  -0.355750  -0.246906
+-0.009274  0.006357  0.017345  -0.232327  -0.217667  -0.057851  -0.091655  -0.007185  -0.045440  -0.041536
+-0.012885  -0.008218  -0.020385  -0.037269  -0.156679  0.011269  0.055346  -0.146987  0.100295  0.142756
+0.005348  -0.001366  -0.027875  0.004330  -0.023464  -0.004911  -0.020777  -0.216223  -0.080589  -0.144991
+0.009843  0.011329  0.028114  -0.003471  0.016571  0.057543  0.073629  -0.089014  0.018186  -0.106900
+-0.001929  -0.013671  0.019657  0.021129  0.096800  0.106571  0.054843  0.074429  0.010871  0.280614
+-0.014482  -0.008564  -0.019482  -0.051300  -0.020509  -0.035591  0.020536  0.039991  0.078036  0.278591
+0.000642  -0.000081  -0.000885  -0.022764  -0.011689  0.014764  -0.015169  -0.002595  0.001311  -0.189811
+0.002994  0.009073  0.002983  -0.006096  -0.004567  -0.008534  -0.067904  -0.029798  -0.104129  -0.246034
+0.032685  0.027630  0.024074  0.079759  0.095704  -0.028565  0.018815  0.037528  -0.002676  0.038213
+0.009344  0.011533  0.016039  0.052300  0.033783  0.042361  0.019544  0.017133  0.100200  0.159617
+-0.001124  0.002658  0.005416  0.011698  0.014386  -0.031792  -0.046644  -0.050950  0.071530  0.002807
+0.008698  0.022123  -0.003025  0.021395  -0.003148  -0.121864  -0.001346  -0.023710  0.186920  0.047278
+-0.006202  -0.000833  -0.039193  -0.118149  -0.047640  -0.050868  0.046018  0.032368  0.254702  0.106246
+-0.027820  -0.044190  0.017040  -0.094260  -0.087840  0.088060  0.009070  -0.032400  -0.270150  -0.055890
+-0.011581  -0.025468  0.025290  -0.017984  0.153194  0.222645  0.073710  0.045758  -0.472597  -0.306532
+-0.014798  -0.020808  -0.008481  0.007394  -0.031663  0.104115  0.064538  0.072702  -0.218635  -0.153481
+0.027705  0.091167  0.045423  0.146718  0.020526  -0.143910  0.073154  0.128346  0.529487  0.308731
+0.030128  0.035233  -0.070384  -0.018698  -0.075535  -0.220372  -0.079291  -0.111209  0.256581  0.101105
+-0.004150  -0.008144  -0.006750  0.004239  0.028372  -0.001983  -0.040928  -0.019661  -0.338700  -0.169967
+-0.004707  -0.006595  0.004500  0.026767  -0.029819  0.169034  -0.002560  0.033819  -0.088190  -0.050612
+-0.006173  0.002647  -0.001513  -0.015320  0.010533  0.053747  0.082887  0.059393  0.183313  0.057387
+-0.000616  -0.004636  0.006606  0.024414  0.051409  0.021773  0.060692  -0.006798  -0.043394  -0.038828
+-0.008696  -0.000618  0.042500  0.037216  0.071137  -0.060206  0.015157  -0.015108  -0.045157  -0.016010
+0.007144  0.005253  0.010336  0.010548  0.009610  -0.013199  -0.071445  0.067541  -0.007733  -0.059884
+0.000036  0.002778  -0.003443  -0.009706  -0.047371  -0.014098  -0.101768  -0.080778  -0.068814  -0.051469
+0.003981  0.007944  0.004537  -0.030662  -0.110694  -0.136056  -0.114219  -0.178281  -0.146781  -0.054756
+0.018125  0.014090  -0.006389  0.069208  -0.085715  -0.056646  0.058569  0.044424  0.070618  0.039938
+0.003460  0.000508  0.014437  0.031119  -0.038722  0.008254  0.073587  0.122825  0.189159  0.163968
+-0.008440  -0.013664  -0.024448  -0.034284  -0.116739  0.058746  -0.085433  -0.144358  -0.008843  0.005045
+-0.014613  -0.019969  -0.015219  -0.052462  0.007394  0.052406  -0.003019  0.003319  -0.151588  -0.158712
+-0.005918  -0.001090  0.014866  -0.032642  0.009075  -0.008806  0.190575  0.273537  -0.036231  -0.026127
+0.012026  0.021332  0.014184  0.012795  0.060216  0.034547  0.069368  0.168979  0.131626  0.105816
+-0.003224  0.001730  -0.013697  -0.012401  0.010480  0.043882  -0.202132  -0.213039  -0.017875  -0.005474
+0.002079  -0.002329  -0.014679  0.042800  -0.053314  -0.068564  -0.097750  -0.222214  -0.053271  -0.046371
+0.002171  0.004986  0.011274  0.009952  0.005562  -0.001692  0.073185  -0.143664  0.102568  0.088301
+-0.012564  0.010821  -0.012821  -0.029090  0.047154  0.091513  -0.049474  0.180192  0.086333  0.017423
+0.002909  -0.028327  -0.148755  -0.080791  -0.206173  -0.356100  -0.022609  -0.061236  -0.157227  -0.113336
+-0.079046  -0.172583  -0.199454  -0.048157  -0.225296  -0.309278  -0.112435  -0.235102  -0.046222  0.006269
+-0.045984  0.018047  0.164258  0.202680  0.263172  0.566937  0.206742  0.329023  0.292391  0.123086
+0.019192  0.112609  0.335853  0.302641  0.400333  0.472173  0.329000  0.377808  0.018436  0.015635
+0.026673  0.004462  -0.162096  0.037442  0.079019  -0.215942  -0.060442  -0.189962  -0.162654  -0.052058
+0.022508  -0.090762  -0.239238  -0.171444  -0.440913  -0.380135  -0.159310  -0.258468  -0.129913  -0.088238
+-0.028069  -0.014437  -0.010850  -0.050656  -0.285669  -0.268906  -0.101344  -0.029094  -0.023888  -0.023181
+0.004862  0.006414  0.001345  -0.063621  -0.052741  -0.180931  -0.238224  0.173172  -0.092862  -0.104207
+0.004697  0.026947  0.086934  0.072974  0.262303  0.283618  -0.096250  0.027066  0.188803  0.149026
+-0.030421  -0.042868  -0.039697  -0.017447  0.021250  0.061789  0.107342  -0.302829  0.010276  0.037605
+-0.002333  0.000385  -0.012577  -0.066256  -0.013564  -0.019269  -0.036936  -0.418756  -0.123474  -0.102654
+0.008575  0.004952  0.005500  0.052904  0.022890  -0.023158  0.154486  0.176897  -0.002651  0.045822
+-0.010061  -0.004970  0.027457  0.013524  0.049537  0.110189  0.103811  0.291598  0.041030  0.020659
+-0.010786  0.000000  -0.026364  -0.123214  -0.022757  -0.047179  -0.121571  -0.019329  -0.032657  0.011214
+-0.011300  -0.010793  -0.028993  -0.133667  -0.052173  -0.109933  -0.172947  -0.209893  -0.044780  0.033867
+-0.000296  0.002438  0.000217  0.048783  -0.025752  -0.011934  0.048301  0.018323  -0.006841  -0.006119
+-0.019991  -0.026871  0.043069  0.164517  0.080086  0.197466  0.212026  0.240767  0.076388  -0.010440
+0.021657  0.030662  0.048081  0.141298  0.130939  0.132485  0.191273  0.032157  -0.015273  -0.007192
+0.007325  0.011669  -0.012494  -0.100969  -0.153569  -0.106119  -0.121781  -0.157719  0.033100  0.027981
+-0.020244  -0.020987  0.002609  -0.130609  -0.150897  -0.197853  -0.238596  -0.012750  -0.034442  -0.025506
+0.003443  0.006460  0.003278  0.014966  0.037915  0.007864  -0.006432  0.067182  -0.049813  -0.092665
+-0.007296  -0.004959  0.010561  0.022714  0.059469  0.054949  0.248225  -0.023347  -0.184122  -0.075653
+-0.076207  -0.095685  -0.078185  0.012696  0.049402  0.032489  0.050826  0.081348  0.123554  0.104446
+0.033461  0.077447  0.156368  0.110447  0.152500  0.047816  -0.081474  0.154829  0.174026  0.149316
+-0.015549  0.010430  0.074415  0.118507  0.195859  0.269563  -0.010204  0.049169  0.015049  -0.026859
+0.040961  0.062588  0.039324  0.109118  0.247696  0.324627  0.319804  -0.049529  -0.021539  -0.003265
+0.043783  0.026833  0.085183  0.210517  -0.340767  -0.259850  0.112733  0.034617  0.036000  0.067850
+0.083529  0.079779  0.005183  -0.208740  -0.354154  -0.443635  -0.417827  0.039221  -0.039269  -0.078413
+0.021417  0.026286  0.001595  -0.051750  -0.054988  -0.357821  -0.359548  -0.067250  -0.058357  -0.043310
+-0.018575  -0.013198  0.025019  0.058547  0.056660  0.223057  -0.061415  0.017830  0.007094  -0.060821
+0.001306  -0.001291  0.017164  0.053478  -0.007545  0.118478  0.178015  0.100440  -0.004933  -0.053530
+-0.001737  -0.002491  0.000614  0.058211  0.043728  0.023728  0.111026  0.098482  -0.078500  -0.067474
+0.004230  0.005440  0.003488  0.008855  -0.008145  -0.014681  -0.009133  0.045972  0.163347  0.068315
+-0.010959  -0.005849  -0.007315  -0.014390  0.006158  0.090856  -0.012445  0.022890  0.158986  0.056925
+0.000749  -0.001213  -0.006018  -0.004422  -0.009865  -0.007207  -0.017749  -0.000249  -0.092991  -0.109251
+0.005029  -0.005757  -0.004360  -0.009669  -0.008691  -0.071544  -0.097934  -0.110368  -0.185699  0.011404
+-0.007715  0.003778  -0.031069  -0.036444  -0.025951  -0.044931  -0.047000  -0.135299  0.146458  0.088236
+0.001761  0.000421  0.007793  0.012389  0.010661  0.025464  0.009525  0.012075  0.122568  0.020621
+0.001769  0.004204  0.008458  0.013602  -0.004023  0.019630  0.023745  0.041588  -0.088407  -0.073875
+0.004633  0.004633  0.020223  -0.006181  0.021078  0.115759  0.078301  0.039090  -0.092398  -0.076898
+-0.002416  -0.001845  0.000173  -0.038956  0.011274  0.029049  0.065712  0.009987  0.029796  0.005615
+-0.002492  -0.004292  -0.031175  -0.060358  -0.026058  -0.109742  -0.029850  -0.074383  -0.080908  0.042942
+-0.002215  -0.002694  -0.002368  0.008698  -0.017256  -0.012021  -0.009492  0.009773  -0.044764  0.018318
+-0.023070  -0.002325  -0.026219  0.008693  -0.018991  0.021789  0.004035  0.107798  0.332026  0.079456
+0.000155  -0.001041  -0.008629  -0.012809  -0.005175  0.001830  -0.000088  0.085892  0.085634  0.039732
+-0.008221  -0.024926  -0.014309  0.013941  -0.022912  -0.097382  -0.000265  -0.141250  -0.313073  0.018647
+0.002872  -0.003733  -0.009488  0.016860  -0.040814  -0.091547  0.116430  -0.175616  -0.024884  0.040326
+-0.008020  0.021970  0.088080  0.111170  0.057580  0.171240  0.092760  0.302830  0.373290  0.143470
+-0.016063  -0.022650  0.036400  -0.175538  -0.357975  -0.198500  -0.256112  -0.126062  0.144225  0.100450
+0.075009  0.047603  -0.037655  -0.129095  -0.251948  -0.360069  -0.312207  -0.445293  -0.496000  -0.212534
+-0.032464  -0.028929  -0.006339  0.207125  0.557589  0.518964  0.543321  0.249214  -0.000589  0.026018
+-0.054765  0.032643  0.199878  0.324673  0.502725  0.640980  0.604908  0.581459  0.316602  0.184429
+0.115611  0.119583  -0.062069  -0.135861  -0.395542  -0.371653  -0.019708  -0.018028  0.313139  0.152028
+0.054066  0.018539  -0.058382  -0.216724  -0.636342  -0.630671  -0.271105  -0.194711  0.044303  0.016355
+0.060100  0.045158  0.113933  0.056442  0.023808  -0.021950  -0.399325  -0.126858  -0.111158  -0.110000
+0.025462  0.025667  0.060218  0.078923  0.231410  0.120885  -0.330885  -0.370833  -0.307731  -0.152218
+-0.010160  -0.013991  -0.024783  -0.012509  0.003821  0.062425  0.184236  -0.088340  -0.045774  -0.025868
+-0.027839  -0.005367  0.082450  0.116321  0.161436  0.232105  0.309069  0.377041  0.202248  0.091963
+-0.028529  -0.008750  -0.003904  -0.076702  0.130596  0.250337  0.239163  0.413154  0.135740  0.016308
+-0.032553  -0.029079  0.012000  -0.010605  0.068842  0.005237  -0.262474  0.205684  -0.058632  -0.013079
+0.038676  0.039985  0.026735  0.179235  0.105368  -0.038294  -0.291868  -0.364471  0.002426  0.050265
+0.082714  0.051690  0.067024  0.003524  -0.244452  0.071381  0.217595  -0.169405  0.056619  0.101190
+-0.014476  -0.009119  -0.074310  -0.216810  -0.273786  -0.212286  0.358714  0.308857  -0.015429  0.012619
+0.055256  0.077333  0.025308  0.062231  0.184090  -0.211680  0.056308  0.154897  0.052615  0.041731
+0.016750  -0.006848  -0.039634  0.201089  0.167759  0.022482  0.016536  0.019232  0.241009  0.112500
+-0.031711  -0.053316  -0.067474  -0.301500  -0.215763  0.395053  0.006316  -0.019132  -0.259737  -0.234632
+-0.033432  -0.059386  0.019295  -0.121341  -0.094205  0.239114  -0.043330  -0.044818  -0.353034  -0.236864
+0.089880  0.101220  0.058980  0.407420  0.200060  -0.299180  -0.042020  -0.004800  0.348860  0.226780
+0.063535  0.105081  -0.007512  0.121267  0.036744  -0.301674  0.020547  0.087756  0.279884  0.140686
+-0.036721  -0.075988  -0.116081  -0.208663  -0.207733  0.048419  0.044802  -0.027035  -0.141651  -0.105349
+-0.028942  -0.024733  -0.114267  -0.168860  0.001767  0.024430  -0.182547  0.006686  0.003116  0.012442
+-0.010038  -0.007665  -0.017722  -0.016968  -0.001627  -0.027013  -0.216025  -0.041468  0.037778  0.051987
+0.002445  0.000783  0.004083  0.035189  0.009283  -0.014559  0.097984  -0.008587  0.066528  0.081354
+-0.001479  0.004418  0.038329  0.046507  0.011096  0.003842  0.252521  0.015459  0.023130  0.096048
+0.000695  -0.002314  0.000295  -0.005229  -0.000771  0.037271  -0.112343  0.036733  -0.082638  -0.066776
+0.005429  -0.000423  -0.015468  0.016917  0.006423  0.007667  -0.216154  -0.041026  -0.113365  -0.150474
+0.002106  0.000589  0.001199  0.014114  -0.001144  0.009093  -0.022373  -0.010568  -0.001915  -0.092614
+-0.007700  -0.009280  0.004070  0.005150  0.014830  0.006340  0.147690  0.018210  0.104050  0.000040
+-0.018965  -0.031535  -0.027744  -0.002988  -0.064337  -0.003465  0.084384  0.036512  0.074326  -0.066721
+-0.001037  0.001463  -0.032152  -0.024066  -0.009885  -0.038361  -0.027086  -0.071250  0.012451  -0.019582
+0.000221  -0.003004  0.008726  -0.003018  0.005336  0.011566  0.030712  0.007863  0.038854  0.107819
+-0.001273  -0.002756  0.004256  0.000318  -0.005261  0.040545  0.000835  0.036057  -0.047239  0.077119
+-0.001737  -0.003442  -0.007500  -0.003781  -0.017844  -0.035866  -0.074321  -0.000629  -0.064170  -0.047701
+-0.000865  -0.001496  0.000354  -0.007527  0.041396  -0.031923  -0.006762  -0.033335  -0.018812  -0.025296
+0.004362  0.001993  0.008519  0.001571  0.017772  -0.017836  0.074396  0.044884  0.014146  0.013418
+0.005041  0.003486  0.002358  0.030174  0.004454  -0.017583  0.066216  0.011294  -0.018147  0.049486
+0.098609  0.056130  -0.083848  0.065065  0.035913  -0.070478  0.000326  -0.083761  0.033696  0.087087
+-0.006835  -0.006643  -0.002096  0.013983  -0.004148  0.007100  -0.049617  -0.069874  0.144304  0.050204
+-0.036358  -0.027594  0.042113  0.034425  0.020057  0.114915  -0.039651  -0.027500  0.117424  0.033953
+-0.036453  -0.048538  -0.012575  -0.072726  0.092472  0.117302  0.013311  -0.088906  -0.205519  -0.027972
+0.080906  0.049094  -0.253469  -0.093781  0.050094  0.012375  0.052594  -0.018031  -0.266562  -0.083219
+0.037921  0.053237  0.031947  0.055237  -0.065842  -0.081947  -0.089368  0.034605  0.020500  -0.208053
+0.051783  0.166457  0.347870  0.082783  -0.110196  -0.038891  0.095239  0.377783  0.013913  -0.021783
+-0.000538  0.005625  0.035154  -0.008760  0.017404  0.027721  0.112288  0.256471  0.104548  0.212971
+-0.026529  -0.052029  -0.034824  0.046559  0.129794  0.208882  -0.038324  -0.364971  0.089353  0.164235
+-0.088931  -0.130208  -0.082486  -0.052222  -0.003667  0.174014  -0.141236  -0.257597  -0.115292  -0.141833
+0.002280  0.010667  0.014080  -0.006000  -0.023200  -0.172953  0.117553  0.058087  -0.019380  -0.005773
+0.101485  0.125258  0.048667  0.014303  -0.150364  -0.389121  -0.019788  0.181545  0.030909  0.035652
+-0.021477  -0.026577  -0.008262  -0.001515  0.036408  -0.184946  -0.200123  -0.032215  -0.062277  -0.037985
+-0.030958  -0.037604  -0.002083  -0.009073  -0.000729  0.256958  0.014604  -0.118438  -0.055438  -0.000802
+-0.027083  -0.051708  -0.031653  -0.091722  -0.062014  0.324194  0.196431  0.120806  0.034556  -0.031875
+0.009636  0.010093  0.017856  -0.005153  0.040102  0.040983  -0.066271  -0.099381  0.058881  0.007881
+0.132500  0.150554  0.177839  0.235321  -0.002214  -0.252696  -0.331750  -0.136554  0.123411  0.067375
+0.023070  0.035640  0.053767  0.124349  0.040721  0.026500  0.116186  0.271256  0.194547  0.035500
+0.001511  0.030878  0.008922  -0.003600  -0.014778  -0.022233  0.320467  0.462356  0.113289  0.039033
+-0.002833  0.002567  -0.035367  -0.121433  0.120900  -0.298700  -0.125667  0.031267  0.204133  0.227500
+-0.087482  -0.144643  -0.111518  -0.391786  -0.326607  -0.065250  -0.175911  -0.304214  -0.538625  -0.389071
+-0.028617  -0.069150  -0.040133  -0.101550  -0.441367  0.076333  -0.076517  -0.169083  -0.356467  -0.191600
+-0.037909  -0.026932  -0.005739  -0.064750  0.012568  0.065080  0.130000  0.049648  0.036273  0.180920
+0.020429  0.047571  0.156480  0.491847  0.329459  0.164786  0.201163  0.245724  0.411480  0.191173
+0.046603  0.153465  0.329621  0.480948  0.254552  -0.051948  0.006879  0.124345  0.195052  0.064207
+0.064943  0.049343  -0.109214  -0.169521  -0.139050  -0.326821  -0.120729  -0.222421  -0.199921  -0.054193
+0.097793  0.029086  -0.172138  -0.229103  -0.186569  -0.017190  -0.131138  -0.189759  -0.084310  -0.040586
+-0.028429  -0.033558  -0.010962  -0.037135  0.003635  0.259936  0.076269  0.121449  0.158077  0.029449
+-0.002591  -0.002159  0.034122  0.053927  0.035512  0.072043  0.003890  0.079787  -0.038762  -0.037805
+-0.007474  -0.005542  -0.016305  -0.025963  -0.010647  -0.028416  -0.005437  -0.082868  -0.089074  -0.016589
+0.007697  -0.002359  -0.008169  0.015887  0.022697  0.031535  0.046972  -0.041028  -0.012831  0.021176
+-0.003731  0.003090  0.059583  0.103763  0.022141  0.115519  0.029179  0.083558  0.049718  0.018327
+-0.008056  0.004766  -0.027331  -0.029758  -0.110411  -0.045073  -0.045476  -0.005403  -0.023113  -0.110976
+-0.059971  -0.081745  -0.041696  -0.042245  -0.137373  -0.157725  -0.148039  -0.236588  -0.112608  -0.111529
+-0.019759  -0.023935  -0.006306  0.012102  -0.020259  0.011241  0.091259  -0.050176  -0.004454  0.092991
+-0.001988  0.003628  0.075360  0.059779  0.041337  0.052640  0.055174  0.421140  0.029523  0.020570
+-0.005745  -0.007896  0.008038  0.007830  0.020094  0.003302  -0.112208  0.117764  -0.012943  0.025623
+-0.002147  -0.003566  -0.004250  0.013301  -0.034485  -0.005022  -0.046176  -0.214603  0.102353  0.015221
+0.004726  0.003258  0.006605  0.011677  0.020250  0.045435  0.033323  -0.045040  0.079436  0.047145
+-0.003679  -0.016330  -0.003062  0.005607  -0.008018  0.005491  -0.074223  -0.197536  -0.323250  -0.114929
+-0.008114  -0.048614  -0.099018  -0.037044  -0.049912  -0.124193  -0.164088  -0.363325  -0.310351  -0.216658
+-0.019828  -0.024500  -0.046828  -0.065414  -0.234859  -0.152266  -0.080797  -0.063445  0.169914  0.076594
+-0.051619  -0.044857  -0.015643  -0.088929  -0.162429  0.028500  0.197690  0.432952  0.321357  0.112452
+-0.021411  -0.009625  0.035554  0.044625  0.280000  0.367500  0.594429  0.622232  0.012473  -0.010839
+0.065200  0.025433  -0.185200  0.034333  0.172600  0.112033  0.257900  -0.247667  -0.057967  -0.027133
+0.052604  -0.015573  -0.146427  -0.089854  -0.148490  -0.284812  -0.383000  -0.623250  -0.117167  -0.030635
+0.010178  0.001711  0.074167  0.051633  -0.081333  -0.014689  -0.139767  0.036767  0.011200  -0.029811
+-0.011123  -0.013965  0.041360  -0.006649  0.107246  0.104482  0.001956  0.101281  0.048351  0.086842
+-0.008518  -0.006877  -0.014095  -0.045659  -0.011573  -0.014714  0.010405  -0.025550  -0.044900  -0.090964
+-0.006465  -0.003227  -0.017219  -0.067123  -0.000727  -0.022958  -0.029050  -0.029381  -0.045496  -0.028827
+0.002947  0.000654  0.007673  0.014638  0.011365  -0.007292  0.023487  -0.006947  0.063934  0.020057
+0.010012  0.006801  0.018313  0.044687  0.014964  0.002892  0.129042  0.031343  -0.116873  -0.021072
+0.003000  -0.006600  0.001167  0.005844  -0.004389  -0.007944  0.020622  0.008278  -0.087733  0.134178
+0.021690  0.021905  -0.002034  -0.020750  -0.060767  -0.101422  -0.137379  0.037319  0.169293  0.090086
+0.010665  0.024394  0.007065  -0.032147  -0.152188  -0.073382  -0.073171  -0.038235  0.107412  -0.021276
+-0.010141  -0.007592  -0.000345  0.009176  -0.030162  -0.013493  0.092930  -0.046155  -0.122746  -0.100711
+-0.019129  -0.019053  -0.007300  -0.056406  -0.006559  -0.009906  0.096847  -0.014329  -0.057535  -0.002618
+-0.006023  -0.003099  -0.007942  -0.055076  -0.022442  -0.017302  -0.024372  0.024244  -0.052012  -0.020442
+-0.001764  -0.002947  0.012634  0.007509  -0.001444  0.040596  -0.029075  -0.010115  -0.013671  -0.020975
+0.004643  0.003214  0.033058  0.038091  0.032539  0.186831  0.011903  0.050208  0.084909  0.043773
+0.011918  0.006448  0.019332  0.038603  0.008931  0.023879  0.000966  -0.007513  -0.060487  -0.017276
+0.000802  -0.003381  -0.057722  -0.102310  -0.043278  -0.232444  -0.004675  -0.075857  0.067659  0.048516
+0.022830  0.036489  -0.018523  -0.039295  -0.088034  -0.234284  0.067557  0.032761  0.157216  0.140830
+-0.027531  -0.031500  -0.009347  -0.015867  -0.129592  -0.069816  0.041286  0.139673  0.075357  0.036143
+-0.058598  -0.085457  -0.062185  -0.035750  0.018500  0.338848  0.211783  0.151435  0.306717  0.144859
+0.003990  -0.014490  0.030125  0.200990  0.394031  0.336115  0.020583  -0.001042  -0.193021  -0.130427
+0.065655  0.064369  0.066869  0.063988  0.025500  -0.247405  -0.359155  -0.222571  -0.383119  -0.206083
+0.011047  0.014733  0.009627  -0.060247  -0.208713  -0.198127  -0.266340  -0.261493  -0.012473  0.008893
+0.000814  0.006486  -0.013586  -0.057714  -0.089071  0.008514  0.357029  0.222214  0.421671  0.320100
+-0.024246  -0.015106  -0.024444  -0.022761  -0.016366  0.051380  0.213641  0.222944  0.118190  0.062296
+0.012047  -0.000609  -0.036078  -0.112906  -0.110055  -0.154563  -0.341305  -0.163672  -0.308563  -0.154023
+-0.011217  -0.041671  -0.037184  0.044184  -0.038086  -0.072882  -0.274671  -0.294520  -0.121211  -0.088862
+0.014457  0.007743  -0.028314  0.002743  0.020600  0.112271  0.258557  -0.115857  0.143500  0.099457
+-0.018966  -0.050190  -0.014914  0.014000  -0.078241  0.058759  0.087776  0.027276  -0.022517  -0.286052
+0.015717  0.022902  -0.000717  0.002457  -0.024989  -0.124141  0.054065  0.056543  -0.092696  -0.160391
+-0.018395  -0.021302  0.012070  0.068942  0.108314  0.043151  0.198256  0.135686  0.181523  0.310233
+0.017176  0.022135  0.008282  0.029400  0.007165  -0.004400  0.194371  0.056929  0.140588  0.187412
+0.007560  -0.003000  -0.013083  -0.030560  -0.112345  -0.029583  -0.192048  -0.133107  -0.013190  -0.218952
+-0.087780  -0.085585  0.018256  -0.057634  -0.070061  0.047000  -0.109598  0.010146  -0.034585  -0.054207
+-0.051962  -0.034558  0.115365  -0.047654  -0.014750  0.280192  0.086308  0.151019  0.024577  0.069750
+-0.027452  -0.034437  0.079937  0.016984  0.081587  0.218762  0.005008  0.020849  -0.120206  -0.055198
+0.004566  -0.000187  -0.024777  0.003825  -0.020386  -0.010813  -0.061428  -0.323717  -0.024928  0.002482
+0.048830  0.060170  -0.076182  -0.000045  -0.007886  -0.244114  -0.021636  -0.240284  -0.042909  -0.004136
+0.124042  0.152875  -0.058896  0.011563  -0.048792  -0.169938  -0.016604  0.114979  -0.079646  -0.131375
+-0.005101  0.002550  0.028239  0.061706  0.167417  0.108211  0.158606  0.204560  -0.032014  -0.016528
+-0.038852  -0.045639  0.037361  0.013083  0.067556  0.111167  0.102907  0.062259  -0.053231  0.045361
+-0.020021  -0.007264  0.011107  -0.120686  0.005171  0.012750  -0.022007  -0.000193  0.053871  0.038593
+-0.003418  -0.000870  0.003767  -0.016205  0.009301  0.030007  -0.081452  -0.011801  0.083904  0.127952
+0.000346  0.000453  0.005026  -0.005474  0.004017  -0.003761  -0.021564  -0.075017  0.036103  0.086560
+-0.034250  -0.043723  -0.035518  -0.196161  -0.024098  0.035554  -0.110509  -0.210902  -0.186991  -0.051268
+0.012764  0.008126  0.008109  -0.002046  -0.022787  -0.052557  -0.209782  -0.120937  -0.224333  -0.158891
+0.010952  0.033119  0.035786  0.219857  0.015119  0.029857  0.223833  0.355214  0.024310  -0.017286
+-0.000092  0.021000  0.008250  -0.044566  0.023566  0.268224  0.521763  0.535605  0.388184  0.227566
+-0.013077  0.028327  -0.022212  -0.192231  0.035212  0.011481  -0.091385  -0.101538  0.238673  0.096962
+0.052638  0.034319  -0.011468  0.007266  -0.038830  -0.332064  -0.312585  -0.389660  -0.121340  -0.025660
+0.118404  0.100558  -0.021212  -0.149231  -0.007327  -0.069269  -0.021673  -0.087750  -0.178423  -0.135250
+-0.020158  -0.019921  0.034553  0.035342  0.041197  0.112684  0.119158  0.372250  -0.188487  -0.175645
+0.009542  -0.006500  0.088917  0.264896  0.208250  0.193687  0.060438  0.370917  -0.009708  -0.054688
+-0.036500  -0.065600  -0.040133  0.217689  0.211800  0.110133  -0.132022  -0.159067  0.053744  0.049333
+0.019846  0.034692  -0.009000  -0.265538  -0.207288  -0.026212  0.159212  -0.120192  -0.015558  0.029442
+0.050740  0.074144  0.038712  -0.225173  -0.276789  -0.197058  0.093067  0.116760  0.000808  -0.011702
+0.030008  0.008515  0.023062  0.188315  0.023023  -0.036569  -0.101577  -0.046085  -0.050469  -0.045662
+-0.033362  -0.046569  0.035672  0.297517  0.059879  0.119259  0.006293  -0.102759  -0.091948  -0.052207
+-0.009295  -0.013779  -0.002689  0.024770  -0.124943  0.050484  0.016631  -0.048434  -0.051221  -0.055205
+-0.021381  -0.004356  -0.017932  -0.165839  -0.110102  -0.156237  -0.077500  0.032195  0.062280  0.028907
+0.011200  0.031329  0.044343  -0.183014  -0.021386  -0.073743  0.035114  0.074343  0.024471  0.016714
+0.013485  0.009005  0.040668  0.041327  0.034569  0.041351  0.092342  0.116787  -0.012881  -0.017673
+-0.019654  -0.039154  -0.091423  0.022833  0.086179  0.182603  0.128141  0.112397  0.013538  0.021000
+-0.065336  -0.074533  -0.121320  -0.077869  0.148352  0.126754  -0.035475  -0.113885  0.049049  0.030705
+0.024107  0.010918  0.027951  0.044869  -0.121607  -0.118828  -0.242148  -0.189000  0.028582  0.021770
+0.023872  0.047262  0.046549  0.005067  -0.293226  -0.291049  -0.271433  -0.214348  -0.183579  -0.102561
+0.012484  -0.006500  -0.007079  0.120468  0.217817  -0.002683  -0.057643  0.018405  -0.153659  -0.152460
+0.142986  0.313500  0.476458  0.442840  0.482167  0.624812  0.582910  0.538771  0.336389  0.201347
+-0.049764  -0.092333  -0.072125  -0.281236  -0.221861  0.191694  0.130875  0.063153  0.080097  0.113542
+-0.143675  -0.325431  -0.482415  -0.520117  -0.633729  -0.644894  -0.440042  -0.386516  -0.237027  -0.134096
+0.049981  0.057904  0.073192  0.216423  -0.097250  -0.204596  0.123404  0.179192  0.008981  -0.027846
+0.189562  0.333948  0.483245  0.451479  0.402672  0.534490  0.260958  0.228979  0.238719  0.114005
+0.009744  -0.011674  0.040244  0.030721  0.099302  0.246837  -0.268360  -0.150756  0.014640  -0.031849
+0.028585  -0.047754  -0.212185  -0.249115  -0.331231  -0.572423  -0.377815  -0.407792  -0.291192  -0.139769
+0.029125  0.030860  0.021838  0.048794  -0.356581  -0.334713  -0.102846  -0.126493  0.021529  0.017331
+0.008423  0.007803  0.059577  0.046535  0.095923  0.272373  0.105317  0.193465  -0.000585  -0.022070
+-0.028200  -0.006645  0.083791  0.101918  0.135282  0.456100  0.205891  0.271345  0.095273  0.030127
+-0.003351  0.001805  -0.011325  -0.016610  0.153532  -0.001558  -0.005188  -0.002500  0.014169  0.028279
+0.003327  0.020806  0.019949  0.042990  0.076490  -0.180796  -0.098388  -0.148622  -0.013745  0.001633
+-0.014939  -0.007015  0.098061  0.096152  -0.035152  0.046121  0.008667  -0.080515  0.034773  0.025439
+-0.001100  -0.012933  -0.008000  0.021400  -0.102578  0.221611  0.041311  0.021922  0.035689  -0.009189
+0.020726  0.027538  -0.100972  0.003717  -0.026566  -0.263981  0.021925  -0.011066  -0.129868  -0.062557
+-0.003357  -0.008946  -0.091304  -0.030321  -0.046393  -0.497393  0.038268  -0.002196  0.020571  0.075518
+0.020074  0.056882  0.067912  -0.120279  -0.029618  -0.070912  -0.107279  -0.048206  0.089441  0.100324
+-0.004276  -0.007303  0.050382  -0.032487  0.017658  0.424921  -0.019737  0.071132  -0.025013  -0.061316
+-0.012562  -0.035937  0.045531  -0.018875  -0.038406  0.317609  0.178125  0.036094  -0.150219  -0.102594
+-0.010892  -0.008142  -0.057378  -0.114912  -0.003628  0.040439  0.057885  0.073581  0.097520  0.062514
+-0.005542  -0.002734  -0.009177  -0.065479  0.051271  0.022156  0.032417  0.027151  0.053104  0.053203
+0.005500  0.004373  0.074582  0.033036  0.012164  0.015755  -0.024100  -0.048709  -0.045209  -0.050855
+0.037098  0.067561  0.160220  0.069171  -0.050866  -0.075659  -0.068476  -0.093012  -0.027000  0.001512
+0.013098  0.023991  0.016509  0.013482  -0.006179  -0.173857  -0.054759  0.003250  0.075143  0.098875
+0.013380  0.019296  -0.055333  0.074389  0.100991  -0.141583  0.006722  0.047019  0.097398  0.068009
+-0.000488  -0.004612  0.002853  0.083282  0.044488  0.071588  0.070453  0.025218  0.022459  -0.007506
+0.001106  -0.006149  -0.061340  0.013436  0.109213  0.196851  0.042681  -0.040819  -0.015234  0.002713
+-0.023723  -0.026089  -0.062732  -0.009125  0.100804  -0.032598  0.022000  0.004759  -0.048571  -0.027768
+-0.037734  -0.019141  -0.053297  -0.069688  -0.013141  -0.161938  0.006508  0.014953  -0.021930  0.018398
+-0.008436  -0.000300  0.000800  -0.082777  -0.106409  -0.048686  -0.054459  -0.027023  -0.018545  -0.036991
+0.008468  0.003195  0.000357  0.020013  -0.013039  0.082942  -0.105091  -0.023987  -0.010760  -0.026318
+0.005458  0.004168  0.015821  0.039747  0.017921  0.092763  0.000974  -0.020484  -0.014053  -0.012868
+0.006193  0.001489  0.009850  0.032904  0.008698  0.011497  0.041382  0.011556  0.023425  0.014374
+-0.004102  -0.002455  -0.010353  -0.012098  -0.017985  -0.025086  0.022368  0.086789  0.005064  0.007782
+-0.000397  -0.003799  0.042552  -0.024362  -0.041161  -0.000241  -0.003184  0.051287  -0.005006  -0.009580
+0.001854  0.002447  -0.008000  -0.004841  -0.067664  -0.044239  -0.054770  -0.125885  -0.008558  -0.021283
+-0.015254  -0.033918  -0.138082  -0.072388  -0.059799  -0.075716  -0.080448  -0.263463  0.001754  -0.026284
+-0.025086  -0.034121  -0.044036  -0.132057  0.050836  0.059671  0.135036  0.156807  -0.006500  0.003193
+-0.023875  -0.019229  0.010583  -0.187063  -0.095271  0.093729  0.126042  0.369333  -0.070667  -0.019625
+-0.000728  -0.024404  0.001368  -0.119507  -0.199412  0.009294  -0.080794  -0.107662  -0.199618  -0.151544
+-0.014456  -0.018971  0.024868  0.371015  0.417897  0.095632  0.024279  -0.120103  0.245000  0.158015
+0.023479  0.084135  -0.001677  0.199719  0.384448  -0.046490  0.141104  0.161542  0.431865  0.293594
+-0.048895  -0.050093  -0.024453  -0.280000  -0.163663  -0.059430  -0.127930  -0.152698  -0.420093  -0.139023
+-0.052188  -0.084297  -0.056375  -0.181516  -0.119547  0.100719  -0.001922  -0.035578  -0.517734  -0.364969
+0.065688  0.079708  0.107937  0.061750  -0.027833  -0.065687  -0.012500  0.079833  0.216271  -0.156896
+0.050583  0.076278  0.032264  0.111264  0.001042  -0.193764  -0.082722  -0.009042  0.382167  0.140597
+-0.003895  -0.000193  -0.020368  0.014982  -0.018886  -0.052632  -0.007096  -0.149544  0.283219  0.177982
+-0.052750  -0.075625  -0.107028  -0.224958  -0.082514  0.252764  -0.017250  -0.033361  0.004014  -0.027750
+-0.089171  -0.101886  -0.016229  -0.004857  0.086171  0.235314  0.042943  0.001543  -0.241571  -0.192371
+0.033000  0.050067  0.044300  0.148450  0.139633  -0.171150  0.108600  0.164217  -0.116817  -0.069700
+0.055811  0.090962  0.176698  0.103745  -0.010472  -0.028047  0.114170  0.093208  0.096255  0.107679
+-0.014517  -0.005948  -0.004707  -0.156362  -0.051879  0.098741  0.009569  -0.013810  0.071828  0.140379
+0.001036  -0.017274  -0.146881  -0.029333  -0.077607  -0.003607  -0.094214  -0.051012  -0.064060  -0.051881
+0.007267  -0.005802  -0.047914  0.016966  -0.033509  -0.054647  -0.244233  -0.272862  0.090940  0.054897
+-0.042609  -0.042609  -0.008707  -0.012446  0.074109  0.089543  -0.127141  -0.197533  0.129913  0.082674
+-0.035304  -0.025990  0.042500  0.060882  0.174804  0.201549  0.357157  0.347628  -0.177549  -0.097196
+-0.002926  0.019485  0.044250  -0.034868  -0.018544  0.024926  0.434294  0.403897  -0.136132  -0.096353
+0.098830  0.073045  0.041591  0.005239  -0.230159  -0.369841  -0.508295  -0.304511  0.196443  0.138216
+0.022670  -0.002180  -0.001750  -0.040810  -0.087830  -0.082820  -0.467400  -0.381280  0.107830  0.036940
+-0.032533  -0.030956  -0.010000  -0.070633  0.054422  0.195256  0.156244  0.065278  -0.029356  -0.062533
+-0.037480  -0.013531  -0.047735  -0.040173  0.019459  0.070755  0.220153  0.205541  0.233082  0.215306
+-0.009748  -0.011446  -0.019824  -0.027234  -0.011108  -0.058743  0.012644  -0.020450  0.095869  0.114248
+-0.007333  -0.004402  0.010470  0.004386  0.001992  -0.013348  -0.010455  0.113848  -0.145909  -0.136402
+-0.002235  -0.001000  0.020549  -0.001284  0.085392  0.077382  -0.009951  0.056412  -0.122529  -0.029598
+-0.000090  -0.003082  0.009806  0.036597  0.054761  0.006851  0.019373  -0.187672  -0.004948  0.021313
+0.044766  0.037032  0.101573  0.149363  0.044653  0.009363  0.001702  0.009363  0.078992  -0.000089
+0.015833  0.034056  -0.037431  -0.028292  -0.085750  -0.015042  -0.023750  0.276000  -0.039722  -0.108667
+-0.108808  -0.129333  -0.209717  -0.241283  -0.072617  -0.074900  0.016717  -0.019583  -0.056658  -0.058058
+-0.023478  -0.015957  -0.092217  -0.246380  -0.086587  -0.065478  -0.005989  -0.003315  0.133859  0.144533
+0.006000  0.072367  0.224641  0.100898  0.104313  0.133883  0.095148  0.072195  0.104383  0.087195
+0.022337  0.010255  0.162867  0.431622  0.262061  0.276571  0.245133  0.184388  -0.028082  -0.073020
+-0.002388  -0.017632  0.045447  0.235447  0.068171  0.089658  0.063520  0.054263  0.017487  -0.017789
+-0.006012  -0.030640  -0.154591  -0.167134  -0.169988  -0.159677  -0.113323  -0.100750  -0.044299  -0.027274
+-0.011145  -0.099819  -0.233217  -0.408703  -0.200130  -0.256406  -0.241739  -0.119841  -0.102986  -0.042029
+0.000442  0.005175  -0.004433  -0.184242  -0.006300  -0.015142  -0.093867  -0.127725  -0.064842  -0.023842
+0.000261  0.002142  0.039343  0.151194  0.024627  0.065239  -0.030216  -0.017552  -0.008485  -0.015448
+0.015540  0.015605  0.045194  0.146218  0.052056  0.033758  0.064355  0.136742  0.012565  0.018710
+0.006541  0.001245  0.017755  0.085132  -0.012736  -0.007455  0.024095  0.042541  0.049459  0.013164
+-0.004965  -0.008015  -0.010050  -0.008663  -0.010743  0.012332  0.013970  -0.151876  -0.030074  -0.052188
+-0.011272  -0.020935  -0.007826  -0.081978  0.071978  -0.001326  -0.030196  -0.113239  -0.064663  -0.050217
+-0.007769  -0.002093  0.025357  0.008813  0.038231  0.029434  0.080357  0.199863  -0.094269  -0.030852
+-0.054650  -0.050129  -0.015471  0.023621  0.062579  0.096657  0.276857  0.182300  -0.096236  -0.030571
+0.159857  0.216964  0.108768  0.097179  -0.065161  -0.043714  -0.020000  -0.079179  0.104875  0.115661
+0.147474  0.163263  0.082158  -0.095711  -0.070895  -0.050921  -0.303079  -0.135632  0.144447  0.049474
+-0.081539  -0.091237  -0.097039  -0.159276  0.058882  0.052566  -0.076934  0.020303  -0.090092  -0.112605
+-0.052706  -0.082221  -0.040250  0.112338  0.092118  0.123544  0.134838  -0.057618  -0.184397  -0.081912
+0.008912  -0.000158  0.024662  0.082759  -0.002399  0.034890  0.019311  0.002570  -0.003991  0.009579
+0.001253  -0.000900  -0.014013  -0.092000  -0.020560  -0.054600  -0.045020  0.033647  0.042680  0.044447
+-0.027895  -0.017352  -0.031593  -0.111932  -0.003302  -0.050636  0.063272  0.054759  0.013926  -0.000210
+-0.011859  -0.020359  -0.031672  0.125234  0.104125  0.026672  -0.007656  -0.071680  -0.076211  -0.035086
+0.019305  -0.003085  -0.006110  0.117049  0.164902  0.026780  -0.195354  -0.191366  -0.119122  -0.109829
+0.001032  -0.017809  -0.049894  -0.007862  -0.059926  -0.083543  -0.188362  0.033000  -0.021404  0.081862
+0.001869  0.028344  0.051402  -0.099607  -0.251615  -0.108869  0.036008  0.040697  0.147270  0.070336
+-0.014261  -0.012870  -0.044793  -0.128293  -0.191674  0.087891  0.320554  0.198924  -0.012087  -0.013011
+-0.017946  -0.026674  -0.067315  0.000685  0.246217  0.095761  0.168565  0.086750  -0.077326  -0.029370
+-0.000175  0.017008  0.023992  0.016050  0.374000  0.110758  0.076983  0.110992  0.178383  0.098492
+-0.017779  -0.020195  -0.014379  0.008800  0.060747  0.032474  0.281953  0.107000  0.056689  0.048711
+0.094692  0.099417  0.077733  0.069758  -0.339492  -0.437242  -0.122958  -0.068417  -0.180900  -0.080242
+0.066095  0.038776  -0.041397  -0.073914  -0.306983  -0.429483  -0.640009  -0.541293  -0.247250  -0.224586
+-0.069660  -0.155860  -0.149080  -0.028500  0.149940  0.021300  -0.261240  -0.389000  0.054540  0.011040
+-0.050097  -0.050370  -0.015006  0.033403  0.184851  0.176234  0.174084  -0.092351  -0.002916  0.042364
+-0.004410  0.005560  -0.020980  -0.006750  -0.030710  -0.067060  0.087660  0.144290  0.014320  -0.054800
+0.004478  0.012311  0.025511  -0.049722  -0.088778  -0.046578  0.068767  0.340800  0.123489  0.061233
+-0.027567  0.000462  0.013163  -0.007615  0.106692  0.079731  0.305923  0.303750  -0.004221  0.115029
+0.024243  0.033676  0.045270  0.051230  0.089243  0.077973  -0.008311  -0.236973  -0.121730  -0.007959
+0.071810  0.053220  0.019940  -0.019150  -0.096820  -0.091230  -0.408370  -0.376440  -0.245770  -0.276870
+-0.090048  -0.103548  -0.126365  -0.174381  -0.176016  -0.176111  -0.221778  -0.032262  -0.119159  -0.164921
+-0.098912  -0.105426  -0.049324  0.014956  0.112559  0.079456  0.456485  0.287412  0.234147  0.253794
+-0.028986  -0.015732  0.135261  0.207979  0.062486  0.089472  0.288324  0.102627  0.200120  0.171085
+0.037500  0.048085  -0.058793  0.093171  0.046646  0.045939  0.082073  -0.101427  0.019171  -0.008427
+0.188586  0.286828  0.285431  0.114500  0.178397  0.139776  -0.098879  -0.022172  -0.170172  -0.151155
+0.175304  0.259761  0.124152  -0.095413  0.042717  -0.002326  -0.211413  0.028957  -0.145935  -0.193978
+-0.196676  -0.352027  -0.517730  -0.501878  -0.552041  -0.314851  -0.214257  -0.241351  0.011122  -0.021689
+-0.106619  -0.214214  -0.182429  -0.180714  -0.432619  -0.223214  -0.045000  -0.206048  0.155500  0.187643
+0.026014  0.034401  0.082042  0.175282  0.266606  0.122937  0.044141  -0.014535  -0.164218  -0.067162
+0.067250  0.115797  0.060031  -0.069016  0.212391  0.112188  -0.072734  0.094281  -0.130578  -0.181391
+0.001891  -0.004475  0.011847  -0.026153  -0.001079  0.040045  0.012970  0.111069  -0.009569  -0.035421
+0.003003  0.000083  0.013473  0.013286  0.017607  0.020054  0.008690  0.183232  0.003307  0.005357
+0.000694  0.000519  0.001344  0.007860  0.003341  0.000545  -0.020854  0.068433  -0.009080  0.005962
+-0.003118  -0.001682  -0.011497  0.013417  -0.009242  0.008860  -0.002408  -0.116850  0.012780  0.002223
+0.002542  0.001380  -0.026739  -0.013859  -0.033704  -0.143937  -0.042655  -0.180211  0.051394  0.031824
+-0.002743  0.030600  0.147771  -0.020200  0.034200  -0.030086  0.065214  -0.029629  -0.023686  -0.000686
+0.008250  -0.034781  0.206031  -0.026250  -0.107406  0.028000  -0.096156  -0.003125  -0.048094  -0.004531
+-0.067492  -0.114339  -0.195585  -0.200754  -0.210483  -0.198322  -0.067288  -0.053678  0.075780  0.062254
+-0.046803  -0.092682  -0.360727  -0.252758  -0.081288  -0.214833  0.006106  -0.068561  -0.048727  0.051030
+0.093023  0.162731  0.192623  0.221300  0.367115  0.283808  0.098715  0.096223  0.037615  -0.009154
+0.029810  0.048464  0.210024  0.289214  0.215607  0.100798  -0.169012  -0.039881  -0.053107  -0.040333
+0.000112  -0.002762  0.024100  -0.011475  -0.297662  -0.096187  0.118425  0.150825  0.046250  -0.002100
+-0.047788  -0.060750  -0.053856  -0.202508  -0.244606  -0.023576  -0.000523  0.120159  0.061348  -0.008864
+-0.011912  -0.041103  -0.162544  -0.187074  0.129485  -0.103500  -0.108353  -0.187500  -0.137074  -0.061956
+0.001868  0.004029  -0.046132  0.016676  0.217603  -0.030706  0.031985  -0.111397  -0.069926  -0.004000
+0.079500  0.136266  0.248989  0.244202  -0.086138  0.044543  -0.025096  0.017245  0.076532  0.026213
+0.010151  0.008212  0.007486  -0.004589  -0.142397  0.005610  -0.071363  -0.039425  0.043856  0.028993
+-0.004537  -0.002079  -0.072732  0.005256  0.000207  0.012433  -0.005213  -0.050896  -0.015884  -0.015848
+0.001773  -0.002472  0.001756  0.170892  0.023318  0.037676  0.022580  0.018523  0.034784  0.021159
+-0.027390  -0.025220  -0.092707  -0.132122  0.107817  -0.012707  0.109171  -0.004341  0.058268  0.094402
+-0.038530  -0.034348  -0.144621  -0.380091  0.075500  0.048258  0.017318  -0.014348  -0.004833  0.029061
+0.115036  0.182357  0.231018  -0.042161  -0.187393  -0.101000  -0.146375  -0.183411  -0.038964  -0.029661
+0.038790  0.073403  0.214645  0.075774  -0.205597  -0.184710  -0.276790  0.024000  -0.066742  -0.097742
+-0.093382  -0.148882  -0.187412  -0.113029  -0.029824  -0.004882  0.037588  0.290559  0.065029  0.059941
+-0.114557  -0.107830  -0.125545  -0.152989  0.026057  0.127011  0.272739  0.125693  0.015716  -0.013955
+0.008712  0.019250  0.084865  0.150673  0.261442  0.280327  -0.126404  -0.325058  -0.083712  -0.015827
+0.172133  0.258767  0.400000  0.301100  0.141767  0.112233  -0.320100  -0.218267  0.018700  0.019733
+0.007398  0.017531  -0.009776  -0.029480  0.013786  -0.149745  0.158735  0.185582  0.053449  0.065816
+-0.003563  0.004663  0.017050  -0.099087  -0.068825  -0.104000  0.010575  0.174112  -0.038550  -0.019738
+-0.002526  -0.002626  0.014300  -0.069979  -0.027142  -0.053632  0.011121  0.018368  -0.003011  -0.014842
+0.021558  0.023151  -0.087512  -0.055081  -0.052640  -0.067942  0.019744  0.023535  0.010244  0.009186
+0.003184  0.004194  -0.001378  0.031214  -0.050888  0.040944  -0.020918  0.014939  -0.031587  -0.011985
+0.062032  0.048479  0.089202  0.060160  -0.064394  0.061766  0.004032  0.008915  0.042926  -0.006521
+0.009985  -0.000085  0.082154  0.041854  0.026115  0.023977  -0.015277  0.017085  0.013346  -0.007938
+0.012921  0.006393  0.021517  0.122023  -0.017354  -0.031933  0.012983  -0.022017  0.008326  0.020573
+-0.001250  -0.019276  -0.102013  -0.014500  -0.031250  -0.056605  -0.046842  -0.028224  -0.214974  -0.037132
+-0.028898  -0.024608  -0.088823  -0.244753  -0.021253  -0.018392  -0.066672  -0.035457  -0.108403  -0.021296
+-0.016841  -0.008205  0.018530  0.036197  0.106326  0.052515  0.025515  0.083576  0.152848  0.034735
+0.009542  0.003873  0.023763  0.124195  0.065602  0.117466  0.018356  0.005661  -0.078093  -0.104508
+-0.006559  0.001068  0.005780  -0.049517  0.023949  0.005136  0.011161  -0.011186  0.049695  -0.054873
+-0.009385  -0.002230  -0.012500  0.027203  -0.010304  -0.007588  0.172182  0.052459  0.350649  0.128791
+-0.014190  -0.010332  -0.030185  -0.069957  -0.024016  -0.011717  -0.015614  -0.015413  0.043326  0.024087
+-0.008397  -0.014801  0.000412  -0.038801  0.025934  0.051412  -0.101618  -0.068199  -0.198618  -0.136853
+0.010333  -0.002402  0.026713  0.085644  0.026006  0.014598  0.021684  0.041305  -0.026621  -0.039724
+0.024034  0.028836  0.027671  0.067192  0.079678  0.018925  0.064027  0.064877  0.059274  0.058637
+0.002885  -0.001236  -0.002791  -0.028358  0.036669  0.019466  -0.049554  -0.015723  -0.045595  0.069203
+-0.009005  -0.005563  0.003353  -0.084011  -0.017358  0.009132  -0.084547  -0.065921  -0.024316  -0.024711
+-0.001307  0.000214  -0.004532  0.001257  -0.013046  -0.011639  0.075671  -0.044261  -0.003350  -0.014146
+0.011852  0.000074  0.031287  0.229352  -0.016602  -0.035500  0.124963  0.028185  0.036769  0.011056
+0.016628  0.005686  0.058163  0.172674  -0.035570  -0.058442  -0.075337  -0.065209  0.117500  0.043163
+-0.019224  -0.024612  -0.091629  -0.383698  -0.106388  -0.149259  -0.097284  -0.057983  0.020379  0.060336
+0.027871  -0.018000  -0.186290  -0.101468  -0.127371  -0.114161  0.019371  0.154742  0.013048  -0.038645
+0.012705  -0.017090  0.126692  0.414872  0.029603  0.003256  0.032526  0.002026  0.004346  0.008218
+-0.009635  0.075625  0.356531  0.297427  0.201344  0.316500  0.073385  0.068719  0.157010  0.099708
+0.048153  0.121226  0.176565  0.135839  0.228694  0.345887  0.572903  0.345911  0.199734  0.165798
+0.093352  0.125296  0.003056  -0.331815  -0.284611  -0.124907  0.109722  0.062167  -0.282741  -0.185019
+-0.002518  -0.130693  -0.287851  -0.337254  -0.528404  -0.675640  -0.742026  -0.683816  -0.344833  -0.202307
+0.045010  -0.057010  -0.064927  -0.087333  -0.189885  -0.290615  -0.623375  -0.238927  -0.063406  -0.088417
+-0.040113  -0.025662  0.109620  0.293458  0.253099  0.350099  0.416338  0.097000  0.213627  0.191373
+-0.005240  0.012444  0.042480  0.084730  0.177520  0.235995  0.337612  0.216842  -0.010964  0.004878
+-0.005946  -0.003804  0.019824  -0.012108  -0.139189  -0.093209  -0.110635  -0.003709  -0.139378  -0.098041
+-0.020409  -0.016795  0.028102  0.035330  0.067602  -0.133170  0.031852  -0.022864  -0.223261  -0.083750
+-0.033507  -0.030629  -0.027136  0.072679  0.238193  0.211593  0.346021  0.159629  0.146929  0.165193
+-0.021422  0.018017  0.078233  0.154638  0.209267  0.303845  0.326776  0.346914  0.508569  0.245431
+-0.018264  -0.005791  -0.007245  -0.230009  -0.400064  -0.202227  -0.349655  -0.276064  -0.091736  -0.074800
+0.090320  0.058795  -0.073402  -0.271451  -0.231238  -0.323393  -0.373082  -0.215262  -0.307975  -0.247582
+0.003605  0.006149  0.015570  0.095105  0.188009  -0.003851  0.099368  0.050842  -0.061930  0.011289
+-0.062364  -0.090761  -0.048193  0.138273  0.063977  0.056352  0.194182  -0.003034  0.080386  0.109886
+0.002359  0.003590  0.005237  0.031667  0.005083  0.026256  0.011660  0.092378  0.021885  0.094513
+-0.004858  -0.006421  0.025384  -0.000053  -0.004389  0.013195  0.056000  0.081874  0.087158  0.099484
+-0.008455  -0.002980  -0.000145  -0.035610  0.005050  -0.038490  0.032485  -0.019125  0.064110  0.019120
+-0.003113  -0.003158  -0.002698  -0.021797  -0.005622  -0.022122  -0.037910  0.018198  0.005649  -0.023221
+-0.000570  0.001000  -0.001164  -0.019055  -0.016094  0.065539  -0.037219  0.042672  -0.007789  -0.055961
+-0.002731  -0.001594  -0.009623  -0.001142  -0.078104  0.020104  0.000712  -0.012165  0.021009  -0.023028
+0.005598  0.008422  -0.041554  -0.014848  -0.026250  -0.096490  -0.025103  -0.054093  0.068103  0.033324
+-0.001569  -0.000693  -0.004020  -0.002980  -0.008936  -0.027124  -0.017842  -0.001149  -0.000465  0.086936
+0.003681  0.002007  -0.006785  0.003938  0.041812  -0.005319  -0.000931  0.004042  -0.084340  0.032410
+0.005540  0.002391  0.003866  0.023144  0.059005  0.031540  -0.007995  -0.025718  -0.141505  -0.061990
+0.010007  0.013187  0.009792  0.005375  0.029618  -0.046701  -0.070368  -0.022514  -0.041403  -0.137090
+-0.021724  -0.013053  -0.068671  -0.039197  -0.111105  -0.210276  -0.045329  0.058908  0.072711  0.059750
+0.002197  -0.002426  -0.002164  0.001295  -0.262311  0.036418  0.048148  -0.049033  0.003844  -0.009328
+-0.010382  0.015816  0.186697  0.052947  0.139013  0.455539  -0.009605  0.006039  -0.164539  -0.120921
+-0.013022  -0.010846  0.043015  0.270757  0.508669  0.237706  0.165213  0.141588  0.174507  0.149235
+-0.010500  -0.017111  -0.157611  0.007722  0.023556  -0.435278  0.191333  0.087778  0.258833  0.241833
+0.073236  0.099403  0.078028  -0.129958  -0.218799  -0.195993  -0.094597  -0.084444  -0.069986  -0.000181
+0.130550  0.129175  0.126900  -0.138112  -0.117313  0.074750  -0.025625  -0.023600  -0.057462  -0.058050
+-0.011613  -0.012006  -0.030232  -0.061155  -0.025756  -0.037565  -0.056220  -0.121155  0.034030  0.035690
+-0.004011  -0.023356  0.005133  0.122922  -0.067767  0.026356  -0.051067  -0.091889  -0.001122  -0.021167
+-0.080174  -0.080000  0.016717  0.098304  0.039804  0.220348  -0.034957  0.196435  0.070717  -0.019304
+-0.014048  -0.009766  0.007234  -0.112210  -0.039500  0.059363  0.016435  0.166290  0.020371  -0.002363
+-0.001434  -0.000481  -0.040981  -0.015264  0.009491  -0.122425  0.110613  -0.054972  -0.021151  -0.005962
+0.077793  0.061183  0.052085  0.151207  -0.015037  -0.061549  0.083317  -0.081061  -0.085598  -0.039732
+0.007553  0.010513  -0.011167  0.064127  -0.045333  -0.044533  -0.035913  -0.041113  -0.052140  -0.118633
+-0.037845  -0.033491  -0.081690  -0.054991  -0.008250  -0.031828  0.020552  0.065310  -0.065595  -0.057966
+-0.012241  -0.020907  -0.038102  -0.123074  0.166685  0.134157  0.060509  0.022963  -0.030435  0.006417
+-0.013462  -0.007424  0.017304  -0.008804  0.223215  0.149854  -0.048506  0.012778  0.014873  0.013076
+-0.003212  -0.000075  -0.001325  -0.055775  -0.087013  -0.016425  -0.164825  0.158112  0.113312  0.040162
+0.008300  -0.007829  -0.019143  -0.052400  -0.492514  0.001143  0.062271  0.033586  0.083129  0.038386
+-0.016588  -0.047020  -0.007804  0.009725  -0.386882  -0.100078  -0.100274  -0.151559  -0.099461  -0.048039
+-0.024750  0.047500  -0.060417  0.081083  0.410000  -0.025167  0.077750  0.000000  -0.299333  0.027833
+-0.072250  -0.082500  0.037142  0.042267  0.287967  0.259775  0.137267  0.163967  -0.219200  -0.121500
+0.007739  -0.031630  -0.079304  0.031826  -0.329304  -0.263587  0.118043  0.209022  0.351804  0.159152
+0.136744  0.158395  -0.130919  -0.045116  -0.246628  -0.168733  -0.087640  0.032895  0.200070  0.029674
+0.210487  0.322649  0.359987  0.278189  0.323324  0.271095  -0.012716  -0.002432  0.019230  0.000338
+0.024413  0.069087  0.116522  0.320000  0.422000  -0.036130  -0.201565  -0.169391  -0.248152  -0.165957
+-0.189829  -0.322632  -0.303039  -0.195026  -0.315789  -0.126697  -0.094592  -0.085592  -0.072132  -0.092184
+-0.087553  -0.128500  -0.197829  -0.022474  -0.037184  -0.023724  0.098092  0.037579  0.228263  0.142289
+0.070338  0.061779  -0.060838  -0.076103  0.134088  0.037515  0.199647  0.122279  0.057000  0.096838
+-0.024842  0.005724  0.027500  -0.255066  0.081382  0.142487  0.011789  0.056776  -0.165974  -0.082329
+0.007213  0.011638  0.007415  -0.012074  0.060628  0.126160  -0.149330  -0.012032  -0.051277  -0.130574
+0.014458  0.024764  0.090458  0.229833  -0.143486  -0.167722  -0.013292  -0.092833  -0.041069  0.049736
+0.020702  0.022574  -0.028117  -0.021745  -0.053543  -0.143564  -0.103840  -0.270638  0.157787  0.136223
+-0.041216  -0.058635  -0.055919  -0.108541  -0.008770  0.151703  -0.083014  0.024554  0.078108  0.025892
+-0.019974  -0.027205  -0.014756  -0.109872  0.002974  0.111577  0.016885  0.173718  -0.110795  -0.118128
+-0.008900  -0.008864  0.015391  -0.051927  0.050464  0.022073  0.062855  -0.044773  -0.124482  -0.030273
+-0.006979  0.002830  0.050915  0.193989  0.086415  -0.029426  0.079702  0.027234  0.139043  0.180394
+0.042280  0.047682  -0.014333  0.146848  -0.020045  -0.091841  0.021871  0.085780  0.153985  0.041561
+0.001812  0.003266  0.003836  0.026734  -0.062641  -0.031695  0.009680  0.062492  -0.041258  -0.065008
+0.002273  -0.005155  0.030736  0.019973  0.010773  0.126136  0.075636  -0.072855  -0.039882  0.008673
+-0.041420  -0.054340  0.019700  -0.063000  0.016500  0.098860  0.010500  -0.133340  0.001780  0.144800
+-0.003470  0.001590  -0.038888  -0.158731  -0.046873  -0.092007  -0.055873  -0.066194  0.037933  0.010933
+-0.019340  -0.015902  -0.034881  -0.126351  -0.070732  -0.186660  -0.067732  -0.064129  -0.100015  -0.019711
+0.011367  0.005117  -0.052820  0.130594  -0.008641  0.012094  0.000398  0.010211  -0.017539  -0.006461
+-0.067569  -0.172216  -0.228010  0.059059  0.000392  -0.055373  -0.072549  -0.173255  0.041549  0.061333
+-0.091788  -0.138627  -0.138458  -0.048534  -0.094415  -0.052390  -0.040763  -0.096568  -0.080042  -0.016492
+0.161488  0.316233  0.399895  0.054605  0.046291  0.170767  0.394640  0.421651  0.036012  0.014872
+0.185316  0.356816  0.450551  0.196331  0.242581  0.316169  0.238235  0.305051  0.058838  0.014721
+-0.127400  -0.285619  -0.417350  -0.354163  -0.332456  -0.404900  -0.522600  -0.477613  -0.430612  -0.269838
+-0.185608  -0.329823  -0.356438  -0.085746  -0.197985  -0.292939  -0.328438  -0.329485  -0.148654  -0.117508
+0.098071  0.193390  0.193630  0.153506  0.194338  0.171344  0.274519  0.244766  0.243669  0.109812
+0.082905  0.135484  0.094770  0.056738  0.109270  0.135056  0.148690  0.104230  0.153365  0.151937
+-0.025256  -0.022488  -0.047360  0.114988  0.018302  -0.020930  -0.083965  -0.062314  0.006419  -0.014663
+-0.006808  -0.001894  0.006394  0.054173  0.183038  0.068817  -0.041202  0.007442  0.112692  0.057183
+-0.009323  0.017435  -0.071500  -0.224903  0.166081  0.238984  0.172726  0.127919  0.179548  0.101371
+-0.003368  -0.018382  -0.037824  -0.175985  -0.366103  -0.133294  -0.093074  -0.038721  -0.219147  -0.155279
+-0.006917  -0.012528  0.105639  0.117028  -0.260944  -0.071667  0.004972  -0.094944  -0.339500  -0.202694
+-0.031095  -0.049310  0.066988  0.041845  0.099571  0.044060  0.018738  -0.023226  0.013893  0.035833
+0.011600  0.037467  0.002178  0.002078  0.202000  -0.037689  -0.041144  0.031722  0.164822  0.150378
+-0.004696  0.014393  0.035527  0.017679  0.003938  -0.100411  0.043938  0.055634  0.089429  0.163107
+-0.032000  -0.034742  -0.094806  -0.327903  -0.116710  -0.038065  0.123500  0.148855  0.044081  0.054435
+-0.132575  -0.269633  -0.506317  -0.532825  -0.117367  -0.132350  -0.228183  -0.185775  -0.127425  -0.109908
+0.032868  0.005515  -0.004132  0.236221  0.017074  0.031471  -0.092324  -0.269868  0.012824  -0.032147
+0.180188  0.289237  0.484300  0.527987  0.271637  0.162050  0.125200  0.118675  0.004350  0.008600
+-0.010043  -0.001574  0.000862  -0.000117  0.044574  -0.006479  0.018734  0.132521  -0.230277  -0.062223
+-0.021023  -0.043341  -0.100750  -0.107875  -0.205670  0.067375  0.130898  0.059955  0.187500  0.090386
+-0.009800  -0.006822  -0.014144  0.010489  -0.032133  0.042200  -0.051344  0.006611  0.218067  -0.042522
+0.017066  0.026789  -0.007921  -0.020553  0.122013  -0.028053  -0.168592  0.047632  -0.023605  -0.050289
+-0.004894  -0.013830  0.007543  0.013553  0.010468  0.015138  0.061979  -0.000894  -0.191128  0.075904
+-0.045868  -0.054640  0.020158  0.002088  -0.071833  0.114825  0.215333  0.057588  0.150211  0.115158
+-0.000649  0.028189  -0.021230  -0.128905  0.147716  0.045162  -0.024811  0.065284  0.129689  0.003662
+0.001171  0.002614  0.002014  0.039371  0.002614  -0.056214  -0.163300  0.071257  -0.168100  -0.063371
+-0.037750  -0.054917  0.104048  0.161226  0.033631  0.153857  0.071095  0.074524  -0.098190  -0.031893
+-0.068062  -0.145812  -0.232984  -0.215625  -0.235625  0.086375  0.043391  -0.126578  0.009672  0.023609
+0.004924  -0.024253  -0.147506  -0.208265  -0.192882  -0.347318  -0.276406  -0.265653  -0.051482  -0.021741
+0.081432  0.106041  0.139432  0.326838  0.035257  -0.179513  -0.029027  0.029811  0.052041  0.022811
+0.004523  0.064314  0.166091  0.160559  0.206491  0.226773  0.129095  0.168732  0.104768  0.067664
+-0.008586  -0.007093  0.000123  -0.030698  -0.009753  0.106623  0.016389  -0.000685  -0.039969  -0.021500
+-0.035319  -0.031379  -0.067690  -0.019569  -0.014776  -0.009716  -0.019940  -0.037871  -0.099767  -0.065871
+-0.004134  -0.005069  -0.000178  -0.060327  0.055421  0.000233  -0.026193  0.027495  -0.024589  0.009916
+-0.003634  -0.001919  -0.005221  -0.016930  0.118355  0.001058  0.060320  0.062686  0.012523  0.028453
+0.013780  -0.001305  -0.060263  0.132042  0.070788  0.067856  0.082610  0.053508  0.098839  0.026864
+0.020060  0.011600  0.189640  0.069440  -0.065620  0.185640  -0.049860  -0.013000  0.245020  0.117580
+-0.093754  -0.124203  -0.147619  -0.185127  -0.112644  -0.212754  -0.035339  -0.095203  -0.181178  -0.031229
+-0.009285  -0.018023  -0.048669  -0.174485  -0.038008  -0.133385  -0.072654  -0.098015  -0.316592  -0.048769
+0.128483  0.130379  -0.033483  0.094190  0.143155  0.078655  0.066569  0.110759  0.006552  0.004655
+-0.017352  -0.000195  0.045133  0.063578  0.047805  0.143891  0.058859  0.080555  0.299711  0.023484
+-0.006931  -0.002621  0.015569  0.033560  -0.011293  -0.067000  -0.096629  -0.093543  0.101466  0.178862
+-0.041358  -0.051403  -0.041164  -0.050172  -0.004336  -0.083000  -0.211179  -0.093500  -0.069470  -0.069896
+-0.003583  -0.002500  -0.021962  -0.025841  -0.054674  -0.049500  -0.061811  -0.022417  -0.250371  -0.333000
+-0.002953  0.003818  -0.014277  -0.019270  -0.007473  -0.023264  0.260892  0.051345  -0.054581  -0.047095
+-0.036862  -0.045362  -0.026569  -0.079086  0.074983  0.066259  0.172655  0.049707  0.205190  0.299655
+0.009602  0.007220  0.002585  0.008987  0.008924  -0.003263  -0.001148  0.009780  0.218932  0.175991
+0.051917  0.046300  0.024000  0.127383  0.059467  0.060967  -0.141233  0.094567  0.144383  -0.002017
+0.036573  0.030371  0.008621  0.075782  0.032315  -0.052194  -0.070661  0.006242  -0.061508  -0.021194
+-0.000047  -0.002041  -0.006169  -0.030432  0.013736  -0.016709  -0.049318  -0.018628  -0.238399  -0.037973
+-0.003013  0.000458  -0.001000  -0.014042  -0.005623  -0.009865  0.063800  0.022652  -0.034729  -0.025268
+-0.003426  0.007303  0.008057  0.001098  0.020533  -0.029910  0.102869  0.013992  0.186352  0.117041
+0.002862  0.001424  0.006865  0.020429  -0.012318  -0.001071  0.000359  -0.020094  0.015694  0.023368
+-0.010474  -0.006716  -0.007608  -0.056379  -0.015004  -0.021466  -0.107909  -0.040405  -0.125884  -0.066207
+0.001787  0.003128  -0.044574  -0.093447  -0.001351  -0.007617  -0.089340  -0.023170  0.128223  0.036064
+-0.001844  0.002754  -0.001492  0.082852  0.005270  0.023287  0.070230  0.053607  0.163377  0.003803
+0.014962  0.008449  -0.013397  0.159090  -0.002513  -0.004256  0.070487  0.050077  -0.115692  -0.107064
+0.009945  0.004571  0.028934  0.068467  0.019495  0.024731  -0.038418  -0.012148  -0.208923  -0.128445
+-0.042800  -0.062075  0.035050  -0.096800  -0.005425  0.097750  -0.103200  -0.040075  -0.169750  0.051550
+-0.076047  -0.094438  -0.133813  -0.114297  0.027766  0.091641  -0.011391  -0.043828  0.206672  0.197063
+-0.005171  -0.003276  -0.061342  -0.013776  -0.066342  0.019421  0.028724  0.164434  0.173250  -0.003605
+0.012258  0.017275  -0.058942  -0.198558  0.018250  0.042883  -0.140675  -0.051450  -0.179533  -0.162567
+-0.073746  -0.092841  -0.176444  -0.228436  -0.150476  -0.182603  -0.253278  -0.232786  -0.185627  -0.114032
+0.047689  0.058933  0.058589  0.300344  0.252044  0.029778  0.314300  0.112933  0.043989  0.046744
+0.101493  0.259416  0.435592  0.465500  0.168838  0.246937  0.377289  0.210000  0.209739  0.161197
+-0.038057  -0.036321  -0.068632  -0.139641  -0.172679  -0.043726  -0.116925  0.047208  0.054792  0.030896
+-0.053153  -0.057235  -0.047857  -0.162969  -0.246847  0.012163  -0.139510  -0.099765  0.008235  -0.028133
+-0.069488  -0.075988  0.155402  0.087963  0.187256  0.098207  0.015890  0.004915  -0.049049  -0.023561
+-0.011185  0.022913  0.161761  0.199609  0.151511  0.013620  -0.000293  0.101424  -0.032413  0.005750
+0.028889  0.025824  -0.037481  0.088019  0.006287  -0.078722  -0.127324  -0.038500  0.074037  0.005972
+-0.074831  -0.147608  -0.260008  -0.200785  -0.068392  -0.090877  -0.199277  -0.173569  0.036277  0.038800
+-0.053474  -0.032447  -0.018184  -0.411737  -0.070224  0.042434  -0.030553  -0.062303  -0.198566  -0.103763
+0.012852  0.100389  0.247648  -0.029167  -0.026481  -0.007981  0.087648  0.151815  0.016167  0.016148
+0.052000  0.044094  0.037179  0.385462  0.104915  0.018123  0.097717  0.116953  0.218283  0.041491
+-0.014217  -0.040983  -0.046667  0.283317  0.129633  0.108317  0.135617  0.180033  -0.012267  -0.048100
+-0.027250  -0.008597  -0.016847  -0.202597  0.009569  0.105333  0.155361  0.021833  -0.057681  0.023458
+0.037775  0.035125  -0.080200  -0.482250  -0.350850  -0.219100  -0.186850  -0.272300  0.087800  0.064750
+0.012099  0.013645  -0.024678  -0.047829  -0.050329  -0.096691  -0.255757  -0.105145  0.030368  -0.012934
+0.069385  0.051692  0.120519  0.257423  -0.051288  -0.027058  -0.053385  0.132596  -0.067615  -0.096000
+0.013500  0.028914  0.116971  0.085200  -0.090843  -0.020200  0.043929  0.117429  -0.001614  -0.043086
+-0.009279  -0.010651  0.048151  -0.028581  -0.147767  0.084802  -0.000419  0.052953  -0.102814  -0.101116
+-0.028956  -0.036149  0.001886  -0.081684  -0.063965  0.176333  -0.015912  -0.029202  -0.054061  -0.114781
+-0.024234  -0.008285  -0.056095  -0.087810  -0.055272  -0.036475  0.003443  -0.101241  -0.024000  -0.024443
+-0.041276  -0.027966  -0.071276  -0.055397  0.037276  -0.037345  -0.006466  -0.079879  -0.136655  0.195672
+0.003592  0.002282  0.002099  0.011134  0.023204  -0.018817  0.030479  0.024965  0.004190  0.159859
+0.006156  0.005484  0.000812  0.007022  0.028613  -0.007495  0.033409  0.249484  0.049070  0.025070
+0.005434  0.006566  -0.001730  0.020984  -0.005648  -0.088082  0.011320  0.005738  0.048500  -0.063541
+0.031023  0.081114  0.154818  0.119045  0.050705  0.056477  0.050523  -0.240568  0.065250  0.051568
+0.009300  -0.025214  -0.043257  0.177843  0.059086  0.067500  -0.062129  -0.129514  0.233200  0.107529
+-0.017946  -0.012375  -0.076411  -0.221964  -0.184036  -0.091536  0.004339  0.174500  -0.154393  -0.114696
+0.015296  0.044204  0.113130  -0.095704  -0.163037  -0.077574  0.065796  0.317833  -0.289241  -0.157389
+0.016413  0.032946  0.120348  0.068761  0.037326  0.067304  -0.136174  -0.135304  -0.103826  -0.077641
+0.027253  0.018089  0.014880  0.124342  0.198133  0.079506  0.210177  0.142316  0.120867  0.091348
+-0.022413  -0.030613  0.027413  0.234987  0.441475  0.318300  0.424813  0.394662  0.215425  0.155400
+-0.013829  -0.053573  -0.171354  -0.112049  -0.083073  -0.067829  -0.259671  -0.221000  0.206976  0.129037
+-0.054054  -0.148464  -0.316071  -0.276375  -0.365161  -0.458705  -0.583929  -0.521964  0.056830  0.046312
+0.017833  -0.000206  0.017500  0.008500  -0.265775  -0.065176  0.067951  0.000167  -0.172392  -0.113529
+0.044409  0.118664  0.176600  0.147755  0.199918  0.188382  0.260191  0.368555  -0.045273  -0.020145
+0.007352  0.005932  0.022685  0.015475  0.116809  0.056062  -0.017432  0.023852  -0.003759  -0.001173
+-0.004315  -0.003948  -0.021310  -0.015887  -0.012992  -0.021778  -0.030177  -0.192298  -0.001540  0.008734
+0.005403  0.001990  0.003260  -0.012255  -0.012776  -0.144515  0.014383  -0.001423  -0.034418  -0.032173
+0.001422  -0.000709  0.001384  0.001922  0.002969  -0.007860  0.007283  0.109911  -0.054740  -0.029326
+0.003028  0.003506  -0.001676  0.009631  -0.006460  0.102097  0.033199  0.047932  -0.004017  -0.001415
+-0.007667  -0.007523  0.003316  -0.003287  0.015270  0.118529  0.033477  0.059466  0.055632  0.047414
+0.002559  0.000697  -0.003928  0.002855  0.003414  0.096651  -0.011684  -0.059026  0.044645  0.040559
+-0.024068  -0.037318  -0.002568  -0.022148  -0.110898  -0.059625  0.002625  -0.182534  -0.110852  0.008000
+0.004233  -0.005100  0.001053  0.009087  -0.036020  -0.224273  -0.031660  -0.119833  -0.124653  -0.056727
+0.029000  0.041643  0.025929  0.023560  -0.012690  -0.100786  -0.062369  0.129774  0.076083  0.011500
+0.007040  0.011581  -0.017331  -0.008379  0.030548  -0.014669  -0.113895  0.082629  0.083306  0.054484
+-0.001044  -0.001246  0.005261  -0.011335  -0.000831  0.038493  0.003827  -0.051268  -0.033471  -0.021790
+0.014247  0.003123  0.029918  0.010603  0.012959  0.254212  0.053877  0.029452  0.003541  0.005719
+0.036492  0.044943  -0.031811  -0.355262  -0.465680  -0.206779  -0.031549  0.049279  0.015730  -0.020607
+0.057756  0.094802  0.107628  -0.090093  -0.406977  -0.401058  -0.116744  0.076407  0.136291  0.024151
+0.184270  0.321010  0.437260  0.537590  0.672380  0.371880  0.219380  0.218040  0.086710  0.042220
+-0.006141  -0.050234  0.026828  0.351906  0.663781  0.448031  0.146781  -0.067063  0.027359  0.028078
+-0.000453  -0.044814  -0.143884  -0.478547  -0.661070  -0.213326  -0.227988  -0.217686  -0.057291  -0.051488
+0.050242  0.012606  0.065576  -0.120121  -0.331712  0.178015  -0.025712  0.017197  -0.031864  -0.083106
+0.001820  0.007205  0.018344  0.041992  0.363943  0.023861  0.022123  0.036016  -0.007336  -0.008139
+-0.020678  -0.013911  -0.057767  -0.074444  -0.060878  -0.406222  -0.072511  -0.087256  -0.024867  0.016333
+0.085190  0.061707  0.004086  0.265138  -0.094397  -0.355828  -0.119431  -0.060569  0.053931  0.001931
+0.025722  0.013784  0.103531  0.273228  0.124395  0.248630  0.149617  0.117679  0.180691  0.045951
+0.004470  0.002333  0.096091  0.086303  0.053038  0.390848  0.035159  0.032636  0.093045  0.023598
+-0.006891  -0.000768  -0.005681  -0.117862  0.090957  0.074688  -0.052370  -0.023435  -0.046326  -0.023087
+-0.007547  -0.003682  -0.011964  -0.126047  -0.014229  -0.034224  -0.021479  -0.041240  -0.092328  -0.021333
+0.004316  0.017032  0.007380  -0.139114  -0.104013  -0.084608  0.014304  0.014203  -0.050013  -0.032943
+0.041707  0.052026  0.004509  -0.003224  -0.138707  -0.046379  -0.000474  0.076552  0.001759  -0.001888
+0.008398  0.007949  0.012720  0.035457  0.021665  0.053701  0.035630  0.076055  0.010276  0.003217
+-0.026354  -0.021948  -0.005302  -0.087740  0.063323  0.174583  -0.003562  0.008146  0.039583  0.029010
+-0.096891  -0.094709  -0.039027  -0.079791  -0.091573  -0.026427  -0.043564  -0.090300  0.094164  0.060500
+-0.010027  -0.011345  -0.030554  0.007311  -0.164926  -0.189155  -0.072358  -0.134331  0.026473  0.008230
+0.013559  0.014428  0.006757  0.043599  0.007145  0.013849  -0.007954  -0.116625  -0.049026  -0.064059
+0.009093  0.020465  0.005419  0.050965  0.033721  0.040105  -0.059872  0.193477  -0.099046  -0.076023
+-0.032074  -0.032766  -0.002362  -0.008713  0.005447  -0.093138  -0.072606  0.211777  -0.032574  -0.006915
+-0.029674  -0.022849  -0.003512  0.003337  0.193477  0.033721  0.050058  0.191500  0.018512  0.045047
+-0.051433  -0.051010  -0.005010  -0.018798  0.060490  0.264760  0.066865  -0.069692  0.123125  0.116183
+0.110907  0.078759  -0.000111  0.097500  -0.255778  -0.092833  -0.062185  -0.233796  0.044574  0.002741
+0.267000  0.312354  0.135188  0.138083  0.048500  -0.002604  0.028521  -0.031063  -0.053750  -0.016563
+0.004336  0.006486  0.004829  0.022893  0.123921  0.050321  0.001886  0.123750  -0.030557  -0.006279
+-0.023226  -0.024381  0.043131  -0.005167  0.065774  -0.008524  -0.018083  0.108488  0.040726  0.028143
+-0.006643  -0.010955  -0.022026  0.005896  -0.070558  -0.158740  0.019929  -0.001195  0.041208  0.019929
+-0.000862  -0.001147  -0.000839  -0.009321  -0.015339  -0.078193  0.037647  0.048922  -0.002885  0.007596
+0.001797  0.001769  0.006734  -0.004589  0.009929  0.047054  -0.003269  0.026554  -0.002089  0.002026
+0.005743  0.002605  0.014819  0.010671  0.027881  0.051524  -0.062695  0.015943  -0.024871  0.009971
+-0.001884  -0.001869  -0.003037  -0.015687  0.007897  -0.002422  -0.095312  -0.020094  -0.017834  -0.022597
+-0.009531  -0.004000  -0.010382  -0.021316  -0.024333  -0.009294  -0.060930  -0.040588  -0.014276  -0.078110
+-0.004457  0.003506  0.004346  -0.001401  0.026870  0.096599  0.154481  0.004784  0.043827  0.019914
+-0.004714  0.000145  -0.004559  -0.007000  -0.018759  -0.018914  0.177318  0.064973  0.027618  0.047991
+0.001250  -0.006436  -0.019203  -0.009855  -0.040657  -0.106558  -0.090930  -0.029971  -0.061610  -0.052593
+-0.003919  -0.002265  0.004015  0.008415  0.000958  -0.014715  -0.174146  -0.048227  -0.030269  -0.049696
+0.009301  0.005724  0.033612  0.016872  0.034755  0.163311  0.040597  0.030643  0.007929  -0.021357
+0.001819  0.008112  0.022675  0.023606  0.072575  0.012969  0.143281  0.055044  -0.002894  0.041800
+0.001732  0.010375  -0.033420  -0.004205  -0.030116  -0.145205  0.054795  0.091134  0.027902  0.053554
+-0.016948  -0.009078  -0.059905  -0.030440  -0.067129  -0.062483  -0.020164  0.044578  0.091138  0.054103
+-0.004038  -0.002604  0.007075  0.019849  0.016953  0.017113  -0.227019  -0.114925  0.165689  0.053500
+-0.002102  -0.005102  -0.000046  0.013676  0.030991  0.098704  -0.041315  -0.161444  0.036278  0.008630
+-0.053149  -0.090541  0.055568  -0.041703  0.010986  0.129108  0.052041  -0.011811  -0.450000  -0.153851
+0.011750  -0.011845  -0.019774  -0.045774  -0.027155  -0.066095  -0.080667  -0.088607  -0.501571  -0.277548
+0.003011  0.023174  -0.005478  -0.065033  -0.178457  -0.108989  -0.037707  -0.020620  0.363869  0.201261
+-0.013268  -0.009963  -0.030744  -0.044415  0.037598  0.070720  0.012085  0.029098  0.485976  0.203061
+-0.022900  -0.028083  0.059483  -0.049200  0.020750  0.288100  0.109267  0.149533  -0.161417  -0.236367
+0.009394  -0.015926  0.081362  0.078372  0.116702  0.102340  0.035585  0.056670  -0.341851  -0.037660
+-0.043394  -0.022333  0.033909  0.056561  0.217742  -0.121273  -0.031652  0.032485  0.004136  0.088136
+-0.016239  -0.023813  -0.031396  -0.004030  -0.105821  -0.134328  0.149007  0.007134  0.096910  0.120806
+-0.013833  -0.014689  -0.023750  -0.015894  -0.217394  -0.148378  0.026511  -0.013489  -0.001978  -0.004594
+0.004176  0.008507  -0.009155  -0.028423  -0.090944  -0.046444  -0.209056  0.010190  -0.023711  -0.069197
+0.004243  0.008191  0.004647  0.022390  -0.008618  0.077206  -0.263176  -0.039728  -0.002551  -0.047360
+0.006581  0.004157  0.010657  0.000329  0.036519  0.035329  -0.134257  0.005543  0.025862  0.015605
+0.003385  0.002622  0.004392  0.023395  0.012941  0.024976  0.020909  0.020287  0.025944  0.057612
+-0.006261  -0.000565  0.000935  0.011609  -0.018804  -0.026812  0.113384  0.015580  -0.024101  -0.082036
+-0.032761  -0.058967  0.000076  0.012272  0.010739  0.063978  0.040793  -0.140304  -0.191467  -0.244424
+-0.002402  -0.001880  0.014185  -0.016707  -0.018054  0.063989  -0.007359  -0.163293  -0.148370  -0.054946
+0.021384  0.027638  0.041775  0.089065  0.079225  0.059703  0.059638  0.065913  0.289029  0.269761
+0.075389  0.101153  0.145347  0.145028  0.004681  -0.022000  0.208639  0.262195  0.361389  0.269556
+0.012109  0.014406  -0.039937  -0.100656  -0.056906  -0.215984  0.154828  0.104578  -0.191875  -0.091812
+-0.000317  -0.010667  -0.026133  -0.012800  -0.099792  0.012017  -0.042700  -0.048692  -0.121483  -0.156817
+-0.045480  -0.039539  0.037971  -0.006529  0.015863  0.117157  -0.148598  -0.090706  0.020343  0.011206
+-0.001388  -0.000044  -0.006131  0.002694  -0.024898  -0.051694  -0.100243  -0.002738  0.034801  0.021825
+-0.003100  -0.001300  -0.012485  -0.005774  -0.024096  0.003226  0.040259  0.022730  0.001189  0.014856
+0.001557  -0.004116  0.020582  -0.010698  -0.001491  0.063230  -0.000013  -0.016097  0.002330  0.007843
+0.012824  0.007808  0.037907  -0.001225  0.017956  -0.026434  -0.003813  0.010368  -0.023445  -0.009621
+-0.001600  0.003753  -0.015384  0.019568  0.036889  -0.108195  -0.002295  -0.012789  -0.022484  0.002863
+-0.021278  -0.010460  -0.084167  0.026619  0.003929  -0.065016  -0.026992  -0.015397  -0.019246  0.004532
+-0.008147  -0.011787  0.073073  0.004127  -0.001120  0.102687  -0.023867  0.024340  -0.033773  -0.030347
+0.033000  0.059336  0.144721  0.037025  0.064525  0.113582  -0.034164  0.015418  0.065361  0.014287
+-0.005375  0.002111  -0.024181  0.036326  0.095736  -0.032271  0.006799  -0.029951  0.034576  0.015326
+0.008000  -0.013762  -0.100437  0.071925  0.057312  -0.034862  0.125025  0.034387  -0.003413  0.000612
+0.093821  0.084244  -0.089256  -0.024192  -0.107885  -0.257423  0.045821  0.051000  0.029333  -0.007410
+0.007302  0.016965  -0.075163  -0.083500  -0.143570  -0.392186  -0.133686  -0.113895  0.152128  0.107802
+-0.175771  -0.213958  0.063396  -0.122792  0.076354  0.314167  -0.022271  -0.074417  -0.167542  -0.027479
+0.045853  0.160647  0.481941  0.485559  0.613853  0.415618  -0.153412  -0.085382  -0.029618  -0.006000
+0.039571  0.011768  -0.067500  0.054018  0.073946  0.186786  0.101964  0.023464  -0.018982  -0.225375
+-0.099618  -0.251368  -0.413412  -0.432735  -0.560662  -0.521265  0.001191  0.029397  -0.050441  -0.003000
+0.042980  -0.031235  -0.116133  -0.161255  -0.385214  -0.455133  0.136490  0.029276  0.012010  0.068990
+-0.009442  -0.012135  -0.127692  -0.227135  0.243269  0.060096  -0.078577  0.027058  -0.009827  -0.050058
+-0.004410  -0.009885  -0.041654  -0.025308  0.328051  0.385487  -0.115628  -0.045167  0.038179  -0.048372
+0.214181  0.354104  0.541776  0.457078  0.069233  0.039155  0.069078  0.109621  0.231603  0.166741
+0.160830  0.341574  0.416734  0.136096  -0.034138  -0.067149  0.131862  0.159160  -0.034872  -0.042968
+-0.112851  -0.198311  -0.173595  -0.125459  -0.034257  0.026351  -0.132405  -0.106500  -0.161892  -0.160392
+-0.096607  -0.157393  -0.092845  -0.027714  0.067476  0.054929  -0.007857  0.018143  -0.008750  -0.037524
+0.077854  0.147677  0.056573  -0.070865  0.000979  0.012771  0.013594  0.054260  0.055385  0.031885
+-0.003318  -0.001693  -0.000159  -0.037918  -0.022625  -0.030503  -0.009554  -0.036841  -0.019616  -0.008378
+0.003737  0.009435  -0.041291  0.026025  0.004493  0.003705  0.010076  0.016568  -0.006795  -0.005094
+0.003355  -0.001776  -0.146711  0.014934  -0.014776  0.025921  0.007671  0.050776  0.014855  0.010987
+-0.045019  -0.023991  -0.022925  -0.025566  -0.024415  -0.003953  0.000358  -0.002717  0.009698  -0.014981
+-0.046216  -0.050830  0.051989  -0.043989  -0.001614  0.014875  -0.028409  -0.047239  -0.028182  -0.005466
+-0.017721  -0.023279  0.041827  -0.050885  0.079538  0.037654  0.035298  0.017769  -0.006058  0.008942
+0.000029  -0.000511  0.001004  -0.004445  0.049191  0.012618  -0.031136  -0.021614  0.019529  0.024107
+0.003830  0.008610  -0.008632  0.075022  -0.059489  -0.041330  -0.036291  -0.011269  0.005060  -0.016165
+0.007312  0.003279  0.023558  0.048968  -0.129370  -0.048318  0.018162  -0.013084  -0.043377  0.012227
+0.001801  0.000012  0.006349  0.002398  -0.067253  0.035633  0.034018  0.013361  0.023054  0.047265
+-0.042630  -0.056100  -0.097790  -0.010760  -0.033250  0.125790  0.099250  0.011160  0.084780  0.058650
+-0.019973  0.022662  -0.139068  -0.171041  -0.000230  -0.229122  -0.003743  0.020757  -0.087216  0.012486
+0.053818  0.129045  0.081477  -0.068773  0.112682  -0.247727  -0.063682  0.002568  -0.160068  -0.089932
+0.010377  -0.003331  0.142546  0.298108  0.151223  0.161177  0.005838  -0.010708  0.076200  0.016446
+-0.085900  -0.151300  -0.057520  0.121000  -0.050900  0.139740  -0.063560  -0.101160  0.078460  -0.004840
+0.050750  0.014933  -0.132117  -0.324917  -0.346233  0.137817  0.165217  0.019550  -0.052717  -0.083317
+0.136606  0.141106  0.047455  -0.064045  -0.171561  -0.111212  0.096333  0.151000  -0.103121  -0.043061
+0.008115  0.018656  0.026500  0.180531  0.147271  -0.167552  -0.046750  -0.065781  -0.035312  -0.020823
+-0.075940  -0.094400  0.025850  0.056480  0.176060  0.040370  -0.046940  -0.092550  -0.013380  0.023520
+-0.002714  -0.003187  -0.001313  -0.015011  0.025687  0.120121  -0.060648  -0.027819  0.008341  -0.009280
+-0.004375  -0.001625  -0.012362  -0.007506  -0.006588  -0.143100  -0.017769  0.028500  0.014188  0.011200
+-0.002634  0.005128  -0.038977  0.025535  -0.016279  -0.065273  0.033395  0.007006  -0.002965  -0.017017
+0.006018  0.004974  0.004287  0.009669  0.006989  0.048140  0.068379  0.019904  -0.010853  -0.008096
+0.006892  -0.000575  0.051986  0.020429  0.018042  0.070943  0.028108  0.041382  0.014146  0.017264
+-0.001965  0.000791  -0.006287  0.018858  -0.017626  0.046098  -0.015035  -0.004606  0.031154  0.009268
+-0.000570  -0.001705  -0.003311  -0.007500  -0.000036  -0.043606  -0.005964  0.006831  -0.035742  -0.052692
+-0.002836  -0.006388  -0.018280  -0.007056  -0.004346  -0.105981  -0.018668  -0.028019  -0.104234  -0.044388
+0.017152  0.008455  0.030015  0.073985  0.054455  0.022182  -0.014553  -0.065144  -0.019659  0.009629
+-0.002798  -0.003921  0.046545  0.139225  0.090118  0.177197  0.066539  -0.016657  0.131331  0.061472
+0.011862  0.027687  0.003125  0.146787  0.239913  -0.138588  -0.171450  -0.115838  0.118200  0.087762
+-0.009185  -0.012352  -0.024759  0.210852  0.268852  -0.341074  -0.371537  -0.369759  -0.147926  -0.069278
+0.018933  0.007017  -0.067800  -0.480050  -0.567567  0.057200  0.195300  0.199500  0.064417  0.075600
+-0.004214  -0.026143  -0.011571  -0.217881  -0.161476  0.337000  0.475857  0.415452  0.074048  0.038548
+0.008514  0.005020  0.014385  0.320196  0.392453  0.029324  0.033851  0.017689  -0.005791  0.015095
+0.010763  0.015816  0.031500  0.249092  0.276237  -0.051803  -0.013224  -0.151118  -0.101750  -0.044421
+0.006668  -0.003826  0.060804  0.003234  -0.034375  -0.021832  -0.000967  -0.019250  -0.008935  -0.003609
+-0.002211  -0.000725  -0.005763  -0.005243  0.000632  -0.066836  -0.014348  0.002357  0.000591  0.001690
+-0.005605  0.000880  -0.040275  -0.032645  -0.017135  -0.082090  0.011020  -0.017120  0.003110  0.008130
+-0.001875  -0.000208  -0.006584  -0.005323  -0.004818  0.006117  0.006784  0.001483  0.012628  0.010504
+-0.000615  -0.002010  0.002647  -0.009829  0.005752  0.094371  0.006986  0.008042  0.022350  0.017822
+-0.002955  -0.002721  -0.000805  -0.016006  0.004377  0.017864  -0.043104  -0.047383  -0.000471  0.005455
+0.003698  0.002401  0.004843  0.007519  -0.004472  -0.022173  -0.033515  -0.033599  -0.003870  -0.007966
+-0.003271  -0.003602  0.000071  0.010410  -0.049564  -0.029519  -0.008301  -0.049128  0.055455  0.033857
+-0.001424  -0.005076  -0.024946  -0.020087  -0.118783  -0.147848  -0.013478  -0.071717  0.025239  0.137413
+-0.003856  0.002040  -0.007057  -0.031000  -0.050080  -0.106523  0.029856  0.020063  -0.127149  -0.039592
+0.009808  0.016400  0.020692  0.036100  0.080000  0.033583  0.041275  0.052942  -0.108642  -0.141492
+-0.013506  -0.004801  0.048712  0.004801  0.169462  0.163064  0.086705  0.064981  0.085577  0.044346
+0.005885  0.010123  -0.002269  -0.042831  -0.135677  0.000177  0.009254  -0.008862  0.086708  0.114177
+-0.007121  -0.005667  -0.052201  -0.087454  -0.229046  -0.073264  -0.028615  -0.063874  -0.074523  -0.056109
+-0.049612  -0.043776  0.005633  0.066908  0.386949  0.207245  -0.096153  -0.087255  -0.098551  -0.042122
+0.007417  -0.004810  0.098393  0.386179  0.592643  0.214940  -0.196488  -0.131786  -0.034714  -0.011512
+-0.039753  -0.068063  -0.044139  0.172696  0.291297  0.231494  0.037006  -0.003000  0.069677  0.040101
+-0.076897  -0.115192  -0.164244  -0.048462  0.125154  0.015103  -0.129820  -0.152833  -0.040231  0.013064
+0.062543  0.092000  -0.038529  -0.456600  -0.711672  -0.453143  0.028471  0.066129  -0.045057  -0.016129
+0.085650  0.118983  0.076150  -0.181017  -0.532267  -0.311950  0.212300  0.227583  0.068900  0.055150
+-0.079574  -0.110382  -0.103191  -0.004721  0.383971  0.480191  0.223912  0.217191  0.221441  0.080250
+-0.203395  -0.298263  -0.258947  0.024289  0.287579  0.237789  0.158868  0.104632  -0.021763  -0.043158
+0.100903  0.133161  0.124935  0.148613  0.067919  -0.139726  -0.092081  -0.154000  -0.233113  -0.111645
+0.057020  0.070461  0.096275  0.126186  0.191559  -0.048108  -0.080873  -0.009735  -0.077059  -0.021010
+0.007764  0.002397  0.008580  0.006713  -0.019385  0.072724  -0.019971  0.058310  0.057144  0.011172
+-0.004052  -0.006414  0.079121  -0.038759  -0.023328  -0.018448  0.011302  -0.021043  0.053802  0.051198
+-0.001127  0.003290  -0.031571  -0.010067  -0.020996  -0.146488  -0.024313  -0.085897  -0.010869  -0.014409
+-0.019683  -0.027793  -0.107317  -0.037238  -0.071628  -0.157994  -0.036585  -0.098585  -0.043610  -0.030537
+-0.001324  -0.002370  -0.015639  -0.006954  -0.026880  0.109000  -0.019648  0.111333  0.004102  -0.002296
+0.005493  0.011118  0.054603  0.038809  0.015132  0.141662  0.049132  0.167103  0.102971  0.048066
+-0.001552  0.001035  -0.004058  0.001924  0.022355  -0.071901  0.076360  -0.006669  0.002762  0.016634
+-0.007608  -0.000366  -0.014414  -0.029247  0.020247  0.002349  0.039441  -0.079769  0.022602  0.010742
+-0.001919  -0.009517  0.010587  -0.045250  -0.037279  0.051634  -0.036988  -0.028669  0.035593  0.021134
+-0.004728  -0.003076  -0.007008  -0.015100  -0.046736  0.001164  -0.079296  -0.003848  -0.002736  0.002888
+0.010773  0.006101  -0.028490  0.059348  0.067010  0.037364  -0.014722  0.009318  -0.014894  -0.020753
+-0.001348  -0.009366  -0.005304  -0.083795  -0.148420  0.090857  0.111509  0.016080  0.045036  0.042446
+-0.027104  -0.020348  -0.047616  -0.170732  -0.205262  -0.218146  0.019841  0.037591  -0.059543  -0.023366
+0.037714  0.034929  -0.031821  0.084036  0.091500  -0.331589  -0.048232  -0.067607  -0.199339  -0.148946
+0.101633  0.096117  0.068233  0.244700  0.213000  0.075525  0.067242  0.043400  0.074900  0.077475
+-0.048125  -0.009080  0.114107  0.048491  0.141161  0.373170  0.118625  0.161348  0.290830  0.153545
+0.000514  0.023458  0.085486  -0.112431  0.008097  0.088736  0.038972  0.075417  0.064833  0.056292
+-0.010239  -0.007261  0.026193  0.153080  0.028375  -0.105784  0.014091  0.026852  0.011250  0.002659
+0.034875  0.033429  -0.149875  0.012982  -0.109929  -0.059018  0.009964  -0.029286  -0.068214  0.009161
+-0.031942  -0.088212  -0.278423  -0.359308  -0.066317  -0.033404  -0.091423  -0.136019  -0.255087  -0.170135
+-0.008269  -0.005857  -0.024891  -0.139597  -0.014122  -0.013319  -0.013336  -0.008626  -0.026655  -0.011374
+0.043679  0.072538  0.216085  0.246538  0.023538  0.087802  0.134132  0.202340  0.090613  0.045934
+-0.032072  -0.054289  0.007902  0.253350  0.324722  0.247443  0.209340  0.128644  0.000160  -0.000515
+-0.112767  -0.219667  -0.350700  -0.217950  0.125500  0.046783  0.049683  -0.030217  -0.252500  -0.136333
+0.064419  0.061927  0.054710  -0.161734  -0.606532  -0.406718  -0.192944  -0.139742  -0.167177  -0.115710
+0.178280  0.306480  0.410660  0.100420  -0.313060  -0.213480  -0.003460  0.165680  0.231740  0.118580
+-0.014806  0.004917  0.063046  0.220991  0.495796  0.494759  0.068194  0.073806  0.064870  0.000398
+-0.112880  -0.263100  -0.433440  -0.176090  0.011180  -0.127630  -0.204240  -0.209740  -0.221260  -0.105410
+-0.104924  -0.232169  -0.436907  -0.334288  -0.310110  -0.502729  -0.240212  -0.297670  -0.090415  -0.034559
+0.005170  0.027740  0.076850  0.087880  0.104610  0.165770  0.085110  0.150810  0.133040  -0.051800
+0.041011  0.066130  0.132815  0.128141  0.136815  0.221848  0.144435  0.132793  -0.133435  -0.082902
+-0.000008  -0.001043  -0.000791  0.003189  0.010795  0.014925  -0.003732  0.028343  -0.063405  -0.013760
+0.006713  0.003713  0.004262  0.032354  -0.019659  0.021939  -0.088531  0.010799  0.074707  0.019165
+0.001586  0.000657  0.005131  0.004123  -0.002724  0.017817  0.017194  -0.058593  0.031269  0.010526
+0.000142  -0.001939  0.002835  -0.002830  0.001222  -0.008038  0.023458  -0.035939  -0.041778  0.030915
+-0.004182  -0.004482  -0.001158  -0.020227  0.001848  -0.009094  0.014106  -0.002021  -0.077539  -0.035212
+0.000746  0.000717  -0.003783  0.000402  0.000610  0.006292  0.006237  0.011543  -0.029697  -0.047113
+0.003366  0.002763  0.006305  0.014268  -0.004097  0.008347  -0.012582  0.019737  0.028305  0.016358
+0.001207  0.000553  -0.002813  0.002957  0.012697  -0.010987  -0.016720  -0.008860  0.064260  0.059973
+0.006075  0.004595  0.001972  0.008115  0.023706  -0.038964  0.013794  0.040556  0.052433  0.053036
+0.010793  0.014598  0.025674  0.034000  0.039022  0.037065  0.078924  0.080630  0.055902  -0.111283
+0.002763  -0.000026  0.001612  0.014599  0.017428  0.075914  0.030697  -0.001882  -0.057717  -0.087605
+-0.006159  -0.008971  -0.001376  0.014824  0.047600  0.077153  -0.061418  -0.099406  -0.054382  -0.007141
+-0.002724  -0.005586  -0.003810  -0.018448  -0.021974  -0.031517  -0.075543  -0.072026  -0.057638  0.056345
+0.001583  0.003090  -0.009226  0.005545  -0.011274  -0.066996  0.002981  -0.006143  0.058823  0.033195
+-0.001360  -0.000728  -0.000664  -0.004356  0.010088  0.015076  -0.038940  -0.007928  0.026688  -0.015752
+0.001356  0.000406  -0.002772  -0.000722  0.001000  0.042639  0.014472  0.041439  -0.151728  -0.027711
+-0.002087  -0.001855  0.000855  -0.012326  -0.001831  -0.027888  0.082831  0.085479  -0.068719  -0.011095
+0.006795  0.010609  -0.014205  0.001532  -0.020141  -0.064622  0.099942  0.071673  0.128462  0.037840
+-0.005100  -0.002653  -0.002141  0.004865  -0.013000  -0.026224  0.008359  -0.009406  0.147859  -0.014576
+0.000990  0.000720  -0.019890  0.015520  0.015780  0.065610  0.009120  -0.005060  0.024090  -0.068260
+-0.015131  -0.017619  -0.006091  -0.002415  0.035392  0.099494  -0.032011  -0.043045  -0.082557  -0.069989
+-0.001912  -0.002494  0.000967  -0.013158  0.015645  0.027661  -0.039448  -0.011015  -0.068873  -0.040970
+-0.008172  -0.007994  0.016374  -0.005770  0.013971  0.143707  0.057782  0.154667  -0.024489  -0.032862
+-0.002478  -0.002809  -0.003743  -0.013043  0.006426  0.026222  0.108548  0.113922  -0.014513  0.044670
+-0.013655  -0.011474  -0.035052  -0.023284  -0.064345  -0.294302  -0.123112  -0.162991  -0.028440  0.046147
+0.042238  0.039548  -0.039762  0.061893  -0.027595  -0.481012  -0.170083  -0.182405  -0.015714  0.016083
+0.021930  -0.002260  0.002730  0.025490  -0.144510  -0.221450  0.210810  0.117630  -0.005800  0.001040
+0.011939  -0.020348  -0.020152  -0.094227  -0.074727  0.544258  0.376879  0.151182  0.043212  0.012591
+-0.009926  0.005296  0.130278  0.127019  0.390537  0.736463  0.079185  -0.016667  0.047204  0.031722
+0.024109  0.098793  0.157228  0.160630  0.305587  0.077500  -0.044663  -0.021565  0.041826  0.058217
+0.098042  0.118000  0.095875  0.132083  -0.367792  -0.595708  0.016625  0.114667  -0.016917  0.037125
+0.050713  -0.005981  -0.160546  -0.155537  -0.266611  -0.589306  -0.117787  -0.133130  -0.226731  -0.129278
+-0.030696  -0.050411  -0.078143  -0.150036  0.166679  0.285929  -0.030393  -0.076875  -0.187661  -0.067750
+-0.040712  -0.055515  0.014053  0.008727  0.204599  0.354780  0.142651  0.053394  -0.010598  0.010515
+-0.018292  -0.014177  0.062723  0.075662  -0.012054  0.053954  0.138308  0.083154  0.107300  0.035738
+-0.005433  -0.004732  0.000970  -0.081140  -0.009726  -0.014518  -0.006689  -0.016537  0.153177  0.056726
+-0.014786  -0.010464  -0.004429  -0.127274  -0.020435  -0.002827  -0.018167  -0.028780  -0.179607  -0.097238
+-0.004944  -0.012112  -0.000851  0.012478  -0.019549  -0.018810  -0.004642  0.002545  -0.190019  -0.073746
+0.004615  0.001797  -0.001236  0.002152  0.003787  0.003118  0.029959  -0.004713  0.116226  0.084135
+-0.003201  0.001244  -0.021671  -0.050680  -0.011709  -0.020637  -0.023419  -0.010748  -0.000081  0.005551
+0.004291  0.004296  0.001937  0.049985  -0.010927  -0.020927  0.027223  -0.019282  -0.057456  -0.035053
+0.006867  0.013171  0.052506  0.127089  -0.004405  0.010785  0.030981  0.055316  0.200930  0.084462
+0.000332  0.000889  -0.000630  -0.011712  -0.012842  0.002582  -0.027323  -0.016494  0.061006  0.013437
+-0.017842  -0.010411  -0.016856  -0.113084  -0.051505  -0.074698  -0.049980  0.002624  -0.147995  -0.060614
+-0.036365  -0.026548  -0.080905  -0.116810  -0.079563  -0.062937  0.068413  0.000675  0.060825  0.078468
+-0.000642  0.003167  0.017556  0.009951  0.019716  0.121920  0.045111  0.036506  0.213420  0.138839
+0.015230  0.063257  0.209189  0.063743  0.028608  0.086784  -0.036811  0.032635  -0.111338  -0.090189
+-0.071484  -0.125459  -0.151557  -0.104164  -0.156861  -0.199836  -0.116467  -0.145934  -0.331148  -0.258279
+-0.104328  -0.205948  -0.366345  -0.163638  0.097328  0.103603  0.062069  0.003328  0.134397  0.047690
+0.142062  0.272494  0.418216  0.402957  0.239265  0.361722  0.400809  0.415210  0.490099  0.290463
+0.062518  0.060625  0.029625  -0.063321  -0.003339  -0.180411  -0.167482  -0.188821  -0.273036  -0.022661
+-0.098154  -0.250231  -0.414452  -0.373673  -0.194779  -0.231692  -0.294962  -0.453923  -0.319865  -0.125365
+-0.007230  0.011836  0.064033  0.217025  0.035811  0.101779  0.161926  0.146148  0.373197  0.127779
+-0.268893  -0.217893  0.036429  -0.093786  -0.039250  -0.032214  0.048214  0.063964  0.121286  0.025714
+-0.043619  -0.076964  0.029607  -0.094726  -0.067964  0.057976  -0.259952  -0.170345  -0.354250  -0.393679
+0.062336  0.095031  0.158016  0.156297  0.124312  0.194844  0.027148  0.027156  -0.003141  -0.022398
+0.156955  0.173545  -0.024455  0.053136  -0.065152  -0.107318  0.172803  0.131045  0.169530  0.098833
+0.008745  -0.001968  -0.184989  -0.030074  -0.031723  -0.156160  -0.077532  -0.024628  0.109638  0.068340
+-0.080500  -0.098097  -0.008274  -0.001597  0.079984  -0.033097  0.035452  -0.032226  0.062032  0.050161
+-0.033098  -0.046461  -0.038627  -0.045686  -0.064078  0.112255  0.157373  0.012951  -0.013814  -0.034716
+-0.002198  -0.001299  0.001858  -0.008096  -0.008864  -0.015204  -0.005824  -0.006364  -0.128488  -0.025062
+0.005184  0.012857  0.086684  0.007449  0.045592  -0.040571  -0.117163  -0.018327  0.014398  0.046449
+0.011670  0.005106  0.024638  0.024482  0.001963  0.051353  -0.008679  0.007950  0.065385  0.069147
+-0.000672  -0.000181  -0.011690  -0.029422  -0.094440  0.020103  0.127216  0.013000  -0.017690  -0.034957
+-0.014961  -0.018844  -0.017000  -0.074578  -0.100883  0.000786  0.059623  0.070883  0.022045  0.008584
+-0.087510  -0.108625  -0.099010  -0.093779  -0.084548  -0.116423  -0.082865  0.037308  -0.028875  -0.039702
+-0.002520  -0.008364  -0.030081  -0.003540  -0.056641  -0.099884  -0.014818  -0.049288  -0.198687  -0.157838
+0.014619  0.018000  0.015774  0.005071  0.089286  0.002226  -0.110857  -0.062500  -0.145190  0.041226
+0.011560  0.014190  0.036976  0.061286  0.038405  0.131119  -0.091048  -0.062786  0.205964  0.233048
+0.001085  0.009457  0.006646  0.006585  0.006970  -0.004061  -0.033701  -0.034732  0.287866  0.050652
+0.002116  0.010488  -0.016663  -0.016360  -0.036047  -0.131337  -0.038581  -0.072116  0.051326  -0.118605
+-0.039740  -0.027894  0.002385  -0.025692  -0.095519  -0.084798  -0.054308  -0.020077  -0.014587  0.053596
+-0.028877  -0.029500  -0.004877  -0.072575  0.063085  0.133991  0.072311  0.060868  -0.173170  -0.008858
+-0.007779  0.000314  0.015860  0.002360  0.076140  0.014070  0.151907  0.156849  -0.270023  -0.163279
+0.115757  0.153176  0.100703  0.036608  0.027851  -0.111297  0.059257  0.088878  -0.027365  0.003689
+0.005651  0.005314  0.013628  0.085128  -0.029733  -0.023942  -0.016215  -0.014733  0.099430  0.086942
+-0.007665  -0.008813  -0.007659  -0.007500  0.015352  0.045126  -0.018769  0.006297  0.070022  0.052429
+-0.002822  -0.000780  -0.009629  -0.000171  0.009027  -0.026959  -0.001551  -0.028615  0.019800  0.012029
+-0.001954  -0.001802  0.000660  -0.003731  -0.015753  -0.035785  0.020177  0.008323  -0.000228  -0.003408
+-0.002350  0.000324  -0.014718  -0.030510  0.010503  -0.024710  0.015715  0.018826  -0.008987  -0.000044
+-0.004361  -0.003962  -0.002820  -0.055244  0.005589  0.031332  -0.002908  0.005184  -0.002968  -0.007528
+-0.001146  -0.000782  -0.001478  0.003246  -0.028160  -0.003854  0.001311  -0.028498  0.000378  -0.009242
+0.004580  0.003674  -0.005045  0.055969  0.002444  -0.005507  -0.006308  -0.009596  -0.001379  -0.004007
+0.006414  0.001939  0.010273  0.019871  0.013050  0.041842  -0.000032  -0.003403  0.010273  0.014187
+0.002212  -0.005414  0.023106  -0.008332  0.012479  0.008702  -0.010493  -0.009637  0.001695  0.006010
+-0.009308  -0.004902  -0.016013  -0.001363  0.011299  -0.044590  -0.053124  -0.038372  -0.001936  0.012419
+-0.000102  0.000734  -0.003380  0.011482  0.028570  0.003627  0.006918  -0.002998  -0.002077  -0.006086
+0.004382  0.002838  0.008794  0.003917  0.038285  0.014772  0.019513  0.038794  -0.013570  -0.013781
+0.006551  0.004193  0.009784  0.063635  0.027517  0.035959  0.006872  0.004429  0.040520  0.007429
+-0.004698  0.004864  -0.039346  0.032673  0.012821  0.017525  -0.002451  -0.019333  0.035525  0.032802
+-0.000776  0.016872  -0.053128  -0.031244  0.012321  0.012840  -0.010603  -0.005186  -0.007372  -0.005462
+-0.014492  -0.015811  -0.018432  -0.057538  -0.088614  0.042636  -0.024530  -0.022364  -0.077364  -0.009705
+-0.037273  -0.056791  0.010691  0.033900  -0.158409  -0.052882  -0.049991  -0.083382  0.024091  0.016627
+-0.003157  -0.001150  -0.006483  0.004017  -0.014930  -0.073450  -0.003423  -0.054793  -0.009897  -0.014997
+0.014386  0.010920  -0.034102  -0.047693  0.082648  -0.058148  -0.015705  0.007443  -0.147352  -0.122011
+0.002500  0.001875  0.024760  -0.016708  0.061958  -0.056042  0.034615  0.108573  -0.007490  0.024563
+0.012351  0.010014  0.007973  0.024291  -0.019041  -0.043709  -0.012095  0.121439  0.036466  0.049230
+0.000342  -0.000125  0.000776  0.030243  -0.027276  -0.005605  0.006342  -0.026217  0.046211  -0.066461
+-0.003454  0.004880  -0.054972  -0.038722  -0.088667  0.051815  0.014176  -0.070306  0.071944  -0.007667
+-0.008877  -0.018849  -0.016255  -0.100170  -0.144396  0.187594  0.039142  0.078123  0.016160  -0.023142
+0.012598  0.000902  0.022484  0.006311  -0.010484  0.184672  -0.039934  -0.033164  0.040221  0.051902
+-0.000157  -0.000491  0.000109  -0.001157  -0.022535  -0.032426  -0.024443  0.041774  0.042700  0.022378
+0.000731  0.002894  0.002750  0.016692  -0.009606  -0.304721  0.004077  0.106317  -0.040837  -0.032433
+0.008609  0.013482  0.010973  0.051173  0.078527  -0.173145  -0.047255  0.006055  -0.091164  -0.053864
+0.016363  0.016157  0.033588  0.075637  0.102637  0.065765  -0.162118  -0.059931  -0.050814  -0.041520
+0.004143  -0.000714  0.027850  0.108086  0.137864  0.168607  -0.114871  -0.078593  0.042264  0.012364
+-0.001169  -0.007077  -0.012261  0.119070  0.095099  -0.001958  -0.023824  -0.031310  0.093606  0.054282
+-0.112548  -0.105355  0.047371  0.147452  0.069323  0.047242  0.084258  0.088790  0.062032  0.030806
+-0.018911  -0.003573  -0.015879  -0.245605  -0.005565  0.003339  -0.007403  0.014379  -0.003153  0.006710
+0.001047  0.019102  -0.123906  -0.161578  -0.133852  -0.041984  0.001398  -0.022477  0.024969  0.002875
+0.151359  0.136875  0.153422  0.150484  0.008484  0.038781  0.214688  0.096250  -0.102266  -0.085531
+0.013304  0.012837  0.096924  0.142239  0.005913  0.003272  -0.019750  -0.008076  -0.127609  -0.040565
+-0.010875  -0.004243  -0.049396  -0.138590  -0.077472  -0.059028  -0.418618  -0.122486  -0.080278  -0.135271
+-0.008542  -0.004621  -0.001826  -0.039784  0.015626  0.005153  -0.097305  -0.013795  0.057232  -0.032000
+0.028654  0.026654  0.026269  -0.017513  -0.078115  0.057179  0.510628  0.158269  0.092321  0.133692
+-0.015689  -0.021613  -0.049745  -0.018491  -0.062717  -0.039151  0.229198  -0.049377  0.018453  0.029877
+-0.022100  -0.033433  0.046650  0.159933  0.111100  -0.107133  -0.188417  0.076250  0.060567  0.046183
+0.022317  0.008769  0.035423  0.035952  -0.016567  -0.103587  -0.377731  0.013683  0.075269  0.005096
+-0.010863  -0.018443  -0.020137  -0.095571  -0.120325  -0.048316  -0.158090  -0.123802  -0.078557  -0.083217
+0.009895  0.031018  0.059974  0.107088  0.088939  0.144623  0.377421  0.013728  -0.001535  0.000816
+0.014911  0.040911  0.033060  0.070518  0.073375  0.198756  0.254149  0.091732  0.088583  0.072976
+-0.029500  -0.019702  -0.059714  -0.027310  0.045095  0.050702  -0.061143  -0.012667  0.033417  0.067500
+-0.019462  -0.018863  -0.011104  -0.041066  -0.024286  -0.113115  -0.123242  -0.059560  0.033538  0.013110
+-0.004582  -0.003159  0.002644  -0.022000  0.000577  -0.091260  -0.062649  -0.004428  -0.029139  -0.006457
+-0.009761  -0.020489  0.108693  -0.003614  0.033273  -0.001443  -0.007227  0.061182  -0.081250  -0.036227
+0.002879  0.001188  0.008374  0.009087  -0.008248  0.022235  0.020351  -0.001260  -0.009347  -0.011696
+0.001505  0.003924  -0.004460  0.008475  0.002298  0.002242  0.007455  0.019995  0.054848  -0.034742
+0.004005  0.003559  -0.012050  -0.000658  0.013964  0.005748  -0.065086  0.026680  -0.006144  -0.006982
+-0.007611  -0.007382  -0.007046  -0.011918  -0.024854  -0.007818  -0.125982  -0.096900  0.032779  -0.000204
+0.000788  -0.000888  0.006073  -0.004958  0.001085  -0.026469  -0.030473  -0.090969  0.022712  0.013408
+-0.000191  0.001113  0.000907  0.027758  0.021428  0.011454  0.140706  -0.003613  -0.004825  0.004711
+0.007053  0.004000  0.008876  0.012920  0.010690  0.030664  0.043597  0.041093  -0.053562  0.012332
+-0.003291  -0.004170  0.021635  -0.053326  0.003170  -0.006486  -0.016149  0.001355  0.001730  0.007968
+-0.000113  -0.000435  0.008659  -0.005267  0.001118  0.003918  0.006401  0.016138  0.002400  -0.001376
+0.000301  0.000564  -0.002722  0.008336  -0.007193  0.001900  -0.022967  -0.005035  0.000973  0.000444
+0.001097  0.005055  -0.004500  -0.000024  -0.071517  -0.048776  -0.006762  0.004786  0.011883  -0.000155
+-0.003252  -0.000345  -0.007000  -0.005248  -0.032965  -0.019226  0.093310  0.015168  0.036695  0.039195
+0.002221  0.000884  -0.021471  0.027773  0.081360  0.082134  -0.016448  0.007401  0.064064  0.014727
+-0.000250  -0.003789  0.004500  0.014852  0.123883  0.069969  0.050391  -0.010133  0.034609  0.116531
+-0.081438  -0.132734  -0.121688  -0.060547  -0.115609  -0.053234  0.240844  0.008266  -0.147344  -0.025813
+-0.030973  -0.018108  -0.017000  -0.084365  -0.073959  -0.123311  0.034581  0.009784  -0.317514  -0.202459
+0.009861  -0.017306  0.063944  0.228806  0.226694  0.057333  -0.632389  -0.398083  -0.032667  -0.074139
+0.067204  0.028481  0.055148  0.144704  -0.117722  -0.015944  -0.265167  -0.164741  0.361519  0.218222
+-0.013508  -0.006525  -0.049347  -0.111754  -0.120322  -0.097568  0.197381  0.087068  0.021729  0.041686
+-0.022805  -0.014208  -0.048188  -0.098214  -0.011883  -0.017617  0.149987  0.057383  -0.156922  -0.078208
+-0.000310  -0.008580  0.028971  -0.080109  -0.005517  0.029184  0.009534  0.024931  -0.052086  -0.053115
+0.000418  -0.001366  -0.014228  -0.055767  -0.059996  0.048978  0.030185  0.036983  -0.000711  0.006487
+-0.007821  -0.005150  -0.009073  -0.030996  0.025394  0.021012  0.038065  0.059358  -0.004679  0.004785
+-0.022178  -0.020747  -0.033086  -0.006236  0.112184  0.088333  0.024655  -0.028759  -0.020874  -0.011971
+-0.000537  0.000945  -0.019799  0.034640  -0.010470  0.070128  -0.019110  -0.073213  0.013030  -0.005274
+0.052197  0.053227  0.054106  0.093258  -0.165136  -0.204417  -0.040000  -0.025205  0.080470  0.037159
+-0.002116  0.004306  -0.010926  0.000926  -0.016278  -0.260074  -0.021583  -0.022000  -0.015727  -0.004690
+0.003129  -0.001082  0.001314  0.008206  0.039387  0.145510  -0.006959  0.032474  -0.015474  0.006119
+-0.000679  0.009962  0.035972  -0.052443  0.108255  0.271255  -0.011736  0.030972  0.014038  0.010783
+0.000118  -0.005253  -0.008446  -0.050000  0.060849  0.071817  0.018253  0.017984  -0.014731  -0.015134
+-0.000931  -0.003356  -0.013600  0.002400  -0.090169  -0.031413  0.026006  -0.067425  -0.007369  -0.015650
+0.009578  0.014375  0.061492  0.030234  -0.151516  -0.143352  -0.033188  0.011844  -0.041852  -0.056078
+0.010290  0.012466  0.031500  0.049949  0.022648  -0.091051  -0.012261  -0.008489  0.022920  0.019398
+0.002930  0.003994  -0.011576  0.052740  0.037962  -0.148203  -0.000063  -0.083582  0.023089  0.033424
+0.026090  0.037634  0.028933  0.043896  -0.083530  -0.141007  -0.054851  -0.058037  0.018731  0.039052
+-0.008333  0.001096  -0.124939  -0.084833  0.036719  -0.020377  -0.092868  -0.083518  -0.001351  -0.000474
+-0.072463  -0.048667  -0.051972  -0.038944  0.179315  0.152667  -0.154870  -0.091018  -0.127444  -0.093093
+-0.023201  -0.038718  -0.021356  0.015034  0.191230  0.160759  0.032052  0.042908  -0.086609  -0.048845
+0.032660  0.022500  0.086021  0.168069  0.058806  0.057368  0.129528  0.095965  0.141097  0.083097
+0.028906  0.062302  0.181566  0.260613  -0.115170  -0.100415  0.103387  0.034594  0.228151  0.148509
+-0.007206  0.000882  -0.017581  -0.046426  -0.101493  -0.047897  0.062581  -0.040309  0.026324  0.011176
+-0.021840  -0.016360  -0.139930  -0.184890  0.042730  -0.043850  0.081070  -0.000750  -0.074710  -0.017290
+-0.025636  -0.009791  -0.063827  -0.096209  0.052973  0.028055  0.022736  0.032509  -0.015855  -0.026173
+0.008083  0.004481  0.022526  0.062571  0.027295  0.012904  -0.046974  -0.007346  0.013615  0.047147
+-0.063062  -0.084677  -0.128521  -0.133771  0.248875  0.309917  0.079062  0.060417  -0.035750  -0.006000
+-0.035389  -0.064722  -0.112444  -0.102708  0.250903  0.348833  0.334000  0.181806  -0.081458  -0.066958
+0.196828  0.304891  0.394312  0.185578  -0.172781  -0.311922  -0.165938  -0.110766  -0.141313  -0.045609
+0.049304  0.066235  0.057745  -0.057539  -0.478784  -0.518245  -0.457784  -0.401853  0.041029  0.052176
+-0.215232  -0.372821  -0.503357  -0.402196  -0.094429  0.080214  0.064946  -0.022000  -0.024125  -0.035571
+0.031287  0.061550  0.034500  -0.011600  0.378344  0.343594  0.182544  0.233300  0.066463  0.019875
+0.078412  0.126684  0.140368  0.083833  0.148386  0.075070  0.071588  0.153947  -0.020860  -0.017070
+-0.012571  -0.010048  -0.069936  -0.006063  0.014492  -0.032087  -0.059865  -0.132778  -0.052754  -0.052254
+0.011247  0.013521  0.003521  0.028699  0.023842  -0.073527  0.004178  0.092274  -0.029678  -0.021856
+0.007302  0.014167  0.088468  0.020881  0.023278  0.014484  0.028524  0.111770  0.017849  0.031413
+-0.010462  -0.016330  0.014849  0.000877  0.079708  0.074057  0.066698  -0.087868  0.022236  0.007472
+0.005718  0.001076  0.004672  0.008794  0.064248  0.030328  0.029727  0.011664  0.013803  0.021239
+-0.010291  -0.000664  -0.045530  0.047284  0.030799  0.005560  0.042515  0.077672  0.048612  0.026590
+-0.002549  -0.001993  -0.008345  -0.025069  -0.004023  -0.012214  0.020914  0.001046  0.013234  0.043602
+-0.012025  -0.006348  -0.004696  -0.091377  0.019564  -0.007250  0.027686  -0.012740  0.000010  0.013956
+-0.004826  -0.003963  -0.014659  -0.004307  0.008578  0.024811  -0.002893  -0.029663  -0.000885  -0.001778
+0.004443  0.005004  0.006916  0.038592  -0.013126  0.006218  -0.061294  -0.063542  -0.013172  -0.013206
+0.005406  0.003194  0.002928  0.025270  -0.016712  -0.005115  -0.039640  -0.002165  -0.038496  -0.021619
+0.003625  0.001327  0.010344  0.020050  -0.000505  0.004615  0.015089  0.040858  -0.005901  -0.007690
+-0.001634  -0.000171  -0.000049  -0.010739  0.021666  0.012590  0.009888  0.009773  0.029907  0.028388
+-0.000422  -0.000967  0.000594  -0.016157  0.003204  0.006825  -0.013016  -0.005873  -0.028749  -0.010878
+-0.000617  0.000162  -0.008543  0.002525  -0.017168  -0.008345  -0.019513  -0.030891  -0.034013  -0.044150
+-0.000729  -0.000051  -0.007470  -0.000436  -0.005617  -0.015837  0.001477  -0.003394  -0.012528  -0.013152
+0.000965  -0.000105  0.006930  -0.010845  0.000073  -0.028816  -0.005041  -0.003307  0.005307  0.013374
+0.001742  0.001509  0.001773  0.027170  0.000170  -0.038142  0.015288  0.016573  0.018052  0.010894
+0.003766  0.005500  0.008172  0.022156  0.013258  0.054641  0.025641  0.050242  0.116070  -0.069453
+0.001413  -0.004971  0.015616  0.008233  0.005977  0.094279  0.079192  0.011983  0.094453  0.092570
+0.088679  0.110083  0.077655  -0.037679  -0.029762  -0.119024  -0.133440  -0.004714  -0.083762  -0.028417
+0.015284  0.014784  -0.039060  -0.035043  -0.043172  -0.221310  -0.091103  -0.049414  -0.257957  -0.108966
+-0.125500  -0.141045  -0.110545  0.047758  0.067258  -0.086015  -0.076197  -0.045561  -0.124576  -0.110030
+-0.202641  -0.210422  -0.122672  -0.091016  -0.107922  -0.096672  -0.251766  -0.055625  0.013422  -0.017750
+0.034361  0.005583  0.011153  -0.199556  -0.239333  0.191097  0.059236  0.111458  0.252347  0.063792
+0.087687  0.088979  0.053458  -0.098812  -0.154812  0.228188  0.348062  0.145396  0.277583  0.182979
+0.045933  0.049167  0.007767  0.136717  0.118083  -0.294317  0.055150  -0.065883  0.103700  0.124733
+-0.046137  -0.041975  0.011087  0.095025  0.077200  -0.097212  -0.192937  -0.093737  -0.196788  -0.178563
+0.031244  0.009633  0.042856  0.106978  0.120600  0.173856  -0.140756  -0.133022  -0.293156  -0.227689
+-0.060940  -0.059520  -0.037930  -0.019450  0.054650  0.090280  0.081460  0.069270  -0.048150  -0.108680
+0.023337  0.038477  -0.022384  -0.108930  -0.156349  -0.175465  0.237535  0.129151  0.195698  0.203360
+-0.041489  -0.027362  0.084543  0.021723  0.089798  0.090213  0.032862  0.058319  0.166862  0.162117
+-0.033176  -0.027882  0.078941  -0.084382  -0.081794  0.225485  -0.154750  -0.008044  0.080103  0.043088
+0.039200  0.031838  0.026546  0.123977  -0.115923  -0.186231  -0.195354  -0.111400  -0.092485  -0.091885
+0.105263  0.128645  0.092289  -0.024132  -0.193303  -0.287118  -0.122645  -0.101132  -0.319566  -0.245329
+0.021955  -0.002205  -0.036000  -0.044432  0.066386  -0.104455  0.027341  0.047614  0.033909  -0.040545
+0.016083  0.049202  0.012119  0.055429  0.046810  -0.080143  0.004726  0.021857  0.320440  0.337369
+-0.015130  -0.019050  -0.008980  -0.014840  0.071910  0.002050  0.023410  -0.053970  0.123670  0.238070
+-0.012875  -0.002104  0.068312  0.157250  0.052896  0.140771  0.011271  0.007021  -0.286354  -0.268750
+-0.009167  0.002833  0.127267  0.245767  0.038667  0.057167  0.038167  0.036733  -0.090267  -0.283567
+-0.111673  -0.135865  -0.179144  -0.031587  -0.000356  -0.077615  0.089760  0.019260  0.026135  0.020587
+-0.095335  -0.245500  -0.413513  -0.452595  -0.267405  -0.350696  -0.306392  -0.165956  -0.365291  -0.259848
+0.017043  0.074424  -0.018924  -0.361609  -0.203250  -0.240739  -0.145098  -0.086500  -0.210696  -0.137598
+0.124238  0.207238  0.284440  0.252714  0.202845  0.164381  0.010536  0.089786  0.383036  0.251000
diff --git a/codec2/branches/0.7/src/codebook/lspdt1-10.txt b/codec2/branches/0.7/src/codebook/lspdt1-10.txt
new file mode 100644 (file)
index 0000000..2f08a7e
--- /dev/null
@@ -0,0 +1,513 @@
+10 512
+-8.250528  28.414351  28.947056  -22.260431  -20.641552  -23.655972  33.499699  29.162037  -26.777473  20.152264
+-13.087674  -29.244776  28.531864  1.223712  -17.642572  -29.978474  10.884624  -23.874582  29.987656  30.394098
+-29.912476  16.450739  -17.856684  21.637835  -26.373550  28.072887  -28.736387  -30.523342  -26.430317  5.712189
+26.232023  17.242741  24.208025  29.041113  23.456097  26.209288  -20.043627  4.131552  30.379368  -30.294384
+29.174519  26.290936  -26.386543  26.420618  30.329287  -27.889307  1.440385  -29.503519  -25.965733  13.266431
+26.815336  21.980131  -23.962013  26.248177  22.603453  -26.797499  24.757118  24.917711  -21.201101  -31.104151
+26.990334  30.932030  29.902292  -26.111679  10.720449  27.045002  -30.309986  -25.548256  -12.764328  15.942853
+-27.131104  7.627721  -23.845989  -24.196527  31.534019  21.284435  2.196042  26.895460  -29.873121  31.457081
+23.783720  31.103455  -16.321165  28.371029  27.756580  -22.705223  28.902239  12.486597  -24.326632  17.364750
+26.624371  29.318468  12.003039  22.658562  28.986195  18.075884  -27.618345  27.107302  -24.388067  -22.760424
+13.515237  -26.350586  25.129314  -30.786650  32.847569  -30.016973  -24.524342  -22.618462  25.237829  -11.466196
+-7.106867  17.136097  3.030111  -16.934315  -29.622986  26.248684  24.710110  -9.607081  34.604813  -28.588524
+15.662686  -27.542521  28.252190  -29.866125  -33.910301  27.976837  6.867967  -28.312788  -10.601373  -21.302893
+-10.193929  14.391588  24.278387  -28.975214  28.665323  30.877426  25.230631  22.649166  34.657333  12.617115
+27.801043  -6.528720  29.821329  -26.306427  31.756905  19.847202  -28.467939  -21.040308  26.433147  22.401430
+30.631275  24.535563  31.284803  9.835046  -9.955822  -21.007423  -28.907034  -6.312805  31.747091  -20.082104
+-23.180269  27.280735  -1.648219  18.616158  -28.962486  16.385414  27.848301  30.031059  -2.877421  30.454214
+28.448109  19.146063  30.305185  -21.223429  -28.729210  4.121464  -32.124985  16.542374  26.426540  25.656050
+-17.137257  29.191708  30.093775  15.418388  -26.740789  4.192141  30.161688  -20.539837  -27.132601  30.135859
+-25.917549  -22.641289  24.594221  13.821900  -22.764513  34.653595  25.676662  -2.283436  -28.713104  21.475290
+-34.803772  16.627371  24.532631  0.507513  -0.351332  -29.709391  -11.731549  26.970554  30.765701  -17.942686
+-21.305920  16.795202  -8.171767  4.816957  -32.731911  29.083702  -15.778113  27.838266  -35.286331  -2.821167
+25.230614  8.306693  30.379696  9.017179  -27.834126  24.510019  29.685558  -29.855885  -24.964121  22.693756
+-24.019381  -24.911600  29.932642  26.527115  24.229420  -25.979359  -24.631037  -26.388783  26.211708  9.389849
+-18.861231  -33.228931  29.733133  30.216154  29.167511  15.435679  25.305086  19.504105  -25.545568  17.099970
+-28.352892  21.202972  -28.220776  -25.223660  -27.102163  -27.997780  -15.985667  -31.684175  8.520580  32.364357
+27.376833  -20.802015  20.907457  30.482269  30.754896  -28.857952  12.509435  13.060081  -28.310965  18.305183
+25.157576  25.038042  -21.250418  28.748077  30.768257  26.917866  7.294786  -21.357422  -20.052004  29.755259
+-24.358604  29.996195  10.147661  15.117146  -25.059454  26.876207  29.655886  1.598995  -31.368891  -24.860382
+-23.087124  -30.624411  26.872061  -25.430162  -27.082129  20.720413  -28.692017  30.691967  -21.279165  -2.551623
+-24.353456  -31.981487  21.236629  -24.626516  28.659883  -25.651659  17.860260  22.199923  -20.723352  31.429373
+-25.257303  31.413050  2.180641  -21.803225  31.604710  26.447760  -3.937415  17.640810  6.967419  29.346401
+-26.361465  -29.989614  6.612124  23.398020  28.787786  26.224808  -32.942394  23.286501  -19.532110  24.959354
+-27.878630  29.734219  19.966755  30.198826  19.773518  -17.789425  -27.085190  31.225122  -28.529303  1.141312
+-30.901060  0.391270  -2.896986  30.007690  27.838476  26.702936  11.228483  25.069935  35.403259  -18.549868
+24.425106  30.878494  -14.288082  -28.314743  30.358965  16.484238  18.017254  -16.166327  -30.419704  -28.554745
+2.113087  19.104361  24.900944  -27.797613  2.455245  -30.316483  -31.873756  -29.685768  25.493534  -25.001156
+12.640694  27.439734  31.413740  28.351887  28.250576  -31.200777  -1.919832  -25.808199  -17.301651  27.257868
+24.302240  -31.663763  -8.108189  31.926470  26.079449  -17.886381  -5.920022  -31.881042  29.882542  9.564315
+26.885803  28.647747  -30.219711  25.136871  28.128950  21.675436  -28.413626  8.504551  15.025225  -19.844286
+-25.595650  -27.307159  25.095547  -7.531783  17.902473  -24.060442  -29.581953  21.509615  -19.275269  -29.422474
+-32.989773  -24.240007  26.426277  26.318930  -30.240437  -30.340971  9.496776  -0.216958  -30.049471  26.236687
+25.384636  -6.275255  -18.597488  -32.691147  29.291729  -27.610168  -21.210382  -30.417465  -17.904039  -27.208693
+-22.291912  13.350454  -28.847847  -27.335732  -24.619164  -25.186035  -31.240126  25.411316  27.413515  26.526279
+-11.963379  -31.066198  9.782462  33.931267  29.914045  33.128548  6.134001  26.757753  24.343744  12.870527
+-25.266705  28.371819  -17.242594  -0.061756  -23.222466  25.648582  -29.380426  -25.207943  30.648054  25.205875
+-28.429790  29.742310  -29.492258  24.673662  -5.577706  -30.121881  24.641495  -5.271527  -28.554474  -25.347298
+30.674225  23.665363  26.509443  -28.156471  -19.652834  -30.558514  3.050400  22.467127  -12.157305  25.608335
+28.007099  -23.921940  -28.883001  16.383432  30.184158  5.257059  -27.107363  -18.662508  30.094419  29.672953
+-4.148671  32.244709  -31.177191  -3.107982  30.788345  -19.094992  -17.701006  21.321257  -28.870909  -22.307236
+-27.787346  21.979095  -28.086067  27.094601  -22.926842  -26.618746  -25.764585  30.389841  9.124823  -20.803688
+-28.622871  14.273782  -18.527746  32.811272  28.237886  26.638952  -29.631285  -21.763582  29.762817  23.678711
+28.507240  -28.432800  24.060392  0.475232  33.547039  10.758526  -3.632491  -28.713354  -29.390940  -21.657669
+-8.461226  -20.445940  20.312346  1.126397  27.891205  -8.802555  29.181444  -33.473057  -24.317173  27.094810
+18.385647  -18.681868  -34.019363  -16.016193  32.892334  30.348473  -18.076117  -17.677099  29.281147  -6.462004
+-27.232441  29.584328  25.616709  -7.832103  22.537663  27.604885  -24.377760  -26.233315  23.746206  -26.995077
+23.928440  27.366444  31.684374  -26.476540  -2.046179  -28.640903  17.716154  -28.665686  20.821653  19.822582
+29.407177  -29.962450  -25.928570  -20.161171  -21.076260  -26.830011  -23.238630  -28.696051  -26.628510  11.198109
+23.762690  -3.135408  -10.013238  -25.964376  31.742970  -25.495323  23.754967  27.876976  23.058678  -27.804108
+-29.595732  -26.108103  -32.855850  -0.777961  26.280220  4.676180  -21.124659  -30.380817  9.198297  -31.738487
+-18.257301  -29.640936  -30.950096  3.669302  -26.327230  -27.560867  -28.221474  21.425386  -23.974077  -27.058352
+22.203074  27.736471  28.689638  -30.763041  18.591822  18.732649  28.202400  21.263161  -14.076660  -28.537773
+24.311007  -19.661934  -30.559019  27.831297  23.832487  23.034298  -19.796577  25.609159  -28.970860  21.383129
+-25.099157  -25.529819  5.853761  -6.068099  -7.706121  11.039868  -8.481035  21.795696  -28.756374  29.722593
+-30.324696  -26.820206  -2.094729  -20.414989  -28.300838  29.801680  25.661100  22.089428  12.858266  -23.677881
+-28.310026  24.394686  26.970953  -19.291451  18.713287  31.958241  20.112799  25.449312  6.026050  -31.284294
+29.731031  -7.458796  -2.055046  -9.766047  -24.399158  25.549126  -17.113363  23.141628  -33.150452  -28.483871
+-28.091705  28.946104  26.639599  26.441015  -5.776271  -31.776129  3.699637  3.309000  -27.088848  28.434065
+24.877413  24.131851  -28.485380  -23.670988  26.915024  -18.530895  22.305233  29.780357  -21.399794  23.557825
+27.733376  -23.716413  -21.622772  30.487514  -7.450827  14.006124  -27.437721  29.446697  18.505186  32.935650
+-24.420240  -22.155836  30.738674  -30.658985  -25.938389  -18.666609  -4.351988  19.271080  27.065073  -24.776644
+29.156111  -28.483194  26.807344  -32.169819  32.677620  -18.160120  -22.820723  19.154898  -25.966934  -15.867821
+-32.402512  28.791231  -19.376459  -33.458790  -4.591619  -2.483457  -26.426649  -11.451970  -3.489601  26.589520
+17.709406  28.119827  -9.284810  33.072849  -3.393136  -13.898425  33.350590  -30.098577  -25.904646  -23.073343
+24.880932  -25.761850  -28.084831  22.513605  -31.395102  -29.289019  26.686272  -6.293370  -24.953367  -14.749125
+16.803219  22.737221  28.072466  -30.104748  -33.386768  -29.029961  -21.493002  -17.387140  -1.687227  -26.739874
+-8.849285  -8.653768  32.022827  -22.359735  29.513790  24.547321  28.248760  -29.673279  -20.694735  -23.920599
+18.995764  -32.690716  -24.981482  31.671928  -22.609871  -27.155401  1.049363  -27.188822  24.030592  30.201191
+-20.475941  26.728388  20.333851  -5.874790  -25.067295  -29.538239  -22.953407  -26.601837  -31.151222  25.098551
+-11.856617  4.262431  -28.877539  26.230621  -30.327372  27.634954  10.315826  -32.939442  -24.725647  -27.897846
+-5.141058  -0.384487  27.112600  15.110576  -11.309449  32.180965  -30.647289  -27.716377  -34.215122  -25.215185
+-28.122921  -28.624094  -8.308435  -27.449034  -31.472042  -27.381563  -21.243340  -18.023628  -22.585512  27.566639
+28.504580  22.803720  21.843224  -27.465639  25.226137  -26.931309  -29.118799  8.342940  19.081705  30.757061
+-16.422394  27.782209  -29.507763  27.667814  -25.478991  15.812572  -31.803295  -8.327382  12.915374  -26.977285
+-13.047698  -24.075064  18.757490  30.889606  13.036374  31.280357  34.008266  -2.397495  27.773239  -4.738329
+-28.075832  31.486786  9.875986  -12.495639  28.213650  20.669672  -20.154669  -27.666166  -29.830408  28.754074
+-20.817934  25.465155  21.660789  30.018974  -33.024593  -26.851126  22.427879  -18.918964  27.513636  -13.117702
+32.712883  20.105747  11.499645  11.480800  -31.893333  -33.761261  26.434597  -16.045656  28.441851  16.275194
+25.468031  -27.301338  14.702893  -21.335854  -22.459711  -32.798584  -27.640146  22.849913  21.499794  12.194662
+27.247601  27.541500  -28.059675  21.635532  11.560982  -27.964947  9.155243  14.273994  28.268442  28.711775
+28.157682  24.629513  -25.688036  -20.681528  27.016497  27.786137  3.006814  -24.266685  26.347130  28.307236
+33.590897  26.544954  -13.754819  10.255233  -8.044541  30.658283  25.738869  -22.977711  8.164171  -24.753832
+31.092783  13.342126  -7.211920  -2.049561  30.282135  -30.253843  -23.966923  -21.516727  32.113659  6.814880
+23.287216  18.627256  -0.295165  -32.785515  1.387961  -33.989265  33.773190  -8.199713  17.003393  -17.363035
+25.101440  28.455503  -8.158275  30.860847  -29.289976  -25.225998  -23.423073  -9.182380  26.093452  -30.787434
+-24.068687  28.119608  -10.572042  23.238905  -30.614655  -23.620752  -22.369682  -24.210314  -24.525866  -28.179277
+-29.210775  9.336824  -27.031591  -29.950668  -22.957783  -28.333061  -14.290992  30.638340  -9.514547  -18.259357
+29.051676  29.304520  -27.803989  20.112759  -23.854359  26.400883  -22.467255  31.361710  24.536663  11.645331
+25.958706  28.463490  -24.367929  10.579311  -25.545280  -29.809126  20.846022  -29.060047  -27.663929  23.973812
+9.121296  30.801323  26.039162  -16.843090  15.986970  -27.447987  1.624425  32.649300  31.067707  28.746941
+27.518221  -30.770910  -21.445694  -25.869053  31.146349  29.838579  -24.894156  16.136885  -18.003977  -7.402350
+-27.305534  -21.246096  -26.871511  27.852213  -11.644767  -31.164965  -30.935816  -26.874981  -30.399879  16.253309
+-6.632153  8.097020  -31.116461  -29.224577  1.844677  33.240108  -17.944588  27.793501  22.504580  -2.187771
+28.788109  24.887934  -12.195354  -26.807501  -18.840614  12.666108  29.015575  30.759928  -26.548164  26.759972
+7.593760  -23.918388  31.474106  -21.832027  23.403120  -29.994598  21.056564  25.481445  28.109774  24.279013
+22.547098  -30.332420  30.663147  22.894178  15.532843  24.273546  -29.101322  12.098467  26.230379  28.198549
+-29.239477  -21.581753  27.146959  30.019226  -6.244174  29.899210  28.713047  -26.166416  -8.515326  -29.176779
+28.122040  -21.038881  23.960810  -16.589050  28.675232  27.318020  26.743977  5.758596  22.055302  23.182400
+-18.961840  -10.698790  -28.763069  28.437471  -35.400574  24.652515  22.043573  14.510972  -23.194159  -30.208973
+-31.020939  22.423620  -30.354576  27.677849  21.787552  24.156179  25.448776  6.797812  23.857073  -10.583152
+28.035105  -8.365502  23.218433  28.703245  29.323349  31.770390  4.667182  -30.053162  19.615248  22.585283
+20.907743  32.282700  20.469995  -2.092622  32.593643  -28.172235  17.193794  -13.688399  23.971102  -29.084644
+-27.821463  -23.167927  -20.422800  -32.688595  20.012943  -5.708320  25.155785  -25.669615  -31.714989  10.813772
+21.059443  22.325644  8.813952  -31.869465  -25.340435  -22.912552  25.651350  -30.096390  -12.251925  27.824656
+33.124298  24.970509  -22.883692  -24.787495  20.120363  27.808098  -24.764261  29.295557  -20.974461  18.732210
+27.873919  13.170330  26.616785  30.360901  23.720774  -28.773775  -32.039742  14.245504  10.406815  23.114937
+-29.642006  21.243027  28.496279  -29.954308  16.027828  28.209349  24.253197  -15.291070  -24.008448  21.691130
+-30.420097  21.261686  23.687590  -29.134315  26.098228  -23.065153  24.013599  11.358426  27.619350  19.153673
+-28.520651  -20.618023  23.632936  20.879873  -28.919048  -27.908325  -29.355772  -29.885509  0.446875  -13.041409
+-23.555792  -30.753073  26.267303  6.488521  22.797260  -26.167721  16.045740  -24.451176  -29.071766  -21.936409
+-2.366049  24.333763  -21.207254  26.385887  32.747791  25.520645  -30.213165  15.314766  -24.096134  30.081877
+27.522026  -25.469622  24.750177  -31.094889  -12.456142  -5.652915  -26.168478  -29.880280  -23.040524  -25.145845
+31.086567  0.399763  -27.909199  -27.119717  12.772094  25.539625  30.645590  19.174603  -7.188969  -17.428612
+-25.660950  -27.140112  -10.629828  -27.045063  -27.010494  -28.772854  -19.600899  -28.375753  -25.870188  -30.110542
+-21.292349  -21.289106  -21.501253  21.520546  15.719978  15.368153  31.115133  23.528603  -29.798271  -28.217384
+-26.340864  -30.756704  25.837341  22.221676  -17.646425  17.593237  -22.739998  -27.202002  -27.505981  23.860538
+11.569932  28.003872  -25.262947  31.434067  -22.080194  7.423393  30.620216  -12.076071  28.589949  30.061836
+-30.388857  24.292381  26.421072  30.324377  20.356447  9.037641  -28.085680  17.950548  25.793188  28.759373
+-23.263527  18.627926  -30.141863  7.740365  22.029932  28.499783  30.285429  -26.274853  -20.482277  23.133362
+32.813244  -20.900084  -24.991117  16.317175  25.896717  -30.170595  -20.606852  -4.947311  -27.353762  -17.023895
+28.343552  -27.288149  -24.964575  32.622482  15.900583  28.223110  -4.864933  -12.131302  -28.233732  -30.439581
+-24.307573  -30.622923  -27.477850  -28.684631  30.428198  -28.051462  -9.877420  19.513367  21.287836  -22.723270
+29.043144  22.876682  -27.117975  30.219616  -26.863281  -17.694811  -23.721672  -30.955458  -23.429083  -10.684244
+11.060363  -26.773920  -22.583313  27.121037  25.142149  23.520163  -35.005611  -30.745600  -23.574781  8.635379
+11.357567  30.427563  20.701384  24.337975  26.384836  26.677534  -7.507456  -30.599634  -28.048975  -28.365108
+23.339508  20.602566  -33.920498  -10.787850  -27.863245  -21.197025  24.051607  -29.691181  28.696939  -16.355665
+27.156740  16.964241  5.571268  -27.733831  -30.067137  21.884510  -21.251928  -30.481337  30.485355  24.729668
+-26.687622  23.605410  -20.949074  24.506336  22.576454  -28.776810  28.682386  8.076501  30.059227  -23.765211
+19.499861  19.529318  31.583889  25.157722  -26.286268  -34.550621  -23.867632  26.800932  -6.820005  12.327001
+-17.908678  -15.761912  23.849796  25.471844  -27.772625  -23.331366  23.346025  -20.287111  -19.387089  -21.679003
+-29.713295  -7.165277  25.469320  -32.656456  -31.675169  -20.736795  22.852297  -27.023853  28.455851  -4.415093
+-31.419279  28.685366  -25.388046  29.722818  15.015548  25.824671  0.442656  25.495337  -24.566687  -24.969934
+27.788668  23.789171  -15.574149  -23.203178  -29.012049  32.678471  25.480368  11.069133  22.169937  17.818844
+27.556049  -14.146981  27.893488  -0.205255  -29.667313  27.449438  -27.657949  -30.545671  -24.696152  24.537466
+22.982018  33.590633  21.231791  19.734377  17.219254  7.570241  20.145592  33.318871  27.775024  -16.882725
+15.009192  29.450502  4.686261  -3.324030  -34.471027  -33.349808  25.874115  5.478483  -20.379084  -5.739206
+13.428425  -26.141970  20.602623  14.879295  -27.248064  -28.260799  -31.781689  -25.459976  -25.936277  -28.731651
+-21.017727  25.616560  32.629795  29.306215  -23.032677  27.910164  -23.108871  19.208513  -30.069599  -23.484737
+-23.726578  -29.088511  16.016588  12.965228  -26.729847  -29.126991  25.498001  25.654112  -29.098560  -28.284170
+-27.480677  5.697550  -30.919975  32.190777  11.537769  -30.228153  26.874218  32.551582  16.837023  12.355412
+-25.134735  28.210272  -28.118145  -27.915285  -31.248295  -29.046194  24.636982  -18.550402  11.327372  -20.042549
+-27.592712  -26.467159  -30.820688  -12.226371  25.467739  28.521854  3.692282  15.284110  14.373300  31.233538
+7.177904  11.423222  -25.810898  -26.818068  35.479370  -25.740366  -30.163752  15.037313  -12.527069  25.534302
+-2.638413  30.585152  25.912683  -18.014620  33.231594  -16.783199  -17.315958  28.074158  -25.544659  29.678978
+26.285452  26.749672  -33.995316  26.974787  -8.064065  21.458660  32.709496  -30.895699  0.037257  2.178612
+28.732716  -23.296423  -18.691906  -31.023714  -23.567375  27.788317  -26.552231  19.305607  27.235626  19.013712
+-28.392611  -29.439262  28.464724  -19.999983  29.721647  21.496183  3.553029  -24.798029  23.571009  -25.178368
+-25.590965  19.625475  32.139542  12.308794  -33.614574  -24.932693  -12.018950  14.945961  -28.347635  -11.778281
+-23.936697  -30.939325  8.649321  -24.380640  -21.523420  24.172867  -21.442892  -28.130402  -26.865345  -18.526720
+23.959433  -15.302689  -28.791048  12.541603  28.438076  -25.868076  31.533470  -28.832186  -25.802338  -18.020861
+29.430056  -13.753139  -30.351770  -19.868355  28.745502  16.640471  -14.774107  26.327574  16.127264  31.980478
+-29.641502  -17.705847  24.447769  -24.623304  -16.330515  26.228224  29.003815  -31.477066  14.041460  -27.526264
+-15.739707  28.716131  2.340807  26.645828  13.053572  -23.754354  17.074375  -34.384674  27.854647  -31.704470
+-27.404348  -28.118250  -33.941959  -30.466818  -11.816746  25.685192  -18.100304  -30.087223  22.637438  13.770916
+30.122972  -29.118546  24.532595  7.057877  30.036701  29.099798  -7.071823  24.592756  11.401652  -26.073618
+-28.692404  -27.009842  11.905396  -28.387501  21.222261  25.882669  31.801846  -29.021738  22.581629  22.886696
+-23.964380  -30.042795  11.303555  -25.320282  27.864023  32.828209  28.997120  16.339516  -28.981457  20.930676
+18.626646  -29.582371  -27.551277  -27.697216  12.197803  18.428934  24.812458  -26.544010  28.405891  -19.468340
+-26.839275  29.005001  -26.756369  -24.117373  25.626078  -5.748903  -33.437027  31.553396  16.725538  -7.001272
+-28.237995  29.670803  6.692709  17.942415  -30.868332  29.001917  -14.060006  23.688519  26.160295  -24.409889
+-17.979515  30.931259  25.636486  -31.712921  -25.322096  30.303371  19.788139  -14.276178  -5.861047  -31.922964
+29.199034  -28.819431  -12.205784  -31.307295  -6.876378  -7.332343  25.940901  31.060841  -32.258877  -20.013409
+6.463464  -32.547859  28.319059  28.421572  -20.190582  33.658432  -17.270596  16.164312  -22.368608  -26.789709
+-27.753912  25.124001  -24.065769  31.459173  -25.951307  -0.960714  22.520782  -28.286674  -23.691193  25.823711
+-32.022495  32.072910  -24.703007  -29.224352  -27.904415  28.083996  -5.967274  27.038555  18.721811  3.493615
+-24.128891  -22.292822  -12.250476  -23.735218  -31.929567  -25.620970  28.912012  27.308689  9.154576  -27.708202
+-2.529298  -27.601696  -29.463570  -36.215473  16.249651  -17.557255  -29.444719  -11.908958  -6.184426  23.358080
+22.185682  28.216541  24.036819  19.887381  -31.464809  -26.278393  -26.571669  -31.595316  7.374464  20.975615
+-19.376390  -12.690674  28.849831  -25.717209  -15.535289  35.125530  -7.713222  23.484344  28.977058  23.431211
+33.227535  -27.833324  24.351425  25.713518  -28.399006  -17.730026  -1.729472  27.119209  -21.333033  -21.328016
+-26.771830  -28.014515  32.189442  -25.928280  20.033003  13.710388  -26.982601  -3.500313  -1.506497  32.057953
+-15.927268  -14.658901  -31.679316  -22.644035  -30.882013  25.508205  -3.187066  10.148254  12.417383  34.725166
+-22.061447  28.227926  -18.534262  -30.699667  15.779271  -29.329414  28.158079  29.011202  19.597822  -26.136396
+-12.276376  15.892327  -13.182528  33.299500  10.344028  -27.171360  -28.183661  -29.153164  2.250963  23.829035
+31.585875  -12.671778  27.297150  26.335220  -31.710556  25.913471  -8.017223  -21.332951  -17.157022  -30.292700
+29.741533  29.534622  26.601515  -25.145164  -24.681961  15.980844  9.520965  -27.243650  -19.263262  -22.375216
+25.433943  -24.467484  -28.143906  25.495886  -14.842226  27.493128  24.425079  -18.644470  22.826246  -24.302608
+-11.835747  30.136255  19.106735  30.824072  24.703981  27.172768  30.038048  29.186287  14.920562  -25.028795
+-24.752653  12.587847  -24.860634  -29.029341  -27.967066  25.020454  29.418030  27.942430  -30.215551  -5.299477
+30.899067  10.949029  30.686211  1.537882  -29.977716  -26.814390  27.016579  -25.541710  -11.079510  -30.835358
+-23.126663  25.899948  -17.426580  -17.390171  -30.503218  26.251877  27.270002  -22.473648  18.283787  30.123409
+26.261578  28.262335  -11.489004  25.436064  -26.994009  -12.419476  -31.502707  29.040253  -27.648924  -25.962418
+-23.910925  -25.429150  32.867672  -24.749254  -7.415473  -30.704737  -21.911823  -22.141689  -15.827194  16.446846
+32.822388  -26.108095  23.612616  -26.657368  8.439564  24.641146  -6.179613  33.014786  10.439384  29.579102
+28.725666  -33.654274  22.856649  22.741859  25.022173  -5.115507  19.444532  -21.232260  26.221478  -29.678156
+11.633716  -25.277298  28.206738  19.001387  -18.242786  -17.984953  26.639774  29.904631  -25.861620  30.963205
+26.100559  -31.884655  -24.972794  20.931379  4.227546  -17.869324  30.058016  32.515915  -28.206936  12.626034
+-32.133125  -16.602737  20.367025  -31.185806  -19.106474  22.728912  -8.192968  -31.767912  11.123755  24.181980
+-28.589380  29.538591  22.653214  -0.282040  -20.724344  -27.879545  21.328064  -28.110569  25.765228  29.024187
+30.860882  -36.364681  32.781525  3.949558  11.079511  5.537791  -25.393511  -25.208115  22.980810  3.930116
+-27.158617  -31.621920  -30.083405  5.409239  28.529272  29.010754  10.388368  -1.306479  -30.552919  23.308531
+30.734177  -11.201901  26.037382  -29.200989  19.392895  28.737637  21.011969  -10.357248  21.548880  -32.679043
+-30.674662  27.818089  -29.203140  -19.854593  17.044485  20.876467  -25.747786  -28.878233  24.511505  -23.141962
+15.673603  23.288090  -27.818857  -32.513565  12.726074  -23.733049  6.036387  -27.862049  31.193783  28.119864
+-25.304333  -10.877955  -31.227898  -16.382595  -28.835913  25.393698  -28.896641  30.803068  10.476258  -26.465452
+23.626778  23.357811  -21.206614  -29.721647  -28.852413  -21.211292  23.961103  28.441339  28.036560  14.108786
+-30.235542  -16.326653  27.562990  18.357885  -28.368156  25.471575  31.773487  3.734513  26.049023  27.969463
+16.980251  9.390479  -26.069489  7.320188  -28.113647  -23.642582  -30.748701  -23.248289  30.193817  29.133545
+-15.223531  29.817465  25.503374  26.672890  -30.908064  19.442265  -24.689878  -2.461775  -11.962740  30.012175
+26.024065  -28.097883  28.531002  -26.941986  -9.108933  -23.738096  26.942194  -32.118740  -21.525244  0.961816
+-21.030514  -29.363424  -29.957251  -3.642823  25.494364  -27.320837  29.038359  20.022373  -21.875433  -12.396379
+-2.554545  -19.473997  -29.914202  -25.034857  28.580915  22.604307  34.856983  9.326077  32.951740  22.441561
+24.712944  -26.632645  -28.892635  -31.333563  -14.416006  4.310412  -0.897436  25.962732  24.652559  -30.673096
+6.788627  -21.653187  -6.069960  12.866386  -27.860754  -26.680700  30.156889  30.329958  30.810295  29.371235
+21.382395  -22.684311  23.297520  33.335854  -27.297352  -17.233984  -31.350203  13.568316  -24.140413  28.863089
+31.643314  27.707121  -29.477461  -9.803405  -3.628554  -7.854528  -23.128674  -24.773476  2.337460  -32.242786
+-28.357882  -29.080982  27.726603  -32.353439  -22.851774  17.860350  26.096420  12.912831  -27.845894  -11.446677
+-17.905165  -28.183750  19.077509  18.199484  -28.807766  -32.092926  -22.621668  26.957857  23.457119  -25.195761
+29.155462  -25.485563  -30.272305  -16.998955  15.935428  -27.434748  16.272764  32.845551  25.275352  20.979900
+32.467125  2.939564  -31.076166  27.574575  30.052773  16.918018  29.306002  23.624807  19.740393  19.112986
+-8.465060  31.190577  -19.820602  25.919401  25.398651  -25.740845  -29.263819  26.071243  16.005625  20.981049
+26.799908  31.759245  13.203218  30.501919  -30.048819  27.405413  -20.117563  -24.532503  -17.605293  -1.400979
+25.599031  -25.007303  -23.524038  -23.979019  11.082253  26.192183  -31.115137  -30.058470  2.727974  -27.772297
+-24.374161  -27.365503  19.043154  30.259495  26.966307  24.007391  -26.921694  -27.449593  -0.693423  -26.959122
+-16.835014  26.655935  -29.384642  -20.400610  16.875422  -9.288965  24.921650  28.477253  27.882397  31.178291
+-27.775560  11.304965  -30.917141  -23.896084  -27.252436  -5.768191  24.565573  25.989275  30.708174  -27.192362
+-21.059984  29.560249  11.736514  6.236456  -22.555840  -11.700287  29.706589  -32.870235  -30.064922  -32.728569
+29.824356  27.638718  -26.119389  -25.752388  -7.091943  29.872379  -25.563438  -20.491268  -15.487212  28.308151
+25.054296  -31.876778  -9.431026  20.878891  11.869048  -26.002031  -29.155945  -26.587269  21.408344  -27.389734
+13.360140  -28.607838  17.558054  29.380537  -31.186047  26.913769  -29.970146  -22.124077  15.529097  28.936937
+-26.935667  -27.751474  -25.886803  24.869987  29.632679  4.262222  26.330482  27.695890  20.406704  26.952892
+27.773643  27.070660  29.386000  -15.045194  29.023048  -14.664932  -26.053480  -28.607267  -29.265291  19.901291
+25.224318  30.863043  -7.171692  -26.044735  25.731773  7.060417  24.963589  -31.946568  -24.867212  23.922573
+-24.416780  -3.127780  26.428778  -31.601528  -28.607794  -32.702267  -30.195272  19.899616  -32.712517  -13.622476
+23.834667  -20.505260  18.961716  -27.534723  19.927999  -27.138330  31.404387  10.160913  -26.514894  28.471298
+-32.579205  -29.109819  -23.370672  0.175204  4.152793  26.609514  -30.408527  20.083223  30.345333  -30.777744
+-25.165133  26.590651  15.164800  34.035385  24.890318  27.121458  -30.423645  6.241826  -13.916649  -20.982605
+24.287477  -4.930229  -29.895758  31.450027  -18.431036  -30.184004  -14.347340  -25.172152  25.120384  -5.390819
+34.449562  -26.830839  -22.914642  26.217722  16.639507  1.244331  33.186203  -28.394007  -10.429307  18.779203
+27.026775  24.603586  -27.057831  -28.173298  -25.732758  21.497812  -24.456360  25.356434  -5.640959  -28.189854
+28.458910  26.698551  10.737266  -30.727051  -14.385382  -3.846819  20.652956  -28.468721  32.331146  -34.411369
+29.262314  -32.190617  26.086044  28.936239  -25.675840  -22.062592  -5.182319  -31.989595  9.402879  6.248139
+28.646204  -26.018677  21.673767  30.117731  -24.644100  -25.889296  30.692308  -22.026123  -28.589268  4.404716
+-22.393431  -21.427132  -31.853867  16.146013  -24.506269  27.188745  30.711731  -34.057224  27.288538  14.982982
+20.574594  -15.383286  20.906435  -28.355043  32.379101  -12.020234  28.393415  -29.822983  31.416735  17.007446
+-25.502262  -9.228008  -3.837359  12.872238  -26.151907  -25.499598  -32.324112  29.786247  -25.967714  28.234489
+-23.084305  -13.282383  19.637316  -28.958052  32.728695  24.140638  -25.476992  -10.069501  -29.599485  -28.257629
+-25.001698  -25.255516  -32.657532  24.237925  -20.142313  -31.082474  16.980850  -25.324553  -24.850039  -22.198929
+-30.783539  21.704845  22.750927  -26.120293  28.412706  -29.031534  25.596516  -13.815741  -21.302029  28.485952
+-11.812229  -23.016167  23.444263  31.846100  -23.763472  -24.157795  30.420347  27.766439  22.159620  -26.217464
+-30.269299  23.074360  -17.584850  -24.882748  -28.447580  -9.149231  -28.034163  -20.211983  28.957960  -28.144926
+-28.273239  31.753962  -31.849707  -24.950897  29.024555  -30.823227  24.291180  -20.824249  -22.976759  9.613055
+-19.141724  -18.903481  33.267681  -29.076090  22.744261  -21.670807  20.176722  21.742088  -27.476349  -20.208090
+-21.814678  26.229355  -22.394960  -23.985876  -22.850430  -11.157884  25.720003  -11.150975  -29.975357  20.922470
+-24.818188  -27.971861  -24.304016  33.115723  -7.687469  18.482296  25.003521  -28.380758  -27.353703  10.670769
+34.711102  18.940998  -8.904346  -29.782681  17.538698  28.884752  -30.254866  -7.674024  26.520487  -22.265539
+20.902689  8.025566  18.674671  -14.390745  34.189243  25.087580  -26.964514  -30.336157  29.974638  -32.069538
+27.297630  32.444088  23.818474  13.905664  13.886219  33.197960  19.602440  -5.438952  -29.282585  4.220894
+-31.047628  -5.967454  -15.532126  31.632353  18.968309  -20.643166  25.451929  -29.252943  25.353363  31.446577
+-29.480902  26.957392  2.875650  -30.756542  28.904150  -30.677294  -7.803256  -3.807869  24.872663  -29.877567
+-22.565489  30.024027  22.170925  27.085526  -26.759377  -20.698097  24.962259  30.733471  -6.988181  -26.746565
+-26.527519  -32.189098  12.014070  6.617297  18.855453  -31.615606  22.567261  5.846895  30.375355  -26.095812
+-27.512320  28.680782  14.500208  21.156994  32.140953  -3.669570  5.279128  -24.266092  29.650183  23.805666
+8.043905  -12.737823  4.512187  15.255741  33.115318  28.959831  31.735544  9.968329  -23.206686  30.895378
+26.174623  26.838005  -26.408766  2.086205  -19.624910  30.056616  -26.491264  -15.869252  -27.731758  -28.084812
+33.798901  9.602103  5.424158  28.581442  -28.910339  31.374783  -21.994387  4.254702  31.387598  -16.908768
+-22.995621  -29.013706  -3.134014  34.395058  18.291862  -14.794615  -25.759489  29.110916  32.434479  6.428141
+22.396238  28.856667  24.694206  29.728733  17.439247  -24.605965  2.835178  32.425121  -29.118446  32.634369
+21.048349  28.621387  29.156994  26.189903  -29.382019  23.461313  28.266794  -0.439052  23.495407  -24.725916
+-27.643070  -24.467356  -24.125101  12.355736  -31.026474  -11.452502  29.360916  26.205215  -27.469412  28.773991
+17.492985  2.943702  27.385895  17.119638  35.015461  -8.329785  -29.867542  -22.840242  6.396861  -29.727692
+14.143679  -29.546240  25.005054  -32.755421  4.263321  12.211868  -25.658663  22.994242  29.143982  -22.893181
+24.109888  -27.497812  -27.954905  32.443611  -3.344005  -31.847933  -11.106377  29.914062  -13.352994  27.370584
+29.769308  -27.634550  10.123406  -0.666036  27.717897  -22.755526  -21.831999  29.521137  -19.971655  31.803200
+-27.502804  34.955513  22.627068  -26.192478  -30.501144  25.425434  -17.472500  33.547077  -21.327307  9.094096
+-30.031528  24.495207  29.067213  27.323195  27.462391  -4.872978  30.398762  -25.902514  -27.583355  10.717492
+-2.095082  11.889703  -10.809792  30.213783  1.781955  -29.186869  -11.892235  25.833742  -32.324806  -32.079998
+-29.235382  30.834251  30.403370  -11.315332  -24.759306  31.109966  31.431036  28.520866  11.053640  3.461449
+-30.244762  -27.393930  28.511477  29.816730  -27.471121  -7.608500  26.504629  -28.544924  9.468965  17.659010
+31.055311  25.810459  -26.201794  -27.467518  -26.213955  -27.562859  -29.694899  21.291172  6.601510  21.115910
+-24.484440  14.377709  27.141979  -24.846848  29.676838  19.359415  -26.188015  -28.933739  27.068943  28.852873
+-1.777584  28.690315  -30.685251  -25.811670  -26.726999  22.073185  30.474836  -26.577009  -1.388977  -24.970066
+-23.217674  -9.603335  25.585693  32.880417  17.636166  -26.905874  29.450474  17.441338  -29.926682  -2.519353
+-18.993116  -17.049662  -29.117178  26.266535  27.745338  -24.618834  -32.491642  21.682329  -15.290477  25.305677
+21.594990  18.116844  -22.970961  26.803097  -28.312132  -25.754536  28.784237  23.493803  -23.988674  24.755627
+26.273111  20.164145  -30.960867  10.705051  -32.859798  -8.560682  27.298222  26.350872  -22.881374  -29.441200
+-22.493010  23.351444  28.667454  -25.100960  -27.100527  26.709175  -27.322639  -25.643158  -23.143845  20.998848
+33.212540  -22.807255  -8.209283  -23.595226  -29.341192  24.369164  27.328712  -26.528467  13.444833  -27.852577
+0.897182  -18.460764  13.430999  25.243839  -22.347672  26.362997  1.497149  -28.266176  35.687267  17.992989
+10.311977  32.574795  -0.212680  -30.948067  -28.844055  -13.601215  1.557753  25.845419  -26.258997  -30.565941
+-31.612873  -9.108874  -26.461384  -20.205444  -30.433044  25.255568  26.380428  -26.816496  -26.852779  9.175333
+-23.040833  -31.964855  -25.077463  -28.732893  -24.889439  26.744467  -26.337885  25.007233  -24.697218  22.533663
+30.737677  14.543345  -26.202257  -15.591269  -22.377333  28.348845  29.444912  -24.730145  -28.503851  18.424576
+-26.413193  28.465033  23.083967  30.347820  12.164445  -25.689840  -32.023987  -12.430599  19.589396  -26.604269
+24.747435  -25.146259  -8.288306  -26.737041  -12.364920  -30.125212  -30.506683  13.233122  -27.001324  -25.677553
+-23.593397  2.490179  30.440943  -25.393753  16.548756  -32.422806  -30.887869  30.479034  -17.930670  22.131184
+-22.438736  8.358352  16.260340  -32.475449  -32.186527  7.956705  22.723034  18.579256  28.241919  32.100170
+19.554148  -27.834885  -22.022249  21.876564  23.675402  27.664116  -25.391336  26.641520  21.600826  -25.006041
+-25.975653  20.819170  25.681568  -14.112076  30.400187  -26.938988  -31.833731  -24.777851  -23.332275  -6.757283
+-22.558081  -30.685102  -29.712374  23.001144  14.667596  17.613012  25.100410  24.326008  24.480333  -29.273287
+-26.562567  28.114670  -24.706234  30.221634  -28.659506  -30.630051  -5.832726  5.143960  -9.164999  28.023228
+-5.923516  -11.563029  -24.251698  -33.599762  11.713305  -26.949112  -18.838186  30.039885  -29.089350  -27.182583
+-28.901306  -31.126938  17.398819  -26.592638  30.544956  3.800116  29.343433  25.095493  9.057474  -27.154503
+25.736546  -13.424304  30.470133  20.869114  18.423546  24.845211  -29.066833  23.181301  -30.541372  25.994198
+27.423670  -27.840143  13.429342  31.628370  27.305670  -15.566775  21.208973  30.164932  26.405418  22.738131
+27.583424  17.739641  -28.972815  27.014660  22.040768  28.733265  5.443688  24.076410  -30.501183  -22.660669
+29.299047  21.763460  -25.778793  -30.054329  18.825420  -28.253668  -18.830385  25.444197  27.765272  -11.697937
+-16.964239  -30.562384  30.909069  11.853930  25.537861  9.847809  -1.116659  28.196758  35.026066  -25.823643
+-27.128920  -31.256323  21.659021  24.397120  -25.733042  20.490381  -23.214678  29.172058  10.333962  9.034096
+14.474123  -23.810432  -24.891966  18.942736  -28.131004  -9.560011  21.164343  -31.593370  -23.664772  30.311522
+-30.458584  -13.034205  0.747105  6.969122  32.300362  -27.568441  19.547087  26.822100  -33.261684  -30.514378
+-32.572960  -16.802517  -21.750109  -26.299847  10.077271  -26.800924  27.696951  -11.072599  26.649021  33.732758
+25.869362  -14.049567  -31.227896  -16.428043  25.684437  26.808477  22.170685  -32.006725  -27.951071  -26.857271
+25.632647  31.340467  -10.101071  -27.868580  28.392941  -30.367975  -24.844458  18.878220  -28.495523  -23.132236
+1.986802  -28.611712  -26.413385  -26.797050  -25.955442  -30.128197  -26.639410  -14.373254  28.916788  19.168682
+-19.165081  11.260596  31.176182  9.450422  31.285467  -20.239744  21.123598  21.685785  29.227621  -31.673935
+0.587843  22.940138  28.678320  25.398922  -18.522312  12.439598  -29.282730  33.175476  21.039089  -26.045649
+-25.681229  -5.916020  24.594976  -27.655167  -19.081779  17.430195  -26.535902  21.330406  -29.509890  -34.709892
+-24.813129  19.791067  26.324507  -33.118763  -18.493454  -25.687447  26.396252  -1.613418  -28.247681  -27.283630
+-25.763205  -18.964548  -24.838812  -18.957668  30.600906  -24.606560  10.967690  -30.789375  28.121155  5.437460
+-28.941336  30.519905  -28.119589  -23.024672  28.105591  29.297325  -1.960685  17.279530  -29.578667  -17.794458
+-14.513925  24.624935  -23.667196  27.040792  3.144825  28.194065  17.492538  28.565624  30.727345  29.069174
+-23.433559  -5.516361  30.931314  25.211166  7.632286  28.322212  0.928505  33.286747  -0.994150  33.493996
+23.183256  27.546146  3.295649  20.680958  32.848858  14.191882  -20.808727  18.313766  28.677576  34.206108
+7.304214  -26.545599  21.813995  -29.120394  -32.868858  -30.856737  24.989367  -3.438031  -10.098872  30.483994
+-1.543379  -9.049648  29.524065  29.556068  30.132706  31.693953  8.643419  16.408585  -29.715712  -27.209595
+-1.318370  -28.632818  -5.848276  -19.451675  27.203268  29.918613  -27.557243  -29.160196  11.098360  30.477375
+30.259293  31.887877  28.997480  -26.240725  29.429012  -0.215187  31.697910  18.112293  7.368057  26.644302
+-28.542744  32.168686  28.398161  -25.519390  21.313173  24.417574  -23.385223  23.575758  -24.957533  -11.581442
+-29.584984  -22.043736  -19.973017  -13.154330  27.776617  28.880579  24.541265  -26.868013  -23.242449  -26.350306
+27.122181  26.698082  -16.079922  -30.070417  -15.069088  -32.086346  -6.156638  -21.599962  -29.905394  -22.629557
+23.463209  -25.001377  -24.783054  -28.923738  -32.481968  -22.494843  22.910870  -24.435270  23.247295  18.574396
+-16.888866  29.557543  25.438974  16.747263  23.634312  30.699593  31.858620  -22.419878  20.923744  27.286860
+23.698317  -28.092585  17.806080  -27.186083  4.859796  30.562733  -21.827574  -19.261030  -30.630808  22.816006
+8.570764  -26.789154  17.791445  -28.964176  -29.611862  30.816334  25.552217  8.495584  -19.825544  30.543760
+10.111639  -19.598457  23.963257  -30.313669  26.156183  -25.989300  27.614353  -24.404526  20.948635  -30.697847
+23.499454  28.296463  28.447521  -23.573496  8.948705  -27.488176  -21.296618  33.204815  -1.533401  -32.551239
+-28.905920  -28.724876  -11.068836  23.758741  -27.164768  2.238347  25.200848  -21.659460  31.813583  -25.553432
+24.451195  23.192873  17.820963  28.785830  -26.175900  -20.575638  -19.249416  24.187832  33.765800  27.542351
+31.044796  18.402918  30.415819  22.584785  5.366678  1.192327  27.368513  27.835930  -29.189474  -26.132465
+-25.984489  -25.897291  -24.572817  -27.869888  35.358978  0.409840  -29.416412  23.666075  -25.127134  0.175234
+-11.632380  1.468935  -12.562681  -4.036163  -17.348457  3.709737  12.364988  -29.359982  13.158352  3.583840
+-31.037598  -23.666887  7.681589  -15.789920  -18.904598  -27.841438  25.454210  28.760548  18.029247  16.851074
+26.357662  -25.009775  -29.791250  14.314116  -28.555151  0.319603  -28.451876  23.641190  29.803474  -19.127604
+20.317736  11.170012  26.932655  -15.372322  20.496868  -30.759846  12.953140  30.441490  -35.144604  -22.444994
+4.470020  -14.852816  -28.201660  30.268980  33.456806  26.419891  16.373205  -28.011635  10.045803  -28.102468
+-29.568325  -19.445253  -23.598480  32.237045  -11.473091  -27.800039  -18.787716  -6.833638  25.951796  -29.994253
+2.175416  18.538134  -15.958865  -26.025406  -28.610727  -23.338968  -29.128931  28.077280  29.938484  -31.821379
+13.321897  -23.288567  25.899305  27.282066  -29.057159  7.306644  -16.628313  19.552446  28.743105  -33.372395
+25.663147  -24.316936  30.338200  0.198456  26.764936  -28.802996  -24.417147  26.743793  26.973076  -22.167675
+-24.675283  -29.163818  4.554856  29.763702  -23.107208  -4.606274  -25.717699  30.389217  -26.685402  -24.885359
+17.466875  22.449562  -30.188108  28.243744  30.856178  -26.148636  -4.465913  -22.124397  24.865055  -26.878393
+13.763696  19.437191  -4.767939  -30.196630  26.213408  27.918175  -29.278442  26.010557  -18.770628  -34.011822
+-29.065424  24.655348  -31.381573  -26.498888  23.706768  1.163733  32.557743  29.334454  -25.294851  0.571252
+2.821732  -29.741623  -25.697899  4.740164  -2.629756  -24.113411  -33.509792  -23.366123  -22.589396  32.119278
+27.928167  -28.453217  -27.783646  28.721386  30.288094  -7.694778  26.734276  20.536390  12.432297  -27.357151
+29.255533  -28.615919  -30.009079  -26.702307  -26.329327  3.907118  14.859112  -0.607094  -32.211464  21.356220
+-18.793222  -3.798059  -26.758448  28.500853  34.239231  -22.307819  -26.285475  27.232656  9.680526  -31.123280
+-22.048409  19.472820  -27.342068  -3.084518  31.052856  28.628109  -18.369673  -6.574208  26.069016  2.390783
+30.838614  -31.065832  -23.328526  -27.681437  28.729666  5.293194  22.912565  -24.776793  -3.040089  23.239820
+24.948847  -29.624977  -18.823366  22.120489  -19.881227  -27.936697  23.355516  13.080451  31.027403  -27.728983
+-27.207590  -31.597433  -12.881650  -6.010530  9.100506  -29.575729  -26.902830  23.663296  30.666758  31.928682
+-21.830980  -31.940022  -27.536440  25.065334  22.005463  27.432138  -18.701872  -23.727381  25.942179  11.190812
+-2.231342  -18.594671  0.143037  -13.649037  -17.063463  -30.886179  15.078956  -32.989906  24.989979  -31.739000
+25.452377  -27.772600  -27.105972  25.484657  -25.555532  -0.991211  -20.596451  -24.194292  -28.303204  -24.034193
+-20.308994  26.506071  -22.997358  -27.003933  27.493284  -1.058701  27.859604  -27.349453  26.765139  -28.524254
+-16.797264  -24.915733  -15.681656  -26.831530  -30.325777  31.558727  -5.553338  -24.391125  31.935699  -28.778387
+31.743446  26.157917  28.448555  -18.487127  7.345466  1.489666  -29.501638  11.606647  -27.396669  -13.608665
+-27.674065  22.803783  -23.587780  -5.956399  17.851345  -29.958305  -2.373573  32.541912  -29.145765  32.780499
+23.156601  -31.936874  -23.037279  23.210339  -16.066366  28.110289  18.845188  30.645571  -26.768814  -16.099922
+27.679998  -20.325911  25.808142  -25.733467  -28.541807  0.567349  28.784498  26.622042  28.476433  -1.516529
+26.030373  -16.593649  22.357252  26.293604  28.905434  -27.011293  26.409996  -18.414158  -21.725388  -33.704205
+-24.948288  -25.220125  -20.178833  -7.443022  9.836597  34.162106  -27.491079  27.349024  -30.223257  -23.430996
+18.110004  -27.612009  -26.904844  -24.353579  4.394511  31.755394  27.892437  27.468506  -19.308678  27.300795
+-27.026585  27.288965  -7.176413  10.046975  25.635988  23.404205  -28.872671  31.483458  29.834528  -28.559134
+30.009659  -11.481675  27.223341  19.816360  4.897099  -24.425240  -28.176208  -27.415291  -29.087711  21.933622
+29.687820  22.965918  27.730066  31.794384  9.901048  4.573306  20.007175  -29.642658  -26.747276  28.268198
+-0.865210  -19.871767  -19.929611  -7.993979  18.854616  -28.328897  -34.383411  22.391741  31.597097  -22.520195
+18.711977  -36.071030  27.292971  15.776377  -27.944176  2.161903  16.054998  3.965790  13.864322  31.318604
+32.407635  5.166471  16.989594  27.554375  27.841732  26.678566  31.432329  28.344770  25.829052  -4.596391
+-27.288744  -30.192442  -24.259874  28.172007  22.895628  -0.534298  -19.668987  -6.121844  -27.388472  -26.192146
+-29.263872  -30.790047  19.891373  -21.585848  -25.329546  -19.121740  27.868361  -25.622396  -13.165931  -27.882870
+22.623146  23.712912  31.028137  20.355440  25.867502  29.143358  -27.648264  28.304945  17.928005  15.036697
+-26.480713  -10.525772  22.626904  -30.745777  -24.995880  -13.706410  23.108267  -30.951660  -27.589741  26.716717
+31.877645  -26.776035  -30.638912  -11.357694  27.723171  -14.465068  -13.479167  29.104784  -25.188648  -26.069992
+-27.348982  15.839380  27.952333  28.053581  21.310860  29.003035  -17.415442  -17.901690  -26.812763  28.250551
+-2.292844  -14.367384  31.270039  -2.544875  -3.583298  34.580555  -30.110287  -25.307888  26.263306  -18.783525
+25.580534  19.344273  24.519999  -27.579952  -28.082302  26.304674  -7.087376  20.679804  -28.221176  25.788729
+26.403370  0.119673  30.563673  -25.678677  23.550240  26.026884  25.694942  -15.687905  -26.583086  28.904022
+-26.024733  -9.991076  -26.260162  -32.388321  25.972918  26.600454  24.502594  25.001644  27.591122  -23.150839
+-20.381500  29.739450  29.266190  -19.060871  31.730856  -27.851404  -29.299297  22.886538  20.299524  -5.612797
+-30.245682  9.170924  27.835001  28.510269  -26.989723  -29.905684  -21.079306  -4.574450  27.621330  26.835732
+-11.741691  -21.096174  -31.672081  -26.892820  -20.835611  26.145498  -19.070086  -8.344960  -25.313398  -28.809412
+27.975668  29.217541  -21.093300  -24.969948  24.385786  27.821079  12.356703  29.299297  31.538540  -18.826864
+-0.011608  -21.470102  -21.539015  26.133718  -24.347315  14.058448  -29.397707  -32.114067  27.519901  -28.864784
+7.751823  25.806000  32.901085  -18.736755  -30.452698  31.745525  -19.301916  23.036520  -1.871948  -13.531702
+-25.096243  -22.490328  -29.185835  29.310244  -22.384819  25.474823  -23.745300  6.527666  -25.035147  26.242929
+31.915901  -17.114971  33.850632  -23.008661  -20.975691  31.195967  -20.159695  25.620447  -9.417980  -21.470547
+-20.885433  -26.098394  -34.525181  -27.231531  -22.594303  -19.190878  -17.335438  -22.200954  23.105984  -27.633783
+-25.089838  27.039967  -29.545822  -26.537960  16.975136  23.591961  27.614595  -26.206774  26.214140  24.426662
+24.727230  9.407478  -19.955605  -30.136086  32.399204  -29.649614  31.909718  -7.453758  -6.022649  21.740572
+12.958760  24.706667  -23.926395  -30.368166  29.662342  14.598271  -25.140099  -27.388971  -21.885681  -8.899488
+-14.913486  5.755036  29.146093  30.288597  26.944231  -23.483667  28.112745  23.703074  26.498447  25.958067
+11.558963  31.078140  20.723763  -30.646187  9.957328  27.129442  -30.294744  21.838882  30.638649  -5.043203
+-29.248917  17.624363  31.224365  30.660954  10.486515  -23.798962  1.554539  -28.965864  -12.215902  -22.325430
+7.900054  -26.661585  27.479298  31.024197  26.996269  -25.794918  -28.789604  20.071230  -26.860794  -21.076006
+-27.726221  -28.307617  34.196552  19.789654  31.658072  9.052336  20.067137  -24.075565  22.948666  33.775368
+-18.119324  -15.809902  27.389950  14.877948  -23.965155  22.419680  31.682259  30.595205  -31.514141  -24.590290
+-18.131638  -31.149517  22.957989  27.805208  29.596313  -18.579456  26.984100  31.832233  -0.351689  -22.661404
+-19.898781  14.091078  -16.836910  -23.718222  26.494846  7.629979  9.194495  19.305960  -2.738285  -35.370060
+-25.090359  25.073004  -29.615166  22.081806  24.856117  13.964811  -28.084621  -24.082621  -25.604486  -24.462408
+30.246601  -5.769229  -5.193548  29.170889  11.829287  -25.503380  -30.386749  30.259050  19.686636  -26.349174
+28.390156  -24.656689  -12.252963  25.772734  -30.656946  29.966541  -27.206295  26.297985  -12.604877  -3.371529
+26.495270  25.092012  -26.570024  29.583403  -12.035311  22.394245  -19.207348  -28.881124  19.397552  26.818882
+-13.935023  -29.313412  -33.118549  -29.540964  9.710785  -26.418322  -15.709097  30.511360  -27.285845  30.564705
+-1.097461  -29.774305  -24.169292  -29.655241  27.834856  19.809050  23.895390  26.617266  -22.941202  -32.466064
+27.327742  -26.427551  27.262140  -21.368608  23.675949  28.715414  28.391165  27.343777  -29.445198  -16.981379
+12.984652  -25.212948  -25.955906  -33.128109  3.915369  32.641487  16.643110  -28.839380  -29.649031  20.084105
+29.169926  -29.581917  -9.146402  26.112736  21.341251  22.479158  2.133000  -27.415180  -27.825184  29.289385
+15.334047  30.304628  -10.422917  -10.776401  -28.027750  22.465811  -27.439026  -30.379057  30.532068  -22.980307
+6.460567  24.801245  27.595768  -18.807585  26.529850  -28.904119  27.325108  -26.231388  -27.992422  -19.203676
+4.858919  9.724921  26.735258  -29.821846  23.857037  28.866035  -28.931206  30.675814  -18.045187  26.510839
+-23.896399  -29.940565  -29.135975  25.415710  -31.608906  26.104200  9.917217  18.043379  26.905247  17.197084
+-32.659801  24.501835  11.548573  24.957283  17.654007  23.903896  30.063805  -25.241699  15.368115  -28.222347
+-21.819532  28.157255  26.924294  -2.496731  -32.710079  28.959297  17.546373  -31.157272  4.777966  13.330534
+-33.874298  -22.775492  -23.086416  23.421789  -26.284649  12.585775  -29.640625  -25.766966  17.247511  16.120251
+-30.796759  -24.995079  -19.737066  13.902723  19.905830  -31.017385  15.919159  -27.547905  -23.628786  28.600891
+28.395857  -14.105124  23.998751  30.859987  -21.012695  28.477846  20.331127  29.432749  22.459372  23.770639
+9.352928  -31.270706  -29.708103  18.127703  29.772743  -31.743284  9.090717  -6.822830  3.621120  25.464043
+-28.046972  -19.711567  -28.521206  16.062174  -18.660967  -32.186073  29.525179  -18.658434  25.409454  3.064334
+29.735567  27.620518  24.151989  29.720812  -32.017345  8.971922  13.413472  28.063982  -21.506521  13.922566
+-29.474632  -19.652834  32.006847  24.401064  24.865980  25.338604  -30.355970  22.534678  2.968681  -22.344526
+-30.064535  28.272619  -11.764478  -28.267519  -9.421213  24.136015  -6.741315  -32.448353  -29.630991  -25.437532
+-26.516050  26.305784  -25.274731  -23.731672  -6.135195  -21.882580  -30.837490  -15.397966  -29.641878  -26.116444
+-17.967083  -36.490044  -21.267710  -29.521482  -20.714117  10.630355  2.775754  32.427319  29.701410  22.186726
+19.387829  -31.321960  6.491024  -3.254502  -9.085204  22.054094  31.965021  -22.539881  -29.751919  -27.778631
+27.144449  28.251413  -27.894733  18.980383  -16.955488  -24.369068  19.126995  24.730665  28.388189  -30.265663
+-22.823879  -16.743576  -0.855249  -20.405294  27.509684  21.952494  -32.309036  30.639891  30.141865  26.804674
+-24.074057  1.584005  -10.435838  -21.381445  27.189999  -23.158571  -31.572952  -11.807989  31.084354  29.657049
+-22.285618  14.744546  30.259914  26.419849  -29.737955  25.760761  -21.247749  26.240458  29.567011  21.174404
+8.155906  24.326309  30.161058  10.056418  -23.279669  -28.574661  32.762390  30.282391  29.276430  3.936939
+-29.147345  31.067495  -32.088154  16.249660  26.796309  -26.572680  -12.852500  -13.132098  23.243259  20.810740
+-26.896341  20.438314  26.042990  19.506247  20.804615  27.008863  32.395691  30.100246  -26.771997  21.191238
+7.246809  27.760994  29.059271  27.027941  3.511128  12.881917  -25.996683  -31.800346  29.468363  20.971094
+13.394855  -22.939171  -32.371952  -11.730799  -26.592562  31.801849  -23.234404  -28.626965  -23.670897  29.706806
+14.622396  29.198448  -11.544444  -7.621999  -4.405611  32.631290  28.775391  28.799553  -29.890314  -29.841303
+21.813150  21.489521  -10.591779  -27.987438  -29.199821  -7.887535  -26.221470  -27.671728  -29.797443  20.302853
+30.639811  13.334771  -8.900882  28.202700  12.857843  -6.109283  30.157297  -15.369250  31.276281  -31.603954
+7.694522  -20.468029  -0.725897  -17.788485  -34.178978  23.927425  -33.732220  4.955217  20.375965  -24.123995
+-16.236792  28.180031  -27.844164  -24.859165  -23.890783  -28.153116  -21.531990  22.802910  -27.761011  23.846361
+28.526554  -27.008692  -30.810272  16.839460  -24.733376  28.403906  -15.245345  -22.803564  23.127598  24.632538
+25.869368  3.164432  26.618368  29.791756  -30.799095  13.229739  26.083759  -33.614803  26.977602  15.521008
+14.767395  -23.872744  18.893583  -25.599060  29.511194  -26.763277  -14.523918  -18.442045  -29.616571  27.419004
+23.568420  -27.056763  24.325432  -23.938623  -28.297735  -6.575099  -26.447481  24.425529  -29.128120  23.467936
+27.782188  30.725523  -1.994576  20.232574  23.253380  31.770685  25.011625  29.346586  -18.634232  24.028671
+-2.991406  30.011583  -28.977139  19.140427  31.104210  25.743391  27.864761  -26.303442  5.711771  -24.898342
+23.080534  32.841953  27.434668  -26.967560  24.944504  23.324984  21.113098  -24.822979  26.371103  3.247402
+10.371755  -28.783300  30.557535  9.852886  -21.892038  29.397787  30.194834  23.821756  23.221987  -29.185167
+27.725525  20.331497  29.906160  29.985994  4.673646  -33.141441  17.755194  19.337343  11.178561  -30.378700
+-29.022953  32.298927  30.623846  -27.330795  -26.317472  -13.545459  -31.038189  14.862134  6.394091  -23.130997
+-27.122976  24.278252  -3.923284  -4.505970  7.424839  -33.698040  28.509602  29.525066  -14.325845  -3.606597
+-23.049450  -26.757929  28.846226  -15.622251  -26.292234  12.927630  -32.268642  -23.362898  33.380123  16.713203
+-26.834475  -25.778423  -25.374941  -33.272823  -8.950101  -26.951784  30.359373  23.437349  -23.741333  17.970463
+23.584236  29.477566  30.482859  24.227072  -0.161754  -28.249121  -25.205200  -22.896660  -26.021072  -27.754309
+24.359877  -15.766882  -22.589453  -28.795191  -22.054977  -25.591492  28.914436  -16.483168  -29.730721  -29.069077
+28.374998  -10.337638  -24.898254  -8.696457  -29.906717  -30.577459  -11.940366  31.599871  -23.696524  16.888037
+28.412569  -11.547874  -23.385649  5.188973  -26.594147  28.829832  30.491238  31.156525  24.449814  -22.396378
+-24.123362  10.227979  -33.093067  -26.940413  19.241301  26.934536  -30.959558  -29.113039  -25.290173  24.200045
+-25.407791  -28.724577  3.698982  -1.167456  32.141792  -3.179670  -27.368929  -31.284103  -29.620163  17.914351
+-26.139801  -23.038982  22.281845  -17.640434  21.039083  16.812750  31.378922  30.040468  20.431204  24.787907
+8.001920  29.006453  -29.817034  -16.471649  24.109184  -22.226015  -31.618090  -31.567238  28.035131  -17.240200
+31.732470  31.900095  27.778193  -4.249768  -15.619086  24.138508  24.233559  14.618389  25.075472  30.349316
+-28.288677  32.652050  -12.559782  -5.508770  -30.175503  -27.688131  6.298277  17.481476  31.894840  12.626587
+-0.359956  29.207279  28.969049  -29.720470  -11.271438  0.406908  17.933264  31.816317  31.016989  -29.226896
+-29.037714  31.317698  29.765678  10.190748  27.784094  -20.760891  19.971119  28.424423  -21.875158  -30.634502
+17.454336  27.734694  -28.182638  22.936987  -30.864325  24.006058  -22.265110  18.289276  -29.283976  23.994133
+-28.076096  24.803003  31.810873  -28.802849  16.174349  -12.161655  -0.723460  -30.066971  -4.219203  -27.094242
+-25.232018  -26.122824  8.917661  30.416269  25.667267  -23.732468  27.151720  -31.532894  21.933271  -24.658945
+4.607127  25.353094  -31.823626  18.221535  -9.143847  28.309465  27.168276  28.348866  4.025306  -16.054871
+24.069939  -6.346677  -18.416504  20.772797  29.109146  -22.270210  28.348614  -25.223400  28.465523  33.228703
+-22.829838  31.330181  2.640439  23.182808  29.689547  -25.471079  31.577196  23.975561  -16.879004  27.922268
+29.727743  -26.793751  4.074662  -26.435411  9.276300  -30.378164  -22.027834  -29.494093  17.942389  32.048019
+12.443921  -31.355478  -20.997168  -26.298655  13.543483  -22.858194  27.675776  -9.945221  27.362482  27.321886
+-22.948797  -16.643089  24.180367  -28.334538  30.239267  25.488913  -27.400799  27.946491  12.241156  -26.680285
+-26.742994  -32.847370  0.372974  29.170841  19.595181  25.148224  25.905928  -27.588221  5.420761  22.849968
+-31.289413  -25.980698  10.574203  -26.781279  23.723721  -16.573223  -29.030935  -27.023516  26.670540  -28.518023
+-20.405828  2.004235  -29.175016  31.777958  18.817739  3.310179  24.954983  23.126196  -33.089378  25.994604
+24.361629  -24.034267  27.114393  -22.175446  -21.102106  26.505531  28.671572  -27.174116  27.081461  17.971365
+23.356621  -5.383027  -5.395381  30.386618  -26.971796  35.123657  25.429768  3.912057  -28.749304  27.695974
+5.089523  30.756739  -18.651115  -29.794476  -11.307332  15.305420  -30.898745  26.515871  -26.690683  31.057924
+-27.608395  2.751207  31.480362  -6.192355  -15.776289  14.917231  -26.300941  -31.236757  -9.482904  -31.367132
+-29.525408  13.207518  30.402412  -27.161982  -16.195581  -8.314233  6.639257  26.347960  -12.045978  31.111658
+-25.366018  20.475132  27.603605  30.567028  -27.804394  21.405256  -6.385581  -26.473637  23.634207  -25.096960
+29.934078  -27.561596  21.638102  -26.487444  -7.843333  -32.990967  25.479225  23.726942  1.743223  -23.586367
+-18.529795  -14.682743  -11.309550  29.943205  -32.861969  -24.109367  -11.641270  30.234364  27.131487  27.869272
+32.296886  16.968967  -28.056850  17.463118  4.709224  -25.974831  -25.367235  1.224072  -26.906301  29.314491
+-25.831589  27.744438  28.279171  -23.356329  5.997526  13.055943  27.772594  -29.972574  30.874453  -6.439247
+-27.270761  -26.999367  17.389296  29.682049  25.536079  -31.437716  -17.270382  18.765409  -14.157981  25.990219
+-25.644127  24.661541  -30.554047  20.114891  -23.111427  22.993216  -27.149054  23.140715  20.203518  27.635824
+-25.846523  22.715874  -12.718971  -3.160396  -14.715969  35.330879  -30.877163  15.205578  -22.881746  29.061197
+-15.076153  23.229858  -33.552963  -0.534045  -26.019924  -30.503695  -30.021885  -26.314020  -0.870840  6.176859
+-31.264351  21.678905  -23.063509  30.365349  32.470901  -10.662707  -8.933731  -26.195234  -25.810390  24.120329
+27.617683  -26.467562  24.821156  -18.866934  -30.946278  -19.225807  -19.320507  -27.095076  29.887562  -27.905640
+29.890749  -16.860283  31.453899  14.095822  6.417044  -24.313219  30.336508  -22.971561  22.078314  15.273052
+10.796197  25.368275  -14.171386  -28.335548  16.275265  -31.915974  -18.500086  -33.356716  -19.192612  33.692402
+-27.123287  27.355597  -30.336468  28.779318  -32.750500  10.814196  24.501240  3.015838  23.269903  -25.158703
+-21.149429  -13.080396  -28.024158  -25.943312  23.708012  -28.325745  26.544689  -25.332069  -15.316700  -32.523273
+13.809246  29.555386  19.702276  28.850292  27.295843  -28.034163  27.024630  -24.833534  26.612434  19.731405
+28.613760  -29.762756  -30.633032  9.729327  -30.736677  4.846626  25.470345  24.346096  11.554205  23.544035
+-26.353815  -0.544388  26.486794  -28.141678  -28.819151  -19.970861  -30.929327  22.311621  27.651613  26.565744
+1.227070  10.043915  -22.600807  26.245567  25.942457  -30.712118  -27.150064  -30.792393  -24.804663  -30.143036
+26.438381  12.739036  29.980673  29.757868  17.797293  25.890196  28.367943  -28.205496  16.972397  -27.318939
diff --git a/codec2/branches/0.7/src/codebook/lspdt1.txt b/codec2/branches/0.7/src/codebook/lspdt1.txt
new file mode 100644 (file)
index 0000000..ba30880
--- /dev/null
@@ -0,0 +1,9 @@
+1 8
+-75
+-50
+-25
+  0
+ 25
+ 50
+ 75
+100
diff --git a/codec2/branches/0.7/src/codebook/lspdt10.txt b/codec2/branches/0.7/src/codebook/lspdt10.txt
new file mode 100644 (file)
index 0000000..e72c16c
--- /dev/null
@@ -0,0 +1,3 @@
+1 2
+-50
+ 50
diff --git a/codec2/branches/0.7/src/codebook/lspdt2.txt b/codec2/branches/0.7/src/codebook/lspdt2.txt
new file mode 100644 (file)
index 0000000..ba30880
--- /dev/null
@@ -0,0 +1,9 @@
+1 8
+-75
+-50
+-25
+  0
+ 25
+ 50
+ 75
+100
diff --git a/codec2/branches/0.7/src/codebook/lspdt3.txt b/codec2/branches/0.7/src/codebook/lspdt3.txt
new file mode 100644 (file)
index 0000000..7ebefd9
--- /dev/null
@@ -0,0 +1,5 @@
+1 4
+-50
+  0
+ 50
+ 100
diff --git a/codec2/branches/0.7/src/codebook/lspdt4.txt b/codec2/branches/0.7/src/codebook/lspdt4.txt
new file mode 100644 (file)
index 0000000..7ebefd9
--- /dev/null
@@ -0,0 +1,5 @@
+1 4
+-50
+  0
+ 50
+ 100
diff --git a/codec2/branches/0.7/src/codebook/lspdt5.txt b/codec2/branches/0.7/src/codebook/lspdt5.txt
new file mode 100644 (file)
index 0000000..7ebefd9
--- /dev/null
@@ -0,0 +1,5 @@
+1 4
+-50
+  0
+ 50
+ 100
diff --git a/codec2/branches/0.7/src/codebook/lspdt6.txt b/codec2/branches/0.7/src/codebook/lspdt6.txt
new file mode 100644 (file)
index 0000000..7ebefd9
--- /dev/null
@@ -0,0 +1,5 @@
+1 4
+-50
+  0
+ 50
+ 100
diff --git a/codec2/branches/0.7/src/codebook/lspdt7.txt b/codec2/branches/0.7/src/codebook/lspdt7.txt
new file mode 100644 (file)
index 0000000..e72c16c
--- /dev/null
@@ -0,0 +1,3 @@
+1 2
+-50
+ 50
diff --git a/codec2/branches/0.7/src/codebook/lspdt8.txt b/codec2/branches/0.7/src/codebook/lspdt8.txt
new file mode 100644 (file)
index 0000000..e72c16c
--- /dev/null
@@ -0,0 +1,3 @@
+1 2
+-50
+ 50
diff --git a/codec2/branches/0.7/src/codebook/lspdt9.txt b/codec2/branches/0.7/src/codebook/lspdt9.txt
new file mode 100644 (file)
index 0000000..e72c16c
--- /dev/null
@@ -0,0 +1,3 @@
+1 2
+-50
+ 50
diff --git a/codec2/branches/0.7/src/codebook/lspjvm1.txt b/codec2/branches/0.7/src/codebook/lspjvm1.txt
new file mode 100644 (file)
index 0000000..9cd10ed
--- /dev/null
@@ -0,0 +1,513 @@
+10 512
+0.435217 0.668864 1.010296 1.220420 1.503978 1.784675 2.135458 2.357467 2.618905 2.738042
+0.179285 0.333160 0.500638 0.796950 1.039987 1.234969 1.652301 1.848233 2.625555 2.804968
+0.268785 0.356576 0.595753 1.044339 1.249382 1.428680 1.686986 1.864689 2.339905 2.513801
+0.120070 0.165585 0.484694 0.959160 1.237528 1.529146 1.837513 2.107730 2.487495 2.766846
+0.150214 0.229487 0.628240 0.961255 1.337065 1.598306 1.919745 2.217861 2.537318 2.759560
+0.268624 0.345980 0.569637 0.754737 0.916538 1.508543 1.786354 1.954418 2.369530 2.501822
+0.246064 0.468874 0.662711 0.890015 1.147153 1.510431 1.781056 2.095943 2.655391 2.800369
+0.191631 0.280628 0.393229 0.611761 1.420170 1.707741 1.873032 2.101553 2.280348 2.499488
+0.361668 0.507047 0.789974 1.045992 1.502378 1.677032 1.905337 2.162555 2.432259 2.590873
+0.208160 0.294285 0.448634 0.694229 0.872517 1.070315 1.703352 2.168742 2.426189 2.603657
+0.316939 0.513618 0.705487 0.917036 1.175989 1.311140 1.618599 2.037840 2.450523 2.579395
+0.241068 0.377728 0.521595 0.717203 1.310414 1.539991 1.736431 2.098926 2.297917 2.587348
+0.234937 0.281875 0.780422 1.440733 1.609428 1.756430 1.977206 2.148605 2.602032 2.722501
+0.178679 0.242672 0.416988 0.708348 0.955620 1.176671 1.781798 2.054488 2.281591 2.448112
+0.345036 0.421080 0.740887 1.165442 1.324944 1.488798 1.763463 1.906174 2.395050 2.649158
+0.249586 0.357494 0.520747 0.847195 1.428408 1.597779 1.778194 2.178502 2.413437 2.564662
+0.295235 0.574231 1.249097 1.464097 1.727559 1.926790 2.095363 2.284830 2.567065 2.722480
+0.341930 0.427307 0.634001 0.804212 0.905629 1.333373 1.790329 1.892756 2.445823 2.602828
+0.363948 0.508985 0.667357 0.946354 1.437562 1.626545 1.811141 2.039091 2.291882 2.435493
+0.163514 0.277407 0.409207 0.902065 1.189070 1.339636 1.802411 1.960770 2.652930 2.818987
+0.302643 0.359753 0.651207 1.208021 1.423702 1.548149 1.882130 2.015591 2.260535 2.578896
+0.155928 0.216908 0.381812 0.654803 1.112373 1.589935 1.847562 1.976716 2.224078 2.725337
+0.274981 0.347675 0.572000 0.736046 0.894248 1.632373 1.891391 2.056890 2.602900 2.721779
+0.154496 0.243461 0.348174 0.689505 1.573807 1.700306 1.943182 2.101580 2.564661 2.773169
+0.292612 0.466612 0.795936 1.047468 1.413693 1.750848 2.062894 2.340073 2.613612 2.769493
+0.242896 0.361500 0.555859 0.793597 0.932291 1.409467 1.863863 2.009534 2.464500 2.677491
+0.221646 0.344724 0.554564 0.729403 1.136575 1.301772 1.529181 2.163590 2.395821 2.610805
+0.160969 0.224467 0.371545 0.626879 1.160953 1.444229 1.675966 1.879779 2.478590 2.672023
+0.214172 0.341585 0.676575 0.977397 1.325429 1.720096 2.072595 2.369539 2.635285 2.778792
+0.203311 0.289438 0.458739 0.914153 1.122885 1.302925 1.583844 1.886828 2.187869 2.427039
+0.280383 0.371600 0.824827 1.100246 1.236225 1.398923 1.578041 2.016000 2.368973 2.506732
+0.170627 0.251778 0.393686 0.608347 1.287599 1.446665 1.793278 2.036554 2.310153 2.752439
+0.180580 0.288746 0.987854 1.431706 1.677216 1.915661 2.124939 2.289452 2.589612 2.754264
+0.176335 0.266263 0.445421 0.706403 0.875402 1.422918 1.758670 1.960910 2.410676 2.601751
+0.216173 0.287404 0.480696 1.009765 1.291304 1.476644 1.895584 2.064286 2.284064 2.483108
+0.176523 0.273934 0.403407 0.966139 1.304724 1.436612 1.944728 2.084836 2.544458 2.762416
+0.311836 0.550501 0.879591 1.096228 1.276661 1.477859 1.817706 2.154340 2.560467 2.779841
+0.179765 0.250560 0.455939 1.023886 1.225132 1.475662 1.734617 1.918713 2.147342 2.438235
+0.271033 0.457235 0.599622 0.821049 0.940125 1.200937 1.849716 1.986656 2.548168 2.751578
+0.179326 0.248002 0.426405 0.817060 1.285888 1.565019 2.117359 2.298712 2.572404 2.752701
+0.374409 0.535936 0.897009 1.185070 1.591569 1.757202 1.967944 2.179985 2.457394 2.622641
+0.185472 0.282752 0.409439 0.657499 0.856446 1.029396 1.879933 2.069323 2.344742 2.753103
+0.375964 0.578457 0.758945 0.929339 1.127475 1.259437 1.704109 2.122973 2.336031 2.498298
+0.225641 0.361030 0.501679 0.783379 1.314851 1.452621 1.714150 1.987157 2.225703 2.724361
+0.144996 0.252919 0.632145 1.226038 1.575343 1.901549 2.171481 2.390554 2.682293 2.809834
+0.172022 0.263338 0.448634 0.729435 0.984007 1.171597 1.757049 1.990232 2.321305 2.771210
+0.235731 0.351117 0.796871 1.055711 1.300224 1.591818 1.895875 2.122918 2.417888 2.599817
+0.254053 0.319371 0.455623 1.086141 1.664667 1.915882 2.059084 2.233416 2.452037 2.586788
+0.375538 0.742993 1.139911 1.337758 1.735562 2.013906 2.315012 2.483433 2.651575 2.755211
+0.247245 0.481131 0.710366 0.897602 1.121094 1.271709 1.787346 2.199502 2.429663 2.740668
+0.226103 0.311441 0.501648 0.844424 1.362818 1.531338 1.777474 1.989925 2.187493 2.358501
+0.195862 0.296224 0.609554 0.783241 1.243472 1.445477 1.637032 2.022645 2.483557 2.646137
+0.233302 0.299441 0.472792 1.249457 1.457875 1.601860 1.831433 1.993719 2.597193 2.755433
+0.168096 0.224183 0.382700 0.596214 1.060587 1.294418 1.605760 1.848489 2.357695 2.569186
+0.330050 0.445912 0.661713 0.874446 1.000792 1.452973 1.943987 2.076916 2.423883 2.612359
+0.226382 0.287303 0.517631 0.806229 1.309009 1.885280 2.160514 2.286410 2.526377 2.660822
+0.203170 0.499314 0.887358 1.235074 1.462922 1.698260 1.999316 2.229225 2.571613 2.766691
+0.307531 0.378353 0.573606 0.712218 0.850169 1.308996 2.059092 2.263816 2.497943 2.676815
+0.276203 0.510250 0.686800 0.902844 1.205197 1.327979 1.718894 2.038947 2.256393 2.697149
+0.161948 0.229115 0.393619 0.683613 1.137811 1.322692 1.783723 1.961584 2.389073 2.636082
+0.201334 0.276773 0.468994 0.967017 1.475971 1.632424 1.965774 2.197278 2.480593 2.701553
+0.214587 0.315421 0.469498 0.733397 1.146003 1.277911 1.727839 2.227135 2.440264 2.681122
+0.255602 0.394609 0.743393 0.977796 1.199085 1.405972 1.918336 2.224828 2.479187 2.663394
+0.245989 0.352625 0.517055 0.802830 1.558712 1.795653 1.944055 2.133640 2.333267 2.479982
+0.337423 0.480433 0.869036 1.139571 1.630764 1.822959 2.074843 2.292613 2.479130 2.625317
+0.220974 0.358850 0.571640 0.752791 0.937013 1.151721 1.674398 2.062466 2.558717 2.784838
+0.267518 0.331708 0.541111 1.116547 1.411121 1.532868 1.792949 1.933520 2.248940 2.628644
+0.084613 0.105083 0.297424 0.916949 1.256301 1.567029 1.885388 2.189875 2.522795 2.792102
+0.205328 0.287223 0.724462 1.032395 1.457708 1.642169 1.925628 2.175524 2.429638 2.605488
+0.232554 0.338724 0.502115 0.859975 1.044090 1.245652 1.806555 1.999641 2.261164 2.459984
+0.291638 0.379172 0.626072 0.792796 0.959124 1.504886 1.734465 1.919612 2.614359 2.722709
+0.191554 0.263114 0.426797 0.610628 1.077406 1.829543 2.021948 2.210572 2.427652 2.613828
+0.389151 0.679476 0.915414 1.036635 1.250846 1.586610 2.040972 2.281500 2.567941 2.718815
+0.203200 0.301280 0.470357 0.668716 0.851737 0.980327 1.570862 2.037617 2.289067 2.693877
+0.304064 0.405934 0.710274 0.962705 1.128820 1.341667 1.635050 1.845382 2.079916 2.507510
+0.171777 0.240705 0.409371 0.786432 1.223202 1.375689 1.691760 1.866080 2.350406 2.493942
+0.231251 0.277994 0.557867 1.325822 1.660352 1.779477 2.007138 2.172322 2.440457 2.652308
+0.188101 0.259494 0.412543 0.624843 0.839549 1.033700 1.634128 1.931944 2.246076 2.425773
+0.361304 0.419465 0.795676 1.184605 1.296796 1.578447 1.841746 1.997361 2.540538 2.687139
+0.274372 0.338938 0.492443 0.963516 1.509514 1.706378 1.869885 2.077166 2.261281 2.444183
+0.415990 0.652103 1.031293 1.269551 1.572746 1.772975 2.004659 2.175272 2.430606 2.596553
+0.242045 0.370942 0.534392 0.763529 1.001165 1.129764 1.682192 2.144644 2.324478 2.715697
+0.377438 0.588168 0.765394 0.976873 1.356652 1.490088 1.737970 2.006774 2.213691 2.389973
+0.191625 0.284123 0.405342 1.016777 1.432730 1.547592 1.813930 1.958317 2.470765 2.649257
+0.272672 0.349555 0.633911 1.152234 1.303938 1.547640 1.919504 2.047696 2.562779 2.730575
+0.168423 0.236330 0.421468 0.831345 1.083543 1.553448 1.880726 2.064701 2.370864 2.632945
+0.219318 0.301481 0.513617 0.765086 1.026019 1.514647 2.048203 2.248568 2.499810 2.657069
+0.232695 0.347947 0.495203 0.718830 1.423013 1.722493 1.879584 2.165044 2.420251 2.589658
+0.270284 0.336865 0.684929 1.155789 1.690421 1.876744 2.027359 2.226178 2.446748 2.582000
+0.149701 0.193747 0.352019 0.520123 0.823974 1.434753 1.686592 1.961148 2.370914 2.693067
+0.254818 0.412303 0.601514 0.771438 1.175450 1.376569 1.539029 1.937039 2.408576 2.563621
+0.233713 0.355886 0.593725 0.762880 1.271479 1.563900 1.797523 2.094688 2.538627 2.711734
+0.179028 0.237103 0.396818 1.042021 1.633539 1.762676 2.123935 2.322391 2.588193 2.751345
+0.182027 0.251039 0.434581 0.714302 0.950997 1.437895 1.813570 1.969103 2.145882 2.353968
+0.501538 0.692148 0.848860 1.071308 1.350543 1.489476 1.841643 2.104284 2.341536 2.515294
+0.274530 0.381470 0.526682 0.922143 1.444946 1.573605 1.858767 2.066747 2.284796 2.626819
+0.360617 0.583131 0.979491 1.254083 1.488351 1.797557 2.219518 2.482176 2.742366 2.862025
+0.140913 0.220301 0.619552 0.818307 1.052429 1.339972 1.830726 2.133953 2.536378 2.751128
+0.293514 0.391691 0.790080 0.962740 1.160319 1.526602 1.805491 2.041462 2.361619 2.564962
+0.199542 0.290571 0.452891 0.689515 1.258530 1.409879 1.886242 2.228126 2.465677 2.726646
+0.296920 0.356356 0.784287 0.996540 1.146175 1.623865 1.815498 2.038297 2.600627 2.705700
+0.206451 0.276025 0.537547 0.802572 1.220407 1.642060 1.863625 2.001978 2.215339 2.585384
+0.333650 0.464751 0.653772 0.966306 1.103865 1.340203 1.784701 1.914591 2.470171 2.686916
+0.181861 0.244870 0.376456 0.554383 1.329897 1.810440 2.047836 2.202318 2.660855 2.817057
+0.450565 0.647291 0.951172 1.229431 1.519644 1.686812 2.049107 2.267169 2.501284 2.650596
+0.219996 0.320591 0.427747 0.601183 0.753448 0.929578 1.741979 2.285789 2.472633 2.749566
+0.333848 0.423373 0.658791 1.031299 1.222625 1.365771 1.901889 2.121101 2.290306 2.531185
+0.166064 0.233902 0.383355 0.661806 1.226567 1.399684 1.771269 1.974537 2.173487 2.566344
+0.189286 0.243602 0.390584 1.387930 1.588719 1.763237 2.091118 2.316314 2.593526 2.755080
+0.158404 0.224878 0.385000 0.668463 0.942954 1.411967 1.700313 1.828069 2.059396 2.692546
+0.325989 0.461263 0.851471 1.045709 1.284028 1.516199 1.797341 2.088387 2.437669 2.627215
+0.223709 0.289190 0.632812 0.858738 1.541903 1.746766 1.935738 2.184816 2.404330 2.583013
+0.545842 0.952420 1.340820 1.516838 1.838879 2.012890 2.244968 2.403170 2.592285 2.691119
+0.238526 0.349079 0.494582 0.987665 1.170746 1.348229 1.468645 2.296964 2.644160 2.787381
+0.270857 0.442003 0.655998 0.881913 1.259254 1.428358 1.769867 1.998528 2.395589 2.652840
+0.154384 0.211806 0.489481 0.997257 1.249817 1.541232 1.778865 1.949397 2.319136 2.623391
+0.268258 0.312888 0.589114 1.258625 1.572705 1.675430 1.912780 2.070458 2.279933 2.564230
+0.170715 0.224965 0.374011 0.540197 1.161887 1.499072 1.925865 2.082569 2.246619 2.469724
+0.324358 0.391989 0.706816 0.833614 1.015725 1.568995 1.735976 2.127068 2.558411 2.653871
+0.178059 0.258575 0.374125 0.536831 1.334827 1.798628 1.986978 2.189252 2.432266 2.626696
+0.198857 0.420955 0.817664 1.178363 1.466742 1.821295 2.207327 2.474411 2.738275 2.851185
+0.188344 0.324302 0.470468 0.790033 0.934101 1.188722 1.887171 2.052833 2.448325 2.630236
+0.201295 0.365646 0.526513 0.758388 1.140096 1.267331 1.650173 1.879342 2.102889 2.600286
+0.135058 0.169428 0.307348 0.503160 1.018083 1.447946 1.810984 2.134002 2.480277 2.759846
+0.178006 0.266610 0.390327 0.928681 1.501613 1.621327 1.871356 2.025864 2.580442 2.770801
+0.246182 0.424290 0.644023 0.801168 1.114876 1.277757 1.503317 2.074888 2.295695 2.501380
+0.322996 0.430355 0.631600 1.047698 1.221840 1.426726 1.903081 2.032223 2.516726 2.708452
+0.292994 0.430599 0.619178 0.794567 1.283029 1.652817 1.840836 2.069946 2.385375 2.528246
+0.525494 0.787797 1.121816 1.387482 1.674574 1.936221 2.224042 2.390624 2.634276 2.743234
+0.299504 0.409196 0.602235 0.892336 1.056426 1.253766 1.489136 1.639876 2.427480 2.650368
+0.423758 0.520480 0.758987 1.041257 1.173655 1.423676 1.818235 1.936407 2.363001 2.626644
+0.155042 0.247496 0.641445 0.954509 1.224970 1.465850 1.837841 2.090456 2.451501 2.716155
+0.251949 0.421094 0.706797 0.975659 1.259906 1.520067 1.816310 2.122017 2.474913 2.716671
+0.215220 0.302248 0.730598 0.896343 1.145567 1.370192 1.700685 2.022563 2.283265 2.489220
+0.285230 0.453559 0.663670 0.861526 1.011602 1.247419 1.655985 1.861291 2.578936 2.731333
+0.162067 0.219409 0.373433 0.544669 1.103298 1.597178 1.921040 2.143402 2.406499 2.660484
+0.342367 0.511499 0.931350 1.163219 1.393645 1.611146 1.972769 2.194416 2.470766 2.649264
+0.251010 0.364125 0.560956 0.746545 1.019837 1.170725 1.532945 2.288671 2.577088 2.723074
+0.315001 0.489412 0.720682 0.877607 1.090466 1.253848 1.448221 1.922954 2.255887 2.408634
+0.174666 0.235793 0.387644 0.554402 1.231089 1.456137 1.688034 2.127450 2.367035 2.597270
+0.215113 0.341915 1.043717 1.322751 1.495414 1.741895 1.961164 2.239824 2.544905 2.703945
+0.219852 0.301770 0.513912 0.705474 0.877540 1.295896 1.699002 1.987057 2.287968 2.496966
+0.290638 0.366442 0.655155 1.044990 1.172154 1.532536 1.800791 1.948931 2.509679 2.660055
+0.232252 0.313770 0.658552 0.941977 1.463174 1.665488 1.862461 2.027843 2.534016 2.701236
+0.326539 0.552681 1.121731 1.331381 1.520072 1.867084 2.082861 2.332474 2.606039 2.737092
+0.190254 0.340428 0.492777 0.739738 0.895461 1.079371 1.643156 1.795290 2.491822 2.729382
+0.283586 0.418440 0.587306 0.870866 1.418553 1.577030 1.799498 2.069398 2.274484 2.438103
+0.235752 0.357650 0.502891 1.012434 1.258853 1.407789 1.820057 1.955830 2.505903 2.734330
+0.278412 0.343137 0.849977 1.232895 1.350504 1.590626 1.787519 2.091578 2.541360 2.663856
+0.162966 0.243159 0.439238 0.684821 0.887783 1.462899 1.881739 2.044253 2.289393 2.705002
+0.235063 0.371799 0.578210 0.752199 1.008546 1.476284 1.804912 2.271399 2.655042 2.789653
+0.154939 0.223696 0.344718 0.667555 1.495659 1.669436 2.069883 2.307215 2.627692 2.811343
+0.239702 0.335917 0.716616 1.131805 1.452514 1.639133 2.105515 2.279822 2.502030 2.669220
+0.226818 0.331261 0.472705 0.651974 0.781639 1.219798 1.822904 2.082732 2.439327 2.610900
+0.223413 0.359594 0.534704 0.741518 1.225894 1.389874 1.618191 2.009911 2.207000 2.459844
+0.171308 0.268378 0.383799 0.858926 1.376293 1.519165 1.780601 1.922915 2.623094 2.802402
+0.140134 0.212320 0.443224 0.967457 1.264241 1.562153 1.929148 2.217388 2.668341 2.830751
+0.221323 0.322124 0.485563 0.818589 1.011837 1.198984 1.423616 1.669403 2.157523 2.363190
+0.369687 0.525655 0.719213 0.939654 1.137631 1.312217 1.599935 1.826813 2.355221 2.580680
+0.211975 0.314411 0.489148 0.739213 1.377801 1.554504 1.824373 2.158875 2.352992 2.722621
+0.170698 0.296368 0.934285 1.243133 1.555900 1.866544 2.159940 2.363436 2.585032 2.738530
+0.189263 0.305887 0.439912 0.784610 1.227264 1.342508 1.587650 1.754907 2.439893 2.721315
+0.296339 0.385169 0.612012 1.081322 1.276361 1.437178 1.871470 2.001718 2.339094 2.640217
+0.229588 0.320544 0.517278 0.969137 1.142560 1.626089 1.877916 2.115461 2.546741 2.708025
+0.248869 0.420193 0.732388 1.049015 1.303410 1.601458 1.949210 2.239464 2.648223 2.822614
+0.207600 0.292320 0.496539 0.857149 1.182294 1.399849 1.714165 1.868238 2.027936 2.200737
+0.225558 0.396897 0.541783 0.873366 1.178972 1.299579 1.677191 1.849602 2.330475 2.752717
+0.176821 0.231377 0.372767 0.508565 1.152819 1.808050 2.112679 2.250073 2.571342 2.748550
+0.352149 0.515765 1.023238 1.260221 1.443565 1.622067 1.872804 2.100177 2.489280 2.671043
+0.166138 0.263444 0.370151 0.590066 0.754819 0.940533 1.761870 1.946611 2.445015 2.758191
+0.342082 0.476411 0.656223 0.851774 1.003992 1.153372 1.694401 2.065625 2.255642 2.440148
+0.227237 0.376514 0.514329 0.894887 1.141673 1.283052 1.831377 1.985902 2.334470 2.784878
+0.215891 0.269548 0.684111 1.405658 1.674813 1.800925 2.172085 2.339395 2.591569 2.730100
+0.236240 0.400377 0.533684 0.750343 0.910405 1.089112 1.737729 1.912807 2.192519 2.688733
+0.169242 0.284879 0.916252 1.169769 1.433683 1.644376 1.919124 2.161625 2.482664 2.682591
+0.270731 0.336506 0.477594 1.042714 1.605840 1.796859 1.945909 2.160039 2.354913 2.520950
+0.420586 0.652563 1.117162 1.406006 1.747537 1.947424 2.203094 2.359970 2.547902 2.682168
+0.281552 0.395037 0.640181 0.944531 1.193959 1.330492 1.718657 2.188389 2.444591 2.578673
+0.311824 0.476892 0.633431 0.845825 1.332518 1.491656 1.693614 2.041082 2.289317 2.439399
+0.133945 0.200790 0.647237 0.927687 1.188883 1.369658 1.699557 1.972777 2.295259 2.678185
+0.204796 0.278215 0.443465 1.270484 1.405209 1.640920 1.824252 2.327085 2.599637 2.772533
+0.183970 0.244116 0.410594 0.639103 1.221589 1.404867 1.628358 1.902439 2.168632 2.306804
+0.343622 0.434735 0.666599 0.868069 1.048942 1.532778 1.819835 1.971884 2.288701 2.448745
+0.238017 0.320361 0.657255 0.917611 1.303306 1.727361 1.988909 2.181455 2.442965 2.613322
+0.323613 0.545056 0.930173 1.226059 1.440181 1.772300 2.056890 2.347811 2.689382 2.820616
+0.288930 0.401387 0.617124 0.836453 0.990306 1.261227 1.913283 2.110049 2.324584 2.557162
+0.332670 0.480804 0.656147 0.880536 1.029566 1.230493 1.769063 1.932296 2.200370 2.585210
+0.185551 0.265352 0.409432 0.608847 1.034698 1.222821 1.876965 2.171647 2.403502 2.666441
+0.155026 0.223348 0.401684 1.079141 1.415789 1.620021 2.045515 2.258512 2.631625 2.802291
+0.183461 0.263081 0.425694 0.635685 1.188664 1.357556 1.574991 2.085982 2.288725 2.511108
+0.314738 0.463011 0.648733 0.877651 1.002890 1.265811 2.005414 2.198095 2.481535 2.714178
+0.244411 0.318444 0.546578 0.793615 1.326150 1.735479 1.945598 2.114662 2.315350 2.478535
+0.326237 0.543540 0.987361 1.304413 1.684932 1.902147 2.207172 2.374273 2.557527 2.716216
+0.157795 0.283302 0.430398 0.660379 0.811060 1.142539 1.479298 1.718714 2.670264 2.847556
+0.220856 0.283872 0.779935 1.074940 1.312211 1.626329 1.837609 1.968885 2.155988 2.602381
+0.140763 0.205719 0.406561 0.762459 1.041266 1.486993 1.838306 2.114606 2.552810 2.772285
+0.140451 0.395920 0.792110 1.108001 1.402642 1.623079 1.943151 2.227952 2.546163 2.773998
+0.229862 0.336462 0.546590 0.810150 1.201906 1.346787 1.825323 2.092925 2.285730 2.473359
+0.224913 0.328246 0.517269 0.874793 1.012587 1.452178 1.695778 2.014930 2.511447 2.672574
+0.247745 0.335741 0.546558 0.710177 1.170556 1.727789 1.970678 2.158532 2.482819 2.628913
+0.398252 0.555087 0.890367 1.121205 1.381533 1.601228 1.866647 2.066612 2.405164 2.588016
+0.198563 0.288867 0.478054 0.658477 0.851841 1.027105 1.539739 2.021106 2.579462 2.784184
+0.304271 0.371642 0.661590 1.068976 1.224249 1.411927 1.680524 1.869770 2.100073 2.308554
+0.188223 0.257939 0.432402 0.735050 1.318038 1.485528 1.828110 2.046435 2.307018 2.457237
+0.246723 0.297276 0.604475 1.310901 1.570442 1.688851 1.913658 2.051334 2.556011 2.714965
+0.158309 0.234509 0.435792 0.667900 0.957567 1.235918 1.592945 1.818158 2.307389 2.768973
+0.419843 0.501412 0.766892 1.073173 1.189374 1.480225 1.766597 1.922151 2.537937 2.694771
+0.275140 0.335563 0.678421 1.081521 1.592379 1.772635 1.931245 2.140699 2.333804 2.490857
+0.372056 0.856814 1.239538 1.409989 1.690297 1.863018 2.072702 2.273547 2.532657 2.690517
+0.321254 0.422981 0.604856 0.793437 0.912112 1.128454 1.795979 2.173232 2.360146 2.536137
+0.395214 0.598779 0.771997 0.946713 1.213777 1.330433 1.660335 1.977154 2.165056 2.344018
+0.225286 0.317828 0.464801 1.112329 1.369512 1.511999 1.921954 2.053407 2.593519 2.777285
+0.330612 0.407807 0.730129 1.259731 1.459811 1.605671 1.981307 2.137009 2.465971 2.679722
+0.213145 0.305305 0.507016 0.662299 1.056848 1.479862 1.671904 2.102707 2.369871 2.581994
+0.219658 0.296096 0.443507 0.610973 0.799691 1.676579 1.965487 2.153235 2.502228 2.692999
+0.174947 0.257739 0.373547 0.552567 1.405316 1.614249 1.848917 2.117795 2.317884 2.711904
+0.209667 0.297529 0.756195 1.095304 1.564196 1.844775 2.103697 2.292657 2.520051 2.679489
+0.170138 0.240310 0.452247 0.684414 0.880102 1.366921 1.741648 2.131295 2.505730 2.732611
+0.278164 0.468635 0.707518 0.853693 1.054780 1.210458 1.540941 2.174562 2.410662 2.612138
+0.155738 0.238890 0.352836 0.621012 1.441438 1.619698 1.825165 1.975331 2.525373 2.748574
+0.223776 0.274424 0.479048 0.797871 1.694190 1.878135 2.135285 2.373726 2.595422 2.729787
+0.151088 0.198286 0.326558 0.536276 0.845893 1.141653 1.460565 1.762868 2.025851 2.177303
+0.434445 0.614208 0.887657 1.028446 1.191359 1.392204 1.786886 2.062481 2.423405 2.619356
+0.180755 0.275311 0.397787 0.859366 1.409762 1.523325 1.908846 2.082319 2.389720 2.743887
+0.275975 0.508416 0.889894 1.318925 1.633314 1.904728 2.169012 2.374655 2.726973 2.847666
+0.156239 0.262624 0.406657 0.739074 1.044495 1.201234 1.810887 2.005600 2.581700 2.804889
+0.195391 0.258771 0.654924 0.824371 1.315259 1.500728 1.765938 2.063992 2.341176 2.513659
+0.178034 0.301047 0.463020 0.716172 1.198868 1.340454 1.834558 2.022132 2.400750 2.776294
+0.340368 0.404236 0.843747 1.039238 1.202107 1.708051 1.914952 2.169509 2.521521 2.623348
+0.218465 0.289694 0.528045 0.817051 1.132337 1.580464 1.838891 1.983392 2.147493 2.348131
+0.322509 0.458058 0.654679 0.958976 1.118211 1.321565 1.901390 2.046409 2.360931 2.664215
+0.191821 0.252321 0.389176 0.581111 1.529667 1.931689 2.083614 2.270465 2.566855 2.713879
+0.493961 0.710827 0.982260 1.196274 1.419327 1.620910 1.928015 2.145652 2.429769 2.601973
+0.213148 0.311589 0.424636 0.602664 0.736895 1.022165 1.992278 2.218533 2.611628 2.850324
+0.288129 0.434441 0.629313 0.856153 1.289667 1.424520 1.875795 2.150240 2.351814 2.536843
+0.160031 0.230716 0.406654 0.870424 1.156517 1.392317 1.804098 1.951437 2.210479 2.735164
+0.229340 0.293962 0.503222 1.242097 1.475824 1.624647 1.998680 2.144499 2.578549 2.753270
+0.158770 0.220035 0.363386 0.577761 0.963090 1.174939 1.738169 1.979202 2.162436 2.661916
+0.346062 0.444816 0.716985 1.180717 1.370580 1.522996 1.892173 2.066682 2.395796 2.627659
+0.307495 0.389330 0.612607 0.969283 1.557708 1.839939 1.996737 2.172382 2.420627 2.539195
+0.437804 0.726957 1.291168 1.503297 1.765428 1.962121 2.163647 2.336227 2.579616 2.708524
+0.232184 0.333678 0.528368 0.706749 1.203280 1.379018 1.611161 2.154678 2.592903 2.750319
+0.272652 0.461710 0.625777 0.839609 1.342021 1.496726 1.715376 2.137572 2.370040 2.597390
+0.184908 0.302324 0.454883 0.880307 1.104383 1.292526 1.777203 1.943364 2.444174 2.622726
+0.265644 0.341261 0.553228 1.139475 1.427148 1.560441 1.933941 2.084129 2.393307 2.654135
+0.167920 0.207301 0.370331 0.525538 1.030891 1.368163 1.782474 2.062404 2.332762 2.526299
+0.343172 0.433912 0.717501 0.889734 1.052060 1.695278 2.053156 2.208456 2.608869 2.718320
+0.216527 0.305247 0.445890 0.729271 1.639736 1.903284 2.053351 2.221254 2.432253 2.568018
+0.110545 0.209955 0.844788 1.174205 1.492201 1.810243 2.177274 2.440496 2.697294 2.835232
+0.217384 0.337412 0.488999 0.761842 0.879715 1.209528 1.970747 2.120795 2.611654 2.791762
+0.190459 0.296484 0.469967 0.800649 1.105561 1.278527 1.516938 1.693066 2.114420 2.716739
+0.134814 0.175978 0.300425 0.496817 1.244295 1.485308 1.861721 2.131233 2.485046 2.773884
+0.210174 0.278266 0.435508 0.927538 1.606908 1.753898 1.957554 2.166283 2.398518 2.749609
+0.213766 0.315300 0.509924 0.709930 0.964724 1.106776 1.382615 2.001070 2.323214 2.565314
+0.400615 0.524954 0.798552 1.012852 1.135488 1.474850 1.989029 2.130909 2.507971 2.679460
+0.249400 0.377023 0.519635 0.754227 1.459559 1.642762 1.828961 2.077882 2.298228 2.467534
+0.473365 0.683973 1.052341 1.375830 1.548106 1.747589 2.139299 2.318768 2.609977 2.739255
+0.203877 0.341791 0.485180 0.884069 1.097592 1.269532 1.479924 1.757879 2.648399 2.822387
+0.273046 0.404254 0.555403 0.954547 1.291233 1.399022 1.722890 1.903441 2.171984 2.645312
+0.040369 0.117266 0.617136 0.892043 1.260331 1.541653 1.859383 2.153096 2.498232 2.761886
+0.132414 0.211358 0.742445 1.066857 1.331084 1.570793 1.867458 2.132535 2.479624 2.731076
+0.237329 0.326529 0.612538 0.790663 0.990133 1.413736 1.738235 1.936914 2.167728 2.451626
+0.273960 0.405794 0.572530 0.933672 1.057816 1.397952 1.856531 1.997548 2.599486 2.760042
+0.199334 0.298380 0.442931 0.628638 1.303213 1.640138 1.804023 2.113020 2.375455 2.548946
+0.350188 0.502010 0.821298 1.038639 1.369294 1.592404 1.910815 2.156486 2.460508 2.653260
+0.281558 0.399892 0.573105 0.753299 0.900613 1.054574 1.581987 2.178437 2.430354 2.616044
+0.344653 0.543532 0.703715 0.862285 1.198215 1.338208 1.579080 2.060769 2.306749 2.485749
+0.220701 0.326795 0.520618 0.755133 1.295552 1.451886 1.690502 2.200045 2.414271 2.615909
+0.279478 0.332193 0.801527 1.345966 1.487477 1.678499 1.922202 2.100025 2.585571 2.713387
+0.163502 0.212169 0.365096 0.525464 0.869846 1.208807 1.793988 2.040314 2.297180 2.469797
+0.285531 0.341488 0.754059 1.170016 1.300835 1.513696 1.699861 1.889918 2.581459 2.706874
+0.249595 0.366997 0.626427 0.945219 1.407043 1.560558 1.831657 2.231149 2.466354 2.654518
+0.271671 0.443136 1.156412 1.406456 1.676521 1.856481 2.063218 2.230498 2.475840 2.639575
+0.286620 0.427806 0.637320 0.803409 0.996161 1.266383 1.681751 2.003968 2.394651 2.588547
+0.314906 0.440519 0.612129 0.896126 1.472415 1.717693 1.881351 2.099437 2.369166 2.495466
+0.170277 0.251270 0.405477 0.915641 1.126887 1.436630 1.714771 1.893198 2.552995 2.738519
+0.279410 0.337137 0.734563 1.281046 1.480602 1.611880 1.853215 1.994883 2.416054 2.654827
+0.165776 0.226083 0.417544 0.744574 1.044468 1.534891 1.808494 1.944946 2.138491 2.601790
+0.264579 0.336652 0.542033 0.710190 0.913338 1.655751 1.817762 2.231956 2.524436 2.658519
+0.158194 0.235588 0.338347 0.541657 1.583377 1.766293 2.009135 2.243336 2.503941 2.775158
+0.332612 0.509620 0.822935 1.075876 1.454286 1.650788 1.974450 2.251279 2.537342 2.745115
+0.262817 0.359709 0.520893 0.707667 0.818364 1.438849 1.971249 2.087666 2.497014 2.646442
+0.233200 0.399599 0.612456 0.775547 1.199192 1.355765 1.646901 2.136245 2.342490 2.695742
+0.149687 0.238538 0.372248 0.634520 1.255813 1.433790 1.770041 1.928752 2.611905 2.824930
+0.137016 0.210297 0.591489 1.125451 1.375648 1.685296 2.089612 2.390888 2.704458 2.844434
+0.213490 0.341024 0.541716 0.750061 1.088199 1.244576 1.555338 1.965568 2.187900 2.383714
+0.300159 0.489291 0.825022 1.037100 1.194088 1.347375 1.684747 2.024936 2.465611 2.740973
+0.170029 0.255033 0.392758 0.727117 1.382065 1.579676 1.800912 1.959072 2.282335 2.728796
+0.175883 0.365509 1.112175 1.385866 1.720391 1.977810 2.245295 2.421614 2.629567 2.754004
+0.162590 0.248164 0.454630 0.763209 0.966031 1.282338 1.730743 1.938052 2.479376 2.667563
+0.258043 0.345866 0.556520 0.981312 1.361528 1.482377 1.872244 2.158226 2.362269 2.555030
+0.234139 0.348843 0.528234 0.987884 1.195217 1.422145 1.960028 2.127365 2.603321 2.793004
+0.179699 0.559209 0.867682 1.088835 1.316888 1.571498 1.922198 2.197391 2.501118 2.728679
+0.216784 0.310791 0.487492 0.932903 1.201954 1.366554 1.800398 1.977499 2.174265 2.537065
+0.186878 0.400655 0.580952 0.846287 1.103872 1.266778 1.842772 2.019592 2.488005 2.717222
+0.164641 0.248712 0.389358 0.772822 1.212561 1.369916 2.025869 2.277615 2.617524 2.809527
+0.351899 0.520326 0.926597 1.219651 1.509839 1.676837 1.921744 2.111253 2.356380 2.545934
+0.242182 0.365285 0.506156 0.716020 0.865221 1.011688 1.786917 2.122981 2.350877 2.767729
+0.413776 0.559566 0.735800 0.928997 1.079117 1.267179 1.880069 2.152492 2.324834 2.539856
+0.210597 0.329568 0.469735 0.788590 1.215495 1.319810 1.711456 2.058991 2.245438 2.653727
+0.197937 0.254148 0.477985 1.227090 1.629920 1.767432 2.186975 2.385104 2.594869 2.725544
+0.205489 0.333855 0.523915 0.706275 1.102152 1.246608 1.648901 2.026835 2.281695 2.759313
+0.230328 0.322431 0.861834 1.145614 1.347211 1.576111 1.807275 2.004824 2.354365 2.572251
+0.224898 0.282022 0.506636 1.152298 1.626560 1.752095 2.028178 2.218821 2.488955 2.670460
+0.313732 0.625469 1.164472 1.499077 1.749612 2.018528 2.262230 2.429601 2.692165 2.822502
+0.375623 0.575307 0.791200 0.935770 1.096937 1.343393 1.807992 2.187306 2.519720 2.694803
+0.236981 0.332412 0.479270 0.844461 1.347641 1.490733 1.683942 2.039143 2.297619 2.458431
+0.129047 0.206250 0.636751 0.865101 1.136893 1.356610 1.704798 1.916685 2.518358 2.756320
+0.195171 0.266517 0.414793 1.239561 1.452906 1.608357 1.833045 2.047802 2.473522 2.621994
+0.165853 0.212720 0.372757 0.536136 1.013938 1.339627 1.555122 1.945745 2.236281 2.440949
+0.256981 0.368868 0.635878 0.802543 1.084757 1.439120 1.814729 2.120519 2.458154 2.621456
+0.214382 0.297135 0.445091 0.702050 1.365102 1.851262 2.067026 2.207298 2.470728 2.612432
+0.340710 0.532103 0.935278 1.171022 1.377886 1.638598 1.965274 2.246164 2.631266 2.806341
+0.310524 0.412051 0.582478 0.768755 0.871594 1.119854 1.926346 2.207508 2.407091 2.636633
+0.249349 0.443517 0.631532 0.810096 1.205129 1.357206 1.607396 1.984157 2.208016 2.645111
+0.143090 0.185312 0.325214 0.504000 1.134467 1.327913 1.673654 2.006903 2.389284 2.746094
+0.226575 0.298946 0.453938 0.998061 1.394600 1.597283 2.064183 2.223246 2.425469 2.569458
+0.183924 0.255181 0.415834 0.624247 1.042338 1.203077 1.555240 2.125309 2.400352 2.661916
+0.275610 0.365968 0.654909 0.990108 1.170799 1.455333 2.077561 2.252672 2.502315 2.685945
+0.204334 0.287844 0.394810 0.761295 1.501200 1.784709 1.935569 2.152830 2.349263 2.545639
+0.342976 0.527539 0.917466 1.160585 1.499531 1.761830 2.095272 2.301872 2.540570 2.694692
+0.202374 0.333367 0.480179 0.708677 0.819505 1.105285 1.806641 1.953348 2.610844 2.797497
+0.307033 0.368471 0.602486 1.108611 1.413347 1.528636 1.798519 1.986138 2.169052 2.437256
+0.144073 0.196932 0.386988 0.819061 1.289767 1.625073 1.901924 2.136105 2.483019 2.707970
+0.176760 0.268627 0.662082 1.056866 1.547973 1.711386 1.972939 2.249909 2.544471 2.761094
+0.191409 0.292985 0.492193 0.800526 1.041836 1.278546 1.836626 2.028677 2.249387 2.627785
+0.324102 0.399146 0.687435 0.868704 1.022957 1.582084 1.853847 1.981885 2.554914 2.677057
+0.229172 0.302836 0.481418 0.704363 0.967567 1.828269 2.097295 2.258467 2.549112 2.704652
+0.467124 0.696788 0.939500 1.094987 1.277543 1.488496 1.896279 2.158470 2.474182 2.659994
+0.175418 0.234039 0.367674 0.513586 0.747619 1.008405 1.583161 2.053114 2.363292 2.681153
+0.410273 0.561949 0.736215 0.956685 1.135688 1.288424 1.750612 1.937714 2.151318 2.489336
+0.204541 0.277613 0.529607 0.722971 1.199975 1.447336 1.715634 1.921054 2.357781 2.507488
+0.253116 0.311907 0.696982 1.320082 1.575418 1.705324 2.005068 2.168666 2.461879 2.665053
+0.163657 0.237902 0.393374 0.609490 0.854272 1.089980 1.526387 1.842337 2.126252 2.679051
+0.448627 0.530664 0.812719 1.095201 1.207641 1.575411 1.884209 2.034297 2.553007 2.688355
+0.262717 0.338748 0.512685 1.003543 1.480178 1.622083 1.828518 2.142415 2.356457 2.511530
+0.417111 0.636688 1.036571 1.319877 1.679924 1.873389 2.073722 2.249396 2.507732 2.651054
+0.263698 0.461151 0.618737 0.830471 1.004041 1.158874 1.801566 2.020222 2.306558 2.743041
+0.387779 0.575108 0.729791 0.932981 1.361163 1.505161 1.751183 2.068466 2.338260 2.487637
+0.181510 0.265666 0.454631 1.082382 1.287303 1.579202 1.851178 2.096963 2.467237 2.646930
+0.277668 0.345119 0.602341 1.179200 1.378990 1.545625 1.813861 1.962590 2.491799 2.664453
+0.179320 0.248080 0.456925 0.722589 1.126932 1.579450 1.799397 1.950668 2.484125 2.707238
+0.314322 0.381145 0.608651 0.727613 0.890472 1.610280 2.136172 2.258358 2.596376 2.709780
+0.189539 0.266068 0.419729 0.651693 1.410161 1.643106 1.854810 2.275582 2.492054 2.722009
+0.254466 0.313038 0.594149 1.012536 1.688813 1.935465 2.119184 2.287869 2.535543 2.667926
+0.134691 0.171906 0.302740 0.492936 0.899551 1.229188 1.733940 2.012878 2.446339 2.742762
+0.231556 0.365068 0.680761 0.889142 1.111338 1.295904 1.542636 1.971784 2.427562 2.631912
+0.222525 0.305606 0.527193 0.687519 1.181381 1.671764 1.863683 2.072023 2.634517 2.779272
+0.178770 0.237415 0.375160 0.856692 1.673680 1.813743 2.016791 2.272421 2.522601 2.735959
+0.193532 0.268731 0.451328 0.753471 0.984854 1.285349 1.685647 1.884123 2.091677 2.243418
+0.476037 0.651610 0.801054 1.010162 1.241374 1.355840 1.775976 2.086152 2.272907 2.454351
+0.211657 0.308331 0.421366 0.865966 1.418774 1.556743 1.786149 2.020332 2.198585 2.631981
+0.203789 0.490794 1.010137 1.275006 1.472213 1.810140 2.170639 2.437660 2.662122 2.788061
+0.174355 0.252095 0.674715 0.842194 1.055087 1.278000 1.698680 2.070561 2.399385 2.657430
+0.245109 0.324049 0.628822 0.927910 1.123601 1.580066 1.878640 2.054601 2.358721 2.546838
+0.182644 0.253804 0.386248 0.614056 1.364821 1.545877 2.040174 2.218827 2.419010 2.624609
+0.295605 0.367794 0.690701 1.055162 1.186600 1.644453 1.944154 2.101444 2.562120 2.691268
+0.220878 0.289573 0.640307 0.822072 1.144055 1.567797 1.766410 1.908109 2.103459 2.560489
+0.403453 0.526298 0.732204 0.901150 1.035869 1.339383 1.783990 1.941961 2.371032 2.626653
+0.212825 0.258570 0.471588 0.685549 1.263740 1.821051 2.163822 2.288398 2.628063 2.788155
+0.401181 0.642053 1.032473 1.236110 1.444450 1.686678 2.006722 2.228515 2.572112 2.723964
+0.239433 0.341091 0.492629 0.707630 0.881426 1.030816 1.719255 2.344056 2.579063 2.756942
+0.294093 0.382770 0.577412 1.009281 1.313036 1.419303 1.744673 2.094230 2.289039 2.475843
+0.169805 0.236922 0.403314 0.638995 1.176446 1.352145 1.665573 1.909756 2.150120 2.716243
+0.210447 0.277913 0.452474 1.402686 1.513430 1.720944 1.903938 2.278499 2.583756 2.743179
+0.159574 0.225382 0.374008 0.714137 1.011253 1.371713 1.699162 1.871587 2.027056 2.491194
+0.258602 0.557253 0.819720 1.038856 1.301470 1.445358 1.830613 2.098171 2.320809 2.541075
+0.232756 0.282242 0.631974 0.898694 1.537444 1.869217 2.063967 2.234463 2.498226 2.633517
+0.580133 0.997946 1.320956 1.481874 1.731605 1.898579 2.120712 2.290128 2.530088 2.651657
+0.211840 0.307093 0.453360 0.945579 1.250815 1.490290 1.724135 2.281097 2.562699 2.752602
+0.314276 0.493555 0.667782 0.896500 1.323006 1.482618 1.667487 1.974415 2.427345 2.555679
+0.182455 0.261592 0.418011 1.050927 1.261387 1.443370 1.665467 1.939030 2.444695 2.638451
+0.241570 0.306934 0.491293 1.105950 1.554827 1.666520 1.923917 2.087652 2.367600 2.654889
+0.190084 0.254850 0.454062 0.724519 1.083362 1.393887 1.892335 2.088856 2.321764 2.484299
+0.306497 0.389831 0.721793 0.839714 1.124754 1.652401 1.822919 2.273310 2.569195 2.669599
+0.186200 0.273460 0.383201 0.564758 1.511073 1.845018 1.998284 2.194096 2.388693 2.587923
+0.300722 0.478218 0.823364 1.127490 1.591141 1.871349 2.174720 2.403181 2.624785 2.782405
+0.228884 0.358342 0.504622 0.795874 1.005622 1.152613 1.908053 2.124794 2.372473 2.797584
+0.171885 0.248234 0.432842 0.833143 1.040892 1.269289 1.661635 1.918629 2.158962 2.653403
+0.140943 0.193684 0.343025 0.562303 1.069552 1.543330 1.824473 1.961637 2.463513 2.770537
+0.173053 0.245656 0.360656 0.960618 1.589535 1.689906 1.984141 2.142998 2.588389 2.759403
+0.240180 0.429951 0.637440 0.786596 1.069147 1.226573 1.470883 1.952052 2.195064 2.615973
+0.367862 0.471897 0.730834 1.082320 1.226293 1.462927 1.928169 2.052466 2.406737 2.662458
+0.247175 0.358209 0.535946 0.781876 1.363697 1.635239 1.807233 1.993776 2.452769 2.601039
+0.445578 0.687898 1.114108 1.301027 1.577397 1.886042 2.224903 2.436534 2.659695 2.761031
+0.214389 0.336025 0.487794 0.759534 0.970518 1.141100 1.457335 1.624644 2.306922 2.715265
+0.377300 0.466775 0.716121 1.083781 1.256543 1.411238 1.789433 1.936372 2.205572 2.562355
+0.148362 0.214593 0.545023 0.840437 1.193325 1.480659 1.791868 2.083419 2.410537 2.676129
+0.150403 0.278398 0.792676 0.976680 1.218845 1.405245 1.775056 2.162458 2.547861 2.746383
+0.236301 0.328633 0.630867 0.839915 1.042349 1.298870 1.627752 1.839491 2.298928 2.493962
+0.337889 0.497920 0.711277 0.850420 0.992027 1.246884 1.710746 2.086682 2.527158 2.707162
+0.172215 0.236540 0.372897 0.525146 1.182577 1.735727 1.927035 2.114619 2.319170 2.542782
+0.415304 0.624807 0.906616 1.117841 1.446155 1.669417 1.948413 2.172815 2.504530 2.670754
+0.265417 0.407241 0.613894 0.816534 0.980063 1.156061 1.756747 2.274851 2.497193 2.712242
+0.276440 0.468209 0.649518 0.816686 1.195171 1.355517 1.549226 1.935272 2.217871 2.426979
+0.188925 0.277012 0.412665 0.672627 1.354807 1.514523 1.699988 2.144554 2.382186 2.586077
+0.242630 0.352485 0.912974 1.343781 1.604428 1.801867 2.014791 2.193072 2.460809 2.631999
+0.190903 0.285841 0.449070 0.760328 0.954285 1.182936 1.692638 1.878163 2.276840 2.465963
+0.220659 0.300374 0.721694 0.947306 1.298330 1.562980 1.760618 1.888247 2.506445 2.689675
+0.213168 0.290928 0.695227 0.918179 1.378186 1.631987 1.847886 2.003072 2.358358 2.619347
+0.328586 0.517244 0.937320 1.376238 1.574840 1.764347 2.058630 2.224334 2.584444 2.756653
+0.248486 0.367007 0.562147 0.750632 0.902785 1.147563 1.637415 1.912062 2.413993 2.605696
+0.310691 0.477895 0.670796 0.940507 1.418293 1.563497 1.805141 2.114076 2.376358 2.535155
+0.256555 0.414210 0.559427 0.981289 1.191646 1.378307 1.678398 1.849306 2.576704 2.756630
+0.291424 0.335003 0.750149 1.289655 1.437209 1.599989 1.803177 1.967415 2.601748 2.733761
+0.195254 0.279513 0.451755 0.649111 0.828694 1.609509 1.914906 2.091219 2.319589 2.534899
+0.222304 0.332624 0.475678 0.685205 1.030332 1.737223 1.920979 2.378290 2.706719 2.817726
+0.164833 0.240093 0.359862 0.801929 1.513677 1.641713 2.040524 2.248843 2.488659 2.714025
+0.214777 0.287322 0.572644 1.145070 1.367112 1.752687 2.042424 2.222067 2.543047 2.697885
+0.226099 0.330382 0.474439 0.687757 0.799187 1.319837 1.944566 2.078099 2.367800 2.508460
+0.244540 0.392163 0.553692 0.729765 1.247865 1.448376 1.617590 2.074636 2.340052 2.518064
+0.175381 0.314231 0.446023 0.797404 1.328458 1.439727 1.793346 1.939571 2.468800 2.721651
+0.205808 0.293670 0.452447 1.074268 1.288235 1.655635 1.857504 2.364687 2.639812 2.798144
+0.253926 0.392653 0.587584 0.800134 0.976310 1.185587 1.570687 1.821414 2.090893 2.349021
+0.322461 0.410912 0.723569 1.060644 1.201524 1.400360 1.579189 1.788759 2.460242 2.616602
+0.211266 0.304981 0.436011 0.771978 1.490623 1.677748 1.886227 2.113497 2.326353 2.727265
+0.235012 0.406911 0.864785 1.291485 1.708295 1.938554 2.179896 2.352404 2.563792 2.711446
+0.176814 0.268620 0.445837 0.823113 1.029776 1.271571 1.623388 1.811215 2.402140 2.614165
+0.241865 0.339268 0.507509 1.003677 1.204347 1.372561 1.940795 2.101371 2.385606 2.669975
+0.230878 0.334743 0.500370 0.879929 1.021894 1.533770 1.970789 2.128971 2.567262 2.717288
+0.297505 0.451574 0.748848 0.988527 1.366237 1.606668 1.894660 2.174481 2.521427 2.759168
+0.199265 0.271145 0.498160 0.854679 1.172103 1.364148 1.762079 1.969095 2.173538 2.311630
+0.222173 0.424864 0.564942 0.829809 1.038172 1.194055 1.720601 1.858086 2.431760 2.741461
+0.181961 0.226819 0.390513 0.556339 1.056596 1.553065 2.128349 2.258018 2.602497 2.802121
+0.357600 0.565047 1.153012 1.350312 1.533576 1.718542 1.957892 2.175347 2.505650 2.678495
+0.162257 0.236808 0.374039 0.570569 0.748034 1.172262 1.823392 2.053032 2.513769 2.772072
+0.305794 0.465870 0.645121 0.882650 1.141294 1.266856 1.701581 2.002881 2.184124 2.411254
+0.231652 0.380738 0.549642 0.837410 1.225266 1.332971 1.851582 2.119371 2.315077 2.732108
+0.235449 0.286771 0.684809 1.346663 1.526630 1.703476 2.101486 2.254546 2.577181 2.718994
+0.233870 0.446515 0.605080 0.814654 1.054963 1.178801 1.633158 1.849743 2.139379 2.732772
+0.271706 0.335152 0.857227 1.253741 1.387189 1.702170 1.896767 2.191114 2.479999 2.601359
+0.237386 0.314549 0.438339 0.912164 1.577764 1.877791 2.032790 2.197037 2.412322 2.536484
+0.361168 0.574093 1.023843 1.468517 1.690562 1.917374 2.187368 2.334035 2.669095 2.806291
+0.278480 0.398742 0.573342 0.839212 1.073888 1.222093 1.691681 2.165258 2.377410 2.536882
+0.286018 0.447947 0.615060 0.849446 1.319465 1.463583 1.769948 2.001035 2.189431 2.450384
+0.219440 0.301601 0.668534 0.861094 1.210001 1.498673 1.745120 1.877765 2.314377 2.619597
+0.223591 0.352153 0.598841 1.217893 1.359082 1.591744 1.771089 2.213856 2.561538 2.735416
+0.176857 0.236601 0.395107 0.634632 1.133495 1.335116 1.770374 1.981313 2.206556 2.339716
+0.334735 0.402265 0.659168 0.781639 0.975228 1.664999 1.872069 2.047533 2.476961 2.573979
+0.215968 0.284755 0.524241 0.781460 1.334811 1.772379 1.953878 2.194209 2.578250 2.741939
+0.298193 0.489879 0.812985 1.183691 1.496418 1.679975 2.108792 2.316557 2.673779 2.851610
+0.312989 0.415446 0.618011 0.899096 1.083683 1.263384 1.887396 2.243064 2.419448 2.570481
+0.244471 0.431115 0.601512 0.813139 1.102163 1.221061 1.692440 2.033163 2.221795 2.619838
+0.150949 0.219060 0.349217 0.611327 1.077112 1.250547 1.915518 2.083980 2.449999 2.792543
+0.161611 0.218964 0.445377 0.927863 1.451151 1.768464 2.130012 2.366724 2.666003 2.814049
+0.196000 0.297256 0.497266 0.691900 1.089877 1.273685 1.513723 2.006472 2.273782 2.572221
+0.335268 0.460795 0.685187 0.867664 1.013807 1.479554 2.011994 2.168476 2.572643 2.717564
+0.257604 0.340872 0.499757 0.843052 1.396548 1.831688 2.034226 2.170332 2.422618 2.540496
+0.417663 0.631718 0.955424 1.197319 1.659797 1.879883 2.168797 2.359053 2.578087 2.698249
+0.162052 0.251583 0.439900 0.660911 0.903902 1.320296 1.624758 1.778577 2.530531 2.799705
+0.256861 0.322803 0.685370 1.086437 1.263276 1.569879 1.851654 2.014946 2.264711 2.447006
+0.125192 0.176171 0.336135 0.781600 1.200220 1.439966 1.805419 2.077525 2.462470 2.738186
+0.102286 0.191322 0.774556 1.076151 1.369456 1.627146 1.973015 2.236001 2.609367 2.812985
+0.173442 0.232622 0.491622 0.844157 1.095241 1.370797 1.696966 2.051411 2.316061 2.502053
+0.257531 0.343598 0.654071 0.838985 1.048102 1.487473 1.725385 1.897417 2.430505 2.585998
+0.197900 0.276312 0.440283 0.705103 1.267341 1.740297 1.934483 2.154007 2.400200 2.624136
+0.409590 0.596785 0.983751 1.181770 1.371153 1.502380 1.758280 2.018571 2.380053 2.592151
+0.231819 0.332890 0.483514 0.644585 0.816808 0.926308 1.403298 2.233007 2.467857 2.678461
+0.258610 0.340064 0.670485 0.908467 1.107611 1.456243 1.759580 1.932179 2.113118 2.310135
+0.184377 0.249203 0.410806 0.587907 1.302501 1.510319 1.724432 1.981890 2.282904 2.422125
+0.254110 0.313328 0.659859 1.265819 1.412949 1.665930 1.927154 2.101984 2.551446 2.673030
+0.161592 0.237480 0.376535 0.637094 0.823028 1.137613 1.696425 1.875770 2.403632 2.639617
+0.384501 0.466812 0.740791 0.938093 1.062352 1.509284 1.749143 1.917797 2.548157 2.671506
+0.333872 0.419367 0.638994 1.092624 1.520550 1.649447 1.866619 2.148941 2.346723 2.506140
+0.426216 0.686997 1.235881 1.428854 1.611591 1.792860 2.017593 2.233715 2.547773 2.696609
+0.262949 0.367509 0.530429 0.741867 0.872474 1.069602 1.745566 2.061187 2.283843 2.494178
+0.335782 0.547236 0.716211 0.919077 1.275686 1.408437 1.685118 1.967394 2.217639 2.446679
+0.227629 0.330991 0.486068 1.117571 1.304983 1.510130 1.757258 1.946972 2.625557 2.782597
+0.359850 0.436633 0.750634 1.201513 1.337571 1.594835 1.970273 2.113840 2.573808 2.729963
+0.211871 0.304028 0.512758 0.663762 1.086354 1.633335 1.818017 2.129577 2.391080 2.600766
+0.196092 0.279726 0.434488 0.624802 0.772358 1.404377 1.948777 2.160918 2.629996 2.775175
+0.176304 0.262521 0.373719 0.581101 1.520108 1.736172 1.933230 2.140172 2.358130 2.753524
+0.254932 0.381411 0.806187 1.102292 1.534523 1.750280 1.970904 2.159871 2.455922 2.658405
+0.190385 0.288656 0.449066 0.678174 0.812376 1.449326 1.728657 1.966320 2.638812 2.789546
+0.251178 0.386509 0.609363 0.797102 1.024159 1.181726 1.454661 2.012630 2.493092 2.698933
+0.166654 0.266226 0.385171 0.711990 1.397897 1.532347 1.915974 2.088003 2.565270 2.789532
+0.238453 0.306036 0.449309 0.876277 1.521437 1.933982 2.134420 2.267986 2.537601 2.658253
+0.161634 0.219919 0.353206 0.524346 0.961806 1.207713 1.687918 1.916939 2.161870 2.320657
+0.413612 0.597095 0.793763 0.986290 1.281786 1.412660 1.652465 2.016091 2.384164 2.528578
+0.228655 0.341562 0.480989 0.988605 1.371003 1.477423 1.861026 2.015852 2.339752 2.773153
+0.259092 0.597012 0.985224 1.321740 1.643354 1.957367 2.288682 2.497474 2.716492 2.844467
+0.185652 0.304664 0.446232 0.864434 1.091795 1.273770 1.942575 2.095543 2.524648 2.768245
+0.176687 0.256678 0.745652 0.934909 1.283760 1.440062 1.765242 2.122092 2.388099 2.590551
+0.189805 0.275637 0.440995 0.821356 1.256020 1.410985 1.929781 2.120144 2.396030 2.604643
+0.266823 0.337688 0.819408 1.134754 1.289204 1.777028 1.982886 2.221748 2.590286 2.698098
+0.205348 0.276512 0.527305 0.727412 1.024647 1.653979 1.904178 2.046613 2.217922 2.455661
+0.293498 0.424494 0.613795 0.956130 1.133981 1.324804 1.809031 1.953922 2.293854 2.575884
+0.183120 0.249650 0.376204 0.543914 1.350827 1.907220 2.092551 2.255705 2.514391 2.687901
+0.541205 0.789796 1.058955 1.269415 1.503899 1.702191 1.970176 2.175444 2.496810 2.652238
+0.229326 0.339475 0.451881 0.661210 0.795832 1.073796 2.027104 2.206371 2.478903 2.726784
+0.330006 0.506868 0.673076 0.887406 1.228765 1.349226 1.781290 2.086583 2.277762 2.480029
+0.138389 0.200001 0.396259 0.811975 1.090712 1.460413 1.745493 1.904269 2.348250 2.699886
+0.176584 0.242161 0.378270 1.177848 1.564718 1.678166 1.951618 2.121413 2.580109 2.737132
+0.145852 0.198423 0.335644 0.550505 1.019727 1.371188 1.797635 1.943825 2.207490 2.746470
+0.385078 0.503696 0.703239 1.069987 1.365736 1.472054 1.825827 2.159636 2.371283 2.520972
+0.284950 0.388050 0.507352 0.879125 1.523530 1.776238 1.929597 2.157558 2.447986 2.586398
+0.491116 0.756155 1.255200 1.522460 1.776579 2.028121 2.286059 2.429774 2.679106 2.776164
+0.252477 0.396081 0.713022 0.861502 1.152223 1.370802 1.614010 2.144798 2.574072 2.712530
+0.282756 0.438437 0.613566 0.847746 1.260772 1.379059 1.642202 2.137540 2.368369 2.522163
+0.203971 0.322195 0.479842 0.953133 1.211278 1.397635 1.800812 1.954516 2.403478 2.573713
+0.264533 0.358424 0.628768 1.111242 1.340246 1.506485 1.999590 2.194109 2.461411 2.667361
+0.177730 0.223680 0.394553 0.556177 0.947415 1.500640 1.733528 1.926046 2.261466 2.436054
+0.314223 0.363636 0.727886 0.851880 1.053844 1.798132 1.974354 2.182595 2.537995 2.629683
+0.201778 0.275500 0.404891 0.747466 1.500050 1.841184 1.998843 2.226807 2.481989 2.669506
+0.132164 0.314955 0.821473 1.196038 1.426590 1.699934 2.036856 2.323497 2.685471 2.828965
+0.223374 0.347335 0.507730 0.773547 0.967916 1.134129 1.991403 2.306567 2.521364 2.788746
+0.312742 0.449784 0.583287 0.934234 1.268567 1.365063 1.569295 1.687046 2.077299 2.595022
+0.124286 0.162126 0.290730 0.654031 1.231658 1.538458 1.893070 2.184784 2.562637 2.798224
+0.177049 0.251654 0.367891 0.912504 1.557576 1.693045 1.898991 2.072136 2.350163 2.646045
+0.240517 0.378333 0.547809 0.754272 0.973321 1.103670 1.574418 2.028049 2.211127 2.562709
+0.427795 0.519003 0.771284 0.937240 1.086617 1.609879 1.878750 2.052791 2.534118 2.657149
+0.224370 0.317969 0.439666 0.812931 1.398497 1.626632 1.794178 2.114000 2.309157 2.496836
diff --git a/codec2/branches/0.7/src/codebook/lspjvm2.txt b/codec2/branches/0.7/src/codebook/lspjvm2.txt
new file mode 100644 (file)
index 0000000..2b7cabf
--- /dev/null
@@ -0,0 +1,513 @@
+5 512
+0.005167 -0.037310 -0.002159 0.016849 0.130396
+0.039445 0.031680 -0.074412 -0.031499 0.060536
+0.019479 -0.030564 -0.048137 -0.056279 -0.027829
+0.020585 -0.011270 0.023913 -0.005706 0.011407
+-0.023217 0.107455 -0.037777 0.004070 -0.017279
+-0.090444 0.007641 0.099001 -0.047913 -0.017199
+0.022700 -0.063865 0.047213 0.043843 -0.036225
+0.001312 -0.123861 -0.038988 0.058666 0.074541
+0.039508 0.110300 0.013954 -0.119228 -0.035807
+-0.047392 0.027035 -0.004412 -0.032650 -0.037150
+0.002491 -0.045447 0.158260 0.022828 -0.030124
+-0.047856 0.088744 -0.009678 0.106688 0.087690
+-0.027941 0.044084 -0.028500 0.018736 -0.069969
+-0.035358 -0.051568 -0.030459 -0.017899 0.027632
+-0.018607 -0.123557 0.019228 0.057485 -0.028907
+0.019057 0.038151 -0.080220 0.034222 0.023081
+0.021312 0.041905 0.112903 0.024092 0.093974
+-0.116679 0.015344 -0.066059 -0.096437 0.004041
+-0.022464 -0.116260 0.047819 -0.003921 -0.073504
+0.001975 -0.025869 0.028200 0.122690 0.010627
+-0.035672 0.078963 -0.009686 0.000743 -0.147582
+0.016932 -0.020291 -0.096896 -0.237875 -0.029121
+0.017376 -0.040130 -0.053865 0.154060 -0.013215
+0.015215 -0.019023 -0.070604 0.032265 0.040340
+0.102365 -0.022746 0.019895 0.050570 0.008845
+-0.034134 0.044441 -0.049387 -0.140481 0.072570
+0.013023 -0.006079 0.037574 0.004937 -0.081501
+0.003696 0.049908 0.007355 0.000403 0.026006
+-0.008466 0.080680 0.061382 -0.108985 -0.088060
+-0.012275 -0.081061 0.020333 -0.079001 0.068724
+-0.014081 -0.042609 0.093365 0.044120 0.000303
+0.063391 0.096574 -0.105424 0.039041 0.010412
+-0.054031 -0.084948 0.080406 -0.035883 0.137428
+0.063037 0.050562 0.024690 -0.031394 0.130320
+-0.015501 -0.078884 -0.076886 -0.013864 -0.073587
+0.048778 0.003814 -0.031125 0.046897 0.028304
+0.048692 0.132795 0.065450 0.059487 -0.042396
+-0.176999 0.056943 -0.004135 -0.049378 -0.041083
+-0.039445 -0.016292 -0.004550 0.062010 -0.079613
+-0.054566 -0.008476 -0.016710 0.049202 0.025758
+-0.078723 0.092091 0.096536 -0.065079 0.021161
+0.076657 0.009203 -0.036866 -0.016559 0.012823
+0.008225 -0.003006 0.108033 0.043120 -0.060870
+-0.019346 0.022790 -0.001728 0.062304 -0.016965
+-0.001302 -0.014490 -0.041803 -0.034058 -0.197066
+-0.033655 -0.127217 -0.108681 -0.010571 -0.004705
+-0.015553 -0.086069 0.034109 -0.101379 0.002068
+-0.004003 -0.044637 -0.068617 0.052228 -0.047812
+-0.043307 0.035681 0.042207 -0.055946 0.055944
+-0.026792 -0.012601 -0.056710 -0.021094 0.105842
+-0.025598 -0.078858 -0.013487 0.030728 -0.031956
+0.031444 0.022763 0.025364 0.121366 0.070736
+-0.084556 0.098118 -0.024301 -0.058655 -0.043194
+-0.011752 -0.043781 0.091051 -0.071201 -0.020980
+0.082904 -0.031657 -0.088247 0.066709 -0.079182
+-0.012151 0.011796 -0.010589 0.100656 0.094539
+0.035967 0.025338 0.071826 0.009741 -0.040209
+0.006866 -0.015095 -0.168469 -0.056133 0.060145
+0.045830 -0.068969 0.034551 0.015842 -0.092809
+0.054699 0.138744 0.001726 0.006927 0.005167
+0.016978 0.046384 -0.060183 -0.040742 -0.072692
+-0.022489 -0.029728 -0.065018 -0.124741 0.044927
+-0.029057 -0.037154 0.031068 0.060086 0.009984
+0.009311 -0.006957 -0.105508 0.059637 -0.019564
+-0.068154 -0.066443 0.000799 0.028579 0.097063
+0.096936 0.030230 -0.034623 -0.088918 0.040334
+0.019439 -0.050707 -0.003294 -0.028505 -0.053599
+0.062460 -0.070688 -0.016465 -0.035680 0.017378
+0.009363 0.048761 0.043374 0.039587 -0.023232
+-0.067033 0.042663 0.054070 -0.042797 -0.089391
+-0.030497 -0.050249 0.059528 0.089089 -0.029633
+0.064125 -0.086614 -0.002005 0.080620 0.000502
+-0.003490 0.097336 0.099565 0.015648 0.006691
+0.077668 0.016572 0.035404 -0.046026 0.017237
+-0.048631 0.009314 0.141479 0.017079 0.043796
+-0.106474 0.145951 0.057740 0.011250 -0.059443
+0.027572 0.026650 0.008527 0.002949 -0.037680
+-0.077991 -0.090617 0.003420 -0.046010 0.007354
+0.019056 -0.128651 0.016464 0.004584 -0.030883
+-0.092069 0.038976 -0.081840 0.066695 -0.047340
+0.003513 0.040613 0.046815 -0.023406 0.062389
+0.021759 0.024928 -0.018922 -0.048006 0.063800
+-0.014416 -0.050333 0.042628 -0.114934 -0.101450
+0.062139 0.029295 -0.065908 0.111463 0.050781
+-0.022707 0.135414 0.003548 0.134535 -0.048259
+-0.092344 -0.027727 0.016343 -0.060786 -0.081502
+-0.005412 -0.026229 -0.143331 0.052404 -0.077298
+-0.035919 -0.041968 -0.106108 -0.004369 0.065028
+0.096370 -0.053299 0.043317 -0.049735 0.049815
+0.032324 0.051309 -0.009607 -0.205917 0.005023
+-0.054316 -0.022895 0.099327 -0.006927 -0.076574
+-0.111024 0.111026 0.038381 -0.060368 0.064238
+-0.034316 0.026846 0.025740 -0.076162 -0.163904
+0.055955 -0.056885 0.014831 -0.120715 0.090938
+0.035289 -0.036439 0.060012 0.080302 0.036215
+0.065250 0.083030 -0.058784 0.104826 -0.051805
+-0.011099 -0.006420 0.053042 0.024127 0.092534
+0.058569 -0.033442 0.025186 -0.018222 0.117744
+0.044345 -0.042456 -0.043767 -0.021378 -0.121965
+0.027371 0.052731 -0.020316 0.036912 0.115357
+0.031150 0.041547 0.059267 -0.039672 -0.086918
+-0.162369 0.024801 0.031725 0.083400 -0.034463
+0.000272 -0.008147 -0.002016 0.131953 -0.092911
+-0.091944 -0.062864 -0.005221 0.063647 -0.012658
+0.042685 0.067952 0.038644 -0.153221 0.096841
+0.108299 0.089446 -0.047164 0.004196 -0.043268
+-0.035456 0.050838 0.070444 0.084465 -0.079980
+-0.048916 0.057726 0.023894 0.027653 0.017775
+0.015461 -0.030287 -0.022245 0.052081 -0.150947
+-0.002682 -0.056774 -0.123366 -0.091754 0.006536
+0.006473 -0.143025 0.054690 -0.043189 0.032970
+0.027446 0.033127 -0.132722 -0.010417 -0.080097
+-0.018187 0.001858 0.111290 -0.090749 0.059434
+-0.068738 0.090679 -0.145070 -0.065277 0.063514
+-0.003982 -0.056382 -0.003673 0.015845 -0.073396
+0.043688 0.002836 0.069211 0.124852 -0.053313
+-0.040946 0.070440 -0.107024 -0.019199 -0.033672
+-0.001440 0.021680 0.110595 -0.053452 -0.052426
+0.035461 -0.028179 -0.049041 0.022580 -0.010989
+-0.002913 -0.051691 -0.075881 0.037241 0.076377
+0.034735 -0.031556 0.073516 -0.001427 0.016296
+-0.017537 0.003346 -0.099774 -0.067624 -0.044257
+-0.018202 0.030622 0.012773 0.046475 -0.121785
+-0.057265 0.116179 -0.079916 0.066396 0.050104
+-0.013177 0.057766 -0.047879 -0.109526 -0.146491
+0.032675 -0.049318 -0.057045 -0.080068 0.089621
+-0.046564 -0.029992 0.040828 0.029281 -0.037369
+-0.009731 -0.082145 -0.117622 0.117077 0.037369
+0.000820 -0.106634 -0.007967 0.000812 0.140637
+0.036530 0.062121 -0.065504 -0.094930 0.121336
+0.017530 -0.017330 -0.040402 -0.018255 0.010992
+0.019746 -0.027564 0.033588 0.042466 -0.003143
+0.013767 0.084179 0.033753 -0.017279 -0.009676
+-0.006452 0.032645 0.031852 -0.030975 -0.043384
+-0.005433 -0.015258 0.053273 0.054748 -0.064736
+0.008959 -0.141223 -0.032957 -0.015079 0.018198
+-0.001681 0.143079 0.076000 0.001037 -0.048744
+0.022062 0.026030 -0.008263 -0.050353 -0.023037
+-0.036477 -0.051733 0.137823 -0.034438 -0.007573
+-0.004256 0.064218 0.075183 0.095106 0.026497
+0.026360 0.009791 -0.058039 0.053315 -0.077817
+-0.033283 -0.081151 -0.055220 0.004268 0.017539
+-0.007329 -0.117200 0.093220 0.037359 0.002718
+0.010749 0.018281 -0.075800 -0.024889 0.005720
+0.022129 0.035613 0.036187 0.032246 0.105439
+-0.073766 0.016887 -0.059934 -0.049471 0.073520
+-0.024041 -0.104642 0.023557 -0.059746 -0.043871
+0.022311 -0.000250 -0.074027 0.198593 0.102732
+0.024478 0.077658 -0.060042 -0.018229 -0.149648
+-0.009871 -0.105822 0.007585 -0.161459 -0.041121
+-0.021460 0.009020 -0.065018 0.111801 -0.024953
+0.074594 -0.026041 -0.062859 0.009199 0.069609
+0.078672 -0.033414 0.054128 0.005408 -0.016273
+0.052076 0.107610 -0.067518 -0.096400 0.033703
+-0.014350 -0.024676 0.056254 -0.043770 -0.060847
+-0.004185 0.073550 -0.057830 -0.016644 0.029096
+0.005755 0.026472 0.040449 -0.091950 -0.048538
+-0.034439 -0.107938 0.090712 -0.117001 0.043170
+-0.006505 -0.035277 0.117316 0.127002 0.047906
+-0.001441 0.118379 -0.132165 0.007380 0.023823
+-0.020120 -0.083725 0.047284 0.023795 0.074123
+-0.013439 0.024994 0.060254 -0.069120 0.166373
+-0.024228 -0.063150 -0.046506 -0.077202 -0.054592
+-0.006571 0.010335 -0.006568 0.003982 0.075837
+0.008643 0.136339 -0.005502 0.033910 -0.066379
+-0.127371 -0.006954 0.039770 -0.070123 0.060925
+-0.046386 -0.026420 -0.005280 0.103509 -0.022310
+-0.003740 -0.014999 -0.037770 0.080005 0.025231
+-0.054995 0.071017 0.009442 -0.075737 0.013441
+0.051947 0.027097 -0.070351 -0.055705 -0.021115
+0.021387 0.029232 0.163331 -0.032380 0.010008
+-0.011987 -0.028631 0.002665 0.014770 -0.009558
+-0.034325 0.015830 -0.091253 -0.012677 -0.107378
+-0.034624 -0.047725 -0.102330 0.042525 -0.006869
+0.014048 -0.043127 0.052384 -0.047473 0.055102
+0.009744 -0.033646 -0.081755 -0.001464 -0.016223
+-0.036697 -0.002279 0.023279 -0.036221 0.101478
+-0.058454 0.065074 0.003524 0.005010 0.097182
+-0.038171 -0.037943 -0.009994 -0.033355 -0.044552
+0.041318 0.065041 0.000092 0.100816 0.029007
+-0.031803 0.183537 -0.009617 -0.010544 -0.028465
+0.006900 -0.014988 0.090490 -0.174817 0.027464
+0.063314 -0.049281 -0.001567 0.091421 -0.078603
+-0.004869 -0.063266 -0.001922 0.069338 0.081771
+0.058737 0.073195 0.081676 -0.047808 -0.025797
+-0.004185 0.033203 -0.125472 -0.108148 0.031258
+0.035192 0.029957 0.046675 0.047238 -0.088197
+0.033315 0.114919 -0.049180 0.025707 0.053843
+0.035182 0.140206 -0.058660 -0.025978 -0.019658
+-0.014847 -0.021051 -0.034385 -0.121789 0.173406
+-0.112251 -0.022333 0.071206 0.028998 0.046468
+0.067704 -0.026159 -0.158316 0.014936 0.040216
+-0.010137 -0.053492 0.004935 -0.011277 0.073852
+0.091261 0.114794 -0.014060 -0.051545 0.077316
+0.101258 -0.046137 0.022994 -0.066767 -0.065537
+0.049952 -0.043582 0.012823 0.009313 0.036343
+0.054885 0.037796 0.021940 0.013211 0.006019
+-0.099578 0.058596 -0.045463 -0.015632 -0.087141
+-0.019273 -0.033140 0.043796 0.119057 -0.081813
+-0.021538 -0.070453 -0.052551 0.077213 0.000094
+0.050268 0.092271 0.051688 -0.025224 0.075437
+0.027983 0.069205 0.031787 -0.099975 0.004387
+-0.002747 -0.056567 0.161394 0.000164 0.084189
+-0.124844 0.050329 0.009844 0.055877 0.055701
+0.030479 0.028843 -0.001076 -0.017173 -0.102770
+-0.038426 -0.133841 -0.035840 -0.072046 0.020206
+0.016438 -0.097885 0.041857 0.034601 0.030422
+-0.089192 -0.014112 -0.052276 0.012005 -0.029335
+-0.011331 0.101833 0.063827 0.044288 0.101597
+-0.034689 -0.027434 -0.017801 -0.079224 0.067103
+-0.027456 -0.098034 0.009448 -0.038986 -0.156729
+0.085023 0.033136 -0.021343 0.110701 -0.011901
+-0.006484 0.082023 -0.027094 0.091208 -0.013163
+-0.012223 0.005933 0.010653 -0.098119 -0.005304
+-0.021061 -0.058077 -0.073035 0.097856 -0.102847
+-0.035329 -0.092754 -0.101463 -0.048671 0.055015
+0.102145 0.062017 0.016002 0.036489 0.059000
+0.042861 0.025447 -0.019735 -0.107841 -0.033752
+-0.043982 -0.067059 0.051092 0.025235 -0.147107
+-0.016269 0.123009 0.035894 -0.020453 0.040013
+0.015557 0.015825 0.080712 -0.069630 -0.149739
+0.022006 -0.008848 0.040169 -0.095688 0.059575
+-0.030641 -0.061353 0.046302 0.104489 0.043372
+-0.001579 0.059737 -0.104073 0.042342 -0.048611
+-0.013811 -0.056255 0.107179 0.057433 0.084815
+0.030217 0.022360 -0.040342 -0.028775 0.120588
+0.041270 -0.045775 -0.030195 -0.106859 -0.104349
+0.072418 -0.003603 -0.013072 0.040728 0.086869
+0.091943 0.066517 0.024442 -0.030929 -0.032920
+-0.160336 -0.010347 -0.068458 0.017458 0.044823
+0.050694 0.067625 0.040303 0.113164 -0.038747
+-0.065558 -0.106357 -0.028352 0.121488 0.026548
+-0.007820 0.054872 0.094674 -0.099533 0.005231
+0.118132 0.042780 -0.065079 0.031440 0.043229
+-0.050024 0.015943 0.073917 0.034049 0.010548
+-0.024979 0.022639 0.027795 0.049491 0.048762
+-0.002738 -0.010783 -0.027637 -0.006986 -0.104141
+-0.066719 -0.061742 -0.067028 -0.053057 -0.003478
+-0.050948 -0.122196 0.022082 0.002595 0.015094
+0.006014 0.005784 -0.184537 -0.034872 -0.036104
+0.055412 0.006886 0.103488 -0.063001 0.096665
+-0.035533 0.009847 -0.095114 0.008588 0.023736
+-0.034278 -0.111970 -0.041172 0.039730 -0.102952
+0.063775 0.039273 0.109863 0.091800 0.030306
+-0.082206 0.089449 -0.058478 -0.029341 0.038389
+0.061057 -0.024711 0.111044 -0.035079 -0.027985
+0.014570 0.002046 -0.031545 0.058848 -0.019500
+-0.002475 -0.025589 -0.144358 0.063478 0.124927
+-0.014094 -0.010970 0.031621 -0.040043 0.004389
+0.025003 0.052397 -0.054526 -0.073469 0.026795
+-0.024697 0.024739 0.118299 0.014948 -0.132109
+0.020192 0.037815 -0.090270 0.049313 0.082764
+-0.022642 -0.006053 -0.038073 -0.057363 -0.107347
+0.033166 -0.027556 -0.019765 -0.111958 0.027773
+-0.063001 -0.052998 0.019353 -0.009646 -0.011270
+0.011872 -0.006508 -0.122226 0.059824 0.041779
+0.016445 -0.031890 -0.036310 0.013085 0.091631
+0.062866 0.054501 -0.117523 -0.010907 0.087026
+-0.014974 -0.035920 -0.048565 -0.019246 -0.043405
+-0.006959 0.006211 0.042370 0.014603 -0.006435
+0.019149 0.078038 -0.020556 0.018114 -0.036521
+-0.054036 0.007325 0.056349 -0.033497 -0.025960
+0.050184 -0.066536 0.091501 0.071356 -0.049044
+-0.032263 -0.095268 -0.008784 0.049033 0.036929
+0.020357 0.152151 0.040814 -0.063159 -0.024324
+-0.017084 0.011876 -0.015442 -0.019811 -0.000366
+-0.002700 -0.072981 0.109288 0.007473 -0.049442
+-0.054040 0.051947 0.019359 0.129160 0.021981
+0.002248 0.035262 -0.023141 0.064666 -0.078273
+-0.031663 -0.031343 -0.006058 -0.045421 0.017466
+-0.067122 -0.130784 0.067057 0.052460 -0.041165
+-0.004411 0.046453 -0.055461 0.048162 -0.009687
+0.021530 0.007211 0.104764 0.079849 0.086248
+-0.072791 0.001112 -0.027964 -0.071233 -0.013339
+0.007979 -0.118231 0.076826 -0.060762 -0.084358
+-0.011447 0.009765 0.014163 0.164784 -0.015892
+-0.020756 0.152509 -0.014014 -0.041853 -0.117008
+-0.011755 -0.005766 -0.086896 -0.139650 -0.032342
+0.025651 -0.007843 -0.039073 0.103397 -0.042591
+-0.005971 -0.001324 -0.053945 -0.000716 0.048977
+0.130185 0.028226 0.061179 0.024489 -0.021939
+-0.007019 0.054336 -0.010040 -0.095411 0.082406
+-0.032130 -0.015054 0.033059 0.002802 -0.080159
+-0.022452 0.077426 -0.015314 0.033583 0.028479
+0.023293 0.035078 0.006442 -0.110541 -0.106244
+-0.034737 -0.104140 -0.034570 -0.114316 0.079382
+0.006009 0.003901 0.080081 0.055082 0.012896
+0.064981 0.057219 -0.112986 0.003906 -0.028414
+-0.012383 -0.054541 0.077483 0.004267 0.123567
+0.007369 0.099856 0.023273 -0.028194 0.122030
+-0.036635 -0.126589 -0.034567 -0.028288 -0.065040
+0.014280 0.011435 -0.004867 0.043901 0.035395
+0.028599 0.075858 0.118460 0.070581 -0.051903
+-0.170905 0.050352 0.053514 -0.017139 0.021748
+-0.096610 0.008904 -0.001049 0.078787 -0.101201
+-0.026229 -0.019757 -0.035771 0.054142 0.068041
+-0.020328 0.099979 0.096623 -0.046957 -0.001733
+0.049586 0.052458 -0.031724 -0.028332 -0.005418
+0.046710 0.014238 0.133125 -0.005428 -0.080055
+-0.033226 0.034007 0.025272 0.033924 -0.044662
+-0.034690 -0.079173 -0.160689 -0.153893 -0.228771
+-0.002450 -0.083966 -0.168294 0.010694 -0.012167
+0.000004 -0.044377 0.023373 -0.077437 0.012178
+-0.015899 -0.010828 -0.062847 0.029927 -0.074557
+-0.053306 0.049688 0.057017 -0.022571 0.015337
+-0.046545 0.018895 -0.024848 -0.004424 0.165442
+-0.060201 -0.098629 -0.065190 0.036582 -0.038566
+0.051453 0.093478 0.039619 0.117535 0.090386
+-0.029366 0.108075 -0.016568 -0.093576 -0.048799
+-0.045599 -0.023619 0.070072 -0.109294 0.001548
+0.076285 -0.091274 -0.068829 0.000215 -0.046519
+-0.022512 -0.027067 0.014905 0.079017 0.140699
+0.061141 0.009178 0.097811 0.033468 -0.006666
+0.007163 -0.007578 -0.124238 -0.025271 0.017581
+0.042405 -0.034252 0.064890 0.002500 -0.139083
+0.009733 0.158179 0.014474 0.038913 0.056290
+-0.004998 0.075401 -0.030557 -0.038595 -0.049070
+-0.014680 -0.076306 -0.132365 -0.177693 0.091760
+-0.057238 -0.072379 0.050877 0.051489 0.028125
+0.004991 0.032621 -0.167359 0.041002 -0.007072
+-0.086405 -0.042263 -0.019757 -0.011524 0.066004
+0.085670 0.008071 -0.013614 -0.062142 0.083280
+0.000887 -0.075820 0.008295 -0.020136 -0.016886
+0.089657 -0.106260 -0.051491 -0.012687 0.054778
+0.011535 0.086613 0.053803 0.027164 -0.023825
+-0.040009 0.080987 0.026309 -0.000334 -0.085288
+-0.024208 -0.085040 0.096077 0.120527 -0.044181
+0.003034 -0.091142 0.006471 0.115971 -0.026358
+0.003489 0.083633 0.109975 -0.029425 0.061726
+0.056115 -0.006711 0.013158 -0.062917 -0.015029
+0.003354 0.031574 0.119045 0.022859 0.023777
+-0.068292 0.115604 0.031617 0.008953 0.006943
+0.014420 0.008569 -0.031547 -0.006857 -0.051690
+-0.086683 -0.108339 0.005093 -0.108646 -0.034720
+0.054273 -0.096753 0.050806 -0.021115 -0.025278
+-0.079997 0.027008 -0.034211 0.090949 0.005678
+0.019288 0.042083 0.062119 0.019301 0.040859
+-0.009113 0.022427 -0.004019 -0.060890 0.032884
+-0.012373 -0.037976 0.017625 -0.079369 -0.050788
+0.079720 -0.039347 -0.085324 0.091044 0.026653
+-0.063122 0.099371 -0.024736 0.084631 -0.100421
+-0.073313 0.014317 0.022555 -0.116051 -0.063966
+-0.009688 -0.063666 -0.131709 0.016744 -0.135028
+-0.003708 -0.043685 -0.121631 -0.036930 0.125776
+0.084333 0.010114 0.071231 -0.010395 0.059391
+0.017760 0.033034 -0.018996 -0.130540 0.025758
+-0.018261 -0.060044 0.127025 -0.032724 -0.107299
+-0.064538 0.090073 -0.010186 -0.066127 0.107025
+-0.010940 0.003083 0.019030 -0.023935 -0.140176
+0.003549 -0.042402 -0.010695 -0.185915 0.060835
+0.005405 -0.013822 0.029205 0.079338 0.068155
+0.071485 0.030282 -0.087207 0.073480 -0.027940
+0.004896 -0.033246 0.072637 0.018017 0.054712
+0.026184 -0.005287 0.034456 -0.036753 0.079232
+0.072707 0.004506 -0.039353 -0.015560 -0.071466
+0.010257 0.067446 -0.006598 0.047396 0.072218
+0.023405 0.082663 0.015319 -0.035436 -0.075461
+-0.124036 -0.032046 0.060837 0.010231 -0.053024
+0.022800 0.042891 -0.041549 0.132395 -0.095330
+-0.077091 -0.058554 -0.070632 0.047570 0.031856
+0.000127 0.114996 0.058660 -0.092472 0.064503
+0.096450 0.066200 -0.001059 0.039487 -0.032859
+-0.065721 0.001601 0.088037 0.059828 -0.047411
+-0.077714 0.010275 0.013629 0.003304 0.005407
+0.000665 0.012927 -0.077525 0.069202 -0.157417
+0.014547 -0.095965 -0.087546 -0.067375 -0.027867
+0.005458 -0.095839 0.105294 -0.044892 0.045151
+-0.001349 0.038356 -0.127152 -0.080503 -0.105423
+-0.018484 0.008439 0.104398 -0.027959 0.082086
+-0.020605 0.042785 -0.109139 -0.025958 0.079733
+0.036289 -0.083773 -0.033819 0.032566 -0.065556
+0.006659 0.002090 0.097027 0.115715 -0.013271
+-0.067514 0.128365 -0.089129 0.026160 -0.040584
+-0.002443 -0.017254 0.129204 -0.110078 -0.064943
+0.089215 -0.022299 -0.034959 0.022446 -0.019254
+-0.038900 -0.069862 -0.070540 0.069949 0.111993
+-0.006311 -0.009057 0.094278 -0.014932 0.003657
+-0.019323 0.026145 -0.062611 -0.073753 -0.007182
+0.014101 0.015776 0.052537 0.064728 -0.160187
+-0.005122 0.076356 -0.104763 0.091493 0.020225
+-0.000433 0.062698 -0.060457 -0.147540 -0.066168
+0.007195 -0.061498 -0.037801 -0.039763 0.059551
+-0.028410 -0.074510 0.057667 0.020584 -0.042510
+-0.025311 -0.037825 -0.188010 0.077423 0.030749
+-0.025465 -0.067541 0.003073 -0.049778 0.127789
+0.002786 0.120009 -0.067812 -0.026565 0.111272
+0.023219 -0.024403 -0.014507 -0.048624 0.022163
+0.014596 -0.052136 0.001580 0.064595 0.017963
+0.021330 0.098862 -0.009253 -0.041062 0.008903
+-0.013829 0.031967 0.076571 -0.005348 -0.044010
+0.031252 0.000369 0.036818 0.072854 -0.038569
+0.004161 -0.128017 -0.053152 0.050896 -0.015212
+-0.036159 0.097995 0.068397 -0.048472 -0.056131
+-0.011920 0.059188 0.010215 -0.061152 -0.011717
+-0.035949 -0.057039 0.090859 -0.029682 0.041466
+-0.025106 0.131191 0.059327 0.085383 0.021699
+0.049230 0.036630 -0.077086 0.017806 -0.088790
+0.004040 -0.069533 -0.026785 0.009666 0.014017
+-0.055897 -0.096299 0.120693 0.029995 0.032602
+-0.001365 0.034015 -0.053512 0.001573 -0.019170
+0.003956 0.006452 0.067313 0.028301 0.160615
+-0.053111 0.013990 -0.027060 -0.013638 0.039376
+-0.054462 -0.096553 0.079994 -0.043791 -0.025051
+-0.003222 0.019418 -0.049525 0.151136 0.034123
+0.055117 0.058918 -0.017393 0.026169 -0.126380
+-0.019008 -0.028939 -0.014027 -0.173373 -0.032841
+-0.003370 0.039680 -0.118311 0.114094 -0.041869
+0.041121 -0.038391 -0.096074 -0.032479 0.060222
+0.063968 -0.024528 0.018158 -0.009892 -0.043882
+-0.005004 0.129800 -0.025438 -0.121186 0.049860
+0.010448 -0.040388 0.061853 -0.017304 -0.035088
+-0.008678 0.061476 -0.039493 -0.005055 0.079169
+0.046134 0.009770 0.068294 -0.078965 -0.043792
+-0.030529 -0.053845 0.053853 -0.140682 0.111461
+0.003549 -0.014939 0.148955 0.072861 0.004332
+0.015386 0.062006 -0.122325 -0.032529 0.010241
+-0.047982 -0.126440 0.055840 0.067128 0.101189
+-0.002630 0.031969 0.046076 -0.080194 0.104740
+-0.033486 -0.077818 -0.058697 -0.095258 -0.111074
+0.037236 0.011711 0.001113 -0.005664 0.048588
+0.041131 0.098257 0.033126 0.029317 -0.095311
+-0.071555 -0.039999 0.026678 -0.072182 0.035031
+-0.007997 -0.048174 -0.006796 0.075959 -0.052060
+-0.007645 0.037076 -0.035574 0.085576 0.034126
+-0.050676 0.051430 0.031999 -0.134308 -0.001489
+0.084564 -0.018394 -0.097410 -0.042931 -0.025608
+-0.025489 0.041919 0.142482 0.004617 -0.041085
+-0.028816 -0.015527 -0.031005 0.028405 -0.022240
+-0.067737 -0.025241 -0.052578 0.012322 -0.120556
+0.016278 -0.081744 -0.099160 0.025144 0.025441
+0.003176 -0.073871 0.031718 -0.028622 0.029031
+0.017910 -0.030693 -0.104215 -0.015422 -0.065738
+-0.048346 -0.012847 0.046849 -0.008621 0.058771
+-0.054495 0.031597 -0.038844 0.043138 0.092588
+-0.071371 -0.059093 -0.001197 0.001766 -0.074762
+0.029470 0.089616 0.005009 0.052977 0.015899
+-0.045424 0.158466 -0.038717 -0.032506 0.028687
+0.011435 -0.006772 0.047605 -0.144659 -0.031229
+0.073577 0.011530 -0.008172 0.058883 -0.088412
+0.033615 -0.034120 -0.030701 0.101215 0.096645
+0.027368 0.041249 0.081502 -0.025440 0.007592
+0.059893 0.012106 -0.112009 -0.114692 0.016397
+0.087068 0.016199 0.051263 0.011915 -0.085364
+0.026046 0.145258 -0.047521 0.077134 -0.000345
+0.034532 0.099801 -0.087591 -0.059719 -0.058671
+0.022737 -0.001887 -0.107049 -0.116757 0.134115
+-0.055403 0.005157 0.067618 0.081074 0.071787
+0.063802 -0.003430 -0.106491 0.017543 0.002214
+-0.013785 -0.032962 0.010084 0.024325 0.045963
+0.059883 0.072282 -0.008608 -0.015127 0.048225
+0.041752 -0.068845 0.012227 -0.090748 -0.035309
+0.045353 -0.078624 -0.019489 0.035531 0.058571
+0.045414 0.039032 -0.011106 0.048787 -0.025336
+-0.084893 0.031896 0.010850 0.012526 -0.053205
+0.016952 -0.044041 0.068766 0.097328 -0.122229
+0.027016 -0.051759 -0.057246 0.074566 0.006201
+0.069904 0.100068 0.076124 0.004278 0.029466
+0.045229 0.055683 0.018790 -0.067806 0.039373
+0.029179 -0.036787 0.129921 -0.028993 0.037711
+-0.105011 0.138747 -0.004370 0.052080 0.050835
+0.025511 -0.002962 0.007852 -0.055234 -0.075055
+0.000460 -0.089231 -0.030467 -0.080347 0.007488
+0.067460 -0.076368 0.084991 0.039544 0.033391
+-0.044318 0.006390 -0.079387 -0.002909 -0.029708
+-0.047882 0.063040 0.065719 0.021811 0.070945
+-0.007571 -0.001302 -0.064119 -0.068005 0.051040
+-0.017747 -0.063938 0.018673 -0.038391 -0.099966
+0.057475 -0.007669 0.009384 0.109283 0.012248
+-0.048858 0.092498 0.011967 0.061525 -0.028819
+-0.015131 -0.024160 -0.033220 -0.101648 -0.017980
+-0.003342 -0.049829 -0.125096 0.128241 -0.047377
+-0.028943 -0.109072 -0.066133 -0.015454 0.098334
+0.053371 0.011324 0.042781 0.044313 0.062510
+0.098408 0.065410 -0.040693 -0.116351 -0.032327
+-0.013634 -0.058591 0.081507 0.042019 -0.099770
+-0.018275 0.084624 -0.007512 -0.041113 0.054203
+0.017879 -0.029747 0.059865 -0.048281 -0.111513
+-0.022478 0.002059 0.022383 -0.125360 0.058216
+0.002386 -0.081600 0.049288 0.157428 0.057724
+0.005046 0.102125 -0.083473 0.044059 -0.094864
+0.039120 -0.063306 0.057341 0.060519 0.107383
+0.007076 -0.009373 -0.012555 -0.066630 0.117121
+0.025254 -0.008796 -0.062102 -0.083164 -0.079007
+0.084839 0.042308 -0.055353 0.036386 0.132641
+0.084464 0.056288 -0.011636 -0.059554 -0.087748
+-0.147377 -0.052414 -0.010203 -0.009159 -0.018829
+0.009621 0.061633 0.015716 0.086332 -0.061465
+-0.011833 -0.062998 -0.021168 0.125194 0.045025
+0.052316 0.025720 0.095155 -0.093252 0.028720
+0.056113 0.063321 -0.045315 0.025199 0.023591
+-0.070481 0.072350 0.092458 0.047973 -0.025439
+-0.001281 0.021028 0.034576 0.084779 0.006867
+-0.010323 -0.046330 -0.009172 0.030485 -0.117679
+-0.021782 -0.034737 -0.086292 -0.045885 0.009655
+-0.037167 -0.123331 0.017291 -0.028319 0.071447
+-0.057180 -0.032912 -0.139418 -0.025966 -0.039305
+0.009411 -0.054017 0.076307 -0.060252 0.110087
+-0.061366 0.038897 -0.098107 0.046119 0.043021
+-0.029130 -0.096885 0.007623 0.090513 -0.097416
+0.053264 0.058296 0.054372 0.060769 0.015586
+-0.067956 0.059996 -0.037850 0.005986 0.000778
+0.045873 -0.065546 0.077900 -0.085638 0.000698
+0.027694 -0.021241 -0.002777 0.034509 -0.048173
+0.009988 0.001008 -0.077434 0.026002 0.139490
+0.008910 0.007791 0.059292 -0.057047 0.014127
+-0.022959 0.085710 -0.068087 -0.081561 0.005935
+0.007577 0.061544 0.076542 0.001660 -0.113279
+0.024973 0.086750 -0.061674 0.095059 0.089352
+-0.024436 0.024181 -0.016117 -0.073634 -0.067986
+0.074701 -0.046868 -0.054634 -0.092485 0.006662
+-0.033256 -0.053774 0.049001 -0.002339 0.013545
+-0.006432 -0.012089 -0.086842 0.104105 0.061991
diff --git a/codec2/branches/0.7/src/codebook/lspjvm3.txt b/codec2/branches/0.7/src/codebook/lspjvm3.txt
new file mode 100644 (file)
index 0000000..72767df
--- /dev/null
@@ -0,0 +1,513 @@
+5 512
+0.007066 0.075781 -0.070082 -0.092014 -0.066477
+0.090510 0.106622 0.025911 -0.016760 0.003724
+-0.024628 0.058332 0.012876 0.059557 -0.002092
+-0.065092 -0.096975 -0.041837 -0.002432 0.058918
+0.014358 0.080049 -0.008803 -0.002091 -0.097584
+0.085323 -0.026053 -0.086585 -0.009541 0.130555
+0.045391 0.037557 0.074726 -0.050453 0.033517
+-0.035576 -0.084211 -0.086430 0.008910 -0.072674
+-0.098699 -0.024540 -0.048972 -0.066975 -0.048791
+0.032184 0.070992 -0.014416 0.141892 -0.044249
+-0.108921 -0.020450 0.115988 0.011287 -0.026273
+0.024341 0.138519 -0.036467 0.020684 0.074258
+-0.053563 0.077463 0.072166 0.032112 -0.079303
+-0.025039 0.079675 0.094211 -0.115754 0.038892
+0.050897 -0.024639 0.057826 -0.110429 0.071184
+0.015309 -0.034027 -0.055726 0.043179 -0.063089
+0.043359 -0.011698 0.006637 0.002751 0.030110
+-0.001261 0.111470 0.043277 -0.004205 -0.021599
+-0.005698 0.058842 0.168422 0.059313 -0.007971
+-0.087599 0.073891 -0.083238 0.099279 -0.017364
+-0.018429 0.014040 -0.014864 -0.111512 0.089450
+-0.028498 -0.087983 -0.077320 -0.062602 0.000328
+-0.027152 -0.093796 0.111381 -0.018603 0.092394
+-0.007256 0.025391 0.011454 0.012802 -0.041680
+0.008078 0.020905 -0.105401 -0.083265 0.027756
+-0.049630 -0.044085 -0.051424 0.104125 -0.000779
+-0.063079 -0.130699 0.070500 0.033468 -0.019802
+-0.061011 0.094839 -0.040122 0.118409 0.056950
+0.086391 -0.006615 0.045337 -0.044190 -0.106474
+-0.081912 0.067557 -0.031649 -0.014437 0.057585
+-0.121755 -0.049113 0.057109 -0.049872 0.044104
+0.064705 -0.091589 0.037286 -0.048606 -0.045398
+0.003456 0.057230 0.006262 -0.055206 -0.063871
+-0.005249 0.081783 0.134969 -0.002331 0.052643
+-0.093346 0.072093 0.116025 -0.031453 -0.006012
+-0.038574 -0.030841 0.010288 0.024420 0.051657
+-0.086584 0.046381 0.005410 0.052622 -0.072741
+0.079023 0.078099 -0.093912 0.005477 -0.006721
+0.100232 -0.017587 0.044819 0.036655 0.021580
+-0.006829 -0.050076 -0.003020 0.088246 0.013560
+-0.015690 0.012477 -0.052595 -0.048861 -0.033688
+0.055615 0.092298 -0.066194 0.016416 -0.066059
+0.046976 0.003023 0.104646 0.109136 0.018293
+-0.016507 -0.006859 0.004326 0.070843 0.140750
+0.025774 0.034730 -0.079590 0.050054 -0.107950
+0.002378 0.097498 0.027111 -0.122953 -0.002423
+-0.020539 -0.063263 -0.095493 -0.157361 -0.039183
+0.025721 0.026897 -0.001200 0.033997 -0.001749
+0.061593 -0.013053 -0.106317 -0.068190 0.046352
+-0.056060 0.157084 -0.049365 0.053959 -0.051065
+-0.047672 0.081570 0.064342 -0.030705 -0.070806
+-0.076503 -0.059471 0.012419 0.073968 -0.026179
+-0.038473 0.059013 -0.035783 -0.030057 -0.036346
+-0.052692 -0.015346 -0.022687 -0.035279 0.013314
+0.068397 -0.046609 -0.009593 -0.040796 0.157438
+-0.075360 -0.110464 0.031839 -0.029035 -0.015222
+0.041013 -0.099212 -0.108920 -0.008627 0.012095
+0.020855 0.009935 -0.086917 0.058827 -0.006536
+0.022104 -0.005013 0.003496 0.046663 -0.051061
+-0.036803 -0.067317 -0.007075 0.180870 -0.027434
+-0.025056 -0.039341 -0.073918 -0.003180 -0.110930
+-0.042711 0.005519 -0.035005 -0.088419 0.170942
+0.001503 -0.121485 0.066383 -0.067346 0.005643
+0.080088 -0.042562 -0.006668 -0.036538 0.020683
+0.042848 0.027852 -0.029088 -0.156468 0.006503
+0.037716 0.032082 0.038416 0.021835 -0.106963
+-0.043017 0.018166 0.070409 -0.005426 -0.035585
+-0.111071 -0.039986 0.050430 0.035157 0.066902
+-0.040684 0.060527 0.036225 0.002527 -0.015087
+0.059243 0.021268 -0.010682 -0.018434 0.059128
+0.111314 -0.054070 0.105744 -0.051476 -0.012970
+-0.000358 -0.099249 -0.077385 0.069924 -0.039101
+-0.072139 -0.049069 -0.088018 0.006144 0.000712
+0.081030 0.021987 -0.046031 0.058087 -0.001320
+-0.046851 -0.011062 0.108321 -0.001146 -0.071193
+0.044973 -0.002915 -0.003323 0.041735 0.094566
+0.053530 0.035927 0.100282 0.059082 -0.054059
+-0.012158 -0.035417 0.020412 -0.073193 0.059296
+-0.040489 -0.095250 -0.003821 -0.084904 0.053925
+0.109183 -0.005862 -0.036538 0.080962 -0.040647
+0.020070 0.057778 -0.020197 -0.079626 -0.003186
+-0.050855 0.128185 0.034731 0.057460 -0.035236
+-0.057096 -0.001238 0.122018 -0.071204 -0.047253
+-0.051767 0.048301 -0.052678 0.025990 -0.017481
+-0.029379 0.030738 0.047207 -0.047864 -0.033561
+0.029884 -0.091175 -0.085446 -0.026140 0.092628
+0.067706 -0.085617 0.081433 0.047305 0.031945
+-0.048728 -0.040387 0.046206 0.010578 -0.037639
+0.011328 -0.042458 -0.149597 0.033882 -0.061869
+0.008800 0.057754 -0.095876 0.038230 0.096876
+-0.033487 -0.141669 -0.014172 0.028439 -0.092764
+-0.053714 0.086926 0.034786 0.136053 -0.005569
+0.028753 0.009630 0.044114 -0.050365 -0.066224
+0.006017 0.014348 0.024471 0.000489 0.067234
+-0.021678 -0.118760 0.036349 -0.040295 0.076358
+-0.008444 -0.086082 -0.044018 -0.025804 0.028971
+-0.009233 0.053026 -0.035341 -0.182193 -0.102515
+0.089210 0.066812 0.032417 0.046882 -0.034815
+-0.052293 0.022814 0.129622 0.128232 -0.012105
+-0.087084 0.004762 0.086538 0.046566 0.098359
+-0.018713 0.039204 -0.021707 -0.060110 -0.117527
+-0.005459 0.060994 -0.057718 -0.021783 0.035154
+0.100557 -0.015470 -0.025818 0.008450 0.051535
+-0.001388 -0.114610 -0.057903 0.041862 0.061778
+0.045701 -0.078563 -0.070166 -0.048450 -0.088530
+0.021375 -0.004598 -0.090710 -0.009399 -0.073952
+-0.035575 -0.050280 0.114780 0.137866 0.065234
+0.003594 -0.066802 -0.144989 0.166201 0.039564
+-0.022457 -0.030090 0.016187 0.115443 -0.097331
+-0.019139 0.099440 0.002198 -0.030953 0.021099
+-0.045399 -0.046871 0.022533 -0.064657 0.005776
+0.049063 -0.028478 0.019268 0.054265 0.028042
+0.045559 -0.005541 -0.014410 -0.024165 -0.054976
+-0.073258 0.084205 0.036077 -0.068683 0.004708
+-0.085228 0.001234 0.046261 -0.050496 -0.028227
+-0.086828 -0.001218 0.021865 0.003791 -0.000568
+-0.088733 -0.040041 -0.035891 -0.054915 0.073463
+-0.132031 -0.012844 -0.068544 0.013052 0.087335
+0.038603 -0.115382 -0.010433 -0.007113 0.095126
+-0.047378 -0.081353 0.018021 -0.021156 -0.120774
+0.040038 0.007633 -0.088728 -0.009928 0.020142
+0.052024 -0.021063 -0.118121 0.102739 -0.055837
+0.005253 -0.061924 0.063680 -0.014512 -0.020259
+0.029493 -0.013435 -0.020638 0.089342 0.001092
+-0.046491 -0.145634 -0.083159 -0.158142 -0.279281
+0.003611 0.055863 -0.064655 -0.088773 0.089283
+-0.029619 -0.089949 0.017197 -0.066633 -0.052347
+0.090828 -0.087551 0.000338 0.085238 -0.005313
+0.096211 0.071381 -0.076546 -0.077927 -0.040864
+0.062936 0.041559 0.016235 -0.017513 0.014773
+-0.025734 0.028586 0.070292 0.055794 -0.026131
+-0.076954 -0.082228 0.043947 -0.035921 0.152668
+-0.049510 0.023159 0.008506 -0.044773 -0.160358
+0.024984 -0.025587 -0.071627 -0.038376 0.088478
+0.120568 0.046723 0.086731 0.000695 -0.015751
+-0.027837 -0.160937 -0.095031 0.036271 -0.009061
+-0.015078 -0.036281 -0.103665 -0.058258 -0.049573
+0.022021 0.108296 -0.002586 0.065655 -0.018584
+-0.046441 -0.031018 0.067350 0.014328 0.008860
+-0.000245 0.063400 -0.001810 0.043515 0.090344
+-0.063845 0.020485 0.079401 0.070558 -0.116428
+0.032628 0.068949 0.052238 -0.044530 0.096813
+0.029911 -0.008814 0.044352 -0.168172 0.009604
+0.055828 -0.100739 -0.026013 0.021193 -0.051425
+0.035891 -0.004085 0.030216 -0.060801 0.037202
+0.007262 0.120686 0.026846 0.058464 -0.100792
+-0.009176 0.027589 0.123957 -0.011283 -0.025744
+-0.105081 0.118244 -0.042122 -0.025404 0.000873
+-0.012703 0.084159 -0.067539 -0.140536 0.041637
+-0.014485 -0.043382 -0.048004 -0.075416 0.054401
+-0.018651 -0.032908 0.164231 -0.053236 0.033946
+-0.021681 -0.012655 -0.037049 -0.001613 -0.053393
+-0.014635 0.017954 -0.116115 -0.027232 0.034005
+-0.035376 0.026492 -0.037250 0.070733 0.074835
+-0.021378 -0.142980 0.123195 0.003699 0.025398
+0.015629 0.077370 0.032623 0.121580 0.097100
+0.000946 -0.056355 0.042065 0.008184 -0.081824
+-0.101937 0.065473 0.003360 0.069241 0.073002
+-0.053844 -0.044301 0.080351 -0.091833 0.044288
+0.007447 -0.120723 -0.013806 -0.023636 -0.064616
+0.030556 0.072630 0.074428 -0.087759 -0.026440
+0.064840 0.049162 0.091053 0.023891 0.033811
+-0.027746 0.116392 0.106126 -0.056644 -0.014781
+0.036137 -0.002632 0.055512 0.070077 0.067819
+-0.030625 0.053772 -0.078457 -0.021351 -0.113011
+0.052797 0.044875 -0.077269 -0.009867 0.101493
+0.073477 -0.024103 0.049145 -0.004706 -0.025211
+-0.053731 -0.049009 -0.035786 0.054430 0.046515
+0.025154 -0.043569 -0.034789 -0.058610 0.006931
+0.012049 0.046809 -0.129441 0.025541 -0.030933
+0.000297 -0.054058 0.179837 0.081515 0.004932
+-0.028445 -0.073753 0.010629 0.080042 0.098710
+-0.014017 0.057597 0.001010 0.071658 -0.067570
+0.074384 0.110366 -0.018121 -0.108754 0.037793
+0.028041 -0.047508 -0.031359 -0.098913 -0.036486
+-0.017311 -0.001279 -0.013694 0.051968 0.036512
+0.088201 0.031155 -0.043442 -0.065045 0.023486
+0.027000 0.104768 -0.015176 -0.038754 -0.004178
+0.003732 0.062166 0.085438 -0.077368 -0.101645
+-0.118347 0.007589 -0.056489 0.082268 0.020253
+-0.035623 0.034235 -0.099354 -0.061237 -0.024285
+0.005441 -0.039694 -0.025957 -0.004411 0.049903
+0.003040 0.036243 0.023552 -0.007334 0.128963
+-0.077727 -0.059175 -0.019437 -0.024872 0.004339
+0.084006 -0.076605 -0.102261 0.036714 -0.035205
+-0.007642 -0.005125 -0.030525 0.096390 -0.053138
+-0.002192 -0.024851 0.050645 0.041490 -0.043183
+0.046796 -0.050894 0.055023 0.133834 -0.024013
+0.000872 -0.057072 -0.000630 0.042070 -0.129339
+-0.064283 0.037836 -0.066393 0.004438 0.125379
+-0.062213 -0.067468 0.090177 -0.046094 -0.025725
+0.079101 -0.074909 -0.043730 -0.073483 0.069672
+-0.020413 -0.000079 -0.049725 -0.120751 -0.046980
+0.039894 0.072305 0.009798 0.005613 -0.045217
+0.006862 0.036285 0.074819 -0.006747 0.015144
+-0.071562 0.012324 -0.001082 0.014835 0.079960
+-0.027804 0.103358 -0.017203 0.014914 -0.056687
+0.030827 0.028076 0.003395 -0.073255 0.110310
+0.056498 -0.044893 0.110122 -0.109058 -0.052302
+-0.001604 -0.089977 -0.060548 0.107808 0.025463
+-0.070203 -0.000513 -0.123913 0.046247 -0.085392
+0.096343 0.095890 -0.064950 0.070363 0.034272
+0.037773 -0.076950 0.124858 -0.009008 -0.010115
+0.083868 0.051242 0.039149 0.015185 0.083375
+0.029773 -0.045961 0.100395 0.003743 -0.138294
+-0.041755 0.010806 0.057797 -0.147374 0.095858
+-0.009929 -0.103347 -0.032310 -0.110560 0.121377
+0.145244 0.017079 -0.080587 0.020516 -0.044939
+-0.010477 0.038347 -0.003466 -0.001618 0.019600
+-0.021762 0.125482 0.011074 0.065815 0.040298
+0.009202 -0.051686 0.129684 -0.131135 0.044536
+0.009313 0.102518 -0.075351 0.054338 0.020273
+-0.045753 0.031345 0.000407 -0.097294 -0.000416
+-0.007466 -0.044972 -0.078744 0.042414 0.066624
+0.030318 -0.067852 0.061416 -0.028992 0.056606
+0.004038 -0.036253 -0.014279 0.023123 -0.007832
+-0.000137 -0.027684 -0.127648 -0.007713 -0.008746
+-0.026500 0.049032 -0.183319 0.059107 0.066500
+0.016902 -0.093331 0.090129 0.016648 -0.083492
+-0.023669 -0.010473 0.027614 0.145068 0.000681
+0.044133 -0.035809 0.005668 -0.090461 -0.090732
+-0.033927 0.042997 0.021700 -0.046955 0.044487
+-0.026444 -0.061011 0.010110 -0.023804 0.030427
+-0.015195 -0.155603 -0.016584 0.021461 -0.003528
+-0.059784 0.032214 0.000847 -0.098859 -0.078980
+0.043188 0.066433 0.062309 0.144507 0.006865
+-0.068953 0.046698 0.099369 0.043354 -0.014309
+-0.033202 -0.002950 0.040734 0.083454 0.039319
+0.051358 0.006074 -0.073465 -0.090554 -0.120787
+-0.040676 0.092412 -0.085151 -0.021699 0.005813
+0.103135 0.024964 0.025832 -0.075982 0.035699
+-0.027310 -0.153007 0.036420 0.057600 0.081630
+0.001605 -0.054191 -0.033043 -0.014390 -0.071383
+0.036180 0.035860 -0.046980 0.038541 -0.044757
+-0.078032 -0.029878 0.078183 0.082251 0.010549
+0.053317 -0.038231 -0.065610 0.055798 0.037504
+0.076317 -0.027605 0.010349 0.095361 -0.088636
+0.049089 0.113316 0.051084 0.038589 0.034330
+-0.055948 -0.037217 -0.015418 -0.139976 0.036306
+0.039306 -0.009889 -0.044910 0.016559 -0.000050
+0.106073 0.015280 -0.002563 -0.109085 -0.048475
+-0.035319 0.163860 0.032981 -0.044932 0.003227
+-0.123233 -0.010638 0.055479 -0.003666 -0.072249
+-0.111158 0.065365 0.010691 0.039119 -0.001837
+-0.118729 0.061470 -0.002077 -0.033335 -0.060165
+-0.026081 -0.001806 -0.079616 -0.000075 0.080598
+0.032908 -0.035140 -0.003136 -0.029024 0.094622
+-0.075773 -0.022898 -0.014817 0.058393 -0.111505
+0.036794 -0.015760 -0.112602 0.030323 0.085897
+-0.020834 0.056079 -0.103762 0.117671 -0.041205
+0.041684 -0.084336 0.034186 0.011973 -0.006313
+0.040836 -0.035709 0.034170 0.122672 0.090973
+-0.053182 -0.059371 0.091017 -0.090998 -0.116986
+0.001405 0.138364 0.017107 -0.064076 0.103486
+-0.031142 -0.030068 0.046547 -0.133471 -0.042055
+0.140418 -0.125084 0.035218 -0.001162 -0.021130
+-0.012034 0.097413 -0.079006 -0.039030 -0.054011
+0.143887 0.078835 -0.000601 -0.021173 -0.039895
+-0.025050 0.075865 0.039221 0.032458 0.038206
+-0.038873 -0.085003 -0.032736 -0.026956 0.113525
+-0.023933 0.120794 -0.003862 -0.026459 -0.138724
+0.089559 0.029002 -0.052098 -0.085692 0.115174
+0.083497 0.024179 0.119021 -0.067541 0.019047
+-0.027720 -0.086083 -0.055329 0.020087 -0.027086
+-0.047858 -0.051975 -0.035205 -0.059342 -0.068582
+0.058936 0.044141 -0.080315 0.119744 -0.046518
+-0.064588 -0.027212 0.147823 0.032404 0.016690
+0.024302 0.085560 -0.001525 0.016469 0.038891
+-0.020146 0.019943 0.045067 0.038070 -0.086274
+-0.025769 0.044192 0.102141 -0.064765 0.055849
+0.048803 -0.030066 -0.009220 -0.116655 0.068295
+0.047580 -0.076138 -0.070307 0.047582 -0.111342
+0.004656 -0.004452 0.029703 -0.004259 0.011130
+0.014446 0.166086 0.059565 0.000985 -0.052607
+0.013251 0.094476 0.106216 0.016715 -0.025581
+-0.101244 0.072897 -0.114526 0.024681 0.010784
+-0.051759 0.032389 -0.050202 -0.083316 0.052334
+-0.035100 -0.116721 -0.110336 -0.053391 0.065541
+-0.029790 -0.020457 0.135285 -0.004142 0.111508
+-0.030936 0.018549 -0.016034 0.018572 -0.084336
+-0.048615 -0.018739 -0.096815 -0.090162 0.019410
+-0.040821 -0.009925 -0.097427 0.091891 0.031793
+-0.024598 -0.132848 0.078353 0.089339 -0.068562
+-0.020779 0.040974 -0.055675 0.169131 0.029649
+0.078165 -0.050679 -0.005881 -0.004983 -0.104324
+-0.069096 0.127960 0.011392 -0.000769 0.062168
+-0.079842 0.001606 0.089284 -0.035465 0.031075
+0.029519 -0.102956 -0.010902 -0.064030 -0.019669
+0.057492 0.075802 -0.008904 -0.060743 -0.053144
+0.005126 0.062980 0.085674 0.019895 0.104448
+-0.086473 0.056906 0.056795 -0.012940 0.036606
+-0.008604 -0.040450 0.042062 0.041810 0.027680
+-0.092256 0.091237 -0.039500 0.024761 -0.088978
+0.068585 0.088295 -0.048033 -0.017808 0.045370
+0.124600 -0.035320 0.056751 0.092751 0.054025
+-0.015725 -0.061938 0.036806 0.078768 -0.016065
+0.002444 -0.023887 -0.072177 -0.029790 -0.005860
+0.015478 0.129142 -0.091024 0.071482 -0.065445
+0.005867 -0.006051 0.098646 0.054089 0.018713
+0.033837 -0.008355 -0.051959 0.057440 0.160305
+-0.001863 0.016738 -0.033705 0.062233 -0.140759
+0.027342 0.060074 0.030362 -0.117875 0.061020
+-0.028026 -0.088238 -0.003782 -0.146288 -0.080395
+0.050048 0.036136 0.019500 0.066902 0.020355
+0.024817 -0.056254 -0.140918 -0.085803 0.020540
+-0.003730 0.161411 -0.049408 0.000219 -0.002348
+-0.055021 0.067820 0.126483 -0.031063 -0.119299
+-0.102834 0.001133 0.010172 0.107707 -0.029106
+-0.059813 0.036698 -0.021720 -0.043189 -0.002270
+-0.031694 0.009605 -0.022459 -0.036417 0.053675
+0.061561 -0.012723 0.050040 -0.029450 0.131044
+-0.124516 -0.107579 -0.012171 0.011761 0.002599
+0.016327 -0.060854 -0.080910 0.030875 -0.002997
+-0.020970 -0.011880 -0.086096 0.037912 0.012421
+0.055253 -0.007250 0.041740 0.055596 -0.024420
+-0.017564 -0.079202 0.008897 0.180091 0.054490
+0.001772 -0.022151 -0.082048 -0.010559 -0.163377
+-0.020660 -0.017827 -0.030800 -0.045856 0.122405
+-0.052946 -0.130490 0.097383 -0.116737 0.039855
+0.056504 -0.059549 -0.059931 -0.018658 0.034898
+0.054889 0.005373 -0.066796 -0.127360 0.047960
+0.071746 0.027410 -0.006212 0.024132 -0.094062
+0.005369 -0.008926 0.073085 -0.014265 -0.029204
+-0.100025 -0.072076 0.014651 0.069368 0.048275
+-0.066823 0.086074 0.014921 -0.015395 -0.045138
+0.026224 0.000902 -0.038208 -0.035221 0.057397
+0.097606 -0.073195 0.051626 -0.033488 0.027813
+0.002070 -0.097510 -0.057877 0.126680 -0.082194
+-0.072597 0.006014 -0.093185 -0.016853 -0.022790
+0.138461 0.005394 -0.056485 0.102778 0.028918
+-0.045604 -0.060041 0.121251 0.029260 -0.101404
+0.061194 0.033039 -0.016798 0.064263 0.065144
+0.010925 0.023151 0.107623 0.027977 -0.090356
+-0.024863 -0.006440 0.047870 -0.047486 0.088211
+-0.012139 -0.116121 -0.000525 -0.140961 0.016604
+0.063490 -0.022732 -0.046944 0.066970 -0.068838
+0.016143 0.026202 -0.043344 -0.064881 0.024877
+-0.072845 0.120531 0.077901 0.047272 0.011713
+-0.044646 0.040932 0.076164 -0.101233 -0.029615
+-0.065118 0.050966 -0.023273 0.053517 0.023710
+-0.007489 0.035822 0.023439 -0.055528 -0.004033
+-0.007662 -0.096546 -0.081662 0.037141 0.137562
+0.075526 -0.097496 0.123990 0.013996 0.087005
+-0.019788 -0.082043 0.020524 0.007027 -0.021537
+-0.036264 -0.090952 -0.177722 -0.009306 -0.031473
+-0.009287 0.047557 -0.090241 0.089347 0.056375
+-0.005506 -0.112128 0.004356 0.064421 -0.038478
+-0.035674 0.040616 0.007731 0.160236 -0.054199
+-0.007537 0.012434 0.022001 -0.021567 -0.075163
+-0.026053 0.015909 0.041015 0.021832 0.034152
+-0.048539 -0.086655 0.047465 0.000682 0.042640
+0.023697 -0.095971 -0.022874 -0.000369 0.003413
+0.046005 0.064807 0.010131 -0.129517 -0.092254
+0.116469 0.053796 0.038110 0.094470 0.018435
+-0.034803 0.073591 0.108348 0.104096 0.049884
+-0.021274 0.022097 0.065347 0.065555 0.089319
+0.000474 -0.004186 -0.040493 -0.065543 -0.083167
+-0.017425 0.049177 -0.044248 0.008399 0.068180
+0.154778 0.027549 -0.008012 0.014950 0.043254
+0.039599 -0.136415 -0.018716 0.061900 0.031263
+0.058118 -0.037200 -0.114692 -0.080876 -0.053238
+0.077436 0.015015 -0.092517 0.005804 -0.065541
+-0.005653 -0.073184 0.095594 0.082470 0.060989
+-0.000262 -0.035766 -0.083441 0.122634 0.088429
+-0.014397 -0.055434 -0.005659 0.069697 -0.064892
+0.008824 0.082498 0.051866 -0.036070 0.033403
+-0.082855 -0.087376 0.002714 -0.097121 -0.019170
+0.027179 -0.069870 -0.009316 0.047450 0.040657
+0.060527 0.004620 -0.040264 -0.051228 -0.029023
+-0.071384 0.101421 0.009538 -0.099185 0.060100
+-0.048395 -0.024677 0.025125 -0.056043 -0.058045
+-0.054059 0.008107 0.021078 0.045290 -0.018459
+-0.113359 0.014009 -0.006826 -0.052747 0.046922
+-0.075976 0.008538 -0.084411 -0.004369 0.045801
+0.075392 -0.067340 0.014454 0.032407 0.092478
+-0.061859 -0.083458 0.051442 0.031695 -0.080233
+0.054028 0.027000 -0.073549 0.032300 0.036501
+-0.011384 -0.020780 -0.124142 0.093905 -0.028332
+0.039139 -0.030944 0.079952 -0.001717 0.013976
+0.038005 -0.001751 -0.044097 0.129827 0.014385
+-0.001682 -0.063458 -0.002511 -0.078150 -0.141236
+0.021955 0.104851 -0.093246 -0.060019 0.069998
+0.004399 -0.096408 0.059327 -0.062268 -0.074327
+0.108063 -0.090534 -0.045654 0.048119 0.049187
+0.042105 0.043964 -0.091516 -0.047999 -0.028881
+0.070471 0.055401 -0.025605 0.011176 0.008475
+0.022254 0.038266 0.048106 0.047176 -0.017967
+-0.010978 -0.088762 0.034806 0.019311 0.126815
+-0.010571 0.053073 0.032162 -0.000780 -0.152200
+-0.014253 -0.021954 -0.131040 -0.061376 0.113838
+0.060725 0.020201 0.102533 -0.011392 -0.052046
+-0.069625 -0.091011 -0.097954 0.067847 0.017856
+-0.053461 -0.040679 -0.121664 -0.077208 -0.106919
+0.057996 0.069756 -0.012433 0.069569 -0.055159
+-0.024801 -0.060448 0.101700 0.014619 0.036580
+-0.004526 0.093977 -0.028211 0.045261 0.149736
+-0.014691 -0.007959 0.097708 0.107128 -0.079723
+0.029157 0.020116 0.104828 -0.064208 0.119172
+0.039583 -0.029446 0.006628 -0.110398 0.004062
+0.048132 -0.060601 0.009448 0.051777 -0.053127
+0.050551 -0.001924 0.028079 -0.050618 -0.013698
+0.001920 0.088162 0.073078 0.085795 -0.066788
+0.014025 0.042699 0.176241 -0.046674 -0.034822
+-0.051433 0.121729 -0.057076 0.023901 0.045075
+-0.057182 0.054780 -0.017280 -0.146674 0.002090
+-0.016223 -0.044841 -0.084524 -0.152479 0.072688
+-0.006962 0.008711 0.127455 -0.003876 0.053162
+-0.013682 -0.025386 -0.000427 -0.024811 -0.024474
+-0.056267 0.062116 -0.121311 -0.053011 0.065651
+-0.075385 -0.008680 -0.063033 0.083039 0.110577
+-0.000152 -0.127017 0.055904 0.013659 0.005664
+-0.002852 0.047248 0.001128 0.100773 0.037274
+0.026368 -0.042205 0.021887 -0.020247 -0.056678
+-0.077475 0.089799 0.058003 0.039741 0.106663
+-0.016853 -0.015972 0.075741 -0.048829 0.015374
+-0.032657 -0.125677 -0.062060 -0.057409 -0.061287
+0.073151 0.050357 0.053547 -0.059886 -0.051298
+0.057954 -0.003817 0.076028 0.006757 0.061109
+-0.038030 0.143209 0.092207 -0.018493 0.062291
+0.005751 -0.036449 0.067582 0.031449 0.101894
+-0.080754 0.011515 -0.049485 -0.016137 -0.087818
+0.108851 0.038222 -0.099315 -0.003117 0.052278
+0.107517 -0.036233 0.065370 0.040409 -0.057029
+-0.033167 -0.081758 -0.019502 0.033438 0.013365
+-0.017760 -0.025906 -0.020244 -0.078722 -0.011697
+-0.028246 0.068647 -0.106417 0.026956 -0.064914
+0.062711 -0.017857 0.151539 0.044613 -0.017820
+0.009085 -0.032785 -0.025795 0.075790 0.075667
+-0.040398 0.058556 -0.042634 0.093973 -0.099529
+0.057103 0.073562 0.012640 -0.066141 0.029558
+0.060219 -0.083699 -0.054799 -0.120442 -0.000374
+0.006521 0.034512 -0.039558 0.042191 0.033865
+0.103992 -0.014977 -0.077384 -0.051340 0.001873
+0.047451 0.140612 -0.024885 -0.021420 -0.046604
+0.030606 0.100660 0.076356 -0.019288 -0.098570
+-0.114463 -0.010855 -0.034657 0.025618 -0.003356
+-0.087913 0.064346 -0.075540 -0.091569 -0.024965
+-0.021232 -0.017255 -0.056931 -0.003104 0.030219
+-0.020112 -0.012334 0.035298 0.001405 0.161753
+-0.064618 -0.064401 -0.007218 -0.000120 -0.047208
+0.116105 -0.056464 -0.069645 -0.007032 -0.012090
+-0.023237 0.016000 -0.039802 0.074319 -0.012604
+0.014863 -0.058081 0.093219 0.062253 -0.040302
+0.027405 -0.128683 0.039923 0.116808 -0.011706
+0.012483 -0.017698 0.003645 -0.007588 -0.120662
+-0.032868 0.066217 -0.031343 -0.034166 0.146334
+-0.031228 -0.125921 0.117756 -0.042686 -0.062094
+0.049375 -0.112262 0.010166 -0.073599 0.048690
+0.028292 0.020076 -0.062865 -0.106114 -0.025300
+0.066916 0.029279 0.028191 -0.003599 -0.040614
+0.020491 0.060238 0.052747 -0.010390 -0.022389
+-0.063358 -0.028707 0.035907 -0.011898 0.079703
+-0.003758 0.078051 -0.017869 0.009045 -0.018982
+0.034974 0.069405 -0.018909 -0.038613 0.083909
+0.033935 -0.036607 0.088891 -0.052599 -0.059839
+0.052758 -0.068308 -0.063615 0.126093 -0.009460
+-0.042175 -0.011113 -0.073071 0.052086 -0.052619
+0.049226 0.066898 -0.045666 0.117923 0.053656
+-0.010739 -0.043962 0.141903 0.001792 -0.035469
+0.090671 0.043993 -0.013655 0.018989 0.127223
+0.001030 -0.001154 0.081839 -0.024979 -0.103704
+-0.077920 0.036083 0.068220 -0.062210 0.113730
+-0.010501 -0.065801 0.050885 -0.104304 0.121937
+0.111850 0.009680 -0.011791 0.001677 -0.035029
+0.010677 0.024572 -0.012860 -0.030323 -0.010466
+0.011279 0.167752 0.003136 0.109709 0.007292
+0.000987 0.004572 0.108706 -0.113192 -0.012431
+-0.015225 0.073653 -0.051275 0.077928 -0.012752
+-0.011708 0.014172 0.025162 -0.095378 0.026382
+-0.028889 -0.058569 -0.129329 0.011087 0.061452
+0.056893 -0.058004 0.103586 -0.060752 0.081824
+-0.042805 -0.015991 -0.024444 0.028952 -0.013528
+0.042851 0.019988 -0.165741 -0.031012 -0.014713
+-0.026059 0.031698 -0.134343 0.032090 0.020828
+0.051674 -0.128006 0.050856 0.022220 -0.073513
+-0.009340 0.013756 0.036163 0.098407 -0.023495
+0.023858 0.008121 0.022220 -0.103489 -0.046663
+-0.033000 0.063565 0.029224 -0.012693 0.084202
+0.012187 -0.051000 0.026126 -0.043293 0.008675
+-0.019812 -0.165070 -0.014555 -0.047431 0.017990
+-0.040073 0.107192 0.022228 -0.089023 -0.066885
+0.014630 0.073186 0.069902 0.072634 0.019593
+-0.041539 0.031788 0.092310 0.027223 0.034027
+-0.051855 0.000391 0.007869 0.131910 0.069384
+0.046276 0.040440 -0.037093 -0.031393 -0.112828
+0.015709 0.096749 -0.103205 -0.021284 0.011405
+0.158287 -0.021028 0.042219 -0.050759 0.069715
+-0.042907 -0.116980 0.014224 0.094648 0.028395
+0.041535 -0.057033 -0.047607 -0.024419 -0.034905
+0.010125 0.036728 -0.052503 -0.001839 -0.033477
+-0.053414 -0.070394 0.092895 0.100600 -0.026352
+0.080574 -0.028763 -0.059548 0.094571 0.091787
+0.041437 0.014312 0.045792 0.108269 -0.081586
+0.056288 0.137447 0.054718 -0.032474 0.054502
+-0.100144 -0.006460 0.024739 -0.117043 -0.008919
+0.070299 -0.036862 -0.014543 0.024500 -0.015222
+0.114975 -0.043705 0.000421 -0.061872 -0.035148
+-0.022797 0.128575 -0.031798 -0.086718 -0.007172
+-0.071706 -0.006833 0.028645 -0.007011 -0.096745
+-0.142269 0.027996 0.065210 0.061381 0.000741
+-0.140531 0.017480 -0.014986 -0.040893 -0.012718
+-0.012494 -0.021869 -0.032923 0.016456 0.104475
+0.010792 -0.066178 0.019097 -0.001893 0.067513
+-0.092673 -0.059851 -0.045936 0.052642 -0.062500
+0.065013 -0.025659 -0.149301 0.051705 0.035692
+-0.045790 -0.007482 -0.069141 0.149365 -0.042039
+0.018492 -0.081315 0.055880 0.058158 0.019669
+0.063836 -0.012391 0.007057 0.155454 0.033854
+-0.016532 -0.007661 0.043113 -0.080283 -0.108670
+-0.029344 0.093781 -0.015840 -0.068134 0.091804
+0.004148 -0.058507 0.059633 -0.095883 -0.004939
+0.086151 -0.113571 -0.019466 -0.009167 0.003662
diff --git a/codec2/branches/0.7/src/codebook/lspmelvq1.txt b/codec2/branches/0.7/src/codebook/lspmelvq1.txt
new file mode 100644 (file)
index 0000000..e13a330
--- /dev/null
@@ -0,0 +1,65 @@
+ 6 64
+ 6.40185185e+02 8.93138889e+02 1.39385185e+03 1.49406481e+03 1.65625926e+03 1.70082407e+03
+ 5.58515625e+02 7.16906250e+02 1.05735938e+03 1.18262500e+03 1.50379688e+03 1.61003125e+03
+ 6.15108108e+02 7.69621622e+02 1.12016216e+03 1.22283784e+03 1.36645946e+03 1.46505405e+03
+ 6.63458333e+02 7.36833333e+02 9.64763889e+02 1.04354167e+03 1.62316667e+03 1.68129167e+03
+ 4.87957447e+02 5.77723404e+02 1.01742553e+03 1.17704255e+03 1.55209574e+03 1.61569149e+03
+ 5.36098765e+02 7.33407407e+02 1.29228395e+03 1.40608642e+03 1.57770370e+03 1.63749383e+03
+ 4.73014706e+02 5.42558824e+02 8.77397059e+02 1.28582353e+03 1.59104412e+03 1.64744118e+03
+ 5.25342857e+02 6.52014286e+02 1.20682857e+03 1.49395714e+03 1.64797143e+03 1.69830000e+03
+ 5.10886792e+02 5.72867925e+02 9.45226415e+02 1.44567925e+03 1.67816981e+03 1.70552830e+03
+ 5.34914530e+02 7.21264957e+02 1.27592308e+03 1.41576068e+03 1.64850427e+03 1.69573504e+03
+ 8.65189189e+02 1.04700000e+03 1.26713514e+03 1.38932432e+03 1.64656757e+03 1.69697297e+03
+ 6.08033113e+02 8.69887417e+02 1.30094702e+03 1.43286755e+03 1.63974172e+03 1.68941060e+03
+ 5.54971831e+02 6.49352113e+02 8.66845070e+02 9.79873239e+02 1.64530986e+03 1.69539437e+03
+ 6.96079208e+02 8.13970297e+02 1.10248515e+03 1.21979208e+03 1.53648515e+03 1.62194059e+03
+ 5.53878788e+02 6.91096970e+02 1.20083636e+03 1.33933939e+03 1.62908485e+03 1.68349697e+03
+ 7.78561224e+02 9.97775510e+02 1.25863265e+03 1.39033673e+03 1.60198980e+03 1.65785714e+03
+ 7.13107143e+02 7.78892857e+02 9.92875000e+02 1.05194643e+03 1.49744643e+03 1.65066071e+03
+ 4.90269663e+02 5.98179775e+02 1.11602247e+03 1.24413483e+03 1.62225843e+03 1.67221348e+03
+ 4.48555556e+02 5.12085470e+02 1.27170085e+03 1.44817949e+03 1.57936752e+03 1.64247863e+03
+ 4.65687500e+02 5.35312500e+02 1.09918750e+03 1.53579167e+03 1.68429167e+03 1.71089583e+03
+ 8.12222222e+02 1.08753333e+03 1.47044444e+03 1.55973333e+03 1.69217778e+03 1.72637778e+03
+ 4.28173913e+02 4.89426087e+02 1.16033043e+03 1.40930435e+03 1.59750435e+03 1.65129565e+03
+ 7.12810000e+02 9.57560000e+02 1.43302000e+03 1.51637000e+03 1.67539000e+03 1.71006000e+03
+ 7.17255474e+02 9.34072993e+02 1.30520438e+03 1.43671533e+03 1.64720438e+03 1.69308759e+03
+ 4.92887640e+02 5.80393258e+02 1.33951685e+03 1.46106742e+03 1.59200000e+03 1.65341573e+03
+ 5.50467290e+02 6.75887850e+02 9.90887850e+02 1.17743925e+03 1.61563551e+03 1.65800000e+03
+ 7.14528302e+02 8.01792453e+02 1.07294340e+03 1.14607547e+03 1.63705660e+03 1.70658491e+03
+ 5.13819149e+02 5.90989362e+02 7.98691489e+02 8.95755319e+02 1.55775532e+03 1.62456383e+03
+ 4.36653333e+02 5.18413333e+02 1.28198667e+03 1.54708000e+03 1.68512000e+03 1.71776000e+03
+ 6.81854167e+02 7.58354167e+02 1.04664583e+03 1.12091667e+03 1.41225000e+03 1.60341667e+03
+ 8.73961538e+02 1.11849038e+03 1.37660577e+03 1.46506731e+03 1.66537500e+03 1.70718269e+03
+ 5.53528736e+02 6.34091954e+02 1.14477011e+03 1.28480460e+03 1.54287356e+03 1.62063218e+03
+ 4.48532258e+02 5.19096774e+02 1.05457258e+03 1.31966129e+03 1.59125806e+03 1.64984677e+03
+ 7.42266667e+02 8.85293333e+02 1.15282667e+03 1.31850667e+03 1.56936000e+03 1.63145333e+03
+ 5.29029851e+02 6.54522388e+02 1.35576119e+03 1.51174627e+03 1.66238806e+03 1.70640299e+03
+ 4.63793651e+02 5.97769841e+02 1.17604762e+03 1.36613492e+03 1.62936508e+03 1.67800794e+03
+ 6.26936170e+02 7.06659574e+02 1.05804255e+03 1.32361702e+03 1.47327660e+03 1.59968085e+03
+ 4.77322222e+02 6.15500000e+02 1.48888889e+03 1.55050000e+03 1.68310000e+03 1.71234444e+03
+ 5.47441558e+02 8.15441558e+02 1.31337662e+03 1.48696104e+03 1.67197403e+03 1.71740260e+03
+ 6.10670968e+02 8.19954839e+02 1.21910968e+03 1.36365806e+03 1.59205161e+03 1.65430968e+03
+ 5.47413793e+02 7.46540230e+02 1.43842529e+03 1.51772414e+03 1.65964368e+03 1.69557471e+03
+ 6.04822917e+02 8.21145833e+02 1.13793750e+03 1.35829167e+03 1.59893750e+03 1.65563542e+03
+ 5.25934783e+02 6.16739130e+02 1.06013043e+03 1.42732609e+03 1.59334783e+03 1.65747826e+03
+ 6.22500000e+02 7.62142857e+02 1.31865306e+03 1.41095918e+03 1.61812245e+03 1.68006122e+03
+ 4.36916667e+02 5.16583333e+02 1.39028571e+03 1.47585714e+03 1.59471429e+03 1.63373810e+03
+ 7.92486726e+02 1.03123894e+03 1.36261947e+03 1.47268142e+03 1.64925664e+03 1.69735398e+03
+ 4.57706897e+02 5.26206897e+02 8.65965517e+02 1.12046552e+03 1.56482759e+03 1.62527586e+03
+ 5.26390000e+02 6.24210000e+02 1.26965000e+03 1.37423000e+03 1.55807000e+03 1.62096000e+03
+ 4.83768421e+02 5.73505263e+02 1.44066316e+03 1.51243158e+03 1.62236842e+03 1.67130526e+03
+ 9.53060606e+02 1.19403030e+03 1.41666667e+03 1.51581818e+03 1.67881818e+03 1.71821212e+03
+ 4.99947368e+02 6.27357895e+02 1.29993684e+03 1.39423158e+03 1.64316842e+03 1.68532632e+03
+ 6.48722892e+02 8.38180723e+02 1.22550000e+03 1.38344578e+03 1.63746386e+03 1.69167470e+03
+ 6.72588235e+02 1.02260294e+03 1.34620588e+03 1.44375000e+03 1.65114706e+03 1.69542647e+03
+ 5.81833333e+02 6.74944444e+02 9.55166667e+02 1.02050000e+03 1.37050000e+03 1.50311111e+03
+ 5.36142857e+02 6.52530612e+02 1.24383673e+03 1.31526531e+03 1.42510204e+03 1.50573469e+03
+ 5.60558376e+02 7.86649746e+02 1.22465990e+03 1.37398477e+03 1.63005584e+03 1.68268020e+03
+ 5.91925926e+02 7.83722222e+02 9.82000000e+02 1.14081481e+03 1.58161111e+03 1.62527778e+03
+ 5.48536585e+02 6.44524390e+02 9.40451220e+02 1.04874390e+03 1.55789024e+03 1.60947561e+03
+ 5.16915789e+02 7.23252632e+02 1.13595263e+03 1.30918947e+03 1.60008421e+03 1.66947895e+03
+ 4.26521127e+02 5.06077465e+02 1.45773239e+03 1.53502113e+03 1.64134507e+03 1.67845070e+03
+ 6.45189189e+02 7.76594595e+02 1.02078378e+03 1.24006757e+03 1.59700000e+03 1.64870270e+03
+ 6.37105263e+02 9.41473684e+02 1.24221053e+03 1.37248684e+03 1.64669737e+03 1.69480263e+03
+ 6.91228261e+02 7.88141304e+02 1.20211957e+03 1.29489130e+03 1.62696739e+03 1.68177174e+03
+ 6.99080460e+02 8.86655172e+02 1.30089655e+03 1.39927586e+03 1.57994253e+03 1.64679310e+03
diff --git a/codec2/branches/0.7/src/codebook/lspmelvq2.txt b/codec2/branches/0.7/src/codebook/lspmelvq2.txt
new file mode 100644 (file)
index 0000000..fd866c2
--- /dev/null
@@ -0,0 +1,65 @@
+ 6 64
+ 4.44342023e+00 5.11708330e+01 7.45725570e+00 -2.74373415e+01 -1.85055703e+01 -1.81988855e+01
+ 5.15799536e+01 6.33165865e+01 5.77795877e+01 -4.41590891e+01 -1.84834304e+01 -6.93391834e+00
+ -2.02794858e+01 -2.17454062e+01 4.66946917e+00 5.21568589e+01 3.04367068e+01 3.68582243e+01
+ -2.91103567e+01 -5.63932590e+00 -3.45382916e+00 -6.30261110e+01 -2.04423477e+01 -1.90484888e+01
+ 2.91622389e+00 4.08374256e+01 1.65790036e+01 -5.18460849e+01 3.85044571e+01 1.81728298e+01
+ -2.06976591e+01 -1.14022219e+01 -3.66173122e+01 -1.66116065e+01 -5.68964685e+01 -2.43009778e+01
+ -2.02385110e+01 2.66331668e+01 3.31191422e+01 2.76284155e+01 -3.67493353e+01 -2.56040969e+01
+ 5.49870513e+01 7.17479528e-01 2.30674073e+01 -2.21030578e+01 1.16642536e+01 1.09937884e+01
+ -6.27214697e+01 2.17547491e+01 2.12906874e+01 -7.64891287e+00 -4.55329824e+00 -9.71776749e+00
+ -9.56338101e+00 -3.85841094e+00 2.50453734e+01 -9.45216004e+00 6.05016771e+00 5.35043165e+00
+ 4.73822779e+01 5.66122493e+01 -2.70314508e+01 -2.46699892e+01 4.86343141e+00 -2.25494963e-01
+ 2.63996634e+01 2.67857198e+01 -1.66167044e+00 6.28366080e+01 -1.97652890e+01 -8.55169245e+00
+ -8.77648251e+00 -9.04545090e+00 -7.88995628e+00 2.82433004e+01 -3.50963028e+01 -2.19709149e+01
+ 1.48422904e+01 2.54563234e+01 -5.61262119e+01 -5.02933841e+01 -2.29392506e+01 -1.58112708e+01
+ 4.94185528e+00 2.77798011e+01 8.34578754e+00 1.08553274e+01 -3.12587321e+00 -3.97806637e+00
+ 1.26426172e+01 -5.22317245e+01 3.72487149e+01 -5.72067399e+01 -1.45125408e+01 -5.54034776e+00
+ 1.34849886e+01 1.53245571e+01 -2.39643623e+01 -2.13134975e+01 1.95779488e+01 1.41596754e+01
+ -5.53542844e+01 -4.52077225e+01 1.05184665e+01 4.30460961e+01 -2.49859454e+01 -1.93484138e+01
+ 2.77226366e+01 3.21881626e+01 2.00321485e+01 2.43327500e+01 -7.28194058e+01 -5.11822933e+01
+ -3.13817941e+01 -5.25745440e+00 -4.37806471e+01 1.41312375e+01 1.76392003e+01 9.81024019e+00
+ -4.82599528e+01 -2.62973101e+01 -4.41428355e+01 -3.19000800e+01 2.25085221e+01 -4.67937987e-01
+ 7.37202096e+00 -7.79070841e+00 -1.25731600e+01 2.71074123e+01 9.34051572e+00 1.44476918e+01
+ 1.45294918e+01 8.82597108e+00 5.70008598e+01 -1.63234076e+01 -3.24142014e+01 -2.10223676e+01
+ 3.24616251e+01 4.86062215e+01 3.85451764e+01 9.77181881e+00 1.82855803e+00 1.15062929e+01
+ -4.38275303e+01 -2.26262503e+01 -2.98278038e+01 1.36114828e+01 9.66848589e+00 -6.35218137e+01
+ -1.19967019e+01 2.74307686e+00 -7.36375365e+01 -2.09808902e+01 -4.11838983e+00 7.71405435e+00
+ 2.40161741e+01 -2.29513293e+00 -6.80983466e+00 -2.64043268e+01 -2.18529016e+01 -1.63381291e+01
+ -1.61483826e+01 3.59085531e+01 -3.08369768e+00 3.83957559e+00 4.23002878e+01 1.75002976e+01
+ 5.41225147e+01 -4.87513410e+01 -1.48712329e+01 -3.81255636e+01 1.52903471e+01 7.33079239e+00
+ 5.30928834e+01 1.39221339e+01 1.06535591e+01 2.43449656e+01 -1.65952406e+01 -1.60364654e+01
+ 3.31414865e+01 3.85713980e+01 -2.60250508e+01 2.20210341e+01 1.56865619e+01 1.32592795e+01
+ 1.57193842e+01 -4.94061178e+01 3.14552297e+01 1.01896451e+01 2.19911283e-01 1.62901547e+00
+ 4.10868090e+00 1.42755212e+01 5.84749767e+01 -1.16668460e+00 5.26264856e+01 4.34937534e+01
+ 3.58653333e+02 -1.12586667e+02 8.59866667e+01 5.20800000e+01 -5.28800000e+01 -2.49240000e+02
+ -1.25792149e+01 -6.64039481e+00 -3.30106093e+01 1.51449305e+00 5.03259445e+01 6.16091231e+01
+ -6.81685332e+00 1.43146311e+01 1.41562793e+01 5.36363349e+01 8.36051350e+01 3.81739887e+01
+ -1.80005518e+01 4.13574694e+01 -4.63736420e+01 8.47794181e+00 -1.04610694e+01 -1.13846635e+01
+ 2.87711486e+01 3.14689155e+01 -3.95743803e+01 1.43977222e+00 -3.77309497e+01 -3.05309094e+01
+ -3.44692147e+01 -1.10777698e+01 4.44680522e+01 -6.00045330e+01 -4.49729480e+01 -3.48364296e+01
+ 3.87401321e+01 4.10529042e+01 -7.92945674e+00 2.00279378e+01 7.44245854e+01 5.46497838e+01
+ 8.18008445e+01 1.33530724e+02 -5.47374752e+00 3.44759309e+01 7.57416682e+01 5.26111643e+01
+ -6.15067453e+01 -7.66327843e+01 -4.72471128e+01 -4.35927870e+01 -9.46878103e+00 8.32597962e-01
+ -1.15439769e+01 -4.47727735e+01 -1.39256628e+01 -3.32121575e+00 2.48160127e+01 2.19063760e+01
+ 2.83944855e+00 -4.50522337e+01 -3.68776005e+01 -1.47576729e+01 -1.19911863e+01 -8.75366538e+00
+ -8.97656602e+00 -1.40499000e+01 3.92627525e+01 4.88037864e+01 -1.43789189e+01 -4.79625297e+00
+ 3.16291704e+01 3.20168152e+01 5.52277932e+00 -7.98410630e+01 -2.41788753e+01 -1.57596645e+01
+ 1.58930283e+01 1.04667104e+01 -4.39057154e+01 -2.04884565e+01 8.07593937e+01 6.80229829e+00
+ 2.23284907e+01 -6.94941558e+01 -5.16156062e+00 4.88867716e+01 4.01995064e+00 -3.04376362e+00
+ 3.14062302e+01 -2.00952330e+01 -5.51259434e+01 5.05988423e-01 2.08599646e+01 1.50816325e+01
+ -1.29696080e+01 3.72548221e+01 1.81009320e+01 5.10766991e+01 1.82053491e+01 1.98473834e+01
+ -4.54854892e+01 -4.53453683e+01 -4.22794830e+00 -1.58693488e+01 -6.07271867e+00 -1.99631436e+00
+ -9.25461576e+00 4.50241444e+01 7.02878753e+01 -4.44483888e+01 2.63164730e+00 4.15336265e+00
+ -5.11588738e+01 -2.77586316e+01 1.97999488e+01 -9.87881525e+00 6.34125456e+01 4.83124190e+01
+ -8.94084134e+00 -1.34814529e+01 -4.49601913e+01 5.28390455e+01 -1.72582148e+01 -1.59438499e+00
+ 2.31799880e+01 -3.00373757e+00 3.31620321e+01 3.15423901e+01 2.91110463e+01 2.59326679e+01
+ -2.84665305e+01 -1.06868238e+01 8.87542554e+01 -3.88024366e+00 1.75880577e+01 1.37336245e+01
+ -1.06577981e+01 7.43021469e+00 -2.09450218e+01 -1.76491054e+01 -1.12815357e+01 -1.08000535e+01
+ -3.56182243e+01 -6.90300711e+00 3.92829138e+00 2.69695474e+01 2.88940235e+00 5.01684684e+00
+ -3.78262741e+00 -1.92095454e+01 -1.05567529e+01 -6.77467970e+01 2.03733175e+01 2.95520123e+01
+ 5.38108573e+01 -3.38374433e+01 -2.78223132e+01 -7.73288956e+00 -3.13462176e+01 -2.35677556e+01
+ -3.88761929e+01 -1.77679216e+01 1.14569557e+01 2.84607024e+01 5.07005660e+01 -1.92487580e+01
+ -4.46024476e+01 -6.02805570e+01 5.63500111e+01 2.17544648e+01 5.23676894e+00 7.66608298e+00
+ -3.80758080e+00 -3.91424613e+01 2.88304674e+01 -3.09285226e+00 -4.27534207e+01 -2.51802947e+01
+ 4.52558846e+01 2.88741805e+01 6.00723263e+01 6.44609745e+01 3.51202685e+00 -2.78829813e+01
diff --git a/codec2/branches/0.7/src/codebook/lspmelvq3.txt b/codec2/branches/0.7/src/codebook/lspmelvq3.txt
new file mode 100644 (file)
index 0000000..17b4d18
--- /dev/null
@@ -0,0 +1,65 @@
+ 6 64
+ -9.63558134e+00 2.75500520e+01 1.54445352e+01 -4.34872231e+00 -1.85869537e+00 1.27053793e+00
+ -1.55342902e+01 2.30514670e+01 -1.54436233e+01 -2.01886592e+00 -6.19433520e+00 -1.35084579e+01
+ 8.38867370e+00 -1.60997829e+00 -3.23903372e+01 1.01764745e+01 1.94669519e+00 1.22453903e+01
+ -3.06305579e+00 -9.55983454e+00 1.43669912e+01 -1.87158872e+00 1.96192339e+01 -3.78366429e+00
+ -1.84949911e+01 -1.33811009e+01 -2.38928068e+01 -2.03745297e+01 -6.87856219e+00 -1.74886898e+01
+ 1.54924765e+01 1.47070114e+01 -6.97854547e-02 1.57541015e+01 1.26051117e+01 -3.19767598e+00
+ 9.60466380e+00 -4.56494120e+00 1.01616352e+01 1.55593699e+01 6.89224494e+00 -3.15602059e+01
+ -1.15624623e+01 -2.30872118e+01 3.49162756e+01 1.23051800e+01 7.67426494e+00 -1.26297575e+00
+ 2.54859847e+00 -3.90250852e+00 -1.91132460e+01 7.61309526e+00 -3.10016268e+01 1.24758542e+01
+ 2.74156140e+00 1.24123828e+01 -3.95057506e+01 -3.25024460e-01 -2.29186113e+01 -2.85606286e+01
+ 6.30148114e+00 1.54401829e+01 -2.62839880e+00 -2.01603121e+01 5.22906241e+00 -1.23450527e+01
+ -6.91861647e+00 1.66334555e+01 -1.65064009e+00 2.99602193e+00 -2.39479486e+01 -1.43946621e+00
+ -1.43906662e+01 -3.14169988e+01 1.01112600e+01 1.70013058e+00 -2.15732981e+01 4.73599588e+00
+ -1.67171131e+00 6.22750796e+00 -1.37186892e+01 2.10936412e+01 -9.69243460e+00 -1.05755505e+01
+ 2.15265759e+00 2.12197974e+01 -1.30171434e+01 -1.43134936e+00 1.88830899e+01 1.06664329e+01
+ 1.38912823e+01 2.73564952e+01 4.72837867e-01 -7.40477398e+00 -1.48704788e+01 2.57448101e+01
+ 2.84020077e+01 -2.05484249e+00 -9.32712325e+00 -1.73169289e+01 1.56430267e+01 6.96908165e+00
+ -1.58630340e+01 -1.78482175e+01 -2.49238306e+01 1.25573572e+01 7.17565614e+00 1.61971650e-02
+ 5.99290542e+00 -4.10228475e+01 1.95790603e+00 -6.78011978e+00 9.20162437e+00 4.62340214e+00
+ -6.33628710e+00 -7.61678949e+00 2.77318403e+01 -8.92139602e+00 -1.41931012e+01 7.88246832e+00
+ -1.22367255e+01 -2.12449687e+01 -2.59270048e+00 1.37776088e+01 -2.78639807e+00 -2.45071888e+01
+ 2.31499628e+01 -9.93687285e+00 -2.92558947e+00 3.88086233e+00 1.12667187e+01 1.11998192e+01
+ 9.67437083e+00 -9.42689854e+00 6.25820343e+00 3.65694017e+01 2.88654337e+00 1.82051686e+00
+ 1.53850350e+01 -2.88243395e+00 1.98376862e+01 -1.45110879e+01 5.92264164e+00 -2.55757052e+00
+ -2.09648354e+01 3.76147238e+00 1.85073811e+01 -1.35546710e+01 -7.84260856e+00 -1.99799886e+01
+ 2.46031823e+01 1.69890405e+01 -1.91622335e+01 1.35534708e+00 -1.22027387e-02 1.66227368e-01
+ 9.98886112e+00 -6.89665978e+00 -2.05111005e+01 -2.89196132e+00 2.58467075e+00 -1.70490443e+01
+ -9.17760933e+00 -2.37209261e+01 1.26087522e+01 -1.82653678e+01 2.17717972e+00 -1.30865104e+01
+ -9.73325636e+00 -1.22681927e+01 6.80913709e+00 2.03469383e+01 -1.02912141e+01 4.85191264e+00
+ -5.19405971e+00 6.78013590e+00 1.80099171e+01 1.43782234e+01 -1.24328209e-01 -1.00140628e+01
+ -4.69805841e+00 6.71393347e+00 -1.91371131e+01 8.19813751e+00 2.33986930e+01 -1.03316046e+01
+ 1.02965114e+00 -4.63654206e+00 2.19822248e+01 1.15087729e+01 -3.09616861e+01 -2.06353989e+01
+ -3.32824280e+01 3.14666327e+01 -1.14836699e+01 1.15143750e+01 -1.36833847e+00 9.44598605e+00
+ -3.75430917e+01 -3.16316521e+00 -2.09497259e+00 -2.62711963e+00 4.04714006e+01 -3.30527290e+01
+ -8.79595013e+00 -1.55173952e+01 -1.57915761e+01 7.97003454e+00 3.72542479e+01 4.07063036e+01
+ -1.47261309e+01 -1.26883966e+01 2.42105009e+00 -1.02685695e+01 2.59032576e+01 1.48524666e+01
+ 2.29597589e+01 -1.66223954e+01 -3.64948776e+00 4.44268970e+00 -2.23896609e+01 1.36968303e+01
+ -1.08740414e+01 4.18930892e+00 -2.42283549e+01 -3.63763568e+00 -1.51378968e+01 4.09515145e+01
+ 2.82393122e+01 -8.63224808e+00 -1.25439700e+01 2.88282453e+01 -9.87894477e-01 -4.98239761e+00
+ -2.50777306e+01 -4.81677621e-01 -3.37082359e+00 5.55113597e+00 -9.89897733e+00 -8.07628392e+00
+ 2.33580811e+01 3.12034460e+00 -8.63347483e+00 6.30419907e-01 -1.82215617e+01 -2.21886118e+01
+ 4.49504750e+01 1.98266721e+01 2.37129225e+01 8.58074741e+00 7.80458003e+00 1.78796190e+00
+ -8.13112376e+00 -2.12620216e+00 -7.12776152e+00 -2.50528525e+01 -1.67286912e+01 8.41402395e+00
+ 2.01964856e+00 1.92578572e+01 2.00963154e+01 5.99198987e+00 2.81097545e+01 5.96128119e+00
+ 2.42492523e+00 -6.33215684e+00 -2.65858257e+01 -2.38606757e+01 8.27049181e+00 3.05804887e+00
+ 1.53248169e-02 4.46111848e-01 -4.92759469e+00 1.90023172e+01 2.27345854e+01 1.55450838e+01
+ -7.39591162e+00 4.02849951e+01 1.08413779e+01 2.57961044e+01 -8.81069145e+00 -1.34999568e+01
+ 5.81305664e+00 1.12384032e+01 6.93765484e+00 -9.43066771e+00 9.51417968e+00 2.29708947e+01
+ -9.17611356e+00 -1.64993397e+01 -1.56928999e+00 -2.91110450e+00 4.17112939e+00 1.09227968e+01
+ 1.00375713e+01 -2.74993429e+01 -8.25331597e+00 -1.71500301e+00 -1.15063443e+01 -1.04669902e+01
+ 2.36636508e+01 -1.38337857e+01 1.47284089e+01 8.00341253e+00 -2.71880968e+00 -8.80708335e+00
+ 2.71009769e+01 2.42801325e+00 1.14599376e+01 -2.41577495e+01 -2.09900573e+01 4.52357891e+00
+ 1.68065353e+01 1.93315410e+01 1.11219486e+01 1.33391053e+01 -1.31522072e+01 9.14279911e-01
+ -2.52603434e+01 6.04836929e+00 1.21994481e+01 2.19372400e+01 1.48794817e+01 6.93368419e+00
+ -1.24639103e+00 -7.96856388e+00 1.64064238e+01 -2.36409457e+00 -2.59092550e+01 4.60937831e+01
+ 8.81686599e+00 2.48004312e+01 1.14474515e+01 -1.32610170e+01 -1.98693483e+01 -2.84792661e+01
+ 1.53175060e+01 -1.25335244e+01 2.41777946e+01 1.05132987e+01 2.22243698e+01 9.93190900e+00
+ -1.87981919e+01 3.89390253e+01 -2.00631273e+01 -3.54051693e+01 7.58790045e+00 -5.99372720e-01
+ -1.81387622e+01 9.58429879e+00 1.74375056e+01 -2.10570251e+01 8.16340142e+00 6.31215716e+00
+ -6.15485876e+01 -8.71159172e+00 1.97501971e+01 -2.52365495e+01 3.56558072e+00 -1.64973217e+00
+ -2.69862835e+01 2.91016925e-01 -1.25336894e+01 -1.05049848e+01 1.10613561e+01 4.84071822e+00
+ -6.30579095e-01 -3.87056005e+00 -7.07794677e-01 -1.31305521e+01 -1.96547570e+01 -1.62436152e+01
+ 4.87021595e+00 -5.90743926e+00 3.46971058e+00 -4.00865595e+01 1.68740955e+01 1.03332584e+01
+ -1.00985334e+00 1.62339777e+01 -4.75836148e-01 2.83847633e+01 1.75473354e+00 2.82608265e+01
diff --git a/codec2/branches/0.7/src/codebook/lspres_bw1.txt b/codec2/branches/0.7/src/codebook/lspres_bw1.txt
new file mode 100644 (file)
index 0000000..2d24a67
--- /dev/null
@@ -0,0 +1,5 @@
+1 4
+35
+80
+140
+250
diff --git a/codec2/branches/0.7/src/codebook/lspres_bw2.txt b/codec2/branches/0.7/src/codebook/lspres_bw2.txt
new file mode 100644 (file)
index 0000000..c7a3e39
--- /dev/null
@@ -0,0 +1,10 @@
+1 8
+50
+100
+200
+400
+500
+600
+800
+1000
+
diff --git a/codec2/branches/0.7/src/codebook/lspres_centre1.txt b/codec2/branches/0.7/src/codebook/lspres_centre1.txt
new file mode 100644 (file)
index 0000000..111a734
--- /dev/null
@@ -0,0 +1,9 @@
+1 8
+300
+350
+400
+450
+500
+550
+600
+650
diff --git a/codec2/branches/0.7/src/codebook/lspres_centre2.txt b/codec2/branches/0.7/src/codebook/lspres_centre2.txt
new file mode 100644 (file)
index 0000000..ee8dd3e
--- /dev/null
@@ -0,0 +1,10 @@
+1 8
+500
+600
+750
+900
+1100
+1300
+1500
+1700
+
diff --git a/codec2/branches/0.7/src/codebook/lspvqanssi1.txt b/codec2/branches/0.7/src/codebook/lspvqanssi1.txt
new file mode 100644 (file)
index 0000000..0b9dd90
--- /dev/null
@@ -0,0 +1,257 @@
+10 256
+0.5862 0.7213 0.9146 1.0909 1.2910 1.4954 1.8370 2.0840 2.3771 2.5518
+0.0871 0.2049 0.5849 0.8552 1.2096 1.4686 1.8210 2.0926 2.4508 2.7389
+0.2274 0.3126 0.6088 0.8338 1.1824 1.5948 1.8228 1.9856 2.1832 2.4793
+0.1827 0.2706 0.5842 0.7761 1.0301 1.2462 1.6313 1.9786 2.3479 2.6790
+0.3055 0.3863 0.7194 1.1609 1.3303 1.5017 1.7265 1.9412 2.4659 2.6315
+0.1794 0.2522 0.5477 0.7892 1.3887 1.7101 1.9471 2.1667 2.4361 2.6310
+0.1825 0.2729 0.4185 0.6024 1.2531 1.7291 1.9937 2.1849 2.5865 2.7748
+0.3219 0.4045 0.7357 1.2708 1.4626 1.6439 1.9388 2.1212 2.5005 2.6749
+0.2234 0.3496 0.5054 0.6981 0.8672 1.0431 1.7091 2.0690 2.3290 2.6195
+0.3009 0.3957 0.7576 0.9751 1.1955 1.7727 2.0383 2.2474 2.5612 2.7188
+0.3841 0.5544 0.9209 1.1811 1.5441 1.8126 2.1175 2.3192 2.5486 2.6935
+0.2153 0.3105 0.5597 0.8313 1.2168 1.4512 1.7012 1.8962 2.3893 2.5852
+0.3196 0.4814 0.7629 1.0869 1.5517 1.7780 2.0462 2.2547 2.5023 2.6706
+0.1964 0.3055 0.4307 0.7178 1.4260 1.6240 1.8392 2.0576 2.2976 2.5492
+0.4260 0.6888 1.2019 1.4194 1.6437 1.8221 2.0469 2.2508 2.5142 2.6795
+0.3004 0.3944 0.5847 1.0050 1.1812 1.3559 1.5479 1.7847 2.4924 2.6703
+0.1595 0.2398 0.4336 0.9228 1.2602 1.5064 1.7915 1.9840 2.2320 2.5692
+0.1832 0.2985 0.4205 0.5980 0.7620 0.9894 1.7499 2.1151 2.4814 2.7214
+0.2234 0.3207 0.5457 0.9799 1.2074 1.7079 1.9734 2.1742 2.4575 2.6366
+0.3598 0.4819 0.6385 0.8878 1.3226 1.4910 1.7257 1.9456 2.2061 2.4579
+0.4671 0.5911 0.8513 1.0923 1.5104 1.7043 1.9727 2.1839 2.4484 2.6111
+0.2418 0.3937 0.5420 0.8971 1.1152 1.3054 1.7928 1.9796 2.5441 2.7572
+0.3541 0.4730 0.6546 0.9063 1.0792 1.2743 1.8545 2.0555 2.3083 2.5404
+0.3121 0.4016 0.7137 0.8835 1.0736 1.5907 1.8624 2.0857 2.5075 2.6668
+0.2232 0.3631 0.5273 0.7438 1.0492 1.2235 1.5449 2.2198 2.5160 2.6852
+0.2557 0.3528 0.5051 0.6528 0.8351 1.5688 1.8838 2.1056 2.4401 2.6111
+0.4342 0.5318 0.9234 1.1146 1.3015 1.5198 1.8211 2.0340 2.3694 2.5506
+0.4310 0.5269 0.7431 0.9018 1.0734 1.5196 1.8267 2.0244 2.4508 2.6177
+0.2150 0.3249 0.4966 0.9434 1.1627 1.3497 1.8003 2.0045 2.3567 2.5909
+0.2798 0.4111 0.5786 0.7971 1.0414 1.2142 1.6947 2.0866 2.3351 2.5545
+0.1688 0.2693 0.4004 0.6337 1.3058 1.5064 1.7535 1.9689 2.5542 2.7424
+0.4419 0.6209 1.0127 1.2135 1.4104 1.6111 1.8820 2.1005 2.4238 2.5966
+0.3645 0.5120 0.8977 1.2209 1.5286 1.7204 1.9787 2.1779 2.4390 2.6114
+0.2897 0.4136 0.5504 0.8515 1.2641 1.4334 1.8079 2.0656 2.3509 2.7593
+0.1611 0.4723 0.7420 1.0071 1.2571 1.5891 1.9224 2.2345 2.5647 2.7991
+0.2528 0.4178 0.8909 1.3117 1.6622 1.8641 2.1017 2.2974 2.5299 2.6982
+0.1749 0.2700 0.4116 0.6036 1.1430 1.7776 2.0394 2.2220 2.4667 2.6598
+0.3451 0.4325 0.6194 0.7406 0.9176 1.5540 1.8426 2.0479 2.4401 2.5965
+0.3672 0.5164 0.6558 0.8441 1.2332 1.4114 1.6955 2.0875 2.3674 2.5471
+0.2194 0.3467 0.7384 1.1079 1.5398 1.8437 2.1212 2.3296 2.5800 2.7403
+0.1525 0.2343 0.3915 0.6843 1.0517 1.5020 1.7905 1.9667 2.2027 2.6725
+0.3531 0.5908 0.7462 0.9441 1.2774 1.4743 1.8268 2.1059 2.4478 2.6484
+0.3611 0.4981 0.7598 0.9676 1.4024 1.6330 1.9094 2.1433 2.4408 2.6130
+0.2153 0.3366 0.4974 0.6693 1.1944 1.6791 1.9002 2.1105 2.4100 2.5922
+0.2421 0.3392 0.5123 0.9818 1.5411 1.7092 1.9989 2.1981 2.5659 2.7656
+0.2116 0.3250 0.4845 0.8021 1.0088 1.2158 1.8038 2.0223 2.2975 2.5810
+0.1902 0.2942 0.8003 1.1086 1.3606 1.6008 1.8956 2.1328 2.4481 2.6405
+0.2772 0.3914 0.5826 0.7654 0.9495 1.1240 1.3949 2.0411 2.3891 2.5959
+0.2678 0.5220 0.7630 1.1000 1.3747 1.6432 1.9391 2.2237 2.5511 2.7893
+0.3200 0.4245 0.6174 0.9904 1.1662 1.3882 1.7601 1.9524 2.3998 2.5819
+0.1702 0.4871 0.8370 1.0989 1.3593 1.5830 1.8750 2.1277 2.4666 2.6885
+0.2280 0.3748 0.6554 0.9113 1.2081 1.4619 1.8181 2.0541 2.3791 2.5701
+0.1752 0.4363 0.6454 0.8798 1.1079 1.5367 1.8667 2.1716 2.4804 2.7249
+0.3804 0.4700 0.8224 1.0099 1.1892 1.5906 1.8879 2.0907 2.4544 2.6238
+0.1808 0.2910 0.4683 0.7059 0.8980 1.4031 1.7063 1.9444 2.4658 2.6776
+0.2418 0.3803 0.5443 0.7589 1.1496 1.3185 1.5451 1.7433 2.1310 2.6523
+0.2698 0.3690 0.5362 1.0732 1.2921 1.4696 1.7440 1.9470 2.5051 2.6841
+0.4099 0.5102 0.6983 1.0468 1.2459 1.4185 1.8851 2.0815 2.3464 2.5605
+0.0669 0.1354 0.3764 0.8433 1.1719 1.4834 1.8181 2.1312 2.4626 2.8044
+0.1614 0.2372 0.3878 0.5708 1.2759 1.4950 1.8052 2.0807 2.3485 2.6293
+0.1688 0.2875 0.4301 0.9059 1.2361 1.4054 1.8057 1.9924 2.5589 2.7495
+0.2864 0.3783 0.7032 1.0817 1.2382 1.5741 1.8619 2.0656 2.5139 2.6848
+0.3829 0.4781 0.6766 0.8340 1.0056 1.4147 1.6650 1.8840 2.3922 2.5619
+0.3259 0.4187 0.6139 0.7338 1.1831 1.6497 1.9000 2.1278 2.4322 2.5930
+0.2569 0.3790 0.5426 0.8390 0.9871 1.4850 1.8652 2.0732 2.4314 2.6005
+0.1408 0.2283 0.4024 0.8784 1.1485 1.4003 1.7004 1.9205 2.3723 2.6522
+0.2971 0.5039 0.8005 1.1212 1.4232 1.7801 2.1255 2.3907 2.6795 2.8487
+0.1515 0.2344 0.4684 0.8040 1.0401 1.3774 1.8329 2.1235 2.5555 2.7770
+0.5778 0.7157 0.8910 1.0966 1.4235 1.6482 1.9551 2.1831 2.4572 2.6234
+0.3017 0.4161 0.8088 0.9971 1.2000 1.4419 1.7867 2.0224 2.3473 2.5400
+0.1208 0.2814 0.6564 0.9448 1.2377 1.5663 1.9084 2.2112 2.5583 2.8155
+0.2127 0.3127 0.4635 0.6416 0.8449 1.6652 2.0577 2.2656 2.5811 2.7434
+0.1942 0.3011 0.4212 0.6901 1.5369 1.7639 1.9608 2.1766 2.4435 2.6663
+0.3510 0.4345 0.7146 0.9086 1.0678 1.2579 1.4425 2.0265 2.4574 2.6252
+0.3225 0.4323 0.6168 0.8580 1.5388 1.7910 1.9927 2.2013 2.4494 2.6160
+0.2271 0.4488 0.6287 0.7857 1.2086 1.3830 1.6194 2.1955 2.5236 2.6945
+0.2568 0.3510 0.5613 1.0500 1.2521 1.4359 1.6995 1.9187 2.2148 2.4275
+0.2933 0.3941 0.6128 0.8899 1.0720 1.2862 1.5331 1.8301 2.1553 2.3865
+0.3480 0.4626 0.6009 0.7630 0.9044 1.1225 1.8539 2.1845 2.5035 2.7091
+0.1337 0.4722 0.8099 1.1273 1.4252 1.6990 2.0188 2.2922 2.6018 2.8168
+0.1138 0.3263 0.8059 1.0473 1.3262 1.6202 1.9439 2.2007 2.5347 2.7702
+0.1979 0.3130 0.4635 0.8504 1.1143 1.3221 2.0371 2.2421 2.5406 2.7491
+0.3321 0.4194 0.8239 1.0458 1.1981 1.3733 1.5661 1.9985 2.3747 2.5416
+0.3729 0.5958 0.9551 1.2650 1.5484 1.9255 2.2256 2.4809 2.7276 2.8935
+0.1664 0.2516 0.5347 0.7545 1.1971 1.4089 1.7400 2.0871 2.4098 2.6795
+0.2370 0.3178 0.6123 1.3315 1.5470 1.7257 2.0063 2.1977 2.5449 2.7252
+0.2030 0.3328 0.4766 0.7357 1.2780 1.4439 1.7229 1.9405 2.2278 2.6816
+0.1702 0.2919 0.4598 0.7123 0.9077 1.1450 1.8632 2.0806 2.4990 2.7100
+0.2421 0.3578 0.5400 0.7217 0.8971 1.4898 1.8518 2.1205 2.6077 2.7894
+0.3030 0.3935 0.5812 0.7404 0.9425 1.8342 2.0887 2.2811 2.5596 2.7118
+0.1322 0.1997 0.3466 0.6981 1.1811 1.4849 1.8594 2.1114 2.4708 2.7804
+0.2317 0.3069 0.6860 1.4306 1.7121 1.8671 2.1249 2.2995 2.5705 2.7456
+0.3778 0.4863 0.6639 0.9163 1.1560 1.3186 1.5389 1.7169 2.1603 2.5797
+0.2118 0.3499 0.5259 0.7200 1.1348 1.3140 1.5657 2.0241 2.2873 2.5184
+0.2902 0.4368 0.6331 0.8971 1.3102 1.5219 1.8674 2.1512 2.4708 2.6809
+0.1418 0.3988 0.6251 0.8544 1.1268 1.3964 1.7585 2.0322 2.3964 2.6928
+0.2314 0.3462 0.7282 0.9211 1.1766 1.4941 1.7368 1.9546 2.5170 2.7066
+0.2076 0.3251 0.7423 0.9590 1.1936 1.5329 1.8887 2.1588 2.4667 2.6709
+0.2058 0.4139 0.5745 0.7832 0.9595 1.1688 1.7561 1.9562 2.4840 2.7001
+0.1834 0.2971 0.4643 0.6625 0.8802 1.1137 1.5183 1.8417 2.3842 2.7042
+0.1688 0.4218 0.7070 1.0465 1.4496 1.6953 1.9560 2.2174 2.5172 2.7404
+0.2323 0.3981 0.5489 0.7227 1.2886 1.5221 1.7158 2.1184 2.4066 2.5898
+0.3470 0.5265 0.8140 1.0152 1.3206 1.5411 1.8490 2.0588 2.3556 2.5393
+0.1707 0.2595 0.6762 0.9037 1.2781 1.4903 1.7946 2.0610 2.3741 2.5771
+0.1457 0.2318 0.6039 1.0078 1.3461 1.5908 1.8818 2.1248 2.4432 2.6714
+0.6574 0.8086 1.0243 1.2183 1.4837 1.7129 2.0197 2.2464 2.5059 2.6716
+0.2546 0.4983 0.8674 1.2536 1.6704 1.9529 2.2134 2.4319 2.6532 2.8109
+0.2455 0.3379 0.4632 0.8635 1.5286 1.8047 1.9909 2.1806 2.4031 2.5729
+0.4772 0.6742 1.0000 1.2474 1.5288 1.7415 2.0102 2.2168 2.4770 2.6449
+0.3357 0.4382 0.6033 1.1317 1.3681 1.5576 1.9251 2.1119 2.5548 2.7395
+0.2588 0.7015 0.8953 1.0830 1.2828 1.5160 1.8965 2.1921 2.5150 2.7258
+0.2466 0.3512 0.5047 0.6646 0.8161 1.2577 1.8046 2.0214 2.4447 2.6491
+0.1631 0.2283 0.4070 0.5955 1.1126 1.3894 1.8978 2.1849 2.5384 2.7382
+0.3424 0.4748 0.6222 0.8020 0.9706 1.1568 1.7044 1.9297 2.2127 2.5627
+0.2088 0.5143 0.7400 0.9277 1.1032 1.3561 1.8841 2.2004 2.5882 2.7993
+0.2016 0.3488 0.5894 0.7419 1.1488 1.3626 1.5566 1.9694 2.5488 2.7209
+0.2558 0.3914 0.5360 0.7521 1.4330 1.6955 1.8886 2.1428 2.4190 2.5966
+0.4021 0.5034 0.6653 0.8123 0.9586 1.2825 1.9184 2.1120 2.4090 2.5970
+0.2343 0.4800 0.6934 0.8523 1.2786 1.4763 1.7235 2.0400 2.3602 2.5562
+0.2460 0.3687 0.5325 0.7044 1.1488 1.3608 1.8112 2.0757 2.4183 2.6630
+0.1616 0.3644 0.5725 0.9166 1.2481 1.4938 1.8388 2.1175 2.4712 2.7464
+0.3760 0.4841 0.6350 1.0082 1.2110 1.4003 1.8127 2.0018 2.5199 2.7238
+0.1988 0.2824 0.6553 1.0337 1.5413 1.7369 1.9751 2.1751 2.4372 2.6265
+0.2728 0.4094 0.7498 1.0645 1.3516 1.5946 1.9910 2.2172 2.4830 2.6614
+0.1657 0.5327 0.7281 0.9966 1.2385 1.4629 1.8119 2.0973 2.4469 2.6979
+0.1413 0.2098 0.3540 0.5492 0.8486 1.1288 1.6320 1.9056 2.2805 2.5438
+0.2856 0.3666 0.6259 1.1424 1.6605 1.8197 2.0147 2.1986 2.4121 2.5919
+0.2725 0.4829 0.7650 1.0119 1.2977 1.5488 1.8755 2.1155 2.4383 2.6377
+0.2736 0.3804 0.5537 1.0258 1.2269 1.4186 1.9718 2.1468 2.5665 2.7689
+0.2341 0.5953 1.1030 1.4549 1.7361 1.9758 2.2126 2.4213 2.6405 2.8181
+0.2273 0.4638 0.6228 0.8500 1.1016 1.2823 1.7094 1.9523 2.2669 2.7029
+0.2438 0.3798 0.7299 0.9600 1.3765 1.6104 1.8644 2.1161 2.5073 2.7137
+0.1551 0.4869 0.8676 1.2274 1.5069 1.8857 2.1868 2.4411 2.7106 2.8767
+0.2746 0.5454 0.7589 0.9458 1.1597 1.3349 1.6653 2.1142 2.4356 2.6239
+0.1793 0.2646 0.4344 0.7482 1.1502 1.3733 1.8558 2.0817 2.3248 2.5171
+0.2698 0.4202 0.5765 0.8301 1.0073 1.2101 1.9714 2.2051 2.5138 2.7395
+0.1929 0.3091 0.4460 0.6266 1.1805 1.3672 1.5990 2.1514 2.4729 2.6468
+0.1901 0.3047 0.4607 1.1019 1.3168 1.5343 1.9234 2.1365 2.5924 2.7807
+0.3139 0.5009 0.6700 0.8268 1.0117 1.1810 1.6539 2.1984 2.4828 2.6576
+0.1403 0.2173 0.4117 0.7302 1.0038 1.2732 1.7392 2.0337 2.3809 2.7386
+0.4166 0.5101 0.7449 1.1663 1.3492 1.5543 1.9000 2.0941 2.4588 2.6365
+0.3342 0.4335 0.6160 0.8559 1.0112 1.2097 1.4029 1.6361 2.4129 2.6324
+0.4543 0.6159 0.7932 0.9843 1.2562 1.4308 1.7116 1.9919 2.2671 2.4631
+0.2153 0.3609 0.5302 0.7089 0.8756 1.0376 1.6496 2.2826 2.5680 2.7441
+0.4380 0.6439 0.8282 1.0651 1.3650 1.5829 1.8838 2.1005 2.4006 2.5771
+0.2523 0.3636 0.5879 1.1628 1.3542 1.6756 2.0488 2.2543 2.6093 2.7953
+0.4179 0.5426 0.7065 0.8996 1.0684 1.3146 1.9705 2.2021 2.5051 2.7061
+0.1659 0.2860 0.6693 0.9229 1.3959 1.6544 1.9709 2.2257 2.5236 2.7460
+0.2540 0.4356 0.5946 0.7627 1.2274 1.4222 1.6573 1.9601 2.2514 2.4711
+0.1633 0.2337 0.3698 0.5421 1.1757 1.5916 2.1561 2.3371 2.5534 2.7737
+0.1953 0.2730 0.4521 1.2005 1.7062 1.8627 2.1313 2.3266 2.5906 2.7667
+0.3053 0.4054 0.5651 0.7470 0.8910 1.1720 1.8864 2.1074 2.3705 2.5744
+0.1761 0.3033 0.6501 0.8268 1.0369 1.2687 1.8534 2.1889 2.5074 2.7339
+0.2265 0.3990 1.1359 1.4137 1.6839 1.8912 2.0948 2.3042 2.5489 2.7234
+0.3326 0.5400 0.8711 1.0948 1.3752 1.6155 1.9360 2.1537 2.4451 2.6133
+0.2162 0.3522 0.5309 0.7470 0.9677 1.1747 1.5056 1.7942 2.1615 2.4800
+0.1872 0.2761 0.4053 0.7469 1.5858 1.8945 2.1198 2.3197 2.5819 2.7758
+0.5381 0.8651 1.2695 1.4918 1.7774 1.9696 2.1865 2.3687 2.5739 2.7158
+0.2663 0.3422 0.6098 1.2120 1.4516 1.6092 1.8506 2.0376 2.2929 2.5088
+0.1904 0.3051 0.5663 0.7391 1.1589 1.5705 1.8756 2.1653 2.5518 2.7693
+0.1543 0.3519 0.6976 1.0664 1.3696 1.7817 2.1308 2.4259 2.7070 2.8753
+0.3304 0.4283 0.5942 0.7425 0.8906 1.4067 2.0676 2.2460 2.5394 2.7006
+0.2080 0.3215 0.6278 0.7882 1.3123 1.5592 1.8048 2.0831 2.4303 2.6266
+0.1188 0.2481 0.8270 1.2420 1.5824 1.8976 2.1816 2.4248 2.6645 2.8459
+0.0635 0.1528 0.5973 0.9377 1.2653 1.5465 1.8818 2.1681 2.5089 2.7924
+0.3249 0.5179 0.9143 1.2973 1.4966 1.7550 2.0715 2.3166 2.6500 2.8305
+0.1918 0.3107 0.4506 0.6994 1.3463 1.5348 1.8447 2.1903 2.4480 2.6877
+0.3405 0.4644 0.7232 0.9199 1.2611 1.5175 1.8446 2.0652 2.3915 2.5781
+0.3289 0.5152 0.6602 1.0213 1.1886 1.5496 1.9553 2.1883 2.5394 2.7362
+0.3000 0.4097 0.8372 1.0793 1.3095 1.5684 1.8746 2.0783 2.3643 2.5490
+0.2421 0.3280 0.5288 0.9261 1.6911 1.8959 2.1013 2.2823 2.5238 2.6960
+0.1070 0.3131 0.6226 0.8881 1.1808 1.4867 1.8146 2.1088 2.4594 2.7186
+0.4400 0.5533 0.7025 0.9206 1.4089 1.5820 1.8080 2.0832 2.3577 2.5300
+0.2250 0.3434 0.4808 0.6721 0.8198 1.1446 2.0201 2.2625 2.5520 2.7604
+0.1671 0.2551 0.4603 0.6777 0.9661 1.5579 1.8659 2.1196 2.4425 2.6551
+0.3910 0.5877 1.0287 1.3547 1.6899 1.9166 2.1451 2.3337 2.5519 2.7071
+0.1435 0.2165 0.3968 0.8376 1.2572 1.5298 1.8791 2.1352 2.4636 2.7011
+0.1756 0.2799 0.4120 0.5808 0.7573 1.3340 1.8235 2.1200 2.4993 2.7365
+0.1332 0.2174 0.4716 0.9483 1.2723 1.6028 1.9272 2.2190 2.5588 2.7990
+0.2122 0.3143 0.7042 0.8849 1.1312 1.3711 1.6832 1.9633 2.2685 2.5156
+0.2089 0.3339 0.4817 0.8526 1.0657 1.2741 1.5747 1.8000 2.4860 2.6843
+0.1636 0.2617 0.4400 0.7357 1.0355 1.2638 1.5672 1.8504 2.1904 2.6588
+0.1945 0.2934 0.4869 0.8567 1.1262 1.3604 1.6898 1.9143 2.1475 2.3503
+0.1606 0.2442 0.3931 0.9237 1.5811 1.7529 2.0133 2.2272 2.5250 2.7265
+0.4866 0.7045 1.0593 1.2795 1.5326 1.8221 2.1461 2.3665 2.6041 2.7599
+0.4012 0.4911 0.7103 0.8585 1.0495 1.7244 2.0116 2.2041 2.5189 2.6643
+0.4365 0.6694 0.8644 1.1330 1.4510 1.7627 2.1032 2.3690 2.6280 2.8306
+0.2072 0.4018 0.6227 0.8913 1.3038 1.6056 1.9704 2.2816 2.6135 2.8182
+0.3302 0.4968 0.8713 1.0761 1.2576 1.4654 1.8152 2.1400 2.5404 2.7493
+0.1385 0.2292 0.3530 0.6006 1.4699 1.6571 1.9438 2.1663 2.5027 2.7308
+0.1894 0.2915 0.4345 0.6341 1.0024 1.1896 1.6896 2.0966 2.4086 2.6768
+0.3841 0.5197 0.8889 1.1480 1.4383 1.6285 1.8642 2.0669 2.3466 2.5325
+0.2008 0.3097 0.4664 0.6638 1.2798 1.4940 1.7270 2.0264 2.2915 2.4750
+0.1864 0.2857 0.4481 1.1025 1.3096 1.5035 1.7614 1.9891 2.4255 2.6031
+0.4081 0.6134 0.9514 1.1818 1.3943 1.6361 1.9891 2.2395 2.5547 2.7287
+0.2964 0.3876 0.9450 1.2247 1.3906 1.5882 1.8241 2.0589 2.4188 2.5871
+0.3127 0.4038 0.6168 1.0810 1.3067 1.4759 1.8817 2.0781 2.3394 2.5539
+0.2066 0.3059 0.4989 0.7132 0.9066 1.4460 1.7584 1.9755 2.2210 2.4741
+0.2634 0.3956 0.5667 0.8777 1.0517 1.6029 2.0590 2.2607 2.6064 2.7647
+0.4331 0.5315 0.7764 1.0444 1.2269 1.4311 1.7093 1.9187 2.4337 2.6149
+0.2161 0.4429 0.6851 0.8336 1.1037 1.2966 1.5283 2.0299 2.3407 2.5384
+0.2814 0.3637 0.5416 0.9475 1.5137 1.6945 1.8892 2.1017 2.3190 2.5007
+0.4454 0.6883 1.1402 1.4098 1.7435 2.0014 2.2521 2.4457 2.6495 2.7985
+0.1641 0.4083 0.6426 1.0592 1.3258 1.5754 1.8666 2.1381 2.4572 2.7177
+0.3391 0.4607 0.6072 0.8463 1.4207 1.6062 1.8303 2.0887 2.3615 2.5348
+0.2414 0.3396 0.5100 0.7470 1.3329 1.8618 2.0751 2.2564 2.5147 2.6874
+0.1694 0.2535 0.4156 0.8302 1.2853 1.5838 2.0907 2.3085 2.5929 2.7951
+0.2047 0.3652 0.6500 0.8068 1.0178 1.1865 1.4889 2.0671 2.5966 2.7634
+0.2425 0.3247 0.6020 1.2226 1.4272 1.5996 1.8377 2.0413 2.5333 2.7021
+0.3842 0.5030 0.6541 0.8771 1.0576 1.2612 1.6744 1.8735 2.4781 2.6803
+0.2042 0.3280 0.7283 0.8985 1.1444 1.3299 1.6032 2.1539 2.4739 2.6547
+0.1268 0.1924 0.3208 0.5153 1.1304 1.4443 1.8047 2.0552 2.4385 2.7572
+0.2713 0.3659 0.5395 1.0705 1.4228 1.5836 1.9763 2.1641 2.4459 2.6301
+0.3047 0.4043 0.5727 0.7368 0.8997 1.3242 1.6473 1.8879 2.4330 2.6295
+0.1224 0.3948 0.6903 0.9199 1.2852 1.5516 1.8645 2.1231 2.4657 2.7044
+0.2157 0.3281 0.5036 0.9272 1.0975 1.5285 1.8080 2.0569 2.5448 2.7221
+0.1670 0.2490 0.3696 0.5921 1.3019 1.8398 2.2165 2.3725 2.6142 2.8338
+0.3899 0.5573 0.8100 1.0732 1.3966 1.6598 2.0001 2.2517 2.5548 2.7403
+0.4905 0.6064 0.8222 0.9966 1.1912 1.5714 1.9628 2.1727 2.5300 2.7055
+0.1309 0.2342 0.6232 0.8795 1.1283 1.3655 1.7371 2.0251 2.3992 2.6885
+0.1805 0.2672 0.4297 1.2440 1.4967 1.6796 1.9592 2.1784 2.5439 2.7289
+0.2280 0.5429 0.6967 0.8732 1.4074 1.6074 1.9516 2.2124 2.5486 2.7722
+0.2339 0.3379 0.4924 0.9061 1.3074 1.4719 1.8884 2.1110 2.3618 2.5545
+0.1384 0.2291 0.5127 1.0450 1.4017 1.7884 2.1134 2.3664 2.6588 2.8435
+0.2196 0.6359 0.9100 1.2007 1.4589 1.7053 2.0128 2.2722 2.5520 2.7643
+0.1698 0.2615 0.3810 0.5706 1.4297 1.8686 2.0728 2.2559 2.4860 2.6701
+0.1445 0.2158 0.3658 0.5451 0.9389 1.3669 1.7900 2.0846 2.3924 2.7161
+0.2789 0.3816 0.5277 0.8487 1.3751 1.5461 1.7832 2.0264 2.2695 2.4665
+0.1733 0.3023 0.9216 1.2368 1.4776 1.7229 1.9952 2.2471 2.5390 2.7265
+0.3374 0.5033 1.0951 1.3262 1.5284 1.7336 1.9733 2.2009 2.4992 2.6751
+0.1293 0.2743 0.7533 1.0166 1.2416 1.4444 1.7962 2.0851 2.4770 2.7204
+0.3106 0.4176 0.6358 0.9434 1.1419 1.3458 1.9638 2.1678 2.4390 2.6235
+0.4533 0.5760 0.7392 0.9136 1.0829 1.2759 1.7903 2.0360 2.3124 2.5325
+0.3702 0.5218 0.6977 0.8776 1.1096 1.2855 1.5612 1.9480 2.2170 2.4361
+0.1637 0.2647 0.4185 0.6666 1.1584 1.3270 1.7829 1.9821 2.4361 2.7094
+0.1769 0.2767 0.3942 0.5746 1.3595 1.7110 1.9176 2.1405 2.3722 2.5705
+0.2712 0.3820 0.6524 0.8317 1.0341 1.3972 1.7312 1.9918 2.3854 2.5886
+0.1003 0.2046 0.7261 1.1004 1.4057 1.6697 1.9903 2.2603 2.5813 2.8009
+0.2534 0.3752 0.7192 0.9323 1.3698 1.5955 1.8653 2.0656 2.3368 2.5340
+0.3589 0.4508 0.6631 1.0521 1.5065 1.6697 1.8929 2.1074 2.3466 2.5242
+0.1955 0.2862 0.6111 0.8053 1.0501 1.5218 1.7996 2.0303 2.3788 2.5973
+0.2982 0.4033 0.5660 0.8924 1.1933 1.3465 1.7895 2.0173 2.2606 2.5069
+0.3356 0.4711 0.6310 0.8491 1.0049 1.4364 1.8176 2.0292 2.5710 2.7525
+0.2016 0.2912 0.4363 0.9800 1.4897 1.6494 1.8862 2.0819 2.3636 2.6091
+0.4549 0.6491 0.8450 1.0209 1.1747 1.3745 1.8824 2.1130 2.3760 2.5768
+0.2510 0.3524 0.5171 0.8931 1.4094 1.5710 1.8536 2.0478 2.4766 2.7320
+0.1576 0.2547 0.3891 0.8551 1.4282 1.5880 1.8583 2.0521 2.5359 2.7340
+0.3481 0.4382 0.7720 1.1289 1.3203 1.5019 1.7665 1.9570 2.2231 2.4465
+0.3116 0.4068 0.6991 0.8894 1.0912 1.5356 1.8084 2.0006 2.2323 2.4367
+0.2706 0.4033 0.8272 1.0851 1.4820 1.6927 1.9292 2.1267 2.4049 2.5857
+0.2745 0.3550 0.8663 1.3742 1.5545 1.7324 1.9664 2.1538 2.4581 2.6245
+0.1736 0.2553 0.5357 0.9009 1.1888 1.5132 1.8579 2.1181 2.4273 2.6847
+0.3026 0.4148 0.9044 1.1695 1.3657 1.7036 1.9891 2.2226 2.5441 2.7085
+0.3998 0.5108 0.7205 0.9848 1.1828 1.3716 1.7154 1.9191 2.1875 2.4257
+0.2141 0.3095 0.7428 1.0426 1.2851 1.5571 1.7901 1.9804 2.2462 2.5265
+0.1574 0.2290 0.3869 0.5735 1.0925 1.3383 1.6598 1.9364 2.2095 2.4195
diff --git a/codec2/branches/0.7/src/codebook/lspvqanssi2.txt b/codec2/branches/0.7/src/codebook/lspvqanssi2.txt
new file mode 100644 (file)
index 0000000..607cb47
--- /dev/null
@@ -0,0 +1,129 @@
+10 128
+0.0120 0.0022 0.0068 -0.0112 -0.0508 -0.0490 0.2249 0.1476 0.0133 -0.0379
+0.0598 0.0477 0.0380 0.0660 0.0517 0.0150 0.0617 0.0081 -0.0768 -0.1007
+-0.0087 -0.0440 0.0873 0.0882 0.0391 -0.0060 0.1100 0.0569 -0.0241 -0.0468
+0.0146 -0.0005 0.0322 -0.0650 -0.0778 -0.0780 -0.0255 -0.0527 -0.0301 -0.0401
+-0.0240 -0.0560 -0.0374 0.0274 0.0484 -0.0227 0.0328 0.1135 0.0117 -0.0300
+-0.0324 -0.0574 0.0302 0.0137 -0.0603 -0.1194 -0.0105 -0.0513 0.0698 0.0538
+0.0635 0.0382 0.0531 0.0897 0.0495 0.0039 -0.0421 -0.0919 0.0407 0.0167
+0.0954 0.0854 0.0360 -0.0025 -0.0252 -0.0528 -0.0435 -0.0561 -0.0405 -0.0432
+0.0110 -0.0010 -0.0433 -0.0167 0.1402 0.0738 0.0423 -0.0024 -0.0920 -0.1099
+0.0179 0.0184 -0.0041 -0.0640 0.1004 0.0608 -0.0023 -0.0357 0.1509 0.1262
+-0.0145 -0.0240 -0.0595 -0.1063 0.0597 -0.0040 -0.0886 0.1184 0.0380 0.0126
+-0.0072 0.0172 0.0076 0.0288 0.0810 0.0278 0.0709 0.0051 0.0214 -0.0301
+0.0127 -0.0126 -0.0434 0.1610 0.1178 0.0704 0.0257 -0.0073 -0.0425 -0.0610
+-0.0165 -0.0369 -0.0785 0.1007 0.0309 -0.0651 0.0142 -0.0614 0.0426 0.0289
+-0.0374 -0.0712 0.0049 -0.0382 0.0472 0.0095 -0.0268 -0.0747 -0.0457 -0.0758
+-0.0211 -0.0432 -0.0547 -0.0446 -0.1078 0.0090 -0.0565 -0.1298 0.0721 0.0351
+-0.0014 -0.0072 -0.0283 -0.0324 -0.0208 -0.0703 0.0979 0.0865 -0.0007 0.1881
+-0.0077 -0.0302 0.1231 0.0905 0.0786 0.0432 -0.0286 -0.0661 -0.0055 -0.0275
+0.0010 0.0043 0.0044 0.0380 -0.1201 -0.0098 -0.0166 0.0105 0.0153 0.0134
+0.0843 0.0636 0.0416 -0.0004 -0.0570 -0.0592 0.1158 0.0590 0.0126 0.0034
+0.0346 0.0290 -0.0037 -0.0026 -0.0457 0.1824 0.1469 0.0870 0.0291 -0.0074
+0.0066 0.0682 -0.0148 0.0287 0.0095 -0.0563 0.1296 0.0426 0.1215 0.0886
+-0.0132 -0.0399 0.0960 0.0474 0.0140 0.0306 -0.0192 -0.0703 -0.1559 -0.1556
+-0.0600 0.0482 0.1257 0.0521 0.0229 -0.0031 0.0817 0.0571 -0.0138 -0.0277
+0.0013 -0.0103 -0.0470 -0.0687 -0.1444 0.0181 0.1350 0.0559 -0.0177 -0.0598
+-0.0215 -0.0318 -0.0689 -0.0268 0.0917 0.0307 0.0135 -0.0184 -0.0857 0.1231
+0.0137 -0.0152 0.0199 -0.0291 -0.0685 0.0438 -0.1137 0.0231 -0.0632 -0.0802
+-0.0011 0.0314 0.0535 -0.0135 -0.0291 -0.0579 -0.1049 0.0288 -0.0628 0.1355
+-0.0901 0.0041 -0.0170 0.0351 0.0144 -0.0505 0.0396 0.0638 -0.0145 0.0141
+-0.0400 -0.0603 -0.0714 0.0329 -0.0049 -0.0529 -0.1251 0.0022 -0.0449 -0.0778
+0.0247 0.0296 0.0239 0.0122 -0.0348 -0.1224 -0.0033 0.1237 -0.0016 -0.0436
+0.0246 0.0050 0.0322 0.0818 0.0203 0.0846 0.0022 0.0876 0.0149 -0.0184
+-0.0204 -0.0228 0.0365 -0.0164 0.1087 0.0374 -0.0550 0.0330 -0.0582 -0.0736
+-0.0305 -0.0485 -0.0572 0.0275 -0.0271 -0.0436 0.1217 0.0700 0.1253 0.0990
+-0.0079 -0.0204 -0.0325 0.0491 0.0158 -0.0365 -0.1309 -0.1812 0.1428 0.1148
+0.0680 0.0547 0.0309 0.0079 -0.0332 0.0391 -0.0287 0.1258 0.1123 0.1016
+-0.0264 -0.0409 -0.0538 -0.0192 -0.0393 -0.0713 -0.0618 -0.1078 -0.1850 0.0532
+0.0081 -0.0115 -0.0090 0.1201 -0.0413 -0.0995 0.0445 -0.0032 -0.0286 -0.0497
+-0.0023 -0.0184 -0.0358 0.1279 0.0847 0.0530 0.0230 -0.0212 0.1245 0.0965
+0.0111 0.1038 0.0597 0.0413 0.0533 0.0011 0.0031 0.0705 0.0242 0.0198
+0.0020 -0.0071 -0.0262 -0.0496 -0.0750 -0.1273 -0.1785 0.0606 -0.0223 -0.0583
+-0.0202 0.0669 0.0081 0.0335 -0.0218 -0.1073 -0.0146 -0.0673 0.0490 0.0210
+-0.0108 -0.0230 -0.0614 -0.0986 0.0629 0.0006 0.1496 0.1099 0.0316 0.0098
+-0.0368 -0.0685 0.0138 -0.0213 -0.0009 0.0344 -0.0249 0.0311 0.0803 0.0759
+0.0038 -0.0158 0.0142 0.0254 0.0970 0.0021 -0.1029 0.0006 0.0576 0.0261
+-0.0083 0.0698 0.0406 -0.0348 0.0200 0.0833 0.0186 -0.0145 -0.0725 -0.0872
+-0.0506 -0.0673 0.0776 -0.0172 -0.0444 -0.0531 -0.0799 0.0005 -0.0359 -0.0446
+0.0368 0.0376 -0.0407 -0.0190 0.0987 0.0212 -0.0349 -0.0951 -0.0084 -0.0342
+-0.0309 -0.0561 0.0950 -0.0125 -0.1028 -0.0133 0.0920 0.0965 0.0668 0.0409
+-0.0898 0.0036 -0.0353 -0.0024 -0.0365 -0.0259 -0.0485 -0.0843 -0.0063 -0.0167
+-0.0255 -0.0407 -0.0456 -0.0931 -0.0892 -0.0293 -0.0510 0.0183 -0.0104 0.0472
+-0.0172 -0.0399 -0.0731 0.0546 0.0320 -0.0283 0.0415 -0.0107 -0.1237 -0.1102
+0.0210 0.0294 -0.0038 -0.0090 -0.0551 -0.0922 0.0261 -0.0334 -0.1181 -0.1536
+0.0092 0.0032 -0.0162 0.0398 0.0205 0.1266 -0.0107 -0.0858 0.0392 0.0032
+-0.0038 -0.0269 -0.0737 0.1138 0.0263 -0.0031 -0.1188 0.1621 0.0831 0.0526
+0.0023 -0.0149 -0.0497 0.0898 0.0456 -0.0145 -0.0928 -0.1507 -0.0611 -0.0938
+0.0120 0.0124 -0.0286 -0.1319 0.0219 0.0311 -0.0398 -0.0465 -0.0008 -0.0375
+0.0138 0.0023 0.0024 0.1072 0.0531 0.0006 0.0292 -0.0115 -0.0620 0.1650
+0.0070 -0.0251 0.0715 0.0380 -0.0404 0.1230 0.0629 0.0096 0.0973 0.0641
+-0.0586 0.0772 0.0128 0.1060 0.0715 0.0374 -0.0074 -0.0365 -0.0543 -0.0489
+-0.0392 0.0871 -0.0069 -0.1084 0.0264 -0.0495 0.0396 0.0005 -0.0293 -0.0240
+-0.0327 0.0605 0.0662 0.0100 -0.0007 -0.0525 -0.0812 -0.0686 -0.0873 -0.0830
+0.0119 0.0058 0.0030 -0.0307 0.0650 0.0175 -0.0741 -0.1500 -0.1947 0.0881
+0.0572 0.0411 0.0152 -0.0127 -0.0589 -0.0510 -0.0212 -0.0834 0.1434 0.1318
+0.0518 0.0417 -0.0430 0.0963 -0.0014 0.0173 0.0234 -0.0273 0.0359 -0.0118
+0.0652 0.0587 0.0013 -0.0700 0.1262 0.0975 0.0680 0.0598 0.0048 -0.0305
+-0.0185 -0.0440 0.1178 0.0656 0.0052 -0.0534 -0.1151 0.1116 0.0659 0.0344
+0.0788 0.0577 0.0452 0.0283 -0.0278 0.0911 0.0280 -0.0254 0.0029 -0.0361
+-0.0165 -0.0322 -0.0526 -0.1057 0.0927 0.0293 -0.1026 -0.1671 0.0470 0.0355
+0.0100 0.0001 -0.0221 -0.0775 -0.1109 -0.1416 0.0884 0.0441 0.0632 0.0409
+0.0204 0.0432 0.0141 -0.0296 0.1073 0.0580 0.0383 0.0270 -0.0857 0.1246
+0.0488 0.0231 0.0648 -0.0179 0.0747 0.0156 -0.0384 -0.0733 -0.0732 -0.0970
+0.0005 -0.0199 -0.0260 -0.0511 -0.1110 0.0670 -0.0413 0.1571 0.0498 0.0191
+0.0037 -0.0085 -0.0796 0.0086 -0.0852 0.0850 0.0115 -0.0065 0.1161 0.0727
+0.0023 0.0483 0.0285 -0.0642 -0.0477 0.0175 0.0346 0.0452 0.0655 0.0284
+-0.0986 0.0463 0.0326 -0.0055 0.0702 0.0194 -0.0423 -0.0107 0.0338 0.0619
+0.0126 -0.0138 -0.1115 0.0159 -0.0331 0.0217 -0.0376 -0.0407 -0.0222 -0.0503
+0.0222 0.0071 -0.0490 0.1017 0.0551 -0.0164 0.1578 0.1059 0.0025 -0.0107
+0.0124 -0.0090 0.0322 0.0930 0.0281 -0.0403 -0.0781 0.0125 -0.0670 -0.1058
+0.0363 0.0077 0.1052 0.0039 0.0676 0.0891 0.0433 0.0252 0.0224 -0.0043
+-0.0045 -0.0194 -0.0193 -0.0480 -0.0640 -0.0695 -0.1597 -0.0030 0.1728 0.1231
+0.0297 0.0025 0.0619 -0.0347 -0.1171 0.1043 0.0868 0.0191 -0.0739 -0.1075
+0.0073 0.0914 0.0367 -0.0236 0.0232 0.0304 -0.0787 -0.1099 0.0460 0.0082
+0.0296 0.0297 -0.0444 0.0184 0.0602 -0.0295 -0.0934 0.0636 -0.0347 -0.0722
+-0.0290 -0.0629 0.0598 0.0013 0.0064 0.1431 0.0920 0.0468 -0.0311 -0.0614
+-0.0152 -0.0311 -0.0500 -0.0672 -0.1257 -0.0134 -0.0220 -0.0612 -0.1131 -0.1417
+0.0371 0.0153 -0.0817 -0.0007 0.0837 0.0481 0.0460 0.0678 0.0524 0.0432
+0.0126 -0.0069 -0.0092 -0.0693 -0.0250 0.1510 0.0098 -0.0683 -0.0566 -0.0769
+-0.0199 -0.0423 0.0806 0.0562 0.0009 -0.0563 -0.1358 -0.1578 -0.0456 0.0032
+0.0091 0.0101 -0.0090 -0.0279 -0.0489 -0.1038 -0.0815 0.2184 0.1172 0.0902
+-0.0024 -0.0135 0.0392 0.0028 0.0792 0.0404 0.0867 0.1610 0.0954 0.0846
+-0.0004 -0.0220 -0.0282 -0.1022 -0.0799 0.1278 0.0765 0.0402 0.0850 0.0611
+0.0443 0.0320 -0.0384 -0.0964 0.0030 -0.0398 -0.0730 -0.0052 -0.0267 0.1209
+-0.0706 0.1151 0.0722 -0.0175 -0.0927 -0.0559 0.0316 0.0186 0.0105 0.0314
+-0.0145 -0.0263 -0.0564 0.0248 -0.0181 -0.0817 -0.0938 0.0366 -0.0315 0.1253
+0.0307 0.0039 0.1290 0.0402 -0.0439 -0.0384 0.0044 -0.0177 -0.0172 -0.0310
+0.0447 0.0298 0.0287 0.0273 -0.0350 -0.0708 -0.1829 -0.0317 0.0643 0.0057
+-0.0820 -0.0326 0.0209 -0.0711 0.0084 0.0111 0.0426 0.0262 -0.0061 0.0005
+0.0545 0.0377 -0.0417 -0.0625 0.0114 -0.0405 0.0573 0.0191 -0.0263 -0.0472
+-0.0053 -0.0049 -0.0255 -0.0578 -0.0237 -0.0721 -0.1487 -0.1636 0.0046 -0.0355
+0.0309 0.0107 0.0163 0.0132 -0.0536 -0.0009 -0.0706 -0.1350 -0.0514 -0.0960
+0.0306 0.0003 0.0494 0.0701 0.0027 -0.0458 0.0780 0.0327 0.0937 0.0605
+-0.0017 -0.0275 0.0797 -0.0268 -0.1014 0.0593 -0.0528 -0.1103 0.0682 0.0322
+-0.0507 -0.0806 -0.0646 -0.0052 -0.0576 0.0451 0.0489 0.0150 0.0029 -0.0189
+0.0270 0.0143 -0.0375 -0.0071 -0.0607 -0.1157 -0.0345 -0.1115 0.0201 -0.0104
+-0.0807 -0.1088 0.0845 0.0720 0.0441 0.0301 0.0043 0.0052 0.0016 0.0201
+-0.0290 -0.0532 0.0036 -0.0201 -0.0723 -0.1321 0.0867 0.0479 -0.0556 -0.0850
+-0.0271 0.0126 0.1283 0.0533 -0.0030 -0.0352 -0.0326 -0.0553 0.1402 0.1121
+-0.0358 -0.0518 -0.1080 0.0134 0.0950 0.0384 -0.0040 -0.0254 0.0026 -0.0217
+-0.0152 -0.0375 -0.0827 0.0916 0.0188 0.1306 0.0983 0.0606 0.0381 0.0080
+-0.0107 -0.0269 -0.0573 -0.1189 0.0258 0.1009 0.0565 0.0270 -0.0557 -0.0778
+-0.0193 -0.0242 -0.0784 -0.0816 0.0287 -0.0484 0.0292 -0.0414 0.1124 0.0767
+0.0177 -0.0148 0.0472 -0.0808 0.0623 -0.0636 0.0750 -0.0107 0.0673 0.0425
+-0.0220 0.0577 -0.0769 -0.0247 -0.0321 0.0341 -0.0108 0.0109 -0.0142 0.0122
+0.0194 0.0248 -0.0096 -0.0205 -0.0460 -0.1160 0.0492 -0.0188 -0.1535 0.0816
+0.0301 -0.0286 -0.0077 -0.0117 -0.0036 -0.0026 0.0133 -0.0032 0.0007 -0.0160
+0.0115 -0.0111 0.0246 -0.0639 0.0325 -0.0313 0.0808 0.0435 -0.0777 -0.1108
+-0.0079 -0.0334 -0.0144 -0.0539 0.1564 0.1175 0.0549 0.0340 0.0319 0.0027
+-0.0155 -0.0275 -0.0739 -0.0932 0.0108 -0.0698 0.0036 -0.0213 -0.0486 -0.0670
+-0.0234 -0.0567 0.0020 0.0908 -0.0151 0.0460 -0.0175 -0.0523 0.0098 -0.0237
+0.0057 -0.0066 -0.0418 0.0418 -0.0449 0.1069 0.0629 -0.0016 -0.1068 -0.1492
+-0.0791 0.0403 -0.0009 0.0285 -0.0065 0.0963 0.0550 0.0634 0.0693 0.0694
+-0.0068 -0.0197 -0.0919 0.0071 -0.0551 -0.1173 0.0926 0.0413 0.0127 -0.0158
+0.0540 0.0389 -0.0195 -0.0800 -0.1383 0.0440 -0.0139 -0.0405 0.0147 -0.0183
+0.0380 0.0248 0.0520 -0.0609 0.0339 -0.0070 -0.0974 0.1182 0.0221 -0.0310
+0.0043 0.0046 -0.0274 -0.0502 0.0326 -0.0143 -0.0586 -0.0866 -0.1673 -0.1624
+0.0428 0.0385 -0.0228 0.0704 0.0069 -0.0145 -0.0623 -0.0639 -0.1479 0.0212
+-0.0078 -0.0297 0.0025 -0.0239 -0.0793 0.0896 0.0315 -0.0546 -0.1309 0.1080
diff --git a/codec2/branches/0.7/src/codebook/lspvqanssi3.txt b/codec2/branches/0.7/src/codebook/lspvqanssi3.txt
new file mode 100644 (file)
index 0000000..a28c3e7
--- /dev/null
@@ -0,0 +1,65 @@
+10 64
+-0.0291 0.0272 -0.0364 -0.0313 -0.0487 -0.0205 0.0501 0.0225 0.0178 0.0080
+-0.0406 -0.0383 0.0013 -0.0155 -0.0261 -0.0598 0.0003 -0.0242 0.0151 -0.0140
+-0.0445 0.0356 0.0180 -0.0272 -0.0018 -0.0177 -0.0703 0.0471 0.0128 -0.0068
+-0.0033 -0.0285 -0.0560 -0.0186 -0.0499 -0.0070 0.0068 -0.0126 0.0388 -0.0097
+-0.0071 -0.0114 -0.0308 -0.0094 -0.0541 -0.0272 -0.0756 0.0477 -0.0234 0.0678
+0.0048 0.0307 -0.0174 -0.0593 0.0097 -0.0134 0.0034 -0.0212 -0.0418 0.0869
+-0.0189 0.0165 -0.0269 0.0744 0.0344 -0.0177 -0.0603 0.0212 -0.0104 0.0345
+-0.0130 -0.0352 -0.0086 -0.0257 -0.0286 0.0409 0.0656 0.0106 -0.0598 0.0252
+0.0041 0.0097 -0.0032 -0.0154 -0.0405 0.0670 -0.0164 0.0451 0.0774 0.0504
+0.0010 -0.0091 -0.0345 0.0511 0.0016 0.0011 0.0684 0.0167 0.0601 0.0512
+0.0204 -0.0038 -0.0426 0.0185 -0.0191 -0.0630 0.0295 -0.0153 -0.0559 0.0560
+-0.0461 -0.0041 0.0515 0.0219 0.0322 0.0093 0.0044 0.0106 -0.0329 -0.0521
+0.0304 0.0017 0.0209 -0.0002 0.0689 0.0136 0.0216 -0.0268 -0.0682 0.0333
+-0.0175 -0.0425 0.0153 -0.0050 -0.0113 0.0297 -0.0659 -0.0344 0.0302 -0.0272
+-0.0217 -0.0362 0.0426 0.0233 -0.0393 0.0052 0.0138 0.0657 0.0427 0.0220
+-0.0039 -0.0011 -0.0002 -0.0453 -0.0835 0.0144 -0.0268 -0.0589 -0.0185 0.0133
+0.0081 -0.0032 0.0638 0.0032 0.0060 0.0002 -0.0303 -0.0823 0.0124 -0.0308
+0.0108 0.0011 0.0059 0.0396 0.0392 0.0351 -0.0045 -0.0323 -0.0512 -0.0975
+-0.0144 -0.0306 -0.0302 -0.0070 0.0123 -0.0042 -0.0083 -0.0514 0.0120 0.1116
+-0.0046 -0.0131 0.0472 0.0144 -0.0296 -0.0518 0.0337 -0.0145 -0.0733 0.0793
+-0.0064 -0.0162 -0.0327 -0.0711 0.0108 -0.0131 0.0025 -0.0254 -0.0277 -0.0680
+-0.0306 0.0055 0.0272 -0.0189 -0.0173 0.0221 0.0773 0.0043 0.0458 -0.0169
+-0.0006 0.0299 0.0259 0.0227 -0.0530 -0.0596 -0.0271 -0.0091 0.0181 -0.0233
+-0.0116 -0.0398 0.0089 0.0708 -0.0028 -0.0084 -0.0206 -0.0354 -0.0275 -0.0037
+0.0259 -0.0064 -0.0380 0.0572 0.0083 0.0286 -0.0565 0.0158 0.0396 -0.0123
+0.0552 0.0331 -0.0052 -0.0346 -0.0180 -0.0194 -0.0237 0.0184 0.0056 -0.0199
+0.0143 0.0131 -0.0166 0.0196 0.0154 0.0310 -0.0048 0.0901 -0.0333 0.0761
+0.0118 -0.0107 0.0099 0.0078 0.0002 -0.0716 -0.0233 0.0793 0.0516 0.0300
+0.0204 0.0243 0.0192 0.0181 0.0001 -0.0243 -0.0764 -0.0622 -0.0324 0.0640
+0.0132 0.0016 -0.0187 -0.0425 0.0627 0.0094 -0.0786 0.0304 0.0294 -0.0146
+-0.0221 -0.0154 0.0285 -0.0709 0.0406 0.0114 0.0073 -0.0199 0.0081 0.0268
+0.0227 0.0055 0.0163 -0.0447 0.0246 0.0795 0.0239 0.0211 -0.0145 -0.0576
+-0.0119 0.0637 0.0278 0.0202 -0.0086 0.0389 0.0320 -0.0049 -0.0272 -0.0274
+0.0040 -0.0211 0.0426 0.0480 0.0415 0.0659 0.0408 0.0198 0.0327 0.0029
+0.0430 0.0311 0.0083 0.0353 0.0250 0.0143 0.0106 -0.0305 0.0633 0.0227
+-0.0277 0.0302 0.0337 0.0176 0.0191 -0.0156 0.0231 0.0118 0.0465 0.0875
+0.0221 0.0146 0.0147 -0.0211 -0.0317 -0.0179 -0.0049 -0.0297 -0.1078 -0.0413
+-0.0531 0.0180 -0.0066 0.0365 -0.0033 0.0090 -0.0158 -0.0698 0.0315 -0.0048
+0.0289 0.0053 0.0082 0.0077 -0.0664 0.0474 0.0407 -0.0096 0.0028 -0.0526
+-0.0106 -0.0129 -0.0315 0.0335 -0.0217 -0.0427 0.0582 0.0193 -0.0288 -0.0777
+-0.0003 -0.0141 -0.0102 0.0007 -0.0077 -0.0517 -0.0909 0.0128 -0.0349 -0.0769
+-0.0227 -0.0159 -0.0327 0.0011 0.0312 0.0100 -0.0180 -0.0537 -0.0997 0.0122
+0.0190 -0.0139 0.0341 -0.0131 -0.0368 -0.0138 -0.0074 -0.0415 0.0791 0.0503
+0.0182 0.0027 0.0032 -0.0325 -0.0309 -0.0898 0.0509 -0.0170 0.0301 -0.0137
+0.0233 0.0100 0.0231 0.0730 0.0212 -0.0299 0.0440 0.0041 -0.0101 -0.0251
+0.0074 -0.0033 -0.0285 -0.0350 0.0101 0.0735 0.0036 -0.0659 0.0429 -0.0052
+0.0148 -0.0035 -0.0233 0.0079 -0.0142 -0.0402 -0.0358 -0.0985 -0.0080 -0.0549
+0.0203 0.0057 -0.0604 0.0098 0.0402 0.0151 0.0500 0.0058 -0.0086 -0.0401
+0.0056 -0.0381 0.0420 -0.0125 0.0157 -0.0268 0.0433 0.0123 -0.0176 -0.0685
+0.0030 0.0502 0.0067 -0.0222 0.0405 -0.0226 0.0020 -0.0401 -0.0026 -0.0521
+0.0317 0.0089 0.0620 0.0251 0.0066 0.0089 -0.0565 0.0414 0.0005 -0.0365
+-0.0058 0.0086 -0.0291 -0.0164 -0.0134 -0.0490 -0.0427 -0.0451 0.0869 0.0334
+0.0024 0.0328 -0.0415 0.0003 -0.0287 0.0193 -0.0547 -0.0222 -0.0196 -0.0571
+-0.0271 -0.0397 -0.0431 -0.0043 0.0332 0.0093 0.0082 0.0585 0.0282 0.0004
+-0.0251 -0.0167 -0.0289 0.0196 -0.0363 0.0850 0.0028 0.0319 -0.0202 -0.0512
+0.0389 0.0226 0.0401 -0.0091 -0.0152 0.0001 0.0738 0.0402 0.0097 0.0310
+-0.0126 0.0130 -0.0046 -0.0216 0.0298 -0.0344 0.0713 0.0547 -0.0470 -0.0294
+0.0125 0.0044 -0.0028 0.0209 -0.0200 0.0854 0.0018 -0.0386 -0.0703 0.0778
+-0.0036 -0.0347 0.0309 -0.0184 0.0290 -0.0025 -0.0644 0.0347 -0.0523 0.0644
+0.0064 0.0295 -0.0017 0.0282 0.0176 0.0027 0.0246 0.0967 0.0401 -0.0231
+0.0054 -0.0109 0.0055 -0.0479 -0.0490 -0.0136 -0.0245 0.0839 0.0026 -0.0493
+0.0128 -0.0050 -0.0219 -0.0621 0.0313 0.0019 0.0696 0.0459 0.0574 0.0299
+-0.0091 -0.0290 -0.0068 0.0276 0.0645 -0.0150 0.0015 -0.0374 0.0415 -0.0124
+-0.0171 0.0177 -0.0138 0.0034 0.0840 0.0584 0.0233 0.0100 0.0122 0.0047
diff --git a/codec2/branches/0.7/src/codebook/lspvqanssi4.txt b/codec2/branches/0.7/src/codebook/lspvqanssi4.txt
new file mode 100644 (file)
index 0000000..01867d4
--- /dev/null
@@ -0,0 +1,65 @@
+10 64
+0.0221 -0.0035 -0.0032 -0.0177 -0.0327 0.0518 -0.0110 -0.0150 -0.0136 -0.0327
+0.0099 -0.0059 0.0031 -0.0174 0.0464 -0.0240 0.0251 -0.0270 0.0454 -0.0082
+-0.0029 0.0025 -0.0267 -0.0318 -0.0157 0.0173 0.0253 0.0063 -0.0481 0.0419
+-0.0332 -0.0179 -0.0042 0.0241 0.0044 -0.0098 -0.0081 0.0024 -0.0414 0.0339
+-0.0060 0.0182 -0.0051 -0.0479 0.0016 -0.0179 0.0316 0.0222 -0.0029 -0.0351
+0.0074 0.0015 0.0337 -0.0082 -0.0008 0.0129 0.0001 0.0650 0.0175 0.0309
+-0.0212 -0.0261 0.0196 -0.0309 0.0093 -0.0272 0.0260 0.0169 0.0132 0.0116
+-0.0010 0.0202 0.0228 -0.0227 -0.0141 0.0192 -0.0423 -0.0097 -0.0342 0.0338
+-0.0149 -0.0110 -0.0156 0.0290 0.0028 0.0123 -0.0350 -0.0501 0.0272 -0.0245
+-0.0005 -0.0194 0.0460 -0.0001 -0.0280 0.0216 -0.0028 -0.0162 0.0177 -0.0254
+-0.0109 -0.0026 0.0038 -0.0150 -0.0421 -0.0422 0.0164 -0.0436 0.0054 -0.0098
+0.0061 -0.0106 0.0062 0.0207 -0.0329 0.0177 -0.0578 0.0408 0.0077 -0.0260
+0.0001 -0.0098 0.0106 -0.0003 -0.0292 0.0032 0.0560 0.0311 -0.0282 -0.0445
+0.0033 0.0345 -0.0022 -0.0029 -0.0228 0.0242 0.0197 -0.0286 0.0194 -0.0328
+0.0094 -0.0010 0.0121 0.0229 0.0161 0.0363 -0.0124 0.0179 -0.0626 0.0020
+-0.0070 -0.0272 -0.0171 -0.0249 -0.0039 0.0254 0.0317 -0.0324 0.0276 -0.0090
+-0.0002 0.0057 -0.0204 0.0512 -0.0170 0.0113 0.0157 0.0427 -0.0024 0.0162
+-0.0064 -0.0144 0.0216 0.0053 -0.0361 0.0287 0.0230 -0.0161 -0.0189 0.0589
+0.0091 -0.0059 -0.0308 0.0171 -0.0137 -0.0033 -0.0505 -0.0155 -0.0527 0.0133
+-0.0121 -0.0051 0.0219 0.0136 0.0476 -0.0090 -0.0460 0.0208 0.0072 -0.0076
+0.0098 -0.0328 -0.0211 0.0054 -0.0146 -0.0263 0.0248 0.0045 -0.0183 0.0301
+0.0101 0.0139 -0.0073 0.0234 0.0083 -0.0194 -0.0365 0.0307 0.0580 0.0153
+-0.0111 0.0019 0.0265 -0.0150 0.0311 0.0362 0.0244 -0.0213 -0.0224 -0.0299
+0.0061 0.0082 -0.0181 0.0081 -0.0344 0.0133 -0.0095 -0.0411 0.0462 0.0371
+0.0089 -0.0157 0.0179 -0.0256 -0.0118 -0.0302 -0.0329 0.0212 -0.0463 -0.0162
+-0.0313 0.0096 -0.0040 0.0186 0.0248 -0.0126 0.0472 -0.0079 0.0115 -0.0270
+0.0055 0.0044 0.0172 0.0079 -0.0089 -0.0202 -0.0233 -0.0397 -0.0305 -0.0620
+-0.0282 -0.0104 -0.0071 -0.0242 -0.0255 0.0204 -0.0187 -0.0103 -0.0227 -0.0424
+-0.0056 0.0065 0.0151 -0.0376 0.0039 0.0009 -0.0507 -0.0040 0.0393 -0.0201
+0.0128 -0.0228 0.0115 -0.0446 0.0316 0.0266 -0.0036 0.0117 -0.0009 0.0048
+-0.0088 0.0226 0.0125 0.0090 0.0008 -0.0341 0.0243 -0.0178 -0.0589 0.0278
+0.0151 0.0021 -0.0349 -0.0365 -0.0098 -0.0179 -0.0212 -0.0313 0.0109 -0.0164
+-0.0211 -0.0112 -0.0446 0.0014 -0.0034 -0.0179 0.0110 0.0176 0.0286 0.0045
+0.0034 -0.0151 0.0380 0.0331 -0.0034 -0.0439 0.0145 0.0120 0.0036 0.0017
+-0.0348 0.0192 0.0167 0.0069 -0.0266 -0.0085 -0.0076 0.0260 0.0234 0.0075
+-0.0237 0.0150 -0.0094 -0.0201 0.0234 -0.0041 -0.0160 -0.0549 -0.0021 0.0239
+-0.0019 0.0173 0.0295 0.0443 0.0081 0.0181 -0.0039 -0.0270 0.0155 0.0107
+0.0065 -0.0055 -0.0368 0.0232 0.0370 0.0367 0.0046 -0.0167 0.0047 0.0173
+0.0116 0.0053 -0.0229 0.0382 0.0160 -0.0453 0.0057 -0.0267 0.0020 -0.0051
+-0.0140 0.0302 -0.0208 0.0106 0.0101 -0.0049 -0.0319 0.0227 -0.0206 -0.0371
+-0.0007 -0.0109 -0.0053 0.0078 0.0410 -0.0001 0.0543 0.0328 -0.0196 0.0332
+-0.0043 -0.0028 -0.0246 0.0285 -0.0248 0.0153 0.0303 -0.0310 -0.0335 -0.0315
+-0.0417 0.1029 0.0377 0.0069 0.0012 0.0065 0.0007 -0.0144 -0.0083 0.0004
+0.0295 0.0099 -0.0144 -0.0145 0.0141 -0.0013 0.0362 -0.0142 -0.0428 -0.0161
+-0.0095 -0.0206 0.0116 0.0132 0.0164 0.0158 0.0012 -0.0024 0.0640 0.0364
+0.0005 -0.0022 -0.0165 -0.0057 0.0263 0.0339 0.0014 0.0541 0.0164 -0.0411
+0.0039 -0.0143 -0.0107 0.0032 -0.0160 -0.0502 0.0010 0.0272 0.0161 -0.0500
+0.0083 0.0292 -0.0076 -0.0201 0.0313 0.0213 0.0120 0.0087 0.0285 0.0332
+0.0170 0.0018 0.0001 0.0205 0.0106 -0.0064 -0.0082 -0.0083 -0.0082 0.0886
+0.0075 -0.0078 -0.0038 -0.0337 -0.0491 0.0048 0.0069 0.0300 0.0369 0.0088
+-0.0091 -0.0327 0.0041 0.0376 0.0170 0.0154 0.0126 0.0153 -0.0024 -0.0353
+0.0289 -0.0080 0.0063 0.0274 -0.0061 0.0208 0.0390 -0.0060 0.0294 -0.0088
+-0.0037 -0.0195 0.0058 0.0023 -0.0149 -0.0360 -0.0587 -0.0248 0.0288 0.0203
+-0.0031 0.0081 -0.0112 -0.0221 0.0067 -0.0505 -0.0233 0.0353 -0.0131 0.0417
+0.0243 0.0231 -0.0013 0.0049 -0.0423 -0.0245 -0.0029 0.0184 -0.0162 -0.0010
+0.0045 0.0101 -0.0042 0.0014 -0.0133 -0.0321 0.0642 0.0153 0.0377 0.0277
+0.0275 0.0083 0.0286 -0.0243 -0.0084 -0.0236 0.0027 -0.0289 0.0201 0.0235
+0.0281 0.0078 0.0038 0.0069 0.0302 0.0170 -0.0423 -0.0340 0.0104 -0.0181
+0.0334 -0.0034 -0.0257 -0.0061 0.0140 -0.0099 -0.0195 0.0529 0.0019 0.0010
+-0.0114 0.0012 -0.0038 -0.0016 -0.0140 0.0697 0.0372 0.0243 0.0172 0.0066
+0.0192 0.0149 0.0285 0.0077 0.0246 -0.0135 0.0145 0.0317 -0.0074 -0.0438
+-0.0034 -0.0175 -0.0245 -0.0153 0.0357 -0.0102 -0.0062 -0.0053 -0.0308 -0.0499
+0.0025 -0.0253 0.0148 0.0031 0.0189 -0.0023 -0.0085 -0.0596 -0.0337 0.0175
+-0.0091 -0.0171 -0.0217 -0.0189 0.0056 0.0249 -0.0499 0.0236 0.0042 0.0449
diff --git a/codec2/branches/0.7/src/codebook/lspvqexp1.txt b/codec2/branches/0.7/src/codebook/lspvqexp1.txt
new file mode 100644 (file)
index 0000000..808b95b
--- /dev/null
@@ -0,0 +1,2049 @@
+10 2048
+0.408892 0.649827 0.954657 1.095560 1.374775 1.695544 2.186975 2.404129 2.599671 2.716599
+0.206312 0.393044 0.534358 0.831490 0.964061 1.315881 1.711009 1.884982 2.656064 2.789476
+0.294007 0.430921 0.584720 0.972610 1.346504 1.446720 1.672880 1.854151 2.292980 2.574467
+0.130573 0.192259 0.568997 1.014611 1.204902 1.371336 1.696595 2.109828 2.488139 2.749404
+0.119174 0.172048 0.555350 1.041664 1.294588 1.603976 1.924941 2.215881 2.537337 2.763865
+0.264060 0.351222 0.551394 0.836209 0.955359 1.467373 1.883071 2.011362 2.370015 2.500936
+0.206715 0.433527 0.682328 0.833734 1.164725 1.476463 1.775427 2.152234 2.639949 2.796348
+0.211225 0.320307 0.437323 0.659797 1.492016 1.699378 1.859517 2.131810 2.328455 2.499706
+0.480644 0.630950 0.822352 1.123960 1.461020 1.594792 1.889414 2.166284 2.404039 2.536132
+0.233285 0.324869 0.445867 0.683777 0.826101 0.975483 1.764219 2.154061 2.334729 2.602314
+0.315909 0.537121 0.711160 0.941341 1.178015 1.302627 1.643751 2.058463 2.464410 2.591263
+0.245173 0.382524 0.532006 0.708503 1.236528 1.448436 1.777993 2.124256 2.306038 2.625603
+0.245615 0.291619 0.819764 1.444781 1.578166 1.731349 2.095787 2.242522 2.603987 2.720052
+0.173862 0.229815 0.418896 0.695378 0.931595 1.188532 1.820958 2.120767 2.330289 2.464753
+0.303527 0.372419 0.740620 1.167964 1.327370 1.494681 1.784226 1.898711 2.311465 2.642713
+0.259744 0.401730 0.575188 0.834348 1.431968 1.604358 1.798482 2.185462 2.402074 2.554969
+0.337109 0.570466 1.175085 1.451610 1.761333 1.975735 2.126135 2.293190 2.536691 2.706431
+0.367145 0.452099 0.647409 0.817255 0.902956 1.238037 1.825344 1.922997 2.436059 2.609846
+0.378662 0.531818 0.674407 0.919671 1.409610 1.559852 1.771428 2.027114 2.253246 2.408198
+0.163411 0.267202 0.378752 0.982090 1.260325 1.393847 1.801359 1.943528 2.730199 2.854737
+0.315416 0.366274 0.657622 1.193970 1.448486 1.554740 1.791291 1.913099 2.285878 2.665674
+0.182284 0.250810 0.478825 0.774649 1.250927 1.657871 1.857476 1.999098 2.286088 2.777030
+0.280912 0.330939 0.631688 0.754025 0.941971 1.616999 1.814228 2.013341 2.634148 2.720386
+0.197110 0.280354 0.442898 0.794104 1.537225 1.674591 1.953914 2.155343 2.626079 2.817453
+0.324055 0.494234 0.849184 1.111214 1.388737 1.737885 1.975967 2.381772 2.611796 2.753205
+0.249643 0.364552 0.527912 0.900747 1.026842 1.398842 1.869778 2.015830 2.450740 2.598903
+0.210241 0.311192 0.495868 0.687507 1.152048 1.296946 1.520174 2.255285 2.440410 2.686456
+0.159037 0.244226 0.385934 0.687847 1.072342 1.386804 1.785080 1.924100 2.533529 2.669124
+0.234363 0.441050 0.678179 0.862648 1.224287 1.720752 1.949118 2.386935 2.642309 2.768447
+0.177323 0.256095 0.417949 0.816232 1.042933 1.254927 1.618581 1.928664 2.118610 2.463463
+0.247362 0.335496 0.753623 1.051947 1.239658 1.426773 1.621176 2.053494 2.480950 2.615165
+0.156480 0.216035 0.368476 0.588087 1.238670 1.459124 1.827783 1.975080 2.316953 2.770680
+0.198050 0.342316 0.883251 1.421788 1.645484 1.905948 2.140263 2.301866 2.620508 2.774812
+0.257995 0.358680 0.537441 0.694512 0.824406 1.362975 1.764952 1.925331 2.486171 2.617074
+0.252496 0.330798 0.493815 0.973920 1.306189 1.439735 1.920226 2.087274 2.257323 2.398019
+0.165073 0.249466 0.371194 1.033936 1.278111 1.449107 2.046790 2.168316 2.497102 2.729474
+0.351523 0.566840 0.885298 1.113196 1.285310 1.425799 1.728030 2.101425 2.514797 2.765585
+0.247070 0.331460 0.517797 1.035640 1.189321 1.389341 1.740344 1.976250 2.202072 2.430856
+0.250272 0.471488 0.632229 0.874364 1.003062 1.214226 1.782201 1.915722 2.618775 2.804373
+0.178042 0.247938 0.413307 0.724804 1.348933 1.537515 2.114127 2.301885 2.636884 2.826241
+0.321648 0.521672 0.933498 1.194774 1.582506 1.752098 1.962687 2.185410 2.511609 2.710750
+0.189405 0.281558 0.405270 0.624133 0.831682 0.979077 1.773124 2.022636 2.231772 2.709233
+0.338988 0.556585 0.722942 0.903725 1.137734 1.260460 1.698745 2.141650 2.342421 2.527244
+0.283960 0.422437 0.547151 0.805702 1.347223 1.507695 1.702228 2.041553 2.221081 2.575186
+0.116988 0.373808 0.677058 1.246354 1.579914 1.860096 2.174202 2.426485 2.666464 2.778514
+0.172660 0.279061 0.420803 0.776647 1.027097 1.182553 1.880931 2.023781 2.400028 2.816622
+0.244703 0.354981 0.775126 1.007264 1.208883 1.571339 1.920167 2.128560 2.418384 2.673311
+0.277862 0.345899 0.491009 1.000182 1.668493 1.893737 2.024216 2.203943 2.418550 2.555188
+0.200787 0.681282 1.126094 1.309507 1.738042 2.023257 2.342799 2.463428 2.602179 2.702804
+0.223979 0.466963 0.728850 0.888776 1.090618 1.234456 1.705574 2.241550 2.510834 2.751795
+0.264860 0.389642 0.536973 0.871669 1.323290 1.441181 1.682582 1.973355 2.163007 2.401176
+0.254211 0.390772 0.549594 0.748576 1.280532 1.474290 1.636048 2.013508 2.479875 2.650004
+0.191314 0.280703 0.420214 1.117728 1.347340 1.558388 1.722577 2.094362 2.606691 2.753977
+0.152313 0.198389 0.337122 0.490241 1.023739 1.222176 1.581978 1.852165 2.361974 2.553970
+0.343523 0.473063 0.661058 0.896926 1.009881 1.426789 2.003978 2.115197 2.358072 2.676757
+0.225495 0.299263 0.443642 0.793508 1.407173 1.798104 2.159374 2.284811 2.501925 2.644715
+0.220837 0.608771 0.967248 1.237940 1.450245 1.693405 2.002186 2.239767 2.534945 2.707207
+0.290250 0.359912 0.599268 0.771394 0.922184 1.257421 2.137963 2.330228 2.526054 2.700371
+0.269144 0.463439 0.625052 0.842594 1.239627 1.353331 1.687365 2.092062 2.284863 2.634475
+0.170231 0.237346 0.408666 0.698347 1.146923 1.313417 1.753705 1.891356 2.401344 2.558038
+0.171963 0.247483 0.388808 0.980638 1.502962 1.644121 1.955137 2.148787 2.393447 2.630021
+0.209519 0.325681 0.464669 0.682705 1.111676 1.225834 1.824262 2.151181 2.384320 2.739424
+0.210672 0.533806 0.825201 0.990473 1.145813 1.393566 1.999486 2.222956 2.524156 2.776040
+0.261962 0.340226 0.472952 0.863674 1.443518 1.829669 1.994398 2.132878 2.355090 2.469655
+0.340277 0.460050 0.748860 1.054174 1.614903 1.804636 1.993799 2.247318 2.473443 2.602200
+0.239159 0.394343 0.578732 0.754990 0.941899 1.128161 1.620559 2.020968 2.585087 2.783718
+0.269667 0.342100 0.485464 1.053892 1.413864 1.534461 1.740671 1.909701 2.286779 2.538869
+0.076962 0.097269 0.408343 0.942043 1.237899 1.573872 1.883029 2.186618 2.520305 2.790522
+0.170175 0.223705 0.651279 1.003661 1.370350 1.628746 1.941629 2.172624 2.450895 2.649955
+0.219608 0.300784 0.472750 0.871097 1.064995 1.283347 1.869030 2.047338 2.234764 2.423176
+0.283455 0.337982 0.663326 0.792275 0.925513 1.457560 1.740494 1.857127 2.583274 2.700391
+0.199190 0.263142 0.443787 0.684379 1.185091 1.879212 2.080132 2.224038 2.427704 2.576557
+0.219374 0.680594 0.965335 1.102093 1.296977 1.590756 2.074636 2.334754 2.586458 2.754939
+0.198099 0.308630 0.432817 0.619556 0.754862 0.931998 1.549410 1.846704 2.294094 2.636366
+0.338876 0.446352 0.640399 0.996449 1.224095 1.344627 1.695974 1.883015 2.104946 2.489100
+0.166453 0.240154 0.399798 0.829295 1.305386 1.443374 1.723531 1.880577 2.379309 2.500316
+0.244810 0.287547 0.565833 1.376218 1.610718 1.731021 2.128375 2.264382 2.552460 2.697921
+0.203376 0.353110 0.454768 0.707277 0.892936 1.038801 1.609843 1.809379 2.065993 2.304645
+0.392222 0.453261 0.813874 1.205541 1.320471 1.599816 1.858220 2.029353 2.491522 2.638332
+0.269519 0.326891 0.470180 1.053385 1.538230 1.686468 1.865876 2.081763 2.229408 2.441901
+0.463250 0.707535 1.093317 1.316217 1.598936 1.783637 1.982618 2.134436 2.396915 2.574501
+0.234043 0.348930 0.473804 0.709797 1.030257 1.152835 1.749074 2.178802 2.334442 2.638112
+0.356771 0.553522 0.702444 0.911763 1.372687 1.512426 1.716079 1.969296 2.175300 2.356841
+0.215283 0.314571 0.448084 0.938241 1.488615 1.610559 1.858891 2.014800 2.487515 2.656114
+0.255059 0.324128 0.591637 1.140724 1.280033 1.626440 1.845765 2.008493 2.607807 2.732065
+0.190953 0.284283 0.446537 0.903721 1.083755 1.521604 1.865214 2.039362 2.398102 2.603527
+0.218632 0.323425 0.485128 0.801138 0.934826 1.550687 1.950327 2.141484 2.437725 2.588421
+0.240697 0.351397 0.469534 0.775124 1.406794 1.725183 1.871364 2.156495 2.381976 2.555115
+0.355558 0.461716 0.684575 1.091512 1.719266 1.926216 2.051391 2.237427 2.507442 2.610706
+0.160350 0.190000 0.366405 0.494497 0.868240 1.345426 1.566707 2.068702 2.335099 2.641913
+0.219362 0.326275 0.619951 0.801217 1.176182 1.324616 1.567767 1.852718 2.393752 2.544625
+0.242295 0.361032 0.536827 0.699045 1.264826 1.578333 1.777090 2.115510 2.587465 2.731970
+0.185629 0.225499 0.394464 1.072663 1.725553 1.814897 2.037215 2.318703 2.570456 2.700776
+0.199282 0.271847 0.427336 0.691175 0.936688 1.307560 1.755173 1.941991 2.180527 2.289541
+0.440652 0.657600 0.846249 1.115177 1.383954 1.526095 1.839294 2.054337 2.261747 2.486134
+0.254743 0.370981 0.519721 0.892661 1.365537 1.512546 1.867709 2.025821 2.338400 2.608154
+0.374541 0.564001 1.042547 1.268517 1.427251 1.737400 2.240345 2.527386 2.748712 2.871518
+0.163240 0.229374 0.631209 0.821347 1.079198 1.312352 1.847665 2.085082 2.462129 2.646514
+0.257702 0.368235 0.785115 0.964453 1.130321 1.417415 1.830826 2.058137 2.393471 2.589613
+0.195822 0.280922 0.414972 0.646213 1.237085 1.398279 1.830678 2.337509 2.561924 2.750149
+0.302754 0.361163 0.751614 0.974525 1.131739 1.643605 1.825553 2.044086 2.641030 2.739994
+0.235437 0.315967 0.652539 0.816752 1.083366 1.622892 1.852217 2.030423 2.192530 2.575813
+0.291611 0.410807 0.602501 0.962264 1.083617 1.420033 1.771443 1.907873 2.445734 2.652716
+0.189868 0.257547 0.397682 0.669228 1.309264 1.797630 1.994844 2.138696 2.608657 2.757821
+0.479797 0.701925 0.989967 1.226383 1.556286 1.735962 2.055139 2.286164 2.529859 2.666528
+0.215045 0.313827 0.431033 0.651895 0.829909 1.000831 1.815727 2.226013 2.392474 2.760351
+0.306301 0.398661 0.653631 1.025764 1.189362 1.401036 1.898166 2.051914 2.236996 2.422421
+0.167970 0.224219 0.368107 0.623431 1.201568 1.381682 1.762247 1.920037 2.113047 2.522470
+0.185718 0.243656 0.376917 1.209258 1.581544 1.690223 2.033223 2.376102 2.591085 2.756869
+0.147871 0.206576 0.362439 0.637580 0.940549 1.343574 1.621941 1.733152 1.946250 2.723886
+0.324080 0.457905 0.793499 1.005600 1.260387 1.583156 1.886643 2.096396 2.372896 2.578810
+0.226219 0.308328 0.636626 0.866278 1.534446 1.701010 1.887737 2.161067 2.358914 2.503200
+0.606744 0.955507 1.338156 1.567438 1.821726 2.055362 2.279753 2.416922 2.604378 2.699013
+0.246984 0.386718 0.502785 0.760434 1.042124 1.263722 1.435097 2.414889 2.724612 2.819326
+0.292410 0.502940 0.672216 0.892183 1.209496 1.339252 1.760220 1.968766 2.362511 2.623487
+0.143375 0.199091 0.483698 0.992064 1.214869 1.614010 1.832079 1.978488 2.281935 2.713930
+0.266561 0.304298 0.533705 1.305138 1.580937 1.665891 1.884884 2.014163 2.228380 2.568778
+0.178658 0.231896 0.383912 0.540251 1.225283 1.458102 1.922772 2.083421 2.250593 2.408925
+0.289292 0.350422 0.695339 0.839824 1.012699 1.582703 1.751493 2.110402 2.491079 2.602625
+0.191978 0.275525 0.396619 0.582467 1.263497 1.658220 1.987982 2.164226 2.491219 2.655634
+0.271271 0.427594 0.784469 1.094218 1.535344 1.895921 2.111855 2.328610 2.716413 2.835820
+0.197072 0.315577 0.461034 0.771499 0.895098 1.249097 1.937811 2.117715 2.428590 2.608183
+0.211338 0.407351 0.538840 0.766827 1.152593 1.246498 1.679320 1.905728 2.120349 2.677619
+0.135615 0.163159 0.283783 0.431117 0.953107 1.462377 1.809595 2.130270 2.442565 2.743798
+0.166707 0.238759 0.367497 0.902142 1.508106 1.650293 1.825543 1.979014 2.655324 2.825020
+0.349277 0.540928 0.693205 0.826151 1.104738 1.259800 1.507300 2.094618 2.320842 2.523635
+0.325055 0.432779 0.621749 1.070682 1.304776 1.457668 1.900591 2.027150 2.460400 2.683254
+0.232534 0.355259 0.543295 0.744519 1.329342 1.648497 1.789282 2.116619 2.343387 2.501568
+0.465485 0.876578 1.205981 1.371947 1.745534 1.938156 2.176847 2.328487 2.521049 2.656868
+0.246604 0.364927 0.536848 0.850639 1.033582 1.224962 1.555694 1.725857 2.343766 2.568854
+0.345140 0.476535 0.650548 0.994609 1.167264 1.343813 1.779614 1.923453 2.324548 2.609157
+0.140607 0.199293 0.674213 0.958553 1.263430 1.520789 1.808626 2.055790 2.415260 2.705252
+0.125913 0.381885 0.618365 0.994294 1.317324 1.547930 1.818095 2.158588 2.494214 2.751068
+0.214195 0.320569 0.719851 0.846412 1.134388 1.428969 1.611410 2.041914 2.282243 2.508041
+0.250098 0.404670 0.540333 0.911835 1.060249 1.279821 1.619963 1.771663 2.496606 2.697909
+0.163090 0.213459 0.360500 0.504711 1.040089 1.576896 1.979044 2.125480 2.339164 2.609713
+0.356943 0.533785 0.924836 1.108094 1.324907 1.563986 2.016874 2.233505 2.510859 2.677439
+0.226046 0.346550 0.669965 0.775492 0.992753 1.149356 1.460794 2.260130 2.505825 2.717261
+0.322304 0.403181 0.776459 0.964458 1.099992 1.312705 1.399455 1.890224 2.369477 2.448458
+0.181583 0.245567 0.398747 0.597666 1.249798 1.421203 1.606076 2.062186 2.473743 2.644347
+0.254588 0.326744 1.005093 1.262125 1.386127 1.779710 1.955644 2.320802 2.571383 2.678189
+0.216441 0.331207 0.529500 0.654360 0.976477 1.361296 1.647430 2.064996 2.284304 2.569981
+0.327013 0.391820 0.720865 1.097162 1.210384 1.510465 1.765619 1.895802 2.508466 2.678337
+0.252152 0.343407 0.663772 1.085064 1.474659 1.659743 1.910625 2.070943 2.565518 2.717751
+0.349806 0.488123 1.077976 1.292638 1.515886 1.846355 2.084915 2.406884 2.610810 2.736561
+0.182819 0.308233 0.418992 0.708488 0.808059 1.045333 1.698019 1.837574 2.442304 2.609622
+0.277323 0.408804 0.571028 0.828924 1.404815 1.598729 1.759862 1.985935 2.333424 2.455915
+0.229839 0.342341 0.470342 1.002275 1.285925 1.399377 1.816619 1.930907 2.470705 2.802064
+0.244913 0.299585 0.779774 1.322881 1.429162 1.587382 1.738489 2.162786 2.520459 2.623668
+0.161891 0.228443 0.419656 0.733282 0.922895 1.405447 1.884393 2.078046 2.269896 2.589494
+0.270447 0.452251 0.634105 0.780705 0.965021 1.351395 1.825782 2.214939 2.632158 2.796098
+0.171118 0.234980 0.395507 0.838430 1.544455 1.699044 2.124182 2.287668 2.660613 2.849673
+0.213781 0.293496 0.663454 0.993393 1.412625 1.646492 2.074110 2.290676 2.508346 2.653511
+0.199402 0.316802 0.426338 0.630931 0.735249 1.132121 1.883614 2.046046 2.416976 2.580155
+0.210048 0.294088 0.590707 0.762351 1.146848 1.352924 1.637070 2.017207 2.305862 2.432462
+0.154676 0.232848 0.373861 0.948260 1.342786 1.514201 1.755766 1.926693 2.555124 2.717005
+0.137148 0.221322 0.381753 0.919373 1.152152 1.376375 1.826205 2.189540 2.648671 2.813516
+0.245209 0.338241 0.486220 0.814091 0.944966 1.134755 1.358289 1.523556 2.149645 2.315495
+0.392124 0.549332 0.727700 0.905451 1.202400 1.375569 1.534258 1.840057 2.422734 2.556400
+0.148684 0.204787 0.552934 0.803123 1.372462 1.550381 1.754747 2.118492 2.372977 2.711653
+0.267280 0.397322 0.846103 1.172950 1.465464 1.857475 2.153775 2.381172 2.591304 2.723190
+0.194992 0.314743 0.526878 0.796319 1.177375 1.299335 1.525584 1.682646 2.452032 2.795741
+0.301179 0.371796 0.577128 1.081605 1.303060 1.419674 1.898891 2.054902 2.252552 2.600649
+0.252900 0.355818 0.549064 0.965795 1.162628 1.585047 1.928827 2.119789 2.498842 2.665173
+0.256762 0.436508 0.715681 1.130116 1.316991 1.587569 1.850331 2.197839 2.605877 2.796521
+0.235855 0.314907 0.609574 0.859658 1.266780 1.499482 1.790537 1.910982 2.039772 2.187359
+0.200486 0.336241 0.495825 0.891310 1.133452 1.285295 1.612858 1.828238 2.394734 2.809663
+0.179969 0.232629 0.363081 0.500578 1.184534 1.700401 2.059216 2.168101 2.610554 2.836451
+0.348768 0.492321 1.055246 1.314914 1.471270 1.645210 1.876419 2.100446 2.525029 2.694314
+0.171135 0.273412 0.378187 0.581850 0.726115 0.908194 1.708076 1.905747 2.542437 2.797354
+0.315194 0.475887 0.658397 0.849734 1.017156 1.173887 1.755577 2.042149 2.216786 2.521016
+0.229599 0.378223 0.495710 0.879870 1.173185 1.276381 1.777400 1.935276 2.173970 2.748099
+0.197210 0.253422 0.651252 1.311542 1.636493 1.706783 2.105431 2.346619 2.641613 2.771729
+0.232136 0.443332 0.579669 0.760076 0.955242 1.094270 1.726616 1.914262 2.122649 2.700118
+0.186271 0.267327 0.840223 1.116294 1.440220 1.650886 1.944246 2.192076 2.483403 2.643816
+0.268607 0.318357 0.512736 1.129834 1.613930 1.740081 1.917514 2.123735 2.299945 2.557182
+0.479249 0.689878 1.088007 1.470716 1.716709 1.922473 2.158730 2.305877 2.511790 2.656073
+0.307991 0.431011 0.578118 0.877244 1.205302 1.312688 1.629259 2.238238 2.462001 2.580776
+0.293918 0.452236 0.659902 0.921329 1.309254 1.422508 1.668206 2.064588 2.322038 2.461436
+0.131440 0.209617 0.702675 1.016897 1.223185 1.385724 1.670724 1.961691 2.376852 2.732092
+0.193489 0.279816 0.428516 1.256267 1.395720 1.633455 1.873432 2.214886 2.671449 2.786280
+0.182323 0.240522 0.451705 0.799605 1.223096 1.445970 1.647433 1.971485 2.217583 2.336581
+0.384106 0.488198 0.644947 0.897630 1.047334 1.468272 1.839224 1.937923 2.262459 2.408476
+0.260306 0.326571 0.615384 1.084790 1.376745 1.778446 1.998233 2.171540 2.424597 2.575747
+0.340699 0.545965 0.865284 1.131340 1.458730 1.711046 2.089316 2.336073 2.684077 2.841771
+0.290674 0.372204 0.609647 0.779269 0.906420 1.332695 1.973245 2.155443 2.354880 2.655993
+0.308041 0.460783 0.632808 0.911363 1.081813 1.231896 1.747306 1.927967 2.170864 2.605727
+0.180523 0.263276 0.388872 0.565969 0.970599 1.149292 1.871610 2.207290 2.458204 2.667791
+0.143978 0.222658 0.400384 1.086970 1.323702 1.528106 1.995792 2.231147 2.688186 2.836361
+0.209150 0.326190 0.485707 0.681360 1.195456 1.385054 1.544410 2.045718 2.276514 2.434761
+0.297725 0.399777 0.588061 0.894914 1.022395 1.243834 2.009751 2.182970 2.413135 2.638027
+0.228593 0.289986 0.631198 0.791618 1.403101 1.777890 1.926222 2.136335 2.313587 2.489963
+0.343174 0.500760 1.039265 1.351369 1.721522 1.925940 2.190967 2.354142 2.532626 2.657845
+0.149735 0.297295 0.440372 0.642471 0.732234 1.200738 1.414606 1.770276 2.778155 2.883980
+0.223698 0.281114 0.635545 1.061406 1.252740 1.613423 1.836402 1.963828 2.140470 2.593562
+0.168168 0.232950 0.408892 0.653722 1.031457 1.548556 1.766449 2.230830 2.626126 2.797381
+0.222326 0.345655 0.786775 1.107909 1.305189 1.588197 1.993469 2.213238 2.511325 2.685326
+0.224020 0.317494 0.598436 0.845315 1.197927 1.319317 1.767399 2.160174 2.338471 2.525570
+0.198682 0.295026 0.450891 0.867753 0.988755 1.401296 1.687600 1.894339 2.559558 2.696080
+0.206679 0.295846 0.477897 0.699492 1.273871 1.789097 1.959682 2.171515 2.399523 2.555694
+0.353705 0.509579 0.861689 1.094569 1.427975 1.625819 1.845189 2.034662 2.339261 2.562173
+0.176626 0.248928 0.429179 0.658231 0.856663 1.071207 1.601595 1.968639 2.470776 2.718292
+0.314175 0.392578 0.678288 0.944677 1.081793 1.304708 1.492952 1.733627 2.167258 2.307337
+0.202661 0.269438 0.509570 0.817339 1.376869 1.513847 1.874609 2.094859 2.323847 2.480180
+0.234414 0.278975 0.540035 1.347889 1.582923 1.720967 1.986105 2.114372 2.567473 2.703603
+0.146798 0.210418 0.385776 0.649932 0.920041 1.248588 1.573579 1.711404 2.232087 2.791487
+0.382058 0.469618 0.713606 1.069660 1.176016 1.497437 1.813598 1.950404 2.598859 2.726089
+0.334215 0.396922 0.687976 1.087820 1.575500 1.754574 1.906641 2.123504 2.311875 2.443046
+0.264352 0.802524 1.285656 1.486584 1.714037 1.865311 2.035536 2.281585 2.562390 2.750718
+0.270580 0.372011 0.562949 0.825388 0.994299 1.169245 1.870741 2.135215 2.301336 2.518290
+0.449329 0.649113 0.811339 0.973882 1.234030 1.349977 1.692316 1.971266 2.154687 2.357538
+0.180117 0.263580 0.408830 1.127021 1.317638 1.497965 1.895425 2.031294 2.672116 2.818667
+0.331179 0.404977 0.766611 1.259419 1.431059 1.581972 1.939935 2.087575 2.416872 2.639616
+0.194102 0.279875 0.549239 0.704386 1.177109 1.529852 1.691669 2.044312 2.359273 2.560290
+0.217844 0.305871 0.442547 0.616270 0.791798 1.713038 1.956014 2.134547 2.520649 2.795859
+0.162088 0.245953 0.365670 0.638902 1.457619 1.641568 1.838031 2.013303 2.320106 2.729780
+0.236749 0.306797 0.734177 1.072402 1.551912 1.853315 2.104151 2.256363 2.475312 2.617668
+0.176733 0.238829 0.485876 0.687779 0.927283 1.403874 1.830537 2.195431 2.429970 2.626018
+0.268020 0.478288 0.731817 0.871173 1.083963 1.253101 1.535103 2.185826 2.455996 2.622463
+0.166174 0.232448 0.362076 0.591660 1.356885 1.632572 1.826301 1.987791 2.467764 2.659140
+0.236315 0.287802 0.548409 0.987167 1.721933 1.836472 2.152486 2.384523 2.592315 2.741028
+0.148319 0.185444 0.292576 0.511994 0.653403 1.371832 1.527681 1.776139 2.182163 2.227991
+0.401535 0.564293 0.893142 1.022987 1.156707 1.327441 1.701821 1.993285 2.370534 2.578619
+0.165638 0.255975 0.370284 0.802811 1.426084 1.572731 1.787459 1.915582 2.413753 2.802844
+0.317083 0.519809 0.936968 1.293236 1.686332 1.984336 2.186929 2.353187 2.746765 2.860986
+0.189287 0.380990 0.546039 0.784587 1.003621 1.162395 1.874419 2.057907 2.555748 2.785834
+0.200570 0.284860 0.609927 0.826229 1.198949 1.436548 1.809361 2.033038 2.401620 2.587587
+0.168913 0.291597 0.445205 0.722025 1.163607 1.283554 1.763882 1.943265 2.445617 2.817539
+0.360050 0.443567 0.853632 0.987093 1.191562 1.562912 1.869792 2.232417 2.543480 2.645225
+0.231905 0.297890 0.611365 0.830346 1.094545 1.582087 1.848979 2.056068 2.241982 2.394253
+0.331013 0.427540 0.641785 0.946294 1.070136 1.373613 1.859665 1.965907 2.332441 2.584977
+0.186393 0.242540 0.372099 0.728034 1.467825 1.880137 2.042177 2.272992 2.633925 2.779591
+0.446483 0.648214 0.993351 1.205829 1.476224 1.661697 1.899206 2.087562 2.408776 2.592556
+0.208614 0.297946 0.427983 0.600065 0.709456 1.284278 2.044367 2.179822 2.682450 2.818833
+0.306024 0.468602 0.638450 0.827416 1.302277 1.427429 1.811154 2.176106 2.372543 2.496738
+0.152872 0.217872 0.355627 0.713701 1.075149 1.446741 1.848785 1.978762 2.159635 2.712916
+0.234973 0.319771 0.478090 1.080036 1.447440 1.571699 1.982304 2.127281 2.559717 2.736762
+0.162524 0.250245 0.389070 0.646952 0.872934 1.222022 1.856534 2.002922 2.205745 2.599505
+0.323202 0.432855 0.814249 1.180773 1.335093 1.521419 1.901656 2.092343 2.350187 2.560064
+0.273240 0.329948 0.562890 1.003483 1.538259 1.875392 2.025443 2.170349 2.380148 2.499017
+0.500444 0.796365 1.318632 1.529307 1.785448 1.972761 2.147764 2.310849 2.519566 2.650408
+0.263728 0.375983 0.556014 0.707339 1.188811 1.339543 1.652143 2.209513 2.616263 2.738796
+0.266858 0.438409 0.640135 0.862517 1.340556 1.500100 1.686339 2.153946 2.448590 2.598137
+0.190447 0.295300 0.432651 0.884499 1.072087 1.256294 1.823661 1.957091 2.345386 2.577329
+0.243926 0.297921 0.524525 1.251205 1.478145 1.594774 1.967380 2.076378 2.370787 2.732472
+0.167306 0.212866 0.358147 0.499128 0.984267 1.284647 1.814420 2.033044 2.314127 2.439818
+0.254879 0.320323 0.682137 0.944750 1.083508 1.662985 2.084039 2.246726 2.582054 2.713386
+0.212215 0.297268 0.418087 0.743693 1.609250 1.923321 2.079152 2.242169 2.464816 2.591376
+0.117901 0.208978 0.750040 1.145517 1.437720 1.744291 2.143051 2.439937 2.749809 2.873675
+0.193258 0.299329 0.443516 0.797326 0.939062 1.148247 2.018657 2.143420 2.638335 2.829836
+0.213782 0.353502 0.481322 0.711845 1.170764 1.302711 1.535835 1.703291 2.279212 2.748103
+0.115171 0.144705 0.242103 0.453456 1.202245 1.525989 1.893854 2.179999 2.517564 2.798073
+0.238570 0.307781 0.447781 0.957056 1.599743 1.771585 1.940690 2.245051 2.435372 2.633593
+0.194447 0.266589 0.445674 0.635231 0.910266 1.074602 1.340239 1.919744 2.377594 2.630265
+0.297496 0.544047 0.851256 1.025765 1.203569 1.446499 1.981579 2.194582 2.414346 2.605178
+0.203460 0.275006 0.515591 0.732576 1.407979 1.561138 1.760709 2.030957 2.312387 2.431093
+0.498532 0.697751 1.045964 1.328280 1.488249 1.717432 2.051335 2.268465 2.588202 2.722759
+0.194097 0.345960 0.482722 0.874859 1.052521 1.250837 1.534492 1.720853 2.636782 2.816708
+0.266101 0.394737 0.545547 0.974166 1.278319 1.387120 1.790143 1.967144 2.177889 2.702878
+0.102867 0.171081 0.576060 0.818748 1.189242 1.510470 1.778003 2.103994 2.520545 2.748259
+0.119052 0.208027 0.744711 1.011939 1.289820 1.547449 1.904002 2.157777 2.533138 2.773751
+0.210113 0.291141 0.487281 0.790277 0.954605 1.401661 1.701442 1.897619 2.210404 2.382596
+0.266446 0.411500 0.593156 0.920817 1.042570 1.321476 1.890868 2.015685 2.574753 2.734992
+0.195053 0.286814 0.458352 0.639707 1.284634 1.645299 1.800882 2.168396 2.390218 2.562172
+0.341567 0.526183 0.892818 1.084248 1.334447 1.590215 1.889298 2.135833 2.519801 2.745352
+0.323599 0.420247 0.572363 0.757221 0.889572 1.036953 1.623345 2.196313 2.409765 2.540575
+0.410364 0.592459 0.763563 0.927955 1.176077 1.308890 1.569276 2.059039 2.380497 2.499273
+0.194371 0.276796 0.581419 0.722859 1.264729 1.505348 1.711903 2.189092 2.444234 2.629075
+0.252525 0.297192 0.844332 1.381854 1.514803 1.693308 1.854404 2.129548 2.591287 2.684159
+0.170004 0.214112 0.394084 0.539179 0.822416 1.250980 1.752323 2.086240 2.289006 2.448613
+0.289267 0.343412 0.775795 1.191573 1.303367 1.539691 1.782253 1.905366 2.579603 2.729614
+0.234791 0.321602 0.704594 0.949738 1.420244 1.594285 1.774127 2.194285 2.467211 2.589613
+0.340968 0.561082 1.199771 1.415378 1.689161 1.838640 2.014730 2.162685 2.430697 2.592350
+0.345276 0.499518 0.706277 0.861164 0.999501 1.150174 1.572106 1.964424 2.390120 2.588870
+0.357406 0.496053 0.646703 0.939578 1.460352 1.676567 1.834109 2.014842 2.385901 2.507758
+0.176473 0.238482 0.404112 0.892358 1.136652 1.536592 1.716827 1.872719 2.552209 2.759174
+0.222384 0.324129 0.833161 1.246603 1.460920 1.650632 1.876566 2.087675 2.354362 2.547825
+0.167777 0.229073 0.433058 0.810575 1.128669 1.556495 1.799821 1.915429 2.106489 2.677788
+0.306967 0.371498 0.623689 0.749815 0.934500 1.649015 1.792619 2.190421 2.536272 2.643777
+0.148383 0.236235 0.322878 0.555588 1.594153 1.725789 1.992119 2.178572 2.540447 2.774265
+0.377895 0.546230 0.852056 1.067292 1.455797 1.652672 2.018925 2.238220 2.468715 2.644735
+0.300062 0.399164 0.567524 0.740898 0.849393 1.425476 1.948578 2.050102 2.416440 2.546289
+0.218019 0.356752 0.584786 0.769374 1.165925 1.291779 1.688308 2.175240 2.369045 2.711417
+0.143884 0.210234 0.342148 0.566261 1.198668 1.437368 1.683504 1.842729 2.638129 2.833574
+0.115081 0.173169 0.584021 1.134381 1.407360 1.689153 2.034286 2.294650 2.638147 2.814312
+0.190721 0.252429 0.584147 0.836602 1.015264 1.254879 1.571659 2.007112 2.245095 2.426652
+0.309544 0.480824 0.812592 1.075038 1.325338 1.457449 1.679174 1.976619 2.381620 2.705381
+0.164599 0.274956 0.399399 0.735839 1.360979 1.482765 1.859273 2.011226 2.288457 2.792980
+0.187333 0.353999 1.222795 1.502985 1.770143 1.982262 2.203271 2.378492 2.606563 2.729390
+0.158025 0.248611 0.551584 0.735140 0.915073 1.281500 1.744031 1.922872 2.435679 2.716805
+0.273434 0.367213 0.642574 1.050887 1.345202 1.494431 1.909997 2.107095 2.336366 2.534901
+0.264699 0.416517 0.576907 0.947351 1.178990 1.385352 1.951926 2.132530 2.549979 2.786944
+0.142221 0.546287 0.805410 1.079219 1.288179 1.492189 1.774180 2.114597 2.427330 2.681890
+0.230540 0.326500 0.461675 0.964559 1.255458 1.369392 1.856593 2.039532 2.207278 2.539486
+0.137659 0.377399 0.593860 0.793016 1.115754 1.281644 1.840901 1.971659 2.472814 2.713504
+0.144356 0.222505 0.346683 0.782224 1.201084 1.371745 2.123343 2.366887 2.623919 2.803847
+0.362575 0.509680 1.001234 1.230119 1.473004 1.608864 1.802561 2.021551 2.326705 2.519219
+0.240803 0.361576 0.516660 0.727416 0.914394 1.051113 1.716835 2.160538 2.328331 2.706675
+0.351054 0.517992 0.725905 0.915622 1.055525 1.339295 1.898183 2.100270 2.307558 2.559254
+0.200168 0.322989 0.505425 0.676330 1.190121 1.354931 1.731948 1.999324 2.249015 2.624332
+0.219896 0.269490 0.521875 1.237665 1.710417 1.793651 2.115240 2.279260 2.536737 2.689478
+0.215336 0.396644 0.543160 0.728604 1.109190 1.229364 1.727973 1.963312 2.325039 2.797789
+0.264892 0.352500 0.883446 1.155268 1.338153 1.628498 1.841805 2.014230 2.264319 2.462976
+0.239779 0.301722 0.529044 1.147546 1.636525 1.760760 1.966137 2.262281 2.456574 2.621762
+0.320203 0.679639 1.229787 1.529834 1.826892 2.060858 2.286789 2.422168 2.716167 2.843881
+0.353658 0.547800 0.796651 0.899078 1.041245 1.321838 1.822982 2.161422 2.619096 2.820678
+0.261908 0.345021 0.472318 0.918792 1.423161 1.564348 1.733377 2.067856 2.262877 2.396698
+0.124156 0.193894 0.636158 0.840841 1.110258 1.289251 1.683161 1.869014 2.398865 2.731114
+0.165710 0.239716 0.465502 1.228637 1.420469 1.692829 1.888377 2.147997 2.486300 2.699831
+0.160684 0.209986 0.367031 0.503201 1.015826 1.200739 1.524190 2.011867 2.222744 2.475835
+0.277916 0.405640 0.619792 0.770716 1.136524 1.426314 1.822220 2.135166 2.485194 2.647977
+0.231394 0.352162 0.469144 0.682116 1.481669 1.842849 2.029794 2.179907 2.469833 2.589806
+0.380604 0.561972 0.896403 1.133414 1.391582 1.626403 1.961716 2.211112 2.588392 2.787673
+0.322688 0.406580 0.586076 0.731518 0.852667 1.152831 1.995073 2.295481 2.441596 2.617794
+0.197630 0.400738 0.603098 0.838719 1.177968 1.302320 1.559507 1.871355 2.200186 2.796317
+0.159189 0.198711 0.364347 0.509370 1.127246 1.399692 1.623432 2.046094 2.279806 2.705935
+0.233578 0.298035 0.460794 1.139533 1.415576 1.616317 2.117648 2.254774 2.452874 2.595232
+0.177717 0.242239 0.394824 0.650020 0.987501 1.104089 1.611392 2.177724 2.393809 2.694514
+0.299562 0.409957 0.723642 1.062891 1.216972 1.411830 2.051394 2.240860 2.503777 2.709591
+0.201879 0.287289 0.406508 0.659566 1.400321 1.792888 1.936179 2.099785 2.279253 2.454742
+0.359188 0.531719 0.904543 1.142371 1.572219 1.782800 2.067174 2.342915 2.583586 2.731217
+0.245193 0.363406 0.508075 0.721046 0.817318 1.141324 1.787709 1.937075 2.532146 2.678676
+0.280203 0.342294 0.579285 1.021875 1.451807 1.612518 1.803002 2.013050 2.189908 2.367656
+0.124640 0.167543 0.484641 0.896195 1.324263 1.701101 1.908392 2.091365 2.427391 2.766624
+0.152261 0.248563 0.705878 1.026619 1.492524 1.688058 2.019960 2.241100 2.465374 2.733867
+0.169524 0.275607 0.440772 0.719798 1.121602 1.261028 1.809404 2.005583 2.240287 2.716912
+0.329978 0.420004 0.718053 0.936318 1.070988 1.489233 1.858025 1.988096 2.520192 2.667419
+0.229078 0.298586 0.511977 0.723831 1.144803 1.763599 2.164905 2.282990 2.512775 2.671092
+0.456055 0.680179 0.929388 1.076639 1.233955 1.484650 1.903702 2.126601 2.527098 2.727819
+0.168979 0.211126 0.352636 0.486868 0.828354 1.056116 1.439894 2.019355 2.482102 2.794744
+0.388525 0.560294 0.717429 0.985928 1.184401 1.320169 1.814889 2.045192 2.224054 2.519281
+0.207864 0.278390 0.577744 0.755061 1.180647 1.365438 1.765814 1.933058 2.355569 2.495779
+0.273703 0.316766 0.687833 1.373372 1.573215 1.679562 2.017370 2.150752 2.443206 2.666143
+0.139043 0.179618 0.315633 0.517664 0.768733 1.079636 1.390644 1.825048 2.101118 2.739679
+0.443325 0.508374 0.821570 1.141790 1.252203 1.580452 1.827461 1.983767 2.580866 2.715534
+0.272418 0.343583 0.526010 1.076654 1.474251 1.582828 1.851400 2.162984 2.327319 2.521128
+0.372015 0.542684 0.990447 1.414552 1.716538 1.844518 2.067134 2.276470 2.459989 2.623009
+0.296347 0.473546 0.629389 0.879809 1.022187 1.210411 1.881605 2.064735 2.306350 2.615239
+0.421613 0.570707 0.726241 1.011174 1.451250 1.595500 1.814127 2.086968 2.350981 2.485098
+0.138010 0.208811 0.371352 1.058801 1.360740 1.563789 1.835310 2.106508 2.488086 2.685686
+0.304388 0.366691 0.637332 1.163418 1.322554 1.489449 1.820316 1.937237 2.490676 2.695981
+0.160998 0.233003 0.393385 0.742550 1.040177 1.581795 1.846434 2.020562 2.454386 2.656034
+0.293730 0.353143 0.554522 0.676232 0.826408 1.581608 2.144029 2.268817 2.602846 2.715369
+0.174487 0.251975 0.375041 0.584283 1.427390 1.560251 1.883505 2.266902 2.453791 2.739291
+0.236065 0.282833 0.692209 1.097292 1.694874 1.966224 2.123394 2.280655 2.544753 2.658369
+0.129365 0.165960 0.285820 0.488714 0.981342 1.175696 1.724506 2.087889 2.501287 2.735548
+0.226211 0.351015 0.619709 0.857773 1.132574 1.308463 1.487032 1.965719 2.504712 2.670516
+0.203957 0.285955 0.462644 0.620843 1.230135 1.668195 1.835692 2.036399 2.639041 2.775792
+0.159885 0.225639 0.351326 0.882800 1.592195 1.709989 2.060725 2.305297 2.531165 2.753869
+0.182663 0.255048 0.437572 0.758568 0.996367 1.382381 1.651134 1.839516 2.008732 2.215961
+0.418150 0.556126 0.728385 1.007878 1.270088 1.366376 1.715316 2.066928 2.257578 2.389769
+0.207212 0.291325 0.416536 0.913294 1.492822 1.637098 1.825777 1.978284 2.214137 2.552111
+0.241341 0.427255 0.990332 1.209018 1.403013 1.731713 2.115958 2.363302 2.608966 2.742739
+0.188611 0.290583 0.686340 0.839849 1.094731 1.279717 1.560751 2.134527 2.353362 2.641874
+0.303141 0.383534 0.612718 0.971405 1.141894 1.558084 1.937162 2.069641 2.316813 2.480680
+0.179032 0.247590 0.375840 0.575450 1.367486 1.543422 2.101856 2.277817 2.513453 2.724165
+0.279200 0.350633 0.674006 1.015821 1.154154 1.656796 1.871235 2.061172 2.539189 2.655336
+0.220829 0.293262 0.666921 0.930888 1.307454 1.585242 1.798660 1.919831 2.100904 2.490486
+0.407626 0.528205 0.695580 0.942289 1.068323 1.248001 1.834686 1.955840 2.367277 2.684681
+0.187917 0.238836 0.392030 0.586354 1.220852 1.713253 2.205448 2.317138 2.607952 2.772751
+0.406035 0.678205 1.009915 1.169891 1.361883 1.567949 1.969141 2.218271 2.484866 2.653946
+0.263469 0.379446 0.574642 0.739690 0.891674 1.015764 1.634497 2.310050 2.531555 2.722555
+0.276896 0.353172 0.495976 0.992936 1.248222 1.349871 1.691833 2.151044 2.363150 2.534333
+0.165915 0.220580 0.380706 0.597420 1.137653 1.320387 1.576770 1.939725 2.122544 2.647358
+0.215129 0.283229 0.414568 1.356845 1.527108 1.679575 1.891014 2.130176 2.602350 2.741207
+0.206573 0.274549 0.539970 0.803271 1.064961 1.486193 1.704709 1.828604 1.978928 2.462439
+0.245410 0.534217 0.840240 1.054925 1.298942 1.439072 1.805223 2.039652 2.261595 2.482457
+0.236976 0.308980 0.585923 0.783026 1.498617 1.930204 2.097800 2.251258 2.476303 2.596959
+0.571463 1.021016 1.359450 1.510990 1.761279 1.913272 2.106845 2.286831 2.543023 2.660054
+0.187494 0.265400 0.418588 0.927645 1.377800 1.582098 1.740975 2.237651 2.615481 2.802350
+0.308598 0.491606 0.632564 0.923419 1.411973 1.578570 1.730433 1.976996 2.433166 2.558710
+0.147715 0.217707 0.377800 0.910933 1.185758 1.366725 1.612211 2.013767 2.403550 2.696412
+0.255983 0.321186 0.503024 1.109229 1.544228 1.645679 1.931499 2.060262 2.490962 2.677649
+0.175450 0.230655 0.407361 0.720246 1.062295 1.330697 1.797198 2.019193 2.315150 2.443569
+0.223790 0.338008 0.719854 0.950722 1.144176 1.597163 1.855352 2.263747 2.561723 2.704014
+0.192133 0.289847 0.398779 0.556338 1.501770 1.755759 1.934139 2.206912 2.388353 2.645486
+0.297639 0.450015 0.788874 1.101418 1.627516 1.880937 2.155204 2.413078 2.599468 2.743886
+0.217417 0.333895 0.462399 0.822556 1.071185 1.203256 1.990668 2.195575 2.436009 2.784665
+0.163563 0.239093 0.376533 0.839654 1.058152 1.266142 1.728781 1.907170 2.096879 2.659086
+0.137806 0.181530 0.328192 0.516935 1.031832 1.525160 1.768896 1.915914 2.359545 2.727805
+0.164104 0.236815 0.332559 0.910079 1.609754 1.696913 2.000392 2.161661 2.560691 2.703739
+0.228917 0.407594 0.638844 0.801544 1.054407 1.197528 1.396765 1.854050 2.203784 2.611161
+0.391989 0.486610 0.771960 1.116329 1.248980 1.474917 1.949979 2.088145 2.481910 2.691692
+0.279187 0.400947 0.576848 0.718895 1.254179 1.650864 1.823958 1.934813 2.498090 2.611019
+0.458469 0.714872 1.061410 1.262159 1.583256 1.935302 2.258053 2.430476 2.654284 2.756814
+0.222188 0.326247 0.447894 0.840363 1.072654 1.191396 1.417342 1.567507 2.404790 2.696868
+0.346704 0.402748 0.714703 1.139511 1.315770 1.444510 1.797498 1.920454 2.155272 2.559128
+0.155723 0.214701 0.494437 0.875267 1.172389 1.405229 1.797171 2.092950 2.373162 2.664794
+0.143642 0.390291 0.851279 1.039361 1.187534 1.415631 1.895439 2.190895 2.617165 2.792304
+0.266078 0.370570 0.662415 0.836415 0.988458 1.316618 1.567592 1.858948 2.257531 2.426635
+0.336056 0.469998 0.781562 0.918047 1.031306 1.219377 1.737468 2.050577 2.458442 2.720080
+0.165799 0.215460 0.363262 0.498067 1.217803 1.622985 1.903435 2.072821 2.251153 2.522123
+0.418176 0.619702 0.947421 1.146388 1.456489 1.664370 1.965827 2.179934 2.466824 2.629682
+0.265129 0.360058 0.519333 0.815729 0.992554 1.155878 1.718766 2.222951 2.442701 2.585525
+0.308187 0.464955 0.631733 0.775884 1.197138 1.454372 1.618186 2.005378 2.298683 2.443207
+0.178219 0.251645 0.407157 0.725307 1.323507 1.464894 1.694747 2.102622 2.283774 2.589151
+0.206659 0.311706 0.925646 1.192852 1.568069 1.802078 2.008324 2.197021 2.461939 2.657140
+0.174956 0.236808 0.392320 0.654967 0.934857 1.152108 1.595741 1.864532 2.214108 2.354775
+0.230434 0.344630 0.704520 0.910666 1.348070 1.567822 1.811907 1.939844 2.509990 2.701550
+0.180253 0.232955 0.624261 0.923991 1.421690 1.599589 1.814005 2.073839 2.413260 2.570514
+0.398056 0.571576 1.027057 1.401582 1.532635 1.743391 2.038501 2.173100 2.635865 2.756941
+0.244124 0.349847 0.599577 0.750991 0.891408 1.153522 1.605551 1.899047 2.317997 2.500479
+0.324856 0.539756 0.695489 0.870499 1.378985 1.583978 1.787428 2.079347 2.366844 2.502610
+0.250886 0.480663 0.608352 0.931539 1.092319 1.383530 1.692940 1.863607 2.650750 2.806650
+0.338327 0.396903 0.699669 1.241511 1.414878 1.559671 1.867401 2.000074 2.583166 2.742075
+0.164041 0.233302 0.383240 0.540410 0.806255 1.495618 1.938839 2.063074 2.286859 2.677635
+0.218870 0.316692 0.450414 0.721514 1.234846 1.762116 1.921161 2.415204 2.642001 2.782596
+0.163667 0.235743 0.354094 0.797110 1.437154 1.554340 2.096932 2.265233 2.481373 2.661373
+0.141630 0.198248 0.557013 1.138173 1.485146 1.786655 1.990698 2.185739 2.443261 2.719231
+0.217999 0.366741 0.519705 0.781024 0.899903 1.248543 1.852721 1.986039 2.401777 2.555847
+0.205878 0.302603 0.472303 0.693773 1.275278 1.505045 1.651223 2.075256 2.330750 2.459809
+0.205336 0.309242 0.483400 0.841555 1.362515 1.548353 1.760082 1.993603 2.496424 2.633078
+0.173174 0.251866 0.410487 1.098827 1.251313 1.651838 1.903428 2.405674 2.698209 2.817074
+0.274582 0.463838 0.620569 0.820587 0.988556 1.155062 1.637870 1.835193 2.071934 2.529835
+0.364198 0.472940 0.697706 1.016409 1.151822 1.373913 1.673193 1.811034 2.432956 2.643088
+0.210609 0.316509 0.475251 0.668420 1.418526 1.631402 1.796155 2.141848 2.319077 2.697236
+0.294479 0.519397 0.846472 1.213453 1.709661 1.916717 2.258070 2.456443 2.600351 2.786559
+0.170463 0.255944 0.401983 0.820520 1.094719 1.322743 1.646553 1.784940 2.486157 2.613248
+0.237336 0.356516 0.490576 0.924631 1.184187 1.304165 1.910651 2.102207 2.302776 2.641078
+0.237089 0.334322 0.503100 0.942044 1.087499 1.511162 1.952715 2.075663 2.564695 2.734500
+0.270484 0.426158 0.787084 1.011450 1.420404 1.627576 1.856282 2.112823 2.548329 2.769664
+0.212376 0.278943 0.617049 0.887684 1.142337 1.356367 1.727600 1.935068 2.149199 2.293257
+0.219581 0.437941 0.549582 0.824175 1.110224 1.217621 1.723719 1.891729 2.537107 2.790704
+0.180332 0.207980 0.422463 0.642179 1.028384 1.607980 2.250525 2.381973 2.608993 2.774395
+0.363639 0.523626 1.148877 1.352576 1.562465 1.724307 1.921396 2.120662 2.445004 2.610164
+0.150266 0.222691 0.365816 0.555803 0.688872 1.162897 1.782593 2.040683 2.522491 2.769536
+0.322510 0.444036 0.616943 0.895765 1.056214 1.275784 1.751504 1.895911 2.132909 2.370408
+0.228790 0.394631 0.548588 0.772733 1.227890 1.335766 1.788390 2.041514 2.278792 2.744098
+0.234366 0.288401 0.669909 1.295698 1.461082 1.731631 2.183204 2.296645 2.539291 2.656637
+0.255688 0.474634 0.639397 0.858887 1.097668 1.228104 1.592196 1.812078 2.070709 2.717623
+0.214002 0.365378 0.921340 1.120628 1.379265 1.601621 1.931336 2.141337 2.414577 2.593476
+0.220925 0.307330 0.407573 0.868421 1.663240 1.844525 1.994660 2.189618 2.371374 2.516151
+0.362773 0.569567 1.005505 1.504530 1.678917 1.910360 2.158978 2.297543 2.659978 2.788995
+0.296160 0.426108 0.649527 0.859492 1.056490 1.213501 1.697291 2.135737 2.364297 2.514164
+0.281900 0.432754 0.589102 0.914308 1.277709 1.401926 1.774347 1.972103 2.235129 2.544435
+0.277240 0.357036 0.828830 1.002473 1.178011 1.446057 1.715661 1.918548 2.237210 2.572122
+0.235923 0.330705 0.623139 1.275081 1.398365 1.615244 1.800110 2.151779 2.592066 2.735797
+0.179223 0.246208 0.400152 0.708696 1.129890 1.318110 1.696185 1.907985 2.203754 2.331059
+0.316183 0.382213 0.679593 0.814474 0.986274 1.762901 1.990617 2.149795 2.433563 2.555738
+0.218193 0.282095 0.586606 0.865818 1.378763 1.742711 1.918177 2.243443 2.595193 2.752713
+0.309792 0.481840 0.827993 1.213125 1.606995 1.730492 2.141679 2.280307 2.608238 2.849348
+0.270780 0.352881 0.501183 0.906847 1.086388 1.325169 1.838184 2.204039 2.421528 2.566162
+0.226107 0.390361 0.555807 0.749815 1.088830 1.205930 1.680764 2.021480 2.201488 2.659122
+0.123441 0.173507 0.307303 0.690407 1.173938 1.333877 1.786765 2.000793 2.425213 2.751118
+0.158591 0.214573 0.427561 0.902581 1.277688 1.674870 2.126902 2.421840 2.701440 2.836990
+0.189303 0.283266 0.464375 0.672875 1.104817 1.250272 1.526572 2.083813 2.270321 2.510880
+0.287382 0.434077 0.583769 0.905506 1.053249 1.483726 1.993792 2.165572 2.575308 2.698217
+0.263500 0.370045 0.536776 0.782922 1.324389 1.844905 2.005965 2.156203 2.458755 2.583419
+0.384009 0.584098 0.936199 1.287834 1.635325 1.761083 2.169160 2.324023 2.535401 2.749390
+0.146402 0.213762 0.398489 0.690149 0.996244 1.435892 1.670170 1.813953 2.445981 2.787485
+0.301226 0.367882 0.654854 1.094027 1.229960 1.592088 1.885201 2.005608 2.274408 2.444608
+0.149947 0.216185 0.391920 0.830502 1.253633 1.431601 1.785490 2.103484 2.525214 2.755484
+0.097894 0.173875 0.729312 1.016482 1.304096 1.606405 1.935582 2.257805 2.640341 2.840475
+0.169855 0.242145 0.571777 0.803659 1.022243 1.354604 1.782360 1.980234 2.368909 2.535598
+0.254591 0.378801 0.672668 0.807056 1.056720 1.493018 1.655380 1.979812 2.449241 2.599697
+0.193304 0.260487 0.459964 0.670291 1.308012 1.768287 1.946244 2.212251 2.405579 2.728625
+0.366883 0.536817 0.908218 1.110776 1.354740 1.500190 1.704032 1.943640 2.329476 2.560555
+0.211004 0.305715 0.399667 0.516282 0.691520 0.849824 1.396564 2.291427 2.546197 2.699794
+0.235007 0.315896 0.593374 0.857317 1.094567 1.500585 1.840100 1.974535 2.128181 2.274238
+0.183909 0.226449 0.400954 0.544120 1.348797 1.515812 1.765685 1.973782 2.256647 2.370030
+0.237680 0.317979 0.661098 1.253198 1.394092 1.734084 1.949126 2.131970 2.641034 2.757610
+0.166212 0.241240 0.371751 0.557281 0.767198 1.134161 1.620608 1.834400 2.454323 2.635245
+0.330393 0.391091 0.780047 1.022404 1.134626 1.502694 1.702935 1.890801 2.580707 2.691910
+0.408812 0.495670 0.687407 1.108832 1.546181 1.696379 1.885325 2.139028 2.368060 2.517184
+0.376422 0.555069 1.161646 1.386418 1.622733 1.845580 2.017094 2.201137 2.552466 2.708053
+0.274146 0.380469 0.549878 0.799730 0.939402 1.117940 1.645452 2.052539 2.350689 2.490049
+0.329001 0.575380 0.735296 0.911471 1.268064 1.391747 1.781411 2.007253 2.202059 2.466893
+0.212169 0.311180 0.439692 1.078259 1.267527 1.468391 1.726469 1.906190 2.628147 2.786434
+0.297463 0.361038 0.824509 1.239302 1.339377 1.569785 1.940696 2.077375 2.519418 2.696863
+0.207701 0.292358 0.552629 0.711964 1.172305 1.651429 1.844960 2.071458 2.419231 2.553707
+0.209832 0.301136 0.449094 0.647610 0.777779 1.480469 1.932068 2.131542 2.710060 2.812704
+0.172423 0.255437 0.369220 0.543108 1.401559 1.717608 1.933428 2.154827 2.367862 2.787661
+0.255748 0.347504 0.796616 1.027751 1.504250 1.760784 1.937354 2.112544 2.469490 2.637341
+0.169424 0.278442 0.444446 0.687556 0.797962 1.369199 1.630793 2.131758 2.696521 2.814286
+0.263582 0.429254 0.626198 0.790299 0.996064 1.131137 1.510958 2.083907 2.354499 2.747674
+0.160669 0.249969 0.366613 0.619384 1.335750 1.509419 1.938079 2.107770 2.598329 2.796645
+0.244289 0.315310 0.439736 0.746805 1.478790 1.975786 2.164362 2.279744 2.549736 2.677409
+0.158860 0.216940 0.349617 0.495945 1.053452 1.187951 1.643661 1.872490 2.121853 2.234733
+0.364934 0.547895 0.703548 1.046696 1.327165 1.444813 1.638612 1.994689 2.369195 2.515047
+0.199825 0.282570 0.423937 1.052805 1.331805 1.455952 1.892213 2.048648 2.272970 2.743986
+0.205916 0.528758 1.069123 1.303179 1.547206 1.887462 2.261478 2.525666 2.727548 2.836565
+0.211344 0.325615 0.470129 0.876822 1.036692 1.388499 2.004071 2.168361 2.641575 2.788384
+0.165214 0.237113 0.652635 0.853498 1.274603 1.418260 1.750475 2.188010 2.392225 2.656697
+0.171345 0.265931 0.404296 0.777656 1.251339 1.381106 1.876187 2.028307 2.321131 2.646341
+0.243930 0.315918 0.797490 1.189416 1.348551 1.850071 2.061191 2.229853 2.567528 2.706220
+0.194777 0.274153 0.522750 0.716292 0.872211 1.616112 1.890034 2.023297 2.194462 2.435800
+0.244945 0.443755 0.592420 0.889336 1.105448 1.259185 1.758350 1.914694 2.352504 2.581197
+0.179880 0.257145 0.369148 0.581368 1.406373 1.820128 2.061537 2.213705 2.526442 2.674115
+0.545317 0.839577 1.093857 1.262533 1.530824 1.739612 2.017505 2.229486 2.511345 2.662061
+0.188061 0.301651 0.405278 0.612153 0.779478 1.037845 2.004224 2.211267 2.475847 2.697676
+0.314335 0.465910 0.634660 0.880106 1.266325 1.367294 1.763992 2.104409 2.276097 2.443435
+0.141443 0.203354 0.372102 0.773557 1.052380 1.521452 1.774251 1.900827 2.384498 2.726988
+0.183016 0.267487 0.382582 1.062637 1.528110 1.626188 1.861114 2.019971 2.608976 2.763674
+0.143357 0.192604 0.323821 0.497856 0.905440 1.343367 1.820946 2.001139 2.153210 2.609622
+0.354165 0.489743 0.667126 1.118630 1.392866 1.492788 1.780757 2.073223 2.328160 2.560997
+0.282856 0.383914 0.485830 0.850543 1.506444 1.797613 1.937969 2.146059 2.427443 2.548079
+0.487767 0.866830 1.364561 1.521265 1.733207 1.945262 2.238743 2.399018 2.632115 2.744288
+0.280530 0.416807 0.597088 0.899084 1.119331 1.255621 1.616253 2.134732 2.562029 2.692235
+0.284821 0.494631 0.684501 0.838586 1.258096 1.395495 1.638054 2.162929 2.354037 2.540591
+0.205140 0.295529 0.494620 0.956357 1.129557 1.430489 1.736194 1.883778 2.442628 2.597296
+0.304833 0.379519 0.691807 1.147815 1.310207 1.513791 2.008217 2.142574 2.387944 2.637546
+0.181676 0.219451 0.383940 0.516016 1.044498 1.517177 1.777135 1.964014 2.218885 2.363256
+0.294578 0.352761 0.665993 0.810615 0.975505 1.763777 1.954836 2.159643 2.626241 2.718025
+0.172769 0.247043 0.367453 0.702216 1.520013 1.752683 1.974569 2.256458 2.462168 2.651882
+0.133992 0.301438 0.794542 1.081390 1.502045 1.696404 2.061943 2.278505 2.623520 2.822598
+0.250639 0.391712 0.550858 0.794112 0.913038 1.085745 2.034282 2.313366 2.505665 2.787062
+0.323242 0.434081 0.555684 0.961893 1.357180 1.456826 1.643504 1.784048 2.015616 2.515904
+0.143041 0.186235 0.352826 0.680065 1.264865 1.599306 1.944390 2.254806 2.597410 2.807813
+0.203141 0.289063 0.395881 0.800946 1.463891 1.689942 1.835029 2.061175 2.225528 2.642274
+0.222797 0.394599 0.573255 0.715466 1.025538 1.188023 1.564145 2.025279 2.191600 2.532423
+0.405610 0.492208 0.769597 0.896548 1.095745 1.667540 1.851755 2.090613 2.499090 2.611378
+0.238982 0.324219 0.447220 0.884037 1.482394 1.649975 1.799871 2.147158 2.341317 2.496853
+0.453661 0.658367 0.977870 1.248116 1.512727 1.831479 2.096748 2.293691 2.622778 2.735454
+0.171442 0.338885 0.499399 0.793308 1.060572 1.203862 1.664796 1.804188 2.519133 2.756339
+0.278022 0.338379 0.636156 1.044803 1.186358 1.516967 1.701121 1.872073 2.394724 2.502070
+0.121438 0.167486 0.411911 0.917381 1.165927 1.533981 1.818319 2.060997 2.450329 2.746320
+0.162532 0.224824 0.658346 0.916673 1.391225 1.595859 1.857208 2.217273 2.498430 2.753849
+0.275986 0.349156 0.568548 0.683453 1.016150 1.598731 1.764733 1.935888 2.342502 2.451659
+0.253773 0.480249 0.604419 0.965946 1.273556 1.519695 1.780207 2.006359 2.680279 2.811275
+0.187376 0.271558 0.385829 0.556450 1.380619 1.664090 1.814039 2.064114 2.245361 2.453707
+0.294725 0.466563 0.736292 1.055050 1.550984 1.693651 1.897743 2.212842 2.491391 2.698543
+0.239923 0.334060 0.461488 0.662636 0.791453 1.005699 1.600227 2.170741 2.458382 2.619019
+0.327525 0.492740 0.643437 0.903326 1.245421 1.348861 1.592207 1.937940 2.512050 2.644548
+0.221363 0.338816 0.483946 0.687648 1.284665 1.551620 1.720135 2.073904 2.254226 2.544134
+0.258618 0.300723 0.704898 1.390679 1.579033 1.718703 1.937423 2.081021 2.591851 2.718075
+0.204543 0.311448 0.448600 0.699217 1.072306 1.225857 1.749871 2.025585 2.206864 2.441320
+0.407224 0.493488 0.735697 1.167395 1.335468 1.468164 1.704353 1.844157 2.418454 2.658505
+0.177985 0.233336 0.506489 0.863799 1.426574 1.604693 1.864455 2.179274 2.402289 2.599311
+0.201307 0.580059 1.233073 1.407900 1.670628 1.818287 2.017446 2.256081 2.551962 2.742129
+0.322757 0.406373 0.612482 0.787838 0.909320 1.345224 1.671798 1.785817 2.404421 2.543501
+0.331870 0.431884 0.597156 0.927729 1.457447 1.672300 1.841455 2.039567 2.250965 2.417211
+0.202946 0.328964 0.442956 0.945971 1.181249 1.322011 1.766214 1.899811 2.569787 2.777471
+0.274929 0.335270 0.613025 1.214599 1.385772 1.557449 1.956849 2.066650 2.288912 2.459016
+0.146768 0.210059 0.360823 0.630784 1.072395 1.512445 1.766060 1.876355 2.226609 2.774121
+0.278686 0.371483 0.567509 0.728655 0.855673 1.555589 1.958603 2.076551 2.544275 2.713690
+0.143219 0.224816 0.347059 0.649970 1.564613 1.685486 1.917021 2.072654 2.453763 2.655050
+0.294541 0.443278 0.726594 0.985933 1.415734 1.765955 2.073442 2.328283 2.592514 2.745548
+0.243739 0.365134 0.572466 0.827675 0.939711 1.401796 1.826498 1.947840 2.429538 2.736311
+0.213082 0.349340 0.619784 0.765201 1.188628 1.358763 1.534192 2.128318 2.415976 2.591807
+0.161799 0.248667 0.354739 0.716246 1.327356 1.505974 1.706364 1.848519 2.455553 2.645897
+0.228516 0.375004 0.745896 1.050532 1.367740 1.799352 2.151717 2.418669 2.673185 2.797596
+0.234744 0.320318 0.466401 1.013481 1.184613 1.343346 1.535391 1.904405 2.318092 2.457794
+0.296936 0.385747 0.828858 1.091916 1.213084 1.370156 1.504418 2.008638 2.299958 2.422080
+0.189955 0.288894 0.417900 0.584179 1.286507 1.481483 1.710061 2.088780 2.259900 2.658597
+0.170659 0.301463 1.070828 1.400247 1.605036 1.820055 2.012834 2.274844 2.579681 2.738437
+0.194796 0.277316 0.434438 0.646763 0.772268 1.506173 1.740645 1.962370 2.464322 2.657388
+0.222257 0.294563 0.463770 1.144565 1.329294 1.506915 1.848439 2.035803 2.320447 2.526842
+0.188443 0.314239 0.448752 0.852815 1.354102 1.446757 1.902520 2.034088 2.526616 2.815041
+0.226181 0.693860 0.965201 1.130620 1.285879 1.475154 1.863626 2.238763 2.603071 2.788862
+0.105661 0.160079 0.370939 0.956425 1.151620 1.531460 1.723426 1.913560 2.122164 2.492465
+0.298984 0.431063 0.586646 0.778394 0.883075 1.252332 1.854971 2.007147 2.580641 2.710519
+0.197240 0.272225 0.520497 0.915877 1.306265 1.547858 2.092985 2.299254 2.524173 2.690593
+0.413504 0.577521 0.882547 1.151243 1.588968 1.757858 1.954145 2.157780 2.423490 2.567497
+0.182013 0.280163 0.398250 0.608531 0.819691 0.969023 1.853980 2.067111 2.358004 2.831492
+0.376103 0.585036 0.744512 0.923312 1.183525 1.290764 1.692231 2.073489 2.270157 2.435995
+0.206648 0.328267 0.465432 0.752470 1.311956 1.450538 1.719681 2.019809 2.237402 2.712715
+0.146386 0.213798 0.495001 1.215327 1.552462 1.867870 2.131376 2.312738 2.674961 2.807719
+0.204301 0.298214 0.439837 0.759917 0.957505 1.118467 1.710802 2.037862 2.222732 2.676717
+0.208889 0.314961 0.807094 0.979256 1.326634 1.615428 1.855738 2.074151 2.481053 2.662164
+0.252094 0.321219 0.425486 1.124218 1.685315 1.954485 2.094831 2.253423 2.478229 2.605367
+0.454303 0.738006 1.152178 1.340103 1.644779 1.957406 2.329060 2.526950 2.700749 2.789332
+0.260026 0.460186 0.631124 0.860895 1.160270 1.274078 1.873660 2.167213 2.365849 2.770340
+0.188841 0.259372 0.483027 0.884169 1.354974 1.505271 1.787912 1.916914 2.217944 2.371433
+0.171267 0.239784 0.594776 0.748624 1.254712 1.402634 1.627575 2.102077 2.361702 2.545685
+0.261290 0.332761 0.480740 1.272870 1.411888 1.585755 1.891613 2.059093 2.603683 2.753852
+0.174471 0.227361 0.395376 0.589674 1.098988 1.351413 1.527512 1.875704 2.288035 2.491253
+0.392523 0.493384 0.723718 0.863221 0.994939 1.404446 1.868453 2.008324 2.440145 2.622287
+0.229001 0.293967 0.482060 0.752040 1.321587 1.964756 2.143632 2.272231 2.511299 2.652857
+0.129576 0.441380 0.809457 1.253754 1.449504 1.695975 2.014264 2.282645 2.615841 2.803547
+0.291794 0.444574 0.567987 0.774856 0.900327 1.365457 2.004858 2.128537 2.620438 2.820651
+0.262097 0.516409 0.687606 0.926622 1.163526 1.292705 1.715555 1.937306 2.227923 2.777260
+0.148606 0.204513 0.361193 0.693710 1.055532 1.278718 1.693525 1.980097 2.352859 2.672283
+0.253802 0.336651 0.526195 0.891801 1.442978 1.584849 1.979819 2.247623 2.476136 2.660081
+0.228789 0.338363 0.500714 0.793809 1.196272 1.305413 1.731081 2.259108 2.442615 2.652754
+0.378062 0.473823 0.693080 1.009192 1.183244 1.328164 1.919726 2.260450 2.429886 2.572302
+0.247090 0.357491 0.583930 0.824533 1.624951 1.779841 1.978982 2.185311 2.378227 2.583823
+0.349863 0.525291 0.898639 1.154449 1.653664 1.882655 2.181526 2.353823 2.532309 2.660763
+0.190910 0.256714 0.576278 0.756016 0.919967 1.182918 1.663565 2.144466 2.501734 2.728244
+0.298865 0.359843 0.568492 1.131552 1.379757 1.490406 1.824274 1.945718 2.238708 2.644005
+0.075640 0.092838 0.245669 0.863294 1.223916 1.524202 1.857987 2.167767 2.516095 2.793204
+0.232965 0.332699 0.723652 1.036910 1.459468 1.595582 1.952510 2.172737 2.392688 2.562895
+0.247766 0.389477 0.616596 0.808130 0.997595 1.253872 1.724465 1.938385 2.286441 2.479069
+0.316879 0.442442 0.602552 0.812843 0.919668 1.524096 1.727104 1.959085 2.648008 2.744204
+0.180121 0.250848 0.377588 0.514084 1.112861 1.845482 2.013326 2.213933 2.474673 2.663237
+0.510891 0.729294 0.918315 1.009382 1.258580 1.685479 2.036454 2.223282 2.546829 2.685952
+0.204819 0.306851 0.495622 0.688481 0.939049 1.054525 1.550902 2.063497 2.267332 2.744891
+0.327442 0.389656 0.773076 1.023761 1.144959 1.391107 1.629777 1.826936 2.044965 2.488423
+0.163318 0.224949 0.377732 0.697324 1.243068 1.379089 1.633682 1.887173 2.332645 2.483657
+0.240171 0.293151 0.543472 1.269350 1.631535 1.739995 1.933642 2.084522 2.414170 2.650266
+0.179979 0.246939 0.396342 0.589909 0.919210 1.070722 1.642599 2.043006 2.217357 2.503273
+0.302811 0.355529 0.811588 1.166553 1.271468 1.626247 1.848829 1.997826 2.540939 2.669384
+0.283439 0.349236 0.510446 0.919208 1.451466 1.719296 1.870795 2.075959 2.292387 2.415026
+0.351847 0.508411 1.045930 1.254317 1.551190 1.805638 2.048595 2.229665 2.467316 2.616962
+0.266736 0.408066 0.559013 0.768550 0.973174 1.096776 1.669225 2.079118 2.239808 2.647906
+0.299839 0.538608 0.750887 0.937387 1.361442 1.507727 1.723958 2.019542 2.288365 2.433554
+0.184692 0.270218 0.419274 1.047374 1.395536 1.529142 1.783612 1.919322 2.399668 2.739026
+0.282417 0.355135 0.625619 1.193013 1.365194 1.548352 1.961542 2.076835 2.555666 2.736510
+0.148276 0.201484 0.357526 0.691839 1.109393 1.590808 1.929494 2.052123 2.288831 2.674265
+0.239872 0.340799 0.510028 0.754201 1.021805 1.444270 2.086249 2.268881 2.498859 2.644372
+0.229200 0.356617 0.469799 0.697079 1.459153 1.736841 1.888964 2.204606 2.435847 2.594633
+0.235297 0.299631 0.756788 1.069754 1.591291 1.782731 1.990029 2.186477 2.404269 2.551371
+0.153218 0.216649 0.366074 0.591966 0.786672 1.337023 1.751677 1.932515 2.401392 2.607477
+0.264340 0.436803 0.595010 0.767010 1.179494 1.352438 1.528478 1.996792 2.441404 2.572631
+0.204113 0.325813 0.640860 0.803282 1.276398 1.511437 1.769275 2.073412 2.562526 2.723891
+0.183616 0.242809 0.370321 0.932837 1.683840 1.816525 2.211177 2.406486 2.636015 2.765906
+0.196637 0.265829 0.439050 0.770452 1.054669 1.487115 1.916956 2.043030 2.176612 2.349845
+0.540575 0.704261 0.884898 1.106375 1.273439 1.431611 1.908872 2.163885 2.347449 2.530928
+0.258740 0.346556 0.466932 0.905095 1.485463 1.645285 1.873902 2.133924 2.308179 2.675230
+0.347296 0.582875 0.945844 1.279162 1.499633 1.852636 2.184304 2.463318 2.760760 2.870853
+0.150936 0.266396 0.672274 0.842540 1.058933 1.395955 1.763874 2.053646 2.603603 2.795989
+0.248334 0.323639 0.796411 0.974630 1.217472 1.616989 1.786496 1.995745 2.426072 2.572132
+0.171528 0.226268 0.387197 0.596052 1.219235 1.373257 1.802693 2.162095 2.401149 2.694122
+0.309880 0.375034 0.782497 0.936541 1.130945 1.571152 1.743522 2.158706 2.484175 2.596635
+0.211833 0.283751 0.471901 0.833897 1.238193 1.611788 1.813797 2.021568 2.299015 2.453586
+0.325164 0.495780 0.668458 0.977772 1.204875 1.377736 1.792224 1.981132 2.470212 2.687064
+0.181910 0.238625 0.380080 0.551818 1.284137 1.815502 2.100874 2.224073 2.678894 2.832381
+0.432484 0.602036 0.967559 1.355422 1.539906 1.638130 2.062617 2.274317 2.408629 2.586735
+0.223933 0.320440 0.455471 0.635789 0.775870 0.919569 1.655549 2.258604 2.454533 2.743063
+0.366581 0.460393 0.676450 1.035749 1.222446 1.344767 1.892128 2.136552 2.294736 2.535285
+0.163193 0.228589 0.372272 0.655743 1.215923 1.357562 1.812178 2.049878 2.219187 2.622506
+0.199107 0.255898 0.383597 1.460200 1.573471 1.769089 1.990458 2.299624 2.582669 2.742646
+0.171634 0.266479 0.432062 0.687765 0.835208 1.354791 1.779760 1.939277 2.152823 2.654474
+0.322744 0.454468 0.896616 1.075278 1.276965 1.525868 1.809606 2.045119 2.396969 2.600609
+0.185456 0.225713 0.593805 0.777028 1.383381 1.756301 1.909552 2.182404 2.428047 2.628560
+0.523864 0.996370 1.345344 1.500637 1.856758 1.976312 2.235904 2.414483 2.560231 2.666268
+0.224472 0.316210 0.461082 1.069924 1.226634 1.409037 1.539144 2.110751 2.541082 2.731841
+0.282572 0.449304 0.655998 0.827960 1.292714 1.495327 1.771585 2.007810 2.430764 2.621645
+0.129294 0.178584 0.451465 1.015109 1.245704 1.462743 1.785107 2.042319 2.339740 2.626045
+0.266450 0.311925 0.672071 1.272373 1.586471 1.680518 1.967287 2.126302 2.331703 2.606765
+0.155912 0.210793 0.359734 0.582139 0.993095 1.506017 1.938903 2.072031 2.211582 2.514161
+0.366487 0.454941 0.765153 0.933105 1.077517 1.457225 1.642714 2.050965 2.548495 2.660408
+0.183421 0.269815 0.375652 0.582732 1.364229 1.857303 2.030324 2.188264 2.389621 2.554337
+0.157986 0.433220 0.872229 1.187796 1.412974 1.724479 2.144349 2.464695 2.761508 2.877055
+0.198383 0.350654 0.577264 0.787611 0.933392 1.119024 1.806604 2.076373 2.430526 2.603043
+0.184568 0.290732 0.456474 0.730730 1.167452 1.298890 1.669065 1.850198 2.187295 2.556672
+0.119787 0.157206 0.296086 0.580699 1.039340 1.448681 1.791765 2.115501 2.493729 2.765061
+0.197875 0.296866 0.460866 0.906361 1.504895 1.622424 1.923913 2.064370 2.528505 2.799113
+0.215006 0.360632 0.624855 0.788786 1.122529 1.271335 1.469548 2.029397 2.292842 2.469529
+0.312967 0.420596 0.594715 1.013895 1.177345 1.350956 1.928177 2.047807 2.512550 2.690404
+0.306441 0.447709 0.635622 0.837489 1.339889 1.684905 1.878731 2.050783 2.442345 2.559302
+0.512714 0.732554 1.090397 1.458930 1.653272 1.872563 2.243616 2.386971 2.644360 2.753299
+0.338380 0.388353 0.687865 0.937576 1.022955 1.198008 1.345071 1.507334 2.539150 2.676481
+0.404547 0.489770 0.787746 1.025925 1.160826 1.496135 1.873747 1.995764 2.348409 2.558815
+0.185178 0.273616 0.662107 0.944310 1.146715 1.437855 1.860110 2.088161 2.488532 2.701156
+0.297691 0.433807 0.689073 0.914516 1.224645 1.524468 1.882477 2.108378 2.460989 2.729694
+0.246421 0.329313 0.740815 0.903181 1.072400 1.285931 1.740684 2.032245 2.270116 2.425587
+0.349571 0.509003 0.727457 0.878169 1.005363 1.205249 1.651188 1.987842 2.609611 2.723475
+0.174962 0.249723 0.401862 0.559808 1.151652 1.704681 1.872495 2.239764 2.430897 2.686106
+0.360336 0.530604 0.935905 1.180560 1.399529 1.740890 1.999598 2.182066 2.486093 2.641677
+0.220231 0.312545 0.449608 0.705056 1.007679 1.135090 1.633644 2.306528 2.622813 2.773890
+0.343635 0.564980 0.719160 0.856829 1.120400 1.237963 1.472239 1.924690 2.221264 2.357713
+0.181932 0.261428 0.385382 0.529871 1.326078 1.525795 1.689465 2.161317 2.354960 2.559655
+0.190215 0.341309 1.145487 1.357611 1.520525 1.690701 1.910605 2.192963 2.496750 2.684620
+0.231256 0.323986 0.509297 0.695026 0.811246 1.205058 1.698676 1.952659 2.225356 2.436417
+0.232855 0.310052 0.551612 0.995822 1.160276 1.555029 1.794030 1.930657 2.512921 2.691535
+0.224518 0.299721 0.651543 0.885427 1.520642 1.679516 1.886989 2.041276 2.532253 2.699897
+0.204419 0.557694 1.100186 1.347777 1.507922 1.794663 2.079200 2.312468 2.590685 2.744668
+0.206125 0.397544 0.556512 0.740671 0.860709 1.076989 1.713565 1.825995 2.561599 2.767561
+0.271126 0.422296 0.596820 0.801216 1.362100 1.508235 1.854835 2.090662 2.270770 2.457032
+0.217883 0.344596 0.493190 0.984719 1.284852 1.446608 1.855635 2.014247 2.506491 2.663445
+0.286136 0.348718 0.879652 1.116298 1.280497 1.611569 1.788213 2.223036 2.485667 2.605528
+0.206618 0.325875 0.503268 0.690657 0.816866 1.603798 1.931282 2.048093 2.300900 2.746683
+0.239837 0.367432 0.586673 0.749249 1.029445 1.541977 1.837717 2.152675 2.628130 2.775655
+0.154164 0.222772 0.333818 0.562653 1.465627 1.728492 1.959659 2.326185 2.619462 2.821726
+0.231365 0.366985 0.807033 1.157258 1.520494 1.640269 2.028108 2.269663 2.456856 2.630277
+0.242567 0.331771 0.487513 0.644276 0.800853 1.242217 1.739018 2.099717 2.426228 2.596782
+0.221262 0.374389 0.569573 0.704902 1.187721 1.414042 1.633903 2.049607 2.225608 2.522881
+0.182959 0.295198 0.401501 0.779683 1.428548 1.551019 1.766917 1.908320 2.610886 2.770247
+0.139632 0.228108 0.540279 0.898292 1.161261 1.527413 1.913196 2.221342 2.669902 2.842594
+0.199568 0.297036 0.423971 0.782421 1.094574 1.237964 1.458722 1.683022 2.217064 2.401823
+0.345577 0.539506 0.728116 0.928242 1.109271 1.252921 1.616753 1.872570 2.294941 2.593196
+0.232502 0.366195 0.532625 0.762469 1.377487 1.543949 1.839468 2.094305 2.306962 2.746485
+0.140704 0.240287 0.914003 1.159689 1.490769 1.781986 2.113189 2.322630 2.553898 2.735752
+0.182050 0.274243 0.384886 0.753150 1.226502 1.367895 1.578386 1.756614 2.368689 2.613973
+0.296233 0.395081 0.622990 1.050299 1.209800 1.377648 1.850837 1.965328 2.357424 2.667891
+0.210632 0.289301 0.558974 0.972835 1.230379 1.669485 1.879551 2.047374 2.584468 2.764860
+0.238075 0.443727 0.795624 1.008735 1.264607 1.681476 1.949029 2.204123 2.681059 2.831198
+0.209107 0.318887 0.502202 0.936331 1.215090 1.364179 1.664829 1.835085 2.029832 2.237236
+0.210399 0.360507 0.466140 0.793696 1.167290 1.269402 1.717457 1.883978 2.332357 2.642576
+0.182774 0.238064 0.406254 0.553908 1.089357 1.921943 2.114739 2.269998 2.553977 2.719355
+0.328207 0.496148 0.997544 1.217533 1.381558 1.589977 1.895773 2.171180 2.563942 2.756785
+0.146726 0.209578 0.327902 0.527454 0.750165 0.964221 1.730110 1.909856 2.277000 2.794161
+0.355489 0.509819 0.674351 0.852118 1.030963 1.155918 1.581384 2.041691 2.263390 2.416994
+0.220775 0.394332 0.538938 0.857502 1.090722 1.239600 1.901251 2.063868 2.417954 2.814398
+0.227931 0.269928 0.659119 1.441707 1.726640 1.837599 2.172077 2.323353 2.607646 2.741321
+0.204294 0.338820 0.480507 0.748377 0.971841 1.112524 1.682403 1.842741 2.204016 2.598799
+0.134004 0.253595 0.893064 1.145993 1.324870 1.551540 1.870979 2.144984 2.515124 2.768074
+0.257317 0.324072 0.436271 0.992642 1.573175 1.838976 1.971813 2.132071 2.317177 2.463177
+0.440270 0.694478 1.072028 1.389390 1.760193 1.976248 2.246033 2.390948 2.572760 2.701541
+0.271868 0.367973 0.618954 0.990978 1.193710 1.400934 1.753507 2.089331 2.441172 2.596397
+0.327621 0.496909 0.684291 0.830070 1.230609 1.553632 1.769123 2.021449 2.321602 2.475665
+0.150834 0.225465 0.584436 0.830787 1.228446 1.381420 1.677267 1.961417 2.348329 2.682122
+0.210368 0.286671 0.430934 1.168493 1.348054 1.560861 1.788186 2.334928 2.567985 2.774704
+0.192791 0.272915 0.432199 0.684073 1.250160 1.396822 1.637113 1.872041 2.138995 2.291744
+0.317041 0.383173 0.714443 0.880122 1.046184 1.601600 1.793056 1.983005 2.334210 2.481632
+0.262491 0.384516 0.723463 0.898594 1.235333 1.679346 2.063633 2.230677 2.438434 2.609821
+0.329714 0.503133 0.986474 1.242112 1.421780 1.772248 2.016548 2.418708 2.735517 2.841414
+0.234483 0.366854 0.685189 0.837277 1.107168 1.323527 1.924146 2.188176 2.392339 2.576791
+0.367554 0.480477 0.685257 0.863574 0.967484 1.324325 1.780913 1.895223 2.217908 2.565386
+0.170831 0.247070 0.413674 0.735129 1.097256 1.244501 1.863046 2.116005 2.354145 2.593904
+0.191987 0.265143 0.522063 1.001132 1.477027 1.634641 2.128571 2.320908 2.626696 2.814549
+0.173820 0.236201 0.389631 0.565594 1.191995 1.339140 1.563074 2.078967 2.273323 2.569148
+0.376887 0.472762 0.685713 0.842626 0.950694 1.348880 2.073181 2.248666 2.464908 2.680293
+0.200511 0.267485 0.473655 0.709045 1.237600 1.615428 2.015635 2.177003 2.363079 2.525359
+0.179632 0.571501 0.993053 1.356696 1.697465 1.978072 2.161225 2.343876 2.605905 2.752543
+0.171679 0.323767 0.479066 0.737860 0.967236 1.119767 1.534022 1.686592 2.597041 2.826056
+0.230844 0.314638 0.827482 1.044417 1.246762 1.604017 1.888847 2.034619 2.240069 2.646086
+0.137641 0.194410 0.446076 0.749008 1.056291 1.455419 1.852539 2.123128 2.508952 2.766009
+0.096036 0.420947 0.665747 1.146516 1.463996 1.612743 1.861963 2.227963 2.503650 2.739358
+0.245487 0.384590 0.558312 0.811909 1.198414 1.349136 1.841320 2.025572 2.208162 2.405870
+0.208252 0.316837 0.487011 0.938933 1.139581 1.396565 1.746724 2.105258 2.522568 2.681942
+0.283283 0.395565 0.569206 0.705427 1.140133 1.660691 1.900167 2.146532 2.523653 2.667587
+0.399059 0.602519 0.918365 1.124094 1.352400 1.574194 1.915640 2.120676 2.392517 2.583609
+0.212592 0.313545 0.489908 0.651935 0.827527 1.014819 1.629779 2.107560 2.651570 2.794154
+0.334733 0.413938 0.656403 1.035599 1.230100 1.372371 1.752515 1.932544 2.116066 2.340962
+0.195470 0.268391 0.431096 0.744590 1.272458 1.434994 1.887256 2.055124 2.216059 2.355652
+0.233843 0.277098 0.577590 1.353544 1.573248 1.679793 1.831093 1.982748 2.575813 2.732432
+0.140410 0.214833 0.361115 0.707069 1.082237 1.227591 1.633210 1.818367 2.466253 2.766104
+0.433646 0.517163 0.808168 1.061617 1.182393 1.497547 1.723696 1.907866 2.509297 2.679398
+0.251461 0.331356 0.713430 0.993326 1.485426 1.665910 1.856843 2.073870 2.333905 2.470116
+0.362946 0.782976 1.168741 1.324526 1.627412 1.779530 1.994819 2.203297 2.514465 2.683132
+0.283937 0.367927 0.590168 0.763650 0.889158 1.242000 1.768049 2.150831 2.361695 2.526931
+0.401929 0.576820 0.737804 0.921682 1.116842 1.229133 1.694656 2.010744 2.155271 2.356219
+0.212653 0.310679 0.420635 1.110694 1.371611 1.510937 1.878595 2.017471 2.541126 2.696793
+0.319899 0.406846 0.688156 1.227145 1.532072 1.647604 1.959419 2.112752 2.468573 2.688910
+0.213311 0.302778 0.513141 0.665182 1.070601 1.519880 1.688862 2.155925 2.405361 2.641935
+0.203445 0.273890 0.446788 0.621718 0.821718 1.552774 1.970174 2.157338 2.529885 2.666726
+0.179248 0.265048 0.386747 0.570219 1.370731 1.523935 1.867101 2.136819 2.309819 2.738000
+0.192568 0.286600 0.737250 1.129156 1.630027 1.793060 2.137459 2.357517 2.543832 2.752975
+0.159062 0.222492 0.441749 0.706956 0.873673 1.273730 1.807800 2.085052 2.433983 2.738811
+0.267122 0.464503 0.667094 0.815715 1.028866 1.162422 1.617585 2.164095 2.329764 2.612700
+0.144708 0.223957 0.317997 0.564825 1.508828 1.655161 1.857741 2.024989 2.639153 2.820953
+0.194645 0.249640 0.406742 0.707511 1.660221 1.859905 2.085456 2.405218 2.607363 2.746061
+0.429960 0.592124 0.787877 0.890595 1.103239 1.404765 1.789301 2.072362 2.432455 2.617254
+0.184536 0.285665 0.429789 0.950068 1.412318 1.523812 1.954708 2.141451 2.414013 2.765321
+0.369916 0.560855 0.927769 1.354226 1.560397 1.733808 2.189951 2.345823 2.725694 2.866959
+0.142852 0.219159 0.368392 0.659778 0.999846 1.194353 1.856812 2.065831 2.665677 2.850916
+0.209110 0.305167 0.683734 0.914276 1.379246 1.526394 1.790110 2.064232 2.299981 2.459264
+0.184899 0.316366 0.506466 0.728745 1.218050 1.378981 1.814293 1.999655 2.544039 2.730706
+0.286474 0.355126 0.718899 1.089400 1.225976 1.695737 1.936410 2.121418 2.444195 2.568086
+0.260728 0.353369 0.604610 0.768238 1.072125 1.608746 1.805375 1.949798 2.105786 2.406476
+0.330885 0.561445 0.724292 0.940383 1.093573 1.263066 1.930153 2.163533 2.408371 2.762449
+0.190585 0.245026 0.388935 0.531269 1.613901 1.940446 2.068138 2.295339 2.525519 2.695115
+0.659517 0.793695 0.983316 1.214573 1.426393 1.621779 1.948650 2.120559 2.402013 2.570449
+0.220748 0.332069 0.424610 0.602935 0.734265 0.935558 2.055617 2.265657 2.530681 2.854902
+0.290477 0.440845 0.612873 0.839848 1.327423 1.456572 1.939179 2.167778 2.371320 2.570765
+0.179431 0.280105 0.432734 0.918191 1.192829 1.320190 1.811052 1.955192 2.340353 2.782529
+0.202912 0.265690 0.431272 1.238667 1.481469 1.610194 1.975157 2.101548 2.630962 2.798935
+0.162106 0.210383 0.366556 0.543819 1.054714 1.205759 1.641024 2.015868 2.178793 2.627151
+0.317316 0.385969 0.673513 1.190904 1.357921 1.500892 1.894288 2.020919 2.379283 2.662802
+0.327266 0.429724 0.606313 0.900788 1.464235 1.816681 2.002694 2.138059 2.452853 2.554712
+0.416374 0.642735 1.300859 1.518625 1.707945 1.956089 2.222013 2.390921 2.684341 2.784854
+0.186066 0.250175 0.562512 0.738528 1.208585 1.362690 1.606043 2.109182 2.501183 2.707198
+0.236912 0.461787 0.686242 0.881092 1.300577 1.424620 1.725187 2.169489 2.361758 2.662324
+0.208063 0.337571 0.482777 0.926508 1.161683 1.311006 1.776451 1.933103 2.448810 2.646540
+0.256479 0.328343 0.499814 1.097457 1.386665 1.496809 1.952745 2.087139 2.342994 2.654825
+0.161661 0.224177 0.383379 0.607758 0.991555 1.381589 1.804283 1.998147 2.415608 2.619198
+0.386111 0.495518 0.750917 0.937387 1.069306 1.592878 2.091954 2.230429 2.574083 2.695163
+0.236835 0.303063 0.548777 0.748487 1.602860 1.790903 1.980987 2.173544 2.482285 2.674930
+0.115857 0.253229 0.839446 1.182318 1.604808 1.930292 2.262789 2.477033 2.731091 2.843896
+0.213435 0.341074 0.506347 0.714649 0.813915 1.154546 1.865334 2.056297 2.656061 2.833781
+0.152341 0.225866 0.394818 0.830840 1.039343 1.299776 1.515314 1.701937 2.172593 2.703933
+0.150002 0.193206 0.361814 0.541289 1.168971 1.515576 1.875006 2.181631 2.473830 2.750294
+0.175983 0.238402 0.392935 0.834832 1.568038 1.753001 1.950436 2.176878 2.408077 2.761430
+0.213829 0.318859 0.535586 0.713597 1.015672 1.174333 1.408597 2.083136 2.354086 2.563569
+0.417612 0.500513 0.811466 1.027816 1.139572 1.532510 1.959824 2.084676 2.544668 2.694259
+0.279259 0.446390 0.589074 0.796267 1.496946 1.723595 1.869786 2.100336 2.331076 2.456141
+0.444430 0.638237 1.041068 1.445315 1.605692 1.733619 2.167615 2.326214 2.602181 2.745455
+0.210087 0.362661 0.515500 0.840169 1.033119 1.239618 1.373615 1.803901 2.716235 2.848165
+0.225160 0.350738 0.501850 0.896968 1.297884 1.414194 1.669332 1.835349 2.075666 2.672832
+0.039211 0.113866 0.622349 0.907025 1.252791 1.535875 1.876167 2.163786 2.540348 2.789312
+0.126350 0.194309 0.675134 1.116698 1.365415 1.576318 1.849118 2.102016 2.438531 2.737802
+0.251266 0.342779 0.622143 0.793543 1.004128 1.433428 1.828192 2.011292 2.214652 2.441068
+0.287491 0.392893 0.575294 0.916666 1.023814 1.482149 1.829139 1.953760 2.589735 2.724978
+0.198423 0.295697 0.439598 0.609605 1.262768 1.619956 1.747689 2.005913 2.368608 2.490906
+0.358531 0.483574 0.802846 1.004510 1.351513 1.645034 1.955330 2.161545 2.477437 2.639225
+0.252099 0.385070 0.557560 0.740943 0.911070 1.013935 1.524718 2.136124 2.396009 2.750794
+0.277335 0.507312 0.745418 0.921396 1.189730 1.321635 1.630275 2.000574 2.318359 2.450355
+0.251729 0.359609 0.480792 0.813240 1.317908 1.441397 1.655896 2.171984 2.476511 2.611973
+0.267463 0.311514 0.756574 1.332619 1.482384 1.635505 1.872999 2.053016 2.640422 2.756993
+0.175657 0.240482 0.383528 0.598077 0.916809 1.091066 1.760568 1.946970 2.313700 2.484722
+0.308726 0.352539 0.822652 1.208001 1.295254 1.507386 1.644261 1.995003 2.594656 2.684930
+0.292332 0.442077 0.718688 0.941531 1.395212 1.630615 1.847265 2.270351 2.514492 2.713146
+0.215044 0.379718 1.248947 1.429713 1.705990 1.881505 2.089432 2.306464 2.505316 2.662383
+0.243250 0.359897 0.521676 0.699893 1.005116 1.271071 1.694794 2.008687 2.440679 2.593828
+0.300924 0.394176 0.559419 0.899409 1.454448 1.708566 1.869825 2.116095 2.376539 2.493592
+0.153405 0.251763 0.392574 0.866089 1.104658 1.286553 1.780043 1.916997 2.532174 2.688015
+0.279453 0.326159 0.753633 1.333374 1.499514 1.626480 1.898852 2.038525 2.500726 2.702071
+0.170059 0.229176 0.395854 0.705543 1.082349 1.588065 1.821443 1.949022 2.120108 2.537716
+0.202145 0.274872 0.419107 0.608489 0.758495 1.603432 1.748277 2.189578 2.559336 2.730653
+0.177888 0.251468 0.365661 0.658086 1.634785 1.816726 1.997979 2.183875 2.456958 2.811253
+0.317970 0.468942 0.803601 1.078125 1.370511 1.630999 1.971111 2.226246 2.543508 2.768268
+0.234066 0.324515 0.462757 0.683101 0.779120 1.399880 1.995585 2.098113 2.538242 2.655334
+0.226221 0.390737 0.587891 0.741564 1.148309 1.290898 1.572982 2.116901 2.296227 2.676682
+0.152380 0.275031 0.397732 0.652751 1.329373 1.439312 1.794813 1.940569 2.520664 2.797824
+0.166696 0.251629 0.512274 1.144842 1.315763 1.710247 2.178415 2.460971 2.703738 2.827969
+0.216867 0.347530 0.531282 0.706161 1.126385 1.301329 1.475176 1.901629 2.242013 2.431677
+0.300362 0.482595 0.791226 1.005231 1.156964 1.313455 1.691239 2.006858 2.373111 2.733635
+0.169474 0.255383 0.406046 0.734985 1.442352 1.579575 1.789148 1.957193 2.399133 2.566651
+0.130440 0.237458 1.032166 1.386551 1.711848 1.993258 2.268221 2.439261 2.683283 2.812111
+0.173867 0.278057 0.388656 0.749215 0.960862 1.146135 1.799140 1.979764 2.471783 2.619305
+0.242130 0.340749 0.474654 0.828524 1.328466 1.445245 1.802538 2.204747 2.373101 2.551440
+0.232537 0.347402 0.580048 1.030748 1.297867 1.477044 1.985462 2.164878 2.627119 2.813421
+0.187113 0.520796 0.877184 1.139100 1.389082 1.622317 1.923715 2.144320 2.454348 2.655504
+0.198782 0.276683 0.501229 0.913907 1.081324 1.395372 1.775624 1.940434 2.159949 2.585288
+0.219192 0.432472 0.587263 0.912549 1.202466 1.322625 1.811369 1.992180 2.458299 2.760505
+0.191165 0.276813 0.416963 0.651161 1.167971 1.294155 2.003249 2.230928 2.506110 2.774812
+0.363801 0.518796 0.957361 1.225911 1.566650 1.757756 1.962407 2.115286 2.359997 2.543054
+0.227701 0.362569 0.499430 0.731314 0.922719 1.040854 1.838698 2.164784 2.383067 2.810807
+0.465091 0.619804 0.778037 0.935635 1.093218 1.259037 1.829035 2.206537 2.404214 2.547685
+0.219345 0.331580 0.468701 0.864163 1.221425 1.316478 1.768475 2.078164 2.234895 2.666223
+0.202678 0.257891 0.463059 1.225499 1.595549 1.714423 2.230601 2.403829 2.599305 2.731507
+0.191295 0.292649 0.453931 0.663743 1.147168 1.275622 1.648493 2.119111 2.300099 2.725340
+0.202700 0.296043 0.842652 1.096103 1.432375 1.634580 1.849789 2.019083 2.373823 2.644180
+0.223698 0.286308 0.535549 0.951336 1.583619 1.712827 2.069074 2.228672 2.508621 2.712105
+0.393154 0.609187 1.147735 1.476125 1.660227 2.028129 2.280391 2.450954 2.687946 2.792306
+0.330421 0.541443 0.735477 0.935290 1.088544 1.300043 1.758898 2.291508 2.520235 2.677690
+0.228002 0.342730 0.476697 0.849764 1.368387 1.487565 1.712396 1.973744 2.334383 2.559863
+0.104462 0.175301 0.563572 0.921064 1.173139 1.367029 1.770789 1.951766 2.518901 2.747920
+0.195798 0.262376 0.397584 1.297059 1.483849 1.624630 1.820421 2.042136 2.481635 2.604228
+0.173538 0.223847 0.382154 0.562642 0.874661 1.340042 1.617180 1.932579 2.238320 2.383936
+0.257237 0.371721 0.696634 0.866614 1.045455 1.380460 1.752496 2.066892 2.504906 2.650308
+0.218997 0.321077 0.437617 0.666034 1.306150 1.849231 2.027564 2.199883 2.494261 2.649249
+0.320867 0.453548 0.918076 1.266491 1.422317 1.759869 1.998420 2.173922 2.635097 2.760926
+0.288066 0.410534 0.547460 0.760858 0.863292 1.068351 1.939410 2.167961 2.348114 2.767507
+0.218835 0.407925 0.654818 0.800374 1.153682 1.307829 1.657331 1.988984 2.263141 2.720996
+0.153945 0.202790 0.346143 0.519640 1.071723 1.237072 1.712069 1.893855 2.509996 2.744059
+0.248060 0.319372 0.459918 0.983442 1.443498 1.755178 2.100888 2.226747 2.447411 2.563325
+0.174462 0.227225 0.392742 0.571792 1.079416 1.257366 1.551460 2.042776 2.429302 2.629154
+0.274891 0.362315 0.660508 0.970740 1.151818 1.492509 2.072636 2.222125 2.494909 2.686200
+0.220299 0.317099 0.435591 0.793260 1.562295 1.723726 1.912306 2.110472 2.315517 2.618587
+0.350079 0.511699 0.888658 1.136538 1.502800 1.698163 2.138112 2.327492 2.505197 2.660921
+0.173175 0.286482 0.419571 0.629953 0.747452 1.073798 1.745440 1.887288 2.728362 2.862994
+0.302893 0.357795 0.579776 1.154149 1.373560 1.502096 1.831774 1.992189 2.178385 2.421943
+0.140345 0.186167 0.360424 0.858043 1.324588 1.624322 1.866334 2.036366 2.402471 2.617804
+0.207490 0.275386 0.532026 0.903652 1.559244 1.774707 1.962334 2.362983 2.596218 2.738415
+0.218842 0.320129 0.541623 0.875722 1.067991 1.362399 1.856837 2.024142 2.291054 2.645666
+0.341898 0.421854 0.677264 0.873738 1.018393 1.630494 1.868485 2.019716 2.616580 2.717499
+0.211631 0.278329 0.446819 0.679617 0.882530 1.848991 2.102209 2.280260 2.586273 2.750039
+0.400922 0.636971 0.853016 1.019114 1.364375 1.550804 1.850055 2.119999 2.453786 2.623222
+0.182154 0.242330 0.378923 0.509876 0.716576 1.076135 1.587035 2.069399 2.351207 2.660390
+0.400616 0.546715 0.729647 0.920762 1.100075 1.250132 1.664408 1.856723 2.067945 2.443519
+0.209711 0.304779 0.494008 0.698197 1.296713 1.461577 1.655811 1.885168 2.324920 2.489386
+0.248365 0.299675 0.641181 1.260844 1.683313 1.795634 2.022337 2.219236 2.445410 2.655259
+0.167092 0.244845 0.404157 0.672069 1.004556 1.174641 1.578514 1.897154 2.103236 2.709969
+0.429420 0.514025 0.817076 1.048094 1.187821 1.561651 1.826573 2.032100 2.492575 2.641130
+0.264974 0.350531 0.483895 0.953322 1.415379 1.541498 1.741521 2.171851 2.402443 2.527925
+0.416115 0.686348 1.016333 1.284030 1.627945 1.880349 2.143431 2.282669 2.504877 2.648617
+0.231020 0.416620 0.567188 0.760726 0.955087 1.089751 1.781039 1.967816 2.404279 2.797135
+0.416422 0.567520 0.709693 0.879615 1.302011 1.438085 1.678611 2.054536 2.326361 2.457927
+0.247904 0.324051 0.545383 1.111006 1.266454 1.612279 1.870112 2.027173 2.425991 2.655109
+0.279983 0.344606 0.621600 1.161229 1.307142 1.554450 1.784019 1.936785 2.444710 2.544691
+0.161547 0.223962 0.393255 0.741174 1.202310 1.599192 1.822694 1.937889 2.442478 2.729139
+0.340992 0.431955 0.678217 0.820520 0.999612 1.548630 2.164553 2.310748 2.585979 2.711488
+0.200183 0.279651 0.467745 0.730753 1.426170 1.607139 1.815853 2.220677 2.506455 2.727126
+0.274123 0.333601 0.517799 0.968069 1.665916 2.015026 2.169211 2.290528 2.535899 2.658723
+0.128641 0.167761 0.298260 0.447464 0.821352 1.285100 1.591690 1.879933 2.400984 2.764683
+0.198225 0.285988 0.697225 0.945530 1.135179 1.304018 1.590254 1.943114 2.370953 2.581323
+0.201444 0.271446 0.576127 0.726304 1.159527 1.677334 1.872822 2.127341 2.665189 2.807544
+0.198540 0.257454 0.402737 0.846677 1.689490 1.872412 2.034308 2.301368 2.545100 2.729540
+0.200348 0.278019 0.471514 0.752728 1.057356 1.291805 1.777614 1.916008 2.050356 2.172844
+0.466866 0.645308 0.804067 0.998786 1.191235 1.303931 1.785280 2.063043 2.218678 2.420840
+0.217955 0.321210 0.422194 0.865351 1.405153 1.526771 1.791058 2.088900 2.251039 2.667199
+0.168989 0.497826 1.018345 1.283132 1.493512 1.888380 2.226737 2.418452 2.616832 2.749197
+0.147852 0.218473 0.622343 0.825646 1.034661 1.220457 1.704813 2.051368 2.264302 2.712720
+0.202129 0.285808 0.640153 0.871843 1.173967 1.564865 1.834400 2.062497 2.412487 2.645130
+0.183772 0.259996 0.404816 0.684417 1.383605 1.536056 1.977056 2.169199 2.372324 2.556503
+0.306590 0.365918 0.723737 1.056338 1.191585 1.709401 1.978183 2.126256 2.594741 2.707129
+0.219620 0.295360 0.600693 0.751928 1.012492 1.554688 1.777591 1.936858 2.168459 2.637471
+0.484146 0.588901 0.779655 0.974444 1.078335 1.362035 1.861448 1.968026 2.308413 2.629418
+0.228810 0.270297 0.510434 0.721201 1.241319 1.730974 2.096849 2.211832 2.642499 2.808686
+0.400197 0.579628 1.063821 1.257463 1.434952 1.645068 2.017358 2.268483 2.625254 2.773542
+0.232047 0.335877 0.450404 0.618767 0.762409 0.943602 1.844169 2.391140 2.569963 2.779299
+0.315037 0.423610 0.597448 0.972112 1.370369 1.476900 1.783359 2.042461 2.209021 2.480610
+0.194589 0.300944 0.526012 0.730548 1.193408 1.383086 1.609867 1.882051 2.100633 2.703077
+0.215641 0.294490 0.558585 1.391554 1.487145 1.740600 1.911148 2.277087 2.578133 2.742082
+0.160391 0.226326 0.368755 0.670545 0.912912 1.286570 1.631159 1.807727 1.987079 2.498593
+0.313582 0.634117 0.786900 0.944061 1.309221 1.432287 1.720247 2.096637 2.283214 2.589845
+0.214437 0.264378 0.625288 0.975877 1.451393 1.848655 2.094494 2.248063 2.542408 2.690286
+0.532950 0.968164 1.239348 1.422500 1.673683 1.785201 2.010288 2.200155 2.489732 2.638101
+0.190399 0.270657 0.393327 0.864241 1.117361 1.553286 1.679497 2.236221 2.526322 2.700079
+0.287724 0.467671 0.675841 0.856838 1.284704 1.460878 1.649715 1.913527 2.422638 2.548168
+0.215869 0.300450 0.454163 1.082174 1.280570 1.465769 1.679659 1.869841 2.473902 2.623546
+0.274887 0.330100 0.521274 1.123699 1.527645 1.625993 1.931695 2.090005 2.295751 2.645233
+0.177139 0.223177 0.433328 0.774459 1.097689 1.467517 1.918942 2.134341 2.337195 2.540463
+0.346166 0.429209 0.673089 0.781966 1.198349 1.775370 1.954363 2.186438 2.523312 2.625185
+0.197636 0.296745 0.398712 0.631500 1.583954 1.843578 1.994071 2.173016 2.361743 2.519793
+0.356767 0.538545 0.898397 1.140796 1.519279 1.870556 2.168497 2.427459 2.643928 2.759816
+0.235015 0.349662 0.469548 0.816642 0.998816 1.146467 1.889133 2.097584 2.284986 2.765528
+0.167083 0.224131 0.448491 0.771954 0.948871 1.283667 1.621698 1.998899 2.223248 2.603115
+0.159315 0.217018 0.374226 0.590601 1.105826 1.536441 1.809766 1.960128 2.582005 2.795394
+0.168849 0.234032 0.344667 1.029831 1.622442 1.708285 2.016025 2.179960 2.644139 2.784632
+0.251075 0.442282 0.599669 0.763346 1.115735 1.253234 1.496825 1.992708 2.184264 2.666670
+0.388258 0.473926 0.719990 1.058667 1.198870 1.374618 1.864229 2.002653 2.271742 2.608038
+0.293347 0.422867 0.533090 0.863648 1.464010 1.686465 1.842829 2.008624 2.424518 2.579258
+0.422335 0.661725 1.188673 1.343060 1.557186 1.860452 2.239896 2.431450 2.631923 2.747718
+0.210220 0.335092 0.511807 0.760320 0.952999 1.125991 1.476685 1.647025 2.137411 2.688168
+0.373319 0.450044 0.685548 1.063488 1.214342 1.368881 1.749950 1.871124 2.228036 2.638333
+0.175282 0.247596 0.583289 0.800597 1.137160 1.494047 1.790222 1.974957 2.343536 2.783786
+0.154093 0.244641 0.765316 0.879236 1.262433 1.388927 1.719208 2.139465 2.523177 2.692366
+0.222311 0.296370 0.669831 0.821863 1.017560 1.348925 1.641603 1.852235 2.386204 2.585103
+0.372785 0.531082 0.729578 0.873202 1.002102 1.194509 1.654182 2.163378 2.555067 2.658778
+0.180452 0.250281 0.391345 0.554433 1.111079 1.737542 1.910605 2.127866 2.347054 2.534033
+0.447990 0.697721 0.913809 1.073923 1.398658 1.670558 1.960290 2.195050 2.584428 2.733637
+0.253764 0.410608 0.631333 0.803642 0.949880 1.072389 1.769476 2.303179 2.473513 2.749295
+0.249292 0.446941 0.652687 0.818128 1.175583 1.321675 1.534828 1.927620 2.151897 2.401118
+0.201342 0.301055 0.433733 0.667341 1.394399 1.542142 1.766411 2.222136 2.392138 2.617167
+0.263299 0.393237 0.913686 1.357749 1.580030 1.698507 1.930164 2.135083 2.415503 2.650696
+0.189848 0.308713 0.459867 0.797899 0.949965 1.168427 1.746219 1.919236 2.340878 2.529939
+0.236533 0.300777 0.705293 0.910173 1.158168 1.522892 1.727631 1.847056 2.544899 2.698351
+0.219264 0.293220 0.734905 0.969140 1.364696 1.628075 1.824426 1.921247 2.283403 2.660295
+0.231171 0.417787 0.828086 1.301747 1.563040 1.823547 2.038748 2.195446 2.600171 2.776056
+0.280635 0.391503 0.560168 0.699729 0.849390 1.139817 1.609055 2.003493 2.496847 2.631252
+0.329050 0.484505 0.654854 0.957533 1.414924 1.532367 1.798653 2.132845 2.332577 2.503880
+0.227219 0.317562 0.601344 0.991967 1.260680 1.430395 1.612725 1.766840 2.496056 2.645255
+0.270493 0.315583 0.641937 1.235995 1.409340 1.574822 1.760130 1.902696 2.598899 2.735147
+0.235474 0.326468 0.507399 0.696822 0.844939 1.633632 1.871816 2.063592 2.368254 2.525576
+0.233853 0.361484 0.482226 0.641979 0.992245 1.767823 1.952577 2.472579 2.742913 2.825489
+0.168433 0.243379 0.376538 0.823302 1.489064 1.619584 1.949821 2.203288 2.468309 2.771787
+0.206625 0.282620 0.554762 1.077945 1.286219 1.787257 2.045355 2.207994 2.522847 2.710409
+0.281540 0.359214 0.508755 0.689167 0.780776 1.277647 1.987095 2.102406 2.452824 2.573050
+0.240331 0.408023 0.587761 0.766784 1.268990 1.450068 1.614701 2.027579 2.386559 2.524671
+0.213600 0.378897 0.482559 0.820665 1.293224 1.395614 1.715777 1.852078 2.466446 2.706440
+0.192448 0.262539 0.378679 1.019763 1.468722 1.663670 1.910800 2.391601 2.621746 2.796560
+0.220322 0.364745 0.565226 0.783488 1.013662 1.175116 1.402286 1.885036 2.103704 2.324743
+0.322267 0.390833 0.713492 1.031629 1.156838 1.350887 1.515558 1.694139 2.382654 2.516728
+0.192624 0.294262 0.426181 0.741678 1.498008 1.633347 1.893062 2.059462 2.393665 2.782635
+0.237455 0.354262 0.864239 1.246075 1.666553 1.844678 2.174333 2.351099 2.520290 2.655921
+0.185359 0.302261 0.428703 0.781405 0.947101 1.141955 1.617902 1.761286 2.464616 2.634452
+0.271859 0.354517 0.569485 1.079860 1.240128 1.441296 1.944968 2.053805 2.406507 2.736827
+0.214936 0.298540 0.472345 0.913665 1.080008 1.684282 1.985267 2.173551 2.601519 2.749361
+0.318521 0.444000 0.739244 0.971075 1.303751 1.557191 1.918998 2.197692 2.552225 2.778091
+0.187184 0.266393 0.414559 0.873123 1.122008 1.345856 1.781616 1.932051 2.123625 2.364411
+0.212033 0.437364 0.587744 0.807841 1.008570 1.156068 1.667422 1.813734 2.388649 2.769182
+0.177749 0.231877 0.394438 0.587873 1.018115 1.532170 2.031818 2.176571 2.587458 2.778604
+0.397403 0.572539 1.117765 1.287841 1.469835 1.676483 1.995880 2.232196 2.496431 2.667425
+0.173937 0.259671 0.371889 0.555593 0.908572 1.118222 1.943858 2.087012 2.545553 2.816900
+0.296434 0.458071 0.635222 0.864989 1.198523 1.305471 1.672912 2.015023 2.193002 2.377815
+0.205052 0.312572 0.468685 0.774972 1.212302 1.316262 1.821237 2.193552 2.380352 2.766685
+0.240642 0.281687 0.717545 1.351376 1.501114 1.640455 2.046214 2.216028 2.588688 2.729942
+0.230445 0.421175 0.558602 0.846662 1.051701 1.197214 1.704701 1.838398 2.267565 2.697618
+0.276287 0.327977 0.824738 1.266737 1.373629 1.712792 1.891497 2.121117 2.537629 2.629970
+0.236249 0.310208 0.402132 0.954290 1.542483 1.886318 2.043856 2.203899 2.435931 2.547918
+0.323080 0.525410 0.940102 1.419025 1.732419 1.904886 2.278288 2.399903 2.613800 2.842137
+0.259462 0.384806 0.559454 0.827377 1.079010 1.194629 1.553023 2.150915 2.369416 2.537197
+0.309877 0.458904 0.634515 0.905896 1.340319 1.484136 1.732179 2.044813 2.234578 2.374887
+0.200760 0.267223 0.619798 0.880150 1.341984 1.566789 1.724877 1.834378 2.408354 2.666757
+0.232160 0.325786 0.611845 1.111911 1.277003 1.508409 1.711967 2.103218 2.470657 2.665982
+0.160381 0.206959 0.356984 0.510509 1.122026 1.271899 1.727695 1.943129 2.251421 2.380751
+0.339821 0.413428 0.663411 0.796136 0.920303 1.589702 1.879891 1.995622 2.491309 2.584399
+0.225236 0.289017 0.531590 0.689709 1.348190 1.761804 1.902696 2.175207 2.654910 2.781414
+0.283922 0.449613 0.777624 1.129523 1.487473 1.706799 2.164061 2.402885 2.691872 2.844990
+0.328301 0.439249 0.648655 0.897495 1.049452 1.222028 1.849808 2.229574 2.423163 2.565623
+0.236478 0.488322 0.656819 0.862950 1.144127 1.252241 1.694351 2.068901 2.226797 2.679600
+0.169945 0.258037 0.384767 0.609183 1.121274 1.266086 1.906028 2.054377 2.436068 2.795471
+0.177152 0.233124 0.534434 0.970496 1.404070 1.867414 2.171355 2.381133 2.619262 2.753148
+0.225245 0.323943 0.535205 0.711545 1.030041 1.268317 1.543910 1.921579 2.352057 2.531897
+0.380284 0.516944 0.727113 0.869680 1.061908 1.484627 1.847885 2.176267 2.550710 2.682243
+0.227653 0.311146 0.407614 0.830722 1.390383 1.796577 1.984514 2.172202 2.442702 2.597183
+0.395180 0.597222 0.988635 1.248608 1.649366 1.943305 2.114992 2.281535 2.610845 2.728627
+0.159527 0.253807 0.427177 0.703855 0.920030 1.359209 1.618673 1.774181 2.658938 2.839174
+0.232953 0.317175 0.734127 1.080631 1.332652 1.674943 1.899956 2.046773 2.307884 2.543358
+0.125436 0.171676 0.329679 0.770190 1.288629 1.482675 1.769818 2.055328 2.430854 2.715479
+0.108098 0.175220 0.776302 1.221645 1.460683 1.686249 1.929306 2.193619 2.536986 2.758891
+0.152357 0.202480 0.472758 0.861767 1.159578 1.340969 1.681897 2.048109 2.275054 2.477467
+0.216694 0.273656 0.664155 0.850536 1.153027 1.561670 1.759318 1.901416 2.353101 2.500133
+0.234504 0.329541 0.449717 0.797883 1.290186 1.691782 1.880443 2.100171 2.454967 2.611905
+0.423938 0.621841 0.996723 1.214793 1.409002 1.563377 1.783564 2.010297 2.490150 2.698586
+0.224661 0.325658 0.459910 0.625802 0.808594 0.895832 1.274078 2.111179 2.326505 2.585806
+0.276916 0.361107 0.729423 0.920236 1.053283 1.413110 1.741880 1.962097 2.139800 2.429514
+0.174802 0.232198 0.385912 0.540434 1.262000 1.441657 1.595105 1.943274 2.269839 2.417795
+0.265949 0.330919 0.614312 1.257075 1.438174 1.628356 1.917882 2.077892 2.425421 2.567960
+0.184742 0.272816 0.441616 0.641718 0.815915 1.210558 1.722330 1.942876 2.319698 2.747254
+0.390404 0.468994 0.743751 0.956882 1.081791 1.532303 1.750715 1.909157 2.466230 2.592626
+0.278150 0.353755 0.588139 1.120329 1.521033 1.629736 1.993707 2.192040 2.399567 2.620496
+0.431717 0.694505 1.256024 1.445196 1.671784 1.844456 2.028769 2.200956 2.506360 2.653075
+0.208110 0.276044 0.538093 0.719555 0.900539 1.075355 1.745222 2.086474 2.298600 2.556630
+0.352056 0.531509 0.676701 0.887365 1.282885 1.426632 1.614434 1.945858 2.270688 2.425511
+0.247241 0.356899 0.502519 1.065178 1.284311 1.437490 1.855456 1.992377 2.597541 2.776219
+0.396219 0.473793 0.715289 1.202273 1.346298 1.549130 1.940574 2.082739 2.514755 2.713815
+0.202378 0.285773 0.510159 0.640990 1.020854 1.686414 1.864702 2.133482 2.472249 2.625491
+0.136813 0.196375 0.389204 0.606996 0.826010 1.435725 1.829944 2.110031 2.522891 2.760011
+0.178586 0.265329 0.368903 0.594584 1.563859 1.743534 1.910893 2.088980 2.290832 2.753782
+0.326016 0.474212 0.821872 1.109710 1.491269 1.780679 1.990347 2.151819 2.439284 2.687522
+0.198877 0.303609 0.451495 0.660899 0.772185 1.284705 1.783160 1.923118 2.602735 2.756655
+0.279250 0.410975 0.617113 0.801949 0.990885 1.139677 1.438000 1.937681 2.530952 2.667930
+0.182348 0.288676 0.418208 0.638943 1.372299 1.531009 1.853629 2.058568 2.425537 2.822046
+0.235124 0.297027 0.512992 0.982242 1.579055 1.930478 2.096962 2.225930 2.572915 2.699703
+0.162278 0.215431 0.355780 0.485908 0.932607 1.181318 1.754127 1.988386 2.205810 2.337559
+0.508788 0.685414 0.844731 0.983038 1.244131 1.360404 1.646047 2.084834 2.375165 2.496801
+0.221912 0.310104 0.433571 0.978939 1.478709 1.587503 1.870190 2.010717 2.307807 2.780012
+0.359050 0.649694 1.005623 1.392268 1.637149 1.994024 2.239355 2.474016 2.727591 2.831065
+0.174907 0.277141 0.433141 0.954995 1.167887 1.336923 1.902421 2.052616 2.483944 2.686652
+0.193342 0.297566 0.824802 1.002859 1.285763 1.465909 1.800134 2.073494 2.392133 2.587289
+0.209852 0.288483 0.458682 0.843162 1.202473 1.352796 2.014405 2.202275 2.423702 2.568228
+0.276031 0.338955 0.858149 1.217747 1.357220 1.691136 1.841368 2.176457 2.647222 2.735745
+0.223125 0.303040 0.542560 0.703413 1.109469 1.691790 1.909510 2.043240 2.184955 2.383039
+0.338660 0.434962 0.644715 0.989980 1.142041 1.308641 1.862318 1.996732 2.219202 2.585521
+0.169788 0.227570 0.355680 0.476462 1.249736 1.884793 2.054427 2.245569 2.516757 2.692583
+0.510617 0.730414 1.008300 1.210250 1.460951 1.677387 1.984236 2.201040 2.503259 2.654324
+0.224817 0.351828 0.465847 0.709341 0.827775 0.992719 1.978367 2.142995 2.475303 2.800083
+0.308599 0.506317 0.673098 0.860582 1.161218 1.306099 1.811163 2.021896 2.233070 2.490125
+0.180388 0.242667 0.458646 0.739129 1.098421 1.521511 1.707512 1.853458 2.375659 2.563893
+0.191139 0.259717 0.375119 1.195018 1.535308 1.637017 1.945089 2.126276 2.528158 2.662854
+0.144026 0.195867 0.353543 0.581701 1.048420 1.377425 1.815657 1.969736 2.339863 2.778177
+0.384542 0.545846 0.742643 1.036203 1.274580 1.406237 1.737850 2.169732 2.446560 2.578757
+0.313042 0.444130 0.599720 0.924365 1.567785 1.748672 1.900293 2.194593 2.410541 2.573262
+0.492225 0.752280 1.124936 1.471295 1.758189 2.030974 2.238788 2.397439 2.680130 2.783434
+0.204117 0.347099 0.699998 0.845266 1.234413 1.419863 1.647535 2.080443 2.553390 2.707330
+0.257069 0.400082 0.558347 0.805346 1.259790 1.380823 1.608549 2.124230 2.308452 2.486914
+0.187028 0.318194 0.445217 0.923741 1.268789 1.390301 1.796420 1.931293 2.418538 2.603222
+0.243477 0.326319 0.635481 1.172112 1.360926 1.526662 2.109593 2.260517 2.545032 2.720529
+0.166613 0.243290 0.400708 0.657757 0.842275 1.476511 1.791837 1.950760 2.119370 2.472850
+0.311146 0.353401 0.824181 1.012251 1.149117 1.842349 2.055130 2.218062 2.570268 2.661992
+0.208668 0.283611 0.411201 0.809929 1.517017 1.823008 1.957049 2.229403 2.412596 2.626293
+0.154448 0.334483 0.779457 1.197447 1.370217 1.692002 1.980004 2.409686 2.713983 2.827926
+0.234171 0.317688 0.451503 0.830950 0.995999 1.149839 1.803812 2.310181 2.531615 2.732000
+0.268413 0.427669 0.559871 0.864380 1.275062 1.362920 1.581797 1.689453 2.226263 2.624807
+0.107565 0.142648 0.266262 0.674471 1.151548 1.464128 1.861043 2.141020 2.509385 2.783297
+0.182059 0.241841 0.379523 1.073956 1.618846 1.718260 1.915296 2.047758 2.360928 2.720733
+0.235150 0.374352 0.545815 0.714492 0.870405 1.000816 1.559351 1.984193 2.158182 2.596142
+0.434816 0.514709 0.756010 0.899497 1.037358 1.585142 1.834527 2.000422 2.564235 2.674345
+0.220087 0.341090 0.451896 0.734427 1.391206 1.582675 1.725710 2.141788 2.371107 2.511862
+0.482146 0.706990 1.033285 1.248170 1.467412 1.657558 2.147999 2.343164 2.600856 2.731213
+0.213401 0.322062 0.647358 0.791444 0.977300 1.281320 1.599647 1.939047 2.672620 2.797626
+0.266041 0.338577 0.634659 1.127429 1.295917 1.449033 1.658080 1.796624 2.285728 2.541842
+0.119705 0.174258 0.480098 1.063251 1.273831 1.476888 1.794829 2.119252 2.513047 2.762255
+0.132629 0.207248 0.566178 1.085083 1.427584 1.613863 1.889768 2.150853 2.557229 2.784690
+0.243227 0.327780 0.614668 0.761155 0.956760 1.516306 1.811880 2.030177 2.440252 2.582195
+0.276721 0.454860 0.642970 0.784038 1.148980 1.495704 1.703559 2.045787 2.591550 2.733608
+0.189778 0.287373 0.392353 0.645856 1.447021 1.617951 1.816249 2.137973 2.286683 2.572288
+0.400084 0.558491 0.869949 1.062095 1.467794 1.653306 1.899420 2.128461 2.442747 2.604032
+0.199764 0.300259 0.426072 0.645425 0.897550 1.048949 1.748510 2.273694 2.495239 2.649109
+0.296976 0.548524 0.761769 0.955832 1.233251 1.360741 1.693122 2.106225 2.391505 2.525275
+0.248971 0.399490 0.565645 0.720524 1.301434 1.542758 1.716234 2.124059 2.351786 2.681231
+0.230842 0.287955 0.878785 1.471322 1.627007 1.798878 2.005181 2.197775 2.563907 2.690549
+0.176416 0.248403 0.402172 0.733179 0.912580 1.227444 1.694562 2.088653 2.427226 2.563010
+0.330895 0.394275 0.774692 1.201779 1.321842 1.534733 1.782019 1.938050 2.422893 2.563017
+0.227080 0.299503 0.577295 0.756890 1.417382 1.624050 1.795338 2.177707 2.440812 2.572784
+0.411173 0.652311 1.207281 1.442451 1.795401 2.003085 2.140804 2.292980 2.639630 2.785365
+0.332277 0.425121 0.639151 0.821829 0.917909 1.367536 1.826675 1.939314 2.535595 2.654182
+0.345400 0.534948 0.689404 0.928224 1.433841 1.640941 1.825449 2.051581 2.274575 2.418295
+0.141590 0.233113 0.380526 0.868351 1.172524 1.363081 1.874782 2.001448 2.669736 2.855042
+0.309644 0.355571 0.694245 1.252006 1.460701 1.577178 1.853145 1.978370 2.227714 2.570337
+0.181796 0.242419 0.465928 0.715655 1.132014 1.662718 1.850134 1.972773 2.184021 2.722527
+0.270338 0.338307 0.544290 0.711724 0.871287 1.703598 1.918408 2.093313 2.668494 2.765585
+0.150135 0.233584 0.336008 0.740881 1.603784 1.723020 1.936836 2.077330 2.611782 2.783379
+0.294465 0.456340 0.870538 1.062801 1.291659 1.616175 2.070689 2.369390 2.648605 2.779945
+0.220578 0.311705 0.491111 0.847979 1.008368 1.532076 1.849702 2.005101 2.512156 2.669189
+0.229638 0.339951 0.513064 0.716308 1.121176 1.256758 1.479075 2.121337 2.503285 2.662824
+0.160524 0.210553 0.362234 0.595417 1.110208 1.477620 1.653645 1.883754 2.439740 2.625662
+0.236615 0.430340 0.682470 0.856444 1.159709 1.515913 1.944281 2.332831 2.633186 2.783526
+0.208672 0.301280 0.471802 0.926610 1.098592 1.288875 1.519452 1.800256 2.105532 2.428804
+0.243004 0.379283 0.831427 0.991746 1.231060 1.393310 1.679725 2.091152 2.354981 2.528458
+0.149934 0.192836 0.336118 0.489287 1.278027 1.443086 1.737711 1.939793 2.258510 2.725935
+0.162158 0.237674 0.813115 1.431297 1.690841 1.974269 2.228385 2.387649 2.645607 2.800036
+0.196527 0.310980 0.462098 0.736718 0.837132 1.268534 1.708387 1.848473 2.433059 2.576944
+0.217349 0.293339 0.438216 0.968725 1.350504 1.532480 1.911129 2.082089 2.268517 2.522732
+0.172105 0.253481 0.450363 0.927945 1.249256 1.437596 1.922782 2.218348 2.523926 2.733317
+0.289228 0.446047 0.832892 1.123024 1.277186 1.474382 1.792564 2.096649 2.561362 2.797590
+0.214142 0.283470 0.516137 1.061346 1.260972 1.417097 1.665641 1.862087 2.187452 2.353608
+0.235527 0.492936 0.614052 0.859127 0.993761 1.190535 1.848411 1.973235 2.500443 2.746547
+0.143271 0.207291 0.331889 0.827028 1.406412 1.555136 2.045910 2.231114 2.689514 2.839109
+0.343742 0.496860 0.865166 1.285087 1.588995 1.756794 2.022431 2.211289 2.468649 2.662665
+0.213309 0.328675 0.455568 0.723514 0.874048 1.082530 1.853818 2.038906 2.260788 2.778839
+0.356471 0.536984 0.755721 0.903361 1.038099 1.226007 1.687762 2.156339 2.420844 2.542644
+0.281664 0.451610 0.591581 0.828915 1.326665 1.477284 1.708022 2.017509 2.266128 2.700127
+0.135742 0.202004 0.583681 1.273102 1.602365 1.942380 2.228707 2.450342 2.728373 2.845988
+0.176935 0.288677 0.440469 0.786770 1.012958 1.172754 1.752038 1.913637 2.366577 2.766438
+0.207276 0.322804 0.788604 1.062222 1.294802 1.485775 1.944748 2.180022 2.397073 2.598545
+0.258418 0.319098 0.442127 1.133408 1.649338 1.854417 1.994251 2.185084 2.363409 2.534653
+0.230448 0.768093 1.180265 1.433576 1.687255 1.978844 2.259606 2.452430 2.659127 2.786279
+0.211701 0.332064 0.697403 0.880507 1.102252 1.277927 1.808607 2.273983 2.531209 2.736845
+0.245378 0.367568 0.512696 0.766674 1.343265 1.519747 1.697079 2.028107 2.215378 2.381457
+0.221209 0.324945 0.580820 0.748228 1.178564 1.431153 1.585928 1.927918 2.511054 2.643255
+0.201716 0.269175 0.401778 1.244589 1.471872 1.604627 1.805637 1.992744 2.610885 2.752593
+0.160780 0.247690 0.362958 0.624009 1.013756 1.182001 1.581983 1.735927 2.415792 2.646241
+0.320217 0.438376 0.710346 0.878476 1.032132 1.508649 1.972158 2.150849 2.428882 2.559870
+0.229810 0.276051 0.623852 0.830087 1.321297 1.854677 2.155401 2.284792 2.546209 2.690175
+0.172343 0.516169 0.866716 1.177175 1.468063 1.699344 1.986666 2.212830 2.511703 2.739129
+0.301807 0.360652 0.549602 0.672645 0.818574 1.362279 2.098253 2.278909 2.509794 2.695143
+0.294974 0.528192 0.672468 0.856772 1.265640 1.393603 1.638102 2.013275 2.218602 2.565642
+0.169196 0.238150 0.410484 0.644996 1.213738 1.372823 1.800122 1.969874 2.449498 2.615088
+0.184333 0.260633 0.376102 1.023515 1.545709 1.640728 2.037188 2.208164 2.488002 2.744323
+0.205806 0.304865 0.436462 0.616734 1.126032 1.261522 1.725527 2.275740 2.464199 2.702123
+0.184070 0.318390 0.717474 0.865476 1.106500 1.361536 2.038210 2.231225 2.554333 2.779851
+0.246294 0.360790 0.538254 0.736709 1.529013 1.795377 1.952814 2.142384 2.364128 2.495169
+0.353866 0.494646 0.877256 1.112783 1.566844 1.730636 2.025508 2.291163 2.453412 2.592313
+0.266813 0.432427 0.627311 0.754824 0.905537 1.197394 1.729117 2.123791 2.612331 2.827337
+0.273873 0.325959 0.540600 1.115405 1.498701 1.606801 1.814584 1.961539 2.188053 2.581605
+0.080925 0.099600 0.276658 0.947658 1.291923 1.611810 1.910613 2.219380 2.537903 2.797293
+0.168058 0.226944 0.705184 1.118312 1.428461 1.627351 1.878361 2.102812 2.397762 2.613552
+0.257821 0.370068 0.510355 0.878371 1.064949 1.223791 1.796480 2.039854 2.276323 2.505472
+0.243671 0.302629 0.595985 0.730818 1.062394 1.558183 1.727802 1.887397 2.590876 2.710615
+0.211122 0.278412 0.520693 0.699430 1.097533 1.812529 1.983523 2.189366 2.429825 2.610746
+0.256155 0.564923 0.839859 0.987034 1.191276 1.647157 2.021784 2.266855 2.558850 2.704555
+0.202989 0.292278 0.435910 0.640810 0.806537 0.924136 1.535334 2.086372 2.299823 2.572501
+0.261418 0.340324 0.627433 1.013276 1.180897 1.361209 1.731180 1.903731 2.106233 2.555098
+0.183272 0.269138 0.450407 0.909918 1.188568 1.381279 1.745735 1.872820 2.365239 2.484744
+0.230426 0.280037 0.644137 1.434869 1.666206 1.796575 2.015246 2.157224 2.561916 2.707798
+0.227013 0.347868 0.525371 0.707399 0.880208 1.091634 1.654713 1.951332 2.177455 2.319267
+0.380861 0.446326 0.749128 1.201643 1.336943 1.503446 1.800630 1.947582 2.527910 2.700466
+0.315223 0.375610 0.564441 1.017919 1.552234 1.710374 1.873741 2.122288 2.299878 2.473435
+0.446116 0.664203 0.984542 1.279400 1.574979 1.727934 1.978897 2.175567 2.469185 2.631008
+0.221571 0.330656 0.499929 0.777432 1.028387 1.180617 1.640596 2.168791 2.367015 2.714387
+0.421994 0.632233 0.778145 1.001218 1.346201 1.466628 1.720295 1.964067 2.152128 2.372888
+0.163687 0.242822 0.347278 0.971370 1.516739 1.620115 1.816941 1.949014 2.443334 2.638176
+0.284949 0.352677 0.685252 1.135143 1.255140 1.560889 1.905396 2.035214 2.547256 2.683043
+0.177362 0.243130 0.452833 0.824266 1.135565 1.520115 1.813864 1.958746 2.294091 2.563724
+0.178458 0.242386 0.592702 0.788280 1.051353 1.502905 1.934975 2.183628 2.477003 2.654310
+0.259519 0.407690 0.538212 0.728451 1.390298 1.713874 1.876895 2.109781 2.420753 2.577065
+0.255216 0.310327 0.589176 1.157266 1.687747 1.925407 2.045142 2.222504 2.425083 2.548028
+0.164446 0.206868 0.378009 0.525559 0.944579 1.419792 1.613300 1.889685 2.292641 2.565572
+0.240619 0.406939 0.588886 0.735213 1.146793 1.389773 1.537737 1.878402 2.297976 2.552226
+0.289310 0.418786 0.620314 0.764899 1.239942 1.612628 1.827524 2.107944 2.485462 2.639007
+0.198771 0.253637 0.405678 1.048168 1.663883 1.766039 2.128211 2.283365 2.560190 2.709800
+0.165963 0.230669 0.375008 0.692069 0.959835 1.378579 1.760825 1.948801 2.081418 2.369799
+0.523510 0.686129 0.825335 1.033919 1.330937 1.444794 1.739869 2.062844 2.315205 2.450730
+0.293681 0.417926 0.595503 0.957896 1.404495 1.522162 1.884014 2.096933 2.301269 2.621891
+0.359283 0.604669 1.076288 1.248249 1.451793 1.744413 2.125184 2.431489 2.687730 2.799316
+0.156185 0.235581 0.552175 0.813130 1.154557 1.326329 1.861696 2.153380 2.503796 2.787362
+0.290411 0.440558 0.736912 0.889007 1.171361 1.470366 1.794734 2.061516 2.373978 2.626041
+0.224936 0.320946 0.527542 0.738900 1.255619 1.428610 1.871090 2.256589 2.480524 2.694434
+0.288975 0.352962 0.777218 0.955880 1.109873 1.594800 1.813598 1.955710 2.589302 2.714964
+0.213548 0.285746 0.635954 0.830113 1.233322 1.591243 1.839168 1.977797 2.191863 2.623667
+0.336902 0.465806 0.655656 0.935793 1.068579 1.275847 1.761107 1.886493 2.444770 2.653299
+0.178879 0.258874 0.377390 0.527403 1.357599 1.761048 1.949090 2.163795 2.596422 2.759195
+0.430143 0.622963 0.955719 1.182584 1.497132 1.720157 2.044968 2.255285 2.544050 2.680998
+0.213810 0.308853 0.412187 0.569347 0.698344 0.951238 1.880619 2.207829 2.428571 2.828730
+0.230078 0.350112 0.747969 0.974442 1.265182 1.407146 1.813877 2.069124 2.247230 2.451871
+0.161458 0.227385 0.387324 0.640232 1.277813 1.478011 1.725217 1.915041 2.125833 2.645182
+0.200302 0.251181 0.381966 1.303694 1.547137 1.662388 2.120598 2.270182 2.603139 2.775037
+0.143149 0.204983 0.349581 0.667355 1.054734 1.399807 1.727708 1.850109 2.047799 2.715549
+0.337070 0.484021 0.803330 0.985730 1.331585 1.542266 1.830512 2.086973 2.445274 2.632911
+0.215583 0.269471 0.606879 0.945487 1.515635 1.750218 1.939935 2.174549 2.408151 2.576074
+0.534065 0.863487 1.372366 1.575333 1.866659 2.070622 2.218716 2.368585 2.634956 2.716254
+0.237658 0.350270 0.489196 0.956466 1.150453 1.341383 1.448597 2.345953 2.655585 2.785735
+0.233020 0.367323 0.713299 0.877999 1.226884 1.412189 1.743848 1.959402 2.416964 2.595603
+0.134934 0.190506 0.457228 0.942655 1.200550 1.509494 1.748249 1.912543 2.326213 2.742656
+0.297757 0.342592 0.625651 1.192568 1.540655 1.652384 1.875775 2.074460 2.224137 2.465967
+0.177286 0.234207 0.389716 0.517516 1.264974 1.424653 1.878090 2.150100 2.343577 2.537476
+0.281819 0.367413 0.659188 0.765361 1.004368 1.501384 1.726113 2.194951 2.534788 2.645854
+0.180979 0.252107 0.389029 0.570917 1.209940 1.699305 2.111361 2.224160 2.447867 2.620250
+0.256330 0.426903 0.826318 1.152683 1.487139 1.915114 2.246737 2.487453 2.705023 2.815420
+0.195539 0.316745 0.452617 0.833168 0.960504 1.269064 1.879314 2.025539 2.474377 2.680723
+0.203505 0.369568 0.536367 0.778820 1.088933 1.243750 1.588708 1.823497 2.020053 2.594631
+0.156418 0.198956 0.346275 0.496071 1.022702 1.572819 1.753592 2.143215 2.439211 2.674470
+0.160863 0.247666 0.345815 0.841020 1.523112 1.638256 1.887324 2.031339 2.509810 2.718796
+0.258214 0.480809 0.650419 0.801775 1.142337 1.283943 1.504959 2.054206 2.225835 2.474616
+0.303681 0.412740 0.649849 1.086617 1.266890 1.447470 1.896224 2.075119 2.565787 2.741747
+0.271067 0.413984 0.597954 0.768944 1.247881 1.606107 1.786404 2.085376 2.326363 2.529854
+0.521626 0.811390 1.129336 1.284608 1.629969 1.909728 2.228029 2.368756 2.570103 2.697107
+0.303633 0.421526 0.573677 0.925024 1.125497 1.258550 1.501212 1.610013 2.249352 2.608832
+0.411522 0.503523 0.746692 1.046522 1.172005 1.384521 1.797259 1.900603 2.387578 2.660719
+0.175711 0.239782 0.620582 0.952051 1.278311 1.501826 1.917072 2.130700 2.368785 2.608122
+0.164631 0.422501 0.724319 0.950544 1.214644 1.491261 1.799734 2.067799 2.473726 2.757283
+0.193259 0.281162 0.690376 0.855405 1.232753 1.402146 1.689327 1.991274 2.228334 2.435353
+0.301425 0.429993 0.650401 0.873662 1.008503 1.369274 1.690750 1.825918 2.520079 2.683664
+0.155700 0.201237 0.338696 0.505340 1.147916 1.472901 1.941300 2.074514 2.326431 2.663368
+0.350326 0.535475 0.827403 1.201270 1.427031 1.581852 1.963067 2.220906 2.472991 2.668217
+0.279035 0.416052 0.604816 0.794888 0.990688 1.105072 1.420018 2.166296 2.539337 2.676318
+0.278246 0.394509 0.777126 0.921607 1.080479 1.281224 1.433634 2.046850 2.283781 2.454104
+0.158340 0.199119 0.354050 0.555065 1.177314 1.442096 1.685385 2.144139 2.396032 2.716012
+0.247102 0.317737 0.855614 1.333153 1.454453 1.787157 1.970697 2.269614 2.586000 2.679846
+0.202515 0.257270 0.542126 0.724324 0.933997 1.317188 1.717435 2.091303 2.303481 2.469447
+0.295032 0.375581 0.775220 1.057728 1.185439 1.521116 1.807145 1.955630 2.459124 2.631564
+0.266524 0.353178 0.553809 1.043318 1.444903 1.560508 1.829729 1.962933 2.504864 2.699633
+0.392075 0.574661 1.110281 1.317280 1.473545 1.883432 2.051877 2.263410 2.613387 2.737894
+0.168326 0.277952 0.453865 0.702950 0.855434 1.035959 1.678564 1.811649 2.430121 2.811216
+0.301453 0.416493 0.552087 0.857890 1.446563 1.610970 1.775934 2.104633 2.298771 2.438580
+0.296445 0.422883 0.572322 1.053033 1.294027 1.427183 1.752752 1.892326 2.450076 2.720985
+0.291284 0.337800 0.787813 1.245129 1.350343 1.575395 1.771522 2.054749 2.520469 2.632047
+0.138710 0.200016 0.384208 0.667517 0.930105 1.493340 1.923603 2.079511 2.389298 2.733779
+0.280864 0.419489 0.614429 0.763022 1.011923 1.456038 1.644559 2.246694 2.668232 2.789516
+0.145213 0.217524 0.328786 0.706480 1.529301 1.661988 2.106773 2.330515 2.581680 2.792686
+0.265809 0.345868 0.597082 1.070990 1.497116 1.633533 2.139627 2.280686 2.512817 2.668144
+0.208788 0.353537 0.448428 0.744542 0.832763 1.081624 1.871188 2.032083 2.429608 2.599530
+0.238916 0.386378 0.542985 0.766669 1.174876 1.281048 1.635077 2.080947 2.247664 2.488499
+0.203556 0.321547 0.427750 0.977606 1.419067 1.509630 1.819297 1.946189 2.580163 2.776386
+0.139996 0.214290 0.381653 0.921888 1.276433 1.581217 1.904101 2.138537 2.662439 2.833853
+0.212852 0.314107 0.462617 0.919913 1.063259 1.256340 1.466783 1.677489 2.033592 2.181966
+0.466600 0.630996 0.782487 0.940455 1.238899 1.391865 1.580807 1.885579 2.314316 2.461513
+0.227025 0.350571 0.564570 0.792724 1.354349 1.541346 1.801883 2.207919 2.410212 2.682787
+0.249981 0.396397 0.985691 1.264822 1.534123 1.871221 2.123754 2.286134 2.517526 2.674066
+0.177530 0.299649 0.406845 0.735920 1.226985 1.334179 1.570608 1.724780 2.559215 2.784411
+0.331581 0.410000 0.675272 1.110025 1.255576 1.427242 1.924905 2.045160 2.303923 2.638796
+0.210022 0.302618 0.477941 0.890428 1.097541 1.628245 1.909906 2.220072 2.508520 2.652118
+0.243446 0.420405 0.781875 1.124911 1.345163 1.548171 1.986124 2.256316 2.655998 2.839208
+0.200937 0.269954 0.466285 0.792334 1.180229 1.434359 1.791176 1.944075 2.077160 2.197213
+0.251311 0.446771 0.586446 0.941160 1.156270 1.303306 1.672045 1.830703 2.385130 2.761692
+0.176967 0.213758 0.376271 0.498915 1.047907 1.738519 2.144585 2.257100 2.630427 2.811560
+0.352772 0.503472 0.939563 1.201270 1.506542 1.660120 1.860724 2.068816 2.441126 2.640996
+0.178023 0.303052 0.386553 0.624462 0.745438 0.945475 1.851506 1.982051 2.478715 2.678062
+0.364266 0.492788 0.670783 0.846141 0.981327 1.137049 1.747901 2.123325 2.278768 2.451425
+0.194628 0.412302 0.576670 0.847302 1.093833 1.250221 1.832799 1.978334 2.268735 2.705748
+0.210126 0.261821 0.730491 1.414850 1.596688 1.714047 2.240294 2.394580 2.609061 2.726773
+0.269651 0.402612 0.565711 0.760525 0.889819 1.107327 1.796638 1.997957 2.232105 2.568438
+0.133808 0.231770 0.964886 1.241597 1.484042 1.687250 1.909900 2.150489 2.488549 2.709142
+0.306823 0.378775 0.528651 1.056677 1.597646 1.784457 1.922205 2.165550 2.402629 2.533249
+0.406081 0.580663 1.171379 1.458297 1.720903 1.880717 2.213995 2.369466 2.530713 2.666970
+0.228294 0.391754 0.668996 0.852912 1.156334 1.293279 1.648848 2.231024 2.414612 2.628285
+0.302709 0.472535 0.626855 0.843574 1.352641 1.488643 1.688728 2.088022 2.315798 2.484648
+0.174773 0.243410 0.746413 0.964816 1.191099 1.363990 1.763375 2.002057 2.265912 2.600431
+0.208518 0.277532 0.471186 1.268798 1.353448 1.735767 1.868117 2.374184 2.641977 2.776723
+0.181223 0.240142 0.433185 0.698630 1.302639 1.456283 1.718530 1.991528 2.237981 2.340398
+0.351292 0.440375 0.723077 0.926148 1.074170 1.439999 1.696850 1.901716 2.300430 2.453901
+0.226417 0.295615 0.571000 0.984080 1.315950 1.698856 1.941891 2.121713 2.342505 2.579999
+0.380156 0.575056 0.932765 1.215036 1.441177 1.764868 2.084529 2.309314 2.649989 2.795048
+0.327618 0.406456 0.591362 0.776642 0.880344 1.202380 1.954155 2.143987 2.351308 2.562503
+0.349506 0.502746 0.667403 0.858540 1.006257 1.182652 1.744117 1.942048 2.263027 2.631113
+0.177120 0.223929 0.376392 0.517683 0.980327 1.245272 1.809519 2.111620 2.342282 2.674853
+0.123205 0.175349 0.396680 1.076230 1.369038 1.673956 1.959621 2.213420 2.585626 2.780840
+0.199931 0.299170 0.450172 0.705023 1.188319 1.349840 1.579504 2.154568 2.351041 2.525566
+0.302167 0.465527 0.626305 0.861772 0.982600 1.308182 1.952424 2.093800 2.477514 2.675986
+0.242409 0.306396 0.609503 0.781681 1.304327 1.721020 1.925053 2.059600 2.219491 2.531271
+0.355459 0.562814 1.005674 1.276256 1.699547 1.938826 2.256737 2.427235 2.599155 2.727721
+0.151530 0.250374 0.398298 0.598018 0.779517 1.173799 1.570201 1.708674 2.564516 2.838232
+0.220397 0.279236 0.757790 1.106570 1.277089 1.577301 1.822237 1.978751 2.121441 2.474720
+0.153326 0.218116 0.394366 0.701525 1.051329 1.626441 1.887066 2.073879 2.602080 2.787764
+0.234610 0.396895 0.841428 1.067362 1.368124 1.669319 1.979920 2.264168 2.548149 2.700534
+0.210859 0.310938 0.499147 0.721086 1.174085 1.319358 1.795112 2.119739 2.328704 2.523434
+0.205900 0.309942 0.473488 0.788729 0.910899 1.492677 1.711470 1.896973 2.451938 2.620192
+0.228664 0.320277 0.483685 0.662193 1.183931 1.743195 1.934444 2.129302 2.472394 2.610315
+0.308768 0.504829 0.834602 1.135142 1.422684 1.603830 1.804246 2.039329 2.434630 2.712164
+0.195372 0.307825 0.510685 0.705293 0.862776 0.987472 1.561941 1.940733 2.431850 2.813875
+0.306758 0.363734 0.676055 1.018763 1.123399 1.370232 1.612188 1.792290 2.051896 2.212304
+0.175686 0.229897 0.430909 0.821342 1.267737 1.439041 1.813710 2.050941 2.367020 2.513483
+0.270387 0.314704 0.625717 1.328248 1.485768 1.648429 1.945037 2.074570 2.558789 2.681083
+0.150545 0.249063 0.484485 0.650722 0.926307 1.336973 1.578609 1.727988 2.372974 2.800106
+0.451543 0.550287 0.774083 1.017766 1.117810 1.452119 1.851289 1.956638 2.541998 2.714928
+0.303976 0.365108 0.645290 1.163674 1.649225 1.816629 1.956898 2.167435 2.334752 2.499609
+0.258346 0.804804 1.233083 1.450024 1.793938 1.975438 2.178153 2.350853 2.545268 2.695382
+0.305873 0.411332 0.559751 0.770260 0.870638 1.070601 1.844362 2.171189 2.331380 2.561172
+0.328067 0.572423 0.818346 0.977873 1.251504 1.396022 1.679055 2.003477 2.202890 2.376892
+0.233685 0.324374 0.505263 1.162727 1.383328 1.533712 1.921509 2.038933 2.644680 2.830387
+0.368811 0.446580 0.830711 1.314440 1.454376 1.633636 1.932315 2.093222 2.523433 2.696884
+0.225386 0.331700 0.499419 0.651259 1.081776 1.536183 1.684810 2.115502 2.326023 2.493957
+0.223044 0.298517 0.436019 0.582229 0.785616 1.768538 2.059742 2.207026 2.494017 2.696171
+0.180285 0.258337 0.369821 0.519766 1.426414 1.652781 1.844922 2.044342 2.221032 2.715648
+0.283330 0.386958 0.793201 1.012390 1.401661 1.814923 2.032214 2.252691 2.478442 2.623605
+0.192303 0.289501 0.500660 0.766599 0.927796 1.379237 1.761645 2.133602 2.524890 2.706929
+0.240366 0.425376 0.713195 0.854560 1.062811 1.239666 1.453114 2.086242 2.409526 2.579680
+0.137084 0.190186 0.315294 0.519061 1.348977 1.578096 1.776272 1.932718 2.478330 2.764053
+0.256575 0.299517 0.557847 0.772199 1.734591 1.838024 2.175501 2.380904 2.586733 2.722357
+0.152502 0.184110 0.342575 0.500794 0.869142 1.091892 1.283627 1.913051 2.078861 2.216081
+0.422116 0.624411 0.936013 1.075293 1.214093 1.394857 1.793604 2.068743 2.420462 2.621433
+0.172110 0.265160 0.376968 0.872523 1.415505 1.522936 1.876576 2.026326 2.412597 2.784541
+0.206316 0.484509 0.867999 1.264771 1.619155 1.941304 2.179857 2.450350 2.746320 2.859252
+0.183287 0.327870 0.479087 0.793937 1.054850 1.228053 1.799851 2.057544 2.605366 2.808018
+0.199645 0.251567 0.651339 0.845163 1.224263 1.400865 1.849917 2.073362 2.320314 2.465281
+0.172950 0.268061 0.408629 0.749321 1.232382 1.363027 1.833510 1.995806 2.311255 2.818028
+0.383755 0.436949 0.854750 1.093429 1.211736 1.678565 1.897539 2.135411 2.547959 2.639036
+0.206666 0.277792 0.525267 0.971550 1.150633 1.543543 1.818711 1.982032 2.192940 2.418823
+0.297704 0.438877 0.602705 0.935349 1.126380 1.302724 1.887231 2.030156 2.370716 2.648705
+0.225939 0.261133 0.511885 0.708833 1.424678 1.892147 2.104001 2.250163 2.605088 2.746840
+0.452216 0.679332 1.031388 1.239650 1.444390 1.576987 1.800188 2.037662 2.347747 2.559010
+0.246537 0.319428 0.434869 0.567303 0.678662 1.145054 2.156111 2.318698 2.695808 2.850677
+0.323068 0.487001 0.653349 0.909650 1.315899 1.427550 1.843764 2.091482 2.277958 2.521041
+0.151653 0.209991 0.374931 0.854455 1.064290 1.434370 1.854148 1.976154 2.226004 2.750320
+0.254129 0.318082 0.553509 1.223731 1.483086 1.618808 1.995613 2.126498 2.542503 2.704703
+0.159794 0.237065 0.373617 0.681392 0.916230 1.100174 1.782317 1.960086 2.120694 2.618079
+0.395727 0.506034 0.756406 1.188386 1.370570 1.507131 1.860951 2.052892 2.386064 2.617425
+0.235512 0.301393 0.657521 0.969184 1.638320 1.830168 1.984994 2.183324 2.395359 2.538524
+0.451916 0.818196 1.310860 1.494170 1.734505 1.944228 2.085155 2.271405 2.604215 2.715654
+0.229547 0.331804 0.499374 0.698992 1.265974 1.467138 1.658356 2.268601 2.583952 2.762021
+0.258732 0.443700 0.582380 0.800795 1.354913 1.537609 1.724000 2.113993 2.369337 2.558869
+0.156813 0.299295 0.462045 0.796077 1.096063 1.269277 1.836371 1.991867 2.448318 2.597971
+0.246591 0.304473 0.529300 1.215091 1.451169 1.571384 1.868982 1.972518 2.391725 2.695616
+0.169559 0.209107 0.367228 0.505130 1.079358 1.293153 1.736205 2.042985 2.323978 2.564293
+0.329533 0.392210 0.720874 0.936253 1.067646 1.644185 1.991320 2.118407 2.596262 2.701052
+0.201406 0.291786 0.394755 0.617862 1.695417 1.914199 2.049472 2.237494 2.441266 2.568384
+0.115269 0.195387 0.738170 1.042436 1.524313 1.807507 2.173634 2.393265 2.651838 2.824917
+0.173769 0.282805 0.419446 0.776536 0.928220 1.160391 1.958931 2.101699 2.541381 2.732928
+0.209696 0.340593 0.516203 0.794250 1.153989 1.275003 1.570690 1.733317 2.086323 2.795392
+0.110476 0.145162 0.248644 0.465410 1.205115 1.426951 1.838992 2.085791 2.488927 2.779657
+0.223681 0.283712 0.440694 1.041879 1.657659 1.762280 2.000478 2.153137 2.435135 2.637721
+0.178995 0.282691 0.473035 0.740633 0.911089 1.104519 1.288366 1.821180 2.201221 2.508461
+0.443099 0.561309 0.804443 1.033650 1.140498 1.408557 1.973383 2.105087 2.432294 2.654409
+0.222370 0.320892 0.431815 0.774539 1.450421 1.638383 1.817605 2.055496 2.231523 2.414745
+0.488759 0.722119 1.075268 1.294956 1.551912 1.839530 2.130626 2.354921 2.626536 2.737698
+0.209201 0.325492 0.450619 1.020698 1.213389 1.358613 1.538589 1.759768 2.620164 2.791411
+0.254420 0.409271 0.532950 0.933560 1.248401 1.350851 1.728513 1.887503 2.311205 2.707429
+0.039082 0.123291 0.563195 0.857519 1.261207 1.529819 1.850039 2.144420 2.476829 2.755410
+0.127556 0.217058 0.807380 1.043662 1.378203 1.631976 1.940815 2.207962 2.528274 2.764303
+0.214258 0.299923 0.606169 0.768797 1.015893 1.349821 1.669065 1.924581 2.111348 2.418396
+0.364885 0.502482 0.675283 0.930660 1.036461 1.354434 1.834770 1.950661 2.559472 2.726950
+0.221471 0.330609 0.456653 0.686616 1.285861 1.685279 1.842952 2.117269 2.300993 2.591367
+0.347069 0.500335 0.788322 1.022915 1.371254 1.585460 1.855588 2.176902 2.477587 2.720481
+0.281028 0.414603 0.602236 0.792786 0.907330 1.090040 1.687453 2.129718 2.489785 2.634419
+0.363245 0.571116 0.705668 0.861203 1.204113 1.333048 1.544624 2.016192 2.258768 2.434454
+0.215734 0.321274 0.465393 0.666555 1.274668 1.427396 1.670511 2.228318 2.394993 2.624012
+0.270727 0.332361 0.883612 1.283495 1.433436 1.649610 1.838125 2.021889 2.560021 2.698378
+0.175763 0.213621 0.391730 0.566755 0.955973 1.388956 1.878982 2.137460 2.349368 2.478188
+0.257598 0.316184 0.657817 1.118064 1.272143 1.501175 1.689925 1.857456 2.616979 2.735442
+0.227270 0.307771 0.544263 1.030949 1.478367 1.606785 1.851814 2.266798 2.452714 2.629357
+0.255179 0.376313 1.164078 1.383762 1.652706 1.817476 2.014659 2.160928 2.460094 2.623430
+0.274618 0.450301 0.650957 0.842032 1.042329 1.233369 1.641038 1.987714 2.446952 2.597194
+0.337780 0.514835 0.668892 0.911283 1.476046 1.714011 1.887574 2.115985 2.373951 2.499093
+0.172594 0.270224 0.434372 0.864398 1.037663 1.485795 1.748590 2.020761 2.643028 2.800341
+0.270150 0.317310 0.733644 1.342780 1.517768 1.641210 1.845979 1.981779 2.361540 2.595899
+0.160609 0.230103 0.452778 0.853418 1.061340 1.458644 1.711466 1.875295 2.205269 2.709841
+0.302065 0.354507 0.587391 0.684546 0.931120 1.757948 1.902878 2.288464 2.550897 2.656497
+0.142376 0.211224 0.315730 0.534420 1.587988 1.751880 2.118162 2.354064 2.604623 2.786794
+0.386559 0.540492 0.884711 1.083540 1.507785 1.692150 1.931330 2.198611 2.531354 2.678491
+0.323902 0.389328 0.540529 0.671309 0.782921 1.525984 2.046871 2.140001 2.472270 2.566702
+0.227988 0.399979 0.639588 0.791383 1.185694 1.369429 1.655774 2.094051 2.385252 2.754008
+0.140257 0.228630 0.342001 0.596028 1.326401 1.465391 1.823254 1.961877 2.671876 2.831534
+0.121381 0.186129 0.623448 1.000592 1.306405 1.641012 2.056458 2.375989 2.709278 2.848728
+0.247607 0.350532 0.510244 0.883136 1.094021 1.210853 1.639562 2.030725 2.223639 2.416473
+0.357005 0.520431 0.875831 1.062576 1.221746 1.345463 1.623626 2.038524 2.477051 2.698891
+0.179634 0.278991 0.394920 0.736511 1.402026 1.576761 1.774624 1.972434 2.183128 2.757177
+0.203160 0.430851 1.114653 1.371969 1.757116 1.992375 2.261491 2.431952 2.637357 2.752659
+0.138600 0.200975 0.519401 0.724917 1.034246 1.394176 1.722948 1.946633 2.443593 2.716691
+0.298095 0.365805 0.582351 1.086692 1.326009 1.425975 1.844288 2.197476 2.361003 2.521646
+0.224031 0.332426 0.469990 1.001054 1.197837 1.340048 1.959629 2.074407 2.586538 2.799850
+0.217865 0.623928 0.846007 1.056459 1.270022 1.514463 1.916564 2.173644 2.481877 2.731790
+0.216744 0.285870 0.554706 0.993990 1.223763 1.481385 1.841075 2.001157 2.202645 2.554494
+0.183332 0.408012 0.595713 0.854496 1.037244 1.240493 1.858004 2.051789 2.454286 2.641640
+0.185879 0.262800 0.433401 0.963144 1.221951 1.453093 2.083738 2.338219 2.637954 2.802979
+0.376619 0.531366 0.924956 1.260648 1.459226 1.589579 1.913753 2.153929 2.384625 2.568935
+0.276908 0.401698 0.535406 0.725282 0.853962 0.993671 1.784685 2.264235 2.415421 2.743011
+0.392628 0.530015 0.694728 0.898255 1.037465 1.203267 1.847972 2.130377 2.294167 2.519263
+0.221585 0.348013 0.498036 0.715769 1.244234 1.381107 1.612806 2.098989 2.271383 2.656074
+0.181011 0.243672 0.520565 1.273809 1.635579 1.924649 2.152884 2.325189 2.545337 2.704856
+0.212747 0.338170 0.512165 0.698820 1.069232 1.195663 1.594938 1.997384 2.252972 2.771008
+0.239602 0.319299 0.856477 1.177220 1.318502 1.493392 1.741957 2.006496 2.283856 2.495161
+0.228476 0.280840 0.476230 1.203494 1.625636 1.719185 2.032736 2.169601 2.510422 2.699013
+0.286987 0.578563 1.175416 1.489497 1.807057 2.031448 2.224193 2.402210 2.620582 2.786223
+0.284803 0.530975 0.821128 0.972435 1.146598 1.402202 1.828804 2.094299 2.506084 2.720046
+0.245331 0.345077 0.478580 0.845525 1.322977 1.438811 1.722802 2.097265 2.261936 2.441149
+0.170708 0.247004 0.608618 0.775849 1.065513 1.283496 1.723268 1.892396 2.539816 2.717299
+0.208332 0.300056 0.505156 1.253926 1.377427 1.594647 1.754029 2.171773 2.487478 2.685632
+0.171329 0.225179 0.378514 0.577821 1.098665 1.311943 1.526522 1.967713 2.172531 2.346440
+0.239282 0.344225 0.528808 0.666274 1.042444 1.388419 1.857559 2.094835 2.473543 2.649229
+0.198580 0.259051 0.438298 0.705347 1.431453 1.897639 2.046829 2.207600 2.449656 2.599716
+0.337069 0.528000 0.951780 1.180918 1.376423 1.654985 1.971529 2.266927 2.704743 2.847367
+0.284813 0.367338 0.523627 0.691416 0.797885 1.120421 1.819243 2.265148 2.456517 2.588448
+0.269159 0.476818 0.659344 0.899456 1.209541 1.335886 1.627523 1.903299 2.132623 2.655472
+0.119224 0.156658 0.271903 0.418321 1.065297 1.360087 1.644993 1.982627 2.382784 2.755980
+0.282273 0.349303 0.537097 1.066089 1.307982 1.458937 2.037910 2.256912 2.434757 2.578973
+0.201474 0.291056 0.422152 0.616067 1.022184 1.152574 1.449965 2.197085 2.439911 2.635280
+0.324130 0.396121 0.713192 1.073384 1.173029 1.526515 2.037201 2.137280 2.569318 2.702445
+0.199269 0.284170 0.404247 0.697358 1.446027 1.807057 1.954743 2.169169 2.379241 2.545732
+0.348456 0.529109 0.879319 1.101024 1.475230 1.807439 2.081272 2.280127 2.549592 2.702863
+0.184393 0.309059 0.446883 0.786980 0.939533 1.169098 1.804458 1.930933 2.599357 2.810854
+0.372412 0.451942 0.679847 1.075185 1.453546 1.572935 1.797280 2.060904 2.239656 2.413231
+0.162340 0.215690 0.397026 0.885715 1.351665 1.692524 1.923001 2.162159 2.529446 2.710698
+0.174845 0.244687 0.722017 1.058880 1.584480 1.712948 1.914989 2.272779 2.514853 2.721138
+0.180603 0.263970 0.439556 0.797992 1.025300 1.271742 1.843790 2.013992 2.183901 2.609028
+0.275445 0.331708 0.686947 0.880832 1.019790 1.601662 1.815444 1.960055 2.524843 2.635159
+0.246743 0.338623 0.507004 0.744344 0.978588 1.719875 2.149981 2.270511 2.455050 2.609715
+0.511182 0.731278 1.001870 1.154541 1.304543 1.479350 1.855646 2.159073 2.465297 2.619985
+0.159919 0.196942 0.359631 0.506645 0.910908 1.079437 1.605706 2.020672 2.336267 2.675469
+0.400414 0.532831 0.732331 1.013768 1.194337 1.337622 1.760440 1.913653 2.137670 2.495860
+0.198432 0.265271 0.463330 0.715843 1.124005 1.473936 1.785103 1.947760 2.284523 2.402467
+0.251071 0.299335 0.761114 1.358836 1.477322 1.755740 1.974355 2.155204 2.509334 2.610900
+0.168430 0.240238 0.385248 0.642207 0.818665 1.079971 1.497030 1.739210 2.014670 2.480512
+0.403618 0.476427 0.760625 1.119521 1.225260 1.585741 1.910637 2.082695 2.602596 2.728042
+0.270110 0.353552 0.507117 0.982357 1.452637 1.561604 1.831119 2.097015 2.260480 2.506040
+0.409239 0.594796 0.975401 1.298743 1.696566 1.869597 2.021276 2.210722 2.513551 2.654084
+0.264683 0.461411 0.644817 0.860983 1.044619 1.166400 1.802711 2.091425 2.295669 2.754119
+0.469686 0.613125 0.780126 0.980941 1.398148 1.536063 1.747415 2.051727 2.394884 2.516178
+0.186791 0.269819 0.399921 1.138197 1.381467 1.573894 1.960790 2.110781 2.483798 2.628204
+0.258801 0.327749 0.504295 1.197030 1.358461 1.528535 1.792614 1.927747 2.524317 2.681583
+0.161459 0.233374 0.511026 0.740697 0.973203 1.529858 1.845698 2.024509 2.388404 2.769333
+0.338109 0.399145 0.642671 0.750976 0.940491 1.777467 2.157523 2.269354 2.634732 2.724164
+0.180623 0.259965 0.390546 0.612711 1.433871 1.678265 1.843034 2.228297 2.443281 2.647327
+0.247299 0.293271 0.692143 0.919932 1.644451 1.918105 2.097755 2.258082 2.510431 2.625830
+0.149020 0.205904 0.356032 0.602403 0.987977 1.147484 1.771885 1.955289 2.387841 2.798390
+0.232598 0.414291 0.675328 0.818194 1.101627 1.308523 1.519246 1.952980 2.347393 2.695458
+0.176302 0.240703 0.418040 0.744771 1.241784 1.631902 1.803676 1.965041 2.614696 2.812026
+0.147792 0.225066 0.327162 0.749127 1.639390 1.742663 2.031072 2.226257 2.554880 2.737390
+0.153870 0.209078 0.349325 0.617112 0.939783 1.262086 1.603026 1.759135 1.968177 2.111699
+0.401254 0.531884 0.716519 1.042091 1.338740 1.442853 1.814274 2.094864 2.275463 2.451094
+0.257481 0.354612 0.474799 0.889648 1.418879 1.545760 1.780610 2.002306 2.180143 2.532227
+0.145143 0.398917 0.981552 1.314723 1.480195 1.798420 2.069724 2.386944 2.668464 2.802905
+0.178493 0.240401 0.691115 0.837764 1.073179 1.297529 1.642950 2.040266 2.463959 2.622440
+0.283570 0.372001 0.585235 0.956144 1.106750 1.584081 1.860096 2.009870 2.399586 2.562348
+0.173740 0.229082 0.361309 0.554292 1.445623 1.608360 2.083231 2.257294 2.420588 2.616658
+0.324415 0.415954 0.746050 1.011384 1.143615 1.556506 1.921430 2.048417 2.544327 2.700584
+0.214462 0.286094 0.581008 0.805945 1.275261 1.610434 1.794665 1.905601 2.100985 2.530385
+0.406606 0.540199 0.741703 0.841294 1.020646 1.288940 1.697760 1.988139 2.374821 2.589349
+0.202273 0.235653 0.484403 0.754406 1.274678 1.821075 2.241890 2.368887 2.620778 2.800892
+0.270698 0.780374 1.036092 1.204303 1.426576 1.652095 1.944935 2.222209 2.496745 2.678321
+0.229051 0.330732 0.459692 0.687040 0.867860 0.971515 1.553263 2.327103 2.599324 2.733993
+0.260962 0.343168 0.545250 1.036179 1.306217 1.422412 1.660351 2.041101 2.335761 2.495897
+0.171216 0.239743 0.394965 0.588008 1.144698 1.289132 1.673831 1.940258 2.235772 2.782337
+0.195902 0.254449 0.377534 1.406314 1.521423 1.673084 1.866963 2.261663 2.535496 2.688582
+0.150694 0.213444 0.372155 0.787173 1.035226 1.454281 1.699328 1.829446 2.003441 2.525940
+0.232566 0.460472 0.787265 0.996419 1.396693 1.523961 1.855686 2.119370 2.346354 2.515401
+0.233393 0.307066 0.580252 0.812411 1.638408 1.916323 2.050381 2.201478 2.398327 2.532500
+0.654665 1.113987 1.347221 1.518794 1.813315 1.953845 2.210362 2.381661 2.551979 2.660202
+0.223873 0.325731 0.467395 0.921251 1.270288 1.397723 1.734370 2.414313 2.638346 2.800382
+0.310637 0.477608 0.685272 0.996817 1.355825 1.484000 1.704038 2.061930 2.448624 2.565929
+0.148930 0.226761 0.370757 1.019241 1.219213 1.396110 1.661688 1.901830 2.408793 2.697915
+0.229342 0.295527 0.586649 1.059472 1.597702 1.716890 1.937422 2.109084 2.436811 2.674887
+0.192819 0.263035 0.434697 0.673121 1.119753 1.338824 1.909548 2.076183 2.261830 2.387228
+0.320147 0.380189 0.741994 0.844995 1.074712 1.639187 1.762953 2.266267 2.646178 2.721096
+0.174567 0.253745 0.360203 0.504953 1.488396 1.814662 1.955756 2.149395 2.323488 2.584030
+0.263126 0.470251 0.798026 1.161280 1.606556 1.808008 2.130398 2.302959 2.489210 2.752479
+0.231279 0.366009 0.530320 0.804291 0.943863 1.141251 1.962507 2.101760 2.449591 2.815548
+0.172028 0.250238 0.449914 0.861171 1.080449 1.240891 1.585537 1.918091 2.217571 2.722636
+0.131319 0.183681 0.316018 0.523172 0.890644 1.486126 1.758535 1.891187 2.487652 2.765559
+0.165174 0.243169 0.350507 1.016712 1.534247 1.638560 1.932592 2.084107 2.538300 2.689502
+0.262744 0.474699 0.655053 0.795707 1.068818 1.252172 1.418647 1.961010 2.309455 2.536506
+0.359054 0.435831 0.725138 1.118933 1.229842 1.514926 1.879370 2.001037 2.462089 2.652002
+0.218540 0.299734 0.601107 0.823625 1.269799 1.620287 1.839893 1.976756 2.375450 2.640668
+0.487484 0.730967 1.052266 1.258969 1.526405 1.802696 2.229099 2.451538 2.684818 2.774190
+0.235780 0.364477 0.520691 0.749469 0.950595 1.159410 1.423255 1.544612 2.361393 2.766014
+0.366160 0.476136 0.652510 1.062481 1.309788 1.418863 1.784871 1.987495 2.189248 2.558080
+0.184696 0.253223 0.471758 0.830299 1.272428 1.483910 1.761955 2.136740 2.416390 2.620731
+0.128256 0.217552 0.752532 1.013345 1.185988 1.415101 1.811830 2.211505 2.607414 2.789321
+0.247330 0.328294 0.701060 0.927525 1.109801 1.291869 1.638584 1.875516 2.227907 2.417348
+0.261841 0.503729 0.732366 0.870192 1.033798 1.299712 1.693809 2.023705 2.463903 2.789299
+0.165555 0.219912 0.358917 0.505900 1.230885 1.663232 1.852393 2.028502 2.286248 2.725340
+0.426544 0.643468 0.917679 1.196829 1.471597 1.648363 1.933059 2.151933 2.533829 2.705743
+0.308359 0.416322 0.591830 0.808745 0.946905 1.230266 1.815498 2.281895 2.520403 2.631259
+0.269965 0.447323 0.574488 0.763324 1.256417 1.405168 1.571648 1.980676 2.220782 2.442545
+0.188326 0.280970 0.408039 0.646742 1.320810 1.446061 1.615924 2.148422 2.351742 2.514250
+0.241655 0.365356 0.810170 1.309700 1.669576 1.812447 2.014631 2.236122 2.442170 2.609315
+0.191747 0.289189 0.450664 0.748517 0.915409 1.168139 1.584199 1.750548 2.260120 2.447778
+0.215480 0.278055 0.768309 1.041609 1.391676 1.605855 1.766698 1.876725 2.528928 2.706006
+0.216771 0.298936 0.710997 0.862001 1.342336 1.590245 1.886295 2.097920 2.415093 2.592546
+0.359220 0.566823 0.939326 1.372126 1.545352 1.699671 2.041310 2.205011 2.518317 2.710314
+0.305907 0.442295 0.613007 0.776603 0.914320 1.099675 1.615712 1.826869 2.359635 2.622631
+0.323177 0.497481 0.632094 0.852217 1.431198 1.600546 1.791940 2.143530 2.380021 2.560286
+0.276909 0.420019 0.563912 1.000971 1.135252 1.388079 1.711802 1.918572 2.573328 2.752989
+0.353490 0.388981 0.807777 1.276863 1.382826 1.606736 1.810843 1.979129 2.631848 2.733152
+0.211471 0.306166 0.424434 0.581123 0.710913 1.547934 2.010370 2.138366 2.380508 2.503481
+0.225924 0.333197 0.488381 0.801446 1.090937 1.638206 1.799647 2.390310 2.652313 2.790138
+0.171504 0.249271 0.358286 0.870885 1.550123 1.667881 2.054589 2.231743 2.439091 2.602023
+0.165599 0.227318 0.460922 1.107714 1.477735 1.814994 2.062885 2.255887 2.546566 2.715347
+0.204992 0.345256 0.473494 0.712728 0.805809 1.312492 1.893635 2.009686 2.341092 2.479636
+0.241898 0.390228 0.537134 0.715035 1.312338 1.499876 1.662491 2.135780 2.352112 2.532228
+0.163569 0.301194 0.427433 0.764441 1.375596 1.484079 1.850824 1.989487 2.494381 2.667698
+0.185986 0.271128 0.421812 1.063503 1.222027 1.628289 1.811308 2.167184 2.682964 2.795197
+0.202601 0.379588 0.533353 0.730653 1.060008 1.189413 1.598490 1.835597 2.061862 2.426341
+0.381195 0.485776 0.727063 1.085074 1.215649 1.412868 1.615482 1.828196 2.539184 2.686523
+0.196130 0.286997 0.409907 0.696364 1.424577 1.699356 1.891753 2.153448 2.327269 2.685103
+0.217874 0.396132 0.938681 1.246697 1.661963 1.931349 2.246916 2.421796 2.619892 2.750931
+0.145642 0.216508 0.413198 0.862759 1.057682 1.322682 1.673351 1.828806 2.347789 2.651186
+0.252166 0.353210 0.523268 0.998504 1.176163 1.345135 1.984750 2.128958 2.373533 2.721309
+0.207926 0.318108 0.470343 0.848345 0.989299 1.405273 1.967910 2.101386 2.512180 2.676499
+0.305162 0.559986 0.771585 0.960172 1.334408 1.717417 1.924182 2.084417 2.601968 2.796124
+0.215239 0.293295 0.505385 0.962671 1.240775 1.392460 1.797329 1.965379 2.131247 2.276248
+0.252164 0.460717 0.585238 0.895100 1.077276 1.245603 1.770113 1.919629 2.388482 2.774345
+0.171691 0.214222 0.361048 0.500619 0.905993 1.365660 2.191797 2.291635 2.536887 2.788810
+0.210536 0.585917 1.067844 1.305357 1.534407 1.728603 1.950964 2.160461 2.474553 2.655915
+0.169262 0.231674 0.372121 0.532093 0.775314 1.210871 1.829565 2.081870 2.370289 2.704223
+0.343950 0.448128 0.628833 0.913957 1.088899 1.224316 1.766842 2.099926 2.246679 2.400841
+0.241643 0.386851 0.578033 0.893447 1.284732 1.404909 1.839518 2.125416 2.327160 2.739690
+0.241059 0.287428 0.601200 1.273580 1.460278 1.653802 2.095665 2.226476 2.507632 2.651598
+0.212479 0.430242 0.578263 0.750884 0.984798 1.103297 1.564720 1.845357 2.044045 2.707564
+0.267240 0.357278 0.901382 1.173429 1.387845 1.739763 1.960853 2.173315 2.408387 2.570937
+0.216978 0.306711 0.423920 0.791397 1.547660 1.881522 2.025421 2.184747 2.389726 2.510855
+0.309853 0.505477 1.137673 1.452808 1.660808 1.914525 2.084337 2.308435 2.638463 2.772736
+0.301921 0.420539 0.593933 0.887576 1.158301 1.268991 1.788041 2.156468 2.316421 2.507218
+0.293230 0.474574 0.623415 0.798513 1.266075 1.425523 1.764734 1.994016 2.181652 2.456787
+0.267189 0.365075 0.696711 0.927891 1.096450 1.472164 1.765266 1.937224 2.223753 2.655092
+0.238720 0.370663 0.617866 1.246955 1.365777 1.650640 1.856445 2.306366 2.616822 2.765237
+0.175180 0.233649 0.388873 0.625509 1.137464 1.364059 1.780788 1.978889 2.142278 2.269743
+0.363510 0.421032 0.668364 0.762955 0.998948 1.715897 1.877803 2.064237 2.529901 2.608567
+0.207131 0.288224 0.537847 0.889921 1.241448 1.796637 1.982317 2.231362 2.514249 2.666169
+0.311071 0.486542 0.911402 1.324355 1.500183 1.670614 2.142536 2.330931 2.596184 2.778564
+0.286136 0.386970 0.584375 0.911705 1.134588 1.317656 1.852739 2.283740 2.498365 2.622864
+0.253233 0.419082 0.572357 0.778424 1.126703 1.277532 1.807391 2.017696 2.220121 2.576306
+0.119841 0.163781 0.296364 0.661342 1.063342 1.241590 1.856804 2.104475 2.497328 2.762449
+0.134955 0.201314 0.403983 0.934711 1.360477 1.718449 2.065183 2.278684 2.574632 2.753186
+0.187681 0.272074 0.453358 0.682207 1.079560 1.206376 1.499740 2.043148 2.242754 2.665815
+0.313258 0.412019 0.658075 0.828689 0.973583 1.514446 1.981071 2.102741 2.535037 2.681357
+0.255030 0.322348 0.627488 0.839253 1.410591 1.810002 2.038784 2.181294 2.416832 2.562402
+0.419919 0.625767 0.997973 1.218385 1.544616 1.788193 2.193417 2.384323 2.580200 2.698287
+0.144698 0.204991 0.382026 0.623303 0.874762 1.289145 1.707320 1.863261 2.458684 2.750055
+0.348116 0.419496 0.704420 1.093503 1.227121 1.494841 1.778803 1.913492 2.247296 2.428664
+0.150045 0.246799 0.376978 0.783403 1.269598 1.422794 1.903455 2.035588 2.514973 2.759883
+0.105122 0.206614 0.753484 1.038977 1.400140 1.658373 2.030750 2.283051 2.654021 2.837336
+0.192365 0.288692 0.447554 0.818792 0.961011 1.398186 1.770980 1.943311 2.350650 2.500051
+0.262128 0.381361 0.574890 0.709707 1.071672 1.453038 1.732793 1.979241 2.422853 2.645439
+0.182137 0.236372 0.375437 0.738739 1.319942 1.813603 1.942481 2.136125 2.304536 2.660541
+0.388048 0.531674 0.948328 1.154568 1.307573 1.434685 1.768235 2.048136 2.364776 2.585037
+0.213588 0.288434 0.462998 0.598306 0.773371 0.915658 1.452520 2.086025 2.523003 2.722037
+0.255467 0.334344 0.621250 0.810402 0.995432 1.466371 1.709488 1.890365 2.052513 2.247982
+0.202649 0.282992 0.450372 0.652595 1.271305 1.607863 1.769708 1.985229 2.230577 2.380831
+0.255806 0.325628 0.668776 1.230304 1.373533 1.702388 1.962730 2.144556 2.518005 2.640112
+0.164126 0.217024 0.367572 0.604779 0.787116 1.194139 1.683264 1.826517 2.301871 2.524861
+0.374711 0.458954 0.726536 0.920865 1.045916 1.511231 1.712666 1.895532 2.601724 2.708894
+0.321014 0.460345 0.639594 1.017667 1.508099 1.631146 1.864246 2.140150 2.327445 2.508909
+0.451810 0.719234 1.150765 1.385625 1.620547 1.892342 2.068707 2.263104 2.625298 2.740266
+0.317844 0.411108 0.550802 0.761160 0.870205 1.038480 1.695720 2.112903 2.292249 2.451544
+0.321858 0.548379 0.720393 0.955644 1.233322 1.359795 1.685327 1.923628 2.307181 2.544584
+0.211797 0.292996 0.437036 1.171159 1.397378 1.525798 1.701395 1.861517 2.572521 2.757919
+0.334603 0.405956 0.767677 1.215768 1.335601 1.658739 1.989520 2.108465 2.602700 2.719250
+0.236812 0.348424 0.519218 0.665697 1.102403 1.611533 1.819999 2.115185 2.332044 2.604171
+0.212181 0.308266 0.480795 0.705382 0.828843 1.420354 1.886330 2.032387 2.621328 2.767098
+0.156168 0.242178 0.348609 0.550072 1.486404 1.641030 1.904334 2.091753 2.439156 2.809664
+0.232081 0.327237 0.817249 1.194162 1.571594 1.731682 1.910994 2.090434 2.488066 2.694976
+0.166025 0.252998 0.441946 0.686509 0.905928 1.524321 1.747034 1.950457 2.619697 2.805258
+0.196816 0.324035 0.613887 0.796124 1.033469 1.198765 1.570531 2.015231 2.414398 2.745220
+0.152873 0.238362 0.348769 0.790622 1.413327 1.522987 1.899666 2.041945 2.648276 2.825752
+0.238929 0.311579 0.412073 0.915401 1.512444 1.940985 2.178055 2.302141 2.517257 2.635463
+0.160234 0.194261 0.347515 0.460654 0.859252 1.041440 1.658005 1.765106 2.252543 2.312052
+0.391446 0.575762 0.767956 0.913604 1.304424 1.440779 1.667960 1.962669 2.446664 2.573637
+0.213295 0.338515 0.465366 0.911020 1.312069 1.413848 1.864947 2.045811 2.354224 2.763667
+0.170870 0.556857 1.036355 1.381019 1.682662 1.999979 2.319783 2.526350 2.739001 2.850764
+0.208142 0.323528 0.474225 0.911543 1.048694 1.258201 1.966595 2.078676 2.553969 2.814829
+0.162972 0.229629 0.731192 0.902973 1.246076 1.372954 1.693139 2.110582 2.362875 2.555643
+0.197223 0.291057 0.436718 0.707631 1.251503 1.421382 1.926786 2.108784 2.413585 2.596412
+0.188400 0.289822 0.797989 1.142133 1.323120 1.715797 2.074975 2.335066 2.566622 2.712846
+0.176052 0.240463 0.486022 0.736587 0.983507 1.654478 1.892603 2.036521 2.205899 2.540522
+0.285807 0.420951 0.578219 0.937462 1.172738 1.315248 1.698845 1.846953 2.333613 2.500319
+0.191178 0.264476 0.384535 0.632084 1.446016 1.916538 2.114759 2.257365 2.532359 2.669854
+0.585958 0.712547 0.995175 1.345358 1.519221 1.715374 1.913837 2.069254 2.514199 2.672046
+0.232352 0.335589 0.447674 0.661655 0.840293 1.102372 2.111319 2.297768 2.505132 2.794479
+0.293351 0.391184 0.614053 0.997235 1.204180 1.322845 1.746085 2.070938 2.259359 2.492199
+0.128784 0.193380 0.374338 0.847941 1.107813 1.396176 1.796836 1.928700 2.389952 2.702928
+0.187671 0.251167 0.419138 1.154089 1.596401 1.689187 1.941996 2.092773 2.621931 2.795923
+0.148570 0.200662 0.344258 0.538968 0.866249 1.341751 1.759051 1.890255 2.225276 2.769903
+0.345597 0.416970 0.657718 1.108569 1.439934 1.549124 1.811931 2.165143 2.359862 2.480281
+0.260394 0.347444 0.453068 0.867942 1.515797 1.830215 1.974617 2.135238 2.518564 2.622302
+0.467387 0.718460 1.257405 1.516226 1.785886 1.982028 2.277442 2.407989 2.575877 2.697560
+0.254025 0.396915 0.711272 0.826708 1.079490 1.303882 1.532614 2.101023 2.580896 2.726410
+0.251349 0.458227 0.691728 0.853294 1.181701 1.324576 1.553722 2.121741 2.324860 2.537399
+0.193070 0.295330 0.434005 1.028433 1.180760 1.492311 1.774884 1.958905 2.378250 2.514336
+0.328295 0.438707 0.672483 1.098796 1.409689 1.525062 1.957988 2.202692 2.417235 2.626557
+0.171589 0.215360 0.396416 0.549523 1.010817 1.564392 1.776805 2.010598 2.334140 2.489964
+0.318782 0.372964 0.715257 0.808908 1.049817 1.858174 2.008814 2.244447 2.552397 2.638023
+0.201432 0.265508 0.443842 0.655062 1.463954 1.780676 1.989105 2.317647 2.504044 2.729015
+0.089299 0.221502 0.866390 1.161581 1.386624 1.681219 2.037751 2.306655 2.683398 2.842046
+0.212127 0.340083 0.489712 0.702958 0.879220 1.069546 1.931755 2.304789 2.539222 2.833730
+0.328502 0.460793 0.574149 0.923510 1.262431 1.349319 1.540115 1.646239 1.968666 2.558808
+0.151688 0.205453 0.364147 0.726598 1.290329 1.608244 1.900602 2.132843 2.473238 2.714681
+0.185087 0.268618 0.380471 0.858380 1.535920 1.659732 1.871001 2.060741 2.281531 2.743722
+0.257576 0.375609 0.522074 0.806014 0.988781 1.118512 1.619900 2.008108 2.189450 2.503981
+0.400530 0.492365 0.729967 0.986855 1.095728 1.599909 1.935703 2.057853 2.435587 2.582604
+0.223967 0.308358 0.436977 0.810278 1.375371 1.715667 1.876660 2.086799 2.333392 2.482046
+0.356889 0.697785 1.003210 1.181500 1.520050 1.769174 2.060990 2.297507 2.609041 2.761196
+0.157986 0.286402 0.432170 0.759718 1.081482 1.206946 1.688203 1.857653 2.667619 2.834603
+0.196232 0.271155 0.616200 0.987195 1.265761 1.503484 1.745037 1.946600 2.389443 2.562468
+0.150612 0.207932 0.531767 0.924718 1.224167 1.532206 1.868861 2.129974 2.479660 2.745102
+0.159516 0.244552 0.677711 0.957418 1.266300 1.638493 1.929433 2.212544 2.525881 2.712593
+0.311860 0.375573 0.609251 0.741478 0.874235 1.502532 1.759234 1.910133 2.346160 2.464214
+0.272687 0.495052 0.602981 0.936595 1.218033 1.659652 1.783798 2.226628 2.673580 2.789721
+0.182994 0.269489 0.387738 0.559582 1.343891 1.727891 1.917480 2.131703 2.353147 2.525604
+0.308577 0.475904 0.797573 1.025973 1.477364 1.632200 1.868066 2.187647 2.448313 2.609309
+0.206491 0.281366 0.496579 0.711998 0.842942 1.042724 1.626715 2.075674 2.411838 2.577868
+0.326421 0.517351 0.715080 0.911851 1.128611 1.259596 1.539759 1.960615 2.508231 2.630330
+0.225691 0.354477 0.473958 0.715802 1.385094 1.590187 1.774163 2.045280 2.231611 2.620722
+0.243650 0.282149 0.801163 1.454069 1.614695 1.739741 1.936677 2.098900 2.621205 2.730598
+0.175768 0.236613 0.389409 0.747034 0.946387 1.205905 1.739280 1.989798 2.245012 2.388323
+0.387506 0.464495 0.740570 1.128342 1.279681 1.451771 1.809069 1.941649 2.324383 2.652406
+0.231774 0.321631 0.420712 0.846725 1.477615 1.662880 1.835880 2.220722 2.418706 2.624548
+0.339377 0.589871 1.313110 1.506577 1.748224 1.947324 2.102041 2.254806 2.543830 2.680043
+0.341587 0.433858 0.661863 0.821397 0.950863 1.418003 1.784815 1.903400 2.385908 2.575412
+0.345179 0.447774 0.612195 0.945135 1.419677 1.592743 1.773414 2.040871 2.324811 2.437686
+0.181279 0.307819 0.435997 0.934515 1.100027 1.302288 1.693949 1.895047 2.700574 2.825382
+0.310037 0.368350 0.622802 1.178640 1.411438 1.526484 1.919150 2.065079 2.254912 2.589937
+0.150978 0.212352 0.348668 0.573651 1.039486 1.590007 1.846476 1.963984 2.148357 2.662487
+0.277951 0.349703 0.550843 0.708320 0.838864 1.573740 1.810453 1.992371 2.532412 2.642545
+0.153422 0.252689 0.342559 0.686894 1.497196 1.638310 1.961921 2.130271 2.557903 2.742772
+0.279249 0.447383 0.763867 1.059905 1.545382 1.724231 2.031986 2.292812 2.552588 2.796233
+0.230577 0.389164 0.539408 0.761297 0.908015 1.337558 1.872590 2.004078 2.333966 2.727901
+0.232875 0.346443 0.540354 0.678135 1.101040 1.382052 1.587740 2.186049 2.411254 2.607361
+0.178843 0.269153 0.416180 0.638286 1.259337 1.389112 1.680672 1.869557 2.418798 2.781921
+0.238712 0.372837 0.675624 1.027319 1.339343 1.669807 2.074360 2.351022 2.663150 2.815245
+0.215603 0.308405 0.496032 0.940314 1.090508 1.308705 1.583747 1.902325 2.209688 2.576931
+0.291384 0.348946 0.780234 1.202297 1.290327 1.444813 1.575215 1.952612 2.399593 2.483613
+0.198791 0.307267 0.456507 0.669854 1.275490 1.409566 1.731928 2.093564 2.326604 2.772666
+0.166723 0.274518 1.057461 1.415490 1.716962 1.941408 2.139410 2.271877 2.554685 2.755174
+0.179844 0.282631 0.449297 0.722971 0.854062 1.439226 1.833271 2.030343 2.411399 2.580818
+0.194891 0.247057 0.501829 1.004986 1.304934 1.451918 1.799457 2.025853 2.311832 2.422165
+0.192373 0.297404 0.420858 0.940309 1.303418 1.426055 1.949700 2.077238 2.623849 2.795647
+0.284285 0.555560 0.869980 1.055893 1.232747 1.442851 1.823935 2.260258 2.608541 2.799256
+0.182395 0.248334 0.473858 1.064734 1.236328 1.480815 1.718550 1.883271 2.073356 2.512622
+0.293574 0.445666 0.581331 0.774876 0.860972 1.080798 1.894962 2.036530 2.546161 2.753034
+0.164780 0.231139 0.397045 0.799136 1.184762 1.560887 2.082481 2.246203 2.538883 2.722312
+0.427982 0.603539 0.920429 1.129159 1.650391 1.805433 1.997586 2.263608 2.512703 2.626448
+0.168043 0.256064 0.384473 0.655220 0.888834 1.046199 1.879431 2.027056 2.416638 2.713319
+0.426266 0.599810 0.770098 0.938960 1.085997 1.239035 1.780899 2.098691 2.240555 2.451170
+0.206361 0.331236 0.460417 0.809533 1.319919 1.432077 1.699325 1.907851 2.185584 2.791362
+0.172066 0.257009 0.693635 1.290430 1.502260 1.882174 2.058034 2.285835 2.654385 2.780637
+0.170469 0.242710 0.420771 0.673196 1.013631 1.168518 1.734302 2.076408 2.284278 2.777254
+0.231524 0.384268 0.762288 1.075716 1.340044 1.570221 1.844109 2.087904 2.435480 2.609095
+0.234196 0.299491 0.501062 1.074183 1.591896 1.874452 2.075105 2.288231 2.499325 2.625494
+0.469375 0.772069 1.143891 1.321644 1.809933 2.060553 2.352686 2.509836 2.660967 2.746296
+0.267541 0.509192 0.697162 0.881682 1.154246 1.287919 1.732950 2.170277 2.373112 2.701116
+0.225002 0.296925 0.521071 0.868722 1.247262 1.605607 1.862301 1.995077 2.132673 2.303312
+0.182154 0.268818 0.650902 0.829595 1.340290 1.518522 1.678145 2.062000 2.476058 2.618836
+0.262094 0.315377 0.554545 1.249325 1.471511 1.602479 1.859154 1.986339 2.555494 2.716803
+0.159937 0.221544 0.379613 0.703404 1.009260 1.336589 1.634712 1.832112 2.318601 2.492376
+0.317307 0.445696 0.644479 0.865391 1.006145 1.475121 1.860039 1.994490 2.375194 2.696675
+0.243257 0.313667 0.455515 0.804455 1.138675 1.990813 2.199166 2.317604 2.528196 2.655319
+0.149876 0.523035 0.850884 1.130052 1.422386 1.709616 2.052423 2.309997 2.639482 2.816247
+0.295517 0.381331 0.579620 0.758901 0.871645 1.328267 1.986843 2.119635 2.549100 2.680632
+0.291632 0.485587 0.631619 0.928421 1.214008 1.324041 1.814157 2.030748 2.252379 2.749354
+0.139746 0.195222 0.343435 0.703664 1.118059 1.352517 1.752608 1.877596 2.297202 2.717509
+0.243712 0.353375 0.585060 0.914994 1.377929 1.519246 1.980348 2.132954 2.489440 2.702636
+0.176444 0.255300 0.420605 0.747448 1.153758 1.299601 1.683980 2.102983 2.463231 2.667324
+0.252495 0.390591 0.697066 0.966926 1.231424 1.414479 1.867378 2.243706 2.495192 2.656606
+0.272420 0.381655 0.551517 0.888825 1.590308 1.808189 1.943240 2.138959 2.358917 2.487502
+0.336178 0.471630 0.935669 1.201733 1.678329 1.870851 2.098930 2.268758 2.467556 2.613989
+0.201767 0.332879 0.530137 0.745363 1.051345 1.174747 1.706266 2.049544 2.461842 2.799073
+0.224306 0.303901 0.510428 1.086097 1.267920 1.446573 1.785392 1.911767 2.289610 2.700286
+0.131135 0.171778 0.323877 0.821611 1.226519 1.537322 1.889645 2.169879 2.520932 2.772178
+0.212962 0.347455 0.744136 0.964332 1.426998 1.636084 1.937573 2.189447 2.476377 2.657238
+0.221564 0.298344 0.590780 0.774362 1.002528 1.237108 1.762739 1.946722 2.225939 2.371709
+0.300082 0.409111 0.600009 0.784231 0.905421 1.449797 1.878545 2.002657 2.618940 2.779774
+0.177168 0.244397 0.382973 0.547832 0.958732 1.796741 2.037031 2.198241 2.416774 2.606982
+0.445089 0.691608 0.911651 1.027834 1.215634 1.498612 2.011028 2.296914 2.571657 2.730890
+0.218890 0.332216 0.485543 0.669862 0.827655 0.946060 1.655213 2.081780 2.297490 2.781759
+0.264561 0.330768 0.698979 0.882675 1.036048 1.373216 1.608206 1.801189 2.021468 2.470223
+0.198417 0.232211 0.502648 0.724700 1.196144 1.304503 1.692944 1.862228 2.327527 2.429571
+0.240112 0.278797 0.513980 1.374924 1.647698 1.742378 1.988501 2.137277 2.329969 2.585200
+0.216630 0.297516 0.454364 0.700613 0.893785 1.036923 1.565511 2.032201 2.301512 2.463679
+0.308267 0.357421 0.811138 1.127420 1.244275 1.651427 1.813657 2.045151 2.637104 2.726842
+0.242030 0.328382 0.452907 0.861731 1.555327 1.743950 1.896242 2.084827 2.255121 2.454955
+0.405487 0.653274 1.000615 1.215980 1.553100 1.809940 2.090490 2.237915 2.442893 2.589896
+0.258975 0.421106 0.596341 0.793521 1.016877 1.148382 1.710733 2.132131 2.329411 2.755008
+0.383770 0.618549 0.792683 0.970281 1.353980 1.492209 1.740595 2.034232 2.262266 2.418759
+0.182576 0.276855 0.395058 1.006542 1.378696 1.494813 1.790120 1.929259 2.427587 2.564728
+0.262944 0.336362 0.560480 1.134456 1.298593 1.499501 1.953395 2.050099 2.524027 2.712280
+0.128134 0.176378 0.373760 0.758708 1.132934 1.485273 1.930693 2.068716 2.343529 2.773154
+0.209614 0.299558 0.469136 0.796651 0.955701 1.572224 2.012335 2.290736 2.580444 2.723601
+0.205230 0.307160 0.423168 0.638468 1.376104 1.735940 1.925713 2.112538 2.470319 2.600522
+0.249605 0.312259 0.801138 1.134882 1.687789 1.883222 2.049696 2.223042 2.454133 2.577341
+0.150236 0.180308 0.350515 0.500915 0.804675 1.506103 1.712024 2.023875 2.343152 2.636887
+0.294328 0.430367 0.587290 0.910719 1.184482 1.304216 1.581107 2.004270 2.395137 2.534772
+0.185620 0.281137 0.544021 0.818067 1.320581 1.540046 1.863117 2.127465 2.523995 2.737758
+0.154431 0.208321 0.340239 1.022588 1.552229 1.696583 2.198386 2.394862 2.607880 2.801047
+0.172397 0.232300 0.478592 0.699642 0.957173 1.484486 1.847798 1.985936 2.145557 2.327115
+0.511765 0.721492 0.860517 1.030820 1.340681 1.459390 1.823745 2.108810 2.406735 2.558400
+0.281714 0.392430 0.578702 0.891995 1.494831 1.661309 1.877927 2.097376 2.291857 2.619590
+0.326495 0.586450 0.954506 1.197200 1.519600 1.893887 2.319365 2.533775 2.736139 2.847582
+0.106638 0.178766 0.680283 0.829053 0.990716 1.241479 1.789242 2.154750 2.597141 2.799901
+0.294220 0.377984 0.793384 0.971352 1.172200 1.572398 1.804897 2.028760 2.264042 2.492483
+0.171726 0.263446 0.395475 0.621988 1.267402 1.408927 1.898373 2.102150 2.426709 2.776510
+0.303342 0.364222 0.792880 1.046061 1.184958 1.568551 1.760719 2.139470 2.565548 2.655674
+0.192848 0.257653 0.414826 0.791829 1.260674 1.636533 1.874636 2.009896 2.202175 2.572052
+0.341824 0.417968 0.655810 1.026514 1.158607 1.346654 1.798696 1.911077 2.526891 2.702043
+0.176931 0.234845 0.363167 0.522327 1.394457 1.894472 2.109195 2.282625 2.684080 2.823357
+0.433185 0.607432 0.929790 1.250808 1.472755 1.627281 2.014445 2.256366 2.466320 2.630010
+0.211267 0.313559 0.402576 0.554601 0.723386 0.871912 1.614736 2.390825 2.565792 2.757341
+0.307409 0.394557 0.612848 0.987028 1.191241 1.356915 1.954914 2.160787 2.345073 2.569786
+0.184320 0.254786 0.425592 0.782972 1.223405 1.413726 1.796288 1.997325 2.163509 2.505424
+0.183175 0.235186 0.358817 1.447766 1.601221 1.798948 2.134861 2.384961 2.598175 2.763819
+0.168505 0.236625 0.392319 0.651410 0.887019 1.463266 1.720871 1.858740 2.054516 2.697266
+0.250944 0.424982 0.901118 1.085636 1.247720 1.422572 1.835136 2.141276 2.468994 2.643082
+0.238593 0.326384 0.595703 0.813678 1.506809 1.745897 1.890343 2.252317 2.461518 2.634033
+0.519767 0.866690 1.252206 1.413883 1.854974 2.027801 2.281339 2.431268 2.597701 2.697588
+0.246522 0.333214 0.509160 1.154104 1.290713 1.443135 1.588080 2.324589 2.609196 2.797383
+0.275391 0.402140 0.584019 0.959905 1.333760 1.460912 1.827046 2.003725 2.436316 2.639286
+0.150522 0.212041 0.531410 1.050416 1.371279 1.580851 1.792845 1.995166 2.294940 2.614257
+0.278576 0.329548 0.667074 1.214075 1.560713 1.652347 1.873746 2.021113 2.338907 2.664300
+0.167863 0.226536 0.396757 0.597846 1.051873 1.627164 1.958256 2.062767 2.191380 2.432992
+0.348666 0.407399 0.764654 0.897788 1.054142 1.537316 1.689159 2.089782 2.640438 2.728359
+0.171013 0.243044 0.356522 0.490258 1.359997 1.815025 1.981484 2.206887 2.431276 2.636843
+0.153522 0.396506 0.847453 1.284564 1.488783 1.804268 2.273812 2.522892 2.761823 2.876763
+0.171880 0.287093 0.496257 0.755483 0.937035 1.107577 1.897834 2.108945 2.413154 2.660532
+0.227201 0.370270 0.530492 0.844519 1.174595 1.296373 1.718215 1.907170 2.166590 2.484352
+0.149331 0.183437 0.326162 0.488638 1.002939 1.377342 1.867235 2.108546 2.503408 2.786207
+0.173193 0.266920 0.374287 0.945263 1.452229 1.556781 1.952554 2.099249 2.609846 2.766646
+0.239351 0.413047 0.605130 0.721419 1.069987 1.322991 1.500901 2.100747 2.338950 2.541476
+0.314543 0.427272 0.646059 0.977969 1.105555 1.443778 1.949196 2.065960 2.472020 2.663676
+0.306321 0.430910 0.620780 0.848250 1.324991 1.683308 1.879595 2.069502 2.344394 2.454817
+0.575586 0.847570 1.152532 1.423138 1.684099 1.969479 2.240224 2.428206 2.665523 2.760463
+0.350078 0.450964 0.688480 0.893082 1.035498 1.299152 1.508386 1.683054 2.499108 2.655705
+0.471148 0.571022 0.813000 1.058092 1.196537 1.491163 1.831861 1.956586 2.408824 2.619234
+0.171564 0.273430 0.738762 0.920791 1.183470 1.349450 1.890642 2.110332 2.341546 2.722247
+0.304218 0.440526 0.720869 0.956392 1.296296 1.536912 1.798491 2.129943 2.470933 2.711029
+0.208585 0.283203 0.713164 0.859752 1.075018 1.320232 1.749308 2.009905 2.348887 2.539152
+0.264896 0.431760 0.680060 0.840630 1.005182 1.200071 1.639044 1.877513 2.579690 2.697610
+0.171107 0.229447 0.393985 0.553918 1.187522 1.583641 1.829031 2.101558 2.437468 2.610652
+0.301877 0.445169 0.968634 1.180258 1.415638 1.646629 1.953737 2.185760 2.483000 2.660034
+0.267959 0.387016 0.557674 0.755435 1.057021 1.189525 1.629581 2.283668 2.558077 2.683573
+0.295624 0.500278 0.696740 0.866240 1.099396 1.243691 1.449224 1.818732 2.156886 2.467455
+0.170796 0.218503 0.382819 0.541542 1.174040 1.482773 1.670539 2.124357 2.342810 2.501870
+0.218617 0.408868 1.012231 1.352073 1.571864 1.753294 1.946988 2.192205 2.547198 2.762737
+0.210391 0.288701 0.475984 0.690054 0.862131 1.282021 1.715676 1.959037 2.326017 2.522621
+0.325276 0.411256 0.607216 1.024267 1.146043 1.558528 1.827982 1.956178 2.547484 2.688731
+0.238733 0.302603 0.642540 0.860406 1.382580 1.700239 1.853297 2.013606 2.539089 2.671372
+0.251458 0.654734 1.143938 1.335095 1.596794 1.905380 2.171292 2.352561 2.549262 2.709208
+0.223912 0.427965 0.590260 0.805826 0.965451 1.148957 1.600066 1.767416 2.589376 2.776857
+0.231425 0.413483 0.638906 0.882586 1.449203 1.579707 1.859705 2.112105 2.296389 2.474881
+0.175747 0.273698 0.397808 1.029989 1.240179 1.441564 1.858169 1.988257 2.524452 2.677832
+0.252558 0.363162 0.974161 1.201176 1.356803 1.559352 1.792123 2.089122 2.459025 2.636551
+0.173802 0.246852 0.480971 0.700611 0.891748 1.561958 1.823062 1.996221 2.202269 2.680874
+0.156459 0.259855 0.526047 0.742605 0.958340 1.426445 1.896392 2.280343 2.683239 2.835947
+0.142921 0.202788 0.307634 0.548822 1.431571 1.572303 1.984312 2.212223 2.639484 2.831017
+0.229329 0.366711 0.836992 1.135952 1.499118 1.677865 2.047730 2.243207 2.553663 2.706012
+0.263443 0.342499 0.477117 0.660406 0.787355 1.288964 1.851275 2.320384 2.518393 2.638003
+0.212725 0.343388 0.492706 0.738769 1.226813 1.353718 1.598551 1.965475 2.110981 2.504476
+0.160187 0.263690 0.362021 0.839661 1.356922 1.457150 1.769821 1.888317 2.678737 2.835838
+0.133248 0.196263 0.549077 0.905288 1.338934 1.580432 1.965798 2.247794 2.613434 2.821093
+0.239176 0.349470 0.587777 0.780748 0.980439 1.200381 1.437420 1.725392 2.240059 2.450024
+0.360450 0.512584 0.678578 0.889177 1.014277 1.240800 1.650560 1.806004 2.370762 2.627783
+0.207946 0.300178 0.419389 0.758257 1.373065 1.509366 1.798146 2.166289 2.334602 2.736094
+0.113082 0.204024 0.875013 1.243194 1.622958 1.886831 2.142636 2.338959 2.579123 2.767029
+0.204623 0.309091 0.441874 0.966890 1.231677 1.366805 1.580086 1.745147 2.374530 2.638283
+0.306051 0.414526 0.628201 1.074722 1.259864 1.439108 1.821360 1.964678 2.394043 2.575006
+0.222328 0.323754 0.568002 0.970977 1.120920 1.580969 1.759222 2.139577 2.608362 2.763997
+0.183300 0.372397 0.683079 1.022379 1.330137 1.624137 1.951990 2.252475 2.602804 2.814906
+0.178777 0.259371 0.411261 0.873219 1.178107 1.319602 1.632433 1.885996 2.112106 2.286708
+0.195172 0.346190 0.497154 0.755965 1.230183 1.347062 1.685780 1.867553 2.329508 2.752389
+0.195738 0.263473 0.396445 0.598238 1.275429 1.903330 2.156978 2.286654 2.571493 2.728101
+0.369955 0.545605 1.042124 1.189996 1.350332 1.546670 1.867983 2.111160 2.467785 2.643118
+0.120478 0.160718 0.275169 0.491413 0.821334 1.099250 1.777446 1.936945 2.424408 2.722251
+0.312690 0.451099 0.623388 0.828741 0.993468 1.136473 1.649831 1.980283 2.173337 2.352824
+0.243020 0.364104 0.491726 0.944543 1.131493 1.302149 1.857127 1.973690 2.400218 2.803623
+0.193524 0.259253 0.688441 1.340521 1.671654 1.914554 2.135144 2.313920 2.516303 2.683437
+0.232326 0.387947 0.503848 0.715456 0.874078 1.042221 1.733322 1.898809 2.239800 2.752745
+0.127511 0.344390 0.935547 1.175974 1.388543 1.630551 1.946941 2.245394 2.574897 2.775392
+0.250995 0.323646 0.441648 0.957645 1.547323 1.747938 1.902388 2.157859 2.364221 2.510959
+0.452291 0.693622 1.167859 1.318220 1.723133 1.940224 2.173724 2.424464 2.649258 2.755778
+0.302326 0.431401 0.690302 0.950763 1.203250 1.329801 1.782387 2.179065 2.423352 2.542775
+0.355954 0.504290 0.646021 0.864339 1.352328 1.533661 1.709471 1.960437 2.313335 2.451721
+0.104149 0.152699 0.587242 0.903889 1.183253 1.432120 1.706576 1.956497 2.205742 2.655087
+0.214047 0.281655 0.457781 1.318444 1.423722 1.610884 1.738687 2.315997 2.544975 2.780560
+0.182527 0.232898 0.390991 0.554764 1.219695 1.416974 1.668180 1.883510 2.094564 2.216562
+0.338387 0.409542 0.641629 0.767246 1.002251 1.650238 1.882942 2.041315 2.327004 2.467281
+0.231453 0.309431 0.647883 0.827408 1.212245 1.724138 1.934800 2.138651 2.400716 2.581201
+0.251173 0.509839 0.868347 1.305335 1.478259 1.819818 2.046666 2.383549 2.753204 2.859247
+0.285117 0.362320 0.652022 0.913386 1.044703 1.289808 1.899468 2.119379 2.316214 2.520072
+0.308945 0.404194 0.607700 0.785461 0.897492 1.263812 1.840947 1.995191 2.217981 2.533953
+0.172631 0.233496 0.395828 0.637121 1.094870 1.305225 1.975991 2.149162 2.425342 2.614303
+0.156972 0.227094 0.399128 1.055061 1.517113 1.669668 2.078208 2.233434 2.697606 2.846463
+0.173100 0.226252 0.408500 0.582801 1.098220 1.450523 1.627000 2.016222 2.249189 2.498326
+0.315638 0.497823 0.661879 0.886266 0.997659 1.195049 2.020156 2.258426 2.523904 2.750360
+0.271575 0.365793 0.531980 0.808835 1.273952 1.739663 1.983593 2.133546 2.348498 2.473697
+0.309045 0.513620 0.898951 1.324674 1.639949 1.904400 2.137826 2.348142 2.582366 2.748999
+0.173271 0.315218 0.477788 0.757177 0.875942 1.105511 1.237776 1.628886 2.684859 2.842014
+0.214839 0.273034 0.819191 1.102040 1.352164 1.657619 1.843619 1.972455 2.148374 2.639406
+0.116215 0.162407 0.342715 0.825790 1.042936 1.381631 1.804365 2.083780 2.487045 2.753736
+0.114070 0.425427 0.799793 1.070942 1.370278 1.618583 1.941131 2.202718 2.530097 2.788603
+0.243867 0.378883 0.547723 0.808932 1.239737 1.400240 1.860324 2.069002 2.263329 2.534065
+0.240195 0.333936 0.487895 0.915142 1.015549 1.511986 1.689823 2.078568 2.520731 2.673842
+0.243495 0.327973 0.505429 0.651882 1.068591 1.611267 2.012066 2.161812 2.523348 2.687469
+0.450190 0.521168 0.921017 1.146167 1.266402 1.657642 1.864716 2.036294 2.463023 2.557702
+0.168729 0.270636 0.453713 0.701140 0.915560 1.098438 1.604334 1.960600 2.637718 2.809070
+0.285452 0.345925 0.683009 1.127133 1.267180 1.493486 1.729244 1.897942 2.101957 2.279775
+0.197911 0.283257 0.436315 0.680443 1.328944 1.456235 1.789607 2.073798 2.297794 2.442548
+0.240843 0.293460 0.653007 1.222875 1.575683 1.682154 1.863647 2.019866 2.562349 2.730154
+0.175191 0.254744 0.507483 0.660774 1.010367 1.200881 1.595444 1.912422 2.384227 2.758183
+0.433781 0.510463 0.720856 1.101334 1.226464 1.443652 1.812748 1.957333 2.487847 2.673719
+0.221585 0.287234 0.682977 1.068491 1.562962 1.716402 1.897843 2.129521 2.335900 2.524987
+0.432705 0.840501 1.285672 1.439193 1.607667 1.795398 2.063813 2.311674 2.563015 2.711062
+0.354576 0.466602 0.650767 0.813566 0.938340 1.128342 1.805345 2.218869 2.395036 2.543280
+0.353822 0.544418 0.717185 0.903075 1.193814 1.302618 1.592775 1.928464 2.123197 2.300791
+0.232127 0.335542 0.466150 1.038780 1.385075 1.474844 1.919673 2.031739 2.495480 2.805573
+0.324665 0.377060 0.695910 1.283924 1.443588 1.596523 2.037150 2.169899 2.487425 2.691252
+0.178303 0.236258 0.409957 0.644793 0.991558 1.439340 1.644055 2.056081 2.477767 2.606365
+0.284645 0.347903 0.527540 0.667977 0.816156 1.687403 1.948029 2.113140 2.519425 2.617605
+0.169782 0.245851 0.359543 0.504529 1.401427 1.633494 1.805664 2.181529 2.362061 2.647147
+0.210292 0.309966 0.666265 1.086214 1.491332 1.862248 2.127350 2.359368 2.574699 2.710415
+0.176920 0.247329 0.439418 0.634764 0.868848 1.346770 1.668256 2.024234 2.456935 2.792061
+0.291292 0.461927 0.673858 0.827395 1.001436 1.123471 1.600221 2.273412 2.437555 2.642259
+0.164460 0.272259 0.374336 0.675110 1.490030 1.612152 1.836475 1.984289 2.535905 2.742055
+0.207858 0.272302 0.418159 0.745538 1.629583 1.981417 2.127840 2.293577 2.578197 2.705476
+-0.062228 -0.323076 -0.332711 -0.101708 -0.034218 -0.067730 -0.032006 -0.034055 -0.063661 -0.112308
+0.471805 0.655978 0.860725 0.972051 1.153458 1.409133 1.784627 2.073639 2.494294 2.661139
+0.180954 0.273084 0.389972 0.849113 1.392936 1.510894 1.921378 2.096123 2.378596 2.651504
+0.225545 0.488038 0.863470 1.410418 1.596034 1.771648 2.216348 2.386984 2.715102 2.839389
+0.144776 0.247942 0.381281 0.699264 1.145490 1.295150 1.800737 2.008105 2.629862 2.826194
+0.184806 0.248115 0.690786 0.828582 1.321220 1.503651 1.718611 2.087128 2.314827 2.538325
+0.177133 0.339599 0.481545 0.790062 1.227237 1.348197 1.883037 2.021486 2.441350 2.699083
+0.311370 0.368740 0.858970 1.014739 1.208416 1.746055 1.924647 2.151463 2.415915 2.560580
+0.199710 0.264710 0.470506 0.794534 1.118412 1.570882 1.812521 1.939545 2.110880 2.373289
+0.350635 0.482066 0.710421 0.960792 1.103058 1.325978 1.913082 2.069461 2.404068 2.662115
+0.186366 0.241536 0.381062 0.517738 1.497745 1.924116 2.070412 2.234108 2.608905 2.750199
+0.509032 0.734852 0.927875 1.145398 1.394132 1.611867 1.956418 2.176366 2.420236 2.596717
+0.201922 0.299074 0.414361 0.597667 0.721234 0.975702 1.929938 2.144210 2.650822 2.846817
+0.249810 0.373368 0.691262 0.918023 1.296625 1.472578 1.881052 2.160262 2.404070 2.576539
+0.136751 0.198997 0.351968 0.839701 1.241879 1.397675 1.739341 1.946552 2.247675 2.676990
+0.215765 0.277228 0.527200 1.277413 1.507933 1.677635 2.048299 2.207947 2.614490 2.774622
+0.146093 0.199242 0.331057 0.518068 0.983944 1.184948 1.769667 1.933330 2.116265 2.713820
+0.311505 0.400669 0.630844 1.132601 1.442876 1.558170 1.906709 2.045975 2.419754 2.659979
+0.328470 0.401583 0.615037 0.993895 1.574441 1.869936 2.011558 2.184989 2.467408 2.581751
+0.463865 0.687911 1.294672 1.536811 1.700885 1.872005 2.174049 2.341841 2.576782 2.729884
+0.225601 0.311949 0.558510 0.720660 1.176452 1.364036 1.558010 2.010565 2.645874 2.801078
+0.300116 0.554320 0.704246 0.926026 1.318277 1.422364 1.788571 2.123745 2.298732 2.683560
+0.217312 0.342834 0.505628 0.885611 1.036468 1.281361 1.711880 1.931222 2.475950 2.632713
+0.235789 0.329023 0.515572 1.047927 1.413696 1.546519 1.893021 2.099995 2.430834 2.628838
+0.170354 0.225158 0.395611 0.654515 1.106878 1.458362 1.794475 2.012486 2.334320 2.553665
+0.420377 0.492906 0.763825 0.888793 1.057272 1.729447 1.982471 2.145245 2.614874 2.700457
+0.227828 0.299193 0.480966 0.855216 1.663391 1.817425 2.035090 2.237723 2.436081 2.645378
+0.104919 0.220297 0.922747 1.248851 1.468985 1.845122 2.172923 2.471447 2.702677 2.827250
+0.245660 0.363951 0.496495 0.718395 0.792531 1.188290 2.028262 2.148021 2.601079 2.767886
+0.204949 0.323637 0.501508 0.803477 1.101494 1.228773 1.446609 1.596114 1.975723 2.669065
+0.162963 0.221990 0.366143 0.569144 1.300415 1.508941 1.736879 2.176494 2.560640 2.781882
+0.226216 0.303208 0.451507 0.942554 1.584997 1.708649 1.937744 2.125981 2.374113 2.806697
+0.279313 0.434425 0.600140 0.761924 0.967326 1.085339 1.400649 2.085299 2.311823 2.531842
+0.496970 0.611003 0.813504 1.003786 1.112345 1.561294 2.006644 2.127810 2.538433 2.707483
+0.263598 0.399612 0.523023 0.751894 1.468733 1.634563 1.854672 2.093993 2.288808 2.486320
+0.447064 0.669729 1.231144 1.393911 1.519359 1.740011 2.130839 2.331661 2.622426 2.742410
+0.217113 0.344226 0.479443 0.953089 1.113345 1.292028 1.405063 2.035854 2.706084 2.818154
+0.215666 0.346628 0.459806 0.841338 1.330315 1.450787 1.693170 1.963290 2.133067 2.598851
+0.032462 0.108906 0.641839 0.918247 1.274605 1.548613 1.860118 2.149524 2.473967 2.745703
+0.126290 0.220180 0.749275 1.069688 1.256552 1.502364 1.780350 2.049865 2.514790 2.760101
+0.201396 0.256212 0.604955 0.839430 1.037016 1.425915 1.784411 2.082149 2.278545 2.520697
+0.250554 0.361913 0.538203 1.009347 1.125631 1.467374 1.842276 1.982168 2.659098 2.812528
+0.173329 0.232821 0.397105 0.674759 1.272214 1.578849 1.859567 2.046929 2.368178 2.523695
+0.361106 0.495511 0.860190 1.082212 1.386309 1.580348 1.935833 2.155852 2.453898 2.622802
+0.232936 0.346360 0.515455 0.716889 0.946937 1.062494 1.542360 2.240413 2.402681 2.639495
+0.329138 0.483393 0.640612 0.860349 1.191888 1.297933 1.656172 2.079184 2.298135 2.457837
+0.238706 0.397136 0.560834 0.799404 1.288560 1.405264 1.678272 2.182520 2.375152 2.668620
+0.304175 0.364112 0.779173 1.338909 1.476173 1.664278 1.993154 2.118992 2.593337 2.731349
+0.164802 0.217347 0.366682 0.565116 0.753855 1.009701 1.744416 2.023924 2.268955 2.433440
+0.296797 0.356308 0.759995 1.197140 1.309824 1.482490 1.667647 1.840314 2.517650 2.648945
+0.273443 0.411365 0.594999 0.894650 1.424021 1.586944 1.842399 2.215251 2.447173 2.729450
+0.236751 0.360177 1.030195 1.434197 1.683780 1.888286 2.114605 2.264435 2.477029 2.630414
+0.273289 0.394610 0.610213 0.759723 0.937713 1.239572 1.713796 1.995028 2.367774 2.635783
+0.334115 0.411443 0.610825 0.955868 1.502521 1.785262 1.937709 2.105790 2.350122 2.470200
+0.159072 0.242631 0.393231 0.844130 1.217685 1.419823 1.733096 1.891617 2.514256 2.659089
+0.309184 0.361119 0.759243 1.263501 1.440575 1.570597 1.821846 1.944982 2.440271 2.684484
+0.161993 0.224640 0.401324 0.753906 1.032749 1.440682 1.809558 1.978594 2.149676 2.538575
+0.247815 0.331789 0.491727 0.713759 0.865824 1.618286 1.768016 2.244205 2.532077 2.684242
+0.170605 0.248525 0.354505 0.495374 1.569514 1.828195 1.990227 2.213056 2.400769 2.760431
+0.331931 0.515143 0.809566 1.042681 1.451957 1.638579 1.956390 2.262500 2.598192 2.813680
+0.209020 0.349585 0.505601 0.704594 0.814790 1.362447 1.939075 2.048582 2.423957 2.756261
+0.281207 0.453713 0.595485 0.765529 1.220000 1.391996 1.561764 2.022289 2.265860 2.679768
+0.150346 0.251592 0.409505 0.770775 1.236125 1.384343 1.745495 1.893299 2.588497 2.822991
+0.161090 0.246862 0.484826 1.245783 1.397859 1.714145 2.040802 2.468857 2.706233 2.837580
+0.213765 0.374235 0.536566 0.733390 1.126324 1.249567 1.538484 1.976391 2.151928 2.359273
+0.272518 0.457655 0.808972 1.019104 1.150011 1.326035 1.711513 2.051136 2.549677 2.799790
+0.179767 0.262954 0.395346 0.660835 1.345694 1.502264 1.819384 1.963548 2.273263 2.618778
+0.175488 0.306329 1.103215 1.306099 1.574389 1.897560 2.214935 2.416432 2.605393 2.738739
+0.154666 0.239592 0.415828 0.780679 0.945224 1.233384 1.696039 1.940742 2.514563 2.679770
+0.269177 0.354740 0.557021 0.969509 1.345317 1.463570 1.798387 2.241221 2.456339 2.610210
+0.239145 0.326264 0.494465 1.071214 1.209459 1.537726 1.952743 2.113220 2.610725 2.747535
+0.218208 0.598959 0.871276 1.110151 1.386993 1.648655 1.918609 2.193362 2.546880 2.756671
+0.176681 0.262087 0.424568 0.933283 1.208095 1.334188 1.755633 1.926341 2.187131 2.556577
+0.213062 0.385248 0.514741 0.876978 1.165897 1.307493 1.825031 2.012224 2.554948 2.737931
+0.151222 0.247007 0.382114 0.751657 1.215610 1.342363 1.975904 2.137584 2.617134 2.820105
+0.299224 0.473356 0.825171 1.146594 1.528401 1.694234 1.952214 2.144722 2.373789 2.555562
+0.207137 0.319897 0.501670 0.711149 0.853927 1.057889 1.770494 2.071726 2.492216 2.811033
+0.465560 0.618831 0.782398 1.010037 1.195984 1.322540 1.855998 2.160517 2.324801 2.507033
+0.201076 0.301843 0.444311 0.822638 1.176021 1.272371 1.646433 2.064560 2.227727 2.623829
+0.210505 0.247037 0.495092 1.302518 1.760886 1.827284 2.217044 2.446377 2.623543 2.741148
+0.195999 0.279369 0.481573 0.654787 1.080842 1.412382 1.716490 2.052322 2.290101 2.738165
+0.236926 0.310814 0.896361 1.162180 1.328092 1.558913 1.774564 1.905228 2.402246 2.665023
+0.244472 0.327963 0.646896 1.095894 1.620412 1.772324 2.045520 2.193957 2.547128 2.722609
+0.346731 0.581380 1.070375 1.522205 1.740223 1.980572 2.266647 2.404418 2.746561 2.871000
+0.430698 0.619190 0.836877 1.015020 1.167909 1.332640 1.815328 2.234722 2.476070 2.638178
+0.221367 0.307079 0.458329 0.850712 1.289560 1.423009 1.621570 1.985342 2.331434 2.467832
+0.116322 0.217253 0.728326 0.940859 1.188330 1.378722 1.687841 1.910693 2.604869 2.797202
+0.187928 0.267923 0.389066 1.155944 1.483571 1.593699 1.818241 1.963936 2.473096 2.607548
+0.168954 0.211406 0.372427 0.529448 0.973588 1.431171 1.621558 1.856431 2.189298 2.343881
+0.273371 0.413963 0.664359 0.794553 1.017733 1.399395 1.724746 2.089838 2.367948 2.555808
+0.212416 0.270112 0.509967 0.759092 1.293781 1.781086 2.091445 2.219374 2.499069 2.630826
+0.300696 0.481937 0.835784 1.276211 1.461493 1.644316 1.971697 2.234847 2.641035 2.829278
+0.285091 0.416886 0.605330 0.808172 0.944872 1.129570 1.919248 2.157389 2.400226 2.673656
+0.225704 0.384656 0.630586 0.788196 1.224861 1.419420 1.681321 1.970805 2.212616 2.617121
+0.132447 0.177755 0.301537 0.471768 1.155148 1.332095 1.708466 2.024543 2.495585 2.788666
+0.252038 0.329800 0.481080 0.954609 1.422083 1.620359 2.006123 2.168392 2.355165 2.505083
+0.183435 0.241389 0.417674 0.598794 1.014975 1.205139 1.701958 1.977784 2.374336 2.586101
+0.302192 0.384974 0.608153 0.938510 1.084287 1.329203 2.069641 2.319152 2.494203 2.675684
+0.198808 0.281220 0.391748 0.777377 1.553382 1.790825 1.925301 2.135471 2.304278 2.485154
+0.370469 0.548730 0.880131 1.168541 1.456674 1.645880 2.049941 2.288441 2.557653 2.759821
+0.156583 0.250724 0.394960 0.691089 0.837322 1.066297 1.836287 1.972838 2.591097 2.786561
+0.322824 0.379018 0.593081 1.086011 1.406693 1.490406 1.734998 1.912817 2.081717 2.475586
+0.158775 0.218842 0.457222 0.869711 1.219773 1.629722 1.953462 2.134004 2.392326 2.640093
+0.217524 0.325911 0.628615 0.997991 1.504329 1.668932 1.958103 2.245372 2.630371 2.808323
+0.170343 0.254286 0.510717 0.814297 1.028209 1.355930 1.726583 2.047676 2.381522 2.692279
+0.297689 0.343194 0.742306 0.882638 1.038877 1.713935 1.880819 2.088189 2.556386 2.634265
+0.215251 0.296748 0.454072 0.676499 1.007705 1.797713 2.004948 2.206914 2.548819 2.725676
+0.412021 0.642343 0.828334 0.951784 1.236305 1.495649 1.898175 2.129486 2.438961 2.666301
+0.179065 0.252377 0.372814 0.530815 0.713797 0.927597 1.666069 2.104770 2.392383 2.734423
+0.433130 0.566964 0.740476 0.961675 1.107074 1.288034 1.772074 1.904854 2.174689 2.570674
+0.223409 0.295735 0.606368 0.786946 1.326960 1.538874 1.755901 1.939986 2.371080 2.488210
+0.224170 0.294402 0.684662 1.251045 1.593460 1.708681 2.018073 2.187551 2.515208 2.721384
+0.166379 0.238226 0.406222 0.623445 0.883761 1.076979 1.603102 1.916054 2.202559 2.699771
+0.489484 0.578385 0.832748 1.115430 1.216650 1.575882 1.929300 2.049396 2.522680 2.658393
+0.291742 0.359710 0.491711 1.071820 1.458792 1.603219 1.747893 2.124226 2.418190 2.528558
+0.438848 0.678792 1.139964 1.311051 1.673038 1.878533 2.126488 2.288717 2.493483 2.631731
+0.271300 0.466760 0.592041 0.808897 0.942888 1.124238 1.820005 1.976080 2.249710 2.775433
+0.389199 0.559773 0.703683 0.900063 1.345064 1.462662 1.769904 2.128433 2.365683 2.501187
+0.190440 0.280423 0.447001 1.039189 1.218375 1.614861 1.844728 2.111340 2.460942 2.613396
+0.241700 0.302019 0.613366 1.249946 1.410607 1.580256 1.768325 1.986861 2.430632 2.581026
+0.206516 0.286418 0.537788 0.707728 1.197196 1.572380 1.755394 1.933391 2.472918 2.645023
+0.318502 0.396523 0.647544 0.775364 0.936563 1.581584 2.058082 2.195477 2.618710 2.743108
+0.191584 0.269771 0.414492 0.786131 1.376273 1.613474 1.799398 2.344394 2.536806 2.749566
+0.237976 0.316356 0.446480 0.893873 1.679975 1.965388 2.096434 2.252618 2.468845 2.587829
+0.123845 0.159072 0.284123 0.467782 0.818151 1.307335 1.754936 2.066298 2.476057 2.758144
+0.261052 0.393384 0.760978 0.918516 1.100980 1.327690 1.632686 2.033602 2.384945 2.554088
+0.264436 0.350588 0.609731 0.749716 1.157992 1.660102 1.868180 2.004961 2.591971 2.739458
+0.164585 0.215089 0.375970 0.959153 1.727354 1.859913 1.991898 2.220550 2.431018 2.769731
+0.204030 0.290606 0.483834 0.827022 1.016831 1.223453 1.699260 1.910125 2.140620 2.267503
+0.526138 0.709922 0.836725 1.069406 1.269462 1.405044 1.834798 2.034524 2.212188 2.459999
+0.225247 0.340174 0.449473 0.914306 1.380619 1.486761 1.795410 1.983939 2.206215 2.713630
+0.200753 0.622848 0.941841 1.226624 1.507543 1.821962 2.134104 2.366417 2.634739 2.771988
+0.174703 0.282776 0.702258 0.898342 1.084446 1.266724 1.757851 2.083739 2.401420 2.756275
+0.249131 0.323445 0.720321 0.878509 1.110362 1.576682 1.865315 2.114744 2.387200 2.528666
+0.192991 0.271656 0.400815 0.639719 1.281970 1.423380 2.050229 2.264541 2.462010 2.662504
+0.266874 0.325220 0.675228 1.126545 1.267438 1.706113 1.920856 2.125988 2.574605 2.678193
+0.223081 0.286041 0.655976 0.816840 1.060069 1.561164 1.748293 1.911129 2.075313 2.503462
+0.407716 0.515541 0.739241 0.941291 1.059746 1.404674 1.781339 1.892197 2.404849 2.648290
+0.240599 0.312213 0.510661 0.666324 1.224803 1.866233 2.050438 2.204639 2.619539 2.768546
+0.384825 0.587577 1.021218 1.214225 1.437340 1.728676 1.998469 2.183120 2.571593 2.747573
+0.245764 0.343500 0.509527 0.727872 0.876936 1.024899 1.769731 2.415709 2.632816 2.787619
+0.290619 0.390761 0.566531 0.941586 1.353924 1.461037 1.795546 2.132642 2.313283 2.486608
+0.172727 0.258217 0.438312 0.716613 1.170907 1.311367 1.733515 1.899224 2.138675 2.739799
+0.222657 0.287215 0.449779 1.369666 1.490501 1.701894 1.880425 2.393512 2.600773 2.787142
+0.154428 0.222305 0.357310 0.630820 1.037882 1.342771 1.730454 1.920364 2.046990 2.549536
+0.299554 0.623129 0.825895 1.063948 1.332600 1.466624 1.854370 2.128982 2.327186 2.521370
+0.218073 0.257913 0.681337 0.900215 1.517137 1.843444 2.006541 2.205575 2.505616 2.633109
+0.686321 1.027088 1.182402 1.346554 1.590920 1.854772 2.111571 2.250916 2.482490 2.625270
+0.220174 0.305579 0.452469 1.009178 1.208905 1.586079 1.726183 2.308495 2.539415 2.745570
+0.341504 0.508703 0.663379 0.854389 1.270406 1.419250 1.624925 2.064447 2.426578 2.552193
+0.199767 0.277559 0.419200 1.151687 1.302355 1.531961 1.720872 2.013206 2.476765 2.595851
+0.243094 0.314600 0.435247 1.051642 1.528616 1.656151 1.884292 2.065968 2.307851 2.563448
+0.224054 0.300322 0.546545 0.706978 1.059557 1.412749 1.925773 2.119205 2.355100 2.490204
+0.342948 0.395972 0.713508 0.788514 1.092279 1.685316 1.836105 2.270695 2.521777 2.625975
+0.183089 0.263605 0.369340 0.558240 1.511750 1.902656 2.045224 2.218195 2.445586 2.611569
+0.332871 0.558850 0.877672 1.147342 1.590679 1.823730 2.184823 2.407743 2.721120 2.860996
+0.228040 0.355308 0.498081 0.818616 1.098234 1.212951 1.802644 2.085736 2.290465 2.748208
+0.189112 0.289591 0.530362 0.768658 0.944224 1.325806 1.678253 1.884531 2.251127 2.682120
+0.144799 0.199748 0.350015 0.546248 1.106050 1.629785 1.884696 2.005826 2.432189 2.780747
+0.172297 0.243074 0.380863 0.968654 1.645970 1.743664 1.952788 2.092464 2.574491 2.809210
+0.220791 0.397930 0.676300 0.814804 1.085618 1.265955 1.557093 1.974461 2.157493 2.568431
+0.351036 0.481040 0.684693 1.046142 1.219179 1.404440 1.909685 2.051432 2.405205 2.669908
+0.255837 0.394071 0.518620 0.767306 1.393237 1.618907 1.766511 2.022002 2.425935 2.559548
+0.418747 0.617245 1.109151 1.299581 1.560582 1.912698 2.151587 2.420609 2.666448 2.766110
+0.194318 0.321980 0.488422 0.733153 0.927489 1.091432 1.537804 1.709529 2.300954 2.777973
+0.441506 0.552407 0.771304 1.070023 1.253431 1.402955 1.774359 1.917186 2.236828 2.573015
+0.096364 0.161493 0.604211 0.841192 1.084960 1.469012 1.765762 2.035652 2.415550 2.679394
+0.164758 0.273531 0.786362 0.944165 1.314729 1.443079 1.820614 2.232970 2.474360 2.689648
+0.214880 0.277389 0.624783 0.819250 1.049581 1.383136 1.664426 1.809937 2.247050 2.531672
+0.339450 0.490710 0.650894 0.802164 0.968459 1.286294 1.736119 2.108232 2.488573 2.676959
+0.173316 0.243343 0.367127 0.508577 1.224968 1.826439 1.981666 2.158278 2.351480 2.588130
+0.452858 0.676518 0.916839 1.095033 1.353796 1.666215 1.906615 2.097253 2.478402 2.671285
+0.255572 0.430173 0.627154 0.845685 1.029142 1.165075 1.851297 2.238290 2.425106 2.786559
+0.292973 0.495593 0.670882 0.825200 1.176688 1.345844 1.524943 1.905429 2.293155 2.481585
+0.190065 0.270578 0.429350 0.650608 1.338108 1.544596 1.723081 2.100587 2.455792 2.616187
+0.270146 0.357004 1.012493 1.334770 1.484494 1.749118 1.948371 2.163260 2.479187 2.615849
+0.190746 0.284342 0.459935 0.840326 1.058271 1.247416 1.686518 1.858042 2.349852 2.474999
+0.261440 0.355783 0.788131 0.963975 1.170960 1.426067 1.663365 1.845513 2.450110 2.615423
+0.223477 0.289406 0.644196 0.841108 1.449672 1.680461 1.864688 1.970082 2.320400 2.678113
+0.307863 0.471864 0.951274 1.401941 1.598874 1.839736 2.064310 2.222939 2.646039 2.793416
+0.215456 0.324380 0.542457 0.738120 0.904477 1.125488 1.593790 1.942637 2.403731 2.625335
+0.327978 0.431326 0.649146 0.980387 1.452639 1.595021 1.827042 2.174676 2.430383 2.562971
+0.221416 0.405136 0.534878 0.941825 1.275052 1.387146 1.678769 1.816890 2.607600 2.805074
+0.261063 0.296006 0.765065 1.323946 1.455938 1.597320 1.755333 1.939918 2.595321 2.725885
+0.196465 0.266597 0.478088 0.673695 0.918173 1.783876 1.968005 2.144556 2.340807 2.571099
+0.222072 0.329556 0.457488 0.632821 0.926941 1.737060 1.925589 2.280188 2.742106 2.840767
+0.177587 0.262768 0.386637 0.661755 1.507334 1.651771 2.016609 2.209898 2.436253 2.794750
+0.237412 0.318760 0.572489 1.126672 1.262629 1.705670 1.962639 2.240223 2.640836 2.760043
+0.164018 0.263560 0.389157 0.576607 0.699517 1.304965 1.938275 2.108181 2.361245 2.481099
+0.312927 0.453499 0.595937 0.720801 1.155128 1.421222 1.654805 2.125481 2.342733 2.559528
+0.187311 0.340553 0.479298 0.800541 1.324137 1.434292 1.773373 1.966276 2.442163 2.794439
+0.240145 0.361802 0.529355 1.032511 1.333136 1.613724 1.902121 2.393189 2.610681 2.798432
+0.256618 0.369979 0.571037 0.805889 0.931870 1.242267 1.556114 1.777808 2.100100 2.279277
+0.315460 0.387429 0.763439 1.135994 1.225008 1.383314 1.479969 1.857272 2.506217 2.572444
+0.231972 0.332687 0.498409 0.763292 1.482840 1.675304 1.917342 2.171163 2.373797 2.762604
+0.241092 0.374768 0.886119 1.278350 1.760790 1.986414 2.153341 2.321588 2.561671 2.682561
+0.181333 0.265570 0.457041 0.832421 0.997777 1.194519 1.519027 1.911348 2.372249 2.624795
+0.217281 0.313910 0.490988 1.021293 1.238563 1.420272 1.905572 2.077699 2.389621 2.611841
+0.241907 0.344617 0.495322 0.833050 0.943750 1.625368 1.957947 2.118287 2.573169 2.706253
+0.260933 0.421768 0.714877 1.045217 1.348286 1.557267 1.920459 2.142565 2.463638 2.761801
+0.191170 0.260573 0.482902 0.852619 1.182296 1.355163 1.734327 2.038425 2.220238 2.348315
+0.235960 0.420321 0.558300 0.822306 0.959709 1.163020 1.746196 1.872763 2.463190 2.656887
+0.182801 0.229509 0.384936 0.525996 1.144440 1.505356 2.087714 2.235691 2.603441 2.821072
+0.433326 0.648975 1.152821 1.324354 1.499568 1.680615 1.927155 2.144623 2.501930 2.672369
+0.185230 0.282855 0.433567 0.613008 0.800249 1.189297 1.815486 2.216184 2.611609 2.819742
+0.305950 0.512379 0.682631 0.866346 1.140903 1.267093 1.689424 1.993235 2.167743 2.491215
+0.214384 0.330677 0.465107 0.799324 1.249335 1.354711 1.961836 2.155521 2.365402 2.768664
+0.252228 0.294891 0.721925 1.385448 1.627786 1.728361 2.094373 2.246017 2.542430 2.725817
+0.247355 0.467492 0.616684 0.821505 1.051679 1.163064 1.676721 1.903589 2.192444 2.770439
+0.267056 0.322353 0.878273 1.273551 1.387890 1.656880 1.838486 2.256932 2.489329 2.617788
+0.276548 0.347431 0.510036 0.916479 1.503298 1.902076 2.081537 2.205346 2.459159 2.574602
+0.420124 0.634373 0.972031 1.349147 1.660814 1.863940 2.209039 2.359323 2.665996 2.774761
+0.245603 0.346643 0.484960 0.852273 1.113317 1.246194 1.675673 2.134010 2.397448 2.567438
+0.278909 0.453205 0.609401 0.817334 1.386351 1.540485 1.784357 2.027199 2.208866 2.416858
+0.216689 0.291968 0.633303 0.821476 1.230792 1.517474 1.740384 1.839894 2.264549 2.645633
+0.250583 0.356352 0.706187 1.159764 1.340429 1.531877 1.805133 2.212588 2.494217 2.645859
+0.173603 0.221482 0.407668 0.602668 1.173887 1.363948 1.714837 2.069366 2.246713 2.384843
+0.351700 0.426939 0.676212 0.785470 1.018054 1.600174 1.760596 1.981016 2.523457 2.622580
+0.247404 0.347843 0.537821 0.715383 1.334742 1.730445 1.932738 2.116362 2.550868 2.719251
+0.267640 0.435192 0.734410 1.154981 1.439281 1.665625 2.036115 2.238505 2.694509 2.857159
+0.377315 0.500802 0.678295 0.852176 0.986722 1.234297 1.946465 2.216296 2.369690 2.568046
+0.282474 0.484623 0.647346 0.838126 1.116069 1.236355 1.605158 2.068283 2.241476 2.594701
+0.179830 0.276699 0.393477 0.618077 1.005536 1.171683 1.936124 2.147218 2.344016 2.802089
+0.150385 0.222615 0.453699 1.059570 1.514904 1.869262 2.170323 2.385821 2.713541 2.834759
+0.190104 0.279191 0.487233 0.679289 1.139586 1.367418 1.532297 1.968753 2.379302 2.609276
+0.383123 0.512258 0.719040 0.900857 1.026096 1.446135 1.985069 2.104295 2.577580 2.725283
+0.233385 0.311008 0.468900 0.822874 1.358548 1.845397 2.088437 2.201482 2.419016 2.524441
+0.448047 0.666107 0.986682 1.233646 1.707798 1.882326 2.175233 2.389889 2.561257 2.672922
+0.190653 0.315609 0.490994 0.746849 0.882522 1.292447 1.594598 1.771911 2.563910 2.770587
+0.215760 0.268515 0.648673 1.130954 1.282429 1.603348 1.802088 2.039412 2.361344 2.489232
+0.146123 0.204228 0.382306 0.718573 1.152464 1.523749 1.750535 2.085976 2.456666 2.706774
+0.097438 0.189231 0.726839 1.130330 1.394979 1.591658 1.959512 2.188961 2.611863 2.823535
+0.153693 0.220100 0.418171 0.907592 1.098588 1.409276 1.661682 2.052898 2.357440 2.534558
+0.249007 0.320795 0.581631 0.894597 1.056178 1.470144 1.725025 1.888314 2.380417 2.512561
+0.215043 0.307452 0.489967 0.675625 1.212878 1.644852 1.813460 2.219287 2.421185 2.711916
+0.454182 0.656019 0.980383 1.162424 1.342999 1.469780 1.737221 2.016043 2.396287 2.589121
+0.248859 0.363988 0.568562 0.710472 0.879383 0.969136 1.321791 2.203573 2.459572 2.685742
+0.275498 0.346347 0.720990 0.962739 1.142409 1.548421 1.756807 1.939827 2.107470 2.346331
+0.168346 0.213677 0.371061 0.533405 1.281879 1.420915 1.743873 1.929374 2.354611 2.516531
+0.269357 0.323555 0.660417 1.246119 1.389881 1.620112 1.880792 2.024803 2.535747 2.641379
+0.143544 0.211826 0.349106 0.686750 0.852997 1.123379 1.740477 1.910903 2.395457 2.675160
+0.391096 0.461323 0.706811 0.863080 0.973392 1.482338 1.771634 1.885759 2.506445 2.623396
+0.306784 0.371767 0.612809 1.165417 1.539601 1.649444 1.847967 2.215674 2.421224 2.551842
+0.412446 0.658776 1.248823 1.445679 1.591378 1.718751 1.944947 2.241242 2.542474 2.718017
+0.219635 0.320449 0.459092 0.733764 0.861516 1.087584 1.877017 2.055926 2.267583 2.421807
+0.353269 0.558306 0.705301 0.895998 1.276299 1.401657 1.682423 1.948663 2.130723 2.378531
+0.266056 0.406507 0.542960 1.171871 1.333369 1.503282 1.781150 1.967881 2.639831 2.805456
+0.366997 0.435212 0.708835 1.184565 1.338341 1.578537 2.031195 2.174915 2.531932 2.718652
+0.180016 0.244121 0.466532 0.637822 0.933798 1.613163 1.758726 2.141582 2.383844 2.570767
+0.183031 0.268217 0.410149 0.583275 0.768297 1.302461 1.927508 2.184191 2.515648 2.724226
+0.198728 0.279758 0.393674 0.687093 1.521403 1.831985 1.964413 2.182576 2.354737 2.718166
+0.266621 0.428987 0.748177 1.052044 1.416922 1.709958 1.975394 2.163065 2.390250 2.722350
+0.187580 0.301657 0.428103 0.623084 0.722948 1.407722 1.664241 1.898839 2.663491 2.802190
+0.207840 0.306975 0.483853 0.724360 1.022497 1.221432 1.415162 1.956839 2.527680 2.734643
+0.188611 0.284294 0.408262 0.721431 1.384715 1.505269 1.966087 2.173208 2.428517 2.770771
+0.222823 0.272639 0.503764 0.859246 1.498403 1.885767 2.099957 2.235388 2.567829 2.691284
+0.152758 0.219680 0.338675 0.597863 0.978697 1.200801 1.746909 1.957261 2.074441 2.404458
+0.429246 0.630671 0.792842 0.964490 1.262744 1.388795 1.721613 2.091229 2.345298 2.490896
+0.256329 0.380734 0.539915 1.009152 1.400960 1.509524 1.869215 2.029196 2.348803 2.776082
+0.272403 0.672458 0.977874 1.334181 1.683066 1.922996 2.291748 2.486116 2.709534 2.862231
+0.158762 0.287189 0.410234 0.812307 1.117621 1.262447 1.898049 2.047016 2.529228 2.738030
+0.179810 0.233529 0.707400 1.047569 1.289640 1.489108 1.847319 2.074331 2.343157 2.539680
+0.215347 0.304896 0.440699 0.897509 1.322585 1.472844 1.996310 2.165007 2.384550 2.574797
+0.286874 0.339813 0.883878 1.115931 1.272467 1.744249 1.885743 2.158576 2.589603 2.672644
+0.210579 0.284270 0.517041 0.796519 1.129021 1.668905 1.939439 2.065525 2.221131 2.479044
+0.261094 0.357573 0.576680 0.963769 1.112459 1.279265 1.822867 1.981048 2.197737 2.571008
+0.181278 0.244687 0.379354 0.499565 1.371147 1.939687 2.081545 2.257664 2.473413 2.679019
+0.491809 0.793403 1.095573 1.248586 1.433776 1.611914 1.888047 2.132035 2.457073 2.627391
+0.251235 0.353668 0.466231 0.673754 0.761327 1.114781 2.007224 2.123861 2.465832 2.639406
+0.345158 0.523258 0.679274 0.860119 1.194849 1.326006 1.848632 2.132397 2.326670 2.510966
+0.160104 0.220957 0.395991 0.698411 0.969721 1.448772 1.710923 1.833738 2.255148 2.614909
+0.154242 0.218964 0.347268 1.230461 1.592574 1.733703 2.002980 2.182922 2.555376 2.704150
+0.147752 0.202050 0.328105 0.531857 1.097229 1.287887 1.880144 2.033520 2.241027 2.732837
+0.394173 0.497084 0.712849 1.053505 1.351267 1.458228 1.861207 2.181794 2.392320 2.533753
+0.302335 0.380917 0.549353 0.985252 1.517171 1.702307 1.859140 2.148560 2.460271 2.579449
+0.489225 0.748632 1.289304 1.544824 1.780201 2.071873 2.310551 2.443509 2.704605 2.789720
+0.237235 0.383617 0.738218 0.908733 1.218091 1.378373 1.607258 2.196781 2.508687 2.662952
+0.287297 0.414596 0.576260 0.837481 1.292636 1.398051 1.699746 2.155291 2.397760 2.512719
+0.226644 0.373291 0.522981 0.950126 1.196878 1.352198 1.832943 1.977466 2.370185 2.574990
+0.202424 0.294204 0.576457 1.079769 1.296360 1.513369 1.942298 2.239055 2.513119 2.684820
+0.205672 0.262350 0.438217 0.606959 0.798794 1.451892 1.730536 1.885799 2.292567 2.433348
+0.304096 0.348725 0.817557 0.973213 1.149195 1.769516 1.914392 2.234704 2.592687 2.674729
+0.206504 0.281307 0.376040 0.779557 1.499555 1.886752 2.032034 2.220961 2.528659 2.666047
+0.130572 0.255765 0.794488 1.301534 1.504711 1.681929 2.069095 2.309137 2.695781 2.848379
+0.214845 0.339856 0.490758 0.723584 1.026000 1.188343 1.937657 2.288473 2.513405 2.753320
+0.359564 0.482479 0.670546 1.042777 1.240083 1.360140 1.592377 1.718141 2.214001 2.639319
+0.106171 0.136363 0.239866 0.666826 1.262252 1.543841 1.886197 2.162484 2.518336 2.782589
+0.188744 0.251920 0.360219 0.913075 1.618822 1.785177 1.927723 2.115808 2.320559 2.642776
+0.225904 0.378515 0.558007 0.728218 0.996381 1.117859 1.477832 1.960983 2.185323 2.667571
+0.436819 0.511780 0.811933 1.004760 1.128440 1.604755 1.813182 1.987683 2.595291 2.709021
+0.249083 0.362078 0.480846 0.813722 1.404123 1.566622 1.741757 2.142883 2.302238 2.567856
+0.249083 0.362078 0.480846 0.813722 1.404123 1.566622 1.741757 2.142883 2.302238 2.567856
diff --git a/codec2/branches/0.7/src/codebook/lspvqexp2.txt b/codec2/branches/0.7/src/codebook/lspvqexp2.txt
new file mode 100644 (file)
index 0000000..80fe18f
--- /dev/null
@@ -0,0 +1,2049 @@
+5 2048
+-0.002077 -0.038247 -0.036477 -0.003710 0.058915
+-0.035874 -0.128709 0.029183 -0.019849 0.049800
+-0.007389 -0.040358 0.044426 0.047695 -0.043474
+0.075558 0.066718 -0.000350 -0.002910 0.009981
+-0.009790 0.076568 -0.100581 0.021504 -0.026649
+-0.026362 -0.100884 -0.003799 0.061469 0.001711
+-0.034198 -0.008936 0.039170 -0.055448 -0.078447
+0.028441 -0.038152 0.015590 0.036567 -0.041377
+0.049588 -0.091695 0.004580 -0.055922 -0.041638
+-0.025374 -0.037246 -0.002046 0.002822 -0.108640
+-0.050719 0.152889 0.036331 0.025204 -0.017701
+0.035302 0.120953 0.037832 -0.092915 0.065586
+-0.048191 -0.092276 -0.077588 -0.043380 0.071115
+0.011347 -0.004383 0.064201 0.091266 -0.037474
+0.019023 0.014911 -0.012935 0.038099 0.015753
+0.005340 -0.046005 0.048595 0.061014 0.075044
+0.083994 -0.042736 0.000191 -0.120346 0.059455
+-0.040009 -0.085618 -0.022013 0.016604 -0.021977
+-0.041351 0.055057 0.041498 -0.057724 -0.004755
+0.046951 0.098620 0.036630 -0.034510 0.026358
+0.034831 -0.018107 -0.038210 -0.024564 -0.076584
+-0.038199 -0.082180 -0.087172 0.100873 -0.013934
+0.007410 0.052748 -0.012468 -0.086356 -0.004344
+-0.008693 0.023248 0.088995 0.063277 -0.010981
+-0.014865 -0.008322 -0.026526 0.001412 -0.009086
+-0.041663 -0.082625 0.022751 -0.040388 -0.157427
+0.000052 0.047105 0.090012 0.049647 -0.052600
+0.043776 0.044112 -0.006996 0.035467 0.033674
+0.038165 0.009940 -0.005274 -0.025234 0.012284
+0.059331 0.033687 -0.030071 0.038173 -0.045016
+0.026068 0.158444 0.048818 -0.057637 0.009770
+-0.040754 -0.099489 -0.027782 -0.004839 0.170178
+0.018211 -0.024125 -0.001981 -0.056519 0.022604
+0.043672 -0.084946 0.014191 0.071154 -0.005074
+-0.088121 -0.013992 -0.039939 0.008830 -0.019720
+-0.014986 0.009192 -0.018737 -0.054735 -0.013960
+-0.001601 0.002582 -0.065304 0.007212 -0.013857
+-0.007417 -0.077118 -0.033128 0.041117 0.100625
+0.000688 -0.014708 -0.011064 -0.123109 -0.008590
+0.038570 -0.013241 0.026994 -0.007213 -0.000633
+0.001257 -0.072096 0.057499 0.003234 0.041459
+-0.084929 -0.010858 0.034929 0.018375 -0.101168
+-0.009436 0.035974 -0.047298 0.107772 -0.014572
+-0.033241 0.076725 -0.052278 -0.044989 0.064574
+-0.034320 -0.080934 -0.062584 -0.052365 -0.007583
+0.043332 -0.039973 0.001890 0.081092 0.032425
+0.072661 0.019296 -0.009173 -0.013795 -0.048534
+0.003494 -0.036829 0.029480 0.062652 0.019438
+0.003633 -0.011968 -0.096593 -0.102286 0.064289
+-0.051416 -0.052157 -0.106111 0.005858 -0.031779
+0.001473 0.071136 -0.017587 0.041119 -0.084642
+-0.019285 0.061407 0.024265 -0.082217 0.101714
+-0.021349 -0.011424 -0.157899 -0.011584 0.086331
+-0.079601 0.013742 -0.095978 0.093032 0.011498
+-0.108846 -0.042340 -0.021774 -0.091363 -0.082840
+-0.068721 -0.023200 0.069062 0.025331 -0.063542
+-0.002176 -0.044709 -0.011586 -0.035579 -0.061392
+0.002329 -0.055782 0.087560 -0.009142 -0.031210
+0.087176 0.029363 0.048300 0.030101 0.003028
+-0.006744 0.110741 0.047285 0.042711 0.114962
+-0.014983 0.067022 -0.034867 0.007693 0.108661
+0.072716 0.001158 -0.020279 0.097118 -0.049090
+0.018332 0.073348 0.048479 0.038012 -0.075550
+0.024128 -0.002290 0.027979 -0.007476 0.128642
+0.063321 -0.016130 -0.010724 -0.033216 0.012203
+0.004603 -0.069020 0.019149 0.023442 -0.041990
+0.001559 -0.054141 -0.017873 0.001051 0.009669
+0.007371 0.043631 0.032348 -0.066689 -0.007712
+0.075542 0.039341 -0.074389 0.089409 -0.067587
+0.013297 -0.123535 -0.034031 0.013429 0.024826
+0.017265 0.052105 0.067939 -0.101957 -0.053347
+0.046413 0.004984 0.062332 0.030324 0.060242
+-0.025911 -0.060816 0.054284 -0.056832 0.016850
+0.007933 -0.018569 -0.000549 0.026701 -0.090331
+-0.006708 0.055666 0.016664 0.060888 -0.010839
+-0.037232 0.056511 -0.020495 -0.017025 0.030780
+-0.059804 -0.054145 -0.035811 -0.030383 -0.022947
+-0.038436 -0.017628 -0.001154 0.071736 0.013679
+0.089806 0.109393 0.002158 0.022933 -0.009429
+-0.081438 -0.020658 0.036259 0.054585 0.017455
+0.037820 0.018769 -0.052528 -0.146355 0.121991
+-0.018012 -0.054744 0.003927 0.003980 -0.068627
+-0.025582 0.068240 0.012886 -0.118982 -0.025012
+-0.060768 0.074453 0.039306 0.043620 -0.021238
+0.008481 -0.086583 -0.067953 0.013657 -0.016164
+0.052682 0.037754 -0.034526 0.147500 -0.038053
+-0.000554 0.038997 -0.033353 -0.103730 -0.024374
+0.063047 0.007908 0.052749 -0.060232 0.105523
+-0.018157 -0.023187 0.050942 -0.044718 0.023590
+-0.031973 -0.076362 0.073925 0.002114 -0.024398
+-0.058682 0.080042 0.018073 0.170306 0.034023
+0.049977 -0.005101 0.005590 0.044243 0.045804
+-0.002783 0.065756 -0.036121 -0.026414 -0.032356
+0.022865 0.009608 0.014138 0.076862 -0.045138
+0.060759 0.119694 0.029403 -0.106477 -0.030301
+0.005873 -0.044463 0.032373 0.018732 0.030235
+0.054996 0.014096 -0.056245 -0.108233 0.076912
+-0.003553 -0.057174 0.014594 -0.044747 -0.000811
+-0.070712 0.032588 0.016264 0.000303 0.049043
+0.009463 0.074638 0.018082 0.009662 0.016092
+0.002476 0.044398 -0.087719 -0.019282 -0.061589
+0.060302 -0.067478 -0.040506 0.023576 0.052937
+-0.072603 -0.012619 0.001381 -0.072008 -0.029615
+0.037036 -0.024612 0.072062 -0.042065 0.019378
+-0.040438 -0.119783 -0.006434 -0.060809 0.085511
+-0.008272 0.020380 0.022744 0.066027 -0.063608
+0.000489 0.072277 0.001453 0.008278 0.040882
+0.032724 0.159938 -0.041156 0.022564 0.038648
+0.014324 -0.095703 -0.056763 -0.088713 0.020001
+-0.023825 0.027423 -0.018492 0.065606 0.000365
+0.039845 0.018820 -0.038350 -0.078718 -0.033629
+-0.001663 0.009565 0.108200 0.058847 0.065809
+-0.049633 -0.045554 0.020137 -0.086381 0.091892
+-0.002517 -0.024076 -0.000222 0.049573 -0.129418
+-0.045283 0.051515 -0.006173 0.029917 -0.010061
+0.006979 0.078079 0.067161 -0.006824 0.036737
+0.001946 0.029299 -0.146673 0.005204 -0.049944
+-0.003573 -0.022387 -0.192735 0.086714 0.000681
+0.023023 0.025278 0.032334 -0.092047 -0.097106
+0.009314 -0.026795 0.048717 -0.014619 0.009445
+-0.034367 0.013246 0.033975 0.027681 -0.048279
+-0.034841 -0.011498 0.129486 0.012413 -0.099857
+-0.009759 0.017468 0.030971 0.054610 0.058014
+-0.053387 0.017293 0.044926 0.081337 0.056077
+-0.014173 0.033715 -0.080168 -0.039195 0.057433
+-0.008063 -0.024017 -0.029873 0.059315 -0.016884
+0.037413 0.102710 0.039066 -0.000322 -0.007096
+0.001081 0.004899 0.064913 -0.009724 0.052938
+0.080878 -0.088833 0.017234 -0.064402 0.068572
+-0.037607 -0.071831 0.000857 0.017839 -0.001686
+0.014565 0.002904 0.000522 -0.003298 0.002213
+0.095679 0.012244 0.036755 -0.099818 0.011289
+-0.028433 0.070577 -0.043776 -0.022561 -0.076359
+-0.030471 -0.127211 -0.047570 0.077242 -0.002030
+0.022748 -0.045608 0.087172 -0.006712 -0.112507
+0.048520 -0.049787 0.033883 0.026952 0.022558
+0.062996 0.012765 0.026950 -0.066289 -0.068448
+0.054918 0.003780 0.040104 -0.005777 -0.085504
+0.064809 0.077196 0.014756 0.043405 0.023787
+0.031364 0.128719 -0.042317 -0.004864 0.087827
+-0.029815 -0.093621 -0.008519 -0.023955 0.051611
+-0.014788 -0.068189 0.037225 0.179376 -0.029766
+0.060538 0.006306 0.012777 0.019308 0.009494
+-0.008692 -0.017852 0.038436 0.046522 0.130088
+-0.012523 -0.023608 0.032478 -0.090472 0.044247
+-0.044404 -0.030180 -0.040445 0.035083 -0.032830
+-0.072877 0.049263 0.081485 -0.069301 0.014635
+-0.057655 0.197364 -0.000351 -0.022115 0.039887
+0.042215 -0.009109 -0.086347 -0.104682 -0.049640
+-0.047970 -0.025332 -0.040848 0.083051 -0.021243
+-0.028802 0.015424 0.001733 -0.128243 -0.060411
+0.055727 0.057515 0.146167 -0.056022 0.024345
+0.002416 -0.015298 0.002236 -0.020925 -0.036973
+-0.029182 -0.058852 0.072372 -0.069443 -0.038400
+-0.056167 0.006957 0.068247 0.059373 -0.048485
+0.034235 0.048623 -0.036035 0.085210 0.110573
+-0.015337 0.046972 -0.043542 0.006351 0.031155
+0.088626 0.069233 0.008134 0.019241 -0.060153
+0.041371 0.089979 -0.041853 0.023626 0.016064
+-0.053828 -0.049329 -0.016176 -0.013092 0.057257
+0.069686 -0.046114 -0.045261 -0.039290 0.020585
+0.061314 -0.027727 -0.001927 0.022808 -0.015832
+-0.075912 -0.014836 0.002965 0.081369 -0.022597
+0.005534 0.065315 0.044334 -0.043319 -0.041186
+-0.013693 0.026330 -0.020694 0.032579 -0.067664
+-0.035584 -0.076274 -0.115553 0.029283 0.115779
+0.013526 -0.034741 0.010015 -0.130855 -0.047597
+0.080984 0.031915 0.048376 -0.028547 -0.023234
+-0.052917 -0.103074 0.071678 -0.043019 -0.020299
+-0.045608 0.007487 -0.028223 0.036499 -0.089053
+-0.034453 0.074651 -0.025209 0.077487 -0.013263
+0.004921 0.072189 -0.050852 0.059399 0.035439
+0.002935 -0.054894 -0.031357 -0.070326 -0.036947
+-0.026730 0.036590 -0.025250 0.113258 0.121094
+0.080910 0.042350 -0.092512 -0.043499 -0.025455
+0.034745 -0.070282 0.032647 0.111722 -0.019157
+0.020761 0.013997 -0.061982 -0.060954 0.055112
+0.036288 -0.080176 -0.027267 0.012212 -0.093795
+-0.041882 0.097155 0.087384 -0.031435 -0.082801
+0.009464 0.032459 0.077828 -0.112376 0.108840
+0.019555 0.014775 -0.073011 -0.043973 0.011444
+-0.048044 0.056260 -0.038387 0.043656 0.008263
+-0.014005 -0.016142 -0.038569 -0.064552 -0.057510
+-0.078202 -0.059032 0.084016 -0.010298 0.012574
+-0.020059 -0.064059 -0.059392 -0.046799 -0.054238
+0.022026 -0.006059 0.084724 0.041685 -0.029012
+0.026514 0.032033 0.022922 0.031857 0.030105
+-0.035650 0.031377 -0.030435 0.061662 0.079732
+-0.025495 0.041751 -0.112711 -0.015737 0.015504
+0.121804 -0.030913 -0.016931 0.056284 -0.031211
+-0.038259 -0.005525 0.074063 -0.019980 -0.074225
+-0.043126 -0.008346 0.052048 -0.010386 0.102477
+0.020457 -0.053151 0.037134 -0.048166 0.025535
+-0.004324 -0.102005 0.042549 0.062684 -0.011027
+-0.041502 -0.022180 -0.001040 0.012690 0.058495
+0.039481 0.061425 0.036436 -0.094401 0.024691
+-0.002509 -0.024231 -0.105831 0.050352 -0.105564
+0.036061 -0.093016 -0.042697 0.049621 -0.014022
+0.037095 0.014433 0.054764 -0.096569 -0.011104
+0.004844 0.011453 0.022667 -0.022798 0.002655
+0.021742 -0.079613 0.045351 -0.079863 0.014770
+0.050245 -0.026754 -0.023870 0.015727 -0.098730
+0.042398 0.154448 -0.009362 0.081429 -0.020656
+-0.072560 0.133852 0.025744 -0.109001 0.075747
+-0.059454 -0.002469 -0.103847 -0.008798 0.031741
+-0.020032 -0.011426 -0.002985 0.061967 -0.058554
+0.096033 0.053995 -0.071745 0.012181 0.016611
+-0.051161 -0.042525 0.015651 0.078963 0.054139
+-0.007119 0.014112 0.000797 -0.147306 0.012158
+-0.048199 -0.042152 -0.060602 0.035608 -0.095526
+-0.044437 0.079277 -0.036361 -0.085666 0.005652
+-0.035263 0.081781 0.098388 -0.015160 0.032423
+0.048597 -0.010937 -0.045141 -0.016016 -0.045851
+0.017285 0.029554 -0.068669 0.090490 -0.069378
+-0.015215 0.065693 -0.080376 -0.098850 -0.001785
+-0.000808 0.001812 0.047789 -0.059522 0.029808
+-0.040358 -0.013967 -0.035444 -0.057752 0.011251
+0.027783 -0.009928 0.081566 -0.060520 -0.032563
+-0.018103 0.008202 0.020263 0.036779 0.028019
+0.034566 0.020755 0.010139 0.022813 0.071878
+-0.033001 0.012734 -0.101437 -0.069713 0.016386
+0.040255 0.034849 0.017738 0.082952 0.030522
+0.011027 0.101822 0.000381 -0.044621 -0.048575
+-0.018043 -0.104642 0.042318 0.024433 0.071077
+0.028556 0.050381 -0.035783 -0.004765 0.019134
+0.004109 -0.114088 -0.030007 -0.003475 -0.033302
+-0.132027 -0.012463 -0.036186 0.000562 -0.054043
+-0.003544 0.052264 0.043304 0.012117 0.016872
+-0.034524 0.066372 -0.065579 -0.033370 0.014889
+0.004579 -0.049747 -0.050504 0.049331 0.040066
+-0.125392 -0.097291 0.050421 -0.071309 -0.051625
+0.065285 0.022484 0.062435 0.017569 -0.040502
+-0.004470 -0.054208 0.010625 -0.094016 0.022508
+0.033725 0.032426 -0.015455 0.036159 -0.115369
+-0.103817 0.142767 -0.000238 -0.019162 0.008959
+0.030765 0.075502 -0.088049 0.017398 0.024749
+-0.021910 -0.075993 -0.149318 -0.174722 0.102620
+0.008195 -0.009007 0.007189 0.076657 0.014460
+0.034428 0.027255 -0.013869 -0.050491 -0.048691
+0.037759 -0.098562 0.085631 0.021691 -0.000794
+-0.029941 0.026585 -0.033603 -0.014074 0.066789
+0.005141 -0.012246 -0.067551 0.100708 -0.040232
+-0.002751 0.049901 0.016959 0.021812 -0.059523
+-0.022331 0.030079 0.058567 -0.029002 0.104237
+-0.013602 -0.035019 -0.155316 0.016558 -0.013881
+0.004136 -0.001657 -0.097220 0.019060 0.052990
+0.004200 0.054365 -0.016768 -0.045191 -0.105984
+-0.052803 -0.016935 0.092437 -0.013893 -0.033606
+-0.023246 -0.039305 0.036068 -0.020164 -0.060244
+0.045916 -0.014132 0.044463 0.046890 -0.118975
+0.074037 0.010976 0.090692 0.090068 0.023711
+-0.044310 0.007556 -0.037900 0.026798 0.084256
+0.002559 0.013715 0.004015 0.008334 0.101711
+0.022258 0.030790 -0.065656 0.019198 -0.035505
+0.026328 0.028683 0.115303 -0.028803 -0.086521
+-0.004355 -0.046031 0.011248 -0.040795 0.121216
+0.000425 -0.056590 0.011373 -0.070856 0.064965
+-0.043302 -0.095015 0.013747 0.048043 0.047157
+-0.046839 -0.005878 -0.013815 0.028948 -0.001373
+0.115513 0.049750 0.038856 0.002747 0.068706
+-0.059471 0.083940 -0.035785 0.026815 -0.027017
+0.004618 -0.093707 -0.031970 0.104710 -0.008533
+-0.008056 -0.017611 0.038062 -0.073507 -0.036477
+0.022407 -0.059049 0.022840 0.012451 -0.010174
+0.057217 -0.050858 -0.053612 -0.064090 -0.097360
+0.041668 -0.011445 -0.075167 0.006584 -0.122856
+-0.011272 0.137465 -0.067901 0.011357 -0.050853
+0.020753 0.070596 0.004302 -0.066991 0.055696
+-0.043828 -0.042721 -0.096928 -0.047589 0.046254
+-0.027538 -0.005234 0.030541 0.077571 -0.039512
+0.032372 -0.022397 0.002903 0.014010 0.028365
+0.007460 0.011506 0.019889 0.062747 0.095319
+0.052300 0.007374 0.036028 -0.116833 0.049517
+0.004313 -0.039924 -0.005692 0.035446 -0.006279
+-0.092093 0.025645 0.053023 -0.015761 -0.045887
+-0.018082 0.081602 0.046870 0.015485 0.067284
+0.055890 0.008159 -0.036149 -0.067704 -0.096800
+0.015948 -0.036949 -0.083131 0.080618 0.031677
+0.025776 0.047673 -0.012634 -0.098220 0.039341
+0.018630 0.024685 0.068760 -0.009148 -0.006932
+0.000131 -0.009954 -0.075954 -0.020703 0.000996
+-0.040731 -0.082876 0.075619 0.017000 -0.130026
+0.003839 0.083757 0.085935 0.058477 -0.018794
+0.019268 0.053820 -0.025907 -0.016484 0.048963
+0.017315 0.011801 -0.016617 -0.016373 0.052079
+0.016567 0.064592 -0.011714 0.047244 -0.029583
+-0.010269 0.112646 -0.025079 -0.018015 -0.021550
+-0.019521 -0.111462 -0.047937 -0.002779 0.083724
+0.004416 0.004607 -0.006974 -0.101561 0.027376
+0.083440 -0.109869 -0.002361 -0.011364 -0.079707
+-0.138325 -0.095825 0.034339 0.024551 -0.012431
+-0.000401 0.007608 0.013950 -0.060441 0.010061
+0.012546 -0.000065 -0.023529 0.015494 -0.012896
+-0.014981 -0.019040 -0.043634 0.076437 0.059672
+0.014985 -0.037394 0.020033 -0.082023 -0.016717
+0.029711 -0.006237 0.055347 0.024365 0.002094
+0.019464 -0.038260 0.127306 -0.051862 0.049168
+-0.074259 -0.022269 0.023182 0.071183 -0.065354
+-0.055933 0.064170 -0.055712 0.107983 0.054978
+0.015294 0.093224 -0.052328 0.000761 -0.020823
+0.023903 -0.063241 -0.093322 -0.054658 -0.006845
+0.048141 -0.023201 -0.047564 0.106605 0.000059
+0.146340 0.030121 -0.040556 -0.020381 -0.050294
+0.016659 -0.021563 0.027855 0.069633 -0.009148
+0.027112 0.056646 -0.023372 -0.211107 0.014012
+-0.019924 -0.122201 -0.040118 0.003571 -0.146470
+0.017162 0.075261 0.002383 -0.006374 -0.081174
+0.043906 -0.005278 -0.027448 -0.046459 0.140484
+0.008671 0.019853 -0.128017 -0.022950 0.048609
+-0.019167 -0.010958 -0.061823 0.072910 0.001440
+-0.023976 -0.030275 0.027463 -0.138470 -0.139145
+-0.028088 -0.013451 0.113264 0.081011 -0.012685
+0.006025 -0.055737 0.022779 -0.019951 -0.046793
+-0.015091 -0.017958 0.063092 0.032101 -0.004007
+0.052309 0.070815 0.012148 0.095984 0.074330
+0.006032 0.083156 -0.045278 0.013825 0.066658
+-0.000966 0.053253 -0.095660 -0.022943 0.108130
+0.092983 -0.012055 0.008111 0.064988 0.010427
+0.042345 0.042586 0.077502 0.053009 -0.031546
+-0.004484 -0.019859 0.027061 0.016614 0.085821
+0.089250 0.014975 -0.022722 -0.045228 0.047095
+-0.028190 -0.124509 -0.029014 0.024231 -0.016564
+-0.025209 -0.031288 -0.023742 0.040341 0.030385
+-0.022564 0.023760 0.018611 -0.077310 0.051696
+0.028200 0.005454 -0.045487 0.027221 -0.074627
+-0.040934 -0.110565 -0.103536 0.033125 0.041451
+-0.017540 0.013737 0.131164 -0.103202 -0.000294
+0.030605 -0.030002 0.058861 0.024425 0.055122
+0.021447 -0.043394 0.039465 -0.020523 -0.012530
+-0.003317 -0.002650 -0.020200 -0.002414 -0.060515
+0.003135 0.115504 0.005075 0.072669 0.057819
+-0.075310 0.064527 0.025999 -0.067556 0.046351
+-0.124098 -0.049305 -0.009230 -0.084801 0.068375
+-0.026781 -0.066657 0.010588 0.093986 0.017406
+0.047141 0.053480 -0.019255 0.069267 0.010659
+-0.068511 0.015815 -0.011687 0.047685 0.033658
+0.064260 0.062994 0.018822 -0.143452 0.092703
+-0.029884 -0.006035 -0.016152 -0.021618 -0.045339
+-0.049252 0.041988 -0.021510 -0.039175 -0.031350
+-0.101541 0.005832 0.055761 0.009961 0.086386
+0.007597 -0.052775 -0.079976 0.023111 0.004302
+-0.020123 0.039264 -0.062497 0.078009 0.004409
+-0.063787 0.038329 -0.055050 -0.086972 -0.084417
+0.025733 -0.011156 0.104895 0.026765 0.037827
+-0.013149 0.009709 0.004095 -0.039085 0.041414
+-0.018153 -0.088525 0.078011 -0.022509 -0.080366
+-0.047630 0.036346 0.013702 0.071239 0.024081
+0.114305 -0.072565 0.004642 0.035947 0.040623
+-0.017954 0.045965 -0.007375 -0.030016 -0.004483
+0.040170 0.083716 0.012267 0.096863 -0.028263
+0.000694 0.069353 0.024960 -0.069792 -0.070096
+-0.028321 -0.072324 0.018256 0.000091 0.049255
+0.038695 0.041521 -0.035000 -0.034223 0.090426
+-0.004319 -0.060041 0.030034 -0.014687 0.016165
+-0.139996 0.013811 0.037782 -0.083214 0.054142
+0.024863 0.017964 0.045207 0.006294 0.058657
+-0.071515 0.093447 -0.050680 -0.014853 -0.071657
+0.007823 -0.010828 -0.096918 0.050508 0.136819
+-0.042282 -0.060920 -0.006691 -0.054808 -0.055435
+0.076309 -0.048186 0.105925 -0.031527 -0.030737
+-0.043870 -0.102846 0.054550 -0.095983 0.065369
+-0.027944 0.014204 0.008256 0.035180 -0.105002
+-0.011778 0.036941 -0.007284 0.034566 0.002672
+-0.011867 0.094032 -0.081505 -0.042171 -0.012357
+0.025234 -0.142099 -0.011399 -0.092199 0.016061
+-0.007420 0.024527 0.010787 0.089568 0.009287
+0.040383 0.043550 0.036649 -0.055816 -0.039815
+0.029883 -0.031089 0.087022 0.064863 0.035410
+-0.010187 0.023054 -0.018519 -0.057105 0.026218
+-0.007645 -0.026641 -0.033134 0.044367 -0.059939
+-0.047569 0.091489 0.022502 0.013205 -0.056318
+0.041414 0.022193 0.081274 -0.006608 0.035220
+-0.012493 0.024440 -0.105974 -0.058317 -0.038994
+0.042143 0.057826 -0.117349 0.047843 0.089338
+0.065029 0.029927 -0.014494 -0.010548 -0.129518
+-0.033996 -0.030825 0.032254 -0.021848 -0.021345
+-0.065200 0.012770 0.020636 -0.034493 -0.080268
+-0.015033 -0.018599 0.076611 0.034283 -0.084435
+0.051904 0.063942 0.046362 0.039561 0.096234
+-0.030658 0.054240 0.027612 0.022042 0.112035
+-0.045512 -0.048431 -0.084263 -0.015994 0.103483
+0.045903 -0.004115 -0.021572 0.057589 0.016494
+0.013949 0.101635 0.127534 0.014985 -0.006815
+-0.053449 -0.000707 0.052773 -0.047290 0.071075
+0.041771 -0.079418 -0.026505 -0.082019 0.091756
+-0.088458 -0.055800 0.015266 0.048373 -0.028842
+0.004456 0.001112 0.005363 0.012172 -0.036807
+0.063688 0.114491 -0.034186 -0.082173 0.044547
+0.010385 0.061010 -0.075589 0.038888 -0.057732
+-0.068354 -0.091781 -0.001533 0.042343 0.007713
+-0.003066 -0.016490 0.097581 -0.008705 -0.169889
+0.041901 -0.029045 0.088606 0.028236 -0.005092
+0.087986 -0.005514 -0.001520 -0.067407 -0.036923
+0.018378 -0.001874 0.029761 -0.028224 -0.114769
+0.024657 0.082316 0.020235 0.034884 -0.039374
+0.106617 0.085265 -0.014306 -0.039880 0.059967
+-0.020866 -0.045287 -0.013407 -0.029010 0.025480
+0.020099 -0.053760 0.035241 0.067883 -0.069313
+0.022318 0.001659 -0.045385 -0.001930 0.007348
+0.027072 -0.051692 0.069337 0.012098 0.107819
+-0.026942 -0.039741 0.043295 -0.135918 0.031043
+-0.040145 -0.021705 -0.052514 0.001132 -0.030098
+-0.040748 0.046793 0.149894 -0.021036 -0.023530
+-0.040778 0.085491 0.068161 0.033268 0.032992
+-0.008355 0.008600 -0.125074 -0.034204 -0.082832
+0.030318 0.000442 -0.007943 0.113836 -0.044022
+0.015079 0.065357 -0.018956 -0.092656 -0.056274
+-0.017481 -0.004857 0.117201 -0.005233 0.069151
+0.011030 -0.024316 -0.015695 -0.011308 -0.005062
+-0.010876 -0.038919 0.032578 -0.054136 -0.121302
+-0.046807 0.041175 0.059588 0.031040 -0.027127
+0.021551 0.000830 -0.013766 0.046306 0.081467
+0.014301 -0.010731 -0.051227 -0.018797 0.043587
+0.050317 0.086115 -0.027629 0.046202 -0.084445
+0.021044 0.041527 0.005458 0.006677 0.002404
+-0.037453 -0.035957 -0.039078 -0.063247 0.088516
+0.079477 0.004030 -0.063421 -0.074051 -0.039753
+0.062917 -0.119760 -0.002471 0.000423 0.007336
+-0.124273 0.001094 -0.026391 0.070714 -0.035166
+0.037072 0.018118 0.017500 -0.050692 -0.015928
+-0.003390 -0.002367 -0.040046 0.013349 -0.041478
+-0.034407 -0.009890 -0.095593 0.109253 0.041509
+-0.062990 -0.041682 0.001528 -0.124601 -0.030128
+0.086076 0.003516 0.073015 0.024339 -0.069858
+-0.022435 -0.042554 0.107497 -0.132302 0.035124
+-0.105430 0.042327 -0.064964 0.057304 -0.092634
+-0.058398 0.052083 0.018947 0.087990 -0.026444
+0.023373 0.037085 -0.083589 0.015247 0.016566
+-0.026782 -0.070361 -0.019757 -0.109826 -0.040199
+-0.009688 -0.005408 -0.003769 0.111444 0.029897
+0.070686 0.021466 -0.052076 0.015609 -0.023854
+0.008088 -0.022084 0.052542 0.122824 -0.018174
+-0.009808 0.107602 -0.059166 -0.100824 0.082456
+-0.004737 -0.023536 -0.095212 -0.007114 -0.098814
+-0.061778 0.049247 0.025130 0.010909 -0.091691
+0.034764 -0.014047 0.002819 -0.050330 0.085399
+0.057257 -0.052435 -0.067151 -0.012311 0.040602
+-0.118166 0.053141 -0.119211 0.024274 0.027075
+-0.022345 -0.060443 -0.046916 -0.099227 -0.115958
+-0.071020 0.015499 0.055810 -0.012697 0.010803
+-0.051685 -0.097540 0.013970 -0.096689 -0.060525
+0.010422 0.018434 0.151855 0.015230 -0.080804
+0.040130 0.043946 0.022887 0.043819 -0.027371
+0.037213 0.059423 -0.040656 0.141843 0.065180
+-0.083238 0.057208 -0.113200 -0.056009 0.030056
+0.060522 -0.054570 0.006137 0.062833 -0.081547
+0.002753 0.037357 0.055441 0.049180 -0.017699
+-0.006225 0.029216 0.040657 0.016328 0.041969
+0.058998 -0.067000 0.002571 -0.008178 0.027776
+-0.026103 -0.049399 0.093279 0.052313 -0.029958
+-0.070689 -0.054589 0.027325 -0.010464 -0.000604
+0.009479 0.125126 0.086072 -0.052874 0.065774
+0.003009 0.013855 -0.088166 0.018907 -0.064212
+0.023827 -0.024022 -0.121652 0.032035 0.015278
+0.023427 -0.027194 0.066092 -0.100117 -0.048548
+0.013755 0.005344 0.038451 -0.000513 0.018468
+0.065931 -0.062001 0.035615 -0.067561 -0.013315
+0.045441 -0.016064 0.010535 0.035953 -0.068093
+0.035872 0.097935 -0.025516 0.061435 0.028137
+-0.042656 0.110708 -0.022981 -0.052860 -0.009583
+-0.084678 -0.040172 -0.092364 0.061778 0.003794
+-0.002964 -0.047375 -0.029968 0.090529 -0.045382
+0.103144 0.034998 -0.012760 0.013885 0.048887
+-0.049886 -0.034647 0.061193 0.058574 0.084107
+-0.022304 -0.008817 0.036857 -0.119972 0.000619
+-0.079467 -0.031710 -0.108927 -0.033843 -0.034845
+-0.125290 0.079806 -0.011673 -0.070719 -0.063897
+-0.051524 0.042071 0.082303 -0.016684 0.053366
+0.024657 -0.062913 -0.040533 -0.032117 -0.013188
+0.036519 0.055734 -0.134481 0.055949 -0.050480
+0.002035 0.010998 -0.064264 -0.078569 -0.026404
+-0.017580 0.005453 0.068795 -0.031274 0.024178
+-0.038245 -0.037973 -0.013256 -0.072256 0.057358
+-0.004941 -0.047850 0.119977 -0.015040 -0.079231
+-0.013449 -0.005542 0.028890 0.032536 -0.020619
+0.083769 -0.028624 0.049040 0.021538 0.104107
+-0.072475 0.019284 -0.044425 -0.058775 0.061172
+0.025682 0.004208 0.041846 0.095369 0.007892
+0.030701 0.062103 -0.086288 -0.068866 -0.110743
+0.052685 -0.069032 0.010339 0.044804 0.106157
+0.105575 0.017263 -0.110890 -0.040735 0.061412
+0.021037 -0.102095 0.039008 0.010335 0.005686
+-0.108307 0.057569 -0.004539 -0.019864 0.033710
+-0.031254 0.013482 0.035051 0.014893 -0.001676
+-0.053780 0.014329 -0.037130 0.010087 -0.043959
+0.031302 -0.006715 -0.065618 0.066261 0.071102
+-0.085133 -0.020753 0.050721 -0.042021 0.006613
+0.038123 0.041345 0.095993 -0.028353 -0.008509
+-0.039544 -0.069281 0.047585 -0.020085 0.000819
+0.000478 0.017818 0.008015 0.068812 -0.184380
+-0.073606 0.120550 -0.032173 0.058092 0.024132
+-0.016705 0.130871 -0.094852 0.044256 0.003919
+-0.002119 -0.026963 -0.003553 -0.110166 0.083113
+-0.008545 -0.026785 0.025936 0.069075 0.054271
+0.029418 0.039817 0.040088 -0.036680 -0.073300
+-0.003368 -0.074471 0.111772 0.030913 -0.018960
+-0.040689 0.058799 -0.017810 -0.064269 0.071408
+-0.022927 -0.077256 -0.075665 0.100717 -0.099471
+0.004792 0.063353 -0.017202 -0.012465 -0.052031
+0.015659 0.049801 0.020300 0.001231 0.061694
+-0.002196 -0.039936 -0.095913 -0.006760 -0.036261
+-0.004827 -0.023039 -0.062452 0.023724 0.043337
+0.002849 -0.004311 -0.067199 -0.039365 -0.082845
+-0.036454 -0.014788 0.059651 -0.039192 -0.021445
+-0.003667 -0.011645 0.021036 -0.006220 -0.025338
+0.010705 -0.002077 0.043196 0.035112 -0.036895
+0.017671 0.003759 0.106991 0.040822 0.011089
+-0.048837 0.025240 -0.002343 0.015983 0.080230
+-0.005045 -0.000454 -0.055852 -0.004494 0.084580
+0.044207 -0.018164 -0.035672 0.024802 -0.028216
+0.026617 0.021648 0.082157 0.012675 -0.049856
+0.001020 -0.118363 0.069854 -0.038161 0.096174
+0.032049 -0.035139 -0.015943 -0.028306 0.055425
+-0.092742 -0.074326 0.010130 -0.020646 0.043131
+-0.014246 -0.037891 0.006922 0.059464 -0.023168
+0.059938 0.021652 -0.004602 -0.005103 0.062343
+0.000410 0.032704 -0.087978 0.042098 -0.008283
+0.000714 -0.078595 0.004443 0.036763 0.004995
+-0.050964 0.045909 0.038942 -0.052841 -0.054318
+0.033939 -0.020268 0.019574 0.029805 -0.002001
+0.068470 -0.056316 0.007236 -0.031313 -0.066063
+-0.003425 0.022247 -0.018479 -0.008040 -0.105011
+-0.109717 0.132884 0.056892 0.052155 -0.073444
+0.051067 0.107179 0.014594 -0.036657 0.110846
+-0.009896 -0.042527 -0.082220 -0.007607 0.057007
+-0.034754 0.003213 0.041643 0.142016 -0.007658
+0.012781 0.014366 -0.021935 0.010511 0.028021
+0.002082 -0.027023 0.055247 0.097082 0.111840
+0.040151 -0.019830 -0.007033 -0.097207 0.026595
+-0.069875 -0.070451 -0.049743 0.053253 -0.019762
+-0.078475 0.043019 0.022103 -0.033625 -0.008627
+0.058858 0.080427 0.060029 0.002771 0.041250
+0.030257 -0.044059 -0.001226 -0.060544 -0.126844
+-0.029407 -0.021079 -0.108126 0.070012 -0.006653
+0.013084 0.090992 -0.002726 -0.070041 -0.006757
+-0.017571 0.027459 0.103937 0.003012 0.038213
+-0.007808 -0.011937 -0.015457 -0.033181 0.012816
+0.010199 -0.056227 0.006057 -0.017569 -0.098687
+0.006000 0.076819 0.022272 0.082508 -0.058508
+0.031808 0.054009 0.007871 0.055301 0.070296
+0.023941 0.025656 -0.005875 -0.068203 0.027482
+0.036615 0.026218 -0.011406 0.026235 -0.022002
+-0.011161 0.120568 0.023165 -0.010473 0.002080
+-0.033028 -0.043255 -0.030454 0.009261 0.113350
+0.023271 -0.015934 -0.037492 -0.032890 0.016928
+0.020967 -0.090717 -0.016510 0.070725 -0.063975
+-0.097203 0.017597 0.016946 0.027298 -0.016049
+-0.019287 -0.005319 0.019000 -0.037327 -0.040993
+-0.003975 0.027897 -0.095076 -0.010053 -0.014610
+0.005584 -0.024009 0.000599 0.082121 0.098790
+0.005987 -0.036027 -0.067221 -0.128015 -0.052111
+0.056606 -0.020029 0.012172 -0.018025 -0.028588
+-0.015169 -0.087101 0.044526 -0.022464 0.054835
+-0.084369 -0.058286 -0.039363 -0.003339 -0.116729
+-0.051506 0.079944 -0.023815 0.113004 -0.052120
+-0.012383 0.075636 -0.024387 -0.039200 0.032050
+-0.031568 -0.140199 -0.082589 -0.060485 -0.013115
+0.092001 -0.002684 -0.027087 0.111635 0.050016
+0.077055 -0.010441 -0.006942 -0.026898 -0.083879
+-0.008401 -0.026725 0.049993 0.043707 0.027966
+-0.019866 -0.057701 -0.086619 -0.114361 -0.008921
+-0.039708 -0.122519 -0.074209 0.014381 -0.065102
+-0.023419 0.118673 -0.000005 0.071661 -0.127659
+-0.009184 0.020308 0.019151 -0.054484 0.096378
+0.016102 -0.060605 -0.128655 -0.004225 0.079251
+-0.021895 0.024065 -0.097479 0.045279 -0.036151
+-0.045806 0.005106 0.000093 -0.074415 -0.071654
+-0.067599 -0.017537 0.050178 0.015860 -0.018919
+-0.015382 -0.057989 0.032437 -0.039627 -0.030285
+0.015438 -0.005533 0.110416 -0.004137 -0.030336
+0.085365 0.089779 0.061676 0.017178 -0.016279
+0.028526 0.055656 0.008566 0.000706 0.124966
+-0.018124 0.040023 -0.067773 0.028532 0.098381
+0.062832 -0.038523 0.003865 0.065698 -0.026661
+0.076081 0.062167 0.112325 0.052139 -0.040826
+0.003747 -0.052113 0.013442 0.002756 0.102858
+0.040603 -0.012693 0.031245 -0.046645 -0.003625
+-0.024647 -0.062463 0.000476 0.024807 -0.036286
+-0.003083 -0.015952 -0.016156 0.002976 0.016598
+-0.015092 0.058522 0.011542 -0.046504 0.009174
+0.097896 0.056220 -0.055387 0.022356 -0.126788
+0.024795 -0.092333 -0.084406 -0.010051 0.060835
+0.013338 -0.010735 0.052739 -0.119952 -0.093185
+0.010522 -0.001505 0.056134 0.038675 0.016542
+0.005217 -0.061424 0.071990 -0.028908 0.011826
+-0.009221 -0.010760 0.023849 0.034664 -0.066108
+0.018587 0.070818 0.013554 0.106469 0.035530
+-0.060716 0.072344 0.010625 -0.017888 0.006548
+-0.122347 -0.080419 -0.039979 -0.045658 -0.046576
+-0.040526 -0.039641 -0.048709 0.067016 0.023042
+0.064800 0.099396 -0.064314 0.005665 -0.025960
+-0.094387 -0.056820 0.015466 0.086382 0.024902
+-0.019486 0.021888 0.000550 -0.168957 0.071388
+-0.019935 -0.042118 -0.040820 -0.012013 -0.072063
+-0.004249 0.039160 0.010084 -0.080610 -0.043915
+-0.101425 0.074442 0.035350 0.051348 0.051160
+-0.031631 -0.053381 -0.062261 -0.020441 -0.031251
+0.050923 0.000358 -0.074646 0.076663 -0.042498
+-0.033718 0.037025 -0.017087 -0.091951 0.017983
+0.015622 0.007807 0.087203 -0.061047 0.077306
+-0.049822 0.015499 0.035918 -0.044388 0.034786
+-0.003435 -0.072680 0.042506 -0.004200 -0.024834
+-0.034415 0.065814 0.079911 0.117115 0.013096
+0.065811 0.001560 0.054427 0.085716 0.083343
+-0.034994 0.035815 -0.034661 -0.032421 0.000133
+0.021908 0.041958 -0.008418 0.091804 -0.023169
+0.019306 0.087287 0.064984 -0.052908 -0.010301
+-0.022717 -0.062698 0.029605 0.020970 0.011270
+0.049229 -0.033794 -0.040198 -0.068419 0.063147
+-0.023097 -0.079045 -0.010748 -0.064320 -0.011785
+-0.108984 0.015970 -0.038308 0.017991 0.062400
+-0.000719 0.044392 0.034008 -0.020969 0.006446
+-0.044457 0.044495 -0.084323 -0.014046 -0.057116
+0.037862 -0.024751 -0.045926 0.007665 0.082611
+-0.081497 -0.013395 -0.026864 -0.040485 -0.031100
+0.095144 0.005947 0.063254 0.009423 0.031198
+0.008443 -0.078212 -0.002275 -0.025354 0.048808
+0.003982 0.011608 -0.005923 0.061556 -0.091653
+-0.028425 0.056332 0.005018 0.007136 0.010607
+0.039647 0.145962 0.007951 -0.017526 -0.039745
+0.023022 -0.066844 -0.047384 -0.044307 0.041848
+-0.056589 0.034263 -0.033277 0.073824 -0.030747
+0.009451 0.005157 -0.048186 -0.045749 -0.054258
+-0.003301 0.004995 0.071505 0.029585 0.050033
+-0.064837 0.012928 0.002785 -0.117405 0.045317
+-0.026899 -0.051475 -0.054625 0.064955 -0.136139
+-0.083576 0.066985 0.000964 0.024630 -0.036989
+0.049229 0.047537 0.090953 0.036197 0.054765
+0.062892 0.045061 -0.097460 0.009938 -0.027736
+-0.008479 0.053538 -0.125219 0.036747 0.027556
+-0.017214 0.036754 0.009736 -0.087187 -0.089725
+-0.002417 -0.039070 0.076625 0.018126 0.032402
+-0.035537 -0.003939 -0.001806 0.018436 -0.060172
+-0.024517 0.048085 0.052646 0.044561 -0.126681
+-0.005381 0.059991 0.064924 0.047878 0.043526
+-0.079817 0.034296 -0.009242 0.037169 0.115281
+-0.015147 -0.019430 -0.077776 -0.033431 0.076276
+0.023914 0.014924 -0.049231 0.048491 -0.012740
+0.023873 0.121027 0.067832 -0.009223 -0.039188
+-0.018355 -0.042663 0.070587 -0.003855 0.077791
+0.036307 -0.069362 -0.035976 -0.011638 0.103907
+-0.055984 -0.110967 -0.002537 -0.016356 -0.022701
+-0.018211 0.017831 -0.009534 0.011128 -0.026445
+0.071893 0.028948 0.017993 -0.055001 0.032913
+0.013143 0.141940 -0.030668 -0.010630 -0.075402
+-0.008241 -0.097950 -0.070541 0.086461 0.063873
+0.010107 -0.006389 0.086778 -0.017779 -0.056644
+0.040699 -0.054122 0.073702 -0.008815 0.011806
+0.020978 -0.004901 0.046808 -0.038708 -0.048713
+0.065026 -0.042069 0.030306 -0.003984 -0.125105
+0.020044 0.154911 0.060110 0.041504 0.013796
+0.003360 0.144327 -0.056583 -0.031643 0.021938
+-0.082644 -0.117123 -0.032869 -0.004149 0.019806
+0.007405 -0.051019 -0.020896 0.133232 -0.028058
+0.050897 0.015399 -0.022377 0.012018 0.002474
+-0.031801 -0.041942 0.020380 0.018326 0.106183
+0.038954 -0.045696 0.017961 -0.080241 0.038198
+-0.031449 -0.026191 -0.079952 0.035385 -0.053671
+-0.055347 0.103293 0.049459 -0.008219 0.010257
+-0.061794 0.124358 0.049411 0.069306 0.034282
+-0.013114 -0.040074 -0.071968 -0.195520 -0.088871
+-0.030547 -0.024227 -0.047665 0.132613 0.012253
+0.036726 0.018979 -0.021295 -0.120084 -0.050532
+-0.020265 0.013963 0.136035 -0.067105 0.051832
+0.013865 -0.036402 0.005526 -0.042230 -0.022246
+-0.030844 -0.014871 0.097708 -0.055950 -0.060091
+-0.107193 -0.000749 0.094279 0.066459 0.015231
+0.068358 0.042724 -0.020943 0.012438 0.110596
+-0.022189 0.026125 -0.011649 0.004604 0.037204
+0.039096 0.065797 0.045162 -0.003834 -0.056679
+0.017104 0.070007 -0.005419 -0.016435 -0.000214
+-0.097253 -0.033412 -0.004272 0.021730 0.092887
+0.039513 -0.027819 -0.045420 -0.062670 -0.013033
+0.033957 -0.040429 -0.018152 0.020048 0.015966
+-0.083740 0.050010 0.032999 0.053057 -0.072973
+0.000797 0.028222 0.063769 -0.045254 -0.001401
+-0.008530 0.000350 -0.050423 0.016321 -0.077400
+-0.017818 -0.062015 -0.039769 0.103694 0.123584
+0.004844 -0.068111 -0.008528 -0.128884 -0.003312
+0.098749 0.025292 0.013547 0.007157 -0.032589
+-0.024049 -0.074941 0.062923 -0.112079 -0.008534
+-0.046211 0.028223 -0.041903 -0.001378 -0.077507
+-0.015178 0.093495 -0.033668 0.043904 -0.026096
+0.008741 0.024695 -0.042365 0.063246 0.013544
+-0.021438 -0.018498 -0.060824 -0.093599 -0.003304
+0.013206 0.019776 0.011491 0.115257 0.066627
+0.042660 0.045968 -0.044189 -0.056683 0.002399
+0.025400 -0.031109 0.037612 0.112170 0.041814
+0.005019 -0.013887 -0.051704 -0.065646 0.030095
+-0.006617 -0.067206 -0.053773 0.020368 -0.060694
+-0.042554 0.031959 0.034480 -0.016413 -0.056939
+0.026266 0.003617 0.032682 -0.066017 0.064464
+0.025224 -0.014523 -0.107735 -0.028243 0.015327
+-0.027555 0.013037 -0.049117 0.015929 -0.001301
+-0.010874 -0.018588 -0.021124 -0.055630 -0.102228
+-0.048525 -0.057257 0.083344 0.005472 0.060981
+-0.022083 -0.107351 -0.002309 -0.015487 -0.065168
+0.011812 -0.029764 0.117191 0.062742 -0.062476
+0.020253 0.014273 0.020564 0.047570 -0.021837
+0.006995 0.009213 -0.047359 0.072944 0.095512
+0.010178 0.039050 -0.077791 -0.020722 0.021947
+0.090992 -0.061050 -0.090772 0.081786 -0.045653
+-0.012634 0.036482 0.058533 -0.002696 -0.033458
+-0.040412 0.012196 0.010799 -0.011791 0.110559
+0.009821 -0.036074 0.066220 -0.015518 0.056690
+-0.027127 -0.071116 0.031944 0.079010 -0.022395
+-0.039431 -0.000384 -0.014285 0.016850 0.033711
+0.008705 0.100114 0.041438 -0.100989 0.011356
+-0.046625 -0.040932 -0.139483 0.054309 -0.063813
+-0.012343 -0.055168 -0.096047 0.031057 -0.034404
+0.061917 0.022545 0.077964 -0.061018 -0.028539
+-0.002541 -0.030177 0.006468 -0.005315 0.042803
+0.027882 -0.101187 0.073519 -0.048492 -0.034044
+0.063858 -0.051841 -0.034119 0.025079 -0.055338
+0.022337 0.072417 -0.039178 0.093515 0.010215
+-0.063332 0.136724 -0.034306 -0.068709 0.036614
+-0.060321 0.003109 -0.064068 -0.001911 0.026497
+-0.043444 0.005220 -0.028260 0.089346 -0.073713
+0.082013 0.000948 -0.079297 0.077331 0.007199
+0.013959 -0.089135 -0.001973 0.083595 0.061678
+-0.027937 0.074507 0.052481 -0.156418 -0.008126
+-0.077649 -0.025098 -0.028822 0.031584 -0.062854
+-0.037974 0.052900 -0.008246 -0.058382 0.007371
+-0.059698 0.005125 0.103990 0.035731 0.076498
+0.045455 -0.034656 -0.089189 0.010512 -0.022809
+0.023399 0.080456 -0.046407 0.119537 -0.046816
+0.011054 0.024797 -0.075119 -0.091853 0.017319
+0.022797 0.030783 0.051211 -0.054302 0.035466
+-0.053426 0.002530 0.020784 -0.089056 0.007237
+0.031757 -0.019566 0.082209 -0.018737 -0.006975
+-0.032879 0.000924 0.069241 0.009323 0.017753
+0.041898 0.020597 0.000749 0.046727 0.117703
+-0.020501 0.027483 -0.056525 -0.059522 0.018749
+0.025171 0.033068 0.005911 0.134204 0.011451
+0.038296 0.086523 -0.027888 -0.033250 -0.035178
+0.043617 -0.108778 0.024102 0.016641 0.092810
+0.073643 0.030016 -0.066742 -0.010738 0.064668
+0.039526 -0.112082 -0.032794 -0.037218 0.027811
+-0.128246 0.003025 -0.070009 -0.076832 -0.013242
+-0.030105 0.038807 0.066675 0.013770 0.023016
+-0.094473 0.028346 -0.050126 -0.043963 -0.011618
+0.017048 -0.083869 -0.023363 0.030985 0.027338
+-0.080760 -0.055583 0.032162 -0.032668 -0.036833
+0.058238 0.020173 0.050309 -0.009187 0.009272
+-0.051130 -0.060180 0.014297 -0.085720 0.033908
+-0.002635 0.061924 -0.014460 0.025310 -0.143366
+-0.086237 0.079075 -0.057641 0.027727 0.053345
+0.030701 0.128530 -0.096663 0.028249 -0.038583
+-0.041418 -0.078768 -0.009950 -0.139435 0.050946
+-0.001476 -0.004529 -0.005454 0.042876 0.012496
+0.037365 0.037258 -0.009785 -0.014137 -0.075187
+-0.015646 -0.084672 0.066850 0.049159 0.022652
+-0.100018 0.030626 -0.031693 -0.026283 0.098183
+0.037095 -0.031902 -0.082082 0.064108 -0.081413
+-0.016931 0.069276 0.025553 0.019033 -0.009843
+0.021095 0.006896 0.091735 -0.006895 0.125729
+-0.038132 -0.025017 -0.094419 0.023870 0.012859
+-0.032674 0.010226 -0.092226 -0.004873 0.064962
+-0.006137 0.026959 -0.019304 -0.064646 -0.056343
+-0.049825 -0.021361 0.067875 -0.021989 0.008580
+-0.036917 -0.006108 0.023764 -0.015728 -0.098608
+0.056344 -0.043710 0.075790 0.016095 -0.079516
+0.016637 0.054791 0.091656 0.119050 -0.037915
+0.002929 -0.026705 -0.038725 0.031207 0.092135
+-0.016211 0.014904 -0.012804 -0.003882 0.145488
+0.013740 -0.018092 -0.113500 0.052133 -0.037974
+0.032356 0.065081 0.054718 -0.006753 -0.115419
+-0.041122 -0.070389 0.024012 -0.033000 0.078595
+0.002090 -0.003576 0.025975 -0.029200 0.073729
+-0.067545 -0.099515 0.068346 0.036494 -0.010089
+-0.040395 -0.024474 0.000906 0.004180 -0.011648
+0.077079 0.062025 0.048336 -0.047553 0.020667
+-0.034650 0.102764 -0.088833 0.063548 -0.063948
+0.004926 -0.075665 -0.010204 0.077117 0.008604
+0.016964 -0.006119 0.015651 -0.060279 -0.084239
+0.021175 -0.041494 0.062789 0.023042 -0.049413
+0.030400 -0.088557 -0.027424 -0.038734 -0.047767
+-0.039267 -0.007115 -0.095571 0.040131 -0.172339
+-0.015514 0.125809 0.002775 0.011847 -0.039818
+0.003508 0.088794 -0.016537 -0.041801 0.077773
+-0.025099 -0.015829 -0.087113 -0.031825 0.018394
+-0.033412 -0.037361 0.054089 0.082347 -0.078775
+0.044163 -0.001941 -0.036779 0.006281 0.033103
+-0.019683 0.013567 0.044802 0.035896 0.099997
+0.048928 0.024331 0.024339 -0.119730 -0.020516
+0.003938 -0.049114 -0.020101 0.025056 -0.039189
+-0.111669 0.015432 0.107806 0.009106 -0.041783
+0.004427 0.114069 0.035561 0.004165 0.048624
+0.065296 -0.020221 -0.112241 -0.024621 -0.104499
+0.040792 -0.042481 -0.126163 0.113850 0.052426
+0.045897 0.073140 -0.038559 -0.101637 -0.010880
+0.014157 0.016488 0.118415 -0.003117 0.015104
+0.005410 -0.047124 -0.034323 -0.038341 0.011107
+-0.021536 -0.087493 0.030662 0.003416 -0.087892
+-0.019840 0.053393 0.053193 0.082340 -0.013319
+0.013522 0.032147 -0.036372 0.021664 0.058868
+0.001821 0.053133 0.015237 -0.029422 0.049671
+0.032518 0.054852 -0.061126 0.052882 0.005097
+-0.000200 0.077584 0.023798 -0.015922 -0.043740
+-0.019244 -0.065261 -0.001356 0.041977 0.064243
+0.006831 0.025573 -0.039113 -0.067333 0.007728
+0.061532 -0.086024 0.037808 0.024787 -0.036093
+-0.148755 -0.014995 0.025827 -0.017793 -0.025363
+0.010676 -0.014283 0.038621 -0.041757 -0.018561
+-0.004984 0.048476 -0.027007 0.007045 -0.010409
+0.017155 -0.042986 -0.059561 0.084763 0.072516
+-0.014595 -0.020495 -0.009080 -0.061622 -0.023300
+0.018242 0.008783 0.036423 -0.001710 -0.025459
+-0.030263 -0.038355 0.112339 -0.013108 0.030839
+-0.050166 -0.045350 -0.006927 0.057254 -0.090539
+-0.052734 0.030495 -0.028123 0.095772 0.021287
+0.004939 0.065006 -0.066334 0.009532 0.009978
+0.000692 -0.079650 -0.130620 -0.025115 -0.037193
+0.028545 -0.011885 -0.018329 0.101976 0.056169
+0.074905 -0.039652 -0.019531 -0.031025 -0.031945
+-0.004999 -0.024155 0.051113 0.063966 -0.016577
+-0.028105 0.007520 -0.098547 -0.151585 0.016061
+-0.011144 -0.064311 -0.071227 -0.012819 -0.089185
+-0.011034 0.126948 0.065626 0.030017 -0.077054
+-0.016170 -0.011244 -0.030183 -0.068083 0.115571
+0.004514 -0.032999 -0.119452 -0.052594 0.048244
+0.006761 0.001824 -0.082055 0.063269 0.016468
+-0.015038 0.008738 -0.042234 -0.087201 -0.135683
+-0.058265 -0.010563 0.099495 0.035913 0.016120
+0.022021 -0.060263 0.058709 -0.025272 -0.069868
+-0.012474 -0.023791 0.072270 0.012475 -0.047178
+0.065743 0.022110 0.027334 0.039002 0.034057
+0.056588 0.090825 -0.083277 0.062553 0.045167
+0.016230 0.042246 -0.055865 -0.029814 0.063583
+0.101556 -0.041974 0.065108 0.059385 -0.023394
+0.067253 0.003519 0.053386 0.071879 -0.052816
+-0.014833 -0.034839 0.008862 0.040661 0.076481
+0.113195 -0.022318 0.022988 -0.047563 0.021223
+-0.031776 -0.097003 0.010273 0.070963 -0.088181
+-0.014952 -0.044557 -0.040211 0.027326 0.055263
+-0.027993 0.036839 0.059553 -0.085166 0.023284
+0.081938 0.013347 -0.056030 0.032386 -0.078191
+-0.012334 -0.065844 -0.082412 0.021620 0.049765
+0.021974 0.064777 0.116942 -0.066893 -0.029098
+0.063773 -0.015678 0.036050 -0.001531 0.050204
+-0.007431 -0.053256 0.019949 -0.084515 -0.052331
+0.003628 -0.002831 0.028651 -0.022563 -0.068663
+-0.046864 0.085680 0.035073 0.090355 0.076019
+-0.033539 0.078709 0.049120 -0.058380 0.063174
+-0.067044 -0.040988 -0.024670 -0.076422 0.022349
+-0.059226 -0.063296 -0.024667 0.109900 -0.039214
+0.081493 0.061838 -0.018769 0.054117 0.049416
+-0.039105 -0.000888 -0.008740 0.069660 0.056013
+-0.013119 0.088704 0.005989 -0.118940 0.055085
+-0.021830 -0.027348 -0.037636 -0.044645 -0.013684
+-0.033348 0.066928 -0.026840 -0.074085 -0.052255
+-0.095346 0.073214 0.052368 0.000793 0.036896
+0.029109 -0.040256 -0.063044 -0.008606 -0.000437
+0.037406 0.035413 -0.064896 0.100694 -0.002451
+-0.062127 -0.005213 -0.045513 -0.099165 -0.029096
+0.046180 -0.038707 0.091676 -0.027947 0.081059
+-0.051970 0.036875 -0.002862 -0.034628 0.032122
+-0.042473 -0.133086 0.097766 0.014513 -0.057376
+-0.026905 0.025345 0.058654 0.088520 0.021655
+0.068829 -0.068890 0.073760 0.037294 0.067743
+0.004270 0.030315 -0.017342 -0.022912 0.021230
+0.027415 0.010279 0.033049 0.105463 -0.080985
+-0.024846 0.118625 0.017407 -0.060377 -0.071617
+-0.034814 -0.031741 0.033114 -0.008946 0.044965
+0.026382 0.068195 -0.053337 -0.079506 0.089886
+0.019186 -0.075490 -0.002131 -0.014334 0.010145
+-0.102313 0.044049 0.024515 -0.079086 0.105318
+0.030157 0.019277 0.009149 -0.002192 0.035223
+-0.093034 0.037988 -0.056189 0.005485 -0.070967
+0.093206 -0.017940 -0.068121 0.025189 0.098473
+-0.047072 -0.057202 0.027986 -0.068841 -0.023193
+0.059350 -0.020968 0.125734 -0.015897 0.013012
+-0.018615 -0.122453 -0.008474 -0.064049 0.013910
+0.021902 0.037915 0.039737 0.028260 -0.089535
+-0.052408 0.036171 0.024766 0.038944 0.043725
+0.068495 0.097351 -0.051536 -0.026994 0.009734
+0.022521 -0.085412 -0.004269 -0.068523 0.026057
+-0.003617 0.002555 -0.024622 0.075742 0.024453
+0.043622 0.048992 -0.003958 -0.051371 -0.010372
+-0.009291 -0.026649 0.112796 0.034440 0.000480
+0.000993 0.012835 -0.024524 -0.086702 0.076990
+-0.012872 -0.012272 -0.049239 0.045637 -0.100430
+-0.080402 0.098860 -0.001607 -0.027740 -0.028447
+0.010187 0.049316 0.064463 -0.032244 0.096351
+0.042173 -0.014830 -0.130350 -0.065157 -0.020131
+0.011826 0.043958 -0.096975 0.094420 0.065360
+0.008046 0.034625 0.022699 -0.011948 -0.162034
+-0.028577 -0.049031 0.062518 0.027121 0.011773
+-0.062840 -0.028274 0.019513 0.004294 -0.058221
+0.015044 0.032322 0.078632 0.074899 -0.089319
+0.012740 0.036679 0.061490 0.073955 0.074210
+-0.042945 0.081229 0.003752 -0.027289 0.107675
+0.028637 -0.027527 -0.094485 -0.014081 0.106655
+0.037034 -0.046495 -0.057983 0.047583 0.007322
+-0.000480 0.084590 0.058447 0.010057 -0.044796
+-0.035563 -0.017414 0.104652 -0.101773 0.088697
+0.008873 -0.059058 -0.074754 -0.068039 0.080127
+-0.042104 -0.067599 0.033969 0.019253 -0.038611
+0.007952 0.028316 -0.003028 0.025731 -0.031708
+0.103465 0.087113 0.002288 -0.034732 0.000345
+0.011011 0.084188 -0.047564 0.007324 -0.100708
+-0.031667 -0.084195 -0.045309 0.035772 0.029785
+-0.003803 0.041355 0.070690 -0.006148 -0.101234
+0.036078 -0.057998 0.086587 0.069468 -0.017787
+0.043517 -0.032858 -0.018033 -0.080238 -0.054284
+0.011916 -0.027168 0.032061 0.004608 -0.164665
+0.024300 0.127777 -0.001633 0.037157 -0.077063
+0.079112 0.092827 -0.045527 0.012537 0.048156
+-0.028838 -0.088344 -0.058200 -0.001037 0.009927
+0.005766 -0.051805 0.035975 0.103039 -0.118515
+0.040739 0.028846 -0.010371 -0.011677 -0.017552
+-0.012737 -0.062534 0.096752 0.040808 0.067058
+-0.016128 -0.050826 0.049568 -0.159884 0.104117
+-0.060870 -0.026777 -0.040150 0.003038 0.011219
+-0.047457 0.044509 0.104699 -0.061694 -0.048700
+-0.028345 0.058571 0.115771 0.060865 0.049165
+-0.017126 -0.029090 -0.087904 -0.040448 -0.053762
+-0.009906 0.012529 -0.107155 0.136828 -0.025232
+0.019743 0.120518 -0.033402 -0.147125 -0.096492
+-0.011562 -0.010821 0.143581 -0.029410 0.012515
+-0.007255 -0.051247 -0.015950 -0.001080 -0.021038
+0.033604 -0.082138 0.032578 -0.050610 -0.097139
+-0.058199 0.107657 0.105983 0.027511 -0.023155
+0.031791 0.024300 -0.017968 0.063148 0.049343
+-0.007836 -0.006517 -0.013473 -0.004970 0.056535
+0.020974 0.047090 0.009318 0.062741 -0.066064
+0.049383 0.062600 -0.007244 0.025406 -0.011447
+-0.019044 -0.033373 -0.012008 -0.020777 0.089488
+0.069039 -0.039904 -0.061004 -0.104096 0.011128
+0.072522 -0.048600 -0.051581 0.021177 0.001740
+-0.135630 0.074921 0.010935 0.054793 -0.041526
+0.024169 0.044285 0.017189 -0.023435 -0.022755
+-0.018169 0.007995 -0.068248 -0.015644 -0.055355
+-0.008988 0.013394 -0.130934 0.055860 0.075055
+-0.024869 -0.072987 0.105486 -0.141599 -0.052593
+0.104369 -0.026032 0.010393 0.003048 -0.077763
+0.020642 -0.054726 0.098890 -0.062038 -0.008284
+-0.030920 0.041949 -0.052596 0.055867 -0.059301
+-0.027785 0.067366 -0.015217 0.061893 -0.058155
+0.044323 0.038825 -0.048558 0.026668 0.056475
+-0.042396 -0.044360 -0.073532 -0.092982 -0.055163
+-0.002151 -0.047433 0.007696 0.110986 0.055177
+0.038644 0.059219 -0.050130 -0.016829 -0.018164
+-0.003120 -0.055675 0.097769 0.119773 0.017092
+-0.022682 0.021229 -0.029792 -0.117466 0.066111
+0.065948 -0.074617 -0.074175 0.016698 -0.071365
+-0.047641 0.063671 0.005349 -0.039942 -0.093589
+0.065751 0.017235 0.035630 -0.031694 0.061852
+0.053612 -0.016144 -0.071008 -0.029225 0.066491
+-0.040345 0.042471 -0.075360 0.066743 0.050696
+-0.014316 -0.034336 0.016703 -0.103271 -0.081002
+-0.052827 0.007353 0.046627 0.008461 0.049725
+-0.003406 -0.093149 0.006210 -0.055973 -0.057089
+-0.020200 0.012346 0.141207 0.045917 -0.012261
+0.039647 0.050373 0.056749 0.072718 0.002752
+0.004009 0.038716 -0.039473 0.082663 0.054674
+-0.004500 0.042366 -0.110686 -0.077697 0.039758
+0.051345 0.003071 -0.019544 0.063662 -0.082557
+0.025358 0.016659 0.029266 0.011585 -0.055014
+-0.026965 0.026974 0.018085 -0.022347 0.075107
+0.063294 -0.046595 0.032484 -0.030675 0.062036
+-0.033627 -0.064331 0.081940 0.081033 -0.050699
+-0.046257 -0.013797 -0.008749 -0.013019 0.018478
+-0.008139 0.075257 0.092736 -0.053166 0.014791
+-0.013803 0.044603 -0.116267 0.032848 -0.092134
+0.020647 -0.052370 -0.128516 0.004475 -0.043562
+0.036375 -0.002867 0.103214 -0.109219 0.008372
+-0.017374 -0.021978 0.020315 0.012816 0.005703
+0.099649 -0.047777 0.054769 -0.025362 -0.003862
+0.036146 -0.000369 -0.000853 0.012461 -0.032338
+0.013247 0.073478 -0.020868 0.034203 0.002982
+-0.016316 0.149713 0.002631 -0.081349 -0.020016
+-0.155943 -0.058299 -0.046014 0.027098 0.028942
+-0.011857 -0.022016 0.017303 0.105805 -0.012430
+0.086002 -0.009549 -0.071369 -0.005224 0.013152
+-0.032159 -0.053343 0.027646 0.043468 0.037717
+-0.009747 0.013014 0.058424 -0.101661 -0.010004
+-0.053787 -0.020784 -0.072472 -0.041184 -0.087878
+-0.077459 0.062841 0.011552 -0.085703 -0.035239
+-0.018818 0.030430 0.040444 -0.042755 0.041121
+0.003887 -0.025745 -0.049363 -0.025894 -0.054378
+0.070007 -0.019364 -0.141059 0.039915 -0.045332
+0.024336 0.030320 -0.082784 -0.048936 -0.027234
+0.020447 0.007182 0.084824 -0.045970 0.027752
+-0.009759 -0.023702 -0.008379 -0.071048 0.015064
+0.009395 -0.052442 0.130155 -0.011644 -0.014787
+-0.021138 0.024468 0.045928 0.043163 -0.030898
+0.065143 -0.014501 -0.008479 -0.017099 0.098271
+-0.038323 0.004035 -0.061317 -0.041506 0.038436
+0.055127 0.060303 0.044674 0.128814 0.038762
+0.086495 0.069068 -0.070150 -0.089410 -0.054372
+0.033209 -0.096623 0.034209 0.050531 0.038502
+0.059019 0.043258 -0.045121 -0.063876 0.049971
+0.014954 -0.153720 0.031755 -0.021388 0.014803
+-0.125385 0.063700 -0.019166 -0.095829 0.022129
+-0.035969 0.041896 0.030461 -0.015321 -0.015067
+-0.040013 0.024331 -0.015398 -0.008113 -0.019773
+0.027804 -0.039993 -0.074170 0.033667 0.046367
+-0.086691 -0.034684 0.054798 -0.087551 -0.014591
+0.044687 0.057457 0.118611 0.010895 0.011308
+-0.066320 -0.063774 0.057919 -0.051338 0.049145
+0.006265 0.048016 -0.010350 0.089136 -0.100672
+-0.040908 0.090819 -0.084327 0.065891 0.025763
+-0.030480 0.103529 -0.144803 -0.036912 0.017161
+-0.020671 -0.059993 -0.030123 -0.104598 0.039178
+0.018764 0.001037 0.014109 0.056332 0.050717
+-0.004747 0.035822 0.019209 -0.010162 -0.044650
+-0.039307 -0.111424 0.122778 0.090067 0.014313
+-0.047117 0.042269 -0.052396 -0.023384 0.123438
+-0.016756 -0.092801 -0.058478 0.080712 -0.052288
+-0.031113 0.064436 -0.005451 -0.018327 -0.053156
+-0.022903 0.031275 0.042126 0.009823 0.074549
+0.002952 -0.010186 -0.114717 -0.029095 -0.026125
+0.003889 -0.003003 -0.060079 0.034566 0.010262
+-0.029593 0.012239 -0.052124 -0.028219 -0.110036
+-0.015073 0.005623 0.053202 -0.029201 -0.038548
+-0.025617 -0.000150 0.022644 0.000550 -0.049223
+0.018036 -0.010954 0.045453 0.019204 -0.075695
+0.027728 0.012573 0.072358 0.082283 0.037531
+-0.003946 0.003139 0.000013 0.021161 0.067238
+0.019852 -0.022422 -0.032314 -0.024316 0.106260
+-0.001499 -0.028984 -0.045186 0.019666 -0.000966
+0.047073 0.075944 0.081739 -0.029633 -0.060673
+-0.013207 -0.057523 0.057259 -0.055200 0.078923
+0.013582 -0.060645 -0.029418 0.013853 0.056976
+-0.061172 -0.146801 0.049472 0.016436 0.045997
+-0.031589 -0.031052 0.031418 0.026113 -0.038676
+0.064035 0.045482 0.020622 0.005875 0.029585
+-0.005284 0.054275 -0.076784 -0.000845 -0.023097
+0.009660 -0.128422 0.002992 0.055651 -0.005932
+-0.027123 0.022215 0.057779 -0.080469 -0.076867
+0.008909 -0.030195 0.004706 0.060938 -0.038886
+0.050785 -0.063214 0.004370 -0.033455 -0.013089
+-0.009154 -0.030641 -0.030220 0.005174 -0.132262
+-0.021476 0.105410 0.027719 0.051123 -0.017271
+-0.000185 0.117864 0.035809 -0.071891 0.116329
+-0.009954 -0.102737 -0.053397 -0.057653 0.058746
+0.009878 0.024776 0.043190 0.082400 -0.020615
+0.032439 0.035539 -0.018820 0.017822 0.016504
+0.008745 -0.008596 0.054707 0.063681 0.056656
+0.032254 -0.023608 -0.002017 -0.146378 0.047072
+-0.016978 -0.066403 -0.042616 0.019845 -0.016902
+-0.036058 0.030091 0.057405 -0.035798 0.002185
+0.033655 0.062726 0.038185 -0.024604 0.038026
+0.013655 -0.050063 -0.040289 -0.034587 -0.089238
+-0.021893 -0.072730 -0.145619 0.108409 0.003979
+0.003043 0.058544 -0.005494 -0.058294 -0.023242
+-0.027050 0.048686 0.105867 0.037255 -0.005019
+-0.017867 0.007807 -0.016470 -0.017352 -0.004222
+-0.051778 -0.082651 0.031128 -0.051302 -0.094105
+-0.007583 0.048196 0.056035 0.076579 -0.049990
+0.037184 0.064354 -0.004853 0.019012 0.052243
+0.041607 0.017800 -0.018867 -0.048040 0.036929
+0.071847 0.012078 -0.003492 0.052903 -0.041736
+-0.008196 0.113020 0.034731 -0.051940 0.022987
+-0.022300 -0.033261 0.020486 -0.029803 0.179316
+0.014762 -0.006096 -0.022377 -0.053417 0.045007
+0.047412 -0.078434 0.007164 0.048187 -0.032463
+-0.106666 -0.022577 -0.007054 0.017166 -0.007364
+0.007677 0.013536 0.004985 -0.052519 -0.019141
+0.018399 0.004096 -0.066275 -0.014342 -0.023287
+0.017068 -0.061082 -0.021342 0.049768 0.072011
+0.006385 -0.035801 -0.027304 -0.099812 0.001797
+0.065304 -0.033306 0.042256 -0.008741 -0.006929
+0.010954 -0.080864 0.095856 -0.012888 0.050346
+-0.058343 -0.042527 0.010740 0.027268 -0.131655
+-0.022159 0.048331 -0.019242 0.139544 -0.009212
+0.008528 0.095408 -0.072588 -0.026269 0.046686
+-0.057569 -0.103939 -0.092932 -0.053006 0.017352
+0.065774 -0.067465 -0.035608 0.077533 0.035754
+0.076737 0.042552 -0.018386 -0.040285 -0.060055
+0.002954 -0.063347 0.023485 0.069391 0.030181
+0.015083 -0.035587 -0.073150 -0.108303 0.033116
+-0.051149 -0.070534 -0.072103 0.010046 -0.008050
+-0.038552 0.065148 -0.005398 0.029138 -0.091804
+-0.032927 0.026057 0.044995 -0.067493 0.140590
+-0.010770 -0.051205 -0.134801 0.039771 0.047000
+-0.040774 0.024562 -0.118058 0.061721 0.010046
+-0.084855 -0.002180 -0.028081 -0.040929 -0.091046
+-0.074457 -0.063377 0.065429 0.036303 -0.058948
+-0.009780 -0.035398 0.010274 -0.054774 -0.052228
+0.000477 -0.035468 0.059891 -0.011652 -0.043705
+0.130993 0.029418 0.024997 0.014118 -0.000473
+0.012220 0.094825 0.003360 0.050743 0.112621
+-0.036424 0.119286 -0.062500 0.028140 0.113267
+0.092232 -0.028352 0.015304 0.118553 -0.037245
+0.047917 0.068301 0.034398 0.054323 -0.111406
+0.016223 -0.016616 0.048104 -0.012621 0.095559
+0.040486 -0.036481 0.006675 -0.029498 0.019722
+-0.005174 -0.090840 0.040097 0.031192 -0.056686
+-0.015354 -0.037239 -0.040451 0.001148 0.016519
+0.027984 0.063613 0.029013 -0.053331 0.009462
+0.094796 0.073376 -0.035437 0.079788 -0.072969
+0.005683 -0.141562 -0.028240 0.056569 0.053462
+0.024141 0.020688 0.105325 -0.088920 -0.074876
+0.044548 0.015221 0.063364 0.044219 0.028301
+-0.011412 -0.033571 0.034361 -0.067847 0.000284
+0.012742 -0.045973 -0.009839 0.044280 -0.077401
+0.013255 0.065280 0.018179 0.074351 0.004383
+-0.054040 0.072674 -0.012623 -0.023532 0.057154
+-0.077067 -0.071007 -0.013831 -0.015362 -0.004755
+-0.051874 -0.046591 -0.008108 0.051772 0.006314
+0.106169 0.066165 -0.024173 0.034211 -0.015378
+-0.085769 -0.015752 -0.008456 0.051049 0.015420
+-0.005850 -0.015631 -0.060787 -0.151510 0.080912
+-0.029476 -0.034162 -0.023308 0.021727 -0.069572
+-0.002926 0.066532 0.034835 -0.091864 -0.014468
+-0.077637 0.085530 0.058931 0.087803 -0.024233
+0.027189 -0.084814 -0.064844 -0.010260 -0.038228
+0.079925 0.040571 -0.027455 0.112376 0.008327
+-0.015541 0.020299 -0.039833 -0.122069 -0.008265
+0.048969 -0.037595 0.073512 -0.070833 0.106844
+-0.031463 -0.019591 0.029763 -0.022865 0.013933
+-0.014056 -0.092923 0.075324 0.002550 0.006051
+-0.074776 0.035465 0.027474 0.120921 0.027105
+0.061516 -0.026568 0.024123 0.047036 0.024385
+0.003344 0.059906 -0.051191 -0.053047 -0.027729
+-0.001564 0.005823 0.010087 0.083294 -0.024265
+0.042741 0.094994 0.021393 -0.083504 -0.083151
+0.011291 -0.058920 0.012861 0.030070 0.042736
+0.022911 -0.008546 -0.057609 -0.069900 0.088492
+-0.002894 -0.066828 -0.009727 -0.047981 0.019844
+-0.085641 0.000042 0.003014 -0.007295 0.035791
+0.036123 0.067002 0.026630 -0.001636 0.009073
+-0.016053 0.084871 -0.100683 -0.050020 -0.071874
+0.072365 -0.036757 -0.017701 0.038197 0.053099
+-0.056378 -0.028855 0.012463 -0.045723 -0.005667
+0.064256 -0.028177 0.057826 -0.055872 0.030883
+-0.002914 -0.097445 0.018108 -0.065132 0.064327
+-0.036809 0.022530 0.032579 0.083859 -0.088729
+-0.009218 0.070687 -0.027232 0.016749 0.037592
+0.061102 0.155046 -0.004610 -0.031402 0.008374
+-0.011437 -0.059360 -0.064021 -0.069056 0.022916
+-0.003860 0.044792 -0.030508 0.057430 -0.013125
+0.027304 -0.003144 -0.007603 -0.074523 -0.036823
+0.004066 -0.035482 0.142619 0.062765 0.083342
+-0.023363 -0.016003 0.016507 -0.060403 0.074455
+-0.020249 -0.025938 -0.007470 0.084381 -0.106173
+-0.060300 0.087411 0.014814 0.028437 0.010883
+0.012873 0.103973 0.089761 0.027096 0.064947
+0.033057 0.028486 -0.133571 -0.002210 -0.014149
+0.005981 0.010927 -0.143115 0.070712 0.006923
+0.044569 0.004846 -0.008362 -0.109156 -0.120284
+-0.007157 -0.027002 0.075999 0.001357 -0.006077
+-0.035577 0.042029 0.018068 0.017700 -0.038593
+-0.058375 0.013590 0.094255 0.021156 -0.080328
+-0.006126 0.058842 0.032376 0.051314 0.064136
+-0.063765 0.028090 0.032284 0.078521 0.108677
+0.012656 0.007400 -0.092093 -0.036734 0.056851
+0.000116 -0.002036 -0.026805 0.084821 -0.011989
+0.023502 0.064916 0.050640 -0.002411 -0.015045
+-0.026830 -0.004301 0.065835 -0.025416 0.056093
+0.090627 -0.051534 -0.023105 -0.029171 0.064099
+-0.030773 -0.085191 0.015343 -0.005415 0.005626
+0.013041 0.010729 0.018058 0.018453 -0.002180
+0.089388 0.064815 0.021466 -0.092663 -0.019224
+-0.008842 0.103392 -0.036092 -0.034972 -0.070552
+-0.077454 -0.124438 -0.056352 0.069482 0.030672
+-0.003203 -0.020694 0.070840 -0.004376 -0.102179
+0.064995 -0.059481 0.049343 0.024210 -0.003858
+0.056350 -0.015583 0.065190 -0.059043 -0.090407
+0.042894 0.012225 0.074108 0.009773 -0.093983
+0.048272 0.093970 0.039985 0.070722 0.010834
+0.011975 0.135085 -0.000165 -0.021759 0.065164
+-0.040893 -0.089985 -0.024270 -0.003863 0.030587
+0.000069 -0.021155 0.028518 0.153614 -0.071797
+0.070676 0.025584 0.005300 0.043065 -0.000089
+-0.003734 -0.036750 0.018132 0.036268 0.168510
+0.019026 -0.021440 0.042884 -0.095824 0.021242
+-0.026137 -0.034052 -0.063076 0.031835 -0.012727
+-0.084292 0.114347 0.068154 -0.074997 0.009182
+-0.056381 0.161792 0.065873 -0.004008 0.052013
+0.005326 0.018022 -0.114663 -0.107213 -0.079062
+-0.037042 0.007951 -0.066766 0.089297 -0.035405
+0.006611 0.013565 0.029000 -0.122667 -0.037773
+0.030080 0.039640 0.112965 -0.038791 0.051681
+0.018950 -0.002870 0.004002 -0.035366 -0.046099
+-0.006632 -0.046456 0.064561 -0.045986 -0.052509
+-0.045507 0.034342 0.094059 0.085895 -0.059965
+0.047107 0.045776 -0.051041 0.069720 0.062871
+-0.004318 0.016990 -0.053383 -0.000405 0.042032
+0.061772 0.087463 0.018593 0.001180 -0.105041
+0.036585 0.091364 -0.010729 0.002978 0.015583
+-0.077926 -0.029862 -0.037549 -0.014135 0.056743
+0.082538 -0.079858 -0.038190 -0.052196 -0.005951
+0.095037 -0.039714 0.003105 0.009675 -0.006472
+-0.098367 0.004226 0.018157 0.116425 -0.033752
+-0.009903 0.043421 0.067382 -0.058642 -0.037966
+-0.004321 0.046370 -0.039951 0.033751 -0.045280
+-0.005703 -0.055692 -0.075669 0.043537 0.088421
+-0.000079 -0.053451 0.015580 -0.177514 -0.037255
+0.081872 -0.006931 0.040197 -0.040382 -0.030544
+-0.032474 -0.073683 0.111389 -0.043286 -0.012181
+-0.070486 0.021008 -0.006453 0.059025 -0.084346
+-0.045844 0.134617 -0.026041 0.078112 -0.027141
+-0.001031 0.044353 -0.065608 0.036661 0.045948
+0.004303 -0.038662 -0.062062 -0.073388 -0.026033
+-0.002636 -0.014067 -0.022648 0.128905 0.104651
+0.091629 0.045550 -0.039856 -0.036999 -0.014194
+0.058828 -0.095390 0.054826 0.108067 0.017921
+0.007401 0.037480 -0.051214 -0.080561 0.050245
+0.005451 -0.084552 -0.014427 0.003994 -0.067761
+-0.042687 0.064428 0.056058 -0.024265 -0.093157
+0.011618 0.006660 0.071511 -0.116214 0.061118
+0.046247 0.008564 -0.083904 -0.015807 0.002628
+-0.075241 0.045928 -0.025621 0.024239 0.024757
+-0.010838 -0.006020 -0.007541 -0.087714 -0.046745
+-0.086472 -0.058225 0.054459 0.025327 0.052933
+-0.014453 -0.076697 -0.033271 -0.024850 -0.042314
+0.006569 0.008881 0.074045 0.050097 -0.053039
+0.019414 0.021988 0.024896 0.056649 0.014029
+-0.029525 0.048784 -0.029431 0.042442 0.049334
+-0.026698 0.072277 -0.101799 -0.008341 0.047314
+0.082658 -0.016114 -0.042442 0.043527 -0.030064
+-0.011416 0.013182 0.060549 0.002644 -0.070164
+-0.045732 -0.022494 0.019693 -0.016130 0.079647
+0.000137 -0.038661 0.034959 -0.041633 0.047926
+0.003937 -0.073487 0.058946 0.065316 -0.021139
+-0.029658 -0.005529 0.019340 0.005718 0.041614
+0.046584 0.048974 0.064738 -0.076893 0.055570
+-0.008793 -0.001555 -0.108121 0.080904 -0.073317
+0.004653 -0.088656 -0.069282 0.058314 0.010922
+0.012637 0.026970 0.078839 -0.078606 -0.003575
+0.010350 0.012762 0.009724 -0.032223 0.025429
+0.028469 -0.112814 0.072108 -0.066038 0.028088
+0.021121 -0.042380 -0.040489 0.029521 -0.098778
+0.078694 0.118164 -0.017958 0.087002 0.013197
+-0.023191 0.159205 0.002982 -0.142188 0.019509
+-0.062408 -0.050584 -0.091242 0.004705 0.040898
+-0.034214 -0.000165 -0.013000 0.062856 -0.025148
+0.102892 0.026243 -0.114277 0.061707 0.020581
+-0.052551 -0.075429 0.028865 0.098236 0.087934
+0.003941 0.037129 0.029683 -0.128548 0.026698
+-0.036967 -0.019454 -0.078159 0.008871 -0.086884
+-0.058585 0.059095 -0.041884 -0.137966 -0.017325
+-0.057685 0.085566 0.119159 -0.011731 0.076164
+0.059270 -0.000533 -0.073970 -0.001937 -0.048985
+0.021162 0.035663 -0.047899 0.054477 -0.072253
+0.030344 0.099352 -0.101163 -0.104366 -0.004390
+0.017480 -0.006506 0.031974 -0.043831 0.028735
+-0.033380 -0.037286 -0.025470 -0.075025 -0.009320
+-0.001852 -0.019244 0.082659 -0.052343 -0.013826
+-0.006310 0.016400 0.043020 0.054048 0.019322
+0.025350 0.000037 0.019873 -0.001509 0.073472
+-0.050388 0.028730 -0.071807 -0.078877 -0.006660
+0.042649 0.008729 -0.001538 0.090951 0.006897
+0.044002 0.096566 0.016693 -0.023445 -0.061755
+0.017879 -0.081886 0.054302 0.025875 0.073506
+0.045439 0.035703 -0.050539 -0.024113 0.030719
+0.003684 -0.089257 -0.009652 0.004777 -0.019300
+-0.184163 0.032927 -0.044636 -0.031259 -0.075344
+-0.014780 0.063123 0.067839 0.012301 -0.009528
+-0.061510 0.097677 -0.067039 -0.006689 -0.004137
+0.016930 -0.038502 -0.023013 0.052181 0.034074
+-0.090822 -0.097151 0.030070 -0.043927 0.004506
+0.049853 0.013260 0.049217 0.011345 -0.015640
+-0.017375 -0.084889 0.027637 -0.083011 0.017271
+0.011964 0.013770 -0.041388 0.021785 -0.113317
+-0.104729 0.128840 -0.005522 0.005470 0.070867
+0.034456 0.113067 -0.120802 0.015723 0.032177
+-0.026534 -0.052353 -0.069474 -0.100515 0.121550
+0.014104 -0.026758 -0.017051 0.063176 0.010188
+0.007059 0.032242 0.002999 -0.038362 -0.058729
+0.021051 -0.069408 0.065496 0.036434 0.024457
+-0.051978 0.045735 -0.057632 -0.009011 0.056847
+0.033616 -0.045577 -0.087817 0.102137 -0.027964
+-0.002581 0.069852 0.041033 0.041021 -0.038913
+-0.025533 0.043910 0.093674 0.006518 0.140256
+-0.022931 0.003222 -0.164511 -0.012575 0.008372
+0.023221 -0.013081 -0.086070 0.000152 0.053139
+0.005914 0.050660 -0.044071 -0.047270 -0.079699
+-0.047341 -0.038511 0.125150 0.012254 -0.032029
+-0.013659 -0.058072 0.035218 -0.033783 -0.083119
+0.046233 -0.049628 0.079349 0.065395 -0.090450
+0.044946 0.046353 0.131024 0.076594 0.042978
+-0.047922 0.002985 -0.056522 0.056443 0.112147
+0.010900 0.000489 -0.020178 0.036351 0.129699
+0.037153 0.027557 -0.079114 0.043216 -0.032491
+0.071191 0.026446 0.111274 -0.011111 -0.062724
+-0.000122 -0.019280 0.038617 -0.059199 0.111019
+0.020501 -0.045138 -0.015061 -0.064807 0.065959
+-0.054589 -0.087659 0.038646 0.014381 0.034881
+-0.048543 -0.006280 -0.009214 0.027865 -0.032303
+0.071681 0.064881 0.009542 -0.005854 0.079711
+-0.030565 0.072960 -0.051732 0.009082 -0.047330
+0.051060 -0.086171 -0.053292 0.117917 0.007520
+0.006614 0.011574 0.052013 -0.067455 -0.037879
+0.006855 -0.046269 0.030860 0.034071 -0.002125
+0.048522 -0.066340 -0.050068 -0.091857 -0.039875
+0.042169 -0.025418 -0.046173 0.047008 -0.159002
+-0.047329 0.169123 -0.038203 -0.005754 -0.037022
+0.040981 0.059210 -0.002242 -0.042617 0.044265
+-0.059317 -0.044882 -0.074775 -0.083442 0.028007
+-0.041098 -0.031959 0.043096 0.061795 -0.028197
+0.040470 -0.018708 -0.008600 0.002891 0.053975
+-0.024208 0.023791 0.009775 0.081813 0.089801
+0.033188 0.016547 0.021751 -0.087759 0.023122
+-0.022831 -0.039574 -0.020474 0.037836 -0.007783
+-0.094861 0.073247 0.069161 -0.023846 -0.041333
+-0.025772 0.087748 0.025988 -0.012948 0.064875
+0.010587 0.013649 -0.041432 -0.081306 -0.084813
+-0.006181 -0.038833 -0.069003 0.107345 0.007611
+0.016453 0.041605 -0.043538 -0.126253 0.035968
+-0.003914 0.021006 0.086272 -0.015117 0.004273
+-0.017316 -0.011375 -0.050330 -0.020760 0.009092
+-0.018200 -0.056900 0.062502 0.046639 -0.106123
+0.033584 0.108129 0.061245 0.069683 -0.038308
+-0.006263 0.062187 -0.026140 -0.006177 0.072540
+0.026465 0.025257 0.000306 -0.033152 0.070377
+0.032552 0.067946 -0.041184 0.068817 -0.042517
+-0.023665 0.089426 -0.009517 -0.031905 -0.028876
+-0.047198 -0.101750 -0.021643 0.030076 0.103800
+0.003349 0.017493 0.002512 -0.094201 -0.005963
+0.089063 -0.095130 0.050351 -0.004288 -0.067613
+-0.131572 -0.051380 0.008583 0.005412 0.028560
+-0.017345 0.004478 0.031108 -0.057891 -0.007459
+-0.009374 0.004726 -0.032662 0.036793 -0.009074
+-0.023603 -0.039928 -0.021853 0.074091 0.084789
+0.020853 -0.007579 0.017575 -0.082903 -0.016044
+0.033216 -0.023150 0.052294 0.018359 -0.025699
+-0.035371 -0.079831 0.144398 -0.041178 0.060835
+-0.045799 -0.044320 0.000953 0.061485 -0.045374
+-0.093964 0.068302 -0.076466 0.119176 -0.014095
+-0.009224 0.091475 -0.038545 0.004967 0.001667
+0.028758 -0.091372 -0.095792 -0.025909 0.005482
+0.031234 -0.025637 -0.021291 0.135677 0.020946
+0.107580 0.013372 -0.085671 0.020971 -0.038560
+0.038570 -0.017209 0.045906 0.060269 0.001966
+0.032650 -0.006186 -0.072219 -0.189856 -0.007205
+-0.015639 -0.055057 -0.065552 -0.053151 -0.128235
+-0.012954 0.084159 0.026617 0.003305 -0.085995
+0.047267 -0.020931 0.007625 -0.078957 0.121974
+0.045764 0.005225 -0.141436 0.003027 0.051391
+-0.036784 -0.001419 -0.053342 0.051094 0.015725
+-0.019096 -0.002840 0.026380 -0.069790 -0.184245
+-0.051566 -0.028396 0.071692 0.098005 -0.020301
+0.016438 -0.046403 0.001404 -0.000052 -0.054688
+-0.022357 0.007259 0.085506 0.017935 -0.014656
+0.098405 0.054979 0.035010 0.075368 0.047790
+0.037848 0.078374 -0.058610 0.016057 0.084829
+0.041381 0.045231 -0.121185 -0.048619 0.095037
+0.078616 0.022570 0.039332 0.081333 -0.008814
+0.036266 0.020667 0.051651 0.048340 -0.014173
+0.001842 -0.015009 0.034124 0.017931 0.056477
+0.124333 0.001687 -0.029607 -0.069722 0.024592
+-0.008487 -0.136955 -0.020417 0.039039 -0.063902
+-0.051767 -0.039427 -0.040545 0.032784 0.056740
+-0.001091 0.036666 0.028260 -0.081961 0.033769
+0.027067 0.018663 -0.038013 0.000810 -0.051724
+-0.017021 -0.083432 -0.113410 0.025947 0.004457
+-0.019510 -0.003952 0.096457 -0.087833 -0.033332
+0.032633 -0.028593 0.053980 0.004859 0.027062
+0.027726 -0.054113 0.046789 -0.047480 -0.022139
+0.006309 0.013074 0.001745 0.000719 -0.068648
+-0.039339 0.124991 -0.017031 0.104387 0.075424
+-0.064776 0.049930 0.021317 -0.031441 0.064129
+-0.081324 -0.071417 -0.036637 -0.054516 0.069005
+-0.034336 -0.097799 0.042552 0.103137 0.014131
+0.086508 0.031131 -0.032366 0.059489 -0.003838
+-0.064570 -0.002930 0.012624 0.042919 0.062446
+0.044061 0.055589 0.003834 -0.094630 0.085990
+-0.053889 -0.024564 -0.026389 -0.016842 -0.060025
+-0.074654 0.030141 -0.008240 -0.045068 -0.051917
+-0.152218 0.035234 0.028967 0.032527 0.062252
+0.000908 -0.036356 -0.081610 -0.001575 0.014623
+-0.004478 0.064008 -0.087800 0.081273 -0.017113
+-0.018705 0.033443 -0.058350 -0.122667 -0.057365
+0.033540 -0.050441 0.124594 0.013386 0.053846
+-0.043376 -0.002266 -0.008195 -0.033995 0.053108
+-0.040370 -0.064239 0.077268 -0.002621 -0.059563
+-0.046177 0.004964 0.033231 0.064375 0.001192
+0.114583 -0.058848 0.061280 0.006693 0.036098
+0.009875 0.035834 -0.018310 -0.036184 -0.014992
+0.069939 0.059780 0.016602 0.073982 -0.035990
+-0.015685 0.078068 0.050322 -0.088097 -0.105328
+-0.025670 -0.057722 -0.013893 0.006662 0.048590
+0.078264 0.016992 -0.038464 -0.047615 0.099275
+0.010093 -0.039867 0.011067 -0.011289 0.010908
+-0.115702 0.003261 0.019257 -0.044432 0.040269
+0.018630 0.024500 0.039527 -0.019008 0.039507
+-0.072659 0.078072 -0.050083 -0.037195 -0.134288
+0.019462 0.000276 -0.077134 0.027231 0.091209
+-0.050042 -0.033161 0.001557 -0.033891 -0.049683
+0.056345 -0.048181 0.069910 -0.020048 -0.046249
+-0.039646 -0.128983 0.089155 -0.075828 0.037947
+0.004400 0.018311 0.016766 0.013464 -0.103994
+-0.006838 0.049909 0.006876 0.039950 0.026768
+0.027940 0.106751 -0.086738 -0.030655 -0.023916
+0.054319 -0.087527 -0.016511 -0.107128 0.027059
+-0.002389 0.030765 0.000550 0.071481 0.033998
+0.036687 0.048116 0.010056 -0.080424 -0.053276
+-0.000327 -0.054330 0.094151 0.063155 0.020931
+-0.026860 0.016310 -0.024435 -0.073159 0.050455
+0.022409 -0.008454 -0.035545 0.054995 -0.048738
+-0.044119 0.073997 0.039168 -0.014561 -0.032013
+0.028242 0.039841 0.075847 -0.017028 0.060085
+-0.021478 0.038475 -0.145149 -0.060014 -0.014315
+0.056108 0.032615 -0.097225 0.033835 0.051055
+0.042640 0.045231 0.000360 -0.041305 -0.108117
+-0.023348 -0.045772 0.038096 0.000486 -0.013393
+-0.093532 0.016559 0.001345 -0.008241 -0.068229
+0.010724 0.006837 0.077785 0.024403 -0.089797
+0.019810 0.041552 0.064900 0.067216 0.122533
+-0.033019 0.073688 0.001023 0.040220 0.079306
+-0.033084 -0.028731 -0.066533 0.015167 0.078774
+0.036633 -0.011276 -0.029348 0.033478 0.000076
+-0.011424 0.089071 0.107503 -0.027201 -0.024133
+-0.086237 -0.015807 0.067867 -0.026911 0.055025
+0.003279 -0.076609 -0.022878 -0.065051 0.117459
+-0.064757 -0.048837 -0.006132 0.015775 -0.025174
+-0.012054 -0.017396 -0.008215 0.026521 -0.033990
+0.045441 0.100425 0.005545 -0.063862 0.021216
+0.038286 0.073333 -0.080698 0.015085 -0.070552
+-0.073377 -0.065780 -0.028242 0.031930 0.034800
+0.014232 0.011229 0.097374 -0.050100 -0.132752
+0.011148 -0.042578 0.076114 0.024497 -0.012283
+0.120806 -0.036672 0.010487 -0.089491 -0.070409
+-0.010691 -0.003941 0.028773 0.005044 -0.130679
+0.045320 0.101038 0.007190 0.023122 -0.032858
+0.071021 0.085183 -0.064280 -0.039826 0.069093
+-0.045199 -0.056327 -0.038230 -0.030074 0.020018
+0.043187 -0.037153 0.053548 0.081616 -0.046930
+0.041026 -0.013232 -0.029798 -0.007515 -0.009780
+-0.014618 -0.049999 0.086479 -0.000441 0.122169
+0.000547 -0.072517 0.024520 -0.173329 0.033337
+-0.032822 -0.039451 -0.029459 -0.010553 -0.014511
+-0.042816 0.043535 0.098090 -0.011974 -0.009803
+-0.011320 0.103835 0.068587 0.016565 0.009926
+-0.038017 -0.036161 -0.141386 -0.056138 -0.087531
+0.012520 0.001341 -0.028710 0.134825 -0.022612
+0.025072 0.059725 -0.059548 -0.077144 -0.055577
+0.008583 0.014431 0.160366 -0.000317 0.069355
+0.021539 -0.030848 -0.001411 0.003884 -0.021168
+-0.002315 -0.031485 0.058421 -0.069080 -0.089460
+-0.074381 0.044224 0.078251 0.015334 -0.018453
+0.024757 -0.006325 -0.030304 0.041022 0.051034
+-0.000912 0.014462 -0.042230 -0.034329 0.049998
+0.042384 0.055463 -0.026732 0.016663 -0.070257
+0.027628 0.032582 0.025606 0.007339 -0.016995
+-0.014641 -0.013348 -0.035777 -0.048054 0.072409
+0.073357 0.019992 -0.053669 -0.099428 0.009662
+0.053875 -0.084206 -0.028164 0.001825 -0.007384
+-0.118351 0.036128 -0.052874 0.044796 -0.008440
+0.034462 0.021959 0.038695 -0.029505 -0.010005
+0.006580 -0.019193 -0.033304 -0.006948 -0.032920
+-0.035370 -0.048525 -0.089756 0.086975 0.071726
+-0.061466 -0.022927 0.037104 -0.115937 -0.074302
+0.095124 0.034074 0.041596 -0.019002 -0.078886
+-0.046289 -0.026431 0.075125 -0.085653 0.030848
+-0.087457 -0.013738 -0.079060 0.085171 -0.076996
+-0.026743 0.040359 0.001789 0.092574 -0.022293
+0.036215 0.020128 -0.057905 0.020242 0.017234
+-0.015028 -0.102072 -0.050335 -0.106620 -0.024631
+-0.035796 -0.019773 0.029319 0.102570 0.030958
+0.052784 0.035726 -0.058017 -0.006419 -0.004020
+-0.014277 -0.047373 0.048700 0.111928 0.002486
+0.008505 0.051728 -0.097055 -0.122271 0.071235
+0.003188 -0.039588 -0.076039 0.021148 -0.078617
+-0.065872 0.029089 -0.000290 0.000898 -0.140194
+0.058506 -0.007075 0.002829 -0.061576 0.057297
+0.022539 -0.043176 -0.078264 -0.026623 0.050164
+-0.067814 0.043950 -0.089140 0.025451 0.015987
+-0.021710 -0.023764 -0.037703 -0.092210 -0.086925
+-0.088289 0.020833 0.085474 0.007660 0.032167
+-0.047200 -0.148647 -0.011014 -0.056924 -0.066650
+0.000222 0.031116 0.120665 0.017924 -0.052237
+0.024475 0.057260 0.023098 0.039613 0.002833
+0.015113 0.005702 -0.065102 0.150484 0.040642
+-0.062865 0.018220 -0.104305 -0.058038 0.078032
+0.062938 -0.043059 -0.041551 0.090274 -0.090255
+0.003055 0.024771 0.053662 0.023982 -0.007128
+-0.022873 0.016118 0.029948 -0.005441 0.027042
+0.035737 -0.062768 0.026554 -0.001648 0.046026
+-0.015209 -0.061640 0.080279 0.035525 -0.062174
+-0.071438 -0.038252 0.017523 0.005805 0.027560
+0.022277 0.116677 0.082862 -0.023075 0.020718
+0.028369 -0.000644 -0.106525 -0.000025 -0.058375
+0.061774 -0.034461 -0.117604 0.015663 0.025243
+0.050739 -0.035373 0.050164 -0.097896 -0.016953
+-0.005625 -0.011887 0.038968 0.009589 0.020354
+0.073417 -0.037194 0.001085 -0.082529 -0.002741
+0.018895 0.000683 -0.005260 0.037680 -0.057914
+0.012065 0.095507 -0.006422 0.038327 0.053359
+-0.034912 0.104532 -0.034267 -0.091475 -0.037716
+-0.084581 -0.011088 -0.054143 0.048128 0.015983
+0.020394 -0.028289 -0.010829 0.083357 -0.051892
+0.095076 0.000131 -0.014931 0.032836 0.067972
+-0.033453 -0.011655 0.043489 0.044985 0.063936
+-0.002184 -0.038102 0.055724 -0.108760 -0.005538
+-0.065997 0.004333 -0.074726 -0.015630 -0.015614
+-0.126012 0.028542 0.044984 -0.082637 -0.073741
+-0.053097 0.043995 0.064370 -0.042989 0.078666
+0.032226 -0.050840 -0.030220 -0.007436 -0.034516
+0.018953 0.031855 -0.118774 0.087949 -0.022126
+-0.018807 0.026136 -0.060837 -0.058430 -0.043270
+-0.023841 -0.001635 0.100076 -0.051546 0.008906
+-0.018942 -0.046607 -0.031680 -0.056224 0.042606
+0.027052 -0.054425 0.104195 -0.058465 -0.062190
+-0.009973 0.010150 0.018185 0.049565 -0.005886
+0.094118 0.002006 0.034862 -0.013054 0.093378
+-0.068149 0.010758 -0.011233 -0.061272 0.036668
+0.049859 -0.008436 0.036689 0.126919 -0.002194
+0.048726 0.081941 -0.048791 -0.035094 -0.075793
+0.038586 -0.043391 0.024660 0.042400 0.074817
+0.074537 0.022976 -0.091022 -0.044301 0.025592
+0.019796 -0.129796 0.029916 0.017043 -0.041798
+-0.122413 0.049991 0.006262 -0.014011 -0.015763
+-0.024958 0.007419 0.020053 -0.006102 -0.004461
+-0.047792 0.040663 -0.058097 0.018616 -0.023217
+0.001382 0.001452 -0.062222 0.051898 0.052539
+-0.068723 -0.000916 0.071418 -0.060541 -0.020258
+0.063725 0.074490 0.080845 -0.023018 -0.006902
+-0.045143 -0.078702 0.018868 -0.044159 0.011980
+0.025938 0.021655 0.025290 0.063764 -0.132708
+-0.035846 0.091140 -0.021667 0.037332 0.035687
+-0.056994 0.140855 -0.102945 -0.006009 0.023620
+0.000204 -0.022699 -0.019046 -0.095351 0.050022
+-0.004054 -0.019058 -0.006429 0.068069 0.054649
+0.022500 0.029309 0.030159 -0.011081 -0.085224
+-0.029775 -0.097594 0.132106 0.026943 0.016069
+-0.012230 0.046209 -0.034177 -0.048993 0.094154
+-0.006547 -0.043268 -0.100110 0.130569 -0.083928
+0.008317 0.041995 -0.020555 0.004803 -0.056359
+0.023566 0.050093 0.044221 0.017323 0.073761
+0.000300 -0.034851 -0.062557 0.003592 -0.037316
+-0.023709 -0.011929 -0.063727 0.008558 0.029238
+0.012654 0.027199 -0.057145 -0.011774 -0.078417
+-0.053560 -0.003741 0.037455 -0.039273 -0.042025
+-0.002715 -0.030644 0.024806 0.010899 -0.041167
+0.026322 -0.013442 0.040313 0.057461 -0.057587
+0.046460 0.004776 0.094893 0.063931 -0.013181
+-0.024787 0.046427 0.000830 0.004541 0.070036
+0.012732 0.022279 -0.046965 -0.012615 0.106753
+0.032489 -0.016696 -0.061242 0.021789 -0.044774
+0.022712 0.030946 0.067933 -0.021075 -0.043324
+-0.010231 -0.077078 0.089327 -0.073913 0.129378
+0.001532 -0.043316 -0.016732 -0.026599 0.046714
+-0.088765 -0.101898 -0.000950 -0.012357 0.078311
+-0.025387 -0.053598 0.022292 0.050494 -0.007031
+0.067206 0.032304 -0.012170 -0.015225 0.029593
+-0.011657 0.043622 -0.062834 0.042909 0.003119
+-0.005148 -0.106709 0.013981 0.016710 0.024731
+-0.050424 0.039756 0.053237 -0.088869 -0.030557
+0.019223 -0.011248 0.001772 0.041389 -0.019693
+0.032684 -0.038816 -0.003782 -0.038112 -0.064818
+-0.036779 0.002321 -0.011310 -0.005428 -0.097258
+-0.068507 0.117705 0.010296 0.057410 -0.042191
+0.060044 0.076100 0.070634 -0.052272 0.109450
+-0.024491 -0.060570 -0.062604 -0.023828 0.043683
+-0.008675 0.020641 0.026445 0.122122 -0.030590
+0.007406 -0.006945 -0.038838 0.022271 0.036487
+-0.008083 -0.015591 0.089045 0.103083 0.080265
+0.048011 0.008577 -0.024779 -0.098878 0.047757
+-0.034944 -0.071262 -0.029632 0.058633 -0.031833
+-0.086670 0.020910 0.017850 -0.060040 -0.000118
+0.072375 0.123805 0.028335 0.006174 0.050778
+0.022055 -0.013090 -0.021358 -0.030207 -0.129857
+-0.009686 -0.036702 -0.094352 0.083990 -0.027328
+0.022973 0.088840 -0.029830 -0.041108 0.007991
+0.010351 0.043580 0.088045 0.019792 0.034260
+-0.018485 -0.026954 0.001393 -0.028881 -0.009226
+-0.007746 -0.080511 -0.012092 -0.026729 -0.115592
+-0.019491 0.098337 0.046778 0.072298 -0.078237
+0.005173 0.056223 -0.004141 0.066867 0.056189
+0.017966 0.044171 0.000676 -0.045110 0.018200
+0.032009 0.030245 -0.024198 0.053369 -0.032949
+0.005817 0.101192 0.004770 -0.022792 0.027114
+0.010600 -0.037525 -0.040021 0.003401 0.139637
+0.013348 -0.003801 -0.031619 -0.055232 -0.000905
+0.059632 -0.125609 -0.015414 0.054802 -0.053951
+-0.064755 0.024768 0.023636 0.018903 -0.000431
+-0.029042 0.021020 0.004843 -0.036543 -0.029041
+-0.023141 0.025949 -0.071411 -0.019207 0.007088
+0.038696 -0.038765 -0.019290 0.071608 0.100669
+0.002161 -0.019148 -0.033723 -0.110313 -0.048374
+0.036294 -0.011707 0.027523 -0.005146 -0.049367
+-0.011778 -0.100402 0.063310 -0.031106 0.021885
+-0.095761 -0.080098 0.004308 0.033965 -0.080439
+-0.023927 0.055660 0.007395 0.124410 -0.073291
+0.004189 0.060944 -0.045152 -0.060831 0.024748
+0.002404 -0.137119 -0.070340 -0.011515 -0.026093
+0.074911 -0.008646 -0.046756 0.070610 0.043733
+0.056208 -0.004307 -0.017910 -0.044341 -0.049322
+-0.031960 -0.031297 0.041787 0.064553 0.010380
+-0.009674 -0.056380 -0.131194 -0.102372 0.013069
+-0.040055 -0.101666 -0.095641 0.031396 -0.040243
+-0.044960 0.107223 -0.038146 0.043004 -0.091273
+0.008832 0.035095 0.018303 -0.033024 0.111336
+-0.012516 -0.088527 -0.138520 -0.042476 0.043839
+-0.066586 0.012378 -0.100214 0.030453 -0.045537
+-0.058136 -0.024370 0.006936 -0.057720 -0.111712
+-0.062832 -0.049461 0.055617 0.032267 -0.008208
+-0.024939 -0.062605 0.007490 -0.019889 -0.032406
+-0.002685 -0.018727 0.104523 0.024688 -0.046299
+0.058710 0.060194 0.045739 0.021202 -0.014056
+0.012044 0.058266 -0.001396 0.021628 0.093785
+-0.015184 0.056542 -0.100357 0.020669 0.075524
+0.037202 -0.028476 -0.004358 0.088662 -0.013431
+0.058653 0.069303 0.068988 0.033660 -0.062939
+0.018950 -0.056021 0.021534 -0.016087 0.075798
+0.048597 -0.010444 0.007248 -0.063630 0.010521
+-0.014106 -0.074996 -0.000773 0.053311 -0.048215
+-0.002735 -0.017992 -0.002647 0.020040 0.029636
+-0.022757 0.078272 0.023803 -0.057204 0.024134
+0.064828 0.052842 -0.109740 -0.016306 -0.097522
+0.035253 -0.097609 -0.069816 0.027249 0.039346
+-0.007883 0.014192 0.087185 -0.137182 -0.071137
+0.013525 0.010840 0.070855 0.012224 0.018564
+-0.008135 -0.046474 0.058225 -0.040550 -0.011424
+-0.027632 -0.035317 0.023198 0.038554 -0.081506
+-0.012968 0.096501 0.027391 0.100326 0.005492
+-0.058045 0.112112 0.002180 -0.025343 0.025626
+-0.099536 -0.061595 -0.061651 -0.027489 -0.010581
+-0.017782 -0.053973 -0.034355 0.078629 0.008211
+0.072702 0.071223 -0.044680 0.012444 -0.044745
+-0.139050 0.003441 0.000913 0.094752 0.048346
+-0.007363 0.025892 0.010184 -0.176655 0.133261
+0.001621 -0.024628 -0.030137 -0.007947 -0.085652
+-0.029719 0.022053 0.013686 -0.080132 -0.026124
+-0.070528 0.051163 0.066954 0.055796 0.025845
+-0.010124 -0.065017 -0.069344 -0.022724 -0.000369
+0.053467 0.016636 -0.040196 0.075376 -0.016667
+-0.029877 0.004811 -0.023632 -0.097696 0.009076
+0.002224 -0.010353 0.064867 -0.044772 0.077105
+-0.055734 -0.018593 0.032803 -0.059184 0.036008
+-0.007975 -0.100334 0.044830 -0.020643 -0.039421
+-0.010042 0.007773 0.099620 0.108164 0.029716
+0.078106 -0.011285 0.030783 0.081425 0.047785
+-0.040324 0.065464 -0.037268 -0.020200 -0.013981
+0.005168 0.027259 -0.021859 0.088221 -0.057304
+0.044425 0.092606 0.044230 -0.055754 -0.033767
+-0.019787 -0.048782 0.003298 0.018153 0.021226
+0.068475 -0.047841 -0.084262 -0.076417 0.054885
+-0.017738 -0.064677 -0.017373 -0.033227 -0.010808
+-0.146013 0.005243 -0.037539 -0.015601 0.022925
+-0.011193 0.044758 0.012972 -0.010808 0.024612
+-0.056295 0.056909 -0.080235 -0.047137 -0.029242
+0.056368 -0.002198 -0.035936 0.027306 0.075325
+-0.064563 0.000437 -0.011783 -0.026348 -0.005163
+0.082637 0.004076 0.084051 -0.032954 0.031309
+-0.006451 -0.094091 0.012843 -0.029321 0.020598
+0.015005 -0.014363 0.013016 0.075182 -0.086563
+-0.024242 0.085406 -0.009668 0.002995 0.003827
+0.027577 0.119405 -0.019147 0.005101 -0.010265
+0.032537 -0.051797 -0.040632 -0.068586 0.019971
+-0.056266 0.018425 -0.035550 0.044019 -0.018450
+0.013988 -0.007499 -0.030389 -0.047227 -0.036402
+-0.019853 -0.021715 0.089123 0.033422 0.051031
+-0.043643 0.004053 0.039026 -0.092898 0.069717
+0.002242 -0.073405 -0.022716 0.065550 -0.109492
+-0.065737 0.051307 -0.007900 -0.001899 -0.038721
+0.061064 0.068115 0.108020 -0.005186 0.091419
+0.038141 0.068502 -0.119719 -0.032776 -0.034200
+0.022829 0.022600 -0.114802 0.021444 0.011983
+-0.010708 0.025008 0.016734 -0.058795 -0.121062
+-0.020649 -0.036630 0.056523 -0.002163 0.027921
+-0.063293 0.012239 0.014511 0.034178 -0.056068
+-0.063080 0.014943 0.080895 0.063737 -0.133859
+0.016385 0.042840 0.046425 0.058005 0.035977
+-0.084512 0.057576 -0.010982 0.060681 0.072678
+-0.008045 0.001068 -0.085375 -0.058554 0.098160
+0.011639 0.009086 -0.053064 0.074379 -0.027243
+-0.013015 0.121189 0.047177 -0.009998 -0.034644
+-0.007092 -0.012841 0.075861 0.011568 0.086842
+0.045432 -0.079240 -0.025773 -0.009674 0.064448
+-0.018079 -0.118996 0.009565 -0.016846 -0.011029
+-0.006024 0.033095 0.005964 -0.000340 -0.012580
+0.081590 0.052148 -0.008312 -0.076947 0.027736
+0.018812 0.136957 -0.054412 -0.040884 -0.124297
+-0.047994 -0.081925 -0.033440 0.118449 0.044842
+0.004569 -0.006306 0.075165 -0.038914 -0.081500
+0.038445 -0.078834 0.047793 -0.013885 0.006954
+0.039465 -0.031245 0.038253 -0.039471 -0.057441
+0.034043 -0.029460 0.017171 0.000194 -0.094801
+0.013428 0.116396 0.026097 0.041725 0.007773
+-0.017706 0.115162 -0.031613 -0.010630 0.042917
+-0.039768 -0.139730 -0.048469 -0.000045 0.028945
+-0.004139 -0.081954 0.003386 0.115256 -0.049927
+0.077924 0.020540 -0.017751 0.003371 -0.011666
+-0.022988 -0.072458 0.027132 0.049961 0.112610
+0.047083 -0.041033 0.043690 -0.084367 0.071528
+-0.011307 -0.010002 -0.059736 0.049793 -0.043057
+-0.038207 0.109289 0.066216 -0.043249 -0.011953
+-0.042904 0.111380 0.021751 0.023150 0.051803
+-0.041532 -0.082754 -0.165799 -0.145192 -0.159015
+-0.036957 -0.008840 -0.028641 0.105964 0.006864
+0.029247 0.059193 0.009831 -0.144329 -0.047501
+-0.014033 0.041089 0.095670 -0.051674 0.049619
+0.031086 -0.026835 -0.015872 -0.041019 -0.016594
+-0.047321 -0.050941 0.108942 -0.059399 -0.094262
+-0.082008 0.021291 0.061910 0.073377 -0.015244
+0.057463 0.023209 -0.065966 0.034032 0.111775
+-0.021516 0.014300 -0.031041 -0.012892 0.024486
+0.045971 0.041949 0.025017 -0.003197 -0.044689
+0.046157 0.053074 -0.010276 -0.022357 0.014208
+-0.059017 -0.049325 0.007655 0.034365 0.071554
+0.043755 -0.026127 -0.068545 -0.041093 -0.027706
+0.042534 -0.059878 -0.006088 0.036135 -0.000512
+-0.141426 0.019792 0.031442 0.038225 -0.087692
+-0.006095 0.062862 0.064053 -0.026935 -0.004107
+-0.015518 0.018237 -0.054342 0.025962 -0.043604
+-0.041405 -0.044407 -0.066543 0.052842 0.123468
+0.018775 -0.097456 0.021557 -0.111244 -0.022276
+0.087995 0.020846 0.009786 -0.024442 -0.000924
+-0.021387 -0.115466 0.059505 -0.084840 -0.018622
+-0.039091 0.041857 -0.059951 0.027552 -0.106180
+-0.013005 0.077819 -0.057001 0.037112 -0.006017
+0.017069 0.035373 -0.036667 0.041547 0.030229
+-0.017543 -0.020408 -0.084738 -0.062925 -0.014286
+-0.003367 -0.001926 0.040560 0.163635 0.057733
+0.052600 0.014935 -0.041074 -0.038673 -0.009607
+0.035704 -0.049327 0.051517 0.079677 0.024194
+-0.021034 -0.014069 -0.062355 -0.078356 0.049042
+-0.028768 -0.088463 -0.035194 0.027880 -0.078732
+-0.051166 0.029644 0.064622 -0.002258 -0.067584
+0.014417 0.014299 0.025278 -0.095873 0.081486
+0.018230 -0.014653 -0.093112 -0.067755 0.006200
+-0.038621 0.033831 -0.065313 0.022443 0.016583
+-0.013554 -0.003383 -0.003813 -0.038565 -0.079906
+-0.054026 -0.097241 0.089312 -0.012968 0.081033
+-0.047581 -0.080574 -0.024559 -0.018898 -0.082106
+0.008601 -0.028523 0.100338 0.112593 -0.048526
+0.027421 0.024654 -0.000988 0.060571 -0.007538
+0.008276 0.041800 -0.035683 0.044325 0.088914
+0.019003 0.052585 -0.106627 -0.043862 0.018154
+0.061095 -0.055270 -0.060593 0.071565 -0.023743
+-0.010098 0.052293 0.067864 0.013882 -0.062200
+-0.017320 0.007520 -0.015594 -0.023894 0.092727
+0.029631 -0.013572 0.043058 -0.024937 0.054426
+-0.006383 -0.060407 0.031096 0.077251 -0.051193
+-0.028054 0.013443 -0.006446 0.025674 0.011140
+0.025108 0.078829 0.096347 -0.120869 0.009600
+-0.016833 -0.041386 -0.147598 0.012379 -0.080149
+-0.001507 -0.061584 -0.069511 0.053464 -0.028698
+0.050460 0.034750 0.053162 -0.062058 -0.000099
+0.013018 -0.014428 0.008787 -0.021213 0.031728
+0.032305 -0.106213 0.027220 -0.042487 -0.013001
+0.042839 -0.025383 -0.014866 0.006080 -0.055914
+-0.004772 0.111496 -0.048142 0.101228 -0.000113
+-0.007065 0.108619 -0.026644 -0.081066 0.026279
+-0.049199 0.003818 -0.043697 0.009844 0.051099
+-0.021007 -0.012906 -0.013888 0.109787 -0.054136
+0.054741 0.002659 -0.080186 0.041342 -0.004960
+-0.009585 -0.090940 0.035445 0.084784 0.071802
+0.004212 0.000051 0.061246 -0.179092 0.004524
+-0.066032 -0.062309 -0.052999 0.003717 -0.054731
+-0.063044 0.065802 0.005675 -0.083010 0.009338
+-0.050599 0.044865 0.069794 0.035892 0.069365
+0.077322 -0.037515 -0.101389 -0.032958 -0.023327
+0.004893 0.076975 -0.094625 0.108672 -0.084543
+0.029133 0.033581 -0.097391 -0.099645 -0.008470
+0.047506 0.014070 0.037599 -0.039370 0.027529
+-0.037487 -0.030513 0.001358 -0.109004 0.006393
+0.046480 -0.005807 0.072837 -0.015338 -0.034187
+-0.036067 0.007979 0.057660 0.043930 0.022410
+0.054219 -0.000956 0.022423 0.048054 0.091746
+-0.006642 0.030166 -0.048592 -0.040789 -0.005702
+0.007988 0.043955 -0.019103 0.106518 0.024012
+0.042589 0.059798 -0.006033 -0.026617 -0.048288
+0.015792 -0.114984 0.000601 -0.000354 0.067489
+0.038969 0.014313 -0.064460 -0.002179 0.051347
+-0.002092 -0.105852 -0.031092 -0.032437 -0.000174
+-0.128927 -0.008284 -0.009141 -0.076672 -0.015283
+-0.049413 0.056280 0.045565 -0.006905 0.022082
+-0.085801 0.050952 -0.050910 -0.017483 0.005888
+-0.006170 -0.061465 -0.030951 0.035802 0.015739
+-0.083792 -0.044795 0.060723 -0.030343 -0.069566
+0.030676 0.038387 0.050804 0.004892 0.017579
+-0.044803 -0.090476 -0.017970 -0.069598 0.035520
+0.006056 0.044354 -0.061744 0.058806 -0.130744
+-0.057101 0.099578 -0.045874 -0.002499 0.046826
+0.049723 0.098173 -0.082881 0.073610 -0.011594
+-0.009669 -0.094859 -0.037445 -0.119323 0.065051
+-0.015284 -0.026778 0.005845 0.048246 0.025717
+0.028300 0.003404 -0.007273 -0.021871 -0.079752
+-0.013062 -0.126858 0.059483 0.049526 0.036093
+-0.056998 -0.003159 -0.043116 -0.016197 0.089723
+0.016100 -0.051512 -0.060459 0.061427 -0.060520
+-0.010836 0.070291 -0.004533 0.015834 -0.031588
+0.046681 0.024603 0.057986 -0.000132 0.098934
+-0.017240 0.002476 -0.113392 0.016989 0.001335
+-0.009243 0.021430 -0.088867 0.016496 0.036539
+-0.024722 0.027988 -0.025209 -0.037811 -0.070416
+-0.027312 -0.042762 0.085979 -0.017748 0.001795
+-0.038652 -0.032652 0.049244 -0.003571 -0.092866
+0.021843 -0.080697 0.081009 0.019897 -0.063178
+0.025596 0.016382 0.119656 0.092436 -0.016244
+-0.023622 -0.006095 -0.013438 0.039393 0.098847
+0.026872 0.057469 -0.033557 -0.019961 0.171557
+0.009244 -0.003066 -0.087323 0.039711 -0.024124
+0.027198 0.088494 0.108382 0.011044 -0.127500
+-0.035575 -0.083203 0.035144 -0.032137 0.120334
+0.002031 -0.020743 0.003890 -0.046130 0.060318
+-0.032118 -0.093914 0.036450 0.036482 -0.003628
+-0.045976 -0.020514 0.020744 0.028721 0.002437
+0.114939 0.051708 0.055899 -0.024311 0.024351
+-0.064421 0.084144 -0.108787 0.030475 -0.042867
+0.008077 -0.063222 -0.026071 0.061247 -0.016598
+0.011100 0.007787 0.023799 -0.068735 -0.056142
+0.025938 -0.060156 0.050084 0.037444 -0.022008
+0.010303 -0.098972 -0.052827 -0.061667 -0.068986
+-0.011902 -0.042759 -0.084042 -0.002067 -0.151469
+-0.017637 0.134014 -0.026226 0.026110 0.007490
+0.021463 0.079145 0.014098 -0.019123 0.079837
+-0.010640 -0.040407 -0.116967 -0.015889 0.022180
+-0.005119 -0.014871 0.057013 0.068658 -0.079078
+0.058641 -0.006509 -0.034086 -0.022005 0.041557
+0.016029 -0.003335 0.062705 0.037826 0.092035
+0.047014 0.007296 -0.014070 -0.130533 -0.001078
+0.025557 -0.063677 -0.037435 0.030993 -0.040663
+-0.133077 0.001203 0.087675 -0.028956 0.005954
+0.030377 0.094103 0.031530 0.029501 0.058250
+0.043750 0.005780 -0.081652 -0.046912 -0.071344
+0.049909 -0.017203 -0.105850 0.077672 0.063239
+0.015203 0.080354 -0.019175 -0.126004 0.012938
+0.004638 -0.013389 0.087621 -0.010466 0.023940
+-0.002703 -0.035427 -0.059936 -0.035946 0.018749
+0.025763 -0.100231 0.035256 0.021093 -0.102097
+-0.023912 0.065319 0.051327 0.052308 0.008324
+0.018600 0.027370 -0.019629 0.003753 0.074711
+-0.009465 0.042899 -0.007945 -0.044091 0.057014
+0.043860 0.063015 -0.053778 0.033882 -0.018588
+-0.007623 0.070289 0.017506 -0.028443 -0.016436
+-0.016131 -0.087520 -0.000211 0.013207 0.081102
+0.026870 0.010280 -0.039354 -0.085402 0.005385
+0.045387 -0.075274 0.005158 0.013437 -0.061107
+-0.123832 -0.006790 0.046660 0.021633 0.005414
+-0.004335 -0.011498 0.029755 -0.025547 -0.002465
+0.008431 0.032361 -0.039776 0.018846 -0.007647
+-0.002531 -0.054317 -0.034538 0.095049 0.040090
+-0.016239 -0.046115 0.006000 -0.083863 -0.018887
+0.001956 -0.005777 0.053960 0.003049 -0.028290
+-0.017755 -0.044904 0.084936 -0.038020 0.048751
+-0.036897 -0.069299 0.003508 0.029780 -0.079610
+-0.085660 0.060685 -0.006321 0.078501 0.006878
+-0.000940 0.062341 -0.042279 -0.015673 0.013762
+-0.029805 -0.051092 -0.117256 -0.046978 -0.012383
+0.024326 -0.000611 -0.046838 0.087711 0.032932
+0.089398 -0.013201 -0.035642 -0.013591 -0.019974
+0.002673 -0.016622 0.070976 0.074861 0.005584
+0.013705 0.013057 -0.070513 -0.132482 0.011905
+-0.021242 -0.092172 -0.098335 -0.045995 -0.077946
+-0.013171 0.148310 0.023267 -0.011841 -0.094360
+-0.008329 0.001195 -0.000926 -0.099253 0.141073
+0.039201 0.001784 -0.135018 -0.082677 0.044641
+-0.005949 -0.030037 -0.085312 0.049127 0.014847
+-0.013469 -0.002593 -0.056090 -0.045962 -0.191274
+-0.041064 -0.030590 0.082413 0.061704 0.022132
+0.035533 -0.066234 0.034454 -0.009588 -0.050467
+-0.029761 -0.016491 0.067872 0.038969 -0.039014
+0.057543 0.047087 0.043850 0.039443 0.054508
+0.058856 0.109195 -0.043374 0.070615 0.089501
+0.024405 0.045632 -0.080334 -0.004657 0.067992
+0.068464 -0.013325 0.052791 0.040606 -0.016031
+0.043482 0.025913 0.030708 0.051020 -0.058413
+0.012923 -0.031961 -0.001425 0.025659 0.065492
+0.081425 -0.018210 0.009682 -0.008238 0.027227
+-0.047221 -0.123710 0.027984 0.046569 -0.051906
+-0.013099 -0.010653 -0.030766 0.027285 0.060770
+-0.039564 0.053122 0.066810 -0.114075 0.054466
+0.054259 0.024216 -0.045685 -0.001518 -0.082578
+-0.026337 -0.055608 -0.075956 0.054064 0.026871
+0.015694 0.016757 0.129806 -0.052800 -0.016678
+0.048569 -0.001337 0.027199 0.004454 0.027064
+0.019218 -0.065149 0.034752 -0.071056 -0.047284
+-0.001601 -0.021741 0.012135 -0.006775 -0.080880
+-0.033474 0.068299 0.002424 0.082260 0.038960
+-0.030455 0.105682 0.013086 -0.054492 0.067646
+-0.084988 -0.031769 -0.005191 -0.045479 0.025036
+-0.054564 -0.097375 0.013290 0.107239 -0.037042
+0.136211 0.054048 -0.044849 0.071688 0.021370
+-0.065162 -0.020715 -0.035790 0.090635 0.057812
+-0.008215 0.061018 -0.000019 -0.085259 0.052848
+-0.027541 -0.005643 -0.052940 -0.038511 -0.027902
+-0.041703 0.075862 0.013165 -0.059187 -0.036318
+-0.141024 0.082443 0.069711 -0.013203 0.014406
+0.030125 -0.045500 -0.041806 0.002497 0.025155
+0.017453 0.003895 -0.083765 0.104400 0.011102
+-0.048345 0.018909 -0.030988 -0.072003 -0.023689
+0.039778 -0.011208 0.089401 -0.003381 0.064581
+-0.037057 0.017900 0.009406 -0.035557 0.007209
+-0.003241 -0.108553 0.107998 -0.002787 -0.041577
+-0.001725 0.010872 0.036545 0.091885 0.044958
+0.069362 -0.032205 0.088568 0.031341 0.039043
+0.010331 0.015777 -0.034748 -0.023237 0.005678
+0.045804 0.043555 0.039834 0.109120 -0.055790
+-0.015894 0.100543 0.050280 -0.072103 -0.045188
+-0.011023 -0.045609 0.030003 -0.010336 0.063708
+0.019876 0.039063 -0.034557 -0.076987 0.129728
+0.030980 -0.069793 0.006613 -0.009915 -0.020373
+-0.069965 0.002061 0.000541 -0.052867 0.092944
+0.006017 0.032142 0.001437 0.012183 0.032717
+-0.116354 0.039141 -0.103482 -0.032555 -0.058604
+0.051576 -0.057991 -0.087256 0.032997 0.087854
+-0.040337 -0.024261 0.038911 -0.077252 -0.039797
+0.081800 0.001805 0.100735 0.013940 0.003214
+-0.061214 -0.144295 0.008308 -0.079288 0.011819
+-0.009353 0.021735 0.041214 0.036036 -0.075607
+-0.035037 0.053300 0.014234 0.024169 0.037498
+0.041347 0.073833 -0.068231 -0.042470 0.014760
+0.033778 -0.058964 -0.006533 -0.067729 -0.003610
+-0.018476 0.009825 -0.029418 0.050496 0.036382
+0.060848 0.025206 -0.004172 -0.075537 -0.012303
+-0.004545 -0.052962 0.118191 0.014623 0.029139
+0.011171 0.016876 -0.013963 -0.059052 0.080971
+0.002827 -0.003879 -0.049140 0.078897 -0.085060
+-0.088602 0.131228 0.004221 -0.011391 -0.071427
+0.017718 0.070627 0.054229 -0.044273 0.070835
+0.025214 0.000275 -0.196338 -0.055537 -0.009349
+0.028434 0.030911 -0.087382 0.065504 0.032241
+0.011778 0.089297 0.008448 -0.051996 -0.159620
+-0.008923 -0.062831 0.056001 0.025205 -0.012758
+-0.071953 -0.005149 0.018063 -0.014935 -0.030631
+0.013403 0.008570 0.080274 0.062037 -0.129636
+0.011472 0.077844 0.062828 0.098467 0.066360
+-0.086768 0.078864 0.029290 -0.000317 0.128502
+0.004070 -0.025683 -0.096323 -0.046173 0.149402
+0.030056 -0.030776 -0.044512 0.070740 -0.008688
+0.014318 0.073530 0.097921 0.001865 -0.050654
+-0.033176 -0.025587 0.089396 -0.054027 0.105766
+0.000104 -0.058115 -0.051152 -0.028157 0.079932
+-0.060212 -0.086791 0.029739 -0.006208 -0.054993
+-0.004691 0.017634 -0.011116 0.051677 -0.039065
+0.062654 0.079876 0.012684 -0.029185 -0.019667
+0.012281 0.089665 -0.044542 0.013976 -0.055887
+-0.029754 -0.078267 -0.023077 0.060156 0.047758
+-0.017389 0.027009 0.061441 -0.041074 -0.115783
+0.058611 -0.060866 0.113852 0.028394 -0.032204
+0.051306 -0.045035 0.012411 -0.104662 -0.067768
+0.005348 -0.053385 0.029868 0.023673 -0.127300
+0.010816 0.112224 -0.017053 0.061578 -0.040140
+0.049130 0.081442 -0.020925 -0.013124 0.049795
+0.000088 -0.080273 -0.041920 -0.006154 0.026384
+-0.017665 -0.029077 0.028767 0.109973 -0.064974
+0.016728 0.012762 -0.017789 -0.018455 -0.027535
+-0.026842 -0.082729 0.081654 0.058251 0.101281
+0.008607 -0.074243 0.030006 -0.114336 0.077834
+-0.042818 -0.047540 -0.040810 0.016980 0.009716
+-0.019924 0.025318 0.094241 -0.026210 -0.040988
+0.003781 0.101619 0.098932 0.076552 0.025069
+0.010124 -0.042034 -0.095420 -0.072274 -0.061223
+-0.025071 -0.016132 -0.047999 0.172624 -0.036838
+0.011581 0.054710 -0.035830 -0.120277 -0.100100
+-0.057028 0.006910 0.118464 -0.022154 0.025012
+-0.017797 -0.033263 -0.008283 -0.003727 -0.043563
+-0.003699 -0.095741 0.060120 -0.083925 -0.090614
+-0.052209 0.069252 0.084102 0.031573 -0.065150
+0.048194 0.013857 -0.000901 0.082968 0.075239
+-0.023543 -0.017918 -0.034752 -0.020715 0.045946
+0.025948 0.035884 -0.001330 0.030377 -0.069708
+0.037228 0.064584 -0.011534 0.004775 -0.031321
+-0.023894 -0.066680 -0.017407 -0.031766 0.082944
+0.029780 -0.020334 -0.059467 -0.105484 -0.011107
+0.107375 -0.081264 -0.085535 0.015847 0.011785
+-0.147292 0.091983 -0.035194 0.018371 -0.019603
+0.000643 0.026524 0.033881 -0.031605 -0.026151
+-0.015905 0.025076 -0.040237 -0.015447 -0.036770
+-0.023092 -0.008956 -0.094738 0.052213 0.066411
+-0.014003 -0.038628 0.067782 -0.113461 -0.048569
+0.077947 -0.029368 0.029847 0.032522 -0.053873
+-0.009694 -0.066035 0.097838 -0.080553 0.014786
+-0.041721 0.042424 -0.067096 0.086017 -0.083068
+-0.031687 0.049261 0.011088 0.055956 -0.042553
+0.064152 0.032740 -0.042521 0.032623 0.026468
+-0.060446 -0.061420 -0.040101 -0.072435 -0.035127
+-0.015938 -0.056502 -0.012235 0.159594 0.036828
+0.014961 0.039926 -0.052046 -0.008302 -0.025221
+-0.019677 -0.050264 0.064556 0.090868 0.045306
+-0.056054 0.027715 -0.051663 -0.105423 0.043022
+0.028868 -0.059945 -0.078316 -0.022563 -0.067438
+-0.015459 0.051782 0.012461 -0.017353 -0.111666
+0.047354 0.038969 0.018721 -0.042239 0.086618
+0.047663 -0.009423 -0.062622 -0.054796 0.027821
+-0.055863 0.015206 -0.063846 0.042120 0.051280
+0.000880 -0.064353 -0.006378 -0.079885 -0.085024
+-0.060682 -0.023010 0.052677 0.020476 0.036878
+-0.022570 -0.097679 0.024609 -0.051637 -0.023871
+0.018994 -0.008905 0.163821 0.035607 -0.004083
+0.029753 0.070722 0.065015 0.036317 0.015253
+-0.018487 0.021981 -0.052297 0.101195 0.046329
+-0.018899 0.076923 -0.090549 -0.069408 0.052880
+0.072613 0.016603 0.009898 0.038810 -0.097531
+0.011528 0.033681 0.044555 0.022445 -0.040337
+-0.006570 0.016912 0.017289 -0.010643 0.054567
+0.039843 -0.082038 0.051662 -0.036190 0.056489
+-0.013943 -0.108354 0.074006 0.095726 -0.069664
+-0.034176 -0.043247 0.007026 -0.014616 0.018185
+0.005567 0.064569 0.062030 -0.061575 0.033160
+0.003638 0.043355 -0.092562 -0.001359 -0.118802
+0.034657 -0.080892 -0.115509 0.051575 -0.016477
+0.073726 -0.028197 0.101744 -0.091687 -0.002308
+0.003490 -0.025382 0.023563 0.013144 -0.007840
+0.098021 -0.089215 0.043236 -0.056307 0.013368
+0.056472 0.016004 0.007337 0.008555 -0.046066
+-0.000940 0.088476 -0.003382 0.056229 0.011333
+0.025841 0.126240 -0.050253 -0.071801 -0.036593
+-0.113256 -0.027423 -0.077799 -0.003365 0.042368
+-0.007708 -0.040673 -0.002409 0.091194 -0.002389
+0.089456 -0.007822 -0.034486 0.016810 0.021491
+-0.021203 -0.054528 0.050001 0.028679 0.059435
+-0.034908 0.003863 0.053342 -0.072845 0.001339
+-0.054033 0.012885 -0.065048 -0.045609 -0.058860
+-0.076548 0.032086 0.025364 -0.136995 -0.019692
+-0.014073 0.049843 0.053275 -0.021054 0.051495
+0.005986 -0.032989 -0.055326 -0.031727 -0.023301
+0.052516 0.011953 -0.114987 0.050477 -0.086649
+0.029069 0.034181 -0.055159 -0.036203 -0.045128
+0.001147 -0.008622 0.073690 -0.077472 0.037649
+-0.023539 -0.019114 0.007866 -0.053950 0.029809
+0.002350 -0.026481 0.147821 -0.047601 -0.036813
+-0.037253 0.033533 0.027495 0.047206 -0.008682
+0.052569 -0.038196 0.009663 -0.000160 0.096707
+-0.058192 0.000390 -0.047017 -0.034486 0.014275
+0.016853 0.040124 0.061386 0.115421 0.015532
+0.083606 0.081646 -0.014130 -0.065768 -0.049301
+0.046979 -0.074307 -0.000569 0.043637 0.041337
+0.036121 0.073310 -0.066751 -0.075889 0.042658
+-0.033533 -0.145897 0.036198 0.008869 -0.000721
+-0.096931 0.083547 -0.053221 -0.059850 0.044181
+-0.047437 0.017891 0.054674 -0.007182 -0.021841
+-0.057955 0.025656 -0.022698 0.003117 0.006525
+0.054665 -0.016601 -0.070885 0.038416 0.036323
+-0.106994 -0.070705 0.076054 -0.096182 0.017493
+0.019099 0.040334 0.095834 0.024157 -0.012504
+-0.036345 -0.054321 0.024473 -0.042893 0.045064
+0.020362 0.013309 -0.022876 0.136195 -0.126968
+-0.008470 0.104812 -0.060638 0.042024 0.051826
+-0.046516 0.068780 -0.166211 0.010537 -0.020067
+-0.016696 -0.031551 -0.045680 -0.140254 0.023460
+0.019033 -0.007193 0.020098 0.033574 0.032849
+-0.009729 0.029711 0.035164 -0.031548 -0.069463
+-0.068795 -0.076409 0.084793 0.058786 0.033407
+-0.055633 0.057879 -0.064890 -0.085820 0.141134
+-0.032456 -0.044056 -0.052030 0.080704 -0.065311
+-0.029210 0.031372 -0.005285 0.001060 -0.066081
+-0.002741 0.043095 0.081838 0.016630 0.083339
+-0.027374 -0.002893 -0.096649 -0.007570 -0.027971
+0.023363 -0.012161 -0.079953 0.015753 0.010524
+0.011885 0.035772 -0.053325 -0.031173 -0.135173
+-0.008628 -0.004336 0.065589 -0.022764 -0.012130
+-0.022211 -0.014175 0.049009 -0.008368 -0.051407
+0.003391 -0.045775 0.040152 0.019404 -0.076654
+-0.003267 0.015085 0.089489 0.060779 0.030779
+-0.008577 0.025139 -0.005374 0.038636 0.058301
+0.018353 -0.010357 -0.012618 -0.013865 0.082768
+0.012199 -0.031424 -0.049425 0.036742 -0.023385
+0.016261 0.046336 0.082459 -0.046018 -0.072305
+0.007065 -0.052342 0.072695 -0.082325 0.056070
diff --git a/codec2/branches/0.7/src/codebook/lspvqexp3.txt b/codec2/branches/0.7/src/codebook/lspvqexp3.txt
new file mode 100644 (file)
index 0000000..04cd64b
--- /dev/null
@@ -0,0 +1,2049 @@
+5 2048
+-0.136198 0.024151 -0.063695 0.003294 0.028292
+0.058532 0.000407 0.081822 0.109613 0.092702
+0.002289 -0.004336 -0.001953 0.032305 -0.008448
+-0.035198 -0.023077 -0.052002 -0.025974 -0.085171
+0.004385 -0.026216 -0.018253 -0.018256 0.012774
+0.006358 0.026024 -0.087778 0.011771 -0.078083
+0.007874 0.003175 -0.052089 0.064003 -0.042512
+0.014535 0.006232 -0.033255 -0.045854 -0.107260
+0.004491 0.019560 0.061050 0.029138 0.036281
+-0.078731 -0.044440 -0.048337 -0.025092 0.081402
+-0.007244 -0.049045 0.058090 0.066585 0.018635
+-0.075770 0.063007 -0.000503 -0.135694 -0.037603
+-0.054068 -0.104063 0.005153 0.006977 0.008814
+-0.020893 -0.019060 -0.070042 0.004665 0.090232
+-0.015010 0.032240 0.000378 -0.002297 0.004771
+-0.040127 -0.041383 0.105462 -0.015007 -0.029958
+0.009637 0.050721 -0.064000 0.070794 -0.027916
+0.001217 -0.095625 0.095422 -0.058274 0.030180
+0.047937 -0.040794 -0.018864 0.036107 -0.038520
+-0.035711 -0.046199 -0.031081 -0.090591 -0.073785
+0.068495 -0.021466 0.055625 0.027533 -0.056869
+0.059775 -0.041632 -0.096969 -0.057469 -0.082582
+0.076556 -0.075055 0.014253 -0.024721 -0.110025
+0.039510 0.002922 0.001583 -0.081297 -0.054432
+0.036638 0.106348 -0.029202 0.053259 0.060782
+-0.053679 0.039323 0.097200 0.001035 0.086560
+-0.023819 -0.121783 -0.029909 0.046493 -0.020142
+0.049289 0.084407 0.081999 -0.002632 -0.023474
+-0.049136 -0.022296 0.090649 0.036711 -0.056647
+0.006248 0.061232 0.007889 -0.075399 0.015312
+0.057416 0.103818 -0.016070 0.040505 -0.001189
+0.114331 -0.090671 0.090784 0.004698 -0.078036
+-0.096890 0.084786 0.041716 0.042491 -0.057462
+-0.014909 -0.032684 0.071338 -0.025083 0.051331
+0.050537 -0.069533 -0.037126 0.032846 0.025729
+-0.047775 0.055988 -0.018972 -0.025690 -0.027975
+-0.017970 0.023020 0.098593 0.004612 0.013157
+0.044770 0.015091 -0.069310 -0.062427 -0.021413
+-0.022487 0.105120 0.052485 0.089068 -0.015127
+-0.069327 -0.005520 -0.039356 -0.065169 -0.081883
+0.077729 0.024051 0.008893 0.135290 0.036535
+-0.016512 -0.061216 -0.051545 0.019876 0.044939
+-0.119244 -0.030603 -0.021134 0.038262 0.002980
+-0.079101 0.080099 0.036993 -0.067815 -0.008885
+-0.054560 -0.014317 0.093316 0.100385 -0.001690
+0.052346 -0.004258 -0.013592 -0.042301 0.049842
+0.092826 0.061851 0.027621 -0.024069 -0.059213
+0.031617 -0.009108 0.022338 -0.063250 -0.097158
+-0.008177 -0.030577 -0.107136 0.017774 0.059538
+-0.053438 0.008281 -0.008953 -0.207584 0.041500
+0.006693 -0.093889 -0.039108 0.040752 0.020200
+0.005813 -0.021241 -0.046317 -0.019980 -0.037740
+0.134550 0.018885 -0.020492 0.033445 -0.004411
+0.000456 -0.030901 -0.058047 -0.081834 -0.007611
+0.006314 0.008851 0.070179 0.003036 -0.035749
+0.067106 -0.087172 0.047680 -0.058147 -0.011858
+-0.043608 -0.020841 0.038136 -0.031081 0.185361
+-0.054055 -0.067146 0.097240 -0.082580 0.051439
+0.003624 -0.133423 0.011530 0.119056 -0.043475
+-0.001737 0.110875 0.038530 -0.027030 0.053434
+0.000648 -0.029320 0.121211 0.029589 -0.039707
+-0.068850 0.000408 -0.032227 -0.003072 0.052231
+0.034923 0.080837 -0.037156 -0.094754 0.014542
+-0.005315 -0.054038 0.012812 -0.027090 -0.001601
+-0.083437 0.019212 -0.016505 0.046104 0.038554
+0.072309 -0.011739 0.059850 -0.056206 0.073386
+0.135263 0.000286 -0.060518 0.036391 -0.060506
+-0.027527 -0.000692 0.036739 -0.066074 -0.088864
+0.005166 -0.054854 -0.003007 -0.010121 0.027824
+-0.036967 -0.100932 -0.182594 -0.013910 0.014657
+0.023979 0.055629 -0.054566 0.106056 -0.079044
+-0.037983 -0.044929 0.043735 -0.085774 -0.009132
+-0.024985 -0.071464 0.051902 0.102450 0.054042
+-0.016588 -0.074683 -0.064110 0.056690 0.110680
+-0.064499 -0.033720 0.024264 0.088022 0.031179
+-0.015453 0.035079 0.044771 -0.043409 -0.047855
+0.078062 -0.091048 0.052298 0.018898 0.005019
+-0.054365 0.080023 -0.065458 -0.065704 0.014520
+-0.003386 0.001319 -0.046118 -0.010700 0.008233
+-0.030496 -0.072516 0.051522 -0.020414 -0.101831
+0.017761 0.038077 -0.114244 0.041726 0.083964
+-0.016531 -0.129688 -0.014288 -0.122167 0.063062
+0.116380 -0.065367 -0.038604 0.095723 -0.036360
+-0.066306 0.014726 -0.011596 -0.005770 -0.048796
+0.090592 -0.004417 0.009466 0.098691 -0.066093
+0.001754 -0.005848 -0.043066 -0.037892 0.031807
+-0.022616 -0.021159 0.045873 0.028421 -0.085595
+0.049794 -0.001914 0.008752 -0.077905 0.029994
+0.044235 0.064398 0.005282 -0.003674 0.086059
+-0.032460 0.015037 -0.007206 -0.036713 0.011909
+-0.017113 -0.061523 -0.001698 0.001480 -0.052389
+-0.005496 0.081887 0.018394 0.005492 -0.048520
+-0.036485 0.006979 0.121328 0.069020 -0.093697
+-0.035414 0.025382 0.033335 -0.042742 0.078618
+0.022150 0.100313 -0.081797 -0.006077 -0.036600
+0.043498 -0.047693 0.080861 -0.041208 -0.074855
+-0.034519 0.006730 0.150509 0.059429 -0.003976
+-0.059532 -0.022218 0.071419 -0.051453 0.008904
+0.063565 -0.107466 -0.026643 -0.009845 0.097906
+-0.094940 0.057756 -0.085002 0.019603 -0.098395
+0.015610 0.000806 0.058999 -0.025760 0.036316
+0.071066 0.030579 -0.066243 -0.023751 -0.060747
+0.067731 0.090313 0.041003 0.076536 -0.012685
+0.069395 0.035647 -0.112161 -0.075184 0.003099
+-0.017065 0.018376 0.017104 0.109557 0.049888
+-0.047698 -0.041877 -0.000537 0.051347 -0.003682
+-0.016370 -0.001696 -0.010154 0.067477 -0.036583
+-0.020092 0.048256 0.084878 -0.100501 -0.035380
+0.008671 -0.122585 0.038716 -0.002197 -0.101482
+0.037247 -0.032842 -0.068559 -0.021387 0.014449
+0.027927 0.060964 -0.048375 0.028367 0.038134
+-0.014885 -0.092447 -0.081616 -0.015822 -0.134913
+-0.021274 0.013697 -0.035055 0.055911 0.033111
+-0.034970 -0.015798 -0.007119 -0.076467 0.028984
+-0.014502 -0.124275 0.021441 0.078607 0.002858
+-0.042356 -0.003098 0.045995 0.031341 -0.016968
+0.041560 0.019148 0.004700 0.005637 0.093016
+0.063490 -0.048735 -0.069068 -0.034088 -0.028215
+0.045350 0.075594 0.037776 0.024450 -0.071678
+0.087072 0.009286 -0.023885 0.019862 -0.012771
+-0.029248 -0.016036 -0.089092 0.074240 0.169069
+-0.033409 0.026100 -0.024626 -0.043863 0.098736
+0.012158 -0.077333 -0.083731 0.013768 -0.080944
+-0.060470 0.037407 -0.013690 0.007337 -0.001188
+0.005453 0.026261 0.119036 0.043940 0.046011
+-0.035860 0.008540 -0.113766 -0.097502 0.024057
+0.024457 0.118827 -0.001543 -0.064711 -0.007631
+0.049637 -0.101928 -0.002462 0.054230 -0.044736
+-0.067470 0.078729 -0.034003 0.014536 -0.022247
+0.161762 -0.041209 0.037097 -0.052532 -0.031344
+0.061129 0.020176 -0.066030 0.038964 0.022928
+-0.014012 -0.030939 -0.092443 0.002874 -0.114395
+-0.010621 -0.005537 0.018042 -0.045648 0.044588
+0.007453 0.095088 -0.128336 0.107088 -0.032186
+-0.047594 0.046694 0.039679 0.083442 -0.088060
+0.060757 0.082896 0.037419 -0.092975 -0.054674
+0.022723 -0.030652 0.025581 0.033843 0.085935
+-0.020876 -0.055952 -0.103915 -0.073020 0.045301
+0.020552 0.047020 0.047981 0.150138 -0.041783
+-0.081206 0.015811 0.025886 -0.105666 0.097623
+-0.026606 -0.109640 0.031300 -0.029835 0.007132
+-0.004757 0.036673 -0.113804 -0.044055 0.015492
+0.016617 0.050138 -0.020709 0.070749 0.016487
+-0.041772 -0.059857 0.040483 0.002005 -0.030924
+0.045135 0.114146 -0.077004 0.040268 0.014157
+-0.007526 -0.029177 0.064663 -0.093478 0.103127
+0.041264 -0.004835 0.013205 0.110399 -0.026498
+-0.107188 -0.024533 -0.071115 -0.052007 -0.006395
+0.030684 -0.035133 0.019891 0.033587 -0.028437
+-0.019472 -0.016122 -0.099020 -0.052317 -0.029623
+0.023893 -0.019150 0.042703 -0.007384 -0.135429
+-0.008658 0.020311 0.016085 -0.113980 -0.001115
+-0.036113 0.054423 0.008653 -0.007789 0.077924
+-0.129044 -0.005070 0.011282 0.013904 0.077014
+-0.025623 -0.031789 -0.073370 0.010481 -0.041819
+0.008182 0.065192 0.027333 -0.034730 -0.026375
+-0.073571 -0.019647 0.040694 -0.003020 -0.065061
+-0.014276 0.079966 0.003562 -0.144068 0.054787
+-0.022846 0.071080 -0.036877 -0.012692 -0.082166
+-0.006918 -0.096688 0.095501 0.064056 0.007213
+-0.036690 0.026213 0.059957 0.047896 0.003414
+0.000914 0.015446 0.098563 -0.056379 0.137143
+0.018164 -0.076211 -0.070196 0.001563 0.047637
+-0.049087 0.114850 -0.090803 -0.012260 -0.036278
+0.029559 0.002293 0.037244 0.047064 0.038113
+0.070849 0.065524 -0.021498 0.000989 -0.091111
+-0.036143 0.076107 0.016355 0.059505 -0.023400
+-0.048163 0.004599 0.025481 -0.093492 -0.022306
+0.020409 0.023572 -0.001520 0.059761 0.064734
+-0.032331 -0.014971 -0.032497 -0.010585 0.008900
+-0.085173 -0.038940 0.017863 0.073312 -0.032050
+-0.026419 0.012730 0.067669 -0.005028 -0.054256
+-0.019721 -0.049805 0.080959 0.050680 0.057457
+-0.006579 -0.003248 -0.080847 -0.103158 0.064238
+0.082133 0.070334 -0.026602 -0.064571 0.042901
+0.017513 -0.081866 -0.016501 -0.088344 0.022655
+0.009335 -0.047461 -0.005181 0.060236 0.032349
+-0.056626 -0.022179 -0.044705 -0.131625 -0.028104
+-0.026924 -0.045874 0.036424 0.026185 0.023864
+-0.028118 -0.018505 0.018550 0.000643 -0.055726
+0.101839 -0.037958 0.031116 0.110118 0.009110
+0.112021 -0.038578 -0.104082 -0.042272 0.040893
+0.028742 -0.028607 0.080643 0.003287 -0.063413
+0.099046 -0.029956 0.002892 -0.067344 -0.016823
+0.008602 0.017513 -0.014264 -0.041185 0.124856
+-0.054844 -0.072185 0.033952 -0.096401 0.046007
+-0.020749 -0.046471 0.003558 0.082125 -0.096910
+0.025411 0.127329 0.076666 0.068718 0.005743
+0.043603 -0.056968 0.086610 0.010153 -0.036367
+-0.068722 0.024772 -0.000639 -0.052051 0.074796
+0.019967 0.077602 -0.034771 -0.009789 -0.023551
+0.047117 -0.066717 -0.066348 -0.063558 0.008220
+-0.027567 0.036273 -0.067110 0.028847 0.089473
+0.083247 0.004591 0.077405 -0.082932 -0.013968
+0.079836 -0.052437 -0.080184 0.015535 0.000867
+-0.020465 0.038101 0.029256 0.027121 -0.094745
+0.022846 0.000927 0.004314 -0.039488 0.016252
+-0.016129 -0.000925 -0.125901 0.037569 -0.012151
+0.050660 0.036394 -0.018283 0.058805 -0.009276
+0.002687 -0.029775 -0.002892 -0.018790 -0.068265
+-0.026723 -0.038695 0.067644 0.027095 0.104267
+-0.033127 -0.092325 -0.101391 0.051657 0.047692
+-0.039487 0.017442 -0.007204 0.106333 -0.026736
+-0.026984 0.048252 0.041384 -0.002131 0.042443
+0.019367 -0.077827 0.019452 -0.004992 0.095049
+-0.020183 0.054128 -0.089501 -0.106767 0.133742
+0.003715 0.065993 -0.010120 0.002578 0.010632
+-0.104027 -0.092526 0.051102 -0.064092 0.007341
+0.037981 0.005348 -0.098388 0.082010 0.023682
+0.101454 -0.074181 0.022470 -0.047488 0.034728
+0.054519 -0.059484 -0.055491 0.133582 0.009556
+-0.120963 -0.043837 0.028549 0.025534 0.028904
+0.108670 -0.032038 0.012596 0.038519 -0.012244
+0.003888 0.019393 -0.076558 -0.013031 -0.019858
+-0.006786 -0.020230 0.044975 0.034040 -0.032445
+0.099970 -0.025120 -0.012044 -0.058520 0.081664
+-0.018743 0.028691 0.017459 0.030523 0.121595
+-0.045728 -0.044359 0.002157 0.025037 0.043565
+-0.027940 -0.112422 0.019525 0.012089 -0.036526
+0.012809 0.102396 0.061700 0.009053 -0.006318
+-0.073644 0.052544 0.093009 0.002094 -0.048500
+-0.067838 0.044219 0.004622 -0.021517 0.144798
+0.000396 0.028552 -0.047957 0.022072 -0.044059
+0.022301 -0.046990 0.069399 -0.022723 0.001209
+-0.061132 0.035083 0.054456 -0.053667 0.023348
+-0.021700 0.035612 0.078641 -0.067377 0.046902
+0.103671 -0.042167 -0.039490 0.027663 0.018158
+-0.034924 0.044647 -0.017309 0.013019 -0.075672
+0.016417 0.018863 -0.005962 -0.054108 -0.028444
+0.033930 -0.024540 -0.021060 0.018088 -0.079446
+0.004808 0.042524 0.042005 0.062594 -0.020936
+0.045898 -0.007873 -0.067501 -0.079291 -0.053730
+-0.044782 0.007470 -0.003636 0.041779 0.032024
+-0.055764 -0.025299 -0.042428 0.043255 0.061536
+-0.028270 0.031312 -0.055603 0.078003 -0.007771
+-0.035400 0.019441 0.101450 -0.047446 -0.021123
+-0.003012 -0.065746 0.021167 0.028415 -0.039012
+0.078986 0.041230 -0.109603 -0.053586 0.081713
+0.069524 0.086261 0.032415 0.020301 0.008172
+-0.050007 -0.043252 0.032538 -0.040149 -0.060186
+-0.036647 0.074839 -0.067704 0.105038 0.016407
+-0.017166 -0.040157 -0.034379 -0.045783 0.036121
+0.006989 -0.053621 -0.014310 0.130029 0.014339
+0.010984 -0.049323 0.011801 0.024418 -0.061108
+0.048945 0.020936 -0.016709 0.036678 0.056799
+-0.032054 -0.081596 -0.020000 -0.014900 -0.016931
+0.025720 0.030371 0.054373 0.041972 -0.103673
+0.072505 -0.008653 -0.038498 -0.082343 -0.011659
+0.008214 -0.051158 -0.011619 0.011396 0.073440
+-0.028140 -0.085370 -0.083429 -0.059579 0.093532
+0.017281 -0.029324 -0.063027 0.036276 -0.035917
+-0.062731 0.083485 0.034826 -0.016723 0.041119
+0.006462 0.063240 0.106462 0.005405 0.014198
+-0.107371 0.016648 -0.039299 -0.060254 0.066074
+0.010798 0.104663 -0.026071 -0.092536 -0.049821
+0.052302 -0.111521 -0.028997 -0.044881 -0.058612
+-0.066180 0.063782 -0.087613 0.131044 0.079319
+0.051549 -0.031150 0.050463 0.014022 0.072812
+0.040951 -0.008242 -0.035076 -0.012706 -0.007732
+-0.087407 -0.043003 -0.051495 -0.005909 -0.078253
+0.024556 -0.000301 -0.002836 0.000471 0.036449
+-0.033227 0.013122 -0.041830 0.053473 -0.062823
+0.001698 0.056414 -0.009009 0.074868 -0.031437
+0.061142 0.034153 0.037913 -0.016467 -0.112529
+-0.042555 0.004865 0.068299 0.039970 0.035002
+-0.032275 -0.054429 -0.110647 -0.004981 0.106602
+-0.009971 -0.070226 0.011717 0.078195 -0.004486
+-0.053666 0.032253 0.019880 -0.063381 -0.011499
+-0.021161 -0.147358 0.022501 0.026856 0.014878
+0.071720 -0.018691 -0.078472 0.006781 0.128504
+0.009349 0.032300 0.024117 0.093683 -0.001689
+-0.038787 -0.022119 0.025894 -0.051130 -0.029077
+-0.003509 0.056923 -0.043564 0.047755 0.029228
+0.094577 -0.059873 0.105327 -0.045681 0.020128
+0.019571 -0.053714 -0.026005 0.082821 0.010883
+-0.090635 -0.046160 0.015147 -0.060630 -0.025114
+0.065345 -0.062635 0.033608 -0.000239 -0.055078
+0.028179 0.007232 -0.132300 -0.058511 -0.027521
+0.009924 -0.057576 0.037098 -0.048222 -0.067691
+0.025807 0.005481 0.053364 -0.071026 0.002704
+-0.019833 0.056496 -0.012323 0.054975 0.053260
+-0.058168 -0.002745 0.051808 0.007857 0.072213
+-0.028508 -0.100966 -0.066436 0.094923 -0.032702
+0.016386 0.144962 0.060276 -0.060885 0.045013
+-0.008694 -0.035070 0.077187 0.011427 -0.039974
+0.041845 0.095921 -0.012129 -0.069502 0.058053
+0.016498 0.068097 -0.063723 0.058607 -0.084662
+0.051080 -0.084087 0.061664 -0.014378 -0.020357
+-0.101420 0.018380 0.026201 0.021273 0.001716
+0.018280 -0.048955 0.114013 0.007403 0.073650
+-0.007198 -0.073071 -0.043345 -0.025399 0.062280
+-0.057043 0.007375 -0.057945 0.001682 -0.068288
+-0.004458 0.057944 0.019870 0.030319 0.023300
+0.023258 0.038816 -0.075939 0.024401 -0.008493
+-0.088976 0.084875 -0.004901 0.107413 0.036685
+-0.017576 0.049893 -0.017089 -0.076959 -0.047043
+0.012304 0.096589 0.020081 0.055371 0.026179
+-0.031262 -0.023054 -0.062863 0.022469 0.026254
+-0.081002 0.001604 -0.067115 0.089364 -0.044846
+-0.104635 0.022051 0.024153 -0.050297 -0.090473
+-0.111208 -0.014747 0.065056 0.064524 0.014978
+-0.018009 -0.045181 -0.036814 -0.049839 0.101556
+0.123355 0.029904 0.046059 0.075873 0.023800
+0.018950 -0.069598 -0.023833 -0.044717 -0.059289
+0.005309 -0.050755 -0.129767 0.090909 0.049327
+0.034593 -0.024217 -0.013090 -0.120429 0.018611
+0.035730 -0.069972 -0.020352 0.040567 -0.008846
+-0.035745 -0.012086 -0.029290 -0.031875 -0.022851
+0.126885 0.093804 -0.041337 0.064417 0.012827
+-0.006103 -0.064712 -0.034377 -0.072895 -0.024513
+0.024964 0.025126 0.053845 -0.032844 -0.040164
+0.057226 -0.047268 0.002180 -0.030810 -0.046649
+-0.011612 -0.016914 0.019534 -0.045647 0.103552
+-0.019784 -0.059284 0.034278 -0.052666 0.063638
+-0.030288 -0.052341 -0.018891 0.060842 -0.038845
+0.029390 0.061982 0.049711 -0.034509 0.014359
+-0.001671 -0.096474 0.111850 -0.008201 -0.039744
+-0.018012 -0.003881 -0.008624 -0.032458 0.060460
+0.046820 0.050558 -0.004330 -0.043328 0.024076
+0.020855 -0.064731 0.003784 -0.011162 -0.039018
+-0.064459 0.004758 -0.065784 0.046246 0.009026
+0.061065 0.051008 0.060159 -0.028994 0.058623
+0.065914 -0.082042 -0.137623 0.009165 -0.028321
+0.013924 0.038290 0.064550 -0.076981 -0.104556
+0.057766 -0.047215 -0.025831 -0.014589 0.040468
+-0.018660 -0.044675 -0.134278 -0.019992 0.000064
+-0.007643 0.019573 -0.005029 0.139097 -0.058444
+0.015872 -0.061714 0.054845 -0.093905 -0.023694
+-0.069868 -0.051634 0.093449 0.116722 0.041075
+-0.031597 -0.064630 -0.001604 -0.011889 0.114102
+-0.038392 -0.043996 0.036345 0.159256 0.042733
+-0.014768 0.023374 0.091565 -0.062174 0.008748
+0.027552 -0.065067 0.043484 0.029833 0.068407
+0.062921 0.100413 -0.044081 -0.047093 0.012867
+-0.021198 0.053674 -0.074601 0.009988 -0.000368
+0.004615 -0.031012 0.126258 -0.044950 -0.053716
+0.068829 0.028389 -0.081499 0.096576 0.111555
+0.032580 -0.091888 0.004783 -0.058619 0.103336
+0.023528 -0.067561 -0.052227 0.060540 -0.008415
+-0.134399 -0.003137 -0.005498 0.000696 -0.064610
+0.103028 -0.016839 0.054380 0.058673 -0.018968
+-0.030411 0.004030 -0.022930 -0.074504 -0.005768
+-0.040922 -0.056206 0.026643 0.091472 -0.046289
+0.024551 0.006847 -0.043098 -0.076632 0.023143
+-0.027690 0.058150 -0.033455 -0.000947 0.108861
+-0.053902 -0.004117 -0.000733 -0.004552 0.018160
+-0.015632 -0.075342 -0.057899 0.043216 -0.030867
+-0.025610 0.087151 0.015012 -0.058812 -0.077554
+-0.057877 0.030875 0.088541 0.068489 -0.037517
+-0.013136 0.003726 0.026354 -0.076145 0.081871
+0.009685 0.049282 -0.053126 -0.041669 -0.055971
+0.070689 -0.000302 0.030654 -0.059458 -0.032358
+-0.073479 0.014645 0.057040 0.060111 0.026122
+-0.021404 -0.035383 0.105578 -0.064143 0.009201
+0.067302 -0.018682 -0.018425 0.053502 0.095608
+-0.089642 0.061823 -0.049713 0.118868 -0.071061
+0.033484 0.020846 0.017472 0.009132 0.017367
+0.095422 0.015719 -0.042701 -0.059963 -0.093737
+0.065153 0.040501 0.070592 0.084313 0.023778
+0.011293 0.022143 -0.078417 -0.072724 0.022472
+-0.047887 0.042426 0.002790 0.080670 0.045298
+-0.124868 -0.052373 -0.036868 0.080892 0.053132
+-0.029773 -0.038766 -0.021131 0.028890 -0.019483
+-0.031257 0.013785 0.114016 -0.019299 -0.095540
+-0.081494 -0.108033 0.072808 0.034714 -0.046113
+0.018918 0.025646 -0.012081 -0.029184 0.035413
+0.062215 0.094361 -0.038357 0.004033 0.061858
+-0.040066 -0.073778 -0.039352 -0.026946 -0.078584
+-0.027017 -0.016385 -0.070475 0.068096 0.031208
+0.024912 -0.031301 0.028130 -0.092740 0.010887
+0.080067 -0.086228 -0.002645 0.062014 0.039789
+-0.000913 -0.002893 0.021215 0.025308 -0.079170
+0.021198 0.011411 -0.029445 0.021288 0.028934
+-0.012482 -0.093791 -0.086795 -0.065003 -0.091575
+0.042822 0.048190 0.027573 0.016672 -0.031582
+0.084478 -0.026855 0.002037 -0.003986 -0.032282
+-0.037516 0.024939 0.006645 0.069559 0.096001
+-0.009324 -0.020647 0.016115 -0.002890 0.099816
+0.035798 -0.055626 -0.082205 0.061510 -0.137040
+-0.003237 0.086092 -0.015616 0.038825 0.025940
+-0.009435 -0.039900 0.130411 0.041684 0.029411
+-0.053212 0.035136 -0.038974 -0.068479 -0.014046
+-0.052464 0.114330 0.014803 -0.043086 -0.031898
+0.114055 -0.094015 0.000194 0.005274 -0.032729
+-0.061821 0.146682 -0.033636 0.052702 -0.025910
+0.076647 0.000572 0.089946 0.018515 -0.012439
+0.057567 -0.023096 -0.066766 0.029717 -0.021521
+-0.048165 0.037444 -0.026950 -0.054050 -0.122571
+0.003033 -0.021280 0.058783 -0.065330 0.032047
+0.016007 0.003629 -0.102811 0.075806 -0.028556
+-0.051245 0.032001 0.006924 0.046225 -0.066944
+0.026360 0.071868 0.000989 -0.051417 -0.082284
+0.007536 -0.005941 0.054340 0.097832 0.059470
+0.005201 -0.029254 -0.063891 -0.032060 0.063113
+0.005567 -0.038440 0.079032 0.117269 -0.027965
+-0.018444 0.021519 0.056596 -0.077845 -0.001929
+0.018144 -0.117195 0.021022 -0.078031 0.060201
+0.068169 0.033446 -0.116183 0.024450 0.054125
+0.043263 0.043637 -0.024388 0.028606 -0.043272
+-0.076651 -0.044322 0.043529 -0.032600 -0.022496
+-0.028618 0.105767 -0.131078 0.022952 0.032809
+0.014704 -0.078921 0.053414 -0.130561 0.025975
+-0.006145 -0.020377 0.002576 0.111120 -0.027416
+-0.056800 -0.034249 -0.102732 -0.077605 -0.054125
+0.013938 -0.018912 0.031272 0.045116 0.009640
+-0.000666 -0.010171 -0.101812 -0.086048 -0.079481
+0.012556 -0.025093 -0.037932 0.018846 -0.121557
+0.019521 0.077648 0.062764 -0.080462 -0.006901
+-0.022906 0.106898 -0.001186 -0.033179 0.083120
+-0.108465 0.004729 -0.004907 -0.051941 0.019890
+-0.052798 -0.048321 -0.039992 0.011392 0.022231
+0.052123 0.053230 0.008893 -0.021235 -0.021543
+-0.052336 -0.002642 0.014048 0.021729 -0.071873
+0.008583 0.063055 -0.005700 -0.130218 -0.004615
+0.001933 0.068978 0.002830 0.041471 -0.075840
+0.058590 -0.105352 0.109710 -0.008703 0.046126
+-0.058564 0.044743 0.028326 -0.017021 -0.043831
+-0.006378 0.002489 0.083015 -0.017479 0.032458
+0.075359 -0.070133 -0.094634 0.004253 0.050570
+-0.084605 0.081302 0.020066 -0.026905 -0.070421
+0.027450 0.006091 0.038101 0.058759 -0.022035
+0.075718 0.034255 -0.003008 0.013391 -0.039205
+-0.027185 0.117021 0.026809 0.017619 -0.048835
+0.013076 -0.001288 -0.041201 -0.077396 -0.060871
+0.003384 0.082249 0.080509 0.073375 0.032946
+-0.020732 -0.036562 -0.005218 0.006654 0.017449
+-0.070219 -0.067294 -0.000185 0.046725 -0.032632
+-0.114281 0.007061 0.027082 -0.042412 -0.035359
+-0.017030 -0.081911 0.091617 -0.001734 0.040171
+0.029232 0.022946 -0.023063 -0.099398 0.088196
+0.134224 0.037312 -0.010897 0.015441 0.048401
+0.036710 -0.079633 0.068283 -0.095899 -0.076950
+0.031388 -0.049701 -0.078358 0.071239 0.093230
+-0.047640 -0.059715 -0.006775 -0.091115 -0.004787
+0.029706 -0.062712 0.001230 0.035511 0.012170
+-0.035826 -0.020972 -0.004566 -0.054826 -0.080743
+0.043183 -0.019993 -0.009134 0.093461 0.062293
+0.055956 -0.052129 -0.076380 -0.112243 0.065413
+0.075567 0.019848 0.094121 0.021786 -0.068644
+0.060691 -0.037556 0.053416 -0.063583 -0.009116
+0.059647 0.033059 0.008383 -0.057678 0.106669
+-0.086182 -0.028844 0.069038 -0.050651 0.045613
+-0.022872 -0.050951 0.020221 0.009049 -0.129767
+-0.034033 0.103312 0.070048 -0.008972 0.021930
+-0.019606 -0.031561 0.065822 0.016592 -0.009995
+-0.028203 0.056913 -0.043993 -0.020496 0.028610
+0.050871 0.070498 -0.045548 -0.038539 -0.050789
+0.065005 -0.048246 0.011105 -0.026236 0.004123
+-0.069629 0.029918 -0.108123 -0.018902 0.020385
+0.012121 0.000873 0.079758 -0.028851 -0.001646
+0.048281 -0.044204 -0.025910 -0.031220 0.006049
+-0.039981 0.031852 -0.007419 -0.008198 -0.105351
+0.021943 -0.009020 0.041415 -0.051481 0.064758
+-0.066937 0.070473 -0.128350 0.059786 -0.012980
+0.046171 -0.005175 -0.054847 0.066448 -0.057361
+0.015253 -0.020476 0.048261 -0.069168 -0.074295
+-0.072588 -0.042977 0.018592 0.070496 0.114648
+0.010817 -0.128853 -0.097246 0.020464 0.031236
+-0.024940 0.041108 0.011415 0.087818 -0.043080
+0.025168 0.025134 0.027778 -0.030419 -0.017191
+-0.010787 -0.089466 0.006383 0.016841 0.083765
+0.008103 0.031762 -0.065297 -0.043194 0.060151
+-0.031870 0.035064 -0.027919 0.019804 0.031581
+0.015682 -0.090393 0.054461 -0.051669 -0.020003
+-0.006273 0.029554 -0.052349 0.122862 0.052590
+0.053436 -0.092575 -0.038422 -0.014132 0.025596
+-0.007446 -0.068838 -0.100706 0.110571 -0.074217
+-0.124216 -0.046391 -0.001952 -0.035192 0.056849
+0.049815 -0.000716 0.078561 0.103458 -0.031106
+0.004277 0.053141 -0.013453 -0.014118 -0.043585
+0.037082 -0.072984 0.085005 0.059632 -0.092468
+0.070536 0.024296 0.032733 -0.064865 0.050807
+0.048457 0.051588 0.064615 0.014068 0.107732
+-0.036905 -0.023656 0.039094 -0.021163 0.016683
+-0.033733 -0.099111 -0.053957 0.004493 -0.052760
+-0.012367 0.103975 0.055514 -0.018205 -0.077832
+-0.018229 0.099840 0.043099 0.026033 -0.127892
+0.005209 0.115289 0.030702 -0.090228 0.102291
+-0.036231 0.059027 -0.073456 0.025828 -0.058846
+0.023155 -0.021831 0.050419 -0.052958 -0.025641
+-0.057417 -0.038855 0.069655 0.009463 -0.011469
+-0.001709 0.032146 0.133188 -0.084494 0.022112
+0.105454 -0.037301 -0.006059 -0.002167 0.033760
+-0.067749 0.052323 -0.002914 0.042408 -0.038078
+0.080983 0.032390 -0.013515 -0.017162 -0.001944
+0.018212 -0.057337 -0.024336 0.003385 -0.053031
+0.007656 0.093900 0.019898 0.057621 -0.016597
+0.028536 0.010449 -0.048939 -0.132260 -0.015093
+-0.032383 0.042496 0.006198 0.022980 0.050028
+-0.091286 0.046546 -0.012873 0.053569 0.100661
+0.001121 0.033644 -0.044783 0.040892 -0.007458
+0.015227 0.057715 0.135154 -0.011532 -0.048523
+-0.020718 -0.100767 0.060073 0.082344 -0.067297
+0.052855 0.019105 -0.072241 -0.034480 0.046910
+0.028509 0.105159 -0.005862 -0.006672 0.031437
+-0.044146 -0.049556 0.015169 -0.001790 -0.082293
+-0.043861 0.020628 -0.082354 0.150955 -0.022192
+-0.053152 -0.023628 -0.040518 -0.032409 0.040596
+-0.072007 -0.085815 0.034433 0.062865 0.051963
+0.007741 -0.008439 0.034908 -0.009552 -0.032946
+0.043386 0.024843 0.020463 0.077839 0.109446
+-0.033733 -0.111561 -0.077032 -0.028750 -0.004143
+0.027687 -0.006467 0.011063 0.043189 -0.123963
+0.091285 0.045529 -0.007055 -0.051180 -0.054342
+0.012612 -0.032042 0.014321 0.047055 0.140528
+-0.069055 -0.048973 -0.035481 -0.091096 0.061054
+-0.017211 -0.042891 -0.047427 0.050343 -0.010907
+-0.031955 0.062361 0.017419 -0.036013 -0.002721
+0.041131 0.024163 0.089626 0.022372 0.009373
+-0.095530 0.047262 -0.031783 -0.036250 -0.009977
+-0.021451 0.082581 -0.051394 -0.022879 -0.034885
+0.076878 -0.111199 -0.010824 0.015104 0.028609
+-0.085213 0.147576 -0.065340 0.019676 0.072754
+0.082529 0.036091 0.076516 0.052432 0.071795
+0.008287 -0.036426 -0.009891 0.029857 0.002193
+-0.003334 -0.028181 -0.037997 -0.010828 -0.075271
+-0.009274 -0.000105 0.026357 -0.014523 -0.000196
+0.045930 0.012760 -0.088269 0.009968 -0.079905
+0.046175 0.009370 -0.000002 0.029935 -0.042887
+0.023842 0.018746 -0.006990 0.008271 -0.090227
+0.030612 0.016519 0.081049 0.009339 0.055323
+-0.044325 0.004172 -0.068893 -0.045980 0.077715
+0.001175 -0.046950 0.036603 0.091690 -0.007926
+-0.030905 0.059344 0.015477 -0.098726 -0.013555
+-0.055799 -0.077539 -0.011439 -0.004065 0.054785
+0.034376 0.008123 -0.066323 0.015381 0.051534
+-0.029072 0.008390 -0.021483 0.034645 -0.015101
+-0.032733 -0.053135 0.072680 -0.018542 0.019239
+0.037756 0.062391 -0.075094 0.101033 0.003228
+0.041719 -0.083617 0.062272 -0.023256 0.039273
+0.009314 -0.036930 -0.022348 0.054612 -0.061547
+-0.057502 -0.045821 -0.027136 -0.057127 -0.040360
+0.066291 0.009189 0.032460 -0.001094 -0.054085
+0.006575 -0.054172 -0.130758 -0.090713 -0.002316
+0.034393 -0.052381 0.012536 0.038109 -0.081767
+0.085920 0.009447 -0.009120 -0.115802 -0.024373
+-0.009739 0.098210 -0.050578 0.009031 0.067793
+-0.102503 0.070893 0.048610 0.025783 0.070098
+-0.082345 -0.110272 -0.069934 0.039617 -0.015865
+0.093134 0.050931 0.078967 0.014464 0.014646
+-0.080307 -0.028843 0.108070 -0.021868 -0.059963
+-0.033823 0.075594 0.036621 -0.060586 0.034463
+0.062713 0.100354 -0.048699 0.006569 -0.054387
+0.085716 -0.042197 0.055028 -0.023813 -0.019848
+-0.128971 0.064906 -0.014135 0.053208 -0.054020
+0.012192 -0.023224 0.086982 0.002569 0.081299
+0.043572 -0.052176 -0.053337 0.001834 -0.002848
+-0.073999 0.045245 -0.072961 0.011777 -0.001025
+-0.038850 0.021979 0.082271 0.023871 -0.014373
+0.066920 0.022695 -0.046891 -0.028261 0.005879
+-0.066511 0.074096 0.039110 0.046744 -0.001032
+-0.028041 0.019515 -0.079802 -0.098550 -0.057732
+0.050261 0.061069 -0.014075 0.084526 0.061622
+-0.011750 -0.051429 -0.073887 -0.004920 0.014058
+-0.107882 -0.029024 -0.096352 0.047279 -0.040754
+-0.069567 0.060745 0.075817 -0.045723 -0.101709
+-0.047723 -0.030640 0.056081 0.076466 0.002197
+-0.010621 0.007690 -0.030150 -0.067986 0.062739
+0.117024 0.061613 0.012656 0.043682 -0.031102
+0.018671 -0.047947 -0.040784 -0.089523 -0.106392
+-0.005815 -0.001616 -0.068421 0.027810 0.057644
+-0.008067 -0.006506 0.039180 -0.154508 -0.011541
+0.033405 -0.122890 -0.013528 0.038364 -0.001838
+-0.004906 -0.046275 -0.038730 -0.031623 -0.003879
+0.152370 -0.022857 -0.072307 0.029362 0.058441
+0.009357 -0.022712 -0.075829 -0.057416 -0.038179
+0.011980 0.029996 0.082156 0.024194 -0.072075
+0.072125 -0.051638 0.039224 -0.086809 -0.049036
+-0.016999 -0.028023 -0.045506 -0.030265 0.170708
+-0.044189 -0.166394 0.095599 -0.078305 0.024710
+-0.012502 -0.049717 0.030435 0.149411 -0.047396
+-0.004166 0.092334 0.002567 0.003784 0.058999
+-0.014837 -0.013693 0.116725 -0.016922 -0.014098
+-0.026542 0.025453 -0.072587 -0.010040 0.040512
+0.061390 0.063914 -0.059682 -0.091206 -0.018253
+-0.019787 -0.066510 0.016750 -0.053649 -0.028817
+-0.092221 0.050852 -0.009044 0.047829 -0.002441
+0.018727 0.036731 0.089017 -0.091873 0.088367
+0.109395 0.014861 -0.097044 -0.015050 0.009286
+0.002921 0.027523 0.011728 -0.046926 -0.098498
+0.000836 -0.056539 0.023297 0.018001 0.049131
+0.004675 0.001073 -0.170749 0.014371 0.034021
+0.020092 0.037851 -0.028229 0.102064 -0.048952
+-0.025833 -0.026058 0.012805 -0.114410 -0.051993
+0.013397 -0.036918 0.089997 0.157135 0.083396
+-0.039602 -0.080711 -0.021277 0.053202 0.071289
+-0.109812 0.002914 -0.015096 0.091661 0.031649
+0.001854 0.034905 0.032772 -0.002794 -0.042979
+0.068519 -0.063135 0.013342 -0.006060 0.046252
+0.017425 0.141501 -0.060676 -0.083881 0.048423
+-0.023162 0.027077 -0.098028 -0.014739 0.010480
+-0.022374 -0.086942 0.100437 -0.075083 -0.115201
+0.007563 0.033322 -0.103828 0.051361 0.024684
+-0.004454 -0.055777 -0.046699 -0.082728 0.073797
+0.055443 -0.143092 -0.037825 0.078811 0.036497
+-0.077281 -0.008325 0.013544 -0.017594 -0.041641
+0.047789 -0.034492 -0.002379 0.073826 -0.075772
+-0.009782 0.050561 -0.019115 -0.056305 -0.001601
+-0.034683 0.008058 0.060254 0.034221 -0.132588
+0.051493 -0.015100 -0.031876 -0.051222 0.000989
+0.047049 0.026343 -0.041914 -0.036045 0.095869
+-0.062112 -0.018423 0.003773 -0.027867 -0.010398
+-0.048280 -0.036537 -0.017897 -0.005851 -0.058694
+-0.014345 0.061231 0.015028 -0.034773 -0.062937
+-0.000104 0.042883 0.145663 0.087783 -0.037200
+0.016255 0.036518 0.046461 -0.034405 0.079881
+0.035236 0.059227 -0.075679 -0.016770 -0.068794
+0.070744 -0.037727 0.127718 -0.021398 -0.046414
+-0.032597 0.063874 0.097691 0.026403 -0.004663
+-0.087849 -0.026770 0.144388 -0.048131 0.031670
+0.106295 -0.065269 -0.040652 -0.014211 0.056560
+-0.043383 0.070554 -0.010791 0.053436 -0.111118
+0.031068 0.016914 0.052035 0.004705 -0.005330
+0.034760 -0.023902 -0.025479 -0.020657 -0.051098
+0.009155 0.063415 0.088456 0.063249 -0.036212
+-0.000009 0.037196 -0.081303 -0.097243 -0.019263
+0.029158 0.050108 0.039763 0.121192 0.042011
+-0.067899 -0.051989 -0.021537 0.068444 0.027782
+-0.016312 -0.019484 -0.002050 0.053199 0.005392
+-0.008887 0.011627 0.044619 -0.090553 -0.063460
+0.004298 -0.096710 0.054118 0.026422 -0.054091
+0.011429 0.013193 -0.050806 -0.014131 0.048069
+0.073934 0.058524 -0.027092 0.000422 0.030744
+-0.027127 -0.040621 -0.081295 -0.132942 -0.174424
+-0.009461 0.028177 -0.035784 0.088923 0.029507
+-0.031399 0.023611 -0.016887 -0.076838 0.033483
+0.030485 -0.089706 0.003531 0.109110 0.014393
+-0.057547 -0.003360 0.039022 0.000441 -0.017536
+0.010777 0.032913 0.009826 0.011260 0.063002
+0.039884 -0.084768 -0.091794 -0.019418 0.001947
+0.035580 0.092377 0.044137 -0.039732 -0.073936
+0.074461 -0.026009 -0.018411 0.052151 -0.023017
+-0.074733 -0.019706 -0.045403 0.041498 0.114826
+-0.062412 -0.015496 -0.008802 0.010005 0.134097
+-0.006114 -0.127624 -0.111323 0.020666 -0.044975
+-0.039706 0.068792 0.011916 0.016754 -0.000454
+-0.010497 0.014889 0.070891 0.116098 0.021857
+-0.085198 0.023739 -0.088592 -0.046397 -0.013729
+-0.021026 0.161165 0.011340 -0.032323 -0.022466
+0.071886 -0.105818 0.021622 0.083276 -0.011759
+-0.053961 0.111353 -0.063359 0.048522 0.020913
+0.155966 -0.097759 0.067338 0.004069 0.048556
+0.039733 0.024807 -0.036450 0.026902 -0.001497
+0.008231 0.007538 -0.082664 -0.024402 -0.130124
+0.001341 0.009836 0.031207 -0.007516 0.063997
+0.013111 0.044756 -0.108910 0.036952 -0.038516
+0.032064 0.054737 0.021054 0.090083 -0.095331
+0.086201 0.072386 0.002048 -0.084090 -0.123429
+0.036048 -0.020936 -0.001486 0.048416 0.057746
+-0.007902 -0.025902 -0.039170 -0.090144 0.033093
+-0.037429 -0.008878 0.031789 0.108803 -0.001264
+-0.067338 0.047247 -0.010053 -0.104491 0.019316
+-0.038488 -0.110868 -0.017281 -0.069637 0.003541
+0.034292 0.055001 -0.090837 -0.028732 0.016192
+0.056000 0.072632 -0.022204 0.040858 0.031991
+-0.034742 -0.035448 0.019035 -0.013232 -0.014398
+-0.006173 0.109096 -0.049988 0.013882 0.005876
+-0.010246 -0.017441 0.025300 -0.098996 0.052687
+0.025387 0.000912 -0.009639 0.084043 -0.052007
+-0.083781 -0.030439 -0.073927 0.007538 0.012090
+0.066881 -0.025604 0.016332 0.037268 -0.033802
+-0.015458 -0.021930 -0.070557 -0.051580 0.012924
+-0.009009 -0.017953 0.042537 -0.020288 -0.091337
+-0.024530 0.040526 0.056023 -0.110282 0.026677
+-0.038359 0.097050 0.014986 0.037195 0.054785
+-0.083630 0.055443 -0.035272 0.003855 0.043706
+-0.057062 -0.037280 -0.046268 0.022056 -0.034342
+0.003546 0.055713 0.011998 0.006224 -0.025227
+-0.088934 -0.028368 0.079334 -0.001505 -0.127990
+-0.061598 0.084053 0.025380 -0.096473 0.067390
+-0.020260 0.092217 -0.018618 0.027917 -0.048252
+0.031415 -0.091387 0.090810 0.045103 -0.026705
+-0.064460 0.002074 0.031180 0.067323 -0.016903
+-0.005864 -0.003330 0.069051 -0.033416 0.082203
+0.044956 -0.053755 -0.137252 -0.046061 0.093635
+-0.088599 0.097969 -0.032264 -0.086639 -0.091644
+0.033056 0.016076 0.011350 0.037895 0.004198
+0.044101 0.049833 -0.032485 0.037383 -0.129242
+-0.042353 0.109453 -0.005173 0.074401 -0.070002
+-0.005799 0.052127 0.027453 -0.100450 -0.058706
+0.015240 0.069141 0.015929 0.041277 0.055504
+-0.023227 -0.001112 0.002065 0.012704 0.036834
+-0.089424 -0.016815 0.074728 0.052480 -0.044368
+-0.072117 0.037136 0.079468 -0.038248 -0.057019
+0.003825 -0.069667 0.055439 0.014255 0.032135
+-0.036398 0.060844 -0.051464 -0.103545 0.071708
+0.063325 0.075800 0.002963 -0.013314 0.045130
+0.020282 -0.083516 0.014408 -0.071592 -0.027531
+-0.010278 -0.013934 -0.042730 0.072202 0.007273
+-0.019582 -0.018122 0.004112 -0.129409 0.026095
+-0.031100 -0.041493 0.001026 0.068622 0.045611
+-0.016275 0.007467 0.007254 0.005397 -0.030822
+0.027449 -0.020425 0.019762 0.122976 0.047420
+0.032987 0.001328 -0.098351 -0.053497 0.013908
+0.029366 0.013866 0.122783 0.041198 -0.068939
+0.102145 -0.006101 0.037359 -0.057573 0.015037
+0.049004 -0.008177 -0.020529 -0.022026 0.125989
+-0.072538 -0.037701 0.022874 -0.032248 0.015711
+-0.012920 -0.043093 -0.039808 0.025999 -0.059643
+-0.020747 0.120412 0.058354 0.038064 0.023366
+0.022306 -0.008795 0.096772 0.019502 -0.021527
+-0.031783 0.042640 -0.012099 -0.056425 0.052337
+0.040885 0.076375 -0.024182 -0.007386 0.006375
+0.012472 -0.048071 -0.011689 -0.054259 0.004254
+-0.041141 0.023551 -0.047763 0.040648 0.055189
+0.041209 0.026372 0.083642 -0.041189 0.018401
+0.098897 -0.079038 -0.058140 -0.021688 -0.004584
+0.008362 0.050981 0.027989 0.004290 -0.077892
+0.079784 0.022189 -0.000950 -0.028833 0.038684
+-0.020911 0.002112 -0.089285 -0.009057 -0.044291
+0.067770 0.023611 -0.010856 0.057004 -0.068496
+0.028960 -0.012273 0.005375 -0.038117 -0.075004
+0.002103 0.002426 0.056212 0.025731 0.113254
+-0.069929 -0.080474 -0.089722 -0.019285 0.039492
+-0.047136 -0.038086 -0.013093 0.104245 -0.014991
+0.002220 0.028745 -0.014120 -0.003022 0.024545
+0.002795 -0.099925 0.077130 -0.017081 0.101062
+-0.062377 0.063615 -0.060597 -0.033619 0.126293
+-0.014254 0.057849 -0.017270 0.000255 0.046692
+-0.054974 -0.092568 0.028597 -0.061007 -0.049412
+0.026217 -0.012099 -0.046248 0.055666 0.060678
+0.069724 -0.056332 -0.008145 -0.067284 0.012714
+0.050454 -0.036820 -0.038474 0.094104 -0.025727
+-0.075576 -0.039175 0.010329 0.008010 0.003823
+0.101716 -0.042132 0.070715 0.035590 0.040456
+0.006306 0.001003 -0.055836 0.007729 -0.026461
+-0.015636 -0.027037 0.017196 0.048239 -0.066902
+0.090990 0.022012 -0.017646 -0.098129 0.037112
+0.005951 0.024530 0.021647 -0.014662 0.107048
+-0.087049 -0.037337 0.044913 0.024889 0.092117
+0.019813 -0.103273 -0.011622 0.001294 -0.057107
+-0.019526 0.055974 0.039931 -0.006568 -0.007790
+-0.048103 0.049238 0.061609 0.006077 -0.075369
+-0.009412 0.048275 0.009865 -0.081620 0.092182
+-0.017333 0.064175 -0.040670 0.004648 -0.022311
+0.003981 -0.066772 0.051258 -0.003877 -0.019203
+-0.071235 0.039869 0.084219 -0.012268 0.000880
+-0.047928 0.058804 0.087149 -0.026185 0.038879
+0.064338 -0.035073 -0.023367 0.048265 0.050703
+-0.021562 0.045307 -0.009582 -0.003124 -0.020818
+0.022634 -0.009844 0.002915 -0.015520 -0.030355
+0.083917 -0.031796 -0.047661 0.008159 -0.040844
+0.028545 0.035008 0.057934 0.053669 -0.054020
+0.035223 0.042440 -0.036255 -0.096245 -0.051155
+-0.029984 0.014055 0.019736 0.048158 0.004093
+-0.025898 -0.014328 0.002510 0.028365 0.085207
+0.006077 0.002203 -0.027505 0.047570 -0.017349
+-0.020587 0.067784 0.099796 -0.026735 -0.024473
+-0.025703 -0.094091 0.031649 0.029644 0.003411
+0.058308 0.049034 -0.068172 -0.115474 0.069425
+0.033811 0.118472 0.050946 0.053623 0.078579
+-0.019271 -0.065324 0.045402 -0.037870 -0.047215
+-0.005675 0.086373 -0.014768 0.145929 0.037386
+-0.014700 -0.049202 0.023594 -0.056698 0.023680
+-0.033374 -0.061027 -0.059854 0.138963 0.011599
+0.001533 -0.035748 -0.008464 0.032284 -0.039337
+0.081951 -0.006716 -0.010483 0.112224 0.090494
+-0.038372 -0.067773 -0.036190 -0.038843 -0.011294
+0.090443 0.048152 0.042218 0.056232 -0.093971
+0.122476 -0.005575 -0.036654 -0.029043 -0.034003
+0.022275 -0.033887 -0.060285 0.004531 0.075150
+-0.065225 -0.097285 -0.022983 -0.069686 0.069205
+-0.001642 -0.056254 -0.077585 0.025569 -0.054803
+-0.100539 0.093912 0.080158 -0.002782 0.010494
+-0.006143 0.026757 0.145882 -0.004906 0.028979
+-0.109082 0.071364 -0.005886 -0.068041 0.037065
+-0.018060 0.065418 -0.041926 -0.102324 -0.083326
+0.011189 -0.087023 -0.052738 -0.029586 -0.017342
+-0.039294 0.027361 -0.091183 0.088291 0.045424
+0.057392 -0.021108 0.072939 0.049198 0.122993
+0.038302 -0.020317 -0.005652 0.011269 -0.001771
+-0.047838 -0.064151 -0.069358 0.022155 -0.083435
+0.003546 0.019317 0.007896 0.030876 0.029493
+-0.015680 0.011502 -0.079687 0.043705 -0.076931
+0.007474 0.001457 0.006085 0.047001 -0.040679
+0.038183 0.030132 -0.015742 -0.043583 -0.066149
+-0.013762 -0.006024 0.029832 0.027818 0.040294
+-0.027094 -0.024302 -0.105055 -0.022415 0.045939
+0.003325 -0.031412 0.002150 0.091557 0.040350
+-0.023031 0.051570 -0.004636 -0.046863 -0.032721
+-0.001379 -0.136365 0.030118 -0.015619 0.060966
+0.051409 0.002981 -0.085911 0.034787 0.092612
+-0.024351 0.032927 -0.011889 0.047216 0.013262
+-0.031903 -0.008671 0.062494 -0.057320 -0.025303
+-0.026174 0.061109 -0.031321 0.063430 -0.001627
+0.033534 -0.042932 0.077354 -0.044685 0.038110
+0.029437 -0.011422 -0.026351 0.079037 -0.011110
+-0.065906 -0.012694 0.002666 -0.081176 0.007352
+0.047210 -0.022385 0.022590 0.004000 -0.056449
+0.028936 -0.002388 -0.119043 0.000528 -0.022876
+0.000565 -0.041766 0.035570 -0.010223 -0.055419
+-0.003717 0.050681 0.042119 -0.073103 -0.034640
+-0.019828 0.077821 -0.007847 0.115964 0.095672
+-0.057148 -0.022559 0.035308 -0.042327 0.097345
+-0.034233 -0.054020 -0.057557 0.089841 0.009229
+0.070683 0.108539 0.046246 -0.050120 -0.008497
+-0.056988 -0.048306 0.068906 0.015296 -0.073327
+0.020887 0.044562 -0.007768 -0.071345 0.057720
+0.027704 0.094761 -0.024903 0.058677 -0.054592
+0.045246 -0.128952 0.028581 0.009761 -0.036013
+-0.137353 0.034736 0.027748 0.045031 0.020522
+-0.032682 -0.010848 0.135840 -0.008210 0.064445
+0.016483 -0.066692 -0.036966 -0.018892 0.037266
+-0.055969 -0.000146 -0.070159 -0.043813 -0.035507
+0.007295 0.067471 0.062439 0.031139 0.004051
+0.081763 0.058234 -0.080642 0.039998 -0.014646
+-0.020107 0.121620 -0.031533 0.049787 0.048427
+-0.027995 0.017340 -0.036722 -0.027766 -0.072522
+0.016754 0.116377 -0.007417 0.117559 -0.023170
+-0.036028 -0.013555 -0.057848 -0.006776 0.057208
+-0.080437 -0.067988 -0.044028 0.086414 -0.051744
+-0.073007 0.043810 0.014807 -0.049665 -0.049222
+-0.085317 -0.073906 0.084214 0.028253 0.022565
+0.061129 -0.008498 -0.065248 -0.093368 0.125544
+0.101010 0.030100 0.021030 0.003998 -0.000819
+0.051523 -0.052633 -0.031029 -0.086071 -0.030398
+-0.049646 -0.039065 -0.114362 0.111554 -0.013322
+0.060882 -0.037407 -0.007392 -0.128509 0.069699
+0.010662 -0.095924 0.004877 0.022956 -0.003608
+-0.040638 0.005864 -0.025032 0.003803 -0.033060
+0.104406 0.009014 -0.070791 0.101107 -0.010706
+0.018493 -0.060775 -0.046556 -0.102536 -0.058762
+0.013012 0.047639 0.074284 -0.021771 -0.071480
+0.121697 -0.062576 -0.061069 -0.084239 -0.030672
+-0.053509 -0.072509 0.029717 -0.075666 0.119601
+-0.071159 -0.064371 0.049556 -0.006955 0.050790
+-0.014936 -0.030424 -0.029046 0.095626 -0.053380
+0.026242 0.084580 0.046043 -0.013774 0.048761
+-0.003036 -0.055345 0.130574 0.072416 -0.040259
+-0.012252 0.029803 -0.017821 -0.029420 0.057413
+0.036485 0.041237 -0.032473 -0.046230 0.000440
+-0.003955 -0.066533 0.009267 0.004057 0.002718
+-0.054960 0.012076 -0.051431 -0.001750 0.015747
+0.067251 0.037864 0.116071 -0.012828 0.063945
+0.065686 0.005781 -0.102444 0.050582 -0.006415
+-0.022414 0.010021 0.095137 -0.034063 -0.154439
+0.018933 -0.026790 -0.009372 -0.025828 0.058756
+0.008035 -0.025525 -0.090140 -0.012845 -0.008559
+0.017881 -0.039468 -0.051786 0.088240 -0.081061
+0.017134 -0.000603 0.072990 -0.106103 -0.045466
+-0.026151 -0.003544 0.108411 0.044002 0.070681
+-0.065841 -0.096530 -0.055378 0.015170 0.126129
+-0.048244 0.006173 0.013564 0.196118 -0.046276
+-0.026911 0.046123 0.060438 -0.042470 -0.007582
+0.086581 -0.077901 0.057108 -0.013982 0.095961
+0.013568 0.081727 -0.063919 -0.008458 0.020099
+0.015455 0.049515 -0.048905 -0.006740 0.017709
+-0.023263 -0.011752 0.104977 -0.091749 -0.072352
+0.041545 0.027311 -0.061505 0.073899 0.057681
+0.060911 -0.048034 -0.006742 -0.018161 0.082492
+0.044955 -0.030697 -0.042272 0.060646 0.025253
+-0.095552 -0.007674 -0.037376 -0.042828 -0.028071
+0.078704 0.034767 0.003569 0.103759 -0.017217
+-0.006459 -0.003174 -0.006884 -0.052177 0.000067
+-0.000080 0.002880 0.067251 0.077245 -0.083559
+0.043695 0.037396 0.005392 -0.085654 0.021389
+0.037997 0.095932 -0.028364 -0.033582 0.112597
+-0.047949 0.014115 0.027626 0.006558 0.055128
+-0.035469 -0.081510 -0.015853 0.031846 -0.003825
+-0.019678 0.109423 0.054030 -0.050997 -0.017309
+-0.027511 -0.012712 0.078270 0.073890 -0.036127
+0.007627 0.021692 0.029178 -0.076480 0.035985
+-0.013671 0.074729 -0.070079 -0.041782 -0.003345
+0.081644 -0.007541 0.018661 -0.069248 -0.082554
+-0.066409 0.041793 0.088394 0.023002 0.031839
+-0.004239 -0.055445 0.153536 -0.029606 0.011440
+0.120925 -0.031292 0.009491 0.023924 0.097333
+-0.064946 0.044945 -0.036368 0.075204 -0.043170
+0.084879 0.044759 0.026172 0.014565 0.045921
+0.045467 -0.017067 -0.028516 -0.030039 -0.097097
+0.033711 0.032445 0.072773 0.052865 -0.002100
+0.007495 0.042950 -0.042792 -0.074042 -0.011530
+-0.056728 0.042999 0.092369 0.099547 0.013443
+-0.054306 -0.043025 -0.068623 0.095940 0.074227
+-0.079501 -0.007941 0.000413 0.032496 -0.031837
+-0.016260 0.033024 0.064746 -0.017847 -0.104087
+0.000197 -0.151410 0.074026 -0.001001 -0.031403
+0.046221 0.036460 -0.040808 -0.021449 0.032127
+0.079554 0.080997 -0.076818 -0.019398 0.037202
+-0.001902 -0.080469 -0.020903 -0.017046 -0.093414
+-0.063198 0.002218 -0.041482 0.114007 -0.001262
+0.004609 -0.045369 -0.012778 -0.106632 -0.009353
+0.046742 -0.093363 -0.020190 0.070943 0.104612
+-0.026496 0.030245 0.036531 0.049474 -0.034971
+0.010070 -0.016557 -0.015930 0.036066 0.046365
+-0.059709 -0.083439 -0.099145 -0.024957 -0.044832
+0.031623 0.022393 0.012334 -0.009649 -0.050844
+0.126142 0.023320 0.052720 0.016504 -0.047781
+0.002926 0.004861 -0.060239 0.050008 0.098520
+-0.050552 -0.025407 -0.003390 -0.014939 0.068650
+0.032517 -0.092568 -0.058102 0.078834 -0.068898
+0.001143 0.108254 0.006322 0.014800 -0.012314
+0.050222 -0.034504 0.174248 0.025459 -0.002951
+-0.040868 0.022522 -0.081662 -0.051546 0.029154
+-0.001469 0.154137 0.010623 0.000752 0.036767
+0.113304 -0.068389 0.029430 0.054651 -0.072835
+-0.063281 0.122269 -0.028825 -0.023612 0.018427
+0.073886 -0.005629 0.074243 -0.013698 0.036158
+0.027137 -0.008779 -0.051317 0.034729 0.011425
+-0.005290 0.084381 -0.046825 -0.054925 -0.134575
+-0.007420 -0.034384 0.032822 -0.006816 0.016250
+0.013071 0.022288 -0.116225 0.121282 -0.061502
+-0.022397 0.009282 0.013596 0.083516 -0.068117
+0.018270 0.070016 -0.019013 -0.055558 -0.038255
+0.048457 -0.023579 0.050451 0.085665 0.035829
+0.005139 -0.053830 -0.068741 -0.045650 0.019271
+-0.039606 -0.040208 0.113025 0.137240 -0.039967
+-0.050847 0.011254 0.031376 -0.087299 0.036520
+0.012497 -0.096540 -0.005847 -0.023409 0.055187
+0.047393 -0.016958 -0.127368 0.014126 0.013071
+0.042850 0.030065 -0.005283 -0.003391 -0.012498
+-0.063424 -0.066634 -0.007857 -0.012463 -0.048025
+-0.038726 0.093465 -0.068296 -0.004955 0.020647
+0.064345 -0.025818 0.123250 -0.113614 0.042799
+0.012083 0.019991 -0.011713 0.093276 -0.018115
+-0.069842 -0.040684 -0.062936 -0.036833 -0.057289
+0.048571 -0.021162 0.059277 0.027594 0.031567
+0.004623 0.013103 -0.070462 -0.031843 -0.062285
+0.003964 -0.043003 0.001089 0.007283 -0.094012
+0.089866 0.071995 0.101778 -0.112357 0.012040
+-0.072256 0.086698 0.032881 -0.033458 0.098016
+-0.082535 0.048160 0.026744 -0.027036 0.025903
+-0.042452 -0.094755 -0.054770 0.004509 0.015786
+0.053114 0.051959 0.021238 -0.079127 -0.025941
+-0.061221 -0.032380 0.000678 0.034720 -0.119877
+-0.029004 0.038623 -0.037611 -0.139319 -0.005737
+0.041081 0.129303 -0.021741 0.027442 -0.123106
+0.038200 -0.064672 0.083376 0.032648 0.033742
+-0.048851 0.029052 0.025199 0.023531 -0.025856
+-0.003336 0.029494 0.075111 -0.010905 0.064079
+0.037642 -0.035068 -0.084707 0.026922 0.022164
+-0.068680 0.075838 -0.025633 -0.004398 -0.115237
+-0.004548 -0.002381 0.026301 0.068400 -0.006462
+0.121501 0.071558 -0.029120 0.004560 -0.059715
+0.020657 0.160004 -0.003257 0.029479 -0.040264
+-0.009405 0.008581 -0.016967 -0.102333 -0.102278
+-0.030081 0.075670 0.078504 0.112244 0.066878
+-0.024548 -0.067136 -0.004662 -0.026166 0.044337
+-0.066652 -0.078118 0.000364 0.038618 -0.076186
+-0.089846 -0.017872 0.072022 -0.066259 -0.059455
+-0.028736 -0.093805 0.079006 0.023036 -0.015992
+-0.045002 -0.004511 -0.021728 -0.091307 0.072076
+0.104573 0.051663 0.037822 0.009659 0.091841
+-0.000223 -0.070248 0.002859 -0.085403 -0.067834
+-0.010392 -0.032752 -0.036464 0.047626 0.061988
+-0.020766 -0.098673 0.010533 -0.120437 -0.028288
+-0.010613 -0.086247 -0.006349 0.031765 0.038227
+-0.042501 0.012368 0.001644 -0.053936 -0.052854
+0.040412 0.006924 0.010332 0.084276 0.018472
+0.030309 -0.012747 -0.071598 -0.111819 0.023998
+0.087829 0.061878 0.094608 -0.037238 -0.050664
+0.036768 -0.026142 0.028210 -0.019029 -0.007024
+0.056710 -0.012442 0.005440 -0.103556 0.139787
+-0.138355 -0.040445 0.025577 -0.107722 0.078150
+-0.001450 -0.071658 -0.025306 0.038319 -0.103037
+-0.028321 0.098830 0.057603 -0.007905 0.078051
+-0.009903 -0.025356 0.086842 0.012796 0.022952
+-0.014137 0.064001 -0.027812 -0.039279 0.060983
+0.027092 0.074119 -0.010385 -0.012999 -0.057892
+0.027647 -0.079000 0.021994 -0.032696 -0.014011
+-0.042864 0.021318 -0.117190 0.023970 0.036325
+0.057969 0.007604 0.135989 -0.027874 0.036906
+0.067047 -0.008885 -0.080445 -0.027705 0.003494
+-0.016421 0.020609 -0.029576 0.029755 -0.109042
+0.078601 -0.014246 0.028812 -0.022730 0.042634
+-0.037523 0.028199 -0.083746 0.036775 -0.009971
+0.037147 0.014445 -0.058619 0.061398 -0.011282
+-0.015391 0.000460 0.008396 -0.046827 -0.027835
+-0.014145 -0.069296 0.027030 0.067044 0.087990
+-0.003414 -0.125998 -0.042444 -0.033398 0.047298
+-0.084005 0.001739 0.050690 0.114059 -0.044072
+0.002756 0.040246 0.024529 -0.045169 0.010004
+-0.037919 -0.092984 0.039383 0.031606 0.079460
+0.010879 0.059048 -0.072431 -0.003405 0.086399
+0.008666 0.031679 -0.042362 0.054428 0.060492
+-0.022185 -0.099806 0.129259 -0.080670 -0.043866
+0.012856 0.013568 -0.033243 0.095598 0.093044
+0.062030 -0.075113 -0.037729 -0.060376 0.060004
+0.031119 -0.061372 -0.096201 0.101855 -0.016822
+-0.082510 -0.060718 -0.033015 -0.027222 0.007231
+0.062973 -0.041640 0.109215 0.081676 -0.013847
+-0.013324 0.027366 -0.033590 -0.046803 -0.039116
+0.061055 -0.037717 0.065252 0.078148 -0.053763
+0.050494 -0.011958 0.033369 -0.107018 0.057087
+-0.015111 0.079702 0.078616 0.051406 0.103170
+-0.055713 -0.031900 0.039951 0.010658 0.030803
+-0.032401 -0.161199 -0.006920 -0.041844 -0.054552
+0.068517 0.125210 0.080621 0.013543 -0.033413
+-0.044663 0.074392 0.035932 0.023301 -0.045912
+-0.009902 0.066933 0.032801 -0.049038 0.095407
+-0.039521 0.112499 -0.074490 0.036163 -0.044197
+0.018696 -0.011558 0.057933 -0.025639 -0.061431
+-0.081026 0.005753 0.057683 -0.011585 0.006821
+-0.006872 0.098313 0.119539 -0.081953 0.004434
+0.067413 -0.006236 0.002746 0.014715 0.026754
+-0.037853 0.034309 -0.028443 0.026642 -0.037707
+0.066061 0.019234 0.029629 -0.015190 -0.012766
+0.027166 -0.042834 -0.056186 -0.009603 -0.083747
+0.050175 0.073412 0.007110 0.043388 -0.043870
+0.042677 0.025735 -0.094635 -0.142996 -0.099443
+-0.025460 0.022178 0.045321 0.069113 0.054570
+-0.064131 0.000827 0.011239 0.039192 0.080176
+-0.032389 -0.013939 -0.064993 0.048795 -0.022851
+-0.004958 0.060895 0.123682 -0.068608 -0.074900
+-0.019889 -0.062160 0.073126 0.058232 -0.032283
+0.081527 -0.007318 -0.072361 0.003923 0.047891
+0.057147 0.118678 -0.020847 -0.014802 -0.015634
+-0.052605 -0.036531 0.034867 -0.078556 -0.111584
+-0.003560 0.003142 -0.024669 0.173160 0.032364
+-0.053222 -0.023754 -0.040899 -0.047008 -0.003696
+-0.033042 -0.093138 -0.004980 0.112166 0.080717
+-0.010216 -0.006619 0.021922 0.016601 -0.003126
+0.051343 0.053954 -0.046302 0.038985 0.078694
+-0.030092 -0.107599 -0.081002 -0.105924 0.002939
+0.011743 0.034846 0.003716 0.065184 -0.117462
+0.164375 0.073700 -0.033512 -0.050132 0.014156
+-0.000174 -0.023948 -0.024012 -0.006934 0.108972
+-0.059460 -0.048846 -0.012336 -0.051560 0.072806
+-0.018567 -0.058139 -0.097127 0.057960 -0.003780
+-0.069194 0.099784 0.014634 0.002396 0.004753
+0.054780 0.066215 0.126638 0.054455 0.006893
+-0.141807 0.059586 -0.018459 -0.063126 -0.022803
+-0.035254 0.069275 -0.013827 -0.071276 -0.003613
+0.069290 -0.132719 0.008038 -0.042340 0.029226
+-0.111912 0.046898 -0.082164 0.046524 0.042479
+0.097773 -0.009098 0.059874 0.073312 0.066974
+0.019922 0.006528 -0.012465 0.012819 -0.009649
+-0.002277 -0.027303 -0.050759 -0.050323 -0.080025
+-0.003253 -0.006990 -0.002405 -0.013040 -0.007020
+0.025178 0.055844 -0.116797 0.017350 -0.095996
+0.027313 0.001295 -0.036475 0.035209 -0.050719
+0.013403 0.027367 -0.033867 -0.020572 -0.083462
+0.026022 0.029014 0.068306 0.059719 0.045583
+-0.102670 -0.014676 -0.070060 -0.007867 0.061628
+0.021102 -0.044131 0.078378 0.066952 0.012162
+-0.059452 0.052841 -0.010660 -0.090335 -0.061320
+-0.052210 -0.080353 0.003880 -0.025212 0.019020
+-0.010473 0.007817 -0.044796 0.000027 0.083904
+0.006729 0.028716 -0.007627 0.008946 -0.012966
+-0.049870 -0.073154 0.092609 -0.040256 -0.020294
+0.003554 0.076666 -0.067856 0.042000 -0.009122
+0.044476 -0.118767 0.080698 -0.076039 0.023373
+0.024567 -0.033258 -0.036048 0.044153 -0.019221
+-0.018260 -0.035700 -0.029634 -0.065584 -0.049991
+0.042902 -0.000452 0.031084 0.045586 -0.065013
+0.072242 -0.014513 -0.122642 -0.018067 -0.052772
+0.066880 -0.103725 0.037586 0.013011 -0.086527
+0.032019 0.010695 0.027327 -0.089804 -0.030002
+0.010910 0.113012 -0.008852 0.024520 0.099760
+-0.077270 0.018171 0.079814 0.035008 0.127627
+-0.025609 -0.178637 -0.034357 0.054347 -0.012604
+0.043660 0.062421 0.068757 0.002273 0.000552
+-0.055697 0.010254 0.102285 0.024048 -0.044425
+-0.004860 0.053366 0.013063 -0.098388 0.046218
+0.043926 0.077559 -0.036943 0.060936 -0.016764
+0.098322 -0.041365 0.092078 0.019431 -0.039793
+-0.118098 0.023995 0.053538 0.015639 -0.041697
+-0.011851 -0.052177 0.084977 -0.050669 0.070218
+0.030401 -0.076060 -0.020483 0.012783 0.033816
+-0.050769 0.057281 -0.040092 -0.021298 -0.002690
+-0.001729 0.035744 0.065206 -0.002257 0.015864
+0.044906 0.045612 -0.081326 -0.040729 -0.018151
+-0.048153 0.086870 0.077712 0.059363 -0.027251
+-0.089240 0.025410 -0.036539 -0.067019 -0.057377
+0.058057 0.070889 -0.015866 0.124536 0.012038
+-0.007238 -0.051026 -0.027541 0.019248 0.026927
+-0.083553 -0.025718 -0.042635 0.058541 -0.011741
+-0.059778 0.065660 0.061292 -0.086725 -0.032482
+-0.047209 -0.027933 0.087677 0.047367 0.001582
+0.051308 -0.018242 -0.025264 -0.062026 0.074843
+0.088969 0.059484 0.048905 -0.025787 -0.015960
+0.010270 -0.030210 0.036763 -0.093327 -0.114689
+0.013105 -0.035443 -0.085439 0.043021 0.056988
+-0.020390 -0.008308 0.009722 -0.148341 0.081086
+0.010332 -0.101445 -0.021486 0.078663 0.025110
+0.007874 -0.023882 -0.034158 0.002488 -0.015558
+0.158690 -0.025837 -0.011736 0.035542 0.005703
+0.001555 -0.019753 -0.040038 -0.051161 -0.002844
+0.041149 0.021540 0.062971 0.012070 -0.035360
+0.091865 -0.090158 0.020460 -0.046615 -0.038100
+0.002630 -0.055311 0.026706 -0.008623 0.155705
+-0.030212 -0.117746 0.084958 -0.087229 0.092780
+-0.011810 -0.084822 -0.029035 0.127892 -0.065824
+0.008357 0.089638 0.003467 -0.034364 0.040506
+-0.001934 -0.050401 0.105320 0.007386 -0.011020
+-0.055669 0.029633 -0.034990 -0.028782 0.050039
+0.059295 0.118394 -0.033924 -0.132036 0.012985
+0.000793 -0.035658 0.031224 -0.040614 -0.014333
+-0.054078 0.015577 -0.031608 0.071981 0.019771
+0.079765 -0.007986 0.076487 -0.077172 0.119140
+0.102976 -0.039809 -0.092140 0.032478 -0.070501
+-0.026617 -0.016197 0.009189 -0.039295 -0.117914
+0.014457 -0.061592 0.025979 -0.028542 0.042043
+-0.029473 -0.031444 -0.158578 -0.003258 0.058182
+0.072344 0.052910 -0.092808 0.085354 -0.079413
+-0.044358 -0.041179 0.072986 -0.129686 -0.025728
+-0.005197 -0.108115 0.063915 0.073996 0.057224
+0.000050 -0.069751 -0.062690 0.026183 0.084719
+-0.052197 -0.011673 0.032435 0.084752 0.060158
+-0.031241 0.023120 0.048633 -0.025976 -0.032094
+0.051737 -0.070951 0.034497 0.003743 0.019843
+-0.055829 0.115532 -0.098594 -0.066675 0.048946
+0.003976 -0.010224 -0.071617 0.007215 0.017134
+-0.023828 -0.066295 0.084251 -0.039425 -0.074279
+-0.010390 0.058722 -0.091528 0.073371 0.071531
+-0.005671 -0.076154 -0.032125 -0.137305 0.071102
+0.068984 -0.088661 -0.037098 0.081501 -0.013426
+-0.093305 0.025622 -0.014982 0.007427 -0.068188
+0.064271 -0.035807 0.026492 0.107054 -0.095956
+-0.008699 0.021743 -0.031579 -0.040618 0.022948
+-0.006215 -0.028661 0.082129 0.022510 -0.090809
+0.032763 -0.014948 -0.000344 -0.068665 0.009455
+0.064722 0.101146 0.018141 -0.019456 0.082955
+-0.033054 0.018056 -0.025308 -0.023021 -0.006592
+-0.027499 -0.079456 -0.014152 0.030881 -0.059661
+-0.023889 0.075852 0.004376 -0.014776 -0.035516
+-0.031784 0.056947 0.125839 0.039811 -0.082984
+-0.015402 0.040202 0.031099 -0.040303 0.047701
+0.050471 0.082637 -0.118070 -0.024705 -0.027053
+0.042555 -0.045217 0.043471 -0.044274 -0.055532
+-0.050709 0.038372 0.139423 0.034228 0.044240
+-0.049598 -0.006876 0.084222 -0.084035 0.029679
+0.024672 -0.099431 -0.061796 0.004907 0.127399
+-0.065852 0.032572 -0.083461 0.040649 -0.064464
+0.021261 0.012978 0.043311 -0.006692 0.029174
+0.033834 0.010903 -0.049322 -0.023014 -0.053063
+0.050601 0.079776 0.017751 0.090575 -0.044427
+0.037446 0.038015 -0.114311 -0.116158 0.028262
+-0.049840 -0.001403 0.022194 0.134131 0.092987
+-0.066064 -0.014258 -0.007936 0.069423 0.006734
+-0.036449 -0.006999 0.014668 0.062054 -0.033927
+-0.037695 0.031955 0.072185 -0.067258 -0.065412
+-0.030677 -0.153131 0.064817 0.020761 -0.114634
+0.046484 -0.012249 -0.045214 -0.032565 0.032724
+0.038377 0.052687 -0.074746 0.015211 0.031545
+-0.001416 -0.092829 -0.036780 -0.058636 -0.153621
+-0.019035 0.008907 -0.020006 0.073795 0.064152
+-0.000207 -0.014885 0.001697 -0.075230 0.026080
+0.012374 -0.089499 0.037475 0.064069 0.017655
+-0.032040 -0.028499 0.036399 0.038500 -0.014121
+0.034750 -0.002062 -0.015799 0.000062 0.074059
+0.038031 -0.076502 -0.082402 -0.051544 -0.043409
+0.052959 0.046017 0.047906 -0.000054 -0.062527
+0.077616 -0.011144 -0.036095 0.006758 0.006522
+-0.023224 -0.010642 -0.107560 0.051291 0.103622
+-0.051956 -0.008535 -0.042995 -0.030987 0.123523
+0.039493 -0.107293 -0.068566 0.006004 -0.077249
+-0.049696 0.040608 0.002098 -0.005654 0.027282
+-0.009389 0.042181 0.088705 0.055663 0.013492
+-0.021941 -0.005352 -0.129536 -0.049372 0.006692
+0.010255 0.107988 0.009301 -0.029104 -0.027292
+0.015083 -0.122624 0.012460 0.056717 -0.065848
+-0.097599 0.064951 -0.063651 0.037039 -0.031919
+0.160199 -0.025996 -0.003930 -0.047321 0.027398
+0.043702 0.013525 -0.061810 0.010431 0.014853
+0.001414 -0.021460 -0.143900 -0.026666 -0.116995
+-0.024697 -0.005896 0.048756 -0.053298 0.041329
+0.012695 0.052326 -0.133818 0.105903 0.031440
+-0.035969 0.050106 0.022116 0.126387 -0.109337
+0.072036 0.100468 -0.005336 -0.056878 -0.046406
+0.015972 -0.014095 -0.004362 0.051363 0.094242
+-0.044797 -0.027049 -0.074056 -0.081706 0.012076
+-0.021437 0.047597 0.088166 0.121074 -0.053524
+-0.101688 0.029406 0.050242 -0.066960 0.062052
+-0.035998 -0.084834 0.048189 -0.024642 0.023264
+-0.011644 0.041881 -0.143927 -0.036006 0.064384
+0.021606 0.052025 -0.023292 0.037743 0.004852
+-0.027128 -0.078095 0.017231 -0.009425 -0.026275
+0.007197 0.096964 -0.068860 0.060880 0.037649
+0.014117 -0.065558 0.047350 -0.098632 0.083283
+0.045025 0.025416 0.038291 0.099379 -0.057242
+-0.098262 -0.004438 -0.093149 -0.017525 -0.064476
+0.025479 -0.016529 0.020430 0.012592 -0.009811
+-0.015037 0.005498 -0.076398 -0.034881 -0.007594
+0.028415 -0.040315 0.028704 -0.028492 -0.105515
+0.018470 0.042456 0.045301 -0.147209 0.007810
+-0.047688 0.032497 -0.008208 0.017988 0.084280
+-0.102271 0.004685 -0.018636 -0.003214 0.061342
+-0.034608 -0.028335 -0.058715 -0.016027 -0.027108
+0.008836 0.088808 0.038542 -0.020970 0.000400
+-0.050920 -0.007459 0.061998 -0.024563 -0.091152
+-0.014850 0.115523 0.022779 -0.107846 0.019813
+-0.004600 0.099048 -0.029527 -0.031147 -0.061377
+0.023544 -0.134421 0.066807 0.032147 0.021599
+-0.043477 0.029615 0.039209 0.024621 0.019526
+-0.002071 0.031970 0.101991 -0.003775 0.121976
+-0.006993 -0.073412 -0.104010 -0.006442 0.062073
+-0.052770 0.070835 -0.091445 -0.041991 -0.068768
+0.059883 0.020621 0.042259 0.038888 0.021605
+0.042693 0.038667 -0.040035 0.004977 -0.076466
+-0.022332 0.056801 -0.000212 0.035708 -0.032640
+-0.038064 0.006782 -0.009894 -0.100385 -0.033497
+0.025298 0.034269 0.027448 0.077164 0.050701
+-0.027548 -0.022455 -0.035381 0.018361 -0.004348
+-0.069287 -0.017294 -0.004310 0.071591 -0.054832
+-0.053949 -0.001929 0.071395 -0.015681 -0.038443
+-0.044016 -0.048662 0.078642 0.014355 0.048150
+-0.009957 0.032861 -0.075294 -0.123870 0.026265
+0.093728 0.046174 -0.009184 -0.050917 0.079102
+0.050699 -0.110383 -0.040917 -0.086311 0.012596
+0.001827 -0.059395 -0.048207 0.063786 0.026565
+-0.077077 -0.004569 -0.044546 -0.099623 0.006256
+-0.016101 -0.027424 0.017338 0.024906 0.015827
+-0.027372 -0.017107 0.034566 -0.019851 -0.035154
+0.065204 -0.032861 -0.006305 0.115986 0.005671
+0.060617 -0.019162 -0.098096 -0.042694 0.047107
+0.037104 -0.008058 0.084632 -0.004556 -0.101542
+0.075086 -0.009191 0.004624 -0.043225 -0.002498
+0.032484 0.053384 0.011807 -0.035382 0.158001
+-0.043066 -0.071159 0.039828 -0.062471 0.016281
+-0.043445 -0.029971 -0.014564 0.054938 -0.076111
+0.022672 0.108672 0.099046 0.018104 0.033550
+0.027144 -0.053217 0.067212 0.035840 -0.020805
+-0.064595 0.009953 -0.011147 -0.063721 0.036759
+0.018701 0.102409 -0.031796 0.011001 -0.023883
+0.028968 -0.057157 -0.042508 -0.052145 0.008972
+-0.065914 0.070920 -0.087959 0.024752 0.079740
+0.056457 0.008541 0.080771 -0.042955 -0.022030
+0.077296 -0.087393 -0.065077 0.010062 -0.035395
+-0.023652 0.009169 0.016281 0.043270 -0.112518
+0.024860 -0.024549 0.016927 -0.028905 0.029316
+-0.008912 -0.016575 -0.120884 0.023903 -0.054407
+0.044132 0.038152 0.018656 0.065922 -0.016132
+-0.006389 -0.043456 -0.005277 -0.038377 -0.043256
+-0.028775 -0.034704 0.041058 0.024792 0.075342
+-0.087680 -0.084754 -0.123797 0.069380 0.046858
+-0.058807 0.032247 -0.003162 0.075858 -0.011643
+-0.015012 0.064356 0.018978 -0.013598 0.027903
+-0.019744 -0.072473 0.036145 -0.023830 0.091601
+0.000445 0.030482 -0.087404 -0.045375 0.130636
+0.016918 0.057383 -0.002236 0.019154 0.035447
+-0.068637 -0.064903 0.079540 -0.091132 -0.027111
+0.020001 -0.002105 -0.063610 0.085303 0.021592
+0.135112 -0.114788 0.011338 -0.012485 0.059281
+0.089211 -0.036178 -0.066274 0.112956 0.046283
+-0.074477 -0.051750 0.031961 0.038617 0.011847
+0.114117 -0.067782 0.028677 0.047877 0.009921
+0.018292 0.016738 -0.056403 -0.038710 -0.010604
+0.020050 -0.022217 0.056833 0.036114 -0.051337
+0.155982 0.012794 -0.028857 -0.120583 0.084902
+0.013151 0.029339 0.004512 0.029269 0.158467
+-0.059083 -0.044942 -0.002369 0.025053 0.077484
+-0.006987 -0.128357 0.000998 0.000658 -0.008066
+0.002694 0.078402 0.051558 0.026018 -0.035135
+-0.051516 0.093206 0.075687 0.007585 -0.030493
+-0.042801 0.024643 0.035323 -0.068825 0.138089
+-0.012481 0.043826 -0.059032 -0.004079 -0.057181
+0.030592 -0.043929 0.081829 -0.034370 -0.027097
+-0.043916 0.028082 0.040159 -0.023825 0.016659
+-0.040314 0.027255 0.066119 -0.088450 0.079633
+0.085602 -0.045368 -0.019169 0.063621 0.015908
+-0.012968 0.043077 -0.011652 -0.009363 -0.072419
+0.041253 0.015117 -0.000599 -0.038888 -0.015197
+0.070823 -0.013167 -0.026186 0.024055 -0.072483
+-0.003924 0.013391 0.055366 0.084999 -0.038449
+0.043468 0.030321 -0.071656 -0.068751 -0.085100
+-0.045854 -0.012937 0.001146 0.029160 0.007917
+-0.038722 -0.013069 -0.022602 0.017646 0.050031
+-0.034069 0.004746 -0.045839 0.088322 -0.033433
+-0.049425 0.044323 0.135449 -0.033950 -0.006189
+0.008117 -0.074632 0.033319 0.057707 -0.034315
+0.061949 0.058279 -0.069064 -0.024633 0.083634
+0.044328 0.065502 0.039147 0.045297 0.010853
+-0.035928 -0.034367 0.029180 -0.079893 -0.056124
+-0.021337 0.069848 -0.042840 0.100637 -0.021594
+-0.017056 -0.026458 -0.005396 -0.038921 0.024334
+-0.013119 -0.040654 -0.019092 0.122318 0.060562
+0.014946 -0.017839 0.014916 0.007557 -0.055684
+0.085343 0.020079 -0.020189 0.024923 0.038626
+-0.008572 -0.098936 -0.015287 -0.036331 -0.030196
+0.029395 0.068464 0.062459 0.007118 -0.121145
+0.090713 0.018611 -0.060202 -0.064626 -0.026447
+0.020572 -0.066985 -0.020928 0.046500 0.071362
+-0.032780 -0.113550 -0.035570 -0.046101 0.123381
+-0.000637 -0.030887 -0.085549 0.058943 -0.047480
+-0.069392 0.133001 0.039940 -0.054277 0.026772
+0.012818 0.061828 0.101149 -0.034239 0.018944
+-0.101441 0.071801 -0.065653 -0.058695 0.062080
+0.017518 0.111010 -0.059046 -0.054110 -0.031295
+0.055930 -0.143458 -0.044617 -0.023186 -0.013649
+-0.111579 0.040441 -0.065712 0.110422 0.014995
+0.035371 0.001600 0.051063 -0.002833 0.096648
+0.023072 0.007446 -0.027126 -0.021716 0.006914
+-0.066680 -0.023776 -0.033004 0.018842 -0.100090
+0.006577 -0.009435 0.014480 0.005289 0.027268
+-0.023355 -0.000517 -0.035704 0.018493 -0.073805
+0.007356 0.036041 -0.026668 0.057975 -0.046666
+0.054676 0.021222 0.006590 -0.020075 -0.091969
+-0.024459 -0.004411 0.080089 0.014146 0.047996
+-0.013099 -0.028560 -0.086210 -0.038070 0.115542
+-0.029380 -0.069424 0.000189 0.102273 0.014531
+-0.058430 0.045176 -0.004636 -0.048318 0.011492
+-0.070572 -0.166966 0.056891 0.042773 0.015200
+0.025472 0.000731 -0.061858 -0.008651 0.108291
+0.012505 0.032344 0.012567 0.062585 0.015632
+-0.026488 -0.012319 0.030187 -0.052121 0.002827
+-0.017721 0.065865 -0.047380 0.020409 0.023943
+0.079766 -0.046306 0.060273 -0.027458 0.038828
+0.032883 -0.043636 0.000901 0.075220 -0.005792
+-0.090456 -0.041894 0.002536 -0.104333 -0.034913
+0.038532 -0.048225 0.033342 -0.011078 -0.035938
+0.000390 0.038012 -0.135572 -0.025786 -0.050179
+0.001333 -0.078764 0.020818 -0.022520 -0.065079
+0.013806 0.009337 0.024640 -0.064068 -0.007668
+-0.005821 0.054794 0.006679 0.052490 0.085097
+-0.084449 0.026105 0.043027 -0.006820 0.063480
+-0.005166 -0.108834 -0.074395 0.066384 0.003385
+0.002689 0.152176 0.074065 -0.025017 0.001996
+-0.026355 -0.035760 0.063399 -0.010722 -0.053613
+0.040833 0.083154 0.032094 -0.074978 0.040456
+0.007659 0.060872 -0.050901 0.029009 -0.066327
+0.040735 -0.106153 0.073500 -0.025479 -0.054887
+-0.075445 0.009415 0.016203 0.012388 0.014428
+0.000457 -0.036095 0.143621 0.046534 0.106183
+-0.039550 -0.060834 -0.058729 -0.030704 0.046588
+-0.069071 0.044146 -0.047632 -0.019171 -0.064829
+0.017817 0.047929 0.039073 0.022116 0.021014
+0.033732 0.050846 -0.059942 0.004345 -0.029985
+-0.080140 0.129440 0.031031 0.084146 0.016015
+-0.036682 0.044772 -0.049258 -0.056682 -0.051988
+0.039973 0.080584 0.002750 0.080571 0.017418
+-0.049233 -0.050745 -0.078517 0.041796 0.028714
+-0.073271 -0.009924 -0.046737 0.077202 -0.089452
+-0.100286 0.026524 0.025935 -0.000519 -0.108153
+-0.097136 -0.011694 0.088312 0.041746 0.052188
+0.026268 -0.054000 -0.039524 -0.030580 0.094436
+0.083377 0.058849 0.024027 0.068118 0.022595
+0.041719 -0.067897 0.005738 -0.058511 -0.080953
+-0.011827 -0.008352 -0.136686 0.077343 0.036266
+0.035162 -0.013237 -0.040135 -0.166246 0.029329
+0.031590 -0.082787 -0.003165 0.022566 -0.029527
+-0.026857 -0.030669 -0.012846 -0.014703 -0.024941
+0.097289 0.062474 -0.023270 0.071516 0.026007
+0.012490 -0.079323 -0.064277 -0.101304 -0.014965
+0.038609 0.050228 0.059018 -0.054583 -0.037042
+0.088943 -0.050793 -0.023046 -0.036841 -0.049866
+0.006089 -0.012353 0.050822 -0.044544 0.133501
+-0.044647 -0.060379 0.051279 -0.028470 0.068335
+-0.008481 -0.078112 -0.022666 0.077373 -0.024423
+0.000007 0.064437 0.062147 -0.038681 0.032008
+-0.017525 -0.067472 0.114370 0.020743 -0.076853
+-0.017874 0.001327 -0.014704 -0.014656 0.034577
+0.024361 0.056274 0.006448 -0.028830 0.044899
+0.016576 -0.044087 -0.010917 -0.013797 -0.018111
+-0.065385 -0.007719 -0.037632 0.031813 0.021400
+0.049162 0.020931 0.037485 -0.026412 0.056338
+0.036907 -0.042904 -0.132436 0.043098 -0.041228
+-0.035680 0.034986 0.047873 -0.072791 -0.131274
+0.044610 -0.023411 -0.025045 0.005907 0.046734
+-0.032724 -0.061008 -0.111818 0.015564 -0.002133
+-0.015445 -0.011766 -0.048157 0.139974 -0.079607
+0.004936 -0.033105 0.052832 -0.087579 -0.040662
+-0.055766 -0.026403 0.102134 0.084616 0.064986
+-0.020826 -0.077346 -0.025393 -0.002277 0.084614
+-0.053523 -0.091453 0.022927 0.150824 -0.002083
+-0.001161 0.030663 0.060472 -0.050918 0.018421
+0.027526 -0.091037 0.070144 0.040963 0.090458
+0.030099 0.071509 -0.062928 -0.052351 0.030143
+-0.026417 0.032481 -0.045066 0.000111 -0.004684
+-0.002093 -0.014278 0.173191 -0.019552 -0.072985
+0.033124 0.074779 -0.053669 0.106059 0.090086
+0.039197 -0.065054 0.025258 -0.050488 0.068107
+0.037370 -0.074734 -0.072895 0.041719 -0.026666
+-0.116776 -0.050593 -0.022049 0.019100 -0.052687
+0.077699 0.002538 0.021642 0.069070 -0.025842
+-0.025721 0.004558 -0.051248 -0.059783 -0.021367
+-0.043714 -0.040732 0.063823 0.074918 -0.079342
+0.050195 0.021249 -0.028816 -0.061727 0.018248
+0.005884 0.050434 -0.021363 -0.018341 0.100200
+-0.041043 -0.005428 0.011984 -0.030931 0.026453
+0.005239 -0.089215 -0.046851 0.018966 -0.029878
+-0.019543 0.106899 0.047058 -0.097279 -0.091117
+-0.029152 0.017775 0.066229 0.079262 -0.009853
+0.015344 0.002972 0.005261 -0.068619 0.065134
+0.021325 0.052198 -0.040335 -0.031105 -0.022038
+0.046868 -0.008746 0.024060 -0.039353 -0.043527
+-0.053729 0.048245 0.078712 0.063353 0.054853
+0.000893 -0.011563 0.116159 -0.043972 0.030272
+0.054786 -0.024768 -0.040403 0.056841 0.146419
+-0.034807 0.057094 -0.054852 0.104343 -0.076770
+0.050072 0.052860 0.019579 -0.001424 0.015739
+0.065242 -0.006303 -0.020658 -0.036628 -0.138792
+0.038907 0.049015 0.064288 0.105084 -0.009955
+-0.013576 0.042749 -0.058027 -0.060563 0.018986
+-0.042694 0.055557 0.029964 0.088314 0.017075
+-0.098025 -0.059071 -0.029354 0.030490 0.045049
+-0.039481 -0.016714 -0.028323 0.051148 -0.033224
+-0.012870 -0.002631 0.095782 -0.018745 -0.067411
+-0.067803 -0.096432 0.048605 0.001590 -0.007541
+0.020762 0.011888 -0.020905 -0.048766 0.049192
+0.094934 0.090567 -0.064939 0.021130 0.094459
+-0.009557 -0.060711 -0.057713 -0.034265 -0.053583
+-0.016969 -0.012648 -0.063332 0.105446 0.016028
+-0.006489 -0.023448 0.027450 -0.092041 -0.002328
+0.038286 -0.093578 0.014068 0.045683 0.038064
+-0.013579 0.012105 0.031264 0.028629 -0.053522
+0.018638 0.010295 -0.019741 0.051773 0.021102
+-0.003833 -0.088492 -0.107650 -0.039638 -0.042960
+0.017232 0.033768 0.024773 0.031441 -0.026193
+0.102995 -0.003033 0.013478 -0.022850 -0.045542
+-0.043058 0.040213 -0.037024 0.062912 0.127046
+0.001959 -0.029856 0.021744 -0.024546 0.073822
+0.034590 -0.034810 -0.073281 0.037715 -0.086249
+-0.031013 0.094574 -0.014633 0.035329 -0.001586
+-0.004488 -0.022600 0.105074 0.068271 0.014684
+-0.069910 0.035216 -0.046091 -0.056792 0.016636
+-0.031304 0.104876 0.015142 -0.014980 -0.018234
+0.076863 -0.070661 -0.018752 0.021078 -0.015693
+-0.082177 0.139823 -0.020936 0.000788 -0.047650
+0.086463 0.003184 0.053978 0.016598 0.005082
+0.037579 -0.007222 -0.068342 0.001780 -0.016838
+0.000034 0.019368 -0.028889 -0.073195 -0.167931
+-0.002740 -0.051503 0.060666 -0.048875 0.013166
+-0.002367 0.018484 -0.088268 0.058154 -0.005778
+-0.019212 0.030488 -0.007580 0.042345 -0.062956
+0.013296 0.040910 0.018849 -0.062445 -0.062359
+-0.004222 -0.003121 0.026069 0.075825 0.086917
+0.019144 -0.018779 -0.072348 -0.063072 0.046388
+0.009524 -0.032045 0.075619 0.076314 -0.042349
+-0.026193 -0.003729 0.066560 -0.103338 -0.004071
+-0.000469 -0.090470 0.033564 -0.067881 0.027775
+0.040936 0.054314 -0.123113 -0.001763 0.032899
+0.028282 0.057689 -0.011369 0.021664 -0.023786
+-0.104368 -0.070997 0.059588 -0.014596 -0.042435
+0.003429 0.090193 -0.113362 -0.007873 0.011799
+0.036299 -0.059670 0.054351 -0.084675 0.034819
+-0.007507 -0.018723 -0.009649 0.092970 0.008836
+-0.028752 -0.044170 -0.070934 -0.103397 -0.030638
+0.048533 -0.032645 0.020691 0.053664 0.011144
+-0.021593 0.015401 -0.085379 -0.058031 -0.078320
+-0.003648 -0.010436 -0.012911 -0.007136 -0.134525
+0.030251 0.042795 0.087389 -0.092708 -0.026287
+-0.039855 0.155791 -0.013492 -0.036665 0.072298
+-0.133309 -0.003156 0.013287 -0.012142 0.018020
+-0.071518 -0.038880 -0.026195 0.009773 -0.006971
+0.044349 0.079337 0.015294 -0.035758 -0.003607
+-0.058092 0.001525 0.042209 0.047862 -0.061178
+0.014357 0.093707 0.022406 -0.118850 -0.034213
+0.019269 0.070424 -0.016998 0.021550 -0.094794
+0.004962 -0.108204 0.128671 0.015466 0.031554
+-0.080559 0.041092 0.022039 0.001186 -0.022630
+-0.043310 0.005192 0.074769 -0.022963 0.039941
+0.055086 -0.081362 -0.064870 0.040274 0.052633
+-0.062993 0.085037 -0.010420 -0.016774 -0.052155
+0.002576 0.013639 0.061713 0.041734 -0.008138
+0.080793 0.024851 -0.042037 0.019932 -0.048494
+-0.029059 0.146206 0.042139 0.033378 -0.021081
+-0.014080 0.001144 -0.016467 -0.076606 -0.056525
+0.005355 0.079452 0.043451 0.085716 0.029884
+-0.042582 -0.055446 0.005137 0.000476 0.001691
+-0.041210 -0.077759 0.022581 0.046845 -0.028540
+-0.120802 -0.013263 0.072039 -0.031588 -0.006830
+-0.040167 -0.125914 0.088795 0.022744 0.055951
+0.003326 0.027383 -0.028722 -0.123214 0.059791
+0.097070 0.030682 -0.019252 0.000330 0.082240
+0.006364 -0.113196 0.035671 -0.063923 -0.075420
+0.017812 -0.046079 -0.059540 0.093696 0.056472
+-0.031904 -0.065015 -0.019089 -0.091007 0.031632
+0.018500 -0.054687 0.032704 0.040721 0.012163
+-0.041854 -0.010613 -0.017039 -0.028850 -0.061295
+0.029279 0.000022 -0.023031 0.084704 0.032995
+0.000464 -0.042280 -0.122277 -0.133466 0.058700
+0.095073 0.044206 0.068361 0.039925 -0.039455
+0.043618 -0.033785 0.035086 -0.056425 0.019711
+0.049265 0.053168 0.030600 -0.096642 0.090726
+-0.078183 -0.002747 0.032400 -0.043278 0.040809
+-0.019946 -0.088229 0.027009 0.056114 -0.113044
+-0.020901 0.076359 0.059245 0.016714 0.040966
+-0.010584 -0.003554 0.056159 0.010151 0.000010
+-0.027039 0.073329 -0.015462 -0.016179 0.013943
+0.075066 0.067462 -0.030769 -0.024755 -0.022212
+0.040264 -0.071337 0.009512 -0.045952 0.023049
+-0.094656 0.057345 -0.124101 -0.007720 0.037588
+0.036110 -0.011456 0.089645 -0.007765 0.014716
+0.059788 -0.047648 -0.019740 -0.007164 -0.013816
+-0.060158 0.013439 0.002759 -0.025340 -0.091571
+0.043341 -0.028869 0.026551 -0.031854 0.060505
+-0.049549 0.033978 -0.109503 0.068308 -0.028080
+0.053928 -0.022460 -0.086171 0.086833 -0.045654
+0.000759 -0.010999 0.026013 -0.046809 -0.054160
+-0.030739 -0.041475 -0.010348 0.057903 0.106187
+-0.031967 -0.136159 -0.056033 0.020976 0.056817
+-0.030310 0.060592 0.045537 0.086963 -0.032719
+0.018689 0.033949 0.017964 -0.019455 0.008378
+0.014325 -0.124934 -0.010142 0.033116 0.066121
+-0.008592 0.059328 -0.090438 -0.060148 0.065598
+-0.010732 0.014210 -0.046081 0.019411 0.040325
+-0.012140 -0.084611 0.064608 -0.023209 -0.018978
+0.028244 -0.000390 -0.070852 0.136445 0.055833
+0.034530 -0.106636 -0.049748 -0.043837 0.056670
+-0.020391 -0.027277 -0.125403 0.082621 -0.064172
+-0.085208 -0.034925 0.000691 -0.016798 0.037357
+0.058365 -0.014015 0.051315 0.078205 0.001672
+0.009538 0.041777 0.001519 -0.031501 -0.027967
+0.008286 -0.051667 0.045953 0.057151 -0.083565
+0.099401 0.052489 0.027972 -0.093449 0.022696
+0.014953 0.056948 0.062741 0.024005 0.076825
+-0.029857 -0.002820 0.046866 -0.002247 0.022284
+-0.005875 -0.120877 -0.029880 0.030478 -0.074641
+0.026517 0.141968 0.041939 -0.017604 -0.063098
+-0.042315 0.108332 0.077079 0.042498 -0.093786
+-0.000624 0.109876 0.061671 -0.037131 0.145507
+-0.015339 0.059306 -0.094584 0.004561 -0.031261
+0.003112 -0.004144 0.054816 -0.035342 -0.020048
+-0.055998 -0.008131 0.096183 0.002903 0.002243
+-0.024465 -0.011484 0.122067 -0.117424 0.061629
+0.100785 -0.008995 -0.021311 -0.034915 0.028992
+-0.065386 0.062233 0.009424 0.013652 -0.066035
+0.068604 0.015424 -0.016048 -0.028882 -0.021780
+0.034733 -0.052918 -0.046384 0.003918 -0.037747
+0.012883 0.061961 0.011614 0.047979 -0.020950
+0.012662 -0.003597 -0.016134 -0.114584 -0.032846
+-0.025773 0.029225 0.029423 0.035929 0.050919
+-0.093288 0.024548 0.026469 0.086567 0.069788
+-0.015915 0.014888 -0.054796 0.032121 0.010392
+0.010094 0.027316 0.105326 -0.033913 -0.034646
+-0.047655 -0.119467 0.014906 0.070898 -0.051722
+0.085920 0.026450 -0.048565 -0.048393 0.040708
+0.013886 0.115144 0.000426 0.025815 0.028617
+-0.076183 -0.060818 0.007730 -0.030613 -0.106233
+0.008414 0.008274 -0.071702 0.123060 -0.014131
+-0.075611 -0.006558 -0.031029 -0.038394 0.018650
+-0.068219 -0.088628 0.017122 0.073322 0.003094
+0.023978 -0.022533 0.052647 0.005485 -0.022853
+0.047387 0.058945 -0.012186 0.049493 0.117395
+-0.008681 -0.136174 -0.057438 -0.017543 -0.020215
+0.064213 -0.018764 0.030830 0.026967 -0.104162
+0.097321 0.026515 -0.008192 -0.071056 -0.023457
+0.037214 -0.028805 0.019265 0.010163 0.118572
+-0.083174 -0.026261 -0.079021 -0.109716 0.081199
+-0.001821 -0.039505 -0.064758 0.022196 -0.008395
+-0.056773 0.070319 0.039957 -0.024091 -0.012671
+0.043873 0.034859 0.113349 0.002335 -0.016767
+-0.117575 0.038224 -0.016650 -0.007249 -0.028289
+-0.020867 0.099598 -0.027205 -0.047643 -0.022079
+0.062869 -0.095742 0.004349 -0.009783 -0.009631
+-0.114174 0.101698 -0.020882 0.032183 0.046772
+0.066030 0.023138 0.031676 0.048789 0.064708
+0.016049 -0.022143 -0.026033 0.014811 0.017879
+0.005234 -0.011470 -0.061933 0.012402 -0.073904
+-0.008574 0.011810 0.022041 -0.034666 0.015863
+0.032824 0.011302 -0.083572 0.034152 -0.049572
+0.046696 -0.004826 -0.026282 0.006930 -0.036282
+0.018845 0.023008 -0.022702 0.002839 -0.056809
+0.046756 -0.012044 0.093032 0.037759 0.053581
+-0.068607 -0.014841 -0.102444 -0.056353 0.054083
+0.022493 -0.027398 0.044342 0.073545 -0.016381
+-0.030891 0.080430 0.020741 -0.064660 -0.030998
+-0.064001 -0.094590 -0.012708 0.031636 0.033664
+0.017650 -0.020332 -0.049802 0.010802 0.048687
+-0.014333 0.032177 -0.003331 0.031214 -0.009314
+-0.043033 -0.047137 0.054111 -0.030505 -0.006532
+0.021755 0.050908 -0.056081 0.074478 0.019301
+0.003105 -0.097554 0.054912 -0.016068 0.031570
+0.019298 -0.067236 -0.010230 0.065782 -0.048545
+-0.032341 -0.039446 -0.004134 -0.054109 -0.014461
+0.064470 -0.004466 0.064183 -0.013807 -0.040371
+0.012385 -0.043869 -0.179654 -0.075267 -0.058833
+0.027833 -0.078315 0.006233 0.019417 -0.100407
+0.057753 0.000717 0.032416 -0.121474 -0.047213
+-0.015720 0.092246 -0.059387 0.040603 0.109440
+-0.058153 0.071202 0.030939 0.049569 0.087021
+-0.076095 -0.131564 -0.027353 -0.000486 -0.015803
+0.104552 0.088105 0.072307 -0.020686 0.043142
+-0.089957 0.000627 0.140513 0.006435 -0.023427
+-0.000585 0.090754 0.029188 -0.057282 0.010274
+0.075187 0.111159 -0.057877 0.069809 -0.050756
+0.062932 -0.036407 0.050992 0.009269 -0.006383
+-0.106503 0.017063 0.008141 0.064195 -0.045832
+0.011576 -0.041847 0.061264 -0.005204 0.058984
+0.021548 -0.048377 -0.044097 0.010789 0.013451
+-0.063551 0.063079 -0.080144 -0.027762 -0.017784
+-0.023803 0.027775 0.060824 0.001841 -0.009369
+0.061007 0.032254 -0.064190 -0.006988 -0.010230
+-0.038793 0.076776 0.045814 0.049754 0.027771
+-0.047904 0.017897 -0.052309 -0.106778 -0.037221
+0.011510 0.060085 -0.009615 0.096725 0.047490
+-0.010900 -0.074275 -0.061489 0.016070 0.006262
+-0.121827 0.005654 -0.050379 0.042456 -0.027064
+-0.068110 0.106922 0.068599 -0.034845 -0.067145
+-0.036874 -0.041315 0.035902 0.059175 0.013939
+0.008294 -0.000352 -0.046255 -0.058090 0.089826
+0.091060 0.092701 0.009236 0.013325 -0.019194
+0.039376 -0.018583 -0.016868 -0.096550 -0.086377
+-0.016296 0.002608 -0.083265 0.049964 0.042836
+-0.011462 -0.046261 0.084247 -0.180528 0.034023
+0.041962 -0.128842 -0.057438 0.031753 -0.013294
+-0.008752 -0.054893 -0.036386 -0.004605 -0.020903
+0.113550 0.017158 -0.063971 0.047456 0.033803
+0.026820 -0.033048 -0.057221 -0.039801 -0.029135
+0.004112 0.055166 0.080631 0.011347 -0.039214
+0.069633 -0.057947 0.018314 -0.110810 -0.006258
+0.011057 -0.058755 -0.016184 -0.078348 0.154720
+-0.056156 -0.110551 0.114867 -0.031689 0.014677
+0.024109 -0.060048 0.019844 0.109975 -0.045339
+0.002565 0.067118 0.019907 0.004995 0.078815
+-0.017892 0.015592 0.118138 0.009682 -0.024624
+-0.025684 0.027247 -0.044912 -0.011851 0.057506
+0.106751 0.066538 -0.073230 -0.069470 -0.044869
+-0.007738 -0.078232 0.000098 -0.056553 -0.000261
+-0.069574 0.025403 -0.032460 0.042204 -0.009414
+0.024336 0.002379 0.084422 -0.062254 0.070007
+0.083297 0.011215 -0.087554 0.008854 -0.031248
+-0.019485 0.015117 0.019539 -0.018885 -0.091190
+0.006668 -0.029364 0.010585 0.004194 0.053285
+-0.032862 0.007750 -0.181078 0.014752 -0.032591
+0.035286 0.052475 -0.044255 0.152326 -0.034986
+0.001871 -0.048154 0.032533 -0.150372 -0.061009
+0.025623 -0.057468 0.099245 0.098809 0.047259
+-0.017644 -0.089718 -0.052981 0.060000 0.050683
+-0.093984 -0.012007 0.021790 0.115572 0.011056
+-0.005239 0.022166 0.036556 -0.019139 -0.017723
+0.036182 -0.053160 0.008506 0.003654 0.035883
+-0.011143 0.126442 -0.042372 -0.049170 0.021566
+-0.034390 0.004133 -0.083543 0.003794 0.003199
+0.023898 -0.058139 0.097937 -0.021906 -0.118046
+-0.009779 0.053140 -0.086424 0.032891 0.040964
+0.003078 -0.054441 -0.008601 -0.059920 0.074604
+0.120587 -0.102501 -0.066840 0.070391 0.032323
+-0.084081 -0.025867 0.003136 -0.037883 -0.064963
+0.077565 -0.011987 -0.030929 0.076324 -0.096244
+-0.003417 0.038221 -0.027320 -0.034091 0.001490
+-0.007638 -0.034015 0.052893 0.055546 -0.147361
+0.042258 -0.020035 -0.017400 -0.076711 -0.017528
+0.045540 0.051725 -0.024199 -0.035180 0.069090
+-0.066211 0.016712 0.012236 -0.023556 -0.008512
+-0.043404 -0.040132 0.006223 0.020953 -0.040829
+-0.031888 0.063196 0.044618 -0.021241 -0.065557
+0.013691 0.016905 0.113755 0.054933 -0.021644
+0.016741 0.030625 0.010121 -0.037365 0.072566
+0.006060 0.080380 -0.086262 -0.033079 -0.082250
+0.087161 -0.049737 0.100611 -0.073241 -0.060578
+-0.018873 0.076177 0.146262 0.031684 -0.014816
+-0.074152 0.012492 0.111905 -0.037241 0.036831
+0.091650 -0.058779 -0.035497 0.009717 0.105238
+-0.068452 0.050555 -0.035241 0.038942 -0.086304
+0.055772 0.028480 0.055647 -0.013345 0.009719
+0.060855 -0.009449 -0.029466 -0.039618 -0.045775
+0.012008 0.093753 0.059452 0.084398 -0.063094
+0.003659 0.074625 -0.110159 -0.075540 -0.006386
+0.010137 0.032774 0.014827 0.166347 0.079179
+-0.032299 -0.047524 -0.033098 0.052546 0.023211
+-0.005083 -0.040770 0.010451 0.047465 -0.015315
+-0.001296 0.006073 0.070897 -0.060137 -0.051576
+-0.032384 -0.082914 0.047391 0.018599 -0.072054
+0.020109 0.006570 -0.072222 -0.028125 0.023991
+0.073458 0.052141 -0.039550 0.020745 -0.004247
+-0.027316 -0.026412 -0.050898 -0.048547 -0.135601
+-0.022268 0.038434 -0.006989 0.106829 0.013384
+0.000746 0.016253 -0.014804 -0.086222 0.017979
+0.043413 -0.078404 0.050130 0.105998 0.009523
+-0.080688 -0.029072 0.043530 0.018815 -0.027097
+0.017270 0.008265 0.029905 0.025756 0.068311
+0.010413 -0.062141 -0.092435 -0.009085 -0.011445
+0.024539 0.076003 0.038136 -0.010407 -0.045941
+0.082228 -0.001579 -0.035917 0.064558 -0.023500
+-0.063481 0.003930 -0.067573 0.030233 0.098224
+-0.042799 0.003064 0.009816 -0.008225 0.109707
+-0.034960 -0.080238 -0.123786 0.048109 -0.059473
+-0.055367 0.057060 -0.001238 0.030381 0.025074
+0.006831 0.017900 0.111674 0.097968 0.015896
+-0.050238 0.041727 -0.107658 -0.072374 -0.018776
+0.001860 0.159151 -0.015443 -0.046034 -0.062151
+0.065586 -0.066719 0.031320 0.059675 -0.022808
+-0.066461 0.086303 -0.026658 0.070774 0.006480
+0.159805 -0.035879 0.058009 0.012928 -0.008505
+0.051041 -0.000692 -0.022889 0.039547 0.001201
+-0.030295 0.029145 -0.073169 -0.019964 -0.102560
+-0.021646 -0.009084 0.039313 -0.008758 0.059413
+0.019112 0.068432 -0.154269 0.042342 -0.017110
+0.003279 0.087898 0.002044 0.110066 -0.076844
+0.041884 0.035740 -0.001247 -0.094360 -0.090406
+0.040890 -0.028718 0.013704 0.031084 0.040651
+-0.028325 -0.027470 -0.060171 -0.069388 0.051373
+-0.010018 0.016317 0.030962 0.131065 -0.012443
+-0.085994 0.023695 0.036048 -0.123378 0.017394
+-0.014188 -0.147008 0.010122 -0.048605 0.011567
+0.011549 0.033481 -0.087698 -0.007977 0.012262
+0.046426 0.046093 -0.000803 0.034084 0.024231
+-0.011190 -0.037156 0.022545 0.009116 -0.021868
+0.000176 0.161431 -0.066441 -0.004212 0.008997
+-0.027580 -0.039554 0.047688 -0.114080 0.037481
+0.021017 -0.015449 0.023651 0.076890 -0.062376
+-0.089367 -0.035901 -0.117304 -0.014988 -0.004232
+0.065798 -0.038753 0.006615 0.027216 0.000892
+-0.043842 -0.027915 -0.077769 -0.025289 0.007296
+0.021684 -0.008098 0.034493 0.002195 -0.089680
+0.015447 0.014866 0.063536 -0.107947 0.040356
+-0.049353 0.085041 -0.019010 0.017126 0.054466
+-0.095573 0.040640 0.005208 0.001846 0.046985
+-0.060406 -0.059147 -0.078410 0.032047 -0.027762
+0.023664 0.067476 0.025927 0.004505 -0.005180
+-0.107366 -0.052865 0.059971 0.018624 -0.086019
+-0.038792 0.082042 -0.009606 -0.082518 0.048899
+-0.032272 0.118434 -0.029891 0.014012 -0.078772
+0.071631 -0.124648 0.096824 0.071580 -0.014951
+-0.078224 0.028148 0.050459 0.044666 -0.016543
+-0.039821 -0.016072 0.087706 -0.056648 0.087416
+0.030016 -0.076113 -0.101181 -0.049336 0.048944
+-0.063956 0.087916 -0.036885 -0.059650 -0.044808
+0.054549 0.006956 0.033701 0.030349 -0.017304
+0.057616 0.016137 -0.052723 0.039906 -0.101393
+-0.068763 0.099576 0.006264 0.083677 -0.032515
+-0.006446 0.031066 0.009386 -0.132131 -0.067080
+0.049843 0.065652 0.020336 0.046760 0.071347
+-0.013796 -0.001044 -0.022677 0.019523 0.014154
+-0.120083 -0.039608 0.050937 0.066017 -0.034193
+-0.069836 0.025969 0.058877 -0.033911 -0.021741
+0.005164 -0.037563 0.051151 0.030827 0.041654
+-0.050675 0.032902 -0.056904 -0.083309 0.051372
+0.092971 0.070309 0.017775 -0.033610 0.023024
+0.044912 -0.113795 0.009331 -0.100912 -0.024567
+0.000589 -0.023568 -0.041534 0.046948 0.019053
+-0.031982 -0.010104 -0.033008 -0.120085 0.014601
+-0.013314 -0.032777 0.022640 0.053925 0.056793
+-0.009301 0.011372 0.004027 -0.017398 -0.055177
+0.038121 -0.000187 0.037310 0.135976 0.012337
+0.060620 -0.032842 -0.103898 -0.068672 0.001160
+0.043004 -0.011293 0.085530 0.053401 -0.086065
+0.123377 0.016620 0.045728 -0.034590 -0.014069
+0.081166 0.009573 0.008541 0.007549 0.143099
+-0.050664 -0.045174 0.012225 -0.052408 0.008760
+-0.016453 -0.030851 -0.052611 0.054134 -0.086747
+-0.068170 0.152077 0.049576 0.035454 0.051824
+0.042151 -0.013574 0.070619 0.043677 -0.011524
+-0.051292 0.065538 -0.002312 -0.036357 0.061560
+0.011089 0.083280 -0.022801 -0.035830 0.007115
+0.022494 -0.033816 -0.026885 -0.055802 0.037931
+-0.067432 0.034696 -0.048668 0.025237 0.063419
+0.052414 0.002888 0.073912 -0.070773 0.030231
+0.098077 -0.052981 -0.038547 -0.044533 0.015899
+-0.006684 0.059142 0.015994 -0.010569 -0.114343
+0.049113 0.011781 0.007813 -0.023202 0.027226
+-0.048228 0.023363 -0.119744 -0.005880 -0.047102
+0.056647 0.043309 -0.020351 0.078326 -0.050033
+0.004297 -0.004014 -0.008930 -0.041817 -0.061743
+-0.031268 0.020567 0.053127 0.035109 0.095886
+-0.022695 -0.103689 -0.101536 -0.035350 0.033822
+-0.071528 -0.027884 -0.013301 0.135256 -0.057997
+-0.006784 0.025162 0.014105 -0.008340 0.036569
+-0.047669 -0.071591 0.074153 -0.001441 0.118717
+-0.038919 0.054650 -0.101206 -0.019929 0.096971
+0.019005 0.066319 -0.033069 -0.010263 0.057814
+-0.038319 -0.115955 0.048866 -0.085605 -0.005601
+0.066517 -0.010474 -0.068925 0.056969 0.055565
+0.068964 -0.047482 -0.006419 -0.087153 0.047383
+0.032670 -0.032209 -0.036239 0.140438 -0.038488
+-0.103112 -0.063917 0.016553 0.017109 -0.018945
+0.071205 -0.057507 0.036017 0.043139 0.045741
+0.011471 0.019692 -0.031466 -0.001430 -0.027755
+-0.010061 -0.028245 0.031925 0.070075 -0.044640
+0.079725 -0.005444 -0.055716 -0.081872 0.035299
+-0.020415 0.060898 0.037726 -0.007902 0.118692
+-0.091406 -0.074996 0.014883 -0.011479 0.096472
+-0.004637 -0.120365 0.011661 -0.019123 -0.055083
+-0.021707 0.080305 0.062197 -0.007888 -0.014681
+-0.064206 0.034037 0.066576 0.037499 -0.089224
+-0.027816 0.038300 -0.009289 -0.093182 0.126160
+0.000015 0.066641 -0.028392 0.023167 -0.021511
+0.010571 -0.044084 0.057444 0.012462 0.005604
+-0.062572 0.054520 0.053554 0.005974 0.010050
+-0.037332 0.047516 0.066630 -0.035787 0.074909
+0.066925 -0.030867 -0.053629 0.022622 0.033939
+-0.033606 0.038370 0.006718 0.000847 -0.048333
+0.027340 -0.025685 0.007564 -0.047322 -0.016881
+0.054471 -0.017126 -0.063705 0.008150 -0.059374
+0.010814 0.037617 0.025879 0.059782 -0.064248
+0.042565 0.025815 -0.028591 -0.064574 -0.034454
+-0.031756 0.000598 0.011630 0.073568 0.026113
+-0.014567 0.003799 -0.014072 0.027953 0.071711
+-0.011735 0.014001 -0.022183 0.070160 -0.007010
+-0.049052 0.104807 0.111959 -0.037082 -0.007329
+-0.011153 -0.073166 0.045311 0.040814 -0.001227
+0.040666 0.038813 -0.049173 -0.078035 0.061429
+0.063840 0.120475 0.035684 0.029819 0.046868
+-0.017290 -0.035945 0.064987 -0.053189 -0.049460
+-0.030434 0.069244 -0.015774 0.136658 -0.012690
+0.005401 -0.045873 0.006291 -0.075787 0.046146
+-0.001969 -0.104323 -0.047978 0.150326 0.032908
+-0.004080 -0.012965 -0.015875 0.014424 -0.040690
+0.098688 0.025183 -0.017974 0.072128 0.070408
+-0.030717 -0.065297 -0.073385 -0.051253 -0.014989
+0.058581 0.033837 0.014225 0.031069 -0.081646
+0.089555 -0.017678 -0.068486 -0.040654 -0.051917
+0.047272 -0.042437 -0.042350 0.019696 0.085122
+-0.053413 -0.122905 -0.021426 -0.039696 0.051817
+0.020410 -0.050261 -0.093654 -0.001174 -0.043672
+-0.102482 0.084668 0.098393 -0.052216 0.050107
+-0.005196 0.034413 0.122643 -0.031565 0.066945
+-0.079300 0.072369 -0.011993 -0.035713 0.023269
+-0.002546 0.076113 -0.067724 -0.084767 -0.053840
+0.037939 -0.091041 -0.026871 -0.009130 -0.021081
+-0.067836 0.022012 -0.052138 0.083855 0.065835
+0.061174 -0.015388 0.100602 -0.009214 0.131331
+0.048374 -0.020733 -0.009385 -0.013658 0.012043
+-0.057898 -0.017737 -0.088355 0.024991 -0.079612
+0.000356 0.019063 0.032476 0.022195 0.010063
+-0.017095 0.024040 -0.080464 0.063948 -0.114944
+0.012612 0.022171 -0.005737 0.035304 -0.061207
+0.055311 0.033024 0.010681 -0.035592 -0.053947
+-0.011004 -0.012254 0.055221 0.045545 0.049084
+0.005046 -0.005400 -0.115901 -0.044796 0.068701
+-0.005781 -0.031080 0.037791 0.097212 0.026378
+-0.032777 0.026666 0.006559 -0.032347 -0.025736
+-0.039802 -0.165807 0.007831 0.003219 0.090520
+0.051658 -0.027677 -0.121531 0.016080 0.074249
+-0.017031 0.055987 0.005024 0.056572 0.006367
+-0.029525 -0.005725 0.069335 -0.024541 -0.003936
+-0.050003 0.053274 -0.052184 0.045028 0.014532
+0.039597 -0.056809 0.094737 -0.048726 0.081476
+0.030138 -0.008376 0.001189 0.059831 -0.018934
+-0.069575 0.002414 -0.006677 -0.061422 -0.024261
+0.061177 -0.023449 -0.000323 -0.012054 -0.074484
+0.038383 0.021929 -0.101717 -0.022789 -0.036563
+0.013636 -0.063362 0.053011 0.004735 -0.077306
+0.008396 0.043986 0.028657 -0.067441 -0.008945
+-0.037043 0.071514 -0.037839 0.077754 0.066277
+-0.065319 -0.001333 0.067596 -0.021862 0.099395
+-0.063958 -0.082056 -0.044809 0.063666 0.000060
+0.046881 0.121405 0.030877 -0.008566 0.007738
+-0.043809 -0.049349 0.046172 0.040387 -0.045205
+0.007940 0.060687 -0.036544 -0.076121 0.042696
+-0.003337 0.102081 -0.040222 0.067540 -0.025542
+0.030041 -0.090029 0.041031 0.020329 -0.012727
+-0.089279 0.046642 0.018999 0.055650 0.032822
+-0.052350 -0.055869 0.123885 -0.019014 0.088042
+0.001830 -0.080700 -0.023798 -0.021378 0.007657
+-0.042996 0.023456 -0.055210 -0.018485 -0.033292
+-0.016446 0.052880 0.043571 0.032302 -0.006553
+0.054726 0.057637 -0.079728 0.030525 -0.045654
+-0.016583 0.136252 -0.001399 0.088342 0.059925
+-0.018644 0.033899 -0.026838 -0.060676 -0.084264
+-0.007612 0.086537 -0.000185 0.091345 0.006932
+-0.012308 -0.029627 -0.057073 -0.008780 0.039234
+-0.044963 -0.042058 -0.067929 0.074154 -0.051802
+-0.061304 0.020025 0.026829 -0.086288 -0.076261
+-0.069406 -0.050920 0.124796 0.022026 0.010977
+0.038169 -0.027398 -0.073580 -0.056630 0.093880
+0.081911 0.024440 0.008606 0.033419 -0.000580
+0.033675 -0.032327 -0.007767 -0.065309 -0.050057
+-0.050072 -0.014708 -0.100502 0.074529 0.005808
+0.016991 -0.022397 -0.012659 -0.102715 0.069860
+0.007505 -0.098626 0.017930 0.000660 0.030909
+-0.019108 -0.001078 -0.038606 -0.007684 -0.046485
+0.070639 0.016330 -0.034902 0.085208 0.016702
+0.031560 -0.039036 -0.086796 -0.116810 -0.043757
+0.027858 0.024031 0.045674 -0.036231 -0.081680
+0.085800 -0.045662 -0.023544 -0.087212 -0.075608
+-0.015723 -0.040238 0.013265 -0.085104 0.106223
+-0.082075 -0.107869 0.056348 -0.031110 0.053637
+0.000135 -0.037700 -0.055809 0.094526 -0.021978
+0.034525 0.054227 0.053019 0.003097 0.040872
+-0.039125 -0.085945 0.154564 0.038990 -0.027547
+0.001012 0.012970 -0.012585 -0.008224 0.076006
+0.057344 0.055498 -0.015305 -0.064045 -0.009027
+0.028053 -0.055613 0.019793 0.005156 -0.005730
+-0.081848 0.009551 -0.035835 -0.005885 -0.006310
+0.056241 0.074335 0.101385 -0.045124 0.075779
+0.098255 -0.025349 -0.135871 0.068593 0.018442
+0.008761 -0.006857 0.032026 -0.041062 -0.176540
+-0.003354 -0.030120 -0.024455 -0.009820 0.053273
+-0.013461 -0.013288 -0.112246 0.007427 0.011505
+0.000211 -0.007304 -0.033855 0.097950 -0.118398
+0.030054 0.000253 0.110782 -0.135596 -0.057368
+-0.016542 -0.002743 0.078980 0.080403 0.081391
+-0.047818 -0.058659 -0.050242 0.012663 0.083037
+-0.061626 0.019808 -0.007693 0.160145 0.019543
+0.010731 0.046526 0.068954 -0.024462 -0.015987
+0.057362 -0.091820 0.016953 0.016968 0.076250
+0.018441 0.111365 -0.067091 -0.018485 0.053164
+0.005666 0.035169 -0.035022 -0.006122 -0.002602
+-0.047379 -0.023841 0.119826 -0.069174 -0.036278
+0.066394 0.057299 -0.074109 0.057609 0.038296
+0.057444 -0.029816 0.022335 -0.034234 0.104815
+0.048829 -0.043111 -0.072490 0.067468 0.004571
+-0.110285 -0.021601 -0.020759 -0.012685 -0.017656
+0.126982 0.016916 -0.004567 0.107105 -0.027552
+0.007144 -0.013052 -0.020950 -0.061707 -0.025117
+-0.020557 -0.015960 0.045201 0.121070 -0.089963
+0.035852 0.025505 -0.020181 -0.106140 0.001278
+-0.003190 0.085573 -0.040587 -0.057134 0.092945
+-0.049909 0.014414 0.010498 -0.020042 0.053348
+-0.005743 -0.065367 -0.017619 0.024990 -0.016761
+-0.001102 0.081298 0.066867 -0.051868 -0.045101
+-0.008798 0.003830 0.082195 0.041312 -0.048878
+0.029855 0.023388 0.029924 -0.050988 0.039197
+-0.009097 0.043885 -0.079323 -0.043981 -0.028178
+0.066419 0.012794 0.059244 -0.059898 -0.071819
+-0.106012 0.055735 0.110205 0.053225 -0.000572
+-0.024268 -0.039276 0.113882 -0.011410 0.026499
+0.086180 -0.011966 0.013046 0.031127 0.066167
+-0.027553 0.060671 -0.045735 0.060949 -0.051384
+0.048136 0.029615 0.023552 0.009801 0.050664
+0.065347 -0.026945 -0.067001 -0.022261 -0.108076
+0.060158 0.041960 0.067335 0.052471 -0.029246
+0.005009 0.007741 -0.052254 -0.083086 -0.017223
+-0.052633 0.052579 0.067865 0.153710 0.017808
+-0.087647 -0.021298 -0.079632 0.070262 0.044472
+-0.050379 -0.010528 -0.002296 0.013103 -0.019826
+-0.007796 0.016897 0.056191 0.006326 -0.079428
+-0.036621 -0.124708 0.063044 -0.022890 -0.045545
+0.041047 0.025474 -0.028608 0.002726 0.048077
+0.099637 0.066892 -0.070620 0.001304 0.013309
+-0.014646 -0.054310 -0.000625 -0.041803 -0.102217
+-0.045571 -0.015019 -0.026224 0.105191 0.032885
+-0.000149 -0.033313 0.006390 -0.078169 -0.030753
+0.041211 -0.066981 0.004327 0.092330 0.071230
+-0.029542 0.036311 0.054269 0.022893 -0.046259
+-0.001621 -0.003966 0.005826 0.056342 0.042238
+-0.028467 -0.044194 -0.112504 -0.019352 -0.056343
+0.025104 0.017498 0.028931 0.016630 -0.061128
+0.115505 0.002142 0.019876 0.014986 -0.066700
+0.002735 0.027334 -0.033263 0.031449 0.112566
+-0.025718 -0.017066 -0.019976 -0.036001 0.083541
+0.048068 -0.073969 -0.035121 0.039966 -0.077883
+-0.015535 0.089870 0.023998 0.011277 0.010489
+0.033555 -0.012483 0.127157 0.027709 0.014969
+-0.033730 0.006080 -0.048319 -0.052745 0.027066
+-0.021685 0.115020 0.006318 -0.021548 0.021575
+0.090884 -0.054542 -0.015574 0.030923 -0.068692
+-0.095404 0.092367 -0.049371 -0.007959 0.012304
+0.123951 0.014405 0.082998 -0.023011 0.029154
+0.017924 -0.006151 -0.084050 0.033509 -0.002582
+0.024225 0.045534 -0.034178 -0.026409 -0.121581
+0.007469 -0.024266 0.049937 -0.020242 0.021756
+-0.020005 0.017806 -0.083185 0.089127 -0.055074
+-0.034134 0.018495 -0.014900 0.084470 -0.088049
+0.012587 0.053323 -0.003416 -0.081639 -0.022685
+0.028673 -0.041773 0.034449 0.070890 0.057659
+0.017152 -0.036172 -0.093521 -0.025296 0.035162
+0.029819 -0.039228 0.085181 0.163548 -0.001854
+-0.029758 0.022943 0.021209 -0.070771 0.014429
+-0.013368 -0.088799 -0.009255 -0.052504 0.041099
+0.025723 0.001161 -0.107366 -0.001012 0.033565
+0.044131 0.035694 -0.021740 0.002649 0.007424
+-0.085656 -0.093763 -0.001170 -0.025695 -0.037360
+-0.044626 0.064499 -0.071805 -0.003962 0.048891
+0.024092 -0.027384 0.095833 -0.090763 0.002000
+0.023459 0.019764 -0.029245 0.119488 0.005968
+-0.096712 -0.071733 -0.047297 -0.074321 -0.062880
+0.035501 -0.027280 0.037144 0.008541 0.020241
+0.018467 -0.015675 -0.095340 -0.027954 -0.069184
+-0.012559 -0.010226 -0.008974 0.014176 -0.089107
+0.055689 0.060512 0.073656 -0.081115 0.028454
+-0.087380 0.077056 -0.016938 -0.014435 0.091481
+-0.117469 0.042015 0.041204 -0.038524 0.004206
+-0.062655 -0.068726 -0.052024 -0.002012 -0.016652
+0.058910 0.036081 0.033210 -0.054379 0.003673
+-0.091615 -0.001601 0.019547 0.062960 -0.110025
+-0.019088 0.071235 -0.039133 -0.103127 0.005287
+0.019768 0.106127 -0.017072 -0.008543 -0.093660
+0.044248 -0.053844 0.097968 0.000346 0.012930
+-0.032294 0.027944 0.021196 0.006513 -0.001250
+-0.020211 0.039251 0.067859 0.020349 0.058248
+0.024609 -0.074146 -0.100418 0.030150 0.026229
+-0.039773 0.099169 0.008735 -0.011164 -0.109708
+0.001230 0.003111 0.054746 0.076006 0.018527
+0.098756 0.017060 -0.025289 -0.006160 -0.078352
+0.002616 0.144579 -0.020766 0.062239 -0.016518
+-0.035809 -0.021765 -0.035105 -0.144630 -0.095066
+0.010952 0.046460 0.068649 0.085352 0.087482
+-0.033104 -0.048980 -0.018280 -0.014775 0.025770
+-0.111625 -0.092460 0.005859 0.075107 -0.062936
+-0.085897 0.005900 0.055026 -0.087076 -0.027440
+-0.033017 -0.063979 0.066972 0.028398 0.010265
+-0.030890 -0.001574 -0.045533 -0.106812 0.113658
+0.104903 0.004971 0.028534 -0.023905 0.074634
+-0.025588 -0.100482 -0.029403 -0.070372 -0.062718
+-0.020418 -0.021403 -0.043078 0.080410 0.075037
+-0.035154 -0.074551 -0.013207 -0.145218 -0.000997
+-0.014570 -0.065138 0.008479 0.044833 0.024817
+-0.038683 0.006048 0.032395 -0.031666 -0.059782
+0.070540 0.001925 0.005314 0.060966 0.028570
+0.041891 -0.035393 -0.044033 -0.087988 0.022861
+0.054156 0.027545 0.100860 -0.032365 -0.073861
+0.047055 -0.005439 0.042181 -0.028039 0.007216
+0.034289 -0.013035 0.012785 -0.068215 0.102120
+-0.090059 -0.035706 0.026737 -0.089429 0.038438
+-0.040128 -0.077000 -0.054932 0.048963 -0.127689
+-0.020587 0.094010 0.104367 -0.014378 0.068899
+0.007536 -0.012966 0.078066 0.039371 0.013971
+-0.019439 0.083877 -0.042991 -0.046952 0.039415
+0.055981 0.076150 -0.000417 -0.001657 -0.048929
+0.046983 -0.072438 -0.012301 -0.047275 -0.023350
+-0.059164 -0.003587 -0.100107 0.007189 0.060971
+0.042822 -0.008493 0.134842 -0.044502 -0.010541
+0.089334 -0.016620 -0.048559 -0.027560 -0.005511
+-0.032724 0.034262 -0.042951 0.017548 -0.145421
+0.056398 -0.006331 0.030847 0.001640 0.057797
+-0.063806 -0.000882 -0.091910 0.016087 -0.019546
+0.061433 0.036856 -0.056495 0.069485 -0.031554
+-0.012055 0.017768 0.015448 -0.074610 -0.037352
+-0.004122 -0.064702 0.053976 0.074254 0.134606
+-0.001169 -0.110572 -0.031859 0.002913 0.016777
+-0.083814 0.052146 0.036174 0.103645 -0.024775
+-0.005335 0.048662 0.002436 -0.040366 0.023406
+-0.028113 -0.087518 0.030981 0.017198 0.042213
+0.009268 0.022638 -0.091913 -0.007325 0.067826
+0.007175 0.039739 -0.030746 0.019636 0.060134
+0.002597 -0.074017 0.092250 -0.059181 -0.016534
+-0.011358 -0.017007 -0.017703 0.102970 0.122663
+0.057377 -0.041987 -0.053837 -0.031373 0.063014
+0.006671 -0.090650 -0.138471 0.106533 0.010497
+-0.102967 -0.075716 -0.038511 -0.071066 0.017321
+0.093836 -0.006301 0.118555 0.061346 0.013449
+-0.000558 0.009959 -0.026395 -0.028150 -0.032041
+0.044864 -0.060691 0.041780 0.046048 -0.051785
+0.062238 0.004872 0.030879 -0.128966 0.012667
+0.023845 0.078065 0.044196 0.046742 0.148868
+-0.030628 -0.042491 0.021535 -0.011918 0.043483
+-0.047778 -0.117530 -0.005429 -0.008792 -0.098801
+0.020009 0.106857 0.089897 0.024663 -0.061028
+-0.015371 0.069471 0.045508 0.046334 -0.069530
+0.010731 0.072915 0.065071 -0.058529 0.071085
+-0.012683 0.094842 -0.090176 0.065021 -0.044033
+0.019140 -0.012000 0.092585 -0.034244 -0.040555
+-0.084684 -0.011832 0.061629 0.009146 0.027188
+-0.026891 0.080725 0.088536 -0.084517 0.044584
+0.093624 -0.016766 0.021101 -0.002887 0.009587
+-0.068241 0.007223 -0.040467 0.035718 -0.043998
+0.050133 0.003764 0.010389 -0.000348 -0.020485
+0.049700 -0.066152 -0.041930 -0.021767 -0.077931
+0.035116 0.108204 0.024456 0.032605 -0.043283
+0.024511 0.009921 -0.031396 -0.173419 -0.049078
+-0.014906 0.036522 0.041073 0.061298 0.024532
+-0.074779 -0.013084 0.018258 0.041618 0.044657
+-0.018537 0.007319 -0.066448 0.027570 -0.032981
+-0.024516 0.092119 0.129643 -0.016032 -0.072728
+-0.044848 -0.084876 0.072567 0.089222 -0.006042
+0.077927 0.001985 -0.041619 -0.009227 0.069988
+0.088912 0.133137 -0.016458 0.008841 0.031287
+-0.047102 -0.083683 0.030843 -0.112282 -0.103671
+-0.006459 -0.031852 -0.057190 0.207145 -0.002174
+-0.047509 -0.051560 -0.034172 -0.058751 0.014904
+-0.055125 -0.123573 -0.025949 0.094512 0.035410
+0.003286 0.008369 0.029091 0.023530 -0.021963
+0.056787 0.037285 -0.041070 0.012945 0.109131
+-0.012940 -0.088290 -0.060557 -0.064861 0.027757
+0.012384 0.004678 -0.022211 0.059852 -0.089239
+0.120404 0.036099 -0.023853 -0.025676 0.001845
+0.000298 -0.029950 -0.027028 0.027301 0.128816
+-0.046314 -0.030039 0.011273 -0.059749 0.055640
+0.001351 -0.032191 -0.091552 0.054641 0.010980
+-0.105128 0.083057 0.017517 0.006971 -0.014256
+0.046500 0.060555 0.099997 0.034081 0.044797
+-0.117689 0.049576 -0.059663 -0.109523 0.015561
+-0.039089 0.097102 -0.015266 -0.057401 0.015861
+0.029363 -0.123492 0.017355 -0.025359 0.005924
diff --git a/codec2/branches/0.7/src/codebook/mel1.txt b/codec2/branches/0.7/src/codebook/mel1.txt
new file mode 100644 (file)
index 0000000..06d59f8
--- /dev/null
@@ -0,0 +1,9 @@
+1 8
+550
+600
+650
+700
+750
+800
+850
+900
diff --git a/codec2/branches/0.7/src/codebook/mel2.txt b/codec2/branches/0.7/src/codebook/mel2.txt
new file mode 100644 (file)
index 0000000..b650319
--- /dev/null
@@ -0,0 +1,5 @@
+1 4
+50
+100
+200
+300
diff --git a/codec2/branches/0.7/src/codebook/mel3.txt b/codec2/branches/0.7/src/codebook/mel3.txt
new file mode 100644 (file)
index 0000000..b81a729
--- /dev/null
@@ -0,0 +1,17 @@
+1 16
+800
+850
+900
+950
+1000
+1050
+1100
+1150
+1200
+1250
+1300
+1350
+1400
+1450
+1500
+1650
diff --git a/codec2/branches/0.7/src/codebook/mel4.txt b/codec2/branches/0.7/src/codebook/mel4.txt
new file mode 100644 (file)
index 0000000..3f79ca8
--- /dev/null
@@ -0,0 +1,9 @@
+1 8
+25
+50
+75
+100
+125
+150
+175
+250
diff --git a/codec2/branches/0.7/src/codebook/mel5.txt b/codec2/branches/0.7/src/codebook/mel5.txt
new file mode 100644 (file)
index 0000000..5791d4a
--- /dev/null
@@ -0,0 +1,9 @@
+1 8
+1350
+1400
+1450
+1500
+1550
+1600
+1650
+1700
diff --git a/codec2/branches/0.7/src/codebook/mel6.txt b/codec2/branches/0.7/src/codebook/mel6.txt
new file mode 100644 (file)
index 0000000..40b319d
--- /dev/null
@@ -0,0 +1,6 @@
+1 4
+25
+50
+100
+150
+
diff --git a/codec2/branches/0.7/src/codebook/newamp1_energy_q.txt b/codec2/branches/0.7/src/codebook/newamp1_energy_q.txt
new file mode 100644 (file)
index 0000000..d2653f3
--- /dev/null
@@ -0,0 +1,17 @@
+1 16
+10.000000
+12.500000
+15.000000
+17.500000
+20.000000
+22.500000
+25.000000
+27.500000
+30.000000
+32.500000
+35.000000
+37.500000
+40.000000
+42.500000
+45.000000
+47.500000
diff --git a/codec2/branches/0.7/src/codebook/train_120_1.txt b/codec2/branches/0.7/src/codebook/train_120_1.txt
new file mode 100644 (file)
index 0000000..a98133c
--- /dev/null
@@ -0,0 +1,513 @@
+20 512
+  6.7484   7.6125   6.0332   5.2789   1.5239   2.2353   2.0748   0.5289   0.8748   2.5432  -2.2863  -3.1910  -0.0434  -1.9857  -3.3605   0.7069  -5.9493  -0.5672  -0.6798 -18.0977 
+  4.0503   3.9086   2.9225   2.3773   0.6580  -0.4363  -0.0644   2.4063   1.3428   2.4542   0.5275   0.9820  -1.3277   0.6811   0.0273  -0.1838  -0.0222  -0.6478  -2.2405 -17.4152 
+ 13.3284  12.1212  10.6531   9.8214  11.0388  15.8120  19.7110  16.5488  16.1068  15.8771   7.2553   4.2486  -6.0036 -12.5476 -20.1299 -28.2803 -25.3971 -21.7907 -11.5143 -26.8590 
+ 21.4405  18.4703  17.8693  14.9679  11.2994   6.4906   4.7717   0.1959  -0.8801   1.8991   1.9793  -4.9755  -7.7852 -10.0492  -8.5295  -8.2893  -4.1203 -12.4072 -16.1660 -26.1817 
+  4.0023   3.8279   1.2681   1.0053   0.7002  -0.3886   3.4465  -1.4055  -6.7846  -2.3345  -2.9050  -0.1344   3.4192   2.4319  10.0096   3.9279   0.6807   0.3220  -3.8325 -17.2565 
+ 29.8276  21.1543  12.7853  13.0246   5.8164   3.7469   2.4198   0.1510  -4.5449   5.2695  11.7552  -4.8954  -6.0291  -8.9780   4.9650 -10.6540 -12.5363 -21.6056 -18.2985 -23.3739 
+  4.8610   5.1207   6.5382   9.8638  15.4754  18.8192  14.8018  10.7685  12.4401  14.0392   2.9200  -3.7283  -9.7213 -13.5526 -16.0730 -13.7571  -5.4267 -12.2552 -14.5143 -26.6193 
+  3.0429   3.0335   4.4785   5.6483   5.3476   5.7519   3.5651   4.9007   4.9672  -0.7330  -0.6458   6.5888   5.2957  -2.0068  -6.0189  -7.2145   2.5545  -5.8358  -7.4936 -25.2263 
+  5.9384   7.0203  10.7433  15.2477  14.8437   8.0949   3.1384  -0.0014  -0.1756   2.1601   8.1029   0.4123  -6.8062  -9.6038  -6.2302   0.4409  -8.9878 -10.1638  -4.6903 -29.4840 
+  7.1880   6.1134   5.4021  10.5427  17.0718  14.5658   6.8632   2.2257   0.4412   3.8257   9.0388  -1.1212  -6.7639  -9.2412  -8.6575  -2.9951  -8.6659  -9.4220  -6.6046 -29.8068 
+  9.8859   4.3889   3.6253   3.2033   4.6563   4.5967   1.8747  -0.0037   3.2114   3.8854   3.1501   0.8523  -5.2830  -8.4603  -5.1159  -3.9157   6.9800  -1.5270  -6.0421 -19.9624 
+  7.6208  10.1888  12.8648  16.4838  14.9269   7.8064   3.5594  -2.8048  -3.6303 -10.8596  -7.1254  -2.8890   5.4295  -2.5015  -5.5359  -2.9934  -6.5980  -7.1493  -4.9387 -21.8545 
+ 12.7227  17.1387  21.7055  19.8068  12.1832   5.8645  -2.4103  -3.8445  -5.5496  -5.5608  -0.2010   5.1772  -1.4666  -6.6602  -1.2573  -3.1593 -10.7925 -14.3751 -12.0047 -27.3167 
+  7.4465   7.8765   9.4912  12.2074  12.1631  11.4780   7.6294   2.6922   0.1566  -2.1903  -1.5699  -1.8031   2.2555  -1.5591  -7.9267 -10.3612  -5.5432  -5.5673 -10.0797 -26.7960 
+  0.3749   1.9725   2.6868   6.3326   8.9635  12.8113  13.6523  14.0916  11.2443   1.2914  -1.9954  -2.9443  -4.6718  -4.3132  -3.4613  -8.1105  -7.9033  -7.0956  -6.5898 -26.3361 
+ 10.3072  10.6822   8.8253   4.8992   4.3627   8.8165   9.7824   3.7264   0.4265   0.6068   3.0934   2.9121  -0.6717  -5.8045  -1.7344  -9.1008  -8.8333  -6.0633 -11.2321 -25.0005 
+ 10.6992  14.8060  18.9665  22.4210  21.8710  15.6647  10.6160  12.1366  14.0479   7.0707  -3.8212 -12.1770 -16.1111 -19.3389 -18.8315 -17.5346  -7.9646  -9.4592 -17.5614 -25.5000 
+  9.9592  11.7001  14.2704  14.1434   7.3322   4.2766  -0.0567  -2.7113  -5.7358  -6.7390  -5.9067  -0.1939   4.8177  -3.9810  -7.2528  -3.2695  -1.5685  -7.8940  -6.3355 -14.8548 
+ 17.6322  19.5153  22.4362  16.2943  10.4698   2.5066  -2.3936  -5.3770  -7.9766  -9.8004 -12.9640 -13.1015  -9.8076  -5.7565   1.8732   0.4843   3.3621  -1.0048  -4.8377 -21.5543 
+  9.9491  17.4987  23.2236  17.3142   6.8072   6.6873   1.9421   1.1415   2.9409   6.8470   2.4633  -7.2869  -8.9792  -3.3155  -0.1918 -11.8037 -18.6298 -12.6475  -9.7620 -24.1984 
+  9.2080   9.9971  12.5064  20.0609  20.9647  10.9574   7.4360   4.4943   4.8454  11.0636   1.8176  -7.3479 -12.5617 -15.3912 -11.5022  -5.0309 -14.7556 -15.4294  -6.4150 -24.9176 
+  7.7917   9.3291  11.8185  15.3501  19.3235  20.6869  19.8160  14.6028  10.2893   9.9407   9.8534   3.6182   2.7695  -5.2735 -19.7962 -24.6834 -27.0316 -25.6805 -24.9149 -27.8096 
+  0.1108   3.1261   6.8163  12.4528  16.9192  10.8153   2.6109  -0.2652  -4.8897  -6.1056  -7.3218  -4.4594   4.3004   3.7728  -2.8276  -0.0458   1.0104  -6.4884  -6.4860 -23.0456 
+ 12.9442  10.3059   3.1303   2.1611   1.4795   2.7580   6.9527   8.4487   7.1533   1.4465  -0.9113  -3.9971  -4.9090  -5.3881  -3.1011  -0.4922  -1.1819  -5.3279  -8.2374 -23.2345 
+ 25.0945  17.8572   8.9500   2.7040   0.2187   1.4115   0.7421   0.5831  -0.3096   0.9334  -2.9667  -4.0352  -2.8473  -4.8594  -4.5863  -4.4311  -2.8466  -4.4808  -5.1669 -21.9645 
+ 14.6124  19.7986  21.2066  15.7620   8.7509   3.7653  -0.5239  -3.8894  -6.8522  -8.4979  -8.1879  -5.8438   0.5485   6.7415   0.4745   2.6750 -10.3676 -15.0245 -12.2357 -22.9125 
+ 11.9959  12.9771  17.1177  21.5310  16.8892  10.8731   9.7276   8.5106  12.9569   2.2512  -6.9324 -13.2124 -16.5380 -18.0518 -16.6252  -9.7038  -6.1220  -8.7542  -6.8998 -21.9905 
+ 12.8107  14.5670  13.4289   7.1693   3.4265   3.1397   2.5457  -1.2214  -0.3887   2.4506   3.9777   0.9056  -6.9195  -7.3811  -3.2619  -0.3714   2.6266  -6.3479 -12.2319 -28.9244 
+  2.6437   2.2575   3.8643   6.0625  10.9091  16.9554  21.5045  12.7233   9.3579   9.4439  12.8585   4.4528  -2.4283  -4.7330  -2.2502 -11.3098 -18.5273 -22.4570 -23.1304 -28.1976 
+ 10.5757  10.9392  14.0126  18.2101  14.3745   8.6896   4.9080   1.0411   2.3482   7.2221   4.5440  -5.0353 -11.2852 -13.0882 -10.9600  -3.0288  -9.5005 -10.2217  -6.6739 -27.0717 
+ 14.6172   4.5412  13.3824   9.2916  19.2818  13.6563  14.4089  10.1260   1.6926   3.9361  -0.6461  -5.1244  -9.3641 -13.9807 -11.4128 -11.8597  -0.8237 -20.3149 -12.3561 -19.0515 
+  4.0591   4.6177   7.7662   6.8737   9.4052  10.1099  12.8714   8.1202   6.6015   7.9224   1.7548  -1.6325  -4.8379  -5.0955  -2.1947  -8.4220 -11.8799 -10.7107 -12.0066 -23.3222 
+ -3.3385  -1.1297   3.0554   4.9769   3.8625   8.6998   8.0974  -0.5519  -1.0699  -5.4771  -4.7235  -4.8192   7.1236  -0.4895  -2.0107   0.1838   3.5180   3.2804   3.1904 -22.3779 
+ 10.9362  15.2821  18.1297  12.4682   2.6895  -1.2007  -1.7676  -6.1681  -6.0524  -5.8064  -3.1002   4.3237   2.0263  -5.5109   1.0348  -0.4760  -4.6274   1.4107  -7.5329 -26.0586 
+ 27.0648  22.2199  14.8908   7.7845   2.8689  -0.0364   0.0683  -0.1186  -1.6323  -2.4217  -4.0112  -2.3476  -5.4442  -5.8509  -6.4386  -6.2558  -6.7739  -5.9348  -7.0916 -20.5398 
+  4.3156  -0.2499   1.1824   2.8225   8.1910   5.2798   2.2597  -3.0043  -5.0382  -5.2727  -4.0013   2.6952   8.1245  -1.1517  -1.8957   2.4603   3.0897  -1.0817  -0.1353 -18.5898 
+ 17.5894  22.9315  26.4862  22.1620  13.7474  13.5177  15.2005  16.3224   4.9523  -4.2419  -8.3503 -12.4022 -12.6698  -6.7159 -16.2122 -20.1926 -20.5969 -16.0749 -12.5173 -22.9353 
+  6.5871   8.0443   8.4339  11.3345  17.3665  13.4455   6.9211   2.0512  -0.7348  -1.2898   1.0076   8.4862  -0.3360  -6.4714  -5.9432  -4.1602 -12.1155 -12.4645 -10.9269 -29.2355 
+ 19.0066  20.3716  18.0417   9.4806   4.8058   0.3359  -4.1091  -8.1930  -8.9962  -9.7495 -13.2924  -8.6275  -4.9424   6.0502  -6.8142  -7.1166  -3.0922   8.8016   5.6937 -17.6547 
+  4.7309  -6.5949   4.9914   7.3489   9.0188   4.1567   7.1949   0.4917   5.0462   7.5219   1.5314 -15.3803   5.3130  -0.0983  -7.0327  -1.2671  -0.4646  -1.6442  -0.7446 -24.1190 
+ 13.7639   5.1424   5.3193   3.8945   3.9574   1.4034   0.1896  -4.0608  -2.5264  -4.9434   2.8459   2.6311  -2.7915  -3.7842  -0.3711   0.5487   5.3766  -4.3496  -3.2801 -18.9656 
+ 12.6752  14.7799  16.2157  18.6944  14.1390   7.0937   3.8206  -2.4778  -3.9766  -4.4531  -2.8711   3.2148   0.6800  -9.1748 -10.1600  -6.0557  -0.8581  -9.2828 -14.0109 -27.9924 
+ 15.0025  18.2042  22.4086  21.6195  14.2308  10.5772   6.7291   6.0463  11.7877   8.4162  -3.4731 -11.2708 -15.6923 -17.5613 -14.5235  -4.5248 -17.8954 -18.3529 -10.3105 -21.4173 
+  2.5368   2.8687   8.7229   5.2089   8.9671   2.8847  -1.3535  -4.4273  -4.9060  -7.8939 -15.4750 -10.4797  -4.4811   6.5892   9.9939  12.9078   3.2705   1.3246   3.7883 -20.0468 
+  8.5207  11.8364  16.4466  19.9166  16.0662   8.4129   4.3290  -0.8928  -3.7592  -5.4071  -4.2870   0.4615   9.9611   5.8190   1.7969  -7.7765 -17.3073 -19.5235 -17.7924 -26.8211 
+  3.0595  10.0158  11.1623   5.9413   3.1988  -2.1129   0.3528  -3.0158  -2.3599  -1.3347  -1.0479   3.9189   7.8019   3.0538  -1.6139   0.8043  -4.9290  -6.9959  -7.2918 -18.6077 
+ 17.8476  19.4332  25.4614  19.1508  12.2748   9.4543   6.1101   3.6929   2.9336   5.5407  -9.2238 -17.0071 -20.8856 -22.9308 -21.1711 -15.0234   4.8627   2.2867  -2.1943 -20.6125 
+  9.6165   8.8018  11.1694  14.6183  18.4154  13.4481   7.1580   4.1650   1.8242   0.9521   5.1356   4.0270  -5.9523 -12.0202 -14.3055 -10.5893  -2.8308 -12.2805 -13.3723 -27.9806 
+ 13.4166  16.7617  20.6572  22.0976  15.9129  10.6410   5.4061   3.1570  -0.7256   1.2303   5.9463   5.1273   3.4864   1.6884 -10.9215 -19.5567 -22.8693 -20.4758 -24.0420 -26.9379 
+  8.0404  15.9476  21.0441  15.0820   8.2842   3.1036  -0.2419  -4.2559  -6.0751  -7.4529  -5.5847   1.5520   8.3483   3.3751  -1.0503 -10.4691 -11.9360  -5.5738  -6.8713 -25.2662 
+ 19.9950  20.2102  18.7443  12.7220   5.8592   3.8088   0.4504  -1.5876  -0.0425  -3.0873   5.5382  -0.1499  -5.8500  -7.9372  -6.2374  -0.2643 -15.0702 -16.9914  -9.3644 -20.7458 
+ -2.6024  -7.4950  -1.2522   3.5119   3.9726   3.4991   2.4457   3.2158  -0.1830  -1.7087  -7.3996  -6.8962  -5.2421  -7.5762  -9.1433   6.6126  10.5297  10.4556  18.2991 -13.0433 
+  0.8317   2.2343   3.6899   5.6335   5.8479   6.4330   6.0022   5.3630   2.3387  -0.5344  -1.0716   0.6509  -0.7175  -4.0229  -6.0631  -4.7546  -1.9700  -4.6226   0.0933 -15.3616 
+ -9.3660  -6.9175  -4.9307  -3.1828  -1.6587  -1.4971  -0.1586   0.6208   0.5169   2.4709   4.6017   5.3127   4.5449   3.2690   3.7590   3.4511   3.8260   3.9369   4.8805 -13.4790 
+ -1.1830   0.5095   1.1754   2.3109   2.2722   1.3243   1.6529  -0.1799  -0.2874  -1.2863  -2.2761  -1.5668  -1.2037  -2.4367  -3.9243  -2.1186   2.3502   1.4312   9.5827  -6.1467 
+  9.2349  10.7650  18.1608  20.6655  13.5769   5.4902   3.0323  -1.0259  -0.5010   1.7689  10.3810  12.0253   9.1922  -4.9615 -15.0315 -19.9651 -21.4377 -17.6800  -6.4577 -27.2328 
+ 10.6391  10.7983  11.4949  16.5329  19.2664  13.6129   6.1846   2.4573  -3.1501  -7.1814  -7.9387  -2.6238   4.6419  -5.9113  -9.3510  -7.0591  -3.2275 -10.2820 -10.5308 -28.3726 
+ 18.6364  19.3874  19.5930  14.3075   9.4402   3.6045  -1.9801  -5.5352  -9.0094 -10.9308 -12.7345 -14.0779 -10.9593  -3.8674   6.3753   9.5959  -1.4018  -7.4988  -6.1435 -16.8015 
+  9.4969  11.3591  11.5468   7.8918   4.7217   3.0266   4.2145   2.2878   1.2224   5.6903  10.6919   4.2718   0.7184  -3.7583  -6.7954  -8.0558  -7.9668 -10.2861 -12.5018 -27.7759 
+  1.9805   4.9512   7.0160   7.8284   8.7891   8.0863   7.7994   7.9865   8.6027  13.1944  14.7771  11.0643   2.1716  -5.7171 -10.9834  -8.7615 -16.8907 -14.3039 -17.4732 -30.1175 
+  7.4683   9.4924  11.1231  14.0490  15.3387   7.9538   5.2116  -0.0275  -3.0014   0.1050   0.6547   7.9660  -2.3476  -7.0894  -4.6113  -2.0949 -15.9720 -16.2041  -7.4758 -20.5386 
+  4.8388   4.2032   3.5738   6.4994  10.8701  16.7006  14.8672   6.7149   3.1448   0.6167   2.5321   7.5899   1.6456  -3.0073  -4.4465  -2.3406 -11.2907 -15.6965 -17.0827 -29.9328 
+  9.8208   5.5733   3.2835   2.3197   5.4502   9.1113  10.3794   8.6442   6.0107   6.4897   4.2548   1.1709  -4.1757  -9.6942 -10.5243 -11.8609 -10.0641  -3.4488  -2.2532 -20.4873 
+  5.8783   5.8851   7.6595   5.2009   5.1000   1.9820   2.2615   1.4023  -1.1079   1.1247   3.7199   2.8362  -0.5182   1.4421   1.5607  -8.4521  -3.7106  -1.6008  -5.2750 -25.3888 
+ 13.8298  17.3228  17.9494  18.8765  12.6415   7.5326   5.2828   1.0300  -1.0231  -5.4994  -6.6194  -2.5155   4.6895  -3.4515  -7.2113  -4.1051 -13.7542 -14.3604 -11.8611 -28.7541 
+ -8.8559  -3.0649   2.2249   4.9828   6.4170   6.9906   9.9342  12.0149  12.2463  14.3103  18.4345   6.3234   4.2404  -2.7341  -6.9396 -10.7644 -10.1668 -12.3674 -16.3891 -26.8371 
+ 10.9983  13.5279  16.2801  19.6892  16.9475  11.0028   3.9633   1.1799  -2.0078  -0.9850   2.7247  -0.1311  -6.6215  -8.5890  -4.3971 -11.9543 -15.4358 -13.3278  -4.8427 -28.0217 
+  7.2013   9.1028  13.1142  19.8377  22.5360  16.6528  11.8330  10.3141  12.9885  15.8372   9.0995   8.4627   1.1838 -14.4656 -21.4397 -23.6775 -22.5547 -24.8595 -24.4974 -26.6692 
+ -8.4073  -6.6779  -3.9580  -1.6241  -2.1470  -2.2867  -2.2534  -3.0205  -4.5931  -2.5545  -2.1350  -1.3098   1.1053  -1.1397   1.2170   6.2234   3.6093   9.8015  23.5766  -3.4260 
+  9.6955  11.4467  15.0851  15.4765   9.8267   3.5490  -0.5777  -2.7726  -5.1878  -5.7225  -4.4558   0.4969   9.2914   5.8917   6.4235  -4.2514 -11.0149  -9.4893 -13.0444 -30.6665 
+  2.9943   1.4307   0.8714   2.2925   2.1145   2.9148   2.4003   1.9382   1.6662  -2.3476  -2.0877  -1.9322   3.3342   1.7171  -0.9114   3.2785   1.7852   1.4651  -1.3549 -21.5695 
+  7.7138   9.3400  11.7519  14.3217  14.9762  11.0903   9.9040   9.3599  10.4611   6.3795  -3.9927  -7.6734 -12.4888 -12.1729  -5.7999  -5.5417  -9.5690  -9.5926  -7.6846 -30.7825 
+  4.4498   9.2290  15.0677  17.9679  11.2745   2.6730  -0.9888  -5.6255  -7.5349  -8.4589  -8.4510  -5.5027   1.7669   4.3143  -4.8629  -2.0721   4.6797  -5.0125  -4.4213 -18.4923 
+ 11.1829  12.4396  12.7925  12.6901   8.0150   3.4089   1.7847  -0.2306  -2.0077  -1.0178   2.2167  -0.4542  -8.4111  -8.9029  -8.0861  -3.9439  -6.2512  -2.2635  -2.1307 -20.8306 
+ -0.0237   3.5900   4.5144   3.8794   5.7527  11.0182   8.9091   7.1863   7.0702   7.1782   4.7799   0.6784  -4.3508  -5.3991  -6.5953  -5.6132  -9.5378  -5.6903  -1.3834 -25.9632 
+ -2.7117  -1.4799   1.2116   2.3262   3.7406   3.7668   1.2697   0.2086   0.7399  -1.3479  -2.2145  -3.7982   4.9747  -0.4583  -1.7465  -0.9161   7.2119   0.8965  -0.2723 -11.4012 
+  7.6123  10.5335  16.3125  23.5319  21.6117  16.3290  18.2001  16.9715   0.9425  -7.0707 -12.7338 -16.0871 -18.4761 -17.8994 -14.8763  -4.8440  -8.9433  -6.8294  -0.8772 -23.4080 
+  9.1763   3.0851   4.6724   8.0499  14.6517  16.8559  10.4532  11.9797  13.2732   7.6578  -1.4245  -7.0469 -11.9925 -15.0269 -14.7577 -15.9057  -2.4494  -8.2002  -4.4694 -18.5819 
+ -0.3793   0.7119   0.4558   1.7011   3.1548   7.4097   8.6888   7.5902   9.1020   7.3493   9.7346  15.2626   6.8726  -0.7975   0.8553  -9.6815  -9.3426 -14.3122 -13.9791 -30.3963 
+  5.2988   6.3406   1.2009   3.3308   2.0290   2.8107   1.0030   0.4513  -1.4458   3.0391   1.2595  -9.2407   1.3164   1.9175   0.7738   1.8301   0.5948  -0.9497  -2.7482 -18.8117 
+ 23.5623  25.0580  25.0568  22.4174  16.4713  14.4026  11.1159   5.0250  -1.0266  -8.5971 -10.1924  -9.6120 -11.8638 -13.7028  -4.2000  -6.0100 -12.7481 -18.5497 -22.5946 -24.0120 
+ -5.0424  -4.2120  -3.2703  -0.4028   1.8335   3.2012   2.3768   2.0802   0.6396   0.2079   0.1418  -0.1844   2.5056  -0.2078  -1.3169  -0.2911   0.8140   1.7717   5.2809  -5.9255 
+  7.6330   9.9835  15.1303  18.9128  13.0001   5.9224   1.3978  -3.1674  -6.4703  -8.3713  -7.7470  -5.2412   1.6661   5.3754   0.9111   2.2634  -7.6214 -11.2828  -5.6474 -26.6470 
+ 15.3965  19.4488  18.3928  11.4564   4.0261   0.4604  -4.6326  -9.8409 -11.0926 -12.7123 -13.1035 -12.3357  -8.4063   1.3638   7.8807   5.5655   3.4210   0.7205   5.4867 -21.4953 
+  4.0267   4.8087   7.0895   9.6094  12.6372  17.6545  19.7244  17.4364  13.7517  13.9367   6.0059  -4.5448  -9.4075 -13.3403 -13.6620 -10.1856 -10.5214 -17.1512 -19.3146 -28.5537 
+ 26.5287  22.7007  21.6748  17.6005  11.9372  12.6653   5.4749  -6.1299  -8.9419  -6.9620  -5.7222  -5.6209  -8.6350 -10.0876  -8.1562  -7.7238  -5.4233 -10.0839 -13.1237 -21.9717 
+  3.9740   4.1572   5.7242  12.4480  17.3522  11.6512   5.2405   1.2103   0.5569   2.7329   9.6369  -0.5073  -5.1263  -2.7956  -0.7621  -3.7186  -1.7764  -8.4788 -18.8985 -32.6208 
+  6.8442  11.6517  15.0164  13.0383   3.5465   0.5949  -3.0134  -7.5262  -8.2082  -8.6101  -7.2813  -1.2345   9.2720   5.1011   6.0543  -0.9163  -4.5878   3.4588  -4.8078 -28.3926 
+  7.8637   4.0004  -2.9380   2.0521   2.2442  -0.4633   1.8855   1.9277  -0.6295   1.3834   1.2896   1.0703  -0.4938   1.5669   0.0079  -1.5584  -2.0070   0.9263  -0.4846 -17.6435 
+  5.8623   7.6023   7.9357   8.1933   9.8252  14.3094  18.5980  17.6310  14.1029  11.3791   8.9224   4.7903  -4.5730 -11.3683 -17.8078 -14.2065 -11.2294 -16.2936 -23.1509 -30.5225 
+ -1.7942  -0.0063   1.9950   3.6026   3.2262   0.8396   2.3621   2.3730   0.2704   0.4107   0.3605   1.3362  -2.3048  -2.1177  -2.8566   0.0808  -2.4432   2.0828  10.0173 -17.4341 
+ 16.0587  21.3030  20.2092  12.2290   4.0091   1.0523  -3.6402  -8.1002  -8.5006 -10.1681  -9.7303  -7.7995  -1.2107   8.9891   5.5157   1.2399  -8.3907  -7.4334  -1.1958 -24.4366 
+ 15.8248  21.2415  22.3705  19.6523  12.6511   4.9800   2.0524   1.2562  -2.0002  -7.0989  -8.4866  -8.1644  -3.6111   2.9801  -6.3159  -7.3905  -2.5939 -11.1587 -18.1433 -28.0453 
+ 11.4701  14.8919  19.2495  17.1766   9.1256   4.6224   0.3569  -3.6692  -6.2969  -8.7664  -7.4764  -1.7487   3.4354  -4.0219  -5.5797   1.1971  -7.0079  -5.6899  -4.9140 -26.3546 
+  4.0502   6.3561   7.7528  13.2425  22.1071  16.8285  10.8539   9.9555  11.6373  14.4871   1.0686  -6.0140  -8.7291  -9.9474  -5.2420 -14.0196 -19.6200 -16.4317 -13.2116 -25.1241 
+ 14.0747  12.9823  14.7396  18.3580  20.8024  21.6686  20.4893  18.2777  14.8271   4.2101  -4.6228  -5.0852  -8.9555  -9.9704 -14.4886 -22.2364 -24.8924 -24.6202 -19.9776 -25.5806 
+  6.5756   6.5342   9.0959  14.5314  20.6452  22.1123  17.0555  14.5823  18.4626   9.7441   0.1482  -4.4759  -4.9624  -0.2271 -12.9306 -21.6336 -23.8195 -22.7039 -21.8165 -26.9179 
+ -2.4130  -0.2375   2.8918   5.5011   6.7427   5.7418   5.0778   5.1858   4.3188   3.4462   4.3416   1.8899   2.3449  -0.9372  -1.2877  -2.8414  -4.0969  -5.4193  -7.2573 -22.9920 
+ 18.6934  11.3904   9.2311   9.3832   5.4199   3.6295  -0.1793   0.6487  -3.5589  -4.0062  -6.2031   0.6797   0.8497  -5.8255  -3.0197  -0.8407   3.4120  -4.6925 -10.2551 -24.7566 
+ -1.1447   1.5640   1.4686   1.7604   1.7234   2.3262   4.7312   2.6246   3.8383   6.5465   3.3830   1.7225  -1.7619  -1.0275  -1.1491   1.9434  -4.9663  -2.3871  -2.8449 -18.3507 
+ 14.1023  13.5650  10.1510   8.7911   7.7313   7.6480   9.2651   8.0399   4.9244   6.1141   5.5459  -0.9256  -6.1550  -7.0836  -8.6484  -9.0926  -9.2649 -13.5303 -12.0852 -29.0925 
+  9.8451  13.4743  16.9269  13.4623   5.8133   1.7553  -0.7487  -3.9831  -8.1249  -9.5689  -8.7611  -6.3983  -0.6612  10.9895  12.8583   0.3283  -8.6023 -10.4136  -5.9048 -22.2865 
+ 19.2227  18.1307  15.9732  13.2757   8.9377   4.0318   2.7371   2.4204   4.8079   5.9436  -1.6587  -5.6682  -8.2354  -8.6156  -5.7373  -5.9194 -13.5825 -11.1928  -9.7272 -25.1435 
+  9.7172  12.7596  17.7880  19.5982  13.1714   6.9756   4.2961   1.3629  -0.4383   4.9630   8.7840   0.9395  -2.9094   0.8700  -9.7739 -17.6442 -19.7626 -14.0983 -10.0576 -26.5411 
+ 19.7847  26.9921  27.0885  20.9467  13.4352   6.9927   3.8926   5.5073   6.3950   3.6410  -3.5260  -9.9366 -12.2833 -15.4366 -15.2739 -13.4030 -13.6697 -14.5223 -14.0162 -22.6082 
+ -4.7450  -2.3439  -1.2527   0.2681   2.5169   3.0271   3.2731   1.1854  -1.4898  -2.2085   0.9214   6.1154   5.0556   7.1405   5.3972   1.8235  -0.1874  -0.9732  -2.7856 -20.7382 
+  2.7354   2.9846   4.5226  11.0075  16.9767   9.7039   5.0497   0.2367  -2.2382  -2.2319   3.3972   5.8953  -3.5572  -7.9222  -5.1006   4.0687  -6.7980  -6.9512  -1.5062 -30.2728 
+  1.8923   1.9933   1.7272   1.4697   2.1029   2.7198   2.2271   0.4083   1.4890   2.3633   0.0136  -3.1335  -1.8351  -3.4645  -2.5082   0.1244  -0.6305  -0.2515   2.6670  -9.3744 
+  7.3147  10.8559  16.3202  21.3322  15.5047   5.7917   2.0324  -0.5787  -3.8385  -3.1611   4.7722   6.9085  -0.8153   0.2585   0.5455 -11.9753 -19.4608 -19.4821 -11.0006 -21.3242 
+ -4.8271  -2.3317  -0.8263  -0.6913   0.0284   2.1785   4.8530   2.4866   0.5257   1.0973   0.9581   2.0508  -0.0850  -0.3240  -2.1544  -3.6769   8.2530   1.6818   2.7619 -11.9586 
+ 28.0344  21.3292  26.7011  15.9009  17.4755  11.8357   5.0600   6.5559  -4.3031  -3.5802  -8.7494  -8.4692  -7.5683  -2.5689 -10.7488 -16.5549 -18.6071 -16.7713 -13.4451 -21.5263 
+ 11.4465  12.5754  14.6510  12.0835   5.3520   1.6789   2.3021  -2.4719  -2.0905  -0.5169  -2.1754  -2.9241  -2.7917   2.0815   1.0635  -3.6587  -4.7680  -6.8125  -8.2348 -26.7899 
+ 11.1007   8.9165  11.8079  11.0313   1.9749  -0.9229  -2.4670  -6.7769  -9.1537 -10.4373  -8.8596  -6.3617   0.2425   8.3330   2.9722   9.5504  -3.2943  -3.1680   4.4488 -18.9367 
+ 12.7055  18.2073  17.6143   9.1957   1.5762  -1.0952  -4.9687  -6.1290  -7.3791  -7.2053  -4.3066   3.6014   9.8467  10.7313  -1.8676 -11.4282 -13.9225  -8.1802   2.6837 -19.6797 
+  0.8368  -1.7610   0.4628   2.3612   5.1160   7.7374   9.4921   4.3865   6.1712   5.6238   6.3738   5.3491   2.7348   5.4859   4.6651  -8.4273 -10.9892  -8.6750 -10.7619 -26.1822 
+ 12.9582  16.0251  19.0637  18.9347  12.6765   7.8161   3.8112   0.9397   6.1611   7.4639  -2.5194  -7.1391 -10.2242 -10.1934  -4.1747  -5.7525 -14.4868  -8.2946 -13.9643 -29.1013 
+ 29.3165  26.9707  19.9517  12.4469   7.3647   2.8794   1.4068  -2.4963  -5.4012  -4.1083  -5.2153  -6.4891  -5.9548  -6.4872  -6.6510  -6.7351  -9.9422  -8.4833 -11.8558 -20.5171 
+  7.6646   7.8496   5.3460   3.4574   6.3183   1.1408   3.1494   5.1045   0.2373   1.0847  -0.4320  -0.3662  -0.3503  -0.5473  -8.1949  -0.9695  -1.7599  -3.3828  -3.0248 -22.3253 
+  7.0587   8.6157   9.7452  14.4294  20.8498  17.0788   7.0614   2.4228  -0.5017  -1.0215   3.1054   5.3564  -3.4904  -7.3987  -7.4398  -7.0656  -8.8032 -12.8630 -18.8666 -28.2731 
+  5.7670  -2.6937   9.6459  -0.7839  10.7523   2.7960  -2.6113  -3.2915  -6.2928  -7.6167 -12.6729  -5.4796   5.0447  13.7582  10.3050   4.5191  -1.3433   5.4917  -1.7375 -23.5567 
+-11.2311  -7.9712  -5.4028  -3.3542  -3.1975  -4.2245  -3.9952  -5.3576  -5.3493  -4.8108  -5.4962  -2.9288   2.5785   4.7736  13.8058  17.8731   9.8332  14.9500  11.0220 -11.5171 
+  2.8142   1.3603   4.2714   4.8975   4.3374  -3.4231   3.1881   5.0714   3.9705   6.2234   3.7268   5.2790   1.3825  -7.6582  -2.9268   2.0075  -4.0570  -5.6086   1.2855 -26.1418 
+  4.9776   6.4457   7.7463   9.3687   9.5559   9.1954   6.3666   4.9237   2.1719   1.7788   1.4634  -0.3859  -6.1409  -5.3778  -2.6336  -2.5068  -8.3667  -7.0441 -11.2867 -20.2514 
+ 10.0472  11.9967  16.4907  19.9334  16.2325   9.2915   4.3130   0.7097  -4.0959  -8.1186 -10.5064 -10.3134  -5.2102   1.0801  -1.5982  -3.8949   1.2501  -7.5248 -12.9333 -27.1495 
+ 17.0433  19.1713  22.6813  17.1064   8.7516   4.3917  -0.7236  -5.3026  -7.9288  -8.3773  -7.4784  -3.7859  -2.5186   0.0200  -1.5465   0.1954 -10.7830 -12.0301  -3.0579 -25.8283 
+ 18.6591  22.3501  23.5831  19.0252  13.9063  13.3289   9.0463  -3.2346   1.2718   1.4619  -4.3706  -7.4089 -10.7710 -11.8151  -0.8947  -8.7094 -22.3259  -8.0672 -18.5235 -26.5118 
+  3.2886   3.8514   1.5062   4.9096   3.9001   3.8964  -0.6349  -1.5534  -1.3119  -2.3130  -1.8455  -3.5666  -2.6094   3.4411  -1.0089  -3.0556   4.5250   3.3979   1.1349 -15.9520 
+ -5.6652  -3.8931  -1.8885   1.6299   2.3371   2.0746   2.1285   0.4372   0.0031   4.2521   5.2010   3.3227   2.8933   1.9467   2.1449   0.9405   2.1680   2.3807  -1.3113 -21.1022 
+ 21.7270  24.2953  23.2112  13.4917   7.3423   1.4843  -3.1924  -4.8355 -10.3896 -11.3960 -12.8133 -11.6304  -9.9774  -2.6034   3.7943   3.5260  -4.2988  -6.0579   0.3494 -22.0269 
+  7.1102   6.3521  11.6650  18.7864  16.7459   8.3216   5.8454   4.3436   9.4868   7.7601  -3.1382 -10.3196 -14.1642 -15.1634 -11.6972  -1.8200  -7.1959  -8.5258  -1.8553 -22.5374 
+ 14.2212  17.8028  21.4842  24.9383  24.9854  22.3982  21.3770  20.9687  13.4315   0.0683  -9.1695 -13.1215 -13.8982 -14.9798 -18.1636 -20.5802 -22.0396 -23.0260 -22.3178 -24.3795 
+  8.9039   9.7955   9.3225  11.7206  17.8844  21.1802  19.2262  17.3421  13.9029   7.3860  -2.6995  -8.3297 -10.1319  -8.7756  -6.0590  -8.7597 -15.4747 -24.0243 -25.5723 -26.8375 
+  3.8554   4.2234   6.2441  12.5445  18.1461  14.0699   5.9992   2.7220   1.0526   2.1813   9.5825   3.3502  -4.3618  -5.0291   0.5610 -10.3142 -15.3449 -12.7063  -7.6401 -29.1358 
+ -8.9085  -6.1917  -3.8341   0.0473  -0.3559  -1.0455   0.4343   0.7424   0.1788  -2.4081  -1.5815   0.7755   2.7896  -0.3538   0.5914   4.7530   5.3039   5.5717   8.4610  -4.9697 
+  6.0177   9.1902  12.5400  17.6650  18.0833  11.1113   3.6376  -0.9348  -2.4340  -3.3221  -2.4870   5.4750   6.1443  -3.6923  -2.5169  -0.6902 -11.0083 -16.8129 -17.3554 -28.6106 
+ 12.6629  16.5188  17.0120  11.3763   2.7817  -0.7077  -5.5288  -8.1972  -9.1883 -10.5072  -9.3239  -6.2042   2.0877   8.3448   2.7802   8.4635  -5.0126  -9.0230  -5.5900 -12.7449 
+ 26.6077  25.1133  19.7421  13.7493   7.5294   4.8418   5.8235   5.9404   3.3399   4.8147  -1.6758  -4.4299  -7.1722  -6.5470  -9.6023  -9.9251 -17.0327 -19.5694 -18.7525 -22.7953 
+  9.3391  15.4719  19.7226  13.6838   5.7655   2.9423  -0.2309  -3.0447  -5.0071  -3.6430   3.6089   8.1171  -1.0555  -2.5360   2.0952  -6.4482 -11.0547  -9.9411 -11.5931 -26.1921 
+  6.7164  12.9088   8.1465   2.9974  -1.5306   3.7966   4.6355   0.1956  -4.4054   2.5643  -3.5126  -0.4027   0.5107  -1.6406   0.9829  -5.6846  -0.0083  -4.8894  -3.3272 -18.0535 
+  1.8584   3.5453  10.7864  10.3313   8.8364  11.3153  12.6550   8.0839  10.2072  14.1247   0.1105   4.9955   5.9811   7.9709   7.5141  -6.0319 -21.0185 -23.4977 -32.6987 -35.0693 
+ 13.1044  15.4062  17.5958  18.0756  11.3524   4.3670   2.6428   0.8781   0.0399   6.6751   8.2361  -2.6757 -10.1776  -9.8299  -3.1506  -9.5151 -14.3971  -6.2859 -13.5883 -28.7532 
+  0.0688   2.2921   6.5965   8.3598   8.2327   8.6486   7.1471   7.1631   4.4823   3.4067  11.3001   9.5567   0.6574  -2.5849  -6.7404  -8.6614  -8.6399 -12.0189 -13.1958 -26.0705 
+  9.5134  11.1944  14.6379  21.3303  20.9351  12.8622   5.9234   3.0673   0.5662   2.8569   7.4992  -0.6339  -9.8527 -12.4761 -11.2573  -4.7464 -13.5940 -18.0638 -14.8928 -24.8691 
+  5.5904   5.1588   4.7053   4.3271   5.8271   9.5093   8.4110   1.6453  -2.2667  -2.6767  -1.4248  -1.1260   2.4114  -1.8009  -4.8190  -8.2201  -2.9355  -0.2567  -0.3488 -21.7105 
+  0.4175   1.2148   5.1829   9.3743   9.7458   5.9476   5.0377   2.5369  -2.7391  -8.8960 -11.0818  -7.0650  -7.4393  -1.4335  10.1963   9.6385   5.0133  -4.2894  -3.8725 -17.4890 
+  8.8274   9.1037  13.6965  18.9331  20.4960  15.7102   9.1227   5.5813   1.7546   1.3849   6.9672   6.4807   5.2247   4.2668  -9.8256 -18.2374 -24.2455 -24.1902 -22.7864 -28.2649 
+-10.4296 -11.2348  -7.6061  -8.6646  -7.9499  -6.1250  -4.3918  -6.8877  -5.4461  -2.2579  -1.3507   2.2980   4.8244  12.7426  12.4434  14.4927  14.8125  12.9871   9.6224 -11.8790 
+  8.8890  12.0408  17.2338  23.3492  22.1801  17.3250  16.4611  18.6109  12.0359  -2.1102  -7.5218 -11.7288 -11.4854  -7.6790 -11.7033 -21.2349 -23.6258 -19.3358  -7.8566 -23.8442 
+ -7.7648  -7.6325  -5.9874  -5.7763  -5.5038  -4.9788  -3.5524  -3.9264  -4.7269  -2.6727  -1.6911  -0.4884   1.8633   1.5449   3.1375   9.0909  11.6855  13.4220  16.9117  -2.9544 
+ 17.5979  21.0040  20.3690  15.7264  13.3239  13.0722  13.4678   1.7577  -6.0904  -6.9925  -8.3415 -10.6335  -9.5482  -1.5234   3.9870  -6.9271 -17.4878 -18.4739  -8.9267 -25.3608 
+  6.1805   4.1462   3.5010   2.7230   3.9708   8.1302   9.4910   3.6927   2.9790   2.0598  -0.6100  -1.6298  -2.5238  -2.5441  -3.9959  -2.7189  -3.9403  -3.9477  -4.9568 -20.0067 
+  7.7322   4.4707   5.2320   7.8782   9.1005   5.4418   6.0577   3.7093   0.1939  -0.2785   1.1984  -2.6011   0.6595   2.7395  -0.9452  -4.5096  -8.4529  -6.4501  -6.8768 -24.2995 
+ -6.4169  -3.8203  -3.3676  -1.3384   0.0068  -0.0917  -0.6540  -1.1092  -2.2062  -2.8976  -3.0409  -2.6706   2.9750   6.3064   7.4779  12.0806   5.7715   5.5715   0.9432 -13.5194 
+  7.6067   9.3813  13.4849  19.9139  22.7781  18.4350  15.9140  18.9134  10.1002  -4.3291  -8.2178 -13.6741 -15.7040 -16.5313 -14.1193  -3.7115 -13.7922 -12.8183  -7.7992 -25.8309 
+  4.7167   3.8923   5.7519   8.0369  12.8563  16.7380  15.0698   9.7568   7.4623   7.4165   7.7550   1.1797  -6.3964  -6.5897  -1.5093  -9.7231 -17.0341 -15.7607 -12.6623 -30.9568 
+  9.6098  13.4286  18.7280  18.1791   9.8536   3.5779   1.4841   0.4639  -0.5329   2.6536   9.8742  -3.2808  -8.9269 -11.0817  -6.3122  -2.5681 -15.3236 -12.3977  -1.9946 -25.4341 
+  3.8990   7.6431  13.4623  16.8504  10.0821   3.4259  -0.1709  -4.7791  -8.1809  -9.2214  -8.3021  -5.9798   2.0125   6.9915   1.4712   6.5493  -3.7836  -4.9571   1.3613 -28.3737 
+ 13.9079  16.7984  20.6342  24.6533  24.3507  19.3643  17.9172  18.3920  11.7020   0.0010 -10.1043 -14.9084 -18.2285 -20.4094 -21.5267 -19.7383 -13.5385  -9.5045 -16.6159 -23.1465 
+  7.1797  11.3922  15.7490  19.3949  17.3819  10.7478   7.3006   6.1472   9.1598  11.0073   4.7816  -2.4892  -3.7349  -3.7521  -1.7971  -9.8976 -22.2914 -25.7550 -23.0236 -27.5010 
+  5.6600   8.4600  10.4652  12.1954  14.9914  18.5645  17.0459  10.3163   4.8130   2.3220   0.5889   4.1108   1.2082  -9.3950 -13.7061 -13.1090 -10.1060 -11.3113 -21.8744 -31.2396 
+ -1.8886  -0.7563   0.4909   4.9127   6.9239   5.1456   6.2254   6.4299   5.1768   9.1990  13.2223   5.4194  -3.0538  -4.7242  -5.1855  -3.7939  -7.3421  -6.1816  -4.3871 -25.8328 
+ 11.3455   9.9507   8.1659   6.0877   1.4526   0.9704   4.7975   4.0208  -0.5941   2.5357   1.5340  -4.3306  -1.6103  -4.4373  -0.0323  -2.6725  -2.0195  -3.5278  -6.3697 -25.2666 
+ -0.8009   5.6194   7.0974   6.1331   7.2063   7.4038   4.5741   8.4379   4.2968   7.9137  13.0725   2.3362   0.6963  -2.4917  -4.9374  -7.2728  -8.2160  -9.6329 -14.4558 -26.9800 
+  9.4449  12.4990  15.8206  17.3018  10.9373   5.5366   0.8716  -1.2105  -2.4770  -3.4484   1.0611   6.1591  -1.7466  -7.5929  -6.9295  -2.1338  -8.9361 -10.3674  -6.3554 -28.4344 
+ 11.5326  10.9047  16.3163  21.0845  11.9757   7.0511   0.8356  -4.9870  -6.9450  -9.2309  -9.7748  -8.2038  -2.2957   5.5139  -5.4119  -2.7410   2.4166  -7.4497  -6.0628 -24.5286 
+  9.3064   9.3678  11.2235  13.9991  14.4345  11.1982   6.3282   1.4131  -2.6884  -7.1825 -11.0075 -12.3749  -9.2573  -6.0414   2.3206   4.6097   3.5670  -3.2208  -9.5445 -26.4507 
+ -6.7163  -6.0323  -3.7943   0.8820   3.6629   4.3198   4.7402   4.0799   4.8854   5.8718   8.3927   9.6825  10.5717   3.8917   0.9125  -1.2807  -3.7018  -5.7570  -8.2525 -26.3582 
+ 10.2748  11.6455  16.3809  20.1490  18.2488  12.7899  10.3972   8.0106  -0.6794  -6.4024  -9.7054 -13.5667 -14.6497 -16.1902  -6.9531   0.2117  -0.7067  -1.2331 -10.6728 -27.3488 
+ 13.3782  16.3500  15.3612   8.9247   3.4890  -0.7729  -2.6106  -7.5432  -8.0129  -7.6140  -7.8535  -2.4356   6.5050  -4.5887  -3.2816   5.8982  -1.3889   0.3111   0.3606 -24.4762 
+ 10.0811  14.1057  20.3635  24.0314  20.3690  17.0236  16.4460  19.2548   6.0111  -3.4365  -9.9143 -13.0905 -15.0150 -11.4726  -6.6405 -10.0976 -14.6658 -19.9459 -19.4800 -23.9274 
+ -7.1817  -5.5458  -1.6137   0.8007   1.9284   2.5116   0.3432   3.3359   0.2833  -1.3305  -2.4960  -1.6366  -2.6968   3.6695   6.8225   4.4926   6.1940   6.7541   2.2072 -16.8418 
+  9.6326  11.3478  14.3982  20.7665  19.7772  12.3406   6.1933   1.0438  -1.1521  -1.5860   1.8440   7.8419  -1.5328  -9.8703 -10.1973  -2.2440 -12.0413 -18.5948 -20.6014 -27.3660 
+  1.5056   1.6880   4.2152   9.5291  17.0514  16.2096   8.5432   4.2111   4.4898  11.7231   5.5770  -4.8191  -7.5020  -5.9733  -0.7664 -10.2798 -14.8967  -9.8638  -3.1062 -27.5357 
+ 15.2115  17.9992  21.5012  24.9136  19.1760  15.8798  16.4094  17.8040   5.9025  -3.3769 -10.4408 -15.3738 -18.5882 -19.7882 -17.7007 -14.2386 -13.9566 -13.8247  -5.8162 -21.6922 
+ 12.1911  17.2966  17.4896  10.6943   3.5061  -0.1018  -2.5405  -6.3143  -7.6095  -8.5828  -7.4501  -2.2275   8.4004   0.0230  -1.6734   2.8727  -8.2243  -7.2548  -0.5950 -19.8998 
+ -0.4264   0.0708   1.9133   6.0904  12.7810  17.8469  12.0313   4.9753   4.2790   6.9401  10.3052   0.2003  -6.7328 -10.0168 -10.0292  -2.7869  -5.6536  -9.3242  -6.0818 -26.3818 
+  7.8387  12.9821  20.1116  21.8527  15.0291  10.4182   9.9996  12.5177  11.6815  -0.1048  -5.5624  -6.4577  -2.0918  -6.3498 -17.7376 -20.9015 -21.1073 -13.6752  -3.7477 -24.6953 
+ 18.0184  21.7405  20.2020  16.4376  12.3859  12.2417  12.1975   6.3324  -4.4281 -11.4734  -5.9353  -8.8421 -10.3280  -4.7973   3.4477   1.4017 -15.9637 -17.1346 -16.9459 -28.5571 
+  8.9922   8.4069  10.2569  10.5303  10.1285   4.9362   1.8698  -0.0537  -5.3906  -5.9983  -4.6797   1.6021  -1.9697  -5.3874  -2.3336  -0.9265  -2.7071  -2.3523  -3.3933 -21.5307 
+  0.1643  -2.2100  -0.9888  -3.4801  -0.5275  -1.4680  -0.5683  -1.5514  -0.4216   0.5034  -0.8521  -2.7835   0.5014  -1.2182  -0.7495   5.2974   5.8643   8.2766   6.0259  -9.8143 
+  7.6720   8.0788   9.1059  14.2217  21.6149  24.6272  15.4198  12.7487  14.5686  14.3925   0.6524  -7.7122 -12.3140 -13.4374  -8.0366 -14.9387 -21.7305 -22.0625 -19.3233 -23.5474 
+  2.2815   1.7578  -0.6674   1.7705   0.4755   0.4978  -1.3799  -2.1107  -2.6075  -3.5652  -2.8715  -6.8295  -1.7109   2.8096  -0.7449   2.5543   8.6739  -0.5359   6.8846  -4.6821 
+ 18.2027  16.9209  12.1191   7.6862   3.0545   0.5751  -1.6156  -1.2378  -3.1289  -4.2377  -5.6464  -5.0994  -5.0515  -1.2417   1.1802   1.1938   0.3821  -6.3202  -6.4152 -21.3203 
+  3.5023   4.9407   6.5095   8.9494  13.2647  15.1725  11.9431   6.2423   1.1652  -1.6313  -2.9929  -1.9072   3.4422   2.8306  -3.2309  -5.3351  -2.3238 -10.7536 -17.8375 -31.9502 
+  4.7778  10.3180  13.9538  16.0868   9.1380   2.9991  -0.6627  -4.2067  -5.6625  -4.9839  -1.2287   7.7334   9.3244   7.4153  -4.1228 -11.6166  -8.7569  -5.6012  -5.8002 -29.1044 
+ -3.8341  -1.3838  -0.9472  -0.4209   1.7906   4.2155   2.2324   4.3091   1.1357   8.4456   9.7973   6.3722   2.6068   0.3293   0.1016  -0.3203  -4.2313  -3.6986  -3.9405 -22.5593 
+  7.9933  10.9520  14.6109  19.7867  15.1983   6.5296   4.9056   0.7415  -0.5271  -0.1092   6.9036  12.3792   7.7901   2.0866  -9.1117 -12.3605  -5.7793 -23.1437 -29.0076 -29.8384 
+ 25.8990  23.1895  19.6721  15.4616   9.3167   5.4831   6.1546   7.4477   4.2279  -1.3757  -8.0309 -11.4646 -10.4795  -7.5543  -4.2227  -6.0439 -16.4547 -16.3865 -13.0397 -21.7998 
+  5.9702   6.6918   8.5551  14.7594  15.5278  10.2403   6.0423   1.7099  -0.1415   0.4245   5.8906  10.2752   2.9571   1.0304  -7.5844 -15.4930 -16.0321  -8.3602 -12.0263 -30.4370 
+  0.2377   1.2490   0.9118   1.8024   3.7548   4.8963   5.1515   4.2684   0.3786   0.5058   0.4839  -0.9914   1.4073   1.1727  -2.9065  -4.4307  -6.9456  -0.2385   0.3969 -11.1044 
+  4.9017   3.2442  -1.2482  -1.2472  -2.0773  -5.4371   0.3708   4.1825  12.1289   1.2950  -2.3136  -3.1723  -0.4429  -1.6571  -9.7455   6.5626  13.4075   7.0987  -2.0865 -23.7642 
+ 26.5958   8.4474  11.9082  11.6976   1.4010  -0.2500   3.9848   3.6429  -6.0468   2.5341  -5.2699 -11.5085   3.8103  -6.3108  -2.4679   2.1530  -6.3876  -7.1780  -8.4060 -22.3496 
+  2.2962   0.8041   0.8352   6.6150  14.5461  15.0856   3.2964   0.5549  -1.6557  -2.0236   2.8955   7.5016  -1.2031  -5.6899  -4.7833   1.2942  -7.3403  -8.3771  -4.0417 -20.6100 
+ -3.1520  -0.4969   6.6485   7.8768   5.5605   6.5283   5.6337   4.1543  13.9779   2.7762   6.1398  -3.7070  -1.7982  -2.8944  -6.0041  -6.5265 -11.4873  -1.5122   6.0580 -27.7754 
+ -8.0020  -4.6131  -0.7821   3.3160   4.4465   4.7754   2.8155   1.0612   4.8060   6.0492   5.9390   3.1446   2.8568  -0.6657  -2.6961  -2.1500  -0.9756  -0.2816  -1.9847 -17.0594 
+ 12.4378  17.8157  22.2857  21.4926  15.3987  11.6565   8.4610  -5.9608 -14.7466 -15.8101 -21.8850 -17.3295 -13.0545  -3.3503   5.7314   1.5346   1.1396  -7.5940  -1.8366 -16.3862 
+  0.8964   0.1937   0.1104   1.6479   5.6517  12.1890  10.2771   4.4234   1.0502  -0.5311   1.2594   6.8796   5.2931  -3.9156  -6.0500  -0.9098  -4.2858  -6.9837  -7.0958 -20.1002 
+ 19.8439  13.4280   9.6622  10.6650   8.0950   5.5066   1.7572  -1.0429  -0.8012  -2.8142  -0.4934   1.3117   0.5243  -6.1730  -8.1290  -6.3324  -1.5063 -10.0417  -9.1390 -24.3207 
+ -2.7279  -1.7097  -1.1534   1.6639   5.7537   6.7942  10.6044  12.5105  10.6069  10.0936   6.6639   5.7680  -0.0784  -3.9348  -2.0808  -2.5423  -7.7730 -12.2311 -11.4054 -24.8224 
+ 10.1275  12.1619  16.2723  20.8127  20.9740  14.8019  10.1842   6.5306   4.4543   7.4531  12.2713   6.9620   6.8204  -5.0668 -18.1362 -24.0479 -25.9037 -25.4208 -24.3890 -26.8618 
+ -9.9466  -6.5695  -9.8093  -1.7391   0.0580   3.2073   7.0375   2.3619  -1.1764  -5.8692   0.3050  -4.2033  11.2777  -0.3904   7.8268   9.8649   4.7504   6.9825   7.6743 -21.6424 
+ 14.0137  16.9699  19.0697  15.0058   7.0268   5.9083   2.9474   2.1595   3.8159   7.2602  11.3975   7.5965   1.6600  -6.7074 -13.8401 -15.7435 -16.6488 -16.4066 -16.4466 -29.0384 
+  6.2399   3.2858  -0.2213  -1.4923   1.3132   3.9330   3.5221   2.8631   1.3615  -0.0790  -1.0125  -1.0737  -0.3033  -0.8480  -0.4749  -1.1495   0.1031  -0.2090  -1.3002 -14.4580 
+ 14.6593  20.5101  23.6344  20.8409  12.5620   6.6891   3.7103  -0.8534  -3.6042  -5.9363  -7.0110  -3.7764   1.6775  -5.6072 -12.2281 -10.8044  -4.3275 -11.1148 -14.7836 -24.2367 
+ 17.5445  22.4817  15.1353  12.5880   5.1049   1.9643   5.3928  -3.5987  -0.4750  11.7373  12.9388  -3.8264  -3.5752  -8.3127   9.4226 -10.0441 -20.2747 -19.0638 -21.8010 -23.3385 
+ 11.5639  14.1176  19.1780  24.7909  18.2344  11.0457   8.2594   6.6617   7.5852  14.1840  12.1883   7.8148  -0.4947 -16.4472 -21.5615 -22.7378 -21.8493 -21.9703 -24.9810 -25.5820 
+  7.3833   6.5793   5.7205  10.2722  16.6567  15.1599   9.5922   5.5668   5.0234   9.3817   5.3741  -5.1082  -9.8091 -12.3432 -12.5495  -6.2366  -5.9929  -8.3697  -6.8581 -29.4426 
+  0.3726  -5.6285  -3.2253   2.1557   3.8332  12.1538  14.6059  12.3634  15.7294  17.0679   4.8054  -1.6834  -7.5585 -11.9417 -12.8749  -9.7037  -1.2933  -5.8852  -6.0304 -17.2623 
+ 12.4589  17.5375  23.1698  18.7129   9.0574   6.8369   3.3366  -0.7668  -3.5028  -5.8079  -2.0422   3.5413  -5.4920 -15.4559 -14.9601  -7.1860  -2.1139 -10.3945  -4.5301 -22.3991 
+  7.7831   5.9803   3.3957   1.1363   0.6624  -0.3876  -1.2270   0.5350   0.3563   5.2276   9.1991   8.9238   2.6320  -1.9335  -4.2120  -2.5342  -1.0999  -4.9168  -4.9485 -24.5720 
+ 12.7865  11.7808  12.0132  12.7418  11.7725  11.2618  10.9064   7.0094   3.3808  -2.3233  -4.5714  -6.7413  -8.0255  -8.7048 -10.9950  -7.0616  -9.3710  -7.6597  -4.9100 -23.2897 
+  7.4583  10.3954  16.3813  20.3810  16.5656   9.1371   4.5296   4.0559   6.8658   9.8043   0.1187  -6.6202  -8.4161  -2.4957  -9.4787 -16.3418 -17.6122 -13.1639  -7.5007 -24.0638 
+ 10.5778  12.5102  15.4500  16.2510  14.1076  12.4513  11.9259  10.4537   6.3771   1.6824  -3.8825  -5.5239  -8.8633  -8.0708  -4.6460  -3.2386 -13.9943 -17.4761 -15.8823 -30.2093 
+ 16.5450  21.4563  20.0130  10.5420   0.7521  -0.1817  -5.7313  -0.2690  -4.1817  -0.5968   6.2079   4.1626  -0.4622   5.1095 -10.2058 -16.0783 -19.9597 -11.6630   4.3789 -19.8380 
+  0.6538   1.9228   2.2930   5.2351  12.5744  11.0394   7.4850   0.8228  -3.4564  -5.0324  -2.9456   4.4755   9.6050   1.6136   0.0025  -0.9954  -6.7769  -7.8860  -2.9330 -27.6973 
+ 14.1315  17.7109  22.9482  25.5022  19.8506  12.4355  10.8121  14.0608  12.2635  -2.6541 -11.3457 -15.5204 -18.0730 -18.7390 -15.7720  -7.2576  -9.9721  -9.7355 -17.1060 -23.5400 
+ -5.7314  -4.0590   1.0581   0.9805   1.3616   2.7093   6.3692  11.6381  12.0180   9.1818   6.8001   1.9409   3.0785  -2.5335  -5.7990  -0.6774   0.8325  -4.7436  -7.1073 -27.3175 
+ -1.0640   0.7851   2.7160   6.1021  12.1198  15.4431  10.3026   4.0089   1.9648  -0.0384   2.4993   9.2599   1.9572  -4.2838  -3.1953  -1.1928  -7.8283  -8.5999 -10.0789 -30.8773 
+ -5.6296  -4.3307  -2.3209  -0.8933   0.2894  -1.9304  -2.0575  -2.7780  -6.2185  -5.9192  -6.6197  -5.5076   1.7000  -2.2417   6.7340   9.7221   5.4135  15.4230  16.2356  -9.0706 
+ 21.8983  23.2393  21.5176  17.3026  15.6381  10.7095  -4.6739  -9.4131  -7.3736  -9.6360 -10.3893  -7.6173  -3.6940   2.4229  12.3234 -14.8401 -14.2133 -12.8790  -4.4302 -25.8921 
+ 11.8056  15.6560  20.2939  16.8416   9.1858   2.5617   2.6711  -1.0207  -1.4500  -0.2437   6.6714   6.5193  -0.4136  -1.1308  -3.7531 -13.8441 -14.3531 -10.4897 -18.0817 -27.4259 
+ 55.7273  39.9360  26.2526  15.0127   6.4718   0.7391  -2.3157  -3.1939  -2.9475  -3.3569  -5.3235  -7.9446 -10.6626 -13.1662 -14.2100 -14.4691 -14.4121 -13.8376 -15.6433 -22.6564 
+  3.7665   2.9173   4.2496   1.8470   7.9023  14.8241  11.0448   3.4540   2.7173  -3.8368   2.5626   4.5604   2.9217  -9.5401  -8.3622  -8.8234  -1.4224  -0.0449  -2.7094 -28.0285 
+ -9.3983  -8.0419  -4.4832   1.9754  -0.3749   4.6985   6.4445   3.4462   1.2139   4.1530  -6.0488   0.4383   7.0647   3.8491   2.7818  -2.6890   2.0052   6.3893   4.3086 -17.7324 
+ 10.6303  13.7716  17.1718  20.1678  12.2486   3.3600   2.4058  -2.5934  -4.8765  -6.0115  -4.6562  -0.7932   8.0003  -2.2840  -3.8243   0.1863  -9.1648 -14.9839 -14.0940 -24.6607 
+ 16.6586  21.6444  20.8223  12.8954   8.1955   4.1214   1.5648  -2.8573  -5.5724  -6.5555  -5.8004  -2.3591   4.8330  -0.2831   0.7092  -9.8961 -15.4807 -12.0228  -6.1807 -24.4365 
+  6.2715   7.1856   9.0377  12.3924  19.0793  22.2584  18.7678  12.6682   9.6569  13.2645   2.9549  -2.9501  -4.4734  -4.2440 -12.7065 -19.5653 -21.3156 -21.7041 -19.8037 -26.7746 
+  6.6118   7.9766   9.5899  16.7112  22.8331  15.9736   8.1328   4.9522   3.0471   7.2666  11.8402  -1.4154  -4.2808  -5.2523  -8.9476 -17.0691 -18.3281 -12.6216 -21.0003 -26.0198 
+ 17.3127  17.4868  17.7344  12.4834   5.8856   4.6009   1.0730  -2.7678  -2.0723  -0.4628  -3.7999  -5.8370  -8.6148  -7.6108  -6.5104  -2.5688  -1.6184  -6.1466  -7.5013 -21.0659 
+  3.4054   5.0769   7.0766   9.8006  20.0250  22.5645  11.5478   6.2329   4.4723   6.4844  10.6573   0.2331  -6.2477 -11.0870 -10.3507  -4.2484 -15.1989 -19.0756 -16.4193 -24.9492 
+  4.7627  -2.1833  -2.2828  -3.7716   2.8453   7.5100  11.3439   6.1880   0.3611  -1.2837 -10.2990  -7.9318  -4.0985   1.3582   6.4088   6.3304   9.4372  -0.3781  -7.0962 -17.2205 
+  0.0639   1.7461   3.2578   7.1373  14.2936  21.0383  16.8137  10.1108  14.3040  14.1399   0.3676  -6.3231 -10.5295 -12.7919  -9.1838  -2.4821 -12.1068 -13.6518  -9.1740 -27.0298 
+  6.2012   6.2177   8.6617  15.7008  20.0807  16.3263   9.7644   7.6670  11.6809   8.6315  -2.6559  -7.4948 -10.0457 -10.1131  -6.9875 -12.9972 -15.7760 -10.0148  -6.4425 -28.4048 
+  8.4071   5.8192   3.5662   1.9627   2.4472   1.8597  -0.7370   2.3814   0.1779   1.4958   2.9385  -6.0143  -2.3152   0.3049  -1.7145   0.7158  -1.3399  -5.1439   2.0438 -16.8555 
+  7.4409   3.3788   6.5115  14.5248  13.0646   4.0268  -1.1894  -5.0999  -7.6910  -8.4282  -7.9356  -3.3516   6.9774   0.9806  -1.3988   5.5785  -3.1694  -5.2282   1.6484 -20.6401 
+ 11.6728   5.2904   7.2713   8.1521   8.6202   4.8390   1.9077  -2.7604  -4.5028  -8.9428 -12.4662 -11.0383  -4.7642   4.2903   3.3702   1.0547   5.8752   0.7203  -0.1952 -18.3942 
+  1.7662   2.1132   0.6823   0.5069  -0.7694  -0.5730  -0.6749   0.4539  -2.3850  -0.8937   3.2905   1.9366   4.8907   8.8910   3.4773   1.6832  -0.3850  -1.0325  -5.4486 -17.5299 
+ 11.1327   8.1369   5.9398   7.2387   9.0755  13.7563  15.6715  10.9671   4.3603   6.5521   8.2784   8.2998  -3.5109  -8.8874 -13.5723 -11.9565 -11.2912 -14.9059 -15.3573 -29.9274 
+ 17.2359  18.8517  18.1626  16.5245  13.3466  10.8703   8.4673   4.7337   2.6350   0.0183   1.1954   4.7388  -2.9359  -6.0731  -7.4347 -16.3769 -19.9350 -20.0072 -15.2078 -28.8095 
+ 15.9881  16.1253  11.9372   8.7157   5.3883   4.3873   5.5095   5.6589   0.5361  -1.1208  -4.8170  -4.8077  -4.2337  -3.8897  -5.7866  -5.1486  -6.6937  -4.6271  -8.1104 -25.0113 
+ 10.5287  10.4645  11.0189  12.4921  10.2092   2.1803   0.6775  -1.9607  -7.8737  -8.5232 -10.8456 -10.0601  -9.5234  -5.7091   4.1283   1.9979   4.9082   2.3842  -1.6831 -14.8109 
+  6.8712   7.1195   7.8478   9.0102   7.5469   4.9121   6.0618   3.0705   0.6628   1.7728   2.7140   6.3541   3.1029  -4.2377  -6.3687  -2.2545  -6.3865 -11.4164  -9.6711 -26.7119 
+ 16.6601  22.0460  20.3084  13.4923   8.0021   8.7024  10.1260  10.4026   4.1888  -3.7328  -6.1710 -10.8693 -16.0494  -7.8483   0.2833   3.3381 -13.0116 -16.9474 -14.2501 -28.6704 
+ -1.6472  -1.5329  -0.7265  -0.8590   1.5500   3.3445   6.0600   5.7678   2.9402   4.2316   1.8384  -2.4116   1.7488  -1.1846   0.2843  -0.4495   1.5215  -2.2191  -1.2847 -16.9723 
+  5.4499   9.2168  13.6525  18.6245  21.2266  16.3225  10.2029  13.7648  16.3433   7.8345  -0.8506  -3.0654   0.8282  -4.7895 -14.3191 -13.6263 -16.5382 -25.7242 -26.3799 -28.1733 
+  5.4928   7.2730  11.4735  16.9546  13.9651   4.9178   1.4991  -1.5005  -3.3689  -4.2367   1.4622   8.4912   0.6337  -0.2593   0.3732  -7.8143 -10.1871  -7.5615  -7.0778 -30.5301 
+  6.6781   5.8903   6.7632   9.1810   8.8397   9.7239   8.7155   7.7970   6.3227   3.4228   0.2514   0.1110  -1.6716  -5.4364  -5.9387  -8.2352  -7.5149  -7.0855  -8.8552 -28.9591 
+ 11.8209  17.4970  19.5821  14.6674   8.7810  10.5929  17.1599  11.1304  -1.5934  -2.4291  -7.1040  -7.2023  -9.3009 -11.7782  -8.5498 -11.3872  -9.7560  -0.1211 -12.0128 -29.9970 
+ 10.1575  12.1948  14.9933  16.4447  14.1842   8.2787   4.1829   1.5996  -0.4007   2.6686   4.5920   3.8070  -0.5362  -2.8498  -6.0317  -8.0974 -11.2561 -15.9690 -16.7096 -31.2528 
+ 17.3728  16.5602  12.1580   2.2953  -0.7338  -2.2088  -3.0060  -3.4950  -5.7703  -1.8968  -4.1417  -2.2550  -0.4691  -0.6536  -2.4783  -1.3584   1.1130  -1.5486  -2.1800 -17.3041 
+ 10.9509  14.6912  20.9171  20.7445  13.3882   9.0276   8.4810  10.4480  11.1634  -1.3107  -8.8976 -12.4550 -14.1419 -12.2168  -8.1653  -9.1840 -14.6536 -10.7798  -3.3490 -24.6582 
+ -4.2511  -4.3180  -6.4235  -4.0719  -2.3887  -3.1485  -4.2032  -3.5194  -7.5010  -5.4107  -2.3368   0.6165  -2.5480  -6.5746   5.7100   1.8165  14.8553  24.3830  15.8024  -6.4884 
+  6.8815  10.8626  15.3667  14.4704   2.5878   0.6962  -3.7687  -7.2033  -9.3334 -10.5308  -9.6190  -8.2135  -3.3921   8.1225   8.7748   9.4979  -0.1825  -3.9609   2.5378 -23.5939 
+ 10.7457  13.4613  16.3838  18.1633  11.9764   6.2322   2.2046  -1.6815  -5.4025  -5.3261  -1.9194   5.7850   7.0183   8.8506  -7.0398 -15.8090 -17.0181  -9.4482  -9.5562 -27.6203 
+  4.4895   6.7459  11.3127  18.7251  18.1351   6.5502   1.1677  -1.0341  -3.9953  -2.3382   3.5745  11.8555   2.9192   6.0596  -4.8984 -13.0118 -16.2470 -15.0252 -10.6982 -24.2871 
+ 10.1449  10.3471  14.7490  16.1718  16.9528  11.3815   6.8749   1.4265  -2.7864  -6.1956  -8.0139  -7.8556  -2.8591   4.0596   5.4548   3.3633 -10.2166 -16.2406 -18.8135 -27.9450 
+  9.5266   9.8619  11.6564  16.1435  22.5856  19.0228   9.5649   5.1013   3.9082   6.9523   9.4453  -4.8784 -10.6008 -16.0258 -16.6123 -14.7740  -6.6639 -13.8342 -16.3927 -23.9867 
+ -2.8166  -0.2578   2.8925   4.4555   5.6756   4.6914   3.4417   3.4041   1.8890   1.8575  -0.5242   1.9867   0.9536  -0.9744  -1.4010  -2.1961  -1.2827  -2.3186  -2.1481 -17.3281 
+  6.5757  10.4876  15.8653  20.5177  18.3749   8.4114   4.7411   0.5009  -2.9659  -4.1461  -4.5681  -0.6566   5.8038  -2.3737  -8.5532  -6.5787  -2.8561 -13.7548 -17.8769 -26.9485 
+  7.1295   8.3469   8.9916  14.7649  20.5000  15.5149   7.3359   0.6792  -1.5195  -5.0373   0.9468   7.0372  -4.0339  -9.7787  -8.9444  -0.8558 -12.0386 -13.0157  -7.1764 -28.8465 
+ -6.3643  -3.5600  -0.9853   1.3808   3.5164   4.4752   4.2783   4.1699   0.4058  -0.8097  -0.9913   3.1386   9.3653  -1.1057  -1.2662   0.7587   1.7985  -2.7481   1.1071 -16.5641 
+ 10.8441   6.1056   4.5464  11.5523  11.5304   4.8593   1.2036   0.6177  -6.5224 -11.5032 -13.3278  -7.1852  -1.6717   9.2735   6.7578  -0.9050  -7.2789  -6.0827   3.0089 -15.8228 
+  2.4300   2.4475   8.1825   8.1925   2.2974  10.8311  15.5690   1.4027   0.3290  -0.4366   6.3648   1.0487  -0.9166  -8.1367  -8.1915  -9.5690  -3.4184   0.0616  -4.9205 -23.5675 
+ 18.5545  22.2390  21.2685  17.0100   9.6982   4.7320   4.3296   7.5541   8.1889   7.8498   0.4258  -3.7349  -6.3446  -8.3581 -11.0931 -16.2715 -16.4055 -15.8123 -17.4410 -26.3892 
+  5.3049   3.9686   5.5462  12.1792  19.9309  17.0320   8.3644   7.8784  10.6383  15.3943   3.6647  -0.1421   3.0499  -3.2605 -15.9284 -20.0685 -19.5084 -15.1548 -11.4151 -27.4740 
+ -4.1173  -2.8993  -1.1226   2.7523   4.1168   4.2377   1.6192   1.4859   2.7141   0.4810   0.9555  -0.9423   1.2205   0.5970   0.3948   0.4670   2.1347   1.5199   1.6806 -17.2954 
+ 15.7137  20.9924  24.3419  24.5468  20.7453  18.1011  19.1224  15.9122  12.9399   8.1629  -8.2323 -12.3399 -17.0242 -22.3729 -23.1787 -23.2286 -17.6989 -10.8077 -20.3082 -25.3873 
+ -1.2634   1.8562   5.1481   8.6050   8.7868   9.5351   6.6634   3.8160  -0.1296  -4.6560  -0.5036  -0.2003   1.6621  -1.6607  -2.8913  -4.8208   0.3233  -5.1066  -6.1044 -19.0592 
+ 10.6986  11.8307  11.5659  12.4490  11.1880   6.9008   2.6629   3.0301   3.4569   5.3227   2.5092  -1.0853  -3.8118  -7.0840  -4.9747  -7.3629 -11.0099  -5.9887 -11.0008 -29.2965 
+ 13.6712  17.1821  19.2431  13.3261   5.9589   0.4984   0.3670  -2.3834  -3.2315  -2.1198   4.8356   0.4745  -8.1763 -11.1278  -9.8688  -0.1733  -8.1227  -9.3563  -5.3546 -15.6426 
+ -5.7735  -2.5076  -1.5044  -1.1663   0.0004   2.3285   2.2748   3.5509   0.5101  -3.3403   0.8431   1.7502   3.2945  -0.4888   1.3903   4.0779   1.6571   2.3564   6.2297 -15.4829 
+  9.1796  11.0931  14.7746  19.7918  17.0503  10.0451   7.8355   5.3063   5.9805  11.7545  10.2992   6.2216   2.6489  -6.8542 -15.2068 -16.6927 -14.0990 -23.4163 -26.3767 -29.3354 
+  4.4691   6.3690   7.7808  12.8470  20.5705  17.7665   9.4381   6.2778   2.4431   5.0549   9.9596   3.2883  -2.2059   2.0400  -4.0438 -15.0151 -19.7303 -18.2469 -20.2388 -28.8235 
+ 25.3208  24.3974  22.6154  19.5733  14.8131  10.5701   9.4361   4.3748  -1.5593  -4.3511 -14.7283 -17.6258  -0.9520  -8.5196  -7.3624  -3.2510  -9.9332 -17.3271 -21.4343 -24.0570 
+ 22.3042  16.1278  12.0077  14.7975  10.7206   8.3648   8.0610  10.1267   7.5498   1.8723  -3.9201  -8.2481 -10.1623 -11.3760 -12.7367  -5.0050  -3.3744 -11.9178 -17.4700 -27.7220 
+  4.0018   3.5852   3.3315   5.3461   4.3656   2.8461  -0.0206  -2.5696   0.1895   5.1002   3.3534   0.2158   1.3297  -0.9671  -0.5937  -1.9855  -1.7054  -1.7064  -4.2453 -19.8713 
+ -0.1820   0.3377   2.3741   5.1705   4.8793   2.2995   4.3309   2.2662   0.4173  -0.8843   6.0098   9.0178   2.9640  -0.8977  -1.5385  -6.1656  -4.1289  -4.7989  -1.1105 -20.3607 
+  7.6526   7.4466   4.8852   0.6442   1.5298   0.3141   2.6136   0.1768   0.3184   1.5717   0.2364  -0.4716  -4.0283  -1.7854   1.1771  -1.1242   0.5833  -0.2901  -4.6526 -16.7979 
+ 19.3739  25.1966  25.2676  19.4367  10.1976   2.4144  -1.1928  -4.0638  -8.7478 -10.5230 -11.0799 -12.5634 -10.0392  -5.3666   3.7592   3.3440   0.1212  -8.8586 -13.7562 -22.9202 
+  9.6043  10.5410  12.3377  19.7574  26.3167  19.8022  16.1636  16.4176  17.5852   2.8061  -5.6826 -11.1198 -15.0897 -15.5002 -11.1047 -14.2676 -20.4525 -20.5783 -15.3843 -22.1521 
+ 12.9015  20.6704  27.9257  24.9274  19.2594  24.2150  19.1475   0.5334  -3.3152 -12.4822 -15.0498 -16.9033 -19.2802 -17.1972  -9.8015  -9.8416 -13.7988  -8.2071  -2.2124 -21.4912 
+ 14.4389  13.4012  16.1103  14.9288   9.7959  11.0171  12.0893  -1.4171  -9.8704  -8.5713 -15.4225 -18.6377 -16.5003 -13.9403   1.0172   8.7826   2.1557  -0.7217  -0.1613 -18.4945 
+  3.2298   2.2245   4.4788   6.2407   6.6193   4.0854   3.5648   2.2977   2.4361   0.5689  -4.6553  -1.2701  -2.8888  -2.1474  -1.0212  -1.5878  -0.7381   0.5436  -4.6923 -17.2887 
+ 12.1886  11.0008  17.9358  24.3010  22.2969  15.0778  12.8771  17.0838  11.2261  -0.0847  -7.9648 -13.0993 -17.1559 -19.7583 -18.6302 -14.9903  -5.4184 -14.9564 -12.1370 -19.7926 
+ 18.1628  19.7982  21.7942  23.1496  22.2974  18.3029  13.8973  12.5987  14.0955   8.3018  -1.2018  -2.7097  -5.1243 -15.5625 -20.9814 -25.9011 -25.5502 -25.1062 -24.3739 -25.8874 
+  5.1200   2.6682   2.7787   5.1220   7.7683   7.6609   0.3239  -0.5597  -2.1976  -4.2025  -2.3433   5.4581   3.3195  -4.6819  -7.7339  -5.9433   6.7709  -3.0093  -0.4617 -15.8570 
+  3.1474   3.9068   4.6743   6.1980   3.9172   5.5703   3.7560   5.3815   6.4792   7.4263   4.0188  -0.9053  -2.9276  -4.2640  -3.8751  -2.5664  -3.8921  -5.7279  -7.3914 -22.9261 
+  7.7606   7.9634   9.2590  13.4058  20.9130  19.2571  11.4285   9.1142  10.4227  12.6605   1.3940  -7.8667 -12.9049 -16.1586 -15.3321  -7.7158 -10.1835 -11.8246 -14.2319 -27.3607 
+  9.9378   9.7046  10.1765  13.1670   9.5151   2.2155  -0.0456   0.0357  -0.3521  -1.2640   0.0667   3.9496  -0.7853   0.9935   1.7327  -2.1738  -2.4763  -8.9075 -14.5354 -30.9548 
+  9.4566  14.4761  17.5184  16.5421  10.8319   4.8634   3.7958   1.0301  -0.7413  -4.7772   0.1278  10.6261   1.7256  -4.7562  -1.8151  -1.2979 -10.9708 -19.1139 -21.0656 -26.4558 
+  4.1609   4.3674   5.1630  10.4393  19.9966  22.0365  15.0772  16.7404  13.2009   0.0579  -7.2967 -13.1855 -16.4671 -16.2778 -13.5417  -3.6468  -7.6575 -10.0591  -0.8708 -22.2374 
+  9.2619   9.2850  10.6963  10.0411   5.3819   1.8030   1.0922  -0.3660  -0.8976  -3.1810  -0.6819  -3.8642  -8.4569  -8.9974  -5.5095  -1.9498  -5.7587  -2.8793   9.9987 -15.0177 
+ 16.0944  15.0736  17.4290  17.1266  16.3425  13.9152  -0.3124  -3.4633  -3.3349  -5.5676   1.0220   7.3152   5.0978   0.8308  -5.9027 -14.3898 -14.2461 -12.2320 -23.5828 -27.2154 
+  2.0137   5.7764  10.2219  14.9245  16.5703  10.5235   3.0729  -1.4882  -7.2050  -6.2506  -5.1311   1.5065   6.9953  -1.4430   1.8240  -1.5831  -9.7701  -7.7954  -0.2269 -32.5358 
+  0.8118   3.1428   4.1975   8.8492  17.1316  16.9999   8.6244  -0.0326  -4.9530  -5.2292  -0.1353   6.3691  -2.1837  -2.6835   3.8299  -6.3313  -4.7140  -0.2060 -11.6261 -31.8615 
+ 16.0656  15.8566  16.2660  14.0919   7.2745   1.1478   0.5592  -3.1884  -2.7528  -3.9872  -1.5200  -5.6031  -7.1936 -11.6082  -9.9024  -5.9648  -1.2652  -4.4434  -0.5317 -13.3008 
+  6.0546   7.8172  12.5175  18.9740  18.6314  12.5099   8.6741   7.3229   9.6232  16.1584   9.3568   6.3688   5.3827 -10.1648 -19.1392 -25.0842 -25.6307 -21.0082 -12.2957 -26.0685 
+  8.7645   5.7385   7.3877   9.4659   8.7034   6.7927   2.2815   1.6420   0.5587  -0.7987   1.2054   8.0228  11.5479   4.5805  -6.4932  -9.4841 -11.6576  -7.6077  -9.5897 -31.0604 
+ 13.5337  13.1762  15.6646  19.9549  24.3470  21.3479  19.5471  19.3675  13.3653  -0.5856  -8.6584 -13.2572 -16.9863 -17.9847 -20.7708 -15.4798 -11.0509 -15.4702 -16.1382 -23.9221 
+  9.4656  10.0639  11.4433  14.6680  18.7771  15.2024   9.3195   5.1370   1.9578   0.3561   3.7670   8.6933   1.3200  -4.9956 -10.6736 -14.3320 -17.7829 -18.0592 -14.3140 -30.0137 
+  1.5799   4.3053   2.3818   2.8910  -1.2059  -0.8300  -0.1903  -0.1292   1.0233   3.9206   3.9828   2.2978   3.2320  -2.5703  -2.6923  -1.3776   2.9213   0.1727  -0.5110 -19.2019 
+  6.8519   4.8647   1.9844   2.2401   3.7555   1.5005  -1.3694   0.5704   2.1485   0.7600   0.6917  -1.0898   1.8295  -1.7615   0.1607  -2.4085   0.4928  -1.2003  -0.2145 -19.8066 
+ 26.8652  27.9313  22.2964  13.2728   4.9234   4.9750  10.5105  12.7213   4.9587  -6.5278  -2.0124  -3.4059  -5.9594  -7.3378 -10.2568 -18.1183 -18.7465 -15.1523 -18.6899 -22.2476 
+ 11.7015  12.5524  16.8036  20.5917  17.3325  11.6535   7.9132   3.4464   6.4909   8.4604   0.1120  -8.6770 -13.3036 -17.0534 -16.5775 -11.3553  -3.4540  -9.9071 -10.9540 -25.7760 
+ 20.0026  21.9415  20.1743  15.7692   9.6829   6.6171  12.1877  15.1379   6.9729  -2.6223 -11.9260  -8.0030  -5.4775  -7.9242 -14.3282  -6.4602 -11.9823 -18.5276 -14.5214 -26.7133 
+  8.4727  10.3130  16.1554  22.5237  20.4885  15.1245  10.9192  10.3785  14.0959   8.6752  -2.6735  -8.1503  -8.9174  -2.4684  -9.1899 -21.2524 -22.7439 -18.1241 -17.6618 -25.9650 
+ 16.4001  11.0790   6.5408   3.9922   0.9638   0.6155   0.1321  -0.0033  -1.5205  -0.5347   0.0838  -0.8675  -0.2837  -1.6297  -1.6342  -2.7530  -2.7291  -3.0597  -3.9086 -20.8833 
+ 12.8347  13.9930  15.6832  15.4917  10.9362  11.4157  15.6476   4.3710 -10.8720   4.3584  -2.6363  -7.3238 -10.3423  -4.3725   0.4684   7.2994 -11.0045 -18.8176 -14.2499 -32.8805 
+ 12.3323  15.8058  21.8399  24.3008  14.4087  10.9930   7.8357   8.0265  12.8222  14.2335   5.8155   6.0731  -6.0593 -17.6762 -22.1263 -23.2555 -24.2165 -21.7123 -15.9183 -23.5226 
+  5.7344   5.3389   3.8374   3.4190   2.8812   1.7219   0.1439   1.8580  -0.5349   2.0653  -5.3722   2.7017   1.0724  -0.8636  -1.4371   0.4192  -0.6553  -2.1126  -0.7370 -19.4805 
+  8.7871   8.8914  10.5080  13.7939  18.1053  18.3809  13.6037   9.9123   6.2489   7.8891   6.4768  -2.8713  -8.9109 -11.1699 -11.8847  -5.8137 -11.8112 -19.3777 -21.5409 -29.2171 
+ 21.2487  22.5877  21.7624  19.0832  14.4498   8.3623   6.4664   3.1545  -0.2860  -1.9696  -3.9389  -1.8288  -3.7243  -9.6176 -13.7865 -15.0846 -11.3343 -12.9399 -16.9243 -25.6805 
+ 15.5067  16.3749  16.3110  12.8646   5.4498   2.4274  -1.0299  -3.2700  -3.2357  -0.0252   7.5399  -0.6948  -6.2588  -9.1664  -6.8883   0.7600 -11.6902  -9.9820  -1.1495 -23.8436 
+ 15.5548  17.3265  20.2482  21.9118  17.7825  12.4436   8.5947   8.3626  10.7582   6.8704  -2.6150  -7.1451 -11.7102 -15.2112 -16.7335 -10.8661 -12.1430 -16.7183 -19.7849 -26.9260 
+  9.7348  18.6985  22.2000   9.7733   3.5414  -0.9890  -5.4561  -5.4928  -8.4760  -6.8757  -4.1569   6.8951   2.1633  -1.2892   3.0483  -7.4717 -12.0842  -7.7317   1.0735 -17.1050 
+  6.6628   6.9628   9.2890   7.3292   2.0881  -0.1054  -1.5163  -4.7058  -4.4988  -5.4883  -6.5025  -2.6194   5.9468  -1.1287  -0.4851   5.3144  -1.6440  -1.6601   4.2795 -17.5182 
+ 11.7595  13.0074  13.6551  14.3417  13.9024  11.5890   9.9365   4.1950  -1.2916  -2.3847  -1.5414  -3.1381  -5.4213  -4.9864   0.0096   0.2286  -7.5940 -13.3606 -21.1287 -31.7780 
+ 16.5560  21.1528  18.2294  14.8217  11.7211   5.8948   0.1128  -5.7142   0.4819   3.4296  -7.6731 -15.2596 -14.0910  -4.3450   4.2359  -1.2610  -8.7829 -14.4366  -8.1323 -16.9402 
+ -9.6162  -5.8920  -0.4336  -0.0688   3.9825   0.7100  -1.9156  -3.0982  -4.8027  -4.2612  -2.6264   1.0431   5.5418  11.1806   9.5552   5.0905   3.5862   4.3463   5.8670 -18.1885 
+  9.2493  12.5210  14.8487  20.3042  16.9267  10.5281   5.4085  -1.4152  -5.3054  -5.3250  -4.1371   2.4443   0.8006  -8.0900  -7.9314  -5.9206 -13.5877 -13.0043  -4.8031 -23.5116 
+  5.9148   6.0122   7.7679  11.9347  14.3202  11.1880   5.7941   0.6362  -0.9006  -3.7616  -1.0465   6.3361   0.5894  -7.7629  -9.2778  -6.0898  -0.4740  -7.4253  -3.1780 -30.5771 
+  9.0470  12.9059  18.1346  24.2631  23.6353  19.2579  20.8877  17.0355   3.1774  -5.2773 -10.0473 -14.9178 -17.5773 -16.4551 -11.9394  -9.6664 -11.9143  -7.0063 -19.2353 -24.3080 
+ 11.6229  13.7686  16.3077  18.9730  21.2077  21.1770  18.6717  15.5260  14.4577  10.9286  -2.0523  -9.7658 -14.1470 -18.3895 -20.2191 -19.9491 -14.1791 -17.4745 -18.9708 -27.4939 
+ -1.2854  -2.7859   2.0352   3.8729   2.5634   1.1875   2.9803   3.4105   0.6928  -0.5396  -6.4408  -2.1739   4.1284  -0.7168  -3.4324  -5.3047   2.1060   6.1169   6.1700 -12.5844 
+  3.6719   5.1933   3.4330   2.0915   1.7090   4.9193   7.5225  11.4575   7.7921   1.1072  -1.3846   0.6720  -0.8916  -0.5196  -2.8857  -5.7085  -3.7344  -4.4707  -6.4364 -23.5377 
+  5.0076   6.0603   5.6858   5.8716   4.9796   4.3510   3.2343  -0.0278  -1.6006  -3.6879  -3.6306  -0.3994  -2.7867  -5.8602  -4.3815  -4.1661   1.9375   0.0251   1.7605 -12.3723 
+  1.5611   2.5677   6.9184  12.7642  12.9002   7.6294   1.5737  -0.4407  -4.6258  -3.3019  -0.3274   9.4821   8.3473   7.1185   0.9099  -4.2945  -2.0947  -5.5952 -16.6889 -34.4035 
+-10.0770  -9.2074  -7.5499  -5.3349  -2.0639   0.7289   3.3239   5.0911   7.8838  10.9963  10.2149   9.1756   7.3923   3.8453  -0.9308  -1.4293  -1.7749  -2.4954  -0.6350 -17.1538 
+ 11.6964  15.7897  21.5631  25.0743  21.2867  19.0704  20.7015  14.1826   0.0839  -7.4606 -11.2687 -14.0743 -15.6804 -14.7951 -10.8010 -12.5161 -17.6133 -13.8075  -7.4286 -24.0031 
+ -6.9283  -6.6188  -5.8684  -5.5056  -3.6164  -2.5751  -3.3395  -0.3521  -3.7955  -8.6077  -6.1256  -4.7755  -5.6371   1.9017   5.4236   6.9088  17.0056   9.6477  17.8081   5.0500 
+  1.0400   4.3584   5.7473   5.9965   7.1951  11.1543  16.3999  17.9219  13.7898   8.5105   6.6032   8.3888   3.1208  -8.4853 -12.1692 -10.3091  -9.4060 -16.3383 -22.0676 -31.4510 
+  4.0785   3.7601   3.2477   4.5535   2.8617   2.8959   4.0341   3.3572  -6.7255   5.4042   2.4187   1.2230   0.1581  -3.0654  -1.9472   0.8423  -1.1312   1.2092  -3.2861 -23.8888 
+  7.3239   6.9150   9.3764  18.0744  16.9415   9.6050   5.2932   1.9763   2.0297   6.2840  11.8379  10.9565   8.5711  -5.0433 -15.8094 -21.0356 -22.5868 -18.9436  -8.4281 -23.3379 
+ -1.7885  -4.8321  -3.3241   0.9574  -0.7694  -4.0018  -4.5674  -4.5260  -2.6221   4.0186   7.6808  10.9687   1.1618   6.5552   7.2914   5.9801   0.8194  -0.4241   1.0077 -19.5855 
+  2.5382   2.7665   6.6332   9.6977  12.0223   5.6888   5.2502  -0.0648   0.1790   1.7261   3.6718   4.6019  -4.2546  -5.2838  -8.6175  -3.5030  -2.8900  -5.1451  -3.1562 -21.8607 
+ -1.7959  -1.6410  -1.3048  -1.9856  -1.1093  -0.5878  -1.7759  -0.7425  -2.7139  -3.3222  -3.9402  -1.9787  -4.1788  -1.9573  -0.0518   0.6181   5.7386   8.4544  14.2974  -0.0227 
+  1.9227   3.4879   4.9261   5.1627   4.2257   4.6417   3.0455  -0.4550  -1.9330  -4.6665  -6.5225  -3.7829  -5.2713  -1.4162   3.7054   5.6573   7.0460   2.7847  -1.9201 -20.6381 
+  5.4951   4.1184   5.0794   4.1307   2.3794   0.0327  -0.8237  -1.5895  -3.7505  -6.6385  -6.0766  -2.2466  -0.4080  -4.9327  -5.8400  -1.6035   0.3752   6.5602  12.3259  -6.5875 
+  6.8048   2.6542   8.2117   4.3594   9.5824   4.9978   9.2805   5.4616   0.1801   2.8218   4.8979   8.0336   1.3602  -0.8584   3.0641  -6.3167 -11.4947 -13.9096  -9.3665 -29.7643 
+ 20.4394  23.8508  19.9523  13.4804   4.7063  -0.8810   2.3157   4.3508   4.6054   2.6117  -2.8160  -5.7052  -5.0189 -10.4846 -14.5942 -12.8055  -6.1098 -12.0585  -7.7055 -18.1337 
+  9.9351  14.3502  19.5530  16.3727   7.0796   2.9949  -1.1604  -3.2246  -3.9592  -2.8637   3.6007   8.3194   1.5624   4.0080  -6.2282 -13.2960 -15.2078 -10.4525  -5.9946 -25.3891 
+  5.5354   4.2644   3.4234   3.5650   3.9406   1.8276   0.2709   0.3493  -0.0020  -0.7304   1.8692   2.1692  -1.3779  -0.9234  -5.0911   0.1335  -1.1518  -0.8308  -1.2357 -16.0052 
+ 14.7180   8.4248   6.7389   6.9731   8.7963  12.7964  14.6589  10.3137   3.2909  -3.7235  -5.8542  -6.9864  -6.8348  -4.2701  -4.4326  -5.4747   0.7281  -9.3904 -11.2298 -29.2424 
+  9.1842   9.7851  10.8472  12.9244  10.6955   6.8423   4.6037   0.7650  -2.0301  -2.7855   1.3686   5.5053  -1.4464  -8.6948  -6.8949  -4.4565  -9.3587 -11.9106  -7.0277 -17.9162 
+  9.5187  11.0469  10.8992  10.5477  12.4336  17.9310  22.0092  22.1029  21.2249  17.7472   4.1368  -3.9142 -11.6583 -18.8125 -22.4708 -24.5855 -14.9292 -12.6855 -22.7109 -27.8313 
+ 12.0341  16.6419  15.8489  10.0396   3.3655  -1.8695  -5.2143  -9.4106 -10.9745 -12.0991 -12.0450 -11.1231  -7.2635   0.0306  12.4231  12.6061   4.1888  -1.9085   0.6831 -15.9537 
+ -1.3674  -0.5228  -4.0775  -3.8100  -1.0761  13.7500  19.2044  15.7231   9.5615   7.9996   6.5298   3.6199   0.5658  -1.3324  -7.5527  -6.3571  -7.0946  -6.2162  -8.1181 -29.4293 
+  7.3145  11.1318  15.8219  21.2414  19.7326  13.4391  10.1286  13.1458  13.5220   4.5818  -4.9865 -10.4663 -12.4137  -8.4915  -7.5278 -14.5074 -14.9519 -10.6855 -18.9716 -27.0572 
+ -2.6938  -1.0116   0.5434  -0.5197   1.2510   2.7810  -3.1452   2.3461   1.3093   1.0916   0.2998   1.6109   9.4326   9.1761  -2.9635  -1.3175  -1.3459  -2.3687  -0.4622 -14.0137 
+ -0.6799  -0.1341   0.7366   1.5016   2.3553   1.9877   1.8684  -1.1687  -1.7388  -0.3259   3.2899   3.7096   2.8005  -0.4016   0.0798   0.8146   0.2490  -0.5574   0.0812 -14.4681 
+ -4.5962  -1.7335   2.2323   4.9758   4.1965   6.1120   6.3004  -0.2420  -0.4268  -3.4101  -1.9343   1.8578  -0.3352  -3.5061  -2.9167   0.7871   0.7063  -1.6356   3.3878  -9.8196 
+ 13.1227  13.7568  12.0750  11.2378  13.9543  15.7037  14.8582   9.5334   0.1292  -3.0889  -7.7565 -10.9896  -5.4579  -2.1373   0.1387 -11.7169 -13.0933  -7.4977 -12.3640 -30.4077 
+ 29.3087  22.8979  20.4744  14.9176   7.8398   2.3822  -3.7671   1.0563  -3.5131   2.1709   4.1060  -2.4865  -7.3802  -9.3667  -9.8213  -8.8247  -9.4073 -14.9259 -16.1530 -19.5079 
+  8.2477  12.7093  19.4580  20.8257  15.6422   8.6762   4.5782   4.1335   5.6439  14.7051  12.4104  11.4909  -6.3291 -17.1032 -20.7835 -24.4558 -22.5241 -14.5649  -5.2278 -27.5328 
+  0.7217   4.0954   5.2473   1.5270   1.7119   3.5822  -1.4614   0.8720  -1.3606  -1.4757  -0.4869   1.0336  -0.7433   2.0743   0.6152  -7.1442   0.5920   6.3583   2.8714 -18.6301 
+ 20.3582  21.7378  21.8475  15.5031   8.5323   5.5254  -0.6584  -4.0833  -5.5901  -5.8466  -2.2597   3.0499  -4.1864  -7.3615  -5.3521  -8.6549  -8.7165 -10.8646  -9.6599 -23.3202 
+  7.9037   5.3843   2.5963   1.7924  -4.1648   1.1119   1.0025   0.4959  -1.4533  -3.0047   0.7379   1.8636   2.4329   0.9500  -0.1706  -0.3177   0.7889   1.1735  -0.4730 -18.6499 
+ -1.9942  -2.2404   1.0361   1.1275   2.4246   0.9687  -0.7731  -0.4350   2.7773   4.6081   2.2666   5.9874   1.4863  -4.3135  -1.0943   3.1059  -4.9201   3.6382   1.5522 -15.2082 
+ 15.5189  17.8940  20.2047  21.1613  16.5719   9.8830   6.2072   1.5961  -2.8649  -4.2350  -1.2109   1.6294  -0.3114  -6.2890  -6.6470  -6.6461 -16.7097 -18.4834 -19.5782 -27.6908 
+  4.5707   9.9453  16.9194  16.3836   7.5074   1.7185  -1.6704  -4.6470  -7.1710  -7.5216  -6.2372  -1.4728   9.1990   4.5872   4.2446  -3.1203 -10.1462  -8.9093  -2.0237 -22.1562 
+ 10.2043   6.2265   8.0480   6.0822   2.9673  -0.2686  -0.4905  -3.3479  -4.2925  -4.0224  -2.6407  -3.8742   0.6899   3.7007   5.8631   8.8480  -1.0855  -6.5692  -4.1304 -21.9079 
+ 12.9155  18.0966  19.8262  14.0767   6.9947   1.6106  -0.8791  -6.2102  -7.3162 -10.2835 -10.9883  -8.3441  -1.6557   0.0080  -5.7847   1.4192  -5.5022  -4.2471   3.9784 -17.7147 
+  5.1637   8.0679  12.5738  17.5701  14.9252   4.1592   0.9276  -0.3161   0.0005   3.6819  10.2605   3.1026  -2.7955  -2.8307  -1.1861  -9.2862 -11.7976  -5.3295 -15.7634 -31.1274 
+  6.9673   6.7974   6.1367  10.4782  15.9809  13.2295   4.9742   0.4813  -4.1310  -5.6911  -5.9712  -1.2511   7.3306   2.6442   0.3224  -0.8372  -7.4799  -9.3018  -8.5882 -32.0913 
+ 13.1396  12.9563  12.3478   9.0857   2.3849  -0.8490  -1.4825  -4.2362  -7.2804  -7.4639  -6.8853  -6.4479  -4.2443  -8.2231  -3.9022   0.4289   0.1896   3.7001   6.9697 -10.1879 
+ 15.3330  18.1603  22.1112  21.6848  13.1886  10.5333   8.8464   9.6626  12.4137  13.9577  10.1420  -0.2864 -11.4409 -16.9791 -19.7494 -15.6645 -19.7643 -22.5000 -23.5283 -26.1208 
+  6.8457  -6.8649   5.4271   5.2712  -1.3685   5.0072   1.5557   0.4655  -8.6121   0.8133  -3.3697  -1.5367   2.2231   2.7614   0.6905  -0.9517   3.9757   2.5271   6.8378 -21.6975 
+  4.0198   5.3861   1.4690  -2.5892  -0.7717   2.5302   1.6444   0.6228   0.0646   3.2916   3.8112  -0.6089   2.1623   0.1459   0.1339   0.1325  -1.6768  -0.5331  -0.5013 -18.7335 
+ -7.1586  -2.6175   0.5796   4.1833  -1.3849   0.3608  -8.9238  -4.4835  -1.6026  -5.1856  -8.3891  -1.4730   9.5706  -8.3291  11.6042  11.1480  -0.2734   4.8182  12.1074  -4.5509 
+ 12.6166  14.8923  16.2633  17.1269  18.2744  19.2870  16.5858  10.4162   6.9131   6.3384   2.9142  -1.3754 -10.9051 -16.4865 -19.5016 -17.7616  -6.9047 -16.5161 -23.1066 -29.0706 
+ 10.8009  12.8094  14.6516  18.7246  16.6285  12.1161   8.7229   6.4887   7.8806  10.1330   4.1720  -4.3839  -6.8368  -8.8011  -8.4415 -14.6175 -16.9291 -13.3638 -20.2402 -29.5143 
+  6.2190   6.4291   6.1608   8.0273   9.8018   9.8514   6.5431   7.0773   5.8326   5.6116   8.2150   7.4679  -0.2957  -6.5386  -7.9000  -7.1888 -10.2895 -12.2362 -14.0338 -28.7541 
+  8.0266   9.6417  12.2059  15.4655  15.3945  10.4886   6.7757   2.3300   3.3664   6.5551   2.3159  -4.1967  -9.2962 -11.8145  -9.9788   0.0400  -6.7484  -6.4088 -11.3916 -32.7710 
+ -6.0361  -3.7035  -0.2831   1.4674   0.7756   0.3247  -0.7445  -0.5024  -2.1341   2.7813  -0.1459  -3.5635  -3.9893  -4.2930  -0.5948   5.6527   2.1314  14.0267  12.5554 -13.7247 
+-14.2301 -11.8469  -5.4438  -2.2899   3.4911   0.4713   0.7187  -2.7114  -1.5588  -2.8210  -0.0887   1.5060   2.8286   9.3500  12.2742   8.0817  12.1298   7.7574   3.4239 -21.0423 
+ 10.2809   9.4545  10.3039  12.6386  19.4980  22.5798  19.2258  15.3342  18.1620  10.8305  -3.6184 -11.2472 -16.1533 -19.0561 -21.3742 -19.1215  -7.0133 -13.0322 -12.3255 -25.3663 
+ -7.1992  -4.0950  -0.4752  -0.0397  -1.2923   1.2680   2.1020  -2.0159   0.5678  -4.1475  -2.2860   1.2468   2.9160   3.7433  -3.5078   6.2645   5.1466   3.3947  11.0482 -12.6391 
+ -1.4558   2.6350   2.5261  -0.4261   7.9067   7.3761  10.5050   2.1413  -4.1382  -2.8818   6.9021   5.4317   4.9534   4.5363  -2.8372  -3.4508  -1.0165  -1.6706  -9.0235 -28.0132 
+  5.4483   7.0338   8.8713  13.9617  19.3432  16.5740  12.5536  13.7232  15.1487   4.1979  -4.0767  -8.9863 -10.9482 -13.1722 -11.3412  -7.4945  -4.4916  -3.5707 -22.8865 -29.8879 
+ 12.0309  14.2862  17.8716  18.2606  13.3426   8.9006   1.3455  -9.4180 -11.1012 -15.4444 -17.4768 -17.9985 -12.4515  -5.2431   8.8612   5.5913   6.3114  -1.1018   0.2013 -16.7679 
+ 16.8689  16.8256  18.5632  14.4683   8.2457   2.7262   1.7491   0.4673  -4.4682  -6.2835  -4.3280   2.1966  -4.4856  -9.6447  -7.5807   2.0175  -9.6747  -9.7002  -3.6650 -24.2978 
+ 10.3443   9.5624   9.5859   9.3945   7.7097   5.9502   5.4955   7.0578   3.8970   1.8002   2.9026   0.8300  -0.8072  -3.4283  -8.7861  -9.4681  -7.6897 -10.0581  -8.5829 -25.7097 
+  8.4589  13.9060  18.3570  21.8577  20.8363  13.5168   7.0018   3.5585   0.2984  -4.3657  -7.6435  -5.4526  -6.4991  -0.0823 -10.9834 -14.4890  -9.9873  -4.5713 -15.9935 -27.7237 
+ -2.7942  -1.0695  -0.1214   2.5877   1.5098   1.0893   1.5717   3.2131   6.2989  10.9335   9.8682   8.6743   4.8838   1.8707  -1.0579  -3.7852  -5.7917  -7.6708  -7.9578 -22.2525 
+ 25.1784  20.8581  17.0052  12.9557   7.7424   3.9815   6.0072   3.4663  -1.9041  -8.1079 -11.4077 -11.8642  -8.7727   4.7601   2.8284  -7.3135 -15.0133 -13.8178  -7.5999 -18.9821 
+ 13.6088  10.9215  11.1892  11.7633  13.2294   6.3264   1.9267  -1.7303  -3.3278  -4.4979  -7.2855  -3.9683   5.3311  -1.6679  -8.5378  -6.9275   2.8396  -8.2151  -5.8206 -25.1573 
+ 20.0774  19.5893  17.1250  15.9021  10.2327   5.8537   4.1551   8.7468   6.2824  -1.6643  -0.8142  -5.7458  -5.8553  -6.7971  -4.8129   0.1863 -14.4064 -22.1846 -19.7857 -26.0848 
+  1.9579   3.5459   5.6047   9.8227  17.1510  16.9383   8.2371   2.3829  -0.9137  -2.6491  -2.1733   3.0262   6.5399  -2.8952  -2.9389  -0.9532  -9.2242 -11.9604 -12.7131 -28.7857 
+  2.7147   5.0851   5.9010   8.2492   9.0379  12.5344  15.7585   7.9343   2.8699  -7.6515  -7.5935  -7.0792  -7.0329  -0.2973  -4.1153   0.8146   0.8342  -8.0293  -6.0641 -23.8708 
+ -1.8671   0.2021   1.1744   3.3514   3.8114   4.6535   6.4708   5.5903   4.6873   6.1200   7.1503  10.8820  10.1467   5.0564  -4.0471  -7.0223  -5.8028  -7.0328 -13.2761 -30.2485 
+ 14.4582  17.2732  16.2772   7.1332   0.6525  -4.4947  -7.7910  -9.8395 -12.5801 -10.7856  -8.8712  -4.2717   7.2719   0.7198   1.5521   3.5804  -2.9845   0.1717   6.3548 -13.8266 
+ 28.6852  25.8888  20.5479  11.1546   4.6177   1.8681   3.9247   1.2950  -2.9240   4.3050   4.3461  -5.4196  -7.8904 -10.2821  -8.2802 -13.9910 -11.2895 -12.5380 -13.7725 -20.2458 
+  6.9489   8.2782  12.9177  18.1269  10.1196   2.5932  -1.2838  -5.9588  -9.0612 -10.7381 -10.6395  -8.4104  -4.0818   7.0965   0.3344   2.1418   2.2817  -3.7137   1.6102 -18.5618 
+  6.2919   7.1483   7.7499  10.3266  12.7585  21.8234  21.7899  13.6697   7.2737   9.3185  13.4418  -0.1530  -6.4198  -9.4554  -7.4143 -12.4542 -21.2295 -24.5545 -24.4585 -25.4529 
+  3.2078   1.1604   2.3820   7.1676  15.6309  19.6735   9.8897   7.8474  10.1305  10.4050  -1.8220  -9.0708 -12.7476 -14.2980 -11.7869  -3.2366  -4.1439  -6.6114  -0.0121 -23.7655 
+  4.9484   5.9562  10.0092  16.2669  12.9260   3.9525   0.4920  -2.9838  -4.7825  -5.0706  -3.0972   4.4166   5.1484  -3.0885  -2.2935   1.8467  -6.6209  -8.5405  -3.2672 -26.2180 
+  9.1190  11.7308  15.3181  20.5759  15.7183   7.6900   3.7341  -3.2723  -6.7161  -9.0437  -8.0703  -0.5930   6.4087   3.5269   3.0413  -8.4178 -14.7425 -12.7049  -6.9905 -26.3121 
+  1.4852  -0.6829  -1.5690  -0.2848   5.5052  12.8631   6.4129   0.4626  -3.5500  -5.4162  -3.9006  -1.4888   7.5205   5.6490   1.1393   5.5204  -1.2344  -6.2194  -3.0728 -19.1390 
+ 11.9158  15.3244  18.2371  17.8689  12.9861   8.5734   2.6935  -0.4620  -0.3115   4.3187   1.8359  -6.5328 -11.3944 -12.3343 -10.2127  -3.2123 -10.7404 -11.6243  -6.0915 -20.8377 
+ -1.1406   4.4681   1.0243   1.7567   0.8452   1.0568   1.7113   1.4304   8.2151   0.5703   1.2053  -5.7909  -4.3638   0.9165  -4.5872   3.4354   6.9859   3.9875  -3.5121 -18.2142 
+ 18.8171  22.5033  16.7157  10.3549   3.9514   1.6962  -0.6346  -5.9992  -6.8816  -7.3001  -7.9076  -4.3326   4.9348   4.6458   0.9437  -3.5521  -9.3640  -2.4386 -11.4118 -24.7409 
+ -0.9409   0.5904   2.2794   4.9547   5.8743   8.7846  11.0088  11.1838  11.6958  14.1355   8.9116   2.5256  -1.8779  -5.6262  -5.5753  -9.1754  -9.0981 -12.4659 -11.4699 -25.7149 
+  0.4141   2.8215   2.0838   3.1886   4.2216   1.7188   4.6179   2.9704   1.6545  -2.8460  -0.9511   2.6537  -1.8008   0.9825   1.2384   1.5282  -0.7271  -3.0940  -0.8090 -19.8659 
+  6.0430   4.6516   4.3017   7.7179   6.7963   6.2910   8.7476   8.7592   7.7014  12.1586   8.0227  -1.3414  -6.0075  -8.1097  -6.8511  -6.6141  -5.8068  -8.7086  -9.3302 -28.4218 
+  7.1395   6.4611   6.4770   6.5752   5.7360   5.6174   3.8338  -0.3402  -1.9803  -2.2319  -4.1316  -3.2411  -2.2252   4.1950   1.9636  -1.7425   0.5431  -3.5115  -6.8529 -22.2844 
+ 17.8843  21.4402  20.6904  15.9517   9.7051   2.5656  -1.5516  -7.4554  -8.8729 -10.2263  -8.6781  -5.1896  -0.7045  -6.7680  -8.2898  -6.9326   1.3954  -3.2208  -6.0504 -15.6928 
+ 10.6767  10.3544  18.1231  11.2879   6.1413  -0.3610  -2.4504  -5.1076  -4.9943  -4.9704  -2.3126   5.9757   0.9523  -4.2427  -2.5152   4.9197  -8.3019  -9.0057   0.3384 -24.5078 
+  9.9161  11.8977  18.2327  24.4645  22.2618  14.5543  11.0874  11.6473  16.7269  16.7802  10.9221   4.3259 -12.8739 -20.0422 -22.5408 -24.1296 -20.9142 -22.6765 -24.3668 -25.2731 
+  9.4023   7.3715  11.9062  12.5120   7.0268  13.6459   7.2747   2.8388  14.6515  22.1573  24.2647   6.5863  -1.1334 -12.1075 -18.8356 -21.0343 -18.7149 -21.3705 -23.1378 -23.3040 
+  6.1154   6.8878   8.0486   2.0830  11.4555  24.4875  10.2548   8.5452   8.1934  -4.1865  11.8854   1.3485   1.9895 -14.5678 -11.0286  -3.4615   1.3428 -19.7548 -24.2069 -25.4313 
+ 10.3570  12.8522  17.3265  22.8368  16.6859  10.9743   8.2198   6.8557   9.3432  12.2609   5.1561   1.5410   1.3448 -11.6896 -19.8579 -22.4891 -19.3409 -16.0157 -19.9891 -26.3720 
+ -2.2958  -3.0198   2.5524   6.5326   5.0549   2.8939   1.6085   1.4431  -0.1701  -2.0055   1.1867  -1.3016  -2.2987   6.1240   3.0188  -0.9646   2.6135   4.0735   0.2584 -25.3041 
+  3.3425  -4.9398   1.7857   0.9810   8.2974  13.8760   7.3422   4.3951   4.0317   8.9378   9.1371  -1.7588  -9.1168 -12.4667 -12.0238  -9.0772   4.3501  -0.6556   4.4305 -20.8684 
+  2.6724   2.4627  -2.5441  -3.3045  -4.2917  -1.4508   1.5865  -1.0572  -2.1109   1.4870  -1.0006   3.5002   3.7107   1.3794  -1.6261   0.0378   2.0162   0.3261   3.2452  -5.0385 
+  3.1268   4.8784   8.6218  13.5865  14.1019   7.2490   1.4764   0.4142  -1.4440  -0.1256   6.7242  13.6333   7.9001   5.1808  -8.7618 -15.9427 -17.5740 -13.2732  -3.9031 -25.8689 
+  8.7515  17.2518  23.5164  15.7690   8.1574   4.9814   0.5026  -0.4621  -1.5217   2.4458  11.1982  12.8925   8.2107 -10.1894 -18.8969 -20.9839 -19.6436  -9.2705  -7.3159 -25.3934 
+ 11.7980  12.1448  14.6065  20.2682  20.5368  14.0544   8.9695   7.1447   9.3182  10.2279  -1.3945  -9.8630 -14.2310 -14.2600 -11.2940  -5.3186 -14.6453 -16.0278 -14.7441 -27.2906 
+  8.3692   9.6882  12.8542  17.3005  21.1340  18.5917  11.2777   5.5517   0.5470  -2.3437  -2.3633  -0.2054   0.7833  -4.4844  -5.7547  -6.4185 -15.2118 -20.9890 -20.6002 -27.7265 
+  3.2540   3.5495   5.6572  11.4443  18.6822  14.2818   7.9623   5.8581   7.6636  11.2380  10.4719  -0.3434  -0.9127   0.3323  -9.6682 -12.3368  -7.0303 -17.5040 -22.5944 -30.0053 
+ 10.5668   4.7765   4.8789   5.9385  13.1029  20.5979  14.5257   8.6496   2.4271  -1.1640   1.2029   9.4957  -0.0200 -12.5730 -14.8513  -9.4220  -4.4288 -12.9535 -14.3720 -26.3782 
+  3.6092   2.1429  -0.2581   2.1516   6.0252   4.4742   4.3520   2.9527   3.6102   2.6901  -0.0942   2.2564   1.3309  -0.5758  -1.1090   0.1191  -0.1180  -0.1015  -5.5503 -27.9075 
+  8.4206  12.6530  18.9633  23.9855  21.2540   9.7237   1.5121  -0.7361   0.7545  -1.5581   2.4158   9.9186   6.7278   3.6705 -12.4971 -19.8574 -23.2581 -23.7200 -10.9203 -27.4525 
+ 22.1951  16.4633  13.2055   7.4970   2.2280  -2.4528   8.7730  10.6870   4.9929   1.1178  -5.3802  -8.2471  -5.7256  -8.8078  -8.3540   1.5835   1.5054 -11.6521 -13.9564 -25.6726 
+ -7.9053  -6.5840  -6.0103  -4.8986  -4.2425  -4.7462  -6.7261  -8.5401  -8.6906  -8.8402  -5.6306  -0.7673   8.6501   5.0800  13.9798  11.4953  10.0314  17.4290  14.9683  -8.0522 
+ 11.9359   8.4098   2.8637   0.1621   4.2653   2.6990   1.2433  -1.9101  -2.5608  -4.4372  -0.7370   5.0345   2.4512  -1.2451  -4.6924  -2.0267   0.3932  -0.7445  -1.8229 -19.2813 
+ -1.3202   3.8184   7.4609  11.6391  16.2849  25.4929  15.8707   1.4126  12.3759  21.2527   8.1587  -3.8943 -14.7860 -10.6930 -17.9239 -16.3824  -1.7644 -13.0054 -19.3451 -24.6522 
+  9.8443   9.9627  12.5201  13.7261  10.3992   6.6290   2.9281  -0.7644  -3.9695  -5.3737  -8.3704  -7.5382  -1.7207   5.7599   1.9410  -0.8146   0.5436  -5.6632 -12.2155 -27.8236 
+  6.4290   4.7082   3.9317   3.1702  -1.6353  -3.6078  -6.3150  -9.1986 -10.3233  -9.8065  -5.8063  -1.3404  -0.7673  -2.2448  -1.2797   7.1795   3.2561  15.5273  14.8629  -6.7401 
+ 23.9506  22.1558  17.7456  14.4350   8.3329   3.1023   4.3134   8.6024   3.8015  -3.9642 -10.7800  -9.6229 -10.8860 -10.6376  -8.0083   4.7524  -6.4851 -13.7226 -12.4871 -24.5980 
+  9.5760  11.4366  12.9012  14.4846  16.8425  19.5473  19.7042  15.2736  12.0272  11.0446   7.4677   1.1314  -9.0848 -18.3215 -23.8214 -23.1710 -19.9932 -10.2715 -17.3599 -29.4137 
+ -3.4431  -3.1613  -1.9102  -0.6935   1.3870   1.2966  -1.0892  -2.4642  -3.0407  -4.4927  -5.4209  -4.2773  -0.5358   0.4090   1.2794   5.8990  14.3402   3.7638  11.1512  -8.9972 
+ 15.2464  18.8014  25.3166  19.5775  11.0313   6.5896   5.6381   2.9552   5.1185  13.2540  13.6736   8.5584  -8.3365 -15.9401 -20.3756 -21.2859 -21.2275 -19.3217 -15.1325 -24.1407 
+  3.1035   6.1792   5.0462   3.5926   7.0741   6.4046   9.9419   7.7684   4.2113   3.6277   6.5092   5.5900  -1.7178  -6.4492  -7.8871  -6.9582  -5.1379  -8.3058 -10.5436 -22.0490 
+ -0.7280   0.5704   3.9717   5.9469   6.0780   4.0770   1.2426  -1.3458  -3.2314  -4.6819  -6.2378  -5.0198  -1.2080  10.5808   2.6382   3.7712   3.8446  -1.7555  -1.1558 -17.3572 
+  5.3326   5.4267   9.8240  16.2001  13.6887   6.9510   1.1917  -1.6723  -2.5788  -2.7648   2.6931   5.4843  -4.2095  -9.6143  -6.2919   3.6211  -3.8754  -6.5263  -5.2823 -27.5977 
+  2.5771   3.4727   5.4467   8.8349   9.8870  12.1341  12.0826   7.7444   4.5255   0.7889  -2.0382  -4.7604  -5.7542  -4.6241  -2.4718  -4.0958  -6.2797  -4.6267  -9.5398 -23.3031 
+ 14.7846  16.0256  18.4400  18.7731  12.4129   9.2087   4.9463   5.2837   7.9434   9.1983   5.6775   1.0431  -7.1678 -12.3799 -13.9635  -9.4290 -13.5075 -18.2553 -21.2672 -27.7670 
+ 14.0860  12.6160  17.7362  22.8480  13.2766   7.4189   5.7487   1.8704   2.3287   6.7312  16.7040  13.9396   0.1199 -14.2720 -18.2397 -22.3862 -24.8172 -19.6941 -10.4326 -25.5823 
+  1.2702  -1.2740  -3.7100  -0.5628  -4.5219  -4.4580  -7.7100  -8.3547  -7.0524  -3.3805  -3.0927   1.9780   6.7217  16.8392  12.2288   6.1018   4.3647   3.7046   7.0648 -16.1569 
+ -1.5691  -0.6625   0.8145   2.7114   4.5683   6.3808   5.3169   3.3697   3.7409  -1.1329   1.3502   1.4333   7.1092   8.0819   7.4140  -0.3489  -3.5222  -5.2023  -8.9373 -30.9159 
+  8.8791  11.5486  17.4354  21.9590  18.7721  13.0614  12.3597  15.8383   7.9901  -4.7504 -11.1404 -17.0402 -20.1418 -20.5768 -16.8543 -10.2710   3.5082   1.5897  -6.0317 -26.1349 
+  1.4924   2.3041   3.6995   3.9735   2.9478   1.4182  -0.1153  -0.7081  -1.6935  -4.7155  -3.8966  -1.0552   4.3924   3.5582   4.7903   3.4573   4.4498   3.7588  -4.9783 -23.0800 
+ 19.7104  23.5312  26.4663  21.1276  13.4352  11.0142  11.5216  12.6431  11.6620   1.8352  -2.6313  -2.1531 -10.9044 -16.4683 -19.1821 -21.4207 -21.6631 -20.6795 -14.5440 -23.3003 
+ -7.3825  -5.1236  -2.0803  -0.3985  -2.1515  -3.3191  -2.5398  -3.6553  -4.6673   0.2450  -1.1380   0.4163  -5.0235  -3.1123   1.6781   0.5456   9.2542  19.9831  16.2303  -7.7611 
+  2.5108   2.1845   2.6268   3.2213   4.7277   4.9151   4.4068   2.5115  -1.2667  -1.0470  -0.5840   3.1980  11.3786   3.1343  -1.5396  -0.7790  -4.2909  -5.9553  -4.0558 -25.2973 
+  1.3099   3.8149   5.9305   6.0290   6.2561   6.5634   6.5483   2.2558   2.8164   5.8479   6.7553   3.8567   2.7371  -0.0626  -3.8527  -5.1436  -5.5124  -7.3236  -9.2045 -29.6219 
+  6.9414   7.8896  11.9174  19.4391  22.8159  17.5130  12.8967  11.7403  13.3801   0.6255  -8.6365 -13.1338 -15.0777 -14.1269  -8.2615 -12.9862 -16.1846 -10.2908  -1.8314 -24.6297 
+ 13.6675  18.7539  23.7644  23.5665  14.5584   8.2788   5.9566   3.8037   5.8231   9.3954   3.8096  -3.7071  -3.0809  -2.7965 -15.3910 -22.2338 -22.7083 -19.7578 -17.2327 -24.4698 
+  6.8878   4.6215   4.0830   1.7534   6.3161   9.3030   9.1793   1.8539  -3.8953  -6.2684  -7.2830  -6.1167   0.8013   5.3564  -0.9241  -2.6976   1.7576  -1.1627  -4.9125 -18.6528 
+ 11.5366   9.1379   9.1023  13.3107  15.2931   8.4262   2.0019  -1.8545  -5.3470 -10.4980 -13.1650  -8.7617  -2.8037   6.5213  -2.9746  -1.1653   2.8950  -3.9002  -0.4074 -27.3478 
+  8.1149   5.2054   4.7193  10.9119  14.2393   9.7159   2.7743   0.0628  -0.9042   2.5046   6.2675   4.5297  -1.7121  -2.7212  -6.4591  -8.2032 -12.1525  -9.7960  -4.5542 -22.5432 
+ 10.4270  10.1489   7.8411   6.9092   5.2675   3.1553   3.1860   0.3063   0.4719  -0.8710  -0.6868  -1.1505  -4.6137  -2.9984  -2.9661  -2.8540  -3.0302  -2.2057  -5.9823 -20.3547 
+ 16.5991  18.8180  20.4139  16.0812  15.2582  13.6000   9.7730   4.8200   7.2670   0.5444  -5.1929  -8.9752 -12.2178 -15.2451  -9.0857  -9.6324 -11.9042  -7.0554 -15.8485 -28.0175 
+  6.9984   7.5807   9.7172  14.2935  21.1422  18.8026  13.0729  13.6068  15.6061   5.7873  -4.4176 -10.6630 -14.9625 -15.2760 -12.1485  -4.9859 -13.8661 -15.0801  -8.9505 -26.2577 
+  4.8529   5.9107   5.9519   3.1046  -0.7986  -3.8000  -3.3218  -6.5949  -9.5964  -7.6925  -7.0336  -3.5031   2.4411  -0.1901   9.1699  13.0532   0.4243  10.9470   3.0406 -16.3654 
+  2.3975   0.4924   3.8005   6.1460   0.9043   2.1381  -0.0106   2.9239 -11.7677  -3.8359  -3.4925   0.8716   3.4740  -2.8287  -3.8786   1.2858   6.8931  -2.1701   3.3894  -6.7326 
+ -3.5428  -1.3900   0.9285   2.4806   2.9675   0.7980   0.9612   0.2854  -2.0562  -1.3222  -1.9025  -0.0059   8.6474   4.6327   1.6964   0.3984   0.9512   1.7069   1.4812 -17.7159 
+ 17.4798  18.9995  21.9699  20.6967  14.4015   9.2408   9.2963   4.6834  -0.5765  -2.0466  -4.6870  -8.1340 -10.8400  -6.9387  -4.9129  -2.3346  -9.5282 -16.6374 -22.8620 -27.2700 
+ 30.2051  29.0816  22.7010  15.9702  13.2347  12.3034   7.9736   1.7110  -2.9050  -5.8220  -9.0457 -11.4933 -10.9824 -10.7128  -9.7198 -11.4470 -12.1083 -14.3720 -14.3489 -20.2236 
+  4.3667   5.6948   7.6382   9.1345   7.9965   5.9946   4.8983   4.5838   1.3099  -1.1182  -2.4032  -2.5986  -0.3123  -3.8248  -3.3874  -4.6492  -2.5381  -4.1010  -4.4278 -22.2567 
+ 13.3799  15.9919  18.2801  18.5738  14.5051  15.0610  12.6361   1.8684  -4.4789  -7.5763  -7.3687  -5.7285  -8.7693 -10.0970  -1.0795   0.7696  -6.5956 -14.5402 -16.2583 -28.5735 
+  1.2989  -0.2985  -0.1264   2.2528   6.1919   9.0850  11.5888   9.6084   6.4565   4.6999   3.8291  -3.1433  -2.0178  -5.4377  -3.5892  -2.4088  -3.4525  -6.5279  -6.8848 -21.1245 
+  6.6990   6.9952   6.9900  10.6461  18.1760  23.4925  20.7738  19.3068  14.5258   4.1679  -5.0313 -10.5967 -15.7569 -18.7535 -19.3572 -18.4953  -9.1098  -8.3084  -3.5080 -22.8561 
+  0.3614  -3.0919  -2.2049   0.2924   3.5194  12.3203  10.5339   6.5081   2.9888   3.7587   9.6208   6.5139  -3.3458  -8.5883  -8.7468  -4.7300   1.1707  -5.5824  -3.0982 -18.2001 
+  3.6833   5.1669   7.0034   5.1138   6.2451   5.1324   2.9024  -0.2756   0.6913   0.7688   2.7471  -3.0081  -4.2841  -1.6790   0.6913  -2.2915  -1.1739  -2.5591  -2.7007 -22.1738 
+ 11.4726  11.0663  10.8078  10.4446  10.6033  12.3965  13.0646   7.6243   1.8855  -2.1733  -3.8981  -0.7658   2.9887  -2.4982 -10.2150 -14.2533 -12.1696  -5.4330  -8.3400 -32.6080 
+ -6.7179  -4.6131  -3.1636   0.0876   0.6888   1.0614   0.5541  -3.5030  -3.5922  -2.2597  -0.8136   6.0096  11.8925   2.9252  -1.1450  -0.4619  -0.0294   2.9522   6.4894  -6.3616 
+  5.3482   3.7310   5.0957   3.1029   1.6780   3.1184   0.5161  -3.5018  -4.5034  -6.3519  -7.8639  -5.6580  -5.1767  -2.3928   0.1325   3.3098   7.8210  11.9881   4.4190 -14.8118 
+  8.2697   5.8835   6.0215  10.4427  12.0342   7.5709   3.5443  -1.0166  -4.1313  -6.5619  -5.0660  -0.8575   7.1102  -0.6052  -4.0956   0.6756   0.8926  -4.2551  -6.4788 -29.3772 
+  2.0192   3.9566   4.9448   8.0890  14.6263  15.3545  12.2775  10.3302   7.2993  12.5826   7.7803  -2.3944  -7.4949 -10.2984  -9.7837  -7.3581  -7.2692  -6.1954 -16.7366 -31.7295 
+ 12.8428  15.9200  16.2497  11.8540   3.8000  -1.0057  -2.5059  -6.5320  -8.3900  -9.9165  -9.6596  -6.0113   1.0447  13.8469   7.3566  -4.1906 -11.0801  -8.0052   3.2361 -18.8537 
+ 17.2020  18.6360  23.3502  20.5862  15.5823  12.7495   6.4445  -6.6661  -9.1710 -15.5663 -21.8272 -18.4838 -16.7082 -14.2582   2.8891   3.6115  -0.4823  -0.0577   2.5754 -20.4057 
+ 11.2405  16.2045  19.5245  19.0279  10.8160   4.2621   0.0074  -4.8018  -7.7494  -9.5065 -10.8518 -10.4718  -6.2617   1.5892   9.5055   4.0459  -4.2300  -9.8946  -9.4119 -23.0441 
+ 21.5981  16.6548   9.2131   4.2901  -2.7752  -6.0814  -5.7172  -6.8518  -5.3057  -3.6255   1.9348   7.8994  -1.3260  -8.0365 -10.6481  -6.5275  -3.0468   3.5257   5.6627 -10.8371 
+  2.3529   1.9098   1.1705  -1.0129   0.2322  -2.1724  -2.7849  -0.3004   1.1108   2.9625   0.3261  -2.0946   1.0272   3.4696   1.9753   1.1513   2.4885   2.1442   0.7739 -14.7298 
+ -1.7003  -2.4848  -2.4346   4.7038  24.9669  27.0962   7.9463   4.7152   0.1920  -0.8991  -0.8489   9.9068  -2.4800  -9.4907 -11.9321  -1.8570  -6.2441 -11.0862 -11.2891 -16.7804 
+ 14.9206  17.9220  23.4494  28.4771  23.9338  22.5858  21.7793   9.3991  -3.6346 -10.2702 -14.3748 -16.3264 -19.3026 -18.4585 -17.3134 -12.2710 -10.5930 -10.9994  -7.9141 -21.0092 
+ 10.8472   9.9985   8.1012   5.6373   0.7372   0.0745  -0.8638  -1.7933  -2.9142  -3.0150  -2.2427  -0.7782  -2.5201  -6.2197  -5.1933   0.2777  -5.0155   0.2927   4.1108  -9.5213 
+ 11.2774  17.5024  20.7927  14.9512   8.8893   5.3831   1.1126  -0.5407  -1.8226  -0.7548   3.8991  14.1917  11.4189  -2.2812 -13.1711 -17.2396 -15.8893 -13.7806 -15.9376 -28.0009 
+ -1.8142  -1.3801  -0.2831   1.3820   1.7722   1.4623  -1.2023  -3.2113  -5.2345  -6.7523  -4.9565  -2.8637   4.0779  -2.6764   0.8821  14.4958   8.5614   4.5439   7.9060 -14.7091 
+ 10.5077  13.8832  19.5676  20.8530  17.7078  12.7109  11.5269   8.0218   2.2318  -5.7244 -10.1683 -12.8120 -14.9230 -10.7023  -2.0109  -8.3963 -10.2008  -5.4032 -10.7793 -25.8902 
+ -0.2509   1.3469   0.6421   2.6377   6.0659   4.3721   5.3520   3.9824  -1.7069  -2.0895  -5.2191  -1.5370  -3.3737   1.3384   4.0383  10.2321   1.6548  -3.2413  -5.1470 -19.0973 
+  6.4953   9.3365  14.1057  20.6271  16.1168   7.3580   1.4929  -2.7587  -4.0681  -3.9748   1.3672   8.9105  -0.9200  -5.3133   0.3345  -6.1299 -12.7503  -9.3229 -13.4612 -27.4454 
+  0.6201   2.4328   4.9760   9.2545  15.4025  12.2971   5.7680   5.0077   4.0499   4.2155   9.7060   7.7493   5.8274   0.3852  -5.9984 -11.5236  -7.3050 -10.3504 -20.7971 -31.7176 
+ -3.7294  -1.4413  -3.7524  -4.5904  -3.2743   0.7360  -3.2763  -4.8007  -0.6213   4.9030  10.4614  11.0474  17.3494  -0.7763   5.4732   0.7769   1.2498  -0.7639  -2.1070 -22.8638 
+  6.7163   9.2255  12.3187  17.6924  17.6404  11.8940   7.0991   4.2645   4.3021   9.9874   5.8382  -3.4579  -6.9519  -4.8090  -2.1538 -14.0697 -18.7474 -17.3320 -11.2745 -28.1824 
+ 14.7156  19.4663  14.7897   6.5422   1.1728  -2.3524  -4.9286  -7.8168  -8.8525  -9.4747 -10.7274  -8.5129  -4.4565   7.8312   0.0283   4.0451   1.6338  -1.3894   4.4306 -16.1441 
+ 19.0680  22.0875  24.6110  22.0341  17.3706  15.8785  14.1658  11.9508   4.4308  -1.1373  -6.4223 -10.3244 -11.8572 -13.5064 -14.4779 -15.1004 -15.5216 -16.8251 -22.0101 -24.4145 
+  9.0336  19.0176  24.4867  24.6758  18.9461  11.7838   7.6427   4.7750   1.2864   0.4513   1.8155  -1.2592  -9.2086 -14.2929 -15.7555 -13.6408  -7.7748 -14.5157 -21.5902 -25.8770 
+  1.4827   0.2805  -0.3810   1.4732   8.2340   8.1707  10.0600   8.3087   4.1212   2.7249   3.5821   7.9718   3.7426  -2.6511  -5.3909  -4.4519  -4.5293  -6.7232  -8.9602 -27.0648 
+ 10.5705  10.6700  11.7791  12.1925  10.0236   6.6964   5.1163   2.6148   4.7648   2.5521  -3.9125  -7.4628  -9.6721  -9.3307  -9.9466  -8.0895   1.1968  -3.8200  -3.4846 -22.4580 
+  7.5905   8.3863  11.5587  16.2565  22.0088  23.0422  17.8049  13.1018  17.1694  13.5769  -0.2381  -1.8062   1.5806 -10.3901 -20.8106 -24.7914 -25.0524 -24.3552 -19.3769 -25.2554 
+  7.3275  11.6160  16.6781  15.5131   8.1538   4.8147  -1.7134  -2.9599  -6.5688  -7.0695  -0.9248   5.3367  -4.5080  -7.1758  -3.4270  -3.5021  -8.7907  -5.2842   1.7479 -19.2635 
+  8.6994  13.7488  20.2706  15.6056   8.0300   2.7906  -2.4915  -6.3762  -9.0577 -10.4892 -11.7811 -10.7422  -7.7494  -0.3422  10.0858   3.8928   3.9680  -2.0796  -2.0561 -23.9265 
+ -1.8066  -1.3696   1.0493   1.3711   1.9691   1.1999  -1.8646  -1.9643  -1.7749  -1.3390  -3.3717   3.1526   1.2109   0.7990   0.4966   2.5531   3.3704   2.3429   4.9229 -10.9469 
+  4.0689   7.4175  12.6940  18.0600  16.5869   9.3259   4.5282   2.8636   1.6428   4.7328  12.4121   9.1212   6.2302   0.0152 -12.5596 -17.7355 -18.6999 -12.7970 -17.6503 -30.2571 
+  0.8292   2.6495   1.8804   4.1439   5.6667   5.7021   4.9475   6.8868   6.7950   8.0289  10.5666   8.6874   1.8534  -2.2297  -6.3646  -6.7900  -8.1505  -9.3082 -10.0423 -25.7522 
+  7.1022   3.8236   1.8946   4.4230   4.7840   4.6315   5.8219   2.7914   1.6501   0.4344   2.2205   4.0071   0.0326  -2.6285  -2.5436  -3.5874  -3.6688  -4.2155  -7.0087 -19.9643 
+  0.1242  12.2019   4.3084   4.2478   1.9093   0.6288   1.1102   1.5269   2.2918   5.1362   2.1955  -5.7687   1.1936  -1.4469   0.2971  -4.6605   0.8522   1.2017  -3.9848 -23.3647 
+ -5.1159  -1.2775   2.5260   4.1265   3.4097  -1.7194  -0.8844  -1.4795  -5.4958  -6.8537  -1.5398   0.9661  -2.3240  -4.8943   8.2925   3.4432  -1.7853   6.3100  13.4410  -9.1454 
+  3.9898   4.3777   4.2357   3.0453   3.7447   2.5019   1.1011  -0.4780  -2.4003  -0.6497   0.8291   0.2117   0.0985  -0.2133   0.3830  -1.7850  -1.0322  -2.1328  -1.6069 -14.2203 
+ 11.3622  14.7416  16.8859  15.0883   9.9488   8.7692   4.3995  -2.0242  -2.6878  -1.0092   0.7764  -2.2298  -4.0840  -8.1165  -6.2525  -5.2064  -7.0092  -6.7164  -9.2528 -27.3833 
+  3.6579   2.8996   4.0461   8.3701  17.0082  23.3625  16.2578   7.1955  17.3887   6.3999  -4.2883  -9.9015 -12.7556 -12.3388  -5.4680 -10.3674 -10.9476 -10.1432  -6.0175 -24.3585 
+  7.5312   5.8939   4.3265   4.0014   2.9087   1.6542   2.9601   3.9087   1.3700  -2.9778  -0.8059  -0.8752  -0.9920  -0.8125  -0.8336  -0.0306  -2.6451  -2.7999  -4.2986 -17.4834 
+ 15.3876  20.0855  22.6771  20.6277  15.1509   8.8202   3.6289  -2.1904  -8.5688 -13.1818 -15.2549 -15.0083 -12.7233  -8.7307   0.5974   4.3829  -2.2770  -0.0304  -7.8902 -25.5026 
+ 23.6589  23.2539  20.3520  15.1761  11.4144   5.8059   5.4712   1.3160   0.0827  -2.4308  -7.0613  -6.1765  -1.8534   5.6004  -1.4387 -15.4564 -17.3870 -18.8680 -17.3832 -24.0763 
+ 11.6709  14.1123  21.1753  25.8068  20.7082  14.0630  14.1588  17.9220  14.6153   4.8179   3.3194   0.4690 -11.4997 -19.1991 -21.5666 -21.4213 -21.1902 -22.3547 -22.1566 -23.4508 
+  4.6799   3.0606   1.6539   6.2007  -2.0201   3.0954   0.5569   3.2707   1.3312   0.0725   1.8286  -5.9667   2.6570  -0.0978  -1.2174  -2.2597   0.2234   1.4765  -4.2077 -14.3379 
+  9.3104  11.8578  14.9832  13.1906   8.5578   4.2616  -0.4942  -3.0677  -3.2171  -5.1322  -1.7298   6.6384  -0.8475  -8.0712  -9.5863  -5.8386   2.6610  -8.3104  -6.0285 -19.1373 
+  2.2896   3.8587   4.9224   8.6357  13.9236  17.8222  15.7427  11.5211   7.5272   9.1679   9.7247   5.7451   0.5275   0.3504  -6.2281 -12.9212 -14.0843 -20.5964 -26.6432 -31.2855 
+ 18.9039  18.0327  13.6297   9.7561   7.4319   5.3744   2.9646   1.7415   0.6716   0.6859   2.7446   0.5342  -4.3187  -6.1877  -6.9311  -9.8734 -11.9041  -9.1281  -8.9591 -25.1690 
+  6.4513   6.7843   9.4438  12.9549  16.4801  14.9093   8.2954   1.6877  -2.5193  -4.4922  -6.7348  -6.9853  -4.6783   0.7181   1.0483  -5.1128  -1.1161  -7.5305 -12.3980 -27.2058 
diff --git a/codec2/branches/0.7/src/codebook/train_120_2.txt b/codec2/branches/0.7/src/codebook/train_120_2.txt
new file mode 100644 (file)
index 0000000..1ca0059
--- /dev/null
@@ -0,0 +1,513 @@
+20 512
+ -1.2668  -1.2477  -0.0681   3.8419  -0.0693  -1.7919  -1.5943   0.8402   0.1550  -3.1526  -3.0204   0.7337  -0.2603   1.6590   0.0230   5.5893  -2.4959   1.9604  -0.6348   0.7999 
+  2.6673   1.4923   1.1408  -0.7478  -1.0755  -1.3421  -0.4884   0.2535   0.2951   1.5088   1.9447  -2.6620   2.3751   1.5298   4.1357  -6.5630  -2.1766  -2.7535  -0.7706   1.2362 
+ -0.6415  -0.4348  -1.2178  -0.9870  -1.1057  -2.1421  -2.3594  -0.4977  -4.1484  -4.7120   5.5425   3.0695   3.6610   2.9729   2.4379  -1.6136  -1.3052   2.1342   1.9164  -0.5692 
+  1.5930  -1.1175  -1.2476   1.6203   2.5315   2.3427  -0.5223  -3.1063  -2.1739  -1.4774  -2.6108  -3.5842  -0.3828  -0.1511   0.8929   2.5717  -1.7657   1.8954   6.0193  -1.3272 
+ -0.2102  -0.3681  -1.2724  -1.1520  -0.3715  -0.5633  -2.5238  -1.7680   4.7356   5.6452   0.8620   0.8750  -0.8932  -1.5918  -1.4047  -0.0720  -0.6080  -0.7876   1.3972   0.0717 
+  5.1178  -1.5391  -4.2881  -1.9745   1.3515   2.4014   0.9329   3.4647  -2.4062  -0.4224   2.8708  -1.6053  -3.1492  -2.6783  -2.6937  -4.4645   1.8599  -0.5456   3.8910   3.8770 
+ -1.7119  -1.0101  -0.5002  -1.7849  -0.4884   0.2279  -0.8335  -1.0083  -1.2819   0.1129  -1.3674  -1.3338   0.9290   3.0765   2.6339   3.5627  -2.2713   0.6565  -1.2099   3.6022 
+ -1.5938  -1.3264   0.9856   2.8765   2.3700   1.2528   1.2586  -1.2453  -1.3974  -1.4988  -1.6309  -1.2183  -0.1625  -0.8690   0.0030  -2.0081   1.3580   2.9585   3.3396  -3.4520 
+ -1.3680  -0.6304  -2.5755  -1.2397   4.9487   2.7251   1.4675  -0.1832  -0.3932   1.4723   1.7410   0.6216  -1.0849  -0.7112  -0.3751  -1.7539   0.1222   1.9858  -0.5248  -4.2444 
+ -1.2786  -0.2384   0.6718   2.9763  -1.6959   6.4607  -3.9459  -2.0560  -2.7306  -0.2583   0.0389  -3.6271  -4.0721   0.8260   0.8112   2.8769   2.2400   0.5444   0.3571   2.0995 
+  2.5196   2.3359   1.6620   0.6250  -1.0528  -0.9133   1.8668   1.2853   1.4368   1.4676   1.1301   1.3664   1.1076  -3.2853  -0.4530   0.4467  -4.7302  -3.8149  -3.9866   0.9865 
+  0.1738   1.2940   1.3514  -0.3684  -0.7078  -0.2329   1.3467  -1.0678  -0.0262   0.2448  -0.8418  -0.3910   2.7415   2.9948  -4.5965  -0.1192   0.2496   0.4684   0.0669  -2.5805 
+  0.2482  -1.3236  -1.4810   0.9433   3.4287   2.2233   8.9344  -1.1138   0.4585  -3.7470   3.0416  -2.7394   2.2880   1.6598  -3.6439   0.0633  -2.7363  -1.2617  -3.1924  -2.0500 
+  1.4672  -1.3248  -0.5511   1.4512  -0.4710  -1.2381   2.9453  -2.3244   2.3249  -2.1969   0.9414  -1.9926   0.5254   0.0792  -3.2076  -2.4140   3.5291   3.5738  -0.0613  -1.0556 
+  1.5560   0.0091   0.0770   2.8542  -1.4594  -2.0102   0.5440   2.8119  -0.2925  -0.7111   0.9589  -1.6923  -1.8606   1.1040  -1.6733  -0.0895   3.6894   2.7628  -6.9922   0.4138 
+ -1.5539   0.6820   1.4458   0.4297  -0.4115  -1.3266   0.5024  -0.6975  -0.3820   1.2840   0.9597  -1.0561   2.2198   0.1292   1.4343   3.0313  -3.9845   0.6776   0.3380  -3.7217 
+ -2.0283  -1.5216   1.0103   4.8788   3.7028   4.4000  -0.3076   2.4853   2.2296  -1.5213   0.4360  -5.9903  -2.6578  -2.3985  -2.0127   1.3737  -3.7950   2.3105  -0.2099  -0.3839 
+ -1.7339  -0.9861  -0.2078  -1.2579   2.5808  -0.9255   3.2388   1.0999   3.6754   4.6424   1.9111   1.4716   2.7531  -0.2725  -0.3573  -0.5392  -4.2109  -6.4662  -2.3713  -2.0442 
+  0.7177   1.4094   0.7205   6.8683   1.7836   7.1562  -2.9368   3.4036  -0.6064   2.3377   2.8714  -7.0408  -9.7129   4.1278  -3.4444  -5.9919   5.5073  -0.8996  -7.5142   1.2434 
+  0.8042   1.5886   0.8754  -0.4378   0.2336   0.0424  -0.1245   0.0847   0.6402   2.6508   1.6375  -3.2393  -2.2823  -2.1435  -1.5628   0.4271   2.2571   2.5048  -1.5933  -2.3629 
+  0.6292   1.1956   0.8357  -0.8634  -0.1796   1.8589   0.6940   2.8309   2.5569  -0.4253   0.2913   0.7772   1.4180   3.4210  -1.9468   4.2236  -7.3361  -3.7802  -3.5980  -2.6029 
+  1.9034  -0.7126  -2.3343   0.2344   3.6545   3.9405   3.0203   0.1937  -1.1906  -1.9012  -0.6667  -1.2590  -1.1021  -2.6650   0.1400  -1.4183  -1.2342   0.0547   0.1519   1.1906 
+ -3.6125  -2.2485  -1.0820  -1.9912  -1.1521  -2.2527  -2.5383   0.9320   1.1572   2.0230   1.6579   1.3763   6.4432   2.1652  -2.0259   1.9724   3.2824  -0.4615  -1.1909  -2.4539 
+ -1.1530  -2.1790  -0.7355  -2.0941   0.6246   1.7502  -3.3266  -3.4374  -2.6486  -2.2938   0.9286   1.3396  -2.1323   0.2739   1.2664   4.4111   1.3864   3.9050   2.8286   1.2861 
+ -1.9752   0.7423   2.4137   1.8854  -1.1393  -2.5802  -2.9355  -3.6740  -1.8244   0.3099   6.1403   4.6215  -2.0636  -3.7172  -0.9400   1.4240  -0.3669   2.0205   0.6217   1.0369 
+ -0.1561   3.9621  -1.3649   0.2912   3.5366   0.8537  -0.9376  -3.7333  -6.5447  -1.2107   3.3183   2.5758   1.9693  -4.8690   0.6212   0.0985   1.5746   0.2433  -2.6173   2.3890 
+  0.6849  -1.1521  -2.0382  -0.8953   0.8771   1.1996  -0.9704  -1.3679  -1.1460   0.0582   0.2636  -1.9785   0.5235   1.6427   0.6362   0.7411   5.6052  -0.3533   0.6579  -2.9883 
+  0.5989  -3.9928  -2.1937   3.8742   2.0056   2.3132  -0.4478  -2.0855  -4.3607  -2.1260   5.3544   1.9827   5.3407  -0.8346  -2.4624   1.1729  -4.3825   0.7623  -1.9429   1.4240 
+ -3.3103   0.0394   2.0113   2.6733   1.2484  -0.2186   0.1156  -0.4856   2.4501   0.8179  -1.1164  -2.1952  -0.9719   2.0728   0.4002   1.1891   1.7518  -1.2571  -3.3136  -1.9012 
+  1.8860   6.9767   2.4311  -2.0414   3.9100   5.5378  -1.7478  -0.8304   2.8523  -1.4075   0.1309   1.8232  -2.8868  -7.5003  -3.4867  -3.2756  -2.8584   6.2611  -7.4682   1.6940 
+  3.5074   1.3392   1.0862   2.9814   0.8158  -2.6160  -2.3837  -0.8255  -0.1595   2.0087  -2.8876  -2.4727  -1.3574  -1.2864  -1.5711  -1.0772   0.4648   2.7262   2.1044  -0.3970 
+ -0.1430  -0.9788  -2.1195  -0.7774   4.0804   3.7123   1.5082   0.2869  -2.5968  -2.0127   1.5147   3.7486   3.2447   0.6959   0.3308  -2.4516  -3.4598  -4.1669  -0.6870   0.2709 
+  0.0724   0.3235  -1.9536  -2.7454  -3.3392  -1.9023  -1.0150   0.7511  -0.0539  -2.8386   5.2737   5.1053   1.4372   1.4046   1.4504   2.4912  -2.6526  -0.6188  -0.6530  -0.5369 
+ -6.9550   1.3233   4.3542   2.9502   0.9929  -0.1186  -0.8657  -2.3452   3.5061   2.8348  -4.1741  -4.1264   4.6970   3.0117  -0.2849  -8.0081   3.4452   0.7819  -2.7443   1.7251 
+ -4.0878  -0.8849  -4.7521   5.0067  -3.3510  -4.8233  -6.6328   4.8752  -0.7474   3.8614   2.6271   0.9119   1.0371   2.2968   4.3160  -3.7042   0.9900   0.4960   4.7952  -2.2300 
+  0.5901   2.0654   1.7824  -0.5570   0.4874   2.7659   0.8232  -0.1306  -0.6795  -1.3143  -1.2480   0.9969   2.0563   0.1625   0.7346   0.0223  -1.6836  -2.9087  -4.1058   0.1406 
+ -0.5074  -0.8373  -0.8579  -0.0460  -0.0854  -1.4221  -0.6935   2.5302   2.2014   2.2225   0.5896   1.2715  -0.7624  -2.7997  -5.3296   4.0372   3.2176  -1.4146  -1.3705   0.0565 
+ -3.8190  -1.1051   1.5169  -0.5542  -1.5591   0.2921  -2.1144   1.6664   2.8275   0.7745   2.6977   4.4021  -0.2010   0.0685   1.3158  -0.8045  -5.9834   1.7874  -2.1592   0.9509 
+  0.6749  -0.0635   0.3751   0.6561   0.4718  -2.3144  -4.9191  -3.0907   0.5499  -0.3498   1.2370   2.6699   1.5353   1.6809   1.2117  -1.3733   0.0977   1.3610   0.0102  -0.4207 
+  0.8139  -2.9454  -1.1694   1.1826   3.5742   4.3331   1.4143   1.7017  -1.2428   4.8459  -4.4642  -0.0684  -1.7273  -0.1932  -2.6041  -1.4272   0.2873  -0.9676  -0.1422  -1.2013 
+ -1.8690   1.2475  -2.8884  -0.3842  -0.3588   2.7759  -2.0060  -2.2023  -2.6599  -2.5791  -3.1221   3.2645   1.8131   2.8630   6.3144  -4.2619   0.7589  -0.7608   4.8657  -0.8104 
+  2.3449   0.3057  -2.2411  -1.3084   0.6572  -0.3790   0.2674   0.5337   0.4996   0.8832   2.3616   3.9339   4.7846  -2.7473  -0.5167  -0.0864   0.9288  -4.3018  -4.0903  -1.8294 
+  2.9658   2.7467  -1.9276  -4.0009  -0.7257  -0.6616  -2.0255  -1.2898   0.3022   1.5810   3.0521   2.5790  -3.2369  -0.4791   0.4455   0.1138   1.1032   0.9003  -1.5708   0.1285 
+  5.2204  -2.8190   0.8203   0.5992  -1.3205  -2.1549   5.0256  -1.6050   0.5506  -2.8092  -0.2831  -1.6376  -1.8233  -0.0177   2.5319   2.0586   0.9166  -1.5417  -0.3071  -1.4039 
+  0.1090  -0.1359  -0.4821  -0.5060  -1.1903  -0.1205   1.3010   0.0989   0.2280   1.3298   1.4648   0.7280   0.0076  -1.4837  -0.1633   1.2525   0.9437  -0.0019  -3.9783   0.5988 
+ -4.0941  -3.4220   0.4966  -5.4678   6.0636   1.1749  -0.1830   3.3518   3.5480   1.4243   2.5791  -5.9065  -1.8723  -1.6703   1.3990   6.8845   1.8643  -1.2344  -3.7475  -1.1880 
+  3.5819   1.2282  -0.2187  -0.8194  -0.0683   0.6784   0.9405  -0.1871  -1.0635  -2.3089  -1.7476  -2.3377  -1.8039  -0.2123   0.7402   0.8810   0.7063  -3.8015   4.2698   1.5426 
+ -0.7508  -2.5319  -1.4606   1.0638  -3.8848   1.2060   2.6878  -1.2315  -0.1629  -2.2730  -3.3361  -1.6208   1.9855   3.4308  -0.2120  -1.4559  -0.3738   2.3568   2.3629   4.2004 
+  1.5564   1.6137   1.4225   1.6668   1.3266   0.0460   0.1831  -0.3664  -1.4348   2.5690   2.2918   1.6955   1.6680  -1.3807  -1.0884  -1.0980  -0.5844  -1.0295  -3.6955  -5.3616 
+  1.7128  -1.8066  -4.0653  -3.8214  -0.9531   3.4797   0.7961  -2.4955  -2.7851   0.0025   0.7872   1.0652   1.5456  -0.4352   1.9173   4.6258   0.3691  -0.1501  -0.2351   0.4458 
+ -1.6777  -3.1299  -1.6947  -1.1535  -2.1999  -3.2226  -0.9846  -2.1533  -0.6467   2.0938   2.1307   2.9065   1.5181   3.0875   0.0486  -0.2157   1.3461   0.7741   2.7320   0.4413 
+ -2.0098  -0.0651  -1.1313  -3.1454  -1.8173   0.4664   2.3278   3.1806  -3.0726  -1.5969   3.6994   0.6478  -0.6833   1.0635   1.1405   6.7102  -4.8934  -4.2029   3.4752  -0.0933 
+  3.0911   3.1320   3.6764   1.2247   2.0977  -0.4399  -3.9470   1.4276  -0.2596   0.5511  -6.4999  -0.9385   3.2215   1.7397  -2.0786  -2.6160  -3.0150  -2.0586   1.9218  -0.2304 
+  0.5955  -0.9572  -3.8115  -1.2133   0.9600   3.0247   8.6360   5.7851   6.1244   0.7094  -2.4410  -1.1712  -1.7901  -3.5399  -2.8318  -2.5468  -4.9596  -0.6022   0.6141  -0.5845 
+ 12.5835   1.8094   0.1352   1.7718   0.9427  -1.3690   7.1277   0.0421  -2.3404  -4.6650   1.4653  -2.4880   2.6056 -10.3828  -8.1067   4.1108  -1.2481  -1.8330  -2.7827   2.6214 
+  2.9658  -0.2617   0.2806  -0.2164   2.8550   1.9755  -3.5301  -1.2350   0.9311   0.8713  -2.2265  -0.6005   2.6386   2.7666  -2.3603  -2.5163   1.6854   1.0161  -7.8883   2.8489 
+ -0.9445   0.6006  -1.3214  -5.0651  -2.1702  -0.0289   0.1003   2.2883   0.0424   3.4686   2.0494   1.6327  -1.6152   0.1220  -2.8666  -2.2261   4.9579  -2.2581  -2.7323   5.9663 
+ -1.3666  -0.2364  -0.3999  -0.9988  -2.0227  -0.0610  -0.5411  -2.2113  -0.2283  -1.7150   1.0239   4.2760   1.9603  -3.0526  -2.5894   0.8611   5.2528   3.4951  -2.2336   0.7875 
+  4.7609   3.7023   0.7955  -3.1291  -1.3671   0.8798  -0.9947   0.2668   0.5762  -0.9479  -4.5541  -0.6922   0.0699  -5.8412   4.2302   5.0652   1.3544  -2.4661  -0.6224  -1.0865 
+ -2.6815  -0.9958   1.6109  -1.7618  -2.5561   1.0357  -1.5863  -2.2811   3.4491   1.1806  -0.2855  -0.1380  -0.0202   5.6861   0.8289  -1.0913   0.5986  -1.1493   3.2455  -3.0884 
+  1.7353   3.1908   5.0898  -0.4602   0.0751  -2.1427  -5.0910  -3.1667  -3.3291   1.9531   0.4802  -4.8101   2.2518   2.4380   0.6439  -7.3548  -0.0689   1.8997   5.7170   0.9491 
+ -1.1588  -3.1119  -3.4525   0.2538   1.3345  -1.0500  -0.3870  -0.0472   0.1522   4.0806   2.8886   3.8741  -1.9507  -2.9183  -0.3828  -0.0805   0.4136   1.1466  -3.1863   3.5818 
+ -4.1654  -5.7362  -5.0041  -0.9889   4.1884   4.8135   1.5658  -2.3781   0.8425   7.5151   7.3977   3.9243   0.6283   0.9194  -5.0741  -1.9566   0.2100  -4.9786   0.8760  -2.5989 
+ -5.3114   2.2992  -1.9803   1.2150   9.1545  -2.1960  -2.8749   9.6686   0.5512  -4.1700  -1.1338  -4.1549   1.6645  -3.1643  -1.7800   4.9896   0.3390  -0.0421  -1.0391  -2.0347 
+  1.0740   2.1840   0.9247   2.0617  -2.1994  -4.0653  -1.5118  -0.9397   1.3781   2.9104  -0.8864   8.5382   0.5495  -3.5922  -0.2482  -0.5485  -0.9604  -1.8453  -3.1808   0.3575 
+  3.5141   2.7621   1.2101  -0.3665  -1.1827  -0.5351   0.4822   0.7598   0.8241   1.4976  -0.8943  -2.8067  -2.3512  -2.0448   0.3706  -0.9201  -3.9192   1.1431   0.4761   1.9809 
+ -1.7817   1.1939  -1.2195   1.7524  -4.7374   1.1520   0.0973   1.5475   2.2848  -7.7870   2.0346   0.5213   2.8861   3.1077   1.1974   2.3936  -1.4248  -0.2888  -1.4706  -1.4588 
+ -0.7677  -2.0426  -2.9918  -1.8722  -1.4336   0.4207   1.4107   1.0509  -0.1714   0.2221   1.3054   0.5884   3.1454   1.8747   0.1510  -0.5701   0.5457   2.7058  -0.0854  -3.4859 
+  1.6593   1.0024   0.3202   1.0267  -0.2368   0.1208  -0.7272  -1.0487   0.2686  -1.0197  -1.3131   4.1829   1.0297   1.7779  -3.0898  -0.7777  -4.5532   2.1765  -0.3100  -0.4886 
+  2.9341  -0.2895  -2.4210   0.9438   2.9490   1.2447  -0.4279  -0.4133  -0.2487   0.6464   0.1859  -0.8613   0.0690  -2.0024  -3.5783  -0.9123  -2.3469   0.3089   5.3909  -1.1710 
+ 13.8818   0.6217  -0.6459  -3.4218   0.8331   0.8918   2.2009   4.0596  -3.0380  -7.3862  -3.2105  -2.2108   4.7972  -5.3735   3.8870  -1.8190  -0.5123   0.9752  -3.6921  -0.8383 
+  0.2536 -11.0226   4.4625  -7.9396   8.6657   2.6088  -1.0215   0.4492  -5.0641   2.7194   1.1735   2.2070   3.3733  -0.2605   5.5319   3.5989   0.2759  -3.6185  -2.9338  -3.4591 
+ -0.2533  -1.2245  -1.1924  -0.1962   0.6099  -2.1289  -2.0002  -2.0390  -1.5592   0.7879   0.1165  -0.9325  -1.5485   0.4552   0.3883   1.9054   2.3495   3.9138   2.3594   0.1886 
+  0.1750   3.7528   1.6899  -4.3270  -5.0437  -3.1410  -4.7768  -1.9628  -4.5893   5.9435  -9.6773  -0.4601   3.0571   1.2797   0.1161   3.5574   3.7157  -2.0222   5.9308   6.7823 
+ -0.6999  -2.9933  -3.6606  -0.6207  -1.4032  -1.1364   0.2530  -0.9004  -2.7685  -4.3142  -0.7561   0.8142  -0.4715   0.8444   2.0053   0.5983   3.3363   4.4913   6.9146   0.4673 
+  1.0959  -0.0886   0.2379   3.2725   1.2016  -1.1581  -1.3640  -0.6268  -0.3678   0.9051   0.7593  -2.2902  -1.4578   0.6349   0.5115  -4.4984   2.2315   2.2535  -2.7867   1.5345 
+  3.6055   3.8842   2.1794  -0.7568  -1.0500  -2.1686  -0.6731  -2.0718   0.8001  -0.6819   1.1112   0.5707  -2.4862   3.1489   2.6767   2.5134  -1.9147  -4.1519  -2.4548  -2.0802 
+ -1.9388  -0.7447  -0.8349   0.1123   0.1251  -1.3476  -2.6413  -0.4770   5.6864  -1.8563  -3.3514  -0.5309  -1.6295  -1.3453  -0.4664   4.5930   1.1909   2.9264   0.9356   1.5944 
+  0.5951  -0.4177  -0.1304   0.5462  -1.3265   1.4534   1.6425   0.9730   0.8946   2.1586   4.2557   0.8968  -5.0524  -1.9576   2.6089   0.6571   0.7918  -2.2504  -4.5907  -1.7480 
+ -1.6456  -2.0706  -2.4462  -2.5983  -2.5056   2.0863  -0.9159  -0.8806  -0.8052  -0.7776   1.0285   0.4522   1.5131   3.4530   4.9330  -2.7752   1.7750   2.1982  -0.0181  -0.0006 
+  2.2117   0.6658  -0.1647  -0.7769  -0.3291  -0.0686   3.1830   1.8603   1.0488  -0.7866  -1.0352   1.6465   0.2395   0.3989  -1.2496  -1.9498  -2.6996  -7.5216   1.3320   3.9951 
+  1.0405   1.3681   2.7153   3.0279   2.8206   1.9933  -1.5434  -2.0223  -1.0490  -1.2756  -0.1434   0.2554   0.8858   1.3178   0.3714   3.5670  -3.1912  -1.0147  -3.0243  -6.0993 
+ -0.8348  -2.4017  -3.6731  -2.0399  -0.2474  -1.0640  -1.1488   1.3352   2.8367   5.1498  -0.0673   1.7148   2.0672   0.7800  -2.8302   2.8981  -0.7525   1.3119  -2.4119  -0.6222 
+  3.0927   2.0509   2.4548  -1.3001  -3.9942  -0.7486   2.8523   0.1569  -4.3404 -10.5627   4.2087   4.2968   2.7013  -1.1646   0.2008  -2.4272   1.8708   0.5192  -2.3092   2.4416 
+  0.6449  -3.5216  -3.8362   2.1329  -1.2999   0.6434  -2.5079   3.1409  -0.9430   2.1409  -0.9005   2.6639   5.8420   2.2508  -0.1834  -3.5407  -2.0329  -1.9827  -0.2675   1.5565 
+  5.1512   4.1361   0.9497  -3.1897  -6.0608  -4.8346  -0.7128  -2.1849  -2.1809   0.1265   0.3295   0.2665   1.1233  -0.4722   2.7945   1.1909   0.4093   1.9529   0.6380   0.5674 
+ -2.0255   1.8944   3.2610  -0.6543  -0.1603   1.6419   1.8339  -4.1284  -1.6495  -7.4417   2.7611   3.0349  -5.4696   5.3754   0.2729   5.1700   0.7296  -0.1265  -1.6533  -2.6659 
+ -7.1882  -6.8851  -0.9549   2.6573   1.6288  -0.3149  -2.2361   1.6706   4.0565   3.2723  -2.0478  -0.6505   2.7769   4.9536   1.8310  -4.1026  -0.8540   2.2409   0.8671  -0.7209 
+  0.8703   1.1461   2.9551   0.5102   0.4539   9.1307  -3.4339  -1.5513  -2.2902  -4.1038  -6.0580  -0.8757   3.5830   2.5081  -1.9449   0.3605   0.8645   0.6768  -0.2206  -2.5809 
+ -4.5091  -1.0618   1.6342   0.5890   1.0199   0.7070  -0.4636  -0.7393  -2.0902  -4.3948  -1.8491   2.8967   1.9263   0.6394   4.9955   3.9485  -0.2145  -1.3652  -1.4955  -0.1736 
+ -1.2527  -0.6868   0.0359   0.5854   0.7286  -0.5988  -1.0892  -1.2358  -0.5524  -1.8766  -4.8554   1.3154   3.0969   1.2141   0.4785   0.5435   0.9660   0.9526   2.5969  -0.3662 
+ -3.4429  -2.5359  -0.7902   1.6794   1.3950   0.9304   0.5281   2.0451  -0.2820  -0.7620  -2.3113  -2.5279  -1.2407  -4.6199   3.9276  -1.3637   2.0692   2.0266   2.4150   2.8601 
+ -0.0841  -1.4504  -2.5295  -2.1914   0.0160  -1.5806  -3.8581  -1.8751   1.2410   1.4792  -0.0268  -3.0304   1.1672   3.1034  -0.0043  -1.7750   1.0722   5.8103   3.7335   0.7830 
+ -1.2601  -0.9248  -0.9753  -1.1580  -0.4657   0.9286   0.4457  -0.7164   2.9298   6.0232   1.1288  -9.2201  -2.6002   1.0866   3.5907  -0.3994  -0.8783  -0.4493   3.0463  -0.1320 
+ -2.6865  -1.7683   0.5719   4.2697   0.4434   0.9403  -0.1787  -3.9995  -1.4954  -2.9666   0.5871   0.7458  -0.5643  -3.3758   2.4009   1.3630   3.2345   2.9305   0.6423  -1.0943 
+  0.2605  -0.1269   0.1894   0.8801   5.6065   4.4842  -0.3360   1.6337  -1.0080   2.2349  -1.3371  -3.4195  -1.5849   3.4658  -2.7632  -2.8878   0.2535  -1.0857  -3.4858  -0.9736 
+  0.5903  -1.1309  -3.8731  -2.8181   0.6957  -2.1930  -3.7976  -0.1684   0.3131   0.8609   0.0568  -0.1356   5.9915   2.3704   3.9840   0.5840  -1.9366  -2.6479   0.4937   2.7608 
+ -1.4917   0.6707  -1.8279   0.4736  -4.3226   7.6508  -0.6770  -1.0388   1.6577   3.4357   2.1210  -1.6783  -1.9394  -0.4857   0.0446  -2.1769  -1.5641   1.5895   1.4750  -1.9161 
+ -2.4617  -1.4865   0.9268   3.7356   1.9298  -1.0879  -0.9003  -0.6573  -0.4536   1.1463   2.5279  -0.9025  -2.1547   0.5579  -1.4546  -2.5618  -1.1020   1.7633   4.9058  -2.2707 
+  3.2436   2.0698   1.3674  -1.4618  -0.4269   1.2764   0.3160   1.2237   0.7208   1.5117   1.4584  -0.5527  -0.7757  -2.7217  -4.0792   1.8261   2.7197  -3.9546  -1.7508  -2.0101 
+  0.2659   1.9357   0.5705  -1.8509  -5.0017  -3.7512  -2.7574   0.2996  -1.1250   0.6895   2.7521   3.7090   3.4556   6.5334  -3.5389  -3.8970  -2.9436   0.7650   1.5177   2.3717 
+ -1.2532  -0.7651  -0.7634  -1.6900  -2.3167  -1.0574   0.9291  -0.7963  -1.4770  -1.6646   0.5558   0.7009   3.4059   9.2719   1.4172   2.4588  -0.7901  -3.7873  -1.0613  -1.3173 
+  3.2264   0.6063  -2.4159  -3.8529  -1.9936   2.6889   2.5115   0.8341   0.8209   1.2008   0.7255  -2.1489  -1.1543  -0.6443   2.0479  -0.7011  -0.5619  -0.0820   0.5538  -1.6613 
+  0.8900   0.2673   1.2328  -0.1459   2.5186   2.3429  -0.5461  -0.5497   1.9452   5.1637   1.5156  -3.9805  -1.5621  -1.5331  -2.7711  -2.2357   0.7958  -1.6083  -2.3152   0.5758 
+  4.0233   3.7838   3.0862   2.4680  -0.8644  -2.4804  -0.9694  -1.9035  -3.4966  -3.9590  -3.9724  -1.2080  -1.6237   0.7915   0.4354   0.8419   1.1287   1.8538   2.3476  -0.2827 
+ -0.5315   1.6742   2.6296  -0.5391  -1.8812   2.7171   6.8646   3.9934  -2.0577  -0.8537  -4.3316  -2.4473  -2.8864  -0.3456  -1.9169  -1.4494   0.4578   1.9608  -0.1673  -0.8898 
+ -2.1559  -2.4800  -1.5001   1.3457   3.3362   2.6367   1.4331   2.3397   3.7557   3.4063   1.6588   1.2723  -0.3658   0.5614  -2.5827  -5.6096  -3.4952  -4.1966  -1.5564   2.1965 
+  0.1567  -1.6324  -1.8735  -2.1011   0.8687   2.8596   1.0227   5.0782  -3.8186  -0.4012  -1.0627  -1.0858   2.3105   2.5822  -1.0014  -0.6915   1.2628   0.1273  -4.3120   1.7113 
+  0.5493   0.1877  -0.3065   0.0805   0.1700  -0.4682  -0.7192   0.7521   1.1935  -1.2445   0.5061   3.0407   3.3122   2.9044   2.0613  -2.6946  -2.8479  -1.4855  -3.4536  -1.5377 
+  1.2611   1.2112  -0.4954   1.5849   2.8817   0.5597  -3.2189  -1.8993  -2.3996   0.0235  -0.9270  -1.1263  -1.6443  -3.5163  -1.2543   1.8410   4.5628   1.0754  -0.1607   1.6406 
+ -0.8759  -1.6975   0.2532   6.4042  -3.4246  -2.9858   1.9661  -3.2513  -4.0109  -0.5134   2.5545  -3.0437  -2.1093  -3.6915   4.1398   6.0036  -1.3456   1.3628  -1.0285   5.2940 
+  8.8405  -7.2360   2.8239   7.1563  -1.4248  -8.0410  -1.9196   1.8187  -0.9320  -3.1134   1.9133   4.5783   5.5866  -1.7440  -0.1615  -9.2039   4.4457  -2.5424   2.5822  -3.4268 
+ -1.9594  -0.1440  -0.0014  -0.5248  -1.2740   1.9184   0.2637   0.9658   3.9879  -1.7646   0.8739   3.6824  -1.4748  -0.5493   4.1940  -0.5892   0.9704  -2.3393  -5.2036  -1.0319 
+ -1.8153  -0.8777  -1.3975  -2.8688  -1.3150   0.6005   2.0795   2.0158  -0.0187   2.3273   5.2446   3.1910   0.5420  -1.0394   1.3294  -4.6550  -1.5318  -1.6999   0.2573  -0.3684 
+  4.3069   1.2137  -1.8464  -3.0026  -0.9539   3.1554   3.4215   2.0922   0.4828   1.6102   1.1857   1.5577  -1.8593  -2.9907  -3.0640  -4.6355  -1.6614   1.3592   1.5116  -1.8833 
+  0.6407   1.1519   1.5429  -0.7369  -1.7269  -1.6671  -0.1290  -0.7049   0.8116  -1.2198  -4.0157  -5.1437  -3.1965   2.3418   0.7111   2.6992   0.5585   1.9829   4.9644   1.1355 
+  0.6364   2.1072   0.9870  -5.1572  -4.3363  -1.0839  -1.3521   1.8709   0.8132  -0.2938  -0.2079  -2.5242  -0.8999   2.3401   0.7392   3.1549   3.0568  -1.1375   0.0963   1.1908 
+ -0.0136  -2.4241  -0.4209   1.6339   3.4114   3.5889  -1.4100  -3.5651   3.1831   2.0426   0.5548  -2.0177   1.6429  -3.2634   1.5780  -4.1305  -0.9389   0.1651   0.4588  -0.0751 
+  2.0687   0.8544  -0.3821  -0.1978   1.0057   2.3289   3.0174  -0.3330   2.0178  -0.6679  -0.1993  -1.9170   1.6018  -0.3834   0.6526   1.9588   0.3355  -2.0462  -4.1767  -5.5379 
+  2.7809   0.2282   0.4820   1.9051  -1.7350  -3.4716  -3.3685  -1.3005   0.1251  -1.5366  -1.9516  -2.1469   1.2541   3.7123   3.0390   0.8154   2.3154   2.5014   0.0685  -3.7166 
+ -2.7442  -0.5589   1.8753   0.2528  -1.7122  -1.5279   0.3471   1.3429  -0.0809  -1.0979  -0.5556   2.8899   0.2864   2.1800   1.7006  -3.4442  -2.6681   2.9174   1.9107  -1.3132 
+  1.1471  -0.3191  -2.5131  -2.6788   2.7236   4.0318   2.9420   3.1336   1.5351   0.4800  -0.0086  -1.0945  -1.1975  -0.4758   0.1588  -0.4970  -0.2437  -3.5219  -3.3061  -0.2958 
+ -0.6947  -3.5085  -2.7613   0.0475   0.2365  -2.4104  -0.4597  -0.9262  -0.2261   1.8983   0.9162   0.3544  -1.0767   2.3229   2.3748  -1.6417   3.4712  -3.6716   0.1472   5.6077 
+ -1.7531  -0.9915  -0.4352   0.4089   0.1890  -1.7111  -0.6401  -0.9353  -0.5743   0.3365  -0.6869   0.9392   0.8776  -0.2201   0.7815  -1.7487  -0.2509   3.0732   0.2971   3.0442 
+ -6.4696  -1.5332   1.3136   7.9582   4.7035   0.4178  -1.4784  -2.4577  -0.6662  -2.4183  -3.1348  -2.0591  -4.3423  -0.2080   1.5975  -2.6953   0.1211   4.7779   4.5315   2.0419 
+  0.8642   3.0824   1.7461  -0.8529   0.9231  -0.3502  -2.7586  -2.7081  -1.4853   1.1577   2.4953  -2.0279   3.1643  -1.1352   0.2786  -0.1650   2.4230  -0.5282  -0.4006  -3.7227 
+ -3.9091   0.2639  -0.0395  -5.0339   1.4635   7.9381  -1.8279  -7.5321   1.8947   0.9696  -7.1991   7.7502   4.8838  -5.2722   5.2271   6.4012  -8.2785  -5.8271   0.4487   7.6786 
+ -0.4051   0.3015  -0.5211  -1.1563  -1.5548  -0.8506  -1.7742  -0.6679   0.3853   3.9695   3.1450  -3.5632  -0.3392  -3.3757   1.3514   4.4934  -1.2754  -0.4248   1.0022   1.2601 
+ -3.0667   3.2388   3.6288  -0.3263  -3.6989  -4.3941  -3.0073  -2.9882  -2.7834  -3.8873   2.3701   6.1068   1.0432  -2.8444   0.1460  -2.5272   1.8208   2.6818   7.7176   0.7699 
+ -0.8674   0.6588  -0.0766   1.9350   3.3452   2.7012   0.4707  -0.8282  -0.7703  -3.8252  -2.8814  -0.2389  -1.3895  -0.9376   0.2572  -3.4418  -2.3763  -1.8695   7.4789   2.6558 
+  0.8567   1.9741   0.6363   2.1993   1.9072   2.2211   3.7376  -0.0455   1.3289  -1.0736  -4.8817  -4.0284   2.4624   1.0596  -3.8101  -3.8498   0.8895  -0.5176  -2.3743   1.3083 
+  3.7465   3.5865   0.1979   0.4072  -1.1714  -1.4598  -2.1688  -1.4971  -1.1953  -2.8028  -1.8515   1.1483   3.7654  -2.6485   1.2635  -2.4929  -1.4965   0.6356   3.3756   0.6583 
+ -1.7286  -0.6675   0.3769   1.1159   0.0587   1.4828   1.2140   6.0165   1.2212  -3.4526  -2.4321  -0.8616  -2.2663  -0.0017  -0.0046   0.2615   0.0517  -0.8546   0.5801  -0.1095 
+  3.4455   1.4668  -0.0851  -2.9245   0.0932   1.2861   1.1250  -0.6317  -4.0005  -4.4206  -1.5097   1.3643  -0.1238  -0.8046  -2.4500   4.2293   2.9297   3.2594  -3.0122   0.7633 
+  2.2354  -0.6334  -2.7256  -1.7876  -1.8603   0.6549   0.1244  -1.8100  -1.7636  -2.7665   1.0419   3.6034   2.7187  -5.8124  -0.9848   2.8478  -0.3193   3.4835   2.5353   1.2184 
+  3.0602   4.3425   2.4260  -0.5623  -0.8919  -0.2730   1.3901   0.4772  -0.5219  -1.3754   0.4815   2.4087  -5.0472  -5.6009  -2.8901  -2.4607   1.8809   3.5997   3.9232  -4.3669 
+ -0.0346  -0.2122  -0.2290  -0.9365  -0.4221  -1.9300  -2.3572  -2.9919  -2.2394   3.2115   2.4104   2.4249  -0.5682   1.5001  -1.3857   2.6140  -1.8866  -5.6180   7.3368   1.3135 
+ -0.4484  -1.1107  -1.9143  -1.2992  -0.5392  -1.0181  -0.6562   0.5186  -0.7919  -1.4379  -4.0959   2.4107   1.5417   0.0557   3.4844   1.7096  -0.8275   1.7994   2.0983   0.5209 
+ -0.4549   0.1830   0.2262  -2.2572  -1.5931  -0.7026   2.6431   2.6098   4.0381  -0.4805  -2.9134  -3.5443  -0.6536  -2.1551   2.0956   1.2393   0.2979   0.9155  -2.0621   2.5682 
+ -0.1092  -1.2889  -2.5682  -2.3378  -1.7259  -0.5628  -0.6114  -2.8295  -2.5690  -3.3678  -2.2669   0.6023   0.3823   5.9006   5.7607   1.9871   0.6942   1.2471   3.2445   0.4186 
+  0.6515   1.8638  -0.3444  -2.0169  -0.6995  -2.9879  -2.4596  -1.0847  -0.8686  -2.3776   2.0331   4.8909   4.1694   1.2690   1.4079   1.9289   1.8820  -0.9986  -3.0198  -3.2390 
+  1.7936   1.2201  -1.9231  -2.6761   1.6107   7.0585   8.8031   2.9894  -2.3291  -6.5825  -1.5641   3.0126  -4.0096  -4.0332  -0.6223  -0.5985  -0.8359   1.2689   0.3585  -2.9410 
+ -1.2384  -0.3295   2.3565   3.0657   3.2204   1.0890  -0.5456   0.1283   2.9904  -0.0970  -5.2104  -1.5801  -2.5751  -2.3243  -0.3014   2.6881   0.5623  -1.5424  -1.9388   1.5825 
+ -2.6631  -2.8705  -3.6445  -0.1511   1.0369   4.6018   2.7993  -0.5794  -0.1152   0.9196   4.1279  -0.7083  -3.1505  -2.1870  -2.5145  -0.8667   1.9629   3.7810   1.8562  -1.6347 
+ -3.7832  -0.9972   1.0298   0.8253  -2.4369  -3.3827  -2.6892  -0.8231  -1.0820  -0.0375  -0.7937  -1.8433  -0.5302   3.8146   2.3123   1.6122   4.1004   5.6672  -1.0450   0.0824 
+ -0.1000  -2.0200  -0.5383   2.2917   0.8366  -2.2105  -0.8495   2.1052   3.4989  -0.0827  -0.3031  -1.7154   1.3463   5.4572  -3.0939  -0.0935  -1.1704  -5.2410   2.4300  -0.5476 
+ -3.7789  -1.9485   1.8338   2.9833   0.6807   1.8337   5.1432  -0.4532   0.5973  -0.6042   0.8753  -1.5014   0.4292  -2.2709  -1.2993  -0.1667  -1.6955   1.1932  -6.0865   4.2353 
+ -0.4920   0.0568  -2.6837  -3.2294  -0.2920  -0.6790   2.7843   3.0219   1.7934  -2.2037  -3.0967   1.8829   0.5782  -1.6334   1.9235   4.5606  -4.2261  -0.0121   2.2982  -0.3517 
+ -0.6429   2.5139   2.3667   2.2000  -1.8905  -1.3195  -0.0575  -0.6720   2.8832   0.3828   0.9744   2.9334  -0.6053   3.2595   2.5269   0.0016  -5.8119  -0.9627  -4.8744  -3.2058 
+  0.8584   0.9302   0.3630  -0.3058  -0.9190  -1.1142  -3.3748  -2.6210   0.9921  -0.0440  -0.2277   0.8060   1.7478   2.0581   0.3900   4.4187   5.8430  -6.6138  -3.1191  -0.0680 
+  0.3281  -0.0986  -1.1173  -1.9481  -2.4515  -1.0863  -1.3545   1.1448   2.8412   3.7501   2.6741   2.7224   1.8554   1.4018  -3.7195  -2.9142  -1.2068  -4.2062   2.9680   0.4170 
+  0.2181  -1.3017  -1.3715  -0.9326  -1.1639  -0.6082   2.2905   2.1838   3.1530   3.3746   2.0088  -0.8055  -1.0486   0.7007  -1.7960  -0.3898  -2.4327  -2.4057  -2.1793   2.5060 
+ -2.4912  -0.4925   1.9418  -0.6320  -1.0125   1.8048  -1.5360  -1.7457  -0.3001   0.5912   0.4548  -1.4661  -1.5177  -0.5917   5.6377  -3.6558   1.8798   3.7139   3.0715  -3.6543 
+ -1.0770   1.7774   3.6503   0.2492  -2.5625  -1.2989   0.3077  -1.4511  -0.7454  -1.0293   0.9281  -0.0970  -1.4180   0.5544   2.0070   3.1415   2.3666  -0.7117  -2.8143  -1.7770 
+ -1.8815  -2.2795  -1.1580   1.0865  -0.0453   1.6476   0.0859  -1.8231  -0.7599  -1.0013   0.0173  -0.6116   0.0110   0.6057   0.1048   0.3920   2.8241  -0.4223  -0.2920   3.4995 
+  0.0544   2.8654   4.0202   1.6845  -1.8534  -2.9185  -1.4228  -3.6388  -2.0210  -2.4342  -3.4254  -1.7961   2.7218   6.6019   2.2780  -0.0758  -2.1727   1.0645  -0.3083   0.7762 
+ -4.2733  -4.7209  -2.5347  -4.1434  -2.3709   0.1195   0.9517  -1.8672   1.5567   3.4133   0.9511   6.1534   5.0591   3.3617   4.3448  -0.8335   0.0697  -1.2096  -2.2085  -1.8188 
+  0.0539   1.0537   0.6965   0.7551  -2.3328  -4.4085  -1.7944   4.6582  -1.8228  -0.3800   0.4342   0.9079   1.1727  -0.2538  -0.9787   1.6403   0.3758   0.2889  -1.0679   1.0017 
+  0.9075   0.5642  -0.6092  -2.8652  -3.3111  -1.2627   1.6981   0.5866   2.5675   2.8589   1.6024   2.0917   0.4354   1.0342   1.2054  -2.7817  -0.5893   0.0883  -2.8199  -1.4010 
+  0.8980  -0.3869  -0.4833   2.6033  -0.0884  -0.3699   7.2953   1.6809   0.8531   1.6498  -4.4993   0.0072  -1.9421  -1.8001  -2.5825  -3.6475  -2.3221   0.6178   0.3128   2.2040 
+ -6.0307  -1.3653  -0.3786   0.0247   0.6616   0.7676   3.3234   3.0965   0.7765  -0.6097   1.0441  -0.9142   1.6186  -9.2158  -4.2017   2.5866   2.2875   2.0945   2.8697   1.5646 
+ -0.3542  -0.0280   4.1718   2.5282   6.0404   2.9659  -1.0269  -1.4497  -5.6815  -3.9178  -3.9280  -6.4467  -2.5804  -4.6703  -1.3963   3.1437   4.3980  -0.5477   2.7035   6.0758 
+ -1.5432   3.8376   1.4210  -1.1449   0.4892   1.3172  -2.0383  -2.2564  -2.1791   3.0272  -4.0284  -1.3615  -1.9716  -4.9880   3.8800   2.5715  -2.8049   5.2429  -2.0992   4.6290 
+  1.9112   0.2401   1.2090   1.9221  -0.5051   2.0731  -0.8317  -1.4381   1.1319   0.2604   4.8570  -4.2486  -4.2343  -0.1445   2.6106   1.1135  -3.4590  -1.7688   1.2613  -1.9600 
+ -4.6396  -2.9689   0.9238   0.7657   0.5574  -0.3650  -3.7022  -4.0756  -5.0362   0.3243   3.1880   1.7270  -0.7319   2.9308   3.7592   2.6099  -0.3181   4.3233   1.9146  -1.1863 
+  0.1980  -2.2883   0.9330   3.8033  -3.0797   0.0635  -1.8773  -1.7344  -1.0161   0.1560  -0.1661  -3.8927  -0.3658   0.3316   1.1226   1.9542  -1.0490  -2.2906   3.6658   5.5322 
+ -0.8058  -0.9870   1.9765   0.8081  -0.8891   1.6549  -1.7178  -0.2062  -0.6134   3.7968   2.8384   4.3753   1.2045  -6.0029  -1.5145  -3.5656   0.8785  -0.8278   0.9419  -1.3448 
+ -1.9513   2.4604   2.9573   3.3043   2.2986   1.0394  -0.4185  -0.0890  -0.2841   2.2073   1.6514   0.3367  -1.0792  -1.4676  -0.8850   1.7747   0.0695  -7.9932  -5.3486   1.4171 
+ -2.8766  -0.2007   0.3439   0.7801  -0.0362  -1.8832   1.2162   3.7611   1.5511  -0.2914   4.4891   2.4265   0.5170   1.2791  -3.0822  -4.3172   2.1550  -1.7349  -2.5924  -1.5044 
+ -1.3853  -0.5001   0.6365  -1.9167  -1.9693  -1.6932  -2.5123  -3.1209  -1.5363   3.8772   1.7176   4.5613   2.2969  -1.7507  -0.4549   2.7398  -2.2572  -0.1132   1.3625   2.0183 
+ -0.2587   0.7517   0.0083  -1.5665  -2.9108  -3.8211  -5.3272  -2.2879  -3.3006   3.2010   3.9688   4.6713   3.8047   3.4665   0.6502   0.9612   0.0958  -1.5002   1.1994  -1.8059 
+ -0.0767  -2.8888  -3.8572  -1.6523   2.8392   3.7128   0.7093  -0.0657   0.9823  -1.6073  -2.1810  -1.5064  -0.6392   2.2679   1.7322  -1.1001   1.0422   1.4078   2.4192  -1.5382 
+  2.1069   1.6101  -0.6015  -1.1106  -0.0731   0.3657   2.1738   0.6411  -3.2826  -4.2217   0.0005   4.1333   2.9287   4.0221  -1.0117  -7.1186  -0.3700   1.5812   0.1654  -1.9391 
+ -3.3989  -5.4211  -3.3823   0.1417  -0.2090  -2.9282   3.8367   5.4395   2.1603  -1.6658  -0.0286   3.8151  -1.6236  -0.4057  -0.8473   2.3634   0.3434   0.0424  -0.3374   2.1055 
+  3.8095  -5.8994  -4.2159  -2.8701   5.1790  -4.6791  -5.6257   0.4437   3.5907   6.0531  -2.4206  -0.6190   2.0474   3.5867   7.1475  -4.6633   4.1906   1.2868 -11.1492   4.8074 
+ -5.2857  -2.3511   1.8870  -1.8753  -2.8109   0.3363  -1.9008  -0.4090   0.8741  -0.4525  -6.3796   0.4485   2.7092   2.5765   4.4129   4.7975  -0.3228   3.7712   2.7353  -2.7608 
+ -3.9913  -5.9775  -2.6898   8.0565   3.5971   1.2374   3.4590   0.3338   0.6958  -1.1912  -2.2406  -2.0748   0.0857   3.9701   1.1276   1.2332   0.6559  -3.8152   0.9255  -3.3971 
+ -2.4876  -2.5150  -2.0296  -1.0642   1.0080   0.6973  -1.7376  -1.5703   1.5923  -0.7283  -0.1226  -1.7315   2.4167  -0.4425  -1.5075   3.8846   0.5544   0.8966   4.6270   0.2600 
+  2.8767   0.9007   0.0796  -2.1662  -1.5086   1.0148  -1.3370   0.8661   0.0749   1.4614   3.1800   2.1743  -1.6449  -2.7523  -2.7644   2.2901  -1.9100  -4.8716  -2.0883   6.1248 
+  3.6336   2.1044   0.4628  -0.6805  -0.0353  -2.3281   1.0902   3.0334  -1.9070  -2.0882  -2.9673   0.1514   0.3556  -1.0151  -5.4063   2.3884   2.5624  -3.2553   3.9458  -0.0449 
+ -1.3869  -1.5992   1.4579   1.4992   1.7691   0.8878   0.9518   0.7305  -1.5050  -1.6287  -1.6402  -0.3868   2.7983  -2.2046  -0.5051   0.1956   7.1623   2.4667  -5.9139  -3.1488 
+ -3.5734  -7.3577  -7.1566  -1.3669   4.3200   2.1415   0.4237  -0.1707   3.4434   2.6751   2.2337   0.4895   2.5968   1.0123  -0.9145  -1.1189   0.9048   2.1474   0.4312  -1.1607 
+ -5.2465  -1.6283  -2.7428  -3.2948  -2.2122   4.3049   4.7808   4.7619   0.2262  -0.6089   1.1643   3.3590  -2.1676   0.2134  -1.1502   1.4193   1.4168   0.3538  -2.8694  -0.0796 
+ -3.4905   1.2508   2.0451   0.4490   3.1300   4.3899   0.1675  -1.3519  -0.0668   0.4245  -1.7121   0.2301  -2.2070   0.3069   3.1491  -7.5721   2.7986   3.8554  -4.1493  -1.6472 
+  1.5232   1.5300  -1.0621  -1.4488  -0.8044  -0.3900   1.3086  -2.5549  -4.3776   0.5264   2.2421  -0.5299  -2.7363   4.9582   1.0929   1.1601   2.8351   1.9896  -4.9813  -0.2808 
+  6.5366  -2.5283  -5.5972  -3.4516  -0.2385   1.8382  -1.6024   0.2804   8.8284   4.4416  -6.1238   3.7728   3.4763   2.9323  -2.3678  -5.5110  -4.9901  -0.1283   0.0084   0.4242 
+  1.9342   1.5660   2.2346   1.0331  -0.6035  -0.4461   0.0271   0.7571   1.1796   0.2963  -0.9807  -0.5607  -1.4711  -2.5426  -4.1871   2.4178   0.2030  -1.7949  -3.6655   4.6035 
+  2.2188   0.9702  -1.9037  -2.3323  -0.9270  -0.7473   0.4463   4.0069   3.2380   1.6378   1.5850  -1.9473  -1.2130  -2.1935  -1.9102  -3.3249   2.6456   1.0820  -1.3884   0.0570 
+  1.8633   1.2717   1.6148   0.3758   2.9711  -0.8914  -1.2864   1.1672   2.0355   1.2245  -3.7030   3.7200  -3.0675  -1.9250   2.2356  -0.7355   0.5128  -4.4528  -2.9595   0.0288 
+ -2.2984  -0.5209   0.3609   2.6675  -3.6910  -0.3519   6.3822   3.0237  -0.1277  -2.2553   1.0403   0.9970  -1.3107  -1.9745  -0.1646   4.8839   0.1333  -1.3256  -3.4240  -2.0441 
+ -2.3190   2.2812   1.2138  -1.1727  -3.3340  -5.2226   3.6390   2.5124  -1.5642   3.4166   0.5330   1.8016  -0.3986  -2.9233  -3.7394   0.9982  -0.0060  -1.6833   4.3443   1.6231 
+ -2.2576  -2.6516  -1.1317  -1.2013   0.7393   0.1827  -1.2343  -3.2192   2.3728   2.7817   1.6779   0.8901   0.5320   1.4647   3.7014   7.0412  -2.6912  -2.5104  -1.2474  -3.2389 
+ -1.7690  -1.9167  -2.8243   0.8559   1.6454   0.6817   0.5231  -1.2522  -2.6542  -3.2288  -0.2864   0.0091   0.5513  -0.6182  -3.9328   4.4973   6.4951   0.4313   1.6808   1.1116 
+ -0.2744  -1.5780  -1.8323  -1.2019  -0.3620   1.2906  -0.2832  -1.9105  -0.8966   0.8634  -0.4648  -2.3172  -1.9676  -1.7065   0.8232  -2.4736   3.5667   5.3037   4.3018   1.1191 
+ -0.4003  -1.4016  -2.6548  -3.2373  -2.1471  -0.9075  -1.1057   1.1084   0.0584   0.6994  -2.2697   0.1501  -0.0187  -0.2177  -1.1214   2.5501   5.4533   5.8815  -0.4561   0.0366 
+  2.4755   2.6766   3.3810   2.8797  -1.3067  -1.2604   0.4792  -1.5575  -2.0569  -1.1560  -1.3594  -0.7176   0.2831   1.2557  -0.1965  -2.5773   0.8488   0.4905  -3.0053   0.4234 
+ -0.5334  -1.6405  -1.4903  -1.2901  -2.0368  -2.4054  -2.0422  -1.2649  -0.3204   2.3946   2.8987   2.5774  -1.9494  -5.6321   2.8212   3.6550   3.9850   1.2152   1.3991  -0.3406 
+ -1.8395  -0.9841  -0.1468  -2.7046   0.5709  -0.0486   2.3079  -3.1973   5.7249  -2.0537  -0.8947  -0.5513  -1.5588  -0.0660   1.7712   1.4939   0.7539   0.8995   0.7376  -0.2144 
+ -2.1136  -6.4960   4.0091  -2.7287  -2.8520   0.0889   4.2865   1.1559   1.4489   2.3747  -0.2811  -1.6675  -2.1043   2.4825   1.5983   3.0151   1.4924   1.4598   1.4466  -6.6156 
+  0.3044   0.5145   0.8314  -0.5726  -1.4732   0.5522   1.0454   0.7132  -0.3595   0.4703   4.9451   2.9593   3.4319  -1.7835  -2.7963  -3.6604  -2.7125   1.2113  -5.0055   1.3846 
+  2.3458   3.2640   1.8110   0.4827  -1.6195   1.9882   1.8256   3.5857   4.1301   1.6235  -5.1588  -3.8052  -1.7214  -1.0231   1.3522  -0.3858  -5.6155  -1.3895  -1.6421  -0.0480 
+  3.7883   2.2512   0.5915   3.6595   3.6582   1.2917  -2.0747   3.0623  -4.8462  -9.6783  -4.7828  -4.1622  -5.2776  -1.2559   2.3471   0.9386   6.0401   4.8334  -1.7435   1.3593 
+ -0.5609  -1.1658  -2.4817  -6.5550  -4.6100  -0.2509   0.7628  -0.8368   3.8495   3.9220   3.0356   2.0951   1.5781   3.7313   2.8834  -1.2291  -3.4270   1.5639   1.6072  -3.9116 
+ -1.4268   0.2383   2.3216   0.1248   2.0796   1.5987   0.8138  -0.2165  -2.9254  -1.2364   4.4075  -3.3005  -5.5475   2.3771   2.6523   1.5551   2.5380   1.7514  -3.2529  -4.5520 
+ -0.7746   0.9904   0.2665   0.8152   1.7416  -1.7222  -3.8193   0.6115   3.8698  -1.5065  -1.1919  -1.2590  -0.9540   1.8722  -0.1520  -4.1283  -0.5510   0.1951   0.7420   4.9546 
+ -4.9471  -2.6326  -0.7296  -2.9661   3.2611   5.2949   1.3584  -0.3484   0.0238  -0.5367   1.0370  -2.4283  -1.4686   5.4446   2.1704  -0.2969  -1.9436   4.7301   0.0591  -5.0816 
+  0.8281  -1.2416  -3.3762  -3.9320  -1.3993  -3.0591  -0.9292   2.5927   2.1047   2.4478   0.5704   1.2666   0.5289  -0.2372   1.2696   3.8278   3.1348   1.0903  -4.3525  -1.1346 
+ -0.7430  -0.7480  -1.2610  -0.7625   1.0816   1.6556   1.2019   2.2812   3.2082   1.5688  -1.3094  -2.0639  -2.5822  -2.2528  -1.3400  -1.6246   0.6375   2.8900   1.4778  -1.3150 
+  0.8081  -1.3233   1.3342  -0.4629   2.2543  -1.7177   1.7285   2.2425  -4.4738   0.6367   1.5497  -1.2988   0.3335  -1.1590   0.1744  -4.2648   5.1183   0.3072  -2.6556   0.8684 
+  4.0404   1.9094  -0.2474  -1.1600  -0.9167  -2.2516   3.9300   2.7965   0.9719  -0.3105   2.6858  -1.8089  -6.0898  -5.0707   2.0812  -0.0971  -1.5043   0.0458  -1.0273   2.0234 
+  0.1375   0.2390   1.2366   1.5253   1.5536   1.1452  -3.3801  -3.1595  -2.7411   1.0175   6.4814   1.4661  -1.2521  -3.3744  -3.5432  -5.4270  -1.3071   4.3703   3.6696   1.3422 
+ -0.0191   0.4401  -0.0551   1.2610   4.9915   1.8859   4.2946   2.2533   1.2460  -0.3261  -1.8245   0.5397  -0.9620  -2.4208  -1.3984   1.3654  -2.3100  -4.0785  -1.5595  -3.3235 
+ -4.1713  -3.8609  -3.6233  -2.2953   0.4590  -0.2721  -0.1506  -1.7078   0.0356   1.5074   1.0712   0.7854   0.7858   0.0168  -0.8160   0.0810   0.5445   4.5197   7.1653  -0.0742 
+ -2.9674  -1.4650   1.0679   3.2208   3.0814  -0.6959  -0.9252   1.0871   0.1680  -0.9317  -0.6966  -1.1041   2.3656   1.0874  -0.7021  -0.5843  -5.9540  -1.0591   4.3651   0.6421 
+ -2.3881  -1.1722  -0.2878  -1.3100   0.1054   2.7187   3.1286   1.3950   2.5138   0.8551  -1.0485  -2.7991  -1.7081  -1.9009  -0.2092  -1.1297   5.4416   0.9634  -4.8359   1.6679 
+  0.3475   0.6761  -0.9160  -3.3303  -2.5114  -1.3053  -2.4606  -1.5909  -0.1066   1.2867   0.1087   0.6627  -0.9380  -2.1561  -4.1442   0.5530   3.6775   4.3771   4.5604   3.2095 
+  1.8172   1.9142   1.3748  -1.2576  -1.3958   0.4060  -0.4725  -1.2643   0.8079  -0.6725  -3.4257  -3.2969   2.8901  -0.0329   4.2131   0.8390  -2.3538  -2.2196   3.3371  -1.2078 
+  1.9496   3.6573   4.2326   1.1863   1.8389  -0.7982  -0.8176   0.9762  -2.1796  -2.4082   0.4600  -2.1099  -0.1300   5.8933  -3.2271   1.4122  -3.0287  -5.0286   0.1022  -1.9807 
+  0.7977   0.4131   0.7926   0.7439  -2.7150  -3.1860  -1.6061  -0.5456   3.5797   0.0724  -0.4993   0.4656  -0.7994  -0.5991   0.0862   3.6997  -0.5342  -0.3047   0.9064  -0.7678 
+  1.0025   0.1292   1.8299  -0.2181  -0.3367   2.6298  -1.6812  -0.7903   1.0473  -0.5336  -4.1833   2.6382   0.9480  -0.3031  -1.3062  -0.6706   1.4954   1.1070  -3.9483   1.1443 
+ -2.8220  -2.9373  -1.7368  -1.1113   0.7976   1.0210   2.2881   1.7823  -1.6829  -2.1388  -0.0636   0.6047   1.3691   0.5354  -2.8472   1.9900  -0.2414  -1.8409   2.3664   4.6674 
+  0.8100   0.5306   3.2216   2.7904   2.3222  -0.0940  -1.2977   0.6699  -0.3153  -2.0729  -0.4524   0.1611   0.0422  -0.9458  -1.6284  -1.0590   0.4113  -0.2203  -0.7025  -2.1711 
+  0.6469   2.9521  -0.5269  -2.8396  -2.8290  -0.4167  -2.6035  -1.8694  -1.2710  -1.1950  -0.6111  -1.1719  -0.0843   4.1129   3.9912  -0.9572  -5.8704   3.6319   4.0418   2.8690 
+ -1.7675   0.6361   2.5132   2.0830   1.8929  -1.5061  -3.5844  -4.2969  -2.8299  -0.6870   0.8308   1.3968   0.3529   4.0998  -1.6161   1.3306   0.5600  -0.5129  -1.6573   2.7621 
+ -4.0964  -1.5173   1.2551   0.2978   1.5682   0.3497  -1.4315  -2.0554  -0.5756   2.5392   0.7900   3.4286  -2.9558  -1.7034  -0.8459   1.0513   5.1871  -2.5294   1.2695  -0.0257 
+  0.0328  -1.2155  -1.2836  -0.9363  -1.2229  -1.6930  -1.8595   0.3399  -1.5276  -1.0107   6.4040  -1.9072   0.7733   0.6079   2.8719   3.0211   2.3070  -3.5448   0.3434  -0.5002 
+ -6.6638  -3.5679   2.7288   3.1465  -1.8044  -3.2026   0.3954   1.5738   0.6840  -0.5029   1.1915  -2.4277  -2.8920  -0.4612   0.5352   2.0495   4.9107   0.7993   0.1809   3.3270 
+ -7.7693  -2.7271  -0.5302  -1.6862  -2.6750  -4.1941   6.2224   4.1406   1.2187  -0.8566   3.2170   2.7593   3.3324  -2.3093  -1.4924   1.2643  -2.9807   2.3328   4.6730  -1.9398 
+ -0.3214   0.7654   1.4453   1.0347   0.7854  -0.0281   0.6653   2.1756   2.5539   2.4886   2.8291  -2.3264  -5.6113  -4.1472  -2.1955  -0.1794  -0.8897  -2.9162   2.0658   1.8062 
+  0.0689  -0.0814   0.5156  -0.9104   1.9645   1.4890  -0.7622  -1.4287   1.4489   2.2731   1.0561   3.0605   2.5928  -3.3062  -2.8865  -3.6767  -3.9506  -2.1727  -0.4806   5.1867 
+ -2.7262  -0.4080  -7.2353   0.2532  -1.7494   4.8406   2.4161  -8.2402  -0.3311   1.0612   3.3760  -0.5373   3.2052   3.7144  -2.9286  10.7765   4.9188  -8.1638  -0.8809  -1.3612 
+  3.8706   1.5102   0.3780  -7.4590  -0.9006   2.4899   2.4680  -2.4184  -1.4186   0.2908   2.1056   2.4328   4.2260  -3.9887  -6.7913  -1.0651   2.4289   0.5874   4.8024  -3.5488 
+ -1.2691  -4.1749  -2.7407   1.4930   1.4665  -0.9212  -1.4630  -5.1747  -2.2251   0.8474   0.8540   6.6525   0.1651  -0.5706  -0.3287   3.1547  -1.4600   0.8291   2.5923   2.2733 
+  3.8347   2.4921   1.8361   2.4264   0.2839  -2.7167   0.2831  -0.5469  -0.6398   0.3108   1.0194  -2.1389  -0.8456  -4.7666  -2.5049   1.2075  -5.6326   1.3761   3.1197   1.6020 
+ -3.7739  -1.8529   0.6063  -0.8541  -1.6370   3.6233   0.8975   1.9643   3.5106  -0.3623  -2.4744  -0.7625  -0.7853  -1.5705   0.2237  -0.6207   0.0761  -0.4742   1.5632   2.7029 
+  1.1570   0.8704   1.6827   1.2654  -0.5848  -2.6900  -2.6615  -0.9589  -1.6641  -2.7103  -1.4381  -0.4901   1.8045  -1.5216  -1.1394   5.0021   4.1235   1.5550  -3.7877   2.1859 
+  2.5420   1.6423   0.7395   0.8846   0.9016   2.7752   3.3824   2.5574   0.4625  -2.0442  -1.8686  -0.1860  -1.7933  -5.0038  -3.5773  -1.2917  -2.0519  -1.8556   1.0146   2.7701 
+ -4.4081  -3.4569  -0.8021   0.2773   2.5574   2.3862   1.3118   0.1408   0.6688   1.9053  -1.5497  -0.5855   1.2457  -0.5521   0.9630  -2.2470  -2.8924  -3.7430   6.1844   2.5961 
+  0.4138  -4.3685  -4.3743   3.3166   1.9814  -1.9703  -1.1246  -1.8788   1.8555   2.5293  -0.6354   0.3032   3.9855   0.4439  -1.3412  -2.6733   1.5434   2.8406  -1.3900   0.5430 
+ -0.9949   0.7752   0.5153  -0.3382   0.7590  -0.3806   0.6362  -0.0446   0.6992  -2.3407  -2.2180  -0.8794   1.9075   1.9883   2.6403   1.4665   1.1384   1.9497  -0.4373  -6.8420 
+ -0.3690   1.5979   3.6520   2.5947   0.9915  -0.4587  -1.5761  -1.3889  -0.8595  -0.0002   0.3336   2.0392   1.9215  -1.5962  -2.1409  -2.1868  -2.0225  -6.9604   4.1862   2.2427 
+  0.7081   1.2472   1.2274  -0.7827  -1.3963   0.1531   1.0164   1.1220   1.4236   4.7449   4.1970  -1.6566   1.4602  -0.4324  -5.0812  -4.6776  -3.2034   0.2020  -0.8325   0.5609 
+ -0.8996  -1.1981  -0.4982  -3.3678  -3.1656  -0.4840  -1.6889   1.4162   1.8691   1.8944   0.6984   2.1971   0.7659  -0.3399  -1.0540  -1.9648   4.8986   2.2357  -0.4350  -0.8795 
+ -3.0303  -1.1024  -3.6351   1.8563   2.2581   0.9526  -1.3180   1.0520   0.9676   1.4472  -0.2536   1.6459   0.5539   2.7964  -2.3045   3.1405  -0.8848  -0.5008  -4.0553   0.4143 
+ -2.0566   0.3509   1.5804  -0.1468  -1.2009  -5.1236  -1.6316  -0.6083  -0.2262  -3.8727  -1.4106   4.1461   2.8353   5.5841   2.0344  -1.3445  -0.2669   1.6597   0.4425  -0.7448 
+  0.4237   5.5027   3.4466  -0.9733   1.1101   0.3187   0.4016  -0.8934  -4.1773   1.2529  -1.0141   1.7716  -1.4207   2.0071  -6.7629  -1.4260  -0.8769  -1.9766   2.0620   1.2241 
+  0.5250   0.4342  -1.3517  -2.8754  -3.0586   0.6098   2.2679   1.4929   1.4608   3.1011   1.5060  -4.8013  -7.5268  -0.6504  -0.5030   2.7780   2.8557   1.0462   3.4571  -0.7675 
+  3.5730   1.8714  -0.1581  -1.7722  -0.3433  -2.7056  -3.0806  -1.9100  -3.1355   1.0548  -1.9906   0.4699   0.0873   2.5566  -0.1726  -0.8702   2.1464   4.3968   5.0995  -5.1171 
+ -0.6968  -1.4896  -0.0495   0.8149   1.4216  -0.0327  -1.7535  -2.2313  -0.3210   1.9568   4.8784  -1.9324  -1.8058  -2.6431  -3.7316   0.3685   1.1306   4.9893  -0.2577   1.3848 
+ -1.4341  -1.1497  -1.8056   0.1413   2.5710   2.9390   0.7055  -0.4196  -0.2614   0.1608  -0.6195  -0.3637   4.1643   0.3576   0.0984   2.2749   0.4728  -7.3150  -0.1921  -0.3248 
+ -4.2895  -7.0396  -4.8802  -1.5844   1.4442   1.8886   0.5829   0.1608  -2.6352  -1.0632   0.4985   3.2097   6.3270   9.0622   8.0546  -0.4311   2.1200  -2.0642  -2.9293  -6.4319 
+ -2.8918  -0.9105  -1.1049  -1.3358   0.0333  -0.4429   1.1140   3.2177  -0.2479  -0.9423   2.0518  -3.4204  -3.3752  -1.5080   4.5184   3.5104   0.8370   0.3279   4.1906  -3.6215 
+  1.1012   2.8300   4.9338   4.9135  -1.4413  -4.6933  -2.9852  -2.2104  -2.0709  -0.2446  -1.7323   0.4460  -0.3491   0.7293   1.2549   1.5520  -1.6591  -0.0263  -1.3091   0.9607 
+ -3.8105  -2.2705  -0.4801   0.0030  -1.0835  -0.8967  -1.8480   4.3428   2.2775   1.1261   1.5948   4.4091   3.5564  -2.1928  -2.8051  -1.2385  -1.6399  -0.9968   0.5731   1.3796 
+  4.5581   4.2833   0.3675  -0.5438   1.9400   3.0816   0.3261  -0.8096  -2.6679  -2.1086  -0.8131  -4.9186  -3.6340   5.7405   0.0185   0.6308   2.5276  -4.0355  -1.8846  -2.0583 
+ -1.2863  -0.2640  -0.1222   1.8197  -0.8215  -1.4173   6.3047  -1.3136   2.0735  -0.1627   3.0262   1.5599  -2.3044  -2.9292  -2.1284  -0.0060  -0.2974  -0.4468   0.2977  -1.5818 
+ -0.3043  -4.9833  -4.4641   1.6692   5.7638   4.6547   3.7525  -0.9610  -3.9550  -2.2488   0.7885   4.2621   3.6322   2.1375  -6.9698   1.9153   2.5541  -3.4886  -0.8469  -2.9081 
+  1.6869  -2.2603  -5.3537  -1.9240  -2.3796   2.8412   5.8922  -3.3838   0.7866   3.3273   0.7220   4.1493  -2.8075   1.2195  -4.1220   2.7912   5.5751  -0.9361  -3.7960  -2.0281 
+  1.8743   1.5687   0.9347  -0.0119   5.1974  -0.9505  -1.5819  -0.0387  -0.2355   2.4835  -2.7180  -2.1816  -1.0347  -1.5606  -1.4552   0.4355  -1.6713  -3.1551  -0.2146   4.3156 
+ -0.5064   0.6473   1.6157   0.4031  -0.7786   0.4664   2.3609  -0.8533  -2.7426   0.0584   3.6047  -1.3728   0.0256  -2.0089   0.7575  -3.1106  -1.7839   0.9710   1.5709   0.6757 
+ -0.1854  -0.4792   0.2327   0.5721   1.3762   0.9344   1.6367   0.2158   0.6455   0.9744  -3.1471  -5.2734  -4.3577   3.1646   3.1365   2.2803   1.2303  -1.9960  -1.5643   0.6037 
+  1.5540   2.1016   2.3825   0.8004  -2.0847  -2.7548  -1.5073   0.1971  -0.2707  -0.7690  -1.8324  -0.6385  -4.5361  -6.8801   5.4599   2.6660   1.1252   2.2850   1.3862   1.3159 
+ -2.3092   8.5984   0.5061  -0.6741  -2.4670   3.2934  -0.6680   2.0327   0.6889  -1.8602  -0.9325  -1.2001  -4.3458  -2.5628   0.6948  -1.1889   0.4479   2.5950   1.2931  -1.9416 
+  0.8421   1.5717   0.5751   0.5951   0.4783  -2.2142   0.3553   6.0828   3.0287  -2.3343  -3.2264  -0.7759  -2.0090  -0.3873  -2.4778   0.6768  -3.4990  -0.8957   4.2903  -0.6766 
+ -0.6942   8.6603  -5.4134  -0.8727  -0.3504  -3.3092  -0.5586  -0.2913   2.8905  -3.0583  -2.9724  -1.7470   3.3250  -1.1022  -4.4193   7.6704   0.5149  -0.7173  -3.6000   6.0453 
+  0.6802   1.0947   1.2451   3.8611   4.5266   1.8951   0.7625   6.2260   2.5223   4.8966   1.8380  -0.3753   1.3861  -7.5361  -6.8810  -3.7307  -4.9193  -2.5727  -4.5778  -0.3414 
+ -1.4648  -1.9631  -1.4302   3.2813   2.7021  -1.3306  -3.5822  -3.4123  -2.6251  -2.5540  -2.9830   1.7868   1.1612   1.7944   0.6471   3.7619   3.5844  -0.4360   2.9666   0.0957 
+ -2.6065  -0.4815   3.7667   3.2609   1.4317   5.8806   0.0973  -3.3441  -3.2874  -4.9485  -1.6589   0.7537   0.3424   0.9215   3.8135  -4.2041  -1.8751  -0.8917   1.0067   2.0227 
+  4.0705  -1.6316  -3.7042  -1.3612   1.3654   1.6949  -0.0461  -0.4280   2.9316   0.2615  -3.3312   0.4341   1.2323  -0.8543  -0.8620  -4.8579  -6.1758   3.1382   4.9340   3.1899 
+ -4.1097  -4.1313  -2.7947  -1.2657  -0.6757   0.0158  -0.2664  -0.7288  -2.8256  -1.9407   0.4965   2.0938   4.2596   1.7443   2.0920   3.1468   3.6217   1.9383   0.0884  -0.7586 
+ -0.5474   3.7117   4.4423  -1.1991  -3.2034   0.2008  -1.1999  -0.3645  -0.3658  -1.5068   4.3945  -0.5362  -1.4209  -0.9138  -0.0750  -0.9590   3.3133   2.7513  -7.0608   0.5385 
+ -0.2792   1.0180   0.1758   4.6409   0.9990   0.8572  -2.2212  -4.3593   1.0210   5.0992   3.1964   1.4429  -1.7425  -0.9214  -2.3245  -1.3975  -6.8773   2.8027  -1.1862   0.0560 
+  1.7064   0.3215  -0.2518   0.0527  -2.5377  -4.4163  -3.0416  -0.1822  -1.1887  -2.9410   0.6761   3.4948   1.6101   1.2626   0.2612   5.6220  -3.9114  -1.0915   4.1888   0.3661 
+ -1.7866  -1.1389  -0.0309  -0.9349   0.3853   1.9195   0.2339   0.3886   0.9745   1.4208   2.5313   4.3943  -4.6360  -2.5445  -2.1898  -2.5330  -0.3527   4.7621   0.5928  -1.4558 
+  7.8057  -3.8468   0.8827   0.8768  -4.7631  -5.1731   0.0664   5.3199  -1.7890  -4.3428   1.9966   2.9221  -4.5512   5.1760   0.5820  -0.2561  -0.2887   0.6505  -0.8654  -0.4024 
+ -2.5780  -0.0834   0.1440  -1.6096  -4.1370  -4.8240  -1.6968   2.0832   4.4015   2.3414   0.0326  -1.7738   3.0088   2.5338   2.2405   0.7822  -3.4270   2.3235   0.3274  -0.0892 
+  2.1843   2.5930   1.3745   1.7373   2.8715   2.7285  -1.1274  -0.1783   0.9497   1.0004  -0.2974  -0.2919   0.6463   0.2228  -1.5085  -5.8708  -3.6910  -0.8536  -2.5539   0.0647 
+ -1.6643  -0.8616   0.2098   2.2486   4.6647   3.8540   2.3834   1.3656  -0.2611  -0.7523  -0.2703   2.8630   1.1570  -1.6263  -4.3844  -3.5346  -0.0484  -0.8649  -4.9645   0.4867 
+  0.6824   1.0939   0.6691   0.3291  -0.2396  -0.9714  -0.9487   0.4056  -0.8422  -1.0662  -0.8121  -1.8756   1.8363   1.0681   3.7568   2.7493  -2.2790   1.4171  -4.9986   0.0258 
+ -2.0461  -1.9677  -1.8134  -2.6831  -3.0621  -1.6874   2.2873   0.6491   1.7878   1.1808   1.5028  -1.1540  -1.2923  -0.0603  -3.5107   6.4917   4.0814   1.4288   0.0396  -0.1721 
+  1.7926   0.6400   0.0107  -3.4114  12.2384  -4.2391  -4.1672  -5.5139  -1.6966   5.3015  -0.9447  -4.0014   3.1093   5.2076   5.6201   2.3962  -5.3615  -1.8057  -0.2628  -4.9121 
+  1.2301  -0.2653   0.0535  -2.1294  -3.7763  -2.5405  -1.3165   1.3892   1.1754   1.8095   2.3931  -0.5310  -0.8291   0.5926  -0.2725  -7.2218   1.8619   3.8534   3.4226   1.1011 
+ -4.1789  -3.5276  -0.8324  -0.4176  -2.4000   0.0369   0.9853   5.4189  -1.8625   4.5416  -0.0534  -2.2531  -1.8390   3.0263   1.3992  -0.9141  -0.2291   0.6856   2.4454  -0.0313 
+ -6.4975  -4.6128  -3.3675  -4.8986  -0.8354   2.3584  -0.6088   4.1352   0.6068   0.7211   0.2750  -2.0557   0.4476   2.7831   4.6078  -0.4014   5.9849   2.1061   1.2312  -1.9795 
+  1.3230   1.1384   1.2773   1.7150  -0.7509  -3.8269  -1.1290  -0.1851  -3.0673   2.4551  -1.8006  -0.5768   2.5367  -0.4358   1.0236   2.8956   4.5161  -0.4242  -3.2309  -3.4534 
+ -0.3567   2.4123   4.0459   3.3988   2.0862  -2.1774  -5.1260  -1.0930  -2.2588  -0.1938   0.5021  -0.2723   1.0175  -2.6722   0.0196  -1.3546  -1.6702   0.8080   0.6509   2.2336 
+ -3.1316  -2.5501  -0.7668   1.9764   1.8647  -0.0801   0.9053   0.9563  -1.0947   0.3992  -1.9982   2.2428   2.0122  -5.4193  -2.6261  -0.7274   0.7121   1.7109   3.9486   1.6660 
+ -7.9949   4.0953   3.7255  -1.4546   8.0933   1.7853  -4.2627   4.4208   9.6075  -2.0281  -0.5418  -3.5660  -1.9219  -6.8006  -1.4426  -1.8720   6.0536  -6.8174   0.7937   0.1276 
+ -1.9787  -1.0115   0.4548  -0.6009   1.0489  -0.3883  -3.8168   3.5539   1.8044  -0.8020   2.2377   4.0130   2.5264   2.9341   2.9402   3.1940 -12.1756  -4.5827   0.7140  -0.0649 
+ -2.6937  -0.9969   0.6136  -0.2092   0.1112   0.1733   0.0276   0.6804  -4.1810   0.4835   3.1126  -0.8365  -1.6005   3.1133  -1.3297  -0.4657   2.8302   2.7130  -2.7204   1.1750 
+ -4.2305  -1.0868   0.5304  -0.1415  -1.2124  -0.8981  -0.8790  -0.8763  -0.9777   1.0148   4.1145   2.1714   1.2310  -1.6938  -1.4429   1.2355   6.6877   0.2382  -3.2655  -0.5189 
+ -2.1503  -3.4325  -3.4567  -1.0918   0.5993   0.3527   0.3437   0.2288   0.7821   1.0173   2.2607  -0.9887  -0.3595   4.4457   3.7070   1.5475  -3.7173   0.7682  -0.5101  -0.3462 
+ -3.7019  -3.2897  -0.3993   1.1225   4.7873   3.2500  -1.8347  -2.0699   0.0727   1.2966  -0.1512   1.4478  -2.4263  -0.3987  -2.4159  -3.3225   2.8445   0.7735   0.8954   3.5197 
+  0.0807  -1.1966  -2.9464   0.8465   1.6234   1.1215   1.2824   3.7187   2.3234  -3.7329  -7.3924  -3.2192  -4.4371  -4.8564   3.1927   2.3654   4.5154  -1.0330   4.4531   3.2910 
+  0.0329   2.1961   1.8627   0.5090  -2.3566  -3.1635  -1.4865  -3.4766  -3.4834  -4.5095  -2.4040  -5.5450   7.4389   3.1752   2.6905   4.3345   1.8695  -0.0444  -0.0458   2.4056 
+ -4.2525  -4.2615  -2.8448  -1.4174  -1.4188  -1.0941   0.0321   2.7304   1.6246   3.7714   3.6887   2.3979   1.9374   0.7696  -7.0469   0.1811   3.9202   4.8839  -3.2038  -0.3977 
+ -0.4109  -0.9615  -1.1887  -1.3425  -1.0669  -2.7829  -2.9395   1.2890   1.6984  -0.5601   1.6775  -0.5469  -0.8102  -0.2298  -0.7565   0.3451   3.1792   2.2226   4.5535  -1.3689 
+ -5.7264  -3.6531  -1.3521   0.1463   1.7110   3.1890   0.7838  -1.0176  -0.2195   1.4384   0.0207  -0.4968  -1.0491   0.1749   1.0739   2.0378   1.3580   1.2360   0.4429  -0.0980 
+  0.7773  -0.8979  -1.2165  -1.9337  -2.9157  -4.0101  -0.3148  -4.6460  -4.2945   4.1770   5.5969   1.4549   3.5448   1.4079  -0.8343  -3.2017   5.5239   2.2268  -0.3838  -0.0607 
+ -0.6985  -0.6307   2.4635  -0.5381  -0.2883   3.4018   2.1088   2.9180  -0.5123  -0.9613   0.0579  -4.3385  -3.8027   1.0743   5.0578  -1.8280  -2.2439  -4.7171   0.9386   2.5388 
+ -4.5218   0.1558   2.8380   2.3948  -1.9436   0.6339  -0.7954   1.9788   1.5836   1.1696  -4.5526  -0.5640   1.4447   7.0584  -6.8023  -4.5393  -6.0449  -0.5031   6.1354   4.8739 
+  0.3624  -1.2047  -2.0776  -1.5816  -0.7523  -0.4259   1.9866  -0.1702  -0.4710  -1.9514  -1.5113  -0.2099   2.7070   3.8409   4.1635  -1.6517   0.8031   3.1180  -4.9637  -0.0100 
+  3.3248   2.1375   1.3785   0.2103   3.0519   1.4244   0.2968  -0.3016  -1.2728   0.9142   0.2763   0.9396   2.3345  -1.6742  -3.9431  -3.4421  -2.5066  -1.7463   1.1359  -2.5381 
+  7.3832   7.8862  -6.4414  -8.9767   0.1372  -3.3099   3.3247  -2.2516  -2.6663   1.5419   7.2572  -0.6762  -1.4552   3.0048   6.9210  -8.5959  -2.6649   2.5301  -0.7893  -2.1588 
+  1.3303   0.1631  -2.4438  -1.2379   0.9953   2.7203   1.9038   1.2786   0.3887   2.8669   0.3680  -0.1846   5.6338   2.1238  -1.0482  -5.2051  -1.0787  -7.2281  -1.5184   0.1722 
+  0.1645  -0.9895  -2.0311  -3.1149  -3.2980  -2.1249   2.0221   2.1048  -0.3058  -1.0676  -2.5289  -1.4215  -1.7517   2.9140   4.1244  -0.6494   2.6877   3.2611   2.5839  -0.5792 
+ -0.4639  -1.9119  -0.6903   1.0816   1.7980   1.1866   0.4220   1.5316   0.8944  -2.9810   5.6782   3.5367  -0.9955   2.4778  -1.9477  -3.1693  -0.0340  -1.9442  -1.8186  -2.6506 
+ -3.9601  -3.1838  -1.3333  -0.9936   0.4708   1.8640   0.2776  -3.5639  -1.8523   3.8979   6.3274   1.9935   2.4867  -0.2835  -0.1329  -0.9778   1.4936   2.4315   0.5084  -5.4702 
+ -1.9007  -8.9624   0.7258  -2.6244   1.8683   0.7413   8.1690  -2.3570  -4.2143  -5.3821   5.3979  -0.3396  -0.0209   2.4866  -1.7903   8.5769  -2.6396  -4.5135   0.4288   6.3503 
+  2.3682   1.2735   1.0581   0.7198  -1.3884  -1.1783   2.7862  -0.3150  -4.4216   1.0457   0.8020   0.2322  -1.8255   0.9933   1.5522   4.2681  -3.4105  -1.8681  -3.1691   0.4773 
+  0.1022   3.5273   4.7298   1.5753  -3.6041  -2.4060   0.8414   1.2204   1.0785   1.4517   0.9533   1.0682  -0.0095  -1.2482  -3.7150  -1.4924   0.0586   0.2151  -3.5086  -0.8381 
+  2.6097   1.3046   0.1797  -0.8433  -0.8002  -0.6737  -0.7817  -0.0181  -1.8564  -0.0021   1.7429   2.1363   2.4019   0.8520  -1.2013  -2.3776   0.1614  -1.6535   0.2922  -1.4730 
+ -1.1555  -1.9989  -3.7971  -3.5419  -1.7702   5.6208   1.6756  -3.4769  -2.2174  -0.5921  -2.9465   2.4449   3.2181   2.5732   0.5741   1.4008  -1.6104   2.6683   4.0017  -1.0706 
+  2.6808   2.4971   2.2595   2.6039   2.5012   2.7248   0.3061  -0.5761  -0.0415  -2.4607  -1.2162  -0.0800  -2.7145  -3.3777   0.3468   1.3821  -2.9010  -0.5334  -2.3262  -1.0750 
+ -1.4573  -0.7869   0.2356  -0.1795  -1.7997  -2.4756  -0.7083  -1.2917  -0.2409   1.8121   2.3854  -0.0780  -2.6742   0.8926   3.1169   2.4329  -3.2335   1.5184   1.6752   0.8566 
+  1.3578   1.5299   1.0786  -1.5960  -3.3648  -1.6673   1.3592   5.7139  -0.3364  -0.8154  -1.0911   0.3285   1.2167  -6.5169   3.5759   0.3841  -3.4189   2.2520  -0.3564   0.3665 
+ -3.9427  -4.1692  -3.9599  -2.7914  -2.7852   0.8501   2.1268   3.1929   2.9997   0.9798   3.7115   2.7044   0.8023  -1.3597  -0.1213   1.8505   0.8537   2.3570   0.4425  -3.7419 
+  1.1259   1.7278   1.7181   1.0824   0.9378   2.2855  -0.4426  -2.0998   0.2868  -2.3258  -2.4774  -3.5030  -2.1920  -0.0403   0.0689  -2.1823  -1.7516   0.3348   2.6371   4.8097 
+  2.6282   3.1949   1.4763  -1.8168  -2.3026  -0.1157  -0.0177   1.6877   0.8500   0.1002  -0.5211   1.2286   1.5164  -0.6411  -0.9348  -3.1872   0.1863  -3.1762  -3.7899   3.6345 
+  0.6239   1.6179   1.2014   0.2608  -1.9920   4.7736   2.9884  -1.6687  -1.5700  -3.2904   2.3265   0.1217  -0.6529   1.1537  -1.3430  -3.2660  -0.7427  -0.3946  -0.8553   0.7078 
+ -2.5785   3.3274   0.7827  -1.1641   0.3099   2.0930  -3.8923  -2.1233  -0.2174  -1.0352   2.3827   3.2008  -1.3061  -1.3553   2.0138  -4.8137   2.2926  -0.4492   0.2262   2.3061 
+  0.7030  -0.6796   0.6702   1.2330   0.3286  -1.1249  -0.2281   0.9008  -0.4257   1.5252   0.1413   3.8708  -2.7125  -0.1048  -1.3046  -2.6469  -1.7645  -0.4236   2.6448  -0.6022 
+ -2.0396   0.9147   3.7884   2.4844  -0.2561  -2.4529   1.8969  -0.1479   0.6950  -1.2549  -4.9008  -1.2459   0.9313   0.6906   5.2636  -1.1277  -0.2394  -2.2895  -2.5856   1.8753 
+  1.6780  -1.6532  -2.7599  -2.2450   0.5197  -1.6003   4.4426   1.0934  -0.3109   0.9191  -3.4242   1.3304  -1.5208  -0.9853  -0.2434   3.9418   0.4425  -2.2543   4.6335  -2.0037 
+  2.2658  -0.6139  -1.3935  -0.0563  -2.9550  -1.9056   3.4601  -0.3817  -1.6475  -0.2910  -0.5503   1.7727   0.0114   2.6384   2.8574   0.5346  -5.4829  -2.6161   0.9580   3.3952 
+ -2.9553   0.0039   3.9564   2.2087  -0.9348  -1.5953  -1.3780   0.1552  -2.1548   0.7917   1.8242   1.6997  -1.8826  -0.8677  -0.7876  -0.2152   2.3842   2.1467   1.7116  -4.1110 
+  0.7023   1.9303   1.0064   0.0165   5.4286  -1.1464  -1.0459  -2.0088  -1.2634  -2.1806  -0.6159   0.3372   3.4050  -1.1188  -2.8596  -2.3910  -0.5550   5.4226  -1.0697  -1.9937 
+ -0.8683   0.0341   1.1306  -1.3868  -1.9833   2.9612  -0.7025   0.9705  -3.1777   4.1388   0.7353   0.3664   2.0843   0.2998  -0.4050  -1.1895   3.2137  -5.0324   1.1351  -2.3244 
+ -1.0092   0.5101   2.3070   2.1852   1.5304  -1.7001   1.6095  -1.4570  -3.9762  -1.6422  -0.2532   1.3474   0.8974   0.9819  -2.2295   4.7058  -2.0380   3.1038  -2.5420  -2.3311 
+  1.9713   1.0803  -1.0686  -1.2321   0.3041  -0.5899  -1.6032  -0.6543  -2.1903  -2.1676   0.3844   0.2905  -0.5787  -1.1285  -3.3703  -0.5637   0.3705   2.2696   8.3763   0.1004 
+ -2.3313   3.6108  -3.7738   2.3534  -6.3897   3.9802   2.8098   6.2413   2.5170   5.1260   2.4541  -1.7202  -4.9921  -5.7179  -3.3204   5.3271   2.0124  -5.7657   0.7907  -3.2116 
+  0.3230   1.0311   1.3660   0.9706   2.0785   2.0724  -0.0151  -0.8301  -1.1195  -2.8044  -0.9819   0.0417   0.0944  -1.2077  -2.2323   4.1593   1.4207  -2.7654  -0.5102  -1.0909 
+  1.0182   0.5812   0.3232   1.7040   1.6371   0.0882   0.7883   2.0623  -2.4549  -1.7632  -0.0828   0.1245  -1.0882  -0.0487  -2.0254  -0.8118  -5.9132   2.5533   0.4880   2.8199 
+ -2.1755  -1.4110   0.7926   3.1903   3.2045   1.4005   2.2246   0.4995   1.4795   1.0003   1.4155  -1.8108  -1.7649  -2.0289  -4.9177   1.9399   0.4644  -0.6846  -2.6827  -0.1356 
+ -2.3372  -0.8774   1.8295   2.5713   0.4237  -1.6200   0.7250   1.2049  -2.5557  -1.7837  -2.0535   1.8608   2.0142   1.1559   0.4140  -2.2055   2.6316  -1.0207  -0.4407   0.0634 
+ -6.4760   2.3566   6.2881   1.1780   2.2768   0.5492   3.6691   1.5956   1.5393   0.8045  -2.4474  -1.1396  -3.0192  -2.8013   2.1788   0.9584  -4.0593  -1.3318  -0.6033  -1.5164 
+ -0.2224   3.1469   4.1918  -1.5853  -2.9401   2.4424  -2.0556  -1.6902   1.4657  -1.4987  -4.5783  -3.9175   1.8499   2.5001  -2.9926  -3.1367   4.3814   2.8761  -0.3135   2.0766 
+  0.2838   0.7448   1.5373   1.7127   1.9184   1.9954   1.4552   0.6636  -0.0775  -1.4076  -2.7023  -2.4765  -6.0615  -4.2297  -2.8214   4.4402   0.5975   1.2302   2.2798   0.9178 
+  0.1873   0.8058   1.4948   0.4584  -0.6762  -2.1053  -0.4098  -0.9510  -0.4347  -0.3909  -1.0508  -2.5837  -1.0389  -4.2899  -4.0647   3.8453   2.2675   2.8481   4.5950   1.4936 
+  6.4165   4.7690   2.1643  -0.5306  -1.7418  -1.1821   0.4655   2.4797  -1.0005  -2.7835   0.6462   1.0540   0.1648  -0.2195  -1.2133  -1.6876  -0.2896  -1.1843  -4.2375  -2.0895 
+  0.6591  -2.4247  -3.5305  -2.0684   0.7993   0.5286  -1.0223  -0.9537   0.6266   1.4075   1.4620   1.6652   1.3324  -0.3799   1.6047  -0.4030  -1.4183  -0.7574   3.5079  -0.6351 
+ -0.7402  -0.5022  -0.0104  -0.1501   0.0126  -0.8303  -0.6338   0.0643   0.7573   4.3586   2.2234  -0.7379   3.8453   0.8151   2.8221  -1.4249  -1.4011  -3.5524  -6.4818   1.5666 
+  1.2970   2.6835   1.2613  -1.8292  -0.9390  -1.6773  -1.9287   1.2477   1.3854  -1.9138  -1.0744   1.6338  -4.8418  -0.5580  -1.2900   5.2745  -2.7458   2.6939  -0.9625   2.2835 
+  1.8861   3.1363   4.0321   1.7435   0.5233  -0.7855   2.0137   0.8065   1.2174  -4.0074   0.5860  -1.0339  -6.4815  -6.1251   1.1641  -3.9644  -6.3895   7.8222   2.0846   1.7715 
+  3.9399   2.2907   1.6049   0.7588  -0.5727  -0.4203   1.1669   0.6185  -0.3417   1.2484   1.5946   1.7091  -1.8086  -4.7596  -2.8399  -3.9325  -2.0296  -0.6780  -0.7509   3.2019 
+ -0.3222   0.6190   2.2698   6.3269   5.8198   2.6992   0.0601  -0.5335  -1.7361  -3.6667   0.2231  -2.3194  -2.0166   2.4960   0.1420  -3.4765  -2.9842  -0.3195  -1.1974  -2.0840 
+  1.2403  -2.3646  -2.0313   0.7252   3.2474   2.8194   3.1981   0.9009   1.1286  -0.9170  -2.4531  -2.4020   1.6229   2.3317  -1.4971   0.7586  -3.2903  -2.1223  -1.2864   0.3911 
+  2.1547  -0.4814  -1.6208  -0.2568   3.7660   2.5927  -0.5335   0.5221   2.1027  -1.7193  -2.1878  -1.5973   0.4487  -3.0208  -3.0695  -0.2839   1.2100  -4.2182   4.8800   1.3123 
+ -0.8216   0.0172   1.0117   1.8195   2.2767   0.0322  -4.7072  -3.7244   0.2876   1.2946  -1.1268  -2.0514  -0.3229   1.5642   2.8282   1.4525  -0.2405   0.3745  -0.8299   0.8658 
+ -0.5885  -0.7711  -0.1566   0.2456  -1.1305  -2.1400  -1.5832  -2.7023   2.6573   2.8982  -1.9439  -1.4435   3.2616   3.0544  -1.0646  -0.2393   0.2808  -0.6774  -3.3509   5.3938 
+ -2.1609   4.7541   2.6519   2.9104  -0.9771  -3.4464   1.3102   4.9024   3.0997   0.1198  -0.6878  -5.0516  -2.6241  -0.1390   0.3260  -3.7625  -4.6033   5.7644  -2.7192   0.3330 
+ -0.0774   0.0212   1.7356   2.6966   3.8703  -1.2640  -2.2040  -3.8688  -2.8745  -0.3830  -1.2433   2.7247   1.1808   0.5913   3.3839  -2.9426   0.1962  -0.6047  -3.1975   2.2593 
+ -1.7694  -0.8337  -1.4857   1.6357   3.0084   1.4757   0.7496   0.4982  -0.8638   1.0294   3.8151   2.5480  -0.4944  -5.1598  -4.1575   1.6819  -0.9028  -3.0629   2.9081  -0.6201 
+ -4.1737  -1.1372   0.4218  -0.3980  -0.2873  -2.0904  -1.4241   1.1799   4.8192   5.5695   2.1240  -1.9634  -0.1503  -0.2208  -2.6623  -1.2140   1.5287   0.1773  -0.4832   0.3844 
+  1.1759   3.6352   3.0816  -1.1382  -0.8341  -1.2549   1.7627  -0.2610  -1.7582  -4.6767  -1.9887   0.8806  -0.2903  -2.9331  -3.3697   0.3291  -2.5313   6.3991   2.6926   1.0793 
+  3.1054   0.5446  -2.7707  -3.1154  -2.4354  -2.1091  -1.9215   1.5263  -0.5089  -2.1954  -3.0602  -1.7502   2.0283   3.0940   3.1639   6.0315   0.1168  -2.3219   2.2755   0.3024 
+  1.4017   0.2037  -0.1188   0.3630  -1.7809   1.2589  -0.0416   0.1426  -0.2900  -0.0669  -0.9365  -1.7637  -4.6543   4.5857   0.7173  -1.2893   0.7992   1.8632   0.4734  -0.8667 
+ -0.6645   0.3054  -0.1583   0.3900   0.1223   1.1996   4.2148   1.7843   2.7706   0.9297  -1.0663   1.2711  -0.1675  -0.5861  -2.5452  -2.9107   1.2640   0.2394  -4.6672  -1.7254 
+  1.3908   0.5115  -0.8577   0.3878   0.7710   1.2838  -1.2112  -1.2930  -1.9359  -2.3893  -2.5796   1.2692   3.1933  -0.2748   0.2489   3.4206  -5.3967  -3.2312   2.6326   4.0600 
+ -3.1151  -2.4768  -1.4409   0.0820  -0.0650   0.8542   2.7545   0.8481   2.7775   3.2925  -1.1392  -0.5600   5.6459  -1.5505   0.7937  -0.2372  -3.8294  -1.7699  -1.1681   0.3038 
+ -1.4631  -1.5744  -1.0602   1.2727   5.2755   0.7411   2.6424   0.9111  -1.5443  -0.8217  -2.4580  -1.9627  -0.3229  -0.7005  -0.1842   1.4410   1.1190  -0.0388  -1.7254   0.4532 
+  2.6735  -0.1320  -2.0731  -1.2667  -0.0059   0.4063   1.1045  -0.6500   0.2919  -0.2343  -0.1432   0.5161  -1.3203  -1.9223  -1.8439  -0.3541   2.5902   0.7807   0.9691   0.6136 
+ -2.5760  -2.1039   3.3039   7.5737   4.8510  -1.9280   1.3509  -0.0624   1.3149   2.3856  -2.8836   1.6777   1.6919  -0.2315   2.0672  -1.6292  -7.7877  -7.8864  -2.4230   3.2949 
+  0.1825   1.4326   1.8802  -0.7600  -3.5028  -2.0654  -2.5905  -1.9780  -1.3931  -2.0377   2.0912  -0.7666  -1.6801   0.1901   1.3312  -0.8245  -0.8221   9.1933   2.6121  -0.4925 
+  0.6596   0.5183   0.0656   0.6099   0.2170  -0.2483   0.3752   0.0528  -1.3550  -1.9590  -3.0746  -2.7901   1.7480   0.0667  -1.3253   1.8365   1.2016   0.6331   1.5502   1.2179 
+  1.5180  -2.8697  -3.0225   1.1901   1.2949   1.2425  -0.2655  -1.0124   0.1504   0.9476   0.8294   0.4980  -4.6214  -0.4714   2.3140   0.5042   0.0042   0.6173   0.0250   1.1274 
+  5.2946   0.9166  -1.6961   2.6183   3.7503  -0.5464  -0.4536  -2.5804   0.7239  -3.0443  -0.9745  -0.5296  -1.2153   0.2578  -4.9483   0.2574   1.6442  -1.7218  -1.0182   3.2654 
+ -0.3113   0.1627   0.2010  -0.6825   0.4894   0.3705   0.5406  -0.5307   2.3413   3.1334  -0.2531   0.7289   0.0127   0.8411  -0.5394  -1.5751  -4.4648   3.3442  -1.3619  -2.4473 
+  0.7892   1.6007   2.2451  -0.0142  -1.8268   1.0211   1.1632  -0.4310   0.4809   0.7681  -0.3119  -3.1840   1.8621   0.7982   3.9396   5.5125  -9.0182  -7.2338   1.4720   0.3673 
+  4.5691   3.1984   0.4848  -1.6299  -1.5279  -0.4613  -0.3940  -0.7641  -0.7740  -1.4705  -2.0718  -3.7739  -3.8204  -2.0882   0.9538   2.3794   3.3309   2.1292   0.9829   0.7475 
+ -1.7639  -2.1300   1.8133   5.4637   4.9096   0.4400  -0.2077  -3.2872  -2.8010  -3.3973   1.4612  -0.7884  -0.4468   0.3167   3.0330   3.6546   1.5554  -2.1172  -5.0158  -0.6924 
+ -0.9691   2.1549   0.9464  -1.8955  -2.4830   0.5229   1.0573  -0.1544  -2.7731  -1.7762  -1.2133   0.4997  -0.4040   0.0598   2.1564   0.9676   0.1749  -0.3066   1.3334   2.1020 
+  0.1735  -0.6351  -2.2851   0.3979   2.1071   0.8723  -1.4327   2.7248   2.2122  -3.8366  -6.8693   2.9956   2.2340   0.2392   4.5854   0.8064  -0.4877  -1.9451   0.1604  -2.0173 
+ -3.0467  -2.6229  -0.6828  -1.5402  -4.5504  -0.6274  -1.5654  -1.1048  -5.0244   1.2208   4.3959   1.7152   0.8404   2.3104   3.9110   1.3725   3.6004  -1.5868  -0.0242   3.0095 
+  4.6972  -2.0723   3.7478  -0.0539  -1.3604  -1.6975  -5.1051   4.5477   7.4910   0.8111  -1.5236  -2.0035  -2.3201  -1.9156  -1.8399   2.7039   1.1102   2.7618   0.1987  -8.1775 
+  4.2697   2.1482   1.1807  -0.8188  -0.0158  -0.9415  -3.1934  -7.6652  -5.2761  -0.4096   0.8289  -0.6591  -0.1321  -2.2645   2.6890   3.5308  -0.1860   2.2844   2.1691   2.4613 
+ -2.6176  -1.9646  -0.3365   0.4490   1.7890   3.0096   1.2687   0.1913   0.7099   3.1055   2.4376   1.5156   0.2027  -3.2954  -0.8316   0.6250   2.5125  -1.9645  -4.7360  -2.0703 
+  0.9801  -1.1590  -1.1869  -1.8206  -2.6697  -2.2474  -1.9247   1.3390   0.7955   3.2786   2.1796   1.2439   3.8310   0.9791  -3.7027  -2.0691  -3.3297   3.4700   4.0219  -2.0091 
+ -1.9305   1.1296   2.7892   3.5086  -0.4192   1.8621  -2.4767  -4.5620  -1.3151  -0.4855   0.2130   4.0896  -0.2763   2.9118   1.5789  -0.3477  -0.8200   5.6054  -7.8822  -3.1730 
+  3.5183   4.1815   1.9981  -0.8261  -1.4369  -0.3881   1.0213  -3.8793  -3.6636   2.2621   1.1803   1.7727  -0.7985  -1.2902  -5.0777  -1.2307   0.3381   4.4122  -1.4815  -0.6120 
+  4.0477   1.4256  -1.6604  -3.5999  -1.9136  -0.3445   0.3946   1.6694   1.2905   0.9828   0.5724  -0.1289   1.3498   1.3379   0.2067   0.3656   0.2492  -1.2128  -3.2905  -1.7416 
+ -2.0178  -2.6699  -1.3526   0.2496   0.4148  -0.8854   1.0823  -0.6203   1.2579   0.4148  -2.2346  -0.4015   1.4157   4.8809   6.6230  -3.5608  -1.8735  -4.5603   3.5038   0.3340 
+  1.4937  -1.5420  -2.3850   3.1706   1.4707   0.1938   0.5057   3.8806  -0.0936   0.3334   0.4606   1.4472  -0.9030  -1.4318   3.5118  -5.2689  -1.4235  -1.2997   0.0053  -2.1257 
+ -3.6561   0.1855   0.3705   1.1645   0.2341  -0.8092   2.3980  -0.3274  -0.4576  -1.1851  -3.8496   2.0281  -3.3309   0.9466  -0.0780   1.0318   4.0737   2.6190  -0.3495  -1.0083 
+ -0.1238  -0.3756  -0.3626  -1.1974  -3.0280  -3.3983  -3.5184  -2.8303  -0.2464  -1.0525   0.7469   1.1667   1.9967   2.0536   5.8842   4.6720   0.6593  -0.2270  -1.2558   0.4368 
+  1.4898  -0.0036   2.1872   4.7731   5.3388   2.1104   0.8610  -1.9286  -4.4764  -2.9139  -5.8875   0.1502   2.3687  -3.3444   1.8016   2.0118   0.3480   1.5855  -1.0664  -5.4053 
+ -0.2559  -0.0970   0.6606  -3.0637  -4.0503  -2.5522   0.2345   0.1786  -0.3244  -2.5706   1.7286   2.2086   1.6927   2.7400   1.9340  -0.1619   5.4140   3.6846  -5.1534  -2.2469 
+  0.7337   0.6464  -0.7291  -0.8337  -0.3024   0.3377   1.5178   1.0116   2.5850   0.9759  -1.3970  -3.2182  -3.6906  -0.0798   3.4993  -1.9939  -5.3046   1.4115   4.7666   0.0639 
+ -2.9601  -0.9321  -1.3007  -4.5012  -0.6859   1.6271   0.8938   1.8188   2.7147   2.4868   2.4402   0.6577   1.2040   2.0247   0.2523   1.3499   1.0757  -5.3086  -0.2223  -2.6347 
+  1.2887   2.2547   3.3766   1.8575  -1.7910  -1.7548   1.5265   2.7964   1.2240   1.9720   0.2687   1.8100   3.1328  -2.5860  -2.7821  -3.9778  -2.4086  -2.0066  -0.0746  -4.1265 
+  0.8108  -0.0118   0.3510   0.2469  -0.3564  -0.0688   2.2772   2.9983   0.0220  -0.8672  -4.8310  -2.0824   0.0877   2.2501   0.0661  -8.6456  -1.6422   4.8643   2.3157   2.2152 
+ -2.3502   1.9923   1.6641  -2.2786   3.4633   2.6050  -3.0058   1.5172  -5.3190  -0.9994  -2.4221   0.2495   3.8898  -2.0580   1.1705   0.4058  -1.2798   2.5712  -0.5349   0.7192 
+  5.2963   2.7580   0.0542  -1.8363   0.6217   3.1975   0.8761   0.6926   0.1889  -2.2049  -2.6639  -2.3949  -0.4550   0.9028   0.9417  -2.3200  -1.6049   2.2215  -3.0876  -1.1840 
+  0.0332   0.6867  -0.5444  -2.6560  -2.3272  -1.9975   2.7492   3.4613   1.2531   2.2970   0.6826   1.6161   0.8081  -2.8567  -0.2510   3.1363  -4.7699  -0.8591   1.4746  -1.9362 
+  0.1179   0.1304  -0.0905  -0.0885   0.5876   2.0857  -0.3875  -1.3306  -0.8957  -0.1982   0.8458  -0.0513  -2.2349  -5.5634   7.5385   3.9965  -1.0630  -1.5645  -2.1020   0.2680 
+  1.5416   0.4773  -0.0338   0.6704   0.3091  -0.0982  -0.8312  -1.8586  -2.1668  -3.0698  -3.6621  -2.8717  -0.1465   2.9749   3.0473   2.3156  -0.0362   0.7605   1.1471   1.5312 
+ -1.4651  -1.1492  -0.6700  -0.6012  -0.1247   1.1550  -0.2106  -1.2695  -0.4411   1.1446   4.1491   2.6600   1.3124   1.6069   0.6316  -0.4851  -2.5715  -4.3867  -1.0040   1.7189 
+  0.2437   0.6555   0.3411   0.8466  -1.7425  -0.1636   6.1311   0.6211  -2.7030  -1.5009  -0.1744   0.8660   1.3589   1.2490   1.1273  -2.7402  -0.0949  -1.5440  -1.8610  -0.9159 
+  4.3927   3.3672   0.9009  -1.2521   0.6230  -0.5206   0.8245  -0.9087  -1.8374   0.0097  -3.1469  -2.4307  -3.0482   0.2541   1.9480   5.7092  -3.3716  -3.2953   2.6836  -0.9014 
+  2.2171   0.1913  -1.6779  -0.9585  -1.3241   0.2292   1.4881   2.7969   0.2756  -3.8207  -2.4695  -0.3208   2.3024   2.5414  -0.1815  -0.2933   2.0837   0.9892  -1.0861  -2.9823 
+  0.1186   0.1645  -0.3865  -0.8001  -0.3047  -2.3398  -0.6229  -0.0641   0.8491   1.7026  -1.1341  -2.0704  -0.3123   0.1814   3.8820   1.2943   0.4627  -0.5672   0.5181  -0.5712 
+ -0.1015  -2.3234  -2.3520   0.9949   2.2704   0.9946   0.3560   0.9113   0.1017  -0.4530   0.8520  -1.0302   0.8806   0.3674  -2.6615  -4.8900  -2.9475   1.9045   2.6392   4.4864 
+  2.3941   1.7010   1.9067   0.4931  -1.4348  -2.6074  -1.1597  -1.0504  -3.0460  -2.8157  -0.6597  -0.5920  -0.3406  -1.1230  -0.8586   4.9381   2.8734   1.4518   2.5923  -2.6625 
+ -0.8669   1.9301   3.2551   6.1577   2.0399   2.6785   0.7380  -0.3115   4.7391   1.4868  -6.0175  -7.4317  -4.5623  -0.8590   3.8966  -0.1349  -2.5476  -0.0080  -1.4441  -2.7383 
+ -1.8064   0.5147   0.5800  -2.6271  -3.9359  -2.9321  -2.4785   0.6104  -1.7343  -0.3653  -0.3024   0.2350   2.3057   1.9998   2.2392   1.9124   3.0438  -0.2241   5.1672  -2.2020 
+  1.8580   3.3342   3.0400   1.0670   0.2251   0.5480   1.7906   0.7871   1.2850  -0.3795  -2.0150  -2.3713   0.5611   0.5214  -0.8547   0.0171  -1.8463  -2.7006  -1.7828  -3.0844 
+  1.4841  -0.8100  -2.4242  -1.8509  -0.9746  -1.0553   4.8924   1.3818  -1.8605  -4.3708  -2.0142   6.4457   0.9506  -0.5924   0.1104   2.4175  -0.6754  -0.8459  -0.1554  -0.0530 
+ -0.0877  -0.9877  -1.7358   0.3853   1.1022   1.2975   4.3189  -1.9877  -3.1833   1.0392   0.1796   4.1158   1.4650  -1.6177   1.6123  -4.1615  -3.2584   1.2187  -4.3136   4.5989 
+  0.4487  -0.1107  -2.0381  -0.2337   2.5745   2.8339  -0.0417   1.4413  -1.4483  -1.1675  -6.2515  -6.9360  -3.2717   4.8492   0.9246  -0.9750   4.1724   1.7821   1.3820   2.0655 
+  0.1081  -0.6949   0.1665   0.6685   0.8790   0.7273   0.1766  -0.0005  -0.2218  -0.4294   0.4489  -0.4843   0.2008   2.1975   4.5024  -1.0296  -1.2026  -2.5547  -1.0944  -2.3636 
+  2.3396   2.1543   2.2429   4.7578   0.8390  -0.8895   4.6297   0.4985  -2.3653   2.1787  -1.0612  -0.8953  -6.2919   0.5546  -0.4272  -0.9670  -1.9781  -0.4692  -5.5295   0.6795 
+  0.1530  -2.1926   2.1973   4.5005  -1.3453   1.3286  -2.0310   1.0783  -1.3510  -0.7983   0.6783  -3.4857   5.3977  -3.6561  -3.5986   6.0882   0.1428  -0.9697   3.0219  -5.1583 
+ -2.6086  -0.0766   2.7222   2.0552   2.4096   3.0319   1.0596  -0.1283  -0.8104  -0.2732  -1.4259  -4.0229  -1.4469  -1.6716  -1.1861  -0.9216   0.6780  -0.0004   2.0118   0.6041 
+  1.8333   3.1078  -1.8097   1.1817   3.7643   0.5185   1.9828  -0.3454   1.2321  -1.0494  -6.2996   3.9399  -4.6043   2.7296  -2.2906  -1.7821  -0.5503  -0.1687   1.5615  -2.9514 
+ -1.9822  -1.7870  -2.0807  -0.6471   1.7376  -0.7108  -0.9897   0.1273  -1.5435  -3.4080   1.1979   3.2003   1.0189  -0.9731  -1.0790  -1.9655   3.5511   1.2692   3.4593   1.6049 
+  1.8097   0.7952   2.3044   2.0422   0.0385  -1.4890  -2.6817  -2.4115  -2.0814  -4.7349   1.3168   5.2099   2.0691   0.2209  -0.3967  -1.3910  -0.0825  -1.3970  -1.3074   2.1664 
+ -0.6317  -0.6961  -1.7818   1.7212   1.8896   0.7627   6.4133   0.0239  -2.0812  -0.6340  -0.8745  -0.8436  -3.5167  -3.0992  -0.4403  -5.0217   5.7819   4.7221  -2.9383   1.2443 
+ -0.8542  -4.8873  -5.4381  -4.2630  -4.1290   0.7749   4.7768   0.2842   0.3115  -0.2820   0.2149  -0.1804   0.6193   5.7873   5.1866  -1.3257  -3.0389  -1.9693   8.9711  -0.5589 
+ -1.7203   0.3016   0.2697   0.0913   0.2499   2.9554   0.3320   0.0927  -3.0516   1.3578  -0.8456   1.2764   0.1248   3.9102   2.8147  -2.3847  -6.7532  -2.2614   1.9868   1.2535 
+  2.3588   1.8978   1.0798   1.0217   0.8258  -0.3312   0.8967  -0.1754  -0.3981   1.0150  -0.3879  -0.8493  -1.2690  -1.1797   1.5079  -0.1598  -2.3607   1.1269   2.6480  -7.2674 
+  1.1746   4.6165   5.4940   3.4461  -3.9021  -1.6050  -0.1323  -0.9380  -0.4156  -1.9000  -0.2856  -1.2349  -3.6515  -2.9147   0.0530   1.1469   0.2371  -1.3253   3.8834  -1.7466 
+ -2.2758   1.8844   4.6711   2.2076  -1.3597  -0.4741   0.4627  -0.0358  -0.0017  -1.0258  -0.6957  -1.0270   1.1372  -2.6040  -3.0616  -4.3523   1.6973   1.9314   1.1807   1.7410 
+  1.9665   1.3206  -0.1069   0.8467   1.1209   2.6581   1.0313  -0.7646  -0.9327  -0.4666   1.3979  -1.1019  -2.4235  -8.2049   1.1737   4.9310   0.7484   0.2664  -6.0708   2.6104 
+  1.1852  -1.5416  -3.6491   4.4048  -6.7437   4.6469   1.6802   1.2910   2.2789   2.7610   1.3944  -0.7732  -5.8136   4.4421  -2.2039   0.8414  -5.8722  -4.6747  -3.6578  10.0038 
+ -3.9689  -0.5502   1.1683  -2.1974  -1.9082   0.1416   1.6772   0.3260   3.7162   2.4168   2.6207  -1.7735   1.5236   0.3480  -0.3569   4.1471   1.4471  -0.6226  -8.1997   0.0448 
+  0.6532   1.4910   1.2058   1.7096   2.3950   1.7319  -1.5483  -1.8447  -2.2888   0.7634   3.2796   1.6709  -4.9985  -3.0829  -1.1211   1.2229  -0.2209  -1.1940   1.9569  -1.7811 
+ -1.9523  -4.3005  -4.5837   1.0346   1.2567   1.0099   3.2344   2.8332   1.1895  -1.5164  -2.2052  -1.2334  -1.4331   2.1022   2.3179   5.6712   2.1958  -2.0504  -2.5243  -1.0460 
+ -1.1815  -1.5300  -0.6842  -0.5633  -2.6867  -1.4016   0.6359  -2.0170  -1.2970  -1.6432  -1.0489  -1.3764  -1.1731  -0.5962   3.5229   5.3595   3.1187   3.4061   0.3009   0.8550 
+ -3.1382  -0.6280  -0.8774  -0.9941   0.9435   0.9619   0.8520  -3.3796  -3.2423  -1.3758   3.3040   2.2194   1.0056   2.5348  -0.2996   0.9762  -3.7819  -0.3936   5.7234  -0.4105 
+ -3.2428  -5.3967  -1.5226   4.3711   2.0836   2.1112   0.7032  -4.0183 -12.6551 -15.4852   0.9361   9.2253  10.5424   3.4081   3.4337  -0.7556   1.6657   0.8127   4.5992  -0.8160 
+  1.8248   0.0419   0.5248   1.8646  -1.2814  -2.6618  -0.0669   0.1817   2.2151  -0.8152   5.1179   2.3104   3.6555  -8.7128  -2.0790   1.0629  -0.0963  -1.5473   0.4756  -2.0146 
+ -0.1111   0.3482  -0.0235  -0.7175  -0.1449  -0.3857  -0.8724   0.4592   0.4980   0.2237   0.3924   0.2623  -0.5426   0.9370  -0.6701   0.1600   0.1978   1.4707  -0.4540  -1.0274 
+ -0.9442  -0.4989  -0.2375  -0.5991  -1.2414  -0.4327  -0.2055  -0.5191   2.6955   3.9938  -2.7275   1.8004   1.9744   1.7067  -0.5541  -5.7033   0.6046  -1.4009  -1.3782   3.6669 
+ -0.8575   0.6722   1.8197   2.2695   1.4265  -1.5445  -1.7430  -1.5937   2.0470  -0.1126   0.3473   1.4243   0.9317  -1.3895  -1.0640   0.4664  -0.0706  -3.0958  -1.0532   1.1198 
+  0.9735  -3.1553  -4.9524  -1.8534   0.7715   2.4911   5.1271   0.4320  -4.1146   1.1236   2.7184   2.0135   1.9444   1.7813   1.8232  -2.6267  -5.6361   0.3774   1.0979  -0.3363 
+  1.9497   1.0413  -1.2191  -0.8636   0.0511  -0.3375  -0.5315  -1.0284   2.1218  -5.0828   1.0827  -2.2172  -1.3936   0.4537   3.3006   0.9962  -1.2147   0.0930  -2.8723   5.6705 
+ -3.0064  -0.6690   1.9882   3.1451   0.5101   1.4897   6.0735   3.0322   0.7197   2.5823   0.9024  -1.3595  -0.6102  -4.4164  -5.2345   0.5038  -1.7243  -1.0135   0.3868  -3.2999 
+ -1.3127  -0.5603  -0.4395  -0.5779  -1.3273  -0.7737   1.1446   2.1363   0.5709  -0.9646   0.1742  -0.3429   0.7079  -1.3617  -0.1807   0.8278   4.5177  -3.6128   1.9484  -0.5738 
+  4.9592   5.5662  -1.4308   2.4625  -1.3728   0.3179   2.5142  -3.1176  -3.0793   2.5866  -6.0767  -3.0209  -1.0428   3.7946   3.4423  -3.9407   3.8680  -5.8781  -3.2612   2.7097 
+  1.8752   4.6096   2.6992   0.0622   1.9683  -1.5159  -0.2846   2.0429   5.1916   0.0415   0.4228   0.2499  -1.8859  -1.2282  -1.8414  -3.2239  -2.8594  -2.2718  -1.9470  -2.1050 
+ -0.4172  -0.0660  -0.7815  -1.3234   1.6425   1.5960   0.1952   2.8005   1.8348  -0.0556  -1.7528  -0.3330   2.5351   3.2175  -0.0237  -2.6102  -2.3993  -0.4569   0.2104  -3.8124 
+  0.5340  -7.1325   7.3739  -7.1474   5.0035   4.0837   1.7481   0.6285   2.1470   3.3649   3.4871  -4.6213   5.3643  -0.8361   2.3067  -0.6517  -4.1528  -4.1599  -0.0969  -7.2432 
+  6.4977  -1.8922   6.0123   2.6649   3.9019  -2.9401  -5.9544   6.5995  -3.7727  -1.3909  -4.1986   0.3151   1.1248   0.2299   1.4836  -7.4381   0.2549   4.7727  -2.9947  -3.2755 
+  0.0546   0.0075   0.5596   0.2523  -2.3268  -4.5642  -3.6799  -0.8395   2.7336   3.7088   2.7486   2.6118   1.5065   0.0463   0.4170  -0.5592   1.5006  -0.4534  -1.6715  -2.0529 
+  2.9815   2.4495   1.7545   3.2822   2.8844   2.5666   0.0398   1.6192   2.6128   3.3153  -4.7284  -2.6356  -1.7561  -4.3333  -3.6328  -2.9815  -0.9212  -0.8755  -0.3601  -1.2811 
+ -0.8024   1.2002   3.2220  -0.7626  -2.1102  -1.0525  -1.8044   0.6518  -0.3024   1.2038   0.2348   0.2257  -2.8991  -1.6610   1.3306  -0.9177  -2.5629  -0.6077   5.6868   1.7272 
+ -0.1833  -0.3751   0.5635   0.1503  -0.2949  -0.6821   1.4873  -1.2805  -1.3007  -0.6803   0.0098   0.9789   1.7868   3.5914   0.8184   1.0857   6.4677  -3.3457  -6.7060  -2.0913 
+  4.2126   1.0339  -0.8906   0.9053   2.8206   3.1913   0.4808   1.7342   1.1617   0.7387   3.7928  -0.7288  -6.1883  -1.6937  -4.9005  -3.6291  -0.7611  -1.4035  -0.2407   0.3643 
+ -8.3754  -2.2519   1.3080   1.8062   0.8850   1.6497   2.0880   2.7261   0.2633  -0.5998   0.5979   0.7034   0.9960   2.9711   0.1650   0.8745  -0.1614  -0.6875  -1.3556  -3.6024 
+  1.4188   1.0202   1.5256   1.6620   0.7476  -1.4390  -3.4051  -1.8780   0.4521  -3.9741   0.7867  -0.3719  -2.3721  -1.0437   0.6801  -0.2011  -3.0818   2.9062   4.2361   2.3315 
+  0.1054  -2.6122  -4.3807  -5.3145  -0.2846   4.3842   3.0170   3.8061   0.7110  -1.0498  -0.2574  -0.9802   0.3402   1.2503   2.5457  -7.8042  -0.1469   2.8259   3.0062   0.8386 
+  5.2058   7.1080   4.9534  -1.2430  -6.6855  -3.7117  -6.1961  -2.1515  -0.5576  -1.6169   5.7678   7.7780  -3.9195   1.0323  -4.8749   2.1979  -6.6948   5.7018  -1.1809  -0.9126 
+  5.0054   3.2246   2.7220   2.5774   0.3515  -0.4988  -0.6659  -1.1531  -0.3512  -0.2899  -1.1677   0.8076  -0.0710  -1.3279  -1.8820  -2.0262  -1.5275  -2.2770  -2.2582   0.8080 
+ -0.3421  -2.1542  -1.9404   1.9715   2.0717   1.2690  -0.5900   2.8831   2.5295  -0.0718   1.0132  -2.1895   0.9449   0.2787   2.8471   3.2171  -2.0622  -4.9892  -4.8142   0.1278 
+ -3.5648  -4.5220  -3.8219  -0.0484   2.5590   3.3348   4.6892   3.0890   3.1738   2.4402  -0.3648  -2.0478  -1.8476   0.1171  -0.1749  -2.2364   0.1988  -2.2378   0.6726   0.5920 
+ -2.5566  -0.8410  -0.4280  -0.4406  -0.5726  -0.3279  -1.8710  -2.4830   2.8140   4.1548  -1.1877  -1.2228   1.1741   0.7041  -4.1128   0.8974   1.6460   2.7315   1.4956   0.4265 
+  0.6395   0.6244   0.2175   0.2548  -0.6436  -1.4509  -1.2471  -1.8889  -1.6984   0.6300  -0.0902  -1.4274   1.6267   2.2897  -1.4907  -1.0863  -0.5990  -0.3234   4.5402   1.1229 
+ -3.0281  -3.4576   0.2465   1.1848  -0.3128  -1.4112  -1.7883  -2.4368  -3.6604   0.2309   4.1432   0.2306   3.9874   1.3414  -2.9661   0.2318   1.3943   2.8996   1.0512   2.1197 
+ -6.4523  -0.8108   3.0394   2.9265   1.7276  -0.6852  -1.3401  -1.2086   0.2339   0.6323   0.9584  -0.4322  -0.4865   1.1438   3.9792  -0.5978  -3.3409  -0.0134   0.1557   0.5712 
+  0.8836   0.6632  -0.5682   1.0909   1.0200   0.2143   1.7898   0.4314  -1.2105  -1.6888  -2.8939   1.5904   1.4323   5.0287  -2.4090  -2.6282  -1.2927  -1.8499  -3.8726   4.2691 
+  2.7571   0.5054   0.5914  -0.4593  -1.9535  -2.8534  -5.1043  -5.0146   0.3167   1.9210   1.9920   1.2596   1.2329  -1.0134  -2.2148  -0.9619   3.3405   0.4893   1.9185   3.2509 
+ -7.8257  -8.0514  -2.2922   4.6049   1.7841   0.2877   2.4600   0.2299   0.3961   0.7952   4.9841   0.5914  -3.3601   1.4043   5.5671   2.2508   0.0018   1.5100  -2.0511  -3.2867 
+  1.5686   1.2169  -0.6391  -2.6751  -3.0325  -3.9104  -2.5516  -0.9763   6.3909  -1.3255   1.3817   1.7409   2.2064   2.8908   0.3118   0.3554   0.3092  -0.0695  -2.5566  -0.6363 
+  1.1784   0.7886   1.7506   3.8841   0.1097  -3.4846  -1.1668  -0.2517  -0.3004  -0.0493   2.0270   0.2092   1.5440   3.4255   0.2943  -0.8517  -1.6072  -4.0976  -5.8976   2.4958 
+  0.9988   2.8848   3.2891   3.3681   1.4676   3.2906   1.3735   1.1970   0.4611  -0.5875   1.7464   0.9583   0.5681  -1.4825  -4.2976  -3.2226  -2.3712  -7.0782  -2.8558   0.2917 
+ -0.2746  -0.1545  -0.1213  -1.7658  -0.9647  -0.8990  -2.2776  -1.6043   2.1487   5.2377  -7.3002  -1.2976   0.8951   2.6087   1.9104   0.8944   4.2107   2.4289  -0.6124  -3.0624 
+  4.5993   2.8908   2.6348   2.5753   3.5423  -1.3467  -3.6340  -1.3719  -1.5896  -1.7807   0.4182  -0.4869  -0.0081  -1.7322  -5.0302  -4.0281   3.2297   0.1854   0.7317   0.2006 
+ -3.2143  -2.4079   2.3832  -1.4835  -2.9589  -4.3471  -9.4701  -8.6980   2.2131  11.9939   3.4222   5.6731   1.0493   0.9347   3.1770   3.6996  -0.0115   2.2951  -2.8928  -1.3571 
+  2.2986   0.5686  -2.7234   0.0628   3.3595   3.0322   1.2528   0.1697   0.2877  -3.1109  -4.5198   4.2898   4.5477  -0.5365  -2.9437  -1.7760  -3.4896  -0.4971   0.5506  -0.8230 
+  0.0226  -1.9088  -4.1034  -3.5139   1.8311   6.6465   1.9042  -0.2585   0.4811  -1.3603  -0.8669  -2.6469  -2.4021  -2.3699  -1.0708   1.8059   0.3697   0.3642   3.4726   3.6036 
+  1.8666   0.3455  -0.4415   1.4530   2.1752   0.4141   0.9988   0.9339   2.0369   0.0808  -1.3138  -1.2683   0.1032   0.3074   0.3794  -2.2480  -4.4451  -2.7006   1.2456   0.0770 
+ -0.9714   0.8948  -0.5528  -1.5023  -2.1884  -1.6190  -2.6643   0.3765   5.2588   1.9474   4.7336   6.0668   0.9206  -6.1173   0.2687   4.2344  -2.7801   4.7836  -5.9468  -5.1428 
+ -3.5447  -2.6492  -1.1225   1.1104  -0.6763  -0.3734   0.7874   2.9348   3.7914   3.3802  -3.0687  -1.7645  -1.7552   0.4322   1.5566   3.1434  -2.9717   0.2913   0.3294   0.1693 
+  2.3099  -0.6833  -2.4051  -0.8700  -0.1793  -0.7055  -1.1773   0.0766  -2.2742  -3.5734  -2.1986   0.6775   0.1605   0.0083   4.2284   1.3025   3.7892  -0.0746  -0.9582   2.5465 
+  0.9486   0.1048   1.8316   3.4918   2.1758   1.1342   1.0848   2.4632   0.0993  -1.9453  -1.1703  -1.6274  -2.0353   0.8991   0.4736  -4.0911  -2.9565  -2.3552  -2.1133   3.5874 
+  0.6208   3.4997   6.2697   4.2107   1.2652   2.1894   1.1355  -2.5271  -2.9525   0.0535   0.3829  -2.5199  -2.9063  -2.7287  -1.9607   1.4600   1.2748   0.4400  -4.8467  -2.3602 
+  0.5243   2.9289   2.2684   0.4191  -2.1542  -0.2881  -0.2706   0.6758   5.4475   1.1883  -2.5477  -6.5024  -4.1506   0.6656   0.9576  -1.2352   1.0736  -4.8441   2.5699   3.2741 
+ -0.7794   1.1463   3.5016   1.1120   0.8485  -1.0628  -0.8132   3.8405  -0.3344   1.2653   0.4357   0.5494  -2.5741  -2.4964  -3.4166  -4.9706   4.8271  -4.7341   1.1838   2.4711 
+  1.8447   1.0979  -1.7573   0.3863  -0.5133  -3.1578   0.0583  -0.5417   4.1974  -4.6030   0.1241  -3.2329   4.6242  -4.6647  -2.4610   0.5959   3.2183  -1.2626   5.6612   0.3859 
+ -2.3894  -1.0328   1.7896   5.5648   5.2220   1.8869   1.0956  -0.1977   3.2983   0.9466  -2.0813  -0.1679  -0.5816  -0.1714  -2.7510   1.1951   1.5496   1.6400  -5.0073  -9.8080 
+  0.7738  -1.7298  -3.2257  -0.3183   1.9284   1.7227   0.8166   0.9095   0.5332  -0.5016  -1.2660  -1.9608   2.0035  -2.6922   3.7039   0.8905  -0.7247   2.7531  -3.0591  -0.5571 
+ -0.0748  -0.5070  -0.2516   1.7723   1.4041   4.3520   1.7022   1.0990  -1.4641  -2.3620   3.1174   0.5476   1.5192  -1.9294  -4.9678   0.2919  -3.1451   1.3976  -0.5997  -1.9017 
+ -0.3043  -4.5751  -6.4864  -2.8079   2.8553   1.4264  -0.6290   0.8259   1.1617  -0.8255  -1.1913  -0.9336  -0.8179  -0.6841   2.7254   1.9190   4.4832   2.4919   2.0452  -0.6788 
+  2.9368   3.5644   3.7164   3.7726   0.3148  -2.5071  -1.0177   0.4365   0.4818  -2.1099  -3.0728  -1.1823  -1.8323  -2.5460  -3.2217  -2.5081   0.1068  -0.3340   2.0018   3.0001 
+  2.0122  -0.8437  -0.0894  -3.5669   0.2151   1.3672  -1.1852   2.2748   0.2674   2.1266  -4.5961  -3.5181   1.6410   4.2095  -4.0873   0.0362   3.5548  -2.6567   1.8468   0.9915 
+ -2.9528   1.3693   1.3737   3.6447   4.6399   3.0004  -0.4081  -0.5069  -2.0885  -2.1563   0.7639   0.4790  -2.4821   1.6495   0.8280  -0.4457  -4.8607   3.5285   3.1896  -8.5655 
+ -4.4449  -2.6584  -0.3396   2.7055   3.1313   2.6691  -0.1405  -2.6920   1.1380   5.9263   0.1508  -2.5031  -2.5963  -2.2339  -0.4387   2.7348   0.1166  -2.0958  -0.1884   1.7591 
+ -0.4506  -2.2585  -2.0183  -1.2141   2.3804   5.1371  -0.1012   0.7185  -1.9558  -5.5843   1.7274   2.5676   1.3295  -2.3148   3.4722   0.9168   0.3809  -1.2468  -0.6805  -0.8055 
+ -0.5741  -1.3187  -1.6054  -1.8387  -3.0009  -2.2631   1.6411   1.0542   0.8630   1.3059   0.6660   0.5171  -0.9355  -1.8837   0.8703   0.3850  -0.0855   0.2754   4.4605   1.4674 
+  4.0853   2.9178   0.0251  -1.7053  -2.9819  -2.0918  -1.9947  -0.8293  -0.6373   0.5052   2.1796   2.6733  -1.7046  -0.6344   1.3620  -0.4864  -2.0884  -1.6708   1.5012   1.5754 
+ -1.5635   2.8252  -0.9149  -3.0463  -4.7327   2.7084   1.1209   0.7968   0.7865  -1.2527  -0.1248   2.6941   2.7972   2.2336  -0.0652  -0.4532  -2.9265  -0.0560  -0.4324  -0.3945 
+  2.4620   0.7164  -1.5674  -3.1513  -1.6402   2.4149   2.9010   2.5761   3.2262   0.0749  -4.5314  -3.4112   0.2922   1.0743   0.0408  -1.5976  -0.5032   0.6577   0.7598  -0.7940 
+  1.9710   1.1730  -0.6838  -2.2094  -1.9356   1.4952  -2.0825  -0.2927   0.7657  -1.8337   4.4472  -3.8324   0.7557   0.0732  -3.6271  -1.9071   4.3140   2.4552  -0.0317   0.9857 
+  3.7325   2.7934   1.0157  -1.7096  -2.8454  -1.8953  -0.7562   0.3146  -0.3781  -1.0020  -1.6158  -0.3984  -0.0573   0.9972   1.0112  -1.0599   0.0370   3.6124   1.1087  -2.9047 
+ -1.4832  -1.9899  -0.8731  -0.9330  -2.9066   2.3820  -0.1603  -0.7170  -1.1285  -0.9274   2.1578   6.4011  -1.6535   2.3099  -1.6654   3.7268   0.0883  -1.8527  -0.5184  -0.2568 
+  0.6353   1.3687   1.8257   0.3226  -0.8766   1.0000   1.0853   1.2934   0.8779   1.7553   1.1543  -2.0442  -1.6763  -0.4593   0.9294  -1.2072  -2.2593  -0.6144  -2.8074  -0.3032 
+ -1.2070  -1.3475  -1.8312  -1.7806  -2.9611  -3.1818   2.9332  -0.1240   0.1906   2.9202  -1.8371   1.0525  -2.0319   2.7074  -2.1979  -1.3072  -0.5591   3.0013   2.6600   4.9011 
+ -5.1303   3.3870  -3.7967  -1.9466  -5.3864  -1.1368  -0.5684   3.7351  -0.5755  -3.2378  -4.4250   2.0350   3.9372   5.4701  -2.7768   5.9464   6.6849  -3.7875   1.9948  -0.4230 
+ -1.3037  -1.9678  -3.1520  -1.4018   0.2092   2.8010   2.0760  -0.3324   1.0911   0.9050   1.7187   3.4255   1.0022   3.5722  -3.5224  -4.7658  -1.0745   0.2766   1.2898  -0.8471 
+  1.9772  -2.9635  -3.0240  -2.2547   0.1703   1.7771  -1.6073  -3.1859   1.5410   1.4356   0.9203   3.9297   4.2495   5.7007  -4.0193  -0.8612   1.6423   0.8844  -5.1605  -1.1517 
+  2.9132   0.8992  -1.0688  -1.5448  -0.9185   0.4003  -1.7700  -2.7768  -1.4639   0.2261   0.7139   1.7997   3.0514   3.3204   0.6803   0.9792  -0.2717  -2.6450  -0.2252  -2.2988 
+ -2.9741  -2.4804  -3.0116  -3.1521   0.1074   1.3714   0.6662   2.0637   1.7849  -0.4611  -0.7720  -1.6172   0.8203   3.4203   0.8069   2.2581   3.2451   0.5915  -2.2429  -0.4245 
+ -0.8028  -0.2290   0.2137  -0.4319   0.5580   0.2543   0.9172   0.8892  -0.4807  -1.2827   0.9202   1.1454  -1.6931  -3.6479   0.4568   3.9049   1.2435   2.6145   0.7928  -5.3425 
+  2.6190   1.9162   0.9769  -0.1078  -0.4290  -0.3650  -2.8284  -4.4494  -5.9910  -4.8405   0.7110  -0.4595   0.2195   3.3942   0.9527  -1.8867   3.8742   3.7699   1.2150   1.7087 
+  1.8829   0.7201   0.6607  -0.0626  -1.1940  -1.4411  -0.0944   0.1172  -0.7491  -0.3712  -2.5287  -2.1899  -1.2280  -1.4906  -0.5689  -1.4885   2.7842   4.0586  -1.1367   4.3200 
+  4.6710   0.9897  -0.6156  -0.6851  -1.4120   4.1532   4.4321   1.1339  -1.0985   0.5736   1.4085  -4.6356  -3.3117  -1.5968  -3.4345  -0.7293  -0.0528  -0.3096  -3.6684   4.1880 
+ -2.5398  -1.3830   0.0979   1.9654   3.5192  -0.0522  -3.2870  -3.8507   0.6356  -0.9850  -3.0198  -3.7269  -0.8310   1.9829   1.8339  -0.8073   0.2152   2.0459   6.1180   2.0688 
+  0.4962   3.2227   3.5953   1.3395  -3.4218  -4.9933  -1.9981   0.9513  -1.0998  -2.7535   1.3298  -0.6976   0.0716   0.7392   5.8854  -4.3047   2.1890   1.9699  -2.4444  -0.0765 
+ -5.8327   1.1129   0.8081   5.6003   5.5684   4.7020   2.8089   0.4347   1.1649  -4.9188 -11.4465  -1.3196   0.4225  -2.4705   0.3286  -0.0113   8.7340  -2.1220  -2.1264  -1.4373 
+ -1.6231  -1.3969  -2.0111  -1.2620   4.3084  -1.2012   1.2341   0.1866   0.0635  -2.6548   2.3896   1.8088   0.0290  -4.3105   3.9166  -0.0331  -0.3748  -2.4710   1.0435   2.3583 
+  0.6310   1.3989   1.5277   0.7608   1.0894   1.7235   2.0681   2.3537   0.9918   1.2164  -0.3325  -2.2666   0.1756   0.1615   0.5196  -2.6730  -7.1201  -2.9272  -5.4551   6.1563 
+  7.8768   5.4153  -2.5369   0.0405   4.1259  -0.2108  -4.6599  -0.9803  -1.3472  -5.5873   0.0334  -6.0975  -0.7915   0.7551  -0.1575   2.8766  -3.5702  -0.2561   4.0100   1.0615 
diff --git a/codec2/branches/0.7/src/codebookd.c b/codec2/branches/0.7/src/codebookd.c
new file mode 100644 (file)
index 0000000..5816402
--- /dev/null
@@ -0,0 +1,433 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* codebook/dlsp1.txt */
+static const float codes0[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800
+};
+  /* codebook/dlsp2.txt */
+static const float codes1[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800
+};
+  /* codebook/dlsp3.txt */
+static const float codes2[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800
+};
+  /* codebook/dlsp4.txt */
+static const float codes3[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  250,
+  300,
+  350,
+  400,
+  450,
+  500,
+  550,
+  600,
+  650,
+  700,
+  750,
+  800,
+  850,
+  900,
+  950,
+  1000,
+  1050,
+  1100,
+  1150,
+  1200,
+  1250,
+  1300,
+  1350,
+  1400
+};
+  /* codebook/dlsp5.txt */
+static const float codes4[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  250,
+  300,
+  350,
+  400,
+  450,
+  500,
+  550,
+  600,
+  650,
+  700,
+  750,
+  800,
+  850,
+  900,
+  950,
+  1000,
+  1050,
+  1100,
+  1150,
+  1200,
+  1250,
+  1300,
+  1350,
+  1400
+};
+  /* codebook/dlsp6.txt */
+static const float codes5[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  250,
+  300,
+  350,
+  400,
+  450,
+  500,
+  550,
+  600,
+  650,
+  700,
+  750,
+  800,
+  850,
+  900,
+  950,
+  1000,
+  1050,
+  1100,
+  1150,
+  1200,
+  1250,
+  1300,
+  1350,
+  1400
+};
+  /* codebook/dlsp7.txt */
+static const float codes6[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800
+};
+  /* codebook/dlsp8.txt */
+static const float codes7[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800
+};
+  /* codebook/dlsp9.txt */
+static const float codes8[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800
+};
+  /* codebook/dlsp10.txt */
+static const float codes9[] = {
+  25,
+  50,
+  75,
+  100,
+  125,
+  150,
+  175,
+  200,
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700,
+  725,
+  750,
+  775,
+  800
+};
+
+const struct lsp_codebook lsp_cbd[] = {
+  /* codebook/dlsp1.txt */
+  {
+    1,
+    5,
+    32,
+    codes0
+  },
+  /* codebook/dlsp2.txt */
+  {
+    1,
+    5,
+    32,
+    codes1
+  },
+  /* codebook/dlsp3.txt */
+  {
+    1,
+    5,
+    32,
+    codes2
+  },
+  /* codebook/dlsp4.txt */
+  {
+    1,
+    5,
+    32,
+    codes3
+  },
+  /* codebook/dlsp5.txt */
+  {
+    1,
+    5,
+    32,
+    codes4
+  },
+  /* codebook/dlsp6.txt */
+  {
+    1,
+    5,
+    32,
+    codes5
+  },
+  /* codebook/dlsp7.txt */
+  {
+    1,
+    5,
+    32,
+    codes6
+  },
+  /* codebook/dlsp8.txt */
+  {
+    1,
+    5,
+    32,
+    codes7
+  },
+  /* codebook/dlsp9.txt */
+  {
+    1,
+    5,
+    32,
+    codes8
+  },
+  /* codebook/dlsp10.txt */
+  {
+    1,
+    5,
+    32,
+    codes9
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebookdt.c b/codec2/branches/0.7/src/codebookdt.c
new file mode 100644 (file)
index 0000000..035cd63
--- /dev/null
@@ -0,0 +1,153 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* codebook/lspdt1.txt */
+static const float codes0[] = {
+  -75,
+  -50,
+  -25,
+  0,
+  25,
+  50,
+  75,
+  100
+};
+  /* codebook/lspdt2.txt */
+static const float codes1[] = {
+  -75,
+  -50,
+  -25,
+  0,
+  25,
+  50,
+  75,
+  100
+};
+  /* codebook/lspdt3.txt */
+static const float codes2[] = {
+  -50,
+  0,
+  50,
+  100
+};
+  /* codebook/lspdt4.txt */
+static const float codes3[] = {
+  -50,
+  0,
+  50,
+  100
+};
+  /* codebook/lspdt5.txt */
+static const float codes4[] = {
+  -50,
+  0,
+  50,
+  100
+};
+  /* codebook/lspdt6.txt */
+static const float codes5[] = {
+  -50,
+  0,
+  50,
+  100
+};
+  /* codebook/lspdt7.txt */
+static const float codes6[] = {
+  -50,
+  50
+};
+  /* codebook/lspdt8.txt */
+static const float codes7[] = {
+  -50,
+  50
+};
+  /* codebook/lspdt9.txt */
+static const float codes8[] = {
+  -50,
+  50
+};
+  /* codebook/lspdt10.txt */
+static const float codes9[] = {
+  -50,
+  50
+};
+
+const struct lsp_codebook lsp_cbdt[] = {
+  /* codebook/lspdt1.txt */
+  {
+    1,
+    3,
+    8,
+    codes0
+  },
+  /* codebook/lspdt2.txt */
+  {
+    1,
+    3,
+    8,
+    codes1
+  },
+  /* codebook/lspdt3.txt */
+  {
+    1,
+    2,
+    4,
+    codes2
+  },
+  /* codebook/lspdt4.txt */
+  {
+    1,
+    2,
+    4,
+    codes3
+  },
+  /* codebook/lspdt5.txt */
+  {
+    1,
+    2,
+    4,
+    codes4
+  },
+  /* codebook/lspdt6.txt */
+  {
+    1,
+    2,
+    4,
+    codes5
+  },
+  /* codebook/lspdt7.txt */
+  {
+    1,
+    1,
+    2,
+    codes6
+  },
+  /* codebook/lspdt8.txt */
+  {
+    1,
+    1,
+    2,
+    codes7
+  },
+  /* codebook/lspdt9.txt */
+  {
+    1,
+    1,
+    2,
+    codes8
+  },
+  /* codebook/lspdt10.txt */
+  {
+    1,
+    1,
+    2,
+    codes9
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebookge.c b/codec2/branches/0.7/src/codebookge.c
new file mode 100644 (file)
index 0000000..5bcb623
--- /dev/null
@@ -0,0 +1,279 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* codebook/gecb.txt */
+static const float codes0[] = {
+  2.71,  12.0184,
+  0.04675,  -2.73881,
+  0.120993,  8.38895,
+  -1.58028,  -0.892307,
+  1.19307,  -1.91561,
+  0.187101,  -3.27679,
+  0.332251,  -7.66455,
+  -1.47944,  31.2461,
+  1.52761,  27.7095,
+  -0.524379,  5.25012,
+  0.55333,  7.4388,
+  -0.843451,  -1.95299,
+  2.26389,  8.61029,
+  0.143143,  2.36549,
+  0.616506,  1.28427,
+  -1.71133,  22.0967,
+  1.00813,  17.3965,
+  -0.106718,  1.41891,
+  -0.136246,  14.2736,
+  -1.70909,  -20.5319,
+  1.65787,  -3.39107,
+  0.138049,  -4.95785,
+  0.536729,  -1.94375,
+  0.196307,  36.8519,
+  1.27248,  22.5565,
+  -0.670219,  -1.90604,
+  0.382092,  6.40113,
+  -0.756911,  -4.90102,
+  1.82931,  4.6138,
+  0.318794,  0.73683,
+  0.612815,  -2.07505,
+  -0.410151,  24.7871,
+  1.77602,  13.1909,
+  0.106457,  -0.104492,
+  0.192206,  10.1838,
+  -1.82442,  -7.71565,
+  0.931346,  4.34835,
+  0.308813,  -4.086,
+  0.397143,  -11.8089,
+  -0.048715,  41.2273,
+  0.877342,  35.8503,
+  -0.759794,  0.476634,
+  0.978593,  7.67467,
+  -1.19506,  3.03883,
+  2.63989,  -3.41106,
+  0.191127,  3.60351,
+  0.402932,  1.0843,
+  -2.15202,  18.1076,
+  1.5468,  8.32271,
+  -0.143089,  -4.07592,
+  -0.150142,  5.86674,
+  -1.40844,  -3.2507,
+  1.56615,  -10.4132,
+  0.178171,  -10.2267,
+  0.362164,  -0.028556,
+  -0.070125,  24.3907,
+  0.594752,  17.4828,
+  -0.28698,  -6.90407,
+  0.464818,  10.2055,
+  -1.00684,  -14.3572,
+  2.32957,  -3.69161,
+  0.335745,  2.40714,
+  1.01966,  -3.15565,
+  -1.25945,  7.9919,
+  2.38369,  19.6806,
+  -0.094947,  -2.41374,
+  0.20933,  6.66477,
+  -2.22103,  1.37986,
+  1.29239,  2.04633,
+  0.243626,  -0.890741,
+  0.428773,  -7.19366,
+  -1.11374,  41.3414,
+  2.6098,  31.1405,
+  -0.446468,  2.53419,
+  0.490104,  4.62757,
+  -1.11723,  -3.24174,
+  1.79156,  8.41493,
+  0.156012,  0.183336,
+  0.532447,  3.15455,
+  -0.764484,  18.514,
+  0.952395,  11.7713,
+  -0.332567,  0.346987,
+  0.202165,  14.7168,
+  -2.12924,  -15.559,
+  1.35358,  -1.92679,
+  -0.010963,  -16.3364,
+  0.399053,  -2.79057,
+  0.750657,  31.1483,
+  0.655743,  24.4819,
+  -0.45321,  -0.735879,
+  0.2869,  6.5467,
+  -0.715673,  -12.3578,
+  1.54849,  3.87217,
+  0.271874,  0.802339,
+  0.502073,  -4.85485,
+  -0.497037,  17.7619,
+  1.19116,  13.9544,
+  0.01563,  1.33157,
+  0.341867,  8.93537,
+  -2.31601,  -5.39506,
+  0.75861,  1.9645,
+  0.24132,  -3.23769,
+  0.267151,  -11.2344,
+  -0.273126,  32.6248,
+  1.75352,  40.432,
+  -0.784011,  3.04576,
+  0.705987,  5.66118,
+  -1.3864,  1.35356,
+  2.37646,  1.67485,
+  0.242973,  4.73218,
+  0.491227,  0.354061,
+  -1.60676,  8.65895,
+  1.16711,  5.9871,
+  -0.137601,  -12.0417,
+  -0.251375,  10.3972,
+  -1.43151,  -8.90411,
+  0.98828,  -13.209,
+  0.261484,  -6.35497,
+  0.395932,  -0.702529,
+  0.283704,  26.8996,
+  0.420959,  15.4418,
+  -0.355804,  -13.7278,
+  0.527372,  12.3985,
+  -1.16956,  -15.9985,
+  1.90669,  -5.81605,
+  0.354492,  3.85157,
+  0.82576,  -4.16264,
+  -0.49019,  13.0572,
+  2.25577,  13.5264,
+  -0.004956,  -3.23713,
+  0.026709,  7.86645,
+  -1.81037,  -0.451183,
+  1.08383,  -0.18362,
+  0.135836,  -2.26658,
+  0.375812,  -5.51225,
+  -1.96644,  38.6829,
+  1.97799,  24.5655,
+  -0.704656,  6.35881,
+  0.480786,  7.05175,
+  -0.976417,  -2.42273,
+  2.50215,  6.75935,
+  0.083588,  3.2588,
+  0.543629,  0.910013,
+  -1.23196,  23.0915,
+  0.785492,  14.807,
+  -0.213554,  1.688,
+  0.004748,  18.1718,
+  -1.54719,  -16.1168,
+  1.50104,  -3.28114,
+  0.080133,  -4.63472,
+  0.476592,  -2.18093,
+  0.44247,  40.304,
+  1.07277,  27.592,
+  -0.594738,  -4.16681,
+  0.42248,  7.61609,
+  -0.927521,  -7.27441,
+  1.99162,  1.29636,
+  0.291307,  2.39878,
+  0.721081,  -1.95062,
+  -0.804256,  24.9295,
+  1.64839,  19.1197,
+  0.060852,  -0.590639,
+  0.266085,  9.10325,
+  -1.9574,  -2.88461,
+  1.11693,  2.6724,
+  0.35458,  -2.74854,
+  0.330733,  -14.1561,
+  -0.527851,  39.5756,
+  0.991152,  43.195,
+  -0.589619,  1.26919,
+  0.787401,  8.73071,
+  -1.0138,  1.02507,
+  2.8254,  1.89538,
+  0.24089,  2.74557,
+  0.427195,  2.54446,
+  -1.95311,  12.244,
+  1.44862,  12.0607,
+  -0.210492,  -3.37906,
+  -0.056713,  10.204,
+  -1.65237,  -5.10274,
+  1.29475,  -12.2708,
+  0.111608,  -8.67592,
+  0.326634,  -1.16763,
+  0.021781,  31.1258,
+  0.455335,  21.4684,
+  -0.37544,  -3.37121,
+  0.39362,  11.302,
+  -0.851456,  -19.4149,
+  2.10703,  -2.22886,
+  0.373233,  1.92406,
+  0.884438,  -1.72058,
+  -0.975127,  9.84013,
+  2.0033,  17.3954,
+  -0.036915,  -1.11137,
+  0.148456,  5.39997,
+  -1.91441,  4.77382,
+  1.44791,  0.537122,
+  0.194979,  -1.03818,
+  0.495771,  -9.95502,
+  -1.05899,  32.9471,
+  2.01122,  32.4544,
+  -0.30965,  4.71911,
+  0.436082,  4.63552,
+  -1.23711,  -1.25428,
+  2.02274,  9.42834,
+  0.190342,  1.46077,
+  0.479017,  2.48479,
+  -1.07848,  16.2217,
+  1.20764,  9.65421,
+  -0.258087,  -1.67236,
+  0.071852,  13.416,
+  -1.87723,  -16.072,
+  1.28957,  -4.87118,
+  0.067713,  -13.4427,
+  0.435551,  -4.1655,
+  0.46614,  30.5895,
+  0.904895,  21.598,
+  -0.518369,  -2.53205,
+  0.337363,  5.63726,
+  -0.554975,  -17.4005,
+  1.69188,  1.14574,
+  0.227934,  0.889297,
+  0.587303,  -5.72973,
+  -0.262133,  18.6666,
+  1.39505,  17.0029,
+  -0.01909,  4.30838,
+  0.304235,  12.6699,
+  -2.07406,  -6.46084,
+  0.920546,  1.21296,
+  0.284927,  -1.78547,
+  0.209724,  -16.024,
+  -0.636067,  31.5768,
+  1.34989,  34.6775,
+  -0.971625,  5.30086,
+  0.590249,  4.44971,
+  -1.56787,  3.60239,
+  2.1455,  4.51666,
+  0.296022,  4.12017,
+  0.445299,  0.868772,
+  -1.44193,  14.1284,
+  1.35575,  6.0074,
+  -0.012814,  -7.49657,
+  -0.43,  8.50012,
+  -1.20469,  -7.11326,
+  1.10102,  -6.83682,
+  0.196463,  -6.234,
+  0.436747,  -1.12979,
+  0.141052,  22.8549,
+  0.290821,  18.8114,
+  -0.529536,  -7.73251,
+  0.63428,  10.7898,
+  -1.33472,  -20.3258,
+  1.81564,  -1.90332,
+  0.394778,  3.79758,
+  0.732682,  -8.18382,
+  -0.741244,  11.7683
+};
+
+const struct lsp_codebook ge_cb[] = {
+  /* codebook/gecb.txt */
+  {
+    2,
+    8,
+    256,
+    codes0
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebookjvm.c b/codec2/branches/0.7/src/codebookjvm.c
new file mode 100644 (file)
index 0000000..86f5b83
--- /dev/null
@@ -0,0 +1,1579 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* codebook/lspjvm1.txt */
+static const float codes0[] = {
+  0.435217,  0.668864,  1.0103,  1.22042,  1.50398,  1.78468,  2.13546,  2.35747,  2.61891,  2.73804,
+  0.179285,  0.33316,  0.500638,  0.79695,  1.03999,  1.23497,  1.6523,  1.84823,  2.62556,  2.80497,
+  0.268785,  0.356576,  0.595753,  1.04434,  1.24938,  1.42868,  1.68699,  1.86469,  2.33991,  2.5138,
+  0.12007,  0.165585,  0.484694,  0.95916,  1.23753,  1.52915,  1.83751,  2.10773,  2.48749,  2.76685,
+  0.150214,  0.229487,  0.62824,  0.961255,  1.33706,  1.59831,  1.91974,  2.21786,  2.53732,  2.75956,
+  0.268624,  0.34598,  0.569637,  0.754737,  0.916538,  1.50854,  1.78635,  1.95442,  2.36953,  2.50182,
+  0.246064,  0.468874,  0.662711,  0.890015,  1.14715,  1.51043,  1.78106,  2.09594,  2.65539,  2.80037,
+  0.191631,  0.280628,  0.393229,  0.611761,  1.42017,  1.70774,  1.87303,  2.10155,  2.28035,  2.49949,
+  0.361668,  0.507047,  0.789974,  1.04599,  1.50238,  1.67703,  1.90534,  2.16255,  2.43226,  2.59087,
+  0.20816,  0.294285,  0.448634,  0.694229,  0.872517,  1.07032,  1.70335,  2.16874,  2.42619,  2.60366,
+  0.316939,  0.513618,  0.705487,  0.917036,  1.17599,  1.31114,  1.6186,  2.03784,  2.45052,  2.5794,
+  0.241068,  0.377728,  0.521595,  0.717203,  1.31041,  1.53999,  1.73643,  2.09893,  2.29792,  2.58735,
+  0.234937,  0.281875,  0.780422,  1.44073,  1.60943,  1.75643,  1.97721,  2.14861,  2.60203,  2.7225,
+  0.178679,  0.242672,  0.416988,  0.708348,  0.95562,  1.17667,  1.7818,  2.05449,  2.28159,  2.44811,
+  0.345036,  0.42108,  0.740887,  1.16544,  1.32494,  1.4888,  1.76346,  1.90617,  2.39505,  2.64916,
+  0.249586,  0.357494,  0.520747,  0.847195,  1.42841,  1.59778,  1.77819,  2.1785,  2.41344,  2.56466,
+  0.295235,  0.574231,  1.2491,  1.4641,  1.72756,  1.92679,  2.09536,  2.28483,  2.56707,  2.72248,
+  0.34193,  0.427307,  0.634001,  0.804212,  0.905629,  1.33337,  1.79033,  1.89276,  2.44582,  2.60283,
+  0.363948,  0.508985,  0.667357,  0.946354,  1.43756,  1.62654,  1.81114,  2.03909,  2.29188,  2.43549,
+  0.163514,  0.277407,  0.409207,  0.902065,  1.18907,  1.33964,  1.80241,  1.96077,  2.65293,  2.81899,
+  0.302643,  0.359753,  0.651207,  1.20802,  1.4237,  1.54815,  1.88213,  2.01559,  2.26054,  2.5789,
+  0.155928,  0.216908,  0.381812,  0.654803,  1.11237,  1.58993,  1.84756,  1.97672,  2.22408,  2.72534,
+  0.274981,  0.347675,  0.572,  0.736046,  0.894248,  1.63237,  1.89139,  2.05689,  2.6029,  2.72178,
+  0.154496,  0.243461,  0.348174,  0.689505,  1.57381,  1.70031,  1.94318,  2.10158,  2.56466,  2.77317,
+  0.292612,  0.466612,  0.795936,  1.04747,  1.41369,  1.75085,  2.06289,  2.34007,  2.61361,  2.76949,
+  0.242896,  0.3615,  0.555859,  0.793597,  0.932291,  1.40947,  1.86386,  2.00953,  2.4645,  2.67749,
+  0.221646,  0.344724,  0.554564,  0.729403,  1.13657,  1.30177,  1.52918,  2.16359,  2.39582,  2.61081,
+  0.160969,  0.224467,  0.371545,  0.626879,  1.16095,  1.44423,  1.67597,  1.87978,  2.47859,  2.67202,
+  0.214172,  0.341585,  0.676575,  0.977397,  1.32543,  1.7201,  2.07259,  2.36954,  2.63528,  2.77879,
+  0.203311,  0.289438,  0.458739,  0.914153,  1.12288,  1.30292,  1.58384,  1.88683,  2.18787,  2.42704,
+  0.280383,  0.3716,  0.824827,  1.10025,  1.23623,  1.39892,  1.57804,  2.016,  2.36897,  2.50673,
+  0.170627,  0.251778,  0.393686,  0.608347,  1.2876,  1.44667,  1.79328,  2.03655,  2.31015,  2.75244,
+  0.18058,  0.288746,  0.987854,  1.43171,  1.67722,  1.91566,  2.12494,  2.28945,  2.58961,  2.75426,
+  0.176335,  0.266263,  0.445421,  0.706403,  0.875402,  1.42292,  1.75867,  1.96091,  2.41068,  2.60175,
+  0.216173,  0.287404,  0.480696,  1.00977,  1.2913,  1.47664,  1.89558,  2.06429,  2.28406,  2.48311,
+  0.176523,  0.273934,  0.403407,  0.966139,  1.30472,  1.43661,  1.94473,  2.08484,  2.54446,  2.76242,
+  0.311836,  0.550501,  0.879591,  1.09623,  1.27666,  1.47786,  1.81771,  2.15434,  2.56047,  2.77984,
+  0.179765,  0.25056,  0.455939,  1.02389,  1.22513,  1.47566,  1.73462,  1.91871,  2.14734,  2.43824,
+  0.271033,  0.457235,  0.599622,  0.821049,  0.940125,  1.20094,  1.84972,  1.98666,  2.54817,  2.75158,
+  0.179326,  0.248002,  0.426405,  0.81706,  1.28589,  1.56502,  2.11736,  2.29871,  2.5724,  2.7527,
+  0.374409,  0.535936,  0.897009,  1.18507,  1.59157,  1.7572,  1.96794,  2.17999,  2.45739,  2.62264,
+  0.185472,  0.282752,  0.409439,  0.657499,  0.856446,  1.0294,  1.87993,  2.06932,  2.34474,  2.7531,
+  0.375964,  0.578457,  0.758945,  0.929339,  1.12748,  1.25944,  1.70411,  2.12297,  2.33603,  2.4983,
+  0.225641,  0.36103,  0.501679,  0.783379,  1.31485,  1.45262,  1.71415,  1.98716,  2.2257,  2.72436,
+  0.144996,  0.252919,  0.632145,  1.22604,  1.57534,  1.90155,  2.17148,  2.39055,  2.68229,  2.80983,
+  0.172022,  0.263338,  0.448634,  0.729435,  0.984007,  1.1716,  1.75705,  1.99023,  2.32131,  2.77121,
+  0.235731,  0.351117,  0.796871,  1.05571,  1.30022,  1.59182,  1.89587,  2.12292,  2.41789,  2.59982,
+  0.254053,  0.319371,  0.455623,  1.08614,  1.66467,  1.91588,  2.05908,  2.23342,  2.45204,  2.58679,
+  0.375538,  0.742993,  1.13991,  1.33776,  1.73556,  2.01391,  2.31501,  2.48343,  2.65158,  2.75521,
+  0.247245,  0.481131,  0.710366,  0.897602,  1.12109,  1.27171,  1.78735,  2.1995,  2.42966,  2.74067,
+  0.226103,  0.311441,  0.501648,  0.844424,  1.36282,  1.53134,  1.77747,  1.98993,  2.18749,  2.3585,
+  0.195862,  0.296224,  0.609554,  0.783241,  1.24347,  1.44548,  1.63703,  2.02264,  2.48356,  2.64614,
+  0.233302,  0.299441,  0.472792,  1.24946,  1.45788,  1.60186,  1.83143,  1.99372,  2.59719,  2.75543,
+  0.168096,  0.224183,  0.3827,  0.596214,  1.06059,  1.29442,  1.60576,  1.84849,  2.3577,  2.56919,
+  0.33005,  0.445912,  0.661713,  0.874446,  1.00079,  1.45297,  1.94399,  2.07692,  2.42388,  2.61236,
+  0.226382,  0.287303,  0.517631,  0.806229,  1.30901,  1.88528,  2.16051,  2.28641,  2.52638,  2.66082,
+  0.20317,  0.499314,  0.887358,  1.23507,  1.46292,  1.69826,  1.99932,  2.22922,  2.57161,  2.76669,
+  0.307531,  0.378353,  0.573606,  0.712218,  0.850169,  1.309,  2.05909,  2.26382,  2.49794,  2.67682,
+  0.276203,  0.51025,  0.6868,  0.902844,  1.2052,  1.32798,  1.71889,  2.03895,  2.25639,  2.69715,
+  0.161948,  0.229115,  0.393619,  0.683613,  1.13781,  1.32269,  1.78372,  1.96158,  2.38907,  2.63608,
+  0.201334,  0.276773,  0.468994,  0.967017,  1.47597,  1.63242,  1.96577,  2.19728,  2.48059,  2.70155,
+  0.214587,  0.315421,  0.469498,  0.733397,  1.146,  1.27791,  1.72784,  2.22713,  2.44026,  2.68112,
+  0.255602,  0.394609,  0.743393,  0.977796,  1.19908,  1.40597,  1.91834,  2.22483,  2.47919,  2.66339,
+  0.245989,  0.352625,  0.517055,  0.80283,  1.55871,  1.79565,  1.94405,  2.13364,  2.33327,  2.47998,
+  0.337423,  0.480433,  0.869036,  1.13957,  1.63076,  1.82296,  2.07484,  2.29261,  2.47913,  2.62532,
+  0.220974,  0.35885,  0.57164,  0.752791,  0.937013,  1.15172,  1.6744,  2.06247,  2.55872,  2.78484,
+  0.267518,  0.331708,  0.541111,  1.11655,  1.41112,  1.53287,  1.79295,  1.93352,  2.24894,  2.62864,
+  0.084613,  0.105083,  0.297424,  0.916949,  1.2563,  1.56703,  1.88539,  2.18987,  2.52279,  2.7921,
+  0.205328,  0.287223,  0.724462,  1.0324,  1.45771,  1.64217,  1.92563,  2.17552,  2.42964,  2.60549,
+  0.232554,  0.338724,  0.502115,  0.859975,  1.04409,  1.24565,  1.80656,  1.99964,  2.26116,  2.45998,
+  0.291638,  0.379172,  0.626072,  0.792796,  0.959124,  1.50489,  1.73447,  1.91961,  2.61436,  2.72271,
+  0.191554,  0.263114,  0.426797,  0.610628,  1.07741,  1.82954,  2.02195,  2.21057,  2.42765,  2.61383,
+  0.389151,  0.679476,  0.915414,  1.03664,  1.25085,  1.58661,  2.04097,  2.2815,  2.56794,  2.71882,
+  0.2032,  0.30128,  0.470357,  0.668716,  0.851737,  0.980327,  1.57086,  2.03762,  2.28907,  2.69388,
+  0.304064,  0.405934,  0.710274,  0.962705,  1.12882,  1.34167,  1.63505,  1.84538,  2.07992,  2.50751,
+  0.171777,  0.240705,  0.409371,  0.786432,  1.2232,  1.37569,  1.69176,  1.86608,  2.35041,  2.49394,
+  0.231251,  0.277994,  0.557867,  1.32582,  1.66035,  1.77948,  2.00714,  2.17232,  2.44046,  2.65231,
+  0.188101,  0.259494,  0.412543,  0.624843,  0.839549,  1.0337,  1.63413,  1.93194,  2.24608,  2.42577,
+  0.361304,  0.419465,  0.795676,  1.18461,  1.2968,  1.57845,  1.84175,  1.99736,  2.54054,  2.68714,
+  0.274372,  0.338938,  0.492443,  0.963516,  1.50951,  1.70638,  1.86988,  2.07717,  2.26128,  2.44418,
+  0.41599,  0.652103,  1.03129,  1.26955,  1.57275,  1.77297,  2.00466,  2.17527,  2.43061,  2.59655,
+  0.242045,  0.370942,  0.534392,  0.763529,  1.00117,  1.12976,  1.68219,  2.14464,  2.32448,  2.7157,
+  0.377438,  0.588168,  0.765394,  0.976873,  1.35665,  1.49009,  1.73797,  2.00677,  2.21369,  2.38997,
+  0.191625,  0.284123,  0.405342,  1.01678,  1.43273,  1.54759,  1.81393,  1.95832,  2.47077,  2.64926,
+  0.272672,  0.349555,  0.633911,  1.15223,  1.30394,  1.54764,  1.9195,  2.0477,  2.56278,  2.73058,
+  0.168423,  0.23633,  0.421468,  0.831345,  1.08354,  1.55345,  1.88073,  2.0647,  2.37086,  2.63295,
+  0.219318,  0.301481,  0.513617,  0.765086,  1.02602,  1.51465,  2.0482,  2.24857,  2.49981,  2.65707,
+  0.232695,  0.347947,  0.495203,  0.71883,  1.42301,  1.72249,  1.87958,  2.16504,  2.42025,  2.58966,
+  0.270284,  0.336865,  0.684929,  1.15579,  1.69042,  1.87674,  2.02736,  2.22618,  2.44675,  2.582,
+  0.149701,  0.193747,  0.352019,  0.520123,  0.823974,  1.43475,  1.68659,  1.96115,  2.37091,  2.69307,
+  0.254818,  0.412303,  0.601514,  0.771438,  1.17545,  1.37657,  1.53903,  1.93704,  2.40858,  2.56362,
+  0.233713,  0.355886,  0.593725,  0.76288,  1.27148,  1.5639,  1.79752,  2.09469,  2.53863,  2.71173,
+  0.179028,  0.237103,  0.396818,  1.04202,  1.63354,  1.76268,  2.12393,  2.32239,  2.58819,  2.75134,
+  0.182027,  0.251039,  0.434581,  0.714302,  0.950997,  1.4379,  1.81357,  1.9691,  2.14588,  2.35397,
+  0.501538,  0.692148,  0.84886,  1.07131,  1.35054,  1.48948,  1.84164,  2.10428,  2.34154,  2.51529,
+  0.27453,  0.38147,  0.526682,  0.922143,  1.44495,  1.5736,  1.85877,  2.06675,  2.2848,  2.62682,
+  0.360617,  0.583131,  0.979491,  1.25408,  1.48835,  1.79756,  2.21952,  2.48218,  2.74237,  2.86203,
+  0.140913,  0.220301,  0.619552,  0.818307,  1.05243,  1.33997,  1.83073,  2.13395,  2.53638,  2.75113,
+  0.293514,  0.391691,  0.79008,  0.96274,  1.16032,  1.5266,  1.80549,  2.04146,  2.36162,  2.56496,
+  0.199542,  0.290571,  0.452891,  0.689515,  1.25853,  1.40988,  1.88624,  2.22813,  2.46568,  2.72665,
+  0.29692,  0.356356,  0.784287,  0.99654,  1.14618,  1.62387,  1.8155,  2.0383,  2.60063,  2.7057,
+  0.206451,  0.276025,  0.537547,  0.802572,  1.22041,  1.64206,  1.86363,  2.00198,  2.21534,  2.58538,
+  0.33365,  0.464751,  0.653772,  0.966306,  1.10387,  1.3402,  1.7847,  1.91459,  2.47017,  2.68692,
+  0.181861,  0.24487,  0.376456,  0.554383,  1.3299,  1.81044,  2.04784,  2.20232,  2.66086,  2.81706,
+  0.450565,  0.647291,  0.951172,  1.22943,  1.51964,  1.68681,  2.04911,  2.26717,  2.50128,  2.6506,
+  0.219996,  0.320591,  0.427747,  0.601183,  0.753448,  0.929578,  1.74198,  2.28579,  2.47263,  2.74957,
+  0.333848,  0.423373,  0.658791,  1.0313,  1.22263,  1.36577,  1.90189,  2.1211,  2.29031,  2.53118,
+  0.166064,  0.233902,  0.383355,  0.661806,  1.22657,  1.39968,  1.77127,  1.97454,  2.17349,  2.56634,
+  0.189286,  0.243602,  0.390584,  1.38793,  1.58872,  1.76324,  2.09112,  2.31631,  2.59353,  2.75508,
+  0.158404,  0.224878,  0.385,  0.668463,  0.942954,  1.41197,  1.70031,  1.82807,  2.0594,  2.69255,
+  0.325989,  0.461263,  0.851471,  1.04571,  1.28403,  1.5162,  1.79734,  2.08839,  2.43767,  2.62721,
+  0.223709,  0.28919,  0.632812,  0.858738,  1.5419,  1.74677,  1.93574,  2.18482,  2.40433,  2.58301,
+  0.545842,  0.95242,  1.34082,  1.51684,  1.83888,  2.01289,  2.24497,  2.40317,  2.59228,  2.69112,
+  0.238526,  0.349079,  0.494582,  0.987665,  1.17075,  1.34823,  1.46864,  2.29696,  2.64416,  2.78738,
+  0.270857,  0.442003,  0.655998,  0.881913,  1.25925,  1.42836,  1.76987,  1.99853,  2.39559,  2.65284,
+  0.154384,  0.211806,  0.489481,  0.997257,  1.24982,  1.54123,  1.77886,  1.9494,  2.31914,  2.62339,
+  0.268258,  0.312888,  0.589114,  1.25863,  1.57271,  1.67543,  1.91278,  2.07046,  2.27993,  2.56423,
+  0.170715,  0.224965,  0.374011,  0.540197,  1.16189,  1.49907,  1.92587,  2.08257,  2.24662,  2.46972,
+  0.324358,  0.391989,  0.706816,  0.833614,  1.01573,  1.56899,  1.73598,  2.12707,  2.55841,  2.65387,
+  0.178059,  0.258575,  0.374125,  0.536831,  1.33483,  1.79863,  1.98698,  2.18925,  2.43227,  2.6267,
+  0.198857,  0.420955,  0.817664,  1.17836,  1.46674,  1.8213,  2.20733,  2.47441,  2.73828,  2.85119,
+  0.188344,  0.324302,  0.470468,  0.790033,  0.934101,  1.18872,  1.88717,  2.05283,  2.44832,  2.63024,
+  0.201295,  0.365646,  0.526513,  0.758388,  1.1401,  1.26733,  1.65017,  1.87934,  2.10289,  2.60029,
+  0.135058,  0.169428,  0.307348,  0.50316,  1.01808,  1.44795,  1.81098,  2.134,  2.48028,  2.75985,
+  0.178006,  0.26661,  0.390327,  0.928681,  1.50161,  1.62133,  1.87136,  2.02586,  2.58044,  2.7708,
+  0.246182,  0.42429,  0.644023,  0.801168,  1.11488,  1.27776,  1.50332,  2.07489,  2.2957,  2.50138,
+  0.322996,  0.430355,  0.6316,  1.0477,  1.22184,  1.42673,  1.90308,  2.03222,  2.51673,  2.70845,
+  0.292994,  0.430599,  0.619178,  0.794567,  1.28303,  1.65282,  1.84084,  2.06995,  2.38538,  2.52825,
+  0.525494,  0.787797,  1.12182,  1.38748,  1.67457,  1.93622,  2.22404,  2.39062,  2.63428,  2.74323,
+  0.299504,  0.409196,  0.602235,  0.892336,  1.05643,  1.25377,  1.48914,  1.63988,  2.42748,  2.65037,
+  0.423758,  0.52048,  0.758987,  1.04126,  1.17366,  1.42368,  1.81824,  1.93641,  2.363,  2.62664,
+  0.155042,  0.247496,  0.641445,  0.954509,  1.22497,  1.46585,  1.83784,  2.09046,  2.4515,  2.71616,
+  0.251949,  0.421094,  0.706797,  0.975659,  1.25991,  1.52007,  1.81631,  2.12202,  2.47491,  2.71667,
+  0.21522,  0.302248,  0.730598,  0.896343,  1.14557,  1.37019,  1.70069,  2.02256,  2.28327,  2.48922,
+  0.28523,  0.453559,  0.66367,  0.861526,  1.0116,  1.24742,  1.65598,  1.86129,  2.57894,  2.73133,
+  0.162067,  0.219409,  0.373433,  0.544669,  1.1033,  1.59718,  1.92104,  2.1434,  2.4065,  2.66048,
+  0.342367,  0.511499,  0.93135,  1.16322,  1.39365,  1.61115,  1.97277,  2.19442,  2.47077,  2.64926,
+  0.25101,  0.364125,  0.560956,  0.746545,  1.01984,  1.17072,  1.53295,  2.28867,  2.57709,  2.72307,
+  0.315001,  0.489412,  0.720682,  0.877607,  1.09047,  1.25385,  1.44822,  1.92295,  2.25589,  2.40863,
+  0.174666,  0.235793,  0.387644,  0.554402,  1.23109,  1.45614,  1.68803,  2.12745,  2.36703,  2.59727,
+  0.215113,  0.341915,  1.04372,  1.32275,  1.49541,  1.74189,  1.96116,  2.23982,  2.5449,  2.70394,
+  0.219852,  0.30177,  0.513912,  0.705474,  0.87754,  1.2959,  1.699,  1.98706,  2.28797,  2.49697,
+  0.290638,  0.366442,  0.655155,  1.04499,  1.17215,  1.53254,  1.80079,  1.94893,  2.50968,  2.66005,
+  0.232252,  0.31377,  0.658552,  0.941977,  1.46317,  1.66549,  1.86246,  2.02784,  2.53402,  2.70124,
+  0.326539,  0.552681,  1.12173,  1.33138,  1.52007,  1.86708,  2.08286,  2.33247,  2.60604,  2.73709,
+  0.190254,  0.340428,  0.492777,  0.739738,  0.895461,  1.07937,  1.64316,  1.79529,  2.49182,  2.72938,
+  0.283586,  0.41844,  0.587306,  0.870866,  1.41855,  1.57703,  1.7995,  2.0694,  2.27448,  2.4381,
+  0.235752,  0.35765,  0.502891,  1.01243,  1.25885,  1.40779,  1.82006,  1.95583,  2.5059,  2.73433,
+  0.278412,  0.343137,  0.849977,  1.2329,  1.3505,  1.59063,  1.78752,  2.09158,  2.54136,  2.66386,
+  0.162966,  0.243159,  0.439238,  0.684821,  0.887783,  1.4629,  1.88174,  2.04425,  2.28939,  2.705,
+  0.235063,  0.371799,  0.57821,  0.752199,  1.00855,  1.47628,  1.80491,  2.2714,  2.65504,  2.78965,
+  0.154939,  0.223696,  0.344718,  0.667555,  1.49566,  1.66944,  2.06988,  2.30721,  2.62769,  2.81134,
+  0.239702,  0.335917,  0.716616,  1.1318,  1.45251,  1.63913,  2.10552,  2.27982,  2.50203,  2.66922,
+  0.226818,  0.331261,  0.472705,  0.651974,  0.781639,  1.2198,  1.8229,  2.08273,  2.43933,  2.6109,
+  0.223413,  0.359594,  0.534704,  0.741518,  1.22589,  1.38987,  1.61819,  2.00991,  2.207,  2.45984,
+  0.171308,  0.268378,  0.383799,  0.858926,  1.37629,  1.51917,  1.7806,  1.92291,  2.62309,  2.8024,
+  0.140134,  0.21232,  0.443224,  0.967457,  1.26424,  1.56215,  1.92915,  2.21739,  2.66834,  2.83075,
+  0.221323,  0.322124,  0.485563,  0.818589,  1.01184,  1.19898,  1.42362,  1.6694,  2.15752,  2.36319,
+  0.369687,  0.525655,  0.719213,  0.939654,  1.13763,  1.31222,  1.59994,  1.82681,  2.35522,  2.58068,
+  0.211975,  0.314411,  0.489148,  0.739213,  1.3778,  1.5545,  1.82437,  2.15887,  2.35299,  2.72262,
+  0.170698,  0.296368,  0.934285,  1.24313,  1.5559,  1.86654,  2.15994,  2.36344,  2.58503,  2.73853,
+  0.189263,  0.305887,  0.439912,  0.78461,  1.22726,  1.34251,  1.58765,  1.75491,  2.43989,  2.72131,
+  0.296339,  0.385169,  0.612012,  1.08132,  1.27636,  1.43718,  1.87147,  2.00172,  2.33909,  2.64022,
+  0.229588,  0.320544,  0.517278,  0.969137,  1.14256,  1.62609,  1.87792,  2.11546,  2.54674,  2.70802,
+  0.248869,  0.420193,  0.732388,  1.04902,  1.30341,  1.60146,  1.94921,  2.23946,  2.64822,  2.82261,
+  0.2076,  0.29232,  0.496539,  0.857149,  1.18229,  1.39985,  1.71416,  1.86824,  2.02794,  2.20074,
+  0.225558,  0.396897,  0.541783,  0.873366,  1.17897,  1.29958,  1.67719,  1.8496,  2.33048,  2.75272,
+  0.176821,  0.231377,  0.372767,  0.508565,  1.15282,  1.80805,  2.11268,  2.25007,  2.57134,  2.74855,
+  0.352149,  0.515765,  1.02324,  1.26022,  1.44357,  1.62207,  1.8728,  2.10018,  2.48928,  2.67104,
+  0.166138,  0.263444,  0.370151,  0.590066,  0.754819,  0.940533,  1.76187,  1.94661,  2.44501,  2.75819,
+  0.342082,  0.476411,  0.656223,  0.851774,  1.00399,  1.15337,  1.6944,  2.06562,  2.25564,  2.44015,
+  0.227237,  0.376514,  0.514329,  0.894887,  1.14167,  1.28305,  1.83138,  1.9859,  2.33447,  2.78488,
+  0.215891,  0.269548,  0.684111,  1.40566,  1.67481,  1.80093,  2.17209,  2.3394,  2.59157,  2.7301,
+  0.23624,  0.400377,  0.533684,  0.750343,  0.910405,  1.08911,  1.73773,  1.91281,  2.19252,  2.68873,
+  0.169242,  0.284879,  0.916252,  1.16977,  1.43368,  1.64438,  1.91912,  2.16162,  2.48266,  2.68259,
+  0.270731,  0.336506,  0.477594,  1.04271,  1.60584,  1.79686,  1.94591,  2.16004,  2.35491,  2.52095,
+  0.420586,  0.652563,  1.11716,  1.40601,  1.74754,  1.94742,  2.20309,  2.35997,  2.5479,  2.68217,
+  0.281552,  0.395037,  0.640181,  0.944531,  1.19396,  1.33049,  1.71866,  2.18839,  2.44459,  2.57867,
+  0.311824,  0.476892,  0.633431,  0.845825,  1.33252,  1.49166,  1.69361,  2.04108,  2.28932,  2.4394,
+  0.133945,  0.20079,  0.647237,  0.927687,  1.18888,  1.36966,  1.69956,  1.97278,  2.29526,  2.67818,
+  0.204796,  0.278215,  0.443465,  1.27048,  1.40521,  1.64092,  1.82425,  2.32709,  2.59964,  2.77253,
+  0.18397,  0.244116,  0.410594,  0.639103,  1.22159,  1.40487,  1.62836,  1.90244,  2.16863,  2.3068,
+  0.343622,  0.434735,  0.666599,  0.868069,  1.04894,  1.53278,  1.81983,  1.97188,  2.2887,  2.44875,
+  0.238017,  0.320361,  0.657255,  0.917611,  1.30331,  1.72736,  1.98891,  2.18145,  2.44297,  2.61332,
+  0.323613,  0.545056,  0.930173,  1.22606,  1.44018,  1.7723,  2.05689,  2.34781,  2.68938,  2.82062,
+  0.28893,  0.401387,  0.617124,  0.836453,  0.990306,  1.26123,  1.91328,  2.11005,  2.32458,  2.55716,
+  0.33267,  0.480804,  0.656147,  0.880536,  1.02957,  1.23049,  1.76906,  1.9323,  2.20037,  2.58521,
+  0.185551,  0.265352,  0.409432,  0.608847,  1.0347,  1.22282,  1.87697,  2.17165,  2.4035,  2.66644,
+  0.155026,  0.223348,  0.401684,  1.07914,  1.41579,  1.62002,  2.04552,  2.25851,  2.63162,  2.80229,
+  0.183461,  0.263081,  0.425694,  0.635685,  1.18866,  1.35756,  1.57499,  2.08598,  2.28872,  2.51111,
+  0.314738,  0.463011,  0.648733,  0.877651,  1.00289,  1.26581,  2.00541,  2.1981,  2.48153,  2.71418,
+  0.244411,  0.318444,  0.546578,  0.793615,  1.32615,  1.73548,  1.9456,  2.11466,  2.31535,  2.47853,
+  0.326237,  0.54354,  0.987361,  1.30441,  1.68493,  1.90215,  2.20717,  2.37427,  2.55753,  2.71622,
+  0.157795,  0.283302,  0.430398,  0.660379,  0.81106,  1.14254,  1.4793,  1.71871,  2.67026,  2.84756,
+  0.220856,  0.283872,  0.779935,  1.07494,  1.31221,  1.62633,  1.83761,  1.96888,  2.15599,  2.60238,
+  0.140763,  0.205719,  0.406561,  0.762459,  1.04127,  1.48699,  1.83831,  2.11461,  2.55281,  2.77228,
+  0.140451,  0.39592,  0.79211,  1.108,  1.40264,  1.62308,  1.94315,  2.22795,  2.54616,  2.774,
+  0.229862,  0.336462,  0.54659,  0.81015,  1.20191,  1.34679,  1.82532,  2.09293,  2.28573,  2.47336,
+  0.224913,  0.328246,  0.517269,  0.874793,  1.01259,  1.45218,  1.69578,  2.01493,  2.51145,  2.67257,
+  0.247745,  0.335741,  0.546558,  0.710177,  1.17056,  1.72779,  1.97068,  2.15853,  2.48282,  2.62891,
+  0.398252,  0.555087,  0.890367,  1.1212,  1.38153,  1.60123,  1.86665,  2.06661,  2.40516,  2.58802,
+  0.198563,  0.288867,  0.478054,  0.658477,  0.851841,  1.0271,  1.53974,  2.02111,  2.57946,  2.78418,
+  0.304271,  0.371642,  0.66159,  1.06898,  1.22425,  1.41193,  1.68052,  1.86977,  2.10007,  2.30855,
+  0.188223,  0.257939,  0.432402,  0.73505,  1.31804,  1.48553,  1.82811,  2.04644,  2.30702,  2.45724,
+  0.246723,  0.297276,  0.604475,  1.3109,  1.57044,  1.68885,  1.91366,  2.05133,  2.55601,  2.71497,
+  0.158309,  0.234509,  0.435792,  0.6679,  0.957567,  1.23592,  1.59294,  1.81816,  2.30739,  2.76897,
+  0.419843,  0.501412,  0.766892,  1.07317,  1.18937,  1.48022,  1.7666,  1.92215,  2.53794,  2.69477,
+  0.27514,  0.335563,  0.678421,  1.08152,  1.59238,  1.77263,  1.93124,  2.1407,  2.3338,  2.49086,
+  0.372056,  0.856814,  1.23954,  1.40999,  1.6903,  1.86302,  2.0727,  2.27355,  2.53266,  2.69052,
+  0.321254,  0.422981,  0.604856,  0.793437,  0.912112,  1.12845,  1.79598,  2.17323,  2.36015,  2.53614,
+  0.395214,  0.598779,  0.771997,  0.946713,  1.21378,  1.33043,  1.66033,  1.97715,  2.16506,  2.34402,
+  0.225286,  0.317828,  0.464801,  1.11233,  1.36951,  1.512,  1.92195,  2.05341,  2.59352,  2.77729,
+  0.330612,  0.407807,  0.730129,  1.25973,  1.45981,  1.60567,  1.98131,  2.13701,  2.46597,  2.67972,
+  0.213145,  0.305305,  0.507016,  0.662299,  1.05685,  1.47986,  1.6719,  2.10271,  2.36987,  2.58199,
+  0.219658,  0.296096,  0.443507,  0.610973,  0.799691,  1.67658,  1.96549,  2.15323,  2.50223,  2.693,
+  0.174947,  0.257739,  0.373547,  0.552567,  1.40532,  1.61425,  1.84892,  2.11779,  2.31788,  2.7119,
+  0.209667,  0.297529,  0.756195,  1.0953,  1.5642,  1.84477,  2.1037,  2.29266,  2.52005,  2.67949,
+  0.170138,  0.24031,  0.452247,  0.684414,  0.880102,  1.36692,  1.74165,  2.13129,  2.50573,  2.73261,
+  0.278164,  0.468635,  0.707518,  0.853693,  1.05478,  1.21046,  1.54094,  2.17456,  2.41066,  2.61214,
+  0.155738,  0.23889,  0.352836,  0.621012,  1.44144,  1.6197,  1.82517,  1.97533,  2.52537,  2.74857,
+  0.223776,  0.274424,  0.479048,  0.797871,  1.69419,  1.87813,  2.13528,  2.37373,  2.59542,  2.72979,
+  0.151088,  0.198286,  0.326558,  0.536276,  0.845893,  1.14165,  1.46056,  1.76287,  2.02585,  2.1773,
+  0.434445,  0.614208,  0.887657,  1.02845,  1.19136,  1.3922,  1.78689,  2.06248,  2.4234,  2.61936,
+  0.180755,  0.275311,  0.397787,  0.859366,  1.40976,  1.52332,  1.90885,  2.08232,  2.38972,  2.74389,
+  0.275975,  0.508416,  0.889894,  1.31893,  1.63331,  1.90473,  2.16901,  2.37466,  2.72697,  2.84767,
+  0.156239,  0.262624,  0.406657,  0.739074,  1.04449,  1.20123,  1.81089,  2.0056,  2.5817,  2.80489,
+  0.195391,  0.258771,  0.654924,  0.824371,  1.31526,  1.50073,  1.76594,  2.06399,  2.34118,  2.51366,
+  0.178034,  0.301047,  0.46302,  0.716172,  1.19887,  1.34045,  1.83456,  2.02213,  2.40075,  2.77629,
+  0.340368,  0.404236,  0.843747,  1.03924,  1.20211,  1.70805,  1.91495,  2.16951,  2.52152,  2.62335,
+  0.218465,  0.289694,  0.528045,  0.817051,  1.13234,  1.58046,  1.83889,  1.98339,  2.14749,  2.34813,
+  0.322509,  0.458058,  0.654679,  0.958976,  1.11821,  1.32157,  1.90139,  2.04641,  2.36093,  2.66422,
+  0.191821,  0.252321,  0.389176,  0.581111,  1.52967,  1.93169,  2.08361,  2.27046,  2.56685,  2.71388,
+  0.493961,  0.710827,  0.98226,  1.19627,  1.41933,  1.62091,  1.92801,  2.14565,  2.42977,  2.60197,
+  0.213148,  0.311589,  0.424636,  0.602664,  0.736895,  1.02216,  1.99228,  2.21853,  2.61163,  2.85032,
+  0.288129,  0.434441,  0.629313,  0.856153,  1.28967,  1.42452,  1.8758,  2.15024,  2.35181,  2.53684,
+  0.160031,  0.230716,  0.406654,  0.870424,  1.15652,  1.39232,  1.8041,  1.95144,  2.21048,  2.73516,
+  0.22934,  0.293962,  0.503222,  1.2421,  1.47582,  1.62465,  1.99868,  2.1445,  2.57855,  2.75327,
+  0.15877,  0.220035,  0.363386,  0.577761,  0.96309,  1.17494,  1.73817,  1.9792,  2.16244,  2.66192,
+  0.346062,  0.444816,  0.716985,  1.18072,  1.37058,  1.523,  1.89217,  2.06668,  2.3958,  2.62766,
+  0.307495,  0.38933,  0.612607,  0.969283,  1.55771,  1.83994,  1.99674,  2.17238,  2.42063,  2.5392,
+  0.437804,  0.726957,  1.29117,  1.5033,  1.76543,  1.96212,  2.16365,  2.33623,  2.57962,  2.70852,
+  0.232184,  0.333678,  0.528368,  0.706749,  1.20328,  1.37902,  1.61116,  2.15468,  2.5929,  2.75032,
+  0.272652,  0.46171,  0.625777,  0.839609,  1.34202,  1.49673,  1.71538,  2.13757,  2.37004,  2.59739,
+  0.184908,  0.302324,  0.454883,  0.880307,  1.10438,  1.29253,  1.7772,  1.94336,  2.44417,  2.62273,
+  0.265644,  0.341261,  0.553228,  1.13947,  1.42715,  1.56044,  1.93394,  2.08413,  2.39331,  2.65413,
+  0.16792,  0.207301,  0.370331,  0.525538,  1.03089,  1.36816,  1.78247,  2.0624,  2.33276,  2.5263,
+  0.343172,  0.433912,  0.717501,  0.889734,  1.05206,  1.69528,  2.05316,  2.20846,  2.60887,  2.71832,
+  0.216527,  0.305247,  0.44589,  0.729271,  1.63974,  1.90328,  2.05335,  2.22125,  2.43225,  2.56802,
+  0.110545,  0.209955,  0.844788,  1.1742,  1.4922,  1.81024,  2.17727,  2.4405,  2.69729,  2.83523,
+  0.217384,  0.337412,  0.488999,  0.761842,  0.879715,  1.20953,  1.97075,  2.1208,  2.61165,  2.79176,
+  0.190459,  0.296484,  0.469967,  0.800649,  1.10556,  1.27853,  1.51694,  1.69307,  2.11442,  2.71674,
+  0.134814,  0.175978,  0.300425,  0.496817,  1.2443,  1.48531,  1.86172,  2.13123,  2.48505,  2.77388,
+  0.210174,  0.278266,  0.435508,  0.927538,  1.60691,  1.7539,  1.95755,  2.16628,  2.39852,  2.74961,
+  0.213766,  0.3153,  0.509924,  0.70993,  0.964724,  1.10678,  1.38261,  2.00107,  2.32321,  2.56531,
+  0.400615,  0.524954,  0.798552,  1.01285,  1.13549,  1.47485,  1.98903,  2.13091,  2.50797,  2.67946,
+  0.2494,  0.377023,  0.519635,  0.754227,  1.45956,  1.64276,  1.82896,  2.07788,  2.29823,  2.46753,
+  0.473365,  0.683973,  1.05234,  1.37583,  1.54811,  1.74759,  2.1393,  2.31877,  2.60998,  2.73925,
+  0.203877,  0.341791,  0.48518,  0.884069,  1.09759,  1.26953,  1.47992,  1.75788,  2.6484,  2.82239,
+  0.273046,  0.404254,  0.555403,  0.954547,  1.29123,  1.39902,  1.72289,  1.90344,  2.17198,  2.64531,
+  0.040369,  0.117266,  0.617136,  0.892043,  1.26033,  1.54165,  1.85938,  2.1531,  2.49823,  2.76189,
+  0.132414,  0.211358,  0.742445,  1.06686,  1.33108,  1.57079,  1.86746,  2.13253,  2.47962,  2.73108,
+  0.237329,  0.326529,  0.612538,  0.790663,  0.990133,  1.41374,  1.73823,  1.93691,  2.16773,  2.45163,
+  0.27396,  0.405794,  0.57253,  0.933672,  1.05782,  1.39795,  1.85653,  1.99755,  2.59949,  2.76004,
+  0.199334,  0.29838,  0.442931,  0.628638,  1.30321,  1.64014,  1.80402,  2.11302,  2.37545,  2.54895,
+  0.350188,  0.50201,  0.821298,  1.03864,  1.36929,  1.5924,  1.91082,  2.15649,  2.46051,  2.65326,
+  0.281558,  0.399892,  0.573105,  0.753299,  0.900613,  1.05457,  1.58199,  2.17844,  2.43035,  2.61604,
+  0.344653,  0.543532,  0.703715,  0.862285,  1.19822,  1.33821,  1.57908,  2.06077,  2.30675,  2.48575,
+  0.220701,  0.326795,  0.520618,  0.755133,  1.29555,  1.45189,  1.6905,  2.20005,  2.41427,  2.61591,
+  0.279478,  0.332193,  0.801527,  1.34597,  1.48748,  1.6785,  1.9222,  2.10002,  2.58557,  2.71339,
+  0.163502,  0.212169,  0.365096,  0.525464,  0.869846,  1.20881,  1.79399,  2.04031,  2.29718,  2.4698,
+  0.285531,  0.341488,  0.754059,  1.17002,  1.30084,  1.5137,  1.69986,  1.88992,  2.58146,  2.70687,
+  0.249595,  0.366997,  0.626427,  0.945219,  1.40704,  1.56056,  1.83166,  2.23115,  2.46635,  2.65452,
+  0.271671,  0.443136,  1.15641,  1.40646,  1.67652,  1.85648,  2.06322,  2.2305,  2.47584,  2.63958,
+  0.28662,  0.427806,  0.63732,  0.803409,  0.996161,  1.26638,  1.68175,  2.00397,  2.39465,  2.58855,
+  0.314906,  0.440519,  0.612129,  0.896126,  1.47241,  1.71769,  1.88135,  2.09944,  2.36917,  2.49547,
+  0.170277,  0.25127,  0.405477,  0.915641,  1.12689,  1.43663,  1.71477,  1.8932,  2.55299,  2.73852,
+  0.27941,  0.337137,  0.734563,  1.28105,  1.4806,  1.61188,  1.85321,  1.99488,  2.41605,  2.65483,
+  0.165776,  0.226083,  0.417544,  0.744574,  1.04447,  1.53489,  1.80849,  1.94495,  2.13849,  2.60179,
+  0.264579,  0.336652,  0.542033,  0.71019,  0.913338,  1.65575,  1.81776,  2.23196,  2.52444,  2.65852,
+  0.158194,  0.235588,  0.338347,  0.541657,  1.58338,  1.76629,  2.00914,  2.24334,  2.50394,  2.77516,
+  0.332612,  0.50962,  0.822935,  1.07588,  1.45429,  1.65079,  1.97445,  2.25128,  2.53734,  2.74512,
+  0.262817,  0.359709,  0.520893,  0.707667,  0.818364,  1.43885,  1.97125,  2.08767,  2.49701,  2.64644,
+  0.2332,  0.399599,  0.612456,  0.775547,  1.19919,  1.35576,  1.6469,  2.13625,  2.34249,  2.69574,
+  0.149687,  0.238538,  0.372248,  0.63452,  1.25581,  1.43379,  1.77004,  1.92875,  2.61191,  2.82493,
+  0.137016,  0.210297,  0.591489,  1.12545,  1.37565,  1.6853,  2.08961,  2.39089,  2.70446,  2.84443,
+  0.21349,  0.341024,  0.541716,  0.750061,  1.0882,  1.24458,  1.55534,  1.96557,  2.1879,  2.38371,
+  0.300159,  0.489291,  0.825022,  1.0371,  1.19409,  1.34738,  1.68475,  2.02494,  2.46561,  2.74097,
+  0.170029,  0.255033,  0.392758,  0.727117,  1.38207,  1.57968,  1.80091,  1.95907,  2.28234,  2.7288,
+  0.175883,  0.365509,  1.11217,  1.38587,  1.72039,  1.97781,  2.2453,  2.42161,  2.62957,  2.754,
+  0.16259,  0.248164,  0.45463,  0.763209,  0.966031,  1.28234,  1.73074,  1.93805,  2.47938,  2.66756,
+  0.258043,  0.345866,  0.55652,  0.981312,  1.36153,  1.48238,  1.87224,  2.15823,  2.36227,  2.55503,
+  0.234139,  0.348843,  0.528234,  0.987884,  1.19522,  1.42215,  1.96003,  2.12737,  2.60332,  2.793,
+  0.179699,  0.559209,  0.867682,  1.08884,  1.31689,  1.5715,  1.9222,  2.19739,  2.50112,  2.72868,
+  0.216784,  0.310791,  0.487492,  0.932903,  1.20195,  1.36655,  1.8004,  1.9775,  2.17426,  2.53707,
+  0.186878,  0.400655,  0.580952,  0.846287,  1.10387,  1.26678,  1.84277,  2.01959,  2.488,  2.71722,
+  0.164641,  0.248712,  0.389358,  0.772822,  1.21256,  1.36992,  2.02587,  2.27762,  2.61752,  2.80953,
+  0.351899,  0.520326,  0.926597,  1.21965,  1.50984,  1.67684,  1.92174,  2.11125,  2.35638,  2.54593,
+  0.242182,  0.365285,  0.506156,  0.71602,  0.865221,  1.01169,  1.78692,  2.12298,  2.35088,  2.76773,
+  0.413776,  0.559566,  0.7358,  0.928997,  1.07912,  1.26718,  1.88007,  2.15249,  2.32483,  2.53986,
+  0.210597,  0.329568,  0.469735,  0.78859,  1.21549,  1.31981,  1.71146,  2.05899,  2.24544,  2.65373,
+  0.197937,  0.254148,  0.477985,  1.22709,  1.62992,  1.76743,  2.18698,  2.3851,  2.59487,  2.72554,
+  0.205489,  0.333855,  0.523915,  0.706275,  1.10215,  1.24661,  1.6489,  2.02683,  2.28169,  2.75931,
+  0.230328,  0.322431,  0.861834,  1.14561,  1.34721,  1.57611,  1.80728,  2.00482,  2.35437,  2.57225,
+  0.224898,  0.282022,  0.506636,  1.1523,  1.62656,  1.75209,  2.02818,  2.21882,  2.48896,  2.67046,
+  0.313732,  0.625469,  1.16447,  1.49908,  1.74961,  2.01853,  2.26223,  2.4296,  2.69216,  2.8225,
+  0.375623,  0.575307,  0.7912,  0.93577,  1.09694,  1.34339,  1.80799,  2.18731,  2.51972,  2.6948,
+  0.236981,  0.332412,  0.47927,  0.844461,  1.34764,  1.49073,  1.68394,  2.03914,  2.29762,  2.45843,
+  0.129047,  0.20625,  0.636751,  0.865101,  1.13689,  1.35661,  1.7048,  1.91668,  2.51836,  2.75632,
+  0.195171,  0.266517,  0.414793,  1.23956,  1.45291,  1.60836,  1.83305,  2.0478,  2.47352,  2.62199,
+  0.165853,  0.21272,  0.372757,  0.536136,  1.01394,  1.33963,  1.55512,  1.94574,  2.23628,  2.44095,
+  0.256981,  0.368868,  0.635878,  0.802543,  1.08476,  1.43912,  1.81473,  2.12052,  2.45815,  2.62146,
+  0.214382,  0.297135,  0.445091,  0.70205,  1.3651,  1.85126,  2.06703,  2.2073,  2.47073,  2.61243,
+  0.34071,  0.532103,  0.935278,  1.17102,  1.37789,  1.6386,  1.96527,  2.24616,  2.63127,  2.80634,
+  0.310524,  0.412051,  0.582478,  0.768755,  0.871594,  1.11985,  1.92635,  2.20751,  2.40709,  2.63663,
+  0.249349,  0.443517,  0.631532,  0.810096,  1.20513,  1.35721,  1.6074,  1.98416,  2.20802,  2.64511,
+  0.14309,  0.185312,  0.325214,  0.504,  1.13447,  1.32791,  1.67365,  2.0069,  2.38928,  2.74609,
+  0.226575,  0.298946,  0.453938,  0.998061,  1.3946,  1.59728,  2.06418,  2.22325,  2.42547,  2.56946,
+  0.183924,  0.255181,  0.415834,  0.624247,  1.04234,  1.20308,  1.55524,  2.12531,  2.40035,  2.66192,
+  0.27561,  0.365968,  0.654909,  0.990108,  1.1708,  1.45533,  2.07756,  2.25267,  2.50232,  2.68595,
+  0.204334,  0.287844,  0.39481,  0.761295,  1.5012,  1.78471,  1.93557,  2.15283,  2.34926,  2.54564,
+  0.342976,  0.527539,  0.917466,  1.16059,  1.49953,  1.76183,  2.09527,  2.30187,  2.54057,  2.69469,
+  0.202374,  0.333367,  0.480179,  0.708677,  0.819505,  1.10529,  1.80664,  1.95335,  2.61084,  2.7975,
+  0.307033,  0.368471,  0.602486,  1.10861,  1.41335,  1.52864,  1.79852,  1.98614,  2.16905,  2.43726,
+  0.144073,  0.196932,  0.386988,  0.819061,  1.28977,  1.62507,  1.90192,  2.13611,  2.48302,  2.70797,
+  0.17676,  0.268627,  0.662082,  1.05687,  1.54797,  1.71139,  1.97294,  2.24991,  2.54447,  2.76109,
+  0.191409,  0.292985,  0.492193,  0.800526,  1.04184,  1.27855,  1.83663,  2.02868,  2.24939,  2.62778,
+  0.324102,  0.399146,  0.687435,  0.868704,  1.02296,  1.58208,  1.85385,  1.98188,  2.55491,  2.67706,
+  0.229172,  0.302836,  0.481418,  0.704363,  0.967567,  1.82827,  2.0973,  2.25847,  2.54911,  2.70465,
+  0.467124,  0.696788,  0.9395,  1.09499,  1.27754,  1.4885,  1.89628,  2.15847,  2.47418,  2.65999,
+  0.175418,  0.234039,  0.367674,  0.513586,  0.747619,  1.0084,  1.58316,  2.05311,  2.36329,  2.68115,
+  0.410273,  0.561949,  0.736215,  0.956685,  1.13569,  1.28842,  1.75061,  1.93771,  2.15132,  2.48934,
+  0.204541,  0.277613,  0.529607,  0.722971,  1.19998,  1.44734,  1.71563,  1.92105,  2.35778,  2.50749,
+  0.253116,  0.311907,  0.696982,  1.32008,  1.57542,  1.70532,  2.00507,  2.16867,  2.46188,  2.66505,
+  0.163657,  0.237902,  0.393374,  0.60949,  0.854272,  1.08998,  1.52639,  1.84234,  2.12625,  2.67905,
+  0.448627,  0.530664,  0.812719,  1.0952,  1.20764,  1.57541,  1.88421,  2.0343,  2.55301,  2.68835,
+  0.262717,  0.338748,  0.512685,  1.00354,  1.48018,  1.62208,  1.82852,  2.14242,  2.35646,  2.51153,
+  0.417111,  0.636688,  1.03657,  1.31988,  1.67992,  1.87339,  2.07372,  2.2494,  2.50773,  2.65105,
+  0.263698,  0.461151,  0.618737,  0.830471,  1.00404,  1.15887,  1.80157,  2.02022,  2.30656,  2.74304,
+  0.387779,  0.575108,  0.729791,  0.932981,  1.36116,  1.50516,  1.75118,  2.06847,  2.33826,  2.48764,
+  0.18151,  0.265666,  0.454631,  1.08238,  1.2873,  1.5792,  1.85118,  2.09696,  2.46724,  2.64693,
+  0.277668,  0.345119,  0.602341,  1.1792,  1.37899,  1.54562,  1.81386,  1.96259,  2.4918,  2.66445,
+  0.17932,  0.24808,  0.456925,  0.722589,  1.12693,  1.57945,  1.7994,  1.95067,  2.48412,  2.70724,
+  0.314322,  0.381145,  0.608651,  0.727613,  0.890472,  1.61028,  2.13617,  2.25836,  2.59638,  2.70978,
+  0.189539,  0.266068,  0.419729,  0.651693,  1.41016,  1.64311,  1.85481,  2.27558,  2.49205,  2.72201,
+  0.254466,  0.313038,  0.594149,  1.01254,  1.68881,  1.93546,  2.11918,  2.28787,  2.53554,  2.66793,
+  0.134691,  0.171906,  0.30274,  0.492936,  0.899551,  1.22919,  1.73394,  2.01288,  2.44634,  2.74276,
+  0.231556,  0.365068,  0.680761,  0.889142,  1.11134,  1.2959,  1.54264,  1.97178,  2.42756,  2.63191,
+  0.222525,  0.305606,  0.527193,  0.687519,  1.18138,  1.67176,  1.86368,  2.07202,  2.63452,  2.77927,
+  0.17877,  0.237415,  0.37516,  0.856692,  1.67368,  1.81374,  2.01679,  2.27242,  2.5226,  2.73596,
+  0.193532,  0.268731,  0.451328,  0.753471,  0.984854,  1.28535,  1.68565,  1.88412,  2.09168,  2.24342,
+  0.476037,  0.65161,  0.801054,  1.01016,  1.24137,  1.35584,  1.77598,  2.08615,  2.27291,  2.45435,
+  0.211657,  0.308331,  0.421366,  0.865966,  1.41877,  1.55674,  1.78615,  2.02033,  2.19859,  2.63198,
+  0.203789,  0.490794,  1.01014,  1.27501,  1.47221,  1.81014,  2.17064,  2.43766,  2.66212,  2.78806,
+  0.174355,  0.252095,  0.674715,  0.842194,  1.05509,  1.278,  1.69868,  2.07056,  2.39938,  2.65743,
+  0.245109,  0.324049,  0.628822,  0.92791,  1.1236,  1.58007,  1.87864,  2.0546,  2.35872,  2.54684,
+  0.182644,  0.253804,  0.386248,  0.614056,  1.36482,  1.54588,  2.04017,  2.21883,  2.41901,  2.62461,
+  0.295605,  0.367794,  0.690701,  1.05516,  1.1866,  1.64445,  1.94415,  2.10144,  2.56212,  2.69127,
+  0.220878,  0.289573,  0.640307,  0.822072,  1.14406,  1.5678,  1.76641,  1.90811,  2.10346,  2.56049,
+  0.403453,  0.526298,  0.732204,  0.90115,  1.03587,  1.33938,  1.78399,  1.94196,  2.37103,  2.62665,
+  0.212825,  0.25857,  0.471588,  0.685549,  1.26374,  1.82105,  2.16382,  2.2884,  2.62806,  2.78816,
+  0.401181,  0.642053,  1.03247,  1.23611,  1.44445,  1.68668,  2.00672,  2.22851,  2.57211,  2.72396,
+  0.239433,  0.341091,  0.492629,  0.70763,  0.881426,  1.03082,  1.71925,  2.34406,  2.57906,  2.75694,
+  0.294093,  0.38277,  0.577412,  1.00928,  1.31304,  1.4193,  1.74467,  2.09423,  2.28904,  2.47584,
+  0.169805,  0.236922,  0.403314,  0.638995,  1.17645,  1.35214,  1.66557,  1.90976,  2.15012,  2.71624,
+  0.210447,  0.277913,  0.452474,  1.40269,  1.51343,  1.72094,  1.90394,  2.2785,  2.58376,  2.74318,
+  0.159574,  0.225382,  0.374008,  0.714137,  1.01125,  1.37171,  1.69916,  1.87159,  2.02706,  2.49119,
+  0.258602,  0.557253,  0.81972,  1.03886,  1.30147,  1.44536,  1.83061,  2.09817,  2.32081,  2.54107,
+  0.232756,  0.282242,  0.631974,  0.898694,  1.53744,  1.86922,  2.06397,  2.23446,  2.49823,  2.63352,
+  0.580133,  0.997946,  1.32096,  1.48187,  1.73161,  1.89858,  2.12071,  2.29013,  2.53009,  2.65166,
+  0.21184,  0.307093,  0.45336,  0.945579,  1.25082,  1.49029,  1.72414,  2.2811,  2.5627,  2.7526,
+  0.314276,  0.493555,  0.667782,  0.8965,  1.32301,  1.48262,  1.66749,  1.97441,  2.42735,  2.55568,
+  0.182455,  0.261592,  0.418011,  1.05093,  1.26139,  1.44337,  1.66547,  1.93903,  2.44469,  2.63845,
+  0.24157,  0.306934,  0.491293,  1.10595,  1.55483,  1.66652,  1.92392,  2.08765,  2.3676,  2.65489,
+  0.190084,  0.25485,  0.454062,  0.724519,  1.08336,  1.39389,  1.89234,  2.08886,  2.32176,  2.4843,
+  0.306497,  0.389831,  0.721793,  0.839714,  1.12475,  1.6524,  1.82292,  2.27331,  2.5692,  2.6696,
+  0.1862,  0.27346,  0.383201,  0.564758,  1.51107,  1.84502,  1.99828,  2.1941,  2.38869,  2.58792,
+  0.300722,  0.478218,  0.823364,  1.12749,  1.59114,  1.87135,  2.17472,  2.40318,  2.62478,  2.7824,
+  0.228884,  0.358342,  0.504622,  0.795874,  1.00562,  1.15261,  1.90805,  2.12479,  2.37247,  2.79758,
+  0.171885,  0.248234,  0.432842,  0.833143,  1.04089,  1.26929,  1.66164,  1.91863,  2.15896,  2.6534,
+  0.140943,  0.193684,  0.343025,  0.562303,  1.06955,  1.54333,  1.82447,  1.96164,  2.46351,  2.77054,
+  0.173053,  0.245656,  0.360656,  0.960618,  1.58953,  1.68991,  1.98414,  2.143,  2.58839,  2.7594,
+  0.24018,  0.429951,  0.63744,  0.786596,  1.06915,  1.22657,  1.47088,  1.95205,  2.19506,  2.61597,
+  0.367862,  0.471897,  0.730834,  1.08232,  1.22629,  1.46293,  1.92817,  2.05247,  2.40674,  2.66246,
+  0.247175,  0.358209,  0.535946,  0.781876,  1.3637,  1.63524,  1.80723,  1.99378,  2.45277,  2.60104,
+  0.445578,  0.687898,  1.11411,  1.30103,  1.5774,  1.88604,  2.2249,  2.43653,  2.65969,  2.76103,
+  0.214389,  0.336025,  0.487794,  0.759534,  0.970518,  1.1411,  1.45733,  1.62464,  2.30692,  2.71527,
+  0.3773,  0.466775,  0.716121,  1.08378,  1.25654,  1.41124,  1.78943,  1.93637,  2.20557,  2.56236,
+  0.148362,  0.214593,  0.545023,  0.840437,  1.19333,  1.48066,  1.79187,  2.08342,  2.41054,  2.67613,
+  0.150403,  0.278398,  0.792676,  0.97668,  1.21885,  1.40524,  1.77506,  2.16246,  2.54786,  2.74638,
+  0.236301,  0.328633,  0.630867,  0.839915,  1.04235,  1.29887,  1.62775,  1.83949,  2.29893,  2.49396,
+  0.337889,  0.49792,  0.711277,  0.85042,  0.992027,  1.24688,  1.71075,  2.08668,  2.52716,  2.70716,
+  0.172215,  0.23654,  0.372897,  0.525146,  1.18258,  1.73573,  1.92703,  2.11462,  2.31917,  2.54278,
+  0.415304,  0.624807,  0.906616,  1.11784,  1.44615,  1.66942,  1.94841,  2.17282,  2.50453,  2.67075,
+  0.265417,  0.407241,  0.613894,  0.816534,  0.980063,  1.15606,  1.75675,  2.27485,  2.49719,  2.71224,
+  0.27644,  0.468209,  0.649518,  0.816686,  1.19517,  1.35552,  1.54923,  1.93527,  2.21787,  2.42698,
+  0.188925,  0.277012,  0.412665,  0.672627,  1.35481,  1.51452,  1.69999,  2.14455,  2.38219,  2.58608,
+  0.24263,  0.352485,  0.912974,  1.34378,  1.60443,  1.80187,  2.01479,  2.19307,  2.46081,  2.632,
+  0.190903,  0.285841,  0.44907,  0.760328,  0.954285,  1.18294,  1.69264,  1.87816,  2.27684,  2.46596,
+  0.220659,  0.300374,  0.721694,  0.947306,  1.29833,  1.56298,  1.76062,  1.88825,  2.50644,  2.68968,
+  0.213168,  0.290928,  0.695227,  0.918179,  1.37819,  1.63199,  1.84789,  2.00307,  2.35836,  2.61935,
+  0.328586,  0.517244,  0.93732,  1.37624,  1.57484,  1.76435,  2.05863,  2.22433,  2.58444,  2.75665,
+  0.248486,  0.367007,  0.562147,  0.750632,  0.902785,  1.14756,  1.63742,  1.91206,  2.41399,  2.6057,
+  0.310691,  0.477895,  0.670796,  0.940507,  1.41829,  1.5635,  1.80514,  2.11408,  2.37636,  2.53516,
+  0.256555,  0.41421,  0.559427,  0.981289,  1.19165,  1.37831,  1.6784,  1.84931,  2.5767,  2.75663,
+  0.291424,  0.335003,  0.750149,  1.28965,  1.43721,  1.59999,  1.80318,  1.96741,  2.60175,  2.73376,
+  0.195254,  0.279513,  0.451755,  0.649111,  0.828694,  1.60951,  1.91491,  2.09122,  2.31959,  2.5349,
+  0.222304,  0.332624,  0.475678,  0.685205,  1.03033,  1.73722,  1.92098,  2.37829,  2.70672,  2.81773,
+  0.164833,  0.240093,  0.359862,  0.801929,  1.51368,  1.64171,  2.04052,  2.24884,  2.48866,  2.71403,
+  0.214777,  0.287322,  0.572644,  1.14507,  1.36711,  1.75269,  2.04242,  2.22207,  2.54305,  2.69789,
+  0.226099,  0.330382,  0.474439,  0.687757,  0.799187,  1.31984,  1.94457,  2.0781,  2.3678,  2.50846,
+  0.24454,  0.392163,  0.553692,  0.729765,  1.24786,  1.44838,  1.61759,  2.07464,  2.34005,  2.51806,
+  0.175381,  0.314231,  0.446023,  0.797404,  1.32846,  1.43973,  1.79335,  1.93957,  2.4688,  2.72165,
+  0.205808,  0.29367,  0.452447,  1.07427,  1.28823,  1.65563,  1.8575,  2.36469,  2.63981,  2.79814,
+  0.253926,  0.392653,  0.587584,  0.800134,  0.97631,  1.18559,  1.57069,  1.82141,  2.09089,  2.34902,
+  0.322461,  0.410912,  0.723569,  1.06064,  1.20152,  1.40036,  1.57919,  1.78876,  2.46024,  2.6166,
+  0.211266,  0.304981,  0.436011,  0.771978,  1.49062,  1.67775,  1.88623,  2.1135,  2.32635,  2.72726,
+  0.235012,  0.406911,  0.864785,  1.29148,  1.70829,  1.93855,  2.1799,  2.3524,  2.56379,  2.71145,
+  0.176814,  0.26862,  0.445837,  0.823113,  1.02978,  1.27157,  1.62339,  1.81122,  2.40214,  2.61417,
+  0.241865,  0.339268,  0.507509,  1.00368,  1.20435,  1.37256,  1.94079,  2.10137,  2.38561,  2.66998,
+  0.230878,  0.334743,  0.50037,  0.879929,  1.02189,  1.53377,  1.97079,  2.12897,  2.56726,  2.71729,
+  0.297505,  0.451574,  0.748848,  0.988527,  1.36624,  1.60667,  1.89466,  2.17448,  2.52143,  2.75917,
+  0.199265,  0.271145,  0.49816,  0.854679,  1.1721,  1.36415,  1.76208,  1.96909,  2.17354,  2.31163,
+  0.222173,  0.424864,  0.564942,  0.829809,  1.03817,  1.19405,  1.7206,  1.85809,  2.43176,  2.74146,
+  0.181961,  0.226819,  0.390513,  0.556339,  1.0566,  1.55306,  2.12835,  2.25802,  2.6025,  2.80212,
+  0.3576,  0.565047,  1.15301,  1.35031,  1.53358,  1.71854,  1.95789,  2.17535,  2.50565,  2.67849,
+  0.162257,  0.236808,  0.374039,  0.570569,  0.748034,  1.17226,  1.82339,  2.05303,  2.51377,  2.77207,
+  0.305794,  0.46587,  0.645121,  0.88265,  1.14129,  1.26686,  1.70158,  2.00288,  2.18412,  2.41125,
+  0.231652,  0.380738,  0.549642,  0.83741,  1.22527,  1.33297,  1.85158,  2.11937,  2.31508,  2.73211,
+  0.235449,  0.286771,  0.684809,  1.34666,  1.52663,  1.70348,  2.10149,  2.25455,  2.57718,  2.71899,
+  0.23387,  0.446515,  0.60508,  0.814654,  1.05496,  1.1788,  1.63316,  1.84974,  2.13938,  2.73277,
+  0.271706,  0.335152,  0.857227,  1.25374,  1.38719,  1.70217,  1.89677,  2.19111,  2.48,  2.60136,
+  0.237386,  0.314549,  0.438339,  0.912164,  1.57776,  1.87779,  2.03279,  2.19704,  2.41232,  2.53648,
+  0.361168,  0.574093,  1.02384,  1.46852,  1.69056,  1.91737,  2.18737,  2.33403,  2.6691,  2.80629,
+  0.27848,  0.398742,  0.573342,  0.839212,  1.07389,  1.22209,  1.69168,  2.16526,  2.37741,  2.53688,
+  0.286018,  0.447947,  0.61506,  0.849446,  1.31947,  1.46358,  1.76995,  2.00103,  2.18943,  2.45038,
+  0.21944,  0.301601,  0.668534,  0.861094,  1.21,  1.49867,  1.74512,  1.87777,  2.31438,  2.6196,
+  0.223591,  0.352153,  0.598841,  1.21789,  1.35908,  1.59174,  1.77109,  2.21386,  2.56154,  2.73542,
+  0.176857,  0.236601,  0.395107,  0.634632,  1.13349,  1.33512,  1.77037,  1.98131,  2.20656,  2.33972,
+  0.334735,  0.402265,  0.659168,  0.781639,  0.975228,  1.665,  1.87207,  2.04753,  2.47696,  2.57398,
+  0.215968,  0.284755,  0.524241,  0.78146,  1.33481,  1.77238,  1.95388,  2.19421,  2.57825,  2.74194,
+  0.298193,  0.489879,  0.812985,  1.18369,  1.49642,  1.67998,  2.10879,  2.31656,  2.67378,  2.85161,
+  0.312989,  0.415446,  0.618011,  0.899096,  1.08368,  1.26338,  1.8874,  2.24306,  2.41945,  2.57048,
+  0.244471,  0.431115,  0.601512,  0.813139,  1.10216,  1.22106,  1.69244,  2.03316,  2.2218,  2.61984,
+  0.150949,  0.21906,  0.349217,  0.611327,  1.07711,  1.25055,  1.91552,  2.08398,  2.45,  2.79254,
+  0.161611,  0.218964,  0.445377,  0.927863,  1.45115,  1.76846,  2.13001,  2.36672,  2.666,  2.81405,
+  0.196,  0.297256,  0.497266,  0.6919,  1.08988,  1.27368,  1.51372,  2.00647,  2.27378,  2.57222,
+  0.335268,  0.460795,  0.685187,  0.867664,  1.01381,  1.47955,  2.01199,  2.16848,  2.57264,  2.71756,
+  0.257604,  0.340872,  0.499757,  0.843052,  1.39655,  1.83169,  2.03423,  2.17033,  2.42262,  2.5405,
+  0.417663,  0.631718,  0.955424,  1.19732,  1.6598,  1.87988,  2.1688,  2.35905,  2.57809,  2.69825,
+  0.162052,  0.251583,  0.4399,  0.660911,  0.903902,  1.3203,  1.62476,  1.77858,  2.53053,  2.79971,
+  0.256861,  0.322803,  0.68537,  1.08644,  1.26328,  1.56988,  1.85165,  2.01495,  2.26471,  2.44701,
+  0.125192,  0.176171,  0.336135,  0.7816,  1.20022,  1.43997,  1.80542,  2.07752,  2.46247,  2.73819,
+  0.102286,  0.191322,  0.774556,  1.07615,  1.36946,  1.62715,  1.97301,  2.236,  2.60937,  2.81298,
+  0.173442,  0.232622,  0.491622,  0.844157,  1.09524,  1.3708,  1.69697,  2.05141,  2.31606,  2.50205,
+  0.257531,  0.343598,  0.654071,  0.838985,  1.0481,  1.48747,  1.72538,  1.89742,  2.43051,  2.586,
+  0.1979,  0.276312,  0.440283,  0.705103,  1.26734,  1.7403,  1.93448,  2.15401,  2.4002,  2.62414,
+  0.40959,  0.596785,  0.983751,  1.18177,  1.37115,  1.50238,  1.75828,  2.01857,  2.38005,  2.59215,
+  0.231819,  0.33289,  0.483514,  0.644585,  0.816808,  0.926308,  1.4033,  2.23301,  2.46786,  2.67846,
+  0.25861,  0.340064,  0.670485,  0.908467,  1.10761,  1.45624,  1.75958,  1.93218,  2.11312,  2.31013,
+  0.184377,  0.249203,  0.410806,  0.587907,  1.3025,  1.51032,  1.72443,  1.98189,  2.2829,  2.42213,
+  0.25411,  0.313328,  0.659859,  1.26582,  1.41295,  1.66593,  1.92715,  2.10198,  2.55145,  2.67303,
+  0.161592,  0.23748,  0.376535,  0.637094,  0.823028,  1.13761,  1.69642,  1.87577,  2.40363,  2.63962,
+  0.384501,  0.466812,  0.740791,  0.938093,  1.06235,  1.50928,  1.74914,  1.9178,  2.54816,  2.67151,
+  0.333872,  0.419367,  0.638994,  1.09262,  1.52055,  1.64945,  1.86662,  2.14894,  2.34672,  2.50614,
+  0.426216,  0.686997,  1.23588,  1.42885,  1.61159,  1.79286,  2.01759,  2.23372,  2.54777,  2.69661,
+  0.262949,  0.367509,  0.530429,  0.741867,  0.872474,  1.0696,  1.74557,  2.06119,  2.28384,  2.49418,
+  0.335782,  0.547236,  0.716211,  0.919077,  1.27569,  1.40844,  1.68512,  1.96739,  2.21764,  2.44668,
+  0.227629,  0.330991,  0.486068,  1.11757,  1.30498,  1.51013,  1.75726,  1.94697,  2.62556,  2.7826,
+  0.35985,  0.436633,  0.750634,  1.20151,  1.33757,  1.59484,  1.97027,  2.11384,  2.57381,  2.72996,
+  0.211871,  0.304028,  0.512758,  0.663762,  1.08635,  1.63333,  1.81802,  2.12958,  2.39108,  2.60077,
+  0.196092,  0.279726,  0.434488,  0.624802,  0.772358,  1.40438,  1.94878,  2.16092,  2.63,  2.77518,
+  0.176304,  0.262521,  0.373719,  0.581101,  1.52011,  1.73617,  1.93323,  2.14017,  2.35813,  2.75352,
+  0.254932,  0.381411,  0.806187,  1.10229,  1.53452,  1.75028,  1.9709,  2.15987,  2.45592,  2.65841,
+  0.190385,  0.288656,  0.449066,  0.678174,  0.812376,  1.44933,  1.72866,  1.96632,  2.63881,  2.78955,
+  0.251178,  0.386509,  0.609363,  0.797102,  1.02416,  1.18173,  1.45466,  2.01263,  2.49309,  2.69893,
+  0.166654,  0.266226,  0.385171,  0.71199,  1.3979,  1.53235,  1.91597,  2.088,  2.56527,  2.78953,
+  0.238453,  0.306036,  0.449309,  0.876277,  1.52144,  1.93398,  2.13442,  2.26799,  2.5376,  2.65825,
+  0.161634,  0.219919,  0.353206,  0.524346,  0.961806,  1.20771,  1.68792,  1.91694,  2.16187,  2.32066,
+  0.413612,  0.597095,  0.793763,  0.98629,  1.28179,  1.41266,  1.65246,  2.01609,  2.38416,  2.52858,
+  0.228655,  0.341562,  0.480989,  0.988605,  1.371,  1.47742,  1.86103,  2.01585,  2.33975,  2.77315,
+  0.259092,  0.597012,  0.985224,  1.32174,  1.64335,  1.95737,  2.28868,  2.49747,  2.71649,  2.84447,
+  0.185652,  0.304664,  0.446232,  0.864434,  1.09179,  1.27377,  1.94257,  2.09554,  2.52465,  2.76824,
+  0.176687,  0.256678,  0.745652,  0.934909,  1.28376,  1.44006,  1.76524,  2.12209,  2.3881,  2.59055,
+  0.189805,  0.275637,  0.440995,  0.821356,  1.25602,  1.41098,  1.92978,  2.12014,  2.39603,  2.60464,
+  0.266823,  0.337688,  0.819408,  1.13475,  1.2892,  1.77703,  1.98289,  2.22175,  2.59029,  2.6981,
+  0.205348,  0.276512,  0.527305,  0.727412,  1.02465,  1.65398,  1.90418,  2.04661,  2.21792,  2.45566,
+  0.293498,  0.424494,  0.613795,  0.95613,  1.13398,  1.3248,  1.80903,  1.95392,  2.29385,  2.57588,
+  0.18312,  0.24965,  0.376204,  0.543914,  1.35083,  1.90722,  2.09255,  2.25571,  2.51439,  2.6879,
+  0.541205,  0.789796,  1.05895,  1.26942,  1.5039,  1.70219,  1.97018,  2.17544,  2.49681,  2.65224,
+  0.229326,  0.339475,  0.451881,  0.66121,  0.795832,  1.0738,  2.0271,  2.20637,  2.4789,  2.72678,
+  0.330006,  0.506868,  0.673076,  0.887406,  1.22877,  1.34923,  1.78129,  2.08658,  2.27776,  2.48003,
+  0.138389,  0.200001,  0.396259,  0.811975,  1.09071,  1.46041,  1.74549,  1.90427,  2.34825,  2.69989,
+  0.176584,  0.242161,  0.37827,  1.17785,  1.56472,  1.67817,  1.95162,  2.12141,  2.58011,  2.73713,
+  0.145852,  0.198423,  0.335644,  0.550505,  1.01973,  1.37119,  1.79763,  1.94383,  2.20749,  2.74647,
+  0.385078,  0.503696,  0.703239,  1.06999,  1.36574,  1.47205,  1.82583,  2.15964,  2.37128,  2.52097,
+  0.28495,  0.38805,  0.507352,  0.879125,  1.52353,  1.77624,  1.9296,  2.15756,  2.44799,  2.5864,
+  0.491116,  0.756155,  1.2552,  1.52246,  1.77658,  2.02812,  2.28606,  2.42977,  2.67911,  2.77616,
+  0.252477,  0.396081,  0.713022,  0.861502,  1.15222,  1.3708,  1.61401,  2.1448,  2.57407,  2.71253,
+  0.282756,  0.438437,  0.613566,  0.847746,  1.26077,  1.37906,  1.6422,  2.13754,  2.36837,  2.52216,
+  0.203971,  0.322195,  0.479842,  0.953133,  1.21128,  1.39763,  1.80081,  1.95452,  2.40348,  2.57371,
+  0.264533,  0.358424,  0.628768,  1.11124,  1.34025,  1.50648,  1.99959,  2.19411,  2.46141,  2.66736,
+  0.17773,  0.22368,  0.394553,  0.556177,  0.947415,  1.50064,  1.73353,  1.92605,  2.26147,  2.43605,
+  0.314223,  0.363636,  0.727886,  0.85188,  1.05384,  1.79813,  1.97435,  2.1826,  2.538,  2.62968,
+  0.201778,  0.2755,  0.404891,  0.747466,  1.50005,  1.84118,  1.99884,  2.22681,  2.48199,  2.66951,
+  0.132164,  0.314955,  0.821473,  1.19604,  1.42659,  1.69993,  2.03686,  2.3235,  2.68547,  2.82896,
+  0.223374,  0.347335,  0.50773,  0.773547,  0.967916,  1.13413,  1.9914,  2.30657,  2.52136,  2.78875,
+  0.312742,  0.449784,  0.583287,  0.934234,  1.26857,  1.36506,  1.5693,  1.68705,  2.0773,  2.59502,
+  0.124286,  0.162126,  0.29073,  0.654031,  1.23166,  1.53846,  1.89307,  2.18478,  2.56264,  2.79822,
+  0.177049,  0.251654,  0.367891,  0.912504,  1.55758,  1.69305,  1.89899,  2.07214,  2.35016,  2.64604,
+  0.240517,  0.378333,  0.547809,  0.754272,  0.973321,  1.10367,  1.57442,  2.02805,  2.21113,  2.56271,
+  0.427795,  0.519003,  0.771284,  0.93724,  1.08662,  1.60988,  1.87875,  2.05279,  2.53412,  2.65715,
+  0.22437,  0.317969,  0.439666,  0.812931,  1.3985,  1.62663,  1.79418,  2.114,  2.30916,  2.49684
+};
+  /* codebook/lspjvm2.txt */
+static const float codes1[] = {
+  0.005167,  -0.03731,  -0.002159,  0.016849,  0.130396,
+  0.039445,  0.03168,  -0.074412,  -0.031499,  0.060536,
+  0.019479,  -0.030564,  -0.048137,  -0.056279,  -0.027829,
+  0.020585,  -0.01127,  0.023913,  -0.005706,  0.011407,
+  -0.023217,  0.107455,  -0.037777,  0.00407,  -0.017279,
+  -0.090444,  0.007641,  0.099001,  -0.047913,  -0.017199,
+  0.0227,  -0.063865,  0.047213,  0.043843,  -0.036225,
+  0.001312,  -0.123861,  -0.038988,  0.058666,  0.074541,
+  0.039508,  0.1103,  0.013954,  -0.119228,  -0.035807,
+  -0.047392,  0.027035,  -0.004412,  -0.03265,  -0.03715,
+  0.002491,  -0.045447,  0.15826,  0.022828,  -0.030124,
+  -0.047856,  0.088744,  -0.009678,  0.106688,  0.08769,
+  -0.027941,  0.044084,  -0.0285,  0.018736,  -0.069969,
+  -0.035358,  -0.051568,  -0.030459,  -0.017899,  0.027632,
+  -0.018607,  -0.123557,  0.019228,  0.057485,  -0.028907,
+  0.019057,  0.038151,  -0.08022,  0.034222,  0.023081,
+  0.021312,  0.041905,  0.112903,  0.024092,  0.093974,
+  -0.116679,  0.015344,  -0.066059,  -0.096437,  0.004041,
+  -0.022464,  -0.11626,  0.047819,  -0.003921,  -0.073504,
+  0.001975,  -0.025869,  0.0282,  0.12269,  0.010627,
+  -0.035672,  0.078963,  -0.009686,  0.000743,  -0.147582,
+  0.016932,  -0.020291,  -0.096896,  -0.237875,  -0.029121,
+  0.017376,  -0.04013,  -0.053865,  0.15406,  -0.013215,
+  0.015215,  -0.019023,  -0.070604,  0.032265,  0.04034,
+  0.102365,  -0.022746,  0.019895,  0.05057,  0.008845,
+  -0.034134,  0.044441,  -0.049387,  -0.140481,  0.07257,
+  0.013023,  -0.006079,  0.037574,  0.004937,  -0.081501,
+  0.003696,  0.049908,  0.007355,  0.000403,  0.026006,
+  -0.008466,  0.08068,  0.061382,  -0.108985,  -0.08806,
+  -0.012275,  -0.081061,  0.020333,  -0.079001,  0.068724,
+  -0.014081,  -0.042609,  0.093365,  0.04412,  0.000303,
+  0.063391,  0.096574,  -0.105424,  0.039041,  0.010412,
+  -0.054031,  -0.084948,  0.080406,  -0.035883,  0.137428,
+  0.063037,  0.050562,  0.02469,  -0.031394,  0.13032,
+  -0.015501,  -0.078884,  -0.076886,  -0.013864,  -0.073587,
+  0.048778,  0.003814,  -0.031125,  0.046897,  0.028304,
+  0.048692,  0.132795,  0.06545,  0.059487,  -0.042396,
+  -0.176999,  0.056943,  -0.004135,  -0.049378,  -0.041083,
+  -0.039445,  -0.016292,  -0.00455,  0.06201,  -0.079613,
+  -0.054566,  -0.008476,  -0.01671,  0.049202,  0.025758,
+  -0.078723,  0.092091,  0.096536,  -0.065079,  0.021161,
+  0.076657,  0.009203,  -0.036866,  -0.016559,  0.012823,
+  0.008225,  -0.003006,  0.108033,  0.04312,  -0.06087,
+  -0.019346,  0.02279,  -0.001728,  0.062304,  -0.016965,
+  -0.001302,  -0.01449,  -0.041803,  -0.034058,  -0.197066,
+  -0.033655,  -0.127217,  -0.108681,  -0.010571,  -0.004705,
+  -0.015553,  -0.086069,  0.034109,  -0.101379,  0.002068,
+  -0.004003,  -0.044637,  -0.068617,  0.052228,  -0.047812,
+  -0.043307,  0.035681,  0.042207,  -0.055946,  0.055944,
+  -0.026792,  -0.012601,  -0.05671,  -0.021094,  0.105842,
+  -0.025598,  -0.078858,  -0.013487,  0.030728,  -0.031956,
+  0.031444,  0.022763,  0.025364,  0.121366,  0.070736,
+  -0.084556,  0.098118,  -0.024301,  -0.058655,  -0.043194,
+  -0.011752,  -0.043781,  0.091051,  -0.071201,  -0.02098,
+  0.082904,  -0.031657,  -0.088247,  0.066709,  -0.079182,
+  -0.012151,  0.011796,  -0.010589,  0.100656,  0.094539,
+  0.035967,  0.025338,  0.071826,  0.009741,  -0.040209,
+  0.006866,  -0.015095,  -0.168469,  -0.056133,  0.060145,
+  0.04583,  -0.068969,  0.034551,  0.015842,  -0.092809,
+  0.054699,  0.138744,  0.001726,  0.006927,  0.005167,
+  0.016978,  0.046384,  -0.060183,  -0.040742,  -0.072692,
+  -0.022489,  -0.029728,  -0.065018,  -0.124741,  0.044927,
+  -0.029057,  -0.037154,  0.031068,  0.060086,  0.009984,
+  0.009311,  -0.006957,  -0.105508,  0.059637,  -0.019564,
+  -0.068154,  -0.066443,  0.000799,  0.028579,  0.097063,
+  0.096936,  0.03023,  -0.034623,  -0.088918,  0.040334,
+  0.019439,  -0.050707,  -0.003294,  -0.028505,  -0.053599,
+  0.06246,  -0.070688,  -0.016465,  -0.03568,  0.017378,
+  0.009363,  0.048761,  0.043374,  0.039587,  -0.023232,
+  -0.067033,  0.042663,  0.05407,  -0.042797,  -0.089391,
+  -0.030497,  -0.050249,  0.059528,  0.089089,  -0.029633,
+  0.064125,  -0.086614,  -0.002005,  0.08062,  0.000502,
+  -0.00349,  0.097336,  0.099565,  0.015648,  0.006691,
+  0.077668,  0.016572,  0.035404,  -0.046026,  0.017237,
+  -0.048631,  0.009314,  0.141479,  0.017079,  0.043796,
+  -0.106474,  0.145951,  0.05774,  0.01125,  -0.059443,
+  0.027572,  0.02665,  0.008527,  0.002949,  -0.03768,
+  -0.077991,  -0.090617,  0.00342,  -0.04601,  0.007354,
+  0.019056,  -0.128651,  0.016464,  0.004584,  -0.030883,
+  -0.092069,  0.038976,  -0.08184,  0.066695,  -0.04734,
+  0.003513,  0.040613,  0.046815,  -0.023406,  0.062389,
+  0.021759,  0.024928,  -0.018922,  -0.048006,  0.0638,
+  -0.014416,  -0.050333,  0.042628,  -0.114934,  -0.10145,
+  0.062139,  0.029295,  -0.065908,  0.111463,  0.050781,
+  -0.022707,  0.135414,  0.003548,  0.134535,  -0.048259,
+  -0.092344,  -0.027727,  0.016343,  -0.060786,  -0.081502,
+  -0.005412,  -0.026229,  -0.143331,  0.052404,  -0.077298,
+  -0.035919,  -0.041968,  -0.106108,  -0.004369,  0.065028,
+  0.09637,  -0.053299,  0.043317,  -0.049735,  0.049815,
+  0.032324,  0.051309,  -0.009607,  -0.205917,  0.005023,
+  -0.054316,  -0.022895,  0.099327,  -0.006927,  -0.076574,
+  -0.111024,  0.111026,  0.038381,  -0.060368,  0.064238,
+  -0.034316,  0.026846,  0.02574,  -0.076162,  -0.163904,
+  0.055955,  -0.056885,  0.014831,  -0.120715,  0.090938,
+  0.035289,  -0.036439,  0.060012,  0.080302,  0.036215,
+  0.06525,  0.08303,  -0.058784,  0.104826,  -0.051805,
+  -0.011099,  -0.00642,  0.053042,  0.024127,  0.092534,
+  0.058569,  -0.033442,  0.025186,  -0.018222,  0.117744,
+  0.044345,  -0.042456,  -0.043767,  -0.021378,  -0.121965,
+  0.027371,  0.052731,  -0.020316,  0.036912,  0.115357,
+  0.03115,  0.041547,  0.059267,  -0.039672,  -0.086918,
+  -0.162369,  0.024801,  0.031725,  0.0834,  -0.034463,
+  0.000272,  -0.008147,  -0.002016,  0.131953,  -0.092911,
+  -0.091944,  -0.062864,  -0.005221,  0.063647,  -0.012658,
+  0.042685,  0.067952,  0.038644,  -0.153221,  0.096841,
+  0.108299,  0.089446,  -0.047164,  0.004196,  -0.043268,
+  -0.035456,  0.050838,  0.070444,  0.084465,  -0.07998,
+  -0.048916,  0.057726,  0.023894,  0.027653,  0.017775,
+  0.015461,  -0.030287,  -0.022245,  0.052081,  -0.150947,
+  -0.002682,  -0.056774,  -0.123366,  -0.091754,  0.006536,
+  0.006473,  -0.143025,  0.05469,  -0.043189,  0.03297,
+  0.027446,  0.033127,  -0.132722,  -0.010417,  -0.080097,
+  -0.018187,  0.001858,  0.11129,  -0.090749,  0.059434,
+  -0.068738,  0.090679,  -0.14507,  -0.065277,  0.063514,
+  -0.003982,  -0.056382,  -0.003673,  0.015845,  -0.073396,
+  0.043688,  0.002836,  0.069211,  0.124852,  -0.053313,
+  -0.040946,  0.07044,  -0.107024,  -0.019199,  -0.033672,
+  -0.00144,  0.02168,  0.110595,  -0.053452,  -0.052426,
+  0.035461,  -0.028179,  -0.049041,  0.02258,  -0.010989,
+  -0.002913,  -0.051691,  -0.075881,  0.037241,  0.076377,
+  0.034735,  -0.031556,  0.073516,  -0.001427,  0.016296,
+  -0.017537,  0.003346,  -0.099774,  -0.067624,  -0.044257,
+  -0.018202,  0.030622,  0.012773,  0.046475,  -0.121785,
+  -0.057265,  0.116179,  -0.079916,  0.066396,  0.050104,
+  -0.013177,  0.057766,  -0.047879,  -0.109526,  -0.146491,
+  0.032675,  -0.049318,  -0.057045,  -0.080068,  0.089621,
+  -0.046564,  -0.029992,  0.040828,  0.029281,  -0.037369,
+  -0.009731,  -0.082145,  -0.117622,  0.117077,  0.037369,
+  0.00082,  -0.106634,  -0.007967,  0.000812,  0.140637,
+  0.03653,  0.062121,  -0.065504,  -0.09493,  0.121336,
+  0.01753,  -0.01733,  -0.040402,  -0.018255,  0.010992,
+  0.019746,  -0.027564,  0.033588,  0.042466,  -0.003143,
+  0.013767,  0.084179,  0.033753,  -0.017279,  -0.009676,
+  -0.006452,  0.032645,  0.031852,  -0.030975,  -0.043384,
+  -0.005433,  -0.015258,  0.053273,  0.054748,  -0.064736,
+  0.008959,  -0.141223,  -0.032957,  -0.015079,  0.018198,
+  -0.001681,  0.143079,  0.076,  0.001037,  -0.048744,
+  0.022062,  0.02603,  -0.008263,  -0.050353,  -0.023037,
+  -0.036477,  -0.051733,  0.137823,  -0.034438,  -0.007573,
+  -0.004256,  0.064218,  0.075183,  0.095106,  0.026497,
+  0.02636,  0.009791,  -0.058039,  0.053315,  -0.077817,
+  -0.033283,  -0.081151,  -0.05522,  0.004268,  0.017539,
+  -0.007329,  -0.1172,  0.09322,  0.037359,  0.002718,
+  0.010749,  0.018281,  -0.0758,  -0.024889,  0.00572,
+  0.022129,  0.035613,  0.036187,  0.032246,  0.105439,
+  -0.073766,  0.016887,  -0.059934,  -0.049471,  0.07352,
+  -0.024041,  -0.104642,  0.023557,  -0.059746,  -0.043871,
+  0.022311,  -0.00025,  -0.074027,  0.198593,  0.102732,
+  0.024478,  0.077658,  -0.060042,  -0.018229,  -0.149648,
+  -0.009871,  -0.105822,  0.007585,  -0.161459,  -0.041121,
+  -0.02146,  0.00902,  -0.065018,  0.111801,  -0.024953,
+  0.074594,  -0.026041,  -0.062859,  0.009199,  0.069609,
+  0.078672,  -0.033414,  0.054128,  0.005408,  -0.016273,
+  0.052076,  0.10761,  -0.067518,  -0.0964,  0.033703,
+  -0.01435,  -0.024676,  0.056254,  -0.04377,  -0.060847,
+  -0.004185,  0.07355,  -0.05783,  -0.016644,  0.029096,
+  0.005755,  0.026472,  0.040449,  -0.09195,  -0.048538,
+  -0.034439,  -0.107938,  0.090712,  -0.117001,  0.04317,
+  -0.006505,  -0.035277,  0.117316,  0.127002,  0.047906,
+  -0.001441,  0.118379,  -0.132165,  0.00738,  0.023823,
+  -0.02012,  -0.083725,  0.047284,  0.023795,  0.074123,
+  -0.013439,  0.024994,  0.060254,  -0.06912,  0.166373,
+  -0.024228,  -0.06315,  -0.046506,  -0.077202,  -0.054592,
+  -0.006571,  0.010335,  -0.006568,  0.003982,  0.075837,
+  0.008643,  0.136339,  -0.005502,  0.03391,  -0.066379,
+  -0.127371,  -0.006954,  0.03977,  -0.070123,  0.060925,
+  -0.046386,  -0.02642,  -0.00528,  0.103509,  -0.02231,
+  -0.00374,  -0.014999,  -0.03777,  0.080005,  0.025231,
+  -0.054995,  0.071017,  0.009442,  -0.075737,  0.013441,
+  0.051947,  0.027097,  -0.070351,  -0.055705,  -0.021115,
+  0.021387,  0.029232,  0.163331,  -0.03238,  0.010008,
+  -0.011987,  -0.028631,  0.002665,  0.01477,  -0.009558,
+  -0.034325,  0.01583,  -0.091253,  -0.012677,  -0.107378,
+  -0.034624,  -0.047725,  -0.10233,  0.042525,  -0.006869,
+  0.014048,  -0.043127,  0.052384,  -0.047473,  0.055102,
+  0.009744,  -0.033646,  -0.081755,  -0.001464,  -0.016223,
+  -0.036697,  -0.002279,  0.023279,  -0.036221,  0.101478,
+  -0.058454,  0.065074,  0.003524,  0.00501,  0.097182,
+  -0.038171,  -0.037943,  -0.009994,  -0.033355,  -0.044552,
+  0.041318,  0.065041,  9.2e-05,  0.100816,  0.029007,
+  -0.031803,  0.183537,  -0.009617,  -0.010544,  -0.028465,
+  0.0069,  -0.014988,  0.09049,  -0.174817,  0.027464,
+  0.063314,  -0.049281,  -0.001567,  0.091421,  -0.078603,
+  -0.004869,  -0.063266,  -0.001922,  0.069338,  0.081771,
+  0.058737,  0.073195,  0.081676,  -0.047808,  -0.025797,
+  -0.004185,  0.033203,  -0.125472,  -0.108148,  0.031258,
+  0.035192,  0.029957,  0.046675,  0.047238,  -0.088197,
+  0.033315,  0.114919,  -0.04918,  0.025707,  0.053843,
+  0.035182,  0.140206,  -0.05866,  -0.025978,  -0.019658,
+  -0.014847,  -0.021051,  -0.034385,  -0.121789,  0.173406,
+  -0.112251,  -0.022333,  0.071206,  0.028998,  0.046468,
+  0.067704,  -0.026159,  -0.158316,  0.014936,  0.040216,
+  -0.010137,  -0.053492,  0.004935,  -0.011277,  0.073852,
+  0.091261,  0.114794,  -0.01406,  -0.051545,  0.077316,
+  0.101258,  -0.046137,  0.022994,  -0.066767,  -0.065537,
+  0.049952,  -0.043582,  0.012823,  0.009313,  0.036343,
+  0.054885,  0.037796,  0.02194,  0.013211,  0.006019,
+  -0.099578,  0.058596,  -0.045463,  -0.015632,  -0.087141,
+  -0.019273,  -0.03314,  0.043796,  0.119057,  -0.081813,
+  -0.021538,  -0.070453,  -0.052551,  0.077213,  9.4e-05,
+  0.050268,  0.092271,  0.051688,  -0.025224,  0.075437,
+  0.027983,  0.069205,  0.031787,  -0.099975,  0.004387,
+  -0.002747,  -0.056567,  0.161394,  0.000164,  0.084189,
+  -0.124844,  0.050329,  0.009844,  0.055877,  0.055701,
+  0.030479,  0.028843,  -0.001076,  -0.017173,  -0.10277,
+  -0.038426,  -0.133841,  -0.03584,  -0.072046,  0.020206,
+  0.016438,  -0.097885,  0.041857,  0.034601,  0.030422,
+  -0.089192,  -0.014112,  -0.052276,  0.012005,  -0.029335,
+  -0.011331,  0.101833,  0.063827,  0.044288,  0.101597,
+  -0.034689,  -0.027434,  -0.017801,  -0.079224,  0.067103,
+  -0.027456,  -0.098034,  0.009448,  -0.038986,  -0.156729,
+  0.085023,  0.033136,  -0.021343,  0.110701,  -0.011901,
+  -0.006484,  0.082023,  -0.027094,  0.091208,  -0.013163,
+  -0.012223,  0.005933,  0.010653,  -0.098119,  -0.005304,
+  -0.021061,  -0.058077,  -0.073035,  0.097856,  -0.102847,
+  -0.035329,  -0.092754,  -0.101463,  -0.048671,  0.055015,
+  0.102145,  0.062017,  0.016002,  0.036489,  0.059,
+  0.042861,  0.025447,  -0.019735,  -0.107841,  -0.033752,
+  -0.043982,  -0.067059,  0.051092,  0.025235,  -0.147107,
+  -0.016269,  0.123009,  0.035894,  -0.020453,  0.040013,
+  0.015557,  0.015825,  0.080712,  -0.06963,  -0.149739,
+  0.022006,  -0.008848,  0.040169,  -0.095688,  0.059575,
+  -0.030641,  -0.061353,  0.046302,  0.104489,  0.043372,
+  -0.001579,  0.059737,  -0.104073,  0.042342,  -0.048611,
+  -0.013811,  -0.056255,  0.107179,  0.057433,  0.084815,
+  0.030217,  0.02236,  -0.040342,  -0.028775,  0.120588,
+  0.04127,  -0.045775,  -0.030195,  -0.106859,  -0.104349,
+  0.072418,  -0.003603,  -0.013072,  0.040728,  0.086869,
+  0.091943,  0.066517,  0.024442,  -0.030929,  -0.03292,
+  -0.160336,  -0.010347,  -0.068458,  0.017458,  0.044823,
+  0.050694,  0.067625,  0.040303,  0.113164,  -0.038747,
+  -0.065558,  -0.106357,  -0.028352,  0.121488,  0.026548,
+  -0.00782,  0.054872,  0.094674,  -0.099533,  0.005231,
+  0.118132,  0.04278,  -0.065079,  0.03144,  0.043229,
+  -0.050024,  0.015943,  0.073917,  0.034049,  0.010548,
+  -0.024979,  0.022639,  0.027795,  0.049491,  0.048762,
+  -0.002738,  -0.010783,  -0.027637,  -0.006986,  -0.104141,
+  -0.066719,  -0.061742,  -0.067028,  -0.053057,  -0.003478,
+  -0.050948,  -0.122196,  0.022082,  0.002595,  0.015094,
+  0.006014,  0.005784,  -0.184537,  -0.034872,  -0.036104,
+  0.055412,  0.006886,  0.103488,  -0.063001,  0.096665,
+  -0.035533,  0.009847,  -0.095114,  0.008588,  0.023736,
+  -0.034278,  -0.11197,  -0.041172,  0.03973,  -0.102952,
+  0.063775,  0.039273,  0.109863,  0.0918,  0.030306,
+  -0.082206,  0.089449,  -0.058478,  -0.029341,  0.038389,
+  0.061057,  -0.024711,  0.111044,  -0.035079,  -0.027985,
+  0.01457,  0.002046,  -0.031545,  0.058848,  -0.0195,
+  -0.002475,  -0.025589,  -0.144358,  0.063478,  0.124927,
+  -0.014094,  -0.01097,  0.031621,  -0.040043,  0.004389,
+  0.025003,  0.052397,  -0.054526,  -0.073469,  0.026795,
+  -0.024697,  0.024739,  0.118299,  0.014948,  -0.132109,
+  0.020192,  0.037815,  -0.09027,  0.049313,  0.082764,
+  -0.022642,  -0.006053,  -0.038073,  -0.057363,  -0.107347,
+  0.033166,  -0.027556,  -0.019765,  -0.111958,  0.027773,
+  -0.063001,  -0.052998,  0.019353,  -0.009646,  -0.01127,
+  0.011872,  -0.006508,  -0.122226,  0.059824,  0.041779,
+  0.016445,  -0.03189,  -0.03631,  0.013085,  0.091631,
+  0.062866,  0.054501,  -0.117523,  -0.010907,  0.087026,
+  -0.014974,  -0.03592,  -0.048565,  -0.019246,  -0.043405,
+  -0.006959,  0.006211,  0.04237,  0.014603,  -0.006435,
+  0.019149,  0.078038,  -0.020556,  0.018114,  -0.036521,
+  -0.054036,  0.007325,  0.056349,  -0.033497,  -0.02596,
+  0.050184,  -0.066536,  0.091501,  0.071356,  -0.049044,
+  -0.032263,  -0.095268,  -0.008784,  0.049033,  0.036929,
+  0.020357,  0.152151,  0.040814,  -0.063159,  -0.024324,
+  -0.017084,  0.011876,  -0.015442,  -0.019811,  -0.000366,
+  -0.0027,  -0.072981,  0.109288,  0.007473,  -0.049442,
+  -0.05404,  0.051947,  0.019359,  0.12916,  0.021981,
+  0.002248,  0.035262,  -0.023141,  0.064666,  -0.078273,
+  -0.031663,  -0.031343,  -0.006058,  -0.045421,  0.017466,
+  -0.067122,  -0.130784,  0.067057,  0.05246,  -0.041165,
+  -0.004411,  0.046453,  -0.055461,  0.048162,  -0.009687,
+  0.02153,  0.007211,  0.104764,  0.079849,  0.086248,
+  -0.072791,  0.001112,  -0.027964,  -0.071233,  -0.013339,
+  0.007979,  -0.118231,  0.076826,  -0.060762,  -0.084358,
+  -0.011447,  0.009765,  0.014163,  0.164784,  -0.015892,
+  -0.020756,  0.152509,  -0.014014,  -0.041853,  -0.117008,
+  -0.011755,  -0.005766,  -0.086896,  -0.13965,  -0.032342,
+  0.025651,  -0.007843,  -0.039073,  0.103397,  -0.042591,
+  -0.005971,  -0.001324,  -0.053945,  -0.000716,  0.048977,
+  0.130185,  0.028226,  0.061179,  0.024489,  -0.021939,
+  -0.007019,  0.054336,  -0.01004,  -0.095411,  0.082406,
+  -0.03213,  -0.015054,  0.033059,  0.002802,  -0.080159,
+  -0.022452,  0.077426,  -0.015314,  0.033583,  0.028479,
+  0.023293,  0.035078,  0.006442,  -0.110541,  -0.106244,
+  -0.034737,  -0.10414,  -0.03457,  -0.114316,  0.079382,
+  0.006009,  0.003901,  0.080081,  0.055082,  0.012896,
+  0.064981,  0.057219,  -0.112986,  0.003906,  -0.028414,
+  -0.012383,  -0.054541,  0.077483,  0.004267,  0.123567,
+  0.007369,  0.099856,  0.023273,  -0.028194,  0.12203,
+  -0.036635,  -0.126589,  -0.034567,  -0.028288,  -0.06504,
+  0.01428,  0.011435,  -0.004867,  0.043901,  0.035395,
+  0.028599,  0.075858,  0.11846,  0.070581,  -0.051903,
+  -0.170905,  0.050352,  0.053514,  -0.017139,  0.021748,
+  -0.09661,  0.008904,  -0.001049,  0.078787,  -0.101201,
+  -0.026229,  -0.019757,  -0.035771,  0.054142,  0.068041,
+  -0.020328,  0.099979,  0.096623,  -0.046957,  -0.001733,
+  0.049586,  0.052458,  -0.031724,  -0.028332,  -0.005418,
+  0.04671,  0.014238,  0.133125,  -0.005428,  -0.080055,
+  -0.033226,  0.034007,  0.025272,  0.033924,  -0.044662,
+  -0.03469,  -0.079173,  -0.160689,  -0.153893,  -0.228771,
+  -0.00245,  -0.083966,  -0.168294,  0.010694,  -0.012167,
+  4e-06,  -0.044377,  0.023373,  -0.077437,  0.012178,
+  -0.015899,  -0.010828,  -0.062847,  0.029927,  -0.074557,
+  -0.053306,  0.049688,  0.057017,  -0.022571,  0.015337,
+  -0.046545,  0.018895,  -0.024848,  -0.004424,  0.165442,
+  -0.060201,  -0.098629,  -0.06519,  0.036582,  -0.038566,
+  0.051453,  0.093478,  0.039619,  0.117535,  0.090386,
+  -0.029366,  0.108075,  -0.016568,  -0.093576,  -0.048799,
+  -0.045599,  -0.023619,  0.070072,  -0.109294,  0.001548,
+  0.076285,  -0.091274,  -0.068829,  0.000215,  -0.046519,
+  -0.022512,  -0.027067,  0.014905,  0.079017,  0.140699,
+  0.061141,  0.009178,  0.097811,  0.033468,  -0.006666,
+  0.007163,  -0.007578,  -0.124238,  -0.025271,  0.017581,
+  0.042405,  -0.034252,  0.06489,  0.0025,  -0.139083,
+  0.009733,  0.158179,  0.014474,  0.038913,  0.05629,
+  -0.004998,  0.075401,  -0.030557,  -0.038595,  -0.04907,
+  -0.01468,  -0.076306,  -0.132365,  -0.177693,  0.09176,
+  -0.057238,  -0.072379,  0.050877,  0.051489,  0.028125,
+  0.004991,  0.032621,  -0.167359,  0.041002,  -0.007072,
+  -0.086405,  -0.042263,  -0.019757,  -0.011524,  0.066004,
+  0.08567,  0.008071,  -0.013614,  -0.062142,  0.08328,
+  0.000887,  -0.07582,  0.008295,  -0.020136,  -0.016886,
+  0.089657,  -0.10626,  -0.051491,  -0.012687,  0.054778,
+  0.011535,  0.086613,  0.053803,  0.027164,  -0.023825,
+  -0.040009,  0.080987,  0.026309,  -0.000334,  -0.085288,
+  -0.024208,  -0.08504,  0.096077,  0.120527,  -0.044181,
+  0.003034,  -0.091142,  0.006471,  0.115971,  -0.026358,
+  0.003489,  0.083633,  0.109975,  -0.029425,  0.061726,
+  0.056115,  -0.006711,  0.013158,  -0.062917,  -0.015029,
+  0.003354,  0.031574,  0.119045,  0.022859,  0.023777,
+  -0.068292,  0.115604,  0.031617,  0.008953,  0.006943,
+  0.01442,  0.008569,  -0.031547,  -0.006857,  -0.05169,
+  -0.086683,  -0.108339,  0.005093,  -0.108646,  -0.03472,
+  0.054273,  -0.096753,  0.050806,  -0.021115,  -0.025278,
+  -0.079997,  0.027008,  -0.034211,  0.090949,  0.005678,
+  0.019288,  0.042083,  0.062119,  0.019301,  0.040859,
+  -0.009113,  0.022427,  -0.004019,  -0.06089,  0.032884,
+  -0.012373,  -0.037976,  0.017625,  -0.079369,  -0.050788,
+  0.07972,  -0.039347,  -0.085324,  0.091044,  0.026653,
+  -0.063122,  0.099371,  -0.024736,  0.084631,  -0.100421,
+  -0.073313,  0.014317,  0.022555,  -0.116051,  -0.063966,
+  -0.009688,  -0.063666,  -0.131709,  0.016744,  -0.135028,
+  -0.003708,  -0.043685,  -0.121631,  -0.03693,  0.125776,
+  0.084333,  0.010114,  0.071231,  -0.010395,  0.059391,
+  0.01776,  0.033034,  -0.018996,  -0.13054,  0.025758,
+  -0.018261,  -0.060044,  0.127025,  -0.032724,  -0.107299,
+  -0.064538,  0.090073,  -0.010186,  -0.066127,  0.107025,
+  -0.01094,  0.003083,  0.01903,  -0.023935,  -0.140176,
+  0.003549,  -0.042402,  -0.010695,  -0.185915,  0.060835,
+  0.005405,  -0.013822,  0.029205,  0.079338,  0.068155,
+  0.071485,  0.030282,  -0.087207,  0.07348,  -0.02794,
+  0.004896,  -0.033246,  0.072637,  0.018017,  0.054712,
+  0.026184,  -0.005287,  0.034456,  -0.036753,  0.079232,
+  0.072707,  0.004506,  -0.039353,  -0.01556,  -0.071466,
+  0.010257,  0.067446,  -0.006598,  0.047396,  0.072218,
+  0.023405,  0.082663,  0.015319,  -0.035436,  -0.075461,
+  -0.124036,  -0.032046,  0.060837,  0.010231,  -0.053024,
+  0.0228,  0.042891,  -0.041549,  0.132395,  -0.09533,
+  -0.077091,  -0.058554,  -0.070632,  0.04757,  0.031856,
+  0.000127,  0.114996,  0.05866,  -0.092472,  0.064503,
+  0.09645,  0.0662,  -0.001059,  0.039487,  -0.032859,
+  -0.065721,  0.001601,  0.088037,  0.059828,  -0.047411,
+  -0.077714,  0.010275,  0.013629,  0.003304,  0.005407,
+  0.000665,  0.012927,  -0.077525,  0.069202,  -0.157417,
+  0.014547,  -0.095965,  -0.087546,  -0.067375,  -0.027867,
+  0.005458,  -0.095839,  0.105294,  -0.044892,  0.045151,
+  -0.001349,  0.038356,  -0.127152,  -0.080503,  -0.105423,
+  -0.018484,  0.008439,  0.104398,  -0.027959,  0.082086,
+  -0.020605,  0.042785,  -0.109139,  -0.025958,  0.079733,
+  0.036289,  -0.083773,  -0.033819,  0.032566,  -0.065556,
+  0.006659,  0.00209,  0.097027,  0.115715,  -0.013271,
+  -0.067514,  0.128365,  -0.089129,  0.02616,  -0.040584,
+  -0.002443,  -0.017254,  0.129204,  -0.110078,  -0.064943,
+  0.089215,  -0.022299,  -0.034959,  0.022446,  -0.019254,
+  -0.0389,  -0.069862,  -0.07054,  0.069949,  0.111993,
+  -0.006311,  -0.009057,  0.094278,  -0.014932,  0.003657,
+  -0.019323,  0.026145,  -0.062611,  -0.073753,  -0.007182,
+  0.014101,  0.015776,  0.052537,  0.064728,  -0.160187,
+  -0.005122,  0.076356,  -0.104763,  0.091493,  0.020225,
+  -0.000433,  0.062698,  -0.060457,  -0.14754,  -0.066168,
+  0.007195,  -0.061498,  -0.037801,  -0.039763,  0.059551,
+  -0.02841,  -0.07451,  0.057667,  0.020584,  -0.04251,
+  -0.025311,  -0.037825,  -0.18801,  0.077423,  0.030749,
+  -0.025465,  -0.067541,  0.003073,  -0.049778,  0.127789,
+  0.002786,  0.120009,  -0.067812,  -0.026565,  0.111272,
+  0.023219,  -0.024403,  -0.014507,  -0.048624,  0.022163,
+  0.014596,  -0.052136,  0.00158,  0.064595,  0.017963,
+  0.02133,  0.098862,  -0.009253,  -0.041062,  0.008903,
+  -0.013829,  0.031967,  0.076571,  -0.005348,  -0.04401,
+  0.031252,  0.000369,  0.036818,  0.072854,  -0.038569,
+  0.004161,  -0.128017,  -0.053152,  0.050896,  -0.015212,
+  -0.036159,  0.097995,  0.068397,  -0.048472,  -0.056131,
+  -0.01192,  0.059188,  0.010215,  -0.061152,  -0.011717,
+  -0.035949,  -0.057039,  0.090859,  -0.029682,  0.041466,
+  -0.025106,  0.131191,  0.059327,  0.085383,  0.021699,
+  0.04923,  0.03663,  -0.077086,  0.017806,  -0.08879,
+  0.00404,  -0.069533,  -0.026785,  0.009666,  0.014017,
+  -0.055897,  -0.096299,  0.120693,  0.029995,  0.032602,
+  -0.001365,  0.034015,  -0.053512,  0.001573,  -0.01917,
+  0.003956,  0.006452,  0.067313,  0.028301,  0.160615,
+  -0.053111,  0.01399,  -0.02706,  -0.013638,  0.039376,
+  -0.054462,  -0.096553,  0.079994,  -0.043791,  -0.025051,
+  -0.003222,  0.019418,  -0.049525,  0.151136,  0.034123,
+  0.055117,  0.058918,  -0.017393,  0.026169,  -0.12638,
+  -0.019008,  -0.028939,  -0.014027,  -0.173373,  -0.032841,
+  -0.00337,  0.03968,  -0.118311,  0.114094,  -0.041869,
+  0.041121,  -0.038391,  -0.096074,  -0.032479,  0.060222,
+  0.063968,  -0.024528,  0.018158,  -0.009892,  -0.043882,
+  -0.005004,  0.1298,  -0.025438,  -0.121186,  0.04986,
+  0.010448,  -0.040388,  0.061853,  -0.017304,  -0.035088,
+  -0.008678,  0.061476,  -0.039493,  -0.005055,  0.079169,
+  0.046134,  0.00977,  0.068294,  -0.078965,  -0.043792,
+  -0.030529,  -0.053845,  0.053853,  -0.140682,  0.111461,
+  0.003549,  -0.014939,  0.148955,  0.072861,  0.004332,
+  0.015386,  0.062006,  -0.122325,  -0.032529,  0.010241,
+  -0.047982,  -0.12644,  0.05584,  0.067128,  0.101189,
+  -0.00263,  0.031969,  0.046076,  -0.080194,  0.10474,
+  -0.033486,  -0.077818,  -0.058697,  -0.095258,  -0.111074,
+  0.037236,  0.011711,  0.001113,  -0.005664,  0.048588,
+  0.041131,  0.098257,  0.033126,  0.029317,  -0.095311,
+  -0.071555,  -0.039999,  0.026678,  -0.072182,  0.035031,
+  -0.007997,  -0.048174,  -0.006796,  0.075959,  -0.05206,
+  -0.007645,  0.037076,  -0.035574,  0.085576,  0.034126,
+  -0.050676,  0.05143,  0.031999,  -0.134308,  -0.001489,
+  0.084564,  -0.018394,  -0.09741,  -0.042931,  -0.025608,
+  -0.025489,  0.041919,  0.142482,  0.004617,  -0.041085,
+  -0.028816,  -0.015527,  -0.031005,  0.028405,  -0.02224,
+  -0.067737,  -0.025241,  -0.052578,  0.012322,  -0.120556,
+  0.016278,  -0.081744,  -0.09916,  0.025144,  0.025441,
+  0.003176,  -0.073871,  0.031718,  -0.028622,  0.029031,
+  0.01791,  -0.030693,  -0.104215,  -0.015422,  -0.065738,
+  -0.048346,  -0.012847,  0.046849,  -0.008621,  0.058771,
+  -0.054495,  0.031597,  -0.038844,  0.043138,  0.092588,
+  -0.071371,  -0.059093,  -0.001197,  0.001766,  -0.074762,
+  0.02947,  0.089616,  0.005009,  0.052977,  0.015899,
+  -0.045424,  0.158466,  -0.038717,  -0.032506,  0.028687,
+  0.011435,  -0.006772,  0.047605,  -0.144659,  -0.031229,
+  0.073577,  0.01153,  -0.008172,  0.058883,  -0.088412,
+  0.033615,  -0.03412,  -0.030701,  0.101215,  0.096645,
+  0.027368,  0.041249,  0.081502,  -0.02544,  0.007592,
+  0.059893,  0.012106,  -0.112009,  -0.114692,  0.016397,
+  0.087068,  0.016199,  0.051263,  0.011915,  -0.085364,
+  0.026046,  0.145258,  -0.047521,  0.077134,  -0.000345,
+  0.034532,  0.099801,  -0.087591,  -0.059719,  -0.058671,
+  0.022737,  -0.001887,  -0.107049,  -0.116757,  0.134115,
+  -0.055403,  0.005157,  0.067618,  0.081074,  0.071787,
+  0.063802,  -0.00343,  -0.106491,  0.017543,  0.002214,
+  -0.013785,  -0.032962,  0.010084,  0.024325,  0.045963,
+  0.059883,  0.072282,  -0.008608,  -0.015127,  0.048225,
+  0.041752,  -0.068845,  0.012227,  -0.090748,  -0.035309,
+  0.045353,  -0.078624,  -0.019489,  0.035531,  0.058571,
+  0.045414,  0.039032,  -0.011106,  0.048787,  -0.025336,
+  -0.084893,  0.031896,  0.01085,  0.012526,  -0.053205,
+  0.016952,  -0.044041,  0.068766,  0.097328,  -0.122229,
+  0.027016,  -0.051759,  -0.057246,  0.074566,  0.006201,
+  0.069904,  0.100068,  0.076124,  0.004278,  0.029466,
+  0.045229,  0.055683,  0.01879,  -0.067806,  0.039373,
+  0.029179,  -0.036787,  0.129921,  -0.028993,  0.037711,
+  -0.105011,  0.138747,  -0.00437,  0.05208,  0.050835,
+  0.025511,  -0.002962,  0.007852,  -0.055234,  -0.075055,
+  0.00046,  -0.089231,  -0.030467,  -0.080347,  0.007488,
+  0.06746,  -0.076368,  0.084991,  0.039544,  0.033391,
+  -0.044318,  0.00639,  -0.079387,  -0.002909,  -0.029708,
+  -0.047882,  0.06304,  0.065719,  0.021811,  0.070945,
+  -0.007571,  -0.001302,  -0.064119,  -0.068005,  0.05104,
+  -0.017747,  -0.063938,  0.018673,  -0.038391,  -0.099966,
+  0.057475,  -0.007669,  0.009384,  0.109283,  0.012248,
+  -0.048858,  0.092498,  0.011967,  0.061525,  -0.028819,
+  -0.015131,  -0.02416,  -0.03322,  -0.101648,  -0.01798,
+  -0.003342,  -0.049829,  -0.125096,  0.128241,  -0.047377,
+  -0.028943,  -0.109072,  -0.066133,  -0.015454,  0.098334,
+  0.053371,  0.011324,  0.042781,  0.044313,  0.06251,
+  0.098408,  0.06541,  -0.040693,  -0.116351,  -0.032327,
+  -0.013634,  -0.058591,  0.081507,  0.042019,  -0.09977,
+  -0.018275,  0.084624,  -0.007512,  -0.041113,  0.054203,
+  0.017879,  -0.029747,  0.059865,  -0.048281,  -0.111513,
+  -0.022478,  0.002059,  0.022383,  -0.12536,  0.058216,
+  0.002386,  -0.0816,  0.049288,  0.157428,  0.057724,
+  0.005046,  0.102125,  -0.083473,  0.044059,  -0.094864,
+  0.03912,  -0.063306,  0.057341,  0.060519,  0.107383,
+  0.007076,  -0.009373,  -0.012555,  -0.06663,  0.117121,
+  0.025254,  -0.008796,  -0.062102,  -0.083164,  -0.079007,
+  0.084839,  0.042308,  -0.055353,  0.036386,  0.132641,
+  0.084464,  0.056288,  -0.011636,  -0.059554,  -0.087748,
+  -0.147377,  -0.052414,  -0.010203,  -0.009159,  -0.018829,
+  0.009621,  0.061633,  0.015716,  0.086332,  -0.061465,
+  -0.011833,  -0.062998,  -0.021168,  0.125194,  0.045025,
+  0.052316,  0.02572,  0.095155,  -0.093252,  0.02872,
+  0.056113,  0.063321,  -0.045315,  0.025199,  0.023591,
+  -0.070481,  0.07235,  0.092458,  0.047973,  -0.025439,
+  -0.001281,  0.021028,  0.034576,  0.084779,  0.006867,
+  -0.010323,  -0.04633,  -0.009172,  0.030485,  -0.117679,
+  -0.021782,  -0.034737,  -0.086292,  -0.045885,  0.009655,
+  -0.037167,  -0.123331,  0.017291,  -0.028319,  0.071447,
+  -0.05718,  -0.032912,  -0.139418,  -0.025966,  -0.039305,
+  0.009411,  -0.054017,  0.076307,  -0.060252,  0.110087,
+  -0.061366,  0.038897,  -0.098107,  0.046119,  0.043021,
+  -0.02913,  -0.096885,  0.007623,  0.090513,  -0.097416,
+  0.053264,  0.058296,  0.054372,  0.060769,  0.015586,
+  -0.067956,  0.059996,  -0.03785,  0.005986,  0.000778,
+  0.045873,  -0.065546,  0.0779,  -0.085638,  0.000698,
+  0.027694,  -0.021241,  -0.002777,  0.034509,  -0.048173,
+  0.009988,  0.001008,  -0.077434,  0.026002,  0.13949,
+  0.00891,  0.007791,  0.059292,  -0.057047,  0.014127,
+  -0.022959,  0.08571,  -0.068087,  -0.081561,  0.005935,
+  0.007577,  0.061544,  0.076542,  0.00166,  -0.113279,
+  0.024973,  0.08675,  -0.061674,  0.095059,  0.089352,
+  -0.024436,  0.024181,  -0.016117,  -0.073634,  -0.067986,
+  0.074701,  -0.046868,  -0.054634,  -0.092485,  0.006662,
+  -0.033256,  -0.053774,  0.049001,  -0.002339,  0.013545,
+  -0.006432,  -0.012089,  -0.086842,  0.104105,  0.061991
+};
+  /* codebook/lspjvm3.txt */
+static const float codes2[] = {
+  0.007066,  0.075781,  -0.070082,  -0.092014,  -0.066477,
+  0.09051,  0.106622,  0.025911,  -0.01676,  0.003724,
+  -0.024628,  0.058332,  0.012876,  0.059557,  -0.002092,
+  -0.065092,  -0.096975,  -0.041837,  -0.002432,  0.058918,
+  0.014358,  0.080049,  -0.008803,  -0.002091,  -0.097584,
+  0.085323,  -0.026053,  -0.086585,  -0.009541,  0.130555,
+  0.045391,  0.037557,  0.074726,  -0.050453,  0.033517,
+  -0.035576,  -0.084211,  -0.08643,  0.00891,  -0.072674,
+  -0.098699,  -0.02454,  -0.048972,  -0.066975,  -0.048791,
+  0.032184,  0.070992,  -0.014416,  0.141892,  -0.044249,
+  -0.108921,  -0.02045,  0.115988,  0.011287,  -0.026273,
+  0.024341,  0.138519,  -0.036467,  0.020684,  0.074258,
+  -0.053563,  0.077463,  0.072166,  0.032112,  -0.079303,
+  -0.025039,  0.079675,  0.094211,  -0.115754,  0.038892,
+  0.050897,  -0.024639,  0.057826,  -0.110429,  0.071184,
+  0.015309,  -0.034027,  -0.055726,  0.043179,  -0.063089,
+  0.043359,  -0.011698,  0.006637,  0.002751,  0.03011,
+  -0.001261,  0.11147,  0.043277,  -0.004205,  -0.021599,
+  -0.005698,  0.058842,  0.168422,  0.059313,  -0.007971,
+  -0.087599,  0.073891,  -0.083238,  0.099279,  -0.017364,
+  -0.018429,  0.01404,  -0.014864,  -0.111512,  0.08945,
+  -0.028498,  -0.087983,  -0.07732,  -0.062602,  0.000328,
+  -0.027152,  -0.093796,  0.111381,  -0.018603,  0.092394,
+  -0.007256,  0.025391,  0.011454,  0.012802,  -0.04168,
+  0.008078,  0.020905,  -0.105401,  -0.083265,  0.027756,
+  -0.04963,  -0.044085,  -0.051424,  0.104125,  -0.000779,
+  -0.063079,  -0.130699,  0.0705,  0.033468,  -0.019802,
+  -0.061011,  0.094839,  -0.040122,  0.118409,  0.05695,
+  0.086391,  -0.006615,  0.045337,  -0.04419,  -0.106474,
+  -0.081912,  0.067557,  -0.031649,  -0.014437,  0.057585,
+  -0.121755,  -0.049113,  0.057109,  -0.049872,  0.044104,
+  0.064705,  -0.091589,  0.037286,  -0.048606,  -0.045398,
+  0.003456,  0.05723,  0.006262,  -0.055206,  -0.063871,
+  -0.005249,  0.081783,  0.134969,  -0.002331,  0.052643,
+  -0.093346,  0.072093,  0.116025,  -0.031453,  -0.006012,
+  -0.038574,  -0.030841,  0.010288,  0.02442,  0.051657,
+  -0.086584,  0.046381,  0.00541,  0.052622,  -0.072741,
+  0.079023,  0.078099,  -0.093912,  0.005477,  -0.006721,
+  0.100232,  -0.017587,  0.044819,  0.036655,  0.02158,
+  -0.006829,  -0.050076,  -0.00302,  0.088246,  0.01356,
+  -0.01569,  0.012477,  -0.052595,  -0.048861,  -0.033688,
+  0.055615,  0.092298,  -0.066194,  0.016416,  -0.066059,
+  0.046976,  0.003023,  0.104646,  0.109136,  0.018293,
+  -0.016507,  -0.006859,  0.004326,  0.070843,  0.14075,
+  0.025774,  0.03473,  -0.07959,  0.050054,  -0.10795,
+  0.002378,  0.097498,  0.027111,  -0.122953,  -0.002423,
+  -0.020539,  -0.063263,  -0.095493,  -0.157361,  -0.039183,
+  0.025721,  0.026897,  -0.0012,  0.033997,  -0.001749,
+  0.061593,  -0.013053,  -0.106317,  -0.06819,  0.046352,
+  -0.05606,  0.157084,  -0.049365,  0.053959,  -0.051065,
+  -0.047672,  0.08157,  0.064342,  -0.030705,  -0.070806,
+  -0.076503,  -0.059471,  0.012419,  0.073968,  -0.026179,
+  -0.038473,  0.059013,  -0.035783,  -0.030057,  -0.036346,
+  -0.052692,  -0.015346,  -0.022687,  -0.035279,  0.013314,
+  0.068397,  -0.046609,  -0.009593,  -0.040796,  0.157438,
+  -0.07536,  -0.110464,  0.031839,  -0.029035,  -0.015222,
+  0.041013,  -0.099212,  -0.10892,  -0.008627,  0.012095,
+  0.020855,  0.009935,  -0.086917,  0.058827,  -0.006536,
+  0.022104,  -0.005013,  0.003496,  0.046663,  -0.051061,
+  -0.036803,  -0.067317,  -0.007075,  0.18087,  -0.027434,
+  -0.025056,  -0.039341,  -0.073918,  -0.00318,  -0.11093,
+  -0.042711,  0.005519,  -0.035005,  -0.088419,  0.170942,
+  0.001503,  -0.121485,  0.066383,  -0.067346,  0.005643,
+  0.080088,  -0.042562,  -0.006668,  -0.036538,  0.020683,
+  0.042848,  0.027852,  -0.029088,  -0.156468,  0.006503,
+  0.037716,  0.032082,  0.038416,  0.021835,  -0.106963,
+  -0.043017,  0.018166,  0.070409,  -0.005426,  -0.035585,
+  -0.111071,  -0.039986,  0.05043,  0.035157,  0.066902,
+  -0.040684,  0.060527,  0.036225,  0.002527,  -0.015087,
+  0.059243,  0.021268,  -0.010682,  -0.018434,  0.059128,
+  0.111314,  -0.05407,  0.105744,  -0.051476,  -0.01297,
+  -0.000358,  -0.099249,  -0.077385,  0.069924,  -0.039101,
+  -0.072139,  -0.049069,  -0.088018,  0.006144,  0.000712,
+  0.08103,  0.021987,  -0.046031,  0.058087,  -0.00132,
+  -0.046851,  -0.011062,  0.108321,  -0.001146,  -0.071193,
+  0.044973,  -0.002915,  -0.003323,  0.041735,  0.094566,
+  0.05353,  0.035927,  0.100282,  0.059082,  -0.054059,
+  -0.012158,  -0.035417,  0.020412,  -0.073193,  0.059296,
+  -0.040489,  -0.09525,  -0.003821,  -0.084904,  0.053925,
+  0.109183,  -0.005862,  -0.036538,  0.080962,  -0.040647,
+  0.02007,  0.057778,  -0.020197,  -0.079626,  -0.003186,
+  -0.050855,  0.128185,  0.034731,  0.05746,  -0.035236,
+  -0.057096,  -0.001238,  0.122018,  -0.071204,  -0.047253,
+  -0.051767,  0.048301,  -0.052678,  0.02599,  -0.017481,
+  -0.029379,  0.030738,  0.047207,  -0.047864,  -0.033561,
+  0.029884,  -0.091175,  -0.085446,  -0.02614,  0.092628,
+  0.067706,  -0.085617,  0.081433,  0.047305,  0.031945,
+  -0.048728,  -0.040387,  0.046206,  0.010578,  -0.037639,
+  0.011328,  -0.042458,  -0.149597,  0.033882,  -0.061869,
+  0.0088,  0.057754,  -0.095876,  0.03823,  0.096876,
+  -0.033487,  -0.141669,  -0.014172,  0.028439,  -0.092764,
+  -0.053714,  0.086926,  0.034786,  0.136053,  -0.005569,
+  0.028753,  0.00963,  0.044114,  -0.050365,  -0.066224,
+  0.006017,  0.014348,  0.024471,  0.000489,  0.067234,
+  -0.021678,  -0.11876,  0.036349,  -0.040295,  0.076358,
+  -0.008444,  -0.086082,  -0.044018,  -0.025804,  0.028971,
+  -0.009233,  0.053026,  -0.035341,  -0.182193,  -0.102515,
+  0.08921,  0.066812,  0.032417,  0.046882,  -0.034815,
+  -0.052293,  0.022814,  0.129622,  0.128232,  -0.012105,
+  -0.087084,  0.004762,  0.086538,  0.046566,  0.098359,
+  -0.018713,  0.039204,  -0.021707,  -0.06011,  -0.117527,
+  -0.005459,  0.060994,  -0.057718,  -0.021783,  0.035154,
+  0.100557,  -0.01547,  -0.025818,  0.00845,  0.051535,
+  -0.001388,  -0.11461,  -0.057903,  0.041862,  0.061778,
+  0.045701,  -0.078563,  -0.070166,  -0.04845,  -0.08853,
+  0.021375,  -0.004598,  -0.09071,  -0.009399,  -0.073952,
+  -0.035575,  -0.05028,  0.11478,  0.137866,  0.065234,
+  0.003594,  -0.066802,  -0.144989,  0.166201,  0.039564,
+  -0.022457,  -0.03009,  0.016187,  0.115443,  -0.097331,
+  -0.019139,  0.09944,  0.002198,  -0.030953,  0.021099,
+  -0.045399,  -0.046871,  0.022533,  -0.064657,  0.005776,
+  0.049063,  -0.028478,  0.019268,  0.054265,  0.028042,
+  0.045559,  -0.005541,  -0.01441,  -0.024165,  -0.054976,
+  -0.073258,  0.084205,  0.036077,  -0.068683,  0.004708,
+  -0.085228,  0.001234,  0.046261,  -0.050496,  -0.028227,
+  -0.086828,  -0.001218,  0.021865,  0.003791,  -0.000568,
+  -0.088733,  -0.040041,  -0.035891,  -0.054915,  0.073463,
+  -0.132031,  -0.012844,  -0.068544,  0.013052,  0.087335,
+  0.038603,  -0.115382,  -0.010433,  -0.007113,  0.095126,
+  -0.047378,  -0.081353,  0.018021,  -0.021156,  -0.120774,
+  0.040038,  0.007633,  -0.088728,  -0.009928,  0.020142,
+  0.052024,  -0.021063,  -0.118121,  0.102739,  -0.055837,
+  0.005253,  -0.061924,  0.06368,  -0.014512,  -0.020259,
+  0.029493,  -0.013435,  -0.020638,  0.089342,  0.001092,
+  -0.046491,  -0.145634,  -0.083159,  -0.158142,  -0.279281,
+  0.003611,  0.055863,  -0.064655,  -0.088773,  0.089283,
+  -0.029619,  -0.089949,  0.017197,  -0.066633,  -0.052347,
+  0.090828,  -0.087551,  0.000338,  0.085238,  -0.005313,
+  0.096211,  0.071381,  -0.076546,  -0.077927,  -0.040864,
+  0.062936,  0.041559,  0.016235,  -0.017513,  0.014773,
+  -0.025734,  0.028586,  0.070292,  0.055794,  -0.026131,
+  -0.076954,  -0.082228,  0.043947,  -0.035921,  0.152668,
+  -0.04951,  0.023159,  0.008506,  -0.044773,  -0.160358,
+  0.024984,  -0.025587,  -0.071627,  -0.038376,  0.088478,
+  0.120568,  0.046723,  0.086731,  0.000695,  -0.015751,
+  -0.027837,  -0.160937,  -0.095031,  0.036271,  -0.009061,
+  -0.015078,  -0.036281,  -0.103665,  -0.058258,  -0.049573,
+  0.022021,  0.108296,  -0.002586,  0.065655,  -0.018584,
+  -0.046441,  -0.031018,  0.06735,  0.014328,  0.00886,
+  -0.000245,  0.0634,  -0.00181,  0.043515,  0.090344,
+  -0.063845,  0.020485,  0.079401,  0.070558,  -0.116428,
+  0.032628,  0.068949,  0.052238,  -0.04453,  0.096813,
+  0.029911,  -0.008814,  0.044352,  -0.168172,  0.009604,
+  0.055828,  -0.100739,  -0.026013,  0.021193,  -0.051425,
+  0.035891,  -0.004085,  0.030216,  -0.060801,  0.037202,
+  0.007262,  0.120686,  0.026846,  0.058464,  -0.100792,
+  -0.009176,  0.027589,  0.123957,  -0.011283,  -0.025744,
+  -0.105081,  0.118244,  -0.042122,  -0.025404,  0.000873,
+  -0.012703,  0.084159,  -0.067539,  -0.140536,  0.041637,
+  -0.014485,  -0.043382,  -0.048004,  -0.075416,  0.054401,
+  -0.018651,  -0.032908,  0.164231,  -0.053236,  0.033946,
+  -0.021681,  -0.012655,  -0.037049,  -0.001613,  -0.053393,
+  -0.014635,  0.017954,  -0.116115,  -0.027232,  0.034005,
+  -0.035376,  0.026492,  -0.03725,  0.070733,  0.074835,
+  -0.021378,  -0.14298,  0.123195,  0.003699,  0.025398,
+  0.015629,  0.07737,  0.032623,  0.12158,  0.0971,
+  0.000946,  -0.056355,  0.042065,  0.008184,  -0.081824,
+  -0.101937,  0.065473,  0.00336,  0.069241,  0.073002,
+  -0.053844,  -0.044301,  0.080351,  -0.091833,  0.044288,
+  0.007447,  -0.120723,  -0.013806,  -0.023636,  -0.064616,
+  0.030556,  0.07263,  0.074428,  -0.087759,  -0.02644,
+  0.06484,  0.049162,  0.091053,  0.023891,  0.033811,
+  -0.027746,  0.116392,  0.106126,  -0.056644,  -0.014781,
+  0.036137,  -0.002632,  0.055512,  0.070077,  0.067819,
+  -0.030625,  0.053772,  -0.078457,  -0.021351,  -0.113011,
+  0.052797,  0.044875,  -0.077269,  -0.009867,  0.101493,
+  0.073477,  -0.024103,  0.049145,  -0.004706,  -0.025211,
+  -0.053731,  -0.049009,  -0.035786,  0.05443,  0.046515,
+  0.025154,  -0.043569,  -0.034789,  -0.05861,  0.006931,
+  0.012049,  0.046809,  -0.129441,  0.025541,  -0.030933,
+  0.000297,  -0.054058,  0.179837,  0.081515,  0.004932,
+  -0.028445,  -0.073753,  0.010629,  0.080042,  0.09871,
+  -0.014017,  0.057597,  0.00101,  0.071658,  -0.06757,
+  0.074384,  0.110366,  -0.018121,  -0.108754,  0.037793,
+  0.028041,  -0.047508,  -0.031359,  -0.098913,  -0.036486,
+  -0.017311,  -0.001279,  -0.013694,  0.051968,  0.036512,
+  0.088201,  0.031155,  -0.043442,  -0.065045,  0.023486,
+  0.027,  0.104768,  -0.015176,  -0.038754,  -0.004178,
+  0.003732,  0.062166,  0.085438,  -0.077368,  -0.101645,
+  -0.118347,  0.007589,  -0.056489,  0.082268,  0.020253,
+  -0.035623,  0.034235,  -0.099354,  -0.061237,  -0.024285,
+  0.005441,  -0.039694,  -0.025957,  -0.004411,  0.049903,
+  0.00304,  0.036243,  0.023552,  -0.007334,  0.128963,
+  -0.077727,  -0.059175,  -0.019437,  -0.024872,  0.004339,
+  0.084006,  -0.076605,  -0.102261,  0.036714,  -0.035205,
+  -0.007642,  -0.005125,  -0.030525,  0.09639,  -0.053138,
+  -0.002192,  -0.024851,  0.050645,  0.04149,  -0.043183,
+  0.046796,  -0.050894,  0.055023,  0.133834,  -0.024013,
+  0.000872,  -0.057072,  -0.00063,  0.04207,  -0.129339,
+  -0.064283,  0.037836,  -0.066393,  0.004438,  0.125379,
+  -0.062213,  -0.067468,  0.090177,  -0.046094,  -0.025725,
+  0.079101,  -0.074909,  -0.04373,  -0.073483,  0.069672,
+  -0.020413,  -7.9e-05,  -0.049725,  -0.120751,  -0.04698,
+  0.039894,  0.072305,  0.009798,  0.005613,  -0.045217,
+  0.006862,  0.036285,  0.074819,  -0.006747,  0.015144,
+  -0.071562,  0.012324,  -0.001082,  0.014835,  0.07996,
+  -0.027804,  0.103358,  -0.017203,  0.014914,  -0.056687,
+  0.030827,  0.028076,  0.003395,  -0.073255,  0.11031,
+  0.056498,  -0.044893,  0.110122,  -0.109058,  -0.052302,
+  -0.001604,  -0.089977,  -0.060548,  0.107808,  0.025463,
+  -0.070203,  -0.000513,  -0.123913,  0.046247,  -0.085392,
+  0.096343,  0.09589,  -0.06495,  0.070363,  0.034272,
+  0.037773,  -0.07695,  0.124858,  -0.009008,  -0.010115,
+  0.083868,  0.051242,  0.039149,  0.015185,  0.083375,
+  0.029773,  -0.045961,  0.100395,  0.003743,  -0.138294,
+  -0.041755,  0.010806,  0.057797,  -0.147374,  0.095858,
+  -0.009929,  -0.103347,  -0.03231,  -0.11056,  0.121377,
+  0.145244,  0.017079,  -0.080587,  0.020516,  -0.044939,
+  -0.010477,  0.038347,  -0.003466,  -0.001618,  0.0196,
+  -0.021762,  0.125482,  0.011074,  0.065815,  0.040298,
+  0.009202,  -0.051686,  0.129684,  -0.131135,  0.044536,
+  0.009313,  0.102518,  -0.075351,  0.054338,  0.020273,
+  -0.045753,  0.031345,  0.000407,  -0.097294,  -0.000416,
+  -0.007466,  -0.044972,  -0.078744,  0.042414,  0.066624,
+  0.030318,  -0.067852,  0.061416,  -0.028992,  0.056606,
+  0.004038,  -0.036253,  -0.014279,  0.023123,  -0.007832,
+  -0.000137,  -0.027684,  -0.127648,  -0.007713,  -0.008746,
+  -0.0265,  0.049032,  -0.183319,  0.059107,  0.0665,
+  0.016902,  -0.093331,  0.090129,  0.016648,  -0.083492,
+  -0.023669,  -0.010473,  0.027614,  0.145068,  0.000681,
+  0.044133,  -0.035809,  0.005668,  -0.090461,  -0.090732,
+  -0.033927,  0.042997,  0.0217,  -0.046955,  0.044487,
+  -0.026444,  -0.061011,  0.01011,  -0.023804,  0.030427,
+  -0.015195,  -0.155603,  -0.016584,  0.021461,  -0.003528,
+  -0.059784,  0.032214,  0.000847,  -0.098859,  -0.07898,
+  0.043188,  0.066433,  0.062309,  0.144507,  0.006865,
+  -0.068953,  0.046698,  0.099369,  0.043354,  -0.014309,
+  -0.033202,  -0.00295,  0.040734,  0.083454,  0.039319,
+  0.051358,  0.006074,  -0.073465,  -0.090554,  -0.120787,
+  -0.040676,  0.092412,  -0.085151,  -0.021699,  0.005813,
+  0.103135,  0.024964,  0.025832,  -0.075982,  0.035699,
+  -0.02731,  -0.153007,  0.03642,  0.0576,  0.08163,
+  0.001605,  -0.054191,  -0.033043,  -0.01439,  -0.071383,
+  0.03618,  0.03586,  -0.04698,  0.038541,  -0.044757,
+  -0.078032,  -0.029878,  0.078183,  0.082251,  0.010549,
+  0.053317,  -0.038231,  -0.06561,  0.055798,  0.037504,
+  0.076317,  -0.027605,  0.010349,  0.095361,  -0.088636,
+  0.049089,  0.113316,  0.051084,  0.038589,  0.03433,
+  -0.055948,  -0.037217,  -0.015418,  -0.139976,  0.036306,
+  0.039306,  -0.009889,  -0.04491,  0.016559,  -5e-05,
+  0.106073,  0.01528,  -0.002563,  -0.109085,  -0.048475,
+  -0.035319,  0.16386,  0.032981,  -0.044932,  0.003227,
+  -0.123233,  -0.010638,  0.055479,  -0.003666,  -0.072249,
+  -0.111158,  0.065365,  0.010691,  0.039119,  -0.001837,
+  -0.118729,  0.06147,  -0.002077,  -0.033335,  -0.060165,
+  -0.026081,  -0.001806,  -0.079616,  -7.5e-05,  0.080598,
+  0.032908,  -0.03514,  -0.003136,  -0.029024,  0.094622,
+  -0.075773,  -0.022898,  -0.014817,  0.058393,  -0.111505,
+  0.036794,  -0.01576,  -0.112602,  0.030323,  0.085897,
+  -0.020834,  0.056079,  -0.103762,  0.117671,  -0.041205,
+  0.041684,  -0.084336,  0.034186,  0.011973,  -0.006313,
+  0.040836,  -0.035709,  0.03417,  0.122672,  0.090973,
+  -0.053182,  -0.059371,  0.091017,  -0.090998,  -0.116986,
+  0.001405,  0.138364,  0.017107,  -0.064076,  0.103486,
+  -0.031142,  -0.030068,  0.046547,  -0.133471,  -0.042055,
+  0.140418,  -0.125084,  0.035218,  -0.001162,  -0.02113,
+  -0.012034,  0.097413,  -0.079006,  -0.03903,  -0.054011,
+  0.143887,  0.078835,  -0.000601,  -0.021173,  -0.039895,
+  -0.02505,  0.075865,  0.039221,  0.032458,  0.038206,
+  -0.038873,  -0.085003,  -0.032736,  -0.026956,  0.113525,
+  -0.023933,  0.120794,  -0.003862,  -0.026459,  -0.138724,
+  0.089559,  0.029002,  -0.052098,  -0.085692,  0.115174,
+  0.083497,  0.024179,  0.119021,  -0.067541,  0.019047,
+  -0.02772,  -0.086083,  -0.055329,  0.020087,  -0.027086,
+  -0.047858,  -0.051975,  -0.035205,  -0.059342,  -0.068582,
+  0.058936,  0.044141,  -0.080315,  0.119744,  -0.046518,
+  -0.064588,  -0.027212,  0.147823,  0.032404,  0.01669,
+  0.024302,  0.08556,  -0.001525,  0.016469,  0.038891,
+  -0.020146,  0.019943,  0.045067,  0.03807,  -0.086274,
+  -0.025769,  0.044192,  0.102141,  -0.064765,  0.055849,
+  0.048803,  -0.030066,  -0.00922,  -0.116655,  0.068295,
+  0.04758,  -0.076138,  -0.070307,  0.047582,  -0.111342,
+  0.004656,  -0.004452,  0.029703,  -0.004259,  0.01113,
+  0.014446,  0.166086,  0.059565,  0.000985,  -0.052607,
+  0.013251,  0.094476,  0.106216,  0.016715,  -0.025581,
+  -0.101244,  0.072897,  -0.114526,  0.024681,  0.010784,
+  -0.051759,  0.032389,  -0.050202,  -0.083316,  0.052334,
+  -0.0351,  -0.116721,  -0.110336,  -0.053391,  0.065541,
+  -0.02979,  -0.020457,  0.135285,  -0.004142,  0.111508,
+  -0.030936,  0.018549,  -0.016034,  0.018572,  -0.084336,
+  -0.048615,  -0.018739,  -0.096815,  -0.090162,  0.01941,
+  -0.040821,  -0.009925,  -0.097427,  0.091891,  0.031793,
+  -0.024598,  -0.132848,  0.078353,  0.089339,  -0.068562,
+  -0.020779,  0.040974,  -0.055675,  0.169131,  0.029649,
+  0.078165,  -0.050679,  -0.005881,  -0.004983,  -0.104324,
+  -0.069096,  0.12796,  0.011392,  -0.000769,  0.062168,
+  -0.079842,  0.001606,  0.089284,  -0.035465,  0.031075,
+  0.029519,  -0.102956,  -0.010902,  -0.06403,  -0.019669,
+  0.057492,  0.075802,  -0.008904,  -0.060743,  -0.053144,
+  0.005126,  0.06298,  0.085674,  0.019895,  0.104448,
+  -0.086473,  0.056906,  0.056795,  -0.01294,  0.036606,
+  -0.008604,  -0.04045,  0.042062,  0.04181,  0.02768,
+  -0.092256,  0.091237,  -0.0395,  0.024761,  -0.088978,
+  0.068585,  0.088295,  -0.048033,  -0.017808,  0.04537,
+  0.1246,  -0.03532,  0.056751,  0.092751,  0.054025,
+  -0.015725,  -0.061938,  0.036806,  0.078768,  -0.016065,
+  0.002444,  -0.023887,  -0.072177,  -0.02979,  -0.00586,
+  0.015478,  0.129142,  -0.091024,  0.071482,  -0.065445,
+  0.005867,  -0.006051,  0.098646,  0.054089,  0.018713,
+  0.033837,  -0.008355,  -0.051959,  0.05744,  0.160305,
+  -0.001863,  0.016738,  -0.033705,  0.062233,  -0.140759,
+  0.027342,  0.060074,  0.030362,  -0.117875,  0.06102,
+  -0.028026,  -0.088238,  -0.003782,  -0.146288,  -0.080395,
+  0.050048,  0.036136,  0.0195,  0.066902,  0.020355,
+  0.024817,  -0.056254,  -0.140918,  -0.085803,  0.02054,
+  -0.00373,  0.161411,  -0.049408,  0.000219,  -0.002348,
+  -0.055021,  0.06782,  0.126483,  -0.031063,  -0.119299,
+  -0.102834,  0.001133,  0.010172,  0.107707,  -0.029106,
+  -0.059813,  0.036698,  -0.02172,  -0.043189,  -0.00227,
+  -0.031694,  0.009605,  -0.022459,  -0.036417,  0.053675,
+  0.061561,  -0.012723,  0.05004,  -0.02945,  0.131044,
+  -0.124516,  -0.107579,  -0.012171,  0.011761,  0.002599,
+  0.016327,  -0.060854,  -0.08091,  0.030875,  -0.002997,
+  -0.02097,  -0.01188,  -0.086096,  0.037912,  0.012421,
+  0.055253,  -0.00725,  0.04174,  0.055596,  -0.02442,
+  -0.017564,  -0.079202,  0.008897,  0.180091,  0.05449,
+  0.001772,  -0.022151,  -0.082048,  -0.010559,  -0.163377,
+  -0.02066,  -0.017827,  -0.0308,  -0.045856,  0.122405,
+  -0.052946,  -0.13049,  0.097383,  -0.116737,  0.039855,
+  0.056504,  -0.059549,  -0.059931,  -0.018658,  0.034898,
+  0.054889,  0.005373,  -0.066796,  -0.12736,  0.04796,
+  0.071746,  0.02741,  -0.006212,  0.024132,  -0.094062,
+  0.005369,  -0.008926,  0.073085,  -0.014265,  -0.029204,
+  -0.100025,  -0.072076,  0.014651,  0.069368,  0.048275,
+  -0.066823,  0.086074,  0.014921,  -0.015395,  -0.045138,
+  0.026224,  0.000902,  -0.038208,  -0.035221,  0.057397,
+  0.097606,  -0.073195,  0.051626,  -0.033488,  0.027813,
+  0.00207,  -0.09751,  -0.057877,  0.12668,  -0.082194,
+  -0.072597,  0.006014,  -0.093185,  -0.016853,  -0.02279,
+  0.138461,  0.005394,  -0.056485,  0.102778,  0.028918,
+  -0.045604,  -0.060041,  0.121251,  0.02926,  -0.101404,
+  0.061194,  0.033039,  -0.016798,  0.064263,  0.065144,
+  0.010925,  0.023151,  0.107623,  0.027977,  -0.090356,
+  -0.024863,  -0.00644,  0.04787,  -0.047486,  0.088211,
+  -0.012139,  -0.116121,  -0.000525,  -0.140961,  0.016604,
+  0.06349,  -0.022732,  -0.046944,  0.06697,  -0.068838,
+  0.016143,  0.026202,  -0.043344,  -0.064881,  0.024877,
+  -0.072845,  0.120531,  0.077901,  0.047272,  0.011713,
+  -0.044646,  0.040932,  0.076164,  -0.101233,  -0.029615,
+  -0.065118,  0.050966,  -0.023273,  0.053517,  0.02371,
+  -0.007489,  0.035822,  0.023439,  -0.055528,  -0.004033,
+  -0.007662,  -0.096546,  -0.081662,  0.037141,  0.137562,
+  0.075526,  -0.097496,  0.12399,  0.013996,  0.087005,
+  -0.019788,  -0.082043,  0.020524,  0.007027,  -0.021537,
+  -0.036264,  -0.090952,  -0.177722,  -0.009306,  -0.031473,
+  -0.009287,  0.047557,  -0.090241,  0.089347,  0.056375,
+  -0.005506,  -0.112128,  0.004356,  0.064421,  -0.038478,
+  -0.035674,  0.040616,  0.007731,  0.160236,  -0.054199,
+  -0.007537,  0.012434,  0.022001,  -0.021567,  -0.075163,
+  -0.026053,  0.015909,  0.041015,  0.021832,  0.034152,
+  -0.048539,  -0.086655,  0.047465,  0.000682,  0.04264,
+  0.023697,  -0.095971,  -0.022874,  -0.000369,  0.003413,
+  0.046005,  0.064807,  0.010131,  -0.129517,  -0.092254,
+  0.116469,  0.053796,  0.03811,  0.09447,  0.018435,
+  -0.034803,  0.073591,  0.108348,  0.104096,  0.049884,
+  -0.021274,  0.022097,  0.065347,  0.065555,  0.089319,
+  0.000474,  -0.004186,  -0.040493,  -0.065543,  -0.083167,
+  -0.017425,  0.049177,  -0.044248,  0.008399,  0.06818,
+  0.154778,  0.027549,  -0.008012,  0.01495,  0.043254,
+  0.039599,  -0.136415,  -0.018716,  0.0619,  0.031263,
+  0.058118,  -0.0372,  -0.114692,  -0.080876,  -0.053238,
+  0.077436,  0.015015,  -0.092517,  0.005804,  -0.065541,
+  -0.005653,  -0.073184,  0.095594,  0.08247,  0.060989,
+  -0.000262,  -0.035766,  -0.083441,  0.122634,  0.088429,
+  -0.014397,  -0.055434,  -0.005659,  0.069697,  -0.064892,
+  0.008824,  0.082498,  0.051866,  -0.03607,  0.033403,
+  -0.082855,  -0.087376,  0.002714,  -0.097121,  -0.01917,
+  0.027179,  -0.06987,  -0.009316,  0.04745,  0.040657,
+  0.060527,  0.00462,  -0.040264,  -0.051228,  -0.029023,
+  -0.071384,  0.101421,  0.009538,  -0.099185,  0.0601,
+  -0.048395,  -0.024677,  0.025125,  -0.056043,  -0.058045,
+  -0.054059,  0.008107,  0.021078,  0.04529,  -0.018459,
+  -0.113359,  0.014009,  -0.006826,  -0.052747,  0.046922,
+  -0.075976,  0.008538,  -0.084411,  -0.004369,  0.045801,
+  0.075392,  -0.06734,  0.014454,  0.032407,  0.092478,
+  -0.061859,  -0.083458,  0.051442,  0.031695,  -0.080233,
+  0.054028,  0.027,  -0.073549,  0.0323,  0.036501,
+  -0.011384,  -0.02078,  -0.124142,  0.093905,  -0.028332,
+  0.039139,  -0.030944,  0.079952,  -0.001717,  0.013976,
+  0.038005,  -0.001751,  -0.044097,  0.129827,  0.014385,
+  -0.001682,  -0.063458,  -0.002511,  -0.07815,  -0.141236,
+  0.021955,  0.104851,  -0.093246,  -0.060019,  0.069998,
+  0.004399,  -0.096408,  0.059327,  -0.062268,  -0.074327,
+  0.108063,  -0.090534,  -0.045654,  0.048119,  0.049187,
+  0.042105,  0.043964,  -0.091516,  -0.047999,  -0.028881,
+  0.070471,  0.055401,  -0.025605,  0.011176,  0.008475,
+  0.022254,  0.038266,  0.048106,  0.047176,  -0.017967,
+  -0.010978,  -0.088762,  0.034806,  0.019311,  0.126815,
+  -0.010571,  0.053073,  0.032162,  -0.00078,  -0.1522,
+  -0.014253,  -0.021954,  -0.13104,  -0.061376,  0.113838,
+  0.060725,  0.020201,  0.102533,  -0.011392,  -0.052046,
+  -0.069625,  -0.091011,  -0.097954,  0.067847,  0.017856,
+  -0.053461,  -0.040679,  -0.121664,  -0.077208,  -0.106919,
+  0.057996,  0.069756,  -0.012433,  0.069569,  -0.055159,
+  -0.024801,  -0.060448,  0.1017,  0.014619,  0.03658,
+  -0.004526,  0.093977,  -0.028211,  0.045261,  0.149736,
+  -0.014691,  -0.007959,  0.097708,  0.107128,  -0.079723,
+  0.029157,  0.020116,  0.104828,  -0.064208,  0.119172,
+  0.039583,  -0.029446,  0.006628,  -0.110398,  0.004062,
+  0.048132,  -0.060601,  0.009448,  0.051777,  -0.053127,
+  0.050551,  -0.001924,  0.028079,  -0.050618,  -0.013698,
+  0.00192,  0.088162,  0.073078,  0.085795,  -0.066788,
+  0.014025,  0.042699,  0.176241,  -0.046674,  -0.034822,
+  -0.051433,  0.121729,  -0.057076,  0.023901,  0.045075,
+  -0.057182,  0.05478,  -0.01728,  -0.146674,  0.00209,
+  -0.016223,  -0.044841,  -0.084524,  -0.152479,  0.072688,
+  -0.006962,  0.008711,  0.127455,  -0.003876,  0.053162,
+  -0.013682,  -0.025386,  -0.000427,  -0.024811,  -0.024474,
+  -0.056267,  0.062116,  -0.121311,  -0.053011,  0.065651,
+  -0.075385,  -0.00868,  -0.063033,  0.083039,  0.110577,
+  -0.000152,  -0.127017,  0.055904,  0.013659,  0.005664,
+  -0.002852,  0.047248,  0.001128,  0.100773,  0.037274,
+  0.026368,  -0.042205,  0.021887,  -0.020247,  -0.056678,
+  -0.077475,  0.089799,  0.058003,  0.039741,  0.106663,
+  -0.016853,  -0.015972,  0.075741,  -0.048829,  0.015374,
+  -0.032657,  -0.125677,  -0.06206,  -0.057409,  -0.061287,
+  0.073151,  0.050357,  0.053547,  -0.059886,  -0.051298,
+  0.057954,  -0.003817,  0.076028,  0.006757,  0.061109,
+  -0.03803,  0.143209,  0.092207,  -0.018493,  0.062291,
+  0.005751,  -0.036449,  0.067582,  0.031449,  0.101894,
+  -0.080754,  0.011515,  -0.049485,  -0.016137,  -0.087818,
+  0.108851,  0.038222,  -0.099315,  -0.003117,  0.052278,
+  0.107517,  -0.036233,  0.06537,  0.040409,  -0.057029,
+  -0.033167,  -0.081758,  -0.019502,  0.033438,  0.013365,
+  -0.01776,  -0.025906,  -0.020244,  -0.078722,  -0.011697,
+  -0.028246,  0.068647,  -0.106417,  0.026956,  -0.064914,
+  0.062711,  -0.017857,  0.151539,  0.044613,  -0.01782,
+  0.009085,  -0.032785,  -0.025795,  0.07579,  0.075667,
+  -0.040398,  0.058556,  -0.042634,  0.093973,  -0.099529,
+  0.057103,  0.073562,  0.01264,  -0.066141,  0.029558,
+  0.060219,  -0.083699,  -0.054799,  -0.120442,  -0.000374,
+  0.006521,  0.034512,  -0.039558,  0.042191,  0.033865,
+  0.103992,  -0.014977,  -0.077384,  -0.05134,  0.001873,
+  0.047451,  0.140612,  -0.024885,  -0.02142,  -0.046604,
+  0.030606,  0.10066,  0.076356,  -0.019288,  -0.09857,
+  -0.114463,  -0.010855,  -0.034657,  0.025618,  -0.003356,
+  -0.087913,  0.064346,  -0.07554,  -0.091569,  -0.024965,
+  -0.021232,  -0.017255,  -0.056931,  -0.003104,  0.030219,
+  -0.020112,  -0.012334,  0.035298,  0.001405,  0.161753,
+  -0.064618,  -0.064401,  -0.007218,  -0.00012,  -0.047208,
+  0.116105,  -0.056464,  -0.069645,  -0.007032,  -0.01209,
+  -0.023237,  0.016,  -0.039802,  0.074319,  -0.012604,
+  0.014863,  -0.058081,  0.093219,  0.062253,  -0.040302,
+  0.027405,  -0.128683,  0.039923,  0.116808,  -0.011706,
+  0.012483,  -0.017698,  0.003645,  -0.007588,  -0.120662,
+  -0.032868,  0.066217,  -0.031343,  -0.034166,  0.146334,
+  -0.031228,  -0.125921,  0.117756,  -0.042686,  -0.062094,
+  0.049375,  -0.112262,  0.010166,  -0.073599,  0.04869,
+  0.028292,  0.020076,  -0.062865,  -0.106114,  -0.0253,
+  0.066916,  0.029279,  0.028191,  -0.003599,  -0.040614,
+  0.020491,  0.060238,  0.052747,  -0.01039,  -0.022389,
+  -0.063358,  -0.028707,  0.035907,  -0.011898,  0.079703,
+  -0.003758,  0.078051,  -0.017869,  0.009045,  -0.018982,
+  0.034974,  0.069405,  -0.018909,  -0.038613,  0.083909,
+  0.033935,  -0.036607,  0.088891,  -0.052599,  -0.059839,
+  0.052758,  -0.068308,  -0.063615,  0.126093,  -0.00946,
+  -0.042175,  -0.011113,  -0.073071,  0.052086,  -0.052619,
+  0.049226,  0.066898,  -0.045666,  0.117923,  0.053656,
+  -0.010739,  -0.043962,  0.141903,  0.001792,  -0.035469,
+  0.090671,  0.043993,  -0.013655,  0.018989,  0.127223,
+  0.00103,  -0.001154,  0.081839,  -0.024979,  -0.103704,
+  -0.07792,  0.036083,  0.06822,  -0.06221,  0.11373,
+  -0.010501,  -0.065801,  0.050885,  -0.104304,  0.121937,
+  0.11185,  0.00968,  -0.011791,  0.001677,  -0.035029,
+  0.010677,  0.024572,  -0.01286,  -0.030323,  -0.010466,
+  0.011279,  0.167752,  0.003136,  0.109709,  0.007292,
+  0.000987,  0.004572,  0.108706,  -0.113192,  -0.012431,
+  -0.015225,  0.073653,  -0.051275,  0.077928,  -0.012752,
+  -0.011708,  0.014172,  0.025162,  -0.095378,  0.026382,
+  -0.028889,  -0.058569,  -0.129329,  0.011087,  0.061452,
+  0.056893,  -0.058004,  0.103586,  -0.060752,  0.081824,
+  -0.042805,  -0.015991,  -0.024444,  0.028952,  -0.013528,
+  0.042851,  0.019988,  -0.165741,  -0.031012,  -0.014713,
+  -0.026059,  0.031698,  -0.134343,  0.03209,  0.020828,
+  0.051674,  -0.128006,  0.050856,  0.02222,  -0.073513,
+  -0.00934,  0.013756,  0.036163,  0.098407,  -0.023495,
+  0.023858,  0.008121,  0.02222,  -0.103489,  -0.046663,
+  -0.033,  0.063565,  0.029224,  -0.012693,  0.084202,
+  0.012187,  -0.051,  0.026126,  -0.043293,  0.008675,
+  -0.019812,  -0.16507,  -0.014555,  -0.047431,  0.01799,
+  -0.040073,  0.107192,  0.022228,  -0.089023,  -0.066885,
+  0.01463,  0.073186,  0.069902,  0.072634,  0.019593,
+  -0.041539,  0.031788,  0.09231,  0.027223,  0.034027,
+  -0.051855,  0.000391,  0.007869,  0.13191,  0.069384,
+  0.046276,  0.04044,  -0.037093,  -0.031393,  -0.112828,
+  0.015709,  0.096749,  -0.103205,  -0.021284,  0.011405,
+  0.158287,  -0.021028,  0.042219,  -0.050759,  0.069715,
+  -0.042907,  -0.11698,  0.014224,  0.094648,  0.028395,
+  0.041535,  -0.057033,  -0.047607,  -0.024419,  -0.034905,
+  0.010125,  0.036728,  -0.052503,  -0.001839,  -0.033477,
+  -0.053414,  -0.070394,  0.092895,  0.1006,  -0.026352,
+  0.080574,  -0.028763,  -0.059548,  0.094571,  0.091787,
+  0.041437,  0.014312,  0.045792,  0.108269,  -0.081586,
+  0.056288,  0.137447,  0.054718,  -0.032474,  0.054502,
+  -0.100144,  -0.00646,  0.024739,  -0.117043,  -0.008919,
+  0.070299,  -0.036862,  -0.014543,  0.0245,  -0.015222,
+  0.114975,  -0.043705,  0.000421,  -0.061872,  -0.035148,
+  -0.022797,  0.128575,  -0.031798,  -0.086718,  -0.007172,
+  -0.071706,  -0.006833,  0.028645,  -0.007011,  -0.096745,
+  -0.142269,  0.027996,  0.06521,  0.061381,  0.000741,
+  -0.140531,  0.01748,  -0.014986,  -0.040893,  -0.012718,
+  -0.012494,  -0.021869,  -0.032923,  0.016456,  0.104475,
+  0.010792,  -0.066178,  0.019097,  -0.001893,  0.067513,
+  -0.092673,  -0.059851,  -0.045936,  0.052642,  -0.0625,
+  0.065013,  -0.025659,  -0.149301,  0.051705,  0.035692,
+  -0.04579,  -0.007482,  -0.069141,  0.149365,  -0.042039,
+  0.018492,  -0.081315,  0.05588,  0.058158,  0.019669,
+  0.063836,  -0.012391,  0.007057,  0.155454,  0.033854,
+  -0.016532,  -0.007661,  0.043113,  -0.080283,  -0.10867,
+  -0.029344,  0.093781,  -0.01584,  -0.068134,  0.091804,
+  0.004148,  -0.058507,  0.059633,  -0.095883,  -0.004939,
+  0.086151,  -0.113571,  -0.019466,  -0.009167,  0.003662
+};
+
+const struct lsp_codebook lsp_cbjvm[] = {
+  /* codebook/lspjvm1.txt */
+  {
+    10,
+    9,
+    512,
+    codes0
+  },
+  /* codebook/lspjvm2.txt */
+  {
+    5,
+    9,
+    512,
+    codes1
+  },
+  /* codebook/lspjvm3.txt */
+  {
+    5,
+    9,
+    512,
+    codes2
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebooknewamp1.c b/codec2/branches/0.7/src/codebooknewamp1.c
new file mode 100644 (file)
index 0000000..6de33ee
--- /dev/null
@@ -0,0 +1,1057 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under 
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* /home/david/codec2-dev/src/codebook/train_120_1.txt */
+static const float codes0[] = {
+  6.7484,  7.6125,  6.0332,  5.2789,  1.5239,  2.2353,  2.0748,  0.5289,  0.8748,  2.5432,  -2.2863,  -3.191,  -0.0434,  -1.9857,  -3.3605,  0.7069,  -5.9493,  -0.5672,  -0.6798,  -18.0977,
+  4.0503,  3.9086,  2.9225,  2.3773,  0.658,  -0.4363,  -0.0644,  2.4063,  1.3428,  2.4542,  0.5275,  0.982,  -1.3277,  0.6811,  0.0273,  -0.1838,  -0.0222,  -0.6478,  -2.2405,  -17.4152,
+  13.3284,  12.1212,  10.6531,  9.8214,  11.0388,  15.812,  19.711,  16.5488,  16.1068,  15.8771,  7.2553,  4.2486,  -6.0036,  -12.5476,  -20.1299,  -28.2803,  -25.3971,  -21.7907,  -11.5143,  -26.859,
+  21.4405,  18.4703,  17.8693,  14.9679,  11.2994,  6.4906,  4.7717,  0.1959,  -0.8801,  1.8991,  1.9793,  -4.9755,  -7.7852,  -10.0492,  -8.5295,  -8.2893,  -4.1203,  -12.4072,  -16.166,  -26.1817,
+  4.0023,  3.8279,  1.2681,  1.0053,  0.7002,  -0.3886,  3.4465,  -1.4055,  -6.7846,  -2.3345,  -2.905,  -0.1344,  3.4192,  2.4319,  10.0096,  3.9279,  0.6807,  0.322,  -3.8325,  -17.2565,
+  29.8276,  21.1543,  12.7853,  13.0246,  5.8164,  3.7469,  2.4198,  0.151,  -4.5449,  5.2695,  11.7552,  -4.8954,  -6.0291,  -8.978,  4.965,  -10.654,  -12.5363,  -21.6056,  -18.2985,  -23.3739,
+  4.861,  5.1207,  6.5382,  9.8638,  15.4754,  18.8192,  14.8018,  10.7685,  12.4401,  14.0392,  2.92,  -3.7283,  -9.7213,  -13.5526,  -16.073,  -13.7571,  -5.4267,  -12.2552,  -14.5143,  -26.6193,
+  3.0429,  3.0335,  4.4785,  5.6483,  5.3476,  5.7519,  3.5651,  4.9007,  4.9672,  -0.733,  -0.6458,  6.5888,  5.2957,  -2.0068,  -6.0189,  -7.2145,  2.5545,  -5.8358,  -7.4936,  -25.2263,
+  5.9384,  7.0203,  10.7433,  15.2477,  14.8437,  8.0949,  3.1384,  -0.0014,  -0.1756,  2.1601,  8.1029,  0.4123,  -6.8062,  -9.6038,  -6.2302,  0.4409,  -8.9878,  -10.1638,  -4.6903,  -29.484,
+  7.188,  6.1134,  5.4021,  10.5427,  17.0718,  14.5658,  6.8632,  2.2257,  0.4412,  3.8257,  9.0388,  -1.1212,  -6.7639,  -9.2412,  -8.6575,  -2.9951,  -8.6659,  -9.422,  -6.6046,  -29.8068,
+  9.8859,  4.3889,  3.6253,  3.2033,  4.6563,  4.5967,  1.8747,  -0.0037,  3.2114,  3.8854,  3.1501,  0.8523,  -5.283,  -8.4603,  -5.1159,  -3.9157,  6.98,  -1.527,  -6.0421,  -19.9624,
+  7.6208,  10.1888,  12.8648,  16.4838,  14.9269,  7.8064,  3.5594,  -2.8048,  -3.6303,  -10.8596,  -7.1254,  -2.889,  5.4295,  -2.5015,  -5.5359,  -2.9934,  -6.598,  -7.1493,  -4.9387,  -21.8545,
+  12.7227,  17.1387,  21.7055,  19.8068,  12.1832,  5.8645,  -2.4103,  -3.8445,  -5.5496,  -5.5608,  -0.201,  5.1772,  -1.4666,  -6.6602,  -1.2573,  -3.1593,  -10.7925,  -14.3751,  -12.0047,  -27.3167,
+  7.4465,  7.8765,  9.4912,  12.2074,  12.1631,  11.478,  7.6294,  2.6922,  0.1566,  -2.1903,  -1.5699,  -1.8031,  2.2555,  -1.5591,  -7.9267,  -10.3612,  -5.5432,  -5.5673,  -10.0797,  -26.796,
+  0.3749,  1.9725,  2.6868,  6.3326,  8.9635,  12.8113,  13.6523,  14.0916,  11.2443,  1.2914,  -1.9954,  -2.9443,  -4.6718,  -4.3132,  -3.4613,  -8.1105,  -7.9033,  -7.0956,  -6.5898,  -26.3361,
+  10.3072,  10.6822,  8.8253,  4.8992,  4.3627,  8.8165,  9.7824,  3.7264,  0.4265,  0.6068,  3.0934,  2.9121,  -0.6717,  -5.8045,  -1.7344,  -9.1008,  -8.8333,  -6.0633,  -11.2321,  -25.0005,
+  10.6992,  14.806,  18.9665,  22.421,  21.871,  15.6647,  10.616,  12.1366,  14.0479,  7.0707,  -3.8212,  -12.177,  -16.1111,  -19.3389,  -18.8315,  -17.5346,  -7.9646,  -9.4592,  -17.5614,  -25.5,
+  9.9592,  11.7001,  14.2704,  14.1434,  7.3322,  4.2766,  -0.0567,  -2.7113,  -5.7358,  -6.739,  -5.9067,  -0.1939,  4.8177,  -3.981,  -7.2528,  -3.2695,  -1.5685,  -7.894,  -6.3355,  -14.8548,
+  17.6322,  19.5153,  22.4362,  16.2943,  10.4698,  2.5066,  -2.3936,  -5.377,  -7.9766,  -9.8004,  -12.964,  -13.1015,  -9.8076,  -5.7565,  1.8732,  0.4843,  3.3621,  -1.0048,  -4.8377,  -21.5543,
+  9.9491,  17.4987,  23.2236,  17.3142,  6.8072,  6.6873,  1.9421,  1.1415,  2.9409,  6.847,  2.4633,  -7.2869,  -8.9792,  -3.3155,  -0.1918,  -11.8037,  -18.6298,  -12.6475,  -9.762,  -24.1984,
+  9.208,  9.9971,  12.5064,  20.0609,  20.9647,  10.9574,  7.436,  4.4943,  4.8454,  11.0636,  1.8176,  -7.3479,  -12.5617,  -15.3912,  -11.5022,  -5.0309,  -14.7556,  -15.4294,  -6.415,  -24.9176,
+  7.7917,  9.3291,  11.8185,  15.3501,  19.3235,  20.6869,  19.816,  14.6028,  10.2893,  9.9407,  9.8534,  3.6182,  2.7695,  -5.2735,  -19.7962,  -24.6834,  -27.0316,  -25.6805,  -24.9149,  -27.8096,
+  0.1108,  3.1261,  6.8163,  12.4528,  16.9192,  10.8153,  2.6109,  -0.2652,  -4.8897,  -6.1056,  -7.3218,  -4.4594,  4.3004,  3.7728,  -2.8276,  -0.0458,  1.0104,  -6.4884,  -6.486,  -23.0456,
+  12.9442,  10.3059,  3.1303,  2.1611,  1.4795,  2.758,  6.9527,  8.4487,  7.1533,  1.4465,  -0.9113,  -3.9971,  -4.909,  -5.3881,  -3.1011,  -0.4922,  -1.1819,  -5.3279,  -8.2374,  -23.2345,
+  25.0945,  17.8572,  8.95,  2.704,  0.2187,  1.4115,  0.7421,  0.5831,  -0.3096,  0.9334,  -2.9667,  -4.0352,  -2.8473,  -4.8594,  -4.5863,  -4.4311,  -2.8466,  -4.4808,  -5.1669,  -21.9645,
+  14.6124,  19.7986,  21.2066,  15.762,  8.7509,  3.7653,  -0.5239,  -3.8894,  -6.8522,  -8.4979,  -8.1879,  -5.8438,  0.5485,  6.7415,  0.4745,  2.675,  -10.3676,  -15.0245,  -12.2357,  -22.9125,
+  11.9959,  12.9771,  17.1177,  21.531,  16.8892,  10.8731,  9.7276,  8.5106,  12.9569,  2.2512,  -6.9324,  -13.2124,  -16.538,  -18.0518,  -16.6252,  -9.7038,  -6.122,  -8.7542,  -6.8998,  -21.9905,
+  12.8107,  14.567,  13.4289,  7.1693,  3.4265,  3.1397,  2.5457,  -1.2214,  -0.3887,  2.4506,  3.9777,  0.9056,  -6.9195,  -7.3811,  -3.2619,  -0.3714,  2.6266,  -6.3479,  -12.2319,  -28.9244,
+  2.6437,  2.2575,  3.8643,  6.0625,  10.9091,  16.9554,  21.5045,  12.7233,  9.3579,  9.4439,  12.8585,  4.4528,  -2.4283,  -4.733,  -2.2502,  -11.3098,  -18.5273,  -22.457,  -23.1304,  -28.1976,
+  10.5757,  10.9392,  14.0126,  18.2101,  14.3745,  8.6896,  4.908,  1.0411,  2.3482,  7.2221,  4.544,  -5.0353,  -11.2852,  -13.0882,  -10.96,  -3.0288,  -9.5005,  -10.2217,  -6.6739,  -27.0717,
+  14.6172,  4.5412,  13.3824,  9.2916,  19.2818,  13.6563,  14.4089,  10.126,  1.6926,  3.9361,  -0.6461,  -5.1244,  -9.3641,  -13.9807,  -11.4128,  -11.8597,  -0.8237,  -20.3149,  -12.3561,  -19.0515,
+  4.0591,  4.6177,  7.7662,  6.8737,  9.4052,  10.1099,  12.8714,  8.1202,  6.6015,  7.9224,  1.7548,  -1.6325,  -4.8379,  -5.0955,  -2.1947,  -8.422,  -11.8799,  -10.7107,  -12.0066,  -23.3222,
+  -3.3385,  -1.1297,  3.0554,  4.9769,  3.8625,  8.6998,  8.0974,  -0.5519,  -1.0699,  -5.4771,  -4.7235,  -4.8192,  7.1236,  -0.4895,  -2.0107,  0.1838,  3.518,  3.2804,  3.1904,  -22.3779,
+  10.9362,  15.2821,  18.1297,  12.4682,  2.6895,  -1.2007,  -1.7676,  -6.1681,  -6.0524,  -5.8064,  -3.1002,  4.3237,  2.0263,  -5.5109,  1.0348,  -0.476,  -4.6274,  1.4107,  -7.5329,  -26.0586,
+  27.0648,  22.2199,  14.8908,  7.7845,  2.8689,  -0.0364,  0.0683,  -0.1186,  -1.6323,  -2.4217,  -4.0112,  -2.3476,  -5.4442,  -5.8509,  -6.4386,  -6.2558,  -6.7739,  -5.9348,  -7.0916,  -20.5398,
+  4.3156,  -0.2499,  1.1824,  2.8225,  8.191,  5.2798,  2.2597,  -3.0043,  -5.0382,  -5.2727,  -4.0013,  2.6952,  8.1245,  -1.1517,  -1.8957,  2.4603,  3.0897,  -1.0817,  -0.1353,  -18.5898,
+  17.5894,  22.9315,  26.4862,  22.162,  13.7474,  13.5177,  15.2005,  16.3224,  4.9523,  -4.2419,  -8.3503,  -12.4022,  -12.6698,  -6.7159,  -16.2122,  -20.1926,  -20.5969,  -16.0749,  -12.5173,  -22.9353,
+  6.5871,  8.0443,  8.4339,  11.3345,  17.3665,  13.4455,  6.9211,  2.0512,  -0.7348,  -1.2898,  1.0076,  8.4862,  -0.336,  -6.4714,  -5.9432,  -4.1602,  -12.1155,  -12.4645,  -10.9269,  -29.2355,
+  19.0066,  20.3716,  18.0417,  9.4806,  4.8058,  0.3359,  -4.1091,  -8.193,  -8.9962,  -9.7495,  -13.2924,  -8.6275,  -4.9424,  6.0502,  -6.8142,  -7.1166,  -3.0922,  8.8016,  5.6937,  -17.6547,
+  4.7309,  -6.5949,  4.9914,  7.3489,  9.0188,  4.1567,  7.1949,  0.4917,  5.0462,  7.5219,  1.5314,  -15.3803,  5.313,  -0.0983,  -7.0327,  -1.2671,  -0.4646,  -1.6442,  -0.7446,  -24.119,
+  13.7639,  5.1424,  5.3193,  3.8945,  3.9574,  1.4034,  0.1896,  -4.0608,  -2.5264,  -4.9434,  2.8459,  2.6311,  -2.7915,  -3.7842,  -0.3711,  0.5487,  5.3766,  -4.3496,  -3.2801,  -18.9656,
+  12.6752,  14.7799,  16.2157,  18.6944,  14.139,  7.0937,  3.8206,  -2.4778,  -3.9766,  -4.4531,  -2.8711,  3.2148,  0.68,  -9.1748,  -10.16,  -6.0557,  -0.8581,  -9.2828,  -14.0109,  -27.9924,
+  15.0025,  18.2042,  22.4086,  21.6195,  14.2308,  10.5772,  6.7291,  6.0463,  11.7877,  8.4162,  -3.4731,  -11.2708,  -15.6923,  -17.5613,  -14.5235,  -4.5248,  -17.8954,  -18.3529,  -10.3105,  -21.4173,
+  2.5368,  2.8687,  8.7229,  5.2089,  8.9671,  2.8847,  -1.3535,  -4.4273,  -4.906,  -7.8939,  -15.475,  -10.4797,  -4.4811,  6.5892,  9.9939,  12.9078,  3.2705,  1.3246,  3.7883,  -20.0468,
+  8.5207,  11.8364,  16.4466,  19.9166,  16.0662,  8.4129,  4.329,  -0.8928,  -3.7592,  -5.4071,  -4.287,  0.4615,  9.9611,  5.819,  1.7969,  -7.7765,  -17.3073,  -19.5235,  -17.7924,  -26.8211,
+  3.0595,  10.0158,  11.1623,  5.9413,  3.1988,  -2.1129,  0.3528,  -3.0158,  -2.3599,  -1.3347,  -1.0479,  3.9189,  7.8019,  3.0538,  -1.6139,  0.8043,  -4.929,  -6.9959,  -7.2918,  -18.6077,
+  17.8476,  19.4332,  25.4614,  19.1508,  12.2748,  9.4543,  6.1101,  3.6929,  2.9336,  5.5407,  -9.2238,  -17.0071,  -20.8856,  -22.9308,  -21.1711,  -15.0234,  4.8627,  2.2867,  -2.1943,  -20.6125,
+  9.6165,  8.8018,  11.1694,  14.6183,  18.4154,  13.4481,  7.158,  4.165,  1.8242,  0.9521,  5.1356,  4.027,  -5.9523,  -12.0202,  -14.3055,  -10.5893,  -2.8308,  -12.2805,  -13.3723,  -27.9806,
+  13.4166,  16.7617,  20.6572,  22.0976,  15.9129,  10.641,  5.4061,  3.157,  -0.7256,  1.2303,  5.9463,  5.1273,  3.4864,  1.6884,  -10.9215,  -19.5567,  -22.8693,  -20.4758,  -24.042,  -26.9379,
+  8.0404,  15.9476,  21.0441,  15.082,  8.2842,  3.1036,  -0.2419,  -4.2559,  -6.0751,  -7.4529,  -5.5847,  1.552,  8.3483,  3.3751,  -1.0503,  -10.4691,  -11.936,  -5.5738,  -6.8713,  -25.2662,
+  19.995,  20.2102,  18.7443,  12.722,  5.8592,  3.8088,  0.4504,  -1.5876,  -0.0425,  -3.0873,  5.5382,  -0.1499,  -5.85,  -7.9372,  -6.2374,  -0.2643,  -15.0702,  -16.9914,  -9.3644,  -20.7458,
+  -2.6024,  -7.495,  -1.2522,  3.5119,  3.9726,  3.4991,  2.4457,  3.2158,  -0.183,  -1.7087,  -7.3996,  -6.8962,  -5.2421,  -7.5762,  -9.1433,  6.6126,  10.5297,  10.4556,  18.2991,  -13.0433,
+  0.8317,  2.2343,  3.6899,  5.6335,  5.8479,  6.433,  6.0022,  5.363,  2.3387,  -0.5344,  -1.0716,  0.6509,  -0.7175,  -4.0229,  -6.0631,  -4.7546,  -1.97,  -4.6226,  0.0933,  -15.3616,
+  -9.366,  -6.9175,  -4.9307,  -3.1828,  -1.6587,  -1.4971,  -0.1586,  0.6208,  0.5169,  2.4709,  4.6017,  5.3127,  4.5449,  3.269,  3.759,  3.4511,  3.826,  3.9369,  4.8805,  -13.479,
+  -1.183,  0.5095,  1.1754,  2.3109,  2.2722,  1.3243,  1.6529,  -0.1799,  -0.2874,  -1.2863,  -2.2761,  -1.5668,  -1.2037,  -2.4367,  -3.9243,  -2.1186,  2.3502,  1.4312,  9.5827,  -6.1467,
+  9.2349,  10.765,  18.1608,  20.6655,  13.5769,  5.4902,  3.0323,  -1.0259,  -0.501,  1.7689,  10.381,  12.0253,  9.1922,  -4.9615,  -15.0315,  -19.9651,  -21.4377,  -17.68,  -6.4577,  -27.2328,
+  10.6391,  10.7983,  11.4949,  16.5329,  19.2664,  13.6129,  6.1846,  2.4573,  -3.1501,  -7.1814,  -7.9387,  -2.6238,  4.6419,  -5.9113,  -9.351,  -7.0591,  -3.2275,  -10.282,  -10.5308,  -28.3726,
+  18.6364,  19.3874,  19.593,  14.3075,  9.4402,  3.6045,  -1.9801,  -5.5352,  -9.0094,  -10.9308,  -12.7345,  -14.0779,  -10.9593,  -3.8674,  6.3753,  9.5959,  -1.4018,  -7.4988,  -6.1435,  -16.8015,
+  9.4969,  11.3591,  11.5468,  7.8918,  4.7217,  3.0266,  4.2145,  2.2878,  1.2224,  5.6903,  10.6919,  4.2718,  0.7184,  -3.7583,  -6.7954,  -8.0558,  -7.9668,  -10.2861,  -12.5018,  -27.7759,
+  1.9805,  4.9512,  7.016,  7.8284,  8.7891,  8.0863,  7.7994,  7.9865,  8.6027,  13.1944,  14.7771,  11.0643,  2.1716,  -5.7171,  -10.9834,  -8.7615,  -16.8907,  -14.3039,  -17.4732,  -30.1175,
+  7.4683,  9.4924,  11.1231,  14.049,  15.3387,  7.9538,  5.2116,  -0.0275,  -3.0014,  0.105,  0.6547,  7.966,  -2.3476,  -7.0894,  -4.6113,  -2.0949,  -15.972,  -16.2041,  -7.4758,  -20.5386,
+  4.8388,  4.2032,  3.5738,  6.4994,  10.8701,  16.7006,  14.8672,  6.7149,  3.1448,  0.6167,  2.5321,  7.5899,  1.6456,  -3.0073,  -4.4465,  -2.3406,  -11.2907,  -15.6965,  -17.0827,  -29.9328,
+  9.8208,  5.5733,  3.2835,  2.3197,  5.4502,  9.1113,  10.3794,  8.6442,  6.0107,  6.4897,  4.2548,  1.1709,  -4.1757,  -9.6942,  -10.5243,  -11.8609,  -10.0641,  -3.4488,  -2.2532,  -20.4873,
+  5.8783,  5.8851,  7.6595,  5.2009,  5.1,  1.982,  2.2615,  1.4023,  -1.1079,  1.1247,  3.7199,  2.8362,  -0.5182,  1.4421,  1.5607,  -8.4521,  -3.7106,  -1.6008,  -5.275,  -25.3888,
+  13.8298,  17.3228,  17.9494,  18.8765,  12.6415,  7.5326,  5.2828,  1.03,  -1.0231,  -5.4994,  -6.6194,  -2.5155,  4.6895,  -3.4515,  -7.2113,  -4.1051,  -13.7542,  -14.3604,  -11.8611,  -28.7541,
+  -8.8559,  -3.0649,  2.2249,  4.9828,  6.417,  6.9906,  9.9342,  12.0149,  12.2463,  14.3103,  18.4345,  6.3234,  4.2404,  -2.7341,  -6.9396,  -10.7644,  -10.1668,  -12.3674,  -16.3891,  -26.8371,
+  10.9983,  13.5279,  16.2801,  19.6892,  16.9475,  11.0028,  3.9633,  1.1799,  -2.0078,  -0.985,  2.7247,  -0.1311,  -6.6215,  -8.589,  -4.3971,  -11.9543,  -15.4358,  -13.3278,  -4.8427,  -28.0217,
+  7.2013,  9.1028,  13.1142,  19.8377,  22.536,  16.6528,  11.833,  10.3141,  12.9885,  15.8372,  9.0995,  8.4627,  1.1838,  -14.4656,  -21.4397,  -23.6775,  -22.5547,  -24.8595,  -24.4974,  -26.6692,
+  -8.4073,  -6.6779,  -3.958,  -1.6241,  -2.147,  -2.2867,  -2.2534,  -3.0205,  -4.5931,  -2.5545,  -2.135,  -1.3098,  1.1053,  -1.1397,  1.217,  6.2234,  3.6093,  9.8015,  23.5766,  -3.426,
+  9.6955,  11.4467,  15.0851,  15.4765,  9.8267,  3.549,  -0.5777,  -2.7726,  -5.1878,  -5.7225,  -4.4558,  0.4969,  9.2914,  5.8917,  6.4235,  -4.2514,  -11.0149,  -9.4893,  -13.0444,  -30.6665,
+  2.9943,  1.4307,  0.8714,  2.2925,  2.1145,  2.9148,  2.4003,  1.9382,  1.6662,  -2.3476,  -2.0877,  -1.9322,  3.3342,  1.7171,  -0.9114,  3.2785,  1.7852,  1.4651,  -1.3549,  -21.5695,
+  7.7138,  9.34,  11.7519,  14.3217,  14.9762,  11.0903,  9.904,  9.3599,  10.4611,  6.3795,  -3.9927,  -7.6734,  -12.4888,  -12.1729,  -5.7999,  -5.5417,  -9.569,  -9.5926,  -7.6846,  -30.7825,
+  4.4498,  9.229,  15.0677,  17.9679,  11.2745,  2.673,  -0.9888,  -5.6255,  -7.5349,  -8.4589,  -8.451,  -5.5027,  1.7669,  4.3143,  -4.8629,  -2.0721,  4.6797,  -5.0125,  -4.4213,  -18.4923,
+  11.1829,  12.4396,  12.7925,  12.6901,  8.015,  3.4089,  1.7847,  -0.2306,  -2.0077,  -1.0178,  2.2167,  -0.4542,  -8.4111,  -8.9029,  -8.0861,  -3.9439,  -6.2512,  -2.2635,  -2.1307,  -20.8306,
+  -0.0237,  3.59,  4.5144,  3.8794,  5.7527,  11.0182,  8.9091,  7.1863,  7.0702,  7.1782,  4.7799,  0.6784,  -4.3508,  -5.3991,  -6.5953,  -5.6132,  -9.5378,  -5.6903,  -1.3834,  -25.9632,
+  -2.7117,  -1.4799,  1.2116,  2.3262,  3.7406,  3.7668,  1.2697,  0.2086,  0.7399,  -1.3479,  -2.2145,  -3.7982,  4.9747,  -0.4583,  -1.7465,  -0.9161,  7.2119,  0.8965,  -0.2723,  -11.4012,
+  7.6123,  10.5335,  16.3125,  23.5319,  21.6117,  16.329,  18.2001,  16.9715,  0.9425,  -7.0707,  -12.7338,  -16.0871,  -18.4761,  -17.8994,  -14.8763,  -4.844,  -8.9433,  -6.8294,  -0.8772,  -23.408,
+  9.1763,  3.0851,  4.6724,  8.0499,  14.6517,  16.8559,  10.4532,  11.9797,  13.2732,  7.6578,  -1.4245,  -7.0469,  -11.9925,  -15.0269,  -14.7577,  -15.9057,  -2.4494,  -8.2002,  -4.4694,  -18.5819,
+  -0.3793,  0.7119,  0.4558,  1.7011,  3.1548,  7.4097,  8.6888,  7.5902,  9.102,  7.3493,  9.7346,  15.2626,  6.8726,  -0.7975,  0.8553,  -9.6815,  -9.3426,  -14.3122,  -13.9791,  -30.3963,
+  5.2988,  6.3406,  1.2009,  3.3308,  2.029,  2.8107,  1.003,  0.4513,  -1.4458,  3.0391,  1.2595,  -9.2407,  1.3164,  1.9175,  0.7738,  1.8301,  0.5948,  -0.9497,  -2.7482,  -18.8117,
+  23.5623,  25.058,  25.0568,  22.4174,  16.4713,  14.4026,  11.1159,  5.025,  -1.0266,  -8.5971,  -10.1924,  -9.612,  -11.8638,  -13.7028,  -4.2,  -6.01,  -12.7481,  -18.5497,  -22.5946,  -24.012,
+  -5.0424,  -4.212,  -3.2703,  -0.4028,  1.8335,  3.2012,  2.3768,  2.0802,  0.6396,  0.2079,  0.1418,  -0.1844,  2.5056,  -0.2078,  -1.3169,  -0.2911,  0.814,  1.7717,  5.2809,  -5.9255,
+  7.633,  9.9835,  15.1303,  18.9128,  13.0001,  5.9224,  1.3978,  -3.1674,  -6.4703,  -8.3713,  -7.747,  -5.2412,  1.6661,  5.3754,  0.9111,  2.2634,  -7.6214,  -11.2828,  -5.6474,  -26.647,
+  15.3965,  19.4488,  18.3928,  11.4564,  4.0261,  0.4604,  -4.6326,  -9.8409,  -11.0926,  -12.7123,  -13.1035,  -12.3357,  -8.4063,  1.3638,  7.8807,  5.5655,  3.421,  0.7205,  5.4867,  -21.4953,
+  4.0267,  4.8087,  7.0895,  9.6094,  12.6372,  17.6545,  19.7244,  17.4364,  13.7517,  13.9367,  6.0059,  -4.5448,  -9.4075,  -13.3403,  -13.662,  -10.1856,  -10.5214,  -17.1512,  -19.3146,  -28.5537,
+  26.5287,  22.7007,  21.6748,  17.6005,  11.9372,  12.6653,  5.4749,  -6.1299,  -8.9419,  -6.962,  -5.7222,  -5.6209,  -8.635,  -10.0876,  -8.1562,  -7.7238,  -5.4233,  -10.0839,  -13.1237,  -21.9717,
+  3.974,  4.1572,  5.7242,  12.448,  17.3522,  11.6512,  5.2405,  1.2103,  0.5569,  2.7329,  9.6369,  -0.5073,  -5.1263,  -2.7956,  -0.7621,  -3.7186,  -1.7764,  -8.4788,  -18.8985,  -32.6208,
+  6.8442,  11.6517,  15.0164,  13.0383,  3.5465,  0.5949,  -3.0134,  -7.5262,  -8.2082,  -8.6101,  -7.2813,  -1.2345,  9.272,  5.1011,  6.0543,  -0.9163,  -4.5878,  3.4588,  -4.8078,  -28.3926,
+  7.8637,  4.0004,  -2.938,  2.0521,  2.2442,  -0.4633,  1.8855,  1.9277,  -0.6295,  1.3834,  1.2896,  1.0703,  -0.4938,  1.5669,  0.0079,  -1.5584,  -2.007,  0.9263,  -0.4846,  -17.6435,
+  5.8623,  7.6023,  7.9357,  8.1933,  9.8252,  14.3094,  18.598,  17.631,  14.1029,  11.3791,  8.9224,  4.7903,  -4.573,  -11.3683,  -17.8078,  -14.2065,  -11.2294,  -16.2936,  -23.1509,  -30.5225,
+  -1.7942,  -0.0063,  1.995,  3.6026,  3.2262,  0.8396,  2.3621,  2.373,  0.2704,  0.4107,  0.3605,  1.3362,  -2.3048,  -2.1177,  -2.8566,  0.0808,  -2.4432,  2.0828,  10.0173,  -17.4341,
+  16.0587,  21.303,  20.2092,  12.229,  4.0091,  1.0523,  -3.6402,  -8.1002,  -8.5006,  -10.1681,  -9.7303,  -7.7995,  -1.2107,  8.9891,  5.5157,  1.2399,  -8.3907,  -7.4334,  -1.1958,  -24.4366,
+  15.8248,  21.2415,  22.3705,  19.6523,  12.6511,  4.98,  2.0524,  1.2562,  -2.0002,  -7.0989,  -8.4866,  -8.1644,  -3.6111,  2.9801,  -6.3159,  -7.3905,  -2.5939,  -11.1587,  -18.1433,  -28.0453,
+  11.4701,  14.8919,  19.2495,  17.1766,  9.1256,  4.6224,  0.3569,  -3.6692,  -6.2969,  -8.7664,  -7.4764,  -1.7487,  3.4354,  -4.0219,  -5.5797,  1.1971,  -7.0079,  -5.6899,  -4.914,  -26.3546,
+  4.0502,  6.3561,  7.7528,  13.2425,  22.1071,  16.8285,  10.8539,  9.9555,  11.6373,  14.4871,  1.0686,  -6.014,  -8.7291,  -9.9474,  -5.242,  -14.0196,  -19.62,  -16.4317,  -13.2116,  -25.1241,
+  14.0747,  12.9823,  14.7396,  18.358,  20.8024,  21.6686,  20.4893,  18.2777,  14.8271,  4.2101,  -4.6228,  -5.0852,  -8.9555,  -9.9704,  -14.4886,  -22.2364,  -24.8924,  -24.6202,  -19.9776,  -25.5806,
+  6.5756,  6.5342,  9.0959,  14.5314,  20.6452,  22.1123,  17.0555,  14.5823,  18.4626,  9.7441,  0.1482,  -4.4759,  -4.9624,  -0.2271,  -12.9306,  -21.6336,  -23.8195,  -22.7039,  -21.8165,  -26.9179,
+  -2.413,  -0.2375,  2.8918,  5.5011,  6.7427,  5.7418,  5.0778,  5.1858,  4.3188,  3.4462,  4.3416,  1.8899,  2.3449,  -0.9372,  -1.2877,  -2.8414,  -4.0969,  -5.4193,  -7.2573,  -22.992,
+  18.6934,  11.3904,  9.2311,  9.3832,  5.4199,  3.6295,  -0.1793,  0.6487,  -3.5589,  -4.0062,  -6.2031,  0.6797,  0.8497,  -5.8255,  -3.0197,  -0.8407,  3.412,  -4.6925,  -10.2551,  -24.7566,
+  -1.1447,  1.564,  1.4686,  1.7604,  1.7234,  2.3262,  4.7312,  2.6246,  3.8383,  6.5465,  3.383,  1.7225,  -1.7619,  -1.0275,  -1.1491,  1.9434,  -4.9663,  -2.3871,  -2.8449,  -18.3507,
+  14.1023,  13.565,  10.151,  8.7911,  7.7313,  7.648,  9.2651,  8.0399,  4.9244,  6.1141,  5.5459,  -0.9256,  -6.155,  -7.0836,  -8.6484,  -9.0926,  -9.2649,  -13.5303,  -12.0852,  -29.0925,
+  9.8451,  13.4743,  16.9269,  13.4623,  5.8133,  1.7553,  -0.7487,  -3.9831,  -8.1249,  -9.5689,  -8.7611,  -6.3983,  -0.6612,  10.9895,  12.8583,  0.3283,  -8.6023,  -10.4136,  -5.9048,  -22.2865,
+  19.2227,  18.1307,  15.9732,  13.2757,  8.9377,  4.0318,  2.7371,  2.4204,  4.8079,  5.9436,  -1.6587,  -5.6682,  -8.2354,  -8.6156,  -5.7373,  -5.9194,  -13.5825,  -11.1928,  -9.7272,  -25.1435,
+  9.7172,  12.7596,  17.788,  19.5982,  13.1714,  6.9756,  4.2961,  1.3629,  -0.4383,  4.963,  8.784,  0.9395,  -2.9094,  0.87,  -9.7739,  -17.6442,  -19.7626,  -14.0983,  -10.0576,  -26.5411,
+  19.7847,  26.9921,  27.0885,  20.9467,  13.4352,  6.9927,  3.8926,  5.5073,  6.395,  3.641,  -3.526,  -9.9366,  -12.2833,  -15.4366,  -15.2739,  -13.403,  -13.6697,  -14.5223,  -14.0162,  -22.6082,
+  -4.745,  -2.3439,  -1.2527,  0.2681,  2.5169,  3.0271,  3.2731,  1.1854,  -1.4898,  -2.2085,  0.9214,  6.1154,  5.0556,  7.1405,  5.3972,  1.8235,  -0.1874,  -0.9732,  -2.7856,  -20.7382,
+  2.7354,  2.9846,  4.5226,  11.0075,  16.9767,  9.7039,  5.0497,  0.2367,  -2.2382,  -2.2319,  3.3972,  5.8953,  -3.5572,  -7.9222,  -5.1006,  4.0687,  -6.798,  -6.9512,  -1.5062,  -30.2728,
+  1.8923,  1.9933,  1.7272,  1.4697,  2.1029,  2.7198,  2.2271,  0.4083,  1.489,  2.3633,  0.0136,  -3.1335,  -1.8351,  -3.4645,  -2.5082,  0.1244,  -0.6305,  -0.2515,  2.667,  -9.3744,
+  7.3147,  10.8559,  16.3202,  21.3322,  15.5047,  5.7917,  2.0324,  -0.5787,  -3.8385,  -3.1611,  4.7722,  6.9085,  -0.8153,  0.2585,  0.5455,  -11.9753,  -19.4608,  -19.4821,  -11.0006,  -21.3242,
+  -4.8271,  -2.3317,  -0.8263,  -0.6913,  0.0284,  2.1785,  4.853,  2.4866,  0.5257,  1.0973,  0.9581,  2.0508,  -0.085,  -0.324,  -2.1544,  -3.6769,  8.253,  1.6818,  2.7619,  -11.9586,
+  28.0344,  21.3292,  26.7011,  15.9009,  17.4755,  11.8357,  5.06,  6.5559,  -4.3031,  -3.5802,  -8.7494,  -8.4692,  -7.5683,  -2.5689,  -10.7488,  -16.5549,  -18.6071,  -16.7713,  -13.4451,  -21.5263,
+  11.4465,  12.5754,  14.651,  12.0835,  5.352,  1.6789,  2.3021,  -2.4719,  -2.0905,  -0.5169,  -2.1754,  -2.9241,  -2.7917,  2.0815,  1.0635,  -3.6587,  -4.768,  -6.8125,  -8.2348,  -26.7899,
+  11.1007,  8.9165,  11.8079,  11.0313,  1.9749,  -0.9229,  -2.467,  -6.7769,  -9.1537,  -10.4373,  -8.8596,  -6.3617,  0.2425,  8.333,  2.9722,  9.5504,  -3.2943,  -3.168,  4.4488,  -18.9367,
+  12.7055,  18.2073,  17.6143,  9.1957,  1.5762,  -1.0952,  -4.9687,  -6.129,  -7.3791,  -7.2053,  -4.3066,  3.6014,  9.8467,  10.7313,  -1.8676,  -11.4282,  -13.9225,  -8.1802,  2.6837,  -19.6797,
+  0.8368,  -1.761,  0.4628,  2.3612,  5.116,  7.7374,  9.4921,  4.3865,  6.1712,  5.6238,  6.3738,  5.3491,  2.7348,  5.4859,  4.6651,  -8.4273,  -10.9892,  -8.675,  -10.7619,  -26.1822,
+  12.9582,  16.0251,  19.0637,  18.9347,  12.6765,  7.8161,  3.8112,  0.9397,  6.1611,  7.4639,  -2.5194,  -7.1391,  -10.2242,  -10.1934,  -4.1747,  -5.7525,  -14.4868,  -8.2946,  -13.9643,  -29.1013,
+  29.3165,  26.9707,  19.9517,  12.4469,  7.3647,  2.8794,  1.4068,  -2.4963,  -5.4012,  -4.1083,  -5.2153,  -6.4891,  -5.9548,  -6.4872,  -6.651,  -6.7351,  -9.9422,  -8.4833,  -11.8558,  -20.5171,
+  7.6646,  7.8496,  5.346,  3.4574,  6.3183,  1.1408,  3.1494,  5.1045,  0.2373,  1.0847,  -0.432,  -0.3662,  -0.3503,  -0.5473,  -8.1949,  -0.9695,  -1.7599,  -3.3828,  -3.0248,  -22.3253,
+  7.0587,  8.6157,  9.7452,  14.4294,  20.8498,  17.0788,  7.0614,  2.4228,  -0.5017,  -1.0215,  3.1054,  5.3564,  -3.4904,  -7.3987,  -7.4398,  -7.0656,  -8.8032,  -12.863,  -18.8666,  -28.2731,
+  5.767,  -2.6937,  9.6459,  -0.7839,  10.7523,  2.796,  -2.6113,  -3.2915,  -6.2928,  -7.6167,  -12.6729,  -5.4796,  5.0447,  13.7582,  10.305,  4.5191,  -1.3433,  5.4917,  -1.7375,  -23.5567,
+  -11.2311,  -7.9712,  -5.4028,  -3.3542,  -3.1975,  -4.2245,  -3.9952,  -5.3576,  -5.3493,  -4.8108,  -5.4962,  -2.9288,  2.5785,  4.7736,  13.8058,  17.8731,  9.8332,  14.95,  11.022,  -11.5171,
+  2.8142,  1.3603,  4.2714,  4.8975,  4.3374,  -3.4231,  3.1881,  5.0714,  3.9705,  6.2234,  3.7268,  5.279,  1.3825,  -7.6582,  -2.9268,  2.0075,  -4.057,  -5.6086,  1.2855,  -26.1418,
+  4.9776,  6.4457,  7.7463,  9.3687,  9.5559,  9.1954,  6.3666,  4.9237,  2.1719,  1.7788,  1.4634,  -0.3859,  -6.1409,  -5.3778,  -2.6336,  -2.5068,  -8.3667,  -7.0441,  -11.2867,  -20.2514,
+  10.0472,  11.9967,  16.4907,  19.9334,  16.2325,  9.2915,  4.313,  0.7097,  -4.0959,  -8.1186,  -10.5064,  -10.3134,  -5.2102,  1.0801,  -1.5982,  -3.8949,  1.2501,  -7.5248,  -12.9333,  -27.1495,
+  17.0433,  19.1713,  22.6813,  17.1064,  8.7516,  4.3917,  -0.7236,  -5.3026,  -7.9288,  -8.3773,  -7.4784,  -3.7859,  -2.5186,  0.02,  -1.5465,  0.1954,  -10.783,  -12.0301,  -3.0579,  -25.8283,
+  18.6591,  22.3501,  23.5831,  19.0252,  13.9063,  13.3289,  9.0463,  -3.2346,  1.2718,  1.4619,  -4.3706,  -7.4089,  -10.771,  -11.8151,  -0.8947,  -8.7094,  -22.3259,  -8.0672,  -18.5235,  -26.5118,
+  3.2886,  3.8514,  1.5062,  4.9096,  3.9001,  3.8964,  -0.6349,  -1.5534,  -1.3119,  -2.313,  -1.8455,  -3.5666,  -2.6094,  3.4411,  -1.0089,  -3.0556,  4.525,  3.3979,  1.1349,  -15.952,
+  -5.6652,  -3.8931,  -1.8885,  1.6299,  2.3371,  2.0746,  2.1285,  0.4372,  0.0031,  4.2521,  5.201,  3.3227,  2.8933,  1.9467,  2.1449,  0.9405,  2.168,  2.3807,  -1.3113,  -21.1022,
+  21.727,  24.2953,  23.2112,  13.4917,  7.3423,  1.4843,  -3.1924,  -4.8355,  -10.3896,  -11.396,  -12.8133,  -11.6304,  -9.9774,  -2.6034,  3.7943,  3.526,  -4.2988,  -6.0579,  0.3494,  -22.0269,
+  7.1102,  6.3521,  11.665,  18.7864,  16.7459,  8.3216,  5.8454,  4.3436,  9.4868,  7.7601,  -3.1382,  -10.3196,  -14.1642,  -15.1634,  -11.6972,  -1.82,  -7.1959,  -8.5258,  -1.8553,  -22.5374,
+  14.2212,  17.8028,  21.4842,  24.9383,  24.9854,  22.3982,  21.377,  20.9687,  13.4315,  0.0683,  -9.1695,  -13.1215,  -13.8982,  -14.9798,  -18.1636,  -20.5802,  -22.0396,  -23.026,  -22.3178,  -24.3795,
+  8.9039,  9.7955,  9.3225,  11.7206,  17.8844,  21.1802,  19.2262,  17.3421,  13.9029,  7.386,  -2.6995,  -8.3297,  -10.1319,  -8.7756,  -6.059,  -8.7597,  -15.4747,  -24.0243,  -25.5723,  -26.8375,
+  3.8554,  4.2234,  6.2441,  12.5445,  18.1461,  14.0699,  5.9992,  2.722,  1.0526,  2.1813,  9.5825,  3.3502,  -4.3618,  -5.0291,  0.561,  -10.3142,  -15.3449,  -12.7063,  -7.6401,  -29.1358,
+  -8.9085,  -6.1917,  -3.8341,  0.0473,  -0.3559,  -1.0455,  0.4343,  0.7424,  0.1788,  -2.4081,  -1.5815,  0.7755,  2.7896,  -0.3538,  0.5914,  4.753,  5.3039,  5.5717,  8.461,  -4.9697,
+  6.0177,  9.1902,  12.54,  17.665,  18.0833,  11.1113,  3.6376,  -0.9348,  -2.434,  -3.3221,  -2.487,  5.475,  6.1443,  -3.6923,  -2.5169,  -0.6902,  -11.0083,  -16.8129,  -17.3554,  -28.6106,
+  12.6629,  16.5188,  17.012,  11.3763,  2.7817,  -0.7077,  -5.5288,  -8.1972,  -9.1883,  -10.5072,  -9.3239,  -6.2042,  2.0877,  8.3448,  2.7802,  8.4635,  -5.0126,  -9.023,  -5.59,  -12.7449,
+  26.6077,  25.1133,  19.7421,  13.7493,  7.5294,  4.8418,  5.8235,  5.9404,  3.3399,  4.8147,  -1.6758,  -4.4299,  -7.1722,  -6.547,  -9.6023,  -9.9251,  -17.0327,  -19.5694,  -18.7525,  -22.7953,
+  9.3391,  15.4719,  19.7226,  13.6838,  5.7655,  2.9423,  -0.2309,  -3.0447,  -5.0071,  -3.643,  3.6089,  8.1171,  -1.0555,  -2.536,  2.0952,  -6.4482,  -11.0547,  -9.9411,  -11.5931,  -26.1921,
+  6.7164,  12.9088,  8.1465,  2.9974,  -1.5306,  3.7966,  4.6355,  0.1956,  -4.4054,  2.5643,  -3.5126,  -0.4027,  0.5107,  -1.6406,  0.9829,  -5.6846,  -0.0083,  -4.8894,  -3.3272,  -18.0535,
+  1.8584,  3.5453,  10.7864,  10.3313,  8.8364,  11.3153,  12.655,  8.0839,  10.2072,  14.1247,  0.1105,  4.9955,  5.9811,  7.9709,  7.5141,  -6.0319,  -21.0185,  -23.4977,  -32.6987,  -35.0693,
+  13.1044,  15.4062,  17.5958,  18.0756,  11.3524,  4.367,  2.6428,  0.8781,  0.0399,  6.6751,  8.2361,  -2.6757,  -10.1776,  -9.8299,  -3.1506,  -9.5151,  -14.3971,  -6.2859,  -13.5883,  -28.7532,
+  0.0688,  2.2921,  6.5965,  8.3598,  8.2327,  8.6486,  7.1471,  7.1631,  4.4823,  3.4067,  11.3001,  9.5567,  0.6574,  -2.5849,  -6.7404,  -8.6614,  -8.6399,  -12.0189,  -13.1958,  -26.0705,
+  9.5134,  11.1944,  14.6379,  21.3303,  20.9351,  12.8622,  5.9234,  3.0673,  0.5662,  2.8569,  7.4992,  -0.6339,  -9.8527,  -12.4761,  -11.2573,  -4.7464,  -13.594,  -18.0638,  -14.8928,  -24.8691,
+  5.5904,  5.1588,  4.7053,  4.3271,  5.8271,  9.5093,  8.411,  1.6453,  -2.2667,  -2.6767,  -1.4248,  -1.126,  2.4114,  -1.8009,  -4.819,  -8.2201,  -2.9355,  -0.2567,  -0.3488,  -21.7105,
+  0.4175,  1.2148,  5.1829,  9.3743,  9.7458,  5.9476,  5.0377,  2.5369,  -2.7391,  -8.896,  -11.0818,  -7.065,  -7.4393,  -1.4335,  10.1963,  9.6385,  5.0133,  -4.2894,  -3.8725,  -17.489,
+  8.8274,  9.1037,  13.6965,  18.9331,  20.496,  15.7102,  9.1227,  5.5813,  1.7546,  1.3849,  6.9672,  6.4807,  5.2247,  4.2668,  -9.8256,  -18.2374,  -24.2455,  -24.1902,  -22.7864,  -28.2649,
+  -10.4296,  -11.2348,  -7.6061,  -8.6646,  -7.9499,  -6.125,  -4.3918,  -6.8877,  -5.4461,  -2.2579,  -1.3507,  2.298,  4.8244,  12.7426,  12.4434,  14.4927,  14.8125,  12.9871,  9.6224,  -11.879,
+  8.889,  12.0408,  17.2338,  23.3492,  22.1801,  17.325,  16.4611,  18.6109,  12.0359,  -2.1102,  -7.5218,  -11.7288,  -11.4854,  -7.679,  -11.7033,  -21.2349,  -23.6258,  -19.3358,  -7.8566,  -23.8442,
+  -7.7648,  -7.6325,  -5.9874,  -5.7763,  -5.5038,  -4.9788,  -3.5524,  -3.9264,  -4.7269,  -2.6727,  -1.6911,  -0.4884,  1.8633,  1.5449,  3.1375,  9.0909,  11.6855,  13.422,  16.9117,  -2.9544,
+  17.5979,  21.004,  20.369,  15.7264,  13.3239,  13.0722,  13.4678,  1.7577,  -6.0904,  -6.9925,  -8.3415,  -10.6335,  -9.5482,  -1.5234,  3.987,  -6.9271,  -17.4878,  -18.4739,  -8.9267,  -25.3608,
+  6.1805,  4.1462,  3.501,  2.723,  3.9708,  8.1302,  9.491,  3.6927,  2.979,  2.0598,  -0.61,  -1.6298,  -2.5238,  -2.5441,  -3.9959,  -2.7189,  -3.9403,  -3.9477,  -4.9568,  -20.0067,
+  7.7322,  4.4707,  5.232,  7.8782,  9.1005,  5.4418,  6.0577,  3.7093,  0.1939,  -0.2785,  1.1984,  -2.6011,  0.6595,  2.7395,  -0.9452,  -4.5096,  -8.4529,  -6.4501,  -6.8768,  -24.2995,
+  -6.4169,  -3.8203,  -3.3676,  -1.3384,  0.0068,  -0.0917,  -0.654,  -1.1092,  -2.2062,  -2.8976,  -3.0409,  -2.6706,  2.975,  6.3064,  7.4779,  12.0806,  5.7715,  5.5715,  0.9432,  -13.5194,
+  7.6067,  9.3813,  13.4849,  19.9139,  22.7781,  18.435,  15.914,  18.9134,  10.1002,  -4.3291,  -8.2178,  -13.6741,  -15.704,  -16.5313,  -14.1193,  -3.7115,  -13.7922,  -12.8183,  -7.7992,  -25.8309,
+  4.7167,  3.8923,  5.7519,  8.0369,  12.8563,  16.738,  15.0698,  9.7568,  7.4623,  7.4165,  7.755,  1.1797,  -6.3964,  -6.5897,  -1.5093,  -9.7231,  -17.0341,  -15.7607,  -12.6623,  -30.9568,
+  9.6098,  13.4286,  18.728,  18.1791,  9.8536,  3.5779,  1.4841,  0.4639,  -0.5329,  2.6536,  9.8742,  -3.2808,  -8.9269,  -11.0817,  -6.3122,  -2.5681,  -15.3236,  -12.3977,  -1.9946,  -25.4341,
+  3.899,  7.6431,  13.4623,  16.8504,  10.0821,  3.4259,  -0.1709,  -4.7791,  -8.1809,  -9.2214,  -8.3021,  -5.9798,  2.0125,  6.9915,  1.4712,  6.5493,  -3.7836,  -4.9571,  1.3613,  -28.3737,
+  13.9079,  16.7984,  20.6342,  24.6533,  24.3507,  19.3643,  17.9172,  18.392,  11.702,  0.001,  -10.1043,  -14.9084,  -18.2285,  -20.4094,  -21.5267,  -19.7383,  -13.5385,  -9.5045,  -16.6159,  -23.1465,
+  7.1797,  11.3922,  15.749,  19.3949,  17.3819,  10.7478,  7.3006,  6.1472,  9.1598,  11.0073,  4.7816,  -2.4892,  -3.7349,  -3.7521,  -1.7971,  -9.8976,  -22.2914,  -25.755,  -23.0236,  -27.501,
+  5.66,  8.46,  10.4652,  12.1954,  14.9914,  18.5645,  17.0459,  10.3163,  4.813,  2.322,  0.5889,  4.1108,  1.2082,  -9.395,  -13.7061,  -13.109,  -10.106,  -11.3113,  -21.8744,  -31.2396,
+  -1.8886,  -0.7563,  0.4909,  4.9127,  6.9239,  5.1456,  6.2254,  6.4299,  5.1768,  9.199,  13.2223,  5.4194,  -3.0538,  -4.7242,  -5.1855,  -3.7939,  -7.3421,  -6.1816,  -4.3871,  -25.8328,
+  11.3455,  9.9507,  8.1659,  6.0877,  1.4526,  0.9704,  4.7975,  4.0208,  -0.5941,  2.5357,  1.534,  -4.3306,  -1.6103,  -4.4373,  -0.0323,  -2.6725,  -2.0195,  -3.5278,  -6.3697,  -25.2666,
+  -0.8009,  5.6194,  7.0974,  6.1331,  7.2063,  7.4038,  4.5741,  8.4379,  4.2968,  7.9137,  13.0725,  2.3362,  0.6963,  -2.4917,  -4.9374,  -7.2728,  -8.216,  -9.6329,  -14.4558,  -26.98,
+  9.4449,  12.499,  15.8206,  17.3018,  10.9373,  5.5366,  0.8716,  -1.2105,  -2.477,  -3.4484,  1.0611,  6.1591,  -1.7466,  -7.5929,  -6.9295,  -2.1338,  -8.9361,  -10.3674,  -6.3554,  -28.4344,
+  11.5326,  10.9047,  16.3163,  21.0845,  11.9757,  7.0511,  0.8356,  -4.987,  -6.945,  -9.2309,  -9.7748,  -8.2038,  -2.2957,  5.5139,  -5.4119,  -2.741,  2.4166,  -7.4497,  -6.0628,  -24.5286,
+  9.3064,  9.3678,  11.2235,  13.9991,  14.4345,  11.1982,  6.3282,  1.4131,  -2.6884,  -7.1825,  -11.0075,  -12.3749,  -9.2573,  -6.0414,  2.3206,  4.6097,  3.567,  -3.2208,  -9.5445,  -26.4507,
+  -6.7163,  -6.0323,  -3.7943,  0.882,  3.6629,  4.3198,  4.7402,  4.0799,  4.8854,  5.8718,  8.3927,  9.6825,  10.5717,  3.8917,  0.9125,  -1.2807,  -3.7018,  -5.757,  -8.2525,  -26.3582,
+  10.2748,  11.6455,  16.3809,  20.149,  18.2488,  12.7899,  10.3972,  8.0106,  -0.6794,  -6.4024,  -9.7054,  -13.5667,  -14.6497,  -16.1902,  -6.9531,  0.2117,  -0.7067,  -1.2331,  -10.6728,  -27.3488,
+  13.3782,  16.35,  15.3612,  8.9247,  3.489,  -0.7729,  -2.6106,  -7.5432,  -8.0129,  -7.614,  -7.8535,  -2.4356,  6.505,  -4.5887,  -3.2816,  5.8982,  -1.3889,  0.3111,  0.3606,  -24.4762,
+  10.0811,  14.1057,  20.3635,  24.0314,  20.369,  17.0236,  16.446,  19.2548,  6.0111,  -3.4365,  -9.9143,  -13.0905,  -15.015,  -11.4726,  -6.6405,  -10.0976,  -14.6658,  -19.9459,  -19.48,  -23.9274,
+  -7.1817,  -5.5458,  -1.6137,  0.8007,  1.9284,  2.5116,  0.3432,  3.3359,  0.2833,  -1.3305,  -2.496,  -1.6366,  -2.6968,  3.6695,  6.8225,  4.4926,  6.194,  6.7541,  2.2072,  -16.8418,
+  9.6326,  11.3478,  14.3982,  20.7665,  19.7772,  12.3406,  6.1933,  1.0438,  -1.1521,  -1.586,  1.844,  7.8419,  -1.5328,  -9.8703,  -10.1973,  -2.244,  -12.0413,  -18.5948,  -20.6014,  -27.366,
+  1.5056,  1.688,  4.2152,  9.5291,  17.0514,  16.2096,  8.5432,  4.2111,  4.4898,  11.7231,  5.577,  -4.8191,  -7.502,  -5.9733,  -0.7664,  -10.2798,  -14.8967,  -9.8638,  -3.1062,  -27.5357,
+  15.2115,  17.9992,  21.5012,  24.9136,  19.176,  15.8798,  16.4094,  17.804,  5.9025,  -3.3769,  -10.4408,  -15.3738,  -18.5882,  -19.7882,  -17.7007,  -14.2386,  -13.9566,  -13.8247,  -5.8162,  -21.6922,
+  12.1911,  17.2966,  17.4896,  10.6943,  3.5061,  -0.1018,  -2.5405,  -6.3143,  -7.6095,  -8.5828,  -7.4501,  -2.2275,  8.4004,  0.023,  -1.6734,  2.8727,  -8.2243,  -7.2548,  -0.595,  -19.8998,
+  -0.4264,  0.0708,  1.9133,  6.0904,  12.781,  17.8469,  12.0313,  4.9753,  4.279,  6.9401,  10.3052,  0.2003,  -6.7328,  -10.0168,  -10.0292,  -2.7869,  -5.6536,  -9.3242,  -6.0818,  -26.3818,
+  7.8387,  12.9821,  20.1116,  21.8527,  15.0291,  10.4182,  9.9996,  12.5177,  11.6815,  -0.1048,  -5.5624,  -6.4577,  -2.0918,  -6.3498,  -17.7376,  -20.9015,  -21.1073,  -13.6752,  -3.7477,  -24.6953,
+  18.0184,  21.7405,  20.202,  16.4376,  12.3859,  12.2417,  12.1975,  6.3324,  -4.4281,  -11.4734,  -5.9353,  -8.8421,  -10.328,  -4.7973,  3.4477,  1.4017,  -15.9637,  -17.1346,  -16.9459,  -28.5571,
+  8.9922,  8.4069,  10.2569,  10.5303,  10.1285,  4.9362,  1.8698,  -0.0537,  -5.3906,  -5.9983,  -4.6797,  1.6021,  -1.9697,  -5.3874,  -2.3336,  -0.9265,  -2.7071,  -2.3523,  -3.3933,  -21.5307,
+  0.1643,  -2.21,  -0.9888,  -3.4801,  -0.5275,  -1.468,  -0.5683,  -1.5514,  -0.4216,  0.5034,  -0.8521,  -2.7835,  0.5014,  -1.2182,  -0.7495,  5.2974,  5.8643,  8.2766,  6.0259,  -9.8143,
+  7.672,  8.0788,  9.1059,  14.2217,  21.6149,  24.6272,  15.4198,  12.7487,  14.5686,  14.3925,  0.6524,  -7.7122,  -12.314,  -13.4374,  -8.0366,  -14.9387,  -21.7305,  -22.0625,  -19.3233,  -23.5474,
+  2.2815,  1.7578,  -0.6674,  1.7705,  0.4755,  0.4978,  -1.3799,  -2.1107,  -2.6075,  -3.5652,  -2.8715,  -6.8295,  -1.7109,  2.8096,  -0.7449,  2.5543,  8.6739,  -0.5359,  6.8846,  -4.6821,
+  18.2027,  16.9209,  12.1191,  7.6862,  3.0545,  0.5751,  -1.6156,  -1.2378,  -3.1289,  -4.2377,  -5.6464,  -5.0994,  -5.0515,  -1.2417,  1.1802,  1.1938,  0.3821,  -6.3202,  -6.4152,  -21.3203,
+  3.5023,  4.9407,  6.5095,  8.9494,  13.2647,  15.1725,  11.9431,  6.2423,  1.1652,  -1.6313,  -2.9929,  -1.9072,  3.4422,  2.8306,  -3.2309,  -5.3351,  -2.3238,  -10.7536,  -17.8375,  -31.9502,
+  4.7778,  10.318,  13.9538,  16.0868,  9.138,  2.9991,  -0.6627,  -4.2067,  -5.6625,  -4.9839,  -1.2287,  7.7334,  9.3244,  7.4153,  -4.1228,  -11.6166,  -8.7569,  -5.6012,  -5.8002,  -29.1044,
+  -3.8341,  -1.3838,  -0.9472,  -0.4209,  1.7906,  4.2155,  2.2324,  4.3091,  1.1357,  8.4456,  9.7973,  6.3722,  2.6068,  0.3293,  0.1016,  -0.3203,  -4.2313,  -3.6986,  -3.9405,  -22.5593,
+  7.9933,  10.952,  14.6109,  19.7867,  15.1983,  6.5296,  4.9056,  0.7415,  -0.5271,  -0.1092,  6.9036,  12.3792,  7.7901,  2.0866,  -9.1117,  -12.3605,  -5.7793,  -23.1437,  -29.0076,  -29.8384,
+  25.899,  23.1895,  19.6721,  15.4616,  9.3167,  5.4831,  6.1546,  7.4477,  4.2279,  -1.3757,  -8.0309,  -11.4646,  -10.4795,  -7.5543,  -4.2227,  -6.0439,  -16.4547,  -16.3865,  -13.0397,  -21.7998,
+  5.9702,  6.6918,  8.5551,  14.7594,  15.5278,  10.2403,  6.0423,  1.7099,  -0.1415,  0.4245,  5.8906,  10.2752,  2.9571,  1.0304,  -7.5844,  -15.493,  -16.0321,  -8.3602,  -12.0263,  -30.437,
+  0.2377,  1.249,  0.9118,  1.8024,  3.7548,  4.8963,  5.1515,  4.2684,  0.3786,  0.5058,  0.4839,  -0.9914,  1.4073,  1.1727,  -2.9065,  -4.4307,  -6.9456,  -0.2385,  0.3969,  -11.1044,
+  4.9017,  3.2442,  -1.2482,  -1.2472,  -2.0773,  -5.4371,  0.3708,  4.1825,  12.1289,  1.295,  -2.3136,  -3.1723,  -0.4429,  -1.6571,  -9.7455,  6.5626,  13.4075,  7.0987,  -2.0865,  -23.7642,
+  26.5958,  8.4474,  11.9082,  11.6976,  1.401,  -0.25,  3.9848,  3.6429,  -6.0468,  2.5341,  -5.2699,  -11.5085,  3.8103,  -6.3108,  -2.4679,  2.153,  -6.3876,  -7.178,  -8.406,  -22.3496,
+  2.2962,  0.8041,  0.8352,  6.615,  14.5461,  15.0856,  3.2964,  0.5549,  -1.6557,  -2.0236,  2.8955,  7.5016,  -1.2031,  -5.6899,  -4.7833,  1.2942,  -7.3403,  -8.3771,  -4.0417,  -20.61,
+  -3.152,  -0.4969,  6.6485,  7.8768,  5.5605,  6.5283,  5.6337,  4.1543,  13.9779,  2.7762,  6.1398,  -3.707,  -1.7982,  -2.8944,  -6.0041,  -6.5265,  -11.4873,  -1.5122,  6.058,  -27.7754,
+  -8.002,  -4.6131,  -0.7821,  3.316,  4.4465,  4.7754,  2.8155,  1.0612,  4.806,  6.0492,  5.939,  3.1446,  2.8568,  -0.6657,  -2.6961,  -2.15,  -0.9756,  -0.2816,  -1.9847,  -17.0594,
+  12.4378,  17.8157,  22.2857,  21.4926,  15.3987,  11.6565,  8.461,  -5.9608,  -14.7466,  -15.8101,  -21.885,  -17.3295,  -13.0545,  -3.3503,  5.7314,  1.5346,  1.1396,  -7.594,  -1.8366,  -16.3862,
+  0.8964,  0.1937,  0.1104,  1.6479,  5.6517,  12.189,  10.2771,  4.4234,  1.0502,  -0.5311,  1.2594,  6.8796,  5.2931,  -3.9156,  -6.05,  -0.9098,  -4.2858,  -6.9837,  -7.0958,  -20.1002,
+  19.8439,  13.428,  9.6622,  10.665,  8.095,  5.5066,  1.7572,  -1.0429,  -0.8012,  -2.8142,  -0.4934,  1.3117,  0.5243,  -6.173,  -8.129,  -6.3324,  -1.5063,  -10.0417,  -9.139,  -24.3207,
+  -2.7279,  -1.7097,  -1.1534,  1.6639,  5.7537,  6.7942,  10.6044,  12.5105,  10.6069,  10.0936,  6.6639,  5.768,  -0.0784,  -3.9348,  -2.0808,  -2.5423,  -7.773,  -12.2311,  -11.4054,  -24.8224,
+  10.1275,  12.1619,  16.2723,  20.8127,  20.974,  14.8019,  10.1842,  6.5306,  4.4543,  7.4531,  12.2713,  6.962,  6.8204,  -5.0668,  -18.1362,  -24.0479,  -25.9037,  -25.4208,  -24.389,  -26.8618,
+  -9.9466,  -6.5695,  -9.8093,  -1.7391,  0.058,  3.2073,  7.0375,  2.3619,  -1.1764,  -5.8692,  0.305,  -4.2033,  11.2777,  -0.3904,  7.8268,  9.8649,  4.7504,  6.9825,  7.6743,  -21.6424,
+  14.0137,  16.9699,  19.0697,  15.0058,  7.0268,  5.9083,  2.9474,  2.1595,  3.8159,  7.2602,  11.3975,  7.5965,  1.66,  -6.7074,  -13.8401,  -15.7435,  -16.6488,  -16.4066,  -16.4466,  -29.0384,
+  6.2399,  3.2858,  -0.2213,  -1.4923,  1.3132,  3.933,  3.5221,  2.8631,  1.3615,  -0.079,  -1.0125,  -1.0737,  -0.3033,  -0.848,  -0.4749,  -1.1495,  0.1031,  -0.209,  -1.3002,  -14.458,
+  14.6593,  20.5101,  23.6344,  20.8409,  12.562,  6.6891,  3.7103,  -0.8534,  -3.6042,  -5.9363,  -7.011,  -3.7764,  1.6775,  -5.6072,  -12.2281,  -10.8044,  -4.3275,  -11.1148,  -14.7836,  -24.2367,
+  17.5445,  22.4817,  15.1353,  12.588,  5.1049,  1.9643,  5.3928,  -3.5987,  -0.475,  11.7373,  12.9388,  -3.8264,  -3.5752,  -8.3127,  9.4226,  -10.0441,  -20.2747,  -19.0638,  -21.801,  -23.3385,
+  11.5639,  14.1176,  19.178,  24.7909,  18.2344,  11.0457,  8.2594,  6.6617,  7.5852,  14.184,  12.1883,  7.8148,  -0.4947,  -16.4472,  -21.5615,  -22.7378,  -21.8493,  -21.9703,  -24.981,  -25.582,
+  7.3833,  6.5793,  5.7205,  10.2722,  16.6567,  15.1599,  9.5922,  5.5668,  5.0234,  9.3817,  5.3741,  -5.1082,  -9.8091,  -12.3432,  -12.5495,  -6.2366,  -5.9929,  -8.3697,  -6.8581,  -29.4426,
+  0.3726,  -5.6285,  -3.2253,  2.1557,  3.8332,  12.1538,  14.6059,  12.3634,  15.7294,  17.0679,  4.8054,  -1.6834,  -7.5585,  -11.9417,  -12.8749,  -9.7037,  -1.2933,  -5.8852,  -6.0304,  -17.2623,
+  12.4589,  17.5375,  23.1698,  18.7129,  9.0574,  6.8369,  3.3366,  -0.7668,  -3.5028,  -5.8079,  -2.0422,  3.5413,  -5.492,  -15.4559,  -14.9601,  -7.186,  -2.1139,  -10.3945,  -4.5301,  -22.3991,
+  7.7831,  5.9803,  3.3957,  1.1363,  0.6624,  -0.3876,  -1.227,  0.535,  0.3563,  5.2276,  9.1991,  8.9238,  2.632,  -1.9335,  -4.212,  -2.5342,  -1.0999,  -4.9168,  -4.9485,  -24.572,
+  12.7865,  11.7808,  12.0132,  12.7418,  11.7725,  11.2618,  10.9064,  7.0094,  3.3808,  -2.3233,  -4.5714,  -6.7413,  -8.0255,  -8.7048,  -10.995,  -7.0616,  -9.371,  -7.6597,  -4.91,  -23.2897,
+  7.4583,  10.3954,  16.3813,  20.381,  16.5656,  9.1371,  4.5296,  4.0559,  6.8658,  9.8043,  0.1187,  -6.6202,  -8.4161,  -2.4957,  -9.4787,  -16.3418,  -17.6122,  -13.1639,  -7.5007,  -24.0638,
+  10.5778,  12.5102,  15.45,  16.251,  14.1076,  12.4513,  11.9259,  10.4537,  6.3771,  1.6824,  -3.8825,  -5.5239,  -8.8633,  -8.0708,  -4.646,  -3.2386,  -13.9943,  -17.4761,  -15.8823,  -30.2093,
+  16.545,  21.4563,  20.013,  10.542,  0.7521,  -0.1817,  -5.7313,  -0.269,  -4.1817,  -0.5968,  6.2079,  4.1626,  -0.4622,  5.1095,  -10.2058,  -16.0783,  -19.9597,  -11.663,  4.3789,  -19.838,
+  0.6538,  1.9228,  2.293,  5.2351,  12.5744,  11.0394,  7.485,  0.8228,  -3.4564,  -5.0324,  -2.9456,  4.4755,  9.605,  1.6136,  0.0025,  -0.9954,  -6.7769,  -7.886,  -2.933,  -27.6973,
+  14.1315,  17.7109,  22.9482,  25.5022,  19.8506,  12.4355,  10.8121,  14.0608,  12.2635,  -2.6541,  -11.3457,  -15.5204,  -18.073,  -18.739,  -15.772,  -7.2576,  -9.9721,  -9.7355,  -17.106,  -23.54,
+  -5.7314,  -4.059,  1.0581,  0.9805,  1.3616,  2.7093,  6.3692,  11.6381,  12.018,  9.1818,  6.8001,  1.9409,  3.0785,  -2.5335,  -5.799,  -0.6774,  0.8325,  -4.7436,  -7.1073,  -27.3175,
+  -1.064,  0.7851,  2.716,  6.1021,  12.1198,  15.4431,  10.3026,  4.0089,  1.9648,  -0.0384,  2.4993,  9.2599,  1.9572,  -4.2838,  -3.1953,  -1.1928,  -7.8283,  -8.5999,  -10.0789,  -30.8773,
+  -5.6296,  -4.3307,  -2.3209,  -0.8933,  0.2894,  -1.9304,  -2.0575,  -2.778,  -6.2185,  -5.9192,  -6.6197,  -5.5076,  1.7,  -2.2417,  6.734,  9.7221,  5.4135,  15.423,  16.2356,  -9.0706,
+  21.8983,  23.2393,  21.5176,  17.3026,  15.6381,  10.7095,  -4.6739,  -9.4131,  -7.3736,  -9.636,  -10.3893,  -7.6173,  -3.694,  2.4229,  12.3234,  -14.8401,  -14.2133,  -12.879,  -4.4302,  -25.8921,
+  11.8056,  15.656,  20.2939,  16.8416,  9.1858,  2.5617,  2.6711,  -1.0207,  -1.45,  -0.2437,  6.6714,  6.5193,  -0.4136,  -1.1308,  -3.7531,  -13.8441,  -14.3531,  -10.4897,  -18.0817,  -27.4259,
+  55.7273,  39.936,  26.2526,  15.0127,  6.4718,  0.7391,  -2.3157,  -3.1939,  -2.9475,  -3.3569,  -5.3235,  -7.9446,  -10.6626,  -13.1662,  -14.21,  -14.4691,  -14.4121,  -13.8376,  -15.6433,  -22.6564,
+  3.7665,  2.9173,  4.2496,  1.847,  7.9023,  14.8241,  11.0448,  3.454,  2.7173,  -3.8368,  2.5626,  4.5604,  2.9217,  -9.5401,  -8.3622,  -8.8234,  -1.4224,  -0.0449,  -2.7094,  -28.0285,
+  -9.3983,  -8.0419,  -4.4832,  1.9754,  -0.3749,  4.6985,  6.4445,  3.4462,  1.2139,  4.153,  -6.0488,  0.4383,  7.0647,  3.8491,  2.7818,  -2.689,  2.0052,  6.3893,  4.3086,  -17.7324,
+  10.6303,  13.7716,  17.1718,  20.1678,  12.2486,  3.36,  2.4058,  -2.5934,  -4.8765,  -6.0115,  -4.6562,  -0.7932,  8.0003,  -2.284,  -3.8243,  0.1863,  -9.1648,  -14.9839,  -14.094,  -24.6607,
+  16.6586,  21.6444,  20.8223,  12.8954,  8.1955,  4.1214,  1.5648,  -2.8573,  -5.5724,  -6.5555,  -5.8004,  -2.3591,  4.833,  -0.2831,  0.7092,  -9.8961,  -15.4807,  -12.0228,  -6.1807,  -24.4365,
+  6.2715,  7.1856,  9.0377,  12.3924,  19.0793,  22.2584,  18.7678,  12.6682,  9.6569,  13.2645,  2.9549,  -2.9501,  -4.4734,  -4.244,  -12.7065,  -19.5653,  -21.3156,  -21.7041,  -19.8037,  -26.7746,
+  6.6118,  7.9766,  9.5899,  16.7112,  22.8331,  15.9736,  8.1328,  4.9522,  3.0471,  7.2666,  11.8402,  -1.4154,  -4.2808,  -5.2523,  -8.9476,  -17.0691,  -18.3281,  -12.6216,  -21.0003,  -26.0198,
+  17.3127,  17.4868,  17.7344,  12.4834,  5.8856,  4.6009,  1.073,  -2.7678,  -2.0723,  -0.4628,  -3.7999,  -5.837,  -8.6148,  -7.6108,  -6.5104,  -2.5688,  -1.6184,  -6.1466,  -7.5013,  -21.0659,
+  3.4054,  5.0769,  7.0766,  9.8006,  20.025,  22.5645,  11.5478,  6.2329,  4.4723,  6.4844,  10.6573,  0.2331,  -6.2477,  -11.087,  -10.3507,  -4.2484,  -15.1989,  -19.0756,  -16.4193,  -24.9492,
+  4.7627,  -2.1833,  -2.2828,  -3.7716,  2.8453,  7.51,  11.3439,  6.188,  0.3611,  -1.2837,  -10.299,  -7.9318,  -4.0985,  1.3582,  6.4088,  6.3304,  9.4372,  -0.3781,  -7.0962,  -17.2205,
+  0.0639,  1.7461,  3.2578,  7.1373,  14.2936,  21.0383,  16.8137,  10.1108,  14.304,  14.1399,  0.3676,  -6.3231,  -10.5295,  -12.7919,  -9.1838,  -2.4821,  -12.1068,  -13.6518,  -9.174,  -27.0298,
+  6.2012,  6.2177,  8.6617,  15.7008,  20.0807,  16.3263,  9.7644,  7.667,  11.6809,  8.6315,  -2.6559,  -7.4948,  -10.0457,  -10.1131,  -6.9875,  -12.9972,  -15.776,  -10.0148,  -6.4425,  -28.4048,
+  8.4071,  5.8192,  3.5662,  1.9627,  2.4472,  1.8597,  -0.737,  2.3814,  0.1779,  1.4958,  2.9385,  -6.0143,  -2.3152,  0.3049,  -1.7145,  0.7158,  -1.3399,  -5.1439,  2.0438,  -16.8555,
+  7.4409,  3.3788,  6.5115,  14.5248,  13.0646,  4.0268,  -1.1894,  -5.0999,  -7.691,  -8.4282,  -7.9356,  -3.3516,  6.9774,  0.9806,  -1.3988,  5.5785,  -3.1694,  -5.2282,  1.6484,  -20.6401,
+  11.6728,  5.2904,  7.2713,  8.1521,  8.6202,  4.839,  1.9077,  -2.7604,  -4.5028,  -8.9428,  -12.4662,  -11.0383,  -4.7642,  4.2903,  3.3702,  1.0547,  5.8752,  0.7203,  -0.1952,  -18.3942,
+  1.7662,  2.1132,  0.6823,  0.5069,  -0.7694,  -0.573,  -0.6749,  0.4539,  -2.385,  -0.8937,  3.2905,  1.9366,  4.8907,  8.891,  3.4773,  1.6832,  -0.385,  -1.0325,  -5.4486,  -17.5299,
+  11.1327,  8.1369,  5.9398,  7.2387,  9.0755,  13.7563,  15.6715,  10.9671,  4.3603,  6.5521,  8.2784,  8.2998,  -3.5109,  -8.8874,  -13.5723,  -11.9565,  -11.2912,  -14.9059,  -15.3573,  -29.9274,
+  17.2359,  18.8517,  18.1626,  16.5245,  13.3466,  10.8703,  8.4673,  4.7337,  2.635,  0.0183,  1.1954,  4.7388,  -2.9359,  -6.0731,  -7.4347,  -16.3769,  -19.935,  -20.0072,  -15.2078,  -28.8095,
+  15.9881,  16.1253,  11.9372,  8.7157,  5.3883,  4.3873,  5.5095,  5.6589,  0.5361,  -1.1208,  -4.817,  -4.8077,  -4.2337,  -3.8897,  -5.7866,  -5.1486,  -6.6937,  -4.6271,  -8.1104,  -25.0113,
+  10.5287,  10.4645,  11.0189,  12.4921,  10.2092,  2.1803,  0.6775,  -1.9607,  -7.8737,  -8.5232,  -10.8456,  -10.0601,  -9.5234,  -5.7091,  4.1283,  1.9979,  4.9082,  2.3842,  -1.6831,  -14.8109,
+  6.8712,  7.1195,  7.8478,  9.0102,  7.5469,  4.9121,  6.0618,  3.0705,  0.6628,  1.7728,  2.714,  6.3541,  3.1029,  -4.2377,  -6.3687,  -2.2545,  -6.3865,  -11.4164,  -9.6711,  -26.7119,
+  16.6601,  22.046,  20.3084,  13.4923,  8.0021,  8.7024,  10.126,  10.4026,  4.1888,  -3.7328,  -6.171,  -10.8693,  -16.0494,  -7.8483,  0.2833,  3.3381,  -13.0116,  -16.9474,  -14.2501,  -28.6704,
+  -1.6472,  -1.5329,  -0.7265,  -0.859,  1.55,  3.3445,  6.06,  5.7678,  2.9402,  4.2316,  1.8384,  -2.4116,  1.7488,  -1.1846,  0.2843,  -0.4495,  1.5215,  -2.2191,  -1.2847,  -16.9723,
+  5.4499,  9.2168,  13.6525,  18.6245,  21.2266,  16.3225,  10.2029,  13.7648,  16.3433,  7.8345,  -0.8506,  -3.0654,  0.8282,  -4.7895,  -14.3191,  -13.6263,  -16.5382,  -25.7242,  -26.3799,  -28.1733,
+  5.4928,  7.273,  11.4735,  16.9546,  13.9651,  4.9178,  1.4991,  -1.5005,  -3.3689,  -4.2367,  1.4622,  8.4912,  0.6337,  -0.2593,  0.3732,  -7.8143,  -10.1871,  -7.5615,  -7.0778,  -30.5301,
+  6.6781,  5.8903,  6.7632,  9.181,  8.8397,  9.7239,  8.7155,  7.797,  6.3227,  3.4228,  0.2514,  0.111,  -1.6716,  -5.4364,  -5.9387,  -8.2352,  -7.5149,  -7.0855,  -8.8552,  -28.9591,
+  11.8209,  17.497,  19.5821,  14.6674,  8.781,  10.5929,  17.1599,  11.1304,  -1.5934,  -2.4291,  -7.104,  -7.2023,  -9.3009,  -11.7782,  -8.5498,  -11.3872,  -9.756,  -0.1211,  -12.0128,  -29.997,
+  10.1575,  12.1948,  14.9933,  16.4447,  14.1842,  8.2787,  4.1829,  1.5996,  -0.4007,  2.6686,  4.592,  3.807,  -0.5362,  -2.8498,  -6.0317,  -8.0974,  -11.2561,  -15.969,  -16.7096,  -31.2528,
+  17.3728,  16.5602,  12.158,  2.2953,  -0.7338,  -2.2088,  -3.006,  -3.495,  -5.7703,  -1.8968,  -4.1417,  -2.255,  -0.4691,  -0.6536,  -2.4783,  -1.3584,  1.113,  -1.5486,  -2.18,  -17.3041,
+  10.9509,  14.6912,  20.9171,  20.7445,  13.3882,  9.0276,  8.481,  10.448,  11.1634,  -1.3107,  -8.8976,  -12.455,  -14.1419,  -12.2168,  -8.1653,  -9.184,  -14.6536,  -10.7798,  -3.349,  -24.6582,
+  -4.2511,  -4.318,  -6.4235,  -4.0719,  -2.3887,  -3.1485,  -4.2032,  -3.5194,  -7.501,  -5.4107,  -2.3368,  0.6165,  -2.548,  -6.5746,  5.71,  1.8165,  14.8553,  24.383,  15.8024,  -6.4884,
+  6.8815,  10.8626,  15.3667,  14.4704,  2.5878,  0.6962,  -3.7687,  -7.2033,  -9.3334,  -10.5308,  -9.619,  -8.2135,  -3.3921,  8.1225,  8.7748,  9.4979,  -0.1825,  -3.9609,  2.5378,  -23.5939,
+  10.7457,  13.4613,  16.3838,  18.1633,  11.9764,  6.2322,  2.2046,  -1.6815,  -5.4025,  -5.3261,  -1.9194,  5.785,  7.0183,  8.8506,  -7.0398,  -15.809,  -17.0181,  -9.4482,  -9.5562,  -27.6203,
+  4.4895,  6.7459,  11.3127,  18.7251,  18.1351,  6.5502,  1.1677,  -1.0341,  -3.9953,  -2.3382,  3.5745,  11.8555,  2.9192,  6.0596,  -4.8984,  -13.0118,  -16.247,  -15.0252,  -10.6982,  -24.2871,
+  10.1449,  10.3471,  14.749,  16.1718,  16.9528,  11.3815,  6.8749,  1.4265,  -2.7864,  -6.1956,  -8.0139,  -7.8556,  -2.8591,  4.0596,  5.4548,  3.3633,  -10.2166,  -16.2406,  -18.8135,  -27.945,
+  9.5266,  9.8619,  11.6564,  16.1435,  22.5856,  19.0228,  9.5649,  5.1013,  3.9082,  6.9523,  9.4453,  -4.8784,  -10.6008,  -16.0258,  -16.6123,  -14.774,  -6.6639,  -13.8342,  -16.3927,  -23.9867,
+  -2.8166,  -0.2578,  2.8925,  4.4555,  5.6756,  4.6914,  3.4417,  3.4041,  1.889,  1.8575,  -0.5242,  1.9867,  0.9536,  -0.9744,  -1.401,  -2.1961,  -1.2827,  -2.3186,  -2.1481,  -17.3281,
+  6.5757,  10.4876,  15.8653,  20.5177,  18.3749,  8.4114,  4.7411,  0.5009,  -2.9659,  -4.1461,  -4.5681,  -0.6566,  5.8038,  -2.3737,  -8.5532,  -6.5787,  -2.8561,  -13.7548,  -17.8769,  -26.9485,
+  7.1295,  8.3469,  8.9916,  14.7649,  20.5,  15.5149,  7.3359,  0.6792,  -1.5195,  -5.0373,  0.9468,  7.0372,  -4.0339,  -9.7787,  -8.9444,  -0.8558,  -12.0386,  -13.0157,  -7.1764,  -28.8465,
+  -6.3643,  -3.56,  -0.9853,  1.3808,  3.5164,  4.4752,  4.2783,  4.1699,  0.4058,  -0.8097,  -0.9913,  3.1386,  9.3653,  -1.1057,  -1.2662,  0.7587,  1.7985,  -2.7481,  1.1071,  -16.5641,
+  10.8441,  6.1056,  4.5464,  11.5523,  11.5304,  4.8593,  1.2036,  0.6177,  -6.5224,  -11.5032,  -13.3278,  -7.1852,  -1.6717,  9.2735,  6.7578,  -0.905,  -7.2789,  -6.0827,  3.0089,  -15.8228,
+  2.43,  2.4475,  8.1825,  8.1925,  2.2974,  10.8311,  15.569,  1.4027,  0.329,  -0.4366,  6.3648,  1.0487,  -0.9166,  -8.1367,  -8.1915,  -9.569,  -3.4184,  0.0616,  -4.9205,  -23.5675,
+  18.5545,  22.239,  21.2685,  17.01,  9.6982,  4.732,  4.3296,  7.5541,  8.1889,  7.8498,  0.4258,  -3.7349,  -6.3446,  -8.3581,  -11.0931,  -16.2715,  -16.4055,  -15.8123,  -17.441,  -26.3892,
+  5.3049,  3.9686,  5.5462,  12.1792,  19.9309,  17.032,  8.3644,  7.8784,  10.6383,  15.3943,  3.6647,  -0.1421,  3.0499,  -3.2605,  -15.9284,  -20.0685,  -19.5084,  -15.1548,  -11.4151,  -27.474,
+  -4.1173,  -2.8993,  -1.1226,  2.7523,  4.1168,  4.2377,  1.6192,  1.4859,  2.7141,  0.481,  0.9555,  -0.9423,  1.2205,  0.597,  0.3948,  0.467,  2.1347,  1.5199,  1.6806,  -17.2954,
+  15.7137,  20.9924,  24.3419,  24.5468,  20.7453,  18.1011,  19.1224,  15.9122,  12.9399,  8.1629,  -8.2323,  -12.3399,  -17.0242,  -22.3729,  -23.1787,  -23.2286,  -17.6989,  -10.8077,  -20.3082,  -25.3873,
+  -1.2634,  1.8562,  5.1481,  8.605,  8.7868,  9.5351,  6.6634,  3.816,  -0.1296,  -4.656,  -0.5036,  -0.2003,  1.6621,  -1.6607,  -2.8913,  -4.8208,  0.3233,  -5.1066,  -6.1044,  -19.0592,
+  10.6986,  11.8307,  11.5659,  12.449,  11.188,  6.9008,  2.6629,  3.0301,  3.4569,  5.3227,  2.5092,  -1.0853,  -3.8118,  -7.084,  -4.9747,  -7.3629,  -11.0099,  -5.9887,  -11.0008,  -29.2965,
+  13.6712,  17.1821,  19.2431,  13.3261,  5.9589,  0.4984,  0.367,  -2.3834,  -3.2315,  -2.1198,  4.8356,  0.4745,  -8.1763,  -11.1278,  -9.8688,  -0.1733,  -8.1227,  -9.3563,  -5.3546,  -15.6426,
+  -5.7735,  -2.5076,  -1.5044,  -1.1663,  0.0004,  2.3285,  2.2748,  3.5509,  0.5101,  -3.3403,  0.8431,  1.7502,  3.2945,  -0.4888,  1.3903,  4.0779,  1.6571,  2.3564,  6.2297,  -15.4829,
+  9.1796,  11.0931,  14.7746,  19.7918,  17.0503,  10.0451,  7.8355,  5.3063,  5.9805,  11.7545,  10.2992,  6.2216,  2.6489,  -6.8542,  -15.2068,  -16.6927,  -14.099,  -23.4163,  -26.3767,  -29.3354,
+  4.4691,  6.369,  7.7808,  12.847,  20.5705,  17.7665,  9.4381,  6.2778,  2.4431,  5.0549,  9.9596,  3.2883,  -2.2059,  2.04,  -4.0438,  -15.0151,  -19.7303,  -18.2469,  -20.2388,  -28.8235,
+  25.3208,  24.3974,  22.6154,  19.5733,  14.8131,  10.5701,  9.4361,  4.3748,  -1.5593,  -4.3511,  -14.7283,  -17.6258,  -0.952,  -8.5196,  -7.3624,  -3.251,  -9.9332,  -17.3271,  -21.4343,  -24.057,
+  22.3042,  16.1278,  12.0077,  14.7975,  10.7206,  8.3648,  8.061,  10.1267,  7.5498,  1.8723,  -3.9201,  -8.2481,  -10.1623,  -11.376,  -12.7367,  -5.005,  -3.3744,  -11.9178,  -17.47,  -27.722,
+  4.0018,  3.5852,  3.3315,  5.3461,  4.3656,  2.8461,  -0.0206,  -2.5696,  0.1895,  5.1002,  3.3534,  0.2158,  1.3297,  -0.9671,  -0.5937,  -1.9855,  -1.7054,  -1.7064,  -4.2453,  -19.8713,
+  -0.182,  0.3377,  2.3741,  5.1705,  4.8793,  2.2995,  4.3309,  2.2662,  0.4173,  -0.8843,  6.0098,  9.0178,  2.964,  -0.8977,  -1.5385,  -6.1656,  -4.1289,  -4.7989,  -1.1105,  -20.3607,
+  7.6526,  7.4466,  4.8852,  0.6442,  1.5298,  0.3141,  2.6136,  0.1768,  0.3184,  1.5717,  0.2364,  -0.4716,  -4.0283,  -1.7854,  1.1771,  -1.1242,  0.5833,  -0.2901,  -4.6526,  -16.7979,
+  19.3739,  25.1966,  25.2676,  19.4367,  10.1976,  2.4144,  -1.1928,  -4.0638,  -8.7478,  -10.523,  -11.0799,  -12.5634,  -10.0392,  -5.3666,  3.7592,  3.344,  0.1212,  -8.8586,  -13.7562,  -22.9202,
+  9.6043,  10.541,  12.3377,  19.7574,  26.3167,  19.8022,  16.1636,  16.4176,  17.5852,  2.8061,  -5.6826,  -11.1198,  -15.0897,  -15.5002,  -11.1047,  -14.2676,  -20.4525,  -20.5783,  -15.3843,  -22.1521,
+  12.9015,  20.6704,  27.9257,  24.9274,  19.2594,  24.215,  19.1475,  0.5334,  -3.3152,  -12.4822,  -15.0498,  -16.9033,  -19.2802,  -17.1972,  -9.8015,  -9.8416,  -13.7988,  -8.2071,  -2.2124,  -21.4912,
+  14.4389,  13.4012,  16.1103,  14.9288,  9.7959,  11.0171,  12.0893,  -1.4171,  -9.8704,  -8.5713,  -15.4225,  -18.6377,  -16.5003,  -13.9403,  1.0172,  8.7826,  2.1557,  -0.7217,  -0.1613,  -18.4945,
+  3.2298,  2.2245,  4.4788,  6.2407,  6.6193,  4.0854,  3.5648,  2.2977,  2.4361,  0.5689,  -4.6553,  -1.2701,  -2.8888,  -2.1474,  -1.0212,  -1.5878,  -0.7381,  0.5436,  -4.6923,  -17.2887,
+  12.1886,  11.0008,  17.9358,  24.301,  22.2969,  15.0778,  12.8771,  17.0838,  11.2261,  -0.0847,  -7.9648,  -13.0993,  -17.1559,  -19.7583,  -18.6302,  -14.9903,  -5.4184,  -14.9564,  -12.137,  -19.7926,
+  18.1628,  19.7982,  21.7942,  23.1496,  22.2974,  18.3029,  13.8973,  12.5987,  14.0955,  8.3018,  -1.2018,  -2.7097,  -5.1243,  -15.5625,  -20.9814,  -25.9011,  -25.5502,  -25.1062,  -24.3739,  -25.8874,
+  5.12,  2.6682,  2.7787,  5.122,  7.7683,  7.6609,  0.3239,  -0.5597,  -2.1976,  -4.2025,  -2.3433,  5.4581,  3.3195,  -4.6819,  -7.7339,  -5.9433,  6.7709,  -3.0093,  -0.4617,  -15.857,
+  3.1474,  3.9068,  4.6743,  6.198,  3.9172,  5.5703,  3.756,  5.3815,  6.4792,  7.4263,  4.0188,  -0.9053,  -2.9276,  -4.264,  -3.8751,  -2.5664,  -3.8921,  -5.7279,  -7.3914,  -22.9261,
+  7.7606,  7.9634,  9.259,  13.4058,  20.913,  19.2571,  11.4285,  9.1142,  10.4227,  12.6605,  1.394,  -7.8667,  -12.9049,  -16.1586,  -15.3321,  -7.7158,  -10.1835,  -11.8246,  -14.2319,  -27.3607,
+  9.9378,  9.7046,  10.1765,  13.167,  9.5151,  2.2155,  -0.0456,  0.0357,  -0.3521,  -1.264,  0.0667,  3.9496,  -0.7853,  0.9935,  1.7327,  -2.1738,  -2.4763,  -8.9075,  -14.5354,  -30.9548,
+  9.4566,  14.4761,  17.5184,  16.5421,  10.8319,  4.8634,  3.7958,  1.0301,  -0.7413,  -4.7772,  0.1278,  10.6261,  1.7256,  -4.7562,  -1.8151,  -1.2979,  -10.9708,  -19.1139,  -21.0656,  -26.4558,
+  4.1609,  4.3674,  5.163,  10.4393,  19.9966,  22.0365,  15.0772,  16.7404,  13.2009,  0.0579,  -7.2967,  -13.1855,  -16.4671,  -16.2778,  -13.5417,  -3.6468,  -7.6575,  -10.0591,  -0.8708,  -22.2374,
+  9.2619,  9.285,  10.6963,  10.0411,  5.3819,  1.803,  1.0922,  -0.366,  -0.8976,  -3.181,  -0.6819,  -3.8642,  -8.4569,  -8.9974,  -5.5095,  -1.9498,  -5.7587,  -2.8793,  9.9987,  -15.0177,
+  16.0944,  15.0736,  17.429,  17.1266,  16.3425,  13.9152,  -0.3124,  -3.4633,  -3.3349,  -5.5676,  1.022,  7.3152,  5.0978,  0.8308,  -5.9027,  -14.3898,  -14.2461,  -12.232,  -23.5828,  -27.2154,
+  2.0137,  5.7764,  10.2219,  14.9245,  16.5703,  10.5235,  3.0729,  -1.4882,  -7.205,  -6.2506,  -5.1311,  1.5065,  6.9953,  -1.443,  1.824,  -1.5831,  -9.7701,  -7.7954,  -0.2269,  -32.5358,
+  0.8118,  3.1428,  4.1975,  8.8492,  17.1316,  16.9999,  8.6244,  -0.0326,  -4.953,  -5.2292,  -0.1353,  6.3691,  -2.1837,  -2.6835,  3.8299,  -6.3313,  -4.714,  -0.206,  -11.6261,  -31.8615,
+  16.0656,  15.8566,  16.266,  14.0919,  7.2745,  1.1478,  0.5592,  -3.1884,  -2.7528,  -3.9872,  -1.52,  -5.6031,  -7.1936,  -11.6082,  -9.9024,  -5.9648,  -1.2652,  -4.4434,  -0.5317,  -13.3008,
+  6.0546,  7.8172,  12.5175,  18.974,  18.6314,  12.5099,  8.6741,  7.3229,  9.6232,  16.1584,  9.3568,  6.3688,  5.3827,  -10.1648,  -19.1392,  -25.0842,  -25.6307,  -21.0082,  -12.2957,  -26.0685,
+  8.7645,  5.7385,  7.3877,  9.4659,  8.7034,  6.7927,  2.2815,  1.642,  0.5587,  -0.7987,  1.2054,  8.0228,  11.5479,  4.5805,  -6.4932,  -9.4841,  -11.6576,  -7.6077,  -9.5897,  -31.0604,
+  13.5337,  13.1762,  15.6646,  19.9549,  24.347,  21.3479,  19.5471,  19.3675,  13.3653,  -0.5856,  -8.6584,  -13.2572,  -16.9863,  -17.9847,  -20.7708,  -15.4798,  -11.0509,  -15.4702,  -16.1382,  -23.9221,
+  9.4656,  10.0639,  11.4433,  14.668,  18.7771,  15.2024,  9.3195,  5.137,  1.9578,  0.3561,  3.767,  8.6933,  1.32,  -4.9956,  -10.6736,  -14.332,  -17.7829,  -18.0592,  -14.314,  -30.0137,
+  1.5799,  4.3053,  2.3818,  2.891,  -1.2059,  -0.83,  -0.1903,  -0.1292,  1.0233,  3.9206,  3.9828,  2.2978,  3.232,  -2.5703,  -2.6923,  -1.3776,  2.9213,  0.1727,  -0.511,  -19.2019,
+  6.8519,  4.8647,  1.9844,  2.2401,  3.7555,  1.5005,  -1.3694,  0.5704,  2.1485,  0.76,  0.6917,  -1.0898,  1.8295,  -1.7615,  0.1607,  -2.4085,  0.4928,  -1.2003,  -0.2145,  -19.8066,
+  26.8652,  27.9313,  22.2964,  13.2728,  4.9234,  4.975,  10.5105,  12.7213,  4.9587,  -6.5278,  -2.0124,  -3.4059,  -5.9594,  -7.3378,  -10.2568,  -18.1183,  -18.7465,  -15.1523,  -18.6899,  -22.2476,
+  11.7015,  12.5524,  16.8036,  20.5917,  17.3325,  11.6535,  7.9132,  3.4464,  6.4909,  8.4604,  0.112,  -8.677,  -13.3036,  -17.0534,  -16.5775,  -11.3553,  -3.454,  -9.9071,  -10.954,  -25.776,
+  20.0026,  21.9415,  20.1743,  15.7692,  9.6829,  6.6171,  12.1877,  15.1379,  6.9729,  -2.6223,  -11.926,  -8.003,  -5.4775,  -7.9242,  -14.3282,  -6.4602,  -11.9823,  -18.5276,  -14.5214,  -26.7133,
+  8.4727,  10.313,  16.1554,  22.5237,  20.4885,  15.1245,  10.9192,  10.3785,  14.0959,  8.6752,  -2.6735,  -8.1503,  -8.9174,  -2.4684,  -9.1899,  -21.2524,  -22.7439,  -18.1241,  -17.6618,  -25.965,
+  16.4001,  11.079,  6.5408,  3.9922,  0.9638,  0.6155,  0.1321,  -0.0033,  -1.5205,  -0.5347,  0.0838,  -0.8675,  -0.2837,  -1.6297,  -1.6342,  -2.753,  -2.7291,  -3.0597,  -3.9086,  -20.8833,
+  12.8347,  13.993,  15.6832,  15.4917,  10.9362,  11.4157,  15.6476,  4.371,  -10.872,  4.3584,  -2.6363,  -7.3238,  -10.3423,  -4.3725,  0.4684,  7.2994,  -11.0045,  -18.8176,  -14.2499,  -32.8805,
+  12.3323,  15.8058,  21.8399,  24.3008,  14.4087,  10.993,  7.8357,  8.0265,  12.8222,  14.2335,  5.8155,  6.0731,  -6.0593,  -17.6762,  -22.1263,  -23.2555,  -24.2165,  -21.7123,  -15.9183,  -23.5226,
+  5.7344,  5.3389,  3.8374,  3.419,  2.8812,  1.7219,  0.1439,  1.858,  -0.5349,  2.0653,  -5.3722,  2.7017,  1.0724,  -0.8636,  -1.4371,  0.4192,  -0.6553,  -2.1126,  -0.737,  -19.4805,
+  8.7871,  8.8914,  10.508,  13.7939,  18.1053,  18.3809,  13.6037,  9.9123,  6.2489,  7.8891,  6.4768,  -2.8713,  -8.9109,  -11.1699,  -11.8847,  -5.8137,  -11.8112,  -19.3777,  -21.5409,  -29.2171,
+  21.2487,  22.5877,  21.7624,  19.0832,  14.4498,  8.3623,  6.4664,  3.1545,  -0.286,  -1.9696,  -3.9389,  -1.8288,  -3.7243,  -9.6176,  -13.7865,  -15.0846,  -11.3343,  -12.9399,  -16.9243,  -25.6805,
+  15.5067,  16.3749,  16.311,  12.8646,  5.4498,  2.4274,  -1.0299,  -3.27,  -3.2357,  -0.0252,  7.5399,  -0.6948,  -6.2588,  -9.1664,  -6.8883,  0.76,  -11.6902,  -9.982,  -1.1495,  -23.8436,
+  15.5548,  17.3265,  20.2482,  21.9118,  17.7825,  12.4436,  8.5947,  8.3626,  10.7582,  6.8704,  -2.615,  -7.1451,  -11.7102,  -15.2112,  -16.7335,  -10.8661,  -12.143,  -16.7183,  -19.7849,  -26.926,
+  9.7348,  18.6985,  22.2,  9.7733,  3.5414,  -0.989,  -5.4561,  -5.4928,  -8.476,  -6.8757,  -4.1569,  6.8951,  2.1633,  -1.2892,  3.0483,  -7.4717,  -12.0842,  -7.7317,  1.0735,  -17.105,
+  6.6628,  6.9628,  9.289,  7.3292,  2.0881,  -0.1054,  -1.5163,  -4.7058,  -4.4988,  -5.4883,  -6.5025,  -2.6194,  5.9468,  -1.1287,  -0.4851,  5.3144,  -1.644,  -1.6601,  4.2795,  -17.5182,
+  11.7595,  13.0074,  13.6551,  14.3417,  13.9024,  11.589,  9.9365,  4.195,  -1.2916,  -2.3847,  -1.5414,  -3.1381,  -5.4213,  -4.9864,  0.0096,  0.2286,  -7.594,  -13.3606,  -21.1287,  -31.778,
+  16.556,  21.1528,  18.2294,  14.8217,  11.7211,  5.8948,  0.1128,  -5.7142,  0.4819,  3.4296,  -7.6731,  -15.2596,  -14.091,  -4.345,  4.2359,  -1.261,  -8.7829,  -14.4366,  -8.1323,  -16.9402,
+  -9.6162,  -5.892,  -0.4336,  -0.0688,  3.9825,  0.71,  -1.9156,  -3.0982,  -4.8027,  -4.2612,  -2.6264,  1.0431,  5.5418,  11.1806,  9.5552,  5.0905,  3.5862,  4.3463,  5.867,  -18.1885,
+  9.2493,  12.521,  14.8487,  20.3042,  16.9267,  10.5281,  5.4085,  -1.4152,  -5.3054,  -5.325,  -4.1371,  2.4443,  0.8006,  -8.09,  -7.9314,  -5.9206,  -13.5877,  -13.0043,  -4.8031,  -23.5116,
+  5.9148,  6.0122,  7.7679,  11.9347,  14.3202,  11.188,  5.7941,  0.6362,  -0.9006,  -3.7616,  -1.0465,  6.3361,  0.5894,  -7.7629,  -9.2778,  -6.0898,  -0.474,  -7.4253,  -3.178,  -30.5771,
+  9.047,  12.9059,  18.1346,  24.2631,  23.6353,  19.2579,  20.8877,  17.0355,  3.1774,  -5.2773,  -10.0473,  -14.9178,  -17.5773,  -16.4551,  -11.9394,  -9.6664,  -11.9143,  -7.0063,  -19.2353,  -24.308,
+  11.6229,  13.7686,  16.3077,  18.973,  21.2077,  21.177,  18.6717,  15.526,  14.4577,  10.9286,  -2.0523,  -9.7658,  -14.147,  -18.3895,  -20.2191,  -19.9491,  -14.1791,  -17.4745,  -18.9708,  -27.4939,
+  -1.2854,  -2.7859,  2.0352,  3.8729,  2.5634,  1.1875,  2.9803,  3.4105,  0.6928,  -0.5396,  -6.4408,  -2.1739,  4.1284,  -0.7168,  -3.4324,  -5.3047,  2.106,  6.1169,  6.17,  -12.5844,
+  3.6719,  5.1933,  3.433,  2.0915,  1.709,  4.9193,  7.5225,  11.4575,  7.7921,  1.1072,  -1.3846,  0.672,  -0.8916,  -0.5196,  -2.8857,  -5.7085,  -3.7344,  -4.4707,  -6.4364,  -23.5377,
+  5.0076,  6.0603,  5.6858,  5.8716,  4.9796,  4.351,  3.2343,  -0.0278,  -1.6006,  -3.6879,  -3.6306,  -0.3994,  -2.7867,  -5.8602,  -4.3815,  -4.1661,  1.9375,  0.0251,  1.7605,  -12.3723,
+  1.5611,  2.5677,  6.9184,  12.7642,  12.9002,  7.6294,  1.5737,  -0.4407,  -4.6258,  -3.3019,  -0.3274,  9.4821,  8.3473,  7.1185,  0.9099,  -4.2945,  -2.0947,  -5.5952,  -16.6889,  -34.4035,
+  -10.077,  -9.2074,  -7.5499,  -5.3349,  -2.0639,  0.7289,  3.3239,  5.0911,  7.8838,  10.9963,  10.2149,  9.1756,  7.3923,  3.8453,  -0.9308,  -1.4293,  -1.7749,  -2.4954,  -0.635,  -17.1538,
+  11.6964,  15.7897,  21.5631,  25.0743,  21.2867,  19.0704,  20.7015,  14.1826,  0.0839,  -7.4606,  -11.2687,  -14.0743,  -15.6804,  -14.7951,  -10.801,  -12.5161,  -17.6133,  -13.8075,  -7.4286,  -24.0031,
+  -6.9283,  -6.6188,  -5.8684,  -5.5056,  -3.6164,  -2.5751,  -3.3395,  -0.3521,  -3.7955,  -8.6077,  -6.1256,  -4.7755,  -5.6371,  1.9017,  5.4236,  6.9088,  17.0056,  9.6477,  17.8081,  5.05,
+  1.04,  4.3584,  5.7473,  5.9965,  7.1951,  11.1543,  16.3999,  17.9219,  13.7898,  8.5105,  6.6032,  8.3888,  3.1208,  -8.4853,  -12.1692,  -10.3091,  -9.406,  -16.3383,  -22.0676,  -31.451,
+  4.0785,  3.7601,  3.2477,  4.5535,  2.8617,  2.8959,  4.0341,  3.3572,  -6.7255,  5.4042,  2.4187,  1.223,  0.1581,  -3.0654,  -1.9472,  0.8423,  -1.1312,  1.2092,  -3.2861,  -23.8888,
+  7.3239,  6.915,  9.3764,  18.0744,  16.9415,  9.605,  5.2932,  1.9763,  2.0297,  6.284,  11.8379,  10.9565,  8.5711,  -5.0433,  -15.8094,  -21.0356,  -22.5868,  -18.9436,  -8.4281,  -23.3379,
+  -1.7885,  -4.8321,  -3.3241,  0.9574,  -0.7694,  -4.0018,  -4.5674,  -4.526,  -2.6221,  4.0186,  7.6808,  10.9687,  1.1618,  6.5552,  7.2914,  5.9801,  0.8194,  -0.4241,  1.0077,  -19.5855,
+  2.5382,  2.7665,  6.6332,  9.6977,  12.0223,  5.6888,  5.2502,  -0.0648,  0.179,  1.7261,  3.6718,  4.6019,  -4.2546,  -5.2838,  -8.6175,  -3.503,  -2.89,  -5.1451,  -3.1562,  -21.8607,
+  -1.7959,  -1.641,  -1.3048,  -1.9856,  -1.1093,  -0.5878,  -1.7759,  -0.7425,  -2.7139,  -3.3222,  -3.9402,  -1.9787,  -4.1788,  -1.9573,  -0.0518,  0.6181,  5.7386,  8.4544,  14.2974,  -0.0227,
+  1.9227,  3.4879,  4.9261,  5.1627,  4.2257,  4.6417,  3.0455,  -0.455,  -1.933,  -4.6665,  -6.5225,  -3.7829,  -5.2713,  -1.4162,  3.7054,  5.6573,  7.046,  2.7847,  -1.9201,  -20.6381,
+  5.4951,  4.1184,  5.0794,  4.1307,  2.3794,  0.0327,  -0.8237,  -1.5895,  -3.7505,  -6.6385,  -6.0766,  -2.2466,  -0.408,  -4.9327,  -5.84,  -1.6035,  0.3752,  6.5602,  12.3259,  -6.5875,
+  6.8048,  2.6542,  8.2117,  4.3594,  9.5824,  4.9978,  9.2805,  5.4616,  0.1801,  2.8218,  4.8979,  8.0336,  1.3602,  -0.8584,  3.0641,  -6.3167,  -11.4947,  -13.9096,  -9.3665,  -29.7643,
+  20.4394,  23.8508,  19.9523,  13.4804,  4.7063,  -0.881,  2.3157,  4.3508,  4.6054,  2.6117,  -2.816,  -5.7052,  -5.0189,  -10.4846,  -14.5942,  -12.8055,  -6.1098,  -12.0585,  -7.7055,  -18.1337,
+  9.9351,  14.3502,  19.553,  16.3727,  7.0796,  2.9949,  -1.1604,  -3.2246,  -3.9592,  -2.8637,  3.6007,  8.3194,  1.5624,  4.008,  -6.2282,  -13.296,  -15.2078,  -10.4525,  -5.9946,  -25.3891,
+  5.5354,  4.2644,  3.4234,  3.565,  3.9406,  1.8276,  0.2709,  0.3493,  -0.002,  -0.7304,  1.8692,  2.1692,  -1.3779,  -0.9234,  -5.0911,  0.1335,  -1.1518,  -0.8308,  -1.2357,  -16.0052,
+  14.718,  8.4248,  6.7389,  6.9731,  8.7963,  12.7964,  14.6589,  10.3137,  3.2909,  -3.7235,  -5.8542,  -6.9864,  -6.8348,  -4.2701,  -4.4326,  -5.4747,  0.7281,  -9.3904,  -11.2298,  -29.2424,
+  9.1842,  9.7851,  10.8472,  12.9244,  10.6955,  6.8423,  4.6037,  0.765,  -2.0301,  -2.7855,  1.3686,  5.5053,  -1.4464,  -8.6948,  -6.8949,  -4.4565,  -9.3587,  -11.9106,  -7.0277,  -17.9162,
+  9.5187,  11.0469,  10.8992,  10.5477,  12.4336,  17.931,  22.0092,  22.1029,  21.2249,  17.7472,  4.1368,  -3.9142,  -11.6583,  -18.8125,  -22.4708,  -24.5855,  -14.9292,  -12.6855,  -22.7109,  -27.8313,
+  12.0341,  16.6419,  15.8489,  10.0396,  3.3655,  -1.8695,  -5.2143,  -9.4106,  -10.9745,  -12.0991,  -12.045,  -11.1231,  -7.2635,  0.0306,  12.4231,  12.6061,  4.1888,  -1.9085,  0.6831,  -15.9537,
+  -1.3674,  -0.5228,  -4.0775,  -3.81,  -1.0761,  13.75,  19.2044,  15.7231,  9.5615,  7.9996,  6.5298,  3.6199,  0.5658,  -1.3324,  -7.5527,  -6.3571,  -7.0946,  -6.2162,  -8.1181,  -29.4293,
+  7.3145,  11.1318,  15.8219,  21.2414,  19.7326,  13.4391,  10.1286,  13.1458,  13.522,  4.5818,  -4.9865,  -10.4663,  -12.4137,  -8.4915,  -7.5278,  -14.5074,  -14.9519,  -10.6855,  -18.9716,  -27.0572,
+  -2.6938,  -1.0116,  0.5434,  -0.5197,  1.251,  2.781,  -3.1452,  2.3461,  1.3093,  1.0916,  0.2998,  1.6109,  9.4326,  9.1761,  -2.9635,  -1.3175,  -1.3459,  -2.3687,  -0.4622,  -14.0137,
+  -0.6799,  -0.1341,  0.7366,  1.5016,  2.3553,  1.9877,  1.8684,  -1.1687,  -1.7388,  -0.3259,  3.2899,  3.7096,  2.8005,  -0.4016,  0.0798,  0.8146,  0.249,  -0.5574,  0.0812,  -14.4681,
+  -4.5962,  -1.7335,  2.2323,  4.9758,  4.1965,  6.112,  6.3004,  -0.242,  -0.4268,  -3.4101,  -1.9343,  1.8578,  -0.3352,  -3.5061,  -2.9167,  0.7871,  0.7063,  -1.6356,  3.3878,  -9.8196,
+  13.1227,  13.7568,  12.075,  11.2378,  13.9543,  15.7037,  14.8582,  9.5334,  0.1292,  -3.0889,  -7.7565,  -10.9896,  -5.4579,  -2.1373,  0.1387,  -11.7169,  -13.0933,  -7.4977,  -12.364,  -30.4077,
+  29.3087,  22.8979,  20.4744,  14.9176,  7.8398,  2.3822,  -3.7671,  1.0563,  -3.5131,  2.1709,  4.106,  -2.4865,  -7.3802,  -9.3667,  -9.8213,  -8.8247,  -9.4073,  -14.9259,  -16.153,  -19.5079,
+  8.2477,  12.7093,  19.458,  20.8257,  15.6422,  8.6762,  4.5782,  4.1335,  5.6439,  14.7051,  12.4104,  11.4909,  -6.3291,  -17.1032,  -20.7835,  -24.4558,  -22.5241,  -14.5649,  -5.2278,  -27.5328,
+  0.7217,  4.0954,  5.2473,  1.527,  1.7119,  3.5822,  -1.4614,  0.872,  -1.3606,  -1.4757,  -0.4869,  1.0336,  -0.7433,  2.0743,  0.6152,  -7.1442,  0.592,  6.3583,  2.8714,  -18.6301,
+  20.3582,  21.7378,  21.8475,  15.5031,  8.5323,  5.5254,  -0.6584,  -4.0833,  -5.5901,  -5.8466,  -2.2597,  3.0499,  -4.1864,  -7.3615,  -5.3521,  -8.6549,  -8.7165,  -10.8646,  -9.6599,  -23.3202,
+  7.9037,  5.3843,  2.5963,  1.7924,  -4.1648,  1.1119,  1.0025,  0.4959,  -1.4533,  -3.0047,  0.7379,  1.8636,  2.4329,  0.95,  -0.1706,  -0.3177,  0.7889,  1.1735,  -0.473,  -18.6499,
+  -1.9942,  -2.2404,  1.0361,  1.1275,  2.4246,  0.9687,  -0.7731,  -0.435,  2.7773,  4.6081,  2.2666,  5.9874,  1.4863,  -4.3135,  -1.0943,  3.1059,  -4.9201,  3.6382,  1.5522,  -15.2082,
+  15.5189,  17.894,  20.2047,  21.1613,  16.5719,  9.883,  6.2072,  1.5961,  -2.8649,  -4.235,  -1.2109,  1.6294,  -0.3114,  -6.289,  -6.647,  -6.6461,  -16.7097,  -18.4834,  -19.5782,  -27.6908,
+  4.5707,  9.9453,  16.9194,  16.3836,  7.5074,  1.7185,  -1.6704,  -4.647,  -7.171,  -7.5216,  -6.2372,  -1.4728,  9.199,  4.5872,  4.2446,  -3.1203,  -10.1462,  -8.9093,  -2.0237,  -22.1562,
+  10.2043,  6.2265,  8.048,  6.0822,  2.9673,  -0.2686,  -0.4905,  -3.3479,  -4.2925,  -4.0224,  -2.6407,  -3.8742,  0.6899,  3.7007,  5.8631,  8.848,  -1.0855,  -6.5692,  -4.1304,  -21.9079,
+  12.9155,  18.0966,  19.8262,  14.0767,  6.9947,  1.6106,  -0.8791,  -6.2102,  -7.3162,  -10.2835,  -10.9883,  -8.3441,  -1.6557,  0.008,  -5.7847,  1.4192,  -5.5022,  -4.2471,  3.9784,  -17.7147,
+  5.1637,  8.0679,  12.5738,  17.5701,  14.9252,  4.1592,  0.9276,  -0.3161,  0.0005,  3.6819,  10.2605,  3.1026,  -2.7955,  -2.8307,  -1.1861,  -9.2862,  -11.7976,  -5.3295,  -15.7634,  -31.1274,
+  6.9673,  6.7974,  6.1367,  10.4782,  15.9809,  13.2295,  4.9742,  0.4813,  -4.131,  -5.6911,  -5.9712,  -1.2511,  7.3306,  2.6442,  0.3224,  -0.8372,  -7.4799,  -9.3018,  -8.5882,  -32.0913,
+  13.1396,  12.9563,  12.3478,  9.0857,  2.3849,  -0.849,  -1.4825,  -4.2362,  -7.2804,  -7.4639,  -6.8853,  -6.4479,  -4.2443,  -8.2231,  -3.9022,  0.4289,  0.1896,  3.7001,  6.9697,  -10.1879,
+  15.333,  18.1603,  22.1112,  21.6848,  13.1886,  10.5333,  8.8464,  9.6626,  12.4137,  13.9577,  10.142,  -0.2864,  -11.4409,  -16.9791,  -19.7494,  -15.6645,  -19.7643,  -22.5,  -23.5283,  -26.1208,
+  6.8457,  -6.8649,  5.4271,  5.2712,  -1.3685,  5.0072,  1.5557,  0.4655,  -8.6121,  0.8133,  -3.3697,  -1.5367,  2.2231,  2.7614,  0.6905,  -0.9517,  3.9757,  2.5271,  6.8378,  -21.6975,
+  4.0198,  5.3861,  1.469,  -2.5892,  -0.7717,  2.5302,  1.6444,  0.6228,  0.0646,  3.2916,  3.8112,  -0.6089,  2.1623,  0.1459,  0.1339,  0.1325,  -1.6768,  -0.5331,  -0.5013,  -18.7335,
+  -7.1586,  -2.6175,  0.5796,  4.1833,  -1.3849,  0.3608,  -8.9238,  -4.4835,  -1.6026,  -5.1856,  -8.3891,  -1.473,  9.5706,  -8.3291,  11.6042,  11.148,  -0.2734,  4.8182,  12.1074,  -4.5509,
+  12.6166,  14.8923,  16.2633,  17.1269,  18.2744,  19.287,  16.5858,  10.4162,  6.9131,  6.3384,  2.9142,  -1.3754,  -10.9051,  -16.4865,  -19.5016,  -17.7616,  -6.9047,  -16.5161,  -23.1066,  -29.0706,
+  10.8009,  12.8094,  14.6516,  18.7246,  16.6285,  12.1161,  8.7229,  6.4887,  7.8806,  10.133,  4.172,  -4.3839,  -6.8368,  -8.8011,  -8.4415,  -14.6175,  -16.9291,  -13.3638,  -20.2402,  -29.5143,
+  6.219,  6.4291,  6.1608,  8.0273,  9.8018,  9.8514,  6.5431,  7.0773,  5.8326,  5.6116,  8.215,  7.4679,  -0.2957,  -6.5386,  -7.9,  -7.1888,  -10.2895,  -12.2362,  -14.0338,  -28.7541,
+  8.0266,  9.6417,  12.2059,  15.4655,  15.3945,  10.4886,  6.7757,  2.33,  3.3664,  6.5551,  2.3159,  -4.1967,  -9.2962,  -11.8145,  -9.9788,  0.04,  -6.7484,  -6.4088,  -11.3916,  -32.771,
+  -6.0361,  -3.7035,  -0.2831,  1.4674,  0.7756,  0.3247,  -0.7445,  -0.5024,  -2.1341,  2.7813,  -0.1459,  -3.5635,  -3.9893,  -4.293,  -0.5948,  5.6527,  2.1314,  14.0267,  12.5554,  -13.7247,
+  -14.2301,  -11.8469,  -5.4438,  -2.2899,  3.4911,  0.4713,  0.7187,  -2.7114,  -1.5588,  -2.821,  -0.0887,  1.506,  2.8286,  9.35,  12.2742,  8.0817,  12.1298,  7.7574,  3.4239,  -21.0423,
+  10.2809,  9.4545,  10.3039,  12.6386,  19.498,  22.5798,  19.2258,  15.3342,  18.162,  10.8305,  -3.6184,  -11.2472,  -16.1533,  -19.0561,  -21.3742,  -19.1215,  -7.0133,  -13.0322,  -12.3255,  -25.3663,
+  -7.1992,  -4.095,  -0.4752,  -0.0397,  -1.2923,  1.268,  2.102,  -2.0159,  0.5678,  -4.1475,  -2.286,  1.2468,  2.916,  3.7433,  -3.5078,  6.2645,  5.1466,  3.3947,  11.0482,  -12.6391,
+  -1.4558,  2.635,  2.5261,  -0.4261,  7.9067,  7.3761,  10.505,  2.1413,  -4.1382,  -2.8818,  6.9021,  5.4317,  4.9534,  4.5363,  -2.8372,  -3.4508,  -1.0165,  -1.6706,  -9.0235,  -28.0132,
+  5.4483,  7.0338,  8.8713,  13.9617,  19.3432,  16.574,  12.5536,  13.7232,  15.1487,  4.1979,  -4.0767,  -8.9863,  -10.9482,  -13.1722,  -11.3412,  -7.4945,  -4.4916,  -3.5707,  -22.8865,  -29.8879,
+  12.0309,  14.2862,  17.8716,  18.2606,  13.3426,  8.9006,  1.3455,  -9.418,  -11.1012,  -15.4444,  -17.4768,  -17.9985,  -12.4515,  -5.2431,  8.8612,  5.5913,  6.3114,  -1.1018,  0.2013,  -16.7679,
+  16.8689,  16.8256,  18.5632,  14.4683,  8.2457,  2.7262,  1.7491,  0.4673,  -4.4682,  -6.2835,  -4.328,  2.1966,  -4.4856,  -9.6447,  -7.5807,  2.0175,  -9.6747,  -9.7002,  -3.665,  -24.2978,
+  10.3443,  9.5624,  9.5859,  9.3945,  7.7097,  5.9502,  5.4955,  7.0578,  3.897,  1.8002,  2.9026,  0.83,  -0.8072,  -3.4283,  -8.7861,  -9.4681,  -7.6897,  -10.0581,  -8.5829,  -25.7097,
+  8.4589,  13.906,  18.357,  21.8577,  20.8363,  13.5168,  7.0018,  3.5585,  0.2984,  -4.3657,  -7.6435,  -5.4526,  -6.4991,  -0.0823,  -10.9834,  -14.489,  -9.9873,  -4.5713,  -15.9935,  -27.7237,
+  -2.7942,  -1.0695,  -0.1214,  2.5877,  1.5098,  1.0893,  1.5717,  3.2131,  6.2989,  10.9335,  9.8682,  8.6743,  4.8838,  1.8707,  -1.0579,  -3.7852,  -5.7917,  -7.6708,  -7.9578,  -22.2525,
+  25.1784,  20.8581,  17.0052,  12.9557,  7.7424,  3.9815,  6.0072,  3.4663,  -1.9041,  -8.1079,  -11.4077,  -11.8642,  -8.7727,  4.7601,  2.8284,  -7.3135,  -15.0133,  -13.8178,  -7.5999,  -18.9821,
+  13.6088,  10.9215,  11.1892,  11.7633,  13.2294,  6.3264,  1.9267,  -1.7303,  -3.3278,  -4.4979,  -7.2855,  -3.9683,  5.3311,  -1.6679,  -8.5378,  -6.9275,  2.8396,  -8.2151,  -5.8206,  -25.1573,
+  20.0774,  19.5893,  17.125,  15.9021,  10.2327,  5.8537,  4.1551,  8.7468,  6.2824,  -1.6643,  -0.8142,  -5.7458,  -5.8553,  -6.7971,  -4.8129,  0.1863,  -14.4064,  -22.1846,  -19.7857,  -26.0848,
+  1.9579,  3.5459,  5.6047,  9.8227,  17.151,  16.9383,  8.2371,  2.3829,  -0.9137,  -2.6491,  -2.1733,  3.0262,  6.5399,  -2.8952,  -2.9389,  -0.9532,  -9.2242,  -11.9604,  -12.7131,  -28.7857,
+  2.7147,  5.0851,  5.901,  8.2492,  9.0379,  12.5344,  15.7585,  7.9343,  2.8699,  -7.6515,  -7.5935,  -7.0792,  -7.0329,  -0.2973,  -4.1153,  0.8146,  0.8342,  -8.0293,  -6.0641,  -23.8708,
+  -1.8671,  0.2021,  1.1744,  3.3514,  3.8114,  4.6535,  6.4708,  5.5903,  4.6873,  6.12,  7.1503,  10.882,  10.1467,  5.0564,  -4.0471,  -7.0223,  -5.8028,  -7.0328,  -13.2761,  -30.2485,
+  14.4582,  17.2732,  16.2772,  7.1332,  0.6525,  -4.4947,  -7.791,  -9.8395,  -12.5801,  -10.7856,  -8.8712,  -4.2717,  7.2719,  0.7198,  1.5521,  3.5804,  -2.9845,  0.1717,  6.3548,  -13.8266,
+  28.6852,  25.8888,  20.5479,  11.1546,  4.6177,  1.8681,  3.9247,  1.295,  -2.924,  4.305,  4.3461,  -5.4196,  -7.8904,  -10.2821,  -8.2802,  -13.991,  -11.2895,  -12.538,  -13.7725,  -20.2458,
+  6.9489,  8.2782,  12.9177,  18.1269,  10.1196,  2.5932,  -1.2838,  -5.9588,  -9.0612,  -10.7381,  -10.6395,  -8.4104,  -4.0818,  7.0965,  0.3344,  2.1418,  2.2817,  -3.7137,  1.6102,  -18.5618,
+  6.2919,  7.1483,  7.7499,  10.3266,  12.7585,  21.8234,  21.7899,  13.6697,  7.2737,  9.3185,  13.4418,  -0.153,  -6.4198,  -9.4554,  -7.4143,  -12.4542,  -21.2295,  -24.5545,  -24.4585,  -25.4529,
+  3.2078,  1.1604,  2.382,  7.1676,  15.6309,  19.6735,  9.8897,  7.8474,  10.1305,  10.405,  -1.822,  -9.0708,  -12.7476,  -14.298,  -11.7869,  -3.2366,  -4.1439,  -6.6114,  -0.0121,  -23.7655,
+  4.9484,  5.9562,  10.0092,  16.2669,  12.926,  3.9525,  0.492,  -2.9838,  -4.7825,  -5.0706,  -3.0972,  4.4166,  5.1484,  -3.0885,  -2.2935,  1.8467,  -6.6209,  -8.5405,  -3.2672,  -26.218,
+  9.119,  11.7308,  15.3181,  20.5759,  15.7183,  7.69,  3.7341,  -3.2723,  -6.7161,  -9.0437,  -8.0703,  -0.593,  6.4087,  3.5269,  3.0413,  -8.4178,  -14.7425,  -12.7049,  -6.9905,  -26.3121,
+  1.4852,  -0.6829,  -1.569,  -0.2848,  5.5052,  12.8631,  6.4129,  0.4626,  -3.55,  -5.4162,  -3.9006,  -1.4888,  7.5205,  5.649,  1.1393,  5.5204,  -1.2344,  -6.2194,  -3.0728,  -19.139,
+  11.9158,  15.3244,  18.2371,  17.8689,  12.9861,  8.5734,  2.6935,  -0.462,  -0.3115,  4.3187,  1.8359,  -6.5328,  -11.3944,  -12.3343,  -10.2127,  -3.2123,  -10.7404,  -11.6243,  -6.0915,  -20.8377,
+  -1.1406,  4.4681,  1.0243,  1.7567,  0.8452,  1.0568,  1.7113,  1.4304,  8.2151,  0.5703,  1.2053,  -5.7909,  -4.3638,  0.9165,  -4.5872,  3.4354,  6.9859,  3.9875,  -3.5121,  -18.2142,
+  18.8171,  22.5033,  16.7157,  10.3549,  3.9514,  1.6962,  -0.6346,  -5.9992,  -6.8816,  -7.3001,  -7.9076,  -4.3326,  4.9348,  4.6458,  0.9437,  -3.5521,  -9.364,  -2.4386,  -11.4118,  -24.7409,
+  -0.9409,  0.5904,  2.2794,  4.9547,  5.8743,  8.7846,  11.0088,  11.1838,  11.6958,  14.1355,  8.9116,  2.5256,  -1.8779,  -5.6262,  -5.5753,  -9.1754,  -9.0981,  -12.4659,  -11.4699,  -25.7149,
+  0.4141,  2.8215,  2.0838,  3.1886,  4.2216,  1.7188,  4.6179,  2.9704,  1.6545,  -2.846,  -0.9511,  2.6537,  -1.8008,  0.9825,  1.2384,  1.5282,  -0.7271,  -3.094,  -0.809,  -19.8659,
+  6.043,  4.6516,  4.3017,  7.7179,  6.7963,  6.291,  8.7476,  8.7592,  7.7014,  12.1586,  8.0227,  -1.3414,  -6.0075,  -8.1097,  -6.8511,  -6.6141,  -5.8068,  -8.7086,  -9.3302,  -28.4218,
+  7.1395,  6.4611,  6.477,  6.5752,  5.736,  5.6174,  3.8338,  -0.3402,  -1.9803,  -2.2319,  -4.1316,  -3.2411,  -2.2252,  4.195,  1.9636,  -1.7425,  0.5431,  -3.5115,  -6.8529,  -22.2844,
+  17.8843,  21.4402,  20.6904,  15.9517,  9.7051,  2.5656,  -1.5516,  -7.4554,  -8.8729,  -10.2263,  -8.6781,  -5.1896,  -0.7045,  -6.768,  -8.2898,  -6.9326,  1.3954,  -3.2208,  -6.0504,  -15.6928,
+  10.6767,  10.3544,  18.1231,  11.2879,  6.1413,  -0.361,  -2.4504,  -5.1076,  -4.9943,  -4.9704,  -2.3126,  5.9757,  0.9523,  -4.2427,  -2.5152,  4.9197,  -8.3019,  -9.0057,  0.3384,  -24.5078,
+  9.9161,  11.8977,  18.2327,  24.4645,  22.2618,  14.5543,  11.0874,  11.6473,  16.7269,  16.7802,  10.9221,  4.3259,  -12.8739,  -20.0422,  -22.5408,  -24.1296,  -20.9142,  -22.6765,  -24.3668,  -25.2731,
+  9.4023,  7.3715,  11.9062,  12.512,  7.0268,  13.6459,  7.2747,  2.8388,  14.6515,  22.1573,  24.2647,  6.5863,  -1.1334,  -12.1075,  -18.8356,  -21.0343,  -18.7149,  -21.3705,  -23.1378,  -23.304,
+  6.1154,  6.8878,  8.0486,  2.083,  11.4555,  24.4875,  10.2548,  8.5452,  8.1934,  -4.1865,  11.8854,  1.3485,  1.9895,  -14.5678,  -11.0286,  -3.4615,  1.3428,  -19.7548,  -24.2069,  -25.4313,
+  10.357,  12.8522,  17.3265,  22.8368,  16.6859,  10.9743,  8.2198,  6.8557,  9.3432,  12.2609,  5.1561,  1.541,  1.3448,  -11.6896,  -19.8579,  -22.4891,  -19.3409,  -16.0157,  -19.9891,  -26.372,
+  -2.2958,  -3.0198,  2.5524,  6.5326,  5.0549,  2.8939,  1.6085,  1.4431,  -0.1701,  -2.0055,  1.1867,  -1.3016,  -2.2987,  6.124,  3.0188,  -0.9646,  2.6135,  4.0735,  0.2584,  -25.3041,
+  3.3425,  -4.9398,  1.7857,  0.981,  8.2974,  13.876,  7.3422,  4.3951,  4.0317,  8.9378,  9.1371,  -1.7588,  -9.1168,  -12.4667,  -12.0238,  -9.0772,  4.3501,  -0.6556,  4.4305,  -20.8684,
+  2.6724,  2.4627,  -2.5441,  -3.3045,  -4.2917,  -1.4508,  1.5865,  -1.0572,  -2.1109,  1.487,  -1.0006,  3.5002,  3.7107,  1.3794,  -1.6261,  0.0378,  2.0162,  0.3261,  3.2452,  -5.0385,
+  3.1268,  4.8784,  8.6218,  13.5865,  14.1019,  7.249,  1.4764,  0.4142,  -1.444,  -0.1256,  6.7242,  13.6333,  7.9001,  5.1808,  -8.7618,  -15.9427,  -17.574,  -13.2732,  -3.9031,  -25.8689,
+  8.7515,  17.2518,  23.5164,  15.769,  8.1574,  4.9814,  0.5026,  -0.4621,  -1.5217,  2.4458,  11.1982,  12.8925,  8.2107,  -10.1894,  -18.8969,  -20.9839,  -19.6436,  -9.2705,  -7.3159,  -25.3934,
+  11.798,  12.1448,  14.6065,  20.2682,  20.5368,  14.0544,  8.9695,  7.1447,  9.3182,  10.2279,  -1.3945,  -9.863,  -14.231,  -14.26,  -11.294,  -5.3186,  -14.6453,  -16.0278,  -14.7441,  -27.2906,
+  8.3692,  9.6882,  12.8542,  17.3005,  21.134,  18.5917,  11.2777,  5.5517,  0.547,  -2.3437,  -2.3633,  -0.2054,  0.7833,  -4.4844,  -5.7547,  -6.4185,  -15.2118,  -20.989,  -20.6002,  -27.7265,
+  3.254,  3.5495,  5.6572,  11.4443,  18.6822,  14.2818,  7.9623,  5.8581,  7.6636,  11.238,  10.4719,  -0.3434,  -0.9127,  0.3323,  -9.6682,  -12.3368,  -7.0303,  -17.504,  -22.5944,  -30.0053,
+  10.5668,  4.7765,  4.8789,  5.9385,  13.1029,  20.5979,  14.5257,  8.6496,  2.4271,  -1.164,  1.2029,  9.4957,  -0.02,  -12.573,  -14.8513,  -9.422,  -4.4288,  -12.9535,  -14.372,  -26.3782,
+  3.6092,  2.1429,  -0.2581,  2.1516,  6.0252,  4.4742,  4.352,  2.9527,  3.6102,  2.6901,  -0.0942,  2.2564,  1.3309,  -0.5758,  -1.109,  0.1191,  -0.118,  -0.1015,  -5.5503,  -27.9075,
+  8.4206,  12.653,  18.9633,  23.9855,  21.254,  9.7237,  1.5121,  -0.7361,  0.7545,  -1.5581,  2.4158,  9.9186,  6.7278,  3.6705,  -12.4971,  -19.8574,  -23.2581,  -23.72,  -10.9203,  -27.4525,
+  22.1951,  16.4633,  13.2055,  7.497,  2.228,  -2.4528,  8.773,  10.687,  4.9929,  1.1178,  -5.3802,  -8.2471,  -5.7256,  -8.8078,  -8.354,  1.5835,  1.5054,  -11.6521,  -13.9564,  -25.6726,
+  -7.9053,  -6.584,  -6.0103,  -4.8986,  -4.2425,  -4.7462,  -6.7261,  -8.5401,  -8.6906,  -8.8402,  -5.6306,  -0.7673,  8.6501,  5.08,  13.9798,  11.4953,  10.0314,  17.429,  14.9683,  -8.0522,
+  11.9359,  8.4098,  2.8637,  0.1621,  4.2653,  2.699,  1.2433,  -1.9101,  -2.5608,  -4.4372,  -0.737,  5.0345,  2.4512,  -1.2451,  -4.6924,  -2.0267,  0.3932,  -0.7445,  -1.8229,  -19.2813,
+  -1.3202,  3.8184,  7.4609,  11.6391,  16.2849,  25.4929,  15.8707,  1.4126,  12.3759,  21.2527,  8.1587,  -3.8943,  -14.786,  -10.693,  -17.9239,  -16.3824,  -1.7644,  -13.0054,  -19.3451,  -24.6522,
+  9.8443,  9.9627,  12.5201,  13.7261,  10.3992,  6.629,  2.9281,  -0.7644,  -3.9695,  -5.3737,  -8.3704,  -7.5382,  -1.7207,  5.7599,  1.941,  -0.8146,  0.5436,  -5.6632,  -12.2155,  -27.8236,
+  6.429,  4.7082,  3.9317,  3.1702,  -1.6353,  -3.6078,  -6.315,  -9.1986,  -10.3233,  -9.8065,  -5.8063,  -1.3404,  -0.7673,  -2.2448,  -1.2797,  7.1795,  3.2561,  15.5273,  14.8629,  -6.7401,
+  23.9506,  22.1558,  17.7456,  14.435,  8.3329,  3.1023,  4.3134,  8.6024,  3.8015,  -3.9642,  -10.78,  -9.6229,  -10.886,  -10.6376,  -8.0083,  4.7524,  -6.4851,  -13.7226,  -12.4871,  -24.598,
+  9.576,  11.4366,  12.9012,  14.4846,  16.8425,  19.5473,  19.7042,  15.2736,  12.0272,  11.0446,  7.4677,  1.1314,  -9.0848,  -18.3215,  -23.8214,  -23.171,  -19.9932,  -10.2715,  -17.3599,  -29.4137,
+  -3.4431,  -3.1613,  -1.9102,  -0.6935,  1.387,  1.2966,  -1.0892,  -2.4642,  -3.0407,  -4.4927,  -5.4209,  -4.2773,  -0.5358,  0.409,  1.2794,  5.899,  14.3402,  3.7638,  11.1512,  -8.9972,
+  15.2464,  18.8014,  25.3166,  19.5775,  11.0313,  6.5896,  5.6381,  2.9552,  5.1185,  13.254,  13.6736,  8.5584,  -8.3365,  -15.9401,  -20.3756,  -21.2859,  -21.2275,  -19.3217,  -15.1325,  -24.1407,
+  3.1035,  6.1792,  5.0462,  3.5926,  7.0741,  6.4046,  9.9419,  7.7684,  4.2113,  3.6277,  6.5092,  5.59,  -1.7178,  -6.4492,  -7.8871,  -6.9582,  -5.1379,  -8.3058,  -10.5436,  -22.049,
+  -0.728,  0.5704,  3.9717,  5.9469,  6.078,  4.077,  1.2426,  -1.3458,  -3.2314,  -4.6819,  -6.2378,  -5.0198,  -1.208,  10.5808,  2.6382,  3.7712,  3.8446,  -1.7555,  -1.1558,  -17.3572,
+  5.3326,  5.4267,  9.824,  16.2001,  13.6887,  6.951,  1.1917,  -1.6723,  -2.5788,  -2.7648,  2.6931,  5.4843,  -4.2095,  -9.6143,  -6.2919,  3.6211,  -3.8754,  -6.5263,  -5.2823,  -27.5977,
+  2.5771,  3.4727,  5.4467,  8.8349,  9.887,  12.1341,  12.0826,  7.7444,  4.5255,  0.7889,  -2.0382,  -4.7604,  -5.7542,  -4.6241,  -2.4718,  -4.0958,  -6.2797,  -4.6267,  -9.5398,  -23.3031,
+  14.7846,  16.0256,  18.44,  18.7731,  12.4129,  9.2087,  4.9463,  5.2837,  7.9434,  9.1983,  5.6775,  1.0431,  -7.1678,  -12.3799,  -13.9635,  -9.429,  -13.5075,  -18.2553,  -21.2672,  -27.767,
+  14.086,  12.616,  17.7362,  22.848,  13.2766,  7.4189,  5.7487,  1.8704,  2.3287,  6.7312,  16.704,  13.9396,  0.1199,  -14.272,  -18.2397,  -22.3862,  -24.8172,  -19.6941,  -10.4326,  -25.5823,
+  1.2702,  -1.274,  -3.71,  -0.5628,  -4.5219,  -4.458,  -7.71,  -8.3547,  -7.0524,  -3.3805,  -3.0927,  1.978,  6.7217,  16.8392,  12.2288,  6.1018,  4.3647,  3.7046,  7.0648,  -16.1569,
+  -1.5691,  -0.6625,  0.8145,  2.7114,  4.5683,  6.3808,  5.3169,  3.3697,  3.7409,  -1.1329,  1.3502,  1.4333,  7.1092,  8.0819,  7.414,  -0.3489,  -3.5222,  -5.2023,  -8.9373,  -30.9159,
+  8.8791,  11.5486,  17.4354,  21.959,  18.7721,  13.0614,  12.3597,  15.8383,  7.9901,  -4.7504,  -11.1404,  -17.0402,  -20.1418,  -20.5768,  -16.8543,  -10.271,  3.5082,  1.5897,  -6.0317,  -26.1349,
+  1.4924,  2.3041,  3.6995,  3.9735,  2.9478,  1.4182,  -0.1153,  -0.7081,  -1.6935,  -4.7155,  -3.8966,  -1.0552,  4.3924,  3.5582,  4.7903,  3.4573,  4.4498,  3.7588,  -4.9783,  -23.08,
+  19.7104,  23.5312,  26.4663,  21.1276,  13.4352,  11.0142,  11.5216,  12.6431,  11.662,  1.8352,  -2.6313,  -2.1531,  -10.9044,  -16.4683,  -19.1821,  -21.4207,  -21.6631,  -20.6795,  -14.544,  -23.3003,
+  -7.3825,  -5.1236,  -2.0803,  -0.3985,  -2.1515,  -3.3191,  -2.5398,  -3.6553,  -4.6673,  0.245,  -1.138,  0.4163,  -5.0235,  -3.1123,  1.6781,  0.5456,  9.2542,  19.9831,  16.2303,  -7.7611,
+  2.5108,  2.1845,  2.6268,  3.2213,  4.7277,  4.9151,  4.4068,  2.5115,  -1.2667,  -1.047,  -0.584,  3.198,  11.3786,  3.1343,  -1.5396,  -0.779,  -4.2909,  -5.9553,  -4.0558,  -25.2973,
+  1.3099,  3.8149,  5.9305,  6.029,  6.2561,  6.5634,  6.5483,  2.2558,  2.8164,  5.8479,  6.7553,  3.8567,  2.7371,  -0.0626,  -3.8527,  -5.1436,  -5.5124,  -7.3236,  -9.2045,  -29.6219,
+  6.9414,  7.8896,  11.9174,  19.4391,  22.8159,  17.513,  12.8967,  11.7403,  13.3801,  0.6255,  -8.6365,  -13.1338,  -15.0777,  -14.1269,  -8.2615,  -12.9862,  -16.1846,  -10.2908,  -1.8314,  -24.6297,
+  13.6675,  18.7539,  23.7644,  23.5665,  14.5584,  8.2788,  5.9566,  3.8037,  5.8231,  9.3954,  3.8096,  -3.7071,  -3.0809,  -2.7965,  -15.391,  -22.2338,  -22.7083,  -19.7578,  -17.2327,  -24.4698,
+  6.8878,  4.6215,  4.083,  1.7534,  6.3161,  9.303,  9.1793,  1.8539,  -3.8953,  -6.2684,  -7.283,  -6.1167,  0.8013,  5.3564,  -0.9241,  -2.6976,  1.7576,  -1.1627,  -4.9125,  -18.6528,
+  11.5366,  9.1379,  9.1023,  13.3107,  15.2931,  8.4262,  2.0019,  -1.8545,  -5.347,  -10.498,  -13.165,  -8.7617,  -2.8037,  6.5213,  -2.9746,  -1.1653,  2.895,  -3.9002,  -0.4074,  -27.3478,
+  8.1149,  5.2054,  4.7193,  10.9119,  14.2393,  9.7159,  2.7743,  0.0628,  -0.9042,  2.5046,  6.2675,  4.5297,  -1.7121,  -2.7212,  -6.4591,  -8.2032,  -12.1525,  -9.796,  -4.5542,  -22.5432,
+  10.427,  10.1489,  7.8411,  6.9092,  5.2675,  3.1553,  3.186,  0.3063,  0.4719,  -0.871,  -0.6868,  -1.1505,  -4.6137,  -2.9984,  -2.9661,  -2.854,  -3.0302,  -2.2057,  -5.9823,  -20.3547,
+  16.5991,  18.818,  20.4139,  16.0812,  15.2582,  13.6,  9.773,  4.82,  7.267,  0.5444,  -5.1929,  -8.9752,  -12.2178,  -15.2451,  -9.0857,  -9.6324,  -11.9042,  -7.0554,  -15.8485,  -28.0175,
+  6.9984,  7.5807,  9.7172,  14.2935,  21.1422,  18.8026,  13.0729,  13.6068,  15.6061,  5.7873,  -4.4176,  -10.663,  -14.9625,  -15.276,  -12.1485,  -4.9859,  -13.8661,  -15.0801,  -8.9505,  -26.2577,
+  4.8529,  5.9107,  5.9519,  3.1046,  -0.7986,  -3.8,  -3.3218,  -6.5949,  -9.5964,  -7.6925,  -7.0336,  -3.5031,  2.4411,  -0.1901,  9.1699,  13.0532,  0.4243,  10.947,  3.0406,  -16.3654,
+  2.3975,  0.4924,  3.8005,  6.146,  0.9043,  2.1381,  -0.0106,  2.9239,  -11.7677,  -3.8359,  -3.4925,  0.8716,  3.474,  -2.8287,  -3.8786,  1.2858,  6.8931,  -2.1701,  3.3894,  -6.7326,
+  -3.5428,  -1.39,  0.9285,  2.4806,  2.9675,  0.798,  0.9612,  0.2854,  -2.0562,  -1.3222,  -1.9025,  -0.0059,  8.6474,  4.6327,  1.6964,  0.3984,  0.9512,  1.7069,  1.4812,  -17.7159,
+  17.4798,  18.9995,  21.9699,  20.6967,  14.4015,  9.2408,  9.2963,  4.6834,  -0.5765,  -2.0466,  -4.687,  -8.134,  -10.84,  -6.9387,  -4.9129,  -2.3346,  -9.5282,  -16.6374,  -22.862,  -27.27,
+  30.2051,  29.0816,  22.701,  15.9702,  13.2347,  12.3034,  7.9736,  1.711,  -2.905,  -5.822,  -9.0457,  -11.4933,  -10.9824,  -10.7128,  -9.7198,  -11.447,  -12.1083,  -14.372,  -14.3489,  -20.2236,
+  4.3667,  5.6948,  7.6382,  9.1345,  7.9965,  5.9946,  4.8983,  4.5838,  1.3099,  -1.1182,  -2.4032,  -2.5986,  -0.3123,  -3.8248,  -3.3874,  -4.6492,  -2.5381,  -4.101,  -4.4278,  -22.2567,
+  13.3799,  15.9919,  18.2801,  18.5738,  14.5051,  15.061,  12.6361,  1.8684,  -4.4789,  -7.5763,  -7.3687,  -5.7285,  -8.7693,  -10.097,  -1.0795,  0.7696,  -6.5956,  -14.5402,  -16.2583,  -28.5735,
+  1.2989,  -0.2985,  -0.1264,  2.2528,  6.1919,  9.085,  11.5888,  9.6084,  6.4565,  4.6999,  3.8291,  -3.1433,  -2.0178,  -5.4377,  -3.5892,  -2.4088,  -3.4525,  -6.5279,  -6.8848,  -21.1245,
+  6.699,  6.9952,  6.99,  10.6461,  18.176,  23.4925,  20.7738,  19.3068,  14.5258,  4.1679,  -5.0313,  -10.5967,  -15.7569,  -18.7535,  -19.3572,  -18.4953,  -9.1098,  -8.3084,  -3.508,  -22.8561,
+  0.3614,  -3.0919,  -2.2049,  0.2924,  3.5194,  12.3203,  10.5339,  6.5081,  2.9888,  3.7587,  9.6208,  6.5139,  -3.3458,  -8.5883,  -8.7468,  -4.73,  1.1707,  -5.5824,  -3.0982,  -18.2001,
+  3.6833,  5.1669,  7.0034,  5.1138,  6.2451,  5.1324,  2.9024,  -0.2756,  0.6913,  0.7688,  2.7471,  -3.0081,  -4.2841,  -1.679,  0.6913,  -2.2915,  -1.1739,  -2.5591,  -2.7007,  -22.1738,
+  11.4726,  11.0663,  10.8078,  10.4446,  10.6033,  12.3965,  13.0646,  7.6243,  1.8855,  -2.1733,  -3.8981,  -0.7658,  2.9887,  -2.4982,  -10.215,  -14.2533,  -12.1696,  -5.433,  -8.34,  -32.608,
+  -6.7179,  -4.6131,  -3.1636,  0.0876,  0.6888,  1.0614,  0.5541,  -3.503,  -3.5922,  -2.2597,  -0.8136,  6.0096,  11.8925,  2.9252,  -1.145,  -0.4619,  -0.0294,  2.9522,  6.4894,  -6.3616,
+  5.3482,  3.731,  5.0957,  3.1029,  1.678,  3.1184,  0.5161,  -3.5018,  -4.5034,  -6.3519,  -7.8639,  -5.658,  -5.1767,  -2.3928,  0.1325,  3.3098,  7.821,  11.9881,  4.419,  -14.8118,
+  8.2697,  5.8835,  6.0215,  10.4427,  12.0342,  7.5709,  3.5443,  -1.0166,  -4.1313,  -6.5619,  -5.066,  -0.8575,  7.1102,  -0.6052,  -4.0956,  0.6756,  0.8926,  -4.2551,  -6.4788,  -29.3772,
+  2.0192,  3.9566,  4.9448,  8.089,  14.6263,  15.3545,  12.2775,  10.3302,  7.2993,  12.5826,  7.7803,  -2.3944,  -7.4949,  -10.2984,  -9.7837,  -7.3581,  -7.2692,  -6.1954,  -16.7366,  -31.7295,
+  12.8428,  15.92,  16.2497,  11.854,  3.8,  -1.0057,  -2.5059,  -6.532,  -8.39,  -9.9165,  -9.6596,  -6.0113,  1.0447,  13.8469,  7.3566,  -4.1906,  -11.0801,  -8.0052,  3.2361,  -18.8537,
+  17.202,  18.636,  23.3502,  20.5862,  15.5823,  12.7495,  6.4445,  -6.6661,  -9.171,  -15.5663,  -21.8272,  -18.4838,  -16.7082,  -14.2582,  2.8891,  3.6115,  -0.4823,  -0.0577,  2.5754,  -20.4057,
+  11.2405,  16.2045,  19.5245,  19.0279,  10.816,  4.2621,  0.0074,  -4.8018,  -7.7494,  -9.5065,  -10.8518,  -10.4718,  -6.2617,  1.5892,  9.5055,  4.0459,  -4.23,  -9.8946,  -9.4119,  -23.0441,
+  21.5981,  16.6548,  9.2131,  4.2901,  -2.7752,  -6.0814,  -5.7172,  -6.8518,  -5.3057,  -3.6255,  1.9348,  7.8994,  -1.326,  -8.0365,  -10.6481,  -6.5275,  -3.0468,  3.5257,  5.6627,  -10.8371,
+  2.3529,  1.9098,  1.1705,  -1.0129,  0.2322,  -2.1724,  -2.7849,  -0.3004,  1.1108,  2.9625,  0.3261,  -2.0946,  1.0272,  3.4696,  1.9753,  1.1513,  2.4885,  2.1442,  0.7739,  -14.7298,
+  -1.7003,  -2.4848,  -2.4346,  4.7038,  24.9669,  27.0962,  7.9463,  4.7152,  0.192,  -0.8991,  -0.8489,  9.9068,  -2.48,  -9.4907,  -11.9321,  -1.857,  -6.2441,  -11.0862,  -11.2891,  -16.7804,
+  14.9206,  17.922,  23.4494,  28.4771,  23.9338,  22.5858,  21.7793,  9.3991,  -3.6346,  -10.2702,  -14.3748,  -16.3264,  -19.3026,  -18.4585,  -17.3134,  -12.271,  -10.593,  -10.9994,  -7.9141,  -21.0092,
+  10.8472,  9.9985,  8.1012,  5.6373,  0.7372,  0.0745,  -0.8638,  -1.7933,  -2.9142,  -3.015,  -2.2427,  -0.7782,  -2.5201,  -6.2197,  -5.1933,  0.2777,  -5.0155,  0.2927,  4.1108,  -9.5213,
+  11.2774,  17.5024,  20.7927,  14.9512,  8.8893,  5.3831,  1.1126,  -0.5407,  -1.8226,  -0.7548,  3.8991,  14.1917,  11.4189,  -2.2812,  -13.1711,  -17.2396,  -15.8893,  -13.7806,  -15.9376,  -28.0009,
+  -1.8142,  -1.3801,  -0.2831,  1.382,  1.7722,  1.4623,  -1.2023,  -3.2113,  -5.2345,  -6.7523,  -4.9565,  -2.8637,  4.0779,  -2.6764,  0.8821,  14.4958,  8.5614,  4.5439,  7.906,  -14.7091,
+  10.5077,  13.8832,  19.5676,  20.853,  17.7078,  12.7109,  11.5269,  8.0218,  2.2318,  -5.7244,  -10.1683,  -12.812,  -14.923,  -10.7023,  -2.0109,  -8.3963,  -10.2008,  -5.4032,  -10.7793,  -25.8902,
+  -0.2509,  1.3469,  0.6421,  2.6377,  6.0659,  4.3721,  5.352,  3.9824,  -1.7069,  -2.0895,  -5.2191,  -1.537,  -3.3737,  1.3384,  4.0383,  10.2321,  1.6548,  -3.2413,  -5.147,  -19.0973,
+  6.4953,  9.3365,  14.1057,  20.6271,  16.1168,  7.358,  1.4929,  -2.7587,  -4.0681,  -3.9748,  1.3672,  8.9105,  -0.92,  -5.3133,  0.3345,  -6.1299,  -12.7503,  -9.3229,  -13.4612,  -27.4454,
+  0.6201,  2.4328,  4.976,  9.2545,  15.4025,  12.2971,  5.768,  5.0077,  4.0499,  4.2155,  9.706,  7.7493,  5.8274,  0.3852,  -5.9984,  -11.5236,  -7.305,  -10.3504,  -20.7971,  -31.7176,
+  -3.7294,  -1.4413,  -3.7524,  -4.5904,  -3.2743,  0.736,  -3.2763,  -4.8007,  -0.6213,  4.903,  10.4614,  11.0474,  17.3494,  -0.7763,  5.4732,  0.7769,  1.2498,  -0.7639,  -2.107,  -22.8638,
+  6.7163,  9.2255,  12.3187,  17.6924,  17.6404,  11.894,  7.0991,  4.2645,  4.3021,  9.9874,  5.8382,  -3.4579,  -6.9519,  -4.809,  -2.1538,  -14.0697,  -18.7474,  -17.332,  -11.2745,  -28.1824,
+  14.7156,  19.4663,  14.7897,  6.5422,  1.1728,  -2.3524,  -4.9286,  -7.8168,  -8.8525,  -9.4747,  -10.7274,  -8.5129,  -4.4565,  7.8312,  0.0283,  4.0451,  1.6338,  -1.3894,  4.4306,  -16.1441,
+  19.068,  22.0875,  24.611,  22.0341,  17.3706,  15.8785,  14.1658,  11.9508,  4.4308,  -1.1373,  -6.4223,  -10.3244,  -11.8572,  -13.5064,  -14.4779,  -15.1004,  -15.5216,  -16.8251,  -22.0101,  -24.4145,
+  9.0336,  19.0176,  24.4867,  24.6758,  18.9461,  11.7838,  7.6427,  4.775,  1.2864,  0.4513,  1.8155,  -1.2592,  -9.2086,  -14.2929,  -15.7555,  -13.6408,  -7.7748,  -14.5157,  -21.5902,  -25.877,
+  1.4827,  0.2805,  -0.381,  1.4732,  8.234,  8.1707,  10.06,  8.3087,  4.1212,  2.7249,  3.5821,  7.9718,  3.7426,  -2.6511,  -5.3909,  -4.4519,  -4.5293,  -6.7232,  -8.9602,  -27.0648,
+  10.5705,  10.67,  11.7791,  12.1925,  10.0236,  6.6964,  5.1163,  2.6148,  4.7648,  2.5521,  -3.9125,  -7.4628,  -9.6721,  -9.3307,  -9.9466,  -8.0895,  1.1968,  -3.82,  -3.4846,  -22.458,
+  7.5905,  8.3863,  11.5587,  16.2565,  22.0088,  23.0422,  17.8049,  13.1018,  17.1694,  13.5769,  -0.2381,  -1.8062,  1.5806,  -10.3901,  -20.8106,  -24.7914,  -25.0524,  -24.3552,  -19.3769,  -25.2554,
+  7.3275,  11.616,  16.6781,  15.5131,  8.1538,  4.8147,  -1.7134,  -2.9599,  -6.5688,  -7.0695,  -0.9248,  5.3367,  -4.508,  -7.1758,  -3.427,  -3.5021,  -8.7907,  -5.2842,  1.7479,  -19.2635,
+  8.6994,  13.7488,  20.2706,  15.6056,  8.03,  2.7906,  -2.4915,  -6.3762,  -9.0577,  -10.4892,  -11.7811,  -10.7422,  -7.7494,  -0.3422,  10.0858,  3.8928,  3.968,  -2.0796,  -2.0561,  -23.9265,
+  -1.8066,  -1.3696,  1.0493,  1.3711,  1.9691,  1.1999,  -1.8646,  -1.9643,  -1.7749,  -1.339,  -3.3717,  3.1526,  1.2109,  0.799,  0.4966,  2.5531,  3.3704,  2.3429,  4.9229,  -10.9469,
+  4.0689,  7.4175,  12.694,  18.06,  16.5869,  9.3259,  4.5282,  2.8636,  1.6428,  4.7328,  12.4121,  9.1212,  6.2302,  0.0152,  -12.5596,  -17.7355,  -18.6999,  -12.797,  -17.6503,  -30.2571,
+  0.8292,  2.6495,  1.8804,  4.1439,  5.6667,  5.7021,  4.9475,  6.8868,  6.795,  8.0289,  10.5666,  8.6874,  1.8534,  -2.2297,  -6.3646,  -6.79,  -8.1505,  -9.3082,  -10.0423,  -25.7522,
+  7.1022,  3.8236,  1.8946,  4.423,  4.784,  4.6315,  5.8219,  2.7914,  1.6501,  0.4344,  2.2205,  4.0071,  0.0326,  -2.6285,  -2.5436,  -3.5874,  -3.6688,  -4.2155,  -7.0087,  -19.9643,
+  0.1242,  12.2019,  4.3084,  4.2478,  1.9093,  0.6288,  1.1102,  1.5269,  2.2918,  5.1362,  2.1955,  -5.7687,  1.1936,  -1.4469,  0.2971,  -4.6605,  0.8522,  1.2017,  -3.9848,  -23.3647,
+  -5.1159,  -1.2775,  2.526,  4.1265,  3.4097,  -1.7194,  -0.8844,  -1.4795,  -5.4958,  -6.8537,  -1.5398,  0.9661,  -2.324,  -4.8943,  8.2925,  3.4432,  -1.7853,  6.31,  13.441,  -9.1454,
+  3.9898,  4.3777,  4.2357,  3.0453,  3.7447,  2.5019,  1.1011,  -0.478,  -2.4003,  -0.6497,  0.8291,  0.2117,  0.0985,  -0.2133,  0.383,  -1.785,  -1.0322,  -2.1328,  -1.6069,  -14.2203,
+  11.3622,  14.7416,  16.8859,  15.0883,  9.9488,  8.7692,  4.3995,  -2.0242,  -2.6878,  -1.0092,  0.7764,  -2.2298,  -4.084,  -8.1165,  -6.2525,  -5.2064,  -7.0092,  -6.7164,  -9.2528,  -27.3833,
+  3.6579,  2.8996,  4.0461,  8.3701,  17.0082,  23.3625,  16.2578,  7.1955,  17.3887,  6.3999,  -4.2883,  -9.9015,  -12.7556,  -12.3388,  -5.468,  -10.3674,  -10.9476,  -10.1432,  -6.0175,  -24.3585,
+  7.5312,  5.8939,  4.3265,  4.0014,  2.9087,  1.6542,  2.9601,  3.9087,  1.37,  -2.9778,  -0.8059,  -0.8752,  -0.992,  -0.8125,  -0.8336,  -0.0306,  -2.6451,  -2.7999,  -4.2986,  -17.4834,
+  15.3876,  20.0855,  22.6771,  20.6277,  15.1509,  8.8202,  3.6289,  -2.1904,  -8.5688,  -13.1818,  -15.2549,  -15.0083,  -12.7233,  -8.7307,  0.5974,  4.3829,  -2.277,  -0.0304,  -7.8902,  -25.5026,
+  23.6589,  23.2539,  20.352,  15.1761,  11.4144,  5.8059,  5.4712,  1.316,  0.0827,  -2.4308,  -7.0613,  -6.1765,  -1.8534,  5.6004,  -1.4387,  -15.4564,  -17.387,  -18.868,  -17.3832,  -24.0763,
+  11.6709,  14.1123,  21.1753,  25.8068,  20.7082,  14.063,  14.1588,  17.922,  14.6153,  4.8179,  3.3194,  0.469,  -11.4997,  -19.1991,  -21.5666,  -21.4213,  -21.1902,  -22.3547,  -22.1566,  -23.4508,
+  4.6799,  3.0606,  1.6539,  6.2007,  -2.0201,  3.0954,  0.5569,  3.2707,  1.3312,  0.0725,  1.8286,  -5.9667,  2.657,  -0.0978,  -1.2174,  -2.2597,  0.2234,  1.4765,  -4.2077,  -14.3379,
+  9.3104,  11.8578,  14.9832,  13.1906,  8.5578,  4.2616,  -0.4942,  -3.0677,  -3.2171,  -5.1322,  -1.7298,  6.6384,  -0.8475,  -8.0712,  -9.5863,  -5.8386,  2.661,  -8.3104,  -6.0285,  -19.1373,
+  2.2896,  3.8587,  4.9224,  8.6357,  13.9236,  17.8222,  15.7427,  11.5211,  7.5272,  9.1679,  9.7247,  5.7451,  0.5275,  0.3504,  -6.2281,  -12.9212,  -14.0843,  -20.5964,  -26.6432,  -31.2855,
+  18.9039,  18.0327,  13.6297,  9.7561,  7.4319,  5.3744,  2.9646,  1.7415,  0.6716,  0.6859,  2.7446,  0.5342,  -4.3187,  -6.1877,  -6.9311,  -9.8734,  -11.9041,  -9.1281,  -8.9591,  -25.169,
+  6.4513,  6.7843,  9.4438,  12.9549,  16.4801,  14.9093,  8.2954,  1.6877,  -2.5193,  -4.4922,  -6.7348,  -6.9853,  -4.6783,  0.7181,  1.0483,  -5.1128,  -1.1161,  -7.5305,  -12.398,  -27.2058
+};
+  /* /home/david/codec2-dev/src/codebook/train_120_2.txt */
+static const float codes1[] = {
+  -1.2668,  -1.2477,  -0.0681,  3.8419,  -0.0693,  -1.7919,  -1.5943,  0.8402,  0.155,  -3.1526,  -3.0204,  0.7337,  -0.2603,  1.659,  0.023,  5.5893,  -2.4959,  1.9604,  -0.6348,  0.7999,
+  2.6673,  1.4923,  1.1408,  -0.7478,  -1.0755,  -1.3421,  -0.4884,  0.2535,  0.2951,  1.5088,  1.9447,  -2.662,  2.3751,  1.5298,  4.1357,  -6.563,  -2.1766,  -2.7535,  -0.7706,  1.2362,
+  -0.6415,  -0.4348,  -1.2178,  -0.987,  -1.1057,  -2.1421,  -2.3594,  -0.4977,  -4.1484,  -4.712,  5.5425,  3.0695,  3.661,  2.9729,  2.4379,  -1.6136,  -1.3052,  2.1342,  1.9164,  -0.5692,
+  1.593,  -1.1175,  -1.2476,  1.6203,  2.5315,  2.3427,  -0.5223,  -3.1063,  -2.1739,  -1.4774,  -2.6108,  -3.5842,  -0.3828,  -0.1511,  0.8929,  2.5717,  -1.7657,  1.8954,  6.0193,  -1.3272,
+  -0.2102,  -0.3681,  -1.2724,  -1.152,  -0.3715,  -0.5633,  -2.5238,  -1.768,  4.7356,  5.6452,  0.862,  0.875,  -0.8932,  -1.5918,  -1.4047,  -0.072,  -0.608,  -0.7876,  1.3972,  0.0717,
+  5.1178,  -1.5391,  -4.2881,  -1.9745,  1.3515,  2.4014,  0.9329,  3.4647,  -2.4062,  -0.4224,  2.8708,  -1.6053,  -3.1492,  -2.6783,  -2.6937,  -4.4645,  1.8599,  -0.5456,  3.891,  3.877,
+  -1.7119,  -1.0101,  -0.5002,  -1.7849,  -0.4884,  0.2279,  -0.8335,  -1.0083,  -1.2819,  0.1129,  -1.3674,  -1.3338,  0.929,  3.0765,  2.6339,  3.5627,  -2.2713,  0.6565,  -1.2099,  3.6022,
+  -1.5938,  -1.3264,  0.9856,  2.8765,  2.37,  1.2528,  1.2586,  -1.2453,  -1.3974,  -1.4988,  -1.6309,  -1.2183,  -0.1625,  -0.869,  0.003,  -2.0081,  1.358,  2.9585,  3.3396,  -3.452,
+  -1.368,  -0.6304,  -2.5755,  -1.2397,  4.9487,  2.7251,  1.4675,  -0.1832,  -0.3932,  1.4723,  1.741,  0.6216,  -1.0849,  -0.7112,  -0.3751,  -1.7539,  0.1222,  1.9858,  -0.5248,  -4.2444,
+  -1.2786,  -0.2384,  0.6718,  2.9763,  -1.6959,  6.4607,  -3.9459,  -2.056,  -2.7306,  -0.2583,  0.0389,  -3.6271,  -4.0721,  0.826,  0.8112,  2.8769,  2.24,  0.5444,  0.3571,  2.0995,
+  2.5196,  2.3359,  1.662,  0.625,  -1.0528,  -0.9133,  1.8668,  1.2853,  1.4368,  1.4676,  1.1301,  1.3664,  1.1076,  -3.2853,  -0.453,  0.4467,  -4.7302,  -3.8149,  -3.9866,  0.9865,
+  0.1738,  1.294,  1.3514,  -0.3684,  -0.7078,  -0.2329,  1.3467,  -1.0678,  -0.0262,  0.2448,  -0.8418,  -0.391,  2.7415,  2.9948,  -4.5965,  -0.1192,  0.2496,  0.4684,  0.0669,  -2.5805,
+  0.2482,  -1.3236,  -1.481,  0.9433,  3.4287,  2.2233,  8.9344,  -1.1138,  0.4585,  -3.747,  3.0416,  -2.7394,  2.288,  1.6598,  -3.6439,  0.0633,  -2.7363,  -1.2617,  -3.1924,  -2.05,
+  1.4672,  -1.3248,  -0.5511,  1.4512,  -0.471,  -1.2381,  2.9453,  -2.3244,  2.3249,  -2.1969,  0.9414,  -1.9926,  0.5254,  0.0792,  -3.2076,  -2.414,  3.5291,  3.5738,  -0.0613,  -1.0556,
+  1.556,  0.0091,  0.077,  2.8542,  -1.4594,  -2.0102,  0.544,  2.8119,  -0.2925,  -0.7111,  0.9589,  -1.6923,  -1.8606,  1.104,  -1.6733,  -0.0895,  3.6894,  2.7628,  -6.9922,  0.4138,
+  -1.5539,  0.682,  1.4458,  0.4297,  -0.4115,  -1.3266,  0.5024,  -0.6975,  -0.382,  1.284,  0.9597,  -1.0561,  2.2198,  0.1292,  1.4343,  3.0313,  -3.9845,  0.6776,  0.338,  -3.7217,
+  -2.0283,  -1.5216,  1.0103,  4.8788,  3.7028,  4.4,  -0.3076,  2.4853,  2.2296,  -1.5213,  0.436,  -5.9903,  -2.6578,  -2.3985,  -2.0127,  1.3737,  -3.795,  2.3105,  -0.2099,  -0.3839,
+  -1.7339,  -0.9861,  -0.2078,  -1.2579,  2.5808,  -0.9255,  3.2388,  1.0999,  3.6754,  4.6424,  1.9111,  1.4716,  2.7531,  -0.2725,  -0.3573,  -0.5392,  -4.2109,  -6.4662,  -2.3713,  -2.0442,
+  0.7177,  1.4094,  0.7205,  6.8683,  1.7836,  7.1562,  -2.9368,  3.4036,  -0.6064,  2.3377,  2.8714,  -7.0408,  -9.7129,  4.1278,  -3.4444,  -5.9919,  5.5073,  -0.8996,  -7.5142,  1.2434,
+  0.8042,  1.5886,  0.8754,  -0.4378,  0.2336,  0.0424,  -0.1245,  0.0847,  0.6402,  2.6508,  1.6375,  -3.2393,  -2.2823,  -2.1435,  -1.5628,  0.4271,  2.2571,  2.5048,  -1.5933,  -2.3629,
+  0.6292,  1.1956,  0.8357,  -0.8634,  -0.1796,  1.8589,  0.694,  2.8309,  2.5569,  -0.4253,  0.2913,  0.7772,  1.418,  3.421,  -1.9468,  4.2236,  -7.3361,  -3.7802,  -3.598,  -2.6029,
+  1.9034,  -0.7126,  -2.3343,  0.2344,  3.6545,  3.9405,  3.0203,  0.1937,  -1.1906,  -1.9012,  -0.6667,  -1.259,  -1.1021,  -2.665,  0.14,  -1.4183,  -1.2342,  0.0547,  0.1519,  1.1906,
+  -3.6125,  -2.2485,  -1.082,  -1.9912,  -1.1521,  -2.2527,  -2.5383,  0.932,  1.1572,  2.023,  1.6579,  1.3763,  6.4432,  2.1652,  -2.0259,  1.9724,  3.2824,  -0.4615,  -1.1909,  -2.4539,
+  -1.153,  -2.179,  -0.7355,  -2.0941,  0.6246,  1.7502,  -3.3266,  -3.4374,  -2.6486,  -2.2938,  0.9286,  1.3396,  -2.1323,  0.2739,  1.2664,  4.4111,  1.3864,  3.905,  2.8286,  1.2861,
+  -1.9752,  0.7423,  2.4137,  1.8854,  -1.1393,  -2.5802,  -2.9355,  -3.674,  -1.8244,  0.3099,  6.1403,  4.6215,  -2.0636,  -3.7172,  -0.94,  1.424,  -0.3669,  2.0205,  0.6217,  1.0369,
+  -0.1561,  3.9621,  -1.3649,  0.2912,  3.5366,  0.8537,  -0.9376,  -3.7333,  -6.5447,  -1.2107,  3.3183,  2.5758,  1.9693,  -4.869,  0.6212,  0.0985,  1.5746,  0.2433,  -2.6173,  2.389,
+  0.6849,  -1.1521,  -2.0382,  -0.8953,  0.8771,  1.1996,  -0.9704,  -1.3679,  -1.146,  0.0582,  0.2636,  -1.9785,  0.5235,  1.6427,  0.6362,  0.7411,  5.6052,  -0.3533,  0.6579,  -2.9883,
+  0.5989,  -3.9928,  -2.1937,  3.8742,  2.0056,  2.3132,  -0.4478,  -2.0855,  -4.3607,  -2.126,  5.3544,  1.9827,  5.3407,  -0.8346,  -2.4624,  1.1729,  -4.3825,  0.7623,  -1.9429,  1.424,
+  -3.3103,  0.0394,  2.0113,  2.6733,  1.2484,  -0.2186,  0.1156,  -0.4856,  2.4501,  0.8179,  -1.1164,  -2.1952,  -0.9719,  2.0728,  0.4002,  1.1891,  1.7518,  -1.2571,  -3.3136,  -1.9012,
+  1.886,  6.9767,  2.4311,  -2.0414,  3.91,  5.5378,  -1.7478,  -0.8304,  2.8523,  -1.4075,  0.1309,  1.8232,  -2.8868,  -7.5003,  -3.4867,  -3.2756,  -2.8584,  6.2611,  -7.4682,  1.694,
+  3.5074,  1.3392,  1.0862,  2.9814,  0.8158,  -2.616,  -2.3837,  -0.8255,  -0.1595,  2.0087,  -2.8876,  -2.4727,  -1.3574,  -1.2864,  -1.5711,  -1.0772,  0.4648,  2.7262,  2.1044,  -0.397,
+  -0.143,  -0.9788,  -2.1195,  -0.7774,  4.0804,  3.7123,  1.5082,  0.2869,  -2.5968,  -2.0127,  1.5147,  3.7486,  3.2447,  0.6959,  0.3308,  -2.4516,  -3.4598,  -4.1669,  -0.687,  0.2709,
+  0.0724,  0.3235,  -1.9536,  -2.7454,  -3.3392,  -1.9023,  -1.015,  0.7511,  -0.0539,  -2.8386,  5.2737,  5.1053,  1.4372,  1.4046,  1.4504,  2.4912,  -2.6526,  -0.6188,  -0.653,  -0.5369,
+  -6.955,  1.3233,  4.3542,  2.9502,  0.9929,  -0.1186,  -0.8657,  -2.3452,  3.5061,  2.8348,  -4.1741,  -4.1264,  4.697,  3.0117,  -0.2849,  -8.0081,  3.4452,  0.7819,  -2.7443,  1.7251,
+  -4.0878,  -0.8849,  -4.7521,  5.0067,  -3.351,  -4.8233,  -6.6328,  4.8752,  -0.7474,  3.8614,  2.6271,  0.9119,  1.0371,  2.2968,  4.316,  -3.7042,  0.99,  0.496,  4.7952,  -2.23,
+  0.5901,  2.0654,  1.7824,  -0.557,  0.4874,  2.7659,  0.8232,  -0.1306,  -0.6795,  -1.3143,  -1.248,  0.9969,  2.0563,  0.1625,  0.7346,  0.0223,  -1.6836,  -2.9087,  -4.1058,  0.1406,
+  -0.5074,  -0.8373,  -0.8579,  -0.046,  -0.0854,  -1.4221,  -0.6935,  2.5302,  2.2014,  2.2225,  0.5896,  1.2715,  -0.7624,  -2.7997,  -5.3296,  4.0372,  3.2176,  -1.4146,  -1.3705,  0.0565,
+  -3.819,  -1.1051,  1.5169,  -0.5542,  -1.5591,  0.2921,  -2.1144,  1.6664,  2.8275,  0.7745,  2.6977,  4.4021,  -0.201,  0.0685,  1.3158,  -0.8045,  -5.9834,  1.7874,  -2.1592,  0.9509,
+  0.6749,  -0.0635,  0.3751,  0.6561,  0.4718,  -2.3144,  -4.9191,  -3.0907,  0.5499,  -0.3498,  1.237,  2.6699,  1.5353,  1.6809,  1.2117,  -1.3733,  0.0977,  1.361,  0.0102,  -0.4207,
+  0.8139,  -2.9454,  -1.1694,  1.1826,  3.5742,  4.3331,  1.4143,  1.7017,  -1.2428,  4.8459,  -4.4642,  -0.0684,  -1.7273,  -0.1932,  -2.6041,  -1.4272,  0.2873,  -0.9676,  -0.1422,  -1.2013,
+  -1.869,  1.2475,  -2.8884,  -0.3842,  -0.3588,  2.7759,  -2.006,  -2.2023,  -2.6599,  -2.5791,  -3.1221,  3.2645,  1.8131,  2.863,  6.3144,  -4.2619,  0.7589,  -0.7608,  4.8657,  -0.8104,
+  2.3449,  0.3057,  -2.2411,  -1.3084,  0.6572,  -0.379,  0.2674,  0.5337,  0.4996,  0.8832,  2.3616,  3.9339,  4.7846,  -2.7473,  -0.5167,  -0.0864,  0.9288,  -4.3018,  -4.0903,  -1.8294,
+  2.9658,  2.7467,  -1.9276,  -4.0009,  -0.7257,  -0.6616,  -2.0255,  -1.2898,  0.3022,  1.581,  3.0521,  2.579,  -3.2369,  -0.4791,  0.4455,  0.1138,  1.1032,  0.9003,  -1.5708,  0.1285,
+  5.2204,  -2.819,  0.8203,  0.5992,  -1.3205,  -2.1549,  5.0256,  -1.605,  0.5506,  -2.8092,  -0.2831,  -1.6376,  -1.8233,  -0.0177,  2.5319,  2.0586,  0.9166,  -1.5417,  -0.3071,  -1.4039,
+  0.109,  -0.1359,  -0.4821,  -0.506,  -1.1903,  -0.1205,  1.301,  0.0989,  0.228,  1.3298,  1.4648,  0.728,  0.0076,  -1.4837,  -0.1633,  1.2525,  0.9437,  -0.0019,  -3.9783,  0.5988,
+  -4.0941,  -3.422,  0.4966,  -5.4678,  6.0636,  1.1749,  -0.183,  3.3518,  3.548,  1.4243,  2.5791,  -5.9065,  -1.8723,  -1.6703,  1.399,  6.8845,  1.8643,  -1.2344,  -3.7475,  -1.188,
+  3.5819,  1.2282,  -0.2187,  -0.8194,  -0.0683,  0.6784,  0.9405,  -0.1871,  -1.0635,  -2.3089,  -1.7476,  -2.3377,  -1.8039,  -0.2123,  0.7402,  0.881,  0.7063,  -3.8015,  4.2698,  1.5426,
+  -0.7508,  -2.5319,  -1.4606,  1.0638,  -3.8848,  1.206,  2.6878,  -1.2315,  -0.1629,  -2.273,  -3.3361,  -1.6208,  1.9855,  3.4308,  -0.212,  -1.4559,  -0.3738,  2.3568,  2.3629,  4.2004,
+  1.5564,  1.6137,  1.4225,  1.6668,  1.3266,  0.046,  0.1831,  -0.3664,  -1.4348,  2.569,  2.2918,  1.6955,  1.668,  -1.3807,  -1.0884,  -1.098,  -0.5844,  -1.0295,  -3.6955,  -5.3616,
+  1.7128,  -1.8066,  -4.0653,  -3.8214,  -0.9531,  3.4797,  0.7961,  -2.4955,  -2.7851,  0.0025,  0.7872,  1.0652,  1.5456,  -0.4352,  1.9173,  4.6258,  0.3691,  -0.1501,  -0.2351,  0.4458,
+  -1.6777,  -3.1299,  -1.6947,  -1.1535,  -2.1999,  -3.2226,  -0.9846,  -2.1533,  -0.6467,  2.0938,  2.1307,  2.9065,  1.5181,  3.0875,  0.0486,  -0.2157,  1.3461,  0.7741,  2.732,  0.4413,
+  -2.0098,  -0.0651,  -1.1313,  -3.1454,  -1.8173,  0.4664,  2.3278,  3.1806,  -3.0726,  -1.5969,  3.6994,  0.6478,  -0.6833,  1.0635,  1.1405,  6.7102,  -4.8934,  -4.2029,  3.4752,  -0.0933,
+  3.0911,  3.132,  3.6764,  1.2247,  2.0977,  -0.4399,  -3.947,  1.4276,  -0.2596,  0.5511,  -6.4999,  -0.9385,  3.2215,  1.7397,  -2.0786,  -2.616,  -3.015,  -2.0586,  1.9218,  -0.2304,
+  0.5955,  -0.9572,  -3.8115,  -1.2133,  0.96,  3.0247,  8.636,  5.7851,  6.1244,  0.7094,  -2.441,  -1.1712,  -1.7901,  -3.5399,  -2.8318,  -2.5468,  -4.9596,  -0.6022,  0.6141,  -0.5845,
+  12.5835,  1.8094,  0.1352,  1.7718,  0.9427,  -1.369,  7.1277,  0.0421,  -2.3404,  -4.665,  1.4653,  -2.488,  2.6056,  -10.3828,  -8.1067,  4.1108,  -1.2481,  -1.833,  -2.7827,  2.6214,
+  2.9658,  -0.2617,  0.2806,  -0.2164,  2.855,  1.9755,  -3.5301,  -1.235,  0.9311,  0.8713,  -2.2265,  -0.6005,  2.6386,  2.7666,  -2.3603,  -2.5163,  1.6854,  1.0161,  -7.8883,  2.8489,
+  -0.9445,  0.6006,  -1.3214,  -5.0651,  -2.1702,  -0.0289,  0.1003,  2.2883,  0.0424,  3.4686,  2.0494,  1.6327,  -1.6152,  0.122,  -2.8666,  -2.2261,  4.9579,  -2.2581,  -2.7323,  5.9663,
+  -1.3666,  -0.2364,  -0.3999,  -0.9988,  -2.0227,  -0.061,  -0.5411,  -2.2113,  -0.2283,  -1.715,  1.0239,  4.276,  1.9603,  -3.0526,  -2.5894,  0.8611,  5.2528,  3.4951,  -2.2336,  0.7875,
+  4.7609,  3.7023,  0.7955,  -3.1291,  -1.3671,  0.8798,  -0.9947,  0.2668,  0.5762,  -0.9479,  -4.5541,  -0.6922,  0.0699,  -5.8412,  4.2302,  5.0652,  1.3544,  -2.4661,  -0.6224,  -1.0865,
+  -2.6815,  -0.9958,  1.6109,  -1.7618,  -2.5561,  1.0357,  -1.5863,  -2.2811,  3.4491,  1.1806,  -0.2855,  -0.138,  -0.0202,  5.6861,  0.8289,  -1.0913,  0.5986,  -1.1493,  3.2455,  -3.0884,
+  1.7353,  3.1908,  5.0898,  -0.4602,  0.0751,  -2.1427,  -5.091,  -3.1667,  -3.3291,  1.9531,  0.4802,  -4.8101,  2.2518,  2.438,  0.6439,  -7.3548,  -0.0689,  1.8997,  5.717,  0.9491,
+  -1.1588,  -3.1119,  -3.4525,  0.2538,  1.3345,  -1.05,  -0.387,  -0.0472,  0.1522,  4.0806,  2.8886,  3.8741,  -1.9507,  -2.9183,  -0.3828,  -0.0805,  0.4136,  1.1466,  -3.1863,  3.5818,
+  -4.1654,  -5.7362,  -5.0041,  -0.9889,  4.1884,  4.8135,  1.5658,  -2.3781,  0.8425,  7.5151,  7.3977,  3.9243,  0.6283,  0.9194,  -5.0741,  -1.9566,  0.21,  -4.9786,  0.876,  -2.5989,
+  -5.3114,  2.2992,  -1.9803,  1.215,  9.1545,  -2.196,  -2.8749,  9.6686,  0.5512,  -4.17,  -1.1338,  -4.1549,  1.6645,  -3.1643,  -1.78,  4.9896,  0.339,  -0.0421,  -1.0391,  -2.0347,
+  1.074,  2.184,  0.9247,  2.0617,  -2.1994,  -4.0653,  -1.5118,  -0.9397,  1.3781,  2.9104,  -0.8864,  8.5382,  0.5495,  -3.5922,  -0.2482,  -0.5485,  -0.9604,  -1.8453,  -3.1808,  0.3575,
+  3.5141,  2.7621,  1.2101,  -0.3665,  -1.1827,  -0.5351,  0.4822,  0.7598,  0.8241,  1.4976,  -0.8943,  -2.8067,  -2.3512,  -2.0448,  0.3706,  -0.9201,  -3.9192,  1.1431,  0.4761,  1.9809,
+  -1.7817,  1.1939,  -1.2195,  1.7524,  -4.7374,  1.152,  0.0973,  1.5475,  2.2848,  -7.787,  2.0346,  0.5213,  2.8861,  3.1077,  1.1974,  2.3936,  -1.4248,  -0.2888,  -1.4706,  -1.4588,
+  -0.7677,  -2.0426,  -2.9918,  -1.8722,  -1.4336,  0.4207,  1.4107,  1.0509,  -0.1714,  0.2221,  1.3054,  0.5884,  3.1454,  1.8747,  0.151,  -0.5701,  0.5457,  2.7058,  -0.0854,  -3.4859,
+  1.6593,  1.0024,  0.3202,  1.0267,  -0.2368,  0.1208,  -0.7272,  -1.0487,  0.2686,  -1.0197,  -1.3131,  4.1829,  1.0297,  1.7779,  -3.0898,  -0.7777,  -4.5532,  2.1765,  -0.31,  -0.4886,
+  2.9341,  -0.2895,  -2.421,  0.9438,  2.949,  1.2447,  -0.4279,  -0.4133,  -0.2487,  0.6464,  0.1859,  -0.8613,  0.069,  -2.0024,  -3.5783,  -0.9123,  -2.3469,  0.3089,  5.3909,  -1.171,
+  13.8818,  0.6217,  -0.6459,  -3.4218,  0.8331,  0.8918,  2.2009,  4.0596,  -3.038,  -7.3862,  -3.2105,  -2.2108,  4.7972,  -5.3735,  3.887,  -1.819,  -0.5123,  0.9752,  -3.6921,  -0.8383,
+  0.2536,  -11.0226,  4.4625,  -7.9396,  8.6657,  2.6088,  -1.0215,  0.4492,  -5.0641,  2.7194,  1.1735,  2.207,  3.3733,  -0.2605,  5.5319,  3.5989,  0.2759,  -3.6185,  -2.9338,  -3.4591,
+  -0.2533,  -1.2245,  -1.1924,  -0.1962,  0.6099,  -2.1289,  -2.0002,  -2.039,  -1.5592,  0.7879,  0.1165,  -0.9325,  -1.5485,  0.4552,  0.3883,  1.9054,  2.3495,  3.9138,  2.3594,  0.1886,
+  0.175,  3.7528,  1.6899,  -4.327,  -5.0437,  -3.141,  -4.7768,  -1.9628,  -4.5893,  5.9435,  -9.6773,  -0.4601,  3.0571,  1.2797,  0.1161,  3.5574,  3.7157,  -2.0222,  5.9308,  6.7823,
+  -0.6999,  -2.9933,  -3.6606,  -0.6207,  -1.4032,  -1.1364,  0.253,  -0.9004,  -2.7685,  -4.3142,  -0.7561,  0.8142,  -0.4715,  0.8444,  2.0053,  0.5983,  3.3363,  4.4913,  6.9146,  0.4673,
+  1.0959,  -0.0886,  0.2379,  3.2725,  1.2016,  -1.1581,  -1.364,  -0.6268,  -0.3678,  0.9051,  0.7593,  -2.2902,  -1.4578,  0.6349,  0.5115,  -4.4984,  2.2315,  2.2535,  -2.7867,  1.5345,
+  3.6055,  3.8842,  2.1794,  -0.7568,  -1.05,  -2.1686,  -0.6731,  -2.0718,  0.8001,  -0.6819,  1.1112,  0.5707,  -2.4862,  3.1489,  2.6767,  2.5134,  -1.9147,  -4.1519,  -2.4548,  -2.0802,
+  -1.9388,  -0.7447,  -0.8349,  0.1123,  0.1251,  -1.3476,  -2.6413,  -0.477,  5.6864,  -1.8563,  -3.3514,  -0.5309,  -1.6295,  -1.3453,  -0.4664,  4.593,  1.1909,  2.9264,  0.9356,  1.5944,
+  0.5951,  -0.4177,  -0.1304,  0.5462,  -1.3265,  1.4534,  1.6425,  0.973,  0.8946,  2.1586,  4.2557,  0.8968,  -5.0524,  -1.9576,  2.6089,  0.6571,  0.7918,  -2.2504,  -4.5907,  -1.748,
+  -1.6456,  -2.0706,  -2.4462,  -2.5983,  -2.5056,  2.0863,  -0.9159,  -0.8806,  -0.8052,  -0.7776,  1.0285,  0.4522,  1.5131,  3.453,  4.933,  -2.7752,  1.775,  2.1982,  -0.0181,  -0.0006,
+  2.2117,  0.6658,  -0.1647,  -0.7769,  -0.3291,  -0.0686,  3.183,  1.8603,  1.0488,  -0.7866,  -1.0352,  1.6465,  0.2395,  0.3989,  -1.2496,  -1.9498,  -2.6996,  -7.5216,  1.332,  3.9951,
+  1.0405,  1.3681,  2.7153,  3.0279,  2.8206,  1.9933,  -1.5434,  -2.0223,  -1.049,  -1.2756,  -0.1434,  0.2554,  0.8858,  1.3178,  0.3714,  3.567,  -3.1912,  -1.0147,  -3.0243,  -6.0993,
+  -0.8348,  -2.4017,  -3.6731,  -2.0399,  -0.2474,  -1.064,  -1.1488,  1.3352,  2.8367,  5.1498,  -0.0673,  1.7148,  2.0672,  0.78,  -2.8302,  2.8981,  -0.7525,  1.3119,  -2.4119,  -0.6222,
+  3.0927,  2.0509,  2.4548,  -1.3001,  -3.9942,  -0.7486,  2.8523,  0.1569,  -4.3404,  -10.5627,  4.2087,  4.2968,  2.7013,  -1.1646,  0.2008,  -2.4272,  1.8708,  0.5192,  -2.3092,  2.4416,
+  0.6449,  -3.5216,  -3.8362,  2.1329,  -1.2999,  0.6434,  -2.5079,  3.1409,  -0.943,  2.1409,  -0.9005,  2.6639,  5.842,  2.2508,  -0.1834,  -3.5407,  -2.0329,  -1.9827,  -0.2675,  1.5565,
+  5.1512,  4.1361,  0.9497,  -3.1897,  -6.0608,  -4.8346,  -0.7128,  -2.1849,  -2.1809,  0.1265,  0.3295,  0.2665,  1.1233,  -0.4722,  2.7945,  1.1909,  0.4093,  1.9529,  0.638,  0.5674,
+  -2.0255,  1.8944,  3.261,  -0.6543,  -0.1603,  1.6419,  1.8339,  -4.1284,  -1.6495,  -7.4417,  2.7611,  3.0349,  -5.4696,  5.3754,  0.2729,  5.17,  0.7296,  -0.1265,  -1.6533,  -2.6659,
+  -7.1882,  -6.8851,  -0.9549,  2.6573,  1.6288,  -0.3149,  -2.2361,  1.6706,  4.0565,  3.2723,  -2.0478,  -0.6505,  2.7769,  4.9536,  1.831,  -4.1026,  -0.854,  2.2409,  0.8671,  -0.7209,
+  0.8703,  1.1461,  2.9551,  0.5102,  0.4539,  9.1307,  -3.4339,  -1.5513,  -2.2902,  -4.1038,  -6.058,  -0.8757,  3.583,  2.5081,  -1.9449,  0.3605,  0.8645,  0.6768,  -0.2206,  -2.5809,
+  -4.5091,  -1.0618,  1.6342,  0.589,  1.0199,  0.707,  -0.4636,  -0.7393,  -2.0902,  -4.3948,  -1.8491,  2.8967,  1.9263,  0.6394,  4.9955,  3.9485,  -0.2145,  -1.3652,  -1.4955,  -0.1736,
+  -1.2527,  -0.6868,  0.0359,  0.5854,  0.7286,  -0.5988,  -1.0892,  -1.2358,  -0.5524,  -1.8766,  -4.8554,  1.3154,  3.0969,  1.2141,  0.4785,  0.5435,  0.966,  0.9526,  2.5969,  -0.3662,
+  -3.4429,  -2.5359,  -0.7902,  1.6794,  1.395,  0.9304,  0.5281,  2.0451,  -0.282,  -0.762,  -2.3113,  -2.5279,  -1.2407,  -4.6199,  3.9276,  -1.3637,  2.0692,  2.0266,  2.415,  2.8601,
+  -0.0841,  -1.4504,  -2.5295,  -2.1914,  0.016,  -1.5806,  -3.8581,  -1.8751,  1.241,  1.4792,  -0.0268,  -3.0304,  1.1672,  3.1034,  -0.0043,  -1.775,  1.0722,  5.8103,  3.7335,  0.783,
+  -1.2601,  -0.9248,  -0.9753,  -1.158,  -0.4657,  0.9286,  0.4457,  -0.7164,  2.9298,  6.0232,  1.1288,  -9.2201,  -2.6002,  1.0866,  3.5907,  -0.3994,  -0.8783,  -0.4493,  3.0463,  -0.132,
+  -2.6865,  -1.7683,  0.5719,  4.2697,  0.4434,  0.9403,  -0.1787,  -3.9995,  -1.4954,  -2.9666,  0.5871,  0.7458,  -0.5643,  -3.3758,  2.4009,  1.363,  3.2345,  2.9305,  0.6423,  -1.0943,
+  0.2605,  -0.1269,  0.1894,  0.8801,  5.6065,  4.4842,  -0.336,  1.6337,  -1.008,  2.2349,  -1.3371,  -3.4195,  -1.5849,  3.4658,  -2.7632,  -2.8878,  0.2535,  -1.0857,  -3.4858,  -0.9736,
+  0.5903,  -1.1309,  -3.8731,  -2.8181,  0.6957,  -2.193,  -3.7976,  -0.1684,  0.3131,  0.8609,  0.0568,  -0.1356,  5.9915,  2.3704,  3.984,  0.584,  -1.9366,  -2.6479,  0.4937,  2.7608,
+  -1.4917,  0.6707,  -1.8279,  0.4736,  -4.3226,  7.6508,  -0.677,  -1.0388,  1.6577,  3.4357,  2.121,  -1.6783,  -1.9394,  -0.4857,  0.0446,  -2.1769,  -1.5641,  1.5895,  1.475,  -1.9161,
+  -2.4617,  -1.4865,  0.9268,  3.7356,  1.9298,  -1.0879,  -0.9003,  -0.6573,  -0.4536,  1.1463,  2.5279,  -0.9025,  -2.1547,  0.5579,  -1.4546,  -2.5618,  -1.102,  1.7633,  4.9058,  -2.2707,
+  3.2436,  2.0698,  1.3674,  -1.4618,  -0.4269,  1.2764,  0.316,  1.2237,  0.7208,  1.5117,  1.4584,  -0.5527,  -0.7757,  -2.7217,  -4.0792,  1.8261,  2.7197,  -3.9546,  -1.7508,  -2.0101,
+  0.2659,  1.9357,  0.5705,  -1.8509,  -5.0017,  -3.7512,  -2.7574,  0.2996,  -1.125,  0.6895,  2.7521,  3.709,  3.4556,  6.5334,  -3.5389,  -3.897,  -2.9436,  0.765,  1.5177,  2.3717,
+  -1.2532,  -0.7651,  -0.7634,  -1.69,  -2.3167,  -1.0574,  0.9291,  -0.7963,  -1.477,  -1.6646,  0.5558,  0.7009,  3.4059,  9.2719,  1.4172,  2.4588,  -0.7901,  -3.7873,  -1.0613,  -1.3173,
+  3.2264,  0.6063,  -2.4159,  -3.8529,  -1.9936,  2.6889,  2.5115,  0.8341,  0.8209,  1.2008,  0.7255,  -2.1489,  -1.1543,  -0.6443,  2.0479,  -0.7011,  -0.5619,  -0.082,  0.5538,  -1.6613,
+  0.89,  0.2673,  1.2328,  -0.1459,  2.5186,  2.3429,  -0.5461,  -0.5497,  1.9452,  5.1637,  1.5156,  -3.9805,  -1.5621,  -1.5331,  -2.7711,  -2.2357,  0.7958,  -1.6083,  -2.3152,  0.5758,
+  4.0233,  3.7838,  3.0862,  2.468,  -0.8644,  -2.4804,  -0.9694,  -1.9035,  -3.4966,  -3.959,  -3.9724,  -1.208,  -1.6237,  0.7915,  0.4354,  0.8419,  1.1287,  1.8538,  2.3476,  -0.2827,
+  -0.5315,  1.6742,  2.6296,  -0.5391,  -1.8812,  2.7171,  6.8646,  3.9934,  -2.0577,  -0.8537,  -4.3316,  -2.4473,  -2.8864,  -0.3456,  -1.9169,  -1.4494,  0.4578,  1.9608,  -0.1673,  -0.8898,
+  -2.1559,  -2.48,  -1.5001,  1.3457,  3.3362,  2.6367,  1.4331,  2.3397,  3.7557,  3.4063,  1.6588,  1.2723,  -0.3658,  0.5614,  -2.5827,  -5.6096,  -3.4952,  -4.1966,  -1.5564,  2.1965,
+  0.1567,  -1.6324,  -1.8735,  -2.1011,  0.8687,  2.8596,  1.0227,  5.0782,  -3.8186,  -0.4012,  -1.0627,  -1.0858,  2.3105,  2.5822,  -1.0014,  -0.6915,  1.2628,  0.1273,  -4.312,  1.7113,
+  0.5493,  0.1877,  -0.3065,  0.0805,  0.17,  -0.4682,  -0.7192,  0.7521,  1.1935,  -1.2445,  0.5061,  3.0407,  3.3122,  2.9044,  2.0613,  -2.6946,  -2.8479,  -1.4855,  -3.4536,  -1.5377,
+  1.2611,  1.2112,  -0.4954,  1.5849,  2.8817,  0.5597,  -3.2189,  -1.8993,  -2.3996,  0.0235,  -0.927,  -1.1263,  -1.6443,  -3.5163,  -1.2543,  1.841,  4.5628,  1.0754,  -0.1607,  1.6406,
+  -0.8759,  -1.6975,  0.2532,  6.4042,  -3.4246,  -2.9858,  1.9661,  -3.2513,  -4.0109,  -0.5134,  2.5545,  -3.0437,  -2.1093,  -3.6915,  4.1398,  6.0036,  -1.3456,  1.3628,  -1.0285,  5.294,
+  8.8405,  -7.236,  2.8239,  7.1563,  -1.4248,  -8.041,  -1.9196,  1.8187,  -0.932,  -3.1134,  1.9133,  4.5783,  5.5866,  -1.744,  -0.1615,  -9.2039,  4.4457,  -2.5424,  2.5822,  -3.4268,
+  -1.9594,  -0.144,  -0.0014,  -0.5248,  -1.274,  1.9184,  0.2637,  0.9658,  3.9879,  -1.7646,  0.8739,  3.6824,  -1.4748,  -0.5493,  4.194,  -0.5892,  0.9704,  -2.3393,  -5.2036,  -1.0319,
+  -1.8153,  -0.8777,  -1.3975,  -2.8688,  -1.315,  0.6005,  2.0795,  2.0158,  -0.0187,  2.3273,  5.2446,  3.191,  0.542,  -1.0394,  1.3294,  -4.655,  -1.5318,  -1.6999,  0.2573,  -0.3684,
+  4.3069,  1.2137,  -1.8464,  -3.0026,  -0.9539,  3.1554,  3.4215,  2.0922,  0.4828,  1.6102,  1.1857,  1.5577,  -1.8593,  -2.9907,  -3.064,  -4.6355,  -1.6614,  1.3592,  1.5116,  -1.8833,
+  0.6407,  1.1519,  1.5429,  -0.7369,  -1.7269,  -1.6671,  -0.129,  -0.7049,  0.8116,  -1.2198,  -4.0157,  -5.1437,  -3.1965,  2.3418,  0.7111,  2.6992,  0.5585,  1.9829,  4.9644,  1.1355,
+  0.6364,  2.1072,  0.987,  -5.1572,  -4.3363,  -1.0839,  -1.3521,  1.8709,  0.8132,  -0.2938,  -0.2079,  -2.5242,  -0.8999,  2.3401,  0.7392,  3.1549,  3.0568,  -1.1375,  0.0963,  1.1908,
+  -0.0136,  -2.4241,  -0.4209,  1.6339,  3.4114,  3.5889,  -1.41,  -3.5651,  3.1831,  2.0426,  0.5548,  -2.0177,  1.6429,  -3.2634,  1.578,  -4.1305,  -0.9389,  0.1651,  0.4588,  -0.0751,
+  2.0687,  0.8544,  -0.3821,  -0.1978,  1.0057,  2.3289,  3.0174,  -0.333,  2.0178,  -0.6679,  -0.1993,  -1.917,  1.6018,  -0.3834,  0.6526,  1.9588,  0.3355,  -2.0462,  -4.1767,  -5.5379,
+  2.7809,  0.2282,  0.482,  1.9051,  -1.735,  -3.4716,  -3.3685,  -1.3005,  0.1251,  -1.5366,  -1.9516,  -2.1469,  1.2541,  3.7123,  3.039,  0.8154,  2.3154,  2.5014,  0.0685,  -3.7166,
+  -2.7442,  -0.5589,  1.8753,  0.2528,  -1.7122,  -1.5279,  0.3471,  1.3429,  -0.0809,  -1.0979,  -0.5556,  2.8899,  0.2864,  2.18,  1.7006,  -3.4442,  -2.6681,  2.9174,  1.9107,  -1.3132,
+  1.1471,  -0.3191,  -2.5131,  -2.6788,  2.7236,  4.0318,  2.942,  3.1336,  1.5351,  0.48,  -0.0086,  -1.0945,  -1.1975,  -0.4758,  0.1588,  -0.497,  -0.2437,  -3.5219,  -3.3061,  -0.2958,
+  -0.6947,  -3.5085,  -2.7613,  0.0475,  0.2365,  -2.4104,  -0.4597,  -0.9262,  -0.2261,  1.8983,  0.9162,  0.3544,  -1.0767,  2.3229,  2.3748,  -1.6417,  3.4712,  -3.6716,  0.1472,  5.6077,
+  -1.7531,  -0.9915,  -0.4352,  0.4089,  0.189,  -1.7111,  -0.6401,  -0.9353,  -0.5743,  0.3365,  -0.6869,  0.9392,  0.8776,  -0.2201,  0.7815,  -1.7487,  -0.2509,  3.0732,  0.2971,  3.0442,
+  -6.4696,  -1.5332,  1.3136,  7.9582,  4.7035,  0.4178,  -1.4784,  -2.4577,  -0.6662,  -2.4183,  -3.1348,  -2.0591,  -4.3423,  -0.208,  1.5975,  -2.6953,  0.1211,  4.7779,  4.5315,  2.0419,
+  0.8642,  3.0824,  1.7461,  -0.8529,  0.9231,  -0.3502,  -2.7586,  -2.7081,  -1.4853,  1.1577,  2.4953,  -2.0279,  3.1643,  -1.1352,  0.2786,  -0.165,  2.423,  -0.5282,  -0.4006,  -3.7227,
+  -3.9091,  0.2639,  -0.0395,  -5.0339,  1.4635,  7.9381,  -1.8279,  -7.5321,  1.8947,  0.9696,  -7.1991,  7.7502,  4.8838,  -5.2722,  5.2271,  6.4012,  -8.2785,  -5.8271,  0.4487,  7.6786,
+  -0.4051,  0.3015,  -0.5211,  -1.1563,  -1.5548,  -0.8506,  -1.7742,  -0.6679,  0.3853,  3.9695,  3.145,  -3.5632,  -0.3392,  -3.3757,  1.3514,  4.4934,  -1.2754,  -0.4248,  1.0022,  1.2601,
+  -3.0667,  3.2388,  3.6288,  -0.3263,  -3.6989,  -4.3941,  -3.0073,  -2.9882,  -2.7834,  -3.8873,  2.3701,  6.1068,  1.0432,  -2.8444,  0.146,  -2.5272,  1.8208,  2.6818,  7.7176,  0.7699,
+  -0.8674,  0.6588,  -0.0766,  1.935,  3.3452,  2.7012,  0.4707,  -0.8282,  -0.7703,  -3.8252,  -2.8814,  -0.2389,  -1.3895,  -0.9376,  0.2572,  -3.4418,  -2.3763,  -1.8695,  7.4789,  2.6558,
+  0.8567,  1.9741,  0.6363,  2.1993,  1.9072,  2.2211,  3.7376,  -0.0455,  1.3289,  -1.0736,  -4.8817,  -4.0284,  2.4624,  1.0596,  -3.8101,  -3.8498,  0.8895,  -0.5176,  -2.3743,  1.3083,
+  3.7465,  3.5865,  0.1979,  0.4072,  -1.1714,  -1.4598,  -2.1688,  -1.4971,  -1.1953,  -2.8028,  -1.8515,  1.1483,  3.7654,  -2.6485,  1.2635,  -2.4929,  -1.4965,  0.6356,  3.3756,  0.6583,
+  -1.7286,  -0.6675,  0.3769,  1.1159,  0.0587,  1.4828,  1.214,  6.0165,  1.2212,  -3.4526,  -2.4321,  -0.8616,  -2.2663,  -0.0017,  -0.0046,  0.2615,  0.0517,  -0.8546,  0.5801,  -0.1095,
+  3.4455,  1.4668,  -0.0851,  -2.9245,  0.0932,  1.2861,  1.125,  -0.6317,  -4.0005,  -4.4206,  -1.5097,  1.3643,  -0.1238,  -0.8046,  -2.45,  4.2293,  2.9297,  3.2594,  -3.0122,  0.7633,
+  2.2354,  -0.6334,  -2.7256,  -1.7876,  -1.8603,  0.6549,  0.1244,  -1.81,  -1.7636,  -2.7665,  1.0419,  3.6034,  2.7187,  -5.8124,  -0.9848,  2.8478,  -0.3193,  3.4835,  2.5353,  1.2184,
+  3.0602,  4.3425,  2.426,  -0.5623,  -0.8919,  -0.273,  1.3901,  0.4772,  -0.5219,  -1.3754,  0.4815,  2.4087,  -5.0472,  -5.6009,  -2.8901,  -2.4607,  1.8809,  3.5997,  3.9232,  -4.3669,
+  -0.0346,  -0.2122,  -0.229,  -0.9365,  -0.4221,  -1.93,  -2.3572,  -2.9919,  -2.2394,  3.2115,  2.4104,  2.4249,  -0.5682,  1.5001,  -1.3857,  2.614,  -1.8866,  -5.618,  7.3368,  1.3135,
+  -0.4484,  -1.1107,  -1.9143,  -1.2992,  -0.5392,  -1.0181,  -0.6562,  0.5186,  -0.7919,  -1.4379,  -4.0959,  2.4107,  1.5417,  0.0557,  3.4844,  1.7096,  -0.8275,  1.7994,  2.0983,  0.5209,
+  -0.4549,  0.183,  0.2262,  -2.2572,  -1.5931,  -0.7026,  2.6431,  2.6098,  4.0381,  -0.4805,  -2.9134,  -3.5443,  -0.6536,  -2.1551,  2.0956,  1.2393,  0.2979,  0.9155,  -2.0621,  2.5682,
+  -0.1092,  -1.2889,  -2.5682,  -2.3378,  -1.7259,  -0.5628,  -0.6114,  -2.8295,  -2.569,  -3.3678,  -2.2669,  0.6023,  0.3823,  5.9006,  5.7607,  1.9871,  0.6942,  1.2471,  3.2445,  0.4186,
+  0.6515,  1.8638,  -0.3444,  -2.0169,  -0.6995,  -2.9879,  -2.4596,  -1.0847,  -0.8686,  -2.3776,  2.0331,  4.8909,  4.1694,  1.269,  1.4079,  1.9289,  1.882,  -0.9986,  -3.0198,  -3.239,
+  1.7936,  1.2201,  -1.9231,  -2.6761,  1.6107,  7.0585,  8.8031,  2.9894,  -2.3291,  -6.5825,  -1.5641,  3.0126,  -4.0096,  -4.0332,  -0.6223,  -0.5985,  -0.8359,  1.2689,  0.3585,  -2.941,
+  -1.2384,  -0.3295,  2.3565,  3.0657,  3.2204,  1.089,  -0.5456,  0.1283,  2.9904,  -0.097,  -5.2104,  -1.5801,  -2.5751,  -2.3243,  -0.3014,  2.6881,  0.5623,  -1.5424,  -1.9388,  1.5825,
+  -2.6631,  -2.8705,  -3.6445,  -0.1511,  1.0369,  4.6018,  2.7993,  -0.5794,  -0.1152,  0.9196,  4.1279,  -0.7083,  -3.1505,  -2.187,  -2.5145,  -0.8667,  1.9629,  3.781,  1.8562,  -1.6347,
+  -3.7832,  -0.9972,  1.0298,  0.8253,  -2.4369,  -3.3827,  -2.6892,  -0.8231,  -1.082,  -0.0375,  -0.7937,  -1.8433,  -0.5302,  3.8146,  2.3123,  1.6122,  4.1004,  5.6672,  -1.045,  0.0824,
+  -0.1,  -2.02,  -0.5383,  2.2917,  0.8366,  -2.2105,  -0.8495,  2.1052,  3.4989,  -0.0827,  -0.3031,  -1.7154,  1.3463,  5.4572,  -3.0939,  -0.0935,  -1.1704,  -5.241,  2.43,  -0.5476,
+  -3.7789,  -1.9485,  1.8338,  2.9833,  0.6807,  1.8337,  5.1432,  -0.4532,  0.5973,  -0.6042,  0.8753,  -1.5014,  0.4292,  -2.2709,  -1.2993,  -0.1667,  -1.6955,  1.1932,  -6.0865,  4.2353,
+  -0.492,  0.0568,  -2.6837,  -3.2294,  -0.292,  -0.679,  2.7843,  3.0219,  1.7934,  -2.2037,  -3.0967,  1.8829,  0.5782,  -1.6334,  1.9235,  4.5606,  -4.2261,  -0.0121,  2.2982,  -0.3517,
+  -0.6429,  2.5139,  2.3667,  2.2,  -1.8905,  -1.3195,  -0.0575,  -0.672,  2.8832,  0.3828,  0.9744,  2.9334,  -0.6053,  3.2595,  2.5269,  0.0016,  -5.8119,  -0.9627,  -4.8744,  -3.2058,
+  0.8584,  0.9302,  0.363,  -0.3058,  -0.919,  -1.1142,  -3.3748,  -2.621,  0.9921,  -0.044,  -0.2277,  0.806,  1.7478,  2.0581,  0.39,  4.4187,  5.843,  -6.6138,  -3.1191,  -0.068,
+  0.3281,  -0.0986,  -1.1173,  -1.9481,  -2.4515,  -1.0863,  -1.3545,  1.1448,  2.8412,  3.7501,  2.6741,  2.7224,  1.8554,  1.4018,  -3.7195,  -2.9142,  -1.2068,  -4.2062,  2.968,  0.417,
+  0.2181,  -1.3017,  -1.3715,  -0.9326,  -1.1639,  -0.6082,  2.2905,  2.1838,  3.153,  3.3746,  2.0088,  -0.8055,  -1.0486,  0.7007,  -1.796,  -0.3898,  -2.4327,  -2.4057,  -2.1793,  2.506,
+  -2.4912,  -0.4925,  1.9418,  -0.632,  -1.0125,  1.8048,  -1.536,  -1.7457,  -0.3001,  0.5912,  0.4548,  -1.4661,  -1.5177,  -0.5917,  5.6377,  -3.6558,  1.8798,  3.7139,  3.0715,  -3.6543,
+  -1.077,  1.7774,  3.6503,  0.2492,  -2.5625,  -1.2989,  0.3077,  -1.4511,  -0.7454,  -1.0293,  0.9281,  -0.097,  -1.418,  0.5544,  2.007,  3.1415,  2.3666,  -0.7117,  -2.8143,  -1.777,
+  -1.8815,  -2.2795,  -1.158,  1.0865,  -0.0453,  1.6476,  0.0859,  -1.8231,  -0.7599,  -1.0013,  0.0173,  -0.6116,  0.011,  0.6057,  0.1048,  0.392,  2.8241,  -0.4223,  -0.292,  3.4995,
+  0.0544,  2.8654,  4.0202,  1.6845,  -1.8534,  -2.9185,  -1.4228,  -3.6388,  -2.021,  -2.4342,  -3.4254,  -1.7961,  2.7218,  6.6019,  2.278,  -0.0758,  -2.1727,  1.0645,  -0.3083,  0.7762,
+  -4.2733,  -4.7209,  -2.5347,  -4.1434,  -2.3709,  0.1195,  0.9517,  -1.8672,  1.5567,  3.4133,  0.9511,  6.1534,  5.0591,  3.3617,  4.3448,  -0.8335,  0.0697,  -1.2096,  -2.2085,  -1.8188,
+  0.0539,  1.0537,  0.6965,  0.7551,  -2.3328,  -4.4085,  -1.7944,  4.6582,  -1.8228,  -0.38,  0.4342,  0.9079,  1.1727,  -0.2538,  -0.9787,  1.6403,  0.3758,  0.2889,  -1.0679,  1.0017,
+  0.9075,  0.5642,  -0.6092,  -2.8652,  -3.3111,  -1.2627,  1.6981,  0.5866,  2.5675,  2.8589,  1.6024,  2.0917,  0.4354,  1.0342,  1.2054,  -2.7817,  -0.5893,  0.0883,  -2.8199,  -1.401,
+  0.898,  -0.3869,  -0.4833,  2.6033,  -0.0884,  -0.3699,  7.2953,  1.6809,  0.8531,  1.6498,  -4.4993,  0.0072,  -1.9421,  -1.8001,  -2.5825,  -3.6475,  -2.3221,  0.6178,  0.3128,  2.204,
+  -6.0307,  -1.3653,  -0.3786,  0.0247,  0.6616,  0.7676,  3.3234,  3.0965,  0.7765,  -0.6097,  1.0441,  -0.9142,  1.6186,  -9.2158,  -4.2017,  2.5866,  2.2875,  2.0945,  2.8697,  1.5646,
+  -0.3542,  -0.028,  4.1718,  2.5282,  6.0404,  2.9659,  -1.0269,  -1.4497,  -5.6815,  -3.9178,  -3.928,  -6.4467,  -2.5804,  -4.6703,  -1.3963,  3.1437,  4.398,  -0.5477,  2.7035,  6.0758,
+  -1.5432,  3.8376,  1.421,  -1.1449,  0.4892,  1.3172,  -2.0383,  -2.2564,  -2.1791,  3.0272,  -4.0284,  -1.3615,  -1.9716,  -4.988,  3.88,  2.5715,  -2.8049,  5.2429,  -2.0992,  4.629,
+  1.9112,  0.2401,  1.209,  1.9221,  -0.5051,  2.0731,  -0.8317,  -1.4381,  1.1319,  0.2604,  4.857,  -4.2486,  -4.2343,  -0.1445,  2.6106,  1.1135,  -3.459,  -1.7688,  1.2613,  -1.96,
+  -4.6396,  -2.9689,  0.9238,  0.7657,  0.5574,  -0.365,  -3.7022,  -4.0756,  -5.0362,  0.3243,  3.188,  1.727,  -0.7319,  2.9308,  3.7592,  2.6099,  -0.3181,  4.3233,  1.9146,  -1.1863,
+  0.198,  -2.2883,  0.933,  3.8033,  -3.0797,  0.0635,  -1.8773,  -1.7344,  -1.0161,  0.156,  -0.1661,  -3.8927,  -0.3658,  0.3316,  1.1226,  1.9542,  -1.049,  -2.2906,  3.6658,  5.5322,
+  -0.8058,  -0.987,  1.9765,  0.8081,  -0.8891,  1.6549,  -1.7178,  -0.2062,  -0.6134,  3.7968,  2.8384,  4.3753,  1.2045,  -6.0029,  -1.5145,  -3.5656,  0.8785,  -0.8278,  0.9419,  -1.3448,
+  -1.9513,  2.4604,  2.9573,  3.3043,  2.2986,  1.0394,  -0.4185,  -0.089,  -0.2841,  2.2073,  1.6514,  0.3367,  -1.0792,  -1.4676,  -0.885,  1.7747,  0.0695,  -7.9932,  -5.3486,  1.4171,
+  -2.8766,  -0.2007,  0.3439,  0.7801,  -0.0362,  -1.8832,  1.2162,  3.7611,  1.5511,  -0.2914,  4.4891,  2.4265,  0.517,  1.2791,  -3.0822,  -4.3172,  2.155,  -1.7349,  -2.5924,  -1.5044,
+  -1.3853,  -0.5001,  0.6365,  -1.9167,  -1.9693,  -1.6932,  -2.5123,  -3.1209,  -1.5363,  3.8772,  1.7176,  4.5613,  2.2969,  -1.7507,  -0.4549,  2.7398,  -2.2572,  -0.1132,  1.3625,  2.0183,
+  -0.2587,  0.7517,  0.0083,  -1.5665,  -2.9108,  -3.8211,  -5.3272,  -2.2879,  -3.3006,  3.201,  3.9688,  4.6713,  3.8047,  3.4665,  0.6502,  0.9612,  0.0958,  -1.5002,  1.1994,  -1.8059,
+  -0.0767,  -2.8888,  -3.8572,  -1.6523,  2.8392,  3.7128,  0.7093,  -0.0657,  0.9823,  -1.6073,  -2.181,  -1.5064,  -0.6392,  2.2679,  1.7322,  -1.1001,  1.0422,  1.4078,  2.4192,  -1.5382,
+  2.1069,  1.6101,  -0.6015,  -1.1106,  -0.0731,  0.3657,  2.1738,  0.6411,  -3.2826,  -4.2217,  0.0005,  4.1333,  2.9287,  4.0221,  -1.0117,  -7.1186,  -0.37,  1.5812,  0.1654,  -1.9391,
+  -3.3989,  -5.4211,  -3.3823,  0.1417,  -0.209,  -2.9282,  3.8367,  5.4395,  2.1603,  -1.6658,  -0.0286,  3.8151,  -1.6236,  -0.4057,  -0.8473,  2.3634,  0.3434,  0.0424,  -0.3374,  2.1055,
+  3.8095,  -5.8994,  -4.2159,  -2.8701,  5.179,  -4.6791,  -5.6257,  0.4437,  3.5907,  6.0531,  -2.4206,  -0.619,  2.0474,  3.5867,  7.1475,  -4.6633,  4.1906,  1.2868,  -11.1492,  4.8074,
+  -5.2857,  -2.3511,  1.887,  -1.8753,  -2.8109,  0.3363,  -1.9008,  -0.409,  0.8741,  -0.4525,  -6.3796,  0.4485,  2.7092,  2.5765,  4.4129,  4.7975,  -0.3228,  3.7712,  2.7353,  -2.7608,
+  -3.9913,  -5.9775,  -2.6898,  8.0565,  3.5971,  1.2374,  3.459,  0.3338,  0.6958,  -1.1912,  -2.2406,  -2.0748,  0.0857,  3.9701,  1.1276,  1.2332,  0.6559,  -3.8152,  0.9255,  -3.3971,
+  -2.4876,  -2.515,  -2.0296,  -1.0642,  1.008,  0.6973,  -1.7376,  -1.5703,  1.5923,  -0.7283,  -0.1226,  -1.7315,  2.4167,  -0.4425,  -1.5075,  3.8846,  0.5544,  0.8966,  4.627,  0.26,
+  2.8767,  0.9007,  0.0796,  -2.1662,  -1.5086,  1.0148,  -1.337,  0.8661,  0.0749,  1.4614,  3.18,  2.1743,  -1.6449,  -2.7523,  -2.7644,  2.2901,  -1.91,  -4.8716,  -2.0883,  6.1248,
+  3.6336,  2.1044,  0.4628,  -0.6805,  -0.0353,  -2.3281,  1.0902,  3.0334,  -1.907,  -2.0882,  -2.9673,  0.1514,  0.3556,  -1.0151,  -5.4063,  2.3884,  2.5624,  -3.2553,  3.9458,  -0.0449,
+  -1.3869,  -1.5992,  1.4579,  1.4992,  1.7691,  0.8878,  0.9518,  0.7305,  -1.505,  -1.6287,  -1.6402,  -0.3868,  2.7983,  -2.2046,  -0.5051,  0.1956,  7.1623,  2.4667,  -5.9139,  -3.1488,
+  -3.5734,  -7.3577,  -7.1566,  -1.3669,  4.32,  2.1415,  0.4237,  -0.1707,  3.4434,  2.6751,  2.2337,  0.4895,  2.5968,  1.0123,  -0.9145,  -1.1189,  0.9048,  2.1474,  0.4312,  -1.1607,
+  -5.2465,  -1.6283,  -2.7428,  -3.2948,  -2.2122,  4.3049,  4.7808,  4.7619,  0.2262,  -0.6089,  1.1643,  3.359,  -2.1676,  0.2134,  -1.1502,  1.4193,  1.4168,  0.3538,  -2.8694,  -0.0796,
+  -3.4905,  1.2508,  2.0451,  0.449,  3.13,  4.3899,  0.1675,  -1.3519,  -0.0668,  0.4245,  -1.7121,  0.2301,  -2.207,  0.3069,  3.1491,  -7.5721,  2.7986,  3.8554,  -4.1493,  -1.6472,
+  1.5232,  1.53,  -1.0621,  -1.4488,  -0.8044,  -0.39,  1.3086,  -2.5549,  -4.3776,  0.5264,  2.2421,  -0.5299,  -2.7363,  4.9582,  1.0929,  1.1601,  2.8351,  1.9896,  -4.9813,  -0.2808,
+  6.5366,  -2.5283,  -5.5972,  -3.4516,  -0.2385,  1.8382,  -1.6024,  0.2804,  8.8284,  4.4416,  -6.1238,  3.7728,  3.4763,  2.9323,  -2.3678,  -5.511,  -4.9901,  -0.1283,  0.0084,  0.4242,
+  1.9342,  1.566,  2.2346,  1.0331,  -0.6035,  -0.4461,  0.0271,  0.7571,  1.1796,  0.2963,  -0.9807,  -0.5607,  -1.4711,  -2.5426,  -4.1871,  2.4178,  0.203,  -1.7949,  -3.6655,  4.6035,
+  2.2188,  0.9702,  -1.9037,  -2.3323,  -0.927,  -0.7473,  0.4463,  4.0069,  3.238,  1.6378,  1.585,  -1.9473,  -1.213,  -2.1935,  -1.9102,  -3.3249,  2.6456,  1.082,  -1.3884,  0.057,
+  1.8633,  1.2717,  1.6148,  0.3758,  2.9711,  -0.8914,  -1.2864,  1.1672,  2.0355,  1.2245,  -3.703,  3.72,  -3.0675,  -1.925,  2.2356,  -0.7355,  0.5128,  -4.4528,  -2.9595,  0.0288,
+  -2.2984,  -0.5209,  0.3609,  2.6675,  -3.691,  -0.3519,  6.3822,  3.0237,  -0.1277,  -2.2553,  1.0403,  0.997,  -1.3107,  -1.9745,  -0.1646,  4.8839,  0.1333,  -1.3256,  -3.424,  -2.0441,
+  -2.319,  2.2812,  1.2138,  -1.1727,  -3.334,  -5.2226,  3.639,  2.5124,  -1.5642,  3.4166,  0.533,  1.8016,  -0.3986,  -2.9233,  -3.7394,  0.9982,  -0.006,  -1.6833,  4.3443,  1.6231,
+  -2.2576,  -2.6516,  -1.1317,  -1.2013,  0.7393,  0.1827,  -1.2343,  -3.2192,  2.3728,  2.7817,  1.6779,  0.8901,  0.532,  1.4647,  3.7014,  7.0412,  -2.6912,  -2.5104,  -1.2474,  -3.2389,
+  -1.769,  -1.9167,  -2.8243,  0.8559,  1.6454,  0.6817,  0.5231,  -1.2522,  -2.6542,  -3.2288,  -0.2864,  0.0091,  0.5513,  -0.6182,  -3.9328,  4.4973,  6.4951,  0.4313,  1.6808,  1.1116,
+  -0.2744,  -1.578,  -1.8323,  -1.2019,  -0.362,  1.2906,  -0.2832,  -1.9105,  -0.8966,  0.8634,  -0.4648,  -2.3172,  -1.9676,  -1.7065,  0.8232,  -2.4736,  3.5667,  5.3037,  4.3018,  1.1191,
+  -0.4003,  -1.4016,  -2.6548,  -3.2373,  -2.1471,  -0.9075,  -1.1057,  1.1084,  0.0584,  0.6994,  -2.2697,  0.1501,  -0.0187,  -0.2177,  -1.1214,  2.5501,  5.4533,  5.8815,  -0.4561,  0.0366,
+  2.4755,  2.6766,  3.381,  2.8797,  -1.3067,  -1.2604,  0.4792,  -1.5575,  -2.0569,  -1.156,  -1.3594,  -0.7176,  0.2831,  1.2557,  -0.1965,  -2.5773,  0.8488,  0.4905,  -3.0053,  0.4234,
+  -0.5334,  -1.6405,  -1.4903,  -1.2901,  -2.0368,  -2.4054,  -2.0422,  -1.2649,  -0.3204,  2.3946,  2.8987,  2.5774,  -1.9494,  -5.6321,  2.8212,  3.655,  3.985,  1.2152,  1.3991,  -0.3406,
+  -1.8395,  -0.9841,  -0.1468,  -2.7046,  0.5709,  -0.0486,  2.3079,  -3.1973,  5.7249,  -2.0537,  -0.8947,  -0.5513,  -1.5588,  -0.066,  1.7712,  1.4939,  0.7539,  0.8995,  0.7376,  -0.2144,
+  -2.1136,  -6.496,  4.0091,  -2.7287,  -2.852,  0.0889,  4.2865,  1.1559,  1.4489,  2.3747,  -0.2811,  -1.6675,  -2.1043,  2.4825,  1.5983,  3.0151,  1.4924,  1.4598,  1.4466,  -6.6156,
+  0.3044,  0.5145,  0.8314,  -0.5726,  -1.4732,  0.5522,  1.0454,  0.7132,  -0.3595,  0.4703,  4.9451,  2.9593,  3.4319,  -1.7835,  -2.7963,  -3.6604,  -2.7125,  1.2113,  -5.0055,  1.3846,
+  2.3458,  3.264,  1.811,  0.4827,  -1.6195,  1.9882,  1.8256,  3.5857,  4.1301,  1.6235,  -5.1588,  -3.8052,  -1.7214,  -1.0231,  1.3522,  -0.3858,  -5.6155,  -1.3895,  -1.6421,  -0.048,
+  3.7883,  2.2512,  0.5915,  3.6595,  3.6582,  1.2917,  -2.0747,  3.0623,  -4.8462,  -9.6783,  -4.7828,  -4.1622,  -5.2776,  -1.2559,  2.3471,  0.9386,  6.0401,  4.8334,  -1.7435,  1.3593,
+  -0.5609,  -1.1658,  -2.4817,  -6.555,  -4.61,  -0.2509,  0.7628,  -0.8368,  3.8495,  3.922,  3.0356,  2.0951,  1.5781,  3.7313,  2.8834,  -1.2291,  -3.427,  1.5639,  1.6072,  -3.9116,
+  -1.4268,  0.2383,  2.3216,  0.1248,  2.0796,  1.5987,  0.8138,  -0.2165,  -2.9254,  -1.2364,  4.4075,  -3.3005,  -5.5475,  2.3771,  2.6523,  1.5551,  2.538,  1.7514,  -3.2529,  -4.552,
+  -0.7746,  0.9904,  0.2665,  0.8152,  1.7416,  -1.7222,  -3.8193,  0.6115,  3.8698,  -1.5065,  -1.1919,  -1.259,  -0.954,  1.8722,  -0.152,  -4.1283,  -0.551,  0.1951,  0.742,  4.9546,
+  -4.9471,  -2.6326,  -0.7296,  -2.9661,  3.2611,  5.2949,  1.3584,  -0.3484,  0.0238,  -0.5367,  1.037,  -2.4283,  -1.4686,  5.4446,  2.1704,  -0.2969,  -1.9436,  4.7301,  0.0591,  -5.0816,
+  0.8281,  -1.2416,  -3.3762,  -3.932,  -1.3993,  -3.0591,  -0.9292,  2.5927,  2.1047,  2.4478,  0.5704,  1.2666,  0.5289,  -0.2372,  1.2696,  3.8278,  3.1348,  1.0903,  -4.3525,  -1.1346,
+  -0.743,  -0.748,  -1.261,  -0.7625,  1.0816,  1.6556,  1.2019,  2.2812,  3.2082,  1.5688,  -1.3094,  -2.0639,  -2.5822,  -2.2528,  -1.34,  -1.6246,  0.6375,  2.89,  1.4778,  -1.315,
+  0.8081,  -1.3233,  1.3342,  -0.4629,  2.2543,  -1.7177,  1.7285,  2.2425,  -4.4738,  0.6367,  1.5497,  -1.2988,  0.3335,  -1.159,  0.1744,  -4.2648,  5.1183,  0.3072,  -2.6556,  0.8684,
+  4.0404,  1.9094,  -0.2474,  -1.16,  -0.9167,  -2.2516,  3.93,  2.7965,  0.9719,  -0.3105,  2.6858,  -1.8089,  -6.0898,  -5.0707,  2.0812,  -0.0971,  -1.5043,  0.0458,  -1.0273,  2.0234,
+  0.1375,  0.239,  1.2366,  1.5253,  1.5536,  1.1452,  -3.3801,  -3.1595,  -2.7411,  1.0175,  6.4814,  1.4661,  -1.2521,  -3.3744,  -3.5432,  -5.427,  -1.3071,  4.3703,  3.6696,  1.3422,
+  -0.0191,  0.4401,  -0.0551,  1.261,  4.9915,  1.8859,  4.2946,  2.2533,  1.246,  -0.3261,  -1.8245,  0.5397,  -0.962,  -2.4208,  -1.3984,  1.3654,  -2.31,  -4.0785,  -1.5595,  -3.3235,
+  -4.1713,  -3.8609,  -3.6233,  -2.2953,  0.459,  -0.2721,  -0.1506,  -1.7078,  0.0356,  1.5074,  1.0712,  0.7854,  0.7858,  0.0168,  -0.816,  0.081,  0.5445,  4.5197,  7.1653,  -0.0742,
+  -2.9674,  -1.465,  1.0679,  3.2208,  3.0814,  -0.6959,  -0.9252,  1.0871,  0.168,  -0.9317,  -0.6966,  -1.1041,  2.3656,  1.0874,  -0.7021,  -0.5843,  -5.954,  -1.0591,  4.3651,  0.6421,
+  -2.3881,  -1.1722,  -0.2878,  -1.31,  0.1054,  2.7187,  3.1286,  1.395,  2.5138,  0.8551,  -1.0485,  -2.7991,  -1.7081,  -1.9009,  -0.2092,  -1.1297,  5.4416,  0.9634,  -4.8359,  1.6679,
+  0.3475,  0.6761,  -0.916,  -3.3303,  -2.5114,  -1.3053,  -2.4606,  -1.5909,  -0.1066,  1.2867,  0.1087,  0.6627,  -0.938,  -2.1561,  -4.1442,  0.553,  3.6775,  4.3771,  4.5604,  3.2095,
+  1.8172,  1.9142,  1.3748,  -1.2576,  -1.3958,  0.406,  -0.4725,  -1.2643,  0.8079,  -0.6725,  -3.4257,  -3.2969,  2.8901,  -0.0329,  4.2131,  0.839,  -2.3538,  -2.2196,  3.3371,  -1.2078,
+  1.9496,  3.6573,  4.2326,  1.1863,  1.8389,  -0.7982,  -0.8176,  0.9762,  -2.1796,  -2.4082,  0.46,  -2.1099,  -0.13,  5.8933,  -3.2271,  1.4122,  -3.0287,  -5.0286,  0.1022,  -1.9807,
+  0.7977,  0.4131,  0.7926,  0.7439,  -2.715,  -3.186,  -1.6061,  -0.5456,  3.5797,  0.0724,  -0.4993,  0.4656,  -0.7994,  -0.5991,  0.0862,  3.6997,  -0.5342,  -0.3047,  0.9064,  -0.7678,
+  1.0025,  0.1292,  1.8299,  -0.2181,  -0.3367,  2.6298,  -1.6812,  -0.7903,  1.0473,  -0.5336,  -4.1833,  2.6382,  0.948,  -0.3031,  -1.3062,  -0.6706,  1.4954,  1.107,  -3.9483,  1.1443,
+  -2.822,  -2.9373,  -1.7368,  -1.1113,  0.7976,  1.021,  2.2881,  1.7823,  -1.6829,  -2.1388,  -0.0636,  0.6047,  1.3691,  0.5354,  -2.8472,  1.99,  -0.2414,  -1.8409,  2.3664,  4.6674,
+  0.81,  0.5306,  3.2216,  2.7904,  2.3222,  -0.094,  -1.2977,  0.6699,  -0.3153,  -2.0729,  -0.4524,  0.1611,  0.0422,  -0.9458,  -1.6284,  -1.059,  0.4113,  -0.2203,  -0.7025,  -2.1711,
+  0.6469,  2.9521,  -0.5269,  -2.8396,  -2.829,  -0.4167,  -2.6035,  -1.8694,  -1.271,  -1.195,  -0.6111,  -1.1719,  -0.0843,  4.1129,  3.9912,  -0.9572,  -5.8704,  3.6319,  4.0418,  2.869,
+  -1.7675,  0.6361,  2.5132,  2.083,  1.8929,  -1.5061,  -3.5844,  -4.2969,  -2.8299,  -0.687,  0.8308,  1.3968,  0.3529,  4.0998,  -1.6161,  1.3306,  0.56,  -0.5129,  -1.6573,  2.7621,
+  -4.0964,  -1.5173,  1.2551,  0.2978,  1.5682,  0.3497,  -1.4315,  -2.0554,  -0.5756,  2.5392,  0.79,  3.4286,  -2.9558,  -1.7034,  -0.8459,  1.0513,  5.1871,  -2.5294,  1.2695,  -0.0257,
+  0.0328,  -1.2155,  -1.2836,  -0.9363,  -1.2229,  -1.693,  -1.8595,  0.3399,  -1.5276,  -1.0107,  6.404,  -1.9072,  0.7733,  0.6079,  2.8719,  3.0211,  2.307,  -3.5448,  0.3434,  -0.5002,
+  -6.6638,  -3.5679,  2.7288,  3.1465,  -1.8044,  -3.2026,  0.3954,  1.5738,  0.684,  -0.5029,  1.1915,  -2.4277,  -2.892,  -0.4612,  0.5352,  2.0495,  4.9107,  0.7993,  0.1809,  3.327,
+  -7.7693,  -2.7271,  -0.5302,  -1.6862,  -2.675,  -4.1941,  6.2224,  4.1406,  1.2187,  -0.8566,  3.217,  2.7593,  3.3324,  -2.3093,  -1.4924,  1.2643,  -2.9807,  2.3328,  4.673,  -1.9398,
+  -0.3214,  0.7654,  1.4453,  1.0347,  0.7854,  -0.0281,  0.6653,  2.1756,  2.5539,  2.4886,  2.8291,  -2.3264,  -5.6113,  -4.1472,  -2.1955,  -0.1794,  -0.8897,  -2.9162,  2.0658,  1.8062,
+  0.0689,  -0.0814,  0.5156,  -0.9104,  1.9645,  1.489,  -0.7622,  -1.4287,  1.4489,  2.2731,  1.0561,  3.0605,  2.5928,  -3.3062,  -2.8865,  -3.6767,  -3.9506,  -2.1727,  -0.4806,  5.1867,
+  -2.7262,  -0.408,  -7.2353,  0.2532,  -1.7494,  4.8406,  2.4161,  -8.2402,  -0.3311,  1.0612,  3.376,  -0.5373,  3.2052,  3.7144,  -2.9286,  10.7765,  4.9188,  -8.1638,  -0.8809,  -1.3612,
+  3.8706,  1.5102,  0.378,  -7.459,  -0.9006,  2.4899,  2.468,  -2.4184,  -1.4186,  0.2908,  2.1056,  2.4328,  4.226,  -3.9887,  -6.7913,  -1.0651,  2.4289,  0.5874,  4.8024,  -3.5488,
+  -1.2691,  -4.1749,  -2.7407,  1.493,  1.4665,  -0.9212,  -1.463,  -5.1747,  -2.2251,  0.8474,  0.854,  6.6525,  0.1651,  -0.5706,  -0.3287,  3.1547,  -1.46,  0.8291,  2.5923,  2.2733,
+  3.8347,  2.4921,  1.8361,  2.4264,  0.2839,  -2.7167,  0.2831,  -0.5469,  -0.6398,  0.3108,  1.0194,  -2.1389,  -0.8456,  -4.7666,  -2.5049,  1.2075,  -5.6326,  1.3761,  3.1197,  1.602,
+  -3.7739,  -1.8529,  0.6063,  -0.8541,  -1.637,  3.6233,  0.8975,  1.9643,  3.5106,  -0.3623,  -2.4744,  -0.7625,  -0.7853,  -1.5705,  0.2237,  -0.6207,  0.0761,  -0.4742,  1.5632,  2.7029,
+  1.157,  0.8704,  1.6827,  1.2654,  -0.5848,  -2.69,  -2.6615,  -0.9589,  -1.6641,  -2.7103,  -1.4381,  -0.4901,  1.8045,  -1.5216,  -1.1394,  5.0021,  4.1235,  1.555,  -3.7877,  2.1859,
+  2.542,  1.6423,  0.7395,  0.8846,  0.9016,  2.7752,  3.3824,  2.5574,  0.4625,  -2.0442,  -1.8686,  -0.186,  -1.7933,  -5.0038,  -3.5773,  -1.2917,  -2.0519,  -1.8556,  1.0146,  2.7701,
+  -4.4081,  -3.4569,  -0.8021,  0.2773,  2.5574,  2.3862,  1.3118,  0.1408,  0.6688,  1.9053,  -1.5497,  -0.5855,  1.2457,  -0.5521,  0.963,  -2.247,  -2.8924,  -3.743,  6.1844,  2.5961,
+  0.4138,  -4.3685,  -4.3743,  3.3166,  1.9814,  -1.9703,  -1.1246,  -1.8788,  1.8555,  2.5293,  -0.6354,  0.3032,  3.9855,  0.4439,  -1.3412,  -2.6733,  1.5434,  2.8406,  -1.39,  0.543,
+  -0.9949,  0.7752,  0.5153,  -0.3382,  0.759,  -0.3806,  0.6362,  -0.0446,  0.6992,  -2.3407,  -2.218,  -0.8794,  1.9075,  1.9883,  2.6403,  1.4665,  1.1384,  1.9497,  -0.4373,  -6.842,
+  -0.369,  1.5979,  3.652,  2.5947,  0.9915,  -0.4587,  -1.5761,  -1.3889,  -0.8595,  -0.0002,  0.3336,  2.0392,  1.9215,  -1.5962,  -2.1409,  -2.1868,  -2.0225,  -6.9604,  4.1862,  2.2427,
+  0.7081,  1.2472,  1.2274,  -0.7827,  -1.3963,  0.1531,  1.0164,  1.122,  1.4236,  4.7449,  4.197,  -1.6566,  1.4602,  -0.4324,  -5.0812,  -4.6776,  -3.2034,  0.202,  -0.8325,  0.5609,
+  -0.8996,  -1.1981,  -0.4982,  -3.3678,  -3.1656,  -0.484,  -1.6889,  1.4162,  1.8691,  1.8944,  0.6984,  2.1971,  0.7659,  -0.3399,  -1.054,  -1.9648,  4.8986,  2.2357,  -0.435,  -0.8795,
+  -3.0303,  -1.1024,  -3.6351,  1.8563,  2.2581,  0.9526,  -1.318,  1.052,  0.9676,  1.4472,  -0.2536,  1.6459,  0.5539,  2.7964,  -2.3045,  3.1405,  -0.8848,  -0.5008,  -4.0553,  0.4143,
+  -2.0566,  0.3509,  1.5804,  -0.1468,  -1.2009,  -5.1236,  -1.6316,  -0.6083,  -0.2262,  -3.8727,  -1.4106,  4.1461,  2.8353,  5.5841,  2.0344,  -1.3445,  -0.2669,  1.6597,  0.4425,  -0.7448,
+  0.4237,  5.5027,  3.4466,  -0.9733,  1.1101,  0.3187,  0.4016,  -0.8934,  -4.1773,  1.2529,  -1.0141,  1.7716,  -1.4207,  2.0071,  -6.7629,  -1.426,  -0.8769,  -1.9766,  2.062,  1.2241,
+  0.525,  0.4342,  -1.3517,  -2.8754,  -3.0586,  0.6098,  2.2679,  1.4929,  1.4608,  3.1011,  1.506,  -4.8013,  -7.5268,  -0.6504,  -0.503,  2.778,  2.8557,  1.0462,  3.4571,  -0.7675,
+  3.573,  1.8714,  -0.1581,  -1.7722,  -0.3433,  -2.7056,  -3.0806,  -1.91,  -3.1355,  1.0548,  -1.9906,  0.4699,  0.0873,  2.5566,  -0.1726,  -0.8702,  2.1464,  4.3968,  5.0995,  -5.1171,
+  -0.6968,  -1.4896,  -0.0495,  0.8149,  1.4216,  -0.0327,  -1.7535,  -2.2313,  -0.321,  1.9568,  4.8784,  -1.9324,  -1.8058,  -2.6431,  -3.7316,  0.3685,  1.1306,  4.9893,  -0.2577,  1.3848,
+  -1.4341,  -1.1497,  -1.8056,  0.1413,  2.571,  2.939,  0.7055,  -0.4196,  -0.2614,  0.1608,  -0.6195,  -0.3637,  4.1643,  0.3576,  0.0984,  2.2749,  0.4728,  -7.315,  -0.1921,  -0.3248,
+  -4.2895,  -7.0396,  -4.8802,  -1.5844,  1.4442,  1.8886,  0.5829,  0.1608,  -2.6352,  -1.0632,  0.4985,  3.2097,  6.327,  9.0622,  8.0546,  -0.4311,  2.12,  -2.0642,  -2.9293,  -6.4319,
+  -2.8918,  -0.9105,  -1.1049,  -1.3358,  0.0333,  -0.4429,  1.114,  3.2177,  -0.2479,  -0.9423,  2.0518,  -3.4204,  -3.3752,  -1.508,  4.5184,  3.5104,  0.837,  0.3279,  4.1906,  -3.6215,
+  1.1012,  2.83,  4.9338,  4.9135,  -1.4413,  -4.6933,  -2.9852,  -2.2104,  -2.0709,  -0.2446,  -1.7323,  0.446,  -0.3491,  0.7293,  1.2549,  1.552,  -1.6591,  -0.0263,  -1.3091,  0.9607,
+  -3.8105,  -2.2705,  -0.4801,  0.003,  -1.0835,  -0.8967,  -1.848,  4.3428,  2.2775,  1.1261,  1.5948,  4.4091,  3.5564,  -2.1928,  -2.8051,  -1.2385,  -1.6399,  -0.9968,  0.5731,  1.3796,
+  4.5581,  4.2833,  0.3675,  -0.5438,  1.94,  3.0816,  0.3261,  -0.8096,  -2.6679,  -2.1086,  -0.8131,  -4.9186,  -3.634,  5.7405,  0.0185,  0.6308,  2.5276,  -4.0355,  -1.8846,  -2.0583,
+  -1.2863,  -0.264,  -0.1222,  1.8197,  -0.8215,  -1.4173,  6.3047,  -1.3136,  2.0735,  -0.1627,  3.0262,  1.5599,  -2.3044,  -2.9292,  -2.1284,  -0.006,  -0.2974,  -0.4468,  0.2977,  -1.5818,
+  -0.3043,  -4.9833,  -4.4641,  1.6692,  5.7638,  4.6547,  3.7525,  -0.961,  -3.955,  -2.2488,  0.7885,  4.2621,  3.6322,  2.1375,  -6.9698,  1.9153,  2.5541,  -3.4886,  -0.8469,  -2.9081,
+  1.6869,  -2.2603,  -5.3537,  -1.924,  -2.3796,  2.8412,  5.8922,  -3.3838,  0.7866,  3.3273,  0.722,  4.1493,  -2.8075,  1.2195,  -4.122,  2.7912,  5.5751,  -0.9361,  -3.796,  -2.0281,
+  1.8743,  1.5687,  0.9347,  -0.0119,  5.1974,  -0.9505,  -1.5819,  -0.0387,  -0.2355,  2.4835,  -2.718,  -2.1816,  -1.0347,  -1.5606,  -1.4552,  0.4355,  -1.6713,  -3.1551,  -0.2146,  4.3156,
+  -0.5064,  0.6473,  1.6157,  0.4031,  -0.7786,  0.4664,  2.3609,  -0.8533,  -2.7426,  0.0584,  3.6047,  -1.3728,  0.0256,  -2.0089,  0.7575,  -3.1106,  -1.7839,  0.971,  1.5709,  0.6757,
+  -0.1854,  -0.4792,  0.2327,  0.5721,  1.3762,  0.9344,  1.6367,  0.2158,  0.6455,  0.9744,  -3.1471,  -5.2734,  -4.3577,  3.1646,  3.1365,  2.2803,  1.2303,  -1.996,  -1.5643,  0.6037,
+  1.554,  2.1016,  2.3825,  0.8004,  -2.0847,  -2.7548,  -1.5073,  0.1971,  -0.2707,  -0.769,  -1.8324,  -0.6385,  -4.5361,  -6.8801,  5.4599,  2.666,  1.1252,  2.285,  1.3862,  1.3159,
+  -2.3092,  8.5984,  0.5061,  -0.6741,  -2.467,  3.2934,  -0.668,  2.0327,  0.6889,  -1.8602,  -0.9325,  -1.2001,  -4.3458,  -2.5628,  0.6948,  -1.1889,  0.4479,  2.595,  1.2931,  -1.9416,
+  0.8421,  1.5717,  0.5751,  0.5951,  0.4783,  -2.2142,  0.3553,  6.0828,  3.0287,  -2.3343,  -3.2264,  -0.7759,  -2.009,  -0.3873,  -2.4778,  0.6768,  -3.499,  -0.8957,  4.2903,  -0.6766,
+  -0.6942,  8.6603,  -5.4134,  -0.8727,  -0.3504,  -3.3092,  -0.5586,  -0.2913,  2.8905,  -3.0583,  -2.9724,  -1.747,  3.325,  -1.1022,  -4.4193,  7.6704,  0.5149,  -0.7173,  -3.6,  6.0453,
+  0.6802,  1.0947,  1.2451,  3.8611,  4.5266,  1.8951,  0.7625,  6.226,  2.5223,  4.8966,  1.838,  -0.3753,  1.3861,  -7.5361,  -6.881,  -3.7307,  -4.9193,  -2.5727,  -4.5778,  -0.3414,
+  -1.4648,  -1.9631,  -1.4302,  3.2813,  2.7021,  -1.3306,  -3.5822,  -3.4123,  -2.6251,  -2.554,  -2.983,  1.7868,  1.1612,  1.7944,  0.6471,  3.7619,  3.5844,  -0.436,  2.9666,  0.0957,
+  -2.6065,  -0.4815,  3.7667,  3.2609,  1.4317,  5.8806,  0.0973,  -3.3441,  -3.2874,  -4.9485,  -1.6589,  0.7537,  0.3424,  0.9215,  3.8135,  -4.2041,  -1.8751,  -0.8917,  1.0067,  2.0227,
+  4.0705,  -1.6316,  -3.7042,  -1.3612,  1.3654,  1.6949,  -0.0461,  -0.428,  2.9316,  0.2615,  -3.3312,  0.4341,  1.2323,  -0.8543,  -0.862,  -4.8579,  -6.1758,  3.1382,  4.934,  3.1899,
+  -4.1097,  -4.1313,  -2.7947,  -1.2657,  -0.6757,  0.0158,  -0.2664,  -0.7288,  -2.8256,  -1.9407,  0.4965,  2.0938,  4.2596,  1.7443,  2.092,  3.1468,  3.6217,  1.9383,  0.0884,  -0.7586,
+  -0.5474,  3.7117,  4.4423,  -1.1991,  -3.2034,  0.2008,  -1.1999,  -0.3645,  -0.3658,  -1.5068,  4.3945,  -0.5362,  -1.4209,  -0.9138,  -0.075,  -0.959,  3.3133,  2.7513,  -7.0608,  0.5385,
+  -0.2792,  1.018,  0.1758,  4.6409,  0.999,  0.8572,  -2.2212,  -4.3593,  1.021,  5.0992,  3.1964,  1.4429,  -1.7425,  -0.9214,  -2.3245,  -1.3975,  -6.8773,  2.8027,  -1.1862,  0.056,
+  1.7064,  0.3215,  -0.2518,  0.0527,  -2.5377,  -4.4163,  -3.0416,  -0.1822,  -1.1887,  -2.941,  0.6761,  3.4948,  1.6101,  1.2626,  0.2612,  5.622,  -3.9114,  -1.0915,  4.1888,  0.3661,
+  -1.7866,  -1.1389,  -0.0309,  -0.9349,  0.3853,  1.9195,  0.2339,  0.3886,  0.9745,  1.4208,  2.5313,  4.3943,  -4.636,  -2.5445,  -2.1898,  -2.533,  -0.3527,  4.7621,  0.5928,  -1.4558,
+  7.8057,  -3.8468,  0.8827,  0.8768,  -4.7631,  -5.1731,  0.0664,  5.3199,  -1.789,  -4.3428,  1.9966,  2.9221,  -4.5512,  5.176,  0.582,  -0.2561,  -0.2887,  0.6505,  -0.8654,  -0.4024,
+  -2.578,  -0.0834,  0.144,  -1.6096,  -4.137,  -4.824,  -1.6968,  2.0832,  4.4015,  2.3414,  0.0326,  -1.7738,  3.0088,  2.5338,  2.2405,  0.7822,  -3.427,  2.3235,  0.3274,  -0.0892,
+  2.1843,  2.593,  1.3745,  1.7373,  2.8715,  2.7285,  -1.1274,  -0.1783,  0.9497,  1.0004,  -0.2974,  -0.2919,  0.6463,  0.2228,  -1.5085,  -5.8708,  -3.691,  -0.8536,  -2.5539,  0.0647,
+  -1.6643,  -0.8616,  0.2098,  2.2486,  4.6647,  3.854,  2.3834,  1.3656,  -0.2611,  -0.7523,  -0.2703,  2.863,  1.157,  -1.6263,  -4.3844,  -3.5346,  -0.0484,  -0.8649,  -4.9645,  0.4867,
+  0.6824,  1.0939,  0.6691,  0.3291,  -0.2396,  -0.9714,  -0.9487,  0.4056,  -0.8422,  -1.0662,  -0.8121,  -1.8756,  1.8363,  1.0681,  3.7568,  2.7493,  -2.279,  1.4171,  -4.9986,  0.0258,
+  -2.0461,  -1.9677,  -1.8134,  -2.6831,  -3.0621,  -1.6874,  2.2873,  0.6491,  1.7878,  1.1808,  1.5028,  -1.154,  -1.2923,  -0.0603,  -3.5107,  6.4917,  4.0814,  1.4288,  0.0396,  -0.1721,
+  1.7926,  0.64,  0.0107,  -3.4114,  12.2384,  -4.2391,  -4.1672,  -5.5139,  -1.6966,  5.3015,  -0.9447,  -4.0014,  3.1093,  5.2076,  5.6201,  2.3962,  -5.3615,  -1.8057,  -0.2628,  -4.9121,
+  1.2301,  -0.2653,  0.0535,  -2.1294,  -3.7763,  -2.5405,  -1.3165,  1.3892,  1.1754,  1.8095,  2.3931,  -0.531,  -0.8291,  0.5926,  -0.2725,  -7.2218,  1.8619,  3.8534,  3.4226,  1.1011,
+  -4.1789,  -3.5276,  -0.8324,  -0.4176,  -2.4,  0.0369,  0.9853,  5.4189,  -1.8625,  4.5416,  -0.0534,  -2.2531,  -1.839,  3.0263,  1.3992,  -0.9141,  -0.2291,  0.6856,  2.4454,  -0.0313,
+  -6.4975,  -4.6128,  -3.3675,  -4.8986,  -0.8354,  2.3584,  -0.6088,  4.1352,  0.6068,  0.7211,  0.275,  -2.0557,  0.4476,  2.7831,  4.6078,  -0.4014,  5.9849,  2.1061,  1.2312,  -1.9795,
+  1.323,  1.1384,  1.2773,  1.715,  -0.7509,  -3.8269,  -1.129,  -0.1851,  -3.0673,  2.4551,  -1.8006,  -0.5768,  2.5367,  -0.4358,  1.0236,  2.8956,  4.5161,  -0.4242,  -3.2309,  -3.4534,
+  -0.3567,  2.4123,  4.0459,  3.3988,  2.0862,  -2.1774,  -5.126,  -1.093,  -2.2588,  -0.1938,  0.5021,  -0.2723,  1.0175,  -2.6722,  0.0196,  -1.3546,  -1.6702,  0.808,  0.6509,  2.2336,
+  -3.1316,  -2.5501,  -0.7668,  1.9764,  1.8647,  -0.0801,  0.9053,  0.9563,  -1.0947,  0.3992,  -1.9982,  2.2428,  2.0122,  -5.4193,  -2.6261,  -0.7274,  0.7121,  1.7109,  3.9486,  1.666,
+  -7.9949,  4.0953,  3.7255,  -1.4546,  8.0933,  1.7853,  -4.2627,  4.4208,  9.6075,  -2.0281,  -0.5418,  -3.566,  -1.9219,  -6.8006,  -1.4426,  -1.872,  6.0536,  -6.8174,  0.7937,  0.1276,
+  -1.9787,  -1.0115,  0.4548,  -0.6009,  1.0489,  -0.3883,  -3.8168,  3.5539,  1.8044,  -0.802,  2.2377,  4.013,  2.5264,  2.9341,  2.9402,  3.194,  -12.1756,  -4.5827,  0.714,  -0.0649,
+  -2.6937,  -0.9969,  0.6136,  -0.2092,  0.1112,  0.1733,  0.0276,  0.6804,  -4.181,  0.4835,  3.1126,  -0.8365,  -1.6005,  3.1133,  -1.3297,  -0.4657,  2.8302,  2.713,  -2.7204,  1.175,
+  -4.2305,  -1.0868,  0.5304,  -0.1415,  -1.2124,  -0.8981,  -0.879,  -0.8763,  -0.9777,  1.0148,  4.1145,  2.1714,  1.231,  -1.6938,  -1.4429,  1.2355,  6.6877,  0.2382,  -3.2655,  -0.5189,
+  -2.1503,  -3.4325,  -3.4567,  -1.0918,  0.5993,  0.3527,  0.3437,  0.2288,  0.7821,  1.0173,  2.2607,  -0.9887,  -0.3595,  4.4457,  3.707,  1.5475,  -3.7173,  0.7682,  -0.5101,  -0.3462,
+  -3.7019,  -3.2897,  -0.3993,  1.1225,  4.7873,  3.25,  -1.8347,  -2.0699,  0.0727,  1.2966,  -0.1512,  1.4478,  -2.4263,  -0.3987,  -2.4159,  -3.3225,  2.8445,  0.7735,  0.8954,  3.5197,
+  0.0807,  -1.1966,  -2.9464,  0.8465,  1.6234,  1.1215,  1.2824,  3.7187,  2.3234,  -3.7329,  -7.3924,  -3.2192,  -4.4371,  -4.8564,  3.1927,  2.3654,  4.5154,  -1.033,  4.4531,  3.291,
+  0.0329,  2.1961,  1.8627,  0.509,  -2.3566,  -3.1635,  -1.4865,  -3.4766,  -3.4834,  -4.5095,  -2.404,  -5.545,  7.4389,  3.1752,  2.6905,  4.3345,  1.8695,  -0.0444,  -0.0458,  2.4056,
+  -4.2525,  -4.2615,  -2.8448,  -1.4174,  -1.4188,  -1.0941,  0.0321,  2.7304,  1.6246,  3.7714,  3.6887,  2.3979,  1.9374,  0.7696,  -7.0469,  0.1811,  3.9202,  4.8839,  -3.2038,  -0.3977,
+  -0.4109,  -0.9615,  -1.1887,  -1.3425,  -1.0669,  -2.7829,  -2.9395,  1.289,  1.6984,  -0.5601,  1.6775,  -0.5469,  -0.8102,  -0.2298,  -0.7565,  0.3451,  3.1792,  2.2226,  4.5535,  -1.3689,
+  -5.7264,  -3.6531,  -1.3521,  0.1463,  1.711,  3.189,  0.7838,  -1.0176,  -0.2195,  1.4384,  0.0207,  -0.4968,  -1.0491,  0.1749,  1.0739,  2.0378,  1.358,  1.236,  0.4429,  -0.098,
+  0.7773,  -0.8979,  -1.2165,  -1.9337,  -2.9157,  -4.0101,  -0.3148,  -4.646,  -4.2945,  4.177,  5.5969,  1.4549,  3.5448,  1.4079,  -0.8343,  -3.2017,  5.5239,  2.2268,  -0.3838,  -0.0607,
+  -0.6985,  -0.6307,  2.4635,  -0.5381,  -0.2883,  3.4018,  2.1088,  2.918,  -0.5123,  -0.9613,  0.0579,  -4.3385,  -3.8027,  1.0743,  5.0578,  -1.828,  -2.2439,  -4.7171,  0.9386,  2.5388,
+  -4.5218,  0.1558,  2.838,  2.3948,  -1.9436,  0.6339,  -0.7954,  1.9788,  1.5836,  1.1696,  -4.5526,  -0.564,  1.4447,  7.0584,  -6.8023,  -4.5393,  -6.0449,  -0.5031,  6.1354,  4.8739,
+  0.3624,  -1.2047,  -2.0776,  -1.5816,  -0.7523,  -0.4259,  1.9866,  -0.1702,  -0.471,  -1.9514,  -1.5113,  -0.2099,  2.707,  3.8409,  4.1635,  -1.6517,  0.8031,  3.118,  -4.9637,  -0.01,
+  3.3248,  2.1375,  1.3785,  0.2103,  3.0519,  1.4244,  0.2968,  -0.3016,  -1.2728,  0.9142,  0.2763,  0.9396,  2.3345,  -1.6742,  -3.9431,  -3.4421,  -2.5066,  -1.7463,  1.1359,  -2.5381,
+  7.3832,  7.8862,  -6.4414,  -8.9767,  0.1372,  -3.3099,  3.3247,  -2.2516,  -2.6663,  1.5419,  7.2572,  -0.6762,  -1.4552,  3.0048,  6.921,  -8.5959,  -2.6649,  2.5301,  -0.7893,  -2.1588,
+  1.3303,  0.1631,  -2.4438,  -1.2379,  0.9953,  2.7203,  1.9038,  1.2786,  0.3887,  2.8669,  0.368,  -0.1846,  5.6338,  2.1238,  -1.0482,  -5.2051,  -1.0787,  -7.2281,  -1.5184,  0.1722,
+  0.1645,  -0.9895,  -2.0311,  -3.1149,  -3.298,  -2.1249,  2.0221,  2.1048,  -0.3058,  -1.0676,  -2.5289,  -1.4215,  -1.7517,  2.914,  4.1244,  -0.6494,  2.6877,  3.2611,  2.5839,  -0.5792,
+  -0.4639,  -1.9119,  -0.6903,  1.0816,  1.798,  1.1866,  0.422,  1.5316,  0.8944,  -2.981,  5.6782,  3.5367,  -0.9955,  2.4778,  -1.9477,  -3.1693,  -0.034,  -1.9442,  -1.8186,  -2.6506,
+  -3.9601,  -3.1838,  -1.3333,  -0.9936,  0.4708,  1.864,  0.2776,  -3.5639,  -1.8523,  3.8979,  6.3274,  1.9935,  2.4867,  -0.2835,  -0.1329,  -0.9778,  1.4936,  2.4315,  0.5084,  -5.4702,
+  -1.9007,  -8.9624,  0.7258,  -2.6244,  1.8683,  0.7413,  8.169,  -2.357,  -4.2143,  -5.3821,  5.3979,  -0.3396,  -0.0209,  2.4866,  -1.7903,  8.5769,  -2.6396,  -4.5135,  0.4288,  6.3503,
+  2.3682,  1.2735,  1.0581,  0.7198,  -1.3884,  -1.1783,  2.7862,  -0.315,  -4.4216,  1.0457,  0.802,  0.2322,  -1.8255,  0.9933,  1.5522,  4.2681,  -3.4105,  -1.8681,  -3.1691,  0.4773,
+  0.1022,  3.5273,  4.7298,  1.5753,  -3.6041,  -2.406,  0.8414,  1.2204,  1.0785,  1.4517,  0.9533,  1.0682,  -0.0095,  -1.2482,  -3.715,  -1.4924,  0.0586,  0.2151,  -3.5086,  -0.8381,
+  2.6097,  1.3046,  0.1797,  -0.8433,  -0.8002,  -0.6737,  -0.7817,  -0.0181,  -1.8564,  -0.0021,  1.7429,  2.1363,  2.4019,  0.852,  -1.2013,  -2.3776,  0.1614,  -1.6535,  0.2922,  -1.473,
+  -1.1555,  -1.9989,  -3.7971,  -3.5419,  -1.7702,  5.6208,  1.6756,  -3.4769,  -2.2174,  -0.5921,  -2.9465,  2.4449,  3.2181,  2.5732,  0.5741,  1.4008,  -1.6104,  2.6683,  4.0017,  -1.0706,
+  2.6808,  2.4971,  2.2595,  2.6039,  2.5012,  2.7248,  0.3061,  -0.5761,  -0.0415,  -2.4607,  -1.2162,  -0.08,  -2.7145,  -3.3777,  0.3468,  1.3821,  -2.901,  -0.5334,  -2.3262,  -1.075,
+  -1.4573,  -0.7869,  0.2356,  -0.1795,  -1.7997,  -2.4756,  -0.7083,  -1.2917,  -0.2409,  1.8121,  2.3854,  -0.078,  -2.6742,  0.8926,  3.1169,  2.4329,  -3.2335,  1.5184,  1.6752,  0.8566,
+  1.3578,  1.5299,  1.0786,  -1.596,  -3.3648,  -1.6673,  1.3592,  5.7139,  -0.3364,  -0.8154,  -1.0911,  0.3285,  1.2167,  -6.5169,  3.5759,  0.3841,  -3.4189,  2.252,  -0.3564,  0.3665,
+  -3.9427,  -4.1692,  -3.9599,  -2.7914,  -2.7852,  0.8501,  2.1268,  3.1929,  2.9997,  0.9798,  3.7115,  2.7044,  0.8023,  -1.3597,  -0.1213,  1.8505,  0.8537,  2.357,  0.4425,  -3.7419,
+  1.1259,  1.7278,  1.7181,  1.0824,  0.9378,  2.2855,  -0.4426,  -2.0998,  0.2868,  -2.3258,  -2.4774,  -3.503,  -2.192,  -0.0403,  0.0689,  -2.1823,  -1.7516,  0.3348,  2.6371,  4.8097,
+  2.6282,  3.1949,  1.4763,  -1.8168,  -2.3026,  -0.1157,  -0.0177,  1.6877,  0.85,  0.1002,  -0.5211,  1.2286,  1.5164,  -0.6411,  -0.9348,  -3.1872,  0.1863,  -3.1762,  -3.7899,  3.6345,
+  0.6239,  1.6179,  1.2014,  0.2608,  -1.992,  4.7736,  2.9884,  -1.6687,  -1.57,  -3.2904,  2.3265,  0.1217,  -0.6529,  1.1537,  -1.343,  -3.266,  -0.7427,  -0.3946,  -0.8553,  0.7078,
+  -2.5785,  3.3274,  0.7827,  -1.1641,  0.3099,  2.093,  -3.8923,  -2.1233,  -0.2174,  -1.0352,  2.3827,  3.2008,  -1.3061,  -1.3553,  2.0138,  -4.8137,  2.2926,  -0.4492,  0.2262,  2.3061,
+  0.703,  -0.6796,  0.6702,  1.233,  0.3286,  -1.1249,  -0.2281,  0.9008,  -0.4257,  1.5252,  0.1413,  3.8708,  -2.7125,  -0.1048,  -1.3046,  -2.6469,  -1.7645,  -0.4236,  2.6448,  -0.6022,
+  -2.0396,  0.9147,  3.7884,  2.4844,  -0.2561,  -2.4529,  1.8969,  -0.1479,  0.695,  -1.2549,  -4.9008,  -1.2459,  0.9313,  0.6906,  5.2636,  -1.1277,  -0.2394,  -2.2895,  -2.5856,  1.8753,
+  1.678,  -1.6532,  -2.7599,  -2.245,  0.5197,  -1.6003,  4.4426,  1.0934,  -0.3109,  0.9191,  -3.4242,  1.3304,  -1.5208,  -0.9853,  -0.2434,  3.9418,  0.4425,  -2.2543,  4.6335,  -2.0037,
+  2.2658,  -0.6139,  -1.3935,  -0.0563,  -2.955,  -1.9056,  3.4601,  -0.3817,  -1.6475,  -0.291,  -0.5503,  1.7727,  0.0114,  2.6384,  2.8574,  0.5346,  -5.4829,  -2.6161,  0.958,  3.3952,
+  -2.9553,  0.0039,  3.9564,  2.2087,  -0.9348,  -1.5953,  -1.378,  0.1552,  -2.1548,  0.7917,  1.8242,  1.6997,  -1.8826,  -0.8677,  -0.7876,  -0.2152,  2.3842,  2.1467,  1.7116,  -4.111,
+  0.7023,  1.9303,  1.0064,  0.0165,  5.4286,  -1.1464,  -1.0459,  -2.0088,  -1.2634,  -2.1806,  -0.6159,  0.3372,  3.405,  -1.1188,  -2.8596,  -2.391,  -0.555,  5.4226,  -1.0697,  -1.9937,
+  -0.8683,  0.0341,  1.1306,  -1.3868,  -1.9833,  2.9612,  -0.7025,  0.9705,  -3.1777,  4.1388,  0.7353,  0.3664,  2.0843,  0.2998,  -0.405,  -1.1895,  3.2137,  -5.0324,  1.1351,  -2.3244,
+  -1.0092,  0.5101,  2.307,  2.1852,  1.5304,  -1.7001,  1.6095,  -1.457,  -3.9762,  -1.6422,  -0.2532,  1.3474,  0.8974,  0.9819,  -2.2295,  4.7058,  -2.038,  3.1038,  -2.542,  -2.3311,
+  1.9713,  1.0803,  -1.0686,  -1.2321,  0.3041,  -0.5899,  -1.6032,  -0.6543,  -2.1903,  -2.1676,  0.3844,  0.2905,  -0.5787,  -1.1285,  -3.3703,  -0.5637,  0.3705,  2.2696,  8.3763,  0.1004,
+  -2.3313,  3.6108,  -3.7738,  2.3534,  -6.3897,  3.9802,  2.8098,  6.2413,  2.517,  5.126,  2.4541,  -1.7202,  -4.9921,  -5.7179,  -3.3204,  5.3271,  2.0124,  -5.7657,  0.7907,  -3.2116,
+  0.323,  1.0311,  1.366,  0.9706,  2.0785,  2.0724,  -0.0151,  -0.8301,  -1.1195,  -2.8044,  -0.9819,  0.0417,  0.0944,  -1.2077,  -2.2323,  4.1593,  1.4207,  -2.7654,  -0.5102,  -1.0909,
+  1.0182,  0.5812,  0.3232,  1.704,  1.6371,  0.0882,  0.7883,  2.0623,  -2.4549,  -1.7632,  -0.0828,  0.1245,  -1.0882,  -0.0487,  -2.0254,  -0.8118,  -5.9132,  2.5533,  0.488,  2.8199,
+  -2.1755,  -1.411,  0.7926,  3.1903,  3.2045,  1.4005,  2.2246,  0.4995,  1.4795,  1.0003,  1.4155,  -1.8108,  -1.7649,  -2.0289,  -4.9177,  1.9399,  0.4644,  -0.6846,  -2.6827,  -0.1356,
+  -2.3372,  -0.8774,  1.8295,  2.5713,  0.4237,  -1.62,  0.725,  1.2049,  -2.5557,  -1.7837,  -2.0535,  1.8608,  2.0142,  1.1559,  0.414,  -2.2055,  2.6316,  -1.0207,  -0.4407,  0.0634,
+  -6.476,  2.3566,  6.2881,  1.178,  2.2768,  0.5492,  3.6691,  1.5956,  1.5393,  0.8045,  -2.4474,  -1.1396,  -3.0192,  -2.8013,  2.1788,  0.9584,  -4.0593,  -1.3318,  -0.6033,  -1.5164,
+  -0.2224,  3.1469,  4.1918,  -1.5853,  -2.9401,  2.4424,  -2.0556,  -1.6902,  1.4657,  -1.4987,  -4.5783,  -3.9175,  1.8499,  2.5001,  -2.9926,  -3.1367,  4.3814,  2.8761,  -0.3135,  2.0766,
+  0.2838,  0.7448,  1.5373,  1.7127,  1.9184,  1.9954,  1.4552,  0.6636,  -0.0775,  -1.4076,  -2.7023,  -2.4765,  -6.0615,  -4.2297,  -2.8214,  4.4402,  0.5975,  1.2302,  2.2798,  0.9178,
+  0.1873,  0.8058,  1.4948,  0.4584,  -0.6762,  -2.1053,  -0.4098,  -0.951,  -0.4347,  -0.3909,  -1.0508,  -2.5837,  -1.0389,  -4.2899,  -4.0647,  3.8453,  2.2675,  2.8481,  4.595,  1.4936,
+  6.4165,  4.769,  2.1643,  -0.5306,  -1.7418,  -1.1821,  0.4655,  2.4797,  -1.0005,  -2.7835,  0.6462,  1.054,  0.1648,  -0.2195,  -1.2133,  -1.6876,  -0.2896,  -1.1843,  -4.2375,  -2.0895,
+  0.6591,  -2.4247,  -3.5305,  -2.0684,  0.7993,  0.5286,  -1.0223,  -0.9537,  0.6266,  1.4075,  1.462,  1.6652,  1.3324,  -0.3799,  1.6047,  -0.403,  -1.4183,  -0.7574,  3.5079,  -0.6351,
+  -0.7402,  -0.5022,  -0.0104,  -0.1501,  0.0126,  -0.8303,  -0.6338,  0.0643,  0.7573,  4.3586,  2.2234,  -0.7379,  3.8453,  0.8151,  2.8221,  -1.4249,  -1.4011,  -3.5524,  -6.4818,  1.5666,
+  1.297,  2.6835,  1.2613,  -1.8292,  -0.939,  -1.6773,  -1.9287,  1.2477,  1.3854,  -1.9138,  -1.0744,  1.6338,  -4.8418,  -0.558,  -1.29,  5.2745,  -2.7458,  2.6939,  -0.9625,  2.2835,
+  1.8861,  3.1363,  4.0321,  1.7435,  0.5233,  -0.7855,  2.0137,  0.8065,  1.2174,  -4.0074,  0.586,  -1.0339,  -6.4815,  -6.1251,  1.1641,  -3.9644,  -6.3895,  7.8222,  2.0846,  1.7715,
+  3.9399,  2.2907,  1.6049,  0.7588,  -0.5727,  -0.4203,  1.1669,  0.6185,  -0.3417,  1.2484,  1.5946,  1.7091,  -1.8086,  -4.7596,  -2.8399,  -3.9325,  -2.0296,  -0.678,  -0.7509,  3.2019,
+  -0.3222,  0.619,  2.2698,  6.3269,  5.8198,  2.6992,  0.0601,  -0.5335,  -1.7361,  -3.6667,  0.2231,  -2.3194,  -2.0166,  2.496,  0.142,  -3.4765,  -2.9842,  -0.3195,  -1.1974,  -2.084,
+  1.2403,  -2.3646,  -2.0313,  0.7252,  3.2474,  2.8194,  3.1981,  0.9009,  1.1286,  -0.917,  -2.4531,  -2.402,  1.6229,  2.3317,  -1.4971,  0.7586,  -3.2903,  -2.1223,  -1.2864,  0.3911,
+  2.1547,  -0.4814,  -1.6208,  -0.2568,  3.766,  2.5927,  -0.5335,  0.5221,  2.1027,  -1.7193,  -2.1878,  -1.5973,  0.4487,  -3.0208,  -3.0695,  -0.2839,  1.21,  -4.2182,  4.88,  1.3123,
+  -0.8216,  0.0172,  1.0117,  1.8195,  2.2767,  0.0322,  -4.7072,  -3.7244,  0.2876,  1.2946,  -1.1268,  -2.0514,  -0.3229,  1.5642,  2.8282,  1.4525,  -0.2405,  0.3745,  -0.8299,  0.8658,
+  -0.5885,  -0.7711,  -0.1566,  0.2456,  -1.1305,  -2.14,  -1.5832,  -2.7023,  2.6573,  2.8982,  -1.9439,  -1.4435,  3.2616,  3.0544,  -1.0646,  -0.2393,  0.2808,  -0.6774,  -3.3509,  5.3938,
+  -2.1609,  4.7541,  2.6519,  2.9104,  -0.9771,  -3.4464,  1.3102,  4.9024,  3.0997,  0.1198,  -0.6878,  -5.0516,  -2.6241,  -0.139,  0.326,  -3.7625,  -4.6033,  5.7644,  -2.7192,  0.333,
+  -0.0774,  0.0212,  1.7356,  2.6966,  3.8703,  -1.264,  -2.204,  -3.8688,  -2.8745,  -0.383,  -1.2433,  2.7247,  1.1808,  0.5913,  3.3839,  -2.9426,  0.1962,  -0.6047,  -3.1975,  2.2593,
+  -1.7694,  -0.8337,  -1.4857,  1.6357,  3.0084,  1.4757,  0.7496,  0.4982,  -0.8638,  1.0294,  3.8151,  2.548,  -0.4944,  -5.1598,  -4.1575,  1.6819,  -0.9028,  -3.0629,  2.9081,  -0.6201,
+  -4.1737,  -1.1372,  0.4218,  -0.398,  -0.2873,  -2.0904,  -1.4241,  1.1799,  4.8192,  5.5695,  2.124,  -1.9634,  -0.1503,  -0.2208,  -2.6623,  -1.214,  1.5287,  0.1773,  -0.4832,  0.3844,
+  1.1759,  3.6352,  3.0816,  -1.1382,  -0.8341,  -1.2549,  1.7627,  -0.261,  -1.7582,  -4.6767,  -1.9887,  0.8806,  -0.2903,  -2.9331,  -3.3697,  0.3291,  -2.5313,  6.3991,  2.6926,  1.0793,
+  3.1054,  0.5446,  -2.7707,  -3.1154,  -2.4354,  -2.1091,  -1.9215,  1.5263,  -0.5089,  -2.1954,  -3.0602,  -1.7502,  2.0283,  3.094,  3.1639,  6.0315,  0.1168,  -2.3219,  2.2755,  0.3024,
+  1.4017,  0.2037,  -0.1188,  0.363,  -1.7809,  1.2589,  -0.0416,  0.1426,  -0.29,  -0.0669,  -0.9365,  -1.7637,  -4.6543,  4.5857,  0.7173,  -1.2893,  0.7992,  1.8632,  0.4734,  -0.8667,
+  -0.6645,  0.3054,  -0.1583,  0.39,  0.1223,  1.1996,  4.2148,  1.7843,  2.7706,  0.9297,  -1.0663,  1.2711,  -0.1675,  -0.5861,  -2.5452,  -2.9107,  1.264,  0.2394,  -4.6672,  -1.7254,
+  1.3908,  0.5115,  -0.8577,  0.3878,  0.771,  1.2838,  -1.2112,  -1.293,  -1.9359,  -2.3893,  -2.5796,  1.2692,  3.1933,  -0.2748,  0.2489,  3.4206,  -5.3967,  -3.2312,  2.6326,  4.06,
+  -3.1151,  -2.4768,  -1.4409,  0.082,  -0.065,  0.8542,  2.7545,  0.8481,  2.7775,  3.2925,  -1.1392,  -0.56,  5.6459,  -1.5505,  0.7937,  -0.2372,  -3.8294,  -1.7699,  -1.1681,  0.3038,
+  -1.4631,  -1.5744,  -1.0602,  1.2727,  5.2755,  0.7411,  2.6424,  0.9111,  -1.5443,  -0.8217,  -2.458,  -1.9627,  -0.3229,  -0.7005,  -0.1842,  1.441,  1.119,  -0.0388,  -1.7254,  0.4532,
+  2.6735,  -0.132,  -2.0731,  -1.2667,  -0.0059,  0.4063,  1.1045,  -0.65,  0.2919,  -0.2343,  -0.1432,  0.5161,  -1.3203,  -1.9223,  -1.8439,  -0.3541,  2.5902,  0.7807,  0.9691,  0.6136,
+  -2.576,  -2.1039,  3.3039,  7.5737,  4.851,  -1.928,  1.3509,  -0.0624,  1.3149,  2.3856,  -2.8836,  1.6777,  1.6919,  -0.2315,  2.0672,  -1.6292,  -7.7877,  -7.8864,  -2.423,  3.2949,
+  0.1825,  1.4326,  1.8802,  -0.76,  -3.5028,  -2.0654,  -2.5905,  -1.978,  -1.3931,  -2.0377,  2.0912,  -0.7666,  -1.6801,  0.1901,  1.3312,  -0.8245,  -0.8221,  9.1933,  2.6121,  -0.4925,
+  0.6596,  0.5183,  0.0656,  0.6099,  0.217,  -0.2483,  0.3752,  0.0528,  -1.355,  -1.959,  -3.0746,  -2.7901,  1.748,  0.0667,  -1.3253,  1.8365,  1.2016,  0.6331,  1.5502,  1.2179,
+  1.518,  -2.8697,  -3.0225,  1.1901,  1.2949,  1.2425,  -0.2655,  -1.0124,  0.1504,  0.9476,  0.8294,  0.498,  -4.6214,  -0.4714,  2.314,  0.5042,  0.0042,  0.6173,  0.025,  1.1274,
+  5.2946,  0.9166,  -1.6961,  2.6183,  3.7503,  -0.5464,  -0.4536,  -2.5804,  0.7239,  -3.0443,  -0.9745,  -0.5296,  -1.2153,  0.2578,  -4.9483,  0.2574,  1.6442,  -1.7218,  -1.0182,  3.2654,
+  -0.3113,  0.1627,  0.201,  -0.6825,  0.4894,  0.3705,  0.5406,  -0.5307,  2.3413,  3.1334,  -0.2531,  0.7289,  0.0127,  0.8411,  -0.5394,  -1.5751,  -4.4648,  3.3442,  -1.3619,  -2.4473,
+  0.7892,  1.6007,  2.2451,  -0.0142,  -1.8268,  1.0211,  1.1632,  -0.431,  0.4809,  0.7681,  -0.3119,  -3.184,  1.8621,  0.7982,  3.9396,  5.5125,  -9.0182,  -7.2338,  1.472,  0.3673,
+  4.5691,  3.1984,  0.4848,  -1.6299,  -1.5279,  -0.4613,  -0.394,  -0.7641,  -0.774,  -1.4705,  -2.0718,  -3.7739,  -3.8204,  -2.0882,  0.9538,  2.3794,  3.3309,  2.1292,  0.9829,  0.7475,
+  -1.7639,  -2.13,  1.8133,  5.4637,  4.9096,  0.44,  -0.2077,  -3.2872,  -2.801,  -3.3973,  1.4612,  -0.7884,  -0.4468,  0.3167,  3.033,  3.6546,  1.5554,  -2.1172,  -5.0158,  -0.6924,
+  -0.9691,  2.1549,  0.9464,  -1.8955,  -2.483,  0.5229,  1.0573,  -0.1544,  -2.7731,  -1.7762,  -1.2133,  0.4997,  -0.404,  0.0598,  2.1564,  0.9676,  0.1749,  -0.3066,  1.3334,  2.102,
+  0.1735,  -0.6351,  -2.2851,  0.3979,  2.1071,  0.8723,  -1.4327,  2.7248,  2.2122,  -3.8366,  -6.8693,  2.9956,  2.234,  0.2392,  4.5854,  0.8064,  -0.4877,  -1.9451,  0.1604,  -2.0173,
+  -3.0467,  -2.6229,  -0.6828,  -1.5402,  -4.5504,  -0.6274,  -1.5654,  -1.1048,  -5.0244,  1.2208,  4.3959,  1.7152,  0.8404,  2.3104,  3.911,  1.3725,  3.6004,  -1.5868,  -0.0242,  3.0095,
+  4.6972,  -2.0723,  3.7478,  -0.0539,  -1.3604,  -1.6975,  -5.1051,  4.5477,  7.491,  0.8111,  -1.5236,  -2.0035,  -2.3201,  -1.9156,  -1.8399,  2.7039,  1.1102,  2.7618,  0.1987,  -8.1775,
+  4.2697,  2.1482,  1.1807,  -0.8188,  -0.0158,  -0.9415,  -3.1934,  -7.6652,  -5.2761,  -0.4096,  0.8289,  -0.6591,  -0.1321,  -2.2645,  2.689,  3.5308,  -0.186,  2.2844,  2.1691,  2.4613,
+  -2.6176,  -1.9646,  -0.3365,  0.449,  1.789,  3.0096,  1.2687,  0.1913,  0.7099,  3.1055,  2.4376,  1.5156,  0.2027,  -3.2954,  -0.8316,  0.625,  2.5125,  -1.9645,  -4.736,  -2.0703,
+  0.9801,  -1.159,  -1.1869,  -1.8206,  -2.6697,  -2.2474,  -1.9247,  1.339,  0.7955,  3.2786,  2.1796,  1.2439,  3.831,  0.9791,  -3.7027,  -2.0691,  -3.3297,  3.47,  4.0219,  -2.0091,
+  -1.9305,  1.1296,  2.7892,  3.5086,  -0.4192,  1.8621,  -2.4767,  -4.562,  -1.3151,  -0.4855,  0.213,  4.0896,  -0.2763,  2.9118,  1.5789,  -0.3477,  -0.82,  5.6054,  -7.8822,  -3.173,
+  3.5183,  4.1815,  1.9981,  -0.8261,  -1.4369,  -0.3881,  1.0213,  -3.8793,  -3.6636,  2.2621,  1.1803,  1.7727,  -0.7985,  -1.2902,  -5.0777,  -1.2307,  0.3381,  4.4122,  -1.4815,  -0.612,
+  4.0477,  1.4256,  -1.6604,  -3.5999,  -1.9136,  -0.3445,  0.3946,  1.6694,  1.2905,  0.9828,  0.5724,  -0.1289,  1.3498,  1.3379,  0.2067,  0.3656,  0.2492,  -1.2128,  -3.2905,  -1.7416,
+  -2.0178,  -2.6699,  -1.3526,  0.2496,  0.4148,  -0.8854,  1.0823,  -0.6203,  1.2579,  0.4148,  -2.2346,  -0.4015,  1.4157,  4.8809,  6.623,  -3.5608,  -1.8735,  -4.5603,  3.5038,  0.334,
+  1.4937,  -1.542,  -2.385,  3.1706,  1.4707,  0.1938,  0.5057,  3.8806,  -0.0936,  0.3334,  0.4606,  1.4472,  -0.903,  -1.4318,  3.5118,  -5.2689,  -1.4235,  -1.2997,  0.0053,  -2.1257,
+  -3.6561,  0.1855,  0.3705,  1.1645,  0.2341,  -0.8092,  2.398,  -0.3274,  -0.4576,  -1.1851,  -3.8496,  2.0281,  -3.3309,  0.9466,  -0.078,  1.0318,  4.0737,  2.619,  -0.3495,  -1.0083,
+  -0.1238,  -0.3756,  -0.3626,  -1.1974,  -3.028,  -3.3983,  -3.5184,  -2.8303,  -0.2464,  -1.0525,  0.7469,  1.1667,  1.9967,  2.0536,  5.8842,  4.672,  0.6593,  -0.227,  -1.2558,  0.4368,
+  1.4898,  -0.0036,  2.1872,  4.7731,  5.3388,  2.1104,  0.861,  -1.9286,  -4.4764,  -2.9139,  -5.8875,  0.1502,  2.3687,  -3.3444,  1.8016,  2.0118,  0.348,  1.5855,  -1.0664,  -5.4053,
+  -0.2559,  -0.097,  0.6606,  -3.0637,  -4.0503,  -2.5522,  0.2345,  0.1786,  -0.3244,  -2.5706,  1.7286,  2.2086,  1.6927,  2.74,  1.934,  -0.1619,  5.414,  3.6846,  -5.1534,  -2.2469,
+  0.7337,  0.6464,  -0.7291,  -0.8337,  -0.3024,  0.3377,  1.5178,  1.0116,  2.585,  0.9759,  -1.397,  -3.2182,  -3.6906,  -0.0798,  3.4993,  -1.9939,  -5.3046,  1.4115,  4.7666,  0.0639,
+  -2.9601,  -0.9321,  -1.3007,  -4.5012,  -0.6859,  1.6271,  0.8938,  1.8188,  2.7147,  2.4868,  2.4402,  0.6577,  1.204,  2.0247,  0.2523,  1.3499,  1.0757,  -5.3086,  -0.2223,  -2.6347,
+  1.2887,  2.2547,  3.3766,  1.8575,  -1.791,  -1.7548,  1.5265,  2.7964,  1.224,  1.972,  0.2687,  1.81,  3.1328,  -2.586,  -2.7821,  -3.9778,  -2.4086,  -2.0066,  -0.0746,  -4.1265,
+  0.8108,  -0.0118,  0.351,  0.2469,  -0.3564,  -0.0688,  2.2772,  2.9983,  0.022,  -0.8672,  -4.831,  -2.0824,  0.0877,  2.2501,  0.0661,  -8.6456,  -1.6422,  4.8643,  2.3157,  2.2152,
+  -2.3502,  1.9923,  1.6641,  -2.2786,  3.4633,  2.605,  -3.0058,  1.5172,  -5.319,  -0.9994,  -2.4221,  0.2495,  3.8898,  -2.058,  1.1705,  0.4058,  -1.2798,  2.5712,  -0.5349,  0.7192,
+  5.2963,  2.758,  0.0542,  -1.8363,  0.6217,  3.1975,  0.8761,  0.6926,  0.1889,  -2.2049,  -2.6639,  -2.3949,  -0.455,  0.9028,  0.9417,  -2.32,  -1.6049,  2.2215,  -3.0876,  -1.184,
+  0.0332,  0.6867,  -0.5444,  -2.656,  -2.3272,  -1.9975,  2.7492,  3.4613,  1.2531,  2.297,  0.6826,  1.6161,  0.8081,  -2.8567,  -0.251,  3.1363,  -4.7699,  -0.8591,  1.4746,  -1.9362,
+  0.1179,  0.1304,  -0.0905,  -0.0885,  0.5876,  2.0857,  -0.3875,  -1.3306,  -0.8957,  -0.1982,  0.8458,  -0.0513,  -2.2349,  -5.5634,  7.5385,  3.9965,  -1.063,  -1.5645,  -2.102,  0.268,
+  1.5416,  0.4773,  -0.0338,  0.6704,  0.3091,  -0.0982,  -0.8312,  -1.8586,  -2.1668,  -3.0698,  -3.6621,  -2.8717,  -0.1465,  2.9749,  3.0473,  2.3156,  -0.0362,  0.7605,  1.1471,  1.5312,
+  -1.4651,  -1.1492,  -0.67,  -0.6012,  -0.1247,  1.155,  -0.2106,  -1.2695,  -0.4411,  1.1446,  4.1491,  2.66,  1.3124,  1.6069,  0.6316,  -0.4851,  -2.5715,  -4.3867,  -1.004,  1.7189,
+  0.2437,  0.6555,  0.3411,  0.8466,  -1.7425,  -0.1636,  6.1311,  0.6211,  -2.703,  -1.5009,  -0.1744,  0.866,  1.3589,  1.249,  1.1273,  -2.7402,  -0.0949,  -1.544,  -1.861,  -0.9159,
+  4.3927,  3.3672,  0.9009,  -1.2521,  0.623,  -0.5206,  0.8245,  -0.9087,  -1.8374,  0.0097,  -3.1469,  -2.4307,  -3.0482,  0.2541,  1.948,  5.7092,  -3.3716,  -3.2953,  2.6836,  -0.9014,
+  2.2171,  0.1913,  -1.6779,  -0.9585,  -1.3241,  0.2292,  1.4881,  2.7969,  0.2756,  -3.8207,  -2.4695,  -0.3208,  2.3024,  2.5414,  -0.1815,  -0.2933,  2.0837,  0.9892,  -1.0861,  -2.9823,
+  0.1186,  0.1645,  -0.3865,  -0.8001,  -0.3047,  -2.3398,  -0.6229,  -0.0641,  0.8491,  1.7026,  -1.1341,  -2.0704,  -0.3123,  0.1814,  3.882,  1.2943,  0.4627,  -0.5672,  0.5181,  -0.5712,
+  -0.1015,  -2.3234,  -2.352,  0.9949,  2.2704,  0.9946,  0.356,  0.9113,  0.1017,  -0.453,  0.852,  -1.0302,  0.8806,  0.3674,  -2.6615,  -4.89,  -2.9475,  1.9045,  2.6392,  4.4864,
+  2.3941,  1.701,  1.9067,  0.4931,  -1.4348,  -2.6074,  -1.1597,  -1.0504,  -3.046,  -2.8157,  -0.6597,  -0.592,  -0.3406,  -1.123,  -0.8586,  4.9381,  2.8734,  1.4518,  2.5923,  -2.6625,
+  -0.8669,  1.9301,  3.2551,  6.1577,  2.0399,  2.6785,  0.738,  -0.3115,  4.7391,  1.4868,  -6.0175,  -7.4317,  -4.5623,  -0.859,  3.8966,  -0.1349,  -2.5476,  -0.008,  -1.4441,  -2.7383,
+  -1.8064,  0.5147,  0.58,  -2.6271,  -3.9359,  -2.9321,  -2.4785,  0.6104,  -1.7343,  -0.3653,  -0.3024,  0.235,  2.3057,  1.9998,  2.2392,  1.9124,  3.0438,  -0.2241,  5.1672,  -2.202,
+  1.858,  3.3342,  3.04,  1.067,  0.2251,  0.548,  1.7906,  0.7871,  1.285,  -0.3795,  -2.015,  -2.3713,  0.5611,  0.5214,  -0.8547,  0.0171,  -1.8463,  -2.7006,  -1.7828,  -3.0844,
+  1.4841,  -0.81,  -2.4242,  -1.8509,  -0.9746,  -1.0553,  4.8924,  1.3818,  -1.8605,  -4.3708,  -2.0142,  6.4457,  0.9506,  -0.5924,  0.1104,  2.4175,  -0.6754,  -0.8459,  -0.1554,  -0.053,
+  -0.0877,  -0.9877,  -1.7358,  0.3853,  1.1022,  1.2975,  4.3189,  -1.9877,  -3.1833,  1.0392,  0.1796,  4.1158,  1.465,  -1.6177,  1.6123,  -4.1615,  -3.2584,  1.2187,  -4.3136,  4.5989,
+  0.4487,  -0.1107,  -2.0381,  -0.2337,  2.5745,  2.8339,  -0.0417,  1.4413,  -1.4483,  -1.1675,  -6.2515,  -6.936,  -3.2717,  4.8492,  0.9246,  -0.975,  4.1724,  1.7821,  1.382,  2.0655,
+  0.1081,  -0.6949,  0.1665,  0.6685,  0.879,  0.7273,  0.1766,  -0.0005,  -0.2218,  -0.4294,  0.4489,  -0.4843,  0.2008,  2.1975,  4.5024,  -1.0296,  -1.2026,  -2.5547,  -1.0944,  -2.3636,
+  2.3396,  2.1543,  2.2429,  4.7578,  0.839,  -0.8895,  4.6297,  0.4985,  -2.3653,  2.1787,  -1.0612,  -0.8953,  -6.2919,  0.5546,  -0.4272,  -0.967,  -1.9781,  -0.4692,  -5.5295,  0.6795,
+  0.153,  -2.1926,  2.1973,  4.5005,  -1.3453,  1.3286,  -2.031,  1.0783,  -1.351,  -0.7983,  0.6783,  -3.4857,  5.3977,  -3.6561,  -3.5986,  6.0882,  0.1428,  -0.9697,  3.0219,  -5.1583,
+  -2.6086,  -0.0766,  2.7222,  2.0552,  2.4096,  3.0319,  1.0596,  -0.1283,  -0.8104,  -0.2732,  -1.4259,  -4.0229,  -1.4469,  -1.6716,  -1.1861,  -0.9216,  0.678,  -0.0004,  2.0118,  0.6041,
+  1.8333,  3.1078,  -1.8097,  1.1817,  3.7643,  0.5185,  1.9828,  -0.3454,  1.2321,  -1.0494,  -6.2996,  3.9399,  -4.6043,  2.7296,  -2.2906,  -1.7821,  -0.5503,  -0.1687,  1.5615,  -2.9514,
+  -1.9822,  -1.787,  -2.0807,  -0.6471,  1.7376,  -0.7108,  -0.9897,  0.1273,  -1.5435,  -3.408,  1.1979,  3.2003,  1.0189,  -0.9731,  -1.079,  -1.9655,  3.5511,  1.2692,  3.4593,  1.6049,
+  1.8097,  0.7952,  2.3044,  2.0422,  0.0385,  -1.489,  -2.6817,  -2.4115,  -2.0814,  -4.7349,  1.3168,  5.2099,  2.0691,  0.2209,  -0.3967,  -1.391,  -0.0825,  -1.397,  -1.3074,  2.1664,
+  -0.6317,  -0.6961,  -1.7818,  1.7212,  1.8896,  0.7627,  6.4133,  0.0239,  -2.0812,  -0.634,  -0.8745,  -0.8436,  -3.5167,  -3.0992,  -0.4403,  -5.0217,  5.7819,  4.7221,  -2.9383,  1.2443,
+  -0.8542,  -4.8873,  -5.4381,  -4.263,  -4.129,  0.7749,  4.7768,  0.2842,  0.3115,  -0.282,  0.2149,  -0.1804,  0.6193,  5.7873,  5.1866,  -1.3257,  -3.0389,  -1.9693,  8.9711,  -0.5589,
+  -1.7203,  0.3016,  0.2697,  0.0913,  0.2499,  2.9554,  0.332,  0.0927,  -3.0516,  1.3578,  -0.8456,  1.2764,  0.1248,  3.9102,  2.8147,  -2.3847,  -6.7532,  -2.2614,  1.9868,  1.2535,
+  2.3588,  1.8978,  1.0798,  1.0217,  0.8258,  -0.3312,  0.8967,  -0.1754,  -0.3981,  1.015,  -0.3879,  -0.8493,  -1.269,  -1.1797,  1.5079,  -0.1598,  -2.3607,  1.1269,  2.648,  -7.2674,
+  1.1746,  4.6165,  5.494,  3.4461,  -3.9021,  -1.605,  -0.1323,  -0.938,  -0.4156,  -1.9,  -0.2856,  -1.2349,  -3.6515,  -2.9147,  0.053,  1.1469,  0.2371,  -1.3253,  3.8834,  -1.7466,
+  -2.2758,  1.8844,  4.6711,  2.2076,  -1.3597,  -0.4741,  0.4627,  -0.0358,  -0.0017,  -1.0258,  -0.6957,  -1.027,  1.1372,  -2.604,  -3.0616,  -4.3523,  1.6973,  1.9314,  1.1807,  1.741,
+  1.9665,  1.3206,  -0.1069,  0.8467,  1.1209,  2.6581,  1.0313,  -0.7646,  -0.9327,  -0.4666,  1.3979,  -1.1019,  -2.4235,  -8.2049,  1.1737,  4.931,  0.7484,  0.2664,  -6.0708,  2.6104,
+  1.1852,  -1.5416,  -3.6491,  4.4048,  -6.7437,  4.6469,  1.6802,  1.291,  2.2789,  2.761,  1.3944,  -0.7732,  -5.8136,  4.4421,  -2.2039,  0.8414,  -5.8722,  -4.6747,  -3.6578,  10.0038,
+  -3.9689,  -0.5502,  1.1683,  -2.1974,  -1.9082,  0.1416,  1.6772,  0.326,  3.7162,  2.4168,  2.6207,  -1.7735,  1.5236,  0.348,  -0.3569,  4.1471,  1.4471,  -0.6226,  -8.1997,  0.0448,
+  0.6532,  1.491,  1.2058,  1.7096,  2.395,  1.7319,  -1.5483,  -1.8447,  -2.2888,  0.7634,  3.2796,  1.6709,  -4.9985,  -3.0829,  -1.1211,  1.2229,  -0.2209,  -1.194,  1.9569,  -1.7811,
+  -1.9523,  -4.3005,  -4.5837,  1.0346,  1.2567,  1.0099,  3.2344,  2.8332,  1.1895,  -1.5164,  -2.2052,  -1.2334,  -1.4331,  2.1022,  2.3179,  5.6712,  2.1958,  -2.0504,  -2.5243,  -1.046,
+  -1.1815,  -1.53,  -0.6842,  -0.5633,  -2.6867,  -1.4016,  0.6359,  -2.017,  -1.297,  -1.6432,  -1.0489,  -1.3764,  -1.1731,  -0.5962,  3.5229,  5.3595,  3.1187,  3.4061,  0.3009,  0.855,
+  -3.1382,  -0.628,  -0.8774,  -0.9941,  0.9435,  0.9619,  0.852,  -3.3796,  -3.2423,  -1.3758,  3.304,  2.2194,  1.0056,  2.5348,  -0.2996,  0.9762,  -3.7819,  -0.3936,  5.7234,  -0.4105,
+  -3.2428,  -5.3967,  -1.5226,  4.3711,  2.0836,  2.1112,  0.7032,  -4.0183,  -12.6551,  -15.4852,  0.9361,  9.2253,  10.5424,  3.4081,  3.4337,  -0.7556,  1.6657,  0.8127,  4.5992,  -0.816,
+  1.8248,  0.0419,  0.5248,  1.8646,  -1.2814,  -2.6618,  -0.0669,  0.1817,  2.2151,  -0.8152,  5.1179,  2.3104,  3.6555,  -8.7128,  -2.079,  1.0629,  -0.0963,  -1.5473,  0.4756,  -2.0146,
+  -0.1111,  0.3482,  -0.0235,  -0.7175,  -0.1449,  -0.3857,  -0.8724,  0.4592,  0.498,  0.2237,  0.3924,  0.2623,  -0.5426,  0.937,  -0.6701,  0.16,  0.1978,  1.4707,  -0.454,  -1.0274,
+  -0.9442,  -0.4989,  -0.2375,  -0.5991,  -1.2414,  -0.4327,  -0.2055,  -0.5191,  2.6955,  3.9938,  -2.7275,  1.8004,  1.9744,  1.7067,  -0.5541,  -5.7033,  0.6046,  -1.4009,  -1.3782,  3.6669,
+  -0.8575,  0.6722,  1.8197,  2.2695,  1.4265,  -1.5445,  -1.743,  -1.5937,  2.047,  -0.1126,  0.3473,  1.4243,  0.9317,  -1.3895,  -1.064,  0.4664,  -0.0706,  -3.0958,  -1.0532,  1.1198,
+  0.9735,  -3.1553,  -4.9524,  -1.8534,  0.7715,  2.4911,  5.1271,  0.432,  -4.1146,  1.1236,  2.7184,  2.0135,  1.9444,  1.7813,  1.8232,  -2.6267,  -5.6361,  0.3774,  1.0979,  -0.3363,
+  1.9497,  1.0413,  -1.2191,  -0.8636,  0.0511,  -0.3375,  -0.5315,  -1.0284,  2.1218,  -5.0828,  1.0827,  -2.2172,  -1.3936,  0.4537,  3.3006,  0.9962,  -1.2147,  0.093,  -2.8723,  5.6705,
+  -3.0064,  -0.669,  1.9882,  3.1451,  0.5101,  1.4897,  6.0735,  3.0322,  0.7197,  2.5823,  0.9024,  -1.3595,  -0.6102,  -4.4164,  -5.2345,  0.5038,  -1.7243,  -1.0135,  0.3868,  -3.2999,
+  -1.3127,  -0.5603,  -0.4395,  -0.5779,  -1.3273,  -0.7737,  1.1446,  2.1363,  0.5709,  -0.9646,  0.1742,  -0.3429,  0.7079,  -1.3617,  -0.1807,  0.8278,  4.5177,  -3.6128,  1.9484,  -0.5738,
+  4.9592,  5.5662,  -1.4308,  2.4625,  -1.3728,  0.3179,  2.5142,  -3.1176,  -3.0793,  2.5866,  -6.0767,  -3.0209,  -1.0428,  3.7946,  3.4423,  -3.9407,  3.868,  -5.8781,  -3.2612,  2.7097,
+  1.8752,  4.6096,  2.6992,  0.0622,  1.9683,  -1.5159,  -0.2846,  2.0429,  5.1916,  0.0415,  0.4228,  0.2499,  -1.8859,  -1.2282,  -1.8414,  -3.2239,  -2.8594,  -2.2718,  -1.947,  -2.105,
+  -0.4172,  -0.066,  -0.7815,  -1.3234,  1.6425,  1.596,  0.1952,  2.8005,  1.8348,  -0.0556,  -1.7528,  -0.333,  2.5351,  3.2175,  -0.0237,  -2.6102,  -2.3993,  -0.4569,  0.2104,  -3.8124,
+  0.534,  -7.1325,  7.3739,  -7.1474,  5.0035,  4.0837,  1.7481,  0.6285,  2.147,  3.3649,  3.4871,  -4.6213,  5.3643,  -0.8361,  2.3067,  -0.6517,  -4.1528,  -4.1599,  -0.0969,  -7.2432,
+  6.4977,  -1.8922,  6.0123,  2.6649,  3.9019,  -2.9401,  -5.9544,  6.5995,  -3.7727,  -1.3909,  -4.1986,  0.3151,  1.1248,  0.2299,  1.4836,  -7.4381,  0.2549,  4.7727,  -2.9947,  -3.2755,
+  0.0546,  0.0075,  0.5596,  0.2523,  -2.3268,  -4.5642,  -3.6799,  -0.8395,  2.7336,  3.7088,  2.7486,  2.6118,  1.5065,  0.0463,  0.417,  -0.5592,  1.5006,  -0.4534,  -1.6715,  -2.0529,
+  2.9815,  2.4495,  1.7545,  3.2822,  2.8844,  2.5666,  0.0398,  1.6192,  2.6128,  3.3153,  -4.7284,  -2.6356,  -1.7561,  -4.3333,  -3.6328,  -2.9815,  -0.9212,  -0.8755,  -0.3601,  -1.2811,
+  -0.8024,  1.2002,  3.222,  -0.7626,  -2.1102,  -1.0525,  -1.8044,  0.6518,  -0.3024,  1.2038,  0.2348,  0.2257,  -2.8991,  -1.661,  1.3306,  -0.9177,  -2.5629,  -0.6077,  5.6868,  1.7272,
+  -0.1833,  -0.3751,  0.5635,  0.1503,  -0.2949,  -0.6821,  1.4873,  -1.2805,  -1.3007,  -0.6803,  0.0098,  0.9789,  1.7868,  3.5914,  0.8184,  1.0857,  6.4677,  -3.3457,  -6.706,  -2.0913,
+  4.2126,  1.0339,  -0.8906,  0.9053,  2.8206,  3.1913,  0.4808,  1.7342,  1.1617,  0.7387,  3.7928,  -0.7288,  -6.1883,  -1.6937,  -4.9005,  -3.6291,  -0.7611,  -1.4035,  -0.2407,  0.3643,
+  -8.3754,  -2.2519,  1.308,  1.8062,  0.885,  1.6497,  2.088,  2.7261,  0.2633,  -0.5998,  0.5979,  0.7034,  0.996,  2.9711,  0.165,  0.8745,  -0.1614,  -0.6875,  -1.3556,  -3.6024,
+  1.4188,  1.0202,  1.5256,  1.662,  0.7476,  -1.439,  -3.4051,  -1.878,  0.4521,  -3.9741,  0.7867,  -0.3719,  -2.3721,  -1.0437,  0.6801,  -0.2011,  -3.0818,  2.9062,  4.2361,  2.3315,
+  0.1054,  -2.6122,  -4.3807,  -5.3145,  -0.2846,  4.3842,  3.017,  3.8061,  0.711,  -1.0498,  -0.2574,  -0.9802,  0.3402,  1.2503,  2.5457,  -7.8042,  -0.1469,  2.8259,  3.0062,  0.8386,
+  5.2058,  7.108,  4.9534,  -1.243,  -6.6855,  -3.7117,  -6.1961,  -2.1515,  -0.5576,  -1.6169,  5.7678,  7.778,  -3.9195,  1.0323,  -4.8749,  2.1979,  -6.6948,  5.7018,  -1.1809,  -0.9126,
+  5.0054,  3.2246,  2.722,  2.5774,  0.3515,  -0.4988,  -0.6659,  -1.1531,  -0.3512,  -0.2899,  -1.1677,  0.8076,  -0.071,  -1.3279,  -1.882,  -2.0262,  -1.5275,  -2.277,  -2.2582,  0.808,
+  -0.3421,  -2.1542,  -1.9404,  1.9715,  2.0717,  1.269,  -0.59,  2.8831,  2.5295,  -0.0718,  1.0132,  -2.1895,  0.9449,  0.2787,  2.8471,  3.2171,  -2.0622,  -4.9892,  -4.8142,  0.1278,
+  -3.5648,  -4.522,  -3.8219,  -0.0484,  2.559,  3.3348,  4.6892,  3.089,  3.1738,  2.4402,  -0.3648,  -2.0478,  -1.8476,  0.1171,  -0.1749,  -2.2364,  0.1988,  -2.2378,  0.6726,  0.592,
+  -2.5566,  -0.841,  -0.428,  -0.4406,  -0.5726,  -0.3279,  -1.871,  -2.483,  2.814,  4.1548,  -1.1877,  -1.2228,  1.1741,  0.7041,  -4.1128,  0.8974,  1.646,  2.7315,  1.4956,  0.4265,
+  0.6395,  0.6244,  0.2175,  0.2548,  -0.6436,  -1.4509,  -1.2471,  -1.8889,  -1.6984,  0.63,  -0.0902,  -1.4274,  1.6267,  2.2897,  -1.4907,  -1.0863,  -0.599,  -0.3234,  4.5402,  1.1229,
+  -3.0281,  -3.4576,  0.2465,  1.1848,  -0.3128,  -1.4112,  -1.7883,  -2.4368,  -3.6604,  0.2309,  4.1432,  0.2306,  3.9874,  1.3414,  -2.9661,  0.2318,  1.3943,  2.8996,  1.0512,  2.1197,
+  -6.4523,  -0.8108,  3.0394,  2.9265,  1.7276,  -0.6852,  -1.3401,  -1.2086,  0.2339,  0.6323,  0.9584,  -0.4322,  -0.4865,  1.1438,  3.9792,  -0.5978,  -3.3409,  -0.0134,  0.1557,  0.5712,
+  0.8836,  0.6632,  -0.5682,  1.0909,  1.02,  0.2143,  1.7898,  0.4314,  -1.2105,  -1.6888,  -2.8939,  1.5904,  1.4323,  5.0287,  -2.409,  -2.6282,  -1.2927,  -1.8499,  -3.8726,  4.2691,
+  2.7571,  0.5054,  0.5914,  -0.4593,  -1.9535,  -2.8534,  -5.1043,  -5.0146,  0.3167,  1.921,  1.992,  1.2596,  1.2329,  -1.0134,  -2.2148,  -0.9619,  3.3405,  0.4893,  1.9185,  3.2509,
+  -7.8257,  -8.0514,  -2.2922,  4.6049,  1.7841,  0.2877,  2.46,  0.2299,  0.3961,  0.7952,  4.9841,  0.5914,  -3.3601,  1.4043,  5.5671,  2.2508,  0.0018,  1.51,  -2.0511,  -3.2867,
+  1.5686,  1.2169,  -0.6391,  -2.6751,  -3.0325,  -3.9104,  -2.5516,  -0.9763,  6.3909,  -1.3255,  1.3817,  1.7409,  2.2064,  2.8908,  0.3118,  0.3554,  0.3092,  -0.0695,  -2.5566,  -0.6363,
+  1.1784,  0.7886,  1.7506,  3.8841,  0.1097,  -3.4846,  -1.1668,  -0.2517,  -0.3004,  -0.0493,  2.027,  0.2092,  1.544,  3.4255,  0.2943,  -0.8517,  -1.6072,  -4.0976,  -5.8976,  2.4958,
+  0.9988,  2.8848,  3.2891,  3.3681,  1.4676,  3.2906,  1.3735,  1.197,  0.4611,  -0.5875,  1.7464,  0.9583,  0.5681,  -1.4825,  -4.2976,  -3.2226,  -2.3712,  -7.0782,  -2.8558,  0.2917,
+  -0.2746,  -0.1545,  -0.1213,  -1.7658,  -0.9647,  -0.899,  -2.2776,  -1.6043,  2.1487,  5.2377,  -7.3002,  -1.2976,  0.8951,  2.6087,  1.9104,  0.8944,  4.2107,  2.4289,  -0.6124,  -3.0624,
+  4.5993,  2.8908,  2.6348,  2.5753,  3.5423,  -1.3467,  -3.634,  -1.3719,  -1.5896,  -1.7807,  0.4182,  -0.4869,  -0.0081,  -1.7322,  -5.0302,  -4.0281,  3.2297,  0.1854,  0.7317,  0.2006,
+  -3.2143,  -2.4079,  2.3832,  -1.4835,  -2.9589,  -4.3471,  -9.4701,  -8.698,  2.2131,  11.9939,  3.4222,  5.6731,  1.0493,  0.9347,  3.177,  3.6996,  -0.0115,  2.2951,  -2.8928,  -1.3571,
+  2.2986,  0.5686,  -2.7234,  0.0628,  3.3595,  3.0322,  1.2528,  0.1697,  0.2877,  -3.1109,  -4.5198,  4.2898,  4.5477,  -0.5365,  -2.9437,  -1.776,  -3.4896,  -0.4971,  0.5506,  -0.823,
+  0.0226,  -1.9088,  -4.1034,  -3.5139,  1.8311,  6.6465,  1.9042,  -0.2585,  0.4811,  -1.3603,  -0.8669,  -2.6469,  -2.4021,  -2.3699,  -1.0708,  1.8059,  0.3697,  0.3642,  3.4726,  3.6036,
+  1.8666,  0.3455,  -0.4415,  1.453,  2.1752,  0.4141,  0.9988,  0.9339,  2.0369,  0.0808,  -1.3138,  -1.2683,  0.1032,  0.3074,  0.3794,  -2.248,  -4.4451,  -2.7006,  1.2456,  0.077,
+  -0.9714,  0.8948,  -0.5528,  -1.5023,  -2.1884,  -1.619,  -2.6643,  0.3765,  5.2588,  1.9474,  4.7336,  6.0668,  0.9206,  -6.1173,  0.2687,  4.2344,  -2.7801,  4.7836,  -5.9468,  -5.1428,
+  -3.5447,  -2.6492,  -1.1225,  1.1104,  -0.6763,  -0.3734,  0.7874,  2.9348,  3.7914,  3.3802,  -3.0687,  -1.7645,  -1.7552,  0.4322,  1.5566,  3.1434,  -2.9717,  0.2913,  0.3294,  0.1693,
+  2.3099,  -0.6833,  -2.4051,  -0.87,  -0.1793,  -0.7055,  -1.1773,  0.0766,  -2.2742,  -3.5734,  -2.1986,  0.6775,  0.1605,  0.0083,  4.2284,  1.3025,  3.7892,  -0.0746,  -0.9582,  2.5465,
+  0.9486,  0.1048,  1.8316,  3.4918,  2.1758,  1.1342,  1.0848,  2.4632,  0.0993,  -1.9453,  -1.1703,  -1.6274,  -2.0353,  0.8991,  0.4736,  -4.0911,  -2.9565,  -2.3552,  -2.1133,  3.5874,
+  0.6208,  3.4997,  6.2697,  4.2107,  1.2652,  2.1894,  1.1355,  -2.5271,  -2.9525,  0.0535,  0.3829,  -2.5199,  -2.9063,  -2.7287,  -1.9607,  1.46,  1.2748,  0.44,  -4.8467,  -2.3602,
+  0.5243,  2.9289,  2.2684,  0.4191,  -2.1542,  -0.2881,  -0.2706,  0.6758,  5.4475,  1.1883,  -2.5477,  -6.5024,  -4.1506,  0.6656,  0.9576,  -1.2352,  1.0736,  -4.8441,  2.5699,  3.2741,
+  -0.7794,  1.1463,  3.5016,  1.112,  0.8485,  -1.0628,  -0.8132,  3.8405,  -0.3344,  1.2653,  0.4357,  0.5494,  -2.5741,  -2.4964,  -3.4166,  -4.9706,  4.8271,  -4.7341,  1.1838,  2.4711,
+  1.8447,  1.0979,  -1.7573,  0.3863,  -0.5133,  -3.1578,  0.0583,  -0.5417,  4.1974,  -4.603,  0.1241,  -3.2329,  4.6242,  -4.6647,  -2.461,  0.5959,  3.2183,  -1.2626,  5.6612,  0.3859,
+  -2.3894,  -1.0328,  1.7896,  5.5648,  5.222,  1.8869,  1.0956,  -0.1977,  3.2983,  0.9466,  -2.0813,  -0.1679,  -0.5816,  -0.1714,  -2.751,  1.1951,  1.5496,  1.64,  -5.0073,  -9.808,
+  0.7738,  -1.7298,  -3.2257,  -0.3183,  1.9284,  1.7227,  0.8166,  0.9095,  0.5332,  -0.5016,  -1.266,  -1.9608,  2.0035,  -2.6922,  3.7039,  0.8905,  -0.7247,  2.7531,  -3.0591,  -0.5571,
+  -0.0748,  -0.507,  -0.2516,  1.7723,  1.4041,  4.352,  1.7022,  1.099,  -1.4641,  -2.362,  3.1174,  0.5476,  1.5192,  -1.9294,  -4.9678,  0.2919,  -3.1451,  1.3976,  -0.5997,  -1.9017,
+  -0.3043,  -4.5751,  -6.4864,  -2.8079,  2.8553,  1.4264,  -0.629,  0.8259,  1.1617,  -0.8255,  -1.1913,  -0.9336,  -0.8179,  -0.6841,  2.7254,  1.919,  4.4832,  2.4919,  2.0452,  -0.6788,
+  2.9368,  3.5644,  3.7164,  3.7726,  0.3148,  -2.5071,  -1.0177,  0.4365,  0.4818,  -2.1099,  -3.0728,  -1.1823,  -1.8323,  -2.546,  -3.2217,  -2.5081,  0.1068,  -0.334,  2.0018,  3.0001,
+  2.0122,  -0.8437,  -0.0894,  -3.5669,  0.2151,  1.3672,  -1.1852,  2.2748,  0.2674,  2.1266,  -4.5961,  -3.5181,  1.641,  4.2095,  -4.0873,  0.0362,  3.5548,  -2.6567,  1.8468,  0.9915,
+  -2.9528,  1.3693,  1.3737,  3.6447,  4.6399,  3.0004,  -0.4081,  -0.5069,  -2.0885,  -2.1563,  0.7639,  0.479,  -2.4821,  1.6495,  0.828,  -0.4457,  -4.8607,  3.5285,  3.1896,  -8.5655,
+  -4.4449,  -2.6584,  -0.3396,  2.7055,  3.1313,  2.6691,  -0.1405,  -2.692,  1.138,  5.9263,  0.1508,  -2.5031,  -2.5963,  -2.2339,  -0.4387,  2.7348,  0.1166,  -2.0958,  -0.1884,  1.7591,
+  -0.4506,  -2.2585,  -2.0183,  -1.2141,  2.3804,  5.1371,  -0.1012,  0.7185,  -1.9558,  -5.5843,  1.7274,  2.5676,  1.3295,  -2.3148,  3.4722,  0.9168,  0.3809,  -1.2468,  -0.6805,  -0.8055,
+  -0.5741,  -1.3187,  -1.6054,  -1.8387,  -3.0009,  -2.2631,  1.6411,  1.0542,  0.863,  1.3059,  0.666,  0.5171,  -0.9355,  -1.8837,  0.8703,  0.385,  -0.0855,  0.2754,  4.4605,  1.4674,
+  4.0853,  2.9178,  0.0251,  -1.7053,  -2.9819,  -2.0918,  -1.9947,  -0.8293,  -0.6373,  0.5052,  2.1796,  2.6733,  -1.7046,  -0.6344,  1.362,  -0.4864,  -2.0884,  -1.6708,  1.5012,  1.5754,
+  -1.5635,  2.8252,  -0.9149,  -3.0463,  -4.7327,  2.7084,  1.1209,  0.7968,  0.7865,  -1.2527,  -0.1248,  2.6941,  2.7972,  2.2336,  -0.0652,  -0.4532,  -2.9265,  -0.056,  -0.4324,  -0.3945,
+  2.462,  0.7164,  -1.5674,  -3.1513,  -1.6402,  2.4149,  2.901,  2.5761,  3.2262,  0.0749,  -4.5314,  -3.4112,  0.2922,  1.0743,  0.0408,  -1.5976,  -0.5032,  0.6577,  0.7598,  -0.794,
+  1.971,  1.173,  -0.6838,  -2.2094,  -1.9356,  1.4952,  -2.0825,  -0.2927,  0.7657,  -1.8337,  4.4472,  -3.8324,  0.7557,  0.0732,  -3.6271,  -1.9071,  4.314,  2.4552,  -0.0317,  0.9857,
+  3.7325,  2.7934,  1.0157,  -1.7096,  -2.8454,  -1.8953,  -0.7562,  0.3146,  -0.3781,  -1.002,  -1.6158,  -0.3984,  -0.0573,  0.9972,  1.0112,  -1.0599,  0.037,  3.6124,  1.1087,  -2.9047,
+  -1.4832,  -1.9899,  -0.8731,  -0.933,  -2.9066,  2.382,  -0.1603,  -0.717,  -1.1285,  -0.9274,  2.1578,  6.4011,  -1.6535,  2.3099,  -1.6654,  3.7268,  0.0883,  -1.8527,  -0.5184,  -0.2568,
+  0.6353,  1.3687,  1.8257,  0.3226,  -0.8766,  1,  1.0853,  1.2934,  0.8779,  1.7553,  1.1543,  -2.0442,  -1.6763,  -0.4593,  0.9294,  -1.2072,  -2.2593,  -0.6144,  -2.8074,  -0.3032,
+  -1.207,  -1.3475,  -1.8312,  -1.7806,  -2.9611,  -3.1818,  2.9332,  -0.124,  0.1906,  2.9202,  -1.8371,  1.0525,  -2.0319,  2.7074,  -2.1979,  -1.3072,  -0.5591,  3.0013,  2.66,  4.9011,
+  -5.1303,  3.387,  -3.7967,  -1.9466,  -5.3864,  -1.1368,  -0.5684,  3.7351,  -0.5755,  -3.2378,  -4.425,  2.035,  3.9372,  5.4701,  -2.7768,  5.9464,  6.6849,  -3.7875,  1.9948,  -0.423,
+  -1.3037,  -1.9678,  -3.152,  -1.4018,  0.2092,  2.801,  2.076,  -0.3324,  1.0911,  0.905,  1.7187,  3.4255,  1.0022,  3.5722,  -3.5224,  -4.7658,  -1.0745,  0.2766,  1.2898,  -0.8471,
+  1.9772,  -2.9635,  -3.024,  -2.2547,  0.1703,  1.7771,  -1.6073,  -3.1859,  1.541,  1.4356,  0.9203,  3.9297,  4.2495,  5.7007,  -4.0193,  -0.8612,  1.6423,  0.8844,  -5.1605,  -1.1517,
+  2.9132,  0.8992,  -1.0688,  -1.5448,  -0.9185,  0.4003,  -1.77,  -2.7768,  -1.4639,  0.2261,  0.7139,  1.7997,  3.0514,  3.3204,  0.6803,  0.9792,  -0.2717,  -2.645,  -0.2252,  -2.2988,
+  -2.9741,  -2.4804,  -3.0116,  -3.1521,  0.1074,  1.3714,  0.6662,  2.0637,  1.7849,  -0.4611,  -0.772,  -1.6172,  0.8203,  3.4203,  0.8069,  2.2581,  3.2451,  0.5915,  -2.2429,  -0.4245,
+  -0.8028,  -0.229,  0.2137,  -0.4319,  0.558,  0.2543,  0.9172,  0.8892,  -0.4807,  -1.2827,  0.9202,  1.1454,  -1.6931,  -3.6479,  0.4568,  3.9049,  1.2435,  2.6145,  0.7928,  -5.3425,
+  2.619,  1.9162,  0.9769,  -0.1078,  -0.429,  -0.365,  -2.8284,  -4.4494,  -5.991,  -4.8405,  0.711,  -0.4595,  0.2195,  3.3942,  0.9527,  -1.8867,  3.8742,  3.7699,  1.215,  1.7087,
+  1.8829,  0.7201,  0.6607,  -0.0626,  -1.194,  -1.4411,  -0.0944,  0.1172,  -0.7491,  -0.3712,  -2.5287,  -2.1899,  -1.228,  -1.4906,  -0.5689,  -1.4885,  2.7842,  4.0586,  -1.1367,  4.32,
+  4.671,  0.9897,  -0.6156,  -0.6851,  -1.412,  4.1532,  4.4321,  1.1339,  -1.0985,  0.5736,  1.4085,  -4.6356,  -3.3117,  -1.5968,  -3.4345,  -0.7293,  -0.0528,  -0.3096,  -3.6684,  4.188,
+  -2.5398,  -1.383,  0.0979,  1.9654,  3.5192,  -0.0522,  -3.287,  -3.8507,  0.6356,  -0.985,  -3.0198,  -3.7269,  -0.831,  1.9829,  1.8339,  -0.8073,  0.2152,  2.0459,  6.118,  2.0688,
+  0.4962,  3.2227,  3.5953,  1.3395,  -3.4218,  -4.9933,  -1.9981,  0.9513,  -1.0998,  -2.7535,  1.3298,  -0.6976,  0.0716,  0.7392,  5.8854,  -4.3047,  2.189,  1.9699,  -2.4444,  -0.0765,
+  -5.8327,  1.1129,  0.8081,  5.6003,  5.5684,  4.702,  2.8089,  0.4347,  1.1649,  -4.9188,  -11.4465,  -1.3196,  0.4225,  -2.4705,  0.3286,  -0.0113,  8.734,  -2.122,  -2.1264,  -1.4373,
+  -1.6231,  -1.3969,  -2.0111,  -1.262,  4.3084,  -1.2012,  1.2341,  0.1866,  0.0635,  -2.6548,  2.3896,  1.8088,  0.029,  -4.3105,  3.9166,  -0.0331,  -0.3748,  -2.471,  1.0435,  2.3583,
+  0.631,  1.3989,  1.5277,  0.7608,  1.0894,  1.7235,  2.0681,  2.3537,  0.9918,  1.2164,  -0.3325,  -2.2666,  0.1756,  0.1615,  0.5196,  -2.673,  -7.1201,  -2.9272,  -5.4551,  6.1563,
+  7.8768,  5.4153,  -2.5369,  0.0405,  4.1259,  -0.2108,  -4.6599,  -0.9803,  -1.3472,  -5.5873,  0.0334,  -6.0975,  -0.7915,  0.7551,  -0.1575,  2.8766,  -3.5702,  -0.2561,  4.01,  1.0615
+};
+
+const struct lsp_codebook newamp1vq_cb[] = {
+  /* /home/david/codec2-dev/src/codebook/train_120_1.txt */
+  {
+    20,
+    9,
+    512,
+    codes0
+  },
+  /* /home/david/codec2-dev/src/codebook/train_120_2.txt */
+  {
+    20,
+    9,
+    512,
+    codes1
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebooknewamp1_energy.c b/codec2/branches/0.7/src/codebooknewamp1_energy.c
new file mode 100644 (file)
index 0000000..6ecdd7c
--- /dev/null
@@ -0,0 +1,39 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under 
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* /home/david/codec2-dev/src/codebook/newamp1_energy_q.txt */
+static const float codes0[] = {
+  10,
+  12.5,
+  15,
+  17.5,
+  20,
+  22.5,
+  25,
+  27.5,
+  30,
+  32.5,
+  35,
+  37.5,
+  40,
+  42.5,
+  45,
+  47.5
+};
+
+const struct lsp_codebook newamp1_energy_cb[] = {
+  /* /home/david/codec2-dev/src/codebook/newamp1_energy_q.txt */
+  {
+    1,
+    4,
+    16,
+    codes0
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebookres.c b/codec2/branches/0.7/src/codebookres.c
new file mode 100644 (file)
index 0000000..f31577e
--- /dev/null
@@ -0,0 +1,97 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* ../src/codebook/lspres_centre1.txt */
+static const float codes0[] = {
+  300,
+  350,
+  400,
+  450,
+  500,
+  550,
+  600,
+  650
+};
+  /* ../src/codebook/lspres_bw1.txt */
+static const float codes1[] = {
+  35,
+  80,
+  140,
+  250
+};
+  /* ../src/codebook/lsp3.txt */
+static const float codes2[] = {
+  500,
+  550,
+  600,
+  650,
+  700,
+  750,
+  800,
+  850,
+  900,
+  950,
+  1000,
+  1050,
+  1100,
+  1150,
+  1200,
+  1250
+};
+  /* ../src/codebook/lsp4.txt */
+static const float codes3[] = {
+  700,
+  800,
+  900,
+  1000,
+  1100,
+  1200,
+  1300,
+  1400,
+  1500,
+  1600,
+  1700,
+  1800,
+  1900,
+  2000,
+  2100,
+  2200
+};
+
+const struct lsp_codebook lsp_cbres[] = {
+  /* ../src/codebook/lspres_centre1.txt */
+  {
+    1,
+    3,
+    8,
+    codes0
+  },
+  /* ../src/codebook/lspres_bw1.txt */
+  {
+    1,
+    2,
+    4,
+    codes1
+  },
+  /* ../src/codebook/lsp3.txt */
+  {
+    1,
+    4,
+    16,
+    codes2
+  },
+  /* ../src/codebook/lsp4.txt */
+  {
+    1,
+    4,
+    16,
+    codes3
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codebookvq.c b/codec2/branches/0.7/src/codebookvq.c
new file mode 100644 (file)
index 0000000..c72a843
--- /dev/null
@@ -0,0 +1,4223 @@
+/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */
+
+/*
+ * This intermediary file and the files that used to create it are under
+ * The LGPL. See the file COPYING.
+ */
+
+#include "defines.h"
+
+  /* codebook/lsp1.txt */
+static const float codes0[] = {
+  225,
+  250,
+  275,
+  300,
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600
+};
+  /* codebook/lsp2.txt */
+static const float codes1[] = {
+  325,
+  350,
+  375,
+  400,
+  425,
+  450,
+  475,
+  500,
+  525,
+  550,
+  575,
+  600,
+  625,
+  650,
+  675,
+  700
+};
+  /* codebook/lsp3.txt */
+static const float codes2[] = {
+  500,
+  550,
+  600,
+  650,
+  700,
+  750,
+  800,
+  850,
+  900,
+  950,
+  1000,
+  1050,
+  1100,
+  1150,
+  1200,
+  1250
+};
+  /* codebook/lsp4.txt */
+static const float codes3[] = {
+  700,
+  800,
+  900,
+  1000,
+  1100,
+  1200,
+  1300,
+  1400,
+  1500,
+  1600,
+  1700,
+  1800,
+  1900,
+  2000,
+  2100,
+  2200
+};
+  /* ../unittest/lsp45678910.txt */
+static const float codes4[] = {
+  1.08123,  1.57884,  1.85557,  1.93731,  2.53244,  2.64981,
+  1.0628,  1.45001,  1.83956,  1.9565,  2.48885,  2.65346,
+  1.10159,  1.36102,  1.83358,  1.93241,  2.50518,  2.62981,
+  1.07906,  1.37686,  1.87269,  1.95508,  2.54134,  2.63378,
+  1.09554,  1.63104,  1.86627,  2.06699,  2.50666,  2.57043,
+  1.09306,  1.56136,  1.77247,  2.12386,  2.54748,  2.61826,
+  1.09365,  1.50021,  1.78605,  2.07712,  2.48377,  2.57254,
+  1.03502,  1.48598,  1.67865,  2.07936,  2.40234,  2.51331,
+  1.23172,  1.63057,  1.84991,  2.02345,  2.46721,  2.57161,
+  1.20636,  1.47819,  1.85565,  2.0092,  2.43743,  2.55238,
+  1.20425,  1.49576,  1.8464,  2.03998,  2.50063,  2.59244,
+  1.27202,  1.43835,  1.8545,  2.03871,  2.51872,  2.62009,
+  1.29891,  1.48336,  1.83887,  1.98366,  2.48837,  2.59701,
+  1.38559,  1.50018,  1.81943,  1.9817,  2.50554,  2.61253,
+  1.41367,  1.56655,  1.76718,  1.99449,  2.56961,  2.62524,
+  1.46905,  1.62608,  1.75177,  2.04119,  2.60895,  2.65878,
+  1.48951,  1.61764,  1.68918,  2.05385,  2.66224,  2.70553,
+  1.43112,  1.53558,  1.64732,  1.81092,  2.57577,  2.6922,
+  1.41167,  1.60617,  1.73036,  1.96937,  2.62811,  2.69185,
+  1.34102,  1.63997,  2.19739,  2.28132,  2.44971,  2.626,
+  1.31988,  1.67483,  2.10118,  2.28173,  2.49978,  2.61148,
+  1.27462,  1.61012,  1.90144,  2.23566,  2.51818,  2.62888,
+  1.17221,  1.36564,  1.7847,  1.90445,  2.53808,  2.64619,
+  1.09616,  1.35011,  1.75499,  1.86967,  2.48657,  2.6055,
+  1.03654,  1.3262,  1.72989,  1.86212,  2.46119,  2.57545,
+  1.01653,  1.27725,  1.6888,  1.80838,  2.46298,  2.57624,
+  0.968031,  1.32901,  1.71641,  1.82136,  2.48115,  2.56195,
+  0.940641,  1.28334,  1.76788,  1.86054,  2.50314,  2.5949,
+  0.926995,  1.24333,  1.73891,  1.901,  2.4495,  2.55764,
+  0.839883,  1.23712,  1.70215,  1.81262,  2.42139,  2.49298,
+  0.924474,  1.18807,  1.75752,  1.8249,  2.45594,  2.61106,
+  0.96423,  1.20727,  1.66622,  1.87681,  2.50715,  2.58041,
+  0.989772,  1.18973,  1.69345,  1.80714,  2.44571,  2.56195,
+  0.919183,  1.20312,  1.67383,  1.77261,  2.3858,  2.51167,
+  0.978552,  1.17542,  1.61386,  1.72687,  2.32896,  2.5167,
+  1.01454,  1.25425,  1.58728,  1.75663,  2.40306,  2.51083,
+  1.09672,  1.23117,  1.5574,  1.84394,  2.46358,  2.55546,
+  1.16877,  1.35118,  1.61393,  1.83103,  2.47627,  2.58122,
+  1.17651,  1.26415,  1.56492,  1.76049,  2.48352,  2.58104,
+  1.01797,  1.24983,  1.42449,  1.59354,  2.45834,  2.52503,
+  1.05399,  1.21603,  1.51742,  1.85194,  2.34275,  2.50233,
+  0.908986,  1.2508,  1.59392,  1.8871,  2.37309,  2.53013,
+  0.993871,  1.16402,  1.61662,  1.77573,  2.56946,  2.65857,
+  1.10248,  1.38615,  1.57368,  1.78564,  2.31793,  2.50856,
+  1.20724,  1.39083,  1.55105,  1.85061,  2.33598,  2.49433,
+  0.905032,  1.41648,  1.58005,  1.84183,  2.50381,  2.6016,
+  0.79589,  1.10793,  1.59771,  2.0155,  2.40215,  2.53461,
+  0.732401,  1.15861,  1.55747,  1.938,  2.62642,  2.70543,
+  0.85967,  1.12906,  1.67186,  1.95399,  2.51479,  2.61587,
+  0.921647,  1.24536,  1.68375,  1.89446,  2.59964,  2.71656,
+  0.845409,  1.19476,  1.76731,  1.84451,  2.58977,  2.71694,
+  0.977678,  1.1414,  1.66711,  1.92383,  2.63201,  2.68907,
+  0.951137,  1.12255,  1.71418,  1.8859,  2.53576,  2.67211,
+  1.02995,  1.15955,  1.73944,  1.92833,  2.48818,  2.62352,
+  0.925634,  1.22593,  1.7518,  1.97075,  2.5329,  2.62107,
+  1.0123,  1.21143,  1.79395,  1.88586,  2.46727,  2.57249,
+  0.993978,  1.13747,  1.74347,  1.84089,  2.39008,  2.56639,
+  0.989822,  1.17307,  1.68756,  1.94893,  2.32553,  2.47342,
+  0.955854,  1.23723,  1.80741,  2.11677,  2.39103,  2.50278,
+  1.10336,  1.35799,  1.85224,  2.09709,  2.39275,  2.55324,
+  1.12887,  1.4409,  1.92791,  2.1767,  2.40798,  2.54428,
+  1.31613,  1.57544,  1.96457,  2.15894,  2.48584,  2.57613,
+  1.4696,  1.7721,  1.95484,  2.16407,  2.39962,  2.48192,
+  1.50652,  1.75488,  2.01841,  2.24949,  2.48627,  2.60761,
+  1.52419,  1.77645,  2.05458,  2.27569,  2.58498,  2.66908,
+  1.518,  1.85028,  2.02643,  2.30188,  2.57753,  2.66918,
+  1.42205,  1.78898,  1.96748,  2.18477,  2.59685,  2.69968,
+  1.20841,  1.4347,  1.92362,  2.00377,  2.60293,  2.68501,
+  1.22117,  1.43657,  1.87997,  2.0334,  2.49815,  2.69542,
+  1.21771,  1.37598,  1.90861,  1.97303,  2.48056,  2.6454,
+  1.20035,  1.41224,  1.86328,  2.05454,  2.40923,  2.64633,
+  1.43945,  1.67593,  2.06471,  2.27323,  2.60645,  2.69621,
+  1.54757,  1.95602,  2.08379,  2.38708,  2.63432,  2.71122,
+  1.74537,  1.99526,  2.17627,  2.40949,  2.63225,  2.70742,
+  1.81929,  1.98216,  2.21017,  2.45219,  2.60377,  2.66452,
+  1.66955,  1.94018,  2.10087,  2.38694,  2.53082,  2.63087,
+  1.59768,  1.94591,  2.07284,  2.33889,  2.54425,  2.60825,
+  1.65615,  1.88869,  1.98455,  2.30113,  2.51078,  2.58636,
+  1.6188,  1.89886,  2.02474,  2.29131,  2.44053,  2.56029,
+  1.48128,  1.82621,  1.97192,  2.19291,  2.41702,  2.53029,
+  1.31873,  1.58154,  1.84545,  2.164,  2.38923,  2.50542,
+  1.34133,  1.56585,  1.80288,  2.21848,  2.43077,  2.54583,
+  1.31851,  1.41266,  1.67762,  2.18235,  2.37275,  2.47653,
+  1.24372,  1.45667,  1.66571,  2.12671,  2.33287,  2.43845,
+  1.1525,  1.45886,  1.58294,  2.03752,  2.3421,  2.4283,
+  1.02538,  1.4076,  1.55153,  1.84679,  2.28286,  2.38544,
+  0.87656,  1.38433,  1.5829,  1.74194,  2.23992,  2.33845,
+  0.953781,  1.44188,  1.5924,  1.76417,  2.29409,  2.4742,
+  0.899968,  1.45403,  1.63436,  1.72431,  2.3534,  2.5975,
+  0.784159,  1.42393,  1.73726,  1.85596,  2.39003,  2.61454,
+  0.802442,  1.39707,  1.65855,  1.81679,  2.42939,  2.5001,
+  0.863071,  1.31849,  1.64602,  1.81297,  2.3981,  2.50385,
+  0.89687,  1.30624,  1.67159,  1.90217,  2.46653,  2.60152,
+  0.999503,  1.30429,  1.70842,  1.89904,  2.51234,  2.65519,
+  1.04528,  1.2663,  1.66963,  1.84632,  2.51707,  2.63748,
+  1.03846,  1.15853,  1.64378,  1.86528,  2.5832,  2.65894,
+  1.02632,  1.21931,  1.76835,  1.84092,  2.53817,  2.67333,
+  1.08097,  1.21543,  1.73019,  1.83693,  2.23686,  2.60887,
+  1.1018,  1.43151,  1.75208,  1.91896,  2.09124,  2.53896,
+  1.17873,  1.29731,  1.7241,  1.85075,  2.31029,  2.62153,
+  1.15118,  1.23968,  1.75479,  1.85052,  2.5391,  2.70599,
+  1.2027,  1.3006,  1.76334,  1.86743,  2.47072,  2.66465,
+  1.26112,  1.36868,  1.75328,  1.84665,  2.46151,  2.6526,
+  1.26307,  1.36429,  1.79767,  1.87694,  2.54373,  2.66022,
+  1.32015,  1.41593,  1.80983,  1.90322,  2.51555,  2.64824,
+  1.33987,  1.45935,  1.80668,  1.92458,  2.49148,  2.58705,
+  1.35517,  1.45177,  1.7634,  1.94416,  2.47263,  2.56117,
+  1.32792,  1.42891,  1.70445,  1.91482,  2.39737,  2.50347,
+  1.3076,  1.41535,  1.61629,  1.84079,  2.32217,  2.47099,
+  1.24825,  1.34921,  1.61761,  1.77273,  2.25068,  2.48653,
+  1.09657,  1.35568,  1.62611,  1.94199,  2.31385,  2.49821,
+  1.01253,  1.34284,  1.64785,  1.90716,  2.43593,  2.53319,
+  0.944393,  1.39928,  1.643,  1.93199,  2.33198,  2.48991,
+  0.883306,  1.40234,  1.70636,  2.02537,  2.37371,  2.54371,
+  0.829559,  1.23577,  1.71275,  2.18485,  2.38674,  2.54418,
+  0.923799,  1.51311,  1.70309,  2.10529,  2.47648,  2.55516,
+  0.772688,  1.4433,  1.65612,  2.05301,  2.45044,  2.53252,
+  0.776285,  1.4032,  1.73402,  1.93526,  2.46409,  2.5668,
+  0.782396,  1.41881,  1.75888,  1.97322,  2.54833,  2.6103,
+  0.789572,  1.41108,  1.77153,  2.06041,  2.54026,  2.63125,
+  0.774326,  1.28802,  1.83727,  1.96095,  2.51242,  2.58163,
+  0.811751,  1.27403,  1.81001,  1.88574,  2.56546,  2.63922,
+  0.844982,  1.32083,  1.87391,  1.9446,  2.56105,  2.66172,
+  0.881256,  1.69536,  1.90698,  2.07889,  2.61855,  2.67865,
+  1.09989,  1.72782,  1.97132,  2.15314,  2.50969,  2.60295,
+  1.17385,  1.68544,  1.91746,  2.14743,  2.38305,  2.56703,
+  1.10155,  1.54322,  1.82061,  2.05532,  2.33872,  2.58503,
+  0.975012,  1.37972,  1.77663,  2.03329,  2.19415,  2.51822,
+  0.967054,  1.08246,  1.61897,  2.07793,  2.20684,  2.37089,
+  1.00961,  1.12061,  1.53418,  2.08853,  2.28294,  2.42058,
+  0.899159,  1.20852,  1.42369,  1.97032,  2.28727,  2.4989,
+  0.879682,  1.31448,  1.47949,  1.68936,  2.20974,  2.28576,
+  1.03347,  1.24384,  1.47314,  1.66799,  2.15942,  2.25504,
+  1.04841,  1.25589,  1.537,  1.82005,  2.14225,  2.31375,
+  1.04825,  1.18926,  1.70511,  1.83599,  2.10545,  2.37206,
+  1.03432,  1.13888,  1.51462,  1.82966,  2.17045,  2.42561,
+  1.10388,  1.21765,  1.62215,  1.80585,  2.02753,  2.37681,
+  1.08723,  1.19501,  1.55902,  1.89504,  2.25012,  2.3792,
+  1.13001,  1.29387,  1.6924,  1.85888,  2.1972,  2.34906,
+  1.16289,  1.3046,  1.69102,  1.96932,  2.26861,  2.43029,
+  1.15181,  1.25793,  1.67383,  1.90202,  2.18916,  2.45871,
+  1.16844,  1.27183,  1.55733,  2.08415,  2.30803,  2.42037,
+  1.2351,  1.34019,  1.65679,  2.09516,  2.28319,  2.40964,
+  1.25239,  1.35536,  1.60985,  2.08519,  2.33271,  2.48887,
+  1.22631,  1.34399,  1.67305,  2.21553,  2.46,  2.54692,
+  1.40818,  1.56645,  1.70193,  2.1551,  2.54024,  2.58859,
+  1.304,  1.549,  1.65358,  2.12874,  2.58947,  2.63332,
+  1.31253,  1.48894,  1.69055,  1.98288,  2.55839,  2.62252,
+  1.30359,  1.48566,  1.773,  1.99142,  2.55563,  2.65006,
+  1.2572,  1.52892,  1.88049,  2.04567,  2.40009,  2.56749,
+  1.29472,  1.63432,  1.91154,  2.04666,  2.43808,  2.61113,
+  1.32844,  1.71607,  1.8503,  2.02126,  2.50705,  2.61286,
+  1.13808,  1.26904,  1.79259,  1.89815,  2.53041,  2.65356,
+  1.02479,  1.14554,  1.68822,  1.81293,  2.42504,  2.65093,
+  1.05666,  1.17804,  1.59034,  1.74735,  2.36845,  2.61871,
+  0.994299,  1.11084,  1.63265,  1.73054,  2.33769,  2.5503,
+  0.96003,  1.10348,  1.6328,  1.74508,  2.19725,  2.53053,
+  0.952099,  1.07891,  1.70416,  1.83731,  2.31907,  2.54431,
+  0.901034,  1.0748,  1.65366,  1.78859,  2.39383,  2.53312,
+  0.970595,  1.13005,  1.56835,  1.82097,  2.44511,  2.56337,
+  0.8832,  1.02914,  1.48058,  1.88436,  2.32162,  2.47072,
+  0.817959,  0.941844,  1.41014,  1.54071,  2.17404,  2.48277,
+  0.772028,  0.888033,  1.49012,  1.71709,  2.32435,  2.56046,
+  0.8742,  1.0201,  1.57148,  1.74681,  2.43739,  2.56133,
+  0.827282,  1.01003,  1.60538,  1.75068,  2.26185,  2.4816,
+  0.790605,  1.149,  1.65382,  1.78105,  2.35864,  2.49161,
+  0.746581,  0.96108,  1.60491,  1.879,  2.31927,  2.55158,
+  0.845418,  0.96953,  1.69617,  1.89093,  2.30188,  2.62149,
+  0.826083,  1.01605,  1.6586,  1.85255,  2.43588,  2.57274,
+  0.80426,  0.948999,  1.68449,  2.10334,  2.47505,  2.57585,
+  0.837016,  1.03,  1.67699,  1.79665,  2.49802,  2.63103,
+  0.779629,  0.917041,  1.60707,  1.8689,  2.45957,  2.6289,
+  0.802981,  0.922379,  1.55614,  1.96784,  2.59545,  2.69251,
+  0.821239,  0.952349,  1.58525,  2.0958,  2.59371,  2.65593,
+  0.819528,  1.10955,  1.52684,  1.76751,  2.6378,  2.71051,
+  0.846222,  1.05572,  1.70728,  1.83863,  2.114,  2.5014,
+  0.956553,  1.43985,  1.7249,  1.93982,  2.14519,  2.43191,
+  1.33429,  1.55159,  1.7214,  2.01917,  2.178,  2.32944,
+  1.24736,  1.57146,  1.83452,  2.11416,  2.26821,  2.48981,
+  1.22315,  1.57342,  1.84625,  2.01609,  2.21928,  2.45785,
+  1.23993,  1.53779,  1.8228,  2.04648,  2.44445,  2.57805,
+  1.29968,  1.55774,  1.7983,  2.08069,  2.39337,  2.5752,
+  1.27312,  1.47413,  1.81487,  2.01491,  2.40501,  2.60292,
+  1.22903,  1.4485,  1.75715,  2.05057,  2.41716,  2.59461,
+  1.2063,  1.5151,  1.78896,  2.04215,  2.36856,  2.5858,
+  1.1589,  1.5448,  1.86145,  2.06665,  2.40525,  2.59099,
+  1.20326,  1.47986,  1.83352,  2.07062,  2.4318,  2.5857,
+  1.17077,  1.55578,  1.82667,  2.07708,  2.46748,  2.61941,
+  1.11628,  1.59353,  1.82425,  2.16082,  2.42781,  2.60049,
+  1.25031,  1.6173,  1.96265,  2.15224,  2.53124,  2.63143,
+  1.353,  1.64524,  2.07019,  2.18038,  2.61203,  2.68877,
+  1.46033,  1.91719,  2.08682,  2.31459,  2.64118,  2.72306,
+  1.5571,  1.91661,  2.0569,  2.2632,  2.64033,  2.7028,
+  1.41067,  1.90339,  2.07783,  2.22294,  2.6154,  2.69412,
+  1.34049,  1.80404,  2.04002,  2.14956,  2.60771,  2.67815,
+  1.09068,  1.32106,  1.86274,  1.98378,  2.47586,  2.59244,
+  1.00246,  1.26551,  1.81302,  1.90434,  2.49926,  2.62654,
+  1.05139,  1.16129,  1.83253,  1.95508,  2.50234,  2.62475,
+  0.942516,  1.06424,  1.66956,  1.97725,  2.46418,  2.59833,
+  0.869608,  0.984141,  1.45461,  1.95618,  2.50789,  2.61787,
+  0.972489,  1.13547,  1.52915,  1.72998,  2.41157,  2.57108,
+  1.05128,  1.14941,  1.54752,  1.82715,  2.51133,  2.61762,
+  1.07974,  1.19121,  1.53936,  1.94473,  2.54524,  2.63216,
+  1.18206,  1.26003,  1.5961,  2.08466,  2.51186,  2.57941,
+  1.172,  1.35276,  1.46275,  2.01506,  2.62536,  2.67937,
+  1.20054,  1.32298,  1.5156,  1.7692,  2.52314,  2.66683,
+  1.22809,  1.30713,  1.73403,  1.91475,  2.24482,  2.56203,
+  1.17619,  1.32166,  1.78231,  1.88258,  2.27136,  2.52145,
+  1.15003,  1.48622,  1.77415,  1.97093,  2.38508,  2.61264,
+  1.10316,  1.455,  1.72062,  1.89959,  2.35671,  2.59138,
+  1.07047,  1.38631,  1.74693,  1.89198,  2.36751,  2.54357,
+  0.95361,  1.17616,  1.64355,  1.91998,  2.37206,  2.57246,
+  1.05232,  1.40517,  1.68895,  1.83167,  2.54288,  2.63248,
+  0.996802,  1.44143,  1.68446,  1.82195,  2.59599,  2.65884,
+  1.02655,  1.33494,  1.74094,  1.84038,  2.57165,  2.67897,
+  1.10832,  1.20084,  1.70613,  1.99908,  2.51466,  2.64821,
+  1.13332,  1.21947,  1.74777,  2.01308,  2.40664,  2.64036,
+  1.14214,  1.21872,  1.81464,  1.95106,  2.43007,  2.66618,
+  1.08156,  1.20709,  1.84645,  1.94628,  2.33914,  2.61266,
+  1.14637,  1.23863,  1.87425,  1.9681,  2.42738,  2.59563,
+  1.06941,  1.39313,  1.85976,  1.94182,  2.37447,  2.53818,
+  1.06022,  1.40293,  1.78464,  1.90995,  2.08085,  2.37542,
+  0.893759,  1.22533,  1.74143,  1.89549,  2.06221,  2.44178,
+  0.911307,  1.30139,  1.65149,  1.79817,  1.99688,  2.20866,
+  1.10291,  1.50331,  1.70777,  1.80853,  1.95863,  2.31168,
+  1.14945,  1.32806,  1.73828,  1.90461,  2.06187,  2.25797,
+  1.12135,  1.23056,  1.74878,  1.95066,  2.08647,  2.38929,
+  0.94897,  1.10189,  1.67664,  1.87539,  2.01682,  2.29668,
+  1.03508,  1.16223,  1.64138,  1.95271,  2.10095,  2.35872,
+  0.994183,  1.11431,  1.5476,  1.77373,  1.96608,  2.3363,
+  1.02511,  1.1397,  1.58524,  1.91237,  2.10246,  2.48243,
+  0.955352,  1.06222,  1.65906,  1.84841,  2.04328,  2.48743,
+  1.0491,  1.12055,  1.44698,  1.94902,  2.0269,  2.56059,
+  1.01243,  1.13828,  1.36794,  2.00847,  2.18944,  2.42242,
+  1.08203,  1.23491,  1.35176,  1.82717,  2.17316,  2.30024,
+  1.09436,  1.23514,  1.41642,  1.92259,  2.12823,  2.41941,
+  1.03451,  1.15131,  1.49236,  1.98085,  2.14904,  2.36531,
+  1.01309,  1.15454,  1.45996,  1.94304,  2.28176,  2.39727,
+  0.987103,  1.27435,  1.56187,  1.91746,  2.33429,  2.49565,
+  0.989791,  1.28917,  1.62314,  1.98233,  2.34503,  2.54805,
+  1.04201,  1.22597,  1.61002,  1.9748,  2.40631,  2.53704,
+  1.01969,  1.32372,  1.67908,  1.98369,  2.44302,  2.56193,
+  1.03098,  1.24991,  1.75329,  1.9703,  2.44275,  2.5771,
+  1.07865,  1.28137,  1.82168,  2.04699,  2.51249,  2.6143,
+  1.0425,  1.31828,  1.81754,  1.97774,  2.53877,  2.64347,
+  1.03375,  1.32343,  1.88596,  1.99364,  2.58713,  2.64829,
+  1.08416,  1.43412,  1.89966,  1.97448,  2.66167,  2.7171,
+  1.09579,  1.4813,  1.91655,  1.97041,  2.67123,  2.73097,
+  1.14796,  1.55307,  1.88454,  1.96066,  2.50184,  2.66788,
+  1.13778,  1.49891,  1.96262,  2.04724,  2.53731,  2.64235,
+  1.10886,  1.43549,  1.95549,  2.19587,  2.51428,  2.60153,
+  1.19107,  1.55785,  1.98454,  2.27079,  2.54188,  2.64206,
+  1.11074,  1.55308,  1.97813,  2.21105,  2.61337,  2.70664,
+  1.11409,  1.72802,  1.97504,  2.12448,  2.60293,  2.68194,
+  1.14848,  1.62709,  1.96813,  2.0739,  2.60736,  2.68667,
+  1.109,  1.45065,  1.9611,  2.05861,  2.61165,  2.69461,
+  1.0959,  1.31876,  1.86664,  2.09629,  2.57468,  2.65884,
+  1.11656,  1.36797,  1.92253,  2.01651,  2.54944,  2.64623,
+  1.12947,  1.52911,  1.9422,  2.00334,  2.52787,  2.69992,
+  1.13905,  1.67954,  1.94587,  2.03292,  2.53743,  2.64217,
+  1.21921,  1.59942,  1.9296,  2.01109,  2.5391,  2.70528,
+  1.23397,  1.5562,  1.931,  2.08479,  2.57858,  2.67583,
+  1.23443,  1.65374,  2.03321,  2.25676,  2.63755,  2.69966,
+  1.25529,  1.47504,  2.02254,  2.28923,  2.58769,  2.70395,
+  1.25339,  1.4722,  1.9564,  2.21119,  2.57424,  2.6761,
+  1.12685,  1.58721,  1.95082,  2.03149,  2.41685,  2.61446,
+  1.00706,  1.6083,  1.89623,  1.98634,  2.22302,  2.52403,
+  1.06728,  1.72945,  1.93189,  2.04533,  2.16485,  2.40091,
+  0.94666,  1.69978,  1.87062,  1.98183,  2.13567,  2.44769,
+  1.00269,  1.72856,  1.93991,  2.07252,  2.27479,  2.46748,
+  1.14879,  1.60055,  2.00306,  2.12803,  2.40911,  2.50653,
+  1.19137,  1.35951,  1.90844,  2.11699,  2.36908,  2.52939,
+  1.22974,  1.31636,  1.90147,  2.00117,  2.36835,  2.5757,
+  1.16745,  1.28408,  1.85155,  2.05628,  2.44629,  2.57376,
+  1.17705,  1.28298,  1.79608,  2.01457,  2.4099,  2.52443,
+  1.16655,  1.28173,  1.80413,  1.93859,  2.38305,  2.5438,
+  1.14471,  1.2662,  1.75578,  1.86551,  2.35412,  2.57514,
+  1.16847,  1.28356,  1.69505,  1.81754,  2.30279,  2.52956,
+  1.09347,  1.31611,  1.62583,  1.79105,  2.30331,  2.40856,
+  1.07299,  1.21888,  1.58691,  1.72531,  2.2192,  2.34352,
+  0.946241,  1.17284,  1.42629,  1.55168,  2.19257,  2.32173,
+  1.0018,  1.17498,  1.50744,  1.69786,  2.2408,  2.47824,
+  0.992564,  1.25778,  1.42909,  1.81983,  2.23415,  2.43492,
+  0.933586,  1.25556,  1.37246,  1.68627,  2.26598,  2.34947,
+  0.987914,  1.16288,  1.40442,  1.56348,  2.22767,  2.48537,
+  1.05858,  1.18583,  1.32538,  1.44559,  2.16451,  2.45514,
+  1.04227,  1.14961,  1.38904,  1.47383,  1.90667,  2.39013,
+  0.966952,  1.07554,  1.28815,  1.4051,  2.06186,  2.45199,
+  0.90153,  1.19448,  1.35473,  1.70575,  2.32503,  2.43481,
+  1.03842,  1.29243,  1.52731,  1.90984,  2.23033,  2.46514,
+  1.33601,  1.44169,  1.84913,  2.20803,  2.4144,  2.53251,
+  1.43622,  1.64565,  2.00864,  2.19816,  2.50228,  2.60141,
+  1.42434,  1.68443,  1.92981,  2.1225,  2.51228,  2.60486,
+  1.4522,  1.72299,  1.96221,  2.15666,  2.4841,  2.58459,
+  1.482,  1.73524,  1.97119,  2.2228,  2.51231,  2.62362,
+  1.39256,  1.72127,  1.9403,  2.17497,  2.48894,  2.60185,
+  1.24335,  1.55846,  1.80982,  1.99089,  2.38197,  2.53748,
+  1.19929,  1.4215,  1.76311,  1.99088,  2.35892,  2.48956,
+  1.21777,  1.34878,  1.71467,  1.91684,  2.37973,  2.45696,
+  1.21952,  1.32685,  1.71966,  1.83808,  2.29933,  2.43541,
+  1.26307,  1.35366,  1.78723,  1.91897,  2.32039,  2.44825,
+  1.27096,  1.3738,  1.71818,  1.85793,  2.36692,  2.48175,
+  1.28435,  1.36807,  1.79391,  1.89508,  2.35679,  2.5246,
+  1.24479,  1.35366,  1.78295,  1.92869,  2.22572,  2.37995,
+  1.26928,  1.36873,  1.71918,  1.90968,  2.26716,  2.49154,
+  1.24931,  1.33819,  1.79992,  1.9171,  2.27469,  2.53322,
+  1.1795,  1.25905,  1.80297,  1.92733,  2.22893,  2.50364,
+  1.14096,  1.2459,  1.70866,  1.92379,  2.24346,  2.55734,
+  1.06395,  1.20903,  1.73729,  1.94535,  2.3387,  2.57309,
+  1.00347,  1.10916,  1.74513,  1.90219,  2.30844,  2.60161,
+  0.937618,  1.07754,  1.7478,  1.86965,  2.20505,  2.57045,
+  0.885099,  1.19245,  1.79054,  1.87616,  2.36031,  2.59811,
+  0.803485,  0.966415,  1.76846,  1.92874,  2.19672,  2.53046,
+  0.797205,  1.12072,  1.77658,  1.87857,  2.37036,  2.61434,
+  0.831514,  1.05908,  1.8088,  1.90548,  2.44821,  2.57305,
+  0.806597,  0.967446,  1.82939,  1.96368,  2.35863,  2.65324,
+  0.699378,  0.851831,  1.73945,  1.93394,  2.51638,  2.65525,
+  0.739203,  1.03399,  1.90211,  2.01033,  2.49415,  2.62982,
+  0.945605,  1.07971,  1.79635,  2.03954,  2.58186,  2.69978,
+  0.843512,  1.30486,  1.83545,  2.03683,  2.60022,  2.67783,
+  0.970152,  1.41437,  1.85405,  1.95779,  2.59605,  2.66543,
+  1.06728,  1.43854,  1.88843,  2.06709,  2.53102,  2.64318,
+  1.11762,  1.56311,  1.88632,  2.21887,  2.53022,  2.62408,
+  1.20966,  1.62691,  1.9437,  2.18743,  2.55509,  2.65867,
+  1.33889,  1.81288,  2.03089,  2.3052,  2.56927,  2.66116,
+  1.30337,  1.8401,  2.03598,  2.28675,  2.61423,  2.71336,
+  1.19343,  1.72735,  1.9262,  2.1844,  2.57478,  2.63181,
+  1.06351,  1.71719,  1.90366,  2.11905,  2.44481,  2.49767,
+  1.06218,  1.18895,  1.81048,  2.04498,  2.32238,  2.57878,
+  1.0732,  1.17756,  1.65473,  2.02326,  2.20037,  2.44287,
+  1.02781,  1.16542,  1.66947,  1.85961,  2.20214,  2.46247,
+  1.03558,  1.14824,  1.6049,  1.87255,  2.25785,  2.55168,
+  1.00721,  1.13109,  1.57915,  1.96979,  2.33164,  2.50791,
+  0.908594,  1.0056,  1.46327,  2.07237,  2.30436,  2.40736,
+  0.981614,  1.12643,  1.28057,  1.88685,  2.10192,  2.48784,
+  1.00676,  1.13256,  1.25309,  1.71832,  2.18925,  2.4366,
+  0.89983,  1.15654,  1.26075,  1.69671,  2.11666,  2.2283,
+  0.896996,  1.24655,  1.43687,  1.64519,  2.07364,  2.14913,
+  0.965481,  1.06967,  1.44649,  1.94949,  2.09158,  2.29833,
+  0.898113,  1.05877,  1.61756,  1.94155,  2.11357,  2.37474,
+  0.769481,  1.15938,  1.59741,  1.95985,  2.28384,  2.4182,
+  0.908091,  1.30534,  1.47357,  1.86255,  2.16415,  2.33109,
+  0.924282,  1.33469,  1.5632,  2.04354,  2.40601,  2.51576,
+  0.972939,  1.38197,  1.54999,  2.02124,  2.26849,  2.41933,
+  1.03223,  1.48403,  1.62003,  1.95223,  2.26732,  2.48644,
+  1.00523,  1.35469,  1.6202,  1.77792,  2.22307,  2.49757,
+  1.07274,  1.24504,  1.66167,  1.81939,  2.2605,  2.4687,
+  1.13447,  1.25048,  1.73703,  1.86897,  2.3032,  2.46643,
+  1.14594,  1.29326,  1.72851,  1.95098,  2.35098,  2.50402,
+  1.22636,  1.3298,  1.75078,  1.98214,  2.34784,  2.55303,
+  1.2348,  1.32811,  1.69673,  2.06056,  2.43731,  2.5356,
+  1.24713,  1.3605,  1.74295,  1.96135,  2.47408,  2.66845,
+  1.23474,  1.32984,  1.68863,  1.91333,  2.44294,  2.6277,
+  1.23043,  1.32664,  1.69759,  1.80604,  2.38147,  2.61854,
+  1.18857,  1.27308,  1.70898,  1.969,  2.34068,  2.58896,
+  1.20428,  1.33122,  1.83552,  2.14126,  2.46323,  2.58349,
+  1.20237,  1.39722,  1.86375,  2.15516,  2.59973,  2.68119,
+  1.21758,  1.3333,  1.7639,  1.99498,  2.60184,  2.68482,
+  1.27237,  1.36445,  1.77635,  1.9521,  2.56342,  2.67617,
+  1.33017,  1.43465,  1.82509,  1.93803,  2.57941,  2.6661,
+  1.38355,  1.51477,  1.77471,  2.135,  2.52858,  2.61471,
+  1.48823,  1.63125,  1.79594,  2.18059,  2.49779,  2.58593,
+  1.49785,  1.59843,  1.7604,  1.98572,  2.53807,  2.62222,
+  1.44651,  1.55569,  1.67548,  1.89962,  2.54707,  2.63713,
+  1.42019,  1.65176,  1.88812,  2.20156,  2.49872,  2.62437,
+  1.52485,  1.74892,  1.93948,  2.13259,  2.42662,  2.6043,
+  1.58821,  1.78697,  1.96571,  2.12325,  2.41743,  2.57989,
+  1.60305,  1.80525,  1.93272,  2.08806,  2.49088,  2.62847,
+  1.52171,  1.85304,  1.96816,  2.19842,  2.53092,  2.59723,
+  1.49631,  1.78581,  2.00198,  2.20617,  2.57416,  2.64528,
+  1.4052,  1.50056,  1.90867,  2.17922,  2.54373,  2.64577,
+  1.36955,  1.50131,  1.8488,  2.08986,  2.55112,  2.64362,
+  1.39538,  1.48864,  1.8724,  2.02812,  2.53026,  2.59919,
+  1.35458,  1.50897,  1.84888,  1.97668,  2.50493,  2.57936,
+  1.32575,  1.41133,  1.83713,  1.97079,  2.50272,  2.58483,
+  1.2645,  1.39044,  1.76476,  2.08734,  2.51928,  2.62504,
+  1.2809,  1.35565,  1.79029,  1.99571,  2.50257,  2.58736,
+  1.26744,  1.36084,  1.85803,  2.03563,  2.50938,  2.58487,
+  1.2389,  1.48754,  1.78666,  2.08035,  2.48091,  2.58214,
+  1.22871,  1.44114,  1.71596,  1.89333,  2.50707,  2.56513,
+  1.16735,  1.39731,  1.67205,  1.92353,  2.43839,  2.52352,
+  1.16923,  1.35681,  1.56743,  1.95038,  2.37895,  2.46801,
+  1.24024,  1.4709,  1.62973,  2.02468,  2.37672,  2.45487,
+  1.37086,  1.66529,  1.8315,  2.17643,  2.4864,  2.58657,
+  1.51337,  1.65704,  1.96501,  2.29801,  2.53215,  2.62301,
+  1.44694,  1.61268,  1.92909,  2.2323,  2.46621,  2.56515,
+  1.43066,  1.66453,  1.88216,  2.23458,  2.42166,  2.52729,
+  1.51155,  1.65893,  1.94404,  2.1985,  2.45195,  2.58835,
+  1.53944,  1.74136,  2.11106,  2.22992,  2.43894,  2.61506,
+  1.51095,  1.84689,  2.06179,  2.20245,  2.48411,  2.57263,
+  1.36639,  1.61165,  2.07937,  2.26007,  2.46706,  2.58803,
+  1.38358,  1.64134,  1.99735,  2.22615,  2.49144,  2.61163,
+  1.38146,  1.7069,  1.96306,  2.12555,  2.5968,  2.68111,
+  1.36003,  1.55825,  1.94966,  2.05483,  2.59957,  2.71455,
+  1.37934,  1.49178,  1.9259,  2.04634,  2.53937,  2.69605,
+  1.31327,  1.4694,  1.86311,  2.14175,  2.55396,  2.6681,
+  1.20152,  1.563,  1.92503,  2.09301,  2.47661,  2.61441,
+  0.965563,  1.66213,  1.8361,  2.07187,  2.53005,  2.57845,
+  0.976435,  1.63512,  1.84473,  2.00512,  2.55308,  2.61415,
+  1.09816,  1.54948,  1.82643,  1.90791,  2.49067,  2.62563,
+  0.971599,  1.43193,  1.81819,  1.92319,  2.49384,  2.56812,
+  0.881008,  1.27287,  1.90143,  1.95922,  2.51367,  2.59602,
+  0.915929,  1.47877,  1.9557,  2.08255,  2.49435,  2.58578,
+  1.00818,  1.57939,  1.8982,  2.13917,  2.47763,  2.55121,
+  0.937399,  1.50757,  1.80391,  1.92259,  2.54605,  2.6373,
+  0.848413,  1.35823,  1.78393,  1.90623,  2.47701,  2.58853,
+  0.863404,  1.48863,  1.8355,  1.93003,  2.4655,  2.54532,
+  0.844376,  1.62228,  1.8268,  2.04836,  2.49055,  2.54581,
+  0.869731,  1.70503,  1.8547,  2.1116,  2.51701,  2.59345,
+  0.862235,  1.62302,  1.89937,  2.02871,  2.52784,  2.5748,
+  0.931658,  1.57634,  1.85361,  1.97512,  2.54224,  2.61479,
+  0.848799,  1.58841,  1.8471,  1.9559,  2.53407,  2.58456,
+  0.737814,  1.45722,  1.82999,  1.9662,  2.50127,  2.57945,
+  0.786199,  1.10008,  1.86037,  1.96428,  2.41936,  2.56613,
+  0.728962,  1.04084,  1.77382,  1.96373,  2.35695,  2.57887,
+  0.733093,  1.14778,  1.78977,  1.90929,  2.34982,  2.4811,
+  0.785959,  1.28024,  1.73049,  1.9267,  2.34691,  2.42248,
+  0.784924,  1.44682,  1.66969,  1.93537,  2.36832,  2.4596,
+  0.758523,  1.46692,  1.8059,  1.94659,  2.35221,  2.42634,
+  0.767907,  1.54429,  1.76817,  2.00394,  2.23904,  2.38619,
+  0.896374,  1.56207,  1.71693,  1.9033,  2.30824,  2.43058,
+  0.83453,  1.50481,  1.73742,  1.91773,  2.40928,  2.49329,
+  0.896027,  1.40695,  1.73003,  1.90333,  2.43125,  2.53972,
+  1.03967,  1.36412,  1.80628,  1.94817,  2.44069,  2.55797,
+  1.09345,  1.41236,  1.83372,  1.9401,  2.48965,  2.56445,
+  1.19018,  1.38617,  1.8487,  1.9562,  2.48155,  2.58088,
+  1.24316,  1.35042,  1.8118,  1.89359,  2.46758,  2.61352,
+  1.22199,  1.30871,  1.81591,  1.91199,  2.41753,  2.601,
+  1.22837,  1.34362,  1.76316,  1.8726,  2.39489,  2.58272,
+  1.27839,  1.38971,  1.7385,  1.87027,  2.42085,  2.53285,
+  1.21164,  1.40179,  1.71015,  1.81102,  2.36383,  2.48224,
+  1.1615,  1.40068,  1.76667,  1.89174,  2.39261,  2.49592,
+  1.11494,  1.40549,  1.71834,  1.92742,  2.35682,  2.46833,
+  1.07468,  1.45296,  1.66872,  1.89809,  2.33653,  2.44346,
+  1.00671,  1.35625,  1.62948,  1.84847,  2.31389,  2.42632,
+  0.966452,  1.45792,  1.65469,  1.90639,  2.32006,  2.41834,
+  0.939007,  1.51999,  1.66701,  1.98942,  2.39067,  2.48895,
+  0.94684,  1.48398,  1.70109,  2.10557,  2.39144,  2.49007,
+  0.909129,  1.50106,  1.66537,  2.00494,  2.2567,  2.38984,
+  0.958919,  1.39061,  1.68008,  2.10716,  2.29725,  2.44084,
+  1.46216,  1.58856,  1.80854,  2.10989,  2.26483,  2.41747,
+  1.30164,  1.67381,  1.89252,  2.16811,  2.47756,  2.56162,
+  1.15277,  1.52933,  1.78378,  2.01435,  2.44661,  2.56093,
+  1.1287,  1.49302,  1.74816,  1.93027,  2.53067,  2.62159,
+  1.16436,  1.49686,  1.76766,  1.87114,  2.60725,  2.68479,
+  1.12271,  1.38051,  1.76224,  1.8756,  2.44152,  2.73281,
+  1.17391,  1.54593,  1.8438,  1.93379,  2.12345,  2.62901,
+  1.15544,  1.46581,  1.79388,  1.92855,  2.16855,  2.60961,
+  1.14781,  1.48454,  1.81642,  1.90876,  2.26262,  2.70408,
+  1.18587,  1.39352,  1.81185,  1.88111,  2.54429,  2.7359,
+  1.1533,  1.45114,  1.8554,  1.88862,  2.60331,  2.73808,
+  1.20885,  1.58236,  1.78486,  1.88009,  2.59648,  2.72788,
+  1.19484,  1.5429,  1.91906,  2.02314,  2.55189,  2.63419,
+  1.23033,  1.49206,  1.93722,  2.13361,  2.61573,  2.69023,
+  1.25876,  1.58131,  1.98007,  2.13876,  2.59904,  2.69103,
+  1.22069,  1.57296,  1.91721,  2.17754,  2.59959,  2.70201,
+  1.25814,  1.55663,  1.87174,  2.13263,  2.58551,  2.67331,
+  1.23377,  1.59824,  1.84996,  2.01367,  2.54286,  2.63448,
+  1.26976,  1.56079,  1.86522,  2.07633,  2.52108,  2.61744,
+  1.11656,  1.68088,  1.78169,  1.9205,  2.59221,  2.67584,
+  1.04821,  1.663,  1.8174,  1.91517,  2.48459,  2.62308,
+  0.954241,  1.61967,  1.81346,  1.88169,  2.55067,  2.63197,
+  0.964363,  1.57975,  1.72871,  1.86213,  2.56757,  2.63633,
+  1.29692,  1.64688,  1.88926,  2.06927,  2.32023,  2.48139,
+  1.23277,  1.6196,  1.95547,  2.06656,  2.33528,  2.45651,
+  1.23897,  1.35179,  1.87757,  2.16641,  2.31797,  2.47439,
+  1.18029,  1.38835,  1.60745,  1.95083,  2.21086,  2.47772,
+  1.124,  1.42354,  1.61732,  1.8268,  2.20607,  2.44408,
+  1.14779,  1.48705,  1.62797,  1.92602,  2.27842,  2.48653,
+  1.09265,  1.49972,  1.62304,  1.88016,  2.41166,  2.64865,
+  1.11529,  1.46869,  1.60763,  1.81446,  2.3569,  2.57609,
+  1.17604,  1.42463,  1.61423,  1.96634,  2.35268,  2.57035,
+  1.21105,  1.46743,  1.61778,  1.85149,  2.38977,  2.59186,
+  1.28768,  1.46486,  1.63379,  1.85623,  2.34975,  2.56532,
+  1.29859,  1.49522,  1.639,  1.94264,  2.41539,  2.51812,
+  1.30989,  1.43114,  1.75719,  1.97721,  2.41487,  2.52088,
+  1.39224,  1.47741,  1.8113,  1.90969,  2.44042,  2.57389,
+  1.41494,  1.51538,  1.859,  2.12794,  2.49067,  2.63542,
+  1.49044,  1.56597,  1.95241,  2.04907,  2.49994,  2.60018,
+  1.48507,  1.73412,  1.99737,  2.08938,  2.52477,  2.60816,
+  1.50713,  1.7872,  2.0481,  2.12836,  2.53363,  2.62465,
+  1.48522,  1.77259,  2.0481,  2.14437,  2.59574,  2.67979,
+  1.56004,  1.74452,  2.07614,  2.15684,  2.61506,  2.69877,
+  1.50628,  1.85545,  2.06419,  2.14453,  2.58566,  2.68779,
+  1.59288,  1.90345,  2.08453,  2.16339,  2.4969,  2.63359,
+  1.60945,  1.87086,  2.11982,  2.18659,  2.5995,  2.69782,
+  1.59478,  1.85535,  2.02562,  2.14254,  2.5723,  2.63784,
+  1.52719,  1.71409,  2.07627,  2.18517,  2.52655,  2.63114,
+  1.51801,  1.62801,  2.03926,  2.13453,  2.45384,  2.57636,
+  1.53131,  1.67808,  2.03518,  2.14689,  2.50486,  2.58417,
+  1.50863,  1.63261,  1.96514,  2.14868,  2.49664,  2.59275,
+  1.4999,  1.59942,  1.91369,  2.03686,  2.45019,  2.53817,
+  1.48116,  1.58381,  1.88446,  2.01387,  2.3595,  2.4811,
+  1.47574,  1.5697,  1.79999,  1.91618,  2.32922,  2.5359,
+  1.49864,  1.6236,  1.79282,  1.94522,  2.35863,  2.49073,
+  1.43113,  1.57463,  1.74326,  2.00612,  2.34776,  2.5089,
+  1.42706,  1.53658,  1.79069,  1.94303,  2.34447,  2.45265,
+  1.43684,  1.54202,  1.75892,  1.92562,  2.24291,  2.41684,
+  1.41979,  1.50904,  1.86332,  1.9954,  2.27579,  2.42473,
+  1.4244,  1.51048,  1.88289,  2.17902,  2.30471,  2.45567,
+  1.36605,  1.46119,  1.93532,  2.14755,  2.26342,  2.46579,
+  1.4074,  1.56497,  1.98112,  2.10344,  2.44529,  2.5651,
+  1.59701,  1.87701,  2.0685,  2.27031,  2.49936,  2.60489,
+  1.48498,  1.81813,  2.14982,  2.33759,  2.50475,  2.58944,
+  1.48788,  1.93718,  2.11827,  2.30837,  2.51178,  2.60463,
+  1.6823,  1.97703,  2.19229,  2.37368,  2.52293,  2.61128,
+  1.74946,  1.90568,  2.21827,  2.35201,  2.57423,  2.68148,
+  1.67622,  1.93651,  2.23718,  2.34378,  2.53591,  2.66127,
+  1.72336,  1.98992,  2.27124,  2.41314,  2.55083,  2.64937,
+  1.75601,  1.99691,  2.31266,  2.46148,  2.62542,  2.70874,
+  1.49977,  1.7633,  2.15887,  2.34688,  2.59272,  2.68285,
+  1.74752,  1.92713,  2.24894,  2.41084,  2.60412,  2.69088,
+  1.67035,  1.93826,  2.24767,  2.44713,  2.65754,  2.73004,
+  1.66924,  1.95961,  2.17932,  2.44053,  2.58843,  2.6408,
+  1.78023,  2.01514,  2.16481,  2.39902,  2.58191,  2.64694,
+  1.73956,  1.96722,  2.06569,  2.36448,  2.58998,  2.64944,
+  1.60501,  1.87511,  2.0189,  2.2274,  2.54118,  2.60354,
+  1.51125,  1.8926,  2.02783,  2.14811,  2.52,  2.6082,
+  1.36336,  1.56877,  1.91085,  2.05769,  2.46351,  2.55882,
+  1.3385,  1.48382,  1.8837,  2.06707,  2.44895,  2.5779,
+  1.36919,  1.43786,  1.84522,  2.07846,  2.4285,  2.61589,
+  1.3777,  1.49829,  1.86767,  2.16496,  2.49255,  2.57091,
+  1.4081,  1.48776,  1.87241,  2.09795,  2.44727,  2.55172,
+  1.40236,  1.53195,  1.89769,  2.12667,  2.41916,  2.55144,
+  1.4565,  1.55463,  1.84107,  2.09581,  2.42129,  2.56176,
+  1.43493,  1.52915,  1.79534,  2.1637,  2.44647,  2.53031,
+  1.39111,  1.4955,  1.86968,  2.16123,  2.38141,  2.53202,
+  1.38893,  1.53447,  1.797,  2.10294,  2.39851,  2.52127,
+  1.35857,  1.4713,  1.76005,  2.10088,  2.3502,  2.54655,
+  1.2766,  1.51921,  1.77942,  2.09582,  2.44294,  2.66594,
+  1.20666,  1.45786,  1.76046,  2.24428,  2.49588,  2.64485,
+  1.21461,  1.46027,  1.97902,  2.23945,  2.39832,  2.63447,
+  1.27547,  1.47347,  1.87857,  2.20312,  2.47503,  2.68785,
+  1.29171,  1.39929,  1.81381,  2.19412,  2.50276,  2.61489,
+  1.26006,  1.398,  1.92489,  2.18672,  2.51167,  2.64455,
+  1.21063,  1.32671,  1.89759,  2.10744,  2.46008,  2.71172,
+  1.20266,  1.31923,  1.89263,  2.07986,  2.37942,  2.67989,
+  0.967019,  1.10597,  1.76132,  2.10743,  2.32843,  2.59315,
+  0.947746,  1.0358,  1.39373,  2.06123,  2.30074,  2.66828,
+  0.996167,  1.21503,  1.37899,  1.86198,  2.32966,  2.60502,
+  1.00882,  1.19848,  1.31384,  1.69352,  2.36075,  2.60482,
+  1.05406,  1.21851,  1.36811,  1.73801,  2.17491,  2.54607,
+  1.02157,  1.13399,  1.36917,  1.93564,  2.2678,  2.54441,
+  1.03374,  1.22777,  1.45129,  2.00592,  2.41262,  2.59503,
+  1.06516,  1.16864,  1.53018,  2.0615,  2.41074,  2.48548,
+  1.12123,  1.28128,  1.43223,  1.90993,  2.20273,  2.50931,
+  1.17003,  1.30604,  1.49495,  1.98191,  2.20282,  2.35174,
+  1.15263,  1.26619,  1.621,  2.05767,  2.21445,  2.38164,
+  1.22813,  1.31327,  1.75147,  2.11847,  2.26342,  2.45389,
+  1.30783,  1.39865,  1.79975,  2.12574,  2.26062,  2.4518,
+  1.3601,  1.47744,  1.83574,  2.12187,  2.29156,  2.49979,
+  1.39848,  1.49297,  1.80652,  2.10714,  2.24141,  2.43415,
+  1.35121,  1.46251,  1.72639,  2.12239,  2.28579,  2.42184,
+  1.2972,  1.49887,  1.76625,  2.15784,  2.37671,  2.49716,
+  1.37735,  1.51897,  1.80379,  2.19115,  2.35637,  2.4789,
+  1.28917,  1.55324,  1.67459,  2.11263,  2.40335,  2.47388,
+  1.18897,  1.70034,  1.83432,  2.05558,  2.59953,  2.70041,
+  1.07704,  1.66767,  1.90219,  2.04569,  2.60291,  2.70006,
+  1.07206,  1.27246,  1.84374,  1.90118,  2.58625,  2.72056,
+  1.08439,  1.39207,  1.82356,  1.9013,  2.58943,  2.68003,
+  1.10632,  1.44136,  1.76614,  1.85372,  2.54936,  2.62741,
+  1.09457,  1.55002,  1.77192,  1.87095,  2.55968,  2.62805,
+  1.0419,  1.59855,  1.8137,  1.92849,  2.54563,  2.6715,
+  1.0902,  1.61051,  1.81256,  2.01926,  2.55632,  2.60879,
+  1.01653,  1.62666,  1.74241,  2.04192,  2.54154,  2.60225,
+  1.07557,  1.64775,  1.87067,  2.07397,  2.5746,  2.6288,
+  1.12666,  1.58621,  1.79257,  1.98241,  2.62918,  2.72556,
+  1.02778,  1.54267,  1.8314,  1.95688,  2.60301,  2.66852,
+  1.1119,  1.54342,  1.86147,  1.94292,  2.62196,  2.67286,
+  1.08051,  1.58319,  1.8573,  1.95846,  2.6336,  2.69514,
+  1.13224,  1.44916,  1.88495,  1.977,  2.60785,  2.70942,
+  1.23277,  1.6126,  1.96044,  2.07169,  2.64468,  2.72712,
+  1.32501,  1.7799,  1.9673,  2.11387,  2.54784,  2.66872,
+  1.40459,  1.64445,  2.05809,  2.25711,  2.51912,  2.63461,
+  1.41349,  1.6094,  2.00252,  2.1841,  2.58753,  2.69615,
+  1.35402,  1.59388,  2.01444,  2.1222,  2.61725,  2.72181,
+  1.37382,  1.65676,  1.99218,  2.18987,  2.54872,  2.70251,
+  1.42118,  1.61108,  1.95807,  2.12362,  2.56983,  2.64814,
+  1.37918,  1.6202,  1.92264,  2.09395,  2.55069,  2.64186,
+  1.36773,  1.65667,  1.83845,  1.99212,  2.59623,  2.65404,
+  1.39455,  1.75062,  1.87227,  2.03843,  2.55322,  2.62359,
+  1.46402,  1.74159,  1.91299,  2.15026,  2.56559,  2.64882,
+  1.46113,  1.80906,  1.95461,  2.2099,  2.57028,  2.64252,
+  1.43452,  1.77083,  1.90402,  2.21731,  2.63118,  2.687,
+  1.37553,  1.63166,  1.886,  2.08659,  2.6005,  2.67126,
+  1.33921,  1.56872,  1.81737,  2.08557,  2.59134,  2.66646,
+  1.5044,  1.77959,  2.05714,  2.27244,  2.5346,  2.63465,
+  1.4745,  1.74632,  2.04471,  2.13738,  2.47455,  2.63053,
+  1.55704,  1.75502,  2.03966,  2.08094,  2.66134,  2.74174,
+  1.57345,  1.71536,  2.05673,  2.09837,  2.69164,  2.74369,
+  1.51143,  1.83189,  1.99159,  2.15604,  2.62435,  2.70952,
+  1.50191,  1.71403,  2.01293,  2.07943,  2.55466,  2.69041,
+  1.54718,  1.67191,  1.97797,  2.10406,  2.50716,  2.61481,
+  1.56326,  1.63597,  1.99013,  2.12372,  2.56382,  2.63319,
+  1.58777,  1.69779,  2.00754,  2.12736,  2.58884,  2.65654,
+  1.6183,  1.72223,  2.00849,  2.13128,  2.61817,  2.68764,
+  1.58008,  1.68493,  2.00065,  2.08783,  2.61398,  2.68767,
+  1.57278,  1.73632,  1.96154,  2.14435,  2.64125,  2.68794,
+  1.53899,  1.65285,  1.95211,  2.15604,  2.6393,  2.68573,
+  1.53713,  1.6228,  1.96353,  2.07594,  2.6122,  2.67933,
+  1.53745,  1.63325,  1.98652,  2.07568,  2.54279,  2.6438,
+  1.54323,  1.77202,  2.05391,  2.14247,  2.53641,  2.69049,
+  1.6218,  1.83,  2.05274,  2.21086,  2.58321,  2.66584,
+  1.60957,  1.93532,  2.14668,  2.39332,  2.59721,  2.67056,
+  1.56082,  1.93554,  2.19144,  2.44438,  2.60992,  2.6926,
+  1.70428,  1.87459,  2.01026,  2.3801,  2.52866,  2.6048,
+  1.62478,  1.83779,  1.92536,  2.19301,  2.49717,  2.56943,
+  1.55613,  1.83265,  1.98694,  2.18932,  2.4532,  2.53163,
+  1.34743,  1.66967,  1.94393,  2.10805,  2.50663,  2.60842,
+  1.27841,  1.49725,  1.83841,  2.07392,  2.45455,  2.59232,
+  1.27105,  1.41512,  1.75811,  2.23246,  2.42277,  2.55467,
+  1.26034,  1.35671,  1.91317,  2.22589,  2.3806,  2.55725,
+  1.2231,  1.30797,  1.78409,  2.20752,  2.36287,  2.48779,
+  1.24945,  1.53816,  1.7166,  1.99832,  2.36211,  2.46553,
+  1.20801,  1.50306,  1.7613,  1.91708,  2.44805,  2.52513,
+  1.15185,  1.46115,  1.78394,  1.94689,  2.45256,  2.55631,
+  1.16556,  1.34777,  1.79995,  1.92075,  2.43788,  2.54695,
+  1.10979,  1.31045,  1.81589,  1.92338,  2.4273,  2.6028,
+  1.09199,  1.23364,  1.78961,  1.92504,  2.4678,  2.61117,
+  1.05232,  1.19475,  1.8099,  1.91423,  2.39018,  2.55632,
+  1.03227,  1.18949,  1.77562,  1.88969,  2.39325,  2.64083,
+  0.992854,  1.16963,  1.81416,  1.91225,  2.32027,  2.63432,
+  1.05441,  1.17775,  1.76276,  1.9072,  2.26618,  2.5163,
+  1.02954,  1.16736,  1.78006,  1.97354,  2.22784,  2.61389,
+  1.06778,  1.18481,  1.74132,  1.91913,  2.12196,  2.50079,
+  1.16784,  1.26305,  1.77863,  1.90072,  2.15081,  2.56866,
+  1.24703,  1.32367,  1.81105,  1.93459,  2.18402,  2.67462,
+  1.33178,  1.42614,  1.78514,  1.96603,  2.11456,  2.54183,
+  1.3609,  1.44414,  1.86253,  1.94975,  2.42674,  2.64611,
+  1.40854,  1.45179,  1.86692,  2.01423,  2.47884,  2.70591,
+  1.40555,  1.48355,  1.87498,  1.96029,  2.50276,  2.66254,
+  1.44237,  1.54466,  1.88335,  1.98759,  2.56298,  2.64776,
+  1.48072,  1.5362,  1.88182,  2.01887,  2.58235,  2.66179,
+  1.51308,  1.58325,  1.89576,  1.98715,  2.58617,  2.67601,
+  1.49776,  1.60209,  1.83101,  1.9854,  2.56409,  2.64364,
+  1.49706,  1.56491,  1.84464,  1.9577,  2.53993,  2.67716,
+  1.46811,  1.52375,  1.86584,  1.94008,  2.60797,  2.68486,
+  1.4681,  1.56439,  1.85892,  1.9824,  2.60648,  2.70969,
+  1.42273,  1.5192,  1.80679,  1.89159,  2.61482,  2.70389,
+  1.39687,  1.4767,  1.7764,  2.01325,  2.60785,  2.66599,
+  1.39153,  1.50457,  1.83054,  2.08154,  2.61102,  2.72081,
+  1.37288,  1.64506,  1.83336,  2.01576,  2.63134,  2.70134,
+  1.33129,  1.7474,  1.89795,  2.14651,  2.58668,  2.65827,
+  1.50318,  1.73469,  1.915,  2.28209,  2.59839,  2.67919,
+  1.46524,  1.71176,  2.02517,  2.28408,  2.65366,  2.71739,
+  1.4234,  1.76876,  2.08441,  2.27788,  2.63644,  2.71152,
+  1.42382,  1.72447,  2.03259,  2.30031,  2.60334,  2.68611,
+  1.43318,  1.81887,  2.05388,  2.40924,  2.6286,  2.69946,
+  1.50985,  1.79349,  2.05264,  2.35777,  2.64413,  2.71806,
+  1.57573,  1.85153,  2.03296,  2.3749,  2.58353,  2.66224,
+  1.50126,  1.78083,  1.99855,  2.32927,  2.5056,  2.60674,
+  1.46006,  1.76321,  1.91233,  2.21442,  2.49433,  2.57762,
+  1.44404,  1.65767,  1.89536,  2.14855,  2.47846,  2.59545,
+  1.45429,  1.61986,  1.93589,  2.18975,  2.47883,  2.59488,
+  1.37724,  1.64218,  1.91967,  2.14284,  2.42151,  2.54104,
+  1.05106,  1.42102,  1.8304,  2.02122,  2.37369,  2.54883,
+  0.964571,  1.07164,  1.3949,  2.1512,  2.37178,  2.46495,
+  0.966306,  1.18103,  1.30221,  2.01482,  2.37509,  2.43513,
+  0.89556,  1.20784,  1.33531,  1.82392,  2.23992,  2.3631,
+  1.00678,  1.20309,  1.31782,  1.87398,  2.33664,  2.40878,
+  1.05413,  1.22559,  1.37901,  2.02469,  2.33331,  2.42155,
+  1.0902,  1.22477,  1.40967,  2.0132,  2.24536,  2.35323,
+  1.07648,  1.20397,  1.56389,  2.03395,  2.20336,  2.3691,
+  1.12797,  1.24913,  1.66469,  2.08043,  2.25662,  2.46954,
+  1.20201,  1.42968,  1.79368,  2.08071,  2.33998,  2.46005,
+  1.51722,  1.6739,  1.92792,  2.20364,  2.38676,  2.52014,
+  1.58662,  1.78624,  2.04167,  2.199,  2.41637,  2.58119,
+  1.5933,  1.80855,  2.14878,  2.25028,  2.37209,  2.53241,
+  1.65729,  1.78346,  2.15039,  2.25813,  2.45392,  2.61621,
+  1.57149,  1.79266,  2.11765,  2.35038,  2.57719,  2.66695,
+  1.30199,  1.72975,  1.97442,  2.09325,  2.5939,  2.66302,
+  1.10022,  1.5634,  1.91991,  2.05922,  2.56297,  2.63776,
+  1.02507,  1.54074,  1.8119,  2.05791,  2.49188,  2.60325,
+  1.01531,  1.4735,  1.80259,  2.01308,  2.43676,  2.60532,
+  1.02207,  1.15848,  1.68979,  2.18353,  2.38378,  2.49237,
+  1.21248,  1.45311,  1.82395,  2.06144,  2.39619,  2.53658,
+  1.12624,  1.45293,  1.80959,  2.07107,  2.40894,  2.54956,
+  0.880332,  1.32478,  1.62134,  1.96725,  2.31316,  2.42693,
+  0.749583,  1.35841,  1.57507,  1.87059,  2.27923,  2.37743,
+  0.901917,  1.29022,  1.67443,  1.95441,  2.23336,  2.39152,
+  0.850971,  1.2521,  1.65765,  1.81646,  2.18389,  2.32881,
+  0.88148,  1.2841,  1.69816,  1.84466,  2.34182,  2.44091,
+  0.874499,  1.18268,  1.70949,  1.91745,  2.36597,  2.49965,
+  0.833751,  1.23113,  1.80332,  1.91802,  2.45909,  2.54688,
+  0.85097,  1.12709,  1.77207,  1.85522,  2.48758,  2.58286,
+  0.88165,  1.1148,  1.8207,  1.95908,  2.52175,  2.59873,
+  0.803558,  1.15029,  1.79848,  1.95267,  2.53892,  2.6349,
+  0.867833,  0.990496,  1.83228,  1.92977,  2.54766,  2.68108,
+  0.865057,  1.06744,  1.77326,  1.86019,  2.55833,  2.70222,
+  0.832529,  0.98596,  1.75637,  1.86293,  2.43828,  2.62378,
+  0.850804,  1.06055,  1.89222,  1.98401,  2.48377,  2.66112,
+  0.873803,  1.04198,  1.7462,  1.93244,  2.33822,  2.55458,
+  0.958594,  1.10347,  1.83644,  1.93678,  2.39376,  2.5732,
+  1.01483,  1.14087,  1.82593,  2.01371,  2.40149,  2.60942,
+  1.07537,  1.45764,  1.90046,  2.03349,  2.31419,  2.49095,
+  1.20171,  1.73617,  1.91408,  2.0665,  2.38691,  2.47696,
+  1.21522,  1.87361,  2.0659,  2.18299,  2.37498,  2.48955,
+  1.62021,  1.85126,  2.11154,  2.3428,  2.52749,  2.63389,
+  1.68388,  1.86037,  2.12601,  2.40434,  2.56298,  2.63616,
+  1.70382,  1.93438,  2.13367,  2.39321,  2.60193,  2.68247,
+  1.52688,  1.90013,  2.1511,  2.36164,  2.57517,  2.65898,
+  1.58725,  1.88139,  2.12995,  2.26786,  2.57786,  2.65784,
+  1.53916,  1.87134,  2.19028,  2.36038,  2.62461,  2.70564,
+  1.62575,  1.86218,  2.12009,  2.33946,  2.59216,  2.68214,
+  1.67953,  1.92069,  2.16117,  2.31711,  2.6489,  2.71211,
+  1.6352,  1.92283,  2.17484,  2.4074,  2.63005,  2.70927,
+  1.45419,  1.9757,  2.15185,  2.37134,  2.60918,  2.68579,
+  1.67244,  2.0114,  2.18302,  2.46392,  2.65296,  2.71152,
+  1.61211,  1.98748,  2.10258,  2.29335,  2.61613,  2.67026,
+  1.52807,  1.89507,  2.05358,  2.2325,  2.54491,  2.62412,
+  1.42035,  1.6835,  1.96343,  2.15942,  2.53673,  2.62013,
+  1.45632,  1.69313,  1.96923,  2.16474,  2.58716,  2.67759,
+  1.48111,  1.63754,  1.99264,  2.17848,  2.54814,  2.63276,
+  1.48852,  1.59117,  2.0165,  2.12332,  2.52866,  2.61492,
+  1.47743,  1.65152,  1.96289,  2.10218,  2.5433,  2.61884,
+  1.47386,  1.6223,  1.99223,  2.08035,  2.57269,  2.64443,
+  1.47822,  1.6334,  1.9312,  2.06413,  2.55228,  2.62934,
+  1.45248,  1.67676,  1.94591,  2.08475,  2.60097,  2.66889,
+  1.41156,  1.70618,  1.89025,  2.16962,  2.56732,  2.65016,
+  1.3834,  1.66463,  1.80326,  2.10861,  2.59577,  2.64622,
+  1.4346,  1.64501,  1.87175,  2.11549,  2.52896,  2.66026,
+  1.44454,  1.58183,  1.89864,  2.09407,  2.52845,  2.6315,
+  1.46556,  1.562,  1.84142,  2.0516,  2.55994,  2.63232,
+  1.49929,  1.58105,  1.85745,  2.09899,  2.5116,  2.60434,
+  1.52868,  1.65135,  1.87131,  2.07123,  2.56255,  2.62246,
+  1.51447,  1.63348,  1.7786,  2.1235,  2.6061,  2.66239,
+  1.30148,  1.68391,  1.79606,  2.17075,  2.64495,  2.69178,
+  1.15442,  1.62694,  1.74922,  1.99641,  2.57924,  2.6529,
+  1.11791,  1.56927,  1.79538,  1.8853,  2.37672,  2.73973,
+  1.25179,  1.62567,  1.83926,  1.99131,  2.35012,  2.65505,
+  1.41213,  1.69423,  1.83936,  1.9984,  2.44522,  2.73968,
+  1.37016,  1.68726,  1.87973,  2.00645,  2.32901,  2.63296,
+  1.17478,  1.72905,  1.88737,  2.01391,  2.25939,  2.55774,
+  1.31792,  1.73704,  1.87808,  1.97931,  2.17536,  2.63486,
+  1.14013,  1.58645,  1.93222,  2.02771,  2.23684,  2.48495,
+  1.10014,  1.6001,  1.85129,  1.97238,  2.60483,  2.64945,
+  1.11197,  1.52598,  1.84271,  2.01149,  2.6016,  2.66939,
+  1.08082,  1.49258,  1.81023,  1.96531,  2.55673,  2.64517,
+  1.12935,  1.6359,  1.78518,  2.1374,  2.498,  2.57252,
+  1.00359,  1.60301,  1.7227,  2.1394,  2.43159,  2.511,
+  1.12017,  1.42515,  1.67568,  2.05077,  2.34325,  2.46068,
+  1.32861,  1.59915,  1.87358,  2.17045,  2.47054,  2.61353,
+  1.38209,  1.59534,  1.92346,  2.08211,  2.34955,  2.51075,
+  1.46619,  1.57286,  1.87047,  2.18,  2.34634,  2.47187,
+  1.37977,  1.63301,  1.80827,  2.16629,  2.39872,  2.49247,
+  1.30592,  1.61002,  1.85641,  2.00154,  2.39067,  2.53391,
+  1.38309,  1.58681,  1.75722,  1.9348,  2.43354,  2.58795,
+  1.30751,  1.45094,  1.67533,  2.03394,  2.24423,  2.41812,
+  1.1915,  1.48407,  1.75027,  2.09664,  2.24938,  2.50498,
+  1.24138,  1.49179,  1.77688,  2.07173,  2.36793,  2.50807,
+  1.2657,  1.45992,  1.78175,  2.0099,  2.34858,  2.51604,
+  1.27951,  1.41465,  1.7951,  2.05594,  2.3957,  2.53054,
+  1.33734,  1.44593,  1.85301,  2.07518,  2.38598,  2.53549,
+  1.28897,  1.42471,  1.79799,  2.02629,  2.2998,  2.42371,
+  1.36528,  1.47179,  1.80171,  1.9377,  2.3453,  2.4667,
+  1.35379,  1.44775,  1.73621,  1.86889,  2.27436,  2.47558,
+  1.36086,  1.44961,  1.68047,  1.80265,  2.39554,  2.51326,
+  1.38833,  1.52625,  1.67333,  1.90987,  2.38502,  2.53543,
+  1.42443,  1.54422,  1.7202,  1.93624,  2.30797,  2.49142,
+  1.44894,  1.55201,  1.79794,  1.93752,  2.40687,  2.54612,
+  1.43203,  1.52162,  1.79932,  2.02144,  2.47733,  2.57175,
+  1.46309,  1.54628,  1.83442,  2.06349,  2.4898,  2.59527,
+  1.42547,  1.55643,  1.90472,  2.11082,  2.46637,  2.58756,
+  1.38484,  1.56941,  1.92558,  2.07237,  2.56129,  2.64054,
+  1.41849,  1.53942,  1.93754,  2.01432,  2.6092,  2.67676,
+  1.39701,  1.48328,  1.93673,  1.97775,  2.59561,  2.73585,
+  1.33562,  1.44187,  1.88474,  1.99496,  2.58963,  2.69575,
+  1.35749,  1.519,  1.8716,  1.9802,  2.62902,  2.7003,
+  1.35356,  1.52432,  1.89108,  1.96371,  2.59581,  2.67933,
+  1.2951,  1.63928,  1.90739,  2.10314,  2.58336,  2.67978,
+  1.45554,  1.66759,  1.9532,  2.24049,  2.57067,  2.67362,
+  1.46028,  1.78665,  1.99775,  2.28513,  2.58293,  2.67762,
+  1.54312,  1.72939,  2.15567,  2.28027,  2.65558,  2.74425,
+  1.43444,  1.74878,  2.0422,  2.20129,  2.6065,  2.69586,
+  1.43608,  1.74734,  2.06784,  2.25326,  2.57594,  2.67908,
+  1.47087,  1.69825,  2.08313,  2.25757,  2.56534,  2.66619,
+  1.41742,  1.69344,  2.05319,  2.24354,  2.54484,  2.6328,
+  1.41211,  1.68159,  2.0818,  2.3261,  2.47245,  2.57058,
+  1.39723,  1.76474,  2.03156,  2.29712,  2.47165,  2.57588,
+  1.4665,  1.6943,  2.00592,  2.20633,  2.53451,  2.63576,
+  1.43711,  1.74657,  1.92384,  2.12785,  2.35663,  2.46448,
+  1.32402,  1.59792,  1.75778,  2.12435,  2.34799,  2.44047,
+  1.37539,  1.62639,  1.77807,  2.0684,  2.25894,  2.39753,
+  1.37958,  1.62179,  1.85796,  1.99428,  2.30609,  2.47721,
+  1.41641,  1.64889,  1.86912,  2.09836,  2.3454,  2.47513,
+  1.42624,  1.6392,  1.9254,  2.07268,  2.44895,  2.53255,
+  1.45905,  1.61587,  1.91117,  2.12546,  2.4837,  2.59209,
+  1.45943,  1.6907,  1.85242,  2.13607,  2.5294,  2.5972,
+  1.48514,  1.57805,  1.81057,  2.15062,  2.55904,  2.61824,
+  1.52905,  1.59466,  1.7389,  2.26122,  2.59577,  2.65162,
+  1.53249,  1.58533,  1.82094,  2.22962,  2.62316,  2.65848,
+  1.3744,  1.52808,  1.84802,  2.04246,  2.45823,  2.59109,
+  1.39987,  1.59747,  1.85308,  2.09608,  2.4316,  2.55685,
+  1.45743,  1.60951,  1.93076,  2.1861,  2.39229,  2.52506,
+  1.44051,  1.60759,  1.86998,  2.15828,  2.42428,  2.55553,
+  1.37676,  1.47479,  1.75056,  2.19062,  2.40618,  2.54712,
+  1.32771,  1.45424,  1.64463,  2.11036,  2.35245,  2.45593,
+  1.3028,  1.41895,  1.60978,  2.09312,  2.26349,  2.39325,
+  1.20771,  1.37987,  1.53641,  2.05993,  2.3173,  2.4554,
+  1.15421,  1.30297,  1.49921,  2.07038,  2.3222,  2.63083,
+  1.11147,  1.22442,  1.62564,  2.17608,  2.34255,  2.60619,
+  0.945723,  1.0833,  1.62541,  2.21453,  2.3899,  2.51008,
+  0.992344,  1.11699,  1.45192,  2.00842,  2.31359,  2.43786,
+  1.11731,  1.39299,  1.71346,  2.13231,  2.27682,  2.49761,
+  1.33287,  1.58093,  1.89551,  2.129,  2.4251,  2.57695,
+  1.32204,  1.49774,  1.81922,  2.12864,  2.44361,  2.56795,
+  1.36194,  1.54738,  1.79097,  2.06294,  2.46532,  2.54609,
+  1.25268,  1.48388,  1.75863,  2.03345,  2.41628,  2.53922,
+  1.09938,  1.34475,  1.68653,  2.01675,  2.35586,  2.53084,
+  1.12611,  1.26362,  1.64994,  1.99154,  2.30909,  2.51489,
+  1.19062,  1.28965,  1.69271,  2.00948,  2.16009,  2.41707,
+  1.17498,  1.41431,  1.79786,  1.9876,  2.27882,  2.49276,
+  1.20535,  1.48205,  1.85076,  2.02555,  2.34228,  2.52343,
+  1.24803,  1.56119,  1.85276,  2.09645,  2.42836,  2.55187,
+  1.26073,  1.60183,  1.90105,  2.13198,  2.40985,  2.56555,
+  1.26504,  1.69384,  2.00053,  2.20004,  2.50351,  2.61771,
+  1.27884,  1.73826,  2.06202,  2.28998,  2.60444,  2.67811,
+  1.33943,  1.73592,  2.05012,  2.35241,  2.59739,  2.68822,
+  1.30106,  1.70875,  1.96598,  2.28621,  2.54671,  2.65318,
+  1.2786,  1.74616,  1.95007,  2.21477,  2.60579,  2.68762,
+  1.18377,  1.52306,  1.87912,  2.00491,  2.60031,  2.69049,
+  1.18622,  1.34213,  1.81783,  1.94008,  2.5049,  2.65925,
+  1.17939,  1.24368,  1.89426,  1.97975,  2.55802,  2.72182,
+  1.17562,  1.35704,  1.85319,  1.94081,  2.64681,  2.70566,
+  1.21112,  1.36964,  1.82525,  1.91329,  2.63472,  2.71226,
+  1.16947,  1.34515,  1.76494,  1.88367,  2.59108,  2.71452,
+  1.22209,  1.38948,  1.80018,  1.9359,  2.57377,  2.70292,
+  1.28727,  1.37591,  1.87874,  1.98605,  2.626,  2.70847,
+  1.29971,  1.3896,  1.8739,  1.94272,  2.53348,  2.69147,
+  1.27136,  1.4242,  1.84985,  1.95357,  2.55556,  2.65237,
+  1.25357,  1.44851,  1.82953,  1.9191,  2.48784,  2.63076,
+  1.22392,  1.32302,  1.84126,  1.93273,  2.22685,  2.57072,
+  1.22617,  1.32139,  1.77179,  1.94807,  2.13788,  2.56305,
+  1.31624,  1.39947,  1.78933,  1.96557,  2.13204,  2.42471,
+  1.26439,  1.36395,  1.73553,  2.0056,  2.15584,  2.41892,
+  1.21403,  1.31978,  1.66202,  1.90295,  2.06463,  2.42483,
+  1.2426,  1.34231,  1.62476,  1.92942,  2.08355,  2.31844,
+  1.24161,  1.43912,  1.64633,  1.81792,  1.99776,  2.19663,
+  1.23935,  1.33692,  1.77706,  2.02801,  2.15585,  2.3287,
+  1.17842,  1.26633,  1.80204,  1.95982,  2.1457,  2.46951,
+  1.2477,  1.32863,  1.81269,  1.99279,  2.20064,  2.49944,
+  1.27008,  1.37091,  1.88227,  1.99723,  2.25428,  2.52605,
+  1.29555,  1.37642,  1.86044,  2.07673,  2.249,  2.56712,
+  1.30484,  1.38609,  1.83276,  2.06162,  2.2194,  2.48635,
+  1.31431,  1.38148,  1.91283,  2.01753,  2.28775,  2.57642,
+  1.27508,  1.35377,  1.85847,  2.03703,  2.36206,  2.61542,
+  1.28711,  1.3668,  1.83552,  1.96109,  2.29199,  2.56297,
+  1.25667,  1.34116,  1.79881,  1.92126,  2.33365,  2.59691,
+  1.22928,  1.33751,  1.75398,  1.94239,  2.40355,  2.60217,
+  1.22487,  1.32298,  1.79261,  1.91891,  2.36331,  2.52058,
+  1.21845,  1.32159,  1.65149,  1.88416,  2.36654,  2.52128,
+  1.19322,  1.35912,  1.6324,  1.85763,  2.32285,  2.45271,
+  1.20547,  1.36803,  1.60803,  1.81504,  2.34185,  2.57451,
+  1.06125,  1.31843,  1.54502,  1.88874,  2.40188,  2.61702,
+  1.07252,  1.36579,  1.51413,  1.89367,  2.36962,  2.47423,
+  1.11164,  1.43679,  1.6061,  1.84246,  2.38242,  2.47411,
+  1.01206,  1.3162,  1.47159,  1.79906,  2.34943,  2.45513,
+  1.08947,  1.24857,  1.57279,  1.95306,  2.29844,  2.46178,
+  1.06836,  1.19581,  1.62402,  2.11129,  2.31148,  2.41925,
+  1.14751,  1.52522,  1.72481,  1.95717,  2.38753,  2.47131,
+  1.33434,  1.56815,  1.74904,  1.96257,  2.39063,  2.48465,
+  1.29814,  1.46788,  1.8144,  1.94157,  2.38423,  2.52218,
+  1.29501,  1.41849,  1.85947,  1.96233,  2.37632,  2.52176,
+  1.33583,  1.43664,  1.85826,  1.96633,  2.44658,  2.56348,
+  1.34649,  1.47798,  1.90564,  1.99809,  2.49005,  2.58447,
+  1.40718,  1.54076,  1.8793,  1.99298,  2.48794,  2.56401,
+  1.44766,  1.62857,  1.8282,  2.05365,  2.53405,  2.60586,
+  1.52471,  1.62005,  1.83788,  2.01792,  2.59217,  2.65337,
+  1.56458,  1.64714,  1.76118,  2.02415,  2.61525,  2.65657,
+  1.52937,  1.59398,  1.68316,  1.97983,  2.60164,  2.65439,
+  1.58508,  1.65284,  1.78677,  2.03185,  2.518,  2.62098,
+  1.58891,  1.64423,  1.81381,  2.04148,  2.61072,  2.66605,
+  1.60136,  1.68607,  1.86295,  2.12711,  2.60886,  2.65502,
+  1.64024,  1.75092,  1.9211,  2.16441,  2.54752,  2.61719,
+  1.5486,  1.6382,  1.9174,  2.09265,  2.56383,  2.61584,
+  1.51587,  1.61696,  1.84416,  2.00703,  2.52817,  2.60107,
+  1.46587,  1.5722,  1.74097,  2.01129,  2.49342,  2.58193,
+  1.41191,  1.53428,  1.66939,  2.02551,  2.41906,  2.53499,
+  1.3394,  1.5249,  1.67455,  2.01899,  2.344,  2.44379,
+  1.30067,  1.52706,  1.67307,  2.03619,  2.26952,  2.38379,
+  1.19308,  1.4765,  1.66446,  1.93323,  2.291,  2.41495,
+  1.19279,  1.48559,  1.64926,  1.84405,  2.29509,  2.502,
+  1.19782,  1.36486,  1.70369,  1.82721,  2.26277,  2.4998,
+  1.13827,  1.37925,  1.65813,  1.91249,  2.38908,  2.58338,
+  1.1666,  1.35794,  1.68892,  1.94273,  2.49153,  2.58925,
+  1.17061,  1.39155,  1.72193,  1.88951,  2.50612,  2.61639,
+  1.21096,  1.4527,  1.75562,  1.84497,  2.49006,  2.62473,
+  1.21214,  1.51972,  1.78592,  1.88927,  2.55126,  2.62949,
+  1.276,  1.66462,  1.95776,  2.24934,  2.60229,  2.6777,
+  1.40086,  1.81618,  1.99446,  2.32596,  2.65178,  2.7173,
+  1.46605,  1.83456,  2.11857,  2.37243,  2.62538,  2.70468,
+  1.57886,  1.79094,  2.1361,  2.39283,  2.63855,  2.71402,
+  1.4807,  1.81656,  2.20645,  2.43239,  2.57589,  2.64511,
+  1.61729,  1.80766,  2.24172,  2.44007,  2.56723,  2.63175,
+  1.5701,  1.78507,  2.17821,  2.34813,  2.46705,  2.55664,
+  1.57968,  1.70153,  2.00519,  2.28877,  2.43415,  2.54859,
+  1.57869,  1.67421,  1.96547,  2.19945,  2.33487,  2.4798,
+  1.64055,  1.72692,  1.99161,  2.24034,  2.40097,  2.52363,
+  1.58853,  1.70967,  1.87442,  2.16082,  2.38152,  2.51723,
+  1.4475,  1.66548,  1.90094,  2.10338,  2.39787,  2.53557,
+  1.20302,  1.59921,  1.88428,  2.03226,  2.36901,  2.50474,
+  1.14652,  1.51319,  1.8805,  1.98579,  2.40738,  2.52248,
+  1.13127,  1.435,  1.83409,  2.11135,  2.30655,  2.53115,
+  1.17671,  1.64034,  1.87012,  2.06494,  2.313,  2.43912,
+  1.25449,  1.59061,  1.95849,  2.20017,  2.34427,  2.47982,
+  1.24396,  1.68449,  2.0165,  2.19295,  2.45108,  2.54733,
+  1.53731,  1.76385,  2.18864,  2.37173,  2.53993,  2.64808,
+  1.64654,  1.88757,  2.28095,  2.44345,  2.59307,  2.68077,
+  1.56746,  1.87617,  2.10871,  2.42783,  2.61173,  2.69136,
+  1.34106,  1.87413,  2.11422,  2.3962,  2.62123,  2.70277,
+  1.4492,  1.83784,  2.0584,  2.30747,  2.61691,  2.68969,
+  1.31349,  1.79435,  1.96106,  2.2375,  2.59774,  2.68519,
+  1.20218,  1.70691,  1.9051,  2.13915,  2.61289,  2.69366,
+  1.08034,  1.59049,  1.84652,  2.05928,  2.63137,  2.69738,
+  1.04322,  1.60191,  1.90035,  2.14104,  2.58835,  2.66252,
+  0.984957,  1.55615,  1.84148,  2.14877,  2.57734,  2.66295,
+  0.979403,  1.55384,  1.84417,  2.0526,  2.57775,  2.64111,
+  0.947313,  1.45389,  1.83646,  1.99878,  2.56655,  2.63755,
+  0.95946,  1.44168,  1.83287,  2.1065,  2.55364,  2.63088,
+  0.951016,  1.39788,  1.79374,  2.05307,  2.49264,  2.62257,
+  0.870727,  1.36922,  1.81779,  2.10748,  2.52423,  2.62794,
+  0.902872,  1.38516,  1.7548,  2.01343,  2.53699,  2.65482,
+  0.891101,  1.3624,  1.75358,  1.87804,  2.5598,  2.66247,
+  0.835616,  1.25933,  1.75717,  1.83234,  2.48635,  2.63568,
+  0.787419,  1.13204,  1.69397,  1.77693,  2.53318,  2.61631,
+  0.791106,  1.06813,  1.69774,  1.8516,  2.57196,  2.66955,
+  0.759951,  1.11236,  1.56236,  1.8552,  2.49068,  2.60197,
+  0.792061,  1.14,  1.72482,  1.95446,  2.60886,  2.68968,
+  0.823952,  1.27093,  1.74109,  2.07766,  2.6132,  2.66939,
+  0.736534,  1.12497,  1.74368,  2.09325,  2.57979,  2.66172,
+  0.797043,  1.05194,  1.78023,  2.24036,  2.58348,  2.66231,
+  0.923582,  1.50315,  1.77688,  2.01847,  2.61391,  2.70304,
+  1.42154,  1.73503,  2.00689,  2.21034,  2.57432,  2.67074,
+  1.35017,  1.60612,  1.96301,  2.08497,  2.47819,  2.58995,
+  1.3618,  1.65658,  1.97408,  2.17388,  2.47963,  2.61201,
+  1.31994,  1.76445,  2.02745,  2.24929,  2.52964,  2.63574,
+  1.39403,  1.6642,  2.00631,  2.24619,  2.55809,  2.67132,
+  1.38539,  1.75543,  2.08002,  2.32987,  2.63089,  2.72267,
+  1.33369,  1.66943,  2.02149,  2.25061,  2.60027,  2.6891,
+  1.34153,  1.69816,  1.975,  2.23711,  2.56085,  2.68438,
+  1.38861,  1.78505,  1.95689,  2.28139,  2.56358,  2.64371,
+  1.34589,  1.70624,  1.84298,  2.26416,  2.60622,  2.69479,
+  1.32033,  1.69419,  1.92336,  2.21815,  2.64548,  2.75026,
+  1.33239,  1.74839,  2.01472,  2.22178,  2.60263,  2.69746,
+  1.3976,  1.71535,  1.94972,  2.236,  2.5778,  2.66148,
+  1.61881,  1.79597,  2.01642,  2.20519,  2.50664,  2.63683,
+  1.65981,  1.73533,  2.02109,  2.17584,  2.44338,  2.64145,
+  1.53953,  1.65206,  1.94677,  2.09508,  2.44664,  2.63655,
+  1.53227,  1.59287,  1.97782,  2.05341,  2.55149,  2.67491,
+  1.50935,  1.58111,  2.00424,  2.05938,  2.5246,  2.70294,
+  1.43253,  1.50463,  1.93071,  2.04233,  2.44066,  2.69085,
+  1.19464,  1.67704,  2.0231,  2.07839,  2.44691,  2.74585,
+  1.21037,  1.82483,  2.02151,  2.13909,  2.53993,  2.65964,
+  1.27662,  1.71544,  1.95249,  2.08382,  2.47346,  2.66435,
+  1.23566,  1.54844,  2.06734,  2.11862,  2.42744,  2.72754,
+  1.28347,  1.3743,  1.96342,  2.09842,  2.47439,  2.70286,
+  1.30502,  1.3947,  2.068,  2.13904,  2.52017,  2.70621,
+  1.28482,  1.49431,  2.05521,  2.14033,  2.60212,  2.69883,
+  1.29659,  1.58772,  2.0872,  2.15656,  2.61856,  2.71863,
+  1.25247,  1.58335,  2.10888,  2.17387,  2.6005,  2.68503,
+  1.17744,  1.61204,  2.09388,  2.15517,  2.58107,  2.69512,
+  1.13296,  1.57299,  2.13546,  2.2206,  2.61573,  2.71057,
+  1.06032,  1.54298,  2.16575,  2.23041,  2.60944,  2.69779,
+  0.993306,  1.5422,  2.17075,  2.24721,  2.63117,  2.70689,
+  0.78375,  1.56854,  2.32332,  2.39888,  2.5942,  2.6906,
+  0.866024,  1.45443,  2.11329,  2.18704,  2.66201,  2.71994,
+  0.793002,  1.4377,  2.12567,  2.22555,  2.58888,  2.66479,
+  0.863183,  1.43983,  2.03195,  2.20395,  2.58648,  2.64689,
+  0.817301,  1.44308,  2.07874,  2.35666,  2.57215,  2.63532,
+  0.8402,  1.2682,  1.97396,  2.38069,  2.54674,  2.62412,
+  0.90591,  1.47285,  2.0008,  2.42018,  2.60601,  2.66254,
+  0.885218,  1.59913,  2.06396,  2.33538,  2.68875,  2.73625,
+  0.812099,  1.48097,  2.10316,  2.19363,  2.62136,  2.70211,
+  0.727009,  1.48128,  2.08817,  2.17056,  2.57558,  2.66056,
+  0.783755,  1.48208,  2.21077,  2.28199,  2.56464,  2.65808,
+  0.81089,  1.318,  2.15666,  2.25015,  2.56537,  2.66617,
+  0.775372,  1.35271,  2.27746,  2.37173,  2.58724,  2.65549,
+  0.765239,  1.28061,  2.22745,  2.3049,  2.57753,  2.69687,
+  0.860727,  1.30996,  2.23921,  2.35825,  2.52375,  2.68183,
+  0.828001,  1.15751,  2.1572,  2.2792,  2.55451,  2.65538,
+  0.776568,  1.131,  2.11047,  2.28237,  2.50224,  2.63453,
+  0.662804,  1.21065,  2.21449,  2.27527,  2.48015,  2.59817,
+  0.752595,  1.17213,  2.27025,  2.35479,  2.53437,  2.61343,
+  0.769014,  1.03754,  2.23985,  2.32019,  2.52388,  2.63727,
+  0.747299,  1.03652,  2.05988,  2.38032,  2.50772,  2.67777,
+  0.818428,  1.11045,  2.13257,  2.30679,  2.44267,  2.59784,
+  0.838124,  1.25603,  2.15252,  2.30408,  2.50108,  2.59185,
+  0.84274,  1.14734,  2.04509,  2.31707,  2.45929,  2.58847,
+  0.950977,  1.15093,  2.09764,  2.29,  2.49742,  2.64345,
+  0.932262,  1.15976,  1.94518,  2.23375,  2.53889,  2.63575,
+  0.87264,  1.29467,  1.88108,  2.11219,  2.48873,  2.6127,
+  0.953242,  1.39834,  1.90676,  2.02445,  2.39667,  2.61633,
+  1.01916,  1.44724,  1.91732,  2.02333,  2.21302,  2.5289,
+  0.98091,  1.42044,  1.85762,  1.94344,  2.29448,  2.59612,
+  1.00792,  1.47472,  1.82759,  1.92148,  2.56736,  2.64375,
+  1.05767,  1.58382,  1.86222,  1.98831,  2.50759,  2.60278,
+  1.08948,  1.61094,  1.8942,  2.06798,  2.40143,  2.58925,
+  1.15564,  1.60152,  1.85378,  2.10992,  2.26642,  2.65488,
+  1.19039,  1.40321,  1.85032,  2.12943,  2.35548,  2.59965,
+  1.16567,  1.26623,  1.84792,  2.19176,  2.35216,  2.57681,
+  1.11254,  1.23723,  1.75555,  2.19641,  2.37841,  2.5159,
+  1.0932,  1.22932,  1.63097,  2.19849,  2.39433,  2.49006,
+  1.03092,  1.16009,  1.537,  2.15027,  2.34576,  2.52617,
+  1.09013,  1.22746,  1.4703,  2.12166,  2.32569,  2.41426,
+  1.08419,  1.35343,  1.49577,  2.16541,  2.39664,  2.50153,
+  1.12869,  1.38014,  1.55146,  2.11031,  2.29686,  2.419,
+  1.08717,  1.45426,  1.65879,  2.02039,  2.1963,  2.38146,
+  1.03939,  1.58219,  1.7281,  2.07018,  2.30185,  2.48943,
+  1.01902,  1.64687,  1.82892,  2.12577,  2.54247,  2.62493,
+  1.01791,  1.67544,  2.00939,  2.20063,  2.43227,  2.53275,
+  0.975365,  1.56846,  2.09963,  2.24376,  2.46967,  2.55866,
+  1.04514,  1.75055,  2.09119,  2.27703,  2.474,  2.55964,
+  1.00349,  1.67,  2.14987,  2.21681,  2.54414,  2.59102,
+  0.972271,  1.66935,  2.06691,  2.25346,  2.52812,  2.62679,
+  1.0014,  1.91054,  2.2089,  2.32209,  2.47505,  2.59415,
+  1.10624,  1.7624,  2.17021,  2.36833,  2.53238,  2.63695,
+  0.937567,  1.5708,  2.20831,  2.31208,  2.5476,  2.60415,
+  0.984015,  1.53165,  2.15445,  2.2604,  2.51955,  2.62137,
+  1.05805,  1.58968,  2.13047,  2.23879,  2.55922,  2.636,
+  1.12629,  1.6743,  2.14238,  2.30438,  2.58199,  2.6598,
+  1.09217,  1.54725,  2.13885,  2.24696,  2.57092,  2.65374,
+  1.16415,  1.51357,  2.1206,  2.20304,  2.55593,  2.62912,
+  1.15444,  1.45166,  2.10988,  2.19379,  2.56938,  2.66869,
+  1.17101,  1.29755,  2.10579,  2.22429,  2.52972,  2.66324,
+  1.13937,  1.34334,  2.02494,  2.16127,  2.57005,  2.66206,
+  1.21497,  1.75949,  2.01362,  2.12671,  2.35066,  2.50893,
+  1.41044,  1.78736,  1.94045,  2.082,  2.25578,  2.40636,
+  1.19253,  1.69828,  1.95689,  2.08484,  2.23574,  2.49064,
+  1.17363,  1.44875,  2.01112,  2.14525,  2.28014,  2.53471,
+  1.1728,  1.32718,  1.93887,  2.09591,  2.24756,  2.52684,
+  1.12971,  1.37614,  1.89153,  1.98533,  2.19635,  2.58265,
+  1.19522,  1.29291,  1.88721,  2.02514,  2.2007,  2.52559,
+  1.24628,  1.33897,  1.85165,  2.07279,  2.20907,  2.45744,
+  1.24471,  1.39554,  1.91684,  2.09705,  2.29649,  2.52665,
+  1.34643,  1.45327,  2.12841,  2.31384,  2.56627,  2.66621,
+  1.39218,  1.50657,  2.06042,  2.18383,  2.52364,  2.65642,
+  1.39767,  1.47836,  2.03787,  2.14002,  2.52288,  2.63488,
+  1.40508,  1.43797,  2.0647,  2.12168,  2.48434,  2.66409,
+  1.52797,  1.73164,  2.0014,  2.18228,  2.47746,  2.60968,
+  1.60222,  1.69405,  2.06501,  2.17614,  2.56757,  2.65075,
+  1.54924,  1.66815,  2.06194,  2.13605,  2.57595,  2.67854,
+  1.59049,  1.69321,  1.92159,  2.19358,  2.52234,  2.65782,
+  1.59312,  1.7156,  2.05786,  2.17281,  2.50201,  2.60776,
+  1.50846,  1.71395,  2.05346,  2.14686,  2.38304,  2.62867,
+  1.50094,  1.57787,  1.97852,  2.08096,  2.51787,  2.64082,
+  1.50382,  1.5592,  1.93328,  2.0306,  2.51619,  2.6575,
+  1.43095,  1.50644,  1.85636,  2.01451,  2.40691,  2.5838,
+  1.39442,  1.47116,  1.91477,  2.01533,  2.41451,  2.56893,
+  1.37672,  1.47674,  1.84174,  1.96157,  2.45962,  2.55251,
+  1.30483,  1.50926,  1.80786,  1.89902,  2.5326,  2.61656,
+  1.48624,  1.64687,  1.92899,  2.17664,  2.50338,  2.64553,
+  1.47707,  1.57641,  1.9373,  2.09445,  2.46873,  2.64363,
+  1.43149,  1.55127,  1.93581,  2.02799,  2.46876,  2.60559,
+  1.42717,  1.67082,  1.94498,  2.10994,  2.48274,  2.65243,
+  1.39319,  1.64956,  1.99108,  2.07033,  2.58645,  2.66734,
+  1.40697,  1.51853,  1.96705,  2.06775,  2.50172,  2.62411,
+  1.39913,  1.48738,  1.88033,  1.97257,  2.35919,  2.60481,
+  1.41945,  1.54191,  1.92089,  2.01526,  2.41644,  2.54754,
+  1.44774,  1.62665,  1.9116,  2.03784,  2.5083,  2.60909,
+  1.50794,  1.64922,  1.95449,  2.06384,  2.51578,  2.59147,
+  1.51251,  1.69788,  1.91927,  2.07717,  2.54577,  2.63108,
+  1.57749,  1.65292,  1.96938,  2.05711,  2.5335,  2.61048,
+  1.60471,  1.68784,  1.94363,  2.0307,  2.55246,  2.65947,
+  1.63482,  1.71009,  1.94351,  2.03574,  2.55304,  2.65052,
+  1.62911,  1.72105,  1.90726,  2.02014,  2.5701,  2.65261,
+  1.65386,  1.73101,  1.91707,  2.0165,  2.55131,  2.67898,
+  1.67562,  1.74025,  1.92311,  1.99547,  2.54389,  2.69347,
+  1.70432,  1.761,  1.89209,  1.9586,  2.52034,  2.70958,
+  1.63175,  1.69802,  1.87977,  1.97482,  2.47504,  2.68871,
+  1.56339,  1.66235,  1.8635,  1.96166,  2.49207,  2.69214,
+  1.53527,  1.6218,  1.86452,  2.01688,  2.4572,  2.70145,
+  1.46363,  1.69,  1.94259,  2.01949,  2.51608,  2.68408,
+  1.42716,  1.54573,  1.9226,  1.98339,  2.54908,  2.72404,
+  1.38786,  1.46942,  1.87429,  2.04709,  2.48657,  2.64301,
+  1.36474,  1.46274,  1.90851,  2.07652,  2.46877,  2.62742,
+  1.42161,  1.61667,  2.07439,  2.24363,  2.60481,  2.69712,
+  1.44357,  1.80248,  2.14589,  2.31103,  2.61513,  2.70497,
+  1.40281,  1.86481,  2.20938,  2.37797,  2.65429,  2.73144,
+  1.47267,  1.8608,  2.16288,  2.44727,  2.64842,  2.71902,
+  1.5185,  1.79472,  2.07501,  2.33921,  2.5521,  2.65593,
+  1.5036,  1.75847,  2.11155,  2.30448,  2.551,  2.64355,
+  1.46676,  1.58771,  2.04614,  2.2766,  2.54651,  2.64991,
+  1.41461,  1.49916,  2.00069,  2.08085,  2.54908,  2.65441,
+  1.32462,  1.59742,  1.9617,  2.07526,  2.51879,  2.63826,
+  1.26245,  1.66607,  1.96155,  2.09827,  2.5491,  2.63037,
+  1.22087,  1.63212,  1.94765,  2.05495,  2.51597,  2.60756,
+  1.13665,  1.56914,  1.92325,  2.0114,  2.51398,  2.61292,
+  1.05857,  1.57058,  1.92127,  2.03797,  2.48449,  2.5695,
+  1.03982,  1.49237,  1.86238,  2.11332,  2.46263,  2.58629,
+  1.29165,  1.54669,  1.88843,  2.16034,  2.44457,  2.57368,
+  1.15415,  1.62983,  1.97872,  2.11452,  2.50541,  2.61617,
+  1.01899,  1.84423,  2.0035,  2.14564,  2.43005,  2.54966,
+  1.00364,  1.90025,  2.10397,  2.20081,  2.55527,  2.67887,
+  1.00718,  1.65253,  2.03338,  2.1179,  2.53436,  2.59384,
+  1.01407,  1.62531,  2.07357,  2.164,  2.54614,  2.61183,
+  1.00985,  1.72901,  2.00161,  2.19007,  2.55455,  2.63543,
+  1.01949,  1.59982,  2.06292,  2.18098,  2.58535,  2.65191,
+  1.04228,  1.55985,  2.06172,  2.18491,  2.60883,  2.71127,
+  1.09398,  1.6067,  2.06705,  2.17946,  2.57811,  2.64708,
+  1.11752,  1.5545,  2.01046,  2.17126,  2.52419,  2.60461,
+  1.18915,  1.68712,  2.02682,  2.22074,  2.58466,  2.6736,
+  1.18429,  1.59293,  2.01141,  2.14056,  2.57563,  2.65276,
+  1.24327,  1.54434,  1.99135,  2.10372,  2.54773,  2.63384,
+  1.2498,  1.53006,  1.93046,  2.04451,  2.4895,  2.61104,
+  1.31723,  1.55086,  1.92747,  2.01911,  2.56358,  2.63241,
+  1.30015,  1.5712,  1.81721,  1.96732,  2.57201,  2.65975,
+  1.30479,  1.45907,  1.80435,  1.8738,  2.57235,  2.67785,
+  1.27211,  1.38793,  1.71059,  1.79844,  2.51912,  2.63097,
+  1.16882,  1.27144,  1.68047,  1.84764,  2.47259,  2.63611,
+  1.12771,  1.38042,  1.70269,  1.94834,  2.2548,  2.51659,
+  1.03734,  1.36207,  1.69887,  1.94336,  2.31998,  2.57611,
+  0.912701,  1.21524,  1.77476,  2.05793,  2.4073,  2.60974,
+  0.884045,  1.28334,  1.74009,  2.01204,  2.33233,  2.53015,
+  0.859928,  1.36139,  1.78777,  2.03243,  2.43916,  2.5725,
+  0.933575,  1.49731,  1.86011,  2.00776,  2.46078,  2.63658,
+  0.980843,  1.37667,  1.80827,  1.8993,  2.55138,  2.66068,
+  0.888314,  1.39084,  1.81906,  1.9386,  2.61173,  2.7137,
+  0.839112,  1.45505,  1.86425,  1.93257,  2.56126,  2.64948,
+  0.851738,  1.63344,  1.85494,  2.0651,  2.59153,  2.63797,
+  0.927993,  1.73919,  1.88202,  2.1332,  2.58502,  2.64078,
+  0.938681,  1.79566,  1.96211,  2.13893,  2.56523,  2.6279,
+  0.939389,  1.84213,  2.02182,  2.19635,  2.61152,  2.65832,
+  0.876668,  1.92276,  2.0666,  2.23861,  2.65783,  2.70914,
+  0.92889,  1.83181,  2.05372,  2.20362,  2.65364,  2.69541,
+  0.843177,  1.78595,  2.18004,  2.25807,  2.59681,  2.66987,
+  0.90471,  1.73857,  2.04548,  2.17133,  2.65908,  2.70177,
+  0.870576,  1.67285,  2.04668,  2.1603,  2.66339,  2.70628,
+  0.863208,  1.61128,  2.03958,  2.13199,  2.66274,  2.71021,
+  0.911587,  1.52148,  1.97225,  2.1177,  2.67151,  2.73629,
+  0.857624,  1.50623,  1.92746,  2.09207,  2.599,  2.67135,
+  0.876724,  1.38621,  1.9301,  2.02012,  2.64025,  2.71571,
+  0.822485,  1.36308,  1.9511,  2.01209,  2.54628,  2.70422,
+  0.896312,  1.29923,  1.94615,  2.04,  2.42757,  2.66043,
+  0.993275,  1.37977,  2.00112,  2.08344,  2.47648,  2.62108,
+  1.11197,  1.36926,  1.98057,  2.05008,  2.51842,  2.65472,
+  1.16821,  1.42116,  1.92965,  2.01373,  2.5139,  2.65946,
+  1.18553,  1.47731,  1.9417,  2.02179,  2.54584,  2.63683,
+  1.13468,  1.49839,  1.99686,  2.07705,  2.4871,  2.60596,
+  1.41173,  1.50081,  1.93056,  2.25169,  2.39141,  2.51475,
+  1.3871,  1.55163,  1.93927,  2.13443,  2.39065,  2.5381,
+  1.43647,  1.60163,  1.85631,  2.00172,  2.49843,  2.57968,
+  1.49076,  1.67386,  1.86537,  2.01526,  2.49094,  2.5896,
+  1.53229,  1.66582,  1.85411,  1.98779,  2.54431,  2.63455,
+  1.56314,  1.68325,  1.81921,  1.98134,  2.5924,  2.65599,
+  1.53269,  1.64287,  1.79509,  1.95595,  2.59557,  2.68867,
+  1.50694,  1.59687,  1.72472,  1.90252,  2.49715,  2.64677,
+  1.38523,  1.5533,  1.73378,  1.99349,  2.38568,  2.62019,
+  1.19137,  1.50809,  1.91412,  2.17718,  2.46035,  2.60064,
+  0.990202,  1.26842,  1.7603,  1.98849,  2.51666,  2.66102,
+  1.00489,  1.27303,  1.91958,  1.97696,  2.62153,  2.71115,
+  1.01329,  1.47917,  1.98377,  2.02111,  2.56129,  2.68139,
+  1.09438,  1.4242,  1.985,  2.16479,  2.59214,  2.67097,
+  1.05777,  1.37751,  1.86611,  2.16542,  2.49067,  2.62334,
+  1.00177,  1.3213,  1.90229,  2.13388,  2.49989,  2.65935,
+  0.896048,  1.41478,  1.92755,  2.1276,  2.57065,  2.6585,
+  0.862503,  1.58697,  1.94655,  2.15362,  2.61512,  2.67787,
+  0.837783,  1.70001,  1.93298,  2.20945,  2.58857,  2.68753,
+  0.901209,  1.63977,  1.99997,  2.07058,  2.5153,  2.76315,
+  0.955829,  1.60125,  2.00897,  2.11223,  2.50389,  2.59284,
+  0.939285,  1.70409,  2.02741,  2.12592,  2.43001,  2.53892,
+  0.948268,  1.70087,  2.00277,  2.08835,  2.56347,  2.62211,
+  0.959154,  1.62427,  2.00582,  2.07776,  2.57772,  2.65873,
+  0.932538,  1.59344,  1.95283,  2.04466,  2.56798,  2.6445,
+  0.933107,  1.59056,  1.9457,  2.1119,  2.53428,  2.60887,
+  0.943808,  1.64909,  1.89702,  2.10465,  2.57817,  2.68976,
+  1.00303,  1.61916,  1.93023,  2.21672,  2.58234,  2.63789,
+  0.93681,  1.69235,  1.96553,  2.11865,  2.62852,  2.6848,
+  0.973578,  1.73782,  1.97567,  2.10634,  2.65829,  2.72245,
+  0.955324,  1.75019,  1.96144,  2.07537,  2.65561,  2.73176,
+  0.994013,  1.72739,  1.94678,  2.06241,  2.64338,  2.73849,
+  1.00536,  1.69392,  1.92987,  2.10018,  2.61875,  2.68486,
+  0.967862,  1.64008,  1.93026,  2.02155,  2.63989,  2.72666,
+  0.928258,  1.57936,  1.86441,  1.97301,  2.63891,  2.71789,
+  1.05833,  1.41059,  1.87085,  2.06602,  2.45158,  2.6337,
+  1.12305,  1.48688,  1.86297,  2.08608,  2.41298,  2.59174,
+  1.17747,  1.43154,  1.84929,  2.09976,  2.42334,  2.56613,
+  1.18703,  1.44351,  1.88207,  1.98332,  2.55067,  2.63939,
+  1.26797,  1.62839,  1.93261,  2.04328,  2.55223,  2.64173,
+  1.35555,  1.70156,  1.92424,  2.03456,  2.59018,  2.66096,
+  1.47206,  1.73998,  1.91426,  2.05233,  2.57389,  2.64493,
+  1.46149,  1.79066,  1.91131,  2.05787,  2.5256,  2.58723,
+  1.54235,  1.7424,  1.90165,  2.06306,  2.49917,  2.58066,
+  1.55081,  1.6429,  1.87739,  1.99515,  2.47436,  2.56117,
+  1.62535,  1.72476,  1.89911,  2.05259,  2.44709,  2.55685,
+  1.6367,  1.7422,  1.90449,  2.15532,  2.47031,  2.56929,
+  1.60869,  1.70103,  1.95711,  2.08558,  2.46532,  2.5522,
+  1.51757,  1.68517,  1.92305,  2.02897,  2.3829,  2.50393,
+  1.21585,  1.64813,  1.84289,  2.04997,  2.39383,  2.48435,
+  1.1585,  1.45299,  1.75267,  1.85902,  2.46727,  2.57552,
+  1.12827,  1.38415,  1.8015,  1.89918,  2.47245,  2.60999,
+  1.08062,  1.41434,  1.81249,  1.91664,  2.42269,  2.62012,
+  1.10487,  1.49291,  1.85404,  1.97194,  2.444,  2.58358,
+  1.23581,  1.43782,  1.91948,  2.04279,  2.484,  2.61715,
+  1.16741,  1.4076,  1.77439,  2.07357,  2.3906,  2.54332,
+  1.09657,  1.31723,  1.78221,  2.01354,  2.39437,  2.57181,
+  1.10431,  1.2068,  1.71858,  2.00101,  2.35134,  2.50564,
+  1.04732,  1.31689,  1.82432,  2.05077,  2.41716,  2.53103,
+  1.08718,  1.4084,  1.84314,  2.03167,  2.44048,  2.54426,
+  1.10852,  1.3942,  1.76003,  2.00573,  2.43503,  2.55215,
+  1.12177,  1.34059,  1.7495,  1.96363,  2.49382,  2.60964,
+  1.12241,  1.45271,  1.79313,  2.03041,  2.50213,  2.59324,
+  1.02688,  1.4681,  1.74534,  1.86047,  2.48368,  2.57975,
+  0.97167,  1.24409,  1.75298,  1.83733,  2.38472,  2.62532,
+  0.917302,  1.10441,  1.67493,  1.79243,  2.33619,  2.62947,
+  0.96156,  1.08836,  1.55578,  1.66371,  2.28232,  2.57975,
+  0.919563,  1.06328,  1.5732,  1.7111,  2.42269,  2.67598,
+  0.875889,  1.02261,  1.38084,  1.82916,  2.58466,  2.66738,
+  0.763749,  1.01881,  1.50632,  1.70798,  2.47153,  2.59587,
+  0.886944,  1.03139,  1.42506,  1.71002,  2.42792,  2.57639,
+  0.890351,  1.03765,  1.44399,  1.58788,  2.52021,  2.69583,
+  0.906256,  1.03505,  1.40561,  1.52374,  2.53653,  2.59608,
+  0.929418,  1.06107,  1.15709,  1.5666,  2.52826,  2.69407,
+  0.917396,  1.10612,  1.25304,  1.38951,  2.55157,  2.7091,
+  0.91023,  1.04207,  1.16253,  1.36213,  2.39308,  2.60535,
+  0.804288,  1.05959,  1.41808,  1.53036,  2.41057,  2.66344,
+  0.907675,  1.04629,  1.39254,  1.50823,  2.49535,  2.69234,
+  0.835212,  1.12687,  1.3505,  1.46321,  2.56773,  2.69467,
+  0.770295,  1.1507,  1.42826,  1.60117,  2.61023,  2.68367,
+  0.924536,  1.07541,  1.46853,  1.66987,  2.54368,  2.6932,
+  0.972382,  1.19176,  1.54476,  1.63867,  2.53532,  2.64297,
+  0.903877,  1.10193,  1.51078,  1.60266,  2.48704,  2.63827,
+  0.881279,  1.0969,  1.55425,  1.6443,  2.42466,  2.55757,
+  0.866115,  1.11888,  1.60304,  1.70247,  2.5439,  2.6493,
+  0.906645,  1.16025,  1.67202,  1.74726,  2.51791,  2.65086,
+  0.861085,  1.20586,  1.66099,  1.84709,  2.46274,  2.63203,
+  0.837175,  1.18778,  1.80604,  1.8895,  2.50861,  2.68456,
+  0.797709,  1.17852,  1.90318,  2.02165,  2.54618,  2.69007,
+  0.802875,  1.26275,  1.92394,  2.00058,  2.56844,  2.67011,
+  0.766638,  1.32083,  1.96102,  2.05894,  2.58231,  2.64672,
+  0.811579,  1.45519,  2.01148,  2.08478,  2.54842,  2.63993,
+  0.82977,  1.48496,  2.05271,  2.12723,  2.53064,  2.60818,
+  0.799011,  1.56745,  2.15563,  2.26511,  2.57317,  2.6685,
+  0.730379,  1.35861,  2.12579,  2.19459,  2.5187,  2.60543,
+  0.720667,  1.27784,  2.04281,  2.11192,  2.5928,  2.6753,
+  0.777663,  1.1637,  2.06679,  2.1792,  2.57,  2.67551,
+  0.839969,  1.37318,  2.18588,  2.30468,  2.50936,  2.60258,
+  0.815752,  1.91522,  2.23363,  2.28848,  2.56998,  2.62843,
+  1.19188,  1.94569,  2.17513,  2.29905,  2.52352,  2.63204,
+  1.03628,  1.74221,  2.07271,  2.14156,  2.57319,  2.64155,
+  1.04251,  1.30305,  2.01289,  2.15461,  2.53068,  2.64918,
+  1.10994,  1.20424,  1.92869,  2.05823,  2.3841,  2.63957,
+  1.18739,  1.2877,  1.95425,  2.07126,  2.38256,  2.64181,
+  1.23919,  1.32776,  1.93055,  2.01528,  2.36169,  2.6275,
+  1.29208,  1.35198,  1.93801,  2.01732,  2.4115,  2.66343,
+  1.30624,  1.3824,  1.91845,  2.03831,  2.33939,  2.63774,
+  1.33024,  1.40164,  1.87376,  1.99044,  2.1855,  2.51091,
+  1.35639,  1.45976,  1.88339,  1.98046,  2.26455,  2.54181,
+  1.3474,  1.43864,  1.89167,  2.01801,  2.30257,  2.64381,
+  1.30088,  1.39017,  1.88927,  1.97293,  2.33752,  2.60564,
+  1.31867,  1.41012,  1.89535,  1.99037,  2.38468,  2.65404,
+  1.30927,  1.4255,  1.96615,  2.0219,  2.50112,  2.69851,
+  1.29385,  1.37092,  1.90844,  1.99915,  2.46548,  2.674,
+  1.2774,  1.38284,  2.0023,  2.06684,  2.49685,  2.66407,
+  1.24538,  1.42244,  2.00291,  2.07072,  2.55684,  2.66639,
+  1.27259,  1.49109,  2.0123,  2.12924,  2.56231,  2.65743,
+  1.26518,  1.53394,  2.02094,  2.09309,  2.49838,  2.63095,
+  1.2657,  1.47703,  2.10301,  2.19653,  2.45528,  2.61989,
+  1.2885,  1.64245,  2.09385,  2.24783,  2.56169,  2.65879,
+  1.41026,  1.82897,  2.17187,  2.37413,  2.56459,  2.65338,
+  1.35389,  1.71004,  2.20933,  2.42604,  2.62932,  2.70219,
+  1.41361,  1.76693,  2.13772,  2.43485,  2.63206,  2.70291,
+  1.45905,  1.70694,  2.13508,  2.37703,  2.62642,  2.70895,
+  1.49802,  1.68792,  2.09482,  2.34295,  2.55878,  2.6657,
+  1.41391,  1.58827,  2.08673,  2.29308,  2.51359,  2.64213,
+  1.4,  1.55334,  1.93877,  2.18387,  2.45866,  2.61041,
+  1.37352,  1.44979,  1.8806,  2.07984,  2.29824,  2.55977,
+  1.36754,  1.44075,  1.97377,  2.08607,  2.33911,  2.62191,
+  1.36884,  1.46082,  2.00605,  2.12979,  2.39152,  2.65052,
+  1.37599,  1.49624,  2.05005,  2.13085,  2.45392,  2.69863,
+  1.34057,  1.48416,  2.08413,  2.14094,  2.54992,  2.68543,
+  1.38997,  1.55301,  2.06378,  2.14798,  2.59226,  2.70382,
+  1.24745,  1.50338,  2.0443,  2.13649,  2.34449,  2.59917,
+  1.31511,  1.54085,  2.02833,  2.11633,  2.27254,  2.43155,
+  1.29883,  1.58749,  2.07193,  2.18587,  2.33569,  2.50078,
+  1.29366,  1.56243,  2.0311,  2.14961,  2.40817,  2.51729,
+  1.35755,  1.5133,  1.99809,  2.15305,  2.45046,  2.5838,
+  1.31441,  1.51742,  2.07946,  2.17944,  2.52229,  2.6162,
+  1.23775,  1.51356,  2.05223,  2.18107,  2.53904,  2.62816,
+  1.20856,  1.48604,  2.0465,  2.19467,  2.48998,  2.63667,
+  1.19657,  1.46249,  2.07314,  2.23086,  2.54763,  2.7006,
+  1.08094,  1.45943,  2.1105,  2.21771,  2.53813,  2.67835,
+  1.09448,  1.37861,  2.16788,  2.24618,  2.56793,  2.69132,
+  0.942435,  1.46334,  2.25353,  2.33078,  2.53848,  2.62677,
+  0.828468,  1.39017,  2.15232,  2.21803,  2.54527,  2.62149,
+  0.883311,  1.3342,  2.09482,  2.19126,  2.47558,  2.57346,
+  0.863185,  1.41868,  2.08049,  2.16638,  2.5561,  2.71409,
+  0.84852,  1.39108,  2.04932,  2.13419,  2.70254,  2.78082,
+  0.826225,  1.37358,  2.03739,  2.12058,  2.73609,  2.78259,
+  0.823246,  1.34385,  2.03389,  2.1118,  2.74087,  2.78707,
+  0.833848,  1.33679,  2.04545,  2.11801,  2.69961,  2.79618,
+  0.811654,  1.32134,  2.09499,  2.17812,  2.49423,  2.6499,
+  0.947528,  1.36115,  2.12785,  2.21901,  2.51138,  2.66819,
+  0.875759,  1.25161,  2.13342,  2.24175,  2.47382,  2.66293,
+  0.933534,  1.44844,  2.13913,  2.24451,  2.48676,  2.60694,
+  0.945109,  1.2808,  2.20894,  2.33506,  2.51132,  2.61453,
+  0.956935,  1.37124,  2.1072,  2.19452,  2.40325,  2.57303,
+  0.981,  1.25193,  2.14796,  2.2666,  2.44042,  2.62437,
+  1.06161,  1.23169,  2.07602,  2.2334,  2.4386,  2.63699,
+  1.01887,  1.35404,  1.99803,  2.26008,  2.44314,  2.55477,
+  1.0803,  1.30189,  2.03463,  2.1456,  2.41506,  2.59122,
+  1.13387,  1.35976,  2.06395,  2.16463,  2.43939,  2.62866,
+  1.12504,  1.41413,  1.99754,  2.10372,  2.39242,  2.59958,
+  1.16727,  1.39356,  1.99818,  2.07648,  2.44178,  2.64329,
+  1.1987,  1.42119,  1.96798,  2.05702,  2.43282,  2.64507,
+  1.25623,  1.37807,  1.94185,  2.01933,  2.44458,  2.60885,
+  1.29557,  1.41215,  1.93241,  2.00835,  2.43005,  2.64902,
+  1.28135,  1.46452,  1.88824,  2.00652,  2.42528,  2.6352,
+  1.27058,  1.4067,  1.90119,  1.96929,  2.47098,  2.6479,
+  1.2667,  1.37289,  1.87181,  1.95759,  2.41497,  2.64862,
+  1.19439,  1.35174,  1.88825,  1.97809,  2.40086,  2.66266,
+  1.19887,  1.29984,  1.86428,  1.96365,  2.36279,  2.61951,
+  1.12658,  1.2401,  1.90254,  1.99765,  2.33143,  2.60863,
+  1.10462,  1.21418,  1.87979,  2.01431,  2.25166,  2.57337,
+  1.02429,  1.19321,  1.86892,  2.12788,  2.37601,  2.62345,
+  1.00036,  1.23021,  1.9603,  2.07524,  2.32935,  2.58413,
+  0.977548,  1.32199,  1.98875,  2.10426,  2.38103,  2.60792,
+  0.927608,  1.44792,  2.02789,  2.12301,  2.47848,  2.58588,
+  0.887733,  1.51653,  2.0469,  2.15389,  2.48052,  2.58201,
+  0.898681,  1.56475,  2.09153,  2.17965,  2.57394,  2.67678,
+  0.974718,  1.50086,  2.08197,  2.17778,  2.53228,  2.63499,
+  1.02382,  1.39064,  2.06059,  2.14203,  2.46939,  2.63691,
+  1.10658,  1.43105,  1.97713,  2.09715,  2.47169,  2.65912,
+  1.20126,  1.48566,  1.94465,  2.11254,  2.50025,  2.66593,
+  1.28569,  1.52066,  1.91106,  2.04425,  2.48771,  2.6658,
+  1.36249,  1.53479,  1.91055,  1.99094,  2.50571,  2.66153,
+  1.43459,  1.51484,  1.93419,  2.01741,  2.50153,  2.69388,
+  1.42084,  1.51949,  1.90935,  1.98665,  2.4604,  2.68819,
+  1.40441,  1.46981,  1.96429,  2.05423,  2.36679,  2.65527,
+  1.38829,  1.46691,  1.96405,  2.05895,  2.28653,  2.60493,
+  1.368,  1.43481,  1.8577,  2.00712,  2.19658,  2.60419,
+  1.30084,  1.38054,  1.74025,  2.04689,  2.23523,  2.52191,
+  1.2313,  1.3216,  1.86723,  2.14763,  2.35463,  2.57914,
+  1.15492,  1.2559,  1.93232,  2.16437,  2.39283,  2.60599,
+  1.09866,  1.20222,  1.94827,  2.15016,  2.4926,  2.62574,
+  1.05746,  1.22185,  1.86913,  2.26883,  2.45654,  2.58036,
+  1.03308,  1.1501,  1.70887,  2.26488,  2.47604,  2.56361,
+  0.988998,  1.15927,  1.96203,  2.30271,  2.44872,  2.56072,
+  1.02842,  1.22869,  2.02591,  2.26037,  2.56185,  2.66176,
+  0.93486,  1.34821,  2.05389,  2.21474,  2.5253,  2.64771,
+  0.91915,  1.26456,  2.06814,  2.1834,  2.53498,  2.64432,
+  0.975247,  1.36223,  2.05215,  2.23142,  2.5828,  2.72448,
+  0.954336,  1.31118,  1.97737,  2.23816,  2.47811,  2.61705,
+  0.941853,  1.33598,  1.97642,  2.21901,  2.57949,  2.7143,
+  0.928694,  1.36645,  1.88488,  2.18315,  2.58056,  2.65759,
+  0.986067,  1.33837,  1.95432,  2.18786,  2.56652,  2.63883,
+  0.912646,  1.2844,  1.81414,  2.17507,  2.55393,  2.63852,
+  0.968965,  1.3105,  1.83969,  2.07808,  2.59033,  2.66057,
+  0.977192,  1.30463,  1.88095,  2.12702,  2.59804,  2.71211,
+  1.02384,  1.29962,  1.94471,  2.10378,  2.62592,  2.7309,
+  1.11021,  1.28631,  1.95938,  2.05397,  2.56459,  2.67613,
+  1.02814,  1.32424,  1.97674,  2.09494,  2.5862,  2.75473,
+  1.1298,  1.26991,  2.01187,  2.10922,  2.5889,  2.69654,
+  1.05697,  1.34048,  2.01617,  2.10555,  2.55761,  2.74716,
+  1.0375,  1.25577,  2.02939,  2.13619,  2.51178,  2.70963,
+  1.00616,  1.41717,  2.07195,  2.13261,  2.5439,  2.70196,
+  1.13696,  1.41621,  2.05034,  2.11204,  2.44967,  2.6952,
+  1.13532,  1.43627,  2.08385,  2.19492,  2.38638,  2.65693,
+  1.09407,  1.38546,  2.01516,  2.11333,  2.3201,  2.64153,
+  1.02593,  1.36065,  1.8783,  1.98146,  2.12804,  2.45894,
+  1.14275,  1.41616,  1.90101,  2.05488,  2.17021,  2.45905,
+  1.09321,  1.48838,  1.80138,  2.07358,  2.20343,  2.49483,
+  1.16124,  1.26326,  1.78481,  2.0712,  2.19458,  2.43622,
+  1.01079,  1.14118,  1.72817,  2.11872,  2.25127,  2.42633,
+  1.0838,  1.27598,  1.88843,  2.06839,  2.22746,  2.51111,
+  1.09382,  1.3034,  1.92409,  2.18396,  2.34853,  2.5317,
+  1.40987,  1.54006,  1.72233,  2.04991,  2.23569,  2.38925,
+  1.4666,  1.61703,  1.81939,  2.03581,  2.43973,  2.54332,
+  1.52688,  1.81173,  1.92615,  2.1292,  2.48147,  2.55606,
+  1.42046,  1.73161,  1.92536,  2.08112,  2.47445,  2.57028,
+  1.24837,  1.46252,  1.69927,  1.90711,  2.35535,  2.4848,
+  1.18322,  1.55816,  1.64662,  1.99981,  2.37407,  2.4616,
+  1.14384,  1.51329,  1.67569,  1.90675,  2.42836,  2.51879,
+  1.06699,  1.50005,  1.66753,  1.96146,  2.4459,  2.52156,
+  1.04665,  1.52076,  1.70516,  1.87838,  2.45976,  2.53273,
+  1.01371,  1.55953,  1.73753,  1.95585,  2.43782,  2.51586,
+  1.02195,  1.58688,  1.73703,  1.92918,  2.52364,  2.57788,
+  0.942307,  1.57915,  1.7761,  2.06027,  2.43722,  2.51765,
+  0.914226,  1.64208,  1.8128,  2.00109,  2.50851,  2.57006,
+  0.952017,  1.68807,  1.93502,  2.01615,  2.44679,  2.56358,
+  0.85628,  1.69751,  1.90273,  2.01269,  2.52241,  2.5844,
+  0.891878,  1.55315,  1.9355,  2.04697,  2.53266,  2.59497,
+  0.845424,  1.60229,  1.93772,  2.02752,  2.58302,  2.64917,
+  0.876501,  1.71662,  1.93957,  2.06754,  2.58826,  2.62536,
+  0.901014,  1.86437,  1.97892,  2.07519,  2.46267,  2.6098,
+  0.911677,  1.76785,  1.94779,  2.07258,  2.59574,  2.63495,
+  0.937394,  1.70873,  1.92774,  2.05461,  2.57411,  2.64743,
+  1.00365,  1.61461,  1.94206,  2.03598,  2.59201,  2.66472,
+  1.08941,  1.56371,  1.91069,  1.97496,  2.59091,  2.68182,
+  1.1802,  1.45723,  1.84084,  1.92159,  2.57341,  2.65935,
+  1.23938,  1.44428,  1.81891,  1.89387,  2.5596,  2.65742,
+  1.37732,  1.52899,  1.7449,  1.86222,  2.59116,  2.66907,
+  1.5049,  1.58946,  1.77776,  1.88723,  2.50621,  2.61775,
+  1.62841,  1.69744,  1.8306,  1.95757,  2.49541,  2.65298,
+  1.65534,  1.72676,  1.91445,  2.04295,  2.58971,  2.65897,
+  1.69817,  1.75401,  1.96719,  2.09043,  2.60271,  2.67713,
+  1.6763,  1.76771,  2.04285,  2.15667,  2.62832,  2.69069,
+  1.72497,  1.78993,  2.02225,  2.13845,  2.57623,  2.67177,
+  1.74819,  1.80267,  2.03778,  2.18025,  2.54251,  2.63895,
+  1.72749,  1.82059,  1.98449,  2.15907,  2.52527,  2.64111,
+  1.68116,  1.82095,  1.9757,  2.15738,  2.4858,  2.59041,
+  1.69559,  1.80719,  1.99368,  2.18089,  2.38033,  2.56086,
+  1.70693,  1.8107,  2.00812,  2.1331,  2.42075,  2.64175,
+  1.65458,  1.76573,  2.02476,  2.12403,  2.49348,  2.66085,
+  1.48228,  1.84953,  2.03934,  2.24048,  2.45722,  2.54777,
+  1.60391,  1.83254,  2.0516,  2.25163,  2.46114,  2.56041,
+  1.61191,  1.78732,  2.13446,  2.25032,  2.62094,  2.67828,
+  1.70226,  1.85766,  2.09357,  2.24578,  2.63356,  2.6878,
+  1.69236,  1.77625,  2.02619,  2.27536,  2.58055,  2.68324,
+  1.58711,  1.7503,  1.99794,  2.24207,  2.58654,  2.69145,
+  1.53555,  1.76534,  2.05361,  2.23362,  2.64673,  2.71788,
+  1.18962,  1.33679,  1.76375,  2.00182,  2.43607,  2.59429,
+  1.19096,  1.32263,  1.6625,  2.02854,  2.34741,  2.53098,
+  1.17093,  1.39469,  1.72743,  2.02281,  2.38266,  2.5526,
+  1.0828,  1.38331,  1.62323,  1.82565,  2.46313,  2.57449,
+  1.05886,  1.31642,  1.61784,  1.7344,  2.49668,  2.60735,
+  1.03174,  1.33271,  1.53473,  1.70742,  2.43327,  2.54421,
+  1.09663,  1.40593,  1.54058,  1.71992,  2.50965,  2.57321,
+  1.08814,  1.38193,  1.50722,  1.61855,  2.48411,  2.61844,
+  1.12836,  1.34181,  1.49417,  1.71555,  2.49597,  2.57986,
+  1.17504,  1.36011,  1.5729,  1.75716,  2.48116,  2.58891,
+  1.25184,  1.38829,  1.58041,  1.74429,  2.53023,  2.61428,
+  1.31074,  1.44427,  1.65725,  1.82349,  2.51511,  2.6146,
+  1.32959,  1.48366,  1.70393,  1.87146,  2.53237,  2.62192,
+  1.36465,  1.5031,  1.75584,  1.91903,  2.54748,  2.62441,
+  1.40014,  1.51678,  1.80865,  1.94381,  2.57234,  2.65555,
+  1.40394,  1.53678,  1.85457,  1.96117,  2.52777,  2.65014,
+  1.44164,  1.5349,  1.87363,  1.97075,  2.52812,  2.67083,
+  1.44861,  1.52867,  1.86098,  1.95195,  2.47324,  2.65781,
+  1.45162,  1.54784,  1.82415,  2.01998,  2.46245,  2.6541,
+  1.47491,  1.54848,  1.89089,  1.99547,  2.48461,  2.65999,
+  1.43235,  1.54152,  1.88892,  2.0602,  2.40709,  2.63044,
+  1.44374,  1.52979,  1.8927,  1.99659,  2.3738,  2.62098,
+  1.37922,  1.48973,  1.89736,  2.01674,  2.41678,  2.6275,
+  1.37707,  1.46312,  1.91165,  2.02262,  2.35539,  2.60865,
+  1.3318,  1.43104,  1.92917,  2.0469,  2.37404,  2.605,
+  1.26139,  1.44854,  1.97546,  2.08252,  2.36686,  2.6208,
+  1.22253,  1.41897,  1.97979,  2.11631,  2.43959,  2.66463,
+  1.14294,  1.30444,  1.9845,  2.07136,  2.47308,  2.67295,
+  1.16307,  1.26852,  1.93044,  2.0463,  2.3051,  2.59445,
+  1.10251,  1.24609,  1.95173,  2.10327,  2.29978,  2.57198,
+  1.01057,  1.14733,  1.90254,  2.04624,  2.28802,  2.567,
+  1.01047,  1.307,  1.82765,  2.07687,  2.33326,  2.55597,
+  1.24634,  1.53463,  1.85908,  2.18799,  2.38807,  2.54162,
+  1.20049,  1.57894,  1.89923,  2.16502,  2.44888,  2.58318,
+  0.969958,  1.32117,  1.8792,  2.16627,  2.41795,  2.60245,
+  0.883738,  1.35958,  2.00452,  2.10073,  2.51698,  2.63339,
+  0.844286,  1.40555,  2.05705,  2.14052,  2.51643,  2.66006,
+  0.862435,  1.50233,  2.10741,  2.20516,  2.55819,  2.66049,
+  0.940459,  1.42824,  2.13982,  2.23332,  2.56448,  2.67376,
+  0.930987,  1.58398,  2.0219,  2.15239,  2.40404,  2.50634,
+  1.04656,  1.79826,  1.98842,  2.12929,  2.35758,  2.45354,
+  1.05348,  1.59375,  2.10433,  2.23268,  2.37281,  2.49815,
+  1.13765,  1.64278,  2.08915,  2.23181,  2.38316,  2.57557,
+  1.18078,  1.89984,  2.11471,  2.22334,  2.45315,  2.55491,
+  1.14477,  1.7958,  2.05817,  2.1941,  2.45214,  2.55875,
+  1.13255,  1.6883,  1.98025,  2.10745,  2.32195,  2.44657,
+  1.15584,  1.527,  1.95125,  2.10187,  2.26567,  2.42326,
+  1.21899,  1.55188,  1.97893,  2.1295,  2.36524,  2.54789,
+  1.26996,  1.59283,  1.9574,  2.05925,  2.47736,  2.62007,
+  1.30477,  1.59715,  1.97427,  2.08441,  2.41441,  2.61344,
+  1.30461,  1.64552,  1.9768,  2.10058,  2.36447,  2.5106,
+  1.35745,  1.72162,  2.01397,  2.14179,  2.38518,  2.51214,
+  1.33572,  1.83391,  2.00127,  2.15585,  2.40144,  2.4961,
+  1.3114,  1.55829,  1.93876,  2.06328,  2.30727,  2.52662,
+  1.36036,  1.44076,  1.89358,  2.07531,  2.23753,  2.5046,
+  1.3316,  1.46849,  1.9289,  2.06096,  2.31803,  2.56782,
+  1.31861,  1.5376,  1.92447,  2.01519,  2.35881,  2.59331,
+  1.21436,  1.54619,  1.8821,  1.99525,  2.37793,  2.65294,
+  1.29633,  1.56653,  1.87514,  2.00328,  2.47632,  2.63153,
+  1.39778,  1.58615,  1.86148,  2.03011,  2.58706,  2.65465,
+  1.47524,  1.6442,  1.91588,  2.04703,  2.65327,  2.71442,
+  1.52474,  1.71602,  1.95782,  2.06765,  2.6237,  2.69024,
+  1.57869,  1.67781,  1.94092,  2.06678,  2.61383,  2.70458,
+  1.55866,  1.70253,  1.93011,  2.02827,  2.61505,  2.68653,
+  1.5009,  1.6999,  1.90892,  1.99874,  2.62063,  2.69128,
+  1.44295,  1.70267,  1.90099,  1.97533,  2.62473,  2.69924,
+  1.37288,  1.63829,  1.91771,  2.02829,  2.62618,  2.69745,
+  1.28422,  1.65621,  1.89785,  1.99256,  2.64442,  2.70738,
+  1.20404,  1.65182,  1.88977,  1.99256,  2.63849,  2.70958,
+  1.1492,  1.62207,  1.88451,  1.97925,  2.63269,  2.69924,
+  1.13373,  1.61863,  1.89504,  1.97754,  2.62505,  2.69488,
+  1.15757,  1.66233,  1.88978,  1.97839,  2.62603,  2.68454,
+  1.21894,  1.6671,  1.87906,  2.00517,  2.60227,  2.65813,
+  1.22423,  1.62686,  1.79198,  1.89465,  2.51764,  2.64787,
+  1.35435,  1.55876,  1.84308,  1.93089,  2.57122,  2.63086,
+  1.33953,  1.59509,  1.76225,  1.97927,  2.54602,  2.6132,
+  1.38922,  1.59242,  1.85964,  1.96212,  2.55095,  2.63771,
+  1.44127,  1.59043,  1.87939,  1.98705,  2.58201,  2.66674,
+  1.43103,  1.60981,  1.89027,  2.03787,  2.52504,  2.67206,
+  1.46838,  1.57542,  1.94585,  2.02987,  2.55147,  2.70532,
+  1.45009,  1.60143,  1.9541,  2.0628,  2.53413,  2.66697,
+  1.48217,  1.56544,  1.97359,  2.12415,  2.52021,  2.65602,
+  1.42942,  1.56017,  1.98437,  2.07841,  2.51093,  2.66835,
+  1.44091,  1.58793,  1.97609,  2.09796,  2.46414,  2.62167,
+  1.43247,  1.58261,  1.97335,  2.15993,  2.50051,  2.66833,
+  1.4291,  1.59392,  1.97481,  2.07021,  2.52705,  2.68379,
+  1.37725,  1.57105,  1.93703,  2.09434,  2.48861,  2.65319,
+  1.48527,  1.57272,  1.93552,  2.01586,  2.47189,  2.68702,
+  1.47361,  1.56926,  1.87262,  1.96288,  2.4128,  2.65437,
+  1.48606,  1.58025,  1.86625,  1.97554,  2.31875,  2.58671,
+  1.46521,  1.58112,  1.78499,  1.91302,  2.17248,  2.55592,
+  1.43366,  1.56634,  1.72851,  1.85326,  2.06197,  2.41395,
+  1.36761,  1.54384,  1.70007,  1.85497,  2.03462,  2.28202,
+  1.50326,  1.65718,  1.80936,  1.93767,  2.14319,  2.43561,
+  1.34074,  1.59327,  1.83384,  2.12941,  2.46894,  2.57284,
+  1.33672,  1.4817,  1.94477,  2.23061,  2.48029,  2.58012,
+  1.32132,  1.60314,  1.96833,  2.20337,  2.5151,  2.65005,
+  1.34193,  1.66834,  1.98884,  2.18525,  2.56414,  2.65322,
+  1.31555,  1.6489,  1.9599,  2.14764,  2.51689,  2.61262,
+  1.27731,  1.62022,  2.00186,  2.22941,  2.53155,  2.62182,
+  1.30517,  1.5786,  2.03863,  2.29551,  2.56534,  2.65484,
+  1.33051,  1.60991,  1.99154,  2.26271,  2.56334,  2.66596,
+  1.374,  1.68393,  1.98007,  2.33857,  2.5956,  2.68273,
+  1.2687,  1.38975,  1.88538,  2.1104,  2.48811,  2.63864,
+  1.21681,  1.31005,  1.85469,  2.03671,  2.27759,  2.56653,
+  1.23495,  1.33781,  1.94943,  2.05936,  2.29533,  2.56647,
+  1.18894,  1.30239,  1.9962,  2.10744,  2.34919,  2.58524,
+  1.26898,  1.44015,  2.02477,  2.13685,  2.44401,  2.66404,
+  1.27437,  1.38312,  2.06673,  2.15117,  2.40756,  2.6542,
+  1.26455,  1.35612,  2.00166,  2.11886,  2.28778,  2.56954,
+  1.23434,  1.32978,  2.06339,  2.15077,  2.36719,  2.5986,
+  1.15521,  1.25744,  2.0825,  2.21144,  2.39059,  2.6201,
+  1.19946,  1.26556,  1.93498,  2.22669,  2.54089,  2.6642,
+  1.3047,  1.52685,  1.95455,  2.17466,  2.47769,  2.62171,
+  1.63807,  1.89626,  2.07708,  2.36101,  2.64603,  2.71884,
+  1.64382,  1.94311,  2.13199,  2.32962,  2.57872,  2.64546,
+  1.6409,  1.98922,  2.16147,  2.26921,  2.58647,  2.6554,
+  1.72301,  1.91007,  2.07019,  2.25957,  2.56439,  2.64034,
+  1.65207,  1.99873,  2.13594,  2.35282,  2.65251,  2.71747,
+  1.68072,  2.07409,  2.26967,  2.45347,  2.69994,  2.76304,
+  1.69509,  2.05897,  2.19364,  2.31357,  2.63934,  2.69945,
+  1.78296,  2.01403,  2.2249,  2.33229,  2.64535,  2.7244,
+  1.70596,  1.97475,  2.18083,  2.25608,  2.57518,  2.71694,
+  1.66256,  1.98864,  2.11518,  2.20528,  2.54838,  2.65766,
+  1.56205,  1.8439,  2.17327,  2.26589,  2.47795,  2.69597,
+  1.68592,  1.79584,  2.07833,  2.18014,  2.46537,  2.66731,
+  1.68061,  1.73855,  1.99474,  2.13119,  2.47319,  2.64954,
+  1.65929,  1.83364,  2.00009,  2.14017,  2.56491,  2.69272,
+  1.71489,  1.78482,  1.97491,  2.08523,  2.56667,  2.70104,
+  1.72911,  1.82606,  1.89504,  2.05372,  2.60392,  2.69924,
+  1.69629,  1.79108,  1.91604,  2.01774,  2.58311,  2.7042,
+  1.62684,  1.72099,  1.89044,  2.01448,  2.58919,  2.68914,
+  1.57418,  1.678,  1.8808,  1.9828,  2.57498,  2.66408,
+  1.4326,  1.67638,  1.83467,  1.96466,  2.5353,  2.63865,
+  1.31853,  1.53537,  1.83696,  1.93288,  2.47841,  2.57835,
+  1.22629,  1.49295,  1.83642,  1.94607,  2.43017,  2.58207,
+  1.09891,  1.49905,  1.89629,  2.02887,  2.54053,  2.6186,
+  1.03446,  1.53337,  1.96484,  2.07097,  2.57858,  2.65152,
+  0.979835,  1.48091,  1.97596,  2.08932,  2.53424,  2.63263,
+  0.916592,  1.48129,  1.96751,  2.05329,  2.55835,  2.64274,
+  0.937338,  1.47437,  2.02376,  2.11046,  2.58544,  2.66546,
+  0.873055,  1.56053,  2.0288,  2.08642,  2.57502,  2.68478,
+  0.901938,  1.62841,  2.03181,  2.10285,  2.61016,  2.68565,
+  0.862562,  1.55614,  1.99757,  2.08174,  2.5332,  2.61576,
+  0.90614,  1.66574,  2.01937,  2.13334,  2.58193,  2.66115,
+  0.872836,  1.63866,  2.03844,  2.09728,  2.64501,  2.69779,
+  0.829264,  1.4419,  2.03919,  2.11114,  2.61166,  2.68861,
+  0.825197,  1.30453,  2.05635,  2.14379,  2.59031,  2.65782,
+  0.79352,  1.52102,  1.97944,  2.05842,  2.59623,  2.66858,
+  0.849751,  1.48553,  1.9861,  2.05546,  2.62427,  2.7019,
+  0.849936,  1.38559,  2.00752,  2.06058,  2.56723,  2.67845,
+  0.829655,  1.23098,  1.9884,  2.10148,  2.53073,  2.67733,
+  0.940677,  1.26451,  1.94632,  2.04672,  2.49981,  2.67798,
+  1.03888,  1.29749,  1.95821,  2.036,  2.40697,  2.65032,
+  1.15791,  1.24731,  1.89251,  1.98433,  2.39699,  2.6634,
+  1.23706,  1.31883,  1.84331,  1.95477,  2.42085,  2.69391,
+  1.32887,  1.40395,  1.80868,  1.94612,  2.40089,  2.6834,
+  1.39319,  1.46081,  1.82213,  1.9396,  2.24255,  2.72323,
+  1.37096,  1.52614,  1.78537,  1.96316,  2.13675,  2.6448,
+  1.50113,  1.60677,  1.84183,  2.00946,  2.19846,  2.61465,
+  1.46794,  1.55147,  1.84985,  1.98283,  2.2086,  2.51479,
+  1.40594,  1.48098,  1.85598,  1.99706,  2.17872,  2.49001,
+  1.44817,  1.52096,  1.86881,  1.97537,  2.24103,  2.61635,
+  1.38081,  1.61267,  1.86996,  2.02679,  2.44348,  2.63998,
+  1.48372,  1.59611,  1.96973,  2.10091,  2.57743,  2.68814,
+  1.46768,  1.57822,  1.98656,  2.19471,  2.57095,  2.67109,
+  1.4963,  1.6142,  2.03202,  2.21832,  2.55346,  2.68181,
+  1.59696,  1.72273,  2.14453,  2.31998,  2.60439,  2.70396,
+  1.56328,  1.83007,  2.21313,  2.43293,  2.64111,  2.721,
+  1.5911,  1.94848,  2.28841,  2.48658,  2.66684,  2.74357,
+  1.47571,  1.71866,  2.05098,  2.21796,  2.48728,  2.5718,
+  1.55893,  1.7723,  2.09447,  2.23446,  2.51893,  2.59774,
+  1.56759,  1.82209,  2.10059,  2.28665,  2.53395,  2.64811,
+  1.75003,  1.93667,  2.1356,  2.34764,  2.5469,  2.63832,
+  1.75688,  1.99858,  2.1168,  2.22341,  2.55656,  2.64706,
+  1.70004,  1.92226,  2.07535,  2.18437,  2.55608,  2.63906,
+  1.59867,  1.70971,  1.99456,  2.09879,  2.5214,  2.62844,
+  1.60978,  1.7198,  1.93753,  2.09198,  2.54758,  2.62107,
+  1.58074,  1.68669,  1.92793,  2.05951,  2.58033,  2.64353,
+  1.54116,  1.68466,  1.9448,  2.03825,  2.56852,  2.6371,
+  1.4745,  1.63389,  1.88133,  1.98885,  2.5547,  2.62359,
+  1.42769,  1.61681,  1.89847,  1.99412,  2.54591,  2.63584,
+  1.36697,  1.58374,  1.86076,  2.01809,  2.52625,  2.59403,
+  1.2579,  1.5624,  1.87076,  1.96175,  2.51205,  2.58959,
+  1.18331,  1.57125,  1.86744,  1.98879,  2.54377,  2.60779,
+  1.13772,  1.60719,  1.87915,  2.00877,  2.5368,  2.60748,
+  1.05382,  1.51142,  1.90444,  2.00239,  2.58485,  2.65709,
+  1.02931,  1.56067,  1.91347,  1.98444,  2.61342,  2.67092,
+  0.990299,  1.5203,  1.91971,  2.00599,  2.61587,  2.70596,
+  0.927002,  1.48685,  1.9001,  1.97777,  2.61462,  2.69576,
+  0.924166,  1.5003,  1.83727,  1.91582,  2.60179,  2.70283,
+  0.901854,  1.42276,  1.89801,  1.95014,  2.57299,  2.7593,
+  0.910623,  1.28648,  1.80128,  1.92579,  2.43815,  2.67129,
+  0.904293,  1.22614,  1.87334,  1.94691,  2.48527,  2.64553,
+  0.872654,  1.12266,  1.9125,  2.04762,  2.46806,  2.64549,
+  1.13608,  1.24801,  1.7254,  2.18063,  2.49378,  2.5794,
+  1.1615,  1.34697,  1.80404,  2.15702,  2.55031,  2.63316,
+  1.28729,  1.66372,  2.04419,  2.32192,  2.59928,  2.68713,
+  1.4568,  1.75827,  2.05527,  2.31065,  2.54931,  2.66007,
+  1.41695,  1.74137,  2.10419,  2.35776,  2.59176,  2.67954,
+  1.37953,  1.75252,  2.17341,  2.36107,  2.6175,  2.69932,
+  1.361,  1.76202,  2.11571,  2.33066,  2.562,  2.65039,
+  1.34078,  1.68536,  2.02489,  2.28195,  2.54742,  2.63946,
+  1.27817,  1.68614,  1.96141,  2.16547,  2.55417,  2.64787,
+  1.29452,  1.54762,  1.98197,  2.18343,  2.54751,  2.63723,
+  1.20162,  1.34364,  2.00786,  2.08943,  2.53568,  2.66074,
+  1.202,  1.33211,  1.94915,  2.05181,  2.5532,  2.66547,
+  1.18035,  1.35425,  1.89052,  2.06991,  2.51523,  2.62012,
+  1.12873,  1.41976,  1.85478,  2.05663,  2.4807,  2.58354,
+  1.13319,  1.40234,  1.82266,  2.01361,  2.53991,  2.63944,
+  1.14927,  1.37693,  1.82119,  1.91493,  2.56242,  2.66404,
+  1.08087,  1.40844,  1.78802,  1.87993,  2.51751,  2.65668,
+  1.15244,  1.5096,  1.82234,  1.93981,  2.52894,  2.61915,
+  1.22726,  1.54378,  1.93541,  2.01768,  2.57551,  2.66563,
+  1.25365,  1.48594,  1.94554,  1.98737,  2.53919,  2.71509,
+  1.2245,  1.52134,  1.98216,  2.04494,  2.52268,  2.68745,
+  1.25872,  1.47612,  1.98186,  2.0731,  2.53617,  2.63409,
+  1.25558,  1.47113,  1.98394,  2.05256,  2.54104,  2.70865,
+  1.22142,  1.55673,  2.01332,  2.08977,  2.5386,  2.7065,
+  1.17848,  1.47465,  2.00764,  2.12209,  2.56026,  2.62943,
+  1.13664,  1.45929,  2.03373,  2.10043,  2.5447,  2.68913,
+  1.0352,  1.46256,  2.02497,  2.19409,  2.5306,  2.66221,
+  1.09088,  1.52242,  2.03844,  2.12942,  2.58762,  2.68739,
+  1.05454,  1.53834,  2.00059,  2.08401,  2.51651,  2.64433,
+  1.06957,  1.47115,  1.97701,  2.10266,  2.54822,  2.64566,
+  1.08464,  1.23507,  1.99903,  2.09101,  2.40519,  2.62241,
+  1.07391,  1.18049,  1.96138,  2.10188,  2.2553,  2.5318,
+  1.18554,  1.32028,  2.00675,  2.09885,  2.44308,  2.58297,
+  1.25681,  1.41999,  1.98353,  2.13096,  2.47042,  2.55869,
+  1.29074,  1.39192,  1.99538,  2.10656,  2.35166,  2.48517,
+  1.42857,  1.7483,  2.04481,  2.27757,  2.51309,  2.62525,
+  1.49577,  1.68666,  2.13566,  2.29223,  2.49901,  2.6165,
+  1.48246,  1.63201,  2.08388,  2.29724,  2.48855,  2.60533,
+  1.53884,  1.63087,  2.11175,  2.22311,  2.57684,  2.69324,
+  1.55163,  1.62855,  2.0406,  2.158,  2.59018,  2.71351,
+  1.57001,  1.63772,  1.9581,  2.12426,  2.57018,  2.69279,
+  1.53459,  1.60799,  1.80164,  2.08727,  2.3927,  2.60093,
+  1.50278,  1.60763,  1.8438,  2.08234,  2.32328,  2.52239,
+  1.5157,  1.61344,  1.83784,  2.02724,  2.40291,  2.60224,
+  1.51003,  1.60758,  1.82642,  1.95546,  2.34057,  2.67962,
+  1.44583,  1.56664,  1.75642,  1.86971,  2.29615,  2.60165,
+  1.41071,  1.48852,  1.82002,  1.91044,  2.35823,  2.61465,
+  1.30157,  1.42828,  1.81243,  1.90258,  2.29336,  2.72528,
+  1.10681,  1.35151,  1.88873,  1.95633,  2.32044,  2.64689,
+  1.05626,  1.36692,  1.86662,  1.96895,  2.42146,  2.65352,
+  1.14875,  1.36805,  1.80964,  2.06411,  2.43779,  2.6041,
+  0.99027,  1.45316,  1.88728,  2.03517,  2.29694,  2.6003,
+  0.943695,  1.20427,  1.748,  1.88645,  2.18161,  2.5098,
+  1.05705,  1.2214,  1.83597,  1.97244,  2.15495,  2.49297,
+  0.936404,  1.22552,  1.89505,  1.99806,  2.53953,  2.64493,
+  0.941516,  1.22449,  1.96641,  2.05527,  2.51509,  2.60908,
+  1.00024,  1.31497,  1.942,  2.05192,  2.53588,  2.63478,
+  1.03139,  1.4074,  1.95347,  2.04544,  2.55082,  2.63437,
+  1.11887,  1.44195,  1.95252,  2.062,  2.49434,  2.60804,
+  1.1971,  1.55316,  1.88765,  2.00919,  2.4721,  2.55066,
+  1.2938,  1.58834,  1.86838,  2.04592,  2.4811,  2.56611,
+  1.35377,  1.61065,  1.89762,  2.08348,  2.40829,  2.5434,
+  1.40368,  1.522,  1.89167,  2.05414,  2.35729,  2.51225,
+  1.3704,  1.44625,  1.87133,  1.99814,  2.33668,  2.57069,
+  1.49939,  1.75525,  2.09033,  2.28295,  2.48403,  2.57439,
+  1.56771,  1.84261,  2.13662,  2.27873,  2.47712,  2.57607,
+  1.59155,  1.76754,  2.16941,  2.30293,  2.52513,  2.6375,
+  1.45827,  1.79974,  2.22722,  2.3975,  2.61653,  2.70557,
+  1.49671,  1.84604,  2.2799,  2.43719,  2.64967,  2.72662,
+  1.50276,  1.73132,  2.26873,  2.46421,  2.62362,  2.70674,
+  1.4973,  1.61793,  2.15658,  2.38626,  2.57903,  2.66472,
+  1.37998,  1.53869,  1.85063,  2.10952,  2.41066,  2.58615,
+  1.40587,  1.49793,  1.7417,  1.93228,  2.33718,  2.56385,
+  1.34617,  1.43104,  1.65743,  1.88442,  2.37395,  2.58735,
+  1.30791,  1.40637,  1.73414,  1.87583,  2.46072,  2.60209,
+  1.27394,  1.57115,  1.77128,  1.91225,  2.53645,  2.59561,
+  1.20006,  1.57518,  1.77085,  1.87763,  2.50802,  2.57915,
+  1.12581,  1.53942,  1.72263,  1.85997,  2.51165,  2.57463,
+  1.0649,  1.48451,  1.69086,  1.83275,  2.51958,  2.58928,
+  1.04287,  1.48323,  1.62712,  1.86708,  2.49587,  2.55026,
+  0.95091,  1.47482,  1.57611,  1.83009,  2.51944,  2.56991,
+  1.00452,  1.42303,  1.55012,  1.83522,  2.4736,  2.54437,
+  1.02641,  1.36569,  1.51066,  1.87911,  2.46718,  2.54387,
+  0.978321,  1.33849,  1.52802,  1.91388,  2.46507,  2.52472,
+  0.922555,  1.40958,  1.52026,  1.93266,  2.40471,  2.47222,
+  1.00902,  1.34503,  1.51873,  1.99953,  2.46306,  2.54494,
+  0.989351,  1.43316,  1.57387,  2.01544,  2.4012,  2.49098,
+  1.03533,  1.55632,  1.67731,  2.08678,  2.48152,  2.56795,
+  1.00412,  1.57529,  1.79639,  2.07552,  2.40291,  2.57424,
+  1.03735,  1.68182,  1.94311,  2.06542,  2.47889,  2.5989,
+  1.00585,  1.68475,  1.97239,  2.10931,  2.56505,  2.62351,
+  0.954873,  1.71979,  2.00619,  2.11235,  2.59863,  2.68278,
+  0.937994,  1.72832,  1.99376,  2.10525,  2.63205,  2.70071,
+  0.889626,  1.70953,  2.00129,  2.09009,  2.62054,  2.7098,
+  0.912128,  1.65762,  1.96678,  2.05864,  2.62643,  2.70292,
+  0.972006,  1.56912,  1.98595,  2.13024,  2.56915,  2.67726,
+  1.03879,  1.65117,  2.00829,  2.11811,  2.59919,  2.70129,
+  1.1022,  1.62499,  1.99876,  2.12503,  2.56976,  2.64664,
+  1.18774,  1.63937,  2.05924,  2.1473,  2.47586,  2.63496,
+  1.2741,  1.59067,  2.01675,  2.09963,  2.54872,  2.66899,
+  1.3734,  1.63001,  1.98149,  2.07093,  2.50595,  2.68933,
+  1.51121,  1.60261,  1.91134,  2.0229,  2.47594,  2.64575,
+  1.55308,  1.6394,  1.8704,  1.97561,  2.47343,  2.62657,
+  1.63342,  1.77332,  1.87513,  1.95948,  2.41315,  2.62591,
+  1.59672,  1.74731,  1.87805,  2.04902,  2.58749,  2.66928,
+  1.66467,  1.93335,  2.15604,  2.28003,  2.46274,  2.57155,
+  1.55119,  1.6958,  2.0471,  2.23698,  2.44759,  2.57084,
+  1.6483,  1.72807,  2.06079,  2.27374,  2.47514,  2.6312,
+  1.63355,  1.75757,  2.08928,  2.24098,  2.43612,  2.55685,
+  1.60864,  1.68471,  2.12375,  2.25657,  2.4865,  2.59823,
+  1.65318,  1.71454,  2.10535,  2.20323,  2.50932,  2.64178,
+  1.54105,  1.67996,  2.10427,  2.24726,  2.54038,  2.62672,
+  1.55966,  1.65964,  2.10138,  2.21367,  2.47324,  2.563,
+  1.60881,  1.67178,  2.07143,  2.18483,  2.49328,  2.63946,
+  1.53888,  1.61019,  2.08308,  2.17154,  2.55439,  2.65099,
+  1.51102,  1.59546,  2.03164,  2.13009,  2.5876,  2.6604,
+  1.34069,  1.58784,  1.931,  2.11712,  2.59986,  2.67657,
+  1.48468,  1.53325,  2.02449,  2.11315,  2.54832,  2.65995,
+  1.53434,  1.60831,  2.03154,  2.136,  2.5371,  2.61772,
+  1.57158,  1.61831,  2.05673,  2.13975,  2.52541,  2.62221,
+  1.56447,  1.63127,  2.06059,  2.16604,  2.47,  2.63566,
+  1.53365,  1.66351,  2.09396,  2.19079,  2.40674,  2.62275,
+  1.57012,  1.63104,  2.04937,  2.16517,  2.39357,  2.5885,
+  1.55247,  1.63452,  2.00848,  2.09888,  2.5092,  2.66932,
+  1.49854,  1.60281,  2.00888,  2.09973,  2.52514,  2.65917,
+  1.45092,  1.66054,  1.99176,  2.1033,  2.54407,  2.69647,
+  1.4476,  1.5691,  1.99305,  2.07976,  2.58771,  2.67639,
+  1.39457,  1.5447,  2.00666,  2.07897,  2.57902,  2.72188,
+  1.34792,  1.50775,  1.99379,  2.07733,  2.51023,  2.68268,
+  1.26519,  1.35538,  1.87785,  2.06383,  2.4258,  2.6578,
+  1.2663,  1.37693,  2.00888,  2.27501,  2.47904,  2.63616,
+  1.41473,  1.68062,  2.0574,  2.33275,  2.54997,  2.65245,
+  1.49988,  1.70879,  2.05474,  2.31358,  2.52103,  2.61391,
+  1.44568,  1.74177,  2.12639,  2.33881,  2.49512,  2.59797,
+  1.4592,  1.79234,  2.11349,  2.34607,  2.5637,  2.66497,
+  1.41684,  1.64439,  2.13147,  2.32291,  2.5788,  2.67716,
+  1.44797,  1.70822,  2.14489,  2.27258,  2.59321,  2.70087,
+  1.47461,  1.74298,  2.06694,  2.34163,  2.60175,  2.68525,
+  1.34672,  1.65394,  1.99915,  2.21854,  2.63336,  2.7236,
+  1.37521,  1.55141,  2.05268,  2.23201,  2.58684,  2.69703,
+  1.26095,  1.50175,  1.9252,  2.03394,  2.54669,  2.65203,
+  1.25934,  1.50019,  1.90965,  1.98291,  2.54588,  2.63867,
+  1.25284,  1.56384,  1.91059,  1.97368,  2.57931,  2.66428,
+  1.263,  1.54633,  1.87808,  2.03115,  2.58347,  2.65379,
+  1.2652,  1.52127,  1.90571,  1.96739,  2.58143,  2.65872,
+  1.3077,  1.54772,  1.88142,  1.96204,  2.57347,  2.65883,
+  1.29134,  1.57501,  1.91524,  1.98556,  2.60208,  2.6977,
+  1.29543,  1.62646,  1.9233,  2.02372,  2.59129,  2.68014,
+  1.30121,  1.62408,  1.87893,  1.99808,  2.5601,  2.63451,
+  1.30581,  1.62092,  1.88803,  1.98904,  2.60623,  2.66943,
+  1.30809,  1.64233,  1.88596,  2.01357,  2.61191,  2.69665,
+  1.3121,  1.62786,  1.86184,  1.9741,  2.60262,  2.65849,
+  1.2929,  1.60573,  1.87713,  1.97339,  2.59964,  2.68284,
+  1.27314,  1.59174,  1.87042,  1.94745,  2.60233,  2.67415,
+  1.28358,  1.62082,  1.84727,  1.92803,  2.59005,  2.63688,
+  1.2462,  1.56007,  1.85162,  1.95453,  2.58753,  2.67354,
+  1.26039,  1.53964,  1.83162,  1.92843,  2.55229,  2.62963,
+  1.26122,  1.50523,  1.85731,  1.93391,  2.569,  2.69631,
+  1.28311,  1.71986,  1.8239,  1.97603,  2.56544,  2.62875,
+  1.31439,  1.61774,  1.80406,  1.96054,  2.59681,  2.68674,
+  1.3387,  1.63728,  1.89693,  2.00913,  2.52347,  2.63738,
+  1.33648,  1.57703,  1.85003,  1.94324,  2.52134,  2.59683,
+  1.39891,  1.54928,  1.72446,  1.86193,  2.16679,  2.46633,
+  1.40689,  1.49743,  1.80504,  1.90912,  2.28428,  2.54258,
+  1.47485,  1.57937,  1.97076,  2.0797,  2.37143,  2.54262,
+  1.45231,  1.5394,  2.07666,  2.138,  2.44297,  2.64951,
+  1.45062,  1.50661,  2.03639,  2.13145,  2.48483,  2.67472,
+  1.4348,  1.58308,  2.02767,  2.13681,  2.42911,  2.57834,
+  1.08757,  1.36721,  1.7863,  2.02503,  2.29808,  2.51567,
+  0.992092,  1.43643,  1.72551,  1.96511,  2.42572,  2.54902,
+  0.969474,  1.49732,  1.73009,  2.01605,  2.41437,  2.63332,
+  0.936277,  1.41301,  1.68361,  2.02977,  2.4431,  2.55283,
+  1.17635,  1.55964,  1.74877,  2.06189,  2.31148,  2.43469,
+  1.06711,  1.40664,  1.64389,  1.97881,  2.37473,  2.54784,
+  0.989262,  1.33311,  1.47509,  1.72865,  2.49202,  2.55347,
+  0.957471,  1.30854,  1.42456,  1.82347,  2.49022,  2.55232,
+  1.03577,  1.25449,  1.35208,  1.78625,  2.53949,  2.58578,
+  1.02368,  1.23242,  1.39848,  1.87577,  2.45168,  2.54025,
+  1.03725,  1.24729,  1.38742,  2.00855,  2.41927,  2.49611,
+  1.04592,  1.23169,  1.36195,  1.88761,  2.38445,  2.4715,
+  1.00098,  1.25084,  1.37666,  1.76767,  2.39805,  2.48444,
+  1.06177,  1.21461,  1.41076,  1.72825,  2.42398,  2.51427,
+  1.16823,  1.29119,  1.59751,  1.90001,  2.41542,  2.55501,
+  1.15079,  1.41286,  1.82595,  1.95326,  2.40005,  2.53532,
+  1.16692,  1.51763,  1.94353,  2.03425,  2.37336,  2.52147,
+  1.18318,  1.52316,  1.99531,  2.11989,  2.43346,  2.59116,
+  1.15948,  1.52173,  2.07237,  2.17696,  2.5149,  2.66076,
+  1.26032,  1.72266,  2.11677,  2.24905,  2.53412,  2.64563,
+  1.45043,  1.71771,  2.04879,  2.21275,  2.49949,  2.63613,
+  1.44923,  1.65312,  2.02364,  2.19689,  2.45305,  2.61252,
+  1.38812,  1.59757,  1.96865,  2.16345,  2.42543,  2.57803,
+  1.3476,  1.44981,  1.89414,  2.16897,  2.44647,  2.60227,
+  1.39801,  1.47176,  1.92206,  2.12096,  2.39643,  2.60072,
+  1.42866,  1.54131,  2.04605,  2.13251,  2.39709,  2.6431,
+  1.49267,  1.58516,  2.05934,  2.1583,  2.48082,  2.64875,
+  1.55899,  1.64879,  2.03751,  2.15332,  2.51238,  2.64766,
+  1.5875,  1.65909,  2.0205,  2.13969,  2.53746,  2.61656,
+  1.63435,  1.73936,  2.04449,  2.21819,  2.53013,  2.62274,
+  1.65015,  1.73677,  2.04927,  2.14892,  2.55187,  2.65129,
+  1.6407,  1.70735,  1.99133,  2.11956,  2.58759,  2.64283,
+  1.65582,  1.70975,  1.94195,  2.09079,  2.57008,  2.63037,
+  1.60644,  1.69562,  1.85276,  2.04784,  2.5549,  2.62809,
+  1.48459,  1.65703,  1.82298,  2.00896,  2.58403,  2.65372,
+  1.34838,  1.6278,  1.77907,  1.89733,  2.52187,  2.6464,
+  1.15564,  1.46487,  1.7638,  1.94355,  2.55585,  2.64209,
+  1.33945,  1.67633,  1.97104,  2.1868,  2.43889,  2.57107,
+  1.29738,  1.61553,  1.94676,  2.15118,  2.42984,  2.55813,
+  1.13646,  1.51989,  1.86723,  2.10739,  2.45273,  2.55371,
+  0.943433,  1.35098,  1.71433,  1.83088,  2.38004,  2.57361,
+  0.93395,  1.07858,  1.55309,  1.66234,  2.02795,  2.45315,
+  0.896937,  1.24693,  1.58663,  1.68408,  2.39714,  2.61171,
+  0.892078,  1.35006,  1.56008,  1.68985,  2.50628,  2.60756,
+  0.772181,  1.31368,  1.52566,  1.65028,  2.46898,  2.63641,
+  0.863603,  1.32858,  1.48114,  1.76889,  2.49678,  2.54657,
+  0.908312,  1.25841,  1.38277,  1.69975,  2.44859,  2.54733,
+  0.863083,  1.2738,  1.42241,  1.57588,  2.50992,  2.5671,
+  0.798143,  1.23338,  1.32805,  1.71855,  2.54548,  2.65489,
+  0.937997,  1.29721,  1.44739,  1.65945,  2.53943,  2.66437,
+  1.01531,  1.28265,  1.44965,  1.65693,  2.51959,  2.59724,
+  1.0126,  1.30809,  1.42876,  1.74264,  2.58138,  2.65475,
+  1.07522,  1.35994,  1.46636,  1.79046,  2.58293,  2.65492,
+  1.17472,  1.35459,  1.47068,  1.80811,  2.61181,  2.6906,
+  1.30467,  1.38057,  1.48642,  1.86325,  2.49909,  2.64664,
+  1.32925,  1.45894,  1.59974,  1.9851,  2.41224,  2.4896,
+  1.32685,  1.46696,  1.65071,  1.97288,  2.17365,  2.36378,
+  1.44073,  1.59786,  1.75692,  1.94212,  2.13442,  2.3309,
+  1.49091,  1.61528,  1.79973,  1.98918,  2.30719,  2.53596,
+  1.523,  1.67644,  1.84139,  2.08449,  2.49007,  2.6195,
+  1.53645,  1.67293,  1.83434,  2.06794,  2.59485,  2.65573,
+  1.58521,  1.67342,  1.87935,  2.02614,  2.60916,  2.69133,
+  1.57645,  1.66211,  1.86811,  1.98727,  2.62983,  2.70249,
+  1.56114,  1.62908,  1.91041,  2.00543,  2.63344,  2.72614,
+  1.53121,  1.61555,  1.87364,  1.96628,  2.52259,  2.70606,
+  1.47329,  1.59122,  1.90894,  1.97341,  2.53504,  2.73312,
+  1.41254,  1.47364,  1.87172,  1.95732,  2.3412,  2.7407,
+  1.37981,  1.47324,  1.92392,  1.98607,  2.44717,  2.65758,
+  1.33369,  1.50012,  1.93353,  2.13803,  2.5018,  2.61583,
+  1.40577,  1.57009,  2.02811,  2.33267,  2.57368,  2.66412,
+  1.38605,  1.54675,  2.10184,  2.38012,  2.6073,  2.71246,
+  1.42055,  1.66408,  2.09684,  2.28767,  2.54543,  2.64567,
+  1.42992,  1.63289,  2.05645,  2.24534,  2.46973,  2.59462,
+  1.45034,  1.54233,  1.93614,  2.16009,  2.38966,  2.59495,
+  1.45865,  1.54584,  1.97395,  2.13284,  2.28055,  2.51911,
+  1.49962,  1.62185,  1.92436,  2.08658,  2.25382,  2.39346,
+  1.48012,  1.59661,  1.8229,  2.03008,  2.21246,  2.44059,
+  1.38557,  1.51579,  1.76353,  2.00756,  2.20701,  2.50516,
+  1.36348,  1.48371,  1.74539,  2.02083,  2.17738,  2.42842,
+  1.42241,  1.52636,  1.80247,  2.04137,  2.26763,  2.50998,
+  1.45178,  1.5395,  1.88862,  2.07975,  2.25853,  2.50082,
+  1.46274,  1.54888,  1.92575,  2.06529,  2.3201,  2.59188,
+  1.45961,  1.52679,  1.9373,  2.02975,  2.426,  2.61822,
+  1.42677,  1.49596,  1.9348,  2.02868,  2.47432,  2.63994,
+  1.39548,  1.4946,  1.92354,  2.00687,  2.5088,  2.6516,
+  1.31532,  1.47588,  1.92587,  2.01244,  2.56254,  2.64267,
+  1.21621,  1.54231,  1.86761,  1.96291,  2.57851,  2.63891,
+  1.18812,  1.59211,  1.82616,  1.95676,  2.59273,  2.65931,
+  1.15728,  1.51903,  1.84128,  1.93613,  2.59672,  2.66939,
+  1.04273,  1.33486,  1.85281,  1.92781,  2.50926,  2.72139,
+  1.07692,  1.51273,  1.89221,  1.97602,  2.37074,  2.63564,
+  1.32864,  1.55521,  1.82696,  2.08002,  2.44793,  2.60775,
+  1.27122,  1.38353,  1.74055,  2.04872,  2.35626,  2.56711,
+  1.28876,  1.38548,  1.79387,  1.97785,  2.3904,  2.60455,
+  1.32866,  1.42224,  1.80564,  2.00282,  2.28916,  2.5443,
+  1.37794,  1.49365,  1.79368,  2.03187,  2.35373,  2.51891,
+  1.38443,  1.45365,  1.83807,  2.00184,  2.39078,  2.63512,
+  1.28946,  1.40343,  1.87102,  1.98612,  2.47998,  2.7238,
+  1.20789,  1.38822,  1.86505,  2.03166,  2.45007,  2.59141,
+  1.21863,  1.30931,  1.90985,  2.00378,  2.49942,  2.60498,
+  1.17883,  1.2733,  1.83281,  2.02504,  2.50863,  2.65023,
+  1.14748,  1.25919,  1.93016,  2.02773,  2.52207,  2.63407,
+  1.10091,  1.26803,  1.85791,  1.9519,  2.50889,  2.66039,
+  1.06983,  1.22567,  1.88895,  1.97434,  2.49213,  2.5921,
+  1.04226,  1.18221,  1.89174,  2.03996,  2.55965,  2.67933,
+  0.956414,  1.18097,  1.88146,  1.99433,  2.31647,  2.61769,
+  1.06179,  1.5717,  1.92657,  2.10718,  2.40416,  2.52545,
+  1.37431,  1.4759,  1.67843,  1.97242,  2.36429,  2.51653,
+  1.36344,  1.45577,  1.76316,  1.9708,  2.36833,  2.58698,
+  1.42304,  1.59189,  1.7982,  2.01278,  2.38811,  2.60218,
+  1.52726,  1.60578,  1.90951,  2.03343,  2.40668,  2.59346,
+  1.58513,  1.66451,  1.91801,  2.02654,  2.42573,  2.60092,
+  1.61189,  1.72856,  1.90767,  2.03404,  2.39568,  2.64177,
+  1.46301,  1.62466,  1.87229,  1.99824,  2.48782,  2.66247,
+  1.50707,  1.59791,  1.89375,  1.99701,  2.53598,  2.67246,
+  1.5024,  1.61803,  1.88856,  2.02416,  2.58185,  2.65654,
+  1.55312,  1.63948,  1.91892,  2.03428,  2.57686,  2.65568,
+  1.57736,  1.64826,  1.95809,  2.05341,  2.56789,  2.65652,
+  1.59537,  1.65463,  1.99777,  2.09975,  2.53164,  2.67521,
+  1.62164,  1.70401,  1.95775,  2.07464,  2.58431,  2.66051,
+  1.61843,  1.71139,  1.95479,  2.06745,  2.53377,  2.69523,
+  1.61785,  1.71631,  1.94968,  2.10336,  2.63594,  2.68689,
+  1.64932,  1.74631,  1.90161,  2.06435,  2.60677,  2.69024,
+  1.63506,  1.7696,  1.90462,  2.0191,  2.6076,  2.71333,
+  1.64557,  1.7795,  1.86895,  1.96533,  2.59215,  2.7149,
+  1.68657,  1.7575,  1.85807,  1.92204,  2.50527,  2.69889,
+  1.61272,  1.70323,  1.83105,  1.9259,  2.37381,  2.61368,
+  1.24435,  1.40956,  1.71346,  1.9677,  2.35146,  2.53736,
+  1.26999,  1.3873,  1.64097,  1.99183,  2.32491,  2.50177,
+  1.30535,  1.45577,  1.78878,  2.09123,  2.48724,  2.61473,
+  1.41386,  1.51881,  1.88852,  2.25227,  2.44809,  2.59472,
+  1.40942,  1.59146,  1.94472,  2.19692,  2.51839,  2.63823,
+  1.39914,  1.70331,  1.96615,  2.22486,  2.61691,  2.73408,
+  1.37531,  1.63638,  2.06176,  2.29242,  2.58662,  2.70574,
+  1.39467,  1.73342,  2.0736,  2.29715,  2.57382,  2.67289,
+  1.36608,  1.73861,  2.01663,  2.28566,  2.60549,  2.69352,
+  1.36062,  1.60169,  1.96797,  2.19484,  2.56485,  2.65792,
+  1.3547,  1.47154,  1.99017,  2.16544,  2.569,  2.67912,
+  1.31937,  1.40392,  2.03022,  2.11501,  2.4527,  2.63591,
+  1.30326,  1.37473,  1.97504,  2.11117,  2.36982,  2.66061,
+  1.32579,  1.43105,  2.03617,  2.11394,  2.476,  2.68507,
+  1.30748,  1.51036,  2.1177,  2.17917,  2.55458,  2.69578,
+  1.31143,  1.54831,  2.12835,  2.27973,  2.5517,  2.6455,
+  1.29377,  1.44223,  2.11556,  2.28956,  2.4159,  2.53121,
+  1.27867,  1.69711,  2.0925,  2.19954,  2.36852,  2.56114,
+  1.29264,  1.86793,  2.12883,  2.20633,  2.45084,  2.55178,
+  1.23486,  1.63107,  2.1437,  2.30446,  2.49101,  2.56573,
+  1.21995,  1.36757,  2.1498,  2.21849,  2.49521,  2.6353,
+  1.2089,  1.48484,  2.1803,  2.27669,  2.52633,  2.62673,
+  1.16526,  1.45824,  2.15559,  2.22728,  2.49018,  2.5968,
+  1.11619,  1.49218,  2.17727,  2.2419,  2.53233,  2.62053,
+  1.0969,  1.52492,  2.09349,  2.34525,  2.48036,  2.61116,
+  1.04378,  1.36903,  2.22928,  2.30665,  2.52743,  2.61303,
+  1.08072,  1.33613,  2.13554,  2.24061,  2.46344,  2.63428,
+  1.12626,  1.50254,  2.06533,  2.27483,  2.51283,  2.58825,
+  1.19913,  1.448,  2.04058,  2.21686,  2.44913,  2.5443,
+  1.2443,  1.54083,  2.03653,  2.17483,  2.47027,  2.58034,
+  1.27719,  1.57406,  2.06637,  2.15037,  2.50854,  2.61173,
+  1.34175,  1.57688,  2.03148,  2.12065,  2.49616,  2.57534,
+  1.33544,  1.5416,  1.99434,  2.1088,  2.51884,  2.62295,
+  1.35172,  1.54371,  2.00331,  2.07535,  2.57916,  2.65663,
+  1.3593,  1.47053,  1.96846,  2.04232,  2.56515,  2.66484,
+  1.3682,  1.43322,  1.98377,  2.04495,  2.4386,  2.6706,
+  1.35118,  1.42613,  1.99129,  2.08773,  2.43075,  2.61637,
+  1.34987,  1.4833,  2.00027,  2.24283,  2.53591,  2.62905,
+  1.32206,  1.59678,  2.11312,  2.40815,  2.54898,  2.62526,
+  1.38129,  1.64876,  2.19246,  2.37836,  2.57952,  2.6545,
+  1.37213,  1.54266,  2.06255,  2.30731,  2.47559,  2.58062,
+  1.36357,  1.46348,  1.86476,  2.28846,  2.4678,  2.57169,
+  1.33579,  1.5363,  1.88616,  2.22187,  2.54338,  2.67053,
+  1.25976,  1.39335,  1.60476,  1.93429,  2.43051,  2.5096,
+  1.22472,  1.34965,  1.48194,  1.83683,  2.38496,  2.46313,
+  1.25366,  1.36921,  1.50551,  1.99434,  2.36606,  2.45456,
+  1.25045,  1.37222,  1.56344,  2.13328,  2.39153,  2.46111,
+  1.29898,  1.41253,  1.56,  2.16285,  2.47558,  2.55147,
+  1.3087,  1.48723,  1.61657,  2.14089,  2.42252,  2.52784,
+  1.36226,  1.50974,  1.69114,  2.15185,  2.42506,  2.50401,
+  1.41519,  1.57382,  1.72634,  2.14569,  2.42361,  2.51895,
+  1.4683,  1.62457,  1.768,  2.10708,  2.43369,  2.50188,
+  1.47421,  1.64517,  1.82938,  2.15047,  2.33054,  2.45413,
+  1.48873,  1.66222,  1.85318,  2.16043,  2.39072,  2.50747,
+  1.51537,  1.6851,  1.8209,  2.09082,  2.47713,  2.54132,
+  1.53394,  1.68102,  1.91115,  2.10105,  2.43121,  2.50742,
+  1.54702,  1.76275,  1.90532,  2.0573,  2.36997,  2.49646,
+  1.52475,  1.7075,  1.88085,  2.14514,  2.33129,  2.4433,
+  1.53267,  1.68946,  1.83844,  2.06671,  2.35207,  2.48759,
+  1.44908,  1.63991,  1.78652,  2.04704,  2.32879,  2.42622,
+  1.39341,  1.607,  1.75213,  2.06596,  2.381,  2.47377,
+  1.23492,  1.62038,  1.75171,  2.07935,  2.40097,  2.47182,
+  1.12865,  1.58919,  1.72598,  2.09781,  2.42178,  2.50718,
+  1.20512,  1.49111,  1.70703,  2.14313,  2.40768,  2.4896,
+  1.10599,  1.52409,  1.74026,  2.14252,  2.42276,  2.53271,
+  1.14687,  1.42809,  1.69879,  2.10033,  2.42333,  2.5455,
+  1.11601,  1.3519,  1.75431,  2.14602,  2.4117,  2.52754,
+  1.17851,  1.30684,  1.82411,  2.27204,  2.45289,  2.54631,
+  1.38605,  1.68653,  2.01082,  2.14869,  2.4392,  2.57093,
+  1.33438,  1.67405,  1.96249,  2.10873,  2.40392,  2.5875,
+  1.30954,  1.51943,  2.0306,  2.11973,  2.43608,  2.6208,
+  1.19962,  1.42519,  2.03789,  2.16133,  2.49331,  2.63953,
+  0.913804,  1.25173,  2.05508,  2.17687,  2.41685,  2.64493,
+  0.822137,  1.06733,  2.01912,  2.21659,  2.39556,  2.65819,
+  0.859923,  0.985874,  1.90428,  2.16059,  2.43371,  2.63982,
+  0.906761,  1.14062,  2.0105,  2.14624,  2.46964,  2.64413,
+  0.950845,  1.25396,  2.03953,  2.0959,  2.60028,  2.71109,
+  0.953879,  1.24532,  1.98547,  2.13315,  2.54365,  2.613,
+  1.03167,  1.28659,  1.97462,  2.03713,  2.54102,  2.69028,
+  1.0516,  1.37316,  1.90525,  2.00964,  2.49555,  2.67405,
+  1.08826,  1.2974,  1.89869,  2.01858,  2.50884,  2.69051,
+  1.1467,  1.28227,  1.93071,  2.01015,  2.43941,  2.64701,
+  1.1572,  1.34385,  1.93082,  2.02912,  2.36815,  2.598,
+  1.24735,  1.43274,  1.94259,  2.06745,  2.39283,  2.5543,
+  1.29762,  1.51602,  1.99339,  2.07927,  2.43946,  2.54827,
+  1.38625,  1.4836,  1.96585,  2.07161,  2.44479,  2.59437,
+  1.42969,  1.49987,  1.88063,  2.07411,  2.3462,  2.60425,
+  1.56913,  1.64448,  1.94276,  2.0452,  2.37069,  2.58937,
+  1.69636,  1.74562,  1.98094,  2.09366,  2.43348,  2.58367,
+  1.69484,  1.80115,  1.96103,  2.06832,  2.45264,  2.63829,
+  1.61979,  1.78559,  1.91963,  2.05582,  2.23816,  2.49876,
+  1.22369,  1.62122,  1.79172,  1.89869,  2.16167,  2.49995,
+  1.14441,  1.45291,  1.78089,  1.86674,  2.21421,  2.49427,
+  1.13554,  1.49512,  1.82078,  1.89436,  2.11501,  2.44158,
+  1.13138,  1.53582,  1.73732,  1.84242,  2.02164,  2.42595,
+  1.21265,  1.31217,  1.75291,  1.88932,  2.10891,  2.4697,
+  1.25395,  1.35241,  1.65265,  1.96095,  2.39444,  2.56868,
+  1.36268,  1.58079,  1.91332,  2.21262,  2.3816,  2.52899,
+  1.41733,  1.58205,  1.97763,  2.23799,  2.41308,  2.58029,
+  1.38316,  1.60355,  2.01614,  2.21013,  2.44905,  2.58723,
+  1.44211,  1.54421,  1.93895,  2.14188,  2.495,  2.59016,
+  1.38173,  1.57916,  1.982,  2.13878,  2.48578,  2.62057,
+  1.36159,  1.59781,  1.96493,  2.13812,  2.54261,  2.62247,
+  1.36066,  1.61469,  2.01078,  2.1615,  2.46045,  2.5839,
+  1.39009,  1.62865,  1.96383,  2.13056,  2.47773,  2.61338,
+  1.34617,  1.6485,  2.08237,  2.32171,  2.55595,  2.64942,
+  1.44042,  1.74244,  2.00765,  2.20824,  2.45099,  2.57791,
+  1.44483,  1.69506,  2.02687,  2.21048,  2.41403,  2.53277,
+  1.34554,  1.58917,  1.95542,  2.12931,  2.40989,  2.54316,
+  1.40004,  1.48192,  1.94707,  2.11026,  2.31316,  2.53117,
+  1.38478,  1.48479,  1.98387,  2.10714,  2.36009,  2.58548,
+  1.42919,  1.51494,  2.01966,  2.13766,  2.32955,  2.58529,
+  1.45055,  1.51832,  2.01003,  2.1028,  2.40169,  2.60328,
+  1.44136,  1.52541,  1.96497,  2.07672,  2.37601,  2.59481,
+  1.46479,  1.52155,  1.96899,  2.07787,  2.44496,  2.62108,
+  1.4867,  1.57368,  2.00184,  2.10852,  2.43377,  2.62616,
+  1.47103,  1.5436,  1.99166,  2.11171,  2.47331,  2.64546,
+  1.41527,  1.52449,  2.0127,  2.09575,  2.45882,  2.64202,
+  1.40751,  1.50149,  2.05031,  2.1562,  2.48019,  2.62327,
+  1.37612,  1.45958,  2.00994,  2.16941,  2.4802,  2.64269,
+  1.34595,  1.47288,  2.07312,  2.18486,  2.48613,  2.61036,
+  1.30637,  1.43838,  2.0905,  2.21314,  2.5542,  2.68395,
+  1.21926,  1.42304,  2.09092,  2.17049,  2.55962,  2.66821,
+  1.18047,  1.40808,  1.93517,  2.08818,  2.54813,  2.63944,
+  1.20954,  1.52893,  1.88727,  1.96188,  2.48344,  2.64934,
+  1.21992,  1.52138,  1.93918,  1.98802,  2.46003,  2.67348,
+  1.19875,  1.4741,  1.85911,  1.98104,  2.39535,  2.7192,
+  1.11841,  1.50485,  1.89794,  2.00238,  2.24287,  2.59852,
+  1.01853,  1.45989,  1.74659,  2.05195,  2.32486,  2.45885,
+  0.86699,  1.38778,  1.6541,  1.79974,  2.32579,  2.40738,
+  0.862252,  1.36583,  1.70576,  1.80225,  2.41635,  2.49385,
+  0.928394,  1.54645,  1.71668,  1.87707,  2.37972,  2.52459,
+  1.08335,  1.48734,  1.80115,  2.00569,  2.32174,  2.55873,
+  1.05743,  1.3398,  1.83442,  1.9346,  2.27962,  2.5307,
+  0.954787,  1.141,  1.79287,  1.8918,  2.34291,  2.49204,
+  0.996853,  1.13004,  1.79215,  1.89541,  2.23624,  2.40335,
+  0.920268,  1.06949,  1.87486,  2.07209,  2.33523,  2.48657,
+  0.954214,  1.08107,  1.82732,  2.07915,  2.23882,  2.50812,
+  0.894487,  1.01384,  1.71654,  2.01845,  2.17535,  2.48224,
+  0.842005,  0.979634,  1.64453,  1.9459,  2.27102,  2.43863,
+  0.95571,  1.09,  1.75405,  1.96707,  2.12784,  2.44888,
+  0.954385,  1.09447,  1.72755,  2.00558,  2.26657,  2.5144,
+  1.02562,  1.1376,  1.78753,  2.00208,  2.3369,  2.51184,
+  1.01381,  1.1751,  1.88194,  2.01664,  2.34586,  2.44572,
+  1.08267,  1.2273,  1.92324,  2.02278,  2.40238,  2.52097,
+  1.11811,  1.22414,  1.82445,  1.96175,  2.24583,  2.51583,
+  1.14645,  1.29899,  1.87293,  1.99547,  2.37173,  2.5269,
+  1.18855,  1.31065,  1.90221,  1.99678,  2.29037,  2.52054,
+  1.30992,  1.41653,  1.87845,  2.05009,  2.22418,  2.38779,
+  1.39476,  1.50627,  1.93489,  2.05682,  2.27119,  2.45334,
+  1.37793,  1.57264,  1.9907,  2.08357,  2.38159,  2.60652,
+  1.44402,  1.6893,  1.99746,  2.15321,  2.36113,  2.5077,
+  1.51504,  1.64277,  1.92909,  2.15934,  2.33551,  2.49784,
+  1.54008,  1.70831,  1.88382,  2.09498,  2.39862,  2.5701,
+  1.60091,  1.69851,  1.88148,  2.08517,  2.45101,  2.65374,
+  1.50263,  1.75606,  2.04072,  2.1634,  2.37617,  2.54867,
+  1.53211,  1.85534,  1.99384,  2.13955,  2.30249,  2.43099,
+  1.48486,  1.82205,  1.9643,  2.13596,  2.33702,  2.47234,
+  1.53669,  1.76692,  1.95125,  2.09052,  2.32417,  2.52921,
+  1.58228,  1.72385,  1.91207,  2.06937,  2.30294,  2.4739,
+  1.49971,  1.59329,  1.9127,  2.0341,  2.36655,  2.55379,
+  1.4342,  1.54071,  1.86757,  1.98917,  2.32371,  2.5394,
+  1.1891,  1.50082,  1.76342,  1.9762,  2.13728,  2.44118,
+  1.16592,  1.47018,  1.773,  1.9271,  2.08801,  2.3043,
+  1.25015,  1.60042,  1.81807,  1.92211,  2.08025,  2.24181,
+  1.12269,  1.6288,  1.81441,  1.93295,  2.0993,  2.41867,
+  1.01962,  1.51066,  1.85073,  1.99562,  2.1302,  2.45706,
+  0.958176,  1.63968,  1.84043,  1.95653,  2.10428,  2.27903,
+  1.01054,  1.53751,  1.77222,  1.93052,  2.10162,  2.24851,
+  0.904371,  1.50502,  1.66433,  1.82788,  2.27803,  2.34842,
+  1.06773,  1.45454,  1.68686,  1.80346,  2.38437,  2.49979,
+  1.26287,  1.516,  1.88275,  1.97556,  2.35357,  2.51973,
+  1.56064,  1.69896,  1.92154,  2.00006,  2.54029,  2.60523,
+  1.66562,  1.74409,  1.99592,  2.104,  2.53894,  2.62016,
+  1.61517,  1.7485,  2.02411,  2.12606,  2.40816,  2.61413,
+  1.67803,  1.75295,  2.0279,  2.14656,  2.38237,  2.56851,
+  1.58035,  1.68027,  1.99741,  2.12246,  2.45985,  2.58783,
+  1.59008,  1.69205,  1.93478,  2.09576,  2.55298,  2.62588,
+  1.539,  1.62024,  1.92077,  2.0316,  2.48167,  2.59269,
+  1.4088,  1.51179,  1.74425,  1.89659,  2.41202,  2.51558,
+  1.32056,  1.48799,  1.75496,  1.89691,  2.43716,  2.56318,
+  1.17487,  1.52485,  1.70818,  1.96295,  2.51378,  2.58101,
+  1.28764,  1.55957,  1.90308,  2.10518,  2.45098,  2.59946,
+  1.22403,  1.508,  1.92279,  2.07637,  2.37291,  2.58121,
+  1.16322,  1.44496,  1.73467,  2.02018,  2.32215,  2.54157,
+  1.21226,  1.448,  1.63849,  2.03192,  2.22935,  2.39947,
+  1.10889,  1.28333,  1.48115,  1.90707,  2.10001,  2.29348,
+  1.15522,  1.29037,  1.47672,  1.68807,  2.08922,  2.18177,
+  1.17147,  1.29039,  1.55651,  1.82599,  2.01814,  2.24349,
+  1.14989,  1.28265,  1.6019,  1.7453,  2.11078,  2.40906,
+  1.22391,  1.36072,  1.65007,  1.79294,  2.2651,  2.37093,
+  1.25437,  1.40454,  1.70667,  1.85465,  2.27647,  2.39469,
+  1.22583,  1.44211,  1.76613,  1.92412,  2.2924,  2.39468,
+  1.21114,  1.46189,  1.80455,  1.92702,  2.36199,  2.45328,
+  1.21864,  1.40578,  1.80953,  1.9142,  2.31845,  2.52005,
+  1.22294,  1.39467,  1.84011,  1.9324,  2.39167,  2.50319,
+  1.2069,  1.37287,  1.84295,  1.9438,  2.42446,  2.57876,
+  1.24631,  1.42383,  1.86621,  1.96241,  2.43605,  2.59566,
+  1.27092,  1.4559,  1.88805,  1.97634,  2.46928,  2.58281,
+  1.19826,  1.32394,  1.88024,  1.94941,  2.47166,  2.6448,
+  1.17432,  1.2932,  1.76561,  2.01928,  2.28224,  2.57624,
+  1.14173,  1.38319,  1.88283,  2.12653,  2.45304,  2.61119,
+  1.48334,  1.65073,  2.04359,  2.1938,  2.51727,  2.62292,
+  1.44607,  1.6219,  1.99961,  2.10353,  2.49348,  2.58192,
+  1.41467,  1.63024,  1.94568,  2.06177,  2.50065,  2.58895,
+  1.43843,  1.61559,  1.90335,  2.01303,  2.42611,  2.61364,
+  1.55667,  1.62312,  1.87546,  1.97231,  2.36669,  2.62922,
+  1.4665,  1.63832,  1.79658,  1.95927,  2.45762,  2.60323,
+  1.30828,  1.48139,  1.73054,  1.97927,  2.33226,  2.53809,
+  1.30165,  1.41374,  1.67444,  1.93338,  2.14349,  2.50814,
+  1.31891,  1.41656,  1.75164,  1.91344,  2.29409,  2.55512,
+  1.32451,  1.42562,  1.84492,  1.94741,  2.37538,  2.59737,
+  1.267,  1.35973,  1.84915,  1.95084,  2.37072,  2.5793,
+  1.1627,  1.34431,  1.90693,  1.98657,  2.47058,  2.58342,
+  1.116,  1.36583,  1.94803,  2.04008,  2.46113,  2.5836,
+  1.0618,  1.35029,  2.00628,  2.08046,  2.45163,  2.52696,
+  1.02433,  1.23357,  1.98941,  2.08505,  2.38718,  2.49582,
+  0.962287,  1.21924,  1.967,  2.08919,  2.42466,  2.59986,
+  0.881533,  1.35683,  2.04743,  2.15539,  2.40907,  2.50875,
+  0.85601,  1.21772,  2.00853,  2.11153,  2.42481,  2.53774,
+  0.774065,  0.965055,  1.87414,  2.03588,  2.25102,  2.52797,
+  0.820344,  0.990331,  1.96096,  2.24212,  2.34955,  2.53547,
+  0.846158,  1.06289,  1.97251,  2.16915,  2.35316,  2.55609,
+  0.748812,  1.06344,  1.94995,  2.06685,  2.36451,  2.602,
+  0.855725,  1.15838,  2.00842,  2.14414,  2.3285,  2.60048,
+  0.862076,  1.18823,  1.90646,  2.19135,  2.36851,  2.54264,
+  0.814218,  1.19401,  2.0864,  2.15686,  2.48295,  2.57478,
+  0.811087,  1.32095,  2.03826,  2.11283,  2.50888,  2.59894,
+  0.967874,  1.19172,  2.04932,  2.14652,  2.42267,  2.56678,
+  1.00803,  1.2342,  2.04091,  2.12104,  2.48015,  2.60909,
+  1.11818,  1.31227,  1.96142,  2.07124,  2.40932,  2.60053,
+  1.18934,  1.30243,  1.96196,  2.06321,  2.43212,  2.5453,
+  1.25389,  1.37123,  1.93188,  2.03014,  2.38756,  2.55895,
+  1.3073,  1.39804,  1.91099,  2.00694,  2.40944,  2.57714,
+  1.33009,  1.46846,  1.90852,  2.01222,  2.41802,  2.53768,
+  1.36799,  1.49229,  1.94202,  2.03675,  2.49887,  2.581,
+  1.36837,  1.44343,  1.94748,  2.01318,  2.48634,  2.58524,
+  1.41828,  1.49685,  1.93344,  2.02463,  2.47368,  2.59404,
+  1.44389,  1.55122,  1.90491,  2.0181,  2.45672,  2.54287,
+  1.47369,  1.5871,  1.89983,  2.07901,  2.4215,  2.58448,
+  1.42467,  1.61133,  1.97452,  2.14272,  2.40288,  2.62076,
+  1.43149,  1.62266,  1.94023,  2.12544,  2.42965,  2.58185,
+  1.48454,  1.69058,  1.92186,  2.1091,  2.4744,  2.60783,
+  1.49814,  1.75158,  1.92573,  2.03913,  2.44052,  2.61618,
+  1.50525,  1.78918,  1.99467,  2.11413,  2.40842,  2.59989,
+  1.60987,  1.79304,  1.98623,  2.1606,  2.51957,  2.59325,
+  1.56282,  1.73991,  1.97418,  2.14322,  2.53959,  2.62009,
+  1.65026,  1.72396,  2.00295,  2.1504,  2.5321,  2.60075,
+  1.58463,  1.66548,  1.83385,  1.97966,  2.51117,  2.57618,
+  1.54756,  1.66563,  1.80511,  1.93045,  2.42867,  2.54861,
+  1.49908,  1.59512,  1.70027,  1.82419,  2.37692,  2.57548,
+  1.30084,  1.55295,  1.66458,  1.79171,  2.4883,  2.56108,
+  1.1686,  1.31195,  1.66858,  1.87291,  2.41357,  2.49328,
+  1.04746,  1.24996,  1.69989,  1.91418,  2.41703,  2.49638,
+  0.948776,  1.27559,  1.73894,  1.99868,  2.31215,  2.46202,
+  0.921081,  1.31195,  1.77524,  1.89549,  2.38216,  2.52844,
+  0.811311,  1.12522,  1.74519,  2.09474,  2.32611,  2.51188,
+  0.796518,  1.06023,  1.74013,  2.0605,  2.17951,  2.3855,
+  0.868836,  1.15335,  1.79283,  1.94564,  2.1255,  2.248,
+  0.915536,  1.21816,  1.81891,  2.06835,  2.2434,  2.34865,
+  0.966595,  1.30161,  1.89525,  2.11196,  2.24865,  2.38925,
+  0.995849,  1.44208,  1.95207,  2.06612,  2.24012,  2.33859,
+  1.05639,  1.37221,  1.98417,  2.11933,  2.2717,  2.37274,
+  1.0984,  1.32416,  1.78153,  2.08286,  2.2188,  2.34432,
+  1.03916,  1.35647,  1.82018,  2.11462,  2.34673,  2.45039,
+  0.988689,  1.29388,  1.91635,  2.0882,  2.3625,  2.48127,
+  1.10441,  1.23068,  1.93943,  2.1224,  2.25481,  2.37771,
+  1.0861,  1.17448,  1.82635,  2.11132,  2.23769,  2.47167,
+  1.0698,  1.20649,  1.84538,  2.11863,  2.47109,  2.5754,
+  1.07496,  1.34279,  1.95531,  2.14771,  2.51147,  2.58927,
+  1.1492,  1.41881,  1.88704,  1.96697,  2.47262,  2.58725,
+  1.45575,  1.66983,  1.9641,  2.17518,  2.46999,  2.60501,
+  1.41855,  1.60357,  1.96443,  2.17568,  2.46676,  2.58333,
+  1.38939,  1.60116,  1.92575,  2.13186,  2.44202,  2.57423,
+  1.41533,  1.50734,  1.91126,  2.08714,  2.5352,  2.62958,
+  1.38248,  1.45371,  1.87229,  1.95541,  2.55434,  2.65851,
+  1.39294,  1.4823,  1.83853,  1.92858,  2.47373,  2.63372,
+  1.39046,  1.46304,  1.83991,  1.92201,  2.51494,  2.69879,
+  1.33938,  1.47012,  1.85875,  1.95952,  2.53943,  2.68638,
+  1.35378,  1.54103,  1.82255,  2.02216,  2.54222,  2.6772,
+  1.35087,  1.63188,  1.91879,  2.18353,  2.50109,  2.61731,
+  1.40764,  1.66913,  2.00074,  2.22423,  2.5228,  2.6349,
+  1.43378,  1.58691,  1.99963,  2.19292,  2.53598,  2.62612,
+  1.41388,  1.63943,  1.9522,  2.1707,  2.50111,  2.61059,
+  1.50539,  1.61369,  1.99159,  2.21446,  2.48787,  2.61284,
+  1.40925,  1.56369,  2.04804,  2.15415,  2.48373,  2.64218,
+  1.41102,  1.6467,  1.98318,  2.15255,  2.56881,  2.66125,
+  1.38475,  1.60381,  1.93449,  2.14195,  2.50764,  2.63005,
+  1.36612,  1.55134,  1.99956,  2.17747,  2.48911,  2.59676,
+  1.35554,  1.63502,  2.00842,  2.16267,  2.46527,  2.66141,
+  1.45397,  1.6737,  2.03786,  2.1802,  2.61597,  2.70928,
+  1.36954,  1.69647,  1.99979,  2.08485,  2.48277,  2.66629,
+  1.34974,  1.46231,  1.96672,  2.05172,  2.47262,  2.65262,
+  1.32731,  1.43776,  1.92852,  2.00639,  2.50581,  2.65892,
+  1.34135,  1.41915,  1.9212,  1.99146,  2.53082,  2.61358,
+  1.3427,  1.50533,  1.94693,  2.02943,  2.53822,  2.63558,
+  1.39274,  1.5351,  1.9361,  2.02457,  2.52728,  2.61426,
+  1.43256,  1.54379,  1.95185,  2.04985,  2.54624,  2.62371,
+  1.45294,  1.56943,  1.93237,  2.03725,  2.55869,  2.6381,
+  1.468,  1.59745,  1.92031,  2.01857,  2.53622,  2.62282,
+  1.48681,  1.56965,  1.87585,  1.96607,  2.53674,  2.63191,
+  1.45462,  1.57813,  1.81162,  1.97466,  2.53751,  2.60633,
+  1.41804,  1.50767,  1.78357,  1.893,  2.5518,  2.62899,
+  1.26414,  1.47438,  1.77059,  1.89893,  2.52476,  2.59407,
+  1.11834,  1.45667,  1.73472,  1.99659,  2.41229,  2.51915,
+  1.09643,  1.60312,  1.80839,  2.01224,  2.40962,  2.54436,
+  0.976303,  1.47374,  1.75917,  1.85583,  2.41293,  2.48395,
+  0.990184,  1.3907,  1.71071,  1.83167,  2.37709,  2.45494,
+  1.0569,  1.38737,  1.78311,  1.87351,  2.40142,  2.48642,
+  0.989786,  1.45262,  1.85157,  1.94592,  2.40345,  2.48294,
+  1.11208,  1.36482,  1.77,  1.922,  2.29041,  2.4373,
+  1.09625,  1.33639,  1.74186,  1.96857,  2.21161,  2.36249,
+  1.00003,  1.34618,  1.70453,  1.96685,  2.27739,  2.38937,
+  1.0279,  1.17407,  1.793,  2.02685,  2.1782,  2.38723,
+  1.05688,  1.1675,  1.861,  2.20442,  2.35125,  2.48563,
+  1.07597,  1.22642,  1.99764,  2.19618,  2.3301,  2.49414,
+  1.14722,  1.25813,  1.95867,  2.25855,  2.38775,  2.55212,
+  1.16281,  1.29057,  2.05279,  2.20183,  2.42462,  2.56048,
+  1.14789,  1.26573,  2.02568,  2.13079,  2.49688,  2.62026,
+  1.23956,  1.31573,  2.01838,  2.12351,  2.46395,  2.56921,
+  1.18113,  1.35894,  1.94216,  2.15983,  2.4587,  2.59396,
+  1.24746,  1.38644,  1.89825,  1.99901,  2.44602,  2.54276,
+  1.22769,  1.50489,  1.818,  1.90802,  2.21333,  2.55223,
+  1.20197,  1.57787,  1.77128,  1.87335,  2.06126,  2.53582,
+  1.30623,  1.51631,  1.81923,  1.92342,  2.38203,  2.58257,
+  1.50572,  1.58565,  1.94933,  2.0462,  2.44831,  2.61596,
+  1.62375,  1.69873,  2.00954,  2.10801,  2.46152,  2.6479,
+  1.69086,  1.76429,  2.0361,  2.1755,  2.51525,  2.61682,
+  1.71534,  1.82829,  2.07855,  2.25221,  2.48367,  2.60765,
+  1.65997,  1.80717,  1.97501,  2.25559,  2.48134,  2.58962,
+  1.73482,  1.85022,  2.01204,  2.27674,  2.51936,  2.60818,
+  1.63577,  1.86255,  1.95646,  2.32874,  2.56887,  2.63247,
+  1.61635,  1.8254,  1.94952,  2.28122,  2.56086,  2.6418,
+  1.59247,  1.80436,  1.92716,  2.16734,  2.57751,  2.64687,
+  1.60648,  1.89509,  1.98315,  2.11245,  2.47761,  2.57696,
+  1.70849,  1.83507,  1.96671,  2.12724,  2.42757,  2.54308,
+  1.69109,  1.88958,  1.98607,  2.20677,  2.5224,  2.6018,
+  1.70244,  1.90212,  2.07638,  2.21622,  2.48484,  2.60354,
+  1.32949,  1.54259,  1.87544,  2.10553,  2.38523,  2.53663,
+  1.32138,  1.47416,  1.93227,  2.1525,  2.37442,  2.50671,
+  1.27775,  1.45858,  1.96309,  2.18238,  2.417,  2.55865,
+  1.20802,  1.41871,  2.00974,  2.13853,  2.39678,  2.55451,
+  1.19891,  1.29992,  1.98363,  2.15013,  2.29612,  2.50594,
+  1.25034,  1.36116,  2.01056,  2.19594,  2.34098,  2.50087,
+  1.30866,  1.58516,  2.10634,  2.21416,  2.40267,  2.63589,
+  1.33017,  1.49463,  2.1419,  2.23581,  2.45958,  2.64947,
+  1.29631,  1.43411,  2.09809,  2.20413,  2.35521,  2.60011,
+  1.30962,  1.40298,  1.89254,  2.18495,  2.33361,  2.51316,
+  1.26907,  1.49184,  1.95896,  2.17457,  2.32469,  2.54367,
+  1.43498,  1.62885,  1.98127,  2.24728,  2.4764,  2.59398,
+  1.45964,  1.65008,  2.02437,  2.26772,  2.54631,  2.6752,
+  1.38149,  1.70319,  2.13891,  2.29556,  2.54576,  2.64253,
+  1.44184,  1.70059,  2.19791,  2.27629,  2.46821,  2.69495,
+  1.53967,  1.99967,  2.20653,  2.35148,  2.65123,  2.73482,
+  1.58958,  1.92641,  2.17346,  2.2562,  2.63324,  2.70768,
+  1.43426,  1.85937,  2.14195,  2.21145,  2.51178,  2.62838,
+  1.32681,  1.59657,  2.02477,  2.11581,  2.42614,  2.60934,
+  1.22907,  1.32555,  1.8387,  2.01305,  2.4713,  2.63928,
+  1.23081,  1.32906,  1.87262,  1.96451,  2.44475,  2.59469,
+  1.1937,  1.4263,  1.89859,  2.03936,  2.50271,  2.58105,
+  1.17564,  1.47329,  1.91242,  2.00274,  2.47622,  2.60685,
+  1.09927,  1.4439,  1.89246,  1.99757,  2.52208,  2.61109,
+  1.11374,  1.4391,  1.91227,  2.00048,  2.46277,  2.55934,
+  1.08551,  1.46963,  1.91446,  2.06461,  2.42792,  2.51241,
+  1.05248,  1.5012,  1.9188,  1.99979,  2.49368,  2.57171,
+  1.0436,  1.33162,  1.92795,  1.98919,  2.44573,  2.57808,
+  1.05198,  1.20039,  1.93863,  2.02681,  2.44675,  2.62988,
+  0.978672,  1.08304,  1.86878,  2.13358,  2.43014,  2.58027,
+  0.904772,  1.10521,  1.96057,  2.06495,  2.36256,  2.60488,
+  0.859439,  1.08463,  1.90171,  2.033,  2.27617,  2.57472,
+  0.948943,  1.04355,  1.85564,  2.05086,  2.44443,  2.66148,
+  0.974338,  1.12646,  1.92732,  2.02091,  2.45549,  2.55978,
+  0.995629,  1.17589,  1.93774,  2.01368,  2.37897,  2.61729,
+  1.00131,  1.22439,  1.9017,  1.97647,  2.42588,  2.57484,
+  0.985969,  1.2826,  1.88661,  2.03245,  2.45596,  2.59953,
+  0.92759,  1.32045,  1.92401,  2.01217,  2.49831,  2.59968,
+  1.00794,  1.38396,  1.92163,  2.00762,  2.50757,  2.6075,
+  0.972512,  1.44677,  1.92036,  2.01349,  2.49021,  2.57649,
+  0.951123,  1.45204,  1.88986,  1.98727,  2.42148,  2.56222,
+  0.924342,  1.36995,  1.85174,  1.94274,  2.47566,  2.54428,
+  0.882605,  1.30167,  1.85081,  2.0325,  2.36463,  2.54182,
+  0.933888,  1.369,  1.94311,  2.02385,  2.40544,  2.53033,
+  0.927916,  1.11238,  1.84743,  1.97909,  2.2556,  2.56399,
+  1.03194,  1.24913,  1.83317,  1.92522,  2.31031,  2.52014,
+  0.934046,  1.23989,  1.9096,  2.00815,  2.37287,  2.54896,
+  0.984297,  1.22003,  1.82379,  1.9476,  2.26436,  2.47865,
+  0.933366,  1.27898,  1.86047,  1.943,  2.2898,  2.46567,
+  0.983115,  1.22771,  1.8421,  2.0477,  2.27265,  2.53198,
+  0.953311,  1.24582,  1.84968,  1.94514,  2.28957,  2.57228,
+  0.994609,  1.30346,  1.86814,  1.97156,  2.37244,  2.58526,
+  0.986061,  1.36409,  1.85213,  1.91782,  2.43511,  2.63387,
+  0.975486,  1.24885,  1.8488,  1.93443,  2.40202,  2.5742,
+  1.00839,  1.30468,  1.80431,  1.88851,  2.36947,  2.59823,
+  0.999393,  1.32994,  1.90144,  1.99438,  2.3975,  2.50455,
+  0.922186,  1.32154,  1.85108,  1.96206,  2.38216,  2.47299,
+  0.897224,  1.38219,  1.78084,  1.92173,  2.35959,  2.44809,
+  0.859516,  1.44737,  1.73231,  1.88119,  2.29523,  2.38085,
+  0.986347,  1.60164,  1.75239,  1.96636,  2.31438,  2.4591,
+  1.26526,  1.61653,  1.81127,  2.09714,  2.37124,  2.55036,
+  1.31896,  1.60043,  1.75564,  2.02981,  2.32919,  2.49314,
+  1.2099,  1.47013,  1.67019,  1.97073,  2.41621,  2.52342,
+  1.12223,  1.3084,  1.45711,  1.72023,  2.38426,  2.47042,
+  1.07767,  1.24551,  1.36648,  1.66428,  2.32734,  2.4192,
+  1.07545,  1.22813,  1.36538,  1.55895,  2.23858,  2.32456,
+  1.0445,  1.21579,  1.32599,  1.64519,  2.14864,  2.22575,
+  0.955863,  1.15061,  1.28313,  1.49231,  2.17758,  2.26668,
+  0.909204,  1.04511,  1.16616,  1.32059,  2.21597,  2.35285,
+  0.960368,  1.10354,  1.27835,  1.46773,  2.26015,  2.46024,
+  1.01022,  1.18678,  1.29006,  1.57843,  2.38873,  2.50032,
+  1.02014,  1.13572,  1.23934,  1.38884,  2.43818,  2.56392,
+  1.08249,  1.20695,  1.34746,  1.49004,  2.40482,  2.49462,
+  1.14411,  1.27864,  1.43473,  1.56789,  2.32277,  2.4248,
+  1.2743,  1.34879,  1.5156,  1.63222,  2.36011,  2.55279,
+  1.30133,  1.39063,  1.63849,  1.76491,  2.34796,  2.57611,
+  1.35852,  1.44445,  1.72449,  1.84371,  2.47814,  2.57455,
+  1.39971,  1.51331,  1.79171,  1.90217,  2.49582,  2.58159,
+  1.44887,  1.53475,  1.82151,  1.93149,  2.51782,  2.62286,
+  1.4384,  1.53006,  1.83144,  1.99933,  2.53193,  2.62328,
+  1.51192,  1.58109,  1.92748,  2.0414,  2.57329,  2.66347,
+  1.53538,  1.60831,  1.92423,  2.0488,  2.54675,  2.68165,
+  1.54437,  1.62041,  1.98043,  2.06813,  2.4774,  2.62665,
+  1.55846,  1.64301,  2.02461,  2.12101,  2.45187,  2.63949,
+  1.5242,  1.61395,  2.0059,  2.11548,  2.42909,  2.66308,
+  1.50452,  1.59038,  1.96636,  2.07263,  2.3769,  2.62109,
+  1.43939,  1.51234,  1.95035,  2.05856,  2.27641,  2.57304,
+  1.31521,  1.40005,  1.85475,  1.95763,  2.2462,  2.5765,
+  1.28812,  1.4889,  1.94557,  2.02484,  2.43985,  2.60568,
+  1.43628,  1.66725,  2.05685,  2.14644,  2.54824,  2.66174,
+  1.41739,  1.81984,  2.08357,  2.22028,  2.60669,  2.69086,
+  1.3736,  1.96301,  2.14457,  2.27406,  2.54739,  2.6389,
+  1.32037,  1.91864,  2.06321,  2.23772,  2.41585,  2.51765,
+  1.22378,  1.61975,  1.89059,  2.10791,  2.521,  2.6297,
+  1.01875,  1.42767,  1.91757,  2.00178,  2.43551,  2.56435,
+  1.02625,  1.37705,  1.94917,  2.03921,  2.39377,  2.53005,
+  1.00999,  1.47285,  1.99805,  2.07988,  2.48496,  2.55395,
+  1.05327,  1.46837,  2.01612,  2.12931,  2.45662,  2.56413,
+  1.10107,  1.35527,  2.01044,  2.10747,  2.39561,  2.53775,
+  1.1328,  1.39166,  2.01657,  2.1141,  2.49762,  2.5851,
+  1.17331,  1.44301,  1.97063,  2.10486,  2.44788,  2.53594,
+  1.20948,  1.3841,  1.97224,  2.06959,  2.45749,  2.57369,
+  1.24242,  1.45356,  1.98373,  2.06842,  2.47104,  2.59361,
+  1.32039,  1.46365,  1.99783,  2.08233,  2.47203,  2.60589,
+  1.38952,  1.47773,  1.97869,  2.09404,  2.48017,  2.64444,
+  1.41374,  1.52609,  1.96375,  2.11392,  2.40385,  2.65443,
+  1.51942,  1.59285,  1.91946,  2.02449,  2.30117,  2.66889,
+  1.51366,  1.60013,  1.92201,  2.1051,  2.27832,  2.52342,
+  1.48185,  1.65994,  1.91355,  2.04944,  2.27225,  2.49379,
+  1.56755,  1.65917,  1.93065,  2.07152,  2.31259,  2.56427,
+  1.55089,  1.67766,  1.86393,  2.01013,  2.22347,  2.52001,
+  1.57277,  1.68302,  1.86305,  2.0022,  2.32038,  2.56079,
+  1.62194,  1.73405,  1.92064,  2.06293,  2.33511,  2.57625,
+  1.63149,  1.69714,  1.95288,  2.05658,  2.45963,  2.65286,
+  1.59471,  1.67149,  1.93609,  2.0133,  2.43078,  2.66963,
+  1.60144,  1.6687,  1.9455,  2.03717,  2.50337,  2.68212,
+  1.58757,  1.6649,  1.94462,  2.03299,  2.56976,  2.70341,
+  1.55642,  1.63125,  1.93071,  2.04051,  2.45387,  2.66518,
+  1.48785,  1.56563,  1.89287,  2.01173,  2.39394,  2.64712,
+  1.40601,  1.52018,  1.79165,  1.98788,  2.28933,  2.60276,
+  1.35822,  1.43604,  1.81848,  1.95708,  2.3098,  2.60578,
+  1.30934,  1.40533,  1.8357,  2.07637,  2.34081,  2.61306,
+  1.30379,  1.41561,  1.98515,  2.12949,  2.46936,  2.64312,
+  1.35895,  1.43773,  1.98883,  2.12737,  2.53798,  2.65647,
+  1.33387,  1.48046,  1.95007,  2.12244,  2.43117,  2.58713,
+  1.38453,  1.53971,  1.96409,  2.13055,  2.51045,  2.65281,
+  1.41262,  1.54444,  1.94728,  2.17319,  2.59302,  2.71664,
+  1.43327,  1.53989,  2.00413,  2.20195,  2.51505,  2.63524,
+  1.44758,  1.55402,  2.12827,  2.24017,  2.47075,  2.65708,
+  1.48065,  1.6099,  2.09796,  2.16757,  2.4737,  2.7007,
+  1.60782,  1.67596,  2.02341,  2.14638,  2.42691,  2.63625,
+  1.6433,  1.71778,  2.06066,  2.19756,  2.41541,  2.61433,
+  1.73739,  1.81697,  2.03936,  2.21971,  2.423,  2.62353,
+  1.69426,  1.79937,  2.0426,  2.2801,  2.41863,  2.58327,
+  1.55619,  1.83187,  1.98536,  2.2079,  2.47168,  2.63082,
+  1.42115,  1.8039,  1.98458,  2.12351,  2.4382,  2.5225,
+  1.32744,  1.66887,  1.88843,  2.02994,  2.22446,  2.46175,
+  1.10982,  1.5622,  1.86266,  1.97786,  2.13955,  2.32864,
+  1.23388,  1.5808,  1.85419,  2.02179,  2.1935,  2.35592,
+  1.20754,  1.56864,  1.87291,  1.98667,  2.13794,  2.48765,
+  1.17998,  1.62595,  1.9,  2.00814,  2.23166,  2.59435,
+  1.46984,  1.7172,  1.87567,  2.02443,  2.32546,  2.48842,
+  1.6411,  1.80978,  1.92676,  2.06205,  2.41404,  2.5429,
+  1.6488,  1.73412,  1.9669,  2.08673,  2.35448,  2.49884,
+  1.60547,  1.68939,  2.01005,  2.11421,  2.40763,  2.52707,
+  1.52089,  1.62873,  1.97701,  2.08677,  2.34016,  2.48934,
+  1.50382,  1.60059,  2.03901,  2.13038,  2.39648,  2.51374,
+  1.43782,  1.54532,  2.04393,  2.18837,  2.35682,  2.52145,
+  1.4454,  1.54921,  1.98221,  2.09666,  2.32863,  2.46213,
+  1.41642,  1.50436,  1.97377,  2.08043,  2.39348,  2.54353,
+  1.42582,  1.52808,  1.99573,  2.16253,  2.44069,  2.56251,
+  1.39427,  1.47395,  2.04354,  2.14909,  2.43298,  2.54908,
+  1.37375,  1.47605,  2.0439,  2.16025,  2.34535,  2.50188,
+  1.37018,  1.44359,  2.09287,  2.1781,  2.41306,  2.5906,
+  1.32039,  1.46637,  2.03678,  2.13781,  2.43562,  2.57891,
+  1.28693,  1.39332,  2.06073,  2.20094,  2.50002,  2.58235,
+  1.32339,  1.42179,  2.0585,  2.15393,  2.49555,  2.63809,
+  1.29531,  1.39322,  2.00442,  2.13819,  2.52637,  2.64154,
+  1.23098,  1.35513,  2.04737,  2.15642,  2.52238,  2.66413,
+  1.23375,  1.30852,  1.93949,  2.09735,  2.48735,  2.64984,
+  1.22759,  1.3551,  1.87583,  1.97754,  2.31929,  2.57519,
+  1.22737,  1.50711,  1.85352,  2.02289,  2.21243,  2.57649,
+  1.1529,  1.47051,  1.83043,  1.95431,  2.33145,  2.53325,
+  1.33666,  1.65018,  1.77921,  2.04342,  2.44482,  2.53964,
+  1.45582,  1.58294,  2.02225,  2.17668,  2.48134,  2.59266,
+  1.43763,  1.55624,  2.08145,  2.17496,  2.48245,  2.61457,
+  1.41647,  1.62089,  2.03301,  2.15707,  2.46292,  2.60159,
+  1.3763,  1.55149,  2.11721,  2.19834,  2.41619,  2.60563,
+  1.4428,  1.65786,  2.12709,  2.2063,  2.34486,  2.57811,
+  1.36811,  1.53873,  2.0602,  2.19805,  2.36688,  2.62224,
+  1.34644,  1.42834,  1.98045,  2.12661,  2.28327,  2.53061,
+  1.30459,  1.37326,  1.92352,  2.09636,  2.23996,  2.50843,
+  1.29803,  1.37159,  1.95497,  2.10751,  2.34971,  2.54557,
+  1.30718,  1.41617,  1.98034,  2.06446,  2.3891,  2.58844,
+  1.2793,  1.39078,  1.95978,  2.09069,  2.43615,  2.61261,
+  1.31702,  1.41587,  1.92187,  2.07179,  2.46382,  2.61622,
+  1.29431,  1.4123,  1.9162,  2.0192,  2.48471,  2.61134,
+  1.31005,  1.40777,  1.85317,  2.00991,  2.46649,  2.64501,
+  1.3413,  1.42233,  1.88516,  1.96781,  2.48386,  2.62632,
+  1.42826,  1.52612,  1.88512,  1.97853,  2.49939,  2.60339,
+  1.50117,  1.58051,  1.84728,  2.00049,  2.46595,  2.60887,
+  1.53851,  1.6254,  1.81392,  1.95006,  2.5229,  2.62047,
+  1.56663,  1.6396,  1.77179,  1.87875,  2.54176,  2.66369,
+  1.54343,  1.64782,  1.74862,  1.8226,  2.43468,  2.63128,
+  1.62339,  1.68092,  1.75915,  1.84454,  2.52147,  2.65361,
+  1.57486,  1.66372,  1.76778,  1.86974,  2.45334,  2.65822,
+  1.55831,  1.66125,  1.79384,  1.89513,  2.26187,  2.57233,
+  1.54368,  1.62776,  1.81767,  1.92128,  2.433,  2.65334,
+  1.49354,  1.57566,  1.80569,  1.93945,  2.47064,  2.66508,
+  1.44005,  1.51384,  1.83221,  1.9378,  2.53025,  2.70287,
+  1.3191,  1.50623,  1.82349,  1.93161,  2.53955,  2.6767,
+  1.30727,  1.56337,  1.84793,  1.95172,  2.25182,  2.45322,
+  1.33641,  1.6616,  1.82882,  1.98833,  2.18951,  2.35425,
+  1.34292,  1.59875,  1.78474,  1.91512,  2.10999,  2.45064,
+  1.3367,  1.64636,  1.80074,  1.89121,  2.23591,  2.55851,
+  1.31176,  1.50001,  1.83022,  1.94504,  2.43039,  2.64458,
+  1.26611,  1.43196,  1.85876,  2.05915,  2.59049,  2.67476,
+  1.31778,  1.41995,  1.91646,  2.12482,  2.57473,  2.66848,
+  1.34152,  1.43617,  1.96842,  2.09744,  2.57279,  2.6851,
+  1.30593,  1.43886,  1.93375,  2.03608,  2.56907,  2.65642,
+  1.27913,  1.40647,  1.94309,  2.03172,  2.53008,  2.63088,
+  1.28601,  1.41003,  1.96969,  2.04024,  2.44857,  2.65137,
+  1.25754,  1.39106,  1.96657,  2.03921,  2.40242,  2.64679,
+  1.22439,  1.35213,  1.93137,  2.00634,  2.4562,  2.69615,
+  1.29629,  1.4881,  1.99695,  2.06819,  2.59454,  2.69584,
+  1.33457,  1.60772,  1.92214,  2.16316,  2.54592,  2.67997,
+  1.38178,  1.64677,  2.03764,  2.20409,  2.54579,  2.63933,
+  1.41682,  1.62893,  2.04593,  2.20935,  2.52385,  2.67579,
+  1.43146,  1.6948,  1.99893,  2.15953,  2.52293,  2.66475,
+  1.38424,  1.62294,  2.03694,  2.11571,  2.52889,  2.63393,
+  1.40383,  1.55836,  2.02735,  2.13802,  2.56277,  2.65938,
+  1.39059,  1.67194,  2.01794,  2.16459,  2.59282,  2.68361,
+  1.35753,  1.55376,  2.02314,  2.21231,  2.42046,  2.55826,
+  1.30172,  1.46582,  2.05293,  2.21596,  2.42069,  2.54852,
+  1.33933,  1.59705,  2.03516,  2.14582,  2.5096,  2.64414,
+  1.34609,  1.63387,  2.00692,  2.11472,  2.57003,  2.68888,
+  1.35844,  1.50167,  1.94958,  2.02763,  2.47964,  2.63746,
+  1.42799,  1.53369,  1.85363,  1.96081,  2.43754,  2.58846,
+  1.507,  1.58581,  1.86464,  1.95027,  2.47877,  2.62455,
+  1.53515,  1.61948,  1.7846,  1.92633,  2.53715,  2.6658,
+  1.49966,  1.57482,  1.68583,  1.82255,  2.53399,  2.70531,
+  1.58548,  1.64242,  1.72185,  1.84674,  2.52449,  2.71035,
+  1.16736,  1.62721,  1.76839,  1.85304,  2.26556,  2.54052,
+  1.11032,  1.50695,  1.80563,  1.88181,  2.36127,  2.58996,
+  1.06643,  1.53942,  1.7463,  1.93612,  2.12799,  2.46118,
+  1.111,  1.56535,  1.85208,  1.96046,  2.21492,  2.4979,
+  1.11612,  1.59069,  1.87918,  1.96908,  2.32329,  2.53297,
+  1.1484,  1.55745,  1.81996,  1.96379,  2.38034,  2.48453,
+  1.09256,  1.56982,  1.784,  1.95924,  2.32426,  2.46849,
+  1.213,  1.57893,  1.75164,  1.90157,  2.27177,  2.38609,
+  1.12398,  1.62627,  1.75806,  1.98376,  2.29113,  2.408,
+  1.07579,  1.53483,  1.78478,  2.04194,  2.2367,  2.36811,
+  1.11878,  1.41569,  1.97193,  2.12276,  2.33025,  2.44046,
+  1.01609,  1.33452,  1.8992,  2.12157,  2.42514,  2.54387,
+  1.0662,  1.28942,  1.94816,  2.08195,  2.47149,  2.59382,
+  1.06499,  1.25576,  1.93597,  2.03695,  2.49318,  2.61275,
+  1.04967,  1.22845,  1.82953,  2.02506,  2.43107,  2.67084,
+  1.01963,  1.31358,  1.88031,  1.95395,  2.49169,  2.64266,
+  1.15348,  1.5519,  1.90975,  2.13353,  2.54007,  2.62647,
+  1.29303,  1.60048,  2.03569,  2.16688,  2.57297,  2.65826,
+  1.40931,  1.62414,  1.99362,  2.26849,  2.52706,  2.65186,
+  1.4264,  1.68151,  2.03941,  2.21528,  2.55906,  2.6814,
+  1.42204,  1.75264,  2.02799,  2.23143,  2.54648,  2.63124,
+  1.40307,  1.73555,  2.00708,  2.20211,  2.63554,  2.71835,
+  1.36412,  1.68736,  2.01193,  2.29363,  2.6407,  2.70526,
+  1.32806,  1.60827,  1.98985,  2.36496,  2.59056,  2.68945,
+  1.33359,  1.64487,  2.1305,  2.30858,  2.64414,  2.73281,
+  1.40524,  1.66596,  2.12336,  2.31586,  2.65694,  2.73287,
+  1.43537,  1.67954,  2.0191,  2.2544,  2.59608,  2.67406,
+  1.04103,  1.47652,  1.92332,  2.29056,  2.59234,  2.67362,
+  0.818396,  1.18975,  2.05137,  2.23338,  2.4171,  2.62257,
+  0.745703,  1.24025,  2.13926,  2.22418,  2.47642,  2.55879,
+  0.786217,  1.29674,  2.00436,  2.24582,  2.54872,  2.6314,
+  0.781573,  1.12234,  1.87575,  2.27728,  2.45942,  2.55721,
+  0.697586,  1.32715,  2.09799,  2.17356,  2.57467,  2.6936,
+  0.773107,  1.39301,  1.97117,  2.27022,  2.5915,  2.65154,
+  0.799951,  1.25267,  1.92838,  2.21123,  2.57772,  2.68382,
+  0.737528,  1.23791,  1.82716,  2.11053,  2.4763,  2.62767,
+  0.896067,  1.42136,  1.84116,  2.10482,  2.43287,  2.58572,
+  0.920446,  1.41858,  1.94342,  2.2527,  2.49124,  2.62311,
+  0.905094,  1.28473,  1.84369,  2.26911,  2.47954,  2.59591,
+  1.04955,  1.4475,  1.84117,  2.16036,  2.57575,  2.6557,
+  1.2828,  1.44542,  1.90123,  2.29017,  2.58164,  2.67873,
+  1.17471,  1.51702,  1.86793,  2.17662,  2.54748,  2.64015,
+  1.24126,  1.5185,  1.93677,  2.20877,  2.52132,  2.61983,
+  1.32193,  1.5402,  1.99853,  2.20577,  2.60566,  2.70791,
+  1.3038,  1.62293,  1.88039,  2.18949,  2.58891,  2.66997,
+  1.36083,  1.65855,  1.90332,  2.17801,  2.55428,  2.63477,
+  1.38546,  1.62331,  1.9591,  2.25774,  2.60539,  2.69462,
+  1.46795,  1.62817,  2.0031,  2.34892,  2.5961,  2.67456,
+  1.41184,  1.69139,  1.94701,  2.25922,  2.52614,  2.61511,
+  1.41526,  1.69746,  2.0031,  2.28429,  2.52624,  2.64336,
+  1.36534,  1.61019,  2.0221,  2.1717,  2.5576,  2.64224,
+  1.34395,  1.63077,  2.04084,  2.26171,  2.47792,  2.64736,
+  1.33358,  1.63038,  2.0312,  2.21087,  2.50406,  2.62333,
+  1.34412,  1.70468,  2.06581,  2.19257,  2.54136,  2.65852,
+  1.43988,  1.66659,  2.08273,  2.20601,  2.63634,  2.69917,
+  1.34435,  1.65594,  2.02685,  2.22783,  2.56587,  2.66126,
+  1.29968,  1.58529,  1.96155,  2.23114,  2.59956,  2.6776,
+  1.18443,  1.44165,  1.88854,  2.25541,  2.55466,  2.62551,
+  1.44657,  1.79255,  2.02266,  2.17921,  2.49716,  2.59111,
+  1.46468,  1.80928,  2.06019,  2.20545,  2.54596,  2.64191,
+  1.48129,  1.72952,  2.02569,  2.25001,  2.53746,  2.66775,
+  1.47646,  1.65779,  2.00806,  2.2492,  2.50322,  2.61312,
+  1.38626,  1.58955,  2.0317,  2.2183,  2.50921,  2.6191,
+  1.38626,  1.66286,  2.05258,  2.20868,  2.48839,  2.62305,
+  1.43812,  1.64607,  1.96782,  2.21244,  2.50872,  2.6294,
+  1.4376,  1.59023,  2.08908,  2.18445,  2.56655,  2.67785,
+  1.36702,  1.65253,  2.08437,  2.16949,  2.4836,  2.65574,
+  1.40378,  1.70134,  2.0628,  2.14854,  2.44319,  2.65725,
+  1.39919,  1.70605,  2.06243,  2.14458,  2.53122,  2.63501,
+  1.40966,  1.75057,  2.00507,  2.08724,  2.60283,  2.69407,
+  1.43015,  1.7604,  2.0488,  2.11806,  2.56938,  2.65727,
+  1.41885,  1.85893,  2.01867,  2.14141,  2.59787,  2.67114,
+  1.51504,  1.81561,  1.94217,  2.08906,  2.55465,  2.6346,
+  1.42003,  1.74012,  1.95375,  2.19613,  2.50269,  2.63975,
+  1.3841,  1.72331,  1.90117,  2.1602,  2.42662,  2.52258,
+  1.34105,  1.73737,  1.89475,  2.11087,  2.40751,  2.50284,
+  1.37576,  1.55398,  1.78427,  1.98142,  2.50412,  2.57153,
+  1.41459,  1.52055,  1.71537,  2.01302,  2.5112,  2.60864,
+  1.38497,  1.51911,  1.69669,  1.93938,  2.5757,  2.64475,
+  1.37786,  1.61168,  1.75124,  2.04456,  2.4936,  2.56797,
+  1.36085,  1.55368,  1.69398,  2.03611,  2.53589,  2.58847,
+  1.39163,  1.48933,  1.63148,  1.85308,  2.52955,  2.63182,
+  1.36408,  1.47605,  1.62904,  1.94902,  2.52574,  2.58792,
+  1.2439,  1.39859,  1.53969,  2.06632,  2.52865,  2.59222,
+  1.25551,  1.42936,  1.54884,  1.95098,  2.51998,  2.57485,
+  1.21333,  1.3888,  1.50598,  1.88664,  2.48612,  2.54536,
+  1.1258,  1.2869,  1.53495,  1.98205,  2.49021,  2.57068,
+  1.13252,  1.2962,  1.46083,  1.92525,  2.35567,  2.44404,
+  1.14673,  1.36534,  1.49607,  2.02061,  2.44833,  2.51065,
+  1.19278,  1.37894,  1.49116,  1.95926,  2.45914,  2.51972,
+  1.27161,  1.38388,  1.52586,  1.95321,  2.47314,  2.52627,
+  1.19995,  1.36609,  1.51973,  1.92677,  2.56299,  2.62374,
+  1.23602,  1.38351,  1.51039,  1.7933,  2.58549,  2.67708,
+  1.27722,  1.41656,  1.53945,  1.92379,  2.59908,  2.66772,
+  1.19596,  1.40806,  1.56871,  2.09079,  2.62218,  2.6689,
+  1.17444,  1.3008,  1.70657,  2.07033,  2.33283,  2.491,
+  1.12025,  1.25279,  1.5621,  2.05712,  2.35786,  2.4881,
+  1.17632,  1.29197,  1.76026,  2.09335,  2.39555,  2.59153,
+  1.19772,  1.41553,  1.80193,  2.03318,  2.45962,  2.59256,
+  1.17046,  1.49125,  1.88804,  2.08248,  2.39229,  2.52815,
+  1.08351,  1.49178,  1.94946,  2.0462,  2.42247,  2.59161,
+  1.05994,  1.41798,  1.95482,  2.07325,  2.48096,  2.59912,
+  0.939633,  1.34851,  2.00568,  2.09423,  2.47405,  2.58029,
+  0.849679,  1.29353,  1.99812,  2.10527,  2.4101,  2.61591,
+  0.886534,  1.43235,  1.99045,  2.0898,  2.37908,  2.5395,
+  0.973462,  1.47362,  1.94439,  2.05184,  2.3931,  2.46861,
+  1.04199,  1.57643,  1.95273,  2.06254,  2.32632,  2.43777,
+  1.0487,  1.54395,  1.79902,  2.01526,  2.41591,  2.48738,
+  1.06075,  1.46328,  1.792,  1.94049,  2.41744,  2.51762,
+  1.08688,  1.35051,  1.71544,  1.80448,  2.48199,  2.57724,
+  1.23776,  1.48723,  1.7249,  1.80832,  2.52853,  2.61455,
+  1.39846,  1.49959,  1.70594,  1.81787,  2.53742,  2.61115,
+  1.46184,  1.54928,  1.71949,  1.83518,  2.48005,  2.65662,
+  1.41193,  1.59484,  1.72262,  1.84021,  2.5366,  2.61871,
+  1.52708,  1.60947,  1.70484,  1.83282,  2.51277,  2.60508,
+  1.5493,  1.64971,  1.74718,  1.83885,  2.59328,  2.68152,
+  1.40865,  1.62213,  1.79776,  1.95077,  2.23897,  2.46394,
+  1.46356,  1.64796,  1.79073,  1.92141,  2.34804,  2.57262,
+  1.53189,  1.70037,  1.83404,  2.0056,  2.41348,  2.57054,
+  1.5952,  1.68156,  1.85702,  2.02018,  2.47538,  2.62026,
+  1.57838,  1.65186,  1.91226,  2.01199,  2.5125,  2.62561,
+  1.55111,  1.64436,  1.93621,  2.04161,  2.52732,  2.61724,
+  1.53197,  1.62315,  1.9276,  2.00745,  2.52804,  2.63456,
+  1.49246,  1.57949,  1.90868,  1.99823,  2.49061,  2.58309,
+  1.44543,  1.54876,  1.9137,  2.0028,  2.51924,  2.61095,
+  1.39728,  1.48225,  1.89122,  1.98384,  2.47449,  2.60778,
+  1.3583,  1.56294,  1.90205,  2.00361,  2.42564,  2.58541,
+  1.31335,  1.51889,  1.92307,  2.01194,  2.49694,  2.5837,
+  1.32168,  1.50683,  1.90306,  1.99006,  2.51061,  2.61974,
+  1.27289,  1.51344,  1.8979,  2.03966,  2.53652,  2.60414,
+  1.25574,  1.43115,  1.89662,  1.96089,  2.52675,  2.62424,
+  1.25356,  1.39283,  1.89379,  1.97508,  2.52068,  2.59667,
+  1.21234,  1.37522,  1.86031,  1.96496,  2.53119,  2.59867,
+  1.17744,  1.32419,  1.80663,  1.88529,  2.48732,  2.59546,
+  1.185,  1.38308,  1.78322,  1.86347,  2.46657,  2.57065,
+  1.16227,  1.44473,  1.79788,  1.96024,  2.51584,  2.59443,
+  1.29313,  1.61263,  1.91287,  2.11307,  2.4672,  2.59265,
+  1.3544,  1.69802,  1.96011,  2.14947,  2.53298,  2.65269,
+  1.41207,  1.72912,  2.03409,  2.17295,  2.53881,  2.64369,
+  1.39179,  1.80176,  1.94479,  2.19455,  2.4673,  2.54771,
+  1.47608,  1.74319,  1.98255,  2.14116,  2.55905,  2.64289,
+  1.42368,  1.8572,  1.99841,  2.14699,  2.4995,  2.58386,
+  1.42068,  1.87817,  2.01232,  2.29828,  2.57827,  2.66549,
+  1.45566,  1.91054,  2.06984,  2.39305,  2.59349,  2.67981,
+  1.52558,  1.92571,  2.18647,  2.40072,  2.66013,  2.74311,
+  1.37615,  1.63344,  1.9343,  2.25049,  2.49406,  2.61897,
+  1.3545,  1.56095,  1.93126,  2.20732,  2.5007,  2.61105,
+  1.30807,  1.56951,  1.96724,  2.24546,  2.46112,  2.59551,
+  1.34701,  1.65498,  1.98091,  2.25189,  2.51009,  2.63498,
+  1.47801,  1.58844,  2.0382,  2.22414,  2.49937,  2.64663,
+  1.45153,  1.63029,  2.1141,  2.24973,  2.4165,  2.6518,
+  1.41214,  1.65583,  2.12835,  2.22464,  2.52506,  2.68174,
+  1.3745,  1.84889,  2.14083,  2.2919,  2.60283,  2.691,
+  1.37857,  1.74485,  2.10667,  2.20122,  2.62683,  2.712,
+  1.08274,  1.60312,  2.07077,  2.12957,  2.50429,  2.65755,
+  1.01329,  1.46791,  1.96003,  2.09179,  2.36205,  2.56155,
+  0.9941,  1.32807,  1.7917,  1.90255,  2.41063,  2.50132,
+  0.999159,  1.32525,  1.72231,  1.87138,  2.28118,  2.50209,
+  1.03528,  1.33808,  1.65302,  1.75976,  2.44146,  2.54067,
+  1.07713,  1.29359,  1.56567,  1.7118,  2.33034,  2.43626,
+  1.05812,  1.24303,  1.48833,  1.62368,  2.33012,  2.42954,
+  1.15066,  1.2962,  1.57472,  1.70184,  2.39048,  2.50735,
+  1.16792,  1.38204,  1.57381,  1.7953,  2.44065,  2.49036,
+  1.22137,  1.40507,  1.53578,  1.72864,  2.41229,  2.51938,
+  1.24827,  1.38398,  1.57228,  1.82686,  2.42535,  2.49422,
+  1.27415,  1.38627,  1.55782,  1.73411,  2.37831,  2.47797,
+  1.34389,  1.45603,  1.66853,  1.8156,  2.24874,  2.4197,
+  1.35602,  1.5593,  1.73128,  1.85333,  2.34397,  2.51476,
+  1.43321,  1.57591,  1.67319,  1.78146,  2.2928,  2.49126,
+  1.35471,  1.6376,  1.87537,  2.16287,  2.40849,  2.56638,
+  1.46466,  1.59144,  2.07122,  2.23546,  2.39889,  2.56349,
+  1.42481,  1.62265,  2.02033,  2.16131,  2.32826,  2.46819,
+  1.36427,  1.51615,  2.01176,  2.10961,  2.3957,  2.55472,
+  1.34268,  1.46052,  2.0389,  2.12298,  2.50665,  2.64345,
+  1.33831,  1.51988,  2.03004,  2.10015,  2.53334,  2.67477,
+  1.32113,  1.54557,  1.97723,  2.12227,  2.55759,  2.68022,
+  1.31509,  1.46711,  1.97243,  2.06854,  2.52684,  2.64563,
+  1.30446,  1.40069,  1.95455,  2.05314,  2.5625,  2.68589,
+  1.26718,  1.37666,  1.88806,  2.02989,  2.54542,  2.66931,
+  1.22501,  1.33934,  1.88732,  1.96524,  2.54351,  2.67229,
+  1.22621,  1.40353,  1.79766,  1.95969,  2.54099,  2.62735,
+  1.34703,  1.60794,  1.96677,  2.18451,  2.47788,  2.60882,
+  1.3321,  1.75596,  1.94842,  2.17671,  2.51339,  2.60137,
+  1.34929,  1.7814,  1.92279,  2.10923,  2.46288,  2.55986,
+  1.36238,  1.69359,  1.88434,  2.08805,  2.52247,  2.61397,
+  1.32029,  1.5103,  1.85775,  2.06543,  2.49473,  2.60556,
+  1.28299,  1.45974,  1.74491,  1.96142,  2.43994,  2.62375,
+  1.25136,  1.38192,  1.67354,  1.7727,  2.32354,  2.66159,
+  1.20426,  1.43515,  1.65423,  1.7378,  2.30506,  2.58156,
+  1.18196,  1.46528,  1.67003,  1.8613,  2.44412,  2.54613,
+  1.34712,  1.62826,  1.93134,  2.12343,  2.46685,  2.59892,
+  1.17048,  1.28493,  1.55274,  1.83255,  2.29979,  2.51981,
+  1.19004,  1.28402,  1.64609,  1.96917,  2.49692,  2.62045,
+  1.25541,  1.38147,  1.78173,  2.09499,  2.43136,  2.59352,
+  1.23188,  1.33417,  1.79625,  2.04,  2.38708,  2.55466,
+  1.18052,  1.30857,  1.81824,  1.97632,  2.2935,  2.4518,
+  1.10256,  1.26632,  1.84425,  1.96176,  2.32484,  2.51408,
+  1.00464,  1.14487,  1.83502,  1.9971,  2.18238,  2.52208,
+  0.956994,  1.21291,  1.94092,  2.06045,  2.31223,  2.44167,
+  0.795434,  1.44428,  1.93242,  2.04716,  2.36568,  2.45052,
+  0.942462,  1.60604,  2.02512,  2.11974,  2.29995,  2.43181,
+  0.812186,  1.46939,  2.07832,  2.17302,  2.39197,  2.47405,
+  0.831008,  1.62061,  2.09294,  2.16773,  2.33486,  2.41672,
+  0.917049,  1.801,  2.12123,  2.19938,  2.34728,  2.44052,
+  0.857286,  1.67915,  2.11243,  2.20307,  2.44474,  2.52921,
+  0.809582,  1.54255,  2.18237,  2.23944,  2.46198,  2.54337,
+  0.912283,  1.7792,  2.16632,  2.25109,  2.46168,  2.57688,
+  0.774827,  1.7702,  2.1792,  2.23961,  2.48732,  2.56023,
+  1.22299,  1.57457,  2.08108,  2.22359,  2.50152,  2.6613,
+  1.39422,  1.69632,  2.03665,  2.27333,  2.5704,  2.68413,
+  1.37077,  1.69891,  2.08266,  2.24567,  2.59879,  2.69545,
+  1.37241,  1.64717,  2.14237,  2.27291,  2.60809,  2.68656,
+  1.34279,  1.69454,  2.12328,  2.25676,  2.57528,  2.69095,
+  1.38055,  1.75068,  2.1234,  2.19974,  2.48804,  2.61024,
+  1.39506,  1.88332,  2.0887,  2.18949,  2.45826,  2.54814,
+  1.41315,  1.87284,  2.02083,  2.16196,  2.39617,  2.48701,
+  1.4031,  1.76424,  1.91125,  2.05585,  2.39101,  2.4846,
+  1.25059,  1.60685,  1.83481,  1.91441,  2.34409,  2.54946,
+  1.17101,  1.40644,  1.69912,  1.8581,  2.35407,  2.47105,
+  1.13269,  1.25187,  1.52135,  1.63829,  2.35528,  2.47061,
+  1.01168,  1.2879,  1.45026,  1.66382,  2.28546,  2.37145,
+  1.03024,  1.20842,  1.36667,  1.55035,  2.33752,  2.4214,
+  0.964915,  1.17119,  1.28816,  1.58842,  2.32729,  2.3883,
+  0.953674,  1.10289,  1.26375,  1.83559,  2.31685,  2.42482,
+  0.886544,  1.07464,  1.24224,  1.96444,  2.29681,  2.41295,
+  0.853009,  1.07708,  1.18453,  1.75232,  2.28304,  2.38922,
+  0.840278,  1.03322,  1.15255,  1.52095,  2.33398,  2.45453,
+  0.91077,  1.08387,  1.22354,  1.66808,  2.34624,  2.51185,
+  0.967915,  1.12182,  1.22026,  1.80659,  2.42113,  2.49818,
+  0.992265,  1.16907,  1.26005,  1.67999,  2.39894,  2.45914,
+  1.06528,  1.23096,  1.32238,  1.75348,  2.3144,  2.41593,
+  1.08131,  1.27178,  1.45801,  1.7294,  2.3323,  2.40512,
+  1.01781,  1.34909,  1.51584,  1.72189,  2.29296,  2.39899,
+  1.09765,  1.33294,  1.57003,  1.77646,  2.37727,  2.46589,
+  1.14764,  1.3025,  1.64016,  1.79704,  2.36388,  2.4748,
+  1.12717,  1.32201,  1.68488,  1.79646,  2.40705,  2.57866,
+  1.15953,  1.26665,  1.70955,  1.83058,  2.43816,  2.57242,
+  1.1371,  1.33151,  1.7494,  1.846,  2.41439,  2.51149,
+  1.12127,  1.3511,  1.72822,  1.84666,  2.44921,  2.56416,
+  1.11868,  1.26154,  1.79446,  1.88577,  2.42901,  2.55277,
+  1.07699,  1.21216,  1.72764,  1.86126,  2.43299,  2.56404,
+  1.08209,  1.2617,  1.76092,  1.85803,  2.31585,  2.57359,
+  1.08635,  1.27906,  1.76312,  1.86419,  2.38079,  2.4853,
+  0.988401,  1.26239,  1.7379,  1.83671,  2.37578,  2.49239,
+  1.07471,  1.1962,  1.67728,  1.80631,  2.3414,  2.56064,
+  1.06786,  1.26529,  1.68935,  1.80299,  2.40195,  2.52406,
+  1.01048,  1.28954,  1.65272,  1.77873,  2.3623,  2.46655,
+  0.97757,  1.26131,  1.57627,  1.74133,  2.29762,  2.40409,
+  1.09718,  1.46442,  1.60666,  1.71761,  2.33071,  2.41207,
+  1.38384,  1.65227,  1.8982,  2.09661,  2.47672,  2.57418,
+  1.27973,  1.70061,  1.89499,  2.02987,  2.46839,  2.58449,
+  1.23667,  1.68331,  1.79106,  1.95337,  2.5331,  2.58708,
+  1.18505,  1.59913,  1.8539,  1.94492,  2.49995,  2.5729,
+  1.16357,  1.30732,  1.87244,  1.95399,  2.54467,  2.62323,
+  1.19097,  1.44925,  1.86329,  1.93767,  2.52527,  2.59997,
+  1.11855,  1.51311,  1.85667,  1.96882,  2.49739,  2.57553,
+  1.15652,  1.63093,  1.84545,  2.05111,  2.44317,  2.53405,
+  1.41004,  1.54198,  2.13551,  2.23561,  2.57541,  2.68055,
+  1.39279,  1.72067,  2.03495,  2.19246,  2.48715,  2.6534,
+  1.58125,  1.83784,  2.10976,  2.18748,  2.4979,  2.66009,
+  1.66308,  1.9013,  2.15166,  2.24829,  2.53479,  2.63979,
+  1.62316,  1.84307,  2.17777,  2.25531,  2.5436,  2.68119,
+  1.53971,  1.84607,  2.11908,  2.31502,  2.60542,  2.69501,
+  1.53269,  1.80536,  2.16618,  2.27652,  2.58208,  2.69532,
+  1.5172,  1.86473,  2.11184,  2.24103,  2.6024,  2.67859,
+  1.481,  1.87977,  2.1834,  2.2585,  2.62458,  2.71471,
+  1.48006,  1.94783,  2.12659,  2.23931,  2.6027,  2.68976,
+  1.61575,  2.02568,  2.18841,  2.29147,  2.6737,  2.72328,
+  1.54669,  2.02367,  2.13758,  2.23388,  2.56357,  2.62736,
+  1.51727,  1.90243,  2.13241,  2.18928,  2.54838,  2.64335,
+  1.49876,  1.60236,  2.15993,  2.27567,  2.54058,  2.68296,
+  1.57357,  1.6552,  2.07174,  2.2146,  2.52345,  2.64214,
+  1.60199,  1.68036,  2.13015,  2.24731,  2.56771,  2.67057,
+  1.63293,  1.73367,  2.1347,  2.25513,  2.55999,  2.68208,
+  1.70743,  1.75206,  2.1397,  2.25206,  2.56764,  2.64791,
+  1.68079,  1.81258,  2.18923,  2.2873,  2.57824,  2.64474,
+  1.74613,  1.77855,  2.11951,  2.28339,  2.59638,  2.68683,
+  1.68024,  1.77494,  2.09785,  2.21399,  2.55851,  2.65628,
+  1.69816,  1.77769,  2.09692,  2.21101,  2.51242,  2.62563,
+  1.75722,  1.8282,  2.09218,  2.21863,  2.4599,  2.65391,
+  1.7683,  1.81576,  2.0446,  2.1744,  2.4698,  2.67439,
+  1.74091,  1.83001,  2.0445,  2.16843,  2.4425,  2.58767,
+  1.72899,  1.80159,  2.0369,  2.13569,  2.483,  2.64735,
+  1.7402,  1.78035,  2.03984,  2.11648,  2.46008,  2.66641,
+  1.67917,  1.81059,  1.9762,  2.08515,  2.33097,  2.5747,
+  1.67538,  1.74168,  1.98661,  2.08699,  2.44484,  2.64839,
+  1.60537,  1.68464,  1.97715,  2.08431,  2.40138,  2.62667,
+  1.59359,  1.66701,  1.99308,  2.09579,  2.47706,  2.66052,
+  1.49544,  1.67749,  1.91544,  2.10752,  2.5041,  2.68752,
+  1.37119,  1.58101,  1.81209,  2.15997,  2.54081,  2.65451,
+  1.3089,  1.65276,  1.8777,  2.10022,  2.49836,  2.63527,
+  1.25755,  1.70119,  1.90866,  2.06398,  2.33088,  2.58848,
+  1.26064,  1.73383,  1.90131,  2.04602,  2.23042,  2.37971,
+  1.19202,  1.69544,  1.86633,  1.96986,  2.13128,  2.36781,
+  1.3313,  1.72762,  1.87569,  1.96723,  2.11549,  2.46165,
+  1.22185,  1.64479,  1.86107,  1.95729,  2.26379,  2.50923,
+  1.29701,  1.68481,  1.82511,  1.98127,  2.3887,  2.49794,
+  1.29299,  1.62169,  1.7955,  1.89158,  2.43094,  2.59724,
+  1.29334,  1.41244,  1.67843,  2.01344,  2.40627,  2.57529,
+  1.35525,  1.47052,  1.74829,  2.04483,  2.41107,  2.59082,
+  1.35208,  1.47438,  1.81195,  2.02853,  2.44538,  2.59798,
+  1.38043,  1.47298,  1.83619,  1.95777,  2.39037,  2.57117,
+  1.41757,  1.51497,  1.83999,  1.97461,  2.38249,  2.51071,
+  1.39633,  1.51162,  1.74391,  2.00952,  2.41409,  2.5335,
+  1.356,  1.5112,  1.77504,  1.97354,  2.4454,  2.56885,
+  1.35748,  1.53331,  1.82063,  1.99833,  2.39546,  2.5737,
+  1.24454,  1.44655,  1.72685,  1.93599,  2.42899,  2.55595,
+  1.20656,  1.36587,  1.51002,  1.80904,  2.46485,  2.52024,
+  1.20471,  1.34027,  1.47715,  1.7318,  2.46108,  2.52582,
+  1.15214,  1.29476,  1.42987,  1.66978,  2.43609,  2.50483,
+  1.12233,  1.28467,  1.44544,  1.8119,  2.44447,  2.53569,
+  1.1671,  1.312,  1.43068,  1.93122,  2.57918,  2.62637,
+  1.14096,  1.25556,  1.41692,  1.91311,  2.46264,  2.55265,
+  1.17538,  1.32509,  1.43414,  1.82628,  2.53411,  2.59969,
+  1.15295,  1.31134,  1.42875,  1.73328,  2.49916,  2.55542,
+  1.20894,  1.31815,  1.45086,  1.63113,  2.48479,  2.56076,
+  1.21498,  1.3123,  1.49697,  1.60268,  2.44106,  2.51374,
+  1.1549,  1.27435,  1.49783,  1.61108,  2.49397,  2.62846,
+  1.22174,  1.32448,  1.52936,  1.6685,  2.49634,  2.57245,
+  1.26548,  1.36044,  1.57445,  1.69829,  2.46587,  2.52945,
+  1.29997,  1.41147,  1.63433,  1.79017,  2.46419,  2.54621,
+  1.29682,  1.4613,  1.67405,  1.8673,  2.47283,  2.54653,
+  1.31923,  1.49303,  1.70292,  1.86718,  2.41758,  2.50385,
+  1.3077,  1.51173,  1.79546,  1.9887,  2.41583,  2.50206,
+  1.34144,  1.56729,  1.84964,  2.05441,  2.36855,  2.48494,
+  1.34609,  1.70986,  1.84782,  2.08987,  2.32039,  2.42693,
+  1.35121,  1.5824,  1.85395,  2.08778,  2.26974,  2.40613,
+  1.40341,  1.68126,  1.93063,  2.06474,  2.3176,  2.44551,
+  1.30356,  1.80043,  1.94655,  2.06478,  2.3479,  2.57565,
+  1.40197,  1.79512,  2.04385,  2.14916,  2.33742,  2.47542,
+  1.48635,  1.89691,  2.03368,  2.16458,  2.42721,  2.51671,
+  1.58122,  1.92036,  2.03292,  2.18664,  2.45883,  2.53417,
+  1.62367,  1.94922,  2.05695,  2.22087,  2.54473,  2.61274,
+  1.72008,  1.91633,  2.06966,  2.31006,  2.50308,  2.59265,
+  1.65207,  1.9939,  2.12217,  2.28232,  2.53373,  2.60413,
+  1.69638,  1.99027,  2.08866,  2.3179,  2.56235,  2.6308,
+  1.68861,  1.97655,  2.0855,  2.35442,  2.4834,  2.56768,
+  1.79189,  1.95662,  2.08476,  2.34413,  2.47321,  2.57802,
+  1.77015,  1.95597,  2.07514,  2.2631,  2.50858,  2.59481,
+  1.68817,  1.95839,  2.09717,  2.23713,  2.44313,  2.55839,
+  1.61409,  1.85811,  1.99613,  2.15125,  2.32732,  2.48534,
+  1.51766,  1.72978,  1.97539,  2.11873,  2.39083,  2.52342,
+  1.57639,  1.76492,  1.93735,  2.15944,  2.35454,  2.47655,
+  1.59652,  1.79672,  1.93068,  2.17377,  2.41526,  2.51519,
+  1.59827,  1.75891,  1.94152,  2.24294,  2.46192,  2.54838,
+  1.56459,  1.66781,  1.91021,  2.20751,  2.43297,  2.56229,
+  1.50226,  1.59876,  1.70104,  1.99352,  2.43166,  2.56861,
+  1.26117,  1.37926,  1.66944,  1.86426,  2.42439,  2.56028,
+  1.18314,  1.29168,  1.49624,  1.77509,  2.41535,  2.57185,
+  1.17686,  1.28064,  1.39729,  1.55628,  2.48261,  2.55691,
+  1.15141,  1.26909,  1.40261,  1.52942,  2.5473,  2.66072,
+  1.13835,  1.27009,  1.3867,  1.65651,  2.51668,  2.57083,
+  1.16764,  1.28839,  1.3794,  1.81595,  2.48874,  2.54402,
+  1.19113,  1.31858,  1.43306,  1.89873,  2.44099,  2.50552,
+  1.23155,  1.33971,  1.50583,  1.86546,  2.40192,  2.56755,
+  1.249,  1.34254,  1.52652,  1.64463,  2.26006,  2.52811,
+  1.29212,  1.38504,  1.56729,  1.92802,  2.3436,  2.52673,
+  1.55306,  1.7312,  1.87558,  2.03762,  2.18958,  2.43362,
+  1.55633,  1.80735,  2.00987,  2.13476,  2.39511,  2.51776,
+  1.7008,  1.863,  2.01606,  2.21287,  2.46583,  2.57661,
+  1.74452,  1.8923,  2.04288,  2.2037,  2.39302,  2.52939,
+  1.61468,  1.86704,  2.02413,  2.17237,  2.40215,  2.56787,
+  1.66255,  1.92647,  2.01622,  2.15368,  2.54468,  2.63661,
+  1.60774,  1.84063,  2.03651,  2.14887,  2.47573,  2.62342,
+  1.5426,  1.78941,  1.98821,  2.1337,  2.50007,  2.62384,
+  1.52049,  1.85402,  1.96628,  2.10023,  2.4655,  2.59099,
+  1.4291,  1.7262,  1.95857,  2.06874,  2.39713,  2.57827,
+  1.23096,  1.48391,  1.90942,  2.03717,  2.27816,  2.44268,
+  1.16547,  1.40247,  1.87767,  1.98503,  2.337,  2.4823,
+  1.06065,  1.34179,  1.89159,  1.9978,  2.34225,  2.47385,
+  1.04598,  1.26441,  1.89288,  2.02811,  2.26571,  2.41834,
+  0.872467,  1.31861,  1.94129,  2.05489,  2.26598,  2.523,
+  0.878165,  1.20878,  1.86352,  2.07417,  2.31989,  2.4605,
+  0.87138,  1.05093,  1.86631,  2.04429,  2.18427,  2.46922,
+  0.814866,  1.20623,  1.93624,  2.04636,  2.24399,  2.39101,
+  0.791495,  1.1548,  1.95086,  2.06223,  2.27019,  2.49712,
+  0.734873,  1.1175,  2.01389,  2.14635,  2.25208,  2.34022,
+  0.717596,  1.11331,  2.14512,  2.21429,  2.35066,  2.43709,
+  0.747897,  1.18189,  1.98264,  2.07339,  2.39106,  2.46122,
+  0.81421,  1.5937,  1.93081,  2.05189,  2.27992,  2.45097,
+  1.008,  1.63525,  1.8487,  1.99829,  2.26496,  2.39937,
+  1.05813,  1.54826,  1.72511,  1.88587,  2.17415,  2.38675,
+  1.06533,  1.44683,  1.76311,  2.06116,  2.39393,  2.53335,
+  1.24544,  1.51311,  1.69987,  1.88597,  2.16373,  2.41256,
+  1.40222,  1.55017,  1.6791,  2.10448,  2.31427,  2.46462,
+  1.43969,  1.56554,  1.74616,  2.17576,  2.35318,  2.44597,
+  1.28279,  1.46757,  1.68979,  2.05702,  2.29957,  2.50654,
+  1.15751,  1.36008,  1.53152,  1.93168,  2.27783,  2.38736,
+  1.12772,  1.28719,  1.42109,  1.84436,  2.28107,  2.38522,
+  1.17251,  1.31751,  1.49783,  1.76833,  2.3271,  2.4534,
+  1.21562,  1.35145,  1.55462,  1.70686,  2.28027,  2.41032,
+  1.16271,  1.31851,  1.56882,  1.75711,  2.22556,  2.32124,
+  1.22115,  1.36407,  1.7282,  1.86724,  2.14964,  2.32343,
+  1.27453,  1.45588,  1.65181,  1.92988,  2.11952,  2.24537,
+  1.32483,  1.46666,  1.83773,  1.98275,  2.16784,  2.29489,
+  1.20741,  1.46374,  1.90723,  2.01094,  2.18761,  2.31538,
+  1.1975,  1.32537,  1.90394,  2.10426,  2.26437,  2.40602,
+  0.964658,  1.42133,  1.80059,  2.07554,  2.24967,  2.39142,
+  0.900184,  1.41949,  1.86053,  2.05217,  2.20467,  2.41473,
+  0.976462,  1.44499,  1.83716,  1.99709,  2.13357,  2.30319,
+  0.943062,  1.5438,  1.91463,  1.99313,  2.18465,  2.34418,
+  0.89678,  1.42697,  1.92355,  2.03999,  2.25792,  2.50452,
+  0.957615,  1.55318,  1.86268,  2.04465,  2.19266,  2.48417,
+  1.02438,  1.62687,  1.89128,  2.04179,  2.30477,  2.61313,
+  1.2607,  1.57098,  1.79692,  1.93891,  2.45798,  2.54369,
+  1.43387,  1.67689,  2.02035,  2.24929,  2.48843,  2.61923,
+  1.42779,  1.60531,  1.99984,  2.19762,  2.47258,  2.62826,
+  1.34494,  1.54775,  2.01991,  2.15346,  2.48252,  2.6649,
+  1.39455,  1.83086,  2.07575,  2.1467,  2.52985,  2.66294,
+  1.39353,  1.57998,  2.00527,  2.06832,  2.59583,  2.67795,
+  1.37167,  1.50166,  2.01236,  2.06929,  2.60572,  2.70121,
+  1.36597,  1.44376,  1.8937,  2.06336,  2.54086,  2.63575,
+  1.39281,  1.47093,  1.92042,  1.98528,  2.61205,  2.67063,
+  1.39358,  1.50234,  1.92649,  2.01951,  2.57154,  2.6457,
+  1.33144,  1.47006,  1.84434,  1.94554,  2.52733,  2.62083,
+  1.28039,  1.38,  1.82279,  1.92768,  2.47072,  2.61404,
+  1.23045,  1.39485,  1.77224,  1.9107,  2.49488,  2.56917,
+  1.10377,  1.421,  1.74216,  1.90103,  2.45853,  2.54496,
+  1.07083,  1.43846,  1.75479,  1.82779,  2.32372,  2.48412,
+  1.02392,  1.52234,  1.71372,  1.83474,  2.2896,  2.49685,
+  1.12384,  1.53995,  1.76628,  1.86662,  2.34998,  2.44122,
+  1.04667,  1.49658,  1.79154,  1.85948,  2.40075,  2.4683,
+  1.03123,  1.5049,  1.71427,  1.94435,  2.36522,  2.45944,
+  1.20118,  1.37012,  1.88263,  2.01133,  2.41129,  2.51029,
+  1.24946,  1.32446,  1.90762,  2.059,  2.44862,  2.55141,
+  1.30858,  1.40302,  1.96116,  2.04859,  2.47571,  2.56247,
+  1.35436,  1.47604,  2.00873,  2.11132,  2.51324,  2.59156,
+  1.41531,  1.55963,  2.02019,  2.10785,  2.50535,  2.59646,
+  1.45215,  1.53696,  2.03346,  2.12047,  2.47346,  2.60024,
+  1.47616,  1.57067,  1.98144,  2.08987,  2.44173,  2.57494,
+  1.53214,  1.60732,  1.99626,  2.09911,  2.44899,  2.57508,
+  1.57825,  1.6709,  1.94645,  2.06793,  2.48457,  2.59603,
+  1.64599,  1.71983,  1.90843,  2.03481,  2.5215,  2.63014,
+  1.6752,  1.73909,  1.85801,  1.95115,  2.54962,  2.66814,
+  1.6988,  1.74067,  1.81622,  1.87221,  2.55299,  2.67504,
+  1.58931,  1.66594,  1.75197,  1.83425,  2.49582,  2.66392,
+  1.44357,  1.53506,  1.6855,  1.78803,  2.39178,  2.64485,
+  1.38939,  1.59756,  1.88429,  2.16105,  2.45363,  2.57728,
+  1.34469,  1.5734,  1.94905,  2.03321,  2.43648,  2.65023,
+  1.34068,  1.44219,  1.90408,  1.99239,  2.42751,  2.60434,
+  1.30157,  1.36352,  1.87021,  1.95339,  2.44581,  2.60937,
+  1.26564,  1.36552,  1.83866,  1.92217,  2.43174,  2.55248,
+  1.29187,  1.45107,  1.77074,  1.90068,  2.38049,  2.47459,
+  1.3198,  1.50206,  1.68621,  1.92201,  2.2912,  2.39261,
+  1.25322,  1.4458,  1.59175,  1.89356,  2.29503,  2.3815,
+  1.17138,  1.37063,  1.52321,  1.82582,  2.33635,  2.39918,
+  1.23899,  1.36509,  1.48683,  1.79013,  2.30251,  2.38422,
+  1.18649,  1.32753,  1.46369,  1.68078,  2.32204,  2.40225,
+  1.16077,  1.2949,  1.46764,  1.61324,  2.21966,  2.32965,
+  1.16797,  1.31227,  1.45879,  1.72547,  2.18251,  2.27065,
+  1.16049,  1.37138,  1.54665,  1.85991,  2.15148,  2.26711,
+  1.06064,  1.44774,  1.58936,  1.76203,  2.18795,  2.31254,
+  1.09687,  1.44937,  1.66994,  1.88079,  2.20516,  2.32292,
+  0.965471,  1.39498,  1.66486,  1.86974,  2.13014,  2.2721,
+  0.992815,  1.27623,  1.73632,  1.88313,  2.19849,  2.29195,
+  0.989087,  1.34899,  1.86928,  1.94503,  2.2171,  2.32962,
+  0.90585,  1.29647,  1.83941,  1.98449,  2.13136,  2.26164,
+  0.913468,  1.3471,  1.97494,  2.05681,  2.23306,  2.3124,
+  0.891335,  1.51815,  1.95606,  2.01705,  2.23425,  2.36954,
+  0.838007,  1.4907,  2.01764,  2.09778,  2.33146,  2.41797,
+  0.918242,  1.41122,  2.04709,  2.15794,  2.31221,  2.4143,
+  0.73747,  1.47534,  2.13171,  2.1951,  2.33607,  2.41009,
+  0.804454,  1.24701,  2.18319,  2.2531,  2.37687,  2.45747,
+  0.910989,  1.12058,  2.03128,  2.13474,  2.30167,  2.40132,
+  0.823657,  1.02371,  1.8993,  2.15349,  2.27816,  2.4689,
+  0.820197,  0.968457,  1.65567,  2.13731,  2.32041,  2.44255,
+  0.901009,  1.04763,  1.78579,  2.12632,  2.24814,  2.41922,
+  0.908944,  1.15154,  1.94127,  2.15376,  2.28778,  2.47786,
+  1.02292,  1.32981,  1.97353,  2.1212,  2.26916,  2.49693,
+  1.00803,  1.17657,  1.83255,  2.13074,  2.26309,  2.48407,
+  1.1484,  1.26162,  1.86817,  2.13834,  2.28791,  2.47577,
+  1.13164,  1.24554,  1.7469,  2.12721,  2.27364,  2.43952,
+  1.10545,  1.23069,  1.75987,  2.02322,  2.2259,  2.48502,
+  1.23228,  1.36348,  1.91488,  2.02165,  2.31404,  2.45593,
+  1.28797,  1.37746,  1.85366,  2.03963,  2.34808,  2.50271,
+  1.28514,  1.52079,  1.95102,  2.05364,  2.36654,  2.48611,
+  1.27636,  1.65661,  1.88233,  2.08463,  2.43062,  2.524,
+  1.3057,  1.53254,  1.86153,  2.02916,  2.43563,  2.51958,
+  1.29572,  1.47484,  1.83837,  2.04501,  2.41302,  2.5453,
+  1.2328,  1.30721,  1.78676,  1.91145,  2.53363,  2.62579,
+  1.10601,  1.25243,  1.73731,  1.8274,  2.39547,  2.65803,
+  1.08032,  1.24974,  1.76381,  1.84223,  2.48808,  2.63797,
+  1.08481,  1.3027,  1.7911,  1.91571,  2.53275,  2.62698,
+  1.02408,  1.39849,  1.75815,  1.94769,  2.53675,  2.6478,
+  1.05255,  1.48652,  1.83597,  2.01313,  2.52654,  2.62152,
+  0.980943,  1.52889,  1.88771,  1.99043,  2.55923,  2.63173,
+  0.954706,  1.35519,  1.89085,  1.96874,  2.5383,  2.6458,
+  0.894853,  1.31642,  1.93192,  2.00063,  2.61782,  2.70696,
+  0.859848,  1.16666,  1.85185,  2.01109,  2.62987,  2.73106,
+  0.817565,  1.16914,  1.97568,  2.11707,  2.59314,  2.68371,
+  0.776768,  0.999874,  1.95167,  2.127,  2.57853,  2.71922,
+  0.750075,  1.10567,  2.01524,  2.09916,  2.46918,  2.63788,
+  0.878438,  1.03962,  2.07882,  2.1891,  2.45317,  2.61062,
+  0.915136,  1.11488,  2.01769,  2.23653,  2.37028,  2.53828,
+  0.82611,  1.20898,  2.06907,  2.15683,  2.33186,  2.46307,
+  0.869876,  1.28956,  2.0617,  2.14305,  2.31374,  2.39581,
+  0.790056,  1.42106,  1.94573,  2.02523,  2.25492,  2.38411,
+  0.782642,  1.67814,  1.92831,  1.98015,  2.1697,  2.29002,
+  0.79594,  1.40966,  1.7678,  1.89476,  2.19165,  2.28019,
+  0.832117,  1.16909,  1.82801,  1.91103,  2.22865,  2.36616,
+  0.862231,  1.1894,  1.75495,  1.92413,  2.31213,  2.41255,
+  1.03477,  1.29047,  1.7835,  1.99616,  2.34376,  2.46273,
+  1.13581,  1.35879,  1.78919,  1.98063,  2.37636,  2.49584,
+  1.3039,  1.415,  1.78751,  1.91844,  2.43546,  2.54775,
+  1.48925,  1.59296,  1.85058,  1.95005,  2.42804,  2.57134,
+  1.63147,  1.74264,  1.88788,  1.99493,  2.49377,  2.61966,
+  1.68385,  1.80038,  1.92661,  2.06405,  2.50915,  2.59263,
+  1.74531,  1.85426,  1.98854,  2.11714,  2.50431,  2.61134,
+  1.76427,  1.89058,  2.03799,  2.1743,  2.50772,  2.60061,
+  1.68017,  1.81737,  1.93711,  2.22898,  2.55014,  2.62331,
+  1.55262,  1.81946,  1.95732,  2.26349,  2.51728,  2.58051,
+  1.55842,  1.78491,  2.02149,  2.23937,  2.54371,  2.63746,
+  1.24066,  1.73929,  1.88981,  2.10508,  2.53244,  2.61823,
+  0.928972,  1.44027,  1.76926,  1.85335,  2.40041,  2.63688,
+  1.05577,  1.48884,  1.75607,  1.83257,  2.20968,  2.65031,
+  1.0133,  1.38103,  1.70409,  1.77271,  2.15549,  2.58513,
+  1.00919,  1.33324,  1.74138,  1.8465,  2.15877,  2.51776,
+  1.00638,  1.5199,  1.81375,  1.91629,  2.40767,  2.58185,
+  1.35773,  1.53055,  1.88364,  2.14151,  2.46327,  2.61463,
+  1.42682,  1.56088,  1.88252,  2.17521,  2.48835,  2.6287,
+  1.31598,  1.57984,  1.85956,  2.08348,  2.41988,  2.56465,
+  1.21305,  1.5389,  1.80025,  1.88207,  2.34157,  2.57461,
+  1.27506,  1.54351,  1.9171,  2.12745,  2.38894,  2.54272,
+  1.43894,  1.69814,  1.85661,  2.07519,  2.26671,  2.43737,
+  1.45433,  1.66376,  1.86982,  2.01141,  2.36627,  2.53339,
+  1.38217,  1.67292,  1.82744,  1.94203,  2.45391,  2.55986,
+  1.40066,  1.58545,  1.84133,  2.00274,  2.427,  2.51776,
+  1.38214,  1.68809,  1.81976,  2.06315,  2.41779,  2.49255,
+  1.2551,  1.60338,  1.75391,  2.04757,  2.45556,  2.56959,
+  1.13478,  1.40915,  1.70528,  1.80211,  2.48803,  2.64714,
+  1.11188,  1.26013,  1.67605,  1.77849,  2.50159,  2.627,
+  1.06035,  1.20881,  1.66035,  1.77686,  2.48876,  2.60446,
+  0.94712,  1.16465,  1.64204,  1.72379,  2.47516,  2.56741,
+  0.902077,  1.2512,  1.66403,  1.76901,  2.499,  2.5767,
+  0.92017,  1.24389,  1.70968,  1.79499,  2.53435,  2.62383,
+  0.93877,  1.26768,  1.72586,  1.87016,  2.54951,  2.6282,
+  0.914357,  1.25432,  1.71291,  1.78474,  2.59043,  2.70748,
+  0.930246,  1.28124,  1.80279,  1.87886,  2.56022,  2.68722,
+  0.95535,  1.14867,  1.81473,  1.90259,  2.55782,  2.68459,
+  0.96833,  1.09859,  1.81344,  1.91188,  2.46314,  2.64649,
+  0.990311,  1.18544,  1.86467,  1.94159,  2.48811,  2.66446,
+  1.1869,  1.59093,  1.95416,  2.0337,  2.59786,  2.66218,
+  1.30264,  1.69442,  1.99744,  2.16905,  2.61741,  2.69308,
+  1.37926,  1.71828,  1.99322,  2.2122,  2.54373,  2.64086,
+  1.40516,  1.78053,  1.99789,  2.15115,  2.55578,  2.63222,
+  1.29777,  1.87826,  2.02027,  2.19057,  2.54647,  2.61734,
+  1.44216,  1.85664,  2.10104,  2.29971,  2.56148,  2.64412,
+  1.37017,  1.78121,  2.11499,  2.25182,  2.44675,  2.54984,
+  1.40345,  1.70357,  2.0793,  2.2214,  2.44877,  2.59398,
+  1.41335,  1.64917,  2.00998,  2.15916,  2.51868,  2.61514,
+  1.32666,  1.71994,  1.95044,  2.02547,  2.52107,  2.63595,
+  1.38595,  1.55275,  1.85678,  1.93751,  2.49665,  2.58016,
+  1.34541,  1.48801,  1.88554,  2.01719,  2.54687,  2.6256,
+  1.33572,  1.42021,  1.78707,  1.97684,  2.50133,  2.64355,
+  1.3038,  1.40827,  1.80145,  1.90147,  2.37505,  2.57595,
+  1.31291,  1.40809,  1.83798,  1.95009,  2.31854,  2.4759,
+  1.19361,  1.29364,  1.81906,  1.97449,  2.46808,  2.58528,
+  1.19153,  1.31147,  1.71163,  1.85459,  2.39504,  2.55402,
+  1.10318,  1.33217,  1.71792,  1.85799,  2.34029,  2.44522,
+  0.996011,  1.23417,  1.75102,  1.86827,  2.28588,  2.40672,
+  1.05531,  1.37824,  1.71212,  1.84167,  2.2067,  2.44054,
+  1.07861,  1.46591,  1.78701,  1.94898,  2.23174,  2.47898,
+  0.98452,  1.42059,  1.8153,  1.92522,  2.26343,  2.43094,
+  0.984574,  1.49518,  1.77419,  1.96413,  2.22166,  2.34685,
+  1.15484,  1.5072,  1.8121,  1.94937,  2.28174,  2.4261,
+  1.17006,  1.42938,  1.74509,  1.93793,  2.23502,  2.37477,
+  1.20649,  1.48753,  1.7673,  2.00984,  2.20705,  2.33947,
+  1.07366,  1.37773,  1.82868,  1.993,  2.13061,  2.25678,
+  1.08845,  1.49539,  1.90777,  1.99687,  2.2139,  2.39049,
+  1.12298,  1.42221,  1.86583,  2.03711,  2.25375,  2.41839,
+  1.13417,  1.38264,  1.80424,  1.9632,  2.16117,  2.4736,
+  1.2454,  1.55261,  1.96081,  2.13469,  2.4536,  2.57754,
+  1.1187,  1.56721,  1.95262,  2.17652,  2.44663,  2.57856,
+  1.14171,  1.6436,  2.01334,  2.27743,  2.55738,  2.63478,
+  1.39251,  1.80792,  2.03934,  2.23792,  2.57802,  2.66829,
+  1.43321,  1.83371,  2.02062,  2.25218,  2.51864,  2.60086,
+  1.37926,  1.71223,  2.025,  2.24296,  2.51553,  2.60248,
+  1.36698,  1.67564,  1.97659,  2.19947,  2.51697,  2.59881,
+  1.35276,  1.80187,  2.03361,  2.18194,  2.49138,  2.58988,
+  1.32366,  1.74357,  2.00964,  2.1227,  2.47452,  2.56638,
+  1.19009,  1.54054,  1.93307,  2.08808,  2.50673,  2.57061,
+  1.51983,  1.76619,  1.906,  2.07675,  2.26142,  2.40768,
+  1.53469,  1.71407,  2.01648,  2.1309,  2.32326,  2.45761,
+  1.52205,  1.79476,  2.05095,  2.21828,  2.40801,  2.53773,
+  1.66536,  1.90687,  2.02566,  2.23238,  2.43013,  2.55064,
+  1.6663,  1.83465,  1.99804,  2.22024,  2.40151,  2.50239,
+  1.52361,  1.73009,  1.86296,  2.1646,  2.46626,  2.54923,
+  1.21612,  1.50347,  1.76046,  1.96747,  2.38172,  2.56435,
+  1.17113,  1.42943,  1.61663,  1.91778,  2.38793,  2.47727,
+  1.0913,  1.35137,  1.56866,  1.7962,  2.43759,  2.51487,
+  1.00128,  1.38691,  1.5396,  1.77505,  2.41327,  2.48215,
+  0.952227,  1.39731,  1.52793,  1.72252,  2.44275,  2.49237,
+  0.824979,  1.38889,  1.56898,  1.73526,  2.40875,  2.47118,
+  0.794444,  1.43306,  1.58885,  1.74958,  2.48937,  2.57636,
+  0.899067,  1.52185,  1.6814,  1.78029,  2.44175,  2.50829,
+  0.922249,  1.46461,  1.59253,  1.82844,  2.41816,  2.47726,
+  0.871556,  1.44442,  1.53832,  1.88901,  2.35369,  2.41254,
+  0.857823,  1.27025,  1.50127,  1.76026,  2.35576,  2.4073,
+  0.846263,  1.17661,  1.48198,  1.61417,  2.36993,  2.48569,
+  0.882414,  1.17609,  1.37797,  1.49739,  2.38001,  2.51651,
+  0.938718,  1.10065,  1.48911,  1.57621,  2.32557,  2.54347,
+  0.932462,  1.10559,  1.29435,  1.47096,  2.40012,  2.55472,
+  0.945253,  1.161,  1.30388,  1.58026,  2.46668,  2.58461,
+  1.01832,  1.21474,  1.33058,  1.68375,  2.48296,  2.55716,
+  1.04824,  1.17548,  1.2581,  1.59909,  2.52145,  2.6425,
+  1.07374,  1.20351,  1.2987,  1.68876,  2.55568,  2.61447,
+  1.09679,  1.26086,  1.3686,  1.75534,  2.49303,  2.60645,
+  1.10564,  1.22703,  1.40439,  1.8497,  2.52331,  2.60157,
+  1.14386,  1.26939,  1.38734,  1.82908,  2.39517,  2.49646,
+  1.09925,  1.22861,  1.34441,  1.66442,  2.44063,  2.51807,
+  1.11618,  1.22832,  1.33295,  1.66731,  2.33167,  2.51226,
+  1.20152,  1.29939,  1.47847,  1.57791,  2.00331,  2.45158,
+  1.16799,  1.29273,  1.47073,  1.81462,  2.14096,  2.43615,
+  1.28052,  1.42488,  1.59521,  1.80388,  2.20583,  2.31538,
+  1.23016,  1.36494,  1.61044,  2.00251,  2.17287,  2.35572,
+  1.30255,  1.40061,  1.73433,  2.074,  2.20855,  2.38927,
+  1.51269,  1.81823,  2.14478,  2.26692,  2.44774,  2.56939,
+  1.50753,  1.76042,  2.16423,  2.27687,  2.47949,  2.62484,
+  1.44651,  1.76044,  2.1147,  2.2567,  2.57257,  2.66147,
+  1.46887,  1.81236,  2.11457,  2.19302,  2.61774,  2.71384,
+  1.44965,  1.77645,  2.0806,  2.21016,  2.54091,  2.71399,
+  1.44125,  1.71952,  2.11461,  2.21869,  2.5113,  2.66005,
+  1.47766,  1.61984,  2.1127,  2.1987,  2.5206,  2.6557,
+  1.53287,  1.71815,  2.13263,  2.2223,  2.55144,  2.66573,
+  1.34103,  1.81458,  2.12504,  2.24586,  2.54798,  2.64959,
+  1.36191,  1.69809,  2.07692,  2.25511,  2.52488,  2.64704,
+  1.31533,  1.59277,  2.10978,  2.21019,  2.51775,  2.66697,
+  1.3828,  1.57159,  2.10684,  2.20406,  2.4952,  2.66142,
+  1.45363,  1.64175,  2.10031,  2.19937,  2.4624,  2.60888,
+  1.3761,  1.64657,  1.98719,  2.21841,  2.41362,  2.52681,
+  1.37284,  1.63246,  2.05624,  2.16372,  2.37619,  2.58687,
+  1.43261,  1.62463,  2.07417,  2.11989,  2.48066,  2.66903,
+  1.41068,  1.6628,  2.06922,  2.13037,  2.58137,  2.714,
+  1.17413,  1.52452,  2.03205,  2.10525,  2.50238,  2.65331,
+  1.15083,  1.24978,  2.00479,  2.15823,  2.31798,  2.58817,
+  1.05764,  1.19972,  2.04367,  2.16548,  2.37102,  2.60817,
+  1.07033,  1.16919,  2.05106,  2.1872,  2.47645,  2.67133,
+  0.989962,  1.10088,  1.95972,  2.10766,  2.45186,  2.65933,
+  0.995945,  1.12508,  1.96773,  2.17105,  2.35276,  2.58638,
+  0.951054,  1.07341,  1.76868,  2.2131,  2.36251,  2.50427,
+  0.912647,  1.06363,  1.87431,  2.20935,  2.34779,  2.51505,
+  0.880146,  1.0577,  1.93951,  2.2982,  2.44787,  2.55972,
+  0.808391,  0.999903,  1.78946,  2.22109,  2.38324,  2.5121,
+  0.872797,  1.05131,  1.90798,  2.34589,  2.55144,  2.62038,
+  0.736864,  0.925226,  2.10155,  2.27386,  2.39295,  2.56886,
+  0.704727,  1.0262,  2.09473,  2.21249,  2.47416,  2.6562,
+  0.793545,  1.02948,  1.90102,  2.33368,  2.65025,  2.72142,
+  0.890709,  1.27007,  2.13985,  2.23832,  2.54438,  2.71132,
+  0.971655,  1.31769,  2.24547,  2.35109,  2.63196,  2.71126,
+  1.08079,  1.55577,  2.01062,  2.24599,  2.52841,  2.64489,
+  1.40951,  1.76932,  2.1067,  2.28426,  2.51225,  2.63834,
+  1.24844,  1.66199,  2.03514,  2.28324,  2.53429,  2.64733,
+  0.95246,  1.1238,  2.10348,  2.25807,  2.39474,  2.60457,
+  0.989645,  1.18166,  2.02343,  2.23737,  2.36952,  2.52253,
+  0.926042,  1.34812,  1.94934,  2.06208,  2.34696,  2.44908,
+  0.919696,  1.4053,  1.83405,  2.0997,  2.37621,  2.49339,
+  1.00081,  1.37165,  1.83665,  2.2241,  2.41011,  2.5393,
+  1.20009,  1.43679,  1.83915,  2.17928,  2.39885,  2.49843,
+  1.22352,  1.48641,  1.94399,  2.25226,  2.40733,  2.54068,
+  1.11367,  1.47721,  1.84416,  2.21801,  2.38133,  2.48688,
+  1.13811,  1.49875,  1.98095,  2.29747,  2.45785,  2.56077,
+  1.14615,  1.61454,  1.8989,  2.23248,  2.41657,  2.51096,
+  1.11967,  1.58992,  1.82441,  2.11191,  2.35476,  2.45328,
+  1.03204,  1.58942,  1.85285,  2.14299,  2.324,  2.47294,
+  0.989427,  1.52898,  1.91464,  2.17919,  2.37674,  2.49437,
+  1.09575,  1.49456,  1.86612,  2.13681,  2.28371,  2.46406,
+  0.834557,  1.46372,  1.88257,  2.15093,  2.37864,  2.46309,
+  0.835589,  1.29607,  1.77137,  2.09878,  2.28624,  2.42638,
+  0.806577,  1.40333,  1.68522,  2.04095,  2.23574,  2.3564,
+  0.800011,  1.38309,  1.81416,  1.95993,  2.30958,  2.38679,
+  0.804745,  1.31821,  1.82136,  1.9087,  2.23513,  2.42714,
+  0.895849,  1.36723,  1.86481,  1.97967,  2.32424,  2.42079,
+  0.82739,  1.42508,  1.76716,  2.05819,  2.37623,  2.46943,
+  0.917915,  1.49792,  1.85534,  1.98721,  2.31538,  2.45164,
+  0.940855,  1.40956,  1.78919,  1.98853,  2.33667,  2.53469,
+  0.972711,  1.2917,  1.78694,  1.91488,  2.32326,  2.40549,
+  0.993281,  1.36882,  1.80724,  1.95862,  2.35727,  2.45928,
+  1.07469,  1.34931,  1.84084,  1.95484,  2.26908,  2.38406,
+  1.1006,  1.21857,  1.75613,  1.90019,  2.27787,  2.40621,
+  1.16562,  1.31369,  1.8437,  1.96222,  2.1571,  2.34291,
+  1.15777,  1.37236,  1.87996,  1.99193,  2.25808,  2.39087,
+  1.28609,  1.78099,  1.9597,  2.11887,  2.32454,  2.43759,
+  1.45517,  1.73815,  2.09889,  2.23501,  2.42846,  2.53971,
+  1.50025,  1.68426,  2.161,  2.27259,  2.39908,  2.51033,
+  1.48567,  1.8464,  2.19572,  2.30566,  2.54628,  2.65059,
+  1.72782,  2.01371,  2.16728,  2.30421,  2.58661,  2.65216,
+  1.67677,  1.96053,  2.21701,  2.36881,  2.59828,  2.68162,
+  1.63196,  1.91575,  2.22704,  2.33518,  2.6031,  2.71022,
+  1.66386,  1.97302,  2.12471,  2.22235,  2.66048,  2.72432,
+  1.54201,  1.92958,  2.0756,  2.17063,  2.62855,  2.70775,
+  1.50969,  1.70605,  2.05691,  2.19767,  2.57833,  2.6539,
+  1.48207,  1.67373,  2.13105,  2.19487,  2.58632,  2.69029,
+  1.42345,  1.64327,  2.09232,  2.17894,  2.5272,  2.63675,
+  1.35515,  1.56517,  2.02393,  2.23649,  2.53832,  2.65549,
+  1.32842,  1.55398,  2.08156,  2.16192,  2.47274,  2.65693,
+  1.33076,  1.41904,  2.02671,  2.12905,  2.368,  2.57102,
+  1.27065,  1.37759,  2.02595,  2.14013,  2.38924,  2.57594,
+  1.23682,  1.34543,  2.02239,  2.10985,  2.47813,  2.63391,
+  1.22208,  1.32043,  1.93967,  2.02174,  2.43681,  2.62853,
+  1.25217,  1.35827,  1.97262,  2.07935,  2.37145,  2.59893,
+  1.26623,  1.4702,  1.93045,  2.14581,  2.47186,  2.61815,
+  1.33228,  1.54641,  2.02572,  2.21952,  2.46462,  2.64511,
+  1.4186,  1.64948,  2.00831,  2.12811,  2.48988,  2.67687,
+  1.45568,  1.68468,  1.98898,  2.15265,  2.4704,  2.65153,
+  1.44749,  1.60065,  1.9359,  2.27176,  2.51299,  2.63183,
+  1.44477,  1.55636,  2.02038,  2.28232,  2.47577,  2.61234,
+  1.38748,  1.48741,  2.02468,  2.24466,  2.44505,  2.58283,
+  1.35392,  1.44328,  1.95756,  2.17131,  2.33611,  2.56008,
+  1.36979,  1.44771,  2.00618,  2.19142,  2.40471,  2.60473,
+  1.42596,  1.50428,  2.07231,  2.17818,  2.41766,  2.60341,
+  1.44024,  1.5405,  2.0824,  2.21198,  2.37707,  2.63732,
+  1.49701,  1.58268,  2.05652,  2.17217,  2.38928,  2.59384,
+  1.50496,  1.58456,  1.98409,  2.14933,  2.36756,  2.55972,
+  1.51904,  1.60399,  1.9938,  2.10993,  2.32726,  2.59969,
+  1.56956,  1.65105,  1.98894,  2.11673,  2.34577,  2.56992,
+  1.56989,  1.68368,  1.98057,  2.18292,  2.35723,  2.58728,
+  1.60707,  1.7127,  1.95147,  2.12568,  2.30717,  2.54725,
+  1.64523,  1.7366,  1.95236,  2.13149,  2.37622,  2.60646,
+  1.66961,  1.76398,  1.97965,  2.17323,  2.33235,  2.51667,
+  1.63244,  1.75887,  1.9808,  2.12427,  2.2859,  2.44383,
+  1.55741,  1.6677,  1.90206,  2.10693,  2.26086,  2.48392,
+  1.47042,  1.68895,  1.84638,  2.03283,  2.18513,  2.37587,
+  1.42194,  1.53148,  1.82567,  2.02659,  2.18038,  2.36012,
+  1.38564,  1.60616,  1.84636,  2.07139,  2.4885,  2.60745,
+  1.35971,  1.57766,  1.8971,  2.11196,  2.47111,  2.603,
+  1.33945,  1.54264,  1.93397,  2.13374,  2.45491,  2.58319,
+  1.32581,  1.69176,  2.08023,  2.16421,  2.47416,  2.60522,
+  1.34715,  1.6247,  2.07411,  2.2144,  2.43059,  2.56295,
+  1.31486,  1.54184,  1.96763,  2.16414,  2.37269,  2.60652,
+  1.3129,  1.53408,  1.91728,  2.08995,  2.41161,  2.57067,
+  1.28302,  1.5574,  1.93788,  2.10334,  2.52062,  2.6237,
+  1.13883,  1.33747,  1.87109,  1.97275,  2.43348,  2.64765,
+  1.15594,  1.28112,  1.83135,  1.91924,  2.2666,  2.60094,
+  1.16684,  1.27382,  1.8432,  1.94603,  2.31838,  2.57879,
+  1.17229,  1.27501,  1.83258,  2.02592,  2.35381,  2.62469,
+  1.08216,  1.26544,  1.89236,  1.98901,  2.38316,  2.60142,
+  1.0919,  1.20882,  1.83501,  2.03446,  2.39472,  2.5629,
+  1.09883,  1.19949,  1.75765,  2.06589,  2.3904,  2.57889,
+  1.1328,  1.24439,  1.87662,  2.07155,  2.33918,  2.53792,
+  1.1806,  1.25947,  1.82316,  2.09506,  2.2569,  2.54272,
+  1.18699,  1.31291,  1.80079,  2.10504,  2.36699,  2.49608,
+  1.26639,  1.37714,  1.81043,  2.11327,  2.32962,  2.53315,
+  1.32359,  1.40452,  1.90424,  2.14593,  2.38611,  2.58094,
+  1.35217,  1.4514,  1.94982,  2.07705,  2.39082,  2.53857,
+  1.34386,  1.45223,  1.88989,  2.02674,  2.31748,  2.48249,
+  1.24481,  1.37885,  1.79256,  1.98674,  2.42257,  2.53695,
+  1.12462,  1.2536,  1.70382,  1.95132,  2.43964,  2.54515,
+  0.995104,  1.41175,  1.72851,  1.86164,  2.4566,  2.54496,
+  1.00107,  1.40911,  1.79773,  1.89757,  2.40948,  2.55532,
+  1.03398,  1.42816,  1.78694,  1.88029,  2.32636,  2.50316,
+  0.970169,  1.32072,  1.71664,  1.84157,  2.2202,  2.38892,
+  0.930477,  1.37338,  1.7984,  1.90473,  2.30579,  2.5253,
+  0.939935,  1.41846,  1.7727,  1.87809,  2.36749,  2.46153,
+  0.949116,  1.52711,  1.7659,  1.84073,  2.16493,  2.47434,
+  0.993353,  1.62934,  1.81344,  1.91022,  2.10077,  2.4929,
+  1.01383,  1.54962,  1.79683,  1.89194,  2.23976,  2.55635,
+  0.970121,  1.5098,  1.83401,  1.93898,  2.33857,  2.50435,
+  0.947238,  1.36138,  1.78355,  1.98471,  2.4239,  2.54718,
+  0.980991,  1.38878,  1.78331,  2.13171,  2.45463,  2.55869,
+  1.00267,  1.40234,  1.80719,  2.02446,  2.46442,  2.55428,
+  1.0107,  1.40419,  1.87256,  2.07936,  2.47933,  2.56962,
+  0.972976,  1.3758,  1.84337,  1.9807,  2.51361,  2.57827,
+  0.932062,  1.27768,  1.85113,  1.98588,  2.46629,  2.56626,
+  0.938577,  1.18115,  1.83396,  1.96503,  2.45801,  2.55053,
+  0.940095,  1.14545,  1.79669,  2.07827,  2.4829,  2.61063,
+  0.909789,  1.07408,  1.7174,  2.13911,  2.46252,  2.57226,
+  0.882446,  1.06665,  1.72956,  2.28466,  2.4789,  2.55502,
+  0.938178,  1.1215,  1.82849,  2.23404,  2.47478,  2.5571,
+  0.917165,  1.28307,  1.7795,  2.10029,  2.47583,  2.59018,
+  1.06294,  1.34904,  1.76276,  2.1183,  2.50481,  2.60679,
+  1.18696,  1.4619,  1.88904,  2.11274,  2.48132,  2.62131,
+  1.48072,  1.61923,  1.97948,  2.1771,  2.43648,  2.57898,
+  1.44872,  1.56634,  1.88013,  2.13853,  2.33968,  2.55459,
+  1.40799,  1.61355,  1.82893,  2.0527,  2.3445,  2.53808,
+  1.61602,  1.69101,  1.85635,  1.98008,  2.54825,  2.63776,
+  1.62817,  1.68416,  1.88615,  2.01287,  2.56377,  2.62158,
+  1.59574,  1.68801,  1.9354,  2.02581,  2.48363,  2.61682,
+  1.64156,  1.70866,  1.95546,  2.04699,  2.51983,  2.64574,
+  1.67367,  1.75221,  1.95129,  2.08092,  2.48739,  2.64072,
+  1.65642,  1.73624,  1.99136,  2.09832,  2.57191,  2.67683,
+  1.65982,  1.73245,  1.95125,  2.07702,  2.58164,  2.69352,
+  1.6548,  1.71621,  1.96664,  2.04423,  2.56325,  2.6802,
+  1.60273,  1.68261,  1.91741,  1.99483,  2.53109,  2.67329,
+  1.58255,  1.63953,  1.9261,  1.99207,  2.53207,  2.69711,
+  1.46237,  1.585,  1.8183,  1.89755,  2.55713,  2.70626,
+  1.4532,  1.55073,  1.81519,  1.91646,  2.39997,  2.66768,
+  1.41939,  1.55772,  1.78444,  1.90918,  2.51138,  2.66998,
+  1.39516,  1.53982,  1.84748,  1.93084,  2.58396,  2.70362,
+  1.34885,  1.61088,  1.95815,  2.04307,  2.58609,  2.66435,
+  1.37239,  1.65814,  1.95866,  2.18944,  2.45048,  2.65032,
+  1.35259,  1.52809,  1.92314,  2.19484,  2.42773,  2.56214,
+  1.38093,  1.61227,  1.99338,  2.17611,  2.50893,  2.63506,
+  1.42958,  1.68659,  2.01713,  2.17256,  2.48642,  2.60927,
+  1.39212,  1.64104,  1.95208,  2.06507,  2.42122,  2.57491,
+  1.39959,  1.78826,  1.95209,  2.09858,  2.48993,  2.62939,
+  1.38376,  1.66244,  1.9831,  2.11224,  2.5328,  2.63181,
+  1.37273,  1.67362,  1.91212,  2.13425,  2.433,  2.61228,
+  1.39603,  1.64262,  1.96263,  2.19739,  2.52132,  2.66069,
+  1.37936,  1.62399,  2.0694,  2.24312,  2.56203,  2.66844,
+  1.33867,  1.61863,  2.04204,  2.19512,  2.57016,  2.6991,
+  1.29412,  1.71208,  2.05016,  2.12013,  2.60784,  2.68169,
+  1.29325,  1.59625,  1.99341,  2.06004,  2.58308,  2.66414,
+  1.20992,  1.36267,  1.95512,  2.02835,  2.51296,  2.6258,
+  1.3817,  1.70662,  2.00317,  2.14647,  2.50003,  2.61301,
+  1.20467,  1.73456,  1.9288,  2.10969,  2.4769,  2.54909,
+  1.11449,  1.69632,  1.88882,  2.04367,  2.53927,  2.63717,
+  1.11931,  1.60146,  1.84673,  2.08566,  2.57754,  2.64535,
+  1.12875,  1.53118,  1.85828,  2.14677,  2.59635,  2.68872,
+  1.13025,  1.67465,  1.83066,  2.17211,  2.56255,  2.67283,
+  1.10077,  1.64441,  1.83323,  2.04061,  2.59933,  2.65229,
+  1.06697,  1.5306,  1.76863,  2.00332,  2.61732,  2.67806,
+  1.06312,  1.46936,  1.79782,  1.88185,  2.56819,  2.67915,
+  1.17729,  1.70328,  1.86551,  2.06104,  2.48107,  2.58144,
+  1.40413,  1.6575,  1.92706,  2.18185,  2.45741,  2.58043,
+  1.42836,  1.66354,  1.98499,  2.18345,  2.45866,  2.56949,
+  1.4032,  1.66715,  1.95509,  2.14645,  2.46264,  2.56266,
+  1.23413,  1.59785,  1.91775,  2.03444,  2.40755,  2.56026,
+  1.22453,  1.36863,  1.84807,  1.92472,  2.49495,  2.67021,
+  1.21477,  1.58834,  1.76581,  2.00386,  2.52678,  2.63596,
+  1.26488,  1.63647,  1.82522,  2.07706,  2.56349,  2.67929,
+  1.26961,  1.58898,  1.78218,  2.09502,  2.62041,  2.69179,
+  1.29641,  1.50434,  1.80291,  2.01338,  2.60569,  2.68162,
+  1.33438,  1.52077,  1.79661,  1.96388,  2.60042,  2.70374,
+  1.39757,  1.60058,  1.84597,  1.94012,  2.61622,  2.69611,
+  1.43088,  1.55907,  1.79924,  1.99405,  2.59895,  2.6747,
+  1.48212,  1.58304,  1.80751,  1.98143,  2.57538,  2.68473,
+  1.46434,  1.56562,  1.77603,  1.91763,  2.575,  2.65927,
+  1.4554,  1.53823,  1.73066,  1.88207,  2.56375,  2.66044,
+  1.49958,  1.58442,  1.68807,  1.89207,  2.5871,  2.68867,
+  1.47976,  1.5737,  1.69519,  2.02444,  2.55818,  2.63904,
+  1.45227,  1.54712,  1.75057,  2.07203,  2.53701,  2.67379,
+  1.44738,  1.56304,  1.79438,  2.14163,  2.35339,  2.50255,
+  1.35172,  1.45071,  1.73023,  1.99189,  2.29835,  2.46355,
+  1.31876,  1.41462,  1.64199,  1.94834,  2.32625,  2.47429,
+  1.21205,  1.34623,  1.6851,  1.95989,  2.32224,  2.51295,
+  1.20902,  1.30295,  1.63462,  1.93085,  2.28291,  2.50754,
+  1.18895,  1.29282,  1.66566,  2.17785,  2.37356,  2.47429,
+  1.25754,  1.45115,  1.83601,  2.16148,  2.44729,  2.59664,
+  1.25342,  1.3702,  1.83372,  2.24474,  2.47977,  2.57602,
+  1.17995,  1.30201,  1.59215,  2.15158,  2.45596,  2.51812,
+  1.11448,  1.25765,  1.41158,  2.04236,  2.54829,  2.62041,
+  1.09999,  1.30707,  1.40717,  2.15942,  2.58591,  2.64936,
+  1.13115,  1.24686,  1.40128,  2.1166,  2.48376,  2.54666,
+  1.17377,  1.34087,  1.4499,  2.0937,  2.56103,  2.62648,
+  1.18957,  1.3462,  1.46559,  2.00354,  2.51775,  2.5757,
+  1.21797,  1.30299,  1.56949,  2.02897,  2.45573,  2.55014,
+  1.23191,  1.39323,  1.52046,  1.95573,  2.47623,  2.64224,
+  1.27718,  1.45114,  1.59102,  1.92599,  2.45809,  2.56656,
+  1.21624,  1.48312,  1.68868,  1.98897,  2.45463,  2.59962,
+  1.18429,  1.55304,  1.83889,  2.10027,  2.38501,  2.55005,
+  1.23917,  1.79282,  1.95907,  2.1826,  2.44529,  2.52957,
+  1.62457,  1.86085,  2.12033,  2.21992,  2.42941,  2.5941,
+  1.75324,  1.88933,  2.13652,  2.25457,  2.43633,  2.56246,
+  1.75727,  1.95692,  2.24234,  2.36011,  2.49374,  2.58763,
+  1.80684,  1.9852,  2.19776,  2.33868,  2.49634,  2.60068,
+  1.85991,  2.03042,  2.28254,  2.396,  2.54859,  2.63263,
+  1.7711,  1.89613,  2.30676,  2.42126,  2.53834,  2.62596,
+  1.50565,  1.89323,  2.01933,  2.32579,  2.48797,  2.58553,
+  1.18914,  1.7711,  1.91507,  2.25487,  2.53443,  2.61278,
+  1.104,  1.64935,  1.83499,  1.93594,  2.53413,  2.652,
+  1.07901,  1.52244,  1.76728,  1.93497,  2.52313,  2.59639,
+  1.10621,  1.60804,  1.75144,  2.00839,  2.49173,  2.57715,
+  1.22513,  1.59727,  1.85783,  2.10361,  2.46542,  2.59305,
+  1.37537,  1.61836,  1.93052,  2.21445,  2.44556,  2.5762,
+  1.42999,  1.69897,  1.98214,  2.23334,  2.49044,  2.60535,
+  1.4828,  1.67946,  1.99776,  2.2224,  2.46458,  2.58682,
+  1.408,  1.67664,  1.97085,  2.22109,  2.44036,  2.59243,
+  1.2799,  1.6188,  1.92099,  2.16109,  2.43881,  2.62742,
+  0.936959,  1.31029,  1.66337,  2.0101,  2.51599,  2.59778,
+  1.01466,  1.40151,  1.59008,  2.08087,  2.55691,  2.62215,
+  1.04365,  1.38457,  1.5715,  1.98823,  2.56866,  2.64789,
+  1.10727,  1.41397,  1.56206,  1.87714,  2.55472,  2.63729,
+  1.17948,  1.46739,  1.605,  1.839,  2.52348,  2.6405,
+  1.21832,  1.41202,  1.59163,  1.79653,  2.5198,  2.66057,
+  1.30537,  1.42738,  1.61458,  1.76369,  2.49727,  2.65779,
+  1.33854,  1.45634,  1.6422,  1.86235,  2.44879,  2.63162,
+  1.32868,  1.44222,  1.57523,  1.85891,  2.47066,  2.57043,
+  1.35122,  1.46628,  1.60143,  1.86374,  2.42525,  2.50034,
+  1.36091,  1.47648,  1.62462,  1.83211,  2.48627,  2.56333,
+  1.40173,  1.49988,  1.6134,  1.74973,  2.42322,  2.59141,
+  1.26155,  1.40299,  1.52378,  1.80204,  2.49974,  2.60553,
+  1.16,  1.46705,  1.6056,  1.78769,  2.50805,  2.55736,
+  1.27952,  1.53509,  1.62057,  1.75862,  2.40962,  2.67642,
+  1.16136,  1.50546,  1.6262,  1.7331,  2.39883,  2.61748,
+  1.18463,  1.52853,  1.61429,  1.69821,  2.35034,  2.6671,
+  1.11735,  1.53807,  1.65845,  1.75962,  2.28126,  2.58068,
+  1.10984,  1.49283,  1.70197,  1.78983,  2.15124,  2.48973,
+  1.01023,  1.46712,  1.63109,  1.88642,  2.42002,  2.52278,
+  0.950861,  1.33689,  1.617,  1.78955,  2.44962,  2.52889,
+  1.02847,  1.3481,  1.57189,  1.88039,  2.54391,  2.60801,
+  1.11075,  1.41566,  1.69055,  2.00551,  2.55818,  2.6501,
+  1.11015,  1.43266,  1.6694,  1.90159,  2.51693,  2.60274,
+  1.06783,  1.54338,  1.71944,  1.979,  2.54367,  2.61757,
+  1.42254,  1.70106,  1.94043,  2.32706,  2.55761,  2.64296,
+  1.38612,  1.78193,  2.04068,  2.38389,  2.57395,  2.63346,
+  1.51277,  1.69633,  2.1845,  2.29598,  2.57899,  2.67726,
+  1.57185,  1.70524,  2.22523,  2.31919,  2.5426,  2.67616,
+  1.51491,  1.84429,  2.24734,  2.36159,  2.52907,  2.6533,
+  1.60358,  1.94842,  2.27181,  2.4296,  2.52821,  2.61773,
+  1.62041,  2.02418,  2.37902,  2.47798,  2.62296,  2.67076,
+  1.57882,  1.90635,  2.23831,  2.37884,  2.55696,  2.64712,
+  1.61114,  1.90067,  2.18578,  2.31738,  2.51701,  2.61014,
+  1.55461,  1.94143,  2.13305,  2.24986,  2.49176,  2.57161,
+  1.46962,  1.9189,  2.09418,  2.22518,  2.49035,  2.56434,
+  1.33537,  1.69721,  2.01709,  2.23232,  2.47434,  2.57102,
+  1.22194,  1.51906,  1.81406,  2.1294,  2.45829,  2.56013,
+  1.19335,  1.42604,  1.73164,  2.00909,  2.48569,  2.5661,
+  1.14086,  1.30414,  1.72407,  1.96212,  2.45682,  2.67358,
+  1.17199,  1.317,  1.75694,  2.05081,  2.52062,  2.67935,
+  1.13514,  1.41021,  1.71529,  2.0926,  2.49945,  2.61771,
+  1.11453,  1.48721,  1.5954,  2.01378,  2.53196,  2.6284,
+  1.18516,  1.39989,  1.58265,  2.19579,  2.51838,  2.58247,
+  1.10455,  1.42368,  1.65629,  2.26253,  2.59319,  2.66401,
+  1.1643,  1.59699,  1.71775,  2.20785,  2.56315,  2.6214,
+  1.02259,  1.59646,  1.83176,  2.28798,  2.51904,  2.58042,
+  0.920067,  1.6565,  1.82922,  2.20717,  2.5356,  2.58254,
+  0.940069,  1.57744,  1.96057,  2.18925,  2.48282,  2.54933,
+  0.824619,  1.70849,  1.93223,  2.18861,  2.55188,  2.60548,
+  0.819752,  1.68897,  1.95061,  2.08345,  2.46319,  2.51587,
+  0.820934,  1.71848,  2.02163,  2.15842,  2.52112,  2.57629,
+  0.860984,  1.61569,  2.04686,  2.14622,  2.46989,  2.57106,
+  0.7224,  1.64737,  1.97316,  2.0661,  2.43884,  2.60907,
+  0.853506,  1.57795,  1.94985,  2.08284,  2.44874,  2.51242,
+  0.745605,  1.46451,  1.99332,  2.07751,  2.46918,  2.53247,
+  0.710718,  1.53369,  1.89005,  2.01388,  2.4256,  2.51639,
+  0.877569,  1.51198,  1.8316,  2.0319,  2.44162,  2.51744,
+  1.25962,  1.51952,  1.8797,  2.13883,  2.45029,  2.61407,
+  1.32666,  1.6701,  1.91934,  2.14837,  2.36293,  2.46445,
+  1.43771,  1.67164,  1.95505,  2.16671,  2.40595,  2.55752,
+  1.60387,  1.74029,  1.98995,  2.19878,  2.46753,  2.58565,
+  1.6385,  1.74325,  2.05109,  2.14971,  2.46263,  2.56933,
+  1.63183,  1.72177,  2.00292,  2.13115,  2.43893,  2.56922,
+  1.60316,  1.76319,  2.08219,  2.17477,  2.37672,  2.50226,
+  1.63098,  1.70394,  2.00922,  2.14927,  2.36918,  2.58057,
+  1.5766,  1.65869,  1.92294,  2.12495,  2.44873,  2.57827,
+  1.51627,  1.63071,  1.8608,  2.12704,  2.4444,  2.58228,
+  1.45888,  1.54763,  1.79608,  2.04697,  2.37806,  2.53559,
+  1.37666,  1.51251,  1.73356,  2.09821,  2.36177,  2.45214,
+  1.13475,  1.32018,  1.58255,  2.05289,  2.44906,  2.52706,
+  1.07945,  1.16406,  1.57337,  2.22076,  2.5003,  2.56093,
+  1.06047,  1.18642,  1.45666,  2.15579,  2.437,  2.5269,
+  0.974645,  1.13281,  1.56353,  2.08986,  2.50461,  2.57178,
+  0.925733,  1.04903,  1.55569,  2.09544,  2.54168,  2.61417,
+  1.01286,  1.15468,  1.28381,  2.12616,  2.55879,  2.59581,
+  0.970704,  1.08889,  1.3988,  1.96967,  2.51746,  2.62149,
+  0.99667,  1.1556,  1.28423,  1.96774,  2.47805,  2.53675,
+  1.06187,  1.17276,  1.29685,  1.89013,  2.46531,  2.55049,
+  0.971133,  1.1469,  1.42509,  1.82366,  2.3102,  2.51319,
+  1.12232,  1.24695,  1.57393,  1.94586,  2.35067,  2.54611,
+  1.13044,  1.2818,  1.71175,  2.05285,  2.47117,  2.56897,
+  1.28579,  1.42518,  1.8744,  2.08523,  2.42611,  2.57699,
+  1.27354,  1.49021,  1.87877,  2.10625,  2.40245,  2.54437,
+  1.22424,  1.46248,  1.90461,  2.12819,  2.41656,  2.57002,
+  1.25206,  1.44985,  1.80251,  2.11987,  2.41888,  2.5188,
+  1.32712,  1.41759,  1.78996,  2.17493,  2.34065,  2.46871,
+  1.34678,  1.43555,  1.73431,  2.03604,  2.35655,  2.53105,
+  1.23582,  1.31596,  1.59712,  1.89787,  2.28422,  2.57595,
+  0.955415,  1.30377,  1.56019,  1.73007,  2.44977,  2.64812,
+  0.909089,  1.47167,  1.62448,  1.89097,  2.38965,  2.62795,
+  0.919631,  1.36687,  1.50602,  1.84259,  2.342,  2.55449,
+  0.855197,  1.27967,  1.53955,  1.68852,  2.38691,  2.50206,
+  0.807057,  1.13562,  1.5416,  1.6813,  2.24391,  2.51087,
+  0.849115,  1.19024,  1.44993,  1.54139,  2.30258,  2.6556,
+  0.832569,  1.27336,  1.59248,  1.79281,  2.28417,  2.49848,
+  0.835449,  1.16892,  1.54463,  1.71893,  2.42389,  2.63262,
+  0.826578,  1.27619,  1.40786,  1.66029,  2.37804,  2.47453,
+  0.873632,  1.36031,  1.50287,  1.75833,  2.5708,  2.71226,
+  0.82832,  1.28463,  1.46241,  1.6242,  2.57586,  2.70561,
+  0.86693,  1.13331,  1.25406,  1.42989,  2.49929,  2.56231,
+  0.807119,  1.21808,  1.34601,  1.54062,  2.48761,  2.6331,
+  0.98368,  1.14658,  1.33665,  1.47931,  2.32716,  2.61436,
+  0.991742,  1.17073,  1.29617,  1.48561,  2.54305,  2.66382,
+  0.857243,  1.17219,  1.29859,  1.6239,  2.58125,  2.67565,
+  1.02446,  1.24516,  1.33583,  1.92396,  2.62349,  2.68982,
+  1.03526,  1.29306,  1.41981,  1.88269,  2.47498,  2.67367,
+  0.98116,  1.23984,  1.33455,  1.62845,  2.54405,  2.68174,
+  0.948338,  1.22739,  1.3601,  1.57206,  2.44798,  2.66861,
+  1.09712,  1.2561,  1.36219,  1.63254,  2.50779,  2.65642,
+  1.06074,  1.284,  1.52793,  1.67627,  2.54094,  2.63814,
+  0.999111,  1.2307,  1.53126,  1.64398,  2.37306,  2.63434,
+  0.900037,  1.35716,  1.5199,  1.69115,  2.33345,  2.6059,
+  0.906535,  1.20048,  1.61525,  1.71596,  2.28887,  2.60957,
+  0.841267,  1.3377,  1.72119,  1.79912,  2.17636,  2.62724,
+  0.950819,  1.50712,  1.71882,  1.82673,  2.05053,  2.48989,
+  0.922437,  1.44759,  1.83206,  1.92051,  2.14899,  2.50957,
+  0.797637,  1.12047,  1.75627,  1.94611,  2.20911,  2.53594,
+  0.821846,  1.16874,  1.83791,  1.97773,  2.36161,  2.64241,
+  0.802821,  1.39464,  1.94559,  2.03152,  2.33749,  2.58995,
+  0.808599,  1.21429,  1.87853,  2.00233,  2.28022,  2.57778,
+  0.825133,  1.3293,  1.89662,  1.97956,  2.45575,  2.5731,
+  0.847939,  1.23595,  1.89729,  2.01661,  2.42221,  2.65115,
+  0.793266,  1.31179,  1.88526,  1.97487,  2.49392,  2.69992,
+  0.835729,  1.41812,  1.83973,  1.90323,  2.50796,  2.64513,
+  0.84938,  1.4762,  1.83681,  1.97738,  2.32134,  2.5611,
+  0.77457,  1.28461,  1.75819,  1.86442,  2.36773,  2.5612,
+  0.896154,  1.46644,  1.77022,  1.87135,  2.58655,  2.68848,
+  1.0978,  1.5765,  1.74232,  1.91022,  2.16067,  2.65845,
+  0.95072,  1.45287,  1.76016,  1.93477,  2.19628,  2.62419,
+  0.947778,  1.33478,  1.74561,  1.83051,  2.25611,  2.66786,
+  0.970291,  1.21491,  1.74593,  1.84071,  2.26878,  2.55518,
+  1.02748,  1.19305,  1.65541,  1.77056,  2.11599,  2.50296,
+  1.10863,  1.22404,  1.55642,  1.7059,  2.01907,  2.46382,
+  1.13733,  1.24864,  1.6599,  1.836,  2.0873,  2.49402,
+  1.19278,  1.29031,  1.65286,  1.87863,  2.08608,  2.61596,
+  1.23183,  1.34329,  1.52821,  1.64612,  1.91216,  2.35441,
+  1.04315,  1.3807,  1.67914,  1.83012,  2.00837,  2.41401,
+  1.10289,  1.24306,  1.74748,  1.86138,  2.20309,  2.50438,
+  1.04973,  1.35437,  1.73588,  1.819,  2.24881,  2.55779,
+  1.10598,  1.57142,  1.76481,  1.95355,  2.42885,  2.56011,
+  1.29085,  1.55016,  1.83756,  2.1266,  2.48883,  2.60078,
+  1.19424,  1.4267,  1.83766,  1.91401,  2.44321,  2.63552,
+  1.1655,  1.26009,  1.79094,  1.89331,  2.40045,  2.64664,
+  1.22495,  1.30814,  1.82593,  1.91949,  2.32136,  2.69508,
+  1.24849,  1.34538,  1.77545,  1.87671,  2.35372,  2.65414,
+  1.27114,  1.39967,  1.81154,  1.89758,  2.40349,  2.65392,
+  1.3091,  1.40766,  1.80684,  1.89783,  2.33922,  2.63235,
+  1.29102,  1.38333,  1.80244,  1.88719,  2.24772,  2.66245,
+  1.26136,  1.37051,  1.75597,  1.87125,  2.1019,  2.59359,
+  1.28264,  1.37654,  1.77553,  1.9045,  2.19234,  2.50743,
+  1.36136,  1.45086,  1.79107,  1.90616,  2.2215,  2.54334,
+  1.33499,  1.43138,  1.71627,  1.90549,  2.0892,  2.37826,
+  1.38567,  1.47042,  1.7654,  1.90922,  2.17384,  2.45657,
+  1.36432,  1.45506,  1.75488,  1.87147,  2.36504,  2.57228,
+  1.38778,  1.48689,  1.71209,  1.8475,  2.24356,  2.57069,
+  1.31245,  1.42529,  1.62289,  1.75678,  1.97847,  2.36751,
+  1.3472,  1.45434,  1.68343,  1.82547,  2.08792,  2.46256,
+  1.32645,  1.40544,  1.72764,  1.83555,  2.32887,  2.61433,
+  1.33311,  1.42971,  1.79607,  1.90035,  2.44506,  2.65291,
+  1.3228,  1.42159,  1.73694,  1.8435,  2.53212,  2.64664,
+  1.34468,  1.43186,  1.76621,  1.92458,  2.55008,  2.68986,
+  1.38828,  1.48581,  1.71196,  1.82621,  2.49614,  2.65849,
+  1.41113,  1.49561,  1.77687,  1.87667,  2.49259,  2.65135,
+  1.41779,  1.49158,  1.80169,  1.89041,  2.44245,  2.70699,
+  1.40612,  1.51559,  1.75734,  1.89697,  2.38205,  2.63363,
+  1.42586,  1.51481,  1.77326,  1.90174,  2.44755,  2.63472,
+  1.47603,  1.55503,  1.74573,  1.86162,  2.39877,  2.61498,
+  1.45985,  1.56153,  1.78645,  1.91123,  2.47654,  2.59179,
+  1.40306,  1.51419,  1.72076,  1.90094,  2.48989,  2.57733,
+  1.42813,  1.52351,  1.68976,  1.83521,  2.4589,  2.56597,
+  1.32896,  1.43471,  1.60407,  1.73425,  2.4663,  2.56683,
+  1.24132,  1.34325,  1.458,  1.69662,  2.52782,  2.64566,
+  1.13662,  1.31113,  1.42996,  1.69536,  2.54253,  2.66041,
+  1.15311,  1.34414,  1.69081,  1.98593,  2.42001,  2.55378,
+  1.23176,  1.37392,  1.66882,  2.11744,  2.40191,  2.48888,
+  0.978581,  1.11559,  1.51713,  2.00053,  2.44902,  2.52602,
+  0.951081,  1.10796,  1.20861,  1.73722,  2.4743,  2.61185,
+  0.981806,  1.12784,  1.22059,  1.72099,  2.58653,  2.69889,
+  0.977554,  1.22407,  1.33776,  1.71327,  2.59337,  2.67541,
+  0.986078,  1.2604,  1.40744,  1.57149,  2.56942,  2.63175,
+  1.06877,  1.2094,  1.46443,  1.55798,  2.55135,  2.66975,
+  1.03419,  1.17431,  1.46726,  1.55529,  2.46049,  2.64226,
+  1.05663,  1.17869,  1.5099,  1.62154,  2.15303,  2.54053,
+  1.10894,  1.24024,  1.65138,  1.77854,  2.22761,  2.57195,
+  1.04085,  1.39778,  1.70963,  1.83002,  2.3987,  2.61895,
+  1.06308,  1.56403,  1.69554,  1.79469,  2.41902,  2.57735,
+  1.15665,  1.57989,  1.74299,  1.88897,  2.41901,  2.62687,
+  1.28215,  1.60467,  1.76982,  1.98481,  2.29053,  2.40855,
+  1.41496,  1.75259,  1.9379,  2.07679,  2.28769,  2.50228,
+  1.56159,  1.88269,  2.08718,  2.19987,  2.3986,  2.50906,
+  1.74177,  1.96305,  2.16108,  2.26221,  2.51606,  2.62613,
+  1.57955,  1.9163,  2.20167,  2.30168,  2.45849,  2.64834,
+  1.6562,  1.8493,  2.1017,  2.30217,  2.48776,  2.57383,
+  1.76171,  1.93589,  2.1671,  2.42309,  2.53131,  2.61977,
+  1.74734,  1.94646,  2.12972,  2.45212,  2.59171,  2.6811,
+  1.66477,  1.95071,  2.06484,  2.45292,  2.65328,  2.71998,
+  1.18212,  1.80699,  2.03181,  2.24045,  2.58934,  2.66695,
+  0.911793,  1.44443,  1.9382,  2.00954,  2.51885,  2.66242,
+  0.906235,  1.35395,  1.86014,  1.94894,  2.57034,  2.65373,
+  0.915756,  1.18244,  1.77937,  1.91835,  2.49518,  2.68524,
+  0.923262,  1.16808,  1.70545,  2.00799,  2.40124,  2.58442,
+  0.915338,  1.1961,  1.64118,  1.9578,  2.23516,  2.50251,
+  1.11694,  1.26915,  1.59747,  1.9508,  2.1291,  2.3925,
+  1.22715,  1.34423,  1.80926,  1.99916,  2.32077,  2.54577,
+  1.30788,  1.51797,  1.83234,  2.04216,  2.34776,  2.54341,
+  1.14291,  1.42748,  1.83152,  2.02229,  2.35648,  2.58964,
+  1.02021,  1.20271,  1.78017,  2.07079,  2.56583,  2.66165,
+  1.08785,  1.26596,  1.65328,  2.09396,  2.62566,  2.70924,
+  1.14659,  1.23417,  1.66629,  2.02225,  2.60572,  2.67625,
+  1.08906,  1.31141,  1.64715,  1.83385,  2.66668,  2.72276,
+  1.18839,  1.31996,  1.72568,  1.80695,  2.57119,  2.66417,
+  1.20957,  1.35804,  1.69743,  1.7942,  2.47045,  2.64023,
+  1.24605,  1.33829,  1.69554,  1.782,  2.56576,  2.66694,
+  1.26125,  1.38448,  1.61968,  1.77958,  2.5918,  2.71243,
+  1.33751,  1.45023,  1.64699,  1.77421,  2.57897,  2.70337,
+  1.38769,  1.4781,  1.61892,  1.74728,  2.53199,  2.6657,
+  1.30178,  1.39264,  1.54187,  1.66565,  2.48454,  2.65506,
+  1.25701,  1.39883,  1.52736,  1.73414,  2.61953,  2.68968,
+  1.21116,  1.32426,  1.66434,  1.91151,  2.58934,  2.68525,
+  1.11303,  1.32541,  1.6977,  1.94018,  2.59112,  2.67963,
+  1.00034,  1.35223,  1.71949,  2.02479,  2.57766,  2.6391,
+  0.952537,  1.56466,  1.91458,  2.02111,  2.48126,  2.55357,
+  0.94138,  1.57337,  1.89848,  1.99082,  2.3884,  2.52782,
+  0.835656,  1.42686,  1.9149,  2.0063,  2.45584,  2.54443,
+  0.762518,  1.61797,  1.84816,  1.95272,  2.51168,  2.57689,
+  0.760103,  1.72025,  1.88404,  1.9725,  2.52618,  2.66897,
+  0.788105,  1.51594,  1.76089,  1.95372,  2.49866,  2.5539,
+  0.84239,  1.23509,  1.68744,  2.01111,  2.39147,  2.52955,
+  0.970555,  1.30488,  1.68991,  2.0601,  2.38601,  2.52427,
+  1.07851,  1.22081,  1.63039,  2.10393,  2.41141,  2.5183,
+  1.03513,  1.37429,  1.73952,  2.01539,  2.38354,  2.54289,
+  1.23277,  1.46612,  1.94288,  2.1126,  2.35987,  2.47684,
+  1.03214,  1.46016,  1.84361,  2.11132,  2.40561,  2.54561,
+  0.863004,  1.57537,  1.75434,  2.02642,  2.48406,  2.54587,
+  0.78188,  1.62113,  1.87611,  2.13162,  2.59115,  2.66521,
+  0.689257,  1.56767,  1.95132,  2.24673,  2.50779,  2.64996,
+  0.76292,  1.45451,  2.05214,  2.23995,  2.40891,  2.57038,
+  0.735313,  1.36954,  2.14112,  2.22674,  2.40426,  2.51585,
+  0.692794,  1.21322,  2.02173,  2.17001,  2.40979,  2.63261,
+  0.749191,  1.32741,  1.8763,  2.15981,  2.39637,  2.54356,
+  0.723514,  1.31193,  1.77912,  2.00099,  2.33306,  2.52163,
+  0.800844,  1.39933,  1.70253,  1.88677,  2.1838,  2.39184,
+  0.935365,  1.5324,  1.7461,  1.84327,  2.02788,  2.36693,
+  0.879717,  1.39098,  1.69669,  1.87323,  2.27339,  2.53295,
+  1.11563,  1.39538,  1.55249,  2.06254,  2.37975,  2.48566,
+  1.25346,  1.37982,  1.72652,  2.1649,  2.38685,  2.50781,
+  1.28865,  1.54861,  1.76922,  2.10614,  2.42884,  2.5175,
+  1.36965,  1.61115,  1.79367,  1.97047,  2.36765,  2.55804,
+  1.39903,  1.69493,  1.86562,  2.03676,  2.40916,  2.58643,
+  1.43333,  1.74573,  1.93073,  2.15938,  2.42655,  2.57904,
+  1.26759,  1.66587,  1.97138,  2.10332,  2.44452,  2.56774,
+  1.22612,  1.49722,  1.88861,  2.08359,  2.54785,  2.62348,
+  1.21786,  1.50232,  1.85015,  1.97391,  2.50602,  2.62557,
+  1.21379,  1.59537,  1.87504,  1.97942,  2.42715,  2.60646,
+  1.23975,  1.51387,  1.76668,  1.94793,  2.28162,  2.49207,
+  1.24763,  1.58563,  1.72974,  1.8947,  2.38196,  2.52212,
+  1.20115,  1.47447,  1.74657,  1.83424,  2.28973,  2.52518,
+  1.18147,  1.55532,  1.7036,  1.82308,  2.31583,  2.44389,
+  1.19633,  1.57376,  1.73522,  1.80803,  2.4035,  2.55724,
+  1.14908,  1.63161,  1.76916,  1.92557,  2.36812,  2.54281,
+  1.07109,  1.63355,  1.76134,  1.87247,  2.40846,  2.57352,
+  1.06523,  1.55174,  1.71341,  1.88049,  2.38743,  2.51216,
+  0.987564,  1.63573,  1.78594,  1.95671,  2.4134,  2.54862,
+  0.931677,  1.52646,  1.77301,  1.89696,  2.43796,  2.5139,
+  0.900322,  1.64588,  1.78798,  2.04104,  2.33427,  2.43459,
+  0.867303,  1.71472,  1.90161,  2.09919,  2.3871,  2.47589,
+  0.868278,  1.69374,  1.9173,  2.01308,  2.2746,  2.38253,
+  0.848816,  1.56719,  1.82901,  1.92983,  2.3394,  2.42562,
+  0.789452,  1.36929,  1.82686,  1.91727,  2.41428,  2.50207,
+  0.737031,  1.1733,  1.87303,  1.97283,  2.45513,  2.54124,
+  0.759015,  1.25073,  1.78111,  1.99463,  2.42044,  2.55494,
+  0.749485,  1.36394,  1.89637,  1.99357,  2.44226,  2.50985,
+  0.749379,  1.21466,  1.94066,  2.03408,  2.45072,  2.5683,
+  0.801242,  1.26916,  1.8709,  1.95599,  2.40516,  2.47386,
+  0.82329,  1.25895,  1.87986,  2.0697,  2.41177,  2.5101,
+  0.836531,  1.27393,  1.9573,  2.04747,  2.49016,  2.58229,
+  0.834116,  1.18388,  1.88646,  1.96919,  2.49948,  2.60434,
+  0.876413,  1.17115,  1.94662,  2.0309,  2.43135,  2.55301,
+  0.839364,  1.05611,  1.85364,  2.10059,  2.39261,  2.55434,
+  0.864173,  1.16468,  1.83549,  1.96885,  2.37631,  2.5161,
+  0.932804,  1.29457,  1.83095,  1.90104,  2.44527,  2.55257,
+  0.963048,  1.35686,  1.76883,  1.89322,  2.47992,  2.61467,
+  1.03707,  1.35972,  1.82081,  1.89105,  2.51931,  2.60502,
+  1.06061,  1.46234,  1.79795,  1.93929,  2.52187,  2.59188,
+  1.07992,  1.50417,  1.80221,  1.93053,  2.46514,  2.5432,
+  1.14011,  1.33906,  1.81335,  1.90531,  2.37007,  2.53042,
+  1.15187,  1.35617,  1.77236,  1.88371,  2.37001,  2.61081,
+  1.28808,  1.63863,  1.75106,  2.27992,  2.55539,  2.62328,
+  1.45144,  1.73949,  1.9164,  2.3887,  2.63615,  2.70283,
+  1.59125,  1.85154,  2.21828,  2.38549,  2.59375,  2.67943,
+  1.59226,  2.01614,  2.2338,  2.33376,  2.54482,  2.66517,
+  1.6542,  1.94158,  2.25097,  2.37237,  2.4589,  2.59983,
+  1.70325,  2.0255,  2.2296,  2.3371,  2.46858,  2.61766,
+  1.63882,  2.00556,  2.20195,  2.26846,  2.49954,  2.61841,
+  1.92467,  2.13532,  2.45818,  2.50417,  2.59384,  2.6254,
+  1.80381,  2.06257,  2.19935,  2.28946,  2.55004,  2.64392,
+  1.77301,  1.97662,  2.10757,  2.22087,  2.44498,  2.54384,
+  1.76495,  2.00173,  2.21445,  2.2547,  2.47561,  2.57975,
+  1.67833,  1.86391,  2.24464,  2.34367,  2.47113,  2.63609,
+  1.75581,  1.86025,  2.22372,  2.35306,  2.4983,  2.58668,
+  1.69343,  1.86924,  2.2833,  2.3958,  2.51974,  2.58367,
+  1.7044,  1.79121,  2.14719,  2.33645,  2.47903,  2.59089,
+  1.68326,  1.86225,  2.16334,  2.35184,  2.52091,  2.61603,
+  1.62322,  1.80421,  2.22207,  2.3603,  2.6199,  2.69951,
+  1.65724,  1.82561,  2.25849,  2.34735,  2.54573,  2.69471,
+  1.66007,  1.86034,  2.25357,  2.36412,  2.56409,  2.63073,
+  1.5969,  1.83951,  2.21893,  2.38579,  2.54647,  2.62589,
+  1.62232,  1.8512,  1.99621,  2.3774,  2.52207,  2.59549,
+  1.02947,  1.25453,  1.74899,  2.05352,  2.44588,  2.57611,
+  0.856689,  0.993818,  1.56961,  2.21376,  2.46185,  2.54708,
+  1.01658,  1.1919,  1.29347,  1.77814,  2.4558,  2.55165,
+  1.01054,  1.22815,  1.31143,  1.82028,  2.53151,  2.65675,
+  0.908278,  1.18958,  1.28554,  1.8586,  2.52592,  2.61992,
+  0.871987,  1.17192,  1.31749,  1.82652,  2.40074,  2.51809,
+  1.03312,  1.18885,  1.4397,  2.03901,  2.57242,  2.6561,
+  0.970197,  1.29563,  1.40244,  2.03504,  2.48818,  2.54989,
+  1.0882,  1.22065,  1.55306,  2.13338,  2.5357,  2.59506,
+  1.00995,  1.3898,  1.51706,  2.11522,  2.47419,  2.55069,
+  0.993372,  1.42737,  1.53917,  1.9724,  2.52584,  2.58386,
+  1.04829,  1.48208,  1.63718,  2.16108,  2.52317,  2.61471,
+  1.02433,  1.56286,  1.69224,  2.29516,  2.59484,  2.64857,
+  0.907692,  1.61256,  1.74613,  2.16254,  2.57575,  2.61626,
+  0.890482,  1.61113,  1.77393,  1.97073,  2.57775,  2.6596,
+  0.808392,  1.5978,  1.78596,  2.0064,  2.56504,  2.63896,
+  0.766474,  1.58442,  1.83584,  1.92974,  2.58154,  2.64107,
+  0.769957,  1.62677,  1.86926,  2.02945,  2.60278,  2.66048,
+  0.798945,  1.53186,  1.83489,  1.94653,  2.62826,  2.69262,
+  0.720628,  1.38023,  1.8176,  1.89535,  2.54776,  2.6072,
+  0.717991,  1.30127,  1.75327,  1.88057,  2.50111,  2.57068,
+  0.757538,  1.19751,  1.71932,  1.8634,  2.4672,  2.58075,
+  0.753702,  1.29247,  1.69185,  1.7758,  2.47259,  2.58378,
+  0.814552,  1.2342,  1.58385,  1.68828,  2.54626,  2.60138,
+  0.892573,  1.25942,  1.54867,  1.62871,  2.46518,  2.55748,
+  0.949846,  1.26057,  1.42925,  1.62028,  2.39675,  2.4574,
+  1.0353,  1.2441,  1.49824,  1.64392,  2.38137,  2.52433,
+  1.10807,  1.33757,  1.53819,  1.80059,  2.51358,  2.61769,
+  1.18254,  1.37047,  1.56189,  1.84416,  2.54573,  2.61445,
+  1.21527,  1.3744,  1.59539,  1.9408,  2.51228,  2.59416,
+  1.23283,  1.3567,  1.64836,  2.04066,  2.51833,  2.60689,
+  1.29553,  1.441,  1.62601,  2.06359,  2.53545,  2.6072,
+  1.31746,  1.48417,  1.66663,  2.1072,  2.50946,  2.56956,
+  1.28814,  1.40484,  1.70844,  2.1424,  2.47826,  2.55815,
+  1.30118,  1.49063,  1.68866,  2.20974,  2.51657,  2.5826,
+  1.38891,  1.4886,  1.75307,  2.24911,  2.46845,  2.53274,
+  1.43236,  1.50195,  1.75604,  2.22738,  2.54031,  2.63382,
+  1.27063,  1.44425,  1.69718,  2.16774,  2.57417,  2.66708,
+  1.37795,  1.51182,  1.61924,  2.07059,  2.58057,  2.65545,
+  1.31909,  1.43763,  1.57516,  1.82626,  2.5685,  2.64694,
+  1.27334,  1.43938,  1.61468,  1.97782,  2.58918,  2.64227,
+  1.36481,  1.49144,  1.65464,  1.9149,  2.27758,  2.49171,
+  1.3814,  1.48233,  1.6257,  1.76745,  2.29282,  2.53541,
+  1.31612,  1.4108,  1.57452,  1.6965,  2.24155,  2.54414,
+  1.24921,  1.44841,  1.65161,  1.81201,  2.16694,  2.52883,
+  1.32999,  1.4301,  1.63778,  1.7537,  2.14427,  2.49173,
+  1.21201,  1.46018,  1.66372,  1.72397,  2.45273,  2.65487,
+  1.15467,  1.42799,  1.63984,  1.70382,  2.52478,  2.64719,
+  1.13219,  1.27638,  1.63819,  1.75073,  2.36014,  2.63024,
+  1.1068,  1.2922,  1.56399,  1.73715,  2.27638,  2.67348,
+  1.00947,  1.4092,  1.60525,  1.75588,  2.54981,  2.6669,
+  0.849242,  1.42476,  1.60734,  1.77047,  2.59306,  2.69757,
+  0.884126,  1.41867,  1.69054,  1.91036,  2.64889,  2.75356,
+  0.835786,  1.50533,  1.65083,  1.83983,  2.66751,  2.73182,
+  0.830887,  1.41843,  1.69822,  1.81279,  2.54661,  2.60518,
+  0.770144,  1.45618,  1.73535,  1.83979,  2.48532,  2.53941,
+  0.741204,  1.4612,  1.72026,  2.03966,  2.61315,  2.65662,
+  0.746126,  1.43606,  1.67492,  1.86887,  2.61646,  2.6596,
+  0.785082,  1.34349,  1.67545,  1.75655,  2.55005,  2.61191,
+  0.745773,  1.35482,  1.63002,  1.93899,  2.4536,  2.54908,
+  0.84578,  1.46925,  1.62908,  1.97497,  2.49928,  2.54978,
+  0.949421,  1.46277,  1.57299,  2.28604,  2.54958,  2.60293,
+  1.02515,  1.38536,  1.64839,  2.19293,  2.44063,  2.53102,
+  1.03372,  1.43617,  1.74409,  2.13226,  2.54404,  2.6189,
+  1.08284,  1.45584,  1.59799,  2.00309,  2.62826,  2.73613,
+  1.02162,  1.3808,  1.5378,  2.00792,  2.65618,  2.72548,
+  0.934605,  1.33831,  1.72128,  2.02138,  2.45266,  2.63594,
+  0.974987,  1.2806,  1.74048,  1.98864,  2.38339,  2.58854,
+  0.963572,  1.35863,  1.77509,  2.07708,  2.37441,  2.55255,
+  1.33939,  1.60607,  1.94104,  2.1598,  2.44654,  2.58731,
+  1.26864,  1.60406,  1.94006,  2.17892,  2.48766,  2.5975,
+  1.12981,  1.52262,  1.87297,  2.07507,  2.47971,  2.63317,
+  1.13535,  1.4223,  1.86599,  1.94531,  2.52336,  2.68614,
+  1.13554,  1.56227,  1.76815,  1.92201,  2.50605,  2.73613,
+  1.17333,  1.63762,  1.8454,  1.97453,  2.37951,  2.62759,
+  1.22309,  1.47716,  1.79951,  1.94529,  2.6037,  2.69777,
+  1.28565,  1.78142,  1.97253,  2.33525,  2.64962,  2.71925,
+  1.51607,  1.86247,  2.08499,  2.38614,  2.56337,  2.65052,
+  1.62251,  1.80088,  2.07468,  2.3711,  2.4941,  2.60895,
+  1.64422,  1.73091,  2.23525,  2.34462,  2.4606,  2.62177,
+  1.64649,  1.74384,  2.11867,  2.33454,  2.48765,  2.5973,
+  1.57447,  1.66694,  2.16568,  2.29463,  2.46302,  2.64293,
+  1.56853,  1.66268,  2.06838,  2.24007,  2.37478,  2.53429,
+  1.50109,  1.67557,  2.0192,  2.25394,  2.40396,  2.56021,
+  1.33322,  1.48186,  1.81038,  2.03244,  2.23527,  2.46402,
+  1.18419,  1.37647,  1.74307,  2.07718,  2.24737,  2.43664,
+  0.860298,  1.01797,  1.39947,  2.03136,  2.44583,  2.51204,
+  0.987543,  1.18722,  1.32467,  2.08656,  2.44026,  2.50786,
+  0.987539,  1.05739,  1.40051,  2.29103,  2.46201,  2.53454,
+  1.07257,  1.16846,  1.33543,  2.28155,  2.59528,  2.64199,
+  1.04242,  1.21947,  1.32875,  2.10439,  2.48141,  2.54485,
+  1.07584,  1.20487,  1.37029,  2.20656,  2.50952,  2.5572,
+  1.07591,  1.18808,  1.41434,  2.3201,  2.53091,  2.58942,
+  1.07615,  1.2674,  1.41198,  2.21842,  2.45229,  2.54095,
+  1.15455,  1.31481,  1.50039,  2.30097,  2.50519,  2.56979,
+  1.17038,  1.30037,  1.47778,  2.20108,  2.41823,  2.51101,
+  1.16483,  1.29078,  1.43643,  2.04217,  2.4346,  2.51715,
+  1.19386,  1.29319,  1.52759,  2.00881,  2.37081,  2.47326,
+  1.26354,  1.38567,  1.59613,  2.04876,  2.42779,  2.50408,
+  1.30519,  1.42101,  1.65888,  2.09585,  2.42943,  2.51858,
+  1.3783,  1.49436,  1.71028,  2.07804,  2.47796,  2.55948,
+  1.33373,  1.47526,  1.67404,  2.03963,  2.44671,  2.52705,
+  1.34615,  1.46853,  1.67367,  1.96109,  2.4626,  2.56716,
+  1.32426,  1.4669,  1.74709,  2.00944,  2.48056,  2.57128,
+  1.30692,  1.41105,  1.74078,  2.0324,  2.46634,  2.57579,
+  1.2773,  1.40831,  1.71568,  1.95693,  2.50597,  2.5973,
+  1.23917,  1.40986,  1.63569,  1.84314,  2.51134,  2.59249,
+  1.26227,  1.3779,  1.66588,  1.78528,  2.41492,  2.5191,
+  1.22377,  1.37861,  1.70694,  1.81201,  2.47211,  2.5535,
+  1.24828,  1.56097,  1.68845,  2.02442,  2.46468,  2.53208,
+  1.55115,  1.67483,  1.86392,  2.2426,  2.42567,  2.51231,
+  1.61354,  1.73636,  1.91583,  2.28434,  2.5051,  2.5755,
+  1.67565,  1.76455,  2.01326,  2.3086,  2.47931,  2.57088,
+  1.67679,  1.73219,  2.21691,  2.35074,  2.51681,  2.58494,
+  1.67209,  1.76809,  2.1703,  2.27753,  2.41116,  2.49253,
+  1.64585,  1.88123,  2.21635,  2.32063,  2.46081,  2.56493,
+  1.71409,  1.93321,  2.22012,  2.3277,  2.45303,  2.55743,
+  1.86416,  1.9656,  2.21189,  2.35407,  2.45155,  2.5437,
+  1.84051,  1.9809,  2.14136,  2.27592,  2.48783,  2.60703,
+  1.28163,  1.50854,  1.87809,  2.15331,  2.51039,  2.59772,
+  1.28594,  1.55852,  1.89593,  2.1545,  2.51005,  2.62888,
+  1.1797,  1.45797,  1.80582,  2.0887,  2.53683,  2.64835,
+  1.21318,  1.47414,  1.79648,  1.88639,  2.42644,  2.59714,
+  1.17576,  1.56663,  1.7868,  1.95963,  2.44398,  2.62181,
+  1.24128,  1.49554,  1.77294,  1.95943,  2.51364,  2.61189,
+  1.25286,  1.54735,  1.7413,  1.87367,  2.44728,  2.67464,
+  1.23425,  1.43703,  1.74215,  1.83575,  2.37217,  2.58149,
+  1.2624,  1.35128,  1.71028,  1.83349,  2.30891,  2.5836,
+  1.33086,  1.4241,  1.67389,  1.80298,  2.27185,  2.55676,
+  1.37492,  1.47319,  1.70336,  1.80452,  2.37449,  2.62583,
+  1.35042,  1.47764,  1.74193,  1.86958,  2.46816,  2.63785,
+  1.29945,  1.40927,  1.70733,  1.82882,  2.41262,  2.66007,
+  1.28367,  1.41318,  1.69401,  1.91384,  2.235,  2.66336,
+  1.13135,  1.54545,  1.7382,  1.92713,  2.24255,  2.52954,
+  1.3104,  1.44532,  1.80081,  1.94176,  2.22418,  2.4307,
+  1.20782,  1.40771,  1.79229,  1.89783,  2.27858,  2.58879,
+  1.17208,  1.38037,  1.76961,  1.87071,  2.42071,  2.66541,
+  1.05037,  1.29292,  1.70868,  1.81557,  2.3983,  2.64784,
+  1.0122,  1.35284,  1.71047,  1.79843,  2.50105,  2.62211,
+  0.949688,  1.51131,  1.80223,  2.05177,  2.38659,  2.54393,
+  1.23953,  1.52331,  1.99264,  2.17592,  2.53584,  2.66332,
+  1.17041,  1.42396,  1.91809,  2.07296,  2.37133,  2.60069,
+  1.15328,  1.63164,  1.94366,  2.04139,  2.42629,  2.52794,
+  1.13099,  1.68734,  1.9131,  1.98242,  2.36664,  2.59216,
+  0.876015,  1.53912,  1.95282,  2.04039,  2.35419,  2.59247,
+  0.741027,  1.33078,  2.01026,  2.08898,  2.40638,  2.51241,
+  0.692068,  1.22098,  1.96684,  2.05317,  2.52761,  2.62537,
+  0.697907,  1.40678,  2.01601,  2.08582,  2.57318,  2.65234,
+  0.747161,  1.54248,  1.98219,  2.09109,  2.57331,  2.6146,
+  0.759939,  1.51811,  1.93822,  2.16296,  2.53435,  2.63909,
+  0.752015,  1.44593,  2.09774,  2.15063,  2.47989,  2.58714,
+  0.80419,  1.42852,  2.01245,  2.19581,  2.47075,  2.57726,
+  0.757784,  1.35654,  1.87818,  2.23225,  2.531,  2.6303,
+  0.782189,  1.2517,  1.76691,  2.20655,  2.56445,  2.6177,
+  0.692136,  1.30829,  1.59302,  1.84293,  2.50433,  2.65265,
+  0.779817,  1.26499,  1.68969,  1.80369,  2.5305,  2.66946,
+  0.774734,  1.19962,  1.64959,  1.72658,  2.4371,  2.59153,
+  0.885025,  1.31194,  1.64647,  1.73919,  2.57872,  2.67199,
+  0.949387,  1.38711,  1.64193,  1.76257,  2.52877,  2.58579,
+  1.01204,  1.45536,  1.66673,  1.75258,  2.43427,  2.55352,
+  1.10407,  1.52937,  1.68209,  1.97304,  2.34551,  2.51158,
+  1.424,  1.61941,  1.99551,  2.29891,  2.43078,  2.52129,
+  1.58246,  1.83207,  2.2751,  2.38313,  2.4828,  2.53932,
+  1.70637,  2.00167,  2.30003,  2.39481,  2.48697,  2.58695,
+  1.53226,  1.93376,  2.28401,  2.42231,  2.62294,  2.70604,
+  1.67894,  1.88906,  2.33897,  2.51297,  2.63237,  2.6795,
+  1.63441,  1.78371,  2.12418,  2.463,  2.61035,  2.69136,
+  1.61835,  1.75102,  2.02613,  2.41802,  2.6094,  2.67895,
+  1.5652,  1.7943,  1.90207,  2.40566,  2.62933,  2.69687,
+  1.28214,  1.59125,  1.85203,  2.31423,  2.61778,  2.72294,
+  1.22037,  1.42168,  1.69434,  1.88174,  2.5568,  2.65318,
+  1.1394,  1.29901,  1.62237,  1.77043,  2.54387,  2.6407,
+  1.21449,  1.46742,  1.62803,  1.79401,  2.56341,  2.6917,
+  1.05963,  1.52181,  1.63195,  1.86516,  2.60104,  2.68366,
+  1.1802,  1.53659,  1.67186,  2.13796,  2.58765,  2.63839,
+  1.21365,  1.58211,  1.7095,  2.15751,  2.4768,  2.57401,
+  1.24846,  1.55305,  1.6453,  1.89754,  2.57776,  2.68128,
+  1.34058,  1.60143,  1.67999,  1.88914,  2.64709,  2.75513,
+  1.19455,  1.57556,  1.69753,  1.80137,  2.59652,  2.75237,
+  1.15299,  1.53138,  1.71641,  1.81272,  2.41715,  2.69646,
+  1.17528,  1.56527,  1.65742,  1.73478,  2.51798,  2.67121,
+  1.31588,  1.51598,  1.77517,  2.05808,  2.3073,  2.4493,
+  1.24713,  1.38127,  1.56836,  1.85701,  2.15728,  2.43501,
+  1.24025,  1.38365,  1.58057,  1.99147,  2.30357,  2.41106,
+  1.2868,  1.38585,  1.7307,  2.06754,  2.32691,  2.47304,
+  1.20411,  1.33789,  1.66549,  2.03875,  2.23142,  2.5434,
+  1.18234,  1.31211,  1.52226,  1.97103,  2.23777,  2.48363,
+  1.09543,  1.31991,  1.46571,  2.03259,  2.27994,  2.52364,
+  1.1525,  1.29451,  1.45831,  2.03253,  2.30603,  2.40676,
+  0.991441,  1.27466,  1.42822,  1.94058,  2.3991,  2.50937,
+  0.850157,  1.27472,  1.45373,  1.89353,  2.38229,  2.47766,
+  0.93606,  1.31321,  1.42674,  1.88897,  2.55174,  2.60439,
+  0.972592,  1.32833,  1.43283,  2.01105,  2.57367,  2.61367,
+  0.9094,  1.42276,  1.49463,  2.07395,  2.62063,  2.66268,
+  0.828475,  1.4317,  1.56949,  2.05425,  2.62211,  2.66974,
+  0.779249,  1.37567,  1.47663,  1.94919,  2.559,  2.62214,
+  0.81571,  1.47269,  1.65049,  2.00091,  2.56521,  2.61168,
+  0.822357,  1.33351,  1.55165,  1.86418,  2.59585,  2.70612,
+  0.736497,  1.25989,  1.49082,  1.88222,  2.49441,  2.61998,
+  0.90224,  1.431,  1.5205,  1.91079,  2.6054,  2.67859,
+  0.900488,  1.36305,  1.46181,  2.00977,  2.66588,  2.71718,
+  1.01539,  1.36153,  1.47485,  1.92044,  2.63748,  2.70257,
+  0.950918,  1.33518,  1.44088,  1.87435,  2.67892,  2.74624,
+  0.965674,  1.30691,  1.41289,  1.72718,  2.65632,  2.73947,
+  1.12134,  1.29133,  1.41298,  1.73139,  2.62458,  2.736,
+  1.13549,  1.29997,  1.44863,  1.63579,  2.61671,  2.68774,
+  1.12041,  1.2482,  1.38368,  1.57976,  2.39717,  2.58524,
+  1.11342,  1.2945,  1.48237,  1.60279,  2.39483,  2.63481,
+  1.24175,  1.31817,  1.47317,  1.5775,  2.426,  2.64978,
+  1.18438,  1.27289,  1.49775,  1.60805,  2.14445,  2.53727,
+  1.28314,  1.37732,  1.54304,  1.64518,  2.10579,  2.4909,
+  1.13801,  1.38076,  1.56048,  1.64098,  2.27101,  2.62552,
+  1.24388,  1.35154,  1.60307,  1.73979,  2.03808,  2.44751,
+  1.26726,  1.50996,  1.64165,  1.83198,  2.33133,  2.47283,
+  1.27637,  1.4764,  1.62502,  1.93034,  2.31938,  2.52437,
+  1.22268,  1.55941,  1.66998,  1.80547,  2.32691,  2.58028,
+  1.26522,  1.50389,  1.83098,  2.09154,  2.39672,  2.56909,
+  1.25605,  1.52888,  1.85303,  2.10617,  2.36514,  2.50328,
+  1.2365,  1.47912,  1.7283,  2.04146,  2.52856,  2.6129,
+  1.22064,  1.60519,  1.71377,  1.95092,  2.59764,  2.64949,
+  1.25555,  1.59187,  1.70675,  2.06271,  2.56138,  2.6269,
+  1.30708,  1.58002,  1.65355,  1.94129,  2.55273,  2.64371,
+  1.31097,  1.5128,  1.65653,  1.83919,  2.5921,  2.67771,
+  1.1886,  1.31608,  1.57937,  1.69077,  2.4385,  2.64188,
+  1.11467,  1.23599,  1.59197,  1.74919,  2.35944,  2.54521,
+  1.08007,  1.27713,  1.728,  2.04141,  2.33707,  2.54979,
+  1.03222,  1.25021,  1.681,  1.99834,  2.31853,  2.5022,
+  1.06472,  1.15918,  1.66673,  2.01929,  2.25657,  2.57347,
+  1.02631,  1.14637,  1.67293,  2.05406,  2.43323,  2.61572,
+  0.942929,  1.09279,  1.61352,  2.07778,  2.36514,  2.49974,
+  0.98025,  1.25478,  1.492,  1.80119,  2.44532,  2.57571,
+  0.957395,  1.25187,  1.37834,  1.74457,  2.50297,  2.66587,
+  0.840336,  1.26799,  1.39773,  1.82798,  2.55587,  2.65128,
+  1.0099,  1.17581,  1.27777,  2.04836,  2.6379,  2.7009,
+  0.88384,  1.02678,  1.14669,  1.89368,  2.51869,  2.61056,
+  0.997171,  1.13829,  1.24641,  1.83753,  2.54982,  2.64269,
+  0.992125,  1.17887,  1.28227,  1.9744,  2.55911,  2.61297,
+  1.06759,  1.2558,  1.35902,  1.96394,  2.54142,  2.59631,
+  1.08633,  1.32907,  1.43233,  1.92884,  2.52833,  2.59824,
+  1.10035,  1.34558,  1.46953,  1.94236,  2.46972,  2.56168,
+  1.10102,  1.37438,  1.56114,  1.94256,  2.48429,  2.553,
+  1.1775,  1.45517,  1.57149,  1.9435,  2.50031,  2.5509,
+  1.26077,  1.4779,  1.60161,  2.02402,  2.48743,  2.55424,
+  1.21644,  1.47008,  1.6396,  1.95721,  2.52383,  2.58819,
+  1.25798,  1.4072,  1.65143,  1.91072,  2.4642,  2.62087,
+  1.16209,  1.43654,  1.68217,  1.89692,  2.4473,  2.67707,
+  1.25022,  1.48463,  1.65387,  1.93047,  2.49389,  2.63344,
+  1.23798,  1.51339,  1.64878,  1.88034,  2.50409,  2.58149,
+  1.2232,  1.41246,  1.63408,  1.79718,  2.45121,  2.62062,
+  1.25874,  1.3584,  1.62772,  1.7261,  2.42829,  2.62133,
+  1.23492,  1.34561,  1.55215,  1.70868,  2.38574,  2.60605,
+  1.18642,  1.34181,  1.63691,  1.75468,  2.42972,  2.54439,
+  1.21626,  1.30589,  1.63278,  1.75577,  2.32081,  2.58379,
+  1.16534,  1.28415,  1.56053,  1.68204,  2.24322,  2.49467,
+  1.08586,  1.21511,  1.5906,  1.71533,  2.23163,  2.52723,
+  1.09165,  1.38416,  1.65516,  1.71656,  2.30278,  2.53555,
+  1.06033,  1.23908,  1.62721,  1.73757,  2.42016,  2.59915,
+  1.09008,  1.39478,  1.68248,  1.7999,  2.33181,  2.53286,
+  1.16904,  1.56812,  1.78572,  2.03155,  2.37221,  2.49786,
+  1.2419,  1.66208,  1.82249,  2.16954,  2.42454,  2.52519,
+  1.04029,  1.69041,  1.8531,  2.03859,  2.47201,  2.53597,
+  0.974879,  1.68906,  1.85014,  2.15131,  2.50742,  2.56254,
+  0.879683,  1.74384,  1.96806,  2.16115,  2.46392,  2.54585,
+  0.790116,  1.79441,  2.0373,  2.15974,  2.5084,  2.56488,
+  0.793374,  1.79617,  2.06052,  2.33107,  2.5913,  2.64858,
+  0.859332,  1.80046,  2.02545,  2.20064,  2.53432,  2.61132,
+  0.825206,  1.89513,  2.06358,  2.26453,  2.51403,  2.6108,
+  0.974068,  1.90478,  2.00264,  2.31585,  2.53967,  2.59516,
+  0.961311,  1.82128,  2.01521,  2.27454,  2.60079,  2.65336,
+  0.97104,  1.73701,  1.91495,  2.2439,  2.57236,  2.6126,
+  0.999552,  1.8179,  1.9531,  2.17859,  2.57433,  2.62628,
+  0.9773,  1.75604,  1.92914,  2.13535,  2.42421,  2.55609,
+  1.06554,  1.74764,  1.89917,  2.30975,  2.58739,  2.63059,
+  1.07706,  1.65572,  1.86833,  2.2386,  2.50891,  2.57184,
+  1.07783,  1.71642,  1.79146,  2.26622,  2.61548,  2.65405,
+  1.27602,  1.71338,  1.78883,  2.10144,  2.62562,  2.67959,
+  1.26317,  1.69909,  1.77693,  2.03511,  2.61035,  2.65342,
+  1.29714,  1.66767,  1.74401,  2.03012,  2.60806,  2.67807,
+  1.26237,  1.62646,  1.78116,  2.02618,  2.63626,  2.69918,
+  1.31803,  1.65777,  1.76358,  1.93904,  2.57545,  2.70561,
+  0.980669,  1.55589,  1.72298,  1.97855,  2.56896,  2.63842,
+  0.840013,  1.4634,  1.77278,  2.16486,  2.56689,  2.66623,
+  0.832158,  1.50575,  1.93789,  2.23397,  2.63013,  2.69488,
+  0.745541,  1.5301,  2.06073,  2.163,  2.61913,  2.69213,
+  0.83205,  1.59799,  2.12768,  2.19666,  2.52887,  2.6193,
+  0.820544,  1.61648,  2.04484,  2.13356,  2.58766,  2.66815,
+  0.789348,  1.63857,  1.99603,  2.2128,  2.57293,  2.61543,
+  0.806795,  1.74253,  2.04392,  2.18384,  2.60341,  2.66027,
+  0.843597,  1.76138,  1.99882,  2.13297,  2.5965,  2.67316,
+  0.927714,  1.7594,  1.98717,  2.20199,  2.59168,  2.65081,
+  1.0705,  1.76711,  1.97829,  2.22719,  2.6427,  2.68638,
+  1.02285,  1.85683,  1.98982,  2.21722,  2.48094,  2.57469,
+  0.886409,  1.74269,  1.86307,  2.0549,  2.54233,  2.62705,
+  0.996501,  1.55364,  1.80806,  1.94851,  2.51673,  2.60575,
+  1.21822,  1.52501,  1.87802,  2.1072,  2.42395,  2.57889,
+  1.27471,  1.49178,  1.90624,  2.10124,  2.45572,  2.56357,
+  1.31948,  1.58708,  1.87982,  2.24044,  2.43946,  2.54799,
+  1.47451,  1.699,  1.92926,  2.22822,  2.45187,  2.56313,
+  1.54527,  1.72271,  1.8921,  2.16916,  2.52024,  2.60296,
+  1.54616,  1.66889,  1.96149,  2.21208,  2.506,  2.62127,
+  1.53562,  1.69929,  2.01636,  2.25082,  2.55009,  2.64562,
+  1.58341,  1.68775,  2.05195,  2.33263,  2.49172,  2.59804,
+  1.50093,  1.59405,  1.92923,  2.25985,  2.42262,  2.54776,
+  1.46492,  1.61478,  1.8817,  2.21673,  2.52895,  2.62322,
+  1.40673,  1.60503,  1.80598,  2.22272,  2.50901,  2.58784,
+  1.10642,  1.52778,  1.73018,  2.04592,  2.54946,  2.6375,
+  1.00815,  1.43972,  1.66547,  1.94137,  2.65244,  2.7511,
+  0.971347,  1.40208,  1.7089,  1.95327,  2.61333,  2.68499,
+  0.946352,  1.50104,  1.67215,  1.97587,  2.5279,  2.58557,
+  0.909229,  1.45358,  1.7139,  2.06564,  2.52931,  2.61316,
+  0.975079,  1.52329,  1.83956,  2.13855,  2.49869,  2.58372,
+  0.899524,  1.55241,  1.83164,  2.06857,  2.54488,  2.61118,
+  0.805175,  1.46233,  1.86054,  2.10134,  2.57044,  2.65485,
+  0.859011,  1.51453,  1.8924,  2.01252,  2.57968,  2.64852,
+  0.763528,  1.52243,  1.90254,  2.01852,  2.55645,  2.60958,
+  0.814387,  1.49485,  1.94172,  2.07798,  2.54033,  2.61284,
+  0.853805,  1.40187,  1.94299,  2.08809,  2.48839,  2.57861,
+  0.782036,  1.34855,  1.9353,  2.02508,  2.51682,  2.59805,
+  0.754386,  1.38495,  1.90024,  1.99966,  2.60037,  2.66376,
+  0.746921,  1.42114,  1.93457,  2.03891,  2.55327,  2.6123,
+  0.731911,  1.45076,  1.92451,  2.03274,  2.4979,  2.55649,
+  0.706741,  1.54373,  1.8766,  1.99252,  2.51018,  2.56596,
+  0.852548,  1.54995,  1.89917,  2.2265,  2.52279,  2.58394,
+  0.885718,  1.657,  1.86579,  2.16289,  2.46739,  2.55377,
+  0.951271,  1.64172,  1.814,  2.15306,  2.4271,  2.49961,
+  0.928485,  1.50278,  1.80944,  2.22477,  2.4724,  2.55392,
+  0.816616,  1.3911,  1.66558,  2.17614,  2.51072,  2.58282,
+  0.915934,  1.39094,  1.76751,  2.16955,  2.47166,  2.65253,
+  1.11534,  1.36231,  1.72259,  2.03303,  2.40636,  2.60188,
+  1.13866,  1.25298,  1.68452,  1.93737,  2.38431,  2.6239,
+  1.08432,  1.21195,  1.63364,  1.88994,  2.41309,  2.62623,
+  1.12622,  1.34492,  1.6486,  2.07112,  2.48419,  2.60566,
+  1.1239,  1.46156,  1.8451,  2.17246,  2.46266,  2.60514,
+  1.13256,  1.46864,  1.74022,  2.18493,  2.46794,  2.5801,
+  1.14825,  1.50617,  1.6766,  2.04929,  2.44677,  2.56542,
+  0.999544,  1.4047,  1.64177,  1.86332,  2.52384,  2.59211,
+  0.932167,  1.39598,  1.70943,  1.84574,  2.52479,  2.59962,
+  0.870085,  1.47633,  1.72151,  1.89709,  2.49026,  2.59376,
+  0.891107,  1.42911,  1.78973,  1.95843,  2.5191,  2.60499,
+  0.85555,  1.42127,  1.90094,  2.01101,  2.54662,  2.60976,
+  0.895038,  1.48258,  1.87357,  1.97483,  2.51943,  2.58445,
+  0.809092,  1.4865,  1.90227,  2.00088,  2.51837,  2.59726,
+  0.808211,  1.46017,  1.88158,  1.9614,  2.46839,  2.61633,
+  0.774237,  1.47186,  1.90122,  2.01376,  2.56487,  2.66569,
+  0.800018,  1.57695,  1.93818,  2.04372,  2.49438,  2.6301,
+  0.804705,  1.57076,  1.88936,  1.97549,  2.44765,  2.55519,
+  0.840709,  1.60338,  1.82708,  2.02632,  2.44289,  2.49242,
+  0.887288,  1.53614,  1.78162,  1.9522,  2.50081,  2.57651,
+  0.847527,  1.5047,  1.79295,  1.89159,  2.57889,  2.63732,
+  0.959025,  1.53382,  1.82149,  1.97974,  2.46375,  2.5443,
+  1.03632,  1.64079,  1.88602,  1.96289,  2.35866,  2.57776,
+  0.981142,  1.48674,  1.7331,  1.87828,  2.53797,  2.61047,
+  1.04649,  1.43851,  1.74084,  1.85001,  2.59088,  2.68414,
+  1.1034,  1.48978,  1.73824,  1.8175,  2.58837,  2.70105,
+  1.17692,  1.47368,  1.73285,  1.82327,  2.52453,  2.73354,
+  1.17332,  1.43838,  1.69656,  1.79254,  2.58079,  2.66577,
+  1.13496,  1.42186,  1.60407,  1.75613,  2.61795,  2.70664,
+  1.13601,  1.38418,  1.6991,  1.85532,  2.59101,  2.68321,
+  1.20171,  1.42193,  1.73786,  2.0112,  2.54096,  2.68109,
+  1.22745,  1.62446,  2.12523,  2.34056,  2.59344,  2.67145,
+  1.26513,  1.76569,  2.13134,  2.39177,  2.61396,  2.69985,
+  1.34228,  1.58141,  1.97924,  2.29776,  2.52039,  2.60226,
+  1.44901,  1.72555,  2.17628,  2.35474,  2.53876,  2.62732,
+  1.41873,  1.89868,  2.20633,  2.2756,  2.48875,  2.58679,
+  1.55571,  1.8376,  2.16574,  2.34619,  2.53018,  2.62876,
+  1.44444,  1.79005,  1.91101,  2.30191,  2.46886,  2.54056,
+  1.37805,  1.6685,  1.84527,  2.32489,  2.53771,  2.60147,
+  1.39474,  1.68271,  1.81735,  2.07553,  2.51212,  2.56689,
+  1.2972,  1.65588,  1.82541,  2.0621,  2.51331,  2.57737,
+  1.28066,  1.6699,  1.82457,  2.16821,  2.52817,  2.60199,
+  1.3069,  1.60081,  1.76797,  2.09529,  2.50987,  2.606,
+  1.25768,  1.55975,  1.7878,  2.07689,  2.54039,  2.62718,
+  1.19685,  1.59755,  1.81742,  2.15266,  2.5808,  2.65125,
+  1.23593,  1.67664,  1.94231,  2.32648,  2.56154,  2.64559,
+  1.18906,  1.81889,  2.0815,  2.36645,  2.60802,  2.67209,
+  1.42759,  1.88542,  2.26491,  2.42422,  2.57137,  2.65115,
+  1.71447,  1.93787,  2.39001,  2.45715,  2.55202,  2.60193,
+  1.87414,  2.07351,  2.37047,  2.51126,  2.70918,  2.7495,
+  1.64782,  1.9878,  2.28191,  2.4121,  2.60469,  2.67482,
+  1.59637,  1.88153,  2.19399,  2.38052,  2.51192,  2.58456,
+  1.55551,  1.77522,  2.06409,  2.3257,  2.51293,  2.59926,
+  1.33005,  1.71296,  1.91762,  2.2859,  2.46659,  2.57928,
+  0.990071,  1.41087,  1.63233,  1.96589,  2.46688,  2.58042,
+  0.92515,  1.29903,  1.5514,  1.89749,  2.49848,  2.64521,
+  0.96808,  1.36713,  1.52036,  1.98816,  2.31347,  2.54694,
+  0.974374,  1.28381,  1.47481,  2.0783,  2.33109,  2.45515,
+  1.00062,  1.29915,  1.41568,  1.95576,  2.26155,  2.35426,
+  0.964045,  1.13649,  1.30593,  1.93641,  2.19754,  2.29942,
+  1.01309,  1.20114,  1.37266,  1.82018,  2.06358,  2.21066,
+  1.08648,  1.2167,  1.47666,  1.60404,  1.85596,  2.3245,
+  1.09016,  1.20121,  1.46078,  1.56222,  2.01609,  2.45898,
+  1.13375,  1.25747,  1.40719,  1.78768,  2.28953,  2.53085,
+  1.13483,  1.34122,  1.63629,  1.81377,  2.21945,  2.58465,
+  0.952747,  1.30093,  1.61689,  1.75101,  2.35211,  2.54788,
+  1.0787,  1.49004,  1.57158,  1.80053,  2.46817,  2.65044,
+  1.23905,  1.33303,  1.55138,  1.70782,  2.24292,  2.60425,
+  1.17652,  1.29911,  1.58888,  1.71408,  2.12886,  2.53352,
+  1.13583,  1.25306,  1.53841,  1.63448,  2.25809,  2.59387,
+  1.09238,  1.25324,  1.54177,  1.67988,  2.4232,  2.61758,
+  1.14266,  1.2564,  1.52828,  1.62968,  2.39158,  2.58969,
+  1.17279,  1.28125,  1.4792,  1.60888,  2.33594,  2.59368,
+  1.14678,  1.25195,  1.43292,  1.55329,  2.23894,  2.53418,
+  1.10995,  1.23142,  1.4121,  1.51605,  2.30857,  2.5999,
+  1.12027,  1.23554,  1.42574,  1.50952,  2.43553,  2.64381,
+  1.08587,  1.1893,  1.39272,  1.49435,  2.12934,  2.50899,
+  1.0205,  1.17314,  1.44097,  1.57442,  2.33586,  2.52405,
+  1.04055,  1.17434,  1.52572,  1.69311,  2.49375,  2.63235,
+  1.03452,  1.20526,  1.36509,  1.513,  2.47179,  2.57801,
+  1.07938,  1.204,  1.33243,  1.4566,  2.50213,  2.66563,
+  1.08886,  1.23695,  1.357,  1.56494,  2.60202,  2.70758,
+  1.10679,  1.2624,  1.36727,  1.82395,  2.59858,  2.6763,
+  1.08501,  1.23353,  1.31146,  1.73033,  2.56009,  2.69032,
+  1.06921,  1.18022,  1.34302,  1.47483,  2.26805,  2.54431,
+  1.03939,  1.37562,  1.72144,  2.03802,  2.464,  2.60081,
+  1.26785,  1.38411,  1.6599,  1.93402,  2.20776,  2.42458,
+  1.22528,  1.31662,  1.67815,  1.81923,  2.16534,  2.49855,
+  1.11414,  1.28303,  1.65552,  1.87967,  2.35247,  2.55354,
+  1.09476,  1.37002,  1.79913,  2.08238,  2.46949,  2.57882,
+  1.04125,  1.47276,  1.74873,  2.04759,  2.5117,  2.58983,
+  1.07167,  1.45655,  1.70052,  1.92732,  2.44148,  2.607,
+  0.929006,  1.48724,  1.66955,  1.88562,  2.54427,  2.62832,
+  0.844366,  1.33971,  1.81246,  2.30021,  2.56601,  2.63125,
+  0.761441,  1.27995,  1.67045,  2.00635,  2.52682,  2.60756,
+  0.716643,  1.37484,  1.84344,  2.12696,  2.55299,  2.61315,
+  0.749967,  1.59846,  1.88327,  2.05044,  2.57918,  2.61411,
+  0.759376,  1.59638,  1.9291,  1.98455,  2.56673,  2.65421,
+  0.724977,  1.6829,  1.88829,  2.0348,  2.50386,  2.5655,
+  0.812327,  1.66987,  1.96177,  2.10215,  2.53878,  2.59856,
+  0.767334,  1.59463,  1.98432,  2.13342,  2.50169,  2.55781,
+  0.76023,  1.65065,  1.92837,  2.09405,  2.56524,  2.59608,
+  0.766762,  1.64806,  1.85855,  2.07859,  2.58708,  2.60821,
+  0.860938,  1.62925,  1.82485,  2.06735,  2.56337,  2.60321,
+  0.960953,  1.58363,  1.75221,  2.07844,  2.55553,  2.62851,
+  1.00793,  1.548,  1.73495,  2.18566,  2.48935,  2.55145,
+  1.0404,  1.47112,  1.64352,  2.05156,  2.50852,  2.57917,
+  1.09602,  1.45743,  1.60401,  1.9262,  2.48203,  2.5522,
+  1.13043,  1.43153,  1.59281,  2.01474,  2.51065,  2.56778,
+  1.1979,  1.46548,  1.62293,  2.07595,  2.50705,  2.58275,
+  1.25883,  1.5048,  1.65911,  1.97065,  2.59575,  2.68565,
+  1.31545,  1.46745,  1.70572,  1.89863,  2.60257,  2.70498,
+  1.27248,  1.43189,  1.71285,  1.94026,  2.65038,  2.71717,
+  1.27886,  1.52865,  1.7962,  1.9952,  2.50176,  2.58761,
+  1.45862,  1.69394,  2.0679,  2.26484,  2.50686,  2.62394,
+  1.7188,  1.90961,  2.1476,  2.35417,  2.48558,  2.59127,
+  1.81387,  1.87548,  2.09764,  2.32968,  2.4978,  2.59625,
+  1.74429,  1.85945,  2.04317,  2.28459,  2.4309,  2.53857,
+  1.51418,  1.8083,  1.93379,  2.23465,  2.46223,  2.54624,
+  1.48926,  1.78119,  1.908,  2.14448,  2.41859,  2.51386,
+  1.43479,  1.67979,  1.81735,  2.10537,  2.43137,  2.52824,
+  1.46958,  1.58951,  1.81351,  2.21313,  2.4405,  2.52051,
+  1.49629,  1.64005,  1.89386,  2.29862,  2.4847,  2.57621,
+  1.33342,  1.58473,  1.89302,  2.12181,  2.52535,  2.63262,
+  1.51872,  1.73584,  1.95653,  2.17643,  2.46534,  2.57234,
+  1.52095,  1.74256,  2.01058,  2.13358,  2.44746,  2.5667,
+  1.45812,  1.69223,  2.00192,  2.12054,  2.43104,  2.56511,
+  1.52691,  1.66239,  2.02514,  2.12506,  2.53787,  2.62681,
+  1.4983,  1.64421,  1.96073,  2.10329,  2.44031,  2.57241,
+  1.41548,  1.54829,  1.7708,  2.09993,  2.45026,  2.59946,
+  1.36719,  1.46063,  1.73948,  2.07403,  2.55195,  2.64
+};
+
+const struct lsp_codebook lsp_cbvq[] = {
+  /* codebook/lsp1.txt */
+  {
+    1,
+    4,
+    16,
+    codes0
+  },
+  /* codebook/lsp2.txt */
+  {
+    1,
+    4,
+    16,
+    codes1
+  },
+  /* codebook/lsp3.txt */
+  {
+    1,
+    4,
+    16,
+    codes2
+  },
+  /* codebook/lsp4.txt */
+  {
+    1,
+    4,
+    16,
+    codes3
+  },
+  /* ../unittest/lsp45678910.txt */
+  {
+    6,
+    12,
+    4096,
+    codes4
+  },
+  { 0, 0, 0, 0 }
+};
diff --git a/codec2/branches/0.7/src/codec2.c b/codec2/branches/0.7/src/codec2.c
new file mode 100644 (file)
index 0000000..de79710
--- /dev/null
@@ -0,0 +1,2269 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 21/8/2010
+
+  Codec2 fully quantised encoder and decoder functions.  If you want use
+  codec2, the codec2_xxx functions are for you.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "defines.h"
+#include "codec2_fft.h"
+#include "sine.h"
+#include "nlp.h"
+#include "dump.h"
+#include "lpc.h"
+#include "quantise.h"
+#include "phase.h"
+#include "interp.h"
+#include "postfilter.h"
+#include "codec2.h"
+#include "lsp.h"
+#include "codec2_internal.h"
+#include "machdep.h"
+#include "bpf.h"
+#include "bpfb.h"
+
+/*---------------------------------------------------------------------------*\
+
+                             FUNCTION HEADERS
+
+\*---------------------------------------------------------------------------*/
+
+void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]);
+void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model,
+                         COMP Aw[]);
+void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est);
+void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_700(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[]);
+void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * bits);
+static void ear_protection(float in_out[], int n);
+
+/*---------------------------------------------------------------------------*\
+
+                                FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_create
+  AUTHOR......: David Rowe
+  DATE CREATED: 21/8/2010
+
+  Create and initialise an instance of the codec.  Returns a pointer
+  to the codec states or NULL on failure.  One set of states is
+  sufficient for a full duuplex codec (i.e. an encoder and decoder).
+  You don't need separate states for encoders and decoders.  See
+  c2enc.c and c2dec.c for examples.
+
+\*---------------------------------------------------------------------------*/
+
+struct CODEC2 * codec2_create(int mode)
+{
+    struct CODEC2 *c2;
+    int            i,l;
+
+    if (!((mode >= 0) && (mode <= CODEC2_MODE_700C))) {
+        return NULL;
+    }  
+
+    c2 = (struct CODEC2*)malloc(sizeof(struct CODEC2));
+    if (c2 == NULL)
+       return NULL;
+
+    c2->mode = mode;
+
+    /* store constants in a few places for convenience */
+
+    c2->c2const = c2const_create(8000);
+    c2->Fs = c2->c2const.Fs;
+    int n_samp = c2->n_samp = c2->c2const.n_samp;
+    int m_pitch = c2->m_pitch = c2->c2const.m_pitch;
+
+    c2->Pn = (float*)malloc(2*n_samp*sizeof(float));
+    if (c2->Pn == NULL) {
+       return NULL;
+    }
+    c2->Sn_ = (float*)malloc(2*n_samp*sizeof(float));
+    if (c2->Sn_ == NULL) {
+       return NULL;
+    }
+    c2->w = (float*)malloc(m_pitch*sizeof(float));
+    if (c2->w == NULL) {
+       return NULL;
+    }
+    c2->Sn = (float*)malloc(m_pitch*sizeof(float));
+    if (c2->Sn == NULL) {
+       return NULL;
+    }
+
+    for(i=0; i<m_pitch; i++)
+       c2->Sn[i] = 1.0;
+    c2->hpf_states[0] = c2->hpf_states[1] = 0.0;
+    for(i=0; i<2*n_samp; i++)
+       c2->Sn_[i] = 0;
+    c2->fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL);
+    c2->fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL);
+    make_analysis_window(&c2->c2const, c2->fft_fwd_cfg, c2->w,c2->W);
+    make_synthesis_window(&c2->c2const, c2->Pn);
+    c2->fftr_inv_cfg = codec2_fftr_alloc(FFT_DEC, 1, NULL, NULL);
+    quantise_init();
+    c2->prev_f0_enc = 1/P_MAX_S;
+    c2->bg_est = 0.0;
+    c2->ex_phase = 0.0;
+
+    for(l=1; l<=MAX_AMP; l++)
+       c2->prev_model_dec.A[l] = 0.0;
+    c2->prev_model_dec.Wo = TWO_PI/c2->c2const.p_max;
+    c2->prev_model_dec.L = PI/c2->prev_model_dec.Wo;
+    c2->prev_model_dec.voiced = 0;
+
+    for(i=0; i<LPC_ORD; i++) {
+      c2->prev_lsps_dec[i] = i*PI/(LPC_ORD+1);
+    }
+    c2->prev_e_dec = 1;
+
+    c2->nlp = nlp_create(&c2->c2const);
+    if (c2->nlp == NULL) {
+       return NULL;
+    }
+
+    if (mode == CODEC2_MODE_700B)
+        c2->gray = 0;             // natural binary better for trellis decoding (hopefully added later)
+    else
+        c2->gray = 1;
+
+    c2->lpc_pf = 1; c2->bass_boost = 1; c2->beta = LPCPF_BETA; c2->gamma = LPCPF_GAMMA;
+
+    c2->xq_enc[0] = c2->xq_enc[1] = 0.0;
+    c2->xq_dec[0] = c2->xq_dec[1] = 0.0;
+
+    c2->smoothing = 0;
+
+    c2->bpf_buf = (float*)malloc(sizeof(float)*(BPF_N+4*c2->n_samp));
+    assert(c2->bpf_buf != NULL);
+    for(i=0; i<BPF_N+4*c2->n_samp; i++)
+        c2->bpf_buf[i] = 0.0;
+
+    c2->softdec = NULL;
+
+#ifndef CORTEX_M4
+    /* newamp1 initialisation */
+
+    if (c2->mode == CODEC2_MODE_700C) {
+        mel_sample_freqs_kHz(c2->rate_K_sample_freqs_kHz, NEWAMP1_K, ftomel(200.0), ftomel(3700.0) );
+        int k;
+        for(k=0; k<NEWAMP1_K; k++) {
+            c2->prev_rate_K_vec_[k] = 0.0;
+        }
+        c2->Wo_left = 0.0;
+        c2->voicing_left = 0;;
+        c2->phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 0, NULL, NULL);
+        c2->phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 1, NULL, NULL);
+    }
+#endif
+
+    return c2;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_destroy
+  AUTHOR......: David Rowe
+  DATE CREATED: 21/8/2010
+
+  Destroy an instance of the codec.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_destroy(struct CODEC2 *c2)
+{
+    assert(c2 != NULL);
+    free(c2->bpf_buf);
+    nlp_destroy(c2->nlp);
+    codec2_fft_free(c2->fft_fwd_cfg);
+    codec2_fftr_free(c2->fftr_fwd_cfg);
+    codec2_fftr_free(c2->fftr_inv_cfg);
+    if (c2->mode == CODEC2_MODE_700C) {
+        codec2_fft_free(c2->phase_fft_fwd_cfg);
+        codec2_fft_free(c2->phase_fft_inv_cfg);
+    }
+    free(c2->Pn);
+    free(c2->Sn);
+    free(c2->w);
+    free(c2->Sn_);
+    free(c2);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_bits_per_frame
+  AUTHOR......: David Rowe
+  DATE CREATED: Nov 14 2011
+
+  Returns the number of bits per frame.
+
+\*---------------------------------------------------------------------------*/
+
+int codec2_bits_per_frame(struct CODEC2 *c2) {
+    if (c2->mode == CODEC2_MODE_3200)
+       return 64;
+    if (c2->mode == CODEC2_MODE_2400)
+       return 48;
+    if  (c2->mode == CODEC2_MODE_1600)
+       return 64;
+    if  (c2->mode == CODEC2_MODE_1400)
+       return 56;
+    if  (c2->mode == CODEC2_MODE_1300)
+       return 52;
+    if  (c2->mode == CODEC2_MODE_1200)
+       return 48;
+    if  (c2->mode == CODEC2_MODE_700)
+       return 28;
+    if  (c2->mode == CODEC2_MODE_700B)
+       return 28;
+    if  (c2->mode == CODEC2_MODE_700C)
+       return 28;
+
+    return 0; /* shouldn't get here */
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_samples_per_frame
+  AUTHOR......: David Rowe
+  DATE CREATED: Nov 14 2011
+
+  Returns the number of speech samples per frame.
+
+\*---------------------------------------------------------------------------*/
+
+int codec2_samples_per_frame(struct CODEC2 *c2) {
+    if (c2->mode == CODEC2_MODE_3200)
+       return 160;
+    if (c2->mode == CODEC2_MODE_2400)
+       return 160;
+    if  (c2->mode == CODEC2_MODE_1600)
+       return 320;
+    if  (c2->mode == CODEC2_MODE_1400)
+       return 320;
+    if  (c2->mode == CODEC2_MODE_1300)
+       return 320;
+    if  (c2->mode == CODEC2_MODE_1200)
+       return 320;
+    if  (c2->mode == CODEC2_MODE_700)
+       return 320;
+    if  (c2->mode == CODEC2_MODE_700B)
+       return 320;
+    if  (c2->mode == CODEC2_MODE_700C)
+       return 320;
+
+    return 0; /* shouldnt get here */
+}
+
+void codec2_encode(struct CODEC2 *c2, unsigned char *bits, short speech[])
+{
+    assert(c2 != NULL);
+    assert((c2->mode >= CODEC2_MODE_3200) && (c2->mode <= CODEC2_MODE_700C));
+
+    if (c2->mode == CODEC2_MODE_3200)
+       codec2_encode_3200(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_2400)
+       codec2_encode_2400(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_1600)
+       codec2_encode_1600(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_1400)
+       codec2_encode_1400(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_1300)
+       codec2_encode_1300(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_1200)
+       codec2_encode_1200(c2, bits, speech);
+#ifndef CORTEX_M4
+    if (c2->mode == CODEC2_MODE_700)
+       codec2_encode_700(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_700B)
+       codec2_encode_700b(c2, bits, speech);
+    if (c2->mode == CODEC2_MODE_700C)
+       codec2_encode_700c(c2, bits, speech);
+#endif
+}
+
+void codec2_decode(struct CODEC2 *c2, short speech[], const unsigned char *bits)
+{
+    codec2_decode_ber(c2, speech, bits, 0.0);
+}
+
+void codec2_decode_ber(struct CODEC2 *c2, short speech[], const unsigned char *bits, float ber_est)
+{
+    assert(c2 != NULL);
+    assert((c2->mode >= CODEC2_MODE_3200) && (c2->mode <= CODEC2_MODE_700C));
+
+    if (c2->mode == CODEC2_MODE_3200)
+       codec2_decode_3200(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_2400)
+       codec2_decode_2400(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_1600)
+       codec2_decode_1600(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_1400)
+       codec2_decode_1400(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_1300)
+       codec2_decode_1300(c2, speech, bits, ber_est);
+    if (c2->mode == CODEC2_MODE_1200)
+       codec2_decode_1200(c2, speech, bits);
+#ifndef CORTEX_M4
+    if (c2->mode == CODEC2_MODE_700)
+       codec2_decode_700(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_700B)
+       codec2_decode_700b(c2, speech, bits);
+    if (c2->mode == CODEC2_MODE_700C)
+       codec2_decode_700c(c2, speech, bits);
+#endif
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_3200
+  AUTHOR......: David Rowe
+  DATE CREATED: 13 Sep 2012
+
+  Encodes 160 speech samples (20ms of speech) into 64 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm twice.  On the
+  first frame we just send the voicing bits.  On the second frame we
+  send all model parameters.  Compared to 2400 we use a larger number
+  of bits for the LSPs and non-VQ pitch and energy.
+
+  The bit allocation is:
+
+    Parameter                      bits/frame
+    --------------------------------------
+    Harmonic magnitudes (LSPs)     50
+    Pitch (Wo)                      7
+    Energy                          5
+    Voicing (10ms update)           2
+    TOTAL                          64
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_3200(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   ak[LPC_ORD+1];
+    float   lsps[LPC_ORD];
+    float   e;
+    int     Wo_index, e_index;
+    int     lspd_indexes[LPC_ORD];
+    int     i;
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* first 10ms analysis frame - we just want voicing */
+
+    analyse_one_frame(c2, &model, speech);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* second 10ms analysis frame */
+
+    analyse_one_frame(c2, &model, &speech[c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+    Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS);
+    pack(bits, &nbit, Wo_index, WO_BITS);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+    e_index = encode_energy(e, E_BITS);
+    pack(bits, &nbit, e_index, E_BITS);
+
+    encode_lspds_scalar(lspd_indexes, lsps, LPC_ORD);
+    for(i=0; i<LSPD_SCALAR_INDEXES; i++) {
+       pack(bits, &nbit, lspd_indexes[i], lspd_bits(i));
+    }
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_3200
+  AUTHOR......: David Rowe
+  DATE CREATED: 13 Sep 2012
+
+  Decodes a frame of 64 bits into 160 samples (20ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_3200(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[2];
+    int     lspd_indexes[LPC_ORD];
+    float   lsps[2][LPC_ORD];
+    int     Wo_index, e_index;
+    float   e[2];
+    float   snr;
+    float   ak[2][LPC_ORD+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    COMP    Aw[FFT_ENC];
+
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<2; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    /* this will partially fill the model params for the 2 x 10ms
+       frames */
+
+    model[0].voiced = unpack(bits, &nbit, 1);
+    model[1].voiced = unpack(bits, &nbit, 1);
+
+    Wo_index = unpack(bits, &nbit, WO_BITS);
+    model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS);
+    model[1].L  = PI/model[1].Wo;
+
+    e_index = unpack(bits, &nbit, E_BITS);
+    e[1] = decode_energy(e_index, E_BITS);
+
+    for(i=0; i<LSPD_SCALAR_INDEXES; i++) {
+       lspd_indexes[i] = unpack(bits, &nbit, lspd_bits(i));
+    }
+    decode_lspds_scalar(&lsps[1][0], lspd_indexes, LPC_ORD);
+
+    /* interpolate ------------------------------------------------*/
+
+    /* Wo and energy are sampled every 20ms, so we interpolate just 1
+       10ms frame between 20ms samples */
+
+    interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min);
+    e[0] = interp_energy(c2->prev_e_dec, e[1]);
+
+    /* LSPs are sampled every 20ms so we interpolate the frame in
+       between, then recover spectral amplitudes */
+
+    interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, LPC_ORD);
+
+    for(i=0; i<2; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[1];
+    c2->prev_e_dec = e[1];
+    for(i=0; i<LPC_ORD; i++)
+       c2->prev_lsps_dec[i] = lsps[1][i];
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_2400
+  AUTHOR......: David Rowe
+  DATE CREATED: 21/8/2010
+
+  Encodes 160 speech samples (20ms of speech) into 48 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm twice.  On the
+  first frame we just send the voicing bit.  On the second frame we
+  send all model parameters.
+
+  The bit allocation is:
+
+    Parameter                      bits/frame
+    --------------------------------------
+    Harmonic magnitudes (LSPs)     36
+    Joint VQ of Energy and Wo       8
+    Voicing (10ms update)           2
+    Spare                           2
+    TOTAL                          48
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_2400(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   ak[LPC_ORD+1];
+    float   lsps[LPC_ORD];
+    float   e;
+    int     WoE_index;
+    int     lsp_indexes[LPC_ORD];
+    int     i;
+    int     spare = 0;
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0', ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* first 10ms analysis frame - we just want voicing */
+
+    analyse_one_frame(c2, &model, speech);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* second 10ms analysis frame */
+
+    analyse_one_frame(c2, &model, &speech[c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+    WoE_index = encode_WoE(&model, e, c2->xq_enc);
+    pack(bits, &nbit, WoE_index, WO_E_BITS);
+
+    encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       pack(bits, &nbit, lsp_indexes[i], lsp_bits(i));
+    }
+    pack(bits, &nbit, spare, 2);
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_2400
+  AUTHOR......: David Rowe
+  DATE CREATED: 21/8/2010
+
+  Decodes frames of 48 bits into 160 samples (20ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_2400(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[2];
+    int     lsp_indexes[LPC_ORD];
+    float   lsps[2][LPC_ORD];
+    int     WoE_index;
+    float   e[2];
+    float   snr;
+    float   ak[2][LPC_ORD+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    COMP    Aw[FFT_ENC];
+
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<2; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    /* this will partially fill the model params for the 2 x 10ms
+       frames */
+
+    model[0].voiced = unpack(bits, &nbit, 1);
+
+    model[1].voiced = unpack(bits, &nbit, 1);
+    WoE_index = unpack(bits, &nbit, WO_E_BITS);
+    decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index);
+
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i));
+    }
+    decode_lsps_scalar(&lsps[1][0], lsp_indexes, LPC_ORD);
+    check_lsp_order(&lsps[1][0], LPC_ORD);
+    bw_expand_lsps(&lsps[1][0], LPC_ORD, 50.0, 100.0);
+
+    /* interpolate ------------------------------------------------*/
+
+    /* Wo and energy are sampled every 20ms, so we interpolate just 1
+       10ms frame between 20ms samples */
+
+    interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min);
+    e[0] = interp_energy(c2->prev_e_dec, e[1]);
+
+    /* LSPs are sampled every 20ms so we interpolate the frame in
+       between, then recover spectral amplitudes */
+
+    interpolate_lsp_ver2(&lsps[0][0], c2->prev_lsps_dec, &lsps[1][0], 0.5, LPC_ORD);
+    for(i=0; i<2; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[1];
+    c2->prev_e_dec = e[1];
+    for(i=0; i<LPC_ORD; i++)
+       c2->prev_lsps_dec[i] = lsps[1][i];
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_1600
+  AUTHOR......: David Rowe
+  DATE CREATED: Feb 28 2013
+
+  Encodes 320 speech samples (40ms of speech) into 64 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm 4 times:
+
+  frame 0: voicing bit
+  frame 1: voicing bit, Wo and E
+  frame 2: voicing bit
+  frame 3: voicing bit, Wo and E, scalar LSPs
+
+  The bit allocation is:
+
+    Parameter                      frame 2  frame 4   Total
+    -------------------------------------------------------
+    Harmonic magnitudes (LSPs)      0       36        36
+    Pitch (Wo)                      7        7        14
+    Energy                          5        5        10
+    Voicing (10ms update)           2        2         4
+    TOTAL                          14       50        64
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_1600(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
+    int     lsp_indexes[LPC_ORD];
+    int     Wo_index, e_index;
+    int     i;
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* frame 1: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, speech);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* frame 2: - voicing, scalar Wo & E -------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS);
+    pack(bits, &nbit, Wo_index, WO_BITS);
+
+    /* need to run this just to get LPC energy */
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+    e_index = encode_energy(e, E_BITS);
+    pack(bits, &nbit, e_index, E_BITS);
+
+    /* frame 3: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/
+
+    analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS);
+    pack(bits, &nbit, Wo_index, WO_BITS);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+    e_index = encode_energy(e, E_BITS);
+    pack(bits, &nbit, e_index, E_BITS);
+
+    encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       pack(bits, &nbit, lsp_indexes[i], lsp_bits(i));
+    }
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_1600
+  AUTHOR......: David Rowe
+  DATE CREATED: 11 May 2012
+
+  Decodes frames of 64 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_1600(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[4];
+    int     lsp_indexes[LPC_ORD];
+    float   lsps[4][LPC_ORD];
+    int     Wo_index, e_index;
+    float   e[4];
+    float   snr;
+    float   ak[4][LPC_ORD+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    float   weight;
+    COMP    Aw[FFT_ENC];
+
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<4; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    /* this will partially fill the model params for the 4 x 10ms
+       frames */
+
+    model[0].voiced = unpack(bits, &nbit, 1);
+
+    model[1].voiced = unpack(bits, &nbit, 1);
+    Wo_index = unpack(bits, &nbit, WO_BITS);
+    model[1].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS);
+    model[1].L  = PI/model[1].Wo;
+
+    e_index = unpack(bits, &nbit, E_BITS);
+    e[1] = decode_energy(e_index, E_BITS);
+
+    model[2].voiced = unpack(bits, &nbit, 1);
+
+    model[3].voiced = unpack(bits, &nbit, 1);
+    Wo_index = unpack(bits, &nbit, WO_BITS);
+    model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS);
+    model[3].L  = PI/model[3].Wo;
+
+    e_index = unpack(bits, &nbit, E_BITS);
+    e[3] = decode_energy(e_index, E_BITS);
+
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i));
+    }
+    decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD);
+    check_lsp_order(&lsps[3][0], LPC_ORD);
+    bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0);
+
+    /* interpolate ------------------------------------------------*/
+
+    /* Wo and energy are sampled every 20ms, so we interpolate just 1
+       10ms frame between 20ms samples */
+
+    interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min);
+    e[0] = interp_energy(c2->prev_e_dec, e[1]);
+    interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min);
+    e[2] = interp_energy(e[1], e[3]);
+
+    /* LSPs are sampled every 40ms so we interpolate the 3 frames in
+       between, then recover spectral amplitudes */
+
+    for(i=0, weight=0.25; i<3; i++, weight += 0.25) {
+       interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD);
+    }
+    for(i=0; i<4; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[3];
+    c2->prev_e_dec = e[3];
+    for(i=0; i<LPC_ORD; i++)
+       c2->prev_lsps_dec[i] = lsps[3][i];
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_1400
+  AUTHOR......: David Rowe
+  DATE CREATED: May 11 2012
+
+  Encodes 320 speech samples (40ms of speech) into 56 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm 4 times:
+
+  frame 0: voicing bit
+  frame 1: voicing bit, joint VQ of Wo and E
+  frame 2: voicing bit
+  frame 3: voicing bit, joint VQ of Wo and E, scalar LSPs
+
+  The bit allocation is:
+
+    Parameter                      frame 2  frame 4   Total
+    -------------------------------------------------------
+    Harmonic magnitudes (LSPs)      0       36        36
+    Energy+Wo                       8        8        16
+    Voicing (10ms update)           2        2         4
+    TOTAL                          10       46        56
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_1400(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
+    int     lsp_indexes[LPC_ORD];
+    int     WoE_index;
+    int     i;
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* frame 1: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, speech);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* frame 2: - voicing, joint Wo & E -------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* need to run this just to get LPC energy */
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+
+    WoE_index = encode_WoE(&model, e, c2->xq_enc);
+    pack(bits, &nbit, WoE_index, WO_E_BITS);
+
+    /* frame 3: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/
+
+    analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+    WoE_index = encode_WoE(&model, e, c2->xq_enc);
+    pack(bits, &nbit, WoE_index, WO_E_BITS);
+
+    encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       pack(bits, &nbit, lsp_indexes[i], lsp_bits(i));
+    }
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_1400
+  AUTHOR......: David Rowe
+  DATE CREATED: 11 May 2012
+
+  Decodes frames of 56 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_1400(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[4];
+    int     lsp_indexes[LPC_ORD];
+    float   lsps[4][LPC_ORD];
+    int     WoE_index;
+    float   e[4];
+    float   snr;
+    float   ak[4][LPC_ORD+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    float   weight;
+    COMP    Aw[FFT_ENC];
+
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<4; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    /* this will partially fill the model params for the 4 x 10ms
+       frames */
+
+    model[0].voiced = unpack(bits, &nbit, 1);
+
+    model[1].voiced = unpack(bits, &nbit, 1);
+    WoE_index = unpack(bits, &nbit, WO_E_BITS);
+    decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index);
+
+    model[2].voiced = unpack(bits, &nbit, 1);
+
+    model[3].voiced = unpack(bits, &nbit, 1);
+    WoE_index = unpack(bits, &nbit, WO_E_BITS);
+    decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index);
+
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i));
+    }
+    decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD);
+    check_lsp_order(&lsps[3][0], LPC_ORD);
+    bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0);
+
+    /* interpolate ------------------------------------------------*/
+
+    /* Wo and energy are sampled every 20ms, so we interpolate just 1
+       10ms frame between 20ms samples */
+
+    interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min);
+    e[0] = interp_energy(c2->prev_e_dec, e[1]);
+    interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min);
+    e[2] = interp_energy(e[1], e[3]);
+
+    /* LSPs are sampled every 40ms so we interpolate the 3 frames in
+       between, then recover spectral amplitudes */
+
+    for(i=0, weight=0.25; i<3; i++, weight += 0.25) {
+       interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD);
+    }
+    for(i=0; i<4; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[3];
+    c2->prev_e_dec = e[3];
+    for(i=0; i<LPC_ORD; i++)
+       c2->prev_lsps_dec[i] = lsps[3][i];
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_1300
+  AUTHOR......: David Rowe
+  DATE CREATED: March 14 2013
+
+  Encodes 320 speech samples (40ms of speech) into 52 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm 4 times:
+
+  frame 0: voicing bit
+  frame 1: voicing bit,
+  frame 2: voicing bit
+  frame 3: voicing bit, Wo and E, scalar LSPs
+
+  The bit allocation is:
+
+    Parameter                      frame 2  frame 4   Total
+    -------------------------------------------------------
+    Harmonic magnitudes (LSPs)      0       36        36
+    Pitch (Wo)                      0        7         7
+    Energy                          0        5         5
+    Voicing (10ms update)           2        2         4
+    TOTAL                           2       50        52
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_1300(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
+    int     lsp_indexes[LPC_ORD];
+    int     Wo_index, e_index;
+    int     i;
+    unsigned int nbit = 0;
+    #ifdef PROFILE
+    unsigned int quant_start;
+    #endif
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* frame 1: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, speech);
+    pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
+
+    /* frame 2: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[c2->n_samp]);
+    pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
+
+    /* frame 3: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
+    pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
+
+    /* frame 4: - voicing, scalar Wo & E, scalar LSPs ------------------*/
+
+    analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
+    pack_natural_or_gray(bits, &nbit, model.voiced, 1, c2->gray);
+
+    Wo_index = encode_Wo(&c2->c2const, model.Wo, WO_BITS);
+    pack_natural_or_gray(bits, &nbit, Wo_index, WO_BITS, c2->gray);
+
+    #ifdef PROFILE
+    quant_start = machdep_profile_sample();
+    #endif
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+    e_index = encode_energy(e, E_BITS);
+    pack_natural_or_gray(bits, &nbit, e_index, E_BITS, c2->gray);
+
+    encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       pack_natural_or_gray(bits, &nbit, lsp_indexes[i], lsp_bits(i), c2->gray);
+    }
+    #ifdef PROFILE
+    machdep_profile_sample_and_log(quant_start, "    quant/packing");
+    #endif
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_1300
+  AUTHOR......: David Rowe
+  DATE CREATED: 11 May 2012
+
+  Decodes frames of 52 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+static int frames;
+void codec2_decode_1300(struct CODEC2 *c2, short speech[], const unsigned char * bits, float ber_est)
+{
+    MODEL   model[4];
+    int     lsp_indexes[LPC_ORD];
+    float   lsps[4][LPC_ORD];
+    int     Wo_index, e_index;
+    float   e[4];
+    float   snr;
+    float   ak[4][LPC_ORD+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    float   weight;
+    COMP    Aw[FFT_ENC];
+    PROFILE_VAR(recover_start);
+
+    assert(c2 != NULL);
+    frames+= 4;
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<4; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    /* this will partially fill the model params for the 4 x 10ms
+       frames */
+
+    model[0].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
+    model[1].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
+    model[2].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
+    model[3].voiced = unpack_natural_or_gray(bits, &nbit, 1, c2->gray);
+
+    Wo_index = unpack_natural_or_gray(bits, &nbit, WO_BITS, c2->gray);
+    model[3].Wo = decode_Wo(&c2->c2const, Wo_index, WO_BITS);
+    model[3].L  = PI/model[3].Wo;
+
+    e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray);
+    e[3] = decode_energy(e_index, E_BITS);
+
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       lsp_indexes[i] = unpack_natural_or_gray(bits, &nbit, lsp_bits(i), c2->gray);
+    }
+    decode_lsps_scalar(&lsps[3][0], lsp_indexes, LPC_ORD);
+    check_lsp_order(&lsps[3][0], LPC_ORD);
+    bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0);
+
+    if (ber_est > 0.15) {
+        model[0].voiced =  model[1].voiced = model[2].voiced = model[3].voiced = 0;
+        e[3] = decode_energy(10, E_BITS);
+        bw_expand_lsps(&lsps[3][0], LPC_ORD, 200.0, 200.0);
+        fprintf(stderr, "soft mute\n");
+    }
+
+    /* interpolate ------------------------------------------------*/
+
+    /* Wo, energy, and LSPs are sampled every 40ms so we interpolate
+       the 3 frames in between */
+
+    PROFILE_SAMPLE(recover_start);
+    for(i=0, weight=0.25; i<3; i++, weight += 0.25) {
+       interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD);
+        interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, c2->c2const.Wo_min);
+        e[i] = interp_energy2(c2->prev_e_dec, e[3],weight);
+    }
+
+    /* then recover spectral amplitudes */
+
+    for(i=0; i<4; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+    /*
+    for(i=0; i<4; i++) {
+        printf("%d Wo: %f L: %d v: %d\n", frames, model[i].Wo, model[i].L, model[i].voiced);
+    }
+    if (frames == 4*50)
+        exit(0);
+    */
+    PROFILE_SAMPLE_AND_LOG2(recover_start, "    recover");
+    #ifdef DUMP
+    dump_lsp_(&lsps[3][0]);
+    dump_ak_(&ak[3][0], LPC_ORD);
+    #endif
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[3];
+    c2->prev_e_dec = e[3];
+    for(i=0; i<LPC_ORD; i++)
+       c2->prev_lsps_dec[i] = lsps[3][i];
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_1200
+  AUTHOR......: David Rowe
+  DATE CREATED: Nov 14 2011
+
+  Encodes 320 speech samples (40ms of speech) into 48 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm four times:
+
+  frame 0: voicing bit
+  frame 1: voicing bit, joint VQ of Wo and E
+  frame 2: voicing bit
+  frame 3: voicing bit, joint VQ of Wo and E, VQ LSPs
+
+  The bit allocation is:
+
+    Parameter                      frame 2  frame 4   Total
+    -------------------------------------------------------
+    Harmonic magnitudes (LSPs)      0       27        27
+    Energy+Wo                       8        8        16
+    Voicing (10ms update)           2        2         4
+    Spare                           0        1         1
+    TOTAL                          10       38        48
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_1200(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD];
+    float   lsps_[LPC_ORD];
+    float   ak[LPC_ORD+1];
+    float   e;
+    int     lsp_indexes[LPC_ORD];
+    int     WoE_index;
+    int     i;
+    int     spare = 0;
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* frame 1: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, speech);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* frame 2: - voicing, joint Wo & E -------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* need to run this just to get LPC energy */
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+
+    WoE_index = encode_WoE(&model, e, c2->xq_enc);
+    pack(bits, &nbit, WoE_index, WO_E_BITS);
+
+    /* frame 3: - voicing ---------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &speech[2*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    /* frame 4: - voicing, joint Wo & E, scalar LSPs ------------------*/
+
+    analyse_one_frame(c2, &model, &speech[3*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD);
+    WoE_index = encode_WoE(&model, e, c2->xq_enc);
+    pack(bits, &nbit, WoE_index, WO_E_BITS);
+
+    encode_lsps_vq(lsp_indexes, lsps, lsps_, LPC_ORD);
+    for(i=0; i<LSP_PRED_VQ_INDEXES; i++) {
+       pack(bits, &nbit, lsp_indexes[i], lsp_pred_vq_bits(i));
+    }
+    pack(bits, &nbit, spare, 1);
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_1200
+  AUTHOR......: David Rowe
+  DATE CREATED: 14 Feb 2012
+
+  Decodes frames of 48 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_1200(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[4];
+    int     lsp_indexes[LPC_ORD];
+    float   lsps[4][LPC_ORD];
+    int     WoE_index;
+    float   e[4];
+    float   snr;
+    float   ak[4][LPC_ORD+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    float   weight;
+    COMP    Aw[FFT_ENC];
+
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<4; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    /* this will partially fill the model params for the 4 x 10ms
+       frames */
+
+    model[0].voiced = unpack(bits, &nbit, 1);
+
+    model[1].voiced = unpack(bits, &nbit, 1);
+    WoE_index = unpack(bits, &nbit, WO_E_BITS);
+    decode_WoE(&c2->c2const, &model[1], &e[1], c2->xq_dec, WoE_index);
+
+    model[2].voiced = unpack(bits, &nbit, 1);
+
+    model[3].voiced = unpack(bits, &nbit, 1);
+    WoE_index = unpack(bits, &nbit, WO_E_BITS);
+    decode_WoE(&c2->c2const, &model[3], &e[3], c2->xq_dec, WoE_index);
+
+    for(i=0; i<LSP_PRED_VQ_INDEXES; i++) {
+       lsp_indexes[i] = unpack(bits, &nbit, lsp_pred_vq_bits(i));
+    }
+    decode_lsps_vq(lsp_indexes, &lsps[3][0], LPC_ORD , 0);
+    check_lsp_order(&lsps[3][0], LPC_ORD);
+    bw_expand_lsps(&lsps[3][0], LPC_ORD, 50.0, 100.0);
+
+    /* interpolate ------------------------------------------------*/
+
+    /* Wo and energy are sampled every 20ms, so we interpolate just 1
+       10ms frame between 20ms samples */
+
+    interp_Wo(&model[0], &c2->prev_model_dec, &model[1], c2->c2const.Wo_min);
+    e[0] = interp_energy(c2->prev_e_dec, e[1]);
+    interp_Wo(&model[2], &model[1], &model[3], c2->c2const.Wo_min);
+    e[2] = interp_energy(e[1], e[3]);
+
+    /* LSPs are sampled every 40ms so we interpolate the 3 frames in
+       between, then recover spectral amplitudes */
+
+    for(i=0, weight=0.25; i<3; i++, weight += 0.25) {
+       interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD);
+    }
+    for(i=0; i<4; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[3];
+    c2->prev_e_dec = e[3];
+    for(i=0; i<LPC_ORD; i++)
+       c2->prev_lsps_dec[i] = lsps[3][i];
+}
+
+
+#ifndef CORTEX_M4
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_700
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Encodes 320 speech samples (40ms of speech) into 28 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm four times:
+
+  frame 0: nothing
+  frame 1: nothing
+  frame 2: nothing
+  frame 3: voicing bit, scalar Wo and E, 17 bit LSP MEL scalar, 2 spare
+
+  The bit allocation is:
+
+    Parameter                      frames 1-3   frame 4   Total
+    -----------------------------------------------------------
+    Harmonic magnitudes (LSPs)          0         17        17
+    Energy                              0          3         3
+    log Wo                              0          5         5
+    Voicing                             0          1         1
+    spare                               0          2         2
+    TOTAL                               0         28        28
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_700(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD_LOW];
+    float   mel[LPC_ORD_LOW];
+    float   ak[LPC_ORD_LOW+1];
+    float   e, f;
+    int     indexes[LPC_ORD_LOW];
+    int     Wo_index, e_index, i;
+    unsigned int nbit = 0;
+    float   bpf_out[4*c2->n_samp];
+    short   bpf_speech[4*c2->n_samp];
+    int     spare = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* band pass filter */
+
+    for(i=0; i<BPF_N; i++)
+        c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i];
+    for(i=0; i<4*c2->n_samp; i++)
+        c2->bpf_buf[BPF_N+i] = speech[i];
+    inverse_filter(&c2->bpf_buf[BPF_N], bpf, 4*c2->n_samp, bpf_out, BPF_N-1);
+    for(i=0; i<4*c2->n_samp; i++)
+        bpf_speech[i] = bpf_out[i];
+
+    /* frame 1 --------------------------------------------------------*/
+
+    analyse_one_frame(c2, &model, bpf_speech);
+
+    /* frame 2 --------------------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]);
+
+    /* frame 3 --------------------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]);
+
+    /* frame 4: - voicing, scalar Wo & E, scalar LSPs -----------------*/
+
+    analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+    Wo_index = encode_log_Wo(&c2->c2const, model.Wo, 5);
+    pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD_LOW);
+    e_index = encode_energy(e, 3);
+    pack_natural_or_gray(bits, &nbit, e_index, 3, c2->gray);
+
+    for(i=0; i<LPC_ORD_LOW; i++) {
+        f = (4000.0/PI)*lsps[i];
+        mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5);
+    }
+    encode_mels_scalar(indexes, mel, LPC_ORD_LOW);
+
+    for(i=0; i<LPC_ORD_LOW; i++) {
+        pack_natural_or_gray(bits, &nbit, indexes[i], mel_bits(i), c2->gray);
+    }
+
+    pack_natural_or_gray(bits, &nbit, spare, 2, c2->gray);
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_700
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Decodes frames of 28 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_700(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[4];
+    int     indexes[LPC_ORD_LOW];
+    float   mel[LPC_ORD_LOW];
+    float   lsps[4][LPC_ORD_LOW];
+    int     Wo_index, e_index;
+    float   e[4];
+    float   snr, f_;
+    float   ak[4][LPC_ORD_LOW+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    float   weight;
+    COMP    Aw[FFT_ENC];
+
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<4; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    model[3].voiced = unpack(bits, &nbit, 1);
+    model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced;
+
+    Wo_index = unpack_natural_or_gray(bits, &nbit, 5, c2->gray);
+    model[3].Wo = decode_log_Wo(&c2->c2const, Wo_index, 5);
+    model[3].L  = PI/model[3].Wo;
+
+    e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray);
+    e[3] = decode_energy(e_index, 3);
+
+    for(i=0; i<LPC_ORD_LOW; i++) {
+        indexes[i] = unpack_natural_or_gray(bits, &nbit, mel_bits(i), c2->gray);
+    }
+
+    decode_mels_scalar(mel, indexes, LPC_ORD_LOW);
+    for(i=0; i<LPC_ORD_LOW; i++) {
+        f_ = 700.0*( pow(10.0, (float)mel[i]/2595.0) - 1.0);
+        lsps[3][i] = f_*(PI/4000.0);
+        //printf("lsps[3][%d]  %f\n", i, lsps[3][i]);
+    }
+
+    check_lsp_order(&lsps[3][0], LPC_ORD_LOW);
+    bw_expand_lsps(&lsps[3][0], LPC_ORD_LOW, 50.0, 100.0);
+
+    #ifdef MASK_NOT_FOR_NOW
+    /* first pass at soft decn error masking, needs further work      */
+    /* If soft dec info available expand further for low power frames */
+
+    if (c2->softdec) {
+        float e = 0.0;
+        for(i=9; i<9+17; i++)
+            e += c2->softdec[i]*c2->softdec[i];
+        e /= 6.0;
+        //fprintf(stderr, "e: %f\n", e);
+        //if (e < 0.3)
+        //      bw_expand_lsps(&lsps[3][0], LPC_ORD_LOW, 150.0, 300.0);
+    }
+    #endif
+
+    /* interpolate ------------------------------------------------*/
+
+    /* LSPs, Wo, and energy are sampled every 40ms so we interpolate
+       the 3 frames in between, then recover spectral amplitudes */
+
+    for(i=0, weight=0.25; i<3; i++, weight += 0.25) {
+       interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD_LOW);
+        interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, c2->c2const.Wo_min);
+        e[i] = interp_energy2(c2->prev_e_dec, e[3],weight);
+    }
+    for(i=0; i<4; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD_LOW);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+
+    #ifdef DUMP
+    dump_lsp_(&lsps[3][0]);
+    dump_ak_(&ak[3][0], LPC_ORD_LOW);
+    dump_model(&model[3]);
+    if (c2->softdec)
+        dump_softdec(c2->softdec, nbit);
+    #endif
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[3];
+    c2->prev_e_dec = e[3];
+    for(i=0; i<LPC_ORD_LOW; i++)
+       c2->prev_lsps_dec[i] = lsps[3][i];
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_700b
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2015
+
+  Version b of 700 bit/s codec.  After some experiments over the air I
+  wanted was unhappy with the rate 700 codec so spent a few weeks
+  trying to improve the speech quality. This version uses a wider BPF
+  and vector quantised mel-lsps.
+
+  Encodes 320 speech samples (40ms of speech) into 28 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm four times:
+
+  frame 0: nothing
+  frame 1: nothing
+  frame 2: nothing
+  frame 3: voicing bit, 5 bit scalar Wo and 3 bit E, 18 bit LSP MEL VQ,
+           1 spare
+
+  The bit allocation is:
+
+    Parameter                      frames 1-3   frame 4   Total
+    -----------------------------------------------------------
+    Harmonic magnitudes (LSPs)          0         18        18
+    Energy                              0          3         3
+    log Wo                              0          5         5
+    Voicing                             0          1         1
+    spare                               0          1         1
+    TOTAL                               0         28        28
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_700b(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL   model;
+    float   lsps[LPC_ORD_LOW];
+    float   mel[LPC_ORD_LOW];
+    float   mel_[LPC_ORD_LOW];
+    float   ak[LPC_ORD_LOW+1];
+    float   e, f;
+    int     indexes[3];
+    int     Wo_index, e_index, i;
+    unsigned int nbit = 0;
+    float   bpf_out[4*c2->n_samp];
+    short   bpf_speech[4*c2->n_samp];
+    int     spare = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    /* band pass filter */
+
+    for(i=0; i<BPF_N; i++)
+        c2->bpf_buf[i] = c2->bpf_buf[4*c2->n_samp+i];
+    for(i=0; i<4*c2->n_samp; i++)
+        c2->bpf_buf[BPF_N+i] = speech[i];
+    inverse_filter(&c2->bpf_buf[BPF_N], bpfb, 4*c2->n_samp, bpf_out, BPF_N-1);
+    for(i=0; i<4*c2->n_samp; i++)
+        bpf_speech[i] = bpf_out[i];
+
+    /* frame 1 --------------------------------------------------------*/
+
+    analyse_one_frame(c2, &model, bpf_speech);
+
+    /* frame 2 --------------------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &bpf_speech[c2->n_samp]);
+
+    /* frame 3 --------------------------------------------------------*/
+
+    analyse_one_frame(c2, &model, &bpf_speech[2*c2->n_samp]);
+
+    /* frame 4: - voicing, scalar Wo & E, VQ mel LSPs -----------------*/
+
+    analyse_one_frame(c2, &model, &bpf_speech[3*c2->n_samp]);
+    pack(bits, &nbit, model.voiced, 1);
+    Wo_index = encode_log_Wo(&c2->c2const, model.Wo, 5);
+    pack_natural_or_gray(bits, &nbit, Wo_index, 5, c2->gray);
+
+    e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, c2->m_pitch, LPC_ORD_LOW);
+    e_index = encode_energy(e, 3);
+    pack_natural_or_gray(bits, &nbit, e_index, 3, c2->gray);
+
+    for(i=0; i<LPC_ORD_LOW; i++) {
+        f = (4000.0/PI)*lsps[i];
+        mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5);
+    }
+    lspmelvq_mbest_encode(indexes, mel, mel_, LPC_ORD_LOW, 5);
+
+    for(i=0; i<3; i++) {
+        pack_natural_or_gray(bits, &nbit, indexes[i], lspmelvq_cb_bits(i), c2->gray);
+    }
+
+    pack_natural_or_gray(bits, &nbit, spare, 1, c2->gray);
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_700b
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2015
+
+  Decodes frames of 28 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_700b(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[4];
+    int     indexes[3];
+    float   mel[LPC_ORD_LOW];
+    float   lsps[4][LPC_ORD_LOW];
+    int     Wo_index, e_index;
+    float   e[4];
+    float   snr, f_;
+    float   ak[4][LPC_ORD_LOW+1];
+    int     i,j;
+    unsigned int nbit = 0;
+    float   weight;
+    COMP    Aw[FFT_ENC];
+
+    assert(c2 != NULL);
+
+    /* only need to zero these out due to (unused) snr calculation */
+
+    for(i=0; i<4; i++)
+       for(j=1; j<=MAX_AMP; j++)
+           model[i].A[j] = 0.0;
+
+    /* unpack bits from channel ------------------------------------*/
+
+    model[3].voiced = unpack(bits, &nbit, 1);
+    model[0].voiced = model[1].voiced = model[2].voiced = model[3].voiced;
+
+    Wo_index = unpack_natural_or_gray(bits, &nbit, 5, c2->gray);
+    model[3].Wo = decode_log_Wo(&c2->c2const, Wo_index, 5);
+    model[3].L  = PI/model[3].Wo;
+
+    e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray);
+    e[3] = decode_energy(e_index, 3);
+
+    for(i=0; i<3; i++) {
+        indexes[i] = unpack_natural_or_gray(bits, &nbit, lspmelvq_cb_bits(i), c2->gray);
+    }
+
+    lspmelvq_decode(indexes, mel, LPC_ORD_LOW);
+
+    #define MEL_ROUND 10
+    for(i=1; i<LPC_ORD_LOW; i++) {
+        if (mel[i] <= mel[i-1]+MEL_ROUND) {
+            mel[i]+=MEL_ROUND/2;
+            mel[i-1]-=MEL_ROUND/2;
+            i = 1;
+        }
+    }
+
+    for(i=0; i<LPC_ORD_LOW; i++) {
+        f_ = 700.0*( pow(10.0, (float)mel[i]/2595.0) - 1.0);
+        lsps[3][i] = f_*(PI/4000.0);
+        //printf("lsps[3][%d]  %f\n", i, lsps[3][i]);
+    }
+
+    /* interpolate ------------------------------------------------*/
+
+    /* LSPs, Wo, and energy are sampled every 40ms so we interpolate
+       the 3 frames in between, then recover spectral amplitudes */
+
+    for(i=0, weight=0.25; i<3; i++, weight += 0.25) {
+       interpolate_lsp_ver2(&lsps[i][0], c2->prev_lsps_dec, &lsps[3][0], weight, LPC_ORD_LOW);
+        interp_Wo2(&model[i], &c2->prev_model_dec, &model[3], weight, c2->c2const.Wo_min);
+        e[i] = interp_energy2(c2->prev_e_dec, e[3],weight);
+    }
+    for(i=0; i<4; i++) {
+       lsp_to_lpc(&lsps[i][0], &ak[i][0], LPC_ORD_LOW);
+       aks_to_M2(c2->fftr_fwd_cfg, &ak[i][0], LPC_ORD_LOW, &model[i], e[i], &snr, 0, 0,
+                  c2->lpc_pf, c2->bass_boost, c2->beta, c2->gamma, Aw);
+       apply_lpc_correction(&model[i]);
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], Aw);
+    }
+
+    #ifdef DUMP
+    dump_lsp_(&lsps[3][0]);
+    dump_ak_(&ak[3][0], LPC_ORD_LOW);
+    dump_model(&model[3]);
+    if (c2->softdec)
+        dump_softdec(c2->softdec, nbit);
+    #endif
+
+    /* update memories for next frame ----------------------------*/
+
+    c2->prev_model_dec = model[3];
+    c2->prev_e_dec = e[3];
+    for(i=0; i<LPC_ORD_LOW; i++)
+       c2->prev_lsps_dec[i] = lsps[3][i];
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_encode_700c
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Version c of 700 bit/s codec that uses newamp1 fixed rate VQ of amplitudes.
+
+  Encodes 320 speech samples (40ms of speech) into 28 bits.
+
+  The codec2 algorithm actually operates internally on 10ms (80
+  sample) frames, so we run the encoding algorithm four times:
+
+  frame 0: nothing
+  frame 1: nothing
+  frame 2: nothing
+  frame 3: 18 bit 2 stage VQ (9 bits/stage), 4 bits energy, 
+           6 bit scalar Wo/voicing. No spare bits.
+
+  Voicing is encoded using the 0 index of the Wo quantiser.
+
+  The bit allocation is:
+
+    Parameter                      frames 1-3   frame 4   Total
+    -----------------------------------------------------------
+    Harmonic magnitudes (rate k VQ)     0         18        18
+    Energy                              0          4         4
+    log Wo/voicing                      0          6         6
+    TOTAL                               0         28        28
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_encode_700c(struct CODEC2 *c2, unsigned char * bits, short speech[])
+{
+    MODEL        model;
+    int          indexes[4], i, M=4;
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    memset(bits, '\0',  ((codec2_bits_per_frame(c2) + 7) / 8));
+
+    for(i=0; i<M; i++) {
+        analyse_one_frame(c2, &model, &speech[i*c2->n_samp]);
+    }
+
+    int K = 20;
+    float rate_K_vec[K], mean;
+    float rate_K_vec_no_mean[K], rate_K_vec_no_mean_[K];
+
+    newamp1_model_to_indexes(&c2->c2const, 
+                             indexes, 
+                             &model, 
+                             rate_K_vec, 
+                             c2->rate_K_sample_freqs_kHz,
+                             K,
+                             &mean,
+                             rate_K_vec_no_mean,
+                             rate_K_vec_no_mean_);
+
+    pack_natural_or_gray(bits, &nbit, indexes[0], 9, 0);
+    pack_natural_or_gray(bits, &nbit, indexes[1], 9, 0);
+    pack_natural_or_gray(bits, &nbit, indexes[2], 4, 0);
+    pack_natural_or_gray(bits, &nbit, indexes[3], 6, 0);
+
+    assert(nbit == (unsigned)codec2_bits_per_frame(c2));
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_decode_700c
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2015
+
+  Decodes frames of 28 bits into 320 samples (40ms) of speech.
+
+\*---------------------------------------------------------------------------*/
+
+void codec2_decode_700c(struct CODEC2 *c2, short speech[], const unsigned char * bits)
+{
+    MODEL   model[4];
+    int     indexes[4];
+    int     i;
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    /* unpack bits from channel ------------------------------------*/
+
+    indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0);
+    indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0);
+    indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0);
+    indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0);
+    
+    int M = 4;
+    COMP  HH[M][MAX_AMP+1];
+    float interpolated_surface_[M][NEWAMP1_K];
+
+    newamp1_indexes_to_model(&c2->c2const,
+                             model,
+                             (COMP*)HH,
+                             (float*)interpolated_surface_,
+                             c2->prev_rate_K_vec_,
+                             &c2->Wo_left,
+                             &c2->voicing_left,
+                             c2->rate_K_sample_freqs_kHz, 
+                             NEWAMP1_K,
+                             c2->phase_fft_fwd_cfg, 
+                             c2->phase_fft_inv_cfg,
+                             indexes);
+
+
+   for(i=0; i<M; i++) {
+       synthesise_one_frame(c2, &speech[c2->n_samp*i], &model[i], &HH[i][0]);
+   }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_energy_700c
+  AUTHOR......: Jeroen Vreeken
+  DATE CREATED: Jan 2017
+
+  Decodes energy value from encoded bits.
+
+\*---------------------------------------------------------------------------*/
+
+float codec2_energy_700c(struct CODEC2 *c2, const unsigned char * bits)
+{
+    int     indexes[4];
+    unsigned int nbit = 0;
+
+    assert(c2 != NULL);
+
+    /* unpack bits from channel ------------------------------------*/
+
+    indexes[0] = unpack_natural_or_gray(bits, &nbit, 9, 0);
+    indexes[1] = unpack_natural_or_gray(bits, &nbit, 9, 0);
+    indexes[2] = unpack_natural_or_gray(bits, &nbit, 4, 0);
+    indexes[3] = unpack_natural_or_gray(bits, &nbit, 6, 0);
+
+    float mean = newamp1_energy_cb[0].cb[indexes[2]];
+    mean -= 10;
+    if (indexes[3] == 0)
+       mean -= 10;
+
+    return powf(10.0, mean/10.0);
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: codec2_get_energy()
+  AUTHOR......: Jeroen Vreeken
+  DATE CREATED: 08/03/2016
+
+  Extract energy value from an encoded frame.
+
+\*---------------------------------------------------------------------------*/
+
+float codec2_get_energy(struct CODEC2 *c2, const unsigned char *bits)
+{
+    assert(c2 != NULL);
+    assert(
+          (c2->mode == CODEC2_MODE_3200) ||
+          (c2->mode == CODEC2_MODE_2400) ||
+          (c2->mode == CODEC2_MODE_1600) ||
+          (c2->mode == CODEC2_MODE_1400) ||
+          (c2->mode == CODEC2_MODE_1300) ||
+          (c2->mode == CODEC2_MODE_1200) ||
+          (c2->mode == CODEC2_MODE_700) ||
+          (c2->mode == CODEC2_MODE_700B) ||
+          (c2->mode == CODEC2_MODE_700C)
+          );
+    MODEL model;
+    float xq_dec[2] = {};
+    int e_index, WoE_index;
+    float e;
+    unsigned int nbit;
+
+    if (c2->mode == CODEC2_MODE_3200) {
+        nbit = 1 + 1 + WO_BITS;
+       e_index = unpack(bits, &nbit, E_BITS);
+        e = decode_energy(e_index, E_BITS);
+    }
+    if (c2->mode == CODEC2_MODE_2400) {
+        nbit = 1 + 1;
+        WoE_index = unpack(bits, &nbit, WO_E_BITS);
+        decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index);
+    }
+    if (c2->mode == CODEC2_MODE_1600) {
+        nbit = 1 + 1 + WO_BITS;
+        e_index = unpack(bits, &nbit, E_BITS);
+        e = decode_energy(e_index, E_BITS);
+    }
+    if (c2->mode == CODEC2_MODE_1400) {
+        nbit = 1 + 1;
+        WoE_index = unpack(bits, &nbit, WO_E_BITS);
+        decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index);
+    }
+    if (c2->mode == CODEC2_MODE_1300) {
+        nbit = 1 + 1 + 1 + 1 + WO_BITS;
+        e_index = unpack_natural_or_gray(bits, &nbit, E_BITS, c2->gray);
+        e = decode_energy(e_index, E_BITS);
+    }
+    if (c2->mode == CODEC2_MODE_1200) {
+        nbit = 1 + 1;
+        WoE_index = unpack(bits, &nbit, WO_E_BITS);
+        decode_WoE(&c2->c2const, &model, &e, xq_dec, WoE_index);
+    }
+    if (c2->mode == CODEC2_MODE_700) {
+        nbit = 1 + 5;
+        e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray);
+        e = decode_energy(e_index, 3);
+    }
+    if (c2->mode == CODEC2_MODE_700B) {
+        nbit = 1 + 5;
+        e_index = unpack_natural_or_gray(bits, &nbit, 3, c2->gray);
+        e = decode_energy(e_index, 3);
+    }
+    if (c2->mode == CODEC2_MODE_700C) {
+        e = codec2_energy_700c(c2, bits);
+    }
+    
+    return e;
+}
+
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: synthesise_one_frame()
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/8/2010
+
+  Synthesise 80 speech samples (10ms) from model parameters.
+
+\*---------------------------------------------------------------------------*/
+
+void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, COMP Aw[])
+{
+    int     i;
+    PROFILE_VAR(phase_start, pf_start, synth_start);
+
+    #ifdef DUMP
+    dump_quantised_model(model);
+    #endif
+
+    PROFILE_SAMPLE(phase_start);
+
+    if (c2->mode == CODEC2_MODE_700C) {
+        /* newamp1, we've already worked out rate L phase */
+        COMP *H = Aw;
+        phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H);       
+    } else {
+        /* LPC based phase synthesis */
+        COMP H[MAX_AMP+1];
+        sample_phase(model, H, Aw);
+        phase_synth_zero_order(c2->n_samp, model, &c2->ex_phase, H);
+    }
+
+    PROFILE_SAMPLE_AND_LOG(pf_start, phase_start, "    phase_synth");
+
+    postfilter(model, &c2->bg_est);
+
+    PROFILE_SAMPLE_AND_LOG(synth_start, pf_start, "    postfilter");
+
+    synthesise(c2->n_samp, c2->fftr_inv_cfg, c2->Sn_, model, c2->Pn, 1);
+
+    PROFILE_SAMPLE_AND_LOG2(synth_start, "    synth");
+
+    ear_protection(c2->Sn_, c2->n_samp);
+
+    for(i=0; i<c2->n_samp; i++) {
+       if (c2->Sn_[i] > 32767.0)
+           speech[i] = 32767;
+       else if (c2->Sn_[i] < -32767.0)
+           speech[i] = -32767;
+       else
+           speech[i] = c2->Sn_[i];
+    }
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: analyse_one_frame()
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/8/2010
+
+  Extract sinusoidal model parameters from 80 speech samples (10ms of
+  speech).
+
+\*---------------------------------------------------------------------------*/
+
+void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[])
+{
+    COMP    Sw[FFT_ENC];
+    float   pitch;
+    int     i;
+    PROFILE_VAR(dft_start, nlp_start, model_start, two_stage, estamps);
+    int     n_samp = c2->n_samp;
+    int     m_pitch = c2->m_pitch;
+
+    /* Read input speech */
+
+    for(i=0; i<m_pitch-n_samp; i++)
+      c2->Sn[i] = c2->Sn[i+n_samp];
+    for(i=0; i<n_samp; i++)
+      c2->Sn[i+m_pitch-n_samp] = speech[i];
+
+    PROFILE_SAMPLE(dft_start);
+    dft_speech(&c2->c2const, c2->fft_fwd_cfg, Sw, c2->Sn, c2->w);
+    PROFILE_SAMPLE_AND_LOG(nlp_start, dft_start, "    dft_speech");
+
+    /* Estimate pitch */
+
+    nlp(c2->nlp, c2->Sn, n_samp, &pitch, Sw, c2->W, &c2->prev_f0_enc);
+    PROFILE_SAMPLE_AND_LOG(model_start, nlp_start, "    nlp");
+
+    model->Wo = TWO_PI/pitch;
+    model->L = PI/model->Wo;
+
+    /* estimate model parameters */
+
+    two_stage_pitch_refinement(&c2->c2const, model, Sw);
+    PROFILE_SAMPLE_AND_LOG(two_stage, model_start, "    two_stage");
+    estimate_amplitudes(model, Sw, c2->W, 0);
+    PROFILE_SAMPLE_AND_LOG(estamps, two_stage, "    est_amps");
+    est_voicing_mbe(&c2->c2const, model, Sw, c2->W);
+    PROFILE_SAMPLE_AND_LOG2(estamps, "    est_voicing");
+    #ifdef DUMP
+    dump_model(model);
+    #endif
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: ear_protection()
+  AUTHOR......: David Rowe
+  DATE CREATED: Nov 7 2012
+
+  Limits output level to protect ears when there are bit errors or the input
+  is overdriven.  This doesn't correct or mask bit errors, just reduces the
+  worst of their damage.
+
+\*---------------------------------------------------------------------------*/
+
+static void ear_protection(float in_out[], int n) {
+    float max_sample, over, gain;
+    int   i;
+
+    /* find maximum sample in frame */
+
+    max_sample = 0.0;
+    for(i=0; i<n; i++)
+        if (in_out[i] > max_sample)
+            max_sample = in_out[i];
+
+    /* determine how far above set point */
+
+    over = max_sample/30000.0;
+
+    /* If we are x dB over set point we reduce level by 2x dB, this
+       attenuates major excursions in amplitude (likely to be caused
+       by bit errors) more than smaller ones */
+
+    if (over > 1.0) {
+        gain = 1.0/(over*over);
+        //fprintf(stderr, "gain: %f\n", gain);
+        for(i=0; i<n; i++)
+            in_out[i] *= gain;
+    }
+}
+
+void codec2_set_lpc_post_filter(struct CODEC2 *c2, int enable, int bass_boost, float beta, float gamma)
+{
+    assert((beta >= 0.0) && (beta <= 1.0));
+    assert((gamma >= 0.0) && (gamma <= 1.0));
+    c2->lpc_pf = enable;
+    c2->bass_boost = bass_boost;
+    c2->beta = beta;
+    c2->gamma = gamma;
+}
+
+/*
+   Allows optional stealing of one of the voicing bits for use as a
+   spare bit, only 1300 & 1400 & 1600 bit/s supported for now.
+   Experimental method of sending voice/data frames for FreeDV.
+*/
+
+int codec2_get_spare_bit_index(struct CODEC2 *c2)
+{
+    assert(c2 != NULL);
+
+    switch(c2->mode) {
+    case CODEC2_MODE_1300:
+        return 2; // bit 2 (3th bit) is v2 (third voicing bit)
+        break;
+    case CODEC2_MODE_1400:
+        return 10; // bit 10 (11th bit) is v2 (third voicing bit)
+        break;
+    case CODEC2_MODE_1600:
+        return 15; // bit 15 (16th bit) is v2 (third voicing bit)
+        break;
+    case CODEC2_MODE_700:
+        return 26; // bits 26 and 27 are spare
+        break;
+    case CODEC2_MODE_700B:
+        return 27; // bit 27 is spare
+        break;
+    }
+
+    return -1;
+}
+
+/*
+   Reconstructs the spare voicing bit.  Note works on unpacked bits
+   for convenience.
+*/
+
+int codec2_rebuild_spare_bit(struct CODEC2 *c2, int unpacked_bits[])
+{
+    int v1,v3;
+
+    assert(c2 != NULL);
+
+    v1 = unpacked_bits[1];
+
+    switch(c2->mode) {
+    case CODEC2_MODE_1300:
+
+        v3 = unpacked_bits[1+1+1];
+
+        /* if either adjacent frame is voiced, make this one voiced */
+
+        unpacked_bits[2] = (v1 || v3);
+
+        return 0;
+
+        break;
+
+    case CODEC2_MODE_1400:
+
+        v3 = unpacked_bits[1+1+8+1];
+
+        /* if either adjacent frame is voiced, make this one voiced */
+
+        unpacked_bits[10] = (v1 || v3);
+
+        return 0;
+
+        break;
+
+    case CODEC2_MODE_1600:
+        v3 = unpacked_bits[1+1+8+5+1];
+
+        /* if either adjacent frame is voiced, make this one voiced */
+
+        unpacked_bits[15] = (v1 || v3);
+
+        return 0;
+
+        break;
+    }
+
+    return -1;
+}
+
+void codec2_set_natural_or_gray(struct CODEC2 *c2, int gray)
+{
+    assert(c2 != NULL);
+    c2->gray = gray;
+}
+
+void codec2_set_softdec(struct CODEC2 *c2, float *softdec)
+{
+    assert(c2 != NULL);
+    c2->softdec = softdec;
+}
+
diff --git a/codec2/branches/0.7/src/codec2.h b/codec2/branches/0.7/src/codec2.h
new file mode 100644 (file)
index 0000000..0e720f9
--- /dev/null
@@ -0,0 +1,69 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 21 August 2010
+
+  Codec 2 fully quantised encoder and decoder functions.  If you want use
+  Codec 2, these are the functions you need to call.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+#ifndef __CODEC2__
+#define  __CODEC2__
+
+#define CODEC2_MODE_3200 0
+#define CODEC2_MODE_2400 1
+#define CODEC2_MODE_1600 2
+#define CODEC2_MODE_1400 3
+#define CODEC2_MODE_1300 4
+#define CODEC2_MODE_1200 5
+#define CODEC2_MODE_700  6
+#define CODEC2_MODE_700B 7
+#define CODEC2_MODE_700C 8
+
+struct CODEC2;
+
+struct CODEC2 *  codec2_create(int mode);
+void codec2_destroy(struct CODEC2 *codec2_state);
+void codec2_encode(struct CODEC2 *codec2_state, unsigned char * bits, short speech_in[]);
+void codec2_decode(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits);
+void codec2_decode_ber(struct CODEC2 *codec2_state, short speech_out[], const unsigned char *bits, float ber_est);
+int  codec2_samples_per_frame(struct CODEC2 *codec2_state);
+int  codec2_bits_per_frame(struct CODEC2 *codec2_state);
+
+void codec2_set_lpc_post_filter(struct CODEC2 *codec2_state, int enable, int bass_boost, float beta, float gamma);
+int  codec2_get_spare_bit_index(struct CODEC2 *codec2_state);
+int  codec2_rebuild_spare_bit(struct CODEC2 *codec2_state, int unpacked_bits[]);
+void codec2_set_natural_or_gray(struct CODEC2 *codec2_state, int gray);
+void codec2_set_softdec(struct CODEC2 *c2, float *softdec);
+float codec2_get_energy(struct CODEC2 *codec2_state, const unsigned char *bits);
+
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/codec2/branches/0.7/src/codec2_cohpsk.h b/codec2/branches/0.7/src/codec2_cohpsk.h
new file mode 100644 (file)
index 0000000..a0ad488
--- /dev/null
@@ -0,0 +1,68 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2_cohpsk.h
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+
+  Functions that implement a coherent PSK FDM modem.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CODEC2_COHPSK__
+#define __CODEC2_COHPSK__
+
+#define COHPSK_BITS_PER_FRAME         56              /* hard coded for now */
+#define COHPSK_NC                      7              /* hard coded for now */
+#define COHPSK_NOM_SAMPLES_PER_FRAME 600
+#define COHPSK_MAX_SAMPLES_PER_FRAME 625
+#define COHPSK_RS                     75
+#define COHPSK_FS                   7500              /* note this is a wierd
+                                                         value to get an integer
+                                                         oversampling rate */
+
+#include "comp.h"
+#include "modem_stats.h"
+
+struct COHPSK;
+
+extern const int test_bits_coh[];
+
+struct COHPSK *cohpsk_create(void);
+void cohpsk_destroy(struct COHPSK *coh);
+void cohpsk_mod(struct COHPSK *cohpsk, COMP tx_fdm[], int tx_bits[], int nbits);
+void cohpsk_clip(COMP tx_fdm[]);
+void cohpsk_demod(struct COHPSK *cohpsk, float rx_bits[], int *sync, COMP rx_fdm[], int *nin_frame);
+void cohpsk_get_demod_stats(struct COHPSK *cohpsk, struct MODEM_STATS *stats);
+void cohpsk_set_verbose(struct COHPSK *coh, int verbose);
+void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[]);
+void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
+                          int *bit_errors, char rx_bits[], int channel);
+int cohpsk_error_pattern_size(void);
+void cohpsk_set_frame(struct COHPSK *coh, int frame);
+void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs,
+                          COMP *foff_phase_rect, int nin);
+
+/* used for accessing upper and lower bits before diversity combination */
+
+float *cohpsk_get_rx_bits_lower(struct COHPSK *coh);
+float *cohpsk_get_rx_bits_upper(struct COHPSK *coh);
+void cohpsk_set_carrier_ampl(struct COHPSK *coh, int c, float ampl);
+
+#endif
diff --git a/codec2/branches/0.7/src/codec2_fdmdv.h b/codec2/branches/0.7/src/codec2_fdmdv.h
new file mode 100644 (file)
index 0000000..4298fab
--- /dev/null
@@ -0,0 +1,113 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2_fdmdv.h
+  AUTHOR......: David Rowe
+  DATE CREATED: April 14 2012
+
+  A 1400 bit/s (nominal) Frequency Division Multiplexed Digital Voice
+  (FDMDV) modem.  Used for digital audio over HF SSB. See
+  README_fdmdv.txt for more information, and fdmdv_mod.c and
+  fdmdv_demod.c for example usage.
+
+  The name codec2_fdmdv.h is used to make it unique when "make
+  installed".
+
+  References:
+
+    [1] http://n1su.com/fdmdv/FDMDV_Docs_Rel_1_4b.pdf
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __FDMDV__
+#define __FDMDV__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* set up the calling convention for DLL function import/export for
+   WIN32 cross compiling */
+
+#ifdef __CODEC2_WIN32__
+#ifdef __CODEC2_BUILDING_DLL__
+#define CODEC2_WIN32SUPPORT __declspec(dllexport) __stdcall
+#else
+#define CODEC2_WIN32SUPPORT __declspec(dllimport) __stdcall
+#endif
+#else
+#define CODEC2_WIN32SUPPORT
+#endif
+
+#include "comp.h"
+#include "modem_stats.h"
+
+#define FDMDV_NC                      14  /* default number of data carriers                                */
+#define FDMDV_NC_MAX                  20  /* maximum number of data carriers                                */
+#define FDMDV_BITS_PER_FRAME          28  /* 20ms frames, for nominal 1400 bit/s                            */
+#define FDMDV_NOM_SAMPLES_PER_FRAME  160  /* modulator output samples/frame and nominal demod samples/frame */
+                                          /* at 8000 Hz sample rate                                         */
+#define FDMDV_MAX_SAMPLES_PER_FRAME  200  /* max demod samples/frame, use this to allocate storage          */
+#define FDMDV_SCALE                 1000  /* suggested scaling for 16 bit shorts                            */
+#define FDMDV_FCENTRE               1500  /* Centre frequency, Nc/2 carriers below this, Nc/2 carriers above (Hz) */
+
+/* 8 to 48 kHz sample rate conversion */
+
+#define FDMDV_OS                 2                            /* oversampling rate                   */
+#define FDMDV_OS_TAPS_16K       48                            /* number of OS filter taps at 16kHz   */
+#define FDMDV_OS_TAPS_8K        (FDMDV_OS_TAPS_16K/FDMDV_OS)  /* number of OS filter taps at 8kHz    */
+
+/* FDMDV states and stats structures */
+
+struct FDMDV;
+
+struct FDMDV * fdmdv_create(int Nc);
+void           fdmdv_destroy(struct FDMDV *fdmdv_state);
+void           fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv_state);
+int            fdmdv_bits_per_frame(struct FDMDV *fdmdv_state);
+float          fdmdv_get_fsep(struct FDMDV *fdmdv_state);
+void           fdmdv_set_fsep(struct FDMDV *fdmdv_state, float fsep);
+
+void           fdmdv_mod(struct FDMDV *fdmdv_state, COMP tx_fdm[], int tx_bits[], int *sync_bit);
+void           fdmdv_demod(struct FDMDV *fdmdv_state, int rx_bits[], int *reliable_sync_bit, COMP rx_fdm[], int *nin);
+
+void           fdmdv_get_test_bits(struct FDMDV *fdmdv_state, int tx_bits[]);
+int            fdmdv_error_pattern_size(struct FDMDV *fdmdv_state);
+void           fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[], int *bit_errors, int *ntest_bits, int rx_bits[]);
+
+void           fdmdv_get_demod_stats(struct FDMDV *fdmdv_state, struct MODEM_STATS *stats);
+
+void           fdmdv_8_to_16(float out16k[], float in8k[], int n);
+void           fdmdv_8_to_16_short(short out16k[], short in8k[], int n);
+void           fdmdv_16_to_8(float out8k[], float in16k[], int n);
+void           fdmdv_16_to_8_short(short out8k[], short in16k[], int n);
+
+void           fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin);
+
+/* debug/development function(s) */
+
+void fdmdv_dump_osc_mags(struct FDMDV *f);
+void fdmdv_simulate_channel(float *sig_pwr_av, COMP samples[], int nin, float target_snr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/codec2/branches/0.7/src/codec2_fft.c b/codec2/branches/0.7/src/codec2_fft.c
new file mode 100644 (file)
index 0000000..e91ff2a
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * codec2_fft.c
+ *
+ *  Created on: 24.09.2016
+ *      Author: danilo
+ */
+
+#include "codec2_fft.h"
+#ifdef USE_KISS_FFT
+#include "_kiss_fft_guts.h"
+
+#else
+#if 0
+// caching constants in RAM did not seem to have an effect on performance
+// TODO: Decide what to with this code
+#define FFT_INIT_CACHE_SIZE 4
+const arm_cfft_instance_f32* fft_init_cache[FFT_INIT_CACHE_SIZE];
+
+static const arm_cfft_instance_f32* arm_fft_instance2ram(const arm_cfft_instance_f32* in)
+{
+
+    arm_cfft_instance_f32* out = malloc(sizeof(arm_cfft_instance_f32));
+
+    if (out) {
+        memcpy(out,in,sizeof(arm_cfft_instance_f32));
+        out->pBitRevTable = malloc(out->bitRevLength * sizeof(uint16_t));
+        out->pTwiddle = malloc(out->fftLen * sizeof(float32_t));
+        memcpy((void*)out->pBitRevTable,in->pBitRevTable,out->bitRevLength * sizeof(uint16_t));
+        memcpy((void*)out->pTwiddle,in->pTwiddle,out->fftLen * sizeof(float32_t));
+    }
+    return out;
+}
+
+
+static const arm_cfft_instance_f32* arm_fft_cache_get(const arm_cfft_instance_f32* romfft)
+{
+    const arm_cfft_instance_f32* retval = NULL;
+    static int used = 0;
+    for (int i = 0; fft_init_cache[i] != NULL && i < used; i++)
+    {
+        if (romfft->fftLen == fft_init_cache[i]->fftLen)
+        {
+            retval = fft_init_cache[i];
+            break;
+        }
+    }
+    if (retval == NULL && used < FFT_INIT_CACHE_SIZE)
+    {
+         retval = arm_fft_instance2ram(romfft);
+         fft_init_cache[used++] = retval;
+    }
+    if (retval == NULL)
+    {
+        retval = romfft;
+    }
+    return retval;
+}
+#endif
+#endif
+
+void codec2_fft_free(codec2_fft_cfg cfg)
+{
+#ifdef USE_KISS_FFT
+    KISS_FFT_FREE(cfg);
+#else
+    free(cfg);
+#endif
+}
+
+codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem)
+{
+    codec2_fft_cfg retval;
+#ifdef USE_KISS_FFT
+    retval = kiss_fft_alloc(nfft, inverse_fft, mem, lenmem);
+#else
+    retval = malloc(sizeof(codec2_fft_struct));
+    retval->inverse  = inverse_fft;
+    switch(nfft)
+    {
+    case 128:
+        retval->instance = &arm_cfft_sR_f32_len128;
+        break;
+    case 256:
+        retval->instance = &arm_cfft_sR_f32_len256;
+        break;
+    case 512:
+        retval->instance = &arm_cfft_sR_f32_len512;
+        break;
+//    case 1024:
+//        retval->instance = &arm_cfft_sR_f32_len1024;
+//        break;
+    default:
+        abort();
+    }
+    // retval->instance = arm_fft_cache_get(retval->instance);
+#endif
+    return retval;
+}
+
+codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem)
+{
+    codec2_fftr_cfg retval;
+#ifdef USE_KISS_FFT
+    retval = kiss_fftr_alloc(nfft, inverse_fft, mem, lenmem);
+#else
+    retval = malloc(sizeof(codec2_fftr_struct));
+    retval->inverse  = inverse_fft;
+    retval->instance = malloc(sizeof(arm_rfft_fast_instance_f32));
+    arm_rfft_fast_init_f32(retval->instance,nfft);
+    // memcpy(&retval->instance->Sint,arm_fft_cache_get(&retval->instance->Sint),sizeof(arm_cfft_instance_f32));
+#endif
+    return retval;
+}
+void codec2_fftr_free(codec2_fftr_cfg cfg)
+{
+#ifdef USE_KISS_FFT
+    KISS_FFT_FREE(cfg);
+#else
+    free(cfg->instance);
+    free(cfg);
+#endif
+}
+
+// there is a little overhead for inplace kiss_fft but this is
+// on the powerful platforms like the Raspberry or even x86 PC based ones
+// not noticeable
+// the reduced usage of RAM and increased performance on STM32 platforms
+// should be worth it.
+void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout)
+{
+
+#ifdef USE_KISS_FFT
+    kiss_fft_cpx in[512];
+    // decide whether to use the local stack based buffer for in
+    // or to allow kiss_fft to allocate RAM
+    // second part is just to play safe since first method
+    // is much faster and uses less RAM
+    if (cfg->nfft <= 512)
+    {
+        memcpy(in,inout,cfg->nfft*sizeof(kiss_fft_cpx));
+        kiss_fft(cfg, in, (kiss_fft_cpx*)inout);
+    }
+    else
+    {
+        kiss_fft(cfg, (kiss_fft_cpx*)inout, (kiss_fft_cpx*)inout);
+    }
+#else
+    arm_cfft_f32(cfg->instance,(float*)inout,cfg->inverse,1);
+    if (cfg->inverse)
+    {
+        arm_scale_f32(inout,cfg->instance->fftLen,inout,cfg->instance->fftLen*2);
+    }
+
+#endif
+}
diff --git a/codec2/branches/0.7/src/codec2_fft.h b/codec2/branches/0.7/src/codec2_fft.h
new file mode 100644 (file)
index 0000000..d421c47
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * codec2_fft.h
+ *
+ *  Created on: 17.09.2016
+ *      Author: danilo
+ */
+
+#ifndef DRIVERS_FREEDV_CODEC2_FFT_H_
+#define DRIVERS_FREEDV_CODEC2_FFT_H_
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef ARM_MATH_CM4
+  #include "stm32f4xx.h"
+  #include "core_cm4.h"
+  #include "arm_math.h"
+  #include "arm_const_structs.h"
+#endif
+
+#include "defines.h"
+#include "comp.h"
+
+#ifndef ARM_MATH_CM4
+    #define USE_KISS_FFT
+#endif
+// #define USE_KISS_FFT
+
+
+typedef COMP    codec2_fft_cpx;
+#include "kiss_fftr.h"
+
+#ifdef USE_KISS_FFT
+    #include "kiss_fft.h"
+    typedef kiss_fftr_cfg codec2_fftr_cfg;
+    typedef kiss_fft_cfg codec2_fft_cfg;
+    typedef kiss_fft_scalar codec2_fft_scalar;
+#else
+  typedef float32_t codec2_fft_scalar;
+  typedef struct {
+      arm_rfft_fast_instance_f32* instance;
+      int inverse;
+  } codec2_fftr_struct;
+
+  typedef codec2_fftr_struct* codec2_fftr_cfg;
+
+  typedef struct {
+        const arm_cfft_instance_f32* instance;
+        int inverse;
+    } codec2_fft_struct;
+  typedef codec2_fft_struct* codec2_fft_cfg;
+#endif
+
+
+
+static inline void codec2_fftr(codec2_fftr_cfg cfg, codec2_fft_scalar* in, codec2_fft_cpx* out)
+{
+
+#ifdef USE_KISS_FFT
+      kiss_fftr(cfg, in, (kiss_fft_cpx*)out);
+#else
+    arm_rfft_fast_f32(cfg->instance,in,(float*)out,cfg->inverse);
+    out->imag = 0; // remove out[FFT_ENC/2]->real stored in out[0].imag
+#endif
+}
+
+static inline void codec2_fftri(codec2_fftr_cfg cfg, codec2_fft_cpx* in, codec2_fft_scalar* out)
+{
+#ifdef USE_KISS_FFT
+      kiss_fftri(cfg, (kiss_fft_cpx*)in, out);
+#else
+    arm_rfft_fast_f32(cfg->instance,(float*)in,out,cfg->inverse);
+    // arm_scale_f32(out,cfg->instance->fftLenRFFT,out,cfg->instance->fftLenRFFT);
+#endif
+
+}
+
+codec2_fft_cfg codec2_fft_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem);
+codec2_fftr_cfg codec2_fftr_alloc(int nfft, int inverse_fft, void* mem, size_t* lenmem);
+void codec2_fft_free(codec2_fft_cfg cfg);
+void codec2_fftr_free(codec2_fftr_cfg cfg);
+
+
+static inline void codec2_fft(codec2_fft_cfg cfg, codec2_fft_cpx* in, codec2_fft_cpx* out)
+{
+
+#ifdef USE_KISS_FFT
+      kiss_fft(cfg, (kiss_fft_cpx*)in, (kiss_fft_cpx*)out);
+#else
+    memcpy(out,in,cfg->instance->fftLen*2*sizeof(float));
+    arm_cfft_f32(cfg->instance,(float*)out,cfg->inverse,0);
+    // TODO: this is not nice, but for now required to keep changes minimal
+    // however, since main goal is to reduce the memory usage
+    // we should convert to an in place interface
+    // on PC like platforms the overhead of using the "inplace" kiss_fft calls
+    // is neglectable compared to the gain in memory usage on STM32 platforms
+    if (cfg->inverse)
+    {
+        arm_scale_f32((float*)out,cfg->instance->fftLen,(float*)out,cfg->instance->fftLen*2);
+    }
+#endif
+}
+
+void codec2_fft_inplace(codec2_fft_cfg cfg, codec2_fft_cpx* inout);
+
+
+#endif
diff --git a/codec2/branches/0.7/src/codec2_fifo.h b/codec2/branches/0.7/src/codec2_fifo.h
new file mode 100644 (file)
index 0000000..5a90b75
--- /dev/null
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2_fifo.h
+  AUTHOR......: David Rowe
+  DATE CREATED: Oct 15 2012
+
+  A FIFO design useful in gluing the FDMDV modem and codec together in
+  integrated applications.
+
+  The name codec2_fifo.h is used to make it unique when "make
+  installed".
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __FIFO__
+#define __FIFO__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct FIFO;
+
+struct FIFO *fifo_create(int nshort);
+void fifo_destroy(struct FIFO *fifo);
+int fifo_write(struct FIFO *fifo, short data[], int n);
+int fifo_read(struct FIFO *fifo, short data[], int n);
+
+/*!
+ * Return the number of bytes stored in the FIFO.
+ */
+int fifo_used(const struct FIFO * const fifo);
+
+/*!
+ * Return the space available in the FIFO.
+ */
+int fifo_free(const struct FIFO * const fifo);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/src/codec2_fm.h b/codec2/branches/0.7/src/codec2_fm.h
new file mode 100644 (file)
index 0000000..36faece
--- /dev/null
@@ -0,0 +1,53 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2_fm.h
+  AUTHOR......: David Rowe
+  DATE CREATED: February 2015
+
+  Functions that implement analog FM, see also octave/fm.m.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CODEC2_FM__
+#define __CODEC2_FM__
+
+#include "comp.h"
+
+struct FM {
+    float  Fs;               /* setme: sample rate                  */
+    float  fm_max;           /* setme: maximum modulation frequency */
+    float  fd;               /* setme: maximum deviation            */
+    float  fc;               /* setme: carrier frequency            */
+    COMP  *rx_bb;
+    COMP   rx_bb_filt_prev;
+    float *rx_dem_mem;
+    float  tx_phase;
+    int    nsam;
+    COMP   lo_phase;
+};
+
+struct FM *fm_create(int nsam);
+void fm_destroy(struct FM *fm_states);
+void fm_demod(struct FM *fm, float rx_out[], float rx[]);
+void fm_mod(struct FM *fm, float tx_in[], float tx_out[]);
+void fm_mod_comp(struct FM *fm_states, float tx_in[], COMP tx_out[]);
+
+#endif
+
diff --git a/codec2/branches/0.7/src/codec2_internal.h b/codec2/branches/0.7/src/codec2_internal.h
new file mode 100644 (file)
index 0000000..48fcb99
--- /dev/null
@@ -0,0 +1,86 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2_internal.h
+  AUTHOR......: David Rowe
+  DATE CREATED: April 16 2012
+
+  Header file for Codec2 internal states, exposed via this header
+  file to assist in testing.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CODEC2_INTERNAL__
+#define __CODEC2_INTERNAL__
+
+#include "codec2_fft.h"
+#include "newamp1.h"
+
+struct CODEC2 {
+    int           mode;
+    C2CONST       c2const;
+    int           Fs;
+    int           n_samp;
+    int           m_pitch;
+    codec2_fft_cfg  fft_fwd_cfg;           /* forward FFT config                        */
+    codec2_fftr_cfg fftr_fwd_cfg;          /* forward real FFT config                   */
+    float        *w;                      /* [m_pitch] time domain hamming window      */
+    COMP          W[FFT_ENC];             /* DFT of w[]                                */
+    float        *Pn;                     /* [2*n_samp] trapezoidal synthesis window   */
+    float        *bpf_buf;                 /* buffer for band pass filter               */
+    float        *Sn;                      /* [m_pitch] input speech                    */
+    float         hpf_states[2];           /* high pass filter states                   */
+    void         *nlp;                     /* pitch predictor states                    */
+    int           gray;                    /* non-zero for gray encoding                */
+
+    codec2_fftr_cfg  fftr_inv_cfg;         /* inverse FFT config                        */
+    float        *Sn_;                    /* [2*n_samp] synthesised output speech      */
+    float         ex_phase;                /* excitation model phase track              */
+    float         bg_est;                  /* background noise estimate for post filter */
+    float         prev_f0_enc;             /* previous frame's f0    estimate           */
+    MODEL         prev_model_dec;          /* previous frame's model parameters         */
+    float         prev_lsps_dec[LPC_ORD];  /* previous frame's LSPs                     */
+    float         prev_e_dec;              /* previous frame's LPC energy               */
+
+    int           lpc_pf;                  /* LPC post filter on                        */
+    int           bass_boost;              /* LPC post filter bass boost                */
+    float         beta;                    /* LPC post filter parameters                */
+    float         gamma;
+
+    float         xq_enc[2];               /* joint pitch and energy VQ states          */
+    float         xq_dec[2];
+
+    int           smoothing;               /* enable smoothing for channels with errors */
+    float        *softdec;                 /* optional soft decn bits from demod        */
+
+    /* newamp1 states */
+
+    float          rate_K_sample_freqs_kHz[NEWAMP1_K];
+    float          prev_rate_K_vec_[NEWAMP1_K];
+    float          Wo_left;
+    int            voicing_left;
+    codec2_fft_cfg phase_fft_fwd_cfg;
+    codec2_fft_cfg phase_fft_inv_cfg;      
+};
+
+// test and debug
+void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]);
+void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model,
+                         COMP Aw[]);
+#endif
diff --git a/codec2/branches/0.7/src/codec2_ofdm.h b/codec2/branches/0.7/src/codec2_ofdm.h
new file mode 100644 (file)
index 0000000..9abd1a3
--- /dev/null
@@ -0,0 +1,69 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2_ofdm.h
+  AUTHORS.....: David Rowe & Steve Sampson
+  DATE CREATED: June 2017
+
+  External user references to the modem library.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2017 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef CODEC2_OFDM_H
+#define CODEC2_OFDM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes */
+    
+#include <complex.h>
+#include <stdbool.h>
+    
+#include "comp.h"
+
+/* Defines */
+
+struct OFDM;
+
+/* Prototypes */
+
+struct OFDM *ofdm_create(void);
+void ofdm_destroy(struct OFDM *);
+void ofdm_mod(struct OFDM *, COMP *, const int *);
+void ofdm_demod(struct OFDM *, int *, COMP *);
+int ofdm_get_nin(struct OFDM *);
+int ofdm_get_samples_per_frame(void);
+int ofdm_get_max_samples_per_frame(void);
+
+/* option setters */
+
+void ofdm_set_verbose(struct OFDM *, int);
+void ofdm_set_timing_enable(struct OFDM *, bool);
+void ofdm_set_foff_est_enable(struct OFDM *, bool);
+void ofdm_set_phase_est_enable(struct OFDM *, bool);
+void ofdm_set_off_est_hz(struct OFDM *, float);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/codec2/branches/0.7/src/cohpsk.c b/codec2/branches/0.7/src/cohpsk.c
new file mode 100644 (file)
index 0000000..303db04
--- /dev/null
@@ -0,0 +1,1303 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: cohpsk.c
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+
+  Functions that implement a coherent PSK FDM modem.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*---------------------------------------------------------------------------*\
+
+                               INCLUDES
+
+\*---------------------------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "codec2_cohpsk.h"
+#include "cohpsk_defs.h"
+#include "cohpsk_internal.h"
+#include "fdmdv_internal.h"
+#include "pilots_coh.h"
+#include "comp_prim.h"
+#include "kiss_fft.h"
+#include "linreg.h"
+#include "rn_coh.h"
+#include "test_bits_coh.h"
+
+static COMP qpsk_mod[] = {
+    { 1.0, 0.0},
+    { 0.0, 1.0},
+    { 0.0,-1.0},
+    {-1.0, 0.0}
+};
+
+static int sampling_points[] = {0, 1, 6, 7};
+
+void corr_with_pilots(float *corr_out, float *mag_out, struct COHPSK *coh, int t, float f_fine);
+void update_ct_symb_buf(COMP ct_symb_buf[][COHPSK_NC*ND], COMP ch_symb[][COHPSK_NC*ND]);
+
+/*---------------------------------------------------------------------------*\
+
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+
+/*--------------------------------------------------------------------------* \
+
+  FUNCTION....: cohpsk_create
+  AUTHOR......: David Rowe
+  DATE CREATED: Marcg 2015
+
+  Create and initialise an instance of the modem.  Returns a pointer
+  to the modem states or NULL on failure.  One set of states is
+  sufficient for a full duplex modem.
+
+\*---------------------------------------------------------------------------*/
+
+struct COHPSK *cohpsk_create(void)
+{
+    struct COHPSK *coh;
+    struct FDMDV  *fdmdv;
+    int            r,c,p,i;
+    float          freq_hz;
+
+    assert(COHPSK_NC == PILOTS_NC);
+    assert(COHPSK_NOM_SAMPLES_PER_FRAME == (COHPSK_M*NSYMROWPILOT));
+    assert(COHPSK_MAX_SAMPLES_PER_FRAME == (COHPSK_M*NSYMROWPILOT+COHPSK_M/P));
+    assert(COHPSK_ND == ND);
+    assert(COHPSK_NSYM == NSYM);  /* as we want to use the tx sym mem on fdmdv */
+    assert(COHPSK_NT == NT);
+
+    coh = (struct COHPSK*)malloc(sizeof(struct COHPSK));
+    if (coh == NULL)
+        return NULL;
+
+    /* set up buffer of tx pilot symbols for coh demod on rx */
+
+    for(r=0; r<2*NPILOTSFRAME; ) {
+        for(p=0; p<NPILOTSFRAME; r++, p++) {
+            for(c=0; c<COHPSK_NC; c++) {
+                coh->pilot2[r][c] = pilots_coh[p][c];
+            }
+        }
+    }
+
+    /* Clear symbol buffer memory */
+
+    for (r=0; r<NCT_SYMB_BUF; r++) {
+        for(c=0; c<COHPSK_NC*ND; c++) {
+            coh->ct_symb_buf[r][c].real = 0.0;
+            coh->ct_symb_buf[r][c].imag = 0.0;
+        }
+    }
+
+    coh->ff_phase.real = 1.0; coh->ff_phase.imag = 0.0;
+    coh->sync  = 0;
+    coh->frame = 0;
+    coh->ratio = 0.0;
+    coh->nin = COHPSK_M;
+
+    /* clear sync window buffer */
+
+    for (i=0; i<NSW*NSYMROWPILOT*COHPSK_M; i++) {
+        coh->ch_fdm_frame_buf[i].real = 0.0;
+        coh->ch_fdm_frame_buf[i].imag = 0.0;
+    }
+
+    /* set up fdmdv states so we can use those modem functions */
+
+    fdmdv = fdmdv_create(COHPSK_NC*ND - 1);
+    fdmdv->fsep = COHPSK_RS*(1.0 + COHPSK_EXCESS_BW);
+    for(c=0; c<COHPSK_NC*ND; c++) {
+       fdmdv->phase_tx[c].real = 1.0;
+       fdmdv->phase_tx[c].imag = 0.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]);
+        for(i=0; i<COHPSK_NFILTER; i++) {
+            coh->rx_filter_memory[c][i].real = 0.0;
+            coh->rx_filter_memory[c][i].imag = 0.0;
+        }
+
+        /* optional per-carrier amplitude weighting for testing */
+
+        coh->carrier_ampl[c] = 1.0;
+    }
+    fdmdv->fbb_rect.real     = cosf(2.0*PI*FDMDV_FCENTRE/COHPSK_FS);
+    fdmdv->fbb_rect.imag     = sinf(2.0*PI*FDMDV_FCENTRE/COHPSK_FS);
+    fdmdv->fbb_pol           = 2.0*PI*FDMDV_FCENTRE/COHPSK_FS;
+
+    coh->fdmdv = fdmdv;
+
+    coh->sig_rms = coh->noise_rms = 0.0;
+
+    for(c=0; c<COHPSK_NC*ND; c++) {
+        for (r=0; r<NSYMROW; r++) {
+            coh->rx_symb[r][c].real = 0.0;
+            coh->rx_symb[r][c].imag = 0.0;
+        }
+    }
+
+    coh->verbose = 0;
+
+    /* disable optional logging by default */
+
+    coh->rx_baseband_log = NULL;
+    coh->rx_baseband_log_col_index = 0;
+    coh->rx_filt_log = NULL;
+    coh->rx_filt_log_col_index = 0;
+    coh->ch_symb_log = NULL;
+    coh->ch_symb_log_r = 0;
+    coh->rx_timing_log = NULL;
+    coh->rx_timing_log_index = 0;
+
+    /* test frames */
+
+    coh->ptest_bits_coh_tx = coh->ptest_bits_coh_rx[0] = coh->ptest_bits_coh_rx[1] = (int*)test_bits_coh;
+    coh->ptest_bits_coh_end = (int*)test_bits_coh + sizeof(test_bits_coh)/sizeof(int);
+
+    return coh;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cohpsk_destroy
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+
+  Destroy an instance of the modem.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_destroy(struct COHPSK *coh)
+{
+    fdmdv_destroy(coh->fdmdv);
+    assert(coh != NULL);
+    free(coh);
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: bits_to_qpsk_symbols()
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+
+  Rate Rs modulator.  Maps bits to parallel DQPSK symbols and inserts pilot symbols.
+
+\*---------------------------------------------------------------------------*/
+
+void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC*ND], int tx_bits[], int nbits)
+{
+    int   i, r, c, p_r, data_r, d, diversity;
+    short bits;
+
+    /* check allowed number of bits supplied matches number of QPSK
+       symbols in the frame */
+
+    assert( (NSYMROW*COHPSK_NC*2 == nbits) || (NSYMROW*COHPSK_NC*2*ND == nbits));
+    
+    /* if we input twice as many bits we don't do diversity */
+
+    if (NSYMROW*COHPSK_NC*2 == nbits) {    
+        diversity = 1; /* diversity mode                         */
+    }
+    else {
+        diversity = 2; /* twice as many bits, non diversity mode */
+    }
+
+    /*
+      Insert two rows of Nc pilots at beginning of data frame.
+
+      Organise QPSK symbols into a NSYMBROWS rows by PILOTS_NC*ND cols matrix,
+      each column is a carrier, time flows down the cols......
+
+      Note: the "& 0x1" prevents and non binary tx_bits[] screwing up
+      our lives.  Call me defensive.
+
+      sqrtf(ND) term ensures the same energy/symbol for different
+      diversity factors.
+    */
+
+    r = 0;
+    for(p_r=0; p_r<2; p_r++) {
+        for(c=0; c<COHPSK_NC*ND; c++) {
+            tx_symb[r][c].real = pilots_coh[p_r][c % COHPSK_NC]/sqrtf(ND);
+            tx_symb[r][c].imag = 0.0;
+        }
+        r++;
+    }
+    for(data_r=0; data_r<NSYMROW; data_r++, r++) {
+        for(c=0; c<COHPSK_NC*diversity; c++) {
+            i = c*NSYMROW + data_r;
+            bits = (tx_bits[2*i]&0x1)<<1 | (tx_bits[2*i+1]&0x1);
+            tx_symb[r][c] = fcmult(1.0/sqrtf(ND),qpsk_mod[bits]);
+        }
+    }
+
+    assert(p_r == NPILOTSFRAME);
+    assert(r == NSYMROWPILOT);
+
+    /* if in diversity mode, copy symbols to upper carriers */
+
+    for(d=1; d<1+ND-diversity; d++) {
+        for(r=0; r<NSYMROWPILOT; r++) {
+            for(c=0; c<COHPSK_NC; c++) {
+                tx_symb[r][c+COHPSK_NC*d] = tx_symb[r][c];
+            }
+        }
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: qpsk_symbols_to_bits()
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+
+  Rate Rs demodulator. Extract pilot symbols and estimate amplitude and phase
+  of each carrier.  Correct phase of data symbols and convert to bits.
+
+  Further improvement.  In channels with slowly changing phase we
+  could optionally use pilots from several past and future symbols.
+
+\*---------------------------------------------------------------------------*/
+
+void qpsk_symbols_to_bits(struct COHPSK *coh, float rx_bits[], COMP ct_symb_buf[][COHPSK_NC*ND])
+{
+    int   p, r, c, i, pc, d, n;
+    float x[NPILOTSFRAME+2], x1;
+    COMP  y[NPILOTSFRAME+2], yfit;
+    COMP  rx_symb_linear[NSYMROW*COHPSK_NC*ND];
+    COMP  m, b;
+    COMP   __attribute__((unused)) corr, rot, pi_on_4, phi_rect, div_symb;
+    float mag,  __attribute__((unused)) phi_,  __attribute__((unused)) amp_;
+    float sum_x, sum_xx, noise_var;
+    COMP  s;
+
+    pi_on_4.real = cosf(M_PI/4); pi_on_4.imag = sinf(M_PI/4);
+
+    for(c=0; c<COHPSK_NC*ND; c++) {
+
+        /* Set up lin reg model and interpolate phase.  Works better than average for channels with
+           quickly changing phase, like HF. */
+
+        for(p=0; p<NPILOTSFRAME+2; p++) {
+            x[p] = sampling_points[p];
+            pc = c % COHPSK_NC;
+            y[p] = fcmult(coh->pilot2[p][pc], ct_symb_buf[sampling_points[p]][c]);
+        }
+
+        linreg(&m, &b, x, y, NPILOTSFRAME+2);
+        for(r=0; r<NSYMROW; r++) {
+            x1 = (float)(r+NPILOTSFRAME);
+            yfit = cadd(fcmult(x1,m),b);
+            coh->phi_[r][c] = atan2(yfit.imag, yfit.real);
+        }
+
+        /* amplitude estimation */
+
+        mag = 0.0;
+        for(p=0; p<NPILOTSFRAME+2; p++) {
+            mag  += cabsolute(ct_symb_buf[sampling_points[p]][c]);
+        }
+        amp_ =  mag/(NPILOTSFRAME+2);
+        for(r=0; r<NSYMROW; r++) {
+             coh->amp_[r][c] = amp_;
+        }
+    }
+
+    /* now correct phase of data symbols */
+
+    for(c=0; c<COHPSK_NC*ND; c++) {
+        for (r=0; r<NSYMROW; r++) {
+            phi_rect.real = cosf(coh->phi_[r][c]); phi_rect.imag = -sinf(coh->phi_[r][c]);
+            coh->rx_symb[r][c] = cmult(ct_symb_buf[NPILOTSFRAME + r][c], phi_rect);
+            i = c*NSYMROW + r;
+            rx_symb_linear[i] = coh->rx_symb[r][c];
+        }
+    }
+
+    /* and finally optional diversity combination, note output is soft decn a "1" is < 0 */
+
+    for(c=0; c<COHPSK_NC; c++) {
+        for(r=0; r<NSYMROW; r++) {
+            div_symb = coh->rx_symb[r][c];
+            for (d=1; d<ND; d++) {
+                div_symb = cadd(div_symb, coh->rx_symb[r][c + COHPSK_NC*d]);
+            }
+            rot = cmult(div_symb, pi_on_4);
+            i = c*NSYMROW + r;
+            rx_bits[2*i+1] = rot.real;
+            rx_bits[2*i]   = rot.imag;
+
+            /* demodulate bits from upper and lower carriers separately for test purposes */
+
+            assert(ND == 2);
+
+            i = c*NSYMROW + r;
+            rot = cmult(coh->rx_symb[r][c], pi_on_4);
+            coh->rx_bits_lower[2*i+1] = rot.real;
+            coh->rx_bits_lower[2*i]   = rot.imag;
+            rot = cmult(coh->rx_symb[r][c + COHPSK_NC], pi_on_4);
+            coh->rx_bits_upper[2*i+1] = rot.real;
+            coh->rx_bits_upper[2*i]   = rot.imag;
+        }
+    }
+
+
+    /* estimate RMS signal and noise */
+
+    mag = 0.0;
+    for(i=0; i<NSYMROW*COHPSK_NC*ND; i++)
+        mag += cabsolute(rx_symb_linear[i]);
+    coh->sig_rms = mag/(NSYMROW*COHPSK_NC*ND);
+
+    sum_x = 0;
+    sum_xx = 0;
+    n = 0;
+    for (i=0; i<NSYMROW*COHPSK_NC*ND; i++) {
+      s = rx_symb_linear[i];
+      if (fabsf(s.real) > coh->sig_rms) {
+        sum_x  += s.imag;
+        sum_xx += s.imag*s.imag;
+        n++;
+      }
+    }
+
+    noise_var = 0;
+    if (n > 1) {
+      noise_var = (n*sum_xx - sum_x*sum_x)/(n*(n-1));
+    }
+    coh->noise_rms = sqrtf(noise_var);
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: tx_filter_and_upconvert_coh()
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  Given NC symbols construct M samples (1 symbol) of NC filtered
+  and upconverted symbols.
+
+  TODO: work out a way to merge with fdmdv version, e.g. run time define M/NSYM,
+  and run unittests on fdmdv and cohpsk modem afterwards.
+
+\*---------------------------------------------------------------------------*/
+
+void tx_filter_and_upconvert_coh(COMP tx_fdm[], int Nc, COMP tx_symbols[],
+                                 COMP tx_filter_memory[COHPSK_NC*ND][COHPSK_NSYM],
+                                 COMP phase_tx[], COMP freq[],
+                                 COMP *fbb_phase, COMP fbb_rect)
+{
+    int     c;
+    int     i,j,k;
+    float   acc;
+    COMP    gain;
+    COMP    tx_baseband;
+    COMP  two = {2.0, 0.0};
+    float mag;
+
+    gain.real = sqrtf(2.0)/2.0;
+    gain.imag = 0.0;
+
+    for(i=0; i<COHPSK_M; i++) {
+       tx_fdm[i].real = 0.0;
+       tx_fdm[i].imag = 0.0;
+    }
+
+    for(c=0; c<Nc; c++)
+       tx_filter_memory[c][COHPSK_NSYM-1] = cmult(tx_symbols[c], gain);
+
+    /*
+       tx filter each symbol, generate M filtered output samples for
+       each symbol, which we then freq shift and sum with other
+       carriers.  Efficient polyphase filter techniques used as
+       tx_filter_memory is sparse
+    */
+
+    for(c=0; c<Nc; c++) {
+        for(i=0; i<COHPSK_M; i++) {
+
+           /* filter real sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=COHPSK_M-i-1; j<COHPSK_NSYM; j++,k+=COHPSK_M)
+               acc += COHPSK_M * tx_filter_memory[c][j].real * gt_alpha5_root_coh[k];
+           tx_baseband.real = acc;
+
+           /* filter imag sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=COHPSK_M-i-1; j<COHPSK_NSYM; j++,k+=COHPSK_M)
+               acc += COHPSK_M * tx_filter_memory[c][j].imag * gt_alpha5_root_coh[k];
+           tx_baseband.imag = acc;
+            //printf("%d %d %f %f\n", c, i, tx_baseband.real, tx_baseband.imag);
+
+            /* freq shift and sum */
+
+           phase_tx[c] = cmult(phase_tx[c], freq[c]);
+           tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband, phase_tx[c]));
+            //printf("%d %d %f %f\n", c, i, phase_tx[c].real, phase_tx[c].imag);
+       }
+        //exit(0);
+    }
+
+    /* shift whole thing up to carrier freq */
+
+    for (i=0; i<COHPSK_M; i++) {
+       *fbb_phase = cmult(*fbb_phase, fbb_rect);
+       tx_fdm[i] = cmult(tx_fdm[i], *fbb_phase);
+    }
+
+    /*
+      Scale such that total Carrier power C of real(tx_fdm) = Nc.  This
+      excludes the power of the pilot tone.
+      We return the complex (single sided) signal to make frequency
+      shifting for the purpose of testing easier
+    */
+
+    for (i=0; i<COHPSK_M; i++)
+       tx_fdm[i] = cmult(two, tx_fdm[i]);
+
+    /* normalise digital oscillators as the magnitude can drift over time */
+
+    for (c=0; c<Nc; c++) {
+        mag = cabsolute(phase_tx[c]);
+       phase_tx[c].real /= mag;
+       phase_tx[c].imag /= mag;
+    }
+
+    mag = cabsolute(*fbb_phase);
+    fbb_phase->real /= mag;
+    fbb_phase->imag /= mag;
+
+    /* shift memory, inserting zeros at end */
+
+    for(i=0; i<COHPSK_NSYM-1; i++)
+       for(c=0; c<Nc; c++)
+           tx_filter_memory[c][i] = tx_filter_memory[c][i+1];
+
+    for(c=0; c<Nc; c++) {
+       tx_filter_memory[c][COHPSK_NSYM-1].real = 0.0;
+       tx_filter_memory[c][COHPSK_NSYM-1].imag = 0.0;
+    }
+}
+
+
+
+void corr_with_pilots(float *corr_out, float *mag_out, struct COHPSK *coh, int t, float f_fine)
+{
+    COMP  acorr, f_fine_rect, f_corr;
+    float mag, corr;
+    int   c, p, pc;
+
+    corr = 0.0; mag = 0.0;
+    for (c=0; c<COHPSK_NC*ND; c++) {
+        acorr.real = 0.0; acorr.imag = 0.0;
+        for (p=0; p<NPILOTSFRAME+2; p++) {
+            f_fine_rect.real = cosf(f_fine*2.0*M_PI*(sampling_points[p]+1.0)/COHPSK_RS);
+            f_fine_rect.imag = sinf(f_fine*2.0*M_PI*(sampling_points[p]+1.0)/COHPSK_RS);
+            f_corr = cmult(f_fine_rect, coh->ct_symb_buf[t+sampling_points[p]][c]);
+            pc = c % COHPSK_NC;
+            acorr = cadd(acorr, fcmult(coh->pilot2[p][pc], f_corr));
+            mag  += cabsolute(f_corr);
+        }
+        corr += cabsolute(acorr);
+    }
+
+    *corr_out = corr;
+    *mag_out  = mag;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: frame_sync_fine_freq_est()
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Returns an estimate of frame sync (coarse timing) offset and fine
+  frequency offset, advances to next sync state if we have a reliable
+  match for frame sync.
+
+\*---------------------------------------------------------------------------*/
+
+void frame_sync_fine_freq_est(struct COHPSK *coh, COMP ch_symb[][COHPSK_NC*ND], int sync, int *next_sync)
+{
+    int   t;
+    float f_fine, mag, max_corr, max_mag, corr;
+
+    update_ct_symb_buf(coh->ct_symb_buf, ch_symb);
+
+    /* sample pilots at start of this frame and start of next frame */
+
+    if (sync == 0) {
+
+        /* sample correlation over 2D grid of time and fine freq points */
+
+        max_corr = max_mag = 0;
+        for (f_fine=-20; f_fine<=20; f_fine+=0.25) {
+            for (t=0; t<NSYMROWPILOT; t++) {
+                corr_with_pilots(&corr, &mag, coh, t, f_fine);
+                //printf("  f: %f  t: %d corr: %f mag: %f\n", f_fine, t, corr, mag);
+                if (corr >= max_corr) {
+                    max_corr = corr;
+                    max_mag = mag;
+                    coh->ct = t;
+                    coh->f_fine_est = f_fine;
+                }
+            }
+        }
+
+
+        coh->ff_rect.real = cosf(coh->f_fine_est*2.0*M_PI/COHPSK_RS);
+        coh->ff_rect.imag = -sinf(coh->f_fine_est*2.0*M_PI/COHPSK_RS);
+        if (coh->verbose)
+            fprintf(stderr, "  [%d]   fine freq f: %6.2f max_ratio: %f ct: %d\n", coh->frame, coh->f_fine_est, max_corr/max_mag, coh->ct);
+
+        if (max_corr/max_mag > 0.9) {
+            if (coh->verbose)
+                fprintf(stderr, "  [%d]   encouraging sync word!\n", coh->frame);
+            coh->sync_timer = 0;
+            *next_sync = 1;
+        }
+        else {
+            *next_sync = 0;
+        }
+        coh->ratio = max_corr/max_mag;
+    }
+}
+
+
+void update_ct_symb_buf(COMP ct_symb_buf[][COHPSK_NC*ND], COMP ch_symb[][COHPSK_NC*ND])
+{
+    int r, c, i;
+
+    /* update memory in symbol buffer */
+
+    for(r=0; r<NCT_SYMB_BUF-NSYMROWPILOT; r++) {
+        for(c=0; c<COHPSK_NC*ND; c++)
+            ct_symb_buf[r][c] = ct_symb_buf[r+NSYMROWPILOT][c];
+    }
+
+    for(r=NCT_SYMB_BUF-NSYMROWPILOT, i=0; r<NCT_SYMB_BUF; r++, i++) {
+        for(c=0; c<COHPSK_NC*ND; c++)
+            ct_symb_buf[r][c] = ch_symb[i][c];
+    }
+}
+
+
+int sync_state_machine(struct COHPSK *coh, int sync, int next_sync)
+{
+    float corr, mag;
+
+    if (sync == 1) {
+
+        /* check that sync is still good, fall out of sync on consecutive bad frames */
+
+        corr_with_pilots(&corr, &mag, coh, coh->ct, coh->f_fine_est);
+        coh->ratio = fabsf(corr)/mag;
+
+        // printf("%f\n", cabsolute(corr)/mag);
+
+        if (fabsf(corr)/mag < 0.8)
+            coh->sync_timer++;
+        else
+            coh->sync_timer = 0;
+
+        if (coh->sync_timer == 10) {
+            if (coh->verbose)
+                fprintf(stderr,"  [%d] lost sync ....\n", coh->frame);
+            next_sync = 0;
+        }
+    }
+
+    sync = next_sync;
+
+    return sync;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cohpsk_mod()
+  AUTHOR......: David Rowe
+  DATE CREATED: 5/4/2015
+
+  COHPSK modulator, take a frame of COHPSK_BITS_PER_FRAME or
+  2*COHPSK_BITS_PER_FRAME bits and generates a frame of
+  COHPSK_NOM_SAMPLES_PER_FRAME modulated symbols.
+
+  if nbits == COHPSK_BITS_PER_FRAME, diveristy mode is used, if nbits
+  == 2*COHPSK_BITS_PER_FRAME diversity mode is not used.
+
+  The output signal is complex to support single sided frequency
+  shifting, for example when testing frequency offsets in channel
+  simulation.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_mod(struct COHPSK *coh, COMP tx_fdm[], int tx_bits[], int nbits)
+{
+    struct FDMDV *fdmdv = coh->fdmdv;
+    COMP  tx_symb[NSYMROWPILOT][COHPSK_NC*ND];
+    COMP  tx_onesym[COHPSK_NC*ND];
+    int  r,c;
+
+    bits_to_qpsk_symbols(tx_symb, tx_bits, nbits);
+
+    for(r=0; r<NSYMROWPILOT; r++) {
+        for(c=0; c<COHPSK_NC*ND; c++)
+            tx_onesym[c] = fcmult(coh->carrier_ampl[c], tx_symb[r][c]);
+        tx_filter_and_upconvert_coh(&tx_fdm[r*COHPSK_M], COHPSK_NC*ND , tx_onesym, fdmdv->tx_filter_memory,
+                                    fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  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_NOM_SAMPLES_PER_FRAME; i++) {
+        sam = tx_fdm[i];
+        mag = cabsolute(sam);
+        if (mag >  COHPSK_CLIP)  {
+            sam = fcmult( COHPSK_CLIP/mag, sam);
+        }
+        tx_fdm[i] = sam;
+    }
+ }
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdm_downconvert_coh
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  Frequency shift each modem carrier down to NC baseband signals.
+
+  TODO: try to combine with fdmdv version, carefully re-test fdmdv modem.
+
+\*---------------------------------------------------------------------------*/
+
+void fdm_downconvert_coh(COMP rx_baseband[COHPSK_NC][COHPSK_M+COHPSK_M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin)
+{
+    int   i,c;
+    float mag;
+
+    /* maximum number of input samples to demod */
+
+    assert(nin <= (COHPSK_M+COHPSK_M/P));
+
+    /* downconvert */
+
+    for (c=0; c<Nc; c++)
+       for (i=0; i<nin; i++) {
+           phase_rx[c] = cmult(phase_rx[c], freq[c]);
+           rx_baseband[c][i] = cmult(rx_fdm[i], cconj(phase_rx[c]));
+       }
+
+    /* normalise digital oscilators as the magnitude can drift over time */
+
+    for (c=0; c<Nc; c++) {
+        mag = cabsolute(phase_rx[c]);
+       phase_rx[c].real /= mag;
+       phase_rx[c].imag /= mag;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: rx_filter_coh()
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  cohpsk version of fdmdv.c rx_filter function.
+
+  TODO: see if we can merge the two!  Will require re-testing of fdmdv modem.
+
+\*---------------------------------------------------------------------------*/
+
+void rx_filter_coh(COMP rx_filt[COHPSK_NC+1][P+1], int Nc, COMP rx_baseband[COHPSK_NC+1][COHPSK_M+COHPSK_M/P], COMP rx_filter_memory[COHPSK_NC+1][+COHPSK_NFILTER], int nin)
+{
+    int c, i,j,k,l;
+    int n=COHPSK_M/P;
+
+    /* rx filter each symbol, generate P filtered output samples for
+       each symbol.  Note we keep filter memory at rate M, it's just
+       the filter output at rate P */
+
+    for(i=0, j=0; i<nin; i+=n,j++) {
+
+       /* latest input sample */
+
+       for(c=0; c<Nc; c++)
+           for(k=COHPSK_NFILTER-n,l=i; k<COHPSK_NFILTER; k++,l++)
+               rx_filter_memory[c][k] = rx_baseband[c][l];
+
+       /* convolution (filtering) */
+
+       for(c=0; c<Nc; c++) {
+           rx_filt[c][j].real = 0.0; rx_filt[c][j].imag = 0.0;
+           for(k=0; k<COHPSK_NFILTER; k++)
+               rx_filt[c][j] = cadd(rx_filt[c][j], fcmult(gt_alpha5_root_coh[k], rx_filter_memory[c][k]));
+       }
+
+       /* make room for next input sample */
+
+       for(c=0; c<Nc; c++)
+           for(k=0,l=n; k<COHPSK_NFILTER-n; k++,l++)
+               rx_filter_memory[c][k] = rx_filter_memory[c][l];
+    }
+
+    assert(j <= (P+1)); /* check for any over runs */
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_freq_shift_coh()
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  Frequency shift modem signal.  The use of complex input and output allows
+  single sided frequency shifting (no images).
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs,
+                          COMP *foff_phase_rect, int nin)
+{
+    COMP  foff_rect;
+    float mag;
+    int   i;
+
+    foff_rect.real = cosf(2.0*PI*foff/Fs);
+    foff_rect.imag = sinf(2.0*PI*foff/Fs);
+    for(i=0; i<nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
+    }
+
+    /* normalise digital oscilator as the magnitude can drfift over time */
+
+    mag = cabsolute(*foff_phase_rect);
+    foff_phase_rect->real /= mag;
+    foff_phase_rect->imag /= mag;
+}
+
+
+void rate_Fs_rx_processing(struct COHPSK *coh, COMP ch_symb[][COHPSK_NC*ND], COMP ch_fdm_frame[], float *f_est, int nsymb, int nin, int freq_track)
+{
+    struct FDMDV *fdmdv = coh->fdmdv;
+    int   r, c, i, ch_fdm_frame_index;
+    COMP  rx_fdm_frame_bb[COHPSK_M+COHPSK_M/P];
+    COMP  rx_baseband[COHPSK_NC*ND][COHPSK_M+COHPSK_M/P];
+    COMP  rx_filt[COHPSK_NC*ND][P+1];
+    float env[NT*P], rx_timing;
+    COMP  rx_onesym[COHPSK_NC*ND];
+    float beta, g;
+    COMP  adiff, amod_strip, mod_strip;
+
+    ch_fdm_frame_index = 0;
+    rx_timing = 0;
+
+    for (r=0; r<nsymb; r++) {
+        fdmdv_freq_shift_coh(rx_fdm_frame_bb, &ch_fdm_frame[ch_fdm_frame_index], -(*f_est), COHPSK_FS, &fdmdv->fbb_phase_rx, nin);
+        ch_fdm_frame_index += nin;
+        fdm_downconvert_coh(rx_baseband, COHPSK_NC*ND, rx_fdm_frame_bb, fdmdv->phase_rx, fdmdv->freq, nin);
+        rx_filter_coh(rx_filt, COHPSK_NC*ND, rx_baseband, coh->rx_filter_memory, nin);
+        rx_timing = rx_est_timing(rx_onesym, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, nin, COHPSK_M);
+
+        for(c=0; c<COHPSK_NC*ND; c++) {
+            ch_symb[r][c] = rx_onesym[c];
+        }
+
+        /* freq tracking, see test_ftrack.m for unit test.  Placed in
+           this function as it needs to work on a symbol by symbol
+           abasis rather than frame by frame.  This means the control
+           loop operates at a sample rate of Rs = 50Hz for say 1 Hz/s
+           drift. */
+
+        if (freq_track) {
+            beta = 0.005;
+            g = 0.2;
+
+            /* combine difference on phase from last symbol over Nc carriers */
+
+            mod_strip.real = 0.0; mod_strip.imag = 0.0;
+            for(c=0; c<fdmdv->Nc+1; c++) {
+                //printf("rx_onesym[%d] %f %f prev_rx_symbols[%d] %f %f\n", c, rx_onesym[c].real, rx_onesym[c].imag,
+                //       fdmdv->prev_rx_symbols[c].real, fdmdv->prev_rx_symbols[c].imag);
+                adiff = cmult(rx_onesym[c], cconj(fdmdv->prev_rx_symbols[c]));
+                fdmdv->prev_rx_symbols[c] = rx_onesym[c];
+
+                /* 4th power strips QPSK modulation, by multiplying phase by 4
+                   Using the abs value of the real coord was found to help
+                   non-linear issues when noise power was large. */
+
+                amod_strip = cmult(adiff, adiff);
+                amod_strip = cmult(amod_strip, amod_strip);
+                amod_strip.real = fabsf(amod_strip.real);
+                mod_strip = cadd(mod_strip, amod_strip);
+            }
+            //printf("modstrip: %f %f\n", mod_strip.real, mod_strip.imag);
+
+            /* loop filter made up of 1st order IIR plus integrator.  Integerator
+               was found to be reqd  */
+
+            fdmdv->foff_filt = (1.0-beta)*fdmdv->foff_filt + beta*atan2(mod_strip.imag, mod_strip.real);
+            //printf("foff_filt: %f angle: %f\n", fdmdv->foff_filt, atan2(mod_strip.imag, mod_strip.real));
+            *f_est += g*fdmdv->foff_filt;
+        }
+
+        /* Optional logging used for testing against Octave version */
+
+        if (coh->rx_baseband_log) {
+            assert(nin <= (COHPSK_M+COHPSK_M/P));
+            for(c=0; c<COHPSK_NC*ND; c++) {
+                for(i=0; i<nin; i++) {
+                    coh->rx_baseband_log[c*coh->rx_baseband_log_col_sz + coh->rx_baseband_log_col_index + i] = rx_baseband[c][i];
+                }
+            }
+            coh->rx_baseband_log_col_index += nin;
+            assert(coh->rx_baseband_log_col_index <= coh->rx_baseband_log_col_sz);
+        }
+
+        if (coh->rx_filt_log) {
+         for(c=0; c<COHPSK_NC*ND; c++) {
+            for(i=0; i<nin/(COHPSK_M/P); i++) {
+              coh->rx_filt_log[c*coh->rx_filt_log_col_sz + coh->rx_filt_log_col_index + i] = rx_filt[c][i];
+            }
+         }
+         coh->rx_filt_log_col_index += nin/(COHPSK_M/P);
+        }
+
+        if (coh->ch_symb_log) {
+            for(c=0; c<COHPSK_NC*ND; c++) {
+               coh->ch_symb_log[coh->ch_symb_log_r*COHPSK_NC*ND + c] = ch_symb[r][c];
+            }
+            coh->ch_symb_log_r++;
+        }
+
+        if (coh->rx_timing_log) {
+            coh->rx_timing_log[coh->rx_timing_log_index] = rx_timing;
+            coh->rx_timing_log_index++;
+            //printf("rx_timing_log_index: %d\n", coh->rx_timing_log_index);
+        }
+
+        /* we only allow a timing shift on one symbol per frame */
+
+        if (nin != COHPSK_M)
+            nin = COHPSK_M;
+    }
+
+    coh->rx_timing = rx_timing;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cohpsk_demod()
+  AUTHOR......: David Rowe
+  DATE CREATED: 5/4/2015
+
+  COHPSK demodulator, takes an array of (nominally) nin_frame =
+  COHPSK_NOM_SAMPLES_PER_FRAME modulated samples, returns an array of
+  COHPSK_BITS_PER_FRAME bits.
+
+  The input signal is complex to support single sided frequency shifting
+  before the demod input (e.g. click to tune feature).
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_demod(struct COHPSK *coh, float rx_bits[], int *sync_good, COMP rx_fdm[], int *nin_frame)
+{
+    COMP  ch_symb[NSW*NSYMROWPILOT][COHPSK_NC*ND];
+    int   i, j, sync, anext_sync, next_sync, nin, r, c;
+    float max_ratio, f_est;
+
+    assert(*nin_frame <= COHPSK_MAX_SAMPLES_PER_FRAME);
+
+    next_sync = sync = coh->sync;
+
+    for (i=0; i<NSW*NSYMROWPILOT*COHPSK_M-*nin_frame; i++)
+        coh->ch_fdm_frame_buf[i] = coh->ch_fdm_frame_buf[i+*nin_frame];
+    //printf("nin_frame: %d i: %d i+nin_frame: %d\n", *nin_frame, i, i+*nin_frame);
+    for (j=0; i<NSW*NSYMROWPILOT*COHPSK_M; i++,j++)
+        coh->ch_fdm_frame_buf[i] = rx_fdm[j];
+    //printf("i: %d j: %d rx_fdm[0]: %f %f\n", i,j, rx_fdm[0].real, rx_fdm[0].imag);
+
+    /* if out of sync do Initial Freq offset estimation using NSW frames to flush out filter memories */
+
+    if (sync == 0) {
+
+        /* we can test +/- 20Hz, so we break this up into 3 tests to cover +/- 60Hz */
+
+        max_ratio = 0.0;
+        f_est = 0.0;
+        for (coh->f_est = FDMDV_FCENTRE-40.0; coh->f_est <= FDMDV_FCENTRE+40.0; coh->f_est += 40.0) {
+
+            if (coh->verbose)
+                fprintf(stderr, "  [%d] acohpsk.f_est: %f +/- 20\n", coh->frame, coh->f_est);
+
+            /* we are out of sync so reset f_est and process two frames to clean out memories */
+
+            rate_Fs_rx_processing(coh, ch_symb, coh->ch_fdm_frame_buf, &coh->f_est, NSW*NSYMROWPILOT, COHPSK_M, 0);
+            for (i=0; i<NSW-1; i++) {
+                update_ct_symb_buf(coh->ct_symb_buf, &ch_symb[i*NSYMROWPILOT]);
+            }
+            frame_sync_fine_freq_est(coh, &ch_symb[(NSW-1)*NSYMROWPILOT], sync, &anext_sync);
+
+            if (anext_sync == 1) {
+                //printf("  [%d] acohpsk.ratio: %f\n", f, coh->ratio);
+                if (coh->ratio > max_ratio) {
+                    max_ratio   = coh->ratio;
+                    f_est       = coh->f_est - coh->f_fine_est;
+                    next_sync   = anext_sync;
+                }
+            }
+        }
+
+        if (next_sync == 1) {
+
+            /* we've found a sync candidate!
+               re-process last NSW frames with adjusted f_est then check again */
+
+            coh->f_est = f_est;
+
+            if (coh->verbose)
+                fprintf(stderr, "  [%d] trying sync and f_est: %f\n", coh->frame, coh->f_est);
+
+            rate_Fs_rx_processing(coh, ch_symb, coh->ch_fdm_frame_buf, &coh->f_est, NSW*NSYMROWPILOT, COHPSK_M, 0);
+            for (i=0; i<NSW-1; i++) {
+                update_ct_symb_buf(coh->ct_symb_buf, &ch_symb[i*NSYMROWPILOT]);
+            }
+            /*
+              for(i=0; i<NSW*NSYMROWPILOT; i++) {
+                printf("%f %f\n", ch_symb[i][0].real, ch_symb[i][0].imag);
+            }
+            */
+            /*
+            for(i=0; i<NCT_SYMB_BUF; i++) {
+                printf("%f %f\n", coh->ct_symb_buf[i][0].real, coh->ct_symb_buf[i][0].imag);
+            }
+            */
+             frame_sync_fine_freq_est(coh, &ch_symb[(NSW-1)*NSYMROWPILOT], sync, &next_sync);
+
+            if (fabs(coh->f_fine_est) > 2.0) {
+                if (coh->verbose)
+                    fprintf(stderr, "  [%d] Hmm %f is a bit big :(\n", coh->frame, coh->f_fine_est);
+                next_sync = 0;
+            }
+        }
+
+        if (next_sync == 1) {
+            /* OK we are in sync!
+               demodulate first frame (demod completed below) */
+
+            if (coh->verbose)
+                fprintf(stderr, "  [%d] in sync! f_est: %f ratio: %f \n", coh->frame, coh->f_est, coh->ratio);
+            for(r=0; r<NSYMROWPILOT+2; r++)
+                for(c=0; c<COHPSK_NC*ND; c++)
+                    coh->ct_symb_ff_buf[r][c] = coh->ct_symb_buf[coh->ct+r][c];
+        }
+    }
+
+    /* If in sync just do sample rate processing on latest frame */
+
+    if (sync == 1) {
+        rate_Fs_rx_processing(coh, ch_symb, rx_fdm, &coh->f_est, NSYMROWPILOT, coh->nin, 1);
+        frame_sync_fine_freq_est(coh, ch_symb, sync, &next_sync);
+
+        for(r=0; r<2; r++)
+            for(c=0; c<COHPSK_NC*ND; c++)
+                coh->ct_symb_ff_buf[r][c] = coh->ct_symb_ff_buf[r+NSYMROWPILOT][c];
+        for(; r<NSYMROWPILOT+2; r++)
+            for(c=0; c<COHPSK_NC*ND; c++)
+                coh->ct_symb_ff_buf[r][c] = coh->ct_symb_buf[coh->ct+r][c];
+    }
+
+    /* if we are in sync complete demodulation with symbol rate processing */
+
+    *sync_good = 0;
+    if ((next_sync == 1) || (sync == 1)) {
+        qpsk_symbols_to_bits(coh, rx_bits, coh->ct_symb_ff_buf);
+        *sync_good = 1;
+    }
+
+    sync = sync_state_machine(coh, sync, next_sync);
+    coh->sync = sync;
+
+    /* work out how many samples we need for the next call to account
+       for differences in tx and rx sample clocks */
+
+    nin = COHPSK_M;
+    if (sync == 1) {
+        if (coh->rx_timing > COHPSK_M/P)
+            nin = COHPSK_M + COHPSK_M/P;
+        if (coh->rx_timing < -COHPSK_M/P)
+            nin = COHPSK_M - COHPSK_M/P;
+    }
+    coh->nin = nin;
+    *nin_frame = (NSYMROWPILOT-1)*COHPSK_M + nin;
+    //if (coh->verbose)
+    //    fprintf(stderr, "%f %d %d\n", coh->rx_timing, nin, *nin_frame);
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cohpsk_fs_offset()
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  Simulates small Fs offset between mod and demod.
+
+\*---------------------------------------------------------------------------*/
+
+int cohpsk_fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm)
+{
+    double tin, f;
+    int   tout, t1, t2;
+
+    tin = 0.0; tout = 0;
+    while (tin < n) {
+      t1 = floor(tin);
+      t2 = ceil(tin);
+      f = tin - t1;
+      out[tout].real = (1.0-f)*in[t1].real + f*in[t2].real;
+      out[tout].imag = (1.0-f)*in[t1].imag + f*in[t2].imag;
+      tout += 1;
+      tin  += 1.0 + sample_rate_ppm/1E6;
+      //printf("tin: %f tout: %d f: %f\n", tin, tout, f);
+    }
+
+    return tout;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cohpsk_get_demod_stats()
+  AUTHOR......: David Rowe
+  DATE CREATED: 14 June 2015
+
+  Fills stats structure with a bunch of demod information.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_get_demod_stats(struct COHPSK *coh, struct MODEM_STATS *stats)
+{
+    int   c,r;
+    COMP  pi_4;
+    float new_snr_est;
+
+    pi_4.real = cosf(M_PI/4.0);
+    pi_4.imag = sinf(M_PI/4.0);
+
+    stats->Nc = COHPSK_NC*ND;
+    assert(stats->Nc <= MODEM_STATS_NC_MAX);
+    new_snr_est = 20*log10((coh->sig_rms+1E-6)/(coh->noise_rms+1E-6)) - 10*log10(3000.0/700.0);
+    stats->snr_est = 0.9*stats->snr_est + 0.1*new_snr_est;
+
+    //fprintf(stderr, "sig_rms: %f noise_rms: %f snr_est: %f\n", coh->sig_rms, coh->noise_rms, stats->snr_est);
+    stats->sync = coh->sync;
+    stats->foff = coh->f_est - FDMDV_FCENTRE;
+    stats->rx_timing = coh->rx_timing;
+    stats->clock_offset = 0.0; /* TODO - implement clock offset estimation */
+
+    assert(NSYMROW <= MODEM_STATS_NR_MAX);
+    stats->nr = NSYMROW;
+    for(c=0; c<COHPSK_NC*ND; c++) {
+        for (r=0; r<NSYMROW; r++) {
+            stats->rx_symbols[r][c] = cmult(coh->rx_symb[r][c], pi_4);
+        }
+    }
+}
+
+
+void cohpsk_set_verbose(struct COHPSK *coh, int verbose)
+{
+    assert(coh != NULL);
+    coh->verbose = verbose;
+}
+
+
+void cohpsk_set_frame(struct COHPSK *coh, int frame)
+{
+    assert(coh != NULL);
+    coh->frame = frame;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cohpsk_get_test_bits()
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2015
+
+  Returns a frame of known test bits.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_get_test_bits(struct COHPSK *coh, int rx_bits[])
+{
+    memcpy(rx_bits, coh->ptest_bits_coh_tx, sizeof(int)*COHPSK_BITS_PER_FRAME);
+    coh->ptest_bits_coh_tx += COHPSK_BITS_PER_FRAME;
+    if (coh->ptest_bits_coh_tx >=coh->ptest_bits_coh_end) {
+        coh->ptest_bits_coh_tx = (int*)test_bits_coh;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cohpsk_put_test_bits()
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2015
+
+  Accepts bits from demod and attempts to sync with the known
+  test_bits sequence.  When synced measures bit errors.
+
+  Has states to track two separate received test sequences based on
+  channel 0 or 1.
+
+\*---------------------------------------------------------------------------*/
+
+void cohpsk_put_test_bits(struct COHPSK *coh, int *state, short error_pattern[],
+                          int *bit_errors, char rx_bits_char[], int channel)
+{
+    int i, next_state, anerror;
+    int rx_bits[COHPSK_BITS_PER_FRAME];
+
+    assert((channel == 0) || (channel == 1));
+    int *ptest_bits_coh_rx = coh->ptest_bits_coh_rx[channel];
+
+    for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+        rx_bits[i] = rx_bits_char[i];
+    }
+
+    *bit_errors = 0;
+    for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+        anerror = (rx_bits[i] & 0x1) ^ ptest_bits_coh_rx[i];
+        if ((anerror < 0) || (anerror > 1)) {
+            fprintf(stderr, "i: %d rx_bits: %d ptest_bits_coh_rx: %d\n", i, rx_bits[i], ptest_bits_coh_rx[i]);
+        }
+        *bit_errors += anerror;
+        error_pattern[i] = anerror;
+    }
+
+    /* state logic */
+
+    next_state = *state;
+
+    if (*state == 0) {
+        if (*bit_errors < 4) {
+            next_state = 1;
+            ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME;
+            if (ptest_bits_coh_rx >= coh->ptest_bits_coh_end) {
+                ptest_bits_coh_rx = (int*)test_bits_coh;
+            }
+        }
+    }
+
+    /* if 5 frames with large BER reset test frame sync */
+
+    if (*state > 0) {
+        if (*bit_errors > 8) {
+            if (*state == 6)
+                next_state = 0;
+            else
+                next_state = *state+1;
+        }
+        else
+            next_state = 1;
+    }
+
+    if (*state > 0) {
+        ptest_bits_coh_rx += COHPSK_BITS_PER_FRAME;
+        if (ptest_bits_coh_rx >= coh->ptest_bits_coh_end) {
+            ptest_bits_coh_rx = (int*)test_bits_coh;
+        }
+    }
+
+    //fprintf(stderr, "state: %d next_state: %d bit_errors: %d\n", *state, next_state, *bit_errors);
+
+    *state = next_state;
+    coh->ptest_bits_coh_rx[channel] = ptest_bits_coh_rx;
+}
+
+
+int cohpsk_error_pattern_size(void) {
+    return COHPSK_BITS_PER_FRAME;
+}
+
+
+float *cohpsk_get_rx_bits_lower(struct COHPSK *coh) {
+    return coh->rx_bits_lower;
+}
+
+float *cohpsk_get_rx_bits_upper(struct COHPSK *coh) {
+    return coh->rx_bits_upper;
+}
+
+void cohpsk_set_carrier_ampl(struct COHPSK *coh, int c, float ampl) {
+    assert(c < COHPSK_NC*ND);
+    coh->carrier_ampl[c] = ampl;
+    fprintf(stderr, "cohpsk_set_carrier_ampl: %d %f\n", c, ampl);
+}
+
diff --git a/codec2/branches/0.7/src/cohpsk_ch.c b/codec2/branches/0.7/src/cohpsk_ch.c
new file mode 100644 (file)
index 0000000..76a5a31
--- /dev/null
@@ -0,0 +1,341 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: cohpsk_ch.c
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  Channel impairment program for testing command line versions of
+  cohpsk modem.
+
+  TODO:
+    [ ] measure and prints pwrs to check, prints warning
+    [ ] SNR in 3000Hz input
+    [ ] example operation with sox for sample rate change
+    [ ] way to calibrate for different input pwrs
+    [ ] HT to do real->complex
+        [ ] check no BER hit just through HT
+        [ ] unit test HT
+    [ ] clipping detect
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+#include "comp_prim.h"
+#include "noise_samples.h"
+#include "ht_coeff.h"
+#include "ssbfilt_coeff.h"
+#include "codec2_fdmdv.h"
+
+#define BUF_N                 160
+#define FAST_FADING_DELAY_MS  2.0
+#define SLOW_FADING_DELAY_MS  0.5
+#define PAPR_TARGET           7.0
+
+/* This file gets generated using the function write_noise_file in tcohpsk.m.  You have to run
+   tcohpsk first (any variant) to load the function into Octave, e.g.:
+
+  octave:17> tcohpsk
+  octave:18> write_noise_file("../raw/fading_samples.float", 7500, 7500*60)
+*/
+
+#define FAST_FADING_FILE_NAME "../../raw/fast_fading_samples.float"
+#define SLOW_FADING_FILE_NAME "../../raw/slow_fading_samples.float"
+
+int main(int argc, char *argv[])
+{
+    FILE          *fin, *ffading, *fout;
+    float          NodB, foff_hz;
+    int            fading_en, nhfdelay;
+
+    short          buf[BUF_N];
+    float          htbuf[HT_N+BUF_N];
+    COMP           ch_in[BUF_N];
+    COMP           ch_fdm[BUF_N];
+    float          ssbfiltbuf[SSBFILT_N+BUF_N];
+    float          ssbfiltout[BUF_N];
+
+    COMP           phase_ch;
+    int            noise_r, noise_end;
+    float          No, variance;
+    COMP           scaled_noise;
+    float          hf_gain;
+    COMP          *ch_fdm_delay = NULL, aspread, aspread_2ms, delayed, direct;
+    float          tx_pwr, tx_pwr_fade, noise_pwr;
+    int            frames, i, j, k, ret, clipped;
+    float          sam, peak, inclip, papr, CNo, snr3k, EbNo700;
+
+    if (argc == 7) {
+        if (strcmp(argv[1], "-")  == 0) fin = stdin;
+        else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+            fprintf(stderr, "Error opening input modem raw 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 raw file: %s: %s.\n",
+                    argv[2], strerror(errno));
+            exit(1);
+        }
+
+        NodB = atof(argv[3]);
+        foff_hz = atof(argv[4]);
+        fading_en = atoi(argv[5]);
+        inclip = atof(argv[6]);
+    }
+    else {
+        fprintf(stderr, "usage: %s InputRealModemRawFileFs7500Hz OutputRealModemRawFileFs7500Hz No(dB/Hz) FoffHz Fading[0-none 1-fast 2-slow] InputClip0to1\n", argv[0]);
+        exit(1);
+    }
+    fprintf(stderr, "NodB: %4.2f foff: %4.2f Hz fading: %d inclip: %4.2f\n", NodB, foff_hz, fading_en, inclip);
+
+    phase_ch.real = 1.0; phase_ch.imag = 0.0;
+    noise_r = 0;
+    noise_end = sizeof(noise)/sizeof(COMP);
+
+    /*  N = var = NoFs */
+
+    No = pow(10.0, NodB/10.0);
+    variance = COHPSK_FS*No;
+
+    tx_pwr = tx_pwr_fade = noise_pwr = 0.0;
+    clipped = 0;
+    peak = 0.0;
+
+    /* init HF fading model */
+
+    ffading = NULL;
+    nhfdelay = 0;
+    if (fading_en) {
+        if (fading_en == 1) {
+            ffading = fopen(FAST_FADING_FILE_NAME, "rb");
+            if (ffading == NULL) {
+                printf("Can't find fast fading file: %s\n", FAST_FADING_FILE_NAME);
+                exit(1);
+            }
+            nhfdelay = floor(FAST_FADING_DELAY_MS*COHPSK_FS/1000);
+        }
+
+        if (fading_en == 2) {
+            ffading = fopen(SLOW_FADING_FILE_NAME, "rb");
+            if (ffading == NULL) {
+                printf("Can't find slow fading file: %s\n", SLOW_FADING_FILE_NAME);
+                exit(1);
+            }
+            nhfdelay = floor(SLOW_FADING_DELAY_MS*COHPSK_FS/1000);
+        }
+
+        ch_fdm_delay = (COMP*)malloc((nhfdelay+COHPSK_NOM_SAMPLES_PER_FRAME)*sizeof(COMP));
+        assert(ch_fdm_delay != NULL);
+        for(i=0; i<nhfdelay+COHPSK_NOM_SAMPLES_PER_FRAME; i++) {
+            ch_fdm_delay[i].real = 0.0;
+            ch_fdm_delay[i].imag = 0.0;
+        }
+
+        /* first values in file are HF gains */
+
+        for (i=0; i<4; i++)
+            ret = fread(&hf_gain, sizeof(float), 1, ffading);
+        fprintf(stderr, "hf_gain: %f\n", hf_gain);
+    }
+
+    for(i=0; i<HT_N; i++) {
+        htbuf[i] = 0.0;
+    }
+
+    /* --------------------------------------------------------*\
+                                 Main Loop
+    \*---------------------------------------------------------*/
+    frames = 0;
+    while(fread(buf, sizeof(short), BUF_N, fin) == BUF_N) {
+       frames++;
+
+        /* Hilbert Transform to produce complex signal so we can do
+           single sided freq shifts.  Allows us to use real signal I/O
+           which is handy */
+
+        for(i=0, j=HT_N; i<BUF_N; i++,j++) {
+
+            /*
+               Hilbert Transform to produce complex signal so we can do
+               single sided freq shifts.  Essential filters out negative
+               freqencies.
+            */
+
+            sam = (float)buf[i];
+            //printf("sam: %f ", sam);
+            if (sam > inclip*32767.0)
+                sam = inclip*32767.0;
+            if (sam < -inclip*32767.0)
+                sam = -inclip*32767.0;
+            //printf("sam: %f\n", sam);
+            htbuf[j] = sam/FDMDV_SCALE;
+
+            if (fabs(htbuf[j]) > peak) {
+                peak = fabs(htbuf[j]);
+            }
+            tx_pwr += pow(htbuf[j], 2.0);
+
+            /* FIR filter with HT to get imag, just delay to get real */
+
+            ch_in[i].real = 0.0;
+            ch_in[i].imag = 0.0;
+            for(k=0; k<HT_N; k++) {
+                ch_in[i].real += htbuf[j-k]*ht_coeff[k].real;
+                ch_in[i].imag += htbuf[j-k]*ht_coeff[k].imag;
+            }
+            //printf("%d %f %f\n", i, ch_in[i].real, ch_in[i].imag);
+        }
+        assert(j <= (BUF_N+HT_N));
+
+        /* update HT memory */
+
+        for(i=0; i<HT_N; i++)
+           htbuf[i] = htbuf[i+BUF_N];
+
+       /* --------------------------------------------------------*\
+                                 Channel
+       \*---------------------------------------------------------*/
+
+        fdmdv_freq_shift(ch_fdm, ch_in, foff_hz, &phase_ch, BUF_N);
+
+        /* optional HF fading -------------------------------------*/
+
+        if (fading_en) {
+
+            /* update delayed signal buffer */
+
+            for(i=0; i<nhfdelay; i++)
+                ch_fdm_delay[i] = ch_fdm_delay[i+BUF_N];
+            for(j=0; j<BUF_N; i++, j++)
+                ch_fdm_delay[i] = ch_fdm[j];
+
+            /* combine direct and delayed paths, both multiplied by
+               "spreading" (doppler) functions */
+
+            for(i=0; i<BUF_N; i++) {
+                ret = fread(&aspread, sizeof(COMP), 1, ffading);
+                assert(ret == 1);
+                ret = fread(&aspread_2ms, sizeof(COMP), 1, ffading);
+                assert(ret == 1);
+                //printf("%f %f %f %f\n", aspread.real, aspread.imag, aspread_2ms.real, aspread_2ms.imag);
+
+                direct    = cmult(aspread, ch_fdm[i]);
+                delayed   = cmult(aspread_2ms, ch_fdm_delay[i]);
+                ch_fdm[i] = fcmult(hf_gain, cadd(direct, delayed));
+            }
+        }
+
+        /* Measure power after fading model to make sure aaverage pwr
+           is the same as AWGN channels. We only output the real
+           signal, which is half the power. */
+
+        for(i=0; i<BUF_N; i++) {
+            tx_pwr_fade += pow(ch_fdm[i].real, 2.0);
+        }
+
+        /* AWGN noise ------------------------------------------*/
+
+        for(i=0; i<BUF_N; i++) {
+            scaled_noise = fcmult(sqrt(variance), noise[noise_r]);
+            ch_fdm[i] = cadd(ch_fdm[i], scaled_noise);
+            noise_pwr += pow(scaled_noise.real, 2.0);
+            noise_r++;
+            if (noise_r > noise_end) {
+                noise_r = 0;
+                //fprintf(stderr, "  [%d] noise wrap\n", f);
+            }
+        }
+
+        /* FIR filter to simulate (a rather flat) SSB filter.  Might
+           be useful to have an option for a filter with a few dB
+           ripple too, to screw up the modem. This is mainly so analog
+           SSB sounds realistic. */
+
+        for(i=0, j=SSBFILT_N; i<BUF_N; i++,j++) {
+            ssbfiltbuf[j] = ch_fdm[i].real;
+            ssbfiltout[i] = 0.0;
+            for(k=0; k<SSBFILT_N; k++) {
+                ssbfiltout[i] += ssbfiltbuf[j-k]*ssbfilt_coeff[k];
+            }
+        }
+
+        /* update SSB filter memory */
+
+        for(i=0; i<SSBFILT_N; i++)
+           ssbfiltbuf[i] = ssbfiltbuf[i+BUF_N];
+
+       /* scale and save to disk as shorts */
+
+       for(i=0; i<BUF_N; i++) {
+            sam = FDMDV_SCALE * ssbfiltout[i];
+            if (sam > 32767.0) {
+                clipped++;
+                sam = 32767.0;
+            }
+            if (sam < -32767.0) {
+                clipped++;
+                sam = -32767.0;
+            }
+           buf[i] = sam;
+        }
+
+       fwrite(buf, sizeof(short), BUF_N, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    fclose(fin);
+    fclose(fout);
+
+    fprintf(stderr, "peak pwr.....: %7.2f\nav input pwr.: %7.2f\nav pwr fading: %7.2f\nnoise pwr....: %7.2f\nclipping.....: %7.2f %%\n",
+            peak*peak,
+            tx_pwr/(frames*BUF_N),
+            tx_pwr_fade/(frames*BUF_N),
+            noise_pwr/(frames*BUF_N),
+            100.0*clipped/frames
+           );
+    papr = 10*log10(peak*peak/(tx_pwr/(frames*BUF_N)));
+    CNo = 10*log10(tx_pwr/(noise_pwr/(COHPSK_FS/2))); // single sided spctrum magic IDFK!
+    snr3k = CNo - 10*log10(3000);
+    EbNo700 = CNo - 10*log10(700) - 10*log10(6.0/4.0); // divide by bit rate and pilot overhead
+    fprintf(stderr, "PAPR (dB)....: %7.2f (target %3.2f)\nC/No (dB)....: %7.2f\nSNR3k........: %7.2f\nEb/No(Rb=700): %7.2f\n",
+            papr,
+            PAPR_TARGET,
+            CNo,
+            snr3k,
+            EbNo700
+            );
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/cohpsk_defs.h b/codec2/branches/0.7/src/cohpsk_defs.h
new file mode 100644 (file)
index 0000000..28b756e
--- /dev/null
@@ -0,0 +1,9 @@
+/* Generated by write_pilot_file() Octave function */
+
+#define NSYMROW      4   /* number of data symbols per carrier (number of rows)     */
+#define NS           4   /* number of data symbols between pilots                   */
+#define NPILOTSFRAME 2   /* number of pilot symbols per carrier                     */
+#define PILOTS_NC    7   /* number of carriers                                      */
+
+#define NSYMROWPILOT 6   /* number of rows after pilots inserted                    */
+
diff --git a/codec2/branches/0.7/src/cohpsk_demod.c b/codec2/branches/0.7/src/cohpsk_demod.c
new file mode 100644 (file)
index 0000000..a53a387
--- /dev/null
@@ -0,0 +1,227 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: cohpsk_demod.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 6 2015
+
+  Given an input file of raw file (8kHz, 16 bit shorts) of COHPSK modem samples,
+  outputs a file of bits (note one bit per int, not compressed).
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+#include "cohpsk_defs.h"
+#include "cohpsk_internal.h"
+#include "codec2_fdmdv.h"
+#include "octave.h"
+
+#define LOG_FRAMES 100
+#define SYNC_FRAMES 12                    /* sync state uses up extra log storage as we reprocess several times */
+
+int opt_exists(char *argv[], int argc, char opt[]) {
+    int i;
+    for (i=0; i<argc; i++) {
+        if (strcmp(argv[i], opt) == 0) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    FILE          *fin, *fout, *foct;
+    struct COHPSK *cohpsk;
+    float         rx_bits[COHPSK_BITS_PER_FRAME];
+    char          rx_bits_char[COHPSK_BITS_PER_FRAME];
+    double        rx_bits_double[COHPSK_BITS_PER_FRAME];
+    COMP          rx_fdm[COHPSK_MAX_SAMPLES_PER_FRAME];
+    short         rx_fdm_scaled[COHPSK_MAX_SAMPLES_PER_FRAME];
+    int           frames, sync, nin_frame;
+    float        *rx_amp_log = NULL;
+    float        *rx_phi_log = NULL;
+    COMP         *rx_symb_log = NULL;
+    float         f_est_log[LOG_FRAMES], ratio_log[LOG_FRAMES];
+    int           i, r, c, log_data_r, oct, logframes, arg, diversity, sd;
+
+    if (argc < 3) {
+        fprintf(stderr, "\n");
+       printf("usage: %s InputModemRawFile OutputFile [-o OctaveLogFile] [--nd]\n", argv[0]);
+        fprintf(stderr, "\n");
+        fprintf(stderr, "              Default output file format is one byte per bit\n");
+        fprintf(stderr, "  -o          Octave log file for testing\n");
+        fprintf(stderr, "  --nd        non-diversity mode, output frames of %d bits\n", ND*COHPSK_BITS_PER_FRAME);
+        fprintf(stderr, "  --sd        soft decision output, one double per symbol\n");
+        fprintf(stderr, "\n");
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input modem sample 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 file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    foct = NULL;
+    oct = 0;
+    if ((arg = opt_exists(argv, argc, "-o")) != 0) {
+        if ( (foct = fopen(argv[arg+1],"wt")) == NULL ) {
+            fprintf(stderr, "Error opening output Octave file: %s: %s.\n",
+                    argv[4], strerror(errno));
+       exit(1);
+        }
+        oct = 1;
+    }
+
+    if (opt_exists(argv, argc, "--nd")) {
+        diversity = 2;
+    } else {
+        diversity = 1;
+    }
+    sd = 0;
+    if (opt_exists(argv, argc, "--sd")) {
+        sd = 1;
+    }
+
+    cohpsk = cohpsk_create();
+    cohpsk_set_verbose(cohpsk, 0);
+
+    if (oct) {
+        logframes = LOG_FRAMES;
+        rx_amp_log = (float *)malloc(sizeof(float)*logframes*NSYMROW*COHPSK_NC*ND);
+        assert(rx_amp_log != NULL);
+        rx_phi_log = (float *)malloc(sizeof(float)*logframes*NSYMROW*COHPSK_NC*ND);
+        assert(rx_phi_log != NULL);
+        rx_symb_log = (COMP *)malloc(sizeof(COMP)*logframes*NSYMROW*COHPSK_NC*ND);
+        assert(rx_symb_log != NULL);
+        cohpsk->rx_timing_log = (float*)malloc(sizeof(float)*SYNC_FRAMES*logframes*NSYMROWPILOT);
+        assert(cohpsk->rx_timing_log != NULL);
+    }
+
+    log_data_r = 0;
+    frames = 0;
+
+    nin_frame = COHPSK_NOM_SAMPLES_PER_FRAME;
+    while(fread(rx_fdm_scaled, sizeof(short), nin_frame, fin) == nin_frame) {
+       frames++;
+        cohpsk_set_frame(cohpsk, frames);
+
+       /* scale and demod */
+
+       for(i=0; i<nin_frame; i++) {
+           rx_fdm[i].real = rx_fdm_scaled[i]/FDMDV_SCALE;
+            rx_fdm[i].imag = 0.0;
+        }
+
+       cohpsk_demod(cohpsk, rx_bits, &sync, rx_fdm, &nin_frame);
+
+       if (sync) {
+            if (diversity == 1) {
+                if (sd == 0) {
+                    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                        rx_bits_char[i] = rx_bits[i] < 0.0;
+                    fwrite(rx_bits_char, sizeof(char), COHPSK_BITS_PER_FRAME, fout);
+                }
+                else {
+                    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                        rx_bits_double[i] = rx_bits[i];
+                    fwrite(rx_bits_double, sizeof(double), COHPSK_BITS_PER_FRAME, fout);
+                }
+            }
+            else {
+                if (sd == 0) {
+                    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                        rx_bits_char[i] = cohpsk->rx_bits_lower[i] < 0.0;
+                    fwrite(rx_bits_char, sizeof(char), COHPSK_BITS_PER_FRAME, fout);
+                    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                        rx_bits_char[i] = cohpsk->rx_bits_upper[i] < 0.0;
+                    fwrite(rx_bits_char, sizeof(char), COHPSK_BITS_PER_FRAME, fout);
+                }
+                else {
+                    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                        rx_bits_double[i] = cohpsk->rx_bits_lower[i];
+                    fwrite(rx_bits_double, sizeof(double), COHPSK_BITS_PER_FRAME, fout);
+                    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                        rx_bits_double[i] = cohpsk->rx_bits_upper[i];
+                    fwrite(rx_bits_double, sizeof(double), COHPSK_BITS_PER_FRAME, fout);
+                }
+            }
+
+            if (oct) {
+                for(r=0; r<NSYMROW; r++, log_data_r++) {
+                    for(c=0; c<COHPSK_NC*ND; c++) {
+                        rx_amp_log[log_data_r*COHPSK_NC*ND+c] = cohpsk->amp_[r][c];
+                        rx_phi_log[log_data_r*COHPSK_NC*ND+c] = cohpsk->phi_[r][c];
+                        rx_symb_log[log_data_r*COHPSK_NC*ND+c] = cohpsk->rx_symb[r][c];
+                    }
+                }
+
+                f_est_log[frames-1] = cohpsk->f_est;
+                ratio_log[frames-1] = cohpsk->ratio;
+                //fprintf(stderr,"ratio: %f\n", cohpsk->ratio);
+
+                //printf("frames: %d log_data_r: %d\n", frames, log_data_r);
+                if (frames == logframes)
+                    oct = 0;
+            }
+        }
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    fclose(fin);
+    fclose(fout);
+
+    /* optionally dump Octave files */
+
+    if (foct != NULL) {
+        octave_save_float(foct, "rx_amp_log_c", (float*)rx_amp_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+        octave_save_float(foct, "rx_phi_log_c", (float*)rx_phi_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+        octave_save_complex(foct, "rx_symb_log_c", (COMP*)rx_symb_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+        octave_save_float(foct, "rx_timing_log_c", (float*)cohpsk->rx_timing_log, 1, cohpsk->rx_timing_log_index, cohpsk->rx_timing_log_index);
+        octave_save_float(foct, "f_est_log_c", f_est_log, 1, logframes, logframes);
+        octave_save_float(foct, "ratio_log_c", ratio_log, 1, logframes, logframes);
+        fclose(foct);
+    }
+
+    cohpsk_destroy(cohpsk);
+
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/cohpsk_get_test_bits.c b/codec2/branches/0.7/src/cohpsk_get_test_bits.c
new file mode 100644 (file)
index 0000000..e1a32b3
--- /dev/null
@@ -0,0 +1,87 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: cohpsk_put_test_bits.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Generates a file of test bits, useful for input to cohpsk_mod.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+#include "test_bits_coh.h"
+
+int main(int argc, char *argv[])
+{
+    FILE         *fout;
+    int           tx_bits[COHPSK_BITS_PER_FRAME];
+    char          tx_bits_char[COHPSK_BITS_PER_FRAME];
+    int           numBits, nFrames, n;
+    int           *ptest_bits_coh, *ptest_bits_coh_end, i;
+
+    if (argc < 2) {
+       printf("usage: %s OutputOneCharPerBitFile numBits\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[1],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file: %s: %s.\n",
+         argv[1], strerror(errno));
+       exit(1);
+    }
+
+    ptest_bits_coh = (int*)test_bits_coh;
+    ptest_bits_coh_end = (int*)test_bits_coh + sizeof(test_bits_coh)/sizeof(int);
+    numBits = atoi(argv[2]);
+    nFrames = numBits/COHPSK_BITS_PER_FRAME;
+
+    for(n=0; n<nFrames; n++) {
+
+        memcpy(tx_bits, ptest_bits_coh, sizeof(int)*COHPSK_BITS_PER_FRAME);
+        ptest_bits_coh += COHPSK_BITS_PER_FRAME;
+        if (ptest_bits_coh >= ptest_bits_coh_end) {
+            ptest_bits_coh = (int*)test_bits_coh;
+        }
+
+        for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+            tx_bits_char[i] = tx_bits[i];
+
+       fwrite(tx_bits_char, sizeof(char), COHPSK_BITS_PER_FRAME, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+    }
+
+    fclose(fout);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/cohpsk_internal.h b/codec2/branches/0.7/src/cohpsk_internal.h
new file mode 100644 (file)
index 0000000..369fc96
--- /dev/null
@@ -0,0 +1,124 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: cohpsk_internal.h
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+
+  Functions that implement a coherent PSK FDM modem.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __COHPSK_INTERNAL__
+#define __COHPSK_INTERNAL__
+
+#define NCT_SYMB_BUF      (2*NSYMROWPILOT+2)
+#define ND                2                           /* diversity factor ND 1 is no diveristy, ND we have orginal plus
+                                                         one copy */
+#define NSW               4                           /* number of sync window frames */
+#define COHPSK_ND         2                           /* diversity factor   */
+#define COHPSK_M          100                         /* oversampling rate */
+#define COHPSK_NSYM       6
+#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"
+
+struct COHPSK {
+    COMP         ch_fdm_frame_buf[NSW*NSYMROWPILOT*COHPSK_M];  /* buffer of several frames of symbols from channel      */
+    float        pilot2[2*NPILOTSFRAME][COHPSK_NC];
+    float        phi_[NSYMROWPILOT][COHPSK_NC*ND];      /* phase estimates for this frame of rx data symbols     */
+    float        amp_[NSYMROW][COHPSK_NC*ND];           /* amplitude estimates for this frame of rx data symbols */
+    COMP         rx_symb[NSYMROWPILOT][COHPSK_NC*ND];   /* demodulated symbols                                   */
+    float        f_est;
+    COMP         rx_filter_memory[COHPSK_NC*ND][COHPSK_NFILTER];
+    COMP         ct_symb_buf[NCT_SYMB_BUF][COHPSK_NC*ND];
+    int          ct;                                    /* coarse timing offset in symbols                       */
+    float        rx_timing;                             /* fine timing for last symbol in frame                  */
+    int          nin;                                   /* number of samples to input for next symbol            */
+    float        f_fine_est;
+    COMP         ff_rect;
+    COMP         ff_phase;
+    COMP         ct_symb_ff_buf[NSYMROWPILOT+2][COHPSK_NC*ND];
+    int          sync;
+    int          sync_timer;
+
+    int          frame;
+    float        ratio;
+
+    float        sig_rms;
+    float        noise_rms;
+
+    struct FDMDV *fdmdv;
+
+    int           verbose;
+
+    int          *ptest_bits_coh_tx;
+    int          *ptest_bits_coh_rx[2];
+    int          *ptest_bits_coh_end;
+
+    /* counting bit errors using pilots */
+
+    int           npilotbits;
+    int           npilotbiterrors;
+
+    /* optional log variables used for testing Octave to C port */
+
+    COMP          *rx_baseband_log;
+    int            rx_baseband_log_col_index;
+    int            rx_baseband_log_col_sz;
+
+    COMP          *rx_filt_log;
+    int            rx_filt_log_col_index;
+    int            rx_filt_log_col_sz;
+
+    COMP          *ch_symb_log;
+    int            ch_symb_log_r;
+    int            ch_symb_log_col_sz;
+
+    float         *rx_timing_log;
+    int            rx_timing_log_index;
+
+    /* demodulated bits before diversity combination for test/instrumentation purposes */
+
+    float          rx_bits_lower[COHPSK_BITS_PER_FRAME];
+    float          rx_bits_upper[COHPSK_BITS_PER_FRAME];
+
+    /* tx amplitude weights for each carrier for test/instrumentation */
+
+    float          carrier_ampl[COHPSK_NC*ND];
+};
+
+void bits_to_qpsk_symbols(COMP tx_symb[][COHPSK_NC*COHPSK_ND], int tx_bits[], int nbits);
+void qpsk_symbols_to_bits(struct COHPSK *coh, float rx_bits[], COMP ct_symb_buf[][COHPSK_NC*COHPSK_ND]);
+void tx_filter_and_upconvert_coh(COMP tx_fdm[], int Nc, COMP tx_symbols[],
+                                 COMP tx_filter_memory[COHPSK_NC][COHPSK_NSYM],
+                                 COMP phase_tx[], COMP freq[],
+                                 COMP *fbb_phase, COMP fbb_rect);
+void fdm_downconvert_coh(COMP rx_baseband[COHPSK_NC][COHPSK_M+COHPSK_M/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
+void rx_filter_coh(COMP rx_filt[COHPSK_NC+1][P+1], int Nc, COMP rx_baseband[COHPSK_NC+1][COHPSK_M+COHPSK_M/P], COMP rx_filter_memory[COHPSK_NC+1][COHPSK_NFILTER], int nin);
+void frame_sync_fine_freq_est(struct COHPSK *coh, COMP ch_symb[][COHPSK_NC*COHPSK_ND], int sync, int *next_sync);
+void fine_freq_correct(struct COHPSK *coh, int sync, int next_sync);
+int sync_state_machine(struct COHPSK *coh, int sync, int next_sync);
+int cohpsk_fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm);
+
+#endif
diff --git a/codec2/branches/0.7/src/cohpsk_mod.c b/codec2/branches/0.7/src/cohpsk_mod.c
new file mode 100644 (file)
index 0000000..51953e3
--- /dev/null
@@ -0,0 +1,123 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: cohpsk_mod.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 5 2015
+
+  Given an input file of bits (note one bit per float, soft decision format),
+  outputs a raw file (8kHz, 16 bit shorts) of COHPSK modem samples
+  ready to send over a HF radio channel.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+#include "codec2_fdmdv.h"
+
+int opt_exists(char *argv[], int argc, char opt[]) {
+    int i;
+    for (i=0; i<argc; i++) {
+        if (strcmp(argv[i], opt) == 0) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    FILE          *fin, *fout;
+    struct COHPSK *cohpsk;
+    char          tx_bits_char[2*COHPSK_BITS_PER_FRAME];
+    int           tx_bits[2*COHPSK_BITS_PER_FRAME];
+    COMP          tx_fdm[COHPSK_NOM_SAMPLES_PER_FRAME];
+    short         tx_fdm_scaled[COHPSK_NOM_SAMPLES_PER_FRAME];
+    int           frames, diversity;
+    int           i;
+
+    if (argc < 3) {
+        fprintf(stderr, "\n");
+       fprintf(stderr, "usage: %s InputOneCharPerBitFile OutputModemRawFile [-nd]\n", argv[0]);
+        fprintf(stderr, "\n");
+        fprintf(stderr, "  --nd        non-diversity mode, input frames of %d bits\n", 2*COHPSK_BITS_PER_FRAME);
+        fprintf(stderr, "\n");
+       exit(1);
+    }
+
+    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);
+    }
+
+    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);
+    }
+
+    cohpsk = cohpsk_create();
+
+    if (opt_exists(argv, argc, "--nd")) {
+        diversity = 2;
+    }
+    else {
+        diversity = 1;
+    }
+    fprintf(stderr, "diversity: %d\n", diversity);
+
+    frames = 0;
+
+    while(fread(tx_bits_char, sizeof(char), COHPSK_BITS_PER_FRAME*diversity, fin) == COHPSK_BITS_PER_FRAME*diversity) {
+       frames++;
+        
+        for(i=0; i<COHPSK_BITS_PER_FRAME*diversity; i++)
+            tx_bits[i] = tx_bits_char[i];
+       cohpsk_mod(cohpsk, tx_fdm, tx_bits, COHPSK_BITS_PER_FRAME*diversity);
+        cohpsk_clip(tx_fdm);
+
+       /* scale and save to disk as shorts */
+
+       for(i=0; i<COHPSK_NOM_SAMPLES_PER_FRAME; i++)
+           tx_fdm_scaled[i] = FDMDV_SCALE * tx_fdm[i].real;
+
+       fwrite(tx_fdm_scaled, sizeof(short), COHPSK_NOM_SAMPLES_PER_FRAME, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    fclose(fin);
+    fclose(fout);
+    cohpsk_destroy(cohpsk);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/cohpsk_put_test_bits.c b/codec2/branches/0.7/src/cohpsk_put_test_bits.c
new file mode 100644 (file)
index 0000000..d2f6d19
--- /dev/null
@@ -0,0 +1,109 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: cohpsk_put_test_bits.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Sinks a stream of test bits generated by cohpsk_get_test_bits, useful for
+  testing coh psk mod and demod.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_cohpsk.h"
+#include "octave.h"
+
+#define LOG_FRAMES 100
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin, *foct;
+    char          rx_bits[COHPSK_BITS_PER_FRAME];
+    int           state, i, nbits, bit_errors, nerrors;
+    short         error_pattern[COHPSK_BITS_PER_FRAME];
+    int           error_positions_hist[COHPSK_BITS_PER_FRAME], logframes;
+    int           nerr_log[LOG_FRAMES];
+    struct COHPSK *coh;
+
+    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+        error_positions_hist[i] = 0;
+
+    if (argc < 2) {
+       fprintf(stderr, "usage: %s InputOneCharPerBitFile [OctaveLogFile]\n", argv[0]);
+       exit(1);
+    }
+
+    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);
+    }
+
+    coh = cohpsk_create();
+
+    foct = NULL;
+    logframes = 0;
+    if (argc == 3) {
+        if ( (foct = fopen(argv[2],"wt")) == NULL ) {
+            fprintf(stderr, "Error opening output Octave file: %s: %s.\n",
+                    argv[2], strerror(errno));
+       exit(1);
+        }
+    }
+
+    for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+        error_positions_hist[i] = 0;
+
+    state = 0; nbits = 0; nerrors = 0;
+    while (fread(rx_bits, sizeof(char), COHPSK_BITS_PER_FRAME, fin) ==  COHPSK_BITS_PER_FRAME) {
+
+        cohpsk_put_test_bits(coh, &state, error_pattern, &bit_errors, rx_bits, 0);
+        if (state == 1) {
+            for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                error_positions_hist[i] += error_pattern[i];
+           if (logframes < LOG_FRAMES)
+                nerr_log[logframes++] = bit_errors;
+            nerrors += bit_errors;
+            nbits   += COHPSK_BITS_PER_FRAME;
+        }
+
+        if (fin == stdin) fflush(stdin);
+    }
+
+    if (foct != NULL) {
+        octave_save_int(foct, "nerr_log_c", nerr_log, 1, logframes);
+        octave_save_int(foct, "error_positions_hist_c", error_positions_hist, 1, COHPSK_BITS_PER_FRAME);
+        fclose(foct);
+    }
+
+    fclose(fin);
+    fprintf(stderr, "BER: %4.3f Nbits: %d Nerrors: %d\n", (float)nerrors/nbits, nbits, nerrors);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/comp.h b/codec2/branches/0.7/src/comp.h
new file mode 100644 (file)
index 0000000..ffc20c1
--- /dev/null
@@ -0,0 +1,38 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: comp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/08/09
+
+  Complex number definition.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __COMP__
+#define __COMP__
+
+/* Complex number */
+
+typedef struct {
+  float real;
+  float imag;
+} COMP;
+
+#endif
diff --git a/codec2/branches/0.7/src/comp_prim.h b/codec2/branches/0.7/src/comp_prim.h
new file mode 100644 (file)
index 0000000..4d130bc
--- /dev/null
@@ -0,0 +1,141 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: comp_prim.h
+  AUTHOR......: David Rowe
+  DATE CREATED: Marh 2015
+
+  Complex number maths primitives.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __COMP_PRIM__
+#define __COMP_PRIM__
+
+/*---------------------------------------------------------------------------*\
+
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+inline static COMP cneg(COMP a)
+{
+    COMP res;
+
+    res.real = -a.real;
+    res.imag = -a.imag;
+
+    return res;
+}
+
+inline static COMP cconj(COMP a)
+{
+    COMP res;
+
+    res.real = a.real;
+    res.imag = -a.imag;
+
+    return res;
+}
+
+inline static COMP cmult(COMP a, COMP b)
+{
+    COMP res;
+
+    res.real = a.real*b.real - a.imag*b.imag;
+    res.imag = a.real*b.imag + a.imag*b.real;
+
+    return res;
+}
+
+inline static COMP fcmult(float a, COMP b)
+{
+    COMP res;
+
+    res.real = a*b.real;
+    res.imag = a*b.imag;
+
+    return res;
+}
+
+inline static COMP cadd(COMP a, COMP b)
+{
+    COMP res;
+
+    res.real = a.real + b.real;
+    res.imag = a.imag + b.imag;
+
+    return res;
+}
+
+inline static float cabsolute(COMP a)
+{
+    return sqrtf(powf(a.real, 2.0) + powf(a.imag, 2.0));
+}
+
+/*
+ * Euler's formula in a new convenient function
+ */
+inline static COMP comp_exp_j(float phi){
+    COMP res;
+    res.real = cosf(phi);
+    res.imag = sinf(phi);
+    return res;
+}
+
+/*
+ * Quick and easy complex 0
+ */
+inline static COMP comp0(){
+    COMP res;
+    res.real = 0;
+    res.imag = 0;
+    return res;
+}
+
+/*
+ * Quick and easy complex subtract
+ */
+inline static COMP csub(COMP a, COMP b){
+    COMP res;
+    res.real = a.real-b.real;
+    res.imag = a.imag-b.imag;
+    return res;
+}
+
+/*
+ * Compare the magnitude of a and b. if |a|>|b|, return true, otw false.
+ * This needs no square roots
+ */
+inline static int comp_mag_gt(COMP a,COMP b){
+    return ((a.real*a.real)+(a.imag*a.imag)) > ((b.real*b.real)+(b.imag*b.imag));
+}
+
+/*
+ * Normalize a complex number's magnitude to 1
+ */
+inline static COMP comp_normalize(COMP a){
+    COMP b;
+    float av = cabsolute(a);
+    b.real = a.real/av;
+    b.imag = a.imag/av;
+    return b;
+}
+
+#endif
diff --git a/codec2/branches/0.7/src/defines.h b/codec2/branches/0.7/src/defines.h
new file mode 100644 (file)
index 0000000..ec94ed8
--- /dev/null
@@ -0,0 +1,113 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: defines.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/4/93
+
+  Defines and structures used throughout the codec.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __DEFINES__
+#define __DEFINES__
+
+/*---------------------------------------------------------------------------*\
+
+                               DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+/* General defines */
+
+#define N_S        0.010        /* buffer size in s                     */
+#define TW_S       0.005        /* trapezoidal synth window overlap     */
+#define MAX_AMP    160         /* maximum number of harmonics          */
+#ifndef PI
+#define PI         3.141592654 /* mathematical constant                */
+#endif
+#define TWO_PI     6.283185307 /* mathematical constant                */
+#define MAX_STR    2048         /* maximum string size                  */
+
+#define FFT_ENC    512         /* size of FFT used for encoder         */
+#define FFT_DEC    512         /* size of FFT used in decoder          */
+#define V_THRESH   6.0          /* voicing threshold in dB              */
+#define LPC_ORD    10          /* LPC order                            */
+#define LPC_ORD_LOW 6          /* LPC order for lower rates            */
+
+/* Pitch estimation defines */
+
+#define M_PITCH_S  0.0400       /* pitch analysis window in s           */
+#define P_MIN_S    0.0025      /* minimum pitch period in s            */
+#define P_MAX_S    0.0200      /* maximum pitch period in s            */
+
+/*---------------------------------------------------------------------------*\
+
+                               TYPEDEFS
+
+\*---------------------------------------------------------------------------*/
+
+/* Structure to hold constants calculated at run time based on sample rate */
+
+typedef struct {
+    int   Fs;            /* sample rate of this instance             */
+    int   n_samp;        /* number of samples per 10ms frame at Fs   */
+    int   max_amp;       /* maximum number of harmonics              */
+    int   m_pitch;       /* pitch estimation window size in samples  */
+    int   p_min;         /* minimum pitch period in samples          */
+    int   p_max;         /* maximum pitch period in samples          */
+    float Wo_min;        
+    float Wo_max;  
+    int   nw;            /* analysis window size in samples          */      
+    int   tw;            /* trapezoidal synthesis window overlap     */
+} C2CONST;
+
+/* Structure to hold model parameters for one frame */
+
+typedef struct {
+    float Wo;            /* fundamental frequency estimate in radians  */
+    int   L;             /* number of harmonics                        */
+    float A[MAX_AMP+1];          /* amplitiude of each harmonic                */
+    float phi[MAX_AMP+1]; /* phase of each harmonic                     */
+    int   voiced;        /* non-zero if this frame is voiced           */
+} MODEL;
+
+/* describes each codebook  */
+
+struct lsp_codebook {
+    int                        k;        /* dimension of vector        */
+    int                        log2m;    /* number of bits in m        */
+    int                        m;        /* elements in codebook       */
+    const float        *       cb;       /* The elements               */
+};
+
+extern const struct lsp_codebook lsp_cb[];
+extern const struct lsp_codebook lsp_cbd[];
+extern const struct lsp_codebook lsp_cbvq[];
+extern const struct lsp_codebook lsp_cbjnd[];
+extern const struct lsp_codebook lsp_cbdt[];
+extern const struct lsp_codebook lsp_cbjvm[];
+extern const struct lsp_codebook lsp_cbvqanssi[];
+extern const struct lsp_codebook mel_cb[];
+extern const struct lsp_codebook ge_cb[];
+extern const struct lsp_codebook lspmelvq_cb[];
+extern const struct lsp_codebook newamp1vq_cb[];
+extern const struct lsp_codebook newamp1_energy_cb[];
+
+#endif
diff --git a/codec2/branches/0.7/src/drs232.c b/codec2/branches/0.7/src/drs232.c
new file mode 100644 (file)
index 0000000..c11202f
--- /dev/null
@@ -0,0 +1,235 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: drs232.c
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2016
+
+  Looks for a unique word in series of bits.  When found, deframes a RS232
+  encoded frame of bytes.  Used for high biit rate Horus SSTV reception.
+
+  Frame format:
+
+    16 bytes 0x55 - 0xabcdef01 UW - 256 bytes of payload - 2 bytes CRC
+
+  Each byte is encoded as a 10 bit RS232 serial word: 
+  
+    0 LSB .... MSB 1
+
+  Building:
+   
+    $ gcc drs232.c -o drs232 -Wall
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+/* states -----------------------------------------------*/
+
+#define LOOK_FOR_UW    0
+#define COLLECT_PACKET 1
+
+/* packet parameters */
+
+#define UW_BYTES               4
+#define UW_BITS                40
+#define UW_ALLOWED_ERRORS      5
+#define BYTES_PER_PACKET       256
+#define CRC_BYTES              2
+#define BITS_PER_BYTE          10
+#define UNPACKED_PACKET_BYTES  ((UW_BYTES+BYTES_PER_PACKET+CRC_BYTES)*BITS_PER_BYTE)
+
+/* UW pattern we look for, including start/stop bits */
+
+uint8_t uw[] = {
+    /* 0xb                0xa */
+    0, 1, 1, 0, 1, 0, 1, 0, 1, 1,
+    /* 0xd                0xc */
+    0, 1, 0, 1, 1, 0, 0, 1, 1, 1,
+    /* 0xf                0xe */
+    0, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+    /* 0x1                0x0 */
+    0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
+};
+
+ // from http://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum
+
+unsigned short gen_crc16(unsigned char* data_p, int length){
+    unsigned char x;
+    unsigned short crc = 0xFFFF;
+
+    while (length--){
+        x = crc >> 8 ^ *data_p++;
+        x ^= x>>4;
+        crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x <<5)) ^ ((unsigned short)x);
+    }
+    
+    return crc;
+}
+
+
+int main(int argc, char *argv[]) {
+    FILE       *fin, *fout;
+    int         state, next_state, i, j, k, ind, score, bits_read;
+    char        bit;
+    uint8_t     unpacked_packet[UNPACKED_PACKET_BYTES];
+    uint8_t     packet[BYTES_PER_PACKET+CRC_BYTES];
+    uint8_t     abyte;
+    uint16_t    tx_checksum, rx_checksum;
+    int         verbose, packet_errors, packets;
+
+    if (argc < 3) {
+       fprintf(stderr, "usage: drs232 InputOneBitPerChar OutputPackets [-v[v]]\n");
+       exit(1);
+    }
+
+    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);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    verbose = 0;
+    if (argc > 3) {
+        if (strcmp(argv[3], "-v") == 0) {
+            verbose = 1;
+        }
+        if (strcmp(argv[3], "-vv") == 0) {
+            verbose = 2;
+        }
+    }
+
+    state = LOOK_FOR_UW;
+    for(i=0; i<UNPACKED_PACKET_BYTES; i++)
+        unpacked_packet[i] = 0;
+    bits_read = 0; 
+
+    packet_errors = packets = 0;
+
+    while(fread(&bit, sizeof(char), 1, fin) == 1) {
+        bits_read++;
+
+        next_state = state;
+
+        if (state == LOOK_FOR_UW) {
+
+            /* put latest input bit into sliding buffer */
+            
+            for(i=0; i<UW_BITS-1; i++) {
+                unpacked_packet[i] = unpacked_packet[i+1];
+            }
+            unpacked_packet[i] = bit;
+
+            /* lets see if it matches the UW */
+
+            score = 0;
+            for(i=0; i<UW_BITS; i++) {
+                score += (unpacked_packet[i] == uw[i]);
+                /* if (i == BITS_PER_BYTE)
+                    printf(" ");
+                    printf("%1d", unpacked_packet[i]); */
+            }
+            //printf("\n");
+            
+            //fprintf(stderr,"UW score: %d\n", score);
+            if (score > (UW_BITS-UW_ALLOWED_ERRORS)) {
+                if (verbose == 2) {
+                    fprintf(stderr,"UW found!\n");
+                }
+                ind = UW_BITS;
+                next_state = COLLECT_PACKET;
+            }             
+        }
+
+        if (state == COLLECT_PACKET) {
+            unpacked_packet[ind++] = bit;
+           if (ind == UNPACKED_PACKET_BYTES) {
+
+               /* OK we have enough bits, remove RS232 sync bits and pack */
+
+               for(i=UW_BITS,k=0; i<UNPACKED_PACKET_BYTES; i+=BITS_PER_BYTE,k++) {
+                   //for(j=0; j<BITS_PER_BYTE; j++)
+                   //    printf("%1d", unpacked_packet[i+j]);
+                   //printf("\n");
+                   abyte = 0;
+                   for(j=0; j<8; j++) {
+                       abyte |= unpacked_packet[i+j+1] << j;
+                   }
+                   packet[k] = abyte;
+                   //printf("k:%d 0x%02x\n", k, packet[k]);
+                   //if (k == 4)
+                   //  exit(0);
+               }
+
+               /* output if CRC check is OK */
+
+               rx_checksum = gen_crc16(packet, BYTES_PER_PACKET);
+               tx_checksum = packet[BYTES_PER_PACKET] + (packet[BYTES_PER_PACKET+1] << 8);
+
+               if (verbose == 2) {
+                   fprintf(stderr, "k=%d bytes after UW  tx_checksum: 0x%02x rx_checksum: 0x%02x\n", 
+                           k, tx_checksum, rx_checksum);
+               }
+
+               packets++;
+               if (rx_checksum == tx_checksum) {
+                   fwrite(packet, sizeof(char), BYTES_PER_PACKET, fout);
+               }
+               else
+                   packet_errors++;
+
+               if (verbose) {
+                   fprintf(stderr, "packets: %d packet_errors: %d PER: %4.3f\n", 
+                           packets, packet_errors, 
+                           (float)packet_errors/packets);
+               }
+
+               next_state = LOOK_FOR_UW;
+            }
+
+        }
+        //if (bits_read == (16*10 + UNPACKED_PACKET_BYTES))
+        //    exit(0);
+
+        state = next_state;      
+    }
+
+    fclose(fin);
+    fclose(fout);
+
+    fprintf(stderr, "packets: %d packet_errors: %d PER: %4.3f\n", packets, packet_errors, 
+            (float)packet_errors/packets);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/drs232_ldpc.c b/codec2/branches/0.7/src/drs232_ldpc.c
new file mode 100755 (executable)
index 0000000..40bb706
--- /dev/null
@@ -0,0 +1,285 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: drs232_ldpc.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Sep 2016
+
+  Looks for a unique word in series of soft decision symbols.  When
+  found, deframes a RS232 encoded frame of soft decision bit, LDPC
+  decodes, and outputs a frame of packed bytes.  Used for high biit
+  rate Horus SSTV reception.
+
+  Frame format:
+
+    16 bytes 0x55 - 0xabcdef01 UW - 256 bytes of payload - 2 bytes CRC - 65 bytes LPDC Parity
+
+  Each byte is encoded as a 10 bit RS232 serial word: 
+  
+    0 LSB .... MSB 1
+
+  Building:
+   
+    $ gcc drs232_ldpc.c mpdecode_core.c -o drs232_ldpc -Wall -lm
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "mpdecode_core.h"
+
+/* Machine generated consts, H_rows, H_cols, test input/output data to
+   change LDPC code regenerate this file. */
+
+#include "H2064_516_sparse.h"  
+
+/* states -----------------------------------------------*/
+
+#define LOOK_FOR_UW    0
+#define COLLECT_PACKET 1
+
+/* packet parameters */
+
+#define UW_BYTES               4
+#define UW_BITS                40
+#define UW_ALLOWED_ERRORS      5
+#define BYTES_PER_PACKET       256
+#define CRC_BYTES              2
+#define PARITY_BYTES           65
+#define BITS_PER_BYTE          10
+#define UNPACKED_PACKET_BYTES  ((UW_BYTES+BYTES_PER_PACKET+CRC_BYTES)*BITS_PER_BYTE)
+#define SYMBOLS_PER_PACKET     (BYTES_PER_PACKET+CRC_BYTES+PARITY_BYTES)*BITS_PER_BYTE
+
+/* UW pattern we look for, including start/stop bits */
+
+uint8_t uw[] = {
+    /* 0xb                0xa */
+    0, 1, 1, 0, 1, 0, 1, 0, 1, 1,
+    /* 0xd                0xc */
+    0, 1, 0, 1, 1, 0, 0, 1, 1, 1,
+    /* 0xf                0xe */
+    0, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+    /* 0x1                0x0 */
+    0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
+};
+
+
+// from http://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum
+
+unsigned short gen_crc16(unsigned char* data_p, int length){
+    unsigned char x;
+    unsigned short crc = 0xFFFF;
+
+    while (length--){
+        x = crc >> 8 ^ *data_p++;
+        x ^= x>>4;
+        crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x <<5)) ^ ((unsigned short)x);
+    }
+    
+    return crc;
+}
+
+
+int main(int argc, char *argv[]) {
+    FILE       *fin, *fout;
+    int         state, next_state, i, j, k, ind, score, verbose;
+    float       symbol;
+    uint8_t     bit, bit_buffer[UW_BITS];
+    double      symbol_buf[SYMBOLS_PER_PACKET];
+    double      symbol_buf_no_rs232[SYMBOLS_PER_PACKET];
+    double      llr[SYMBOLS_PER_PACKET];
+    char        unpacked_packet[CODELENGTH];
+    uint8_t     packet[BYTES_PER_PACKET+CRC_BYTES];
+    uint8_t     abyte;
+    uint16_t    tx_checksum, rx_checksum, packet_errors, packets;
+    int         CodeLength, iter;
+    struct LDPC ldpc;
+
+    assert(sizeof(uw) == UW_BITS);
+
+    /* LDPC parameters */
+
+    CodeLength = CODELENGTH;                    /* length of entire codeword in bits */
+
+    /* set up LDPC code from include file constants */
+
+    ldpc.max_iter = MAX_ITER;
+    ldpc.dec_type = 0;
+    ldpc.q_scale_factor = 1;
+    ldpc.r_scale_factor = 1;
+    ldpc.CodeLength = CODELENGTH;
+    ldpc.NumberParityBits = NUMBERPARITYBITS;
+    ldpc.NumberRowsHcols = NUMBERROWSHCOLS;
+    ldpc.max_row_weight = MAX_ROW_WEIGHT;
+    ldpc.max_col_weight = MAX_COL_WEIGHT;
+    ldpc.H_rows = H_rows;
+    ldpc.H_cols = H_cols;
+
+    /* process command line ----------------------------------------------*/
+
+    if (argc < 3) {
+       fprintf(stderr, "usage: drs232 InputOneSymbolPerFloat OutputPackets [-v[v]]\n");
+       exit(1);
+    }
+
+    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);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    verbose = 0;
+    if (argc > 3) {
+        if (strcmp(argv[3], "-v") == 0) {
+            verbose = 1;
+        }
+        if (strcmp(argv[3], "-vv") == 0) {
+            verbose = 2;
+        }
+    }
+
+    state = LOOK_FOR_UW;
+    memset(bit_buffer,0,  sizeof(bit_buffer));
+
+    packet_errors = packets = 0;
+
+    while(fread(&symbol, sizeof(float), 1, fin) == 1) {
+
+        /* make hard decision for purpose of UW detection */
+
+        bit = symbol < 0;
+        //printf("symbol; %f bit: %d\n", symbol, bit);
+        next_state = state;
+        if (state == LOOK_FOR_UW) {
+
+            /* put latest input bit into sliding buffer */
+            
+            for(i=0; i<UW_BITS-1; i++) {
+                bit_buffer[i] = bit_buffer[i+1];
+            }
+            bit_buffer[i] = bit;
+
+            /* lets see if it matches the UW */
+
+            score = 0;
+            for(i=0; i<UW_BITS; i++) {
+                score += (bit_buffer[i] == uw[i]);
+                /* if (i == BITS_PER_BYTE)
+                    printf(" ");
+                    printf("%1d", unpacked_packet[i]); */
+            }
+            //printf("\n");
+            
+            //fprintf(stderr,"UW score: %d\n", score);
+            if (score >= (UW_BITS-UW_ALLOWED_ERRORS)) {
+                //fprintf(stderr,"UW found! score: %d\n verbose: %d\n", score, verbose);
+                ind = 0;
+                next_state = COLLECT_PACKET;
+            }             
+        }
+
+        if (state == COLLECT_PACKET) {
+            symbol_buf[ind++] = symbol;
+            if (ind == SYMBOLS_PER_PACKET) {
+
+               /* OK we have enough bits, remove RS232 sync symbols.
+                  This is set up for bit<->byte ordering as per python
+                  tx code */
+
+               for(i=0,k=0; i<SYMBOLS_PER_PACKET; i+=BITS_PER_BYTE) {
+                   for(j=0; j<8; j++) {
+                       symbol_buf_no_rs232[k+j] = symbol_buf[i+7-j+1];
+                   }
+                   k += 8;
+               }
+
+               /* now LDPC decode */
+
+               sd_to_llr(llr, symbol_buf_no_rs232, CodeLength);
+               iter = run_ldpc_decoder(&ldpc, unpacked_packet, llr);
+
+               /* pack into bytes */
+
+               for(i=0; i<BYTES_PER_PACKET+CRC_BYTES; i++) {
+                   abyte = 0;
+                   for(j=0; j<8; j++)
+                       abyte |= unpacked_packet[8*i+j] << (7-j);
+                   packet[i] = abyte;
+               }
+
+               /* then output if CRC check is OK */
+
+               rx_checksum = gen_crc16(packet, BYTES_PER_PACKET);
+               tx_checksum = packet[BYTES_PER_PACKET] + (packet[BYTES_PER_PACKET+1] << 8);
+
+               if (verbose == 2) {
+                   if (rx_checksum != tx_checksum) {
+                       fprintf(stderr, "tx_checksum: 0x%02x rx_checksum: 0x%02x\n", 
+                               tx_checksum, rx_checksum);
+                   }
+               }
+               
+               packets++;
+               if (rx_checksum == tx_checksum) {
+                   fwrite(packet, sizeof(char), BYTES_PER_PACKET, fout);
+               }
+               else
+                   packet_errors++;
+
+               if (verbose) {
+                   fprintf(stderr, "packets: %d packet_errors: %d PER: %4.3f iter: %d\n", 
+                           packets, packet_errors, 
+                           (float)packet_errors/packets, iter);
+               }
+               //exit(0);
+               next_state = LOOK_FOR_UW;
+            }
+
+        }
+        //if (bits_read == (16*10 + UNPACKED_PACKET_BYTES))
+        //    exit(0);
+
+        state = next_state;      
+    }
+
+    fclose(fin);
+    fclose(fout);
+
+    fprintf(stderr, "packets: %d packet_errors: %d PER: %4.3f\n", packets, packet_errors, 
+            (float)packet_errors/packets);
+
+    return 0;
+}
+
+
diff --git a/codec2/branches/0.7/src/dump.c b/codec2/branches/0.7/src/dump.c
new file mode 100644 (file)
index 0000000..c8b3b31
--- /dev/null
@@ -0,0 +1,674 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: dump.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 25/8/09
+
+  Routines to dump data to text files for Octave analysis.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "defines.h"
+#include "comp.h"
+#include "dump.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef __EMBEDDED__
+#include "gdb_stdio.h"
+#define fprintf gdb_stdio_fprintf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#endif
+
+#ifdef DUMP
+static int dumpon = 0;
+
+static FILE *fsn = NULL;
+static FILE *fsw = NULL;
+static FILE *few = NULL;
+static FILE *fsw_ = NULL;
+static FILE *fsoftdec = NULL;
+static FILE *fmodel = NULL;
+static FILE *fqmodel = NULL;
+static FILE *fpwb = NULL;
+static FILE *fpw = NULL;
+static FILE *frw = NULL;
+static FILE *flsp = NULL;
+static FILE *fweights = NULL;
+static FILE *flsp_ = NULL;
+static FILE *fmel = NULL;
+static FILE *fmel_indexes = NULL;
+static FILE *fphase = NULL;
+static FILE *fphase_ = NULL;
+static FILE *ffw = NULL;
+static FILE *fe = NULL;
+static FILE *fsq = NULL;
+static FILE *fdec = NULL;
+static FILE *fsnr = NULL;
+static FILE *flpcsnr = NULL;
+static FILE *fak = NULL;
+static FILE *fak_ = NULL;
+static FILE *fbg = NULL;
+static FILE *fE = NULL;
+static FILE *frk = NULL;
+static FILE *fhephase = NULL;
+
+static char  prefix[MAX_STR];
+
+void dump_on(char p[]) {
+    dumpon = 1;
+    strcpy(prefix, p);
+}
+
+void dump_off(){
+    if (fsn != NULL)
+       fclose(fsn);
+    if (fsw != NULL)
+       fclose(fsw);
+    if (fsw_ != NULL)
+       fclose(fsw_);
+    if (few != NULL)
+       fclose(few);
+    if (fmodel != NULL)
+       fclose(fmodel);
+    if (fsoftdec != NULL)
+       fclose(fsoftdec);
+    if (fqmodel != NULL)
+       fclose(fqmodel);
+    if (fpwb != NULL)
+       fclose(fpwb);
+    if (fpw != NULL)
+       fclose(fpw);
+    if (frw != NULL)
+       fclose(frw);
+    if (flsp != NULL)
+       fclose(flsp);
+    if (fweights != NULL)
+       fclose(fweights);
+    if (flsp_ != NULL)
+       fclose(flsp_);
+    if (fmel != NULL)
+       fclose(fmel);
+    if (fmel_indexes != NULL)
+       fclose(fmel_indexes);
+    if (fphase != NULL)
+       fclose(fphase);
+    if (fphase_ != NULL)
+       fclose(fphase_);
+    if (ffw != NULL)
+       fclose(ffw);
+    if (fe != NULL)
+       fclose(fe);
+    if (fsq != NULL)
+       fclose(fsq);
+    if (fdec != NULL)
+       fclose(fdec);
+    if (fsnr != NULL)
+       fclose(fsnr);
+    if (flpcsnr != NULL)
+       fclose(flpcsnr);
+    if (fak != NULL)
+       fclose(fak);
+    if (fak_ != NULL)
+       fclose(fak_);
+    if (fbg != NULL)
+       fclose(fbg);
+    if (fE != NULL)
+       fclose(fE);
+    if (frk != NULL)
+       fclose(frk);
+    if (fhephase != NULL)
+       fclose(fhephase);
+}
+
+void dump_Sn(int m_pitch, float Sn[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fsn == NULL) {
+       sprintf(s,"%s_sn.txt", prefix);
+       fsn = fopen(s, "wt");
+       assert(fsn != NULL);
+    }
+
+    /* split across two lines to avoid max line length problems */
+    /* reconstruct in Octave */
+
+    for(i=0; i<m_pitch/2; i++)
+       fprintf(fsn,"%f\t",Sn[i]);
+    fprintf(fsn,"\n");
+    for(i=m_pitch/2; i<m_pitch; i++)
+       fprintf(fsn,"%f\t",Sn[i]);
+    fprintf(fsn,"\n");
+}
+
+void dump_Sw(COMP Sw[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fsw == NULL) {
+       sprintf(s,"%s_sw.txt", prefix);
+       fsw = fopen(s, "wt");
+       assert(fsw != NULL);
+    }
+
+    for(i=0; i<FFT_ENC/2; i++)
+       fprintf(fsw,"%f\t",
+               10.0*log10(Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag));
+    fprintf(fsw,"\n");
+}
+
+void dump_Sw_(COMP Sw_[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fsw_ == NULL) {
+       sprintf(s,"%s_sw_.txt", prefix);
+       fsw_ = fopen(s, "wt");
+       assert(fsw_ != NULL);
+    }
+
+    for(i=0; i<FFT_ENC/2; i++)
+       fprintf(fsw_,"%f\t",
+               10.0*log10(Sw_[i].real*Sw_[i].real + Sw_[i].imag*Sw_[i].imag));
+    fprintf(fsw_,"\n");
+}
+
+void dump_Ew(COMP Ew[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (few == NULL) {
+       sprintf(s,"%s_ew.txt", prefix);
+       few = fopen(s, "wt");
+       assert(few != NULL);
+    }
+
+    for(i=0; i<FFT_ENC/2; i++)
+       fprintf(few,"%f\t",
+               10.0*log10(Ew[i].real*Ew[i].real + Ew[i].imag*Ew[i].imag));
+    fprintf(few,"\n");
+}
+
+void dump_softdec(float *softdec, int n)
+{
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fsoftdec == NULL) {
+       sprintf(s,"%s_softdec.txt", prefix);
+       fsoftdec = fopen(s, "wt");
+       assert(fsoftdec != NULL);
+    }
+
+    for(i=0; i<n; i++)
+       fprintf(fsoftdec,"%f\t", softdec[i]);
+    fprintf(fsoftdec,"\n");
+}
+
+void dump_model(MODEL *model) {
+    int l;
+    char s[MAX_STR];
+    char line[MAX_STR*10];
+
+    if (!dumpon) return;
+
+    if (fmodel == NULL) {
+       sprintf(s,"%s_model.txt", prefix);
+       fmodel = fopen(s, "wt");
+       assert(fmodel != NULL);
+    }
+
+    sprintf(line,"%12f %12d ", model->Wo, model->L);
+    for(l=1; l<=model->L; l++) {
+       sprintf(s,"%12f ",model->A[l]);
+        strcat(line, s);
+        assert(strlen(line) < MAX_STR*10);
+    }
+    for(l=model->L+1; l<=MAX_AMP; l++) {
+       sprintf(s,"%12f ", 0.0);
+        strcat(line,s);
+        assert(strlen(line) < MAX_STR*10);
+    }
+
+    sprintf(s,"%d\n",model->voiced);
+    strcat(line,s);
+    fprintf(fmodel,"%s",line);
+}
+
+void dump_quantised_model(MODEL *model) {
+    int l;
+    char s[MAX_STR];
+    char line[2048];
+
+    if (!dumpon) return;
+
+    if (fqmodel == NULL) {
+       sprintf(s,"%s_qmodel.txt", prefix);
+       fqmodel = fopen(s, "wt");
+       assert(fqmodel != NULL);
+    }
+
+    sprintf(line,"%12f %12d ", model->Wo, model->L);
+    for(l=1; l<=model->L; l++) {
+       sprintf(s,"%12f ",model->A[l]);
+        strcat(line, s);
+    }
+    for(l=model->L+1; l<=MAX_AMP; l++) {
+       sprintf(s,"%12f ", 0.0);
+        strcat(line, s);
+    }
+
+    sprintf(s,"%d\n",model->voiced);
+    strcat(line, s);
+    fprintf(fqmodel, "%s", line);
+}
+
+void dump_phase(float phase[], int L) {
+    int l;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fphase == NULL) {
+       sprintf(s,"%s_phase.txt", prefix);
+       fphase = fopen(s, "wt");
+       assert(fphase != NULL);
+    }
+
+    for(l=1; l<=L; l++)
+       fprintf(fphase,"%f\t",phase[l]);
+    for(l=L+1; l<=MAX_AMP; l++)
+       fprintf(fphase,"%f\t",0.0);
+    fprintf(fphase,"\n");
+}
+
+void dump_phase_(float phase_[], int L) {
+    int l;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fphase_ == NULL) {
+       sprintf(s,"%s_phase_.txt", prefix);
+       fphase_ = fopen(s, "wt");
+       assert(fphase_ != NULL);
+    }
+
+    for(l=1; l<=L; l++)
+       fprintf(fphase_,"%f\t",phase_[l]);
+    for(l=L+1; l<MAX_AMP; l++)
+       fprintf(fphase_,"%f\t",0.0);
+    fprintf(fphase_,"\n");
+}
+
+
+void dump_hephase(int ind[], int dim) {
+    int m;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fhephase == NULL) {
+       sprintf(s,"%s_hephase.txt", prefix);
+       fhephase = fopen(s, "wt");
+       assert(fhephase != NULL);
+    }
+
+    for(m=0; m<dim; m++)
+       fprintf(fhephase,"%d\t",ind[m]);
+    fprintf(fhephase,"\n");
+}
+
+
+void dump_snr(float snr) {
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fsnr == NULL) {
+       sprintf(s,"%s_snr.txt", prefix);
+       fsnr = fopen(s, "wt");
+       assert(fsnr != NULL);
+    }
+
+    fprintf(fsnr,"%f\n",snr);
+}
+
+void dump_lpc_snr(float snr) {
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (flpcsnr == NULL) {
+       sprintf(s,"%s_lpc_snr.txt", prefix);
+       flpcsnr = fopen(s, "wt");
+       assert(flpcsnr != NULL);
+    }
+
+    fprintf(flpcsnr,"%f\n",snr);
+}
+
+/* Pw "before" post filter so we can plot before and after */
+
+void dump_Pwb(float Pwb[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fpwb == NULL) {
+       sprintf(s,"%s_pwb.txt", prefix);
+       fpwb = fopen(s, "wt");
+       assert(fpwb != NULL);
+    }
+
+    for(i=0; i<FFT_ENC/2; i++)
+       fprintf(fpwb,"%f\t",Pwb[i]);
+    fprintf(fpwb,"\n");
+}
+
+void dump_Pw(float Pw[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fpw == NULL) {
+       sprintf(s,"%s_pw.txt", prefix);
+       fpw = fopen(s, "wt");
+       assert(fpw != NULL);
+    }
+
+    for(i=0; i<FFT_ENC/2; i++)
+       fprintf(fpw,"%f\t",Pw[i]);
+    fprintf(fpw,"\n");
+}
+
+void dump_Rw(float Rw[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (frw == NULL) {
+       sprintf(s,"%s_rw.txt", prefix);
+       frw = fopen(s, "wt");
+       assert(frw != NULL);
+    }
+
+    for(i=0; i<FFT_ENC/2; i++)
+       fprintf(frw,"%f\t",Rw[i]);
+    fprintf(frw,"\n");
+}
+
+void dump_weights(float w[], int order) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fweights == NULL) {
+       sprintf(s,"%s_weights.txt", prefix);
+       fweights = fopen(s, "wt");
+       assert(fweights != NULL);
+    }
+
+    for(i=0; i<order; i++)
+       fprintf(fweights,"%f\t", w[i]);
+    fprintf(fweights,"\n");
+}
+
+void dump_lsp(float lsp[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (flsp == NULL) {
+       sprintf(s,"%s_lsp.txt", prefix);
+       flsp = fopen(s, "wt");
+       assert(flsp != NULL);
+    }
+
+    for(i=0; i<10; i++)
+       fprintf(flsp,"%f\t",lsp[i]);
+    fprintf(flsp,"\n");
+}
+
+void dump_lsp_(float lsp_[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (flsp_ == NULL) {
+       sprintf(s,"%s_lsp_.txt", prefix);
+       flsp_ = fopen(s, "wt");
+       assert(flsp_ != NULL);
+    }
+
+    for(i=0; i<10; i++)
+       fprintf(flsp_,"%f\t",lsp_[i]);
+    fprintf(flsp_,"\n");
+}
+
+void dump_mel(float mel[], int order) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fmel == NULL) {
+       sprintf(s,"%s_mel.txt", prefix);
+       fmel = fopen(s, "wt");
+       assert(fmel != NULL);
+    }
+
+    for(i=0; i<order; i++)
+       fprintf(fmel,"%f\t",mel[i]);
+    fprintf(fmel,"\n");
+}
+
+void dump_mel_indexes(int mel_indexes[], int order) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fmel_indexes == NULL) {
+       sprintf(s,"%s_mel_indexes.txt", prefix);
+       fmel_indexes = fopen(s, "wt");
+       assert(fmel_indexes != NULL);
+    }
+
+    for(i=0; i<order; i++)
+       fprintf(fmel_indexes,"%d\t",mel_indexes[i]);
+    fprintf(fmel_indexes,"\n");
+}
+
+void dump_ak(float ak[], int order) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fak == NULL) {
+       sprintf(s,"%s_ak.txt", prefix);
+       fak = fopen(s, "wt");
+       assert(fak != NULL);
+    }
+
+    for(i=0; i<=order; i++)
+       fprintf(fak,"%f\t",ak[i]);
+    fprintf(fak,"\n");
+}
+
+void dump_ak_(float ak_[], int order) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fak_ == NULL) {
+       sprintf(s,"%s_ak_.txt", prefix);
+       fak_ = fopen(s, "wt");
+       assert(fak_ != NULL);
+    }
+
+    for(i=0; i<=order; i++)
+       fprintf(fak_,"%f\t",ak_[i]);
+    fprintf(fak_,"\n");
+}
+
+void dump_Fw(COMP Fw[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (ffw == NULL) {
+       sprintf(s,"%s_fw.txt", prefix);
+       ffw = fopen(s, "wt");
+       assert(ffw != NULL);
+    }
+
+    for(i=0; i<256; i++)
+       fprintf(ffw,"%f\t",Fw[i].real);
+    fprintf(ffw,"\n");
+}
+
+void dump_e(float e_hz[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fe == NULL) {
+       sprintf(s,"%s_e.txt", prefix);
+       fe = fopen(s, "wt");
+       assert(fe != NULL);
+    }
+
+    for(i=0; i<500/2; i++)
+       fprintf(fe,"%f\t",e_hz[i]);
+    fprintf(fe,"\n");
+    for(i=500/2; i<500; i++)
+       fprintf(fe,"%f\t",e_hz[i]);
+    fprintf(fe,"\n");
+}
+
+void dump_sq(int m_pitch, float sq[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fsq == NULL) {
+       sprintf(s,"%s_sq.txt", prefix);
+       fsq = fopen(s, "wt");
+       assert(fsq != NULL);
+    }
+
+    for(i=0; i<m_pitch/2; i++)
+       fprintf(fsq,"%f\t",sq[i]);
+    fprintf(fsq,"\n");
+    for(i=m_pitch/2; i<m_pitch; i++)
+       fprintf(fsq,"%f\t",sq[i]);
+    fprintf(fsq,"\n");
+}
+
+void dump_dec(COMP Fw[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fdec == NULL) {
+       sprintf(s,"%s_dec.txt", prefix);
+       fdec = fopen(s, "wt");
+       assert(fdec != NULL);
+    }
+
+    for(i=0; i<320/5; i++)
+       fprintf(fdec,"%f\t",Fw[i].real);
+    fprintf(fdec,"\n");
+}
+
+void dump_bg(float e, float bg_est, float percent_uv) {
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fbg == NULL) {
+       sprintf(s,"%s_bg.txt", prefix);
+       fbg = fopen(s, "wt");
+       assert(fbg != NULL);
+    }
+
+    fprintf(fbg,"%f\t%f\t%f\n", e, bg_est, percent_uv);
+}
+
+void dump_E(float E) {
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (fE == NULL) {
+       sprintf(s,"%s_E.txt", prefix);
+       fE = fopen(s, "wt");
+       assert(fE != NULL);
+    }
+
+    fprintf(fE,"%f\n", 10.0*log10(E));
+}
+
+#if 0
+void dump_Rk(float Rk[]) {
+    int i;
+    char s[MAX_STR];
+
+    if (!dumpon) return;
+
+    if (frk == NULL) {
+       sprintf(s,"%s_rk.txt", prefix);
+       frk = fopen(s, "wt");
+       assert(frk != NULL);
+    }
+
+    for(i=0; i<P_MAX; i++)
+       fprintf(frk,"%f\t",Rk[i]);
+    fprintf(frk,"\n");
+}
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/src/dump.h b/codec2/branches/0.7/src/dump.h
new file mode 100644 (file)
index 0000000..08eca2d
--- /dev/null
@@ -0,0 +1,82 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: dump.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 25/8/09
+
+  Routines to dump data to text files for Octave analysis.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __DUMP__
+#define __DUMP__
+
+#include "defines.h"
+#include "comp.h"
+#include "codec2_fft.h"
+#include "codec2_internal.h"
+
+void dump_on(char filename_prefix[]);
+void dump_off();
+
+void dump_Sn(int m_pitch, float Sn[]);
+void dump_Sw(COMP Sw[]);
+void dump_Sw_(COMP Sw_[]);
+void dump_Ew(COMP Ew[]);
+void dump_softdec(float *softdec, int n);
+
+/* amplitude modelling */
+
+void dump_model(MODEL *m);
+void dump_quantised_model(MODEL *m);
+void dump_Pwn(COMP Pw[]);
+void dump_Pw(float Pw[]);
+void dump_Rw(float Rw[]);
+void dump_lsp(float lsp[]);
+void dump_weights(float w[], int ndim);
+void dump_lsp_(float lsp_[]);
+void dump_mel(float mel[], int order);
+void dump_mel_indexes(int mel_indexes[], int order);
+void dump_ak(float ak[], int order);
+void dump_ak_(float ak[], int order);
+void dump_E(float E);
+void dump_lpc_snr(float snr);
+
+/* phase modelling */
+
+void dump_snr(float snr);
+void dump_phase(float phase[], int L);
+void dump_phase_(float phase[], int L);
+void dump_hephase(int ind[], int dim);
+
+/* NLP states */
+
+void dump_sq(int m_pitch, float sq[]);
+void dump_dec(COMP Fw[]);
+void dump_Fw(COMP Fw[]);
+void dump_e(float e_hz[]);
+#if 0
+void dump_Rk(float Rk[]);
+#endif
+
+/* post filter */
+
+void dump_bg(float e, float bg_est, float percent_uv);
+void dump_Pwb(float Pwb[]);
+
+#endif
diff --git a/codec2/branches/0.7/src/fdmdv.c b/codec2/branches/0.7/src/fdmdv.c
new file mode 100644 (file)
index 0000000..ee07501
--- /dev/null
@@ -0,0 +1,1990 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 14 2012
+
+  Functions that implement the FDMDV modem.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*---------------------------------------------------------------------------*\
+
+                               INCLUDES
+
+\*---------------------------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef ARM_MATH_CM4
+  #include "stm32f4xx.h"
+  #include "core_cm4.h"
+  #include "arm_math.h"
+#endif
+
+
+#include "fdmdv_internal.h"
+#include "codec2_fdmdv.h"
+#include "comp_prim.h"
+#include "rn.h"
+#include "rxdec_coeff.h"
+#include "test_bits.h"
+#include "pilot_coeff.h"
+#include "codec2_fft.h"
+#include "hanning.h"
+#include "os.h"
+#include "machdep.h"
+
+static int sync_uw[] = {1,-1,1,-1,1,-1};
+#ifdef __EMBEDDED__
+#define printf gdb_stdio_printf
+#endif
+
+#ifndef ARM_MATH_CM4
+  #define SINF(a) sinf(a)
+  #define COSF(a) cosf(a)
+#else
+  #define SINF(a) arm_sin_f32(a)
+  #define COSF(a) arm_cos_f32(a)
+#endif
+
+static const COMP  pi_on_4 = { .70710678118654752439, .70710678118654752439 }; // COSF(PI/4) , SINF(PI/4)
+
+
+/*--------------------------------------------------------------------------* \
+
+  FUNCTION....: fdmdv_create
+  AUTHOR......: David Rowe
+  DATE CREATED: 16/4/2012
+
+  Create and initialise an instance of the modem.  Returns a pointer
+  to the modem states or NULL on failure.  One set of states is
+  sufficient for a full duplex modem.
+
+\*---------------------------------------------------------------------------*/
+
+struct FDMDV * fdmdv_create(int Nc)
+{
+    struct FDMDV *f;
+    int           c, i, k;
+
+    assert(NC == FDMDV_NC_MAX);  /* check public and private #defines match */
+    assert(Nc <= NC);
+    assert(FDMDV_NOM_SAMPLES_PER_FRAME == M_FAC);
+    assert(FDMDV_MAX_SAMPLES_PER_FRAME == (M_FAC+M_FAC/P));
+
+    f = (struct FDMDV*)malloc(sizeof(struct FDMDV));
+    if (f == NULL)
+       return NULL;
+
+    f->Nc = Nc;
+
+    f->ntest_bits = Nc*NB*4;
+    f->current_test_bit = 0;
+    f->rx_test_bits_mem = (int*)malloc(sizeof(int)*f->ntest_bits);
+    assert(f->rx_test_bits_mem != NULL);
+    for(i=0; i<f->ntest_bits; i++)
+       f->rx_test_bits_mem[i] = 0;
+    assert((sizeof(test_bits)/sizeof(int)) >= f->ntest_bits);
+
+    f->old_qpsk_mapping = 0;
+
+    f->tx_pilot_bit = 0;
+
+    for(c=0; c<Nc+1; c++) {
+       f->prev_tx_symbols[c].real = 1.0;
+       f->prev_tx_symbols[c].imag = 0.0;
+       f->prev_rx_symbols[c].real = 1.0;
+       f->prev_rx_symbols[c].imag = 0.0;
+
+       for(k=0; k<NSYM; k++) {
+           f->tx_filter_memory[c][k].real = 0.0;
+           f->tx_filter_memory[c][k].imag = 0.0;
+       }
+
+       /* Spread initial FDM carrier phase out as far as possible.
+           This helped PAPR for a few dB.  We don't need to adjust rx
+           phase as DQPSK takes care of that. */
+
+       f->phase_tx[c].real = COSF(2.0*PI*c/(Nc+1));
+       f->phase_tx[c].imag = SINF(2.0*PI*c/(Nc+1));
+
+       f->phase_rx[c].real = 1.0;
+       f->phase_rx[c].imag = 0.0;
+
+       for(k=0; k<NT*P; k++) {
+           f->rx_filter_mem_timing[c][k].real = 0.0;
+           f->rx_filter_mem_timing[c][k].imag = 0.0;
+       }
+    }
+    f->prev_tx_symbols[Nc].real = 2.0;
+
+    fdmdv_set_fsep(f, FSEP);
+    f->freq[Nc].real = COSF(2.0*PI*0.0/FS);
+    f->freq[Nc].imag = SINF(2.0*PI*0.0/FS);
+    f->freq_pol[Nc]  = 2.0*PI*0.0/FS;
+
+    f->fbb_rect.real     = COSF(2.0*PI*FDMDV_FCENTRE/FS);
+    f->fbb_rect.imag     = SINF(2.0*PI*FDMDV_FCENTRE/FS);
+    f->fbb_pol           = 2.0*PI*FDMDV_FCENTRE/FS;
+    f->fbb_phase_tx.real = 1.0;
+    f->fbb_phase_tx.imag = 0.0;
+    f->fbb_phase_rx.real = 1.0;
+    f->fbb_phase_rx.imag = 0.0;
+
+    /* Generate DBPSK pilot Look Up Table (LUT) */
+
+    generate_pilot_lut(f->pilot_lut, &f->freq[Nc]);
+
+    /* freq Offset estimation states */
+
+    f->fft_pilot_cfg = codec2_fft_alloc (MPILOTFFT, 0, NULL, NULL);
+    assert(f->fft_pilot_cfg != NULL);
+
+    for(i=0; i<NPILOTBASEBAND; i++) {
+       f->pilot_baseband1[i].real = f->pilot_baseband2[i].real = 0.0;
+       f->pilot_baseband1[i].imag = f->pilot_baseband2[i].imag = 0.0;
+    }
+    f->pilot_lut_index = 0;
+    f->prev_pilot_lut_index = 3*M_FAC;
+
+    for(i=0; i<NRXDEC-1+M_FAC; i++) {
+        f->rxdec_lpf_mem[i].real = 0.0;
+        f->rxdec_lpf_mem[i].imag = 0.0;
+    }
+
+    for(i=0; i<NPILOTLPF; i++) {
+       f->pilot_lpf1[i].real = f->pilot_lpf2[i].real = 0.0;
+       f->pilot_lpf1[i].imag = f->pilot_lpf2[i].imag = 0.0;
+    }
+
+    f->foff = 0.0;
+    f->foff_phase_rect.real = 1.0;
+    f->foff_phase_rect.imag = 0.0;
+
+    for(i=0; i<NFILTER+M_FAC; i++) {
+        f->rx_fdm_mem[i].real = 0.0;
+        f->rx_fdm_mem[i].imag = 0.0;
+    }
+
+    f->fest_state = 0;
+    f->sync = 0;
+    f->timer = 0;
+    for(i=0; i<NSYNC_MEM; i++)
+        f->sync_mem[i] = 0;
+
+    for(c=0; c<Nc+1; c++) {
+       f->sig_est[c] = 0.0;
+       f->noise_est[c] = 0.0;
+    }
+
+    f->sig_pwr_av = 0.0;
+    f->foff_filt = 0.0;
+
+    return f;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_destroy
+  AUTHOR......: David Rowe
+  DATE CREATED: 16/4/2012
+
+  Destroy an instance of the modem.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_destroy(struct FDMDV *fdmdv)
+{
+    assert(fdmdv != NULL);
+    codec2_fft_free(fdmdv->fft_pilot_cfg);
+    free(fdmdv->rx_test_bits_mem);
+    free(fdmdv);
+}
+
+
+void fdmdv_use_old_qpsk_mapping(struct FDMDV *fdmdv) {
+    fdmdv->old_qpsk_mapping = 1;
+}
+
+
+int fdmdv_bits_per_frame(struct FDMDV *fdmdv)
+{
+    return (fdmdv->Nc * NB);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_get_test_bits()
+  AUTHOR......: David Rowe
+  DATE CREATED: 16/4/2012
+
+  Generate a frame of bits from a repeating sequence of random data.  OK so
+  it's not very random if it repeats but it makes syncing at the demod easier
+  for test purposes.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_get_test_bits(struct FDMDV *f, int tx_bits[])
+{
+    int i;
+    int bits_per_frame = fdmdv_bits_per_frame(f);
+
+    for(i=0; i<bits_per_frame; i++) {
+       tx_bits[i] = test_bits[f->current_test_bit];
+       f->current_test_bit++;
+       if (f->current_test_bit > (f->ntest_bits-1))
+           f->current_test_bit = 0;
+    }
+}
+
+float fdmdv_get_fsep(struct FDMDV *f)
+{
+    return f->fsep;
+}
+
+void fdmdv_set_fsep(struct FDMDV *f, float fsep) {
+    int   c;
+    float carrier_freq;
+
+    f->fsep = fsep;
+
+    /* Set up frequency of each carrier */
+
+    for(c=0; c<f->Nc/2; c++) {
+       carrier_freq = (-f->Nc/2 + c)*f->fsep;
+       f->freq[c].real = COSF(2.0*PI*carrier_freq/FS);
+       f->freq[c].imag = SINF(2.0*PI*carrier_freq/FS);
+       f->freq_pol[c]  = 2.0*PI*carrier_freq/FS;
+    }
+
+    for(c=f->Nc/2; c<f->Nc; c++) {
+       carrier_freq = (-f->Nc/2 + c + 1)*f->fsep;
+       f->freq[c].real = COSF(2.0*PI*carrier_freq/FS);
+       f->freq[c].imag = SINF(2.0*PI*carrier_freq/FS);
+       f->freq_pol[c]  = 2.0*PI*carrier_freq/FS;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: bits_to_dqpsk_symbols()
+  AUTHOR......: David Rowe
+  DATE CREATED: 16/4/2012
+
+  Maps bits to parallel DQPSK symbols. Generate Nc+1 QPSK symbols from
+  vector of (1,Nc*Nb) input tx_bits.  The Nc+1 symbol is the +1 -1 +1
+  .... BPSK sync carrier.
+
+\*---------------------------------------------------------------------------*/
+
+void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping)
+{
+    int c, msb, lsb;
+    COMP j = {0.0,1.0};
+
+    /* Map tx_bits to to Nc DQPSK symbols.  Note legacy support for
+       old (suboptimal) V0.91 FreeDV mapping */
+
+    for(c=0; c<Nc; c++) {
+       msb = tx_bits[2*c];
+       lsb = tx_bits[2*c+1];
+       if ((msb == 0) && (lsb == 0))
+           tx_symbols[c] = prev_tx_symbols[c];
+       if ((msb == 0) && (lsb == 1))
+            tx_symbols[c] = cmult(j, prev_tx_symbols[c]);
+       if ((msb == 1) && (lsb == 0)) {
+           if (old_qpsk_mapping)
+                tx_symbols[c] = cneg(prev_tx_symbols[c]);
+            else
+                tx_symbols[c] = cmult(cneg(j),prev_tx_symbols[c]);
+        }
+       if ((msb == 1) && (lsb == 1)) {
+           if (old_qpsk_mapping)
+                tx_symbols[c] = cmult(cneg(j),prev_tx_symbols[c]);
+            else
+                tx_symbols[c] = cneg(prev_tx_symbols[c]);
+        }
+    }
+
+    /* +1 -1 +1 -1 BPSK sync carrier, once filtered becomes (roughly)
+       two spectral lines at +/- Rs/2 */
+
+    if (*pilot_bit)
+       tx_symbols[Nc] = cneg(prev_tx_symbols[Nc]);
+    else
+       tx_symbols[Nc] = prev_tx_symbols[Nc];
+
+    if (*pilot_bit)
+       *pilot_bit = 0;
+    else
+       *pilot_bit = 1;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: tx_filter()
+  AUTHOR......: David Rowe
+  DATE CREATED: 17/4/2012
+
+  Given Nc*NB bits construct M_FAC samples (1 symbol) of Nc+1 filtered
+  symbols streams.
+
+\*---------------------------------------------------------------------------*/
+
+void tx_filter(COMP tx_baseband[NC+1][M_FAC], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM])
+{
+    int     c;
+    int     i,j,k;
+    float   acc;
+    COMP    gain;
+
+    gain.real = sqrtf(2.0)/2.0;
+    gain.imag = 0.0;
+
+    for(c=0; c<Nc+1; c++)
+       tx_filter_memory[c][NSYM-1] = cmult(tx_symbols[c], gain);
+
+    /*
+       tx filter each symbol, generate M_FAC filtered output samples for each symbol.
+       Efficient polyphase filter techniques used as tx_filter_memory is sparse
+    */
+
+    for(i=0; i<M_FAC; i++) {
+       for(c=0; c<Nc+1; c++) {
+
+           /* filter real sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+               acc += M_FAC * tx_filter_memory[c][j].real * gt_alpha5_root[k];
+           tx_baseband[c][i].real = acc;
+
+           /* filter imag sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+               acc += M_FAC * tx_filter_memory[c][j].imag * gt_alpha5_root[k];
+           tx_baseband[c][i].imag = acc;
+
+       }
+    }
+
+    /* shift memory, inserting zeros at end */
+
+    for(i=0; i<NSYM-1; i++)
+       for(c=0; c<Nc+1; c++)
+           tx_filter_memory[c][i] = tx_filter_memory[c][i+1];
+
+    for(c=0; c<Nc+1; c++) {
+       tx_filter_memory[c][NSYM-1].real = 0.0;
+       tx_filter_memory[c][NSYM-1].imag = 0.0;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: tx_filter_and_upconvert()
+  AUTHOR......: David Rowe
+  DATE CREATED: 13 August 2014
+
+  Given Nc symbols construct M_FAC samples (1 symbol) of Nc+1 filtered
+  and upconverted symbols.
+
+\*---------------------------------------------------------------------------*/
+
+void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[],
+                             COMP tx_filter_memory[NC+1][NSYM],
+                             COMP phase_tx[], COMP freq[],
+                             COMP *fbb_phase, COMP fbb_rect)
+{
+    int     c;
+    int     i,j,k;
+    float   acc;
+    COMP    gain;
+    COMP    tx_baseband;
+    COMP  two = {2.0, 0.0};
+    float mag;
+
+    gain.real = sqrtf(2.0)/2.0;
+    gain.imag = 0.0;
+
+    for(i=0; i<M_FAC; i++) {
+       tx_fdm[i].real = 0.0;
+       tx_fdm[i].imag = 0.0;
+    }
+
+    for(c=0; c<Nc+1; c++)
+       tx_filter_memory[c][NSYM-1] = cmult(tx_symbols[c], gain);
+
+    /*
+       tx filter each symbol, generate M_FAC filtered output samples for
+       each symbol, which we then freq shift and sum with other
+       carriers.  Efficient polyphase filter techniques used as
+       tx_filter_memory is sparse
+    */
+
+    for(c=0; c<Nc+1; c++) {
+        for(i=0; i<M_FAC; i++) {
+
+           /* filter real sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+               acc += M_FAC * tx_filter_memory[c][j].real * gt_alpha5_root[k];
+           tx_baseband.real = acc;
+
+           /* filter imag sample of symbol for carrier c */
+
+           acc = 0.0;
+           for(j=0,k=M_FAC-i-1; j<NSYM; j++,k+=M_FAC)
+               acc += M_FAC * tx_filter_memory[c][j].imag * gt_alpha5_root[k];
+           tx_baseband.imag = acc;
+
+            /* freq shift and sum */
+
+           phase_tx[c] = cmult(phase_tx[c], freq[c]);
+           tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband, phase_tx[c]));
+       }
+    }
+
+    /* shift whole thing up to carrier freq */
+
+    for (i=0; i<M_FAC; i++) {
+       *fbb_phase = cmult(*fbb_phase, fbb_rect);
+       tx_fdm[i] = cmult(tx_fdm[i], *fbb_phase);
+    }
+
+    /*
+      Scale such that total Carrier power C of real(tx_fdm) = Nc.  This
+      excludes the power of the pilot tone.
+      We return the complex (single sided) signal to make frequency
+      shifting for the purpose of testing easier
+    */
+
+    for (i=0; i<M_FAC; i++)
+       tx_fdm[i] = cmult(two, tx_fdm[i]);
+
+    /* normalise digital oscillators as the magnitude can drift over time */
+
+    for (c=0; c<Nc+1; c++) {
+        mag = cabsolute(phase_tx[c]);
+       phase_tx[c].real /= mag;
+       phase_tx[c].imag /= mag;
+    }
+
+    mag = cabsolute(*fbb_phase);
+    fbb_phase->real /= mag;
+    fbb_phase->imag /= mag;
+
+    /* shift memory, inserting zeros at end */
+
+    for(i=0; i<NSYM-1; i++)
+       for(c=0; c<Nc+1; c++)
+           tx_filter_memory[c][i] = tx_filter_memory[c][i+1];
+
+    for(c=0; c<Nc+1; c++) {
+       tx_filter_memory[c][NSYM-1].real = 0.0;
+       tx_filter_memory[c][NSYM-1].imag = 0.0;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdm_upconvert()
+  AUTHOR......: David Rowe
+  DATE CREATED: 17/4/2012
+
+  Construct FDM signal by frequency shifting each filtered symbol
+  stream.  Returns complex signal so we can apply frequency offsets
+  easily.
+
+\*---------------------------------------------------------------------------*/
+
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M_FAC], COMP phase_tx[], COMP freq[],
+                   COMP *fbb_phase, COMP fbb_rect)
+{
+    int   i,c;
+    COMP  two = {2.0, 0.0};
+    float mag;
+
+    for(i=0; i<M_FAC; i++) {
+       tx_fdm[i].real = 0.0;
+       tx_fdm[i].imag = 0.0;
+    }
+
+    for (c=0; c<=Nc; c++)
+       for (i=0; i<M_FAC; i++) {
+           phase_tx[c] = cmult(phase_tx[c], freq[c]);
+           tx_fdm[i] = cadd(tx_fdm[i], cmult(tx_baseband[c][i], phase_tx[c]));
+       }
+
+    /* shift whole thing up to carrier freq */
+
+    for (i=0; i<M_FAC; i++) {
+       *fbb_phase = cmult(*fbb_phase, fbb_rect);
+       tx_fdm[i] = cmult(tx_fdm[i], *fbb_phase);
+    }
+
+    /*
+      Scale such that total Carrier power C of real(tx_fdm) = Nc.  This
+      excludes the power of the pilot tone.
+      We return the complex (single sided) signal to make frequency
+      shifting for the purpose of testing easier
+    */
+
+    for (i=0; i<M_FAC; i++)
+       tx_fdm[i] = cmult(two, tx_fdm[i]);
+
+    /* normalise digital oscilators as the magnitude can drift over time */
+
+    for (c=0; c<Nc+1; c++) {
+        mag = cabsolute(phase_tx[c]);
+       phase_tx[c].real /= mag;
+       phase_tx[c].imag /= mag;
+    }
+
+    mag = cabsolute(*fbb_phase);
+    fbb_phase->real /= mag;
+    fbb_phase->imag /= mag;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_mod()
+  AUTHOR......: David Rowe
+  DATE CREATED: 26/4/2012
+
+  FDMDV modulator, take a frame of FDMDV_BITS_PER_FRAME bits and
+  generates a frame of FDMDV_SAMPLES_PER_FRAME modulated symbols.
+  Sync bit is returned to aid alignment of your next frame.
+
+  The sync_bit value returned will be used for the _next_ frame.
+
+  The output signal is complex to support single sided frequency
+  shifting, for example when testing frequency offsets in channel
+  simulation.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_mod(struct FDMDV *fdmdv, COMP tx_fdm[], int tx_bits[], int *sync_bit)
+{
+    COMP          tx_symbols[NC+1];
+    PROFILE_VAR(mod_start, tx_filter_and_upconvert_start);
+
+    PROFILE_SAMPLE(mod_start);
+    bits_to_dqpsk_symbols(tx_symbols, fdmdv->Nc, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit, fdmdv->old_qpsk_mapping);
+    memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(fdmdv->Nc+1));
+    PROFILE_SAMPLE_AND_LOG(tx_filter_and_upconvert_start, mod_start, "    bits_to_dqpsk_symbols");
+    tx_filter_and_upconvert(tx_fdm, fdmdv->Nc, tx_symbols, fdmdv->tx_filter_memory,
+                            fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
+    PROFILE_SAMPLE_AND_LOG2(tx_filter_and_upconvert_start, "    tx_filter_and_upconvert");
+
+    *sync_bit = fdmdv->tx_pilot_bit;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: generate_pilot_fdm()
+  AUTHOR......: David Rowe
+  DATE CREATED: 19/4/2012
+
+  Generate M_FAC samples of DBPSK pilot signal for Freq offset estimation.
+
+\*---------------------------------------------------------------------------*/
+
+void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol,
+                       float *filter_mem, COMP *phase, COMP *freq)
+{
+    int   i,j,k;
+    float tx_baseband[M_FAC];
+
+    /* +1 -1 +1 -1 DBPSK sync carrier, once filtered becomes (roughly)
+       two spectral lines at +/- RS/2 */
+
+    if (*bit)
+       *symbol = -*symbol;
+
+    if (*bit)
+       *bit = 0;
+    else
+       *bit = 1;
+
+    /* filter DPSK symbol to create M_FAC baseband samples */
+
+    filter_mem[NFILTER-1] = (sqrtf(2)/2) * *symbol;
+    for(i=0; i<M_FAC; i++) {
+       tx_baseband[i] = 0.0;
+       for(j=M_FAC-1,k=M_FAC-i-1; j<NFILTER; j+=M_FAC,k+=M_FAC)
+           tx_baseband[i] += M_FAC * filter_mem[j] * gt_alpha5_root[k];
+    }
+
+    /* shift memory, inserting zeros at end */
+
+    for(i=0; i<NFILTER-M_FAC; i++)
+       filter_mem[i] = filter_mem[i+M_FAC];
+
+    for(i=NFILTER-M_FAC; i<NFILTER; i++)
+       filter_mem[i] = 0.0;
+
+    /* upconvert */
+
+    for(i=0; i<M_FAC; i++) {
+       *phase = cmult(*phase, *freq);
+       pilot_fdm[i].real = sqrtf(2)*2*tx_baseband[i] * phase->real;
+       pilot_fdm[i].imag = sqrtf(2)*2*tx_baseband[i] * phase->imag;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: generate_pilot_lut()
+  AUTHOR......: David Rowe
+  DATE CREATED: 19/4/2012
+
+  Generate a 4M sample vector of DBPSK pilot signal.  As the pilot signal
+  is periodic in 4M samples we can then use this vector as a look up table
+  for pilot signal generation in the demod.
+
+\*---------------------------------------------------------------------------*/
+
+void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq)
+{
+    int   pilot_rx_bit = 0;
+    float pilot_symbol = sqrtf(2.0);
+    COMP  pilot_phase  = {1.0, 0.0};
+    float pilot_filter_mem[NFILTER];
+    COMP  pilot[M_FAC];
+    int   i,f;
+
+    for(i=0; i<NFILTER; i++)
+       pilot_filter_mem[i] = 0.0;
+
+    /* discard first 4 symbols as filter memory is filling, just keep
+       last four symbols */
+
+    for(f=0; f<8; f++) {
+       generate_pilot_fdm(pilot, &pilot_rx_bit, &pilot_symbol, pilot_filter_mem, &pilot_phase, pilot_freq);
+       if (f >= 4)
+           memcpy(&pilot_lut[M_FAC*(f-4)], pilot, M_FAC*sizeof(COMP));
+    }
+   
+    // create complex conjugate since we need this and only this later on 
+    for (f=0;f<4*M_FAC;f++)
+    {
+        pilot_lut[f] = cconj(pilot_lut[f]);
+    }
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: lpf_peak_pick()
+  AUTHOR......: David Rowe
+  DATE CREATED: 20/4/2012
+
+  LPF and peak pick part of freq est, put in a function as we call it twice.
+
+\*---------------------------------------------------------------------------*/
+
+void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[],
+                  COMP pilot_lpf[], codec2_fft_cfg fft_pilot_cfg, COMP S[], int nin,
+                   int do_fft)
+{
+    int   i,j,k;
+    int   mpilot;
+    float mag, imax;
+    int   ix;
+    float r;
+
+    /* LPF cutoff 200Hz, so we can handle max +/- 200 Hz freq offset */
+
+    for(i=0; i<NPILOTLPF-nin; i++)
+        pilot_lpf[i] = pilot_lpf[nin+i];
+    for(i=NPILOTLPF-nin, j=NPILOTBASEBAND-nin; i<NPILOTLPF; i++,j++) {
+        pilot_lpf[i].real = 0.0; pilot_lpf[i].imag = 0.0;
+
+        // STM32F4 hand optimized, this alone makes it go done from 1.6 to 1.17ms
+        // switching pilot_coeff to RAM (by removing const in pilot_coeff.h) would save
+        // another 0.11 ms at the expense of NPILOTCOEFF * 4 bytes == 120 bytes RAM
+
+        if (NPILOTCOEFF%5 == 0)
+        {
+            for(k=0; k<NPILOTCOEFF; k+=5)
+            {
+                COMP i0 = fcmult(pilot_coeff[k], pilot_baseband[j-NPILOTCOEFF+1+k]);
+                COMP i1 = fcmult(pilot_coeff[k+1], pilot_baseband[j-NPILOTCOEFF+1+k+1]);
+                COMP i2 = fcmult(pilot_coeff[k+2], pilot_baseband[j-NPILOTCOEFF+1+k+2]);
+                COMP i3 = fcmult(pilot_coeff[k+3], pilot_baseband[j-NPILOTCOEFF+1+k+3]);
+                COMP i4 = fcmult(pilot_coeff[k+4], pilot_baseband[j-NPILOTCOEFF+1+k+4]);
+
+                pilot_lpf[i] = cadd(cadd(cadd(cadd(cadd(pilot_lpf[i], i0),i1),i2),i3),i4);
+            }
+        }
+        else
+        {
+            for(k=0; k<NPILOTCOEFF; k++)
+            {
+                pilot_lpf[i] = cadd(pilot_lpf[i], fcmult(pilot_coeff[k], pilot_baseband[j-NPILOTCOEFF+1+k]));
+            }
+
+        }
+    }
+
+    /* We only need to do FFTs if we are out of sync.  Making them optional saves CPU in sync, which is when
+       we need to run the codec */
+
+    imax = 0.0;
+    *foff = 0.0;
+    for(i=0; i<MPILOTFFT; i++) {
+        S[i].real = 0.0;
+        S[i].imag = 0.0;
+    }
+
+    if (do_fft) {
+
+        /* decimate to improve DFT resolution, window and DFT */
+        mpilot = FS/(2*200);  /* calc decimation rate given new sample rate is twice LPF freq */
+        for(i=0,j=0; i<NPILOTLPF; i+=mpilot,j++) {
+            S[j] = fcmult(hanning[i], pilot_lpf[i]);
+        }
+
+        codec2_fft_inplace(fft_pilot_cfg, S);
+
+        /* peak pick and convert to Hz */
+
+        imax = 0.0;
+        ix = 0;
+        for(i=0; i<MPILOTFFT; i++) {
+            mag = S[i].real*S[i].real + S[i].imag*S[i].imag;
+            if (mag > imax) {
+                imax = mag;
+                ix = i;
+            }
+        }
+        r = 2.0*200.0/MPILOTFFT;     /* maps FFT bin to frequency in Hz */
+
+        if (ix >= MPILOTFFT/2)
+            *foff = (ix - MPILOTFFT)*r;
+        else
+            *foff = (ix)*r;
+    }
+
+    *max = imax;
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: rx_est_freq_offset()
+  AUTHOR......: David Rowe
+  DATE CREATED: 19/4/2012
+
+  Estimate frequency offset of FDM signal using BPSK pilot.  Note that
+  this algorithm is quite sensitive to pilot tone level wrt other
+  carriers, so test variations to the pilot amplitude carefully.
+
+\*---------------------------------------------------------------------------*/
+
+float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin, int do_fft)
+{
+    int  i;
+#ifndef ARM_MATH_CM4
+    int j;
+#endif
+    COMP pilot[M_FAC+M_FAC/P];
+    COMP prev_pilot[M_FAC+M_FAC/P];
+    float foff, foff1, foff2;
+    float   max1, max2;
+
+    assert(nin <= M_FAC+M_FAC/P);
+
+    /* get pilot samples used for correlation/down conversion of rx signal */
+
+    for (i=0; i<nin; i++) {
+       pilot[i] = f->pilot_lut[f->pilot_lut_index];
+       f->pilot_lut_index++;
+       if (f->pilot_lut_index >= 4*M_FAC)
+           f->pilot_lut_index = 0;
+
+       prev_pilot[i] = f->pilot_lut[f->prev_pilot_lut_index];
+       f->prev_pilot_lut_index++;
+       if (f->prev_pilot_lut_index >= 4*M_FAC)
+           f->prev_pilot_lut_index = 0;
+    }
+
+    /*
+      Down convert latest M_FAC samples of pilot by multiplying by ideal
+      BPSK pilot signal we have generated locally.  The peak of the
+      resulting signal is sensitive to the time shift between the
+      received and local version of the pilot, so we do it twice at
+      different time shifts and choose the maximum.
+    */
+
+    for(i=0; i<NPILOTBASEBAND-nin; i++) {
+       f->pilot_baseband1[i] = f->pilot_baseband1[i+nin];
+       f->pilot_baseband2[i] = f->pilot_baseband2[i+nin];
+    }
+
+#ifndef ARM_MATH_CM4
+    for(i=0,j=NPILOTBASEBAND-nin; i<nin; i++,j++) {
+               f->pilot_baseband1[j] = cmult(rx_fdm[i], pilot[i]);
+       f->pilot_baseband2[j] = cmult(rx_fdm[i], prev_pilot[i]);
+    }
+#else
+    // TODO: Maybe a handwritten mult taking advantage of rx_fdm[0] being 
+    // used twice would be faster but this is for sure faster than 
+    // the implementation above in any case.
+    arm_cmplx_mult_cmplx_f32(&rx_fdm[0].real,&pilot[0].real,&f->pilot_baseband1[NPILOTBASEBAND-nin].real,nin);
+    arm_cmplx_mult_cmplx_f32(&rx_fdm[0].real,&prev_pilot[0].real,&f->pilot_baseband2[NPILOTBASEBAND-nin].real,nin);
+#endif
+
+    lpf_peak_pick(&foff1, &max1, f->pilot_baseband1, f->pilot_lpf1, f->fft_pilot_cfg, f->S1, nin, do_fft);
+    lpf_peak_pick(&foff2, &max2, f->pilot_baseband2, f->pilot_lpf2, f->fft_pilot_cfg, f->S2, nin, do_fft);
+
+    if (max1 > max2)
+       foff = foff1;
+    else
+       foff = foff2;
+
+    return foff;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_freq_shift()
+  AUTHOR......: David Rowe
+  DATE CREATED: 26/4/2012
+
+  Frequency shift modem signal.  The use of complex input and output allows
+  single sided frequency shifting (no images).
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff,
+                      COMP *foff_phase_rect, int nin)
+{
+    COMP  foff_rect;
+    float mag;
+    int   i;
+
+    foff_rect.real = COSF(2.0*PI*foff/FS);
+    foff_rect.imag = SINF(2.0*PI*foff/FS);
+    for(i=0; i<nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
+    }
+
+    /* normalise digital oscilator as the magnitude can drfift over time */
+
+    mag = cabsolute(*foff_phase_rect);
+    foff_phase_rect->real /= mag;
+    foff_phase_rect->imag /= mag;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdm_downconvert
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/4/2012
+
+  Frequency shift each modem carrier down to Nc+1 baseband signals.
+
+\*---------------------------------------------------------------------------*/
+
+void fdm_downconvert(COMP rx_baseband[NC+1][M_FAC+M_FAC/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin)
+{
+    int   i,c;
+    float mag;
+
+    /* maximum number of input samples to demod */
+
+    assert(nin <= (M_FAC+M_FAC/P));
+
+    /* downconvert */
+
+    for (c=0; c<Nc+1; c++)
+       for (i=0; i<nin; i++) {
+           phase_rx[c] = cmult(phase_rx[c], freq[c]);
+           rx_baseband[c][i] = cmult(rx_fdm[i], cconj(phase_rx[c]));
+       }
+
+    /* normalise digital oscilators as the magnitude can drift over time */
+
+    for (c=0; c<Nc+1; c++) {
+        mag = cabsolute(phase_rx[c]);
+       phase_rx[c].real /= mag;
+       phase_rx[c].imag /= mag;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: rx_filter()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/4/2012
+
+  Receive filter each baseband signal at oversample rate P.  Filtering at
+  rate P lowers CPU compared to rate M_FAC.
+
+  Depending on the number of input samples to the demod nin, we
+  produce P-1, P (usually), or P+1 filtered samples at rate P.  nin is
+  occasionally adjusted to compensate for timing slips due to
+  different tx and rx sample clocks.
+
+\*---------------------------------------------------------------------------*/
+
+void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M_FAC+M_FAC/P], COMP rx_filter_memory[NC+1][NFILTER], int nin)
+{
+    int c, i,j,k,l;
+    int n=M_FAC/P;
+
+    /* rx filter each symbol, generate P filtered output samples for
+       each symbol.  Note we keep filter memory at rate M_FAC, it's just
+       the filter output at rate P */
+
+    for(i=0, j=0; i<nin; i+=n,j++) {
+
+       /* latest input sample */
+
+       for(c=0; c<Nc+1; c++)
+           for(k=NFILTER-n,l=i; k<NFILTER; k++,l++)
+               rx_filter_memory[c][k] = rx_baseband[c][l];
+
+       /* convolution (filtering) */
+
+       for(c=0; c<Nc+1; c++) {
+           rx_filt[c][j].real = 0.0; rx_filt[c][j].imag = 0.0;
+           for(k=0; k<NFILTER; k++)
+               rx_filt[c][j] = cadd(rx_filt[c][j], fcmult(gt_alpha5_root[k], rx_filter_memory[c][k]));
+       }
+
+       /* make room for next input sample */
+
+       for(c=0; c<Nc+1; c++)
+           for(k=0,l=n; k<NFILTER-n; k++,l++)
+               rx_filter_memory[c][k] = rx_filter_memory[c][l];
+    }
+
+    assert(j <= (P+1)); /* check for any over runs */
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: rxdec_filter()
+  AUTHOR......: David Rowe
+  DATE CREATED: 31 July 2014
+
+  +/- 1000Hz low pass filter, allows us to filter at rate Q to save CPU load.
+
+\*---------------------------------------------------------------------------*/
+
+void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin) {
+    int i,j,k;
+
+    for(i=0; i<NRXDEC-1+M_FAC-nin; i++)
+        rxdec_lpf_mem[i] = rxdec_lpf_mem[i+nin];
+    for(i=0, j=NRXDEC-1+M_FAC-nin; i<nin; i++,j++)
+        rxdec_lpf_mem[j] = rx_fdm[i];
+
+    for(i=0; i<nin; i++) {
+        rx_fdm_filter[i].real = 0.0;
+        for(k=0; k<NRXDEC; k++)
+            rx_fdm_filter[i].real += rxdec_lpf_mem[i+k].real * rxdec_coeff[k];
+        rx_fdm_filter[i].imag = 0.0;
+        for(k=0; k<NRXDEC; k++)
+            rx_fdm_filter[i].imag += rxdec_lpf_mem[i+k].imag * rxdec_coeff[k];
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fir_filter2()
+  AUTHOR......: Danilo Beuche
+  DATE CREATED: August 2016
+
+  Ths version submitted by Danilo for the STM32F4 platform.  The idea
+  is to avoid reading the same value from the STM32F4 "slow" flash
+  twice. 2-4ms of savings per frame were measured by Danilo and the mcHF
+  team.
+
+\*---------------------------------------------------------------------------*/
+
+static void fir_filter2(float acc[2], float mem[], const float coeff[], const unsigned int dec_rate) {
+    acc[0] = 0.0;
+    acc[1] = 0.0;
+
+    float c1,c2,c3,c4,c5,m1,m2,m3,m4,m5,m6,m7,m8,m9,m10,a1,a2;
+    float* inpCmplx = &mem[0];
+    const float* coeffPtr = &coeff[0];
+
+    int m;
+
+    // this manual loop unrolling gives significant boost on STM32 machines
+    // reduction from avg 3.2ms to 2.4ms in tfdmv.c test
+    // 5 was the sweet spot, with 6 it took longer again
+    // and should not harm other, more powerful machines
+    // no significant difference in output, only rounding (which was to be expected)
+    // TODO: try to move coeffs to RAM and check if it makes a significant difference
+    if (NFILTER%(dec_rate*5) == 0) {
+        for(m=0; m<NFILTER; m+=dec_rate*5) {
+            c1 = *coeffPtr;
+
+            m1 = inpCmplx[0];
+            m2 = inpCmplx[1];
+
+            inpCmplx+= dec_rate*2;
+            coeffPtr+= dec_rate;
+
+            c2 = *coeffPtr;
+            m3 = inpCmplx[0];
+            m4 = inpCmplx[1];
+
+            inpCmplx+= dec_rate*2;
+            coeffPtr+= dec_rate;
+
+            c3 = *coeffPtr;
+            m5 = inpCmplx[0];
+            m6 = inpCmplx[1];
+
+            inpCmplx+= dec_rate*2;
+            coeffPtr+= dec_rate;
+
+            c4 = *coeffPtr;
+            m7 = inpCmplx[0];
+            m8 = inpCmplx[1];
+
+            inpCmplx+= dec_rate*2;
+            coeffPtr+= dec_rate;
+
+            c5 = *coeffPtr;
+            m9 = inpCmplx[0];
+            m10 = inpCmplx[1];
+
+            inpCmplx+= dec_rate*2;
+            coeffPtr+= dec_rate;
+
+            a1 = c1 * m1 + c2 * m3 + c3 * m5 + c4 * m7 + c5 * m9;
+            a2 = c1 * m2 + c2 * m4 + c3 * m6 + c4 * m8 + c5 * m10;
+            acc[0] += a1;
+            acc[1] += a2;
+        }
+    }
+    else
+    {
+        for(m=0; m<NFILTER; m+=dec_rate) {
+            c1 = *coeffPtr;
+
+            m1 = inpCmplx[0];
+            m2 = inpCmplx[1];
+
+            inpCmplx+= dec_rate*2;
+            coeffPtr+= dec_rate;
+
+            a1 = c1 * m1;
+            a2 = c1 * m2;
+            acc[0] += a1;
+            acc[1] += a2;
+        }
+    }
+    acc[0] *= dec_rate;
+    acc[1] *= dec_rate;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: down_convert_and_rx_filter()
+  AUTHOR......: David Rowe
+  DATE CREATED: 30/6/2014
+
+  Combined down convert and rx filter, more memory efficient but less
+  intuitive design.
+
+  Depending on the number of input samples to the demod nin, we
+  produce P-1, P (usually), or P+1 filtered samples at rate P.  nin is
+  occasionally adjusted to compensate for timing slips due to
+  different tx and rx sample clocks.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+   TODO: [ ] windback phase calculated once at init time
+*/
+
+void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
+                                COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[],
+                                float freq_pol[], int nin, int dec_rate)
+{
+    int i,k,c,st,Nval;
+    float windback_phase, mag;
+    COMP  windback_phase_rect;
+    COMP  rx_baseband[NFILTER+M_FAC];
+    COMP  f_rect;
+
+    //PROFILE_VAR(windback_start,  downconvert_start, filter_start);
+
+    /* update memory of rx_fdm */
+
+#if 0
+    for(i=0; i<NFILTER+M_FAC-nin; i++)
+        rx_fdm_mem[i] = rx_fdm_mem[i+nin];
+    for(i=NFILTER+M_FAC-nin, k=0; i<NFILTER+M_FAC; i++, k++)
+        rx_fdm_mem[i] = rx_fdm[k];
+#else
+    // this gives only 40uS gain on STM32 but now that we have, we keep it
+    memmove(&rx_fdm_mem[0],&rx_fdm_mem[nin],(NFILTER+M_FAC-nin)*sizeof(COMP));
+    memcpy(&rx_fdm_mem[NFILTER+M_FAC-nin],&rx_fdm[0],nin*sizeof(COMP));
+#endif
+    for(c=0; c<Nc+1; c++) {
+
+        /*
+          now downconvert using current freq offset to get Nfilter+nin
+          baseband samples.
+
+                     Nfilter             nin
+          |--------------------------|---------|
+                                      |
+                                  phase_rx(c)
+
+          This means winding phase(c) back from this point to ensure
+          phase continuity.
+         */
+
+        //PROFILE_SAMPLE(windback_start);
+        windback_phase           = -freq_pol[c]*NFILTER;
+        windback_phase_rect.real = COSF(windback_phase);
+        windback_phase_rect.imag = SINF(windback_phase);
+        phase_rx[c]              = cmult(phase_rx[c],windback_phase_rect);
+        //PROFILE_SAMPLE_AND_LOG(downconvert_start, windback_start, "        windback");
+
+        /* down convert all samples in buffer */
+
+        st  = NFILTER+M_FAC-1;    /* end of buffer                  */
+        st -= nin-1;          /* first new sample               */
+        st -= NFILTER;        /* first sample used in filtering */
+
+        /* freq shift per dec_rate step is dec_rate times original shift */
+
+        f_rect = freq[c];
+        for(i=0; i<dec_rate-1; i++)
+            f_rect = cmult(f_rect,freq[c]);
+
+        for(i=st; i<NFILTER+M_FAC; i+=dec_rate) {
+            phase_rx[c]    = cmult(phase_rx[c], f_rect);
+            rx_baseband[i] = cmult(rx_fdm_mem[i],cconj(phase_rx[c]));
+        }
+        //PROFILE_SAMPLE_AND_LOG(filter_start, downconvert_start, "        downconvert");
+
+        /* now we can filter this carrier's P symbols */
+
+        Nval=M_FAC/P;
+        for(i=0, k=0; i<nin; i+=Nval, k++) {
+#ifdef ORIG
+            rx_filt[c][k].real = 0.0; rx_filt[c][k].imag = 0.0;
+
+            for(m=0; m<NFILTER; m++)
+                rx_filt[c][k] = cadd(rx_filt[c][k], fcmult(gt_alpha5_root[m], rx_baseband[st+i+m]));
+#else
+            // rx_filt[c][k].real = fir_filter(&rx_baseband[st+i].real, (float*)gt_alpha5_root, dec_rate);
+            // rx_filt[c][k].imag = fir_filter(&rx_baseband[st+i].imag, (float*)gt_alpha5_root, dec_rate);
+            fir_filter2(&rx_filt[c][k].real,&rx_baseband[st+i].real, gt_alpha5_root, dec_rate);
+#endif
+        }
+        //PROFILE_SAMPLE_AND_LOG2(filter_start, "        filter");
+
+        /* normalise digital oscilators as the magnitude can drift over time */
+
+        mag = cabsolute(phase_rx[c]);
+       phase_rx[c].real /= mag;
+       phase_rx[c].imag /= mag;
+
+       //printf("phase_rx[%d] = %f %f\n", c, phase_rx[c].real, phase_rx[c].imag);
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: rx_est_timing()
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/4/2012
+
+  Estimate optimum timing offset, re-filter receive symbols at optimum
+  timing estimate.
+
+\*---------------------------------------------------------------------------*/
+
+float rx_est_timing(COMP rx_symbols[],
+                    int  Nc,
+                   COMP rx_filt[NC+1][P+1],
+                   COMP rx_filter_mem_timing[NC+1][NT*P],
+                   float env[],
+                   int nin,
+                    int m)
+{
+    int   c,i,j;
+    int   adjust;
+    COMP  x, phase, freq;
+    float rx_timing, fract, norm_rx_timing;
+    int   low_sample, high_sample;
+
+    /*
+      nin  adjust
+      --------------------------------
+      120  -1 (one less rate P sample)
+      160   0 (nominal)
+      200   1 (one more rate P sample)
+    */
+
+    adjust = P - nin*P/m;
+
+    /* update buffer of NT rate P filtered symbols */
+
+    for(c=0; c<Nc+1; c++)
+       for(i=0,j=P-adjust; i<(NT-1)*P+adjust; i++,j++)
+           rx_filter_mem_timing[c][i] = rx_filter_mem_timing[c][j];
+    for(c=0; c<Nc+1; c++)
+       for(i=(NT-1)*P+adjust,j=0; i<NT*P; i++,j++)
+           rx_filter_mem_timing[c][i] = rx_filt[c][j];
+
+    /* sum envelopes of all carriers */
+
+    for(i=0; i<NT*P; i++) {
+       env[i] = 0.0;
+       for(c=0; c<Nc+1; c++)
+           env[i] += cabsolute(rx_filter_mem_timing[c][i]);
+    }
+
+    /* The envelope has a frequency component at the symbol rate.  The
+       phase of this frequency component indicates the timing.  So work
+       out single DFT at frequency 2*pi/P */
+
+    x.real = 0.0; x.imag = 0.0;
+    freq.real = COSF(2*PI/P);
+    freq.imag = SINF(2*PI/P);
+    phase.real = 1.0;
+    phase.imag = 0.0;
+
+    for(i=0; i<NT*P; i++) {
+       x = cadd(x, fcmult(env[i], phase));
+       phase = cmult(phase, freq);
+    }
+
+    /* Map phase to estimated optimum timing instant at rate P.  The
+       P/4 part was adjusted by experiment, I know not why.... */
+
+    norm_rx_timing = atan2f(x.imag, x.real)/(2*PI);
+    assert(fabsf(norm_rx_timing) < 1.0);
+    //fprintf(stderr,"%f %f norm_rx_timing: %f\n", x.real, x.imag, norm_rx_timing);
+    rx_timing      = norm_rx_timing*P + P/4;
+
+    if (rx_timing > P)
+       rx_timing -= P;
+    if (rx_timing < -P)
+       rx_timing += P;
+
+    /* rx_filter_mem_timing contains Nt*P samples (Nt symbols at rate
+       P), where Nt is odd.  Lets use linear interpolation to resample
+       in the centre of the timing estimation window .*/
+
+    rx_timing  += floorf(NT/2.0)*P;
+    low_sample = floorf(rx_timing);
+    fract = rx_timing - low_sample;
+    high_sample = ceilf(rx_timing);
+
+    //printf("rx_timing: %f low_sample: %d high_sample: %d fract: %f\n", rx_timing, low_sample, high_sample, fract);
+
+    for(c=0; c<Nc+1; c++) {
+        rx_symbols[c] = cadd(fcmult(1.0-fract, rx_filter_mem_timing[c][low_sample-1]), fcmult(fract, rx_filter_mem_timing[c][high_sample-1]));
+        //rx_symbols[c] = rx_filter_mem_timing[c][high_sample];
+    }
+
+    return norm_rx_timing*m;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: qpsk_to_bits()
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/4/2012
+
+  Convert DQPSK symbols back to an array of bits, extracts sync bit
+  from DBPSK pilot, and also uses pilot to estimate fine frequency
+  error.
+
+\*---------------------------------------------------------------------------*/
+
+float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[],
+                   COMP rx_symbols[], int old_qpsk_mapping)
+{
+    int   c;
+    COMP  d;
+    int   msb=0, lsb=0;
+    float ferr, norm;
+
+
+    /* Extra 45 degree clockwise lets us use real and imag axis as
+       decision boundaries. "norm" makes sure the phase subtraction
+       from the previous symbol doesn't affect the amplitude, which
+       leads to sensible scatter plots */
+
+    for(c=0; c<Nc; c++) {
+        norm = 1.0/(cabsolute(prev_rx_symbols[c])+1E-6);
+       phase_difference[c] = cmult(cmult(rx_symbols[c], fcmult(norm,cconj(prev_rx_symbols[c]))), pi_on_4);
+    }
+
+    /* map (Nc,1) DQPSK symbols back into an (1,Nc*Nb) array of bits */
+
+    for (c=0; c<Nc; c++) {
+      d = phase_difference[c];
+      if ((d.real >= 0) && (d.imag >= 0)) {
+          msb = 0; lsb = 0;
+      }
+      if ((d.real < 0) && (d.imag >= 0)) {
+          msb = 0; lsb = 1;
+      }
+      if ((d.real < 0) && (d.imag < 0)) {
+          if (old_qpsk_mapping) {
+              msb = 1; lsb = 0;
+          } else {
+              msb = 1; lsb = 1;
+          }
+      }
+      if ((d.real >= 0) && (d.imag < 0)) {
+          if (old_qpsk_mapping) {
+              msb = 1; lsb = 1;
+          } else {
+              msb = 1; lsb = 0;
+          }
+      }
+      rx_bits[2*c] = msb;
+      rx_bits[2*c+1] = lsb;
+    }
+
+    /* Extract DBPSK encoded Sync bit and fine freq offset estimate */
+
+    norm = 1.0/(cabsolute(prev_rx_symbols[Nc])+1E-6);
+    phase_difference[Nc] = cmult(rx_symbols[Nc], fcmult(norm, cconj(prev_rx_symbols[Nc])));
+    if (phase_difference[Nc].real < 0) {
+      *sync_bit = 1;
+      ferr = phase_difference[Nc].imag*norm;    /* make f_err magnitude insensitive */
+    }
+    else {
+      *sync_bit = 0;
+      ferr = -phase_difference[Nc].imag*norm;
+    }
+
+    /* pilot carrier gets an extra pi/4 rotation to make it consistent
+       with other carriers, as we need it for snr_update and scatter
+       diagram */
+
+    phase_difference[Nc] = cmult(phase_difference[Nc], pi_on_4);
+
+    return ferr;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: snr_update()
+  AUTHOR......: David Rowe
+  DATE CREATED: 17 May 2012
+
+  Given phase differences update estimates of signal and noise levels.
+
+\*---------------------------------------------------------------------------*/
+
+void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[])
+{
+    float s[NC+1];
+    COMP  refl_symbols[NC+1];
+    float n[NC+1];
+    int   c;
+
+
+    /* mag of each symbol is distance from origin, this gives us a
+       vector of mags, one for each carrier. */
+
+    for(c=0; c<Nc+1; c++)
+       s[c] = cabsolute(phase_difference[c]);
+
+    /* signal mag estimate for each carrier is a smoothed version of
+       instantaneous magntitude, this gives us a vector of smoothed
+       mag estimates, one for each carrier. */
+
+    for(c=0; c<Nc+1; c++)
+       sig_est[c] = SNR_COEFF*sig_est[c] + (1.0 - SNR_COEFF)*s[c];
+
+    /* noise mag estimate is distance of current symbol from average
+       location of that symbol.  We reflect all symbols into the first
+       quadrant for convenience. */
+
+    for(c=0; c<Nc+1; c++) {
+       refl_symbols[c].real = fabsf(phase_difference[c].real);
+       refl_symbols[c].imag = fabsf(phase_difference[c].imag);
+       n[c] = cabsolute(cadd(fcmult(sig_est[c], pi_on_4), cneg(refl_symbols[c])));
+    }
+
+    /* noise mag estimate for each carrier is a smoothed version of
+       instantaneous noise mag, this gives us a vector of smoothed
+       noise power estimates, one for each carrier. */
+
+    for(c=0; c<Nc+1; c++)
+       noise_est[c] = SNR_COEFF*noise_est[c] + (1 - SNR_COEFF)*n[c];
+}
+
+// returns number of shorts in error_pattern[], one short per error
+
+int fdmdv_error_pattern_size(struct FDMDV *f) {
+    return f->ntest_bits;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_put_test_bits()
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/4/2012
+
+  Accepts nbits from rx and attempts to sync with test_bits sequence.
+  If sync OK measures bit errors.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_put_test_bits(struct FDMDV *f, int *sync, short error_pattern[],
+                        int *bit_errors, int *ntest_bits, int rx_bits[])
+{
+    int   i,j;
+    float ber;
+    int   bits_per_frame = fdmdv_bits_per_frame(f);
+
+    /* Append to our memory */
+
+    for(i=0,j=bits_per_frame; i<f->ntest_bits-bits_per_frame; i++,j++)
+       f->rx_test_bits_mem[i] = f->rx_test_bits_mem[j];
+    for(i=f->ntest_bits-bits_per_frame,j=0; i<f->ntest_bits; i++,j++)
+       f->rx_test_bits_mem[i] = rx_bits[j];
+
+    /* see how many bit errors we get when checked against test sequence */
+
+    *bit_errors = 0;
+    for(i=0; i<f->ntest_bits; i++) {
+        error_pattern[i] = test_bits[i] ^ f->rx_test_bits_mem[i];
+       *bit_errors += error_pattern[i];
+       //printf("%d %d %d %d\n", i, test_bits[i], f->rx_test_bits_mem[i], test_bits[i] ^ f->rx_test_bits_mem[i]);
+    }
+
+    /* if less than a thresh we are aligned and in sync with test sequence */
+
+    ber = (float)*bit_errors/f->ntest_bits;
+
+    *sync = 0;
+    if (ber < 0.2)
+       *sync = 1;
+
+    *ntest_bits = f->ntest_bits;
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freq_state(()
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/4/2012
+
+  Freq offset state machine.  Moves between coarse and fine states
+  based on BPSK pilot sequence.  Freq offset estimator occasionally
+  makes mistakes when used continuously.  So we use it until we have
+  acquired the BPSK pilot, then switch to a more robust "fine"
+  tracking algorithm.  If we lose sync we switch back to coarse mode
+  for fast re-acquisition of large frequency offsets.
+
+  The sync state is also useful for higher layers to determine when
+  there is valid FDMDV data for decoding.  We want to reliably and
+  quickly get into sync, stay in sync even on fading channels, and
+  fall out of sync quickly if tx stops or it's a false sync.
+
+  In multipath fading channels the BPSK sync carrier may be pushed
+  down in the noise, despite other carriers being at full strength.
+  We want to avoid loss of sync in these cases.
+
+\*---------------------------------------------------------------------------*/
+
+int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem)
+{
+    int next_state, sync, unique_word, i, corr;
+
+    /* look for 6 symbols (120ms) 101010 of sync sequence */
+
+    unique_word = 0;
+    for(i=0; i<NSYNC_MEM-1; i++)
+        sync_mem[i] = sync_mem[i+1];
+    sync_mem[i] = 1 - 2*sync_bit;
+    corr = 0;
+    for(i=0; i<NSYNC_MEM; i++)
+        corr += sync_mem[i]*sync_uw[i];
+    if (abs(corr) == NSYNC_MEM)
+        unique_word = 1;
+    *reliable_sync_bit = (corr == NSYNC_MEM);
+
+    /* iterate state machine */
+
+    next_state = *state;
+    switch(*state) {
+    case 0:
+       if (unique_word) {
+           next_state = 1;
+            *timer = 0;
+        }
+       break;
+    case 1:                   /* tentative sync state         */
+       if (unique_word) {
+            (*timer)++;
+            if (*timer == 25) /* sync has been good for 500ms */
+                next_state = 2;
+        }
+       else
+           next_state = 0;  /* quickly fall out of sync     */
+       break;
+    case 2:                  /* good sync state */
+       if (unique_word == 0) {
+            *timer = 0;
+           next_state = 3;
+        }
+       break;
+    case 3:                  /* tentative bad state, but could be a fade */
+       if (unique_word)
+           next_state = 2;
+       else  {
+            (*timer)++;
+            if (*timer == 50) /* wait for 1000ms in case sync comes back  */
+                next_state = 0;
+        }
+       break;
+    }
+
+    //printf("state: %d next_state: %d uw: %d timer: %d\n", *state, next_state, unique_word, *timer);
+    *state = next_state;
+    if (*state)
+       sync = 1;
+    else
+       sync = 0;
+
+    return sync;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_demod()
+  AUTHOR......: David Rowe
+  DATE CREATED: 26/4/2012
+
+  FDMDV demodulator, take an array of FDMDV_SAMPLES_PER_FRAME
+  modulated samples, returns an array of FDMDV_BITS_PER_FRAME bits,
+  plus the sync bit.
+
+  The input signal is complex to support single sided frequency shifting
+  before the demod input (e.g. fdmdv2 click to tune feature).
+
+  The number of input samples nin will normally be M_FAC ==
+  FDMDV_SAMPLES_PER_FRAME.  However to adjust for differences in
+  transmit and receive sample clocks nin will occasionally be M_FAC-M_FAC/P,
+  or M_FAC+M_FAC/P.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_demod(struct FDMDV *fdmdv, int rx_bits[],
+                int *reliable_sync_bit, COMP rx_fdm[], int *nin)
+{
+    float         foff_coarse, foff_fine;
+    COMP          rx_fdm_fcorr[M_FAC+M_FAC/P];
+    COMP          rx_fdm_filter[M_FAC+M_FAC/P];
+    COMP          rx_fdm_bb[M_FAC+M_FAC/P];
+    COMP          rx_filt[NC+1][P+1];
+    COMP          rx_symbols[NC+1];
+    float         env[NT*P];
+    int           sync_bit;
+    PROFILE_VAR(demod_start, fdmdv_freq_shift_start, down_convert_and_rx_filter_start);
+    PROFILE_VAR(rx_est_timing_start, qpsk_to_bits_start, snr_update_start, freq_state_start);
+
+    /* shift down to complex baseband */
+
+    fdmdv_freq_shift(rx_fdm_bb, rx_fdm, -FDMDV_FCENTRE, &fdmdv->fbb_phase_rx, *nin);
+
+    /* freq offset estimation and correction */
+
+    PROFILE_SAMPLE(demod_start);
+    foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm_bb, *nin, !fdmdv->sync);
+    PROFILE_SAMPLE_AND_LOG(fdmdv_freq_shift_start, demod_start, "    rx_est_freq_offset");
+
+    if (fdmdv->sync == 0)
+       fdmdv->foff = foff_coarse;
+    fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm_bb, -fdmdv->foff, &fdmdv->foff_phase_rect, *nin);
+    PROFILE_SAMPLE_AND_LOG(down_convert_and_rx_filter_start, fdmdv_freq_shift_start, "    fdmdv_freq_shift");
+
+    /* baseband processing */
+
+    rxdec_filter(rx_fdm_filter, rx_fdm_fcorr, fdmdv->rxdec_lpf_mem, *nin);
+    down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_filter, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq,
+                               fdmdv->freq_pol, *nin, M_FAC/Q);
+    PROFILE_SAMPLE_AND_LOG(rx_est_timing_start, down_convert_and_rx_filter_start, "    down_convert_and_rx_filter");
+    fdmdv->rx_timing = rx_est_timing(rx_symbols, fdmdv->Nc, rx_filt, fdmdv->rx_filter_mem_timing, env, *nin, M_FAC);
+    PROFILE_SAMPLE_AND_LOG(qpsk_to_bits_start, rx_est_timing_start, "    rx_est_timing");
+
+    /* Adjust number of input samples to keep timing within bounds */
+
+    *nin = M_FAC;
+
+    if (fdmdv->rx_timing > 2*M_FAC/P)
+       *nin += M_FAC/P;
+
+    if (fdmdv->rx_timing < 0)
+       *nin -= M_FAC/P;
+
+    foff_fine = qpsk_to_bits(rx_bits, &sync_bit, fdmdv->Nc, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols,
+                             fdmdv->old_qpsk_mapping);
+    memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(fdmdv->Nc+1));
+    PROFILE_SAMPLE_AND_LOG(snr_update_start, qpsk_to_bits_start, "    qpsk_to_bits");
+    snr_update(fdmdv->sig_est, fdmdv->noise_est, fdmdv->Nc, fdmdv->phase_difference);
+    PROFILE_SAMPLE_AND_LOG(freq_state_start, snr_update_start, "    snr_update");
+
+    /* freq offset estimation state machine */
+
+    fdmdv->sync = freq_state(reliable_sync_bit, sync_bit, &fdmdv->fest_state, &fdmdv->timer, fdmdv->sync_mem);
+    PROFILE_SAMPLE_AND_LOG2(freq_state_start, "    freq_state");
+    fdmdv->foff  -= TRACK_COEFF*foff_fine;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: calc_snr()
+  AUTHOR......: David Rowe
+  DATE CREATED: 17 May 2012
+
+  Calculate current SNR estimate (3000Hz noise BW)
+
+\*---------------------------------------------------------------------------*/
+
+float calc_snr(int Nc, float sig_est[], float noise_est[])
+{
+    float S, SdB;
+    float mean, N50, N50dB, N3000dB;
+    float snr_dB;
+    int   c;
+
+    S = 0.0;
+    for(c=0; c<Nc+1; c++)
+       S += powf(sig_est[c], 2.0);
+    SdB = 10.0*log10f(S+1E-12);
+
+    /* Average noise mag across all carriers and square to get an
+       average noise power.  This is an estimate of the noise power in
+       Rs = 50Hz of BW (note for raised root cosine filters Rs is the
+       noise BW of the filter) */
+
+    mean = 0.0;
+    for(c=0; c<Nc+1; c++)
+       mean += noise_est[c];
+    mean /= (Nc+1);
+    N50 = powf(mean, 2.0);
+    N50dB = 10.0*log10f(N50+1E-12);
+
+    /* Now multiply by (3000 Hz)/(50 Hz) to find the total noise power
+       in 3000 Hz */
+
+    N3000dB = N50dB + 10.0*log10f(3000.0/RS);
+
+    snr_dB = SdB - N3000dB;
+
+    return snr_dB;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_get_demod_stats()
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 May 2012
+
+  Fills stats structure with a bunch of demod information.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_get_demod_stats(struct FDMDV *fdmdv, struct MODEM_STATS *stats)
+{
+    int   c;
+
+    assert(fdmdv->Nc <= MODEM_STATS_NC_MAX);
+
+    stats->Nc = fdmdv->Nc;
+    stats->snr_est = calc_snr(fdmdv->Nc, fdmdv->sig_est, fdmdv->noise_est);
+    stats->sync = fdmdv->sync;
+    stats->foff = fdmdv->foff;
+    stats->rx_timing = fdmdv->rx_timing;
+    stats->clock_offset = 0.0; /* TODO - implement clock offset estimation */
+
+    stats->nr = 1;
+    for(c=0; c<fdmdv->Nc+1; c++) {
+       stats->rx_symbols[0][c] = fdmdv->phase_difference[c];
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_8_to_16()
+  AUTHOR......: David Rowe
+  DATE CREATED: 9 May 2012
+
+  Changes the sample rate of a signal from 8 to 16 kHz.  Support function for
+  SM1000.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_8_to_16(float out16k[], float in8k[], int n)
+{
+    int i,k,l;
+    float acc;
+
+    /* make sure n is an integer multiple of the oversampling rate, ow
+       this function breaks */
+
+    assert((n % FDMDV_OS) == 0);
+
+    /* this version unrolled for specific FDMDV_OS */
+
+    assert(FDMDV_OS == 2);
+
+    for(i=0; i<n; i++) {
+        acc = 0.0;
+        for(k=0,l=0; k<FDMDV_OS_TAPS_16K; k+=FDMDV_OS,l++)
+            acc += fdmdv_os_filter[k]*in8k[i-l];
+        out16k[i*FDMDV_OS] = FDMDV_OS*acc;
+
+        acc = 0.0;
+        for(k=1,l=0; k<FDMDV_OS_TAPS_16K; k+=FDMDV_OS,l++)
+            acc += fdmdv_os_filter[k]*in8k[i-l];
+        out16k[i*FDMDV_OS+1] = FDMDV_OS*acc;
+    }
+
+    /* update filter memory */
+
+    for(i=-(FDMDV_OS_TAPS_8K); i<0; i++)
+       in8k[i] = in8k[i + n];
+
+}
+
+void fdmdv_8_to_16_short(short out16k[], short in8k[], int n)
+{
+    int i,k,l;
+    float acc;
+
+    /* make sure n is an integer multiple of the oversampling rate, ow
+       this function breaks */
+
+    assert((n % FDMDV_OS) == 0);
+
+    /* this version unrolled for specific FDMDV_OS */
+
+    assert(FDMDV_OS == 2);
+
+    for(i=0; i<n; i++) {
+        acc = 0.0;
+        for(k=0,l=0; k<FDMDV_OS_TAPS_16K; k+=FDMDV_OS,l++)
+            acc += fdmdv_os_filter[k]*(float)in8k[i-l];
+        out16k[i*FDMDV_OS] = FDMDV_OS*acc;
+
+        acc = 0.0;
+        for(k=1,l=0; k<FDMDV_OS_TAPS_16K; k+=FDMDV_OS,l++)
+            acc += fdmdv_os_filter[k]*(float)in8k[i-l];
+        out16k[i*FDMDV_OS+1] = FDMDV_OS*acc;
+    }
+
+    /* update filter memory */
+
+    for(i=-(FDMDV_OS_TAPS_8K); i<0; i++)
+       in8k[i] = in8k[i + n];
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_16_to_8()
+  AUTHOR......: David Rowe
+  DATE CREATED: 9 May 2012
+
+  Changes the sample rate of a signal from 16 to 8 kHz.
+
+  n is the number of samples at the 8 kHz rate, there are FDMDV_OS*n
+  samples at the 48 kHz rate.  As above however a memory of
+  FDMDV_OS_TAPS samples is reqd for in16k[] (see t16_8.c unit test as example).
+
+  Low pass filter the 16 kHz signal at 4 kHz using the same filter as
+  the upsampler, then just output every FDMDV_OS-th filtered sample.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_16_to_8(float out8k[], float in16k[], int n)
+{
+    float acc;
+    int   i,j,k;
+
+    for(i=0, k=0; k<n; i+=FDMDV_OS, k++) {
+       acc = 0.0;
+       for(j=0; j<FDMDV_OS_TAPS_16K; j++)
+           acc += fdmdv_os_filter[j]*in16k[i-j];
+        out8k[k] = acc;
+    }
+
+    /* update filter memory */
+
+    for(i=-FDMDV_OS_TAPS_16K; i<0; i++)
+       in16k[i] = in16k[i + n*FDMDV_OS];
+}
+
+void fdmdv_16_to_8_short(short out8k[], short in16k[], int n)
+{
+    float acc;
+    int i,j,k;
+
+    for(i=0, k=0; k<n; i+=FDMDV_OS, k++) {
+       acc = 0.0;
+       for(j=0; j<FDMDV_OS_TAPS_16K; j++)
+           acc += fdmdv_os_filter[j]*(float)in16k[i-j];
+        out8k[k] = acc;
+    }
+
+    /* update filter memory */
+
+    for(i=-FDMDV_OS_TAPS_16K; i<0; i++)
+       in16k[i] = in16k[i + n*FDMDV_OS];
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  Function used during development to test if magnitude of digital
+  oscillators was drifting.  It was!
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_dump_osc_mags(struct FDMDV *f)
+{
+    int   i;
+
+    fprintf(stderr, "phase_tx[]:\n");
+    for(i=0; i<=f->Nc; i++)
+       fprintf(stderr,"  %1.3f", (double)cabsolute(f->phase_tx[i]));
+    fprintf(stderr,"\nfreq[]:\n");
+    for(i=0; i<=f->Nc; i++)
+       fprintf(stderr,"  %1.3f", (double)cabsolute(f->freq[i]));
+    fprintf(stderr,"\nfoff_phase_rect: %1.3f", (double)cabsolute(f->foff_phase_rect));
+    fprintf(stderr,"\nphase_rx[]:\n");
+    for(i=0; i<=f->Nc; i++)
+       fprintf(stderr,"  %1.3f", (double)cabsolute(f->phase_rx[i]));
+    fprintf(stderr, "\n\n");
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: randn()
+  AUTHOR......: David Rowe
+  DATE CREATED: 2 August 2014
+
+  Simple approximation to normal (gaussian) random number generator
+  with 0 mean and unit variance.
+
+\*---------------------------------------------------------------------------*/
+
+#define RANDN_IT 12  /* This magic number of iterations gives us a
+                        unit variance.  I think beacuse var =
+                        (b-a)^2/12 for one uniform random variable, so
+                        for a sum of n random variables it's
+                        n(b-a)^2/12, or for b=1, a = 0, n=12, we get
+                        var = 12(1-0)^2/12 = 1 */
+
+static float randn() {
+    int   i;
+    float rn = 0.0;
+
+    for(i=0; i<RANDN_IT; i++)
+        rn += (float)rand()/RAND_MAX;
+
+    rn -= (float)RANDN_IT/2.0;
+    return rn;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_simulate_channel()
+  AUTHOR......: David Rowe
+  DATE CREATED: 10 July 2014
+
+  Simple channel simulation function to aid in testing.  Target SNR
+  uses noise measured in a 3 kHz bandwidth.
+
+  Doesn't use fdmdv states so can be called from anywhere, e.g. non
+  fdmdv applications.
+
+  TODO: Measured SNR is coming out a few dB higher than target_snr, this
+  needs to be fixed.
+
+\*---------------------------------------------------------------------------*/
+
+void fdmdv_simulate_channel(float *sig_pwr_av, COMP samples[], int nin, float target_snr)
+{
+    float sig_pwr, target_snr_linear, noise_pwr, noise_pwr_1Hz, noise_pwr_4000Hz, noise_gain;
+    int   i;
+
+    /* estimate signal power */
+
+    sig_pwr = 0.0;
+    for(i=0; i<nin; i++)
+        sig_pwr += samples[i].real*samples[i].real + samples[i].imag*samples[i].imag;
+
+    sig_pwr /= nin;
+
+    *sig_pwr_av = 0.9**sig_pwr_av + 0.1*sig_pwr;
+
+    /* det noise to meet target SNR */
+
+    target_snr_linear = powf(10.0, target_snr/10.0);
+    noise_pwr = *sig_pwr_av/target_snr_linear;       /* noise pwr in a 3000 Hz BW     */
+    noise_pwr_1Hz = noise_pwr/3000.0;                  /* noise pwr in a 1 Hz bandwidth */
+    noise_pwr_4000Hz = noise_pwr_1Hz*4000.0;           /* noise pwr in a 4000 Hz BW, which
+                                                          due to fs=8000 Hz in our simulation noise BW */
+
+    noise_gain = sqrtf(0.5*noise_pwr_4000Hz);          /* split noise pwr between real and imag sides  */
+
+    for(i=0; i<nin; i++) {
+        samples[i].real += noise_gain*randn();
+        samples[i].imag += noise_gain*randn();
+    }
+    /*
+    fprintf(stderr, "sig_pwr: %f f->sig_pwr_av: %e target_snr_linear: %f noise_pwr_4000Hz: %e noise_gain: %e\n",
+            sig_pwr, f->sig_pwr_av, target_snr_linear, noise_pwr_4000Hz, noise_gain);
+    */
+}
diff --git a/codec2/branches/0.7/src/fdmdv_channel.c b/codec2/branches/0.7/src/fdmdv_channel.c
new file mode 100644 (file)
index 0000000..d3d82b3
--- /dev/null
@@ -0,0 +1,104 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_channel.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 2 August 2014
+
+  Given an input raw file (8kHz, 16 bit shorts) of FDMDV modem
+  samples, adds channel impairments and outputs to another raw file.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_fdmdv.h"
+#include "fdmdv_internal.h"
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin, *fout;
+    short         rx_fdm_buf[FDMDV_NOM_SAMPLES_PER_FRAME];
+    COMP          rx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME];
+    struct FDMDV *fdmdv;
+    float         snrdB, sam;
+    int           i;
+
+    if (argc < 3) {
+       printf("usage: %s InputModemRawFile OutputModemRawFile SNRdB\n", argv[0]);
+       printf("e.g    %s test_in.raw test_out.raw 4\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input modem sample 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);
+    }
+
+    snrdB = atof(argv[3]);
+    fdmdv = fdmdv_create(FDMDV_NC);
+
+    while(fread(rx_fdm_buf, sizeof(short), FDMDV_NOM_SAMPLES_PER_FRAME, fin) == FDMDV_NOM_SAMPLES_PER_FRAME) {
+
+       for(i=0; i<FDMDV_NOM_SAMPLES_PER_FRAME; i++) {
+           rx_fdm[i].real = (float)rx_fdm_buf[i]/FDMDV_SCALE;
+            rx_fdm[i].imag = 0.0;
+        }
+
+        /* real signal so we adjust SNR to suit.  I think.  I always get confused by this! */
+
+        fdmdv_simulate_channel(&fdmdv->sig_pwr_av, rx_fdm, FDMDV_NOM_SAMPLES_PER_FRAME, snrdB - 3.0);
+
+       for(i=0; i<FDMDV_NOM_SAMPLES_PER_FRAME; i++) {
+           sam = FDMDV_SCALE*rx_fdm[i].real;
+            if (sam >  32767.0) sam =  32767.0;
+            if (sam < -32767.0) sam = -32767.0;
+            rx_fdm_buf[i] = sam;
+        }
+
+        fwrite(rx_fdm_buf, sizeof(short), FDMDV_NOM_SAMPLES_PER_FRAME, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    fclose(fin);
+    fclose(fout);
+    fdmdv_destroy(fdmdv);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/fdmdv_demod.c b/codec2/branches/0.7/src/fdmdv_demod.c
new file mode 100644 (file)
index 0000000..3f0d1e2
--- /dev/null
@@ -0,0 +1,246 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_demod.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 30 2012
+
+  Given an input raw file (8kHz, 16 bit shorts) of FDMDV modem samples
+  outputs a file of bits.  The output file is assumed to be arranged
+  as codec frames of 56 bits (7 bytes) which are received as two 28
+  bit modem frames.
+
+  Demod states can be optionally logged to an Octave file for display
+  using the Octave script fdmdv_demod_c.m.  This is useful for
+  checking demod performance.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_fdmdv.h"
+#include "octave.h"
+#include "freedv_api.h"
+
+/* lof of information we want to dump to Octave */
+
+#define MAX_FRAMES 50*60 /* 1 minute at 50 symbols/s */
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin, *fout;
+    struct FDMDV *fdmdv;
+    char         *packed_bits;
+    int          *rx_bits;
+    int          *codec_bits;
+    COMP          rx_fdm[FDMDV_MAX_SAMPLES_PER_FRAME];
+    short         rx_fdm_scaled[FDMDV_MAX_SAMPLES_PER_FRAME];
+    int           i, bit, byte, c;
+    int           nin, nin_prev;
+    int           sync_bit = 0, reliable_sync_bit;
+    int           sync = 0;
+    int           f;
+    FILE         *foct = NULL;
+    struct MODEM_STATS stats;
+    COMP         *rx_fdm_log;
+    int           rx_fdm_log_col_index;
+    COMP         *rx_symbols_log;
+    int           sync_log[MAX_FRAMES];
+    float         rx_timing_log[MAX_FRAMES];
+    float         foff_log[MAX_FRAMES];
+    int           sync_bit_log[MAX_FRAMES];
+    int           rx_bits_log[FDMDV_BITS_PER_FRAME*MAX_FRAMES];
+    float         snr_est_log[MAX_FRAMES];
+    float        *rx_spec_log;
+    int           max_frames_reached;
+    int           bits_per_fdmdv_frame;
+    int           bits_per_codec_frame;
+    int           bytes_per_codec_frame;
+    int           Nc;
+
+    if (argc < 2) {
+       printf("usage: %s InputModemRawFile OutputBitFile [Nc [OctaveDumpFile]]\n", argv[0]);
+       printf("e.g    %s hts1a_fdmdv.raw hts1a.c2\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input modem sample 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 bit file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (argc >= 4) {
+        Nc = atoi(argv[3]);
+
+        if ((Nc < 2) || (Nc > FDMDV_NC_MAX) ) {
+            fprintf(stderr, "Error number of carriers must be between 2 and %d\n",  FDMDV_NC_MAX);
+            exit(1);
+        }
+    }
+    else
+        Nc = FDMDV_NC;
+
+    fdmdv = fdmdv_create(Nc);
+    modem_stats_open(&stats);
+
+    bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);
+    bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    bytes_per_codec_frame = (bits_per_codec_frame+7)/8;
+
+    /* malloc some buffers that are dependant on Nc */
+
+    packed_bits = (char*)malloc(bytes_per_codec_frame); assert(packed_bits != NULL);
+    rx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame); assert(rx_bits != NULL);
+    codec_bits = (int*)malloc(2*sizeof(int)*bits_per_fdmdv_frame); assert(codec_bits != NULL);
+
+    /* malloc some of the larger variables to prevent out of stack problems */
+
+    rx_fdm_log = (COMP*)malloc(sizeof(COMP)*FDMDV_MAX_SAMPLES_PER_FRAME*MAX_FRAMES);
+    assert(rx_fdm_log != NULL);
+    rx_spec_log = (float*)malloc(sizeof(float)*MODEM_STATS_NSPEC*MAX_FRAMES);
+    assert(rx_spec_log != NULL);
+    rx_symbols_log = (COMP*)malloc(sizeof(COMP)*(Nc+1)*MAX_FRAMES);
+    assert(rx_fdm_log != NULL);
+
+    f = 0;
+    nin = FDMDV_NOM_SAMPLES_PER_FRAME;
+    rx_fdm_log_col_index = 0;
+    max_frames_reached = 0;
+
+    while(fread(rx_fdm_scaled, sizeof(short), nin, fin) == nin)
+    {
+       for(i=0; i<nin; i++) {
+           rx_fdm[i].real = (float)rx_fdm_scaled[i]/FDMDV_SCALE;
+            rx_fdm[i].imag = 0;
+        }
+       nin_prev = nin;
+       fdmdv_demod(fdmdv, rx_bits, &reliable_sync_bit, rx_fdm, &nin);
+
+       /* log data for optional Octave dump */
+
+       if (f < MAX_FRAMES) {
+           fdmdv_get_demod_stats(fdmdv, &stats);
+
+           /* log modem states for later dumping to Octave log file */
+
+           memcpy(&rx_fdm_log[rx_fdm_log_col_index], rx_fdm, sizeof(COMP)*nin_prev);
+           rx_fdm_log_col_index += nin_prev;
+
+           for(c=0; c<Nc+1; c++)
+               rx_symbols_log[f*(Nc+1)+c] = stats.rx_symbols[0][c];
+           foff_log[f] = stats.foff;
+           rx_timing_log[f] = stats.rx_timing;
+           sync_log[f] = stats.sync;
+           sync_bit_log[f] = sync_bit;
+           memcpy(&rx_bits_log[bits_per_fdmdv_frame*f], rx_bits, sizeof(int)*bits_per_fdmdv_frame);
+           snr_est_log[f] = stats.snr_est;
+
+           modem_stats_get_rx_spectrum(&stats, &rx_spec_log[f*MODEM_STATS_NSPEC], rx_fdm, nin_prev);
+
+           f++;
+       }
+
+       if ((f == MAX_FRAMES) && !max_frames_reached) {
+           fprintf(stderr,"MAX_FRAMES exceed in Octave log, log truncated\n");
+           max_frames_reached = 1;
+       }
+
+        if (reliable_sync_bit)
+            sync = 1;
+        //printf("sync_bit: %d reliable_sync_bit: %d sync: %d\n", sync_bit, reliable_sync_bit, sync);
+
+        if (sync == 0) {
+            memcpy(codec_bits, rx_bits, bits_per_fdmdv_frame*sizeof(int));
+            sync = 1;
+        }
+        else {
+            memcpy(&codec_bits[bits_per_fdmdv_frame], rx_bits, bits_per_fdmdv_frame*sizeof(int));
+
+            /* pack bits, MSB received first  */
+
+            bit = 7; byte = 0;
+            memset(packed_bits, 0, bytes_per_codec_frame);
+            for(i=0; i<bits_per_codec_frame; i++) {
+                packed_bits[byte] |= (codec_bits[i] << bit);
+                bit--;
+                if (bit < 0) {
+                    bit = 7;
+                    byte++;
+                }
+            }
+
+            fwrite(packed_bits, sizeof(char), bytes_per_codec_frame, fout);
+            sync = 0;
+        }
+
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    /* Optional dump to Octave log file */
+
+    if (argc == 5) {
+
+       if ((foct = fopen(argv[4],"wt")) == NULL ) {
+           fprintf(stderr, "Error opening Octave dump file: %s: %s.\n",
+               argv[4], strerror(errno));
+           exit(1);
+       }
+       octave_save_complex(foct, "rx_fdm_log_c", rx_fdm_log, 1, rx_fdm_log_col_index, FDMDV_MAX_SAMPLES_PER_FRAME);
+       octave_save_complex(foct, "rx_symbols_log_c", (COMP*)rx_symbols_log, Nc+1, f, MAX_FRAMES);
+       octave_save_float(foct, "foff_log_c", foff_log, 1, f, MAX_FRAMES);
+       octave_save_float(foct, "rx_timing_log_c", rx_timing_log, 1, f, MAX_FRAMES);
+       octave_save_int(foct, "sync_log_c", sync_log, 1, f);
+       octave_save_int(foct, "rx_bits_log_c", rx_bits_log, 1, bits_per_fdmdv_frame*f);
+       octave_save_int(foct, "sync_bit_log_c", sync_bit_log, 1, f);
+       octave_save_float(foct, "snr_est_log_c", snr_est_log, 1, f, MAX_FRAMES);
+       octave_save_float(foct, "rx_spec_log_c", rx_spec_log, f, MODEM_STATS_NSPEC, MODEM_STATS_NSPEC);
+       fclose(foct);
+    }
+
+    //fdmdv_dump_osc_mags(fdmdv);
+
+    fclose(fin);
+    fclose(fout);
+    free(rx_fdm_log);
+    free(rx_spec_log);
+    fdmdv_destroy(fdmdv);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/fdmdv_get_test_bits.c b/codec2/branches/0.7/src/fdmdv_get_test_bits.c
new file mode 100644 (file)
index 0000000..043bc10
--- /dev/null
@@ -0,0 +1,124 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_get_test_bits.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 May 2012
+
+  Generates a file of packed test bits, useful for input to fdmdv_mod.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_fdmdv.h"
+
+int main(int argc, char *argv[])
+{
+    FILE         *fout;
+    struct FDMDV *fdmdv;
+    char          *packed_bits;
+    int           *tx_bits;
+    int           n, i, bit, byte;
+    int           numBits, nCodecFrames;
+    int           bits_per_fdmdv_frame;
+    int           bits_per_codec_frame;
+    int           bytes_per_codec_frame;
+    int           Nc;
+
+    if (argc < 3) {
+       printf("usage: %s OutputBitFile numBits [Nc]\n", argv[0]);
+       printf("e.g    %s test.c2 1400\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[1],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output bit file: %s: %s.\n",
+         argv[1], strerror(errno));
+       exit(1);
+    }
+
+    numBits = atoi(argv[2]);
+
+    if (argc == 4) {
+        Nc = atoi(argv[3]);
+        if ((Nc < 2) || (Nc > FDMDV_NC_MAX) ) {
+            fprintf(stderr, "Error number of carriers must be btween 2 and %d\n",  FDMDV_NC_MAX);
+            exit(1);
+        }
+    }
+    else
+        Nc = FDMDV_NC;
+
+    fdmdv = fdmdv_create(Nc);
+
+    bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);
+    bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    bytes_per_codec_frame = (bits_per_codec_frame+7)/8;
+    fprintf(stderr, "bits_per_fdmdv_frame: %d bits_per_codec_frame: %d bytes_per_codec_frame: %d\n",
+            bits_per_fdmdv_frame, bits_per_codec_frame, bytes_per_codec_frame);
+
+    packed_bits = (char*)malloc(bytes_per_codec_frame);
+    assert(packed_bits != NULL);
+    tx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame);
+    assert(tx_bits != NULL);
+
+    nCodecFrames = numBits/bits_per_codec_frame;
+
+    for(n=0; n<nCodecFrames; n++) {
+
+       fdmdv_get_test_bits(fdmdv, tx_bits);
+       fdmdv_get_test_bits(fdmdv, &tx_bits[bits_per_fdmdv_frame]);
+
+       /* pack bits, MSB received first  */
+
+       bit = 7; byte = 0;
+       memset(packed_bits, 0, bytes_per_codec_frame);
+       for(i=0; i<bits_per_codec_frame; i++) {
+           packed_bits[byte] |= (tx_bits[i] << bit);
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+
+       fwrite(packed_bits, sizeof(char), bytes_per_codec_frame, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+    }
+
+    free(tx_bits);
+    free(packed_bits);
+    fclose(fout);
+    fdmdv_destroy(fdmdv);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/fdmdv_interleave.c b/codec2/branches/0.7/src/fdmdv_interleave.c
new file mode 100644 (file)
index 0000000..ffefb82
--- /dev/null
@@ -0,0 +1,164 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_interleave.c
+  AUTHOR......: David Rowe
+  DATE CREATED: May 27 2012
+
+  Given an input file of bits outputs an interleaved or optionally
+  de-intervleaved file of bits.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_fdmdv.h"
+
+#define MAX_INTERLEAVER 10000
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin, *fout, *finter;
+    int          interleaver[MAX_INTERLEAVER];
+    char         *packed_bits;
+    int          *bits;
+    int          *interleaved_bits;
+    int           i, bit, byte, m, mpacked, frames, interleave, src_bit, dest_bit;
+
+    if (argc < 4) {
+       printf("usage: %s InputBitFile OutputBitFile InterleaverFile [de]\n", argv[0]);
+       printf("e.g    %s hts1a.c2 hts1a_interleaved.c2 interleaver.txt\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input bit 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 bit file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if ((finter = fopen(argv[3],"rt")) == NULL ) {
+       fprintf(stderr, "Error opening interleaver file: %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    if (argc == 5)
+       interleave = 1;
+    else
+       interleave = 0;
+
+    /* load interleaver, size determines block size we will process */
+
+    src_bit = 0;
+    while(fscanf(finter, "%d\n", &dest_bit) == 1) {
+       if (interleave)
+           interleaver[dest_bit] = src_bit;
+       else
+           interleaver[src_bit] = dest_bit;
+
+       src_bit++;
+       if (src_bit == MAX_INTERLEAVER) {
+           fprintf(stderr, "Error interleaver too big\n");
+           exit(1);
+       }
+    }
+    fclose(finter);
+
+    m = src_bit;
+    fprintf(stderr, "Interleaver size m = %d  interleave = %d\n", m, interleave);
+    assert((m%8) == 0);
+    mpacked = m/8;
+
+    packed_bits = (char*)malloc(mpacked*sizeof(char));
+    assert(packed_bits != NULL);
+    bits = (int*)malloc(m*sizeof(int));
+    assert(bits != NULL);
+    interleaved_bits = (int*)malloc(m*sizeof(int));
+    assert(interleaved_bits != NULL);
+
+    frames = 0;
+
+    while(fread(packed_bits, sizeof(char), mpacked, fin) == mpacked) {
+       frames++;
+
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<m; i++) {
+           bits[i] = (packed_bits[byte] >> bit) & 0x1;
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+       assert(byte == mpacked);
+
+       /* (de) interleave */
+
+       for(i=0; i<m; i++)
+           interleaved_bits[i] = bits[interleaver[i]];
+
+       /* pack bits, MSB sent first  */
+
+       bit = 7; byte = 0;
+       memset(packed_bits, 0, mpacked);
+       for(i=0; i<m; i++) {
+           packed_bits[byte] |= (interleaved_bits[i] << bit);
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+       assert(byte == mpacked);
+
+       fwrite(packed_bits, sizeof(char), mpacked, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    free(packed_bits);
+    free(bits);
+    free(interleaved_bits);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/fdmdv_internal.h b/codec2/branches/0.7/src/fdmdv_internal.h
new file mode 100644 (file)
index 0000000..3f830ba
--- /dev/null
@@ -0,0 +1,192 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_internal.h
+  AUTHOR......: David Rowe
+  DATE CREATED: April 16 2012
+
+  Header file for FDMDV internal functions, exposed via this header
+  file for testing.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __FDMDV_INTERNAL__
+#define __FDMDV_INTERNAL__
+
+#include "comp.h"
+#include "codec2_fdmdv.h"
+#include "codec2_fft.h"
+
+/*---------------------------------------------------------------------------*\
+
+                               DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef PI
+#define PI             3.141592654
+#endif
+#define FS                    8000  /* sample rate in Hz                                                    */
+#define T                 (1.0/FS)  /* sample period in seconds                                             */
+#define RS                      50  /* symbol rate in Hz                                                    */
+#define NC                      20  /* max number of data carriers (plus one pilot in the centre)           */
+#define NB                       2  /* Bits/symbol for QPSK modulation                                      */
+#define RB              (NC*RS*NB)  /* bit rate                                                             */
+#define M_FAC                  (FS/RS)  /* oversampling factor                                                  */
+#define NSYM                     6  /* number of symbols to filter over                                     */
+#define NFILTER            (NSYM*M_FAC) /* size of tx/rx filters at sample rate M                               */
+
+#define FSEP                    75  /* Default separation between carriers (Hz)                             */
+
+#define NT                       5  /* number of symbols we estimate timing over                            */
+#define P                        4  /* oversample factor used for initial rx symbol filtering output        */
+#define Q                     (M_FAC/4) /* oversample factor used for initial rx symbol filtering input         */
+#define NRXDEC                  31  /* number of taps in the rx decimation filter                           */
+
+#define NPILOT_LUT                 (4*M_FAC)    /* number of pilot look up table samples                 */
+#define NPILOTCOEFF                   30    /* number of FIR filter coeffs in LP filter              */
+#define NPILOTBASEBAND (NPILOTCOEFF+M_FAC+M_FAC/P)  /* number of pilot baseband samples reqd for pilot LPF   */
+#define NPILOTLPF                  (4*M_FAC)    /* number of samples we DFT pilot over, pilot est window */
+#define MPILOTFFT                    256
+
+#define NSYNC_MEM                6
+
+/* averaging filter coeffs */
+
+#define TRACK_COEFF              0.5
+#define SNR_COEFF                0.9       /* SNR est averaging filter coeff */
+
+/*---------------------------------------------------------------------------*\
+
+                               STRUCT for States
+
+\*---------------------------------------------------------------------------*/
+
+struct FDMDV {
+
+    int   Nc;
+    float fsep;
+
+    /* test data (test frame) states */
+
+    int  ntest_bits;
+    int  current_test_bit;
+    int *rx_test_bits_mem;
+
+    /* Modulator */
+
+    int   old_qpsk_mapping;
+    int   tx_pilot_bit;
+    COMP  prev_tx_symbols[NC+1];
+    COMP  tx_filter_memory[NC+1][NSYM];
+    COMP  phase_tx[NC+1];
+    COMP  freq[NC+1];
+    float freq_pol[NC+1];
+
+    /* Pilot generation at demodulator */
+
+    COMP pilot_lut[NPILOT_LUT];
+    int  pilot_lut_index;
+    int  prev_pilot_lut_index;
+
+    /* freq offset estimation states */
+
+    codec2_fft_cfg fft_pilot_cfg;
+    COMP pilot_baseband1[NPILOTBASEBAND];
+    COMP pilot_baseband2[NPILOTBASEBAND];
+    COMP pilot_lpf1[NPILOTLPF];
+    COMP pilot_lpf2[NPILOTLPF];
+    COMP S1[MPILOTFFT];
+    COMP S2[MPILOTFFT];
+
+    /* baseband to low IF carrier states */
+
+    COMP  fbb_rect;
+    float fbb_pol;
+    COMP  fbb_phase_tx;
+    COMP  fbb_phase_rx;
+
+    /* freq offset correction states */
+
+    float foff;
+    COMP foff_phase_rect;
+    float foff_filt;
+
+    /* Demodulator */
+
+    COMP  rxdec_lpf_mem[NRXDEC-1+M_FAC];
+    COMP  rx_fdm_mem[NFILTER+M_FAC];
+    COMP  phase_rx[NC+1];
+    COMP  rx_filter_mem_timing[NC+1][NT*P];
+    float rx_timing;
+    COMP  phase_difference[NC+1];
+    COMP  prev_rx_symbols[NC+1];
+
+    /* sync state machine */
+
+    int  sync_mem[NSYNC_MEM];
+    int  fest_state;
+    int  sync;
+    int  timer;
+
+    /* SNR estimation states */
+
+    float sig_est[NC+1];
+    float noise_est[NC+1];
+
+    /* channel simulation */
+
+    float sig_pwr_av;
+};
+
+/*---------------------------------------------------------------------------*\
+
+                              FUNCTION PROTOTYPES
+
+\*---------------------------------------------------------------------------*/
+
+void bits_to_dqpsk_symbols(COMP tx_symbols[], int Nc, COMP prev_tx_symbols[], int tx_bits[], int *pilot_bit, int old_qpsk_mapping);
+void tx_filter(COMP tx_baseband[NC+1][M_FAC], int Nc, COMP tx_symbols[], COMP tx_filter_memory[NC+1][NSYM]);
+void fdm_upconvert(COMP tx_fdm[], int Nc, COMP tx_baseband[NC+1][M_FAC], COMP phase_tx[], COMP freq_tx[],
+                   COMP *fbb_phase, COMP fbb_rect);
+void tx_filter_and_upconvert(COMP tx_fdm[], int Nc, COMP tx_symbols[],
+                             COMP tx_filter_memory[NC+1][NSYM],
+                             COMP phase_tx[], COMP freq[], COMP *fbb_phase, COMP fbb_rect);
+void generate_pilot_fdm(COMP *pilot_fdm, int *bit, float *symbol, float *filter_mem, COMP *phase, COMP *freq);
+void generate_pilot_lut(COMP pilot_lut[], COMP *pilot_freq);
+float rx_est_freq_offset(struct FDMDV *f, COMP rx_fdm[], int nin, int do_fft);
+void lpf_peak_pick(float *foff, float *max, COMP pilot_baseband[], COMP pilot_lpf[], codec2_fft_cfg fft_pilot_cfg, COMP S[], int nin, int do_fft);
+void fdm_downconvert(COMP rx_baseband[NC+1][M_FAC+M_FAC/P], int Nc, COMP rx_fdm[], COMP phase_rx[], COMP freq[], int nin);
+void rxdec_filter(COMP rx_fdm_filter[], COMP rx_fdm[], COMP rxdec_lpf_mem[], int nin);
+void rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_baseband[NC+1][M_FAC+M_FAC/P], COMP rx_filter_memory[NC+1][NFILTER], int nin);
+void down_convert_and_rx_filter(COMP rx_filt[NC+1][P+1], int Nc, COMP rx_fdm[],
+                                COMP rx_fdm_mem[], COMP phase_rx[], COMP freq[],
+                                float freq_pol[], int nin, int dec_rate);
+float rx_est_timing(COMP  rx_symbols[], int Nc,
+                   COMP  rx_filt[NC+1][P+1],
+                   COMP  rx_filter_mem_timing[NC+1][NT*P],
+                   float env[],
+                   int   nin,
+                    int   m);
+float qpsk_to_bits(int rx_bits[], int *sync_bit, int Nc, COMP phase_difference[], COMP prev_rx_symbols[], COMP rx_symbols[], int old_qpsk_mapping);
+void snr_update(float sig_est[], float noise_est[], int Nc, COMP phase_difference[]);
+int freq_state(int *reliable_sync_bit, int sync_bit, int *state, int *timer, int *sync_mem);
+float calc_snr(int Nc, float sig_est[], float noise_est[]);
+
+#endif
diff --git a/codec2/branches/0.7/src/fdmdv_mod.c b/codec2/branches/0.7/src/fdmdv_mod.c
new file mode 100644 (file)
index 0000000..c6eb796
--- /dev/null
@@ -0,0 +1,163 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_mod.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 28 2012
+
+  Given an input file of bits outputs a raw file (8kHz, 16 bit shorts)
+  of FDMDV modem samples ready to send over a HF radio channel.  The
+  input file is assumed to be arranged as codec frames of 56 bits (7
+  bytes) which we send as two 28 bit modem frames.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_fdmdv.h"
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin, *fout;
+    struct FDMDV *fdmdv;
+    char          *packed_bits;
+    int           *tx_bits;
+    COMP          tx_fdm[2*FDMDV_NOM_SAMPLES_PER_FRAME];
+    short         tx_fdm_scaled[2*FDMDV_NOM_SAMPLES_PER_FRAME];
+    int           frames;
+    int           i, bit, byte;
+    int           sync_bit;
+    int           bits_per_fdmdv_frame;
+    int           bits_per_codec_frame;
+    int           bytes_per_codec_frame;
+    int           Nc;
+#ifdef CHANNEL_SIM
+    COMP          foff_phase_rect;
+    float         foff;
+#endif
+
+    if (argc < 3) {
+       printf("usage: %s InputBitFile OutputModemRawFile [Nc]\n", argv[0]);
+       printf("e.g    %s hts1a.c2 hts1a_fdmdv.raw\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input bit 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);
+    }
+
+    if (argc == 4) {
+        Nc = atoi(argv[3]);
+
+        if ((Nc < 2) || (Nc > FDMDV_NC_MAX) ) {
+            fprintf(stderr, "Error number of carriers must be btween 2 and %d\n",  FDMDV_NC_MAX);
+            exit(1);
+        }
+   }
+    else
+        Nc = FDMDV_NC;
+
+    fdmdv = fdmdv_create(Nc);
+
+    bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);
+    bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    bytes_per_codec_frame = (bits_per_codec_frame+7)/8;
+
+    packed_bits = (char*)malloc(bytes_per_codec_frame);
+    assert(packed_bits != NULL);
+    tx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame);
+    assert(tx_bits != NULL);
+
+#ifdef CHANNEL_SIM
+    foff = -100;
+    foff_phase_rect.real = 1.0; foff_phase_rect.imag = 0.0;
+#endif
+
+    frames = 0;
+
+    while(fread(packed_bits, sizeof(char), bytes_per_codec_frame, fin) == bytes_per_codec_frame) {
+       frames++;
+
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<bits_per_codec_frame; i++) {
+           tx_bits[i] = (packed_bits[byte] >> bit) & 0x1;
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+
+       /* modulate even and odd frames */
+
+       fdmdv_mod(fdmdv, tx_fdm, tx_bits, &sync_bit);
+       assert(sync_bit == 1);
+
+       fdmdv_mod(fdmdv, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &tx_bits[bits_per_fdmdv_frame], &sync_bit);
+       assert(sync_bit == 0);
+
+        #ifdef CHANNEL_SIM
+        /* optional freq shift and channel simulation */
+
+        fdmdv_freq_shift(tx_fdm, tx_fdm, foff, &foff_phase_rect, 2*FDMDV_NOM_SAMPLES_PER_FRAME);
+        fdmdv_simulate_channel(&sig_pwr_av, tx_fdm, 2*FDMDV_NOM_SAMPLES_PER_FRAME, 10.0);
+        #endif
+
+       /* scale and save to disk as shorts */
+
+       for(i=0; i<2*FDMDV_NOM_SAMPLES_PER_FRAME; i++)
+           tx_fdm_scaled[i] = FDMDV_SCALE * tx_fdm[i].real;
+
+       fwrite(tx_fdm_scaled, sizeof(short), 2*FDMDV_NOM_SAMPLES_PER_FRAME, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    //fdmdv_dump_osc_mags(fdmdv);
+
+    free(tx_bits);
+    free(packed_bits);
+    fclose(fin);
+    fclose(fout);
+    fdmdv_destroy(fdmdv);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/fdmdv_put_test_bits.c b/codec2/branches/0.7/src/fdmdv_put_test_bits.c
new file mode 100644 (file)
index 0000000..a0ffb1b
--- /dev/null
@@ -0,0 +1,169 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_put_test_bits.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 May 2012
+
+  Using a file of packed test bits as input, determines bit error
+  rate.  Useful for testing fdmdv_demod.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_fdmdv.h"
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin;
+    struct FDMDV *fdmdv;
+    char         *packed_bits;
+    int          *rx_bits;
+    int           i, bit, byte;
+    int           test_frame_sync, bit_errors, total_bit_errors, total_bits, ntest_bits;
+    int           test_frame_sync_state, test_frame_count;
+    int           bits_per_fdmdv_frame;
+    int           bits_per_codec_frame;
+    int           bytes_per_codec_frame;
+    int           Nc;
+    short        *error_pattern;
+
+    if (argc < 2) {
+       printf("usage: %s InputBitFile [Nc]\n", argv[0]);
+       printf("e.g    %s test.c2\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-") == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input bit file: %s: %s.\n",
+         argv[1], strerror(errno));
+       exit(1);
+    }
+
+    if (argc == 3) {
+        Nc = atoi(argv[2]);
+        if ((Nc < 2) || (Nc > FDMDV_NC_MAX) ) {
+            fprintf(stderr, "Error number of carriers must be between 2 and %d\n",  FDMDV_NC_MAX);
+            exit(1);
+        }
+    }
+    else
+        Nc = FDMDV_NC;
+
+    fdmdv = fdmdv_create(Nc);
+
+    bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);
+    bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    bytes_per_codec_frame = (bits_per_codec_frame+7)/8;
+    fprintf(stderr, "bits_per_fdmdv_frame: %d bits_per_codec_frame: %d bytes_per_codec_frame: %d\n",
+            bits_per_fdmdv_frame, bits_per_codec_frame, bytes_per_codec_frame);
+
+    packed_bits = (char*)malloc(bytes_per_codec_frame);
+    assert(packed_bits != NULL);
+    rx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame);
+    assert(rx_bits != NULL);
+
+    error_pattern = (short*)malloc(fdmdv_error_pattern_size(fdmdv)*sizeof(int));
+    assert(error_pattern != NULL);
+
+    total_bit_errors = 0;
+    total_bits = 0;
+    test_frame_sync_state = 0;
+    test_frame_count = 0;
+
+    while(fread(packed_bits, sizeof(char), bytes_per_codec_frame, fin) == bytes_per_codec_frame) {
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<bits_per_codec_frame; i++) {
+           rx_bits[i] = (packed_bits[byte] >> bit) & 0x1;
+           //printf("%d 0x%x %d\n", i, packed_bits[byte], rx_bits[i]);
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+
+       fdmdv_put_test_bits(fdmdv, &test_frame_sync, error_pattern, &bit_errors, &ntest_bits, rx_bits);
+
+       if (test_frame_sync == 1) {
+           test_frame_sync_state = 1;
+            test_frame_count = 0;
+        }
+
+        if (test_frame_sync_state) {
+            if (test_frame_count == 0) {
+                total_bit_errors += bit_errors;
+                total_bits = total_bits + ntest_bits;
+                printf("+");
+            }
+            else
+                printf("-");
+            test_frame_count++;
+            if (test_frame_count == 4)
+                test_frame_count = 0;
+       }
+        else
+            printf("-");
+
+       fdmdv_put_test_bits(fdmdv, &test_frame_sync,  error_pattern, &bit_errors, &ntest_bits, &rx_bits[bits_per_fdmdv_frame]);
+
+       if (test_frame_sync == 1) {
+           test_frame_sync_state = 1;
+            test_frame_count = 0;
+        }
+
+        if (test_frame_sync_state) {
+            if (test_frame_count == 0) {
+                total_bit_errors += bit_errors;
+                total_bits = total_bits + ntest_bits;
+                printf("+");
+            }
+            else
+                printf("-");
+            test_frame_count++;
+            if (test_frame_count == 4)
+                test_frame_count = 0;
+       }
+       else
+           printf("-");
+
+       /* if this is in a pipeline, we probably don't want the usual
+          buffering to occur */
+
+        if (fin == stdin) fflush(stdin);
+    }
+
+    fclose(fin);
+    free(error_pattern);
+    fdmdv_destroy(fdmdv);
+
+    printf("\nbits %d  errors %d  BER %1.4f\n", total_bits, total_bit_errors, (float)total_bit_errors/(1E-6+total_bits) );
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/fec_dec.c b/codec2/branches/0.7/src/fec_dec.c
new file mode 100644 (file)
index 0000000..ea19d19
--- /dev/null
@@ -0,0 +1,307 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fec_dec.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 4 march 2013
+
+  FEC decoder for data from modem containing compressed Codec 2 data
+  and FEC.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+#include "codec2_fdmdv.h"
+#include "golay23.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define MODE_1600 0
+#define MODE_1850 1
+#define MODE_2000 2
+
+int main(int argc, char *argv[])
+{
+    void          *codec2, *fdmdv;
+    FILE          *fin;
+    FILE          *fout;
+    int            bits_per_input_frame, bytes_per_input_frame;
+    unsigned char *packed_input_bits;
+    int           *unpacked_input_bits;
+    int            bits_per_output_frame, bytes_per_output_frame;
+    unsigned char *packed_output_bits;
+    int           *unpacked_output_bits;
+    int            codec2_mode, mode, Nc, bit, byte;
+    int            i,j;
+    int            recd_codeword, codeword1, codeword2;
+
+    if (argc < 3) {
+       printf("%s InputFromModemWithFECFile OutputToCodec2File [2000|1600]\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input file from Demod: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file to Codec : %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    /* input parameters and buffers. Note data is split into two 20ms
+       frames for transmission over modem. */
+
+    if ((argc != 4) || (strcmp(argv[3],"2000") == 0)) {
+        /* 2000 bit/s with FEC */
+        mode = MODE_2000;
+       codec2_mode = CODEC2_MODE_1400;
+        Nc = 20;
+    } else if ((strcmp(argv[3],"1850") == 0)) {
+        /* 1850 bit/s with FEC */
+        mode = MODE_1850;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 20;
+    }
+    else if (strcmp(argv[3],"1600") == 0) {
+        /* 1600 bit/s with FEC (actually 1575 with one spare) */
+        mode = MODE_1600;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 16;
+    }
+    else {
+       fprintf(stderr, "Error in mode: %s.  Must be 2000 or 1600\n", argv[3]);
+       exit(1);
+    }
+
+    fdmdv = fdmdv_create(Nc);
+
+    bits_per_input_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    bytes_per_input_frame = bits_per_input_frame / 8;
+    assert((bits_per_input_frame % 8) == 0); /* make sure integer number of bytes per frame */
+
+    packed_input_bits = (unsigned char*)malloc(bytes_per_input_frame*sizeof(char));
+    assert(packed_input_bits != NULL);
+    unpacked_input_bits = (int*)malloc(bits_per_input_frame*sizeof(int));
+    assert(unpacked_input_bits != NULL);
+
+    /*
+       Output parameters and buffers.
+    */
+
+    codec2 = codec2_create(codec2_mode);
+
+    bits_per_output_frame = codec2_bits_per_frame(codec2);
+    bytes_per_output_frame = (bits_per_output_frame+7)/8;
+
+    packed_output_bits = (unsigned char*)malloc(bytes_per_output_frame*sizeof(char));
+    assert(packed_output_bits != NULL);
+    unpacked_output_bits = (int*)malloc(bits_per_output_frame*sizeof(int));
+    assert(unpacked_output_bits != NULL);
+
+    fprintf(stderr, "input bits: %d  input_bytes: %d  output_bits: %d  output_bytes: %d\n",
+            bits_per_input_frame,  bytes_per_input_frame, bits_per_output_frame,  bytes_per_output_frame);
+
+    /* main loop */
+
+    golay23_init();
+
+    while(fread(packed_input_bits, sizeof(char), bytes_per_input_frame, fin) == (size_t)bytes_per_input_frame) {
+
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<bits_per_input_frame; i++) {
+           unpacked_input_bits[i] = (packed_input_bits[byte] >> bit) & 0x1;
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+
+        #ifdef TEST
+        /* Some test bit errors (not comprehesnive) */
+        unpacked_input_bits[0] = (unpacked_input_bits[0] ^ 1) & 0x1;
+        unpacked_input_bits[23] = (unpacked_input_bits[23] ^ 1) & 0x1;
+        #endif
+
+        if (mode == MODE_2000) {
+            /* decode first codeword */
+
+            recd_codeword = 0;
+            for(i=0; i<12; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame; i<bits_per_output_frame+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_decode(recd_codeword);
+            //codeword1 = recd_codeword;
+            //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+
+            for(i=0; i<12; i++) {
+                unpacked_output_bits[i] = (codeword1 >> (22-i)) & 0x1;
+            }
+
+            /* decode second codeword */
+
+            recd_codeword = 0;
+            for(i=12; i<24; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame+11; i<bits_per_output_frame+11+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_decode(recd_codeword);
+            //codeword2 = recd_codeword;
+            //fprintf(stderr, "received codeword2: 0x%x  decoded codeword2: 0x%x\n", recd_codeword, codeword2);
+
+            for(i=0; i<12; i++) {
+                unpacked_output_bits[12+i] = (codeword2 >> (22-i)) & 0x1;
+            }
+
+            /* unprotected bits */
+
+            for(i=24; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+        }
+
+        if (mode == MODE_1600) {
+            recd_codeword = 0;
+            for(i=0; i<8; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame; i<bits_per_output_frame+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_decode(recd_codeword);
+            //codeword1 = recd_codeword;
+            //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+
+            for(i=0; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+
+            for(i=0; i<8; i++) {
+                unpacked_output_bits[i] = (codeword1 >> (22-i)) & 0x1;
+            }
+            for(i=8,j=11; i<12; i++,j++) {
+                unpacked_output_bits[j] = (codeword1 >> (22-i)) & 0x1;
+            }
+        }
+
+        if (mode == MODE_1850) {
+            recd_codeword = 0;
+            for(i=0; i<8; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame; i<bits_per_output_frame+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_decode(recd_codeword);
+            //codeword1 = recd_codeword;
+            //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+
+            recd_codeword = 0;
+            for(i=16; i<28; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            for(i=bits_per_output_frame+11; i<bits_per_output_frame+11+11; i++) {
+                recd_codeword <<= 1;
+                recd_codeword |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_decode(recd_codeword);
+            fprintf(stderr, "received codeword2: 0x%x  decoded codeword2: 0x%x\n", recd_codeword, codeword2);
+
+            for(i=0; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+
+            for(i=0; i<8; i++) {
+                unpacked_output_bits[i] = (codeword1 >> (22-i)) & 0x1;
+            }
+            for(i=8,j=11; i<12; i++,j++) {
+                unpacked_output_bits[j] = (codeword1 >> (22-i)) & 0x1;
+            }
+            for(i=0,j=16; i<12; i++,j++) {
+                unpacked_output_bits[j] = (codeword2 >> (22-i)) & 0x1;
+            }
+
+        }
+
+        /* pack bits, MSB first  */
+
+        bit = 7; byte = 0;
+        memset(packed_output_bits, 0, bytes_per_output_frame);
+        for(i=0; i<bits_per_output_frame; i++) {
+            packed_output_bits[byte] |= (unpacked_output_bits[i] << bit);
+            bit--;
+            if (bit < 0) {
+                bit = 7;
+                byte++;
+            }
+        }
+
+       fwrite(packed_output_bits, sizeof(char), bytes_per_output_frame, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+           buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    codec2_destroy(codec2);
+    fdmdv_destroy(fdmdv);
+
+    free(packed_input_bits);
+    free(unpacked_input_bits);
+    free(packed_output_bits);
+    free(unpacked_output_bits);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/fec_enc.c b/codec2/branches/0.7/src/fec_enc.c
new file mode 100644 (file)
index 0000000..9b777a7
--- /dev/null
@@ -0,0 +1,312 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fec_enc.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 4 march 2013
+
+  Encodes compressed Codec 2 data using FEC.  This initial version
+  assumes 1400 bit/s Codec 2 input data (56 bit, 40ms frames), with 80
+  bit frame outpout, suitable for 20 carrier, 2000 bit/s modem.  In
+  future other experimental schemes may be supported.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+#include "codec2_fdmdv.h"
+#include "golay23.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define MODE_1600 0
+#define MODE_1850 1
+#define MODE_2000 2
+
+int main(int argc, char *argv[])
+{
+    void          *codec2, *fdmdv;
+    FILE          *fin;
+    FILE          *fout;
+    int            bits_per_input_frame, bytes_per_input_frame;
+    unsigned char *packed_input_bits;
+    int           *unpacked_input_bits;
+    int            bits_per_output_frame, bytes_per_output_frame;
+    unsigned char *packed_output_bits;
+    int           *unpacked_output_bits;
+    int            codec2_mode, mode, Nc, bit, byte;
+    int            i,j;
+    int            data, codeword1, codeword2;
+
+    if (argc < 3) {
+       printf("%s InputFromCodecFile OutputToModemWithFECFile [2000|1850|1600]\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input file from Codec: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file : %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    if ((argc != 4) || (strcmp(argv[3],"2000") == 0)) {
+        /* 2000 bit/s with FEC */
+        mode = MODE_2000;
+       codec2_mode = CODEC2_MODE_1400;
+        Nc = 20;
+    } else if ((strcmp(argv[3],"1850") == 0)) {
+        /* 1850 bit/s with FEC */
+        mode = MODE_1850;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 20;
+    }
+    else if (strcmp(argv[3],"1600") == 0) {
+        /* 1600 bit/s with FEC (actually 1575 with one spare) */
+        mode = MODE_1600;
+       codec2_mode = CODEC2_MODE_1300;
+        Nc = 16;
+    }
+    else {
+       fprintf(stderr, "Error in mode: %s.  Must be 2000, 1850, or 1600\n", argv[3]);
+       exit(1);
+    }
+
+    /* input parameters and buffers */
+
+    codec2 = codec2_create(codec2_mode);
+
+    bits_per_input_frame = codec2_bits_per_frame(codec2);
+    bytes_per_input_frame = (bits_per_input_frame + 7)/8;
+
+    packed_input_bits = (unsigned char*)malloc(bytes_per_input_frame*sizeof(char));
+    assert(packed_input_bits != NULL);
+    unpacked_input_bits = (int*)malloc(bits_per_input_frame*sizeof(int));
+    assert(unpacked_input_bits != NULL);
+
+    /*
+       Output parameters and buffers.  Data is split into two 20ms
+       frames for transmission over modem, but this doesn't really
+       bother us here, as fdmdv_mod takes care of that.
+    */
+
+    fdmdv = fdmdv_create(Nc);
+
+    bits_per_output_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    bytes_per_output_frame = (bits_per_output_frame+7)/8;
+
+    packed_output_bits = (unsigned char*)malloc(bytes_per_output_frame*sizeof(char));
+    assert(packed_output_bits != NULL);
+    unpacked_output_bits = (int*)malloc(bits_per_output_frame*sizeof(int));
+    assert(unpacked_output_bits != NULL);
+
+    fprintf(stderr, "mode: %d  Nc: %d\n", mode, Nc);
+    fprintf(stderr, "input bits: %d  input_bytes: %d  output_bits: %d  output_bytes: %d\n",
+            bits_per_input_frame,  bytes_per_input_frame, bits_per_output_frame,  bytes_per_output_frame);
+
+    /* main loop */
+
+    golay23_init();
+
+    while(fread(packed_input_bits, sizeof(char), bytes_per_input_frame, fin) == (size_t)bytes_per_input_frame) {
+
+       /* unpack bits, MSB first */
+
+       bit = 7; byte = 0;
+       for(i=0; i<bits_per_input_frame; i++) {
+           unpacked_input_bits[i] = (packed_input_bits[byte] >> bit) & 0x1;
+           bit--;
+           if (bit < 0) {
+               bit = 7;
+               byte++;
+           }
+       }
+
+        /* add FEC  ---------------------------------------------------------*/
+
+        if (mode == MODE_2000) {
+            /* Protect first 24 bits with (23,12) Golay Code.  The first
+               24 bits are the most sensitive, as they contain the
+               pitch/energy VQ and voicing bits. This uses 56 + 11 + 11 =
+               78 bits, so we have two spare in 80 bit frame sent to
+               modem. */
+
+            /* first codeword */
+
+            data = 0;
+            for(i=0; i<12; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_encode(data);
+            //fprintf(stderr, "data1: 0x%x codeword1: 0x%x\n", data, codeword1);
+
+            /* second codeword */
+
+            data = 0;
+            for(i=12; i<24; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_encode(data);
+            //fprintf(stderr, "data: 0x%x codeword2: 0x%x\n", data, codeword2);
+
+            /* now pack output frame with parity bits at end to make them
+               as far apart as possible from the data the protect.  Parity
+               bits are LSB of the Golay codeword */
+
+            for(i=0; i<bits_per_input_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+            for(j=0; i<bits_per_input_frame+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+            }
+            for(j=0; i<bits_per_input_frame+11+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword2 >> (10-j)) & 0x1;
+            }
+        }
+
+        if (mode == MODE_1850) {
+
+            /* Protect first 12 out of first 16 excitation bits with (23,12) Golay Code:
+
+               0,1,2,3: v[0]..v[1]
+               4,5,6,7: MSB of pitch
+               11,12,13,14: MSB of energy
+
+            */
+
+            data = 0;
+            for(i=0; i<8; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_encode(data);
+
+            /* Protect first 12 LSP bits with (23,12) Golay Code */
+
+            data = 0;
+            for(i=16; i<28; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword2 = golay23_encode(data);
+            fprintf(stderr, "codeword2: 0x0%x\n", codeword2);
+
+            /* now pack output frame with parity bits at end to make them
+               as far apart as possible from the data they protect.  Parity
+               bits are LSB of the Golay codeword */
+
+            for(i=0; i<bits_per_input_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+            for(j=0; i<bits_per_input_frame+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+                unpacked_output_bits[i+11] = (codeword2 >> (10-j)) & 0x1;
+            }
+            for(i=bits_per_input_frame+11+11; i<bits_per_output_frame; i++)
+                unpacked_output_bits[i] = 0;
+        }
+
+        if (mode == MODE_1600) {
+
+            /* Protect first 12 out of first 16 excitation bits with (23,12) Golay Code:
+
+               0,1,2,3: v[0]..v[1]
+               4,5,6,7: MSB of pitch
+               11,12,13,14: MSB of energy
+
+            */
+
+            data = 0;
+            for(i=0; i<8; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            for(i=11; i<15; i++) {
+                data <<= 1;
+                data |= unpacked_input_bits[i];
+            }
+            codeword1 = golay23_encode(data);
+
+            /* now pack output frame with parity bits at end to make them
+               as far apart as possible from the data they protect.  Parity
+               bits are LSB of the Golay codeword */
+
+            for(i=0; i<bits_per_input_frame; i++)
+                unpacked_output_bits[i] = unpacked_input_bits[i];
+            for(j=0; i<bits_per_input_frame+11; i++,j++) {
+                unpacked_output_bits[i] = (codeword1 >> (10-j)) & 0x1;
+            }
+            unpacked_output_bits[i] = 0; /* spare bit */
+
+            //for(i=0; i<bits_per_input_frame+12; i++)
+            //    printf("%d\n", unpacked_output_bits[i]);
+
+        }
+
+        /* pack bits, MSB first  */
+
+        bit = 7; byte = 0;
+        memset(packed_output_bits, 0, bytes_per_output_frame);
+        for(i=0; i<bits_per_output_frame; i++) {
+            assert((unpacked_output_bits[i] == 0) || (unpacked_output_bits[i] == 1));
+            packed_output_bits[byte] |= (unpacked_output_bits[i] << bit);
+            bit--;
+            if (bit < 0) {
+                bit = 7;
+                byte++;
+            }
+        }
+        assert(byte == bytes_per_output_frame);
+
+       fwrite(packed_output_bits, sizeof(char), bytes_per_output_frame, fout);
+
+       /* if this is in a pipeline, we probably don't want the usual
+           buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    codec2_destroy(codec2);
+    fdmdv_destroy(fdmdv);
+
+    free(packed_input_bits);
+    free(unpacked_input_bits);
+    free(packed_output_bits);
+    free(unpacked_output_bits);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/fifo.c b/codec2/branches/0.7/src/fifo.c
new file mode 100644 (file)
index 0000000..f9aadc3
--- /dev/null
@@ -0,0 +1,143 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fifo.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Oct 15 2012
+
+  A FIFO design useful in gluing the FDMDV modem and codec together in
+  integrated applications.  The unittest/tfifo indicates these
+  routines are thread safe without the need for syncronisation
+  object, e.g. a different thread can read and write to a fifo at the
+  same time.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "codec2_fifo.h"
+
+struct FIFO {
+    short *buf;
+    short *pin;
+    short *pout;
+    int    nshort;
+};
+
+struct FIFO *fifo_create(int nshort) {
+    struct FIFO *fifo;
+
+    fifo = (struct FIFO *)malloc(sizeof(struct FIFO));
+    assert(fifo != NULL);
+
+    fifo->buf = (short*)malloc(sizeof(short)*nshort);
+    assert(fifo->buf != NULL);
+    fifo->pin = fifo->buf;
+    fifo->pout = fifo->buf;
+    fifo->nshort = nshort;
+
+    return fifo;
+}
+
+void fifo_destroy(struct FIFO *fifo) {
+    assert(fifo != NULL);
+    free(fifo->buf);
+    free(fifo);
+}
+
+int fifo_write(struct FIFO *fifo, short data[], int n) {
+    int            i;
+    short         *pdata;
+    short         *pin = fifo->pin;
+
+    assert(fifo != NULL);
+    assert(data != NULL);
+
+    if (n > fifo_free(fifo)) {
+       return -1;
+    }
+    else {
+
+       /* This could be made more efficient with block copies
+          using memcpy */
+
+       pdata = data;
+       for(i=0; i<n; i++) {
+           *pin++ = *pdata++;
+           if (pin == (fifo->buf + fifo->nshort))
+               pin = fifo->buf;
+       }
+       fifo->pin = pin;
+    }
+
+    return 0;
+}
+
+int fifo_read(struct FIFO *fifo, short data[], int n)
+{
+    int            i;
+    short         *pdata;
+    short         *pout = fifo->pout;
+
+    assert(fifo != NULL);
+    assert(data != NULL);
+
+    if (n > fifo_used(fifo)) {
+       return -1;
+    }
+    else {
+
+       /* This could be made more efficient with block copies
+          using memcpy */
+
+       pdata = data;
+       for(i=0; i<n; i++) {
+           *pdata++ = *pout++;
+           if (pout == (fifo->buf + fifo->nshort))
+               pout = fifo->buf;
+       }
+       fifo->pout = pout;
+    }
+
+    return 0;
+}
+
+int fifo_used(const struct FIFO * const fifo)
+{
+    short         *pin = fifo->pin;
+    short         *pout = fifo->pout;
+    unsigned int   used;
+
+    assert(fifo != NULL);
+    if (pin >= pout)
+        used = pin - pout;
+    else
+        used = fifo->nshort + (unsigned int)(pin - pout);
+
+    return used;
+}
+
+int fifo_free(const struct FIFO * const fifo)
+{
+    // available storage is one less than nshort as prd == pwr
+    // is reserved for empty rather than full
+
+    return fifo->nshort - fifo_used(fifo) - 1;
+}
diff --git a/codec2/branches/0.7/src/fm.c b/codec2/branches/0.7/src/fm.c
new file mode 100644 (file)
index 0000000..e1fbe37
--- /dev/null
@@ -0,0 +1,290 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fm.c
+  AUTHOR......: David Rowe
+  DATE CREATED: February 2015
+
+  Functions that implement analog FM modulation and demodulation, see
+  also octave/fm.m.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*---------------------------------------------------------------------------*\
+
+                               DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+#define FILT_MEM 200
+
+/*---------------------------------------------------------------------------*\
+
+                               INCLUDES
+
+\*---------------------------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "codec2_fm.h"
+#include "fm_fir_coeff.h"
+#include "comp_prim.h"
+
+/*---------------------------------------------------------------------------*\
+
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fm_create
+  AUTHOR......: David Rowe
+  DATE CREATED: 24 Feb 2015
+
+  Create and initialise an instance of the "modem".  Returns a pointer
+  to the modem states or NULL on failure.  One set of states is
+  sufficient for a full duplex modem.
+
+\*---------------------------------------------------------------------------*/
+
+struct FM *fm_create(int nsam)
+{
+    struct FM *fm;
+
+    fm = (struct FM*)malloc(sizeof(struct FM));
+    if (fm == NULL)
+       return NULL;
+    fm->rx_bb = (COMP*)malloc(sizeof(COMP)*(FILT_MEM+nsam));
+    assert(fm->rx_bb != NULL);
+
+    fm->rx_bb_filt_prev.real = 0.0;
+    fm->rx_bb_filt_prev.imag = 0.0;
+    fm->lo_phase.real = 1.0;
+    fm->lo_phase.imag = 0.0;
+
+    fm->tx_phase = 0;
+
+    fm->rx_dem_mem = (float*)malloc(sizeof(float)*(FILT_MEM+nsam));
+    assert(fm->rx_dem_mem != NULL);
+
+    fm->nsam = nsam;
+
+    return fm;
+}
+
+
+void fm_destroy(struct FM *fm_states)
+{
+    free(fm_states->rx_bb);
+    free(fm_states->rx_dem_mem);
+    free(fm_states);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fm_demod
+  AUTHOR......: David Rowe
+  DATE CREATED: 24 Feb 2015
+
+  Demodulate a FM signal to baseband audio.
+
+\*---------------------------------------------------------------------------*/
+
+void fm_demod(struct FM *fm_states, float rx_out[], float rx[])
+{
+  float  Fs = fm_states->Fs;
+  float  fc = fm_states->fc;
+  float  wc = 2*M_PI*fc/Fs;
+  float  fd = fm_states->fd;
+  float  wd = 2*M_PI*fd/Fs;
+  COMP  *rx_bb = fm_states->rx_bb + FILT_MEM;
+  COMP   wc_rect, rx_bb_filt, rx_bb_diff;
+  float  rx_dem;
+  /*
+  float acc;
+  */
+  float *rx_dem_mem = fm_states->rx_dem_mem + FILT_MEM;
+  int    nsam = fm_states->nsam;
+  float  mag;
+  int    i,k;
+
+  wc_rect.real = cosf(wc); wc_rect.imag = -sinf(wc);
+
+  for(i=0; i<nsam; i++) {
+
+      /* down to complex baseband */
+
+      fm_states->lo_phase = cmult(fm_states->lo_phase, wc_rect);
+      rx_bb[i] = fcmult(rx[i], fm_states->lo_phase);
+
+      /* input FIR filter */
+
+      rx_bb_filt.real = 0.0; rx_bb_filt.imag = 0.0;
+
+      for(k=0; k<FILT_MEM/2; k++) {
+          rx_bb_filt.real += rx_bb[i-k].real * bin[k+FILT_MEM/4];
+          rx_bb_filt.imag += rx_bb[i-k].imag * bin[k+FILT_MEM/4];
+      }
+
+      //rx_bb_filt = rx_bb[i];
+      //printf("%f %f %f\n", rx[i], wc_rect.real, wc_rect.imag);
+      //printf("%f %f %f\n", rx[i], fm_states->lo_phase.real, fm_states->lo_phase.imag);
+      //printf("%f %f %f\n", rx[i], rx_bb[i].real, rx_bb[i].imag);
+      //printf("%f %f\n", rx_bb_filt.real, rx_bb_filt.imag);
+      /*
+         Differentiate first, in rect domain, then find angle, this
+         puts signal on the positive side of the real axis and helps
+         atan2() behaive.
+      */
+
+      rx_bb_diff = cmult(rx_bb_filt, cconj(fm_states->rx_bb_filt_prev));
+      fm_states->rx_bb_filt_prev = rx_bb_filt;
+
+      rx_dem = atan2f(rx_bb_diff.imag, rx_bb_diff.real);
+
+      /* limit maximum phase jumps, to remove static type noise at low SNRs */
+
+      if (rx_dem > wd)
+          rx_dem = wd;
+      if (rx_dem < -wd)
+          rx_dem = -wd;
+
+      rx_dem *= (1/wd);
+      //printf("%f %f\n", rx_bb_diff.real, rx_bb_diff.imag);
+      rx_dem_mem[i] = rx_dem;
+      /*
+      acc = 0;
+        for(k=0; k<FILT_MEM; k++) {
+          acc += rx_dem_mem[i-k] * bout[k];
+      }
+      */
+      rx_out[i] = rx_dem;
+  }
+
+  /* update filter memories */
+
+  rx_bb      -= FILT_MEM;
+  rx_dem_mem -= FILT_MEM;
+  for(i=0; i<FILT_MEM; i++) {
+      rx_bb[i] = rx_bb[i+nsam];
+      rx_dem_mem[i] = rx_dem_mem[i+nsam];
+  }
+
+  /* normalise digital oscillator as the magnitude can drift over time */
+
+  mag = cabsolute(fm_states->lo_phase);
+  fm_states->lo_phase.real /= mag;
+  fm_states->lo_phase.imag /= mag;
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fm_mod
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: Sept. 10 2015
+
+  Modulate an FM signal from a baseband modulating signal
+
+  struct FM *fm - FM state structure. Can be reused from fm_demod.
+  float tx_in[] - nsam baseband samples to be modulated
+  float tx_out[] - nsam samples in which to place the modulated FM
+
+\*---------------------------------------------------------------------------*/
+
+void fm_mod(struct FM *fm_states, float tx_in[], float tx_out[]) {
+  float  Fs = fm_states->Fs;    //Sampling freq
+  float  fc = fm_states->fc;    //Center freq
+  float  wc = 2*M_PI*fc/Fs;     //Center freq in rads/samp
+  float  fd = fm_states->fd;    //Max deviation in cycles/samp
+  float  wd = 2*M_PI*fd/Fs;     //Max deviation in rads/samp
+  int  nsam = fm_states->nsam;  //Samples per batch of modulation
+  float tx_phase = fm_states->tx_phase; //Transmit phase in rads
+  float w;                     //Temp variable for phase of VFO during loop
+  int i;
+
+  //Go through the samples, spin the oscillator, and generate some FM
+  for(i=0; i<nsam; i++){
+      w = wc + wd*tx_in[i];   //Calculate phase of VFO
+      tx_phase += w;          //Spin TX oscillator
+
+      //TODO: Add pre-emphasis and pre-emph AGC for voice
+
+      //Make sure tx_phase stays from 0 to 2PI.
+      //If tx_phase goes above 4PI, It's because fc+fd*tx_in[i] is way too large for the sample
+      // rate.
+      if(tx_phase > 2*M_PI)
+          tx_phase -= 2*M_PI;
+      tx_out[i] = cosf(tx_phase);
+  }
+  //Save phase back into state struct
+  fm_states->tx_phase = tx_phase;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fm_mod
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: Sept. 10 2015
+
+  Modulate an FM signal from a baseband modulating signal. Output signal is
+   in complex domain
+
+  struct FM *fm - FM state structure. Can be reused from fm_demod.
+  float tx_in[] - nsam baseband samples to be modulated
+  COMP tx_out[] - nsam samples in which to place the modulated FM
+
+\*---------------------------------------------------------------------------*/
+
+void fm_mod_comp(struct FM *fm_states, float tx_in[], COMP tx_out[]){
+  float  Fs = fm_states->Fs;    //Sampling freq
+  float  fc = fm_states->fc;    //Center freq
+  float  wc = 2*M_PI*fc/Fs;     //Center freq in rads/samp
+  float  fd = fm_states->fd;    //Max deviation in cycles/samp
+  float  wd = 2*M_PI*fd/Fs;     //Max deviation in rads/samp
+  int  nsam = fm_states->nsam;  //Samples per batch of modulation
+  float tx_phase = fm_states->tx_phase; //Transmit phase in rads
+  float w;                     //Temp variable for phase of VFO during loop
+  int i;
+
+  //Go through the samples, spin the oscillator, and generate some FM
+  for(i=0; i<nsam; i++){
+      w = wc + wd*tx_in[i];   //Calculate phase of VFO
+      tx_phase += w;          //Spin TX oscillator
+      
+      //TODO: Add pre-emphasis and pre-emph AGC for voice
+
+      //Make sure tx_phase stays from 0 to 2PI.
+      //If tx_phase goes above 4PI, It's because fc+fd*tx_in[i] is way too large for the sample
+      // rate.
+      if(tx_phase > 2*M_PI)
+          tx_phase -= 2*M_PI;
+
+      tx_out[i].real = cosf(tx_phase);
+      tx_out[i].imag = sinf(tx_phase);
+  }
+  //Save phase back into state struct
+  fm_states->tx_phase = tx_phase;
+}
+
diff --git a/codec2/branches/0.7/src/fm_demod.c b/codec2/branches/0.7/src/fm_demod.c
new file mode 100644 (file)
index 0000000..11d4dd5
--- /dev/null
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fm_demod.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Feb 24 2015
+
+  Given an input raw file (44.4 kHz, 16 bit shorts) with a FM signal centered
+  11.1 kHz, outputs a file of demodulated audio samples.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <errno.h>
+
+#include "codec2_fm.h"
+#include "octave.h"
+
+#define N 160
+
+#define TEST_MOD_COMP
+
+int main(int argc, char *argv[])
+{
+    FILE         *fin, *fout;
+    struct FM    *fm;
+    short         buf[N*2];
+    float         rx[N];
+#if defined(TEST_MODE) && !defined(TEST_MODE_COMP)
+    float         rx_out[N];
+#endif
+    COMP          out_comp[N];
+    int           i;
+
+    if (argc < 2) {
+       printf("usage: %s InputFMRawFile OutputSpeechRawFile\n", argv[0]);
+       printf("e.g    %s fm.raw fm_demodulated.raw\n", argv[0]);
+       exit(1);
+    }
+
+    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);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[2],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    fm         = fm_create(N);
+    fm->Fs     = 48000.0;
+    fm->fm_max = 3000.0;
+    fm->fd     = 5000.0;
+    fm->fc     = 0;
+
+    while(fread(buf, sizeof(short), N, fin) == N) {
+       for(i=0; i<N; i++) {
+           rx[i] = ((float)buf[i])/16384;
+        }
+#ifdef TEST_MOD
+       fm_mod(fm, rx, rx_out);
+#else
+#ifdef  TEST_MOD_COMP
+       fm_mod_comp(fm, rx, out_comp);
+#else
+        fm_demod(fm, rx_out, rx);
+#endif
+#endif
+
+
+#ifdef TEST_MOD_COMP
+       for(i=0; i<N; i++) {
+           buf[i*2    ] = 16384*out_comp[i].real;
+            buf[1+(i*2)] = 16384*out_comp[i].imag;
+        }
+       fwrite(buf, sizeof(short), N*2, fout);
+#else
+       for(i=0; i<N; i++) {
+           buf[i] = 16384*rx_out[i];
+        }
+        fwrite(buf, sizeof(short), N, fout);
+#endif
+    }
+
+    fm_destroy(fm);
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/fm_fir_coeff.h b/codec2/branches/0.7/src/fm_fir_coeff.h
new file mode 100644 (file)
index 0000000..e96926e
--- /dev/null
@@ -0,0 +1,413 @@
+/* Generated by fm_fir_coeff_file() Octave function in fm.m */
+
+const float bin[]={
+  4.79309e-05,
+  1.1306e-05,
+  -5.5983e-05,
+  -7.01194e-05,
+  7.06484e-06,
+  9.92193e-05,
+  8.58591e-05,
+  -4.54326e-05,
+  -0.000152003,
+  -8.65645e-05,
+  0.000107704,
+  0.000207915,
+  6.24307e-05,
+  -0.000194905,
+  -0.000256788,
+  -3.72067e-06,
+  0.000303862,
+  0.000285027,
+  -9.75377e-05,
+  -0.000426141,
+  -0.000276571,
+  0.000245596,
+  0.00054748,
+  0.000214543,
+  -0.000438995,
+  -0.000647904,
+  -8.35097e-05,
+  0.000668808,
+  0.000702715,
+  -0.000127804,
+  -0.000917433,
+  -0.000684399,
+  0.000423605,
+  0.00115821,
+  0.000565432,
+  -0.000798262,
+  -0.00135608,
+  -0.000321829,
+  0.00123404,
+  0.00146953,
+  -6.28411e-05,
+  -0.00169975,
+  -0.00145365,
+  0.000593351,
+  0.00215057,
+  0.00126444,
+  -0.00125906,
+  -0.00252937,
+  -0.000863858,
+  0.00203097,
+  0.00276961,
+  0.000225378,
+  -0.00286002,
+  -0.00279968,
+  0.00066048,
+  0.00367697,
+  0.00254856,
+  -0.00178121,
+  -0.00439398,
+  -0.00195226,
+  0.00309842,
+  0.00490791,
+  0.000960678,
+  -0.0045454,
+  -0.00510509,
+  0.000456067,
+  0.00602631,
+  0.00486678,
+  -0.00230217,
+  -0.00741688,
+  -0.00407467,
+  0.00455244,
+  0.00856596,
+  0.0026148,
+  -0.00715072,
+  -0.0092966,
+  -0.000377815,
+  0.0100109,
+  0.00940383,
+  -0.00274808,
+  -0.0130204,
+  -0.00864357,
+  0.00689875,
+  0.0160465,
+  0.0066998,
+  -0.0122874,
+  -0.0189444,
+  -0.0030966,
+  0.0193367,
+  0.0215669,
+  -0.00304913,
+  -0.0290487,
+  -0.0237748,
+  0.0138493,
+  0.0443198,
+  0.0254471,
+  -0.0364426,
+  -0.0771407,
+  -0.0264901,
+  0.120993,
+  0.285249,
+  0.366844,
+  0.285249,
+  0.120993,
+  -0.0264901,
+  -0.0771407,
+  -0.0364426,
+  0.0254471,
+  0.0443198,
+  0.0138493,
+  -0.0237748,
+  -0.0290487,
+  -0.00304913,
+  0.0215669,
+  0.0193367,
+  -0.0030966,
+  -0.0189444,
+  -0.0122874,
+  0.0066998,
+  0.0160465,
+  0.00689875,
+  -0.00864357,
+  -0.0130204,
+  -0.00274808,
+  0.00940383,
+  0.0100109,
+  -0.000377815,
+  -0.0092966,
+  -0.00715072,
+  0.0026148,
+  0.00856596,
+  0.00455244,
+  -0.00407467,
+  -0.00741688,
+  -0.00230217,
+  0.00486678,
+  0.00602631,
+  0.000456067,
+  -0.00510509,
+  -0.0045454,
+  0.000960678,
+  0.00490791,
+  0.00309842,
+  -0.00195226,
+  -0.00439398,
+  -0.00178121,
+  0.00254856,
+  0.00367697,
+  0.00066048,
+  -0.00279968,
+  -0.00286002,
+  0.000225378,
+  0.00276961,
+  0.00203097,
+  -0.000863858,
+  -0.00252937,
+  -0.00125906,
+  0.00126444,
+  0.00215057,
+  0.000593351,
+  -0.00145365,
+  -0.00169975,
+  -6.28411e-05,
+  0.00146953,
+  0.00123404,
+  -0.000321829,
+  -0.00135608,
+  -0.000798262,
+  0.000565432,
+  0.00115821,
+  0.000423605,
+  -0.000684399,
+  -0.000917433,
+  -0.000127804,
+  0.000702715,
+  0.000668808,
+  -8.35097e-05,
+  -0.000647904,
+  -0.000438995,
+  0.000214543,
+  0.00054748,
+  0.000245596,
+  -0.000276571,
+  -0.000426141,
+  -9.75377e-05,
+  0.000285027,
+  0.000303862,
+  -3.72067e-06,
+  -0.000256788,
+  -0.000194905,
+  6.24307e-05,
+  0.000207915,
+  0.000107704,
+  -8.65645e-05,
+  -0.000152003,
+  -4.54326e-05,
+  8.58591e-05,
+  9.92193e-05,
+  7.06484e-06,
+  -7.01194e-05,
+  -5.5983e-05,
+  1.1306e-05,
+  4.79309e-05
+};
+
+const float bout[]={
+  -0.000901664,
+  -0.00105423,
+  -0.00102202,
+  -0.000796428,
+  -0.0004047,
+  9.24929e-05,
+  0.000610043,
+  0.00105267,
+  0.00133217,
+  0.00138452,
+  0.00118367,
+  0.000749102,
+  0.000145346,
+  -0.000527025,
+  -0.00114777,
+  -0.00159812,
+  -0.00178311,
+  -0.00165083,
+  -0.00120494,
+  -0.000507584,
+  0.000328412,
+  0.0011573,
+  0.00182538,
+  0.00219909,
+  0.00219097,
+  0.00177877,
+  0.00101358,
+  1.48175e-05,
+  -0.00104765,
+  -0.00198192,
+  -0.00260813,
+  -0.00279243,
+  -0.00247437,
+  -0.00168247,
+  -0.000534171,
+  0.000780521,
+  0.00202976,
+  0.00298006,
+  0.00343915,
+  0.00329371,
+  0.00253482,
+  0.00126569,
+  -0.000310763,
+  -0.00192329,
+  -0.00327808,
+  -0.0041113,
+  -0.00423916,
+  -0.00359628,
+  -0.00225463,
+  -0.000418452,
+  0.00160526,
+  0.00345676,
+  0.00478613,
+  0.00531776,
+  0.00490513,
+  0.00356541,
+  0.00148629,
+  -0.000997692,
+  -0.00345694,
+  -0.0054391,
+  -0.00654985,
+  -0.00652835,
+  -0.00530323,
+  -0.00301796,
+  -1.90046e-05,
+  0.00319335,
+  0.00604515,
+  0.00798756,
+  0.00859787,
+  0.00766479,
+  0.00524199,
+  0.001658,
+  -0.00252213,
+  -0.00658004,
+  -0.00976079,
+  -0.011405,
+  -0.0110744,
+  -0.00864874,
+  -0.00437487,
+  0.00114403,
+  0.00702171,
+  0.0122173,
+  0.0157018,
+  0.0166372,
+  0.0145415,
+  0.00940928,
+  0.00176699,
+  -0.00735151,
+  -0.0165112,
+  -0.0240533,
+  -0.0283208,
+  -0.027902,
+  -0.0218568,
+  -0.00988994,
+  0.0075553,
+  0.0293009,
+  0.0535398,
+  0.0780316,
+  0.100365,
+  0.118251,
+  0.129808,
+  0.143804,
+  0.129808,
+  0.118251,
+  0.100365,
+  0.0780316,
+  0.0535398,
+  0.0293009,
+  0.0075553,
+  -0.00988994,
+  -0.0218568,
+  -0.027902,
+  -0.0283208,
+  -0.0240533,
+  -0.0165112,
+  -0.00735151,
+  0.00176699,
+  0.00940928,
+  0.0145415,
+  0.0166372,
+  0.0157018,
+  0.0122173,
+  0.00702171,
+  0.00114403,
+  -0.00437487,
+  -0.00864874,
+  -0.0110744,
+  -0.011405,
+  -0.00976079,
+  -0.00658004,
+  -0.00252213,
+  0.001658,
+  0.00524199,
+  0.00766479,
+  0.00859787,
+  0.00798756,
+  0.00604515,
+  0.00319335,
+  -1.90046e-05,
+  -0.00301796,
+  -0.00530323,
+  -0.00652835,
+  -0.00654985,
+  -0.0054391,
+  -0.00345694,
+  -0.000997692,
+  0.00148629,
+  0.00356541,
+  0.00490513,
+  0.00531776,
+  0.00478613,
+  0.00345676,
+  0.00160526,
+  -0.000418452,
+  -0.00225463,
+  -0.00359628,
+  -0.00423916,
+  -0.0041113,
+  -0.00327808,
+  -0.00192329,
+  -0.000310763,
+  0.00126569,
+  0.00253482,
+  0.00329371,
+  0.00343915,
+  0.00298006,
+  0.00202976,
+  0.000780521,
+  -0.000534171,
+  -0.00168247,
+  -0.00247437,
+  -0.00279243,
+  -0.00260813,
+  -0.00198192,
+  -0.00104765,
+  1.48175e-05,
+  0.00101358,
+  0.00177877,
+  0.00219097,
+  0.00219909,
+  0.00182538,
+  0.0011573,
+  0.000328412,
+  -0.000507584,
+  -0.00120494,
+  -0.00165083,
+  -0.00178311,
+  -0.00159812,
+  -0.00114777,
+  -0.000527025,
+  0.000145346,
+  0.000749102,
+  0.00118367,
+  0.00138452,
+  0.00133217,
+  0.00105267,
+  0.000610043,
+  9.24929e-05,
+  -0.0004047,
+  -0.000796428,
+  -0.00102202,
+  -0.00105423,
+  -0.000901664
+};
diff --git a/codec2/branches/0.7/src/fmfsk.c b/codec2/branches/0.7/src/fmfsk.c
new file mode 100644 (file)
index 0000000..ab56945
--- /dev/null
@@ -0,0 +1,376 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fmfsk.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 6 February 2016
+
+  C Implementation of a FM+ME+FSK modem for FreeDV mode B and other applications
+  (better APRS, anyone?)
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+
+
+#include "fmfsk.h"
+#include "modem_probe.h"
+#include "comp_prim.h"
+
+#define STD_PROC_BITS 96
+
+/* Define this to enable EbNodB estimate */
+/* This needs square roots, may take more cpu time than it's worth */
+#define EST_EBNO
+
+/*
+ * Create a new fmfsk modem instance.
+ * 
+ * int Fs - sample rate
+ * int Rb - non-manchester bitrate
+ * returns - new struct FMFSK on sucess, NULL on failure
+ */
+struct FMFSK * fmfsk_create(int Fs,int Rb){
+    assert( Fs % (Rb*2) == 0 );  /* Sample freq must be divisible by symbol rate */
+    
+    int nbits = STD_PROC_BITS;
+    
+    /* Allocate the struct */
+    struct FMFSK *fmfsk = malloc(sizeof(struct FMFSK));
+    if(fmfsk==NULL) return NULL;
+    
+    /* Set up static parameters */
+    fmfsk->Rb = Rb;
+    fmfsk->Rs = Rb*2;
+    fmfsk->Fs = Fs;
+    fmfsk->Ts = Fs/fmfsk->Rs;
+    fmfsk->N = nbits*2*fmfsk->Ts;
+    fmfsk->nmem = fmfsk->N+(fmfsk->Ts*4);
+    fmfsk->nsym = nbits*2;
+    fmfsk->nbit = nbits;
+    
+    /* Set up demod state */
+    fmfsk->lodd = 0;
+    fmfsk->nin = fmfsk->N;
+    fmfsk->snr_mean = 0;
+    
+    float *oldsamps = malloc(sizeof(float)*fmfsk->nmem);
+    if(oldsamps == NULL){
+        free(fmfsk);
+        return NULL;
+    }
+    
+    fmfsk->oldsamps = oldsamps;
+
+    fmfsk->stats = (struct MODEM_STATS*)malloc(sizeof(struct MODEM_STATS));
+    if (fmfsk->stats == NULL) {
+        free(oldsamps);
+        free(fmfsk);
+        return NULL;
+    }
+    
+    return fmfsk;
+}
+
+/*
+ * Destroys an fmfsk modem and deallocates memory
+ */
+void fmfsk_destroy(struct FMFSK *fmfsk){
+    free(fmfsk->oldsamps);
+    free(fmfsk);
+}
+
+/*
+ * Returns the number of samples that must be fed to fmfsk_demod the next
+ * cycle
+ */
+uint32_t fmfsk_nin(struct FMFSK *fmfsk){
+    return (uint32_t)fmfsk->nin;
+}
+
+void fmfsk_get_demod_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats){
+    /* copy from internal stats, note we can't overwrite stats completely
+       as it has other states rqd by caller, also we want a consistent
+       interface across modem types for the freedv_api.
+    */
+
+    stats->clock_offset = fmfsk->stats->clock_offset;
+    stats->snr_est = fmfsk->stats->snr_est;           // TODO: make this SNR not Eb/No
+    stats->rx_timing = fmfsk->stats->rx_timing;
+    stats->foff = fmfsk->stats->foff;
+
+    stats->neyesamp = fmfsk->stats->neyesamp;
+    stats->neyetr = fmfsk->stats->neyetr;
+    memcpy(stats->rx_eye, fmfsk->stats->rx_eye, sizeof(stats->rx_eye));
+
+    /* these fields not used for FSK so set to something sensible */
+
+    stats->sync = 0;
+    stats->nr = fmfsk->stats->nr;
+    stats->Nc = fmfsk->stats->Nc;
+}
+
+/*
+ * Modulates nbit bits into N samples to be sent through an FM radio
+ * 
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * float mod_out[] - Buffer for N samples of modulated FMFSK
+ * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
+ */
+
+void fmfsk_mod(struct FMFSK *fmfsk, float fmfsk_out[],uint8_t bits_in[]){
+    int i,j;
+    int nbit = fmfsk->nbit;
+    int Ts = fmfsk->Ts;
+    
+    for(i=0; i<nbit; i++){
+        /* Save a manchester-encoded 0 */
+        if(bits_in[i] == 0){
+            for(j=0; j<Ts; j++)
+                fmfsk_out[   j+i*Ts*2] = -1;
+            for(j=0; j<Ts; j++)
+                fmfsk_out[Ts+j+i*Ts*2] =  1;
+        } else {
+        /* Save a manchester-encoded 1 */
+            for(j=0; j<Ts; j++)
+                fmfsk_out[   j+i*Ts*2] =  1;
+            for(j=0; j<Ts; j++)
+                fmfsk_out[Ts+j+i*Ts*2] = -1;
+        }
+    }
+}
+
+/*
+ * Demodulate some number of FMFSK samples. The number of samples to be 
+ *  demodulated can be found by calling fmfsk_nin().
+ * 
+ * struct FMFSK *fsk - FMFSK config/state struct, set up by fsk_create
+ * uint8_t rx_bits[] - Buffer for nbit unpacked bits to be written
+ * float fsk_in[] - nin samples of modualted FMFSK from an FM radio
+ */
+void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]){
+    int i,j,k;
+    int Ts          = fmfsk->Ts;
+    int Fs          = fmfsk->Fs;
+    int Rs          = fmfsk->Rs;
+    int nin         = fmfsk->nin;
+    int N           = fmfsk->N;
+    int nsym        = fmfsk->nsym;
+    int nbit        = fmfsk->nbit;
+    int nmem        = fmfsk->nmem;
+    float *oldsamps = fmfsk->oldsamps;
+    int nold        =  nmem-nin;
+    COMP phi_ft,dphi_ft;    /* Phase and delta-phase for fine timing estimator */
+    float t;
+    COMP x;                 /* Magic fine timing angle */
+    float norm_rx_timing,old_norm_rx_timing,d_norm_rx_timing,appm;
+    int rx_timing,sample_offset;
+    int next_nin;
+    float apeven,apodd;     /* Approx. prob of even or odd stream being correct */
+    float currv,mdiff,lastv;
+    int neyesamp;
+    int neyeoffset;
+    float eye_max;
+    uint8_t mbit;
+    #ifdef EST_EBNO
+    float amp_even = 0, amp_odd = 0, amp_bit, amp_noise;
+    #endif
+    
+    /* Shift in nin samples */
+    memcpy(&oldsamps[0]   , &oldsamps[nmem-nold], sizeof(float)*nold);
+    memcpy(&oldsamps[nold], &fmfsk_in[0]        , sizeof(float)*nin );
+    
+    /* Allocate memory for filtering */
+    float *rx_filt = alloca(sizeof(float)*(nsym+1)*Ts);
+    
+    /* Integrate over Ts input symbols at every offset */
+    for(i=0; i<(nsym+1)*Ts; i++){
+        t=0;
+        /* Integrate over some samples */
+        for(j=i;j<i+Ts;j++){
+            t += oldsamps[j];
+        }
+        rx_filt[i] = t;
+    }
+    
+    /*
+     *  Fine timing estimation
+     *
+     * Estimate fine timing using line at Rs/2 that Manchester encoding provides
+     * We need this to sync up to Manchester codewords.
+     */
+    
+    /* init fine timing extractor */
+    phi_ft.real = 1;
+    phi_ft.imag = 0;
+    
+    /* Set up delta-phase */ 
+    dphi_ft.real = cosf(2*M_PI*((float)Rs)/((float)Fs));
+    dphi_ft.imag = sinf(2*M_PI*((float)Rs)/((float)Fs));
+    
+    x.real = 0;
+    x.imag = 0;
+    
+    for(i=0; i<(nsym+1)*Ts; i++){
+        /* Apply non-linearity */
+        t = rx_filt[i]*rx_filt[i];
+        
+        /* Shift Rs/2 down to DC and accumulate */
+        x = cadd(x,fcmult(t,phi_ft));
+        
+        /* Spin downshift oscillator */
+        phi_ft = cmult(dphi_ft,phi_ft);
+        modem_probe_samp_c("t_phi_ft",&phi_ft,1);
+    }
+    
+    /* Figure out the normalized RX timing, using David's magic number */
+    norm_rx_timing =  atan2f(x.imag,x.real)/(2*M_PI) - .42;
+    rx_timing = (int)lroundf(norm_rx_timing*(float)Ts);
+    
+    old_norm_rx_timing = fmfsk->norm_rx_timing;
+    fmfsk->norm_rx_timing = norm_rx_timing;
+    
+    /* Estimate sample clock offset */
+    d_norm_rx_timing = norm_rx_timing - old_norm_rx_timing;
+    
+    /* Filter out big jumps in due to nin change */
+    if(fabsf(d_norm_rx_timing) < .2){
+        appm = 1e6*d_norm_rx_timing/(float)nsym;
+        fmfsk->ppm = .9*fmfsk->ppm + .1*appm;
+    }
+    
+    /* Figure out how far offset the sample points are */
+    sample_offset = (Ts/2)+Ts+rx_timing-1;
+    
+    /* Request fewer or greater samples next time, if fine timing is far
+     * enough off. This also makes it possible to tolerate clock offsets */
+    next_nin = N;
+    if(norm_rx_timing > -.2)
+        next_nin += Ts/2;
+    if(norm_rx_timing < -.65)
+        next_nin -= Ts/2;
+    fmfsk->nin = next_nin;
+    
+    /* Make first diff of this round the last sample of the last round, 
+     * for the odd stream */
+    lastv = fmfsk->lodd;
+    apeven = 0;
+    apodd = 0;
+    for(i=0; i<nsym; i++){
+        /* Sample a filtered value */
+        currv = rx_filt[sample_offset+(i*Ts)];
+        modem_probe_samp_f("t_symsamp",&currv,1);
+        mdiff = lastv - currv;
+        mbit = mdiff>0 ? 1 : 0;
+        lastv = currv;
+        
+        mdiff = mdiff>0 ? mdiff : 0-mdiff;
+        
+        /* Put bit in it's stream */
+        if((i%2)==1){
+            apeven += mdiff;
+            /* Even stream goes in LSB */
+            rx_bits[i>>1] |= mbit ? 0x1 : 0x0;
+            #ifdef EST_EBNO
+            amp_even += currv * currv;
+            #endif
+        }else{
+            apodd += mdiff;
+            /* Odd in second-to-LSB */
+            rx_bits[i>>1]  = mbit ? 0x2 : 0x0;
+            #ifdef EST_EBNO
+            amp_odd += currv * currv;
+            #endif
+        }
+    }
+    #ifdef EST_EBNO
+    amp_even = sqrt(amp_even);
+    amp_odd = sqrt(amp_odd);
+    #endif
+    if(apeven>apodd){
+        /* Zero out odd bits from output bitstream */
+        for(i=0;i<nbit;i++)
+            rx_bits[i] &= 0x1;
+        #ifdef EST_EBNO
+        amp_bit = amp_even;
+        amp_noise = amp_odd;
+        #endif
+    }else{
+        /* Shift odd bits into LSB and even bits out of existence */
+        for(i=0;i<nbit;i++)
+            rx_bits[i] = (rx_bits[i]&0x2)>>1;
+        #ifdef EST_EBNO
+        amp_bit = amp_odd;
+        amp_noise = amp_even;
+        #endif
+    }
+    
+    /* Save last sample of int stream for next demod round */
+    fmfsk->lodd = lastv;
+    
+    /* Save demod statistics */
+    fmfsk->stats->Nc = 0;
+    fmfsk->stats->nr = 0;
+        
+    /* Clock offset and RX timing are all we know here */
+    fmfsk->stats->clock_offset = fmfsk->ppm;
+    fmfsk->stats->rx_timing = (float)rx_timing;
+        
+    /* Zero out all of the other things */
+    fmfsk->stats->foff = 0;
+
+#ifdef EST_EBNO
+    amp_bit = fabsf(amp_bit - amp_noise);
+    fmfsk->snr_mean *= .9;
+    fmfsk->snr_mean += (amp_bit+1e-6)/(amp_noise+1e-6);
+    fmfsk->stats->snr_est = 20+20*log10f(fmfsk->snr_mean); 
+#else
+    fmfsk->stats->snr_est = 0;
+#endif
+        
+    /* Collect an eye diagram */
+    /* Take a sample for the eye diagrams */
+    neyesamp = fmfsk->stats->neyesamp = Ts*4;
+    neyeoffset = sample_offset+(Ts*2*28);
+        
+    fmfsk->stats->neyetr = 8;
+    for(k=0; k<fmfsk->stats->neyetr; k++)
+        for(j=0; j<neyesamp; j++)                                 
+            fmfsk->stats->rx_eye[k][j] = rx_filt[k*neyesamp+neyeoffset+j];
+    //fmfsk->stats->rx_eye[k][j] = fmfsk_in[k*neyesamp+neyeoffset+j];
+    eye_max = 0;
+        
+    /* Normalize eye to +/- 1 */
+    for(i=0; i<fmfsk->stats->neyetr; i++)
+        for(j=0; j<neyesamp; j++)
+            if(fabsf(fmfsk->stats->rx_eye[i][j])>eye_max)
+                eye_max = fabsf(fmfsk->stats->rx_eye[i][j]);
+        
+    for(i=0; i<fmfsk->stats->neyetr; i++)
+        for(j=0; j<neyesamp; j++)
+            fmfsk->stats->rx_eye[i][j] = (fmfsk->stats->rx_eye[i][j]/(2*eye_max))+.5;
+    
+    modem_probe_samp_f("t_norm_rx_timing",&norm_rx_timing,1);
+    modem_probe_samp_f("t_rx_filt",rx_filt,(nsym+1)*Ts);
+}
diff --git a/codec2/branches/0.7/src/fmfsk.h b/codec2/branches/0.7/src/fmfsk.h
new file mode 100644 (file)
index 0000000..9ec6418
--- /dev/null
@@ -0,0 +1,110 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fmfsk.h
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 6 February 2016
+
+  C Implementation of 2FSK+Manchester over FM modulator/demodulator, based
+  on mancyfsk.m and fmfsk.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __C2FMFSK_H
+#define __C2FMFSK_H
+#include <stdint.h>
+#include "comp.h"
+#include "modem_stats.h"
+
+#define FMFSK_SCALE 16383
+
+/* 
+ * fm-me-2fsk state
+ */
+struct FMFSK{
+    /* Static fmfsk parameters */
+    int Rb;             /* Manchester-encoded bitrate */
+    int Rs;             /* Raw modem symbol rate */
+    int Fs;             /* Sample rate */
+    int Ts;             /* Samples-per-symbol */
+    int N;              /* Sample processing buffer size */
+    int nsym;           /* Number of raw modem symbols processed per demod call */
+    int nbit;           /* Number of bits spit out per demod call */
+    int nmem;           /* Number of samples kept around between demod calls */
+    
+    /* State kept by demod */
+    int nin;            /* Number of samples to be demod-ed the next cycle */
+    int lodd;           /* Last integrated sample for odd bitstream generation */
+    float * oldsamps;   /* Memory of old samples to make clock-offset-tolerance possible */
+    
+    /* Stats generated by demod */
+    float norm_rx_timing; /* RX Timing, used to calculate clock offset */
+    int ppm;                   /* Clock offset in parts-per-million */
+    float snr_mean;
+    
+    /* Modem stat structure */
+    struct MODEM_STATS * stats;
+};
+
+/*
+ * Create a new fmfsk modem instance.
+ * 
+ * int Fs - sample rate
+ * int Rb - non-manchester bitrate
+ * returns - new struct FMFSK on sucess, NULL on failure
+ */
+struct FMFSK * fmfsk_create(int Fs,int Rb);
+
+/*
+ * Destroys an fmfsk modem and deallocates memory
+ */
+void fmfsk_destroy(struct FMFSK *fmfsk);
+
+/*
+ * Deposit demod statistics into a MODEM_STATS struct
+ */
+void fmfsk_get_demod_stats(struct FMFSK *fmfsk,struct MODEM_STATS *stats);
+
+/*
+ * Returns the number of samples that must be fed to fmfsk_demod the next
+ * cycle
+ */
+uint32_t fmfsk_nin(struct FMFSK *fmfsk);
+
+/*
+ * Modulates nbit bits into N samples to be sent through an FM radio
+ * 
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * float mod_out[] - Buffer for N samples of modulated FMFSK
+ * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
+ */
+void fmfsk_mod(struct FMFSK *fmfsk, float fmfsk_out[],uint8_t bits_in[]);
+
+
+/*
+ * Demodulate some number of FMFSK samples. The number of samples to be 
+ *  demodulated can be found by calling fmfsk_nin().
+ * 
+ * struct FMFSK *fsk - FMFSK config/state struct, set up by fsk_create
+ * uint8_t rx_bits[] - Buffer for nbit unpacked bits to be written
+ * float fsk_in[] - nin samples of modualted FMFSK from an FM radio
+ */
+void fmfsk_demod(struct FMFSK *fmfsk, uint8_t rx_bits[],float fmfsk_in[]);
+
+#endif
diff --git a/codec2/branches/0.7/src/fmfsk_demod.c b/codec2/branches/0.7/src/fmfsk_demod.c
new file mode 100644 (file)
index 0000000..1421c87
--- /dev/null
@@ -0,0 +1,144 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk_demod.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 8 January 2016
+
+  C test driver for fsk_demod in fsk.c. Reads in a stream of 32 bit cpu endian
+  floats and writes out the detected bits
+   
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include "fmfsk.h"
+#include "modem_stats.h"
+#define MODEMPROBE_ENABLE
+#include "modem_probe.h"
+#include "codec2_fdmdv.h"
+
+int main(int argc,char *argv[]){
+    struct FMFSK *fmfsk;
+    int Fs,Rb;
+    struct MODEM_STATS stats;
+    float loop_time;
+    int enable_stats = 0;
+    int stats_ctr = 0;
+    int stats_loop = 0;
+    FILE *fin,*fout;
+    uint8_t *bitbuf;
+    int16_t *rawbuf;
+    float *modbuf;
+    int i,j,t;
+    
+    if(argc<4){
+        fprintf(stderr,"usage: %s SampleFreq BitRate InputModemRawFile OutputOneBitPerCharFile [S]\n",argv[0]);
+        exit(1);
+    }
+    
+    /* Extract parameters */
+    Fs = atoi(argv[1]);
+    Rb = atoi(argv[2]);
+    
+    /* Open files */
+    if(strcmp(argv[3],"-")==0){
+       fin = stdin;
+    }else{
+       fin = fopen(argv[3],"r");
+    }
+       
+    if(strcmp(argv[4],"-")==0){
+       fout = stdout;
+    }else{
+       fout = fopen(argv[4],"w");
+    }
+       
+    /* set up FSK */
+    fmfsk = fmfsk_create(Fs,Rb);
+
+    if(argc>5){
+       if(strcmp(argv[5],"S")==0){
+           enable_stats = 1;
+           loop_time = ((float)fmfsk_nin(fmfsk))/((float)Fs);
+           stats_loop = (int)(.125/loop_time);
+           stats_ctr = 0;
+       }
+    }
+    
+    if(fin==NULL || fout==NULL || fmfsk==NULL){
+        fprintf(stderr,"Couldn't open test vector files\n");
+        goto cleanup;
+    }
+    
+    /* allocate buffers for processing */
+    bitbuf = (uint8_t*)alloca(sizeof(uint8_t)*fmfsk->nbit);
+    rawbuf = (int16_t*)alloca(sizeof(int16_t)*(fmfsk->N+fmfsk->Ts*2));
+    modbuf = (float*)alloca(sizeof(float)*(fmfsk->N+fmfsk->Ts*2));
+    
+    /* Demodulate! */
+    while( fread(rawbuf,sizeof(int16_t),fmfsk_nin(fmfsk),fin) == fmfsk_nin(fmfsk) ){
+       for(i=0;i<fmfsk_nin(fmfsk);i++){
+           modbuf[i] = ((float)rawbuf[i])/FDMDV_SCALE;
+       }
+       
+       modem_probe_samp_f("t_d_sampin",modbuf,fmfsk_nin(fmfsk));
+        fmfsk_demod(fmfsk,bitbuf,modbuf);
+        
+       for(i=0;i<fmfsk->nbit;i++){
+           t = (int)bitbuf[i];
+           modem_probe_samp_i("t_d_bitout",&t,1);
+       }
+        
+       fwrite(bitbuf,sizeof(uint8_t),fmfsk->nbit,fout);
+        
+       if(enable_stats && stats_ctr <= 0){
+           fmfsk_get_demod_stats(fmfsk,&stats);
+           fprintf(stderr,"{\"EbNodB\": %2.2f,\t\"ppm\": %d,",stats.snr_est,(int)stats.clock_offset);
+           fprintf(stderr,"\t\"f1_est\":%.1f,\t\"f2_est\":%.1f",0.0,0.0);
+           fprintf(stderr,",\t\"eye_diagram\":[");
+           for(i=0;i<stats.neyetr;i++){
+               fprintf(stderr,"[");
+               for(j=0;j<stats.neyesamp;j++){
+                   fprintf(stderr,"%f",stats.rx_eye[i][j]);
+                   if(j<stats.neyesamp-1) fprintf(stderr,",");
+               }
+               fprintf(stderr,"]");
+               if(i<stats.neyetr-1) fprintf(stderr,",");
+           }
+           
+           fprintf(stderr,"]}\n");
+           stats_ctr = stats_loop;
+       }
+       stats_ctr--;
+       
+        if(fin == stdin || fout == stdin){
+           fflush(fin);
+           fflush(fout);
+       }
+    }
+    
+    modem_probe_close();
+    cleanup:
+    fclose(fin);
+    fclose(fout);
+    fmfsk_destroy(fmfsk);
+    exit(0);
+}
+
diff --git a/codec2/branches/0.7/src/fmfsk_mod.c b/codec2/branches/0.7/src/fmfsk_mod.c
new file mode 100644 (file)
index 0000000..ae73982
--- /dev/null
@@ -0,0 +1,99 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fmfsk_mod.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 7 February 2016
+
+  C test driver for fmfsk_mod in fmfsk.c. Reads in a set of bits to modulate
+   from a file, passed as a parameter, and writes modulated output to
+   another file
+   
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "fmfsk.h"
+#include "codec2_fdmdv.h"
+
+int main(int argc,char *argv[]){
+    struct FMFSK *fmfsk;
+    int Fs,Rb;
+    int i;
+    FILE *fin,*fout;
+    uint8_t *bitbuf;
+    int16_t *rawbuf;
+    float *modbuf;
+    
+    if(argc<4){
+        fprintf(stderr,"usage: %s SampleFreq BitRate InputOneBitPerCharFile OutputModRawFile\n",argv[0]);
+        exit(1);
+    }
+    
+    /* Extract parameters */
+    Fs = atoi(argv[1]);
+    Rb = atoi(argv[2]);
+    
+    if(strcmp(argv[3],"-")==0){
+               fin = stdin;
+       }else{
+               fin = fopen(argv[3],"r");
+       }
+       
+       if(strcmp(argv[4],"-")==0){
+               fout = stdout;
+       }else{
+               fout = fopen(argv[4],"w");
+       }
+    
+    
+    /* set up FMFSK */
+    fmfsk = fmfsk_create(Fs,Rb);
+    
+    if(fin==NULL || fout==NULL || fmfsk==NULL){
+        fprintf(stderr,"Couldn't open test vector files\n");
+        goto cleanup;
+    }
+    
+    /* allocate buffers for processing */
+    bitbuf = (uint8_t*)alloca(sizeof(uint8_t)*fmfsk->nbit);
+    rawbuf = (int16_t*)alloca(sizeof(int16_t)*fmfsk->N);
+    modbuf = (float*)alloca(sizeof(float)*fmfsk->N);
+    
+    /* Modulate! */
+    while( fread(bitbuf,sizeof(uint8_t),fmfsk->nbit,fin) == fmfsk->nbit ){
+        fmfsk_mod(fmfsk,modbuf,bitbuf);
+        for(i=0; i<fmfsk->N; i++){
+           rawbuf[i] = (int16_t)(modbuf[i]*(float)FDMDV_SCALE);
+       }
+        fwrite(rawbuf,sizeof(int16_t),fmfsk->N,fout);
+        
+       if(fin == stdin || fout == stdin){
+           fflush(fin);
+           fflush(fout);
+       }
+    }
+    
+    cleanup:
+    fclose(fin);
+    fclose(fout);
+    fmfsk_destroy(fmfsk);
+    exit(0);
+}
diff --git a/codec2/branches/0.7/src/fq20.sh b/codec2/branches/0.7/src/fq20.sh
new file mode 100755 (executable)
index 0000000..b83784b
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+# fq20.shsh
+# David Rowe 27 July 2010
+# 
+# Decode a file with fully quantised codec at 20ms frame rate
+
+../src/sinedec ../raw/$1.raw $1.mdl -o $1_phase0_lsp_20_EWo2.raw --phase 0 --lpc 10 --lsp --postfilter --dec
+
diff --git a/codec2/branches/0.7/src/freedv_api.c b/codec2/branches/0.7/src/freedv_api.c
new file mode 100644 (file)
index 0000000..f0aafcf
--- /dev/null
@@ -0,0 +1,1782 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_api.c
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2014
+
+  Library of API functions that implement FreeDV "modes", useful for
+  embedding FreeDV in other programs.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#ifdef __APPLE__
+#include <malloc/malloc.h>
+#else
+#include <malloc.h>
+#endif /* __APPLE__ */
+
+#include "fsk.h"
+#include "fmfsk.h"
+#include "codec2.h"
+#include "codec2_fdmdv.h"
+#include "fdmdv_internal.h"
+#include "golay23.h"
+#include "varicode.h"
+#include "freedv_api.h"
+#include "freedv_api_internal.h"
+#include "freedv_vhf_framing.h"
+#include "comp_prim.h"
+
+#define VERSION     11    /* The API version number.  The first version
+                           is 10.  Increment if the API changes in a
+                           way that would require changes by the API
+                           user. */
+/*
+ * Version 10   Initial version August 2, 2015.
+ * Version 11   September 2015
+ *              Added: freedv_zero_total_bit_errors(), freedv_get_sync()
+ *              Changed all input and output sample rates to 8000 sps.  Rates for FREEDV_MODE_700 and 700B were 7500.
+ */
+
+#define NORM_PWR_COHPSK  1.74   /* experimentally derived fudge factor to normalise power for cohpsk modes */
+#define NORM_PWR_FSK     0.193  /* experimentally derived fudge factor to normalise power for fsk modes    */
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_open
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 August 2014
+
+  Call this first to initialise.  Returns NULL if initialisation fails
+  (e.g. out of memory or mode not supported).
+
+\*---------------------------------------------------------------------------*/
+
+struct freedv *freedv_open(int mode) {
+    struct freedv *f;
+    int            Nc, codec2_mode, nbit, nbyte;
+
+    if ((mode != FREEDV_MODE_1600) && (mode != FREEDV_MODE_700) && 
+        (mode != FREEDV_MODE_700B) && (mode != FREEDV_MODE_2400A) &&
+        (mode != FREEDV_MODE_2400B) && (mode != FREEDV_MODE_800XA) &&
+        (mode != FREEDV_MODE_700C))
+        return NULL;
+
+    f = (struct freedv*)malloc(sizeof(struct freedv));
+    if (f == NULL)
+        return NULL;
+
+    f->mode = mode;
+    f->test_frames = f->smooth_symbols = 0;
+    f->freedv_put_error_pattern = NULL;
+    f->error_pattern_callback_state = NULL;
+    f->n_protocol_bits = 0;
+
+    if (mode == FREEDV_MODE_1600) {
+        f->snr_squelch_thresh = 2.0;
+        f->squelch_en = 1;
+        Nc = 16;
+        f->tx_sync_bit = 0;
+        codec2_mode = CODEC2_MODE_1300;
+        f->fdmdv = fdmdv_create(Nc);
+        if (f->fdmdv == NULL)
+            return NULL;
+        golay23_init();
+        f->nin = FDMDV_NOM_SAMPLES_PER_FRAME;
+        f->n_nom_modem_samples = 2*FDMDV_NOM_SAMPLES_PER_FRAME;
+        f->n_nat_modem_samples = f->n_nom_modem_samples;
+        f->n_max_modem_samples = FDMDV_NOM_SAMPLES_PER_FRAME+FDMDV_MAX_SAMPLES_PER_FRAME;
+        f->modem_sample_rate = FS;
+        nbit = fdmdv_bits_per_frame(f->fdmdv);
+        f->fdmdv_bits = (int*)malloc(nbit*sizeof(int));
+        if (f->fdmdv_bits == NULL)
+            return NULL;
+        nbit = 2*fdmdv_bits_per_frame(f->fdmdv);
+        f->tx_bits = (int*)malloc(nbit*sizeof(int));
+        f->rx_bits = (int*)malloc(nbit*sizeof(int));
+        if ((f->tx_bits == NULL) || (f->rx_bits == NULL))
+            return NULL;
+        f->evenframe = 0;
+        f->sz_error_pattern = fdmdv_error_pattern_size(f->fdmdv);
+    }
+
+#ifndef CORTEX_M4
+    if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C)) {
+        f->snr_squelch_thresh = 0.0;
+        f->squelch_en = 0;
+        switch(mode) {
+        case FREEDV_MODE_700:
+            codec2_mode = CODEC2_MODE_700;
+            break;
+        case FREEDV_MODE_700B:
+            codec2_mode = CODEC2_MODE_700B;
+            break;
+        case FREEDV_MODE_700C:
+            codec2_mode = CODEC2_MODE_700C;
+            break;
+        default:
+            assert(0);
+        }
+
+        f->cohpsk = cohpsk_create();
+        f->nin = COHPSK_NOM_SAMPLES_PER_FRAME;
+        f->n_nat_modem_samples = COHPSK_NOM_SAMPLES_PER_FRAME;             // native modem samples as used by the modem
+        f->n_nom_modem_samples = f->n_nat_modem_samples * FS / COHPSK_FS;  // number of samples after native samples are interpolated to 8000 sps
+        f->n_max_modem_samples = COHPSK_MAX_SAMPLES_PER_FRAME * FS / COHPSK_FS + 1;
+        f->modem_sample_rate = FS;                                         /* note wierd sample rate tamed by interpolator */
+        f->clip = 1;
+        nbit = COHPSK_BITS_PER_FRAME;
+        f->tx_bits = (int*)malloc(nbit*sizeof(int));
+        if (f->tx_bits == NULL)
+            return NULL;
+        f->sz_error_pattern = cohpsk_error_pattern_size();
+    }
+#endif  
+    if ((mode == FREEDV_MODE_2400A) || (mode == FREEDV_MODE_2400B)) {
+      
+        /* Set up the C2 mode */
+        codec2_mode = CODEC2_MODE_1300;
+        /* Set the number of protocol bits */
+        f->n_protocol_bits = 20;
+        f->sz_error_pattern = 0;
+    }
+    
+    if (mode == FREEDV_MODE_2400A) {
+        /* Create the framer|deframer */
+        f->deframer = fvhff_create_deframer(FREEDV_VHF_FRAME_A,0);
+        if(f->deframer == NULL)
+            return NULL;
+  
+        f->fsk = fsk_create_hbr(48000,1200,10,4,1200,1200);
+        
+        /* Note: fsk expects tx/rx bits as an array of uint8_ts, not ints */
+        f->tx_bits = (int*)malloc(f->fsk->Nbits*sizeof(uint8_t));
+        
+        if(f->fsk == NULL){
+            fvhff_destroy_deframer(f->deframer);
+            return NULL;
+        }
+        
+        f->n_nom_modem_samples = f->fsk->N;
+        f->n_max_modem_samples = f->fsk->N + (f->fsk->Ts);
+        f->n_nat_modem_samples = f->fsk->N;
+        f->nin = fsk_nin(f->fsk);
+        f->modem_sample_rate = 48000;
+        /* Malloc something to appease freedv_init and freedv_destroy */
+        f->codec_bits = malloc(1);
+    }
+    
+    if (mode == FREEDV_MODE_2400B) {
+        /* Create the framer|deframer */
+        f->deframer = fvhff_create_deframer(FREEDV_VHF_FRAME_A,1);
+        if(f->deframer == NULL)
+            return NULL;
+        
+        f->fmfsk = fmfsk_create(48000,2400);
+         
+        if(f->fmfsk == NULL){
+            fvhff_destroy_deframer(f->deframer);
+            return NULL;
+        }
+        /* Note: fsk expects tx/rx bits as an array of uint8_ts, not ints */
+        f->tx_bits = (int*)malloc(f->fmfsk->nbit*sizeof(uint8_t));
+        
+        f->n_nom_modem_samples = f->fmfsk->N;
+        f->n_max_modem_samples = f->fmfsk->N + (f->fmfsk->Ts);
+        f->n_nat_modem_samples = f->fmfsk->N;
+        f->nin = fmfsk_nin(f->fmfsk);
+        f->modem_sample_rate = 48000;
+        /* Malloc something to appease freedv_init and freedv_destroy */
+        f->codec_bits = malloc(1);
+    }
+    
+    if (mode == FREEDV_MODE_800XA) {
+        /* Create the framer|deframer */
+        f->deframer = fvhff_create_deframer(FREEDV_HF_FRAME_B,0);
+        if(f->deframer == NULL)
+            return NULL;
+  
+        f->fsk = fsk_create_hbr(8000,400,10,4,800,400);
+        fsk_set_nsym(f->fsk,32);
+        
+        /* Note: fsk expects tx/rx bits as an array of uint8_ts, not ints */
+        f->tx_bits = (int*)malloc(f->fsk->Nbits*sizeof(uint8_t));
+        
+        if(f->fsk == NULL){
+            fvhff_destroy_deframer(f->deframer);
+            return NULL;
+        }
+        
+        f->n_nom_modem_samples = f->fsk->N;
+        f->n_max_modem_samples = f->fsk->N + (f->fsk->Ts);
+        f->n_nat_modem_samples = f->fsk->N;
+        f->nin = fsk_nin(f->fsk);
+        f->modem_sample_rate = 8000;
+        /* Malloc something to appease freedv_init and freedv_destroy */
+        f->codec_bits = malloc(1);
+        
+        f->n_protocol_bits = 0;
+        codec2_mode = CODEC2_MODE_700C;
+        fsk_stats_normalise_eye(f->fsk, 0);
+        f->sz_error_pattern = 0;
+    }
+    
+
+    f->test_frames_diversity = 1;
+    f->test_frame_sync_state = 0;
+    f->test_frame_sync_state_upper = 0;
+    f->total_bits = 0;
+    f->total_bit_errors = 0;
+
+    f->codec2 = codec2_create(codec2_mode);
+    if (f->codec2 == NULL)
+        return NULL;
+    if ((mode == FREEDV_MODE_1600) || (mode == FREEDV_MODE_2400A) || (mode == FREEDV_MODE_2400B)) {
+        f->n_speech_samples = codec2_samples_per_frame(f->codec2);
+        f->n_codec_bits = codec2_bits_per_frame(f->codec2);
+        nbit = f->n_codec_bits;
+        nbyte = (nbit + 7) / 8;
+    } else if ((mode == FREEDV_MODE_800XA)) {
+        f->n_speech_samples = 2*codec2_samples_per_frame(f->codec2);
+        f->n_codec_bits = codec2_bits_per_frame(f->codec2);
+        nbit = f->n_codec_bits;
+        nbyte = (nbit + 7) / 8;
+        nbyte = nbyte*2;
+        nbit = 8*nbyte;
+        f->n_codec_bits = nbit;
+    } else { /* ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C)) */
+        f->n_speech_samples = 2*codec2_samples_per_frame(f->codec2);
+        f->n_codec_bits = 2*codec2_bits_per_frame(f->codec2);
+        nbit = f->n_codec_bits;
+        nbyte = 2*((codec2_bits_per_frame(f->codec2) + 7) / 8);
+    }
+    
+    f->prev_rx_bits = (float*)malloc(sizeof(float)*2*codec2_bits_per_frame(f->codec2));
+    if (f->prev_rx_bits == NULL)
+        return NULL;
+
+    f->packed_codec_bits = (unsigned char*)malloc(nbyte*sizeof(char));
+    if (mode == FREEDV_MODE_1600)
+        f->codec_bits = (int*)malloc(nbit*sizeof(int));
+    if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C))
+        f->codec_bits = (int*)malloc(COHPSK_BITS_PER_FRAME*sizeof(int));
+    
+    /* Note: VHF Framer/deframer goes directly from packed codec/vc/proto bits to filled frame */
+    if ((f->packed_codec_bits == NULL) || (f->codec_bits == NULL))
+        return NULL;
+
+    if ((mode == FREEDV_MODE_700) || (mode == FREEDV_MODE_700B) || (mode == FREEDV_MODE_700C) ) {        // change modem rates to 8000 sps
+        f->ptFilter7500to8000 = (struct quisk_cfFilter *)malloc(sizeof(struct quisk_cfFilter));
+        f->ptFilter8000to7500 = (struct quisk_cfFilter *)malloc(sizeof(struct quisk_cfFilter));
+        quisk_filt_cfInit(f->ptFilter8000to7500, quiskFilt120t480, sizeof(quiskFilt120t480)/sizeof(float));
+        quisk_filt_cfInit(f->ptFilter7500to8000, quiskFilt120t480, sizeof(quiskFilt120t480)/sizeof(float));
+    }
+    else {
+        f->ptFilter7500to8000 = NULL;
+        f->ptFilter8000to7500 = NULL;
+    }
+
+    varicode_decode_init(&f->varicode_dec_states, 1);
+    f->nvaricode_bits = 0;
+    f->varicode_bit_index = 0;
+    f->freedv_get_next_tx_char = NULL;
+    f->freedv_put_next_rx_char = NULL;
+       f->freedv_put_next_proto = NULL;
+       f->freedv_get_next_proto = NULL;
+    f->total_bit_errors = 0;
+
+    return f;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_close
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 August 2014
+
+  Frees up memory.
+
+\*---------------------------------------------------------------------------*/
+
+void freedv_close(struct freedv *freedv) {
+    assert(freedv != NULL);
+
+    free(freedv->prev_rx_bits);
+    free(freedv->packed_codec_bits);
+    free(freedv->codec_bits);
+    free(freedv->tx_bits);
+    if (freedv->mode == FREEDV_MODE_1600)
+        fdmdv_destroy(freedv->fdmdv);
+#ifndef CORTEX_M4
+    if ((freedv->mode == FREEDV_MODE_700) || (freedv->mode == FREEDV_MODE_700B) || (freedv->mode == FREEDV_MODE_700C))
+        cohpsk_destroy(freedv->cohpsk);
+#endif
+    if ((freedv->mode == FREEDV_MODE_2400A) || (freedv->mode == FREEDV_MODE_800XA)){
+        fsk_destroy(freedv->fsk);
+        fvhff_destroy_deframer(freedv->deframer);
+       }
+    
+    if (freedv->mode == FREEDV_MODE_2400B){
+        fmfsk_destroy(freedv->fmfsk);
+               fvhff_destroy_deframer(freedv->deframer);
+    }
+    
+    codec2_destroy(freedv->codec2);
+    if (freedv->ptFilter8000to7500) {
+        quisk_filt_destroy(freedv->ptFilter8000to7500);
+        free(freedv->ptFilter8000to7500);
+        freedv->ptFilter8000to7500 = NULL;
+    }
+    if (freedv->ptFilter7500to8000) {
+        quisk_filt_destroy(freedv->ptFilter7500to8000);
+        free(freedv->ptFilter7500to8000);
+        freedv->ptFilter7500to8000 = NULL;
+    }
+    free(freedv);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_tx
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 August 2014
+
+  Takes a frame of input speech samples, encodes and modulates them to
+  produce a frame of modem samples that can be sent to the
+  transmitter.  See freedv_tx.c for an example.
+
+  speech_in[] is sampled at 8000 Hz, and the user must supply a block
+  of exactly freedv_get_n_speech_samples(). The speech_in[] level
+  should be such that the peak speech level is between +/- 16384 and
+  +/- 32767.
+
+  The FDM modem signal mod_out[] is sampled at 8000 Hz and is
+  freedv_get_n_nom_modem_samples() long.  mod_out[] will be scaled
+  such that the peak level is just less than +/-32767.
+
+  The complex-valued output can directly drive an I/Q modulator to
+  produce a single sideband signal.  To generate the other sideband,
+  take the complex conjugate of mod_out[].
+
+  The FreeDV 1600 modem has a high crest factor (around 12dB), however
+  the energy and duration of the peaks is small.  FreeDV 1600 is
+  usually operated at a "backoff" of 8dB.  Adjust the power amplifier
+  drive so that the average power is 8dB less than the peak power of
+  the PA.  For example, on a radio rated at 100W PEP for SSB, the
+  average FreeDV power is typically 20W.
+
+  The FreeDV 700 modem has a crest factor of about 8dB (with
+  f->clip=1, the default), so if your PA can handle it, it can be
+  driven harder than FreeDV 1600.  Caution - some PAs cannot handle a
+  high continuous power.  A conservative level is 20W average for a
+  100W PEP rated PA.
+
+\*---------------------------------------------------------------------------*/
+
+/* real-valued short sample output, useful for going straight to DAC */
+
+/* TX routines for 2400 FSK modes, after codec2 encoding */
+static void freedv_tx_fsk_voice(struct freedv *f, short mod_out[]) {
+    int  i;
+    float *tx_float; /* To hold on to modulated samps from fsk/fmfsk */
+    uint8_t vc_bits[2]; /* Varicode bits for 2400 framing */
+    uint8_t proto_bits[3]; /* Prococol bits for 2400 framing */
+        
+    /* Frame for 2400A/B */
+    if(f->mode == FREEDV_MODE_2400A || f->mode == FREEDV_MODE_2400B){
+        /* Get varicode bits for TX and possibly ask for a new char */
+        /* 2 bits per 2400A/B frame, so this has to be done twice */
+        for(i=0;i<2;i++){
+            if (f->nvaricode_bits) {
+                vc_bits[i] = f->tx_varicode_bits[f->varicode_bit_index++];
+                f->nvaricode_bits--;
+            }
+
+            if (f->nvaricode_bits == 0) {
+                /* get new char and encode */
+                char s[2];
+                if (f->freedv_get_next_tx_char != NULL) {
+                    s[0] = (*f->freedv_get_next_tx_char)(f->callback_state);
+                    f->nvaricode_bits = varicode_encode(f->tx_varicode_bits, s, VARICODE_MAX_BITS, 1, 1);
+                    f->varicode_bit_index = 0;
+                }
+            }
+        }
+            
+        /* If the API user hasn't set up message callbacks, don't bother with varicode bits */
+        if(f->freedv_get_next_proto != NULL){
+            (*f->freedv_get_next_proto)(f->proto_callback_state,(char*)proto_bits);
+            fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),proto_bits,vc_bits);
+        }else if(f->freedv_get_next_tx_char != NULL){
+            fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),NULL,vc_bits);
+        }else {
+            fvhff_frame_bits(FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),NULL,NULL);
+        }
+    /* Frame for 800XA */
+    }else if(f->mode == FREEDV_MODE_800XA){
+        fvhff_frame_bits(FREEDV_HF_FRAME_B,(uint8_t*)(f->tx_bits),(uint8_t*)(f->packed_codec_bits),NULL,NULL);
+    }
+        
+    /* Allocate floating point buffer for FSK mod */
+    tx_float = alloca(sizeof(float)*f->n_nom_modem_samples);
+        
+    /* do 4fsk mod */
+    if(f->mode == FREEDV_MODE_2400A || f->mode == FREEDV_MODE_800XA){
+        fsk_mod(f->fsk,tx_float,(uint8_t*)(f->tx_bits));
+        /* Convert float samps to short */
+        for(i=0; i<f->n_nom_modem_samples; i++){
+            mod_out[i] = (short)(tx_float[i]*FSK_SCALE*NORM_PWR_FSK);
+        }
+    /* do me-fsk mod */
+    }else if(f->mode == FREEDV_MODE_2400B){
+        fmfsk_mod(f->fmfsk,tx_float,(uint8_t*)(f->tx_bits));
+        /* Convert float samps to short */
+        for(i=0; i<f->n_nom_modem_samples; i++){
+            mod_out[i] = (short)(tx_float[i]*FMFSK_SCALE);
+        }
+    }
+}
+
+/* TX routines for 2400 FSK modes, data channel */
+static void freedv_tx_fsk_data(struct freedv *f, short mod_out[]) {
+    int  i;
+    float *tx_float; /* To hold on to modulated samps from fsk/fmfsk */
+    
+    if (f->mode != FREEDV_MODE_800XA)
+       fvhff_frame_data_bits(f->deframer, FREEDV_VHF_FRAME_A,(uint8_t*)(f->tx_bits));
+    else
+        fvhff_frame_data_bits(f->deframer, FREEDV_HF_FRAME_B,(uint8_t*)(f->tx_bits));
+        
+    /* Allocate floating point buffer for FSK mod */
+    tx_float = alloca(sizeof(float)*f->n_nom_modem_samples);
+        
+    /* do 4fsk mod */
+    if(f->mode == FREEDV_MODE_2400A || f->mode == FREEDV_MODE_800XA){
+        fsk_mod(f->fsk,tx_float,(uint8_t*)(f->tx_bits));
+        /* Convert float samps to short */
+        for(i=0; i<f->n_nom_modem_samples; i++){
+            mod_out[i] = (short)(tx_float[i]*FSK_SCALE);
+        }
+    /* do me-fsk mod */
+    }else if(f->mode == FREEDV_MODE_2400B){
+        fmfsk_mod(f->fmfsk,tx_float,(uint8_t*)(f->tx_bits));
+        /* Convert float samps to short */
+        for(i=0; i<f->n_nom_modem_samples; i++){
+            mod_out[i] = (short)(tx_float[i]*FMFSK_SCALE);
+        }
+    }
+}
+
+void freedv_tx(struct freedv *f, short mod_out[], short speech_in[]) {
+    assert(f != NULL);
+    COMP tx_fdm[f->n_nom_modem_samples];
+    int  i;
+    assert((f->mode == FREEDV_MODE_1600)  || (f->mode == FREEDV_MODE_700)   || 
+           (f->mode == FREEDV_MODE_700B)  || (f->mode == FREEDV_MODE_700C)  || 
+           (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || 
+           (f->mode == FREEDV_MODE_800XA));
+    
+    /* FSK and MEFSK/FMFSK modems work only on real samples. It's simpler to just 
+     * stick them in the real sample tx/rx functions than to add a comp->real converter
+     * to comptx */
+     
+    if((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA)){
+        /* 800XA has two codec frames per modem frame */
+        if((f->mode == FREEDV_MODE_800XA)){
+            codec2_encode(f->codec2, &f->packed_codec_bits[0], &speech_in[  0]);
+            codec2_encode(f->codec2, &f->packed_codec_bits[4], &speech_in[320]);
+        }else{
+            codec2_encode(f->codec2, f->packed_codec_bits, speech_in);
+        }
+        freedv_tx_fsk_voice(f, mod_out);
+    }else{
+        freedv_comptx(f, tx_fdm, speech_in);
+        for(i=0; i<f->n_nom_modem_samples; i++)
+            mod_out[i] = tx_fdm[i].real;
+    }
+}
+
+/* complex valued output, useful for suitable for single sided freq shifting */
+
+static void freedv_comptx_fdmdv_1600(struct freedv *f, COMP mod_out[]) {
+    int    bit, byte, i, j;
+    int    bits_per_codec_frame, bits_per_modem_frame;
+    int    data, codeword1, data_flag_index;
+    COMP   tx_fdm[f->n_nat_modem_samples];
+
+    bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+    bits_per_modem_frame = fdmdv_bits_per_frame(f->fdmdv);
+
+    /* unpack bits, MSB first */
+
+    bit = 7; byte = 0;
+    for(i=0; i<bits_per_codec_frame; i++) {
+        f->codec_bits[i] = (f->packed_codec_bits[byte] >> bit) & 0x1;
+        bit--;
+        if (bit < 0) {
+            bit = 7;
+            byte++;
+        }
+    }
+
+    // spare bit in frame that codec defines.  Use this 1
+    // bit/frame to send txt messages
+
+    data_flag_index = codec2_get_spare_bit_index(f->codec2);
+
+    if (f->nvaricode_bits) {
+        f->codec_bits[data_flag_index] = f->tx_varicode_bits[f->varicode_bit_index++];
+        f->nvaricode_bits--;
+    }
+
+    if (f->nvaricode_bits == 0) {
+        /* get new char and encode */
+        char s[2];
+        if (f->freedv_get_next_tx_char != NULL) {
+            s[0] = (*f->freedv_get_next_tx_char)(f->callback_state);
+            f->nvaricode_bits = varicode_encode(f->tx_varicode_bits, s, VARICODE_MAX_BITS, 1, 1);
+            f->varicode_bit_index = 0;
+        }
+    }
+
+    /* Protect first 12 out of first 16 excitation bits with (23,12) Golay Code:
+
+       0,1,2,3: v[0]..v[1]
+       4,5,6,7: MSB of pitch
+       11,12,13,14: MSB of energy
+
+    */
+
+    data = 0;
+    for(i=0; i<8; i++) {
+        data <<= 1;
+        data |= f->codec_bits[i];
+    }
+    for(i=11; i<15; i++) {
+        data <<= 1;
+        data |= f->codec_bits[i];
+    }
+    codeword1 = golay23_encode(data);
+
+    /* now pack output frame with parity bits at end to make them
+       as far apart as possible from the data they protect.  Parity
+       bits are LSB of the Golay codeword */
+
+    for(i=0; i<bits_per_codec_frame; i++)
+        f->tx_bits[i] = f->codec_bits[i];
+    for(j=0; i<bits_per_codec_frame+11; i++,j++) {
+        f->tx_bits[i] = (codeword1 >> (10-j)) & 0x1;
+    }
+    f->tx_bits[i] = 0; /* spare bit */
+
+    /* optionally overwrite with test frames */
+
+    if (f->test_frames) {
+        fdmdv_get_test_bits(f->fdmdv, f->tx_bits);
+        fdmdv_get_test_bits(f->fdmdv, &f->tx_bits[bits_per_modem_frame]);
+        //fprintf(stderr, "test frames on tx\n");
+    }
+
+    /* modulate even and odd frames */
+
+    fdmdv_mod(f->fdmdv, tx_fdm, f->tx_bits, &f->tx_sync_bit);
+    assert(f->tx_sync_bit == 1);
+
+    fdmdv_mod(f->fdmdv, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &f->tx_bits[bits_per_modem_frame], &f->tx_sync_bit);
+    assert(f->tx_sync_bit == 0);
+
+    assert(2*FDMDV_NOM_SAMPLES_PER_FRAME == f->n_nom_modem_samples);
+
+    for(i=0; i<f->n_nom_modem_samples; i++)
+        mod_out[i] = fcmult(FDMDV_SCALE, tx_fdm[i]);
+}
+
+#ifndef CORTEX_M4
+static void freedv_comptx_fdmdv_700(struct freedv *f, COMP mod_out[]) {
+    int    bit, byte, i, j, k;
+    int    bits_per_codec_frame, bits_per_modem_frame;
+    int    data_flag_index, nspare;
+    COMP   tx_fdm[f->n_nat_modem_samples];
+
+    bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+    bits_per_modem_frame = COHPSK_BITS_PER_FRAME;
+
+    byte = 0;
+    for (j=0; j<bits_per_modem_frame; j+=bits_per_codec_frame) {
+
+        /* unpack bits, MSB first */
+
+        bit = 7;
+        for(i=0; i<bits_per_codec_frame; i++) {
+            f->codec_bits[j+i] = (f->packed_codec_bits[byte] >> bit) & 0x1;
+            bit--;
+            if (bit < 0) {
+                bit = 7;
+                byte++;
+            }
+        }
+       if (bit != 7)
+           byte++;
+
+        // spare bits in frame that codec defines.  Use these spare
+        // bits/frame to send txt messages
+
+        switch(f->mode) {
+        case FREEDV_MODE_700:
+            nspare = 2;
+            break;
+        case FREEDV_MODE_700B:
+            nspare = 1; // Just one spare bit for FREEDV_MODE_700B
+            break;
+        case FREEDV_MODE_700C:
+            nspare = 0; // and no spare bits for 700C atm
+            break;
+        default:
+            assert(0);
+        }
+
+        data_flag_index = codec2_get_spare_bit_index(f->codec2);
+
+        for(k=0; k<nspare; k++) {
+            if (f->nvaricode_bits) {
+                f->codec_bits[j+data_flag_index+k] = f->tx_varicode_bits[f->varicode_bit_index++];
+                //fprintf(stderr, "%d %d\n", j+data_flag_index+k, f->codec_bits[j+data_flag_index+k]);
+                f->nvaricode_bits--;
+            }
+            if (f->nvaricode_bits == 0) {
+                /* get new char and encode */
+                char s[2];
+                if (f->freedv_get_next_tx_char != NULL) {
+                    s[0] = (*f->freedv_get_next_tx_char)(f->callback_state);
+                    f->nvaricode_bits = varicode_encode(f->tx_varicode_bits, s, VARICODE_MAX_BITS, 1, 1);
+                    f->varicode_bit_index = 0;
+                }
+            }
+        }
+    }
+    /* optionally ovwerwrite the codec bits with test frames */
+
+    if (f->test_frames) {
+        cohpsk_get_test_bits(f->cohpsk, f->codec_bits);
+    }
+
+    /* cohpsk modulator */
+
+    cohpsk_mod(f->cohpsk, tx_fdm, f->codec_bits, COHPSK_BITS_PER_FRAME);
+    if (f->clip)
+        cohpsk_clip(tx_fdm);
+    for(i=0; i<f->n_nat_modem_samples; i++)
+        mod_out[i] = fcmult(FDMDV_SCALE*NORM_PWR_COHPSK, tx_fdm[i]);
+    i = quisk_cfInterpDecim(mod_out, f->n_nat_modem_samples, f->ptFilter7500to8000, 16, 15);
+    //assert(i == f->n_nom_modem_samples);
+    // Caution: assert fails if f->n_nat_modem_samples * 16.0 / 15.0 is not an integer
+
+}
+#endif
+
+void freedv_comptx(struct freedv *f, COMP mod_out[], short speech_in[]) {
+    assert(f != NULL);
+    int    i;
+#ifndef CORTEX_M4
+    int    j;  
+    int    bits_per_codec_frame;
+#endif
+    short  tx_real[f->n_nom_modem_samples];
+
+    assert((f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || 
+           (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C) || 
+           (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B));
+
+    if (f->mode == FREEDV_MODE_1600) {
+        codec2_encode(f->codec2, f->packed_codec_bits, speech_in);
+        freedv_comptx_fdmdv_1600(f, mod_out);
+    }
+
+#ifndef CORTEX_M4
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)|| (f->mode == FREEDV_MODE_700C)) {
+        bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+       int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+       int codec_frames = f->n_codec_bits / bits_per_codec_frame;
+
+        for (j=0; j < codec_frames; j++) {
+            codec2_encode(f->codec2, f->packed_codec_bits + j * bytes_per_codec_frame, speech_in);
+            speech_in += codec2_samples_per_frame(f->codec2);
+        }
+       freedv_comptx_fdmdv_700(f, mod_out);
+    }
+#endif
+    /* 2400 A and B are handled by the real-mode TX */
+    if((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B)){
+        freedv_tx(f,tx_real,speech_in);
+        /* Convert to complex-mode */
+        for(i=0; i<f->n_nom_modem_samples; i++){
+            mod_out[i].real = (float) tx_real[i];
+            mod_out[i].imag = 0;
+        }
+    }
+}
+
+void freedv_codectx(struct freedv *f, short mod_out[], unsigned char *packed_codec_bits) {
+    assert(f != NULL);
+    COMP tx_fdm[f->n_nom_modem_samples];
+    int bits_per_codec_frame;
+    int bytes_per_codec_frame;
+    int codec_frames;
+    int  i;
+    bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+    bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+    codec_frames = f->n_codec_bits / bits_per_codec_frame;
+
+    memcpy(f->packed_codec_bits, packed_codec_bits, bytes_per_codec_frame * codec_frames);
+    
+    switch(f->mode) {
+        case FREEDV_MODE_1600:
+            freedv_comptx_fdmdv_1600(f, tx_fdm);
+            break;
+    #ifndef CORTEX_M4
+        case FREEDV_MODE_700:
+        case FREEDV_MODE_700B:
+        case FREEDV_MODE_700C:
+            freedv_comptx_fdmdv_700(f, tx_fdm);
+            break;
+        case FREEDV_MODE_2400A:
+        case FREEDV_MODE_2400B:
+        case FREEDV_MODE_800XA:
+            freedv_tx_fsk_voice(f, mod_out);
+            return; /* output is already real */
+    #endif
+    }
+    /* convert complex to real */
+    for(i=0; i<f->n_nom_modem_samples; i++)
+        mod_out[i] = tx_fdm[i].real;
+}
+
+void freedv_datatx  (struct freedv *f, short mod_out[]){
+    assert(f != NULL);
+    if (f->mode == FREEDV_MODE_2400A || f->mode == FREEDV_MODE_2400B || f->mode == FREEDV_MODE_800XA) {
+            freedv_tx_fsk_data(f, mod_out);
+    }
+}
+
+int  freedv_data_ntxframes (struct freedv *f){
+    assert(f != NULL);
+    if (f->mode == FREEDV_MODE_2400A || f->mode == FREEDV_MODE_2400B) {
+        if (f->deframer->fdc)
+            return freedv_data_get_n_tx_frames(f->deframer->fdc, 8);
+    } else if (f->mode == FREEDV_MODE_800XA) {
+        if (f->deframer->fdc)
+            return freedv_data_get_n_tx_frames(f->deframer->fdc, 6);
+    }
+    return 0;
+}
+
+int freedv_nin(struct freedv *f) {
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C))
+        // For mode 700, the input rate is 8000 sps, but the modem rate is 7500 sps
+        // For mode 700, we request a larger number of Rx samples that will be decimated to f->nin samples
+        return (16 * f->nin + f->ptFilter8000to7500->decim_index) / 15;
+    else
+        return f->nin;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_rx
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 August 2014
+
+  Takes a frame of samples from the radio receiver, demodulates and
+  decodes them, producing a frame of decoded speech samples.  See
+  freedv_rx.c for an example.
+
+  demod_in[] is a block of received samples sampled at 8000 Hz.
+  To account for difference in the transmit and receive sample clock
+  frequencies, the number of demod_in[] samples is time varying. You
+  MUST call freedv_nin() BEFORE each call to freedv_rx() and pass
+  exactly that many samples to this function.
+
+  To help set your buffer sizes, The maximum value of freedv_nin() is
+  freedv_get_n_max_modem_samples().
+
+  freedv_rx() returns the number of output speech samples available in
+  speech_out[], which is sampled at 8000 Hz.  You should ALWAYS check
+  the return value of freedv_rx(), and read EXACTLY that number of
+  speech samples from speech_out[].
+
+  1600 mode: When out of sync, it the number of output speech samples
+  returned will be freedv_nin(). When in sync to a valid FreeDV 1600
+  signal, the number of output speech samples will alternate between
+  freedv_get_n_speech_samples() and 0.
+
+  700 and 700B mode: The number of output speech samples returned will
+  always be freedv_get_n_speech_samples(), regardless of sync.
+
+  The peak level of demod_in[] is not critical, as the demod works
+  well over a wide range of amplitude scaling.  However avoid clipping
+  (overload, or samples pinned to +/- 32767).  speech_out[] will peak
+  at just less than +/-32767.
+
+  When out of sync, this function echoes the demod_in[] samples to
+  speech_out[].  This allows the user to listen to the channel, which
+  is useful for tuning FreeDV signals or reception of non-FreeDV
+  signals.  Setting the squelch with freedv_set_squelch_en(1) will
+  return zero-valued samples instead.
+
+\*---------------------------------------------------------------------------*/
+
+
+// short version
+
+int freedv_rx(struct freedv *f, short speech_out[], short demod_in[]) {
+    assert(f != NULL);
+    int i;
+    int nin = freedv_nin(f);
+    assert(nin <= f->n_max_modem_samples);
+    
+    
+    /* FSK RX happens in real floats, so convert to those and call their demod here */
+    if( (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA) ){
+        float rx_float[f->n_max_modem_samples];
+        for(i=0; i<nin; i++) {
+            rx_float[i] = ((float)demod_in[i]);
+        }
+        return freedv_floatrx(f,speech_out,rx_float);
+    }
+    
+    if( (f->mode == FREEDV_MODE_1600) || (f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)){
+        /* FDM RX happens with complex samps, so do that */
+        COMP rx_fdm[f->n_max_modem_samples];
+        for(i=0; i<nin; i++) {
+            rx_fdm[i].real = (float)demod_in[i];
+            rx_fdm[i].imag = 0.0;
+        }
+        return freedv_comprx(f, speech_out, rx_fdm);
+    }
+    return 0; /* should never get here */
+}
+
+
+// float input samples version
+int freedv_comprx_fsk(struct freedv *f, COMP demod_in[], int *valid) {
+    /* Varicode and protocol bits */
+    uint8_t vc_bits[2];
+    uint8_t proto_bits[3];
+    short vc_bit;
+    int i;
+    int n_ascii;
+    char ascii_out;
+
+    if(f->mode == FREEDV_MODE_2400A || f->mode == FREEDV_MODE_800XA){        
+       fsk_demod(f->fsk,(uint8_t*)f->tx_bits,demod_in);
+        f->nin = fsk_nin(f->fsk);
+        float EbNodB = f->fsk->stats->snr_est;           /* fsk demod actually estimates Eb/No     */
+        f->snr_est = EbNodB + 10.0*log10f(800.0/3000.0); /* so convert to SNR Rb=800, noise B=3000 */
+        //fprintf(stderr," %f %f\n", EbNodB, f->snr_est);
+    } else{      
+        /* 2400B needs real input samples */
+        int n = fmfsk_nin(f->fmfsk);
+        float demod_in_float[n];
+        for(i=0; i<n; i++) {
+            demod_in_float[i] = demod_in[i].real;
+        }
+        fmfsk_demod(f->fmfsk,(uint8_t*)f->tx_bits,demod_in_float);
+        f->nin = fmfsk_nin(f->fmfsk);
+    }
+    
+    if(fvhff_deframe_bits(f->deframer,f->packed_codec_bits,proto_bits,vc_bits,(uint8_t*)f->tx_bits)){
+        /* Decode varicode text */
+        for(i=0; i<2; i++){
+            /* Note: deframe_bits spits out bits in uint8_ts while varicode_decode expects shorts */
+            vc_bit = vc_bits[i];
+            n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, &vc_bit, 1, 1);
+            if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+                (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+            }
+        }
+        /* Pass proto bits on down if callback is present */
+        if( f->freedv_put_next_proto != NULL){
+            (*f->freedv_put_next_proto)(f->proto_callback_state,(char*)proto_bits);
+        }
+        *valid = 1;
+
+        /* squelch if if sync but SNR too low */
+        if (f->squelch_en && (f->snr_est < f->snr_squelch_thresh)) {
+            *valid = 0;
+        }
+    } else {
+        /* squelch if out of sync, or echo input of squelch off */
+        if (f->squelch_en) 
+            *valid = 0;
+        else
+            *valid = -1;
+    }
+    f->sync = f->deframer->state;
+    f->stats.sync = f->deframer->state;
+
+    return f->n_speech_samples;
+}
+
+int freedv_floatrx(struct freedv *f, short speech_out[], float demod_in[]) {
+    assert(f != NULL);
+    int  i;
+    int nin = freedv_nin(f);    
+    
+    assert(nin <= f->n_max_modem_samples);
+    
+    COMP rx_fdm[f->n_max_modem_samples];
+    for(i=0; i<nin; i++) {
+        rx_fdm[i].real = demod_in[i];
+        rx_fdm[i].imag = 0;
+    }
+
+    return freedv_comprx(f, speech_out, rx_fdm);
+}
+
+// complex input samples version
+
+static int freedv_comprx_fdmdv_1600(struct freedv *f, COMP demod_in[], int *valid) {
+    int                 bits_per_codec_frame, bytes_per_codec_frame, bits_per_fdmdv_frame;
+    int                 i, j, bit, byte, nin_prev, nout;
+    int                 recd_codeword, codeword1, data_flag_index, n_ascii;
+    short               abit[1];
+    char                ascii_out;
+    int                 reliable_sync_bit;
+
+    bits_per_codec_frame  = codec2_bits_per_frame(f->codec2);
+    bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+    nout = f->n_speech_samples;
+
+    COMP ademod_in[f->nin];
+    for(i=0; i<f->nin; i++)
+        ademod_in[i] = fcmult(1.0/FDMDV_SCALE, demod_in[i]);
+
+    bits_per_fdmdv_frame  = fdmdv_bits_per_frame(f->fdmdv);
+
+    nin_prev = f->nin;
+    fdmdv_demod(f->fdmdv, f->fdmdv_bits, &reliable_sync_bit, ademod_in, &f->nin);
+    fdmdv_get_demod_stats(f->fdmdv, &f->stats);
+    f->sync = f->fdmdv->sync;
+    f->snr_est = f->stats.snr_est;
+
+    if (reliable_sync_bit == 1) {
+        f->evenframe = 1;
+    }
+
+    if (f->stats.sync) {
+        if (f->evenframe == 0) {
+            memcpy(f->rx_bits, f->fdmdv_bits, bits_per_fdmdv_frame*sizeof(int));
+            nout = 0;
+           *valid = 0;
+        }
+        else {
+            memcpy(&f->rx_bits[bits_per_fdmdv_frame], f->fdmdv_bits, bits_per_fdmdv_frame*sizeof(int));
+
+            if (f->test_frames == 0) {
+                recd_codeword = 0;
+                for(i=0; i<8; i++) {
+                    recd_codeword <<= 1;
+                    recd_codeword |= (f->rx_bits[i] & 0x1);
+                }
+                for(i=11; i<15; i++) {
+                    recd_codeword <<= 1;
+                    recd_codeword |= (f->rx_bits[i] & 0x1);
+                }
+                for(i=bits_per_codec_frame; i<bits_per_codec_frame+11; i++) {
+                    recd_codeword <<= 1;
+                    recd_codeword |= (f->rx_bits[i] & 0x1);
+                }
+                codeword1 = golay23_decode(recd_codeword);
+                f->total_bit_errors += golay23_count_errors(recd_codeword, codeword1);
+                f->total_bits       += 23;
+
+                //codeword1 = recd_codeword;
+                //fprintf(stderr, "received codeword1: 0x%x  decoded codeword1: 0x%x\n", recd_codeword, codeword1);
+
+                for(i=0; i<bits_per_codec_frame; i++)
+                    f->codec_bits[i] = f->rx_bits[i];
+
+                for(i=0; i<8; i++) {
+                    f->codec_bits[i] = (codeword1 >> (22-i)) & 0x1;
+                }
+                for(i=8,j=11; i<12; i++,j++) {
+                    f->codec_bits[j] = (codeword1 >> (22-i)) & 0x1;
+                }
+
+                // extract txt msg data bit ------------------------------------------------------------
+
+                data_flag_index = codec2_get_spare_bit_index(f->codec2);
+                abit[0] = f->codec_bits[data_flag_index];
+
+                n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
+                if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+                    (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+                }
+
+                // reconstruct missing bit we steal for data bit and decode speech
+
+                codec2_rebuild_spare_bit(f->codec2, f->codec_bits);
+
+                // pack bits, MSB received first
+
+                bit  = 7;
+                byte = 0;
+                memset(f->packed_codec_bits, 0,  bytes_per_codec_frame);
+                for(i=0; i<bits_per_codec_frame; i++) {
+                    f->packed_codec_bits[byte] |= (f->codec_bits[i] << bit);
+                    bit--;
+                    if(bit < 0) {
+                        bit = 7;
+                        byte++;
+                    }
+                }
+                *valid = 1;
+            }
+            else {
+                int   test_frame_sync, bit_errors, ntest_bits, k;
+                short error_pattern[fdmdv_error_pattern_size(f->fdmdv)];
+
+                for(k=0; k<2; k++) {
+                    /* test frames, so lets sync up to the test frames and count any errors */
+
+                    fdmdv_put_test_bits(f->fdmdv, &test_frame_sync, error_pattern, &bit_errors, &ntest_bits, &f->rx_bits[k*bits_per_fdmdv_frame]);
+
+                    if (test_frame_sync == 1) {
+                        f->test_frame_sync_state = 1;
+                        f->test_frame_count = 0;
+                    }
+
+                    if (f->test_frame_sync_state) {
+                        if (f->test_frame_count == 0) {
+                            f->total_bit_errors += bit_errors;
+                            f->total_bits += ntest_bits;
+                            if (f->freedv_put_error_pattern != NULL) {
+                                (*f->freedv_put_error_pattern)(f->error_pattern_callback_state, error_pattern, fdmdv_error_pattern_size(f->fdmdv));
+                            }
+                        }
+                        f->test_frame_count++;
+                        if (f->test_frame_count == 4)
+                            f->test_frame_count = 0;
+                    }
+
+                    //fprintf(stderr, "test_frame_sync: %d test_frame_sync_state: %d bit_errors: %d ntest_bits: %d\n",
+                    //        test_frame_sync, f->test_frame_sync_state, bit_errors, ntest_bits);
+                }
+            }
+
+
+            /* squelch if beneath SNR threshold or test frames enabled */
+
+            if ((f->squelch_en && (f->stats.snr_est < f->snr_squelch_thresh)) || f->test_frames) {
+                //fprintf(stderr,"squelch %f %f !\n", f->stats.snr_est, f->snr_squelch_thresh);
+                *valid = 0;
+            }
+
+            nout = f->n_speech_samples;
+
+        }
+
+        /* note this freewheels if reliable sync dissapears on bad channels */
+
+        if (f->evenframe)
+            f->evenframe = 0;
+        else
+            f->evenframe = 1;
+        //fprintf(stderr,"%d\n",  f->evenframe);
+
+    } /* if (sync) .... */
+    else {
+        /* if not in sync pass through analog samples */
+        /* this lets us "hear" whats going on, e.g. during tuning */
+
+        //fprintf(stderr, "out of sync\n");
+
+        if (f->squelch_en == 0) {
+           *valid = -1;
+        }
+        else {
+           *valid = 0;
+        }
+        //fprintf(stderr, "%d %d %d\n", nin_prev, speech_out[0], speech_out[nin_prev-1]);
+        nout = nin_prev;
+    }
+    return nout;
+}
+
+#ifndef CORTEX_M4
+static int freedv_comprx_fdmdv_700(struct freedv *f, COMP demod_in_8kHz[], int *valid) {
+    int                 bits_per_codec_frame, bytes_per_codec_frame;
+    int                 i, j, bit, byte, nout, k;
+    int                 data_flag_index, n_ascii, nspare;
+    short               abit[1];
+    char                ascii_out;
+    float rx_bits[COHPSK_BITS_PER_FRAME]; /* soft decn rx bits */
+    int   sync;
+    int   frames;
+
+    bits_per_codec_frame  = codec2_bits_per_frame(f->codec2);
+    bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+    frames = f->n_codec_bits / bits_per_codec_frame;
+    nout = f->n_speech_samples;
+
+    // echo samples back out as default (say if sync not found)
+    *valid = -1;
+
+    // quisk_cfInterpDecim() modifies input data so lets make a copy just in case there
+    // is no sync and we need to echo inout to output
+
+    COMP demod_in[freedv_nin(f)];
+    for(i=0; i<freedv_nin(f); i++)
+        demod_in[i] = demod_in_8kHz[i];
+
+    i = quisk_cfInterpDecim(demod_in, freedv_nin(f), f->ptFilter8000to7500, 15, 16);
+    //if (i != f->nin)
+    //    printf("freedv_comprx decimation: input %d output %d\n", freedv_nin(f), i);
+
+    for(i=0; i<f->nin; i++)
+        demod_in[i] = fcmult(1.0/FDMDV_SCALE, demod_in[i]);
+    
+    cohpsk_demod(f->cohpsk, rx_bits, &sync, demod_in, &f->nin);
+
+    f->sync = sync;
+    cohpsk_get_demod_stats(f->cohpsk, &f->stats);
+    f->snr_est = f->stats.snr_est;
+
+    memset(f->packed_codec_bits, 0, bytes_per_codec_frame * frames);
+
+    if (sync) {
+
+        if (f->test_frames == 0) {
+            data_flag_index = codec2_get_spare_bit_index(f->codec2);
+
+            /* optional smoothing of codec symbols */
+
+            if (f->smooth_symbols) {
+
+                for(i=0; i<bits_per_codec_frame; i++) {
+                    rx_bits[i] += rx_bits[i+bits_per_codec_frame];
+                    rx_bits[i+bits_per_codec_frame] = rx_bits[i];
+                }
+            }
+
+            byte = 0;
+            for (j=0; j<COHPSK_BITS_PER_FRAME; j+=bits_per_codec_frame) {
+
+                /* extract txt msg data bit(s) */
+
+                switch(f->mode) {
+                case FREEDV_MODE_700:
+                    nspare = 2;
+                    break;
+                case FREEDV_MODE_700B:
+                    nspare = 1; // Just one spare bit for FREEDV_MODE_700B
+                    break;
+                case FREEDV_MODE_700C:
+                    nspare = 0; // and no spare bits for 700C atm
+                    break;
+                default:
+                    assert(0);
+                }
+
+                for(k=0; k<nspare; k++)  {
+                    abit[0] = rx_bits[data_flag_index+j+k] < 0.0;
+
+                    n_ascii = varicode_decode(&f->varicode_dec_states, &ascii_out, abit, 1, 1);
+                    if (n_ascii && (f->freedv_put_next_rx_char != NULL)) {
+                        (*f->freedv_put_next_rx_char)(f->callback_state, ascii_out);
+                    }
+                }
+
+                /* pack bits, MSB received first */
+
+                bit = 7;
+                for(i=0; i<bits_per_codec_frame; i++) {
+                    f->packed_codec_bits[byte] |= ((rx_bits[j+i] < 0.0) << bit);
+                    bit--;
+                    if (bit < 0) {
+                        bit = 7;
+                        byte++;
+                    }
+                }
+               if (bit != 7)
+                   byte++;
+
+                if (f->squelch_en && (f->stats.snr_est < f->snr_squelch_thresh)) {
+                  *valid = 0;
+                }
+               *valid = 1;
+            }
+            nout = f->n_speech_samples;
+        }
+        else {
+            //fprintf(stderr, " freedv_api:  f->test_frames_diversity: %d\n", f->test_frames_diversity);
+
+            if (f->test_frames_diversity) {
+                /* normal operation - error pattern on frame after diveristy combination */
+                short error_pattern[COHPSK_BITS_PER_FRAME];
+                int   bit_errors;
+
+                /* test data, lets see if we can sync to the test data sequence */
+
+                char rx_bits_char[COHPSK_BITS_PER_FRAME];
+                for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+                    rx_bits_char[i] = rx_bits[i] < 0.0;
+                cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors, rx_bits_char, 0);
+                if (f->test_frame_sync_state) {
+                    f->total_bit_errors += bit_errors;
+                    f->total_bits       += COHPSK_BITS_PER_FRAME;
+                    if (f->freedv_put_error_pattern != NULL) {
+                        (*f->freedv_put_error_pattern)(f->error_pattern_callback_state, error_pattern, COHPSK_BITS_PER_FRAME);
+                    }
+                }
+            } 
+            else {
+                /* calculate error pattern on uncombined carriers - test mode to spot any carrier specific issues like
+                   tx passband filtering */
+
+                short error_pattern[2*COHPSK_BITS_PER_FRAME];
+                char  rx_bits_char[COHPSK_BITS_PER_FRAME];
+                int   bit_errors_lower, bit_errors_upper;
+
+                /* lower group of carriers */
+
+                float *rx_bits_lower = cohpsk_get_rx_bits_lower(f->cohpsk);
+                for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+                    rx_bits_char[i] = rx_bits_lower[i] < 0.0;
+                }
+                cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state, error_pattern, &bit_errors_lower, rx_bits_char, 0);
+
+                /* upper group of carriers */
+
+                float *rx_bits_upper = cohpsk_get_rx_bits_upper(f->cohpsk);
+                for(i=0; i<COHPSK_BITS_PER_FRAME; i++) {
+                    rx_bits_char[i] = rx_bits_upper[i] < 0.0;
+                }
+                cohpsk_put_test_bits(f->cohpsk, &f->test_frame_sync_state_upper, &error_pattern[COHPSK_BITS_PER_FRAME], &bit_errors_upper, rx_bits_char, 1);
+                //                fprintf(stderr, " freedv_api:  f->test_frame_sync_state: %d f->test_frame_sync_state_upper: %d\n", 
+                //        f->test_frame_sync_state, f->test_frame_sync_state_upper);
+
+                /* combine total errors and call callback */
+
+                if (f->test_frame_sync_state && f->test_frame_sync_state_upper) {
+                    f->total_bit_errors += bit_errors_lower + bit_errors_upper;
+                    f->total_bits       += 2*COHPSK_BITS_PER_FRAME;
+                    if (f->freedv_put_error_pattern != NULL) {
+                        (*f->freedv_put_error_pattern)(f->error_pattern_callback_state, error_pattern, 2*COHPSK_BITS_PER_FRAME);
+                    }
+                }
+
+            }
+            
+           *valid = 0;
+            nout = f->n_speech_samples;
+        }
+
+    }
+
+    /* no valid FreeDV signal - squelch output */
+
+    if (sync == 0) {
+        nout = freedv_nin(f);
+        if (f->squelch_en) {
+           *valid = 0;
+        }
+    }
+    return nout;
+}
+#endif
+
+
+int freedv_comprx(struct freedv *f, short speech_out[], COMP demod_in[]) {
+    assert(f != NULL);
+    int                 bits_per_codec_frame, bytes_per_codec_frame;
+    int                 i, nout = 0;
+    int valid;
+    
+    assert(f->nin <= f->n_max_modem_samples);
+
+    bits_per_codec_frame  = codec2_bits_per_frame(f->codec2);
+    bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+
+    if (f->mode == FREEDV_MODE_1600) {
+        nout = freedv_comprx_fdmdv_1600(f, demod_in, &valid);
+    }
+#ifndef CORTEX_M4
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) {
+        nout = freedv_comprx_fdmdv_700(f, demod_in, &valid);
+        //valid = -1;
+    }
+
+    if( (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA)){
+        nout = freedv_comprx_fsk(f, demod_in, &valid);
+    }
+#endif
+
+    if (valid == 0) {
+        for (i = 0; i < nout; i++)
+            speech_out[i] = 0;
+    }
+    else if (valid < 0) {
+        for (i = 0; i < nout; i++)
+            speech_out[i] = demod_in[i].real;
+    }
+    else {
+        int frames = f->n_codec_bits / bits_per_codec_frame;
+        for (i = 0; i < frames; i++) {
+            codec2_decode(f->codec2, speech_out, f->packed_codec_bits + i * bytes_per_codec_frame);
+            speech_out += codec2_samples_per_frame(f->codec2);
+        }
+    }
+
+    //fprintf(stderr,"freedv_nin(f): %d nout: %d valid: %d\n", freedv_nin(f), nout, valid);
+    return nout;
+}
+
+int freedv_codecrx(struct freedv *f, unsigned char *packed_codec_bits, short demod_in[])
+{
+    assert(f != NULL);
+    COMP rx_fdm[f->n_max_modem_samples];
+    int i;
+    int nin = freedv_nin(f);
+    int valid;
+    int ret = 0;
+
+    assert(nin <= f->n_max_modem_samples);
+    
+    for(i=0; i<nin; i++) {
+        rx_fdm[i].real = (float)demod_in[i];
+        rx_fdm[i].imag = 0.0;
+    }
+
+    if (f->mode == FREEDV_MODE_1600) {
+        freedv_comprx_fdmdv_1600(f, rx_fdm, &valid);
+    }
+
+#ifndef CORTEX_M4
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) {
+        freedv_comprx_fdmdv_700(f, rx_fdm, &valid);
+    }
+#endif
+    
+    if( (f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA)){
+        freedv_comprx_fsk(f, rx_fdm, &valid);
+    }
+
+    if (valid == 1) {
+        int bits_per_codec_frame = codec2_bits_per_frame(f->codec2);
+        int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+        int codec_frames = f->n_codec_bits / bits_per_codec_frame;
+
+        memcpy(packed_codec_bits, f->packed_codec_bits, bytes_per_codec_frame * codec_frames);
+       ret = bytes_per_codec_frame * codec_frames;
+    }
+    
+    return ret;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_get_version
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 28 July 2015
+
+  Return the version of the FreeDV API.  This is meant to help API users determine when
+  incompatible changes have occurred.
+
+\*---------------------------------------------------------------------------*/
+
+int freedv_get_version(void)
+{
+    return VERSION;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_set_callback_txt
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 28 July 2015
+
+  Set the callback functions and the callback state pointer that will be used
+  for the aux txt channel.  The freedv_callback_rx is a function pointer that
+  will be called to return received characters.  The freedv_callback_tx is a
+  function pointer that will be called to send transmitted characters.  The callback
+  state is a user-defined void pointer that will be passed to the callback functions.
+  Any or all can be NULL, and the default is all NULL.
+  The function signatures are:
+    void receive_char(void *callback_state, char c);
+    char transmit_char(void *callback_state);
+
+\*---------------------------------------------------------------------------*/
+
+void freedv_set_callback_txt(struct freedv *f, freedv_callback_rx rx, freedv_callback_tx tx, void *state)
+{
+    if (f->mode != FREEDV_MODE_800XA) {
+        f->freedv_put_next_rx_char = rx;
+        f->freedv_get_next_tx_char = tx;
+        f->callback_state = state;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_set_callback_protocol
+  AUTHOR......: Brady OBrien
+  DATE CREATED: 21 February 2016
+
+  Set the callback functions and callback pointer that will be used for the
+  protocol data channel. freedv_callback_protorx will be called when a frame
+  containing protocol data arrives. freedv_callback_prototx will be called
+  when a frame containing protocol information is being generated. Protocol
+  information is intended to be used to develop protocols and fancy features
+  atop VHF freedv, much like those present in DMR.
+   Protocol bits are to be passed in an msb-first char array
+   The number of protocol bits are findable with freedv_get_protocol_bits
+\*---------------------------------------------------------------------------*/
+
+void freedv_set_callback_protocol(struct freedv *f, freedv_callback_protorx rx, freedv_callback_prototx tx, void *callback_state){
+    if (f->mode != FREEDV_MODE_800XA) {
+        f->freedv_put_next_proto = rx;
+        f->freedv_get_next_proto = tx;
+        f->proto_callback_state = callback_state;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_set_callback_datarx / freedv_set_callback_datatx
+  AUTHOR......: Jeroen Vreeken
+  DATE CREATED: 04 March 2016
+
+  Set the callback functions and callback pointer that will be used for the
+  data channel. freedv_callback_datarx will be called when a packet has been
+  successfully received. freedv_callback_data_tx will be called when 
+  transmission of a new packet can begin.
+  If the returned size of the datatx callback is zero the data frame is still
+  generated, but will contain only a header update.
+\*---------------------------------------------------------------------------*/
+void freedv_set_callback_data(struct freedv *f, freedv_callback_datarx datarx, freedv_callback_datatx datatx, void *callback_state) {
+    if ((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA)){
+        if (!f->deframer->fdc)
+            f->deframer->fdc = freedv_data_channel_create();
+        if (!f->deframer->fdc)
+            return;
+        
+        freedv_data_set_cb_rx(f->deframer->fdc, datarx, callback_state);
+        freedv_data_set_cb_tx(f->deframer->fdc, datatx, callback_state);
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_set_data_header
+  AUTHOR......: Jeroen Vreeken
+  DATE CREATED: 04 March 2016
+
+  Set the data header for the data channel.
+  Header compression will be used whenever packets from this header are sent.
+  The header will also be used for fill packets when a data frame is requested
+  without a packet available.
+\*---------------------------------------------------------------------------*/
+void freedv_set_data_header(struct freedv *f, unsigned char *header)
+{
+    if ((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_2400B) || (f->mode == FREEDV_MODE_800XA)){
+        if (!f->deframer->fdc)
+            f->deframer->fdc = freedv_data_channel_create();
+        if (!f->deframer->fdc)
+            return;
+        
+        freedv_data_set_header(f->deframer->fdc, header);
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freedv_get_modem_stats
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 28 July 2015
+
+  Return data from the modem.  The arguments are pointers to the data items.  The
+  pointers can be NULL if the data item is not wanted.
+
+\*---------------------------------------------------------------------------*/
+
+void freedv_get_modem_stats(struct freedv *f, int *sync, float *snr_est)
+{
+    if (f->mode == FREEDV_MODE_1600)
+        fdmdv_get_demod_stats(f->fdmdv, &f->stats);
+#ifndef CORTEX_M4
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B)  || (f->mode == FREEDV_MODE_700C))
+        cohpsk_get_demod_stats(f->cohpsk, &f->stats);
+#endif
+    if (sync) *sync = f->stats.sync;
+    if (snr_est) *snr_est = f->stats.snr_est;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTIONS...: freedv_set_*
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 28 July 2015
+
+  Set some parameters used by FreeDV.  It is possible to write a macro using ## for
+  this, but I wasn't sure it would be 100% portable.
+
+\*---------------------------------------------------------------------------*/
+
+// Set integers
+void freedv_set_test_frames               (struct freedv *f, int val) {f->test_frames = val;}
+void freedv_set_test_frames_diversity    (struct freedv *f, int val) {f->test_frames_diversity = val;}
+void freedv_set_squelch_en                (struct freedv *f, int val) {f->squelch_en = val;}
+void freedv_set_total_bit_errors          (struct freedv *f, int val) {f->total_bit_errors = val;}
+void freedv_set_total_bits                (struct freedv *f, int val) {f->total_bits = val;}
+void freedv_set_clip                      (struct freedv *f, int val) {f->clip = val;}
+void freedv_set_varicode_code_num         (struct freedv *f, int val) {varicode_set_code_num(&f->varicode_dec_states, val);}
+
+// Set floats
+void freedv_set_snr_squelch_thresh        (struct freedv *f, float val) {f->snr_squelch_thresh = val;}
+
+void freedv_set_callback_error_pattern    (struct freedv *f, freedv_calback_error_pattern cb, void *state)
+{
+    f->freedv_put_error_pattern = cb;
+    f->error_pattern_callback_state = state;
+}
+
+#ifndef CORTEX_M4
+void freedv_set_carrier_ampl(struct freedv *freedv, int c, float ampl) {
+    assert(freedv->mode == FREEDV_MODE_700C);
+    cohpsk_set_carrier_ampl(freedv->cohpsk, c, ampl);
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTIONS...: freedv_set_alt_modem_samp_rate
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 25 June 2016
+
+  Attempt to set the alternative sample rate on the modem side of the api. Only
+   a few alternative sample rates are supported. Please see below.
+   
+   2400A - 48000, 96000
+   2400B - 48000, 96000
+  
+  TODO: Implement 2400B rate changing, allow other rate changing.
+   
+
+\*---------------------------------------------------------------------------*/
+
+int freedv_set_alt_modem_samp_rate(struct freedv *f, int samp_rate){
+       if(f->mode == FREEDV_MODE_2400A){ 
+               if(samp_rate == 48000 || samp_rate == 96000){
+                       fsk_destroy(f->fsk);
+                       f->fsk = fsk_create_hbr(samp_rate,1200,10,4,1200,1200);
+        
+                       free(f->tx_bits);
+                       /* Note: fsk expects tx/rx bits as an array of uint8_ts, not ints */
+                       f->tx_bits = (int*)malloc(f->fsk->Nbits*sizeof(uint8_t));
+        
+                       f->n_nom_modem_samples = f->fsk->N;
+                       f->n_max_modem_samples = f->fsk->N + (f->fsk->Ts);
+                       f->n_nat_modem_samples = f->fsk->N;
+                       f->nin = fsk_nin(f->fsk);
+                       f->modem_sample_rate = samp_rate;
+                       return 0;
+               }else
+                       return -1;
+       }else if(f->mode == FREEDV_MODE_2400B){
+               if(samp_rate == 48000 || samp_rate == 96000){
+                       return -1;
+               }else
+                       return -1;
+       }
+       return -1;
+}
+
+struct FSK * freedv_get_fsk(struct freedv *f){
+       return f->fsk;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTIONS...: freedv_get_*
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 28 July 2015
+
+  Get some parameters from FreeDV.  It is possible to write a macro using ## for
+  this, but I wasn't sure it would be 100% portable.
+
+\*---------------------------------------------------------------------------*/
+
+// Get integers
+int freedv_get_protocol_bits              (struct freedv *f) {return  f->n_protocol_bits;}
+int freedv_get_mode                       (struct freedv *f) {return f->mode;}
+int freedv_get_test_frames                (struct freedv *f) {return f->test_frames;}
+int freedv_get_n_speech_samples           (struct freedv *f) {return f->n_speech_samples;}
+int freedv_get_modem_sample_rate          (struct freedv *f) {return f->modem_sample_rate;}
+int freedv_get_n_max_modem_samples        (struct freedv *f) {return f->n_max_modem_samples;}
+int freedv_get_n_nom_modem_samples        (struct freedv *f) {return f->n_nom_modem_samples;}
+int freedv_get_total_bits                 (struct freedv *f) {return f->total_bits;}
+int freedv_get_total_bit_errors           (struct freedv *f) {return f->total_bit_errors;}
+int freedv_get_sync                       (struct freedv *f) {return f->stats.sync;}
+
+int freedv_get_sz_error_pattern(struct freedv *f) 
+{
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C)) {
+        /* if diversity disabled callback sends error pattern for upper and lower carriers */
+        return f->sz_error_pattern * (2 - f->test_frames_diversity);
+    }
+    else {
+        return f->sz_error_pattern;
+    }
+}
+
+// Get floats
+
+struct CODEC2 *freedv_get_codec2       (struct freedv *f){return  f->codec2;}
+int freedv_get_n_codec_bits             (struct freedv *f){return f->n_codec_bits;}
+
+void freedv_get_modem_extended_stats(struct freedv *f, struct MODEM_STATS *stats)
+{
+    if (f->mode == FREEDV_MODE_1600)
+        fdmdv_get_demod_stats(f->fdmdv, stats);
+
+    if ((f->mode == FREEDV_MODE_2400A) || (f->mode == FREEDV_MODE_800XA)) {
+        fsk_get_demod_stats(f->fsk, stats);
+        float EbNodB = stats->snr_est;                       /* fsk demod actually estimates Eb/No     */
+        stats->snr_est = EbNodB + 10.0*log10f(800.0/3000.0); /* so convert to SNR Rb=800, noise B=3000 */
+    }
+
+    if (f->mode == FREEDV_MODE_2400B) {
+        fmfsk_get_demod_stats(f->fmfsk, stats);
+    }
+    
+#ifndef CORTEX_M4
+    if ((f->mode == FREEDV_MODE_700) || (f->mode == FREEDV_MODE_700B) || (f->mode == FREEDV_MODE_700C))
+        cohpsk_get_demod_stats(f->cohpsk, stats);
+#endif
+}
+
+/*--  Functions below this line are private, and not meant for public use  --*/
+/*---------------------------------------------------------------------------*\
+
+  FUNCTIONS...: quisk_filt_cfInit
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 27 August 2015
+
+  Initialize a FIR filter that will be used to change sample rates.  These rate
+  changing filters were copied from Quisk and modified for float samples.
+
+\*---------------------------------------------------------------------------*/
+
+static void quisk_filt_cfInit(struct quisk_cfFilter * filter, float * coefs, int taps)
+{    // Prepare a new filter using coefs and taps.  Samples are complex.
+    filter->dCoefs = coefs;
+    filter->cSamples = (COMP *)malloc(taps * sizeof(COMP));
+    memset(filter->cSamples, 0, taps * sizeof(COMP));
+    filter->ptcSamp = filter->cSamples;
+    filter->nTaps = taps;
+    filter->cBuf = NULL;
+    filter->nBuf = 0;
+    filter->decim_index = 0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTIONS...: quisk_filt_destroy
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 27 August 2015
+
+  Destroy the FIR filter and free all resources.
+
+\*---------------------------------------------------------------------------*/
+
+static void quisk_filt_destroy(struct quisk_cfFilter * filter)
+{
+    if (filter->cSamples) {
+        free(filter->cSamples);
+        filter->cSamples = NULL;
+    }
+    if (filter->cBuf) {
+        free(filter->cBuf);
+        filter->cBuf = NULL;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTIONS...: quisk_cfInterpDecim
+  AUTHOR......: Jim Ahlstrom
+  DATE CREATED: 27 August 2015
+
+  Take an array of samples cSamples of length count, multiply the sample rate
+  by interp, and then divide the sample rate by decim.  Return the new number
+  of samples.  Each specific interp and decim will require its own custom
+  FIR filter.
+
+\*---------------------------------------------------------------------------*/
+
+static int quisk_cfInterpDecim(COMP * cSamples, int count, struct quisk_cfFilter * filter, int interp, int decim)
+{   // Interpolate by interp, and then decimate by decim.
+    // This uses the float coefficients of filter (not the complex).  Samples are complex.
+    int i, k, nOut;
+    float * ptCoef;
+    COMP * ptSample;
+    COMP csample;
+
+    if (count > filter->nBuf) {    // increase size of sample buffer
+        filter->nBuf = count * 2;
+        if (filter->cBuf)
+            free(filter->cBuf);
+        filter->cBuf = (COMP *)malloc(filter->nBuf * sizeof(COMP));
+    }
+    memcpy(filter->cBuf, cSamples, count * sizeof(COMP));
+    nOut = 0;
+    for (i = 0; i < count; i++) {
+        // Put samples into buffer left to right.  Use samples right to left.
+        *filter->ptcSamp = filter->cBuf[i];
+        while (filter->decim_index < interp) {
+            ptSample = filter->ptcSamp;
+            ptCoef = filter->dCoefs + filter->decim_index;
+            csample.real = 0;
+            csample.imag = 0;
+            for (k = 0; k < filter->nTaps / interp; k++, ptCoef += interp) {
+                csample.real += (*ptSample).real * *ptCoef;
+                csample.imag += (*ptSample).imag * *ptCoef;
+                if (--ptSample < filter->cSamples)
+                    ptSample = filter->cSamples + filter->nTaps - 1;
+            }
+            cSamples[nOut].real = csample.real * interp;
+            cSamples[nOut].imag = csample.imag * interp;
+            nOut++;
+            filter->decim_index += decim;
+        }
+        if (++filter->ptcSamp >= filter->cSamples + filter->nTaps)
+            filter->ptcSamp = filter->cSamples;
+        filter->decim_index = filter->decim_index - interp;
+    }
+    return nOut;
+}
+
diff --git a/codec2/branches/0.7/src/freedv_api.h b/codec2/branches/0.7/src/freedv_api.h
new file mode 100644 (file)
index 0000000..34ec730
--- /dev/null
@@ -0,0 +1,142 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_api.h
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2014
+
+  Library of API functions that implement FreeDV "modes", useful for
+  embedding FreeDV in other programs.  Please see the documentation
+  for each function in freedv_api.c, and the sample freedv_tx.c and
+  freedv_rx.c programs.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+#ifndef __FREEDV__
+
+// This declares a single-precision (float) complex number
+#include <sys/types.h>
+#include "comp.h"
+
+#define FREEDV_MODE_1600        0
+#define FREEDV_MODE_700         1
+#define FREEDV_MODE_700B        2
+#define FREEDV_MODE_2400A       3
+#define FREEDV_MODE_2400B       4
+#define FREEDV_MODE_800XA       5
+#define FREEDV_MODE_700C        6
+
+struct freedv;
+
+/* Called when text message char is decoded */
+typedef void (*freedv_callback_rx)(void *, char);
+/* Called when new text message char is needed */
+typedef char (*freedv_callback_tx)(void *);
+typedef void (*freedv_calback_error_pattern)
+       (void *error_pattern_callback_state, short error_pattern[], int sz_error_pattern);
+
+/* Protocol bits are packed MSB-first */
+/* Called when a frame containing protocol data is decoded */
+typedef void (*freedv_callback_protorx)(void *, char *);
+/* Called when a frame containing protocol data is to be sent */
+typedef void (*freedv_callback_prototx)(void *, char *);
+
+/* Data packet callbacks */
+/* Called when a packet has been received */
+typedef void (*freedv_callback_datarx)(void *, unsigned char *packet, size_t size);
+/* Called when a new packet can be send */
+typedef void (*freedv_callback_datatx)(void *, unsigned char *packet, size_t *size);
+
+
+/*---------------------------------------------------------------------------*\
+
+                                 FreeDV API functions
+
+\*---------------------------------------------------------------------------*/
+
+// open, close ----------------------------------------------------------------
+
+struct freedv *freedv_open(int mode);
+void freedv_close   (struct freedv *freedv);
+
+// Transmit -------------------------------------------------------------------
+
+void freedv_tx      (struct freedv *freedv, short mod_out[], short speech_in[]);
+void freedv_comptx  (struct freedv *freedv, COMP  mod_out[], short speech_in[]);
+void freedv_codectx (struct freedv *f, short mod_out[], unsigned char *packed_codec_bits);
+void freedv_datatx  (struct freedv *f, short mod_out[]);
+int  freedv_data_ntxframes (struct freedv *freedv);
+
+// Receive -------------------------------------------------------------------
+
+int freedv_nin      (struct freedv *freedv);
+int freedv_rx       (struct freedv *freedv, short speech_out[], short demod_in[]);
+int freedv_floatrx  (struct freedv *freedv, short speech_out[], float demod_in[]);
+int freedv_comprx   (struct freedv *freedv, short speech_out[], COMP  demod_in[]);
+int freedv_codecrx  (struct freedv *freedv, unsigned char *packed_codec_bits, short demod_in[]);
+
+// Set parameters ------------------------------------------------------------
+
+void freedv_set_callback_txt            (struct freedv *freedv, freedv_callback_rx rx, freedv_callback_tx tx, void *callback_state);
+void freedv_set_callback_protocol       (struct freedv *freedv, freedv_callback_protorx rx, freedv_callback_prototx tx, void *callback_state);
+void freedv_set_callback_data         (struct freedv *freedv, freedv_callback_datarx datarx, freedv_callback_datatx datatx, void *callback_state);
+void freedv_set_test_frames                        (struct freedv *freedv, int test_frames);
+void freedv_set_test_frames_diversity  (struct freedv *freedv, int test_frames_diversity);
+void freedv_set_smooth_symbols             (struct freedv *freedv, int smooth_symbols);
+void freedv_set_squelch_en                         (struct freedv *freedv, int squelch_en);
+void freedv_set_snr_squelch_thresh         (struct freedv *freedv, float snr_squelch_thresh);
+void freedv_set_clip                   (struct freedv *freedv, int val);
+void freedv_set_total_bit_errors       (struct freedv *freedv, int val);
+void freedv_set_total_bits              (struct freedv *freedv, int val);
+void freedv_set_callback_error_pattern  (struct freedv *freedv, freedv_calback_error_pattern cb, void *state);
+void freedv_set_varicode_code_num       (struct freedv *freedv, int val);
+void freedv_set_data_header             (struct freedv *freedv, unsigned char *header);
+int freedv_set_alt_modem_samp_rate      (struct freedv *freedv, int samp_rate);
+void freedv_set_carrier_ampl            (struct freedv *freedv, int c, float ampl);
+
+// Get parameters -------------------------------------------------------------------------
+
+struct MODEM_STATS;
+int freedv_get_version(void);
+int freedv_get_mode                 (struct freedv *freedv);
+void freedv_get_modem_stats         (struct freedv *freedv, int *sync, float *snr_est);
+void freedv_get_modem_extended_stats(struct freedv *freedv, struct MODEM_STATS *stats);
+int freedv_get_test_frames                     (struct freedv *freedv);
+int freedv_get_n_speech_samples                (struct freedv *freedv);
+int freedv_get_modem_sample_rate       (struct freedv *freedv);
+int freedv_get_n_max_modem_samples     (struct freedv *freedv);
+int freedv_get_n_nom_modem_samples     (struct freedv *freedv);
+int freedv_get_total_bits                      (struct freedv *freedv);
+int freedv_get_total_bit_errors                (struct freedv *freedv);
+int freedv_get_sync                        (struct freedv *freedv);
+struct FSK * freedv_get_fsk(struct freedv *f);
+struct CODEC2 *freedv_get_codec2       (struct freedv *freedv);
+int freedv_get_n_codec_bits             (struct freedv *freedv);
+int freedv_get_sz_error_pattern     (struct freedv *freedv);
+int freedv_get_protocol_bits        (struct freedv *freedv);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/codec2/branches/0.7/src/freedv_api_internal.h b/codec2/branches/0.7/src/freedv_api_internal.h
new file mode 100644 (file)
index 0000000..7ef000c
--- /dev/null
@@ -0,0 +1,241 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_api_internal.h
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2014
+
+  This declares the structure freedv.  A pointer to this structure is
+  returned by the FreeDV API freedv_open() function.  The pointer is used
+  by the other FreeDV API functions declared in freedv_api.h.  This
+  structure is intended to be internal to the FreeDV API.  The public
+  functions are declared in freedv_api.h.  Changes to this structure
+  are expected.  Changes (except additions) to freedv_api.h are
+  discouraged.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+#ifndef __FREEDV__
+
+#include "varicode.h"
+#include "fsk.h"
+#include "fmfsk.h"
+#include "codec2_fdmdv.h"
+#include "codec2_cohpsk.h"
+
+struct quisk_cfFilter {        // Structure to hold the static data for FIR filters
+    float * dCoefs;    // filter coefficients
+    int nBuf;          // dimension of cBuf
+    int nTaps;         // dimension of dSamples, cSamples, dCoefs
+    int decim_index;   // index of next sample for decimation
+    COMP * cSamples;   // storage for old samples
+    COMP * ptcSamp;    // next available position in cSamples
+    COMP * cBuf;       // auxillary buffer for interpolation
+} ;
+
+static int quisk_cfInterpDecim(COMP *, int, struct quisk_cfFilter *, int, int);
+static void quisk_filt_cfInit(struct quisk_cfFilter *, float *, int);
+static void quisk_filt_destroy(struct quisk_cfFilter *);
+static float quiskFilt120t480[480];
+
+struct freedv {
+    int                  mode;
+
+    struct CODEC2       *codec2;
+    struct FDMDV        *fdmdv;
+    struct MODEM_STATS   stats;
+    struct COHPSK       *cohpsk;
+    struct FSK          *fsk;
+    struct FMFSK        *fmfsk;
+    
+    struct freedv_vhf_deframer * deframer;      //Extracts frames from VHF stream
+
+    struct quisk_cfFilter * ptFilter7500to8000;     // Filters to change to/from 7500 and 8000 sps
+    struct quisk_cfFilter * ptFilter8000to7500;
+
+    int                  n_speech_samples;
+    int                  n_nom_modem_samples;    // size of tx and most rx modem sample buffers
+    int                  n_max_modem_samples;    // make your rx modem sample buffers this big
+    int                  n_nat_modem_samples;    // tx modem sample block length as used by the modem before interpolation to output
+
+    int                  modem_sample_rate;      // ATM caller is responsible for meeting this (TBC)
+    int                  clip;                   // non-zero for cohpsk modem output clipping for low PAPR
+
+    unsigned char       *packed_codec_bits;
+    int                 *codec_bits;
+    int                 *tx_bits;
+    int                 *fdmdv_bits;
+    int                 *rx_bits;
+    int                  tx_sync_bit;
+    int                  smooth_symbols;
+    float               *prev_rx_bits;
+    int                  n_codec_bits;           // amount of codec bits in a frame
+
+    int                 *ptest_bits_coh;
+    int                 *ptest_bits_coh_end;
+
+    int                  test_frames;            // set this baby for 1 to tx/rx test frames to look at bit error stats
+    int                  test_frames_diversity;  // 1 -> used combined carriers for error counting on 700 waveforms
+    int                  test_frame_sync_state;
+    int                  test_frame_sync_state_upper;  // when test_frames_diveristy==0 we need extra states for upper carriers
+    int                  test_frame_count;
+    int                  total_bits;
+    int                  total_bit_errors;
+    int                  sz_error_pattern;
+
+    /* optional user defined function to pass error pattern when a test frame is received */
+
+    void                *error_pattern_callback_state;
+    void (*freedv_put_error_pattern)(void *error_pattern_callback_state, short error_pattern[], int sz_error_pattern);
+
+    int                  sync;
+    int                  evenframe;
+    float                snr_est;
+    float                snr_squelch_thresh;
+    int                  squelch_en;
+    int                  nin;
+
+    struct VARICODE_DEC  varicode_dec_states;
+    short                tx_varicode_bits[VARICODE_MAX_BITS];
+    int                  nvaricode_bits;
+    int                  varicode_bit_index;
+
+    /* user defined function ptrs to produce and consume ASCII
+      characters using aux txt channel */
+
+    char (*freedv_get_next_tx_char)(void *callback_state);
+    void (*freedv_put_next_rx_char)(void *callback_state, char c);
+    void                *callback_state;
+    
+    /* user defined functions to produce and consume protocol bits */
+    /* Protocol bits are packed MSB-first */
+    void (*freedv_put_next_proto)(void *callback_state, char *proto_bits_packed);
+    void (*freedv_get_next_proto)(void *callback_state, char *proto_bits_packed);
+    void *proto_callback_state;
+    int n_protocol_bits;
+};
+
+// FIR filter suitable for changing rates 7500 to/from 8000
+// Sample 120000 Hz, pass 2700, stop 3730, ripple 0.1dB, atten 100 dB.  Stop 0.03108.
+static float quiskFilt120t480[480] = { -0.000005050567303837, -0.000000267011791999, 0.000000197734700398, 0.000001038946634000,
+ 0.000002322193058869, 0.000004115682735322, 0.000006499942123311, 0.000009551098482930, 0.000013350669444763,
+ 0.000017966192635412, 0.000023463361155584, 0.000029885221425020, 0.000037271082107518, 0.000045630720487935,
+ 0.000054970017069384, 0.000065233162392019, 0.000076360900545177, 0.000088271373315159, 0.000100818605854714,
+ 0.000113853476544409, 0.000127174196746337, 0.000140558396336177, 0.000153744508371709, 0.000166450784469067,
+ 0.000178368313347299, 0.000189176709991702, 0.000198541881389953, 0.000206128795372885, 0.000211604878787747,
+ 0.000214655997661182, 0.000214994859281552, 0.000212358734245594, 0.000206539880117977, 0.000197379393194548,
+ 0.000184780318878738, 0.000168719942655099, 0.000149250512353807, 0.000126511346757621, 0.000100726393185629,
+ 0.000072210925236429, 0.000041365841965015, 0.000008680571408025, -0.000025277165852799, -0.000059865389594949,
+-0.000094384355854646, -0.000128080670195777, -0.000160170174848483, -0.000189854272533545, -0.000216333899003825,
+-0.000238836419299503, -0.000256632149501508, -0.000269058714331757, -0.000275541485292432, -0.000275614059005332,
+-0.000268937472718753, -0.000255317038867589, -0.000234717772155001, -0.000207273956099563, -0.000173297342436372,
+-0.000133280012107173, -0.000087895370243821, -0.000037986085678081, 0.000015440388211825, 0.000071232572821451,
+ 0.000128114399130489, 0.000184710477990398, 0.000239577162514028, 0.000291234779803098, 0.000338204791740229,
+ 0.000379047713684221, 0.000412403761615261, 0.000437031818051652, 0.000451848709179591, 0.000455966225408344,
+ 0.000448726371643413, 0.000429729020814434, 0.000398857326863837, 0.000356297600912998, 0.000302547334727027,
+ 0.000238422248479072, 0.000165048886226905, 0.000083853091464077, -0.000003462782744354, -0.000094949813106744,
+-0.000188451833293202, -0.000281651282503015, -0.000372121907291206, -0.000457387566635848, -0.000534985542936898,
+-0.000602532044011899, -0.000657788245032425, -0.000698728981427767, -0.000723604675185869, -0.000731002305621048,
+-0.000719899536922384, -0.000689709694056092, -0.000640319946685634, -0.000572115873292030, -0.000485996080304965,
+-0.000383371840261246, -0.000266155252511831, -0.000136731311264191, 0.000002082667095075, 0.000147092077716480,
+ 0.000294790953130229, 0.000441441918072383, 0.000583164190168290, 0.000716029226064227, 0.000836164238172957,
+ 0.000939856052624227, 0.001023657909064450, 0.001084492755093968, 0.001119751426837743, 0.001127383039339373,
+ 0.001105974243787613, 0.001054815583369999, 0.000973950761085690, 0.000864209315714227, 0.000727219011746881,
+ 0.000565398080608305, 0.000381924396468366, 0.000180685902835315, -0.000033793183292569, -0.000256444114966522,
+-0.000481764526566339, -0.000703946352348464, -0.000917016099829735, -0.001114986581270253, -0.001292014799874503,
+-0.001442563411804926, -0.001561559957317790, -0.001644551048567398, -0.001687846581475964, -0.001688649703502788,
+-0.001645167889846890, -0.001556702802350076, -0.001423714708648073, -0.001247857669697092, -0.001031986722557201,
+-0.000780131048444402, -0.000497436825078657, -0.000190077210351809, 0.000134868279325909, 0.000469563533327739,
+ 0.000805591531546815, 0.001134152328775355, 0.001446279849797673, 0.001733071409562941, 0.001985924997799762,
+ 0.002196778054604388, 0.002358342626407065, 0.002464328098407475, 0.002509648218888532, 0.002490604086803692,
+ 0.002405037734357425, 0.002252452724297770, 0.002034094661603120, 0.001752990365583534, 0.001413941154886139,
+ 0.001023470495638453, 0.000589723521647734, 0.000122320866350319, -0.000367832138027160, -0.000868777013398284,
+-0.001367771151677059, -0.001851587344265625, -0.002306838088978190, -0.002720317947026380, -0.003079353614002113,
+-0.003372155891804708, -0.003588162376578369, -0.003718362558663737, -0.003755596511143005, -0.003694818131674599,
+-0.003533315298404129, -0.003270878754553819, -0.002909914962857412, -0.002455496391464944, -0.001915346645364514,
+-0.001299757227227888, -0.000621437066532776, 0.000104706515738248, 0.000861849931067767, 0.001631595707499856,
+ 0.002394368911341672, 0.003129858565588139, 0.003817496679992245, 0.004436963307209760, 0.004968707287606522,
+ 0.005394469536085115, 0.005697797543539088, 0.005864537618023589, 0.005883292537600076, 0.005745832319314692,
+ 0.005447447099071761, 0.004987231255534477, 0.004368289529377007, 0.003597859022418248, 0.002687338851256991,
+ 0.001652226293162047, 0.000511956075882180, -0.000710356149138656, -0.001988263330091648, -0.003292424566049982,
+-0.004591123342747130, -0.005850857852106148, -0.007036991266043732, -0.008114450164977267, -0.009048456200082230,
+-0.009805276478965942, -0.010352975302354198, -0.010662152577592631, -0.010706650669328861, -0.010464214075017983,
+-0.009917087295446811, -0.009052534679222271, -0.007863270920348924, -0.006347789704693751, -0.004510582323649121,
+-0.002362238055733795, 0.000080576968834213, 0.002795265196543707, 0.005753566158586979, 0.008921944932552510,
+ 0.012262093950265378, 0.015731539846483594, 0.019284344624007944, 0.022871886384520687, 0.026443706729191677,
+ 0.029948406200633094, 0.033334570666910354, 0.036551709955124537, 0.039551189200810140, 0.042287133974308874,
+ 0.044717290029466283, 0.046803820535016104, 0.048514022996355009, 0.049820951883635139, 0.050703932928426454,
+ 0.051148959210315710, 0.051148959210315710, 0.050703932928426454, 0.049820951883635139, 0.048514022996355009,
+ 0.046803820535016104, 0.044717290029466283, 0.042287133974308874, 0.039551189200810140, 0.036551709955124537,
+ 0.033334570666910354, 0.029948406200633094, 0.026443706729191677, 0.022871886384520687, 0.019284344624007944,
+ 0.015731539846483594, 0.012262093950265378, 0.008921944932552510, 0.005753566158586979, 0.002795265196543707,
+ 0.000080576968834213, -0.002362238055733795, -0.004510582323649121, -0.006347789704693751, -0.007863270920348924,
+-0.009052534679222271, -0.009917087295446811, -0.010464214075017983, -0.010706650669328861, -0.010662152577592631,
+-0.010352975302354198, -0.009805276478965942, -0.009048456200082230, -0.008114450164977267, -0.007036991266043732,
+-0.005850857852106148, -0.004591123342747130, -0.003292424566049982, -0.001988263330091648, -0.000710356149138656,
+ 0.000511956075882180, 0.001652226293162047, 0.002687338851256991, 0.003597859022418248, 0.004368289529377007,
+ 0.004987231255534477, 0.005447447099071761, 0.005745832319314692, 0.005883292537600076, 0.005864537618023589,
+ 0.005697797543539088, 0.005394469536085115, 0.004968707287606522, 0.004436963307209760, 0.003817496679992245,
+ 0.003129858565588139, 0.002394368911341672, 0.001631595707499856, 0.000861849931067767, 0.000104706515738248,
+-0.000621437066532776, -0.001299757227227888, -0.001915346645364514, -0.002455496391464944, -0.002909914962857412,
+-0.003270878754553819, -0.003533315298404129, -0.003694818131674599, -0.003755596511143005, -0.003718362558663737,
+-0.003588162376578369, -0.003372155891804708, -0.003079353614002113, -0.002720317947026380, -0.002306838088978190,
+-0.001851587344265625, -0.001367771151677059, -0.000868777013398284, -0.000367832138027160, 0.000122320866350319,
+ 0.000589723521647734, 0.001023470495638453, 0.001413941154886139, 0.001752990365583534, 0.002034094661603120,
+ 0.002252452724297770, 0.002405037734357425, 0.002490604086803692, 0.002509648218888532, 0.002464328098407475,
+ 0.002358342626407065, 0.002196778054604388, 0.001985924997799762, 0.001733071409562941, 0.001446279849797673,
+ 0.001134152328775355, 0.000805591531546815, 0.000469563533327739, 0.000134868279325909, -0.000190077210351809,
+-0.000497436825078657, -0.000780131048444402, -0.001031986722557201, -0.001247857669697092, -0.001423714708648073,
+-0.001556702802350076, -0.001645167889846890, -0.001688649703502788, -0.001687846581475964, -0.001644551048567398,
+-0.001561559957317790, -0.001442563411804926, -0.001292014799874503, -0.001114986581270253, -0.000917016099829735,
+-0.000703946352348464, -0.000481764526566339, -0.000256444114966522, -0.000033793183292569, 0.000180685902835315,
+ 0.000381924396468366, 0.000565398080608305, 0.000727219011746881, 0.000864209315714227, 0.000973950761085690,
+ 0.001054815583369999, 0.001105974243787613, 0.001127383039339373, 0.001119751426837743, 0.001084492755093968,
+ 0.001023657909064450, 0.000939856052624227, 0.000836164238172957, 0.000716029226064227, 0.000583164190168290,
+ 0.000441441918072383, 0.000294790953130229, 0.000147092077716480, 0.000002082667095075, -0.000136731311264191,
+-0.000266155252511831, -0.000383371840261246, -0.000485996080304965, -0.000572115873292030, -0.000640319946685634,
+-0.000689709694056092, -0.000719899536922384, -0.000731002305621048, -0.000723604675185869, -0.000698728981427767,
+-0.000657788245032425, -0.000602532044011899, -0.000534985542936898, -0.000457387566635848, -0.000372121907291206,
+-0.000281651282503015, -0.000188451833293202, -0.000094949813106744, -0.000003462782744354, 0.000083853091464077,
+ 0.000165048886226905, 0.000238422248479072, 0.000302547334727027, 0.000356297600912998, 0.000398857326863837,
+ 0.000429729020814434, 0.000448726371643413, 0.000455966225408344, 0.000451848709179591, 0.000437031818051652,
+ 0.000412403761615261, 0.000379047713684221, 0.000338204791740229, 0.000291234779803098, 0.000239577162514028,
+ 0.000184710477990398, 0.000128114399130489, 0.000071232572821451, 0.000015440388211825, -0.000037986085678081,
+-0.000087895370243821, -0.000133280012107173, -0.000173297342436372, -0.000207273956099563, -0.000234717772155001,
+-0.000255317038867589, -0.000268937472718753, -0.000275614059005332, -0.000275541485292432, -0.000269058714331757,
+-0.000256632149501508, -0.000238836419299503, -0.000216333899003825, -0.000189854272533545, -0.000160170174848483,
+-0.000128080670195777, -0.000094384355854646, -0.000059865389594949, -0.000025277165852799, 0.000008680571408025,
+ 0.000041365841965015, 0.000072210925236429, 0.000100726393185629, 0.000126511346757621, 0.000149250512353807,
+ 0.000168719942655099, 0.000184780318878738, 0.000197379393194548, 0.000206539880117977, 0.000212358734245594,
+ 0.000214994859281552, 0.000214655997661182, 0.000211604878787747, 0.000206128795372885, 0.000198541881389953,
+ 0.000189176709991702, 0.000178368313347299, 0.000166450784469067, 0.000153744508371709, 0.000140558396336177,
+ 0.000127174196746337, 0.000113853476544409, 0.000100818605854714, 0.000088271373315159, 0.000076360900545177,
+ 0.000065233162392019, 0.000054970017069384, 0.000045630720487935, 0.000037271082107518, 0.000029885221425020,
+ 0.000023463361155584, 0.000017966192635412, 0.000013350669444763, 0.000009551098482930, 0.000006499942123311,
+ 0.000004115682735322, 0.000002322193058869, 0.000001038946634000, 0.000000197734700398, -0.000000267011791999,
+-0.000005050567303837 };
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/codec2/branches/0.7/src/freedv_data_channel.c b/codec2/branches/0.7/src/freedv_data_channel.c
new file mode 100644 (file)
index 0000000..810ed50
--- /dev/null
@@ -0,0 +1,312 @@
+/*---------------------------------------------------------------------------*\\r
+\r
+  FILE........: freedv_data_channel.c\r
+  AUTHOR......: Jeroen Vreeken\r
+  DATE CREATED: 03 March 2016\r
+\r
+  Data channel for ethernet like packets in freedv VHF frames.\r
+  Currently designed for-\r
+  * 2 control bits per frame\r
+  * 4 byte counter bits per frame\r
+  * 64 bits of data per frame\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+  Copyright (C) 2016 Jeroen Vreeken\r
+\r
+  All rights reserved.\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU Lesser General Public License version 2.1, as\r
+  published by the Free Software Foundation.  This program is\r
+  distributed in the hope that it will be useful, but WITHOUT ANY\r
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\r
+  License for more details.\r
+\r
+  You should have received a copy of the GNU Lesser General Public License\r
+  along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#include "freedv_data_channel.h"\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+static unsigned char fdc_header_bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };\r
+\r
+/* CCIT CRC table (0x1201 polynomal) */\r
+static unsigned short fdc_crc_table[256] = {\r
+    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,\r
+    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,\r
+    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,\r
+    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,\r
+    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,\r
+    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,\r
+    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,\r
+    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,\r
+    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,\r
+    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,\r
+    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,\r
+    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,\r
+    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,\r
+    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,\r
+    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,\r
+    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,\r
+    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,\r
+    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,\r
+    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,\r
+    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,\r
+    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,\r
+    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,\r
+    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,\r
+    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,\r
+    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,\r
+    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,\r
+    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,\r
+    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,\r
+    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,\r
+    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,\r
+    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,\r
+    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78\r
+};\r
+\r
+static unsigned short fdc_crc(unsigned char *buffer, size_t len)\r
+{\r
+    unsigned short crc = 0xffff;\r
+    size_t i;\r
+\r
+    for (i = 0; i < len; i++, buffer++) {\r
+        crc = (crc >> 8) ^ fdc_crc_table[(crc ^ *buffer) & 0xff];\r
+    }\r
+\r
+    return crc ^ 0xffff;\r
+}\r
+\r
+/* CRC4 0x03 polynomal */\r
+static unsigned char fdc_crc4(unsigned char *buffer, size_t len)\r
+{\r
+    unsigned char crc = 0x0f;\r
+    size_t i;\r
+    \r
+    for (i = 0; i < len; i++, buffer++) {\r
+        int shift;\r
+       \r
+        for (shift = 7; shift <= 0; shift--) {\r
+            crc <<= 1;\r
+            if ((*buffer >> shift) & 0x1)\r
+                crc |= 1;\r
+            if (crc & 0x10)\r
+                crc ^= 0x03;\r
+       }\r
+    }\r
+    \r
+    return crc & 0x0f;\r
+}\r
\r
+struct freedv_data_channel *freedv_data_channel_create(void)\r
+{\r
+    struct freedv_data_channel *fdc;\r
+  \r
+    fdc = malloc(sizeof(struct freedv_data_channel));\r
+    if (!fdc)\r
+        return NULL;\r
+\r
+    fdc->cb_rx = NULL;\r
+\r
+    freedv_data_set_header(fdc, fdc_header_bcast);\r
+\r
+    memcpy(fdc->rx_header, fdc->tx_header, 8);\r
+    \r
+    return fdc;\r
+}\r
+\r
+void freedv_data_channel_destroy(struct freedv_data_channel *fdc)\r
+{\r
+    free(fdc);\r
+}\r
+\r
+\r
+void freedv_data_set_cb_rx(struct freedv_data_channel *fdc, freedv_data_callback_rx cb, void *state)\r
+{\r
+    fdc->cb_rx = cb;\r
+    fdc->cb_rx_state = state;\r
+}\r
+\r
+void freedv_data_set_cb_tx(struct freedv_data_channel *fdc, freedv_data_callback_tx cb, void *state)\r
+{\r
+    fdc->cb_tx = cb;\r
+    fdc->cb_tx_state = state;\r
+}\r
+\r
+void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int from_bit, int bcast_bit, int crc_bit, int end_bits)\r
+{\r
+    int copy_bits;\r
+    if (end_bits) {\r
+        copy_bits = end_bits;\r
+    } else {\r
+        copy_bits = size;\r
+    }\r
+\r
+    /* New packet? */\r
+    if (fdc->packet_rx_cnt == 0) {\r
+        /* Does the packet have a compressed from field? */\r
+        if (from_bit) {\r
+           /* Compressed from: take the previously received header */\r
+           memcpy(fdc->packet_rx + fdc->packet_rx_cnt, fdc->rx_header, 6);\r
+           fdc->packet_rx_cnt += 6;        \r
+               }\r
+       if (bcast_bit) {\r
+            if (!from_bit) {\r
+                /* Copy from header and modify size and end_bits accordingly */\r
+                memcpy(fdc->packet_rx + fdc->packet_rx_cnt, data, 6);\r
+                fdc->packet_rx_cnt += 6;\r
+                copy_bits -= 6;\r
+                if (copy_bits < 0)\r
+                    copy_bits = 0;\r
+                data += 6;\r
+            }\r
+            /* Compressed to: fill in broadcast address */\r
+            memcpy(fdc->packet_rx + fdc->packet_rx_cnt, fdc_header_bcast, sizeof(fdc_header_bcast));\r
+            fdc->packet_rx_cnt += 6;\r
+       }\r
+        if (crc_bit) {\r
+            unsigned char calc_crc = fdc_crc4(data, size);\r
+            if (calc_crc == end_bits) {\r
+               /* It is a single header field, remember it for later */\r
+                memcpy(fdc->packet_rx + 6, data, 6);\r
+               memcpy(fdc->packet_rx, fdc_header_bcast, 6);\r
+                if (fdc->cb_rx) {\r
+                    fdc->cb_rx(fdc->cb_rx_state, fdc->packet_rx, 12);\r
+                }\r
+            }\r
+            fdc->packet_rx_cnt = 0;\r
+            return;\r
+        }\r
+    }\r
+    \r
+    if (fdc->packet_rx_cnt + copy_bits >= FREEDV_DATA_CHANNEL_PACKET_MAX) {\r
+        /* Something went wrong... this can not be a real packet */\r
+       fdc->packet_rx_cnt = 0;\r
+       return;\r
+    }\r
+\r
+    memcpy(fdc->packet_rx + fdc->packet_rx_cnt, data, copy_bits);\r
+    fdc->packet_rx_cnt += copy_bits;\r
+    \r
+    if (end_bits != 0 && fdc->packet_rx_cnt >= 2) {\r
+        unsigned short calc_crc = fdc_crc(fdc->packet_rx, fdc->packet_rx_cnt - 2);\r
+        unsigned short rx_crc;\r
+       rx_crc = fdc->packet_rx[fdc->packet_rx_cnt - 1] << 8;\r
+        rx_crc |= fdc->packet_rx[fdc->packet_rx_cnt - 2];\r
+\r
+        if (rx_crc == calc_crc) {\r
+            if (fdc->packet_rx_cnt == size) {\r
+               /* It is a single header field, remember it for later */\r
+                memcpy(fdc->rx_header, fdc->packet_rx, 6);\r
+            }\r
+\r
+            /* callback */\r
+            if (fdc->cb_rx) {\r
+                unsigned char tmp[6];\r
+               memcpy(tmp, fdc->packet_rx, 6);\r
+               memcpy(fdc->packet_rx, fdc->packet_rx + 6, 6);\r
+               memcpy(fdc->packet_rx + 6, tmp, 6);\r
+               \r
+               size_t size = fdc->packet_rx_cnt - 2;\r
+                if (size < 12)\r
+                    size = 12;\r
+                fdc->cb_rx(fdc->cb_rx_state, fdc->packet_rx, size);\r
+            }\r
+        }    \r
+        fdc->packet_rx_cnt = 0;\r
+    }\r
+}\r
+\r
+void freedv_data_channel_tx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int *from_bit, int *bcast_bit, int *crc_bit, int *end_bits)\r
+{\r
+    *from_bit = 0;\r
+    *bcast_bit = 0;\r
+    *crc_bit = 0;\r
+    \r
+    if (!fdc->packet_tx_size) {\r
+        fdc->packet_tx_cnt = 0;\r
+       \r
+        if (fdc->cb_tx) {\r
+            fdc->packet_tx_size = FREEDV_DATA_CHANNEL_PACKET_MAX;\r
+            fdc->cb_tx(fdc->cb_tx_state, fdc->packet_tx, &fdc->packet_tx_size);\r
+        }\r
+       if (!fdc->packet_tx_size) {\r
+           /* Nothing to send, insert a header frame */\r
+           memcpy(fdc->packet_tx, fdc->tx_header, size);\r
+            if (size < 8) {\r
+                *end_bits = fdc_crc4(fdc->tx_header, size);\r
+                *crc_bit = 1;\r
+                memcpy(data, fdc->tx_header, size);\r
+\r
+                return;\r
+            } else {\r
+                fdc->packet_tx_size = size;\r
+            }            \r
+       } else {\r
+           /* new packet */\r
+           unsigned short crc;\r
+            unsigned char tmp[6];\r
+            \r
+            *from_bit = !memcmp(fdc->packet_tx + 6, fdc->tx_header, 6);\r
+            *bcast_bit = !memcmp(fdc->packet_tx, fdc_header_bcast, 6);\r
+\r
+            memcpy(tmp, fdc->packet_tx, 6);\r
+           memcpy(fdc->packet_tx, fdc->packet_tx + 6, 6);\r
+           memcpy(fdc->packet_tx + 6, tmp, 6);\r
+\r
+            crc = fdc_crc(fdc->packet_tx, fdc->packet_tx_size);\r
+\r
+           fdc->packet_tx[fdc->packet_tx_size] = crc & 0xff;\r
+           fdc->packet_tx_size++;\r
+           fdc->packet_tx[fdc->packet_tx_size] = (crc >> 8) & 0xff;\r
+           fdc->packet_tx_size++;\r
+           \r
+           if (*from_bit) {\r
+               fdc->packet_tx_cnt = 6;\r
+            } else {\r
+                if (*bcast_bit) {\r
+                    memcpy(fdc->packet_tx + 6, fdc->packet_tx, 6);\r
+                }\r
+            }\r
+            if (*bcast_bit) {\r
+                fdc->packet_tx_cnt += 6;\r
+            }\r
+       }\r
+    }\r
+    if (fdc->packet_tx_size) {\r
+        int copy = fdc->packet_tx_size - fdc->packet_tx_cnt;\r
+       \r
+        if (copy > size) {\r
+            copy = size;\r
+           *end_bits = 0;\r
+        } else {\r
+            *end_bits = copy;\r
+            fdc->packet_tx_size = 0;\r
+        }\r
+        memcpy(data, fdc->packet_tx + fdc->packet_tx_cnt, copy);\r
+        fdc->packet_tx_cnt += copy;\r
+    }\r
+}\r
+\r
+void freedv_data_set_header(struct freedv_data_channel *fdc, unsigned char *header)\r
+{\r
+    unsigned short crc = fdc_crc(header, 6);\r
+\r
+    memcpy(fdc->tx_header, header, 6);\r
+    fdc->tx_header[6] = crc & 0xff;\r
+    fdc->tx_header[7] = (crc >> 8) & 0xff;\r
+}\r
+\r
+int freedv_data_get_n_tx_frames(struct freedv_data_channel *fdc, size_t size)\r
+{\r
+    if (fdc->packet_tx_size == 0)\r
+        return 0;\r
+    /* packet will be send in 'size' byte frames */\r
+    return (fdc->packet_tx_size - fdc->packet_tx_cnt + size-1) / size;\r
+}\r
diff --git a/codec2/branches/0.7/src/freedv_data_channel.h b/codec2/branches/0.7/src/freedv_data_channel.h
new file mode 100644 (file)
index 0000000..e12f6dc
--- /dev/null
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------*\\r
+\r
+  FILE........: freedv_data_channel.h\r
+  AUTHOR......: Jeroen Vreeken\r
+  DATE CREATED: 03 March 2016\r
+\r
+  Data channel for ethernet like packets in freedv VHF frames.\r
+  Currently designed for-\r
+  * 2 control bits per frame\r
+  * 4 byte counter bits per frame\r
+  * 64 bits of data per frame\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+  Copyright (C) 2016 Jeroen Vreeken\r
+\r
+  All rights reserved.\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU Lesser General Public License version 2.1, as\r
+  published by the Free Software Foundation.  This program is\r
+  distributed in the hope that it will be useful, but WITHOUT ANY\r
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\r
+  License for more details.\r
+\r
+  You should have received a copy of the GNU Lesser General Public License\r
+  along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#ifndef _FREEDV_DATA_CHANNEL_H\r
+#define _FREEDV_DATA_CHANNEL_H\r
+\r
+#include <stdlib.h>\r
+\r
+#define FREEDV_DATA_CHANNEL_PACKET_MAX 2048\r
+\r
+typedef void (*freedv_data_callback_rx)(void *, unsigned char *packet, size_t size);\r
+typedef void (*freedv_data_callback_tx)(void *, unsigned char *packet, size_t *size);\r
+\r
+struct freedv_data_channel {\r
+    freedv_data_callback_rx cb_rx;\r
+    void *cb_rx_state;\r
+     freedv_data_callback_tx cb_tx;\r
+    void *cb_tx_state;\r
+   \r
+    unsigned char rx_header[8];\r
+    unsigned char packet_rx[FREEDV_DATA_CHANNEL_PACKET_MAX + 2];\r
+    int packet_rx_cnt;\r
+    \r
+    unsigned char tx_header[8];\r
+    unsigned char packet_tx[FREEDV_DATA_CHANNEL_PACKET_MAX + 2];\r
+    int packet_tx_cnt;\r
+    size_t packet_tx_size;\r
+};\r
+\r
+\r
+struct freedv_data_channel *freedv_data_channel_create(void);\r
+void freedv_data_channel_destroy(struct freedv_data_channel *fdc);\r
+\r
+void freedv_data_set_cb_rx(struct freedv_data_channel *fdc, freedv_data_callback_rx cb, void *state);\r
+void freedv_data_set_cb_tx(struct freedv_data_channel *fdc, freedv_data_callback_tx cb, void *state);\r
+\r
+void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int from_bit, int bcast_bit, int crc_bit, int end_bits);\r
+void freedv_data_channel_tx_frame(struct freedv_data_channel *fdc, unsigned char *data, size_t size, int *from_bit, int *bcast_bit, int *crc_bit, int *end_bits);\r
+\r
+void freedv_data_set_header(struct freedv_data_channel *fdc, unsigned char *header);\r
+int freedv_data_get_n_tx_frames(struct freedv_data_channel *fdc, size_t size);\r
+\r
+#endif /* _FREEDV_DATA_CHANNEL_H */\r
diff --git a/codec2/branches/0.7/src/freedv_rx.c b/codec2/branches/0.7/src/freedv_rx.c
new file mode 100644 (file)
index 0000000..9100a38
--- /dev/null
@@ -0,0 +1,261 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_rx.c
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2014
+
+  Demo receive program for FreeDV API functions, some side information
+  written to freedv_rx_log.txt
+
+  Example usage (all one line):
+
+     codec2-dev/build_linux/src$ ./freedv_tx 1600 ../../raw/ve9qrp_10s.raw - |
+                                 ./freedv_rx 1600 - - | play -t raw -r 8000 -s -2 -
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "freedv_api.h"
+#include "modem_stats.h"
+
+#include "codec2.h"
+
+struct my_callback_state {
+    FILE *ftxt;
+};
+
+void my_put_next_rx_char(void *callback_state, char c) {
+    struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
+    if (pstate->ftxt != NULL) {
+        fprintf(pstate->ftxt, "text msg: %c\n", c);
+    }
+}
+
+void my_put_next_rx_proto(void *callback_state,char *proto_bits){
+    struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
+    if (pstate->ftxt != NULL) {
+        fprintf(pstate->ftxt, "proto chars: %.*s\n",2, proto_bits);
+    }
+}
+
+/* Called when a packet has been received */
+void my_datarx(void *callback_state, unsigned char *packet, size_t size) {
+    struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
+    if (pstate->ftxt != NULL) {
+        size_t i;
+       
+       fprintf(pstate->ftxt, "data (%zd bytes): ", size);
+       for (i = 0; i < size; i++) {
+           fprintf(pstate->ftxt, "0x%02x ", packet[i]);
+       }
+       fprintf(pstate->ftxt, "\n");
+    }
+}
+
+/* Called when a new packet can be send */
+void my_datatx(void *callback_state, unsigned char *packet, size_t *size) {
+    /* This should not happen while receiving.. */
+    fprintf(stderr, "datarx callback called, this should not happen!\n");    
+    *size = 0;
+}
+
+int main(int argc, char *argv[]) {
+    FILE                      *fin, *fout, *ftxt;
+    short                     *speech_out;
+    short                     *demod_in;
+    struct freedv             *freedv;
+    int                        nin, nout, frame = 0;
+    struct my_callback_state   my_cb_state;
+    struct MODEM_STATS         stats;
+    int                        mode;
+    int                        sync;
+    int                        total_bits;
+    int                        total_bit_errors;
+    float                      snr_est;
+    int                        n_speech_samples;
+    int                        n_max_modem_samples;
+    float                      clock_offset;
+    int                        use_codecrx;
+    struct CODEC2             *c2 = NULL;
+    int                        i;
+
+
+    if (argc < 4) {
+       printf("usage: %s 1600|700|700B|700C|2400A|2400B|800XA InputModemSpeechFile OutputSpeechRawFile [--test_frames] [--codecrx]\n", argv[0]);
+       printf("e.g    %s 1600 hts1a_fdmdv.raw hts1a_out.raw txtLogFile\n", argv[0]);
+       exit(1);
+    }
+
+    mode = -1;
+    if (!strcmp(argv[1],"1600"))
+        mode = FREEDV_MODE_1600;
+    if (!strcmp(argv[1],"700"))
+        mode = FREEDV_MODE_700;
+    if (!strcmp(argv[1],"700B"))
+        mode = FREEDV_MODE_700B;
+    if (!strcmp(argv[1],"700C"))
+        mode = FREEDV_MODE_700C;
+    if (!strcmp(argv[1],"2400A"))
+        mode = FREEDV_MODE_2400A;
+    if (!strcmp(argv[1],"2400B"))
+        mode = FREEDV_MODE_2400B;
+    if (!strcmp(argv[1],"800XA"))
+        mode = FREEDV_MODE_800XA;
+    assert(mode != -1);
+
+    if (strcmp(argv[2], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[2],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input raw modem sample file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[3], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[3],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output speech sample file: %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    freedv = freedv_open(mode);
+    assert(freedv != NULL);
+
+    use_codecrx = 0;
+
+    if (argc > 4) {
+        for (i = 4; i < argc; i++) {
+            if (strcmp(argv[i], "--testframes") == 0) {
+                freedv_set_test_frames(freedv, 1);
+            }
+            if (strcmp(argv[i], "--codecrx") == 0) {
+                int c2_mode;
+
+                if (mode == FREEDV_MODE_700)  {
+                   c2_mode = CODEC2_MODE_700;
+               } else if ((mode == FREEDV_MODE_700B)|| (mode == FREEDV_MODE_800XA)) {
+                    c2_mode = CODEC2_MODE_700B;
+                } else {
+                    c2_mode = CODEC2_MODE_1300;
+                }
+                use_codecrx = 1;
+
+                c2 = codec2_create(c2_mode);
+                assert(c2 != NULL);
+            }
+        }
+    }
+    freedv_set_snr_squelch_thresh(freedv, -100.0);
+    freedv_set_squelch_en(freedv, 0);
+
+    n_speech_samples = freedv_get_n_speech_samples(freedv);
+    n_max_modem_samples = freedv_get_n_max_modem_samples(freedv);
+    speech_out = (short*)malloc(sizeof(short)*n_speech_samples);
+    assert(speech_out != NULL);
+    demod_in = (short*)malloc(sizeof(short)*n_max_modem_samples);
+    assert(demod_in != NULL);
+
+    ftxt = fopen("freedv_rx_log.txt","wt");
+    assert(ftxt != NULL);
+    my_cb_state.ftxt = ftxt;
+    freedv_set_callback_txt(freedv, &my_put_next_rx_char, NULL, &my_cb_state);
+    freedv_set_callback_protocol(freedv, &my_put_next_rx_proto, NULL, &my_cb_state);
+    freedv_set_callback_data(freedv, my_datarx, my_datatx, &my_cb_state);
+
+    /* Note we need to work out how many samples demod needs on each
+       call (nin).  This is used to adjust for differences in the tx and rx
+       sample clock frequencies.  Note also the number of output
+       speech samples is time varying (nout). */
+
+    nin = freedv_nin(freedv);
+    while(fread(demod_in, sizeof(short), nin, fin) == nin) {
+        frame++;
+
+        if (use_codecrx == 0) {
+            /* Use the freedv_api to do everything: speech decoding, demodulating */
+            nout = freedv_rx(freedv, speech_out, demod_in);
+        } else {
+            int bits_per_codec_frame = codec2_bits_per_frame(c2);
+            int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+            int codec_frames = freedv_get_n_codec_bits(freedv) / bits_per_codec_frame;
+            int samples_per_frame = codec2_samples_per_frame(c2);
+            unsigned char encoded[bytes_per_codec_frame * codec_frames];
+
+            /* Use the freedv_api to demodulate only */
+            nout = freedv_codecrx(freedv, encoded, demod_in);
+
+            /* deccode the speech ourself (or send it to elsewhere, e.g. network) */
+            if (nout) {
+                unsigned char *enc_frame = encoded;
+                short *speech_frame = speech_out;
+                
+                nout = 0;
+                for (i = 0; i < codec_frames; i++) {
+                    codec2_decode(c2, speech_frame, enc_frame);
+                    enc_frame += bytes_per_codec_frame;
+                    speech_frame += samples_per_frame;
+                    nout += samples_per_frame;
+                }
+            }
+        }
+
+        nin = freedv_nin(freedv);
+
+        fwrite(speech_out, sizeof(short), nout, fout);
+        freedv_get_modem_stats(freedv, &sync, &snr_est);
+        freedv_get_modem_extended_stats(freedv,&stats);
+        total_bit_errors = freedv_get_total_bit_errors(freedv);
+        clock_offset = stats.clock_offset;
+
+        /* log some side info to the txt file */
+
+        if (ftxt != NULL) {
+            fprintf(ftxt, "frame: %d  demod sync: %d  nin:%d demod snr: %3.2f dB  bit errors: %d clock_offset: %f\n",
+                    frame, sync, nin, snr_est, total_bit_errors, clock_offset);
+        }
+
+       /* if this is in a pipeline, we probably don't want the usual
+           buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    if (freedv_get_test_frames(freedv)) {
+        total_bits = freedv_get_total_bits(freedv);
+        total_bit_errors = freedv_get_total_bit_errors(freedv);
+        fprintf(stderr, "bits: %d errors: %d BER: %4.3f\n", total_bits, total_bit_errors, (float)total_bit_errors/total_bits);
+    }
+
+    free(speech_out);
+    free(demod_in);
+    freedv_close(freedv);
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/freedv_tx.c b/codec2/branches/0.7/src/freedv_tx.c
new file mode 100644 (file)
index 0000000..874a9b5
--- /dev/null
@@ -0,0 +1,243 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_tx.c
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2014
+
+  Demo transmit program for FreeDV API functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "freedv_api.h"
+#include "codec2.h"
+
+struct my_callback_state {
+    char  tx_str[80];
+    char *ptx_str;
+    int calls;
+};
+
+char my_get_next_tx_char(void *callback_state) {
+    struct my_callback_state* pstate = (struct my_callback_state*)callback_state;
+    char  c = *pstate->ptx_str++;
+
+    if (*pstate->ptx_str == 0) {
+        pstate->ptx_str = pstate->tx_str;
+    }
+
+    return c;
+}
+
+void my_get_next_proto(void *callback_state,char *proto_bits){
+    struct my_callback_state* cb_states = (struct my_callback_state*)(callback_state);
+    snprintf(proto_bits,3,"%2d",cb_states->calls);
+    cb_states->calls = cb_states->calls + 1;
+}
+
+/* Called when a packet has been received */
+void my_datarx(void *callback_state, unsigned char *packet, size_t size) {
+    /* This should not happen while sending... */
+    fprintf(stderr, "datarx callback called, this should not happen!\n");    
+}
+
+/* Called when a new packet can be send */
+void my_datatx(void *callback_state, unsigned char *packet, size_t *size) {
+    static int data_toggle;
+    
+    /* Data could come from a network interface, here we just make up some */
+    
+    data_toggle = !data_toggle;
+    if (data_toggle) {
+        /* Send a packet with data */
+        int i;
+       for (i = 0; i < 64; i++)
+           packet[i] = i;
+        *size = i;
+    } else {
+        /* set size to zero, the freedv api will insert a header frame */
+        *size = 0;
+    }
+}
+
+
+int main(int argc, char *argv[]) {
+    FILE                     *fin, *fout;
+    short                    *speech_in;
+    short                    *mod_out;
+    struct freedv            *freedv;
+    struct my_callback_state  my_cb_state;
+    int                       mode;
+    int                       n_speech_samples;
+    int                       n_nom_modem_samples;
+    int                       use_codectx;
+    int                       use_datatx;
+    struct CODEC2             *c2;
+    int                       i;
+
+    if (argc < 4) {
+        printf("usage: %s 1600|700|700B|700C|2400A|2400B|800XA InputRawSpeechFile OutputModemRawFile [--testframes] [--codectx] [--datatx]\n", argv[0]);
+        printf("e.g    %s 1600 hts1a.raw hts1a_fdmdv.raw\n", argv[0]);
+        exit(1);
+    }
+
+    mode = -1;
+    if (!strcmp(argv[1],"1600"))
+        mode = FREEDV_MODE_1600;
+    if (!strcmp(argv[1],"700"))
+        mode = FREEDV_MODE_700;
+    if (!strcmp(argv[1],"700B"))
+        mode = FREEDV_MODE_700B;
+    if (!strcmp(argv[1],"700C"))
+        mode = FREEDV_MODE_700C;
+    if (!strcmp(argv[1],"2400A")){
+        mode = FREEDV_MODE_2400A;
+       }
+    if (!strcmp(argv[1],"2400B"))
+        mode = FREEDV_MODE_2400B;
+    if (!strcmp(argv[1],"800XA"))
+        mode = FREEDV_MODE_800XA;
+    assert(mode != -1);
+
+    if (strcmp(argv[2], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[2],"rb")) == NULL ) {
+        fprintf(stderr, "Error opening input raw speech sample file: %s: %s.\n", argv[2], strerror(errno));
+        exit(1);
+    }
+
+    if (strcmp(argv[3], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[3],"wb")) == NULL ) {
+        fprintf(stderr, "Error opening output modem sample file: %s: %s.\n", argv[3], strerror(errno));
+        exit(1);
+    }
+
+    freedv = freedv_open(mode);
+    assert(freedv != NULL);
+
+    use_codectx = 0;
+    use_datatx = 0;
+
+    if (argc > 4) {
+        for (i = 4; i < argc; i++) {
+            if (strcmp(argv[i], "--testframes") == 0) {
+                freedv_set_test_frames(freedv, 1);
+            }
+            if (strcmp(argv[i], "--codectx") == 0) {
+                int c2_mode;
+                
+                if (mode == FREEDV_MODE_700)  {
+                    c2_mode = CODEC2_MODE_700;
+                } else if ((mode == FREEDV_MODE_700B)|| (mode == FREEDV_MODE_800XA)) {
+                    c2_mode = CODEC2_MODE_700B;
+                } else {
+                    c2_mode = CODEC2_MODE_1300;
+                }
+                use_codectx = 1;
+                c2 = codec2_create(c2_mode);
+                assert(c2 != NULL);
+            }
+            if (strcmp(argv[i], "--datatx") == 0) {
+                unsigned char header[6] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc };
+                freedv_set_data_header(freedv, header);
+                use_datatx = 1;
+            }
+        }
+    }
+    freedv_set_snr_squelch_thresh(freedv, -100.0);
+    freedv_set_squelch_en(freedv, 1);
+
+    n_speech_samples = freedv_get_n_speech_samples(freedv);
+    n_nom_modem_samples = freedv_get_n_nom_modem_samples(freedv);
+    speech_in = (short*)malloc(sizeof(short)*n_speech_samples);
+    assert(speech_in != NULL);
+    mod_out = (short*)malloc(sizeof(short)*n_nom_modem_samples);
+    assert(mod_out != NULL);
+
+    /* set up callback for txt msg chars */
+
+    sprintf(my_cb_state.tx_str, "cq cq cq hello world\r");
+    my_cb_state.ptx_str = my_cb_state.tx_str;
+    my_cb_state.calls = 0;
+    freedv_set_callback_txt(freedv, NULL, &my_get_next_tx_char, &my_cb_state);
+    
+    /* set up callback for protocol bits */
+    freedv_set_callback_protocol(freedv, NULL, &my_get_next_proto, &my_cb_state);
+
+    /* set up callback for data packets */
+    freedv_set_callback_data(freedv, my_datarx, my_datatx, &my_cb_state);
+
+    /* OK main loop */
+
+    while(fread(speech_in, sizeof(short), n_speech_samples, fin) == n_speech_samples) {
+        if (use_codectx == 0) {
+            /* Use the freedv_api to do everything: speech encoding, modulating */
+            freedv_tx(freedv, mod_out, speech_in);
+        } else {
+            int bits_per_codec_frame = codec2_bits_per_frame(c2);
+            int bytes_per_codec_frame = (bits_per_codec_frame + 7) / 8;
+            int codec_frames = freedv_get_n_codec_bits(freedv) / bits_per_codec_frame;
+            int samples_per_frame = codec2_samples_per_frame(c2);
+            unsigned char encoded[bytes_per_codec_frame * codec_frames];
+            unsigned char *enc_frame = encoded;
+            short *speech_frame = speech_in;
+            float energy = 0;
+
+            /* Encode the speech ourself (or get it from elsewhere, e.g. network) */
+            for (i = 0; i < codec_frames; i++) {
+                codec2_encode(c2, enc_frame, speech_frame);
+                energy += codec2_get_energy(c2, enc_frame);
+                enc_frame += bytes_per_codec_frame;
+                speech_frame += samples_per_frame;
+            }
+            energy /= codec_frames;
+            fprintf(stderr,"energy:%f\n",energy);
+            /* Is the audio fragment quiet? */
+            if (use_datatx && energy < 1.0) {
+                /* Insert a frame with data instead of speech */
+                freedv_datatx(freedv, mod_out);
+            } else {
+                /* Use the freedv_api to modulate already encoded frames */
+                freedv_codectx(freedv, mod_out, encoded);
+            }
+        }
+
+        fwrite(mod_out, sizeof(short), n_nom_modem_samples, fout);
+
+        /* if this is in a pipeline, we probably don't want the usual
+           buffering to occur */
+
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+    }
+
+    free(speech_in);
+    free(mod_out);
+    freedv_close(freedv);
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/freedv_vhf_framing.c b/codec2/branches/0.7/src/freedv_vhf_framing.c
new file mode 100644 (file)
index 0000000..da3901c
--- /dev/null
@@ -0,0 +1,831 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 11 February 2016
+
+  Framer and deframer for VHF FreeDV modes 'A' and 'B'
+  Currently designed for-
+  * 40ms ota modem frames
+  * 40ms Codec2 1300 frames
+  * 52 bits of Codec2 per frame
+  * 16 bits of unique word per frame
+  * 28 'spare' bits per frame
+  *  - 4 spare bits at front and end of frame (8 total) for padding
+  *  - 20 'protocol' bits, either for higher layers of 'protocol' or
+  *  - 18 'protocol' bits and 2 vericode sidechannel bits
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "freedv_vhf_framing.h"
+
+/* The voice UW of the VHF type A frame */
+static const uint8_t A_uw_v[] =    {0,1,1,0,0,1,1,1,
+                                    1,0,1,0,1,1,0,1};
+
+/* The data UW of the VHF type A frame */
+static const uint8_t A_uw_d[] =    {1,1,1,1,0,0,0,1,
+                                    1,1,1,1,1,1,0,0};
+
+/* Blank VHF type A frame */
+static const uint8_t A_blank[] =   {1,0,1,0,0,1,1,1, /* Padding[0:3] Proto[0:3]   */
+                                    1,0,1,0,0,1,1,1, /* Proto[4:11]               */
+                                    0,0,0,0,0,0,0,0, /* Voice[0:7]                */
+                                    0,0,0,0,0,0,0,0, /* Voice[8:15]               */
+                                    0,0,0,0,0,0,0,0, /* Voice[16:23]              */
+                                    0,1,1,0,0,1,1,1, /* UW[0:7]                   */
+                                    1,0,1,0,1,1,0,1, /* UW[8:15]                  */
+                                    0,0,0,0,0,0,0,0, /* Voice[24:31]              */
+                                    0,0,0,0,0,0,0,0, /* Voice[32:39]              */
+                                    0,0,0,0,0,0,0,0, /* Voice[40:47]              */
+                                    0,0,0,0,0,0,1,0, /* Voice[48:51] Proto[12:15] */
+                                    0,1,1,1,0,0,1,0};/* Proto[16:19] Padding[4:7] */
+                    
+/* Blank VHF type AT (A for TDMA; padding bits not transmitted) frame */
+static const uint8_t AT_blank[] =  {        0,1,1,1, /*              Proto[0:3]   */
+                                    1,0,1,0,0,1,1,1, /* Proto[4:11]               */
+                                    0,0,0,0,0,0,0,0, /* Voice[0:7]                */
+                                    0,0,0,0,0,0,0,0, /* Voice[8:15]               */
+                                    0,0,0,0,0,0,0,0, /* Voice[16:23]              */
+                                    0,1,1,0,0,1,1,1, /* UW[0:7]                   */
+                                    1,0,1,0,1,1,0,1, /* UW[8:15]                  */
+                                    0,0,0,0,0,0,0,0, /* Voice[24:31]              */
+                                    0,0,0,0,0,0,0,0, /* Voice[32:39]              */
+                                    0,0,0,0,0,0,0,0, /* Voice[40:47]              */
+                                    0,0,0,0,0,0,1,0, /* Voice[48:51] Proto[12:15] */
+                                    0,1,1,1        };/* Proto[16:19]              */
+
+/* HF Type B voice UW */
+static const uint8_t B_uw_v[] =    {0,1,1,0,0,1,1,1};
+
+/* HF Type B data UW */
+static const uint8_t B_uw_d[] =    {1,1,1,1,0,0,1,0};
+                                    
+/* Blank HF type B frame */
+static const uint8_t B_blank[] =   {0,1,1,0,0,1,1,1, /* UW[0:7]                                          */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[0:7]                           */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[8:15]                          */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[16:23]                         */
+                                                                       0,0,0,0,0,0,0,0, /* Voice1[24:28] Voice2[0:3] */
+                                                                       0,0,0,0,0,0,0,0, /* Voice2[4:11]                          */
+                                                                       0,0,0,0,0,0,0,0, /* Voice2[12:19]                         */
+                                                                       0,0,0,0,0,0,0,0};/* Voice2[20:28]                         */
+
+/* States */
+#define ST_NOSYNC 0 /* Not synchronized */
+#define ST_SYNC 1   /* Synchronized */
+
+/* Get a single bit out of an MSB-first packed byte array */
+#define UNPACK_BIT_MSBFIRST(bytes,bitidx) ((bytes)[(bitidx)>>3]>>(7-((bitidx)&0x7)))&0x1
+
+enum frame_payload_type {
+    FRAME_PAYLOAD_TYPE_VOICE,
+    FRAME_PAYLOAD_TYPE_DATA,
+};
+
+/* Place codec and other bits into a frame */
+void fvhff_frame_bits(  int frame_type,
+                        uint8_t bits_out[],
+                        uint8_t codec2_in[],
+                        uint8_t proto_in[],
+                        uint8_t vc_in[]){
+    int i,ibit;
+    if(frame_type == FREEDV_VHF_FRAME_A){
+        /* Fill out frame with blank frame prototype */
+        for(i=0; i<96; i++)
+            bits_out[i] = A_blank[i];
+        
+        /* Fill in protocol bits, if present */
+        if(proto_in!=NULL){
+            ibit = 0;
+            /* First half of protocol bits */
+            /* Extract and place in frame, MSB first */
+            for(i=4 ; i<16; i++){
+                bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
+                ibit++;
+            }
+            /* Last set of protocol bits */
+            for(i=84; i<92; i++){
+                bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
+                ibit++;
+            }
+        }
+        
+        /* Fill in varicode bits, if present */
+        if(vc_in!=NULL){
+            bits_out[90] = vc_in[0];
+            bits_out[91] = vc_in[1];
+        }
+        
+        /* Fill in codec2 bits, present or not */
+        ibit = 0;
+        for(i=16; i<40; i++){   /* First half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
+            ibit++;
+        }
+        for(i=56; i<84; i++){   /* Second half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
+            ibit++;
+        }
+    }else if(frame_type == FREEDV_HF_FRAME_B){
+        /* Pointers to both c2 frames so the bit unpack macro works */
+        uint8_t * codec2_in1 = &codec2_in[0];
+        uint8_t * codec2_in2 = &codec2_in[4];
+        /* Fill out frame with blank prototype */
+        for(i=0; i<64; i++)
+            bits_out[i] = B_blank[i];
+        
+        /* Fill out first codec2 block */
+        ibit=0;
+        for(i=8; i<36; i++){
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in1,ibit);
+            ibit++;
+        }
+        /* Fill out second codec2 block */
+        ibit=0;
+        for(i=36; i<64; i++){
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in2,ibit);
+            ibit++;
+        }
+    }else if(frame_type == FREEDV_VHF_FRAME_AT){
+        /* Fill out frame with blank frame prototype */
+        for(i=0; i<88; i++)
+            bits_out[i] = AT_blank[i];
+        
+        /* Fill in protocol bits, if present */
+        if(proto_in!=NULL){
+            ibit = 0;
+            /* First half of protocol bits */
+            /* Extract and place in frame, MSB first */
+            for(i=0 ; i<12; i++){
+                bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
+                ibit++;
+            }
+            /* Last set of protocol bits */
+            for(i=80; i<88; i++){
+                bits_out[i] = UNPACK_BIT_MSBFIRST(proto_in,ibit);
+                ibit++;
+            }
+        }
+        
+        /* Fill in varicode bits, if present */
+        if(vc_in!=NULL){
+            bits_out[86] = vc_in[0];
+            bits_out[87] = vc_in[1];
+        }
+        
+        /* Fill in codec2 bits, present or not */
+        ibit = 0;
+        for(i=12; i<36; i++){   /* First half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
+            ibit++;
+        }
+        for(i=52; i<80; i++){   /* Second half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(codec2_in,ibit);
+            ibit++;
+        }
+    }
+}
+
+/* Place data and other bits into a frame */
+void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,
+                        uint8_t bits_out[]){
+    int i,ibit;
+    if(frame_type == FREEDV_VHF_FRAME_A){
+        uint8_t data[8];
+        int end_bits;
+        int from_bit;
+        int bcast_bit;
+        int crc_bit;
+
+        /* Fill out frame with blank frame prototype */
+        for(i=0; i<4; i++)
+            bits_out[i] = A_blank[i];
+        for(i=92; i<96; i++)
+            bits_out[i] = A_blank[i];
+            
+        /* UW data */
+        for (i=0; i < 16; i++)
+            bits_out[40 + i] = A_uw_d[i];
+        
+        if (def->fdc)
+                freedv_data_channel_tx_frame(def->fdc, data, 8, &from_bit, &bcast_bit, &crc_bit, &end_bits);
+        else
+            return;
+
+        bits_out[4] = from_bit;
+        bits_out[5] = bcast_bit;
+        bits_out[6] = 0; /* unused */
+        bits_out[7] = 0; /* unused */
+
+        /* Fill in data bits */
+        ibit = 0;
+        for(i=8; i<40; i++){   /* First half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
+            ibit++;
+        }
+        for(i=56; i<88; i++){  /* Second half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
+            ibit++;
+        }
+
+        for (i = 0; i < 4; i++)
+            bits_out[88 + i] = (end_bits >> (3-i)) & 0x1;
+    } else if (frame_type == FREEDV_HF_FRAME_B){
+        uint8_t data[6];
+        int end_bits;
+        int from_bit;
+        int bcast_bit;
+        int crc_bit;
+
+        /* Fill out frame with blank prototype */
+        for(i=0; i<64; i++)
+            bits_out[i] = B_blank[i];
+
+        /* UW data */
+        for (i=0; i < 8; i++)
+            bits_out[0 + i] = B_uw_d[i];
+        
+        if (def->fdc)
+            freedv_data_channel_tx_frame(def->fdc, data, 6, &from_bit, &bcast_bit, &crc_bit, &end_bits);
+        else
+            return;
+
+        bits_out[56] = from_bit;
+        bits_out[57] = bcast_bit;
+        bits_out[58] = crc_bit;
+        bits_out[59] = 0; /* unused */
+
+        /* Fill in data bits */
+        ibit = 0;
+        for(i=8; i<56; i++){   /* First half */
+            bits_out[i] = UNPACK_BIT_MSBFIRST(data,ibit);
+            ibit++;
+        }
+        for (i = 0; i < 4; i++)
+            bits_out[60 + i] = (end_bits >> (3-i)) & 0x1;
+    }
+}
+
+/* Init and allocate memory for a freedv-vhf framer/deframer */
+struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type, int enable_bit_flip){
+    struct freedv_vhf_deframer * deframer;
+    uint8_t *bits,*invbits;
+    int frame_size;
+    int uw_size;
+    
+    assert( (frame_type == FREEDV_VHF_FRAME_A) || (frame_type == FREEDV_HF_FRAME_B) );
+    
+    /* It's a Type A frame */
+    if(frame_type == FREEDV_VHF_FRAME_A){
+        frame_size = 96;
+        uw_size = 16;
+    }else if(frame_type == FREEDV_HF_FRAME_B){
+        frame_size = 64;
+        uw_size = 8;
+    }else{
+        return NULL;
+    }
+    
+    /* Allocate memory for the thing */
+    deframer = malloc(sizeof(struct freedv_vhf_deframer));
+    if(deframer == NULL)
+        return NULL;
+        
+    /* Allocate the not-bit buffer */
+    if(enable_bit_flip){
+        invbits = malloc(sizeof(uint8_t)*frame_size);
+        if(invbits == NULL)
+            return NULL;
+    }else{
+        invbits = NULL;
+    }
+    
+    /* Allocate the bit buffer */
+    bits = malloc(sizeof(uint8_t)*frame_size);
+    if(bits == NULL)
+        return NULL;
+    
+    deframer->bits = bits;
+    deframer->invbits = invbits;
+    deframer->ftype = frame_type;
+    deframer->state = ST_NOSYNC;
+    deframer->bitptr = 0;
+    deframer->last_uw = 0;
+    deframer->miss_cnt = 0;
+    deframer->frame_size = frame_size;
+    deframer->uw_size = uw_size;
+    deframer->on_inv_bits = 0;
+    deframer->sym_size = 1;
+    
+    deframer->ber_est = 0;
+    deframer->total_uw_bits = 0;
+    deframer->total_uw_err = 0;
+    
+    deframer->fdc = NULL;
+
+    return deframer;
+}
+
+/* Get size of frame in bits */
+int fvhff_get_frame_size(struct freedv_vhf_deframer * def){
+    return def->frame_size;
+}
+
+/* Codec2 size in bytes */
+int fvhff_get_codec2_size(struct freedv_vhf_deframer * def){
+    if(def->ftype == FREEDV_VHF_FRAME_A){
+        return 7;
+    } else if(def->ftype == FREEDV_HF_FRAME_B){
+        return 8;
+    } else{
+        return 0;
+    }
+}
+
+/* Protocol bits in bits */
+int fvhff_get_proto_size(struct freedv_vhf_deframer * def){
+    if(def->ftype == FREEDV_VHF_FRAME_A){
+        return 20;
+    } else if(def->ftype == FREEDV_HF_FRAME_B){
+        return 0;
+    } else{
+        return 0;
+    }
+}
+
+/* Varicode bits in bits */
+int fvhff_get_varicode_size(struct freedv_vhf_deframer * def){
+    if(def->ftype == FREEDV_VHF_FRAME_A){
+        return 2;
+    } else if(def->ftype == FREEDV_HF_FRAME_B){
+        return 0;
+    } else{
+        return 0;
+    }
+}
+
+void fvhff_destroy_deframer(struct freedv_vhf_deframer * def){
+    freedv_data_channel_destroy(def->fdc);
+    free(def->bits);
+    free(def);
+}
+
+int fvhff_synchronized(struct freedv_vhf_deframer * def){
+    return (def->state) == ST_SYNC;
+}
+
+/* See if the UW is where it should be, to within a tolerance, in a bit buffer */
+static int fvhff_match_uw(struct freedv_vhf_deframer * def,uint8_t bits[],int tol,int *rdiff, enum frame_payload_type *pt){
+    int frame_type  = def->ftype;
+    int bitptr      = def->bitptr;
+    int frame_size  = def->frame_size;
+    int uw_len      = def->uw_size;
+    int iuw,ibit;
+    const uint8_t * uw[2];
+    int uw_offset;
+    int diff[2] = { 0, 0 };
+    int i;
+    int match[2];
+    int r;
+
+    /* defaults to make compiler happy on -O3 */
+
+    *pt = FRAME_PAYLOAD_TYPE_VOICE; 
+    *rdiff = 0;
+
+    /* Set up parameters for the standard type of frame */
+    if(frame_type == FREEDV_VHF_FRAME_A){
+        uw[0] = A_uw_v;
+        uw[1] = A_uw_d;
+        uw_len = 16;
+        uw_offset = 40;
+    } else if(frame_type == FREEDV_HF_FRAME_B){
+        uw[0] = B_uw_v;
+        uw[1] = B_uw_d;
+        uw_len = 8;
+        uw_offset = 0;
+    } else {
+        return 0;
+    }
+    
+    /* Check both the voice and data UWs */
+    for (i = 0; i < 2; i++) {
+        /* Start bit pointer where UW should be */
+        ibit = bitptr + uw_offset;
+        if(ibit >= frame_size) ibit -= frame_size;
+        /* Walk through and match bits in frame with bits of UW */
+        for(iuw=0; iuw<uw_len; iuw++){
+            if(bits[ibit] != uw[i][iuw]) diff[i]++;
+            ibit++;
+            if(ibit >= frame_size) ibit = 0;
+        }
+        match[i] = diff[i] <= tol;
+    }
+    /* Pick the best matching UW */
+
+    if (diff[0] < diff[1]) {
+        r = match[0];
+        *rdiff = diff[0];
+        *pt = FRAME_PAYLOAD_TYPE_VOICE;
+    } else {
+        r = match[1];
+        *rdiff = diff[1];
+        *pt = FRAME_PAYLOAD_TYPE_DATA;
+    }
+    
+    return r;
+}
+
+static void fvhff_extract_frame_voice(struct freedv_vhf_deframer * def,uint8_t bits[],uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[]){
+    int frame_type  = def->ftype;
+    int bitptr      = def->bitptr;
+    int frame_size  = def->frame_size;
+    int iframe,ibit;
+    
+    if(frame_type == FREEDV_VHF_FRAME_A){
+        /* Extract codec2 bits */
+        memset(codec2_out,0,7);
+        ibit = 0;
+        /* Extract and pack first half, MSB first */
+        iframe = bitptr+16;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<24;ibit++){
+            codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        
+        /* Extract and pack last half, MSB first */
+        iframe = bitptr+56;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<52;ibit++){
+            codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        /* Extract varicode bits, if wanted */
+        if(vc_out!=NULL){
+            iframe = bitptr+90;
+            if(iframe >= frame_size) iframe-=frame_size;
+            vc_out[0] = bits[iframe];
+            iframe++;
+            vc_out[1] = bits[iframe];
+        }
+        /* Extract protocol bits, if proto is passed through */
+        if(proto_out!=NULL){
+            /* Clear protocol bit array */
+            memset(proto_out,0,3);
+            ibit = 0;
+            /* Extract and pack first half, MSB first */
+            iframe = bitptr+4;
+            if(iframe >= frame_size) iframe-=frame_size;
+            for(;ibit<12;ibit++){
+                proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+                iframe++;
+                if(iframe >= frame_size) iframe=0;
+            }
+            
+            /* Extract and pack last half, MSB first */
+            iframe = bitptr+84;
+            if(iframe >= frame_size) iframe-=frame_size;
+            for(;ibit<20;ibit++){
+                proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+                iframe++;
+                if(iframe >= frame_size) iframe=0;
+            }
+        }
+
+    }else if(frame_type == FREEDV_HF_FRAME_B){
+        /* Pointers to both c2 frames */
+        uint8_t * codec2_out1 = &codec2_out[0];
+        uint8_t * codec2_out2 = &codec2_out[4];
+        
+        /* Extract codec2 bits */
+        memset(codec2_out,0,8);
+        ibit = 0;
+        
+        /* Extract and pack first c2 frame, MSB first */
+        iframe = bitptr+8;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<28;ibit++){
+            codec2_out1[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        
+        /* Extract and pack second c2 frame, MSB first */
+        iframe = bitptr+36;
+        ibit = 0;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<28;ibit++){
+            codec2_out2[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+    }else if(frame_type == FREEDV_VHF_FRAME_AT){
+        /* Extract codec2 bits */
+        memset(codec2_out,0,7);
+        ibit = 0;
+        /* Extract and pack first half, MSB first */
+        iframe = bitptr+12;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<24;ibit++){
+            codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        
+        /* Extract and pack last half, MSB first */
+        iframe = bitptr+52;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<52;ibit++){
+            codec2_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        /* Extract varicode bits, if wanted */
+        if(vc_out!=NULL){
+            iframe = bitptr+86;
+            if(iframe >= frame_size) iframe-=frame_size;
+            vc_out[0] = bits[iframe];
+            iframe++;
+            vc_out[1] = bits[iframe];
+        }
+        /* Extract protocol bits, if proto is passed through */
+        if(proto_out!=NULL){
+            /* Clear protocol bit array */
+            memset(proto_out,0,3);
+            ibit = 0;
+            /* Extract and pack first half, MSB first */
+            iframe = bitptr+4;
+            if(iframe >= frame_size) iframe-=frame_size;
+            for(;ibit<12;ibit++){
+                proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+                iframe++;
+                if(iframe >= frame_size) iframe=0;
+            }
+            
+            /* Extract and pack last half, MSB first */
+            iframe = bitptr+84;
+            if(iframe >= frame_size) iframe-=frame_size;
+            for(;ibit<20;ibit++){
+                proto_out[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+                iframe++;
+                if(iframe >= frame_size) iframe=0;
+            }
+        }
+
+    }
+}
+
+static void fvhff_extract_frame_data(struct freedv_vhf_deframer * def,uint8_t bits[]){
+    int frame_type  = def->ftype;
+    int bitptr      = def->bitptr;
+    int frame_size  = def->frame_size;
+    int iframe,ibit;
+    
+    if(frame_type == FREEDV_VHF_FRAME_A){
+        uint8_t data[8];
+        int end_bits = 0;
+        int from_bit;
+        int bcast_bit;
+    
+        iframe = bitptr+4;
+        if(iframe >= frame_size) iframe-=frame_size;
+        from_bit = bits[iframe];
+        iframe++;
+        if(iframe >= frame_size) iframe-=frame_size;
+        bcast_bit = bits[iframe];
+
+        /* Extract data bits */
+        memset(data,0,8);
+        ibit = 0;
+        /* Extract and pack first half, MSB first */
+        iframe = bitptr+8;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<32;ibit++){
+            data[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+        
+        /* Extract and pack last half, MSB first */
+        iframe = bitptr+56;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<64;ibit++){
+            data[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+
+        /* Extract endbits value, MSB first*/
+        iframe = bitptr+88;
+        ibit = 0;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<4;ibit++){
+            end_bits |= (bits[iframe]&0x1)<<(3-(ibit));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+    
+        if (def->fdc) {
+            freedv_data_channel_rx_frame(def->fdc, data, 8, from_bit, bcast_bit, 0, end_bits);
+        }
+    } else if(frame_type == FREEDV_HF_FRAME_B){
+        uint8_t data[6];
+        int end_bits = 0;
+        int from_bit;
+        int bcast_bit;
+       int crc_bit;
+        
+        ibit = 0;
+        memset(data,0,6);
+        
+        /* Extract and pack first c2 frame, MSB first */
+        iframe = bitptr+8;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<48;ibit++){
+            data[ibit>>3] |= (bits[iframe]&0x1)<<(7-(ibit&0x7));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+
+        iframe = bitptr+56;
+        if(iframe >= frame_size) iframe-=frame_size;
+        from_bit = bits[iframe];
+        iframe++;
+        if(iframe >= frame_size) iframe-=frame_size;
+        bcast_bit = bits[iframe];
+        iframe++;
+        if(iframe >= frame_size) iframe-=frame_size;
+        crc_bit = bits[iframe];
+        
+        /* Extract endbits value, MSB first*/
+        iframe = bitptr+60;
+        ibit = 0;
+        if(iframe >= frame_size) iframe-=frame_size;
+        for(;ibit<4;ibit++){
+            end_bits |= (bits[iframe]&0x1)<<(3-(ibit));
+            iframe++;
+            if(iframe >= frame_size) iframe=0;
+        }
+
+        if (def->fdc) {
+            freedv_data_channel_rx_frame(def->fdc, data, 6, from_bit, bcast_bit, crc_bit, end_bits);
+        }
+    }
+}
+
+static void fvhff_extract_frame(struct freedv_vhf_deframer * def,uint8_t bits[],uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[],enum frame_payload_type pt){
+    switch (pt) {
+        case FRAME_PAYLOAD_TYPE_VOICE:
+        fvhff_extract_frame_voice(def, bits, codec2_out, proto_out, vc_out);
+        break;
+    case FRAME_PAYLOAD_TYPE_DATA:
+        fvhff_extract_frame_data(def, bits);
+        break;
+    }
+}
+
+/*
+ * Try to find the UW and extract codec/proto/vc bits in def->frame_size bits 
+ */
+int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[],uint8_t bits_in[]){
+    uint8_t * strbits  = def->bits;
+    uint8_t * invbits  = def->invbits;
+    uint8_t * bits;
+    int on_inv_bits = def->on_inv_bits;
+    int frame_type  = def->ftype;
+    int state       = def->state;
+    int bitptr      = def->bitptr;
+    int last_uw     = def->last_uw;
+    int miss_cnt    = def->miss_cnt;
+    int frame_size  = def->frame_size;
+    int uw_size     = def->uw_size;
+    int uw_diff;
+    int i;
+    int uw_first_tol;   
+    int uw_sync_tol;
+    int miss_tol;
+    int extracted_frame = 0;
+    enum frame_payload_type pt = FRAME_PAYLOAD_TYPE_VOICE;
+    
+    /* Possibly set up frame-specific params here */
+    if(frame_type == FREEDV_VHF_FRAME_A){
+        uw_first_tol = 1;   /* The UW bit-error tolerance for the first frame */
+        uw_sync_tol = 3;    /* The UW bit error tolerance for frames after sync */
+        miss_tol = 4;       /* How many UWs may be missed before going into the de-synced state */
+    }else if(frame_type == FREEDV_HF_FRAME_B){
+        uw_first_tol = 0;   /* The UW bit-error tolerance for the first frame */
+        uw_sync_tol = 1;    /* The UW bit error tolerance for frames after sync */
+        miss_tol = 3;       /* How many UWs may be missed before going into the de-synced state */
+    }else{
+        return 0;
+    }
+    /* Skip N bits for multi-bit symbol modems */
+    for(i=0; i<frame_size; i++){
+        /* Put a bit in the buffer */
+        strbits[bitptr] = bits_in[i];
+        /* If we're checking the inverted bitstream, put a bit in it */
+        if(invbits!=NULL)
+            invbits[bitptr] = bits_in[i]?0:1;
+        
+        bitptr++;
+        if(bitptr >= frame_size) bitptr -= frame_size;
+        def->bitptr = bitptr;
+        /* Enter state machine */
+        if(state==ST_SYNC){
+            /* Already synchronized, just wait till UW is back where it should be */
+            last_uw++;
+            if(invbits!=NULL){
+                if(on_inv_bits)
+                    bits = invbits;
+                else
+                    bits = strbits;
+            }else{
+                bits=strbits;
+            }
+            /* UW should be here. We're sunk, so deframe anyway */
+            if(last_uw == frame_size){
+                last_uw = 0;
+                
+                if(!fvhff_match_uw(def,bits,uw_sync_tol,&uw_diff, &pt))
+                    miss_cnt++;
+                else
+                    miss_cnt=0;
+                
+                /* If we go over the miss tolerance, go into no-sync */
+                if(miss_cnt>miss_tol){
+                    state = ST_NOSYNC;
+                }
+                /* Extract the bits */
+                extracted_frame = 1;
+                fvhff_extract_frame(def,bits,codec2_out,proto_out,vc_out,pt);
+                
+                /* Update BER estimate */
+                def->ber_est = (.995*def->ber_est) + (.005*((float)uw_diff)/((float)uw_size));
+                def->total_uw_bits += uw_size;
+                def->total_uw_err += uw_diff;
+            }
+        /* Not yet sunk */
+        }else{
+            /* It's a sync!*/
+            if(invbits!=NULL){
+                if(fvhff_match_uw(def,invbits,uw_first_tol, &uw_diff, &pt)){
+                    state = ST_SYNC;
+                    last_uw = 0;
+                    miss_cnt = 0;
+                    extracted_frame = 1;
+                    on_inv_bits = 1;
+                    fvhff_extract_frame(def,invbits,codec2_out,proto_out,vc_out,pt);
+                    /* Update BER estimate */
+                    def->ber_est = (.995*def->ber_est) + (.005*((float)uw_diff)/((float)uw_size));
+                    def->total_uw_bits += uw_size;
+                    def->total_uw_err += uw_diff;
+                }
+            }
+            if(fvhff_match_uw(def,strbits,uw_first_tol, &uw_diff, &pt)){
+                state = ST_SYNC;
+                last_uw = 0;
+                miss_cnt = 0;
+                extracted_frame = 1;
+                on_inv_bits = 0;
+                fvhff_extract_frame(def,strbits,codec2_out,proto_out,vc_out,pt);
+                /* Update BER estimate */
+                def->ber_est = (.995*def->ber_est) + (.005*((float)uw_diff)/((float)uw_size));
+                def->total_uw_bits += uw_size;
+                def->total_uw_err += uw_diff;
+            }
+        }
+    }
+    def->state = state;
+    def->last_uw = last_uw;
+    def->miss_cnt = miss_cnt;
+    def->on_inv_bits = on_inv_bits;
+    /* return zero for data frames, they are already handled by callback */
+    return extracted_frame && pt == FRAME_PAYLOAD_TYPE_VOICE;
+}
diff --git a/codec2/branches/0.7/src/freedv_vhf_framing.h b/codec2/branches/0.7/src/freedv_vhf_framing.h
new file mode 100644 (file)
index 0000000..85f6e7b
--- /dev/null
@@ -0,0 +1,93 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_vhf_framing.h
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 11 February 2016
+
+  Framer and deframer for VHF FreeDV modes 'A' and 'B'
+  Currently designed for-
+  * 40ms ota modem frames
+  * 40ms Codec2 1300 frames
+  * 52 bits of Codec2 per frame
+  * 16 bits of unique word per frame
+  * 28 'spare' bits per frame
+  *  - 4 spare bits at front and end of frame (8 total) for padding
+  *  - 20 'protocol' bits, either for higher layers of 'protocol' or
+  *  - 18 'protocol' bits and 2 vericode sidechannel bits
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _FREEDV_VHF_FRAMING_H\r
+#define _FREEDV_VHF_FRAMING_H\r
+\r
+#include "freedv_data_channel.h"\r
+\r
+/* Standard frame type */\r
+#define FREEDV_VHF_FRAME_A 1    /* 2400A/B Frame */
+#define FREEDV_HF_FRAME_B 2     /* 800XA Frame */
+#define FREEDV_VHF_FRAME_AT 3   /* 4800T Frame */\r
+\r
+struct freedv_vhf_deframer {
+    int ftype;          /* Type of frame to be looking for */
+    int state;          /* State of deframer */
+    uint8_t * bits;     /* Bits currently being decanted */
+    uint8_t * invbits;  /* Inversion of bits currently being decanted, for FMFSK */
+    
+    int bitptr;         /* Pointer into circular bit buffer */
+    int miss_cnt;       /* How many UWs have been missed */
+    int last_uw;        /* How many bits since the last UW? */\r
+    int frame_size;     /* How big is a frame? */
+    int uw_size;        /* How big is the UW */\r
+    int on_inv_bits;    /* Are we using the inverted bits? */
+    int sym_size;       /* How many bits in a modem symbol */ \r
+
+    float ber_est;      /* Bit error rate estimate */
+    int total_uw_bits;  /* Total RX-ed bits of UW */
+    int total_uw_err;   /* Total errors in UW bits */
+\r
+    struct freedv_data_channel *fdc;\r
+};\r
+\r
+/* Init and allocate memory for a freedv-vhf framer/deframer */\r
+struct freedv_vhf_deframer * fvhff_create_deframer(uint8_t frame_type,int enable_bit_flip);
+
+/* Get size of various frame parameters */
+/* Frame size in bits */
+int fvhff_get_frame_size(struct freedv_vhf_deframer * def);
+/* Codec2 size in bytes */
+int fvhff_get_codec2_size(struct freedv_vhf_deframer * def);
+/* Protocol bits in bits */
+int fvhff_get_proto_size(struct freedv_vhf_deframer * def);
+/* Varicode bits in bits */
+int fvhff_get_varicode_size(struct freedv_vhf_deframer * def);
+
+/* Free the memory used by a freedv-vhf framer/deframer */
+void fvhff_destroy_deframer(struct freedv_vhf_deframer * def);
+\r
+/* Place codec and other bits into a frame */\r
+void fvhff_frame_bits(int frame_type,uint8_t bits_out[],uint8_t codec2_in[],uint8_t proto_in[],uint8_t vc_in[]);\r
+void fvhff_frame_data_bits(struct freedv_vhf_deframer * def, int frame_type,uint8_t bits_out[]);
+\r
+/* Find and extract frames from a stream of bits */\r
+int fvhff_deframe_bits(struct freedv_vhf_deframer * def,uint8_t codec2_out[],uint8_t proto_out[],uint8_t vc_out[],uint8_t bits_in[]);\r
+
+/* Is the de-framer synchronized? */
+int fvhff_synchronized(struct freedv_vhf_deframer * def);
+
+#endif //_FREEDV_VHF_FRAMING_H
diff --git a/codec2/branches/0.7/src/fsk.c b/codec2/branches/0.7/src/fsk.c
new file mode 100644 (file)
index 0000000..931f846
--- /dev/null
@@ -0,0 +1,1105 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 7 January 2016
+
+  C Implementation of 2/4FSK modulator/demodulator, based on octave/fsk_horus.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*---------------------------------------------------------------------------*\
+
+                               DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+/* P oversampling rate constant -- should probably be init-time configurable */
+#define horus_P 8
+
+/* Define this to enable EbNodB estimate */
+/* This needs square roots, may take more cpu time than it's worth */
+#define EST_EBNO
+
+/* This is a flag to make the mod/demod allocate their memory on the stack instead of the heap */
+/* At large sample rates, there's not enough stack space to run the demod */
+#define DEMOD_ALLOC_STACK
+
+/* This is a flag for the freq. estimator to use a precomputed/rt computed hann window table
+   On platforms with slow cosf, this will produce a substantial speedup at the cost of a small
+    amount of memory 
+*/
+#define USE_HANN_TABLE
+
+/* This flag turns on run-time hann table generation. If USE_HANN_TABLE is unset,
+    this flag has no effect. If USE_HANN_TABLE is set and this flag is set, the
+    hann table will be allocated and generated when fsk_init or fsk_init_hbr is 
+    called. If this flag is not set, a hann function table of size fsk->Ndft MUST
+    be provided. On small platforms, this can be used with a precomputed table to
+    save memory at the cost of flash space.
+*/
+#define GENERATE_HANN_TABLE_RUNTIME
+
+/* Turn off table generation if on cortex M4 to save memory */
+#ifdef CORTEX_M4
+#undef USE_HANN_TABLE
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+                               INCLUDES
+
+\*---------------------------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "fsk.h"
+#include "comp_prim.h"
+#include "kiss_fftr.h"
+#include "modem_probe.h"
+
+/*---------------------------------------------------------------------------*\
+
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+
+#ifdef USE_HANN_TABLE
+/*
+   This is used by fsk_create and fsk_create_hbr to generate a hann function
+   table
+*/
+static void fsk_generate_hann_table(struct FSK* fsk){
+    int Ndft = fsk->Ndft;
+    size_t i;
+
+    /* Set up complex oscilator to calculate hann function */
+    COMP dphi = comp_exp_j((2*M_PI)/((float)Ndft-1));
+    COMP rphi = {.5,0};
+    
+    rphi = cmult(cconj(dphi),rphi);
+    
+    for(i=0; i<Ndft; i++){
+        rphi = cmult(dphi,rphi);
+        float hannc = .5-rphi.real;
+        //float hann = .5-(.5*cosf((2*M_PI*(float)(i))/((float)Ndft-1)));
+        
+        fsk->hann_table[i] = hannc;
+    }  
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fsk_create_hbr
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 11 February 2016
+  
+  Create and initialize an instance of the FSK modem. Returns a pointer
+  to the modem state/config struct. One modem config struct may be used
+  for both mod and demod. returns NULL on failure.
+
+\*---------------------------------------------------------------------------*/
+
+struct FSK * fsk_create_hbr(int Fs, int Rs,int P,int M, int tx_f1, int tx_fs)
+{
+    struct FSK *fsk;
+    int i;
+    int memold;
+    int Ndft = 0;
+    /* Number of symbols in a processing frame */
+    int nsyms = 48;
+    /* Check configuration validity */
+    assert(Fs > 0 );
+    assert(Rs > 0 );
+    assert(tx_f1 > 0);
+    assert(tx_fs > 0);
+    assert(P > 0);
+    /* Ts (Fs/Rs) must be an integer */
+    assert( (Fs%Rs) == 0 );
+    /* Ts/P (Fs/Rs/P) must be an integer */
+    assert( ((Fs/Rs)%P) == 0 );
+    assert( M==2 || M==4);
+    
+    fsk = (struct FSK*) malloc(sizeof(struct FSK));
+    if(fsk == NULL) return NULL;
+     
+    
+    /* Set constant config parameters */
+    fsk->Fs = Fs;
+    fsk->Rs = Rs;
+    fsk->Ts = Fs/Rs;
+    fsk->N = fsk->Ts*nsyms;
+    fsk->P = P;
+    fsk->Nsym = nsyms;
+    fsk->Nmem = fsk->N+(2*fsk->Ts);
+    fsk->f1_tx = tx_f1;
+    fsk->fs_tx = tx_fs;
+    fsk->nin = fsk->N;
+    fsk->mode = M==2 ? MODE_2FSK : MODE_4FSK;
+    fsk->Nbits = M==2 ? fsk->Nsym : fsk->Nsym*2;
+    
+    /* Find smallest 2^N value that fits Fs for efficient FFT */
+    /* It would probably be better to use KISS-FFt's routine here */
+    for(i=1; i; i<<=1)
+        if((fsk->N)&i)
+            Ndft = i;
+    
+    fsk->Ndft = Ndft;
+    
+    fsk->est_min = Rs/2;
+    if(fsk->est_min<0) fsk->est_min = 0;
+    
+    fsk->est_max = (Fs/2)-Rs;
+    
+    fsk->est_space = Rs-(Rs/5);
+    
+    /* Set up rx state */
+    
+    for( i=0; i<M; i++)
+        fsk->phi_c[i] = comp_exp_j(0);
+    
+    memold = (4*fsk->Ts);
+    
+    fsk->nstash = memold; 
+    fsk->samp_old = (COMP*) malloc(sizeof(COMP)*memold);
+    if(fsk->samp_old == NULL){
+        free(fsk);
+        return NULL;
+    }
+    
+    for(i=0;i<memold;i++) {
+        fsk->samp_old[i].real = 0;
+        fsk->samp_old[i].imag = 0;
+    }
+
+    fsk->fft_cfg = kiss_fft_alloc(fsk->Ndft,0,NULL,NULL);
+    if(fsk->fft_cfg == NULL){
+        free(fsk->samp_old);
+        free(fsk);
+        return NULL;
+    }
+    
+    fsk->fft_est = (float*)malloc(sizeof(float)*fsk->Ndft/2);
+    if(fsk->fft_est == NULL){
+        free(fsk->samp_old);
+        free(fsk->fft_cfg);
+        free(fsk);
+        return NULL;
+    }
+    
+    #ifdef USE_HANN_TABLE
+        #ifdef GENERATE_HANN_TABLE_RUNTIME
+            fsk->hann_table = (float*)malloc(sizeof(float)*fsk->Ndft);
+            if(fsk->hann_table == NULL){
+                free(fsk->fft_est);
+                free(fsk->samp_old);
+                free(fsk->fft_cfg);
+                free(fsk);
+                return NULL;
+            }
+            fsk_generate_hann_table(fsk);
+        #else
+            fsk->hann_table = NULL;
+        #endif
+    #endif
+    
+    for(i=0;i<fsk->Ndft/2;i++)fsk->fft_est[i] = 0;
+    
+    fsk->norm_rx_timing = 0;
+    
+    /* Set up tx state */
+    fsk->tx_phase_c = comp_exp_j(0);
+    
+    /* Set up demod stats */
+    fsk->EbNodB = 0;
+    
+    for( i=0; i<M; i++)
+        fsk->f_est[i] = 0;
+    
+    fsk->ppm = 0;
+
+    fsk->stats = (struct MODEM_STATS*)malloc(sizeof(struct MODEM_STATS));
+    if(fsk->stats == NULL){
+        free(fsk->fft_est);
+        free(fsk->samp_old);
+        free(fsk->fft_cfg);
+        free(fsk);
+        return NULL;
+    }
+    fsk->normalise_eye = 1;
+
+    return fsk;
+}
+
+#define HORUS_MIN 800
+#define HORUS_MAX 2500
+#define HORUS_MIN_SPACING 100
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fsk_create
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 7 January 2016
+  
+  Create and initialize an instance of the FSK modem. Returns a pointer
+  to the modem state/config struct. One modem config struct may be used
+  for both mod and demod. returns NULL on failure.
+
+\*---------------------------------------------------------------------------*/
+
+struct FSK * fsk_create(int Fs, int Rs,int M, int tx_f1, int tx_fs)
+{
+    struct FSK *fsk;
+    int i;
+    int Ndft = 0;
+    int memold;
+    
+    /* Check configuration validity */
+    assert(Fs > 0 );
+    assert(Rs > 0 );
+    assert(tx_f1 > 0);
+    assert(tx_fs > 0);
+    assert(horus_P > 0);
+    /* Ts (Fs/Rs) must be an integer */
+    assert( (Fs%Rs) == 0 );
+    /* Ts/P (Fs/Rs/P) must be an integer */
+    assert( ((Fs/Rs)%horus_P) == 0 );
+    assert( M==2 || M==4);
+    
+    fsk = (struct FSK*) malloc(sizeof(struct FSK));
+    if(fsk == NULL) return NULL;
+     
+    Ndft = 1024;
+    
+    /* Set constant config parameters */
+    fsk->Fs = Fs;
+    fsk->Rs = Rs;
+    fsk->Ts = Fs/Rs;
+    fsk->N = Fs;
+    fsk->P = horus_P;
+    fsk->Nsym = fsk->N/fsk->Ts;
+    fsk->Ndft = Ndft;
+    fsk->Nmem = fsk->N+(2*fsk->Ts);
+    fsk->f1_tx = tx_f1;
+    fsk->fs_tx = tx_fs;
+    fsk->nin = fsk->N;
+    fsk->mode = M==2 ? MODE_2FSK : MODE_4FSK;
+    fsk->Nbits = M==2 ? fsk->Nsym : fsk->Nsym*2;
+    fsk->est_min = HORUS_MIN;
+    fsk->est_max = HORUS_MAX;
+    fsk->est_space = HORUS_MIN_SPACING;
+    
+    /* Set up rx state */
+    for( i=0; i<M; i++)
+        fsk->phi_c[i] = comp_exp_j(0);
+    
+    memold = (4*fsk->Ts);
+    
+    fsk->nstash = memold; 
+    fsk->samp_old = (COMP*) malloc(sizeof(COMP)*memold);
+    if(fsk->samp_old == NULL){
+        free(fsk);
+        return NULL;
+    }
+    
+    for(i=0;i<memold;i++) {
+        fsk->samp_old[i].real = 0.0;
+        fsk->samp_old[i].imag = 0.0;
+    }
+    
+    fsk->fft_cfg = kiss_fft_alloc(Ndft,0,NULL,NULL);
+    if(fsk->fft_cfg == NULL){
+        free(fsk->samp_old);
+        free(fsk);
+        return NULL;
+    }
+    
+    fsk->fft_est = (float*)malloc(sizeof(float)*fsk->Ndft/2);
+    if(fsk->fft_est == NULL){
+        free(fsk->samp_old);
+        free(fsk->fft_cfg);
+        free(fsk);
+        return NULL;
+    }
+    
+    #ifdef USE_HANN_TABLE
+        #ifdef GENERATE_HANN_TABLE_RUNTIME
+            fsk->hann_table = (float*)malloc(sizeof(float)*fsk->Ndft);
+            if(fsk->hann_table == NULL){
+                free(fsk->fft_est);
+                free(fsk->samp_old);
+                free(fsk->fft_cfg);
+                free(fsk);
+                return NULL;
+            }
+            fsk_generate_hann_table(fsk);
+        #else
+            fsk->hann_table = NULL;
+        #endif
+    #endif
+    
+    for(i=0;i<Ndft/2;i++)fsk->fft_est[i] = 0;
+    
+    fsk->norm_rx_timing = 0;
+    
+    /* Set up tx state */
+    fsk->tx_phase_c = comp_exp_j(0);
+    
+    /* Set up demod stats */
+    fsk->EbNodB = 0;
+    
+    for( i=0; i<M; i++)
+        fsk->f_est[i] = 0; 
+    
+    fsk->ppm = 0;
+    
+    fsk->stats = (struct MODEM_STATS*)malloc(sizeof(struct MODEM_STATS));
+    if(fsk->stats == NULL){
+        free(fsk->fft_est);
+        free(fsk->samp_old);
+        free(fsk->fft_cfg);
+        free(fsk);
+        return NULL;
+    }
+    fsk->normalise_eye = 1;
+
+    return fsk;
+}
+
+
+void fsk_set_nsym(struct FSK *fsk,int nsyms){
+    assert(nsyms>0);
+    int Ndft,i;
+    Ndft = 0;
+    
+    /* Set constant config parameters */
+    fsk->N = fsk->Ts*nsyms;
+    fsk->Nsym = nsyms;
+    fsk->Nmem = fsk->N+(2*fsk->Ts);
+    fsk->nin = fsk->N;
+    fsk->Nbits = fsk->mode==2 ? fsk->Nsym : fsk->Nsym*2;
+    
+    /* Find smallest 2^N value that fits Fs for efficient FFT */
+    /* It would probably be better to use KISS-FFt's routine here */
+    for(i=1; i; i<<=1)
+        if((fsk->N)&i)
+            Ndft = i;
+    
+    fsk->Ndft = Ndft;
+    
+    free(fsk->fft_cfg);
+    free(fsk->fft_est);
+    
+    fsk->fft_cfg = kiss_fft_alloc(Ndft,0,NULL,NULL);
+    fsk->fft_est = (float*)malloc(sizeof(float)*fsk->Ndft/2);
+    
+    for(i=0;i<Ndft/2;i++)fsk->fft_est[i] = 0;
+    
+}
+
+
+void fsk_clear_estimators(struct FSK *fsk){
+    int i;
+    /* Clear freq estimator state */
+    for(i=0; i < (fsk->Ndft/2); i++){
+        fsk->fft_est[i] = 0;
+    }
+    /* Reset timing diff correction */
+    fsk->nin = fsk->N;
+}
+
+uint32_t fsk_nin(struct FSK *fsk){
+    return (uint32_t)fsk->nin;
+}
+
+void fsk_destroy(struct FSK *fsk){
+    free(fsk->fft_cfg);
+    free(fsk->samp_old);
+    free(fsk->stats);
+    free(fsk);
+}
+
+void fsk_get_demod_stats(struct FSK *fsk, struct MODEM_STATS *stats){
+    /* copy from internal stats, note we can't overwrite stats completely
+       as it has other states rqd by caller, also we want a consistent
+       interface across modem types for the freedv_api.
+    */
+
+    stats->clock_offset = fsk->stats->clock_offset;
+    stats->snr_est = fsk->stats->snr_est;           // TODO: make this SNR not Eb/No
+    stats->rx_timing = fsk->stats->rx_timing;
+    stats->foff = fsk->stats->foff;
+
+    stats->neyesamp = fsk->stats->neyesamp;
+    stats->neyetr = fsk->stats->neyetr;
+    memcpy(stats->rx_eye, fsk->stats->rx_eye, sizeof(stats->rx_eye));
+
+    /* these fields not used for FSK so set to something sensible */
+
+    stats->sync = 0;
+    stats->nr = fsk->stats->nr;
+    stats->Nc = fsk->stats->Nc;
+}
+
+/*
+ * Set the minimum and maximum frequencies at which the freq. estimator can find tones
+ */
+void fsk_set_est_limits(struct FSK *fsk,int est_min, int est_max){
+    
+    fsk->est_min = est_min;
+    if(fsk->est_min<0) fsk->est_min = 0;
+    
+    fsk->est_max = est_max;
+}
+
+/*
+ * Internal function to estimate the frequencies of the two tones within a block of samples.
+ * This is split off because it is fairly complicated, needs a bunch of memory, and probably
+ * takes more cycles than the rest of the demod.
+ * Parameters:
+ * fsk - FSK struct from demod containing FSK config
+ * fsk_in - block of samples in this demod cycles, must be nin long
+ * freqs - Array for the estimated frequencies
+ * M - number of frequency peaks to find
+ */
+void fsk_demod_freq_est(struct FSK *fsk, COMP fsk_in[],float *freqs,int M){
+    int Ndft = fsk->Ndft;
+    int Fs = fsk->Fs;
+    int nin = fsk->nin;
+    size_t i,j;
+    int fft_samps;
+    float hann;
+    float max;
+    float tc;
+    int imax;
+    kiss_fft_cfg fft_cfg = fsk->fft_cfg;
+    int freqi[M];
+    int f_min,f_max,f_zero;
+    
+    /* Array to do complex FFT from using kiss_fft */
+    #ifdef DEMOD_ALLOC_STACK
+    kiss_fft_cpx *fftin  = (kiss_fft_cpx*)alloca(sizeof(kiss_fft_cpx)*Ndft);
+    kiss_fft_cpx *fftout = (kiss_fft_cpx*)alloca(sizeof(kiss_fft_cpx)*Ndft);
+    #else
+    kiss_fft_cpx *fftin  = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx)*Ndft);
+    kiss_fft_cpx *fftout = (kiss_fft_cpx*)malloc(sizeof(kiss_fft_cpx)*Ndft);
+    #endif
+    
+    #ifndef USE_HANN_TABLE
+    COMP dphi = comp_exp_j((2*M_PI)/((float)Ndft-1));
+    COMP rphi = {.5,0};
+    rphi = cmult(cconj(dphi),rphi);
+    #endif
+
+    fft_samps = Ndft;
+    
+    f_min  = (fsk->est_min*Ndft)/Fs;
+    f_max  = (fsk->est_max*Ndft)/Fs;
+    f_zero = (fsk->est_space*Ndft)/Fs;
+  
+    /* scale averaging time constant based on number of samples */
+    tc = 0.95*Ndft/Fs;
+    
+    int fft_loops = nin/Ndft;
+    for(j=0; j<fft_loops; j++){
+    /* Copy FSK buffer into reals of FFT buffer and apply a hann window */
+        for(i=0; i<fft_samps; i++){
+            #ifdef USE_HANN_TABLE
+            hann = fsk->hann_table[i];
+            #else
+            //hann = 1-cosf((2*M_PI*(float)(i))/((float)fft_samps-1));
+            rphi = cmult(dphi,rphi);
+            hann = .5-rphi.real;
+            #endif
+            fftin[i].r = hann*fsk_in[i+Ndft*j].real;
+            fftin[i].i = hann*fsk_in[i+Ndft*j].imag;
+        }
+        /* Zero out the remaining slots */
+        for(; i<Ndft;i++){
+            fftin[i].r = 0;
+            fftin[i].i = 0;
+        }
+        
+        /* Do the FFT */
+        kiss_fft(fft_cfg,fftin,fftout);
+        
+        /* Find the magnitude^2 of each freq slot and stash away in the real
+        * value, so this only has to be done once. Since we're only comparing
+        * these values and only need the mag of 2 points, we don't need to do
+        * a sqrt to each value */
+        for(i=0; i<Ndft/2; i++){
+            fftout[i].r = (fftout[i].r*fftout[i].r) + (fftout[i].i*fftout[i].i) ;
+        }
+        
+        /* Zero out the minimum and maximum ends */
+        for(i=0; i<f_min; i++){
+            fftout[i].r = 0;
+        }
+        for(i=f_max-1; i<Ndft/2; i++){
+            fftout[i].r = 0;
+        }
+        /* Mix back in with the previous fft block */
+        /* Copy new fft est into imag of fftout for frequency divination below */
+        for(i=0; i<Ndft/2; i++){
+            fsk->fft_est[i] = (fsk->fft_est[i]*(1-tc)) + (sqrtf(fftout[i].r)*tc);
+            fftout[i].i = fsk->fft_est[i];
+        }
+    }
+    
+    modem_probe_samp_f("t_fft_est",fsk->fft_est,Ndft/2);
+    
+    max = 0;
+    /* Find the M frequency peaks here */
+    for(i=0; i<M; i++){
+        imax = 0;
+        max = 0;
+        for(j=0;j<Ndft/2;j++){
+            if(fftout[j].i > max){
+                max = fftout[j].i;
+                imax = j;
+            }
+        }
+        /* Blank out FMax +/-Fspace/2 */
+        f_min = imax - f_zero;
+        f_min = f_min < 0 ? 0 : f_min;
+        f_max = imax + f_zero;
+        f_max = f_max > Ndft ? Ndft : f_max;
+        for(j=f_min; j<f_max; j++)
+            fftout[j].i = 0;
+        
+        /* Stick the freq index on the list */
+        freqi[i] = imax;
+    }
+    
+    /* Gnome sort the freq list */
+    /* My favorite sort of sort*/
+    i = 1;
+    while(i<M){
+        if(freqi[i] >= freqi[i-1]) i++;
+        else{
+            j = freqi[i];
+            freqi[i] = freqi[i-1];
+            freqi[i-1] = j;
+            if(i>1) i--;
+        }
+    }
+
+    /* Convert freqs from indices to frequencies */
+    for(i=0; i<M; i++){
+        freqs[i] = (float)(freqi[i])*((float)Fs/(float)Ndft);
+    }
+    #ifndef DEMOD_ALLOC_STACK
+    free(fftin);
+    free(fftout);
+    #endif
+}
+
+void fsk2_demod(struct FSK *fsk, uint8_t rx_bits[], float rx_sd[], COMP fsk_in[]){
+    int N = fsk->N;
+    int Ts = fsk->Ts;
+    int Rs = fsk->Rs;
+    int Fs = fsk->Fs;
+    int nsym = fsk->Nsym;
+    int nin = fsk->nin;
+    int P = fsk->P;
+    int Nmem = fsk->Nmem;
+    int M = fsk->mode;
+    size_t i,j,m,dc_i,cbuf_i;
+    float ft1;
+    int nstash = fsk->nstash;
+    
+    COMP* f_int[M];     /* Filtered and downsampled symbol tones */
+    COMP t[M];          /* complex number temps */
+    COMP t_c;           /* another complex temp */
+    COMP phi_c[M];  
+    COMP phi_ft;        
+    int nold = Nmem-nin;
+    
+    COMP dphi[M];
+    COMP dphift;
+    float rx_timing,norm_rx_timing,old_norm_rx_timing,d_norm_rx_timing,appm;
+    int using_old_samps;
+
+    COMP* sample_src;
+    COMP* f_intbuf_m;
+    
+    float f_est[M],fc_avg,fc_tx;
+    float meanebno,stdebno,eye_max;
+    int neyesamp,neyeoffset;
+    
+    #ifdef MODEMPROBE_ENABLE
+    char mp_name_tmp[20]; /* Temporary string for modem probe trace names */
+    #endif
+    
+    /* Load up demod phases from struct */
+    for( m=0; m<M; m++)
+        phi_c[m] = fsk->phi_c[m];
+    
+    /* Estimate tone frequencies */
+    fsk_demod_freq_est(fsk,fsk_in,f_est,M);
+    modem_probe_samp_f("t_f_est",f_est,M);
+    
+    
+    /* Allocate circular buffer for integration */
+    #ifdef DEMOD_ALLOC_STACK
+    f_intbuf_m = (COMP*) alloca(sizeof(COMP)*Ts);
+    #else
+    f_intbuf_m = (COMP*) malloc(sizeof(COMP)*Ts);    
+    #endif
+    
+    /* allocate memory for the integrated samples */
+    for( m=0; m<M; m++){
+        #ifdef DEMOD_ALLOC_STACK
+        /* allocate memory for the integrated samples */
+        /* Note: This must be kept after fsk_demod_freq_est for memory usage reasons */
+        f_int[m] = (COMP*) alloca(sizeof(COMP)*(nsym+1)*P);
+        
+        #else
+        f_int[m] = (COMP*) malloc(sizeof(COMP)*(nsym+1)*P);
+        #endif
+    }
+    
+    /* If this is the first run, we won't have any valid f_est */
+    /* TODO: add first_run flag to FSK to make negative freqs possible */
+    if(fsk->f_est[0]<1){
+        for( m=0; m<M; m++)
+            fsk->f_est[m] = f_est[m];
+    }
+    
+    /* Initalize downmixers for each symbol tone */
+    for( m=0; m<M; m++){
+        /* Back the stored phase off to account for re-integraton of old samples */
+        dphi[m] = comp_exp_j(-2*(Nmem-nin-(Ts/P))*M_PI*((fsk->f_est[m])/(float)(Fs)));
+        phi_c[m] = cmult(dphi[m],phi_c[m]);
+
+        /* Figure out how much to nudge each sample downmixer for every sample */
+        dphi[m] = comp_exp_j(2*M_PI*((fsk->f_est[m])/(float)(Fs)));
+    }
+    
+    /* Integrate and downsample for symbol tones */
+    for(m=0; m<M; m++){
+        /* Copy buffer pointers in to avoid second buffer indirection */
+        float f_est_m = f_est[m];
+        COMP* f_int_m = &(f_int[m][0]);
+        COMP dphi_m = dphi[m];
+        
+        dc_i = 0;
+        cbuf_i = 0;
+        sample_src = &(fsk->samp_old[nstash-nold]);
+        using_old_samps = 1;
+        
+        /* Pre-fill integration buffer */
+        for(dc_i=0; dc_i<Ts-(Ts/P); dc_i++){
+            /* Switch sample source to new samples when we run out of old ones */
+            if(dc_i>=nold && using_old_samps){
+                sample_src = &fsk_in[0];
+                dc_i = 0;
+                using_old_samps = 0;
+                
+                /* Recalculate delta-phi after switching to new sample source */
+                phi_c[m] = comp_normalize(phi_c[m]);
+                dphi_m = comp_exp_j(2*M_PI*((f_est_m)/(float)(Fs)));
+            }
+            /* Downconvert and place into integration buffer */
+            f_intbuf_m[dc_i]=cmult(sample_src[dc_i],cconj(phi_c[m]));
+            
+            #ifdef MODEMPROBE_ENABLE
+            snprintf(mp_name_tmp,19,"t_f%zd_dc",m+1);
+            modem_probe_samp_c(mp_name_tmp,&f_intbuf_m[dc_i],1);
+            #endif
+            /* Spin downconversion phases */
+            phi_c[m] = cmult(phi_c[m],dphi_m);
+        }
+        cbuf_i = dc_i;
+        
+        /* Integrate over Ts at offsets of Ts/P */
+        for(i=0; i<(nsym+1)*P; i++){
+            /* Downconvert and Place Ts/P samples in the integration buffers */
+            for(j=0; j<(Ts/P); j++,dc_i++){
+                /* Switch sample source to new samples when we run out of old ones */
+                if(dc_i>=nold && using_old_samps){
+                    sample_src = &fsk_in[0];
+                    dc_i = 0;
+                    using_old_samps = 0;
+                    
+                    /* Recalculate delta-phi after switching to new sample source */
+                    phi_c[m] = comp_normalize(phi_c[m]);
+                    dphi_m = comp_exp_j(2*M_PI*((f_est_m)/(float)(Fs)));
+                }
+                /* Downconvert and place into integration buffer */
+                f_intbuf_m[cbuf_i+j]=cmult(sample_src[dc_i],cconj(phi_c[m]));
+        
+                #ifdef MODEMPROBE_ENABLE
+                snprintf(mp_name_tmp,19,"t_f%zd_dc",m+1);
+                modem_probe_samp_c(mp_name_tmp,&f_intbuf_m[cbuf_i+j],1);
+                #endif
+                /* Spin downconversion phases */
+                phi_c[m] = cmult(phi_c[m],dphi_m);
+                
+            }
+            
+            /* Dump internal samples */
+            cbuf_i += Ts/P;
+            if(cbuf_i>=Ts) cbuf_i = 0;
+            
+            /* Integrate over the integration buffers, save samples */
+            float it_r = 0;
+            float it_i = 0;
+            for(j=0; j<Ts; j++){
+                it_r += f_intbuf_m[j].real;
+                it_i += f_intbuf_m[j].imag;
+            }
+            f_int_m[i].real = it_r;
+            f_int_m[i].imag = it_i;
+        }
+    }
+    
+    /* Save phases back into FSK struct */
+    for(m=0; m<M; m++){
+        fsk->phi_c[m] = phi_c[m];
+        fsk->f_est[m] = f_est[m];
+    }
+
+    /* Stash samples away in the old sample buffer for the next round of bit getting */
+    memcpy((void*)&(fsk->samp_old[0]),(void*)&(fsk_in[nin-nstash]),sizeof(COMP)*nstash);
+    
+    /* Fine Timing Estimation */
+    /* Apply magic nonlinearity to f1_int and f2_int, shift down to 0, 
+     * extract angle */
+     
+    /* Figure out how much to spin the oscillator to extract magic spectral line */
+    dphift = comp_exp_j(2*M_PI*((float)(Rs)/(float)(P*Rs)));
+    phi_ft.real = 1;
+    phi_ft.imag = 0;
+    t_c=comp0();
+    for(i=0; i<(nsym+1)*P; i++){
+        /* Get abs^2 of fx_int[i], and add 'em */
+        ft1 = 0;
+        for( m=0; m<M; m++){
+            ft1 += (f_int[m][i].real*f_int[m][i].real) + (f_int[m][i].imag*f_int[m][i].imag);
+        }
+        
+        /* Down shift and accumulate magic line */
+        t_c = cadd(t_c,fcmult(ft1,phi_ft));
+
+        /* Spin the oscillator for the magic line shift */
+        phi_ft = cmult(phi_ft,dphift);
+    }
+    /* Get the magic angle */
+    norm_rx_timing =  atan2f(t_c.imag,t_c.real)/(2*M_PI);
+    rx_timing = norm_rx_timing*(float)P;
+    
+    old_norm_rx_timing = fsk->norm_rx_timing;
+    fsk->norm_rx_timing = norm_rx_timing;
+    
+    /* Estimate sample clock offset */
+    d_norm_rx_timing = norm_rx_timing - old_norm_rx_timing;
+    
+    /* Filter out big jumps in due to nin change */
+    if(fabsf(d_norm_rx_timing) < .2){
+        appm = 1e6*d_norm_rx_timing/(float)nsym;
+        fsk->ppm = .9*fsk->ppm + .1*appm;
+    }
+    
+    /* Figure out how many samples are needed the next modem cycle */
+    if(norm_rx_timing > 0.25)
+        fsk->nin = N+Ts/2;
+    else if(norm_rx_timing < -0.25)
+        fsk->nin = N-Ts/2;
+    else
+        fsk->nin = N;
+    
+    modem_probe_samp_f("t_norm_rx_timing",&(norm_rx_timing),1);
+    modem_probe_samp_i("t_nin",&(fsk->nin),1);
+    
+    /* Re-sample the integrators with linear interpolation magic */
+    int low_sample = (int)floorf(rx_timing);
+    float fract = rx_timing - (float)low_sample;
+    int high_sample = (int)ceilf(rx_timing);
+    /* Vars for finding the max-of-4 for each bit */
+    float tmax[M];
+    
+    #ifdef EST_EBNO
+    meanebno = 0;
+    stdebno = 0;
+    #endif
+  
+    /* FINALLY, THE BITS */
+    /* also, resample fx_int */
+    for(i=0; i<nsym; i++){
+        int st = (i+1)*P;
+        for( m=0; m<M; m++){
+            t[m] =           fcmult(1-fract,f_int[m][st+ low_sample]);
+            t[m] = cadd(t[m],fcmult(  fract,f_int[m][st+high_sample]));
+            /* Figure mag^2 of each resampled fx_int */
+            tmax[m] = (t[m].real*t[m].real) + (t[m].imag*t[m].imag);
+        }
+        
+        float max = tmax[0]; /* Maximum for figuring correct symbol */
+        float min = tmax[0];
+        int sym = 0; /* Index of maximum */
+        for( m=0; m<M; m++){
+            if(tmax[m]>max){
+                max = tmax[m];
+                sym = m;
+            }
+            if(tmax[m]<min){
+                min = tmax[m];
+            }
+        }
+        
+        /* Get the actual bit */
+        if(rx_bits != NULL){
+            /* Get bits for 2FSK and 4FSK */
+            /* TODO: Replace this with something more generic maybe */
+            if(M==2){
+                rx_bits[i] = sym==1;                /* 2FSK. 1 bit per symbol */
+            }else if(M==4){
+                rx_bits[(i*2)+1] = (sym&0x1);       /* 4FSK. 2 bits per symbol */
+                rx_bits[(i*2)  ] = (sym&0x2)>>1;
+            }
+        }
+        
+        /* Produce soft decision symbols */
+        if(rx_sd != NULL){
+            /* Convert symbols from max^2 into max */
+            for( m=0; m<M; m++)
+                tmax[m] = sqrtf(tmax[m]);
+            
+            if(M==2){
+                rx_sd[i] = tmax[0] - tmax[1];
+            }else if(M==4){
+                /* TODO: Find a soft-decision mode that works for 4FSK */
+                min = sqrtf(min);
+                rx_sd[(i*2)+1] = - tmax[0] ;  /* Bits=00 */
+                rx_sd[(i*2)  ] = - tmax[0] ;
+                rx_sd[(i*2)+1]+=   tmax[1] ;  /* Bits=01 */
+                rx_sd[(i*2)  ]+= - tmax[1] ;
+                rx_sd[(i*2)+1]+= - tmax[2] ;  /* Bits=10 */
+                rx_sd[(i*2)  ]+=   tmax[2] ;
+                rx_sd[(i*2)+1]+=   tmax[3] ;  /* Bits=11 */
+                rx_sd[(i*2)  ]+=   tmax[3] ;
+            }
+        }
+        /* Accumulate resampled int magnitude for EbNodB estimation */
+        /* Standard deviation is calculated by algorithm devised by crafty soviets */
+        #ifdef EST_EBNO
+        /* Accumulate the square of the sampled value */
+        ft1 = max;
+        stdebno += ft1;
+        
+        /* Figure the abs value of the max tone */
+        meanebno += sqrtf(ft1);
+        #endif
+        /* Soft output goes here */
+    }
+    
+    #ifdef EST_EBNO
+    /* Calculate mean for EbNodB estimation */
+    meanebno = meanebno/(float)nsym;
+    
+    /* Calculate the std. dev for EbNodB estimate */
+    stdebno = (stdebno/(float)nsym) - (meanebno*meanebno);
+    stdebno = sqrt(stdebno);
+    
+    fsk->EbNodB = -6+(20*log10f((1e-6+meanebno)/(1e-6+stdebno)));
+    #else
+    fsk->EbNodB = 1;
+    #endif
+    
+    /* Write some statistics to the stats struct */
+
+    /* Save clock offset in ppm */
+    fsk->stats->clock_offset = fsk->ppm;
+        
+    /* Calculate and save SNR from EbNodB estimate */
+    fsk->stats->snr_est = .5*fsk->stats->snr_est + .5*fsk->EbNodB;//+ 10*log10f(((float)Rs)/((float)Rs*M));
+        
+    /* Save rx timing */
+    fsk->stats->rx_timing = (float)rx_timing;
+        
+    /* Estimate and save frequency offset */
+    fc_avg = (f_est[0]+f_est[1])/2;
+    fc_tx = (fsk->f1_tx+fsk->f1_tx+fsk->fs_tx)/2;
+    fsk->stats->foff = fc_tx-fc_avg;
+    
+    /* Take a sample for the eye diagrams */
+    neyesamp = fsk->stats->neyesamp = P*2;
+    neyeoffset = high_sample+1+(P*28);
+        
+    int eye_traces = MODEM_STATS_ET_MAX/M;
+        
+    fsk->stats->neyetr = fsk->mode*eye_traces;
+    for( i=0; i<eye_traces; i++){
+        for ( m=0; m<M; m++){
+            for(j=0; j<neyesamp; j++)
+                fsk->stats->rx_eye[i*M+m][j] = cabsolute(f_int[m][neyesamp*i+neyeoffset+j]);
+        }
+    }
+        
+    if (fsk->normalise_eye) {
+        eye_max = 0;
+        /* Normalize eye to +/- 1 */
+        for(i=0; i<M*eye_traces; i++)
+            for(j=0; j<neyesamp; j++)
+                if(fabsf(fsk->stats->rx_eye[i][j])>eye_max)
+                    eye_max = fabsf(fsk->stats->rx_eye[i][j]);
+        
+        for(i=0; i<M*eye_traces; i++)
+            for(j=0; j<neyesamp; j++)
+                fsk->stats->rx_eye[i][j] = fsk->stats->rx_eye[i][j]/eye_max;
+    }
+
+    fsk->stats->nr = 0;
+    fsk->stats->Nc = 0;
+    
+    /* Dump some internal samples */
+    modem_probe_samp_f("t_EbNodB",&(fsk->EbNodB),1);
+    modem_probe_samp_f("t_ppm",&(fsk->ppm),1);
+    modem_probe_samp_f("t_rx_timing",&(rx_timing),1);
+    
+    #ifdef MODEMPROBE_ENABLE
+    for( m=0; m<M; m++){
+        snprintf(mp_name_tmp,19,"t_f%zd_int",m+1);
+        modem_probe_samp_c(mp_name_tmp,f_int[m],(nsym+1)*P);
+        snprintf(mp_name_tmp,19,"t_f%zd",m+1);
+        modem_probe_samp_f(mp_name_tmp,&f_est[m],1);
+    }
+    #endif
+    
+    #ifndef DEMOD_ALLOC_STACK
+    for( m=0; m<M; m++){
+        free(f_int[m]);
+    }
+    free(f_intbuf_m);
+    #endif
+}
+
+void fsk_demod(struct FSK *fsk, uint8_t rx_bits[], COMP fsk_in[]){
+    fsk2_demod(fsk,rx_bits,NULL,fsk_in);
+}
+
+void fsk_demod_sd(struct FSK *fsk, float rx_sd[], COMP fsk_in[]){
+    fsk2_demod(fsk,NULL,rx_sd,fsk_in);
+}
+
+void fsk_mod(struct FSK *fsk,float fsk_out[],uint8_t tx_bits[]){
+    COMP tx_phase_c = fsk->tx_phase_c; /* Current complex TX phase */
+    int f1_tx = fsk->f1_tx;         /* '0' frequency */
+    int fs_tx = fsk->fs_tx;         /* space between frequencies */
+    int Ts = fsk->Ts;               /* samples-per-symbol */
+    int Fs = fsk->Fs;               /* sample freq */
+    int M = fsk->mode;
+    COMP dosc_f[M];                 /* phase shift per sample */
+    COMP dph;                       /* phase shift of current bit */
+    size_t i,j,m,bit_i,sym;
+    
+    /* Init the per sample phase shift complex numbers */
+    for( m=0; m<M; m++){
+        dosc_f[m] = comp_exp_j(2*M_PI*((float)(f1_tx+(fs_tx*m))/(float)(Fs)));
+    }
+    
+    bit_i = 0;
+    for( i=0; i<fsk->Nsym; i++){
+        sym = 0;
+        /* Pack the symbol number from the bit stream */
+        for( m=M; m>>=1; ){
+            uint8_t bit = tx_bits[bit_i];
+            bit = (bit==1)?1:0;
+            sym = (sym<<1)|bit;
+            bit_i++;
+        }
+        /* Look up symbol phase shift */
+        dph = dosc_f[sym];
+        /* Spin the oscillator for a symbol period */
+        for(j=0; j<Ts; j++){
+            tx_phase_c = cmult(tx_phase_c,dph);
+            fsk_out[i*Ts+j] = 2*tx_phase_c.real;
+        }
+    
+    }
+    
+    /* Normalize TX phase to prevent drift */
+    tx_phase_c = comp_normalize(tx_phase_c);
+    
+    /* save TX phase */
+    fsk->tx_phase_c = tx_phase_c;
+    
+}
+
+void fsk_mod_c(struct FSK *fsk,COMP fsk_out[],uint8_t tx_bits[]){
+    COMP tx_phase_c = fsk->tx_phase_c; /* Current complex TX phase */
+    int f1_tx = fsk->f1_tx;         /* '0' frequency */
+    int fs_tx = fsk->fs_tx;         /* space between frequencies */
+    int Ts = fsk->Ts;               /* samples-per-symbol */
+    int Fs = fsk->Fs;               /* sample freq */
+    int M = fsk->mode;
+    COMP dosc_f[M];                 /* phase shift per sample */
+    COMP dph;                       /* phase shift of current bit */
+    size_t i,j,m,bit_i,sym;
+    
+    /* Init the per sample phase shift complex numbers */
+    for( m=0; m<M; m++){
+        dosc_f[m] = comp_exp_j(2*M_PI*((float)(f1_tx+(fs_tx*m))/(float)(Fs)));
+    }
+    
+    bit_i = 0;
+    for( i=0; i<fsk->Nsym; i++){
+        sym = 0;
+        /* Pack the symbol number from the bit stream */
+        for( m=M; m>>=1; ){
+            uint8_t bit = tx_bits[bit_i];
+            bit = (bit==1)?1:0;
+            sym = (sym<<1)|bit;
+            bit_i++;
+        }
+        /* Look up symbol phase shift */
+        dph = dosc_f[sym];
+        /* Spin the oscillator for a symbol period */
+        for(j=0; j<Ts; j++){
+            tx_phase_c = cmult(tx_phase_c,dph);
+            fsk_out[i*Ts+j] = fcmult(2,tx_phase_c);
+        }
+    }
+    
+    /* Normalize TX phase to prevent drift */
+    tx_phase_c = comp_normalize(tx_phase_c);
+    
+    /* save TX phase */
+    fsk->tx_phase_c = tx_phase_c;
+    
+}
+
+void fsk_stats_normalise_eye(struct FSK *fsk, int normalise_enable) {
+    fsk->normalise_eye = normalise_enable;
+}
+
+
+
+
+
+
+
diff --git a/codec2/branches/0.7/src/fsk.h b/codec2/branches/0.7/src/fsk.h
new file mode 100644 (file)
index 0000000..d20b665
--- /dev/null
@@ -0,0 +1,190 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk.h
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 6 January 2016
+
+  C Implementation of 2FSK/4FSK modulator/demodulator, based on octave/fsk_horus.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifndef __C2FSK_H
+#define __C2FSK_H
+#include <stdint.h>
+#include "comp.h"
+#include "kiss_fftr.h"
+#include "modem_stats.h"
+
+#define MODE_2FSK 2
+#define MODE_4FSK 4
+
+#define MODE_M_MAX 4
+
+#define FSK_SCALE 16383
+
+struct FSK {
+    /*  Static parameters set up by fsk_init */\r
+    int Ndft;               /* buffer size for freq offset est fft */\r
+    int Fs;                 /* sample freq */
+    int N;                  /* processing buffer size */
+    int Rs;                 /* symbol rate */
+    int Ts;                 /* samples per symbol */
+    int Nmem;               /* size of extra mem for timing adj */
+    int P;                  /* oversample rate for timing est/adj */
+    int Nsym;               /* Number of symbols spat out in a processing frame */
+    int Nbits;              /* Number of bits spat out in a processing frame */
+    int f1_tx;              /* f1 for modulator */
+    int fs_tx;              /* Space between TX freqs for modulatosr */
+    int mode;               /* 2FSK or 4FSK */
+    int est_min;            /* Minimum frequency for freq. estimator */
+    int est_max;            /* Maximum frequency for freq. estimaotr */
+    int est_space;          /* Minimum frequency spacing for freq. estimator */
+    float* hann_table;         /* Precomputed or runtime computed hann window table */
+    
+    /*  Parameters used by demod */
+    COMP phi_c[MODE_M_MAX];
+    
+    kiss_fft_cfg fft_cfg;   /* Config for KISS FFT, used in freq est */
+    float norm_rx_timing;   /* Normalized RX timing */
+    
+    COMP* samp_old;         /* Tail end of last batch of samples */
+    int nstash;             /* How many elements are in there */
+    
+    float* fft_est;                    /* Freq est FFT magnitude */
+    
+    /* Memory used by demod but not important between demod frames */
+    
+    /*  Parameters used by mod */
+    COMP tx_phase_c;        /* TX phase, but complex */ 
+    
+    /*  Statistics generated by demod */
+    float EbNodB;           /* Estimated EbNo in dB */
+    float f_est[MODE_M_MAX];/* Estimated frequencies */
+    float ppm;              /* Estimated PPM clock offset */
+    
+    /*  Parameters used by mod/demod and driving code */
+    int nin;                /* Number of samples to feed the next demod cycle */
+    
+    /*  modem statistic struct */
+    struct MODEM_STATS *stats;
+    int normalise_eye;      /* enables/disables normalisation of eye diagram */
+};
+
+/*
+ * Create an FSK config/state struct from a set of config parameters
+ * 
+ * int Fs - Sample frequency
+ * int Rs - Symbol rate
+ * int tx_f1 - '0' frequency
+ * int tx_fs - frequency spacing
+ */
+struct FSK * fsk_create(int Fs, int Rs, int M, int tx_f1, int tx_fs);
+
+/*
+ * Create an FSK config/state struct from a set of config parameters
+ * 
+ * int Fs - Sample frequency
+ * int Rs - Symbol rate
+ * int tx_f1 - '0' frequency
+ * int tx_fs - frequency spacing
+ */
+struct FSK * fsk_create_hbr(int Fs, int Rs, int P, int M, int tx_f1, int tx_fs);
+
+/* 
+ * Set a new number of symbols per processing frame
+ */
+void fsk_set_nsym(struct FSK *fsk,int nsym);
+
+/*
+ * Set the minimum and maximum frequencies at which the freq. estimator can find tones
+ */
+void fsk_set_est_limits(struct FSK *fsk,int fmin, int fmax);
+
+/* 
+ * Clear the estimator states
+ */
+void fsk_clear_estimators(struct FSK *fsk);
+
+/*
+ * Fills MODEM_STATS struct with demod statistics
+ */
+void fsk_get_demod_stats(struct FSK *fsk, struct MODEM_STATS *stats);
+
+/*
+ * Destroy an FSK state struct and free it's memory
+ * 
+ * struct FSK *fsk - FSK config/state struct to be destroyed
+ */
+void fsk_destroy(struct FSK *fsk);
+
+/*
+ * Modulates Nsym bits into N samples
+ * 
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * float fsk_out[] - Buffer for N samples of modulated FSK
+ * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
+ */
+void fsk_mod(struct FSK *fsk, float fsk_out[], uint8_t tx_bits[]);
+
+/*
+ * Modulates Nsym bits into N complex samples
+ * 
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * comp fsk_out[] - Buffer for N samples of modulated FSK
+ * uint8_t tx_bits[] - Buffer containing Nbits unpacked bits
+ */
+void fsk_mod_c(struct FSK *fsk, COMP fsk_out[], uint8_t tx_bits[]);
+
+
+/*
+ * Returns the number of samples needed for the next fsk_demod() cycle
+ *
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * returns - number of samples to be fed into fsk_demod next cycle 
+ */
+uint32_t fsk_nin(struct FSK *fsk);
+
+
+/*
+ * Demodulate some number of FSK samples. The number of samples to be 
+ *  demodulated can be found by calling fsk_nin().
+ * 
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * uint8_t rx_bits[] - Buffer for Nbits unpacked bits to be written
+ * float fsk_in[] - nin samples of modualted FSK
+ */
+void fsk_demod(struct FSK *fsk, uint8_t rx_bits[],COMP fsk_in[]);
+
+/*
+ * Demodulate some number of FSK samples. The number of samples to be 
+ *  demodulated can be found by calling fsk_nin().
+ * 
+ * struct FSK *fsk - FSK config/state struct, set up by fsk_create
+ * float rx_bits[] - Buffer for Nbits soft decision bits to be written
+ * float fsk_in[] - nin samples of modualted FSK
+ */
+void fsk_demod_sd(struct FSK *fsk, float rx_bits[],COMP fsk_in[]);
+
+/* enables/disables normalisation of eye diagram samples */
+  
+void fsk_stats_normalise_eye(struct FSK *fsk, int normalise_enable);
+
+#endif
diff --git a/codec2/branches/0.7/src/fsk_demod.c b/codec2/branches/0.7/src/fsk_demod.c
new file mode 100644 (file)
index 0000000..ddbff92
--- /dev/null
@@ -0,0 +1,296 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk_demod.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 8 January 2016
+
+  C test driver for fsk_demod in fsk.c. Reads in a stream of 32 bit cpu endian
+  floats and writes out the detected bits
+   
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include "fsk.h"
+#include "codec2_fdmdv.h"
+#include "modem_stats.h"
+
+int main(int argc,char *argv[]){
+    struct FSK *fsk;
+    struct MODEM_STATS stats;
+    int Fs,Rs,M,P,stats_ctr,stats_loop;
+    float loop_time;
+    int enable_stats = 0;
+    int hbr = 1;
+    FILE *fin,*fout;
+    uint8_t *bitbuf;
+    int16_t *rawbuf;
+    COMP *modbuf;
+    float *sdbuf;
+    int i,j,Ndft;
+    int soft_dec_mode = 0;
+    stats_loop = 0;
+    int complex_input = 1, bytes_per_sample = 2;
+    int stats_rate = 8;
+    P = 0;
+    M = 0;
+    
+    /* -m 2/4 --mode 2/4  - FSK mode
+     * -l --lbr      - Low bit rate mode
+     * -p n --conv n    - Downconverted symbol size
+     * If p is unspecified, it will default to Ts
+     * -c --cs16      - Complex (signed 16-bit)
+     * -d --cu8      - Complex (unsigned 8-bit)
+     * If neither -c or -d are specified, input will be real valued signed 16-bit
+     * -t --stats - dump demod statistics to stderr
+     * -s --soft-dec - ouput soft decision (float 32-bit)
+     */
+     /* usage: [-l] [-p P]  [-s] [(-c|-d)] [-t] (2|4) SampleRate SymbolRatez InputModemRawFile OutputOneBitPerCharFile */
+     
+     int o = 0;
+     int opt_idx = 0;
+     while( o != -1 ){
+        static struct option long_opts[] = {
+            {"help",      no_argument,        0, 'h'},
+            {"lbr",       no_argument,        0, 'l'},
+            {"conv",      required_argument,  0, 'p'},
+            {"cs16",      no_argument,        0, 'c'},
+            {"cu8",       no_argument,        0, 'd'},
+            {"stats",     optional_argument,  0, 't'},
+            {"soft-dec",  no_argument,        0, 's'},
+            {0, 0, 0, 0}
+        };
+        
+        o = getopt_long(argc,argv,"hlp:cdt::s",long_opts,&opt_idx);
+        
+        switch(o){
+            case 'l':
+                hbr = 0;
+                break;
+            case 'c':
+                complex_input = 2;
+                bytes_per_sample = 2;
+                break;
+            case 'd':
+                complex_input = 2;
+                bytes_per_sample = 1;
+                break;
+            case 't':
+                enable_stats = 1;
+                if(optarg != NULL){
+                    stats_rate = atoi(optarg);
+                    if(stats_rate == 0){
+                        stats_rate = 8;
+                    }
+                }
+                break;
+            case 's':
+                soft_dec_mode = 1;
+                break;
+            case 'p':
+                P = atoi(optarg);
+                break;
+            case 'h':
+            case '?':
+                goto helpmsg;
+                break;
+        }
+    }
+    int dx = optind;
+    
+    if( (argc - dx) < 5){
+        fprintf(stderr, "Too few arguments\n");
+        goto helpmsg;
+    }
+    
+    if( (argc - dx) > 5){
+        fprintf(stderr, "Too many arguments\n");
+        helpmsg:
+        fprintf(stderr,"usage: %s [-l] [-p P]  [-s] [(-c|-d)] [-t [r]] (2|4) SampleRate SymbolRate InputModemRawFile OutputFile\n",argv[0]);
+        fprintf(stderr," -lP --conv=P      -  P specifies the rate at which symbols are down-converted before further processing\n");
+        fprintf(stderr,"                        P must be divisible by the symbol size. Smaller P values will result in faster\n");
+        fprintf(stderr,"                        processing but lower demodulation preformance. If no P value is specified,\n");
+        fprintf(stderr,"                        P will default to it's highes possible value\n");
+        fprintf(stderr," -c --cs16         -  The raw input file will be in complex signed 16 bit format.\n");
+        fprintf(stderr," -d --cu8          -  The raw input file will be in complex unsigned 8 bit format.\n");
+        fprintf(stderr,"                        If neither -c nor -d are used, the input should be in signed 16 bit format.\n");
+        fprintf(stderr," -t[r] --stats=[r] -  Print out modem statistics to stderr in JSON.\n");
+        fprintf(stderr,"                         r, if provided, sets the number of modem frames between statistic printouts\n");
+        fprintf(stderr," -s --soft-dec     -  The output file will be in a soft-decision format, with one 32-bit float per bit.\n");
+        fprintf(stderr,"                        If -s is not used, the output will be in a 1 byte-per-bit format.\n");
+        exit(1);
+    }
+    
+    /* Extract parameters */
+    M = atoi(argv[dx]);
+    Fs = atoi(argv[dx + 1]);
+    Rs = atoi(argv[dx + 2]);
+    
+    if( P == 0 ){
+        P = Fs/Rs;
+    }
+    
+    if( (M!=2) && (M!=4) ){
+        fprintf(stderr,"Mode %d is not valid. Mode must be 2 or 4.\n",M);
+        goto helpmsg;
+    }
+    
+    /* Open files */
+    if(strcmp(argv[dx + 3],"-")==0){
+        fin = stdin;
+    }else{
+        fin = fopen(argv[dx + 3],"r");
+    }
+    
+    if(strcmp(argv[dx + 4],"-")==0){
+        fout = stdout;
+    }else{
+        fout = fopen(argv[dx + 4],"w");
+    }
+    
+    
+    /* set up FSK */
+    if(!hbr)
+    fsk = fsk_create(Fs,Rs,M,1200,400);
+    else
+    fsk = fsk_create_hbr(Fs,Rs,P,M,1200,400);
+    
+    if(fin==NULL || fout==NULL || fsk==NULL){
+        fprintf(stderr,"Couldn't open test vector files\n");
+        exit(1);
+    }
+    
+    if(enable_stats){
+        loop_time = ((float)fsk_nin(fsk))/((float)Fs);
+        stats_loop = (int)(1/(stats_rate*loop_time));
+        stats_ctr = 0;
+    }
+    
+    /* allocate buffers for processing */
+    if(soft_dec_mode){
+        sdbuf = (float*)malloc(sizeof(float)*fsk->Nbits);
+    }else{
+        bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*fsk->Nbits);
+    }
+    rawbuf = (int16_t*)malloc(bytes_per_sample*(fsk->N+fsk->Ts*2)*complex_input);
+    modbuf = (COMP*)malloc(sizeof(COMP)*(fsk->N+fsk->Ts*2));
+    
+    /* Demodulate! */
+    while( fread(rawbuf,bytes_per_sample*complex_input,fsk_nin(fsk),fin) == fsk_nin(fsk) ){
+        /* convert input to a buffer of floats.  Note scaling isn't really necessary for FSK */
+
+       if (complex_input == 1) {
+            /* S16 real input */
+            for(i=0;i<fsk_nin(fsk);i++){
+                modbuf[i].real = ((float)rawbuf[i])/FDMDV_SCALE;
+                modbuf[i].imag = 0.0;
+            }
+        }
+        else {
+            if (bytes_per_sample == 1) {
+                /* U8 complex */
+                uint8_t *rawbuf_u8 = (uint8_t*)rawbuf;
+                for(i=0;i<fsk_nin(fsk);i++){
+                    modbuf[i].real = ((float)rawbuf_u8[2*i]-127.0)/128.0;
+                    modbuf[i].imag = ((float)rawbuf_u8[2*i+1]-127.0)/128.0;
+                }
+            }
+            else {
+                /* S16 complex */
+                for(i=0;i<fsk_nin(fsk);i++){
+                    modbuf[i].real = ((float)rawbuf[2*i])/FDMDV_SCALE;
+                    modbuf[i].imag = ((float)rawbuf[2*i+1]/FDMDV_SCALE);
+                }
+            }            
+        }
+        if(soft_dec_mode){
+            fsk_demod_sd(fsk,sdbuf,modbuf);
+        }else{
+            fsk_demod(fsk,bitbuf,modbuf);
+        }
+        
+        if(enable_stats && stats_ctr <= 0){
+            fsk_get_demod_stats(fsk,&stats);
+           /* Print standard 2FSK stats */
+            fprintf(stderr,"{\"EbNodB\": %2.2f,\t\"ppm\": %d,",stats.snr_est,(int)fsk->ppm);
+            fprintf(stderr,"\t\"f1_est\":%.1f,\t\"f2_est\":%.1f",fsk->f_est[0],fsk->f_est[1]);
+           /* Print 4FSK stats if in 4FSK mode */
+            if(fsk->mode == 4){
+                fprintf(stderr,",\t\"f3_est\":%.1f,\t\"f4_est\":%.1f",fsk->f_est[2],fsk->f_est[3]);
+            }
+           
+           /* Print the eye diagram */
+            fprintf(stderr,",\t\"eye_diagram\":[");
+            for(i=0;i<stats.neyetr;i++){
+                fprintf(stderr,"[");
+                for(j=0;j<stats.neyesamp;j++){
+                    fprintf(stderr,"%f ",stats.rx_eye[i][j]);
+                    if(j<stats.neyesamp-1) fprintf(stderr,",");
+                }
+                fprintf(stderr,"]");
+                if(i<stats.neyetr-1) fprintf(stderr,",");
+            }
+            fprintf(stderr,"],");
+           
+           /* Print a sample of the FFT from the freq estimator */
+           fprintf(stderr,"\"samp_fft\":[");
+           Ndft = fsk->Ndft/2;
+           for(i=0; i<Ndft; i++){
+               fprintf(stderr,"%f ",(fsk->fft_est)[i]);
+               if(i<Ndft-1) fprintf(stderr,",");
+           }
+           fprintf(stderr,"]}\n");
+            stats_ctr = stats_loop;
+        }
+        stats_ctr--;
+            /*for(i=0;i<fsk->Nbits;i++){
+            t = (int)bitbuf[i];
+        }*/
+        if(soft_dec_mode){
+            fwrite(sdbuf,sizeof(float),fsk->Nbits,fout);
+        }else{
+            fwrite(bitbuf,sizeof(uint8_t),fsk->Nbits,fout);
+        }
+            if(fin == stdin || fout == stdin){
+            fflush(fin);
+            fflush(fout);
+        }
+    }
+    
+    if(soft_dec_mode){
+        free(sdbuf);
+    }else{
+        free(bitbuf);
+    }
+    
+    free(rawbuf);
+    free(modbuf);
+    
+    fclose(fin);
+    fclose(fout);
+    fsk_destroy(fsk);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/src/fsk_get_test_bits.c b/codec2/branches/0.7/src/fsk_get_test_bits.c
new file mode 100644 (file)
index 0000000..fb26e2e
--- /dev/null
@@ -0,0 +1,90 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk_get_test_bits.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: January 2016
+
+  Generates a pseudorandom sequence of bits for testing of fsk_mod and fsk_demod
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include "fsk.h"
+
+#define TEST_FRAME_SIZE 100  /* arbitrary chice, repeats after this
+                                many bits, sets frame size for rx
+                                processing */
+
+int main(int argc,char *argv[]){
+    int bitcnt, framecnt;
+    int i;
+    FILE *fout;
+    uint8_t *bitbuf;
+    
+    if(argc != 3){
+        fprintf(stderr,"usage: %s OutputBitsOnePerByte numBits\n",argv[0]);
+        exit(1);
+    }
+    
+    /* Extract parameters */
+    bitcnt = atoi(argv[2]);
+    framecnt = bitcnt/TEST_FRAME_SIZE;
+    if (framecnt == 0) {
+        fprintf(stderr,"Need a minimum of %d bits\n", TEST_FRAME_SIZE);
+        exit(1);
+    }
+
+    if(strcmp(argv[1],"-")==0){
+        fout = stdout;
+    }else{
+        fout = fopen(argv[1],"w");
+    }
+    
+    if(fout==NULL){
+        fprintf(stderr,"Couldn't open output file: %s\n", argv[1]);
+        goto cleanup;
+    }
+    
+    /* allocate buffers for processing */
+    bitbuf = (uint8_t*)alloca(sizeof(uint8_t)*TEST_FRAME_SIZE);
+    
+    /* Generate buffer of test frame bits from known seed */
+    srand(158324);
+    for(i=0; i<TEST_FRAME_SIZE; i++){
+       bitbuf[i] = rand()&0x1;
+    }
+        
+    /* Output test frames */
+    srand(158324);
+    for(i=0; i<framecnt; i++){
+       fwrite(bitbuf,sizeof(uint8_t),TEST_FRAME_SIZE,fout);
+       if(fout == stdout){
+           fflush(fout);
+       }
+    }
+    
+ cleanup:
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/fsk_mod.c b/codec2/branches/0.7/src/fsk_mod.c
new file mode 100644 (file)
index 0000000..e9295be
--- /dev/null
@@ -0,0 +1,108 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk_mod.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 8 January 2016
+
+  C test driver for fsk_mod in fsk.c. Reads in a set of bits to modulate
+   from a file, passed as a parameter, and writes modulated output to
+   another file
+   
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include "fsk.h"
+#include "codec2_fdmdv.h"
+
+int main(int argc,char *argv[]){
+    struct FSK *fsk;
+    int Fs,Rs,f1,fs,M;
+    int i;
+    int p;
+    FILE *fin,*fout;
+    uint8_t *bitbuf;
+    int16_t *rawbuf;
+    float *modbuf;
+    
+    if(argc<8){
+        fprintf(stderr,"usage: %s Mode SampleFreq SymbolFreq TxFreq1 TxFreqSpace InputOneBitPerCharFile OutputModRawFile\n",argv[0]);
+        exit(1);
+    }
+    
+    /* Extract parameters */
+    M = atoi(argv[1]);
+    Fs = atoi(argv[2]);
+    Rs = atoi(argv[3]);
+    f1 = atoi(argv[4]);
+    fs = atoi(argv[5]);
+    
+    if(strcmp(argv[6],"-")==0){
+               fin = stdin;
+       }else{
+               fin = fopen(argv[6],"r");
+       }
+       
+       if(strcmp(argv[7],"-")==0){
+               fout = stdout;
+       }else{
+               fout = fopen(argv[7],"w");
+       }
+    
+    p = Fs/Rs;
+    
+    /* set up FSK */
+    fsk = fsk_create_hbr(Fs,Rs,p,M,f1,fs);
+    
+    if(fin==NULL || fout==NULL || fsk==NULL){
+        fprintf(stderr,"Couldn't open test vector files\n");
+        goto cleanup;
+    }
+    
+    
+    /* allocate buffers for processing */
+    bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*fsk->Nbits);
+    rawbuf = (int16_t*)malloc(sizeof(int16_t)*fsk->N);
+    modbuf = (float*)malloc(sizeof(float)*fsk->N);
+    
+    /* Modulate! */
+    while( fread(bitbuf,sizeof(uint8_t),fsk->Nbits,fin) == fsk->Nbits ){
+        fsk_mod(fsk,modbuf,bitbuf);
+        for(i=0; i<fsk->N; i++){
+                       rawbuf[i] = (int16_t)(modbuf[i]*(float)FDMDV_SCALE);
+               }
+        fwrite(rawbuf,sizeof(int16_t),fsk->N,fout);
+        
+               if(fin == stdin || fout == stdin){
+                       fflush(fin);
+                       fflush(fout);
+               }
+    }
+    free(bitbuf);
+    free(rawbuf);
+    free(modbuf);
+    
+    cleanup:
+    fclose(fin);
+    fclose(fout);
+    fsk_destroy(fsk);
+    exit(0);
+}
diff --git a/codec2/branches/0.7/src/fsk_put_test_bits.c b/codec2/branches/0.7/src/fsk_put_test_bits.c
new file mode 100644 (file)
index 0000000..4186049
--- /dev/null
@@ -0,0 +1,104 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fsk_get_test_bits.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: January 2016
+
+  Generates a pseudorandom sequence of bits for testing of fsk_mod and
+  fsk_demod.
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include "fsk.h"
+
+#define TEST_FRAME_SIZE 100  /* must match fsk_get_test_bits.c */
+
+int main(int argc,char *argv[]){
+    int bitcnt,biterr,i,errs;
+    FILE *fin;
+    uint8_t *bitbuf_tx, *bitbuf_rx, abit;
+    
+    if(argc != 2){
+        fprintf(stderr,"usage: %s InputBitsOnePerByte \n",argv[0]);
+        exit(1);
+    }
+    
+    if(strcmp(argv[1],"-")==0 || argc<2){
+        fin = stdin;
+    }else{
+        fin = fopen(argv[1],"r");
+    }
+    
+    if(fin==NULL){
+        fprintf(stderr,"Couldn't open input file: %s\n", argv[1]);
+        goto cleanup;
+    }
+
+    /* allocate buffers for processing */
+    bitbuf_tx = (uint8_t*)alloca(sizeof(uint8_t)*TEST_FRAME_SIZE);
+    bitbuf_rx = (uint8_t*)alloca(sizeof(uint8_t)*TEST_FRAME_SIZE);
+    
+    /* Generate known tx frame from known seed */
+    srand(158324);
+    for(i=0; i<TEST_FRAME_SIZE; i++){
+       bitbuf_tx[i] = rand()&0x1;
+       bitbuf_rx[i] = 0;
+    }
+    
+    bitcnt = 0;
+    biterr = 0;
+    
+    while(fread(&abit,sizeof(uint8_t),1,fin)>0){
+
+        /* update silding window of input bits */
+
+        for(i=0; i<TEST_FRAME_SIZE-1; i++) {
+            bitbuf_rx[i] = bitbuf_rx[i+1];
+        }
+        bitbuf_rx[TEST_FRAME_SIZE-1] = abit;
+
+        /* compare to know tx frame.  If they are time aligned, there
+           will be a fairly low bit error rate */
+
+        errs = 0;
+        for(i=0; i<TEST_FRAME_SIZE; i++) {
+            if (bitbuf_rx[i] != bitbuf_tx[i]) {
+                errs++;
+            }
+        }
+        if (errs < 0.1*TEST_FRAME_SIZE) {
+            /* OK, we have a valid test frame sync, so lets count errors */
+            bitcnt += TEST_FRAME_SIZE;
+            biterr += errs;
+            fprintf(stderr,"errs: %d FSK BER %f, bits tested %d, bit errors %d\n",
+                    errs, ((float)biterr/(float)bitcnt),bitcnt,biterr);
+        }
+    }
+    
+ cleanup:
+    fclose(fin);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/generate_codebook.c b/codec2/branches/0.7/src/generate_codebook.c
new file mode 100644 (file)
index 0000000..835fc7d
--- /dev/null
@@ -0,0 +1,179 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: generate_codebook.c
+  AUTHOR......: Bruce Perens
+  DATE CREATED: 29 Sep 2010
+
+  Generate header files containing LSP quantisers, runs at compile time.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+static const char usage[] =
+"Usage: %s filename array_name [filename ...]\n"
+"\tCreate C code for codebook tables.\n";
+
+static const char format[] =
+"The table format must be:\n"
+"\tTwo integers describing the dimensions of the codebook.\n"
+"\tThen, enough numbers to fill the specified dimensions.\n";
+
+static const char header[] =
+"/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */\n\n"
+"/*\n"
+" * This intermediary file and the files that used to create it are under \n"
+" * The LGPL. See the file COPYING.\n"
+" */\n\n"
+"#include \"defines.h\"\n\n";
+
+struct codebook {
+  unsigned int k;
+  unsigned int log2m;
+  unsigned int m;
+  float * cb;
+};
+
+static void
+dump_array(const struct codebook * b, int index)
+{
+  int  limit = b->k * b->m;
+  int  i;
+
+  printf("static const float codes%d[] = {\n", index);
+  for ( i = 0; i < limit; i++ ) {
+    printf("  %g", b->cb[i]);
+    if ( i < limit - 1 )
+      printf(",");
+
+    /* organise VQs by rows, looks prettier */
+    if ( ((i+1) % b->k) == 0 )
+       printf("\n");
+  }
+  printf("};\n");
+}
+
+static void
+dump_structure(const struct codebook * b, int index)
+{
+  printf("  {\n");
+  printf("    %d,\n", b->k);
+  printf("    %g,\n", log(b->m) / log(2));
+  printf("    %d,\n", b->m);
+  printf("    codes%d\n", index);
+  printf("  }");
+}
+
+float
+get_float(FILE * in, const char * name, char * * cursor, char * buffer,
+ int size)
+{
+  for ( ; ; ) {
+    char *     s = *cursor;
+    char       c;
+
+    while ( (c = *s) != '\0' && !isdigit(c) && c != '-' && c != '.' )
+      s++;
+
+    /* Comments start with "#" and continue to the end of the line. */
+    if ( c != '\0' && c != '#' ) {
+      char *   end = 0;
+      float    f = 0;
+
+      f = strtod(s, &end);
+
+      if ( end != s )
+        *cursor = end;
+      return f;
+    }
+
+    if ( fgets(buffer, size, in) == NULL ) {
+      fprintf(stderr, "%s: Format error. %s\n", name, format);
+      exit(1);
+    }
+    *cursor = buffer;
+  }
+}
+
+static struct codebook *
+load(FILE * file, const char * name)
+{
+  char                 line[1024];
+  char *               cursor = line;
+  struct codebook *    b = malloc(sizeof(struct codebook));
+  int                  i;
+  int                  size;
+
+  *cursor = '\0';
+
+  b->k = (int)get_float(file, name, &cursor, line, sizeof(line));
+  b->m = (int)get_float(file, name ,&cursor, line, sizeof(line));
+  size = b->k * b->m;
+
+  b->cb = (float *)malloc(size * sizeof(float));
+
+  for ( i = 0; i < size; i++ )
+    b->cb[i] = get_float(file, name, &cursor, line, sizeof(line));
+
+  return b;
+}
+
+int
+main(int argc, char * * argv)
+{
+  struct codebook * *  cb = malloc(argc * sizeof(struct codebook *));
+  int                  i;
+
+  if ( argc < 2 ) {
+    fprintf(stderr, usage, argv[0]);
+    fprintf(stderr, format);
+    exit(1);
+  }
+
+  for ( i = 0; i < argc - 2; i++ ) {
+    FILE *     in = fopen(argv[i + 2], "r");
+
+    if ( in == NULL ) {
+      perror(argv[i + 2]);
+      exit(1);
+    }
+
+    cb[i] = load(in, argv[i + 2]);
+
+    fclose(in);
+  }
+
+  printf(header);
+  for ( i = 0; i < argc - 2; i++ ) {
+    printf("  /* %s */\n", argv[i + 2]);
+    dump_array(cb[i], i);
+  }
+  printf("\nconst struct lsp_codebook %s[] = {\n", argv[1]);
+  for ( i = 0; i < argc - 2; i++ ) {
+    printf("  /* %s */\n", argv[i + 2]);
+    dump_structure(cb[i], i);
+    printf(",\n");
+  }
+  printf("  { 0, 0, 0, 0 }\n");
+  printf("};\n");
+
+  return 0;
+}
diff --git a/codec2/branches/0.7/src/golay23.c b/codec2/branches/0.7/src/golay23.c
new file mode 100644 (file)
index 0000000..d382179
--- /dev/null
@@ -0,0 +1,311 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: golay23.c
+  AUTHOR......: Tomas Härdin & David Rowe
+  DATE CREATED: 3 March 2013
+
+  To test:
+
+     src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST                   && ./golay23
+     src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST -DRUN_TIME_TABLES && ./golay23
+     src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_UNITTEST -DNO_TABLES       && ./golay23
+
+  To generate tables:
+     src$ gcc golay23.c -o golay23 -Wall -O3 -DGOLAY23_MAKETABLES                 && ./golay23
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 Tomas Härdin & David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not,see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+
+#ifdef GOLAY23_MAKETABLES
+#define RUN_TIME_TABLES
+#endif
+
+#ifndef NO_TABLES
+#ifdef RUN_TIME_TABLES
+int static encoding_table[4096];
+int static decoding_table[2048];
+static int inited = 0;
+#else
+//default is to use precomputed tables
+#include "golayenctable.h"
+#include "golaydectable.h"
+#endif
+#endif
+
+//since we want to avoid bit-reversing inside syndrome() we bit-reverse the polynomial instead
+#define GOLAY_POLYNOMIAL    0xC75   //AE3 reversed
+
+static int syndrome(int c) {
+    //could probably be done slightly smarter, but works
+    int x;
+    for (x = 11; x >= 0; x--) {
+        if (c & ((1<<11) << x)) {
+            c ^= GOLAY_POLYNOMIAL << x;
+        }
+    }
+    return c;
+}
+
+#ifdef __GNUC__
+#define popcount __builtin_popcount
+#elif defined(__MSC_VER)
+#include <intrin.h>
+#define popcount __popcnt
+#else
+static int popcount(unsigned int c) {
+    int ret = 0;
+    while (c) {
+        if (c & 1) {
+            ret++;
+        }
+        c >>= 1;
+    }
+    return ret;
+}
+#endif
+
+#if defined(NO_TABLES) || defined(RUN_TIME_TABLES)
+static int golay23_encode_no_tables(int c) {
+    c <<= 11;
+    return syndrome(c) | c;
+}
+#endif
+
+#ifdef NO_TABLES
+static int unrotate(unsigned int c, int x) {
+    return ((c << x) & 0x7FFFFF) | (c >> (23 - x));
+}
+
+static int golay23_decode_no_tables(int c) {
+    //TODO: optimize?
+    int x;
+    c = unrotate(c, 12);
+
+    for (x = 0; x < 23; x++) {
+        int t;
+        int s = syndrome(c);
+
+        if (popcount(s) <= 3) {
+            return unrotate(c ^ s, x) & 0xFFF;
+        }
+
+        for (t = 0; t < 23; t++) {
+            int c2 = c ^ (1 << t);
+            int s = syndrome(c2);
+
+            if (popcount(s) <= 2) {
+                return unrotate(c2 ^ s, x) & 0xFFF;
+            }
+        }
+
+        //rotate
+        c = (c >> 1) | ((c & 1) << 22);
+    }
+
+    //shouldn't reach here..
+    assert("Something is wrong with golay23_decode_no_tables()..");
+    return c & 0xFFF;
+}
+#endif
+
+void golay23_init(void) {
+#ifdef RUN_TIME_TABLES
+    int x, y, z;
+    inited = 1;
+    for (x = 0; x < 4096; x++) {
+        encoding_table[x] = golay23_encode_no_tables(x);
+    }
+
+    decoding_table[0] = 0;
+    //1-bit errors
+    for (x = 0; x < 23; x++) {
+        int d = 1<<x;
+        decoding_table[syndrome(d)] = d;
+    }
+    //2-bit errors
+    for (x = 0; x < 22; x++) {
+        for (y = x+1; y < 23; y++) {
+            int d = (1<<x) | (1<<y);
+            decoding_table[syndrome(d)] = d;
+        }
+    }
+    //3-bit errors
+    for (x = 0; x < 21; x++) {
+        for (y = x+1; y < 22; y++) {
+            for (z = y+1; z < 23; z++) {
+                int d = (1<<x) | (1<<y) | (1<<z);
+                decoding_table[syndrome(d)] = d;
+            }
+        }
+    }
+#endif
+}
+
+int  golay23_encode(int c) {
+    assert(c >= 0 && c <= 0xFFF);
+#ifdef RUN_TIME_TABLES
+    assert(inited);
+#endif
+
+#ifdef NO_TABLES
+    return golay23_encode_no_tables(c);
+#else
+    return encoding_table[c];
+#endif
+}
+
+int  golay23_decode(int c) {
+    assert(c >= 0 && c <= 0x7FFFFF);
+#ifdef RUN_TIME_TABLES
+    assert(inited);
+#endif
+
+#ifdef NO_TABLES
+    //duplicate old golay23_decode()'s shift
+    return unrotate(golay23_decode_no_tables(c), 11);
+#else
+    //message is shifted 11 places left in the return value
+    return c ^ decoding_table[syndrome(c)];
+#endif
+}
+
+int  golay23_count_errors(int recd_codeword, int corrected_codeword) {
+    return popcount(recd_codeword ^ corrected_codeword);
+}
+
+/**
+ * Table generation and testing code below
+ */
+
+#ifdef GOLAY23_MAKETABLES
+#include <stdio.h>
+
+int main() {
+    int x;
+    //generate and dump
+    golay23_init();
+
+    FILE *enc = fopen("golayenctable.h", "w");
+    FILE *dec = fopen("golaydectable.h", "w");
+
+    fprintf(enc, "/* Generated by golay23.c -DGOLAY23_MAKETABLE */\n\
+\n\
+const int static encoding_table[]={\n");
+    for (x = 0; x < 4096; x++) {
+        fprintf(enc, x < 4095 ? "  0x%x,\n" : "  0x%x\n", encoding_table[x]);
+    }
+    fprintf(enc, "};\n");
+
+    fprintf(dec, "/* Generated by golay23.c -DGOLAY23_MAKETABLE */\n\
+\n\
+const int static decoding_table[]={\n");
+    for (x = 0; x < 2048; x++) {
+        fprintf(dec, x < 2047 ? "  0x%x,\n" : "  0x%x\n", decoding_table[x]);
+    }
+    fprintf(dec, "};\n");
+
+    fclose(enc);
+    fclose(dec);
+
+    return 0;
+}
+
+#elif defined(GOLAY23_UNITTEST)
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+
+int main() {
+    int c;
+
+    golay23_init();
+
+    //keep track of whether every single codeword has been checked
+    char *checkmask = malloc(1<<23);
+    memset(checkmask, 0, 1<<23);
+
+    //step through all possible messages
+    for (c = 0; c < (1<<12); c++) {
+        int g23 = golay23_encode(c);
+        int x,y,z;
+        checkmask[g23] = 1;
+        int c2 = golay23_decode(g23) >> 11;
+
+        printf("%03x -> %06x %03x\n", c, g23, c2);
+
+        if (c != c2) {
+            printf("Bad!\n");
+            exit(1);
+        }
+
+        //test the code by flipping every combination of one, two and three bits
+        for (x = 0; x < 23; x++) {
+            int flipped = g23 ^ (1<<x);
+            checkmask[flipped] = 1;
+            int c2 = golay23_decode(flipped) >> 11;
+            if (c != c2) {
+                printf("Bad!\n");
+                
+                exit(1);
+            }
+        }
+        
+        for (x = 0; x < 22; x++) {
+            for (y = x+1; y < 23; y++) {
+                int flipped = g23 ^ (1<<x) ^ (1<<y);
+                checkmask[flipped] = 1;
+                int c2 = golay23_decode(flipped) >> 11;
+                if (c != c2) {
+                    printf("Bad!\n");
+                    
+                    exit(1);
+                }
+            }
+        }
+        
+        for (x = 0; x < 21; x++) {
+            for (y = x+1; y < 22; y++) {
+                for (z = y+1; z < 23; z++) {
+                    int flipped = g23 ^ (1<<x) ^ (1<<y) ^ (1<<z);
+                    checkmask[flipped] = 1;
+                    int c2 = golay23_decode(flipped) >> 11;
+                    if (c != c2) {
+                        printf("Bad!\n");
+                        exit(1);
+                    }
+                }
+            }
+        }
+    }
+
+    //did we check every codeword?
+    for (c = 0; c < (1<<23); c++) {
+        if (checkmask[c] != 1) {
+            printf("%06x unchecked!\n", c);
+            exit(1);
+        }
+    }
+
+    printf("Everything checks out\n");
+    free(checkmask);
+    return 0;
+}
+#endif
diff --git a/codec2/branches/0.7/src/golay23.h b/codec2/branches/0.7/src/golay23.h
new file mode 100644 (file)
index 0000000..a916d29
--- /dev/null
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: golay23.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 March 2013
+
+  Header file for Golay FEC.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __GOLAY23__
+#define __GOLAY23__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void golay23_init(void);
+int  golay23_encode(int data);
+int  golay23_decode(int received_codeword);
+int  golay23_count_errors(int recd_codeword, int corrected_codeword);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/src/golaydectable.h b/codec2/branches/0.7/src/golaydectable.h
new file mode 100644 (file)
index 0000000..bfc7670
--- /dev/null
@@ -0,0 +1,2052 @@
+/* Generated by golay23.c -DGOLAY23_MAKETABLE */
+
+const int static decoding_table[]={
+  0x0,
+  0x1,
+  0x2,
+  0x3,
+  0x4,
+  0x5,
+  0x6,
+  0x7,
+  0x8,
+  0x9,
+  0xa,
+  0xb,
+  0xc,
+  0xd,
+  0xe,
+  0x24020,
+  0x10,
+  0x11,
+  0x12,
+  0x13,
+  0x14,
+  0x15,
+  0x16,
+  0x412000,
+  0x18,
+  0x19,
+  0x1a,
+  0x180800,
+  0x1c,
+  0x200300,
+  0x48040,
+  0x1480,
+  0x20,
+  0x21,
+  0x22,
+  0x23,
+  0x24,
+  0x25,
+  0x26,
+  0x24008,
+  0x28,
+  0x29,
+  0x2a,
+  0x24004,
+  0x2c,
+  0x24002,
+  0x24001,
+  0x24000,
+  0x30,
+  0x31,
+  0x32,
+  0x8180,
+  0x34,
+  0xc40,
+  0x301000,
+  0xc0200,
+  0x38,
+  0x43000,
+  0x400600,
+  0x210040,
+  0x90080,
+  0x508000,
+  0x2900,
+  0x24010,
+  0x40,
+  0x41,
+  0x42,
+  0x43,
+  0x44,
+  0x45,
+  0x46,
+  0x280080,
+  0x48,
+  0x49,
+  0x4a,
+  0x2500,
+  0x4c,
+  0x111000,
+  0x48010,
+  0x400a00,
+  0x50,
+  0x51,
+  0x52,
+  0x21200,
+  0x54,
+  0xc20,
+  0x48008,
+  0x104100,
+  0x58,
+  0x404080,
+  0x48004,
+  0x210020,
+  0x48002,
+  0xa2000,
+  0x48000,
+  0x48001,
+  0x60,
+  0x61,
+  0x62,
+  0x540000,
+  0x64,
+  0xc10,
+  0x10300,
+  0xb000,
+  0x68,
+  0x88200,
+  0x1880,
+  0x210010,
+  0x602000,
+  0x40180,
+  0x180400,
+  0x24040,
+  0x70,
+  0xc04,
+  0x86000,
+  0x210008,
+  0xc01,
+  0xc00,
+  0x420080,
+  0xc02,
+  0x120100,
+  0x210002,
+  0x210001,
+  0x210000,
+  0x5200,
+  0xc08,
+  0x48020,
+  0x210004,
+  0x80,
+  0x81,
+  0x82,
+  0x83,
+  0x84,
+  0x85,
+  0x86,
+  0x280040,
+  0x88,
+  0x89,
+  0x8a,
+  0x50200,
+  0x8c,
+  0xa800,
+  0x500100,
+  0x1410,
+  0x90,
+  0x91,
+  0x92,
+  0x8120,
+  0x94,
+  0x160000,
+  0x4a00,
+  0x1408,
+  0x98,
+  0x404040,
+  0x222000,
+  0x1404,
+  0x90020,
+  0x1402,
+  0x1401,
+  0x1400,
+  0xa0,
+  0xa1,
+  0xa2,
+  0x8110,
+  0xa4,
+  0x401200,
+  0x42400,
+  0x110800,
+  0xa8,
+  0x300400,
+  0x1840,
+  0x482000,
+  0x90010,
+  0x40140,
+  0x208200,
+  0x24080,
+  0xb0,
+  0x8102,
+  0x8101,
+  0x8100,
+  0x90008,
+  0x206000,
+  0x420040,
+  0x8104,
+  0x90004,
+  0x20a00,
+  0x144000,
+  0x8108,
+  0x90000,
+  0x90001,
+  0x90002,
+  0x1420,
+  0xc0,
+  0xc1,
+  0xc2,
+  0x280004,
+  0xc4,
+  0x280002,
+  0x280001,
+  0x280000,
+  0xc8,
+  0x404010,
+  0x1820,
+  0x128000,
+  0x20600,
+  0x40120,
+  0x16000,
+  0x280008,
+  0xd0,
+  0x404008,
+  0x110400,
+  0x42800,
+  0x3100,
+  0x18200,
+  0x420020,
+  0x280010,
+  0x404001,
+  0x404000,
+  0x80300,
+  0x404002,
+  0x300800,
+  0x404004,
+  0x48080,
+  0x1440,
+  0xe0,
+  0x32000,
+  0x1808,
+  0x4600,
+  0x10c000,
+  0x40108,
+  0x420010,
+  0x280020,
+  0x1802,
+  0x40104,
+  0x1800,
+  0x1801,
+  0x40101,
+  0x40100,
+  0x1804,
+  0x40102,
+  0x240200,
+  0x181000,
+  0x420004,
+  0x8140,
+  0x420002,
+  0xc80,
+  0x420000,
+  0x420001,
+  0xa400,
+  0x404020,
+  0x1810,
+  0x210080,
+  0x90040,
+  0x40110,
+  0x420008,
+  0x102200,
+  0x100,
+  0x101,
+  0x102,
+  0x103,
+  0x104,
+  0x105,
+  0x106,
+  0x41800,
+  0x108,
+  0x109,
+  0x10a,
+  0x2440,
+  0x10c,
+  0x200210,
+  0x500080,
+  0x98000,
+  0x110,
+  0x111,
+  0x112,
+  0x80a0,
+  0x114,
+  0x200208,
+  0xa0400,
+  0x104040,
+  0x118,
+  0x200204,
+  0x15000,
+  0x460000,
+  0x200201,
+  0x200200,
+  0x2820,
+  0x200202,
+  0x120,
+  0x121,
+  0x122,
+  0x8090,
+  0x124,
+  0x182000,
+  0x10240,
+  0x600400,
+  0x128,
+  0x410800,
+  0x2c0000,
+  0x101200,
+  0x9400,
+  0x400c0,
+  0x2810,
+  0x24100,
+  0x130,
+  0x8082,
+  0x8081,
+  0x8080,
+  0x444000,
+  0x31000,
+  0x2808,
+  0x8084,
+  0x120040,
+  0x84400,
+  0x2804,
+  0x8088,
+  0x2802,
+  0x200220,
+  0x2800,
+  0x2801,
+  0x140,
+  0x141,
+  0x142,
+  0x2408,
+  0x144,
+  0x428000,
+  0x10220,
+  0x104010,
+  0x148,
+  0x2402,
+  0x2401,
+  0x2400,
+  0x84800,
+  0x400a0,
+  0x221000,
+  0x2404,
+  0x150,
+  0xd0000,
+  0x600800,
+  0x104004,
+  0x3080,
+  0x104002,
+  0x104001,
+  0x104000,
+  0x120020,
+  0x9800,
+  0x80280,
+  0x2410,
+  0x410400,
+  0x200240,
+  0x48100,
+  0x104008,
+  0x160,
+  0x205000,
+  0x10204,
+  0xa0800,
+  0x10202,
+  0x40088,
+  0x10200,
+  0x10201,
+  0x120010,
+  0x40084,
+  0x40c000,
+  0x2420,
+  0x40081,
+  0x40080,
+  0x10208,
+  0x40082,
+  0x120008,
+  0x402200,
+  0x41400,
+  0x80c0,
+  0x288000,
+  0xd00,
+  0x10210,
+  0x104020,
+  0x120000,
+  0x120001,
+  0x120002,
+  0x210100,
+  0x120004,
+  0x40090,
+  0x2840,
+  0x481000,
+  0x180,
+  0x181,
+  0x182,
+  0x8030,
+  0x184,
+  0x14400,
+  0x500008,
+  0x22200,
+  0x188,
+  0xa1000,
+  0x500004,
+  0x204800,
+  0x500002,
+  0x40060,
+  0x500000,
+  0x500001,
+  0x190,
+  0x8022,
+  0x8021,
+  0x8020,
+  0x3040,
+  0x480800,
+  0x250000,
+  0x8024,
+  0x40c00,
+  0x112000,
+  0x80240,
+  0x8028,
+  0x2c000,
+  0x200280,
+  0x500010,
+  0x1500,
+  0x1a0,
+  0x8012,
+  0x8011,
+  0x8010,
+  0x220800,
+  0x40048,
+  0x85000,
+  0x8014,
+  0x6200,
+  0x40044,
+  0x30400,
+  0x8018,
+  0x40041,
+  0x40040,
+  0x500020,
+  0x40042,
+  0x8003,
+  0x8002,
+  0x8001,
+  0x8000,
+  0x100600,
+  0x8006,
+  0x8005,
+  0x8004,
+  0x601000,
+  0x800a,
+  0x8009,
+  0x8008,
+  0x90100,
+  0x40050,
+  0x2880,
+  0x800c,
+  0x1c0,
+  0x100a00,
+  0x64000,
+  0x411000,
+  0x3010,
+  0x40028,
+  0x8c00,
+  0x280100,
+  0x218000,
+  0x40024,
+  0x80210,
+  0x2480,
+  0x40021,
+  0x40020,
+  0x500040,
+  0x40022,
+  0x3004,
+  0x220400,
+  0x80208,
+  0x8060,
+  0x3000,
+  0x3001,
+  0x3002,
+  0x104080,
+  0x80202,
+  0x404100,
+  0x80200,
+  0x80201,
+  0x3008,
+  0x40030,
+  0x80204,
+  0x30800,
+  0x480400,
+  0x4000c,
+  0x302000,
+  0x8050,
+  0x40009,
+  0x40008,
+  0x10280,
+  0x4000a,
+  0x40005,
+  0x40004,
+  0x1900,
+  0x40006,
+  0x40001,
+  0x40000,
+  0x40003,
+  0x40002,
+  0x14800,
+  0x8042,
+  0x8041,
+  0x8040,
+  0x3020,
+  0x40018,
+  0x420100,
+  0x8044,
+  0x120080,
+  0x40014,
+  0x80220,
+  0x8048,
+  0x40011,
+  0x40010,
+  0x204400,
+  0x40012,
+  0x200,
+  0x201,
+  0x202,
+  0x203,
+  0x204,
+  0x205,
+  0x206,
+  0x108400,
+  0x208,
+  0x209,
+  0x20a,
+  0x50080,
+  0x20c,
+  0x200110,
+  0x83000,
+  0x400840,
+  0x210,
+  0x211,
+  0x212,
+  0x21040,
+  0x214,
+  0x200108,
+  0x4880,
+  0xc0020,
+  0x218,
+  0x200104,
+  0x400420,
+  0xe000,
+  0x200101,
+  0x200100,
+  0x130000,
+  0x200102,
+  0x220,
+  0x221,
+  0x222,
+  0x202800,
+  0x224,
+  0x401080,
+  0x10140,
+  0xc0010,
+  0x228,
+  0x88040,
+  0x400410,
+  0x101100,
+  0x140800,
+  0x12400,
+  0x208080,
+  0x24200,
+  0x230,
+  0x114000,
+  0x400408,
+  0xc0004,
+  0x2a000,
+  0xc0002,
+  0xc0001,
+  0xc0000,
+  0x400402,
+  0x20880,
+  0x400400,
+  0x400401,
+  0x5040,
+  0x200120,
+  0x400404,
+  0xc0008,
+  0x240,
+  0x241,
+  0x242,
+  0x21010,
+  0x244,
+  0x46000,
+  0x10120,
+  0x400808,
+  0x248,
+  0x88020,
+  0x304000,
+  0x400804,
+  0x20480,
+  0x400802,
+  0x400801,
+  0x400800,
+  0x250,
+  0x21002,
+  0x21001,
+  0x21000,
+  0x580000,
+  0x18080,
+  0x202400,
+  0x21004,
+  0x12800,
+  0x140400,
+  0x80180,
+  0x21008,
+  0x5020,
+  0x200140,
+  0x48200,
+  0x400810,
+  0x260,
+  0x88008,
+  0x10104,
+  0x4480,
+  0x10102,
+  0x320000,
+  0x10100,
+  0x10101,
+  0x88001,
+  0x88000,
+  0x62000,
+  0x88002,
+  0x5010,
+  0x88004,
+  0x10108,
+  0x400820,
+  0x240080,
+  0x402100,
+  0x108800,
+  0x21020,
+  0x5008,
+  0xe00,
+  0x10110,
+  0xc0040,
+  0x5004,
+  0x88010,
+  0x400440,
+  0x210200,
+  0x5000,
+  0x5001,
+  0x5002,
+  0x102080,
+  0x280,
+  0x281,
+  0x282,
+  0x50008,
+  0x284,
+  0x401020,
+  0x4810,
+  0x22100,
+  0x288,
+  0x50002,
+  0x50001,
+  0x50000,
+  0x20440,
+  0x184000,
+  0x208020,
+  0x50004,
+  0x290,
+  0x82400,
+  0x4804,
+  0x700000,
+  0x4802,
+  0x18040,
+  0x4800,
+  0x4801,
+  0x109000,
+  0x20820,
+  0x80140,
+  0x50010,
+  0x442000,
+  0x200180,
+  0x4808,
+  0x1600,
+  0x2a0,
+  0x401004,
+  0x1a0000,
+  0x4440,
+  0x401001,
+  0x401000,
+  0x208008,
+  0x401002,
+  0x6100,
+  0x20810,
+  0x208004,
+  0x50020,
+  0x208002,
+  0x401008,
+  0x208000,
+  0x208001,
+  0x240040,
+  0x20808,
+  0x13000,
+  0x8300,
+  0x100500,
+  0x401010,
+  0x4820,
+  0xc0080,
+  0x20801,
+  0x20800,
+  0x400480,
+  0x20802,
+  0x90200,
+  0x20804,
+  0x208010,
+  0x102040,
+  0x2c0,
+  0x100900,
+  0x40a000,
+  0x4420,
+  0x20408,
+  0x18010,
+  0x141000,
+  0x280200,
+  0x20404,
+  0x203000,
+  0x80110,
+  0x50040,
+  0x20400,
+  0x20401,
+  0x20402,
+  0x400880,
+  0x240020,
+  0x18004,
+  0x80108,
+  0x21080,
+  0x18001,
+  0x18000,
+  0x4840,
+  0x18002,
+  0x80102,
+  0x404200,
+  0x80100,
+  0x80101,
+  0x20410,
+  0x18008,
+  0x80104,
+  0x102020,
+  0x240010,
+  0x4402,
+  0x4401,
+  0x4400,
+  0x82800,
+  0x401040,
+  0x10180,
+  0x4404,
+  0x510000,
+  0x88080,
+  0x1a00,
+  0x4408,
+  0x20420,
+  0x40300,
+  0x208040,
+  0x102010,
+  0x240000,
+  0x240001,
+  0x240002,
+  0x4410,
+  0x240004,
+  0x18020,
+  0x420200,
+  0x102008,
+  0x240008,
+  0x20840,
+  0x80120,
+  0x102004,
+  0x5080,
+  0x102002,
+  0x102001,
+  0x102000,
+  0x300,
+  0x301,
+  0x302,
+  0x484000,
+  0x304,
+  0x200018,
+  0x10060,
+  0x22080,
+  0x308,
+  0x200014,
+  0x28800,
+  0x101020,
+  0x200011,
+  0x200010,
+  0x44400,
+  0x200012,
+  0x310,
+  0x20000c,
+  0x142000,
+  0x10c00,
+  0x200009,
+  0x200008,
+  0x409000,
+  0x20000a,
+  0x200005,
+  0x200004,
+  0x800c0,
+  0x200006,
+  0x200001,
+  0x200000,
+  0x200003,
+  0x200002,
+  0x320,
+  0x60400,
+  0x10044,
+  0x101008,
+  0x10042,
+  0xc800,
+  0x10040,
+  0x10041,
+  0x6080,
+  0x101002,
+  0x101001,
+  0x101000,
+  0x4a0000,
+  0x200030,
+  0x10048,
+  0x101004,
+  0x81800,
+  0x402040,
+  0x224000,
+  0x8280,
+  0x100480,
+  0x200028,
+  0x10050,
+  0xc0100,
+  0x58000,
+  0x200024,
+  0x400500,
+  0x101010,
+  0x200021,
+  0x200020,
+  0x2a00,
+  0x200022,
+  0x340,
+  0x100880,
+  0x10024,
+  0x248000,
+  0x10022,
+  0x81400,
+  0x10020,
+  0x10021,
+  0x441000,
+  0x34000,
+  0x80090,
+  0x2600,
+  0x10a000,
+  0x200050,
+  0x10028,
+  0x400900,
+  0xc400,
+  0x402020,
+  0x80088,
+  0x21100,
+  0x60800,
+  0x200048,
+  0x10030,
+  0x104200,
+  0x80082,
+  0x200044,
+  0x80080,
+  0x80081,
+  0x200041,
+  0x200040,
+  0x80084,
+  0x200042,
+  0x10006,
+  0x402010,
+  0x10004,
+  0x10005,
+  0x10002,
+  0x10003,
+  0x10000,
+  0x10001,
+  0x200c00,
+  0x88100,
+  0x1000c,
+  0x101040,
+  0x1000a,
+  0x40280,
+  0x10008,
+  0x10009,
+  0x402001,
+  0x402000,
+  0x10014,
+  0x402002,
+  0x10012,
+  0x402004,
+  0x10010,
+  0x10011,
+  0x120200,
+  0x402008,
+  0x800a0,
+  0x44800,
+  0x5100,
+  0x200060,
+  0x10018,
+  0x28400,
+  0x380,
+  0x100840,
+  0x201400,
+  0x22004,
+  0xc8000,
+  0x22002,
+  0x22001,
+  0x22000,
+  0x6020,
+  0x408400,
+  0x80050,
+  0x50100,
+  0x11800,
+  0x200090,
+  0x500200,
+  0x22008,
+  0x430000,
+  0x45000,
+  0x80048,
+  0x8220,
+  0x100420,
+  0x200088,
+  0x4900,
+  0x22010,
+  0x80042,
+  0x200084,
+  0x80040,
+  0x80041,
+  0x200081,
+  0x200080,
+  0x80044,
+  0x200082,
+  0x6008,
+  0x290000,
+  0x440800,
+  0x8210,
+  0x100410,
+  0x401100,
+  0x100c0,
+  0x22020,
+  0x6000,
+  0x6001,
+  0x6002,
+  0x101080,
+  0x6004,
+  0x40240,
+  0x208100,
+  0x80c00,
+  0x100404,
+  0x8202,
+  0x8201,
+  0x8200,
+  0x100400,
+  0x100401,
+  0x100402,
+  0x8204,
+  0x6010,
+  0x20900,
+  0x80060,
+  0x8208,
+  0x100408,
+  0x2000a0,
+  0x61000,
+  0x414000,
+  0x100801,
+  0x100800,
+  0x80018,
+  0x100802,
+  0x604000,
+  0x100804,
+  0x100a0,
+  0x22040,
+  0x80012,
+  0x100808,
+  0x80010,
+  0x80011,
+  0x20500,
+  0x40220,
+  0x80014,
+  0xd000,
+  0x8000a,
+  0x100810,
+  0x80008,
+  0x80009,
+  0x3200,
+  0x18100,
+  0x8000c,
+  0x440400,
+  0x80002,
+  0x80003,
+  0x80000,
+  0x80001,
+  0x80006,
+  0x2000c0,
+  0x80004,
+  0x80005,
+  0x29000,
+  0x100820,
+  0x10084,
+  0x4500,
+  0x10082,
+  0x40208,
+  0x10080,
+  0x10081,
+  0x6040,
+  0x40204,
+  0x80030,
+  0x620000,
+  0x40201,
+  0x40200,
+  0x10088,
+  0x40202,
+  0x240100,
+  0x402080,
+  0x80028,
+  0x8240,
+  0x100440,
+  0xa4000,
+  0x10090,
+  0x201800,
+  0x80022,
+  0x11400,
+  0x80020,
+  0x80021,
+  0x408800,
+  0x40210,
+  0x80024,
+  0x102100,
+  0x400,
+  0x401,
+  0x402,
+  0x403,
+  0x404,
+  0x405,
+  0x406,
+  0x108200,
+  0x408,
+  0x409,
+  0x40a,
+  0x2140,
+  0x40c,
+  0x4c0000,
+  0x210800,
+  0x1090,
+  0x410,
+  0x411,
+  0x412,
+  0x244000,
+  0x414,
+  0x860,
+  0xa0100,
+  0x1088,
+  0x418,
+  0x38000,
+  0x400220,
+  0x1084,
+  0x106000,
+  0x1082,
+  0x1081,
+  0x1080,
+  0x420,
+  0x421,
+  0x422,
+  0x91000,
+  0x424,
+  0x850,
+  0x42080,
+  0x600100,
+  0x428,
+  0x300080,
+  0x400210,
+  0x48800,
+  0x9100,
+  0x12200,
+  0x180040,
+  0x24400,
+  0x430,
+  0x844,
+  0x400208,
+  0x122000,
+  0x841,
+  0x840,
+  0x1c000,
+  0x842,
+  0x400202,
+  0x84100,
+  0x400200,
+  0x400201,
+  0x260000,
+  0x848,
+  0x400204,
+  0x10a0,
+  0x440,
+  0x441,
+  0x442,
+  0x2108,
+  0x444,
+  0x830,
+  0x405000,
+  0x70000,
+  0x448,
+  0x2102,
+  0x2101,
+  0x2100,
+  0x20280,
+  0x20c000,
+  0x180020,
+  0x2104,
+  0x450,
+  0x824,
+  0x110080,
+  0x488000,
+  0x821,
+  0x820,
+  0x202200,
+  0x822,
+  0x281000,
+  0x140200,
+  0x24800,
+  0x2110,
+  0x410100,
+  0x828,
+  0x48400,
+  0x10c0,
+  0x460,
+  0x814,
+  0x228000,
+  0x4280,
+  0x811,
+  0x810,
+  0x180008,
+  0x812,
+  0x54000,
+  0x421000,
+  0x180004,
+  0x2120,
+  0x180002,
+  0x818,
+  0x180000,
+  0x180001,
+  0x805,
+  0x804,
+  0x41100,
+  0x806,
+  0x801,
+  0x800,
+  0x803,
+  0x802,
+  0xa080,
+  0x80c,
+  0x400240,
+  0x210400,
+  0x809,
+  0x808,
+  0x180010,
+  0x80a,
+  0x480,
+  0x481,
+  0x482,
+  0x420800,
+  0x484,
+  0x14100,
+  0x42020,
+  0x1018,
+  0x488,
+  0x300020,
+  0x8c000,
+  0x1014,
+  0x20240,
+  0x1012,
+  0x1011,
+  0x1010,
+  0x490,
+  0x82200,
+  0x110040,
+  0x100c,
+  0x608000,
+  0x100a,
+  0x1009,
+  0x1008,
+  0x40900,
+  0x1006,
+  0x1005,
+  0x1004,
+  0x1003,
+  0x1002,
+  0x1001,
+  0x1000,
+  0x4a0,
+  0x300008,
+  0x42004,
+  0x4240,
+  0x42002,
+  0xa8000,
+  0x42000,
+  0x42001,
+  0x300001,
+  0x300000,
+  0x30100,
+  0x300002,
+  0x404800,
+  0x300004,
+  0x42008,
+  0x1030,
+  0x25000,
+  0x450000,
+  0x280800,
+  0x8500,
+  0x100300,
+  0x8c0,
+  0x42010,
+  0x1028,
+  0xa040,
+  0x300010,
+  0x400280,
+  0x1024,
+  0x90400,
+  0x1022,
+  0x1021,
+  0x1020,
+  0x4c0,
+  0x49000,
+  0x110010,
+  0x4220,
+  0x20208,
+  0x502000,
+  0x8900,
+  0x280400,
+  0x20204,
+  0x90800,
+  0x640000,
+  0x2180,
+  0x20200,
+  0x20201,
+  0x20202,
+  0x1050,
+  0x110002,
+  0x220100,
+  0x110000,
+  0x110001,
+  0xc4000,
+  0x8a0,
+  0x110004,
+  0x1048,
+  0xa020,
+  0x404400,
+  0x110008,
+  0x1044,
+  0x20210,
+  0x1042,
+  0x1041,
+  0x1040,
+  0x480100,
+  0x4202,
+  0x4201,
+  0x4200,
+  0x211000,
+  0x890,
+  0x42040,
+  0x4204,
+  0xa010,
+  0x300040,
+  0x1c00,
+  0x4208,
+  0x20220,
+  0x40500,
+  0x180080,
+  0x418000,
+  0xa008,
+  0x884,
+  0x110020,
+  0x4210,
+  0x881,
+  0x880,
+  0x420400,
+  0x882,
+  0xa000,
+  0xa001,
+  0xa002,
+  0xe0000,
+  0xa004,
+  0x888,
+  0x204100,
+  0x1060,
+  0x500,
+  0x501,
+  0x502,
+  0x2048,
+  0x504,
+  0x14080,
+  0xa0010,
+  0x600020,
+  0x508,
+  0x2042,
+  0x2041,
+  0x2040,
+  0x9020,
+  0x120800,
+  0x44200,
+  0x2044,
+  0x510,
+  0x501000,
+  0xa0004,
+  0x10a00,
+  0xa0002,
+  0x4a000,
+  0xa0000,
+  0xa0001,
+  0x40880,
+  0x84020,
+  0x308000,
+  0x2050,
+  0x410040,
+  0x200600,
+  0xa0008,
+  0x1180,
+  0x520,
+  0x60200,
+  0x104800,
+  0x600004,
+  0x9008,
+  0x600002,
+  0x600001,
+  0x600000,
+  0x9004,
+  0x84010,
+  0x30080,
+  0x2060,
+  0x9000,
+  0x9001,
+  0x9002,
+  0x600008,
+  0x212000,
+  0x84008,
+  0x41040,
+  0x8480,
+  0x100280,
+  0x940,
+  0xa0020,
+  0x600010,
+  0x84001,
+  0x84000,
+  0x400300,
+  0x84002,
+  0x9010,
+  0x84004,
+  0x2c00,
+  0x150000,
+  0x540,
+  0x200a,
+  0x2009,
+  0x2008,
+  0x340000,
+  0x81200,
+  0x8880,
+  0x200c,
+  0x2003,
+  0x2002,
+  0x2001,
+  0x2000,
+  0x410010,
+  0x2006,
+  0x2005,
+  0x2004,
+  0xc200,
+  0x220080,
+  0x41020,
+  0x2018,
+  0x410008,
+  0x920,
+  0xa0040,
+  0x104400,
+  0x410004,
+  0x2012,
+  0x2011,
+  0x2010,
+  0x410000,
+  0x410001,
+  0x410002,
+  0x2014,
+  0x480080,
+  0x118000,
+  0x41010,
+  0x2028,
+  0x26000,
+  0x910,
+  0x10600,
+  0x600040,
+  0x200a00,
+  0x2022,
+  0x2021,
+  0x2020,
+  0x9040,
+  0x40480,
+  0x180100,
+  0x2024,
+  0x41002,
+  0x904,
+  0x41000,
+  0x41001,
+  0x901,
+  0x900,
+  0x41004,
+  0x902,
+  0x120400,
+  0x84040,
+  0x41008,
+  0x2030,
+  0x410020,
+  0x908,
+  0x204080,
+  0x28200,
+  0x580,
+  0x14004,
+  0x201200,
+  0x1c0000,
+  0x14001,
+  0x14000,
+  0x8840,
+  0x14002,
+  0x40810,
+  0x408200,
+  0x30020,
+  0x20c0,
+  0x282000,
+  0x14008,
+  0x500400,
+  0x1110,
+  0x40808,
+  0x220040,
+  0x406000,
+  0x8420,
+  0x100220,
+  0x14010,
+  0xa0080,
+  0x1108,
+  0x40800,
+  0x40801,
+  0x40802,
+  0x1104,
+  0x40804,
+  0x1102,
+  0x1101,
+  0x1100,
+  0x480040,
+  0x3800,
+  0x30008,
+  0x8410,
+  0x100210,
+  0x14020,
+  0x42100,
+  0x600080,
+  0x30002,
+  0x300100,
+  0x30000,
+  0x30001,
+  0x9080,
+  0x40440,
+  0x30004,
+  0x80a00,
+  0x100204,
+  0x8402,
+  0x8401,
+  0x8400,
+  0x100200,
+  0x100201,
+  0x100202,
+  0x8404,
+  0x40820,
+  0x84080,
+  0x30010,
+  0x8408,
+  0x100208,
+  0x422000,
+  0x204040,
+  0x1120,
+  0x480020,
+  0x220010,
+  0x8804,
+  0x2088,
+  0x8802,
+  0x14040,
+  0x8800,
+  0x8801,
+  0x105000,
+  0x2082,
+  0x2081,
+  0x2080,
+  0x20300,
+  0x40420,
+  0x8808,
+  0x2084,
+  0x220001,
+  0x220000,
+  0x110100,
+  0x220002,
+  0x3400,
+  0x220004,
+  0x8810,
+  0x440200,
+  0x40840,
+  0x220008,
+  0x80600,
+  0x2090,
+  0x410080,
+  0x188000,
+  0x204020,
+  0x1140,
+  0x480000,
+  0x480001,
+  0x480002,
+  0x4300,
+  0x480004,
+  0x40408,
+  0x8820,
+  0x121000,
+  0x480008,
+  0x40404,
+  0x30040,
+  0x20a0,
+  0x40401,
+  0x40400,
+  0x204010,
+  0x40402,
+  0x480010,
+  0x220020,
+  0x41080,
+  0x8440,
+  0x100240,
+  0x980,
+  0x204008,
+  0x92000,
+  0xa100,
+  0x11200,
+  0x204004,
+  0x500800,
+  0x204002,
+  0x40410,
+  0x204000,
+  0x204001,
+  0x600,
+  0x601,
+  0x602,
+  0x108004,
+  0x604,
+  0x108002,
+  0x108001,
+  0x108000,
+  0x608,
+  0x5800,
+  0x400030,
+  0x2a0000,
+  0x200c0,
+  0x12020,
+  0x44100,
+  0x108008,
+  0x610,
+  0x82080,
+  0x400028,
+  0x10900,
+  0x51000,
+  0x424000,
+  0x202040,
+  0x108010,
+  0x400022,
+  0x140040,
+  0x400020,
+  0x400021,
+  0x88800,
+  0x200500,
+  0x400024,
+  0x1280,
+  0x620,
+  0x60100,
+  0x400018,
+  0x40c0,
+  0x284000,
+  0x12008,
+  0x21800,
+  0x108020,
+  0x400012,
+  0x12004,
+  0x400010,
+  0x400011,
+  0x12001,
+  0x12000,
+  0x400014,
+  0x12002,
+  0x40000a,
+  0x209000,
+  0x400008,
+  0x400009,
+  0x100180,
+  0xa40,
+  0x40000c,
+  0xc0400,
+  0x400002,
+  0x400003,
+  0x400000,
+  0x400001,
+  0x400006,
+  0x12010,
+  0x400004,
+  0x400005,
+  0x640,
+  0x610000,
+  0xc0800,
+  0x40a0,
+  0x20088,
+  0x81100,
+  0x202010,
+  0x108040,
+  0x20084,
+  0x140010,
+  0x19000,
+  0x2300,
+  0x20080,
+  0x20081,
+  0x20082,
+  0x400c00,
+  0xc100,
+  0x140008,
+  0x202004,
+  0x21400,
+  0x202002,
+  0xa20,
+  0x202000,
+  0x202001,
+  0x140001,
+  0x140000,
+  0x400060,
+  0x140002,
+  0x20090,
+  0x140004,
+  0x202008,
+  0x94000,
+  0x103000,
+  0x4082,
+  0x4081,
+  0x4080,
+  0x448000,
+  0xa10,
+  0x10500,
+  0x4084,
+  0x200900,
+  0x88400,
+  0x400050,
+  0x4088,
+  0x200a0,
+  0x12040,
+  0x180200,
+  0x241000,
+  0xb0000,
+  0xa04,
+  0x400048,
+  0x4090,
+  0xa01,
+  0xa00,
+  0x202020,
+  0xa02,
+  0x400042,
+  0x140020,
+  0x400040,
+  0x400041,
+  0x5400,
+  0xa08,
+  0x400044,
+  0x28100,
+  0x680,
+  0x82010,
+  0x201100,
+  0x4060,
+  0x20048,
+  0x240800,
+  0x490000,
+  0x108080,
+  0x20044,
+  0x408100,
+  0x102800,
+  0x50400,
+  0x20040,
+  0x20041,
+  0x20042,
+  0x1210,
+  0x82001,
+  0x82000,
+  0x68000,
+  0x82002,
+  0x100120,
+  0x82004,
+  0x4c00,
+  0x1208,
+  0x214000,
+  0x82008,
+  0x4000a0,
+  0x1204,
+  0x20050,
+  0x1202,
+  0x1201,
+  0x1200,
+  0x18800,
+  0x4042,
+  0x4041,
+  0x4040,
+  0x100110,
+  0x401400,
+  0x42200,
+  0x4044,
+  0xc1000,
+  0x300200,
+  0x400090,
+  0x4048,
+  0x20060,
+  0x12080,
+  0x208400,
+  0x80900,
+  0x100104,
+  0x82020,
+  0x400088,
+  0x4050,
+  0x100100,
+  0x100101,
+  0x100102,
+  0x230000,
+  0x400082,
+  0x20c00,
+  0x400080,
+  0x400081,
+  0x100108,
+  0x4c000,
+  0x400084,
+  0x1220,
+  0x2000c,
+  0x4022,
+  0x4021,
+  0x4020,
+  0x20008,
+  0x20009,
+  0x2000a,
+  0x4024,
+  0x20004,
+  0x20005,
+  0x20006,
+  0x4028,
+  0x20000,
+  0x20001,
+  0x20002,
+  0x20003,
+  0x401800,
+  0x82040,
+  0x110200,
+  0x4030,
+  0x20018,
+  0x18400,
+  0x202080,
+  0x440100,
+  0x20014,
+  0x140080,
+  0x80500,
+  0x208800,
+  0x20010,
+  0x20011,
+  0x20012,
+  0x1240,
+  0x4003,
+  0x4002,
+  0x4001,
+  0x4000,
+  0x20028,
+  0x4006,
+  0x4005,
+  0x4004,
+  0x20024,
+  0x400a,
+  0x4009,
+  0x4008,
+  0x20020,
+  0x20021,
+  0x20022,
+  0x400c,
+  0x240400,
+  0x4012,
+  0x4011,
+  0x4010,
+  0x100140,
+  0xa80,
+  0x89000,
+  0x4014,
+  0xa200,
+  0x11100,
+  0x4000c0,
+  0x4018,
+  0x20030,
+  0x680000,
+  0x50800,
+  0x102400,
+  0x700,
+  0x60020,
+  0x201080,
+  0x10810,
+  0x402800,
+  0x81040,
+  0x44008,
+  0x108100,
+  0x190000,
+  0x408080,
+  0x44004,
+  0x2240,
+  0x44002,
+  0x200410,
+  0x44000,
+  0x44001,
+  0xc040,
+  0x10802,
+  0x10801,
+  0x10800,
+  0x1000a0,
+  0x200408,
+  0xa0200,
+  0x10804,
+  0x23000,
+  0x200404,
+  0x400120,
+  0x10808,
+  0x200401,
+  0x200400,
+  0x44010,
+  0x200402,
+  0x60001,
+  0x60000,
+  0x8a000,
+  0x60002,
+  0x100090,
+  0x60004,
+  0x10440,
+  0x600200,
+  0x200840,
+  0x60008,
+  0x400110,
+  0x101400,
+  0x9200,
+  0x12100,
+  0x44020,
+  0x80880,
+  0x100084,
+  0x60010,
+  0x400108,
+  0x10820,
+  0x100080,
+  0x100081,
+  0x100082,
+  0x7000,
+  0x400102,
+  0x84200,
+  0x400100,
+  0x400101,
+  0x100088,
+  0x200420,
+  0x400104,
+  0x28040,
+  0xc010,
+  0x81004,
+  0x520000,
+  0x2208,
+  0x81001,
+  0x81000,
+  0x10420,
+  0x81002,
+  0x200820,
+  0x2202,
+  0x2201,
+  0x2200,
+  0x20180,
+  0x81008,
+  0x44040,
+  0x2204,
+  0xc000,
+  0xc001,
+  0xc002,
+  0x10840,
+  0xc004,
+  0x81010,
+  0x202100,
+  0x440080,
+  0xc008,
+  0x140100,
+  0x80480,
+  0x2210,
+  0x410200,
+  0x200440,
+  0x101800,
+  0x28020,
+  0x200808,
+  0x60040,
+  0x10404,
+  0x4180,
+  0x10402,
+  0x81020,
+  0x10400,
+  0x10401,
+  0x200800,
+  0x200801,
+  0x200802,
+  0x2220,
+  0x200804,
+  0x504000,
+  0x10408,
+  0x28010,
+  0xc020,
+  0x402400,
+  0x41200,
+  0x380000,
+  0x1000c0,
+  0xb00,
+  0x10410,
+  0x28008,
+  0x200810,
+  0x11080,
+  0x400140,
+  0x28004,
+  0xc2000,
+  0x28002,
+  0x28001,
+  0x28000,
+  0x201002,
+  0x408008,
+  0x201000,
+  0x201001,
+  0x100030,
+  0x14200,
+  0x201004,
+  0x22400,
+  0x408001,
+  0x408000,
+  0x201008,
+  0x408002,
+  0x20140,
+  0x408004,
+  0x44080,
+  0x80820,
+  0x100024,
+  0x82100,
+  0x201010,
+  0x10880,
+  0x100020,
+  0x100021,
+  0x100022,
+  0x440040,
+  0x40a00,
+  0x408010,
+  0x80440,
+  0x124000,
+  0x100028,
+  0x200480,
+  0x1a000,
+  0x1300,
+  0x100014,
+  0x60080,
+  0x201020,
+  0x4140,
+  0x100010,
+  0x100011,
+  0x100012,
+  0x80808,
+  0x6400,
+  0x408020,
+  0x30200,
+  0x80804,
+  0x100018,
+  0x80802,
+  0x80801,
+  0x80800,
+  0x100004,
+  0x100005,
+  0x100006,
+  0x8600,
+  0x100000,
+  0x100001,
+  0x100002,
+  0x100003,
+  0x10000c,
+  0x11040,
+  0x400180,
+  0x242000,
+  0x100008,
+  0x100009,
+  0x10000a,
+  0x80810,
+  0x52000,
+  0x100c00,
+  0x201040,
+  0x4120,
+  0x20108,
+  0x81080,
+  0x8a00,
+  0x440010,
+  0x20104,
+  0x408040,
+  0x80410,
+  0x2280,
+  0x20100,
+  0x20101,
+  0x20102,
+  0x310000,
+  0xc080,
+  0x220200,
+  0x80408,
+  0x440004,
+  0x100060,
+  0x440002,
+  0x440001,
+  0x440000,
+  0x80402,
+  0x11020,
+  0x80400,
+  0x80401,
+  0x20110,
+  0x6800,
+  0x80404,
+  0x440008,
+  0x480200,
+  0x4102,
+  0x4101,
+  0x4100,
+  0x100050,
+  0x20a000,
+  0x10480,
+  0x4104,
+  0x200880,
+  0x11010,
+  0x148000,
+  0x4108,
+  0x20120,
+  0x40600,
+  0x403000,
+  0x80840,
+  0x100044,
+  0x11008,
+  0x22800,
+  0x4110,
+  0x100040,
+  0x100041,
+  0x100042,
+  0x440020,
+  0x11001,
+  0x11000,
+  0x80420,
+  0x11002,
+  0x100048,
+  0x11004,
+  0x204200,
+  0x28080
+};
diff --git a/codec2/branches/0.7/src/golayenctable.h b/codec2/branches/0.7/src/golayenctable.h
new file mode 100644 (file)
index 0000000..048cee8
--- /dev/null
@@ -0,0 +1,4100 @@
+/* Generated by golay23.c -DGOLAY23_MAKETABLE */
+
+const int static encoding_table[]={
+  0x0,
+  0xc75,
+  0x149f,
+  0x18ea,
+  0x254b,
+  0x293e,
+  0x31d4,
+  0x3da1,
+  0x46e3,
+  0x4a96,
+  0x527c,
+  0x5e09,
+  0x63a8,
+  0x6fdd,
+  0x7737,
+  0x7b42,
+  0x81b3,
+  0x8dc6,
+  0x952c,
+  0x9959,
+  0xa4f8,
+  0xa88d,
+  0xb067,
+  0xbc12,
+  0xc750,
+  0xcb25,
+  0xd3cf,
+  0xdfba,
+  0xe21b,
+  0xee6e,
+  0xf684,
+  0xfaf1,
+  0x10366,
+  0x10f13,
+  0x117f9,
+  0x11b8c,
+  0x1262d,
+  0x12a58,
+  0x132b2,
+  0x13ec7,
+  0x14585,
+  0x149f0,
+  0x1511a,
+  0x15d6f,
+  0x160ce,
+  0x16cbb,
+  0x17451,
+  0x17824,
+  0x182d5,
+  0x18ea0,
+  0x1964a,
+  0x19a3f,
+  0x1a79e,
+  0x1abeb,
+  0x1b301,
+  0x1bf74,
+  0x1c436,
+  0x1c843,
+  0x1d0a9,
+  0x1dcdc,
+  0x1e17d,
+  0x1ed08,
+  0x1f5e2,
+  0x1f997,
+  0x206cc,
+  0x20ab9,
+  0x21253,
+  0x21e26,
+  0x22387,
+  0x22ff2,
+  0x23718,
+  0x23b6d,
+  0x2402f,
+  0x24c5a,
+  0x254b0,
+  0x258c5,
+  0x26564,
+  0x26911,
+  0x271fb,
+  0x27d8e,
+  0x2877f,
+  0x28b0a,
+  0x293e0,
+  0x29f95,
+  0x2a234,
+  0x2ae41,
+  0x2b6ab,
+  0x2bade,
+  0x2c19c,
+  0x2cde9,
+  0x2d503,
+  0x2d976,
+  0x2e4d7,
+  0x2e8a2,
+  0x2f048,
+  0x2fc3d,
+  0x305aa,
+  0x309df,
+  0x31135,
+  0x31d40,
+  0x320e1,
+  0x32c94,
+  0x3347e,
+  0x3380b,
+  0x34349,
+  0x34f3c,
+  0x357d6,
+  0x35ba3,
+  0x36602,
+  0x36a77,
+  0x3729d,
+  0x37ee8,
+  0x38419,
+  0x3886c,
+  0x39086,
+  0x39cf3,
+  0x3a152,
+  0x3ad27,
+  0x3b5cd,
+  0x3b9b8,
+  0x3c2fa,
+  0x3ce8f,
+  0x3d665,
+  0x3da10,
+  0x3e7b1,
+  0x3ebc4,
+  0x3f32e,
+  0x3ff5b,
+  0x401ed,
+  0x40d98,
+  0x41572,
+  0x41907,
+  0x424a6,
+  0x428d3,
+  0x43039,
+  0x43c4c,
+  0x4470e,
+  0x44b7b,
+  0x45391,
+  0x45fe4,
+  0x46245,
+  0x46e30,
+  0x476da,
+  0x47aaf,
+  0x4805e,
+  0x48c2b,
+  0x494c1,
+  0x498b4,
+  0x4a515,
+  0x4a960,
+  0x4b18a,
+  0x4bdff,
+  0x4c6bd,
+  0x4cac8,
+  0x4d222,
+  0x4de57,
+  0x4e3f6,
+  0x4ef83,
+  0x4f769,
+  0x4fb1c,
+  0x5028b,
+  0x50efe,
+  0x51614,
+  0x51a61,
+  0x527c0,
+  0x52bb5,
+  0x5335f,
+  0x53f2a,
+  0x54468,
+  0x5481d,
+  0x550f7,
+  0x55c82,
+  0x56123,
+  0x56d56,
+  0x575bc,
+  0x579c9,
+  0x58338,
+  0x58f4d,
+  0x597a7,
+  0x59bd2,
+  0x5a673,
+  0x5aa06,
+  0x5b2ec,
+  0x5be99,
+  0x5c5db,
+  0x5c9ae,
+  0x5d144,
+  0x5dd31,
+  0x5e090,
+  0x5ece5,
+  0x5f40f,
+  0x5f87a,
+  0x60721,
+  0x60b54,
+  0x613be,
+  0x61fcb,
+  0x6226a,
+  0x62e1f,
+  0x636f5,
+  0x63a80,
+  0x641c2,
+  0x64db7,
+  0x6555d,
+  0x65928,
+  0x66489,
+  0x668fc,
+  0x67016,
+  0x67c63,
+  0x68692,
+  0x68ae7,
+  0x6920d,
+  0x69e78,
+  0x6a3d9,
+  0x6afac,
+  0x6b746,
+  0x6bb33,
+  0x6c071,
+  0x6cc04,
+  0x6d4ee,
+  0x6d89b,
+  0x6e53a,
+  0x6e94f,
+  0x6f1a5,
+  0x6fdd0,
+  0x70447,
+  0x70832,
+  0x710d8,
+  0x71cad,
+  0x7210c,
+  0x72d79,
+  0x73593,
+  0x739e6,
+  0x742a4,
+  0x74ed1,
+  0x7563b,
+  0x75a4e,
+  0x767ef,
+  0x76b9a,
+  0x77370,
+  0x77f05,
+  0x785f4,
+  0x78981,
+  0x7916b,
+  0x79d1e,
+  0x7a0bf,
+  0x7acca,
+  0x7b420,
+  0x7b855,
+  0x7c317,
+  0x7cf62,
+  0x7d788,
+  0x7dbfd,
+  0x7e65c,
+  0x7ea29,
+  0x7f2c3,
+  0x7feb6,
+  0x803da,
+  0x80faf,
+  0x81745,
+  0x81b30,
+  0x82691,
+  0x82ae4,
+  0x8320e,
+  0x83e7b,
+  0x84539,
+  0x8494c,
+  0x851a6,
+  0x85dd3,
+  0x86072,
+  0x86c07,
+  0x874ed,
+  0x87898,
+  0x88269,
+  0x88e1c,
+  0x896f6,
+  0x89a83,
+  0x8a722,
+  0x8ab57,
+  0x8b3bd,
+  0x8bfc8,
+  0x8c48a,
+  0x8c8ff,
+  0x8d015,
+  0x8dc60,
+  0x8e1c1,
+  0x8edb4,
+  0x8f55e,
+  0x8f92b,
+  0x900bc,
+  0x90cc9,
+  0x91423,
+  0x91856,
+  0x925f7,
+  0x92982,
+  0x93168,
+  0x93d1d,
+  0x9465f,
+  0x94a2a,
+  0x952c0,
+  0x95eb5,
+  0x96314,
+  0x96f61,
+  0x9778b,
+  0x97bfe,
+  0x9810f,
+  0x98d7a,
+  0x99590,
+  0x999e5,
+  0x9a444,
+  0x9a831,
+  0x9b0db,
+  0x9bcae,
+  0x9c7ec,
+  0x9cb99,
+  0x9d373,
+  0x9df06,
+  0x9e2a7,
+  0x9eed2,
+  0x9f638,
+  0x9fa4d,
+  0xa0516,
+  0xa0963,
+  0xa1189,
+  0xa1dfc,
+  0xa205d,
+  0xa2c28,
+  0xa34c2,
+  0xa38b7,
+  0xa43f5,
+  0xa4f80,
+  0xa576a,
+  0xa5b1f,
+  0xa66be,
+  0xa6acb,
+  0xa7221,
+  0xa7e54,
+  0xa84a5,
+  0xa88d0,
+  0xa903a,
+  0xa9c4f,
+  0xaa1ee,
+  0xaad9b,
+  0xab571,
+  0xab904,
+  0xac246,
+  0xace33,
+  0xad6d9,
+  0xadaac,
+  0xae70d,
+  0xaeb78,
+  0xaf392,
+  0xaffe7,
+  0xb0670,
+  0xb0a05,
+  0xb12ef,
+  0xb1e9a,
+  0xb233b,
+  0xb2f4e,
+  0xb37a4,
+  0xb3bd1,
+  0xb4093,
+  0xb4ce6,
+  0xb540c,
+  0xb5879,
+  0xb65d8,
+  0xb69ad,
+  0xb7147,
+  0xb7d32,
+  0xb87c3,
+  0xb8bb6,
+  0xb935c,
+  0xb9f29,
+  0xba288,
+  0xbaefd,
+  0xbb617,
+  0xbba62,
+  0xbc120,
+  0xbcd55,
+  0xbd5bf,
+  0xbd9ca,
+  0xbe46b,
+  0xbe81e,
+  0xbf0f4,
+  0xbfc81,
+  0xc0237,
+  0xc0e42,
+  0xc16a8,
+  0xc1add,
+  0xc277c,
+  0xc2b09,
+  0xc33e3,
+  0xc3f96,
+  0xc44d4,
+  0xc48a1,
+  0xc504b,
+  0xc5c3e,
+  0xc619f,
+  0xc6dea,
+  0xc7500,
+  0xc7975,
+  0xc8384,
+  0xc8ff1,
+  0xc971b,
+  0xc9b6e,
+  0xca6cf,
+  0xcaaba,
+  0xcb250,
+  0xcbe25,
+  0xcc567,
+  0xcc912,
+  0xcd1f8,
+  0xcdd8d,
+  0xce02c,
+  0xcec59,
+  0xcf4b3,
+  0xcf8c6,
+  0xd0151,
+  0xd0d24,
+  0xd15ce,
+  0xd19bb,
+  0xd241a,
+  0xd286f,
+  0xd3085,
+  0xd3cf0,
+  0xd47b2,
+  0xd4bc7,
+  0xd532d,
+  0xd5f58,
+  0xd62f9,
+  0xd6e8c,
+  0xd7666,
+  0xd7a13,
+  0xd80e2,
+  0xd8c97,
+  0xd947d,
+  0xd9808,
+  0xda5a9,
+  0xda9dc,
+  0xdb136,
+  0xdbd43,
+  0xdc601,
+  0xdca74,
+  0xdd29e,
+  0xddeeb,
+  0xde34a,
+  0xdef3f,
+  0xdf7d5,
+  0xdfba0,
+  0xe04fb,
+  0xe088e,
+  0xe1064,
+  0xe1c11,
+  0xe21b0,
+  0xe2dc5,
+  0xe352f,
+  0xe395a,
+  0xe4218,
+  0xe4e6d,
+  0xe5687,
+  0xe5af2,
+  0xe6753,
+  0xe6b26,
+  0xe73cc,
+  0xe7fb9,
+  0xe8548,
+  0xe893d,
+  0xe91d7,
+  0xe9da2,
+  0xea003,
+  0xeac76,
+  0xeb49c,
+  0xeb8e9,
+  0xec3ab,
+  0xecfde,
+  0xed734,
+  0xedb41,
+  0xee6e0,
+  0xeea95,
+  0xef27f,
+  0xefe0a,
+  0xf079d,
+  0xf0be8,
+  0xf1302,
+  0xf1f77,
+  0xf22d6,
+  0xf2ea3,
+  0xf3649,
+  0xf3a3c,
+  0xf417e,
+  0xf4d0b,
+  0xf55e1,
+  0xf5994,
+  0xf6435,
+  0xf6840,
+  0xf70aa,
+  0xf7cdf,
+  0xf862e,
+  0xf8a5b,
+  0xf92b1,
+  0xf9ec4,
+  0xfa365,
+  0xfaf10,
+  0xfb7fa,
+  0xfbb8f,
+  0xfc0cd,
+  0xfccb8,
+  0xfd452,
+  0xfd827,
+  0xfe586,
+  0xfe9f3,
+  0xff119,
+  0xffd6c,
+  0x1007b4,
+  0x100bc1,
+  0x10132b,
+  0x101f5e,
+  0x1022ff,
+  0x102e8a,
+  0x103660,
+  0x103a15,
+  0x104157,
+  0x104d22,
+  0x1055c8,
+  0x1059bd,
+  0x10641c,
+  0x106869,
+  0x107083,
+  0x107cf6,
+  0x108607,
+  0x108a72,
+  0x109298,
+  0x109eed,
+  0x10a34c,
+  0x10af39,
+  0x10b7d3,
+  0x10bba6,
+  0x10c0e4,
+  0x10cc91,
+  0x10d47b,
+  0x10d80e,
+  0x10e5af,
+  0x10e9da,
+  0x10f130,
+  0x10fd45,
+  0x1104d2,
+  0x1108a7,
+  0x11104d,
+  0x111c38,
+  0x112199,
+  0x112dec,
+  0x113506,
+  0x113973,
+  0x114231,
+  0x114e44,
+  0x1156ae,
+  0x115adb,
+  0x11677a,
+  0x116b0f,
+  0x1173e5,
+  0x117f90,
+  0x118561,
+  0x118914,
+  0x1191fe,
+  0x119d8b,
+  0x11a02a,
+  0x11ac5f,
+  0x11b4b5,
+  0x11b8c0,
+  0x11c382,
+  0x11cff7,
+  0x11d71d,
+  0x11db68,
+  0x11e6c9,
+  0x11eabc,
+  0x11f256,
+  0x11fe23,
+  0x120178,
+  0x120d0d,
+  0x1215e7,
+  0x121992,
+  0x122433,
+  0x122846,
+  0x1230ac,
+  0x123cd9,
+  0x12479b,
+  0x124bee,
+  0x125304,
+  0x125f71,
+  0x1262d0,
+  0x126ea5,
+  0x12764f,
+  0x127a3a,
+  0x1280cb,
+  0x128cbe,
+  0x129454,
+  0x129821,
+  0x12a580,
+  0x12a9f5,
+  0x12b11f,
+  0x12bd6a,
+  0x12c628,
+  0x12ca5d,
+  0x12d2b7,
+  0x12dec2,
+  0x12e363,
+  0x12ef16,
+  0x12f7fc,
+  0x12fb89,
+  0x13021e,
+  0x130e6b,
+  0x131681,
+  0x131af4,
+  0x132755,
+  0x132b20,
+  0x1333ca,
+  0x133fbf,
+  0x1344fd,
+  0x134888,
+  0x135062,
+  0x135c17,
+  0x1361b6,
+  0x136dc3,
+  0x137529,
+  0x13795c,
+  0x1383ad,
+  0x138fd8,
+  0x139732,
+  0x139b47,
+  0x13a6e6,
+  0x13aa93,
+  0x13b279,
+  0x13be0c,
+  0x13c54e,
+  0x13c93b,
+  0x13d1d1,
+  0x13dda4,
+  0x13e005,
+  0x13ec70,
+  0x13f49a,
+  0x13f8ef,
+  0x140659,
+  0x140a2c,
+  0x1412c6,
+  0x141eb3,
+  0x142312,
+  0x142f67,
+  0x14378d,
+  0x143bf8,
+  0x1440ba,
+  0x144ccf,
+  0x145425,
+  0x145850,
+  0x1465f1,
+  0x146984,
+  0x14716e,
+  0x147d1b,
+  0x1487ea,
+  0x148b9f,
+  0x149375,
+  0x149f00,
+  0x14a2a1,
+  0x14aed4,
+  0x14b63e,
+  0x14ba4b,
+  0x14c109,
+  0x14cd7c,
+  0x14d596,
+  0x14d9e3,
+  0x14e442,
+  0x14e837,
+  0x14f0dd,
+  0x14fca8,
+  0x15053f,
+  0x15094a,
+  0x1511a0,
+  0x151dd5,
+  0x152074,
+  0x152c01,
+  0x1534eb,
+  0x15389e,
+  0x1543dc,
+  0x154fa9,
+  0x155743,
+  0x155b36,
+  0x156697,
+  0x156ae2,
+  0x157208,
+  0x157e7d,
+  0x15848c,
+  0x1588f9,
+  0x159013,
+  0x159c66,
+  0x15a1c7,
+  0x15adb2,
+  0x15b558,
+  0x15b92d,
+  0x15c26f,
+  0x15ce1a,
+  0x15d6f0,
+  0x15da85,
+  0x15e724,
+  0x15eb51,
+  0x15f3bb,
+  0x15ffce,
+  0x160095,
+  0x160ce0,
+  0x16140a,
+  0x16187f,
+  0x1625de,
+  0x1629ab,
+  0x163141,
+  0x163d34,
+  0x164676,
+  0x164a03,
+  0x1652e9,
+  0x165e9c,
+  0x16633d,
+  0x166f48,
+  0x1677a2,
+  0x167bd7,
+  0x168126,
+  0x168d53,
+  0x1695b9,
+  0x1699cc,
+  0x16a46d,
+  0x16a818,
+  0x16b0f2,
+  0x16bc87,
+  0x16c7c5,
+  0x16cbb0,
+  0x16d35a,
+  0x16df2f,
+  0x16e28e,
+  0x16eefb,
+  0x16f611,
+  0x16fa64,
+  0x1703f3,
+  0x170f86,
+  0x17176c,
+  0x171b19,
+  0x1726b8,
+  0x172acd,
+  0x173227,
+  0x173e52,
+  0x174510,
+  0x174965,
+  0x17518f,
+  0x175dfa,
+  0x17605b,
+  0x176c2e,
+  0x1774c4,
+  0x1778b1,
+  0x178240,
+  0x178e35,
+  0x1796df,
+  0x179aaa,
+  0x17a70b,
+  0x17ab7e,
+  0x17b394,
+  0x17bfe1,
+  0x17c4a3,
+  0x17c8d6,
+  0x17d03c,
+  0x17dc49,
+  0x17e1e8,
+  0x17ed9d,
+  0x17f577,
+  0x17f902,
+  0x18046e,
+  0x18081b,
+  0x1810f1,
+  0x181c84,
+  0x182125,
+  0x182d50,
+  0x1835ba,
+  0x1839cf,
+  0x18428d,
+  0x184ef8,
+  0x185612,
+  0x185a67,
+  0x1867c6,
+  0x186bb3,
+  0x187359,
+  0x187f2c,
+  0x1885dd,
+  0x1889a8,
+  0x189142,
+  0x189d37,
+  0x18a096,
+  0x18ace3,
+  0x18b409,
+  0x18b87c,
+  0x18c33e,
+  0x18cf4b,
+  0x18d7a1,
+  0x18dbd4,
+  0x18e675,
+  0x18ea00,
+  0x18f2ea,
+  0x18fe9f,
+  0x190708,
+  0x190b7d,
+  0x191397,
+  0x191fe2,
+  0x192243,
+  0x192e36,
+  0x1936dc,
+  0x193aa9,
+  0x1941eb,
+  0x194d9e,
+  0x195574,
+  0x195901,
+  0x1964a0,
+  0x1968d5,
+  0x19703f,
+  0x197c4a,
+  0x1986bb,
+  0x198ace,
+  0x199224,
+  0x199e51,
+  0x19a3f0,
+  0x19af85,
+  0x19b76f,
+  0x19bb1a,
+  0x19c058,
+  0x19cc2d,
+  0x19d4c7,
+  0x19d8b2,
+  0x19e513,
+  0x19e966,
+  0x19f18c,
+  0x19fdf9,
+  0x1a02a2,
+  0x1a0ed7,
+  0x1a163d,
+  0x1a1a48,
+  0x1a27e9,
+  0x1a2b9c,
+  0x1a3376,
+  0x1a3f03,
+  0x1a4441,
+  0x1a4834,
+  0x1a50de,
+  0x1a5cab,
+  0x1a610a,
+  0x1a6d7f,
+  0x1a7595,
+  0x1a79e0,
+  0x1a8311,
+  0x1a8f64,
+  0x1a978e,
+  0x1a9bfb,
+  0x1aa65a,
+  0x1aaa2f,
+  0x1ab2c5,
+  0x1abeb0,
+  0x1ac5f2,
+  0x1ac987,
+  0x1ad16d,
+  0x1add18,
+  0x1ae0b9,
+  0x1aeccc,
+  0x1af426,
+  0x1af853,
+  0x1b01c4,
+  0x1b0db1,
+  0x1b155b,
+  0x1b192e,
+  0x1b248f,
+  0x1b28fa,
+  0x1b3010,
+  0x1b3c65,
+  0x1b4727,
+  0x1b4b52,
+  0x1b53b8,
+  0x1b5fcd,
+  0x1b626c,
+  0x1b6e19,
+  0x1b76f3,
+  0x1b7a86,
+  0x1b8077,
+  0x1b8c02,
+  0x1b94e8,
+  0x1b989d,
+  0x1ba53c,
+  0x1ba949,
+  0x1bb1a3,
+  0x1bbdd6,
+  0x1bc694,
+  0x1bcae1,
+  0x1bd20b,
+  0x1bde7e,
+  0x1be3df,
+  0x1befaa,
+  0x1bf740,
+  0x1bfb35,
+  0x1c0583,
+  0x1c09f6,
+  0x1c111c,
+  0x1c1d69,
+  0x1c20c8,
+  0x1c2cbd,
+  0x1c3457,
+  0x1c3822,
+  0x1c4360,
+  0x1c4f15,
+  0x1c57ff,
+  0x1c5b8a,
+  0x1c662b,
+  0x1c6a5e,
+  0x1c72b4,
+  0x1c7ec1,
+  0x1c8430,
+  0x1c8845,
+  0x1c90af,
+  0x1c9cda,
+  0x1ca17b,
+  0x1cad0e,
+  0x1cb5e4,
+  0x1cb991,
+  0x1cc2d3,
+  0x1ccea6,
+  0x1cd64c,
+  0x1cda39,
+  0x1ce798,
+  0x1cebed,
+  0x1cf307,
+  0x1cff72,
+  0x1d06e5,
+  0x1d0a90,
+  0x1d127a,
+  0x1d1e0f,
+  0x1d23ae,
+  0x1d2fdb,
+  0x1d3731,
+  0x1d3b44,
+  0x1d4006,
+  0x1d4c73,
+  0x1d5499,
+  0x1d58ec,
+  0x1d654d,
+  0x1d6938,
+  0x1d71d2,
+  0x1d7da7,
+  0x1d8756,
+  0x1d8b23,
+  0x1d93c9,
+  0x1d9fbc,
+  0x1da21d,
+  0x1dae68,
+  0x1db682,
+  0x1dbaf7,
+  0x1dc1b5,
+  0x1dcdc0,
+  0x1dd52a,
+  0x1dd95f,
+  0x1de4fe,
+  0x1de88b,
+  0x1df061,
+  0x1dfc14,
+  0x1e034f,
+  0x1e0f3a,
+  0x1e17d0,
+  0x1e1ba5,
+  0x1e2604,
+  0x1e2a71,
+  0x1e329b,
+  0x1e3eee,
+  0x1e45ac,
+  0x1e49d9,
+  0x1e5133,
+  0x1e5d46,
+  0x1e60e7,
+  0x1e6c92,
+  0x1e7478,
+  0x1e780d,
+  0x1e82fc,
+  0x1e8e89,
+  0x1e9663,
+  0x1e9a16,
+  0x1ea7b7,
+  0x1eabc2,
+  0x1eb328,
+  0x1ebf5d,
+  0x1ec41f,
+  0x1ec86a,
+  0x1ed080,
+  0x1edcf5,
+  0x1ee154,
+  0x1eed21,
+  0x1ef5cb,
+  0x1ef9be,
+  0x1f0029,
+  0x1f0c5c,
+  0x1f14b6,
+  0x1f18c3,
+  0x1f2562,
+  0x1f2917,
+  0x1f31fd,
+  0x1f3d88,
+  0x1f46ca,
+  0x1f4abf,
+  0x1f5255,
+  0x1f5e20,
+  0x1f6381,
+  0x1f6ff4,
+  0x1f771e,
+  0x1f7b6b,
+  0x1f819a,
+  0x1f8def,
+  0x1f9505,
+  0x1f9970,
+  0x1fa4d1,
+  0x1fa8a4,
+  0x1fb04e,
+  0x1fbc3b,
+  0x1fc779,
+  0x1fcb0c,
+  0x1fd3e6,
+  0x1fdf93,
+  0x1fe232,
+  0x1fee47,
+  0x1ff6ad,
+  0x1ffad8,
+  0x20031d,
+  0x200f68,
+  0x201782,
+  0x201bf7,
+  0x202656,
+  0x202a23,
+  0x2032c9,
+  0x203ebc,
+  0x2045fe,
+  0x20498b,
+  0x205161,
+  0x205d14,
+  0x2060b5,
+  0x206cc0,
+  0x20742a,
+  0x20785f,
+  0x2082ae,
+  0x208edb,
+  0x209631,
+  0x209a44,
+  0x20a7e5,
+  0x20ab90,
+  0x20b37a,
+  0x20bf0f,
+  0x20c44d,
+  0x20c838,
+  0x20d0d2,
+  0x20dca7,
+  0x20e106,
+  0x20ed73,
+  0x20f599,
+  0x20f9ec,
+  0x21007b,
+  0x210c0e,
+  0x2114e4,
+  0x211891,
+  0x212530,
+  0x212945,
+  0x2131af,
+  0x213dda,
+  0x214698,
+  0x214aed,
+  0x215207,
+  0x215e72,
+  0x2163d3,
+  0x216fa6,
+  0x21774c,
+  0x217b39,
+  0x2181c8,
+  0x218dbd,
+  0x219557,
+  0x219922,
+  0x21a483,
+  0x21a8f6,
+  0x21b01c,
+  0x21bc69,
+  0x21c72b,
+  0x21cb5e,
+  0x21d3b4,
+  0x21dfc1,
+  0x21e260,
+  0x21ee15,
+  0x21f6ff,
+  0x21fa8a,
+  0x2205d1,
+  0x2209a4,
+  0x22114e,
+  0x221d3b,
+  0x22209a,
+  0x222cef,
+  0x223405,
+  0x223870,
+  0x224332,
+  0x224f47,
+  0x2257ad,
+  0x225bd8,
+  0x226679,
+  0x226a0c,
+  0x2272e6,
+  0x227e93,
+  0x228462,
+  0x228817,
+  0x2290fd,
+  0x229c88,
+  0x22a129,
+  0x22ad5c,
+  0x22b5b6,
+  0x22b9c3,
+  0x22c281,
+  0x22cef4,
+  0x22d61e,
+  0x22da6b,
+  0x22e7ca,
+  0x22ebbf,
+  0x22f355,
+  0x22ff20,
+  0x2306b7,
+  0x230ac2,
+  0x231228,
+  0x231e5d,
+  0x2323fc,
+  0x232f89,
+  0x233763,
+  0x233b16,
+  0x234054,
+  0x234c21,
+  0x2354cb,
+  0x2358be,
+  0x23651f,
+  0x23696a,
+  0x237180,
+  0x237df5,
+  0x238704,
+  0x238b71,
+  0x23939b,
+  0x239fee,
+  0x23a24f,
+  0x23ae3a,
+  0x23b6d0,
+  0x23baa5,
+  0x23c1e7,
+  0x23cd92,
+  0x23d578,
+  0x23d90d,
+  0x23e4ac,
+  0x23e8d9,
+  0x23f033,
+  0x23fc46,
+  0x2402f0,
+  0x240e85,
+  0x24166f,
+  0x241a1a,
+  0x2427bb,
+  0x242bce,
+  0x243324,
+  0x243f51,
+  0x244413,
+  0x244866,
+  0x24508c,
+  0x245cf9,
+  0x246158,
+  0x246d2d,
+  0x2475c7,
+  0x2479b2,
+  0x248343,
+  0x248f36,
+  0x2497dc,
+  0x249ba9,
+  0x24a608,
+  0x24aa7d,
+  0x24b297,
+  0x24bee2,
+  0x24c5a0,
+  0x24c9d5,
+  0x24d13f,
+  0x24dd4a,
+  0x24e0eb,
+  0x24ec9e,
+  0x24f474,
+  0x24f801,
+  0x250196,
+  0x250de3,
+  0x251509,
+  0x25197c,
+  0x2524dd,
+  0x2528a8,
+  0x253042,
+  0x253c37,
+  0x254775,
+  0x254b00,
+  0x2553ea,
+  0x255f9f,
+  0x25623e,
+  0x256e4b,
+  0x2576a1,
+  0x257ad4,
+  0x258025,
+  0x258c50,
+  0x2594ba,
+  0x2598cf,
+  0x25a56e,
+  0x25a91b,
+  0x25b1f1,
+  0x25bd84,
+  0x25c6c6,
+  0x25cab3,
+  0x25d259,
+  0x25de2c,
+  0x25e38d,
+  0x25eff8,
+  0x25f712,
+  0x25fb67,
+  0x26043c,
+  0x260849,
+  0x2610a3,
+  0x261cd6,
+  0x262177,
+  0x262d02,
+  0x2635e8,
+  0x26399d,
+  0x2642df,
+  0x264eaa,
+  0x265640,
+  0x265a35,
+  0x266794,
+  0x266be1,
+  0x26730b,
+  0x267f7e,
+  0x26858f,
+  0x2689fa,
+  0x269110,
+  0x269d65,
+  0x26a0c4,
+  0x26acb1,
+  0x26b45b,
+  0x26b82e,
+  0x26c36c,
+  0x26cf19,
+  0x26d7f3,
+  0x26db86,
+  0x26e627,
+  0x26ea52,
+  0x26f2b8,
+  0x26fecd,
+  0x27075a,
+  0x270b2f,
+  0x2713c5,
+  0x271fb0,
+  0x272211,
+  0x272e64,
+  0x27368e,
+  0x273afb,
+  0x2741b9,
+  0x274dcc,
+  0x275526,
+  0x275953,
+  0x2764f2,
+  0x276887,
+  0x27706d,
+  0x277c18,
+  0x2786e9,
+  0x278a9c,
+  0x279276,
+  0x279e03,
+  0x27a3a2,
+  0x27afd7,
+  0x27b73d,
+  0x27bb48,
+  0x27c00a,
+  0x27cc7f,
+  0x27d495,
+  0x27d8e0,
+  0x27e541,
+  0x27e934,
+  0x27f1de,
+  0x27fdab,
+  0x2800c7,
+  0x280cb2,
+  0x281458,
+  0x28182d,
+  0x28258c,
+  0x2829f9,
+  0x283113,
+  0x283d66,
+  0x284624,
+  0x284a51,
+  0x2852bb,
+  0x285ece,
+  0x28636f,
+  0x286f1a,
+  0x2877f0,
+  0x287b85,
+  0x288174,
+  0x288d01,
+  0x2895eb,
+  0x28999e,
+  0x28a43f,
+  0x28a84a,
+  0x28b0a0,
+  0x28bcd5,
+  0x28c797,
+  0x28cbe2,
+  0x28d308,
+  0x28df7d,
+  0x28e2dc,
+  0x28eea9,
+  0x28f643,
+  0x28fa36,
+  0x2903a1,
+  0x290fd4,
+  0x29173e,
+  0x291b4b,
+  0x2926ea,
+  0x292a9f,
+  0x293275,
+  0x293e00,
+  0x294542,
+  0x294937,
+  0x2951dd,
+  0x295da8,
+  0x296009,
+  0x296c7c,
+  0x297496,
+  0x2978e3,
+  0x298212,
+  0x298e67,
+  0x29968d,
+  0x299af8,
+  0x29a759,
+  0x29ab2c,
+  0x29b3c6,
+  0x29bfb3,
+  0x29c4f1,
+  0x29c884,
+  0x29d06e,
+  0x29dc1b,
+  0x29e1ba,
+  0x29edcf,
+  0x29f525,
+  0x29f950,
+  0x2a060b,
+  0x2a0a7e,
+  0x2a1294,
+  0x2a1ee1,
+  0x2a2340,
+  0x2a2f35,
+  0x2a37df,
+  0x2a3baa,
+  0x2a40e8,
+  0x2a4c9d,
+  0x2a5477,
+  0x2a5802,
+  0x2a65a3,
+  0x2a69d6,
+  0x2a713c,
+  0x2a7d49,
+  0x2a87b8,
+  0x2a8bcd,
+  0x2a9327,
+  0x2a9f52,
+  0x2aa2f3,
+  0x2aae86,
+  0x2ab66c,
+  0x2aba19,
+  0x2ac15b,
+  0x2acd2e,
+  0x2ad5c4,
+  0x2ad9b1,
+  0x2ae410,
+  0x2ae865,
+  0x2af08f,
+  0x2afcfa,
+  0x2b056d,
+  0x2b0918,
+  0x2b11f2,
+  0x2b1d87,
+  0x2b2026,
+  0x2b2c53,
+  0x2b34b9,
+  0x2b38cc,
+  0x2b438e,
+  0x2b4ffb,
+  0x2b5711,
+  0x2b5b64,
+  0x2b66c5,
+  0x2b6ab0,
+  0x2b725a,
+  0x2b7e2f,
+  0x2b84de,
+  0x2b88ab,
+  0x2b9041,
+  0x2b9c34,
+  0x2ba195,
+  0x2bade0,
+  0x2bb50a,
+  0x2bb97f,
+  0x2bc23d,
+  0x2bce48,
+  0x2bd6a2,
+  0x2bdad7,
+  0x2be776,
+  0x2beb03,
+  0x2bf3e9,
+  0x2bff9c,
+  0x2c012a,
+  0x2c0d5f,
+  0x2c15b5,
+  0x2c19c0,
+  0x2c2461,
+  0x2c2814,
+  0x2c30fe,
+  0x2c3c8b,
+  0x2c47c9,
+  0x2c4bbc,
+  0x2c5356,
+  0x2c5f23,
+  0x2c6282,
+  0x2c6ef7,
+  0x2c761d,
+  0x2c7a68,
+  0x2c8099,
+  0x2c8cec,
+  0x2c9406,
+  0x2c9873,
+  0x2ca5d2,
+  0x2ca9a7,
+  0x2cb14d,
+  0x2cbd38,
+  0x2cc67a,
+  0x2cca0f,
+  0x2cd2e5,
+  0x2cde90,
+  0x2ce331,
+  0x2cef44,
+  0x2cf7ae,
+  0x2cfbdb,
+  0x2d024c,
+  0x2d0e39,
+  0x2d16d3,
+  0x2d1aa6,
+  0x2d2707,
+  0x2d2b72,
+  0x2d3398,
+  0x2d3fed,
+  0x2d44af,
+  0x2d48da,
+  0x2d5030,
+  0x2d5c45,
+  0x2d61e4,
+  0x2d6d91,
+  0x2d757b,
+  0x2d790e,
+  0x2d83ff,
+  0x2d8f8a,
+  0x2d9760,
+  0x2d9b15,
+  0x2da6b4,
+  0x2daac1,
+  0x2db22b,
+  0x2dbe5e,
+  0x2dc51c,
+  0x2dc969,
+  0x2dd183,
+  0x2dddf6,
+  0x2de057,
+  0x2dec22,
+  0x2df4c8,
+  0x2df8bd,
+  0x2e07e6,
+  0x2e0b93,
+  0x2e1379,
+  0x2e1f0c,
+  0x2e22ad,
+  0x2e2ed8,
+  0x2e3632,
+  0x2e3a47,
+  0x2e4105,
+  0x2e4d70,
+  0x2e559a,
+  0x2e59ef,
+  0x2e644e,
+  0x2e683b,
+  0x2e70d1,
+  0x2e7ca4,
+  0x2e8655,
+  0x2e8a20,
+  0x2e92ca,
+  0x2e9ebf,
+  0x2ea31e,
+  0x2eaf6b,
+  0x2eb781,
+  0x2ebbf4,
+  0x2ec0b6,
+  0x2eccc3,
+  0x2ed429,
+  0x2ed85c,
+  0x2ee5fd,
+  0x2ee988,
+  0x2ef162,
+  0x2efd17,
+  0x2f0480,
+  0x2f08f5,
+  0x2f101f,
+  0x2f1c6a,
+  0x2f21cb,
+  0x2f2dbe,
+  0x2f3554,
+  0x2f3921,
+  0x2f4263,
+  0x2f4e16,
+  0x2f56fc,
+  0x2f5a89,
+  0x2f6728,
+  0x2f6b5d,
+  0x2f73b7,
+  0x2f7fc2,
+  0x2f8533,
+  0x2f8946,
+  0x2f91ac,
+  0x2f9dd9,
+  0x2fa078,
+  0x2fac0d,
+  0x2fb4e7,
+  0x2fb892,
+  0x2fc3d0,
+  0x2fcfa5,
+  0x2fd74f,
+  0x2fdb3a,
+  0x2fe69b,
+  0x2feaee,
+  0x2ff204,
+  0x2ffe71,
+  0x3004a9,
+  0x3008dc,
+  0x301036,
+  0x301c43,
+  0x3021e2,
+  0x302d97,
+  0x30357d,
+  0x303908,
+  0x30424a,
+  0x304e3f,
+  0x3056d5,
+  0x305aa0,
+  0x306701,
+  0x306b74,
+  0x30739e,
+  0x307feb,
+  0x30851a,
+  0x30896f,
+  0x309185,
+  0x309df0,
+  0x30a051,
+  0x30ac24,
+  0x30b4ce,
+  0x30b8bb,
+  0x30c3f9,
+  0x30cf8c,
+  0x30d766,
+  0x30db13,
+  0x30e6b2,
+  0x30eac7,
+  0x30f22d,
+  0x30fe58,
+  0x3107cf,
+  0x310bba,
+  0x311350,
+  0x311f25,
+  0x312284,
+  0x312ef1,
+  0x31361b,
+  0x313a6e,
+  0x31412c,
+  0x314d59,
+  0x3155b3,
+  0x3159c6,
+  0x316467,
+  0x316812,
+  0x3170f8,
+  0x317c8d,
+  0x31867c,
+  0x318a09,
+  0x3192e3,
+  0x319e96,
+  0x31a337,
+  0x31af42,
+  0x31b7a8,
+  0x31bbdd,
+  0x31c09f,
+  0x31ccea,
+  0x31d400,
+  0x31d875,
+  0x31e5d4,
+  0x31e9a1,
+  0x31f14b,
+  0x31fd3e,
+  0x320265,
+  0x320e10,
+  0x3216fa,
+  0x321a8f,
+  0x32272e,
+  0x322b5b,
+  0x3233b1,
+  0x323fc4,
+  0x324486,
+  0x3248f3,
+  0x325019,
+  0x325c6c,
+  0x3261cd,
+  0x326db8,
+  0x327552,
+  0x327927,
+  0x3283d6,
+  0x328fa3,
+  0x329749,
+  0x329b3c,
+  0x32a69d,
+  0x32aae8,
+  0x32b202,
+  0x32be77,
+  0x32c535,
+  0x32c940,
+  0x32d1aa,
+  0x32dddf,
+  0x32e07e,
+  0x32ec0b,
+  0x32f4e1,
+  0x32f894,
+  0x330103,
+  0x330d76,
+  0x33159c,
+  0x3319e9,
+  0x332448,
+  0x33283d,
+  0x3330d7,
+  0x333ca2,
+  0x3347e0,
+  0x334b95,
+  0x33537f,
+  0x335f0a,
+  0x3362ab,
+  0x336ede,
+  0x337634,
+  0x337a41,
+  0x3380b0,
+  0x338cc5,
+  0x33942f,
+  0x33985a,
+  0x33a5fb,
+  0x33a98e,
+  0x33b164,
+  0x33bd11,
+  0x33c653,
+  0x33ca26,
+  0x33d2cc,
+  0x33deb9,
+  0x33e318,
+  0x33ef6d,
+  0x33f787,
+  0x33fbf2,
+  0x340544,
+  0x340931,
+  0x3411db,
+  0x341dae,
+  0x34200f,
+  0x342c7a,
+  0x343490,
+  0x3438e5,
+  0x3443a7,
+  0x344fd2,
+  0x345738,
+  0x345b4d,
+  0x3466ec,
+  0x346a99,
+  0x347273,
+  0x347e06,
+  0x3484f7,
+  0x348882,
+  0x349068,
+  0x349c1d,
+  0x34a1bc,
+  0x34adc9,
+  0x34b523,
+  0x34b956,
+  0x34c214,
+  0x34ce61,
+  0x34d68b,
+  0x34dafe,
+  0x34e75f,
+  0x34eb2a,
+  0x34f3c0,
+  0x34ffb5,
+  0x350622,
+  0x350a57,
+  0x3512bd,
+  0x351ec8,
+  0x352369,
+  0x352f1c,
+  0x3537f6,
+  0x353b83,
+  0x3540c1,
+  0x354cb4,
+  0x35545e,
+  0x35582b,
+  0x35658a,
+  0x3569ff,
+  0x357115,
+  0x357d60,
+  0x358791,
+  0x358be4,
+  0x35930e,
+  0x359f7b,
+  0x35a2da,
+  0x35aeaf,
+  0x35b645,
+  0x35ba30,
+  0x35c172,
+  0x35cd07,
+  0x35d5ed,
+  0x35d998,
+  0x35e439,
+  0x35e84c,
+  0x35f0a6,
+  0x35fcd3,
+  0x360388,
+  0x360ffd,
+  0x361717,
+  0x361b62,
+  0x3626c3,
+  0x362ab6,
+  0x36325c,
+  0x363e29,
+  0x36456b,
+  0x36491e,
+  0x3651f4,
+  0x365d81,
+  0x366020,
+  0x366c55,
+  0x3674bf,
+  0x3678ca,
+  0x36823b,
+  0x368e4e,
+  0x3696a4,
+  0x369ad1,
+  0x36a770,
+  0x36ab05,
+  0x36b3ef,
+  0x36bf9a,
+  0x36c4d8,
+  0x36c8ad,
+  0x36d047,
+  0x36dc32,
+  0x36e193,
+  0x36ede6,
+  0x36f50c,
+  0x36f979,
+  0x3700ee,
+  0x370c9b,
+  0x371471,
+  0x371804,
+  0x3725a5,
+  0x3729d0,
+  0x37313a,
+  0x373d4f,
+  0x37460d,
+  0x374a78,
+  0x375292,
+  0x375ee7,
+  0x376346,
+  0x376f33,
+  0x3777d9,
+  0x377bac,
+  0x37815d,
+  0x378d28,
+  0x3795c2,
+  0x3799b7,
+  0x37a416,
+  0x37a863,
+  0x37b089,
+  0x37bcfc,
+  0x37c7be,
+  0x37cbcb,
+  0x37d321,
+  0x37df54,
+  0x37e2f5,
+  0x37ee80,
+  0x37f66a,
+  0x37fa1f,
+  0x380773,
+  0x380b06,
+  0x3813ec,
+  0x381f99,
+  0x382238,
+  0x382e4d,
+  0x3836a7,
+  0x383ad2,
+  0x384190,
+  0x384de5,
+  0x38550f,
+  0x38597a,
+  0x3864db,
+  0x3868ae,
+  0x387044,
+  0x387c31,
+  0x3886c0,
+  0x388ab5,
+  0x38925f,
+  0x389e2a,
+  0x38a38b,
+  0x38affe,
+  0x38b714,
+  0x38bb61,
+  0x38c023,
+  0x38cc56,
+  0x38d4bc,
+  0x38d8c9,
+  0x38e568,
+  0x38e91d,
+  0x38f1f7,
+  0x38fd82,
+  0x390415,
+  0x390860,
+  0x39108a,
+  0x391cff,
+  0x39215e,
+  0x392d2b,
+  0x3935c1,
+  0x3939b4,
+  0x3942f6,
+  0x394e83,
+  0x395669,
+  0x395a1c,
+  0x3967bd,
+  0x396bc8,
+  0x397322,
+  0x397f57,
+  0x3985a6,
+  0x3989d3,
+  0x399139,
+  0x399d4c,
+  0x39a0ed,
+  0x39ac98,
+  0x39b472,
+  0x39b807,
+  0x39c345,
+  0x39cf30,
+  0x39d7da,
+  0x39dbaf,
+  0x39e60e,
+  0x39ea7b,
+  0x39f291,
+  0x39fee4,
+  0x3a01bf,
+  0x3a0dca,
+  0x3a1520,
+  0x3a1955,
+  0x3a24f4,
+  0x3a2881,
+  0x3a306b,
+  0x3a3c1e,
+  0x3a475c,
+  0x3a4b29,
+  0x3a53c3,
+  0x3a5fb6,
+  0x3a6217,
+  0x3a6e62,
+  0x3a7688,
+  0x3a7afd,
+  0x3a800c,
+  0x3a8c79,
+  0x3a9493,
+  0x3a98e6,
+  0x3aa547,
+  0x3aa932,
+  0x3ab1d8,
+  0x3abdad,
+  0x3ac6ef,
+  0x3aca9a,
+  0x3ad270,
+  0x3ade05,
+  0x3ae3a4,
+  0x3aefd1,
+  0x3af73b,
+  0x3afb4e,
+  0x3b02d9,
+  0x3b0eac,
+  0x3b1646,
+  0x3b1a33,
+  0x3b2792,
+  0x3b2be7,
+  0x3b330d,
+  0x3b3f78,
+  0x3b443a,
+  0x3b484f,
+  0x3b50a5,
+  0x3b5cd0,
+  0x3b6171,
+  0x3b6d04,
+  0x3b75ee,
+  0x3b799b,
+  0x3b836a,
+  0x3b8f1f,
+  0x3b97f5,
+  0x3b9b80,
+  0x3ba621,
+  0x3baa54,
+  0x3bb2be,
+  0x3bbecb,
+  0x3bc589,
+  0x3bc9fc,
+  0x3bd116,
+  0x3bdd63,
+  0x3be0c2,
+  0x3becb7,
+  0x3bf45d,
+  0x3bf828,
+  0x3c069e,
+  0x3c0aeb,
+  0x3c1201,
+  0x3c1e74,
+  0x3c23d5,
+  0x3c2fa0,
+  0x3c374a,
+  0x3c3b3f,
+  0x3c407d,
+  0x3c4c08,
+  0x3c54e2,
+  0x3c5897,
+  0x3c6536,
+  0x3c6943,
+  0x3c71a9,
+  0x3c7ddc,
+  0x3c872d,
+  0x3c8b58,
+  0x3c93b2,
+  0x3c9fc7,
+  0x3ca266,
+  0x3cae13,
+  0x3cb6f9,
+  0x3cba8c,
+  0x3cc1ce,
+  0x3ccdbb,
+  0x3cd551,
+  0x3cd924,
+  0x3ce485,
+  0x3ce8f0,
+  0x3cf01a,
+  0x3cfc6f,
+  0x3d05f8,
+  0x3d098d,
+  0x3d1167,
+  0x3d1d12,
+  0x3d20b3,
+  0x3d2cc6,
+  0x3d342c,
+  0x3d3859,
+  0x3d431b,
+  0x3d4f6e,
+  0x3d5784,
+  0x3d5bf1,
+  0x3d6650,
+  0x3d6a25,
+  0x3d72cf,
+  0x3d7eba,
+  0x3d844b,
+  0x3d883e,
+  0x3d90d4,
+  0x3d9ca1,
+  0x3da100,
+  0x3dad75,
+  0x3db59f,
+  0x3db9ea,
+  0x3dc2a8,
+  0x3dcedd,
+  0x3dd637,
+  0x3dda42,
+  0x3de7e3,
+  0x3deb96,
+  0x3df37c,
+  0x3dff09,
+  0x3e0052,
+  0x3e0c27,
+  0x3e14cd,
+  0x3e18b8,
+  0x3e2519,
+  0x3e296c,
+  0x3e3186,
+  0x3e3df3,
+  0x3e46b1,
+  0x3e4ac4,
+  0x3e522e,
+  0x3e5e5b,
+  0x3e63fa,
+  0x3e6f8f,
+  0x3e7765,
+  0x3e7b10,
+  0x3e81e1,
+  0x3e8d94,
+  0x3e957e,
+  0x3e990b,
+  0x3ea4aa,
+  0x3ea8df,
+  0x3eb035,
+  0x3ebc40,
+  0x3ec702,
+  0x3ecb77,
+  0x3ed39d,
+  0x3edfe8,
+  0x3ee249,
+  0x3eee3c,
+  0x3ef6d6,
+  0x3efaa3,
+  0x3f0334,
+  0x3f0f41,
+  0x3f17ab,
+  0x3f1bde,
+  0x3f267f,
+  0x3f2a0a,
+  0x3f32e0,
+  0x3f3e95,
+  0x3f45d7,
+  0x3f49a2,
+  0x3f5148,
+  0x3f5d3d,
+  0x3f609c,
+  0x3f6ce9,
+  0x3f7403,
+  0x3f7876,
+  0x3f8287,
+  0x3f8ef2,
+  0x3f9618,
+  0x3f9a6d,
+  0x3fa7cc,
+  0x3fabb9,
+  0x3fb353,
+  0x3fbf26,
+  0x3fc464,
+  0x3fc811,
+  0x3fd0fb,
+  0x3fdc8e,
+  0x3fe12f,
+  0x3fed5a,
+  0x3ff5b0,
+  0x3ff9c5,
+  0x40063a,
+  0x400a4f,
+  0x4012a5,
+  0x401ed0,
+  0x402371,
+  0x402f04,
+  0x4037ee,
+  0x403b9b,
+  0x4040d9,
+  0x404cac,
+  0x405446,
+  0x405833,
+  0x406592,
+  0x4069e7,
+  0x40710d,
+  0x407d78,
+  0x408789,
+  0x408bfc,
+  0x409316,
+  0x409f63,
+  0x40a2c2,
+  0x40aeb7,
+  0x40b65d,
+  0x40ba28,
+  0x40c16a,
+  0x40cd1f,
+  0x40d5f5,
+  0x40d980,
+  0x40e421,
+  0x40e854,
+  0x40f0be,
+  0x40fccb,
+  0x41055c,
+  0x410929,
+  0x4111c3,
+  0x411db6,
+  0x412017,
+  0x412c62,
+  0x413488,
+  0x4138fd,
+  0x4143bf,
+  0x414fca,
+  0x415720,
+  0x415b55,
+  0x4166f4,
+  0x416a81,
+  0x41726b,
+  0x417e1e,
+  0x4184ef,
+  0x41889a,
+  0x419070,
+  0x419c05,
+  0x41a1a4,
+  0x41add1,
+  0x41b53b,
+  0x41b94e,
+  0x41c20c,
+  0x41ce79,
+  0x41d693,
+  0x41dae6,
+  0x41e747,
+  0x41eb32,
+  0x41f3d8,
+  0x41ffad,
+  0x4200f6,
+  0x420c83,
+  0x421469,
+  0x42181c,
+  0x4225bd,
+  0x4229c8,
+  0x423122,
+  0x423d57,
+  0x424615,
+  0x424a60,
+  0x42528a,
+  0x425eff,
+  0x42635e,
+  0x426f2b,
+  0x4277c1,
+  0x427bb4,
+  0x428145,
+  0x428d30,
+  0x4295da,
+  0x4299af,
+  0x42a40e,
+  0x42a87b,
+  0x42b091,
+  0x42bce4,
+  0x42c7a6,
+  0x42cbd3,
+  0x42d339,
+  0x42df4c,
+  0x42e2ed,
+  0x42ee98,
+  0x42f672,
+  0x42fa07,
+  0x430390,
+  0x430fe5,
+  0x43170f,
+  0x431b7a,
+  0x4326db,
+  0x432aae,
+  0x433244,
+  0x433e31,
+  0x434573,
+  0x434906,
+  0x4351ec,
+  0x435d99,
+  0x436038,
+  0x436c4d,
+  0x4374a7,
+  0x4378d2,
+  0x438223,
+  0x438e56,
+  0x4396bc,
+  0x439ac9,
+  0x43a768,
+  0x43ab1d,
+  0x43b3f7,
+  0x43bf82,
+  0x43c4c0,
+  0x43c8b5,
+  0x43d05f,
+  0x43dc2a,
+  0x43e18b,
+  0x43edfe,
+  0x43f514,
+  0x43f961,
+  0x4407d7,
+  0x440ba2,
+  0x441348,
+  0x441f3d,
+  0x44229c,
+  0x442ee9,
+  0x443603,
+  0x443a76,
+  0x444134,
+  0x444d41,
+  0x4455ab,
+  0x4459de,
+  0x44647f,
+  0x44680a,
+  0x4470e0,
+  0x447c95,
+  0x448664,
+  0x448a11,
+  0x4492fb,
+  0x449e8e,
+  0x44a32f,
+  0x44af5a,
+  0x44b7b0,
+  0x44bbc5,
+  0x44c087,
+  0x44ccf2,
+  0x44d418,
+  0x44d86d,
+  0x44e5cc,
+  0x44e9b9,
+  0x44f153,
+  0x44fd26,
+  0x4504b1,
+  0x4508c4,
+  0x45102e,
+  0x451c5b,
+  0x4521fa,
+  0x452d8f,
+  0x453565,
+  0x453910,
+  0x454252,
+  0x454e27,
+  0x4556cd,
+  0x455ab8,
+  0x456719,
+  0x456b6c,
+  0x457386,
+  0x457ff3,
+  0x458502,
+  0x458977,
+  0x45919d,
+  0x459de8,
+  0x45a049,
+  0x45ac3c,
+  0x45b4d6,
+  0x45b8a3,
+  0x45c3e1,
+  0x45cf94,
+  0x45d77e,
+  0x45db0b,
+  0x45e6aa,
+  0x45eadf,
+  0x45f235,
+  0x45fe40,
+  0x46011b,
+  0x460d6e,
+  0x461584,
+  0x4619f1,
+  0x462450,
+  0x462825,
+  0x4630cf,
+  0x463cba,
+  0x4647f8,
+  0x464b8d,
+  0x465367,
+  0x465f12,
+  0x4662b3,
+  0x466ec6,
+  0x46762c,
+  0x467a59,
+  0x4680a8,
+  0x468cdd,
+  0x469437,
+  0x469842,
+  0x46a5e3,
+  0x46a996,
+  0x46b17c,
+  0x46bd09,
+  0x46c64b,
+  0x46ca3e,
+  0x46d2d4,
+  0x46dea1,
+  0x46e300,
+  0x46ef75,
+  0x46f79f,
+  0x46fbea,
+  0x47027d,
+  0x470e08,
+  0x4716e2,
+  0x471a97,
+  0x472736,
+  0x472b43,
+  0x4733a9,
+  0x473fdc,
+  0x47449e,
+  0x4748eb,
+  0x475001,
+  0x475c74,
+  0x4761d5,
+  0x476da0,
+  0x47754a,
+  0x47793f,
+  0x4783ce,
+  0x478fbb,
+  0x479751,
+  0x479b24,
+  0x47a685,
+  0x47aaf0,
+  0x47b21a,
+  0x47be6f,
+  0x47c52d,
+  0x47c958,
+  0x47d1b2,
+  0x47ddc7,
+  0x47e066,
+  0x47ec13,
+  0x47f4f9,
+  0x47f88c,
+  0x4805e0,
+  0x480995,
+  0x48117f,
+  0x481d0a,
+  0x4820ab,
+  0x482cde,
+  0x483434,
+  0x483841,
+  0x484303,
+  0x484f76,
+  0x48579c,
+  0x485be9,
+  0x486648,
+  0x486a3d,
+  0x4872d7,
+  0x487ea2,
+  0x488453,
+  0x488826,
+  0x4890cc,
+  0x489cb9,
+  0x48a118,
+  0x48ad6d,
+  0x48b587,
+  0x48b9f2,
+  0x48c2b0,
+  0x48cec5,
+  0x48d62f,
+  0x48da5a,
+  0x48e7fb,
+  0x48eb8e,
+  0x48f364,
+  0x48ff11,
+  0x490686,
+  0x490af3,
+  0x491219,
+  0x491e6c,
+  0x4923cd,
+  0x492fb8,
+  0x493752,
+  0x493b27,
+  0x494065,
+  0x494c10,
+  0x4954fa,
+  0x49588f,
+  0x49652e,
+  0x49695b,
+  0x4971b1,
+  0x497dc4,
+  0x498735,
+  0x498b40,
+  0x4993aa,
+  0x499fdf,
+  0x49a27e,
+  0x49ae0b,
+  0x49b6e1,
+  0x49ba94,
+  0x49c1d6,
+  0x49cda3,
+  0x49d549,
+  0x49d93c,
+  0x49e49d,
+  0x49e8e8,
+  0x49f002,
+  0x49fc77,
+  0x4a032c,
+  0x4a0f59,
+  0x4a17b3,
+  0x4a1bc6,
+  0x4a2667,
+  0x4a2a12,
+  0x4a32f8,
+  0x4a3e8d,
+  0x4a45cf,
+  0x4a49ba,
+  0x4a5150,
+  0x4a5d25,
+  0x4a6084,
+  0x4a6cf1,
+  0x4a741b,
+  0x4a786e,
+  0x4a829f,
+  0x4a8eea,
+  0x4a9600,
+  0x4a9a75,
+  0x4aa7d4,
+  0x4aaba1,
+  0x4ab34b,
+  0x4abf3e,
+  0x4ac47c,
+  0x4ac809,
+  0x4ad0e3,
+  0x4adc96,
+  0x4ae137,
+  0x4aed42,
+  0x4af5a8,
+  0x4af9dd,
+  0x4b004a,
+  0x4b0c3f,
+  0x4b14d5,
+  0x4b18a0,
+  0x4b2501,
+  0x4b2974,
+  0x4b319e,
+  0x4b3deb,
+  0x4b46a9,
+  0x4b4adc,
+  0x4b5236,
+  0x4b5e43,
+  0x4b63e2,
+  0x4b6f97,
+  0x4b777d,
+  0x4b7b08,
+  0x4b81f9,
+  0x4b8d8c,
+  0x4b9566,
+  0x4b9913,
+  0x4ba4b2,
+  0x4ba8c7,
+  0x4bb02d,
+  0x4bbc58,
+  0x4bc71a,
+  0x4bcb6f,
+  0x4bd385,
+  0x4bdff0,
+  0x4be251,
+  0x4bee24,
+  0x4bf6ce,
+  0x4bfabb,
+  0x4c040d,
+  0x4c0878,
+  0x4c1092,
+  0x4c1ce7,
+  0x4c2146,
+  0x4c2d33,
+  0x4c35d9,
+  0x4c39ac,
+  0x4c42ee,
+  0x4c4e9b,
+  0x4c5671,
+  0x4c5a04,
+  0x4c67a5,
+  0x4c6bd0,
+  0x4c733a,
+  0x4c7f4f,
+  0x4c85be,
+  0x4c89cb,
+  0x4c9121,
+  0x4c9d54,
+  0x4ca0f5,
+  0x4cac80,
+  0x4cb46a,
+  0x4cb81f,
+  0x4cc35d,
+  0x4ccf28,
+  0x4cd7c2,
+  0x4cdbb7,
+  0x4ce616,
+  0x4cea63,
+  0x4cf289,
+  0x4cfefc,
+  0x4d076b,
+  0x4d0b1e,
+  0x4d13f4,
+  0x4d1f81,
+  0x4d2220,
+  0x4d2e55,
+  0x4d36bf,
+  0x4d3aca,
+  0x4d4188,
+  0x4d4dfd,
+  0x4d5517,
+  0x4d5962,
+  0x4d64c3,
+  0x4d68b6,
+  0x4d705c,
+  0x4d7c29,
+  0x4d86d8,
+  0x4d8aad,
+  0x4d9247,
+  0x4d9e32,
+  0x4da393,
+  0x4dafe6,
+  0x4db70c,
+  0x4dbb79,
+  0x4dc03b,
+  0x4dcc4e,
+  0x4dd4a4,
+  0x4dd8d1,
+  0x4de570,
+  0x4de905,
+  0x4df1ef,
+  0x4dfd9a,
+  0x4e02c1,
+  0x4e0eb4,
+  0x4e165e,
+  0x4e1a2b,
+  0x4e278a,
+  0x4e2bff,
+  0x4e3315,
+  0x4e3f60,
+  0x4e4422,
+  0x4e4857,
+  0x4e50bd,
+  0x4e5cc8,
+  0x4e6169,
+  0x4e6d1c,
+  0x4e75f6,
+  0x4e7983,
+  0x4e8372,
+  0x4e8f07,
+  0x4e97ed,
+  0x4e9b98,
+  0x4ea639,
+  0x4eaa4c,
+  0x4eb2a6,
+  0x4ebed3,
+  0x4ec591,
+  0x4ec9e4,
+  0x4ed10e,
+  0x4edd7b,
+  0x4ee0da,
+  0x4eecaf,
+  0x4ef445,
+  0x4ef830,
+  0x4f01a7,
+  0x4f0dd2,
+  0x4f1538,
+  0x4f194d,
+  0x4f24ec,
+  0x4f2899,
+  0x4f3073,
+  0x4f3c06,
+  0x4f4744,
+  0x4f4b31,
+  0x4f53db,
+  0x4f5fae,
+  0x4f620f,
+  0x4f6e7a,
+  0x4f7690,
+  0x4f7ae5,
+  0x4f8014,
+  0x4f8c61,
+  0x4f948b,
+  0x4f98fe,
+  0x4fa55f,
+  0x4fa92a,
+  0x4fb1c0,
+  0x4fbdb5,
+  0x4fc6f7,
+  0x4fca82,
+  0x4fd268,
+  0x4fde1d,
+  0x4fe3bc,
+  0x4fefc9,
+  0x4ff723,
+  0x4ffb56,
+  0x50018e,
+  0x500dfb,
+  0x501511,
+  0x501964,
+  0x5024c5,
+  0x5028b0,
+  0x50305a,
+  0x503c2f,
+  0x50476d,
+  0x504b18,
+  0x5053f2,
+  0x505f87,
+  0x506226,
+  0x506e53,
+  0x5076b9,
+  0x507acc,
+  0x50803d,
+  0x508c48,
+  0x5094a2,
+  0x5098d7,
+  0x50a576,
+  0x50a903,
+  0x50b1e9,
+  0x50bd9c,
+  0x50c6de,
+  0x50caab,
+  0x50d241,
+  0x50de34,
+  0x50e395,
+  0x50efe0,
+  0x50f70a,
+  0x50fb7f,
+  0x5102e8,
+  0x510e9d,
+  0x511677,
+  0x511a02,
+  0x5127a3,
+  0x512bd6,
+  0x51333c,
+  0x513f49,
+  0x51440b,
+  0x51487e,
+  0x515094,
+  0x515ce1,
+  0x516140,
+  0x516d35,
+  0x5175df,
+  0x5179aa,
+  0x51835b,
+  0x518f2e,
+  0x5197c4,
+  0x519bb1,
+  0x51a610,
+  0x51aa65,
+  0x51b28f,
+  0x51befa,
+  0x51c5b8,
+  0x51c9cd,
+  0x51d127,
+  0x51dd52,
+  0x51e0f3,
+  0x51ec86,
+  0x51f46c,
+  0x51f819,
+  0x520742,
+  0x520b37,
+  0x5213dd,
+  0x521fa8,
+  0x522209,
+  0x522e7c,
+  0x523696,
+  0x523ae3,
+  0x5241a1,
+  0x524dd4,
+  0x52553e,
+  0x52594b,
+  0x5264ea,
+  0x52689f,
+  0x527075,
+  0x527c00,
+  0x5286f1,
+  0x528a84,
+  0x52926e,
+  0x529e1b,
+  0x52a3ba,
+  0x52afcf,
+  0x52b725,
+  0x52bb50,
+  0x52c012,
+  0x52cc67,
+  0x52d48d,
+  0x52d8f8,
+  0x52e559,
+  0x52e92c,
+  0x52f1c6,
+  0x52fdb3,
+  0x530424,
+  0x530851,
+  0x5310bb,
+  0x531cce,
+  0x53216f,
+  0x532d1a,
+  0x5335f0,
+  0x533985,
+  0x5342c7,
+  0x534eb2,
+  0x535658,
+  0x535a2d,
+  0x53678c,
+  0x536bf9,
+  0x537313,
+  0x537f66,
+  0x538597,
+  0x5389e2,
+  0x539108,
+  0x539d7d,
+  0x53a0dc,
+  0x53aca9,
+  0x53b443,
+  0x53b836,
+  0x53c374,
+  0x53cf01,
+  0x53d7eb,
+  0x53db9e,
+  0x53e63f,
+  0x53ea4a,
+  0x53f2a0,
+  0x53fed5,
+  0x540063,
+  0x540c16,
+  0x5414fc,
+  0x541889,
+  0x542528,
+  0x54295d,
+  0x5431b7,
+  0x543dc2,
+  0x544680,
+  0x544af5,
+  0x54521f,
+  0x545e6a,
+  0x5463cb,
+  0x546fbe,
+  0x547754,
+  0x547b21,
+  0x5481d0,
+  0x548da5,
+  0x54954f,
+  0x54993a,
+  0x54a49b,
+  0x54a8ee,
+  0x54b004,
+  0x54bc71,
+  0x54c733,
+  0x54cb46,
+  0x54d3ac,
+  0x54dfd9,
+  0x54e278,
+  0x54ee0d,
+  0x54f6e7,
+  0x54fa92,
+  0x550305,
+  0x550f70,
+  0x55179a,
+  0x551bef,
+  0x55264e,
+  0x552a3b,
+  0x5532d1,
+  0x553ea4,
+  0x5545e6,
+  0x554993,
+  0x555179,
+  0x555d0c,
+  0x5560ad,
+  0x556cd8,
+  0x557432,
+  0x557847,
+  0x5582b6,
+  0x558ec3,
+  0x559629,
+  0x559a5c,
+  0x55a7fd,
+  0x55ab88,
+  0x55b362,
+  0x55bf17,
+  0x55c455,
+  0x55c820,
+  0x55d0ca,
+  0x55dcbf,
+  0x55e11e,
+  0x55ed6b,
+  0x55f581,
+  0x55f9f4,
+  0x5606af,
+  0x560ada,
+  0x561230,
+  0x561e45,
+  0x5623e4,
+  0x562f91,
+  0x56377b,
+  0x563b0e,
+  0x56404c,
+  0x564c39,
+  0x5654d3,
+  0x5658a6,
+  0x566507,
+  0x566972,
+  0x567198,
+  0x567ded,
+  0x56871c,
+  0x568b69,
+  0x569383,
+  0x569ff6,
+  0x56a257,
+  0x56ae22,
+  0x56b6c8,
+  0x56babd,
+  0x56c1ff,
+  0x56cd8a,
+  0x56d560,
+  0x56d915,
+  0x56e4b4,
+  0x56e8c1,
+  0x56f02b,
+  0x56fc5e,
+  0x5705c9,
+  0x5709bc,
+  0x571156,
+  0x571d23,
+  0x572082,
+  0x572cf7,
+  0x57341d,
+  0x573868,
+  0x57432a,
+  0x574f5f,
+  0x5757b5,
+  0x575bc0,
+  0x576661,
+  0x576a14,
+  0x5772fe,
+  0x577e8b,
+  0x57847a,
+  0x57880f,
+  0x5790e5,
+  0x579c90,
+  0x57a131,
+  0x57ad44,
+  0x57b5ae,
+  0x57b9db,
+  0x57c299,
+  0x57ceec,
+  0x57d606,
+  0x57da73,
+  0x57e7d2,
+  0x57eba7,
+  0x57f34d,
+  0x57ff38,
+  0x580254,
+  0x580e21,
+  0x5816cb,
+  0x581abe,
+  0x58271f,
+  0x582b6a,
+  0x583380,
+  0x583ff5,
+  0x5844b7,
+  0x5848c2,
+  0x585028,
+  0x585c5d,
+  0x5861fc,
+  0x586d89,
+  0x587563,
+  0x587916,
+  0x5883e7,
+  0x588f92,
+  0x589778,
+  0x589b0d,
+  0x58a6ac,
+  0x58aad9,
+  0x58b233,
+  0x58be46,
+  0x58c504,
+  0x58c971,
+  0x58d19b,
+  0x58ddee,
+  0x58e04f,
+  0x58ec3a,
+  0x58f4d0,
+  0x58f8a5,
+  0x590132,
+  0x590d47,
+  0x5915ad,
+  0x5919d8,
+  0x592479,
+  0x59280c,
+  0x5930e6,
+  0x593c93,
+  0x5947d1,
+  0x594ba4,
+  0x59534e,
+  0x595f3b,
+  0x59629a,
+  0x596eef,
+  0x597605,
+  0x597a70,
+  0x598081,
+  0x598cf4,
+  0x59941e,
+  0x59986b,
+  0x59a5ca,
+  0x59a9bf,
+  0x59b155,
+  0x59bd20,
+  0x59c662,
+  0x59ca17,
+  0x59d2fd,
+  0x59de88,
+  0x59e329,
+  0x59ef5c,
+  0x59f7b6,
+  0x59fbc3,
+  0x5a0498,
+  0x5a08ed,
+  0x5a1007,
+  0x5a1c72,
+  0x5a21d3,
+  0x5a2da6,
+  0x5a354c,
+  0x5a3939,
+  0x5a427b,
+  0x5a4e0e,
+  0x5a56e4,
+  0x5a5a91,
+  0x5a6730,
+  0x5a6b45,
+  0x5a73af,
+  0x5a7fda,
+  0x5a852b,
+  0x5a895e,
+  0x5a91b4,
+  0x5a9dc1,
+  0x5aa060,
+  0x5aac15,
+  0x5ab4ff,
+  0x5ab88a,
+  0x5ac3c8,
+  0x5acfbd,
+  0x5ad757,
+  0x5adb22,
+  0x5ae683,
+  0x5aeaf6,
+  0x5af21c,
+  0x5afe69,
+  0x5b07fe,
+  0x5b0b8b,
+  0x5b1361,
+  0x5b1f14,
+  0x5b22b5,
+  0x5b2ec0,
+  0x5b362a,
+  0x5b3a5f,
+  0x5b411d,
+  0x5b4d68,
+  0x5b5582,
+  0x5b59f7,
+  0x5b6456,
+  0x5b6823,
+  0x5b70c9,
+  0x5b7cbc,
+  0x5b864d,
+  0x5b8a38,
+  0x5b92d2,
+  0x5b9ea7,
+  0x5ba306,
+  0x5baf73,
+  0x5bb799,
+  0x5bbbec,
+  0x5bc0ae,
+  0x5bccdb,
+  0x5bd431,
+  0x5bd844,
+  0x5be5e5,
+  0x5be990,
+  0x5bf17a,
+  0x5bfd0f,
+  0x5c03b9,
+  0x5c0fcc,
+  0x5c1726,
+  0x5c1b53,
+  0x5c26f2,
+  0x5c2a87,
+  0x5c326d,
+  0x5c3e18,
+  0x5c455a,
+  0x5c492f,
+  0x5c51c5,
+  0x5c5db0,
+  0x5c6011,
+  0x5c6c64,
+  0x5c748e,
+  0x5c78fb,
+  0x5c820a,
+  0x5c8e7f,
+  0x5c9695,
+  0x5c9ae0,
+  0x5ca741,
+  0x5cab34,
+  0x5cb3de,
+  0x5cbfab,
+  0x5cc4e9,
+  0x5cc89c,
+  0x5cd076,
+  0x5cdc03,
+  0x5ce1a2,
+  0x5cedd7,
+  0x5cf53d,
+  0x5cf948,
+  0x5d00df,
+  0x5d0caa,
+  0x5d1440,
+  0x5d1835,
+  0x5d2594,
+  0x5d29e1,
+  0x5d310b,
+  0x5d3d7e,
+  0x5d463c,
+  0x5d4a49,
+  0x5d52a3,
+  0x5d5ed6,
+  0x5d6377,
+  0x5d6f02,
+  0x5d77e8,
+  0x5d7b9d,
+  0x5d816c,
+  0x5d8d19,
+  0x5d95f3,
+  0x5d9986,
+  0x5da427,
+  0x5da852,
+  0x5db0b8,
+  0x5dbccd,
+  0x5dc78f,
+  0x5dcbfa,
+  0x5dd310,
+  0x5ddf65,
+  0x5de2c4,
+  0x5deeb1,
+  0x5df65b,
+  0x5dfa2e,
+  0x5e0575,
+  0x5e0900,
+  0x5e11ea,
+  0x5e1d9f,
+  0x5e203e,
+  0x5e2c4b,
+  0x5e34a1,
+  0x5e38d4,
+  0x5e4396,
+  0x5e4fe3,
+  0x5e5709,
+  0x5e5b7c,
+  0x5e66dd,
+  0x5e6aa8,
+  0x5e7242,
+  0x5e7e37,
+  0x5e84c6,
+  0x5e88b3,
+  0x5e9059,
+  0x5e9c2c,
+  0x5ea18d,
+  0x5eadf8,
+  0x5eb512,
+  0x5eb967,
+  0x5ec225,
+  0x5ece50,
+  0x5ed6ba,
+  0x5edacf,
+  0x5ee76e,
+  0x5eeb1b,
+  0x5ef3f1,
+  0x5eff84,
+  0x5f0613,
+  0x5f0a66,
+  0x5f128c,
+  0x5f1ef9,
+  0x5f2358,
+  0x5f2f2d,
+  0x5f37c7,
+  0x5f3bb2,
+  0x5f40f0,
+  0x5f4c85,
+  0x5f546f,
+  0x5f581a,
+  0x5f65bb,
+  0x5f69ce,
+  0x5f7124,
+  0x5f7d51,
+  0x5f87a0,
+  0x5f8bd5,
+  0x5f933f,
+  0x5f9f4a,
+  0x5fa2eb,
+  0x5fae9e,
+  0x5fb674,
+  0x5fba01,
+  0x5fc143,
+  0x5fcd36,
+  0x5fd5dc,
+  0x5fd9a9,
+  0x5fe408,
+  0x5fe87d,
+  0x5ff097,
+  0x5ffce2,
+  0x600527,
+  0x600952,
+  0x6011b8,
+  0x601dcd,
+  0x60206c,
+  0x602c19,
+  0x6034f3,
+  0x603886,
+  0x6043c4,
+  0x604fb1,
+  0x60575b,
+  0x605b2e,
+  0x60668f,
+  0x606afa,
+  0x607210,
+  0x607e65,
+  0x608494,
+  0x6088e1,
+  0x60900b,
+  0x609c7e,
+  0x60a1df,
+  0x60adaa,
+  0x60b540,
+  0x60b935,
+  0x60c277,
+  0x60ce02,
+  0x60d6e8,
+  0x60da9d,
+  0x60e73c,
+  0x60eb49,
+  0x60f3a3,
+  0x60ffd6,
+  0x610641,
+  0x610a34,
+  0x6112de,
+  0x611eab,
+  0x61230a,
+  0x612f7f,
+  0x613795,
+  0x613be0,
+  0x6140a2,
+  0x614cd7,
+  0x61543d,
+  0x615848,
+  0x6165e9,
+  0x61699c,
+  0x617176,
+  0x617d03,
+  0x6187f2,
+  0x618b87,
+  0x61936d,
+  0x619f18,
+  0x61a2b9,
+  0x61aecc,
+  0x61b626,
+  0x61ba53,
+  0x61c111,
+  0x61cd64,
+  0x61d58e,
+  0x61d9fb,
+  0x61e45a,
+  0x61e82f,
+  0x61f0c5,
+  0x61fcb0,
+  0x6203eb,
+  0x620f9e,
+  0x621774,
+  0x621b01,
+  0x6226a0,
+  0x622ad5,
+  0x62323f,
+  0x623e4a,
+  0x624508,
+  0x62497d,
+  0x625197,
+  0x625de2,
+  0x626043,
+  0x626c36,
+  0x6274dc,
+  0x6278a9,
+  0x628258,
+  0x628e2d,
+  0x6296c7,
+  0x629ab2,
+  0x62a713,
+  0x62ab66,
+  0x62b38c,
+  0x62bff9,
+  0x62c4bb,
+  0x62c8ce,
+  0x62d024,
+  0x62dc51,
+  0x62e1f0,
+  0x62ed85,
+  0x62f56f,
+  0x62f91a,
+  0x63008d,
+  0x630cf8,
+  0x631412,
+  0x631867,
+  0x6325c6,
+  0x6329b3,
+  0x633159,
+  0x633d2c,
+  0x63466e,
+  0x634a1b,
+  0x6352f1,
+  0x635e84,
+  0x636325,
+  0x636f50,
+  0x6377ba,
+  0x637bcf,
+  0x63813e,
+  0x638d4b,
+  0x6395a1,
+  0x6399d4,
+  0x63a475,
+  0x63a800,
+  0x63b0ea,
+  0x63bc9f,
+  0x63c7dd,
+  0x63cba8,
+  0x63d342,
+  0x63df37,
+  0x63e296,
+  0x63eee3,
+  0x63f609,
+  0x63fa7c,
+  0x6404ca,
+  0x6408bf,
+  0x641055,
+  0x641c20,
+  0x642181,
+  0x642df4,
+  0x64351e,
+  0x64396b,
+  0x644229,
+  0x644e5c,
+  0x6456b6,
+  0x645ac3,
+  0x646762,
+  0x646b17,
+  0x6473fd,
+  0x647f88,
+  0x648579,
+  0x64890c,
+  0x6491e6,
+  0x649d93,
+  0x64a032,
+  0x64ac47,
+  0x64b4ad,
+  0x64b8d8,
+  0x64c39a,
+  0x64cfef,
+  0x64d705,
+  0x64db70,
+  0x64e6d1,
+  0x64eaa4,
+  0x64f24e,
+  0x64fe3b,
+  0x6507ac,
+  0x650bd9,
+  0x651333,
+  0x651f46,
+  0x6522e7,
+  0x652e92,
+  0x653678,
+  0x653a0d,
+  0x65414f,
+  0x654d3a,
+  0x6555d0,
+  0x6559a5,
+  0x656404,
+  0x656871,
+  0x65709b,
+  0x657cee,
+  0x65861f,
+  0x658a6a,
+  0x659280,
+  0x659ef5,
+  0x65a354,
+  0x65af21,
+  0x65b7cb,
+  0x65bbbe,
+  0x65c0fc,
+  0x65cc89,
+  0x65d463,
+  0x65d816,
+  0x65e5b7,
+  0x65e9c2,
+  0x65f128,
+  0x65fd5d,
+  0x660206,
+  0x660e73,
+  0x661699,
+  0x661aec,
+  0x66274d,
+  0x662b38,
+  0x6633d2,
+  0x663fa7,
+  0x6644e5,
+  0x664890,
+  0x66507a,
+  0x665c0f,
+  0x6661ae,
+  0x666ddb,
+  0x667531,
+  0x667944,
+  0x6683b5,
+  0x668fc0,
+  0x66972a,
+  0x669b5f,
+  0x66a6fe,
+  0x66aa8b,
+  0x66b261,
+  0x66be14,
+  0x66c556,
+  0x66c923,
+  0x66d1c9,
+  0x66ddbc,
+  0x66e01d,
+  0x66ec68,
+  0x66f482,
+  0x66f8f7,
+  0x670160,
+  0x670d15,
+  0x6715ff,
+  0x67198a,
+  0x67242b,
+  0x67285e,
+  0x6730b4,
+  0x673cc1,
+  0x674783,
+  0x674bf6,
+  0x67531c,
+  0x675f69,
+  0x6762c8,
+  0x676ebd,
+  0x677657,
+  0x677a22,
+  0x6780d3,
+  0x678ca6,
+  0x67944c,
+  0x679839,
+  0x67a598,
+  0x67a9ed,
+  0x67b107,
+  0x67bd72,
+  0x67c630,
+  0x67ca45,
+  0x67d2af,
+  0x67deda,
+  0x67e37b,
+  0x67ef0e,
+  0x67f7e4,
+  0x67fb91,
+  0x6806fd,
+  0x680a88,
+  0x681262,
+  0x681e17,
+  0x6823b6,
+  0x682fc3,
+  0x683729,
+  0x683b5c,
+  0x68401e,
+  0x684c6b,
+  0x685481,
+  0x6858f4,
+  0x686555,
+  0x686920,
+  0x6871ca,
+  0x687dbf,
+  0x68874e,
+  0x688b3b,
+  0x6893d1,
+  0x689fa4,
+  0x68a205,
+  0x68ae70,
+  0x68b69a,
+  0x68baef,
+  0x68c1ad,
+  0x68cdd8,
+  0x68d532,
+  0x68d947,
+  0x68e4e6,
+  0x68e893,
+  0x68f079,
+  0x68fc0c,
+  0x69059b,
+  0x6909ee,
+  0x691104,
+  0x691d71,
+  0x6920d0,
+  0x692ca5,
+  0x69344f,
+  0x69383a,
+  0x694378,
+  0x694f0d,
+  0x6957e7,
+  0x695b92,
+  0x696633,
+  0x696a46,
+  0x6972ac,
+  0x697ed9,
+  0x698428,
+  0x69885d,
+  0x6990b7,
+  0x699cc2,
+  0x69a163,
+  0x69ad16,
+  0x69b5fc,
+  0x69b989,
+  0x69c2cb,
+  0x69cebe,
+  0x69d654,
+  0x69da21,
+  0x69e780,
+  0x69ebf5,
+  0x69f31f,
+  0x69ff6a,
+  0x6a0031,
+  0x6a0c44,
+  0x6a14ae,
+  0x6a18db,
+  0x6a257a,
+  0x6a290f,
+  0x6a31e5,
+  0x6a3d90,
+  0x6a46d2,
+  0x6a4aa7,
+  0x6a524d,
+  0x6a5e38,
+  0x6a6399,
+  0x6a6fec,
+  0x6a7706,
+  0x6a7b73,
+  0x6a8182,
+  0x6a8df7,
+  0x6a951d,
+  0x6a9968,
+  0x6aa4c9,
+  0x6aa8bc,
+  0x6ab056,
+  0x6abc23,
+  0x6ac761,
+  0x6acb14,
+  0x6ad3fe,
+  0x6adf8b,
+  0x6ae22a,
+  0x6aee5f,
+  0x6af6b5,
+  0x6afac0,
+  0x6b0357,
+  0x6b0f22,
+  0x6b17c8,
+  0x6b1bbd,
+  0x6b261c,
+  0x6b2a69,
+  0x6b3283,
+  0x6b3ef6,
+  0x6b45b4,
+  0x6b49c1,
+  0x6b512b,
+  0x6b5d5e,
+  0x6b60ff,
+  0x6b6c8a,
+  0x6b7460,
+  0x6b7815,
+  0x6b82e4,
+  0x6b8e91,
+  0x6b967b,
+  0x6b9a0e,
+  0x6ba7af,
+  0x6babda,
+  0x6bb330,
+  0x6bbf45,
+  0x6bc407,
+  0x6bc872,
+  0x6bd098,
+  0x6bdced,
+  0x6be14c,
+  0x6bed39,
+  0x6bf5d3,
+  0x6bf9a6,
+  0x6c0710,
+  0x6c0b65,
+  0x6c138f,
+  0x6c1ffa,
+  0x6c225b,
+  0x6c2e2e,
+  0x6c36c4,
+  0x6c3ab1,
+  0x6c41f3,
+  0x6c4d86,
+  0x6c556c,
+  0x6c5919,
+  0x6c64b8,
+  0x6c68cd,
+  0x6c7027,
+  0x6c7c52,
+  0x6c86a3,
+  0x6c8ad6,
+  0x6c923c,
+  0x6c9e49,
+  0x6ca3e8,
+  0x6caf9d,
+  0x6cb777,
+  0x6cbb02,
+  0x6cc040,
+  0x6ccc35,
+  0x6cd4df,
+  0x6cd8aa,
+  0x6ce50b,
+  0x6ce97e,
+  0x6cf194,
+  0x6cfde1,
+  0x6d0476,
+  0x6d0803,
+  0x6d10e9,
+  0x6d1c9c,
+  0x6d213d,
+  0x6d2d48,
+  0x6d35a2,
+  0x6d39d7,
+  0x6d4295,
+  0x6d4ee0,
+  0x6d560a,
+  0x6d5a7f,
+  0x6d67de,
+  0x6d6bab,
+  0x6d7341,
+  0x6d7f34,
+  0x6d85c5,
+  0x6d89b0,
+  0x6d915a,
+  0x6d9d2f,
+  0x6da08e,
+  0x6dacfb,
+  0x6db411,
+  0x6db864,
+  0x6dc326,
+  0x6dcf53,
+  0x6dd7b9,
+  0x6ddbcc,
+  0x6de66d,
+  0x6dea18,
+  0x6df2f2,
+  0x6dfe87,
+  0x6e01dc,
+  0x6e0da9,
+  0x6e1543,
+  0x6e1936,
+  0x6e2497,
+  0x6e28e2,
+  0x6e3008,
+  0x6e3c7d,
+  0x6e473f,
+  0x6e4b4a,
+  0x6e53a0,
+  0x6e5fd5,
+  0x6e6274,
+  0x6e6e01,
+  0x6e76eb,
+  0x6e7a9e,
+  0x6e806f,
+  0x6e8c1a,
+  0x6e94f0,
+  0x6e9885,
+  0x6ea524,
+  0x6ea951,
+  0x6eb1bb,
+  0x6ebdce,
+  0x6ec68c,
+  0x6ecaf9,
+  0x6ed213,
+  0x6ede66,
+  0x6ee3c7,
+  0x6eefb2,
+  0x6ef758,
+  0x6efb2d,
+  0x6f02ba,
+  0x6f0ecf,
+  0x6f1625,
+  0x6f1a50,
+  0x6f27f1,
+  0x6f2b84,
+  0x6f336e,
+  0x6f3f1b,
+  0x6f4459,
+  0x6f482c,
+  0x6f50c6,
+  0x6f5cb3,
+  0x6f6112,
+  0x6f6d67,
+  0x6f758d,
+  0x6f79f8,
+  0x6f8309,
+  0x6f8f7c,
+  0x6f9796,
+  0x6f9be3,
+  0x6fa642,
+  0x6faa37,
+  0x6fb2dd,
+  0x6fbea8,
+  0x6fc5ea,
+  0x6fc99f,
+  0x6fd175,
+  0x6fdd00,
+  0x6fe0a1,
+  0x6fecd4,
+  0x6ff43e,
+  0x6ff84b,
+  0x700293,
+  0x700ee6,
+  0x70160c,
+  0x701a79,
+  0x7027d8,
+  0x702bad,
+  0x703347,
+  0x703f32,
+  0x704470,
+  0x704805,
+  0x7050ef,
+  0x705c9a,
+  0x70613b,
+  0x706d4e,
+  0x7075a4,
+  0x7079d1,
+  0x708320,
+  0x708f55,
+  0x7097bf,
+  0x709bca,
+  0x70a66b,
+  0x70aa1e,
+  0x70b2f4,
+  0x70be81,
+  0x70c5c3,
+  0x70c9b6,
+  0x70d15c,
+  0x70dd29,
+  0x70e088,
+  0x70ecfd,
+  0x70f417,
+  0x70f862,
+  0x7101f5,
+  0x710d80,
+  0x71156a,
+  0x71191f,
+  0x7124be,
+  0x7128cb,
+  0x713021,
+  0x713c54,
+  0x714716,
+  0x714b63,
+  0x715389,
+  0x715ffc,
+  0x71625d,
+  0x716e28,
+  0x7176c2,
+  0x717ab7,
+  0x718046,
+  0x718c33,
+  0x7194d9,
+  0x7198ac,
+  0x71a50d,
+  0x71a978,
+  0x71b192,
+  0x71bde7,
+  0x71c6a5,
+  0x71cad0,
+  0x71d23a,
+  0x71de4f,
+  0x71e3ee,
+  0x71ef9b,
+  0x71f771,
+  0x71fb04,
+  0x72045f,
+  0x72082a,
+  0x7210c0,
+  0x721cb5,
+  0x722114,
+  0x722d61,
+  0x72358b,
+  0x7239fe,
+  0x7242bc,
+  0x724ec9,
+  0x725623,
+  0x725a56,
+  0x7267f7,
+  0x726b82,
+  0x727368,
+  0x727f1d,
+  0x7285ec,
+  0x728999,
+  0x729173,
+  0x729d06,
+  0x72a0a7,
+  0x72acd2,
+  0x72b438,
+  0x72b84d,
+  0x72c30f,
+  0x72cf7a,
+  0x72d790,
+  0x72dbe5,
+  0x72e644,
+  0x72ea31,
+  0x72f2db,
+  0x72feae,
+  0x730739,
+  0x730b4c,
+  0x7313a6,
+  0x731fd3,
+  0x732272,
+  0x732e07,
+  0x7336ed,
+  0x733a98,
+  0x7341da,
+  0x734daf,
+  0x735545,
+  0x735930,
+  0x736491,
+  0x7368e4,
+  0x73700e,
+  0x737c7b,
+  0x73868a,
+  0x738aff,
+  0x739215,
+  0x739e60,
+  0x73a3c1,
+  0x73afb4,
+  0x73b75e,
+  0x73bb2b,
+  0x73c069,
+  0x73cc1c,
+  0x73d4f6,
+  0x73d883,
+  0x73e522,
+  0x73e957,
+  0x73f1bd,
+  0x73fdc8,
+  0x74037e,
+  0x740f0b,
+  0x7417e1,
+  0x741b94,
+  0x742635,
+  0x742a40,
+  0x7432aa,
+  0x743edf,
+  0x74459d,
+  0x7449e8,
+  0x745102,
+  0x745d77,
+  0x7460d6,
+  0x746ca3,
+  0x747449,
+  0x74783c,
+  0x7482cd,
+  0x748eb8,
+  0x749652,
+  0x749a27,
+  0x74a786,
+  0x74abf3,
+  0x74b319,
+  0x74bf6c,
+  0x74c42e,
+  0x74c85b,
+  0x74d0b1,
+  0x74dcc4,
+  0x74e165,
+  0x74ed10,
+  0x74f5fa,
+  0x74f98f,
+  0x750018,
+  0x750c6d,
+  0x751487,
+  0x7518f2,
+  0x752553,
+  0x752926,
+  0x7531cc,
+  0x753db9,
+  0x7546fb,
+  0x754a8e,
+  0x755264,
+  0x755e11,
+  0x7563b0,
+  0x756fc5,
+  0x75772f,
+  0x757b5a,
+  0x7581ab,
+  0x758dde,
+  0x759534,
+  0x759941,
+  0x75a4e0,
+  0x75a895,
+  0x75b07f,
+  0x75bc0a,
+  0x75c748,
+  0x75cb3d,
+  0x75d3d7,
+  0x75dfa2,
+  0x75e203,
+  0x75ee76,
+  0x75f69c,
+  0x75fae9,
+  0x7605b2,
+  0x7609c7,
+  0x76112d,
+  0x761d58,
+  0x7620f9,
+  0x762c8c,
+  0x763466,
+  0x763813,
+  0x764351,
+  0x764f24,
+  0x7657ce,
+  0x765bbb,
+  0x76661a,
+  0x766a6f,
+  0x767285,
+  0x767ef0,
+  0x768401,
+  0x768874,
+  0x76909e,
+  0x769ceb,
+  0x76a14a,
+  0x76ad3f,
+  0x76b5d5,
+  0x76b9a0,
+  0x76c2e2,
+  0x76ce97,
+  0x76d67d,
+  0x76da08,
+  0x76e7a9,
+  0x76ebdc,
+  0x76f336,
+  0x76ff43,
+  0x7706d4,
+  0x770aa1,
+  0x77124b,
+  0x771e3e,
+  0x77239f,
+  0x772fea,
+  0x773700,
+  0x773b75,
+  0x774037,
+  0x774c42,
+  0x7754a8,
+  0x7758dd,
+  0x77657c,
+  0x776909,
+  0x7771e3,
+  0x777d96,
+  0x778767,
+  0x778b12,
+  0x7793f8,
+  0x779f8d,
+  0x77a22c,
+  0x77ae59,
+  0x77b6b3,
+  0x77bac6,
+  0x77c184,
+  0x77cdf1,
+  0x77d51b,
+  0x77d96e,
+  0x77e4cf,
+  0x77e8ba,
+  0x77f050,
+  0x77fc25,
+  0x780149,
+  0x780d3c,
+  0x7815d6,
+  0x7819a3,
+  0x782402,
+  0x782877,
+  0x78309d,
+  0x783ce8,
+  0x7847aa,
+  0x784bdf,
+  0x785335,
+  0x785f40,
+  0x7862e1,
+  0x786e94,
+  0x78767e,
+  0x787a0b,
+  0x7880fa,
+  0x788c8f,
+  0x789465,
+  0x789810,
+  0x78a5b1,
+  0x78a9c4,
+  0x78b12e,
+  0x78bd5b,
+  0x78c619,
+  0x78ca6c,
+  0x78d286,
+  0x78def3,
+  0x78e352,
+  0x78ef27,
+  0x78f7cd,
+  0x78fbb8,
+  0x79022f,
+  0x790e5a,
+  0x7916b0,
+  0x791ac5,
+  0x792764,
+  0x792b11,
+  0x7933fb,
+  0x793f8e,
+  0x7944cc,
+  0x7948b9,
+  0x795053,
+  0x795c26,
+  0x796187,
+  0x796df2,
+  0x797518,
+  0x79796d,
+  0x79839c,
+  0x798fe9,
+  0x799703,
+  0x799b76,
+  0x79a6d7,
+  0x79aaa2,
+  0x79b248,
+  0x79be3d,
+  0x79c57f,
+  0x79c90a,
+  0x79d1e0,
+  0x79dd95,
+  0x79e034,
+  0x79ec41,
+  0x79f4ab,
+  0x79f8de,
+  0x7a0785,
+  0x7a0bf0,
+  0x7a131a,
+  0x7a1f6f,
+  0x7a22ce,
+  0x7a2ebb,
+  0x7a3651,
+  0x7a3a24,
+  0x7a4166,
+  0x7a4d13,
+  0x7a55f9,
+  0x7a598c,
+  0x7a642d,
+  0x7a6858,
+  0x7a70b2,
+  0x7a7cc7,
+  0x7a8636,
+  0x7a8a43,
+  0x7a92a9,
+  0x7a9edc,
+  0x7aa37d,
+  0x7aaf08,
+  0x7ab7e2,
+  0x7abb97,
+  0x7ac0d5,
+  0x7acca0,
+  0x7ad44a,
+  0x7ad83f,
+  0x7ae59e,
+  0x7ae9eb,
+  0x7af101,
+  0x7afd74,
+  0x7b04e3,
+  0x7b0896,
+  0x7b107c,
+  0x7b1c09,
+  0x7b21a8,
+  0x7b2ddd,
+  0x7b3537,
+  0x7b3942,
+  0x7b4200,
+  0x7b4e75,
+  0x7b569f,
+  0x7b5aea,
+  0x7b674b,
+  0x7b6b3e,
+  0x7b73d4,
+  0x7b7fa1,
+  0x7b8550,
+  0x7b8925,
+  0x7b91cf,
+  0x7b9dba,
+  0x7ba01b,
+  0x7bac6e,
+  0x7bb484,
+  0x7bb8f1,
+  0x7bc3b3,
+  0x7bcfc6,
+  0x7bd72c,
+  0x7bdb59,
+  0x7be6f8,
+  0x7bea8d,
+  0x7bf267,
+  0x7bfe12,
+  0x7c00a4,
+  0x7c0cd1,
+  0x7c143b,
+  0x7c184e,
+  0x7c25ef,
+  0x7c299a,
+  0x7c3170,
+  0x7c3d05,
+  0x7c4647,
+  0x7c4a32,
+  0x7c52d8,
+  0x7c5ead,
+  0x7c630c,
+  0x7c6f79,
+  0x7c7793,
+  0x7c7be6,
+  0x7c8117,
+  0x7c8d62,
+  0x7c9588,
+  0x7c99fd,
+  0x7ca45c,
+  0x7ca829,
+  0x7cb0c3,
+  0x7cbcb6,
+  0x7cc7f4,
+  0x7ccb81,
+  0x7cd36b,
+  0x7cdf1e,
+  0x7ce2bf,
+  0x7ceeca,
+  0x7cf620,
+  0x7cfa55,
+  0x7d03c2,
+  0x7d0fb7,
+  0x7d175d,
+  0x7d1b28,
+  0x7d2689,
+  0x7d2afc,
+  0x7d3216,
+  0x7d3e63,
+  0x7d4521,
+  0x7d4954,
+  0x7d51be,
+  0x7d5dcb,
+  0x7d606a,
+  0x7d6c1f,
+  0x7d74f5,
+  0x7d7880,
+  0x7d8271,
+  0x7d8e04,
+  0x7d96ee,
+  0x7d9a9b,
+  0x7da73a,
+  0x7dab4f,
+  0x7db3a5,
+  0x7dbfd0,
+  0x7dc492,
+  0x7dc8e7,
+  0x7dd00d,
+  0x7ddc78,
+  0x7de1d9,
+  0x7dedac,
+  0x7df546,
+  0x7df933,
+  0x7e0668,
+  0x7e0a1d,
+  0x7e12f7,
+  0x7e1e82,
+  0x7e2323,
+  0x7e2f56,
+  0x7e37bc,
+  0x7e3bc9,
+  0x7e408b,
+  0x7e4cfe,
+  0x7e5414,
+  0x7e5861,
+  0x7e65c0,
+  0x7e69b5,
+  0x7e715f,
+  0x7e7d2a,
+  0x7e87db,
+  0x7e8bae,
+  0x7e9344,
+  0x7e9f31,
+  0x7ea290,
+  0x7eaee5,
+  0x7eb60f,
+  0x7eba7a,
+  0x7ec138,
+  0x7ecd4d,
+  0x7ed5a7,
+  0x7ed9d2,
+  0x7ee473,
+  0x7ee806,
+  0x7ef0ec,
+  0x7efc99,
+  0x7f050e,
+  0x7f097b,
+  0x7f1191,
+  0x7f1de4,
+  0x7f2045,
+  0x7f2c30,
+  0x7f34da,
+  0x7f38af,
+  0x7f43ed,
+  0x7f4f98,
+  0x7f5772,
+  0x7f5b07,
+  0x7f66a6,
+  0x7f6ad3,
+  0x7f7239,
+  0x7f7e4c,
+  0x7f84bd,
+  0x7f88c8,
+  0x7f9022,
+  0x7f9c57,
+  0x7fa1f6,
+  0x7fad83,
+  0x7fb569,
+  0x7fb91c,
+  0x7fc25e,
+  0x7fce2b,
+  0x7fd6c1,
+  0x7fdab4,
+  0x7fe715,
+  0x7feb60,
+  0x7ff38a,
+  0x7fffff
+};
diff --git a/codec2/branches/0.7/src/hanning.h b/codec2/branches/0.7/src/hanning.h
new file mode 100644 (file)
index 0000000..81d88dc
--- /dev/null
@@ -0,0 +1,644 @@
+/* Generated by hanning_file() Octave function */
+
+const float hanning[]={
+  0,
+  2.4171e-05,
+  9.66816e-05,
+  0.000217525,
+  0.000386689,
+  0.000604158,
+  0.00086991,
+  0.00118392,
+  0.00154616,
+  0.00195659,
+  0.00241517,
+  0.00292186,
+  0.00347661,
+  0.00407937,
+  0.00473008,
+  0.00542867,
+  0.00617507,
+  0.00696922,
+  0.00781104,
+  0.00870045,
+  0.00963736,
+  0.0106217,
+  0.0116533,
+  0.0127322,
+  0.0138581,
+  0.0150311,
+  0.0162509,
+  0.0175175,
+  0.0188308,
+  0.0201906,
+  0.0215968,
+  0.0230492,
+  0.0245478,
+  0.0260923,
+  0.0276826,
+  0.0293186,
+  0.0310001,
+  0.032727,
+  0.034499,
+  0.036316,
+  0.0381779,
+  0.0400844,
+  0.0420354,
+  0.0440307,
+  0.04607,
+  0.0481533,
+  0.0502802,
+  0.0524506,
+  0.0546643,
+  0.056921,
+  0.0592206,
+  0.0615627,
+  0.0639473,
+  0.0663741,
+  0.0688427,
+  0.0713531,
+  0.0739048,
+  0.0764978,
+  0.0791318,
+  0.0818064,
+  0.0845214,
+  0.0872767,
+  0.0900718,
+  0.0929066,
+  0.0957807,
+  0.0986939,
+  0.101646,
+  0.104636,
+  0.107665,
+  0.110732,
+  0.113836,
+  0.116978,
+  0.120156,
+  0.123372,
+  0.126624,
+  0.129912,
+  0.133235,
+  0.136594,
+  0.139989,
+  0.143418,
+  0.146881,
+  0.150379,
+  0.153911,
+  0.157476,
+  0.161074,
+  0.164705,
+  0.168368,
+  0.172063,
+  0.17579,
+  0.179549,
+  0.183338,
+  0.187158,
+  0.191008,
+  0.194888,
+  0.198798,
+  0.202737,
+  0.206704,
+  0.2107,
+  0.214724,
+  0.218775,
+  0.222854,
+  0.226959,
+  0.231091,
+  0.235249,
+  0.239432,
+  0.243641,
+  0.247874,
+  0.252132,
+  0.256414,
+  0.260719,
+  0.265047,
+  0.269398,
+  0.273772,
+  0.278167,
+  0.282584,
+  0.287021,
+  0.29148,
+  0.295958,
+  0.300456,
+  0.304974,
+  0.30951,
+  0.314065,
+  0.318638,
+  0.323228,
+  0.327835,
+  0.332459,
+  0.3371,
+  0.341756,
+  0.346427,
+  0.351113,
+  0.355814,
+  0.360528,
+  0.365256,
+  0.369997,
+  0.374751,
+  0.379516,
+  0.384293,
+  0.389082,
+  0.393881,
+  0.398691,
+  0.40351,
+  0.408338,
+  0.413176,
+  0.418022,
+  0.422876,
+  0.427737,
+  0.432605,
+  0.43748,
+  0.44236,
+  0.447247,
+  0.452138,
+  0.457034,
+  0.461935,
+  0.466839,
+  0.471746,
+  0.476655,
+  0.481568,
+  0.486481,
+  0.491397,
+  0.496313,
+  0.501229,
+  0.506145,
+  0.511061,
+  0.515976,
+  0.520889,
+  0.5258,
+  0.530708,
+  0.535614,
+  0.540516,
+  0.545414,
+  0.550308,
+  0.555197,
+  0.560081,
+  0.564958,
+  0.56983,
+  0.574695,
+  0.579552,
+  0.584402,
+  0.589244,
+  0.594077,
+  0.598901,
+  0.603715,
+  0.60852,
+  0.613314,
+  0.618097,
+  0.622868,
+  0.627628,
+  0.632375,
+  0.63711,
+  0.641831,
+  0.646538,
+  0.651232,
+  0.655911,
+  0.660574,
+  0.665222,
+  0.669855,
+  0.67447,
+  0.679069,
+  0.683651,
+  0.688215,
+  0.69276,
+  0.697287,
+  0.701795,
+  0.706284,
+  0.710752,
+  0.7152,
+  0.719627,
+  0.724033,
+  0.728418,
+  0.73278,
+  0.73712,
+  0.741437,
+  0.74573,
+  0.75,
+  0.754246,
+  0.758467,
+  0.762663,
+  0.766833,
+  0.770978,
+  0.775097,
+  0.779189,
+  0.783254,
+  0.787291,
+  0.791301,
+  0.795283,
+  0.799236,
+  0.80316,
+  0.807055,
+  0.810921,
+  0.814756,
+  0.81856,
+  0.822334,
+  0.826077,
+  0.829788,
+  0.833468,
+  0.837115,
+  0.840729,
+  0.844311,
+  0.847859,
+  0.851374,
+  0.854855,
+  0.858301,
+  0.861713,
+  0.86509,
+  0.868431,
+  0.871737,
+  0.875007,
+  0.87824,
+  0.881437,
+  0.884598,
+  0.887721,
+  0.890806,
+  0.893854,
+  0.896864,
+  0.899835,
+  0.902768,
+  0.905661,
+  0.908516,
+  0.911331,
+  0.914106,
+  0.916841,
+  0.919536,
+  0.92219,
+  0.924804,
+  0.927376,
+  0.929907,
+  0.932397,
+  0.934845,
+  0.93725,
+  0.939614,
+  0.941935,
+  0.944213,
+  0.946448,
+  0.94864,
+  0.950789,
+  0.952894,
+  0.954955,
+  0.956972,
+  0.958946,
+  0.960874,
+  0.962759,
+  0.964598,
+  0.966393,
+  0.968142,
+  0.969846,
+  0.971505,
+  0.973118,
+  0.974686,
+  0.976207,
+  0.977683,
+  0.979112,
+  0.980495,
+  0.981832,
+  0.983122,
+  0.984365,
+  0.985561,
+  0.986711,
+  0.987813,
+  0.988868,
+  0.989876,
+  0.990837,
+  0.99175,
+  0.992616,
+  0.993434,
+  0.994204,
+  0.994927,
+  0.995601,
+  0.996228,
+  0.996807,
+  0.997337,
+  0.99782,
+  0.998255,
+  0.998641,
+  0.998979,
+  0.999269,
+  0.999511,
+  0.999704,
+  0.999849,
+  0.999946,
+  0.999994,
+  0.999994,
+  0.999946,
+  0.999849,
+  0.999704,
+  0.999511,
+  0.999269,
+  0.998979,
+  0.998641,
+  0.998255,
+  0.99782,
+  0.997337,
+  0.996807,
+  0.996228,
+  0.995601,
+  0.994927,
+  0.994204,
+  0.993434,
+  0.992616,
+  0.99175,
+  0.990837,
+  0.989876,
+  0.988868,
+  0.987813,
+  0.986711,
+  0.985561,
+  0.984365,
+  0.983122,
+  0.981832,
+  0.980495,
+  0.979112,
+  0.977683,
+  0.976207,
+  0.974686,
+  0.973118,
+  0.971505,
+  0.969846,
+  0.968142,
+  0.966393,
+  0.964598,
+  0.962759,
+  0.960874,
+  0.958946,
+  0.956972,
+  0.954955,
+  0.952894,
+  0.950789,
+  0.94864,
+  0.946448,
+  0.944213,
+  0.941935,
+  0.939614,
+  0.93725,
+  0.934845,
+  0.932397,
+  0.929907,
+  0.927376,
+  0.924804,
+  0.92219,
+  0.919536,
+  0.916841,
+  0.914106,
+  0.911331,
+  0.908516,
+  0.905661,
+  0.902768,
+  0.899835,
+  0.896864,
+  0.893854,
+  0.890806,
+  0.887721,
+  0.884598,
+  0.881437,
+  0.87824,
+  0.875007,
+  0.871737,
+  0.868431,
+  0.86509,
+  0.861713,
+  0.858301,
+  0.854855,
+  0.851374,
+  0.847859,
+  0.844311,
+  0.840729,
+  0.837115,
+  0.833468,
+  0.829788,
+  0.826077,
+  0.822334,
+  0.81856,
+  0.814756,
+  0.810921,
+  0.807055,
+  0.80316,
+  0.799236,
+  0.795283,
+  0.791301,
+  0.787291,
+  0.783254,
+  0.779189,
+  0.775097,
+  0.770978,
+  0.766833,
+  0.762663,
+  0.758467,
+  0.754246,
+  0.75,
+  0.74573,
+  0.741437,
+  0.73712,
+  0.73278,
+  0.728418,
+  0.724033,
+  0.719627,
+  0.7152,
+  0.710752,
+  0.706284,
+  0.701795,
+  0.697287,
+  0.69276,
+  0.688215,
+  0.683651,
+  0.679069,
+  0.67447,
+  0.669855,
+  0.665222,
+  0.660574,
+  0.655911,
+  0.651232,
+  0.646538,
+  0.641831,
+  0.63711,
+  0.632375,
+  0.627628,
+  0.622868,
+  0.618097,
+  0.613314,
+  0.60852,
+  0.603715,
+  0.598901,
+  0.594077,
+  0.589244,
+  0.584402,
+  0.579552,
+  0.574695,
+  0.56983,
+  0.564958,
+  0.560081,
+  0.555197,
+  0.550308,
+  0.545414,
+  0.540516,
+  0.535614,
+  0.530708,
+  0.5258,
+  0.520889,
+  0.515976,
+  0.511061,
+  0.506145,
+  0.501229,
+  0.496313,
+  0.491397,
+  0.486481,
+  0.481568,
+  0.476655,
+  0.471746,
+  0.466839,
+  0.461935,
+  0.457034,
+  0.452138,
+  0.447247,
+  0.44236,
+  0.43748,
+  0.432605,
+  0.427737,
+  0.422876,
+  0.418022,
+  0.413176,
+  0.408338,
+  0.40351,
+  0.398691,
+  0.393881,
+  0.389082,
+  0.384293,
+  0.379516,
+  0.374751,
+  0.369997,
+  0.365256,
+  0.360528,
+  0.355814,
+  0.351113,
+  0.346427,
+  0.341756,
+  0.3371,
+  0.332459,
+  0.327835,
+  0.323228,
+  0.318638,
+  0.314065,
+  0.30951,
+  0.304974,
+  0.300456,
+  0.295958,
+  0.29148,
+  0.287021,
+  0.282584,
+  0.278167,
+  0.273772,
+  0.269398,
+  0.265047,
+  0.260719,
+  0.256414,
+  0.252132,
+  0.247874,
+  0.243641,
+  0.239432,
+  0.235249,
+  0.231091,
+  0.226959,
+  0.222854,
+  0.218775,
+  0.214724,
+  0.2107,
+  0.206704,
+  0.202737,
+  0.198798,
+  0.194888,
+  0.191008,
+  0.187158,
+  0.183338,
+  0.179549,
+  0.17579,
+  0.172063,
+  0.168368,
+  0.164705,
+  0.161074,
+  0.157476,
+  0.153911,
+  0.150379,
+  0.146881,
+  0.143418,
+  0.139989,
+  0.136594,
+  0.133235,
+  0.129912,
+  0.126624,
+  0.123372,
+  0.120156,
+  0.116978,
+  0.113836,
+  0.110732,
+  0.107665,
+  0.104636,
+  0.101646,
+  0.0986939,
+  0.0957807,
+  0.0929066,
+  0.0900718,
+  0.0872767,
+  0.0845214,
+  0.0818064,
+  0.0791318,
+  0.0764978,
+  0.0739048,
+  0.0713531,
+  0.0688427,
+  0.0663741,
+  0.0639473,
+  0.0615627,
+  0.0592206,
+  0.056921,
+  0.0546643,
+  0.0524506,
+  0.0502802,
+  0.0481533,
+  0.04607,
+  0.0440307,
+  0.0420354,
+  0.0400844,
+  0.0381779,
+  0.036316,
+  0.034499,
+  0.032727,
+  0.0310001,
+  0.0293186,
+  0.0276826,
+  0.0260923,
+  0.0245478,
+  0.0230492,
+  0.0215968,
+  0.0201906,
+  0.0188308,
+  0.0175175,
+  0.0162509,
+  0.0150311,
+  0.0138581,
+  0.0127322,
+  0.0116533,
+  0.0106217,
+  0.00963736,
+  0.00870045,
+  0.00781104,
+  0.00696922,
+  0.00617507,
+  0.00542867,
+  0.00473008,
+  0.00407937,
+  0.00347661,
+  0.00292186,
+  0.00241517,
+  0.00195659,
+  0.00154616,
+  0.00118392,
+  0.00086991,
+  0.000604158,
+  0.000386689,
+  0.000217525,
+  9.66816e-05,
+  2.4171e-05,
+  0
+};
diff --git a/codec2/branches/0.7/src/horus_l2.c b/codec2/branches/0.7/src/horus_l2.c
new file mode 100644 (file)
index 0000000..f3cdc73
--- /dev/null
@@ -0,0 +1,1177 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: horus_l2.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Dec 2015
+
+  Horus telemetry layer 2 processing.  Takes an array of 8 bit payload
+  data, generates parity bits for a (23,12) Golay code, interleaves
+  data and parity bits, pre-pends a Unique Word for modem sync.
+  Caller is responsible for providing storage for output packet.
+
+  [ ] code based interleaver
+  [ ] test correction of 1,2 & 3 error patterms    
+
+  1/ Unit test on a PC:
+
+     $ gcc horus_l2.c -o horus_l2 -Wall -DHORUS_L2_UNITTEST
+     $ ./horus_l2
+
+     test 0: 22 bytes of payload data BER: 0.00 errors: 0
+     test 0: 22 bytes of payload data BER: 0.01 errors: 0
+     test 0: 22 bytes of payload data BER: 0.05 errors: 0
+     test 0: 22 bytes of payload data BER: 0.10 errors: 7
+     
+     This indicates it's correcting all channel errors for 22 bytes of
+     payload data, at bit error rate (BER) of 0, 0.01, 0.05.  It falls
+     over at a BER of 0.10 which is expected.
+
+  2/ To build with just the tx function, ie for linking with the payload
+  firmware:
+
+    $ gcc horus_l2.c -c -Wall
+    
+  By default the RX side is #ifdef-ed out, leaving the minimal amount
+  of code for tx.
+
+  3/ Generate some tx_bits as input for testing with fsk_horus:
+    $ gcc horus_l2.c -o horus_l2 -Wall -DGEN_TX_BITS -DSCRAMBLER
+    $ ./horus_l2
+    $ more ../octave/horus_tx_bits_binary.txt
+   
+  4/ Unit testing interleaver:
+
+    $ gcc horus_l2.c -o horus_l2 -Wall -DINTERLEAVER -DTEST_INTERLEAVER -DSCRAMBLER
+
+  5/ Compile for use as decoder called by fsk_horus.m and fsk_horus_stream.m:
+
+    $ gcc horus_l2.c -o horus_l2 -Wall -DDEC_RX_BITS -DHORUS_L2_RX
+
+\*---------------------------------------------------------------------------*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include "horus_l2.h"
+
+#ifdef HORUS_L2_UNITTEST
+#define HORUS_L2_RX
+#endif
+
+#define RUN_TIME_TABLES
+
+static char uw[] = {'$','$'};
+
+/* Function Prototypes ------------------------------------------------*/
+
+int32_t get_syndrome(int32_t pattern);
+void golay23_init(void);
+int golay23_decode(int received_codeword);
+unsigned short gen_crc16(unsigned char* data_p, unsigned char length);
+void interleave(unsigned char *inout, int nbytes, int dir);
+void scramble(unsigned char *inout, int nbytes);
+
+/* Functions ----------------------------------------------------------*/
+
+/*
+   We are using a Golay (23,12) code which has a codeword 23 bits
+   long.  The tx packet format is:
+
+      | Unique Word | payload data bits | parity bits |
+
+   This function works out how much storage the caller of
+   horus_l2_encode_tx_packet() will need to store the tx packet
+ */
+
+int horus_l2_get_num_tx_data_bytes(int num_payload_data_bytes) {
+    int num_payload_data_bits, num_golay_codewords;
+    int num_tx_data_bits, num_tx_data_bytes;
+    
+    num_payload_data_bits = num_payload_data_bytes*8;
+    num_golay_codewords = num_payload_data_bits/12;
+    if (num_payload_data_bits % 12) /* round up to 12 bits, may mean some unused bits */
+        num_golay_codewords++;
+
+    num_tx_data_bits = sizeof(uw)*8 + num_payload_data_bits + num_golay_codewords*11;
+    num_tx_data_bytes = num_tx_data_bits/8;
+    if (num_tx_data_bits % 8) /* round up to nearest byte, may mean some unused bits */
+        num_tx_data_bytes++;
+    
+    #ifdef DEBUG0
+    fprintf(stderr, "\nnum_payload_data_bytes: %d\n", num_payload_data_bytes);
+    fprintf(stderr, "num_golay_codewords...: %d\n", num_golay_codewords);
+    fprintf(stderr, "num_tx_data_bits......: %d\n", num_tx_data_bits);
+    fprintf(stderr, "num_tx_data_bytes.....: %d\n\n", num_tx_data_bytes);
+    #endif
+
+    return num_tx_data_bytes;
+}
+
+
+/*
+  Takes an array of payload data bytes, prepends a unique word and appends
+  parity bits.
+
+  The encoder will run on the payload on a small 8-bit uC.  As we are
+  memory constrained so we do a lot of burrowing for bits out of
+  packed arrays, and don't use a LUT for Golay encoding.  Hopefully it
+  will run fast enough.  This was quite difficult to get going,
+  suspect there is a better way to write this.  Oh well, have to start
+  somewhere.
+ */
+
+int horus_l2_encode_tx_packet(unsigned char *output_tx_data,
+                              unsigned char *input_payload_data,
+                              int            num_payload_data_bytes)
+{
+    int            num_tx_data_bytes, num_payload_data_bits;
+    unsigned char *pout = output_tx_data;
+    int            ninbit, ningolay, nparitybits;
+    int32_t        ingolay, paritybyte, inbit, golayparity;
+    int            ninbyte, shift, golayparitybit, i;
+
+    num_tx_data_bytes = horus_l2_get_num_tx_data_bytes(num_payload_data_bytes);
+    memcpy(pout, uw, sizeof(uw)); pout += sizeof(uw);
+    memcpy(pout, input_payload_data, num_payload_data_bytes); pout += num_payload_data_bytes;
+
+    /* Read input bits one at a time.  Fill input Golay codeword.  Find output Golay codeword.
+       Write this to parity bits.  Write parity bytes when we have 8 parity bits.  Bits are
+       written MSB first. */
+
+    num_payload_data_bits = num_payload_data_bytes*8;
+    ninbit = 0;
+    ingolay = 0;
+    ningolay = 0;
+    paritybyte = 0;
+    nparitybits = 0;
+
+    while (ninbit < num_payload_data_bits) {
+
+        /* extract input data bit */
+
+        ninbyte = ninbit/8;
+        shift = 7 - (ninbit % 8);
+        inbit = (input_payload_data[ninbyte] >> shift) & 0x1;
+        #ifdef DEBUG1
+        fprintf(stderr, "inbit %d ninbyte: %d inbyte: 0x%02x inbit: %d\n", 
+                ninbit, ninbyte, input_payload_data[ninbyte], inbit);
+        #endif
+        ninbit++;
+
+        /* build up input golay codeword */
+
+        ingolay = ingolay | inbit;
+        ningolay++;
+
+        /* when we get 12 bits do a Golay encode */
+
+        if (ningolay % 12) {
+            ingolay <<= 1;
+        }
+        else {
+            #ifdef DEBUG0
+            fprintf(stderr, "  ningolay: %d ingolay: 0x%04x\n", ningolay, ingolay);
+            #endif
+            golayparity = get_syndrome(ingolay<<11);
+            ingolay = 0;
+
+            #ifdef DEBUG0
+            fprintf(stderr, "  golayparity: 0x%04x\n", golayparity);
+            #endif
+
+            /* write parity bits to output data */
+
+            for (i=0; i<11; i++) {
+                golayparitybit = (golayparity >> (10-i)) & 0x1;
+                paritybyte = paritybyte | golayparitybit;
+                #ifdef DEBUG0
+                fprintf(stderr, "    i: %d golayparitybit: %d paritybyte: 0x%02x\n", 
+                        i, golayparitybit, paritybyte);
+                #endif
+                nparitybits++;
+                if (nparitybits % 8) {
+                   paritybyte <<= 1;
+                }
+                else {
+                    /* OK we have a full byte ready */
+                    *pout = paritybyte;
+                    #ifdef DEBUG0
+                    fprintf(stderr,"      Write paritybyte: 0x%02x\n", paritybyte);
+                    #endif
+                    pout++;
+                    paritybyte = 0;
+                }
+            }
+        }
+    } /* while(.... */
+
+
+    /* Complete final Golay encode, we may have partially finished ingolay, paritybyte */
+
+    #ifdef DEBUG0
+    fprintf(stderr, "finishing up .....\n");
+    #endif
+
+    if (ningolay % 12) {
+        ingolay >>= 1;
+        golayparity = get_syndrome(ingolay<<12);
+        #ifdef DEBUG0
+        fprintf(stderr, "  ningolay: %d ingolay: 0x%04x\n", ningolay, ingolay);
+        fprintf(stderr, "  golayparity: 0x%04x\n", golayparity);
+        #endif
+
+        /* write parity bits to output data */
+
+        for (i=0; i<11; i++) {
+            golayparitybit = (golayparity >> (10 - i)) & 0x1;
+            paritybyte = paritybyte | golayparitybit;
+            #ifdef DEBUG1
+            fprintf(stderr, "    i: %d golayparitybit: %d paritybyte: 0x%02x\n", 
+                    i, golayparitybit, paritybyte);
+            #endif
+            nparitybits++;
+            if (nparitybits % 8) {
+                paritybyte <<= 1;
+            }
+            else {
+                /* OK we have a full byte ready */
+                *pout++ = (unsigned char)paritybyte;
+                #ifdef DEBUG0
+                fprintf(stderr,"      Write paritybyte: 0x%02x\n", paritybyte);
+                #endif
+                paritybyte = 0;
+            }
+        }
+    }
+    /* and final, partially complete, parity byte */
+
+    if (nparitybits % 8) {
+        paritybyte <<= 7 - (nparitybits % 8);  // use MS bits first
+        *pout++ = (unsigned char)paritybyte;
+        #ifdef DEBUG0
+        fprintf(stderr,"      Write last paritybyte: 0x%02x nparitybits: %d \n", paritybyte, nparitybits);
+        #endif
+    }
+
+    #ifdef DEBUG0
+    fprintf(stderr, "\npout - output_tx_data: %ld num_tx_data_bytes: %d\n",
+            pout - output_tx_data, num_tx_data_bytes);
+    #endif
+    assert(pout == (output_tx_data + num_tx_data_bytes));
+
+    /* optional interleaver - we dont interleave UW */
+
+    #ifdef INTERLEAVER
+    interleave(&output_tx_data[sizeof(uw)], num_tx_data_bytes-2, 0);
+    #endif
+
+    /* optional scrambler to prevent long strings of the same symbol
+       which upsets the modem - we dont scramble UW */
+
+    #ifdef SCRAMBLER
+    scramble(&output_tx_data[sizeof(uw)], num_tx_data_bytes-2);
+    #endif
+
+    return num_tx_data_bytes;
+}
+
+
+#ifdef HORUS_L2_RX
+void horus_l2_decode_rx_packet(unsigned char *output_payload_data,
+                               unsigned char *input_rx_data,
+                               int            num_payload_data_bytes)
+{
+    int            num_payload_data_bits;
+    unsigned char *pout = output_payload_data;
+    unsigned char *pin  = input_rx_data;
+    int            ninbit, ingolay, ningolay, paritybyte, nparitybits;
+    int            ninbyte, shift, inbit, golayparitybit, i, outbit, outbyte, noutbits, outdata;
+    int num_tx_data_bytes = horus_l2_get_num_tx_data_bytes(num_payload_data_bytes);
+
+    /* optional scrambler and interleaver - we dont interleave UW */
+
+    #ifdef SCRAMBLER
+    scramble(&input_rx_data[sizeof(uw)], num_tx_data_bytes-2);
+    #endif
+
+    #ifdef INTERLEAVER
+    interleave(&input_rx_data[sizeof(uw)], num_tx_data_bytes-2, 1);
+    #endif
+
+    pin = input_rx_data + sizeof(uw) + num_payload_data_bytes;
+
+    /* Read input data bits one at a time.  When we have 12 read 11 parity bits. Golay decode.
+       Write decoded (output data) bits every time we have 8 of them. */
+
+    num_payload_data_bits = num_payload_data_bytes*8;
+    ninbit = 0;
+    ingolay = 0;
+    ningolay = 0;
+    nparitybits = 0;
+    paritybyte = *pin++;
+    #ifdef DEBUG0
+    fprintf(stderr,"  Read paritybyte: 0x%02x\n", paritybyte);
+    #endif
+    pout = output_payload_data;
+    noutbits = 0;
+    outbyte = 0;
+
+    while (ninbit < num_payload_data_bits) {
+
+        /* extract input data bit */
+
+        ninbyte = ninbit/8 + sizeof(uw);
+        shift = 7 - (ninbit % 8);
+        inbit = (input_rx_data[ninbyte] >> shift) & 0x1;
+        #ifdef DEBUG1
+        fprintf(stderr, "inbit %d ninbyte: %d inbyte: 0x%02x inbit: %d\n", 
+                ninbit, ninbyte, input_rx_data[ninbyte], inbit);
+        #endif
+        ninbit++;
+
+        /* build up golay codeword */
+
+        ingolay = ingolay | inbit;
+        ningolay++;
+        ingolay <<= 1;
+
+        /* when we get 12 data bits start reading parity bits */
+
+        if ((ningolay % 12) == 0) {
+            #ifdef DEBUG0
+            fprintf(stderr, "  ningolay: %d ingolay: 0x%04x\n", ningolay, ingolay>>1);
+            #endif
+            for (i=0; i<11; i++) {
+                shift = 7 - (nparitybits % 8);
+                golayparitybit = (paritybyte >> shift) & 0x1;
+                ingolay |= golayparitybit;
+                if (i != 10)
+                    ingolay <<=1;
+                nparitybits++;
+                if ((nparitybits % 8) == 0) {
+                    /* OK grab a new byte */
+                    paritybyte = *pin++;
+                    #ifdef DEBUG0
+                    fprintf(stderr,"  Read paritybyte: 0x%02x\n", paritybyte);
+                    #endif
+                }
+            }
+
+            #ifdef DEBUG0
+            fprintf(stderr, "  golay code word: 0x%04x\n", ingolay);
+            fprintf(stderr, "  golay decode...: 0x%04x\n", golay23_decode(ingolay));
+            #endif
+           
+            /* write decoded/error corrected bits to output payload data */
+
+            outdata = golay23_decode(ingolay) >> 11;
+            #ifdef DEBUG0
+            fprintf(stderr, "  outdata...: 0x%04x\n", outdata);
+            #endif
+
+            for(i=0; i<12; i++) {   
+                shift = 11 - i;
+                outbit = (outdata >> shift) & 0x1;
+                outbyte |= outbit;
+                noutbits++;
+                if (noutbits % 8) {
+                    outbyte <<= 1;
+                }
+                else {
+                    #ifdef DEBUG0
+                    fprintf(stderr, "  output payload byte: 0x%02x\n", outbyte);
+                    #endif
+                    *pout++ = outbyte;
+                    outbyte = 0;
+                }
+            }
+
+            ingolay = 0;
+        }
+    } /* while(.... */
+
+
+    #ifdef DEBUG0
+    fprintf(stderr, "finishing up .....\n");
+    #endif
+
+    /* Complete final Golay decode  */
+
+    int golayparity = 0;
+    if (ningolay % 12) {
+        for (i=0; i<11; i++) {
+            shift = 7 - (nparitybits % 8);
+            golayparitybit = (paritybyte >> shift) & 0x1;
+            golayparity |= golayparitybit;
+            if (i != 10)
+                golayparity <<=1;
+            nparitybits++;
+            if ((nparitybits % 8) == 0) {
+                /* OK grab a new byte */
+                paritybyte = *pin++;
+                #ifdef DEBUG0
+                fprintf(stderr,"  Read paritybyte: 0x%02x\n", paritybyte);
+                #endif
+            }
+        }
+
+        ingolay >>= 1;
+        int codeword = (ingolay<<12) + golayparity;
+        #ifdef DEBUG0
+        fprintf(stderr, "  ningolay: %d ingolay: 0x%04x\n", ningolay, ingolay);
+        fprintf(stderr, "  golay code word: 0x%04x\n", codeword);
+        fprintf(stderr, "  golay decode...: 0x%04x\n", golay23_decode(codeword));
+        #endif
+
+        outdata = golay23_decode(codeword) >> 11;
+        #ifdef DEBUG0
+        fprintf(stderr, "  outdata...: 0x%04x\n", outdata);
+        fprintf(stderr, "  num_payload_data_bits: %d noutbits: %d\n", num_payload_data_bits, noutbits);
+        #endif
+
+        /* write final byte */
+
+        int ntogo = num_payload_data_bits - noutbits;
+        for(i=0; i<ntogo; i++) {   
+            shift = ntogo - i;
+            outbit = (outdata >> shift) & 0x1;
+            outbyte |= outbit;
+            noutbits++;
+            if (noutbits % 8) {
+                outbyte <<= 1;
+            }
+            else {
+                #ifdef DEBUG0
+                fprintf(stderr, "  output payload byte: 0x%02x\n", outbyte);
+                #endif
+                *pout++ = outbyte;
+                outbyte = 0;
+            }
+        }
+    }
+
+    #ifdef DEBUG0
+    fprintf(stderr, "\npin - output_payload_data: %ld num_payload_data_bytes: %d\n",
+            pout - output_payload_data, num_payload_data_bytes);
+    #endif
+
+    assert(pout == (output_payload_data + num_payload_data_bytes));
+
+}
+#endif
+
+#ifdef INTERLEAVER
+
+uint16_t primes[] = {
+    2,      3,      5,      7,      11,     13,     17,     19,     23,     29, 
+    31,     37,     41,     43,     47,     53,     59,     61,     67,     71, 
+    73,     79,     83,     89,     97,     101,    103,    107,    109,    113, 
+    127,    131,    137,    139,    149,    151,    157,    163,    167,    173, 
+    179,    181,    191,    193,    197,    199,    211,    223,    227,    229, 
+    233,    239,    241,    251,    257,    263,    269,    271,    277,    281, 
+    283,    293,    307,    311,    313,    317,    331,    337,    347
+};
+
+void interleave(unsigned char *inout, int nbytes, int dir)
+{
+    /* note: to work on small uCs (e.g. AVR) needed to declare specific words sizes */
+    uint16_t nbits = (uint16_t)nbytes*8;
+    uint32_t i, j, n, ibit, ibyte, ishift, jbyte, jshift;
+    uint32_t b;
+    unsigned char out[nbytes];
+
+    memset(out, 0, nbytes);
+           
+    /* b chosen to be co-prime with nbits, I'm cheating by just finding the 
+       nearest prime to nbits.  It also uses storage, is run on every call,
+       and has an upper limit.  Oh Well, still seems to interleave OK. */
+    i = 1;
+    uint16_t imax = sizeof(primes)/sizeof(uint16_t);
+    while ((primes[i] < nbits) && (i < imax))
+        i++;
+    b = primes[i-1];
+
+    for(n=0; n<nbits; n++) {
+
+        /*
+          "On the Analysis and Design of Good Algebraic Interleavers", Xie et al,eq (5)
+        */
+
+        i = n;
+        j = (b*i) % nbits; /* note these all need to be 32-bit ints to make multiply work without overflow */
+        
+        if (dir) {
+            uint16_t tmp = j;
+            j = i;
+            i = tmp;
+        }
+        
+        #ifdef DEBUG0
+        printf("i: %d j: %d\n",i, j);
+        #endif
+
+        /* read bit i and write to bit j postion */
+
+        ibyte = i/8;
+        ishift = i%8;
+        ibit = (inout[ibyte] >> ishift) & 0x1;
+
+        jbyte = j/8;
+        jshift = j%8;
+
+        /* write jbit to ibit position */
+
+        out[jbyte] |= ibit << jshift; // replace with i-th bit
+        //out[ibyte] |= ibit << ishift; // replace with i-th bit
+    }
+    memcpy(inout, out, nbytes);
+
+    #ifdef DEBUG0
+    printf("\nInterleaver Out:\n");
+    for (i=0; i<nbytes; i++)
+        printf("%02d 0x%02x\n", i, inout[i]);
+    #endif
+}
+#endif
+
+
+#ifdef TEST_INTERLEAVER
+int main(void) {
+    int nbytes = 43;
+    unsigned char inout[nbytes];
+    unsigned char inter[nbytes];
+    unsigned char incopy[nbytes];
+    int i;
+
+    /* copy of input for later comp   */
+
+    for(i=0; i<nbytes; i++)
+        inout[i] = incopy[i] = rand() & 0xff;    
+    
+    interleave(inout, nbytes, 0);    /* interleave                     */
+    memcpy(inter, inout, nbytes);    /* snap shot of interleaved bytes */
+    interleave(inout, nbytes, 1);    /* de-interleave                  */
+
+    /* all ones in last col means it worked! */
+
+    for(i=0; i<nbytes; i++) {
+        printf("%d 0x%02x 0x%02x 0x%02x %d\n", 
+               i, incopy[i], inter[i], inout[i],  incopy[i] == inout[i]);
+        assert(incopy[i] == inout[i]);
+    }
+    printf("Interleaver tested OK!\n");
+
+    return 0;
+}
+#endif
+
+
+#ifdef SCRAMBLER
+
+/* 16 bit DVB additive scrambler as per Wikpedia example */
+
+void scramble(unsigned char *inout, int nbytes)
+{
+    int nbits = nbytes*8;
+    int i, ibit, ibits, ibyte, ishift, mask;
+    uint16_t scrambler = 0x4a80;  /* init additive scrambler at start of every frame */
+    uint16_t scrambler_out;
+
+    /* in place modification of each bit */
+
+    for(i=0; i<nbits; i++) {
+
+        scrambler_out = ((scrambler & 0x2) >> 1) ^ (scrambler & 0x1);
+
+        /* modify i-th bit by xor-ing with scrambler output sequence */
+
+        ibyte = i/8;
+        ishift = i%8;
+        ibit = (inout[ibyte] >> ishift) & 0x1;
+        ibits = ibit ^ scrambler_out;                  // xor ibit with scrambler output
+
+        mask = 1 << ishift;
+        inout[ibyte] &= ~mask;                  // clear i-th bit
+        inout[ibyte] |= ibits << ishift;         // set to scrambled value
+
+        /* update scrambler */
+
+        scrambler >>= 1;
+        scrambler |= scrambler_out << 14;
+
+        #ifdef DEBUG0
+        printf("i: %02d ibyte: %d ishift: %d ibit: %d ibits: %d scrambler_out: %d\n", 
+               i, ibyte, ishift, ibit, ibits, scrambler_out);
+        #endif
+
+    }
+
+    #ifdef DEBUG0
+    printf("\nScrambler Out:\n");
+    for (i=0; i<nbytes; i++)
+        printf("%02d 0x%02x\n", i, inout[i]);
+    #endif
+}
+#endif
+
+#ifdef HORUS_L2_UNITTEST
+
+/*
+  Test function to construct a packet of payload data, encode, add
+  some bit errors, decode, count errors.
+*/
+
+int test_sending_bytes(int nbytes, float ber, int error_pattern) {
+    unsigned char input_payload[nbytes];
+    int num_tx_data_bytes = horus_l2_get_num_tx_data_bytes(sizeof(input_payload));
+    unsigned char tx[num_tx_data_bytes];
+    unsigned char output_payload[sizeof(input_payload)];
+    int b, nbiterrors = 0;
+    int i;
+
+    for(i=0; i<nbytes; i++)
+        input_payload[i] = i;
+
+    horus_l2_encode_tx_packet(tx, input_payload, sizeof(input_payload));
+
+    #ifdef DEBUG0
+    fprintf(stderr, "\nTx Data:\n");
+    for(i=0; i<num_tx_data_bytes; i++)
+        fprintf(stderr, "  %02d 0x%02x\n", i, tx[i]);
+    #endif
+
+    /* insert random bit errors */
+
+    if (error_pattern == 0) {
+        float r;
+        for(i=0; i<num_tx_data_bytes; i++) {
+            for (b=0; b<8; b++) {
+                r = (float)rand()/RAND_MAX;
+                if (r < ber) {
+                    unsigned char mask = (1<<b);
+                    #ifdef DEBUG1
+                    fprintf("mask: 0x%x tx[%d] = 0x%x ", mask, i, tx[i]);
+                    #endif
+                    tx[i] ^= mask;
+                    #ifdef DEBUG1
+                    fprintf("0x%x\n", tx[i]);
+                    #endif
+                    nbiterrors++;
+                }
+            }
+        }
+    }
+
+    /* insert and error burst */
+
+    if (error_pattern == 1) {
+        tx[2] ^= 0xff;
+        tx[3] ^= 0xff;
+    }
+
+    /* insert 1 error every 12 bits, this gives up to 3 errors per 23
+       bit codeword, which is the limit of the code */
+
+    if (error_pattern == 2) {
+        int bn = 0;
+        for(i=0; i<num_tx_data_bytes; i++) {
+            for (b=0; b<8; b++) {
+                bn++;
+                if ((bn % 12) == 0) {
+                    unsigned char mask = (1<<(7-b));
+                    #ifdef DEBUG1
+                    fprintf("mask: 0x%x tx[%d] = 0x%x ", mask, i, tx[i]);
+                    #endif
+                    tx[i] ^= mask;
+                    #ifdef DEBUG1
+                    fprintf("0x%x\n", tx[i]);
+                    #endif
+                    nbiterrors++;
+                }
+            }
+        }
+    }
+
+    #ifdef DEBUG0
+    fprintf(stderr, "\nTx Data after errors:\n");
+    for(i=0; i<num_tx_data_bytes; i++)
+        fprintf(stderr, "  %02d 0x%02x\n", i, tx[i]);
+    #endif
+
+    #ifdef DEBUG0
+    fprintf(stderr, "nbiterrors: %d BER: %3.2f\n", nbiterrors, (float)nbiterrors/(num_tx_data_bytes*8));
+    #endif
+
+    golay23_init();
+    horus_l2_decode_rx_packet(output_payload, tx, sizeof(input_payload));
+
+    #ifdef DEBUG0
+    fprintf(stderr, "\nOutput Payload:\n");
+    for(i=0; i<sizeof(input_payload); i++)
+        fprintf(stderr, "  %02d 0x%02x\n", i, output_payload[i]);
+    #endif
+
+    /* count bit errors */
+
+    int nerr = 0;
+    for(i=0; i<nbytes; i++) {
+        int error_pattern = input_payload[i] ^ output_payload[i];
+        for(b=0; b<8; b++)
+            nerr += (error_pattern>>b) & 0x1;
+    }
+    
+    return nerr;
+}
+
+/* unit test designed to run on a PC */
+
+int main(void) {
+    printf("test 0: BER: 0.00 ...........: %d\n", test_sending_bytes(22, 0.00, 0));
+    printf("test 1: BER: 0.01 ...........: %d\n", test_sending_bytes(22, 0.01, 0));
+    printf("test 2: BER: 0.05 ...........: %d\n", test_sending_bytes(22, 0.05, 0));
+
+    /* we expect this always to fail, as chance of > 3 errors/codeword is high */
+
+    printf("test 3: BER: 0.10 ...........: %d\n", test_sending_bytes(22, 0.10, 0));
+
+    /* -DINTERLEAVER will make this puppy pass */
+
+    printf("test 4: 8 bit burst error....: %d\n", test_sending_bytes(22, 0.00, 1));
+
+    /* Insert 2 errors in every codeword, the maximum correction
+       capability of a Golay (23,12) code. note this one will fail
+       with -DINTERLEAVER, as we can't guarantee <= 3 errors per
+       codeword after interleaving */
+
+    printf("test 5: 1 error every 12 bits: %d\n", test_sending_bytes(22, 0.00, 2));
+    return 0;
+}
+#endif
+
+/* Horus binary packet */
+
+struct TBinaryPacket
+{
+    uint8_t     PayloadID;
+    uint16_t   Counter;
+    uint8_t    Hours;
+    uint8_t    Minutes;
+    uint8_t    Seconds;
+    float      Latitude;
+    float      Longitude;
+    uint16_t   Altitude;
+    uint8_t     Speed;       // Speed in Knots (1-255 knots)
+    uint8_t     Sats;
+    int8_t      Temp;        // Twos Complement Temp value.
+    uint8_t     BattVoltage; // 0 = 0.5v, 255 = 2.0V, linear steps in-between.
+    uint16_t    Checksum;    // CRC16-CCITT Checksum.
+}  __attribute__ ((packed));
+
+#ifdef GEN_TX_BITS
+/* generate a file of tx_bits to modulate using fsk_horus.m for modem simulations */
+
+int main(void) {
+    int nbytes = sizeof(struct TBinaryPacket);
+    struct TBinaryPacket input_payload;
+    int num_tx_data_bytes = horus_l2_get_num_tx_data_bytes(nbytes);
+    unsigned char tx[num_tx_data_bytes];
+    int i;
+
+    /* all zeros is nastiest sequence for demod before scrambling */
+
+    memset(&input_payload, 0, nbytes);
+    input_payload.Checksum = gen_crc16((unsigned char*)&input_payload, nbytes-2);
+
+    horus_l2_encode_tx_packet(tx, (unsigned char*)&input_payload, nbytes);
+    
+    FILE *f = fopen("../octave/horus_tx_bits_binary.txt","wt");
+    assert(f != NULL);
+    int b, tx_bit;
+    for(i=0; i<num_tx_data_bytes; i++) {
+        for(b=0; b<8; b++) {
+            tx_bit = (tx[i] >> (7-b)) & 0x1; /* msb first */
+            fprintf(f,"%d ", tx_bit);
+        }
+    }
+    fclose(f);
+
+    return 0;
+}
+#endif
+
+
+#ifdef DEC_RX_BITS
+
+/* Decode a binary file rx_bytes, e.g. from fsk_horus.m */
+
+int main(void) {
+    int nbytes = 22;
+    unsigned char output_payload[nbytes];
+    int num_tx_data_bytes = horus_l2_get_num_tx_data_bytes(nbytes);
+
+    /* real world data horus payload generated when running tx above */
+    unsigned char rx[45] = {
+        0x24,0x24,0x01,0x0b,0x00,0x00,0x05,0x3b,0xf2,0xa7,0x0b,0xc2,0x1b,
+        0xaa,0x0a,0x43,0x7e,0x00,0x05,0x00,0x25,0xc0,0xce,0xbb,0x36,0x69,
+        0x50,0x00,0x41,0xb0,0xa6,0x5e,0x91,0xa2,0xa3,0xf8,0x1d,0x00,0x00,
+        0x0c,0x76,0xc6,0x05,0xb0,0xb8};
+    int i, ret;
+
+    assert(num_tx_data_bytes == 45);
+
+    #define READ_FILE /* overwrite tx[] above, that's OK */
+    #ifdef READ_FILE
+    FILE *f = fopen("../octave/horus_rx_bits_binary.bin","rb");
+    assert(f != NULL);
+    ret = fread(rx, sizeof(char), num_tx_data_bytes, f);
+    assert(ret == num_tx_data_bytes);
+    fclose(f);
+    #endif
+
+    golay23_init();
+    horus_l2_decode_rx_packet(output_payload, rx, nbytes);
+
+    #ifdef HEX_DUMP
+    fprintf(stderr, "\nOutput Payload:\n");
+    for(i=0; i<nbytes; i++)
+        fprintf(stderr, "  %02d 0x%02x 0x%02x\n", i, output_payload[i], rx[i+2]);
+    #endif
+
+    struct TBinaryPacket h;
+    assert(sizeof(h) == nbytes);
+    memcpy(&h, output_payload, nbytes);
+
+    uint16_t crc_rx = gen_crc16(output_payload, nbytes-2);
+    char crc_str[80];
+    
+    if (crc_rx == h.Checksum) {
+        sprintf(crc_str, "CRC OK");
+    } else {
+        sprintf(crc_str, "CRC BAD");
+    }
+
+    fprintf(stderr, "%d,%d,%02d:%02d:%02d,%f,%f,%d,%d,%d,%d,%d,%04x %s\n",
+        h.PayloadID, h.Counter, h.Hours, h.Minutes, h.Seconds,
+        h.Latitude, h.Longitude, h.Altitude, h.Speed, h.Sats, h.Temp, 
+            h.BattVoltage, h.Checksum, crc_str);
+    
+    /* Hex ASCII file output */
+
+    #define WRITE_HEX_FILE /* overwrite tx[] above, that's OK */
+    #ifdef WRITE_HEX_FILE
+    FILE *fh = fopen("../octave/horus_rx_bits_hex.txt","wt");
+    assert(fh != NULL);
+    for(i=0; i<nbytes; i++) {
+        fprintf(fh, "%02X", (unsigned int)output_payload[i]);
+    }
+    fclose(fh);
+    #endif
+
+    return 0;
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+                                   GOLAY FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+/* File:    golay23.c
+ * Title:   Encoder/decoder for a binary (23,12,7) Golay code
+ * Author:  Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu)
+ * Date:    August 1994
+ *
+ * The binary (23,12,7) Golay code is an example of a perfect code, that is,
+ * the number of syndromes equals the number of correctable error patterns.
+ * The minimum distance is 7, so all error patterns of Hamming weight up to
+ * 3 can be corrected. The total number of these error patterns is:
+ *
+ *       Number of errors         Number of patterns
+ *       ----------------         ------------------
+ *              0                         1
+ *              1                        23
+ *              2                       253
+ *              3                      1771
+ *                                     ----
+ *    Total number of error patterns = 2048 = 2^{11} = number of syndromes
+ *                                               --
+ *                number of redundant bits -------^
+ *
+ * Because of its relatively low length (23), dimension (12) and number of
+ * redundant bits (11), the binary (23,12,7) Golay code can be encoded and
+ * decoded simply by using look-up tables. The program below uses a 16K
+ * encoding table and an 8K decoding table.
+ *
+ * For more information, suggestions, or other ideas on implementing error
+ * correcting codes, please contact me at (I'm temporarily in Japan, but
+ * below is my U.S. address):
+ *
+ *                    Robert Morelos-Zaragoza
+ *                    770 S. Post Oak Ln. #200
+ *                      Houston, Texas 77056
+ *
+ *             email: robert@spectra.eng.hawaii.edu
+ *
+ *       Homework: Add an overall parity-check bit to get the (24,12,8)
+ *                 extended Golay code.
+ *
+ * COPYRIGHT NOTICE: This computer program is free for non-commercial purposes.
+ * You may implement this program for any non-commercial application. You may
+ * also implement this program for commercial purposes, provided that you
+ * obtain my written permission. Any modification of this program is covered
+ * by this copyright.
+ *
+ * ==   Copyright (c) 1994  Robert Morelos-Zaragoza. All rights reserved.   ==
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#define X22             0x00400000   /* vector representation of X^{22} */
+#define X11             0x00000800   /* vector representation of X^{11} */
+#define MASK12          0xfffff800   /* auxiliary vector for testing */
+#define GENPOL          0x00000c75   /* generator polinomial, g(x) */
+
+/* Global variables:
+ *
+ * pattern = error pattern, or information, or received vector
+ * encoding_table[] = encoding table
+ * decoding_table[] = decoding table
+ * data = information bits, i(x)
+ * codeword = code bits = x^{11}i(x) + (x^{11}i(x) mod g(x))
+ * numerr = number of errors = Hamming weight of error polynomial e(x)
+ * position[] = error positions in the vector representation of e(x)
+ * recd = representation of corrupted received polynomial r(x) = c(x) + e(x)
+ * decerror = number of decoding errors
+ * a[] = auxiliary array to generate correctable error patterns
+ */
+
+#ifdef HORUS_L2_RX
+static int inited =  0;
+
+#ifdef RUN_TIME_TABLES
+static int encoding_table[4096], decoding_table[2048];
+#else
+#include "golayenctable.h"
+#include "golaydectable.h"
+#endif
+
+#ifdef RUN_TIME_TABLES
+static int arr2int(int a[], int r)
+/*
+ * Convert a binary vector of Hamming weight r, and nonzero positions in
+ * array a[1]...a[r], to a long integer \sum_{i=1}^r 2^{a[i]-1}.
+ */
+{
+   int i;
+   long mul, result = 0, temp;
+
+   for (i=1; i<=r; i++) {
+      mul = 1;
+      temp = a[i]-1;
+      while (temp--)
+         mul = mul << 1;
+      result += mul;
+      }
+   return(result);
+}
+#endif
+#endif
+
+#ifdef HORUS_L2_RX
+void nextcomb(int n, int r, int a[])
+/*
+ * Calculate next r-combination of an n-set.
+ */
+{
+  int  i, j;
+
+  a[r]++;
+  if (a[r] <= n)
+      return;
+  j = r - 1;
+  while (a[j] == n - r + j)
+     j--;
+  for (i = r; i >= j; i--)
+      a[i] = a[j] + i - j + 1;
+  return;
+}
+#endif
+
+int32_t get_syndrome(int32_t pattern)
+/*
+ * Compute the syndrome corresponding to the given pattern, i.e., the
+ * remainder after dividing the pattern (when considering it as the vector
+ * representation of a polynomial) by the generator polynomial, GENPOL.
+ * In the program this pattern has several meanings: (1) pattern = infomation
+ * bits, when constructing the encoding table; (2) pattern = error pattern,
+ * when constructing the decoding table; and (3) pattern = received vector, to
+ * obtain its syndrome in decoding.
+ */
+{
+    int32_t aux = X22;
+
+    if (pattern >= X11)
+       while (pattern & MASK12) {
+           while (!(aux & pattern))
+              aux = aux >> 1;
+           pattern ^= (aux/X11) * GENPOL;
+           }
+    return(pattern);
+}
+
+#ifdef HORUS_L2_RX
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: golay23_init()
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 March 2013
+
+  Call this once when you start your program to init the Golay tables.
+
+\*---------------------------------------------------------------------------*/
+
+void golay23_init(void) {
+#ifdef RUN_TIME_TABLES
+   int  i;
+   long temp;
+   int  a[4];
+   int  pattern;
+
+   /*
+    * ---------------------------------------------------------------------
+    *                  Generate ENCODING TABLE
+    *
+    * An entry to the table is an information vector, a 32-bit integer,
+    * whose 12 least significant positions are the information bits. The
+    * resulting value is a codeword in the (23,12,7) Golay code: A 32-bit
+    * integer whose 23 least significant bits are coded bits: Of these, the
+    * 12 most significant bits are information bits and the 11 least
+    * significant bits are redundant bits (systematic encoding).
+    * ---------------------------------------------------------------------
+    */
+    for (pattern = 0; pattern < 4096; pattern++) {
+        temp = pattern << 11;          /* multiply information by X^{11} */
+        encoding_table[pattern] = temp + get_syndrome(temp);/* add redundancy */
+        }
+
+   /*
+    * ---------------------------------------------------------------------
+    *                  Generate DECODING TABLE
+    *
+    * An entry to the decoding table is a syndrome and the resulting value
+    * is the most likely error pattern. First an error pattern is generated.
+    * Then its syndrome is calculated and used as a pointer to the table
+    * where the error pattern value is stored.
+    * ---------------------------------------------------------------------
+    *
+    * (1) Error patterns of WEIGHT 1 (SINGLE ERRORS)
+    */
+    decoding_table[0] = 0;
+    decoding_table[1] = 1;
+    temp = 1;
+    for (i=2; i<= 23; i++) {
+        temp *= 2;
+        decoding_table[get_syndrome(temp)] = temp;
+        }
+   /*
+    * (2) Error patterns of WEIGHT 2 (DOUBLE ERRORS)
+    */
+    a[1] = 1; a[2] = 2;
+    temp = arr2int(a,2);
+    decoding_table[get_syndrome(temp)] = temp;
+    for (i=1; i<253; i++) {
+        nextcomb(23,2,a);
+        temp = arr2int(a,2);
+        decoding_table[get_syndrome(temp)] = temp;
+        }
+   /*
+    * (3) Error patterns of WEIGHT 3 (TRIPLE ERRORS)
+    */
+    a[1] = 1; a[2] = 2; a[3] = 3;
+    temp = arr2int(a,3);
+    decoding_table[get_syndrome(temp)] = temp;
+    for (i=1; i<1771; i++) {
+        nextcomb(23,3,a);
+        temp = arr2int(a,3);
+        decoding_table[get_syndrome(temp)] = temp;
+    }
+#endif
+    inited = 1;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: golay23_encode()
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 March 2013
+
+  Given 12 bits of data retiurns a 23 bit codeword for transmission
+  over the channel.
+
+\*---------------------------------------------------------------------------*/
+
+int golay23_encode(int data) {
+    assert(inited);
+    assert(data <= 0xfff);
+
+    //printf("data: 0x%x\n", data);
+    return encoding_table[data];
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: golay23_decode()
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 March 2013
+
+  Given a 23 bit received codeword, returns the 12 bit corrected data.
+
+\*---------------------------------------------------------------------------*/
+
+int golay23_decode(int received_codeword) {
+    assert(inited);
+    assert((received_codeword < (1<<23)) && (received_codeword >= 0));
+
+    //printf("syndrome: 0x%x\n", get_syndrome(received_codeword));
+    return received_codeword ^= decoding_table[get_syndrome(received_codeword)];
+}
+
+int golay23_count_errors(int recd_codeword, int corrected_codeword)
+{
+    int errors = 0;
+    int diff, i;
+
+    diff = recd_codeword ^ corrected_codeword;
+    for(i=0; i<23; i++) {
+        if (diff & 0x1)
+            errors++;
+        diff >>= 1;
+    }
+
+    return errors;
+}
+
+#endif
+
+// from http://stackoverflow.com/questions/10564491/function-to-calculate-a-crc16-checksum
+
+unsigned short gen_crc16(unsigned char* data_p, unsigned char length){
+    unsigned char x;
+    unsigned short crc = 0xFFFF;
+
+    while (length--){
+        x = crc >> 8 ^ *data_p++;
+        x ^= x>>4;
+        crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x <<5)) ^ ((unsigned short)x);
+    }
+    return crc;
+}
+
diff --git a/codec2/branches/0.7/src/horus_l2.h b/codec2/branches/0.7/src/horus_l2.h
new file mode 100644 (file)
index 0000000..7ded29a
--- /dev/null
@@ -0,0 +1,23 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: horus_l2.h
+  AUTHOR......: David Rowe
+  DATE CREATED: Dec 2015
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef __HORUS_L2__
+#define __HORUS_L2__
+
+int horus_l2_get_num_tx_data_bytes(int num_payload_data_bytes);
+
+/* returns number of output bytes in output_tx_data */
+int horus_l2_encode_tx_packet(unsigned char *output_tx_data,
+                              unsigned char *input_payload_data,
+                              int            num_payload_data_bytes);
+
+void horus_l2_decode_rx_packet(unsigned char *output_payload_data,
+                               unsigned char *input_rx_data,
+                               int            num_payload_data_bytes);
+
+#endif
diff --git a/codec2/branches/0.7/src/ht_coeff.h b/codec2/branches/0.7/src/ht_coeff.h
new file mode 100644 (file)
index 0000000..98c5c6e
--- /dev/null
@@ -0,0 +1,107 @@
+/* Hilbert Transform FIR filter coeffs */
+/* Generated by make_hilb Octave script */
+
+#define HT_N 100
+
+COMP ht_coeff[]={
+  {0.000000,0.000000},
+  {-0.000000,-0.000001},
+  {0.000000,0.000000},
+  {-0.000000,-0.000017},
+  {0.000000,0.000000},
+  {0.000000,-0.000079},
+  {0.000000,0.000000},
+  {0.000000,-0.000217},
+  {0.000000,0.000000},
+  {0.000000,-0.000461},
+  {0.000000,0.000000},
+  {-0.000000,-0.000842},
+  {0.000000,0.000000},
+  {-0.000000,-0.001391},
+  {0.000000,0.000000},
+  {-0.000000,-0.002140},
+  {0.000000,0.000000},
+  {-0.000000,-0.003121},
+  {0.000000,0.000000},
+  {0.000000,-0.004371},
+  {0.000000,0.000000},
+  {0.000000,-0.005928},
+  {0.000000,0.000000},
+  {-0.000000,-0.007839},
+  {0.000000,0.000000},
+  {-0.000000,-0.010159},
+  {0.000000,0.000000},
+  {-0.000000,-0.012957},
+  {0.000000,0.000000},
+  {-0.000000,-0.016327},
+  {0.000000,0.000000},
+  {0.000000,-0.020399},
+  {0.000000,0.000000},
+  {-0.000000,-0.025364},
+  {0.000000,0.000000},
+  {0.000000,-0.031512},
+  {0.000000,0.000000},
+  {0.000000,-0.039319},
+  {0.000000,0.000000},
+  {0.000000,-0.049610},
+  {0.000000,0.000000},
+  {-0.000000,-0.063952},
+  {0.000000,0.000000},
+  {-0.000000,-0.085722},
+  {0.000000,0.000000},
+  {0.000000,-0.123718},
+  {0.000000,0.000000},
+  {0.000000,-0.210249},
+  {0.000000,0.000000},
+  {-0.000000,-0.636250},
+  {0.999748,0.000000},
+  {0.000000,0.634969},
+  {0.000000,0.000000},
+  {0.000000,0.208979},
+  {0.000000,0.000000},
+  {0.000000,0.122467},
+  {0.000000,0.000000},
+  {-0.000000,0.084502},
+  {0.000000,0.000000},
+  {0.000000,0.062771},
+  {0.000000,0.000000},
+  {0.000000,0.048477},
+  {0.000000,0.000000},
+  {0.000000,0.038242},
+  {0.000000,0.000000},
+  {-0.000000,0.030497},
+  {0.000000,0.000000},
+  {0.000000,0.024418},
+  {0.000000,0.000000},
+  {0.000000,0.019527},
+  {0.000000,0.000000},
+  {-0.000000,0.015532},
+  {0.000000,0.000000},
+  {0.000000,0.012242},
+  {0.000000,0.000000},
+  {-0.000000,0.009524},
+  {0.000000,0.000000},
+  {-0.000000,0.007285},
+  {0.000000,0.000000},
+  {-0.000000,0.005454},
+  {0.000000,0.000000},
+  {-0.000000,0.003973},
+  {0.000000,0.000000},
+  {0.000000,0.002796},
+  {0.000000,0.000000},
+  {-0.000000,0.001882},
+  {0.000000,0.000000},
+  {-0.000000,0.001196},
+  {0.000000,0.000000},
+  {-0.000000,0.000701},
+  {0.000000,0.000000},
+  {0.000000,0.000367},
+  {0.000000,0.000000},
+  {0.000000,0.000160},
+  {0.000000,0.000000},
+  {0.000000,0.000051},
+  {0.000000,0.000000},
+  {-0.000000,0.000008},
+  {0.000000,0.000000},
+  {0.000000,0.000000}
+};
\ No newline at end of file
diff --git a/codec2/branches/0.7/src/insert_errors.c b/codec2/branches/0.7/src/insert_errors.c
new file mode 100644 (file)
index 0000000..7567903
--- /dev/null
@@ -0,0 +1,120 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: insert_errors.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 20/2/2013
+
+  Inserts errors into a Codec 2 bit stream using error files.  The
+  error files have one 16 bit short per bit, the short is set to 1 if
+  there is an error, or zero otherwise.  The Codec 2 bit stream files
+  are in packed format, i.e. c2enc/c2dec format.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int main(int argc, char *argv[])
+{
+    FILE          *fin;
+    FILE          *fout;
+    FILE          *ferror;
+    int            i, start_bit, end_bit, bit;
+    unsigned char  byte;
+    short          error;
+    int            errors, bits;
+    int            bits_per_frame;
+
+    if (argc < 4) {
+       printf("%s InputBitFile OutputBitFile ErrorFile bitsPerFrame [startBit endBit]\n", argv[0]);
+       printf("%s InputBitFile OutputBitFile BER\n", argv[0]);
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input bit 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 speech file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if ((ferror = fopen(argv[3],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening error file: %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    bits_per_frame = atoi(argv[4]);
+
+    start_bit = 0; end_bit = bits_per_frame;
+    if (argc == 7) {
+       start_bit = atoi(argv[5]);
+       end_bit = atoi(argv[6]);
+    }
+
+    bit = 0;
+    bits = errors = 0;
+
+    while(fread(&byte, sizeof(char), 1, fin) == 1) {
+
+        for(i=0; i<8; i++, bits++) {
+            if (bits != bits_per_frame) {
+                if (fread(&error, sizeof(short), 1, ferror)) {
+                    if ((bit >= start_bit) && (bit <= end_bit))
+                        byte ^= error << (7-i);
+                    if (error)
+                        errors++;
+                }
+                else {
+                    fprintf(stderr,"bits: %d ber: %4.3f\n", bits, (float)errors/bits);
+                    fclose (fin); fclose(fout); fclose(ferror);
+                    exit(0);
+                }
+            }
+        }
+
+        fwrite(&byte, sizeof(char), 1, fout);
+        if (bits == bits_per_frame)
+            bits = 0;
+        if (fout == stdout) fflush(stdout);
+        if (fin == stdin) fflush(stdin);
+
+    }
+
+    fclose(fin);
+    fclose(fout);
+    fclose(ferror);
+
+    fprintf(stderr,"bits: %d ber: %4.3f\n", bits, (float)errors/bits);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/interp.c b/codec2/branches/0.7/src/interp.c
new file mode 100644 (file)
index 0000000..31ab4d7
--- /dev/null
@@ -0,0 +1,331 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: interp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 9/10/09
+
+  Interpolation of 20ms frames to 10ms frames.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "defines.h"
+#include "interp.h"
+#include "lsp.h"
+#include "quantise.h"
+
+float sample_log_amp(MODEL *model, float w);
+
+#if 0
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/10
+
+  Given two frames decribed by model parameters 20ms apart, determines
+  the model parameters of the 10ms frame between them.  Assumes
+  voicing is available for middle (interpolated) frame.  Outputs are
+  amplitudes and Wo for the interpolated frame.
+
+  This version can interpolate the amplitudes between two frames of
+  different Wo and L.
+
+  This version works by log linear interpolation, but listening tests
+  showed it creates problems in background noise, e.g. hts2a and mmt1.
+  When this function is used (--dec mode) bg noise appears to be
+  amplitude modulated, and gets louder.  The interp_lsp() function
+  below seems to do a better job.
+
+\*---------------------------------------------------------------------------*/
+
+void interpolate(
+  MODEL *interp,    /* interpolated model params                     */
+  MODEL *prev,      /* previous frames model params                  */
+  MODEL *next,      /* next frames model params                      */
+  float Wo_min 
+)
+{
+    int   l;
+    float w,log_amp;
+
+    /* Wo depends on voicing of this and adjacent frames */
+
+    if (interp->voiced) {
+       if (prev->voiced && next->voiced)
+           interp->Wo = (prev->Wo + next->Wo)/2.0;
+       if (!prev->voiced && next->voiced)
+           interp->Wo = next->Wo;
+       if (prev->voiced && !next->voiced)
+           interp->Wo = prev->Wo;
+    }
+    else {
+       interp->Wo = Wo_min;
+    }
+    interp->L = PI/interp->Wo;
+
+    /* Interpolate amplitudes using linear interpolation in log domain */
+
+    for(l=1; l<=interp->L; l++) {
+       w = l*interp->Wo;
+       log_amp = (sample_log_amp(prev, w) + sample_log_amp(next, w))/2.0;
+       interp->A[l] = powf(10.0, log_amp);
+    }
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: sample_log_amp()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/10
+
+  Samples the amplitude envelope at an arbitrary frequency w.  Uses
+  linear interpolation in the log domain to sample between harmonic
+  amplitudes.
+
+\*---------------------------------------------------------------------------*/
+
+float sample_log_amp(MODEL *model, float w)
+{
+    int   m;
+    float f, log_amp;
+
+    assert(w > 0.0); assert (w <= PI);
+
+    m = floorf(w/model->Wo + 0.5);
+    f = (w - m*model->Wo)/w;
+    assert(f <= 1.0);
+
+    if (m < 1) {
+       log_amp = f*log10f(model->A[1] + 1E-6);
+    }
+    else if ((m+1) > model->L) {
+       log_amp = (1.0-f)*log10f(model->A[model->L] + 1E-6);
+    }
+    else {
+       log_amp = (1.0-f)*log10f(model->A[m] + 1E-6) +
+                  f*log10f(model->A[m+1] + 1E-6);
+    }
+
+    return log_amp;
+}
+
+#ifdef NOT_NEEDED
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_lsp()
+  AUTHOR......: David Rowe
+  DATE CREATED: 10 Nov 2010
+
+  Given two frames decribed by model parameters 20ms apart, determines
+  the model parameters of the 10ms frame between them.  Assumes
+  voicing is available for middle (interpolated) frame.  Outputs are
+  amplitudes and Wo for the interpolated frame.
+
+  This version uses interpolation of LSPs, seems to do a better job
+  with bg noise.
+
+\*---------------------------------------------------------------------------*/
+
+void interpolate_lsp(
+  codec2_fft_cfg  fft_fwd_cfg,
+  MODEL *interp,      /* interpolated model params                     */
+  MODEL *prev,        /* previous frames model params                  */
+  MODEL *next,        /* next frames model params                      */
+  float *prev_lsps,   /* previous frames LSPs                          */
+  float  prev_e,      /* previous frames LPC energy                    */
+  float *next_lsps,   /* next frames LSPs                              */
+  float  next_e,      /* next frames LPC energy                        */
+  float *ak_interp,   /* interpolated aks for this frame               */
+  float *lsps_interp, /* interpolated lsps for this frame              */
+  float  Wo_min
+)
+{
+    int   i;
+    float e;
+    float snr;
+
+    /* trap corner case where V est is probably wrong */
+
+    if (interp->voiced && !prev->voiced && !next->voiced) {
+       interp->voiced = 0;
+    }
+
+    /* Wo depends on voicing of this and adjacent frames */
+
+    if (interp->voiced) {
+       if (prev->voiced && next->voiced)
+           interp->Wo = (prev->Wo + next->Wo)/2.0;
+       if (!prev->voiced && next->voiced)
+           interp->Wo = next->Wo;
+       if (prev->voiced && !next->voiced)
+           interp->Wo = prev->Wo;
+    }
+    else {
+       interp->Wo = Wo_min;
+    }
+    interp->L = PI/interp->Wo;
+
+    //printf("  interp: prev_v: %d next_v: %d prev_Wo: %f next_Wo: %f\n",
+    //    prev->voiced, next->voiced, prev->Wo, next->Wo);
+    //printf("  interp: Wo: %1.5f  L: %d\n", interp->Wo, interp->L);
+
+    /* interpolate LSPs */
+
+    for(i=0; i<LPC_ORD; i++) {
+       lsps_interp[i] = (prev_lsps[i] + next_lsps[i])/2.0;
+    }
+
+    /* Interpolate LPC energy in log domain */
+
+    e = powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0);
+    //printf("  interp: e: %f\n", e);
+
+    /* convert back to amplitudes */
+
+    lsp_to_lpc(lsps_interp, ak_interp, LPC_ORD);
+    aks_to_M2(fft_fwd_cfg, ak_interp, LPC_ORD, interp, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA);
+    //printf("  interp: ak[1]: %f A[1] %f\n", ak_interp[1], interp->A[1]);
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_Wo()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22 May 2012
+
+  Interpolates centre 10ms sample of Wo and L samples given two
+  samples 20ms apart. Assumes voicing is available for centre
+  (interpolated) frame.
+
+\*---------------------------------------------------------------------------*/
+
+void interp_Wo(
+  MODEL *interp,    /* interpolated model params                     */
+  MODEL *prev,      /* previous frames model params                  */
+  MODEL *next,      /* next frames model params                      */
+  float  Wo_min
+              )
+{
+    interp_Wo2(interp, prev, next, 0.5, Wo_min);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_Wo2()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22 May 2012
+
+  Weighted interpolation of two Wo samples.
+
+\*---------------------------------------------------------------------------*/
+
+void interp_Wo2(
+  MODEL *interp,    /* interpolated model params                     */
+  MODEL *prev,      /* previous frames model params                  */
+  MODEL *next,      /* next frames model params                      */
+  float  weight,
+  float  Wo_min
+)
+{
+    /* trap corner case where voicing est is probably wrong */
+
+    if (interp->voiced && !prev->voiced && !next->voiced) {
+       interp->voiced = 0;
+    }
+
+    /* Wo depends on voicing of this and adjacent frames */
+
+    if (interp->voiced) {
+       if (prev->voiced && next->voiced)
+           interp->Wo = (1.0 - weight)*prev->Wo + weight*next->Wo;
+       if (!prev->voiced && next->voiced)
+           interp->Wo = next->Wo;
+       if (prev->voiced && !next->voiced)
+           interp->Wo = prev->Wo;
+    }
+    else {
+       interp->Wo = Wo_min;
+    }
+    interp->L = PI/interp->Wo;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_energy()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22 May 2012
+
+  Interpolates centre 10ms sample of energy given two samples 20ms
+  apart.
+
+\*---------------------------------------------------------------------------*/
+
+float interp_energy(float prev_e, float next_e)
+{
+    //return powf(10.0, (log10f(prev_e) + log10f(next_e))/2.0);
+    return sqrtf(prev_e * next_e); //looks better is math. identical and faster math
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_energy2()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22 May 2012
+
+  Interpolates centre 10ms sample of energy given two samples 20ms
+  apart.
+
+\*---------------------------------------------------------------------------*/
+
+float interp_energy2(float prev_e, float next_e, float weight)
+{
+    return powf(10.0, (1.0 - weight)*log10f(prev_e) + weight*log10f(next_e));
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interpolate_lsp_ver2()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22 May 2012
+
+  Weighted interpolation of LSPs.
+
+\*---------------------------------------------------------------------------*/
+
+void interpolate_lsp_ver2(float interp[], float prev[],  float next[], float weight, int order)
+{
+    int i;
+
+    for(i=0; i<order; i++)
+       interp[i] = (1.0 - weight)*prev[i] + weight*next[i];
+}
+
diff --git a/codec2/branches/0.7/src/interp.h b/codec2/branches/0.7/src/interp.h
new file mode 100644 (file)
index 0000000..1247b7e
--- /dev/null
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: interp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 9/10/09
+
+  Interpolation of 20ms frames to 10ms frames.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __INTERP__
+#define __INTERP__
+
+#include "kiss_fft.h"
+
+void interpolate(MODEL *interp, MODEL *prev, MODEL *next);
+void interpolate_lsp(kiss_fft_cfg  fft_dec_cfg,
+                    MODEL *interp, MODEL *prev, MODEL *next,
+                    float *prev_lsps, float  prev_e,
+                    float *next_lsps, float  next_e,
+                    float *ak_interp, float *lsps_interp, float Wo_min);
+void interp_Wo(MODEL *interp, MODEL *prev, MODEL *next, float Wo_min);
+void interp_Wo2(MODEL *interp, MODEL *prev, MODEL *next, float weight, float Wo_min);
+float interp_energy(float prev, float next);
+float interp_energy2(float prev, float next, float weight);
+void interpolate_lsp_ver2(float interp[], float prev[],  float next[], float weight, int order);
+
+#endif
diff --git a/codec2/branches/0.7/src/kiss_fft.c b/codec2/branches/0.7/src/kiss_fft.c
new file mode 100644 (file)
index 0000000..05f7f27
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+Copyright (c) 2003-2010, Mark Borgerding
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+#include "_kiss_fft_guts.h"
+/* The guts header contains all the multiplication and addition macros that are defined for
+ fixed or floating point complex numbers.  It also delares the kf_ internal functions.
+ */
+
+static void kf_bfly2(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        int m
+        )
+{
+    kiss_fft_cpx * Fout2;
+    kiss_fft_cpx * tw1 = st->twiddles;
+    kiss_fft_cpx t;
+    Fout2 = Fout + m;
+    do{
+        C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2);
+
+        C_MUL (t,  *Fout2 , *tw1);
+        tw1 += fstride;
+        C_SUB( *Fout2 ,  *Fout , t );
+        C_ADDTO( *Fout ,  t );
+        ++Fout2;
+        ++Fout;
+    }while (--m);
+}
+
+static void kf_bfly4(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        const size_t m
+        )
+{
+    kiss_fft_cpx *tw1,*tw2,*tw3;
+    kiss_fft_cpx scratch[6];
+    size_t k=m;
+    const size_t m2=2*m;
+    const size_t m3=3*m;
+
+
+    tw3 = tw2 = tw1 = st->twiddles;
+
+    do {
+        C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4);
+
+        C_MUL(scratch[0],Fout[m] , *tw1 );
+        C_MUL(scratch[1],Fout[m2] , *tw2 );
+        C_MUL(scratch[2],Fout[m3] , *tw3 );
+
+        C_SUB( scratch[5] , *Fout, scratch[1] );
+        C_ADDTO(*Fout, scratch[1]);
+        C_ADD( scratch[3] , scratch[0] , scratch[2] );
+        C_SUB( scratch[4] , scratch[0] , scratch[2] );
+        C_SUB( Fout[m2], *Fout, scratch[3] );
+        tw1 += fstride;
+        tw2 += fstride*2;
+        tw3 += fstride*3;
+        C_ADDTO( *Fout , scratch[3] );
+
+        if(st->inverse) {
+            Fout[m].r = scratch[5].r - scratch[4].i;
+            Fout[m].i = scratch[5].i + scratch[4].r;
+            Fout[m3].r = scratch[5].r + scratch[4].i;
+            Fout[m3].i = scratch[5].i - scratch[4].r;
+        }else{
+            Fout[m].r = scratch[5].r + scratch[4].i;
+            Fout[m].i = scratch[5].i - scratch[4].r;
+            Fout[m3].r = scratch[5].r - scratch[4].i;
+            Fout[m3].i = scratch[5].i + scratch[4].r;
+        }
+        ++Fout;
+    }while(--k);
+}
+
+static void kf_bfly3(
+         kiss_fft_cpx * Fout,
+         const size_t fstride,
+         const kiss_fft_cfg st,
+         size_t m
+         )
+{
+     size_t k=m;
+     const size_t m2 = 2*m;
+     kiss_fft_cpx *tw1,*tw2;
+     kiss_fft_cpx scratch[5];
+     kiss_fft_cpx epi3;
+     epi3 = st->twiddles[fstride*m];
+
+     tw1=tw2=st->twiddles;
+
+     do{
+         C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3);
+
+         C_MUL(scratch[1],Fout[m] , *tw1);
+         C_MUL(scratch[2],Fout[m2] , *tw2);
+
+         C_ADD(scratch[3],scratch[1],scratch[2]);
+         C_SUB(scratch[0],scratch[1],scratch[2]);
+         tw1 += fstride;
+         tw2 += fstride*2;
+
+         Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+         Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
+
+         C_MULBYSCALAR( scratch[0] , epi3.i );
+
+         C_ADDTO(*Fout,scratch[3]);
+
+         Fout[m2].r = Fout[m].r + scratch[0].i;
+         Fout[m2].i = Fout[m].i - scratch[0].r;
+
+         Fout[m].r -= scratch[0].i;
+         Fout[m].i += scratch[0].r;
+
+         ++Fout;
+     }while(--k);
+}
+
+static void kf_bfly5(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        int m
+        )
+{
+    kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
+    int u;
+    kiss_fft_cpx scratch[13];
+    kiss_fft_cpx * twiddles = st->twiddles;
+    kiss_fft_cpx *tw;
+    kiss_fft_cpx ya,yb;
+    ya = twiddles[fstride*m];
+    yb = twiddles[fstride*2*m];
+
+    Fout0=Fout;
+    Fout1=Fout0+m;
+    Fout2=Fout0+2*m;
+    Fout3=Fout0+3*m;
+    Fout4=Fout0+4*m;
+
+    tw=st->twiddles;
+    for ( u=0; u<m; ++u ) {
+        C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5);
+        scratch[0] = *Fout0;
+
+        C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
+        C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
+        C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
+        C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
+
+        C_ADD( scratch[7],scratch[1],scratch[4]);
+        C_SUB( scratch[10],scratch[1],scratch[4]);
+        C_ADD( scratch[8],scratch[2],scratch[3]);
+        C_SUB( scratch[9],scratch[2],scratch[3]);
+
+        Fout0->r += scratch[7].r + scratch[8].r;
+        Fout0->i += scratch[7].i + scratch[8].i;
+
+        scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+        scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
+
+        scratch[6].r =  S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
+        scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
+
+        C_SUB(*Fout1,scratch[5],scratch[6]);
+        C_ADD(*Fout4,scratch[5],scratch[6]);
+
+        scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+        scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+        scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
+        scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
+
+        C_ADD(*Fout2,scratch[11],scratch[12]);
+        C_SUB(*Fout3,scratch[11],scratch[12]);
+
+        ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
+    }
+}
+
+/* perform the butterfly for one stage of a mixed radix FFT */
+static void kf_bfly_generic(
+        kiss_fft_cpx * Fout,
+        const size_t fstride,
+        const kiss_fft_cfg st,
+        int m,
+        int p
+        )
+{
+    int u,k,q1,q;
+    kiss_fft_cpx * twiddles = st->twiddles;
+    kiss_fft_cpx t;
+    int Norig = st->nfft;
+
+    kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p);
+
+    for ( u=0; u<m; ++u ) {
+        k=u;
+        for ( q1=0 ; q1<p ; ++q1 ) {
+            scratch[q1] = Fout[ k  ];
+            C_FIXDIV(scratch[q1],p);
+            k += m;
+        }
+
+        k=u;
+        for ( q1=0 ; q1<p ; ++q1 ) {
+            int twidx=0;
+            Fout[ k ] = scratch[0];
+            for (q=1;q<p;++q ) {
+                twidx += fstride * k;
+                if (twidx>=Norig) twidx-=Norig;
+                C_MUL(t,scratch[q] , twiddles[twidx] );
+                C_ADDTO( Fout[ k ] ,t);
+            }
+            k += m;
+        }
+    }
+    KISS_FFT_TMP_FREE(scratch);
+}
+
+static
+void kf_work(
+        kiss_fft_cpx * Fout,
+        const kiss_fft_cpx * f,
+        const size_t fstride,
+        int in_stride,
+        int * factors,
+        const kiss_fft_cfg st
+        )
+{
+    kiss_fft_cpx * Fout_beg=Fout;
+    const int p=*factors++; /* the radix  */
+    const int m=*factors++; /* stage's fft length/p */
+    const kiss_fft_cpx * Fout_end = Fout + p*m;
+
+#ifdef _OPENMP
+    // use openmp extensions at the
+    // top-level (not recursive)
+    if (fstride==1 && p<=5)
+    {
+        int k;
+
+        // execute the p different work units in different threads
+#       pragma omp parallel for
+        for (k=0;k<p;++k)
+            kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st);
+        // all threads have joined by this point
+
+        switch (p) {
+            case 2: kf_bfly2(Fout,fstride,st,m); break;
+            case 3: kf_bfly3(Fout,fstride,st,m); break;
+            case 4: kf_bfly4(Fout,fstride,st,m); break;
+            case 5: kf_bfly5(Fout,fstride,st,m); break;
+            default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+        }
+        return;
+    }
+#endif
+
+    if (m==1) {
+        do{
+            *Fout = *f;
+            f += fstride*in_stride;
+        }while(++Fout != Fout_end );
+    }else{
+        do{
+            // recursive call:
+            // DFT of size m*p performed by doing
+            // p instances of smaller DFTs of size m,
+            // each one takes a decimated version of the input
+            kf_work( Fout , f, fstride*p, in_stride, factors,st);
+            f += fstride*in_stride;
+        }while( (Fout += m) != Fout_end );
+    }
+
+    Fout=Fout_beg;
+
+    // recombine the p smaller DFTs
+    switch (p) {
+        case 2: kf_bfly2(Fout,fstride,st,m); break;
+        case 3: kf_bfly3(Fout,fstride,st,m); break;
+        case 4: kf_bfly4(Fout,fstride,st,m); break;
+        case 5: kf_bfly5(Fout,fstride,st,m); break;
+        default: kf_bfly_generic(Fout,fstride,st,m,p); break;
+    }
+}
+
+/*  facbuf is populated by p1,m1,p2,m2, ...
+    where
+    p[i] * m[i] = m[i-1]
+    m0 = n                  */
+static
+void kf_factor(int n,int * facbuf)
+{
+    int p=4;
+    double floor_sqrt;
+    floor_sqrt = floorf( sqrtf((double)n) );
+
+    /*factor out powers of 4, powers of 2, then any remaining primes */
+    do {
+        while (n % p) {
+            switch (p) {
+                case 4: p = 2; break;
+                case 2: p = 3; break;
+                default: p += 2; break;
+            }
+            if (p > floor_sqrt)
+                p = n;          /* no more factors, skip to end */
+        }
+        n /= p;
+        *facbuf++ = p;
+        *facbuf++ = n;
+    } while (n > 1);
+}
+
+/*
+ *
+ * User-callable function to allocate all necessary storage space for the fft.
+ *
+ * The return value is a contiguous block of memory, allocated with malloc.  As such,
+ * It can be freed with free(), rather than a kiss_fft-specific function.
+ * */
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem )
+{
+    kiss_fft_cfg st=NULL;
+    size_t memneeded = sizeof(struct kiss_fft_state)
+        + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/
+
+    if ( lenmem==NULL ) {
+        st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded );
+    }else{
+        if (mem != NULL && *lenmem >= memneeded)
+            st = (kiss_fft_cfg)mem;
+        *lenmem = memneeded;
+    }
+    if (st) {
+        int i;
+        st->nfft=nfft;
+        st->inverse = inverse_fft;
+
+        for (i=0;i<nfft;++i) {
+            const double pi=3.141592653589793238462643383279502884197169399375105820974944;
+            double phase = -2*pi*i / nfft;
+            if (st->inverse)
+                phase *= -1;
+            kf_cexp(st->twiddles+i, phase );
+        }
+
+        kf_factor(nfft,st->factors);
+    }
+    return st;
+}
+
+
+void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride)
+{
+    if (fin == fout) {
+        //NOTE: this is not really an in-place FFT algorithm.
+        //It just performs an out-of-place FFT into a temp buffer
+        kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft);
+        kf_work(tmpbuf,fin,1,in_stride, st->factors,st);
+        memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft);
+        KISS_FFT_TMP_FREE(tmpbuf);
+    }else{
+        kf_work( fout, fin, 1,in_stride, st->factors,st );
+    }
+}
+
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
+{
+    kiss_fft_stride(cfg,fin,fout,1);
+}
+
+
+void kiss_fft_cleanup(void)
+{
+    // nothing needed any more
+}
+
+int kiss_fft_next_fast_size(int n)
+{
+    while(1) {
+        int m=n;
+        while ( (m%2) == 0 ) m/=2;
+        while ( (m%3) == 0 ) m/=3;
+        while ( (m%5) == 0 ) m/=5;
+        if (m<=1)
+            break; /* n is completely factorable by twos, threes, and fives */
+        n++;
+    }
+    return n;
+}
diff --git a/codec2/branches/0.7/src/kiss_fft.h b/codec2/branches/0.7/src/kiss_fft.h
new file mode 100644 (file)
index 0000000..c01722c
--- /dev/null
@@ -0,0 +1,124 @@
+#ifndef KISS_FFT_H
+#define KISS_FFT_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ ATTENTION!
+ If you would like a :
+ -- a utility that will handle the caching of fft objects
+ -- real-only (no imaginary time component ) FFT
+ -- a multi-dimensional FFT
+ -- a command-line utility to perform ffts
+ -- a command-line utility to perform fast-convolution filtering
+
+ Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c
+  in the tools/ directory.
+*/
+
+#ifdef USE_SIMD
+# include <xmmintrin.h>
+# define kiss_fft_scalar __m128
+#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16)
+#define KISS_FFT_FREE _mm_free
+#else
+#define KISS_FFT_MALLOC malloc
+#define KISS_FFT_FREE free
+#endif
+
+
+#ifdef FIXED_POINT
+#include <sys/types.h>
+# if (FIXED_POINT == 32)
+#  define kiss_fft_scalar int32_t
+# else
+#  define kiss_fft_scalar int16_t
+# endif
+#else
+# ifndef kiss_fft_scalar
+/*  default is float */
+#   define kiss_fft_scalar float
+# endif
+#endif
+
+typedef struct {
+    kiss_fft_scalar r;
+    kiss_fft_scalar i;
+}kiss_fft_cpx;
+
+typedef struct kiss_fft_state* kiss_fft_cfg;
+
+/*
+ *  kiss_fft_alloc
+ *
+ *  Initialize a FFT (or IFFT) algorithm's cfg/state buffer.
+ *
+ *  typical usage:      kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL);
+ *
+ *  The return value from fft_alloc is a cfg buffer used internally
+ *  by the fft routine or NULL.
+ *
+ *  If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc.
+ *  The returned value should be free()d when done to avoid memory leaks.
+ *
+ *  The state can be placed in a user supplied buffer 'mem':
+ *  If lenmem is not NULL and mem is not NULL and *lenmem is large enough,
+ *      then the function places the cfg in mem and the size used in *lenmem
+ *      and returns mem.
+ *
+ *  If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough),
+ *      then the function returns NULL and places the minimum cfg
+ *      buffer size in *lenmem.
+ * */
+
+kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem);
+
+/*
+ * kiss_fft(cfg,in_out_buf)
+ *
+ * Perform an FFT on a complex input buffer.
+ * for a forward FFT,
+ * fin should be  f[0] , f[1] , ... ,f[nfft-1]
+ * fout will be   F[0] , F[1] , ... ,F[nfft-1]
+ * Note that each element is complex and can be accessed like
+    f[k].r and f[k].i
+ * */
+void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
+
+/*
+ A more generic version of the above function. It reads its input from every Nth sample.
+ * */
+void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride);
+
+/* If kiss_fft_alloc allocated a buffer, it is one contiguous
+   buffer and can be simply free()d when no longer needed*/
+#define kiss_fft_free free
+
+/*
+ Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up
+ your compiler output to call this before you exit.
+*/
+void kiss_fft_cleanup(void);
+
+
+/*
+ * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5)
+ */
+int kiss_fft_next_fast_size(int n);
+
+/* for real ffts, we need an even size */
+#define kiss_fftr_next_fast_size_real(n) \
+        (kiss_fft_next_fast_size( ((n)+1)>>1)<<1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/src/kiss_fftr.c b/codec2/branches/0.7/src/kiss_fftr.c
new file mode 100644 (file)
index 0000000..ca5d418
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+Copyright (c) 2003-2004, Mark Borgerding
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "kiss_fftr.h"
+#include "_kiss_fft_guts.h"
+#include "assert.h"
+
+struct kiss_fftr_state{
+    kiss_fft_cfg substate;
+    kiss_fft_cpx * tmpbuf;
+    kiss_fft_cpx * super_twiddles;
+#ifdef USE_SIMD
+    void * pad;
+#endif
+};
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem)
+{
+    int i;
+    kiss_fftr_cfg st = NULL;
+    size_t subsize, memneeded;
+
+    if (nfft & 1) {
+        fprintf(stderr,"Real FFT optimization must be even.\n");
+        return NULL;
+    }
+    nfft >>= 1;
+
+    kiss_fft_alloc (nfft, inverse_fft, NULL, &subsize);
+    memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft * 3 / 2);
+
+    if (lenmem == NULL) {
+        st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded);
+    } else {
+        if (*lenmem >= memneeded)
+            st = (kiss_fftr_cfg) mem;
+        *lenmem = memneeded;
+    }
+    if (!st)
+        return NULL;
+
+    st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */
+    st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize);
+    st->super_twiddles = st->tmpbuf + nfft;
+    kiss_fft_alloc(nfft, inverse_fft, st->substate, &subsize);
+
+    for (i = 0; i < nfft/2; ++i) {
+        double phase =
+            -3.14159265358979323846264338327 * ((double) (i+1) / nfft + .5);
+        if (inverse_fft)
+            phase *= -1;
+        kf_cexp (st->super_twiddles+i,phase);
+    }
+    return st;
+}
+
+void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata)
+{
+    /* input buffer timedata is stored row-wise */
+    int k,ncfft;
+    kiss_fft_cpx fpnk,fpk,f1k,f2k,tw,tdc;
+
+    assert(st->substate->inverse==0);
+
+    ncfft = st->substate->nfft;
+
+    /*perform the parallel fft of two real signals packed in real,imag*/
+    kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf );
+    /* The real part of the DC element of the frequency spectrum in st->tmpbuf
+     * contains the sum of the even-numbered elements of the input time sequence
+     * The imag part is the sum of the odd-numbered elements
+     *
+     * The sum of tdc.r and tdc.i is the sum of the input time sequence. 
+     *      yielding DC of input time sequence
+     * The difference of tdc.r - tdc.i is the sum of the input (dot product) [1,-1,1,-1... 
+     *      yielding Nyquist bin of input time sequence
+     */
+    tdc.r = st->tmpbuf[0].r;
+    tdc.i = st->tmpbuf[0].i;
+    C_FIXDIV(tdc,2);
+    CHECK_OVERFLOW_OP(tdc.r ,+, tdc.i);
+    CHECK_OVERFLOW_OP(tdc.r ,-, tdc.i);
+    freqdata[0].r = tdc.r + tdc.i;
+    freqdata[ncfft].r = tdc.r - tdc.i;
+#ifdef USE_SIMD    
+    freqdata[ncfft].i = freqdata[0].i = _mm_set1_ps(0);
+#else
+    freqdata[ncfft].i = freqdata[0].i = 0;
+#endif
+
+    for ( k=1;k <= ncfft/2 ; ++k ) {
+        fpk    = st->tmpbuf[k]; 
+        fpnk.r =   st->tmpbuf[ncfft-k].r;
+        fpnk.i = - st->tmpbuf[ncfft-k].i;
+        C_FIXDIV(fpk,2);
+        C_FIXDIV(fpnk,2);
+
+        C_ADD( f1k, fpk , fpnk );
+        C_SUB( f2k, fpk , fpnk );
+        C_MUL( tw , f2k , st->super_twiddles[k-1]);
+
+        freqdata[k].r = HALF_OF(f1k.r + tw.r);
+        freqdata[k].i = HALF_OF(f1k.i + tw.i);
+        freqdata[ncfft-k].r = HALF_OF(f1k.r - tw.r);
+        freqdata[ncfft-k].i = HALF_OF(tw.i - f1k.i);
+    }
+}
+
+void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata)
+{
+    /* input buffer timedata is stored row-wise */
+    int k, ncfft;
+
+    assert(st->substate->inverse == 1);
+
+    ncfft = st->substate->nfft;
+
+    st->tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;
+    st->tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;
+    C_FIXDIV(st->tmpbuf[0],2);
+
+    for (k = 1; k <= ncfft / 2; ++k) {
+        kiss_fft_cpx fk, fnkc, fek, fok, tmp;
+        fk = freqdata[k];
+        fnkc.r = freqdata[ncfft - k].r;
+        fnkc.i = -freqdata[ncfft - k].i;
+        C_FIXDIV( fk , 2 );
+        C_FIXDIV( fnkc , 2 );
+
+        C_ADD (fek, fk, fnkc);
+        C_SUB (tmp, fk, fnkc);
+        C_MUL (fok, tmp, st->super_twiddles[k-1]);
+        C_ADD (st->tmpbuf[k],     fek, fok);
+        C_SUB (st->tmpbuf[ncfft - k], fek, fok);
+#ifdef USE_SIMD        
+        st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0);
+#else
+        st->tmpbuf[ncfft - k].i *= -1;
+#endif
+    }
+    kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);
+}
diff --git a/codec2/branches/0.7/src/kiss_fftr.h b/codec2/branches/0.7/src/kiss_fftr.h
new file mode 100644 (file)
index 0000000..72e5a57
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef KISS_FTR_H
+#define KISS_FTR_H
+
+#include "kiss_fft.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+    
+/* 
+ Real optimized version can save about 45% cpu time vs. complex fft of a real seq.
+
+ */
+
+typedef struct kiss_fftr_state *kiss_fftr_cfg;
+
+
+kiss_fftr_cfg kiss_fftr_alloc(int nfft,int inverse_fft,void * mem, size_t * lenmem);
+/*
+ nfft must be even
+
+ If you don't care to allocate space, use mem = lenmem = NULL 
+*/
+
+
+void kiss_fftr(kiss_fftr_cfg cfg,const kiss_fft_scalar *timedata,kiss_fft_cpx *freqdata);
+/*
+ input timedata has nfft scalar points
+ output freqdata has nfft/2+1 complex points
+*/
+
+void kiss_fftri(kiss_fftr_cfg cfg,const kiss_fft_cpx *freqdata,kiss_fft_scalar *timedata);
+/*
+ input freqdata has  nfft/2+1 complex points
+ output timedata has nfft scalar points
+*/
+
+#define kiss_fftr_free free
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/codec2/branches/0.7/src/ldpc_dec.c b/codec2/branches/0.7/src/ldpc_dec.c
new file mode 100644 (file)
index 0000000..edf14bb
--- /dev/null
@@ -0,0 +1,245 @@
+/* \r
+  FILE...: ldpc_dec.c\r
+  AUTHOR.: Matthew C. Valenti, Rohit Iyer Seshadri, David Rowe\r
+  CREATED: Sep 2016\r
+\r
+  Command line C LDPC decoder derived from MpDecode.c in the CML\r
+  library.  Allows us to run the same decoder in Octave and C.  The\r
+  code is defined by the parameters and array stored in the include\r
+  file below, which can be machine generated from the Octave function\r
+  ldpc_fsk_lib.m:ldpc_decode()\r
+\r
+  The include file also contains test input/output vectors for the LDPC\r
+  decoder for testing this program.\r
+\r
+  Build:\r
+\r
+    $ gcc -O2 -o ldpc_dec ldpc_dec.c mpdecode_core.c -Wall -lm -g\r
+\r
+  Note: -O2 option was required to get identical results to MpDecode,\r
+  which is also compiled with -O2.  Without it the number of bit errors\r
+  between C and Octave was different, especially when the code did\r
+  not converge and hit max_iters.\r
+\r
+  TODO:\r
+  [ ] C cmd line encoder\r
+      [ ] SD output option\r
+      [ ] Es/No option for testing\r
+  [ ] decoder\r
+      [X] test mode or file I/O (incl stdin/stdout)\r
+      [X] Octave code to generate include file\r
+          + MAX_ITER as well\r
+      [X] check into SVN\r
+      [ ] enc/dec running on cmd line\r
+      [ ] fsk_demod modified for soft decisions\r
+      [ ] drs232 modified for SD\r
+          + use UW syn cin this program to check BER with coding\r
+      [ ] revisit CML support, maybe blog post\r
+*/\r
+\r
+#include <assert.h>\r
+#include <errno.h>\r
+#include <math.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdio.h>\r
+#include "mpdecode_core.h"\r
+\r
+/* Machine generated consts, H_rows, H_cols, test input/output data to\r
+   change LDPC code regenerate this file. */\r
+\r
+/* TODO: Better octave/C support for multuple codes */\r
+\r
+#include "H2064_516_sparse.h"  \r
+#include "HRA_112_112.h"  \r
+\r
+int opt_exists(char *argv[], int argc, char opt[]) {\r
+    int i;\r
+    for (i=0; i<argc; i++) {\r
+        if (strcmp(argv[i], opt) == 0) {\r
+            return i;\r
+        }\r
+    }\r
+    return 0;\r
+}\r
+\r
+void extract_output(char out_char[], int DecodedBits[], int ParityCheckCount[], int max_iter, int CodeLength, int NumberParityBits);\r
+\r
+int main(int argc, char *argv[])\r
+{    \r
+    int         CodeLength, NumberParityBits;\r
+    int         i, r, num_ok, num_runs, codename;\r
+    char        out_char[CODELENGTH], *adetected_data;\r
+    struct LDPC ldpc;\r
+    double     *ainput;\r
+       \r
+    if (argc < 2) {\r
+        fprintf(stderr, "\n");\r
+        fprintf(stderr, "usage: %s --test [--code CodeName]\n\n", argv[0]);\r
+        fprintf(stderr, "  Run internal self test and print code parameters.\n");\r
+        fprintf(stderr, "\n");\r
+        fprintf(stderr, "usage: %s --listcodes\n\n", argv[0]);\r
+        fprintf(stderr, "  List supported codes (more can be added via using Octave ldpc scripts)\n");\r
+        fprintf(stderr, "\n");\r
+        fprintf(stderr, "usage: %s InOneSymbolPerDouble OutOneBitPerByte [--sd] [--half] [--code CodeName]\n\n", argv[0]);\r
+        fprintf(stderr, "   InOneSymbolPerDouble    Input file of double LLRs, use - for the \n");        \r
+        fprintf(stderr, "                           file names to use stdin/stdout\n");\r
+        fprintf(stderr, "   --code                  Treat input file samples as Soft Decision\n");\r
+        fprintf(stderr, "                           demod outputs rather than LLRs\n");\r
+        fprintf(stderr, "   --sd                    Treat input file samples as Soft Decision\n");\r
+        fprintf(stderr, "                           demod outputs rather than LLRs\n");\r
+        fprintf(stderr, "   --half                  Load framesize/2 input samples for each decode\n");\r
+        fprintf(stderr, "                           attempt, only output decoded bits if decoder\n");\r
+        fprintf(stderr, "                           converges.  Form of frame sync.\n");\r
+        fprintf(stderr, "\n");\r
+        exit(0);\r
+    }\r
+\r
+\r
+    if ((codename = opt_exists(argv, argc, "--listcodes")) != 0) {\r
+        fprintf(stderr,"\n");\r
+        fprintf(stderr,"H2064_516_sparse\n");\r
+        fprintf(stderr,"HRA_112_112\n");\r
+        fprintf(stderr,"\n");\r
+        exit(0);\r
+    }\r
+\r
+    /* default Wenet High Alitiude Balloon rate 0.8 code */\r
+\r
+    ldpc.max_iter = MAX_ITER;\r
+    ldpc.dec_type = 0;\r
+    ldpc.q_scale_factor = 1;\r
+    ldpc.r_scale_factor = 1;\r
+    ldpc.CodeLength = CODELENGTH;\r
+    ldpc.NumberParityBits = NUMBERPARITYBITS;\r
+    ldpc.NumberRowsHcols = NUMBERROWSHCOLS;\r
+    ldpc.max_row_weight = MAX_ROW_WEIGHT;\r
+    ldpc.max_col_weight = MAX_COL_WEIGHT;\r
+    ldpc.H_rows = H_rows;\r
+    ldpc.H_cols = H_cols;\r
+    ainput = input;\r
+    adetected_data = detected_data;\r
+\r
+    if ((codename = opt_exists(argv, argc, "--code")) != 0) {\r
+\r
+        /* short rate 1/2 code for FreeDV HF digital voice */\r
+        \r
+        if (strcmp(argv[codename+1], "HRA_112_112") == 0) {\r
+            fprintf(stderr, "code: %s\n", argv[codename+1]);\r
+            ldpc.max_iter = HRA_112_112_MAX_ITER;\r
+            ldpc.dec_type = 0;\r
+            ldpc.q_scale_factor = 1;\r
+            ldpc.r_scale_factor = 1;\r
+            ldpc.CodeLength = HRA_112_112_CODELENGTH;\r
+            ldpc.NumberParityBits = HRA_112_112_NUMBERPARITYBITS;\r
+            ldpc.NumberRowsHcols = HRA_112_112_NUMBERROWSHCOLS;\r
+            ldpc.max_row_weight = HRA_112_112_MAX_ROW_WEIGHT;\r
+            ldpc.max_col_weight = HRA_112_112_MAX_COL_WEIGHT;\r
+            ldpc.H_rows = HRA_112_112_H_rows;\r
+            ldpc.H_cols = HRA_112_112_H_cols;\r
+            ainput = HRA_112_112_input;\r
+            adetected_data = HRA_112_112_detected_data;\r
+        }\r
+    }\r
+\r
+    CodeLength = ldpc.CodeLength;                    /* length of entire codeword */\r
+    NumberParityBits = ldpc.NumberParityBits;\r
+\r
+    if (!strcmp(argv[1],"--test")) {\r
+\r
+        /* test mode --------------------------------------------------------*/\r
+\r
+        fprintf(stderr, "Starting test using pre-compiled test data .....\n");\r
+        fprintf(stderr, "Codeword length: %d\n",  CodeLength);\r
+        fprintf(stderr, "Parity Bits....: %d\n",  NumberParityBits);\r
+\r
+        num_runs = 100; num_ok = 0;\r
+\r
+        for(r=0; r<num_runs; r++) {\r
+\r
+            run_ldpc_decoder(&ldpc, out_char, ainput);\r
+\r
+            int ok = 0;\r
+            for (i=0; i<CodeLength; i++) {\r
+                if (out_char[i] == adetected_data[i])                    \r
+                    ok++;\r
+            }\r
+\r
+            if (ok == CodeLength)\r
+                num_ok++;            \r
+        }\r
+\r
+        fprintf(stderr, "test runs......: %d\n",  num_runs);\r
+        fprintf(stderr, "test runs OK...: %d\n",  num_ok);\r
+        if (num_runs == num_ok)\r
+            fprintf(stderr, "test runs OK...: PASS\n");\r
+        else\r
+            fprintf(stderr, "test runs OK...: FAIL\n");\r
+    }\r
+    else {\r
+        FILE *fin, *fout;\r
+        int   sdinput, readhalfframe, nread, offset, iter;\r
+\r
+        /* File I/O mode ------------------------------------------------*/\r
+\r
+        if (strcmp(argv[1], "-")  == 0) fin = stdin;\r
+        else if ( (fin = fopen(argv[1],"rb")) == NULL ) {\r
+            fprintf(stderr, "Error opening input SD file: %s: %s.\n",\r
+                    argv[1], strerror(errno));\r
+            exit(1);\r
+        }\r
+        \r
+        if (strcmp(argv[2], "-") == 0) fout = stdout;\r
+        else if ( (fout = fopen(argv[2],"wb")) == NULL ) {\r
+            fprintf(stderr, "Error opening output bit file: %s: %s.\n",\r
+                    argv[2], strerror(errno));\r
+            exit(1);\r
+        }\r
+\r
+        sdinput = 0;\r
+        readhalfframe = 0;\r
+        if (opt_exists(argv, argc, "--sd")) {\r
+            sdinput = 1;\r
+        }\r
+        if (opt_exists(argv, argc, "--half")) {\r
+            readhalfframe = 1;\r
+        }\r
+\r
+        double *input_double = calloc(CodeLength, sizeof(double));\r
+\r
+        nread = CodeLength;\r
+        offset = 0;\r
+        if (readhalfframe) {\r
+            nread = CodeLength/2;\r
+            offset = CodeLength/2;\r
+            for(i=0; i<offset; i++) {\r
+                input_double[i] = 0.0;\r
+            }\r
+        }\r
+\r
+        while(fread(&input_double[offset], sizeof(double), nread, fin) == nread) {\r
+            if (sdinput) {\r
+                sd_to_llr(input_double, input_double, CodeLength);\r
+            }\r
+\r
+            iter = run_ldpc_decoder(&ldpc, out_char, input_double);\r
+            fprintf(stderr, "%4d ", iter);\r
+\r
+            // output data bits if decoder converged\r
+\r
+            if (iter != MAX_ITER) {\r
+              fwrite(out_char, sizeof(char), ldpc.NumberRowsHcols, fout);\r
+            }\r
+\r
+            for(i=0; i<offset; i++) {\r
+                input_double[i] = input_double[i+offset];\r
+            }\r
+        }\r
+\r
+        free(input_double);\r
+    }\r
+\r
+    return 0;\r
+}\r
+\r
+\r
diff --git a/codec2/branches/0.7/src/ldpc_enc.c b/codec2/branches/0.7/src/ldpc_enc.c
new file mode 100644 (file)
index 0000000..6a6011e
--- /dev/null
@@ -0,0 +1,153 @@
+/* 
+  FILE...: ldpc_enc.c
+  AUTHOR.: Bill Cowley, David Rowe
+  CREATED: Sep 2016
+
+  RA LDPC encoder program. Using the elegant back substitution of RA
+  LDPC codes.
+
+  building: gcc ldpc_enc.c -o ldpc_enc -Wall -g
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "mpdecode_core.h"
+
+/* generated by ldpc_fsk_lib.m:ldpc_decode() */
+
+#include "H2064_516_sparse.h"  
+#include "HRA_112_112.h"  
+
+int opt_exists(char *argv[], int argc, char opt[]) {
+    int i;
+    for (i=0; i<argc; i++) {
+        if (strcmp(argv[i], opt) == 0) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+void encode(struct LDPC *ldpc, unsigned char ibits[], unsigned char pbits[]) {
+    unsigned int p, i, tmp, par, prev=0;
+    int          ind;
+    double      *H_rows = ldpc->H_rows;
+
+    for (p=0; p<ldpc->NumberParityBits; p++) {
+        par = 0; 
+
+        for (i=0; i<ldpc->max_row_weight; i++) {
+            ind = (int)H_rows[p + i*ldpc->NumberParityBits];
+            par = par + ibits[ind-1];
+        }
+
+        tmp = par + prev;
+
+        tmp &= 1;    // only retain the lsb 
+        prev = tmp; 
+        pbits[p] = tmp; 
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    unsigned char ibits[NUMBERROWSHCOLS];
+    unsigned char pbits[NUMBERPARITYBITS];
+    FILE         *fin, *fout;
+    int           sd, i, codename;
+    double        sdout[NUMBERROWSHCOLS+NUMBERPARITYBITS];
+    struct LDPC   ldpc;
+
+    if (argc < 2) {
+        fprintf(stderr, "\n");
+        fprintf(stderr, "usage: %s InputOneBytePerBit OutputFile [--sd] [--code CodeName]\n", argv[0]);
+        fprintf(stderr, "\n");
+        fprintf(stderr, "usage: %s --listcodes\n\n", argv[0]);
+        fprintf(stderr, "  List supported codes (more can be added via using Octave ldpc scripts)\n");
+        fprintf(stderr, "\n");
+        exit(0);
+    }
+
+    /* todo: put this in a function file to share with ldpc_dec.c */
+
+    if ((codename = opt_exists(argv, argc, "--listcodes")) != 0) {
+        fprintf(stderr,"\n");
+        fprintf(stderr,"H2064_516_sparse\n");
+        fprintf(stderr,"HRA_112_112\n");
+        fprintf(stderr,"\n");
+        exit(0);
+    }
+
+    /* set up LDPC code from include file constants */
+
+    if ((codename = opt_exists(argv, argc, "--code")) != 0) {
+
+        /* short rate 1/2 code for FreeDV HF digital voice */
+
+        if (strcmp(argv[codename+1], "HRA_112_112") == 0) {
+            fprintf(stderr, "code: %s\n", argv[codename+1]);
+            ldpc.CodeLength = HRA_112_112_CODELENGTH;
+            ldpc.NumberParityBits = HRA_112_112_NUMBERPARITYBITS;
+            ldpc.NumberRowsHcols = HRA_112_112_NUMBERROWSHCOLS;
+            ldpc.max_row_weight = HRA_112_112_MAX_ROW_WEIGHT;
+            ldpc.max_col_weight = HRA_112_112_MAX_COL_WEIGHT;
+            ldpc.H_rows = HRA_112_112_H_rows;
+            ldpc.H_cols = HRA_112_112_H_cols;
+        }
+    } else {
+
+        /* default Wenet High Alitiude Balloon rate 0.8 code */
+
+        ldpc.CodeLength = CODELENGTH;
+        ldpc.NumberParityBits = NUMBERPARITYBITS;
+        ldpc.NumberRowsHcols = NUMBERROWSHCOLS;
+        ldpc.max_row_weight = MAX_ROW_WEIGHT;
+        ldpc.max_col_weight = MAX_COL_WEIGHT;
+        ldpc.H_rows = H_rows;
+        ldpc.H_cols = H_cols;
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+        fprintf(stderr, "Error opening input bit 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 bit file: %s: %s.\n",
+                argv[2], strerror(errno));
+        exit(1);
+    }
+    
+    sd = 0;
+    if (opt_exists(argv, argc, "--sd")) {
+        sd = 1;
+    }
+
+    while (fread(ibits, sizeof(char), ldpc.NumberParityBits, fin) == ldpc.NumberParityBits) {
+
+        encode(&ldpc, ibits, pbits);  
+        
+        if (sd) {
+            for (i=0; i<ldpc.NumberRowsHcols; i++)
+                sdout[i] = 1.0 - 2.0 * ibits[i];
+            for (i=0; i<ldpc.NumberParityBits; i++)
+                sdout[i+ldpc.NumberRowsHcols] = 1.0 - 2.0 * pbits[i];
+            fwrite(sdout, sizeof(double), ldpc.NumberRowsHcols+ldpc.NumberParityBits, fout); 
+        }
+        else {
+            fwrite(ibits, sizeof(char), ldpc.NumberRowsHcols, fout); 
+            fwrite(pbits, sizeof(char), ldpc.NumberParityBits, fout); 
+        }
+    }
+
+    fclose(fin);  
+    fclose(fout); 
+
+    return 1;
+}
diff --git a/codec2/branches/0.7/src/linreg.c b/codec2/branches/0.7/src/linreg.c
new file mode 100644 (file)
index 0000000..f37634d
--- /dev/null
@@ -0,0 +1,106 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: linreg.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Linear regression C module based on:
+
+    http://stackoverflow.com/questions/5083465/fast-efficient-least-squares-fit-algorithm-in-c
+
+  Use:
+
+    $ gcc linreg.c -o linreg -D__UNITTEST__ -Wall
+    $ ./linreg
+
+    Then compare yfit results with octave/tlinreg.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include "linreg.h"
+#include "comp_prim.h"
+
+
+void linreg(COMP *m, COMP *b, float x[], COMP y[], int n)
+{
+    float  sumx  = 0.0;         /* sum of x          */
+    float  sumx2 = 0.0;         /* sum of x^2        */
+    COMP   sumxy = {0.0,0.0};   /* sum of x * y      */
+    COMP   sumy  = {0.0,0.0};   /* sum of y          */
+    COMP   sumy2 = {0.0,0.0};   /* sum of y**2       */
+    float  denom;
+    COMP   zero;
+    int    i;
+
+    for (i=0; i<n; i++) {
+        sumx  += x[i];
+        sumx2 += x[i]*x[i];
+        sumxy = cadd(sumxy, fcmult(x[i], y[i]));
+        sumy  = cadd(sumy, y[i]);
+        sumy2 = cadd(sumy2, cmult(y[i],y[i]));
+    }
+
+  denom = (n * sumx2 - sumx*sumx);
+
+  if (denom == 0) {
+      /* singular matrix. can't solve the problem */
+      zero.real = 0.0; zero.imag = 0.0;
+      *m = zero;
+      *b = zero;
+  } else {
+      *m = fcmult(1.0/denom, cadd(fcmult(n, sumxy), cneg(fcmult(sumx,sumy))));
+      *b = fcmult(1.0/denom, cadd(fcmult(sumx2,sumy), cneg(fcmult(sumx, sumxy))));
+  }
+}
+
+
+#ifdef __UNITTEST__
+
+
+static float x[] = {1, 2, 7, 8};
+
+static COMP  y[] = {
+  {-0.70702,  0.70708},
+  {-0.77314,  0.63442},
+  {-0.98083,  0.19511},
+  {-0.99508,  0.09799}
+};
+
+
+int main(void) {
+    float  x1;
+    COMP   m,b,yfit;
+
+    linreg(&m, &b, x, y, sizeof(x)/sizeof(float));
+
+    for (x1=1; x1<=8; x1++) {
+        yfit = cadd(fcmult(x1, m),b);
+        printf("%f %f\n", yfit.real, yfit.imag);
+    }
+
+    return 0;
+}
+
+#endif
+
diff --git a/codec2/branches/0.7/src/linreg.h b/codec2/branches/0.7/src/linreg.h
new file mode 100644 (file)
index 0000000..c86dfad
--- /dev/null
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: linreg.h
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Linear regression C module based
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LINREG__
+#define __LINREG__
+
+#include "comp.h"
+
+void linreg(COMP *m, COMP *b, float x[], COMP y[], int n);
+
+#endif
diff --git a/codec2/branches/0.7/src/listensim.sh b/codec2/branches/0.7/src/listensim.sh
new file mode 100755 (executable)
index 0000000..b296cac
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/sh
+# listensim.sh
+# David Rowe 10 Sep 2009
+#
+# Listen to files processed with sim.sh
+
+../script/menu.sh $1_uq.raw $1_lpc10.raw $1_lpcpf.raw $1_phase0.raw $1_phase0_lpcpf.raw $2 $3 $4 $5
+
+
diff --git a/codec2/branches/0.7/src/lpc.c b/codec2/branches/0.7/src/lpc.c
new file mode 100644 (file)
index 0000000..31442cd
--- /dev/null
@@ -0,0 +1,306 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: lpc.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 30 Sep 1990 (!)
+
+  Linear Prediction functions written in C.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009-2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define LPC_MAX_N 512          /* maximum no. of samples in frame */
+#define PI 3.141592654         /* mathematical constant */
+
+#define ALPHA 1.0
+#define BETA  0.94
+
+#include <assert.h>
+#include <math.h>
+#include "defines.h"
+#include "lpc.h"
+
+/*---------------------------------------------------------------------------*\
+
+  pre_emp()
+
+  Pre-emphasise (high pass filter with zero close to 0 Hz) a frame of
+  speech samples.  Helps reduce dynamic range of LPC spectrum, giving
+  greater weight and hense a better match to low energy formants.
+
+  Should be balanced by de-emphasis of the output speech.
+
+\*---------------------------------------------------------------------------*/
+
+void pre_emp(
+  float  Sn_pre[], /* output frame of speech samples                     */
+  float  Sn[],    /* input frame of speech samples                      */
+  float *mem,      /* Sn[-1]single sample memory                         */
+  int   Nsam      /* number of speech samples to use                    */
+)
+{
+    int   i;
+
+    for(i=0; i<Nsam; i++) {
+       Sn_pre[i] = Sn[i] - ALPHA * mem[0];
+       mem[0] = Sn[i];
+    }
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  de_emp()
+
+  De-emphasis filter (low pass filter with a pole close to 0 Hz).
+
+\*---------------------------------------------------------------------------*/
+
+void de_emp(
+  float  Sn_de[],  /* output frame of speech samples                     */
+  float  Sn[],    /* input frame of speech samples                      */
+  float *mem,      /* Sn[-1]single sample memory                         */
+  int    Nsam     /* number of speech samples to use                    */
+)
+{
+    int   i;
+
+    for(i=0; i<Nsam; i++) {
+       Sn_de[i] = Sn[i] + BETA * mem[0];
+       mem[0] = Sn_de[i];
+    }
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  hanning_window()
+
+  Hanning windows a frame of speech samples.
+
+\*---------------------------------------------------------------------------*/
+
+void hanning_window(
+  float Sn[],  /* input frame of speech samples */
+  float Wn[],  /* output frame of windowed samples */
+  int Nsam     /* number of samples */
+)
+{
+  int i;       /* loop variable */
+
+  for(i=0; i<Nsam; i++)
+    Wn[i] = Sn[i]*(0.5 - 0.5*cosf(2*PI*(float)i/(Nsam-1)));
+}
+
+/*---------------------------------------------------------------------------*\
+
+  autocorrelate()
+
+  Finds the first P autocorrelation values of an array of windowed speech
+  samples Sn[].
+
+\*---------------------------------------------------------------------------*/
+
+void autocorrelate(
+  float Sn[],  /* frame of Nsam windowed speech samples */
+  float Rn[],  /* array of P+1 autocorrelation coefficients */
+  int Nsam,    /* number of windowed samples to use */
+  int order    /* order of LPC analysis */
+)
+{
+  int i,j;     /* loop variables */
+
+  for(j=0; j<order+1; j++) {
+    Rn[j] = 0.0;
+    for(i=0; i<Nsam-j; i++)
+      Rn[j] += Sn[i]*Sn[i+j];
+  }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  levinson_durbin()
+
+  Given P+1 autocorrelation coefficients, finds P Linear Prediction Coeff.
+  (LPCs) where P is the order of the LPC all-pole model. The Levinson-Durbin
+  algorithm is used, and is described in:
+
+    J. Makhoul
+    "Linear prediction, a tutorial review"
+    Proceedings of the IEEE
+    Vol-63, No. 4, April 1975
+
+\*---------------------------------------------------------------------------*/
+
+void levinson_durbin(
+  float R[],           /* order+1 autocorrelation coeff */
+  float lpcs[],                /* order+1 LPC's */
+  int order            /* order of the LPC analysis */
+)
+{
+  float a[order+1][order+1];
+  float sum, e, k;
+  int i,j;                             /* loop variables */
+
+  e = R[0];                            /* Equation 38a, Makhoul */
+
+  for(i=1; i<=order; i++) {
+    sum = 0.0;
+    for(j=1; j<=i-1; j++)
+      sum += a[i-1][j]*R[i-j];
+    k = -1.0*(R[i] + sum)/e;           /* Equation 38b, Makhoul */
+    if (fabsf(k) > 1.0)
+      k = 0.0;
+
+    a[i][i] = k;
+
+    for(j=1; j<=i-1; j++)
+      a[i][j] = a[i-1][j] + k*a[i-1][i-j];     /* Equation 38c, Makhoul */
+
+    e *= (1-k*k);                              /* Equation 38d, Makhoul */
+  }
+
+  for(i=1; i<=order; i++)
+    lpcs[i] = a[order][i];
+  lpcs[0] = 1.0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  inverse_filter()
+
+  Inverse Filter, A(z).  Produces an array of residual samples from an array
+  of input samples and linear prediction coefficients.
+
+  The filter memory is stored in the first order samples of the input array.
+
+\*---------------------------------------------------------------------------*/
+
+void inverse_filter(
+  float Sn[],  /* Nsam input samples */
+  float a[],   /* LPCs for this frame of samples */
+  int Nsam,    /* number of samples */
+  float res[], /* Nsam residual samples */
+  int order    /* order of LPC */
+)
+{
+  int i,j;     /* loop variables */
+
+  for(i=0; i<Nsam; i++) {
+    res[i] = 0.0;
+    for(j=0; j<=order; j++)
+      res[i] += Sn[i-j]*a[j];
+  }
+}
+
+/*---------------------------------------------------------------------------*\
+
+ synthesis_filter()
+
+ C version of the Speech Synthesis Filter, 1/A(z).  Given an array of
+ residual or excitation samples, and the the LP filter coefficients, this
+ function will produce an array of speech samples.  This filter structure is
+ IIR.
+
+ The synthesis filter has memory as well, this is treated in the same way
+ as the memory for the inverse filter (see inverse_filter() notes above).
+ The difference is that the memory for the synthesis filter is stored in
+ the output array, wheras the memory of the inverse filter is stored in the
+ input array.
+
+ Note: the calling function must update the filter memory.
+
+\*---------------------------------------------------------------------------*/
+
+void synthesis_filter(
+  float res[], /* Nsam input residual (excitation) samples */
+  float a[],   /* LPCs for this frame of speech samples */
+  int Nsam,    /* number of speech samples */
+  int order,   /* LPC order */
+  float Sn_[]  /* Nsam output synthesised speech samples */
+)
+{
+  int i,j;     /* loop variables */
+
+  /* Filter Nsam samples */
+
+  for(i=0; i<Nsam; i++) {
+    Sn_[i] = res[i]*a[0];
+    for(j=1; j<=order; j++)
+      Sn_[i] -= Sn_[i-j]*a[j];
+  }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  find_aks()
+
+  This function takes a frame of samples, and determines the linear
+  prediction coefficients for that frame of samples.
+
+\*---------------------------------------------------------------------------*/
+
+void find_aks(
+  float Sn[],  /* Nsam samples with order sample memory */
+  float a[],   /* order+1 LPCs with first coeff 1.0 */
+  int Nsam,    /* number of input speech samples */
+  int order,   /* order of the LPC analysis */
+  float *E     /* residual energy */
+)
+{
+  float Wn[LPC_MAX_N]; /* windowed frame of Nsam speech samples */
+  float R[order+1];    /* order+1 autocorrelation values of Sn[] */
+  int i;
+
+  assert(Nsam < LPC_MAX_N);
+
+  hanning_window(Sn,Wn,Nsam);
+  autocorrelate(Wn,R,Nsam,order);
+  levinson_durbin(R,a,order);
+
+  *E = 0.0;
+  for(i=0; i<=order; i++)
+    *E += a[i]*R[i];
+  if (*E < 0.0)
+    *E = 1E-12;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  weight()
+
+  Weights a vector of LPCs.
+
+\*---------------------------------------------------------------------------*/
+
+void weight(
+  float ak[],  /* vector of order+1 LPCs */
+  float gamma, /* weighting factor */
+  int order,   /* num LPCs (excluding leading 1.0) */
+  float akw[]  /* weighted vector of order+1 LPCs */
+)
+{
+  int i;
+
+  for(i=1; i<=order; i++)
+    akw[i] = ak[i]*powf(gamma,(float)i);
+}
+
diff --git a/codec2/branches/0.7/src/lpc.h b/codec2/branches/0.7/src/lpc.h
new file mode 100644 (file)
index 0000000..482aa1f
--- /dev/null
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: lpc.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/8/09
+
+  Linear Prediction functions written in C.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009-2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LPC__
+#define __LPC__
+
+#define LPC_MAX_ORDER 20
+
+void pre_emp(float Sn_pre[], float Sn[], float *mem, int Nsam);
+void de_emp(float Sn_se[], float Sn[], float *mem, int Nsam);
+void hanning_window(float Sn[],        float Wn[], int Nsam);
+void autocorrelate(float Sn[], float Rn[], int Nsam, int order);
+void levinson_durbin(float R[],        float lpcs[], int order);
+void inverse_filter(float Sn[], float a[], int Nsam, float res[], int order);
+void synthesis_filter(float res[], float a[], int Nsam,        int order, float Sn_[]);
+void find_aks(float Sn[], float a[], int Nsam, int order, float *E);
+void weight(float ak[],        float gamma, int order, float akw[]);
+
+#endif
diff --git a/codec2/branches/0.7/src/lsp.c b/codec2/branches/0.7/src/lsp.c
new file mode 100644 (file)
index 0000000..05d190e
--- /dev/null
@@ -0,0 +1,321 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: lsp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/2/93
+
+
+  This file contains functions for LPC to LSP conversion and LSP to
+  LPC conversion. Note that the LSP coefficients are not in radians
+  format but in the x domain of the unit circle.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "defines.h"
+#include "lsp.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/*---------------------------------------------------------------------------*\
+
+  Introduction to Line Spectrum Pairs (LSPs)
+  ------------------------------------------
+
+  LSPs are used to encode the LPC filter coefficients {ak} for
+  transmission over the channel.  LSPs have several properties (like
+  less sensitivity to quantisation noise) that make them superior to
+  direct quantisation of {ak}.
+
+  A(z) is a polynomial of order lpcrdr with {ak} as the coefficients.
+
+  A(z) is transformed to P(z) and Q(z) (using a substitution and some
+  algebra), to obtain something like:
+
+    A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)]  (1)
+
+  As you can imagine A(z) has complex zeros all over the z-plane. P(z)
+  and Q(z) have the very neat property of only having zeros _on_ the
+  unit circle.  So to find them we take a test point z=exp(jw) and
+  evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0
+  and pi.
+
+  The zeros (roots) of P(z) also happen to alternate, which is why we
+  swap coefficients as we find roots.  So the process of finding the
+  LSP frequencies is basically finding the roots of 5th order
+  polynomials.
+
+  The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence
+  the name Line Spectrum Pairs (LSPs).
+
+  To convert back to ak we just evaluate (1), "clocking" an impulse
+  thru it lpcrdr times gives us the impulse response of A(z) which is
+  {ak}.
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: cheb_poly_eva()
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/2/93
+
+  This function evalutes a series of chebyshev polynomials
+
+  FIXME: performing memory allocation at run time is very inefficient,
+  replace with stack variables of MAX_P size.
+
+\*---------------------------------------------------------------------------*/
+
+
+static float
+cheb_poly_eva(float *coef,float x,int order)
+/*  float coef[]       coefficients of the polynomial to be evaluated  */
+/*  float x            the point where polynomial is to be evaluated   */
+/*  int order          order of the polynomial                         */
+{
+    int i;
+    float *t,*u,*v,sum;
+    float T[(order / 2) + 1];
+
+    /* Initialise pointers */
+
+    t = T;                             /* T[i-2]                       */
+    *t++ = 1.0;
+    u = t--;                           /* T[i-1]                       */
+    *u++ = x;
+    v = u--;                           /* T[i]                         */
+
+    /* Evaluate chebyshev series formulation using iterative approach  */
+
+    for(i=2;i<=order/2;i++)
+       *v++ = (2*x)*(*u++) - *t++;     /* T[i] = 2*x*T[i-1] - T[i-2]   */
+
+    sum=0.0;                           /* initialise sum to zero       */
+    t = T;                             /* reset pointer                */
+
+    /* Evaluate polynomial and return value also free memory space */
+
+    for(i=0;i<=order/2;i++)
+       sum+=coef[(order/2)-i]**t++;
+
+    return sum;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: lpc_to_lsp()
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/2/93
+
+  This function converts LPC coefficients to LSP coefficients.
+
+\*---------------------------------------------------------------------------*/
+
+int lpc_to_lsp (float *a, int order, float *freq, int nb, float delta)
+/*  float *a                   lpc coefficients                        */
+/*  int order                  order of LPC coefficients (10)          */
+/*  float *freq                LSP frequencies in radians              */
+/*  int nb                     number of sub-intervals (4)             */
+/*  float delta                        grid spacing interval (0.02)            */
+{
+    float psuml,psumr,psumm,temp_xr,xl,xr,xm = 0;
+    float temp_psumr;
+    int i,j,m,flag,k;
+    float *px;                 /* ptrs of respective P'(z) & Q'(z)     */
+    float *qx;
+    float *p;
+    float *q;
+    float *pt;                 /* ptr used for cheb_poly_eval()
+                                  whether P' or Q'                     */
+    int roots=0;               /* number of roots found                */
+    float Q[order + 1];
+    float P[order + 1];
+
+    flag = 1;
+    m = order/2;               /* order of P'(z) & Q'(z) polynimials   */
+
+    /* Allocate memory space for polynomials */
+
+    /* determine P'(z)'s and Q'(z)'s coefficients where
+      P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */
+
+    px = P;                      /* initilaise ptrs */
+    qx = Q;
+    p = px;
+    q = qx;
+    *px++ = 1.0;
+    *qx++ = 1.0;
+    for(i=1;i<=m;i++){
+       *px++ = a[i]+a[order+1-i]-*p++;
+       *qx++ = a[i]-a[order+1-i]+*q++;
+    }
+    px = P;
+    qx = Q;
+    for(i=0;i<m;i++){
+       *px = 2**px;
+       *qx = 2**qx;
+        px++;
+        qx++;
+    }
+    px = P;                    /* re-initialise ptrs                   */
+    qx = Q;
+
+    /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z).
+    Keep alternating between the two polynomials as each zero is found         */
+
+    xr = 0;                    /* initialise xr to zero                */
+    xl = 1.0;                  /* start at point xl = 1                */
+
+
+    for(j=0;j<order;j++){
+       if(j%2)                 /* determines whether P' or Q' is eval. */
+           pt = qx;
+       else
+           pt = px;
+
+       psuml = cheb_poly_eva(pt,xl,order);     /* evals poly. at xl    */
+       flag = 1;
+       while(flag && (xr >= -1.0)){
+           xr = xl - delta ;                   /* interval spacing     */
+           psumr = cheb_poly_eva(pt,xr,order);/* poly(xl-delta_x)      */
+           temp_psumr = psumr;
+           temp_xr = xr;
+
+        /* if no sign change increment xr and re-evaluate
+           poly(xr). Repeat til sign change.  if a sign change has
+           occurred the interval is bisected and then checked again
+           for a sign change which determines in which interval the
+           zero lies in.  If there is no sign change between poly(xm)
+           and poly(xl) set interval between xm and xr else set
+           interval between xl and xr and repeat till root is located
+           within the specified limits  */
+
+           if(((psumr*psuml)<0.0) || (psumr == 0.0)){
+               roots++;
+
+               psumm=psuml;
+               for(k=0;k<=nb;k++){
+                   xm = (xl+xr)/2;             /* bisect the interval  */
+                   psumm=cheb_poly_eva(pt,xm,order);
+                   if(psumm*psuml>0.){
+                       psuml=psumm;
+                       xl=xm;
+                   }
+                   else{
+                       psumr=psumm;
+                       xr=xm;
+                   }
+               }
+
+              /* once zero is found, reset initial interval to xr      */
+              freq[j] = (xm);
+              xl = xm;
+              flag = 0;                /* reset flag for next search   */
+           }
+           else{
+               psuml=temp_psumr;
+               xl=temp_xr;
+           }
+       }
+    }
+
+    /* convert from x domain to radians */
+
+    for(i=0; i<order; i++) {
+       freq[i] = acosf(freq[i]);
+    }
+
+    return(roots);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: lsp_to_lpc()
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/2/93
+
+  This function converts LSP coefficients to LPC coefficients.  In the
+  Speex code we worked out a way to simplify this significantly.
+
+\*---------------------------------------------------------------------------*/
+
+void lsp_to_lpc(float *lsp, float *ak, int order)
+/*  float *freq         array of LSP frequencies in radians            */
+/*  float *ak          array of LPC coefficients                       */
+/*  int order          order of LPC coefficients                       */
+
+
+{
+    int i,j;
+    float xout1,xout2,xin1,xin2;
+    float *pw,*n1,*n2,*n3,*n4 = 0;
+    float freq[order];
+    float Wp[(order * 4) + 2];
+
+    /* convert from radians to the x=cos(w) domain */
+
+    for(i=0; i<order; i++)
+       freq[i] = cosf(lsp[i]);
+
+    pw = Wp;
+
+    /* initialise contents of array */
+
+    for(i=0;i<=4*(order/2)+1;i++){             /* set contents of buffer to 0 */
+       *pw++ = 0.0;
+    }
+
+    /* Set pointers up */
+
+    pw = Wp;
+    xin1 = 1.0;
+    xin2 = 1.0;
+
+    /* reconstruct P(z) and Q(z) by cascading second order polynomials
+      in form 1 - 2xz(-1) +z(-2), where x is the LSP coefficient */
+
+    for(j=0;j<=order;j++){
+       for(i=0;i<(order/2);i++){
+           n1 = pw+(i*4);
+           n2 = n1 + 1;
+           n3 = n2 + 1;
+           n4 = n3 + 1;
+           xout1 = xin1 - 2*(freq[2*i]) * *n1 + *n2;
+           xout2 = xin2 - 2*(freq[2*i+1]) * *n3 + *n4;
+           *n2 = *n1;
+           *n4 = *n3;
+           *n1 = xin1;
+           *n3 = xin2;
+           xin1 = xout1;
+           xin2 = xout2;
+       }
+       xout1 = xin1 + *(n4+1);
+       xout2 = xin2 - *(n4+2);
+       ak[j] = (xout1 + xout2)*0.5;
+       *(n4+1) = xin1;
+       *(n4+2) = xin2;
+
+       xin1 = 0.0;
+       xin2 = 0.0;
+    }
+}
+
diff --git a/codec2/branches/0.7/src/lsp.h b/codec2/branches/0.7/src/lsp.h
new file mode 100644 (file)
index 0000000..5acef01
--- /dev/null
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: lsp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/2/93
+
+
+  This file contains functions for LPC to LSP conversion and LSP to
+  LPC conversion. Note that the LSP coefficients are not in radians
+  format but in the x domain of the unit circle.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LSP__
+#define __LSP__
+
+int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta);
+void lsp_to_lpc(float *freq, float *ak, int lpcrdr);
+
+#endif
diff --git a/codec2/branches/0.7/src/machdep.h b/codec2/branches/0.7/src/machdep.h
new file mode 100644 (file)
index 0000000..4dff9ba
--- /dev/null
@@ -0,0 +1,52 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: machdep.h
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2 2013
+
+  Machine dependant functions, e.g. profiling that requires access to a clock
+  counter register.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __MACHDEP__
+#define __MACHDEP__
+
+#ifdef PROFILE
+#define PROFILE_VAR(...) unsigned int __VA_ARGS__
+#define PROFILE_SAMPLE(timestamp) timestamp = machdep_profile_sample()
+#define PROFILE_SAMPLE_AND_LOG(timestamp, prev_timestamp, label) \
+    timestamp = machdep_profile_sample_and_log(prev_timestamp, label)
+#define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label) \
+    machdep_profile_sample_and_log(prev_timestamp, label)
+#else
+#define PROFILE_VAR(...)
+#define PROFILE_SAMPLE(timestamp)
+#define PROFILE_SAMPLE_AND_LOG(timestamp, prev_timestamp, label)
+#define PROFILE_SAMPLE_AND_LOG2(prev_timestamp, label)
+#endif
+
+void         machdep_profile_init(void);
+void         machdep_profile_reset(void);
+unsigned int machdep_profile_sample(void);
+unsigned int machdep_profile_sample_and_log(unsigned int start, char s[]);
+void         machdep_profile_print_logged_samples(void);
+
+#endif
diff --git a/codec2/branches/0.7/src/mbest.c b/codec2/branches/0.7/src/mbest.c
new file mode 100644 (file)
index 0000000..e092d71
--- /dev/null
@@ -0,0 +1,142 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: mbest.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Multistage vector quantiser search algorithm that keeps multiple
+  candidates from each stage.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright David Rowe 2017
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "mbest.h"
+
+struct MBEST *mbest_create(int entries) {
+    int           i,j;
+    struct MBEST *mbest;
+
+    assert(entries > 0);
+    mbest = (struct MBEST *)malloc(sizeof(struct MBEST));
+    assert(mbest != NULL);
+
+    mbest->entries = entries;
+    mbest->list = (struct MBEST_LIST *)malloc(entries*sizeof(struct MBEST_LIST));
+    assert(mbest->list != NULL);
+
+    for(i=0; i<mbest->entries; i++) {
+       for(j=0; j<MBEST_STAGES; j++)
+           mbest->list[i].index[j] = 0;
+       mbest->list[i].error = 1E32;
+    }
+
+    return mbest;
+}
+
+
+void mbest_destroy(struct MBEST *mbest) {
+    assert(mbest != NULL);
+    free(mbest->list);
+    free(mbest);
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  mbest_insert
+
+  Insert the results of a vector to codebook entry comparison. The
+  list is ordered in order or error, so those entries with the
+  smallest error will be first on the list.
+
+\*---------------------------------------------------------------------------*/
+
+void mbest_insert(struct MBEST *mbest, int index[], float error) {
+    int                i, j, found;
+    struct MBEST_LIST *list    = mbest->list;
+    int                entries = mbest->entries;
+
+    found = 0;
+    for(i=0; i<entries && !found; i++)
+       if (error < list[i].error) {
+           found = 1;
+           for(j=entries-1; j>i; j--)
+               list[j] = list[j-1];
+           for(j=0; j<MBEST_STAGES; j++)
+               list[i].index[j] = index[j];
+           list[i].error = error;
+       }
+}
+
+
+#ifdef MBEST_PRINT_OUT
+static void mbest_print(char title[], struct MBEST *mbest) {
+    int i,j;
+
+    fprintf(stderr, "%s\n", title);
+    for(i=0; i<mbest->entries; i++) {
+       for(j=0; j<MBEST_STAGES; j++)
+           fprintf(stderr, "  %4d ", mbest->list[i].index[j]);
+       fprintf(stderr, " %f\n", mbest->list[i].error);
+    }
+}
+#endif
+
+
+/*---------------------------------------------------------------------------*\
+
+  mbest_search
+
+  Searches vec[] to a codebbook of vectors, and maintains a list of the mbest
+  closest matches.
+
+\*---------------------------------------------------------------------------*/
+
+void mbest_search(
+                 const float  *cb,     /* VQ codebook to search         */
+                 float         vec[],  /* target vector                 */
+                 float         w[],    /* weighting vector              */
+                 int           k,      /* dimension of vector           */
+                 int           m,      /* number on entries in codebook */
+                 struct MBEST *mbest,  /* list of closest matches       */
+                 int           index[] /* indexes that lead us here     */
+)
+{
+   float   e;
+   int     i,j;
+   float   diff;
+
+   for(j=0; j<m; j++) {
+       e = 0.0;
+       for(i=0; i<k; i++) {
+           diff = cb[j*k+i]-vec[i];
+           e += powf(diff*w[i],2.0);
+       }
+       index[0] = j;
+       mbest_insert(mbest, index, e);
+   }
+}
+
diff --git a/codec2/branches/0.7/src/mbest.h b/codec2/branches/0.7/src/mbest.h
new file mode 100644 (file)
index 0000000..eeaad40
--- /dev/null
@@ -0,0 +1,58 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: mbest.h
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Multistage vector quantiser search algorithm that keeps multiple
+  candidates from each stage.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright David Rowe 2017
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef __MBEST__
+#define __MBEST__
+
+#define MBEST_STAGES 4
+
+struct MBEST_LIST {
+    int   index[MBEST_STAGES];    /* index of each stage that lead us to this error */
+    float error;
+};
+
+struct MBEST {
+    int                entries;   /* number of entries in mbest list   */
+    struct MBEST_LIST *list;
+};
+
+struct MBEST *mbest_create(int entries);
+void mbest_destroy(struct MBEST *mbest);
+void mbest_insert(struct MBEST *mbest, int index[], float error);
+void mbest_search(const float  *cb, float vec[], float w[], int k, int m, struct MBEST *mbest, int index[]);
+
+// #define MBEST_PRINT_OUT
+#ifdef MBEST_PRINT_OUT
+ #define MBEST_PRINT(a,b) mbest_print((a),(b))
+#else
+ #define MBEST_PRINT(a,b) 
+#endif
+
+
+#endif
diff --git a/codec2/branches/0.7/src/modem_probe.c b/codec2/branches/0.7/src/modem_probe.c
new file mode 100644 (file)
index 0000000..884a1a8
--- /dev/null
@@ -0,0 +1,240 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: modem_probe.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 9 January 2016
+
+  Library to easily extract debug traces from modems during development and
+  verification
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "comp.h"
+#include "octave.h"
+
+#define TRACE_I 1
+#define TRACE_F 2
+#define TRACE_C 3
+
+
+typedef struct probe_trace_info_s probe_trace_info;
+typedef struct datlink_s datlink;
+
+struct datlink_s{
+       void * data;
+       size_t len;
+       datlink * next;
+};
+
+struct probe_trace_info_s{
+       int type;
+       char name[255];
+       datlink * data;
+       datlink * last;
+       probe_trace_info *next;
+};
+
+static char *run = NULL;
+static char *mod = NULL;
+static probe_trace_info *first_trace = NULL;
+
+/* Init the probing library */
+void modem_probe_init_int(char *modname, char *runname){
+       mod = malloc((strlen(modname)+1)*sizeof(char));
+       run = malloc((strlen(runname)+1)*sizeof(char));
+       strcpy(run,runname);
+       strcpy(mod,modname);
+}
+
+/* 
+ * Gather the data stored in the linked list into a single blob,
+ * freeing links and buffers as it goes
+ */
+void * gather_data(datlink * d,size_t * len){
+       size_t size = 0;
+       datlink * cur = d;
+       datlink * next;
+       while(cur!=NULL){
+               size += d->len;
+               cur = cur->next;
+       }
+       cur = d;
+       size_t i = 0;
+       void * newbuf = malloc(size);
+       
+       while(cur!=NULL){
+               memcpy(newbuf+i,cur->data,cur->len);
+               i += cur->len;
+               free(cur->data);
+               next = cur->next;
+               free(cur);
+               cur = next;
+       }
+       *len = size;
+       return newbuf;
+}
+
+/* Dump all of the traces into a nice octave-able dump file */
+void modem_probe_close_int(){
+       if(run==NULL)
+               return;
+       
+       probe_trace_info *cur,*next;
+       cur = first_trace;
+       FILE * dumpfile = fopen(run,"w");
+       void * dbuf;
+       size_t len;
+       
+       while(cur != NULL){
+               dbuf = gather_data(cur->data,&len);
+               switch(cur->type){
+                       case TRACE_I:
+                               octave_save_int(dumpfile,cur->name,(int32_t*)dbuf,1,len/sizeof(int32_t));
+                       break;
+                       case TRACE_F:
+                               octave_save_float(dumpfile,cur->name,(float*)dbuf,1,len/sizeof(float),10);
+                               break;
+                       case TRACE_C:
+                               octave_save_complex(dumpfile,cur->name,(COMP*)dbuf,1,len/sizeof(COMP),10);
+                               break;
+               }
+               next = cur->next;
+               free(cur);
+               free(dbuf);
+               cur = next;
+       }
+       
+       fclose(dumpfile);
+       free(run);
+       free(mod);
+}
+
+/* Look up or create a trace by name */
+probe_trace_info * modem_probe_get_trace(char * tracename){
+       probe_trace_info *cur,*npti;
+       
+       /* Make sure probe session is open */
+       if(run==NULL)
+               return NULL;
+       
+       cur = first_trace;
+       /* Walk through list, find trace with matching name */
+       while(cur != NULL){
+               /* We got one! */
+               if(strcmp( cur->name, tracename) == 0){
+                       return cur;
+               }
+               cur = cur->next;
+       }
+       /* None found, open a new trace */
+       
+       npti = (probe_trace_info *) malloc(sizeof(probe_trace_info));
+       npti->next = first_trace;
+       npti->data = NULL;
+       npti->last = NULL;
+       strcpy(npti->name,tracename);
+       first_trace = npti;
+       
+       return npti;
+       
+}
+
+void modem_probe_samp_i_int(char * tracename,int32_t samp[],size_t cnt){
+       probe_trace_info *pti;
+       datlink *ndat;
+       
+       pti = modem_probe_get_trace(tracename);
+       if(pti == NULL)
+               return;
+       
+       pti->type = TRACE_I;
+       
+       ndat = (datlink*) malloc(sizeof(datlink));
+       ndat->data = malloc(sizeof(int32_t)*cnt);
+       
+       ndat->len = cnt*sizeof(int32_t);
+       ndat->next = NULL;
+       memcpy(ndat->data,(void*)&(samp[0]),sizeof(int32_t)*cnt);
+       
+       if(pti->last!=NULL){
+               pti->last->next = ndat;
+               pti->last = ndat;
+       } else {
+               pti->data = ndat;
+               pti->last = ndat;
+       }
+       
+}
+
+void modem_probe_samp_f_int(char * tracename,float samp[],size_t cnt){
+       probe_trace_info *pti;
+       datlink *ndat;
+       
+       pti = modem_probe_get_trace(tracename);
+       if(pti == NULL)
+               return;
+       
+       pti->type = TRACE_F;
+       
+       ndat = (datlink*) malloc(sizeof(datlink));
+       ndat->data = malloc(sizeof(float)*cnt);
+       
+       ndat->len = cnt*sizeof(float);
+       ndat->next = NULL;
+       memcpy(ndat->data,(void*)&(samp[0]),sizeof(float)*cnt);
+       
+       if(pti->last!=NULL){
+               pti->last->next = ndat;
+               pti->last = ndat;
+       } else {
+               pti->data = ndat;
+               pti->last = ndat;
+       }
+}
+       
+void modem_probe_samp_c_int(char * tracename,COMP samp[],size_t cnt){
+       probe_trace_info *pti;
+       datlink *ndat;
+       
+       pti = modem_probe_get_trace(tracename);
+       if(pti == NULL)
+               return;
+       
+       pti->type = TRACE_C;
+       
+       ndat = (datlink*) malloc(sizeof(datlink));
+       ndat->data = malloc(sizeof(COMP)*cnt);
+       
+       ndat->len = cnt*sizeof(COMP);
+       ndat->next = NULL;
+       memcpy(ndat->data,(void*)&(samp[0]),sizeof(COMP)*cnt);
+       
+       if(pti->last!=NULL){
+               pti->last->next = ndat;
+               pti->last = ndat;
+       } else {
+               pti->data = ndat;
+               pti->last = ndat;
+       }
+}
diff --git a/codec2/branches/0.7/src/modem_probe.h b/codec2/branches/0.7/src/modem_probe.h
new file mode 100644 (file)
index 0000000..2faada1
--- /dev/null
@@ -0,0 +1,115 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: modem_probe.h
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 9 January 2016
+
+  Library to easily extract debug traces from modems during development
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __MODEMPROBE_H
+#define __MODEMPROBE_H
+#include <stdint.h>
+#include <stdlib.h>
+#include "comp.h"
+
+
+#ifdef MODEMPROBE_ENABLE
+
+/* Internal functions */
+void modem_probe_init_int(char *modname, char *runname);
+void modem_probe_close_int();
+
+void modem_probe_samp_i_int(char * tracename,int samp[],size_t cnt);
+void modem_probe_samp_f_int(char * tracename,float samp[],size_t cnt);
+void modem_probe_samp_c_int(char * tracename,COMP samp[],size_t cnt);
+
+/* 
+ * Init the probe library.
+ * char *modname - Name of the modem under test
+ * char *runname - Name/path of the file data is dumped to
+ */
+static inline void modem_probe_init(char *modname,char *runname){
+        modem_probe_init_int(modname,runname);
+}
+
+/*
+ * Dump traces to a file and clean up
+ */
+static inline void modem_probe_close(){
+        modem_probe_close_int();
+}
+
+/*
+ * Save some number of int samples to a named trace
+ * char *tracename - name of trace being saved to
+ * int samp[] - int samples
+ * size_t cnt - how many samples to save
+ */
+static inline void modem_probe_samp_i(char *tracename,int samp[],size_t cnt){
+        modem_probe_samp_i_int(tracename,samp,cnt);
+}
+
+/*
+ * Save some number of float samples to a named trace
+ * char *tracename - name of trace being saved to
+ * float samp[] - int samples
+ * size_t cnt - how many samples to save
+ */
+static inline void modem_probe_samp_f(char *tracename,float samp[],size_t cnt){
+        modem_probe_samp_f_int(tracename,samp,cnt);
+}       
+
+/*
+ * Save some number of complex samples to a named trace
+ * char *tracename - name of trace being saved to
+ * COMP samp[] - int samples
+ * size_t cnt - how many samples to save
+ */
+static inline void modem_probe_samp_c(char *tracename,COMP samp[],size_t cnt){
+        modem_probe_samp_c_int(tracename,samp,cnt);
+}
+
+#else
+
+static inline void modem_probe_init(char *modname,char *runname){
+        return;
+}
+
+static inline void modem_probe_close(){
+        return;
+}
+
+static inline void modem_probe_samp_i(char *name,int samp[],size_t sampcnt){
+        return;
+}
+
+static inline void modem_probe_samp_f(char *name,float samp[],size_t cnt){
+        return;
+}
+
+static inline void modem_probe_samp_c(char *name,COMP samp[],size_t cnt){
+        return;
+}
+
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/src/modem_stats.c b/codec2/branches/0.7/src/modem_stats.c
new file mode 100644 (file)
index 0000000..26a2fc1
--- /dev/null
@@ -0,0 +1,111 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: modem_stats.c
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2015
+
+  Common functions for returning demod stats from fdmdv and cohpsk modems.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <math.h>
+#include "modem_stats.h"
+#include "codec2_fdmdv.h"
+
+void modem_stats_open(struct MODEM_STATS *f)
+{
+    int i;
+
+    for(i=0; i<2*MODEM_STATS_NSPEC; i++)
+       f->fft_buf[i] = 0.0;
+    f->fft_cfg = kiss_fft_alloc (2*MODEM_STATS_NSPEC, 0, NULL, NULL);
+    assert(f->fft_cfg != NULL);
+}
+
+void modem_stats_close(struct MODEM_STATS *f)
+{
+    KISS_FFT_FREE(f->fft_cfg);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: modem_stats_get_rx_spectrum()
+  AUTHOR......: David Rowe
+  DATE CREATED: 9 June 2012
+
+  Returns the MODEM_STATS_NSPEC point magnitude spectrum of the rx signal in
+  dB. The spectral samples are scaled so that 0dB is the peak, a good
+  range for plotting is 0 to -40dB.
+
+  Note only the real part of the complex input signal is used at
+  present.  A complex variable is used for input for compatability
+  with the other rx signal procesing.
+
+  Successive calls can be used to build up a waterfall or spectrogram
+  plot, by mapping the received levels to colours.
+
+  The time-frequency resolution of the spectrum can be adjusted by varying
+  MODEM_STATS_NSPEC.  Note that a 2* MODEM_STATS_NSPEC size FFT is reqd to get
+  MODEM_STATS_NSPEC output points.  MODEM_STATS_NSPEC must be a power of 2.
+
+  See octave/tget_spec.m for a demo real time spectral display using
+  Octave. This demo averages the output over time to get a smoother
+  display:
+
+     av = 0.9*av + 0.1*mag_dB
+
+\*---------------------------------------------------------------------------*/
+
+void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COMP rx_fdm[], int nin)
+{
+    int   i,j;
+    COMP  fft_in[2*MODEM_STATS_NSPEC];
+    COMP  fft_out[2*MODEM_STATS_NSPEC];
+    float full_scale_dB;
+
+    /* update buffer of input samples */
+
+    for(i=0; i<2*MODEM_STATS_NSPEC-nin; i++)
+       f->fft_buf[i] = f->fft_buf[i+nin];
+    for(j=0; j<nin; j++,i++)
+       f->fft_buf[i] = rx_fdm[j].real;
+    assert(i == 2*MODEM_STATS_NSPEC);
+
+    /* window and FFT */
+
+    for(i=0; i<2*MODEM_STATS_NSPEC; i++) {
+       fft_in[i].real = f->fft_buf[i] * (0.5 - 0.5*cosf((float)i*2.0*M_PI/(2*MODEM_STATS_NSPEC)));
+       fft_in[i].imag = 0.0;
+    }
+
+    kiss_fft(f->fft_cfg, (kiss_fft_cpx *)fft_in, (kiss_fft_cpx *)fft_out);
+
+    /* FFT scales up a signal of level 1 FDMDV_NSPEC */
+
+    full_scale_dB = 20*log10(MODEM_STATS_NSPEC*FDMDV_SCALE);
+
+    /* scale and convert to dB */
+
+    for(i=0; i<MODEM_STATS_NSPEC; i++) {
+       mag_spec_dB[i]  = 10.0*log10f(fft_out[i].real*fft_out[i].real + fft_out[i].imag*fft_out[i].imag + 1E-12);
+       mag_spec_dB[i] -= full_scale_dB;
+    }
+}
diff --git a/codec2/branches/0.7/src/modem_stats.h b/codec2/branches/0.7/src/modem_stats.h
new file mode 100644 (file)
index 0000000..86309d8
--- /dev/null
@@ -0,0 +1,75 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: modem_stats.h
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2015
+
+  Common structure for returning demod stats from fdmdv and cohpsk modems.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef __cplusplus
+  extern "C" {
+#endif
+
+#ifndef __MODEM_STATS__
+#define __MODEM_STATS__
+
+#include "comp.h"
+#include "kiss_fft.h"
+
+#define MODEM_STATS_NC_MAX 20
+#define MODEM_STATS_NR_MAX 6
+#define MODEM_STATS_ET_MAX 8
+#define MODEM_STATS_NSPEC            512
+#define MODEM_STATS_MAX_F_HZ         4000
+
+struct MODEM_STATS {
+    int    Nc;
+    float  snr_est;                          /* estimated SNR of rx signal in dB (3 kHz noise BW)  */
+    COMP   rx_symbols[MODEM_STATS_NR_MAX][MODEM_STATS_NC_MAX+1];
+                                             /* latest received symbols, for scatter plot          */
+    int    nr;                               /* number of rows in rx_symbols                       */
+    int    sync;                             /* demod sync state                                   */
+    float  foff;                             /* estimated freq offset in Hz                        */
+    float  rx_timing;                        /* estimated optimum timing offset in samples         */
+    float  clock_offset;                     /* Estimated tx/rx sample clock offset in ppm         */
+
+    /* eye diagram traces */
+    /* Eye diagram plot -- first dim is trace number, second is the trace idx */
+    float  rx_eye[MODEM_STATS_ET_MAX][80];
+    int    neyetr;                           /* How many eye traces are plotted */
+    int    neyesamp;                         /* How many samples in the eye diagram */
+
+    /* Buf for FFT/waterfall */
+
+    float        fft_buf[2*MODEM_STATS_NSPEC];
+    kiss_fft_cfg fft_cfg;
+};
+
+void modem_stats_open(struct MODEM_STATS *f);
+void modem_stats_close(struct MODEM_STATS *f);
+void modem_stats_get_rx_spectrum(struct MODEM_STATS *f, float mag_spec_dB[], COMP rx_fdm[], int nin);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/codec2/branches/0.7/src/mpdecode_core.c b/codec2/branches/0.7/src/mpdecode_core.c
new file mode 100644 (file)
index 0000000..e3d6d12
--- /dev/null
@@ -0,0 +1,731 @@
+/*
+  FILE...: mpdecode_core.c
+  AUTHOR.: Matthew C. Valenti, Rohit Iyer Seshadri, David Rowe
+  CREATED: Sep 2016
+
+  C-callable core functions moved from MpDecode.c, so they can be used for
+  Octave and C programs.
+*/
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "mpdecode_core.h"
+
+int extract_output(char out_char[], int DecodedBits[], int ParityCheckCount[], 
+                    int max_iter, int CodeLength, int NumberParityBits);
+
+/* Phi function */
+static float phi0(
+                 float x )
+{
+  float z;
+
+  if (x>10)
+    return( 0 );
+  else if (x< 9.08e-5 )
+    return( 10 );
+  else if (x > 9)
+    return( 1.6881e-4 );
+  /* return( 1.4970e-004 ); */
+  else if (x > 8)
+    return( 4.5887e-4 );
+  /* return( 4.0694e-004 ); */
+  else if (x > 7)
+    return( 1.2473e-3 );
+  /* return( 1.1062e-003 ); */
+  else if (x > 6)
+    return( 3.3906e-3 );
+  /* return( 3.0069e-003 ); */
+  else if (x > 5)
+    return( 9.2168e-3 );
+  /* return( 8.1736e-003 ); */
+  else {
+    z = (float) exp(x);
+    return( (float) log( (z+1)/(z-1) ) ); 
+  }
+}
+
+static float correction(
+                       float xinput )
+{
+  if (xinput > 2.625 )
+    return( 0 );
+  else if (xinput < 1 )
+    return( -0.375*xinput + 0.6825 );
+  else 
+    return( -0.1875*xinput + 0.5 );
+
+}
+
+static float LambdaAPPstar(    float mag1,
+                               float mag2 )
+{
+  if (mag1 > mag2)
+    return( fabs( mag2 + correction( mag1 + mag2 ) - correction( mag1 - mag2 ) ) );
+  else
+    return( fabs( mag1 + correction( mag1 + mag2 ) - correction( mag2 - mag1 ) ) );
+}
+
+void init_c_v_nodes(struct c_node *c_nodes, 
+                    int     shift, 
+                    int     NumberParityBits, 
+                    int     max_row_weight,
+                    double *H_rows,
+                    int     H1,
+                    int     CodeLength,
+                    struct v_node *v_nodes, 
+                    int     NumberRowsHcols, 
+                    double *H_cols,
+                    int     max_col_weight,
+                    int     dec_type,
+                    double *input)
+{
+    int i, j, k, count, cnt, c_index, v_index;
+
+    /* first determine the degree of each c-node */
+       
+    if (shift ==0){    
+        for (i=0;i<NumberParityBits;i++) {
+            count = 0;
+            for (j=0;j<max_row_weight;j++) {
+                if ( H_rows[i+j*NumberParityBits] > 0 ) {
+                    count++;
+                }
+            }
+            c_nodes[i].degree = count;
+            if (H1){
+                if (i==0){
+                    c_nodes[i].degree=count+1;
+                } 
+                else{
+                    c_nodes[i].degree=count+2;
+                }
+            }
+        }
+    }  
+    else{      
+        cnt=0; 
+        for (i=0;i<(NumberParityBits/shift);i++) {             
+            for (k=0;k<shift;k++){
+                count = 0;
+                for (j=0;j<max_row_weight;j++) {
+                    if ( H_rows[cnt+j*NumberParityBits] > 0 ) {
+                        count++;
+                    }
+                }
+                c_nodes[cnt].degree = count;
+                if ((i==0)||(i==(NumberParityBits/shift)-1)){
+                    c_nodes[cnt].degree=count+1;
+                } 
+                else{
+                    c_nodes[cnt].degree=count+2;
+                }
+                cnt++;
+            }     
+        }      
+    }
+                       
+    if (H1){
+
+        if (shift ==0){
+            for (i=0;i<NumberParityBits;i++) {
+                /* now that we know the size, we can dynamically allocate memory */
+                c_nodes[i].index =  calloc( c_nodes[i].degree, sizeof( int ) );
+                c_nodes[i].message =calloc( c_nodes[i].degree, sizeof( float ) );
+                c_nodes[i].socket = calloc( c_nodes[i].degree, sizeof( int ) );
+                       
+                for (j=0;j<c_nodes[i].degree-2;j++) {
+                    c_nodes[i].index[j] = (int) (H_rows[i+j*NumberParityBits] - 1);
+                }                          
+                j=c_nodes[i].degree-2;
+               
+                if (i==0){
+                    c_nodes[i].index[j] = (int) (H_rows[i+j*NumberParityBits] - 1);                            
+                }
+                else {
+                    c_nodes[i].index[j] = (CodeLength-NumberParityBits)+i-1;
+                }
+                                               
+                j=c_nodes[i].degree-1;                 
+                c_nodes[i].index[j] = (CodeLength-NumberParityBits)+i;
+                   
+            }                
+        }              
+        if (shift >0){
+            cnt=0;
+            for (i=0;i<(NumberParityBits/shift);i++){            
+                 
+                for (k =0;k<shift;k++){
+                    c_nodes[cnt].index =  calloc( c_nodes[cnt].degree, sizeof( int ) );
+                    c_nodes[cnt].message =calloc( c_nodes[cnt].degree, sizeof( float ) );
+                    c_nodes[cnt].socket = calloc( c_nodes[cnt].degree, sizeof( int ) );
+                                          
+                    for (j=0;j<c_nodes[cnt].degree-2;j++) {
+                        c_nodes[cnt].index[j] = (int) (H_rows[cnt+j*NumberParityBits] - 1);
+                    }                      
+                    j=c_nodes[cnt].degree-2;
+                    if ((i ==0)||(i==(NumberParityBits/shift-1))){
+                        c_nodes[cnt].index[j] = (int) (H_rows[cnt+j*NumberParityBits] - 1);    
+                    }
+                    else{
+                        c_nodes[cnt].index[j] = (CodeLength-NumberParityBits)+k+shift*(i);
+                    }                  
+                    j=c_nodes[cnt].degree-1;                        
+                    c_nodes[cnt].index[j] = (CodeLength-NumberParityBits)+k+shift*(i+1);
+                    if (i== (NumberParityBits/shift-1))
+                        {
+                            c_nodes[cnt].index[j] = (CodeLength-NumberParityBits)+k+shift*(i);
+                        }
+                    cnt++;                         
+                } 
+            }
+        }
+                               
+    } else {
+        for (i=0;i<NumberParityBits;i++) {
+            /* now that we know the size, we can dynamically allocate memory */
+            c_nodes[i].index =  calloc( c_nodes[i].degree, sizeof( int ) );
+            c_nodes[i].message =calloc( c_nodes[i].degree, sizeof( float ) );
+            c_nodes[i].socket = calloc( c_nodes[i].degree, sizeof( int ) );
+            for (j=0;j<c_nodes[i].degree;j++){
+                c_nodes[i].index[j] = (int) (H_rows[i+j*NumberParityBits] - 1);
+            }                  
+        }
+    }  
+
+
+    /* determine degree of each v-node */
+
+    for(i=0;i<(CodeLength-NumberParityBits+shift);i++){
+        count=0;               
+        for (j=0;j<max_col_weight;j++) {
+            if ( H_cols[i+j*NumberRowsHcols] > 0 ) {
+                count++;
+            }
+        }
+        v_nodes[i].degree = count;
+    }
+       
+    for(i=CodeLength-NumberParityBits+shift;i<CodeLength;i++){
+        count=0;
+        if (H1){
+            if(i!=CodeLength-1){
+                v_nodes[i].degree=2;
+            }  else{
+                v_nodes[i].degree=1;
+            }   
+                       
+        } else{
+            for (j=0;j<max_col_weight;j++) {
+                if ( H_cols[i+j*NumberRowsHcols] > 0 ) {
+                    count++;
+                }
+            }      
+            v_nodes[i].degree = count;           
+        }       
+    }  
+        
+    if (shift>0){
+        v_nodes[CodeLength-1].degree =v_nodes[CodeLength-1].degree+1;                     
+    }
+       
+    
+    /* set up v_nodes */
+
+    for (i=0;i<CodeLength;i++) {
+        /* allocate memory according to the degree of the v-node */
+        v_nodes[i].index = calloc( v_nodes[i].degree, sizeof( int ) );
+        v_nodes[i].message = calloc( v_nodes[i].degree, sizeof( float ) );
+        v_nodes[i].sign = calloc( v_nodes[i].degree, sizeof( int ) );
+        v_nodes[i].socket = calloc( v_nodes[i].degree, sizeof( int ) );
+               
+        /* index tells which c-nodes this v-node is connected to */
+        v_nodes[i].initial_value = input[i];
+        count=0;
+
+        for (j=0;j<v_nodes[i].degree;j++) {                    
+            if ((H1)&& (i>=CodeLength-NumberParityBits+shift)){
+                v_nodes[i].index[j]=i-(CodeLength-NumberParityBits+shift)+count;
+                if (shift ==0){
+                    count=count+1;
+                }
+                else{
+                    count=count+shift;
+                }
+            } else  {
+                v_nodes[i].index[j] = (int) (H_cols[i+j*NumberRowsHcols] - 1);
+            }                  
+                                               
+            /* search the connected c-node for the proper message value */
+            for (c_index=0;c_index<c_nodes[ v_nodes[i].index[j] ].degree;c_index++)
+                if ( c_nodes[ v_nodes[i].index[j] ].index[c_index] == i ) {
+                    v_nodes[i].socket[j] = c_index;
+                    break;
+                }                              
+            /* initialize v-node with received LLR */                  
+            if ( dec_type == 1)
+                v_nodes[i].message[j] = fabs(input[i]);
+            else
+                v_nodes[i].message[j] = phi0( fabs(input[i]) );
+                               
+            if (input[i] < 0)
+                v_nodes[i].sign[j] = 1;                        
+        }
+       
+    }
+       
+       
+       
+    /* now finish setting up the c_nodes */
+    for (i=0;i<NumberParityBits;i++) {         
+        /* index tells which v-nodes this c-node is connected to */
+        for (j=0;j<c_nodes[i].degree;j++) {                    
+            /* search the connected v-node for the proper message value */
+            for (v_index=0;v_index<v_nodes[ c_nodes[i].index[j] ].degree;v_index++)
+                if (v_nodes[ c_nodes[i].index[j] ].index[v_index] == i ) {
+                    c_nodes[i].socket[j] = v_index;
+                    break;
+                }
+        }
+    }
+
+}
+
+
+/* function for doing the MP decoding */
+void ApproximateMinStar(        int      BitErrors[],
+                                int      DecodedBits[],
+                                struct c_node c_nodes[],
+                                struct v_node v_nodes[],
+                                int      CodeLength,
+                                int      NumberParityBits,
+                                int      max_iter )
+{
+  int i,j, iter;
+  int sign;
+  float temp_sum;
+  float Qi;
+
+  float delta, minval, deltaAPP;
+  int mink;
+
+  for (iter=0;iter<max_iter;iter++) {
+    /* update r */
+    for (j=0;j<NumberParityBits;j++) { 
+      /* start new code for approximate-min-star */
+      mink = 0;
+      sign = v_nodes[ c_nodes[j].index[0] ].sign[ c_nodes[j].socket[0] ];
+      minval = v_nodes[ c_nodes[j].index[0] ].message[ c_nodes[j].socket[0] ];
+               
+      for (i=1;i<c_nodes[j].degree;i++) {
+       /* first find the minimum magnitude input message */
+       if ( v_nodes[ c_nodes[j].index[i] ].message[ c_nodes[j].socket[i] ] < minval ) {
+         mink = i;
+         minval = v_nodes[ c_nodes[j].index[i] ].message[ c_nodes[j].socket[i] ];                                                      
+       }
+       /* update the aggregate sign */
+       sign ^= v_nodes[ c_nodes[j].index[i] ].sign[ c_nodes[j].socket[i] ];
+      }
+
+      /* find the magnitude to send out the minimum input magnitude branch */
+      if ( mink == 0 ) {
+       delta = v_nodes[ c_nodes[j].index[1] ].message[ c_nodes[j].socket[1] ];
+       for (i=2;i<c_nodes[j].degree;i++) {
+         delta = LambdaAPPstar( delta, v_nodes[ c_nodes[j].index[i] ].message[ c_nodes[j].socket[i] ] );
+       }
+      } else {
+       delta = v_nodes[ c_nodes[j].index[0] ].message[ c_nodes[j].socket[0] ];
+       for (i=1;i<c_nodes[j].degree;i++) {
+         if ( i != mink )
+           delta = LambdaAPPstar( delta, v_nodes[ c_nodes[j].index[i] ].message[ c_nodes[j].socket[i] ] );
+       }
+      }
+
+      deltaAPP = LambdaAPPstar( delta, v_nodes[ c_nodes[j].index[mink] ].message[ c_nodes[j].socket[mink] ] );
+
+      /* compute outgoing messages */
+      for (i=0;i<c_nodes[j].degree;i++) {
+       if ( i == mink ) {
+         if ( sign^v_nodes[ c_nodes[j].index[i] ].sign[ c_nodes[j].socket[i] ] )
+           c_nodes[j].message[i] = - delta;
+         else
+           c_nodes[j].message[i] = delta;
+       } else {
+         if ( sign^v_nodes[ c_nodes[j].index[i] ].sign[ c_nodes[j].socket[i] ] )
+           c_nodes[j].message[i] = - deltaAPP;
+         else
+           c_nodes[j].message[i] = deltaAPP;
+       }
+      }                
+    }
+
+    /* update q */
+    for (i=0;i<CodeLength;i++) {
+
+      /* first compute the LLR */
+      Qi = v_nodes[i].initial_value;
+      for (j=0;j<v_nodes[i].degree;j++) {                              
+       Qi += c_nodes[ v_nodes[i].index[j] ].message[ v_nodes[i].socket[j] ];
+      }
+
+      /* make hard decision */                 
+      if (Qi < 0) {
+       DecodedBits[iter+max_iter*i] = 1;
+       BitErrors[iter]++;
+      }
+
+      /* now subtract to get the extrinsic information */
+      for (j=0;j<v_nodes[i].degree;j++) {
+       temp_sum = Qi - c_nodes[ v_nodes[i].index[j] ].message[ v_nodes[i].socket[j] ];
+                               
+       v_nodes[i].message[j] = fabs( temp_sum );
+       if (temp_sum > 0)
+         v_nodes[i].sign[j] = 0;
+       else
+         v_nodes[i].sign[j] = 1;
+      }
+    }
+
+    /* detect errors */
+    if (BitErrors[iter] == 0)
+      break; 
+  }
+}
+
+
+/* function for doing the MP decoding */
+void MinSum(            int      BitErrors[],
+                                int      DecodedBits[],
+                                struct c_node c_nodes[],
+                                struct v_node v_nodes[],
+                                int      CodeLength,
+                                int      NumberParityBits,
+                                int      max_iter, 
+                                float    r_scale_factor,
+                                float    q_scale_factor, 
+                                int      data[] )
+{
+  int i,j, iter, i_prime;
+  float min_beta;
+  int sign;
+  float temp_sum;
+  float Qi;
+
+  for (iter=0;iter<max_iter;iter++) {
+
+    /* update r */
+    for (j=0;j<NumberParityBits;j++) {
+      sign = 0;
+      for (i=0;i<c_nodes[j].degree;i++) 
+       sign ^= v_nodes[ c_nodes[j].index[i] ].sign[ c_nodes[j].socket[i] ];
+
+      for (i=0;i<c_nodes[j].degree;i++) {
+       min_beta = 1000;                
+                                                               
+       for (i_prime=0;i_prime<c_nodes[j].degree;i_prime++) 
+         if ( ( v_nodes[ c_nodes[j].index[i_prime] ].message[c_nodes[j].socket[i_prime]] < min_beta )&&(i_prime != i) )
+           min_beta = v_nodes[ c_nodes[j].index[i_prime] ].message[c_nodes[j].socket[i_prime]];
+
+       if ( sign^v_nodes[ c_nodes[j].index[i] ].sign[ c_nodes[j].socket[i] ] )
+         c_nodes[j].message[i] = -min_beta*r_scale_factor;
+       else
+         c_nodes[j].message[i] = min_beta*r_scale_factor;
+      }
+    }
+
+    /* update q */
+    for (i=0;i<CodeLength;i++) {
+                       
+      /* first compute the LLR */
+      Qi = v_nodes[i].initial_value;
+      for (j=0;j<v_nodes[i].degree;j++) {                              
+       Qi += c_nodes[ v_nodes[i].index[j] ].message[ v_nodes[i].socket[j] ];
+      }
+
+      /* make hard decision */                 
+      if (Qi < 0) {
+       DecodedBits[iter+max_iter*i] = 1;
+      }
+
+      /* now subtract to get the extrinsic information */
+      for (j=0;j<v_nodes[i].degree;j++) {
+       temp_sum = Qi - c_nodes[ v_nodes[i].index[j] ].message[ v_nodes[i].socket[j] ];
+                               
+       v_nodes[i].message[j] = fabs( temp_sum )*q_scale_factor;
+       if (temp_sum > 0)
+         v_nodes[i].sign[j] = 0;
+       else
+         v_nodes[i].sign[j] = 1;
+      }
+    }
+
+    /* count data bit errors, assuming that it is systematic */
+    for (i=0;i<CodeLength-NumberParityBits;i++)
+      if ( DecodedBits[iter+max_iter*i] != data[i] )
+       BitErrors[iter]++;
+
+    /* detect errors */
+    if (BitErrors[iter] == 0)
+      break; 
+  }
+}
+
+
+/* function for doing the MP decoding */
+void SumProduct(        int      BitErrors[],
+                        int      DecodedBits[],
+                        struct c_node c_nodes[],
+                        struct v_node v_nodes[],
+                        int      CodeLength,
+                        int      NumberParityBits,
+                        int      max_iter,
+                        float    r_scale_factor,
+                        float    q_scale_factor, 
+                        int      data[] )
+{
+  int i,j, iter;
+  float phi_sum;
+  int sign;
+  float temp_sum;
+  float Qi;
+  int   ssum; 
+
+  for (iter=0;iter<max_iter;iter++) {
+    /* update r */
+    ssum = 0; 
+    for (j=0;j<NumberParityBits;j++) {         
+      sign = v_nodes[ c_nodes[j].index[0] ].sign[ c_nodes[j].socket[0] ];
+      phi_sum = v_nodes[ c_nodes[j].index[0] ].message[ c_nodes[j].socket[0] ];
+                       
+      for (i=1;i<c_nodes[j].degree;i++) {
+       phi_sum += v_nodes[ c_nodes[j].index[i] ].message[ c_nodes[j].socket[i] ];
+       sign ^= v_nodes[ c_nodes[j].index[i] ].sign[ c_nodes[j].socket[i] ];
+      }
+
+      if (sign==0) ssum++; 
+               
+      for (i=0;i<c_nodes[j].degree;i++) {
+       if ( sign^v_nodes[ c_nodes[j].index[i] ].sign[ c_nodes[j].socket[i] ] ) {
+         c_nodes[j].message[i] = -phi0( phi_sum - v_nodes[ c_nodes[j].index[i] ].message[ c_nodes[j].socket[i] ] )*r_scale_factor;
+       } else
+         c_nodes[j].message[i] = phi0( phi_sum - v_nodes[ c_nodes[j].index[i] ].message[ c_nodes[j].socket[i] ] )*r_scale_factor;
+      }
+    }
+
+    /* update q */
+    for (i=0;i<CodeLength;i++) {
+
+      /* first compute the LLR */
+      Qi = v_nodes[i].initial_value;
+      for (j=0;j<v_nodes[i].degree;j++) {                              
+       Qi += c_nodes[ v_nodes[i].index[j] ].message[ v_nodes[i].socket[j] ];
+      }
+
+      /* make hard decision */                 
+      if (Qi < 0) {
+       DecodedBits[iter+max_iter*i] = 1;
+      }
+
+      /* now subtract to get the extrinsic information */
+      for (j=0;j<v_nodes[i].degree;j++) {
+       temp_sum = Qi - c_nodes[ v_nodes[i].index[j] ].message[ v_nodes[i].socket[j] ];
+                               
+       v_nodes[i].message[j] = phi0( fabs( temp_sum ) )*q_scale_factor;
+       if (temp_sum > 0)
+         v_nodes[i].sign[j] = 0;
+       else
+         v_nodes[i].sign[j] = 1;
+      }
+    }
+
+    /* count data bit errors, assuming that it is systematic */
+    for (i=0;i<CodeLength-NumberParityBits;i++)
+      if ( DecodedBits[iter+max_iter*i] != data[i] )
+       BitErrors[iter]++;
+
+    /* Halt if zero errors */
+    if (BitErrors[iter] == 0)
+      break; 
+
+    // added by Bill -- reuse the BitErrors array to count PCs
+    // count the number of PC satisfied and exit if all OK
+    BitErrors[iter] = ssum;
+    if (ssum==NumberParityBits) break;
+
+
+  }
+   
+  // printf(" ssum is %d \n",   ssum); 
+}
+
+
+/* Convenience function to call LDPC decoder from C programs */
+
+int run_ldpc_decoder(struct LDPC *ldpc, char out_char[], double input[]) {
+    int                max_iter, dec_type;
+    float       q_scale_factor, r_scale_factor;
+    int                max_row_weight, max_col_weight;
+    int         CodeLength, NumberParityBits, NumberRowsHcols, shift, H1;
+    int         i;
+    struct c_node *c_nodes;
+    struct v_node *v_nodes;
+    
+    /* default values */
+
+    max_iter  = ldpc->max_iter;
+    dec_type  = ldpc->dec_type;
+    q_scale_factor = ldpc->q_scale_factor;
+    r_scale_factor = ldpc->r_scale_factor;
+
+    CodeLength = ldpc->CodeLength;                    /* length of entire codeword */
+    NumberParityBits = ldpc->NumberParityBits;
+    NumberRowsHcols = ldpc->NumberRowsHcols;
+
+    int *DecodedBits = calloc( max_iter*CodeLength, sizeof( int ) );
+    int *ParityCheckCount = calloc( max_iter, sizeof(int) );
+
+    /* derive some parameters */
+
+    shift = (NumberParityBits + NumberRowsHcols) - CodeLength;
+    if (NumberRowsHcols == CodeLength) {
+        H1=0;
+        shift=0;
+    } else {
+        H1=1;
+    }
+       
+    max_row_weight = ldpc->max_row_weight;
+    max_col_weight = ldpc->max_col_weight;
+    /* 
+    c_nodes = calloc( NumberParityBits, sizeof( struct c_node ) );
+    v_nodes = calloc( CodeLength, sizeof( struct v_node));
+    */
+    /* initialize c-node and v-node structures */
+
+    c_nodes = calloc( NumberParityBits, sizeof( struct c_node ) );
+    v_nodes = calloc( CodeLength, sizeof( struct v_node));
+       
+    init_c_v_nodes(c_nodes, shift, NumberParityBits, max_row_weight, ldpc->H_rows, H1, CodeLength, 
+                   v_nodes, NumberRowsHcols, ldpc->H_cols, max_col_weight, dec_type, input);
+
+    int DataLength = CodeLength - NumberParityBits;
+    int *data_int = calloc( DataLength, sizeof(int) );
+       
+    /* need to clear these on each call */
+
+    for(i=0; i<max_iter; i++)
+        ParityCheckCount[i] = 0;
+     for(i=0; i<max_iter*CodeLength; i++)
+         DecodedBits[i] = 0;
+
+    /* Call function to do the actual decoding */
+
+    if ( dec_type == 1) {
+        MinSum( ParityCheckCount, DecodedBits, c_nodes, v_nodes, CodeLength, 
+                NumberParityBits, max_iter, r_scale_factor, q_scale_factor, data_int );
+    } else if ( dec_type == 2) {
+        fprintf(stderr, "dec_type = 2 not currently supported");
+        /* ApproximateMinStar( BitErrors, DecodedBits, c_nodes, v_nodes, 
+           CodeLength, NumberParityBits, max_iter, r_scale_factor, q_scale_factor );*/
+    } else {
+        SumProduct( ParityCheckCount, DecodedBits, c_nodes, v_nodes, CodeLength, 
+                    NumberParityBits, max_iter, r_scale_factor, q_scale_factor, data_int ); 
+    }
+
+    int iter = extract_output(out_char, DecodedBits, ParityCheckCount, max_iter, CodeLength, NumberParityBits);
+
+    /* Clean up memory */
+
+    free(ParityCheckCount);
+    free(DecodedBits);
+    free( data_int );
+
+    /*  Cleaning c-node elements */
+
+    for (i=0;i<NumberParityBits;i++) {
+        free( c_nodes[i].index );
+        free( c_nodes[i].message );
+        free( c_nodes[i].socket );
+    }
+       
+    /* printf( "Cleaning c-nodes \n" ); */
+    free( c_nodes );
+       
+    /* printf( "Cleaning v-node elements\n" ); */
+    for (i=0;i<CodeLength;i++) {
+        free( v_nodes[i].index);
+        free( v_nodes[i].sign );
+        free( v_nodes[i].message );
+        free( v_nodes[i].socket );
+    }
+       
+    /* printf( "Cleaning v-nodes \n" ); */
+    free( v_nodes );
+
+    return iter;
+}
+
+
+void sd_to_llr(double llr[], double sd[], int n) {
+    double sum, mean, sign, sumsq, estvar, estEsN0, x;
+    int i;
+
+    /* convert SD samples to LLRs -------------------------------*/
+
+    sum = 0.0;
+    for(i=0; i<n; i++)
+        sum += fabs(sd[i]);
+    mean = sum/n;
+                
+    /* scale by mean to map onto +/- 1 symbol position */
+
+    for(i=0; i<n; i++) {
+        sd[i] /= mean;
+    }
+
+    /* find variance from +/-1 symbol position */
+
+    sum = sumsq = 0.0; 
+    for(i=0; i<n; i++) {
+        sign = (sd[i] > 0.0) - (sd[i] < 0.0);
+        x = (sd[i] - sign);
+        sum += x;
+        sumsq += x*x;
+    }
+    mean = sum/n;
+    estvar = sumsq/n - mean*mean;
+
+    estEsN0 = 1.0/(2.0 * estvar + 1E-3); 
+    for(i=0; i<n; i++)
+        llr[i] = 4.0 * estEsN0 * sd[i];              
+}
+
+
+int extract_output(char out_char[], int DecodedBits[], int ParityCheckCount[], int max_iter, int CodeLength, int NumberParityBits) {
+    int i, j;
+
+    /* extract output bits from iteration that solved all parity
+       equations, or failing that the last iteration. */
+
+    int converged = 0;
+    int iter = 0;
+    for (i=0;i<max_iter;i++) {
+        if (converged == 0)
+            iter++;
+        if ((ParityCheckCount[i] == NumberParityBits)) {
+            for (j=0; j<CodeLength; j++) {
+                out_char[j] = DecodedBits[i+j*max_iter];
+            }
+            converged = 1;
+        }               
+    }
+    if (converged == 0) {
+        for (j=0; j<CodeLength; j++) {
+            out_char[j] = DecodedBits[max_iter-1+j*max_iter];
+        }
+    }
+    //fprintf(stderr, "iter: %d\n", iter);
+    return iter;
+}
+
diff --git a/codec2/branches/0.7/src/mpdecode_core.h b/codec2/branches/0.7/src/mpdecode_core.h
new file mode 100644 (file)
index 0000000..bbb6250
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+  FILE...: mpdecode_core.h
+  AUTHOR.: David Rowe
+  CREATED: Sep 2016
+
+  C-callable core functions for MpDecode, so they can be used for
+  Octave and C programs.  Also some convenience functions to help use
+  the C-callable LDPC decoder in C programs.
+*/
+
+#ifndef __MPDECODE_CORE__
+#define __MPDECODE_CORE__
+
+struct LDPC {
+    int max_iter;
+    int dec_type;
+    int q_scale_factor;
+    int r_scale_factor;
+    int CodeLength;
+    int NumberParityBits;
+    int NumberRowsHcols;
+    int max_row_weight;
+    int max_col_weight;
+    double *H_rows;
+    double *H_cols;
+};
+
+int run_ldpc_decoder(struct LDPC *ldpc, char out_char[], double input[]);
+
+void sd_to_llr(double llr[], double sd[], int n);
+
+struct v_node {
+  int degree;
+  float initial_value;
+  int *index;  /* the index of a c_node it is connected to */
+  int *socket; /* socket number at the c_node */
+  float *message;     
+  int *sign;
+};
+
+struct c_node {
+  int degree;
+  int *index;                     
+  float *message;     
+  int *socket; /* socket number at the v_node */
+};
+
+void init_c_v_nodes(struct c_node *c_nodes, 
+                    int     shift, 
+                    int     NumberParityBits, 
+                    int     max_row_weight,
+                    double *H_rows,
+                    int     H1,
+                    int     CodeLength,
+                    struct v_node *v_nodes, 
+                    int     NumberRowsHcols, 
+                    double *H_cols,
+                    int     max_col_weight,
+                    int     dec_type,
+                    double *input);
+
+void ApproximateMinStar(        int      BitErrors[],
+                                int      DecodedBits[],
+                                struct c_node c_nodes[],
+                                struct v_node v_nodes[],
+                                int      CodeLength,
+                                int      NumberParityBits,
+                                int      max_iter );
+
+void MinSum(            int      BitErrors[],
+                                int      DecodedBits[],
+                                struct c_node c_nodes[],
+                                struct v_node v_nodes[],
+                                int      CodeLength,
+                                int      NumberParityBits,
+                                int      max_iter, 
+                                float    r_scale_factor,
+                                float    q_scale_factor, 
+                                int      data[] );
+
+
+void SumProduct(        int      BitErrors[],
+                        int      DecodedBits[],
+                        struct c_node c_nodes[],
+                        struct v_node v_nodes[],
+                        int      CodeLength,
+                        int      NumberParityBits,
+                        int      max_iter,
+                        float    r_scale_factor,
+                        float    q_scale_factor, 
+                        int      data[]);
+
+#endif
diff --git a/codec2/branches/0.7/src/newamp1.c b/codec2/branches/0.7/src/newamp1.c
new file mode 100644 (file)
index 0000000..f6af1b8
--- /dev/null
@@ -0,0 +1,607 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: newamp1.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Quantisation functions for the sinusoidal coder, using "newamp1"
+  algorithm that resamples variable rate L [Am} to a fixed rate K then
+  VQs.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright David Rowe 2017
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "defines.h"
+#include "phase.h"
+#include "quantise.h"
+#include "mbest.h"
+#include "newamp1.h"
+
+#define NEWAMP1_VQ_MBEST_DEPTH 5  /* how many candidates we keep for each stage of mbest search */
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_para()
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  General 2nd order parabolic interpolator.  Used splines orginally,
+  but this is much simpler and we don't need much accuracy.  Given two
+  vectors of points xp and yp, find interpolated values y at points x.
+
+\*---------------------------------------------------------------------------*/
+
+void interp_para(float y[], float xp[], float yp[], int np, float x[], int n)
+{
+    assert(np >= 3);
+
+    int k,i;
+    float xi, x1, y1, x2, y2, x3, y3, a, b;
+
+    k = 0;
+    for (i=0; i<n; i++) {
+        xi = x[i];
+
+        /* k is index into xp of where we start 3 points used to form parabola */
+
+        while ((xp[k+1] < xi) && (k < (np-3)))
+            k++;
+    
+        x1 = xp[k]; y1 = yp[k]; x2 = xp[k+1]; y2 = yp[k+1]; x3 = xp[k+2]; y3 = yp[k+2];
+
+        //printf("k: %d np: %d i: %d xi: %f x1: %f y1: %f\n", k, np, i, xi, x1, y1);
+
+        a = ((y3-y2)/(x3-x2)-(y2-y1)/(x2-x1))/(x3-x1);
+        b = ((y3-y2)/(x3-x2)*(x2-x1)+(y2-y1)/(x2-x1)*(x3-x2))/(x3-x1);
+  
+        y[i] = a*(xi-x2)*(xi-x2) + b*(xi-x2) + y2;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: ftomel()
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Non linear sampling of frequency axis, reducing the "rate" is a
+  first step before VQ
+
+\*---------------------------------------------------------------------------*/
+
+float ftomel(float fHz) {
+    float mel = floorf(2595.0*log10f(1.0 + fHz/700.0)+0.5);
+    return mel;
+}
+
+void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, float mel_start, float mel_end)
+{
+    float step = (mel_end-mel_start)/(K-1);
+    float mel;
+    int k;
+
+    mel = mel_start;
+    for (k=0; k<K; k++) {
+        rate_K_sample_freqs_kHz[k] = 0.7*(pow(10.0, (mel/2595.0)) - 1.0);
+        mel += step;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: resample_const_rate_f()
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Resample Am from time-varying rate L=floor(pi/Wo) to fixed rate K.
+
+\*---------------------------------------------------------------------------*/
+
+void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K)
+{
+    int m;
+    float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1], AmdB_peak;
+
+    /* convert rate L=pi/Wo amplitude samples to fixed rate K */
+
+    AmdB_peak = -100.0;
+    for(m=1; m<=model->L; m++) {
+        AmdB[m] = 20.0*log10(model->A[m]+1E-16);
+        if (AmdB[m] > AmdB_peak) {
+            AmdB_peak = AmdB[m];
+        }
+        rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
+        //printf("m: %d AmdB: %f AmdB_peak: %f  sf: %f\n", m, AmdB[m], AmdB_peak, rate_L_sample_freqs_kHz[m]);
+    }
+    
+    /* clip between peak and peak -50dB, to reduce dynamic range */
+
+    for(m=1; m<=model->L; m++) {
+        if (AmdB[m] < (AmdB_peak-50.0)) {
+            AmdB[m] = AmdB_peak-50.0;
+        }
+    }
+
+    interp_para(rate_K_vec, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, rate_K_sample_freqs_kHz, K);    
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: rate_K_mbest_encode
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Two stage rate K newamp1 VQ quantiser using mbest search.
+
+\*---------------------------------------------------------------------------*/
+
+float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries)
+{
+  int i, j, n1, n2;
+  const float *codebook1 = newamp1vq_cb[0].cb;
+  const float *codebook2 = newamp1vq_cb[1].cb;
+  struct MBEST *mbest_stage1, *mbest_stage2;
+  float target[ndim];
+  float w[ndim];
+  int   index[MBEST_STAGES];
+  float mse, tmp;
+
+  /* codebook is compiled for a fixed K */
+
+  assert(ndim == newamp1vq_cb[0].k);
+
+  /* equal weights, could be argued mel freq axis gives freq dep weighting */
+
+  for(i=0; i<ndim; i++)
+      w[i] = 1.0;
+
+  mbest_stage1 = mbest_create(mbest_entries);
+  mbest_stage2 = mbest_create(mbest_entries);
+  for(i=0; i<MBEST_STAGES; i++)
+      index[i] = 0;
+
+  /* Stage 1 */
+
+  mbest_search(codebook1, x, w, ndim, newamp1vq_cb[0].m, mbest_stage1, index);
+  MBEST_PRINT("Stage 1:", mbest_stage1);
+
+  /* Stage 2 */
+
+  for (j=0; j<mbest_entries; j++) {
+      index[1] = n1 = mbest_stage1->list[j].index[0];
+      for(i=0; i<ndim; i++)
+         target[i] = x[i] - codebook1[ndim*n1+i];
+      mbest_search(codebook2, target, w, ndim, newamp1vq_cb[1].m, mbest_stage2, index);
+  }
+  MBEST_PRINT("Stage 2:", mbest_stage2);
+
+  n1 = mbest_stage2->list[0].index[1];
+  n2 = mbest_stage2->list[0].index[0];
+  mse = 0.0;
+  for (i=0;i<ndim;i++) {
+      tmp = codebook1[ndim*n1+i] + codebook2[ndim*n2+i];
+      mse += (x[i]-tmp)*(x[i]-tmp);
+      xq[i] = tmp;
+  }
+
+  mbest_destroy(mbest_stage1);
+  mbest_destroy(mbest_stage2);
+
+  indexes[0] = n1; indexes[1] = n2;
+
+  return mse;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: post_filter
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Post Filter, has a big impact on speech quality after VQ.  When used
+  on a mean removed rate K vector, it raises formants, and supresses
+  anti-formants.  As it manipulates amplitudes, we normalise energy to
+  prevent clipping or large level variations.  pf_gain of 1.2 to 1.5
+  (dB) seems to work OK.  Good area for further investigations and
+  improvements in speech quality.
+
+\*---------------------------------------------------------------------------*/
+
+void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_gain)
+{
+    int k;
+
+    /*
+      vec is rate K vector describing spectrum of current frame lets
+      pre-emp before applying PF. 20dB/dec over 300Hz.  Postfilter
+      affects energy of frame so we measure energy before and after
+      and normalise.  Plenty of room for experiment here as well.
+    */
+    
+    float pre[K];
+    float e_before = 0.0;
+    float e_after = 0.0;
+    for(k=0; k<K; k++) {
+        pre[k] = 20.0*log10f(sample_freq_kHz[k]/0.3);
+        vec[k] += pre[k];
+        e_before += powf(10.0, 2.0*vec[k]/20.0);
+        vec[k] *= pf_gain;
+        e_after += powf(10.0, 2.0*vec[k]/20.0);        
+    }
+
+    float gain = e_after/e_before;
+    float gaindB = 10*log10f(gain);
+  
+    for(k=0; k<K; k++) {
+        vec[k] -= gaindB;
+        vec[k] -= pre[k];
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: interp_Wo_v
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Decoder side interpolation of Wo and voicing, to go from 25 Hz
+  sample rate used over channle to 100Hz internal sample rate of Codec 2.
+
+\*---------------------------------------------------------------------------*/
+
+void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, int voicing1, int voicing2)
+{
+    int i;
+    int M = 4;  /* interpolation rate */
+
+    for(i=0; i<M; i++)
+        voicing_[i] = 0;
+
+    if (!voicing1 && !voicing2) {
+        for(i=0; i<M; i++)
+            Wo_[i] = 2.0*M_PI/100.0;
+    }
+
+    if (voicing1 && !voicing2) {
+       Wo_[0] = Wo_[1] = Wo1;
+       Wo_[2] = Wo_[3] = 2.0*M_PI/100.0;
+       voicing_[0] = voicing_[1] = 1;
+    }
+
+    if (!voicing1 && voicing2) {
+       Wo_[0] = Wo_[1] = 2.0*M_PI/100.0;
+       Wo_[2] = Wo_[3] = Wo2;
+       voicing_[2] = voicing_[3] = 1;
+    }
+
+    if (voicing1 && voicing2) {
+        float c;
+        for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
+            Wo_[i] = Wo1*c + Wo2*(1.0-c);
+            voicing_[i] = 1;
+        }
+    }
+
+    for(i=0; i<M; i++) {
+        L_[i] = floorf(M_PI/Wo_[i]);
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: resample_rate_L
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Decoder side conversion of rate K vector back to rate L.
+
+\*---------------------------------------------------------------------------*/
+
+void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K)
+{
+   float rate_K_vec_term[K+2], rate_K_sample_freqs_kHz_term[K+2];
+   float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1];
+   int m,k;
+
+   /* terminate either end of the rate K vecs with 0dB points */
+
+   rate_K_vec_term[0] = rate_K_vec_term[K+1] = 0.0;
+   rate_K_sample_freqs_kHz_term[0] = 0.0;
+   rate_K_sample_freqs_kHz_term[K+1] = 4.0;
+
+   for(k=0; k<K; k++) {
+       rate_K_vec_term[k+1] = rate_K_vec[k];
+       rate_K_sample_freqs_kHz_term[k+1] = rate_K_sample_freqs_kHz[k];
+  
+       //printf("k: %d f: %f rate_K: %f\n", k, rate_K_sample_freqs_kHz[k], rate_K_vec[k]);
+   }
+
+   for(m=1; m<=model->L; m++) {
+       rate_L_sample_freqs_kHz[m] = m*model->Wo*(c2const->Fs/2000.0)/M_PI;
+   }
+
+   interp_para(&AmdB[1], rate_K_sample_freqs_kHz_term, rate_K_vec_term, K+2, &rate_L_sample_freqs_kHz[1], model->L);    
+   for(m=1; m<=model->L; m++) {
+       model->A[m] = pow(10.0,  AmdB[m]/20.0);
+       // printf("m: %d f: %f AdB: %f A: %f\n", m, rate_L_sample_freqs_kHz[m], AmdB[m], model->A[m]);
+   }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: determine_phase
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Given a magnitude spectrum determine a phase spectrum, used for
+  phase synthesis with newamp1.
+
+\*---------------------------------------------------------------------------*/
+
+void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg)
+{
+    int i,m,b;
+    int Ns = Nfft/2+1;
+    float Gdbfk[Ns], sample_freqs_kHz[Ns], phase[Ns];
+    float AmdB[MAX_AMP+1], rate_L_sample_freqs_kHz[MAX_AMP+1];
+
+    for(m=1; m<=model->L; m++) {
+        AmdB[m] = 20.0*log10f(model->A[m]+1);
+        rate_L_sample_freqs_kHz[m] = (float)m*model->Wo*(c2const->Fs/2000.0)/M_PI;
+    }
+    
+    for(i=0; i<Ns; i++) {
+        sample_freqs_kHz[i] = (c2const->Fs/1000.0)*(float)i/Nfft;
+    }
+
+    interp_para(Gdbfk, &rate_L_sample_freqs_kHz[1], &AmdB[1], model->L, sample_freqs_kHz, Ns);
+
+    mag_to_phase(phase, Gdbfk, Nfft, fwd_cfg, inv_cfg);
+
+    for(m=1; m<=model->L; m++) {
+        b = floorf(0.5+m*model->Wo*Nfft/(2.0*M_PI));
+        H[m].real = cosf(phase[b]); H[m].imag = sinf(phase[b]);
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: newamp1_model_to_indexes
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  newamp1 encoder for amplitdues {Am}.  Given the rate L model
+  parameters, outputs VQ and energy quantiser indexes.
+
+\*---------------------------------------------------------------------------*/
+
+void newamp1_model_to_indexes(C2CONST *c2const,
+                              int    indexes[], 
+                              MODEL *model, 
+                              float  rate_K_vec[], 
+                              float  rate_K_sample_freqs_kHz[], 
+                              int    K,
+                              float *mean,
+                              float  rate_K_vec_no_mean[], 
+                              float  rate_K_vec_no_mean_[]
+                              )
+{
+    int k;
+
+    /* convert variable rate L to fixed rate K */
+
+    resample_const_rate_f(c2const, model, rate_K_vec, rate_K_sample_freqs_kHz, K);
+
+    /* remove mean and two stage VQ */
+
+    float sum = 0.0;
+    for(k=0; k<K; k++)
+        sum += rate_K_vec[k];
+    *mean = sum/K;
+    for(k=0; k<K; k++)
+        rate_K_vec_no_mean[k] = rate_K_vec[k] - *mean;
+    rate_K_mbest_encode(indexes, rate_K_vec_no_mean, rate_K_vec_no_mean_, K, NEWAMP1_VQ_MBEST_DEPTH);
+
+    /* scalar quantise mean (effectively the frame energy) */
+
+    float w[1] = {1.0};
+    float se;
+    indexes[2] = quantise(newamp1_energy_cb[0].cb, 
+                          mean, 
+                          w, 
+                          newamp1_energy_cb[0].k, 
+                          newamp1_energy_cb[0].m, 
+                          &se);
+
+    /* scalar quantise Wo.  We steal the smallest Wo index to signal
+       an unvoiced frame */
+
+    if (model->voiced) {
+        int index = encode_log_Wo(c2const, model->Wo, 6);
+        if (index == 0) {
+            index = 1;
+        }
+        indexes[3] = index;
+    }
+    else {
+        indexes[3] = 0;
+    }
+
+ }
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: newamp1_interpolate
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+\*---------------------------------------------------------------------------*/
+
+void newamp1_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K)
+{
+    int  i, k;
+    int  M = 4;
+    float c;
+
+    /* (linearly) interpolate 25Hz amplitude vectors back to 100Hz */
+
+    for(i=0,c=1.0; i<M; i++,c-=1.0/M) {
+        for(k=0; k<K; k++) {
+            interpolated_surface_[i*K+k] = left_vec[k]*c + right_vec[k]*(1.0-c);
+        }
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: newamp1_indexes_to_rate_K_vec
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  newamp1 decoder for amplitudes {Am}.  Given the rate K VQ and energy
+  indexes, outputs rate K vector.
+
+\*---------------------------------------------------------------------------*/
+
+void newamp1_indexes_to_rate_K_vec(float  rate_K_vec_[],  
+                                   float  rate_K_vec_no_mean_[],
+                                   float  rate_K_sample_freqs_kHz[], 
+                                   int    K,
+                                   float *mean_,
+                                   int    indexes[])
+{
+    int   k;
+    const float *codebook1 = newamp1vq_cb[0].cb;
+    const float *codebook2 = newamp1vq_cb[1].cb;
+    int n1 = indexes[0];
+    int n2 = indexes[1];
+    
+    for(k=0; k<K; k++) {
+      rate_K_vec_no_mean_[k] = codebook1[K*n1+k] + codebook2[K*n2+k];
+    }
+
+    post_filter_newamp1(rate_K_vec_no_mean_, rate_K_sample_freqs_kHz, K, 1.5);
+
+    *mean_ = newamp1_energy_cb[0].cb[indexes[2]];
+
+    for(k=0; k<K; k++) {
+        rate_K_vec_[k] = rate_K_vec_no_mean_[k] + *mean_;
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: newamp1_indexes_to_model
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  newamp1 decoder.
+
+\*---------------------------------------------------------------------------*/
+
+void newamp1_indexes_to_model(C2CONST *c2const,
+                              MODEL  model_[],
+                              COMP   H[],
+                              float *interpolated_surface_,
+                              float  prev_rate_K_vec_[],
+                              float  *Wo_left,
+                              int    *voicing_left,
+                              float  rate_K_sample_freqs_kHz[], 
+                              int    K,
+                              codec2_fft_cfg fwd_cfg, 
+                              codec2_fft_cfg inv_cfg,
+                              int    indexes[])
+{
+    float rate_K_vec_[K], rate_K_vec_no_mean_[K], mean_, Wo_right;
+    int   voicing_right, k;
+    int   M = 4;
+
+    /* extract latest rate K vector */
+
+    newamp1_indexes_to_rate_K_vec(rate_K_vec_, 
+                                  rate_K_vec_no_mean_,
+                                  rate_K_sample_freqs_kHz, 
+                                  K,
+                                  &mean_,
+                                  indexes);
+
+
+    /* decode latest Wo and voicing */
+
+    if (indexes[3]) {
+        Wo_right = decode_log_Wo(c2const, indexes[3], 6);
+        voicing_right = 1;
+    }
+    else {
+        Wo_right  = 2.0*M_PI/100.0;
+        voicing_right = 0;
+    }
+
+    /* interpolate 25Hz rate K vec back to 100Hz */
+
+    float *left_vec = prev_rate_K_vec_;
+    float *right_vec = rate_K_vec_;
+    newamp1_interpolate(interpolated_surface_, left_vec, right_vec, K);
+
+    /* interpolate 25Hz v and Wo back to 100Hz */
+
+    float aWo_[M];
+    int avoicing_[M], aL_[M], i;
+
+    interp_Wo_v(aWo_, aL_, avoicing_, *Wo_left, Wo_right, *voicing_left, voicing_right);
+
+    /* back to rate L amplitudes, synthesis phase for each frame */
+
+    for(i=0; i<M; i++) {
+        model_[i].Wo = aWo_[i];
+        model_[i].L  = aL_[i];
+        model_[i].voiced = avoicing_[i];
+
+        resample_rate_L(c2const, &model_[i], &interpolated_surface_[K*i], rate_K_sample_freqs_kHz, K);
+        determine_phase(c2const, &H[(MAX_AMP+1)*i], &model_[i], NEWAMP1_PHASE_NFFT, fwd_cfg, inv_cfg);
+    }
+
+    /* update memories for next time */
+
+    for(k=0; k<K; k++) {
+        prev_rate_K_vec_[k] = rate_K_vec_[k];
+    }
+    *Wo_left = Wo_right;
+    *voicing_left = voicing_right;
+
+}
+
diff --git a/codec2/branches/0.7/src/newamp1.h b/codec2/branches/0.7/src/newamp1.h
new file mode 100644 (file)
index 0000000..e3d526a
--- /dev/null
@@ -0,0 +1,80 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: newamp1.h
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Quantisation functions for the sinusoidal coder, using "newamp1"
+  algorithm that resamples variable rate L [Am} to a fixed rate K then
+  VQs.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright David Rowe 2017
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __NEWAMP1__
+#define __NEWAMP1__
+
+#define NEWAMP1_N_INDEXES    4  /* Number of indexes to pack: vq1, vq2, energy, Wo */
+#define NEWAMP1_PHASE_NFFT 128  /* size of FFT used for phase synthesis            */
+#define NEWAMP1_K           20  /* rate K vector length                            */
+
+#include "codec2_fft.h"
+#include "comp.h"
+
+void interp_para(float y[], float xp[], float yp[], int np, float x[], int n);
+float ftomel(float fHz);
+void mel_sample_freqs_kHz(float rate_K_sample_freqs_kHz[], int K, float mel_start, float mel_end);
+void resample_const_rate_f(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K);
+float rate_K_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries);
+void post_filter_newamp1(float vec[], float sample_freq_kHz[], int K, float pf_gain);
+void interp_Wo_v(float Wo_[], int L_[], int voicing_[], float Wo1, float Wo2, int voicing1, int voicing2);
+void resample_rate_L(C2CONST *c2const, MODEL *model, float rate_K_vec[], float rate_K_sample_freqs_kHz[], int K);
+void determine_phase(C2CONST *c2const, COMP H[], MODEL *model, int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg);
+void newamp1_model_to_indexes(C2CONST *c2const,
+                              int    indexes[], 
+                              MODEL *model, 
+                              float  rate_K_vec[], 
+                              float  rate_K_sample_freqs_kHz[], 
+                              int    K,
+                              float *mean,
+                              float  rate_K_vec_no_mean[], 
+                              float  rate_K_vec_no_mean_[]
+                              );
+void newamp1_indexes_to_rate_K_vec(float  rate_K_vec_[],  
+                                   float  rate_K_vec_no_mean_[],
+                                   float  rate_K_sample_freqs_kHz[], 
+                                   int    K,
+                                   float *mean_,
+                                   int    indexes[]);
+void newamp1_interpolate(float interpolated_surface_[], float left_vec[], float right_vec[], int K);
+
+void newamp1_indexes_to_model(C2CONST *c2const,
+                              MODEL  model_[],
+                              COMP   H[],
+                              float  interpolated_surface_[],
+                              float  prev_rate_K_vec_[],
+                              float  *Wo_left,
+                              int    *voicing_left,
+                              float  rate_K_sample_freqs_kHz[], 
+                              int    K,
+                              codec2_fft_cfg fwd_cfg, 
+                              codec2_fft_cfg inv_cfg,
+                              int    indexes[]);
+
+#endif
diff --git a/codec2/branches/0.7/src/nlp.c b/codec2/branches/0.7/src/nlp.c
new file mode 100644 (file)
index 0000000..8c8d5f1
--- /dev/null
@@ -0,0 +1,702 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: nlp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/3/93
+
+  Non Linear Pitch (NLP) estimation functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "defines.h"
+#include "nlp.h"
+#include "dump.h"
+#include "codec2_fft.h"
+#undef PROFILE
+#include "machdep.h"
+#include "os.h"
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+
+/*---------------------------------------------------------------------------*\
+
+                               DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+#define PMAX_M      320                /* maximum NLP analysis window size     */
+#define COEFF       0.95       /* notch filter parameter               */
+#define PE_FFT_SIZE 512                /* DFT size for pitch estimation        */
+#define DEC         5          /* decimation factor                    */
+#define SAMPLE_RATE 8000
+#define PI          3.141592654        /* mathematical constant                */
+#define T           0.1         /* threshold for local minima candidate */
+#define F0_MAX      500
+#define CNLP        0.3                /* post processor constant              */
+#define NLP_NTAP 48            /* Decimation LPF order */
+#undef  POST_PROCESS_MBE        /* choose post processor                */
+
+/* 8 to 16 kHz sample rate conversion */
+
+#define FDMDV_OS                 2                            /* oversampling rate                   */
+#define FDMDV_OS_TAPS_16K       48                            /* number of OS filter taps at 16kHz   */
+#define FDMDV_OS_TAPS_8K        (FDMDV_OS_TAPS_16K/FDMDV_OS)  /* number of OS filter taps at 8kHz    */
+
+/*---------------------------------------------------------------------------*\
+
+                               GLOBALS
+
+\*---------------------------------------------------------------------------*/
+
+/* 48 tap 600Hz low pass FIR filter coefficients */
+
+const float nlp_fir[] = {
+  -1.0818124e-03,
+  -1.1008344e-03,
+  -9.2768838e-04,
+  -4.2289438e-04,
+   5.5034190e-04,
+   2.0029849e-03,
+   3.7058509e-03,
+   5.1449415e-03,
+   5.5924666e-03,
+   4.3036754e-03,
+   8.0284511e-04,
+  -4.8204610e-03,
+  -1.1705810e-02,
+  -1.8199275e-02,
+  -2.2065282e-02,
+  -2.0920610e-02,
+  -1.2808831e-02,
+   3.2204775e-03,
+   2.6683811e-02,
+   5.5520624e-02,
+   8.6305944e-02,
+   1.1480192e-01,
+   1.3674206e-01,
+   1.4867556e-01,
+   1.4867556e-01,
+   1.3674206e-01,
+   1.1480192e-01,
+   8.6305944e-02,
+   5.5520624e-02,
+   2.6683811e-02,
+   3.2204775e-03,
+  -1.2808831e-02,
+  -2.0920610e-02,
+  -2.2065282e-02,
+  -1.8199275e-02,
+  -1.1705810e-02,
+  -4.8204610e-03,
+   8.0284511e-04,
+   4.3036754e-03,
+   5.5924666e-03,
+   5.1449415e-03,
+   3.7058509e-03,
+   2.0029849e-03,
+   5.5034190e-04,
+  -4.2289438e-04,
+  -9.2768838e-04,
+  -1.1008344e-03,
+  -1.0818124e-03
+};
+
+typedef struct {
+    int           Fs;                /* sample rate in Hz            */
+    int           m;
+    float         w[PMAX_M/DEC];     /* DFT window                   */
+    float         sq[PMAX_M];       /* squared speech samples       */
+    float         mem_x,mem_y;       /* memory for notch filter      */
+    float         mem_fir[NLP_NTAP]; /* decimation FIR filter memory */
+    codec2_fft_cfg  fft_cfg;         /* kiss FFT config              */
+    float        *Sn16k;            /* Fs=16kHz input speech vector */
+    FILE         *f;
+} NLP;
+
+#ifdef POST_PROCESS_MBE
+float test_candidate_mbe(COMP Sw[], COMP W[], float f0);
+float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo);
+#endif
+float post_process_sub_multiples(COMP Fw[],
+                                int pmin, int pmax, float gmax, int gmax_bin,
+                                float *prev_f0);
+static void fdmdv_16_to_8(float out8k[], float in16k[], int n);
+
+/*---------------------------------------------------------------------------*\
+
+  nlp_create()
+
+  Initialisation function for NLP pitch estimator.
+
+\*---------------------------------------------------------------------------*/
+
+void *nlp_create(C2CONST *c2const)
+{
+    NLP *nlp;
+    int  i;
+    int  m = c2const->m_pitch;
+    int  Fs = c2const->Fs;
+
+    nlp = (NLP*)malloc(sizeof(NLP));
+    if (nlp == NULL)
+       return NULL;
+
+    assert((Fs == 8000) || (Fs == 16000));
+    nlp->Fs = Fs;
+
+    nlp->m = m;
+
+    /* if running at 16kHz allocate storage for decimating filter memory */
+
+    if (Fs == 16000) {
+        nlp->Sn16k = (float*)malloc(sizeof(float)*(FDMDV_OS_TAPS_16K + c2const->n_samp));
+        for(i=0; i<FDMDV_OS_TAPS_16K; i++) {
+           nlp->Sn16k[i] = 0.0;
+        }
+        if (nlp->Sn16k == NULL) {
+            free(nlp);
+            return NULL;
+        }
+
+        /* most processing occurs at 8 kHz sample rate so halve m */
+
+        m /= 2;
+    }
+
+    assert(m <= PMAX_M);
+    
+    for(i=0; i<m/DEC; i++) {
+       nlp->w[i] = 0.5 - 0.5*cosf(2*PI*i/(m/DEC-1));
+    }
+
+    for(i=0; i<PMAX_M; i++)
+       nlp->sq[i] = 0.0;
+    nlp->mem_x = 0.0;
+    nlp->mem_y = 0.0;
+    for(i=0; i<NLP_NTAP; i++)
+       nlp->mem_fir[i] = 0.0;
+
+    nlp->fft_cfg = codec2_fft_alloc (PE_FFT_SIZE, 0, NULL, NULL);
+    assert(nlp->fft_cfg != NULL);
+
+    return (void*)nlp;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  nlp_destroy()
+
+  Shut down function for NLP pitch estimator.
+
+\*---------------------------------------------------------------------------*/
+
+void nlp_destroy(void *nlp_state)
+{
+    NLP   *nlp;
+    assert(nlp_state != NULL);
+    nlp = (NLP*)nlp_state;
+
+    codec2_fft_free(nlp->fft_cfg);
+    if (nlp->Fs == 16000) {
+        free(nlp->Sn16k);
+    }
+    free(nlp_state);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  nlp()
+
+  Determines the pitch in samples using the Non Linear Pitch (NLP)
+  algorithm [1]. Returns the fundamental in Hz.  Note that the actual
+  pitch estimate is for the centre of the M sample Sn[] vector, not
+  the current N sample input vector.  This is (I think) a delay of 2.5
+  frames with N=80 samples.  You should align further analysis using
+  this pitch estimate to be centred on the middle of Sn[].
+
+  Two post processors have been tried, the MBE version (as discussed
+  in [1]), and a post processor that checks sub-multiples.  Both
+  suffer occasional gross pitch errors (i.e. neither are perfect).  In
+  the presence of background noise the sub-multiple algorithm tends
+  towards low F0 which leads to better sounding background noise than
+  the MBE post processor.
+
+  A good way to test and develop the NLP pitch estimator is using the
+  tnlp (codec2/unittest) and the codec2/octave/plnlp.m Octave script.
+
+  A pitch tracker searching a few frames forward and backward in time
+  would be a useful addition.
+
+  References:
+
+    [1] http://rowetel.com/downloads/1997_rowe_phd_thesis.pdf Chapter 4
+
+\*---------------------------------------------------------------------------*/
+
+float nlp(
+  void *nlp_state,
+  float  Sn[],                 /* input speech vector                                */
+  int    n,                    /* frames shift (no. new samples in Sn[])             */
+  float *pitch,                        /* estimated pitch period in samples at current Fs    */
+  COMP   Sw[],                  /* Freq domain version of Sn[]                        */
+  COMP   W[],                   /* Freq domain window                                 */
+  float *prev_f0                /* previous pitch f0 in Hz, memory for pitch tracking */
+)
+{
+    NLP   *nlp;
+    float  notch;                  /* current notch filter output          */
+    COMP   Fw[PE_FFT_SIZE];        /* DFT of squared signal (input/output) */
+    float  gmax;
+    int    gmax_bin;
+    int    m, i, j;
+    float  best_f0;
+    PROFILE_VAR(start, tnotch, filter, peakpick, window, fft, magsq, shiftmem);
+
+    assert(nlp_state != NULL);
+    nlp = (NLP*)nlp_state;
+    m = nlp->m;
+
+    /* Square, notch filter at DC, and LP filter vector */
+
+    /* If running at 16 kHz decimate to 8 kHz, as NLP ws designed for
+       Fs = 8kHz. The decimating filter introduces about 3ms of delay,
+       that shouldn't be a problem as pitch changes slowly. */
+
+    if (nlp->Fs == 8000) {
+        /* Square latest input samples */
+
+        for(i=m-n; i<m; i++) {
+         nlp->sq[i] = Sn[i]*Sn[i];
+        }
+    }
+    else {
+        assert(nlp->Fs == 16000);
+
+        /* re-sample at 8 KHz */
+
+        for(i=0; i<n; i++) {
+            nlp->Sn16k[FDMDV_OS_TAPS_16K+i] = Sn[m-n+i];
+        }
+
+        m /= 2; n /= 2;
+
+        float Sn8k[n];
+        fdmdv_16_to_8(Sn8k, &nlp->Sn16k[FDMDV_OS_TAPS_16K], n);
+
+        /* Square latest input samples */
+
+        for(i=m-n, j=0; i<m; i++, j++) {
+           nlp->sq[i] = Sn8k[j]*Sn8k[j];
+        }
+        assert(j <= n);
+    }
+    //fprintf(stderr, "n: %d m: %d\n", n, m);
+
+    PROFILE_SAMPLE(start);
+
+    for(i=m-n; i<m; i++) {     /* notch filter at DC */
+       notch = nlp->sq[i] - nlp->mem_x;
+       notch += COEFF*nlp->mem_y;
+       nlp->mem_x = nlp->sq[i];
+       nlp->mem_y = notch;
+       nlp->sq[i] = notch + 1.0;  /* With 0 input vectors to codec,
+                                     kiss_fft() would take a long
+                                     time to execute when running in
+                                     real time.  Problem was traced
+                                     to kiss_fft function call in
+                                     this function. Adding this small
+                                     constant fixed problem.  Not
+                                     exactly sure why. */
+    }
+
+    PROFILE_SAMPLE_AND_LOG(tnotch, start, "      square and notch");
+
+    for(i=m-n; i<m; i++) {     /* FIR filter vector */
+
+       for(j=0; j<NLP_NTAP-1; j++)
+           nlp->mem_fir[j] = nlp->mem_fir[j+1];
+       nlp->mem_fir[NLP_NTAP-1] = nlp->sq[i];
+
+       nlp->sq[i] = 0.0;
+       for(j=0; j<NLP_NTAP; j++)
+           nlp->sq[i] += nlp->mem_fir[j]*nlp_fir[j];
+    }
+
+    PROFILE_SAMPLE_AND_LOG(filter, tnotch, "      filter");
+
+    /* Decimate and DFT */
+
+    for(i=0; i<PE_FFT_SIZE; i++) {
+       Fw[i].real = 0.0;
+       Fw[i].imag = 0.0;
+    }
+    for(i=0; i<m/DEC; i++) {
+       Fw[i].real = nlp->sq[i*DEC]*nlp->w[i];
+    }
+    PROFILE_SAMPLE_AND_LOG(window, filter, "      window");
+    #ifdef DUMP
+    dump_dec(Fw);
+    #endif
+
+    // FIXME: check if this can be converted to a real fft
+    // since all imag inputs are 0
+    codec2_fft_inplace(nlp->fft_cfg, Fw);
+    PROFILE_SAMPLE_AND_LOG(fft, window, "      fft");
+
+    for(i=0; i<PE_FFT_SIZE; i++)
+       Fw[i].real = Fw[i].real*Fw[i].real + Fw[i].imag*Fw[i].imag;
+
+    PROFILE_SAMPLE_AND_LOG(magsq, fft, "      mag sq");
+    #ifdef DUMP
+    dump_sq(m, nlp->sq);
+    dump_Fw(Fw);
+    #endif
+
+    /* todo: express everything in f0, as pitch in samples is dep on Fs */
+
+    int pmin = floor(SAMPLE_RATE*P_MIN_S);
+    int pmax = floor(SAMPLE_RATE*P_MAX_S);
+
+    /* find global peak */
+
+    gmax = 0.0;
+    gmax_bin = PE_FFT_SIZE*DEC/pmax;
+    for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) {
+       if (Fw[i].real > gmax) {
+           gmax = Fw[i].real;
+           gmax_bin = i;
+       }
+    }
+
+    PROFILE_SAMPLE_AND_LOG(peakpick, magsq, "      peak pick");
+
+    #ifdef POST_PROCESS_MBE
+    best_f0 = post_process_mbe(Fw, pmin, pmax, gmax, Sw, W, prev_f0);
+    #else
+    best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, prev_f0);
+    #endif
+
+    PROFILE_SAMPLE_AND_LOG(shiftmem, peakpick,  "      post process");
+
+    /* Shift samples in buffer to make room for new samples */
+
+    for(i=0; i<m-n; i++)
+       nlp->sq[i] = nlp->sq[i+n];
+
+    /* return pitch period in samples and F0 estimate */
+
+    *pitch = (float)nlp->Fs/best_f0;
+
+    PROFILE_SAMPLE_AND_LOG2(shiftmem,  "      shift mem");
+
+    PROFILE_SAMPLE_AND_LOG2(start,  "      nlp int");
+
+    *prev_f0 = best_f0;
+
+    return(best_f0);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  post_process_sub_multiples()
+
+  Given the global maximma of Fw[] we search integer submultiples for
+  local maxima.  If local maxima exist and they are above an
+  experimentally derived threshold (OK a magic number I pulled out of
+  the air) we choose the submultiple as the F0 estimate.
+
+  The rational for this is that the lowest frequency peak of Fw[]
+  should be F0, as Fw[] can be considered the autocorrelation function
+  of Sw[] (the speech spectrum).  However sometimes due to phase
+  effects the lowest frequency maxima may not be the global maxima.
+
+  This works OK in practice and favours low F0 values in the presence
+  of background noise which means the sinusoidal codec does an OK job
+  of synthesising the background noise.  High F0 in background noise
+  tends to sound more periodic introducing annoying artifacts.
+
+\*---------------------------------------------------------------------------*/
+
+float post_process_sub_multiples(COMP Fw[],
+                                int pmin, int pmax, float gmax, int gmax_bin,
+                                float *prev_f0)
+{
+    int   min_bin, cmax_bin;
+    int   mult;
+    float thresh, best_f0;
+    int   b, bmin, bmax, lmax_bin;
+    float lmax;
+    int   prev_f0_bin;
+
+    /* post process estimate by searching submultiples */
+
+    mult = 2;
+    min_bin = PE_FFT_SIZE*DEC/pmax;
+    cmax_bin = gmax_bin;
+    prev_f0_bin = *prev_f0*(PE_FFT_SIZE*DEC)/SAMPLE_RATE;
+
+    while(gmax_bin/mult >= min_bin) {
+
+       b = gmax_bin/mult;                      /* determine search interval */
+       bmin = 0.8*b;
+       bmax = 1.2*b;
+       if (bmin < min_bin)
+           bmin = min_bin;
+
+       /* lower threshold to favour previous frames pitch estimate,
+           this is a form of pitch tracking */
+
+       if ((prev_f0_bin > bmin) && (prev_f0_bin < bmax))
+           thresh = CNLP*0.5*gmax;
+       else
+           thresh = CNLP*gmax;
+
+       lmax = 0;
+       lmax_bin = bmin;
+       for (b=bmin; b<=bmax; b++)           /* look for maximum in interval */
+           if (Fw[b].real > lmax) {
+               lmax = Fw[b].real;
+               lmax_bin = b;
+           }
+
+       if (lmax > thresh)
+           if ((lmax > Fw[lmax_bin-1].real) && (lmax > Fw[lmax_bin+1].real)) {
+               cmax_bin = lmax_bin;
+           }
+
+       mult++;
+    }
+
+    best_f0 = (float)cmax_bin*SAMPLE_RATE/(PE_FFT_SIZE*DEC);
+
+    return best_f0;
+}
+
+#ifdef POST_PROCESS_MBE
+
+/*---------------------------------------------------------------------------*\
+
+  post_process_mbe()
+
+  Use the MBE pitch estimation algorithm to evaluate pitch candidates.  This
+  works OK but the accuracy at low F0 is affected by NW, the analysis window
+  size used for the DFT of the input speech Sw[].  Also favours high F0 in
+  the presence of background noise which causes periodic artifacts in the
+  synthesised speech.
+
+\*---------------------------------------------------------------------------*/
+
+float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax, COMP Sw[], COMP W[], float *prev_Wo)
+{
+  float candidate_f0;
+  float f0,best_f0;            /* fundamental frequency */
+  float e,e_min;                /* MBE cost function */
+  int   i;
+  #ifdef DUMP
+  float e_hz[F0_MAX];
+  #endif
+  #if !defined(NDEBUG) || defined(DUMP)
+  int   bin;
+  #endif
+  float f0_min, f0_max;
+  float f0_start, f0_end;
+
+  f0_min = (float)SAMPLE_RATE/pmax;
+  f0_max = (float)SAMPLE_RATE/pmin;
+
+  /* Now look for local maxima.  Each local maxima is a candidate
+     that we test using the MBE pitch estimation algotithm */
+
+  #ifdef DUMP
+  for(i=0; i<F0_MAX; i++)
+      e_hz[i] = -1;
+  #endif
+  e_min = 1E32;
+  best_f0 = 50;
+  for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) {
+    if ((Fw[i].real > Fw[i-1].real) && (Fw[i].real > Fw[i+1].real)) {
+
+       /* local maxima found, lets test if it's big enough */
+
+       if (Fw[i].real > T*gmax) {
+
+           /* OK, sample MBE cost function over +/- 10Hz range in 2.5Hz steps */
+
+           candidate_f0 = (float)i*SAMPLE_RATE/(PE_FFT_SIZE*DEC);
+           f0_start = candidate_f0-20;
+           f0_end = candidate_f0+20;
+           if (f0_start < f0_min) f0_start = f0_min;
+           if (f0_end > f0_max) f0_end = f0_max;
+
+           for(f0=f0_start; f0<=f0_end; f0+= 2.5) {
+               e = test_candidate_mbe(Sw, W, f0);
+               #if !defined(NDEBUG) || defined(DUMP)
+               bin = floorf(f0); assert((bin > 0) && (bin < F0_MAX));
+               #endif
+               #ifdef DUMP
+                e_hz[bin] = e;
+                #endif
+               if (e < e_min) {
+                   e_min = e;
+                   best_f0 = f0;
+               }
+           }
+
+       }
+    }
+  }
+
+  /* finally sample MBE cost function around previous pitch estimate
+     (form of pitch tracking) */
+
+  candidate_f0 = *prev_Wo * SAMPLE_RATE/TWO_PI;
+  f0_start = candidate_f0-20;
+  f0_end = candidate_f0+20;
+  if (f0_start < f0_min) f0_start = f0_min;
+  if (f0_end > f0_max) f0_end = f0_max;
+
+  for(f0=f0_start; f0<=f0_end; f0+= 2.5) {
+      e = test_candidate_mbe(Sw, W, f0);
+      #if !defined(NDEBUG) || defined(DUMP)
+      bin = floorf(f0); assert((bin > 0) && (bin < F0_MAX));
+      #endif
+      #ifdef DUMP
+      e_hz[bin] = e;
+      #endif
+      if (e < e_min) {
+         e_min = e;
+         best_f0 = f0;
+      }
+  }
+
+  #ifdef DUMP
+  dump_e(e_hz);
+  #endif
+
+  return best_f0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  test_candidate_mbe()
+
+  Returns the error of the MBE cost function for the input f0.
+
+  Note: I think a lot of the operations below can be simplified as
+  W[].imag = 0 and has been normalised such that den always equals 1.
+
+\*---------------------------------------------------------------------------*/
+
+float test_candidate_mbe(
+    COMP  Sw[],
+    COMP  W[],
+    float f0
+)
+{
+    COMP  Sw_[FFT_ENC];   /* DFT of all voiced synthesised signal */
+    int   l,al,bl,m;      /* loop variables */
+    COMP  Am;             /* amplitude sample for this band */
+    int   offset;         /* centers Hw[] about current harmonic */
+    float den;            /* denominator of Am expression */
+    float error;          /* accumulated error between originl and synthesised */
+    float Wo;             /* current "test" fundamental freq. */
+    int   L;
+
+    L = floorf((SAMPLE_RATE/2.0)/f0);
+    Wo = f0*(2*PI/SAMPLE_RATE);
+
+    error = 0.0;
+
+    /* Just test across the harmonics in the first 1000 Hz (L/4) */
+
+    for(l=1; l<L/4; l++) {
+       Am.real = 0.0;
+       Am.imag = 0.0;
+       den = 0.0;
+       al = ceilf((l - 0.5)*Wo*FFT_ENC/TWO_PI);
+       bl = ceilf((l + 0.5)*Wo*FFT_ENC/TWO_PI);
+
+       /* Estimate amplitude of harmonic assuming harmonic is totally voiced */
+
+       for(m=al; m<bl; m++) {
+           offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5;
+           Am.real += Sw[m].real*W[offset].real + Sw[m].imag*W[offset].imag;
+           Am.imag += Sw[m].imag*W[offset].real - Sw[m].real*W[offset].imag;
+           den += W[offset].real*W[offset].real + W[offset].imag*W[offset].imag;
+        }
+
+        Am.real = Am.real/den;
+        Am.imag = Am.imag/den;
+
+        /* Determine error between estimated harmonic and original */
+
+        for(m=al; m<bl; m++) {
+           offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5;
+           Sw_[m].real = Am.real*W[offset].real - Am.imag*W[offset].imag;
+           Sw_[m].imag = Am.real*W[offset].imag + Am.imag*W[offset].real;
+           error += (Sw[m].real - Sw_[m].real)*(Sw[m].real - Sw_[m].real);
+           error += (Sw[m].imag - Sw_[m].imag)*(Sw[m].imag - Sw_[m].imag);
+       }
+    }
+
+    return error;
+}
+
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fdmdv_16_to_8()
+  AUTHOR......: David Rowe
+  DATE CREATED: 9 May 2012
+
+  Changes the sample rate of a signal from 16 to 8 kHz.
+
+  n is the number of samples at the 8 kHz rate, there are FDMDV_OS*n
+  samples at the 48 kHz rate.  As above however a memory of
+  FDMDV_OS_TAPS samples is reqd for in16k[] (see t16_8.c unit test as example).
+
+  Low pass filter the 16 kHz signal at 4 kHz using the same filter as
+  the upsampler, then just output every FDMDV_OS-th filtered sample.
+
+  Note: this function copied from fdmdv.c, included in nlp.c as a convenience
+  to avoid linking with another source file.
+
+\*---------------------------------------------------------------------------*/
+
+static void fdmdv_16_to_8(float out8k[], float in16k[], int n)
+{
+    float acc;
+    int   i,j,k;
+
+    for(i=0, k=0; k<n; i+=FDMDV_OS, k++) {
+       acc = 0.0;
+       for(j=0; j<FDMDV_OS_TAPS_16K; j++)
+           acc += fdmdv_os_filter[j]*in16k[i-j];
+        out8k[k] = acc;
+    }
+
+    /* update filter memory */
+
+    for(i=-FDMDV_OS_TAPS_16K; i<0; i++)
+       in16k[i] = in16k[i + n*FDMDV_OS];
+}
diff --git a/codec2/branches/0.7/src/nlp.h b/codec2/branches/0.7/src/nlp.h
new file mode 100644 (file)
index 0000000..28a59c3
--- /dev/null
@@ -0,0 +1,38 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: nlp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/3/93
+
+  Non Linear Pitch (NLP) estimation functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __NLP__
+#define __NLP__
+
+#include "comp.h"
+
+void *nlp_create(C2CONST *c2const);
+void nlp_destroy(void *nlp_state);
+float nlp(void *nlp_state, float Sn[], int n, 
+         float *pitch_samples, COMP Sw[], COMP W[], float *prev_f0);
+
+#endif
diff --git a/codec2/branches/0.7/src/noise_samples.h b/codec2/branches/0.7/src/noise_samples.h
new file mode 100644 (file)
index 0000000..1e271bc
--- /dev/null
@@ -0,0 +1,60006 @@
+/* unit variance complex noise samples */
+
+/* Generated by write_noise_file() Octave function */
+
+COMP noise[]={
+  {-1.885516,0.055745},
+  {-0.521966,-0.622614},
+  {1.066249,0.337187},
+  {0.425638,1.008370},
+  {-0.318666,-0.210894},
+  {-0.498824,0.361164},
+  {-0.300114,-0.527950},
+  {0.385872,0.182296},
+  {1.195960,-0.586922},
+  {0.266811,0.178374},
+  {0.013054,0.215778},
+  {-0.823216,-0.322273},
+  {0.837766,-0.727259},
+  {-0.862485,0.092857},
+  {0.075880,0.633056},
+  {-0.410681,-0.646296},
+  {0.586237,-0.116673},
+  {-0.058715,0.066528},
+  {0.857992,-1.043428},
+  {-0.123710,-0.261511},
+  {0.185764,0.023376},
+  {0.236794,-0.527785},
+  {-1.703954,0.502907},
+  {-0.299082,-0.422089},
+  {-0.288630,-0.675562},
+  {-0.424885,-0.319811},
+  {-0.032088,0.101098},
+  {0.605509,0.242926},
+  {0.145393,-0.199722},
+  {-0.184393,-1.528490},
+  {0.081268,-0.843421},
+  {0.654326,-0.158813},
+  {-0.234536,1.226681},
+  {0.221648,-1.226646},
+  {-0.193938,-0.336096},
+  {-0.518051,-1.309855},
+  {-0.664323,1.059784},
+  {0.007637,1.113850},
+  {-0.465620,1.714405},
+  {1.028837,-0.549814},
+  {0.073478,-0.721235},
+  {0.964658,0.084118},
+  {-1.822765,-0.997525},
+  {1.032482,0.916581},
+  {-0.597571,-0.136872},
+  {-0.009127,-0.208567},
+  {0.516709,-0.773967},
+  {-1.129711,1.021948},
+  {-0.697322,-0.812202},
+  {0.327103,-0.638199},
+  {-0.497829,0.319382},
+  {-1.362630,-0.414764},
+  {-0.307641,0.207521},
+  {-0.982186,-0.198641},
+  {-0.588516,-0.097265},
+  {1.299202,0.644097},
+  {-0.972070,-0.680644},
+  {0.782015,-0.002870},
+  {-1.177445,-1.014379},
+  {-0.398772,0.513042},
+  {-0.666921,0.266484},
+  {-0.803497,0.971730},
+  {0.267153,0.335670},
+  {-0.591532,0.779734},
+  {-1.211656,-0.382351},
+  {0.065910,-0.504718},
+  {-0.686435,-0.584560},
+  {0.858992,-1.042560},
+  {0.847992,1.057437},
+  {1.492562,-0.829278},
+  {0.816092,-1.530742},
+  {-0.520592,-0.549319},
+  {-0.076793,0.021602},
+  {-0.697792,0.763414},
+  {0.821960,0.552985},
+  {0.376647,-1.094689},
+  {-1.401195,-0.857007},
+  {-0.376378,-0.783975},
+  {-0.120497,0.662907},
+  {0.670862,-0.673604},
+  {-0.177972,-1.238774},
+  {-0.037790,-1.376598},
+  {-0.899490,-0.445965},
+  {0.474709,1.022354},
+  {-0.291882,0.370018},
+  {-0.072661,-0.118012},
+  {0.396912,-1.371327},
+  {-0.711547,0.258054},
+  {-1.118704,-0.050908},
+  {-0.592657,-1.747229},
+  {-0.731285,-0.387065},
+  {-0.535939,-0.294046},
+  {-1.314716,-1.534715},
+  {0.361445,0.618672},
+  {-0.082988,-0.336140},
+  {0.210252,0.650233},
+  {-0.674824,0.056007},
+  {0.596070,0.007299},
+  {0.305633,-1.176059},
+  {1.659456,0.424673},
+  {0.660546,-0.514937},
+  {-0.206967,0.241885},
+  {-1.104655,-0.744576},
+  {-0.218762,0.014955},
+  {0.165193,1.381141},
+  {0.078718,-1.222328},
+  {-0.377642,-0.152884},
+  {0.108755,0.412056},
+  {-0.429127,-0.383452},
+  {0.518805,0.741250},
+  {0.740139,-0.770384},
+  {-1.485392,-0.336407},
+  {-0.078238,0.141468},
+  {-1.271050,0.180219},
+  {-0.211076,-1.217480},
+  {1.461947,0.144679},
+  {-0.109724,-0.861360},
+  {-0.296620,-1.282399},
+  {0.201649,-0.713701},
+  {-0.156722,0.424378},
+  {1.029760,-1.173706},
+  {0.571211,-0.156216},
+  {-0.455729,0.236642},
+  {0.742660,0.014606},
+  {-0.097202,-0.498742},
+  {0.266521,0.048233},
+  {-0.060433,0.282215},
+  {-0.239310,1.006663},
+  {0.389689,-0.071960},
+  {-0.689538,0.568830},
+  {0.759056,0.330529},
+  {0.149945,-0.521060},
+  {-0.580738,-0.907159},
+  {1.448531,-0.054100},
+  {0.690290,0.275166},
+  {-0.478557,-0.516261},
+  {-0.820324,-0.831472},
+  {-0.341231,0.409044},
+  {0.180268,0.231572},
+  {-0.450892,1.061669},
+  {0.192718,-0.862400},
+  {-0.399038,0.268735},
+  {-0.856262,-0.454883},
+  {0.363651,-0.198669},
+  {-0.642075,-0.189629},
+  {0.005932,-0.508157},
+  {0.985162,-0.020120},
+  {1.562916,0.229486},
+  {-0.899449,0.307419},
+  {0.112975,0.627516},
+  {-1.857863,-1.008967},
+  {0.378419,0.019322},
+  {0.443381,0.253609},
+  {1.715317,-0.767294},
+  {-0.385770,0.001505},
+  {-0.645703,-0.310651},
+  {-1.888905,0.409068},
+  {0.805380,0.333960},
+  {-1.046012,-0.674661},
+  {0.794386,-0.303931},
+  {-0.286721,0.610492},
+  {-0.123797,-0.552424},
+  {0.206278,-0.663653},
+  {0.428624,-0.249450},
+  {0.430463,-0.635776},
+  {-0.119454,0.773666},
+  {-0.578332,-0.980697},
+  {0.235559,1.481441},
+  {-0.714737,-1.423728},
+  {0.350707,0.157071},
+  {0.453768,0.680754},
+  {0.283172,-1.286042},
+  {0.031254,-0.559665},
+  {-0.008719,-0.527750},
+  {-1.036011,-0.024812},
+  {0.392333,0.647429},
+  {0.203090,0.422197},
+  {-1.948977,0.778356},
+  {1.366324,-0.798091},
+  {1.180139,-0.048221},
+  {0.114722,1.012431},
+  {0.615604,0.391601},
+  {0.987843,0.495600},
+  {-0.496219,-0.900673},
+  {1.001277,-0.568435},
+  {-0.576352,-1.332582},
+  {0.306377,0.123371},
+  {0.211114,-0.685042},
+  {0.298619,0.362809},
+  {0.202382,0.173210},
+  {-0.075417,-0.014578},
+  {-1.015379,-0.025271},
+  {0.128685,0.929594},
+  {-0.723128,0.984769},
+  {-0.536901,-0.125969},
+  {0.240670,0.812981},
+  {-0.763511,1.108132},
+  {0.500508,-0.241395},
+  {0.624663,-0.410191},
+  {-0.094272,-0.521839},
+  {1.429982,-0.369827},
+  {-0.070236,-1.263636},
+  {-0.498143,-0.973796},
+  {0.575172,-1.017724},
+  {0.487669,0.215515},
+  {0.562802,-0.136995},
+  {-0.963325,-0.880169},
+  {-0.541808,-0.623215},
+  {0.613993,0.303645},
+  {-0.604527,-0.329199},
+  {-0.331248,1.331861},
+  {-1.040864,1.077405},
+  {0.342707,0.741436},
+  {-0.627839,-0.347768},
+  {0.231630,-0.578183},
+  {-1.128172,0.396462},
+  {-0.198999,1.538255},
+  {-0.177279,-0.290086},
+  {-0.687712,-0.894058},
+  {-0.124584,0.925987},
+  {-0.602825,0.432388},
+  {-0.111357,-0.496225},
+  {0.034978,0.298642},
+  {0.324142,-0.092883},
+  {1.347456,0.820678},
+  {0.674479,-0.288974},
+  {1.539829,-1.107841},
+  {-1.023161,0.056007},
+  {0.317892,-0.963086},
+  {0.158138,0.483226},
+  {0.340379,-0.422898},
+  {-0.813880,-0.882603},
+  {-0.322466,0.829669},
+  {-0.217180,-1.046571},
+  {0.452658,0.839521},
+  {-0.622912,-0.060398},
+  {-0.034008,-0.564055},
+  {-1.793271,-0.605655},
+  {-0.028383,0.886204},
+  {-0.308408,0.061571},
+  {0.536948,0.120042},
+  {-0.574106,-0.562561},
+  {0.406051,-0.338068},
+  {0.492813,-0.083346},
+  {-0.711445,-0.455225},
+  {-0.061165,0.217759},
+  {0.338502,-0.376511},
+  {0.832324,-0.406104},
+  {-0.083176,0.715563},
+  {0.040608,-0.871143},
+  {-0.462891,0.849255},
+  {-0.372708,-1.019345},
+  {0.934808,-0.626071},
+  {1.010369,-1.084185},
+  {0.479580,-0.842863},
+  {0.927175,0.131809},
+  {-0.689773,-0.142861},
+  {1.343912,0.404388},
+  {-1.759282,0.448528},
+  {0.619114,-0.525565},
+  {-0.321018,0.404425},
+  {-0.741470,-0.296394},
+  {-1.980475,0.026427},
+  {-0.614688,0.342918},
+  {0.066823,0.132296},
+  {0.498182,0.005019},
+  {0.182848,0.162708},
+  {-0.493550,0.153312},
+  {1.072346,-1.225466},
+  {1.139312,0.832815},
+  {1.252850,0.105664},
+  {-0.397363,-0.754276},
+  {0.580338,-1.300751},
+  {0.009278,-0.598071},
+  {0.402804,-0.530334},
+  {-0.039782,-0.370667},
+  {-0.990988,-0.169245},
+  {1.697751,-0.452739},
+  {1.272906,-0.324169},
+  {-1.567337,-0.459235},
+  {-0.798090,-0.024978},
+  {0.697111,-1.399949},
+  {0.110211,-0.941636},
+  {-1.480043,-0.132934},
+  {-1.148194,0.987249},
+  {-0.873447,-0.209100},
+  {1.065186,-1.104929},
+  {0.099062,0.126155},
+  {1.977617,0.094483},
+  {-0.786564,-0.546020},
+  {-0.714383,0.131073},
+  {0.905849,0.394293},
+  {0.190777,-0.513831},
+  {0.437916,0.203698},
+  {1.043923,0.145473},
+  {-0.443628,-0.725054},
+  {0.983123,-0.489622},
+  {0.842413,0.307580},
+  {-0.822191,-0.258379},
+  {-0.523631,0.285446},
+  {0.571865,-0.025860},
+  {-0.201652,-0.099850},
+  {-0.022666,0.495916},
+  {0.596392,0.867633},
+  {0.804110,-0.338599},
+  {-0.026179,-1.043212},
+  {-0.598738,0.094476},
+  {-1.478593,-0.541411},
+  {-0.941390,0.363421},
+  {0.361994,0.590341},
+  {1.113285,-1.212781},
+  {0.701988,0.084937},
+  {-0.083600,-0.245951},
+  {-1.484694,-0.468464},
+  {0.162783,1.536800},
+  {0.252869,-0.052530},
+  {0.926480,-0.277632},
+  {0.299984,-1.410909},
+  {-0.425939,-0.332244},
+  {0.464111,0.662834},
+  {-0.802428,-0.324926},
+  {0.028548,0.511754},
+  {0.140263,0.200719},
+  {1.751965,1.362158},
+  {0.773686,-0.044970},
+  {-0.098854,0.668847},
+  {-0.356892,1.006610},
+  {0.272827,0.118268},
+  {0.294481,0.308008},
+  {1.772151,0.001790},
+  {0.399585,-0.223070},
+  {0.143887,0.187282},
+  {-0.580062,0.483563},
+  {0.263317,0.146606},
+  {0.913153,0.409123},
+  {0.176392,0.531394},
+  {1.266576,0.812919},
+  {-0.339609,-0.004748},
+  {1.029027,-0.899818},
+  {-0.770858,-0.547236},
+  {0.286743,-0.638120},
+  {-0.521747,-0.089493},
+  {-0.565535,-0.929156},
+  {-1.535774,0.479567},
+  {-0.615287,-0.520953},
+  {-0.553663,-0.319031},
+  {0.582640,1.113202},
+  {0.232977,0.041975},
+  {-0.199109,-0.254687},
+  {-0.066200,0.947135},
+  {0.666122,0.627375},
+  {0.480019,1.051260},
+  {-0.093472,-0.787448},
+  {0.480187,0.926381},
+  {-0.857216,0.556518},
+  {0.442832,0.376201},
+  {-0.119017,-0.140136},
+  {-0.409616,-1.213675},
+  {-0.437294,-0.024768},
+  {0.451274,-0.787326},
+  {-0.533223,-0.923706},
+  {0.131233,1.268746},
+  {1.743505,1.131077},
+  {0.987317,0.595257},
+  {-0.088862,0.853512},
+  {0.551818,0.665099},
+  {0.883782,0.470033},
+  {-0.516423,-1.423524},
+  {0.091609,0.378477},
+  {0.009939,0.994809},
+  {1.045723,-1.221703},
+  {-0.276956,-0.093140},
+  {-0.409436,-0.171621},
+  {-0.964290,-0.362871},
+  {0.592260,0.544377},
+  {-0.681616,-0.447483},
+  {-0.431291,0.024446},
+  {0.663176,1.026108},
+  {0.838537,-0.118180},
+  {-0.747318,0.251341},
+  {-0.380034,-0.715319},
+  {-0.900635,0.212346},
+  {-0.464843,0.620745},
+  {-1.093005,0.607958},
+  {0.515036,1.299937},
+  {-1.016371,-0.029679},
+  {-0.205308,0.148501},
+  {0.505373,-0.440794},
+  {-0.048557,-0.301057},
+  {-0.698358,-1.099303},
+  {-0.088257,-0.329308},
+  {0.075595,-0.362464},
+  {0.027192,-0.680106},
+  {-0.757238,-0.166757},
+  {-1.448321,-0.138835},
+  {-0.136439,0.459323},
+  {0.912758,0.296751},
+  {0.799521,-0.573520},
+  {-0.861892,-0.589343},
+  {-0.567036,0.158120},
+  {0.478773,-1.056482},
+  {0.709261,0.523567},
+  {0.739101,-1.002925},
+  {-0.494944,0.003764},
+  {0.454782,-0.046268},
+  {0.210620,0.297517},
+  {-0.781813,0.236194},
+  {0.348782,-0.613968},
+  {-0.094413,-0.465826},
+  {1.768494,-0.406883},
+  {0.007841,0.789725},
+  {-0.162655,0.552781},
+  {-0.758330,0.343804},
+  {0.454609,-0.732044},
+  {-0.168881,0.095592},
+  {0.515566,-0.569084},
+  {1.255135,-0.757000},
+  {0.469649,0.564189},
+  {1.260765,0.360564},
+  {0.055027,-0.177677},
+  {0.600213,-1.511142},
+  {-0.018551,1.257905},
+  {0.308072,0.151081},
+  {-0.207634,-1.327921},
+  {-0.527733,0.174325},
+  {-0.159456,-0.732546},
+  {-0.220168,-0.415477},
+  {0.543532,-0.145998},
+  {0.884459,1.021665},
+  {-0.262540,-0.398469},
+  {-0.281570,0.698927},
+  {-0.908972,-0.709079},
+  {1.589970,0.503578},
+  {-0.171265,-0.741831},
+  {-0.743265,-0.294431},
+  {0.731885,0.012954},
+  {0.007728,-0.499237},
+  {0.089515,-0.775161},
+  {0.725415,-0.411110},
+  {0.298849,-0.118750},
+  {-1.303123,0.250206},
+  {0.310939,0.936912},
+  {-0.172330,0.754859},
+  {0.093154,0.269182},
+  {-0.858640,-0.029252},
+  {-1.073149,0.280686},
+  {-0.601430,-0.256738},
+  {-0.351531,-0.914084},
+  {-1.751136,-0.490966},
+  {0.112360,-0.656132},
+  {0.921817,-0.276350},
+  {0.763771,0.769928},
+  {0.221840,1.213251},
+  {-0.706608,-0.303978},
+  {0.281566,-1.404763},
+  {1.496795,0.177279},
+  {0.261977,-0.939172},
+  {-0.919389,-0.188529},
+  {0.044503,0.718759},
+  {-0.825230,0.774033},
+  {0.693991,0.858213},
+  {0.509792,0.099608},
+  {-0.020553,-0.839990},
+  {-0.854648,-0.540134},
+  {-0.000525,1.256322},
+  {0.894022,-0.693105},
+  {0.442684,-0.596914},
+  {0.498318,0.275977},
+  {-0.388386,0.465259},
+  {0.414579,-1.294942},
+  {0.098001,-0.237709},
+  {1.594870,-0.240582},
+  {-0.711413,0.451491},
+  {0.019527,2.133193},
+  {0.948900,0.242084},
+  {0.059194,0.584269},
+  {0.852393,-0.156332},
+  {-1.485739,0.262110},
+  {-0.016760,-0.827316},
+  {-0.891646,0.181925},
+  {-0.018801,0.682929},
+  {-0.690712,-0.572420},
+  {1.070712,0.423795},
+  {1.438766,0.043977},
+  {-0.318368,-0.067348},
+  {-0.661371,-1.089229},
+  {0.046538,0.984436},
+  {0.749236,-0.964548},
+  {1.566314,0.918615},
+  {-1.235787,1.002522},
+  {0.416022,1.866776},
+  {1.217135,0.668893},
+  {-0.698937,-0.486054},
+  {-0.478062,-1.168289},
+  {1.113613,-0.737028},
+  {0.773078,0.234230},
+  {-0.270515,-0.411625},
+  {-0.228462,0.192394},
+  {-0.838646,0.153818},
+  {-0.436599,-0.408881},
+  {-0.286055,-0.410803},
+  {0.729377,-0.731766},
+  {0.197643,0.237175},
+  {0.836606,0.664076},
+  {-1.657439,1.703306},
+  {-0.925155,-0.171418},
+  {0.078549,-0.331130},
+  {0.629470,0.307286},
+  {1.248656,0.135449},
+  {1.243601,0.442489},
+  {0.387421,-0.154848},
+  {-1.179918,-0.732728},
+  {1.236507,0.602991},
+  {0.372452,0.171586},
+  {-0.394677,-0.101565},
+  {0.381677,1.147393},
+  {-1.697199,0.109712},
+  {0.188553,-0.752200},
+  {0.333632,-1.929951},
+  {-1.659946,0.767602},
+  {-0.190815,-0.557146},
+  {-1.244192,0.038106},
+  {0.077329,0.305661},
+  {0.945212,1.065261},
+  {-0.912713,1.292797},
+  {-0.391785,-0.024158},
+  {0.240759,-1.304114},
+  {0.112919,-0.091566},
+  {-0.424359,-0.382424},
+  {-1.079261,0.972243},
+  {0.454041,-0.530269},
+  {-1.976890,-0.123184},
+  {-0.190632,-0.544888},
+  {0.296577,-0.825026},
+  {-0.477747,-0.335360},
+  {0.208503,0.097964},
+  {-0.579558,-0.380423},
+  {-0.414982,-0.344604},
+  {0.940711,-0.907772},
+  {-0.962894,-1.441203},
+  {-0.648064,2.197827},
+  {-0.633787,-0.990602},
+  {0.215111,-0.181544},
+  {0.232828,-0.123360},
+  {-0.303892,1.339899},
+  {-0.166969,1.219343},
+  {0.508222,-0.102310},
+  {-0.811188,1.126966},
+  {0.321233,-1.277579},
+  {0.007428,0.316342},
+  {0.506948,0.481229},
+  {-1.304547,0.311991},
+  {0.142125,0.263640},
+  {0.391351,0.737307},
+  {1.437568,-0.534043},
+  {-0.949425,1.069958},
+  {-0.409085,-0.759735},
+  {0.412259,0.737801},
+  {-0.492377,-0.804608},
+  {-0.217219,-0.405020},
+  {0.115039,0.000846},
+  {0.349041,0.299516},
+  {-0.460594,0.403723},
+  {0.196753,1.155867},
+  {-0.277940,0.266830},
+  {-0.274583,0.585154},
+  {-1.172068,1.790906},
+  {0.590439,-0.406621},
+  {1.328016,-0.283713},
+  {1.517565,-0.073409},
+  {0.130855,1.772665},
+  {-2.619775,1.072108},
+  {0.319751,1.536673},
+  {0.047733,-0.326729},
+  {0.289634,1.226698},
+  {2.014575,-0.883138},
+  {0.229264,-0.183602},
+  {0.589396,-1.070306},
+  {0.273592,-2.039844},
+  {-0.935323,-0.715785},
+  {0.849403,0.619567},
+  {0.480466,-0.484123},
+  {0.222280,-0.134613},
+  {-0.258632,-1.289221},
+  {0.050742,0.026907},
+  {-0.283583,0.031728},
+  {-0.757978,0.771411},
+  {-0.434361,0.111156},
+  {0.021107,-0.043801},
+  {0.773835,-0.122289},
+  {-0.292605,0.119946},
+  {0.501058,0.447133},
+  {0.227193,0.479879},
+  {-0.544627,-0.222938},
+  {0.583272,-0.387875},
+  {-0.223831,-0.468512},
+  {-1.520007,0.446069},
+  {-0.573569,0.226990},
+  {-1.019881,0.053637},
+  {-0.634610,-0.875259},
+  {0.504476,-0.027282},
+  {-0.039342,0.409377},
+  {0.202815,1.231918},
+  {-0.843921,0.164374},
+  {0.356392,-0.821357},
+  {0.108781,-0.523469},
+  {-0.196590,-0.568744},
+  {0.903934,1.041689},
+  {-0.544910,-0.022931},
+  {0.299150,1.544291},
+  {0.880525,0.454125},
+  {-0.528507,-0.169262},
+  {-0.683196,-0.079160},
+  {0.153998,-0.420623},
+  {0.324243,0.022550},
+  {0.099578,1.237426},
+  {0.613243,0.648504},
+  {-0.190038,0.945184},
+  {-1.058645,0.829361},
+  {0.657373,-0.037085},
+  {0.292522,-1.824963},
+  {1.306603,0.982009},
+  {0.202489,-0.632477},
+  {-0.198865,1.503029},
+  {-0.506292,0.002522},
+  {0.709691,0.107836},
+  {-0.135288,-0.949001},
+  {-0.013697,0.446746},
+  {0.269863,1.736851},
+  {0.147020,-0.676663},
+  {-0.044332,0.878172},
+  {-0.969214,0.385042},
+  {-0.108626,-0.577699},
+  {0.573041,-0.693982},
+  {-0.430415,1.253413},
+  {0.106646,-0.057892},
+  {-0.946692,-0.108739},
+  {-0.070615,-0.924246},
+  {-0.407323,-1.048572},
+  {0.541592,-0.183877},
+  {1.559869,-0.734420},
+  {-0.667415,-0.567982},
+  {0.194163,-0.030077},
+  {0.088646,0.226636},
+  {0.502396,-1.399375},
+  {-0.016646,-0.215656},
+  {0.348238,0.112063},
+  {1.303715,0.470275},
+  {-0.665134,-0.786941},
+  {0.470438,0.135527},
+  {-1.337204,0.482771},
+  {-0.535810,0.980521},
+  {-0.168026,-0.750603},
+  {0.387649,-0.230317},
+  {-0.100852,0.278379},
+  {0.685615,0.909829},
+  {-1.248533,-0.401446},
+  {0.402464,1.846549},
+  {0.119498,0.304702},
+  {0.717501,-1.078118},
+  {-0.450438,0.775426},
+  {-1.459832,-0.482867},
+  {0.328487,-0.012362},
+  {-0.126026,0.086507},
+  {-0.630993,0.029377},
+  {-1.326625,0.927913},
+  {-0.198820,0.150652},
+  {0.266277,-0.555360},
+  {0.424295,-0.359816},
+  {1.393099,-0.408979},
+  {-0.137465,0.133084},
+  {0.628200,-0.501458},
+  {-0.684531,-0.666955},
+  {-0.181920,0.890694},
+  {-0.700720,-0.956197},
+  {-0.060714,-1.247294},
+  {-0.405972,-0.881525},
+  {1.118188,0.072000},
+  {-0.195761,-1.868639},
+  {0.358203,0.349429},
+  {0.154352,-1.476324},
+  {-0.210438,-1.836233},
+  {0.277728,0.211249},
+  {0.104063,1.608697},
+  {0.078646,-0.690233},
+  {1.107666,0.152621},
+  {0.976973,0.132356},
+  {0.625021,0.424496},
+  {1.106620,-1.108251},
+  {-0.606551,0.611908},
+  {-0.079978,0.362614},
+  {0.450618,0.582625},
+  {-0.256559,-0.109762},
+  {-1.029120,-0.607627},
+  {0.030983,0.226229},
+  {0.466365,-0.698225},
+  {-0.320317,0.232588},
+  {-0.294836,0.215016},
+  {0.380833,0.902802},
+  {0.179398,-0.539814},
+  {-0.750583,-0.650149},
+  {-0.528202,0.616827},
+  {-1.363519,-1.202585},
+  {0.284990,-1.236363},
+  {0.243581,-0.864788},
+  {0.624023,0.137801},
+  {-0.032040,-0.595454},
+  {0.518910,0.207927},
+  {-0.623962,0.216663},
+  {-0.382311,0.684690},
+  {-1.561598,0.901426},
+  {0.426931,1.278804},
+  {0.332361,-0.658982},
+  {0.181141,-0.012956},
+  {0.171052,0.552234},
+  {-0.435677,0.454231},
+  {-0.919015,0.176359},
+  {-0.000067,-0.799626},
+  {-0.930220,-0.187525},
+  {-0.452119,-0.228146},
+  {0.380184,-0.566153},
+  {-0.179594,0.470684},
+  {0.176167,-0.917050},
+  {0.002315,0.589605},
+  {1.252774,0.206557},
+  {-0.284561,-1.124914},
+  {0.174024,0.351072},
+  {-0.838853,1.170720},
+  {-0.067488,-0.254230},
+  {-0.622343,-1.414225},
+  {0.436853,0.611763},
+  {-0.128391,0.096025},
+  {-0.819464,-0.451713},
+  {-0.165038,-0.122421},
+  {0.024147,-1.314003},
+  {0.304931,0.164088},
+  {-0.288640,-0.620373},
+  {0.357003,0.454057},
+  {-1.286647,0.415088},
+  {1.849891,0.616365},
+  {-0.185972,-1.212797},
+  {-0.415794,-0.401859},
+  {-0.431783,-0.137922},
+  {0.768623,-0.292081},
+  {0.012545,1.445239},
+  {-1.689607,-0.394403},
+  {0.152052,-0.025210},
+  {-1.765495,0.816127},
+  {0.035743,0.371073},
+  {-0.218734,-0.149507},
+  {1.291120,-1.111594},
+  {-0.374380,0.070194},
+  {-0.903368,0.788305},
+  {0.867657,-0.973921},
+  {0.913874,0.430432},
+  {-0.121419,0.832404},
+  {-0.415312,1.135312},
+  {-0.393487,-0.150178},
+  {-0.079568,-0.565870},
+  {1.522292,0.090401},
+  {-0.334966,0.599134},
+  {0.515824,0.178857},
+  {-0.199075,-0.457595},
+  {0.246401,-0.054357},
+  {1.396896,-1.363043},
+  {-0.027178,-0.553311},
+  {1.010836,0.249187},
+  {0.075435,0.009485},
+  {-0.217608,1.185129},
+  {-0.522616,0.556410},
+  {0.858783,-0.313273},
+  {-0.001036,-0.621413},
+  {0.960607,-1.149066},
+  {-0.521696,0.268324},
+  {-0.517445,-1.383789},
+  {0.305025,0.761437},
+  {0.031777,-0.095862},
+  {-0.795680,-1.512038},
+  {0.033550,-0.338430},
+  {-0.398340,-0.145735},
+  {-0.322545,0.322695},
+  {0.372049,-0.610750},
+  {-0.137179,-0.590167},
+  {-0.504190,-0.258481},
+  {-0.335035,0.338316},
+  {-0.364893,0.692466},
+  {0.038100,-0.724327},
+  {0.296797,0.135183},
+  {0.159604,0.214980},
+  {0.250361,-0.215980},
+  {-0.347541,0.122078},
+  {-0.056809,0.890072},
+  {0.285375,0.181473},
+  {0.170715,-0.393356},
+  {-1.015282,-0.208756},
+  {-0.785738,0.483868},
+  {0.007467,1.387720},
+  {-0.178938,0.754625},
+  {0.664808,-0.600883},
+  {0.001036,-0.083353},
+  {0.194157,0.160494},
+  {1.084332,-0.062428},
+  {0.349357,0.373911},
+  {1.433766,-1.303837},
+  {0.037403,2.429277},
+  {0.395728,-0.834206},
+  {-0.389085,-0.755077},
+  {0.850327,0.007645},
+  {-0.368104,0.126990},
+  {-0.775816,-0.923819},
+  {-0.537167,0.945156},
+  {0.142793,1.312552},
+  {-0.125607,0.032723},
+  {-0.137840,-0.002817},
+  {0.742073,0.013517},
+  {0.251125,-0.528226},
+  {0.820089,-0.035605},
+  {-0.713914,0.167522},
+  {-0.863981,-0.178499},
+  {-0.390476,-0.120624},
+  {0.583901,-0.243569},
+  {-0.227909,0.309306},
+  {0.324491,-0.693688},
+  {-1.094183,0.252179},
+  {0.192052,0.039188},
+  {-0.267150,-0.444016},
+  {-0.005890,-0.573760},
+  {-0.232266,-0.276434},
+  {0.382483,0.162194},
+  {0.150483,-0.651730},
+  {0.067169,0.902480},
+  {-2.098348,0.945188},
+  {0.825451,1.329186},
+  {-0.815597,-1.181818},
+  {0.461014,-0.678300},
+  {-0.711512,0.009708},
+  {0.260361,1.191568},
+  {0.185182,-0.338544},
+  {0.478590,0.221720},
+  {0.624523,0.990393},
+  {-0.706888,0.014106},
+  {1.173506,-1.110449},
+  {-0.091258,-0.061557},
+  {1.120091,1.816875},
+  {-0.989880,-1.531038},
+  {0.692417,-1.128270},
+  {1.716773,0.088070},
+  {1.162503,0.054400},
+  {0.810364,0.272585},
+  {-0.013515,-0.520286},
+  {-0.730928,-0.950759},
+  {0.008127,0.539806},
+  {-1.317219,0.544458},
+  {0.781036,0.503169},
+  {-0.335197,-0.425765},
+  {-0.735000,-0.347362},
+  {0.528729,0.365142},
+  {-0.617825,0.301920},
+  {0.910278,-0.760821},
+  {-0.709713,-0.356227},
+  {0.953397,0.042611},
+  {0.086349,-0.037081},
+  {0.171876,0.033586},
+  {1.106060,-0.413432},
+  {-0.408955,1.259989},
+  {0.072173,1.348382},
+  {0.650744,0.132067},
+  {0.241760,-0.334014},
+  {-0.088343,0.502032},
+  {-0.043052,0.355098},
+  {-0.313450,0.269137},
+  {-0.329212,-1.672112},
+  {-0.207438,-0.117867},
+  {0.366077,-0.234852},
+  {0.411392,-0.008275},
+  {0.353902,0.251566},
+  {-1.477623,0.757765},
+  {0.654771,-0.149077},
+  {0.076332,-0.376470},
+  {-0.879182,-0.887672},
+  {0.125407,1.010632},
+  {-0.871182,0.304759},
+  {0.194266,-0.223159},
+  {0.060104,-0.953143},
+  {-0.045438,0.534938},
+  {0.615844,0.411408},
+  {-0.374972,-0.055209},
+  {-0.253019,0.383784},
+  {-0.891703,-0.218474},
+  {-0.706804,0.115545},
+  {-1.026031,1.389687},
+  {-0.462136,0.335579},
+  {-0.773215,-0.951771},
+  {-0.779558,-0.464746},
+  {0.476106,-0.777170},
+  {0.664543,-0.569407},
+  {0.214316,0.063090},
+  {-0.569488,-0.008396},
+  {0.750912,-0.739441},
+  {0.214514,0.148096},
+  {-0.198354,1.474815},
+  {-1.805212,-0.107083},
+  {0.169518,-0.786940},
+  {-0.409644,0.852013},
+  {-0.221826,-0.037541},
+  {0.253388,-0.616419},
+  {-1.774513,-1.460955},
+  {0.742875,0.456503},
+  {-0.232420,-1.359596},
+  {-0.507235,-0.763391},
+  {0.195227,0.320688},
+  {-0.224637,-0.845635},
+  {1.009627,0.163178},
+  {0.778218,-1.096235},
+  {0.865546,0.293077},
+  {1.466179,0.233799},
+  {0.226625,-0.545274},
+  {0.692166,-0.527514},
+  {0.013789,0.635607},
+  {0.807891,-0.801895},
+  {-1.053395,0.465520},
+  {-0.036991,-1.273551},
+  {-0.589794,-0.753839},
+  {-0.030564,-0.036160},
+  {0.155678,-1.045183},
+  {0.625342,-0.595545},
+  {0.036864,-0.046397},
+  {-0.004179,-0.652544},
+  {-0.820676,0.620457},
+  {-0.183887,0.725946},
+  {-0.166238,-1.560859},
+  {0.175907,-1.429565},
+  {-0.020052,0.815148},
+  {-0.197063,-1.522027},
+  {0.813251,-2.196093},
+  {-1.334144,-0.008865},
+  {0.412217,0.219281},
+  {-0.080738,-0.419816},
+  {0.192626,-0.493562},
+  {-0.370266,-1.389646},
+  {-0.030379,0.021337},
+  {0.496641,0.294285},
+  {-0.416795,0.418699},
+  {0.195812,-0.707197},
+  {0.122865,-0.525780},
+  {-0.610908,-0.373378},
+  {-0.177131,-1.018769},
+  {0.403266,0.457369},
+  {-0.288750,1.777459},
+  {-0.606019,0.137316},
+  {0.164513,1.727904},
+  {0.911565,-0.299473},
+  {-0.493145,0.145941},
+  {0.279365,0.579905},
+  {0.452409,1.222730},
+  {-0.329814,0.070742},
+  {-0.098010,-0.289855},
+  {1.204663,0.662790},
+  {-0.493696,0.573452},
+  {-0.938748,-0.639465},
+  {-0.739078,1.243613},
+  {-0.343832,0.558003},
+  {0.027203,0.055290},
+  {-0.170201,0.729385},
+  {-0.878156,-1.902973},
+  {0.690907,1.079256},
+  {0.028972,0.634171},
+  {-0.155383,0.545055},
+  {-0.431928,0.330613},
+  {-0.635781,0.072453},
+  {0.615176,0.308009},
+  {0.104105,-0.205818},
+  {0.415076,1.103903},
+  {-0.024480,0.212016},
+  {0.664855,-0.116184},
+  {0.652496,-1.192114},
+  {0.695982,-0.080428},
+  {-0.526819,-0.078349},
+  {1.742119,0.556368},
+  {-0.153092,1.204460},
+  {0.311190,0.421990},
+  {0.938121,1.025194},
+  {0.156598,-0.031073},
+  {0.224118,0.600692},
+  {-0.051218,0.216583},
+  {-0.842484,0.468331},
+  {0.407989,0.450259},
+  {-0.949113,-1.564583},
+  {-0.434143,0.325978},
+  {0.747291,2.322704},
+  {0.737442,1.246064},
+  {-0.762481,-0.758876},
+  {0.729215,0.853799},
+  {-0.908589,-0.622078},
+  {-0.598447,1.603107},
+  {-0.959017,0.214551},
+  {0.536470,-0.187251},
+  {0.530038,0.557070},
+  {-0.247256,0.391664},
+  {0.445570,0.089350},
+  {1.499768,-0.418437},
+  {0.800986,-0.273838},
+  {0.177952,-1.141694},
+  {1.090844,1.147880},
+  {0.084762,-0.180105},
+  {-0.464588,0.255076},
+  {-0.710487,-0.422911},
+  {-0.159879,0.388722},
+  {0.919932,-0.041034},
+  {-0.515947,-0.139864},
+  {-0.432913,-0.527550},
+  {-0.275296,-1.159533},
+  {-0.136299,0.789806},
+  {-0.464789,-0.109964},
+  {0.939702,-0.027732},
+  {0.197460,0.125553},
+  {0.360497,-0.081121},
+  {-1.038393,0.917326},
+  {-0.562256,-0.247960},
+  {-0.506010,0.057694},
+  {-0.061158,0.007115},
+  {1.085933,0.036530},
+  {0.782551,0.730841},
+  {-1.730593,-0.649685},
+  {1.033557,0.042674},
+  {1.004293,-0.582702},
+  {-0.588062,1.893153},
+  {-0.038458,-0.489328},
+  {-0.223353,0.176598},
+  {-0.602039,-0.177264},
+  {0.484092,-0.207521},
+  {0.131809,0.406690},
+  {-0.420236,2.391833},
+  {-1.389783,-0.697870},
+  {-1.051676,0.985787},
+  {1.027283,0.026054},
+  {-0.193866,0.459321},
+  {-0.237210,-0.168983},
+  {0.034746,0.785979},
+  {1.228488,-0.966549},
+  {1.189960,0.910590},
+  {0.215783,-0.132182},
+  {0.865491,1.580951},
+  {0.342861,-1.317527},
+  {-0.347129,0.117582},
+  {0.477505,0.073989},
+  {-0.330732,-0.626076},
+  {-0.383103,-1.051103},
+  {-1.127629,0.266550},
+  {0.077820,0.478365},
+  {0.979591,-0.218870},
+  {-0.666472,0.081770},
+  {-0.846640,0.983632},
+  {-0.481019,0.374114},
+  {0.076811,0.167969},
+  {-1.276667,-1.056656},
+  {0.884138,1.533002},
+  {-0.422899,0.149947},
+  {-0.471814,0.310129},
+  {-0.294613,0.138715},
+  {-0.917606,0.974627},
+  {0.338625,0.106750},
+  {-0.447939,-0.094187},
+  {0.404872,0.074803},
+  {-0.759799,-0.426123},
+  {-0.788273,0.712513},
+  {-0.021566,-0.188178},
+  {-0.162962,-1.214495},
+  {0.093791,-0.540991},
+  {-0.961095,0.434286},
+  {0.353384,-1.489342},
+  {0.292430,-1.036190},
+  {0.150482,-0.471052},
+  {0.149233,-0.987746},
+  {-0.432685,0.980449},
+  {-0.738729,0.443044},
+  {-0.038329,0.068701},
+  {1.188859,-0.898705},
+  {-1.250213,-0.076530},
+  {-0.526824,0.334444},
+  {-0.464058,0.049049},
+  {-0.642591,-0.525583},
+  {0.192584,-0.630311},
+  {0.437306,0.681520},
+  {0.487855,0.369540},
+  {0.641239,-0.574243},
+  {0.371964,-1.021879},
+  {-1.041124,0.131275},
+  {-0.691663,0.998510},
+  {0.546112,0.831658},
+  {1.393481,-0.148050},
+  {1.262175,0.248708},
+  {0.540609,-0.336198},
+  {0.041225,-1.024662},
+  {-0.177173,-0.224147},
+  {0.867867,-0.187578},
+  {-0.967667,-1.219234},
+  {0.213381,-0.057988},
+  {-0.675667,-1.091565},
+  {0.556298,-0.770728},
+  {-0.188682,0.656382},
+  {-0.092475,0.407926},
+  {-1.641683,0.484862},
+  {0.190082,-0.330329},
+  {0.174209,-0.676685},
+  {-0.950743,-0.193766},
+  {-0.435225,-0.580076},
+  {0.246472,-0.472847},
+  {-0.505688,-0.759662},
+  {-1.255934,-0.736332},
+  {1.935964,0.332194},
+  {-0.500932,0.083885},
+  {-0.067564,0.231471},
+  {-0.379280,0.846503},
+  {-0.030848,-0.246677},
+  {0.125241,-0.397222},
+  {-1.137543,-0.555543},
+  {-0.122221,0.387840},
+  {2.042492,-1.202247},
+  {1.772027,0.326225},
+  {-0.550197,0.205095},
+  {0.450376,0.791456},
+  {-0.506594,0.069919},
+  {-0.063568,1.032985},
+  {-0.621426,-0.028421},
+  {0.043761,-1.038331},
+  {-2.012759,-0.886260},
+  {-0.144653,-0.613454},
+  {1.042293,-0.047165},
+  {-0.059067,0.116286},
+  {0.148872,-0.095572},
+  {-0.573228,-0.480453},
+  {-0.200914,-1.046460},
+  {-0.824112,1.568436},
+  {-0.133283,-0.288869},
+  {0.597348,0.377234},
+  {-0.505799,1.227439},
+  {-0.606898,0.148651},
+  {-0.583873,-1.081077},
+  {-0.347056,0.271253},
+  {0.784106,0.033133},
+  {0.184385,0.180992},
+  {0.378686,-0.264273},
+  {1.264891,1.156455},
+  {-0.180967,0.378180},
+  {1.185364,2.147560},
+  {-0.443654,-0.290601},
+  {-1.069806,0.508735},
+  {1.608167,1.233684},
+  {-0.794538,0.519840},
+  {-0.078219,1.219228},
+  {0.334451,-0.046541},
+  {-0.666285,0.564027},
+  {-0.577876,-0.550521},
+  {-0.000416,-0.584869},
+  {0.624742,-0.128862},
+  {-0.205674,-0.383454},
+  {-0.377425,0.710460},
+  {0.086861,-1.107777},
+  {0.781845,-0.797178},
+  {0.153671,0.734022},
+  {0.009617,-0.036667},
+  {0.752946,1.007603},
+  {0.471233,0.459138},
+  {-0.821665,-0.267974},
+  {-0.924172,0.593227},
+  {-0.364922,0.183033},
+  {0.503286,0.374220},
+  {0.817608,-1.185941},
+  {-1.068648,0.590834},
+  {-0.100083,-0.975689},
+  {0.801345,0.166370},
+  {0.878885,0.514705},
+  {-0.707014,0.403084},
+  {0.827796,0.483292},
+  {-0.975586,0.279704},
+  {0.362153,1.075430},
+  {0.799974,0.002309},
+  {0.676713,-1.092933},
+  {1.578438,0.276312},
+  {0.110806,-1.246881},
+  {-0.865309,0.165009},
+  {-0.282162,0.733062},
+  {-0.990404,-0.702353},
+  {0.121363,0.147771},
+  {0.038031,-0.195024},
+  {0.138621,0.371235},
+  {0.142721,0.021207},
+  {0.268035,-0.692454},
+  {0.945280,-0.180407},
+  {-0.253126,-1.299034},
+  {0.215126,0.964959},
+  {0.214474,0.039968},
+  {-0.315065,1.317935},
+  {-0.495310,0.013483},
+  {0.470253,0.354208},
+  {-0.089794,0.245806},
+  {-0.208178,1.288801},
+  {0.753819,-0.739573},
+  {-0.885257,-0.056685},
+  {0.478816,0.673381},
+  {0.388771,0.612329},
+  {-0.820496,-1.297063},
+  {-1.437975,0.521158},
+  {0.271222,-0.170637},
+  {-0.400573,-0.022383},
+  {-1.216831,-0.194283},
+  {1.347498,-0.865849},
+  {1.490747,1.638422},
+  {-0.066047,-0.399105},
+  {-0.420802,1.133171},
+  {0.135157,1.573802},
+  {0.541187,0.894018},
+  {1.510389,0.809415},
+  {0.881448,-0.730401},
+  {0.296695,-0.733757},
+  {0.339736,-1.370242},
+  {0.274695,0.252843},
+  {-1.281780,0.313851},
+  {1.274502,-0.466039},
+  {0.808820,-0.486975},
+  {0.817662,0.485549},
+  {-0.095951,0.029602},
+  {-0.110720,0.676979},
+  {1.202230,0.782503},
+  {0.323406,-0.119733},
+  {-0.284233,0.460801},
+  {-0.138012,-0.172029},
+  {0.660058,-0.652850},
+  {0.681055,0.587900},
+  {1.034573,-1.401681},
+  {-0.803681,0.663399},
+  {0.279558,-1.726715},
+  {-0.064446,-0.133818},
+  {0.111129,-0.818469},
+  {-0.109438,0.108017},
+  {0.655329,-0.214051},
+  {-0.182692,0.983672},
+  {-0.386961,-0.148666},
+  {-0.520381,0.408330},
+  {-0.277355,0.529608},
+  {-0.227798,1.212313},
+  {0.286884,1.328657},
+  {0.330357,0.676798},
+  {-0.386855,-0.073008},
+  {-0.005346,0.643306},
+  {-0.408125,-0.611805},
+  {-1.344349,1.214852},
+  {0.280046,0.328383},
+  {0.193258,0.841163},
+  {0.688097,1.470022},
+  {-0.543274,0.871549},
+  {-0.243657,0.867887},
+  {0.031152,0.192752},
+  {-1.158627,-1.398383},
+  {-0.797943,-0.620853},
+  {0.551211,-1.681158},
+  {0.057558,-1.031877},
+  {-1.029493,0.639438},
+  {0.099115,-0.246357},
+  {0.343168,0.265658},
+  {1.188859,1.031717},
+  {0.126086,0.836314},
+  {-0.606482,0.051107},
+  {0.162957,-0.781010},
+  {-0.462344,-0.438913},
+  {-0.539638,0.657519},
+  {0.022154,0.230604},
+  {-0.843574,0.180764},
+  {0.398755,-0.125898},
+  {0.299966,-0.155337},
+  {1.022899,-0.742968},
+  {-0.807121,-0.640128},
+  {-0.392841,-0.596371},
+  {-0.360295,-1.003922},
+  {0.679328,-0.665397},
+  {-0.072668,1.290516},
+  {-0.280499,-0.949490},
+  {0.111927,0.581514},
+  {-1.363240,-1.343656},
+  {-1.084450,0.050768},
+  {-0.385367,-0.565308},
+  {0.202467,-1.237126},
+  {-0.242867,0.417895},
+  {-1.545462,-0.660856},
+  {-0.215712,0.754475},
+  {0.950926,0.189388},
+  {-0.907607,-0.356709},
+  {-0.018424,-0.492529},
+  {0.592479,-0.228064},
+  {-0.666301,-0.997495},
+  {0.316365,2.371218},
+  {0.234107,-0.170388},
+  {-0.382072,-0.617266},
+  {0.008455,0.054220},
+  {0.391055,-0.070040},
+  {-1.131104,0.097647},
+  {0.114958,0.491805},
+  {-1.828644,0.079717},
+  {1.282146,0.110291},
+  {0.357302,-0.071632},
+  {-1.285120,-0.698425},
+  {-0.620723,0.250825},
+  {-1.580495,0.607744},
+  {-0.310391,0.023209},
+  {0.659152,-0.517724},
+  {0.722716,0.407689},
+  {-0.310078,0.307880},
+  {-0.515929,-0.421393},
+  {0.481648,-0.771808},
+  {-0.613531,-0.311456},
+  {-0.557038,0.487850},
+  {0.240958,1.033137},
+  {-0.411849,-0.652721},
+  {-1.414977,1.570391},
+  {0.198022,0.143388},
+  {-0.665199,0.006710},
+  {-0.125512,1.145256},
+  {0.939666,-0.184737},
+  {1.254756,0.210233},
+  {-0.414391,-1.647095},
+  {0.149630,0.144509},
+  {0.288296,0.362648},
+  {-0.017046,0.108292},
+  {0.500758,1.194654},
+  {-0.132504,0.838117},
+  {0.436872,-1.259608},
+  {0.185786,-0.150289},
+  {0.570040,-0.268047},
+  {-0.924944,0.709866},
+  {0.460708,-0.753595},
+  {1.505297,0.124422},
+  {0.070403,0.380217},
+  {-0.453289,-0.844383},
+  {0.339141,0.421633},
+  {-0.276216,0.254737},
+  {-0.740343,0.477980},
+  {-1.140554,0.373471},
+  {-0.619092,-0.126768},
+  {-0.106514,-0.394367},
+  {1.219767,0.408088},
+  {0.570849,0.749630},
+  {0.279189,0.802048},
+  {-1.761637,0.917490},
+  {-0.125839,-0.480779},
+  {-0.716519,-1.313543},
+  {-0.886599,1.677483},
+  {0.471796,0.455429},
+  {0.472861,-0.700399},
+  {0.630634,0.789490},
+  {0.388011,0.023963},
+  {0.160770,-0.328353},
+  {0.684503,-0.912411},
+  {-0.613712,-0.942848},
+  {0.187679,-1.243436},
+  {-0.303386,0.183180},
+  {-0.430191,-0.919399},
+  {-0.486669,0.017418},
+  {-0.196664,-0.596788},
+  {-0.016898,-0.305134},
+  {-1.003277,0.875101},
+  {0.016353,-0.323237},
+  {0.821922,0.531172},
+  {0.068244,-1.142754},
+  {0.564201,-0.493468},
+  {-0.108778,-0.451831},
+  {-1.104421,-0.533559},
+  {-0.190109,1.354647},
+  {-1.625892,-0.106572},
+  {0.053986,0.048085},
+  {-0.078443,-0.504104},
+  {-0.981755,0.138946},
+  {-0.089922,0.305097},
+  {-2.134689,-0.514083},
+  {-0.557133,1.367571},
+  {-0.124624,0.607339},
+  {-1.498195,-1.186483},
+  {-0.872943,-0.334031},
+  {0.433069,0.253202},
+  {0.748849,0.097565},
+  {0.431413,-0.732537},
+  {0.468929,0.578734},
+  {-1.277818,0.672101},
+  {0.471820,-0.460997},
+  {0.494373,0.102286},
+  {-0.141118,0.866229},
+  {-0.347544,-0.467992},
+  {-0.772585,0.634551},
+  {-0.968830,-0.935472},
+  {-0.019241,0.227594},
+  {-0.813687,0.776289},
+  {-0.124640,0.511015},
+  {0.045039,0.998667},
+  {0.160430,-0.284327},
+  {-0.252488,-0.276808},
+  {-1.446518,-0.593809},
+  {0.444264,-0.215641},
+  {-0.495694,1.313423},
+  {0.233200,0.628049},
+  {1.058397,-0.209975},
+  {-0.631813,0.212791},
+  {0.724289,0.730092},
+  {0.766557,0.140992},
+  {-0.422498,-0.065908},
+  {0.759667,-0.394613},
+  {-0.280825,-0.249983},
+  {-0.334594,-0.099555},
+  {-0.100845,-0.279454},
+  {-0.631641,-0.001709},
+  {-0.390891,0.591299},
+  {-0.614147,-0.867562},
+  {0.794232,0.262570},
+  {-0.855585,-0.445803},
+  {0.137634,-0.208739},
+  {0.735539,-0.285394},
+  {0.254964,-1.231606},
+  {0.529011,0.143706},
+  {1.430450,-0.392117},
+  {0.441543,-0.753268},
+  {-0.215594,0.692776},
+  {0.235193,1.031127},
+  {-0.658717,-0.573607},
+  {-0.945679,-1.445653},
+  {-0.416275,0.659500},
+  {0.907194,0.304227},
+  {-0.031342,0.374716},
+  {0.005759,-0.770302},
+  {-0.877440,-0.213883},
+  {-0.710438,-0.089993},
+  {-0.417193,-0.780149},
+  {0.281753,-1.127371},
+  {0.074096,0.751776},
+  {-1.369300,-0.313873},
+  {0.975236,-0.674780},
+  {-0.395840,0.453994},
+  {0.229087,-0.431998},
+  {0.686648,-0.040472},
+  {-1.932872,-2.114067},
+  {-0.053147,0.889797},
+  {1.557776,0.187376},
+  {-0.177372,-0.372058},
+  {-0.145758,-0.406644},
+  {0.893661,-0.736872},
+  {0.699794,-0.837986},
+  {0.562408,-1.315862},
+  {0.248331,0.796103},
+  {-0.974681,-0.545749},
+  {-0.633997,-0.920930},
+  {-0.653344,-0.148806},
+  {-0.278669,-1.016823},
+  {0.990752,0.282628},
+  {-0.002135,0.295268},
+  {0.247889,-0.002233},
+  {0.299683,0.464098},
+  {-0.348562,0.234081},
+  {-0.653547,1.042115},
+  {1.427451,-0.211486},
+  {-0.249740,0.299611},
+  {0.236624,-0.236593},
+  {0.361321,-0.011710},
+  {0.225996,-0.116814},
+  {0.665416,-0.154760},
+  {-0.343271,0.309692},
+  {0.214282,0.840876},
+  {0.436174,0.465315},
+  {0.491642,-0.396010},
+  {-0.840432,0.546308},
+  {-0.484284,-0.253952},
+  {-0.674070,0.614429},
+  {-1.132196,0.300718},
+  {-0.686720,-0.668618},
+  {-0.209752,-0.193816},
+  {-0.864450,0.711636},
+  {-0.704162,0.080921},
+  {-0.281052,-0.711402},
+  {0.476961,-0.296571},
+  {-0.567590,0.120557},
+  {1.206292,-0.739669},
+  {0.073467,0.983447},
+  {-0.761649,-0.205547},
+  {-0.101813,-0.757212},
+  {-0.036924,-1.095216},
+  {-0.203280,0.087312},
+  {0.419187,0.045301},
+  {-0.128742,0.611231},
+  {0.002422,-0.752412},
+  {0.674792,0.880037},
+  {-0.130573,-0.395283},
+  {0.043261,0.842507},
+  {0.744393,0.440538},
+  {0.327633,0.077634},
+  {-0.173323,1.100831},
+  {-0.364820,0.190809},
+  {-0.929120,0.340176},
+  {0.083238,-0.252833},
+  {-0.812169,1.206466},
+  {-0.658568,0.595224},
+  {-1.328600,0.526328},
+  {-2.155765,1.269370},
+  {-0.046160,-0.114023},
+  {0.293193,-0.938083},
+  {-0.254478,-1.169655},
+  {0.586072,0.064899},
+  {-0.826939,0.519365},
+  {0.000194,-0.042804},
+  {0.703387,0.425636},
+  {-0.071028,0.344410},
+  {-0.690411,-0.426178},
+  {-0.305423,-0.957584},
+  {0.565793,0.471864},
+  {0.572453,-1.210154},
+  {-0.176756,-0.543416},
+  {-0.122719,0.142358},
+  {0.041164,-0.689254},
+  {0.488677,0.046068},
+  {0.272934,-0.298194},
+  {0.056580,-0.113747},
+  {-0.586258,-0.393607},
+  {0.449298,0.411649},
+  {0.222406,0.339896},
+  {-0.259049,0.537135},
+  {-0.162509,1.788969},
+  {0.261787,-1.022771},
+  {0.342338,0.185518},
+  {0.579314,-0.173051},
+  {-0.141523,-0.044285},
+  {0.193116,-0.235134},
+  {-1.353094,-1.018692},
+  {-0.436509,0.480147},
+  {0.110273,0.018753},
+  {-0.074405,0.256683},
+  {-0.246641,-0.072741},
+  {0.193535,0.110739},
+  {0.236249,0.450123},
+  {-1.328284,0.200608},
+  {0.203875,0.971534},
+  {0.140868,0.836049},
+  {-1.180779,-0.571187},
+  {0.352527,-0.941286},
+  {-0.603336,1.499530},
+  {-1.722024,-0.622489},
+  {-0.665516,0.309695},
+  {-0.196527,0.388266},
+  {0.748597,0.328682},
+  {-0.700676,-0.457945},
+  {0.241755,0.916166},
+  {-1.055948,0.612258},
+  {-0.088514,-1.051597},
+  {-0.666181,-0.503929},
+  {-0.373979,0.896727},
+  {-0.372882,-0.074176},
+  {-0.109262,0.026398},
+  {0.140324,0.378864},
+  {-0.019849,-1.097344},
+  {0.235596,-0.286668},
+  {0.782230,-0.389778},
+  {0.013781,-0.571368},
+  {0.789306,0.647173},
+  {0.630138,0.773210},
+  {0.750400,-1.183298},
+  {-0.682019,-1.609188},
+  {0.896088,0.067930},
+  {0.420614,-0.078741},
+  {-1.496000,0.450049},
+  {-0.863680,-0.475229},
+  {-1.423561,-0.224888},
+  {0.024832,-0.453597},
+  {0.737548,0.300150},
+  {-0.738513,0.671116},
+  {0.789577,-0.557279},
+  {0.667659,-0.837533},
+  {0.440875,-1.043855},
+  {-0.051215,-1.357721},
+  {0.359163,-1.468140},
+  {-0.336103,-0.186086},
+  {-1.253254,0.917832},
+  {-0.307426,0.767409},
+  {-0.567196,0.228002},
+  {-0.028435,0.944140},
+  {0.222374,0.474538},
+  {1.165054,-0.954027},
+  {0.925421,0.519574},
+  {-0.072758,-0.302302},
+  {0.298489,0.526333},
+  {0.559091,-0.004799},
+  {0.661053,-0.291473},
+  {0.589520,-0.043129},
+  {0.486342,-0.102644},
+  {0.399697,0.607928},
+  {-1.591074,0.238188},
+  {0.864441,0.826969},
+  {-0.717594,0.995645},
+  {0.335125,1.336621},
+  {-0.374524,0.390990},
+  {-0.010197,0.428746},
+  {-0.061779,0.352761},
+  {-1.529446,-0.080619},
+  {0.588116,1.395893},
+  {-0.455056,0.445153},
+  {-0.217297,1.396009},
+  {-0.657833,-1.016368},
+  {-1.806291,0.038937},
+  {0.002294,-0.394349},
+  {-0.774411,1.119519},
+  {-0.807535,0.342889},
+  {-0.122509,0.143458},
+  {-1.612262,0.133762},
+  {-0.704500,-0.634429},
+  {0.421355,1.477149},
+  {-0.346425,1.488303},
+  {-0.320905,1.385086},
+  {0.517736,1.018882},
+  {-0.698406,-0.561933},
+  {0.455363,1.519318},
+  {-1.529130,-0.417045},
+  {1.090679,1.108610},
+  {0.054188,0.538953},
+  {0.034975,0.942247},
+  {1.127053,-1.169750},
+  {0.347556,0.169247},
+  {-0.388350,-0.124856},
+  {0.119545,0.172064},
+  {0.335029,-0.074899},
+  {-0.071492,0.385402},
+  {0.701349,0.030827},
+  {0.272265,0.385385},
+  {-1.295989,-0.440285},
+  {-0.016185,-0.292499},
+  {-0.425862,0.192669},
+  {-0.474981,1.023225},
+  {0.378090,-0.085647},
+  {-1.380673,-0.172079},
+  {0.267498,-0.609266},
+  {-0.174361,-0.720071},
+  {-0.903868,0.497839},
+  {-0.754455,0.498984},
+  {0.333531,0.300701},
+  {0.570416,0.121552},
+  {-0.856487,1.273007},
+  {0.864065,0.677483},
+  {-0.359296,-0.764656},
+  {0.373897,-0.165979},
+  {0.004695,1.059938},
+  {-0.205988,0.159122},
+  {0.240554,-0.757747},
+  {-2.731705,-1.090066},
+  {0.196211,-0.214263},
+  {-1.060994,0.303117},
+  {0.065935,-1.370273},
+  {0.147199,0.460440},
+  {-1.434710,-0.211987},
+  {0.506390,0.291023},
+  {-0.385415,0.150877},
+  {-0.058076,0.033607},
+  {-0.040447,0.121214},
+  {0.217183,0.381020},
+  {0.008537,0.171304},
+  {-0.793652,0.273910},
+  {-0.113031,-0.165199},
+  {-0.137888,-0.411958},
+  {0.129773,1.543414},
+  {0.026013,1.008311},
+  {0.859350,0.590368},
+  {0.137087,-0.138097},
+  {0.273403,-0.938621},
+  {0.365497,-0.156764},
+  {0.670901,0.144948},
+  {0.356986,-0.869288},
+  {-0.882520,-0.440277},
+  {0.462818,0.724776},
+  {-0.573334,-0.513149},
+  {-0.216443,-1.260162},
+  {-0.037775,0.735246},
+  {-0.374519,0.457316},
+  {0.058640,-0.761478},
+  {-0.440620,-0.890988},
+  {-0.052313,-0.360096},
+  {-0.537367,0.085238},
+  {-0.894927,-0.267870},
+  {-0.710221,-0.890203},
+  {-1.603747,1.430830},
+  {1.840006,1.279425},
+  {0.449807,0.176538},
+  {0.071127,-0.599730},
+  {0.340974,0.830768},
+  {0.167339,0.262566},
+  {-0.519153,-0.781460},
+  {-0.953526,-0.572926},
+  {-0.718084,1.342914},
+  {0.887380,-0.767601},
+  {-0.500773,-1.256327},
+  {-0.504054,-0.387444},
+  {-0.423248,0.941044},
+  {-0.075436,-0.011957},
+  {0.778830,-0.741112},
+  {0.527124,1.470712},
+  {-0.061345,0.245175},
+  {-0.108031,-0.165018},
+  {0.089631,-0.062024},
+  {-0.079677,-0.101521},
+  {-0.396044,-0.025846},
+  {0.849632,0.900182},
+  {0.614655,-0.309219},
+  {-0.168051,0.184285},
+  {0.629810,-0.125703},
+  {-0.626641,-0.299066},
+  {-0.766331,0.668178},
+  {1.026631,0.970999},
+  {1.056465,0.385935},
+  {0.034025,0.934794},
+  {1.049357,-1.364552},
+  {-0.307284,0.554048},
+  {-0.124591,0.459456},
+  {0.634236,0.196816},
+  {0.846920,-0.870074},
+  {0.377849,-0.151186},
+  {0.010945,0.711493},
+  {-0.143725,-0.331314},
+  {-0.428652,0.812929},
+  {-0.507231,0.476529},
+  {0.822266,-0.169064},
+  {-0.312591,0.878717},
+  {0.126182,-0.185989},
+  {1.011325,0.536978},
+  {0.511545,1.633077},
+  {-1.054305,0.395063},
+  {1.824536,0.854489},
+  {-1.843423,1.187168},
+  {-0.260379,0.320860},
+  {0.762158,0.289641},
+  {0.273799,-0.015125},
+  {0.406928,0.953909},
+  {-0.053545,-0.024161},
+  {-0.636427,-0.198150},
+  {-0.601937,-0.004703},
+  {0.117514,-0.399147},
+  {0.147300,-0.182524},
+  {0.117742,-0.391568},
+  {0.598795,-0.217514},
+  {-0.530160,-1.275872},
+  {-0.448360,0.509787},
+  {-0.231334,0.208376},
+  {0.653553,-0.510494},
+  {-0.469246,-0.599648},
+  {0.223253,-0.260082},
+  {0.425304,-1.320700},
+  {-1.013285,-0.561188},
+  {-0.649321,0.686967},
+  {-1.283270,-0.227414},
+  {-0.186007,0.368703},
+  {-0.136933,-0.192889},
+  {1.185159,0.545198},
+  {1.216968,0.689015},
+  {0.910311,-0.002513},
+  {-0.253238,-0.334718},
+  {-0.272165,0.329764},
+  {0.419154,0.171196},
+  {0.856108,-0.866033},
+  {-0.363408,-1.279964},
+  {-0.323154,1.229737},
+  {0.515595,0.771904},
+  {-0.113071,0.472993},
+  {-1.090156,-0.702003},
+  {-0.615317,0.258520},
+  {-1.389988,0.090579},
+  {0.227189,1.873838},
+  {0.238943,1.189236},
+  {0.997707,-0.750336},
+  {-0.168988,1.198045},
+  {-0.908115,-0.325316},
+  {-0.276129,-0.887500},
+  {-0.193721,0.061984},
+  {0.372694,-1.067987},
+  {-0.021077,-1.086837},
+  {-0.355942,-0.129020},
+  {0.601311,0.890568},
+  {0.458201,0.949799},
+  {0.477640,0.087344},
+  {0.024384,0.268283},
+  {-0.314620,0.511970},
+  {0.208499,-0.010617},
+  {1.054139,-0.793165},
+  {0.712241,0.313028},
+  {0.095001,0.032736},
+  {-0.050507,-0.099467},
+  {0.966046,-0.046950},
+  {0.735177,-0.035276},
+  {1.216582,-0.536102},
+  {0.579388,0.044030},
+  {-0.031001,-1.871012},
+  {1.061978,-0.288872},
+  {-0.504246,-0.401761},
+  {-0.562567,-0.284664},
+  {-0.275011,-0.021875},
+  {-0.393798,0.931489},
+  {0.006711,0.841041},
+  {0.402936,0.199119},
+  {0.107574,-1.388760},
+  {-0.230410,0.022241},
+  {-0.191842,-1.192988},
+  {1.171249,0.021609},
+  {0.716926,0.486816},
+  {0.145686,0.517127},
+  {-1.328921,0.377331},
+  {0.851484,-1.077027},
+  {-0.182252,-0.973016},
+  {0.547530,0.307628},
+  {0.752337,0.227463},
+  {-0.943868,-1.105141},
+  {0.051322,1.847229},
+  {0.162891,1.662704},
+  {0.215910,0.074535},
+  {0.968104,-0.819955},
+  {0.398545,0.106263},
+  {0.311276,0.300695},
+  {0.553913,1.407050},
+  {-0.074835,-0.314706},
+  {-0.756606,-0.249815},
+  {-0.007184,0.241820},
+  {-0.903521,-1.140063},
+  {-0.347949,0.735517},
+  {-1.520924,-0.054318},
+  {-0.336836,-1.417745},
+  {0.668140,-0.550144},
+  {-0.813826,-0.378920},
+  {-1.142460,-0.895100},
+  {-0.464542,0.305670},
+  {-0.803636,0.464800},
+  {-0.519269,0.330770},
+  {-0.744446,0.223551},
+  {0.133873,0.641134},
+  {-0.234319,-0.617046},
+  {0.237105,0.190497},
+  {-0.207124,0.186992},
+  {-0.222716,-0.026379},
+  {0.616382,0.940631},
+  {-0.202311,0.380659},
+  {0.365658,0.144009},
+  {1.794867,-0.495343},
+  {0.500606,-0.433379},
+  {0.363196,-0.689170},
+  {-0.025768,0.286324},
+  {-0.868493,1.012894},
+  {0.110665,-0.207569},
+  {-0.041372,1.248633},
+  {0.885087,-0.488457},
+  {0.910808,0.069023},
+  {0.693604,-0.067264},
+  {0.566380,0.592366},
+  {1.130313,-0.894986},
+  {0.853269,1.224186},
+  {0.451775,0.907155},
+  {-0.899638,-0.755130},
+  {0.009159,-0.715130},
+  {0.725935,-0.067967},
+  {-0.648557,-0.976766},
+  {-0.215151,-0.130206},
+  {-0.882912,1.101720},
+  {0.549423,1.141824},
+  {0.091037,-1.123045},
+  {0.851998,-1.088543},
+  {0.671949,-0.768697},
+  {-0.026212,-0.142371},
+  {0.188458,0.044498},
+  {1.035851,0.732378},
+  {0.496930,0.763086},
+  {0.620814,-0.084441},
+  {-0.816705,-1.005846},
+  {0.129933,0.607144},
+  {-0.335244,0.079260},
+  {0.062206,0.842265},
+  {0.342883,0.267645},
+  {-0.570073,0.645440},
+  {-0.179948,-0.386216},
+  {-0.767378,0.206902},
+  {0.759143,-0.306648},
+  {0.482275,0.475103},
+  {0.825030,-0.514951},
+  {-1.028938,-0.819744},
+  {1.732835,0.066877},
+  {0.450762,-0.541033},
+  {-0.616540,-0.408825},
+  {0.089601,-0.831240},
+  {-0.716228,-0.620456},
+  {-0.045554,1.373536},
+  {0.723475,0.165982},
+  {0.238882,-0.391897},
+  {1.879258,0.418675},
+  {-0.908657,0.808384},
+  {-0.286725,0.203416},
+  {0.622622,1.988791},
+  {-0.204689,0.503124},
+  {-0.840514,-1.052989},
+  {0.109104,-0.491465},
+  {-0.458429,-0.890611},
+  {-0.040308,0.387025},
+  {0.334213,0.845817},
+  {-0.485131,1.161892},
+  {-0.154884,-0.021494},
+  {0.901447,0.368832},
+  {-0.577289,0.422688},
+  {0.066667,0.480205},
+  {0.497143,1.273457},
+  {0.411773,-0.013752},
+  {0.663922,0.240592},
+  {0.147365,-0.939324},
+  {0.265064,-0.679686},
+  {0.080121,-0.490473},
+  {0.405063,-0.141264},
+  {1.250869,-1.013448},
+  {-1.771650,-0.026840},
+  {-0.214699,-0.238854},
+  {0.153398,0.152295},
+  {-0.332406,0.850663},
+  {0.082405,0.034282},
+  {-0.778027,1.776842},
+  {1.119535,0.093578},
+  {0.405343,0.144457},
+  {0.318296,-1.045619},
+  {0.894029,-0.789367},
+  {-0.705205,-0.559302},
+  {-0.583245,-0.587218},
+  {-1.732809,0.502952},
+  {-0.072216,-0.619449},
+  {-1.005389,-1.337074},
+  {-0.925036,-1.050076},
+  {-0.849897,1.451525},
+  {-0.640269,-0.536556},
+  {0.280792,-0.596720},
+  {-1.731763,-1.392341},
+  {0.225837,-1.310780},
+  {-0.855570,0.357171},
+  {-0.596824,0.705603},
+  {1.015263,-0.013845},
+  {-1.378102,-0.871470},
+  {-0.037446,-0.148328},
+  {-1.100256,-0.404901},
+  {0.618017,-0.193406},
+  {-0.165397,0.385855},
+  {1.048162,1.070281},
+  {0.913836,0.796236},
+  {-0.470200,-0.595482},
+  {0.435984,0.550976},
+  {0.991639,0.713741},
+  {1.354705,0.236459},
+  {-0.514888,0.034946},
+  {0.447832,-0.324686},
+  {-0.324818,0.064890},
+  {0.512776,-1.010271},
+  {0.644555,1.172259},
+  {-0.884525,0.399588},
+  {0.106287,-0.599133},
+  {0.245535,0.597192},
+  {-0.128277,0.432917},
+  {0.307422,-0.650546},
+  {0.870460,0.392310},
+  {-0.236295,0.161812},
+  {-0.905288,0.260416},
+  {-0.288011,-0.014239},
+  {-0.391415,-0.625783},
+  {1.255478,-0.407403},
+  {1.023093,0.311064},
+  {0.059888,-2.054203},
+  {0.200850,0.982033},
+  {0.936100,0.701518},
+  {-0.629761,0.267995},
+  {1.891356,-0.312648},
+  {0.084493,0.120200},
+  {0.658455,0.408385},
+  {0.401558,-0.236054},
+  {0.213266,-0.339748},
+  {0.249614,1.030643},
+  {0.861996,-0.401135},
+  {-0.645997,-0.919200},
+  {0.345041,-0.019794},
+  {0.422888,-1.570761},
+  {-0.728576,-0.302344},
+  {0.698979,0.162284},
+  {0.432374,-0.278804},
+  {0.288216,-0.280750},
+  {0.692058,-0.788072},
+  {-0.513736,0.160921},
+  {-0.484442,0.091290},
+  {0.217502,0.258031},
+  {-0.564786,-0.078785},
+  {0.773842,-0.205731},
+  {0.496951,0.661244},
+  {0.703862,0.256431},
+  {0.417277,-0.643702},
+  {0.030253,0.964357},
+  {0.487751,-0.148838},
+  {0.603282,0.729704},
+  {0.623268,-1.087961},
+  {0.673468,0.933167},
+  {-0.456305,0.170897},
+  {-0.397510,-0.674178},
+  {-0.320248,0.681368},
+  {0.138825,0.000576},
+  {-0.706556,0.500306},
+  {-0.180191,-0.216743},
+  {-1.383253,0.599270},
+  {-0.024074,0.774923},
+  {0.117188,0.327920},
+  {-0.897107,-0.217729},
+  {0.780948,-1.488166},
+  {-0.189833,-1.665574},
+  {0.160742,0.396893},
+  {0.132436,-0.269463},
+  {-0.477604,0.319153},
+  {-1.594824,-0.229696},
+  {-1.033510,0.226079},
+  {-0.375408,0.377189},
+  {0.203341,-0.627341},
+  {0.000475,-0.876883},
+  {-0.354389,-0.692829},
+  {0.902375,0.537518},
+  {0.765544,1.350291},
+  {0.617121,0.549060},
+  {0.191055,-1.656615},
+  {-0.637320,0.461113},
+  {-0.139140,0.405568},
+  {0.338228,0.190319},
+  {-0.111718,0.427500},
+  {-0.607051,-0.223998},
+  {-0.256013,-0.126726},
+  {-0.460717,0.657032},
+  {-0.264035,0.642030},
+  {-0.480224,-0.125524},
+  {-1.104871,-1.244684},
+  {0.794316,-0.618685},
+  {-1.325048,0.625898},
+  {-0.609105,-0.317561},
+  {-0.110370,0.574926},
+  {-0.079341,-0.941059},
+  {1.123131,0.516150},
+  {0.646988,-0.799697},
+  {-0.528347,0.716934},
+  {-1.297124,0.049700},
+  {0.952649,-0.161405},
+  {0.104493,-0.030703},
+  {-1.168308,1.727449},
+  {0.676470,0.693357},
+  {-0.412443,0.253094},
+  {-0.447798,0.038550},
+  {-0.228133,0.125712},
+  {0.274084,-0.664014},
+  {-1.273383,-0.516870},
+  {0.331193,-0.663290},
+  {0.834921,-1.083132},
+  {-0.016795,0.063665},
+  {0.463293,0.100810},
+  {-0.222092,-1.166433},
+  {-0.045631,-0.035269},
+  {-0.045329,-0.674897},
+  {-0.784392,-1.057570},
+  {-0.329826,0.339698},
+  {1.178970,0.965670},
+  {-0.300943,-0.650654},
+  {0.152251,-0.474047},
+  {-0.578936,-0.462915},
+  {0.349399,-0.057776},
+  {0.102065,-0.396655},
+  {0.217686,0.393256},
+  {-1.565998,-0.678150},
+  {-0.317381,0.390873},
+  {0.032866,0.637578},
+  {-0.462473,-1.228468},
+  {0.037433,-0.126953},
+  {-0.219955,-0.079598},
+  {0.986041,-0.242647},
+  {0.981236,-0.308921},
+  {-0.714607,0.747562},
+  {0.878252,0.290233},
+  {-0.013550,-0.801533},
+  {-0.837193,-0.073407},
+  {0.004598,-0.299227},
+  {0.718243,-0.521436},
+  {-1.411477,0.345819},
+  {-0.185560,0.407726},
+  {-0.645613,0.341977},
+  {-0.144282,-0.130033},
+  {0.170185,0.210823},
+  {0.648260,0.522148},
+  {0.163927,0.452781},
+  {0.091997,-1.512229},
+  {-0.925560,0.389415},
+  {0.396382,-0.605291},
+  {-0.206984,0.810648},
+  {0.605544,-0.329259},
+  {-0.496895,-0.433621},
+  {0.821201,-0.159951},
+  {-0.287604,-0.461316},
+  {0.269550,-0.172898},
+  {0.223504,-0.519438},
+  {-1.219596,-1.509329},
+  {-1.177703,0.106731},
+  {-0.614510,-2.303451},
+  {-0.508790,-0.814873},
+  {-0.235748,-0.655716},
+  {0.675918,0.241968},
+  {0.848823,0.109502},
+  {-0.339173,0.251667},
+  {-0.907714,0.025476},
+  {1.135073,-0.983344},
+  {0.597885,0.092979},
+  {0.775967,0.017399},
+  {-2.228663,-0.026600},
+  {0.991905,1.087891},
+  {-1.345601,0.617191},
+  {0.369217,-0.003157},
+  {0.380365,-0.183456},
+  {1.141741,-0.120062},
+  {0.208724,0.917995},
+  {-0.751646,1.025081},
+  {-0.244497,-1.070647},
+  {-0.426150,-0.441223},
+  {-0.083133,0.600314},
+  {-0.639394,-0.449710},
+  {-0.227868,-0.052185},
+  {0.039466,0.902238},
+  {-0.228256,0.424697},
+  {-1.264894,1.007502},
+  {0.025662,-1.050856},
+  {-0.853853,-0.077905},
+  {-0.283073,0.020308},
+  {0.102863,0.285404},
+  {-0.729183,-0.883586},
+  {0.488278,-0.537274},
+  {-0.638371,0.705178},
+  {0.257958,0.187060},
+  {1.876355,-0.296744},
+  {-0.029220,0.081046},
+  {-1.202058,0.013792},
+  {0.143679,-0.221348},
+  {0.813612,1.334167},
+  {-0.308881,0.009709},
+  {0.744881,0.191344},
+  {0.703735,0.479720},
+  {0.916091,0.301598},
+  {0.229351,0.527300},
+  {0.608015,1.084639},
+  {-0.028380,0.179041},
+  {0.741942,0.210321},
+  {-0.441117,2.019392},
+  {0.287010,1.148982},
+  {0.751560,-0.634404},
+  {0.633605,-0.574008},
+  {0.254998,0.117379},
+  {1.321661,-0.738031},
+  {-0.086967,-0.576727},
+  {0.357126,0.432979},
+  {-0.743290,0.811585},
+  {-0.501911,0.783671},
+  {-0.187481,0.444391},
+  {0.175805,0.576845},
+  {0.749123,0.582751},
+  {-1.669288,-1.212711},
+  {-0.024771,0.530228},
+  {-0.600212,0.278748},
+  {0.380659,0.552119},
+  {-0.054384,-0.183081},
+  {-0.577043,1.758637},
+  {-1.290098,-0.034919},
+  {-0.626743,-0.901914},
+  {0.548593,0.563251},
+  {-1.189395,-0.111436},
+  {0.672192,0.884066},
+  {0.490141,-0.258325},
+  {1.522702,-0.355020},
+  {0.280899,0.463460},
+  {0.297340,-0.975150},
+  {-0.783965,-0.193888},
+  {0.116301,-0.696152},
+  {-0.613030,0.111460},
+  {-1.438732,-0.335699},
+  {0.152343,0.580044},
+  {0.174164,-0.175062},
+  {-0.148853,-0.874012},
+  {0.175072,0.017771},
+  {0.358267,0.083250},
+  {-1.047536,0.175354},
+  {-0.048482,-0.104485},
+  {0.180338,0.466878},
+  {-0.062379,-0.997160},
+  {-0.737199,-0.210693},
+  {0.536667,0.012390},
+  {0.013080,-0.896293},
+  {-1.111020,0.036888},
+  {-0.592474,-0.623239},
+  {-0.587658,-1.419053},
+  {0.481731,0.315493},
+  {0.239846,0.451458},
+  {-0.107999,-0.142484},
+  {-0.238403,0.700594},
+  {0.326648,0.295695},
+  {0.709781,-0.414870},
+  {-0.303296,-0.812312},
+  {0.605543,-1.441576},
+  {0.046576,0.392842},
+  {0.391747,1.805781},
+  {-0.610474,-0.502987},
+  {-0.084417,-0.635316},
+  {-0.117791,-0.511594},
+  {1.263054,-0.152197},
+  {0.036088,-1.413123},
+  {-1.142865,0.441812},
+  {0.670441,-1.734080},
+  {-0.655343,-0.321802},
+  {0.441931,-0.212622},
+  {0.368448,-1.376489},
+  {0.216562,-0.500590},
+  {0.430320,0.433900},
+  {0.910263,0.145197},
+  {0.261373,-0.024356},
+  {-0.931035,-1.031641},
+  {0.071638,-0.030381},
+  {1.047164,-0.390936},
+  {0.786061,0.374129},
+  {0.399636,-0.470714},
+  {-0.828217,0.411402},
+  {0.402586,0.304012},
+  {0.173574,-0.061146},
+  {0.718928,0.903788},
+  {0.757697,-0.340347},
+  {0.311022,-0.630422},
+  {-0.320119,0.438468},
+  {0.213126,0.315590},
+  {-0.367474,-0.858977},
+  {-0.364710,-0.211865},
+  {-0.088531,-0.338955},
+  {-0.426875,-1.259798},
+  {0.017767,0.903531},
+  {-1.317742,-0.291868},
+  {-0.021616,-0.223357},
+  {-0.466416,-0.982947},
+  {-0.723046,-0.216801},
+  {-0.506496,-1.256971},
+  {-0.876586,-0.668156},
+  {0.799653,0.883145},
+  {-0.116016,-0.230735},
+  {0.153892,0.245910},
+  {-1.493473,-0.543369},
+  {-0.104258,0.937885},
+  {0.145870,-0.862457},
+  {0.004280,0.091261},
+  {-0.201859,0.062320},
+  {1.434108,0.390146},
+  {0.223945,-0.417881},
+  {-1.429893,-0.221635},
+  {-0.263642,-0.043051},
+  {-0.301817,-0.656976},
+  {-0.055533,-0.422469},
+  {-0.170936,0.094114},
+  {0.920585,-0.536474},
+  {-0.244583,0.125218},
+  {-0.398405,-0.673800},
+  {-0.648268,-0.174215},
+  {0.104402,-0.545924},
+  {1.039966,-0.450643},
+  {0.454026,-0.007051},
+  {-1.348483,0.435892},
+  {-1.154315,0.012219},
+  {0.586239,-0.790228},
+  {0.420334,-0.425579},
+  {-0.695935,0.400174},
+  {-0.324462,-0.569611},
+  {-0.891715,1.286844},
+  {-0.225809,-0.497207},
+  {-0.877583,-0.401090},
+  {-0.230709,-0.162162},
+  {0.040464,0.348907},
+  {-0.431771,0.340009},
+  {0.045460,-0.714410},
+  {-0.216520,-2.046873},
+  {0.804486,0.379955},
+  {0.107529,0.317036},
+  {0.349638,-1.542756},
+  {0.112593,0.633379},
+  {0.245919,-1.442921},
+  {1.226988,0.413531},
+  {-0.216186,-1.098418},
+  {-0.592056,-0.703833},
+  {-0.461250,1.152356},
+  {-0.451106,-1.041155},
+  {0.758497,-0.026281},
+  {0.580829,0.434704},
+  {-0.244442,-1.287007},
+  {0.871367,-0.668387},
+  {-0.252397,-0.492179},
+  {-0.105915,0.221225},
+  {-0.396868,0.424444},
+  {0.468587,-0.808788},
+  {-0.332904,0.334434},
+  {-0.300457,-0.004120},
+  {0.200741,0.652505},
+  {-0.290567,0.311535},
+  {-0.596088,-0.685691},
+  {0.383474,-0.564410},
+  {0.365202,-0.520154},
+  {0.303368,0.394516},
+  {0.156166,0.414418},
+  {-1.362271,-0.651302},
+  {-0.565455,0.543162},
+  {-0.528145,0.145123},
+  {-1.176076,-1.178721},
+  {0.086984,-0.105966},
+  {-0.021746,-0.978670},
+  {0.518625,0.155903},
+  {-1.258329,0.223466},
+  {0.130332,-0.419232},
+  {0.563122,0.231711},
+  {0.306401,-0.507524},
+  {-1.053291,1.560204},
+  {0.047668,0.546148},
+  {0.948363,0.284353},
+  {0.672895,0.507781},
+  {-1.334744,-0.168633},
+  {-1.208243,0.148212},
+  {-0.848912,0.415874},
+  {0.843947,0.736823},
+  {-1.158485,0.210237},
+  {-0.099862,1.120765},
+  {0.337771,0.007164},
+  {-0.469080,0.520155},
+  {-0.100074,-1.349217},
+  {-0.157844,0.287353},
+  {-0.779996,0.294751},
+  {0.073369,0.492718},
+  {-0.464267,0.726453},
+  {-0.462696,-0.741070},
+  {0.023056,1.172214},
+  {0.224251,0.025615},
+  {-0.336091,-0.276409},
+  {0.473509,-0.561504},
+  {0.845649,-0.907685},
+  {0.627133,-0.351774},
+  {-0.990811,-0.590419},
+  {-0.172712,-0.470133},
+  {0.723323,-0.199676},
+  {-0.307695,-0.713114},
+  {-0.083497,0.329677},
+  {-0.518250,0.421263},
+  {0.084627,0.104033},
+  {-0.333341,0.047107},
+  {-1.401702,0.346693},
+  {-1.554243,-0.861078},
+  {0.326409,-0.263726},
+  {-0.100557,-0.931537},
+  {1.703162,0.946824},
+  {-0.198882,-0.911880},
+  {-0.506174,-0.771035},
+  {-0.827505,0.609437},
+  {0.673322,-0.205578},
+  {-0.806857,-0.975934},
+  {0.294299,0.863600},
+  {-0.008905,0.140791},
+  {-0.175659,-0.263704},
+  {0.242597,-0.175465},
+  {0.581556,-0.693348},
+  {0.221080,-0.123343},
+  {0.864177,1.380508},
+  {-0.485638,-0.235111},
+  {0.019145,-0.507227},
+  {1.115591,1.035217},
+  {-1.242264,-0.613672},
+  {0.528370,0.525414},
+  {-0.389619,-0.519511},
+  {-0.156849,-0.205102},
+  {-0.985984,-1.423871},
+  {0.517087,-0.357108},
+  {-0.199417,-0.794782},
+  {0.201648,-0.957863},
+  {0.127940,-0.981328},
+  {-0.892293,-0.484381},
+  {-0.246429,-0.134570},
+  {-1.208455,1.697750},
+  {0.005429,0.475156},
+  {1.495576,-0.048856},
+  {-0.532713,0.246399},
+  {0.020822,0.397247},
+  {-0.943340,0.215974},
+  {0.091969,0.698433},
+  {-0.605709,-0.662562},
+  {-0.662931,0.331181},
+  {0.510917,-0.498797},
+  {-0.070321,-0.339604},
+  {-0.828848,0.232796},
+  {0.637634,0.622874},
+  {-0.384873,0.201997},
+  {0.762228,-0.732545},
+  {-0.051603,-0.149058},
+  {0.029130,0.529245},
+  {0.834301,0.594478},
+  {-0.261223,-0.069449},
+  {-1.302920,-0.290366},
+  {-0.609619,-0.588839},
+  {0.497506,0.424783},
+  {-0.187720,0.612541},
+  {0.017128,0.698742},
+  {-1.811540,-0.055316},
+  {0.862133,-1.369530},
+  {1.262000,-0.131324},
+  {1.156433,0.484189},
+  {-0.076493,-0.424579},
+  {-0.130062,1.379691},
+  {0.833397,0.567487},
+  {0.078902,0.473863},
+  {0.055890,-0.769505},
+  {0.060725,-0.404843},
+  {0.000445,0.737484},
+  {-0.625014,-0.395060},
+  {-0.753279,-0.276740},
+  {1.520089,1.037106},
+  {-0.319487,1.277601},
+  {0.118810,1.297974},
+  {-0.215298,-0.455871},
+  {0.254708,0.218111},
+  {0.418569,-0.707815},
+  {-1.185689,0.006936},
+  {0.123850,0.442040},
+  {-0.408899,0.843042},
+  {-0.086253,-0.322820},
+  {-1.244809,-0.408063},
+  {-0.152610,0.218428},
+  {-0.304509,0.721444},
+  {-0.223893,-0.198213},
+  {0.161462,0.965719},
+  {-0.016545,-0.046833},
+  {0.014223,0.409396},
+  {1.975500,-1.416411},
+  {0.987470,-0.295333},
+  {1.392536,-0.339042},
+  {-1.772024,1.071792},
+  {0.561628,0.260545},
+  {-0.614207,0.253911},
+  {0.255899,0.338669},
+  {-0.545300,0.377977},
+  {-0.781682,-0.308513},
+  {-0.473559,0.115544},
+  {0.970356,0.389522},
+  {1.340998,0.204031},
+  {0.636971,-0.691872},
+  {1.087438,-0.703128},
+  {0.335864,-0.678190},
+  {-0.567828,-0.567210},
+  {-0.650808,0.427866},
+  {-0.267197,-0.819795},
+  {-0.757122,-1.946263},
+  {-0.479753,-0.686059},
+  {-1.058098,-0.284788},
+  {-0.601739,-1.515210},
+  {0.613674,0.326730},
+  {1.501791,-0.056387},
+  {-0.990549,0.002105},
+  {-0.865560,-0.308869},
+  {0.464395,-0.231092},
+  {-0.644999,0.444856},
+  {0.545002,-0.193149},
+  {0.447797,-0.492268},
+  {-0.421009,-0.021117},
+  {-0.190813,0.311118},
+  {0.467296,0.294717},
+  {0.154595,1.419043},
+  {0.281873,0.405801},
+  {-1.053144,0.367926},
+  {0.048581,1.905063},
+  {-0.637562,-0.469837},
+  {0.650205,-1.538225},
+  {-0.885319,-0.085329},
+  {-0.052037,0.098850},
+  {-1.205488,0.099386},
+  {1.421300,-0.337389},
+  {0.163746,1.595691},
+  {0.316168,0.058669},
+  {0.901451,-0.757891},
+  {0.374950,0.220098},
+  {0.289515,-0.754124},
+  {-0.344068,-0.343308},
+  {0.232374,0.263313},
+  {2.246893,0.378554},
+  {-0.376969,0.322563},
+  {0.709981,-1.565807},
+  {-0.784404,0.311436},
+  {-0.414114,0.191005},
+  {-0.912873,-1.111710},
+  {0.022198,1.018839},
+  {-1.388431,-0.029500},
+  {1.318379,0.695939},
+  {0.832088,-0.225946},
+  {-0.685464,1.189551},
+  {-1.724108,0.128743},
+  {-0.267640,0.820472},
+  {0.369300,1.266272},
+  {-0.485413,-1.174063},
+  {-1.258036,0.730961},
+  {-1.037161,-0.806028},
+  {-1.128983,-0.308337},
+  {0.655767,-0.390841},
+  {-0.343421,0.248034},
+  {0.458703,-0.580272},
+  {-0.309516,-0.875010},
+  {0.612543,0.577868},
+  {0.291884,0.221870},
+  {0.556053,0.899818},
+  {-0.155180,-0.104632},
+  {0.342271,0.297307},
+  {0.201082,0.328868},
+  {1.519672,-1.255112},
+  {-0.277044,0.809604},
+  {-0.983866,-0.270883},
+  {-0.252473,0.652332},
+  {0.320750,0.253181},
+  {0.439080,-1.174365},
+  {0.577125,0.328839},
+  {0.900496,0.913433},
+  {0.217882,-0.002589},
+  {-0.005437,-0.172455},
+  {0.777052,-0.589731},
+  {-0.319754,-0.552669},
+  {0.663022,0.005191},
+  {-0.444068,0.973952},
+  {-0.284655,0.373087},
+  {-0.653444,0.000541},
+  {0.937499,-0.190486},
+  {-0.353436,-0.421615},
+  {-0.586946,1.251421},
+  {-0.106296,-0.907972},
+  {-0.133041,-1.699473},
+  {-1.323406,1.678851},
+  {0.297010,-1.495266},
+  {-0.282727,-0.006885},
+  {2.101317,-0.581565},
+  {-0.386652,0.065565},
+  {-0.086661,0.930770},
+  {1.072493,-0.689899},
+  {-1.072787,1.386659},
+  {1.079130,0.126657},
+  {-0.255408,-0.604117},
+  {0.923296,0.431058},
+  {0.884115,0.288090},
+  {-0.783201,-0.804343},
+  {-1.563031,0.029382},
+  {-0.366755,0.047618},
+  {0.931579,0.790832},
+  {0.079395,-1.064498},
+  {-0.576885,-1.423422},
+  {1.061247,-0.359222},
+  {-0.079346,-0.583210},
+  {-0.513897,-1.038086},
+  {-0.306731,-0.347102},
+  {-0.303644,0.082931},
+  {1.070749,0.846657},
+  {0.596321,-0.863198},
+  {-1.493087,0.752431},
+  {-0.326493,-0.259466},
+  {0.762672,0.637558},
+  {0.470650,-0.475920},
+  {1.217709,1.223485},
+  {-0.105262,0.348860},
+  {0.809125,0.110621},
+  {0.705164,-0.451192},
+  {0.256454,0.998392},
+  {-0.182322,-1.808778},
+  {0.132926,-0.046858},
+  {-0.115529,-0.094157},
+  {-0.386512,-0.427899},
+  {1.703266,0.413302},
+  {1.689060,0.300520},
+  {-0.746970,-0.620105},
+  {0.331307,1.166821},
+  {-1.642881,-0.355440},
+  {0.284702,-0.125837},
+  {-0.942006,0.609114},
+  {0.490133,-0.550940},
+  {0.479289,0.712846},
+  {-0.733015,1.085078},
+  {1.342473,0.807258},
+  {-0.139847,-0.210786},
+  {-1.019707,-0.083367},
+  {-0.515722,-0.667669},
+  {-0.490205,0.536208},
+  {1.137698,-2.187429},
+  {0.689605,-0.279192},
+  {-0.758482,-1.078222},
+  {-0.062444,-1.440962},
+  {-0.959758,-0.131322},
+  {0.578693,1.089248},
+  {-0.447809,0.153117},
+  {-0.380639,0.131958},
+  {0.663486,0.877594},
+  {0.280871,-1.058013},
+  {-0.699962,0.353879},
+  {-0.162627,0.269167},
+  {-0.204061,0.751909},
+  {0.209289,-0.584008},
+  {0.284208,0.331193},
+  {0.885480,0.772389},
+  {-0.252435,-0.861216},
+  {1.302831,0.447444},
+  {0.039083,-0.234160},
+  {-0.935810,-0.162396},
+  {0.125644,0.184471},
+  {0.445812,-1.213550},
+  {-1.380393,0.775430},
+  {-0.188419,0.701213},
+  {0.684211,-0.154271},
+  {-0.182573,0.039267},
+  {0.811469,-0.969950},
+  {-0.778200,1.188098},
+  {-0.049732,-0.445024},
+  {-0.852271,-0.949873},
+  {0.086241,-0.750884},
+  {-0.096712,-1.624033},
+  {-0.400723,0.228941},
+  {1.049161,-2.253919},
+  {-0.058805,-0.708923},
+  {-1.286261,-1.145985},
+  {-0.215680,0.977318},
+  {-1.137437,0.643552},
+  {0.648707,0.534293},
+  {-0.097589,0.270605},
+  {-0.536918,0.019383},
+  {0.467302,0.109569},
+  {-1.583003,-0.761356},
+  {-0.935186,-0.891575},
+  {-0.514207,0.428989},
+  {0.765034,-0.341230},
+  {0.067731,0.661021},
+  {-0.145722,0.204315},
+  {-0.062658,0.608009},
+  {0.471454,0.095159},
+  {-0.452387,1.030955},
+  {0.553401,-0.726777},
+  {0.622963,0.530085},
+  {0.208907,1.294012},
+  {-0.324651,1.366459},
+  {-0.576267,-0.393594},
+  {-1.011991,0.804189},
+  {0.737499,0.822178},
+  {0.481131,-0.143674},
+  {-0.684440,0.644153},
+  {0.794158,-0.398822},
+  {0.568346,0.400063},
+  {0.913021,-0.104825},
+  {-0.181232,-0.575912},
+  {-1.186140,0.417101},
+  {0.311493,0.955016},
+  {0.331007,1.201278},
+  {0.208202,0.031411},
+  {0.463080,0.501488},
+  {0.482757,0.079090},
+  {-0.880469,0.584826},
+  {-0.159840,-0.023861},
+  {0.845792,-0.498914},
+  {1.200194,-0.998738},
+  {-0.687638,0.627621},
+  {0.834554,-0.044152},
+  {-0.567932,0.022438},
+  {0.649994,-0.451273},
+  {1.550910,0.386612},
+  {0.643220,-1.226031},
+  {-0.084707,0.483131},
+  {1.142138,-0.495484},
+  {0.591518,0.600105},
+  {0.909766,-0.968842},
+  {-0.318164,-1.216190},
+  {-0.002672,0.682111},
+  {0.303462,-0.734521},
+  {-1.328197,-0.512260},
+  {0.142123,-0.446938},
+  {-0.563399,-0.108576},
+  {-0.595759,0.432539},
+  {0.140978,-0.820013},
+  {0.691118,-0.298545},
+  {-0.892137,0.532776},
+  {0.882700,-0.514615},
+  {-1.126496,-0.553388},
+  {-0.366223,0.264003},
+  {1.216088,-0.643513},
+  {0.144411,0.190855},
+  {-0.513814,1.301282},
+  {-0.139218,-1.666939},
+  {-0.873328,1.087577},
+  {0.368330,-0.436673},
+  {-0.799562,0.387875},
+  {1.105326,0.374214},
+  {0.212973,0.611913},
+  {-1.233469,-0.191584},
+  {-0.678596,-0.747265},
+  {-1.464750,0.891797},
+  {-0.103633,0.529639},
+  {0.946408,0.704495},
+  {-0.247739,0.650610},
+  {0.314285,-0.478465},
+  {-0.801484,-1.330346},
+  {-0.474770,0.029146},
+  {0.156161,0.354246},
+  {-0.514883,0.437114},
+  {-0.723243,-0.302359},
+  {-0.623393,-0.064006},
+  {0.668911,0.512527},
+  {-0.200754,0.270304},
+  {1.274333,-1.593959},
+  {-0.433487,-0.077630},
+  {1.022869,-0.724708},
+  {1.302765,-0.324157},
+  {0.048530,0.524041},
+  {0.580503,0.255952},
+  {0.871851,-0.571890},
+  {-1.320527,0.372024},
+  {-0.837724,-1.330308},
+  {-0.130319,1.947338},
+  {-0.966811,-0.248498},
+  {-0.980519,0.121219},
+  {-0.928127,0.014107},
+  {0.784902,-0.292815},
+  {-0.001154,0.102495},
+  {0.174204,-0.798143},
+  {-0.616828,-1.187243},
+  {0.901858,0.095972},
+  {-0.036058,-0.624901},
+  {-0.136308,0.048002},
+  {0.724986,0.204018},
+  {-0.290315,-0.226273},
+  {-0.937261,0.310854},
+  {1.350983,1.247481},
+  {0.132400,-0.117268},
+  {-0.433586,0.672210},
+  {0.427985,1.263974},
+  {0.053098,-0.134753},
+  {0.145390,-1.579824},
+  {-0.466987,-0.271971},
+  {-0.452877,-0.054139},
+  {-0.137701,-0.493978},
+  {0.449226,0.123858},
+  {0.641004,-1.580859},
+  {0.732717,0.424758},
+  {-1.191464,-0.668713},
+  {-0.068454,-1.558817},
+  {-1.255019,0.090546},
+  {0.133334,-0.672320},
+  {-0.357994,-0.062960},
+  {-0.179648,-0.136934},
+  {-1.405926,-0.152062},
+  {-0.122649,-0.447278},
+  {-0.956039,0.706032},
+  {-0.577964,0.702715},
+  {-1.092396,-0.224851},
+  {-0.080453,0.539972},
+  {0.941582,0.526443},
+  {-0.245442,-0.421211},
+  {-0.655510,0.175952},
+  {0.090653,0.356258},
+  {0.597282,0.245042},
+  {-1.281953,1.174625},
+  {0.246278,0.484865},
+  {-2.421806,-0.626013},
+  {-0.515321,0.348373},
+  {0.100784,-0.155870},
+  {-0.518027,-0.137351},
+  {-1.091217,0.932436},
+  {0.298705,0.215227},
+  {-0.032357,0.318942},
+  {-0.028669,0.835347},
+  {-0.164235,-0.633671},
+  {-0.978889,0.405411},
+  {-0.366083,-0.163942},
+  {-0.367713,0.709928},
+  {-0.245638,-0.099905},
+  {-0.171231,0.640628},
+  {-0.531550,-0.252464},
+  {-0.460142,1.860309},
+  {-1.486483,-0.241096},
+  {-1.050993,-0.330973},
+  {0.877660,0.278261},
+  {0.471375,0.863250},
+  {0.815270,0.878291},
+  {-1.064940,1.248690},
+  {-0.069835,-0.017150},
+  {1.102388,0.275357},
+  {1.179494,0.240331},
+  {-1.664730,-0.144800},
+  {-0.236780,-0.450388},
+  {0.727520,-0.630164},
+  {-0.976490,-0.375161},
+  {1.003983,-1.257875},
+  {-0.358144,-0.688150},
+  {0.425984,0.320394},
+  {0.145065,-0.070437},
+  {-0.791365,-0.328291},
+  {0.251614,-0.243055},
+  {-0.393163,0.191665},
+  {-0.150863,-0.584294},
+  {-0.673513,-0.686572},
+  {-0.402621,-0.474615},
+  {-1.157962,-0.033111},
+  {0.452590,-1.526519},
+  {0.021951,-0.726401},
+  {-0.912745,0.826707},
+  {-0.372052,0.412758},
+  {0.777297,-0.106160},
+  {-0.135258,0.030331},
+  {-0.109689,-0.926576},
+  {0.683335,-1.604886},
+  {-0.421987,0.744210},
+  {-0.557095,-0.775698},
+  {0.454006,-0.044498},
+  {0.177879,0.041843},
+  {0.074312,0.324311},
+  {-1.059395,0.620565},
+  {-0.421680,0.527942},
+  {-1.202068,1.160552},
+  {-0.115764,-0.745636},
+  {-1.541088,0.056196},
+  {0.381186,0.008007},
+  {-0.499599,0.141341},
+  {0.013978,-0.125940},
+  {0.090000,-1.187147},
+  {1.160943,-0.631971},
+  {-0.156704,0.697033},
+  {-1.239590,-0.623728},
+  {-0.792073,0.313426},
+  {-0.731100,-0.549662},
+  {-0.357447,1.054545},
+  {-1.142243,-0.677072},
+  {0.337990,0.046116},
+  {0.530248,-1.446341},
+  {0.636612,-0.662750},
+  {-2.179262,0.191543},
+  {-0.550411,0.747675},
+  {-0.402629,0.988314},
+  {-0.083953,0.479871},
+  {0.124996,-0.359557},
+  {0.421828,0.346338},
+  {-0.171740,-1.735271},
+  {1.095081,-0.775815},
+  {-0.492503,0.267703},
+  {-0.204414,0.545646},
+  {0.385776,-0.276769},
+  {0.183290,0.903289},
+  {-0.084581,-0.121421},
+  {-0.245414,-0.714739},
+  {-0.576804,0.885006},
+  {-1.119495,-0.231658},
+  {1.164001,0.578247},
+  {0.112226,0.129056},
+  {-0.593079,-1.115176},
+  {0.166237,-0.014866},
+  {-0.444435,0.569202},
+  {-1.420244,-0.532449},
+  {-0.340449,-0.654735},
+  {1.268462,-0.042484},
+  {-0.553843,-0.819293},
+  {0.303196,-0.769441},
+  {0.388195,-0.520681},
+  {-0.196868,-0.813691},
+  {0.519316,-1.007083},
+  {0.706958,0.112890},
+  {-1.075358,-0.054663},
+  {0.741997,0.785043},
+  {0.052625,-0.121979},
+  {0.253025,0.356385},
+  {0.828369,-0.593061},
+  {-0.384827,0.456143},
+  {-0.140667,0.196871},
+  {-1.966096,-0.083070},
+  {-1.020553,-1.461990},
+  {0.190510,-0.037306},
+  {-0.625134,-0.080120},
+  {-0.562010,-0.950249},
+  {-0.230976,-0.527893},
+  {-0.228677,-0.348693},
+  {-0.332359,-0.311350},
+  {-0.704024,-1.084836},
+  {-0.434046,0.133438},
+  {-0.318342,-0.053535},
+  {-0.096872,0.012919},
+  {-0.610696,-0.174108},
+  {-0.252555,-0.509190},
+  {1.061245,0.467663},
+  {0.252635,-0.703320},
+  {-0.212390,1.327738},
+  {0.587415,0.199159},
+  {-0.966466,-0.076941},
+  {-0.829028,1.083157},
+  {-0.505337,1.097833},
+  {0.691992,0.091951},
+  {0.564158,0.597321},
+  {0.804210,0.592029},
+  {-0.413688,0.496419},
+  {-0.298775,0.196912},
+  {-0.092485,-0.806745},
+  {-1.159163,0.204774},
+  {-0.794889,-0.067174},
+  {-0.438785,-0.115991},
+  {0.282720,-0.231078},
+  {-1.228366,-0.260419},
+  {-1.528740,-0.246528},
+  {-0.246221,-0.580162},
+  {0.114350,-1.968410},
+  {-0.218031,-0.356657},
+  {-0.948797,0.708502},
+  {-0.805080,-0.480688},
+  {-0.334364,0.785381},
+  {0.070317,-0.128118},
+  {0.470661,-0.323759},
+  {-0.185075,0.483122},
+  {-0.404439,0.149669},
+  {0.074842,0.256006},
+  {-1.013446,0.621396},
+  {-0.134759,0.287886},
+  {0.376520,1.192665},
+  {-0.362520,-0.634418},
+  {0.362985,-0.196815},
+  {0.653376,0.725399},
+  {1.234385,-0.520766},
+  {0.281393,1.887825},
+  {-0.506625,0.262909},
+  {-1.755273,0.507609},
+  {-0.321531,-0.128175},
+  {0.301331,-0.922664},
+  {-0.600594,-1.248979},
+  {-0.314934,-0.073132},
+  {-1.253293,-0.794391},
+  {-0.119523,-0.106375},
+  {-1.036734,-0.848670},
+  {-0.204574,0.546471},
+  {0.823228,0.262015},
+  {1.082957,-0.114482},
+  {-0.728824,0.148125},
+  {-0.883430,0.785116},
+  {0.641440,-0.078952},
+  {-1.272558,0.134591},
+  {0.505240,-0.602016},
+  {-0.972164,1.092034},
+  {0.612247,0.549404},
+  {0.450208,0.493039},
+  {-0.525409,0.940858},
+  {-0.216053,0.053321},
+  {-0.034777,0.076897},
+  {-0.559997,-1.618377},
+  {-0.739954,0.626905},
+  {-0.033963,-0.233715},
+  {0.672760,-0.049505},
+  {-0.208845,-0.160882},
+  {0.953452,-0.034831},
+  {-0.376313,-0.779698},
+  {-1.116935,0.789470},
+  {1.852068,-0.400982},
+  {0.337988,-0.001624},
+  {0.591794,-0.223387},
+  {-0.764729,-0.256717},
+  {0.409644,-0.331827},
+  {0.353446,0.986947},
+  {0.013275,-0.074213},
+  {0.197200,-0.544923},
+  {-0.331489,0.568903},
+  {0.432285,-0.929833},
+  {0.600862,0.718698},
+  {0.872893,-0.419268},
+  {-0.200237,-0.718290},
+  {0.242213,0.079084},
+  {-1.577807,1.174048},
+  {-0.379725,0.187433},
+  {0.307646,1.344402},
+  {1.215462,0.395933},
+  {0.029692,0.606788},
+  {0.892763,-0.031153},
+  {0.685208,0.002816},
+  {0.907146,0.248276},
+  {0.328204,0.310385},
+  {-0.450021,-0.534631},
+  {2.075611,-0.976094},
+  {0.337534,0.624849},
+  {-0.375221,-0.715899},
+  {-0.134676,-0.128634},
+  {-0.654845,-0.951174},
+  {-0.407146,-0.844925},
+  {-1.268266,-0.592878},
+  {-0.624101,-0.781781},
+  {-0.162159,-0.785210},
+  {-1.763260,0.357187},
+  {-0.408447,0.565726},
+  {-0.392385,-0.323932},
+  {0.070956,-0.460428},
+  {-0.053136,0.207713},
+  {-0.164207,-1.296008},
+  {-1.192106,-1.901697},
+  {-0.431213,-1.017489},
+  {-0.520848,1.407188},
+  {0.145023,-0.336089},
+  {0.856252,-0.968676},
+  {0.695109,-1.115058},
+  {0.942748,0.032814},
+  {-0.442368,0.501998},
+  {-1.339842,0.494702},
+  {0.793722,0.683030},
+  {-0.080036,-0.001120},
+  {-0.124282,-0.176612},
+  {-0.510859,-0.403349},
+  {-0.013581,-0.068892},
+  {-0.285268,0.123699},
+  {0.681833,-0.376550},
+  {0.665080,1.385498},
+  {-1.217502,0.225975},
+  {-0.594094,-0.361329},
+  {0.640636,-1.635224},
+  {0.440288,-0.173718},
+  {-1.095971,0.028588},
+  {-0.391012,0.536173},
+  {-0.679180,-0.332060},
+  {0.443795,0.206495},
+  {0.102913,-0.012004},
+  {-0.877523,-1.194485},
+  {1.576267,-0.479076},
+  {-1.125040,-0.707965},
+  {-0.293637,-0.295395},
+  {1.163673,0.261285},
+  {-0.009871,1.620751},
+  {0.420659,1.657904},
+  {0.184678,0.360919},
+  {-1.117315,-0.182509},
+  {-1.805887,-0.737423},
+  {1.715050,-0.359039},
+  {0.548347,-0.711148},
+  {0.819885,-0.536776},
+  {0.038829,-0.046101},
+  {-1.555754,1.115475},
+  {0.059829,-0.900202},
+  {0.215772,0.610962},
+  {0.008583,-0.164357},
+  {-0.394604,-0.266908},
+  {-0.089186,0.115016},
+  {0.879229,-1.099212},
+  {0.666276,-1.094933},
+  {-2.243026,0.931909},
+  {1.069452,-0.301207},
+  {1.192592,1.144332},
+  {-0.546448,-0.404087},
+  {1.042238,0.099649},
+  {-1.150986,-0.352998},
+  {1.671102,0.062038},
+  {-0.292935,-0.142184},
+  {0.912273,0.927933},
+  {-0.610804,-0.790526},
+  {-1.233318,0.582164},
+  {0.362886,0.126435},
+  {0.266818,0.880278},
+  {0.334312,-0.851251},
+  {-0.625542,0.254909},
+  {0.730234,0.366879},
+  {0.714704,0.004163},
+  {1.194976,-0.023707},
+  {0.326624,-0.471626},
+  {-0.229043,-0.827678},
+  {0.325709,-0.115376},
+  {0.677117,-0.136203},
+  {0.609055,-0.553231},
+  {0.043072,-0.424984},
+  {0.441790,0.828142},
+  {-0.436910,-0.103521},
+  {-0.626695,0.363246},
+  {-1.091702,0.016860},
+  {0.576059,0.141374},
+  {-0.152014,-0.661996},
+  {-0.774034,-0.052961},
+  {0.523869,0.787151},
+  {0.022872,0.624295},
+  {2.371050,2.241895},
+  {0.099188,-0.686992},
+  {-0.026026,-0.171252},
+  {0.675816,1.843051},
+  {0.006666,0.000152},
+  {1.021349,0.543076},
+  {-0.602923,0.676056},
+  {1.027891,-0.418795},
+  {-1.759205,-1.102256},
+  {1.116023,0.103083},
+  {0.576224,-1.411952},
+  {-0.156183,1.999043},
+  {0.124434,-0.238939},
+  {-0.938087,0.337435},
+  {0.047635,0.159295},
+  {0.217816,-0.807263},
+  {-0.727492,0.439254},
+  {0.245795,-1.372293},
+  {1.078585,0.289308},
+  {-0.746381,-0.190481},
+  {0.461490,-0.156236},
+  {0.279562,-0.141011},
+  {0.800455,0.112162},
+  {0.846632,-1.442145},
+  {0.896583,-0.366371},
+  {0.142449,0.555705},
+  {0.443817,-0.165670},
+  {-0.278247,1.893330},
+  {-0.148235,0.209155},
+  {0.819120,-0.340799},
+  {0.110860,-0.461213},
+  {-0.191900,-1.200356},
+  {0.385260,0.158268},
+  {0.179177,-0.338312},
+  {0.286717,0.336873},
+  {-0.596235,-0.074333},
+  {0.311757,-1.159880},
+  {-0.906439,0.587565},
+  {0.837066,-0.107715},
+  {-0.260451,-1.427325},
+  {-0.216606,1.473217},
+  {-1.717780,-0.058343},
+  {-1.378627,0.891233},
+  {-0.079320,0.532493},
+  {-0.016687,0.630684},
+  {0.240314,0.096040},
+  {-0.331577,0.458243},
+  {0.372299,-1.365709},
+  {-0.741196,1.252891},
+  {-0.264394,-0.346368},
+  {0.174941,0.592150},
+  {-0.182301,0.472894},
+  {-1.078744,0.352627},
+  {0.668825,-0.839549},
+  {-0.794913,0.098837},
+  {0.346916,0.827142},
+  {-0.557851,-0.824683},
+  {0.152571,-1.089133},
+  {0.317379,-0.377552},
+  {-0.310447,-0.798186},
+  {1.416259,0.538289},
+  {-0.139209,0.950880},
+  {-0.671851,-0.023958},
+  {-0.295455,0.491929},
+  {-0.042358,-0.225679},
+  {0.306427,-0.412672},
+  {-0.096405,-0.210148},
+  {1.661258,-0.451881},
+  {0.887263,-0.441136},
+  {1.303738,0.032488},
+  {1.248415,-0.771581},
+  {-0.521452,0.088019},
+  {-1.103925,-1.154315},
+  {0.257631,1.121379},
+  {-0.262130,0.533858},
+  {0.605826,-0.581051},
+  {-0.188663,0.498607},
+  {0.764838,0.473480},
+  {0.860975,-1.159374},
+  {0.452993,0.327307},
+  {0.175875,1.009939},
+  {0.281291,-0.479527},
+  {0.434156,0.687246},
+  {0.453294,0.558911},
+  {0.191183,-0.316014},
+  {0.214000,0.309648},
+  {0.502847,0.327473},
+  {-0.398865,-1.147691},
+  {-0.952348,0.394180},
+  {-0.349121,-0.235417},
+  {-0.449837,0.044554},
+  {-0.402914,-0.408737},
+  {0.199668,0.760049},
+  {0.010913,-0.831466},
+  {0.090912,0.009287},
+  {0.512837,-0.858424},
+  {-0.283099,-0.240292},
+  {-0.112692,-0.322550},
+  {-0.417705,-0.353556},
+  {-1.267119,0.235106},
+  {-0.412714,-1.078769},
+  {-1.068857,-0.020876},
+  {0.735610,-0.698172},
+  {0.097437,1.100995},
+  {-0.824265,-0.625636},
+  {-0.151463,0.035774},
+  {-0.097028,-0.167782},
+  {-0.354245,-0.055691},
+  {0.360549,0.749328},
+  {0.718972,-0.297089},
+  {0.093750,-0.638153},
+  {-0.247393,-0.297925},
+  {-1.029741,-0.068838},
+  {0.526758,0.786855},
+  {-0.926147,0.224848},
+  {0.558481,-0.057841},
+  {-0.267158,-0.691253},
+  {-1.247372,-0.770014},
+  {-0.163633,-1.488970},
+  {-0.501774,0.176045},
+  {0.136177,-0.868078},
+  {0.777970,0.447295},
+  {0.460035,0.095623},
+  {0.503416,-0.169723},
+  {1.171534,-0.676447},
+  {-0.713499,0.434530},
+  {0.462648,0.066601},
+  {-0.832730,-1.270562},
+  {0.765136,0.913623},
+  {0.417389,0.798048},
+  {-1.426013,-0.274914},
+  {-0.825985,-0.424720},
+  {0.603344,-0.834278},
+  {0.709370,0.850793},
+  {0.003214,-0.250830},
+  {-1.002978,-0.742748},
+  {-0.936138,0.680271},
+  {-0.053393,0.089266},
+  {0.420002,-0.368487},
+  {0.710330,-0.438794},
+  {-1.087089,0.102425},
+  {0.476970,-1.002341},
+  {0.375935,0.399873},
+  {-0.989189,0.653074},
+  {0.872430,0.758053},
+  {-0.890879,-0.312795},
+  {-0.238132,-0.250050},
+  {0.849829,-0.245135},
+  {-0.306339,1.034213},
+  {0.133859,-0.614994},
+  {-0.556895,0.160389},
+  {-0.042028,-1.154500},
+  {-0.019949,-0.576390},
+  {-1.028293,0.814275},
+  {0.766851,0.887268},
+  {0.044484,-0.512244},
+  {0.795847,-0.238133},
+  {-0.123321,1.153876},
+  {1.732138,0.309731},
+  {-0.429759,0.508320},
+  {-0.700518,-0.577407},
+  {0.586965,0.247099},
+  {0.474665,-0.264909},
+  {0.657846,0.682646},
+  {1.683598,-0.181147},
+  {0.481185,0.407061},
+  {-0.867097,-0.307912},
+  {-0.884851,0.803434},
+  {0.248120,0.335810},
+  {-0.766947,-0.015652},
+  {0.138088,-0.540963},
+  {0.483644,-0.292753},
+  {0.434778,-0.933118},
+  {0.969690,-0.575479},
+  {0.033365,-0.110259},
+  {0.045278,-0.657264},
+  {-0.823623,0.516920},
+  {-0.153628,-1.007980},
+  {-0.500080,0.938031},
+  {-0.332981,0.507900},
+  {0.290413,0.159538},
+  {-0.402051,0.813947},
+  {0.464196,0.574152},
+  {0.578220,-1.425212},
+  {0.202852,-0.043236},
+  {1.658922,0.205793},
+  {-0.485749,-0.745853},
+  {-0.446857,0.377168},
+  {0.876179,1.074485},
+  {-0.584951,0.013578},
+  {-0.837915,-0.240871},
+  {-1.524292,0.233789},
+  {-0.825139,0.748604},
+  {1.596491,0.933630},
+  {-0.401496,-1.003424},
+  {-0.258193,-0.695623},
+  {-0.052062,-0.166794},
+  {0.690957,0.351045},
+  {0.493275,-0.920828},
+  {-0.863543,1.297232},
+  {-0.108419,0.062067},
+  {1.378657,-1.208240},
+  {0.085856,-1.104558},
+  {-0.366961,0.245213},
+  {0.832540,0.165383},
+  {-0.584261,0.126903},
+  {0.016941,0.536423},
+  {-0.270773,1.502084},
+  {-0.372237,-0.400977},
+  {1.068030,-0.451306},
+  {-0.621204,-0.546822},
+  {1.960128,0.187646},
+  {-0.280504,-0.872304},
+  {0.683431,0.366819},
+  {0.595984,-0.857526},
+  {-0.631380,-0.386350},
+  {0.020853,-0.369727},
+  {-0.212579,0.923348},
+  {0.683995,-0.323235},
+  {0.805253,0.720984},
+  {-0.198278,-0.751235},
+  {-0.587794,1.028549},
+  {0.082077,0.108813},
+  {0.745455,-0.151971},
+  {-0.976860,-1.417301},
+  {-0.100352,0.301667},
+  {0.452015,0.239125},
+  {-1.198564,1.164572},
+  {-0.347850,-0.780059},
+  {1.005080,-0.098043},
+  {-0.076527,0.140155},
+  {0.822524,0.259489},
+  {-0.484033,0.190539},
+  {0.547659,0.465998},
+  {0.402279,-0.058429},
+  {-0.145342,0.125883},
+  {-0.136622,1.065746},
+  {0.408618,-0.650430},
+  {0.015056,0.491154},
+  {1.132468,-0.328837},
+  {-0.012391,-0.686920},
+  {0.053038,0.495824},
+  {0.071729,-0.474581},
+  {-0.440191,-0.561736},
+  {-0.524869,0.365948},
+  {0.556736,-0.017547},
+  {0.292031,-0.097135},
+  {1.006116,1.298618},
+  {0.516901,0.626829},
+  {0.630999,-0.413970},
+  {0.774604,-1.207384},
+  {-0.615805,0.565898},
+  {0.364355,-0.950000},
+  {0.530245,-1.069383},
+  {1.242254,0.041582},
+  {1.198631,-0.852988},
+  {0.409406,-0.362121},
+  {-0.051573,1.378894},
+  {0.526354,0.639450},
+  {-0.194904,-1.121370},
+  {0.927330,1.050282},
+  {-1.444789,0.271173},
+  {-0.428099,0.664772},
+  {-0.780386,0.717917},
+  {-0.113324,-0.553108},
+  {0.355862,-0.738216},
+  {-0.099107,0.064152},
+  {-0.154411,1.265266},
+  {0.802506,-0.378603},
+  {-0.254708,-0.134292},
+  {0.098108,-0.759107},
+  {-0.609531,-1.121607},
+  {-0.421901,-0.211898},
+  {0.711968,-0.180637},
+  {-1.105167,1.156956},
+  {-1.003797,0.694685},
+  {0.049084,-0.230107},
+  {-0.236223,1.025917},
+  {0.404298,-0.017089},
+  {-0.066885,0.931927},
+  {-1.723563,-0.969529},
+  {0.491575,-0.029033},
+  {0.623884,-0.068448},
+  {0.176416,-0.045140},
+  {-0.898063,-0.441314},
+  {0.054965,-0.105671},
+  {0.099547,0.031943},
+  {-0.136638,-0.641491},
+  {-0.416031,0.788225},
+  {0.421132,0.199360},
+  {0.973337,-0.185653},
+  {0.088055,0.466610},
+  {0.175948,0.713615},
+  {-0.186074,-0.718673},
+  {-0.477278,0.873979},
+  {0.439899,0.385747},
+  {0.281673,1.501744},
+  {-0.893871,0.167312},
+  {-1.196201,0.511553},
+  {-0.088248,1.523528},
+  {-0.127180,0.047668},
+  {-1.244524,1.220496},
+  {-0.458583,0.408467},
+  {-0.423980,-0.843592},
+  {-0.680569,-0.034943},
+  {0.025603,-0.219165},
+  {-0.182524,-0.609754},
+  {-0.540846,1.056731},
+  {0.303247,1.820157},
+  {0.180851,0.479806},
+  {0.025760,-1.252858},
+  {-0.747286,-0.234204},
+  {-1.773173,0.069396},
+  {0.370812,-0.513683},
+  {-0.420497,-0.847213},
+  {-0.820247,0.180888},
+  {0.377636,-0.251796},
+  {-0.084840,0.837256},
+  {0.204533,-0.516983},
+  {-0.579383,0.361949},
+  {-0.079244,-0.997139},
+  {0.763352,-0.920005},
+  {0.991156,0.097808},
+  {-0.207017,-0.379039},
+  {-1.048663,0.392404},
+  {-0.947993,-0.165707},
+  {0.222565,-1.486800},
+  {1.309369,0.187803},
+  {0.083914,0.759151},
+  {0.017533,-0.350594},
+  {0.936769,-0.133694},
+  {-0.542859,0.015576},
+  {0.527186,1.057142},
+  {0.576027,-1.107543},
+  {-0.597828,0.116528},
+  {-0.573770,-0.408299},
+  {-0.564696,0.907437},
+  {-0.843667,0.002832},
+  {1.708716,-1.282816},
+  {0.099415,-0.410289},
+  {-1.175233,0.409935},
+  {-0.505987,1.096503},
+  {0.831878,-0.633435},
+  {-0.036724,0.894208},
+  {-1.009229,0.523294},
+  {-0.206856,-0.518026},
+  {-0.265399,0.734165},
+  {-1.418101,-0.082190},
+  {0.605095,0.372543},
+  {-1.234487,1.112847},
+  {-0.036487,0.136546},
+  {-0.027486,-0.021950},
+  {0.087476,0.308363},
+  {0.380610,-0.770809},
+  {-0.612494,0.395982},
+  {-0.760804,0.774983},
+  {1.865483,0.743280},
+  {0.077926,0.679733},
+  {-0.346491,-0.172862},
+  {0.652737,-0.498038},
+  {-0.306556,-0.127240},
+  {1.422770,-0.788084},
+  {0.727473,0.199273},
+  {0.998929,0.906173},
+  {-0.062778,-0.292218},
+  {0.389584,-0.499927},
+  {1.122804,0.323068},
+  {-0.936607,0.116318},
+  {0.080546,-1.053398},
+  {-0.108415,0.262303},
+  {0.675554,-0.771375},
+  {0.697370,0.301939},
+  {-0.516065,0.371745},
+  {-1.958861,-0.787043},
+  {1.816436,-0.421257},
+  {0.580993,0.294074},
+  {-0.218823,-0.831417},
+  {-0.217031,-1.430616},
+  {-0.483142,0.379944},
+  {0.067187,-0.582305},
+  {-0.697808,-0.168340},
+  {1.293952,0.231077},
+  {0.097290,-0.755162},
+  {0.165245,0.091931},
+  {-1.238996,0.033182},
+  {0.094961,-0.517375},
+  {-0.390291,0.240153},
+  {0.023253,2.137456},
+  {0.621424,-0.412412},
+  {0.242280,-0.594768},
+  {-0.765264,-0.423112},
+  {-0.153731,0.730757},
+  {0.419930,0.768227},
+  {0.164315,0.199661},
+  {-1.536602,0.855813},
+  {0.226126,-0.357326},
+  {0.350009,0.143890},
+  {0.337303,0.843891},
+  {-0.411561,-1.142193},
+  {-0.701707,-0.241532},
+  {-0.754151,-0.193665},
+  {-0.371459,-0.379980},
+  {-0.276399,-0.210742},
+  {-1.074638,0.834850},
+  {1.617356,-0.576681},
+  {1.568916,-0.678719},
+  {0.562247,0.287642},
+  {0.631863,1.237075},
+  {0.042284,-0.047805},
+  {1.485053,-0.684224},
+  {0.160235,-0.248368},
+  {-0.389660,0.710686},
+  {-0.050819,0.065209},
+  {0.147388,0.158528},
+  {0.327583,-1.242319},
+  {-0.185792,-0.398783},
+  {-0.880967,-0.168451},
+  {0.561261,0.309319},
+  {0.114879,0.834084},
+  {-0.630472,0.320430},
+  {0.435172,-0.147865},
+  {0.138108,0.189852},
+  {0.433189,0.538220},
+  {-0.539843,-0.734402},
+  {0.102453,1.548384},
+  {-0.349662,-0.123426},
+  {-0.497825,-0.681592},
+  {-0.815304,0.920879},
+  {0.264205,1.651104},
+  {-0.360736,-0.822221},
+  {-0.546373,-0.203813},
+  {1.506398,0.351934},
+  {1.271735,0.262145},
+  {0.706702,0.382961},
+  {0.063130,0.014527},
+  {-0.198279,-0.082914},
+  {0.756777,0.133322},
+  {0.762393,0.070534},
+  {-1.168252,0.042773},
+  {-0.875856,0.058973},
+  {-0.907179,1.363516},
+  {0.003700,1.289862},
+  {0.279690,-0.489829},
+  {-0.952025,-0.016869},
+  {-0.062242,0.118709},
+  {0.335991,-0.262022},
+  {-0.135763,0.124727},
+  {0.827726,-0.460658},
+  {0.070106,0.118099},
+  {-0.594234,0.138962},
+  {0.638866,1.436196},
+  {0.038912,0.342362},
+  {-0.409336,1.245498},
+  {0.246502,-0.213165},
+  {-0.522154,-0.329476},
+  {-1.023245,-0.070043},
+  {0.648593,-0.512078},
+  {0.202472,-1.312851},
+  {-1.306352,-0.890312},
+  {1.086565,-0.802461},
+  {0.842372,-1.343072},
+  {-0.159571,-0.014023},
+  {0.857682,-0.038734},
+  {-1.088896,-0.345921},
+  {0.822683,0.990156},
+  {-0.329881,0.808677},
+  {1.062717,1.498025},
+  {-0.433379,-0.433149},
+  {-1.122758,-0.127346},
+  {0.542121,0.927791},
+  {0.308221,0.175934},
+  {-0.149790,-1.068382},
+  {-0.616779,-0.744305},
+  {0.839533,-0.157706},
+  {0.303678,0.382350},
+  {0.194006,-0.212379},
+  {0.033246,-0.903250},
+  {-0.338256,-0.678675},
+  {-0.613313,-0.387690},
+  {-1.010888,-0.461805},
+  {0.256900,1.327843},
+  {0.791153,0.371449},
+  {0.412562,-0.756850},
+  {0.065134,-0.322337},
+  {0.083713,0.126607},
+  {0.723780,1.256984},
+  {-1.243036,-0.742905},
+  {0.026896,0.353344},
+  {-0.269050,0.745763},
+  {1.149596,0.347420},
+  {-0.774535,0.020295},
+  {0.596979,0.015554},
+  {-0.615475,-0.620565},
+  {0.318177,0.396116},
+  {0.421686,-0.052160},
+  {-0.430877,-1.293244},
+  {-0.155236,-0.215658},
+  {-0.602139,0.532974},
+  {-0.243152,-1.579031},
+  {0.123780,-0.983632},
+  {0.136269,-0.821246},
+  {0.284418,0.304578},
+  {-0.397824,0.300438},
+  {-0.360441,0.227509},
+  {0.046855,-0.171865},
+  {-1.804252,-0.700048},
+  {-0.924882,-0.556849},
+  {0.134748,0.082988},
+  {-0.132825,-0.916706},
+  {0.786704,0.720149},
+  {1.091863,0.641613},
+  {0.881371,0.215342},
+  {-0.096880,0.560482},
+  {0.422486,-0.921443},
+  {0.341221,-0.894846},
+  {0.075976,1.064656},
+  {-0.533020,-0.023005},
+  {0.320752,0.244138},
+  {-0.040666,0.065450},
+  {1.450750,0.008950},
+  {0.306952,-0.562488},
+  {0.302953,0.123134},
+  {0.798245,0.094443},
+  {0.038655,-0.516631},
+  {-0.252824,1.501311},
+  {-0.356779,0.297983},
+  {-0.180288,1.164347},
+  {-1.407410,-0.435116},
+  {-0.576522,-0.443552},
+  {0.111603,-0.209512},
+  {0.136332,1.190104},
+  {-0.810554,0.693664},
+  {0.308525,0.629498},
+  {0.318195,-2.104560},
+  {0.162520,-0.149801},
+  {-1.142162,1.218633},
+  {-0.351640,-0.468696},
+  {-0.793111,-0.658338},
+  {-0.575915,0.941180},
+  {0.317133,0.669761},
+  {0.985808,-0.707916},
+  {0.260989,0.770580},
+  {-0.078153,-0.123214},
+  {0.053145,1.817637},
+  {-0.628024,0.069947},
+  {-0.777414,-0.126421},
+  {-0.647336,0.166883},
+  {2.207409,-0.473580},
+  {-1.038409,0.398710},
+  {-0.345503,0.161175},
+  {0.081747,0.890997},
+  {-0.308902,-0.075592},
+  {-0.139376,-0.676387},
+  {0.971584,-0.470253},
+  {-0.162857,1.149113},
+  {0.171516,0.587119},
+  {-0.613744,-0.035450},
+  {-0.580046,-0.329255},
+  {0.100551,-1.085898},
+  {-0.592872,-0.489665},
+  {-0.941300,-0.498021},
+  {0.156036,0.709273},
+  {0.178233,-0.632015},
+  {0.678891,0.228611},
+  {0.492409,-0.005288},
+  {-1.497998,-1.024431},
+  {0.838897,-0.110250},
+  {0.568010,-1.606525},
+  {-0.432611,0.904418},
+  {0.334915,1.309759},
+  {-0.890282,1.529258},
+  {-1.064858,-1.150747},
+  {0.051353,0.433881},
+  {-0.146728,-0.312565},
+  {-1.063791,-0.097197},
+  {-0.181281,0.331634},
+  {1.723937,-0.176101},
+  {0.569951,0.990671},
+  {0.418655,-0.675772},
+  {0.182521,-0.095608},
+  {-1.007120,0.018916},
+  {1.718394,1.198867},
+  {-0.313048,0.068845},
+  {-1.421110,-0.661129},
+  {-1.370764,-0.150880},
+  {0.358122,1.405506},
+  {-2.015900,-0.734896},
+  {0.605181,-0.924120},
+  {-1.191318,0.682983},
+  {-0.456857,-0.148538},
+  {0.300737,-0.194614},
+  {0.929323,0.927409},
+  {-0.450904,0.410019},
+  {0.838989,0.855354},
+  {0.011216,0.148217},
+  {1.790998,-0.435076},
+  {0.979138,0.801324},
+  {-0.434199,0.113647},
+  {0.244367,-0.759697},
+  {-0.866268,-0.172338},
+  {0.185045,-0.400993},
+  {-0.381384,-0.328469},
+  {0.870050,-1.131930},
+  {0.475579,-1.270791},
+  {0.553011,-0.863202},
+  {0.654535,0.866937},
+  {0.636370,0.353826},
+  {0.532848,-0.266808},
+  {-0.305542,0.323175},
+  {0.817581,-1.178811},
+  {-1.196670,0.435729},
+  {-0.879273,-0.080918},
+  {-0.355981,0.831777},
+  {-0.514107,-0.221697},
+  {-0.173027,0.391314},
+  {0.480640,-0.762188},
+  {-1.365528,0.280669},
+  {-1.190631,-0.468936},
+  {0.865182,-1.193025},
+  {0.501712,1.474804},
+  {-0.256834,0.036278},
+  {0.625077,-0.710525},
+  {0.236352,1.463872},
+  {1.622799,-0.836983},
+  {-1.629799,-0.761636},
+  {0.048897,1.161363},
+  {-0.782579,1.512752},
+  {0.305203,-0.203621},
+  {0.078598,0.853412},
+  {-0.590944,0.241544},
+  {0.173496,-1.406007},
+  {-0.999952,-0.051233},
+  {0.671370,-0.805464},
+  {-0.681366,0.306463},
+  {0.562013,-1.218074},
+  {-0.901352,0.429769},
+  {-0.149506,0.266835},
+  {0.214535,1.287188},
+  {-0.169843,-0.687892},
+  {-0.054779,1.567896},
+  {0.240689,0.339854},
+  {-0.874400,-0.867453},
+  {0.412938,0.074314},
+  {0.567298,-2.005843},
+  {0.023167,0.258225},
+  {-1.641902,0.893004},
+  {-0.335666,-0.481124},
+  {-0.406708,-0.010981},
+  {0.658780,0.316174},
+  {-0.955737,0.114306},
+  {-0.015993,-1.537689},
+  {1.424653,0.275514},
+  {0.391517,-0.073148},
+  {-0.745075,0.282317},
+  {0.345172,0.271172},
+  {0.481076,0.739154},
+  {-0.356021,-0.874318},
+  {-0.063438,0.390779},
+  {-1.109843,-0.988009},
+  {0.717374,0.051986},
+  {-0.076888,0.729893},
+  {1.231962,0.770958},
+  {-0.473425,0.077225},
+  {-0.541175,0.273609},
+  {0.353179,-1.140094},
+  {0.000531,0.335460},
+  {-0.553490,-0.163401},
+  {-0.267372,-0.190631},
+  {-1.005119,0.844056},
+  {-0.739355,-0.466000},
+  {1.232900,-0.286890},
+  {0.072653,0.156869},
+  {0.766814,0.123674},
+  {0.409127,0.391504},
+  {-1.568030,0.076824},
+  {0.312427,1.087632},
+  {0.194971,0.012558},
+  {-0.835118,-0.977949},
+  {1.155426,0.060691},
+  {-0.251222,0.836983},
+  {0.405056,0.222589},
+  {0.062390,-0.297580},
+  {0.201353,-0.620657},
+  {-0.057828,0.302448},
+  {0.353545,-0.819051},
+  {-1.077600,0.701107},
+  {0.551567,-0.547460},
+  {-0.206217,0.843281},
+  {0.195007,-0.522554},
+  {0.786147,0.742689},
+  {-0.915141,-0.436052},
+  {-1.052682,1.424224},
+  {0.597211,-0.177125},
+  {-0.226331,-0.785225},
+  {-1.502941,0.305148},
+  {0.211830,0.257461},
+  {0.039781,0.621727},
+  {1.764019,-0.364944},
+  {-0.011250,0.080853},
+  {-0.037767,-0.191529},
+  {0.120387,0.320196},
+  {1.215214,0.159849},
+  {0.951333,-0.128658},
+  {0.683926,0.291417},
+  {0.465572,0.464227},
+  {0.237083,-0.278794},
+  {0.825346,1.939517},
+  {-1.000650,0.397936},
+  {-0.422528,0.457669},
+  {-0.415993,-0.857881},
+  {0.654893,0.925834},
+  {0.702427,0.341379},
+  {-0.992852,-0.485504},
+  {0.468854,-0.558263},
+  {1.051053,-1.438013},
+  {-1.609177,-0.229971},
+  {-0.338898,1.308837},
+  {1.716121,-0.108408},
+  {-1.842097,-0.281067},
+  {0.180047,0.058089},
+  {0.314948,-0.365466},
+  {-0.598626,-1.149004},
+  {0.282546,0.129074},
+  {-0.297604,-0.102458},
+  {-0.134736,0.128291},
+  {1.822758,-0.192577},
+  {0.071825,-0.011008},
+  {0.497849,-0.199343},
+  {-0.005720,-0.569142},
+  {-0.765651,-0.543594},
+  {-1.172104,-0.011979},
+  {-0.242091,0.779012},
+  {-0.028042,0.723704},
+  {0.451185,-0.941516},
+  {-0.613115,-0.114437},
+  {-0.972157,0.133869},
+  {-0.076452,-0.516053},
+  {0.083782,0.204923},
+  {0.784000,0.582870},
+  {-0.183293,0.586900},
+  {-0.219489,0.464479},
+  {0.144135,1.149970},
+  {0.288305,-0.029936},
+  {1.159682,0.771728},
+  {-0.068957,0.519200},
+  {-0.352525,-0.019248},
+  {-0.265696,-0.606806},
+  {-0.369018,0.437127},
+  {0.533511,-0.112122},
+  {-0.720835,0.975622},
+  {1.285089,-0.946088},
+  {0.455252,0.289840},
+  {-1.326309,-0.639170},
+  {0.108470,-0.476583},
+  {0.142548,0.079352},
+  {-0.029694,0.643831},
+  {-1.482084,-0.771038},
+  {-0.465824,-1.087531},
+  {0.707385,0.077513},
+  {-0.076182,1.057646},
+  {0.379631,0.409768},
+  {0.188938,-0.425715},
+  {-0.234099,-0.734066},
+  {0.043174,0.676531},
+  {-1.163066,-0.193611},
+  {-0.159620,-0.673125},
+  {0.127940,-1.817839},
+  {-0.451725,0.015069},
+  {0.235742,0.360075},
+  {1.748806,-0.323556},
+  {-1.276301,0.117820},
+  {0.166940,0.213350},
+  {0.355975,0.062672},
+  {-0.320198,-1.132743},
+  {-0.855608,-1.215465},
+  {0.013539,0.799086},
+  {0.828422,0.915972},
+  {1.006847,0.215101},
+  {0.595009,0.252831},
+  {0.442370,0.482821},
+  {-0.693609,0.417306},
+  {0.288466,-1.005315},
+  {-0.396817,0.004994},
+  {-0.293724,-1.217092},
+  {1.212464,0.943142},
+  {-0.865108,0.242460},
+  {0.390441,0.080091},
+  {0.871808,-1.076529},
+  {0.254390,-0.387861},
+  {0.532100,-1.371890},
+  {0.132686,-1.074121},
+  {0.426648,0.209831},
+  {1.146969,0.503369},
+  {-0.668154,-0.483259},
+  {0.259931,-0.150336},
+  {0.082358,-0.893764},
+  {0.840501,-0.011365},
+  {-0.082053,0.647275},
+  {0.266846,1.226206},
+  {-0.140652,-0.516312},
+  {0.643273,-0.881556},
+  {-0.379870,1.065882},
+  {0.680447,0.242642},
+  {-1.571274,-0.140568},
+  {-0.535686,0.628896},
+  {-0.010813,-0.606330},
+  {0.361251,1.002445},
+  {1.065906,-0.068655},
+  {-0.224415,1.117594},
+  {0.218497,-0.668069},
+  {-0.429568,0.891438},
+  {-0.998373,-0.389920},
+  {0.226733,-0.730284},
+  {1.059704,-0.349823},
+  {-0.625330,-0.250376},
+  {0.007118,1.525240},
+  {-0.162942,-0.147716},
+  {-0.666501,1.257793},
+  {-0.909984,-0.138492},
+  {-1.032952,-0.006279},
+  {-0.404583,-1.848097},
+  {-1.225754,0.434826},
+  {1.235797,-0.792226},
+  {0.783316,-0.750591},
+  {-0.975057,0.365633},
+  {-1.894987,-0.971523},
+  {-0.147116,0.722479},
+  {0.279787,0.076446},
+  {1.433566,0.223812},
+  {0.878914,-0.054495},
+  {0.011693,0.776712},
+  {-0.558728,0.481371},
+  {0.641182,0.167371},
+  {-0.669665,-0.807005},
+  {-0.791191,0.591605},
+  {-0.461665,0.714639},
+  {0.066197,-0.199694},
+  {-1.124229,0.833225},
+  {-1.295771,-0.025693},
+  {-0.037691,-0.391047},
+  {-0.847875,0.862880},
+  {0.441229,0.830506},
+  {-0.259800,-0.491246},
+  {-0.240834,0.911920},
+  {0.442518,-0.580840},
+  {1.561534,1.501570},
+  {0.280203,0.397246},
+  {-0.194177,0.276828},
+  {0.944982,-0.351264},
+  {0.022922,0.275745},
+  {-0.867058,-1.632255},
+  {0.280170,-0.145873},
+  {0.108578,-0.052305},
+  {-0.745809,-0.673504},
+  {-0.616121,-0.379739},
+  {1.008981,-0.155303},
+  {0.285808,-0.263033},
+  {0.601160,-0.612923},
+  {0.900771,0.463246},
+  {-1.013394,-0.618011},
+  {1.233695,-0.032871},
+  {-0.521967,-0.979415},
+  {0.273272,-0.433226},
+  {-0.240057,0.465270},
+  {-0.465325,0.770377},
+  {0.988019,-1.088975},
+  {0.592680,0.367929},
+  {0.800055,-0.721733},
+  {-0.737244,-1.452977},
+  {-0.427059,0.281520},
+  {0.866413,-0.643401},
+  {-0.182692,0.588766},
+  {0.273523,0.294392},
+  {0.566235,0.542400},
+  {0.129606,0.397222},
+  {-0.579409,0.288147},
+  {-0.238510,0.268652},
+  {1.122152,0.526534},
+  {-0.841624,1.691837},
+  {0.833782,1.207890},
+  {-0.924153,2.110262},
+  {-0.474350,-0.238235},
+  {-0.515517,0.124354},
+  {-0.064715,-0.236171},
+  {0.599675,1.079644},
+  {1.849341,0.024192},
+  {0.161045,-0.379662},
+  {0.823915,0.389173},
+  {-1.260631,-0.467304},
+  {0.052479,-0.187389},
+  {-0.036665,0.449072},
+  {0.069593,-0.152828},
+  {0.068830,-1.285841},
+  {0.680442,0.401365},
+  {-0.160834,-2.024653},
+  {-0.929411,0.671114},
+  {-0.421687,0.749814},
+  {-0.065965,0.527096},
+  {0.929475,-0.741284},
+  {-0.077824,-0.442484},
+  {0.193024,-0.911981},
+  {-0.101269,0.845595},
+  {0.165756,0.295690},
+  {0.319546,0.593792},
+  {-0.808930,0.153177},
+  {1.124408,0.458110},
+  {0.771971,0.222809},
+  {-0.167902,0.238733},
+  {-0.169285,1.231875},
+  {-1.585493,0.216024},
+  {-0.747700,0.098100},
+  {0.340226,-0.192779},
+  {-1.219417,-0.107218},
+  {0.228007,0.456442},
+  {-0.007155,-0.634464},
+  {-1.875543,0.567589},
+  {-0.519810,-2.179719},
+  {-0.904975,-2.451302},
+  {0.736883,-0.419567},
+  {0.918135,-1.128765},
+  {0.384645,0.353239},
+  {0.434095,-0.284308},
+  {-0.374883,-0.095262},
+  {-0.304398,0.413076},
+  {-0.748666,1.124787},
+  {-0.701671,0.451972},
+  {0.395372,0.412637},
+  {0.588244,-0.145257},
+  {0.405163,1.023715},
+  {0.744314,0.958872},
+  {-0.037084,-0.577777},
+  {-0.628322,-1.456151},
+  {0.762014,-0.483828},
+  {-0.958353,-0.171473},
+  {-0.113997,1.464166},
+  {1.350982,-0.530942},
+  {-0.172846,-0.004565},
+  {0.233537,0.941079},
+  {-0.200530,0.383425},
+  {0.264278,0.095382},
+  {0.725498,1.193517},
+  {1.280922,-0.026653},
+  {0.097571,-0.441089},
+  {0.300984,0.414280},
+  {-0.041914,-0.544705},
+  {1.009088,0.188493},
+  {0.866042,-0.355025},
+  {-0.317615,-0.910565},
+  {0.489751,-0.574142},
+  {0.963424,-0.661532},
+  {-0.318844,-0.517722},
+  {-0.190129,0.036885},
+  {0.186444,-0.158205},
+  {0.078693,-2.586327},
+  {-0.266931,0.725793},
+  {-0.074349,0.454831},
+  {-0.374770,0.697565},
+  {-0.467025,-0.014349},
+  {-0.260550,-0.127574},
+  {0.666807,0.559806},
+  {-0.271031,-0.063661},
+  {0.095739,0.428225},
+  {-0.115755,0.220370},
+  {1.075172,-0.821800},
+  {1.387517,-1.151660},
+  {-1.516364,0.833318},
+  {-0.347857,0.250917},
+  {0.299464,0.749435},
+  {0.154734,-1.501682},
+  {-0.503228,1.050996},
+  {0.327790,-0.112045},
+  {0.987849,-0.260528},
+  {0.449412,1.852591},
+  {-0.526460,0.814047},
+  {-0.451808,-0.480134},
+  {0.678355,0.739133},
+  {0.317312,-0.328581},
+  {0.196623,0.404023},
+  {0.324616,1.699530},
+  {-0.776618,-0.269720},
+  {0.162184,0.179116},
+  {0.297846,-0.710724},
+  {-0.169321,0.167991},
+  {1.769393,1.076862},
+  {-1.380745,-0.595286},
+  {0.568804,0.534699},
+  {-0.846191,-0.871218},
+  {-0.110816,-0.141844},
+  {0.285220,-0.612886},
+  {-1.000946,-0.050010},
+  {-0.101431,-0.938313},
+  {0.162775,0.079309},
+  {-0.582009,0.345429},
+  {0.124885,0.247372},
+  {-1.328240,0.510701},
+  {0.442295,0.051789},
+  {0.949722,0.676903},
+  {-0.111284,0.899622},
+  {-0.437720,-0.322130},
+  {-0.258154,0.985684},
+  {-0.758257,0.557973},
+  {-0.421330,-0.073546},
+  {1.197222,-0.621330},
+  {-1.526086,0.768420},
+  {0.144164,0.595554},
+  {0.071158,0.831643},
+  {0.121315,1.096341},
+  {-0.442333,0.055718},
+  {0.261819,-0.929387},
+  {-0.335194,-0.703410},
+  {-0.634767,-0.488540},
+  {-0.152389,-0.588104},
+  {0.153830,-0.655196},
+  {-0.631695,0.677282},
+  {1.746302,-0.602460},
+  {0.338172,-0.699808},
+  {0.901305,0.660470},
+  {1.137559,-0.192002},
+  {-0.332112,0.081961},
+  {-0.379872,0.728106},
+  {-0.433884,-1.073145},
+  {-0.247557,0.726460},
+  {-0.232024,-0.849128},
+  {1.187650,-0.092062},
+  {-0.392385,-0.780775},
+  {0.413751,-0.559636},
+  {-0.431597,-0.961824},
+  {0.463489,0.645597},
+  {-0.897957,-0.663863},
+  {0.842534,-0.688768},
+  {-0.834302,-0.540110},
+  {0.174923,-0.886926},
+  {0.256774,-0.733313},
+  {-0.513784,-0.360074},
+  {0.156928,0.710061},
+  {-0.779415,-0.205818},
+  {1.122295,-0.263072},
+  {-0.067941,-0.241437},
+  {0.775305,-1.499039},
+  {-0.959691,-0.336725},
+  {-0.557347,0.644162},
+  {0.097356,0.117803},
+  {0.085507,1.845262},
+  {0.507571,-0.452847},
+  {0.157979,0.584192},
+  {0.534463,0.510878},
+  {0.436897,-0.704341},
+  {-0.598275,-1.183016},
+  {-0.479736,1.993246},
+  {-1.004427,-0.606627},
+  {1.175857,-0.209354},
+  {-0.555928,0.024468},
+  {-0.519805,-0.867264},
+  {0.391430,0.558873},
+  {-0.640640,0.630178},
+  {-1.513294,0.362170},
+  {-0.096170,0.302206},
+  {1.549390,0.176401},
+  {-0.712729,0.480838},
+  {0.400243,-0.498461},
+  {0.050925,-0.342701},
+  {0.365122,0.134136},
+  {0.517262,1.140502},
+  {0.650985,-0.879352},
+  {0.791790,0.189469},
+  {0.654234,0.497645},
+  {0.384115,-0.034611},
+  {-0.125724,0.640141},
+  {-0.543262,-1.255624},
+  {-0.220592,-0.656310},
+  {-0.130609,-0.147886},
+  {-0.441347,0.720036},
+  {0.400598,-0.080680},
+  {-0.199337,0.873405},
+  {0.032691,1.536398},
+  {-0.093394,-1.310056},
+  {-0.854984,1.071773},
+  {0.102072,-0.810930},
+  {-0.477344,0.066698},
+  {0.648895,0.026279},
+  {-0.285891,1.400032},
+  {-1.216298,-0.236778},
+  {-0.549714,0.688796},
+  {-0.062685,-0.343855},
+  {-0.341088,0.238776},
+  {0.105347,0.048365},
+  {0.514533,-0.634733},
+  {-0.571926,0.456588},
+  {0.367809,-0.456143},
+  {0.979090,-1.286519},
+  {-1.218222,0.367350},
+  {-0.590629,-1.532832},
+  {-1.718226,0.242958},
+  {1.096783,-0.711503},
+  {0.588342,0.376010},
+  {0.744463,0.371433},
+  {0.003243,0.668123},
+  {0.062086,0.809872},
+  {-1.132122,-0.104988},
+  {0.084982,0.995250},
+  {-0.688752,0.216891},
+  {0.215504,-0.061450},
+  {0.452003,-0.690233},
+  {-0.723135,-0.275493},
+  {0.357621,-0.515781},
+  {-0.890998,-0.479333},
+  {0.498701,-0.923387},
+  {0.936200,-2.091405},
+  {-0.879032,1.485557},
+  {0.332185,-0.128280},
+  {0.550373,0.387625},
+  {0.632224,0.633608},
+  {-0.605378,1.048378},
+  {-0.472907,0.472679},
+  {-0.926621,0.312398},
+  {-0.285207,-0.148072},
+  {-0.160155,-0.599110},
+  {0.743425,0.098568},
+  {0.668188,1.079139},
+  {1.112103,1.452457},
+  {-0.727684,-0.625500},
+  {0.582495,0.602978},
+  {-0.533045,-0.290135},
+  {-0.137783,-0.815375},
+  {-0.423199,-0.027111},
+  {-0.199832,0.858830},
+  {-0.774598,-0.479101},
+  {-0.808559,0.112108},
+  {-0.095061,-0.376614},
+  {-0.643351,1.359531},
+  {0.932951,-1.417012},
+  {-0.848382,-0.222414},
+  {-1.002188,-1.075297},
+  {-0.939211,-0.668392},
+  {0.479471,-0.342248},
+  {-0.651955,0.089450},
+  {-0.529345,1.103163},
+  {-0.297371,0.787987},
+  {-0.692098,-0.212505},
+  {0.441398,0.601694},
+  {1.155338,0.506600},
+  {0.806606,-0.500708},
+  {-0.740199,-1.292330},
+  {-0.301074,0.068852},
+  {0.517610,0.645486},
+  {-0.240596,0.629380},
+  {0.078991,-0.446581},
+  {0.463990,-0.548239},
+  {0.076625,-0.265612},
+  {0.100232,-0.929770},
+  {0.066872,0.589058},
+  {-0.187736,-0.658316},
+  {-0.822249,0.309850},
+  {-0.917348,0.269891},
+  {-0.295888,0.149902},
+  {0.910250,0.779854},
+  {-0.763011,-0.047352},
+  {-0.345678,-0.728869},
+  {0.991317,-1.211605},
+  {0.654773,-1.301914},
+  {0.240193,0.127080},
+  {0.683297,0.857939},
+  {-1.056701,0.902413},
+  {0.538899,-0.329668},
+  {-0.212189,0.730930},
+  {-1.240264,-0.481620},
+  {-0.735395,-0.030127},
+  {-0.024994,-0.142647},
+  {0.112034,-0.735685},
+  {0.427365,-0.104027},
+  {-0.416424,-1.693984},
+  {1.186313,0.507243},
+  {-1.550728,0.625737},
+  {-0.395223,1.280803},
+  {0.117296,0.255594},
+  {0.078576,-0.343091},
+  {0.336925,-0.610704},
+  {0.535086,-0.319883},
+  {0.586244,0.858364},
+  {0.792222,-0.425311},
+  {-1.174751,-0.317509},
+  {-0.296053,1.341013},
+  {-0.761628,0.373641},
+  {0.144214,-0.064574},
+  {0.308336,-0.161496},
+  {0.713510,0.549545},
+  {0.561945,0.014662},
+  {0.618634,0.376704},
+  {0.566078,-0.488592},
+  {0.749551,-0.008964},
+  {-1.439229,-1.800224},
+  {0.330291,0.691467},
+  {-0.371258,1.717772},
+  {0.264541,1.219097},
+  {-0.449660,0.278444},
+  {-0.925116,-0.622006},
+  {1.810841,0.357436},
+  {-0.361036,-0.568890},
+  {-0.245604,-0.543745},
+  {-0.809004,-0.297720},
+  {0.673398,-1.349551},
+  {0.320146,0.122381},
+  {0.055778,0.645761},
+  {-1.114450,0.141513},
+  {0.191087,1.024756},
+  {-0.230242,0.131826},
+  {1.440529,-0.146838},
+  {-0.309778,-0.905495},
+  {0.038309,0.453297},
+  {-0.322784,0.721147},
+  {-0.358682,-0.408192},
+  {-0.387312,-1.581744},
+  {0.455011,0.089694},
+  {-0.435709,0.434022},
+  {1.121966,0.703677},
+  {-0.000289,0.898656},
+  {0.370298,0.569843},
+  {-0.759395,0.155326},
+  {0.264595,-0.758241},
+  {-0.717438,-1.284560},
+  {0.534397,0.044761},
+  {-0.387217,-0.850411},
+  {0.044635,-0.092650},
+  {-0.372661,-0.068370},
+  {0.066867,0.992163},
+  {0.309686,-0.088930},
+  {-0.551975,1.140835},
+  {0.282269,-0.265153},
+  {-0.385975,0.629002},
+  {-0.588541,0.936380},
+  {-0.450421,-0.312229},
+  {-0.584466,0.390126},
+  {-0.561504,0.846689},
+  {-0.327959,1.138398},
+  {0.772840,-1.154541},
+  {0.109965,0.119873},
+  {-1.041428,0.030014},
+  {-1.054290,-0.520300},
+  {-0.401694,-1.322928},
+  {0.339501,-1.053816},
+  {-1.483539,0.383590},
+  {0.179033,-0.005078},
+  {-0.449563,0.617536},
+  {0.159361,-0.300597},
+  {0.681503,0.425180},
+  {0.075334,-0.054530},
+  {1.127598,-0.722161},
+  {0.830144,-0.411552},
+  {0.130735,-0.537078},
+  {-0.318294,0.279468},
+  {1.329998,0.436047},
+  {0.628394,0.202456},
+  {0.452344,-1.322196},
+  {-1.328185,1.430783},
+  {-0.607721,-0.864380},
+  {0.504693,-0.747412},
+  {0.873797,0.066753},
+  {-1.716981,-1.433918},
+  {-1.009027,-0.760573},
+  {-0.113434,0.171071},
+  {-0.037380,0.247667},
+  {0.522725,-0.251274},
+  {0.372523,-0.578671},
+  {0.363876,-0.147056},
+  {0.646783,-0.450081},
+  {1.137476,0.323571},
+  {-0.780254,-0.368106},
+  {1.146234,0.162286},
+  {0.762737,0.417214},
+  {-1.238331,0.742666},
+  {-0.390029,-0.580793},
+  {0.171207,0.920070},
+  {0.371806,-0.258019},
+  {-1.675454,0.112764},
+  {0.314425,0.532884},
+  {-0.212717,0.521552},
+  {1.230658,0.602619},
+  {0.024240,1.086085},
+  {-0.753075,0.421991},
+  {1.184260,0.288993},
+  {-0.156075,-0.349412},
+  {0.070528,-0.556874},
+  {1.304863,0.059083},
+  {0.075264,0.205343},
+  {-0.115468,0.910225},
+  {-0.086719,-0.359175},
+  {0.580907,1.065438},
+  {0.059108,-1.456124},
+  {1.143980,-0.250649},
+  {-0.532360,0.202426},
+  {-1.306963,0.894754},
+  {-0.004374,0.331473},
+  {0.530959,1.017206},
+  {0.896061,-0.486310},
+  {0.124527,-0.835825},
+  {0.401800,-0.694786},
+  {0.131098,-0.507110},
+  {-0.493495,-1.031719},
+  {-0.380582,0.015232},
+  {-1.773868,0.203092},
+  {-0.243199,-0.939094},
+  {-0.243723,-1.167272},
+  {0.991581,0.396060},
+  {-0.559749,0.941881},
+  {0.942520,1.077600},
+  {-0.572208,0.399250},
+  {-1.198896,0.820616},
+  {-0.733767,0.042879},
+  {-1.020932,1.153919},
+  {-1.048099,0.943322},
+  {-0.354407,0.317066},
+  {0.308045,0.211141},
+  {0.831764,-1.378969},
+  {-0.007062,-0.513552},
+  {0.967642,0.641026},
+  {-0.668442,0.316706},
+  {-1.122864,-0.024464},
+  {0.316990,0.362859},
+  {-0.111627,0.744548},
+  {0.185230,-0.636517},
+  {1.227635,-0.165264},
+  {-0.506497,0.297073},
+  {-0.317230,-0.293662},
+  {0.344244,0.550272},
+  {0.086386,0.725618},
+  {-0.374595,0.121906},
+  {0.205497,1.783572},
+  {0.647253,-0.895754},
+  {0.162982,-0.022414},
+  {-0.994075,-1.237339},
+  {1.033565,-0.151604},
+  {-0.280396,0.878138},
+  {-0.264564,-0.165480},
+  {0.301752,0.255018},
+  {-0.615882,0.711428},
+  {0.300740,0.246028},
+  {1.845295,-0.214744},
+  {1.080206,-0.092894},
+  {0.015605,0.522865},
+  {1.172807,-0.447869},
+  {-0.821485,0.490399},
+  {-0.306496,0.230408},
+  {0.709987,-0.375342},
+  {-0.355816,0.453023},
+  {-0.212208,-0.678919},
+  {0.091036,-0.565006},
+  {0.116062,-0.416735},
+  {1.050847,0.339220},
+  {1.742643,-0.228713},
+  {-0.434887,-0.201646},
+  {-0.382463,-0.917137},
+  {-0.598962,0.979455},
+  {-0.678083,-0.074060},
+  {1.074554,0.667668},
+  {-0.175566,0.080397},
+  {-0.746242,-0.837080},
+  {0.569198,-0.288397},
+  {-0.419237,0.814960},
+  {1.110668,0.610994},
+  {1.024729,-0.522782},
+  {0.287071,0.129891},
+  {1.059693,0.192434},
+  {-0.500546,1.681387},
+  {-0.352649,0.693367},
+  {1.330871,0.878471},
+  {1.452162,1.296531},
+  {-0.561816,1.060767},
+  {-0.024246,0.549463},
+  {-0.558191,-0.475732},
+  {0.579874,-0.378951},
+  {-0.386188,0.616314},
+  {1.904212,-0.081406},
+  {0.056011,0.587343},
+  {2.079102,-0.449990},
+  {-0.585793,0.200955},
+  {-0.148105,-0.720863},
+  {-0.871106,1.178992},
+  {-0.259457,0.018706},
+  {-0.838352,-0.101366},
+  {1.104726,-0.165176},
+  {-0.376425,0.962019},
+  {-0.383321,-0.621639},
+  {0.185654,-0.673447},
+  {0.088111,0.910684},
+  {1.972742,1.066469},
+  {0.343070,1.425779},
+  {0.235284,-1.008437},
+  {-0.232498,-0.780531},
+  {-0.285426,0.387394},
+  {0.570176,0.601760},
+  {0.857470,0.042025},
+  {0.823288,0.485621},
+  {-0.161700,0.393089},
+  {0.653084,-0.695477},
+  {0.397400,1.144465},
+  {0.330464,1.209299},
+  {-0.905504,0.536976},
+  {0.462790,0.056269},
+  {0.181789,0.418193},
+  {-0.442622,-0.997435},
+  {-0.622074,-1.020432},
+  {0.174594,-0.272027},
+  {0.195162,0.424718},
+  {-0.483125,-0.014181},
+  {-0.333027,-0.666385},
+  {-0.225218,-1.387923},
+  {0.380830,-0.801521},
+  {0.500795,0.083064},
+  {-0.354031,0.562019},
+  {-0.322369,0.355784},
+  {-0.689934,1.420140},
+  {0.505533,0.590711},
+  {-0.258165,-0.519527},
+  {0.484829,0.168475},
+  {-0.887195,0.627565},
+  {-0.569851,0.255714},
+  {0.656937,1.030732},
+  {0.253163,1.183688},
+  {-0.090994,0.350419},
+  {-0.621855,0.522503},
+  {1.260944,-0.340844},
+  {-0.328843,1.339729},
+  {-0.187433,0.904883},
+  {-0.091476,1.344383},
+  {-0.398040,-0.259532},
+  {0.059961,-0.952296},
+  {-0.669200,-0.513899},
+  {0.882696,-0.883357},
+  {0.445337,0.858188},
+  {-0.376645,0.216174},
+  {0.251451,1.293422},
+  {-0.343713,0.459366},
+  {-0.790002,-1.400639},
+  {-0.281481,0.156530},
+  {-0.050578,-0.812539},
+  {-0.069669,-0.942398},
+  {0.206314,1.062811},
+  {-0.862538,0.079873},
+  {-0.142145,-0.179803},
+  {-0.635656,0.187704},
+  {-0.288690,-0.632587},
+  {0.489273,-1.319410},
+  {-0.113265,0.243749},
+  {-0.547880,0.138515},
+  {0.503130,-0.553393},
+  {-1.042138,1.207500},
+  {0.993756,1.771553},
+  {0.945115,0.708578},
+  {-0.755664,-0.227831},
+  {2.114421,0.144923},
+  {1.322935,0.007610},
+  {0.668800,0.872877},
+  {1.206511,1.284430},
+  {0.119083,1.037143},
+  {0.469420,-0.968104},
+  {0.178111,-0.706050},
+  {-0.093654,0.351570},
+  {1.216869,-0.083921},
+  {1.128239,-0.721634},
+  {-0.603763,-1.222727},
+  {-0.246507,0.765585},
+  {-0.469168,-0.154943},
+  {0.115194,-0.645646},
+  {-0.628875,-0.134190},
+  {-0.218869,1.072319},
+  {-0.304600,-0.845963},
+  {0.041486,0.312707},
+  {-0.824256,0.026274},
+  {-0.398291,0.206157},
+  {0.865547,0.384018},
+  {-0.518704,-0.244805},
+  {0.770365,-0.244413},
+  {-0.853040,1.803973},
+  {-0.112336,0.330401},
+  {0.389707,0.066202},
+  {-1.206726,-0.931216},
+  {0.890161,1.029948},
+  {0.224077,-0.218359},
+  {-0.835221,0.379948},
+  {-0.576608,0.010603},
+  {-0.046229,-0.651582},
+  {0.149031,-0.006860},
+  {-0.232445,-0.153048},
+  {-0.361445,-0.624316},
+  {-0.089316,-0.902206},
+  {-0.677576,0.291582},
+  {-0.694052,0.341786},
+  {0.604152,0.954109},
+  {-0.451568,-1.027999},
+  {0.888470,0.246610},
+  {1.378708,-0.162367},
+  {0.807884,-0.154657},
+  {-0.121010,0.723971},
+  {0.756675,-0.287967},
+  {-1.352302,0.460834},
+  {-0.539413,-0.417247},
+  {0.138693,0.716212},
+  {-1.262669,0.189740},
+  {-0.127893,0.098501},
+  {-2.031114,-0.515120},
+  {-0.566216,0.134760},
+  {-0.894512,-1.013835},
+  {0.545570,-0.785318},
+  {0.314537,-0.541041},
+  {-0.623232,-0.972520},
+  {-0.239815,-0.060572},
+  {-0.016385,0.088118},
+  {0.233685,0.536110},
+  {-0.701300,0.465990},
+  {0.772176,-0.169732},
+  {-0.111524,-0.101524},
+  {0.058288,1.465041},
+  {0.712798,-0.116610},
+  {0.667813,0.354510},
+  {-0.055343,-0.426603},
+  {0.923450,-0.343740},
+  {0.351264,-0.768122},
+  {-0.881422,0.152680},
+  {-0.929116,1.638255},
+  {0.167936,-0.278059},
+  {1.027618,0.529101},
+  {-0.777487,-0.773029},
+  {-0.171119,-0.587115},
+  {-0.630818,0.969008},
+  {0.561234,0.268168},
+  {0.106045,-0.638529},
+  {1.266788,-1.129971},
+  {-0.995631,-0.558621},
+  {0.188110,-0.702478},
+  {0.335395,-0.240620},
+  {-0.116215,0.260554},
+  {0.680446,-0.603189},
+  {0.904362,1.717741},
+  {-0.015833,0.746788},
+  {-0.148045,0.051645},
+  {0.009869,0.846651},
+  {0.298090,1.350605},
+  {1.345340,-1.423719},
+  {-0.754747,-1.335279},
+  {0.419094,-0.864441},
+  {-0.145479,-0.797688},
+  {0.135712,0.991836},
+  {0.225006,-0.060168},
+  {0.355427,0.550726},
+  {1.954229,0.656213},
+  {-0.169736,0.311985},
+  {0.939487,0.650424},
+  {0.789964,-0.684274},
+  {0.164532,0.093543},
+  {0.060515,0.106031},
+  {-0.024316,-0.913373},
+  {-0.582858,0.242192},
+  {-0.599441,0.706627},
+  {-0.037631,-0.529508},
+  {0.108102,0.029830},
+  {-0.766994,0.601282},
+  {-1.162212,-0.241856},
+  {-0.283526,1.599770},
+  {-1.549907,-0.505364},
+  {0.722774,0.073483},
+  {-1.024597,-0.392075},
+  {0.858099,-0.287027},
+  {0.327537,-1.007954},
+  {0.667032,-0.025028},
+  {0.975513,0.143732},
+  {0.018982,0.474133},
+  {-0.098149,1.106961},
+  {-0.108187,-0.707083},
+  {-0.219794,0.475886},
+  {0.210508,-0.510677},
+  {-0.416087,-0.900413},
+  {-0.752409,-0.392688},
+  {0.327123,-0.496539},
+  {-0.879819,-1.010528},
+  {-1.401704,-0.483436},
+  {-1.566675,-0.015039},
+  {-0.550926,-0.315944},
+  {-0.711913,-0.986015},
+  {0.408434,-0.200798},
+  {-0.921718,0.340502},
+  {-1.323506,-0.767555},
+  {0.762208,-0.010204},
+  {1.414222,-0.108579},
+  {-1.279120,-0.115126},
+  {-1.063315,-0.287798},
+  {-0.612699,0.708367},
+  {1.058841,-0.974767},
+  {-0.887090,0.515838},
+  {-0.169713,-0.586082},
+  {0.468957,-1.057315},
+  {-1.137185,-0.201351},
+  {0.857001,0.506281},
+  {-0.694478,1.116885},
+  {-0.101536,0.252581},
+  {-0.186678,0.121469},
+  {0.237319,1.220649},
+  {0.590731,0.106154},
+  {-0.307152,-0.195058},
+  {-0.534827,0.484876},
+  {1.112901,0.239961},
+  {0.050445,0.481539},
+  {0.545830,0.854745},
+  {-0.687006,-0.117939},
+  {0.167796,0.067286},
+  {-0.200961,-0.851043},
+  {-0.029250,-0.070030},
+  {0.571111,-0.402512},
+  {-0.291893,-0.486622},
+  {0.199427,-0.464909},
+  {0.485504,0.196643},
+  {-1.203786,1.305744},
+  {-0.457443,2.058590},
+  {-0.206683,-0.175040},
+  {0.166361,0.461590},
+  {-0.426843,-1.352936},
+  {0.501698,0.238129},
+  {-0.809285,-0.792133},
+  {-0.655155,0.336089},
+  {0.726113,-1.582158},
+  {-0.150580,0.179097},
+  {0.715039,-1.127365},
+  {-0.012255,-1.422302},
+  {-0.291115,-0.120922},
+  {0.109163,0.722364},
+  {0.653337,0.016132},
+  {0.459079,-0.773381},
+  {-1.171660,1.182249},
+  {-0.102436,0.837007},
+  {0.845445,0.528685},
+  {-0.409713,0.406902},
+  {0.830749,0.057450},
+  {0.671611,0.782030},
+  {0.200145,-1.167993},
+  {-0.205830,-0.256860},
+  {0.341035,0.280555},
+  {-1.201147,-0.323218},
+  {-0.212821,0.050460},
+  {0.742152,-0.323082},
+  {0.819270,0.195198},
+  {0.669024,0.897072},
+  {-0.501893,-0.365942},
+  {-1.308934,0.089249},
+  {-0.037597,-0.113499},
+  {-1.004372,0.368385},
+  {0.141077,-0.067610},
+  {0.275376,-0.743583},
+  {-0.191894,-1.129273},
+  {-1.258964,-0.039886},
+  {0.728804,-1.000285},
+  {1.086578,-0.617149},
+  {-0.855317,-0.310454},
+  {-0.147711,0.408143},
+  {-0.517206,0.043758},
+  {0.719426,-1.283598},
+  {-0.235939,0.668859},
+  {-0.380010,-0.313257},
+  {0.316778,-0.118759},
+  {-0.262927,-1.567183},
+  {-0.282733,0.420140},
+  {0.818925,-0.012589},
+  {0.357610,0.577911},
+  {-0.190272,-0.414123},
+  {0.625359,1.169565},
+  {-0.917634,0.809205},
+  {0.909000,-0.614465},
+  {-0.273865,0.307313},
+  {0.708742,1.146401},
+  {-0.736018,1.297624},
+  {-0.132588,-0.042389},
+  {0.752216,-0.630562},
+  {0.602787,-0.506396},
+  {0.633488,0.200361},
+  {0.862136,-0.559107},
+  {0.745865,-1.328896},
+  {-0.015377,-0.603058},
+  {0.012261,0.207465},
+  {-1.262966,0.309847},
+  {-0.816732,-0.048421},
+  {1.368862,-0.089376},
+  {-0.950272,-0.966439},
+  {0.201282,-0.088005},
+  {-0.675286,0.791768},
+  {0.857350,-0.330363},
+  {0.297582,-0.494692},
+  {-0.536755,0.002392},
+  {-0.209953,0.732953},
+  {-0.443116,-0.086068},
+  {-1.175001,0.573199},
+  {-0.515406,0.620601},
+  {0.519220,0.365639},
+  {0.179975,-0.360670},
+  {-0.307683,0.106896},
+  {0.132153,0.727465},
+  {-0.280980,-0.228803},
+  {0.239138,-0.878369},
+  {-0.037641,0.340422},
+  {0.908774,-1.101317},
+  {0.049850,-0.299075},
+  {0.019113,0.674994},
+  {-0.015975,0.379414},
+  {0.288954,-0.809359},
+  {0.347018,-1.157598},
+  {0.074732,-0.537650},
+  {0.996135,-0.001765},
+  {0.056827,-0.488387},
+  {-0.833093,0.386931},
+  {0.758476,0.872903},
+  {-0.745092,-0.444934},
+  {-0.224247,-0.116532},
+  {-0.204749,0.261726},
+  {0.404937,0.616612},
+  {0.339130,0.532116},
+  {0.321454,-0.851996},
+  {0.318065,0.804013},
+  {0.255111,-0.303607},
+  {0.430730,0.409011},
+  {0.336340,-0.608268},
+  {0.689794,0.099887},
+  {0.120092,0.052738},
+  {-0.588516,-0.366448},
+  {0.325651,-0.658579},
+  {0.947989,-0.734417},
+  {0.016734,-0.728917},
+  {-0.841605,0.381322},
+  {0.231804,0.206317},
+  {1.051284,-0.490680},
+  {-0.050906,-0.211480},
+  {-0.105047,0.477795},
+  {-0.252414,-0.626855},
+  {-0.057217,-0.134807},
+  {1.067822,-0.178322},
+  {-0.086659,-1.147155},
+  {-0.741801,0.582173},
+  {0.803925,-1.119881},
+  {0.543473,0.197205},
+  {0.407991,-0.434675},
+  {0.107264,-0.319198},
+  {1.091457,0.760169},
+  {-0.013718,0.000686},
+  {-1.248275,0.208178},
+  {-0.899392,0.261502},
+  {-0.631148,-0.302873},
+  {0.083128,0.705050},
+  {-0.778608,-0.788078},
+  {1.135346,-0.872922},
+  {-1.157340,-0.867567},
+  {-0.593543,-2.187029},
+  {0.093469,0.234575},
+  {0.443437,-0.304265},
+  {1.551142,-1.422596},
+  {0.442576,-1.577903},
+  {0.192425,0.160683},
+  {-0.902680,-0.431437},
+  {-1.004525,-0.745898},
+  {-0.483396,-0.192180},
+  {1.080987,-0.266741},
+  {-0.903296,1.170854},
+  {-0.364402,0.684777},
+  {0.309202,-0.017096},
+  {-0.492831,-0.600043},
+  {-1.612991,-0.804477},
+  {-0.407146,-0.758813},
+  {0.829137,-0.603992},
+  {-0.251557,-0.383196},
+  {-0.743938,0.109216},
+  {1.011679,-0.340907},
+  {0.241315,0.068707},
+  {-1.006463,0.402521},
+  {0.031220,-0.028792},
+  {-0.417251,-1.398311},
+  {0.775474,0.111723},
+  {-1.223098,-0.658243},
+  {2.340365,-0.265007},
+  {0.301015,-0.206530},
+  {-0.200633,-0.557171},
+  {-0.202832,0.319060},
+  {-0.010049,0.742861},
+  {0.106082,0.811121},
+  {0.055592,-0.191956},
+  {0.355395,0.583195},
+  {0.282830,-0.170406},
+  {0.025638,1.918779},
+  {0.944669,-0.058716},
+  {1.264998,1.490664},
+  {0.823037,0.092036},
+  {1.217579,-0.491040},
+  {0.037653,-0.782702},
+  {0.149131,-0.656208},
+  {0.410757,1.584757},
+  {1.325665,0.028426},
+  {0.971514,-0.170968},
+  {0.142927,-0.349601},
+  {-0.675615,1.239243},
+  {1.118417,0.482521},
+  {-0.525994,0.493175},
+  {-1.053111,-0.390079},
+  {0.030564,0.067288},
+  {-0.074059,-0.899509},
+  {-0.360663,0.382902},
+  {0.550419,0.853873},
+  {-0.544569,-0.824151},
+  {0.568337,0.130398},
+  {-0.604970,0.925242},
+  {0.220753,-0.254279},
+  {0.337711,0.557667},
+  {-0.753422,-0.586669},
+  {0.428708,-0.232984},
+  {1.794279,0.483338},
+  {1.304773,-0.365589},
+  {-0.433436,-0.791504},
+  {-0.214934,0.966716},
+  {-0.305057,0.580224},
+  {-0.106751,-0.822595},
+  {1.028315,-0.877748},
+  {0.852443,-0.409121},
+  {0.625301,0.180248},
+  {1.396398,0.143160},
+  {1.108587,0.541150},
+  {0.468621,-1.043421},
+  {0.906804,0.715312},
+  {-0.766680,0.905431},
+  {-0.441257,0.668639},
+  {0.284121,-0.043281},
+  {-0.616953,0.794195},
+  {0.163532,-0.395955},
+  {-0.412360,-0.597153},
+  {0.241518,-0.585513},
+  {0.482960,0.567925},
+  {-1.054434,-0.649045},
+  {0.605650,-0.378689},
+  {-0.609803,0.359699},
+  {1.365516,0.646388},
+  {-0.344219,0.120575},
+  {-0.654285,-0.631225},
+  {0.468870,0.618246},
+  {-0.390055,0.556382},
+  {-0.508965,0.454676},
+  {0.116800,0.138547},
+  {-1.168829,-0.304091},
+  {-0.385664,-0.659049},
+  {-0.639212,-1.396839},
+  {1.224527,1.061921},
+  {-0.712606,-0.081001},
+  {0.120125,-0.300214},
+  {0.179791,-0.636082},
+  {-0.605018,-0.693630},
+  {-0.678318,-0.318564},
+  {-0.598472,-0.031708},
+  {-0.520574,-0.296742},
+  {0.067744,-0.796947},
+  {0.696445,0.463145},
+  {0.094760,-0.023756},
+  {-1.028425,1.287291},
+  {-0.669956,0.116063},
+  {-0.209304,0.099915},
+  {-1.108453,-0.002002},
+  {-0.060206,-0.515472},
+  {0.981295,0.380674},
+  {0.263531,-0.667106},
+  {0.250979,0.072504},
+  {-0.096590,0.766292},
+  {0.920231,-0.755035},
+  {-0.505097,-1.091862},
+  {-0.615787,0.117510},
+  {0.368374,0.389098},
+  {-0.126383,-0.430203},
+  {0.164085,-0.529933},
+  {0.599555,-0.034148},
+  {1.102519,-0.438562},
+  {0.085070,-0.251993},
+  {0.865140,0.585431},
+  {0.934833,-1.057558},
+  {0.249809,-0.620187},
+  {0.265592,1.080486},
+  {-0.634548,-0.038819},
+  {-0.150059,0.264938},
+  {0.250318,1.521858},
+  {-0.173384,-0.223300},
+  {0.129138,0.492724},
+  {1.592594,0.165069},
+  {-0.331133,1.012240},
+  {-0.697260,-0.195315},
+  {-0.312506,-1.024730},
+  {-0.234223,-0.824909},
+  {-0.383885,0.106128},
+  {-0.175865,0.392687},
+  {-0.510849,-0.462690},
+  {-1.018937,1.151529},
+  {-0.038301,-0.066566},
+  {0.530731,0.127405},
+  {-0.208679,-0.107666},
+  {0.120497,1.016165},
+  {-0.052440,0.725401},
+  {1.832884,-0.342007},
+  {0.092143,0.258115},
+  {-1.159934,-0.970688},
+  {0.589430,-0.586012},
+  {1.209632,1.986167},
+  {-0.366520,0.055513},
+  {0.384307,0.775611},
+  {-0.877936,-2.193519},
+  {-0.003713,1.002400},
+  {-1.173911,0.755036},
+  {-0.477599,0.075858},
+  {0.388147,0.137404},
+  {-0.270243,-0.165515},
+  {-0.260462,1.171696},
+  {-0.150456,-0.885312},
+  {0.469399,-0.599552},
+  {-0.597813,-0.750128},
+  {0.095583,-0.274177},
+  {-0.509728,1.587391},
+  {0.972749,0.614814},
+  {-0.752960,-0.189362},
+  {1.062092,-0.210413},
+  {-0.114508,0.325050},
+  {1.881627,0.271021},
+  {-1.128107,-0.567826},
+  {0.014185,-0.695967},
+  {0.338390,0.827812},
+  {-0.274898,0.464329},
+  {0.550296,0.200794},
+  {-0.197346,-1.187593},
+  {-0.155908,-0.802583},
+  {-0.207092,-0.070371},
+  {-0.486399,-1.113643},
+  {-0.129494,-0.242884},
+  {0.631126,0.237594},
+  {0.772150,-1.293381},
+  {-0.148225,1.069063},
+  {-0.557726,0.180037},
+  {-0.251261,0.420506},
+  {-0.687525,-1.530252},
+  {0.308271,-0.038557},
+  {-1.212547,0.035603},
+  {-0.060400,-0.303898},
+  {1.425639,-0.355048},
+  {0.144429,0.420649},
+  {-0.688609,-0.997562},
+  {0.259183,-0.891376},
+  {0.275503,-0.114022},
+  {-1.060990,-0.859264},
+  {-1.590535,-0.179986},
+  {-0.197122,-0.339152},
+  {-1.741402,-1.241081},
+  {-0.101596,-0.103421},
+  {-0.576440,-0.998940},
+  {-0.159847,-0.078504},
+  {-0.598367,-0.701100},
+  {0.454856,0.507896},
+  {-1.739180,-0.913037},
+  {1.341986,0.134193},
+  {-0.290217,-0.535215},
+  {0.783955,-0.574633},
+  {-0.126710,-1.241383},
+  {-1.693904,-0.209030},
+  {0.500406,0.058675},
+  {0.876139,-0.205673},
+  {0.347464,1.353533},
+  {-0.250533,-0.590198},
+  {-0.049717,0.984800},
+  {-1.667565,-0.013165},
+  {0.328547,0.584034},
+  {-0.578874,-0.321222},
+  {0.607281,-0.663825},
+  {-0.042807,-0.635103},
+  {-0.198325,-0.054844},
+  {-0.567400,-1.007322},
+  {0.181597,-0.281650},
+  {0.922825,0.237707},
+  {-0.725941,0.008540},
+  {0.146820,0.712341},
+  {-2.004479,0.919673},
+  {-0.437029,-0.158475},
+  {0.009848,0.194884},
+  {0.064501,0.515108},
+  {0.966986,-0.106012},
+  {0.431525,-0.640987},
+  {0.226213,0.704404},
+  {-0.389554,0.297250},
+  {0.227194,-0.123749},
+  {0.958163,0.684737},
+  {-0.763641,-1.299124},
+  {-0.519729,1.144937},
+  {0.517323,0.380140},
+  {0.358759,-0.376012},
+  {0.485276,-1.189659},
+  {-1.128039,0.154856},
+  {0.012640,-0.800780},
+  {-1.023062,0.541789},
+  {-0.088985,1.220985},
+  {-0.274541,0.330453},
+  {-0.223176,0.277022},
+  {-1.250833,0.859561},
+  {0.166349,-1.059528},
+  {0.706370,1.301363},
+  {0.865846,-0.966971},
+  {-0.746104,-0.181980},
+  {-0.382071,-0.287606},
+  {-0.696105,0.935651},
+  {-0.754779,-0.608633},
+  {1.558518,-0.068025},
+  {-0.730162,-1.159437},
+  {-1.243312,-0.025267},
+  {0.538259,-0.151188},
+  {0.755668,0.731049},
+  {0.362774,-1.112199},
+  {0.951361,-0.710292},
+  {1.205493,0.703087},
+  {-0.384461,-0.900938},
+  {0.558954,0.738985},
+  {0.534887,-0.264438},
+  {0.451519,-0.094902},
+  {0.271715,-0.849368},
+  {-0.622068,-0.879637},
+  {0.747059,0.748628},
+  {-0.141696,-0.554025},
+  {-0.162613,-0.058699},
+  {-0.438999,-0.305623},
+  {-0.974950,-0.030913},
+  {-0.836826,-1.211227},
+  {0.066026,-0.500706},
+  {0.317875,0.639406},
+  {1.768633,-1.108933},
+  {-0.169267,-0.005666},
+  {0.308455,0.547168},
+  {-0.792556,-0.067929},
+  {-1.053188,-0.742882},
+  {-0.439344,1.796462},
+  {0.928509,-1.153488},
+  {-0.883353,0.292079},
+  {1.150053,-0.757907},
+  {0.159497,0.386146},
+  {-0.575171,0.435701},
+  {-0.104603,-0.597094},
+  {-0.010359,-0.762375},
+  {0.533096,-0.049087},
+  {-0.622529,-0.504482},
+  {-0.649558,-0.521691},
+  {1.604563,-0.953022},
+  {0.483842,0.422572},
+  {0.604771,0.258910},
+  {-0.420070,0.075085},
+  {-0.670900,-0.537843},
+  {-0.643097,-0.750436},
+  {2.158761,-0.134695},
+  {-0.699376,1.792557},
+  {0.316584,0.159085},
+  {-1.290301,0.659405},
+  {-0.470062,0.491114},
+  {-0.217911,0.097260},
+  {-0.883950,0.411357},
+  {-1.137233,-0.417558},
+  {-0.060187,0.823960},
+  {-0.527339,0.909397},
+  {0.614027,-0.516774},
+  {0.326730,-0.720490},
+  {-0.732945,1.140511},
+  {0.527214,-0.857791},
+  {0.354728,0.527356},
+  {-1.042879,-0.843408},
+  {0.388951,-0.250227},
+  {-0.760452,-0.272504},
+  {0.670556,1.780283},
+  {0.178493,-0.103607},
+  {0.281239,0.573283},
+  {-0.276774,-0.666889},
+  {-0.369088,-0.515050},
+  {-1.566099,-0.292304},
+  {0.241018,0.111041},
+  {-0.579810,-0.131634},
+  {0.614676,-1.020588},
+  {2.122965,-0.652456},
+  {1.003513,-0.009904},
+  {0.384063,-0.315227},
+  {1.662325,-1.228987},
+  {0.421827,-0.875429},
+  {0.615807,-1.046427},
+  {-0.369778,0.103087},
+  {-1.400076,-1.351331},
+  {0.243226,0.565874},
+  {-0.190009,-1.569295},
+  {0.431636,-0.614997},
+  {0.640676,-0.202974},
+  {0.723470,0.490124},
+  {0.178854,0.920912},
+  {0.291047,0.310138},
+  {1.437523,-0.613064},
+  {0.311316,1.098868},
+  {0.064226,0.222299},
+  {0.635425,0.681261},
+  {-2.079335,-0.027042},
+  {-1.620853,-0.434969},
+  {-0.771540,-0.951936},
+  {0.075813,-0.359065},
+  {-0.196248,0.026575},
+  {0.549859,-0.479033},
+  {0.779249,-0.479395},
+  {0.489763,0.682128},
+  {0.779679,0.447111},
+  {0.248959,-0.926465},
+  {-0.978864,-0.625647},
+  {0.487766,-0.729178},
+  {0.488021,-0.395398},
+  {-1.132487,-0.266249},
+  {-0.946289,-0.121230},
+  {-0.043873,-0.494146},
+  {-1.797368,-0.163129},
+  {0.604546,0.840547},
+  {-0.100001,0.205591},
+  {-0.704900,-0.745045},
+  {0.141108,-0.367080},
+  {0.714093,0.338304},
+  {-0.211548,0.288865},
+  {-0.139203,1.696446},
+  {0.398683,-0.856051},
+  {-1.399684,1.056120},
+  {-0.172748,-0.560887},
+  {-0.742047,-1.011942},
+  {0.435281,-1.466353},
+  {0.372200,0.312796},
+  {-0.470258,0.052912},
+  {-0.720672,-0.015639},
+  {0.525673,0.064041},
+  {0.322946,0.778343},
+  {-0.715545,0.200291},
+  {-0.638279,-0.376644},
+  {0.318214,1.262688},
+  {0.518733,-0.228811},
+  {-0.587650,-1.462563},
+  {0.669318,-0.231777},
+  {0.771174,0.304270},
+  {-0.186317,1.664676},
+  {0.111617,-1.626430},
+  {-0.574343,1.310556},
+  {1.093523,1.010366},
+  {-0.051229,0.373412},
+  {-1.055527,-0.123199},
+  {1.258413,-0.434222},
+  {0.204129,0.827730},
+  {-0.609029,0.323469},
+  {1.834988,0.769506},
+  {-0.473224,0.009616},
+  {-0.936846,-1.464676},
+  {0.419282,0.867511},
+  {0.691505,-0.431348},
+  {0.462740,-0.806883},
+  {-0.077804,0.056353},
+  {0.201756,0.460018},
+  {-0.101533,-0.186722},
+  {-0.683106,-0.812029},
+  {0.393013,0.220783},
+  {0.960070,0.016689},
+  {-0.818561,0.072895},
+  {-0.304093,0.221132},
+  {0.432887,0.613225},
+  {0.799350,1.722360},
+  {-1.201054,0.101461},
+  {-0.284951,-0.099726},
+  {-0.284407,1.019124},
+  {1.161096,-1.015084},
+  {0.470649,0.547416},
+  {0.910485,-0.148244},
+  {0.903437,-0.639555},
+  {0.414630,-0.744832},
+  {-0.807047,0.328593},
+  {0.546277,0.129403},
+  {0.979881,1.317070},
+  {0.815188,-1.157551},
+  {0.652102,0.325572},
+  {0.986148,-0.443291},
+  {0.321192,-0.168401},
+  {-0.095464,0.134572},
+  {-0.644626,-0.367752},
+  {1.186512,1.426639},
+  {-1.268228,-1.212135},
+  {0.329307,-0.048942},
+  {-0.453068,0.181014},
+  {-0.120221,1.319718},
+  {0.203761,1.057543},
+  {0.323603,-0.370886},
+  {1.278257,0.506360},
+  {-0.137128,-0.217014},
+  {-0.123980,-0.196150},
+  {0.969988,0.131635},
+  {1.034595,0.043616},
+  {0.051072,-0.038913},
+  {0.475718,0.545762},
+  {0.860966,-0.183492},
+  {1.509751,0.139050},
+  {0.183777,0.478787},
+  {0.452950,0.262511},
+  {1.193602,-0.473727},
+  {1.279293,1.055423},
+  {0.496909,0.719865},
+  {1.540333,-0.346943},
+  {-0.293427,-0.718329},
+  {0.304463,1.034630},
+  {0.081471,-1.789542},
+  {-0.654413,0.275167},
+  {-0.234365,0.326354},
+  {-1.026665,0.836313},
+  {1.740778,-0.446498},
+  {1.571499,0.008159},
+  {-1.551162,0.190736},
+  {0.766180,-1.958868},
+  {-0.246677,0.141081},
+  {-1.245445,-1.767784},
+  {0.338713,-0.398232},
+  {-0.167049,0.337391},
+  {1.670908,-0.878596},
+  {-0.346210,0.066791},
+  {-0.167848,-0.262351},
+  {-0.838038,-0.908504},
+  {0.665549,-0.241012},
+  {0.507867,-1.133164},
+  {0.083940,-0.788292},
+  {0.689884,0.002313},
+  {0.188896,0.230707},
+  {-0.395535,0.585358},
+  {0.759700,0.630998},
+  {0.406334,0.692208},
+  {-0.523691,0.244080},
+  {-0.358877,-0.192886},
+  {0.658757,-1.197811},
+  {0.276591,-0.550659},
+  {1.042222,-0.377038},
+  {-0.519696,0.588037},
+  {0.042507,0.893983},
+  {-1.038433,-0.388424},
+  {0.229740,0.097563},
+  {0.050357,0.853214},
+  {1.178250,0.666711},
+  {1.119683,0.327372},
+  {0.299392,0.581337},
+  {-0.726023,0.958577},
+  {-2.087364,-0.040116},
+  {-0.733430,-0.365305},
+  {-0.183230,0.747083},
+  {0.195544,-0.669629},
+  {0.096009,0.081064},
+  {-0.158337,0.140540},
+  {-0.141282,1.098426},
+  {-0.200366,-0.260091},
+  {0.179909,0.324990},
+  {-0.177505,0.710188},
+  {0.418389,0.656253},
+  {0.201164,-0.480767},
+  {-0.663206,-0.632061},
+  {0.866354,0.298333},
+  {0.580605,-0.186255},
+  {1.573994,-0.905037},
+  {-0.331628,-0.857198},
+  {0.740416,0.061667},
+  {-0.564123,-0.882095},
+  {-0.015107,0.034831},
+  {0.843711,0.918154},
+  {-1.214840,0.950409},
+  {-0.362231,0.026602},
+  {-0.345554,0.438305},
+  {-0.413601,0.471900},
+  {-1.395099,-1.305808},
+  {-0.405840,-0.326921},
+  {0.411408,-0.368048},
+  {0.883666,-0.358755},
+  {-0.035198,0.003136},
+  {0.954488,-0.213214},
+  {0.332939,0.172640},
+  {0.959216,0.688263},
+  {0.018761,2.039100},
+  {2.100315,0.051013},
+  {-0.271325,-0.485585},
+  {0.510974,-0.232181},
+  {-0.510400,-0.715401},
+  {0.026534,-0.521681},
+  {0.089140,0.147550},
+  {-0.756320,0.829660},
+  {-0.500559,0.266032},
+  {-0.082253,0.526760},
+  {-0.317537,1.100217},
+  {0.537659,0.004379},
+  {-0.511521,-0.070164},
+  {-0.950504,0.979454},
+  {-0.434086,-0.894423},
+  {-0.161771,0.383922},
+  {0.169965,0.443431},
+  {1.126951,0.313781},
+  {-0.083320,0.064187},
+  {1.105827,0.058595},
+  {1.599304,1.457213},
+  {0.097539,-0.136787},
+  {0.050654,0.763772},
+  {-0.815735,0.069732},
+  {0.712392,0.340298},
+  {-0.349751,1.663162},
+  {-0.520406,0.437961},
+  {-0.182619,-1.106802},
+  {1.249108,0.082180},
+  {-1.228325,-0.360564},
+  {-1.231868,-0.419608},
+  {-0.294485,0.226044},
+  {-0.060826,0.702817},
+  {-1.200765,0.467426},
+  {-0.116198,0.278628},
+  {1.214728,0.324470},
+  {0.225038,0.563450},
+  {-0.007607,-0.256299},
+  {-1.010766,-0.953903},
+  {-0.277060,0.812392},
+  {0.707381,0.168940},
+  {-0.918905,0.693847},
+  {0.282631,-0.353127},
+  {0.225166,1.501837},
+  {-0.954247,-0.586650},
+  {0.318076,-0.497355},
+  {-0.418723,0.065298},
+  {0.084946,0.228400},
+  {0.307594,0.474237},
+  {-0.107772,-0.421675},
+  {-0.232476,0.576236},
+  {0.586626,-0.859792},
+  {0.283680,-1.605937},
+  {0.065020,0.212051},
+  {-0.474997,-0.555701},
+  {0.353018,0.138387},
+  {-1.107164,0.434415},
+  {0.138023,1.048943},
+  {0.390060,-0.475007},
+  {0.216655,-1.005081},
+  {-0.421095,0.760430},
+  {0.827316,0.631502},
+  {-0.349654,0.360977},
+  {0.492383,1.430285},
+  {-1.500687,0.296066},
+  {-0.380852,-0.291811},
+  {-0.484800,-0.267565},
+  {-0.346712,0.186646},
+  {-0.083542,0.405885},
+  {-0.188996,1.142481},
+  {1.320101,0.391448},
+  {-0.146608,0.368600},
+  {-1.163383,0.327332},
+  {0.298202,-0.377332},
+  {-0.805110,0.443164},
+  {-0.871706,0.069784},
+  {0.373116,-0.326406},
+  {-0.607307,0.912847},
+  {-0.607633,-0.101585},
+  {1.970281,1.321946},
+  {-0.148369,0.105401},
+  {-0.282688,0.816048},
+  {1.025746,0.483259},
+  {-0.713131,0.610143},
+  {0.300423,-0.665059},
+  {-0.374302,0.666611},
+  {-0.869616,0.119894},
+  {1.018758,-0.715852},
+  {-0.928172,-1.549172},
+  {0.085113,0.833680},
+  {1.108642,0.496890},
+  {-1.549615,-1.217051},
+  {0.266179,-0.905077},
+  {-0.215376,0.513998},
+  {1.069599,0.120225},
+  {-0.307138,-0.329984},
+  {-0.571582,-0.130708},
+  {2.142098,-1.288388},
+  {-0.420347,1.053044},
+  {0.495939,-0.195319},
+  {0.502492,0.785095},
+  {0.766173,0.428730},
+  {-0.099107,-0.093918},
+  {0.729183,-0.195718},
+  {0.426967,0.415027},
+  {-0.895545,0.886429},
+  {-0.968602,-1.162273},
+  {0.416021,-0.046332},
+  {-1.219170,0.166351},
+  {0.586550,-0.244157},
+  {0.838475,-0.615897},
+  {-0.672975,-0.618807},
+  {-0.360221,-0.009750},
+  {-0.674237,-0.787390},
+  {0.760231,-0.187308},
+  {-0.812272,-0.645441},
+  {0.790059,-0.221013},
+  {-0.232809,-1.981273},
+  {1.111118,0.087870},
+  {0.404225,-1.245472},
+  {0.461102,0.105999},
+  {0.013247,1.296239},
+  {-0.108755,0.536528},
+  {-1.449621,0.250056},
+  {-0.195004,-1.416802},
+  {0.037800,-0.364457},
+  {0.552454,-0.675048},
+  {-0.065913,0.268582},
+  {-0.831306,-0.075565},
+  {0.515745,-0.533599},
+  {-1.138916,-1.364227},
+  {-0.070245,-0.567231},
+  {0.128759,0.526600},
+  {0.665589,0.326906},
+  {-0.224787,0.432314},
+  {-0.228078,-0.843603},
+  {-0.031752,-0.495566},
+  {0.022634,-0.591376},
+  {-0.700905,1.335250},
+  {-0.661231,0.287638},
+  {0.023830,-0.433696},
+  {-1.666931,-1.034963},
+  {0.531734,-0.239730},
+  {-0.827702,-1.580614},
+  {-0.751258,0.940162},
+  {-0.287944,-0.191240},
+  {-0.907179,-0.244279},
+  {0.709229,-0.938878},
+  {0.900749,0.288377},
+  {-0.676512,1.189215},
+  {0.514203,0.472178},
+  {0.721634,-0.583054},
+  {1.061447,0.267226},
+  {-1.211157,0.301310},
+  {-0.167337,-0.373970},
+  {0.028457,0.985726},
+  {0.110579,-0.098623},
+  {-0.172895,-0.801720},
+  {1.208278,0.474267},
+  {-0.384456,-1.699807},
+  {-0.218454,-0.500844},
+  {-0.106211,0.296750},
+  {-1.006444,-0.168547},
+  {0.382713,-0.009482},
+  {0.331157,-0.878432},
+  {0.031083,-0.458680},
+  {-0.365436,-0.454964},
+  {-0.398935,-0.993382},
+  {-0.769671,0.501222},
+  {-0.051267,-0.864739},
+  {1.167413,0.251483},
+  {-0.638681,-0.123305},
+  {-0.903249,-1.315449},
+  {1.127817,0.729152},
+  {-1.489803,-0.197712},
+  {0.258543,-0.400706},
+  {-0.067041,-0.250410},
+  {1.170671,0.585027},
+  {-1.025814,-0.952182},
+  {0.191594,-0.695594},
+  {1.088652,0.211765},
+  {-0.672739,0.157990},
+  {0.594503,-0.652204},
+  {0.621315,-1.149470},
+  {-1.002667,-0.051699},
+  {-0.548659,0.070243},
+  {-0.256829,-0.297262},
+  {0.978255,0.627959},
+  {0.645651,0.839562},
+  {0.851345,-0.772047},
+  {0.605615,-1.084795},
+  {-1.066617,0.157309},
+  {-0.431485,-0.334219},
+  {-0.065427,-1.128954},
+  {-0.568002,-1.040160},
+  {0.572203,-0.754751},
+  {0.659738,-0.070165},
+  {-0.381698,-0.328700},
+  {-1.564251,0.477004},
+  {0.088705,-1.206888},
+  {0.054398,1.727333},
+  {-0.225188,-0.242253},
+  {0.166157,-0.688561},
+  {-0.949477,0.963288},
+  {0.412511,0.460764},
+  {-0.156152,-0.188229},
+  {1.155036,0.424556},
+  {-0.490640,-0.278005},
+  {-0.412096,0.287758},
+  {1.863923,-0.062265},
+  {-0.222627,0.474599},
+  {1.395178,0.343841},
+  {-0.147666,-1.077881},
+  {-1.174875,0.087301},
+  {0.690832,0.894002},
+  {0.207429,-0.821849},
+  {1.005274,1.609804},
+  {0.371987,-0.429320},
+  {-0.514226,-0.590668},
+  {-0.026782,0.397409},
+  {1.015714,0.810520},
+  {0.927649,0.649634},
+  {0.776910,-0.296798},
+  {0.976134,0.656214},
+  {0.003040,-0.262665},
+  {0.315733,1.042726},
+  {-0.596531,0.246790},
+  {-0.402001,0.608359},
+  {0.581907,0.501635},
+  {1.279527,0.729790},
+  {0.490545,0.881851},
+  {1.094798,-1.607173},
+  {0.965914,0.484647},
+  {-0.960222,0.649783},
+  {0.364875,-0.219241},
+  {-0.077840,-0.737867},
+  {0.774998,0.247243},
+  {-0.119677,-0.232309},
+  {-0.570180,-0.118825},
+  {0.977602,1.283441},
+  {0.831912,-0.804168},
+  {-0.196479,-0.062512},
+  {0.656737,0.855329},
+  {0.528258,-0.285970},
+  {-2.250344,0.084504},
+  {0.546068,0.570570},
+  {-0.858377,-0.909879},
+  {-1.108219,0.488554},
+  {-0.490006,-0.454847},
+  {0.049783,-0.432571},
+  {0.144726,1.065848},
+  {-1.394773,0.611523},
+  {0.082976,0.531777},
+  {0.285337,-0.535880},
+  {0.308235,-0.704091},
+  {-0.234517,0.379574},
+  {-0.039539,0.828459},
+  {0.357857,-0.609556},
+  {0.753604,-1.306881},
+  {0.790172,0.034169},
+  {0.056248,-0.121251},
+  {0.186954,0.648174},
+  {-0.995005,0.274405},
+  {-1.001077,0.860050},
+  {-0.057085,1.511382},
+  {-1.206087,0.878339},
+  {0.137995,1.844478},
+  {-1.493125,-0.998766},
+  {0.745860,-0.643919},
+  {-2.238097,1.200986},
+  {-1.456539,0.719147},
+  {0.950348,0.805055},
+  {-0.011920,1.722326},
+  {1.586502,-0.601509},
+  {-0.761579,-0.427211},
+  {-0.442142,0.336680},
+  {0.366955,-0.402493},
+  {0.706776,1.396136},
+  {-0.456781,0.836723},
+  {1.000545,-0.568838},
+  {0.385663,0.662292},
+  {0.477626,0.829285},
+  {-0.458256,-1.032467},
+  {-0.359687,-0.822045},
+  {-0.684604,0.498532},
+  {-1.225389,0.177601},
+  {0.432596,0.406977},
+  {-0.151285,0.179645},
+  {1.147279,-1.685706},
+  {0.525030,0.020319},
+  {-0.118010,-0.066492},
+  {-0.080738,0.414352},
+  {0.066255,0.637437},
+  {0.213317,-0.937024},
+  {0.349175,-0.783824},
+  {-0.536209,0.153490},
+  {-0.439903,-0.158521},
+  {0.270046,0.415777},
+  {0.680110,-0.429989},
+  {0.868958,-0.394753},
+  {-0.327469,-0.604439},
+  {0.018249,0.086110},
+  {0.863033,-0.847249},
+  {0.819329,0.546402},
+  {1.547121,-0.605341},
+  {-0.742487,0.218372},
+  {-0.531181,-0.785213},
+  {-0.414961,-1.837414},
+  {-0.697729,-0.105849},
+  {0.562781,1.161757},
+  {-0.252197,0.174986},
+  {1.019893,-1.022593},
+  {1.147283,-0.216186},
+  {-0.192484,0.544878},
+  {-0.288308,-1.126081},
+  {-0.653159,1.145602},
+  {0.356144,-0.300500},
+  {-1.877840,-0.660298},
+  {-0.888508,0.081546},
+  {0.095668,-0.650209},
+  {-0.996078,-0.377501},
+  {-0.936371,-1.051814},
+  {0.735572,0.371096},
+  {0.667417,0.241111},
+  {-1.166763,-0.795707},
+  {-0.604337,-0.214551},
+  {0.366715,-0.220244},
+  {0.135127,-1.369202},
+  {-1.280505,0.349096},
+  {1.611228,0.383331},
+  {0.010946,-0.325781},
+  {0.156384,1.852116},
+  {-0.937935,0.398887},
+  {-0.149062,0.073763},
+  {2.104644,1.227660},
+  {-0.626178,-0.143603},
+  {0.148232,0.324548},
+  {0.172888,-0.311778},
+  {-1.220482,-0.578080},
+  {-0.817595,1.215959},
+  {-0.071187,-0.946781},
+  {-0.316114,-0.621434},
+  {0.612704,-0.753227},
+  {0.053054,-0.899090},
+  {-0.548320,-0.228200},
+  {0.163999,0.796821},
+  {-0.245404,0.209061},
+  {0.441967,1.234234},
+  {-0.551563,0.044447},
+  {0.658026,0.187557},
+  {0.127459,-0.986518},
+  {-1.929082,-1.281298},
+  {-0.281742,-0.218021},
+  {-0.024907,0.738612},
+  {-0.576868,0.213936},
+  {1.047293,1.199670},
+  {-0.588133,0.536676},
+  {-0.873318,-0.257263},
+  {-0.173412,-0.363335},
+  {-0.711159,-1.458770},
+  {-0.627417,-0.146663},
+  {0.734973,0.087137},
+  {1.617436,-0.176356},
+  {-0.695416,0.009464},
+  {0.641452,0.164848},
+  {-0.365163,-0.298145},
+  {-0.040627,-0.594555},
+  {-1.136559,0.782394},
+  {0.889175,1.501206},
+  {-0.505251,-0.965412},
+  {-0.235839,0.215222},
+  {-0.031725,0.742335},
+  {0.298775,-0.150465},
+  {-0.849287,0.112957},
+  {1.179378,0.099546},
+  {0.512879,0.770936},
+  {-1.199297,-0.033108},
+  {-0.539796,0.936294},
+  {-0.205207,-1.051996},
+  {-0.131672,0.924508},
+  {-0.089858,0.043459},
+  {-0.523057,0.636311},
+  {-0.307674,1.349578},
+  {0.036264,0.711152},
+  {1.140221,-0.739087},
+  {-0.755562,0.284111},
+  {-0.724637,2.054996},
+  {-0.342831,-0.691441},
+  {-0.131512,-0.096478},
+  {-0.257152,0.074351},
+  {0.214615,1.055861},
+  {1.802147,-0.650688},
+  {0.494614,-0.618490},
+  {0.345858,-0.425000},
+  {-0.654990,0.633968},
+  {1.944518,-0.824383},
+  {0.027463,-1.406552},
+  {-0.356381,1.000390},
+  {-0.326255,-0.349790},
+  {-1.301773,-0.173698},
+  {1.209587,0.733830},
+  {-0.415904,-0.973085},
+  {-0.342312,0.036046},
+  {-0.186381,0.151542},
+  {-0.326625,0.939369},
+  {0.462830,-0.373640},
+  {0.606673,-0.179940},
+  {-0.484880,0.561731},
+  {-0.508378,-0.365497},
+  {0.234596,-1.627686},
+  {1.368364,-0.734676},
+  {-0.795618,-1.015961},
+  {-2.239029,-0.882143},
+  {0.465919,-0.251305},
+  {0.445335,-1.446642},
+  {-0.265756,0.613863},
+  {-0.452452,-0.137435},
+  {0.431065,0.801259},
+  {-0.152433,0.602319},
+  {-0.540982,-0.360173},
+  {0.631619,0.163229},
+  {-0.006424,-0.396139},
+  {-1.237030,0.367923},
+  {-0.850830,-0.132116},
+  {0.775877,-0.627868},
+  {0.771979,-0.413618},
+  {0.022536,0.168067},
+  {1.196601,0.009715},
+  {-0.617334,0.060062},
+  {0.364119,-0.116998},
+  {0.673689,0.458119},
+  {0.149576,-0.055954},
+  {-0.543521,0.313275},
+  {-0.158121,0.340606},
+  {-1.637515,0.192407},
+  {-0.980130,-1.214198},
+  {0.271889,-1.100195},
+  {-0.043511,-0.011070},
+  {1.944409,1.536861},
+  {1.054500,-0.241073},
+  {-0.266577,-1.534933},
+  {-0.040460,-0.625212},
+  {-0.459612,-1.252847},
+  {0.965432,0.594862},
+  {0.576392,-0.927788},
+  {-0.551566,0.279525},
+  {0.426353,0.063682},
+  {0.612646,-1.516517},
+  {-0.007228,-0.346205},
+  {0.011120,0.115249},
+  {0.472003,-0.089491},
+  {0.714530,-0.399992},
+  {-0.151271,-0.191677},
+  {-0.775722,0.462697},
+  {0.938747,-0.059595},
+  {-0.019837,0.256951},
+  {1.336979,-0.025192},
+  {-0.897808,-0.356736},
+  {-0.805198,0.998662},
+  {-0.427256,0.460826},
+  {0.649266,-0.173119},
+  {0.712430,-0.425832},
+  {-0.254883,0.091398},
+  {-0.082338,-0.612070},
+  {0.215579,-0.567451},
+  {-1.144568,0.155085},
+  {0.780083,-0.289786},
+  {-0.695259,0.933670},
+  {0.982418,-1.676289},
+  {2.030334,1.321377},
+  {0.038067,0.527490},
+  {-0.875315,-0.009320},
+  {0.068908,-1.082731},
+  {-0.327867,0.493442},
+  {-0.247380,0.306530},
+  {-0.737028,0.122061},
+  {0.989016,0.117014},
+  {-0.043846,0.663677},
+  {0.666528,-1.034380},
+  {0.394277,0.951912},
+  {-0.002676,0.539665},
+  {1.144832,0.222148},
+  {0.575492,0.698214},
+  {-0.465967,0.644700},
+  {0.135505,-0.027215},
+  {0.971868,0.345926},
+  {0.064156,-0.279836},
+  {-0.379608,0.096507},
+  {-0.122669,-0.207917},
+  {0.579961,0.725394},
+  {0.595409,-0.048807},
+  {1.252596,-0.666008},
+  {0.928256,0.648530},
+  {-0.765453,0.753437},
+  {-0.869056,-0.282207},
+  {0.599402,1.136827},
+  {-0.491976,1.257567},
+  {-0.690075,0.095121},
+  {0.114144,0.613636},
+  {-0.016676,0.984432},
+  {-0.038227,1.273482},
+  {-0.273440,0.465032},
+  {-0.042422,-0.082568},
+  {0.293014,-0.062751},
+  {0.091950,1.052528},
+  {1.290355,0.079452},
+  {-0.373801,-0.287744},
+  {0.178010,0.153087},
+  {-0.069493,-0.767951},
+  {0.592277,-0.164846},
+  {-0.624072,0.699601},
+  {-0.164866,0.014304},
+  {-0.989879,0.549690},
+  {-0.390924,0.210302},
+  {0.028281,1.109096},
+  {0.200445,-0.121299},
+  {-0.837043,-0.089108},
+  {-0.330949,-0.683155},
+  {-1.497096,-0.744454},
+  {0.724696,1.325496},
+  {1.093918,-0.158002},
+  {-0.986055,0.252052},
+  {0.738405,0.425232},
+  {0.346898,-0.636832},
+  {0.795577,-0.558523},
+  {1.639357,0.539509},
+  {-1.027171,-1.972701},
+  {-0.526853,0.066382},
+  {0.029728,0.371083},
+  {0.493240,-0.618207},
+  {-0.085066,0.157037},
+  {-0.598327,0.875382},
+  {0.473045,-0.683630},
+  {-0.190108,0.531203},
+  {0.755223,-0.445656},
+  {-0.970831,-0.378947},
+  {0.691900,-0.774742},
+  {-0.566027,-1.971771},
+  {0.221130,0.861383},
+  {1.126111,-1.603044},
+  {-0.238397,-0.723054},
+  {-1.355820,0.134919},
+  {0.901198,0.804579},
+  {-0.152608,-0.056988},
+  {-0.405939,0.133609},
+  {-0.748368,-0.793250},
+  {-1.127288,-0.628552},
+  {-0.545445,-0.085877},
+  {-0.731033,1.379358},
+  {0.017076,0.460959},
+  {0.860053,0.187958},
+  {-0.398644,0.846772},
+  {-0.136298,-0.593748},
+  {-0.570386,-0.054041},
+  {-0.208522,0.414807},
+  {1.089348,0.418117},
+  {0.071506,-0.234059},
+  {0.803787,-0.420491},
+  {0.379378,1.744838},
+  {0.984846,-0.269280},
+  {0.287580,1.777600},
+  {-0.044561,0.393765},
+  {1.037652,0.288589},
+  {1.365033,1.028047},
+  {-0.268731,0.214781},
+  {-1.399734,-0.585635},
+  {0.396474,-0.012739},
+  {-0.310157,-0.572639},
+  {-0.869280,-0.470035},
+  {-0.767115,-0.147986},
+  {-0.594210,-0.009435},
+  {-0.259161,0.687769},
+  {0.400244,0.052298},
+  {-0.081466,1.100944},
+  {-0.597903,-0.298039},
+  {-0.112978,0.185533},
+  {-1.188213,0.607802},
+  {0.406532,0.557457},
+  {0.053603,0.608809},
+  {-0.909431,-1.412004},
+  {0.092312,-0.308009},
+  {-1.045767,-0.193634},
+  {-0.655190,0.515159},
+  {-0.979891,-0.064583},
+  {-0.305666,2.135184},
+  {0.263726,-1.169643},
+  {0.138287,0.442218},
+  {0.414382,-0.295128},
+  {-1.223938,-0.394704},
+  {-0.670657,-0.732705},
+  {-0.130172,1.369600},
+  {0.795171,0.769043},
+  {-0.363984,0.127902},
+  {-0.154541,-0.229581},
+  {0.285194,1.725037},
+  {-1.330522,0.314956},
+  {-0.233268,-0.249791},
+  {-0.867872,-0.116151},
+  {0.528821,0.939245},
+  {0.529436,-0.728938},
+  {1.562335,-0.647528},
+  {0.100798,0.930577},
+  {-0.638534,-0.474881},
+  {-0.985353,-0.905430},
+  {-0.508469,-0.557904},
+  {0.109266,-0.555654},
+  {0.066719,-1.050199},
+  {0.086614,0.288710},
+  {-0.064293,0.794723},
+  {0.211760,0.375610},
+  {-0.388465,0.047865},
+  {0.115226,0.666505},
+  {0.090883,-1.307463},
+  {-0.505210,-0.481163},
+  {0.297328,0.181031},
+  {-1.005686,-0.291049},
+  {-0.384623,-0.349974},
+  {-1.117550,-0.533047},
+  {-0.273571,1.197142},
+  {-0.355377,-0.791390},
+  {-1.166707,0.219873},
+  {-0.039557,0.571754},
+  {-0.869280,0.219124},
+  {-0.267389,0.851277},
+  {-0.047552,-0.759693},
+  {-1.247211,0.340410},
+  {0.074985,-0.567950},
+  {0.114898,-0.993669},
+  {1.315018,1.236524},
+  {0.490222,-1.122814},
+  {-0.208569,0.122706},
+  {0.811257,0.284157},
+  {-1.535386,-0.961487},
+  {-0.575903,-0.329705},
+  {-0.440839,0.189689},
+  {0.461173,0.106876},
+  {-1.404882,-0.039592},
+  {0.157627,-0.164670},
+  {-0.143457,-0.082398},
+  {0.137764,-1.405608},
+  {1.138510,0.467085},
+  {-0.569274,0.068115},
+  {0.254692,-0.256963},
+  {-0.200568,-0.105250},
+  {0.649507,0.852508},
+  {0.256781,0.075334},
+  {-0.422662,0.827176},
+  {0.453451,-0.274344},
+  {-0.619070,-0.789528},
+  {0.511156,-0.517215},
+  {-0.746724,0.533320},
+  {-0.266023,0.211951},
+  {0.820569,-0.021797},
+  {0.906967,-0.184995},
+  {0.080283,-0.845286},
+  {0.216563,-0.065165},
+  {-1.069864,-0.627168},
+  {-0.694919,-0.377147},
+  {0.560266,0.723653},
+  {-1.810003,0.936073},
+  {0.401495,-0.323666},
+  {0.279725,-0.512582},
+  {0.115233,0.391509},
+  {-0.049100,0.503527},
+  {0.381476,-0.924580},
+  {0.158435,-0.369579},
+  {-1.724612,-0.082530},
+  {0.146337,-0.627385},
+  {-0.580628,-1.005474},
+  {-1.283667,-0.367336},
+  {1.671694,0.093866},
+  {0.495123,0.338942},
+  {1.386453,1.289725},
+  {0.046473,-0.010269},
+  {0.345976,0.217331},
+  {-1.307691,0.901025},
+  {0.011671,-0.051992},
+  {0.446749,0.491618},
+  {-0.798861,-1.715122},
+  {0.459684,0.845517},
+  {-0.619994,-0.080941},
+  {0.726701,0.519006},
+  {0.366870,-1.500535},
+  {-0.695698,-0.307731},
+  {0.383154,-0.604660},
+  {-0.200421,-0.592773},
+  {0.845962,0.202566},
+  {-0.081811,-0.479720},
+  {-0.162211,0.211402},
+  {-0.508318,-0.515009},
+  {-0.598247,-0.160839},
+  {-0.361101,1.022331},
+  {-0.593453,-0.828867},
+  {-0.335951,-1.161512},
+  {0.323913,0.171438},
+  {0.880390,-0.900887},
+  {0.961106,1.439049},
+  {-0.145219,0.714873},
+  {-0.035628,0.517433},
+  {-1.289047,0.344996},
+  {0.823198,-0.391606},
+  {-0.666119,-0.158353},
+  {-0.497984,-0.154500},
+  {0.346989,1.546966},
+  {0.708533,-0.966663},
+  {0.374617,1.425507},
+  {-0.337693,0.237900},
+  {0.070178,-1.763557},
+  {-0.029864,-0.502392},
+  {1.018740,0.551282},
+  {0.470196,0.024369},
+  {-1.046625,0.923415},
+  {-0.440020,0.376281},
+  {0.735956,-1.156211},
+  {-0.994301,0.170391},
+  {0.092725,0.006086},
+  {0.907493,-0.090784},
+  {0.594763,0.737713},
+  {0.906663,-0.107508},
+  {-0.367296,-0.557330},
+  {-2.018388,0.168510},
+  {0.752505,0.463679},
+  {0.078006,0.290962},
+  {0.109202,1.088115},
+  {-0.098741,2.088661},
+  {0.628856,0.143489},
+  {0.531659,-0.603075},
+  {-0.792778,0.565173},
+  {1.033181,0.091416},
+  {-0.436632,1.313604},
+  {-0.484757,-0.142273},
+  {0.419226,-1.120024},
+  {0.480503,1.065520},
+  {-0.237411,-0.260825},
+  {0.605263,-0.918341},
+  {0.875513,-0.731113},
+  {1.386509,1.669871},
+  {-0.213429,0.316753},
+  {0.131674,1.000488},
+  {0.748148,-0.249815},
+  {-0.533266,0.340614},
+  {-0.869102,0.414872},
+  {0.441595,-0.694290},
+  {0.054900,1.807807},
+  {-1.703986,-0.934117},
+  {-1.249102,0.046980},
+  {-0.221412,-0.687920},
+  {0.448836,0.201658},
+  {0.650497,1.040959},
+  {0.177494,-0.799854},
+  {-0.085265,0.556515},
+  {-0.932668,-0.426775},
+  {-0.062327,-1.158497},
+  {-0.500424,-0.587836},
+  {0.391493,-0.387043},
+  {-0.617236,-0.317457},
+  {-0.578667,0.512964},
+  {-0.169709,-0.817154},
+  {-0.110670,0.372632},
+  {-0.222525,-0.793149},
+  {-0.009570,0.182038},
+  {-0.527806,0.463093},
+  {-1.697382,-1.718132},
+  {0.361860,0.075201},
+  {0.089404,0.241598},
+  {-0.946784,0.814996},
+  {-0.613512,-0.255426},
+  {-0.177349,-0.488484},
+  {0.054348,-0.553629},
+  {-0.194009,1.167781},
+  {1.709740,0.267476},
+  {-0.821832,-0.696939},
+  {-0.200828,-0.430296},
+  {1.069248,-0.373373},
+  {-0.238442,-0.199476},
+  {-0.180144,-0.025549},
+  {-0.139817,-0.071419},
+  {-0.173577,-0.475708},
+  {0.304222,-0.368525},
+  {-0.590842,-0.064255},
+  {-1.185859,-1.155381},
+  {-0.081806,-0.629742},
+  {0.922781,0.144932},
+  {0.942112,0.322870},
+  {0.825791,1.003816},
+  {0.826714,-0.826888},
+  {0.213177,0.794777},
+  {-0.099002,-0.002608},
+  {-0.492385,0.451787},
+  {0.128127,1.082202},
+  {0.271635,-1.443648},
+  {-0.178330,-1.243963},
+  {-0.067726,0.414538},
+  {-0.546234,0.480571},
+  {-0.991696,-0.224893},
+  {0.432404,-0.524750},
+  {-0.501489,-0.744894},
+  {0.103839,-1.138339},
+  {-0.279854,-0.368705},
+  {0.455291,0.602993},
+  {-1.678218,0.178024},
+  {-0.130112,0.138684},
+  {-1.101287,0.579001},
+  {-0.092947,-0.011740},
+  {0.295525,0.118103},
+  {0.785569,0.325779},
+  {0.504792,-0.455453},
+  {1.132796,0.017106},
+  {0.033302,0.186834},
+  {0.810809,-0.362816},
+  {-0.474375,0.097647},
+  {-1.062575,-0.732286},
+  {0.342440,-0.680445},
+  {-0.732904,-0.575352},
+  {0.303712,-0.631739},
+  {-0.319236,-1.030421},
+  {-0.387937,-0.348376},
+  {-1.079633,0.118041},
+  {-0.602187,-0.491677},
+  {0.423529,0.249166},
+  {-0.952323,0.209902},
+  {0.034247,0.375740},
+  {-0.592018,-0.397569},
+  {-0.163837,-0.427724},
+  {0.382374,-0.150979},
+  {0.555706,-0.725082},
+  {-0.355857,0.158597},
+  {0.761846,0.076153},
+  {-0.634078,-0.304593},
+  {0.471280,-0.916497},
+  {0.242803,0.758195},
+  {0.754191,1.510976},
+  {1.548155,-0.494631},
+  {0.691794,-0.562304},
+  {0.668136,-0.981643},
+  {-0.254217,-0.991335},
+  {-0.318592,-0.794923},
+  {-0.462833,-0.254355},
+  {0.963190,-0.369654},
+  {-0.006760,0.514227},
+  {-0.029911,0.884285},
+  {0.486003,-0.768507},
+  {0.111313,-0.201531},
+  {0.594695,-0.372400},
+  {0.590731,-0.701254},
+  {-0.563540,0.783977},
+  {0.368562,-1.798989},
+  {0.756754,0.099174},
+  {-0.637641,-1.143978},
+  {0.650260,-0.244381},
+  {-0.691307,-1.071333},
+  {0.861524,0.340780},
+  {0.505066,0.009908},
+  {1.474460,0.787023},
+  {0.976164,0.140441},
+  {-0.254395,-0.077743},
+  {-0.607054,-0.319290},
+  {0.265146,0.411305},
+  {-1.013336,0.386584},
+  {0.105899,0.018232},
+  {0.563171,-0.016770},
+  {-0.940128,-0.278832},
+  {-0.221102,0.977281},
+  {1.567826,0.261716},
+  {0.196254,-1.341196},
+  {-0.102125,0.328156},
+  {-0.201069,-0.674704},
+  {0.352926,-0.898702},
+  {0.911536,0.859603},
+  {-0.528193,0.953868},
+  {1.140887,0.032021},
+  {-0.020405,0.168142},
+  {0.328295,-0.517896},
+  {-0.337676,0.588593},
+  {0.585343,0.249905},
+  {-0.287053,-0.782415},
+  {0.794615,0.416868},
+  {-0.332534,1.181646},
+  {0.674689,-0.239908},
+  {-0.248407,0.137528},
+  {-0.301989,0.114605},
+  {-0.044851,0.768646},
+  {0.542929,0.080812},
+  {-0.071794,-0.299563},
+  {-0.734715,0.382308},
+  {-0.421130,0.911202},
+  {-0.430273,0.472535},
+  {-0.687487,-0.273706},
+  {0.367111,-0.660188},
+  {-0.918680,0.527015},
+  {-0.341398,0.970202},
+  {-0.107157,0.886225},
+  {0.938713,-0.223450},
+  {-0.671171,-0.152803},
+  {-0.385831,0.640238},
+  {-0.780561,-0.635265},
+  {0.715185,0.185086},
+  {-0.699200,0.606720},
+  {-0.653360,0.102234},
+  {0.131534,-1.084895},
+  {0.261869,0.060136},
+  {0.317683,-0.939159},
+  {-0.840538,-0.043646},
+  {-1.424293,0.084761},
+  {1.215854,-0.694838},
+  {0.062843,-0.337987},
+  {0.563976,0.504785},
+  {-0.080370,0.085930},
+  {0.032035,-1.010920},
+  {0.551369,0.494227},
+  {-0.116020,0.300480},
+  {0.331724,0.036285},
+  {-0.382426,-0.529493},
+  {1.077808,-0.458413},
+  {0.331854,1.032253},
+  {-0.535004,-0.323188},
+  {-0.819970,0.052055},
+  {0.719559,-0.602325},
+  {0.915057,0.257542},
+  {-0.428636,-0.009926},
+  {-1.805475,0.369659},
+  {-0.614094,-0.001800},
+  {-1.235578,-0.052044},
+  {0.097063,-0.732735},
+  {-1.460257,1.469093},
+  {1.278098,-0.169305},
+  {-1.378817,0.540052},
+  {0.493755,-0.307548},
+  {0.218180,1.141994},
+  {-0.221486,-0.292270},
+  {0.287143,-0.163096},
+  {0.703925,0.446666},
+  {0.212925,0.082821},
+  {0.484300,0.306027},
+  {0.357386,-1.297873},
+  {-0.738326,-0.241678},
+  {-0.741457,-0.442234},
+  {0.327873,0.656962},
+  {-0.853324,0.049464},
+  {0.311712,-0.772024},
+  {0.492337,-0.224030},
+  {-0.072145,-0.706020},
+  {0.120789,-0.269756},
+  {0.510265,-0.199574},
+  {0.305081,1.339218},
+  {-1.174933,-0.318689},
+  {-0.310504,0.857660},
+  {-0.260578,-0.738450},
+  {0.840290,-0.412105},
+  {0.978639,0.996309},
+  {0.545701,-0.214489},
+  {0.442492,0.140782},
+  {0.134327,-0.614024},
+  {0.152361,-0.415766},
+  {0.402772,-0.590738},
+  {-0.086536,0.126473},
+  {0.212853,0.348347},
+  {1.454511,0.690384},
+  {-0.525360,0.196963},
+  {0.096687,-0.682747},
+  {0.001357,0.832025},
+  {-0.426188,-0.466376},
+  {0.206853,-0.152419},
+  {0.687454,1.804000},
+  {-1.322728,1.203989},
+  {0.482003,-1.241984},
+  {0.500789,-0.065064},
+  {0.244065,0.269642},
+  {-0.469472,-0.237159},
+  {-0.066490,-0.163310},
+  {-0.281095,-0.567134},
+  {0.893307,0.612599},
+  {-0.632126,-0.774347},
+  {0.109283,0.368826},
+  {0.148461,-0.404510},
+  {-0.667521,1.577892},
+  {0.218306,0.265584},
+  {0.264606,-0.211250},
+  {0.652372,-0.157857},
+  {-0.577376,-0.888662},
+  {-0.945390,0.153267},
+  {0.375344,-1.667404},
+  {-0.156601,-0.117106},
+  {-1.462571,-0.718417},
+  {-0.575509,-0.808437},
+  {0.364817,0.078618},
+  {-0.403867,0.323323},
+  {0.157170,0.940718},
+  {-0.905934,0.911193},
+  {0.173700,1.333921},
+  {0.056693,-0.033255},
+  {-0.296912,-0.103485},
+  {0.153056,-0.604195},
+  {0.377705,0.504978},
+  {-0.673747,0.286633},
+  {0.034797,0.558569},
+  {-0.710120,-0.480598},
+  {-0.362652,-0.642279},
+  {-0.284230,0.181896},
+  {-0.426250,2.162377},
+  {0.985906,-1.488951},
+  {-0.458442,-0.456442},
+  {0.553374,-0.612342},
+  {-0.809457,-0.439975},
+  {0.180812,0.353789},
+  {-0.978222,0.464068},
+  {-0.300099,0.132864},
+  {1.487060,0.218514},
+  {0.957071,0.801319},
+  {-1.294117,0.020448},
+  {0.445091,0.773514},
+  {-0.199977,0.450449},
+  {1.443591,0.429417},
+  {-0.113708,0.610933},
+  {0.137175,-0.859998},
+  {-0.132513,-1.322847},
+  {-1.005503,-0.177505},
+  {0.000357,0.779256},
+  {1.075366,0.024032},
+  {0.459241,0.710256},
+  {-0.305482,0.106401},
+  {-0.276184,1.043264},
+  {0.516417,-1.254294},
+  {-0.131916,0.527997},
+  {0.234204,-1.557823},
+  {0.030533,-0.531908},
+  {1.085678,-0.371773},
+  {-0.221198,-0.710384},
+  {-0.063287,0.159905},
+  {0.444706,-0.383745},
+  {-0.446182,-0.684475},
+  {0.740908,0.413410},
+  {0.167352,0.712524},
+  {0.392175,0.355523},
+  {0.129803,-0.137579},
+  {-0.528156,-0.906438},
+  {0.405284,-0.052276},
+  {0.240957,-1.088857},
+  {0.642791,-0.012554},
+  {-0.439821,0.196588},
+  {0.640984,0.397706},
+  {-1.267697,-0.882481},
+  {-0.129466,1.197844},
+  {1.461545,-0.514695},
+  {-0.664521,-0.084123},
+  {-0.351623,1.236291},
+  {0.412838,-0.694709},
+  {0.414800,-0.181844},
+  {-0.304968,-0.380719},
+  {1.155782,-0.095914},
+  {-0.071784,-1.320101},
+  {-0.694458,0.795722},
+  {0.810258,0.637455},
+  {1.163340,-0.742524},
+  {-0.963930,0.444600},
+  {0.655143,0.089189},
+  {-0.592677,-1.127872},
+  {0.887550,-0.327055},
+  {0.625412,-0.529684},
+  {0.713678,-0.696201},
+  {0.055567,-0.252346},
+  {0.166431,0.153213},
+  {0.441026,-1.378759},
+  {0.559243,-0.537530},
+  {0.202748,0.275560},
+  {-0.840727,0.168231},
+  {-0.064211,0.001891},
+  {0.281684,0.135740},
+  {-0.358316,-0.959788},
+  {1.306011,0.464514},
+  {-1.036941,-0.959162},
+  {1.406593,0.632846},
+  {-1.569454,-0.365218},
+  {-0.346228,0.731728},
+  {-1.295997,0.560615},
+  {-0.959968,0.986496},
+  {-0.585640,-0.657095},
+  {-0.118904,-0.871209},
+  {0.926150,-0.531476},
+  {0.933032,0.480609},
+  {0.263173,0.494663},
+  {0.886100,-0.059677},
+  {-0.369519,-0.535388},
+  {0.421964,-0.910301},
+  {-0.326652,-0.190231},
+  {0.547934,0.631971},
+  {0.710113,-0.411325},
+  {0.693213,-0.929055},
+  {0.018916,-0.458380},
+  {-0.289372,-0.644681},
+  {1.603608,-0.790238},
+  {-0.870347,-0.519386},
+  {-0.120219,-0.195792},
+  {0.896996,0.754328},
+  {-1.072971,0.660451},
+  {-0.169902,0.618787},
+  {1.392250,0.699588},
+  {0.102127,-1.159976},
+  {0.654802,-1.138594},
+  {0.341693,0.533089},
+  {0.622157,0.293998},
+  {0.739470,-0.685871},
+  {0.889143,-1.040852},
+  {0.028575,1.018274},
+  {1.349263,-0.463929},
+  {0.455431,-0.360066},
+  {-0.778939,1.099713},
+  {-0.893473,0.754993},
+  {0.004027,-0.390836},
+  {-0.251340,0.012372},
+  {-0.222768,-0.628511},
+  {-0.106092,-1.338030},
+  {-1.913003,0.816801},
+  {0.249156,-0.479677},
+  {-0.736923,1.666795},
+  {1.082270,-0.175401},
+  {-0.885157,0.570095},
+  {-0.049028,0.558581},
+  {-0.490770,0.519661},
+  {-0.287551,-0.111662},
+  {1.033980,0.682340},
+  {0.087287,1.358185},
+  {-0.050552,0.564941},
+  {-0.303037,0.089188},
+  {0.842740,0.611644},
+  {0.467414,-0.006327},
+  {0.466794,0.602077},
+  {0.439659,-0.483228},
+  {0.974723,-0.062053},
+  {-0.260206,-1.049128},
+  {-0.205828,0.295329},
+  {-1.647119,0.441492},
+  {-0.714502,0.081394},
+  {-0.205006,-0.757855},
+  {-1.960274,0.470666},
+  {-0.533298,0.409415},
+  {0.855841,1.096989},
+  {0.358798,0.730984},
+  {0.750960,-0.725304},
+  {1.146306,1.834112},
+  {-0.476547,0.068212},
+  {-0.694398,-0.779186},
+  {1.092268,-0.985842},
+  {1.398056,-0.217714},
+  {0.251666,0.911836},
+  {0.110386,0.085893},
+  {0.701887,0.259171},
+  {0.516668,0.334310},
+  {-0.003315,-0.918830},
+  {-0.195731,0.013077},
+  {0.430466,-0.277817},
+  {1.030171,-0.394052},
+  {-0.225629,-0.195349},
+  {-0.027538,-0.056974},
+  {0.031358,0.064035},
+  {0.387717,0.243636},
+  {0.317769,-0.582616},
+  {0.940290,0.778192},
+  {-0.490807,-0.763537},
+  {0.207110,-0.045007},
+  {1.971938,0.382367},
+  {-0.727075,0.439464},
+  {-0.077633,0.672896},
+  {-1.460959,1.007622},
+  {-0.025801,-0.096694},
+  {-0.993988,-0.999907},
+  {0.464187,0.789316},
+  {0.256421,-1.363865},
+  {0.159660,-0.277453},
+  {-0.006103,0.852472},
+  {0.060031,0.596424},
+  {0.620580,0.715707},
+  {0.276113,-0.545072},
+  {-1.012081,-1.133049},
+  {-0.097912,-0.474511},
+  {1.319384,0.602481},
+  {-0.031653,0.663256},
+  {0.386930,0.752664},
+  {-0.991397,-0.430424},
+  {0.051973,-1.136431},
+  {-1.149435,0.841670},
+  {-0.186103,0.364773},
+  {-0.412187,0.132497},
+  {-0.775032,0.368945},
+  {0.032215,0.521604},
+  {1.015831,-0.411670},
+  {0.726604,-0.273412},
+  {-0.017691,0.358815},
+  {-0.486292,-1.210999},
+  {-0.099767,0.094482},
+  {0.097904,0.233600},
+  {-1.240408,0.247283},
+  {0.721376,-1.415937},
+  {0.561702,0.753190},
+  {-0.214495,-0.390780},
+  {-0.433983,-0.193696},
+  {-0.539126,-0.635186},
+  {0.334874,0.117167},
+  {0.112738,-0.692831},
+  {1.294694,1.248792},
+  {-0.305773,0.353188},
+  {1.021686,0.202287},
+  {0.256958,-0.390091},
+  {0.166097,0.454005},
+  {-0.079576,-1.102067},
+  {1.538520,-0.563688},
+  {-1.731706,-1.126758},
+  {-0.670402,0.414350},
+  {0.514859,-0.033709},
+  {0.457049,-0.953866},
+  {-0.025339,-0.186967},
+  {0.921516,-0.006589},
+  {1.133250,0.762349},
+  {-1.942749,-0.290318},
+  {-1.006259,-1.719958},
+  {0.583133,0.184458},
+  {1.533676,0.565125},
+  {1.678753,1.997106},
+  {0.414856,0.635099},
+  {0.248681,-0.371868},
+  {-0.480461,0.508675},
+  {0.128528,1.225431},
+  {-1.035243,-0.326540},
+  {-0.591735,-0.256529},
+  {0.404609,0.115763},
+  {-0.127455,-0.322196},
+  {-1.377901,0.027817},
+  {-0.419663,-0.117352},
+  {0.100835,-0.416059},
+  {0.112067,-0.455572},
+  {-0.918836,-1.089230},
+  {0.819424,-0.676223},
+  {-1.262287,-0.710934},
+  {-1.405267,-0.629728},
+  {-0.245684,0.259446},
+  {0.275126,0.743111},
+  {-0.632728,0.059081},
+  {-0.268444,1.149652},
+  {0.262731,-0.503980},
+  {-0.732316,1.865036},
+  {0.546659,-0.355999},
+  {1.055911,-0.387197},
+  {0.493665,-0.753767},
+  {-0.182871,0.659888},
+  {0.622885,-1.309388},
+  {-0.557757,-0.093695},
+  {0.098147,0.439508},
+  {0.803828,-0.887762},
+  {-0.324194,-0.317906},
+  {-1.732072,-0.835605},
+  {-0.244274,0.535165},
+  {0.459924,0.794849},
+  {-0.678300,1.156888},
+  {-0.492597,0.785141},
+  {0.158968,0.435641},
+  {-0.036905,0.358065},
+  {0.110872,-0.689448},
+  {0.880365,-1.190838},
+  {0.796720,1.588231},
+  {-1.706377,0.554221},
+  {-0.358409,-0.529411},
+  {-0.715658,0.777524},
+  {-0.561075,-0.227583},
+  {0.899021,-0.235572},
+  {0.525853,-1.659359},
+  {0.079290,0.113489},
+  {0.113024,0.340952},
+  {-0.139241,0.174221},
+  {0.224799,0.763237},
+  {-1.379719,0.258011},
+  {-0.935142,-0.447336},
+  {-0.784769,0.357662},
+  {-0.232321,-1.397151},
+  {-1.450584,0.943146},
+  {-0.324962,-0.543177},
+  {-1.282408,0.863020},
+  {0.050112,0.898989},
+  {-0.604191,-0.538101},
+  {0.343664,-0.068146},
+  {0.102684,-0.123663},
+  {0.928256,0.360823},
+  {-0.097289,0.462497},
+  {-0.092053,0.034602},
+  {0.440637,-0.296188},
+  {1.149567,-0.825341},
+  {0.260298,-0.546318},
+  {0.369902,-0.765528},
+  {-0.115122,-0.752161},
+  {-0.134579,-0.097381},
+  {-0.352925,-0.341836},
+  {-0.133949,0.670338},
+  {-1.133992,-0.211796},
+  {-0.771100,0.093373},
+  {-0.958877,0.269735},
+  {-1.004989,-0.185393},
+  {-0.095868,0.247778},
+  {-2.586064,-0.157309},
+  {0.225446,-0.204901},
+  {0.848046,-0.114858},
+  {0.944526,0.415761},
+  {0.175256,0.081095},
+  {-0.221988,0.520441},
+  {0.101561,0.235463},
+  {1.036973,0.143210},
+  {1.226535,-0.837936},
+  {0.071154,-0.334797},
+  {0.002085,-1.605103},
+  {-0.217532,-0.203431},
+  {-0.020084,-0.177046},
+  {1.594854,0.364505},
+  {0.353434,0.078027},
+  {-0.408512,0.470233},
+  {1.312720,-0.497096},
+  {-0.446915,1.180362},
+  {0.576132,-0.033510},
+  {0.987148,0.361694},
+  {-0.741101,0.494390},
+  {-0.147701,0.106470},
+  {-0.122341,0.707589},
+  {-0.828018,0.595488},
+  {0.358592,0.384138},
+  {1.122524,-0.548564},
+  {0.865484,0.246095},
+  {-0.347659,0.661972},
+  {-0.629108,-0.078289},
+  {0.435537,0.266599},
+  {-0.290543,0.076388},
+  {1.350286,-1.026417},
+  {-0.279524,0.033803},
+  {0.805857,-1.271171},
+  {1.494965,-0.166193},
+  {0.224108,-0.156611},
+  {0.348711,0.043524},
+  {0.486362,0.705632},
+  {-0.135721,0.860144},
+  {-0.419355,-0.933635},
+  {0.585876,-0.739752},
+  {0.348953,1.633115},
+  {-0.716160,-0.030413},
+  {-1.012214,0.928111},
+  {1.274223,-1.604781},
+  {0.986726,0.442809},
+  {0.926012,-1.822679},
+  {-0.976620,-0.129446},
+  {-0.631693,-1.113716},
+  {0.013938,-0.471054},
+  {-0.337122,0.006422},
+  {-0.075227,1.194378},
+  {0.192303,0.005400},
+  {0.482293,0.882435},
+  {0.759362,-1.106292},
+  {-0.178414,0.131685},
+  {-0.109098,-0.738940},
+  {0.076915,1.201590},
+  {-0.065114,-0.913385},
+  {0.258717,0.253192},
+  {0.006675,0.474848},
+  {-0.120236,0.074537},
+  {-0.914876,-0.604674},
+  {-0.239318,0.139784},
+  {0.373102,-0.811346},
+  {-0.112757,1.025991},
+  {0.939548,0.465295},
+  {-0.350290,-0.018134},
+  {-0.562664,0.175504},
+  {0.514850,-0.074323},
+  {0.521176,0.137696},
+  {0.194373,0.197405},
+  {0.927279,1.181192},
+  {-0.118453,-0.014140},
+  {1.916604,-0.970558},
+  {0.612289,-1.323595},
+  {-0.046588,0.676538},
+  {-0.361614,0.343330},
+  {-0.072801,-0.258052},
+  {-0.387405,-0.305871},
+  {-0.953448,-0.183769},
+  {0.528532,-0.434791},
+  {-0.180672,-0.359667},
+  {-0.599359,0.653634},
+  {0.050363,-0.480589},
+  {0.233107,0.154633},
+  {-0.948858,0.182072},
+  {0.456937,-0.516302},
+  {0.303400,0.828243},
+  {-0.675064,-0.986310},
+  {-0.305059,0.166836},
+  {1.464878,0.165149},
+  {0.374637,-0.656082},
+  {0.718124,-1.594720},
+  {0.470116,-0.781559},
+  {0.309853,-0.650064},
+  {-1.133502,0.331558},
+  {0.145630,-0.142324},
+  {-0.157430,-0.301290},
+  {1.777805,0.083103},
+  {0.717511,0.394040},
+  {-0.145187,0.174645},
+  {-0.557239,0.572090},
+  {0.191157,0.101788},
+  {0.484733,0.137371},
+  {0.285309,-0.047834},
+  {0.197723,0.435201},
+  {1.212389,1.074376},
+  {1.174508,-1.056099},
+  {-0.076020,-0.321082},
+  {-1.196586,-0.557423},
+  {-0.610224,-1.475905},
+  {-0.009208,0.213072},
+  {0.515729,-1.346302},
+  {0.103609,-0.105880},
+  {-1.120470,0.071781},
+  {-0.777519,0.463790},
+  {1.156226,-0.298195},
+  {0.203968,0.760272},
+  {-0.780637,-0.918900},
+  {-0.769841,-0.775429},
+  {0.935468,0.026705},
+  {-0.241774,1.112869},
+  {0.227628,0.184193},
+  {-0.183832,0.409623},
+  {1.130661,0.731075},
+  {-0.555506,0.437555},
+  {0.457972,-1.800335},
+  {0.272675,0.660832},
+  {-1.884673,0.050126},
+  {-0.580737,-0.779387},
+  {1.227434,0.547756},
+  {0.053354,-0.616688},
+  {0.478480,0.910639},
+  {-0.333049,0.719330},
+  {0.010465,-0.612533},
+  {0.906478,0.818118},
+  {-1.193153,-1.824502},
+  {0.706058,0.615496},
+  {-0.370577,-0.145762},
+  {-0.902391,-0.628656},
+  {-0.106987,-0.364320},
+  {-0.084966,-1.302484},
+  {0.849559,-0.758851},
+  {-0.721184,0.072056},
+  {0.445967,0.442923},
+  {1.135449,1.092539},
+  {0.250839,1.832846},
+  {0.242031,-0.912937},
+  {0.969083,-1.380916},
+  {-0.854039,0.805446},
+  {-0.063648,-0.529546},
+  {-0.556826,0.358275},
+  {0.502400,-0.419893},
+  {1.121981,-0.341123},
+  {0.146130,1.403614},
+  {-1.507194,0.954692},
+  {1.696664,1.704881},
+  {-0.599841,-0.359776},
+  {-0.044186,-0.459231},
+  {-0.118475,-0.554999},
+  {-0.833973,-0.512125},
+  {-1.163373,-0.238938},
+  {-0.208580,0.332700},
+  {0.371481,-0.478670},
+  {-0.607465,-1.178812},
+  {-0.293391,0.125643},
+  {-0.646705,0.940141},
+  {0.189148,-1.350865},
+  {0.342294,-1.580507},
+  {-1.132454,-0.157761},
+  {-0.019979,0.524966},
+  {-0.169449,-0.519595},
+  {1.065918,-0.985098},
+  {-0.915971,-0.284780},
+  {0.098857,-1.215288},
+  {0.783253,0.635773},
+  {0.449313,-0.510098},
+  {0.689266,0.814086},
+  {-0.144834,-0.612379},
+  {-1.427958,0.199905},
+  {-0.474064,-0.742974},
+  {-0.337112,-0.137790},
+  {-0.674899,-0.264672},
+  {0.912269,1.104826},
+  {0.831791,-0.341448},
+  {-0.388669,0.672793},
+  {1.087330,1.281850},
+  {0.118528,0.631338},
+  {-0.206049,-0.715623},
+  {-0.781056,0.033644},
+  {0.792916,0.295321},
+  {-0.482422,-0.237909},
+  {0.261478,-0.752447},
+  {-0.754615,-0.516213},
+  {0.192734,0.378640},
+  {-0.439435,-0.431982},
+  {-0.946669,0.479718},
+  {-0.357092,-0.691345},
+  {1.157752,0.666368},
+  {-1.383208,0.311908},
+  {0.409399,0.461214},
+  {-0.698759,-0.607928},
+  {-0.482476,1.416944},
+  {-0.199183,0.371134},
+  {-0.082352,0.429145},
+  {0.432215,-1.285389},
+  {-0.244029,-0.686566},
+  {-1.015378,0.249656},
+  {0.956609,0.256536},
+  {-1.108435,-0.400837},
+  {0.358475,0.626661},
+  {0.376849,0.118413},
+  {0.384957,-0.159492},
+  {1.550985,0.318564},
+  {-0.658378,0.829656},
+  {0.070058,-1.867597},
+  {-0.556355,0.877398},
+  {-0.939162,-0.758821},
+  {-0.975259,0.428551},
+  {-0.465374,0.248586},
+  {-0.647683,0.162461},
+  {0.478579,-0.086328},
+  {1.171809,-1.210333},
+  {0.350605,-0.026423},
+  {-1.535107,-0.289105},
+  {0.569494,0.289004},
+  {-0.842191,-0.535135},
+  {-1.056587,-0.341966},
+  {0.571423,-0.949688},
+  {0.377006,0.223183},
+  {0.895255,-1.194232},
+  {0.407145,0.361737},
+  {-0.133994,-1.212235},
+  {-0.635602,0.102165},
+  {-0.112363,0.370473},
+  {0.088680,-0.934189},
+  {0.189376,0.032527},
+  {0.241638,0.015864},
+  {0.926939,-0.360267},
+  {0.633242,-0.199406},
+  {-0.777074,0.718454},
+  {1.263760,1.272871},
+  {-0.887876,0.895443},
+  {0.045161,-0.732052},
+  {-0.500926,0.113907},
+  {-0.126137,0.817229},
+  {0.086923,-0.332814},
+  {0.016727,0.325903},
+  {-0.336638,-0.207087},
+  {-0.613900,-0.550235},
+  {1.069793,-0.208412},
+  {0.077398,-1.607311},
+  {-0.215649,0.115757},
+  {-0.404151,-0.996211},
+  {0.226156,-0.014279},
+  {-1.177157,0.074822},
+  {-0.140062,0.186657},
+  {-0.409112,-0.330324},
+  {1.309929,-0.332041},
+  {0.821633,0.695834},
+  {-0.938862,-1.552127},
+  {0.075839,1.054654},
+  {0.323977,-1.147671},
+  {0.310022,0.038229},
+  {-0.359029,-0.022630},
+  {0.324017,0.387352},
+  {-0.048052,0.500409},
+  {-0.768604,-0.470784},
+  {0.684604,0.201031},
+  {0.736939,-1.300678},
+  {-0.479045,-1.017034},
+  {0.007828,-0.810752},
+  {-0.304589,-0.420991},
+  {0.655603,-0.376914},
+  {-0.526926,-0.309443},
+  {1.263186,0.124584},
+  {-0.301892,0.095891},
+  {0.329349,0.607629},
+  {0.858170,0.481326},
+  {0.863272,-1.044820},
+  {-0.185530,0.990111},
+  {-0.944209,0.851341},
+  {-0.140130,1.176828},
+  {0.656967,-0.249158},
+  {0.831843,0.166278},
+  {0.281441,1.026104},
+  {0.815836,1.287209},
+  {1.204176,-0.446447},
+  {-0.824919,-0.004133},
+  {-1.288957,0.000250},
+  {0.202791,0.163948},
+  {-0.652007,1.250650},
+  {-0.940207,1.250555},
+  {0.060222,-0.160424},
+  {0.276591,-0.733905},
+  {1.240840,-0.391642},
+  {1.228907,0.734534},
+  {0.183878,0.004227},
+  {0.471755,-0.211169},
+  {1.313163,1.109955},
+  {0.040600,-1.427535},
+  {-1.534644,0.502761},
+  {-0.618235,0.755691},
+  {0.075225,0.536254},
+  {-0.464799,-0.526058},
+  {-0.418575,-0.584390},
+  {-0.394190,-1.816489},
+  {0.225854,0.231993},
+  {-0.635186,-0.053889},
+  {-0.064877,-0.134776},
+  {-0.030140,0.052716},
+  {-0.548128,-0.690454},
+  {0.386017,0.089867},
+  {1.770913,0.146184},
+  {-0.245883,1.392924},
+  {-0.437879,0.537205},
+  {-0.330323,0.467750},
+  {0.586680,-1.393470},
+  {-0.120830,-0.437540},
+  {-0.963768,0.437445},
+  {0.330936,-0.667993},
+  {0.308680,-1.588304},
+  {0.825726,0.482044},
+  {0.226749,-0.379008},
+  {0.713663,0.392264},
+  {-0.364814,-1.242878},
+  {-0.029851,-0.845113},
+  {0.519322,-0.794357},
+  {0.118346,-1.295004},
+  {-0.992456,1.318909},
+  {-0.072580,-0.019761},
+  {-0.289738,1.767553},
+  {-1.316428,0.126071},
+  {1.683718,0.210909},
+  {1.611788,0.725453},
+  {0.165352,0.295910},
+  {2.416738,0.700021},
+  {0.526805,-0.148660},
+  {0.937490,-0.086265},
+  {0.818973,0.716807},
+  {1.269264,0.610734},
+  {0.966294,0.177897},
+  {-0.865904,0.933524},
+  {-0.204972,0.387884},
+  {1.036139,-0.352334},
+  {0.025383,0.301119},
+  {1.257758,-0.315413},
+  {0.678906,0.616848},
+  {1.169668,-0.413489},
+  {-0.307375,0.005018},
+  {0.073738,-0.187008},
+  {1.813125,-0.752193},
+  {1.392039,-0.785845},
+  {-0.643245,0.390684},
+  {0.463355,0.238971},
+  {-0.002376,-0.085880},
+  {-0.838524,1.114617},
+  {-0.367220,-0.351002},
+  {0.266690,-0.777264},
+  {0.192761,-0.720230},
+  {-1.500903,0.695838},
+  {0.493120,0.067029},
+  {0.030118,1.236780},
+  {0.034760,-0.819626},
+  {0.293606,0.201533},
+  {0.312385,1.481040},
+  {0.644201,-0.675942},
+  {-0.630559,0.140196},
+  {0.752821,0.626086},
+  {-0.310553,0.372922},
+  {0.511409,1.005211},
+  {-0.312640,1.205754},
+  {0.047365,1.161801},
+  {0.634709,0.848718},
+  {-0.185228,0.068916},
+  {0.710197,-0.424226},
+  {-0.627263,0.410260},
+  {-0.890694,1.019410},
+  {-0.911236,-0.507543},
+  {0.072052,-0.119403},
+  {0.277360,0.255984},
+  {0.011718,-0.365213},
+  {-1.242291,-0.359709},
+  {-0.266353,-0.290392},
+  {-1.193119,-0.901162},
+  {0.016134,-0.154263},
+  {-0.392536,-1.082696},
+  {0.997809,0.053994},
+  {-1.230871,-0.639927},
+  {0.753734,0.260376},
+  {-0.177411,-0.654997},
+  {-0.664207,-0.818289},
+  {0.558704,-0.173549},
+  {-0.456297,-0.523642},
+  {0.437174,0.603725},
+  {1.110922,0.929951},
+  {-1.145341,0.606142},
+  {0.762613,-0.534990},
+  {1.123318,0.182479},
+  {-0.924404,0.074693},
+  {0.421870,-0.803706},
+  {0.237068,-0.731789},
+  {0.114878,0.715037},
+  {-0.115797,0.490062},
+  {0.613808,-0.057239},
+  {-0.002727,0.385070},
+  {0.118135,-0.066553},
+  {-0.137414,-0.095722},
+  {0.241358,-0.096421},
+  {-0.514497,-0.904141},
+  {-0.484342,1.537877},
+  {-0.143724,0.510801},
+  {0.761716,0.162944},
+  {0.627842,-0.387618},
+  {-0.263134,-0.631088},
+  {0.435091,0.285372},
+  {-0.506864,1.600501},
+  {-0.514922,-0.416914},
+  {-0.127203,0.976581},
+  {-1.080020,-1.111665},
+  {0.197020,0.354050},
+  {1.494278,-0.024726},
+  {-0.547009,0.483956},
+  {-0.111064,-1.245961},
+  {-0.654196,-0.610226},
+  {0.233488,0.119793},
+  {-0.816235,-0.666550},
+  {-0.154340,0.061817},
+  {-0.949530,0.341751},
+  {0.045377,1.203108},
+  {0.430596,1.308333},
+  {-0.016732,-0.389215},
+  {0.399432,0.672581},
+  {0.459967,0.156065},
+  {-0.095913,-1.398591},
+  {-1.249649,-0.318145},
+  {0.584487,0.046164},
+  {0.523293,-0.263306},
+  {0.928685,-0.941009},
+  {-0.094772,1.143322},
+  {-0.647698,0.255648},
+  {-1.029936,0.187780},
+  {0.514449,1.421299},
+  {0.437990,-0.736063},
+  {-0.148725,-1.226925},
+  {0.735137,-0.988119},
+  {1.047799,-0.121534},
+  {-0.407426,0.264870},
+  {-0.700435,-1.115746},
+  {0.532253,0.835391},
+  {-0.713866,-0.766539},
+  {-0.594814,-1.583788},
+  {-0.091316,0.186157},
+  {-1.061280,0.790775},
+  {1.196936,-0.655124},
+  {0.138017,-0.110440},
+  {-0.482455,-0.535907},
+  {1.275872,-0.400182},
+  {-0.064806,0.484727},
+  {0.401664,-0.613058},
+  {-0.700481,-0.936574},
+  {0.532775,0.696085},
+  {1.008801,0.749932},
+  {-0.986396,-1.189219},
+  {-0.913639,0.371736},
+  {0.784265,-0.263053},
+  {-0.408200,-1.066935},
+  {-0.668052,-0.239838},
+  {-1.178900,-1.241531},
+  {-0.853686,0.295449},
+  {0.166123,-1.515813},
+  {-0.444517,0.062558},
+  {0.332299,0.329983},
+  {-1.982113,-0.485853},
+  {1.132998,-1.205220},
+  {-0.804666,0.302509},
+  {-0.238308,-0.134546},
+  {0.710908,-0.432452},
+  {0.315154,1.398999},
+  {-0.681044,0.872108},
+  {0.606473,0.523653},
+  {0.014945,0.278227},
+  {-0.139660,0.507999},
+  {0.589431,1.064057},
+  {1.203018,-0.095737},
+  {-0.706335,0.844312},
+  {-0.457733,0.411376},
+  {1.392476,0.615478},
+  {0.503531,0.629748},
+  {-1.868925,1.019854},
+  {0.623614,-0.097751},
+  {1.591276,-0.051853},
+  {-0.113714,0.458968},
+  {0.053809,-0.896137},
+  {0.828523,-0.324982},
+  {-0.897275,0.933097},
+  {1.465266,0.219218},
+  {-0.328468,-0.511827},
+  {-0.269574,0.240325},
+  {0.158350,-0.002023},
+  {0.007904,0.374705},
+  {-0.748152,-0.404403},
+  {0.401461,1.023925},
+  {-0.694375,0.165567},
+  {-0.750854,-0.441250},
+  {-0.732961,1.478016},
+  {-1.351355,-0.403812},
+  {1.015405,-0.641125},
+  {-1.187931,0.516955},
+  {0.356994,0.568579},
+  {-0.980631,-1.747832},
+  {0.841677,-0.390122},
+  {-0.341402,-0.520199},
+  {0.267459,0.114024},
+  {-0.241603,-0.232871},
+  {0.477839,0.132306},
+  {-1.470251,0.729433},
+  {0.041666,-1.683171},
+  {0.476142,0.743715},
+  {-0.601401,-0.980501},
+  {0.652458,-0.252309},
+  {0.456130,-0.278763},
+  {1.118120,0.633555},
+  {-0.749787,-0.239808},
+  {-0.104785,0.184428},
+  {0.669072,0.512814},
+  {-0.766815,-0.611725},
+  {0.264691,0.519192},
+  {0.723239,0.197053},
+  {0.208870,-1.040927},
+  {0.225315,1.672246},
+  {-0.292557,0.249723},
+  {0.028916,0.585265},
+  {0.095992,0.356909},
+  {-0.555301,-0.057219},
+  {-0.928637,-0.681245},
+  {-0.528215,0.113653},
+  {0.051210,-0.925710},
+  {-0.488349,-1.072004},
+  {0.388358,-0.829677},
+  {-0.440984,0.402262},
+  {-0.587779,0.415484},
+  {-0.854813,-1.202757},
+  {0.140449,0.615316},
+  {-0.969118,0.625102},
+  {0.723061,-0.023433},
+  {-0.466547,-1.193377},
+  {0.174382,-0.191844},
+  {-0.069412,0.744591},
+  {0.614304,0.878272},
+  {1.039704,-0.498006},
+  {-0.308974,0.145160},
+  {1.014526,-0.374036},
+  {0.252267,0.687180},
+  {-0.162024,-0.879458},
+  {-0.069318,-0.136461},
+  {1.084086,-0.626762},
+  {-0.337708,0.138883},
+  {-0.614793,0.495342},
+  {-0.313819,0.218629},
+  {-0.355789,-0.208860},
+  {1.264926,-0.581676},
+  {0.995574,1.298469},
+  {0.048826,1.154609},
+  {0.853013,0.154451},
+  {-0.288999,-0.321106},
+  {-0.313594,-1.063780},
+  {0.993070,0.561339},
+  {0.227798,1.300257},
+  {0.228511,1.096806},
+  {-0.206126,-0.606261},
+  {0.534751,1.086407},
+  {0.990795,-0.239272},
+  {-0.221983,-1.228456},
+  {-0.853842,-0.354515},
+  {-1.529191,-0.080374},
+  {0.510801,0.916183},
+  {-0.406386,0.535647},
+  {-0.894904,-0.543193},
+  {-0.238739,-0.062090},
+  {-0.888515,-0.567698},
+  {-0.480891,-0.205695},
+  {0.174172,-0.275572},
+  {-0.272541,0.816420},
+  {-2.017061,-0.971229},
+  {0.654095,-0.688792},
+  {-1.521416,-0.151355},
+  {-0.419304,-0.564373},
+  {-0.683359,-0.964495},
+  {0.191915,0.116535},
+  {-0.122173,0.698014},
+  {0.091031,0.996259},
+  {0.807417,-0.307397},
+  {0.503590,-0.560922},
+  {-0.025515,-0.177932},
+  {-1.471801,0.431103},
+  {-0.274382,-1.436026},
+  {0.410563,0.251427},
+  {-0.688289,0.531037},
+  {0.235751,-0.017373},
+  {1.697625,0.330051},
+  {1.296692,-0.008806},
+  {-0.161821,-1.267515},
+  {-0.157375,0.552060},
+  {0.194818,-0.498418},
+  {-0.803649,0.679683},
+  {-0.085934,0.145656},
+  {1.299868,-0.011962},
+  {-0.912591,-0.421947},
+  {1.145332,0.300821},
+  {0.269805,0.306810},
+  {-0.204528,-0.802886},
+  {-0.467310,0.023213},
+  {-0.143521,-0.064844},
+  {-0.615181,-0.550979},
+  {-1.849136,-0.009920},
+  {0.171609,-0.665812},
+  {-0.491934,0.882227},
+  {-1.650295,0.114048},
+  {-0.400294,0.424205},
+  {-0.514118,-0.669073},
+  {0.258922,0.794121},
+  {0.049997,0.134089},
+  {0.194488,-0.156671},
+  {0.344593,-0.056610},
+  {-0.065019,-0.791255},
+  {-0.712143,-0.889316},
+  {-0.037947,-0.410308},
+  {-0.608536,0.363014},
+  {-0.995931,0.748773},
+  {-0.532246,1.524272},
+  {-1.273984,-0.692641},
+  {0.216458,-0.969723},
+  {0.596969,1.207691},
+  {0.630096,0.619046},
+  {0.053170,0.680191},
+  {-0.316325,2.215220},
+  {-0.727683,0.614145},
+  {-0.426250,-0.833144},
+  {0.824881,-0.500053},
+  {-0.529623,0.311797},
+  {-0.178255,0.825478},
+  {0.103841,-0.104707},
+  {-0.031122,0.452810},
+  {-1.102562,-0.565139},
+  {0.562892,-1.009280},
+  {-0.990678,0.532690},
+  {0.780854,-0.558275},
+  {-0.797341,-0.248667},
+  {0.419113,0.984902},
+  {-0.373388,-0.223312},
+  {-0.219678,-0.502263},
+  {0.073586,-0.923303},
+  {0.462648,-0.208484},
+  {0.402837,1.456425},
+  {0.394849,0.801398},
+  {-0.032908,-0.398294},
+  {0.137910,0.005318},
+  {-0.388445,0.932065},
+  {-0.968678,0.568907},
+  {-1.168897,0.713647},
+  {-0.135803,0.675903},
+  {-0.798947,0.409210},
+  {-0.210345,0.474493},
+  {-0.996924,-0.261361},
+  {-0.376090,-0.169902},
+  {-0.084624,-0.337132},
+  {-0.149856,1.151486},
+  {-0.334993,-0.025083},
+  {0.014955,-0.281633},
+  {-0.296591,1.360250},
+  {-0.356625,-0.268706},
+  {0.092831,-0.664457},
+  {0.661417,1.101560},
+  {0.818075,-0.436305},
+  {0.257700,0.826407},
+  {-0.876984,-0.265632},
+  {-0.847009,0.983195},
+  {0.533962,0.025176},
+  {0.475236,-0.021672},
+  {-0.408513,0.144330},
+  {-0.054836,-0.056845},
+  {-0.811997,-0.428748},
+  {-0.041344,0.580983},
+  {-0.403695,1.106749},
+  {-0.782566,-0.126241},
+  {-0.164866,0.115952},
+  {-0.511490,-0.220781},
+  {0.758437,1.045866},
+  {1.585939,0.717827},
+  {0.198230,-0.423196},
+  {0.425990,0.760640},
+  {0.349586,0.560766},
+  {-0.394644,0.704755},
+  {0.816262,0.894866},
+  {0.669015,2.130989},
+  {0.400988,0.020291},
+  {0.271768,0.213246},
+  {0.677947,-0.681183},
+  {-1.418844,-0.062849},
+  {0.154916,-0.318327},
+  {-0.397071,2.104998},
+  {0.775958,-0.897373},
+  {-0.332711,0.107389},
+  {0.120366,-0.286305},
+  {0.329814,-0.271822},
+  {0.103319,-1.265877},
+  {-0.729148,1.209006},
+  {0.782576,-1.122029},
+  {-0.924092,-0.627575},
+  {-0.804932,-0.421433},
+  {0.344793,-0.265698},
+  {0.408639,0.540421},
+  {-0.154016,0.136751},
+  {-1.289312,0.562553},
+  {-0.541214,0.328546},
+  {0.113700,0.137387},
+  {-0.357670,0.284727},
+  {0.870838,-0.493262},
+  {-0.984308,-0.399538},
+  {0.156173,0.616735},
+  {0.558083,0.793972},
+  {-0.041236,-0.886977},
+  {-0.272831,-0.458041},
+  {0.720271,-1.299717},
+  {0.800746,-0.688169},
+  {0.003356,-0.488594},
+  {0.112341,1.180680},
+  {-0.404111,-0.185403},
+  {-1.132811,0.187327},
+  {0.278689,0.563330},
+  {-0.475478,0.253690},
+  {0.822805,-1.018580},
+  {-0.536317,-0.432998},
+  {1.196511,0.646342},
+  {0.248643,-0.351856},
+  {0.023010,0.801504},
+  {0.082477,0.227903},
+  {-0.739984,1.409377},
+  {-1.093346,0.284272},
+  {0.014437,0.797834},
+  {-0.231989,-0.756894},
+  {-0.324308,-0.373406},
+  {0.327255,0.165462},
+  {0.077915,0.976373},
+  {0.099804,-0.232398},
+  {-0.188951,-1.848099},
+  {-0.264076,0.299642},
+  {-0.249151,0.531139},
+  {-0.085369,0.191014},
+  {0.418407,0.643442},
+  {0.548592,-0.986217},
+  {0.201831,-0.013044},
+  {0.402804,0.414341},
+  {0.672157,-1.203954},
+  {0.095442,-0.174176},
+  {0.841303,-0.015891},
+  {-1.263681,-1.045229},
+  {0.761722,0.884349},
+  {-1.504885,-0.472921},
+  {-0.346331,0.174952},
+  {0.933591,0.149618},
+  {0.730042,-0.463471},
+  {-0.475737,1.006552},
+  {0.759548,-0.283706},
+  {0.157366,-1.489094},
+  {0.523688,0.334166},
+  {0.876784,0.002512},
+  {-1.026722,0.090503},
+  {-1.165607,0.169016},
+  {0.359693,-0.053239},
+  {0.215738,0.499053},
+  {-0.350342,0.196230},
+  {0.896169,0.062044},
+  {2.042446,-1.127256},
+  {-0.534803,-0.041073},
+  {-0.164018,0.930955},
+  {1.250713,0.249031},
+  {-0.869230,0.749397},
+  {0.340076,-0.429473},
+  {0.156416,-0.607349},
+  {-0.876436,0.247448},
+  {0.631910,-0.711511},
+  {-0.353926,0.595086},
+  {-0.317500,0.152275},
+  {0.016852,0.409049},
+  {0.138180,-0.897995},
+  {-1.043338,0.106864},
+  {0.249097,0.765102},
+  {-0.063449,-0.898102},
+  {-0.009991,0.423051},
+  {-2.479719,-0.472494},
+  {0.089759,0.324779},
+  {-0.425748,-0.136768},
+  {-0.039432,0.113546},
+  {0.378075,0.584178},
+  {-0.116790,-0.340992},
+  {1.409989,0.608333},
+  {0.185191,0.854648},
+  {0.148669,-0.916006},
+  {0.243601,-0.578485},
+  {0.534792,0.128748},
+  {0.096589,-0.011526},
+  {0.302454,-0.104072},
+  {0.557113,-0.581964},
+  {0.123224,0.084108},
+  {-0.040691,1.241659},
+  {-0.976656,-0.139564},
+  {0.461107,0.951388},
+  {-0.172467,-1.082873},
+  {-1.153675,-0.385351},
+  {-0.618565,0.103723},
+  {0.584970,-0.576273},
+  {-0.072267,0.632778},
+  {-1.229002,-0.083644},
+  {-0.398376,-0.960650},
+  {-0.182248,0.182768},
+  {0.047476,-0.416691},
+  {-0.006784,0.265975},
+  {0.197887,-0.503323},
+  {1.187192,-0.302236},
+  {-0.243130,-1.039109},
+  {-0.062329,0.768271},
+  {0.943091,0.735741},
+  {-0.034137,0.599684},
+  {-0.528197,-0.012226},
+  {-1.206841,0.534777},
+  {-0.136555,0.133648},
+  {-0.026909,-0.925145},
+  {0.545718,0.306186},
+  {0.019155,0.114856},
+  {0.108414,0.467932},
+  {-0.690591,0.822777},
+  {-0.784363,-0.578012},
+  {-0.355875,0.224161},
+  {1.082772,0.724638},
+  {0.259778,-0.690524},
+  {0.144948,-0.594185},
+  {-0.569524,-0.553273},
+  {0.951085,-1.238274},
+  {-0.334362,0.954367},
+  {0.270034,-0.455925},
+  {0.135168,0.992027},
+  {0.673968,-0.116692},
+  {1.150927,-0.985755},
+  {0.401896,-0.044726},
+  {-0.404015,0.215494},
+  {-0.874189,-0.310641},
+  {-1.076193,-1.010944},
+  {-1.077048,-0.032036},
+  {-0.059354,-0.173463},
+  {-0.218021,0.018288},
+  {-0.196944,-0.747249},
+  {0.734062,0.379284},
+  {1.158500,0.450099},
+  {-0.858797,0.229643},
+  {1.308480,-0.146091},
+  {-0.741501,0.254662},
+  {1.000943,0.157585},
+  {0.521755,-0.098708},
+  {0.086764,0.359042},
+  {-0.099892,0.739584},
+  {0.340750,-1.523697},
+  {-0.536943,1.085834},
+  {0.570584,0.105172},
+  {0.202618,-0.072868},
+  {-0.636440,0.211023},
+  {0.497984,0.587557},
+  {-0.110149,-1.306920},
+  {-0.679943,0.412284},
+  {-0.316334,-0.908325},
+  {-0.711702,1.541623},
+  {1.257867,0.108194},
+  {-0.642721,-0.461193},
+  {-0.358721,-0.241200},
+  {0.150649,-1.176602},
+  {-1.319244,0.289257},
+  {0.773558,0.096770},
+  {-0.827512,-0.185106},
+  {-0.040823,-1.803707},
+  {0.649424,-0.745211},
+  {1.254139,0.001556},
+  {0.329440,-0.291886},
+  {-0.640815,-0.162880},
+  {0.091218,1.039846},
+  {0.699821,-0.470335},
+  {-0.583234,-0.635644},
+  {0.819819,-1.751943},
+  {-0.721584,0.787984},
+  {-0.179237,0.328456},
+  {-0.063781,0.429699},
+  {1.631510,0.041000},
+  {0.122645,-0.926669},
+  {0.970309,-0.036087},
+  {-0.204184,-0.045486},
+  {-0.597965,0.889277},
+  {-0.564184,-0.344697},
+  {-1.064722,-1.138890},
+  {-0.751389,-0.391462},
+  {-0.024089,0.535480},
+  {-0.265461,0.383199},
+  {-0.504780,-1.007336},
+  {-1.021076,0.831820},
+  {0.141181,-0.805943},
+  {0.451375,0.655968},
+  {1.100952,0.897682},
+  {0.205680,-1.447828},
+  {-0.748725,0.229730},
+  {0.886689,-0.042364},
+  {-1.821520,-0.303140},
+  {0.697765,-0.619635},
+  {-0.046616,-0.261678},
+  {-0.207704,-0.328292},
+  {-0.534695,-0.547877},
+  {-1.575192,0.622682},
+  {0.469863,0.483822},
+  {-0.215089,1.552073},
+  {0.505524,-0.648942},
+  {0.262484,0.623770},
+  {0.427704,-0.562431},
+  {-0.872769,0.672559},
+  {-0.020422,-0.187349},
+  {1.243445,-1.678458},
+  {0.123213,-0.587475},
+  {0.071629,-0.272299},
+  {0.150438,0.166304},
+  {-0.278067,-0.782556},
+  {0.011738,-0.690190},
+  {0.881321,-0.960599},
+  {0.234258,-0.529572},
+  {-1.583603,-1.199128},
+  {0.394669,-0.930577},
+  {-0.358556,1.527559},
+  {-1.524935,-0.981286},
+  {-1.283556,0.168284},
+  {-0.071836,-0.156780},
+  {1.300191,1.006321},
+  {-1.238737,0.048229},
+  {-0.377324,-0.229504},
+  {1.099479,0.998962},
+  {-0.298661,-1.195932},
+  {-0.283137,-0.159995},
+  {0.098216,1.750651},
+  {-1.026856,0.639700},
+  {0.770303,0.037554},
+  {-0.190248,-0.145522},
+  {-0.674866,0.016212},
+  {-1.556569,1.310796},
+  {-0.417356,1.000320},
+  {1.292398,-0.862891},
+  {-0.666403,1.999084},
+  {0.359215,0.069716},
+  {0.347212,-0.033478},
+  {-0.378434,-0.364239},
+  {-0.177074,0.536678},
+  {0.665238,-0.817818},
+  {-0.050101,0.086105},
+  {0.402255,-0.348473},
+  {-0.108418,-0.286375},
+  {0.632875,-0.573563},
+  {-0.401028,-1.098233},
+  {-0.209670,-0.524291},
+  {1.161718,-0.018141},
+  {0.062103,0.583460},
+  {0.477218,1.102610},
+  {-0.467535,1.244971},
+  {-0.375225,-0.086564},
+  {0.628985,-0.808293},
+  {1.769568,-0.074081},
+  {-0.632422,0.452516},
+  {-0.080602,0.904194},
+  {-0.036578,0.987790},
+  {-1.059879,-0.224910},
+  {-0.942022,0.248616},
+  {0.604268,0.203433},
+  {0.511442,-0.200682},
+  {-1.007013,0.355784},
+  {-0.895393,-0.034260},
+  {-1.057717,1.382638},
+  {0.611742,0.856244},
+  {0.703185,-0.058025},
+  {-0.130182,-0.591155},
+  {0.638317,-0.190395},
+  {0.522978,-0.891479},
+  {-0.002451,-0.012145},
+  {-0.321576,0.154897},
+  {-1.017726,0.839232},
+  {0.275647,-0.836124},
+  {-0.118267,-0.695792},
+  {-2.185583,-0.392189},
+  {0.732423,-0.118374},
+  {0.884142,0.303615},
+  {-1.341810,-0.498593},
+  {-0.479942,-0.379985},
+  {0.111066,-2.027992},
+  {0.639038,-1.018160},
+  {0.123944,0.497292},
+  {-1.415298,-0.098769},
+  {1.108608,-1.269705},
+  {-1.101691,0.124200},
+  {0.442822,-0.443518},
+  {-1.122461,0.522937},
+  {-0.142504,-0.305149},
+  {-0.176067,-0.623792},
+  {-0.196882,0.715774},
+  {0.406265,0.244901},
+  {1.161033,0.506478},
+  {0.167092,-0.544898},
+  {-0.008688,-0.682775},
+  {-0.481234,-0.114580},
+  {-0.301007,-0.278349},
+  {0.839510,-0.084011},
+  {0.523550,0.618197},
+  {-1.485248,1.869149},
+  {-0.385724,0.172770},
+  {-0.388899,-0.581958},
+  {0.615073,-0.767256},
+  {0.695869,1.535576},
+  {-1.500226,-0.888290},
+  {-0.511725,0.657499},
+  {-0.738649,-0.437450},
+  {0.652296,-0.153666},
+  {-0.169144,-0.366049},
+  {-0.213299,0.312138},
+  {-0.862391,-0.179164},
+  {0.479733,1.023316},
+  {-1.704103,-0.974490},
+  {-0.348370,-1.488505},
+  {-1.099062,0.282122},
+  {-1.578280,-0.162824},
+  {-1.091052,0.744575},
+  {-0.515178,-0.044797},
+  {0.065343,0.960922},
+  {-0.051800,-0.142943},
+  {-0.117723,-1.467680},
+  {-0.643133,1.163677},
+  {-0.034072,0.261251},
+  {0.464990,-0.130008},
+  {0.133313,-1.401987},
+  {0.126248,0.450691},
+  {-0.003664,-0.323720},
+  {0.142170,-0.755157},
+  {-1.656898,-0.020361},
+  {-0.612778,0.036440},
+  {0.353884,-0.743228},
+  {-0.430287,-0.179029},
+  {0.625341,0.171575},
+  {1.016815,-0.257385},
+  {0.324956,-0.714199},
+  {-1.174736,-0.158217},
+  {-0.274466,-0.771165},
+  {-0.393455,-0.971745},
+  {-0.298555,0.790057},
+  {-0.646557,-1.558486},
+  {0.758193,0.973426},
+  {-0.512463,-0.785605},
+  {0.980556,-0.044524},
+  {0.453143,0.624350},
+  {1.147269,0.020674},
+  {-0.501269,-0.404065},
+  {-0.244718,-0.507250},
+  {0.770791,0.097876},
+  {0.244499,-0.019047},
+  {-0.727271,-1.001762},
+  {-0.366096,-0.511113},
+  {0.479774,0.574401},
+  {0.917365,-0.129024},
+  {-0.745295,-0.245488},
+  {0.745051,1.034707},
+  {0.810366,-0.847422},
+  {0.235447,0.300914},
+  {-0.708897,-0.941699},
+  {0.309677,-1.041238},
+  {-0.081649,0.128611},
+  {0.844397,0.010619},
+  {-1.009033,0.934418},
+  {1.144116,0.074744},
+  {-0.057235,-0.308853},
+  {0.360603,0.036429},
+  {0.830911,-0.450962},
+  {-0.194946,-0.151025},
+  {-0.211182,0.118259},
+  {0.021337,0.332110},
+  {0.129465,-0.225661},
+  {-1.052171,-0.755217},
+  {0.633623,-0.177776},
+  {0.100743,-0.704954},
+  {-0.818968,1.180590},
+  {-0.535346,-0.545943},
+  {-0.006770,0.316309},
+  {0.775806,0.533149},
+  {0.339163,0.050466},
+  {0.318535,-0.074793},
+  {-1.297398,-0.351562},
+  {-0.772665,1.015512},
+  {0.295548,-0.180960},
+  {-0.044699,-0.203172},
+  {0.724933,-1.023951},
+  {-0.167979,-0.725819},
+  {0.686506,0.268161},
+  {-0.480277,-0.221435},
+  {-0.056920,0.480959},
+  {0.030116,-0.272789},
+  {-0.302421,0.129490},
+  {-1.671242,0.181529},
+  {-0.281706,-0.333536},
+  {0.016290,-0.028753},
+  {-0.259901,-0.190484},
+  {0.289524,-0.195349},
+  {-1.337980,0.540319},
+  {0.661628,-0.670418},
+  {0.599796,0.557768},
+  {0.580559,0.969807},
+  {0.031230,0.964814},
+  {0.198048,0.444485},
+  {0.578456,-0.883133},
+  {0.624222,1.329692},
+  {-0.625168,-0.127331},
+  {-0.017311,1.164091},
+  {-0.621783,-0.446638},
+  {0.701142,-0.309340},
+  {-1.057874,-0.834624},
+  {0.346678,-1.338687},
+  {0.667874,-0.522838},
+  {-1.028893,-0.504854},
+  {-1.338328,-0.931585},
+  {0.287635,0.120742},
+  {0.230818,0.167010},
+  {-0.328503,-0.748337},
+  {-0.255351,0.964045},
+  {0.510160,-1.611867},
+  {0.223958,-0.860844},
+  {0.239175,-0.837760},
+  {1.266567,-0.125655},
+  {0.582400,0.156299},
+  {0.251579,-1.778354},
+  {0.650474,0.028121},
+  {0.993767,-0.090186},
+  {0.441591,-0.361052},
+  {-1.413507,0.317850},
+  {0.334364,-0.332911},
+  {-0.010362,-0.177608},
+  {0.014458,-0.502127},
+  {-0.919481,-1.160841},
+  {-0.443414,0.552915},
+  {-0.054788,-1.052794},
+  {-0.561902,0.153077},
+  {-0.677469,-0.159762},
+  {0.650310,-0.922686},
+  {0.296712,0.812605},
+  {-0.294342,0.055605},
+  {-0.535585,-1.384576},
+  {-1.433487,-0.747544},
+  {0.645626,-0.741622},
+  {0.920579,-0.258878},
+  {0.169646,0.529906},
+  {0.674057,0.410030},
+  {-0.351663,0.199608},
+  {-0.339342,-0.416492},
+  {-0.271758,1.138671},
+  {0.224929,-1.327320},
+  {0.601037,1.033542},
+  {-0.193132,-0.768238},
+  {0.364633,-0.653041},
+  {0.783166,-0.809904},
+  {0.559880,0.350413},
+  {0.615788,-0.237848},
+  {0.236813,-0.842202},
+  {0.031135,-0.661401},
+  {0.349296,-0.774153},
+  {1.759036,-0.724450},
+  {-0.116563,0.294276},
+  {0.375200,-1.357901},
+  {-1.029118,1.305234},
+  {0.497985,-0.464184},
+  {-0.295867,-0.349915},
+  {0.221068,-0.835466},
+  {-0.838100,0.275901},
+  {-1.020066,0.277497},
+  {1.091145,0.328918},
+  {0.327124,0.702349},
+  {-0.476125,0.304774},
+  {0.520932,0.875467},
+  {-1.726524,1.028699},
+  {0.060615,0.113976},
+  {0.297927,1.293605},
+  {-0.405591,0.650445},
+  {0.037677,-0.734049},
+  {-0.565393,0.943537},
+  {0.910424,-0.580765},
+  {0.493416,-0.962297},
+  {0.956024,0.716498},
+  {0.474440,0.623715},
+  {-0.922501,-0.564992},
+  {-0.794655,0.719802},
+  {0.596664,-0.091353},
+  {-1.236730,0.412576},
+  {-0.041676,0.394763},
+  {0.786846,0.085198},
+  {1.051734,-0.257630},
+  {-0.906726,-1.590711},
+  {0.362094,-1.386569},
+  {0.148797,-0.901821},
+  {-0.736306,0.417423},
+  {0.329381,-0.221941},
+  {0.009126,0.513875},
+  {-1.192236,0.638637},
+  {-0.317820,0.575279},
+  {1.586186,-0.027898},
+  {-0.025386,0.094059},
+  {-0.315796,-0.838576},
+  {0.030063,-0.320087},
+  {0.534822,0.130995},
+  {0.477222,-0.398652},
+  {-0.913466,-0.563169},
+  {-0.823684,-0.189615},
+  {-0.213996,0.665743},
+  {0.654202,0.146227},
+  {-0.004974,0.257017},
+  {-0.024927,-0.214095},
+  {-1.045988,0.681355},
+  {0.146436,0.294438},
+  {1.089600,-0.127405},
+  {0.798004,0.931002},
+  {-0.505832,0.828742},
+  {0.361348,-0.830710},
+  {-0.305041,1.032923},
+  {-0.728657,-0.579665},
+  {0.517347,-0.452207},
+  {0.879566,-0.278807},
+  {-0.124969,-0.036169},
+  {0.628951,-0.089218},
+  {-0.603025,-0.528341},
+  {0.019535,1.501341},
+  {0.881593,0.143029},
+  {-0.231925,-0.097508},
+  {0.538676,0.300952},
+  {-0.127155,0.296466},
+  {-0.274248,0.005941},
+  {1.500761,-0.345010},
+  {-0.907824,1.044908},
+  {0.414848,1.043371},
+  {-0.867983,-0.304333},
+  {0.044936,0.571416},
+  {-0.266616,0.376188},
+  {0.878846,0.549724},
+  {-0.170746,0.362205},
+  {0.160919,0.167739},
+  {0.462195,0.540838},
+  {-0.875388,-0.096774},
+  {0.307478,-0.185363},
+  {-0.181949,0.313114},
+  {-0.085873,-0.399748},
+  {-0.129085,1.140098},
+  {-0.252383,0.086665},
+  {0.189609,-1.301528},
+  {0.382798,0.498417},
+  {-0.506249,-0.317346},
+  {-1.212357,0.230474},
+  {0.474321,0.181404},
+  {0.681870,-0.999781},
+  {0.607469,-0.406532},
+  {0.622035,-0.522596},
+  {0.227928,0.106501},
+  {-0.379127,-0.283975},
+  {0.139899,-0.090042},
+  {0.672276,-0.271219},
+  {-0.234798,-0.982539},
+  {0.475426,-0.896914},
+  {-0.325514,0.546342},
+  {0.437787,0.300656},
+  {-0.625297,-0.525772},
+  {-0.061169,0.198968},
+  {-0.094667,0.112590},
+  {0.786903,0.717350},
+  {-0.109661,-0.225045},
+  {0.186298,-1.271786},
+  {-0.369875,0.986481},
+  {0.689748,-0.439040},
+  {-0.965116,-0.848020},
+  {0.656998,-2.318079},
+  {0.002981,0.218055},
+  {-1.189818,0.355672},
+  {0.584073,-1.050715},
+  {-0.108002,-0.588069},
+  {-0.313385,0.621555},
+  {-0.889104,-0.082471},
+  {-0.769348,1.617374},
+  {-1.728674,1.396468},
+  {-0.616521,1.370656},
+  {-1.249198,0.309463},
+  {0.189456,-0.979952},
+  {-0.118186,1.507419},
+  {0.747125,0.309914},
+  {-0.614646,1.308353},
+  {0.333443,-1.419442},
+  {-1.700063,0.680655},
+  {0.266295,0.063078},
+  {-1.331327,0.169856},
+  {0.242049,-1.531715},
+  {0.960667,-0.302137},
+  {-0.061825,0.429394},
+  {-0.329970,0.278702},
+  {0.410208,1.176057},
+  {-0.789042,-0.174484},
+  {-0.238696,-0.184614},
+  {0.602804,0.051704},
+  {-0.633642,0.103324},
+  {0.065643,-0.546136},
+  {-0.339235,-0.673524},
+  {-0.315448,-0.300233},
+  {-0.864395,0.215781},
+  {0.254565,0.459681},
+  {-0.723593,1.270257},
+  {-0.583801,0.838345},
+  {-0.808536,-0.416249},
+  {-0.053534,0.820439},
+  {0.798705,-0.418082},
+  {1.776613,-1.110952},
+  {0.366472,0.636865},
+  {0.324757,0.701457},
+  {-0.036684,0.112409},
+  {-0.877729,0.003873},
+  {-1.084160,-0.401799},
+  {-0.008295,0.326360},
+  {0.787213,-0.261947},
+  {0.836987,-0.392854},
+  {0.275954,0.382297},
+  {-0.690174,0.027938},
+  {-0.374934,0.437628},
+  {-0.759869,0.360720},
+  {-0.638815,0.093196},
+  {0.189722,-0.218160},
+  {-0.454777,-1.027413},
+  {1.236142,0.310097},
+  {0.477871,-0.594035},
+  {-0.124788,-0.108431},
+  {0.544631,0.996734},
+  {-0.496622,-0.463029},
+  {0.625047,0.069807},
+  {0.557384,0.060492},
+  {-0.265568,-1.409334},
+  {0.239741,0.259396},
+  {0.904890,-0.068242},
+  {-0.744938,0.163030},
+  {-0.471091,-0.345572},
+  {-0.273164,0.370181},
+  {0.729318,1.531839},
+  {-0.726184,-0.223504},
+  {0.242483,0.053784},
+  {-0.205845,-0.562647},
+  {-2.151637,-0.069466},
+  {-0.846446,0.795935},
+  {1.110915,-0.399958},
+  {0.489046,-0.556660},
+  {0.205667,0.176983},
+  {0.328136,0.200920},
+  {0.527322,0.191632},
+  {1.546037,-0.657550},
+  {-0.310488,0.301548},
+  {0.585276,0.957516},
+  {0.128524,0.840981},
+  {0.018146,1.407488},
+  {-1.516386,0.228783},
+  {0.124218,-0.156492},
+  {0.265637,0.315627},
+  {-1.063782,-0.367510},
+  {0.827797,0.276360},
+  {1.960161,-1.227262},
+  {0.806068,1.260862},
+  {0.373849,-0.276127},
+  {-0.498184,-0.462535},
+  {-0.077592,0.327073},
+  {0.588710,-0.430273},
+  {-0.905723,-1.065033},
+  {-0.016188,-0.290291},
+  {-0.109620,0.477222},
+  {0.565824,-0.470857},
+  {0.705157,0.606991},
+  {0.614145,-0.049931},
+  {-0.031315,-0.632364},
+  {0.072033,-0.559342},
+  {0.458793,1.387290},
+  {0.206636,0.224213},
+  {-0.392240,-0.854508},
+  {-0.839329,1.695036},
+  {0.566507,-0.629087},
+  {0.370644,-1.070375},
+  {0.761916,-0.623349},
+  {0.602129,0.418224},
+  {0.790301,-0.310664},
+  {1.481982,0.146058},
+  {-1.573813,0.024454},
+  {0.567915,-0.336681},
+  {-0.639597,0.182668},
+  {1.260436,2.207508},
+  {0.696288,0.181341},
+  {0.376110,0.431512},
+  {-0.000551,0.056281},
+  {0.402438,-0.361156},
+  {0.072172,0.279490},
+  {-0.885060,-0.641645},
+  {1.385817,0.885361},
+  {0.690711,-0.158455},
+  {-0.960198,-0.182059},
+  {0.321308,0.180684},
+  {0.147669,-0.549752},
+  {-0.107020,0.306074},
+  {0.174252,0.899434},
+  {0.061913,-0.189282},
+  {1.102905,-1.250777},
+  {0.223198,-0.637361},
+  {-2.146420,0.173387},
+  {-0.084436,-0.775938},
+  {0.287327,0.446614},
+  {1.090236,0.383949},
+  {1.121181,0.127876},
+  {0.103766,0.991675},
+  {1.242702,0.272046},
+  {1.008926,-0.211179},
+  {-1.353983,-0.705201},
+  {-1.661310,0.179906},
+  {-0.572442,0.843940},
+  {0.534838,-0.420940},
+  {1.906158,1.102764},
+  {-0.553360,-0.478077},
+  {-0.636383,-1.315762},
+  {-1.124395,0.081685},
+  {0.220542,0.468091},
+  {-1.229590,-0.659073},
+  {-0.564517,0.239986},
+  {-1.172267,-0.314597},
+  {0.151538,0.149107},
+  {0.242211,-0.821363},
+  {0.254545,0.273831},
+  {-0.534100,-0.226399},
+  {1.163542,-0.942243},
+  {1.041018,0.317274},
+  {-0.401554,-0.096105},
+  {-0.113999,-0.117513},
+  {-0.010346,-0.748131},
+  {0.354813,0.636504},
+  {-0.681541,-0.112983},
+  {-0.488145,0.464117},
+  {-0.193164,0.061733},
+  {-0.192093,-0.321730},
+  {0.509883,0.382645},
+  {-1.403973,-0.336215},
+  {0.394349,-0.205158},
+  {0.391611,-0.502082},
+  {0.616434,-0.022915},
+  {0.804218,-0.495715},
+  {-0.079753,0.070374},
+  {0.341990,-0.635143},
+  {0.067861,-0.236447},
+  {-1.101606,-0.120961},
+  {0.442884,-0.438436},
+  {0.212980,0.309736},
+  {0.528495,-0.251375},
+  {-0.692353,-0.169402},
+  {0.562221,-0.028760},
+  {0.590351,0.405250},
+  {-0.717372,0.369161},
+  {-0.806613,0.504272},
+  {0.286954,1.111197},
+  {-0.105423,-0.153474},
+  {-0.346757,-1.116428},
+  {0.226199,-0.504658},
+  {0.004135,-0.101712},
+  {-0.040985,-0.512184},
+  {-0.022114,-0.025237},
+  {-0.334621,-0.134380},
+  {0.534726,-0.729250},
+  {-0.282945,-0.576566},
+  {-0.931037,0.047644},
+  {1.365371,-0.644779},
+  {0.168399,-1.211458},
+  {2.486020,-1.456800},
+  {-0.004467,-0.574279},
+  {-0.401257,1.031333},
+  {0.424854,0.679751},
+  {-0.360869,-0.836076},
+  {-0.349323,1.100520},
+  {0.126475,0.711401},
+  {-0.075597,1.820855},
+  {-1.746648,1.113080},
+  {-0.153525,-0.544782},
+  {-0.533184,-0.693391},
+  {-0.769927,-0.582211},
+  {-0.680363,0.216778},
+  {-0.004214,-1.526735},
+  {-0.086907,-0.002847},
+  {0.232166,-0.016912},
+  {0.817197,0.482386},
+  {-1.105532,0.491655},
+  {-0.376338,0.410127},
+  {1.042417,0.054103},
+  {-0.241349,-0.748510},
+  {-0.014625,-0.417149},
+  {0.738367,0.443956},
+  {-1.044035,0.497683},
+  {0.292520,-0.751995},
+  {-0.217407,0.722108},
+  {0.918647,-0.718313},
+  {-0.164316,0.409743},
+  {1.309759,0.090394},
+  {0.233709,-0.815158},
+  {-0.239462,0.605397},
+  {-0.039005,-0.027079},
+  {-0.954133,-0.096347},
+  {1.816169,0.521655},
+  {0.153716,-0.328576},
+  {0.835515,-0.359370},
+  {-0.705611,-0.523065},
+  {0.138570,-0.063344},
+  {0.083846,-0.023266},
+  {-0.562762,-0.812709},
+  {0.365173,-0.859163},
+  {0.578421,-0.182048},
+  {-0.126089,1.117181},
+  {0.617319,-1.086710},
+  {0.769929,0.422361},
+  {-1.309781,1.172984},
+  {-0.596821,-0.251837},
+  {0.212351,-0.811837},
+  {-0.162098,-0.192380},
+  {-0.813093,1.121627},
+  {0.256762,0.936857},
+  {-0.875631,1.008870},
+  {0.247567,0.868075},
+  {0.971357,-0.738473},
+  {-0.226325,0.330532},
+  {-0.162002,0.916161},
+  {-0.400712,1.001422},
+  {0.074112,1.112345},
+  {0.860980,0.266196},
+  {0.395444,-0.557019},
+  {0.120734,-1.186860},
+  {0.556697,0.066680},
+  {0.854588,0.178589},
+  {2.451387,-1.403948},
+  {0.227316,0.024298},
+  {0.591620,0.075444},
+  {0.200034,0.061233},
+  {0.482442,-0.836773},
+  {1.044504,0.162091},
+  {0.928003,-0.484096},
+  {0.382501,-0.191498},
+  {-0.375135,0.607373},
+  {-0.736591,0.301910},
+  {0.174839,-0.142515},
+  {0.733383,0.997919},
+  {-0.786136,-1.067298},
+  {-0.206222,-0.113384},
+  {-0.464171,0.094194},
+  {-1.350080,-0.791223},
+  {-1.126134,-0.116062},
+  {-0.208917,-1.109539},
+  {-0.370726,-0.057655},
+  {-0.091744,-1.090501},
+  {-0.208418,0.132989},
+  {0.864632,-0.798601},
+  {1.102361,1.368734},
+  {-0.272215,-0.247604},
+  {-1.023085,-0.986586},
+  {-0.065967,0.605997},
+  {0.063587,-0.976618},
+  {-0.267152,-0.116898},
+  {-0.461969,-0.203471},
+  {-0.573852,0.570464},
+  {-0.138348,0.534036},
+  {-0.090592,0.936618},
+  {0.850179,-0.537120},
+  {-0.433713,-0.556356},
+  {-0.537237,-0.713364},
+  {0.426253,-0.478599},
+  {1.133750,-0.964272},
+  {-1.331896,0.116871},
+  {0.191830,0.696149},
+  {-0.109898,-1.447008},
+  {0.959592,0.346543},
+  {0.261532,-0.822086},
+  {0.303775,-1.459434},
+  {0.530404,0.421720},
+  {-0.453037,-1.463699},
+  {0.123500,0.017147},
+  {0.172476,-0.507657},
+  {-0.160135,1.263925},
+  {0.030836,0.556500},
+  {-0.185416,-0.025333},
+  {0.637640,0.395256},
+  {0.089760,-0.864083},
+  {0.577483,1.581489},
+  {0.979522,1.296548},
+  {-0.497799,-0.045689},
+  {-0.047660,1.066061},
+  {0.048446,-1.060159},
+  {-0.968548,-0.221439},
+  {1.484060,0.378410},
+  {-0.770293,-0.087204},
+  {-0.764451,-0.554893},
+  {0.348932,-0.676770},
+  {-1.210537,0.339603},
+  {0.924898,-0.536966},
+  {-1.159727,-0.216140},
+  {-0.625226,-0.977963},
+  {0.640809,0.919168},
+  {-0.239144,0.785286},
+  {0.809998,0.679827},
+  {0.397941,-0.337279},
+  {1.158469,-0.284939},
+  {0.740868,-0.632110},
+  {0.246451,0.582746},
+  {1.169569,-0.447871},
+  {-0.206093,-0.436712},
+  {1.593053,-0.562783},
+  {-0.072116,-1.390822},
+  {0.534517,-0.038637},
+  {0.034689,0.141429},
+  {0.474386,0.514105},
+  {0.572791,-0.330251},
+  {-0.548599,-0.594569},
+  {-1.071301,-0.270923},
+  {0.486895,0.652847},
+  {-0.069770,1.249662},
+  {-0.040552,-0.687992},
+  {-0.284734,0.643650},
+  {-0.808577,0.013167},
+  {-0.452947,0.353593},
+  {-0.729562,-2.012804},
+  {1.237631,-1.264824},
+  {0.110039,1.404809},
+  {0.107938,-0.296577},
+  {0.386214,-0.709940},
+  {1.137573,0.606987},
+  {0.412215,-0.555525},
+  {-1.988232,-0.162112},
+  {0.848561,0.408090},
+  {-0.811612,0.394181},
+  {0.485756,-0.746334},
+  {0.049115,-0.087741},
+  {-1.022135,-0.921590},
+  {-0.633999,0.061617},
+  {-0.090648,0.618570},
+  {-1.247020,-0.001903},
+  {-0.421031,-0.238286},
+  {0.711286,-0.314523},
+  {-0.147505,-0.383916},
+  {-0.683990,0.445952},
+  {0.432133,-0.119312},
+  {-1.132072,-0.396738},
+  {0.135841,0.222292},
+  {-0.230532,0.331470},
+  {0.254731,-0.376331},
+  {-0.776682,0.039871},
+  {-1.169703,-0.331153},
+  {-0.873728,0.067719},
+  {-0.207084,-0.835310},
+  {0.037790,-0.362456},
+  {0.583451,1.129280},
+  {-0.558111,-0.573604},
+  {0.856679,-0.022411},
+  {0.164767,0.141428},
+  {-0.009111,-0.317562},
+  {1.150656,1.264776},
+  {-0.789474,0.292994},
+  {-0.466256,0.131396},
+  {-0.773386,0.095435},
+  {-0.310801,0.037979},
+  {0.426976,0.983285},
+  {0.477342,0.671231},
+  {0.453581,0.460922},
+  {-0.126415,0.223835},
+  {-0.197906,-0.189931},
+  {-0.526443,0.635295},
+  {-0.729339,-0.271754},
+  {-0.277572,-0.106432},
+  {0.605958,0.268731},
+  {0.697244,-0.324635},
+  {-0.601406,0.750119},
+  {2.020241,-0.455436},
+  {-0.545556,-1.777371},
+  {-0.106454,-0.323364},
+  {0.730151,-0.521349},
+  {-0.222232,-0.678729},
+  {-0.822648,0.759164},
+  {0.347482,0.318147},
+  {0.320443,1.047896},
+  {-0.007527,-0.099273},
+  {-0.469680,0.811059},
+  {-0.725923,0.045348},
+  {-0.845127,0.408992},
+  {-0.483176,-0.402357},
+  {-0.244242,-0.138255},
+  {0.777707,0.361076},
+  {-0.284361,-1.213446},
+  {-0.005269,1.151649},
+  {-0.132040,-0.605975},
+  {-0.614343,0.207020},
+  {0.172750,1.326225},
+  {-0.902838,0.195327},
+  {0.343014,-0.865008},
+  {0.125967,0.451258},
+  {0.332072,0.614969},
+  {-0.298182,0.490626},
+  {1.424204,-0.479491},
+  {-0.031385,0.164505},
+  {0.233636,-1.315612},
+  {-0.450889,0.377407},
+  {0.029363,0.410567},
+  {0.306058,0.200634},
+  {-1.349288,0.431649},
+  {0.358784,0.047745},
+  {-0.557686,1.348221},
+  {-0.061715,-0.056931},
+  {-0.363172,0.195052},
+  {-0.657930,-0.139592},
+  {-0.228460,0.043261},
+  {-0.400956,-0.445312},
+  {-0.518420,0.120859},
+  {-0.698407,-1.044712},
+  {1.235472,1.348407},
+  {0.487842,0.303364},
+  {-0.723742,0.780963},
+  {-0.593303,-0.225305},
+  {-0.534609,0.308384},
+  {0.517702,0.592656},
+  {0.954708,0.946876},
+  {0.138369,0.042618},
+  {-0.011117,0.156468},
+  {0.129045,-0.782424},
+  {0.544442,-0.335302},
+  {0.100454,0.021699},
+  {-0.414913,-0.364941},
+  {-1.446169,0.180437},
+  {-0.104807,-1.198166},
+  {-0.663552,0.253006},
+  {-0.873757,0.653705},
+  {0.913861,0.776582},
+  {0.408304,-0.209211},
+  {-0.292234,0.935191},
+  {0.612411,0.506772},
+  {0.052624,-0.170316},
+  {-0.316935,0.099714},
+  {-0.353097,0.013558},
+  {1.233948,0.295996},
+  {0.369796,0.587798},
+  {-0.240517,-0.082754},
+  {0.456761,1.042474},
+  {-0.213108,0.167637},
+  {0.399378,-1.139074},
+  {0.884318,-0.559808},
+  {1.445237,-0.362312},
+  {0.116480,1.022887},
+  {-1.064627,-0.325939},
+  {0.517946,-0.548647},
+  {0.415227,0.031714},
+  {0.100481,-0.138348},
+  {-0.809183,-0.296851},
+  {0.780624,1.262479},
+  {0.563065,-0.043795},
+  {0.912444,-0.494706},
+  {-0.734037,0.870375},
+  {-0.318819,1.118381},
+  {-0.000746,-0.287874},
+  {-1.164864,-0.526955},
+  {0.294943,0.563007},
+  {-0.310269,0.305960},
+  {-0.477327,-0.723869},
+  {1.444745,0.187725},
+  {1.871817,-0.263160},
+  {-0.194735,0.555531},
+  {-0.321051,-0.730174},
+  {-0.190988,-0.402861},
+  {-0.471553,-0.864754},
+  {0.858125,-1.345250},
+  {-0.616872,0.087958},
+  {1.283791,0.027641},
+  {0.256228,-1.305667},
+  {0.135487,-0.829405},
+  {-1.326564,0.237115},
+  {-0.150936,0.123060},
+  {0.525275,-1.201838},
+  {0.345162,-0.254455},
+  {-0.289832,-0.377094},
+  {-0.152667,-0.439359},
+  {-1.044104,-0.312180},
+  {0.123564,0.909003},
+  {0.092452,-0.627863},
+  {-1.077986,0.652712},
+  {0.546415,0.317801},
+  {-0.327865,0.791680},
+  {-0.742691,0.429484},
+  {1.359870,0.653960},
+  {0.618629,-0.810634},
+  {-1.486101,-0.628531},
+  {0.594045,-0.133495},
+  {-0.470586,0.135156},
+  {-0.143237,-0.465263},
+  {-1.088628,0.943733},
+  {0.198579,-0.639867},
+  {-0.063074,-0.021058},
+  {0.108028,0.446404},
+  {1.189162,0.613968},
+  {0.337471,-1.129207},
+  {-0.455311,0.326954},
+  {-0.570540,-1.907149},
+  {-0.314445,0.220247},
+  {-0.644406,0.871505},
+  {-0.516263,0.822251},
+  {-0.557629,-0.170696},
+  {0.722273,-0.131339},
+  {0.230421,0.790328},
+  {-0.104488,-1.716517},
+  {-1.241919,0.455016},
+  {-0.692486,1.120817},
+  {1.549314,-0.046370},
+  {-0.106043,0.644970},
+  {-0.074406,-0.804419},
+  {0.548174,0.128521},
+  {-0.595960,-0.462357},
+  {0.142829,-0.219578},
+  {-0.162097,-0.875243},
+  {0.686753,0.775003},
+  {0.873880,1.383881},
+  {-0.653841,0.636136},
+  {0.383632,-0.777116},
+  {-1.108266,0.038942},
+  {0.971520,0.211922},
+  {-0.268643,0.730017},
+  {0.855520,0.049969},
+  {0.302034,-0.524310},
+  {-0.852706,-0.537224},
+  {-0.804297,-0.114715},
+  {-1.478564,-0.084384},
+  {-0.408535,0.423840},
+  {-0.168721,-0.141810},
+  {0.077383,0.243237},
+  {-1.559434,1.191402},
+  {1.022154,-0.100324},
+  {0.323561,0.469589},
+  {-0.663531,0.640213},
+  {0.554019,1.763611},
+  {1.013954,-0.099589},
+  {-0.768361,0.429501},
+  {-1.056947,-0.854475},
+  {0.199817,-1.902227},
+  {-0.070703,-0.504816},
+  {-0.936270,0.009265},
+  {0.151126,-0.507320},
+  {-0.504326,0.276844},
+  {-0.314265,1.314549},
+  {0.326736,-0.579350},
+  {0.592561,-0.964175},
+  {-0.223907,-0.829707},
+  {-0.401792,-0.560375},
+  {0.302453,-0.641377},
+  {0.179660,0.273186},
+  {-0.093790,-1.403175},
+  {-0.547478,-0.365566},
+  {-1.082055,-0.079541},
+  {0.493591,0.675680},
+  {0.488427,0.562525},
+  {0.214921,0.219073},
+  {1.036597,-0.145378},
+  {-0.027255,-0.113060},
+  {0.673240,0.620677},
+  {0.723878,-0.899601},
+  {0.069137,-0.059731},
+  {0.241888,0.932147},
+  {0.990557,0.522072},
+  {0.333210,-0.429499},
+  {0.416918,0.495753},
+  {-0.659767,-0.994323},
+  {0.616175,0.547587},
+  {1.096390,0.648779},
+  {1.512614,1.140619},
+  {-0.038962,-1.035122},
+  {-1.083694,-0.279680},
+  {0.614096,0.432151},
+  {-0.347563,0.062973},
+  {1.386988,-0.035997},
+  {0.327510,-0.207868},
+  {-1.183518,-1.737384},
+  {-0.208895,1.406995},
+  {0.663338,-0.017747},
+  {-0.897272,-0.573788},
+  {0.942633,-0.547325},
+  {-0.099388,-0.254556},
+  {-0.201353,0.644556},
+  {0.866075,-0.228444},
+  {0.946155,-0.216844},
+  {-0.253558,0.114459},
+  {0.715896,0.743102},
+  {-0.359932,0.276616},
+  {-0.210247,-0.083149},
+  {0.802847,0.140860},
+  {0.408994,0.029881},
+  {0.377356,0.319152},
+  {-0.372690,-0.245271},
+  {0.676166,0.109436},
+  {0.724096,0.333436},
+  {0.221166,0.187551},
+  {-0.391584,0.738071},
+  {0.005351,0.778829},
+  {-0.358326,0.932486},
+  {0.490539,0.803589},
+  {-1.940728,-0.191677},
+  {0.344834,0.501654},
+  {0.800213,0.523732},
+  {0.582049,-0.075948},
+  {-0.161980,0.485703},
+  {-0.259158,-0.582118},
+  {1.062836,0.273222},
+  {-0.778178,0.190672},
+  {0.714527,-1.538556},
+  {-0.396795,0.449148},
+  {-0.781750,0.953574},
+  {-0.338389,-0.501176},
+  {-0.641856,-0.054484},
+  {0.563696,-0.904985},
+  {-0.099391,1.184931},
+  {-0.112808,0.108574},
+  {0.646080,0.427004},
+  {0.212517,0.155965},
+  {0.535560,-0.571720},
+  {0.553376,-0.294148},
+  {-1.607834,-0.184165},
+  {-1.547767,0.680574},
+  {0.781165,0.154537},
+  {0.560969,0.631483},
+  {0.495580,1.820957},
+  {0.007403,-0.213880},
+  {-0.133441,0.263800},
+  {-0.539947,-1.040542},
+  {0.451911,-0.153928},
+  {0.637194,0.419776},
+  {1.273621,1.299122},
+  {-0.212328,0.126958},
+  {-0.797461,1.644603},
+  {-0.122874,1.002433},
+  {0.531739,1.435631},
+  {-0.292445,0.088739},
+  {0.116979,0.506073},
+  {0.300921,-0.773498},
+  {-0.001333,-0.556370},
+  {-0.895409,0.437721},
+  {0.917279,0.508782},
+  {-0.491002,0.775053},
+  {0.198360,-0.494544},
+  {-0.466188,0.389353},
+  {1.026724,0.378360},
+  {0.554313,0.153011},
+  {2.109013,0.702959},
+  {-1.076990,-0.126220},
+  {-0.628257,-0.250837},
+  {-0.360120,-0.713433},
+  {0.323767,-0.526853},
+  {0.618992,0.232543},
+  {0.680284,-0.239604},
+  {-0.469444,0.121707},
+  {-0.121518,-0.113712},
+  {0.429205,-0.768057},
+  {0.120817,-0.738954},
+  {0.246917,-0.025595},
+  {0.223685,0.828870},
+  {0.558682,0.833145},
+  {-0.226176,-1.141426},
+  {0.592138,0.661966},
+  {0.057983,-0.123112},
+  {-0.277232,0.942800},
+  {0.380806,-0.215897},
+  {-1.027768,-0.692785},
+  {1.629491,-1.099912},
+  {-0.047831,-1.555090},
+  {-0.577377,-0.165198},
+  {0.708597,-0.250402},
+  {-1.063587,-0.338164},
+  {0.505373,0.385189},
+  {0.072781,-0.658487},
+  {0.542617,-0.198652},
+  {1.367844,0.323822},
+  {-0.727703,0.962762},
+  {-0.393308,0.873045},
+  {-0.950481,0.223532},
+  {1.018389,0.884161},
+  {-0.042519,0.854602},
+  {-1.358413,-0.098257},
+  {0.245351,-0.975102},
+  {-0.055406,-1.219287},
+  {1.325559,-0.297813},
+  {-0.072107,-0.600966},
+  {-0.045452,-0.636110},
+  {1.196032,-0.569957},
+  {0.455332,-1.319878},
+  {-0.547178,-0.392150},
+  {-1.296887,-0.758016},
+  {0.862281,0.903182},
+  {-0.538526,-0.948723},
+  {0.065158,0.398744},
+  {-0.565977,-0.745461},
+  {-0.050462,0.869712},
+  {0.205620,-0.219247},
+  {0.093927,-0.270377},
+  {1.113685,-1.069443},
+  {-0.718055,0.556379},
+  {0.050929,0.307347},
+  {-1.222501,0.207457},
+  {0.951141,-1.438969},
+  {-0.003803,-0.125003},
+  {-1.267607,0.411439},
+  {-0.857943,-1.588554},
+  {0.596604,-0.286897},
+  {-0.872539,-0.101087},
+  {-0.658556,0.189207},
+  {-0.387868,-0.070786},
+  {-0.462842,0.344476},
+  {1.085369,-0.860640},
+  {1.581858,1.043663},
+  {-0.972570,0.171239},
+  {-0.075607,-0.486479},
+  {1.421958,-1.399106},
+  {-0.589684,0.410053},
+  {0.377491,0.034375},
+  {0.428788,0.365635},
+  {-0.528193,-1.238089},
+  {0.262891,0.578832},
+  {0.066590,0.188433},
+  {-0.745635,-0.018847},
+  {-0.116912,-0.514034},
+  {0.597006,0.677949},
+  {0.107517,-0.406065},
+  {1.015423,0.001044},
+  {-0.197476,0.574557},
+  {-0.248416,-0.193462},
+  {0.473342,-1.017108},
+  {0.137976,1.024174},
+  {-0.210346,0.751566},
+  {-1.015057,-0.473646},
+  {-0.595567,0.801209},
+  {0.796281,0.545814},
+  {-0.856927,-0.309617},
+  {0.591179,1.361440},
+  {0.157283,-0.776932},
+  {0.393443,1.025215},
+  {0.537778,0.697904},
+  {2.219707,0.499801},
+  {1.273309,-0.828332},
+  {-0.982928,0.949413},
+  {-1.153902,0.670467},
+  {-0.156032,-0.994523},
+  {0.821935,-0.378448},
+  {0.260809,0.087339},
+  {0.216860,-0.601138},
+  {-0.882410,-0.227433},
+  {-0.440866,-0.094405},
+  {-0.074585,0.039917},
+  {-0.737009,1.217088},
+  {-0.268090,0.493822},
+  {-0.066510,-0.570724},
+  {-0.203579,0.757423},
+  {0.062591,-0.452128},
+  {0.507822,1.130258},
+  {-1.135255,-0.393007},
+  {0.740321,0.411285},
+  {-0.402801,-0.390182},
+  {0.794407,0.970310},
+  {0.566977,0.605520},
+  {-0.537209,0.639380},
+  {-0.426697,0.138911},
+  {-0.087417,0.452920},
+  {-1.152861,-0.321958},
+  {-0.284884,0.639191},
+  {0.145500,0.907847},
+  {0.982621,0.367939},
+  {-0.195191,1.137989},
+  {0.211046,-1.239543},
+  {0.562427,-0.534005},
+  {0.830928,-0.588515},
+  {0.651664,-0.531934},
+  {-0.056867,0.384091},
+  {-0.589129,1.364900},
+  {-0.141771,-0.114847},
+  {-0.411185,0.073030},
+  {-0.265763,0.272064},
+  {0.882316,0.793624},
+  {-0.160386,0.002500},
+  {-0.235607,-0.567823},
+  {-1.210585,0.206751},
+  {0.817503,0.330202},
+  {-0.162811,-1.417884},
+  {0.592217,0.010516},
+  {1.662363,-0.402841},
+  {-0.446189,0.501595},
+  {-0.729150,-0.238869},
+  {-0.452834,0.078506},
+  {-1.518996,-0.427439},
+  {-0.266874,0.101362},
+  {0.531735,-0.547254},
+  {-0.965587,0.011378},
+  {-0.298296,-0.096297},
+  {-0.149287,0.531172},
+  {0.448779,-0.448307},
+  {1.047356,-0.315960},
+  {1.247794,0.506753},
+  {0.590511,0.472349},
+  {0.121279,-0.433674},
+  {-0.114362,0.767422},
+  {1.581429,0.955828},
+  {1.476868,-0.288333},
+  {-0.556583,-1.164155},
+  {-0.059431,-1.160055},
+  {0.634128,1.002689},
+  {-0.575933,0.033633},
+  {1.081099,1.385344},
+  {-1.422736,0.075505},
+  {1.046288,0.401673},
+  {0.435929,-0.472107},
+  {-0.206122,0.348224},
+  {-0.412777,-0.109916},
+  {0.121895,-0.581462},
+  {-0.133105,0.264961},
+  {-0.850482,-0.072401},
+  {-0.577871,0.376519},
+  {-1.388756,-0.023759},
+  {0.779804,-0.186311},
+  {-0.620828,-0.118957},
+  {0.932679,0.434943},
+  {0.633370,0.592508},
+  {1.134259,0.028486},
+  {0.799487,0.223794},
+  {-0.347314,-0.170474},
+  {0.539087,-0.221093},
+  {-0.820533,0.307851},
+  {-0.717160,0.017505},
+  {0.542587,-1.162436},
+  {-0.624600,0.801725},
+  {1.352536,-0.143812},
+  {-0.796545,-0.900611},
+  {-0.356700,-0.350123},
+  {0.038018,0.541666},
+  {0.289386,0.401983},
+  {-0.137301,1.430812},
+  {1.503273,0.402538},
+  {-0.492407,-0.424006},
+  {0.932498,-0.226829},
+  {0.093021,0.081391},
+  {-0.093971,-0.658882},
+  {-0.284706,-0.026044},
+  {-0.226983,0.526229},
+  {0.029324,0.041975},
+  {0.873120,0.151935},
+  {-0.393476,-0.848702},
+  {1.838695,-0.084288},
+  {-0.074042,1.079671},
+  {0.039939,-1.111425},
+  {0.669271,2.216002},
+  {-0.589368,-0.446797},
+  {-0.465512,0.085837},
+  {0.651261,0.403519},
+  {0.218905,-0.766309},
+  {-0.128001,0.073902},
+  {-0.272830,-0.432066},
+  {0.519152,-0.589446},
+  {-0.311524,0.233018},
+  {-0.545692,-0.664651},
+  {-1.380502,0.757145},
+  {-0.000180,-0.339163},
+  {0.446891,0.438011},
+  {0.454009,-0.094370},
+  {-1.035878,0.187205},
+  {-0.896572,0.237276},
+  {0.382598,0.442667},
+  {-2.504186,-0.537285},
+  {0.099216,0.970556},
+  {-0.381212,-0.168048},
+  {0.554364,-0.100494},
+  {-0.269872,-1.498621},
+  {-0.494833,-0.343613},
+  {0.449499,0.124923},
+  {0.027846,-0.151862},
+  {-0.115574,-0.391918},
+  {0.431950,-0.632974},
+  {-0.223079,0.433815},
+  {-0.360470,0.230335},
+  {-0.351935,-0.652477},
+  {-0.699202,-0.709860},
+  {0.165994,1.156386},
+  {0.946215,-0.422976},
+  {-0.694515,0.460667},
+  {0.163665,-0.096615},
+  {-0.011231,0.132682},
+  {1.105695,0.245389},
+  {1.070530,0.039658},
+  {-0.393505,-0.942814},
+  {0.695178,-0.279964},
+  {0.373143,-0.153469},
+  {0.068343,-0.246175},
+  {0.255959,0.802372},
+  {-0.561208,0.096934},
+  {-0.520615,-0.044160},
+  {0.829240,-0.282919},
+  {0.617384,-0.417490},
+  {1.900495,1.234182},
+  {-1.341464,1.226474},
+  {-0.168441,-0.813023},
+  {1.015085,-0.464638},
+  {0.369413,-0.066272},
+  {-0.239524,0.683590},
+  {0.357866,-0.112409},
+  {1.009900,1.254497},
+  {0.068589,0.356761},
+  {-0.438932,-0.304929},
+  {-0.012575,-0.341361},
+  {0.299906,-0.036658},
+  {0.404167,-0.128515},
+  {0.366136,-1.307424},
+  {-0.598692,-1.008058},
+  {0.110613,-0.159653},
+  {1.201734,0.376235},
+  {-0.704852,0.106275},
+  {0.007635,0.082348},
+  {-0.767279,0.145814},
+  {-2.046550,1.123715},
+  {-0.006254,-0.772897},
+  {1.860613,0.657821},
+  {-1.010233,0.378664},
+  {0.049775,0.410985},
+  {-1.426361,0.659661},
+  {0.362923,0.949449},
+  {0.169229,-0.433502},
+  {1.588609,-1.429715},
+  {1.714049,1.762603},
+  {0.280914,0.315189},
+  {-0.366100,0.687960},
+  {-0.017839,0.001341},
+  {-0.011156,-0.946371},
+  {0.605485,-0.901263},
+  {1.083968,-1.642610},
+  {0.689493,1.137977},
+  {-1.346342,-1.228991},
+  {0.441885,0.428678},
+  {-0.300121,-0.242661},
+  {0.151982,0.516324},
+  {1.165886,0.321775},
+  {-0.428105,0.187019},
+  {-1.004687,0.294742},
+  {0.338772,1.213508},
+  {0.988679,-0.037867},
+  {-0.224368,0.155973},
+  {0.141559,0.186316},
+  {-0.644438,0.395989},
+  {-0.199866,-0.523264},
+  {-0.107300,-0.461294},
+  {0.358698,-0.649953},
+  {-0.634770,-0.312915},
+  {-0.564734,-0.715844},
+  {0.255026,-1.108371},
+  {-0.086293,0.312637},
+  {0.814938,-0.283814},
+  {1.229763,0.128464},
+  {0.227974,-0.418647},
+  {-0.120043,-0.684067},
+  {0.077666,-0.085758},
+  {-0.050780,-0.670323},
+  {0.136626,0.813804},
+  {0.594956,-0.407936},
+  {0.955985,-0.191253},
+  {0.489552,-1.486926},
+  {0.577579,-0.486322},
+  {0.562717,-0.751664},
+  {0.002459,0.263571},
+  {0.288905,-0.878478},
+  {-0.464409,-0.538675},
+  {0.286060,0.412672},
+  {-0.181148,0.381556},
+  {0.151361,0.358454},
+  {-0.078488,0.251609},
+  {0.773414,-0.739208},
+  {0.691577,-0.694201},
+  {-1.293390,-0.509235},
+  {1.146156,-0.653543},
+  {-0.242636,-0.801005},
+  {0.353931,-0.135868},
+  {-0.243086,-0.439001},
+  {0.354013,-0.233653},
+  {-0.277764,-0.677296},
+  {0.473043,0.038362},
+  {-0.176500,0.264359},
+  {-0.625575,0.366112},
+  {0.202867,0.941900},
+  {-0.326032,0.671700},
+  {-1.046037,-0.687290},
+  {-0.868275,-0.007581},
+  {-0.570060,0.286439},
+  {0.713059,0.210833},
+  {-1.294165,-0.028527},
+  {0.071361,0.847772},
+  {0.508287,0.046283},
+  {0.058998,-0.528609},
+  {-0.568115,1.051018},
+  {0.922293,-0.377449},
+  {0.202094,0.031911},
+  {-0.114554,-0.415825},
+  {-0.776175,-0.804922},
+  {-0.057279,-0.584848},
+  {0.412935,0.618731},
+  {-1.092835,0.486985},
+  {-0.678552,0.788882},
+  {-0.968375,0.329940},
+  {-0.714789,-0.149820},
+  {-0.384156,0.175588},
+  {0.730323,-0.459545},
+  {-0.374056,-0.030715},
+  {-0.530865,1.744913},
+  {0.317942,0.712183},
+  {0.514842,-1.521713},
+  {-1.982352,0.917451},
+  {0.533069,-0.184669},
+  {-0.047735,-0.546721},
+  {-0.084978,0.164704},
+  {-0.713723,0.221991},
+  {0.082505,-0.468486},
+  {-0.100827,0.472135},
+  {-0.666553,0.018597},
+  {0.287429,-0.329748},
+  {-1.436239,1.330035},
+  {0.290806,-0.769263},
+  {-0.048715,0.566687},
+  {-0.968640,-0.211849},
+  {0.088714,-1.498366},
+  {-0.081821,-1.526247},
+  {-0.569582,0.589569},
+  {-0.581721,-0.848599},
+  {-0.006144,-0.254501},
+  {-0.374622,1.266927},
+  {-0.426722,0.039232},
+  {-0.613330,0.408639},
+  {0.242699,-0.420023},
+  {-0.511846,-0.344112},
+  {0.055041,-0.785869},
+  {0.817784,0.414807},
+  {0.327502,-0.140078},
+  {-0.177410,0.254219},
+  {-0.697158,1.041201},
+  {0.443662,0.437433},
+  {0.255286,1.735288},
+  {-0.986974,0.995444},
+  {-0.170297,0.934111},
+  {0.016505,-0.449689},
+  {0.074375,0.925671},
+  {-0.264038,-0.993178},
+  {0.394263,0.428509},
+  {0.275369,-0.148148},
+  {-0.026461,0.786728},
+  {0.219694,-0.715724},
+  {-0.198181,-0.337653},
+  {-0.046106,1.077969},
+  {-0.427274,-1.648299},
+  {0.916379,0.354817},
+  {-0.495159,0.025080},
+  {0.900671,-0.716446},
+  {-0.255983,0.933249},
+  {0.849832,-0.023818},
+  {0.848812,1.222279},
+  {0.762640,-0.407851},
+  {-1.113535,-0.693755},
+  {0.853063,-0.222685},
+  {0.182071,-0.562988},
+  {0.452813,-0.071797},
+  {-1.401647,0.298240},
+  {-1.096633,-0.276216},
+  {-0.470637,-1.218317},
+  {0.061808,0.397691},
+  {0.600333,-0.767871},
+  {1.008250,0.000708},
+  {-0.647290,0.306240},
+  {-0.398649,0.249797},
+  {-1.305586,-0.172789},
+  {0.385940,-1.320990},
+  {0.758806,0.901173},
+  {-0.002028,-0.687838},
+  {-0.619773,-0.519246},
+  {0.850480,-0.003780},
+  {-0.327611,1.357023},
+  {0.407292,0.562773},
+  {-0.053213,-0.769666},
+  {1.106032,1.282982},
+  {-0.673619,1.289760},
+  {0.476732,-0.611785},
+  {0.152022,-1.680944},
+  {-0.649479,-0.291411},
+  {-0.012972,-0.162121},
+  {-0.691724,0.407729},
+  {0.236190,-1.267413},
+  {0.533790,0.419325},
+  {-0.018652,0.266647},
+  {0.229770,0.165313},
+  {-0.558823,-0.887105},
+  {-0.764080,0.628785},
+  {0.355465,0.190894},
+  {-1.031620,0.424156},
+  {0.210209,-0.511032},
+  {2.231847,-1.271046},
+  {0.495758,-0.561719},
+  {-0.007179,-0.289322},
+  {0.208132,1.637787},
+  {-0.761436,-0.158279},
+  {-1.584498,-0.324741},
+  {0.085113,0.686596},
+  {-0.430017,0.361140},
+  {0.205829,-0.606992},
+  {0.307451,0.417509},
+  {-0.305665,0.631657},
+  {-0.401597,-0.758367},
+  {-0.231825,-0.733147},
+  {0.413582,0.999199},
+  {-0.017343,-0.416519},
+  {-0.165102,-1.228027},
+  {1.079916,0.834003},
+  {-0.032758,1.090964},
+  {0.682886,0.223947},
+  {-0.125567,0.406849},
+  {-0.291070,0.319598},
+  {-0.433261,1.411476},
+  {-0.521844,0.077749},
+  {-1.622536,0.199245},
+  {-1.152493,-1.236599},
+  {0.010262,-1.143242},
+  {0.590426,0.129957},
+  {0.710855,-0.106919},
+  {0.453857,-0.988619},
+  {-0.904005,-0.503640},
+  {0.589253,-0.486321},
+  {-0.430470,-0.027916},
+  {-0.820770,-0.751695},
+  {-0.282278,-0.038594},
+  {0.864998,0.097233},
+  {0.111612,-0.288777},
+  {-0.028031,-0.269425},
+  {0.431845,0.101275},
+  {-0.339818,-0.152321},
+  {0.921835,0.289830},
+  {-0.671086,-0.501673},
+  {0.247329,0.183999},
+  {0.567859,-0.307398},
+  {0.116284,0.435589},
+  {0.203286,0.041931},
+  {0.492580,-1.168513},
+  {0.661239,0.504958},
+  {0.626179,0.315147},
+  {1.241463,-0.126592},
+  {-0.242149,0.706826},
+  {0.022340,-1.150953},
+  {-0.121594,0.286725},
+  {-0.759044,0.336943},
+  {1.203657,-0.225805},
+  {-0.307556,-0.613049},
+  {0.760114,-0.923164},
+  {-1.293027,0.195280},
+  {1.015077,0.098072},
+  {-2.074471,-0.189545},
+  {0.841240,0.955406},
+  {-0.178337,0.721980},
+  {1.160489,0.003816},
+  {-0.384566,2.620896},
+  {0.704705,0.063137},
+  {0.548336,0.066192},
+  {0.190808,-0.012015},
+  {0.553649,0.329412},
+  {-0.320558,0.795527},
+  {-0.615417,0.909293},
+  {-1.246752,-0.698925},
+  {0.549175,0.281020},
+  {-0.778784,-1.430814},
+  {0.806743,0.036949},
+  {0.477405,-0.736326},
+  {-0.702940,-0.929653},
+  {0.151960,0.582314},
+  {0.865540,-0.423882},
+  {0.491950,0.963153},
+  {0.330508,0.053934},
+  {0.464252,0.827913},
+  {0.192361,-0.235847},
+  {0.816402,-0.115001},
+  {0.092131,-0.660784},
+  {0.174107,0.285417},
+  {-0.755223,0.514173},
+  {0.364767,-0.792043},
+  {-0.562086,-0.217651},
+  {0.353453,0.348443},
+  {0.585457,1.370006},
+  {0.984197,-0.178664},
+  {-0.366706,-0.786270},
+  {1.414700,-0.134770},
+  {0.941644,0.284337},
+  {-0.455753,1.036933},
+  {1.382049,0.541054},
+  {0.575756,-0.046144},
+  {-0.051649,0.048517},
+  {-1.119540,0.541357},
+  {0.273349,1.070178},
+  {-0.456227,-0.374803},
+  {-0.426392,-0.882598},
+  {-0.085007,1.118462},
+  {-0.265127,0.515600},
+  {0.769586,-0.251247},
+  {-0.458924,1.727463},
+  {0.661363,0.210307},
+  {0.953185,0.310892},
+  {0.165745,-0.249229},
+  {0.003256,-1.461112},
+  {-1.295068,0.895661},
+  {0.505398,-0.514159},
+  {-0.794349,-0.483016},
+  {-0.156867,-1.192899},
+  {0.540678,0.515770},
+  {-0.124202,-0.030591},
+  {-0.391160,1.843647},
+  {0.495854,0.368012},
+  {0.973258,-0.316386},
+  {-0.194668,-0.132074},
+  {-0.155372,-0.897061},
+  {0.231087,-0.105997},
+  {-0.153340,-0.294455},
+  {0.796845,0.174109},
+  {0.603647,0.542966},
+  {0.254563,0.674866},
+  {-0.956172,-0.048158},
+  {-0.530818,-0.801843},
+  {-1.026113,-0.351077},
+  {0.523780,0.415202},
+  {-0.948912,-1.572310},
+  {0.410020,0.659503},
+  {-0.701486,-0.147504},
+  {2.688922,0.358403},
+  {1.560465,-0.433628},
+  {-0.496547,-0.211502},
+  {-0.124965,-0.391226},
+  {-0.533224,0.503166},
+  {-0.321520,-0.572785},
+  {1.258924,0.163907},
+  {0.151190,-0.084062},
+  {0.226057,-0.056905},
+  {0.587172,-0.471113},
+  {-0.695980,-0.163141},
+  {-1.237538,-0.208643},
+  {0.998500,0.955563},
+  {-0.179606,0.559009},
+  {0.137764,-0.393149},
+  {0.502345,-0.054011},
+  {-0.904479,0.141850},
+  {-0.350247,-0.211378},
+  {0.404017,-0.839708},
+  {1.263962,0.630874},
+  {-0.135289,-2.442988},
+  {0.442130,-0.830587},
+  {0.122658,0.023062},
+  {0.883724,0.665128},
+  {-0.178230,0.306886},
+  {-0.468211,0.071836},
+  {0.246586,0.267636},
+  {-0.557471,-0.275384},
+  {0.580532,-0.339634},
+  {0.229230,0.098588},
+  {-0.037226,0.048941},
+  {0.429143,-0.409864},
+  {-0.994136,0.254552},
+  {1.166575,0.976509},
+  {0.851270,-0.625880},
+  {-0.345877,0.458113},
+  {1.414551,-0.046154},
+  {-0.380014,0.085284},
+  {-0.464670,0.922754},
+  {0.372413,-0.292998},
+  {0.047303,-0.678625},
+  {0.754110,-0.077518},
+  {-0.818388,-0.489265},
+  {0.374833,0.280108},
+  {0.074119,-1.470670},
+  {-0.635899,-0.637640},
+  {0.921722,0.985314},
+  {-1.420950,0.022021},
+  {0.627703,0.569002},
+  {0.340334,0.147938},
+  {0.400352,0.190057},
+  {-1.088817,0.050628},
+  {0.137021,0.484178},
+  {0.078217,0.350442},
+  {0.294682,0.070688},
+  {-0.085588,0.602284},
+  {0.673964,-0.173427},
+  {-0.235137,-0.583674},
+  {-0.707102,0.052630},
+  {0.474050,-1.693641},
+  {1.003813,0.543324},
+  {0.628591,-0.050070},
+  {-0.249527,0.767586},
+  {-1.879195,-0.452537},
+  {0.396132,-0.415229},
+  {-0.028199,0.551825},
+  {0.385329,-0.220834},
+  {1.324679,-0.312798},
+  {-0.642863,-0.825135},
+  {-0.004710,-0.058157},
+  {-0.847162,0.856134},
+  {-0.740614,-0.863084},
+  {-1.158400,0.973958},
+  {-1.671737,-0.563632},
+  {-0.650321,-0.235563},
+  {0.598594,-0.545525},
+  {0.526469,0.149947},
+  {-0.237268,0.583359},
+  {0.423311,-0.217139},
+  {0.379071,1.034865},
+  {-1.758812,0.686033},
+  {-0.185959,0.643266},
+  {0.032531,0.661944},
+  {-0.298139,-0.817098},
+  {-1.599706,-0.313605},
+  {0.426141,-0.444764},
+  {-1.006136,-0.819221},
+  {-0.706618,-0.317805},
+  {0.141126,1.084697},
+  {0.623824,0.023016},
+  {-1.046610,0.015300},
+  {0.745230,0.751430},
+  {-1.319946,-0.564289},
+  {-0.604642,0.954636},
+  {-0.483640,1.126604},
+  {-0.757284,-0.011440},
+  {-0.387955,-0.304309},
+  {0.153010,2.368292},
+  {0.914144,-1.029997},
+  {-0.299668,-0.611878},
+  {0.525482,-0.659581},
+  {0.420515,0.491139},
+  {-0.366100,0.268333},
+  {0.341777,-1.103398},
+  {-0.323677,0.907073},
+  {-1.121212,0.392582},
+  {0.633364,0.164803},
+  {0.338245,-0.443073},
+  {-0.135408,-0.702552},
+  {-1.008789,-0.011260},
+  {-0.781123,-0.685846},
+  {0.776429,-0.662386},
+  {1.057167,0.352887},
+  {-0.597591,0.229540},
+  {0.084232,1.119583},
+  {-0.285929,0.236433},
+  {0.186841,0.460782},
+  {-0.172005,-0.130474},
+  {0.310647,0.559606},
+  {-0.119430,0.878673},
+  {-1.612776,0.477573},
+  {-0.154730,-0.506361},
+  {-0.083025,-1.341480},
+  {-0.590808,-0.873065},
+  {0.237921,0.451140},
+  {-1.029581,-0.416044},
+  {-0.719467,-1.896297},
+  {-0.051499,0.067354},
+  {0.889375,-0.684079},
+  {-0.718765,0.727295},
+  {-0.536690,-0.605252},
+  {-0.739059,-0.585248},
+  {0.344357,0.106056},
+  {-0.829777,0.728094},
+  {-0.283713,0.261390},
+  {0.152151,0.078054},
+  {0.567021,0.126294},
+  {0.291900,0.562743},
+  {1.059085,0.084687},
+  {-0.551331,-1.234712},
+  {-0.588794,-1.091670},
+  {-1.691073,-0.118561},
+  {1.420551,-1.631329},
+  {0.205528,-0.641568},
+  {0.162794,0.566978},
+  {0.766135,-0.410851},
+  {-0.798597,0.988584},
+  {-0.718769,-0.992680},
+  {0.344092,0.608391},
+  {0.292893,0.732026},
+  {0.056027,-0.138066},
+  {0.429755,0.079029},
+  {0.187873,0.660457},
+  {-0.517005,0.344139},
+  {-0.147412,-0.311869},
+  {-0.426811,-0.332282},
+  {1.157440,-0.638019},
+  {0.183905,-0.237103},
+  {-0.779848,0.107454},
+  {-0.451815,-0.023654},
+  {-0.631830,0.052062},
+  {-0.010302,0.265023},
+  {-0.740212,0.667259},
+  {-0.327306,-0.562585},
+  {-0.036460,-0.926800},
+  {-0.695698,0.585635},
+  {0.506878,0.691465},
+  {0.758726,0.102093},
+  {0.084728,0.503180},
+  {1.401625,0.519015},
+  {-0.631581,-0.606695},
+  {0.803128,-0.862507},
+  {0.940896,0.866730},
+  {0.194009,1.652032},
+  {0.144810,-0.487873},
+  {-0.461080,-0.403805},
+  {0.002382,0.136163},
+  {0.075381,-0.322951},
+  {-0.966995,0.269808},
+  {-0.030479,-0.126750},
+  {-0.149463,0.291122},
+  {1.059634,-0.087343},
+  {-0.579570,0.637704},
+  {-0.747178,-0.468939},
+  {0.647099,-0.724797},
+  {-0.223191,0.924383},
+  {-0.337221,-0.601146},
+  {-0.515588,0.209382},
+  {-0.439052,-0.285641},
+  {-0.461382,0.405431},
+  {-0.342314,-0.077113},
+  {-0.631056,-0.415190},
+  {0.238351,-0.386171},
+  {-0.862323,0.642213},
+  {0.023490,1.420643},
+  {-0.875054,-0.335857},
+  {-0.501911,0.198525},
+  {-0.610229,-0.615875},
+  {-0.798574,0.715166},
+  {0.822130,-1.270475},
+  {-1.244082,0.455988},
+  {1.012773,-0.052447},
+  {1.371291,0.428342},
+  {0.352000,-0.742200},
+  {-0.239479,-0.204546},
+  {-0.894340,-0.160308},
+  {0.011754,-0.047223},
+  {-0.665009,-1.202901},
+  {-0.774045,-1.477797},
+  {0.298235,0.642437},
+  {0.281567,-0.363596},
+  {-0.359115,0.641628},
+  {0.457527,0.395590},
+  {-0.613016,0.686037},
+  {0.366476,-1.001394},
+  {-1.256980,-0.267237},
+  {-0.929750,0.866740},
+  {0.450983,-0.179572},
+  {-0.783167,0.315364},
+  {0.373729,-0.263585},
+  {-0.829264,1.092197},
+  {-0.294844,-1.307715},
+  {-0.382714,0.271065},
+  {0.432171,1.321070},
+  {1.193662,-0.601561},
+  {0.441481,1.078067},
+  {0.816584,0.272961},
+  {0.550523,-0.150661},
+  {0.184214,-0.219220},
+  {-0.009063,-0.442284},
+  {1.646675,-0.741609},
+  {1.016200,0.837222},
+  {-0.793906,-0.222885},
+  {0.919271,0.064883},
+  {-1.356202,0.423254},
+  {0.049124,-0.191414},
+  {-0.195965,0.184440},
+  {1.121060,1.056448},
+  {-1.033376,-0.124441},
+  {0.347735,1.195392},
+  {0.503386,0.384467},
+  {0.000622,0.057254},
+  {0.170387,-0.558950},
+  {0.128132,0.079457},
+  {1.004037,-0.526779},
+  {0.385914,0.909700},
+  {1.335021,-1.678956},
+  {-0.288577,-0.895513},
+  {0.565198,-0.882130},
+  {0.225851,0.962253},
+  {0.879317,-0.347095},
+  {0.176626,0.994786},
+  {-0.866639,-0.349720},
+  {-0.671101,-0.515104},
+  {-0.485501,0.483706},
+  {-0.618060,0.335038},
+  {0.041503,-0.588110},
+  {0.111759,0.143271},
+  {0.462091,-1.215689},
+  {-0.745533,0.359722},
+  {-0.258587,-0.704901},
+  {0.274778,0.923238},
+  {-0.004584,-0.433904},
+  {-0.110584,0.522650},
+  {0.310410,-0.005530},
+  {-0.937176,-1.562305},
+  {-0.827198,0.289808},
+  {-0.698794,-2.184667},
+  {-0.330698,-0.129384},
+  {1.282239,0.020580},
+  {0.367543,0.233161},
+  {0.065772,0.245385},
+  {-1.368919,-0.232512},
+  {-0.022110,-0.434683},
+  {0.989342,2.850177},
+  {0.301916,-0.504838},
+  {-0.199269,0.274472},
+  {0.050557,-0.762571},
+  {-0.439144,-1.131543},
+  {-1.080251,-0.382884},
+  {0.966876,-2.108684},
+  {-0.843520,-0.663706},
+  {0.898827,0.695593},
+  {1.141696,1.743007},
+  {-1.209097,0.920291},
+  {-0.133004,-0.591750},
+  {0.230189,-0.024491},
+  {0.267833,-0.097969},
+  {0.945771,-0.620059},
+  {-1.927322,0.029121},
+  {0.624278,-1.539738},
+  {0.038578,0.956436},
+  {-0.340126,0.630304},
+  {0.615450,0.090583},
+  {0.546216,-0.444248},
+  {1.103206,-0.220818},
+  {0.249552,-1.338686},
+  {0.137988,-0.524542},
+  {0.535324,-0.053403},
+  {-0.312144,0.754749},
+  {-0.305128,-0.570806},
+  {-0.270710,-0.431734},
+  {1.075527,-0.517887},
+  {0.925849,-0.402164},
+  {0.780606,-0.094631},
+  {0.304430,-0.321345},
+  {-2.161699,0.828282},
+  {-0.074158,-0.677161},
+  {-0.063345,-1.326582},
+  {-0.309826,0.355096},
+  {-0.276573,-0.413940},
+  {0.647672,0.302474},
+  {-0.232098,-1.147781},
+  {0.120684,-1.621992},
+  {0.955412,0.475249},
+  {-1.220155,-0.114060},
+  {1.336061,0.110965},
+  {-0.643678,-0.340022},
+  {-0.275077,-0.365716},
+  {0.534379,-0.975696},
+  {-1.015498,-0.567058},
+  {-0.064751,-0.046544},
+  {1.134877,-0.470992},
+  {-1.008269,0.759255},
+  {-0.144860,0.949311},
+  {-0.732892,1.047155},
+  {-1.535131,-0.961362},
+  {-0.269558,0.444843},
+  {0.059658,-0.187720},
+  {0.035190,-0.221091},
+  {-0.281704,-0.358197},
+  {1.022722,0.075790},
+  {-1.083448,-0.575743},
+  {-1.302319,0.027091},
+  {0.650458,1.349900},
+  {-1.899117,1.012783},
+  {0.181135,0.688259},
+  {-0.202816,0.372898},
+  {0.022705,1.006927},
+  {0.407585,-0.837289},
+  {0.002035,0.352033},
+  {-0.356021,0.346572},
+  {-0.617595,0.786143},
+  {0.239147,-0.279550},
+  {-0.088149,0.102956},
+  {-0.145992,0.070007},
+  {0.061313,-0.731353},
+  {-0.584911,-0.334126},
+  {-1.203326,0.593685},
+  {-0.269043,-0.369218},
+  {0.521335,-0.180848},
+  {0.144528,0.438304},
+  {0.735844,-0.087415},
+  {0.843519,0.404185},
+  {0.253477,0.233027},
+  {0.286579,-0.892798},
+  {0.017010,1.496329},
+  {-0.282048,-0.432474},
+  {-0.831781,-0.766073},
+  {-0.339801,0.157388},
+  {0.117625,-0.661367},
+  {-0.133374,-0.349166},
+  {-0.700496,-0.598886},
+  {1.062019,-0.225486},
+  {-0.844149,1.129804},
+  {0.879032,0.843744},
+  {-0.329666,0.330986},
+  {0.186070,-0.855283},
+  {-0.324321,-1.583881},
+  {1.541431,-0.622636},
+  {0.819195,-0.182278},
+  {0.449811,-0.132524},
+  {-0.888292,-1.515782},
+  {-1.001516,-0.830254},
+  {0.250502,-0.344122},
+  {-0.187613,1.197694},
+  {-0.529563,1.498822},
+  {-0.076462,-0.133383},
+  {0.650433,0.946105},
+  {-0.483935,0.181802},
+  {-0.723391,-0.925543},
+  {-0.431870,-0.262836},
+  {-0.422439,0.651529},
+  {-0.782266,0.681568},
+  {0.562754,-0.374426},
+  {0.519622,0.043415},
+  {-0.801116,1.075381},
+  {-0.799244,-1.077313},
+  {0.540276,1.027038},
+  {-0.894727,-0.874882},
+  {-0.749377,1.018981},
+  {0.184097,-0.111914},
+  {0.042289,-0.830370},
+  {1.791222,-0.588920},
+  {-0.047891,0.031348},
+  {0.043701,-0.440535},
+  {-0.840151,-0.568261},
+  {0.323255,0.787932},
+  {1.107241,0.054776},
+  {0.060801,-0.856247},
+  {-0.813509,0.705567},
+  {-0.791245,1.459674},
+  {-0.014035,-0.216140},
+  {0.387915,0.037240},
+  {0.642452,-0.129442},
+  {-1.843821,-0.114364},
+  {-0.035832,0.415178},
+  {0.767540,0.263665},
+  {-0.652285,-0.081054},
+  {-1.285872,0.969226},
+  {0.618911,0.255848},
+  {-0.807479,0.457430},
+  {1.064158,0.201941},
+  {0.880563,0.083746},
+  {-0.305545,1.351159},
+  {0.904389,-0.245280},
+  {-0.217445,0.025212},
+  {-0.836006,-0.776473},
+  {0.738829,1.044716},
+  {0.284688,-0.270552},
+  {1.085086,-0.533687},
+  {0.671634,1.461351},
+  {0.644988,-0.881924},
+  {-0.894529,0.426442},
+  {0.562243,0.029641},
+  {0.404564,0.410895},
+  {0.425106,-0.487737},
+  {-0.640461,-0.176507},
+  {-0.113150,-0.170049},
+  {0.212635,-0.218543},
+  {0.269008,1.255394},
+  {0.432785,0.488759},
+  {0.513129,0.005448},
+  {0.099545,0.578849},
+  {0.086904,-0.186066},
+  {-1.555150,0.851275},
+  {-0.032900,0.503340},
+  {1.149826,0.331512},
+  {0.073811,0.159585},
+  {-0.223626,0.427643},
+  {1.261585,0.418598},
+  {0.601685,-0.525800},
+  {-0.486987,-0.199185},
+  {-0.059233,0.227470},
+  {0.226861,0.459247},
+  {-0.341422,-1.927231},
+  {-0.171239,0.113076},
+  {0.078549,1.096510},
+  {-0.338355,-1.369953},
+  {0.159905,-0.691937},
+  {-0.307114,0.783536},
+  {-0.566867,0.107976},
+  {0.511947,-0.433910},
+  {0.691441,-0.214146},
+  {-0.603745,0.410150},
+  {0.628406,1.315388},
+  {0.785402,-0.016113},
+  {0.897580,1.142371},
+  {-0.523238,0.503762},
+  {-1.709664,-0.720023},
+  {0.458547,-0.008885},
+  {-0.334689,-0.277679},
+  {0.489018,-0.845080},
+  {0.523348,0.669807},
+  {-0.078580,0.679453},
+  {0.434669,1.223368},
+  {-0.046575,1.365787},
+  {-0.280968,-0.687172},
+  {-1.099810,0.666500},
+  {-0.860152,-0.227991},
+  {-0.330220,0.063645},
+  {-0.469986,-0.845073},
+  {-0.674068,1.048877},
+  {0.455515,0.818142},
+  {0.849858,-0.564687},
+  {0.059095,-0.035666},
+  {-0.223894,0.001953},
+  {-0.067447,-1.792125},
+  {1.605312,0.096682},
+  {-1.475052,-0.104396},
+  {-0.360386,-0.579824},
+  {0.955123,1.157321},
+  {-1.251963,0.038931},
+  {0.370436,-0.992312},
+  {1.371997,-0.487094},
+  {0.015502,-0.447989},
+  {-0.022840,-0.149928},
+  {-0.664625,0.831535},
+  {0.757109,0.066880},
+  {-0.632931,-0.921457},
+  {-0.231963,-0.193233},
+  {0.777090,0.166369},
+  {0.609395,-0.027552},
+  {0.139106,0.541898},
+  {0.942118,0.587904},
+  {0.251157,-0.133831},
+  {0.487019,0.189802},
+  {0.457665,0.362136},
+  {-0.424465,-1.249760},
+  {0.581103,-0.376516},
+  {0.510419,-0.590129},
+  {1.037473,0.371550},
+  {-0.466737,-1.004333},
+  {-0.011938,0.537880},
+  {0.547161,1.035422},
+  {0.606423,-0.516887},
+  {0.056961,1.039645},
+  {0.477078,-0.559180},
+  {-0.254626,-1.547132},
+  {-1.133833,0.334869},
+  {0.822161,0.621644},
+  {-0.062360,-1.517223},
+  {-0.703293,-0.420242},
+  {0.317995,-0.825593},
+  {0.736898,-0.336708},
+  {0.771707,-0.083937},
+  {-0.213908,0.357054},
+  {1.824059,0.566277},
+  {-0.196467,1.192675},
+  {0.798056,0.142119},
+  {-1.061991,0.018563},
+  {-0.560025,0.370005},
+  {0.454753,-0.180904},
+  {-0.998511,0.325013},
+  {-0.821580,-0.926141},
+  {0.234012,-1.400391},
+  {-0.674742,-0.704986},
+  {-0.291769,1.030446},
+  {-0.034057,0.722172},
+  {0.696109,-0.239704},
+  {0.209895,-1.576507},
+  {-0.157850,0.127201},
+  {0.466905,0.165965},
+  {0.723092,-0.550305},
+  {0.061567,0.078169},
+  {-0.065939,0.569606},
+  {-0.133807,0.770113},
+  {0.393001,0.504942},
+  {0.938111,-0.161913},
+  {-0.597112,0.176459},
+  {-0.258463,0.179758},
+  {1.377765,-0.886022},
+  {0.438264,0.736861},
+  {-1.525573,0.999277},
+  {-0.620013,0.193526},
+  {0.575873,-1.214428},
+  {-0.126903,0.386866},
+  {0.530483,0.213737},
+  {0.088473,-0.115534},
+  {-0.212839,0.385450},
+  {-1.321082,0.296746},
+  {0.250801,0.116243},
+  {-0.419752,0.580050},
+  {0.941619,-1.096349},
+  {0.016156,-0.012206},
+  {0.223729,-0.513092},
+  {0.431069,-0.090005},
+  {-0.564370,0.121675},
+  {0.207579,0.543705},
+  {-0.569522,0.970283},
+  {0.817061,0.419924},
+  {-0.249714,0.263547},
+  {0.715514,0.375579},
+  {0.601764,0.078943},
+  {0.912619,-0.785623},
+  {-0.761932,0.233378},
+  {0.345236,-0.083941},
+  {0.256879,0.092192},
+  {1.596566,0.978531},
+  {0.233048,0.142618},
+  {0.613216,-0.032437},
+  {0.829523,-0.330173},
+  {0.230123,-0.145399},
+  {1.458398,1.026591},
+  {0.430070,0.208748},
+  {0.266168,0.118494},
+  {0.539393,-0.277606},
+  {-0.413476,-0.313748},
+  {-0.369556,0.091205},
+  {-0.326428,-0.843489},
+  {0.876747,0.200702},
+  {-0.649832,0.677572},
+  {-0.132473,-0.408711},
+  {-0.189154,-1.243630},
+  {0.300237,-0.606909},
+  {-0.727253,-1.333235},
+  {0.491897,0.548159},
+  {0.129355,1.663229},
+  {-0.845514,-0.240228},
+  {-0.375039,-0.919784},
+  {0.911949,-0.218323},
+  {0.235257,0.391849},
+  {-0.246544,0.164098},
+  {-0.231634,0.840406},
+  {0.469351,-0.182122},
+  {-1.743900,0.992432},
+  {0.852607,-0.539289},
+  {0.795267,-0.387124},
+  {-0.185710,1.359292},
+  {0.094303,0.079949},
+  {0.642032,0.393244},
+  {-0.155963,0.192307},
+  {-0.348090,-0.970893},
+  {0.392175,0.779526},
+  {0.325050,-1.394403},
+  {-0.089091,-0.577495},
+  {-0.483524,0.167122},
+  {-0.942847,0.788769},
+  {-0.766730,-0.156880},
+  {0.105378,0.028165},
+  {-0.514349,0.215037},
+  {0.561907,-0.681160},
+  {0.734924,0.641628},
+  {-0.145145,-0.683320},
+  {0.393664,0.363491},
+  {-0.681003,0.495072},
+  {0.548521,-0.587928},
+  {-0.058075,0.565056},
+  {-0.107237,1.111712},
+  {0.172436,-0.254398},
+  {0.227540,-0.704157},
+  {0.265045,-0.730209},
+  {-0.869922,-0.474264},
+  {-0.424165,0.721119},
+  {-1.396401,-0.989424},
+  {0.221913,-0.297296},
+  {0.286758,-1.498876},
+  {0.359150,0.152013},
+  {0.112532,0.792481},
+  {-0.518915,0.573917},
+  {0.223169,-0.581940},
+  {0.093260,-0.638841},
+  {0.366104,0.042771},
+  {0.417517,0.376103},
+  {0.991679,-0.041029},
+  {-0.060651,-0.884169},
+  {-1.391370,0.124718},
+  {1.114556,1.972558},
+  {1.020741,-0.667193},
+  {-0.025144,0.571881},
+  {0.669084,-0.756397},
+  {0.439585,-0.056732},
+  {0.015199,0.202094},
+  {0.566927,-0.613071},
+  {-0.253624,0.616822},
+  {-1.725917,0.187096},
+  {-0.845198,1.593293},
+  {-0.490629,-0.100485},
+  {0.571619,-0.604498},
+  {-0.018727,-0.145532},
+  {-0.003540,0.086011},
+  {-0.606243,-0.821588},
+  {0.783794,0.540017},
+  {1.102898,-0.136964},
+  {0.216892,1.340393},
+  {0.342599,-1.539241},
+  {-0.575259,0.204180},
+  {-1.488872,0.715385},
+  {-0.221673,-0.742431},
+  {-0.113355,0.020189},
+  {0.213762,-0.406233},
+  {-0.170202,-1.176525},
+  {-0.131939,-0.115900},
+  {0.612452,0.453876},
+  {-0.743530,-0.455021},
+  {0.466304,0.328039},
+  {-0.258516,0.475259},
+  {-0.516879,-0.380717},
+  {-1.270884,-0.082694},
+  {0.501087,-0.200590},
+  {-1.445308,-0.484118},
+  {0.650660,-0.526876},
+  {-0.229810,-0.738966},
+  {-0.802840,0.194996},
+  {0.829044,-0.227303},
+  {-0.054933,-0.287901},
+  {0.285078,0.281370},
+  {-0.363464,0.182841},
+  {0.075010,-1.057872},
+  {-0.589787,-0.269938},
+  {1.178426,0.146037},
+  {-0.073736,1.967197},
+  {0.910865,0.370300},
+  {-0.153322,0.395913},
+  {1.123574,0.170210},
+  {-0.882067,0.376414},
+  {0.111788,0.783705},
+  {-0.791890,0.455797},
+  {0.724860,0.924557},
+  {-1.174621,1.356142},
+  {-1.081595,-0.106305},
+  {-0.006296,-0.172133},
+  {-0.122594,-1.407199},
+  {-0.404103,0.582921},
+  {-0.882765,0.122557},
+  {0.094063,-0.110042},
+  {1.335416,-0.733367},
+  {0.464591,-0.575710},
+  {-0.121591,-0.127096},
+  {-0.062471,1.097518},
+  {0.159503,1.027292},
+  {-1.093872,-0.247750},
+  {0.529288,-0.443974},
+  {-0.136074,-0.048432},
+  {0.556999,0.495463},
+  {0.588577,0.128776},
+  {0.462049,-0.451937},
+  {0.353590,-0.723830},
+  {0.204804,-1.625933},
+  {0.092930,1.161258},
+  {-1.224485,0.628751},
+  {0.229420,-0.877564},
+  {0.739953,-0.878338},
+  {-0.892648,0.514262},
+  {-0.544203,0.616829},
+  {1.134951,-1.505910},
+  {0.708691,0.176345},
+  {-0.292243,0.137628},
+  {-0.337737,-0.596135},
+  {1.471883,0.535997},
+  {-0.850951,0.121347},
+  {0.243537,-0.589604},
+  {-0.059771,1.176776},
+  {-0.454490,0.804287},
+  {0.070382,0.030761},
+  {0.242788,0.176748},
+  {-0.126759,0.129941},
+  {0.030666,-0.850073},
+  {1.875655,0.587808},
+  {-0.161780,-1.784124},
+  {-0.569807,0.916039},
+  {-0.569185,0.072547},
+  {-1.127872,0.026428},
+  {-1.150343,1.487388},
+  {0.720566,0.922631},
+  {0.383465,-1.084402},
+  {-1.237511,0.762091},
+  {-0.099930,-0.928349},
+  {-0.601861,-0.484212},
+  {0.014186,0.985724},
+  {0.396531,-0.374346},
+  {0.370483,0.478921},
+  {0.417636,0.285218},
+  {0.144493,0.855940},
+  {1.513194,-0.430838},
+  {-0.286139,-0.974602},
+  {-1.347122,-1.183399},
+  {-0.109208,-0.834271},
+  {-0.070154,-1.123663},
+  {0.980670,0.398785},
+  {1.504316,-1.491271},
+  {0.365317,0.703937},
+  {0.327227,-1.471393},
+  {0.779325,-0.291336},
+  {-0.813175,-0.633449},
+  {0.201307,-1.315156},
+  {-0.157624,0.806373},
+  {1.101852,0.306818},
+  {0.548022,0.618568},
+  {0.914485,-1.093983},
+  {-0.788237,1.330140},
+  {0.204645,-1.260284},
+  {0.708261,-0.487650},
+  {0.831419,0.494045},
+  {-0.479281,-0.174932},
+  {0.274606,0.031707},
+  {0.511466,1.479375},
+  {-0.749887,0.138556},
+  {0.094436,-1.604624},
+  {1.701213,-0.021478},
+  {1.273051,0.873564},
+  {-0.564715,-0.604606},
+  {0.576919,-0.577415},
+  {0.854536,0.069007},
+  {2.004698,-0.186701},
+  {-1.020772,0.648632},
+  {-0.474304,-0.256917},
+  {0.280593,-0.442013},
+  {0.609646,-0.099227},
+  {-0.587909,-1.324509},
+  {-0.478677,-0.380842},
+  {0.992419,-0.833282},
+  {-0.207837,0.203639},
+  {0.504914,0.234515},
+  {-0.266033,0.132612},
+  {-0.242541,-0.095664},
+  {-0.167233,-0.590706},
+  {-1.276869,0.288847},
+  {-0.312084,-0.687477},
+  {0.271583,-0.587164},
+  {0.515093,0.888483},
+  {-0.886180,1.600277},
+  {0.761687,1.283905},
+  {-0.917327,-0.468507},
+  {-0.255153,0.234853},
+  {-0.698140,0.280238},
+  {-0.173308,-0.549159},
+  {1.163074,-0.136380},
+  {-0.522856,-1.545376},
+  {-0.250713,-0.577033},
+  {0.127714,0.573650},
+  {-0.619459,0.761195},
+  {0.854662,-0.335280},
+  {1.288629,-1.596849},
+  {-0.259143,0.994771},
+  {-0.089218,0.323881},
+  {1.037082,-0.027840},
+  {0.020579,1.366726},
+  {-0.158254,0.495453},
+  {0.551658,0.631316},
+  {0.038543,-0.710163},
+  {0.702737,-1.985090},
+  {1.398746,-0.143418},
+  {0.084599,-0.676724},
+  {-0.015678,1.464065},
+  {-0.034517,-1.102207},
+  {-0.094801,-0.520467},
+  {-0.203622,0.612699},
+  {-1.132184,-0.715451},
+  {-0.130513,0.631629},
+  {-0.340655,0.517577},
+  {-1.132617,-0.041877},
+  {-0.913628,0.061052},
+  {1.393766,-0.805041},
+  {0.243021,-0.275513},
+  {0.592899,0.812328},
+  {-0.181057,0.511301},
+  {-0.230935,0.289646},
+  {-0.253628,1.248452},
+  {-0.375765,-0.450903},
+  {0.175142,-0.879180},
+  {0.632521,0.051703},
+  {0.714207,1.053456},
+  {-0.848408,1.064349},
+  {-0.233667,-0.270396},
+  {0.383107,-0.240141},
+  {0.507137,-0.249806},
+  {-0.030230,-0.356838},
+  {-0.578340,0.125787},
+  {-1.095438,-1.281125},
+  {0.471165,-1.473161},
+  {-0.176499,-0.292983},
+  {0.283998,-0.579375},
+  {-1.456174,0.442805},
+  {-1.091059,-0.554400},
+  {0.325498,1.215230},
+  {0.374914,-0.970670},
+  {1.014939,0.866143},
+  {-0.947639,0.514860},
+  {0.945109,-0.393500},
+  {-1.063523,-0.388257},
+  {0.026398,-0.066196},
+  {-0.485485,0.511262},
+  {0.171215,-0.511392},
+  {-1.389303,-0.782160},
+  {0.119798,-0.872876},
+  {-0.380890,-0.950004},
+  {-0.454074,0.379206},
+  {-0.150043,-0.133012},
+  {0.209178,0.071162},
+  {0.194253,-0.916240},
+  {-0.696335,-1.251679},
+  {-0.227848,0.695565},
+  {-0.243941,-0.084309},
+  {-0.950502,-0.635794},
+  {-0.290364,0.216578},
+  {-0.751428,-1.213585},
+  {0.460577,-0.149599},
+  {0.324715,0.166467},
+  {-0.614041,-1.173885},
+  {-0.142238,-0.336419},
+  {-1.471493,-0.936717},
+  {1.646690,0.184204},
+  {0.225939,0.300060},
+  {-0.128450,0.389350},
+  {0.727421,-0.454894},
+  {-0.435942,0.105538},
+  {1.205978,0.100260},
+  {-1.315567,0.308342},
+  {0.754698,1.164033},
+  {-0.107954,-0.172451},
+  {-1.047203,1.015069},
+  {-1.389840,-0.266683},
+  {0.547945,0.616535},
+  {-0.434114,0.849453},
+  {0.071122,-0.277037},
+  {-0.050800,0.284288},
+  {-0.165278,0.009121},
+  {-0.219966,-0.098418},
+  {0.198508,0.353809},
+  {-0.581533,0.448088},
+  {-1.784726,-1.161621},
+  {-0.604861,-0.274908},
+  {0.183057,0.051142},
+  {-0.317797,0.278299},
+  {-0.850828,-0.630589},
+  {0.104573,0.285301},
+  {0.105866,0.698211},
+  {-0.180861,-0.862928},
+  {0.475285,-0.838884},
+  {0.532029,-1.353946},
+  {-0.605465,1.385299},
+  {0.218651,-1.214866},
+  {2.160576,-0.144045},
+  {0.168189,1.107664},
+  {0.299490,-0.176740},
+  {-0.396194,0.210866},
+  {-0.125884,-0.224011},
+  {0.853672,0.228498},
+  {-1.748178,-1.154824},
+  {0.367379,0.232790},
+  {-0.181073,-0.618603},
+  {-0.789253,-0.907517},
+  {0.589666,0.083053},
+  {0.205531,-0.292960},
+  {-1.755342,-0.647660},
+  {1.320671,0.483386},
+  {0.751741,-0.776958},
+  {0.895885,0.848563},
+  {0.581838,-0.625789},
+  {-0.172855,-0.093791},
+  {1.730868,-0.185926},
+  {-0.859963,-0.199970},
+  {0.619064,-1.075834},
+  {-0.751592,-0.307590},
+  {0.383126,0.058031},
+  {0.532780,-0.855648},
+  {-0.809753,0.598019},
+  {0.523282,-0.210299},
+  {0.092903,0.620162},
+  {-0.841020,-0.066447},
+  {-0.888254,0.244874},
+  {-0.225321,-0.358074},
+  {-0.523697,0.142496},
+  {-0.211782,0.560938},
+  {0.850574,-0.508918},
+  {-0.016610,0.930612},
+  {-0.170152,-0.661760},
+  {0.379929,0.104789},
+  {-0.781353,0.502040},
+  {1.259342,-0.010921},
+  {-0.135465,0.122281},
+  {0.166991,-0.732114},
+  {0.955615,-0.124115},
+  {1.109480,-1.575200},
+  {0.054263,-0.253799},
+  {0.862238,-1.307799},
+  {0.016864,0.606661},
+  {0.483294,-0.230111},
+  {1.663652,0.729566},
+  {-0.611224,-0.653048},
+  {-1.924986,-0.524554},
+  {-0.603593,-0.245722},
+  {0.878295,0.316568},
+  {0.052504,-1.019809},
+  {0.512341,0.171092},
+  {0.774275,-0.490241},
+  {-1.055341,0.751595},
+  {-1.688396,1.987387},
+  {-0.902226,-0.336708},
+  {-0.433191,-0.099476},
+  {-0.920050,1.128085},
+  {-1.100896,0.374304},
+  {0.388182,1.245751},
+  {0.280377,0.511610},
+  {-0.344954,-0.349710},
+  {0.567448,-0.222402},
+  {-0.230275,0.053800},
+  {-1.450383,-0.655175},
+  {-0.140144,0.256758},
+  {-1.291789,0.096818},
+  {-0.626539,-1.194533},
+  {0.550245,-0.702534},
+  {0.445211,0.411623},
+  {0.860433,-0.689320},
+  {0.660554,-0.055735},
+  {0.924256,-0.222386},
+  {1.467143,-0.039871},
+  {0.423189,-0.130886},
+  {-0.157257,-0.253543},
+  {0.054858,0.012374},
+  {0.004722,-0.181412},
+  {1.204185,-0.360653},
+  {0.683748,-1.078223},
+  {0.114180,0.204924},
+  {-0.209641,0.052979},
+  {0.590545,-0.623896},
+  {0.855198,0.077004},
+  {-0.183976,0.390004},
+  {0.562404,-0.634269},
+  {0.638455,0.770984},
+  {0.539077,0.058849},
+  {1.143837,-0.619012},
+  {0.379303,0.131913},
+  {0.694961,-0.856962},
+  {1.031972,-0.095841},
+  {-0.414443,-0.130743},
+  {-0.530670,-1.027409},
+  {0.532992,0.593755},
+  {-0.302745,0.408516},
+  {-0.163969,-0.009049},
+  {-0.937897,0.569411},
+  {0.236075,-0.118090},
+  {0.367388,0.920104},
+  {-0.228411,-0.020714},
+  {0.450075,-1.376905},
+  {0.672742,0.878365},
+  {0.272849,0.717775},
+  {0.332603,-0.084299},
+  {-0.123209,0.546980},
+  {1.599618,-0.734019},
+  {-1.207434,-1.476439},
+  {0.126576,0.023655},
+  {1.085747,0.148754},
+  {-1.156599,-0.185243},
+  {1.100054,-0.369996},
+  {-0.075626,-0.451481},
+  {-0.905205,-0.526888},
+  {-0.401543,-0.591241},
+  {-0.114917,-0.419392},
+  {0.538569,-0.347340},
+  {0.301107,-0.265479},
+  {-1.341466,-0.843870},
+  {-1.296856,-0.888799},
+  {0.498068,-0.039892},
+  {-0.390159,0.729649},
+  {1.171404,1.213731},
+  {-0.539536,-0.533475},
+  {-0.471922,-0.364102},
+  {0.204217,-0.768619},
+  {0.692290,-0.199941},
+  {0.682400,2.105154},
+  {-0.663000,0.094841},
+  {1.190975,1.491593},
+  {-0.756086,0.111941},
+  {0.061172,0.566461},
+  {-0.048715,0.143162},
+  {0.311618,-0.313990},
+  {0.310462,0.386462},
+  {0.466845,0.225448},
+  {0.572650,-1.340082},
+  {-0.824610,0.849502},
+  {0.746589,-0.306592},
+  {1.392851,0.308872},
+  {0.506791,0.509163},
+  {-1.012017,0.338057},
+  {-0.425655,0.744355},
+  {-0.177273,-1.268582},
+  {1.931480,-0.463406},
+  {-1.005768,-0.526282},
+  {-0.554007,0.732979},
+  {0.203002,1.016918},
+  {-0.343580,0.392522},
+  {0.671733,0.125681},
+  {-1.033077,-0.210715},
+  {-0.047144,-1.546564},
+  {0.263303,-0.350745},
+  {-0.790377,-0.556737},
+  {0.347599,-0.244305},
+  {-0.267536,-0.557566},
+  {-0.914996,-0.772484},
+  {-1.415204,0.476464},
+  {0.636720,0.271362},
+  {-0.160421,-0.202122},
+  {0.256900,-0.971435},
+  {-1.341629,-1.340080},
+  {-0.996941,-0.175151},
+  {-0.275634,-0.620064},
+  {0.277806,1.181420},
+  {0.257685,-0.644443},
+  {0.972835,0.904661},
+  {-0.069391,0.979036},
+  {0.033424,1.180349},
+  {1.601465,-0.899762},
+  {-1.159530,-0.513358},
+  {0.659085,-0.351394},
+  {-0.778353,0.391627},
+  {-0.732485,-0.817011},
+  {0.160577,-0.745746},
+  {-1.425300,0.587289},
+  {0.466481,0.028874},
+  {0.257711,-0.211149},
+  {0.360215,0.446898},
+  {0.160066,-0.290423},
+  {-0.826929,0.104860},
+  {-1.006527,1.418773},
+  {0.086332,-0.509908},
+  {-0.775915,-0.277061},
+  {-0.568888,-1.679972},
+  {-0.636057,0.987827},
+  {-0.308029,0.307089},
+  {0.717339,-0.888667},
+  {-0.398455,0.051524},
+  {1.624831,-0.428584},
+  {-0.995265,-0.949414},
+  {-0.574018,-0.660601},
+  {0.821218,0.649943},
+  {-0.066875,-0.742312},
+  {-1.042409,-0.345767},
+  {-0.694825,-0.086997},
+  {0.892671,0.304710},
+  {1.463746,1.347942},
+  {-0.794659,-1.465119},
+  {0.093978,-1.391761},
+  {-0.289519,0.622867},
+  {-0.038301,-0.287028},
+  {0.225742,-0.501018},
+  {-0.619576,1.728619},
+  {-0.078345,0.521977},
+  {0.410487,0.768793},
+  {0.898314,-1.505122},
+  {0.982556,-0.321653},
+  {-0.156688,0.426663},
+  {0.914887,0.476645},
+  {-0.661801,-1.162848},
+  {-0.834380,-0.187532},
+  {-1.033042,-0.657361},
+  {-0.258103,-0.279691},
+  {-0.077377,-0.617789},
+  {-0.067528,-0.795636},
+  {0.697166,1.250363},
+  {0.612638,0.426930},
+  {0.414738,0.159230},
+  {0.012610,1.110968},
+  {0.088986,0.174993},
+  {-0.701699,-0.585427},
+  {0.005547,-1.001461},
+  {-0.499370,-0.219090},
+  {-0.409379,-1.410114},
+  {0.678592,1.914758},
+  {-0.333608,0.094601},
+  {1.473032,-0.764558},
+  {0.234098,0.682258},
+  {-0.764432,0.203001},
+  {-0.286558,-0.776227},
+  {0.015636,-0.427128},
+  {-0.829637,-0.587309},
+  {0.126426,-0.046741},
+  {-0.999990,-0.782663},
+  {-1.231364,-0.812437},
+  {-0.064503,-0.714886},
+  {-0.917891,0.770603},
+  {-0.586602,0.007693},
+  {0.403223,0.712644},
+  {-0.008010,-0.902316},
+  {0.357368,0.403032},
+  {0.138081,-0.123957},
+  {-0.283588,0.063573},
+  {-0.309539,0.658890},
+  {-0.406599,0.958829},
+  {-0.708649,-0.300691},
+  {-0.292065,0.281290},
+  {0.654537,0.474224},
+  {-0.708419,-2.474893},
+  {-0.285932,0.822338},
+  {-1.107321,-0.186473},
+  {-0.369601,-0.659469},
+  {0.617200,-0.315311},
+  {0.185574,-1.073683},
+  {-1.332198,0.646972},
+  {1.358647,-0.343407},
+  {0.423292,0.187194},
+  {-1.766024,0.026657},
+  {-0.511465,-0.056579},
+  {-0.202844,-0.666845},
+  {-0.061273,0.149654},
+  {-0.160488,0.253664},
+  {-0.336715,0.856404},
+  {-0.211530,0.286960},
+  {-0.096027,-0.438433},
+  {-0.123255,0.410071},
+  {-0.588208,0.110857},
+  {-0.160651,-0.237762},
+  {0.178849,-0.486365},
+  {0.523072,-0.604543},
+  {-0.481635,0.822471},
+  {-1.427760,1.475099},
+  {-0.015193,0.056991},
+  {-0.020920,-0.628689},
+  {-0.662725,-0.334047},
+  {-0.029955,0.271499},
+  {-0.549856,0.193420},
+  {-0.591084,-0.460397},
+  {-0.847475,0.176087},
+  {0.134666,1.535474},
+  {-0.404517,1.774605},
+  {-0.012591,-0.025081},
+  {0.304635,0.349055},
+  {1.032524,-1.067513},
+  {-0.654717,-0.443237},
+  {0.354067,-0.906890},
+  {0.645732,-0.808004},
+  {0.708526,0.422639},
+  {0.251741,-0.199950},
+  {-0.343301,-0.372559},
+  {0.521966,0.293809},
+  {0.596219,1.459711},
+  {-0.911900,1.090172},
+  {-0.180459,-0.242334},
+  {0.043777,-0.308086},
+  {0.892502,-0.297267},
+  {0.069414,0.548758},
+  {0.106618,0.638483},
+  {0.075271,0.328460},
+  {-0.453758,0.763184},
+  {0.873083,-0.518432},
+  {-0.165817,-0.466517},
+  {-0.777957,0.195349},
+  {-1.045421,-0.135624},
+  {1.085889,0.201413},
+  {0.045273,0.861950},
+  {-0.380225,-0.540513},
+  {1.234628,-0.061586},
+  {0.388294,0.042646},
+  {-1.184967,-0.334204},
+  {-0.431482,0.137044},
+  {-0.260536,-0.255510},
+  {0.676812,-1.129665},
+  {0.060250,-0.101155},
+  {0.177268,0.504934},
+  {0.447116,0.913391},
+  {-0.188139,0.308266},
+  {-0.461521,-0.562924},
+  {0.803880,-0.403873},
+  {-0.719793,0.283642},
+  {-0.274215,-1.343825},
+  {-0.176226,-0.931566},
+  {-0.456589,0.988810},
+  {0.069589,-0.085009},
+  {0.498388,0.661623},
+  {1.764237,-1.921451},
+  {-0.520769,-0.283433},
+  {-0.863480,-0.545718},
+  {0.164524,-1.140960},
+  {0.391842,1.388107},
+  {-0.211966,-0.760097},
+  {0.882238,0.726142},
+  {-0.494735,-0.147398},
+  {-2.130035,-0.271010},
+  {-0.091024,-0.085686},
+  {-1.139421,0.482023},
+  {-1.313630,0.069675},
+  {-1.013372,-0.030979},
+  {-0.010000,-0.309232},
+  {0.015798,-0.454868},
+  {-0.021211,1.170452},
+  {0.733800,0.657433},
+  {-0.564449,-1.202041},
+  {-1.438305,-0.225477},
+  {0.737473,0.034093},
+  {-0.124011,0.017096},
+  {-1.054430,-0.490369},
+  {0.735048,-0.170665},
+  {-0.603735,-0.398150},
+  {-0.291035,-1.773649},
+  {-0.230866,0.024045},
+  {0.565597,-0.230533},
+  {0.341789,1.338716},
+  {-0.174622,-0.278944},
+  {-0.235408,-1.074645},
+  {0.457028,0.409652},
+  {0.792267,0.082481},
+  {0.739603,-0.207675},
+  {-0.446134,0.728303},
+  {0.271171,0.646737},
+  {-0.080809,-0.597354},
+  {-0.333713,0.650210},
+  {-0.058765,-0.037884},
+  {0.313115,0.179699},
+  {1.061631,0.029643},
+  {-0.718130,-0.867332},
+  {0.161520,-0.373053},
+  {0.115240,1.018624},
+  {-1.401570,-1.811324},
+  {-0.389145,1.565653},
+  {0.275466,0.553665},
+  {1.366925,-0.550564},
+  {-0.653708,-0.492507},
+  {0.639135,0.108763},
+  {0.502588,1.583952},
+  {-0.959099,1.271320},
+  {-1.233735,0.101634},
+  {-0.740340,-0.248321},
+  {-0.892102,0.109857},
+  {-0.345742,0.073819},
+  {0.031049,-0.115825},
+  {0.366890,1.202980},
+  {-0.555795,0.858266},
+  {-0.789748,-0.582250},
+  {-0.684044,-0.073831},
+  {0.431366,-0.264677},
+  {-0.251106,-1.079765},
+  {-0.048445,-0.527598},
+  {-0.257022,0.807331},
+  {0.604370,0.108487},
+  {1.193560,-0.504331},
+  {0.887205,0.223083},
+  {0.165226,0.181709},
+  {-0.694678,0.305534},
+  {-0.539173,-0.699254},
+  {-0.962349,-2.031904},
+  {0.437054,0.981274},
+  {0.472644,0.330887},
+  {0.577628,0.332816},
+  {-0.547620,-0.333722},
+  {-0.651263,2.080435},
+  {-0.084852,0.079156},
+  {-0.760344,0.805795},
+  {0.499899,-1.470379},
+  {0.351524,0.328809},
+  {0.080884,-0.587359},
+  {-0.553406,-0.169034},
+  {0.039425,-0.538786},
+  {0.858310,-0.140728},
+  {0.472670,-2.246532},
+  {-0.368775,-0.323302},
+  {0.090378,-1.378154},
+  {-0.550284,0.507064},
+  {0.539224,0.603538},
+  {-0.000691,-1.727633},
+  {-2.003468,-0.661973},
+  {0.337784,0.651070},
+  {0.162028,0.567114},
+  {-0.067531,0.050097},
+  {0.182332,-0.719324},
+  {-1.474951,0.685114},
+  {0.860035,0.235277},
+  {0.673692,-0.745029},
+  {0.163864,0.823959},
+  {0.712323,-0.579740},
+  {0.133995,-0.852349},
+  {-0.093329,-0.759119},
+  {0.285367,1.120202},
+  {0.187071,-0.415625},
+  {0.522904,0.451246},
+  {0.757153,0.243609},
+  {0.184169,1.090276},
+  {1.479287,-1.344383},
+  {1.487636,0.349166},
+  {-0.095602,0.755634},
+  {-0.112605,0.207789},
+  {-0.441569,-0.286210},
+  {-0.409203,1.547667},
+  {-0.546806,-1.646303},
+  {1.074615,1.044879},
+  {-0.434627,-0.525903},
+  {-0.242109,1.227347},
+  {-1.319122,0.275312},
+  {-0.545729,0.662611},
+  {0.343853,0.157724},
+  {0.475258,0.149229},
+  {0.253291,1.076345},
+  {-0.570123,-1.272515},
+  {-0.186610,0.269897},
+  {-0.189057,1.120619},
+  {-0.383515,0.226731},
+  {0.924259,-0.098409},
+  {-0.080234,-0.649794},
+  {-0.726238,-1.386272},
+  {0.806442,-0.219207},
+  {0.024879,0.089845},
+  {0.913936,-0.796274},
+  {2.617004,-0.280960},
+  {-0.718628,-0.178037},
+  {-0.428151,0.215331},
+  {-0.073535,-0.606667},
+  {0.254862,0.639116},
+  {1.488909,0.267331},
+  {-0.583632,-0.698212},
+  {1.157905,0.856185},
+  {0.267413,0.309240},
+  {-0.460028,0.787779},
+  {0.527296,0.364704},
+  {0.341824,-1.132002},
+  {0.758196,0.233237},
+  {0.556152,0.517602},
+  {0.066575,-0.831919},
+  {0.517617,-1.003521},
+  {-0.448421,0.717349},
+  {0.254943,0.001274},
+  {-0.525383,-0.477606},
+  {1.091618,0.208053},
+  {-0.123831,-0.791330},
+  {0.334160,0.226185},
+  {-0.698222,0.706486},
+  {-0.032881,0.242425},
+  {-0.281343,0.751205},
+  {0.632088,-1.214175},
+  {0.073367,-1.174985},
+  {-0.324776,-0.120150},
+  {0.164874,0.111320},
+  {0.609620,-0.439175},
+  {0.031007,0.000219},
+  {1.028218,-0.287004},
+  {1.158747,0.853374},
+  {-1.199486,-0.275183},
+  {-1.283849,1.091030},
+  {0.561488,-0.120327},
+  {-0.287822,-0.044037},
+  {-0.968829,-0.687665},
+  {1.352591,-0.243109},
+  {-1.373144,0.694374},
+  {-0.378153,0.037286},
+  {-0.802495,0.406625},
+  {-0.041211,-0.643437},
+  {0.185728,-0.003745},
+  {-0.305742,-0.281991},
+  {0.387514,-1.518495},
+  {-0.242799,0.206669},
+  {-0.669666,-0.599745},
+  {-0.141009,-2.414735},
+  {-0.003491,-0.033090},
+  {-0.289344,-0.418806},
+  {0.520367,0.013915},
+  {0.555563,-1.274973},
+  {-0.324143,0.296732},
+  {-1.457603,0.238373},
+  {0.410639,0.101798},
+  {-1.012753,-0.935328},
+  {0.899841,0.309905},
+  {0.127096,-0.954350},
+  {0.106654,1.147259},
+  {-0.355125,-0.287927},
+  {-1.547840,-0.332855},
+  {-0.733110,0.032549},
+  {-0.271676,0.273160},
+  {-0.415254,-1.088883},
+  {0.067924,-1.032075},
+  {0.476029,-0.014800},
+  {-0.003191,-0.439740},
+  {-0.798743,0.822659},
+  {0.883440,0.479619},
+  {-1.455205,-0.328712},
+  {0.775377,0.211114},
+  {1.220351,0.695741},
+  {0.452471,1.035777},
+  {0.341504,-1.320770},
+  {-0.611155,0.468035},
+  {0.908185,0.273328},
+  {0.292692,-1.200411},
+  {-0.033289,-1.174946},
+  {0.994273,-0.733959},
+  {0.214130,0.413516},
+  {0.274615,-0.372335},
+  {1.346686,-1.437341},
+  {-0.197733,-0.578892},
+  {0.149638,-0.107375},
+  {-0.339736,0.034751},
+  {-0.338912,0.066107},
+  {0.750437,0.078081},
+  {-1.049538,0.591718},
+  {-0.041805,0.895005},
+  {-1.095430,0.700039},
+  {-0.235200,0.094713},
+  {0.065897,0.602921},
+  {0.755398,-0.108273},
+  {1.091147,0.071925},
+  {0.228578,-0.294732},
+  {-0.584694,-0.554632},
+  {-0.078499,0.146121},
+  {-0.915751,-0.799416},
+  {-0.365473,0.373294},
+  {-0.531644,-0.071814},
+  {0.721813,0.581123},
+  {-0.110709,0.244037},
+  {0.199982,1.816332},
+  {0.564345,1.371369},
+  {0.467000,1.041223},
+  {-0.686056,0.372524},
+  {0.104741,-0.231289},
+  {0.409822,-0.375921},
+  {0.031726,-0.309260},
+  {1.183292,0.898475},
+  {-0.493938,-0.680656},
+  {0.890296,0.420048},
+  {0.070555,-0.613145},
+  {-0.022719,0.779646},
+  {1.421551,-0.488215},
+  {-1.226503,1.639620},
+  {-0.306046,0.416864},
+  {-0.696823,0.344132},
+  {-0.143656,1.441148},
+  {-0.689809,-0.700984},
+  {0.463316,0.449139},
+  {-1.364012,0.198649},
+  {0.449165,0.742472},
+  {-0.486011,-1.473443},
+  {0.500896,0.833914},
+  {-0.622554,-0.239606},
+  {1.189831,-1.242437},
+  {1.151693,-0.330836},
+  {0.920582,-0.666624},
+  {-1.224090,-1.875929},
+  {-1.092502,-0.769761},
+  {-0.262561,-0.202329},
+  {0.431854,1.719011},
+  {-0.428703,-0.207687},
+  {0.564636,0.288137},
+  {-0.667355,0.277334},
+  {0.180266,0.623707},
+  {-0.315467,-0.069400},
+  {-0.601639,-0.462335},
+  {-0.948292,-0.538306},
+  {-1.253119,-0.336230},
+  {-0.049082,0.253962},
+  {-0.451911,0.428742},
+  {0.736800,0.882449},
+  {-0.412044,0.366809},
+  {-0.467545,-1.006095},
+  {1.008279,1.350596},
+  {-0.359243,1.473972},
+  {0.331398,-0.803076},
+  {-0.297361,-0.463851},
+  {0.201236,-0.107912},
+  {0.239863,0.923164},
+  {-0.353475,0.650233},
+  {0.384891,0.803903},
+  {0.302545,1.670567},
+  {0.799741,0.176856},
+  {-0.024317,0.120099},
+  {0.008041,-0.350004},
+  {0.230942,0.570515},
+  {-0.132010,0.455897},
+  {-0.263291,-0.539349},
+  {-0.645935,0.218008},
+  {-0.463458,0.613702},
+  {0.243487,1.705323},
+  {-0.868175,1.548390},
+  {-0.227668,1.410199},
+  {0.658615,0.988933},
+  {-1.447789,0.664133},
+  {0.798315,0.707355},
+  {0.425196,-1.360819},
+  {-0.135508,-1.272751},
+  {0.647140,0.224335},
+  {1.161476,0.319277},
+  {-0.480896,0.374320},
+  {1.878285,0.118100},
+  {-0.211065,2.614610},
+  {0.436903,-0.128683},
+  {1.200507,-0.109365},
+  {-0.119335,-0.098252},
+  {0.589978,0.683516},
+  {-0.940828,1.101724},
+  {-1.549157,0.580937},
+  {-0.045247,1.021449},
+  {0.032804,-0.767668},
+  {0.999415,-0.176564},
+  {-0.273115,-1.412497},
+  {0.167989,-0.295090},
+  {-0.036130,-0.505037},
+  {0.340076,-0.586571},
+  {-0.911702,0.260780},
+  {-0.738639,-1.333492},
+  {0.734417,-1.151579},
+  {-1.217327,-0.926407},
+  {0.231592,0.190441},
+  {0.737205,-0.440307},
+  {0.438334,-0.481113},
+  {0.415552,0.334575},
+  {0.720010,0.454014},
+  {-0.802826,-0.345235},
+  {-1.888756,0.673207},
+  {-0.545520,-0.182574},
+  {1.213482,0.417727},
+  {-1.244954,0.421645},
+  {-0.259205,-0.972422},
+  {-0.804418,0.298643},
+  {-0.497450,-1.013039},
+  {-0.363112,-0.066604},
+  {-0.295601,0.914620},
+  {1.021939,-0.017453},
+  {0.680981,0.298866},
+  {1.107544,0.912255},
+  {0.209341,0.491702},
+  {1.108210,0.582607},
+  {-1.014248,-0.037100},
+  {0.258361,0.684969},
+  {1.045870,-0.304365},
+  {-0.871056,0.100909},
+  {0.823420,-0.126928},
+  {-1.214117,0.314406},
+  {0.871430,0.118769},
+  {-0.231277,0.241207},
+  {0.035972,0.285960},
+  {-0.742023,0.505129},
+  {0.254087,0.341223},
+  {0.454655,-0.525507},
+  {0.755748,-0.462112},
+  {0.587311,0.633949},
+  {-1.442459,0.796037},
+  {-0.318407,-0.290317},
+  {-0.527692,-0.825944},
+  {0.971368,-0.736664},
+  {0.229420,1.203638},
+  {-0.736167,-1.347227},
+  {1.412800,0.828552},
+  {0.740372,-0.240037},
+  {0.876093,-1.017553},
+  {-1.210328,0.107513},
+  {1.137077,0.416858},
+  {-0.750964,-0.268489},
+  {-0.489146,-0.819406},
+  {0.703970,-0.019085},
+  {-0.301573,0.768771},
+  {-0.280863,-0.923373},
+  {-0.372715,0.726574},
+  {0.399350,1.779629},
+  {-0.254864,-0.001700},
+  {0.357948,1.923558},
+  {0.853556,-0.006690},
+  {0.509726,0.496630},
+  {-0.858094,-1.471612},
+  {-1.728564,1.392049},
+  {0.623779,-0.300334},
+  {-0.675676,-0.167689},
+  {-0.849742,-0.641322},
+  {0.697436,-0.283774},
+  {-0.275413,-0.855216},
+  {0.109529,-1.411846},
+  {-0.609845,1.742109},
+  {0.172157,0.641408},
+  {0.021837,0.465026},
+  {-0.022089,-1.116902},
+  {0.964458,0.032398},
+  {0.532234,0.444177},
+  {1.296815,-0.784017},
+  {0.749398,0.180579},
+  {0.574044,-0.467364},
+  {-0.838701,-1.398614},
+  {0.129156,0.516463},
+  {-1.055356,-1.190214},
+  {0.528734,-0.367550},
+  {0.797226,0.908928},
+  {-0.050036,0.414600},
+  {-1.125256,-0.572235},
+  {0.346222,0.074931},
+  {-0.538717,-0.265686},
+  {-0.056401,0.092578},
+  {-0.207907,-0.019935},
+  {1.012684,0.194750},
+  {-0.367511,-0.884469},
+  {0.107956,0.421098},
+  {-0.130369,-0.206243},
+  {-0.422989,0.053730},
+  {0.242778,0.306604},
+  {1.008636,-1.384316},
+  {0.333947,0.589110},
+  {-0.676884,0.681691},
+  {0.948866,0.105958},
+  {0.426000,0.672980},
+  {-1.064013,0.336557},
+  {-0.240377,0.553604},
+  {-1.066478,-0.727211},
+  {-0.640961,-0.431194},
+  {-0.047056,0.430286},
+  {1.455127,0.086339},
+  {1.044019,0.478455},
+  {-0.476166,0.241834},
+  {0.380861,-1.272487},
+  {-0.346503,-0.477271},
+  {0.130709,0.817365},
+  {-0.985777,-1.207054},
+  {-0.046189,-1.202671},
+  {-0.330047,0.026048},
+  {-0.239273,1.694012},
+  {-0.003318,-0.758511},
+  {0.329162,-0.169705},
+  {-0.474235,-0.351765},
+  {0.503979,1.428228},
+  {0.554457,0.574828},
+  {-1.434442,-0.919440},
+  {-0.451345,0.194554},
+  {0.521378,-0.954107},
+  {0.200849,0.335852},
+  {-0.124435,0.284194},
+  {-0.895518,-0.304695},
+  {0.301791,0.348402},
+  {0.093200,-1.526336},
+  {0.633977,0.922629},
+  {0.135976,-0.420617},
+  {0.232458,-0.359167},
+  {0.716139,0.072091},
+  {0.254796,-0.013268},
+  {-0.379655,-0.585246},
+  {-0.022477,0.395561},
+  {-1.191544,-0.383859},
+  {1.447703,-0.326901},
+  {1.032686,1.916231},
+  {-0.883760,0.132351},
+  {0.797983,0.389918},
+  {0.690284,0.427680},
+  {-0.500221,-0.126779},
+  {-0.347322,1.756772},
+  {0.199207,0.321965},
+  {1.155876,-0.872054},
+  {0.930258,-0.737929},
+  {0.355776,0.125540},
+  {0.111132,-0.084686},
+  {-1.765447,-0.399887},
+  {-0.484057,-0.693399},
+  {0.164002,1.979783},
+  {0.861997,0.458612},
+  {1.264516,0.761647},
+  {-0.265837,0.631914},
+  {1.055233,0.348404},
+  {-1.092578,-1.237799},
+  {0.095743,-1.847219},
+  {-0.335968,-0.005423},
+  {-0.404703,0.532334},
+  {-0.681848,-0.884532},
+  {-1.117062,-1.755286},
+  {-0.757974,-0.504821},
+  {-0.349785,0.132151},
+  {0.770082,0.883966},
+  {-0.583158,-0.064996},
+  {-1.505933,0.375539},
+  {0.417048,0.888212},
+  {0.276252,-0.045163},
+  {-0.424762,-0.615027},
+  {-0.365226,-0.268774},
+  {0.618845,-0.605848},
+  {0.164242,-0.422652},
+  {0.645703,0.576558},
+  {0.709919,0.591569},
+  {0.666594,-0.737500},
+  {0.026753,0.073156},
+  {-0.021352,-0.729128},
+  {0.909815,-0.255206},
+  {-0.589314,-0.428360},
+  {0.632534,-0.568628},
+  {0.261934,-1.385056},
+  {0.119414,0.325016},
+  {0.805002,-1.770542},
+  {0.277957,-0.422711},
+  {0.741012,-1.257607},
+  {1.212983,1.441817},
+  {-0.765914,0.535380},
+  {0.317519,-0.080034},
+  {-0.338720,0.031978},
+  {0.437849,0.750522},
+  {0.047748,-0.215083},
+  {-0.962192,-0.546992},
+  {-0.645064,0.921583},
+  {-0.551719,0.389382},
+  {0.105114,-0.340749},
+  {-0.310464,-1.039947},
+  {0.161271,0.002407},
+  {-0.846793,-0.332475},
+  {0.085515,-0.070405},
+  {0.516329,0.565764},
+  {-0.035842,-1.577365},
+  {-0.663475,-0.556161},
+  {0.282857,0.891555},
+  {-1.157957,0.323517},
+  {0.468238,0.244984},
+  {-0.001649,-1.302923},
+  {-0.138291,0.749416},
+  {0.078580,1.089354},
+  {0.049946,-0.266946},
+  {0.138307,-0.213026},
+  {-0.398241,0.031845},
+  {-1.097927,0.485306},
+  {-0.228563,0.686991},
+  {1.497539,0.916258},
+  {0.779815,-0.813548},
+  {-0.470301,-0.251974},
+  {0.471512,1.453454},
+  {-0.334489,-0.584985},
+  {-0.471259,-1.117006},
+  {0.399544,-0.900880},
+  {0.372172,0.255576},
+  {-0.107049,-0.126052},
+  {0.408528,-0.020332},
+  {0.284764,0.268221},
+  {-0.298182,-0.221228},
+  {-1.686760,0.052717},
+  {-0.036532,0.036560},
+  {-0.523159,-0.734161},
+  {-1.978600,-0.302538},
+  {-0.584814,-0.405386},
+  {-0.741486,0.753370},
+  {-0.040990,-0.509271},
+  {-0.541529,-0.386237},
+  {0.566418,0.037714},
+  {0.151225,0.807270},
+  {0.189559,-0.703980},
+  {-0.079181,-0.363765},
+  {-0.031324,-1.081530},
+  {0.083723,-0.843167},
+  {0.221127,0.064046},
+  {-0.427889,0.022969},
+  {0.139107,0.082158},
+  {-0.086705,1.011836},
+  {0.342143,0.246917},
+  {0.207554,0.133077},
+  {-0.080966,1.046769},
+  {-1.059233,-1.085633},
+  {-0.356010,0.718178},
+  {-0.577859,-0.109375},
+  {0.542744,1.108480},
+  {-0.876346,-0.752113},
+  {1.300557,-0.250276},
+  {-1.010939,1.119039},
+  {0.250270,-0.805066},
+  {-0.711292,-0.052695},
+  {-0.272900,0.801570},
+  {-0.129894,-1.472325},
+  {-0.059291,0.042281},
+  {0.343083,0.256834},
+  {0.652360,1.649133},
+  {-0.441827,0.270447},
+  {-0.338878,0.306703},
+  {-0.533263,-0.367020},
+  {-0.251497,-0.091588},
+  {-0.288078,-0.953882},
+  {-0.687001,1.500250},
+  {-0.145605,-0.885543},
+  {-0.295624,0.364480},
+  {-0.773724,0.838420},
+  {-0.755309,-0.637771},
+  {0.140479,0.139850},
+  {0.164407,-0.946375},
+  {0.334796,0.474215},
+  {-0.108846,0.443189},
+  {-0.315848,-0.562709},
+  {1.146425,-0.086577},
+  {1.422925,1.452282},
+  {0.528118,1.090295},
+  {0.142858,-1.517183},
+  {0.089292,-1.030106},
+  {1.868715,-0.729473},
+  {-0.847120,1.530669},
+  {-0.619504,-0.077095},
+  {0.013841,0.239227},
+  {0.358968,-0.495570},
+  {0.529144,-0.319802},
+  {-0.237481,0.008175},
+  {-0.949545,-1.524610},
+  {-0.764478,1.202526},
+  {-0.754071,0.211168},
+  {0.726948,-0.350558},
+  {-0.383736,-0.722571},
+  {-0.531464,0.251220},
+  {-0.215829,0.489119},
+  {-0.673253,0.780101},
+  {-0.425690,0.571457},
+  {-0.591886,-0.066992},
+  {-1.591411,-0.156612},
+  {0.832392,-2.183463},
+  {0.089291,0.262270},
+  {0.334040,0.864206},
+  {1.070955,-0.017792},
+  {-0.209751,-0.368139},
+  {0.320312,0.611719},
+  {0.299755,-0.675094},
+  {0.945826,0.192595},
+  {0.160973,-0.236396},
+  {-0.930557,-0.137053},
+  {0.824962,-0.452584},
+  {-0.781090,0.259436},
+  {0.499810,-0.342312},
+  {-0.976936,-0.295870},
+  {-1.864960,-1.380520},
+  {-0.343277,1.189033},
+  {0.354532,0.766793},
+  {-0.539951,0.213865},
+  {-0.755910,0.577450},
+  {-1.051209,-1.337479},
+  {-0.047104,0.329372},
+  {0.415117,-0.259529},
+  {0.118073,0.808609},
+  {1.623840,-0.219009},
+  {-0.092132,1.145445},
+  {-0.289294,0.153253},
+  {-0.118908,0.241607},
+  {-1.524828,-0.280118},
+  {0.532567,-0.648456},
+  {-0.104690,-0.952993},
+  {0.096358,0.341141},
+  {0.577925,-1.416989},
+  {-0.472131,0.005166},
+  {0.441558,0.684743},
+  {-1.075276,0.458788},
+  {-0.542887,-2.145492},
+  {0.982289,-0.712595},
+  {0.376656,-0.133513},
+  {-0.495061,-0.153725},
+  {-0.843701,-0.590876},
+  {0.189824,-1.026949},
+  {0.271507,0.450949},
+  {-1.214261,1.019265},
+  {-0.192929,0.809120},
+  {0.580104,-0.580059},
+  {-1.008693,0.258822},
+  {-0.686540,-0.150929},
+  {-0.806180,0.585680},
+  {0.382421,0.681665},
+  {0.993495,0.326671},
+  {-0.011094,0.137639},
+  {0.230903,1.353307},
+  {0.321925,-0.530779},
+  {0.445268,-0.218635},
+  {-0.248939,-0.811110},
+  {-0.438773,0.174895},
+  {0.092849,-0.786051},
+  {0.672213,0.282743},
+  {0.310022,0.016750},
+  {-0.554465,-1.296100},
+  {1.167694,0.289020},
+  {-1.008050,-1.267211},
+  {1.337627,-0.727579},
+  {1.107920,-0.800503},
+  {1.580887,-0.434263},
+  {0.534123,-0.023207},
+  {-0.672041,-1.190008},
+  {-0.623945,-1.000304},
+  {-0.339638,-0.090139},
+  {-0.247150,-0.090013},
+  {-0.248865,-0.373625},
+  {-1.008469,-0.345410},
+  {0.219290,-0.748377},
+  {-1.110240,0.109012},
+  {-1.315957,-0.132981},
+  {0.328799,0.407528},
+  {0.992340,0.695968},
+  {0.540487,0.100143},
+  {-0.101748,1.200990},
+  {1.372902,-0.484321},
+  {0.182478,0.930679},
+  {1.286810,-0.092169},
+  {0.361417,-0.430697},
+  {0.059600,0.508897},
+  {0.957065,0.231615},
+  {0.315519,0.910029},
+  {-0.259820,-1.108543},
+  {1.139876,1.306830},
+  {0.111378,0.598970},
+  {-1.158463,0.057921},
+  {0.732254,0.269129},
+  {-0.422410,0.384354},
+  {0.434930,0.258197},
+  {-0.135920,-0.584475},
+  {-0.525475,0.266487},
+  {0.479545,-1.317436},
+  {-0.588906,-1.032770},
+  {0.421416,-0.456796},
+  {-1.112158,0.197872},
+  {0.427474,-1.371221},
+  {1.169989,0.066283},
+  {-0.285752,0.682510},
+  {-1.103367,-0.081644},
+  {-0.492414,-0.508673},
+  {-0.603259,0.274685},
+  {0.453820,-0.705243},
+  {0.451449,-0.286640},
+  {-0.890995,1.493104},
+  {-0.269448,-0.111697},
+  {-0.284481,0.892255},
+  {-0.156936,1.178820},
+  {-0.026075,-0.288447},
+  {0.192773,-0.689622},
+  {0.408094,0.221306},
+  {-0.077789,0.462070},
+  {-0.763512,0.374190},
+  {1.372160,-0.387671},
+  {-0.961063,0.123053},
+  {-0.563208,-1.176171},
+  {-0.681526,0.053875},
+  {0.246027,0.916420},
+  {0.074971,0.397053},
+  {-0.509338,-0.467579},
+  {-0.028080,-0.246218},
+  {-0.778298,-1.008908},
+  {-0.688193,-0.856779},
+  {2.135919,-0.463805},
+  {-0.151521,-0.435434},
+  {0.286563,-1.399753},
+  {-0.238350,0.812805},
+  {-0.637019,0.391566},
+  {-0.930719,-0.753007},
+  {-0.130401,-0.095141},
+  {-2.022008,1.588912},
+  {0.465128,-0.736271},
+  {0.259710,0.008248},
+  {-0.670376,0.573592},
+  {-0.759845,-0.245010},
+  {1.199012,1.484925},
+  {0.117486,-1.283839},
+  {0.823713,0.601557},
+  {0.430107,1.305288},
+  {-0.857913,-0.086698},
+  {-0.240219,1.178419},
+  {0.106586,-0.727451},
+  {-0.013468,-0.553821},
+  {0.331834,-0.839487},
+  {-0.314308,-0.236823},
+  {-1.020583,-0.465144},
+  {-1.183478,-0.838031},
+  {-0.688226,-0.504797},
+  {-0.659946,0.110839},
+  {-0.317790,-0.888356},
+  {0.070495,-0.690989},
+  {-0.215137,-0.280878},
+  {-0.523957,-1.084659},
+  {-1.625006,-0.827692},
+  {-1.254357,-0.098812},
+  {-0.037334,-0.320405},
+  {-1.032500,-1.006692},
+  {1.085823,-0.464633},
+  {-0.424815,-0.295596},
+  {-0.359488,-1.184184},
+  {-0.081069,-0.021767},
+  {0.194173,-1.145768},
+  {-0.408176,-0.113861},
+  {-0.210713,0.116032},
+  {0.153323,-0.278102},
+  {-0.824116,-0.348393},
+  {1.711024,-0.546763},
+  {0.732380,0.343069},
+  {-0.031038,-0.890522},
+  {0.333504,-0.385973},
+  {0.838976,0.266577},
+  {-0.957789,-0.709820},
+  {0.084819,-0.404493},
+  {0.086928,0.312046},
+  {0.263436,0.677942},
+  {-0.878981,-0.061526},
+  {1.171282,-0.158491},
+  {1.014568,-0.534002},
+  {-0.414913,-0.218960},
+  {1.441376,-0.016469},
+  {-1.076862,0.575999},
+  {-0.508823,-0.139239},
+  {0.558421,0.010286},
+  {0.950772,-0.758483},
+  {-0.041742,0.060954},
+  {-0.951736,-0.703192},
+  {1.175201,0.090376},
+  {-0.088403,0.175440},
+  {1.137298,0.338050},
+  {0.202901,-0.780958},
+  {0.061536,1.037387},
+  {0.163756,0.146354},
+  {-1.082413,-0.656845},
+  {-0.663994,-0.554342},
+  {0.921438,0.127520},
+  {-1.683027,-0.494672},
+  {-1.207142,0.324501},
+  {-1.591428,-0.689670},
+  {0.380479,-0.276296},
+  {-1.370787,-0.457896},
+  {0.311180,0.865492},
+  {0.329667,-0.284122},
+  {0.764384,-0.263737},
+  {0.388595,0.581989},
+  {0.530794,0.089158},
+  {-0.194579,-0.160770},
+  {-0.497197,0.237652},
+  {-0.969043,0.476531},
+  {0.638742,0.543269},
+  {-0.246685,-0.490291},
+  {-0.504714,0.519112},
+  {-0.275926,0.004395},
+  {-0.679165,0.801614},
+  {-1.013769,0.245981},
+  {-1.048180,0.133878},
+  {-0.347843,-0.709411},
+  {-0.382321,0.205123},
+  {-0.289524,0.058317},
+  {0.779829,-0.108258},
+  {-0.607607,-0.504919},
+  {-0.313592,-0.887478},
+  {-1.599302,0.151143},
+  {-0.235541,0.112637},
+  {0.193417,0.135649},
+  {0.160499,-0.467862},
+  {-0.417821,0.508193},
+  {-0.371340,-0.797004},
+  {-1.218597,-0.463920},
+  {-0.329584,-0.832050},
+  {0.403735,-0.347268},
+  {0.312113,-0.544869},
+  {-0.885796,-0.033127},
+  {0.757105,0.871085},
+  {-0.135961,0.870860},
+  {-0.428802,-1.184347},
+  {0.290754,0.685975},
+  {0.025818,-0.815321},
+  {0.241907,0.375104},
+  {1.038442,0.255637},
+  {0.196660,-0.681084},
+  {-1.074595,-0.105662},
+  {-1.073237,0.535047},
+  {-1.330165,-0.216306},
+  {0.568918,-1.460499},
+  {0.046209,-1.528571},
+  {0.044727,0.488519},
+  {-0.583277,-0.315108},
+  {-1.471177,-0.727805},
+  {-0.046036,-0.582608},
+  {-0.295384,0.529362},
+  {0.361797,-0.922655},
+  {0.397070,-0.019993},
+  {-0.492521,-0.117990},
+  {0.782889,1.170999},
+  {0.662184,0.636561},
+  {-1.735288,0.395381},
+  {0.079380,-0.052730},
+  {0.709996,0.654113},
+  {-0.376010,-0.821716},
+  {0.920385,-1.393132},
+  {-0.322399,0.137951},
+  {0.319344,-0.513440},
+  {1.985403,-1.230494},
+  {-0.254706,0.778217},
+  {-0.381202,0.578765},
+  {-0.175651,0.459589},
+  {0.364902,-0.349097},
+  {-0.521217,0.377102},
+  {-0.696214,0.237524},
+  {-1.428330,0.264137},
+  {1.113969,-0.075405},
+  {-1.211818,0.228307},
+  {-0.100941,0.790198},
+  {0.189215,-0.790792},
+  {0.363891,-1.198473},
+  {-0.964005,0.251669},
+  {0.801589,-0.261038},
+  {-1.090147,0.402919},
+  {-0.227480,-0.351480},
+  {-0.406823,0.119514},
+  {-0.814855,1.243446},
+  {0.516934,-1.114966},
+  {0.026047,0.248718},
+  {-0.378437,0.509858},
+  {0.312049,0.311611},
+  {-0.891748,0.177292},
+  {0.608950,0.028471},
+  {-0.495443,-0.650332},
+  {-0.032869,0.579244},
+  {1.360294,-1.192193},
+  {-0.391750,0.494781},
+  {-0.337458,0.448717},
+  {0.363825,-0.229340},
+  {-1.236290,0.427883},
+  {0.399168,0.082217},
+  {0.280208,-0.644907},
+  {-0.759483,-1.003514},
+  {1.269082,-0.253776},
+  {0.442041,1.322204},
+  {1.329775,-0.544052},
+  {0.399145,0.137237},
+  {0.772111,0.321600},
+  {-0.588199,-0.243919},
+  {-0.658466,-0.868454},
+  {0.146449,-0.936439},
+  {0.021534,-0.658851},
+  {0.764039,0.391941},
+  {0.200860,-0.212653},
+  {0.159180,-0.042023},
+  {-0.537129,-0.147575},
+  {0.702245,-1.015617},
+  {1.790915,0.570027},
+  {0.766059,-1.875739},
+  {-0.182925,-0.787800},
+  {0.315391,0.206610},
+  {0.710280,-0.029793},
+  {0.798824,0.611930},
+  {0.082498,-0.122377},
+  {-0.441196,-0.130910},
+  {0.361502,0.019255},
+  {-0.494324,1.258054},
+  {-0.658917,0.549865},
+  {1.452774,0.133686},
+  {-0.454627,-0.589725},
+  {-0.880561,0.736115},
+  {-0.035445,0.327460},
+  {0.642400,0.698314},
+  {0.196188,0.488357},
+  {-1.092548,-0.378542},
+  {1.012368,0.219866},
+  {0.136436,1.050915},
+  {0.450533,-0.095960},
+  {-1.079073,0.205764},
+  {0.129783,-0.607319},
+  {0.304598,-0.028435},
+  {1.256490,-0.636622},
+  {0.251786,-0.305137},
+  {-0.501987,0.211074},
+  {-0.906736,-0.486202},
+  {-0.082131,0.034965},
+  {-0.584390,0.499364},
+  {0.129603,-0.644452},
+  {-0.480831,0.196367},
+  {0.349143,1.779059},
+  {0.431185,1.141092},
+  {-0.747513,0.731564},
+  {-0.786213,0.604126},
+  {1.290785,0.708430},
+  {-1.621136,0.607945},
+  {-1.515636,0.414725},
+  {-1.243614,0.535769},
+  {-0.468547,0.431251},
+  {-0.710815,-1.121571},
+  {-1.329742,-0.444443},
+  {-0.399959,0.076529},
+  {-0.261205,-0.551109},
+  {-0.712130,-1.339364},
+  {-1.672925,1.158768},
+  {0.511278,0.494824},
+  {1.221284,-0.403334},
+  {-0.689758,0.135193},
+  {-0.266714,-1.264919},
+  {-0.186901,-1.052718},
+  {0.711819,1.601651},
+  {-0.004976,-1.134699},
+  {0.264689,0.143991},
+  {-0.485013,0.240249},
+  {-0.430138,-0.180132},
+  {-0.448256,0.065344},
+  {-0.313909,0.042542},
+  {-1.788176,-1.003737},
+  {-0.430691,0.515782},
+  {-0.552024,0.033933},
+  {-0.511113,-0.396641},
+  {-0.667628,1.324609},
+  {1.536055,-0.176847},
+  {-0.371362,-0.780574},
+  {-0.604459,-0.180242},
+  {0.127890,-0.724469},
+  {-0.546043,1.055909},
+  {-1.160424,0.296830},
+  {0.851429,-0.834491},
+  {-0.653446,-0.319744},
+  {-0.281928,0.036064},
+  {0.152684,0.887427},
+  {-0.584216,-1.129730},
+  {-0.301487,-0.448074},
+  {-0.644999,-0.062434},
+  {-1.064140,-0.877770},
+  {-0.025358,0.318626},
+  {-0.169102,-1.656778},
+  {-0.410128,1.517397},
+  {0.908370,0.349006},
+  {-1.017744,-0.256003},
+  {-0.115645,0.371458},
+  {-1.286410,-1.036681},
+  {0.668494,-0.174631},
+  {0.543753,-0.269535},
+  {0.520788,-0.045167},
+  {-0.348305,0.919992},
+  {0.371761,0.757065},
+  {0.314541,-0.679578},
+  {0.365607,0.778578},
+  {-0.119374,0.153537},
+  {-0.266104,-1.198807},
+  {0.480855,0.786074},
+  {-0.032335,-0.840292},
+  {0.610415,0.164635},
+  {-0.644738,-0.147418},
+  {0.544935,0.824594},
+  {0.702994,-1.244186},
+  {0.383204,1.467042},
+  {0.264960,-0.885661},
+  {0.500914,-0.588794},
+  {0.070323,0.125276},
+  {-1.166675,-1.286120},
+  {2.429481,-0.059230},
+  {0.764725,-0.984194},
+  {1.319205,0.802877},
+  {0.667521,-1.156544},
+  {-0.490046,-1.778711},
+  {0.006985,0.759426},
+  {-0.060767,0.767774},
+  {-0.536098,-0.574244},
+  {-0.438429,-1.187924},
+  {-0.482447,-1.117342},
+  {-0.450270,-0.012118},
+  {-0.862294,0.414935},
+  {0.111836,-0.764191},
+  {0.176201,-0.840321},
+  {0.003283,0.329039},
+  {-1.081580,-0.831850},
+  {-0.757816,-0.792817},
+  {1.390379,0.527990},
+  {-0.423941,-0.375055},
+  {1.019446,0.722048},
+  {-1.226189,-0.806075},
+  {-0.767485,-0.457873},
+  {0.492217,-0.548094},
+  {0.691643,-0.508868},
+  {0.141146,-0.799097},
+  {-0.090612,0.367936},
+  {-1.588061,-0.270815},
+  {-0.235590,-0.137989},
+  {-0.055501,0.515153},
+  {0.710591,-0.228057},
+  {-0.499118,0.081473},
+  {0.605634,-0.712194},
+  {-1.465126,-0.300375},
+  {-1.525912,0.646441},
+  {-0.143056,0.092698},
+  {-1.615522,0.655455},
+  {-0.920867,0.776885},
+  {1.293398,0.375770},
+  {-0.367088,0.290023},
+  {0.060016,-1.396905},
+  {-0.564301,-0.163519},
+  {0.765264,0.454371},
+  {0.251582,-0.413469},
+  {-0.202361,-0.426122},
+  {-0.059972,0.009915},
+  {-0.818937,0.409182},
+  {0.019321,1.223693},
+  {-0.308784,-0.106641},
+  {-0.245638,-1.287715},
+  {-1.559027,0.473275},
+  {-0.523531,0.009086},
+  {-0.815917,0.794331},
+  {1.557748,0.201257},
+  {-1.003834,0.532228},
+  {-0.108970,-0.321004},
+  {0.324720,-1.294292},
+  {-0.526747,1.138428},
+  {-0.648496,0.837288},
+  {0.145426,0.003744},
+  {0.995406,-0.617984},
+  {0.658038,-0.080149},
+  {0.680441,-0.468064},
+  {1.360485,0.405642},
+  {-0.648630,0.199765},
+  {1.421996,0.120768},
+  {-1.160572,0.425829},
+  {-0.534584,0.437195},
+  {0.263973,1.083009},
+  {0.084184,-0.731033},
+  {-0.583261,-0.202720},
+  {-0.567244,-0.031166},
+  {-0.393410,0.011082},
+  {0.471308,0.529559},
+  {0.817988,0.803892},
+  {-0.436848,0.012289},
+  {0.134056,-0.016346},
+  {-0.510996,-0.160355},
+  {0.301328,0.155798},
+  {0.135075,-0.240089},
+  {-2.111101,-0.043898},
+  {0.492706,-1.075578},
+  {0.331122,-0.193177},
+  {-0.337675,-0.385101},
+  {0.600488,-0.607441},
+  {-0.482480,0.488866},
+  {0.510644,-1.348219},
+  {-0.900080,-0.246883},
+  {0.054556,-0.043343},
+  {-2.185732,-0.132914},
+  {-1.179464,-0.506427},
+  {0.060865,0.023893},
+  {0.465712,-0.293140},
+  {0.600472,-0.542588},
+  {0.339465,-0.734740},
+  {0.066566,-0.329599},
+  {-0.182971,-0.834260},
+  {-0.759862,-0.649675},
+  {0.503928,0.562654},
+  {0.180099,-0.072681},
+  {-0.298720,0.091572},
+  {0.414829,0.685094},
+  {-0.178731,1.490621},
+  {-0.764312,-0.940243},
+  {-0.609986,0.139467},
+  {0.620076,-0.882397},
+  {-0.662503,-0.243036},
+  {0.756788,0.492556},
+  {-0.192028,-0.450766},
+  {0.351446,0.122595},
+  {0.312300,-0.348844},
+  {-0.844268,0.241385},
+  {-0.245266,-0.747779},
+  {-1.043476,-2.173372},
+  {0.689560,0.287984},
+  {-0.604039,1.340161},
+  {-0.186566,-1.016223},
+  {-1.636023,-1.237069},
+  {-0.183189,0.475359},
+  {0.632049,-0.473980},
+  {-0.105737,0.324525},
+  {-0.734339,-0.411750},
+  {-0.959041,-0.918415},
+  {0.467121,-0.942991},
+  {0.819873,0.146195},
+  {0.528463,-0.981180},
+  {0.144697,0.795032},
+  {0.104364,0.648283},
+  {0.183268,0.614067},
+  {-1.164645,0.810951},
+  {0.009496,0.610751},
+  {-1.300113,-0.583004},
+  {-1.015675,0.243285},
+  {0.097064,0.342813},
+  {-0.245720,0.670790},
+  {0.205629,0.159022},
+  {-0.262508,-0.028034},
+  {-0.035008,0.785832},
+  {0.565660,0.072977},
+  {0.857016,-0.270113},
+  {0.136789,-0.121418},
+  {-0.656906,0.866977},
+  {0.154962,1.086797},
+  {1.053022,-1.172792},
+  {0.226542,0.180113},
+  {0.245718,-0.555295},
+  {-0.232891,0.136740},
+  {-0.930222,0.234981},
+  {-0.486962,-0.336185},
+  {0.350798,0.599626},
+  {0.574125,0.169891},
+  {0.614118,-0.392546},
+  {-1.180994,0.390905},
+  {0.683221,0.485573},
+  {-0.841497,0.916893},
+  {0.493882,0.242793},
+  {1.254721,-0.271983},
+  {-0.534063,0.438921},
+  {0.575408,-0.133856},
+  {0.312608,-0.033845},
+  {0.580808,-0.613817},
+  {-0.784972,-0.028488},
+  {0.021831,-0.097100},
+  {1.458365,-0.869399},
+  {-1.300065,0.760049},
+  {0.248812,-0.160696},
+  {0.577725,0.443818},
+  {-0.187965,1.600714},
+  {0.318288,-0.795075},
+  {-0.721696,-0.233585},
+  {0.273242,0.614688},
+  {0.681000,-0.554330},
+  {-1.334662,-0.151226},
+  {0.090395,0.928536},
+  {0.810563,0.579363},
+  {-1.128333,0.111594},
+  {1.434974,0.769472},
+  {-1.029423,0.004195},
+  {-0.400590,0.108051},
+  {-0.108363,-0.294703},
+  {2.176060,-0.435633},
+  {0.755020,0.883148},
+  {-0.455663,-0.243404},
+  {0.367326,-1.926805},
+  {-0.455835,-0.070141},
+  {1.081696,0.103537},
+  {0.413618,-0.241936},
+  {-0.155372,-0.490682},
+  {-0.621036,0.039829},
+  {0.890303,-0.313264},
+  {-0.023574,-0.297114},
+  {0.149197,0.434404},
+  {-0.685611,-0.688437},
+  {0.206938,0.778492},
+  {-0.031417,0.174300},
+  {-0.246155,-0.983701},
+  {0.342626,1.369090},
+  {-0.431405,0.516606},
+  {-0.058886,-0.776391},
+  {1.360163,0.224372},
+  {1.125009,0.009836},
+  {0.803894,0.584153},
+  {-1.066450,-0.134171},
+  {0.881308,-0.764883},
+  {0.171104,0.260482},
+  {0.114729,-0.114913},
+  {0.883607,1.086200},
+  {0.699362,-0.659063},
+  {-0.164816,-0.175345},
+  {0.387135,-0.085228},
+  {-0.572309,0.619865},
+  {-0.012015,-0.860950},
+  {-0.342715,0.692370},
+  {-0.024062,-0.039234},
+  {0.292654,0.782865},
+  {0.060171,0.442951},
+  {0.160037,-0.381519},
+  {0.408238,-0.320343},
+  {-0.342973,-0.880725},
+  {0.737359,0.306119},
+  {-0.536555,-0.356491},
+  {0.838071,-0.060380},
+  {0.019197,-0.215087},
+  {0.281771,0.139607},
+  {-0.133836,-0.948025},
+  {0.064779,-0.167417},
+  {-0.325938,0.106840},
+  {0.447499,0.335119},
+  {0.025073,0.284159},
+  {-0.052734,0.106778},
+  {-0.701789,-1.485622},
+  {0.518739,-0.597975},
+  {-1.716639,0.510981},
+  {-0.148489,0.188995},
+  {0.199804,0.565255},
+  {0.503694,-0.249207},
+  {0.351417,0.318152},
+  {-0.004846,0.498401},
+  {-0.527585,0.429634},
+  {2.230256,0.657682},
+  {1.005492,0.534070},
+  {0.335269,-0.396652},
+  {-0.245966,0.173556},
+  {1.145575,0.588938},
+  {0.250537,0.473746},
+  {0.273775,-0.223929},
+  {0.015710,-0.244761},
+  {-0.725572,0.598468},
+  {0.272714,0.218757},
+  {-1.388789,1.100565},
+  {0.552103,-0.509940},
+  {-1.061048,-0.439544},
+  {0.192437,0.828632},
+  {-0.847671,1.023359},
+  {0.366431,-0.588009},
+  {0.237764,0.442998},
+  {-0.676158,-0.309010},
+  {-0.610452,-0.659422},
+  {-0.259924,0.412575},
+  {0.388464,0.697350},
+  {0.043340,0.184411},
+  {-0.572546,-0.447644},
+  {-0.330020,0.540548},
+  {-0.476494,0.090675},
+  {0.428011,0.507960},
+  {-0.296043,-0.255790},
+  {1.215630,-0.318831},
+  {-1.154660,-0.477923},
+  {-0.262266,1.238092},
+  {-0.608603,0.453266},
+  {-0.032630,-0.939531},
+  {-1.660462,-0.153632},
+  {1.705682,-0.866847},
+  {0.429987,-0.912308},
+  {0.416998,0.929955},
+  {1.043259,0.307132},
+  {-0.982368,0.014721},
+  {0.123933,1.132765},
+  {-0.203176,-0.346598},
+  {0.070922,-0.385330},
+  {0.144019,0.165251},
+  {0.096086,-0.226780},
+  {0.793344,0.135213},
+  {-0.393406,-0.119594},
+  {1.126684,-1.053134},
+  {-0.132630,0.517421},
+  {0.300448,-1.340154},
+  {-0.834868,0.378596},
+  {-0.132590,-0.127355},
+  {-0.544568,1.427218},
+  {-0.443372,0.521400},
+  {-1.030830,1.124109},
+  {-1.434174,0.036345},
+  {-0.448801,-0.849006},
+  {1.295485,1.176937},
+  {0.612869,-0.763780},
+  {-0.369440,-1.146724},
+  {-0.183304,-0.234196},
+  {0.228224,-0.830902},
+  {1.022613,0.744120},
+  {0.025729,0.401274},
+  {-0.291958,0.275394},
+  {-0.232227,-0.344890},
+  {-0.372023,-0.748359},
+  {0.399097,-0.026262},
+  {-0.980706,0.557794},
+  {-1.242178,-0.160578},
+  {0.807544,0.089148},
+  {-0.313827,-0.935789},
+  {0.877743,0.053390},
+  {-0.471764,-1.392615},
+  {0.816500,1.445653},
+  {-0.016996,-0.915960},
+  {-0.919171,-0.825732},
+  {0.536946,0.833119},
+  {-1.361314,-0.838853},
+  {-0.180351,-0.307114},
+  {0.720178,1.060531},
+  {0.168912,1.130233},
+  {1.082306,0.407076},
+  {0.193384,0.074239},
+  {0.505658,-0.337304},
+  {-0.059033,-0.040496},
+  {-0.238771,-0.195282},
+  {-0.160034,1.174256},
+  {1.572109,-0.122569},
+  {0.170932,-0.122646},
+  {0.407778,0.454863},
+  {-0.016869,-0.027842},
+  {0.533907,-0.455801},
+  {1.171133,1.451143},
+  {-0.221926,0.445829},
+  {-0.343024,-1.134887},
+  {-0.084294,-0.803381},
+  {1.762508,0.510097},
+  {0.422538,-1.828873},
+  {-0.272140,-0.351999},
+  {-0.432142,1.296591},
+  {-0.804792,1.207034},
+  {-0.903372,0.071198},
+  {0.221699,-0.548004},
+  {0.296788,-0.487708},
+  {-0.892082,0.116939},
+  {0.118529,-0.058040},
+  {0.889249,0.038813},
+  {-1.435339,0.345064},
+  {0.196684,0.414290},
+  {-1.174361,-0.538056},
+  {-0.655841,0.448240},
+  {0.472673,-0.022418},
+  {0.940362,0.311382},
+  {-0.835209,-0.613456},
+  {1.186347,0.367963},
+  {-0.745946,-1.281948},
+  {0.614204,-0.405224},
+  {0.981560,0.711532},
+  {-0.869991,0.308124},
+  {-0.141029,-0.054972},
+  {-0.145974,0.432189},
+  {0.451887,-0.259041},
+  {-0.784348,-0.033713},
+  {0.793608,0.102305},
+  {-0.744519,0.342470},
+  {0.486741,0.105299},
+  {0.347823,-0.107864},
+  {-0.331637,0.717920},
+  {-0.508501,1.192128},
+  {1.490978,0.162327},
+  {0.736492,-0.127445},
+  {-0.085074,-0.474562},
+  {0.599451,-0.167800},
+  {0.674386,0.323677},
+  {-0.412837,-0.758638},
+  {0.609945,-0.786243},
+  {0.606302,0.662258},
+  {0.070750,0.124316},
+  {0.362489,0.853723},
+  {-0.421579,-0.217535},
+  {-0.769619,2.120710},
+  {-0.686205,-1.002458},
+  {0.847970,0.499804},
+  {-0.240487,-1.200173},
+  {-0.787843,-0.870082},
+  {0.134999,-0.037935},
+  {1.418077,1.020690},
+  {0.255585,-0.903872},
+  {0.517503,1.018629},
+  {0.222738,-0.956358},
+  {-1.235963,0.716474},
+  {0.896358,1.292193},
+  {0.622993,0.939205},
+  {0.032065,0.164409},
+  {-0.779169,0.659748},
+  {-0.738374,0.133285},
+  {-0.620870,-0.855214},
+  {0.342903,0.804248},
+  {0.339164,-0.133036},
+  {-1.661026,-0.210091},
+  {0.245305,-0.675406},
+  {-0.984197,0.390112},
+  {-0.061474,-1.162560},
+  {-0.723975,0.336075},
+  {0.796753,-0.371630},
+  {-0.548010,-0.761000},
+  {-0.603116,-0.658810},
+  {0.990442,0.351586},
+  {-0.086890,-0.036006},
+  {0.092425,-0.586906},
+  {-0.925900,0.593131},
+  {-0.763373,-0.389790},
+  {-0.938653,-0.603703},
+  {1.319069,0.867869},
+  {0.485223,0.597602},
+  {0.488264,-0.833841},
+  {0.550617,-0.599518},
+  {-0.329951,0.815395},
+  {0.408096,-0.163820},
+  {0.427087,-0.036759},
+  {0.177247,0.112508},
+  {0.674777,-0.049031},
+  {-0.068546,1.438730},
+  {0.238263,-1.518472},
+  {0.883496,0.410851},
+  {-0.306168,-0.121973},
+  {0.119223,0.124116},
+  {-0.458455,0.205762},
+  {0.819118,-0.420270},
+  {-0.502089,0.258248},
+  {-0.168138,0.489351},
+  {0.807982,-0.264625},
+  {0.084262,-0.505577},
+  {-0.559426,0.054462},
+  {0.257622,-0.205514},
+  {0.063041,-0.447553},
+  {0.373281,0.067113},
+  {-0.407206,-0.939355},
+  {0.143221,-0.451897},
+  {0.706256,0.478611},
+  {0.537206,0.751956},
+  {0.186734,-0.620411},
+  {0.745475,-1.471416},
+  {0.698281,0.256863},
+  {0.042234,-0.046608},
+  {0.099521,-0.430961},
+  {0.236487,0.680732},
+  {0.928581,0.289094},
+  {-0.110851,0.188157},
+  {-0.222611,-0.812705},
+  {-0.633681,0.426959},
+  {1.240335,-1.514135},
+  {0.889274,-0.903866},
+  {0.435835,0.552663},
+  {0.713055,0.641659},
+  {-0.042562,-0.629798},
+  {-0.218147,-0.486607},
+  {0.534103,-0.801708},
+  {0.241010,0.206161},
+  {0.572140,-0.082834},
+  {-1.509288,-0.142938},
+  {0.613317,-1.136810},
+  {-0.196998,-0.273118},
+  {-0.692536,-1.013502},
+  {-0.524362,-0.353001},
+  {-1.413574,-0.317148},
+  {-0.184674,-1.254237},
+  {0.212553,-0.393970},
+  {0.115187,-0.497395},
+  {-1.156764,0.217090},
+  {-0.424303,-0.518804},
+  {0.414805,0.157648},
+  {0.213679,-0.158910},
+  {-0.174193,0.696145},
+  {0.085286,0.143396},
+  {-1.850393,0.435779},
+  {-0.015959,-0.039908},
+  {-1.196652,-0.512413},
+  {0.461147,1.083615},
+  {1.188726,-1.253006},
+  {0.191977,0.248884},
+  {-0.633004,0.193534},
+  {0.030327,0.447737},
+  {-0.264705,0.787837},
+  {0.010620,0.245484},
+  {-0.824799,-0.704581},
+  {-0.850004,0.204610},
+  {0.381113,-0.610533},
+  {0.471917,1.571607},
+  {1.071030,-0.224993},
+  {-0.384820,-0.304042},
+  {0.283926,-0.337624},
+  {-0.030392,-0.446234},
+  {0.380697,1.115396},
+  {-0.572464,0.561788},
+  {0.625570,0.831812},
+  {0.385308,0.863936},
+  {-0.754364,0.169919},
+  {0.019587,-0.256785},
+  {0.572060,0.074947},
+  {-0.701087,-0.235522},
+  {-0.048703,0.055669},
+  {1.222353,0.777241},
+  {0.332950,0.082754},
+  {-0.367895,-0.645924},
+  {0.770417,0.554187},
+  {-0.458786,-1.031422},
+  {0.314500,-0.322402},
+  {-0.683719,-0.429777},
+  {-1.553851,-0.570942},
+  {-0.067857,-0.160216},
+  {2.145920,0.854215},
+  {0.213836,-0.315033},
+  {-0.513806,-0.416544},
+  {-1.457721,-1.141119},
+  {0.886807,-0.392147},
+  {-0.193698,-0.206875},
+  {0.548596,-0.465798},
+  {0.215522,0.180953},
+  {-0.391465,-0.142202},
+  {0.902257,0.158063},
+  {0.408777,-0.224758},
+  {0.446692,0.091443},
+  {-0.094655,0.081225},
+  {0.499235,0.958718},
+  {0.761380,-0.531675},
+  {0.276579,1.203927},
+  {0.276615,0.189762},
+  {-0.100258,-0.732587},
+  {-0.027769,1.596871},
+  {0.462540,0.379880},
+  {-0.341576,1.767737},
+  {0.394437,-0.167993},
+  {-0.105307,-0.509844},
+  {0.334850,-2.520104},
+  {0.845128,-0.104068},
+  {-0.740984,-0.026126},
+  {-0.974643,-0.280273},
+  {-0.134239,-0.078789},
+  {-0.299124,-0.863529},
+  {0.106515,0.170939},
+  {-0.927394,0.870161},
+  {-0.491114,-1.917638},
+  {-0.529767,-0.057114},
+  {0.786100,-0.565618},
+  {0.176072,-0.842280},
+  {0.326239,-0.605491},
+  {0.116318,1.170250},
+  {0.644626,0.571773},
+  {0.232028,-1.300912},
+  {0.588283,0.271257},
+  {-0.906647,-1.277791},
+  {0.521843,-0.527216},
+  {1.442306,0.379763},
+  {0.236952,1.052319},
+  {-0.295295,-0.568414},
+  {0.242369,-0.208334},
+  {-0.513807,-0.995215},
+  {0.709065,0.862066},
+  {-0.881110,-0.392734},
+  {-0.341385,-0.818876},
+  {-0.562235,-0.774610},
+  {-0.383367,-0.394595},
+  {0.193563,0.074610},
+  {1.080435,0.606053},
+  {0.541249,1.153279},
+  {-0.507145,-0.367372},
+  {-0.179289,0.029067},
+  {0.098487,-0.117080},
+  {-0.648908,1.440715},
+  {0.227369,0.898461},
+  {0.080062,-0.499544},
+  {0.644433,-0.375275},
+  {1.389011,0.012401},
+  {-0.264708,-0.741045},
+  {0.537436,-0.075225},
+  {1.106610,-0.549125},
+  {1.258275,-0.013265},
+  {0.728976,0.175113},
+  {-1.886547,-0.858978},
+  {-0.781953,-0.791226},
+  {0.122237,-0.660890},
+  {-1.264703,-0.283197},
+  {0.103200,-0.239052},
+  {-0.243478,0.149221},
+  {-0.144997,-0.203846},
+  {-1.067080,-1.526123},
+  {-0.976317,0.443019},
+  {-1.106013,0.024286},
+  {-0.311371,0.312037},
+  {0.122867,-0.212564},
+  {-1.891145,0.276717},
+  {-0.898165,-0.258266},
+  {0.160126,-1.155622},
+  {0.322655,-0.124973},
+  {0.709720,-0.446937},
+  {0.646654,-0.041224},
+  {-0.212961,0.280510},
+  {0.377353,0.020557},
+  {-0.559193,0.356275},
+  {-0.304649,0.801474},
+  {0.039679,-1.071028},
+  {0.201060,0.268840},
+  {0.060299,0.506095},
+  {0.468796,0.933767},
+  {-0.161046,0.352827},
+  {0.444057,-0.026569},
+  {-0.686397,0.188762},
+  {-0.335728,0.854376},
+  {1.571248,-0.778097},
+  {-0.297224,-1.112280},
+  {-0.298702,0.212694},
+  {0.753050,-0.774688},
+  {0.772973,0.801142},
+  {1.006190,0.195367},
+  {0.333846,-0.480112},
+  {-0.391853,1.243410},
+  {-0.695698,-0.290131},
+  {-0.739155,-0.888427},
+  {-0.332246,-1.694342},
+  {-0.872134,-0.491913},
+  {-1.196152,-0.951224},
+  {0.677412,0.228122},
+  {0.078804,0.855733},
+  {0.835586,0.425326},
+  {-0.229803,-0.248342},
+  {-0.718329,-0.707283},
+  {-0.509813,-1.200162},
+  {0.225505,-1.007218},
+  {-0.328166,-0.713028},
+  {0.464166,0.043179},
+  {0.309117,1.116584},
+  {0.123684,0.813080},
+  {-0.557566,0.056690},
+  {0.771158,0.111089},
+  {-0.102040,0.365176},
+  {0.283581,-0.304576},
+  {0.965047,0.603779},
+  {-0.888726,0.478438},
+  {0.477779,1.650476},
+  {-1.743258,-0.545295},
+  {1.377725,-0.340541},
+  {-0.086465,0.288027},
+  {0.172055,-1.416793},
+  {-0.156652,-1.552419},
+  {1.449604,-0.803632},
+  {0.172637,0.621346},
+  {0.793824,1.127283},
+  {-0.470779,0.819345},
+  {0.854335,-0.217494},
+  {1.238408,-0.227297},
+  {-0.446910,-0.251604},
+  {-0.124721,0.631903},
+  {1.355742,-0.253180},
+  {0.521698,-0.380554},
+  {0.610522,-0.644701},
+  {-0.081964,0.075793},
+  {-0.023329,1.079615},
+  {0.035329,0.305532},
+  {0.833652,0.329381},
+  {1.248972,-0.520503},
+  {1.090623,-0.312108},
+  {-0.298609,0.072040},
+  {-1.133040,-1.182362},
+  {0.439116,0.599685},
+  {-0.255228,-0.318038},
+  {-0.027322,0.405769},
+  {-0.892907,1.076022},
+  {-0.262922,0.302096},
+  {-0.920155,-0.097186},
+  {-0.540438,1.415810},
+  {0.272013,-1.071177},
+  {-1.292397,-0.727006},
+  {-0.061905,-0.763598},
+  {-0.941549,0.110682},
+  {-0.295776,0.793431},
+  {-0.169404,2.201666},
+  {-0.222637,-0.543007},
+  {-0.231419,1.018982},
+  {0.431675,-0.674150},
+  {0.647789,1.313624},
+  {-0.264086,-1.589729},
+  {-0.501708,1.108352},
+  {-0.208768,-0.310074},
+  {-0.597616,0.571167},
+  {0.001134,-0.028259},
+  {1.776513,0.322038},
+  {0.000932,0.887187},
+  {-0.308110,-0.292049},
+  {-0.532540,-0.401817},
+  {0.489140,-0.274389},
+  {2.617062,0.127502},
+  {0.147567,1.240201},
+  {0.663675,0.555925},
+  {-0.074294,-0.891471},
+  {-0.052708,1.536838},
+  {0.022298,-0.206741},
+  {0.479854,0.468749},
+  {-0.554820,1.208232},
+  {0.082508,0.244005},
+  {0.308910,0.266430},
+  {-0.474058,0.730188},
+  {-0.234200,-0.862644},
+  {0.952488,0.374155},
+  {-1.407313,0.324058},
+  {0.255768,0.333183},
+  {-1.409944,0.885110},
+  {-0.133868,0.923739},
+  {0.365945,-0.286467},
+  {-0.173753,-0.130918},
+  {-0.127021,-0.366972},
+  {0.038457,0.743113},
+  {-0.478880,-0.722286},
+  {-0.422107,-0.391745},
+  {1.431973,1.075899},
+  {0.065443,0.277849},
+  {-1.101839,-0.748236},
+  {0.291738,0.774096},
+  {-0.408096,0.206278},
+  {-1.180762,0.039864},
+  {0.986053,-0.063561},
+  {0.898749,0.024366},
+  {0.206499,0.151574},
+  {0.542112,0.681856},
+  {0.773880,0.684502},
+  {-0.241328,-0.031931},
+  {-0.382695,-0.326442},
+  {-0.849252,-0.163569},
+  {-0.224038,0.104381},
+  {-0.271735,0.180993},
+  {-0.297649,1.141589},
+  {-0.707010,-0.959005},
+  {0.401963,-0.582866},
+  {-0.715231,-0.495908},
+  {0.530290,-1.238800},
+  {-0.754427,0.394484},
+  {0.419279,-1.220995},
+  {0.230175,0.787427},
+  {0.371875,-0.606294},
+  {0.450371,-0.675309},
+  {0.171612,-0.392663},
+  {0.044028,0.193995},
+  {0.390951,0.897858},
+  {0.462471,-1.607671},
+  {1.295156,0.465999},
+  {0.793000,-0.411269},
+  {0.521132,-0.780113},
+  {0.533996,-0.337154},
+  {0.465286,0.327814},
+  {0.575773,0.419234},
+  {-0.030753,-0.501412},
+  {-0.575181,-1.392250},
+  {0.464516,0.592014},
+  {-1.051143,0.268391},
+  {0.131935,0.110597},
+  {0.074115,0.640275},
+  {1.141666,-0.715042},
+  {0.981527,0.398484},
+  {-0.318100,-0.014155},
+  {0.180788,-2.372129},
+  {-0.228512,-1.445935},
+  {0.604143,0.511910},
+  {0.061448,0.220588},
+  {1.285856,0.755178},
+  {-0.007362,0.382650},
+  {-0.121693,-1.355384},
+  {0.384877,1.724619},
+  {0.501171,0.169846},
+  {0.072657,1.420837},
+  {-0.653957,-1.801468},
+  {1.157954,-0.653464},
+  {-0.086409,0.466198},
+  {-0.284619,-1.509457},
+  {0.250620,0.007603},
+  {-0.493596,-0.521283},
+  {0.052350,0.242415},
+  {-0.662703,0.329744},
+  {0.270573,0.839284},
+  {1.071362,-1.329600},
+  {1.398703,-0.282566},
+  {-0.731533,1.666659},
+  {1.288748,0.120392},
+  {-0.275091,-0.249067},
+  {0.385583,0.034420},
+  {-0.019935,-0.619918},
+  {0.126886,0.241649},
+  {-0.634954,-0.683893},
+  {-0.689498,-0.555893},
+  {0.355284,-0.081731},
+  {-1.040687,-0.136149},
+  {-0.539910,-1.308056},
+  {-0.577548,0.394734},
+  {-1.345688,0.532236},
+  {-0.139622,0.230896},
+  {0.266085,-0.109778},
+  {0.720346,1.119455},
+  {0.079954,0.124289},
+  {0.511923,-1.657132},
+  {-2.248034,0.251991},
+  {1.364589,0.688028},
+  {0.888909,-0.151714},
+  {-0.569128,0.357256},
+  {-0.771377,1.271462},
+  {-0.737187,-0.032195},
+  {-0.719654,0.068332},
+  {-0.741507,-0.004577},
+  {-0.437575,0.452222},
+  {0.046679,0.449842},
+  {-0.220268,-0.231133},
+  {0.487091,-0.782256},
+  {-0.588303,-0.523988},
+  {0.078759,0.662810},
+  {1.248130,-0.793583},
+  {0.508679,0.242683},
+  {0.870960,-0.005896},
+  {0.322792,-0.772706},
+  {-0.837291,-0.424434},
+  {-0.273942,-0.068730},
+  {-0.996061,0.634835},
+  {-0.325385,0.366167},
+  {-1.601558,-0.215569},
+  {0.865809,-0.026148},
+  {1.361558,-0.115469},
+  {-0.588242,-0.102336},
+  {-0.387966,0.323272},
+  {0.289584,-0.504165},
+  {-0.754503,-1.114553},
+  {-0.353904,-0.014974},
+  {-0.948798,0.383592},
+  {-0.060121,-1.007894},
+  {-0.209254,0.035108},
+  {-0.191868,-0.327112},
+  {-0.872958,1.449912},
+  {1.215036,0.727058},
+  {-0.851767,0.775217},
+  {0.370956,-0.452360},
+  {-0.325553,-0.956322},
+  {-0.341459,1.281000},
+  {-0.094430,-0.289030},
+  {0.272220,0.131684},
+  {-0.490177,-0.806252},
+  {-0.099482,0.801627},
+  {0.660006,-0.111388},
+  {-0.412095,0.392647},
+  {-0.019833,0.332668},
+  {-0.076947,1.499139},
+  {-0.243294,1.683990},
+  {-0.671076,-0.433132},
+  {0.167768,-0.058623},
+  {1.324849,0.390514},
+  {-0.069259,-1.476604},
+  {-0.201312,-0.076595},
+  {0.817829,-0.669267},
+  {0.271931,0.149985},
+  {-0.209551,-0.803738},
+  {0.823791,-0.880931},
+  {0.945366,-0.396813},
+  {-0.636227,0.164765},
+  {-0.560128,1.371587},
+  {-0.210411,-0.871558},
+  {0.049073,0.899454},
+  {-0.426285,0.802485},
+  {0.481298,0.695859},
+  {-1.158734,0.585655},
+  {0.344093,-0.512270},
+  {0.837968,0.186502},
+  {0.446366,-0.555741},
+  {0.389203,-0.792521},
+  {-1.165375,-1.629469},
+  {-1.254712,0.471550},
+  {0.689930,1.197958},
+  {-1.004811,0.105754},
+  {0.841131,0.147341},
+  {0.154420,-0.297913},
+  {-0.796042,-0.454021},
+  {-1.231614,-1.187511},
+  {-1.109815,-0.141912},
+  {-0.566546,-0.288210},
+  {-0.661025,0.127627},
+  {-1.017198,-1.001861},
+  {1.186309,0.060379},
+  {-0.220627,1.019218},
+  {-1.293678,-0.087054},
+  {-0.025609,0.418478},
+  {0.771157,-0.681107},
+  {0.539560,0.233353},
+  {-0.378370,0.264538},
+  {1.893478,-0.101454},
+  {0.248258,-0.000550},
+  {-0.031156,-0.785691},
+  {1.781812,-1.292306},
+  {1.084657,0.507894},
+  {-0.699208,0.885340},
+  {1.285794,-0.619386},
+  {0.955586,-0.121447},
+  {-0.914452,-1.178647},
+  {-0.242399,-0.427685},
+  {-0.000717,0.064139},
+  {0.574391,-0.693162},
+  {0.485580,-0.614569},
+  {-0.408661,-0.616323},
+  {-0.464543,0.219753},
+  {0.765718,0.874867},
+  {1.166937,-0.037645},
+  {-0.387840,0.839810},
+  {-0.522687,1.260869},
+  {0.079230,0.752776},
+  {-1.317984,1.303184},
+  {1.280048,0.412472},
+  {1.609177,-1.354228},
+  {1.037420,0.014540},
+  {0.221589,0.058322},
+  {-0.629552,0.832290},
+  {-1.314747,0.685569},
+  {0.279436,-0.743734},
+  {-1.036796,0.905691},
+  {0.495922,0.253242},
+  {-0.916021,0.154075},
+  {0.864485,0.140135},
+  {-0.350216,-0.107206},
+  {-0.536267,0.213086},
+  {1.398571,-0.305908},
+  {-1.517443,-0.348266},
+  {0.316594,0.475011},
+  {-0.682424,0.439457},
+  {-0.443305,1.044724},
+  {-0.515239,-0.514528},
+  {-1.187287,0.148757},
+  {0.286934,-0.102590},
+  {0.258621,-0.932940},
+  {1.392701,-0.258996},
+  {-0.247044,0.662986},
+  {-0.039077,-0.511042},
+  {0.844728,-0.217617},
+  {0.655759,-0.440128},
+  {-0.413628,-0.925661},
+  {-0.488104,-1.044892},
+  {-0.543050,0.155919},
+  {0.817307,0.193785},
+  {0.341966,0.009039},
+  {0.574199,0.718193},
+  {-0.179957,-0.492905},
+  {0.487152,0.524160},
+  {0.329158,-0.281555},
+  {-0.816659,-1.487422},
+  {0.535622,0.409912},
+  {0.252481,-0.624546},
+  {-0.108432,-0.823732},
+  {0.302554,-1.011194},
+  {-0.425776,-1.472152},
+  {-0.398910,-0.198658},
+  {-0.068758,-1.227234},
+  {0.126371,-0.758421},
+  {0.343071,-0.216133},
+  {0.001535,1.505001},
+  {0.112153,0.738745},
+  {-1.513525,-1.478555},
+  {0.939067,1.193568},
+  {0.382158,-0.305531},
+  {-0.777582,-1.155642},
+  {-0.672354,-0.312022},
+  {-0.374348,-1.352798},
+  {-0.418581,0.634617},
+  {0.217850,-0.116165},
+  {0.432181,0.426225},
+  {-0.889372,0.893485},
+  {0.855687,-0.582910},
+  {-0.438450,-0.263930},
+  {-0.466874,-0.869459},
+  {0.040757,-0.535451},
+  {-0.140064,0.789127},
+  {-0.027951,0.105940},
+  {-0.437942,-0.211395},
+  {-0.040889,-0.017258},
+  {0.338753,0.833301},
+  {0.111661,-0.175934},
+  {0.984011,0.077959},
+  {-0.244420,0.211986},
+  {-1.269522,0.063911},
+  {0.409668,-0.303990},
+  {0.462926,1.021879},
+  {0.011614,-0.284044},
+  {1.020808,0.476647},
+  {0.196290,0.617474},
+  {-1.098523,0.371501},
+  {0.161323,-0.313071},
+  {-0.002902,0.397897},
+  {-0.356512,0.045680},
+  {0.279592,-0.533235},
+  {-0.475045,0.692805},
+  {-0.089288,-0.703191},
+  {-0.405232,-0.892280},
+  {1.186783,0.798136},
+  {-1.149640,-0.304031},
+  {-0.243771,-0.696568},
+  {-1.109856,0.231693},
+  {0.587465,-0.480350},
+  {0.184300,0.622183},
+  {0.153163,0.512540},
+  {1.675888,0.477305},
+  {0.698217,0.670234},
+  {0.860644,1.171471},
+  {-0.330617,0.580491},
+  {-0.058262,-0.788790},
+  {-0.358326,-0.426058},
+  {0.905134,-0.409635},
+  {-0.008586,0.990271},
+  {0.929488,-0.596337},
+  {-1.358305,0.391919},
+  {0.902404,0.342821},
+  {-0.063962,0.618381},
+  {-0.053813,0.301008},
+  {0.297584,-0.666505},
+  {0.556545,0.163475},
+  {-0.105724,0.005318},
+  {0.756775,0.828292},
+  {-0.274629,-0.880320},
+  {-0.476757,-1.149811},
+  {1.127103,-0.294822},
+  {-1.437952,0.298334},
+  {0.907496,0.739951},
+  {0.482075,0.004954},
+  {0.157887,-0.816916},
+  {-1.104784,0.063870},
+  {-0.724938,-0.327697},
+  {-0.487298,0.975783},
+  {-0.065203,0.869972},
+  {-0.211487,-0.462389},
+  {1.094010,0.177366},
+  {0.291395,-1.629667},
+  {0.319282,0.785872},
+  {1.229602,0.954910},
+  {-0.342436,-0.978418},
+  {0.352808,-0.930560},
+  {0.347757,-0.981736},
+  {0.298532,-0.077863},
+  {-0.714535,-0.393789},
+  {-0.333766,-0.139255},
+  {-0.418941,0.359123},
+  {-0.645184,0.861929},
+  {-0.722475,0.301444},
+  {-0.583318,1.352369},
+  {-0.712937,0.243635},
+  {0.440878,-0.827122},
+  {0.327224,-0.062067},
+  {0.186287,1.258463},
+  {-0.729241,0.868902},
+  {0.541857,-0.200516},
+  {1.156841,-0.049354},
+  {1.070085,-0.139319},
+  {0.275765,0.779653},
+  {0.355802,-0.444176},
+  {-0.215164,1.591130},
+  {0.410285,-0.761158},
+  {-0.921834,-0.002490},
+  {-0.552404,-0.660768},
+  {0.405438,0.139289},
+  {-0.275428,-0.582028},
+  {0.727740,-0.766058},
+  {-0.306953,-0.280078},
+  {0.816312,-0.261072},
+  {-0.199058,0.147132},
+  {-0.360431,1.125081},
+  {1.191538,-0.047433},
+  {0.305817,-0.633319},
+  {-0.494003,0.488029},
+  {0.212671,0.098168},
+  {0.210869,-0.461609},
+  {-0.134279,0.437562},
+  {0.343639,-0.292114},
+  {-0.041375,-0.808615},
+  {-1.049076,0.685913},
+  {-0.665760,-1.010501},
+  {-0.316509,-0.003953},
+  {0.009980,0.599501},
+  {0.638152,-0.300940},
+  {-1.337720,-1.392983},
+  {-0.275772,0.226258},
+  {-0.550300,0.251820},
+  {-0.584194,0.093470},
+  {0.610120,1.230993},
+  {-0.976958,0.361009},
+  {-0.875544,1.373339},
+  {0.287035,-0.431066},
+  {-0.467716,0.616202},
+  {-0.521935,-1.111703},
+  {-0.098289,-0.170971},
+  {-0.189521,-0.430798},
+  {0.994687,-0.127269},
+  {0.197679,0.364513},
+  {-0.553761,-1.362114},
+  {-1.599143,0.283164},
+  {0.343200,0.241993},
+  {0.950041,0.135606},
+  {-0.496251,0.947582},
+  {0.112208,-0.474788},
+  {-0.043567,-0.201243},
+  {-0.152120,0.819050},
+  {-0.698148,-0.987049},
+  {0.472844,0.167428},
+  {0.805574,0.137483},
+  {0.993595,0.361435},
+  {-0.755927,0.329879},
+  {-0.477493,0.425378},
+  {0.513390,0.862967},
+  {-0.370640,-1.203726},
+  {0.303774,0.888996},
+  {-0.531538,-0.061148},
+  {0.292513,1.123151},
+  {-1.375406,0.912479},
+  {0.874095,0.312105},
+  {0.285703,1.070449},
+  {-0.327598,0.204123},
+  {0.514364,-0.591838},
+  {0.187292,0.151885},
+  {-0.305341,0.797145},
+  {0.512371,-0.430627},
+  {-0.263249,1.117044},
+  {1.457063,0.655659},
+  {0.400834,-0.687060},
+  {-0.534341,0.199095},
+  {-0.670479,-0.049629},
+  {0.170424,0.355076},
+  {-0.089197,-0.199899},
+  {-0.516640,-0.098609},
+  {-1.415132,-0.986232},
+  {-0.543245,-0.612453},
+  {1.700407,-0.111663},
+  {-0.333996,0.941663},
+  {-0.558882,0.628745},
+  {-0.189070,-0.269156},
+  {-0.092103,0.289742},
+  {1.721874,-0.613049},
+  {0.400596,-1.689893},
+  {0.029330,0.780505},
+  {0.702801,-1.886583},
+  {0.527904,1.344383},
+  {-1.532567,-0.282722},
+  {-0.187656,1.032522},
+  {-0.563567,0.352977},
+  {1.552724,1.036609},
+  {-0.362367,0.884433},
+  {0.907224,-0.245049},
+  {0.968850,0.022296},
+  {0.991932,-0.528220},
+  {-0.574841,-0.667893},
+  {-1.285195,-0.410222},
+  {0.961984,0.592525},
+  {0.851798,-0.802477},
+  {-1.049946,-0.207182},
+  {0.797470,-0.161487},
+  {-0.749814,0.644751},
+  {1.147914,0.191578},
+  {1.094925,-0.009702},
+  {-0.016473,-0.192798},
+  {-0.479182,-0.608849},
+  {-0.521973,0.822191},
+  {-0.532269,0.303592},
+  {1.239154,0.041944},
+  {0.389138,0.091142},
+  {-0.663000,0.328936},
+  {0.342085,-0.836875},
+  {-1.076007,-0.660702},
+  {-0.134030,0.851663},
+  {0.024222,0.084575},
+  {-1.902667,-0.772045},
+  {-0.584827,-0.179968},
+  {0.072428,0.119199},
+  {-0.342968,0.700217},
+  {-0.467256,-0.216460},
+  {0.245841,0.459667},
+  {-0.569716,-0.968906},
+  {-0.425136,-0.329992},
+  {-0.290409,0.687952},
+  {0.225955,0.172615},
+  {1.003682,-0.248519},
+  {-0.114798,1.216756},
+  {1.860231,-0.053088},
+  {0.106746,-0.618765},
+  {0.288442,-0.650337},
+  {0.718256,-0.694432},
+  {-0.331457,-0.719543},
+  {1.068076,0.148336},
+  {-0.096353,-0.028651},
+  {0.897863,-0.741848},
+  {0.412489,1.038703},
+  {-0.114692,-0.055749},
+  {0.139043,-0.040275},
+  {0.638080,-0.220795},
+  {-0.633578,1.226884},
+  {-0.251365,1.662993},
+  {0.225500,0.307234},
+  {-0.602385,-1.321478},
+  {0.034489,-0.600173},
+  {-0.758390,-0.563067},
+  {-0.284530,-0.408226},
+  {-0.579724,1.090416},
+  {0.564264,-0.546693},
+  {1.299442,-0.259779},
+  {0.540747,0.139655},
+  {0.950786,0.132223},
+  {-0.293267,-0.682357},
+  {-0.926701,1.267867},
+  {-0.861209,-0.469813},
+  {0.266995,0.266466},
+  {-0.336500,0.231023},
+  {-0.345643,0.297993},
+  {-1.065829,-0.717767},
+  {0.337612,-0.915230},
+  {0.091474,0.162675},
+  {0.308361,-0.094296},
+  {0.577293,-1.348639},
+  {-0.284413,0.283653},
+  {0.357282,0.494051},
+  {1.245152,0.281545},
+  {-1.431170,-0.390320},
+  {0.181289,0.594357},
+  {0.532038,-1.703506},
+  {-0.080299,-0.145390},
+  {0.706124,0.883663},
+  {-0.383556,-0.058734},
+  {-0.778841,-0.343133},
+  {0.466969,-0.233412},
+  {0.438538,-0.476148},
+  {0.583980,-0.010636},
+  {-0.877575,0.042320},
+  {0.360100,-1.169871},
+  {-0.088032,-0.398826},
+  {-0.476665,-0.290729},
+  {0.290340,0.526910},
+  {0.348399,-0.419803},
+  {0.846750,0.362483},
+  {1.325840,0.694740},
+  {-0.345673,-0.490818},
+  {-0.280731,-0.855840},
+  {1.003652,0.167563},
+  {0.046835,0.199770},
+  {-0.137995,0.109839},
+  {1.236355,0.414718},
+  {0.076375,0.187022},
+  {0.540177,1.332342},
+  {-0.536548,0.170836},
+  {-0.538823,-0.787885},
+  {-0.030721,-0.152529},
+  {-0.197468,-0.453547},
+  {-0.860949,-0.359616},
+  {-0.076259,-0.168284},
+  {0.128913,0.374510},
+  {0.491855,0.338274},
+  {0.841089,0.539245},
+  {-0.918791,-0.642914},
+  {0.722143,0.109400},
+  {-1.613346,0.192994},
+  {0.138179,0.384452},
+  {0.217286,0.484391},
+  {-0.617670,0.552131},
+  {-0.314759,1.396384},
+  {0.680449,0.920245},
+  {-0.776923,0.591054},
+  {0.357123,0.348420},
+  {-0.552000,-0.959852},
+  {-0.457786,-0.012405},
+  {0.194398,0.372935},
+  {-1.158776,-0.739099},
+  {-0.119856,0.695673},
+  {-1.044994,0.542655},
+  {-0.057589,0.663487},
+  {-0.637497,1.383641},
+  {0.841195,1.016650},
+  {-0.227216,0.350548},
+  {-0.666675,0.297665},
+  {-0.837852,0.428705},
+  {-1.515275,-0.555662},
+  {-0.151261,-0.712636},
+  {-0.221931,-0.513521},
+  {-1.443995,0.844288},
+  {0.313953,0.097811},
+  {-0.204681,-0.430877},
+  {0.980967,-0.423177},
+  {0.232925,-0.543011},
+  {0.306555,-0.317551},
+  {-1.105006,-0.200727},
+  {-0.491818,-0.043239},
+  {-0.024608,-0.174225},
+  {0.033530,2.148918},
+  {-0.623382,-0.443777},
+  {-1.073524,0.750841},
+  {-0.120307,1.009256},
+  {0.383676,-0.259419},
+  {-0.313467,-1.256964},
+  {-0.422919,-0.188656},
+  {1.284099,0.681505},
+  {0.223126,-0.031646},
+  {0.306322,-0.620767},
+  {0.442285,0.769126},
+  {-0.724718,-0.051262},
+  {0.239249,-0.361381},
+  {0.330321,-0.151744},
+  {-0.732583,0.357697},
+  {1.352363,0.469735},
+  {-0.520244,-1.172771},
+  {-0.830415,0.617391},
+  {-0.345373,-0.338332},
+  {-0.195310,1.495399},
+  {-0.303452,-0.330434},
+  {-0.858515,0.736562},
+  {-0.299252,0.080389},
+  {1.345959,-0.872637},
+  {0.074448,-0.237625},
+  {1.059866,-0.609576},
+  {-0.575313,0.866044},
+  {-0.077763,1.006470},
+  {-1.001055,0.181480},
+  {0.602403,-0.828705},
+  {0.704641,-0.635900},
+  {0.125989,0.812281},
+  {-0.020565,-0.376771},
+  {0.086654,0.473210},
+  {-0.807156,-0.842660},
+  {1.800373,0.552391},
+  {-0.130840,0.401600},
+  {1.213215,0.407588},
+  {0.032867,0.902099},
+  {-0.647827,-0.660410},
+  {0.139245,0.572428},
+  {0.503025,-0.013337},
+  {-0.345741,-0.790109},
+  {1.992791,-0.453862},
+  {-1.025935,0.141881},
+  {1.284579,-0.440883},
+  {-0.079254,0.984268},
+  {0.774126,0.771004},
+  {0.446898,0.009177},
+  {-0.145382,0.156029},
+  {0.640419,1.548422},
+  {0.417477,-0.537218},
+  {-0.166369,-1.168204},
+  {-1.576589,-0.006857},
+  {-0.568257,0.799393},
+  {-0.097194,0.950091},
+  {0.517471,-1.411220},
+  {0.238796,-0.516115},
+  {0.520339,0.649062},
+  {0.066756,-0.377378},
+  {-0.337598,0.506655},
+  {0.082550,-0.452063},
+  {0.348994,0.931952},
+  {-0.986407,-0.704322},
+  {-0.127239,0.598529},
+  {0.326580,-0.100612},
+  {-0.479889,-0.405277},
+  {-1.261540,0.389325},
+  {-0.326830,-0.479964},
+  {0.362882,0.916080},
+  {0.351699,0.236263},
+  {0.339159,-0.569330},
+  {0.193999,0.722854},
+  {-0.383134,-0.307248},
+  {0.983325,-0.083201},
+  {0.134546,1.185024},
+  {0.453730,0.055284},
+  {0.699766,-0.295923},
+  {-1.300227,2.106761},
+  {1.649077,0.568909},
+  {1.754100,-0.494836},
+  {1.533405,0.734520},
+  {1.171021,0.482031},
+  {1.401353,0.104870},
+  {0.365542,-1.022673},
+  {-0.297745,0.086303},
+  {0.811492,0.413641},
+  {-0.006258,0.257878},
+  {0.025602,0.267244},
+  {0.302591,0.729528},
+  {1.143575,0.702035},
+  {0.878501,0.429343},
+  {-0.568291,1.009797},
+  {0.475038,-0.837439},
+  {0.463692,0.574354},
+  {-0.262200,-0.340073},
+  {-0.092665,0.807504},
+  {0.502834,-0.559747},
+  {-0.405528,0.310426},
+  {0.892265,0.595287},
+  {1.606894,-1.747076},
+  {-0.552482,0.153944},
+  {-1.140951,0.420524},
+  {-0.002796,0.745166},
+  {1.856330,-0.471658},
+  {-0.278099,0.079846},
+  {-0.859602,0.915874},
+  {-0.131552,-0.316820},
+  {-0.384475,-0.141175},
+  {1.036717,-0.801126},
+  {-0.243963,-0.971380},
+  {-0.096054,0.106090},
+  {-1.006589,0.633260},
+  {1.195284,0.049783},
+  {1.377535,0.570432},
+  {0.727388,0.842091},
+  {-0.591521,-0.187649},
+  {0.435684,-0.688750},
+  {-0.294460,0.716584},
+  {1.215540,-0.474825},
+  {-0.696852,-1.070607},
+  {-0.396589,0.554698},
+  {0.089609,-0.423692},
+  {-1.348885,-0.346625},
+  {0.203519,0.440114},
+  {0.743717,-0.894146},
+  {-0.159810,-0.334923},
+  {0.682591,-0.546565},
+  {-0.712575,0.476973},
+  {-1.104661,-0.456355},
+  {-0.479537,0.251457},
+  {-1.174705,-0.052909},
+  {-0.352342,0.708805},
+  {0.131579,-0.078383},
+  {0.418601,0.558629},
+  {-0.035404,-0.244368},
+  {0.264606,-1.039640},
+  {-0.949351,0.500103},
+  {0.788048,0.890085},
+  {-0.089676,0.665759},
+  {-0.926300,0.785008},
+  {0.511916,0.407786},
+  {0.421369,-0.501708},
+  {0.673039,-0.920122},
+  {-1.286538,-0.354717},
+  {0.248195,0.038161},
+  {-0.205990,1.080045},
+  {-0.217009,0.702000},
+  {-0.276423,0.807365},
+  {-0.426657,0.829259},
+  {1.389469,-0.172937},
+  {0.242023,0.337750},
+  {0.111603,-1.317547},
+  {-0.474308,-0.557545},
+  {-0.943573,0.433703},
+  {0.637707,-0.325782},
+  {0.288693,0.683452},
+  {0.404386,0.934451},
+  {0.280019,0.234267},
+  {0.235777,-0.732291},
+  {0.679205,-0.897298},
+  {-0.633602,1.471122},
+  {0.135238,0.129816},
+  {-0.615491,-0.198805},
+  {-0.064142,-0.264310},
+  {-0.386053,-0.523291},
+  {0.905432,-0.812653},
+  {-0.251535,0.119324},
+  {0.544902,-1.468042},
+  {0.940112,-1.020098},
+  {0.261122,0.539496},
+  {-1.028811,-1.062924},
+  {-0.961214,1.210793},
+  {0.440965,-0.383521},
+  {-0.471681,-0.646258},
+  {-0.640999,0.630283},
+  {-0.593379,0.907085},
+  {-0.559648,-0.906520},
+  {0.131252,0.190629},
+  {-1.155937,0.469075},
+  {-0.774295,0.491694},
+  {-0.391053,0.660751},
+  {0.248040,0.038323},
+  {-0.603211,0.265228},
+  {-1.222478,-0.223261},
+  {1.022423,0.355851},
+  {0.285110,0.398718},
+  {1.496522,-0.815689},
+  {0.651223,-0.214058},
+  {1.483784,-0.345858},
+  {0.338015,-0.489712},
+  {-0.046722,-0.437334},
+  {0.159075,-1.718044},
+  {-0.190740,-0.099638},
+  {0.061885,0.049811},
+  {0.679428,-0.232491},
+  {0.435870,-0.001996},
+  {1.027309,-0.975858},
+  {-0.014691,-0.487557},
+  {-0.295080,0.752236},
+  {-0.274321,0.469497},
+  {-0.517557,1.067698},
+  {0.064585,0.127431},
+  {-1.046478,-0.199519},
+  {0.243379,0.939476},
+  {0.061894,-0.918354},
+  {0.182123,0.572483},
+  {0.530045,0.686889},
+  {-0.039721,-0.301593},
+  {1.310340,-1.022175},
+  {0.167251,-0.342483},
+  {-0.873160,0.739288},
+  {1.084948,-1.081913},
+  {0.987790,-0.737875},
+  {1.115765,0.832754},
+  {0.710369,0.565371},
+  {1.222391,-0.328709},
+  {0.981649,-0.055245},
+  {-0.777509,-1.846205},
+  {0.368035,0.488807},
+  {-1.365216,0.569074},
+  {1.124465,0.671338},
+  {0.992709,0.751788},
+  {-0.470874,0.278596},
+  {0.636061,-0.169493},
+  {0.359905,0.085555},
+  {0.222456,0.382605},
+  {-1.173254,0.201384},
+  {0.279053,-1.466444},
+  {-0.551690,1.345065},
+  {-0.510876,-0.198530},
+  {0.495703,-0.623988},
+  {0.084364,0.323890},
+  {-1.999895,-0.270420},
+  {-0.076837,1.042714},
+  {-0.752037,0.184538},
+  {0.788181,-0.585590},
+  {-0.331946,0.352529},
+  {-0.573372,0.687863},
+  {0.138512,-0.567696},
+  {-0.295121,-0.726297},
+  {-0.543169,0.137349},
+  {-1.715495,-1.038332},
+  {-0.792709,1.829956},
+  {-0.512584,-0.042359},
+  {0.314335,0.342696},
+  {0.301736,0.685331},
+  {0.538495,1.567646},
+  {0.619975,0.078173},
+  {-0.498993,-0.523364},
+  {-0.772238,0.214198},
+  {-0.098512,-0.182276},
+  {0.454210,-0.534136},
+  {-1.022817,-1.137971},
+  {0.073646,1.100400},
+  {-1.024269,-1.297541},
+  {0.102126,-0.936219},
+  {-0.656945,0.838675},
+  {-0.883419,-0.256136},
+  {-0.187742,-0.020857},
+  {0.277194,-0.076560},
+  {0.664217,-0.799587},
+  {-0.150595,-0.678707},
+  {1.282330,-0.650995},
+  {0.230992,-0.615056},
+  {1.240003,-0.672353},
+  {-0.277618,-0.291440},
+  {0.819647,0.226890},
+  {0.150397,-0.913147},
+  {-0.416220,0.946438},
+  {-0.076384,1.536212},
+  {1.392241,-1.502352},
+  {1.326505,-0.499578},
+  {-0.091994,-0.153227},
+  {-0.961196,0.689524},
+  {0.781255,-0.480439},
+  {0.928013,0.550042},
+  {-0.232140,0.627398},
+  {-0.954812,-0.337019},
+  {0.310334,1.994616},
+  {0.437513,-0.248398},
+  {0.219854,0.604570},
+  {-0.986371,0.508113},
+  {0.338285,-1.014958},
+  {0.109864,0.456381},
+  {0.279878,-0.662212},
+  {0.837898,0.324217},
+  {0.556637,0.129244},
+  {0.274982,0.417030},
+  {-0.610253,-0.031767},
+  {0.087246,-0.527219},
+  {-0.003924,-0.518842},
+  {-1.162910,0.023406},
+  {-0.748007,-0.086280},
+  {-1.473481,0.519776},
+  {0.227004,-0.462845},
+  {-1.082161,0.747261},
+  {-0.506904,0.368379},
+  {-0.400566,-0.884841},
+  {0.601519,0.983189},
+  {-0.166960,0.343570},
+  {-1.095310,0.099506},
+  {1.360160,0.674208},
+  {-0.147483,0.107427},
+  {0.281204,-0.417472},
+  {0.661175,-0.414379},
+  {-1.448734,1.031802},
+  {-0.755926,0.045997},
+  {-0.411609,0.573619},
+  {0.557744,0.825309},
+  {-0.849476,-0.220213},
+  {0.491201,0.095585},
+  {0.495856,-0.624079},
+  {0.271922,-0.075840},
+  {-1.176081,0.131668},
+  {0.199308,0.838635},
+  {1.157825,-0.261944},
+  {0.499849,0.118281},
+  {0.977981,0.048878},
+  {1.199673,-0.964225},
+  {0.858596,-0.581090},
+  {-0.452553,-0.218746},
+  {0.299985,0.111416},
+  {0.658092,0.162666},
+  {-1.038127,-1.509123},
+  {-0.476839,-0.238866},
+  {-0.825964,-0.083540},
+  {-0.311650,0.915382},
+  {-0.346397,0.095597},
+  {1.291551,-0.057599},
+  {-0.180325,1.013067},
+  {-0.377176,-0.025424},
+  {-0.170279,-0.752118},
+  {-1.045206,-0.436628},
+  {1.077868,0.598796},
+  {-1.083213,-1.758250},
+  {-0.312935,0.179621},
+  {0.255198,-0.202909},
+  {0.713268,-1.475905},
+  {-0.464259,0.230728},
+  {-0.089435,0.405254},
+  {0.475353,-0.424938},
+  {-0.867856,-0.104100},
+  {-0.636819,-0.246586},
+  {-0.172386,0.532258},
+  {-0.100517,-0.057939},
+  {-0.090309,-0.013900},
+  {-0.012730,-0.418781},
+  {-0.323899,-0.112924},
+  {0.548806,-0.078950},
+  {0.011270,-0.804839},
+  {-1.476368,0.179108},
+  {0.820229,-0.630583},
+  {1.295267,-0.443406},
+  {0.544548,0.943069},
+  {1.785252,-0.261154},
+  {2.075199,-0.129452},
+  {0.294332,0.738836},
+  {-0.488866,1.007274},
+  {-0.503534,-1.208814},
+  {-0.422143,0.460624},
+  {-0.695711,1.140055},
+  {-0.298145,0.028151},
+  {-0.530038,0.012494},
+  {1.063207,0.272223},
+  {0.307094,-0.925566},
+  {-0.396384,-0.079196},
+  {-0.264129,-0.690633},
+  {0.342815,1.176028},
+  {0.208513,0.031339},
+  {1.092949,-1.279019},
+  {-0.182367,1.458113},
+  {0.459643,0.537035},
+  {-1.422746,-0.199628},
+  {0.120842,0.431555},
+  {0.120487,0.860370},
+  {0.880075,-1.318327},
+  {-0.918494,-0.508262},
+  {1.039805,-0.397278},
+  {-1.116948,-0.764242},
+  {-0.648588,0.086831},
+  {-0.310475,0.435516},
+  {0.627558,-0.763336},
+  {-0.357348,1.121826},
+  {-0.261118,-0.210469},
+  {0.566079,0.338734},
+  {0.732632,-0.864559},
+  {-0.031237,-0.416613},
+  {-0.486114,0.440274},
+  {1.080200,0.451333},
+  {0.411008,-0.914379},
+  {1.630417,-0.573224},
+  {1.789973,-0.128818},
+  {-1.282816,-0.068424},
+  {0.649218,-0.044922},
+  {0.219130,0.525529},
+  {-0.370677,-0.053050},
+  {1.003421,-0.883361},
+  {-0.342108,-0.405991},
+  {0.559990,0.090486},
+  {-0.819193,1.397662},
+  {-0.712352,0.014975},
+  {0.372887,0.809808},
+  {0.368211,0.098352},
+  {0.107715,0.035441},
+  {-1.024098,0.171511},
+  {-1.378939,-0.282636},
+  {-0.515788,0.376429},
+  {0.019939,0.105386},
+  {-0.458813,-0.083868},
+  {-0.496787,0.049241},
+  {0.463699,0.772761},
+  {-0.261173,1.395466},
+  {-0.700428,-0.454140},
+  {0.203633,0.129327},
+  {0.688547,-0.064068},
+  {-0.286357,-0.615908},
+  {1.006754,-0.251008},
+  {0.233480,0.634520},
+  {0.098067,-0.799585},
+  {0.531663,1.047693},
+  {-0.357639,0.643432},
+  {-0.454815,-1.314132},
+  {0.024120,0.533402},
+  {-0.411249,-1.147575},
+  {-0.478917,0.650582},
+  {0.527923,-0.220407},
+  {0.760079,-0.003595},
+  {-1.436180,1.015680},
+  {0.226704,0.663645},
+  {-0.045143,-0.061152},
+  {-0.302953,0.503048},
+  {-1.017092,-0.028102},
+  {-0.437520,-0.181724},
+  {0.691820,0.557386},
+  {0.481078,0.854929},
+  {0.210535,-0.105821},
+  {0.309759,1.545655},
+  {-0.118720,-0.106134},
+  {-0.491147,0.073132},
+  {-0.315558,1.304714},
+  {-0.069603,-0.566994},
+  {-1.420324,-0.302228},
+  {-0.001001,-0.159619},
+  {0.538514,-0.717943},
+  {-0.023256,0.486612},
+  {0.961986,-0.094342},
+  {1.390177,1.690547},
+  {0.060921,-0.573038},
+  {1.227780,-1.614966},
+  {0.860354,0.141537},
+  {-0.673537,-0.182732},
+  {-0.394389,0.486924},
+  {0.189958,-0.299760},
+  {-0.187816,0.758961},
+  {0.930850,0.838789},
+  {0.532089,0.052800},
+  {1.183978,0.043238},
+  {0.000885,1.006165},
+  {0.652237,-0.033242},
+  {-0.062365,0.853989},
+  {0.074019,1.062932},
+  {0.548674,1.299869},
+  {0.635525,0.892433},
+  {1.040413,-0.904244},
+  {-0.637131,-1.220854},
+  {-0.178723,0.705191},
+  {0.679517,-1.054694},
+  {0.050417,0.463792},
+  {-0.432476,-0.705006},
+  {0.479097,-1.050954},
+  {0.759427,-0.851752},
+  {1.022693,-0.592958},
+  {-1.062087,0.416080},
+  {0.240269,-0.546121},
+  {0.721674,0.787447},
+  {0.390897,0.893822},
+  {-1.344788,-0.366112},
+  {-0.388957,1.529754},
+  {-0.410491,-0.551688},
+  {0.059600,0.157555},
+  {0.589211,0.635496},
+  {1.524161,-0.681505},
+  {0.382074,0.694384},
+  {0.184238,-1.242472},
+  {-1.872358,0.314061},
+  {0.197887,-0.051333},
+  {0.134921,1.052766},
+  {0.262707,0.571038},
+  {0.217454,1.533922},
+  {-0.473612,1.565367},
+  {-0.430548,-0.327960},
+  {2.456992,0.326251},
+  {-0.249071,-1.096478},
+  {1.629764,0.016947},
+  {-0.311299,-0.966789},
+  {-0.271977,0.129707},
+  {0.570742,0.441806},
+  {-0.663392,-0.189752},
+  {-0.657755,-0.378028},
+  {-0.289619,0.178035},
+  {-1.547191,-1.379442},
+  {0.318863,0.097885},
+  {-0.133141,-0.867632},
+  {1.709726,-0.325249},
+  {-0.859378,-1.097579},
+  {-0.824774,-1.066003},
+  {0.667650,-0.896375},
+  {0.771396,0.193745},
+  {0.187997,0.834902},
+  {0.264365,-0.077232},
+  {-0.205345,-0.363629},
+  {0.785119,0.128526},
+  {-0.691053,-0.612586},
+  {0.013257,-0.052083},
+  {0.825087,0.514926},
+  {-0.296533,0.266757},
+  {0.172197,-1.001242},
+  {-0.096571,0.384834},
+  {0.009580,-0.143642},
+  {-0.430595,0.227296},
+  {0.246564,-0.054633},
+  {-0.094468,-0.110370},
+  {-0.692380,0.378773},
+  {-0.199042,-1.555449},
+  {0.505427,0.687997},
+  {0.449979,0.039450},
+  {0.393759,-0.881240},
+  {1.174371,0.587504},
+  {-0.022562,-0.094548},
+  {0.799280,-1.480472},
+  {0.041460,-1.331186},
+  {-0.092273,-0.056904},
+  {1.089637,1.394368},
+  {0.377098,-0.286844},
+  {-1.518074,0.303598},
+  {-0.424125,-0.919862},
+  {0.735314,0.790515},
+  {-0.419136,-0.537595},
+  {-0.224393,-1.089326},
+  {-0.932735,0.204017},
+  {-1.046173,-0.492433},
+  {0.530493,-0.892328},
+  {-1.605953,-0.056949},
+  {-0.082756,-0.072003},
+  {-0.273932,-0.025963},
+  {-0.800355,0.314344},
+  {0.072312,0.478394},
+  {0.398293,0.285516},
+  {-0.548830,0.122373},
+  {-0.168767,0.843687},
+  {-0.270897,1.661998},
+  {-1.170453,-0.201107},
+  {-0.475110,-0.145280},
+  {1.305465,-0.282810},
+  {-0.315642,0.100244},
+  {-0.086178,1.029969},
+  {0.615427,0.779651},
+  {-0.207107,0.112033},
+  {1.324170,-0.301879},
+  {0.970426,-0.300709},
+  {-0.051026,-1.504892},
+  {-0.710653,0.471644},
+  {-0.246991,0.815189},
+  {0.603725,0.395888},
+  {0.287185,-0.903460},
+  {0.542505,-0.034145},
+  {0.491362,0.846853},
+  {-0.795065,-0.413406},
+  {-0.094830,-1.353670},
+  {0.848408,-0.279441},
+  {0.423856,-0.773367},
+  {0.223410,-0.744911},
+  {-0.290439,0.138562},
+  {0.179655,-0.293731},
+  {0.963360,1.602055},
+  {-0.162586,-0.561803},
+  {0.690172,-0.162130},
+  {-0.056525,-0.217605},
+  {0.406531,-1.570055},
+  {-0.214027,1.317937},
+  {-1.324464,0.041843},
+  {0.524061,0.463133},
+  {-0.308113,-0.660500},
+  {-0.045374,0.866035},
+  {-1.375194,-0.346669},
+  {-0.241115,-1.057360},
+  {1.046871,1.007542},
+  {-1.538573,-0.349429},
+  {-1.296515,0.500255},
+  {-0.319061,1.182597},
+  {0.822835,1.088292},
+  {-0.242570,0.808708},
+  {-0.741186,-0.287133},
+  {-0.043203,-0.170825},
+  {0.086436,1.296764},
+  {0.039347,0.444439},
+  {-0.452934,0.019311},
+  {0.165106,0.678114},
+  {0.077917,0.386698},
+  {-0.827517,0.531529},
+  {0.008533,0.559169},
+  {0.779173,-1.106132},
+  {-0.141012,-1.305121},
+  {-0.017937,0.457808},
+  {1.289752,0.160765},
+  {0.540358,1.399083},
+  {-0.512611,0.568784},
+  {-0.648622,-0.300842},
+  {-0.293245,1.682090},
+  {0.675206,0.479373},
+  {-0.247437,0.127139},
+  {0.385699,-1.137733},
+  {0.734392,0.440471},
+  {-1.045057,-0.228324},
+  {0.556728,-0.598054},
+  {-0.283752,-0.097712},
+  {-0.555117,0.220327},
+  {0.850535,0.713509},
+  {-0.187237,-0.137412},
+  {-0.069355,-0.705473},
+  {0.514740,-0.842808},
+  {-0.680879,-0.366539},
+  {0.249006,-0.335864},
+  {-0.098391,0.639156},
+  {0.171737,-0.709357},
+  {-0.443634,-0.636049},
+  {1.088524,0.709373},
+  {1.223219,-0.602659},
+  {1.372139,-0.120711},
+  {0.934723,0.998017},
+  {-0.627598,0.214279},
+  {1.030711,-0.173404},
+  {0.136914,0.142240},
+  {-0.703009,-1.393580},
+  {0.296772,-0.271707},
+  {-0.650348,0.475265},
+  {0.681210,-0.614719},
+  {-0.063976,0.173702},
+  {0.927263,-0.034156},
+  {0.436673,0.433596},
+  {-0.011766,0.233163},
+  {-0.461304,-2.176818},
+  {-0.555505,-0.395928},
+  {-0.121968,-0.515902},
+  {-0.078036,-0.661705},
+  {0.922070,-1.399317},
+  {0.438197,-0.410533},
+  {0.889117,2.238643},
+  {-0.109874,-1.599532},
+  {-0.122962,-0.682850},
+  {-1.305958,-0.154182},
+  {0.431402,1.018367},
+  {-0.143377,-0.893054},
+  {0.560765,-0.446487},
+  {0.753484,-0.241121},
+  {-0.967923,0.257292},
+  {-0.119665,-1.032914},
+  {-0.991815,0.479675},
+  {-0.629275,0.847630},
+  {0.721789,0.636400},
+  {0.977668,-0.039434},
+  {0.187379,-0.387067},
+  {-0.314152,0.141318},
+  {-0.817531,0.628117},
+  {-0.923341,-0.167044},
+  {-0.155868,-0.084994},
+  {-0.686082,-0.206933},
+  {0.021763,-1.069100},
+  {0.091063,-0.184178},
+  {-0.307996,-0.942727},
+  {0.036592,0.643156},
+  {-0.299491,1.314708},
+  {-0.149338,-0.041127},
+  {-0.365165,0.727747},
+  {-0.591302,-0.009641},
+  {-0.511106,0.790851},
+  {-0.008839,-0.298441},
+  {0.450988,-0.963904},
+  {-0.043228,-0.140045},
+  {0.622787,-0.480381},
+  {1.330465,-0.430632},
+  {0.237069,0.372814},
+  {0.013612,0.660065},
+  {-0.005838,0.638106},
+  {0.099138,0.487362},
+  {-0.462270,0.760901},
+  {-0.039276,-0.367186},
+  {-0.849389,0.963066},
+  {0.260960,-0.760724},
+  {-0.017266,-0.504135},
+  {0.468009,0.090059},
+  {1.015524,0.512994},
+  {0.320663,-0.586802},
+  {1.320691,-0.542734},
+  {-0.662519,-0.014055},
+  {-0.297684,-0.044484},
+  {-0.799770,-0.356844},
+  {-0.382747,0.640791},
+  {-0.656885,0.305997},
+  {0.114703,-0.966648},
+  {0.136089,-0.769987},
+  {0.032134,-0.482388},
+  {0.164098,-0.131159},
+  {0.378416,0.078075},
+  {-0.221686,1.091587},
+  {-0.103693,0.709294},
+  {-0.345252,-0.305954},
+  {1.203122,-0.260458},
+  {0.793078,-1.844025},
+  {0.052521,0.691232},
+  {0.327413,1.180506},
+  {0.000942,-0.045549},
+  {0.500746,-0.800283},
+  {-0.118962,-0.269397},
+  {0.302711,-0.955327},
+  {-0.451537,-0.663640},
+  {-0.783589,-0.143810},
+  {0.777130,0.550576},
+  {-1.296793,-0.096188},
+  {0.156387,1.318119},
+  {-0.441793,0.789109},
+  {0.098510,-0.721234},
+  {1.144887,0.174284},
+  {-0.628743,1.542204},
+  {-0.746915,-1.002669},
+  {0.640209,1.564354},
+  {-0.042800,0.694716},
+  {-1.546423,0.892586},
+  {-0.302209,1.431112},
+  {-0.691142,0.333508},
+  {-0.429388,-1.099203},
+  {1.047799,-0.141377},
+  {-0.835629,-0.419429},
+  {-0.395704,0.291504},
+  {1.169077,-0.006899},
+  {-0.000406,-1.023570},
+  {-0.005843,0.363119},
+  {-0.830499,-0.161589},
+  {-0.049930,0.150634},
+  {0.110034,0.489642},
+  {0.229673,-0.090654},
+  {0.628243,1.472188},
+  {-0.426285,-0.014405},
+  {0.704156,-0.031663},
+  {1.408712,-0.223024},
+  {-0.310124,0.322176},
+  {1.341750,-0.011950},
+  {-0.475503,-0.217211},
+  {-0.322988,0.045987},
+  {-0.293056,0.205099},
+  {-0.120599,-0.231858},
+  {-0.145756,-1.419736},
+  {0.586338,0.525593},
+  {-0.107314,0.053626},
+  {-0.592978,-0.037145},
+  {-1.158385,-1.045554},
+  {0.119389,0.728346},
+  {1.574950,-0.490199},
+  {-0.282055,-0.229629},
+  {0.168220,0.641829},
+  {0.215137,0.436435},
+  {-1.469822,-1.022768},
+  {0.122827,-0.355324},
+  {0.340368,0.460545},
+  {-0.133655,-0.013018},
+  {-0.214706,-0.229367},
+  {1.137280,-0.600999},
+  {-0.774999,-1.178053},
+  {1.518943,1.058591},
+  {0.407081,-0.502228},
+  {-1.241990,0.417551},
+  {0.014212,0.382705},
+  {1.079171,0.037512},
+  {1.449532,-0.035599},
+  {-0.342860,0.119856},
+  {-0.203089,1.758978},
+  {0.892215,-0.343795},
+  {-0.742509,-0.990385},
+  {0.467033,-0.033716},
+  {0.478131,-0.642241},
+  {1.344997,-0.160438},
+  {-0.420145,0.331979},
+  {-0.652954,0.592996},
+  {-0.495241,0.174791},
+  {0.187080,-0.257417},
+  {-0.382043,-0.147167},
+  {0.529967,0.430835},
+  {0.479963,-0.054450},
+  {-0.878576,0.171068},
+  {0.128695,-0.437802},
+  {-0.715424,-0.054429},
+  {-0.735767,1.208460},
+  {0.913745,0.145152},
+  {-0.901428,0.263530},
+  {-0.108728,1.211707},
+  {0.869162,1.245237},
+  {1.346936,0.981211},
+  {0.064847,-0.378967},
+  {0.076235,1.113281},
+  {-0.158075,-0.350806},
+  {-0.830559,0.718345},
+  {0.165189,0.659124},
+  {0.566927,-0.057358},
+  {-0.256642,0.501692},
+  {-0.496891,0.558987},
+  {0.314791,1.531419},
+  {-0.105210,-0.967250},
+  {0.340576,0.711382},
+  {-1.141627,-1.066447},
+  {-0.110436,-0.387441},
+  {0.079143,-0.720602},
+  {0.166833,0.239506},
+  {-0.442205,-0.338438},
+  {0.483370,0.156757},
+  {0.693114,0.276451},
+  {-0.183391,0.020851},
+  {0.204206,-0.677262},
+  {0.689076,0.309579},
+  {-0.481239,-0.584827},
+  {-0.933420,-0.491870},
+  {-0.520784,-0.281925},
+  {1.692787,-0.862935},
+  {0.974295,-0.065542},
+  {0.013460,-0.253194},
+  {-0.484361,0.487765},
+  {1.102883,-0.797744},
+  {1.017178,-0.706175},
+  {-0.306430,0.465774},
+  {0.652186,0.377622},
+  {-0.509788,-0.117614},
+  {-0.182832,0.281499},
+  {-0.243806,-0.608884},
+  {-0.812188,1.031517},
+  {-0.318785,-1.096473},
+  {-0.753378,0.448524},
+  {0.190946,0.805434},
+  {1.315679,0.386423},
+  {0.517649,-0.029638},
+  {0.005505,0.303030},
+  {0.245582,-0.056264},
+  {-1.003810,0.352134},
+  {0.145024,0.704185},
+  {0.462317,0.143256},
+  {0.942234,0.897553},
+  {-0.215521,-0.331736},
+  {-0.486441,-0.282984},
+  {-0.132013,-0.653772},
+  {0.703166,-0.978950},
+  {1.265242,-0.730936},
+  {0.541313,-1.092878},
+  {-0.426889,-0.709462},
+  {0.358945,-0.092949},
+  {1.287703,-0.466656},
+  {-0.029177,-0.528144},
+  {-1.262047,-0.156719},
+  {1.119061,-0.140010},
+  {0.744231,1.364940},
+  {-1.477712,0.677879},
+  {1.394701,0.568561},
+  {-0.709296,1.089103},
+  {-1.084068,1.032923},
+  {0.692925,-1.436255},
+  {-0.583488,0.006146},
+  {-0.096832,0.481081},
+  {0.065004,-0.486029},
+  {0.870241,-0.777612},
+  {-0.485691,1.334895},
+  {1.654056,-0.558402},
+  {-0.123607,-0.634878},
+  {-0.327436,-0.483555},
+  {-0.308836,0.238801},
+  {0.997275,0.372461},
+  {1.298622,-0.350636},
+  {0.054553,-0.251766},
+  {-0.663848,0.096227},
+  {-0.414783,-0.476282},
+  {0.017994,-0.596242},
+  {0.073553,0.224045},
+  {-0.017235,-0.787626},
+  {-0.513162,-0.883175},
+  {0.296796,-0.667669},
+  {0.609890,0.396096},
+  {-0.429109,0.719473},
+  {1.004360,-0.399219},
+  {-0.729476,-0.121898},
+  {0.495306,0.262692},
+  {-0.113961,-0.354866},
+  {-0.397658,0.111103},
+  {0.772712,0.034410},
+  {1.351640,-0.201355},
+  {-0.632191,-0.828298},
+  {-1.263127,-0.771645},
+  {0.439372,-1.090465},
+  {0.360964,-0.050497},
+  {0.347296,-0.241183},
+  {0.779991,1.223795},
+  {-0.304319,0.532105},
+  {0.438098,0.404655},
+  {-0.851470,-0.274463},
+  {-0.456542,0.692725},
+  {-0.246019,0.385583},
+  {0.191244,0.619761},
+  {-1.086195,0.003533},
+  {0.904869,0.542475},
+  {0.998638,0.170402},
+  {-0.706807,-0.315809},
+  {0.166527,-0.172701},
+  {-1.000581,-0.025441},
+  {-0.835619,1.640966},
+  {0.465558,-0.261938},
+  {-0.312499,1.039515},
+  {0.963936,0.325342},
+  {-0.691905,-1.644457},
+  {0.352920,-1.072839},
+  {0.628098,0.001310},
+  {0.081833,0.343911},
+  {0.014168,0.756927},
+  {-0.973338,-0.558293},
+  {-0.871959,-0.104032},
+  {-0.002001,-0.006319},
+  {1.286904,-0.201689},
+  {0.244030,1.578598},
+  {-0.616804,0.274645},
+  {-0.318141,0.335599},
+  {-0.697360,-0.095197},
+  {0.011818,-0.863732},
+  {-0.138582,-0.019176},
+  {-0.725250,-0.217377},
+  {-0.875897,0.417330},
+  {-0.319059,0.539565},
+  {-0.482789,-0.312334},
+  {0.409422,1.158154},
+  {-0.015202,0.405469},
+  {0.566499,-0.239419},
+  {-0.048926,-0.333125},
+  {0.123632,-0.575811},
+  {-0.737014,1.050065},
+  {-0.498796,-0.462582},
+  {1.103683,-1.514551},
+  {-0.494598,-0.326410},
+  {-0.197300,0.386700},
+  {0.062856,0.241676},
+  {1.540076,0.134030},
+  {0.167199,0.718623},
+  {1.460202,0.168436},
+  {-0.151115,1.190752},
+  {-1.605562,-0.849851},
+  {-0.182316,0.843664},
+  {0.063442,-0.632068},
+  {0.600120,-1.467388},
+  {-0.214057,0.008288},
+  {-0.591725,0.015858},
+  {0.426621,-0.467059},
+  {0.308007,-0.521593},
+  {0.187186,0.432812},
+  {0.771873,-0.797405},
+  {-1.666113,-0.612908},
+  {0.662923,-0.640449},
+  {0.418502,0.839952},
+  {0.567399,1.411843},
+  {1.409143,0.943162},
+  {0.272974,0.334327},
+  {-0.194930,-0.042914},
+  {-0.656420,0.632150},
+  {-1.041831,0.166806},
+  {0.747201,0.813639},
+  {0.281704,0.944374},
+  {1.358369,0.491507},
+  {0.367469,-0.875805},
+  {-0.422513,0.169091},
+  {1.285167,0.685694},
+  {0.330428,-0.193560},
+  {0.299608,0.675410},
+  {-0.270314,-0.081031},
+  {0.064389,1.581159},
+  {-0.222432,-0.019499},
+  {0.426707,0.157563},
+  {0.722662,-0.647789},
+  {0.242988,0.714443},
+  {0.748898,-0.308079},
+  {-0.016544,0.354901},
+  {-0.997099,-0.209123},
+  {-0.235030,-0.400691},
+  {-0.203206,1.099828},
+  {0.142727,0.095450},
+  {-0.341516,0.326233},
+  {0.095229,0.019195},
+  {-0.660175,0.112390},
+  {0.905233,-0.514587},
+  {0.319161,-0.949665},
+  {-0.405405,-2.149487},
+  {0.208820,0.999381},
+  {-0.315606,1.516585},
+  {-0.641859,-1.688719},
+  {0.964642,-0.657701},
+  {0.065903,-0.060402},
+  {-0.026539,-0.681936},
+  {-0.614921,-0.563590},
+  {0.246976,-0.939397},
+  {0.385899,0.281023},
+  {-0.094005,0.848061},
+  {-0.169226,0.774612},
+  {-0.724207,0.299136},
+  {-1.194411,-0.024786},
+  {0.882686,-0.287766},
+  {-0.483190,-0.806528},
+  {-0.483338,0.922785},
+  {0.041603,0.257413},
+  {0.498249,0.308889},
+  {0.634894,-0.438796},
+  {0.295743,-0.624397},
+  {0.071996,0.006979},
+  {-0.372322,-0.699701},
+  {-0.914731,1.474448},
+  {-0.027933,-0.761139},
+  {-0.295425,-0.913413},
+  {1.158772,-0.605934},
+  {-1.099764,1.238334},
+  {0.225717,-0.107705},
+  {-0.060501,-0.133608},
+  {-1.004261,-0.846772},
+  {1.353121,0.234258},
+  {0.115511,-0.813911},
+  {-2.526341,-0.552748},
+  {0.628997,0.483053},
+  {-0.185551,0.719097},
+  {1.038135,-1.267809},
+  {-0.807875,-0.433980},
+  {-0.095644,0.352912},
+  {-0.401847,0.180421},
+  {0.326983,-0.414106},
+  {-0.700716,-0.454423},
+  {1.753344,0.341367},
+  {-0.495613,0.589827},
+  {0.795817,-0.022842},
+  {-0.921182,-0.686602},
+  {-1.692668,-0.029685},
+  {-1.122250,-0.221354},
+  {-0.588052,1.370316},
+  {0.988746,-0.162050},
+  {-0.653970,-0.824491},
+  {0.362938,-0.445459},
+  {1.171398,-0.033829},
+  {-0.128480,0.441175},
+  {-0.102669,-0.405796},
+  {1.815588,-0.843343},
+  {-0.009833,-0.493984},
+  {-0.949789,1.129682},
+  {0.396000,0.520610},
+  {0.793786,-1.116647},
+  {0.245421,-0.634161},
+  {-1.542438,0.723155},
+  {-0.983627,-0.634587},
+  {0.325658,0.423862},
+  {0.686591,0.678101},
+  {0.840170,1.189774},
+  {-0.124161,0.328021},
+  {-0.670110,0.306719},
+  {-0.647672,-0.390379},
+  {-0.799760,-0.896996},
+  {0.791386,0.183740},
+  {-0.999459,0.290365},
+  {0.108208,0.682826},
+  {0.722602,-0.063568},
+  {0.675050,-0.417068},
+  {0.049737,-0.626277},
+  {-0.091161,-0.152698},
+  {-0.169368,-0.424080},
+  {0.965155,1.073006},
+  {0.875146,0.371974},
+  {0.027511,-0.094845},
+  {0.046664,-0.034023},
+  {0.088000,0.191606},
+  {-0.292866,0.357606},
+  {0.486410,-0.150151},
+  {0.758034,0.769236},
+  {0.373728,0.795101},
+  {-0.271229,-0.284477},
+  {1.579846,-0.350881},
+  {-0.201557,0.028050},
+  {-0.509997,0.955817},
+  {0.452960,0.647232},
+  {-0.406892,0.567143},
+  {-1.706461,1.360423},
+  {0.953890,-0.875465},
+  {0.657629,0.021581},
+  {-0.129957,-1.226930},
+  {-0.302970,-0.942701},
+  {0.048147,-0.690086},
+  {-0.477384,0.846820},
+  {0.024795,1.669001},
+  {1.201373,0.130037},
+  {0.028444,-0.954818},
+  {0.597766,-0.157195},
+  {1.257619,-0.713805},
+  {-0.793364,0.384184},
+  {-1.448279,0.244332},
+  {-0.241725,0.023413},
+  {-0.834162,-1.002103},
+  {-0.092808,-0.130621},
+  {0.251400,0.563136},
+  {0.142776,-0.576081},
+  {0.082036,-0.836429},
+  {0.477424,-0.233922},
+  {0.592498,-0.708705},
+  {-0.092424,-0.165077},
+  {0.961011,-0.437526},
+  {-0.040373,-0.007315},
+  {0.151106,0.495559},
+  {-0.791185,-0.172713},
+  {0.532989,-0.116812},
+  {0.323417,-0.257345},
+  {-1.564697,1.408229},
+  {-0.721557,1.018666},
+  {0.590124,-0.231628},
+  {0.771734,-0.400268},
+  {-0.051036,0.575551},
+  {-0.045053,-0.822877},
+  {0.870412,0.425655},
+  {-0.252330,-0.444619},
+  {-0.101144,-0.403048},
+  {-0.027262,1.535667},
+  {-0.641673,-0.519516},
+  {0.738704,0.547992},
+  {0.168648,-0.151548},
+  {-1.710591,0.257789},
+  {-0.092677,0.346082},
+  {-0.338101,0.082259},
+  {-0.050333,-0.211235},
+  {-0.699288,-0.374695},
+  {-0.591992,1.089774},
+  {0.627032,-0.226781},
+  {-0.162334,0.632005},
+  {1.473994,-0.687098},
+  {-0.034147,-0.046207},
+  {1.689347,0.546087},
+  {-0.064003,0.303521},
+  {0.024821,-0.361900},
+  {0.625408,0.536032},
+  {0.859899,-0.542843},
+  {-0.768487,0.655731},
+  {0.156214,0.442436},
+  {-0.920403,-0.423091},
+  {0.288070,-0.057672},
+  {0.835439,-0.025869},
+  {0.486492,-0.403805},
+  {-0.670555,-0.015233},
+  {0.202429,-0.231184},
+  {0.368462,0.045512},
+  {-0.759523,-0.656840},
+  {-0.306825,-1.845469},
+  {-1.126798,0.416730},
+  {0.253965,-0.048144},
+  {0.573909,0.256679},
+  {-0.077506,0.902226},
+  {0.106140,-0.161830},
+  {0.944351,-0.103539},
+  {0.996280,0.024614},
+  {-0.437475,-0.095610},
+  {1.605320,0.269590},
+  {-0.030932,0.428579},
+  {0.298472,-0.901861},
+  {-0.459703,-1.415808},
+  {-1.427354,-0.827994},
+  {-0.668940,-0.453174},
+  {0.081398,-0.075764},
+  {0.449178,0.115437},
+  {1.319972,0.180253},
+  {0.214731,-0.518376},
+  {0.401389,-0.697856},
+  {-0.966804,-0.086393},
+  {0.091583,0.256263},
+  {0.121284,-0.390260},
+  {0.682460,0.337722},
+  {-0.528372,-0.012843},
+  {0.535463,0.220828},
+  {-0.207327,-0.002275},
+  {0.032177,-1.481349},
+  {-1.046740,0.503154},
+  {0.990748,-1.593273},
+  {-0.395646,0.419805},
+  {0.309283,-0.466387},
+  {1.107873,0.046100},
+  {0.557575,0.602810},
+  {-0.973449,-0.826520},
+  {1.174536,-0.115438},
+  {0.270087,-0.056070},
+  {0.301369,-1.259042},
+  {0.176198,0.039041},
+  {0.685912,-1.168439},
+  {0.868333,0.870309},
+  {0.428619,-0.314340},
+  {-0.605176,-0.019613},
+  {0.551734,0.028005},
+  {0.967593,-0.636688},
+  {0.282477,0.393573},
+  {0.681596,-0.537855},
+  {0.080952,0.362344},
+  {1.080137,-1.004045},
+  {-0.121193,-0.497869},
+  {0.873317,-0.001814},
+  {-0.626031,-0.544039},
+  {0.108145,-0.684680},
+  {-0.563032,-0.925852},
+  {0.979941,-0.514612},
+  {-0.608938,0.633467},
+  {-0.053909,0.182506},
+  {-0.043155,1.357664},
+  {-0.258396,0.276981},
+  {-0.273572,-0.131251},
+  {-0.146091,-0.601641},
+  {-0.285407,-0.362421},
+  {-0.145943,-0.085332},
+  {1.246647,-0.702939},
+  {0.000929,-0.146198},
+  {0.426066,0.520638},
+  {-0.385219,-1.726361},
+  {0.895211,0.932719},
+  {1.007455,-1.259203},
+  {-0.192862,0.700090},
+  {-0.229940,0.047657},
+  {-0.530813,-0.440148},
+  {-0.611116,-0.509634},
+  {-0.580100,0.142553},
+  {0.614953,0.098769},
+  {1.398503,0.775546},
+  {-0.541719,-1.671509},
+  {-0.241597,1.020908},
+  {-1.077532,-0.515526},
+  {0.655762,0.775059},
+  {-0.765450,-1.239293},
+  {0.962747,-0.806323},
+  {-0.609721,0.251087},
+  {0.050378,-0.384786},
+  {0.848758,0.698701},
+  {2.116104,1.231120},
+  {0.111879,-0.017177},
+  {-0.687465,-0.181288},
+  {-0.675059,-0.418819},
+  {0.279545,-0.339861},
+  {-0.599722,0.492495},
+  {0.684005,-0.397453},
+  {0.147776,-0.639692},
+  {0.097598,-0.641184},
+  {0.081977,0.034408},
+  {-1.362164,0.108665},
+  {0.163552,-1.671503},
+  {0.040631,-1.212350},
+  {0.291558,0.657082},
+  {-0.295903,-1.140027},
+  {-0.376469,1.434394},
+  {0.423132,1.500112},
+  {0.939533,0.706458},
+  {-0.723371,0.467943},
+  {0.734789,-1.367821},
+  {-0.286426,-0.430950},
+  {0.741645,0.202610},
+  {-0.474269,-0.383443},
+  {-0.111238,-1.258131},
+  {0.660971,-0.293692},
+  {-1.682554,0.395094},
+  {-0.315600,1.396362},
+  {-0.537842,0.199873},
+  {-0.495910,1.133647},
+  {-0.202967,0.311606},
+  {0.956309,1.302041},
+  {0.014266,1.520439},
+  {-0.219412,0.174062},
+  {-0.681151,-0.951635},
+  {0.404607,1.513381},
+  {0.416153,0.210891},
+  {0.142163,0.694091},
+  {0.076219,0.460826},
+  {-1.083648,1.037683},
+  {0.270994,0.354254},
+  {0.986873,2.149951},
+  {0.393861,0.989633},
+  {0.688971,0.339303},
+  {0.071278,0.056799},
+  {-1.016039,-0.020912},
+  {-1.334468,-0.536643},
+  {0.734131,-0.538999},
+  {0.610162,-0.467191},
+  {0.178098,0.248881},
+  {1.107075,0.903290},
+  {0.067019,0.376517},
+  {0.063519,0.307756},
+  {0.222092,0.047481},
+  {-0.642008,1.339605},
+  {-1.434671,0.390346},
+  {-0.286363,-1.096375},
+  {0.528233,-0.114303},
+  {0.002839,-0.363739},
+  {0.081966,0.477424},
+  {-0.745078,-0.212704},
+  {0.262151,-0.629614},
+  {0.650702,0.297788},
+  {-0.360384,0.654797},
+  {-1.210552,0.346825},
+  {-1.123528,0.141074},
+  {0.254125,0.134089},
+  {-0.854449,-1.272994},
+  {0.503444,0.407784},
+  {-0.063343,0.002590},
+  {-1.217891,0.297324},
+  {1.362821,-0.092500},
+  {-0.620024,-0.181695},
+  {-0.583878,-0.087572},
+  {-0.077708,-0.591811},
+  {0.407316,0.210572},
+  {0.370971,-1.195471},
+  {-0.299583,1.320451},
+  {0.203216,0.646346},
+  {0.366164,0.909438},
+  {0.203023,0.338926},
+  {0.886110,-0.616392},
+  {0.123373,-0.265751},
+  {1.002188,-0.721736},
+  {-0.087786,-0.162014},
+  {-0.147706,-0.257366},
+  {0.138837,0.156403},
+  {-0.935765,-0.897313},
+  {0.145589,0.934317},
+  {-1.257050,0.339883},
+  {-0.640691,-0.497094},
+  {0.249565,0.324230},
+  {0.429013,-0.807024},
+  {0.951042,-0.750363},
+  {-0.233908,0.322168},
+  {-0.155345,-0.058620},
+  {-0.923954,1.122193},
+  {0.575643,0.585440},
+  {0.020598,1.436937},
+  {-0.091407,-0.699294},
+  {0.578322,1.106103},
+  {-0.103452,-0.119980},
+  {1.023561,0.237926},
+  {-0.294089,-0.806202},
+  {0.353528,-0.555679},
+  {-0.047433,-0.322646},
+  {1.165529,0.140760},
+  {-0.792405,-0.115971},
+  {-1.054716,-1.248429},
+  {-0.445960,-0.522722},
+  {-0.535668,-0.623538},
+  {1.871897,0.379341},
+  {-0.602944,0.291409},
+  {0.163383,-0.302622},
+  {-0.434323,-0.137421},
+  {-0.350281,0.083213},
+  {0.871609,-0.841751},
+  {0.975364,-0.601977},
+  {0.494758,0.224624},
+  {0.242478,0.421058},
+  {0.232225,-1.453569},
+  {0.414761,0.849492},
+  {0.604876,0.053472},
+  {0.281405,-0.468279},
+  {-0.722334,-0.651553},
+  {0.212448,0.783791},
+  {0.338838,0.566970},
+  {0.968908,0.412173},
+  {-0.818738,1.184692},
+  {-0.942716,1.063357},
+  {0.156179,-0.884947},
+  {0.275563,-0.824764},
+  {0.161075,0.512591},
+  {-0.063483,-0.132659},
+  {0.244437,0.539625},
+  {-1.022381,0.103652},
+  {-0.191213,0.245448},
+  {1.202137,-0.341605},
+  {-0.830870,0.088173},
+  {-0.376038,-1.505356},
+  {-0.132499,-0.483134},
+  {1.405172,-0.388605},
+  {-0.731394,-0.474684},
+  {0.424459,1.084378},
+  {0.569630,-0.465403},
+  {0.342360,0.588034},
+  {0.530620,0.584731},
+  {0.465075,0.367666},
+  {0.476078,-0.835102},
+  {0.325328,0.098233},
+  {-0.588893,0.045396},
+  {0.190879,0.254040},
+  {0.743863,1.485769},
+  {0.092567,0.772116},
+  {-0.316621,0.345606},
+  {-0.782686,-0.306573},
+  {-0.034863,-0.764078},
+  {0.087823,1.095970},
+  {0.006421,0.475137},
+  {-0.539624,1.058665},
+  {-0.112003,-0.421538},
+  {0.814427,-2.240315},
+  {0.297667,0.029955},
+  {0.387983,0.365167},
+  {-0.512255,0.697944},
+  {-1.002389,-1.053748},
+  {0.785925,-0.982717},
+  {0.513858,-0.382507},
+  {-0.739047,0.720458},
+  {0.563904,-0.592574},
+  {0.269190,-0.290482},
+  {-0.443868,1.120572},
+  {-1.130339,0.430364},
+  {0.653121,-1.146882},
+  {-0.143795,-0.395516},
+  {-0.601965,0.136010},
+  {0.108440,-1.108889},
+  {-0.633592,-0.202239},
+  {-0.057448,0.917590},
+  {-0.339216,0.038929},
+  {-0.236586,0.236913},
+  {0.250535,0.573183},
+  {-1.205567,-0.151059},
+  {0.435760,0.422565},
+  {0.195745,-0.511377},
+  {1.127967,-0.973948},
+  {0.989271,-1.392772},
+  {0.135742,0.374199},
+  {-0.344161,0.674263},
+  {-0.011739,-0.360829},
+  {-1.431782,0.085627},
+  {-0.120657,0.501635},
+  {0.750871,0.035088},
+  {-0.415468,-0.782156},
+  {0.295173,0.275036},
+  {-0.601768,0.944578},
+  {-0.818800,-0.499709},
+  {0.750934,0.255211},
+  {0.011539,-0.207586},
+  {-0.059063,0.577347},
+  {0.027127,0.182079},
+  {0.058243,0.931415},
+  {-0.671812,0.744172},
+  {0.645644,0.221537},
+  {-0.870574,-0.487558},
+  {1.078105,0.615241},
+  {-0.212722,-0.339828},
+  {1.044228,-0.140719},
+  {0.507397,-0.046622},
+  {-0.034885,-0.440408},
+  {0.752870,2.271021},
+  {-0.581907,-0.235032},
+  {-0.322662,-0.221511},
+  {0.415694,1.662084},
+  {0.145703,-0.397409},
+  {0.254030,0.000521},
+  {-0.087437,-0.980333},
+  {0.227735,-0.592052},
+  {-1.659078,1.444394},
+  {0.165351,0.893154},
+  {0.143596,-1.051117},
+  {-0.150326,-0.227989},
+  {-0.176142,-2.753715},
+  {-0.304719,-1.679630},
+  {0.142689,1.087978},
+  {-0.017008,-1.616949},
+  {-1.541590,0.163136},
+  {-0.310240,-0.896758},
+  {-1.275426,0.756192},
+  {1.243312,-0.449887},
+  {1.116768,0.875750},
+  {-0.707965,0.070670},
+  {0.913211,-0.140092},
+  {-0.979090,0.451250},
+  {-0.864155,-1.828690},
+  {0.921171,0.476562},
+  {0.355440,0.234661},
+  {-0.524266,0.329766},
+  {-0.358736,-1.603375},
+  {-0.648495,0.757445},
+  {0.418951,0.216528},
+  {-0.427809,-0.403671},
+  {0.337321,-1.387978},
+  {1.655019,-0.215407},
+  {0.451075,-0.095607},
+  {-0.244406,0.146289},
+  {-0.137790,0.167550},
+  {0.630097,0.525331},
+  {1.207748,0.306192},
+  {0.281222,2.135639},
+  {1.263418,-0.404728},
+  {-0.462965,-0.321707},
+  {-0.502160,-0.109373},
+  {0.267206,0.604009},
+  {-0.095540,-0.133320},
+  {-0.518950,-0.011799},
+  {0.882133,-0.870423},
+  {-0.273993,-0.871520},
+  {-0.369624,-0.376413},
+  {-0.426616,-1.054248},
+  {0.605760,-0.041916},
+  {-1.076826,-0.702786},
+  {0.262593,0.312531},
+  {-0.247497,0.678962},
+  {0.286441,-0.227566},
+  {-0.090176,-0.850555},
+  {-0.613904,-0.323067},
+  {-0.479344,0.855193},
+  {0.812688,0.259328},
+  {-0.397216,-0.922578},
+  {0.056809,-0.180688},
+  {-1.371158,0.243855},
+  {-1.014261,0.371907},
+  {0.033020,0.410626},
+  {-0.916478,1.112751},
+  {0.669737,1.082816},
+  {0.431280,-0.142717},
+  {0.497122,-0.690756},
+  {-0.119205,-0.540953},
+  {0.181345,0.682248},
+  {0.031749,-0.632391},
+  {-0.426867,0.192814},
+  {-0.081193,0.403163},
+  {0.211498,1.119102},
+  {-0.832741,-0.389058},
+  {0.687365,0.355030},
+  {0.635475,-0.427351},
+  {-0.546154,-0.025184},
+  {-0.489334,0.302793},
+  {-0.652276,-0.513544},
+  {1.042010,-0.712245},
+  {-1.620305,0.506514},
+  {-0.862786,0.428432},
+  {0.604738,-0.408423},
+  {-0.521311,-0.121360},
+  {0.541474,-1.269409},
+  {-0.497038,0.414833},
+  {-0.241790,-0.086959},
+  {-0.152804,-0.480866},
+  {-0.370062,1.004085},
+  {0.669046,0.066165},
+  {-0.781561,0.108622},
+  {-0.559473,0.168401},
+  {-0.453866,0.541715},
+  {-0.674082,0.794643},
+  {-1.933105,-0.147404},
+  {1.300205,0.575127},
+  {0.347053,1.234056},
+  {0.029991,1.224125},
+  {0.468447,0.084716},
+  {0.172597,-0.493143},
+  {0.474934,0.314407},
+  {-0.641944,-1.460289},
+  {-0.397220,1.519256},
+  {-0.434311,0.720815},
+  {0.309265,0.342057},
+  {-1.198355,-0.052924},
+  {-0.707677,0.641043},
+  {-0.961501,-0.105753},
+  {0.041026,-0.219741},
+  {0.296451,-0.155747},
+  {-0.041502,0.329670},
+  {-0.175649,-1.146940},
+  {0.291242,-0.629172},
+  {0.201876,0.521308},
+  {-1.249795,1.396366},
+  {0.721736,-0.901069},
+  {-0.279288,0.146240},
+  {0.057212,-0.542932},
+  {0.895544,0.168533},
+  {1.243546,0.419985},
+  {1.443173,0.998921},
+  {1.178023,-0.424663},
+  {0.944378,0.694314},
+  {0.077267,-0.557875},
+  {-0.100770,-0.061053},
+  {0.091123,0.783914},
+  {0.627541,-0.406884},
+  {0.300425,0.129705},
+  {1.588361,1.060950},
+  {-0.737907,-0.102440},
+  {-0.408529,-0.967258},
+  {0.409326,-0.583521},
+  {-0.252992,0.274365},
+  {0.467400,0.293939},
+  {0.616506,0.083653},
+  {0.069252,0.630033},
+  {1.261570,-0.161448},
+  {0.980182,0.016625},
+  {-0.967191,0.426424},
+  {0.974353,0.373262},
+  {0.465758,0.406121},
+  {0.049765,0.155789},
+  {1.019360,1.113022},
+  {1.482616,-1.082850},
+  {-0.370055,1.170347},
+  {-0.914180,-0.076800},
+  {0.711749,0.443053},
+  {1.000344,-0.911585},
+  {-0.685291,-0.007084},
+  {0.003534,-1.342957},
+  {-0.224481,-0.897010},
+  {1.435450,1.058341},
+  {0.901816,-1.078478},
+  {0.440206,0.310660},
+  {-0.440452,1.055084},
+  {-0.481999,0.510978},
+  {-0.425880,-0.638269},
+  {-0.887044,0.737327},
+  {0.766324,0.831116},
+  {0.474519,0.013742},
+  {0.719499,0.072296},
+  {0.128751,0.551124},
+  {-0.346348,-0.115964},
+  {-0.027651,-0.597646},
+  {0.459124,0.203102},
+  {0.076236,0.050293},
+  {-1.070625,1.089285},
+  {0.946162,0.643590},
+  {0.493112,-0.908918},
+  {-0.530798,0.636518},
+  {-0.775397,0.649794},
+  {0.666540,-0.670376},
+  {-0.051724,-1.176117},
+  {0.734299,-0.049687},
+  {-0.366040,0.690415},
+  {-0.363912,-0.763731},
+  {0.809317,-0.192377},
+  {-0.584942,-0.575854},
+  {0.212895,0.318501},
+  {-0.229536,-0.564216},
+  {0.325465,-0.148910},
+  {-1.208239,0.149334},
+  {-0.854608,-0.061222},
+  {-1.275009,1.356758},
+  {0.005121,0.384686},
+  {0.540351,-0.968782},
+  {0.522470,0.505677},
+  {1.606856,0.455340},
+  {0.390568,0.183534},
+  {-0.517696,0.031122},
+  {0.301117,2.578628},
+  {-0.301510,-1.216527},
+  {-0.342228,-0.046947},
+  {-0.348194,0.992603},
+  {-0.067880,-0.448626},
+  {1.327164,0.245718},
+  {-0.452255,-1.409662},
+  {0.439151,1.195320},
+  {-1.258445,1.550755},
+  {-0.487881,1.205291},
+  {-0.539438,-0.040513},
+  {0.112800,0.659260},
+  {0.163991,-0.512811},
+  {-0.598902,0.260073},
+  {-0.759021,1.076704},
+  {-0.850034,-0.410968},
+  {0.017091,-0.374513},
+  {-1.673326,0.068799},
+  {0.965866,-0.779812},
+  {-0.058769,-0.720178},
+  {-0.055818,-0.470524},
+  {-1.050913,0.161955},
+  {1.117855,0.191514},
+  {1.104705,0.175696},
+  {0.367485,-0.458936},
+  {0.138570,0.060696},
+  {-0.646029,0.418187},
+  {0.562371,-0.098041},
+  {0.132342,0.156962},
+  {0.616000,0.247797},
+  {-0.849396,-0.017041},
+  {-1.265605,-0.174037},
+  {0.263149,0.173862},
+  {-0.947393,-0.548476},
+  {-0.781072,-1.083780},
+  {0.283519,-1.581446},
+  {-0.649758,0.090980},
+  {0.080903,-0.435490},
+  {-0.546066,-0.445276},
+  {0.883145,0.033681},
+  {-1.438228,-1.592795},
+  {-0.929637,0.644398},
+  {-0.843645,1.001079},
+  {-0.103938,0.314698},
+  {-0.882742,0.603233},
+  {0.560060,0.672982},
+  {0.265318,-0.520901},
+  {0.037542,-0.468269},
+  {-0.614846,-0.896426},
+  {-0.811132,-0.075196},
+  {-0.701491,-0.278436},
+  {-0.169226,0.555609},
+  {0.152666,0.988791},
+  {0.155918,-1.638999},
+  {-0.029867,-0.008556},
+  {0.789905,-0.447722},
+  {0.369189,0.638383},
+  {0.224741,-0.857948},
+  {1.360289,-0.368943},
+  {1.012567,-1.472297},
+  {0.750105,-0.167508},
+  {0.543334,-0.115844},
+  {0.551806,-1.337525},
+  {1.881674,0.384950},
+  {-0.334593,-0.392176},
+  {0.568056,0.658811},
+  {0.826330,-0.070998},
+  {-0.837258,-0.838016},
+  {-0.559858,-1.022418},
+  {0.141410,-0.739586},
+  {-0.910228,-1.581966},
+  {-0.196767,-0.383060},
+  {-1.084272,-0.459566},
+  {-0.639058,0.491458},
+  {0.003765,0.880280},
+  {1.188473,-0.151647},
+  {0.210026,-1.324828},
+  {-0.100415,0.512765},
+  {0.513964,-0.254631},
+  {-0.644200,0.342062},
+  {0.783293,0.003817},
+  {0.641491,0.529011},
+  {0.382460,-0.793553},
+  {-0.168696,0.881504},
+  {-0.665068,-0.411740},
+  {-0.422928,-0.392841},
+  {-0.293466,-0.490343},
+  {0.174657,0.011203},
+  {0.371092,0.692387},
+  {0.221498,0.094331},
+  {1.040101,-0.724797},
+  {-0.594782,-0.235973},
+  {0.067611,-1.262378},
+  {0.159732,-0.070026},
+  {0.643780,-0.804505},
+  {0.537444,0.286446},
+  {0.032259,-0.725526},
+  {-0.348096,1.322484},
+  {-0.412691,-0.682603},
+  {0.064050,-0.147144},
+  {-1.125518,-0.730751},
+  {0.100103,-0.336546},
+  {0.011121,-1.408579},
+  {-0.435174,0.184880},
+  {0.216681,0.145450},
+  {0.160929,-0.027522},
+  {-0.094411,0.775505},
+  {0.917143,-0.930427},
+  {0.346981,0.563719},
+  {-1.570088,-0.176042},
+  {-0.151329,-1.215049},
+  {-0.517596,-0.556149},
+  {1.388624,0.121150},
+  {-1.346197,-0.331584},
+  {-1.014897,-0.904715},
+  {-0.370488,0.625232},
+  {0.234481,-0.599066},
+  {-0.838492,0.445635},
+  {0.570000,0.510314},
+  {-0.117676,0.285231},
+  {1.428193,0.287780},
+  {0.846940,0.133845},
+  {1.197855,0.607831},
+  {-0.882803,-1.383388},
+  {0.034651,-0.574273},
+  {0.081993,-1.106833},
+  {-0.415176,-0.051580},
+  {-0.142726,0.131354},
+  {0.705295,0.285068},
+  {0.616462,0.274167},
+  {0.542851,-0.557143},
+  {-0.453895,1.480666},
+  {0.389829,0.139984},
+  {0.729928,0.418423},
+  {0.199777,0.543327},
+  {-0.777423,-0.121813},
+  {0.544161,1.047456},
+  {0.144618,0.189402},
+  {-0.330806,-0.839508},
+  {-0.386112,0.095356},
+  {0.334664,-0.570556},
+  {0.688800,0.258836},
+  {-0.375194,0.976342},
+  {-0.979181,0.389248},
+  {0.352754,0.182541},
+  {-0.557678,0.183718},
+  {0.059676,-0.515850},
+  {0.889687,0.384437},
+  {0.326761,-0.569045},
+  {-0.356064,0.960982},
+  {-0.015646,0.537468},
+  {0.070428,-0.848307},
+  {-0.986289,0.860168},
+  {-0.141119,0.141116},
+  {0.387450,1.352744},
+  {0.898063,0.207277},
+  {0.307952,0.280249},
+  {-1.091253,-0.645560},
+  {1.079365,0.448420},
+  {0.318470,-0.047758},
+  {-0.664574,0.564786},
+  {-0.568208,0.492372},
+  {0.143767,0.051228},
+  {-0.416511,0.722973},
+  {-0.892012,-0.308575},
+  {0.361998,-0.008642},
+  {-0.497223,-0.648014},
+  {0.249791,-0.081327},
+  {0.207192,0.128874},
+  {-1.025766,-0.510293},
+  {0.098964,0.621213},
+  {-0.490461,0.631713},
+  {-0.448633,1.805053},
+  {-0.321075,-0.425673},
+  {0.109959,0.748809},
+  {-0.636473,0.818729},
+  {-0.323787,-0.565485},
+  {-0.031436,0.886588},
+  {-1.100856,-0.295367},
+  {0.013026,1.275442},
+  {1.243183,-0.863036},
+  {-0.016862,-1.104960},
+  {-0.503751,0.059092},
+  {-0.428264,-1.092108},
+  {0.240446,0.733125},
+  {-0.924166,-0.286675},
+  {0.081255,0.268827},
+  {0.578614,0.267076},
+  {0.855698,0.686772},
+  {0.694556,0.169285},
+  {0.065727,-1.138257},
+  {-1.326172,-0.634456},
+  {-0.290709,0.244074},
+  {0.184962,-0.684550},
+  {-0.484932,-0.874069},
+  {0.683665,-1.045173},
+  {-0.583586,0.853352},
+  {-0.817727,-1.045137},
+  {-0.661010,-1.251055},
+  {-0.369424,0.527159},
+  {-1.301217,0.246717},
+  {0.143446,0.006156},
+  {-0.073755,0.534466},
+  {-1.136401,-0.589760},
+  {-0.607309,-0.316112},
+  {0.335294,-0.448585},
+  {-0.574601,0.205810},
+  {-0.239630,0.283724},
+  {-0.697449,-0.307286},
+  {0.071816,0.155103},
+  {1.367617,-1.141154},
+  {-0.396951,-0.248389},
+  {-1.092599,-0.617174},
+  {-1.294691,-0.226609},
+  {-0.380847,-0.089574},
+  {-0.743203,0.637321},
+  {0.235272,-0.819851},
+  {-1.195970,0.512104},
+  {-1.679973,-0.738527},
+  {0.575380,-0.899765},
+  {-1.649001,-0.199959},
+  {0.213428,1.358885},
+  {0.943931,-0.471162},
+  {0.432717,0.866101},
+  {0.145445,0.133728},
+  {-0.555018,0.149227},
+  {-0.914787,0.598720},
+  {-0.653930,-0.654901},
+  {-1.346925,0.329945},
+  {-0.171424,-0.565344},
+  {-0.301527,0.240508},
+  {1.273836,-0.145758},
+  {-0.675821,-1.095405},
+  {-0.413545,-0.143713},
+  {-0.106844,0.824615},
+  {0.131452,-1.038036},
+  {-0.326685,1.463916},
+  {-0.584519,-0.458745},
+  {-0.543369,-1.094143},
+  {0.143483,-0.846585},
+  {0.272163,0.167407},
+  {0.401943,-0.563082},
+  {1.212306,0.087879},
+  {0.504145,-0.648031},
+  {-0.462351,-0.159423},
+  {-0.319523,0.179709},
+  {1.357242,0.045627},
+  {1.074160,0.840235},
+  {0.790452,0.720079},
+  {-0.705431,0.410349},
+  {0.416680,-0.002549},
+  {-0.884954,-0.146867},
+  {-0.808279,-0.171336},
+  {-1.018281,0.721639},
+  {0.822228,1.039615},
+  {1.037790,0.060549},
+  {-0.074556,-0.200271},
+  {-0.880853,-0.366553},
+  {-0.343761,0.333341},
+  {-0.313231,-0.586011},
+  {0.283823,0.573617},
+  {1.143016,0.089887},
+  {0.410687,1.083689},
+  {0.277861,-0.083366},
+  {0.021606,-0.194773},
+  {-0.750214,1.458612},
+  {0.917402,-0.016748},
+  {-0.339684,-0.337568},
+  {1.005284,-0.645882},
+  {-0.519209,0.899330},
+  {0.826162,-0.741211},
+  {1.300132,-1.109551},
+  {-0.374995,-0.317730},
+  {0.785101,0.228184},
+  {0.415868,0.737788},
+  {0.527210,-0.188643},
+  {0.376705,0.413658},
+  {0.989599,0.805633},
+  {-0.137061,-0.915614},
+  {-1.702346,-0.057933},
+  {-1.956591,0.046432},
+  {-0.416960,0.338240},
+  {-0.658461,-1.216968},
+  {0.365795,0.659371},
+  {0.252050,-0.558653},
+  {-0.454467,0.004934},
+  {0.504714,0.229244},
+  {-0.278911,-0.228103},
+  {-0.127623,-0.114296},
+  {-0.014266,-0.342689},
+  {-0.604625,0.121864},
+  {-0.387685,-0.068082},
+  {-0.091712,0.800537},
+  {0.485931,-0.161304},
+  {-0.016110,0.493620},
+  {-0.653134,-0.353877},
+  {-1.046778,0.196967},
+  {-0.263242,-0.289129},
+  {0.336474,-0.180203},
+  {0.298396,-0.644825},
+  {-0.427587,0.572250},
+  {-0.208223,0.053185},
+  {0.533386,-1.227956},
+  {-0.725350,0.128195},
+  {0.672904,0.530250},
+  {-0.061316,-0.194678},
+  {-0.709433,-0.046001},
+  {-0.588879,0.353459},
+  {0.123260,0.618527},
+  {-0.549665,0.060101},
+  {0.890191,-0.845135},
+  {-0.454263,-1.313850},
+  {0.783957,-0.491876},
+  {1.361276,0.023611},
+  {-0.458428,0.042147},
+  {-0.143219,-0.073745},
+  {0.074903,-0.017429},
+  {-0.067903,-0.816547},
+  {-0.380387,-0.772921},
+  {-0.240030,1.420491},
+  {-0.003621,0.010600},
+  {-0.444036,0.409901},
+  {0.277409,0.726745},
+  {0.119726,1.707099},
+  {-0.621712,-0.457125},
+  {-0.214421,1.545744},
+  {0.278621,-0.735467},
+  {-0.099482,0.119682},
+  {0.952647,-1.013460},
+  {-0.290825,-0.041022},
+  {0.368084,-0.002760},
+  {-0.689006,-0.068005},
+  {0.015785,0.505867},
+  {1.306051,0.203435},
+  {-0.263603,-0.214893},
+  {0.292584,-0.248845},
+  {-0.344389,-1.191472},
+  {0.096606,-0.045469},
+  {0.147219,0.465939},
+  {-0.579923,-1.133735},
+  {-0.918253,-0.931145},
+  {0.557217,0.127417},
+  {0.614199,0.613104},
+  {0.412233,0.943510},
+  {-0.471662,-0.514960},
+  {-0.817375,-0.836164},
+  {-0.264718,-0.546935},
+  {0.508435,0.771316},
+  {0.031847,-1.856060},
+  {-0.443846,-0.260004},
+  {-0.716667,-1.374211},
+  {0.501604,0.548927},
+  {0.314912,1.032581},
+  {-0.781109,0.916868},
+  {-0.869837,-1.039860},
+  {0.630546,0.674600},
+  {0.272632,0.214175},
+  {0.531070,0.330978},
+  {0.675056,-0.653400},
+  {0.573720,0.836919},
+  {-0.611225,0.014075},
+  {-0.257263,-0.391545},
+  {-0.759020,-0.312859},
+  {0.264351,0.791373},
+  {-0.438730,-0.456151},
+  {-0.103243,-0.632429},
+  {0.482892,0.141475},
+  {-1.072978,0.148871},
+  {-0.939209,-0.558985},
+  {0.464793,-0.984782},
+  {0.344131,0.564869},
+  {1.005227,-0.360487},
+  {-0.225080,0.071180},
+  {0.208733,-0.458590},
+  {0.680123,-1.202615},
+  {-0.308920,0.517768},
+  {0.980274,0.589646},
+  {0.902236,-0.040233},
+  {-1.138100,0.039754},
+  {0.169840,0.120056},
+  {-0.733937,0.211810},
+  {0.623660,-0.836100},
+  {-0.173754,0.076214},
+  {-0.541470,0.864952},
+  {-0.080678,-0.163713},
+  {-0.044093,0.109390},
+  {-0.028695,-0.639742},
+  {0.643003,0.482195},
+  {-0.364304,-0.293403},
+  {-0.231682,-0.410161},
+  {-0.467438,-0.345931},
+  {-0.390529,0.236207},
+  {-0.175126,0.380258},
+  {0.978393,0.640634},
+  {0.257795,-0.903357},
+  {0.641261,0.315085},
+  {-0.098354,0.511919},
+  {-0.717823,-0.919712},
+  {0.709709,-0.590981},
+  {0.997767,0.207366},
+  {0.588275,-0.122289},
+  {-0.222499,0.042538},
+  {0.394217,0.054417},
+  {0.214881,0.114854},
+  {0.596482,0.581786},
+  {0.477025,-0.157396},
+  {-0.633506,-1.318668},
+  {-0.037122,0.440028},
+  {0.968742,-0.275315},
+  {-0.513770,0.381195},
+  {1.098776,0.728930},
+  {0.150417,-0.421163},
+  {-0.902237,1.142415},
+  {-0.729498,0.499136},
+  {0.418742,0.861949},
+  {0.267916,-0.737845},
+  {0.024422,0.770033},
+  {0.566193,0.531592},
+  {0.166300,-0.113780},
+  {-0.275348,-0.044917},
+  {0.629763,-0.044562},
+  {0.108581,-0.580329},
+  {0.247883,-0.494344},
+  {-1.462176,0.531806},
+  {0.324773,-1.258865},
+  {-0.406431,0.059552},
+  {0.113265,0.337107},
+  {-0.506166,1.040579},
+  {-0.703153,0.839870},
+  {-0.260571,-1.535683},
+  {-0.454874,-0.041822},
+  {-0.199992,-0.302883},
+  {-0.743083,-0.906848},
+  {-0.675013,-0.597745},
+  {-0.338081,-1.521178},
+  {0.931345,-1.090509},
+  {0.651153,-1.330153},
+  {-1.079088,0.315838},
+  {0.246740,0.044863},
+  {0.202616,1.446147},
+  {-0.433066,0.284324},
+  {-0.609858,0.344346},
+  {1.142330,-0.944550},
+  {-0.350428,-0.881955},
+  {-0.451507,-1.605877},
+  {-0.400012,-0.239471},
+  {-0.136838,-0.775874},
+  {0.282265,-0.413392},
+  {-0.988833,1.529659},
+  {0.719835,0.005099},
+  {0.052020,-0.477086},
+  {-1.283307,0.058599},
+  {0.165701,0.649111},
+  {1.021960,-1.416111},
+  {0.940476,0.062629},
+  {-0.751199,0.038566},
+  {0.243450,-0.762697},
+  {-0.649152,0.044560},
+  {0.908395,0.209002},
+  {0.325158,0.216998},
+  {0.396454,0.138658},
+  {-0.763522,-0.025907},
+  {-0.762589,-0.137472},
+  {-0.327529,-1.036809},
+  {-0.632504,0.676907},
+  {0.183574,0.389227},
+  {-0.859700,-0.703806},
+  {-1.154826,-0.991693},
+  {0.449444,0.396030},
+  {0.441770,0.491508},
+  {-1.205186,0.299378},
+  {1.050428,-0.456205},
+  {0.096725,0.154959},
+  {0.584349,-0.864514},
+  {-1.679030,1.143489},
+  {0.008505,0.228789},
+  {-0.661763,0.775812},
+  {0.142798,-0.623065},
+  {-0.241421,-0.526502},
+  {1.106520,0.156370},
+  {0.365753,-0.256303},
+  {-0.977046,1.118332},
+  {0.884009,0.203437},
+  {-0.353712,0.852741},
+  {1.135822,-0.309740},
+  {-0.439555,-0.067368},
+  {0.554689,-0.288402},
+  {1.734416,1.344531},
+  {-1.349819,0.759427},
+  {0.102799,-0.495112},
+  {0.063102,0.722775},
+  {-1.222947,-0.080150},
+  {-0.340332,1.061612},
+  {-0.228259,-1.903851},
+  {-0.090773,0.687378},
+  {0.203348,0.507128},
+  {-0.577364,-0.212706},
+  {-0.857515,-0.853969},
+  {-0.562304,0.383151},
+  {-0.918214,-1.478510},
+  {1.026666,0.071216},
+  {-0.012886,-0.308529},
+  {0.022988,-0.145717},
+  {0.234582,1.146633},
+  {1.975283,-0.173765},
+  {-1.487083,0.919537},
+  {-1.203767,1.128685},
+  {-1.355804,-0.425852},
+  {-0.102354,-1.008553},
+  {-0.436827,0.374401},
+  {-1.741085,0.223597},
+  {-0.898223,0.399684},
+  {0.002133,-0.652951},
+  {0.333743,0.185220},
+  {-0.163247,1.355073},
+  {-0.198911,-0.789921},
+  {0.240101,0.133008},
+  {-0.149245,-0.404471},
+  {1.281203,-0.360689},
+  {-0.172603,-0.635725},
+  {0.286292,-0.148272},
+  {-0.989616,0.037128},
+  {-0.811488,1.305276},
+  {0.736930,-1.009141},
+  {1.069361,-0.737178},
+  {0.752787,-0.592366},
+  {-0.668359,0.755571},
+  {0.005078,-0.395512},
+  {0.006600,0.636287},
+  {-0.619231,-0.611731},
+  {0.333470,-0.919963},
+  {-0.492449,-1.419036},
+  {-0.622632,0.194757},
+  {0.676292,1.819990},
+  {-0.328240,0.542470},
+  {0.345128,-0.019528},
+  {-0.616645,0.691087},
+  {-0.507449,-0.432094},
+  {-0.204852,-0.217874},
+  {0.834005,-0.099980},
+  {1.199202,-0.293367},
+  {0.449203,-0.521362},
+  {0.226780,-0.171567},
+  {0.523436,0.775392},
+  {-0.711218,-0.421231},
+  {0.151391,-1.096606},
+  {-0.249307,0.995733},
+  {0.245582,-0.339674},
+  {0.412624,-0.060258},
+  {-0.300827,0.023954},
+  {-0.265459,0.720401},
+  {-0.496526,-2.099281},
+  {-0.605097,-0.001741},
+  {-1.378320,-0.341276},
+  {-0.994346,0.085029},
+  {1.632400,0.360458},
+  {-0.491899,-0.396243},
+  {-0.010321,-1.021544},
+  {-1.316304,0.895828},
+  {-0.198830,-0.208983},
+  {0.916044,0.314340},
+  {0.562103,-0.885413},
+  {0.878424,-0.092960},
+  {-1.045844,-0.687749},
+  {-1.295066,-0.226382},
+  {-0.359215,0.110638},
+  {0.540396,-0.456394},
+  {1.030585,0.127512},
+  {-0.085532,0.952881},
+  {0.106917,0.478915},
+  {-0.664272,-0.344642},
+  {0.788052,1.409984},
+  {-0.673592,1.430835},
+  {-0.718720,-0.290875},
+  {-0.721900,0.085461},
+  {0.476120,-0.538352},
+  {0.554070,0.581590},
+  {-0.576287,-0.853427},
+  {-0.431295,-0.014809},
+  {-2.353094,1.312785},
+  {1.022447,1.017332},
+  {0.418273,2.001674},
+  {-0.898325,0.139499},
+  {0.235885,0.080549},
+  {0.183877,0.730680},
+  {1.009956,0.519400},
+  {-0.689154,0.060848},
+  {-0.683728,-0.649710},
+  {0.079095,0.516578},
+  {-1.386436,-0.530334},
+  {0.302774,-0.053089},
+  {-0.248980,0.192447},
+  {-0.680767,0.423570},
+  {-0.043439,0.510224},
+  {-1.016935,0.183362},
+  {0.076796,-1.333739},
+  {-0.313256,-1.452270},
+  {-0.850463,0.112410},
+  {0.244360,-0.084178},
+  {0.067792,-0.882987},
+  {-0.569372,-0.399011},
+  {-0.189225,0.729525},
+  {-0.588975,-0.077969},
+  {1.010968,-0.489609},
+  {-0.395063,0.239897},
+  {0.025387,0.354833},
+  {0.725579,0.805842},
+  {-1.146500,-0.264508},
+  {-0.222810,-1.814964},
+  {0.507912,-1.443934},
+  {0.296149,0.880303},
+  {-0.439268,1.606203},
+  {0.334727,0.325640},
+  {-0.869431,-0.847762},
+  {-0.407707,0.153088},
+  {0.348556,0.542411},
+  {-0.082133,0.838110},
+  {-0.377740,0.348750},
+  {-0.523685,0.000306},
+  {0.451224,1.080533},
+  {0.864641,0.961894},
+  {-0.464419,-0.075393},
+  {0.247437,-0.100790},
+  {0.677059,-0.034906},
+  {0.977166,0.730818},
+  {0.276546,-0.403567},
+  {-0.380227,-0.745522},
+  {-0.300027,0.125790},
+  {0.454573,0.006509},
+  {-0.771309,0.081517},
+  {-0.311846,-0.412134},
+  {-0.014595,0.090009},
+  {0.707382,-0.074778},
+  {-1.353019,-0.753631},
+  {-0.100071,0.822131},
+  {0.954790,-0.432571},
+  {-0.078897,-0.647015},
+  {0.386041,-0.035061},
+  {0.448108,0.197019},
+  {-0.270952,0.887823},
+  {0.648405,-1.073664},
+  {0.044912,-0.754380},
+  {-0.455401,-1.209139},
+  {-1.242109,0.132042},
+  {0.391696,-0.419274},
+  {-0.160193,-1.086374},
+  {0.193327,0.720599},
+  {1.178831,-0.759304},
+  {-0.564605,1.076430},
+  {-0.643302,-0.416708},
+  {-0.962134,-0.990827},
+  {0.368858,-0.144279},
+  {0.036509,-0.440959},
+  {0.179113,0.270476},
+  {0.049637,-0.799549},
+  {0.618109,-0.582336},
+  {-1.394815,0.395536},
+  {0.810724,-0.184896},
+  {-0.176056,-0.058013},
+  {-0.488312,-0.368066},
+  {-0.080337,-0.440737},
+  {0.116364,0.953468},
+  {-0.307639,-0.302137},
+  {0.341945,0.164106},
+  {-0.466698,-1.158425},
+  {0.052765,-0.344994},
+  {-0.107626,-0.229995},
+  {0.080011,0.653158},
+  {-0.438442,0.465432},
+  {1.422075,-0.608592},
+  {0.108080,-1.057456},
+  {-0.484339,-0.907178},
+  {-0.746907,-1.978396},
+  {-0.177762,0.203051},
+  {0.386845,-1.106388},
+  {0.611978,-1.018232},
+  {0.520887,-0.361754},
+  {-0.360101,-0.064618},
+  {0.794305,0.526908},
+  {0.619432,-0.126033},
+  {-0.340265,-1.373028},
+  {0.847319,1.149398},
+  {-0.270491,-0.369213},
+  {-1.409881,0.523044},
+  {-0.402942,0.347133},
+  {0.100939,-0.350152},
+  {-0.107951,-0.680471},
+  {0.436856,-0.753223},
+  {-0.874005,0.762825},
+  {1.008767,-0.929545},
+  {0.927536,-0.502055},
+  {1.498450,-0.602521},
+  {0.762959,-0.278194},
+  {-1.522717,-0.649417},
+  {0.994833,-0.186581},
+  {0.216919,0.567066},
+  {0.850492,-0.682931},
+  {-0.777097,-0.903028},
+  {-0.850634,-0.188701},
+  {0.044620,1.541080},
+  {-0.307342,-0.202304},
+  {-1.090498,-0.818833},
+  {-0.004279,0.647200},
+  {-0.290596,0.500608},
+  {-0.009800,-0.272120},
+  {-1.731344,-0.849070},
+  {-0.389416,-0.540169},
+  {1.177543,0.747062},
+  {-0.858150,-0.456143},
+  {0.973307,1.377374},
+  {1.032589,0.695827},
+  {0.015056,0.450971},
+  {-0.934915,-0.677001},
+  {0.342935,0.069114},
+  {0.145474,-0.791543},
+  {1.997462,-0.362196},
+  {-0.993218,-0.020078},
+  {1.123258,-0.113204},
+  {0.125841,1.008802},
+  {0.727876,1.066038},
+  {-0.224529,0.890501},
+  {0.213441,1.187995},
+  {0.239012,-0.848701},
+  {-0.519815,-0.475935},
+  {0.113620,-0.506924},
+  {0.203290,-0.296634},
+  {-0.290231,-0.514121},
+  {0.218741,1.021963},
+  {-1.315299,0.334324},
+  {-0.936988,0.419998},
+  {0.886813,0.145840},
+  {-0.188194,-1.261272},
+  {0.949296,0.646163},
+  {-0.826651,-0.432253},
+  {0.061005,0.573649},
+  {0.922200,-1.334003},
+  {-0.006091,0.134091},
+  {1.024516,0.063476},
+  {-0.089739,-0.290697},
+  {0.339610,0.989953},
+  {0.555781,-1.426528},
+  {-0.025669,-0.189457},
+  {-0.710042,0.953935},
+  {-1.262187,0.132588},
+  {0.658343,-0.530960},
+  {0.676713,-0.669361},
+  {0.834718,-2.007914},
+  {0.833518,0.359230},
+  {0.649170,-0.687822},
+  {-0.001830,-0.386894},
+  {0.994915,-0.229340},
+  {0.092444,0.399221},
+  {0.536323,-0.782432},
+  {0.262010,1.204889},
+  {-0.208387,0.425622},
+  {-1.100914,1.683131},
+  {-1.658393,-0.775979},
+  {-0.078725,-0.220114},
+  {-0.303566,0.923927},
+  {-0.225885,0.033406},
+  {-0.837593,0.349616},
+  {-0.560227,0.714755},
+  {0.551992,-0.393791},
+  {0.541405,-0.530435},
+  {-1.165526,0.078792},
+  {-1.026038,0.387096},
+  {-0.517090,-0.484350},
+  {0.136127,0.124638},
+  {0.698761,0.346848},
+  {-0.783071,0.074379},
+  {0.158195,1.117125},
+  {0.712435,-0.286792},
+  {-0.362540,-1.001977},
+  {-0.261314,1.161940},
+  {1.007828,0.544864},
+  {0.141605,0.538099},
+  {-0.536036,-0.744530},
+  {-0.056455,1.157725},
+  {0.270982,-0.362836},
+  {1.263497,0.040674},
+  {0.146764,-0.753269},
+  {0.364839,0.210494},
+  {0.142940,0.490340},
+  {0.272361,0.068047},
+  {-1.040589,1.260799},
+  {1.008508,0.670697},
+  {-1.014574,2.123840},
+  {-0.791800,-1.531609},
+  {-1.780964,0.224965},
+  {1.573411,0.802257},
+  {-0.041381,0.109724},
+  {-1.138676,0.501035},
+  {-0.552511,0.754384},
+  {0.074825,-0.740712},
+  {0.310992,-0.947818},
+  {-0.161513,1.611466},
+  {0.351436,-0.213846},
+  {-0.232344,0.926067},
+  {-0.712473,0.154074},
+  {0.531308,0.239847},
+  {0.530134,0.456501},
+  {-0.297722,-0.791948},
+  {-0.072871,-1.399393},
+  {0.183656,0.497474},
+  {-0.279718,-0.393118},
+  {0.648989,-0.820860},
+  {0.372595,-1.044493},
+  {1.032547,0.849237},
+  {1.174671,-0.618382},
+  {-1.652857,-1.472496},
+  {0.158852,0.191819},
+  {0.298620,0.279073},
+  {-0.234746,-0.135384},
+  {-0.875820,0.319486},
+  {-0.426039,0.843713},
+  {-0.496797,-0.192881},
+  {-0.578836,0.257663},
+  {-0.238402,0.900325},
+  {-0.204088,-1.191861},
+  {0.736090,1.052130},
+  {-0.052316,-0.025508},
+  {-0.213198,-0.936710},
+  {-0.491398,0.410943},
+  {0.177843,0.351607},
+  {0.413028,-0.384109},
+  {-0.296570,0.034297},
+  {-0.222102,0.514522},
+  {0.347397,-0.839739},
+  {0.755191,0.119118},
+  {-1.317696,1.106367},
+  {0.012111,0.796336},
+  {0.227983,0.378704},
+  {-0.182946,0.270691},
+  {-0.133785,0.099382},
+  {-0.266511,0.038997},
+  {-0.821681,0.553035},
+  {0.389307,-1.106532},
+  {0.135254,-0.883464},
+  {1.870178,-0.286558},
+  {-0.437784,-0.288228},
+  {0.390194,0.094215},
+  {0.606508,-1.296029},
+  {-0.093019,-0.614305},
+  {1.233362,1.207790},
+  {0.161323,-0.765341},
+  {-0.350088,1.001790},
+  {-0.502004,-0.037202},
+  {-0.067642,-0.030906},
+  {-0.579459,-0.835251},
+  {-0.327448,-1.330617},
+  {-0.822818,-0.500291},
+  {1.616254,-0.161664},
+  {0.523254,0.304197},
+  {0.874754,0.727626},
+  {-0.625833,0.211643},
+  {-0.295817,-0.417120},
+  {-0.533891,0.548556},
+  {-0.558758,0.571516},
+  {0.822203,0.414686},
+  {1.369430,0.325986},
+  {1.064004,0.174272},
+  {-0.985833,0.875381},
+  {-0.345980,0.354199},
+  {0.100855,1.346421},
+  {1.413487,-0.299202},
+  {-0.121055,-1.168458},
+  {0.501534,-0.001734},
+  {-0.099610,0.124655},
+  {-0.014849,-0.560165},
+  {1.152084,0.973772},
+  {-0.517379,-0.823509},
+  {0.020539,-0.675177},
+  {-0.039182,0.878191},
+  {0.067950,0.560550},
+  {-1.394269,0.829335},
+  {-0.441627,-0.010153},
+  {0.385140,0.222085},
+  {0.653992,-0.840685},
+  {0.554082,-0.687828},
+  {0.754380,-0.171576},
+  {0.690489,-0.152949},
+  {0.000351,-0.549264},
+  {0.634582,-0.004171},
+  {-0.818523,1.190795},
+  {-0.877491,-0.566566},
+  {-1.770940,-0.640230},
+  {-0.681648,0.896819},
+  {0.714653,-1.455870},
+  {0.904495,-1.333302},
+  {0.574457,-0.384864},
+  {-0.758292,-0.483590},
+  {0.187676,0.405114},
+  {0.994700,-0.071836},
+  {0.104159,0.532615},
+  {-0.044879,-0.582247},
+  {0.088417,0.343948},
+  {-0.123630,-0.413369},
+  {-0.520220,1.012739},
+  {-0.210080,-0.180696},
+  {1.090599,-0.559357},
+  {0.684438,0.378806},
+  {-0.026784,0.937192},
+  {1.281961,0.075214},
+  {0.730268,-0.520097},
+  {0.937449,-1.019487},
+  {-0.061509,-0.176202},
+  {-0.421825,0.313385},
+  {-0.367561,0.463862},
+  {-0.121494,-0.479397},
+  {0.550684,-0.312000},
+  {-0.047790,-0.598700},
+  {-0.759626,-0.857538},
+  {0.464120,-0.230825},
+  {0.787116,-0.630031},
+  {-0.508880,0.581898},
+  {-0.454863,0.576846},
+  {-0.207468,1.946940},
+  {-0.913960,-0.235153},
+  {1.143211,0.111025},
+  {-0.137003,0.162749},
+  {-1.146435,1.853002},
+  {-0.318815,-0.421180},
+  {-0.260398,-0.035725},
+  {0.175171,-0.048527},
+  {-0.261859,0.350284},
+  {0.162278,-0.033220},
+  {-0.592133,-0.719742},
+  {1.618602,0.334038},
+  {-0.096548,-0.880363},
+  {-0.348537,0.448118},
+  {-0.662260,0.179356},
+  {1.039235,0.256463},
+  {-0.996895,0.746454},
+  {-0.834224,-0.090841},
+  {-0.647685,-0.812629},
+  {-1.308253,0.412350},
+  {-0.125295,-0.126640},
+  {0.576406,-0.583028},
+  {-0.374377,-0.094747},
+  {0.533871,-0.080927},
+  {0.515122,-1.155921},
+  {-0.507165,0.282523},
+  {-0.699975,1.619406},
+  {0.182354,-0.753123},
+  {0.710919,-0.243223},
+  {1.477830,-0.025138},
+  {1.782881,0.259661},
+  {-0.521191,0.411698},
+  {-0.166741,0.852319},
+  {0.207224,-0.159255},
+  {-0.487196,1.583805},
+  {0.420298,-0.587703},
+  {-0.287136,0.347728},
+  {-0.058681,-1.279535},
+  {-0.213399,-0.886647},
+  {-1.030968,0.343184},
+  {0.028405,-0.952633},
+  {0.464603,0.442204},
+  {0.931560,0.453043},
+  {0.284575,0.967136},
+  {0.138022,0.059599},
+  {-0.451299,-1.015639},
+  {1.003979,1.068919},
+  {-0.655263,-0.663366},
+  {-0.019621,-0.138225},
+  {0.156525,-0.341867},
+  {0.381232,0.059268},
+  {-0.023279,-0.077880},
+  {-0.156909,0.250573},
+  {-0.169278,-0.914286},
+  {0.305569,-0.291525},
+  {0.731565,0.454905},
+  {1.160261,0.085413},
+  {-0.402037,-0.336640},
+  {-0.086852,1.607379},
+  {1.032812,0.761434},
+  {-1.011438,0.206404},
+  {-0.152752,0.593129},
+  {0.239131,-0.087052},
+  {0.808812,-0.541022},
+  {-0.140430,-1.364158},
+  {0.194295,0.880644},
+  {0.118366,0.064148},
+  {-0.536040,0.778541},
+  {-0.720747,0.002512},
+  {0.088296,-1.191485},
+  {0.644848,-0.444607},
+  {0.485903,0.409511},
+  {1.460176,-0.876221},
+  {-0.339190,-0.439055},
+  {0.447675,0.418898},
+  {-1.175829,-0.902773},
+  {0.534399,0.539156},
+  {-0.365101,-0.459903},
+  {-0.889603,-0.728754},
+  {-0.720091,0.356776},
+  {0.152954,0.223066},
+  {1.507327,0.739365},
+  {0.310249,-0.006371},
+  {-0.112344,-0.419108},
+  {0.843904,-0.314723},
+  {0.087930,0.313616},
+  {0.844712,0.196815},
+  {0.375568,0.356237},
+  {0.204981,-0.400083},
+  {0.361654,-0.270180},
+  {-0.424588,-0.363919},
+  {-0.302380,0.390982},
+  {0.538019,-0.362291},
+  {-0.287025,0.105711},
+  {-0.592141,-0.264936},
+  {-0.265425,0.583077},
+  {-0.152032,0.522918},
+  {-0.189186,-0.250399},
+  {-1.096465,0.469056},
+  {-0.888549,-1.140952},
+  {-0.501972,-0.339613},
+  {-0.203446,0.426474},
+  {-0.039456,-0.535356},
+  {0.070475,0.484328},
+  {0.924276,-0.396241},
+  {-0.106967,0.012352},
+  {-0.367264,0.819153},
+  {0.456802,0.237844},
+  {0.563188,-1.024814},
+  {0.009682,-0.064482},
+  {-0.764852,0.219713},
+  {-0.414932,-0.531342},
+  {-0.088775,-0.892699},
+  {-0.473699,0.186136},
+  {-0.776648,-0.582610},
+  {0.175734,-1.058049},
+  {1.285690,-0.391957},
+  {-0.091057,-1.011907},
+  {-0.162767,0.561617},
+  {0.031953,-0.540131},
+  {0.534081,0.664403},
+  {-0.360770,0.122694},
+  {-0.178962,0.466559},
+  {-0.004184,-0.337578},
+  {-0.757067,0.029093},
+  {-1.101300,0.209913},
+  {0.465322,-0.086027},
+  {-0.168690,1.115947},
+  {0.263414,-0.000775},
+  {0.159567,0.853760},
+  {0.094110,-0.060344},
+  {-0.421000,-1.195796},
+  {0.441781,0.242496},
+  {-0.021002,-0.381271},
+  {-0.481126,-0.563097},
+  {-0.798248,-0.508280},
+  {-0.268196,0.934724},
+  {1.292721,-0.335166},
+  {0.226534,0.445048},
+  {1.184933,0.558462},
+  {0.375495,-1.145480},
+  {0.748214,-0.745104},
+  {0.688162,1.047310},
+  {0.637883,0.949140},
+  {-0.578133,-0.371881},
+  {-0.506057,0.137040},
+  {-0.392437,-1.031430},
+  {-1.250713,-1.946813},
+  {-0.206704,1.462894},
+  {0.398430,-0.219612},
+  {0.730672,-0.702692},
+  {-0.698928,-0.450961},
+  {0.584867,-0.708127},
+  {0.590944,-0.109226},
+  {-0.542510,0.253958},
+  {-0.268875,1.111628},
+  {0.649546,-0.696286},
+  {-1.149829,-0.309965},
+  {-0.154368,-1.500089},
+  {0.822416,0.353288},
+  {0.501110,-0.318761},
+  {-0.212429,-0.008096},
+  {-0.006164,-0.123611},
+  {0.288868,0.048345},
+  {-0.574713,-0.524916},
+  {0.018293,-1.030497},
+  {-0.005055,-0.072736},
+  {0.723568,-0.635163},
+  {0.237863,-0.875191},
+  {-1.247980,-0.863139},
+  {-0.302079,-0.212290},
+  {-0.421802,-0.759025},
+  {-0.589974,-0.507471},
+  {-0.334862,0.003375},
+  {0.401797,0.706722},
+  {-0.461749,0.283630},
+  {-0.841187,-0.665548},
+  {-0.626371,0.618334},
+  {-0.020821,0.503040},
+  {0.116914,-0.093341},
+  {-0.151675,-0.528033},
+  {-0.193343,-1.099319},
+  {0.274029,0.445690},
+  {-0.021446,-1.220103},
+  {0.513206,-0.740022},
+  {1.777028,0.407704},
+  {0.786759,0.109353},
+  {-1.004914,0.876901},
+  {0.464743,1.170006},
+  {-0.002439,0.125068},
+  {0.962875,-0.407956},
+  {0.530559,-0.756573},
+  {-0.389738,0.110620},
+  {-0.556624,0.014509},
+  {-0.132983,0.247574},
+  {0.587943,-0.342146},
+  {1.296368,0.197680},
+  {-0.733120,-0.623643},
+  {-0.011093,0.978888},
+  {0.039641,-0.978184},
+  {-0.443314,-0.153156},
+  {0.588043,0.490341},
+  {0.218709,0.363791},
+  {-0.914626,0.826702},
+  {1.411108,-0.816719},
+  {-0.490262,-0.144227},
+  {-1.206037,1.156620},
+  {-0.662082,0.479091},
+  {0.615883,-0.149877},
+  {1.177829,-0.036366},
+  {0.394260,-1.578483},
+  {0.383648,0.485998},
+  {-0.028002,0.334074},
+  {0.722762,0.190366},
+  {0.475814,0.082245},
+  {0.439991,-0.022567},
+  {0.014753,0.128088},
+  {-1.144640,-0.335474},
+  {0.470690,0.257257},
+  {-0.751319,-1.107300},
+  {0.531539,0.456327},
+  {0.464679,0.083408},
+  {0.077604,-2.053833},
+  {-0.031526,-0.401000},
+  {-0.741780,-0.921745},
+  {-0.504616,-1.015580},
+  {0.999344,-0.252633},
+  {0.199592,-0.614304},
+  {-1.630268,-0.100880},
+  {-0.754618,-0.275004},
+  {-1.115735,-0.519031},
+  {-0.156714,-0.646913},
+  {-0.315061,0.123277},
+  {-0.414084,-0.655534},
+  {0.469319,-0.330941},
+  {0.647004,-0.163404},
+  {-0.255922,1.618105},
+  {-1.376396,-0.535470},
+  {1.334960,-0.249415},
+  {-0.920735,-0.189727},
+  {2.380895,-0.939174},
+  {-0.661720,0.252740},
+  {1.948294,-0.096848},
+  {-1.518951,-0.774151},
+  {0.370676,-0.131442},
+  {0.135880,0.077151},
+  {-0.793921,0.407360},
+  {0.434706,0.909590},
+  {-0.892096,0.523341},
+  {-0.077199,0.691331},
+  {-0.703000,0.726934},
+  {-0.793375,-0.399673},
+  {0.170385,-0.177280},
+  {0.497139,0.034646},
+  {-0.972295,1.093025},
+  {-0.260981,-0.434597},
+  {0.295369,0.422417},
+  {0.508523,0.711213},
+  {-0.589540,0.610066},
+  {0.089695,0.577849},
+  {-1.169455,0.371278},
+  {0.097553,-0.508773},
+  {-1.427358,-0.450822},
+  {0.764169,-0.321795},
+  {0.281425,1.167852},
+  {-0.513064,-0.109472},
+  {1.086924,0.792903},
+  {-0.003835,0.815400},
+  {-0.876442,-0.231937},
+  {0.483821,-0.227180},
+  {0.779304,0.300537},
+  {-1.021341,-1.075650},
+  {-0.042599,1.217835},
+  {-0.124324,1.154569},
+  {0.983924,0.128325},
+  {-0.262283,-0.571139},
+  {0.163939,0.036503},
+  {0.502541,-0.457276},
+  {0.027506,0.551723},
+  {-0.759208,-0.190703},
+  {-0.532469,1.757544},
+  {-0.097832,1.793890},
+  {-0.233310,0.236538},
+  {-0.296963,-0.245692},
+  {0.331985,0.497470},
+  {1.077897,-0.029477},
+  {0.485004,-1.550032},
+  {0.829323,-1.208018},
+  {-0.417397,-0.885481},
+  {-0.910960,0.333680},
+  {0.505911,0.222267},
+  {-0.779049,-0.648859},
+  {0.024723,-0.506963},
+  {-1.044112,0.858742},
+  {0.349329,0.199761},
+  {0.426148,0.579699},
+  {1.397881,-0.625570},
+  {-0.999539,0.150193},
+  {-0.506555,-0.493017},
+  {0.815503,-1.014094},
+  {-0.309845,0.860823},
+  {0.636101,0.034581},
+  {0.383700,0.629026},
+  {0.046350,-0.409060},
+  {0.382661,0.192436},
+  {1.578886,0.214420},
+  {-0.287174,0.113654},
+  {-0.567400,0.209722},
+  {0.432908,-0.738713},
+  {-0.114021,1.023082},
+  {-0.087467,-0.003324},
+  {1.628689,0.382128},
+  {0.930859,-0.955031},
+  {0.365787,-0.587545},
+  {-0.566131,0.401941},
+  {1.205574,-0.693033},
+  {1.041772,-0.318306},
+  {0.520455,-0.180903},
+  {1.313961,0.417802},
+  {-0.785333,-0.826391},
+  {-0.003165,0.987190},
+  {0.202221,-1.499396},
+  {-0.156205,0.234217},
+  {-0.034555,-0.710464},
+  {0.578915,0.025341},
+  {-0.967250,0.482964},
+  {-0.125553,0.645679},
+  {0.121600,0.282214},
+  {-0.467374,-0.523647},
+  {0.801851,0.110140},
+  {-0.202959,0.245792},
+  {0.964451,-0.823875},
+  {-0.720574,-0.733981},
+  {-1.552269,0.726240},
+  {0.240196,0.208363},
+  {-1.020113,0.453542},
+  {0.835032,0.546624},
+  {-0.427770,0.890482},
+  {0.244842,-0.570207},
+  {0.187974,-0.525677},
+  {-0.033276,-0.603446},
+  {0.681630,0.069452},
+  {-0.076943,1.444004},
+  {-0.466249,-1.483352},
+  {-0.333822,-0.553728},
+  {-0.464640,1.570671},
+  {0.247143,-0.404809},
+  {0.217763,-1.913662},
+  {0.569612,0.403222},
+  {-0.950478,0.269484},
+  {1.296281,-0.340172},
+  {0.248056,-0.421869},
+  {0.333895,1.464495},
+  {-0.974868,0.646046},
+  {0.432670,-1.031978},
+  {1.128838,0.295748},
+  {-0.460823,0.493682},
+  {-0.717489,1.188427},
+  {1.258650,-0.377973},
+  {-0.828146,0.064178},
+  {0.641771,-0.060587},
+  {0.245022,0.356199},
+  {0.154221,-0.400658},
+  {0.570724,0.989517},
+  {-0.412180,0.972591},
+  {0.350613,0.545597},
+  {1.122365,-1.975271},
+  {0.160367,0.137915},
+  {0.352691,-0.878584},
+  {0.423026,0.373635},
+  {-0.726179,0.179411},
+  {-0.338326,-1.788241},
+  {1.947859,1.575207},
+  {-0.951344,0.536022},
+  {0.247396,-0.497166},
+  {0.724586,-0.403144},
+  {-0.061126,-0.153871},
+  {0.528230,-0.103315},
+  {-0.022290,-0.672390},
+  {-0.000978,-0.182703},
+  {-0.241614,-0.359854},
+  {0.220241,0.428535},
+  {0.798476,-0.295902},
+  {-0.146218,0.143398},
+  {-0.619417,0.438462},
+  {-0.308855,0.331077},
+  {-1.361136,1.024312},
+  {-0.647613,0.907512},
+  {0.233092,-1.078341},
+  {1.052241,-0.621467},
+  {-0.198725,1.172681},
+  {-0.081506,0.023033},
+  {-0.547092,0.137317},
+  {0.637615,1.859723},
+  {-0.623497,-0.596191},
+  {0.149195,-0.605881},
+  {0.093756,0.630550},
+  {0.213268,-0.787503},
+  {0.426453,-0.185747},
+  {-1.548568,0.881788},
+  {0.051195,0.231489},
+  {0.209291,-0.593744},
+  {0.628475,0.857678},
+  {-1.089235,-0.641101},
+  {0.594605,-0.576514},
+  {0.252215,-0.021007},
+  {1.067553,0.471123},
+  {0.321541,-0.402181},
+  {0.284533,-0.960188},
+  {0.541105,-0.082863},
+  {0.565337,1.026278},
+  {0.317525,-1.185003},
+  {0.530922,-0.175306},
+  {-0.946283,1.216512},
+  {-0.462192,0.124213},
+  {-0.067219,0.018689},
+  {-0.295595,0.227283},
+  {-1.116823,0.278792},
+  {0.252187,-0.143898},
+  {-1.275510,0.009213},
+  {-0.097323,-1.128635},
+  {-0.292395,-0.146099},
+  {0.287647,0.343419},
+  {-0.297120,1.037639},
+  {-1.152909,-1.062561},
+  {0.117167,0.480675},
+  {0.542487,0.344975},
+  {-0.269590,0.071787},
+  {0.351416,1.336789},
+  {-0.679649,1.205267},
+  {0.158638,0.405538},
+  {0.690315,-0.580242},
+  {-0.528184,0.321935},
+  {-0.275456,0.434026},
+  {1.047915,-0.868060},
+  {-0.268058,0.433124},
+  {0.395739,0.168345},
+  {-0.706243,0.261628},
+  {-1.686516,0.100118},
+  {1.210646,0.205449},
+  {-0.403912,1.149188},
+  {0.218345,-0.059565},
+  {0.666191,-1.686280},
+  {-1.080821,0.264224},
+  {0.133752,-0.095685},
+  {-0.765833,-0.042006},
+  {-0.851086,-0.571563},
+  {-0.431850,-0.146573},
+  {-0.083487,0.324847},
+  {-0.458226,0.266507},
+  {-1.653483,0.274261},
+  {-0.892105,0.192638},
+  {0.325240,0.618814},
+  {0.839860,-0.650172},
+  {0.586121,0.493141},
+  {0.424046,-0.596069},
+  {0.579320,-0.426532},
+  {-0.860414,-0.096015},
+  {1.231735,-0.063091},
+  {0.667487,0.509589},
+  {-0.244143,-0.241915},
+  {0.392425,-0.336987},
+  {-0.577080,0.077028},
+  {-0.243798,0.518442},
+  {-0.186535,-0.514620},
+  {-0.350824,0.893193},
+  {-1.068767,-0.852674},
+  {0.256260,-0.692879},
+  {0.700920,-0.234622},
+  {-1.148149,0.242284},
+  {0.140398,-0.995881},
+  {-1.137315,-0.101466},
+  {0.642480,1.006613},
+  {-0.539053,-0.106642},
+  {0.894393,-0.576259},
+  {0.055949,-0.805028},
+  {-0.346054,-0.817483},
+  {-0.401898,0.351013},
+  {0.959261,-0.648991},
+  {-0.653608,1.002869},
+  {0.844153,0.220495},
+  {-0.631592,-0.347616},
+  {-0.725926,1.047737},
+  {0.236023,0.283730},
+  {0.123264,0.320307},
+  {1.048852,-0.451049},
+  {-0.411348,-0.986237},
+  {-0.003611,-1.217079},
+  {-0.178690,0.757153},
+  {-0.913871,0.555166},
+  {0.359649,-0.092164},
+  {-0.762808,-1.868481},
+  {-0.459054,-0.002625},
+  {-0.409244,-0.658257},
+  {0.538408,-0.336349},
+  {-0.748231,-0.660716},
+  {-0.250560,-0.025371},
+  {0.456996,-0.231112},
+  {0.299549,-1.219953},
+  {1.172228,-0.394426},
+  {-0.378361,0.665830},
+  {0.415112,0.418938},
+  {-0.548112,0.102843},
+  {-0.133962,-0.903369},
+  {-0.468702,0.681193},
+  {1.222459,1.556622},
+  {0.578721,0.124503},
+  {-0.465609,-1.236596},
+  {0.344855,0.485644},
+  {-0.769591,0.360454},
+  {-0.285111,-0.421824},
+  {0.383924,-0.612774},
+  {-0.340934,-0.217555},
+  {1.033859,-0.961846},
+  {-0.638277,-0.124713},
+  {0.713854,-1.025591},
+  {0.641113,0.723899},
+  {-0.714185,0.025297},
+  {-0.243242,-0.632974},
+  {0.004698,-0.561759},
+  {0.826869,1.173450},
+  {0.966164,-0.707247},
+  {-0.542635,1.049767},
+  {-0.518506,-0.302156},
+  {0.545221,-0.705138},
+  {-0.102193,-0.186358},
+  {0.365136,0.095347},
+  {0.201770,-0.480568},
+  {0.016332,0.581984},
+  {-0.200321,-0.337498},
+  {0.655831,0.299526},
+  {-0.638049,0.233237},
+  {1.424052,-0.333001},
+  {0.052369,-0.134042},
+  {-0.288253,1.232961},
+  {0.183916,-0.245885},
+  {0.477995,-1.296021},
+  {-0.386385,-0.681627},
+  {-0.871080,0.846105},
+  {0.995819,-0.009435},
+  {0.296135,0.463088},
+  {0.504048,0.026186},
+  {0.829560,-1.492906},
+  {0.848924,-0.979175},
+  {-0.656607,-0.872808},
+  {0.063178,-0.565062},
+  {-0.543978,0.668214},
+  {-0.282821,-0.442039},
+  {0.348789,0.133412},
+  {-0.108280,-0.389999},
+  {0.463560,-0.296653},
+  {0.762565,-0.939430},
+  {0.562681,0.745310},
+  {-0.475544,-0.766254},
+  {-0.140575,0.199589},
+  {-0.681751,-0.057548},
+  {-1.695019,-0.254700},
+  {-0.534453,-1.252818},
+  {-0.097463,-0.033164},
+  {0.013134,0.327568},
+  {0.838379,0.372423},
+  {0.665435,-1.323001},
+  {-0.545902,1.244126},
+  {-0.272644,0.828079},
+  {-0.246118,0.092456},
+  {1.201818,0.219538},
+  {0.298446,0.028810},
+  {0.130586,-1.150124},
+  {-0.189182,0.693609},
+  {-0.220031,0.117008},
+  {0.553178,-1.375086},
+  {0.699370,0.127016},
+  {0.961901,0.570180},
+  {-0.251472,-0.425322},
+  {0.846566,0.693479},
+  {-0.078834,-0.799604},
+  {-0.174930,-0.493040},
+  {-1.328997,-0.114349},
+  {0.127677,0.719281},
+  {-1.121602,-1.078388},
+  {-0.664228,1.733879},
+  {1.383895,-0.064893},
+  {0.539674,-2.059210},
+  {-1.022668,0.526521},
+  {0.733573,-0.308119},
+  {-0.188367,1.132020},
+  {0.610091,-0.282697},
+  {0.423397,0.009993},
+  {0.393636,-0.644193},
+  {0.128715,-0.357517},
+  {0.517623,-0.447918},
+  {0.158965,1.067064},
+  {0.371601,-0.581261},
+  {-0.927113,-0.619224},
+  {1.303716,-1.165499},
+  {0.322206,0.200896},
+  {-0.825444,0.595176},
+  {0.762828,-1.494917},
+  {1.295692,-1.470736},
+  {0.013767,-0.200418},
+  {-0.238785,-0.631234},
+  {-0.022044,-0.446997},
+  {0.407923,-0.215020},
+  {-0.523749,-0.371120},
+  {0.713283,0.184292},
+  {-0.268406,-0.526939},
+  {0.138893,-1.775308},
+  {-0.937942,1.003578},
+  {-0.063107,0.546195},
+  {-0.317434,0.743692},
+  {0.750336,0.359023},
+  {-0.674060,-1.184966},
+  {2.118200,0.150908},
+  {0.312808,0.577403},
+  {-0.115615,-0.380405},
+  {0.093313,0.277709},
+  {0.781873,-0.614278},
+  {0.868257,-0.087240},
+  {0.696852,-0.037947},
+  {0.418258,-0.615206},
+  {-0.502346,-0.363948},
+  {0.607748,1.486425},
+  {-0.564759,0.351200},
+  {-0.583354,-1.006512},
+  {0.270122,-0.440737},
+  {0.779603,-0.084426},
+  {-0.007898,-0.106035},
+  {0.320554,0.214694},
+  {-0.177764,-1.660508},
+  {0.364537,-0.190366},
+  {0.239589,-0.553225},
+  {-0.383177,0.604839},
+  {0.055061,0.152930},
+  {0.224963,0.592680},
+  {0.196291,-0.213862},
+  {-0.145762,0.712477},
+  {0.968561,0.056109},
+  {0.598746,0.380951},
+  {0.702798,0.468182},
+  {-0.052676,-0.835553},
+  {0.586200,-0.290487},
+  {-0.725037,-0.556427},
+  {0.267490,-0.645407},
+  {-0.859603,0.256510},
+  {-1.167129,-0.483687},
+  {-0.249517,-0.840456},
+  {-0.081174,-0.251055},
+  {-0.107692,1.266167},
+  {0.924662,-0.992418},
+  {0.178689,0.182523},
+  {-0.559303,-0.632352},
+  {-0.754172,-0.225666},
+  {0.422639,-0.820600},
+  {0.948590,1.657351},
+  {-0.281405,-0.169279},
+  {0.057540,0.103383},
+  {0.965329,-0.888955},
+  {-0.568440,1.343059},
+  {-0.186236,-0.018155},
+  {-0.110761,-0.791860},
+  {-0.525465,-0.172692},
+  {-0.820201,-0.368637},
+  {0.488156,-0.537817},
+  {-0.115891,-0.625948},
+  {-0.244424,-0.566245},
+  {-0.034738,-0.193282},
+  {0.995996,1.175802},
+  {0.633444,1.030137},
+  {0.651915,0.959199},
+  {1.923756,-0.905022},
+  {-1.312415,0.148790},
+  {-0.096677,-0.026953},
+  {0.390501,0.602404},
+  {0.867561,-0.780886},
+  {-0.248516,0.609102},
+  {0.754966,-0.110229},
+  {0.193581,-1.306164},
+  {-0.006005,-0.435352},
+  {-0.309464,0.845346},
+  {-1.119399,-0.660584},
+  {1.827421,-0.534782},
+  {1.365352,-0.177950},
+  {-0.386234,-0.795813},
+  {-0.468086,-0.003789},
+  {0.881840,0.036744},
+  {-0.514770,-0.810572},
+  {0.151684,0.110164},
+  {0.458389,0.323786},
+  {-0.120473,-1.314917},
+  {0.204646,1.100970},
+  {0.020544,0.284023},
+  {-1.429218,1.177050},
+  {0.905353,0.885557},
+  {-1.160315,1.849909},
+  {-1.424230,-1.176559},
+  {-0.905514,0.530293},
+  {0.395918,0.575079},
+  {-0.420402,0.728284},
+  {-0.068162,-0.727264},
+  {-1.231408,0.352116},
+  {-0.629367,0.024142},
+  {-0.776077,0.835663},
+  {1.388639,1.024976},
+  {0.079304,0.123010},
+  {-0.742089,-0.595562},
+  {0.413633,0.178427},
+  {1.148139,0.310845},
+  {-1.223023,-0.107151},
+  {0.893529,-0.158779},
+  {0.455295,0.570938},
+  {0.361370,0.154722},
+  {0.452221,0.207669},
+  {0.342056,0.533909},
+  {1.139659,0.955398},
+  {0.954993,0.826294},
+  {0.436891,0.869010},
+  {0.229994,-0.244482},
+  {0.099847,-0.476888},
+  {-0.522935,0.503299},
+  {-0.406360,0.610955},
+  {0.944435,-0.128204},
+  {0.065770,-1.670135},
+  {0.740768,-0.036056},
+  {-0.584472,-2.391807},
+  {-0.818919,0.704807},
+  {-0.164141,0.180842},
+  {-0.896661,0.450317},
+  {0.871090,0.180263},
+  {0.135365,1.111712},
+  {-0.834453,-0.341845},
+  {-0.257690,-0.035587},
+  {-0.462253,0.690694},
+  {-0.658742,-0.564799},
+  {-0.424196,2.228747},
+  {0.041939,-0.154539},
+  {-0.403634,0.374377},
+  {-1.213989,-0.071425},
+  {-1.333255,0.641658},
+  {0.544231,0.130374},
+  {-0.285297,-0.101088},
+  {0.409156,0.353600},
+  {-0.616579,-0.490166},
+  {0.138329,1.149111},
+  {-0.089856,-0.208823},
+  {0.269195,0.727445},
+  {-0.532599,0.947341},
+  {1.064642,0.518264},
+  {-0.160568,0.127441},
+  {-0.982412,0.428601},
+  {0.671490,-0.105111},
+  {-0.544419,0.539514},
+  {0.650748,0.073317},
+  {1.383643,0.790720},
+  {0.254461,-1.150863},
+  {-1.104232,0.797452},
+  {-0.254246,-0.008363},
+  {-0.300772,-0.103863},
+  {0.576015,0.396718},
+  {1.176581,0.732102},
+  {0.153447,0.054295},
+  {0.000016,-0.797409},
+  {0.700654,0.049420},
+  {-0.194685,-0.862644},
+  {-0.478585,-0.200502},
+  {-1.569114,-0.100896},
+  {-0.099857,1.359227},
+  {0.499119,0.183329},
+  {-0.594711,0.176504},
+  {0.329206,1.105346},
+  {0.247398,-0.273746},
+  {-0.345935,-0.650667},
+  {-0.038984,-0.023328},
+  {-0.333903,-0.697988},
+  {-1.651307,-0.010374},
+  {0.135007,-0.017740},
+  {-0.899312,0.155947},
+  {-0.464175,-0.248264},
+  {0.009996,0.360149},
+  {-0.695577,-0.382261},
+  {-0.402334,-0.007657},
+  {0.620490,0.453809},
+  {0.091440,0.758711},
+  {0.343166,1.541721},
+  {0.429339,-0.421495},
+  {-1.151836,0.034463},
+  {-0.085981,0.906358},
+  {-0.026440,1.303161},
+  {0.193819,0.354018},
+  {0.562069,-0.395005},
+  {-0.439914,-0.948032},
+  {-0.334438,0.562737},
+  {-0.864347,0.208509},
+  {-0.643184,-0.135769},
+  {0.053163,0.285246},
+  {1.646151,-0.432861},
+  {1.132792,-0.101623},
+  {-0.698541,0.212543},
+  {-0.600253,-0.394334},
+  {-1.414120,-0.017888},
+  {-0.368393,-0.718877},
+  {-0.680915,0.363811},
+  {-0.319313,0.322213},
+  {-0.244923,0.003331},
+  {1.157367,-0.139673},
+  {0.607064,-0.324347},
+  {-0.644671,-0.765634},
+  {0.089788,-0.064507},
+  {-0.720007,-0.670351},
+  {0.360654,0.469579},
+  {-0.309126,-0.364294},
+  {0.500641,-0.866124},
+  {-0.320571,-0.281417},
+  {-0.224328,1.348302},
+  {0.115238,0.182192},
+  {-0.936327,-0.335628},
+  {0.137544,0.668139},
+  {0.100546,-0.022904},
+  {-0.024822,-0.108423},
+  {0.011225,0.990800},
+  {-0.279834,-0.438608},
+  {-0.275984,0.874441},
+  {-0.823737,0.963043},
+  {-0.768202,1.310865},
+  {-0.066729,1.666242},
+  {0.907228,0.372265},
+  {-0.319255,0.457291},
+  {-0.671123,0.800845},
+  {-0.077611,0.279797},
+  {-0.194283,-0.608156},
+  {-0.041376,-0.876926},
+  {-0.020332,-0.458281},
+  {-0.440460,0.163008},
+  {0.454897,0.330234},
+  {-0.331951,-1.540866},
+  {-0.633680,-0.034518},
+  {0.757495,0.101301},
+  {-0.833573,-0.786251},
+  {0.965374,-1.392252},
+  {-1.562416,-0.203946},
+  {0.170349,0.102477},
+  {-0.297897,0.362400},
+  {-0.231639,-0.158231},
+  {0.959721,0.665986},
+  {1.098533,0.573646},
+  {-0.091776,0.472902},
+  {0.533416,-1.030881},
+  {0.526210,1.060061},
+  {-0.223194,0.188243},
+  {-0.611879,-1.854657},
+  {0.428365,0.538233},
+  {-1.044283,-0.338610},
+  {0.027523,0.049873},
+  {-0.049738,0.893777},
+  {-0.579892,-0.756394},
+  {-0.740191,0.748805},
+  {-0.542898,-1.202564},
+  {0.825741,-0.048525},
+  {0.539443,-1.170783},
+  {1.033500,0.348025},
+  {0.715562,0.128228},
+  {0.108775,0.269008},
+  {0.955005,0.864143},
+  {-0.207915,0.674605},
+  {1.403034,0.313231},
+  {0.296529,-1.450481},
+  {0.548132,1.537754},
+  {-0.021173,-0.057581},
+  {0.936941,0.628264},
+  {-0.628539,0.130955},
+  {0.068526,0.421100},
+  {-0.403953,-1.199911},
+  {1.453961,-0.456943},
+  {-0.201087,0.108304},
+  {0.271445,0.783038},
+  {0.520304,0.921613},
+  {-1.395021,-0.780013},
+  {0.131228,-0.186797},
+  {-0.855353,0.537660},
+  {-0.337268,-0.724038},
+  {-0.432516,0.344531},
+  {-0.767389,0.464180},
+  {-1.035498,0.530026},
+  {0.441212,0.883714},
+  {1.105195,-0.408422},
+  {-1.103082,-0.169069},
+  {-0.295896,0.969360},
+  {-0.478854,-0.782398},
+  {0.416756,0.605709},
+  {0.733967,0.544675},
+  {0.971172,0.356416},
+  {0.599161,-1.120536},
+  {-0.248181,0.556249},
+  {0.887368,-0.641314},
+  {0.673646,-0.843245},
+  {-0.312341,0.397320},
+  {0.729720,1.731690},
+  {-0.801968,0.323223},
+  {-0.536627,0.327754},
+  {1.622578,-0.105935},
+  {-1.750543,-0.207221},
+  {-1.908934,-0.520022},
+  {-1.469000,0.309230},
+  {-0.115261,0.192568},
+  {-0.122709,0.084334},
+  {0.189000,0.696045},
+  {0.493215,-1.328955},
+  {-0.721492,-0.333963},
+  {1.161054,-0.002184},
+  {0.512723,1.972711},
+  {-0.444754,-0.130414},
+  {-0.868852,-0.249870},
+  {-0.816170,0.515289},
+  {1.022070,-0.030086},
+  {-0.638999,-1.338192},
+  {0.242959,0.271414},
+  {-0.602075,-0.601963},
+  {0.423126,0.633321},
+  {0.223533,0.010055},
+  {0.646706,1.390161},
+  {-0.357542,0.682465},
+  {-2.009524,-0.830636},
+  {-0.778937,-0.933904},
+  {0.175269,-1.002111},
+  {-0.634257,0.665399},
+  {-0.657813,0.290878},
+  {0.747272,-0.428248},
+  {0.007320,-0.768663},
+  {1.248404,-0.212529},
+  {-0.270378,0.342898},
+  {-0.666666,-1.140755},
+  {0.196211,1.501705},
+  {0.302202,0.083526},
+  {0.991868,-0.189178},
+  {0.155298,-1.253545},
+  {-0.466703,-0.348936},
+  {0.716118,0.723010},
+  {-1.105804,-0.353013},
+  {0.555094,0.469380},
+  {-0.287244,1.500390},
+  {-0.246485,0.237558},
+  {-0.510462,-0.763731},
+  {-0.561608,-0.551817},
+  {-0.069471,0.227096},
+  {1.137497,0.948345},
+  {0.172721,-0.065489},
+  {0.748416,0.831896},
+  {-0.155555,-0.792121},
+  {-0.477453,0.763809},
+  {0.124495,0.775665},
+  {-0.615673,0.574783},
+  {0.204540,0.358135},
+  {-0.903123,-0.381671},
+  {0.487242,0.995473},
+  {-0.926024,0.064502},
+  {0.929931,0.258942},
+  {0.312395,-0.341280},
+  {0.549625,-0.936615},
+  {-0.861195,0.434874},
+  {1.386344,1.002935},
+  {0.150581,1.440757},
+  {-0.223814,0.226411},
+  {-1.239970,0.911429},
+  {0.525911,-0.294822},
+  {0.774677,-0.033484},
+  {-0.481076,-0.140935},
+  {0.097171,0.602864},
+  {0.273227,1.072022},
+  {0.309890,0.473631},
+  {-0.466034,0.111893},
+  {-0.691036,0.030113},
+  {-0.821156,-0.280252},
+  {-0.526502,-0.289481},
+  {0.720837,0.871377},
+  {0.790615,0.875528},
+  {0.797253,0.484843},
+  {0.111852,-1.055992},
+  {0.169400,0.295747},
+  {1.171135,-0.137264},
+  {0.290213,0.662161},
+  {-0.393626,-0.143884},
+  {-0.749653,-0.256666},
+  {0.260497,0.439210},
+  {1.135854,-0.431511},
+  {0.258906,0.670444},
+  {-1.066888,-0.119150},
+  {0.453981,0.837529},
+  {0.411804,0.845536},
+  {-1.059449,0.036210},
+  {0.764611,0.473083},
+  {-0.027347,0.346493},
+  {0.339275,-1.308645},
+  {-0.110170,-0.533479},
+  {-0.509505,0.121273},
+  {0.007601,0.222193},
+  {0.245116,1.845521},
+  {-0.063218,0.106742},
+  {0.947333,0.014644},
+  {0.082611,-0.363300},
+  {0.686892,-0.186853},
+  {1.235221,0.021879},
+  {-0.257780,0.017378},
+  {0.015664,0.281120},
+  {0.190295,0.897504},
+  {0.379354,0.120590},
+  {0.427338,-0.164006},
+  {1.172924,0.915224},
+  {0.721570,-1.247163},
+  {0.084550,0.312004},
+  {-1.286085,0.190192},
+  {0.284174,-0.119200},
+  {-0.010789,-1.373622},
+  {-0.185711,-0.418035},
+  {0.505770,0.363854},
+  {0.061188,0.700576},
+  {-0.462928,0.573874},
+  {0.740084,-0.629523},
+  {0.528961,1.652541},
+  {0.623314,0.190869},
+  {-0.597870,-0.927126},
+  {0.533533,0.251731},
+  {0.277124,1.153433},
+  {0.851106,-0.786252},
+  {-1.330171,1.147345},
+  {-0.464697,0.070864},
+  {0.212042,-0.145618},
+  {-0.687571,1.186801},
+  {0.481482,0.178028},
+  {-0.149879,0.044565},
+  {-0.223578,0.104703},
+  {0.574649,-0.285176},
+  {-1.833740,0.013517},
+  {-1.725660,-0.234990},
+  {-0.463536,0.588847},
+  {0.902710,0.788674},
+  {-0.254637,-0.532033},
+  {0.572229,1.349808},
+  {-0.063305,-0.215431},
+  {0.516429,0.299522},
+  {-1.130246,0.308680},
+  {-0.900674,-0.507683},
+  {-0.583496,0.223002},
+  {-0.592279,-0.950809},
+  {-0.100426,-0.586777},
+  {-0.028076,0.677118},
+  {-1.803788,-0.573550},
+  {-1.088822,1.183910},
+  {0.596317,-1.549580},
+  {0.668189,-0.306555},
+  {-0.020441,0.607971},
+  {0.853888,0.246148},
+  {0.879904,1.225752},
+  {1.614124,0.830021},
+  {-0.291743,-0.135559},
+  {0.458523,-0.480775},
+  {0.275255,0.138678},
+  {0.883940,0.525436},
+  {-0.542455,-0.182128},
+  {0.999170,-0.332015},
+  {0.099745,0.792268},
+  {0.708489,0.722752},
+  {-1.050482,-0.202141},
+  {-1.139348,0.223888},
+  {-0.165198,-0.429917},
+  {0.319484,0.084528},
+  {0.047179,0.526009},
+  {-1.274314,-0.347434},
+  {-0.377124,0.028014},
+  {-0.360881,0.915426},
+  {-0.725553,-1.003947},
+  {0.135016,0.821066},
+  {0.748460,0.802817},
+  {0.130105,0.256667},
+  {-0.269583,0.719719},
+  {0.649401,0.873793},
+  {0.987143,0.161186},
+  {-0.240362,0.789136},
+  {-0.121450,0.924916},
+  {-0.259843,0.404871},
+  {0.016597,-0.851491},
+  {-0.042926,-0.009539},
+  {-0.196370,-0.423108},
+  {-1.535905,0.622120},
+  {-0.853325,0.069428},
+  {-0.713308,0.493254},
+  {0.023896,0.016209},
+  {-1.230161,0.130732},
+  {0.290839,-1.217903},
+  {-0.256162,-0.539416},
+  {0.629392,0.257101},
+  {0.982458,-0.309371},
+  {1.120927,1.254970},
+  {2.080817,-0.873252},
+  {-0.419871,0.427512},
+  {-0.008634,0.589147},
+  {-1.033991,-0.181336},
+  {0.243382,-0.186332},
+  {0.333660,-0.327366},
+  {0.221360,0.080553},
+  {0.704698,0.309089},
+  {-0.450895,0.130395},
+  {0.168094,-0.573576},
+  {1.018659,0.358155},
+  {0.418952,-0.622499},
+  {-0.997778,0.362820},
+  {0.222152,-0.219744},
+  {-0.166802,0.480155},
+  {-0.919339,-0.890832},
+  {-0.286039,0.292035},
+  {0.448303,-0.301572},
+  {-0.449567,1.207951},
+  {0.897655,-0.477985},
+  {0.503965,-0.545751},
+  {0.401514,-1.644501},
+  {0.271308,0.286347},
+  {-0.284592,0.577983},
+  {-0.009884,0.478410},
+  {1.517272,-1.524143},
+  {-1.437806,0.700884},
+  {-0.275556,-1.439763},
+  {1.893314,-0.130608},
+  {-0.166340,0.557318},
+  {-0.691321,0.091720},
+  {-0.106616,0.561819},
+  {-0.383283,-0.766395},
+  {0.775944,0.312252},
+  {0.208777,-0.783645},
+  {-0.680476,0.061669},
+  {0.183494,-1.161476},
+  {-0.392678,-0.523162},
+  {-0.073376,0.398882},
+  {1.160349,-0.807825},
+  {-0.986883,0.472541},
+  {-0.034247,-0.317474},
+  {0.352450,-0.542563},
+  {0.578726,0.400276},
+  {-0.141064,-0.541357},
+  {-0.202180,0.303236},
+  {-0.873698,-0.388820},
+  {-1.241604,-0.714657},
+  {0.264090,-1.498626},
+  {0.602075,0.227838},
+  {-0.154430,0.667914},
+  {-1.462996,0.458992},
+  {-0.822634,0.424372},
+  {-0.658739,0.865879},
+  {-0.422218,0.182616},
+  {0.053181,-0.072330},
+  {-0.062806,0.762247},
+  {0.835446,-1.311912},
+  {0.087703,0.026320},
+  {0.542328,-0.151886},
+  {-1.828505,0.593531},
+  {-1.080520,1.086271},
+  {0.849256,0.525323},
+  {0.497942,0.697413},
+  {-0.244531,1.043887},
+  {-1.458797,-0.216500},
+  {-1.214738,-1.022308},
+  {0.159061,-0.098262},
+  {0.727952,1.271393},
+  {-0.754485,0.954004},
+  {-0.176632,0.615747},
+  {0.028411,-0.767032},
+  {-0.748180,-0.441965},
+  {0.242074,-0.788659},
+  {0.670060,1.096734},
+  {0.154009,-1.243446},
+  {0.850586,-1.501833},
+  {1.150581,0.774110},
+  {-0.989572,0.879881},
+  {-0.575178,0.294339},
+  {0.003447,0.489239},
+  {1.145287,0.324623},
+  {0.184091,-1.062771},
+  {0.158889,0.215402},
+  {0.201577,0.011042},
+  {-0.181512,-0.504270},
+  {-0.055374,0.590276},
+  {-0.531721,-0.884568},
+  {-0.209470,-0.372283},
+  {-1.255795,-0.759923},
+  {0.366333,-0.922058},
+  {1.322717,-0.181335},
+  {-0.678275,1.164669},
+  {-0.750670,-0.137794},
+  {0.112897,0.410423},
+  {0.191286,0.113733},
+  {-0.452766,0.723349},
+  {-0.736083,-0.170689},
+  {0.692416,0.132405},
+  {1.018870,-1.559833},
+  {-1.443120,-0.229399},
+  {0.716224,0.947647},
+  {0.279685,0.653005},
+  {0.710520,0.177459},
+  {-0.557518,-1.425511},
+  {-0.256127,0.315232},
+  {-0.082281,0.579783},
+  {-0.857951,-0.531888},
+  {-0.747733,1.197090},
+  {-0.006789,-0.966185},
+  {-0.612837,-0.621645},
+  {1.132351,0.561013},
+  {0.365387,0.280771},
+  {0.819015,0.005642},
+  {0.077710,-0.275083},
+  {-0.589305,0.053577},
+  {0.746235,0.106363},
+  {0.483010,-0.756925},
+  {0.555464,-1.006915},
+  {1.083126,-0.706053},
+  {-0.114394,-0.110508},
+  {1.101602,-1.451006},
+  {0.482109,0.584615},
+  {0.242472,-1.768441},
+  {2.096101,0.679566},
+  {-0.527421,-0.071384},
+  {1.001152,0.540874},
+  {1.515730,-0.408948},
+  {-1.081754,-0.587317},
+  {-1.534001,-0.908835},
+  {0.161009,0.022969},
+  {-0.555147,0.084544},
+  {-0.049147,0.004229},
+  {-0.281130,1.140545},
+  {1.877216,0.501126},
+  {0.834883,0.052106},
+  {0.108568,-1.416109},
+  {-0.496393,-0.851726},
+  {-0.546421,-0.850434},
+  {-0.100497,0.366563},
+  {-0.505233,-0.181871},
+  {0.003181,-0.257644},
+  {-0.427184,0.802357},
+  {2.175829,0.214003},
+  {-1.470833,-0.859757},
+  {0.177123,-0.005589},
+  {-0.155512,-0.028954},
+  {-0.576782,-0.183170},
+  {0.659928,0.889550},
+  {0.547329,-0.667458},
+  {1.543267,-0.883763},
+  {-0.027341,-0.587168},
+  {-0.767299,0.181322},
+  {-0.058809,0.621716},
+  {-0.136666,0.112151},
+  {1.320616,-0.923620},
+  {-0.758136,0.563569},
+  {-0.896224,0.826225},
+  {0.415972,1.835909},
+  {-0.226084,0.573171},
+  {0.648683,0.868590},
+  {0.148597,0.095773},
+  {-0.923255,-0.006413},
+  {0.008498,0.345011},
+  {-0.438936,-0.177137},
+  {-0.220799,0.289912},
+  {0.374629,-1.246758},
+  {-0.405352,-0.920192},
+  {0.267008,0.274742},
+  {-0.976383,-0.137177},
+  {0.688771,1.380999},
+  {-0.478994,-0.518246},
+  {0.005349,0.286922},
+  {-0.296630,0.203362},
+  {-0.543880,-0.873593},
+  {1.511098,-0.907825},
+  {0.433183,-1.112696},
+  {0.716750,-0.497192},
+  {0.545947,0.471261},
+  {1.624519,-0.037766},
+  {-0.383763,-0.364185},
+  {-0.361717,0.471989},
+  {-0.997984,1.419701},
+  {0.816524,-0.299520},
+  {-0.245384,0.189731},
+  {0.065447,-0.059209},
+  {0.779328,0.204790},
+  {0.731539,-0.345297},
+  {0.404574,0.248687},
+  {1.043347,2.307089},
+  {0.334605,-0.253063},
+  {-0.216840,-0.098456},
+  {0.350238,-0.382642},
+  {0.349119,-0.532957},
+  {-1.859158,-0.233730},
+  {0.862392,-0.445325},
+  {-0.101752,-0.036104},
+  {-0.378956,-0.338704},
+  {-0.994805,0.464318},
+  {-0.996382,0.208659},
+  {0.808323,0.455032},
+  {-2.112046,0.061540},
+  {0.819598,0.624593},
+  {0.878981,1.053073},
+  {-0.341489,-0.442258},
+  {-0.496671,-0.854729},
+  {0.065132,0.231571},
+  {-0.246478,0.530029},
+  {-0.284105,0.054951},
+  {0.376465,-0.172238},
+  {0.299234,0.652101},
+  {-0.627995,1.886543},
+  {-0.482888,-0.856058},
+  {-0.830026,-0.832774},
+  {0.779929,0.337171},
+  {-0.369851,-0.412797},
+  {-0.432700,0.692209},
+  {-0.065776,1.142133},
+  {1.054275,-0.392488},
+  {-0.718737,-0.644947},
+  {-0.076992,-0.542669},
+  {-0.175216,0.328426},
+  {-1.591234,-0.008631},
+  {-0.369091,-0.575943},
+  {-0.664370,0.357384},
+  {-0.223916,-0.159983},
+  {-0.524674,0.109124},
+  {0.980964,0.285221},
+  {1.085013,0.302149},
+  {0.239054,-1.200352},
+  {-1.131626,0.880129},
+  {0.611328,0.462691},
+  {0.109595,-0.038623},
+  {0.137486,0.811529},
+  {0.196871,-0.418142},
+  {0.699526,-0.181672},
+  {-0.998589,0.332045},
+  {-0.339367,-0.358573},
+  {-0.870253,0.811889},
+  {0.424311,2.218276},
+  {0.122027,0.056903},
+  {-0.485555,-0.599874},
+  {-0.023325,0.457989},
+  {-0.257390,0.531017},
+  {-0.594800,-0.363526},
+  {1.037002,0.461854},
+  {0.667577,0.489237},
+  {0.025804,0.603610},
+  {-0.453581,-0.162107},
+  {0.230955,-0.243543},
+  {-0.669782,0.966822},
+  {-0.624782,-0.044558},
+  {-0.787855,0.834564},
+  {-0.309755,-0.555690},
+  {0.895544,0.561778},
+  {-0.081447,-0.146939},
+  {0.741198,-0.128052},
+  {0.669056,0.986545},
+  {-0.747874,0.482845},
+  {0.073550,-0.909752},
+  {-0.872751,-0.413878},
+  {-0.863929,-0.294266},
+  {1.093727,-0.577195},
+  {-0.161357,0.324918},
+  {0.125704,0.723239},
+  {-0.766171,-0.998274},
+  {-0.023512,0.626686},
+  {-0.790729,-0.296770},
+  {2.140339,0.378394},
+  {-0.262331,0.246625},
+  {-0.856882,-0.281878},
+  {0.997209,0.093078},
+  {1.148219,-0.546145},
+  {-0.030454,0.592030},
+  {0.076696,0.233782},
+  {-0.141260,-0.777390},
+  {-0.589189,-0.483685},
+  {0.289672,0.386135},
+  {-1.264861,-0.995417},
+  {-0.042752,-0.532604},
+  {-0.134781,0.365284},
+  {-0.340780,1.472232},
+  {-1.483415,0.914143},
+  {-0.283508,0.156881},
+  {-0.736152,-1.343692},
+  {-0.096745,0.290601},
+  {0.091744,0.223455},
+  {-0.353464,0.284825},
+  {-2.136104,-0.528703},
+  {0.494303,0.010275},
+  {0.096905,-0.401126},
+  {0.727808,0.185508},
+  {-0.613681,0.534158},
+  {1.044872,0.971303},
+  {0.717104,0.100286},
+  {-1.419618,-0.604448},
+  {-0.410767,-0.231726},
+  {0.848536,0.951917},
+  {0.746859,-0.161283},
+  {-1.056914,-0.626140},
+  {-0.302984,0.411916},
+  {-0.391683,0.373145},
+  {-0.314457,0.491804},
+  {1.239795,-0.694703},
+  {-0.168077,-0.742324},
+  {0.053671,0.573151},
+  {1.116908,-0.547143},
+  {-0.580176,1.202944},
+  {0.088589,-0.455011},
+  {0.779909,0.947051},
+  {-0.559228,-0.818329},
+  {-0.112108,-0.428851},
+  {0.483455,0.814911},
+  {1.219918,-1.265525},
+  {-0.808586,0.580155},
+  {-0.538486,-0.056154},
+  {0.696324,0.122801},
+  {-0.312645,-0.640077},
+  {0.504048,-1.031634},
+  {0.178747,0.494393},
+  {1.744485,1.430984},
+  {-0.106728,0.085838},
+  {-0.572292,0.236523},
+  {0.052278,0.163252},
+  {0.083152,-0.214327},
+  {0.114333,0.425771},
+  {0.359542,-0.296919},
+  {-0.935315,0.054319},
+  {0.076361,-0.824908},
+  {-0.081657,0.104635},
+  {-0.267140,-0.395640},
+  {0.426262,-1.206860},
+  {0.257655,0.559848},
+  {0.244592,1.151796},
+  {0.897633,-0.515393},
+  {0.418324,0.647156},
+  {-0.741549,0.112829},
+  {0.988401,-0.625204},
+  {0.369894,-0.802808},
+  {0.658272,-2.303792},
+  {-0.215105,1.646744},
+  {0.519888,1.012419},
+  {-0.238965,-0.324462},
+  {-0.112710,0.191850},
+  {-0.066331,-1.146826},
+  {-0.038528,-0.023964},
+  {0.373568,0.001974},
+  {-0.864264,-0.906543},
+  {0.679871,0.421732},
+  {-0.043741,1.101931},
+  {-0.552452,-0.138525},
+  {-0.095636,-0.883681},
+  {-0.072871,0.876045},
+  {-0.238791,0.132820},
+  {0.244078,-0.390211},
+  {-0.082340,0.487018},
+  {0.796116,0.096262},
+  {0.408338,0.230686},
+  {-0.441585,-0.626388},
+  {0.365510,0.719968},
+  {0.126699,-0.388437},
+  {0.110592,-0.075274},
+  {2.264902,-1.563334},
+  {-0.272466,-0.015424},
+  {0.608222,1.351945},
+  {-1.147737,1.113406},
+  {0.284979,-0.205787},
+  {-0.450449,0.238860},
+  {1.027885,-0.840673},
+  {-0.455186,-0.221859},
+  {-0.938632,-2.082159},
+  {1.391911,0.802204},
+  {0.975475,-0.276338},
+  {-0.243330,-0.064295},
+  {0.138971,0.536216},
+  {0.691166,0.177819},
+  {1.026026,-1.879955},
+  {-0.187583,0.063026},
+  {-0.074402,-0.288843},
+  {-0.243687,0.652614},
+  {-1.212718,-0.767727},
+  {0.251387,0.506600},
+  {-0.660165,0.422242},
+  {0.679188,1.371130},
+  {-0.170699,-0.614176},
+  {0.520129,-0.476992},
+  {0.848435,-0.401178},
+  {0.405024,-0.093561},
+  {0.626143,0.076985},
+  {0.295405,-0.762852},
+  {0.549177,0.725065},
+  {0.526664,0.156528},
+  {0.977468,-0.889557},
+  {-0.501570,-0.343316},
+  {-2.000729,-1.623071},
+  {-1.946962,0.328553},
+  {0.777598,-0.856117},
+  {-0.326491,0.100360},
+  {0.198779,-0.141495},
+  {-0.995361,-1.077920},
+  {0.047623,-0.345042},
+  {1.887429,-0.220347},
+  {-0.157694,0.558083},
+  {0.462495,-0.577463},
+  {-0.215078,-0.858704},
+  {1.253739,0.253756},
+  {-0.169634,-1.005008},
+  {-0.047497,0.740879},
+  {-0.581666,0.040685},
+  {-0.201745,1.662973},
+  {0.317519,-1.047738},
+  {0.967803,0.032915},
+  {0.212464,0.089187},
+  {0.718780,0.944362},
+  {-1.948257,-0.331151},
+  {0.922229,-0.646998},
+  {-0.627500,0.378164},
+  {-0.222201,-1.313254},
+  {-0.266142,0.014479},
+  {-0.424176,-0.993625},
+  {-0.059820,0.319289},
+  {-0.843761,-0.433096},
+  {0.087394,-0.412266},
+  {0.305914,-1.210798},
+  {0.471462,0.643052},
+  {1.252232,0.000904},
+  {0.216403,-0.122659},
+  {1.216662,0.381311},
+  {1.296341,-0.140316},
+  {-0.022925,0.194975},
+  {0.862409,0.620792},
+  {0.064807,1.351515},
+  {-0.565969,-0.236810},
+  {-0.155437,0.605360},
+  {0.051996,0.325921},
+  {0.150445,0.429124},
+  {0.459964,0.511976},
+  {0.428904,0.323586},
+  {0.188316,-0.513317},
+  {0.939000,1.371945},
+  {0.649626,-0.024783},
+  {1.376851,0.200015},
+  {-0.048111,-1.183880},
+  {-0.786435,-0.777301},
+  {-0.241709,1.388115},
+  {-0.109006,0.946566},
+  {1.156840,1.561297},
+  {-0.127523,1.700414},
+  {0.761736,-0.883463},
+  {-1.099255,-0.579362},
+  {1.338325,0.799131},
+  {-1.021709,0.379151},
+  {-0.994399,0.063684},
+  {0.818383,-0.273057},
+  {0.668366,-0.297543},
+  {-1.015779,0.889539},
+  {0.913941,-0.629156},
+  {-1.700678,0.079532},
+  {0.256160,-0.369452},
+  {0.150019,0.098158},
+  {-0.119020,-1.045646},
+  {0.741243,-0.716726},
+  {-1.108436,0.863056},
+  {0.307252,0.506812},
+  {-0.171352,-0.503576},
+  {1.261155,0.176500},
+  {0.174007,-0.712686},
+  {-0.141806,0.330990},
+  {-0.109117,-0.228317},
+  {0.203634,0.606610},
+  {-0.712412,0.250541},
+  {-0.137947,0.768827},
+  {-0.744735,0.914129},
+  {-1.167755,0.152721},
+  {0.327150,-0.113608},
+  {0.177006,-0.387882},
+  {0.848800,0.884244},
+  {-0.111614,-0.152304},
+  {-0.300267,0.243189},
+  {0.093467,0.290017},
+  {1.352682,0.983666},
+  {0.299551,0.490373},
+  {-0.353636,0.504747},
+  {0.613392,-0.069319},
+  {1.054224,-0.871011},
+  {2.339625,-0.344715},
+  {-1.010481,0.230538},
+  {-0.539544,-0.583309},
+  {0.499012,0.102340},
+  {-0.575380,0.783295},
+  {0.805940,0.307558},
+  {0.417599,-0.060720},
+  {-0.177191,-0.033481},
+  {0.109710,-0.280558},
+  {0.446148,-0.888981},
+  {0.195612,-0.768271},
+  {0.039506,0.628468},
+  {-0.492624,-0.504992},
+  {-1.396420,-0.011736},
+  {-0.046356,0.570300},
+  {1.085142,-1.294011},
+  {0.752542,-0.090279},
+  {-1.473829,0.875925},
+  {0.761430,-0.161165},
+  {0.959718,0.258992},
+  {0.460259,0.467090},
+  {0.108088,-0.414908},
+  {0.842820,0.796490},
+  {0.248226,0.228333},
+  {-0.166433,-2.038801},
+  {-1.326628,-0.722473},
+  {-0.475355,0.696458},
+  {0.138056,0.500725},
+  {0.168092,-0.866839},
+  {0.019798,-0.447601},
+  {-0.724926,0.046180},
+  {-0.276801,1.054389},
+  {0.003609,-0.044388},
+  {-0.692568,0.378780},
+  {-0.950437,-0.173717},
+  {0.251268,-0.282029},
+  {-0.439649,0.031710},
+  {-1.080425,-0.215370},
+  {0.719048,-0.338402},
+  {-0.687926,-0.765291},
+  {-0.401951,-1.098793},
+  {-0.568740,-0.550765},
+  {-1.100182,-1.817952},
+  {0.427277,0.515781},
+  {-0.227288,0.535524},
+  {0.311561,-0.427903},
+  {0.531886,0.638625},
+  {-1.225598,-0.291583},
+  {-0.123388,-0.705261},
+  {0.958207,0.537159},
+  {0.328784,-0.348955},
+  {0.027395,-0.081869},
+  {0.067524,0.032020},
+  {0.528416,-0.759115},
+  {0.941596,-0.896593},
+  {-0.219845,-0.026498},
+  {-0.032095,1.010285},
+  {-0.610792,0.633952},
+  {0.108644,0.649716},
+  {0.552711,0.848451},
+  {0.201063,0.583580},
+  {-1.261548,0.388021},
+  {0.890668,-0.175176},
+  {0.607208,-0.307948},
+  {-0.205981,0.041344},
+  {-0.776250,0.177243},
+  {0.337239,0.161071},
+  {-0.037705,-0.120282},
+  {-0.014045,-1.241609},
+  {-0.555803,0.188605},
+  {0.241814,-0.987252},
+  {-0.463139,0.874492},
+  {-0.070504,0.160308},
+  {-0.178391,0.972757},
+  {-0.366224,-1.177044},
+  {0.971867,0.479103},
+  {0.125259,0.461216},
+  {0.694764,-1.494325},
+  {-0.277845,0.320865},
+  {0.616292,-0.626879},
+  {-0.030863,0.874982},
+  {-0.766846,-0.016767},
+  {-0.369774,0.258101},
+  {-0.149097,0.291851},
+  {-0.493542,-0.295266},
+  {1.146361,-0.267924},
+  {-0.934380,-0.011444},
+  {0.415305,0.183752},
+  {-0.491891,-0.357477},
+  {-0.560602,-0.794771},
+  {0.317386,0.323920},
+  {-0.500328,-0.562780},
+  {0.041451,-0.181370},
+  {-0.529525,-0.497591},
+  {0.648109,0.580791},
+  {-0.582613,-0.249940},
+  {-0.051540,-0.826063},
+  {1.646775,0.986751},
+  {0.481024,-0.258589},
+  {-0.789469,-0.719895},
+  {0.638624,-0.406398},
+  {-0.281974,-0.250588},
+  {-0.619277,-0.458814},
+  {1.953618,-0.616999},
+  {1.097286,0.692794},
+  {-0.079763,1.146230},
+  {-0.662413,-0.114838},
+  {-0.710125,-0.561579},
+  {0.652582,-1.218519},
+  {-1.107519,-1.568995},
+  {-0.128567,-0.868703},
+  {1.148380,-0.401765},
+  {0.275385,0.300600},
+  {0.619924,0.435204},
+  {0.536274,-1.285634},
+  {-0.410239,-0.168935},
+  {0.305748,0.032075},
+  {-0.278987,-0.244613},
+  {0.272564,-0.215397},
+  {0.442925,0.284863},
+  {0.343083,-0.985089},
+  {0.243655,-0.535491},
+  {-0.058256,-0.138061},
+  {1.469464,0.252023},
+  {0.457389,0.293408},
+  {-0.401809,0.313757},
+  {0.756131,-0.077182},
+  {-0.785143,0.185929},
+  {0.335933,0.863780},
+  {-0.386318,-0.435270},
+  {0.083281,-0.052628},
+  {0.228627,-0.248970},
+  {0.607702,-0.139063},
+  {-0.640376,-1.314560},
+  {-0.128571,-0.846763},
+  {0.614100,-0.123165},
+  {0.129793,-0.321393},
+  {-0.266171,-0.648007},
+  {0.416713,-0.029613},
+  {0.225510,0.728644},
+  {0.393598,0.429328},
+  {1.597007,-0.340253},
+  {0.768635,0.000382},
+  {0.010930,0.047671},
+  {-0.193073,0.323188},
+  {-1.230056,0.049060},
+  {-0.445542,-0.226577},
+  {-1.104063,-0.513824},
+  {0.799375,0.141533},
+  {0.706937,0.178929},
+  {0.236867,0.128337},
+  {-0.097298,-1.042810},
+  {-0.735652,0.420616},
+  {-0.588963,-0.623118},
+  {-1.635909,0.027266},
+  {-0.945824,1.046139},
+  {-0.697924,-0.368466},
+  {0.335071,-0.324357},
+  {0.418055,-0.170021},
+  {-0.243762,0.064872},
+  {0.400947,-0.261076},
+  {-0.356738,-0.672932},
+  {1.059406,0.747656},
+  {0.122394,-0.472220},
+  {0.295724,0.705496},
+  {-0.593362,0.561189},
+  {0.827451,-0.913072},
+  {0.575753,-0.582888},
+  {-0.449487,-1.203258},
+  {0.002070,-0.209496},
+  {-0.819372,1.013107},
+  {-0.223983,0.409793},
+  {-0.105117,-0.240320},
+  {0.505813,0.544863},
+  {-0.062506,0.840417},
+  {-0.074185,-1.498686},
+  {-0.050561,-0.531679},
+  {-0.407497,0.036355},
+  {-0.640938,-0.667689},
+  {0.015491,0.043753},
+  {0.687209,-1.632878},
+  {0.618242,-1.063427},
+  {-0.241815,-0.839270},
+  {0.602280,0.346705},
+  {-0.701291,0.105225},
+  {-0.407340,-0.339801},
+  {-0.345298,-1.047087},
+  {-0.134469,-0.783420},
+  {-0.543787,1.086768},
+  {-0.222433,-0.012544},
+  {0.760408,-0.125045},
+  {-0.585757,-1.015366},
+  {-0.622145,-0.507983},
+  {-0.105669,-0.357043},
+  {-0.255007,0.058948},
+  {-0.925739,0.274361},
+  {-0.375779,-0.555844},
+  {0.432849,0.596696},
+  {0.057883,-0.368657},
+  {-0.451532,-0.509855},
+  {-0.756553,-1.048769},
+  {-0.348112,-0.540951},
+  {-0.831728,-0.598372},
+  {0.332533,0.729092},
+  {-0.135877,0.565378},
+  {0.062568,-0.041090},
+  {-0.367750,-0.509901},
+  {-0.553719,-0.111947},
+  {-1.021522,0.275873},
+  {-0.050085,0.315809},
+  {-0.928466,0.206772},
+  {-1.191365,1.451377},
+  {0.920724,1.063243},
+  {-0.063332,-0.406468},
+  {-0.515630,-1.279352},
+  {0.487661,-0.818408},
+  {-0.027072,-0.002359},
+  {0.227643,0.002201},
+  {1.084393,0.067814},
+  {0.552847,0.362214},
+  {0.199879,0.680228},
+  {0.372569,0.685069},
+  {0.292540,0.321147},
+  {0.363653,0.247260},
+  {-0.588959,-0.794473},
+  {0.352148,0.263375},
+  {0.524180,-1.109269},
+  {-0.285997,-0.110195},
+  {-1.179159,-0.952197},
+  {0.573545,0.373895},
+  {-0.224947,0.447142},
+  {0.137062,-0.810396},
+  {0.027311,-0.504226},
+  {1.193193,0.163454},
+  {0.554125,0.651387},
+  {0.650385,0.140576},
+  {-0.818715,-0.166574},
+  {0.098850,0.910239},
+  {-0.364286,1.396334},
+  {-0.209655,-0.775914},
+  {-0.370780,-1.208692},
+  {-0.047578,0.440463},
+  {1.233010,-0.648612},
+  {-0.140918,0.321229},
+  {0.196838,0.020064},
+  {0.376956,0.417526},
+  {0.185651,0.879134},
+  {0.640523,-0.156284},
+  {0.743281,-0.154083},
+  {-0.360541,-0.915597},
+  {-0.177171,-0.588081},
+  {0.960627,-0.156028},
+  {0.537350,-0.452252},
+  {-0.235733,-0.027291},
+  {-0.746237,-0.017686},
+  {-0.406613,0.579063},
+  {-0.994922,-1.060790},
+  {-0.669324,0.430821},
+  {-0.398869,-0.634411},
+  {0.762944,-0.143725},
+  {0.283899,0.878354},
+  {-0.070692,-1.069885},
+  {1.509989,-0.562410},
+  {0.612479,-0.758589},
+  {-0.176361,-0.743195},
+  {-1.116313,-0.446980},
+  {-0.007589,0.391379},
+  {0.102751,0.106416},
+  {0.704608,-0.302822},
+  {0.013309,-0.343502},
+  {1.258582,-0.751478},
+  {-0.768097,-1.864140},
+  {-1.428795,0.401529},
+  {-0.620903,-1.088542},
+  {-0.328758,-0.244061},
+  {-0.351989,-0.302104},
+  {0.040004,0.117331},
+  {-0.116617,-0.037641},
+  {-0.271723,0.244152},
+  {0.359241,-0.171465},
+  {-0.586401,-0.121233},
+  {0.604605,1.161484},
+  {-0.403794,1.518033},
+  {-0.320099,-1.946147},
+  {1.265835,-1.070397},
+  {1.028280,0.157896},
+  {0.070852,0.788980},
+  {-0.628415,-0.602539},
+  {-0.452347,0.152041},
+  {0.078811,0.062621},
+  {0.343871,1.592619},
+  {-0.148877,0.159315},
+  {-0.000463,-0.181856},
+  {-1.639889,-0.376867},
+  {0.521937,1.142912},
+  {0.935462,-0.231012},
+  {0.779969,-0.218677},
+  {-0.354689,-0.476571},
+  {-0.904562,0.034987},
+  {0.125173,0.573088},
+  {-0.495766,-1.612758},
+  {-2.062263,0.055393},
+  {-0.580883,0.751677},
+  {0.616167,-0.770758},
+  {0.926324,-0.141294},
+  {1.046484,-0.562055},
+  {0.375710,-0.089429},
+  {-1.166185,-0.487809},
+  {-0.707975,-0.729558},
+  {-0.118322,-0.402670},
+  {0.272092,0.594689},
+  {0.240115,-0.224296},
+  {0.244773,-0.446577},
+  {-0.046161,0.215951},
+  {1.385255,-0.292633},
+  {0.161275,-0.089966},
+  {-0.145126,-0.954704},
+  {-0.061937,0.085533},
+  {-0.448217,-0.232410},
+  {-0.295303,0.406249},
+  {-0.273240,-0.980753},
+  {-0.413078,0.765020},
+  {0.565840,-0.524401},
+  {0.554666,-0.284595},
+  {0.114768,0.187983},
+  {-0.890592,-0.266010},
+  {0.650560,0.103151},
+  {0.586884,-0.342944},
+  {0.626604,-1.021207},
+  {-1.554120,-0.024893},
+  {1.869185,0.210050},
+  {-0.012275,0.388102},
+  {-0.462074,-0.605148},
+  {0.255341,-0.179884},
+  {-0.340660,-1.397953},
+  {0.187923,0.360639},
+  {0.484712,-0.181846},
+  {-0.177458,0.360760},
+  {-0.482337,-0.081107},
+  {-0.253224,0.661932},
+  {-0.724755,0.316380},
+  {-0.028731,-0.097583},
+  {-0.090675,0.918420},
+  {-0.288796,-0.874214},
+  {-1.281843,-1.346400},
+  {-1.975214,0.339394},
+  {-0.613541,0.515236},
+  {0.250206,0.074632},
+  {0.996936,0.863932},
+  {-0.782503,-0.162518},
+  {-0.086359,-1.378544},
+  {0.721407,-0.891762},
+  {0.240897,0.580625},
+  {-0.133187,1.084532},
+  {1.435339,-0.476021},
+  {0.283575,0.906435},
+  {-0.470645,-0.523456},
+  {-0.939491,-0.042648},
+  {-0.949484,-0.012379},
+  {-0.083733,-0.312338},
+  {-0.885689,-0.387254},
+  {0.644921,-1.190076},
+  {-1.121036,-0.485559},
+  {-0.356930,-0.523413},
+  {-0.479120,-0.096518},
+  {0.952204,-0.417529},
+  {0.557766,-1.049478},
+  {1.135059,-0.173027},
+  {-0.302560,-0.322420},
+  {-0.183123,-0.081440},
+  {0.074167,-0.077368},
+  {-1.407874,0.624530},
+  {-0.230311,-0.298617},
+  {0.770821,0.424980},
+  {-1.662785,-0.094771},
+  {-0.287911,0.475809},
+  {-0.048476,-0.203032},
+  {0.553445,-1.016724},
+  {-0.376555,-0.217766},
+  {0.114631,-0.345042},
+  {-0.593877,0.872006},
+  {0.276043,0.101842},
+  {0.882983,0.102907},
+  {0.001158,-0.755667},
+  {0.047028,-0.324113},
+  {-0.646981,0.918540},
+  {0.291671,0.556886},
+  {-0.137889,-1.529846},
+  {0.298642,-0.279176},
+  {1.768655,-0.293840},
+  {-0.235337,-0.109834},
+  {0.114141,-1.468380},
+  {0.478717,0.202262},
+  {-0.370501,-1.198972},
+  {-0.151985,0.917563},
+  {-0.053941,0.940994},
+  {1.249975,-0.625239},
+  {0.398662,0.117818},
+  {-0.205314,-0.918815},
+  {-0.419043,-0.126397},
+  {-1.290054,0.482208},
+  {0.604014,-0.941747},
+  {0.399735,0.820368},
+  {-0.249355,1.154546},
+  {0.359412,-1.303754},
+  {-0.016680,-1.368714},
+  {0.248771,-0.238636},
+  {-0.263899,0.869256},
+  {-0.369987,-0.283830},
+  {-0.466650,-0.208697},
+  {-1.657492,-0.255177},
+  {0.933283,0.293801},
+  {2.525568,-0.350252},
+  {-0.106274,-0.303690},
+  {-0.411917,1.078396},
+  {-0.386613,-1.306253},
+  {0.971809,-0.252645},
+  {0.155680,0.462985},
+  {-0.520441,-0.015665},
+  {0.566224,-0.363200},
+  {0.858518,-0.442505},
+  {-0.176691,0.428155},
+  {-0.006586,-0.742642},
+  {-0.224886,-0.229415},
+  {1.261164,-0.739608},
+  {-0.669418,-0.283427},
+  {1.069320,-0.425814},
+  {-1.009479,0.708147},
+  {-0.473014,-0.106836},
+  {0.283953,-0.549942},
+  {-0.853421,-0.329629},
+  {-0.464193,0.622219},
+  {-0.087188,-0.801405},
+  {0.500055,0.318167},
+  {1.123225,0.074764},
+  {-0.235380,-0.485006},
+  {-0.714091,0.030128},
+  {-0.239461,-1.534452},
+  {1.116795,-0.824399},
+  {-0.825487,-0.207473},
+  {-0.051835,-0.448793},
+  {0.164883,0.984871},
+  {0.253362,-0.188939},
+  {-0.372140,-0.968723},
+  {0.119889,0.519344},
+  {1.497227,-0.331945},
+  {-1.279538,-0.084243},
+  {1.188019,-0.265337},
+  {0.213106,-1.016021},
+  {0.100412,0.388037},
+  {-0.512935,-0.810146},
+  {-0.598912,-0.689186},
+  {-0.567116,-1.257426},
+  {0.086859,-0.193039},
+  {-0.940346,0.374944},
+  {-0.034308,0.275811},
+  {-0.545470,0.096491},
+  {-0.093181,0.866228},
+  {-1.219487,0.113771},
+  {1.206312,0.106241},
+  {0.892992,-0.849006},
+  {-1.354809,0.769571},
+  {0.735957,0.424012},
+  {-0.565301,0.510339},
+  {-0.899932,0.461990},
+  {1.103376,0.451826},
+  {0.132011,-0.842416},
+  {-0.638797,0.144869},
+  {-0.642707,0.416796},
+  {-0.427401,0.363543},
+  {0.168475,-0.766367},
+  {-0.751506,0.061892},
+  {0.574152,-0.505695},
+  {-0.335072,-0.286006},
+  {-0.834026,0.619608},
+  {0.547215,0.287132},
+  {0.298914,-0.179478},
+  {-0.561363,0.759409},
+  {0.745341,0.945481},
+  {-0.902903,-0.037729},
+  {-0.390261,-0.658194},
+  {0.279026,0.870289},
+  {-0.157925,0.902163},
+  {0.536656,1.220876},
+  {0.488578,0.348556},
+  {-0.531355,0.421049},
+  {0.117253,0.950821},
+  {0.718010,-0.541365},
+  {-0.837644,0.805630},
+  {0.181802,-0.456620},
+  {-1.144830,-0.841213},
+  {0.996041,0.509847},
+  {-0.317890,1.355479},
+  {0.444140,0.143680},
+  {-0.301898,0.640867},
+  {0.655019,0.121403},
+  {-0.515694,1.185059},
+  {0.107950,0.148497},
+  {-0.134465,0.366955},
+  {-0.413694,-0.651129},
+  {-1.609086,-0.006717},
+  {1.545435,0.251703},
+  {-0.413004,-0.506535},
+  {1.058658,-0.827896},
+  {-0.625554,-1.151844},
+  {0.662481,0.578591},
+  {-0.053525,0.667165},
+  {-1.458461,0.403909},
+  {1.438034,1.671089},
+  {0.449605,-0.144770},
+  {-0.211705,0.239155},
+  {0.737903,-0.691716},
+  {-0.892143,-0.156775},
+  {1.022161,0.568443},
+  {-0.895021,-1.159661},
+  {-0.129957,-1.015277},
+  {0.025829,0.618146},
+  {-0.725841,1.354559},
+  {-0.404110,0.239310},
+  {-0.381553,-1.030973},
+  {0.661700,0.726828},
+  {-0.871968,-0.873774},
+  {-0.634683,-1.073318},
+  {-0.190002,0.527019},
+  {0.450145,0.068487},
+  {-0.493345,-0.565194},
+  {-0.067292,-1.089015},
+  {0.311426,-0.162816},
+  {0.696492,-1.081337},
+  {-0.079561,0.192018},
+  {-1.038164,0.001589},
+  {-1.209152,0.260031},
+  {0.517225,0.673063},
+  {-1.070390,0.051018},
+  {-0.172812,-0.518776},
+  {0.246896,0.360236},
+  {1.261445,-1.363637},
+  {-0.249520,0.115168},
+  {-1.039049,1.002534},
+  {0.995219,-0.530594},
+  {0.158186,-0.370508},
+  {0.269083,-0.100298},
+  {0.446531,0.134572},
+  {0.163460,-0.234424},
+  {0.655361,-0.266745},
+  {1.368913,-1.221585},
+  {-0.037131,0.339951},
+  {-0.094642,0.057267},
+  {1.801376,1.555417},
+  {-0.674158,-0.035333},
+  {1.133275,-0.083941},
+  {-0.528994,0.797127},
+  {-0.613801,-0.039986},
+  {0.326418,0.552173},
+  {0.961590,0.195621},
+  {0.164999,-0.415260},
+  {1.123196,-0.173849},
+  {-1.028232,-0.935003},
+  {-0.006582,-0.860200},
+  {0.017667,0.604943},
+  {-0.069771,-0.320669},
+  {0.410253,-0.394301},
+  {-0.464009,-1.065665},
+  {-0.388085,-0.714962},
+  {-0.379551,-0.026035},
+  {-0.465111,0.046714},
+  {0.329026,1.072201},
+  {-0.204617,0.340843},
+  {0.353240,-0.991605},
+  {0.276096,0.606240},
+  {0.180433,0.509623},
+  {0.603712,-1.428401},
+  {-0.288965,0.170324},
+  {0.199499,-0.953213},
+  {0.555000,-0.156563},
+  {-0.332052,-0.212173},
+  {-0.551909,-1.110573},
+  {-0.701355,-0.256082},
+  {0.052215,-0.905251},
+  {0.154667,0.287735},
+  {-0.375212,0.075292},
+  {0.831316,-0.327454},
+  {-0.544062,-0.324524},
+  {0.375690,0.435796},
+  {1.420773,-1.694466},
+  {-0.472987,-0.933482},
+  {-0.295863,1.125223},
+  {1.051997,-0.065696},
+  {-0.318684,-0.268566},
+  {-0.407761,0.906795},
+  {0.611763,-0.834517},
+  {-0.577473,-0.618957},
+  {-0.056931,1.173181},
+  {1.188827,-0.751072},
+  {-0.395580,-0.277524},
+  {-0.286643,-0.821660},
+  {-0.243831,-0.902510},
+  {-0.859681,0.635123},
+  {0.132016,0.648423},
+  {0.176409,-0.202077},
+  {0.916956,-0.416387},
+  {-0.387859,0.270335},
+  {-0.470603,-1.118427},
+  {-0.082099,0.536118},
+  {-0.319736,0.623595},
+  {0.105603,-1.227178},
+  {-0.246468,-0.676755},
+  {-0.137842,-0.198255},
+  {-0.612401,0.267072},
+  {0.140070,0.928564},
+  {-0.276867,-0.692713},
+  {0.330789,0.082247},
+  {-0.310965,0.471960},
+  {-0.638029,-0.130571},
+  {-0.227627,0.371444},
+  {1.447594,-0.579724},
+  {1.434342,1.967624},
+  {-0.533127,-0.360049},
+  {0.090985,0.865811},
+  {1.621069,-0.655068},
+  {-0.107101,0.602642},
+  {-0.678090,-0.200194},
+  {0.631410,0.856782},
+  {0.026655,-0.682962},
+  {1.024181,-2.110779},
+  {-0.329181,-0.015544},
+  {-0.869617,0.964415},
+  {-0.574403,0.639381},
+  {-0.200844,-0.526831},
+  {-0.254985,-0.692828},
+  {-0.627544,0.386942},
+  {-0.594953,0.059818},
+  {-0.728173,0.322703},
+  {-0.125809,-0.264083},
+  {-0.862048,-0.024952},
+  {-0.305275,0.632945},
+  {0.503292,0.276135},
+  {-1.035994,-0.815081},
+  {0.004263,-0.952890},
+  {0.188009,-0.695292},
+  {-0.490270,-0.076733},
+  {-0.847985,1.389987},
+  {0.757101,0.356868},
+  {-0.744715,0.614691},
+  {-1.179587,-1.951262},
+  {0.406179,-0.501517},
+  {-0.567337,0.303614},
+  {-0.351789,1.342365},
+  {1.001646,-0.588464},
+  {-0.751630,-0.865141},
+  {-0.336056,0.681107},
+  {0.181667,-0.648438},
+  {0.661723,-0.599597},
+  {-0.843666,0.930312},
+  {0.610179,0.011804},
+  {0.637391,0.730488},
+  {0.887057,-0.039574},
+  {-0.596744,0.306742},
+  {0.693533,-0.788946},
+  {0.358266,-0.635755},
+  {-0.103668,1.012763},
+  {-0.409437,0.643533},
+  {0.623653,-0.403418},
+  {0.974759,-0.268196},
+  {0.726314,0.552070},
+  {-0.209079,-0.180960},
+  {-0.253123,0.174441},
+  {-0.343619,-0.120766},
+  {0.153239,-1.407465},
+  {0.003501,-0.301579},
+  {-0.565188,1.263652},
+  {0.256238,0.366026},
+  {-0.196671,0.887337},
+  {-0.842150,1.461294},
+  {-0.109778,-0.496130},
+  {0.715528,-0.835101},
+  {-0.091186,1.525347},
+  {1.127749,0.614371},
+  {0.816348,0.223844},
+  {0.088529,0.545457},
+  {0.681807,-0.374392},
+  {0.497116,0.065098},
+  {1.063631,0.330052},
+  {-0.473036,0.034874},
+  {-0.157862,-0.001305},
+  {0.434218,0.197264},
+  {-0.550799,0.054486},
+  {0.973037,0.002784},
+  {0.493822,1.160678},
+  {0.413581,1.777586},
+  {0.337161,0.056664},
+  {-0.209438,-0.856569},
+  {0.312104,-0.137281},
+  {-0.812145,-1.333425},
+  {-0.687317,1.281605},
+  {0.245950,0.130437},
+  {-1.137658,-1.119996},
+  {-0.321589,-0.976619},
+  {1.042918,0.688281},
+  {0.126441,-0.281123},
+  {-0.690719,0.538968},
+  {0.814742,0.984337},
+  {0.800806,1.660842},
+  {0.253362,0.679494},
+  {0.289842,0.084567},
+  {0.065649,-1.313600},
+  {1.285205,0.734431},
+  {0.200443,-0.037244},
+  {1.168457,0.074900},
+  {0.726807,-0.504987},
+  {-0.246237,-0.309694},
+  {-0.030608,0.807033},
+  {-0.040489,-0.022902},
+  {-0.102770,-0.193521},
+  {0.760273,-0.024193},
+  {0.153393,0.638818},
+  {-0.049047,0.072808},
+  {-0.751583,0.168734},
+  {-0.163908,-0.509905},
+  {0.673933,-0.014424},
+  {-0.833475,-1.008629},
+  {-0.590986,-0.105231},
+  {0.643961,0.628600},
+  {0.438267,0.052614},
+  {0.110321,0.046113},
+  {-0.517915,1.355916},
+  {0.868033,-0.159152},
+  {0.371602,-0.857592},
+  {-0.419888,-0.337480},
+  {0.558052,0.219982},
+  {-1.131058,-1.257138},
+  {0.733544,0.933340},
+  {-0.646570,-0.253332},
+  {-0.419020,0.398702},
+  {1.839728,-0.458298},
+  {0.357707,-1.077159},
+  {0.104771,0.546341},
+  {-1.056007,-0.099425},
+  {-0.111075,-2.042791},
+  {0.053667,1.959269},
+  {0.389828,-0.320662},
+  {1.618109,0.681527},
+  {0.103634,-1.050246},
+  {0.915626,0.011762},
+  {1.378525,0.843142},
+  {-0.180366,-1.548472},
+  {0.582354,0.761079},
+  {-0.022354,-0.375777},
+  {-0.465816,-0.153786},
+  {0.803733,1.015041},
+  {-0.844731,-0.505638},
+  {0.629193,-0.387865},
+  {-0.170733,0.143273},
+  {-0.240827,0.231065},
+  {-1.250344,-0.026121},
+  {-0.388932,0.564174},
+  {0.216054,-0.002170},
+  {0.232108,1.522422},
+  {0.519424,-0.502575},
+  {-0.052313,0.444903},
+  {-0.705677,-0.812735},
+  {-1.176015,-1.380785},
+  {-1.723397,-0.849389},
+  {-0.225763,-0.831275},
+  {-0.102199,-0.389384},
+  {0.320482,-0.065426},
+  {0.050518,-0.353202},
+  {0.095464,0.245600},
+  {0.610228,-1.495030},
+  {0.499674,0.301388},
+  {0.079124,-0.689882},
+  {-0.176226,0.270693},
+  {0.591074,-0.395837},
+  {0.962485,1.108556},
+  {-0.376415,1.325772},
+  {1.593700,-1.306007},
+  {-0.669529,0.727318},
+  {0.730542,-0.798588},
+  {-1.006559,-1.222182},
+  {0.105828,-0.657938},
+  {-0.965177,-0.739113},
+  {-0.235450,0.413555},
+  {0.384625,-0.100571},
+  {1.362594,-1.289672},
+  {1.236262,0.729084},
+  {0.648425,-0.684215},
+  {0.986055,-0.194520},
+  {-1.152769,-0.783978},
+  {0.576223,0.548201},
+  {0.097504,-0.259566},
+  {-0.360024,0.723081},
+  {0.607059,-1.003423},
+  {-0.227951,-0.734850},
+  {-0.294650,-1.235194},
+  {0.193334,-1.675714},
+  {-0.767385,0.618813},
+  {0.098473,-1.515022},
+  {0.358150,-0.135228},
+  {1.113325,1.368268},
+  {-0.151595,-0.246173},
+  {-1.570232,-0.023322},
+  {-1.226877,-0.155807},
+  {1.879898,0.177321},
+  {1.050730,-0.192028},
+  {0.075023,0.738806},
+  {0.439378,0.159967},
+  {-0.870739,-0.053774},
+  {-0.613293,1.773483},
+  {1.022477,0.589100},
+  {-1.903232,-0.116118},
+  {0.130492,0.364978},
+  {-0.889512,0.294264},
+  {-0.898750,0.561895},
+  {0.251006,0.804611},
+  {-0.113566,-0.941961},
+  {-0.234088,-0.917563},
+  {-0.250283,-0.288450},
+  {-0.907878,-0.094818},
+  {-0.881149,0.528179},
+  {-1.303454,-0.223259},
+  {0.206582,0.221846},
+  {-1.571029,1.443146},
+  {-0.706678,-0.390482},
+  {0.141913,0.510894},
+  {0.182936,0.421928},
+  {-0.119593,0.561059},
+  {-0.744027,0.428400},
+  {-0.152375,-0.959526},
+  {1.160939,-0.069288},
+  {-0.076280,0.162181},
+  {0.327619,0.155115},
+  {-0.530834,0.574725},
+  {-0.430831,-0.101593},
+  {0.920280,-0.279728},
+  {0.031487,-0.263205},
+  {-0.576176,-0.109081},
+  {0.808516,-0.116405},
+  {1.125426,-0.338095},
+  {-0.908021,-0.070953},
+  {0.115823,0.531403},
+  {0.848018,-0.378923},
+  {-0.380277,-0.804293},
+  {-0.373310,0.893974},
+  {-0.330087,0.948002},
+  {-0.086096,-0.437250},
+  {-0.469167,0.454149},
+  {0.970617,0.231241},
+  {-0.817633,0.825176},
+  {-0.435250,0.430634},
+  {1.683802,0.853621},
+  {1.351207,0.235931},
+  {-0.050678,-0.032962},
+  {-0.355436,0.398207},
+  {-0.678845,-0.389077},
+  {-0.273377,-0.710650},
+  {-1.210956,0.678632},
+  {-0.755085,-0.086894},
+  {-1.100352,0.299255},
+  {-0.035763,0.330123},
+  {0.322939,1.101242},
+  {0.595764,-1.157084},
+  {-1.243325,-0.664861},
+  {-1.663768,-0.505836},
+  {-1.267451,0.873669},
+  {-0.455003,-0.043938},
+  {0.470999,0.538119},
+  {0.579555,-0.717479},
+  {-0.802576,0.421240},
+  {-0.237682,0.488393},
+  {0.862354,0.812298},
+  {0.230856,0.213576},
+  {0.141439,0.509505},
+  {0.206889,0.858483},
+  {0.026078,-0.546219},
+  {0.781592,-0.388893},
+  {-0.123377,-0.794665},
+  {0.068495,1.214323},
+  {-0.714881,-1.054803},
+  {-0.461472,-0.106502},
+  {0.562470,-0.529948},
+  {-0.709943,-1.806260},
+  {0.774827,0.627849},
+  {-0.082874,0.781436},
+  {-0.301659,-0.219263},
+  {0.608640,-0.139735},
+  {-0.786892,-1.283778},
+  {-0.366386,-1.194705},
+  {1.061684,-0.463841},
+  {-0.559144,0.542831},
+  {-0.177584,1.693041},
+  {-0.677950,0.092316},
+  {0.408613,-0.701200},
+  {0.245716,-0.034669},
+  {0.997366,-0.451955},
+  {-0.206925,0.136163},
+  {0.352996,1.213371},
+  {0.148059,0.397297},
+  {1.053839,0.169786},
+  {0.573741,-0.636227},
+  {0.612745,-0.530977},
+  {0.516292,0.150499},
+  {-0.036636,1.234072},
+  {-0.283012,0.155921},
+  {-0.487859,0.275921},
+  {-0.763096,1.543259},
+  {-1.012146,0.104486},
+  {0.648292,0.052648},
+  {1.113207,-1.334106},
+  {1.621335,-0.326147},
+  {0.044245,1.144835},
+  {-0.604862,-0.428931},
+  {0.208504,0.480038},
+  {0.621283,-0.263113},
+  {-0.268506,-1.286471},
+  {-1.190871,-0.981942},
+  {-0.343443,-0.970982},
+  {-0.443971,0.172888},
+  {-0.529676,0.789394},
+  {-0.747990,-0.355262},
+  {0.260979,-0.616260},
+  {-0.364506,0.875792},
+  {0.230262,-0.650448},
+  {-0.157869,-0.224029},
+  {-0.138491,0.273796},
+  {-0.337906,0.142918},
+  {-1.126425,1.012362},
+  {-0.045829,-1.204217},
+  {-0.040201,0.072991},
+  {0.095082,-0.512595},
+  {0.391243,-0.697281},
+  {0.028836,0.470680},
+  {-0.254693,0.317709},
+  {0.527280,0.185890},
+  {0.679726,-0.539661},
+  {0.536096,0.202399},
+  {0.636754,-0.073378},
+  {-1.635579,0.303301},
+  {-0.055276,-0.309005},
+  {-0.377681,-0.618366},
+  {-0.570992,0.899069},
+  {0.318571,-1.082007},
+  {-0.501136,-0.050577},
+  {0.463349,-0.492909},
+  {-0.586518,1.437252},
+  {-1.498805,0.669497},
+  {-0.668884,0.501976},
+  {0.849874,-0.274321},
+  {1.503969,0.089087},
+  {0.495296,-0.282796},
+  {0.643539,-0.319368},
+  {-0.003123,0.503895},
+  {0.448926,0.415716},
+  {1.300971,1.185440},
+  {0.666304,-1.011385},
+  {-0.501095,-0.437884},
+  {0.126722,-0.628526},
+  {0.602820,0.306907},
+  {-1.052462,1.759648},
+  {0.804709,-0.383309},
+  {-0.783674,0.703607},
+  {0.555353,-0.894576},
+  {0.367530,-1.251446},
+  {-0.379656,1.053925},
+  {-0.368063,1.523577},
+  {-0.512766,1.220449},
+  {0.310470,1.126447},
+  {-0.668240,-0.719845},
+  {1.311328,-0.273581},
+  {1.193026,0.758730},
+  {0.011468,0.411093},
+  {0.679916,0.227215},
+  {0.200297,-0.461842},
+  {0.203994,-0.360266},
+  {-1.711995,-0.791191},
+  {-0.587169,-0.795622},
+  {-0.126559,0.539690},
+  {-0.311544,0.215622},
+  {0.624084,-0.939499},
+  {0.451027,0.963659},
+  {0.053951,0.473962},
+  {-0.378173,-0.754404},
+  {-0.483375,0.169867},
+  {0.327772,0.443014},
+  {0.438977,-0.918669},
+  {0.272163,0.913450},
+  {-1.148166,-1.651656},
+  {0.678756,0.022641},
+  {-0.162722,1.419714},
+  {-0.442976,-0.324650},
+  {-0.101127,-0.176612},
+  {-0.257379,-0.900592},
+  {-0.692997,-0.167735},
+  {-0.576470,-1.033809},
+  {0.129483,-0.795888},
+  {-0.091165,-0.991940},
+  {-1.546060,0.754515},
+  {-1.955953,0.823558},
+  {-0.507420,-0.342439},
+  {0.839643,0.549449},
+  {1.041734,-0.351442},
+  {-0.099299,0.427514},
+  {0.396409,0.685967},
+  {1.582812,1.019917},
+  {0.095047,-1.033650},
+  {1.097222,0.232333},
+  {0.235403,0.744469},
+  {-0.956056,-0.248764},
+  {-0.007542,1.351857},
+  {0.829327,0.165330},
+  {1.934778,0.740345},
+  {-0.042057,-0.505659},
+  {0.029940,0.584136},
+  {-0.660522,0.974654},
+  {0.550707,0.625208},
+  {-0.736240,-0.090338},
+  {-0.773422,1.383895},
+  {0.164752,0.971219},
+  {-0.078130,-0.016604},
+  {1.174557,-0.671066},
+  {0.709217,-0.447833},
+  {1.173960,0.447247},
+  {-0.452182,-0.283778},
+  {0.221362,0.238256},
+  {0.438321,1.115051},
+  {0.385345,-0.134963},
+  {-0.116907,-0.452026},
+  {1.326754,-0.143928},
+  {0.377629,0.647795},
+  {0.706637,0.054253},
+  {0.484648,0.233001},
+  {0.559643,-0.014661},
+  {0.442585,0.019897},
+  {-0.481860,0.319169},
+  {-1.873430,-0.373696},
+  {-1.468880,-0.338588},
+  {-0.564341,0.015573},
+  {0.135980,-1.308351},
+  {-0.209918,0.409567},
+  {0.134787,0.555218},
+  {-0.280328,0.229205},
+  {0.356642,0.145734},
+  {1.209981,-0.768739},
+  {0.323467,0.471938},
+  {-0.538486,0.833259},
+  {0.377447,1.471453},
+  {-1.542076,0.534062},
+  {0.308006,-0.915789},
+  {0.667877,0.838388},
+  {-1.325876,-0.147813},
+  {0.049283,-0.409670},
+  {0.822751,-0.324401},
+  {-0.248490,0.044080},
+  {0.397286,-0.527903},
+  {0.267321,0.173917},
+  {0.097825,-0.258165},
+  {0.156112,-0.403906},
+  {-1.493610,-0.584519},
+  {1.035700,-0.624181},
+  {0.193366,0.367275},
+  {-0.591444,-0.918827},
+  {-0.031241,1.199647},
+  {-0.635795,-0.401301},
+  {0.292380,-1.257504},
+  {0.790531,0.283300},
+  {-0.612248,-0.856913},
+  {-0.003711,0.557474},
+  {0.046168,0.504684},
+  {-0.258980,-0.145285},
+  {-0.700174,0.664606},
+  {-1.044332,0.112828},
+  {-1.203219,-0.050509},
+  {-0.098679,0.681808},
+  {0.117978,1.020073},
+  {-0.138431,-0.213658},
+  {-0.373621,0.314261},
+  {-1.125660,0.217905},
+  {0.579220,0.315413},
+  {0.819870,-0.421409},
+  {0.215607,0.366435},
+  {-0.391899,-0.353763},
+  {0.031600,0.391145},
+  {0.779146,-0.001210},
+  {-0.371743,0.236842},
+  {0.044205,0.077276},
+  {-0.029682,0.564854},
+  {-0.803910,0.609822},
+  {0.083413,-0.621601},
+  {-0.569837,-0.201887},
+  {-1.037479,0.198802},
+  {0.870755,-0.457554},
+  {-0.644685,0.562159},
+  {-0.368567,-0.571753},
+  {-0.908622,0.593380},
+  {-0.022836,-0.725834},
+  {-0.212127,0.760100},
+  {0.182831,-0.768164},
+  {1.377295,0.894573},
+  {-0.388203,-1.179584},
+  {-0.366572,0.592177},
+  {-1.357572,1.221986},
+  {-1.467493,1.254612},
+  {0.728275,1.398245},
+  {0.270538,-0.980435},
+  {-0.109704,0.391466},
+  {-0.819701,-0.282182},
+  {-1.576902,-0.264228},
+  {-0.293211,-0.354652},
+  {0.932537,0.499530},
+  {0.124587,0.187973},
+  {-1.182933,0.450079},
+  {0.045172,0.295898},
+  {-0.952133,-0.026615},
+  {-1.077399,1.492134},
+  {2.165598,-0.025851},
+  {0.615697,-0.448814},
+  {0.371116,0.104843},
+  {-0.637342,0.743420},
+  {-0.339935,1.886651},
+  {-0.118879,-0.518939},
+  {-1.136926,0.479470},
+  {0.151684,0.264658},
+  {-0.017438,0.081592},
+  {0.013367,-0.432744},
+  {0.818175,-0.660425},
+  {0.169977,1.246542},
+  {0.046875,-0.572609},
+  {0.971265,1.007843},
+  {0.552874,-0.763970},
+  {0.402362,0.688291},
+  {-0.177514,0.862440},
+  {0.727237,0.600365},
+  {-0.123267,-0.320214},
+  {-0.973245,-1.093332},
+  {-0.622050,0.480692},
+  {0.850534,0.250697},
+  {1.435793,-1.334161},
+  {-0.297031,-1.179966},
+  {0.304224,0.432995},
+  {-0.319411,0.044257},
+  {-0.130799,-0.801940},
+  {0.073259,-0.088438},
+  {-0.115683,0.651869},
+  {-1.284032,0.744815},
+  {-0.572874,1.298015},
+  {0.284922,-0.246805},
+  {0.516957,0.398332},
+  {-0.407991,-0.949022},
+  {0.136622,0.969059},
+  {0.040189,-0.190255},
+  {-0.287121,-0.074766},
+  {-0.610242,-0.365421},
+  {-0.695631,0.472487},
+  {-0.761210,-1.011743},
+  {-0.159401,0.335151},
+  {-0.127480,-2.513513},
+  {-0.621617,-0.001532},
+  {-0.233636,0.540107},
+  {-0.615082,0.740370},
+  {0.728082,-0.745504},
+  {0.755201,-0.364350},
+  {1.455688,0.113219},
+  {-0.384111,1.799205},
+  {-0.060414,0.594761},
+  {-0.645534,-1.282521},
+  {1.354648,-0.365049},
+  {0.700581,-0.261592},
+  {-0.420933,0.412919},
+  {-0.118914,-0.126970},
+  {-0.369305,-0.651979},
+  {0.833302,-0.776442},
+  {-0.889951,0.333417},
+  {0.717829,0.832634},
+  {-0.780598,-0.353698},
+  {-0.126353,0.156872},
+  {-0.870306,-0.186695},
+  {0.188068,-0.272942},
+  {-0.853431,-0.099724},
+  {-0.972554,-0.599254},
+  {-1.109184,-0.599650},
+  {0.911559,0.240889},
+  {-0.351639,-0.044241},
+  {0.189684,-1.491880},
+  {0.667445,-0.069260},
+  {0.369786,-0.124370},
+  {0.521743,-0.479616},
+  {-1.023666,0.709321},
+  {-0.009410,-1.304473},
+  {0.457866,-0.753617},
+  {0.514681,-1.122756},
+  {0.052715,0.047106},
+  {-0.308785,-0.058814},
+  {-0.543798,0.853832},
+  {0.057451,0.111738},
+  {0.023706,0.449120},
+  {0.854094,-2.321072},
+  {-1.288841,0.610626},
+  {1.070943,0.900281},
+  {-0.314136,0.986491},
+  {-0.484965,-0.906231},
+  {-0.534703,-0.786444},
+  {0.529497,0.880418},
+  {-0.594563,-0.523274},
+  {-0.714857,-0.819102},
+  {0.846788,-0.989649},
+  {-0.535982,0.146718},
+  {-0.205090,-1.063691},
+  {0.080422,-1.044347},
+  {0.026911,0.228324},
+  {1.491431,0.321161},
+  {0.661557,-0.309540},
+  {0.438783,-0.302408},
+  {0.264915,1.176531},
+  {0.410967,-0.019055},
+  {0.147043,-0.649251},
+  {0.492513,-0.013112},
+  {0.332999,-0.478951},
+  {0.068906,0.560099},
+  {-0.486798,-0.215182},
+  {-0.415900,0.858515},
+  {0.705293,1.097754},
+  {-0.154359,0.384802},
+  {-0.221449,-0.178315},
+  {-0.575917,0.074498},
+  {0.146447,0.313370},
+  {0.126790,0.398399},
+  {0.289635,-0.126919},
+  {-0.074227,-0.213796},
+  {-0.065885,0.678123},
+  {0.656923,0.499602},
+  {-0.564350,-0.575801},
+  {-0.629272,1.852769},
+  {-0.652193,-1.012536},
+  {0.935159,0.505553},
+  {0.010577,0.401854},
+  {0.400071,0.797892},
+  {-0.638037,0.362640},
+  {-1.348614,-0.440950},
+  {0.377069,-0.621824},
+  {0.782456,0.777046},
+  {0.279392,-0.409277},
+  {-0.093743,-0.882047},
+  {0.432319,-0.202289},
+  {-0.854399,0.269268},
+  {-0.569395,-0.550870},
+  {-1.305619,-0.766131},
+  {0.399734,0.356151},
+  {-0.587518,0.990603},
+  {-0.461472,-0.854095},
+  {-0.776429,1.123592},
+  {-2.094551,0.016854},
+  {-0.852694,-0.164675},
+  {-0.752425,-1.146923},
+  {0.235446,0.097446},
+  {-0.191573,0.584031},
+  {0.036355,0.837690},
+  {0.950405,-0.468673},
+  {0.022319,0.946512},
+  {-0.666949,0.540367},
+  {-0.517209,-0.408994},
+  {-1.497582,1.429821},
+  {-1.424709,-0.265863},
+  {1.067800,-0.018164},
+  {-0.403612,0.521463},
+  {0.520736,0.179845},
+  {1.558446,2.297753},
+  {-0.611957,0.341035},
+  {0.574676,0.189530},
+  {0.258192,-0.367458},
+  {-0.515869,-0.068053},
+  {0.320528,0.981756},
+  {0.756459,0.855889},
+  {-0.436195,0.505209},
+  {-0.197706,-0.042505},
+  {0.570348,-0.442366},
+  {0.618202,-1.234316},
+  {-0.246493,0.145392},
+  {0.249191,0.204177},
+  {-0.504036,-0.337933},
+  {0.265983,0.156993},
+  {1.010411,-0.820082},
+  {0.967946,-1.061406},
+  {-0.994254,0.516854},
+  {0.246911,-1.559882},
+  {-0.224508,-1.563141},
+  {-0.420039,-0.552007},
+  {0.078066,-0.074774},
+  {-0.203336,-0.297024},
+  {-0.109335,0.225023},
+  {1.250758,-0.808705},
+  {-1.025240,0.921113},
+  {0.077180,1.828942},
+  {-0.881796,-0.755137},
+  {-0.091333,-1.279348},
+  {-0.062119,0.378901},
+  {-1.499594,0.831770},
+  {-1.371222,0.612782},
+  {0.282594,0.759345},
+  {0.601033,-0.540685},
+  {0.873884,-2.107622},
+  {-0.413409,1.183102},
+  {0.035613,0.033901},
+  {-0.371701,-0.512521},
+  {-0.390149,0.589897},
+  {-0.421352,-0.052553},
+  {0.213716,-0.657424},
+  {-0.090430,-0.071487},
+  {0.058196,-0.653575},
+  {-0.705436,0.067998},
+  {-0.053729,-0.957150},
+  {-0.271140,0.371048},
+  {1.052676,1.059416},
+  {1.043681,0.143528},
+  {1.356857,0.687629},
+  {0.091930,1.509739},
+  {0.339513,0.792737},
+  {-0.055242,1.281981},
+  {0.029510,0.013582},
+  {-0.120412,0.188881},
+  {-1.249855,-0.851677},
+  {-1.079515,-0.452445},
+  {0.393657,-1.150160},
+  {-0.008601,-0.141600},
+  {0.225137,0.963209},
+  {-0.201913,0.770309},
+  {-0.791302,-0.165032},
+  {0.517454,-1.029753},
+  {-0.607919,-0.209344},
+  {0.527461,-0.735633},
+  {-0.266679,-0.286525},
+  {-1.703636,-1.176549},
+  {-0.200180,0.435851},
+  {0.269835,0.613393},
+  {0.745864,-0.434237},
+  {0.471439,1.529898},
+  {0.363553,-0.002981},
+  {-0.338163,0.906062},
+  {0.883375,-0.307422},
+  {-1.120693,-0.268472},
+  {1.221899,2.130810},
+  {0.141656,0.031991},
+  {-1.233096,0.667534},
+  {0.624299,0.425867},
+  {-0.170222,0.592248},
+  {1.076470,1.444681},
+  {-0.183938,0.142772},
+  {-0.821524,-1.008571},
+  {-0.146813,0.404454},
+  {0.684416,-1.073105},
+  {1.117901,-0.560429},
+  {0.530161,-0.027038},
+  {-0.253069,-1.639337},
+  {-0.717668,-1.081437},
+  {0.653127,0.114892},
+  {0.095271,0.140140},
+  {-0.053616,0.987509},
+  {-0.122837,0.191773},
+  {-0.706302,0.420038},
+  {1.186340,1.028863},
+  {-0.117144,-0.018757},
+  {1.239061,-0.216330},
+  {0.295645,0.318719},
+  {-0.287663,0.752288},
+  {1.436414,1.607598},
+  {-1.174806,0.781807},
+  {0.919130,0.760221},
+  {-1.465950,-0.301338},
+  {-0.028985,0.532472},
+  {0.108693,0.221737},
+  {-0.679071,-0.035699},
+  {0.046814,-1.058415},
+  {0.343905,0.344772},
+  {0.570854,0.524909},
+  {0.315360,0.196929},
+  {-0.434684,1.005404},
+  {-0.404268,0.684464},
+  {-0.747997,-0.269495},
+  {-0.358844,0.247169},
+  {-0.714708,-0.157657},
+  {1.004165,0.448171},
+  {-1.235014,-0.550712},
+  {0.442388,-0.935624},
+  {0.702100,-0.807752},
+  {0.358939,-0.783201},
+  {-1.133754,-0.837761},
+  {-0.467297,-0.165956},
+  {1.008790,0.066224},
+  {-0.272849,0.330043},
+  {-1.966277,1.246796},
+  {-0.917265,-1.017836},
+  {-0.027061,-0.299158},
+  {1.124767,-0.984969},
+  {0.146385,1.049555},
+  {0.558241,0.085019},
+  {-0.158555,-1.463400},
+  {-0.133509,-0.671532},
+  {0.666487,-0.563999},
+  {0.656119,0.119249},
+  {1.041716,0.447584},
+  {-0.025932,0.527085},
+  {-1.593675,-0.940512},
+  {0.218719,0.224522},
+  {0.858700,-0.400714},
+  {-1.323566,-1.320280},
+  {-1.019153,-0.525948},
+  {1.737703,0.326414},
+  {-0.638443,0.055007},
+  {0.086753,0.243740},
+  {-0.885970,0.377519},
+  {1.184245,0.505174},
+  {0.202493,-0.306676},
+  {1.189207,-0.823331},
+  {0.398937,0.120145},
+  {-0.646384,0.314075},
+  {-1.137885,-0.095339},
+  {0.948864,-0.716966},
+  {0.463843,-0.358252},
+  {0.980654,-0.901849},
+  {-1.215558,-0.298514},
+  {0.270095,0.365947},
+  {0.140718,-0.306677},
+  {0.587339,-0.550040},
+  {0.855364,-0.692435},
+  {-0.456061,-0.045239},
+  {0.462259,-0.725169},
+  {0.724895,0.455988},
+  {-1.028200,-0.257751},
+  {-1.072973,-1.142716},
+  {-0.576397,-1.548709},
+  {-0.284426,0.134787},
+  {-1.039392,0.502217},
+  {-0.217312,-0.180047},
+  {0.694919,0.186815},
+  {-0.847320,-1.048344},
+  {-1.022385,-0.565583},
+  {-0.660343,0.410869},
+  {-0.718115,-0.544506},
+  {-0.182651,0.469230},
+  {-0.231679,-0.362006},
+  {-0.015608,0.083363},
+  {1.222271,-0.723882},
+  {-0.508861,-0.822197},
+  {-0.902930,0.636436},
+  {0.112424,-0.324648},
+  {0.315799,-0.188587},
+  {1.024169,-0.474601},
+  {-1.152947,0.595031},
+  {0.902782,-0.236906},
+  {-0.241519,0.977620},
+  {-1.518523,-0.585001},
+  {-0.000930,0.727162},
+  {0.877585,1.068244},
+  {-1.638870,-0.206063},
+  {1.408922,-0.130538},
+  {-0.523389,-0.811424},
+  {0.101777,0.366629},
+  {1.289354,-0.426427},
+  {0.604590,-1.337170},
+  {-0.058429,1.861749},
+  {-0.561091,-0.637419},
+  {0.424127,-0.323688},
+  {-0.081614,-1.449043},
+  {0.968017,0.267704},
+  {0.108011,0.499381},
+  {0.170847,-0.487345},
+  {-0.458183,-0.767461},
+  {-0.039893,0.250217},
+  {0.131645,-1.086087},
+  {0.161841,0.342612},
+  {-1.600553,0.342165},
+  {0.541176,0.414102},
+  {0.409636,0.349951},
+  {1.204189,-1.086040},
+  {0.350477,0.682488},
+  {-0.721238,0.208825},
+  {0.428534,-0.790265},
+  {0.121097,-0.359704},
+  {1.361358,1.230809},
+  {-0.384294,0.472650},
+  {0.145290,-0.174952},
+  {-0.046377,-0.107608},
+  {-0.383656,0.796097},
+  {1.031273,0.264224},
+  {1.167621,-0.300218},
+  {-0.292386,-0.318581},
+  {-0.335417,-1.144967},
+  {-0.648088,-0.289108},
+  {-0.068185,-0.682794},
+  {0.894230,0.285057},
+  {-1.260050,0.086270},
+  {0.247349,0.104827},
+  {0.007993,0.124410},
+  {-0.089590,-0.563814},
+  {1.509332,-1.875702},
+  {-0.076540,1.065093},
+  {0.316001,-0.172131},
+  {0.102151,-0.953328},
+  {-0.190367,0.254101},
+  {0.255213,1.104178},
+  {0.291825,-0.052904},
+  {-1.058847,-0.004168},
+  {-0.293184,-0.372100},
+  {-0.420888,0.496658},
+  {0.646020,0.472691},
+  {-0.568856,-0.424865},
+  {-0.822198,0.342074},
+  {0.566707,-0.906916},
+  {0.880532,-1.481777},
+  {-0.158097,0.395299},
+  {-0.169400,-0.308643},
+  {-0.420999,-0.995964},
+  {-0.134220,-0.451067},
+  {-0.560854,-0.358684},
+  {0.533672,0.609505},
+  {0.225296,-0.259670},
+  {0.136387,1.320238},
+  {-0.143082,-0.656944},
+  {-0.039519,-0.440310},
+  {0.064516,-0.216104},
+  {0.327496,-1.720161},
+  {1.222967,0.133978},
+  {0.344704,-0.992218},
+  {-0.298720,1.336461},
+  {0.910618,0.343415},
+  {0.792131,-0.077562},
+  {-0.078523,0.161363},
+  {0.419388,0.354756},
+  {-1.022862,-0.528513},
+  {0.024169,0.636111},
+  {-0.121226,0.869259},
+  {0.269960,0.147618},
+  {-0.173962,-0.286819},
+  {-0.610308,-0.112641},
+  {1.516570,0.220792},
+  {0.067268,-0.929080},
+  {0.140334,1.330344},
+  {0.126366,-1.081471},
+  {-0.243734,-0.118978},
+  {-0.277617,-1.194380},
+  {-0.682716,0.298833},
+  {-1.288838,1.513837},
+  {-1.077710,-0.288363},
+  {0.353844,0.331654},
+  {-0.496007,-0.449799},
+  {0.674501,-0.901818},
+  {-0.425209,-0.743499},
+  {-0.493533,-0.014724},
+  {-0.126484,-0.166360},
+  {0.321523,-1.190012},
+  {-0.243319,0.253336},
+  {-0.324947,-0.463787},
+  {0.224061,-0.778740},
+  {-0.022366,-0.614416},
+  {-0.104315,-0.614804},
+  {0.416559,0.514345},
+  {-0.380783,-0.071819},
+  {1.224245,-0.170595},
+  {0.668510,0.088242},
+  {0.011928,-0.606299},
+  {-1.276925,-0.185928},
+  {1.427795,0.603522},
+  {-0.687761,-0.603504},
+  {-0.132693,-0.457303},
+  {-0.680173,-0.865798},
+  {-0.251745,-0.935759},
+  {0.444854,-0.248104},
+  {0.068890,0.189164},
+  {-0.218620,-1.194219},
+  {0.102438,0.748316},
+  {0.626796,-0.085816},
+  {0.382283,0.477754},
+  {-0.055020,-0.453327},
+  {-0.629663,-0.255501},
+  {-0.314275,-0.853495},
+  {0.153019,0.700717},
+  {0.819287,0.714535},
+  {0.078689,-0.639930},
+  {-0.470512,-0.225320},
+  {0.479791,0.944982},
+  {1.631216,1.256571},
+  {-0.936889,0.646269},
+  {-0.494894,0.683656},
+  {0.921918,0.268295},
+  {0.561338,0.520386},
+  {0.414373,1.463005},
+  {0.760467,0.214625},
+  {0.964109,-0.139284},
+  {-0.587657,-0.930694},
+  {0.299208,0.117574},
+  {-0.452623,1.080372},
+  {-0.206742,-0.027465},
+  {-0.995999,0.131516},
+  {-0.409115,-1.251451},
+  {0.286588,0.339968},
+  {0.248896,0.976740},
+  {-0.600229,-1.037789},
+  {1.217989,-0.829786},
+  {-0.533772,-0.390166},
+  {-0.252891,0.090843},
+  {0.830241,-0.674900},
+  {-0.305120,-0.830369},
+  {-0.491488,0.649178},
+  {0.438337,-0.155879},
+  {-0.355961,0.587665},
+  {0.504438,0.139915},
+  {0.729127,-0.183104},
+  {0.107723,-0.278060},
+  {0.688445,0.756468},
+  {0.393728,-1.411304},
+  {0.536781,1.086957},
+  {-0.520090,-0.203326},
+  {0.533082,-0.846444},
+  {-0.394528,0.670604},
+  {-0.382789,-0.861758},
+  {0.250303,0.478741},
+  {-0.327998,0.777437},
+  {0.733849,-0.765777},
+  {-0.089826,-1.110802},
+  {-0.206186,-0.678356},
+  {0.386616,0.326163},
+  {0.525415,-1.219435},
+  {0.133794,0.344521},
+  {0.004897,-0.582482},
+  {-0.750436,-0.832588},
+  {1.048079,-0.016272},
+  {1.705627,0.415836},
+  {1.430775,0.468125},
+  {0.131126,-0.137068},
+  {0.835151,-0.271749},
+  {-0.298794,0.661111},
+  {-1.031776,-0.466190},
+  {0.920307,0.012391},
+  {0.714790,0.765926},
+  {0.049065,1.311591},
+  {-0.718093,-0.406004},
+  {0.398720,-1.039662},
+  {-0.246073,0.103843},
+  {-0.710795,0.507890},
+  {0.091547,-0.294237},
+  {1.265596,0.506513},
+  {0.247169,-0.808032},
+  {0.329468,-0.429356},
+  {0.401651,-1.497002},
+  {-0.915131,0.517771},
+  {-0.158804,-1.010671},
+  {0.337866,0.270349},
+  {-0.334280,-0.437324},
+  {0.587549,-0.839959},
+  {0.609462,0.218756},
+  {0.663163,0.295161},
+  {0.199296,-0.011211},
+  {0.336088,-0.804984},
+  {-0.689722,0.139018},
+  {1.805106,0.071002},
+  {0.012271,-0.185305},
+  {-0.242626,1.069228},
+  {-0.001816,-0.770260},
+  {1.082567,-0.538776},
+  {-0.300932,0.408739},
+  {0.673658,-0.546763},
+  {-0.522996,-0.593263},
+  {0.783541,0.018982},
+  {0.129059,1.126919},
+  {0.089440,0.382453},
+  {-0.027288,0.112335},
+  {0.207647,-0.722367},
+  {-0.570810,0.360483},
+  {0.285651,-0.252501},
+  {0.723943,0.093512},
+  {0.112908,0.175056},
+  {-0.488045,0.285721},
+  {-0.059020,-0.037746},
+  {-0.512124,-0.099456},
+  {-0.349365,-0.609648},
+  {0.107796,-0.112698},
+  {-1.477146,0.619852},
+  {0.417878,1.275517},
+  {0.029314,-0.196885},
+  {0.570071,-0.086919},
+  {0.249916,0.287204},
+  {0.383593,0.201145},
+  {0.114623,0.900762},
+  {0.682162,-0.223562},
+  {0.322560,0.917578},
+  {0.750428,0.353774},
+  {-0.948208,0.123629},
+  {0.768450,0.085982},
+  {1.272772,0.309070},
+  {-0.439142,-0.382147},
+  {-0.008128,-1.247159},
+  {0.009078,-0.697620},
+  {0.007060,0.961034},
+  {0.129413,0.505956},
+  {-1.910256,-0.665300},
+  {0.069935,-1.173748},
+  {-0.120057,0.181999},
+  {0.399439,-0.688444},
+  {0.284874,0.541595},
+  {0.285854,0.693654},
+  {-0.001666,-0.103849},
+  {-1.224582,1.329128},
+  {-0.648986,0.890249},
+  {-0.388631,-0.337343},
+  {-0.610412,0.675449},
+  {0.271354,-0.522851},
+  {-0.469737,0.289745},
+  {-0.135145,0.094711},
+  {0.391914,0.360719},
+  {-1.432849,-0.395919},
+  {0.718524,0.095473},
+  {0.971875,0.020463},
+  {0.321075,1.646243},
+  {-0.198847,-0.236427},
+  {1.874800,-0.097315},
+  {-0.243075,-0.495529},
+  {0.920510,0.609915},
+  {0.471311,-2.079300},
+  {-0.581785,-1.219514},
+  {-0.280604,0.335288},
+  {0.744908,1.156712},
+  {1.065821,1.187737},
+  {0.063306,0.219678},
+  {0.149226,0.523140},
+  {-0.223783,-0.203258},
+  {-0.453659,-0.055288},
+  {-0.577265,0.580418},
+  {-0.394131,0.807998},
+  {-0.805989,0.389628},
+  {0.497947,0.244122},
+  {0.156364,0.586017},
+  {-0.824797,1.008399},
+  {0.152007,-1.426285},
+  {0.515238,0.477685},
+  {-0.477381,0.117855},
+  {-0.950519,-1.318016},
+  {0.420935,0.940154},
+  {-1.026912,-0.466710},
+  {-0.582401,0.139818},
+  {-0.549374,-0.236186},
+  {0.644767,-0.465686},
+  {0.830889,-0.265762},
+  {-0.144430,-0.761845},
+  {-0.128806,-1.521828},
+  {-0.372228,-0.069244},
+  {-0.492768,0.219460},
+  {-0.490296,0.354823},
+  {-0.848195,0.898729},
+  {0.865969,-0.571089},
+  {-0.454317,0.699749},
+  {0.042831,-0.315084},
+  {-0.285471,-0.292725},
+  {-0.534360,0.172237},
+  {0.689555,0.264977},
+  {0.815292,-1.505314},
+  {0.497006,-0.098925},
+  {0.298728,0.364288},
+  {0.136240,0.303815},
+  {0.283923,0.596503},
+  {0.114502,-0.238589},
+  {-0.297723,0.385486},
+  {-0.316969,0.430939},
+  {0.040942,-0.313941},
+  {-0.289333,0.351903},
+  {0.896973,0.079274},
+  {-0.268520,0.041966},
+  {1.030958,-0.635246},
+  {-1.875177,0.592061},
+  {-0.430594,-0.653622},
+  {0.267462,0.655383},
+  {-0.514834,1.076798},
+  {-0.097106,0.538920},
+  {0.013117,0.662483},
+  {0.644666,0.595031},
+  {-0.117338,0.439290},
+  {-0.357636,-0.677673},
+  {-0.088865,-0.231393},
+  {0.965777,-0.113227},
+  {0.220975,0.768523},
+  {-0.828622,0.050192},
+  {-0.240097,-0.029707},
+  {-1.058309,1.038959},
+  {-0.570250,-0.924301},
+  {-0.262456,-1.462101},
+  {-1.228857,-0.142778},
+  {0.469875,0.739288},
+  {1.100930,0.341907},
+  {0.672967,-0.393436},
+  {0.518804,0.496781},
+  {-0.142314,0.761519},
+  {0.125922,-0.550510},
+  {-0.348100,-0.273610},
+  {-0.427612,0.061501},
+  {0.256513,0.747116},
+  {-0.059648,0.168510},
+  {-0.913990,0.875762},
+  {-0.802038,0.135093},
+  {0.203664,-0.374754},
+  {0.469188,-0.636419},
+  {0.809588,0.460623},
+  {0.113743,0.524456},
+  {-0.272354,-0.854766},
+  {0.022865,0.418124},
+  {-0.133409,0.060661},
+  {1.539998,-0.517456},
+  {-0.645522,-0.426623},
+  {-0.371401,-0.661202},
+  {-0.122534,1.261750},
+  {0.093323,-0.383381},
+  {0.134252,0.902849},
+  {0.511477,1.313929},
+  {0.099273,0.514895},
+  {-0.058003,0.969434},
+  {-0.141294,-0.471783},
+  {-0.429620,-0.154513},
+  {-0.287361,-0.442306},
+  {-0.336878,-0.062789},
+  {-0.605904,0.102936},
+  {-0.142869,-0.443398},
+  {1.535686,1.529627},
+  {0.367539,0.095620},
+  {0.212680,0.531485},
+  {0.604709,-0.251699},
+  {-0.161790,-0.242223},
+  {-0.575133,0.475413},
+  {0.007935,0.138656},
+  {-0.156317,0.351535},
+  {1.107248,1.232089},
+  {-0.269558,0.504884},
+  {0.074465,-0.942669},
+  {0.141073,-0.429191},
+  {-0.269876,0.330541},
+  {-0.209983,0.505994},
+  {0.562585,1.614445},
+  {0.439637,-1.675931},
+  {0.030853,-1.163880},
+  {0.304423,1.022936},
+  {-0.327022,-0.504994},
+  {1.936745,-1.338733},
+  {-0.351500,-0.385984},
+  {-0.563641,-0.826557},
+  {-0.380570,0.789590},
+  {-0.148708,0.255027},
+  {-0.888800,-1.395291},
+  {0.632760,-0.463043},
+  {0.234656,0.303244},
+  {0.116743,-0.473395},
+  {0.271851,0.175900},
+  {-0.552514,-0.338339},
+  {0.691982,0.143707},
+  {-0.976338,0.662087},
+  {-0.504830,0.685742},
+  {-0.264117,-0.307242},
+  {0.511863,0.356987},
+  {0.055412,-1.049023},
+  {0.191737,0.267756},
+  {0.231510,-1.056609},
+  {0.204476,-0.636612},
+  {-0.133734,1.938848},
+  {0.255605,-1.483930},
+  {1.011052,1.161027},
+  {0.898627,0.805878},
+  {-0.213312,0.436263},
+  {0.755626,0.187831},
+  {-0.762523,0.657359},
+  {0.036146,0.739059},
+  {-0.116160,-0.417153},
+  {-0.150632,-0.670163},
+  {0.418430,-0.878027},
+  {0.525073,-0.538173},
+  {-0.370425,-1.117374},
+  {-0.757346,0.213995},
+  {-0.208166,-0.014412},
+  {1.041135,-0.440021},
+  {0.745159,-0.655492},
+  {0.075926,-0.175046},
+  {-0.667127,-1.402322},
+  {-0.420118,-0.660770},
+  {-0.911100,-0.316687},
+  {-0.103679,0.220340},
+  {-0.660715,-0.765549},
+  {-1.825846,0.383159},
+  {-0.802056,-0.280138},
+  {-0.373981,0.538737},
+  {-0.426700,0.773436},
+  {-0.163357,0.074898},
+  {1.227122,1.422060},
+  {1.288474,-0.542456},
+  {-1.032935,0.639189},
+  {0.437950,-0.087142},
+  {0.475027,-0.968816},
+  {0.165371,0.564307},
+  {-0.510503,-0.411686},
+  {-1.231209,-0.637638},
+  {1.256137,-0.449882},
+  {-1.522424,-0.184787},
+  {-1.028042,0.985088},
+  {1.030749,-0.439651},
+  {-0.387196,0.411551},
+  {1.188856,0.408318},
+  {-0.587327,-0.142216},
+  {1.135026,-0.262557},
+  {-0.508316,-0.762131},
+  {-0.149100,0.280352},
+  {-0.951866,0.279302},
+  {-0.604205,-0.672315},
+  {1.600248,-0.457873},
+  {0.569092,0.161693},
+  {-1.152617,0.488698},
+  {0.409741,0.570698},
+  {-0.507684,-0.112046},
+  {-0.748483,1.030598},
+  {-0.076532,-0.294944},
+  {0.270334,-0.074069},
+  {0.758352,0.152663},
+  {-1.269700,0.914973},
+  {-0.730966,0.274066},
+  {-1.529546,-0.878928},
+  {-1.992355,-0.301284},
+  {-0.645659,0.223827},
+  {-1.002499,0.318252},
+  {0.165309,-0.639122},
+  {-1.019766,0.307431},
+  {0.679903,-1.055646},
+  {-0.003741,0.179578},
+  {0.256276,0.808911},
+  {1.114403,-1.010407},
+  {-1.146745,-0.331667},
+  {0.404155,0.383710},
+  {-0.237773,0.921262},
+  {1.885775,0.430458},
+  {-0.818223,0.346674},
+  {-0.078311,0.863722},
+  {-0.428592,0.254773},
+  {0.534155,0.809113},
+  {1.383017,0.888617},
+  {-0.515986,-0.599548},
+  {0.212821,-0.000715},
+  {-1.206773,0.526967},
+  {0.014093,0.006118},
+  {0.158839,-1.216860},
+  {-0.027659,0.926053},
+  {0.019575,0.165710},
+  {0.197453,-0.230582},
+  {1.261566,0.802630},
+  {0.197086,0.008144},
+  {0.059366,-1.335864},
+  {0.762630,0.316835},
+  {0.094044,0.216878},
+  {-0.061064,0.344751},
+  {1.017651,-1.442284},
+  {0.827257,0.377237},
+  {-1.187013,-0.462500},
+  {0.582280,-0.502331},
+  {0.744537,-1.480232},
+  {-0.629860,0.197390},
+  {0.059392,-0.392031},
+  {-0.574393,0.117983},
+  {0.129667,-0.171614},
+  {-0.108789,-0.144976},
+  {-0.289720,0.028863},
+  {-0.236768,0.375456},
+  {-0.026387,-0.120244},
+  {-0.494994,1.099108},
+  {-0.243313,-0.271767},
+  {0.887063,-0.199488},
+  {-1.520577,0.158127},
+  {1.002710,-0.502214},
+  {-0.690706,-0.243567},
+  {-1.318276,-0.321401},
+  {-0.458306,-0.366136},
+  {-0.120988,0.372985},
+  {-0.278336,0.750513},
+  {-0.430248,0.203486},
+  {-0.431980,0.898660},
+  {0.147149,0.183560},
+  {-0.761892,-0.033976},
+  {0.544541,0.195048},
+  {-1.004320,0.048136},
+  {0.445875,0.124557},
+  {0.819350,0.116228},
+  {-0.074228,-0.359250},
+  {0.149207,0.639891},
+  {0.338190,0.705314},
+  {0.771753,0.452919},
+  {0.713768,-0.325439},
+  {0.792008,0.244063},
+  {0.619732,-0.670480},
+  {-0.192255,-0.539623},
+  {-0.071555,0.106152},
+  {-0.531400,0.439331},
+  {0.858087,0.454744},
+  {-0.324386,-0.432407},
+  {-0.049221,-0.765374},
+  {0.524452,0.531419},
+  {0.003815,0.508387},
+  {-0.841803,-0.132345},
+  {-0.251592,0.174575},
+  {0.134064,-0.846480},
+  {-0.380022,-0.772825},
+  {0.570028,0.455106},
+  {0.685860,0.878152},
+  {0.349189,-0.979386},
+  {-0.870929,0.582146},
+  {-0.970770,-0.902920},
+  {1.432578,0.124514},
+  {-1.833284,0.491911},
+  {-0.632608,0.655085},
+  {-0.587920,-0.340920},
+  {-0.688839,-0.890105},
+  {0.453233,-1.036321},
+  {1.020132,0.523791},
+  {0.951761,0.683777},
+  {-1.376582,1.527485},
+  {0.236742,-1.750241},
+  {-0.460403,0.501992},
+  {1.020721,0.229132},
+  {1.051587,-0.362471},
+  {-0.259974,0.863537},
+  {0.429171,1.050911},
+  {0.191844,0.578415},
+  {-0.231841,0.432569},
+  {-0.984387,-0.084837},
+  {-0.358412,0.102102},
+  {0.878619,0.582503},
+  {-0.205932,0.835352},
+  {-0.103196,-0.742711},
+  {1.284650,-0.553309},
+  {-0.438278,-0.845167},
+  {-0.180808,-0.562684},
+  {-1.415280,0.309014},
+  {1.032654,1.546299},
+  {-0.578971,0.502129},
+  {-0.372922,0.342322},
+  {-0.601495,-0.396972},
+  {0.449218,1.693786},
+  {-0.215480,-0.912576},
+  {-0.305294,-0.068039},
+  {1.234584,0.890927},
+  {-0.133936,-0.401511},
+  {-0.029240,-0.508774},
+  {-0.446670,0.056391},
+  {0.438196,0.121282},
+  {-0.235203,-0.016227},
+  {0.085158,0.853693},
+  {0.589462,-0.003206},
+  {-0.347001,1.098295},
+  {-0.482088,0.276294},
+  {1.115959,0.104063},
+  {1.222275,-0.122048},
+  {1.131900,-0.401884},
+  {0.416713,0.972292},
+  {0.268957,0.822470},
+  {-0.378075,-0.239070},
+  {0.678130,-0.622487},
+  {0.001222,0.176722},
+  {0.515715,0.556026},
+  {-0.811341,-0.664363},
+  {-0.066931,-0.106832},
+  {0.259630,-0.482719},
+  {-1.051136,0.675293},
+  {-0.444388,-0.119788},
+  {0.307477,-0.014828},
+  {-0.184077,0.282394},
+  {-0.719949,0.155395},
+  {0.689853,0.466149},
+  {0.254500,-1.065029},
+  {-1.153940,1.026575},
+  {-0.724639,0.811474},
+  {0.280946,0.774506},
+  {1.733286,0.702247},
+  {0.057015,-0.144861},
+  {1.201717,-0.620823},
+  {-1.489848,-0.513420},
+  {0.007687,0.478682},
+  {0.217798,-0.381518},
+  {0.395505,0.487883},
+  {0.637114,0.738214},
+  {-0.696254,-0.017240},
+  {-0.601473,-0.310016},
+  {-0.911395,-0.423135},
+  {0.943762,0.871834},
+  {0.712787,-0.214152},
+  {-0.154493,0.356730},
+  {0.439694,2.528324},
+  {0.511167,-0.597179},
+  {-1.077821,1.509451},
+  {0.534645,-0.031730},
+  {0.367335,-0.235827},
+  {-1.523038,0.527418},
+  {0.337825,-0.714982},
+  {-0.447831,-0.426621},
+  {-1.118101,-0.239219},
+  {0.531552,0.943312},
+  {-1.294295,-0.742653},
+  {0.625772,0.643434},
+  {-0.277690,-0.187306},
+  {0.253799,-0.294410},
+  {-0.613186,0.208064},
+  {-0.188373,-0.612828},
+  {0.217985,-0.165977},
+  {0.588750,0.477662},
+  {-0.901009,-0.304080},
+  {-1.010997,0.557475},
+  {-0.375059,-0.290759},
+  {0.071666,-0.579673},
+  {0.210535,0.735150},
+  {-0.448087,-0.526083},
+  {0.398716,0.065340},
+  {0.485392,1.369999},
+  {-0.299177,-1.126727},
+  {-0.103942,0.680101},
+  {0.328730,0.178544},
+  {0.142174,0.134296},
+  {0.204866,-0.912750},
+  {-2.020140,0.645009},
+  {0.177036,-0.288237},
+  {-0.069950,1.225832},
+  {-0.304805,0.134353},
+  {-1.765184,-0.128221},
+  {-0.393885,-0.444420},
+  {-1.330829,0.743254},
+  {0.830278,0.671366},
+  {0.869670,-0.919906},
+  {1.211946,-1.221721},
+  {0.363820,0.389598},
+  {-0.613657,-0.172961},
+  {0.534523,-0.777950},
+  {0.899525,0.837620},
+  {0.229674,0.539808},
+  {-0.588145,1.541271},
+  {0.526527,0.218288},
+  {0.108346,-0.146209},
+  {0.256885,0.222342},
+  {-0.471906,-0.622017},
+  {-1.040667,-1.033413},
+  {1.262585,0.812615},
+  {-0.109457,1.184248},
+  {-0.777400,-1.560435},
+  {0.151619,-0.442552},
+  {1.678563,0.504373},
+  {-0.589008,-0.440073},
+  {-0.173452,0.875637},
+  {-0.330927,-0.861614},
+  {0.529098,0.754519},
+  {-0.530484,0.361856},
+  {-0.340118,-0.014196},
+  {-0.443443,-0.221920},
+  {-0.295703,0.775663},
+  {0.931839,0.391841},
+  {1.227308,0.357324},
+  {1.058906,-0.561328},
+  {0.379099,0.857939},
+  {0.379845,0.088003},
+  {2.175076,0.202864},
+  {0.100406,-0.297335},
+  {0.240141,-0.401507},
+  {0.578608,0.265995},
+  {-0.515623,0.946173},
+  {-0.587795,-0.555286},
+  {0.383657,-0.195416},
+  {0.759589,-0.774641},
+  {-0.109808,-0.123684},
+  {0.172620,1.054034},
+  {0.231130,1.353771},
+  {0.832332,-0.629704},
+  {0.736182,-0.815986},
+  {1.913341,-0.066831},
+  {0.548944,0.930218},
+  {1.187104,0.054595},
+  {-0.065391,1.307484},
+  {-1.032659,-0.304898},
+  {0.770218,0.384590},
+  {-0.461868,0.279681},
+  {0.659794,1.167296},
+  {-0.280067,1.596266},
+  {-0.557632,-1.620087},
+  {0.231064,0.159401},
+  {-0.585902,-0.632748},
+  {-1.008761,0.180220},
+  {-2.136943,0.182556},
+  {0.578714,-0.151526},
+  {0.468830,-0.370074},
+  {-0.124409,0.101686},
+  {-0.623913,0.511890},
+  {0.603725,-0.110424},
+  {0.086402,0.305489},
+  {0.397162,-0.844066},
+  {0.287331,0.595819},
+  {0.435615,-0.308301},
+  {-1.631188,1.233723},
+  {-0.099963,-0.568243},
+  {-0.069033,-0.553885},
+  {0.465490,1.705170},
+  {-1.502903,0.051838},
+  {0.202618,0.056840},
+  {0.690444,0.625482},
+  {0.529718,-0.327767},
+  {-0.489490,-0.609651},
+  {0.832393,1.453277},
+  {1.712547,0.803720},
+  {0.189576,-1.727333},
+  {0.907285,-0.228063},
+  {1.339552,-0.868890},
+  {-1.166663,-1.224587},
+  {-0.379674,0.609648},
+  {-0.573722,-0.147682},
+  {-0.268252,-0.294019},
+  {-0.342327,0.622820},
+  {-0.973481,1.055302},
+  {0.765404,-0.814623},
+  {-0.533027,-1.451319},
+  {-0.272482,1.012991},
+  {-0.542893,-1.562890},
+  {-0.171077,0.717300},
+  {0.308168,0.116356},
+  {0.314240,-0.370956},
+  {0.804733,-0.334112},
+  {0.386616,-0.027912},
+  {-0.099513,0.902143},
+  {-0.123303,0.843877},
+  {1.079426,-0.071035},
+  {0.598008,-0.248097},
+  {0.573794,0.625676},
+  {0.290775,0.601791},
+  {-0.846620,-0.609600},
+  {0.441754,0.374976},
+  {-0.292908,-0.310313},
+  {0.389009,-1.122842},
+  {-1.994184,-0.597685},
+  {-0.288490,-0.137211},
+  {0.826802,-0.414513},
+  {0.440020,-0.030550},
+  {-0.776099,-0.389480},
+  {0.554564,0.554801},
+  {1.224902,0.286133},
+  {-0.979788,0.109225},
+  {1.253196,0.209456},
+  {0.251155,0.753947},
+  {0.665114,-0.393747},
+  {-0.564377,-0.513027},
+  {1.288081,-2.157011},
+  {0.235869,0.471166},
+  {-0.406039,0.027257},
+  {-0.294357,-0.382251},
+  {0.119859,-0.100326},
+  {-0.458593,0.981385},
+  {1.025987,-0.633064},
+  {0.615666,1.604773},
+  {0.594899,-0.462359},
+  {0.309323,0.834967},
+  {1.020212,0.969725},
+  {-0.195893,-0.386131},
+  {-0.627758,0.223954},
+  {-1.018009,0.285884},
+  {-0.624008,0.485126},
+  {0.160685,-0.253051},
+  {-1.063582,1.681213},
+  {-0.198088,-0.757754},
+  {0.728279,0.034337},
+  {0.762127,-0.032588},
+  {0.221347,-0.818478},
+  {0.269797,-1.110743},
+  {-1.210268,-0.495728},
+  {0.485286,-0.320922},
+  {-0.155302,0.041326},
+  {-0.402684,1.638042},
+  {-0.478496,-0.696576},
+  {0.857587,-0.932290},
+  {-0.479103,-1.444577},
+  {0.106673,0.771573},
+  {0.174064,0.228316},
+  {0.379493,0.761051},
+  {-0.573243,-0.279958},
+  {0.611776,0.691011},
+  {0.437668,0.574424},
+  {1.270251,0.249666},
+  {0.164892,0.358455},
+  {0.667730,1.155659},
+  {0.466743,0.958982},
+  {-0.728237,-0.561067},
+  {-0.191912,0.053633},
+  {-0.319731,-0.092707},
+  {-0.675490,0.366198},
+  {0.535741,-1.151621},
+  {-0.343547,0.839867},
+  {0.751048,-1.498414},
+  {1.666151,-0.356844},
+  {0.042997,0.353855},
+  {0.599371,0.374659},
+  {-0.030844,-0.467997},
+  {0.527571,-0.170217},
+  {1.039629,0.511229},
+  {0.139445,-0.375293},
+  {-0.643767,-0.579323},
+  {-0.213417,0.056574},
+  {0.868315,-0.291497},
+  {1.312809,0.661863},
+  {-0.239329,-0.350563},
+  {0.055933,1.334509},
+  {-0.896131,1.594030},
+  {-0.843781,-1.287317},
+  {0.346229,-0.350082},
+  {-0.385374,-0.165116},
+  {0.058133,-0.170327},
+  {-0.302902,-0.091267},
+  {-0.224982,-0.275217},
+  {-0.639219,0.182658},
+  {1.005439,0.970002},
+  {0.302856,0.157512},
+  {0.167572,0.392681},
+  {-0.183465,-0.536818},
+  {-0.276488,0.932653},
+  {-0.698586,-0.291830},
+  {-0.663474,0.073177},
+  {-0.707151,0.843712},
+  {0.813781,-0.237099},
+  {-0.567100,-0.155201},
+  {-0.695440,0.900429},
+  {-0.507948,-0.238936},
+  {0.813905,-1.435846},
+  {-1.030962,0.416183},
+  {0.010413,-0.077815},
+  {-0.456217,0.939060},
+  {-0.280898,0.860698},
+  {-1.059189,-0.026381},
+  {0.418985,0.103886},
+  {0.243547,0.263705},
+  {1.022534,-0.870284},
+  {-0.319105,-0.830518},
+  {0.309283,0.131609},
+  {-0.366955,0.545398},
+  {-1.091913,0.803764},
+  {0.919995,-1.444688},
+  {-0.514388,-0.892124},
+  {0.046488,-0.043293},
+  {-0.097040,-0.142277},
+  {-0.621773,0.278483},
+  {-0.238226,-0.303143},
+  {-0.239201,-0.202993},
+  {0.828891,-0.447296},
+  {-0.814409,-0.762757},
+  {0.317636,-0.775188},
+  {-0.704665,-0.001095},
+  {0.190795,-0.410853},
+  {0.438536,0.007221},
+  {-1.275473,1.581711},
+  {-1.032641,0.427879},
+  {0.043270,0.560571},
+  {-0.310790,-0.295852},
+  {-0.322617,-0.582956},
+  {-0.823786,0.792678},
+  {-0.825312,0.460310},
+  {-0.142982,-0.231356},
+  {-0.107885,0.006865},
+  {-0.428315,-0.575707},
+  {-0.451766,-1.312755},
+  {-0.605263,0.052154},
+  {-0.858527,0.472405},
+  {-0.147632,0.851068},
+  {-0.032356,-0.398183},
+  {-0.601653,-0.044037},
+  {0.037578,0.212620},
+  {0.475474,0.577324},
+  {-1.937575,-1.393675},
+  {0.241383,-0.543812},
+  {0.300632,-0.384921},
+  {0.860763,0.252422},
+  {0.040594,-0.371765},
+  {0.552900,0.011664},
+  {-0.353449,0.312965},
+  {0.857064,1.235445},
+  {-0.408279,-0.576770},
+  {0.133850,-0.708734},
+  {0.979223,1.697775},
+  {-0.859229,-0.252335},
+  {-1.136499,-0.537318},
+  {-0.025246,0.178310},
+  {1.169886,-0.131893},
+  {0.491317,-0.071596},
+  {1.485336,-0.526005},
+  {1.948320,-0.173133},
+  {0.359882,-0.593865},
+  {0.784955,0.290084},
+  {-0.367032,0.564664},
+  {-0.053053,0.166978},
+  {0.576522,-1.319649},
+  {0.593626,-0.037716},
+  {0.330368,0.727155},
+  {0.248306,0.837877},
+  {-0.596916,-0.440271},
+  {-0.031691,0.753502},
+  {-0.427416,1.496483},
+  {0.024830,0.428486},
+  {-0.251342,-1.094742},
+  {0.345125,-0.553380},
+  {-0.898429,-0.026258},
+  {0.712027,0.447699},
+  {-1.220289,-0.815846},
+  {0.262894,0.251074},
+  {-0.136647,0.183869},
+  {0.404985,-0.461170},
+  {0.431711,-1.281842},
+  {0.163396,0.332593},
+  {-0.552892,0.335223},
+  {-0.672727,-0.000601},
+  {0.044287,0.469885},
+  {0.199923,0.345696},
+  {0.723835,-0.177781},
+  {-0.379719,0.397453},
+  {-0.641487,1.511009},
+  {0.061980,0.031751},
+  {-0.844554,0.892103},
+  {-0.715934,-1.294866},
+  {0.173878,-1.451147},
+  {0.564775,-0.224633},
+  {-0.475705,0.218131},
+  {1.368321,2.155638},
+  {-0.559571,-0.151806},
+  {0.367671,-1.069871},
+  {-0.480085,-0.683981},
+  {-0.968596,-0.196502},
+  {0.088215,-0.398611},
+  {0.089681,0.049280},
+  {0.019565,0.640091},
+  {0.804096,-0.312743},
+  {-0.029222,-0.817238},
+  {0.111560,0.026803},
+  {1.124348,-0.247172},
+  {0.828146,-1.297903},
+  {0.584710,1.072408},
+  {-1.079120,0.519528},
+  {-0.559623,-2.083301},
+  {-0.013739,0.168279},
+  {0.094835,-0.001691},
+  {-0.176566,-0.071756},
+  {0.143178,0.023358},
+  {-1.209996,-0.402923},
+  {0.502949,-0.787258},
+  {-0.439794,-0.826874},
+  {0.037231,-0.182201},
+  {0.559047,-0.316920},
+  {1.353808,-0.063423},
+  {-0.184105,-1.087707},
+  {0.520159,0.016875},
+  {0.408005,0.337109},
+  {0.012034,-0.141686},
+  {-0.116381,0.989265},
+  {0.215828,-0.819388},
+  {-0.175628,0.230390},
+  {-0.392693,-0.773533},
+  {0.019304,0.018939},
+  {0.019620,1.129002},
+  {-0.266461,0.476351},
+  {-0.932192,-0.308265},
+  {1.087973,0.187229},
+  {0.878040,0.274679},
+  {-0.967149,-1.149465},
+  {0.110062,-0.288712},
+  {0.410077,0.016828},
+  {-1.137827,0.737936},
+  {0.556373,0.712373},
+  {-0.136341,-0.106141},
+  {0.966315,0.131986},
+  {-1.636164,0.243468},
+  {1.058806,-0.648276},
+  {0.211281,1.021837},
+  {-0.200606,0.108194},
+  {0.343630,0.685307},
+  {0.492227,-0.038799},
+  {0.033762,0.584277},
+  {0.236607,0.567255},
+  {0.680730,0.758640},
+  {-1.029663,1.126743},
+  {-1.572466,-0.113236},
+  {-0.285795,0.080142},
+  {-0.974205,-0.403896},
+  {1.117339,-0.485668},
+  {-0.600984,-1.054548},
+  {0.893469,-0.995996},
+  {1.668182,-0.272915},
+  {-0.209205,0.453159},
+  {0.256428,-0.019136},
+  {0.333610,0.511375},
+  {-1.232951,0.873284},
+  {-0.761203,-0.368131},
+  {-0.518450,-1.168993},
+  {0.742393,-0.718962},
+  {0.449123,0.250070},
+  {0.014006,-0.412005},
+  {-0.680747,-0.172112},
+  {0.116133,-0.562759},
+  {0.460738,-0.656872},
+  {0.650550,0.619822},
+  {0.131879,0.424197},
+  {-0.553638,-1.742206},
+  {0.312592,0.469697},
+  {-0.531606,-0.391612},
+  {1.380083,1.445451},
+  {-0.921923,-0.915796},
+  {-1.153275,0.556598},
+  {-0.161191,0.501045},
+  {-0.702263,-0.058096},
+  {0.560614,0.671590},
+  {0.036180,-0.376868},
+  {-0.588677,0.721655},
+  {0.621821,-0.164663},
+  {0.794529,0.699955},
+  {-0.719335,0.651360},
+  {0.148510,0.760655},
+  {-0.114731,0.951111},
+  {0.895827,0.383900},
+  {-0.746435,0.641606},
+  {-0.421358,0.631822},
+  {0.466984,-0.324033},
+  {0.489916,-0.957898},
+  {0.079711,0.062274},
+  {1.246410,-0.778342},
+  {-0.318010,0.318632},
+  {0.510297,-0.392028},
+  {1.251361,1.171531},
+  {0.293846,0.756420},
+  {-0.909834,-1.088653},
+  {0.185629,-0.928923},
+  {-0.192179,0.381852},
+  {0.128132,-0.618807},
+  {1.135265,1.096902},
+  {1.130910,0.031333},
+  {0.189199,-0.530720},
+  {0.364752,0.516586},
+  {-0.640494,-0.438013},
+  {-0.554450,0.002218},
+  {-1.568253,-0.283404},
+  {0.597701,-0.124230},
+  {1.153399,0.400638},
+  {0.290154,-0.118022},
+  {-0.394926,0.335760},
+  {-0.046594,-1.272174},
+  {0.520793,-0.596359},
+  {0.684737,1.409372},
+  {2.146829,-0.595201},
+  {0.334683,0.150969},
+  {0.037160,0.579834},
+  {0.559788,-1.024755},
+  {-0.268161,-1.685690},
+  {-0.777837,0.327112},
+  {-0.628273,-0.114822},
+  {-2.163572,0.843763},
+  {-0.523453,1.909596},
+  {-0.390204,0.742400},
+  {0.184483,-0.248507},
+  {0.492118,0.308610},
+  {0.809920,-0.427897},
+  {0.210169,-0.601697},
+  {0.065808,-0.422819},
+  {-1.259986,0.023207},
+  {-1.222129,0.568027},
+  {-0.255664,-0.612253},
+  {0.228229,0.962349},
+  {-1.340872,1.427331},
+  {-0.567869,-1.869379},
+  {-0.763201,-0.271214},
+  {-1.445104,0.226024},
+  {-0.645348,0.310639},
+  {-0.516378,0.457223},
+  {0.261481,-0.723054},
+  {0.698503,-0.491313},
+  {0.002835,0.081625},
+  {-1.025465,-0.176307},
+  {-0.479908,0.644662},
+  {-0.748698,-0.134649},
+  {0.463082,-1.921004},
+  {0.586063,-2.033114},
+  {-0.458925,0.394895},
+  {-0.509606,0.005512},
+  {-0.447751,-1.910113},
+  {-1.557059,-0.149125},
+  {0.534921,-0.429562},
+  {0.211883,0.620042},
+  {-1.527148,0.587183},
+  {0.401908,1.280822},
+  {0.031060,0.420576},
+  {-0.762789,-0.367085},
+  {1.175118,-0.820434},
+  {-0.478197,-0.370352},
+  {-0.236025,0.061470},
+  {0.686564,-0.585512},
+  {-0.237052,0.253177},
+  {-0.729385,-0.466642},
+  {-0.662395,-0.391071},
+  {0.273296,0.506813},
+  {0.965051,-0.027263},
+  {0.070026,1.046618},
+  {0.092287,0.070415},
+  {-0.908972,-0.539245},
+  {-0.623800,1.413496},
+  {0.325102,0.822477},
+  {-0.518215,0.034588},
+  {0.220737,0.705239},
+  {-0.818519,-0.857503},
+  {-1.388012,0.171706},
+  {0.650287,1.022428},
+  {2.412083,-0.776552},
+  {-0.297618,1.080676},
+  {0.467493,-0.420103},
+  {-0.059584,-0.053936},
+  {0.624517,-0.194404},
+  {0.036811,1.302039},
+  {0.842010,-0.194790},
+  {0.215698,0.725725},
+  {-0.272988,0.542958},
+  {-0.298502,1.190862},
+  {0.166648,0.297913},
+  {-0.783560,-0.385328},
+  {0.351894,-0.279022},
+  {0.183874,0.243079},
+  {0.134334,0.079331},
+  {-0.383688,0.849714},
+  {-0.227904,0.641252},
+  {0.329318,0.943028},
+  {0.936512,1.038576},
+  {0.757479,0.393397},
+  {1.478493,-0.037539},
+  {-1.189804,0.402658},
+  {0.292558,-1.779022},
+  {-0.284935,-0.366083},
+  {-0.386498,1.453383},
+  {0.611253,0.499528},
+  {-0.251683,0.181155},
+  {0.804380,-0.388200},
+  {-0.231037,0.258398},
+  {0.623782,0.017725},
+  {0.468501,0.540843},
+  {0.054289,1.158843},
+  {0.109397,0.089475},
+  {0.057510,0.640870},
+  {-1.007740,-1.110276},
+  {0.732886,0.842128},
+  {0.268033,-0.755497},
+  {-0.031795,-0.214367},
+  {-0.643266,-0.275480},
+  {1.885364,-0.353332},
+  {1.004060,-1.001434},
+  {-0.017497,0.894947},
+  {1.829552,0.069833},
+  {-0.930362,-0.271928},
+  {-0.374898,0.170401},
+  {-0.104757,-0.184549},
+  {1.479948,-0.472800},
+  {-0.766489,-0.268751},
+  {-0.188110,0.343063},
+  {-0.068686,0.373199},
+  {-0.335110,0.539789},
+  {0.926700,-0.263069},
+  {-0.060970,0.075089},
+  {-0.047239,-2.343455},
+  {-0.758616,-0.638756},
+  {0.194242,0.628520},
+  {-0.670422,-0.252502},
+  {-0.586947,1.217569},
+  {0.325827,0.180049},
+  {-1.170374,-0.478935},
+  {1.157467,0.136615},
+  {0.553874,0.901300},
+  {0.489163,0.191637},
+  {0.233215,-0.282606},
+  {1.394105,-0.595516},
+  {-0.616522,0.715078},
+  {-0.840391,-0.099596},
+  {0.539287,-0.316566},
+  {-0.384641,1.575414},
+  {0.708599,0.923721},
+  {-0.728650,0.399285},
+  {-0.884493,-0.797352},
+  {0.346664,0.439675},
+  {-0.912444,-1.014233},
+  {0.440793,1.115063},
+  {-0.852873,-0.619209},
+  {0.167686,-0.498302},
+  {1.288179,0.409765},
+  {1.402931,0.688458},
+  {-0.515123,-0.824088},
+  {0.192950,-0.248628},
+  {-0.062076,0.319169},
+  {0.488478,2.046597},
+  {-0.279347,0.144513},
+  {-0.425342,-0.162927},
+  {0.794761,0.950190},
+  {0.050606,-1.039568},
+  {0.258260,0.371916},
+  {0.299544,0.840263},
+  {1.011669,1.277889},
+  {-0.455175,0.008475},
+  {0.006032,0.495940},
+  {-0.564037,0.951911},
+  {-0.739710,0.911333},
+  {0.288278,0.246605},
+  {-0.415489,0.418020},
+  {0.214393,-0.216782},
+  {-0.258230,0.012515},
+  {0.085156,-1.067564},
+  {-0.477948,-0.126020},
+  {0.819553,0.227472},
+  {0.218761,0.118708},
+  {-1.147643,0.315880},
+  {-0.227523,0.539005},
+  {0.001495,0.428174},
+  {1.833835,-0.253958},
+  {0.094817,-0.427417},
+  {0.304182,0.027684},
+  {-0.448943,1.724177},
+  {0.306482,-1.723176},
+  {0.297892,0.566358},
+  {0.070474,-0.408958},
+  {-1.135178,0.616141},
+  {1.174561,0.739951},
+  {-0.427643,-0.076585},
+  {-0.143676,-0.561043},
+  {-0.575947,-0.963853},
+  {0.287610,-0.416596},
+  {1.053362,0.219671},
+  {0.215916,-0.082404},
+  {-0.004859,1.016390},
+  {-0.304115,-1.250074},
+  {-0.804160,1.414419},
+  {0.435396,1.580271},
+  {-0.540909,-0.386004},
+  {0.391329,0.175570},
+  {0.068666,-0.634001},
+  {-0.924601,-1.223534},
+  {-0.244715,-1.882378},
+  {-0.005935,0.055254},
+  {0.053374,-2.037105},
+  {-0.222229,-0.314341},
+  {1.683783,-0.136252},
+  {-0.209519,0.319064},
+  {0.128087,0.515904},
+  {1.057809,0.518777},
+  {1.302667,-0.667992},
+  {0.711711,1.370832},
+  {-0.425870,-0.921453},
+  {-0.282099,-0.019978},
+  {0.475885,0.778538},
+  {-1.191533,0.734870},
+  {-0.029950,0.617866},
+  {-0.455740,-0.735148},
+  {-1.482617,0.289506},
+  {-0.281529,-1.036867},
+  {-0.900051,-0.070463},
+  {-0.281393,-0.018742},
+  {-1.565083,0.033298},
+  {-1.253289,0.604701},
+  {-1.473103,0.505138},
+  {-1.337558,-0.025304},
+  {0.025156,0.114029},
+  {1.186775,0.120767},
+  {0.833490,-1.016311},
+  {-0.566033,-1.332979},
+  {-0.525104,-0.650364},
+  {-0.791062,0.388240},
+  {1.154731,1.317110},
+  {-0.317317,-0.091369},
+  {0.113614,0.044248},
+  {-0.258272,-0.047712},
+  {1.078975,0.638972},
+  {-0.597647,0.741361},
+  {-0.489840,-0.645206},
+  {0.555416,0.241694},
+  {-0.612925,-1.006549},
+  {-1.021876,-0.178930},
+  {-0.739651,0.372522},
+  {0.602211,1.641040},
+  {0.379708,-0.413169},
+  {0.089748,-0.616324},
+  {0.599494,-0.401401},
+  {0.259038,1.039479},
+  {0.006801,-0.534216},
+  {-1.441283,-0.788294},
+  {0.652339,-0.170895},
+  {0.170934,0.389251},
+  {0.369531,1.157200},
+  {-1.009088,0.126682},
+  {-0.315585,0.221797},
+  {0.202527,1.134547},
+  {-0.272163,-0.354116},
+  {-0.278950,-0.284232},
+  {-0.055980,-0.181156},
+  {-0.432454,-0.002721},
+  {-0.818628,-0.041833},
+  {-0.544952,-0.105704},
+  {0.552322,0.225571},
+  {-0.429020,-0.426446},
+  {0.450359,0.329922},
+  {-0.420977,0.010542},
+  {0.524081,0.061941},
+  {-0.611116,-0.497061},
+  {-0.185940,-1.029832},
+  {-0.352210,0.272805},
+  {-0.523549,0.577421},
+  {0.484978,-0.655545},
+  {0.426839,0.473204},
+  {-0.694465,0.191582},
+  {1.346640,-0.894402},
+  {-0.108025,0.551475},
+  {0.196850,0.014778},
+  {0.461298,-0.661029},
+  {1.183668,-0.482788},
+  {0.451475,1.978741},
+  {0.436252,-0.573917},
+  {-0.793265,0.340729},
+  {0.372344,0.278611},
+  {-0.754183,0.302767},
+  {-1.031154,-1.065581},
+  {0.628203,-0.223986},
+  {0.430165,-0.891388},
+  {-0.015695,-0.279011},
+  {0.048695,-1.308632},
+  {-0.269414,-0.197042},
+  {-0.795862,1.044719},
+  {0.436994,-0.946302},
+  {0.660415,0.069112},
+  {-0.073069,-0.338405},
+  {-1.016127,-0.176174},
+  {0.603558,0.251424},
+  {0.051546,-0.212910},
+  {-0.297017,-1.927157},
+  {-0.110347,-0.266009},
+  {0.592700,-0.192662},
+  {-0.562193,-0.059079},
+  {-0.549655,1.273057},
+  {0.063368,0.733878},
+  {-0.221776,1.592995},
+  {-0.742231,-1.023633},
+  {-0.300987,1.027012},
+  {0.819822,1.696182},
+  {-0.391936,0.788524},
+  {0.532161,-0.042235},
+  {-0.366096,-0.206694},
+  {-0.124892,-0.264484},
+  {-0.704913,0.651417},
+  {2.149216,-0.035024},
+  {-0.208488,0.467413},
+  {0.197927,-0.450251},
+  {0.775973,0.707921},
+  {-0.971095,0.934934},
+  {-0.675312,-0.556623},
+  {0.398423,2.014933},
+  {1.314999,0.121784},
+  {-0.149328,-0.548591},
+  {0.624388,0.554257},
+  {0.794465,-0.762318},
+  {-0.342740,-0.044003},
+  {0.664133,0.988572},
+  {-0.591256,-0.550813},
+  {0.004503,-0.209721},
+  {-0.704415,1.115631},
+  {0.499527,-0.865457},
+  {-0.427010,-0.058056},
+  {-0.442966,-0.801730},
+  {-0.028645,-0.432707},
+  {-0.520193,-0.477441},
+  {0.693746,-0.591685},
+  {-0.723356,-0.124885},
+  {-0.271467,0.138230},
+  {0.378694,-1.346075},
+  {0.867608,-0.861081},
+  {-0.030809,-0.637696},
+  {1.547649,-0.433481},
+  {0.281972,1.218074},
+  {0.289769,-0.252994},
+  {-0.547299,-1.114947},
+  {0.281379,0.103827},
+  {0.144241,0.141649},
+  {0.882615,0.777328},
+  {0.293825,-0.291434},
+  {0.115586,0.642325},
+  {-0.661045,-0.025898},
+  {0.339237,0.790670},
+  {-0.709378,0.173682},
+  {-0.691671,0.227216},
+  {-0.093392,0.390772},
+  {-0.822655,1.661899},
+  {0.470760,-0.539462},
+  {0.883847,0.324028},
+  {-0.816597,-0.501790},
+  {-0.171583,-1.222645},
+  {0.589553,0.087931},
+  {0.352979,-0.325299},
+  {-0.040087,0.573102},
+  {-0.333396,0.702907},
+  {0.678815,0.634352},
+  {1.236381,-0.495768},
+  {0.455672,1.242359},
+  {-0.877502,-1.177867},
+  {0.036368,0.084722},
+  {-0.261535,1.262188},
+  {-0.187800,0.138469},
+  {0.075047,0.017116},
+  {-0.553277,-0.427987},
+  {0.203971,-0.219700},
+  {-0.102810,0.727420},
+  {-0.208146,0.641188},
+  {0.505555,-1.229252},
+  {-0.089677,-0.317869},
+  {0.045298,0.553962},
+  {0.682165,0.978041},
+  {0.758240,1.062833},
+  {-0.591609,-0.169416},
+  {0.200002,-0.806496},
+  {0.401893,-0.505467},
+  {-0.049368,0.974221},
+  {-1.338392,-1.052507},
+  {-0.234168,-0.459732},
+  {-0.049076,-0.787956},
+  {-0.440995,0.824773},
+  {-0.310494,0.155186},
+  {0.629950,0.438434},
+  {0.128082,-0.298934},
+  {-0.889005,-0.700750},
+  {0.725139,1.108872},
+  {0.806530,0.172376},
+  {1.274152,-1.109091},
+  {0.361415,0.304318},
+  {-0.770589,-1.690576},
+  {-0.077050,-1.541958},
+  {0.055098,0.140834},
+  {-1.027384,-0.083170},
+  {-0.387121,1.173074},
+  {-0.511185,-0.640359},
+  {0.970168,0.278280},
+  {-0.399875,-0.215985},
+  {0.578435,0.171387},
+  {-0.143334,-0.387392},
+  {1.048777,0.181700},
+  {0.369934,0.608091},
+  {1.128358,-0.533869},
+  {0.725995,-0.677232},
+  {0.131748,-0.914071},
+  {-0.661664,0.557397},
+  {0.864385,0.026499},
+  {-0.076076,-0.384927},
+  {-1.700148,0.806878},
+  {-0.093025,0.160711},
+  {0.657889,-0.819687},
+  {1.415252,0.043090},
+  {-0.474513,1.021749},
+  {-0.235819,0.669443},
+  {-0.209294,0.038555},
+  {0.350373,0.947927},
+  {-0.473777,0.450919},
+  {-0.439863,-1.296476},
+  {-0.041963,0.452473},
+  {0.519491,-0.934337},
+  {0.029848,0.199221},
+  {0.568997,0.413023},
+  {-0.422968,0.191107},
+  {-1.046889,-0.575230},
+  {0.555575,0.114778},
+  {-0.271803,-0.125287},
+  {-1.492866,-0.813928},
+  {0.581882,-0.352968},
+  {-0.802623,1.377947},
+  {0.700558,0.297364},
+  {0.010499,0.485443},
+  {0.030525,-0.214066},
+  {0.290003,-0.036848},
+  {0.177382,0.633674},
+  {-0.142112,-0.817479},
+  {-1.506692,0.130953},
+  {-0.549851,0.089496},
+  {0.530755,1.632153},
+  {0.958531,-1.707736},
+  {0.610349,2.078139},
+  {-0.086293,0.239772},
+  {0.202042,-0.362267},
+  {0.894271,-1.466671},
+  {0.438957,0.318388},
+  {-0.721440,-1.241242},
+  {0.570884,0.929768},
+  {0.691115,0.078293},
+  {2.031262,0.005026},
+  {0.614740,0.403247},
+  {-0.153316,-0.453097},
+  {-0.500683,-0.473711},
+  {-0.604458,0.407987},
+  {0.182040,0.697141},
+  {-0.162319,0.006736},
+  {0.525699,0.675310},
+  {-0.360962,-0.686781},
+  {1.308789,-0.386448},
+  {-0.174349,-0.941565},
+  {-1.104866,0.335170},
+  {-0.705175,0.291939},
+  {-0.244608,-0.192226},
+  {0.962480,0.146916},
+  {0.413036,-0.045753},
+  {0.322721,0.586207},
+  {-0.285444,0.020732},
+  {-0.201547,-0.960376},
+  {-0.525784,0.598120},
+  {-0.594926,0.215987},
+  {-0.157909,-0.395456},
+  {0.609670,0.114630},
+  {0.326789,-0.001808},
+  {-0.652800,0.608450},
+  {0.630816,-0.318163},
+  {1.290349,-0.308122},
+  {0.302288,0.042105},
+  {-0.618234,-0.122607},
+  {-0.671018,0.647521},
+  {-0.033489,1.029981},
+  {1.127675,0.838844},
+  {-0.391586,0.406333},
+  {0.634599,-0.206173},
+  {-0.158274,0.281173},
+  {0.031888,0.459707},
+  {-0.371921,0.932324},
+  {0.076527,-0.283407},
+  {-0.241424,0.283793},
+  {0.312402,0.175612},
+  {0.212368,-0.432081},
+  {-0.773642,0.100780},
+  {0.251432,0.483141},
+  {-0.166812,-0.067869},
+  {0.027261,0.793139},
+  {0.764140,0.027200},
+  {0.014120,-0.858433},
+  {-0.996727,0.370392},
+  {0.132527,0.167380},
+  {0.972844,0.615013},
+  {-0.400845,-1.129354},
+  {0.468849,-0.867083},
+  {1.017556,-0.782061},
+  {-0.109531,-0.643417},
+  {-0.213625,0.158193},
+  {0.199067,-0.074333},
+  {0.344584,-1.074916},
+  {-0.221442,0.527535},
+  {-0.427743,0.192179},
+  {-0.445158,0.223376},
+  {-0.406246,-1.129810},
+  {0.498180,-0.537912},
+  {0.246385,1.147774},
+  {1.124593,0.638781},
+  {-0.238219,-1.178279},
+  {0.564715,0.082624},
+  {0.009528,-0.294926},
+  {0.449595,-0.413499},
+  {-0.222000,-0.383341},
+  {-0.293071,-0.020010},
+  {0.262525,-0.619825},
+  {-0.622110,0.994815},
+  {0.826520,-0.318905},
+  {-0.139956,0.034670},
+  {-0.602776,1.445757},
+  {-0.000428,0.515115},
+  {0.262184,-0.002736},
+  {1.304981,-0.501046},
+  {-0.321231,0.622551},
+  {1.054329,-0.220852},
+  {-0.492771,-0.940654},
+  {-0.780517,1.146123},
+  {-0.030875,-1.453137},
+  {0.833466,-0.395468},
+  {0.523778,0.759513},
+  {-1.126077,-0.417115},
+  {-0.556663,0.032786},
+  {0.206892,-1.122757},
+  {-0.366164,1.106942},
+  {0.152365,-0.067752},
+  {0.046570,-0.568357},
+  {-1.294625,0.304168},
+  {-0.314597,-0.414620},
+  {1.204236,0.126016},
+  {-0.051512,0.247893},
+  {-0.662050,-0.548429},
+  {0.806882,0.635211},
+  {0.354519,0.315406},
+  {-0.102549,-0.307759},
+  {-0.945865,-1.144877},
+  {0.092988,-0.095752},
+  {-0.590799,1.426964},
+  {-0.512031,-0.295192},
+  {-0.241074,-0.440517},
+  {0.829680,0.087681},
+  {-0.109337,-0.289886},
+  {0.656985,0.294518},
+  {0.564203,0.206732},
+  {-0.898597,-0.207926},
+  {0.327259,0.685055},
+  {1.226880,-0.695505},
+  {-0.829727,0.718718},
+  {-1.451225,-0.289371},
+  {0.837042,1.220714},
+  {-0.158113,0.175430},
+  {0.974037,-0.062980},
+  {0.178835,0.169509},
+  {1.118203,0.735886},
+  {0.104949,-0.340257},
+  {0.378724,0.089648},
+  {0.214056,-0.821406},
+  {1.396107,0.599080},
+  {0.369926,0.109247},
+  {0.673800,0.763612},
+  {-0.268951,-0.230063},
+  {0.567933,0.162580},
+  {-1.689604,-0.345288},
+  {0.137885,-0.093063},
+  {-0.298533,-0.191792},
+  {1.251967,-0.136681},
+  {-0.693495,-0.932444},
+  {-0.555325,-0.131594},
+  {0.236263,-0.069815},
+  {-1.252648,0.035106},
+  {-1.764317,0.733486},
+  {-0.075051,1.622354},
+  {-0.085244,-0.605377},
+  {-0.642959,-0.089863},
+  {-0.113593,-0.099045},
+  {0.058362,-1.029047},
+  {0.826847,0.113454},
+  {-0.244119,-0.050284},
+  {-1.073509,0.123867},
+  {-0.904460,-0.901549},
+  {0.453204,-0.459712},
+  {-1.264724,-0.418653},
+  {0.472295,-1.485124},
+  {0.323558,-0.092765},
+  {1.800720,0.519789},
+  {-1.126308,-0.318456},
+  {0.724158,-0.269665},
+  {0.710385,0.177657},
+  {-0.783852,-0.215007},
+  {-1.354067,0.031020},
+  {-1.015185,0.249321},
+  {0.839984,1.457903},
+  {-0.353245,-0.313877},
+  {0.763070,0.903317},
+  {-1.656538,-0.791042},
+  {-0.892608,-0.381481},
+  {0.649284,-0.643492},
+  {1.455720,-0.133815},
+  {0.732560,-0.289157},
+  {-0.377583,-1.019029},
+  {-0.377847,-1.270397},
+  {0.809711,-0.293496},
+  {-1.027232,-0.492600},
+  {-0.531947,-1.149837},
+  {-0.321890,0.886703},
+  {-0.603477,-1.377457},
+  {0.259723,-0.220563},
+  {0.949998,0.240148},
+  {0.261264,0.890932},
+  {0.595257,-1.336390},
+  {-0.362741,0.082717},
+  {-0.355324,-0.058517},
+  {-0.404853,-0.487143},
+  {-0.431324,0.299014},
+  {0.079328,-0.804580},
+  {0.824935,-0.454231},
+  {0.262757,-0.554689},
+  {0.126869,-0.439135},
+  {-1.051874,-0.512746},
+  {0.293715,0.904688},
+  {-1.530512,-0.258114},
+  {0.782473,1.192382},
+  {0.532046,0.769399},
+  {0.384142,-0.126943},
+  {0.161275,-0.961466},
+  {-0.060918,-0.053277},
+  {0.876995,1.833961},
+  {-0.747767,0.165348},
+  {-0.052410,-0.612302},
+  {0.814379,0.370027},
+  {0.848717,-0.351940},
+  {-0.797478,-0.346407},
+  {0.451936,1.010194},
+  {0.582376,0.949018},
+  {-0.342362,0.108576},
+  {0.556515,-0.142943},
+  {0.728162,-1.097160},
+  {-1.075414,0.137602},
+  {0.457708,-0.654780},
+  {0.165246,1.781712},
+  {-0.319642,-0.993107},
+  {-0.584410,0.462585},
+  {-0.203283,-0.682679},
+  {-0.872903,0.560968},
+  {0.545374,0.278981},
+  {0.918419,0.246065},
+  {-0.632251,-0.167158},
+  {-0.285094,0.517218},
+  {0.742545,-0.428022},
+  {-0.272512,-0.650121},
+  {0.007097,-0.259464},
+  {0.321549,-0.153838},
+  {-0.935528,-0.478174},
+  {-0.609717,-0.076270},
+  {-0.755654,-0.453108},
+  {0.881595,0.809393},
+  {-0.851194,-0.126438},
+  {-0.678539,-0.168662},
+  {-0.735439,1.454476},
+  {-0.702070,-0.732654},
+  {0.950217,0.061374},
+  {0.931381,0.383055},
+  {-1.577577,-0.830957},
+  {1.081051,0.875738},
+  {0.946201,1.485701},
+  {0.433276,0.890427},
+  {1.505338,0.234134},
+  {0.083216,0.185535},
+  {0.206556,0.692397},
+  {0.800164,1.210478},
+  {0.308393,-0.573495},
+  {-0.455541,0.377465},
+  {0.285379,0.593679},
+  {1.807014,0.007663},
+  {1.599165,-0.768434},
+  {-0.182963,-1.147207},
+  {0.691660,0.496669},
+  {0.235179,-0.284885},
+  {-0.461998,0.542110},
+  {-1.935320,-0.774389},
+  {-0.078056,-0.127823},
+  {0.299281,-0.033361},
+  {0.302731,0.078716},
+  {0.069066,-0.050105},
+  {0.221607,-1.239222},
+  {0.340220,0.582368},
+  {-0.565872,0.345751},
+  {-0.470414,0.191707},
+  {-0.086475,-1.321960},
+  {-0.653337,1.499706},
+  {-1.186698,0.203143},
+  {0.362014,0.335224},
+  {0.763790,-0.914370},
+  {1.135858,-1.463878},
+  {0.719099,-0.477518},
+  {0.269766,0.421199},
+  {0.064365,-0.175814},
+  {-0.367548,0.001256},
+  {0.544776,-0.698629},
+  {0.615651,-0.386841},
+  {-0.875089,-0.516872},
+  {0.413476,-1.281108},
+  {0.502809,-0.490843},
+  {-2.204143,0.110420},
+  {-0.385040,-0.740596},
+  {0.695904,0.385231},
+  {0.255709,0.008205},
+  {-0.586557,-0.564665},
+  {0.803747,0.411107},
+  {1.601181,0.662062},
+  {0.865286,-0.979781},
+  {0.689845,0.519237},
+  {0.395498,0.145840},
+  {-0.626369,0.344739},
+  {0.042164,0.051887},
+  {-1.403498,0.671656},
+  {0.598572,0.681828},
+  {1.220256,-1.165620},
+  {-0.793312,0.715179},
+  {-0.234183,0.019938},
+  {0.385507,0.226328},
+  {-0.450997,-1.107601},
+  {-1.171289,0.649867},
+  {-1.080178,-1.231856},
+  {-0.061619,1.143806},
+  {0.430298,0.525364},
+  {-1.049354,0.166192},
+  {-0.080776,-0.357525},
+  {0.511572,-1.785495},
+  {-0.558196,0.261639},
+  {-0.887145,0.298578},
+  {-1.566637,0.706769},
+  {1.151140,0.445122},
+  {-0.586133,0.107778},
+  {-0.804525,0.245580},
+  {0.980744,1.043818},
+  {-0.070419,-0.910922},
+  {-0.451713,0.466261},
+  {1.125777,0.160904},
+  {0.577041,0.069860},
+  {1.144021,-0.150339},
+  {-0.411414,0.404973},
+  {0.188443,0.548050},
+  {0.225498,-0.614626},
+  {1.398432,-1.427287},
+  {-0.035313,0.492779},
+  {0.460713,-1.022950},
+  {-0.523193,-0.887124},
+  {-1.045011,0.261402},
+  {1.388863,-0.612235},
+  {0.475152,-0.857959},
+  {0.468680,-0.231389},
+  {0.983306,0.199760},
+  {-0.645385,0.205021},
+  {-0.363448,-0.870316},
+  {-0.003819,0.010668},
+  {0.471121,0.244769},
+  {-0.040500,0.556180},
+  {-1.479050,0.358434},
+  {0.182788,0.373558},
+  {-0.858638,-0.878108},
+  {0.001368,0.436654},
+  {0.142518,0.294864},
+  {-1.153171,0.438127},
+  {0.937820,0.034099},
+  {1.521724,-0.077421},
+  {-0.377694,-0.278517},
+  {1.467230,-0.459260},
+  {0.145964,0.357560},
+  {0.619192,-1.480037},
+  {-0.797876,0.686615},
+  {-0.465726,1.294829},
+  {1.120753,0.433341},
+  {0.481084,0.429728},
+  {-0.993491,-0.218804},
+  {0.080120,0.061366},
+  {-0.345080,-1.108765},
+  {0.597685,-1.108810},
+  {0.272861,-1.448070},
+  {0.103180,-0.368753},
+  {0.452562,-0.193846},
+  {-0.047889,-0.169513},
+  {-0.062237,-0.499899},
+  {-0.208393,1.227431},
+  {0.358621,-0.122079},
+  {-0.538647,0.167846},
+  {-0.535399,0.147300},
+  {-0.016851,-0.523791},
+  {0.185591,0.287441},
+  {-0.076126,0.077379},
+  {0.111808,-0.298068},
+  {-0.360049,0.447806},
+  {-0.468579,0.021829},
+  {0.999254,0.093009},
+  {0.409156,0.087569},
+  {-0.290239,1.155172},
+  {-0.631769,0.113278},
+  {-0.485475,0.352847},
+  {0.132807,0.899243},
+  {0.231351,-0.149363},
+  {0.389824,-1.011206},
+  {-0.093767,0.618494},
+  {0.302881,0.883287},
+  {0.253348,-0.020438},
+  {0.310115,0.544154},
+  {-0.181672,0.250213},
+  {0.785253,-0.002714},
+  {0.399704,-0.310344},
+  {-1.634428,0.357997},
+  {0.976723,0.117106},
+  {-0.663422,0.938808},
+  {1.142522,0.426250},
+  {-0.176854,0.538674},
+  {1.134571,1.976267},
+  {-0.793977,0.553600},
+  {-0.496199,0.132777},
+  {0.428161,1.342281},
+  {0.881731,-0.349207},
+  {0.487284,-0.673507},
+  {0.834150,0.300816},
+  {1.043740,0.574802},
+  {-0.108407,1.056837},
+  {-0.745715,0.304328},
+  {0.494903,0.535517},
+  {-0.608093,0.752694},
+  {0.430291,-0.135674},
+  {-0.174181,-1.362910},
+  {-0.064613,-1.995513},
+  {-0.704478,0.276742},
+  {0.232225,-0.347325},
+  {0.129886,0.297225},
+  {0.095056,0.366532},
+  {1.123177,-0.516860},
+  {0.280489,0.548995},
+  {0.950114,0.871146},
+  {-0.045855,-0.101106},
+  {0.323361,0.916197},
+  {-0.379042,-0.789420},
+  {0.155370,-0.526626},
+  {0.123440,-0.404112},
+  {1.122189,-0.542010},
+  {0.287594,-0.412748},
+  {-0.487695,-0.914112},
+  {0.326158,-0.133099},
+  {-0.166449,-1.353339},
+  {-0.055827,0.625175},
+  {-1.228110,0.059411},
+  {-0.274514,-1.194058},
+  {0.008816,-0.571387},
+  {-0.700423,0.936284},
+  {-0.528928,0.824434},
+  {-0.436216,1.131698},
+  {-1.371594,-0.535034},
+  {-0.002092,0.190907},
+  {-0.652668,1.278957},
+  {0.101573,-0.906194},
+  {0.783427,-0.139790},
+  {-2.499705,-0.774554},
+  {0.580857,0.350367},
+  {-0.259410,0.346345},
+  {1.443858,0.066180},
+  {1.007880,-0.608615},
+  {-1.185398,-0.124630},
+  {-1.074749,-0.104417},
+  {-0.075128,0.869631},
+  {-0.157998,1.035636},
+  {-0.212559,-0.416354},
+  {0.399589,-0.077372},
+  {0.139788,0.342017},
+  {1.188158,-1.194288},
+  {0.290935,0.230597},
+  {0.467906,0.144104},
+  {0.777358,0.288836},
+  {0.818580,0.308433},
+  {-0.210142,0.214512},
+  {0.315948,-0.636328},
+  {-0.005891,-0.999753},
+  {0.072755,-0.563891},
+  {0.425654,0.196551},
+  {0.361411,-0.211226},
+  {0.905206,-1.349513},
+  {-0.790974,-0.395724},
+  {0.525156,0.770383},
+  {-0.092408,-0.488183},
+  {0.265920,-0.036150},
+  {-0.276333,-0.689856},
+  {0.117261,0.005735},
+  {-0.665691,-0.164460},
+  {0.312157,-0.594442},
+  {0.107864,-0.443120},
+  {1.118670,-0.671898},
+  {-0.022763,0.583797},
+  {0.510916,-0.179671},
+  {0.714169,-0.104546},
+  {0.396036,1.216840},
+  {0.373920,0.135520},
+  {0.553972,-0.997894},
+  {0.052585,0.462084},
+  {-0.150044,-0.163447},
+  {1.461147,0.659548},
+  {-1.000455,-1.680109},
+  {-0.717611,-0.210337},
+  {-0.772596,-0.251350},
+  {0.537726,1.050492},
+  {-0.482650,-0.283289},
+  {-0.633239,-0.569656},
+  {-0.904458,-0.617468},
+  {0.109119,-1.522443},
+  {-1.226419,-0.899079},
+  {0.379579,-0.252179},
+  {-0.104614,0.852366},
+  {-0.503179,0.002718},
+  {0.361405,-0.255127},
+  {0.707854,-0.139151},
+  {0.588351,0.341695},
+  {0.541234,0.404290},
+  {-0.423201,0.945891},
+  {0.540899,0.903758},
+  {-0.383715,-1.224310},
+  {0.541671,-0.191686},
+  {0.220524,-0.467755},
+  {0.419523,-0.261834},
+  {-0.248004,-0.524029},
+  {1.166929,-0.005245},
+  {0.162462,0.683697},
+  {0.021613,-1.336883},
+  {-0.371790,-0.820360},
+  {0.064987,-0.180902},
+  {-0.530311,-0.237448},
+  {0.014535,0.196268},
+  {0.302158,-0.943375},
+  {-0.741328,-0.621982},
+  {-0.990134,-0.843669},
+  {0.298802,0.314671},
+  {0.150737,-0.515418},
+  {0.642389,0.170803},
+  {-0.660634,-0.070932},
+  {-0.466752,0.294915},
+  {0.498991,0.882812},
+  {-0.120033,-0.318492},
+  {-0.283866,0.416022},
+  {-1.125159,0.156951},
+  {0.164229,0.285664},
+  {-0.680682,0.531478},
+  {-0.228335,0.444181},
+  {0.424797,-0.850202},
+  {-0.620993,1.933195},
+  {0.618146,1.057688},
+  {0.351681,0.093757},
+  {0.343992,-0.350496},
+  {0.419756,-0.682277},
+  {0.132223,-0.220393},
+  {0.315669,-0.077213},
+  {0.623756,-0.047636},
+  {-0.980970,0.008924},
+  {-0.180176,0.848320},
+  {1.546197,0.370102},
+  {0.713022,-0.899697},
+  {-0.512503,-0.004650},
+  {-1.161518,0.132127},
+  {-1.041393,-0.554167},
+  {-0.036518,0.378256},
+  {-0.567661,-0.897940},
+  {0.259504,-0.049623},
+  {-0.026158,-0.270600},
+  {0.724927,-0.499448},
+  {0.138307,1.291056},
+  {-1.822129,-1.644371},
+  {0.671500,0.097591},
+  {-0.980895,0.107560},
+  {-0.420513,0.010420},
+  {0.003000,-0.162645},
+  {0.447768,-0.633708},
+  {0.382118,0.153956},
+  {-0.223916,-0.841490},
+  {-1.102503,-0.035876},
+  {0.040286,0.813246},
+  {0.067205,-2.636223},
+  {-1.058178,-0.439882},
+  {0.240943,0.599442},
+  {-0.266778,-1.074089},
+  {0.320826,-0.918839},
+  {-0.646954,-0.007690},
+  {-0.530749,-0.347252},
+  {-0.393036,-0.123253},
+  {0.053211,-2.091439},
+  {-0.481911,-0.677379},
+  {-0.014975,0.997160},
+  {0.536010,1.088136},
+  {-1.031007,-1.129666},
+  {-0.116730,0.519996},
+  {1.565485,-0.343272},
+  {-0.368459,0.506657},
+  {-0.230470,-0.260120},
+  {0.621381,1.007440},
+  {0.186324,-0.312790},
+  {0.273069,-0.166279},
+  {0.201102,1.556145},
+  {-1.115634,1.567159},
+  {-0.648866,-0.322859},
+  {-0.704410,0.380438},
+  {0.342389,0.213936},
+  {-0.042804,0.701810},
+  {0.016719,0.090798},
+  {-0.731592,-0.277491},
+  {0.103078,0.783883},
+  {0.345053,0.215559},
+  {0.067924,1.081925},
+  {0.369806,-0.219722},
+  {1.098806,0.215612},
+  {-0.724316,-0.036048},
+  {0.186158,0.608022},
+  {0.139663,0.056514},
+  {-0.575010,-0.801492},
+  {-1.123663,-0.414602},
+  {0.564236,0.266108},
+  {-0.391462,0.093429},
+  {0.144703,-0.560902},
+  {-0.686121,1.329790},
+  {-0.379640,-0.241261},
+  {-0.498875,-1.364991},
+  {0.541470,0.214751},
+  {-0.508841,-0.694946},
+  {0.812702,0.407024},
+  {0.257132,0.128592},
+  {-1.187255,-0.495273},
+  {0.020247,-0.196925},
+  {0.188392,-0.459074},
+  {-0.932918,0.525366},
+  {1.134929,1.151288},
+  {-1.296745,-0.844320},
+  {-0.610290,-1.014578},
+  {0.623994,0.443023},
+  {-0.303615,-1.049124},
+  {-0.597543,-0.208275},
+  {0.252960,0.992397},
+  {-0.023412,0.368284},
+  {-0.429581,-0.070039},
+  {0.923782,-0.778340},
+  {0.060056,-0.739469},
+  {0.753096,0.478049},
+  {-0.127857,0.093383},
+  {0.106401,0.423911},
+  {-0.183224,-0.032369},
+  {-0.381160,0.851604},
+  {-0.797228,-0.217383},
+  {0.227067,0.316891},
+  {0.451114,1.830366},
+  {-1.042958,0.186763},
+  {-0.171936,0.478779},
+  {-0.075379,0.034822},
+  {0.385404,1.160047},
+  {0.105260,-1.211098},
+  {1.211046,-1.103540},
+  {0.308818,-1.042156},
+  {-0.704631,-0.115963},
+  {0.012675,-0.547391},
+  {-0.484557,-0.100460},
+  {-0.836917,-0.043501},
+  {-0.463115,1.544351},
+  {0.309894,-0.669455},
+  {0.685375,0.000866},
+  {0.511942,0.836813},
+  {-0.929517,-0.531037},
+  {0.050933,0.075894},
+  {0.845070,1.231045},
+  {0.796139,0.796776},
+  {0.766749,-0.653760},
+  {0.742048,1.398289},
+  {-0.403017,-0.007496},
+  {-0.509706,1.110607},
+  {-1.449968,0.427343},
+  {-0.010909,1.223294},
+  {-0.077727,-0.670769},
+  {0.526333,0.308160},
+  {0.319094,-0.176388},
+  {0.742543,1.379446},
+  {1.245044,1.188638},
+  {-0.025489,-0.164810},
+  {0.608945,-0.073624},
+  {-0.174670,-0.273746},
+  {-0.624686,1.010041},
+  {-0.670461,0.584006},
+  {-0.444858,-1.904891},
+  {0.222806,0.547945},
+  {0.138390,0.546322},
+  {-0.446882,-0.696967},
+  {-0.628694,-1.208785},
+  {-2.152300,-0.613403},
+  {-0.096864,0.068138},
+  {-0.301906,-0.946012},
+  {-0.369820,-0.646125},
+  {-1.447581,-0.646713},
+  {-0.400707,-0.494477},
+  {-0.635435,-0.038456},
+  {0.296783,0.278288},
+  {-1.001213,0.042941},
+  {0.091071,0.902239},
+  {-0.460656,0.281628},
+  {0.479946,0.142043},
+  {-0.487485,-0.696643},
+  {-0.407485,-0.541246},
+  {-0.607882,-0.853128},
+  {-1.305443,-0.877425},
+  {-0.359749,-0.647498},
+  {-0.626709,0.576527},
+  {-0.148729,-0.090456},
+  {0.172979,0.177948},
+  {-0.107637,-0.478667},
+  {0.366998,0.024629},
+  {0.462107,0.857612},
+  {-0.460563,0.248349},
+  {0.907838,0.853909},
+  {0.783150,0.585374},
+  {-0.299669,-0.212882},
+  {1.119594,0.504852},
+  {0.377228,0.481423},
+  {0.852296,0.676788},
+  {-0.286757,-0.002129},
+  {0.209843,-0.977784},
+  {-0.441823,-0.072773},
+  {0.917957,-0.753300},
+  {0.273348,-0.628772},
+  {-0.284862,0.155215},
+  {-0.247355,-0.247082},
+  {2.118546,-0.537469},
+  {-0.310251,-0.363626},
+  {1.378995,0.614774},
+  {0.009172,-1.398820},
+  {-0.300000,0.441999},
+  {-0.297449,0.954413},
+  {0.683275,0.180768},
+  {-0.371476,-1.618431},
+  {-0.175134,-1.231505},
+  {-0.749555,-0.428287},
+  {-0.969477,0.592818},
+  {0.687133,-0.691685},
+  {-0.165526,-0.045505},
+  {0.910848,-0.391948},
+  {1.179305,0.100935},
+  {0.166614,-0.729254},
+  {-1.130469,0.164593},
+  {-1.549639,0.217721},
+  {-0.481054,-0.872328},
+  {-0.586590,-1.074824},
+  {0.091563,0.381294},
+  {-0.609678,-0.230306},
+  {0.503876,0.238278},
+  {-0.562595,1.625733},
+  {1.273220,0.329444},
+  {0.309265,-0.432313},
+  {0.950421,0.011570},
+  {0.374275,-0.221395},
+  {-0.002535,-0.068439},
+  {-0.704010,-0.714205},
+  {0.645151,-0.117244},
+  {-0.548621,0.089519},
+  {-1.310708,0.214149},
+  {-0.222895,0.327611},
+  {-1.536313,0.422522},
+  {0.805899,-1.158480},
+  {0.201190,0.527469},
+  {0.085621,-0.741991},
+  {-0.638953,0.135701},
+  {0.610284,0.256558},
+  {-0.021550,-0.185034},
+  {-0.663349,0.344785},
+  {1.234438,0.087483},
+  {-0.131234,-1.490191},
+  {0.256245,0.425473},
+  {-0.093340,0.831930},
+  {-1.552555,-0.056483},
+  {0.441688,0.115210},
+  {0.108127,0.046402},
+  {-0.367616,-0.887437},
+  {-0.808894,-0.681247},
+  {-0.609795,-0.206087},
+  {0.578144,0.401209},
+  {-0.066620,0.628916},
+  {0.230375,-0.294361},
+  {0.168031,0.445080},
+  {0.184035,0.358481},
+  {0.251087,-0.489438},
+  {-0.945207,2.090916},
+  {-0.899493,0.281441},
+  {-0.600711,0.695281},
+  {0.496877,1.825249},
+  {0.557064,1.787828},
+  {-0.032903,0.096150},
+  {-0.171482,-0.526085},
+  {-0.560700,0.472487},
+  {-0.295947,0.009918},
+  {1.142040,0.416169},
+  {-0.447775,0.074483},
+  {-0.823909,-1.010476},
+  {-1.547191,1.727266},
+  {-0.760387,-0.877929},
+  {-1.629711,-0.932786},
+  {0.486282,0.248117},
+  {-0.264396,0.926022},
+  {1.081113,0.075435},
+  {-0.643699,-0.289886},
+  {0.440984,0.308158},
+  {0.821736,-0.810105},
+  {-1.505203,-1.521192},
+  {-0.542677,0.842918},
+  {0.164887,0.399004},
+  {-0.811521,0.078831},
+  {0.797827,-1.167125},
+  {-0.401101,-0.501867},
+  {0.364811,-0.809028},
+  {0.734068,-0.323428},
+  {-0.319197,-0.550535},
+  {-0.271324,-0.367006},
+  {-0.059699,0.983663},
+  {-1.366932,0.282483},
+  {0.168976,0.203650},
+  {0.302598,-0.221575},
+  {1.175485,0.753488},
+  {0.107512,1.781766},
+  {0.946028,-0.282479},
+  {-0.679608,-0.932184},
+  {-1.191856,0.201361},
+  {-0.166462,-0.053378},
+  {-0.812532,-0.147616},
+  {1.611017,0.674833},
+  {0.314528,1.017239},
+  {-1.162592,0.325194},
+  {-1.032033,0.635921},
+  {0.084120,-0.730470},
+  {0.494315,0.897198},
+  {0.847109,0.168996},
+  {1.644454,0.751446},
+  {-0.353970,-0.863128},
+  {0.678397,0.141939},
+  {-0.973674,-2.013022},
+  {0.685345,0.419897},
+  {-1.288642,-0.442089},
+  {-0.054887,-0.748914},
+  {-0.601785,-0.605123},
+  {-0.214297,-0.391510},
+  {-1.074972,0.659726},
+  {0.105391,0.708672},
+  {-0.113354,-0.765485},
+  {0.300873,0.781452},
+  {0.170277,0.599499},
+  {0.147834,-0.954326},
+  {-0.339726,-0.501183},
+  {0.544002,0.385444},
+  {0.352044,1.066552},
+  {0.911869,0.956912},
+  {-0.191047,0.108966},
+  {1.413499,-0.757569},
+  {0.706789,-1.026854},
+  {0.539308,-0.138690},
+  {0.080942,-0.272806},
+  {0.098018,0.018024},
+  {0.195238,-0.389384},
+  {0.488144,-0.357992},
+  {-0.309817,0.010149},
+  {-1.032893,-0.592658},
+  {-0.298775,-0.388887},
+  {1.131782,-1.690704},
+  {-0.193514,0.171204},
+  {-0.537903,-0.543134},
+  {0.659055,-0.601144},
+  {0.304951,0.294985},
+  {0.888941,0.970043},
+  {0.458543,-0.183693},
+  {-0.759308,0.795668},
+  {-0.350375,-0.113882},
+  {-0.127585,0.382365},
+  {-0.213916,0.521858},
+  {-0.344818,0.116112},
+  {-0.092834,-0.185633},
+  {0.061649,1.365497},
+  {0.476463,-0.791558},
+  {-0.984206,0.997109},
+  {-0.057978,-0.489422},
+  {-0.194234,-0.607085},
+  {-0.657674,0.088412},
+  {-0.469191,0.137722},
+  {1.011820,-0.291022},
+  {-0.303269,-0.626332},
+  {0.561159,-0.200477},
+  {0.140475,0.804297},
+  {0.160608,-0.598328},
+  {0.213319,1.449153},
+  {1.142243,0.283340},
+  {0.065037,-0.257834},
+  {0.261033,0.207025},
+  {0.700460,0.482503},
+  {0.843141,-0.154417},
+  {0.292633,0.402510},
+  {-0.818789,-0.671620},
+  {0.736334,-0.267822},
+  {-0.736153,0.705889},
+  {-1.012207,-0.010744},
+  {0.662579,0.401311},
+  {-0.387354,-0.679445},
+  {1.209621,-0.153205},
+  {-0.701672,0.069607},
+  {1.319853,1.085888},
+  {1.254748,-0.101110},
+  {0.266011,-0.499106},
+  {0.615725,0.884454},
+  {-1.011208,0.102181},
+  {-1.099802,-0.974027},
+  {-0.531963,-0.562972},
+  {0.121607,-0.356338},
+  {0.518231,0.154831},
+  {0.499951,1.188225},
+  {-0.817457,1.714401},
+  {0.369950,0.572897},
+  {-0.414845,-0.182628},
+  {-0.718216,1.117213},
+  {-1.333928,0.469810},
+  {-1.207522,-0.417102},
+  {0.561111,0.726184},
+  {-1.117766,-0.219214},
+  {0.744550,-0.034760},
+  {0.797619,1.455506},
+  {-0.584053,0.337943},
+  {0.157397,-0.757585},
+  {0.116196,-0.446006},
+  {0.146428,0.467807},
+  {0.714421,-0.366232},
+  {1.429872,0.625346},
+  {-0.033015,0.198674},
+  {0.105885,-0.216353},
+  {-0.023687,0.692143},
+  {-0.048073,0.669529},
+  {-0.205184,0.780326},
+  {0.266525,0.176072},
+  {0.141148,0.252191},
+  {-0.388369,0.046018},
+  {0.299170,-0.177464},
+  {-1.081893,-1.145642},
+  {0.010014,0.514986},
+  {0.448166,-0.748932},
+  {-0.295357,-0.035173},
+  {-0.033904,0.187373},
+  {-0.964666,-0.232491},
+  {0.485426,-1.478534},
+  {0.150372,0.430681},
+  {1.004055,0.755612},
+  {-1.273932,-0.382681},
+  {-0.123319,0.320989},
+  {-0.919513,-0.315545},
+  {-0.497703,0.345372},
+  {0.182013,-0.018783},
+  {0.188130,-1.169909},
+  {-0.716006,-0.184715},
+  {0.178950,-0.378160},
+  {-1.121777,0.261067},
+  {-0.884913,0.533499},
+  {-0.252487,-0.381490},
+  {-0.521029,-0.459944},
+  {0.109009,-0.604069},
+  {-0.131799,-0.166129},
+  {-0.915776,0.867035},
+  {-0.051356,-0.189373},
+  {0.352025,0.298949},
+  {0.197533,0.081879},
+  {-0.198604,0.668512},
+  {1.153004,0.840196},
+  {-0.111957,-0.162456},
+  {1.271047,0.649951},
+  {-0.272905,1.016445},
+  {-0.490432,-1.110506},
+  {0.098962,0.280027},
+  {-0.149747,-1.055724},
+  {0.592247,-0.565550},
+  {1.155912,-1.145805},
+  {0.763039,0.568494},
+  {-0.395993,0.406406},
+  {0.047324,0.263514},
+  {-0.137376,0.214639},
+  {-0.226893,-0.197915},
+  {0.966088,-0.475559},
+  {-0.194234,-0.012569},
+  {-0.473935,-0.886494},
+  {-0.265603,0.751773},
+  {-1.593588,0.084399},
+  {1.119877,0.854302},
+  {-0.038422,0.118207},
+  {0.370947,0.914543},
+  {1.114324,0.036220},
+  {0.206356,-0.695196},
+  {1.075653,0.031579},
+  {-0.428467,0.099867},
+  {-0.942289,0.247139},
+  {-0.925418,-0.511600},
+  {-0.275870,-0.147021},
+  {0.403291,-0.774485},
+  {-0.147236,-0.816691},
+  {0.715749,-0.581534},
+  {0.714183,-0.266639},
+  {-0.530022,0.395632},
+  {-0.081142,0.308192},
+  {0.776196,-1.301781},
+  {0.402042,0.760863},
+  {0.582426,1.116527},
+  {0.303501,-1.230810},
+  {0.909943,-0.101521},
+  {-0.304997,0.216745},
+  {-0.534911,-1.278462},
+  {0.117181,0.344833},
+  {0.598680,-0.801582},
+  {-0.488952,0.298129},
+  {-0.577852,-1.244262},
+  {1.066878,-0.383162},
+  {0.365205,-0.304288},
+  {0.219744,1.047894},
+  {-0.203519,0.603274},
+  {0.562170,0.561149},
+  {0.172008,0.053308},
+  {-0.240833,-0.248882},
+  {0.374048,0.395277},
+  {-0.184462,0.712107},
+  {-0.744861,-0.403328},
+  {0.909695,-0.029738},
+  {-0.518537,0.759702},
+  {0.075402,0.358815},
+  {1.141827,-0.585600},
+  {-0.562473,0.258697},
+  {-1.676194,0.124049},
+  {0.233487,-1.891531},
+  {-0.829451,0.542206},
+  {0.671130,-0.997574},
+  {-0.508597,-0.729909},
+  {1.180725,-0.338574},
+  {1.129566,-0.232048},
+  {-0.380058,0.044743},
+  {-0.520974,0.138217},
+  {0.316724,0.009838},
+  {0.133527,-1.443095},
+  {0.420516,0.089332},
+  {-0.302825,0.028929},
+  {1.668571,-0.092751},
+  {0.452698,0.532245},
+  {0.360685,-1.949182},
+  {-0.909377,1.422417},
+  {0.108981,0.031519},
+  {0.529371,-0.320971},
+  {-0.439658,0.288459},
+  {0.212286,-0.312996},
+  {0.505587,0.680236},
+  {0.990288,-0.247507},
+  {-0.568695,-0.327833},
+  {-0.026999,-2.401438},
+  {0.339704,-0.467720},
+  {1.232324,-0.049586},
+  {-1.244245,-0.285340},
+  {-1.630956,0.212445},
+  {0.099499,0.057161},
+  {0.764231,-0.893147},
+  {0.454370,-0.132950},
+  {0.140425,0.680194},
+  {0.516606,0.024468},
+  {-0.862301,0.058704},
+  {0.505420,0.269336},
+  {-1.237570,-0.038382},
+  {0.535371,-1.536667},
+  {-0.363929,-0.038955},
+  {0.024531,0.914036},
+  {0.543681,0.532978},
+  {-0.515135,-0.698846},
+  {-0.428846,0.073398},
+  {-1.039931,0.055062},
+  {-0.621873,-1.226401},
+  {0.007829,0.811232},
+  {0.571021,-0.114346},
+  {-0.382807,0.023667},
+  {-1.068780,-1.869853},
+  {1.156098,-0.153257},
+  {0.573828,-0.535261},
+  {-0.790467,0.176901},
+  {-0.315664,0.803594},
+  {-0.334936,0.354728},
+  {-0.055522,0.952521},
+  {1.315614,0.102351},
+  {0.491766,0.538302},
+  {0.653814,-0.342202},
+  {-0.127639,-1.045441},
+  {0.819444,-0.227273},
+  {-0.029933,0.258527},
+  {-0.824566,0.432697},
+  {0.165227,-0.560056},
+  {-0.588310,0.436099},
+  {-0.421849,-0.388859},
+  {-0.090400,-1.251581},
+  {-0.533719,1.429956},
+  {0.394513,1.115320},
+  {-0.782266,0.768142},
+  {-0.197776,0.622177},
+  {-0.067525,1.525139},
+  {1.756764,0.035239},
+  {0.798450,-0.795585},
+  {-0.262068,0.632512},
+  {1.880538,-0.279111},
+  {-0.792909,-0.561815},
+  {0.888441,1.301812},
+  {0.701364,-0.873528},
+  {1.343495,-0.562411},
+  {0.868597,0.141126},
+  {-0.328745,0.918909},
+  {-0.941006,-1.339590},
+  {-1.343155,-0.049963},
+  {-0.574658,-1.478137},
+  {0.137838,0.792901},
+  {-0.041365,0.454133},
+  {0.091431,-0.459571},
+  {-1.358113,-0.736001},
+  {-0.192427,-0.926593},
+  {0.350541,0.433002},
+  {-0.084577,-0.444999},
+  {0.205895,-0.138558},
+  {-0.941218,-0.106877},
+  {-0.194195,0.335722},
+  {0.734401,-0.283139},
+  {1.613564,-0.517256},
+  {-0.090641,0.231313},
+  {0.266345,0.222315},
+  {0.518095,0.960832},
+  {0.250561,-0.619001},
+  {-0.130002,-0.001817},
+  {-0.447930,0.628615},
+  {-1.273623,0.406367},
+  {0.212427,0.986079},
+  {-0.997576,-0.940297},
+  {0.375197,0.358510},
+  {0.229471,-1.781878},
+  {0.184320,0.461606},
+  {0.434436,-0.414778},
+  {0.034886,-0.062974},
+  {-1.325976,0.135652},
+  {0.189020,-0.739167},
+  {-0.205637,-0.572855},
+  {0.860524,-0.315333},
+  {0.469117,-1.548092},
+  {-0.513513,1.158982},
+  {-0.837350,0.105504},
+  {-0.061953,-0.530778},
+  {0.293859,0.467221},
+  {-1.319548,-0.912039},
+  {-0.137013,-0.872433},
+  {0.387589,-0.454601},
+  {-0.234174,-0.245068},
+  {-0.744095,-0.128278},
+  {-0.391439,0.309053},
+  {0.908503,0.583369},
+  {0.802960,0.512355},
+  {-0.685064,1.108868},
+  {0.251810,0.543558},
+  {-0.142699,0.735253},
+  {-0.039414,-0.908746},
+  {0.003694,-0.414133},
+  {0.715774,0.070174},
+  {-0.374828,1.309546},
+  {-0.427538,0.385587},
+  {1.338794,0.002127},
+  {-0.216609,-0.694721},
+  {-1.047300,0.562533},
+  {0.397480,0.627659},
+  {-0.068233,-1.155685},
+  {-0.553008,0.472904},
+  {-0.042893,-0.644339},
+  {-0.448845,-1.208575},
+  {-1.198214,0.953970},
+  {0.997727,0.245114},
+  {0.597755,0.536424},
+  {0.056192,0.023036},
+  {-0.599560,0.905339},
+  {-0.495127,-1.106235},
+  {-0.677290,-0.536778},
+  {-0.732936,0.552336},
+  {-0.341833,0.636930},
+  {0.745283,0.226951},
+  {-1.677101,-0.140140},
+  {0.185817,1.107540},
+  {-0.845686,-0.138093},
+  {0.337944,-0.600359},
+  {1.011849,0.076595},
+  {-0.535078,0.401710},
+  {-0.509358,0.080738},
+  {-0.713136,0.201088},
+  {-0.037796,-0.459023},
+  {0.077312,0.078831},
+  {-0.674500,0.304809},
+  {0.022353,0.208630},
+  {0.234088,-0.185560},
+  {-0.100573,-0.317607},
+  {1.598601,0.170815},
+  {1.128860,0.395856},
+  {0.126361,0.194856},
+  {-0.743378,-1.283214},
+  {-0.729153,-1.745945},
+  {0.427334,0.514369},
+  {-0.260759,0.127843},
+  {0.726265,0.484686},
+  {-1.043220,1.583933},
+  {0.058154,0.202930},
+  {-0.691332,0.298501},
+  {0.914411,-0.450303},
+  {0.871508,-0.248846},
+  {-0.880065,-1.352105},
+  {-0.347400,-0.479989},
+  {-0.523254,-0.137392},
+  {0.062610,0.321808},
+  {0.583315,1.055442},
+  {-0.543484,0.434486},
+  {-0.325772,-0.127451},
+  {-0.691826,-2.465879},
+  {-0.182029,-0.371495},
+  {0.061634,0.106658},
+  {0.465593,-0.215001},
+  {0.799056,-0.576378},
+  {0.246446,0.624574},
+  {-0.629259,-0.126268},
+  {-0.332421,-0.594629},
+  {0.811796,0.672092},
+  {-0.362575,-0.952485},
+  {-0.013237,-0.559132},
+  {0.462364,-0.104255},
+  {-1.326460,-0.448336},
+  {-0.472969,-1.030240},
+  {0.263871,0.137456},
+  {0.289922,0.058766},
+  {0.129665,-0.095386},
+  {0.004142,0.060144},
+  {0.440724,0.236644},
+  {-0.648048,-0.197413},
+  {-0.313149,0.016730},
+  {-0.002432,0.336209},
+  {0.258660,1.080749},
+  {-0.622678,-0.971236},
+  {-0.756907,-0.630989},
+  {-0.511331,1.518728},
+  {0.044649,-0.192437},
+  {-0.525301,1.021474},
+  {-0.281214,0.054685},
+  {-1.829357,-0.855561},
+  {-1.000657,-0.711545},
+  {0.117003,-0.447632},
+  {0.776485,-0.166259},
+  {0.540743,0.110749},
+  {0.957454,-0.352617},
+  {1.317026,1.546090},
+  {0.140886,0.013168},
+  {-0.570171,0.392356},
+  {-0.129722,0.788992},
+  {-0.725847,0.653395},
+  {0.679142,0.364229},
+  {0.007173,-0.853037},
+  {0.914126,-0.596944},
+  {0.066525,0.639936},
+  {0.026810,0.096725},
+  {-0.538577,-0.152497},
+  {0.239321,1.002422},
+  {0.129554,-1.193610},
+  {-0.187528,0.700211},
+  {-0.645819,0.080298},
+  {0.283125,0.043507},
+  {0.350661,0.372335},
+  {-0.655806,0.541560},
+  {0.259071,0.914486},
+  {-0.920489,-0.623889},
+  {0.682493,0.379061},
+  {-0.505215,0.663097},
+  {-0.426863,-0.323863},
+  {0.363894,0.848174},
+  {-0.959164,0.304144},
+  {0.370840,0.239161},
+  {-0.576532,1.683390},
+  {0.072048,-0.479737},
+  {0.248627,-0.740696},
+  {0.267982,-1.331841},
+  {-0.742341,-0.098982},
+  {-1.397583,0.691099},
+  {0.062944,-0.918057},
+  {-0.341076,-0.572305},
+  {-0.625912,0.261916},
+  {0.000942,0.115087},
+  {-0.175561,-0.065593},
+  {0.613856,-0.651875},
+  {-0.374162,-1.289950},
+  {-0.165900,-0.183065},
+  {0.934889,-0.088622},
+  {-0.658801,-0.699260},
+  {-0.381254,-0.924817},
+  {-0.606669,0.746831},
+  {-0.801585,-0.060323},
+  {0.750367,-1.191764},
+  {0.422306,0.025905},
+  {-0.348244,-0.193827},
+  {0.533889,0.323919},
+  {-0.475731,-0.614214},
+  {1.358458,1.027040},
+  {0.041062,0.716650},
+  {1.086781,0.856076},
+  {-0.318239,-0.090265},
+  {-0.583590,-0.229458},
+  {0.280177,-0.106195},
+  {-0.066028,1.050147},
+  {0.446572,0.653688},
+  {1.619855,1.546549},
+  {-0.200833,-0.507327},
+  {1.815705,1.725080},
+  {0.491063,-0.912080},
+  {-0.302422,-0.518018},
+  {-1.497067,-0.317440},
+  {0.268533,-2.004116},
+  {-0.197770,-0.600212},
+  {0.599980,0.496906},
+  {-0.801705,-0.434370},
+  {-0.209023,-0.416797},
+  {0.089678,0.179194},
+  {0.720592,-0.140217},
+  {0.937690,0.785413},
+  {0.390751,0.123322},
+  {0.407110,-0.263791},
+  {-0.635582,0.585058},
+  {1.028085,0.038369},
+  {0.650746,-0.320141},
+  {0.273652,-0.045191},
+  {-0.773139,-0.851372},
+  {0.357316,0.497209},
+  {0.140061,0.278817},
+  {-0.416838,-1.327050},
+  {1.445687,-0.014796},
+  {0.457813,0.799090},
+  {-0.556724,0.854916},
+  {-0.641068,-0.733796},
+  {-0.186028,0.209995},
+  {0.018928,-0.915909},
+  {-0.352721,0.748722},
+  {-0.917271,0.414704},
+  {-1.388564,0.625074},
+  {-0.601451,1.435210},
+  {-0.090926,-0.755952},
+  {-0.293108,-1.116392},
+  {0.041463,-0.942099},
+  {0.666369,-0.398063},
+  {0.076754,-0.528375},
+  {0.698873,-1.134724},
+  {-0.392975,-1.312348},
+  {-0.526917,0.774984},
+  {-0.133714,-0.398997},
+  {-0.990661,-0.808244},
+  {0.208158,0.174976},
+  {-0.042402,0.479397},
+  {0.972845,-1.260660},
+  {-0.360790,2.380324},
+  {-1.161445,-0.617964},
+  {-1.369325,0.963665},
+  {0.712060,0.409267},
+  {0.061189,1.091821},
+  {0.108450,0.248626},
+  {-0.532186,0.684632},
+  {0.049827,0.344103},
+  {-0.730446,-0.644051},
+  {0.644672,0.108521},
+  {-0.311770,0.388340},
+  {0.133496,0.663978},
+  {-1.068918,-0.856697},
+  {-0.186471,-2.407906},
+  {0.497449,0.217132},
+  {0.553690,0.561973},
+  {-0.222306,0.573912},
+  {0.294889,-0.153714},
+  {-0.467937,-0.114124},
+  {0.505513,0.947824},
+  {0.835613,1.387442},
+  {0.099424,-0.647555},
+  {-1.266308,0.746230},
+  {-0.314232,-0.506824},
+  {-0.017508,1.148471},
+  {-0.005104,0.544153},
+  {1.347437,0.169568},
+  {0.736192,-2.120244},
+  {0.478583,-0.538318},
+  {-0.845261,-0.241234},
+  {0.711244,0.248858},
+  {-0.960539,0.885631},
+  {0.519557,0.157119},
+  {0.400078,-0.558660},
+  {-0.355913,-0.726436},
+  {0.620301,0.283481},
+  {0.437469,0.894420},
+  {-0.246065,-0.441159},
+  {-0.207652,0.260112},
+  {0.235413,1.202266},
+  {-0.147333,0.651418},
+  {-0.885893,-0.987513},
+  {-0.126637,-0.161050},
+  {0.198054,-0.239859},
+  {0.753221,-0.122113},
+  {0.852570,0.312679},
+  {-1.421536,0.339068},
+  {-0.608847,0.082841},
+  {0.806647,-0.618066},
+  {-0.055481,0.361346},
+  {0.524385,1.872652},
+  {-0.288788,-0.146810},
+  {-0.967147,-0.853194},
+  {1.966405,-0.833411},
+  {0.789003,-0.347270},
+  {0.015620,-0.631887},
+  {-0.150879,0.915769},
+  {-1.491238,0.217030},
+  {0.326333,1.498518},
+  {0.141223,-0.389036},
+  {-0.513646,0.793641},
+  {0.900859,0.209672},
+  {0.036641,-0.621067},
+  {-0.472702,0.503169},
+  {-0.229471,0.415297},
+  {-0.063377,-0.510807},
+  {1.772735,-0.165259},
+  {0.367308,0.204078},
+  {-0.811216,-0.742540},
+  {-0.346736,-1.336241},
+  {-0.390538,-0.215693},
+  {0.273645,0.017357},
+  {-0.411219,-0.583215},
+  {0.179285,0.386901},
+  {-0.714087,-0.705568},
+  {0.354034,-0.029101},
+  {-0.124648,-1.203258},
+  {1.036534,-0.216642},
+  {-0.079461,-0.167129},
+  {-0.519538,0.969040},
+  {-0.926647,-0.543191},
+  {-0.311806,0.129944},
+  {0.338452,0.046144},
+  {0.443791,1.037348},
+  {0.366235,0.139119},
+  {-0.436045,-0.889787},
+  {-0.487186,-0.329841},
+  {0.501924,-0.296196},
+  {-0.155070,0.928638},
+  {-2.271375,-1.096587},
+  {-0.875416,0.031515},
+  {0.034895,1.136367},
+  {1.259196,0.151467},
+  {-0.252917,0.546385},
+  {0.146755,0.215855},
+  {-1.279319,1.584790},
+  {-0.218261,-0.211344},
+  {0.838865,-0.281694},
+  {0.072992,0.018618},
+  {-1.486640,-1.384387},
+  {0.673440,0.783368},
+  {0.039087,0.485902},
+  {0.548339,-0.131470},
+  {-0.662826,2.232434},
+  {-0.724622,-0.767747},
+  {-0.737761,-0.048276},
+  {0.858736,0.000247},
+  {-0.219835,-1.241124},
+  {0.396621,-0.086901},
+  {-1.437003,0.502828},
+  {-1.537267,0.734791},
+  {0.247638,-1.034931},
+  {-0.879638,0.130748},
+  {0.532153,0.697673},
+  {0.869286,1.340851},
+  {0.477714,-0.332712},
+  {-0.081229,0.614635},
+  {-0.409415,-0.046581},
+  {0.677428,-1.891076},
+  {-0.988289,0.508962},
+  {0.887530,-0.096640},
+  {-1.348466,0.384365},
+  {-1.031462,-0.619078},
+  {-0.457756,1.980067},
+  {-1.307319,-0.821311},
+  {-0.428687,-1.927863},
+  {0.126831,0.314297},
+  {0.552891,0.191885},
+  {1.303032,-1.178928},
+  {-0.456697,0.537127},
+  {-0.138564,0.139533},
+  {-0.864216,-0.683295},
+  {0.036298,-1.122012},
+  {0.480571,-0.713238},
+  {0.192623,-0.245657},
+  {1.311303,-0.200987},
+  {0.399964,-0.611107},
+  {0.442759,1.073488},
+  {-0.696011,-1.128391},
+  {0.170959,-0.286343},
+  {1.066110,-0.985228},
+  {-0.541647,0.438916},
+  {-0.441049,1.398625},
+  {0.351268,-0.444252},
+  {-0.100225,-0.353511},
+  {-0.544437,0.471382},
+  {0.719671,0.361168},
+  {0.651644,0.499506},
+  {0.854268,-0.138822},
+  {-0.292998,-1.397932},
+  {0.351302,0.565472},
+  {-0.249761,-0.289783},
+  {0.579986,1.135063},
+  {0.380274,0.431460},
+  {0.142501,-0.768253},
+  {1.174364,-1.250559},
+  {0.124183,-0.664356},
+  {-1.775768,-0.426318},
+  {-0.410384,1.397669},
+  {-0.001185,0.082445},
+  {0.683819,0.016434},
+  {-0.474231,-1.274486},
+  {-0.227899,-0.715442},
+  {0.190972,-1.037010},
+  {0.515506,1.060213},
+  {0.574070,-0.057852},
+  {0.794263,0.456543},
+  {0.941117,0.348461},
+  {0.714095,0.442504},
+  {-1.016134,-0.621262},
+  {1.501944,-0.164696},
+  {0.859384,0.325223},
+  {0.605958,-0.405522},
+  {0.907773,-0.133478},
+  {-0.652518,0.324279},
+  {-0.223686,1.532219},
+  {0.361665,0.114357},
+  {0.118379,-1.485257},
+  {0.306623,-1.663751},
+  {-0.611527,0.305831},
+  {-0.371509,0.148804},
+  {-0.317648,0.168418},
+  {-0.579078,-0.164959},
+  {0.064958,1.214070},
+  {-1.513764,-0.019390},
+  {0.016424,2.001058},
+  {-0.457485,-0.024951},
+  {-0.847341,0.548593},
+  {-0.839426,0.760265},
+  {-0.698344,1.016456},
+  {-0.246799,0.331351},
+  {0.869786,-0.376963},
+  {-0.318179,0.256495},
+  {0.392127,-1.203653},
+  {-0.120425,-0.077075},
+  {1.005891,-0.597390},
+  {0.055568,-0.619495},
+  {0.760399,0.047681},
+  {0.293058,0.480236},
+  {0.295600,1.063913},
+  {0.595203,0.121404},
+  {0.681366,-0.184135},
+  {1.298989,-0.786985},
+  {-0.354303,0.275603},
+  {0.255593,-0.140121},
+  {1.054477,0.948719},
+  {-0.798213,0.913454},
+  {-0.582777,0.673212},
+  {-1.973554,1.089905},
+  {0.606828,-0.566130},
+  {-0.539355,-1.199468},
+  {0.086100,0.764955},
+  {0.792542,-1.548656},
+  {-0.533920,0.802166},
+  {0.132591,-0.662338},
+  {-0.061156,0.482952},
+  {-0.104437,-0.056214},
+  {-2.042381,0.317327},
+  {-0.706828,0.899494},
+  {-0.098682,0.865073},
+  {0.231769,-0.480548},
+  {-0.723515,-0.797806},
+  {-0.333745,-0.255096},
+  {1.425486,0.616569},
+  {-0.223026,-0.286492},
+  {0.945380,-0.819845},
+  {-0.836305,0.433398},
+  {0.888634,-0.227558},
+  {-0.302648,-0.403994},
+  {-0.266759,0.341454},
+  {-0.911044,0.207652},
+  {0.257598,0.267578},
+  {-0.376137,-0.484206},
+  {-0.106228,1.155262},
+  {-0.547100,-1.021943},
+  {-0.252786,0.099260},
+  {0.089525,-0.008952},
+  {-0.445924,0.184429},
+  {0.141610,-0.548673},
+  {-0.639422,-1.083761},
+  {0.498910,0.621386},
+  {0.093824,-0.107770},
+  {-0.245646,0.217584},
+  {-0.612243,-0.523719},
+  {0.457347,0.364012},
+  {-0.411336,-0.629464},
+  {-0.092268,0.204563},
+  {0.920493,-0.578667},
+  {-0.869454,-0.238633},
+  {-0.751389,0.777007},
+  {0.580578,0.705056},
+  {-1.233334,-1.695404},
+  {-0.121305,0.368160},
+  {0.782543,0.610795},
+  {0.553925,1.300069},
+  {1.374260,0.609157},
+  {-1.357033,0.843414},
+  {0.098626,-0.521365},
+  {-0.032515,0.264753},
+  {0.062218,0.085845},
+  {0.138012,-1.084788},
+  {-0.187827,1.380862},
+  {0.263689,1.028871},
+  {-1.215770,-0.552066},
+  {-0.971891,-0.672402},
+  {-0.256976,0.648996},
+  {0.007809,-0.724976},
+  {-1.053466,-0.103232},
+  {0.957392,-1.526623},
+  {0.387851,1.252142},
+  {0.298416,-0.686813},
+  {-0.249408,-0.417895},
+  {-0.524619,-0.646987},
+  {-0.101608,0.062621},
+  {0.111389,-0.960781},
+  {1.101285,0.205008},
+  {-0.120747,-0.663793},
+  {-0.602035,0.176470},
+  {1.221108,0.961762},
+  {0.159797,-0.161413},
+  {-0.233941,0.806754},
+  {1.256036,0.863057},
+  {0.259618,0.549863},
+  {0.320844,0.899846},
+  {1.030547,-0.232090},
+  {-0.517929,-0.918284},
+  {0.680314,0.060717},
+  {-0.505026,-1.527791},
+  {0.162336,0.314724},
+  {0.234991,-0.216314},
+  {1.375132,0.094076},
+  {-0.125705,-0.044844},
+  {0.657598,0.128665},
+  {0.281292,0.370853},
+  {0.027894,-0.981212},
+  {-0.732655,0.132501},
+  {-0.338577,0.250010},
+  {-1.883558,0.143130},
+  {-1.095169,-0.539749},
+  {0.166138,0.224390},
+  {-1.094189,-0.104317},
+  {-0.997375,-0.598321},
+  {-0.535645,-0.686231},
+  {1.289569,-0.268987},
+  {0.998965,0.994487},
+  {-0.349591,0.714244},
+  {-0.457773,-1.093644},
+  {-1.171475,1.478846},
+  {0.523449,0.576947},
+  {-0.610201,0.802389},
+  {1.367942,-0.063770},
+  {-1.189872,0.914725},
+  {0.408213,0.132025},
+  {-0.856124,-1.135856},
+  {-0.347681,-0.706150},
+  {0.226903,0.619634},
+  {0.548890,0.651093},
+  {-1.798606,-0.216122},
+  {-0.220157,-0.282742},
+  {0.108822,-0.485596},
+  {-0.238309,-0.347750},
+  {-0.476180,0.392785},
+  {0.428713,-0.175999},
+  {0.416074,-0.089752},
+  {1.268016,-1.407373},
+  {-0.322409,0.315716},
+  {-0.086932,-0.954776},
+  {-1.178527,1.119818},
+  {0.873189,-0.405550},
+  {-0.286794,-0.449645},
+  {0.741120,-0.039714},
+  {-0.401502,0.784565},
+  {1.378832,0.131114},
+  {-0.510286,-0.774428},
+  {-0.241374,0.226729},
+  {-0.413898,-0.710203},
+  {-0.617347,-0.040064},
+  {1.452338,-1.110283},
+  {0.018838,-0.592385},
+  {0.339572,-0.084802},
+  {0.262142,1.120113},
+  {0.382072,0.167998},
+  {-0.273583,1.253093},
+  {-0.509580,-0.586627},
+  {-1.016938,0.501199},
+  {0.530467,0.149760},
+  {0.204492,0.038013},
+  {0.074458,-0.292217},
+  {0.257628,0.451130},
+  {0.557490,-0.411723},
+  {-0.181796,-0.641207},
+  {-0.392248,-0.582808},
+  {0.705525,-0.502120},
+  {-1.021501,-0.207399},
+  {-0.060821,0.298599},
+  {-0.261969,-0.318225},
+  {-0.350443,1.831054},
+  {0.029182,0.719110},
+  {-1.269295,-1.154099},
+  {-1.488271,-1.469956},
+  {0.176535,1.097410},
+  {-1.195927,0.342358},
+  {0.582184,0.396307},
+  {-0.764560,-0.634440},
+  {0.106084,-0.378503},
+  {0.760363,0.649530},
+  {-0.020356,-0.601389},
+  {-0.423594,-0.651490},
+  {0.600149,-0.395775},
+  {0.421193,0.051504},
+  {-1.364237,0.717686},
+  {0.876530,-0.288772},
+  {-0.098973,0.266692},
+  {0.051789,0.462817},
+  {0.361495,-0.346842},
+  {-0.553109,0.940488},
+  {-0.653951,0.277526},
+  {0.163045,-0.244626},
+  {-0.126776,-0.299731},
+  {0.860475,0.302389},
+  {0.606731,-0.425179},
+  {0.305458,0.780583},
+  {1.028347,-1.635167},
+  {0.197608,1.209333},
+  {0.150105,-0.773508},
+  {-0.560487,-1.383294},
+  {-0.657034,0.108016},
+  {-0.629934,-0.335711},
+  {-0.404889,0.112022},
+  {0.350071,-0.125444},
+  {-0.397430,-0.533393},
+  {1.157015,-0.673598},
+  {0.836126,-0.091404},
+  {0.420003,0.030830},
+  {0.304754,0.940964},
+  {0.857632,-0.131707},
+  {1.482902,-0.526416},
+  {-0.506755,0.581483},
+  {0.798173,-0.622550},
+  {0.199645,0.054187},
+  {-1.166797,-0.592686},
+  {0.703425,-0.099088},
+  {0.100574,-0.652021},
+  {-0.452634,0.557510},
+  {-0.395655,0.631259},
+  {0.005128,-0.031089},
+  {-0.476422,0.288975},
+  {-0.696440,1.007601},
+  {0.651351,0.229279},
+  {-0.546184,0.967790},
+  {-1.783408,0.458041},
+  {-0.158492,0.721176},
+  {-0.829438,-0.495769},
+  {0.853862,-0.436152},
+  {-0.510630,0.354021},
+  {0.410283,-0.562993},
+  {1.333456,0.619765},
+  {0.680707,0.364967},
+  {0.768117,0.202325},
+  {-0.624035,0.194222},
+  {-0.242982,-0.068768},
+  {-0.060626,0.243812},
+  {0.918857,0.010191},
+  {-0.158575,-0.660882},
+  {0.268070,-1.046163},
+  {-0.550812,-0.916602},
+  {0.222526,-1.326576},
+  {-0.142632,1.771943},
+  {-0.500111,0.366333},
+  {0.045897,-0.931826},
+  {0.061037,-0.398634},
+  {-1.206603,1.049450},
+  {-0.346603,0.009748},
+  {-0.194651,-0.420179},
+  {-0.172385,1.200766},
+  {-0.276451,-1.221394},
+  {-0.971227,0.736046},
+  {0.849993,-0.122658},
+  {0.565771,1.029030},
+  {0.572575,-0.539519},
+  {-0.278977,0.982730},
+  {-0.406039,-0.534002},
+  {-0.022104,-0.217645},
+  {0.393789,-0.655764},
+  {-0.821859,0.222043},
+  {0.709829,-0.538537},
+  {0.309091,1.335973},
+  {0.555716,0.225149},
+  {1.155433,-0.264109},
+  {-0.224191,-0.004592},
+  {-0.076549,0.928899},
+  {0.141337,-0.500391},
+  {-0.286491,0.403995},
+  {0.340087,1.192301},
+  {-0.264734,0.101794},
+  {0.873252,-1.455120},
+  {-0.574337,0.221889},
+  {-1.110424,0.703227},
+  {0.420803,0.333899},
+  {0.277080,-0.644572},
+  {-0.747538,0.159962},
+  {0.552815,1.068068},
+  {1.368512,0.010990},
+  {-0.206001,-0.237472},
+  {0.288503,-0.659436},
+  {-0.954056,0.215502},
+  {1.548500,-0.238286},
+  {-0.889812,0.522877},
+  {-0.012439,-0.723786},
+  {-0.525273,-0.379121},
+  {-0.527515,-1.502476},
+  {0.133542,0.108887},
+  {0.492447,-0.045511},
+  {0.574807,-1.260810},
+  {0.878001,0.683264},
+  {-0.376682,-0.588180},
+  {0.164608,0.358034},
+  {0.459547,0.386397},
+  {-1.374767,0.442204},
+  {-0.699591,-0.427016},
+  {-0.228447,-1.161662},
+  {-0.322419,1.606881},
+  {0.576055,1.101472},
+  {0.563123,0.146375},
+  {0.244216,-0.241690},
+  {0.438112,-0.485327},
+  {-1.276929,0.367200},
+  {-0.181353,-1.346356},
+  {-0.146869,-0.957341},
+  {-2.198517,0.705247},
+  {-0.289717,-0.177364},
+  {0.280325,-1.142208},
+  {0.002380,0.345383},
+  {-0.418233,-1.133385},
+  {0.183564,0.534520},
+  {-0.372636,-0.051311},
+  {-0.020811,-0.085884},
+  {1.163894,-0.173220},
+  {0.616165,0.230038},
+  {-1.320575,-0.652613},
+  {0.123778,-0.062176},
+  {-0.722536,-0.008719},
+  {1.340873,0.027244},
+  {-0.294827,-0.522338},
+  {-0.602427,0.183616},
+  {-0.785766,-0.953680},
+  {-0.286187,0.348720},
+  {-0.280901,0.554931},
+  {0.380116,0.763759},
+  {0.780404,0.192032},
+  {1.328343,1.436113},
+  {-0.362877,0.085413},
+  {1.403308,-0.413647},
+  {0.773876,-0.086423},
+  {-1.316530,-0.726207},
+  {-0.379298,-0.390658},
+  {-0.150301,0.006436},
+  {0.370812,-0.684290},
+  {-0.905463,-0.548246},
+  {-0.072613,0.421906},
+  {-0.211486,0.321136},
+  {-0.247273,0.076461},
+  {-1.160356,0.131643},
+  {0.379819,-0.441965},
+  {1.064987,0.033534},
+  {-0.575692,-0.336300},
+  {-0.131156,0.299834},
+  {-0.907355,-0.562159},
+  {-0.142894,-0.067061},
+  {-0.305338,0.059685},
+  {-0.890171,-0.918641},
+  {-0.333344,0.104434},
+  {0.450288,0.236190},
+  {0.180918,-0.376193},
+  {-0.816878,0.145535},
+  {-0.789538,-1.143910},
+  {-0.022631,0.224265},
+  {-0.080696,0.591185},
+  {-0.511739,0.521540},
+  {1.522040,-1.191704},
+  {-0.120255,0.225194},
+  {-0.124457,0.484338},
+  {-0.332395,0.668069},
+  {1.358569,0.343165},
+  {-0.907961,0.303291},
+  {-0.726165,0.958101},
+  {-0.631030,-0.969657},
+  {0.187222,-0.841928},
+  {-1.702365,-0.218011},
+  {0.042628,-1.318380},
+  {0.356098,0.394505},
+  {-0.321503,-0.176962},
+  {-1.508798,0.471924},
+  {0.284711,-0.884522},
+  {-0.279981,1.075346},
+  {0.261212,0.062374},
+  {0.730161,-0.028577},
+  {1.413322,-0.696512},
+  {-0.537404,-0.498826},
+  {0.470840,-0.050515},
+  {1.075743,1.816796},
+  {0.238969,0.728689},
+  {0.021923,-0.203939},
+  {0.068466,0.691633},
+  {-0.463844,0.382524},
+  {0.536354,1.367231},
+  {-0.269568,0.317660},
+  {-0.509721,-0.056128},
+  {-0.996035,0.482343},
+  {-0.318504,0.613621},
+  {0.724407,-0.391671},
+  {-0.976483,0.002770},
+  {0.168754,-0.138651},
+  {-0.850412,0.004662},
+  {-0.778271,0.301141},
+  {-0.556300,-0.014048},
+  {-0.144566,0.581755},
+  {1.567425,-1.299013},
+  {-0.633055,-1.176258},
+  {-1.218887,1.088643},
+  {-0.057700,0.210952},
+  {-0.252005,-0.056308},
+  {-0.164041,1.200916},
+  {0.881096,-0.523409},
+  {1.271002,0.348902},
+  {0.300212,0.080781},
+  {-1.259126,-0.385348},
+  {0.380261,-0.005380},
+  {0.301990,-0.096667},
+  {-0.644417,0.661865},
+  {0.031295,-0.414362},
+  {0.513909,-0.849192},
+  {1.037724,0.167813},
+  {0.045507,0.302800},
+  {-1.007752,-0.631584},
+  {-1.626240,0.520166},
+  {0.161739,-0.005463},
+  {-1.011094,-0.296322},
+  {0.530863,-0.353709},
+  {0.919905,-1.215387},
+  {-0.399307,0.348172},
+  {0.124302,-0.831545},
+  {-1.101106,0.209511},
+  {0.423896,0.392179},
+  {-0.194011,-0.630735},
+  {-0.500591,0.215709},
+  {0.031183,0.910928},
+  {0.038389,-0.311259},
+  {-0.355431,-1.334079},
+  {0.530912,-0.294080},
+  {-0.716034,-1.092596},
+  {0.581166,0.307768},
+  {0.499546,-1.691484},
+  {-0.109812,-0.243400},
+  {0.044216,0.158567},
+  {-1.588308,-0.037482},
+  {0.222448,-1.635453},
+  {-0.184406,-0.084681},
+  {1.961808,0.936940},
+  {0.545590,0.745191},
+  {0.655076,0.761226},
+  {0.928499,-0.528748},
+  {0.311753,0.419596},
+  {1.127516,0.514393},
+  {-1.142233,-1.018180},
+  {-0.751043,0.873569},
+  {-0.003552,-0.256010},
+  {-0.055468,-0.040296},
+  {-0.461006,0.063426},
+  {0.114477,1.054606},
+  {0.646237,-0.738074},
+  {0.047691,0.563215},
+  {0.182860,-0.736483},
+  {1.006184,-0.743762},
+  {0.208249,1.194100},
+  {-0.936638,-0.678655},
+  {1.379611,-1.003314},
+  {-0.214213,0.683884},
+  {-0.412822,0.050631},
+  {0.206172,-0.486222},
+  {-0.262572,0.662397},
+  {0.484827,0.903902},
+  {1.340717,0.828282},
+  {0.376723,-0.394673},
+  {0.947224,0.377674},
+  {-1.479304,-0.488522},
+  {-0.346264,-1.112863},
+  {0.079983,-0.757019},
+  {-0.589024,-0.865351},
+  {0.154858,0.742523},
+  {-0.185417,-1.110911},
+  {0.054021,0.213561},
+  {0.049129,0.159524},
+  {0.250903,1.427318},
+  {-1.002452,-1.002884},
+  {-0.706890,0.148861},
+  {-1.154288,-0.107721},
+  {-0.817221,0.436977},
+  {-0.157997,-0.870204},
+  {1.385451,-1.059729},
+  {-0.802317,0.030557},
+  {0.536617,-0.377124},
+  {-0.267416,1.257724},
+  {0.271600,-0.064099},
+  {-0.293484,0.280734},
+  {-0.139114,-0.129475},
+  {0.480314,-0.765081},
+  {0.342935,-0.322883},
+  {0.036162,-0.632071},
+  {0.182499,0.303409},
+  {0.388280,-0.850579},
+  {-0.118716,0.915001},
+  {-0.755100,-0.436041},
+  {-0.860414,0.326513},
+  {-0.078845,0.146499},
+  {-0.454604,0.719797},
+  {-2.241604,0.049962},
+  {-1.192389,1.327719},
+  {0.375567,1.037999},
+  {0.689446,-0.703830},
+  {0.302199,-0.655993},
+  {-0.087239,0.488734},
+  {0.211377,0.892874},
+  {-1.046074,-0.479046},
+  {-1.018003,0.367627},
+  {-0.152274,1.650427},
+  {-0.779947,1.239985},
+  {0.952925,0.318968},
+  {0.643531,0.231822},
+  {-0.469200,-0.137811},
+  {0.818526,-0.988439},
+  {0.143608,-0.391619},
+  {-0.078638,-0.494635},
+  {-0.706101,-0.278646},
+  {-0.828922,0.806409},
+  {-0.198227,0.585023},
+  {-0.181743,-0.538596},
+  {0.696894,0.324933},
+  {-1.035302,-0.067149},
+  {1.116654,-0.636352},
+  {-1.447442,-0.383901},
+  {-0.842335,0.808594},
+  {-0.059386,-1.333912},
+  {0.039588,-0.568428},
+  {1.841497,0.186063},
+  {-0.222182,0.546696},
+  {-0.492511,0.065429},
+  {-0.049596,0.521704},
+  {0.950219,0.001244},
+  {0.239031,0.821970},
+  {-0.148545,-0.111477},
+  {-0.799855,0.719260},
+  {-0.198976,-0.598787},
+  {1.057029,-0.080555},
+  {-0.042454,0.198415},
+  {-0.396442,0.128443},
+  {0.356674,0.917567},
+  {0.629624,-0.252468},
+  {0.494230,0.346046},
+  {-0.203429,0.238311},
+  {-1.254628,-0.489511},
+  {-0.885587,1.273245},
+  {0.130810,-0.161627},
+  {0.060963,-0.761843},
+  {-0.216955,-1.087269},
+  {0.365978,0.094954},
+  {0.912409,0.200455},
+  {-1.054822,-0.278074},
+  {0.608031,0.908329},
+  {0.311314,-0.062994},
+  {-1.084923,-0.437044},
+  {0.483123,0.692619},
+  {0.487429,0.109963},
+  {-0.553350,0.131579},
+  {-0.992250,0.280366},
+  {-0.884746,0.002868},
+  {-0.029371,1.412446},
+  {0.678184,0.364567},
+  {-0.139078,-0.387712},
+  {-0.347524,1.175467},
+  {-1.183990,-0.650822},
+  {1.246393,-1.035660},
+  {-0.296366,0.060319},
+  {-1.583348,0.761657},
+  {-0.150878,0.717756},
+  {-0.539900,0.032499},
+  {0.538042,-0.765398},
+  {0.608876,-0.599854},
+  {0.351878,-0.018209},
+  {-0.963879,0.867025},
+  {-0.746801,0.240322},
+  {-0.264184,-0.061670},
+  {0.684332,0.011746},
+  {1.440898,-0.176096},
+  {0.229892,-1.161869},
+  {0.056788,-0.657892},
+  {-0.700251,-0.949597},
+  {-0.678207,-1.371336},
+  {0.610739,0.719252},
+  {-1.817905,-0.601268},
+  {0.031990,0.180419},
+  {0.060516,0.204577},
+  {-0.679842,1.491688},
+  {0.905999,-1.561989},
+  {-0.013397,-0.658106},
+  {0.646469,-0.124247},
+  {0.231365,-0.066460},
+  {0.072911,1.358672},
+  {0.523387,0.767592},
+  {-0.255464,-0.837687},
+  {-0.347596,0.065474},
+  {-0.118698,0.282555},
+  {0.227003,-0.532110},
+  {-0.105316,1.261845},
+  {-1.287464,0.009365},
+  {0.164639,0.004452},
+  {0.487845,-0.036515},
+  {0.237642,-0.113136},
+  {0.280221,-0.370952},
+  {-0.693740,-0.547488},
+  {-0.026475,-1.513071},
+  {0.562730,-0.294865},
+  {-0.407170,-0.821101},
+  {-0.007381,-0.255046},
+  {-0.882883,0.044493},
+  {0.458046,-0.236675},
+  {-0.280611,0.402649},
+  {0.655407,0.081470},
+  {-0.583163,0.689875},
+  {-0.126923,-0.141713},
+  {0.568498,-0.192502},
+  {0.207786,-0.707445},
+  {0.181237,-0.315024},
+  {0.452277,-0.237819},
+  {0.804749,0.161488},
+  {-0.668502,-0.165804},
+  {-0.995984,-0.756193},
+  {-1.477199,0.138328},
+  {0.224779,0.153369},
+  {0.714115,-0.105414},
+  {0.755752,-1.157271},
+  {-0.624159,0.288454},
+  {0.410050,-0.940682},
+  {-0.735226,0.333144},
+  {-0.319454,-0.151368},
+  {-0.534119,0.581015},
+  {-1.021982,0.025073},
+  {0.364749,-0.324409},
+  {-0.809700,-0.013999},
+  {-0.631631,-1.111146},
+  {0.041314,-0.401087},
+  {0.694871,0.735264},
+  {-0.367532,-1.564337},
+  {-0.580821,-0.330655},
+  {0.183537,0.598051},
+  {-0.245114,-0.399095},
+  {0.431852,-0.491440},
+  {-1.538842,0.741551},
+  {0.355387,-0.411799},
+  {0.047607,-1.484812},
+  {-0.406563,-0.099734},
+  {-0.476070,-0.974793},
+  {0.424268,-0.049799},
+  {-0.463479,0.342533},
+  {-0.021704,-0.441977},
+  {0.274849,0.092550},
+  {0.062134,0.876438},
+  {0.724167,-0.072370},
+  {-0.878909,0.087750},
+  {0.496256,-0.162627},
+  {0.279006,0.247471},
+  {1.112257,-0.008240},
+  {-0.542958,1.121075},
+  {0.883658,-1.033522},
+  {0.665774,1.218471},
+  {-0.485500,0.566506},
+  {0.101171,-0.467048},
+  {0.428733,0.037372},
+  {0.070215,0.356568},
+  {-0.115995,0.469828},
+  {-0.288060,0.751706},
+  {-0.893341,-0.479910},
+  {0.129788,-0.712225},
+  {0.607605,-0.659464},
+  {-0.928870,0.184671},
+  {1.532564,0.622921},
+  {-0.259213,0.773723},
+  {-0.613180,1.165169},
+  {-0.246855,0.477170},
+  {-0.763396,0.185209},
+  {0.176437,-0.026025},
+  {0.238849,0.442184},
+  {-0.352254,-0.531682},
+  {0.807799,-0.627800},
+  {0.047221,0.691612},
+  {-1.063426,-0.086542},
+  {0.127711,-0.873769},
+  {-0.266249,-0.401636},
+  {-0.792988,0.561747},
+  {1.359199,0.175116},
+  {0.055027,0.221748},
+  {-0.811887,0.783136},
+  {-0.242847,1.170197},
+  {0.603982,-0.386618},
+  {-0.066028,-0.887924},
+  {0.195072,-0.461362},
+  {-0.124588,-1.349309},
+  {-0.923671,0.021243},
+  {0.672608,0.390882},
+  {-0.157503,0.476204},
+  {0.395069,1.581050},
+  {0.546212,0.493126},
+  {-0.275470,-0.171620},
+  {0.279435,0.010272},
+  {0.398665,-0.060216},
+  {-0.540549,-0.545716},
+  {-0.203679,0.332363},
+  {-0.496097,-0.577372},
+  {0.580802,0.437667},
+  {1.112826,-0.947356},
+  {-0.740122,-1.666636},
+  {0.794783,-1.131704},
+  {-0.942124,-0.854277},
+  {-0.673412,0.214855},
+  {-0.147656,0.291988},
+  {-0.104863,0.388239},
+  {0.076779,0.606955},
+  {0.200388,0.524721},
+  {-0.320980,0.897459},
+  {0.075462,0.168864},
+  {1.058383,-0.217411},
+  {-0.257135,-0.135694},
+  {-0.967934,-0.164808},
+  {-0.923465,1.535662},
+  {-0.342228,0.493143},
+  {0.950437,0.330328},
+  {1.159788,0.029407},
+  {0.519360,-0.289634},
+  {-0.387919,0.756822},
+  {0.110258,-0.324655},
+  {-0.834385,0.057787},
+  {0.385197,0.770062},
+  {-0.865068,-0.695108},
+  {-0.163616,0.499126},
+  {-0.260925,0.174936},
+  {0.269825,-0.563868},
+  {0.085977,0.711242},
+  {-0.154136,-0.310298},
+  {0.667896,0.312458},
+  {0.455000,0.511352},
+  {-0.119230,0.565919},
+  {0.448509,-0.266193},
+  {-0.076594,0.711581},
+  {0.487758,-0.084284},
+  {-0.134384,0.512608},
+  {-0.073188,-1.588799},
+  {0.263813,-1.537716},
+  {-0.318161,0.668523},
+  {0.716481,1.034983},
+  {0.100407,0.603227},
+  {1.278314,0.725134},
+  {-1.102419,-0.668425},
+  {-1.533689,-0.122580},
+  {-0.015321,-0.363228},
+  {-0.354993,-0.049059},
+  {0.234433,-0.176360},
+  {1.531154,1.445120},
+  {0.196174,-0.704589},
+  {0.939701,0.188199},
+  {-0.883210,-0.154533},
+  {0.533736,1.018771},
+  {1.025444,-0.745913},
+  {-0.224936,0.074982},
+  {-0.445386,-0.861890},
+  {0.037407,-0.227981},
+  {-0.186347,-1.290577},
+  {-0.309371,0.403374},
+  {-0.532396,0.613887},
+  {2.165530,1.358975},
+  {2.007988,-0.415721},
+  {1.170118,1.184736},
+  {0.147671,0.285319},
+  {0.189048,-1.372490},
+  {0.572345,-0.160934},
+  {-0.968055,0.078689},
+  {-0.838057,0.005487},
+  {0.002971,0.754035},
+  {0.963936,-1.052451},
+  {1.384693,-0.238220},
+  {0.730919,-0.253514},
+  {-0.055962,-1.239576},
+  {-0.971576,0.081729},
+  {1.592811,0.554873},
+  {0.891373,-1.465274},
+  {-0.436801,0.681487},
+  {0.781594,-0.567997},
+  {-0.734441,-0.356614},
+  {-0.417233,0.307766},
+  {-0.342015,-0.643618},
+  {-0.292766,-0.377798},
+  {0.524786,0.511648},
+  {-0.581227,1.232650},
+  {-0.014453,0.621820},
+  {0.249726,0.375897},
+  {0.606730,-0.436103},
+  {0.470665,1.092492},
+  {0.049061,0.242758},
+  {0.356517,0.602295},
+  {-0.136680,-0.171375},
+  {0.138788,0.924838},
+  {1.014005,-0.233081},
+  {-1.201889,0.445990},
+  {1.026871,-0.586108},
+  {0.489435,1.106440},
+  {-0.647070,0.966539},
+  {0.412053,0.403891},
+  {1.508765,0.651857},
+  {0.967302,0.360629},
+  {0.643439,0.542859},
+  {0.009643,0.167438},
+  {-0.043095,-0.479629},
+  {-0.427617,-0.891696},
+  {0.262743,0.496652},
+  {0.399848,0.055136},
+  {0.389352,-0.140837},
+  {-0.874961,-0.286650},
+  {-1.148781,0.964809},
+  {-0.075158,-1.058411},
+  {-1.356972,0.477178},
+  {-0.583056,0.785091},
+  {0.180521,0.643195},
+  {-0.341790,0.582116},
+  {0.617637,-0.386019},
+  {0.287523,-0.641069},
+  {0.445544,-1.046088},
+  {0.056885,0.909019},
+  {0.237974,-0.577966},
+  {0.265120,0.170968},
+  {0.831315,0.261175},
+  {-0.053478,0.750541},
+  {-0.910915,0.305149},
+  {0.740491,0.199702},
+  {-0.644430,0.804073},
+  {-0.032674,0.043810},
+  {0.506929,0.722204},
+  {-1.458642,-0.012285},
+  {1.125423,-0.870600},
+  {-0.413975,-1.013859},
+  {0.263494,-0.250882},
+  {-0.509992,0.642512},
+  {0.309917,0.102069},
+  {0.432682,-0.594946},
+  {0.389074,-0.347972},
+  {0.363322,0.447382},
+  {0.409466,0.684147},
+  {-0.383569,1.103528},
+  {0.400605,1.027698},
+  {-0.244181,-1.174979},
+  {-0.138094,-0.035489},
+  {-0.732504,-1.119719},
+  {0.401623,-0.226204},
+  {-0.009444,-0.493273},
+  {-0.623539,0.052497},
+  {-0.082322,0.624134},
+  {-0.241276,0.692779},
+  {-0.855399,-0.954111},
+  {-0.102812,0.455049},
+  {-0.163148,-0.813131},
+  {0.632547,-0.140929},
+  {0.494530,-0.185368},
+  {-0.193079,-0.723176},
+  {0.337338,-0.445788},
+  {0.401790,0.559695},
+  {0.230591,-0.192288},
+  {-0.300693,-0.121974},
+  {1.384646,-0.585677},
+  {0.325791,-0.040454},
+  {-0.012575,0.226125},
+  {-1.008117,-1.345584},
+  {-0.253066,-0.722583},
+  {0.510556,-1.634320},
+  {-0.620574,0.638105},
+  {0.744498,-0.848184},
+  {-0.604678,0.294828},
+  {0.576435,-0.241527},
+  {-0.209046,1.633283},
+  {-0.037161,-0.383274},
+  {-0.522555,-0.336960},
+  {0.454551,0.473618},
+  {-0.155145,-0.383863},
+  {0.691671,0.364433},
+  {0.110858,-0.308247},
+  {0.291931,-0.200529},
+  {-0.257731,-0.294773},
+  {-0.297832,-0.078972},
+  {-1.000551,-0.056650},
+  {-0.728054,1.617977},
+  {0.683715,-0.328680},
+  {-0.000525,0.011541},
+  {0.620598,-0.661930},
+  {0.264711,-0.928142},
+  {0.228987,-0.335306},
+  {-0.244599,-0.068855},
+  {-0.836542,-0.817358},
+  {0.092673,0.460987},
+  {-1.129502,-0.114615},
+  {-0.632434,0.515582},
+  {0.031820,0.686984},
+  {0.770886,-0.492505},
+  {-0.596480,1.289307},
+  {-0.101952,-0.691478},
+  {-0.104274,-0.131200},
+  {-0.625558,-1.086399},
+  {0.877969,-0.772245},
+  {0.268059,-0.223637},
+  {-0.900697,1.204608},
+  {0.050722,0.907601},
+  {0.673273,0.381280},
+  {-2.047377,-0.460464},
+  {-0.180485,0.585813},
+  {0.917693,-0.593887},
+  {-0.800537,0.647290},
+  {-0.440595,0.183335},
+  {-0.713969,-0.073229},
+  {-0.774967,-0.149180},
+  {0.404131,0.588253},
+  {-0.461998,-0.696968},
+  {0.274178,-0.357117},
+  {0.206730,0.108627},
+  {-1.064527,-0.450529},
+  {0.868135,-0.511465},
+  {1.861500,-0.019361},
+  {-0.168042,0.157278},
+  {-0.306666,-0.372632},
+  {-0.358648,0.439013},
+  {-0.508541,0.110548},
+  {0.429907,0.318529},
+  {0.768140,0.536835},
+  {-0.468226,-0.061801},
+  {-0.479689,-0.447397},
+  {1.419374,-0.900772},
+  {1.265393,-0.725799},
+  {-1.446047,0.967326},
+  {-1.003305,-0.450572},
+  {-0.765069,-0.367291},
+  {0.058085,0.520892},
+  {0.507400,0.307971},
+  {-0.096135,0.082836},
+  {0.499087,-0.483651},
+  {0.786245,-0.896910},
+  {-0.776823,-0.917120},
+  {0.046113,-0.674221},
+  {0.437166,-0.946565},
+  {-0.481481,0.348660},
+  {-0.303571,-1.297511},
+  {0.184266,-0.433271},
+  {0.351287,0.490834},
+  {0.136868,0.207400},
+  {-0.928643,-0.705652},
+  {0.411477,-0.296834},
+  {-0.130098,0.423371},
+  {0.256138,0.201198},
+  {1.325804,-1.394897},
+  {-0.987536,0.911194},
+  {0.467954,0.721556},
+  {-1.111917,-0.388390},
+  {-0.225829,-0.194731},
+  {0.686892,0.002306},
+  {0.017090,-0.337756},
+  {0.320620,0.701407},
+  {-0.126604,-0.448189},
+  {-1.038320,0.350680},
+  {0.525033,-0.775856},
+  {1.423413,-0.907011},
+  {-0.654169,1.310124},
+  {-0.256723,-1.274182},
+  {-0.148799,1.158405},
+  {-1.309938,-0.423753},
+  {-0.822022,0.520373},
+  {-0.487639,-0.029609},
+  {-1.731135,1.225201},
+  {0.860007,0.817290},
+  {1.085528,-0.477385},
+  {0.170410,0.225994},
+  {0.130012,0.501964},
+  {1.362920,-1.040532},
+  {0.274595,-0.360680},
+  {-0.180443,-1.150807},
+  {-1.010892,-2.785690},
+  {-0.185408,0.645141},
+  {0.408186,0.598987},
+  {-0.276912,-0.233762},
+  {-0.554369,0.384061},
+  {-0.313129,-1.273413},
+  {-0.295076,-0.206805},
+  {-1.135422,0.314641},
+  {-0.091967,1.316718},
+  {-1.148036,0.420483},
+  {0.464056,0.070829},
+  {0.643956,-1.132460},
+  {0.007388,-0.087534},
+  {-0.670980,-0.644856},
+  {-0.562657,0.103308},
+  {-0.910544,-0.624181},
+  {-1.294871,-0.704342},
+  {0.253288,-1.249465},
+  {0.010697,-0.206204},
+  {0.032296,-0.068846},
+  {0.227298,0.289679},
+  {-1.018986,0.376146},
+  {0.196228,0.336658},
+  {0.324491,0.481509},
+  {1.401432,-1.385349},
+  {0.469776,-0.021242},
+  {-0.359218,0.077900},
+  {0.263855,-0.553276},
+  {-1.338136,1.760596},
+  {0.345680,-0.356526},
+  {0.967508,-0.348957},
+  {-0.000197,-0.317256},
+  {0.266182,0.209979},
+  {0.645966,-0.065156},
+  {0.095471,0.687960},
+  {-0.950904,0.472007},
+  {0.237504,1.029535},
+  {-1.188493,0.582823},
+  {0.037901,0.276498},
+  {1.500981,0.033858},
+  {0.470859,0.204791},
+  {-0.325697,-0.511828},
+  {-0.701164,-0.624759},
+  {-1.022831,0.029449},
+  {-0.617654,-0.209681},
+  {-1.086358,-0.753587},
+  {-0.620495,0.350436},
+  {0.255824,0.780289},
+  {0.259997,0.853987},
+  {0.178984,0.708660},
+  {0.206355,0.342937},
+  {-0.203803,0.123989},
+  {0.087570,-0.018768},
+  {-0.251778,0.402282},
+  {-0.067944,0.802752},
+  {0.814430,-1.075422},
+  {0.980073,0.924960},
+  {-0.643462,0.281085},
+  {-0.043385,0.222169},
+  {0.150379,-0.073680},
+  {-0.866595,-0.370094},
+  {0.070700,-0.031495},
+  {-0.718160,-0.057721},
+  {-1.453375,0.891355},
+  {0.289324,0.775060},
+  {0.181655,0.483275},
+  {-0.752997,-0.073676},
+  {-0.304538,-1.541777},
+  {-0.709192,0.581410},
+  {0.492839,-0.517246},
+  {0.183811,-0.156000},
+  {0.653373,0.230724},
+  {0.406458,0.005703},
+  {-0.311049,0.812297},
+  {-0.520574,0.204449},
+  {0.054290,-0.724717},
+  {0.094583,-0.073227},
+  {0.038531,1.556567},
+  {-0.384123,-0.654494},
+  {0.561946,-0.464299},
+  {-0.404523,-0.766166},
+  {-0.481575,0.460856},
+  {-1.907571,-0.823209},
+  {2.101905,0.161585},
+  {0.287454,-0.132443},
+  {1.242270,0.686925},
+  {-0.921165,-0.565261},
+  {0.611637,0.513699},
+  {0.049954,-1.129081},
+  {-0.501940,0.054891},
+  {1.429713,-0.551187},
+  {-0.836163,-0.446508},
+  {0.278495,0.087073},
+  {0.218168,-0.779450},
+  {-0.223319,-0.407988},
+  {0.634553,-0.616996},
+  {1.182395,0.959111},
+  {-0.978832,0.211972},
+  {0.424967,-0.249287},
+  {-0.041136,-0.865872},
+  {0.678616,0.138109},
+  {-0.183760,0.626009},
+  {0.774335,0.071065},
+  {-0.711756,0.994632},
+  {-1.071178,-0.459611},
+  {-0.483535,0.070145},
+  {-1.195615,0.843780},
+  {-0.466068,-0.769168},
+  {-0.277629,-1.090422},
+  {0.421671,-0.180614},
+  {0.412349,0.215483},
+  {0.770770,-1.211197},
+  {0.216869,-1.257316},
+  {1.131962,1.071910},
+  {0.604317,1.569760},
+  {-0.432696,-0.511691},
+  {1.490919,0.544307},
+  {0.722433,-0.223854},
+  {-0.747281,0.587934},
+  {0.591043,-0.389259},
+  {0.915617,0.907123},
+  {-0.090304,0.260222},
+  {-0.286085,0.181432},
+  {-1.366335,0.134996},
+  {1.006915,-0.256088},
+  {-0.742269,-0.287000},
+  {-0.560519,0.149843},
+  {0.228870,-0.089042},
+  {0.485062,1.555019},
+  {-2.098179,-1.037507},
+  {0.281221,0.160181},
+  {1.124136,0.576409},
+  {0.377565,0.179290},
+  {-0.774858,-0.594426},
+  {0.057609,0.773926},
+  {-0.352908,0.659389},
+  {-0.214422,-0.486733},
+  {1.185269,-0.773319},
+  {2.361595,0.580060},
+  {-0.480781,0.323322},
+  {-0.280537,0.592566},
+  {-0.518135,1.090907},
+  {0.038454,-0.673850},
+  {-0.396300,0.291648},
+  {0.431237,-0.742958},
+  {-0.354511,-0.258468},
+  {0.589504,-0.340787},
+  {0.350439,0.872189},
+  {0.434521,0.321774},
+  {-0.033107,0.105060},
+  {0.708078,-0.753049},
+  {0.529888,-0.271240},
+  {0.536421,-1.059462},
+  {-0.225809,-0.688310},
+  {1.434065,0.509015},
+  {-0.173576,0.479379},
+  {-1.128043,-1.200555},
+  {-0.400962,0.006900},
+  {-0.193926,0.797977},
+  {0.890121,-0.520395},
+  {0.483454,-0.759030},
+  {0.120016,0.881875},
+  {-0.600343,-0.651720},
+  {-1.451600,-1.029965},
+  {0.761142,0.319997},
+  {-0.112053,-1.155185},
+  {1.220439,1.751782},
+  {1.160185,0.688299},
+  {-0.512242,-0.051162},
+  {-0.706967,-0.136270},
+  {0.615304,1.293581},
+  {-1.400761,0.916505},
+  {1.187036,0.351908},
+  {0.080335,-1.965701},
+  {-1.630052,0.439980},
+  {-1.391160,0.129870},
+  {1.155798,0.582881},
+  {-0.065111,-1.099486},
+  {0.125533,-0.003002},
+  {-0.164680,0.102916},
+  {0.466728,0.343552},
+  {0.762902,0.475304},
+  {0.744999,-0.654491},
+  {-1.398257,0.311517},
+  {-0.237558,-0.246793},
+  {0.428761,0.156024},
+  {0.570756,0.535184},
+  {2.016382,-0.060246},
+  {-1.088301,0.681331},
+  {0.830869,-0.097576},
+  {0.388942,1.207765},
+  {-0.606217,-0.034154},
+  {-0.231597,-0.930088},
+  {-1.380885,-0.946200},
+  {1.243384,-0.076184},
+  {-0.876585,1.046718},
+  {0.966272,0.210433},
+  {-0.291174,0.271509},
+  {0.211819,0.974055},
+  {-0.463701,-0.565772},
+  {0.487341,-0.602470},
+  {-1.121183,-0.165544},
+  {-0.252906,0.474726},
+  {-0.402199,0.851284},
+  {0.080496,-0.760036},
+  {0.025413,-1.091766},
+  {0.547332,-0.330242},
+  {-0.672557,0.494495},
+  {0.954815,-0.310860},
+  {0.424952,0.387591},
+  {-0.206481,-1.215096},
+  {-0.565978,0.308471},
+  {-0.594998,0.287291},
+  {0.244841,-1.011218},
+  {-0.121897,-0.182509},
+  {0.436936,-0.388815},
+  {-0.237612,0.125997},
+  {0.469551,0.559430},
+  {-0.150812,0.430465},
+  {-0.309672,-0.159915},
+  {-0.041266,-0.484249},
+  {-0.498416,0.134495},
+  {-0.216836,-0.600673},
+  {0.753550,0.178144},
+  {-0.829567,0.580848},
+  {0.151586,0.985193},
+  {-0.030831,0.835093},
+  {-1.336242,-0.274785},
+  {0.877728,0.795873},
+  {-1.272274,-0.088021},
+  {0.329721,0.397562},
+  {0.284857,-0.480608},
+  {0.682917,0.080741},
+  {-0.101889,-0.248454},
+  {-0.682076,1.494906},
+  {0.629653,0.954928},
+  {-0.543290,1.090091},
+  {1.459454,0.219865},
+  {0.242040,-0.001250},
+  {1.335699,-0.279217},
+  {-0.929197,-0.177255},
+  {-1.073987,-0.628953},
+  {-0.603636,0.406831},
+  {-0.127502,-0.233138},
+  {-0.595331,-1.556322},
+  {-0.003979,-0.372901},
+  {-0.071019,0.395963},
+  {0.367574,-1.213747},
+  {-0.334848,-0.212891},
+  {0.545672,0.431015},
+  {-0.319922,-1.488089},
+  {1.622107,-0.160144},
+  {-0.443496,-0.342474},
+  {-0.182690,0.814460},
+  {0.294580,0.439232},
+  {-0.456404,-0.781690},
+  {-0.239482,0.065164},
+  {0.522642,0.114414},
+  {0.220545,0.027521},
+  {0.928442,-0.357315},
+  {-0.037976,0.045284},
+  {0.271085,-0.280372},
+  {1.126150,-0.692677},
+  {0.605778,-0.288038},
+  {-0.839818,0.853392},
+  {-0.017924,-0.218859},
+  {0.193144,0.838310},
+  {0.382364,-0.079117},
+  {-1.218131,-1.625995},
+  {0.587757,-0.067836},
+  {1.112485,-0.821042},
+  {-1.079681,1.113467},
+  {0.739449,0.903260},
+  {-0.337197,-0.539171},
+  {-0.715782,0.433698},
+  {-0.681131,-1.078419},
+  {-0.399622,-0.481035},
+  {0.985279,0.921888},
+  {-0.886267,-0.759144},
+  {0.477293,-0.151442},
+  {-0.382453,-0.131280},
+  {-0.996212,-0.422600},
+  {0.704734,0.607694},
+  {0.134826,0.350086},
+  {-0.256879,0.214261},
+  {-0.492210,-1.268288},
+  {0.269138,1.401154},
+  {-0.717996,0.256866},
+  {0.058280,-0.897792},
+  {0.335278,-0.190030},
+  {-0.247184,-0.605186},
+  {0.020146,0.328500},
+  {-1.189915,0.129145},
+  {0.215961,1.303383},
+  {0.478757,0.180930},
+  {-0.299342,-0.948503},
+  {-1.146943,0.060521},
+  {-0.868843,-1.063643},
+  {0.923269,-0.045103},
+  {-0.878523,1.072741},
+  {0.151682,-0.385870},
+  {1.248675,0.859689},
+  {0.583381,-0.622081},
+  {-0.427717,-0.653473},
+  {0.114755,1.122795},
+  {0.715533,-1.419478},
+  {-0.653173,-0.975489},
+  {0.388866,-0.494883},
+  {0.991641,-1.615541},
+  {1.623819,-0.756583},
+  {-0.477507,-0.049437},
+  {-0.921536,-0.203534},
+  {0.524950,-1.209924},
+  {0.015214,0.484588},
+  {-0.744276,-0.907266},
+  {-0.256785,0.726990},
+  {-0.989783,0.236785},
+  {-0.927026,0.190489},
+  {-1.224202,0.044595},
+  {0.695077,-0.066990},
+  {0.118911,0.317058},
+  {0.216068,0.148307},
+  {0.147362,0.344791},
+  {-0.335603,0.447019},
+  {-1.224890,-0.325840},
+  {0.002756,-0.321191},
+  {-0.160248,1.419446},
+  {1.272372,-0.411115},
+  {0.090553,-0.020891},
+  {-0.813158,0.552475},
+  {-1.298817,0.862553},
+  {-0.585694,1.251896},
+  {-0.013283,-0.413138},
+  {-0.297463,-0.903216},
+  {-0.255549,1.091331},
+  {-0.206760,0.800369},
+  {-0.390704,0.606333},
+  {0.513017,-1.429631},
+  {0.433862,2.005801},
+  {-0.383853,-0.598873},
+  {1.005859,0.614970},
+  {0.851717,0.475903},
+  {0.326298,0.574711},
+  {-0.558315,0.661107},
+  {0.524201,0.697230},
+  {0.354126,-1.373313},
+  {-0.935029,0.948730},
+  {-0.134743,0.135532},
+  {0.276808,1.185467},
+  {0.018978,0.217541},
+  {-0.112404,1.728553},
+  {-1.302444,0.146517},
+  {0.311354,-0.511768},
+  {-0.162418,1.170043},
+  {1.221405,-0.185509},
+  {0.187501,-0.388756},
+  {-0.992425,0.895706},
+  {0.010906,-0.436499},
+  {-1.151269,-0.978387},
+  {0.331651,2.365055},
+  {-0.261792,-0.105662},
+  {-0.015082,-1.027851},
+  {-0.566662,-0.066912},
+  {0.333652,0.030599},
+  {-0.580868,1.197625},
+  {-0.698983,-0.072313},
+  {-0.336455,0.586318},
+  {-0.460653,-1.130129},
+  {1.129557,-0.342097},
+  {0.675431,-0.111390},
+  {0.656948,-1.198251},
+  {0.124118,0.471617},
+  {0.873740,-0.661021},
+  {0.883188,-0.120431},
+  {-0.231922,0.823063},
+  {-0.037173,0.803393},
+  {0.249852,-0.697130},
+  {-0.608230,0.681932},
+  {-0.243067,-0.598592},
+  {1.280129,0.144530},
+  {0.335054,-0.507225},
+  {-0.148178,0.471538},
+  {-1.320556,0.648198},
+  {0.793534,0.184092},
+  {0.175364,0.260736},
+  {-0.345658,-1.638374},
+  {-0.954853,0.361345},
+  {-0.439794,-0.209984},
+  {-0.580261,-0.437008},
+  {-0.042380,-1.008410},
+  {-0.256240,0.240739},
+  {0.997668,0.041341},
+  {0.084286,1.337007},
+  {-0.089726,0.349824},
+  {-0.351226,-0.439389},
+  {0.789935,-0.231385},
+  {0.559332,0.372916},
+  {0.431332,-0.309163},
+  {0.438769,0.729816},
+  {-0.709308,-0.453381},
+  {-0.806887,0.031475},
+  {-0.109243,0.296421},
+  {1.053895,-0.808360},
+  {1.310377,-0.018203},
+  {-0.088228,0.464224},
+  {0.404860,1.091152},
+  {0.980650,-0.822832},
+  {-0.182331,0.154915},
+  {-0.416259,0.293648},
+  {-1.202575,0.608544},
+  {-0.939778,0.311341},
+  {0.362085,-0.732201},
+  {0.318978,-0.637671},
+  {-0.485214,0.461226},
+  {-0.302925,-0.728450},
+  {0.411979,-0.138660},
+  {-0.429297,-0.510534},
+  {-1.260831,-0.795375},
+  {0.852526,-0.602336},
+  {-0.795936,0.503556},
+  {-1.379397,-0.490658},
+  {0.325956,-1.584800},
+  {-0.223558,0.569081},
+  {0.081155,0.347926},
+  {-0.295295,0.593889},
+  {1.147863,0.678079},
+  {0.666420,0.268891},
+  {0.335919,-0.387414},
+  {1.884109,-0.565796},
+  {-1.155022,-0.181474},
+  {-0.083694,0.434470},
+  {-0.431032,-0.709799},
+  {0.867853,-0.661146},
+  {1.308108,-0.705654},
+  {0.441709,0.237870},
+  {0.906238,0.160666},
+  {0.263269,-0.911975},
+  {1.316673,0.073375},
+  {0.495316,0.359938},
+  {-0.137338,-0.098128},
+  {1.551014,-0.986343},
+  {0.852076,-0.721691},
+  {0.453226,0.292144},
+  {1.095678,-0.511793},
+  {-0.038954,1.062364},
+  {0.808936,-0.562206},
+  {-0.290931,-0.645168},
+  {0.256794,0.145837},
+  {-0.849594,0.501363},
+  {0.383039,-0.725827},
+  {0.191017,0.987863},
+  {-0.260132,0.407206},
+  {0.386396,-1.059209},
+  {-0.377412,-0.745123},
+  {-0.291906,-0.531367},
+  {-0.405497,0.709018},
+  {0.620085,0.652872},
+  {-0.848280,-0.510761},
+  {0.284859,0.615713},
+  {0.348772,-0.207622},
+  {-0.055816,1.039482},
+  {0.334478,0.209594},
+  {1.605196,-0.420670},
+  {-0.605169,-0.084273},
+  {0.630320,0.781429},
+  {0.014900,-0.362734},
+  {0.894942,-0.727579},
+  {0.067741,0.754466},
+  {0.949988,-0.066743},
+  {-0.253311,-0.959373},
+  {-0.348181,0.499553},
+  {0.059039,-0.130159},
+  {-0.127018,-0.015114},
+  {0.113024,-0.379652},
+  {-0.474835,-0.334921},
+  {0.787752,1.233290},
+  {0.730310,-0.362158},
+  {-0.043029,0.764059},
+  {0.702234,0.977776},
+  {-0.707870,0.675695},
+  {-0.746668,-0.056283},
+  {-1.427597,0.548321},
+  {-0.889836,-0.322518},
+  {0.559716,-0.205609},
+  {0.866683,-0.427771},
+  {0.190978,-0.991563},
+  {-0.904855,0.124091},
+  {0.050012,-0.833915},
+  {-0.237735,0.753702},
+  {1.054057,-0.159998},
+  {-1.311705,-0.141423},
+  {-0.167340,-0.857237},
+  {0.299898,-2.073567},
+  {1.438581,0.978587},
+  {-0.643269,-0.584753},
+  {0.133317,0.494257},
+  {-0.649429,0.374599},
+  {0.275902,-1.538577},
+  {1.198951,-0.760458},
+  {-1.385012,-0.069386},
+  {-1.281703,-0.058265},
+  {-0.555278,-0.011261},
+  {-2.004580,-0.558871},
+  {0.177745,-0.102492},
+  {0.172073,-0.727798},
+  {0.435496,-0.446889},
+  {0.636023,-1.534272},
+  {0.316862,0.134926},
+  {-0.152594,-0.252641},
+  {1.716484,-0.760875},
+  {0.577497,1.141460},
+  {0.259169,0.340464},
+  {0.148970,-0.160064},
+  {1.170360,0.759366},
+  {-0.411688,0.120789},
+  {0.282131,-0.723614},
+  {-0.570560,-0.471775},
+  {0.394987,0.179098},
+  {0.078922,-1.605195},
+  {1.222166,0.705268},
+  {0.112494,0.182192},
+  {-0.419529,-0.187154},
+  {-1.690670,-0.646314},
+  {-1.058211,0.228100},
+  {0.214788,0.185218},
+  {0.288251,0.244880},
+  {-1.430080,-1.445750},
+  {0.247476,-0.302103},
+  {0.265110,-0.804134},
+  {1.164424,1.113711},
+  {0.311110,-1.210742},
+  {0.796506,0.428281},
+  {-0.316142,-0.291436},
+  {-0.440177,-0.503075},
+  {0.097647,-0.178009},
+  {0.663421,0.217058},
+  {0.665703,-0.958534},
+  {0.310222,0.430380},
+  {1.264676,0.514635},
+  {0.652022,-0.675808},
+  {0.546673,-0.732842},
+  {-1.412238,0.029713},
+  {1.812263,-0.439160},
+  {-0.059908,-0.137715},
+  {0.717444,-0.127056},
+  {-0.231742,0.293963},
+  {0.953017,0.337998},
+  {-0.259151,0.250980},
+  {0.052105,-0.381903},
+  {0.152729,-1.519173},
+  {-0.591415,-0.657243},
+  {-0.150356,0.561554},
+  {0.049513,-0.328535},
+  {0.980559,-0.235285},
+  {1.255975,-0.268207},
+  {0.054851,0.313362},
+  {1.065817,0.798603},
+  {0.333122,0.943230},
+  {0.173731,1.244529},
+  {-0.137778,1.175759},
+  {-0.572404,-0.089366},
+  {-1.084071,0.201398},
+  {-0.302239,-0.089035},
+  {-2.102849,0.327512},
+  {-0.071969,0.048153},
+  {-0.987305,0.609359},
+  {0.045616,-0.070737},
+  {0.255401,-0.350403},
+  {-0.325866,-0.684457},
+  {-0.949723,-0.234736},
+  {0.084110,-0.655785},
+  {0.250549,1.066458},
+  {0.025403,-0.832694},
+  {-0.995800,0.738287},
+  {0.298398,1.547136},
+  {-1.442081,0.084168},
+  {0.067213,-0.221365},
+  {0.242559,0.174805},
+  {-0.326723,-0.622174},
+  {0.223836,-0.637175},
+  {0.811831,-0.299335},
+  {0.773214,0.551379},
+  {0.392211,-0.445570},
+  {-0.284968,-0.265439},
+  {-0.881859,1.508451},
+  {-0.347475,-0.325761},
+  {-0.616885,-0.769191},
+  {0.576795,-0.557282},
+  {0.047390,0.337606},
+  {-0.097859,1.780184},
+  {-0.429312,1.112392},
+  {-0.524623,0.219636},
+  {0.405006,-0.298594},
+  {0.382213,-1.012895},
+  {-0.976113,-0.643431},
+  {-0.135279,0.069899},
+  {-0.077138,0.056443},
+  {-0.622842,-0.648767},
+  {-0.142333,-0.385734},
+  {0.939501,1.168477},
+  {-0.090723,-0.021190},
+  {0.941865,-1.007430},
+  {-0.986187,0.958079},
+  {0.375743,0.363480},
+  {-0.381949,-0.320752},
+  {1.268664,-0.616885},
+  {0.136944,0.263353},
+  {-2.053794,0.961262},
+  {-0.684081,-1.224868},
+  {0.599383,0.140131},
+  {-0.032657,0.782458},
+  {0.385562,-0.313714},
+  {0.404669,0.093627},
+  {1.091659,0.677779},
+  {-0.253105,-0.859333},
+  {-0.324104,0.386444},
+  {-1.904799,-0.146740},
+  {0.373496,0.440722},
+  {1.125800,0.354270},
+  {-0.276754,-0.390405},
+  {0.553166,-0.230742},
+  {0.345504,1.257560},
+  {0.326855,0.709150},
+  {0.168127,0.088543},
+  {0.349772,-0.368904},
+  {-0.285477,-0.469480},
+  {0.523761,-0.504454},
+  {0.904464,-0.016717},
+  {0.081565,-0.511504},
+  {0.885394,0.427703},
+  {-0.042153,0.607306},
+  {-0.240457,-0.369428},
+  {-0.476362,0.849541},
+  {0.090063,-0.979648},
+  {0.986172,-1.489947},
+  {-1.101995,0.630631},
+  {-0.700222,-0.297787},
+  {-0.105735,-0.061019},
+  {0.274621,0.286836},
+  {0.956524,-0.005156},
+  {1.141911,0.489715},
+  {0.155700,0.477954},
+  {0.161408,-0.280752},
+  {0.208306,-0.382345},
+  {-0.319743,-0.654164},
+  {1.015004,-0.453518},
+  {0.798286,0.047264},
+  {-0.339036,1.191907},
+  {-0.508641,0.191641},
+  {-0.312756,0.231250},
+  {1.006892,0.770095},
+  {0.392099,-0.187454},
+  {0.827204,-1.196456},
+  {-0.071158,0.489808},
+  {-0.111609,-0.123514},
+  {-0.392260,1.137272},
+  {-0.418037,-0.312706},
+  {-0.890258,-0.638300},
+  {0.922980,1.538843},
+  {-0.076405,-0.034489},
+  {-0.056280,0.132953},
+  {0.470452,-0.751306},
+  {-0.507513,-0.546397},
+  {-1.195554,0.917548},
+  {0.119745,-1.039416},
+  {0.641056,0.873863},
+  {-1.881030,0.230334},
+  {-0.472662,-0.485251},
+  {-0.731312,-0.241578},
+  {1.386169,-0.814696},
+  {0.439633,0.192069},
+  {0.060629,-0.471375},
+  {-0.908071,0.528836},
+  {0.831151,0.885574},
+  {-1.203440,-0.299895},
+  {0.129863,0.106531},
+  {0.936271,0.756381},
+  {0.084020,-0.140794},
+  {0.018339,-0.191766},
+  {0.476259,1.311259},
+  {0.250059,-1.190703},
+  {-0.203745,0.761848},
+  {-0.825526,-0.180980},
+  {0.812343,0.263797},
+  {-0.153643,0.325493},
+  {-0.823435,-0.089900},
+  {-0.936715,-0.947103},
+  {0.504302,0.273732},
+  {-0.136153,0.040614},
+  {-0.228844,0.063628},
+  {0.961477,-0.801511},
+  {0.144958,0.157167},
+  {-0.275340,0.067845},
+  {0.982365,0.655564},
+  {-0.101251,0.364215},
+  {-0.518940,0.008418},
+  {1.146963,0.276110},
+  {-0.685455,0.477746},
+  {-0.867617,0.334274},
+  {-0.216229,-1.075130},
+  {0.222334,0.883621},
+  {0.561563,-0.562039},
+  {0.122965,-1.491563},
+  {0.905398,0.202764},
+  {0.237011,0.541816},
+  {0.995545,-0.305894},
+  {0.621302,-0.394520},
+  {0.118272,-0.759820},
+  {0.217348,-1.054868},
+  {0.146891,0.018121},
+  {-1.551826,-0.096002},
+  {0.015579,-0.036639},
+  {1.011278,-1.192439},
+  {-0.071961,0.011541},
+  {-0.953020,-0.444260},
+  {-0.367500,1.228606},
+  {1.526161,0.151876},
+  {1.107404,0.159669},
+  {0.491996,-0.158496},
+  {-0.098865,0.292759},
+  {-0.430131,-1.325361},
+  {1.032900,0.131424},
+  {0.238858,-0.653212},
+  {1.227567,-0.970755},
+  {-1.135533,0.454609},
+  {-0.498524,-0.586837},
+  {-0.249832,0.164953},
+  {0.788240,0.689636},
+  {-1.805305,0.688304},
+  {-0.568470,-0.213126},
+  {-1.008743,0.494092},
+  {-0.068211,-0.558996},
+  {1.019529,-1.524452},
+  {-1.555353,0.038906},
+  {-1.517993,0.035634},
+  {-0.183605,1.086476},
+  {-0.901828,1.815693},
+  {-0.376961,0.539305},
+  {0.384843,0.052507},
+  {-0.147705,-1.045677},
+  {0.880142,-0.997078},
+  {-0.854662,0.272260},
+  {0.283422,1.151546},
+  {-1.105150,0.930541},
+  {0.044104,0.397594},
+  {-0.104013,-0.673208},
+  {-0.211616,-0.621975},
+  {0.027161,0.371316},
+  {0.600274,-0.606245},
+  {0.806180,0.471603},
+  {-1.008090,0.778175},
+  {-0.289146,-0.809723},
+  {-0.038659,-0.429242},
+  {-1.334523,-0.137992},
+  {-1.995175,0.137457},
+  {0.021312,-0.091064},
+  {-1.281258,-0.684793},
+  {-0.413871,-0.292442},
+  {0.381687,0.818085},
+  {0.295284,0.101209},
+  {0.665034,0.592564},
+  {0.037124,0.035242},
+  {0.132064,-0.657651},
+  {1.053341,0.819935},
+  {1.210807,0.675951},
+  {0.457895,-1.075189},
+  {0.358357,0.147282},
+  {-0.499271,0.175458},
+  {0.854323,0.068143},
+  {1.991820,0.805889},
+  {1.826429,-0.005057},
+  {-0.467242,0.138414},
+  {-0.366227,-1.697539},
+  {0.485183,-0.821876},
+  {0.536318,0.341220},
+  {-0.441596,0.831566},
+  {-0.134826,0.751288},
+  {0.358869,1.095253},
+  {-0.386092,0.078119},
+  {-0.397661,-0.118587},
+  {-0.419914,-1.100465},
+  {0.280444,0.389289},
+  {-0.832278,0.269468},
+  {0.472347,0.132484},
+  {0.088928,-0.278739},
+  {0.361290,-0.444613},
+  {-0.320039,-0.519034},
+  {1.354470,0.178576},
+  {-0.168088,-0.359028},
+  {-1.317068,-0.040397},
+  {-0.157570,0.775248},
+  {0.150971,-0.256518},
+  {0.921575,0.744693},
+  {-0.137337,-0.764665},
+  {-0.917358,-0.458914},
+  {-0.705772,-0.263352},
+  {-0.510704,-1.187616},
+  {0.796905,0.825262},
+  {-0.050399,0.512465},
+  {0.768824,-0.159475},
+  {-0.687249,0.364975},
+  {-0.430008,-0.471340},
+  {-0.202663,-0.386981},
+  {-0.518536,0.608685},
+  {0.525161,0.135142},
+  {-0.372337,-0.486685},
+  {0.717387,-1.392395},
+  {0.854322,0.356855},
+  {-1.102180,-0.156184},
+  {-0.209081,-0.377676},
+  {-0.967928,-0.798301},
+  {0.111753,0.232228},
+  {0.314745,0.446778},
+  {-0.989801,0.082857},
+  {-0.298760,0.326928},
+  {-0.204933,0.197721},
+  {1.048764,-0.114128},
+  {-0.304972,0.032725},
+  {0.104894,0.290204},
+  {-0.045314,0.859009},
+  {-0.718912,1.194088},
+  {-0.242557,0.422101},
+  {-0.859795,0.575768},
+  {0.311124,-0.177388},
+  {-1.427806,0.214970},
+  {-0.645104,0.500403},
+  {-0.219194,-0.984099},
+  {0.788104,-0.907460},
+  {0.513765,0.453685},
+  {0.335412,-0.418488},
+  {-1.097887,0.150175},
+  {-0.979087,0.198912},
+  {0.305300,-1.140391},
+  {0.077787,0.856586},
+  {0.214734,-0.592854},
+  {-1.113305,0.320877},
+  {-0.669169,0.448671},
+  {0.253991,0.932563},
+  {-0.455481,0.185849},
+  {0.762277,-0.010084},
+  {-0.477479,0.184388},
+  {0.960667,0.390639},
+  {-0.720191,0.037977},
+  {-1.316302,1.152700},
+  {0.398760,0.257566},
+  {-0.401636,-0.419254},
+  {-1.914376,1.449176},
+  {-0.339228,0.296751},
+  {0.207467,0.305288},
+  {-1.731574,-0.030498},
+  {-0.240750,-0.617304},
+  {-0.237212,0.715578},
+  {-0.416285,-1.008641},
+  {0.634027,1.717009},
+  {0.384123,-0.449106},
+  {-1.160894,-1.767794},
+  {0.618354,-0.261380},
+  {-1.569626,-0.364495},
+  {0.631915,-0.543410},
+  {0.282734,-0.370501},
+  {-0.977373,-0.433726},
+  {1.432343,-0.462557},
+  {-0.972547,0.004444},
+  {0.784231,-0.243932},
+  {-0.376546,-0.584034},
+  {1.001247,-0.164126},
+  {0.554715,-0.308636},
+  {0.540227,0.426550},
+  {-1.066853,-0.294694},
+  {-0.504114,0.275915},
+  {-0.949985,0.630675},
+  {0.506317,-0.294027},
+  {0.133689,0.989125},
+  {0.105266,0.527915},
+  {0.072913,0.211680},
+  {0.381472,0.837872},
+  {-0.183162,0.180758},
+  {0.458198,-0.961007},
+  {-0.004799,0.996245},
+  {-1.561414,-0.676542},
+  {-1.427195,0.800941},
+  {0.173579,0.155504},
+  {-0.830370,0.498583},
+  {-0.232669,0.505982},
+  {-0.096304,-0.750719},
+  {1.906512,-1.461034},
+  {-0.395663,-1.409489},
+  {-0.705341,-0.497179},
+  {-0.163104,-0.442154},
+  {0.853744,-0.265722},
+  {-0.361874,0.151299},
+  {0.107204,-0.414142},
+  {-0.106144,0.419209},
+  {-1.286889,-0.802826},
+  {-0.144332,0.370855},
+  {0.474858,0.913496},
+  {-0.867293,0.301363},
+  {-0.545302,0.146680},
+  {0.001880,0.805475},
+  {1.320236,0.643083},
+  {-1.141064,1.684144},
+  {-0.128674,0.678582},
+  {-0.343416,0.309854},
+  {0.019772,1.077821},
+  {-0.239235,-0.119506},
+  {-0.373356,-0.583563},
+  {0.403890,-0.534354},
+  {-0.519976,0.020956},
+  {0.712048,0.988539},
+  {-0.861664,-0.493059},
+  {0.093158,-0.833793},
+  {1.052626,0.468904},
+  {0.091221,0.456901},
+  {-0.584013,-0.961460},
+  {1.685019,0.470576},
+  {-0.180148,-0.785828},
+  {-0.210638,-0.498937},
+  {0.934431,1.304392},
+  {0.066268,-0.504962},
+  {0.151449,-0.194295},
+  {0.247991,0.136973},
+  {-0.126328,-0.633755},
+  {-0.857218,1.918319},
+  {0.354034,0.566611},
+  {-0.323836,-0.588707},
+  {-0.093776,-0.592204},
+  {-0.027068,-0.042178},
+  {0.002969,0.636477},
+  {-0.480469,-0.201484},
+  {-1.191052,0.906057},
+  {0.598655,-0.164748},
+  {-0.044789,-1.118828},
+  {-0.541816,-0.070911},
+  {0.074609,1.345165},
+  {-0.032322,-0.231974},
+  {-0.449760,1.661760},
+  {0.707548,0.034345},
+  {-0.907888,-0.004174},
+  {0.152966,0.440522},
+  {0.046909,0.346149},
+  {-0.281537,-1.219698},
+  {-0.895213,1.513594},
+  {-0.881255,0.124261},
+  {-1.081693,-0.436486},
+  {-0.106278,0.626797},
+  {0.754899,0.295278},
+  {-0.227234,0.474572},
+  {-0.763770,-0.042921},
+  {-1.002643,0.429052},
+  {0.478156,-0.815031},
+  {-0.733688,-0.279437},
+  {-0.362104,0.064655},
+  {-0.114674,0.196627},
+  {0.044324,-1.013509},
+  {-0.452231,-1.026683},
+  {-0.928972,0.240171},
+  {0.531384,-0.041877},
+  {0.360475,2.263092},
+  {-0.002502,0.278693},
+  {-1.068170,-0.652698},
+  {-0.133973,0.404417},
+  {0.112787,0.817903},
+  {0.093469,0.514351},
+  {0.173190,0.030494},
+  {-0.386117,-0.119304},
+  {-0.150011,1.098977},
+  {-0.718702,1.061190},
+  {-0.187865,0.769379},
+  {-0.673330,-0.520017},
+  {-0.782271,0.749117},
+  {1.040643,-0.447207},
+  {-0.686538,-1.825913},
+  {0.706101,-1.401344},
+  {-0.031939,-0.069587},
+  {1.026212,-0.730925},
+  {0.311104,0.591601},
+  {0.589268,-0.406947},
+  {-0.305040,0.233919},
+  {-0.658906,-0.074957},
+  {-0.172826,0.539225},
+  {1.621683,0.577736},
+  {1.074205,0.776840},
+  {-1.131216,-0.504166},
+  {-0.664862,-0.542385},
+  {-0.245912,0.040006},
+  {1.012363,-0.520893},
+  {-1.044423,-0.968495},
+  {0.057525,-0.137602},
+  {0.031642,-0.360814},
+  {0.302685,0.776735},
+  {-0.590976,0.666512},
+  {-0.153819,-0.015702},
+  {0.050475,1.733477},
+  {0.474972,0.052117},
+  {0.185655,-0.901557},
+  {0.383428,0.150210},
+  {0.254788,0.679409},
+  {-0.224796,0.681574},
+  {-0.256749,-1.077031},
+  {0.134707,-0.760133},
+  {1.014226,-1.619607},
+  {-0.766887,-0.104736},
+  {0.761824,-0.642466},
+  {0.640060,0.025030},
+  {0.717916,0.808046},
+  {0.158375,-0.609786},
+  {0.599932,0.529572},
+  {0.920422,-1.417508},
+  {0.247593,-0.365323},
+  {0.143007,0.147123},
+  {-0.698949,-0.661064},
+  {0.099640,0.528546},
+  {0.387466,1.303945},
+  {0.721636,-0.563915},
+  {-0.056200,-0.095831},
+  {0.127167,0.466936},
+  {0.614167,-0.250185},
+  {0.324173,-0.104513},
+  {0.564475,-0.584259},
+  {0.000883,-0.715214},
+  {0.175617,-0.853427},
+  {-0.655242,0.141206},
+  {-0.799496,-0.397656},
+  {0.509296,-0.078758},
+  {0.824815,-0.397955},
+  {0.165592,-0.838807},
+  {-1.406393,-0.034832},
+  {-0.140087,-0.245922},
+  {-0.039954,-0.580654},
+  {0.592499,0.257650},
+  {0.865662,-0.321183},
+  {-0.348095,0.633829},
+  {-0.222209,0.346638},
+  {0.077141,-0.429164},
+  {-0.612928,0.649756},
+  {-0.218828,-0.978959},
+  {-0.467017,0.873553},
+  {1.012268,-0.236361},
+  {0.935993,-0.768227},
+  {-0.637278,0.397934},
+  {-0.171380,0.726429},
+  {-0.200094,1.039778},
+  {-0.395740,-0.290233},
+  {-0.251927,0.547605},
+  {-0.317331,2.066899},
+  {0.874234,-0.172457},
+  {-0.112367,0.968130},
+  {-0.608874,-0.281634},
+  {0.458084,0.134327},
+  {-0.327929,-0.153658},
+  {-0.809721,-1.217724},
+  {0.108791,0.635246},
+  {-0.127071,0.688169},
+  {-0.681222,0.292983},
+  {-0.447850,-0.098757},
+  {-0.059162,0.033865},
+  {-1.459920,-0.167831},
+  {-0.546872,1.304584},
+  {0.567670,-0.764303},
+  {-0.051371,0.814561},
+  {0.018359,0.085225},
+  {0.295254,0.367041},
+  {0.923804,-0.382126},
+  {-0.094986,0.179273},
+  {0.751972,-1.355834},
+  {-0.131853,-0.066514},
+  {0.223027,-0.074406},
+  {-0.447982,-0.207079},
+  {-1.165943,-1.747960},
+  {0.289496,-0.581631},
+  {0.995888,-0.840471},
+  {0.287864,-1.173235},
+  {-0.035233,-0.012186},
+  {1.404205,-0.502267},
+  {0.271013,-0.607421},
+  {0.082209,-0.294491},
+  {1.108759,0.397367},
+  {0.147693,-0.077201},
+  {0.644694,-1.167422},
+  {0.439444,-0.480603},
+  {1.596557,0.704222},
+  {0.202072,-1.010761},
+  {0.472276,-0.171207},
+  {0.496560,-0.780542},
+  {1.279076,-0.623514},
+  {0.182762,-0.393778},
+  {0.150084,0.277712},
+  {0.752527,0.683646},
+  {0.480142,1.172231},
+  {1.005193,-0.949569},
+  {0.668218,-0.521006},
+  {-0.401607,0.695572},
+  {0.934451,-1.387263},
+  {-1.060714,-0.674529},
+  {0.445290,-0.241091},
+  {0.757956,0.271408},
+  {1.231487,0.237535},
+  {-0.486448,0.433734},
+  {-1.455954,1.581795},
+  {-1.037576,-1.013962},
+  {-0.251248,-0.324413},
+  {1.064396,0.130331},
+  {-1.209972,-0.399869},
+  {0.412389,0.237274},
+  {-0.971736,0.139207},
+  {0.364493,0.360362},
+  {0.462466,0.123618},
+  {0.015647,0.662696},
+  {0.521067,-0.464325},
+  {-0.691029,-0.419101},
+  {0.797372,-0.361360},
+  {-0.711848,-0.337005},
+  {0.276187,0.033567},
+  {0.261731,0.465815},
+  {-0.122547,-0.163457},
+  {0.449124,0.025562},
+  {-0.366007,-0.325535},
+  {0.741756,0.044402},
+  {0.795758,-1.009837},
+  {-0.045791,-1.021170},
+  {-0.690750,-0.553651},
+  {-0.885860,0.289949},
+  {0.587965,-0.598258},
+  {0.645572,0.810630},
+  {-0.008388,-0.730176},
+  {0.161907,0.977525},
+  {-0.967148,0.872038},
+  {0.372738,-0.028752},
+  {0.255575,1.354765},
+  {-0.947345,0.186383},
+  {0.938292,0.931974},
+  {-0.137511,-1.156500},
+  {1.535508,1.226839},
+  {0.098197,0.233959},
+  {1.091029,-0.489096},
+  {0.919905,1.862780},
+  {0.715268,0.128684},
+  {0.737863,-0.154854},
+  {-0.231765,-0.541695},
+  {-0.512769,-0.574521},
+  {-0.128448,0.487393},
+  {0.352688,1.345931},
+  {0.064971,-0.982254},
+  {-0.726009,1.313529},
+  {0.448623,-0.053441},
+  {1.469537,-0.044362},
+  {1.011843,0.352729},
+  {1.063249,-0.322635},
+  {-0.131380,0.533014},
+  {0.451360,0.230248},
+  {0.001995,0.153600},
+  {1.646787,0.881911},
+  {-1.458759,-0.586824},
+  {-0.702392,-0.241636},
+  {-0.074182,-0.072131},
+  {0.262439,0.583482},
+  {-0.476122,0.082469},
+  {0.438068,0.803544},
+  {-0.207061,0.660637},
+  {0.567990,-0.597823},
+  {-1.688718,-0.103409},
+  {-0.829192,0.426556},
+  {0.827020,0.826934},
+  {0.441454,-0.546262},
+  {-0.304897,-0.022233},
+  {-0.357555,-0.612953},
+  {-0.388052,0.013095},
+  {0.777314,0.544567},
+  {0.437676,0.305298},
+  {-0.356608,-0.848358},
+  {0.791083,-0.271240},
+  {0.044885,0.107636},
+  {0.364655,0.012973},
+  {0.538263,-1.124278},
+  {0.228271,-1.168910},
+  {0.026633,-0.327359},
+  {0.464736,-0.077427},
+  {-0.438151,-0.387916},
+  {0.384472,0.255111},
+  {-0.913587,0.151118},
+  {0.215311,0.261325},
+  {0.133743,1.302663},
+  {0.977288,-1.212393},
+  {-1.005590,1.135110},
+  {-1.031105,-0.046053},
+  {0.034069,0.088167},
+  {-1.874043,0.314546},
+  {-0.138676,-0.665746},
+  {-1.367737,0.809027},
+  {-0.617917,0.576212},
+  {-0.059977,0.148805},
+  {1.021231,-1.734845},
+  {0.232449,-1.635767},
+  {-0.402629,0.093773},
+  {0.306316,-0.589913},
+  {0.691035,-0.933528},
+  {-0.854344,-0.581280},
+  {-0.550056,-0.087623},
+  {-0.735359,0.440600},
+  {-0.599941,-0.566529},
+  {-0.157511,0.329776},
+  {-0.620057,-0.573574},
+  {-0.618399,-0.151361},
+  {0.173969,-0.559218},
+  {-0.316563,2.332789},
+  {-0.512502,-0.263662},
+  {0.127996,0.407326},
+  {0.888734,-0.229112},
+  {0.431876,-0.881928},
+  {0.480039,-0.855335},
+  {0.548737,0.504779},
+  {0.039114,-0.355311},
+  {-0.536205,1.175569},
+  {-0.006012,-1.440053},
+  {-0.366908,-0.714389},
+  {-0.253160,-0.482878},
+  {0.071598,-0.022415},
+  {0.484456,0.242941},
+  {0.353405,-0.516339},
+  {0.269909,0.018111},
+  {-0.512141,0.368190},
+  {-0.034358,-0.690191},
+  {0.186251,-0.383563},
+  {-1.243734,1.020511},
+  {-0.310334,-0.639568},
+  {-0.238013,1.203421},
+  {-0.276677,0.105597},
+  {0.528988,0.213357},
+  {0.351103,0.004227},
+  {0.686052,-0.683489},
+  {0.402253,-0.548756},
+  {-0.244236,-0.179112},
+  {0.039858,0.390838},
+  {0.985325,0.842588},
+  {0.440814,-0.329205},
+  {0.666419,0.644613},
+  {0.548497,-0.000859},
+  {-0.938426,1.023278},
+  {-0.941754,0.721262},
+  {0.000099,1.114577},
+  {-1.218951,1.191773},
+  {-0.607709,0.205343},
+  {-0.206425,0.838011},
+  {0.699534,-0.002445},
+  {1.352826,-0.100402},
+  {0.041916,0.740550},
+  {0.416504,-0.341657},
+  {0.097466,1.186724},
+  {0.687240,-0.367369},
+  {0.545399,-0.035212},
+  {0.374638,0.479261},
+  {0.135228,-0.116509},
+  {-0.608795,0.777712},
+  {0.335622,0.171713},
+  {-0.049759,0.394634},
+  {0.882455,-0.007277},
+  {0.074308,0.777326},
+  {0.370312,0.102349},
+  {0.376820,0.573884},
+  {-0.431049,0.306366},
+  {1.085490,0.744110},
+  {-0.230620,-0.315921},
+  {0.436716,0.557135},
+  {-0.702941,0.571264},
+  {0.221250,0.066672},
+  {-0.570686,-0.286918},
+  {-0.560485,-1.471082},
+  {-0.314618,-0.584589},
+  {-0.311362,0.168867},
+  {1.173793,0.106905},
+  {-1.017770,-0.355978},
+  {-0.228067,-0.524127},
+  {-0.163044,-1.799027},
+  {-0.126843,-0.121222},
+  {-0.360908,-0.655512},
+  {1.040580,-1.978968},
+  {-0.769183,0.705786},
+  {-0.275717,-0.258945},
+  {-0.590592,-1.078141},
+  {-1.062724,0.958762},
+  {0.123248,0.000726},
+  {-0.630985,-0.643702},
+  {-0.304755,0.333120},
+  {-0.354195,-0.773979},
+  {-1.222200,-0.340033},
+  {-0.500831,-0.495272},
+  {0.395941,0.305049},
+  {1.926537,-0.064242},
+  {0.102387,0.533556},
+  {1.094398,0.165614},
+  {-1.017921,-1.540784},
+  {-0.218494,-0.929660},
+  {-0.535317,0.186219},
+  {1.199743,-0.241787},
+  {0.086699,-0.643872},
+  {-0.586069,0.057078},
+  {0.457002,-0.144936},
+  {0.938976,0.355965},
+  {-0.478159,-0.863239},
+  {0.123059,0.137369},
+  {-0.726764,0.697758},
+  {-0.776171,-0.293292},
+  {0.532566,-0.658669},
+  {0.490077,-0.101454},
+  {0.031428,0.291178},
+  {-0.667737,0.741288},
+  {0.907230,0.233775},
+  {0.515349,-0.227823},
+  {1.010764,-0.015213},
+  {0.444179,-0.562985},
+  {-0.276474,0.657198},
+  {-0.172263,0.956311},
+  {-0.355806,0.703603},
+  {-0.506885,-0.799493},
+  {-0.697335,-0.297622},
+  {-0.012191,1.840314},
+  {-0.847463,0.284183},
+  {0.854194,0.403219},
+  {1.929827,0.528325},
+  {-0.261886,0.577017},
+  {-0.031070,-2.348125},
+  {-0.155820,-0.265157},
+  {0.512475,0.208609},
+  {-1.450445,-0.816839},
+  {0.564060,0.610582},
+  {0.208762,0.538423},
+  {-0.394083,-0.217364},
+  {0.232377,-0.084660},
+  {0.344522,0.516178},
+  {-1.449901,-0.112290},
+  {0.000158,-0.982079},
+  {0.787346,1.416797},
+  {0.158547,-0.490012},
+  {-0.765118,0.416037},
+  {0.552854,0.197313},
+  {-0.560294,0.168624},
+  {-0.710216,-0.278700},
+  {-0.022732,0.174521},
+  {-0.831227,0.475439},
+  {0.219373,-0.678127},
+  {-0.002961,-0.573618},
+  {-0.945813,0.412736},
+  {-0.979897,1.265908},
+  {-0.311475,0.379769},
+  {-0.082964,0.038846},
+  {-0.500868,0.551077},
+  {-1.116548,-0.382053},
+  {-0.150512,-0.889516},
+  {0.003441,-0.441244},
+  {-0.155477,0.236868},
+  {-0.372866,-0.003664},
+  {0.517363,-0.227696},
+  {0.348671,-1.184919},
+  {0.023715,-0.857359},
+  {-1.165542,0.373084},
+  {-0.372004,0.745161},
+  {1.486675,0.482708},
+  {0.713017,-0.111925},
+  {0.698459,0.261537},
+  {-1.448937,0.151106},
+  {-0.936754,0.023684},
+  {0.896661,-0.031541},
+  {0.360038,0.783076},
+  {-0.094289,0.365897},
+  {1.270895,0.047391},
+  {-0.069325,-0.911174},
+  {0.356797,-0.202779},
+  {0.966214,-0.501017},
+  {-1.056213,-0.334850},
+  {-1.048820,1.448814},
+  {-1.559907,0.438635},
+  {-0.533985,0.378701},
+  {1.577709,-0.730175},
+  {0.591595,1.416816},
+  {-0.192300,-0.219470},
+  {0.299344,-0.860943},
+  {0.318677,0.121607},
+  {0.335483,0.070689},
+  {-0.111371,-1.205420},
+  {0.395077,0.205784},
+  {1.026121,-0.818676},
+  {-0.968687,0.857896},
+  {0.312721,1.501156},
+  {-0.482650,0.352206},
+  {0.997697,0.112893},
+  {0.950446,-0.398203},
+  {0.097713,-1.070921},
+  {-0.800673,-0.325717},
+  {0.671945,-0.861890},
+  {0.021531,-0.436324},
+  {0.437880,1.356432},
+  {0.457176,-0.276639},
+  {-0.247776,0.777048},
+  {0.251688,0.079969},
+  {-1.334482,-1.474248},
+  {-0.483623,0.743976},
+  {0.355137,-0.034433},
+  {-0.956198,-1.078557},
+  {0.405169,1.702393},
+  {-0.835610,-0.412153},
+  {0.177645,-0.803742},
+  {0.190991,-0.126655},
+  {-0.293197,0.907349},
+  {0.208255,0.226394},
+  {-0.590120,-0.320991},
+  {-0.477141,-0.954609},
+  {0.534067,-0.035251},
+  {-0.962419,0.424134},
+  {0.409965,-0.074026},
+  {-0.110630,-0.862237},
+  {0.037791,0.944337},
+  {0.944043,-0.704466},
+  {-0.648236,0.057918},
+  {-0.617177,-0.830966},
+  {0.416183,-0.658194},
+  {1.180214,0.519521},
+  {-0.123865,-0.426364},
+  {0.019066,0.317164},
+  {0.234837,0.331158},
+  {-0.656986,0.335032},
+  {0.346063,-1.649529},
+  {0.058210,-0.381788},
+  {-0.260900,0.186365},
+  {0.429371,0.681698},
+  {1.939461,-1.181745},
+  {-0.445243,-0.716289},
+  {0.131740,0.865901},
+  {-0.918136,-0.131137},
+  {-0.053577,-0.373297},
+  {-0.531049,0.031422},
+  {-1.254709,0.556524},
+  {-1.119247,0.394916},
+  {-0.498215,-0.035437},
+  {1.322329,0.190493},
+  {-0.701283,-1.164440},
+  {-0.361131,-0.504716},
+  {-0.117174,0.107979},
+  {0.700073,1.603625},
+  {-0.582119,0.440169},
+  {1.018868,-0.420729},
+  {-0.212079,-0.280104},
+  {1.132422,-0.035123},
+  {0.026273,1.886585},
+  {-0.729453,0.098911},
+  {0.805546,0.750763},
+  {0.224181,0.331261},
+  {0.116170,0.259857},
+  {0.100047,0.046190},
+  {-0.055174,0.957446},
+  {-1.456418,-1.105336},
+  {0.290339,-0.811412},
+  {-0.403941,-0.272939},
+  {1.707646,0.332927},
+  {0.858293,0.006974},
+  {-0.476534,0.364698},
+  {-0.705168,0.544668},
+  {-0.667669,0.289049},
+  {1.181489,-0.102266},
+  {-0.363524,-0.507603},
+  {0.077873,-0.227451},
+  {-0.070765,0.236432},
+  {0.547170,0.221358},
+  {-0.084700,-0.954482},
+  {-0.930200,-1.003973},
+  {0.641949,1.189144},
+  {0.292530,1.376169},
+  {0.146329,0.050514},
+  {0.504086,0.327294},
+  {0.560656,-0.819642},
+  {-0.782328,0.555732},
+  {-0.321355,0.040423},
+  {0.575312,0.676942},
+  {0.676739,0.371605},
+  {-0.739089,0.154797},
+  {-0.196959,0.765774},
+  {-0.075477,-0.064618},
+  {-0.708957,-0.695153},
+  {-0.114007,-0.274311},
+  {-0.208777,-0.197655},
+  {-0.330289,0.090402},
+  {0.645717,-0.861720},
+  {0.759627,1.159973},
+  {0.736863,0.016140},
+  {-0.290055,1.066642},
+  {-0.360313,0.572408},
+  {0.559798,-0.118348},
+  {1.099664,0.913475},
+  {-1.221145,0.753011},
+  {-1.080846,-0.309538},
+  {0.898748,-1.751489},
+  {-0.793636,-0.682252},
+  {0.601441,0.716634},
+  {-0.754166,-0.295275},
+  {-0.057178,-0.531244},
+  {-0.503737,0.754428},
+  {-0.092784,0.415358},
+  {-0.428408,0.867882},
+  {-0.531645,-0.427532},
+  {0.015225,0.360774},
+  {0.052039,0.804546},
+  {0.140220,0.683936},
+  {-0.183837,-0.075742},
+  {0.141611,0.121116},
+  {0.863189,-0.304942},
+  {-0.183500,-1.267097},
+  {0.721582,0.324832},
+  {0.490362,-0.620402},
+  {0.032723,-0.342147},
+  {0.015191,0.299803},
+  {-0.453198,0.232907},
+  {0.890290,-0.037167},
+  {1.101406,-0.724242},
+  {-1.147539,-0.245951},
+  {-1.727078,-1.683502},
+  {0.261545,-0.107582},
+  {0.068065,0.753220},
+  {0.369570,0.796556},
+  {0.143988,0.884428},
+  {0.009223,-0.259795},
+  {-0.207237,1.912655},
+  {0.901343,0.446570},
+  {1.779646,-0.190026},
+  {0.060311,-0.035492},
+  {0.471146,-0.987103},
+  {-0.678292,-0.087719},
+  {-0.381341,0.932014},
+  {0.423463,-0.374888},
+  {0.132522,-0.133326},
+  {0.725087,-0.055467},
+  {-0.026041,0.630602},
+  {0.237645,-0.147676},
+  {0.384787,0.046887},
+  {1.184148,-0.971991},
+  {0.904135,-1.133769},
+  {1.047468,-0.174437},
+  {-0.262063,1.567163},
+  {-0.323006,0.521236},
+  {0.517606,0.341770},
+  {-0.289763,-0.525198},
+  {1.140138,-0.745015},
+  {0.748583,0.650728},
+  {-0.040966,0.218449},
+  {0.340059,0.915520},
+  {0.031779,0.421656},
+  {-0.394555,-0.262061},
+  {0.204192,-0.199669},
+  {-0.222583,0.416622},
+  {0.026680,0.648281},
+  {0.394312,-0.072898},
+  {-0.547009,-0.610642},
+  {-0.323403,-0.781335},
+  {0.246200,-0.481307},
+  {1.250227,-0.203189},
+  {1.335570,0.028829},
+  {0.907068,-0.322204},
+  {-0.241285,0.672412},
+  {-0.500388,1.413200},
+  {0.348404,0.053563},
+  {-0.515993,1.348158},
+  {0.419507,0.843740},
+  {-1.680552,-0.349667},
+  {1.125661,0.162114},
+  {-2.253658,-1.822658},
+  {-0.603819,-0.131986},
+  {-0.688067,-1.520234},
+  {0.107885,1.042587},
+  {0.794351,0.550783},
+  {0.107568,0.622575},
+  {0.427502,0.055636},
+  {-0.386636,-0.648276},
+  {-0.530590,0.233918},
+  {-0.069396,-0.648418},
+  {0.677155,1.610371},
+  {-0.636080,0.824467},
+  {1.069180,0.649464},
+  {-1.099628,0.652186},
+  {1.175325,0.015894},
+  {0.519414,-1.197649},
+  {-0.613790,-0.781378},
+  {-1.117294,0.891372},
+  {0.284313,-0.488536},
+  {0.142283,1.641906},
+  {1.718632,-0.694643},
+  {-0.611194,-0.432577},
+  {-0.251579,-0.852987},
+  {-0.170100,0.486159},
+  {0.320121,-0.580628},
+  {0.872266,-0.384060},
+  {-0.208309,0.139307},
+  {-1.583756,-0.645014},
+  {-0.702369,-0.541675},
+  {0.336241,0.831866},
+  {-0.865645,0.436119},
+  {-0.620241,-0.606092},
+  {-0.104203,0.984638},
+  {-0.410559,-0.040961},
+  {-0.416490,-0.226391},
+  {0.088726,-0.220726},
+  {-1.499559,-0.585178},
+  {0.293249,0.186455},
+  {-1.210379,-0.633716},
+  {-0.277191,-1.244025},
+  {1.139804,0.055639},
+  {-0.228353,0.448129},
+  {0.559068,-0.023119},
+  {-1.221999,0.465622},
+  {1.162107,-0.729434},
+  {-0.368202,0.259066},
+  {-0.285426,1.295138},
+  {0.379646,0.224708},
+  {0.294352,-0.551327},
+  {-0.462702,0.187464},
+  {-0.026366,-1.131739},
+  {0.894485,-0.169837},
+  {1.029962,-0.513169},
+  {-0.308485,-0.846109},
+  {0.013267,0.200561},
+  {0.442056,0.037734},
+  {-1.579953,-0.567456},
+  {0.313331,0.287219},
+  {0.237625,-1.467799},
+  {-0.343068,0.471870},
+  {0.808584,-0.605491},
+  {-0.384505,0.285999},
+  {-0.821182,1.140405},
+  {0.083857,0.569015},
+  {0.358021,0.251793},
+  {-1.050896,0.222264},
+  {0.693579,-0.417443},
+  {0.488468,0.599156},
+  {-0.102947,-1.320533},
+  {0.340396,-0.671734},
+  {0.618710,-0.219283},
+  {-0.125032,-0.163230},
+  {-0.088188,-0.534394},
+  {0.682064,1.041136},
+  {-0.344705,-0.089664},
+  {-0.529053,0.255838},
+  {-0.136569,-0.214062},
+  {1.455681,0.491256},
+  {1.238314,-0.436456},
+  {0.183785,-0.294781},
+  {-1.115245,1.248687},
+  {-0.649421,-0.614780},
+  {1.178710,-0.312908},
+  {0.812326,-0.393600},
+  {-0.874232,0.893146},
+  {-1.043341,-0.195049},
+  {-1.266037,-0.004749},
+  {-0.377230,-0.359996},
+  {-0.196225,0.796953},
+  {0.996897,-0.623582},
+  {-0.556859,-0.864103},
+  {-1.371972,0.769551},
+  {0.056397,-0.658378},
+  {-0.074004,0.516830},
+  {-0.019248,0.750291},
+  {0.172892,-0.524600},
+  {-0.598676,-0.007268},
+  {0.137861,1.698237},
+  {-0.084691,1.344243},
+  {0.001925,-0.191394},
+  {0.240667,-0.596132},
+  {-0.139205,1.502034},
+  {0.716061,-1.415551},
+  {0.861506,-0.658005},
+  {0.514495,0.090184},
+  {-0.528631,1.006103},
+  {-0.388832,-0.792382},
+  {0.735890,0.122394},
+  {-1.547132,1.015471},
+  {0.121113,-0.501140},
+  {0.975384,-1.280454},
+  {0.079350,0.996285},
+  {0.046097,-1.248331},
+  {-0.978137,-0.857029},
+  {-0.292484,0.917538},
+  {0.476399,-0.533662},
+  {-0.185424,0.410061},
+  {-0.516918,0.560953},
+  {-1.108884,0.242701},
+  {0.393610,-1.112134},
+  {-0.342411,0.026459},
+  {0.960001,-0.039799},
+  {0.292966,-0.871399},
+  {0.509531,0.068985},
+  {0.306125,0.182601},
+  {0.684688,0.611943},
+  {0.366705,-1.300976},
+  {-0.161117,0.460565},
+  {0.919045,0.162937},
+  {-0.600136,0.528728},
+  {0.807988,-0.082820},
+  {0.723075,-1.101493},
+  {0.408624,0.497548},
+  {0.592179,-0.511883},
+  {-0.624763,0.320432},
+  {0.702432,0.047555},
+  {-0.826321,0.702721},
+  {-0.590704,0.927206},
+  {-1.222225,0.520187},
+  {0.057220,-0.355501},
+  {-0.346697,0.327871},
+  {-0.389801,-1.554275},
+  {0.700315,-0.895953},
+  {0.367463,0.307326},
+  {-0.364395,-1.611608},
+  {-0.506932,0.889372},
+  {-0.243596,0.575283},
+  {-0.802028,0.056860},
+  {-0.171424,0.239689},
+  {0.169908,-0.522395},
+  {0.213199,-0.701460},
+  {0.552262,0.906828},
+  {-1.016062,0.643300},
+  {0.298917,-0.477633},
+  {0.354035,0.004910},
+  {-0.091019,0.375327},
+  {-0.237197,0.523797},
+  {-0.445213,0.236868},
+  {0.184486,0.210037},
+  {-0.200655,-0.532764},
+  {-0.165018,0.252682},
+  {0.301383,-0.470096},
+  {0.733004,-0.519851},
+  {-0.340900,0.559258},
+  {-0.003634,0.397142},
+  {-0.158002,-0.601995},
+  {1.029616,-0.712344},
+  {-0.272084,1.292895},
+  {-0.245181,0.153895},
+  {1.537927,0.233934},
+  {-0.194398,-0.207617},
+  {-0.037529,-0.362480},
+  {-1.439610,-0.069318},
+  {-0.527334,-0.847175},
+  {0.888073,1.120245},
+  {0.759059,-1.709285},
+  {-0.038818,-0.451563},
+  {-1.569456,0.059742},
+  {-1.135825,1.105116},
+  {0.860456,-0.054651},
+  {0.791421,0.583433},
+  {0.300375,0.733727},
+  {0.740330,0.173272},
+  {0.720677,-0.006213},
+  {0.211773,0.171237},
+  {1.239301,0.513578},
+  {-0.038229,-1.319419},
+  {-1.110608,0.623842},
+  {-1.199877,2.009182},
+  {0.110201,1.359225},
+  {-0.521048,1.259603},
+  {-0.779884,0.080694},
+  {0.922866,1.378522},
+  {-0.036678,-0.256378},
+  {0.630587,0.356473},
+  {-0.818911,0.348724},
+  {-0.823156,-0.403827},
+  {-0.305461,-0.183285},
+  {0.545495,-0.917827},
+  {-0.307489,0.278087},
+  {0.576430,0.263072},
+  {-0.110932,0.343314},
+  {-0.730010,0.924897},
+  {0.492041,0.775198},
+  {0.461854,0.423507},
+  {0.427495,1.700151},
+  {0.432533,0.301152},
+  {-0.593518,1.393076},
+  {-0.389399,-0.733757},
+  {-1.049504,0.301791},
+  {0.546392,0.734537},
+  {0.338524,0.116400},
+  {-0.597570,-1.925078},
+  {0.322346,1.008118},
+  {0.513935,-0.042958},
+  {-0.518049,0.101353},
+  {1.352677,-0.293425},
+  {0.240988,-1.041734},
+  {-0.691185,-1.063328},
+  {0.130569,1.016253},
+  {-0.586304,-0.555797},
+  {0.462853,-0.235079},
+  {0.079994,-0.355770},
+  {0.153572,0.147783},
+  {-0.596490,-0.795026},
+  {0.326538,-0.790256},
+  {-1.460756,-0.251033},
+  {0.017858,0.259083},
+  {0.507881,-1.054094},
+  {0.266351,0.627879},
+  {-0.752761,-0.513762},
+  {-0.627282,0.008649},
+  {-0.886446,0.842860},
+  {-0.463043,-0.469626},
+  {0.096623,0.933024},
+  {-0.286410,0.744126},
+  {-0.542282,1.126897},
+  {-0.313235,0.205528},
+  {-1.320519,0.277179},
+  {0.071715,0.147248},
+  {-0.903511,-0.083047},
+  {0.656132,-1.350683},
+  {-0.207632,-0.039248},
+  {0.117073,-0.120780},
+  {-1.332364,0.590990},
+  {-0.380298,-0.400794},
+  {-0.366577,0.174013},
+  {0.485112,-0.117400},
+  {0.372690,-0.023396},
+  {-0.909507,-0.293390},
+  {1.037746,0.057621},
+  {0.939461,-1.025088},
+  {1.893673,-0.611078},
+  {0.078827,-0.951650},
+  {-0.839030,0.090466},
+  {-1.104840,-1.126416},
+  {0.590214,0.068381},
+  {1.100851,0.573205},
+  {-0.393116,-0.875980},
+  {-0.254150,-0.405253},
+  {-0.278855,1.000683},
+  {0.921864,0.463923},
+  {-0.041988,-0.112156},
+  {0.155288,-0.019315},
+  {0.099627,0.916635},
+  {-0.622412,-0.503004},
+  {-0.262853,0.533022},
+  {-2.349103,-0.232631},
+  {-0.387689,-0.672924},
+  {-0.981208,0.386278},
+  {0.021049,-0.336082},
+  {0.385965,1.431628},
+  {0.084666,-0.022362},
+  {1.501095,-0.445381},
+  {-0.174828,0.029946},
+  {-0.075096,-0.754793},
+  {0.440599,-0.624117},
+  {-0.191469,-0.122779},
+  {-0.619664,0.048316},
+  {0.681431,-1.113935},
+  {0.392264,-0.416262},
+  {-1.025569,0.426959},
+  {0.231863,1.526328},
+  {-0.235847,0.767781},
+  {-0.081400,-1.937839},
+  {-0.142145,0.413403},
+  {-0.578059,-0.410749},
+  {0.886248,-1.144489},
+  {-0.584558,-0.717462},
+  {0.337355,-0.804375},
+  {-0.070221,0.776269},
+  {-0.020066,0.015296},
+  {-0.731855,1.217179},
+  {0.430529,-0.118092},
+  {0.121456,2.210222},
+  {0.825156,-1.563617},
+  {-0.365542,-0.034897},
+  {0.238998,0.603491},
+  {-0.488885,-0.418294},
+  {0.519796,-1.412865},
+  {-1.114191,-0.510320},
+  {-0.752598,0.541650},
+  {0.380631,-0.713726},
+  {0.023115,1.015882},
+  {-0.198359,0.433732},
+  {0.103927,0.017306},
+  {-0.039809,0.223707},
+  {1.711996,0.402454},
+  {-0.056678,0.174339},
+  {-1.687713,-0.160125},
+  {0.696416,-0.493909},
+  {-0.873410,0.257890},
+  {0.319853,0.072947},
+  {-0.368300,0.341422},
+  {-0.482285,0.930112},
+  {-0.004708,0.893093},
+  {-0.051559,0.713417},
+  {1.244796,1.336726},
+  {-0.104941,-0.449322},
+  {0.655462,0.706759},
+  {-0.239773,1.696788},
+  {-0.324650,0.398949},
+  {0.624589,0.044072},
+  {0.357952,0.443955},
+  {0.749903,1.159453},
+  {-1.563112,-0.838062},
+  {-0.617714,-0.025810},
+  {1.450510,-0.020522},
+  {0.225253,-1.483181},
+  {-0.666102,-0.989824},
+  {0.463322,0.622948},
+  {-0.252765,-0.493345},
+  {-0.030605,0.132428},
+  {-0.104919,-1.328013},
+  {0.512898,-0.265843},
+  {0.641341,0.344586},
+  {0.586485,-0.656758},
+  {-0.869639,-1.444607},
+  {-0.283470,-0.175611},
+  {-0.403954,-0.687469},
+  {0.222511,-0.720233},
+  {-1.268683,-0.981553},
+  {-0.379982,-0.435577},
+  {1.266867,0.349347},
+  {0.164557,-1.057785},
+  {0.093567,0.955540},
+  {-0.141307,-0.705522},
+  {0.371905,0.120573},
+  {-0.389172,-0.765473},
+  {0.917816,-0.237643},
+  {1.004090,0.178844},
+  {-0.629418,-0.412242},
+  {-0.210337,0.560592},
+  {-0.318360,1.059381},
+  {0.583389,-1.323808},
+  {-0.817288,0.993688},
+  {-0.878170,-1.153520},
+  {0.368115,0.337455},
+  {0.031655,0.110590},
+  {0.265206,0.204946},
+  {0.088893,0.170791},
+  {-0.177558,2.292458},
+  {0.141059,-0.985035},
+  {-0.660856,-0.980383},
+  {-0.609849,0.985874},
+  {-0.214610,0.730502},
+  {-0.616156,-0.316919},
+  {0.694992,-0.768053},
+  {-0.325122,-1.054053},
+  {1.217558,-0.854166},
+  {0.854051,-0.005104},
+  {1.209427,-0.241328},
+  {0.324556,0.132322},
+  {-0.343527,0.053413},
+  {0.224351,0.479553},
+  {0.421346,-0.521788},
+  {0.118883,-0.218365},
+  {0.188380,-0.456052},
+  {-0.349273,-0.770785},
+  {0.219073,0.003962},
+  {-0.296130,-0.656501},
+  {0.636082,0.026015},
+  {-0.625080,0.346952},
+  {0.929759,0.857013},
+  {0.187340,0.484039},
+  {0.007584,-0.624158},
+  {0.309799,-2.221435},
+  {0.640643,1.329439},
+  {0.226335,-0.805996},
+  {0.822625,1.060992},
+  {-0.470881,-1.000766},
+  {0.425072,-0.397100},
+  {-0.223623,0.531114},
+  {0.292353,-0.088059},
+  {0.366968,0.358980},
+  {-0.753461,-0.700875},
+  {0.249173,0.177231},
+  {0.182607,-0.592219},
+  {-0.058347,0.078718},
+  {0.183978,-0.226199},
+  {0.648659,-0.221680},
+  {-0.656861,-0.408497},
+  {0.798399,0.044049},
+  {-1.154125,-0.803622},
+  {0.008225,-0.136806},
+  {0.676763,-0.316637},
+  {-0.376109,0.251771},
+  {-1.331292,1.241033},
+  {0.190767,0.475373},
+  {0.578552,1.172062},
+  {0.505876,-0.233129},
+  {-0.361797,-0.297199},
+  {-0.097264,-0.225741},
+  {-0.050572,-0.001436},
+  {-0.454120,-0.192442},
+  {1.120225,-0.898933},
+  {-0.216917,0.333024},
+  {0.110060,0.750588},
+  {0.760030,0.575150},
+  {0.975368,0.487183},
+  {-0.416180,1.692559},
+  {0.804607,-0.335317},
+  {-0.669472,0.243862},
+  {1.112954,-0.010765},
+  {-0.312142,-0.937224},
+  {-0.567689,-0.263702},
+  {0.041868,0.572080},
+  {1.804127,-0.566619},
+  {-0.521481,1.063847},
+  {1.819315,0.382287},
+  {0.380872,-0.611233},
+  {0.296314,-0.222157},
+  {1.498113,0.879454},
+  {1.518674,0.605166},
+  {0.019620,-0.040801},
+  {1.102724,0.266670},
+  {-0.684836,-0.568236},
+  {0.519185,-0.779516},
+  {-0.226690,-0.818393},
+  {0.394623,-1.286799},
+  {0.900695,0.487765},
+  {-0.799478,-0.400191},
+  {-0.830514,-0.562055},
+  {0.951365,-0.076491},
+  {-0.152298,-1.042769},
+  {0.069064,-1.023238},
+  {0.053427,-1.985536},
+  {-0.686719,0.206313},
+  {-0.872301,0.294649},
+  {-0.624577,-0.387285},
+  {-0.050756,0.173358},
+  {-0.721308,0.536205},
+  {0.598027,-1.956268},
+  {1.243462,-0.102223},
+  {0.272178,0.642981},
+  {0.490204,-1.332468},
+  {-0.459636,1.005367},
+  {-0.186912,-0.782287},
+  {-0.912943,-0.294037},
+  {1.394333,0.134047},
+  {-0.104225,0.280412},
+  {0.396206,-0.652859},
+  {-1.350593,0.267762},
+  {-0.192340,0.249925},
+  {-0.294556,0.392405},
+  {-0.585629,-0.706280},
+  {0.416039,-0.105205},
+  {0.230197,-0.642631},
+  {-0.788622,-0.801780},
+  {0.641724,0.143368},
+  {0.868609,0.721575},
+  {-0.648315,-0.221029},
+  {-0.759865,-0.581518},
+  {0.050452,-0.421412},
+  {0.554405,-0.621567},
+  {-0.620533,-0.351417},
+  {-0.708260,0.277084},
+  {-0.663141,0.789494},
+  {0.544607,-0.890151},
+  {0.915475,0.208660},
+  {-0.089024,-1.629471},
+  {0.122487,0.665973},
+  {0.778714,-0.473087},
+  {0.436424,-0.053708},
+  {-0.962989,0.178894},
+  {-0.093878,-1.372909},
+  {-1.334592,-0.532912},
+  {0.914235,-1.047946},
+  {0.468339,0.302520},
+  {0.144360,0.390533},
+  {-0.851259,0.971010},
+  {-0.701207,0.150590},
+  {0.338131,-0.762748},
+  {1.102405,-0.101683},
+  {0.187218,1.112117},
+  {0.825270,-0.520667},
+  {0.520354,0.359599},
+  {-0.541755,0.243781},
+  {-0.025789,-0.276606},
+  {0.663983,-0.217932},
+  {-0.424530,0.937543},
+  {0.087080,-0.695290},
+  {0.125273,-0.056948},
+  {-0.574391,0.829597},
+  {0.707433,-0.081680},
+  {1.053279,0.587411},
+  {1.371934,-0.232203},
+  {1.377562,-0.181817},
+  {0.301180,1.214186},
+  {-1.259045,-0.768218},
+  {-0.106634,0.320428},
+  {0.638354,0.147326},
+  {1.035767,1.246632},
+  {-0.484057,-0.778008},
+  {-0.568900,0.810352},
+  {1.343526,-0.565878},
+  {-0.078860,0.468044},
+  {-0.241550,-0.951938},
+  {0.207429,-0.254585},
+  {0.447816,-0.015839},
+  {0.302137,0.164948},
+  {0.563014,0.769551},
+  {-1.148579,0.887160},
+  {-0.083611,0.680195},
+  {0.369397,0.512873},
+  {0.381627,1.395393},
+  {0.681791,0.515388},
+  {-0.542576,-1.534588},
+  {1.918437,0.611528},
+  {-0.522244,1.209917},
+  {-0.093985,-0.455651},
+  {-0.107796,0.859061},
+  {-1.018800,0.051540},
+  {-0.539498,-0.754561},
+  {-0.015481,-1.049091},
+  {0.407858,0.681992},
+  {1.168251,-0.815391},
+  {0.280607,-0.068227},
+  {-0.528591,0.091963},
+  {-1.073499,-0.577745},
+  {0.395243,-0.629384},
+  {1.095985,-0.516588},
+  {-0.136250,-0.015595},
+  {-0.696164,0.819270},
+  {-0.192516,-0.906690},
+  {1.066016,0.386976},
+  {0.084233,-0.420819},
+  {0.691169,-0.036671},
+  {0.304274,-0.143800},
+  {0.174184,1.080694},
+  {-0.812545,-0.113297},
+  {0.498295,-0.183696},
+  {1.482711,0.261931},
+  {-1.195411,-0.365014},
+  {-1.007641,-1.211093},
+  {0.180812,-0.582404},
+  {-0.600608,0.360349},
+  {-0.795459,-0.612485},
+  {-0.498403,-0.770827},
+  {0.179341,0.252923},
+  {0.078219,-0.134409},
+  {0.029020,0.530232},
+  {-1.082486,-0.964627},
+  {0.475449,0.228865},
+  {0.945295,-0.971173},
+  {-0.376007,-0.822730},
+  {-0.048402,-0.952172},
+  {0.442908,0.788001},
+  {-0.523677,0.317709},
+  {0.249828,-0.866534},
+  {0.288825,-0.711717},
+  {0.749714,1.240367},
+  {0.231159,-0.142686},
+  {-0.672808,-0.212280},
+  {-0.205479,0.294669},
+  {-0.867840,1.497664},
+  {0.602268,0.171039},
+  {-0.439475,-0.397819},
+  {0.056233,1.305299},
+  {-0.202537,-1.087085},
+  {0.879143,0.645517},
+  {-0.098655,0.549591},
+  {-0.079826,0.092852},
+  {0.787565,-0.587819},
+  {0.844504,0.083068},
+  {-0.316615,-0.486807},
+  {0.318470,-0.589745},
+  {-0.323499,0.031700},
+  {0.794815,1.192794},
+  {-1.434705,-0.743418},
+  {0.194635,0.496011},
+  {-0.068369,1.097164},
+  {0.055882,-0.610884},
+  {-0.944299,-0.941208},
+  {-0.498806,0.156640},
+  {0.208447,-0.528226},
+  {0.956777,-0.354452},
+  {-0.879130,-1.356783},
+  {-0.605954,1.495664},
+  {-0.025056,0.107553},
+  {0.610923,0.435619},
+  {-1.008064,0.239170},
+  {-0.137944,-0.395381},
+  {-0.531626,0.570013},
+  {0.039088,-0.074388},
+  {-0.602167,-0.940069},
+  {0.520930,0.839237},
+  {-1.547177,0.015998},
+  {0.439233,0.453052},
+  {-0.029776,-0.125403},
+  {-0.345532,0.150671},
+  {0.283820,-0.311247},
+  {0.691268,0.439948},
+  {-0.297298,0.571417},
+  {-0.664505,-0.174490},
+  {1.265258,0.472942},
+  {0.049889,0.244857},
+  {-0.095322,0.754115},
+  {-0.029737,-0.356600},
+  {0.146569,-1.294022},
+  {-0.295789,0.369970},
+  {0.200032,-0.482899},
+  {0.781168,1.247152},
+  {-0.245575,0.442512},
+  {-1.080089,-1.224498},
+  {0.347986,-0.310894},
+  {1.813778,-0.546107},
+  {0.347830,1.098305},
+  {1.139714,0.083681},
+  {0.613995,-0.064648},
+  {0.627980,-1.185934},
+  {-0.088940,-0.247523},
+  {0.293299,0.282612},
+  {0.145607,-0.363898},
+  {0.682261,0.069479},
+  {-0.062785,-0.107404},
+  {-0.404708,0.102763},
+  {-0.237587,0.193964},
+  {0.971118,1.637474},
+  {-0.449309,0.565929},
+  {1.795769,0.373496},
+  {-0.873712,0.616632},
+  {-0.196513,-0.640404},
+  {-0.186019,-0.672891},
+  {0.405301,-0.523678},
+  {-1.000323,1.087868},
+  {-0.748565,0.346213},
+  {-0.533750,0.023908},
+  {-0.576248,0.401431},
+  {-0.892996,0.627997},
+  {-0.467071,1.447969},
+  {-0.139768,-1.028884},
+  {0.278656,0.126379},
+  {-0.238544,0.542289},
+  {-0.270467,-1.010170},
+  {-0.228088,0.216426},
+  {1.142972,-0.627060},
+  {1.031965,-0.434600},
+  {0.340546,-0.237191},
+  {-0.136616,0.924569},
+  {-0.852451,0.409948},
+  {-0.030960,0.003293},
+  {0.751540,-0.478669},
+  {0.454761,-0.433887},
+  {-1.611252,0.302680},
+  {0.003690,-0.193511},
+  {-0.883646,-0.472813},
+  {-0.217567,0.614904},
+  {-0.060909,-0.291651},
+  {0.348777,0.769840},
+  {-0.205364,-0.945972},
+  {0.100935,-1.105324},
+  {-0.730546,1.197917},
+  {0.037881,-1.364004},
+  {-0.790273,-0.500485},
+  {1.019594,1.405192},
+  {0.553383,-0.760307},
+  {0.079813,1.242097},
+  {0.724602,0.322399},
+  {0.691650,-0.277596},
+  {-0.999711,0.814944},
+  {-0.103090,0.702437},
+  {-0.245544,-0.599467},
+  {-0.194306,1.677402},
+  {0.436362,1.246626},
+  {0.206087,-0.136172},
+  {1.747782,0.584106},
+  {0.406945,0.500722},
+  {0.401018,0.061251},
+  {-0.485579,-0.126287},
+  {0.102872,0.074572},
+  {0.526394,-0.130306},
+  {-0.997377,0.317494},
+  {0.651321,-0.412428},
+  {-1.160759,-1.663891},
+  {-1.106270,0.202325},
+  {-0.698919,0.195317},
+  {0.486878,0.717703},
+  {-0.998619,0.718843},
+  {0.006452,0.669891},
+  {1.418430,-0.380581},
+  {-0.079725,0.248431},
+  {0.034193,-0.516827},
+  {0.087614,-0.200013},
+  {-0.608534,-0.918271},
+  {-0.096351,-0.320469},
+  {-0.803814,-0.983979},
+  {-0.563381,0.035484},
+  {0.725737,0.753731},
+  {0.945344,-0.412933},
+  {1.252002,0.158636},
+  {-0.615195,-0.442558},
+  {-0.181433,-0.153078},
+  {-0.131831,0.255303},
+  {0.028794,0.045431},
+  {-0.901468,-0.112194},
+  {-0.240013,0.332503},
+  {0.725427,1.028639},
+  {-0.832698,-1.074637},
+  {-0.087355,2.052221},
+  {-1.695433,1.195954},
+  {0.348765,0.618883},
+  {-1.261736,0.226435},
+  {-1.036571,1.108908},
+  {-0.631858,0.969470},
+  {-0.383927,0.513694},
+  {-1.065415,0.305332},
+  {-0.770717,-0.211612},
+  {-0.042169,-0.577398},
+  {0.778070,0.164015},
+  {-0.308740,0.253317},
+  {0.673013,0.384047},
+  {-0.663271,-1.645542},
+  {-0.594806,-0.266981},
+  {0.031422,0.017209},
+  {0.372819,0.179241},
+  {-0.451831,-1.222927},
+  {-1.473253,-1.466359},
+  {-0.021394,1.299407},
+  {0.517073,1.048515},
+  {-0.492487,0.319604},
+  {0.045902,-0.369191},
+  {0.761630,-0.646184},
+  {-1.143760,-0.877989},
+  {-1.207937,0.402411},
+  {0.647822,-0.684881},
+  {1.561865,-0.520949},
+  {0.034907,0.267810},
+  {-0.060274,-1.422451},
+  {-0.739349,0.707542},
+  {-0.536740,-0.575886},
+  {-0.052684,-0.290248},
+  {-0.123131,-0.743400},
+  {-0.514004,0.128876},
+  {-0.865755,0.825335},
+  {-1.093714,-1.041393},
+  {1.399303,-0.474390},
+  {-1.593978,-0.302014},
+  {-0.647736,0.276940},
+  {-1.921976,-1.024671},
+  {-0.330629,-1.292647},
+  {-0.758354,0.195156},
+  {0.469699,0.035348},
+  {-0.091111,0.143719},
+  {-0.451077,0.345265},
+  {0.206307,-1.201955},
+  {-0.710390,1.963236},
+  {0.375559,-0.576808},
+  {0.149091,-1.086740},
+  {-0.449572,0.325384},
+  {-0.192764,0.050606},
+  {0.421631,-0.018053},
+  {1.221822,0.036003},
+  {0.377659,0.155503},
+  {0.659024,-0.972623},
+  {0.028611,1.195320},
+  {0.766597,1.851492},
+  {-0.080947,-0.311238},
+  {-0.546674,0.601715},
+  {0.100401,-0.217646},
+  {0.545637,0.168297},
+  {-1.346635,-0.631837},
+  {-0.682666,0.621478},
+  {0.045733,-0.349107},
+  {-1.244812,-0.204358},
+  {-0.422721,0.108213},
+  {0.079947,-0.097146},
+  {-0.020068,0.559199},
+  {0.297205,0.513111},
+  {0.941640,0.417691},
+  {-0.925712,-0.314921},
+  {-0.315827,1.287305},
+  {0.529011,0.755734},
+  {-1.309677,0.875144},
+  {-0.230303,0.267374},
+  {0.868997,0.302759},
+  {-0.111540,0.065648},
+  {-0.142909,0.138899},
+  {-0.578420,-1.061350},
+  {0.245031,0.319639},
+  {1.260454,-0.384548},
+  {0.982616,0.576288},
+  {0.159346,0.750479},
+  {-0.087783,1.089588},
+  {0.196171,-0.771344},
+  {-0.607085,0.048410},
+  {-0.068539,-0.651095},
+  {0.361776,-0.899946},
+  {0.513233,-0.276754},
+  {-0.815696,0.184741},
+  {0.595970,0.094903},
+  {0.115271,-0.496266},
+  {1.233400,-0.604420},
+  {-1.610600,0.068291},
+  {1.685176,-0.540653},
+  {1.331054,-0.306383},
+  {0.474553,-0.181542},
+  {-0.349692,-1.046318},
+  {0.466882,0.552974},
+  {0.671398,0.059918},
+  {1.220610,-0.655965},
+  {-1.017139,0.324829},
+  {-0.405089,-0.133175},
+  {-1.230806,-0.614727},
+  {0.053516,0.105043},
+  {0.263139,-0.629699},
+  {0.284898,-0.362198},
+  {-0.210472,0.588927},
+  {0.430466,0.051079},
+  {0.114497,0.987658},
+  {-1.348501,0.053213},
+  {-0.087962,0.937382},
+  {-0.583326,-0.560167},
+  {0.925946,0.254656},
+  {-0.883881,-1.030357},
+  {-0.800863,0.810453},
+  {1.625943,-1.280755},
+  {0.323764,-0.336854},
+  {0.797648,0.589424},
+  {-0.219584,0.872309},
+  {0.640241,0.052660},
+  {0.266435,-0.575933},
+  {0.010578,0.226011},
+  {0.416890,0.200529},
+  {1.452786,-0.051537},
+  {-0.310855,0.121700},
+  {-0.632248,-0.915323},
+  {0.030787,-0.673870},
+  {-1.049494,0.197745},
+  {0.047091,-1.145422},
+  {0.711093,0.945179},
+  {-0.242047,0.140575},
+  {0.340217,0.852112},
+  {0.630934,1.603793},
+  {-0.212128,0.191145},
+  {-1.331703,-0.244984},
+  {0.474762,-1.272654},
+  {-0.064322,0.887641},
+  {-0.772426,-0.137183},
+  {-0.476909,-0.765121},
+  {-0.921167,0.515822},
+  {0.706203,-0.726292},
+  {-1.297285,1.234220},
+  {0.251867,0.516994},
+  {0.152440,0.693035},
+  {0.355725,-0.222082},
+  {0.070784,-0.573142},
+  {-0.472779,0.405148},
+  {-0.387195,0.495100},
+  {0.353239,1.388869},
+  {0.436446,0.846312},
+  {0.117673,0.291440},
+  {0.038314,0.003910},
+  {0.832524,0.297668},
+  {-0.067787,-0.787236},
+  {0.308990,-1.201882},
+  {-0.716303,0.682363},
+  {-1.541222,0.779205},
+  {-0.399833,0.182525},
+  {-1.489015,0.201933},
+  {-1.085351,-0.414808},
+  {-0.593430,-0.460045},
+  {-0.136958,0.225884},
+  {0.839454,0.132045},
+  {0.512016,0.539074},
+  {1.021031,-0.818081},
+  {-2.082684,-0.974775},
+  {1.078381,-0.424613},
+  {-0.215449,-1.070854},
+  {-0.267500,-0.045646},
+  {-0.097457,-0.787663},
+  {-1.127850,-0.129833},
+  {0.261141,0.361222},
+  {-0.047321,-0.078316},
+  {-0.213066,-0.934763},
+  {-0.693972,0.416171},
+  {0.734195,0.443239},
+  {-0.761988,1.089263},
+  {0.254715,0.226029},
+  {0.302206,0.304181},
+  {-0.588604,-0.955464},
+  {-0.724068,0.962523},
+  {1.030788,1.094885},
+  {-1.634408,0.959742},
+  {-0.343578,0.529590},
+  {-0.913576,0.062114},
+  {-0.029438,0.785613},
+  {-0.978121,-1.357258},
+  {0.393594,-0.252471},
+  {-0.547676,0.105908},
+  {0.540394,-0.607045},
+  {0.769064,-0.118855},
+  {-0.655730,0.653167},
+  {0.624079,0.821763},
+  {0.289239,-0.019449},
+  {0.171656,-0.435785},
+  {1.322478,0.011860},
+  {-2.093062,1.275452},
+  {-0.213217,0.410659},
+  {-0.922502,0.014639},
+  {1.481723,-0.168258},
+  {-1.494468,-0.526159},
+  {0.212115,-0.653763},
+  {0.247302,0.440803},
+  {-0.227827,-0.164564},
+  {-0.730551,0.626705},
+  {0.955221,-0.640437},
+  {0.083621,-0.495753},
+  {0.010779,0.268628},
+  {-0.517990,0.518614},
+  {-0.127293,0.121118},
+  {-1.391215,0.845785},
+  {0.376562,0.013170},
+  {-0.023148,0.651098},
+  {-0.545330,1.030364},
+  {0.423751,-1.034899},
+  {0.064578,0.069449},
+  {0.727233,-0.170816},
+  {-0.262943,-0.128789},
+  {-0.200262,0.310986},
+  {0.252975,0.424229},
+  {-0.907615,-0.073997},
+  {-0.543862,-0.735072},
+  {-0.813343,-0.173314},
+  {-1.201885,1.528061},
+  {0.656099,0.166095},
+  {-1.168671,0.209173},
+  {0.835893,0.449546},
+  {0.058003,-0.443218},
+  {-0.940742,0.333260},
+  {0.685444,1.349441},
+  {-0.070850,0.383320},
+  {-0.784000,0.412765},
+  {0.972754,0.248983},
+  {-0.611710,0.795272},
+  {0.740168,-0.382664},
+  {-0.595800,1.134890},
+  {-0.291688,-0.192899},
+  {-0.324666,1.139416},
+  {-0.026190,0.014553},
+  {-0.797475,0.108035},
+  {0.257394,-0.383343},
+  {0.936633,-2.076909},
+  {-0.164027,0.563305},
+  {-0.029333,-1.077666},
+  {-0.776752,0.687745},
+  {-0.361438,-1.434606},
+  {0.159147,0.129632},
+  {0.742079,-0.379723},
+  {-0.325943,-0.534641},
+  {0.421914,0.776426},
+  {-1.185213,1.207085},
+  {-0.812063,-0.427344},
+  {-1.734549,-0.468229},
+  {-0.532631,-0.196973},
+  {-1.124256,-0.783135},
+  {0.002816,-0.609461},
+  {0.497856,-0.858671},
+  {0.297182,-0.995354},
+  {-0.009002,-0.094468},
+  {-0.841901,0.478523},
+  {-0.357151,-0.724320},
+  {0.684269,-0.106986},
+  {-0.875832,0.368872},
+  {-0.451512,1.155647},
+  {0.007695,0.984606},
+  {-0.245539,-0.586946},
+  {-0.438202,0.003614},
+  {0.272786,0.270776},
+  {0.645523,0.541562},
+  {-0.237560,-0.637564},
+  {-0.848358,-0.612336},
+  {-0.277362,-0.783485},
+  {0.481862,-0.045225},
+  {0.276958,0.039033},
+  {-0.226987,1.330472},
+  {1.139474,0.298630},
+  {-0.452719,0.688238},
+  {0.575993,-1.073807},
+  {-0.877879,-0.474368},
+  {1.162578,-0.352652},
+  {-0.616572,-0.422459},
+  {-0.353035,1.347897},
+  {-1.158601,-0.646731},
+  {0.451272,0.588822},
+  {-0.141924,0.363633},
+  {0.527233,-0.473859},
+  {-0.363216,-0.892939},
+  {-1.340083,-0.111274},
+  {-0.603631,-0.270979},
+  {-0.188457,0.012816},
+  {-0.811343,1.252060},
+  {1.188571,-0.831308},
+  {-1.041929,-0.096941},
+  {0.712698,0.394449},
+  {-0.553583,0.946137},
+  {-1.219442,-0.169581},
+  {0.864311,-0.554224},
+  {-0.262955,1.220312},
+  {-0.576259,0.887034},
+  {1.004077,0.461673},
+  {-1.593715,0.659881},
+  {0.531584,0.228323},
+  {-0.240945,0.486940},
+  {0.922614,-0.455564},
+  {0.275567,0.685332},
+  {-0.420722,1.269918},
+  {0.430470,0.686037},
+  {0.034631,-0.235561},
+  {-0.314039,-0.525507},
+  {0.272926,1.024054},
+  {-0.597859,-0.371195},
+  {0.369351,0.638611},
+  {-0.203028,1.337666},
+  {0.939544,0.549966},
+  {0.478238,-0.275508},
+  {-0.155890,0.618782},
+  {0.065502,1.306056},
+  {-0.144435,-1.053199},
+  {0.675192,-1.042800},
+  {0.887757,0.799049},
+  {1.032078,-0.335687},
+  {-0.416585,-0.671976},
+  {-0.277219,0.392748},
+  {-1.373308,0.145767},
+  {-1.898957,0.258620},
+  {-1.507777,-0.799117},
+  {0.125190,-1.513681},
+  {-0.555275,-1.147338},
+  {0.109193,0.630449},
+  {0.850572,-0.428761},
+  {0.762598,-0.418743},
+  {-0.658676,0.120374},
+  {0.219889,0.679444},
+  {0.960891,0.748391},
+  {0.870463,0.591815},
+  {1.008497,0.258433},
+  {-0.397245,0.229091},
+  {0.079530,-0.765548},
+  {-1.189197,0.391146},
+  {1.090130,-0.176457},
+  {0.878735,-1.220042},
+  {-0.282687,0.045037},
+  {0.690295,0.760265},
+  {-0.064226,-1.270045},
+  {0.451127,0.620894},
+  {0.518653,-0.291379},
+  {1.427926,0.763723},
+  {0.013799,-0.112367},
+  {-0.284511,0.556617},
+  {0.023375,-1.498134},
+  {0.527409,0.837385},
+  {-0.337269,0.119037},
+  {0.397375,1.457268},
+  {-0.915267,1.637006},
+  {0.189049,0.517475},
+  {0.118637,1.005364},
+  {0.396135,-1.604041},
+  {-0.089106,-0.609048},
+  {-0.028093,0.096681},
+  {0.978246,-0.222336},
+  {0.078209,0.502843},
+  {0.317957,-0.209239},
+  {-0.235391,-1.067509},
+  {0.672564,-0.630147},
+  {0.573721,0.505773},
+  {-0.211566,0.007962},
+  {0.493715,-1.029766},
+  {0.610607,-0.973276},
+  {-0.204172,-0.197208},
+  {1.323638,-0.298948},
+  {-1.036127,-1.456968},
+  {-0.650336,-0.262731},
+  {-0.324206,-0.556171},
+  {0.184158,-0.349058},
+  {0.439262,0.058320},
+  {-1.534475,0.227140},
+  {-0.631174,1.780843},
+  {-0.755815,-0.501755},
+  {0.146835,-0.731846},
+  {0.859454,0.963689},
+  {0.800582,-0.146938},
+  {1.372001,0.638182},
+  {-0.919889,-0.622212},
+  {0.681129,-0.602858},
+  {0.172753,1.274081},
+  {-0.669045,-0.735854},
+  {1.072433,-0.430603},
+  {-0.945714,0.249387},
+  {0.058404,-0.356905},
+  {0.280842,1.395081},
+  {-1.333727,0.175503},
+  {-0.162653,0.997135},
+  {1.349928,-0.778412},
+  {0.351735,-0.432853},
+  {0.130525,-0.679365},
+  {-0.255894,0.000290},
+  {-0.033975,0.753936},
+  {0.880727,0.592943},
+  {-0.432137,-1.241763},
+  {-0.916417,0.629270},
+  {-0.417353,0.281667},
+  {1.027431,-0.561347},
+  {-0.313624,-0.862803},
+  {0.688305,-1.114407},
+  {0.407758,0.350545},
+  {-0.084867,-0.097319},
+  {0.659983,0.568765},
+  {-0.226611,0.133226},
+  {-0.215283,-0.443496},
+  {0.718936,-0.037813},
+  {0.933978,-0.233086},
+  {-0.516582,0.734210},
+  {0.736643,0.706611},
+  {0.305234,0.000249},
+  {-0.370270,0.590320},
+  {0.962118,-0.925841},
+  {-1.048981,-0.103269},
+  {0.044995,0.871437},
+  {0.797065,-0.797195},
+  {0.012374,1.464487},
+  {-0.744670,-0.902590},
+  {-0.975379,0.299666},
+  {-0.751756,-0.171825},
+  {-0.478057,1.113745},
+  {-0.351503,0.127088},
+  {0.589924,-0.913712},
+  {1.035181,-0.319182},
+  {-0.226216,-0.426067},
+  {0.740355,0.631193},
+  {-0.506299,-2.521827},
+  {-0.734618,-0.279302},
+  {-0.793006,0.934782},
+  {0.400248,0.019342},
+  {-0.460130,0.039696},
+  {-1.182922,-0.759926},
+  {-0.322657,0.433662},
+  {1.295318,0.089107},
+  {0.776325,-0.202020},
+  {-1.354920,-0.019325},
+  {-0.070378,-0.628537},
+  {-0.313186,-0.122804},
+  {0.679820,-0.407435},
+  {0.568100,-0.865077},
+  {-0.270622,-0.118376},
+  {-0.120073,1.163957},
+  {-2.521375,-0.093829},
+  {0.242298,-0.793270},
+  {0.110432,1.286578},
+  {0.589488,0.684460},
+  {-0.130721,-0.833847},
+  {-1.196174,0.719174},
+  {1.558364,-0.705261},
+  {0.040922,0.325140},
+  {-0.591884,0.749348},
+  {-0.121397,0.219684},
+  {0.378761,-0.899270},
+  {-0.292474,-0.083947},
+  {-0.868838,-1.003608},
+  {0.229984,-1.746968},
+  {-0.653827,-0.413638},
+  {-0.724029,0.485097},
+  {0.014806,1.481808},
+  {-0.493384,-0.210216},
+  {0.722527,-0.225007},
+  {1.054819,1.601291},
+  {-0.282008,-0.282742},
+  {-0.866851,0.072647},
+  {-1.735218,-0.205276},
+  {-0.689724,-0.951328},
+  {0.216225,0.177342},
+  {-0.124588,-0.162394},
+  {0.489274,-0.190430},
+  {-0.057484,-0.451252},
+  {-0.838170,0.008589},
+  {-0.012782,1.507933},
+  {-0.471353,0.394553},
+  {-0.190237,0.685665},
+  {0.557875,-0.620214},
+  {-0.059726,0.397332},
+  {-0.592982,-0.006411},
+  {-0.123340,0.161368},
+  {-0.854995,0.700566},
+  {-0.572703,-0.252267},
+  {-0.763440,0.344721},
+  {0.021265,0.446768},
+  {-0.586946,0.323793},
+  {0.180415,0.043743},
+  {-0.288882,-0.511805},
+  {2.624556,-0.567090},
+  {0.551481,0.803221},
+  {-0.143453,-0.586976},
+  {0.992092,1.533923},
+  {-0.318124,-0.550864},
+  {1.318704,-0.063433},
+  {-0.155347,1.117042},
+  {0.058911,-0.944546},
+  {0.108052,-0.051107},
+  {-1.035368,0.386023},
+  {-0.823147,0.171737},
+  {0.846301,0.680001},
+  {-0.110664,0.468723},
+  {-0.083706,0.625575},
+  {0.290091,0.858146},
+  {-0.662183,-0.590796},
+  {-0.288190,-0.353492},
+  {-1.159802,-1.337642},
+  {-0.306885,-0.750638},
+  {0.044691,-1.653807},
+  {-0.615050,0.289028},
+  {-0.201731,0.465221},
+  {1.008004,-0.060762},
+  {-0.550498,0.300423},
+  {-0.116548,-0.013405},
+  {0.549048,1.586230},
+  {0.759367,-0.971517},
+  {1.323636,1.681829},
+  {0.170062,0.089436},
+  {-0.211072,0.704819},
+  {-0.419963,-0.128266},
+  {0.626398,-0.551576},
+  {1.543900,0.511508},
+  {-0.784514,1.183790},
+  {0.502940,1.028658},
+  {-1.016714,0.248965},
+  {0.112604,0.111350},
+  {-0.123006,0.683764},
+  {0.021753,-0.247159},
+  {0.138703,1.086674},
+  {-0.051887,-1.076659},
+  {1.737884,0.864115},
+  {-0.215718,0.020311},
+  {0.666013,-0.799401},
+  {-1.108657,0.547216},
+  {0.552800,2.316691},
+  {-0.103811,0.195943},
+  {-0.559387,0.399860},
+  {-0.574699,-0.002171},
+  {0.494645,0.839499},
+  {1.539942,0.061094},
+  {-1.185473,0.157370},
+  {0.687725,-0.726402},
+  {1.062304,0.143174},
+  {-0.231306,0.431820},
+  {0.181212,0.243572},
+  {0.048089,1.016969},
+  {1.019749,-0.468151},
+  {0.272841,-0.383551},
+  {0.606381,-0.216956},
+  {-1.061207,-1.080103},
+  {-0.174838,0.363043},
+  {-0.498895,1.116096},
+  {-0.098641,0.561958},
+  {0.043930,0.385439},
+  {-0.427768,-1.146650},
+  {0.923076,-0.396539},
+  {0.754689,0.963067},
+  {-0.037038,-0.203416},
+  {0.019305,-0.562339},
+  {-0.797642,-0.371491},
+  {0.081456,-0.831708},
+  {0.208751,-1.180105},
+  {-0.774074,-0.978951},
+  {1.266618,0.537957},
+  {-0.712267,0.567095},
+  {0.145303,-0.817414},
+  {1.967789,1.007710},
+  {0.193202,0.217408},
+  {-0.798454,-0.633302},
+  {-0.330441,0.650118},
+  {-0.007839,0.797737},
+  {-0.990287,0.006108},
+  {-0.443475,1.373610},
+  {0.356907,-0.324058},
+  {-0.456490,0.150888},
+  {0.778863,-0.215198},
+  {-0.465454,-0.433403},
+  {0.906855,0.653127},
+  {0.492398,-0.648731},
+  {0.945877,-1.419218},
+  {-0.177893,-0.646512},
+  {1.411359,-0.241056},
+  {-0.264133,-1.505842},
+  {-0.366946,0.985009},
+  {-0.128469,-0.052593},
+  {0.167171,-0.446152},
+  {0.919920,0.002816},
+  {0.119854,-0.960683},
+  {1.395234,-1.093261},
+  {0.264784,0.684038},
+  {0.136742,-0.623673},
+  {-1.157844,0.208610},
+  {-0.081146,-0.545579},
+  {0.129620,0.317296},
+  {-0.565284,0.051918},
+  {-0.552605,0.036032},
+  {0.605695,-0.026673},
+  {0.050425,2.453665},
+  {0.044827,-1.616143},
+  {-0.113293,0.653822},
+  {1.093501,2.247677},
+  {0.695921,-1.033199},
+  {0.000694,-0.086366},
+  {0.421101,0.539692},
+  {0.051940,-1.072276},
+  {0.040107,-0.888686},
+  {-0.229449,1.123220},
+  {1.198503,-0.862325},
+  {0.700102,0.555513},
+  {-0.119860,-0.774937},
+  {-0.028011,1.437656},
+  {1.000033,0.429811},
+  {0.381991,-0.471777},
+  {-1.061909,0.633338},
+  {0.795537,-0.653199},
+  {1.595592,-1.118207},
+  {-0.084673,-1.361223},
+  {-0.624297,0.764246},
+  {0.089882,1.013592},
+  {-0.533656,0.632749},
+  {0.465736,0.775404},
+  {-0.888801,-0.059761},
+  {0.523573,0.053779},
+  {-0.209593,0.885880},
+  {0.748105,0.127068},
+  {0.599795,-1.139121},
+  {-0.077588,0.842374},
+  {0.761840,-0.795831},
+  {0.709548,0.183950},
+  {-0.252544,0.680008},
+  {0.570220,0.515018},
+  {0.266137,-0.206870},
+  {-0.885632,1.679647},
+  {1.150557,0.483125},
+  {-0.468721,-1.841706},
+  {0.271059,0.926911},
+  {-0.154149,-0.322614},
+  {-0.329320,1.218566},
+  {-0.171047,-1.007784},
+  {0.223529,-0.505620},
+  {0.772175,0.801805},
+  {-0.341824,0.518301},
+  {0.968368,-1.633597},
+  {0.073692,-0.583842},
+  {-0.953372,-0.161117},
+  {0.551488,0.447077},
+  {0.020273,-0.505357},
+  {0.365393,-0.032102},
+  {0.844367,-0.639689},
+  {1.018752,0.751834},
+  {1.126097,-0.613405},
+  {1.016788,-0.019078},
+  {0.623747,0.592169},
+  {-1.319641,0.298078},
+  {-0.329394,-0.423323},
+  {0.364704,-0.653483},
+  {0.617694,-0.252054},
+  {-0.591705,1.619074},
+  {-0.161785,1.838932},
+  {0.564582,-0.723667},
+  {0.225778,0.243980},
+  {-0.037796,0.502040},
+  {0.367842,-1.021410},
+  {-0.427836,-0.366767},
+  {-0.488887,1.324747},
+  {0.283351,-0.475819},
+  {-0.368885,-0.343402},
+  {0.022111,-1.503025},
+  {0.608174,0.232807},
+  {0.872253,-0.186510},
+  {-0.550839,-0.327475},
+  {-0.154591,-0.267873},
+  {-0.747008,-0.379431},
+  {-0.277511,-0.951636},
+  {-0.759266,0.574239},
+  {1.154286,0.179194},
+  {-0.112772,-0.817203},
+  {0.200759,0.799191},
+  {-0.502025,0.432883},
+  {-1.119323,-0.074693},
+  {1.254542,0.141465},
+  {0.080510,0.266965},
+  {1.402806,0.382574},
+  {0.817240,-0.115142},
+  {0.507720,0.176294},
+  {0.210651,-0.143840},
+  {-0.689945,1.732906},
+  {0.235579,-0.641823},
+  {0.851720,-0.271216},
+  {-0.214092,-1.383215},
+  {1.260678,-0.375676},
+  {-0.342547,0.300925},
+  {0.157321,-1.216358},
+  {-1.291505,0.269752},
+  {-0.813264,0.966839},
+  {0.385009,-0.966745},
+  {0.048812,0.037934},
+  {0.157922,0.072546},
+  {0.136019,-0.636157},
+  {-1.131118,0.701695},
+  {0.057882,0.542163},
+  {-0.289670,-0.556624},
+  {0.296565,0.901636},
+  {0.811896,0.152258},
+  {0.071886,-0.310387},
+  {0.248307,-1.423973},
+  {-0.077694,-0.208889},
+  {0.351881,-0.374276},
+  {-1.108993,0.435304},
+  {0.689461,-0.661618},
+  {-0.847280,0.417742},
+  {-0.693780,-0.030547},
+  {0.205481,0.163966},
+  {1.152296,0.501315},
+  {0.421218,-0.000555},
+  {-0.796311,0.281834},
+  {-0.269010,1.052164},
+  {0.133541,-0.454531},
+  {-0.412860,1.370429},
+  {0.616688,0.124832},
+  {0.702940,-1.203623},
+  {0.675882,-0.390202},
+  {0.830890,1.250459},
+  {0.674844,0.665324},
+  {-0.043831,0.707066},
+  {-0.886906,-0.060713},
+  {0.677298,-0.111700},
+  {-0.754756,-0.380721},
+  {-0.561574,0.787921},
+  {-0.138727,-0.246949},
+  {0.399551,0.257836},
+  {0.391218,-0.046240},
+  {-0.604638,-0.547392},
+  {1.211615,0.045085},
+  {-2.243039,-0.736534},
+  {0.779312,0.843648},
+  {0.162298,0.157163},
+  {-0.140700,0.766237},
+  {-0.144998,0.378899},
+  {0.417087,0.656509},
+  {-0.663537,0.226287},
+  {0.623830,0.333788},
+  {2.231783,0.374867},
+  {0.734099,0.049999},
+  {1.036979,-0.688127},
+  {-1.040401,-0.707128},
+  {0.381121,-0.100134},
+  {1.359817,-0.400703},
+  {-0.552157,-1.396689},
+  {0.259124,-0.224525},
+  {-0.273705,-0.347394},
+  {-0.409249,0.216952},
+  {-0.216934,-0.899068},
+  {-0.235146,0.030945},
+  {-0.889038,0.360220},
+  {-0.157354,0.100057},
+  {-0.036127,-0.499812},
+  {-0.348823,0.151622},
+  {0.279825,-0.589387},
+  {-0.933342,0.643324},
+  {0.555767,-0.017369},
+  {-0.011276,-0.013992},
+  {-0.434804,0.253158},
+  {0.675855,-0.224374},
+  {-0.805744,0.659219},
+  {0.808692,0.008962},
+  {0.397507,-1.041463},
+  {-0.127428,-0.570829},
+  {-0.029020,-0.201817},
+  {-1.009712,-0.877845},
+  {-1.216129,0.783185},
+  {0.328932,-0.747150},
+  {-0.854801,-0.178626},
+  {-0.785073,-1.023245},
+  {0.788804,0.147804},
+  {-0.654940,0.835733},
+  {1.194529,0.469089},
+  {-0.435047,-0.112630},
+  {-0.398296,0.298359},
+  {0.614442,-0.831401},
+  {0.898647,1.252811},
+  {-0.651719,0.063096},
+  {0.829332,-0.130964},
+  {-0.644862,0.485383},
+  {0.099189,-1.241679},
+  {0.232553,-1.087991},
+  {0.827992,0.327188},
+  {0.251847,-0.542311},
+  {0.114473,0.172203},
+  {-0.607207,-0.449144},
+  {-0.376521,0.290727},
+  {-0.132065,0.363772},
+  {0.435356,-0.571154},
+  {-0.190653,0.248960},
+  {0.651496,-0.923586},
+  {0.512997,-0.004873},
+  {-0.236174,-0.568753},
+  {0.932160,-1.334080},
+  {0.155451,0.672475},
+  {-0.911918,-0.030052},
+  {0.263176,0.406002},
+  {0.304970,-0.011967},
+  {-0.410390,-0.330155},
+  {-0.141643,0.047151},
+  {-0.172968,-1.012272},
+  {-0.372838,0.560728},
+  {-0.855840,0.042006},
+  {-0.164063,0.636134},
+  {-1.109047,-0.279656},
+  {-0.069774,-0.604646},
+  {-0.282135,-0.394121},
+  {0.176084,0.052311},
+  {0.487541,-0.565642},
+  {-0.208335,0.518275},
+  {-0.149021,-0.363198},
+  {-0.249631,-0.090729},
+  {-0.249841,-0.596483},
+  {0.640211,-0.976106},
+  {0.326645,0.866942},
+  {1.183765,0.830576},
+  {-0.029594,-0.620946},
+  {1.115148,-0.337932},
+  {1.567311,0.261972},
+  {-0.721293,-0.564232},
+  {-0.357507,0.803439},
+  {-1.016735,-0.027591},
+  {-0.426745,1.104032},
+  {0.443712,1.244449},
+  {1.160755,-0.838377},
+  {-0.819387,-0.128786},
+  {0.288092,0.008755},
+  {-0.515644,0.101036},
+  {0.364482,-0.130023},
+  {-0.229438,-0.654899},
+  {0.906635,-0.125711},
+  {-0.159322,-0.304040},
+  {-1.211824,0.158356},
+  {-0.012123,-0.488427},
+  {-0.426069,-0.835684},
+  {-0.125217,-1.170805},
+  {-0.270562,0.000386},
+  {0.623183,-0.945317},
+  {0.848419,-0.522606},
+  {1.250635,0.444407},
+  {0.492130,1.050228},
+  {1.080375,-0.338691},
+  {-0.764704,-1.279899},
+  {0.741656,0.485046},
+  {0.956357,-1.023715},
+  {-0.247405,-0.820810},
+  {-0.149085,-0.107801},
+  {-0.570624,1.043465},
+  {-0.115018,-0.641550},
+  {-0.616512,-0.289516},
+  {1.176485,-0.172412},
+  {-0.362269,1.717443},
+  {-0.817064,-0.370700},
+  {-0.465179,0.259246},
+  {-0.642608,0.664244},
+  {0.747615,0.390002},
+  {-1.838046,-0.673345},
+  {-0.071150,-0.063051},
+  {0.124401,-0.037791},
+  {0.721531,-0.349121},
+  {0.948579,-0.683095},
+  {-0.296344,-1.657454},
+  {-0.244777,-0.050854},
+  {-0.355675,-0.088336},
+  {0.834088,-0.200241},
+  {-1.139669,0.315556},
+  {-0.080632,-0.198803},
+  {-0.187648,0.739006},
+  {0.609210,-1.146719},
+  {0.133987,0.472373},
+  {1.301981,-0.658052},
+  {0.148344,0.175711},
+  {0.482189,-1.298825},
+  {-0.666823,-0.399625},
+  {0.067421,-0.725454},
+  {-0.052146,-0.168842},
+  {0.332959,0.334690},
+  {-1.054764,0.239030},
+  {-0.165250,-0.447066},
+  {-0.428016,1.320568},
+  {0.510212,0.318306},
+  {0.451920,0.645015},
+  {1.606643,0.236357},
+  {0.230974,0.123761},
+  {-0.049062,0.112286},
+  {0.479037,0.015434},
+  {-0.287389,0.872496},
+  {1.067029,0.499731},
+  {-0.126337,0.779721},
+  {-0.370434,0.612051},
+  {0.075632,0.614917},
+  {-0.528660,-0.850174},
+  {0.487266,-0.590261},
+  {-0.234836,0.263938},
+  {-0.065654,2.081570},
+  {-0.636267,-0.906258},
+  {-0.803871,0.321421},
+  {-0.328638,0.333370},
+  {-0.516140,0.175497},
+  {0.347902,-0.402807},
+  {0.411276,0.362019},
+  {0.440469,0.412853},
+  {1.107078,-0.338276},
+  {0.856038,-0.131811},
+  {-0.369578,0.324333},
+  {0.516267,0.144410},
+  {-0.706354,-0.923046},
+  {1.199280,-0.679079},
+  {-0.206381,0.733361},
+  {-1.118980,-0.339299},
+  {0.249695,1.301003},
+  {-0.001465,1.070052},
+  {-0.888923,-0.187516},
+  {0.810337,0.313939},
+  {0.305196,0.026000},
+  {0.494726,1.024847},
+  {1.476541,-0.802107},
+  {-0.526713,0.266385},
+  {0.384008,-0.961735},
+  {1.282973,-0.698481},
+  {0.988486,0.038408},
+  {-0.219075,-1.024923},
+  {-0.466889,0.255891},
+  {0.003917,0.530058},
+  {-0.767964,-0.385498},
+  {-0.377691,0.462312},
+  {0.026027,-1.093603},
+  {-0.458202,0.027801},
+  {0.806314,-0.293232},
+  {0.050386,0.705391},
+  {0.738212,0.099567},
+  {1.685787,0.176921},
+  {-0.892685,-0.318613},
+  {1.109295,-0.356620},
+  {-0.037037,-0.399946},
+  {1.099257,0.066189},
+  {-0.138197,0.931202},
+  {0.352476,0.541835},
+  {-0.234773,1.811281},
+  {0.220325,1.006277},
+  {1.183808,0.818720},
+  {0.412037,-0.266925},
+  {-0.046189,0.101378},
+  {-0.525259,0.184060},
+  {0.223098,-0.866883},
+  {0.759485,1.089619},
+  {-0.645569,0.593185},
+  {-0.363564,-0.111653},
+  {-0.760729,0.424275},
+  {-0.173270,0.825271},
+  {-0.893186,0.404038},
+  {0.757566,0.583220},
+  {-0.256129,-0.077900},
+  {0.284986,0.630869},
+  {0.664454,0.481663},
+  {0.119009,0.113249},
+  {-0.205947,1.010834},
+  {0.932543,-0.060003},
+  {0.274266,-0.406043},
+  {-0.247609,0.396317},
+  {-0.442815,0.120444},
+  {-1.305720,0.295270},
+  {0.936322,0.968362},
+  {-0.571598,-0.407698},
+  {-0.392774,-0.484139},
+  {0.822763,0.339368},
+  {-0.517289,0.041135},
+  {0.147543,-0.792703},
+  {-1.670020,0.099579},
+  {-0.299869,-0.266431},
+  {0.605640,-0.814238},
+  {1.222721,1.050723},
+  {-0.467391,-0.124769},
+  {-0.575869,0.609053},
+  {1.713472,0.570511},
+  {0.042960,-1.006402},
+  {1.239476,-0.082176},
+  {0.378559,-0.955065},
+  {-0.165652,0.451352},
+  {0.429384,-0.053004},
+  {-0.244308,1.056232},
+  {0.830270,-0.183125},
+  {-0.600558,-1.360258},
+  {0.171056,-0.003685},
+  {0.839484,0.430587},
+  {-0.553197,-1.112661},
+  {0.472149,1.241828},
+  {0.428034,0.237235},
+  {0.611704,-0.377012},
+  {-0.231170,-0.306880},
+  {0.087621,0.844398},
+  {1.390622,0.674419},
+  {0.387463,-0.353450},
+  {-0.150300,0.730488},
+  {-1.062157,0.504289},
+  {-0.531514,0.020223},
+  {0.128882,-0.065820},
+  {0.331307,0.862964},
+  {-0.725060,0.793610},
+  {0.668800,-2.340218},
+  {0.306622,0.510434},
+  {-0.240424,0.483310},
+  {0.755874,-0.307130},
+  {0.307453,-0.534037},
+  {-0.260084,-0.957092},
+  {0.030535,-0.356006},
+  {0.063740,0.338408},
+  {0.137347,0.408912},
+  {0.071998,-0.512812},
+  {-0.816655,0.667604},
+  {0.206418,0.459734},
+  {-0.199134,-1.021477},
+  {-0.027864,-0.229509},
+  {0.029766,0.406308},
+  {0.263539,0.950641},
+  {1.107474,0.510104},
+  {0.701356,-0.092664},
+  {-0.332519,0.882492},
+  {-0.259295,0.542719},
+  {0.803323,-0.516191},
+  {-0.810940,0.828519},
+  {-0.333099,0.493898},
+  {0.803446,0.041317},
+  {-0.752852,-0.397360},
+  {-0.508714,-0.341192},
+  {-0.998590,0.444147},
+  {0.540311,0.590371},
+  {0.352505,-0.284619},
+  {-0.330681,0.699920},
+  {-0.428966,0.610587},
+  {-1.333091,-0.297171},
+  {0.345433,-0.821063},
+  {0.993852,0.062134},
+  {0.729285,0.480559},
+  {-0.038753,-0.071297},
+  {-0.388438,-0.398816},
+  {-0.746620,-0.076653},
+  {0.345309,0.817757},
+  {0.769405,-0.063687},
+  {0.092044,-0.442898},
+  {1.029397,-0.869702},
+  {0.832081,0.437601},
+  {-0.374608,-0.269611},
+  {-0.728890,-1.033769},
+  {-0.207543,1.059676},
+  {0.140337,0.321861},
+  {-0.268235,0.376937},
+  {0.554032,-1.522496},
+  {0.302898,1.115891},
+  {-0.566679,1.087246},
+  {0.209126,-0.299056},
+  {0.183449,-0.446472},
+  {0.769257,1.156924},
+  {-0.426186,-0.534314},
+  {1.357257,-0.027091},
+  {0.125598,-0.148277},
+  {0.361150,-0.612232},
+  {0.733645,-0.215266},
+  {-0.599140,-0.087500},
+  {0.364386,-0.379064},
+  {0.106744,0.427322},
+  {0.244401,-0.090466},
+  {-0.086618,0.290300},
+  {-0.769588,1.227312},
+  {0.410929,0.406906},
+  {0.033896,-0.301329},
+  {1.368098,-1.264228},
+  {0.265425,0.246094},
+  {-1.089731,0.655995},
+  {-0.959035,-0.323536},
+  {-0.177452,0.299655},
+  {-1.085650,0.751856},
+  {-0.934940,-0.467314},
+  {0.157832,-1.370121},
+  {-0.756801,1.174560},
+  {-0.238213,1.484015},
+  {0.103337,0.562886},
+  {-0.883352,-0.457006},
+  {-0.619941,-0.072602},
+  {0.827989,-0.576543},
+  {-0.274512,0.688768},
+  {0.192892,0.046977},
+  {0.494114,-1.198486},
+  {0.210812,-1.483980},
+  {0.068552,-0.412908},
+  {0.768963,0.512225},
+  {0.887015,-0.416106},
+  {0.069268,-0.161404},
+  {1.158016,0.428234},
+  {1.414889,0.177849},
+  {-0.043316,-0.734135},
+  {1.519925,-0.641341},
+  {-0.954973,-0.096053},
+  {-0.627640,0.832967},
+  {-0.128482,0.227255},
+  {0.096457,-0.172163},
+  {-1.188885,0.383040},
+  {-0.636699,0.641324},
+  {0.760031,-0.811875},
+  {-0.020737,0.443516},
+  {0.457384,-0.365880},
+  {-0.876749,1.149372},
+  {0.295054,0.679878},
+  {0.023256,0.103668},
+  {-0.327805,-0.125698},
+  {0.020041,0.216254},
+  {-0.306899,-0.187019},
+  {1.085265,0.158704},
+  {-0.145690,-0.394788},
+  {0.338803,0.342693},
+  {-0.515034,-1.539775},
+  {-0.389804,1.336893},
+  {-0.094832,0.858926},
+  {-0.697567,-0.301372},
+  {0.304157,-0.457016},
+  {0.445920,0.840317},
+  {0.367189,-0.400123},
+  {-0.537674,0.319642},
+  {0.040484,0.213835},
+  {0.486631,0.235979},
+  {-0.927168,0.494577},
+  {0.095336,0.538537},
+  {-0.685255,-0.341503},
+  {-0.414110,0.730628},
+  {-0.249497,-0.384687},
+  {-0.381906,0.335050},
+  {-0.296216,0.192564},
+  {0.259756,0.167208},
+  {-0.631983,0.213763},
+  {-0.107557,0.031968},
+  {0.086282,-0.608626},
+  {-0.520260,-0.616549},
+  {-0.380245,1.375046},
+  {-1.355688,-0.262657},
+  {-1.404467,0.037742},
+  {0.045811,0.570009},
+  {-0.416171,-0.129814},
+  {0.370554,0.880282},
+  {0.719642,1.595834},
+  {0.056979,1.643866},
+  {0.509780,-0.269105},
+  {-0.035170,-0.008985},
+  {-0.380304,0.435292},
+  {-0.061932,0.766256},
+  {0.417917,0.120335},
+  {-1.059375,0.118735},
+  {0.561525,-0.136216},
+  {1.044780,0.316513},
+  {0.278741,0.285996},
+  {0.445276,1.914646},
+  {1.135214,-0.056030},
+  {1.552693,-0.468664},
+  {0.107992,0.196631},
+  {0.010882,-0.782850},
+  {0.411889,0.243120},
+  {1.041102,0.506174},
+  {-0.436580,1.011682},
+  {0.234764,-1.107368},
+  {-0.369947,-0.283590},
+  {0.712020,-0.042864},
+  {0.256171,-0.289042},
+  {-0.664674,-0.389437},
+  {0.501317,-0.199763},
+  {-0.233973,0.776302},
+  {-0.551974,-0.311394},
+  {-1.213793,-0.063365},
+  {-0.942542,0.886742},
+  {0.120656,-0.927157},
+  {0.848886,-0.191111},
+  {-0.085995,0.712069},
+  {-0.121119,0.712586},
+  {0.795790,0.039031},
+  {1.130273,-1.091505},
+  {-1.009660,-0.084673},
+  {-1.391243,1.439570},
+  {-0.790172,1.190427},
+  {-1.055203,1.031347},
+  {0.351972,-0.261797},
+  {0.309700,-0.121583},
+  {-1.395336,-0.368211},
+  {-0.242807,0.043287},
+  {-0.091725,1.525055},
+  {0.222701,-0.585086},
+  {-0.197990,1.109946},
+  {0.683433,0.234584},
+  {0.778488,1.031004},
+  {-1.728844,-0.828213},
+  {-0.305833,0.235194},
+  {0.839395,1.013991},
+  {-0.732283,-1.178569},
+  {0.751353,0.525831},
+  {-0.608151,-0.209578},
+  {-0.760489,0.909863},
+  {-0.941207,0.596632},
+  {0.113422,0.124614},
+  {-0.677100,-0.845145},
+  {-2.116992,-1.043945},
+  {0.443954,1.264070},
+  {-0.844221,-0.548022},
+  {0.073296,0.266820},
+  {0.606826,-0.308290},
+  {-0.142944,0.057349},
+  {0.072881,0.302992},
+  {-0.294356,-1.221644},
+  {0.671911,0.295323},
+  {-0.409702,-0.847209},
+  {0.266690,-0.020814},
+  {1.417976,0.528433},
+  {0.294250,-1.224903},
+  {-0.438673,-0.509542},
+  {0.044148,0.398124},
+  {-0.812297,-0.912451},
+  {-0.879513,-0.624383},
+  {0.758342,0.704452},
+  {0.563399,-1.164427},
+  {0.809358,-0.309169},
+  {-0.076009,-1.386514},
+  {-0.580469,0.458582},
+  {0.513892,0.214365},
+  {-0.640728,-0.171872},
+  {-0.521270,-0.133816},
+  {-0.843834,0.906054},
+  {-1.123661,0.041336},
+  {0.082797,0.087755},
+  {0.904721,1.160552},
+  {-0.238756,0.127971},
+  {-1.306804,0.307469},
+  {-0.097808,0.500074},
+  {-0.007891,-0.206617},
+  {-1.058789,-1.223922},
+  {-0.086817,1.141660},
+  {-0.672100,0.422630},
+  {1.107477,0.445402},
+  {-1.048691,0.148970},
+  {0.860657,-0.307406},
+  {-0.075900,-0.772589},
+  {0.085372,-0.654328},
+  {-0.402544,0.348887},
+  {0.836413,-0.212447},
+  {0.969845,-0.432787},
+  {1.678800,-0.719544},
+  {0.122685,0.736764},
+  {-0.610210,-0.231955},
+  {-0.602630,0.861072},
+  {1.689118,-0.524512},
+  {-0.570388,-0.710299},
+  {0.359182,-0.302528},
+  {-0.584968,0.029896},
+  {0.376150,-0.101358},
+  {0.190034,-0.895052},
+  {-0.083246,0.352043},
+  {0.488237,-0.109218},
+  {0.864959,-0.134808},
+  {-0.489859,0.046721},
+  {-0.285949,-0.556426},
+  {-0.090628,-0.144285},
+  {-0.407313,0.094491},
+  {-0.754715,0.269388},
+  {-0.110048,0.336987},
+  {-1.504402,0.827809},
+  {-1.144984,0.736338},
+  {-0.615585,-0.119038},
+  {-1.320089,0.799899},
+  {0.146051,-1.613330},
+  {-0.203844,1.002752},
+  {1.005593,-1.051012},
+  {0.590068,0.881226},
+  {1.034314,0.478533},
+  {-0.807146,0.527922},
+  {-1.431626,1.052176},
+  {0.254060,-0.588784},
+  {-0.552606,0.801991},
+  {0.571316,-0.099644},
+  {1.906518,0.779457},
+  {0.661004,0.688072},
+  {-0.848444,-0.767891},
+  {-0.446525,1.557097},
+  {0.342626,0.070643},
+  {1.499481,-0.562495},
+  {0.474748,-0.065518},
+  {-1.305470,0.236428},
+  {-0.996922,0.424136},
+  {0.109899,0.116446},
+  {-1.376289,-1.178174},
+  {1.094583,0.176159},
+  {-0.660629,0.735661},
+  {0.324773,-0.650471},
+  {-0.050363,0.168514},
+  {1.411432,0.431589},
+  {-0.841104,1.189949},
+  {-0.090368,0.422103},
+  {-0.138836,-0.227462},
+  {0.251194,0.456981},
+  {-0.456550,-1.052269},
+  {-0.585470,-0.733649},
+  {0.718189,0.069608},
+  {-0.215514,0.144581},
+  {-0.295208,-0.293870},
+  {0.064279,1.659733},
+  {-0.639890,0.107245},
+  {0.671313,-0.308464},
+  {0.171154,0.201673},
+  {0.530860,-0.395579},
+  {0.405182,0.111475},
+  {-1.105560,0.477897},
+  {-0.469701,-0.814646},
+  {-0.310904,-0.140531},
+  {0.906292,0.445761},
+  {0.641656,-0.711619},
+  {1.811121,-0.499532},
+  {0.544038,0.258314},
+  {0.240229,0.023662},
+  {-0.161251,-0.927410},
+  {0.526134,0.501783},
+  {-0.633589,-0.525689},
+  {-0.969783,1.421790},
+  {0.164651,-1.234975},
+  {-0.945772,0.158957},
+  {0.120218,-0.221355},
+  {0.234672,-0.016298},
+  {-0.397618,-0.661839},
+  {1.072883,-0.141947},
+  {-1.348040,0.586734},
+  {-0.872801,0.434857},
+  {-1.430760,0.165192},
+  {-0.636803,0.781150},
+  {-0.071279,0.396819},
+  {-0.298115,0.418331},
+  {0.831866,-0.535220},
+  {0.958718,0.633147},
+  {1.412960,-0.748229},
+  {-0.178002,-0.206609},
+  {-0.024151,0.915775},
+  {1.393923,0.405981},
+  {-0.206648,1.302225},
+  {0.259960,0.096155},
+  {0.842216,0.222933},
+  {-0.375179,0.699708},
+  {-1.103264,-0.776247},
+  {0.193353,-1.171155},
+  {0.205492,0.076179},
+  {-0.072841,-1.186499},
+  {-0.401707,1.760304},
+  {-0.205922,0.764063},
+  {0.028046,0.211591},
+  {0.009746,0.166249},
+  {-0.523126,0.458907},
+  {0.775557,-0.863099},
+  {0.597490,0.287191},
+  {1.398946,-0.443293},
+  {-0.610123,-1.801501},
+  {-0.659803,0.440813},
+  {-0.254009,0.206463},
+  {0.023678,-1.708605},
+  {1.336293,-1.666408},
+  {-0.624224,-0.008318},
+  {-0.391454,-0.672562},
+  {0.005607,0.074204},
+  {-0.563962,0.743411},
+  {-0.451022,-0.173040},
+  {-0.382636,0.398129},
+  {-0.036862,-0.079446},
+  {-0.008467,-2.296086},
+  {0.023278,1.499503},
+  {-0.064032,-0.525729},
+  {1.457191,-0.108098},
+  {0.321643,0.192680},
+  {0.121531,0.798915},
+  {0.925207,0.317706},
+  {1.826658,0.097183},
+  {-1.022560,0.131480},
+  {-0.318490,1.086323},
+  {-1.671511,-0.990183},
+  {-0.087723,1.093251},
+  {-0.866849,0.094690},
+  {0.559302,-0.868112},
+  {-0.607928,-1.491484},
+  {-0.369056,0.883585},
+  {-0.373229,-0.023122},
+  {-0.971052,0.792590},
+  {0.851785,-0.009613},
+  {-0.460853,0.096153},
+  {-0.755498,0.166030},
+  {-0.598639,-0.848533},
+  {0.291127,-0.247983},
+  {-0.829961,-1.371573},
+  {-0.887194,-0.038222},
+  {1.016759,0.265340},
+  {-1.203644,-0.226689},
+  {1.077377,0.055066},
+  {-0.711420,-0.799640},
+  {-0.952350,1.757540},
+  {-0.699760,-0.395833},
+  {0.196095,-0.452552},
+  {0.858758,0.082961},
+  {-0.102536,-0.000287},
+  {0.343266,-0.165811},
+  {-0.728940,0.271092},
+  {-0.365214,0.684535},
+  {0.216959,0.140539},
+  {1.180350,-0.419423},
+  {1.324288,-0.085228},
+  {0.147214,-0.477679},
+  {-0.340726,-0.495787},
+  {-1.273332,-1.550655},
+  {0.922246,-0.111028},
+  {0.801098,0.605313},
+  {0.636192,1.656684},
+  {-0.459339,0.881863},
+  {1.781037,0.234321},
+  {0.109470,0.133394},
+  {-0.004980,-0.810822},
+  {0.908525,-0.163045},
+  {-0.974477,0.323659},
+  {-0.048603,-0.036304},
+  {0.325440,-0.342764},
+  {-0.337570,-1.092254},
+  {0.903449,-0.284129},
+  {-0.513390,0.181617},
+  {-0.906126,0.669673},
+  {-0.047735,-0.670418},
+  {0.017003,0.589952},
+  {0.028141,0.768896},
+  {-0.578796,0.026764},
+  {0.153556,-1.036369},
+  {1.736299,0.027607},
+  {0.207225,-0.621084},
+  {0.705813,0.683555},
+  {0.613738,-0.279927},
+  {0.893509,-0.452908},
+  {0.636020,-0.005940},
+  {-0.658270,-0.311733},
+  {-0.134504,0.070080},
+  {1.042131,0.291936},
+  {-1.287365,0.847615},
+  {-0.003671,0.744938},
+  {1.467651,0.342594},
+  {0.428411,0.563561},
+  {-0.684351,0.323237},
+  {-1.151725,-1.138706},
+  {-0.979643,-0.060294},
+  {-0.950965,1.226894},
+  {0.275188,1.399455},
+  {1.059926,-0.504133},
+  {1.403033,-0.687512},
+  {0.451808,-0.267527},
+  {0.287162,0.469132},
+  {0.667303,-0.852516},
+  {-0.817966,0.656727},
+  {-0.610009,-1.209200},
+  {-0.303650,-0.565971},
+  {0.794594,-0.236306},
+  {0.431590,-0.908313},
+  {-0.486556,-0.148481},
+  {0.047972,-0.563498},
+  {0.402585,-0.280605},
+  {-0.378654,1.233252},
+  {0.353901,-0.875133},
+  {0.422729,0.132703},
+  {0.856809,1.362334},
+  {-0.307263,-1.011948},
+  {-0.301736,0.329660},
+  {-1.085452,0.606158},
+  {0.652982,-0.949242},
+  {0.162631,-0.537617},
+  {-0.965026,-0.836121},
+  {-0.224588,-0.548422},
+  {-0.437774,-0.279190},
+  {0.115997,1.282330},
+  {-0.897054,-0.047287},
+  {-0.798308,0.372153},
+  {0.665938,-0.055502},
+  {-0.287413,-0.908496},
+  {0.678644,1.314557},
+  {-1.449310,1.522950},
+  {0.133398,-0.047658},
+  {1.224299,-0.149895},
+  {0.441690,-0.259865},
+  {0.126046,0.235240},
+  {-0.966749,-0.417786},
+  {-0.246070,0.437277},
+  {-0.513593,0.459173},
+  {1.263919,0.212954},
+  {-0.627105,0.099150},
+  {-0.594187,1.118584},
+  {0.080869,0.148184},
+  {0.706184,0.093108},
+  {-0.250103,0.904912},
+  {-0.085195,0.370800},
+  {-0.081942,1.186957},
+  {-0.296313,0.398278},
+  {0.107458,-0.270042},
+  {-1.468816,0.286041},
+  {-0.248786,-0.194616},
+  {-0.839973,0.355437},
+  {-0.683425,-0.178796},
+  {-0.338075,-0.537129},
+  {-0.036752,-0.461836},
+  {-1.024372,-0.805341},
+  {0.013059,0.294161},
+  {0.921884,0.535430},
+  {-1.007252,1.557665},
+  {0.542827,-0.917693},
+  {0.309396,0.368338},
+  {1.457432,-0.177952},
+  {0.233876,-1.087922},
+  {-0.287049,-0.480668},
+  {-2.620387,0.600910},
+  {1.326669,-0.917157},
+  {0.401335,0.923110},
+  {0.162796,1.157234},
+  {0.041788,-0.014345},
+  {0.072941,-0.425285},
+  {-0.560475,0.764890},
+  {0.016479,0.416079},
+  {0.097405,0.248996},
+  {0.019340,-0.636057},
+  {-0.744067,0.747826},
+  {0.245503,0.206129},
+  {-0.143130,-0.092267},
+  {-0.030139,-0.746082},
+  {-0.340620,-0.172249},
+  {0.574330,0.097636},
+  {0.705237,1.038887},
+  {0.036829,-1.428994},
+  {-0.385480,1.221082},
+  {0.367570,-0.573062},
+  {0.850865,-0.205763},
+  {-1.330905,0.354961},
+  {-1.307074,-0.343509},
+  {-0.957751,-0.442580},
+  {-0.409731,0.243503},
+  {0.567889,-0.604233},
+  {0.388103,0.085991},
+  {0.040627,-0.011142},
+  {0.077060,2.004945},
+  {-0.833086,-0.049453},
+  {-0.843774,-0.478384},
+  {0.372355,-0.792844},
+  {-0.234287,0.672964},
+  {0.107062,-0.502565},
+  {-1.135028,0.280502},
+  {0.638347,0.034212},
+  {-0.199093,-0.238458},
+  {0.782282,1.017529},
+  {1.389149,0.234737},
+  {-0.823454,-0.341639},
+  {0.651162,0.121302},
+  {0.653624,0.783446},
+  {0.352699,-0.207281},
+  {1.238071,-0.754767},
+  {-0.238806,0.128663},
+  {0.262681,0.361327},
+  {0.509025,-0.603024},
+  {0.981913,-0.189391},
+  {-0.706196,-0.289371},
+  {1.145942,0.153677},
+  {-0.907823,-1.129337},
+  {0.188763,0.623059},
+  {-0.207448,0.309242},
+  {-1.436932,-0.449519},
+  {0.263175,0.540244},
+  {-0.483092,-0.058570},
+  {0.397371,0.753641},
+  {0.644110,0.798701},
+  {-0.237872,-0.334731},
+  {0.600366,-0.897091},
+  {0.710538,-0.133366},
+  {-1.516116,0.488503},
+  {-0.939188,0.418730},
+  {-0.827630,-1.305309},
+  {0.991499,-0.948166},
+  {-0.499176,-0.031343},
+  {0.451127,0.527453},
+  {-0.546957,-0.430328},
+  {0.946791,-0.178838},
+  {1.094307,-0.154938},
+  {0.609540,-0.054620},
+  {0.425711,0.862792},
+  {1.052342,-0.544269},
+  {0.017746,0.359976},
+  {0.075115,-0.401081},
+  {0.374648,1.155752},
+  {-0.461745,0.439978},
+  {0.047619,-0.886710},
+  {-0.099683,0.583548},
+  {-0.334765,0.050996},
+  {-0.478206,-1.264766},
+  {0.516489,0.865504},
+  {0.320340,-0.267298},
+  {-1.324292,0.440493},
+  {-0.710460,-0.206828},
+  {-0.884704,0.660258},
+  {-0.262272,0.394818},
+  {-1.601370,0.444466},
+  {-0.040487,1.753595},
+  {0.449335,0.513686},
+  {-0.558298,0.133991},
+  {-1.303113,-0.149324},
+  {-0.640885,0.046974},
+  {-0.069325,-1.365680},
+  {0.608970,0.076633},
+  {-0.606595,1.106964},
+  {-1.357901,-0.599083},
+  {0.171158,-0.825277},
+  {-0.169345,1.197084},
+  {0.952399,-0.276599},
+  {-1.216459,-1.814032},
+  {0.336292,-0.361441},
+  {-0.391223,0.027209},
+  {-0.888571,1.002162},
+  {0.433612,0.093511},
+  {-0.367321,1.307070},
+  {0.857512,-0.309022},
+  {0.552752,-0.380307},
+  {-0.133756,-0.251153},
+  {-0.076031,0.670133},
+  {0.150394,0.146506},
+  {-0.499016,0.809971},
+  {-0.790913,0.740662},
+  {-1.123231,-1.005292},
+  {0.580124,0.208377},
+  {-0.466913,0.115610},
+  {1.579526,0.786724},
+  {0.463652,0.545059},
+  {0.363065,-0.468610},
+  {0.052198,0.530309},
+  {-0.533674,1.126832},
+  {0.055098,1.460855},
+  {0.446183,-0.620585},
+  {0.061081,-0.558367},
+  {0.602677,1.026030},
+  {-0.214633,0.288994},
+  {-0.885402,-0.515751},
+  {0.666543,0.166763},
+  {-0.582033,-0.122415},
+  {0.363257,-0.093152},
+  {0.197198,0.114842},
+  {0.406922,1.065118},
+  {-0.242795,0.181694},
+  {1.181767,0.889092},
+  {0.397062,-0.428570},
+  {-1.448884,-0.474985},
+  {-0.309184,-0.467696},
+  {0.137783,2.027669},
+  {0.474842,-0.884960},
+  {-1.661712,0.148843},
+  {-0.069285,-0.320696},
+  {-0.170034,1.251510},
+  {-0.222496,-0.937833},
+  {-0.311250,-0.485117},
+  {-0.383917,-0.251372},
+  {-0.320437,-0.642387},
+  {0.206323,-0.019793},
+  {-0.278823,-0.242762},
+  {0.680746,-0.243103},
+  {-0.567863,-0.748655},
+  {-0.323796,-0.790379},
+  {0.524243,-1.175681},
+  {-0.397445,-0.523772},
+  {-0.474692,-0.477136},
+  {0.189023,0.966859},
+  {0.386555,0.481977},
+  {-0.140878,-0.911496},
+  {0.406182,-0.015365},
+  {0.102477,-0.746348},
+  {0.090930,-0.614517},
+  {-0.086082,-0.376112},
+  {0.370291,1.207642},
+  {1.139898,0.217497},
+  {-0.610672,0.245983},
+  {-0.174618,0.833632},
+  {-0.831968,0.195580},
+  {-0.757329,-0.178189},
+  {-0.452875,0.648865},
+  {-0.050510,-0.011244},
+  {0.607291,0.053154},
+  {-0.511124,0.651127},
+  {1.482337,-0.900918},
+  {-0.703173,0.311134},
+  {-0.814727,0.000269},
+  {-0.500544,-0.108025},
+  {-0.986775,-1.061037},
+  {0.121914,-0.452219},
+  {-0.442473,1.026816},
+  {0.763792,1.515099},
+  {0.623316,0.417977},
+  {-0.212855,0.306216},
+  {-0.561318,-0.795493},
+  {0.576698,0.693102},
+  {0.061154,1.127743},
+  {-0.887248,-0.434093},
+  {0.400682,-0.310835},
+  {0.432078,0.437754},
+  {-1.820646,-0.665382},
+  {-0.545136,-0.481289},
+  {0.400912,0.700684},
+  {0.137771,0.590814},
+  {0.811931,1.048663},
+  {-0.815412,-0.744414},
+  {-0.182987,0.208578},
+  {-0.481622,-0.883622},
+  {-1.174057,0.017304},
+  {0.762922,0.651641},
+  {-0.225956,0.405115},
+  {0.170487,0.754648},
+  {-0.324751,-0.699111},
+  {0.508982,0.579276},
+  {-0.217381,0.280138},
+  {-0.164204,0.071186},
+  {1.046480,-0.151789},
+  {-0.407525,0.236215},
+  {0.043528,0.503335},
+  {-0.422499,0.544007},
+  {0.737522,-1.360706},
+  {1.348720,0.519788},
+  {-0.879691,0.405074},
+  {-0.357675,0.687248},
+  {-0.860730,-0.689677},
+  {-1.748928,-1.078704},
+  {-0.195426,-1.049862},
+  {-0.035495,-0.350232},
+  {1.033713,-0.030587},
+  {0.800092,-0.110899},
+  {-0.305951,0.274492},
+  {-0.832381,-0.825501},
+  {1.297737,0.530891},
+  {-0.024356,0.967573},
+  {-0.449962,1.296328},
+  {0.341683,-0.869522},
+  {-1.470761,0.197663},
+  {-0.936318,-1.271953},
+  {0.048144,-0.615236},
+  {0.378908,0.844420},
+  {0.461083,-0.366872},
+  {0.047960,0.407828},
+  {-0.840079,-1.095449},
+  {-0.027915,1.084483},
+  {0.674601,0.522046},
+  {1.931610,0.765981},
+  {-0.125784,-0.336877},
+  {0.019115,-1.481554},
+  {0.820840,-0.447176},
+  {0.707047,0.929830},
+  {0.958282,-0.396113},
+  {-0.580240,0.094636},
+  {-0.174754,-1.196160},
+  {-0.860568,-0.091731},
+  {0.523920,-0.030573},
+  {0.274479,-0.049813},
+  {0.153459,0.249274},
+  {0.533358,0.444977},
+  {-1.241255,0.245974},
+  {-1.012174,-0.027701},
+  {-0.395522,-0.193917},
+  {-0.972526,0.180350},
+  {0.430804,-0.833766},
+  {-1.011518,0.292716},
+  {0.207684,-0.205800},
+  {0.044858,0.152791},
+  {0.448157,-0.030646},
+  {-0.499634,-0.262260},
+  {-0.143806,-1.010803},
+  {0.886031,-0.336787},
+  {-0.362530,-1.768263},
+  {-0.242831,-0.154468},
+  {0.734717,0.111474},
+  {0.072613,0.508828},
+  {-1.899793,0.301018},
+  {0.090072,0.247977},
+  {1.285664,0.732956},
+  {-0.135188,0.142834},
+  {1.273538,-0.920904},
+  {0.221604,0.753942},
+  {0.117900,1.060812},
+  {-0.232774,-0.083558},
+  {-0.425926,0.686408},
+  {-0.340529,-0.169042},
+  {-1.070367,-0.239810},
+  {0.173529,-0.065984},
+  {-0.933640,0.004310},
+  {-0.566267,1.379593},
+  {0.734686,-0.766672},
+  {-0.413294,0.709294},
+  {0.595004,-1.135705},
+  {0.718267,-0.281773},
+  {0.106468,-0.863281},
+  {-1.145502,0.206171},
+  {0.887536,-0.242405},
+  {-0.075956,0.156573},
+  {-0.567216,-0.288216},
+  {0.664645,-0.362856},
+  {0.547459,-1.799647},
+  {-0.241719,0.821927},
+  {-0.034155,0.250263},
+  {-0.046388,-0.235086},
+  {0.419359,0.310763},
+  {-0.215888,-1.367215},
+  {0.034387,1.044299},
+  {-0.358005,0.645426},
+  {0.326152,0.748784},
+  {0.202163,-1.123275},
+  {0.690767,-0.848466},
+  {-0.125006,-0.255902},
+  {0.162892,-0.345699},
+  {-0.955042,0.294080},
+  {0.083320,1.880625},
+  {-1.198282,0.804137},
+  {0.587054,-0.958859},
+  {-1.601116,-0.725511},
+  {1.139292,-0.045379},
+  {0.203917,0.685789},
+  {-0.493037,0.458789},
+  {-0.031010,-0.106568},
+  {-0.429805,1.119367},
+  {-0.528015,0.735593},
+  {-0.134197,-1.255463},
+  {-0.448291,-0.262008},
+  {-0.050223,0.690944},
+  {-0.326287,0.961302},
+  {0.124462,-0.571389},
+  {-1.086006,0.724509},
+  {0.209547,1.056945},
+  {-1.293691,0.471514},
+  {-0.003896,0.567797},
+  {0.183588,-0.440099},
+  {0.728438,-0.316034},
+  {0.626752,-0.654537},
+  {-0.323843,-0.581490},
+  {-0.584120,1.235448},
+  {-0.724753,-0.357822},
+  {0.651802,-0.255045},
+  {1.066699,0.145706},
+  {-0.327084,-0.703887},
+  {0.726433,0.902326},
+  {0.615929,-0.468777},
+  {0.215638,0.025393},
+  {0.133688,0.312972},
+  {1.480107,0.472599},
+  {-0.422097,-0.160696},
+  {-0.044013,-0.556906},
+  {0.614888,-0.377907},
+  {-0.064303,-0.363883},
+  {0.417722,0.242693},
+  {-0.610622,-0.349784},
+  {0.274353,1.229638},
+  {1.376876,-0.661918},
+  {0.065799,0.192942},
+  {-0.985618,1.632529},
+  {0.007131,-0.681075},
+  {0.034166,-0.337426},
+  {-0.725304,-0.279474},
+  {-0.730621,-0.266983},
+  {-0.843057,0.478930},
+  {0.474710,-0.454256},
+  {-0.507851,-1.321088},
+  {-0.017476,-0.794130},
+  {-1.038323,0.066833},
+  {0.385382,1.225797},
+  {0.021934,-0.410591},
+  {-1.010484,-0.669754},
+  {0.429793,1.532827},
+  {0.636827,-0.288977},
+  {-0.534265,-0.646029},
+  {-0.844287,-0.564450},
+  {-0.396490,0.315667},
+  {-1.273186,0.218433},
+  {0.417662,-0.018864},
+  {0.462506,-1.253567},
+  {-0.182622,-0.273477},
+  {-1.579637,0.949574},
+  {0.433213,-0.037784},
+  {-0.846671,0.082560},
+  {0.662308,0.650516},
+  {0.045595,-0.496667},
+  {0.119091,0.014749},
+  {0.608458,0.837623},
+  {-0.687084,-0.195381},
+  {-0.018589,0.789815},
+  {-0.298420,0.261702},
+  {-0.040271,-0.194730},
+  {0.620631,0.613639},
+  {-0.937617,-1.049478},
+  {-1.053561,-0.076996},
+  {-0.146382,1.050599},
+  {-0.020837,0.355688},
+  {0.201458,0.287587},
+  {2.218790,0.476933},
+  {-0.104763,0.355760},
+  {-0.479467,1.109721},
+  {-0.893756,-0.550251},
+  {0.956522,-0.432295},
+  {-0.194464,0.764093},
+  {-0.704136,0.235401},
+  {-0.654628,-0.706623},
+  {-0.493649,-1.139754},
+  {1.131061,-0.875211},
+  {0.422646,0.452794},
+  {1.210811,0.230644},
+  {0.529746,1.430776},
+  {0.460853,-0.100968},
+  {0.145607,0.417836},
+  {-0.183425,0.671501},
+  {0.712047,0.585763},
+  {0.667523,0.427398},
+  {0.083714,0.241186},
+  {0.603047,-0.437378},
+  {0.671836,-0.108031},
+  {0.147556,1.611462},
+  {-0.474514,0.338308},
+  {0.669331,-0.582147},
+  {-0.518075,-1.063090},
+  {-0.404972,1.037375},
+  {0.392642,0.132706},
+  {0.091281,-0.677244},
+  {-0.101493,0.595298},
+  {-0.273278,-0.149243},
+  {-0.056904,0.119955},
+  {-1.155884,-1.080464},
+  {-0.068053,-0.148710},
+  {0.578176,0.409176},
+  {0.840193,0.143279},
+  {-0.240609,-0.502595},
+  {-1.242000,-0.441204},
+  {1.109439,0.606569},
+  {0.055563,-0.064248},
+  {-0.149710,0.672466},
+  {0.726856,-0.310854},
+  {-0.653160,-0.652705},
+  {0.278598,0.458304},
+  {1.079266,0.059011},
+  {-1.419938,0.322182},
+  {0.945599,0.108086},
+  {-0.751556,0.294139},
+  {0.427620,0.212390},
+  {-0.069527,0.242822},
+  {0.278856,-0.156601},
+  {-0.065200,0.118212},
+  {-0.195535,-0.019769},
+  {-0.420603,-0.282551},
+  {-0.907453,0.158124},
+  {0.113203,-0.260452},
+  {0.108842,-0.457941},
+  {0.325193,0.172876},
+  {0.291742,-1.615476},
+  {1.111341,0.223062},
+  {0.355686,0.290422},
+  {0.634955,-0.443257},
+  {-0.288282,-0.326955},
+  {0.392507,-0.445702},
+  {-0.079780,-0.200318},
+  {0.358629,0.085606},
+  {-1.037372,0.489174},
+  {-0.650397,-0.686827},
+  {1.025516,-1.009867},
+  {0.704492,-0.014842},
+  {-1.937672,0.038744},
+  {1.043168,-0.182518},
+  {0.767195,1.172210},
+  {-0.973759,0.495782},
+  {0.727765,-0.454134},
+  {-0.463311,0.027464},
+  {0.461195,0.676168},
+  {0.563002,-0.443334},
+  {0.837410,1.297797},
+  {0.530937,0.527558},
+  {-0.207558,1.073655},
+  {0.017685,-0.129331},
+  {-0.434984,-0.756967},
+  {1.186167,0.330663},
+  {-0.494215,-0.229928},
+  {-1.967930,0.423566},
+  {0.085717,0.490676},
+  {0.579028,0.081474},
+  {-1.165809,1.066751},
+  {0.155616,-0.207882},
+  {0.824000,0.024005},
+  {-0.650314,-0.289259},
+  {0.289677,0.562463},
+  {0.084380,-0.741257},
+  {-0.185975,-1.002760},
+  {-0.258544,-1.231110},
+  {-0.680721,-0.132215},
+  {-0.126178,-0.346100},
+  {0.059501,-0.556818},
+  {0.257426,0.740194},
+  {0.209590,0.920746},
+  {0.278486,0.751635},
+  {-0.266518,-0.406470},
+  {0.747083,0.368274},
+  {0.361351,1.035953},
+  {0.730710,0.834248},
+  {-0.629610,-0.456521},
+  {-1.063318,0.238140},
+  {-0.239986,0.455673},
+  {0.045907,1.094522},
+  {-0.098907,-1.444712},
+  {0.346836,-0.959861},
+  {-0.120778,-0.989386},
+  {0.411690,0.088654},
+  {-0.269997,0.408287},
+  {0.840135,-0.066117},
+  {-0.488370,1.718434},
+  {0.875784,1.132982},
+  {-0.423667,-0.074866},
+  {0.406809,-1.179861},
+  {0.214059,-0.303153},
+  {-0.302193,1.101238},
+  {0.868983,-0.955911},
+  {-0.507030,-0.093825},
+  {0.906214,0.198565},
+  {-1.340024,0.138617},
+  {-0.383054,-0.069114},
+  {-0.486159,-0.087876},
+  {-0.469249,0.620882},
+  {-0.278926,0.596592},
+  {-1.669627,0.194691},
+  {0.742352,-0.614247},
+  {0.718457,-1.097553},
+  {-1.226771,0.059541},
+  {-0.753392,-1.289320},
+  {-0.209317,-0.130344},
+  {0.481910,0.355924},
+  {-0.316461,0.620936},
+  {-1.244952,-0.290661},
+  {0.215579,-0.017983},
+  {-0.469612,-0.348379},
+  {-1.275008,0.509724},
+  {-0.522839,0.762522},
+  {1.326882,0.479414},
+  {0.226020,-0.210263},
+  {-1.179333,-0.508178},
+  {-0.818269,-0.304733},
+  {-0.173224,-0.439298},
+  {-0.536131,0.998854},
+  {0.607704,0.360449},
+  {0.006800,1.240915},
+  {-0.835128,-0.346159},
+  {0.147648,0.135792},
+  {-0.724952,-0.728993},
+  {0.387685,-0.535468},
+  {0.119265,0.577041},
+  {0.496673,-0.247011},
+  {-0.506871,0.140888},
+  {-0.556531,-0.131979},
+  {-0.286395,0.267888},
+  {-1.535815,0.901937},
+  {-0.025959,-0.061265},
+  {0.571857,0.076721},
+  {0.378659,-1.266500},
+  {0.474031,-1.498596},
+  {-0.010007,0.157154},
+  {1.036847,0.749449},
+  {1.036444,0.841654},
+  {0.548594,-0.632059},
+  {0.368966,-1.003432},
+  {0.570837,-0.124028},
+  {0.341200,0.495283},
+  {1.122887,0.046649},
+  {0.748775,-0.646888},
+  {0.114935,0.407391},
+  {0.016391,-1.068782},
+  {0.276187,0.082486},
+  {0.328695,-0.203988},
+  {-0.955191,-0.006992},
+  {-0.954723,0.976115},
+  {0.130024,0.006814},
+  {1.178728,-1.134652},
+  {-0.280919,1.145315},
+  {-0.074035,-0.138700},
+  {-0.885872,-0.173488},
+  {-0.052446,0.391385},
+  {0.061407,-0.036012},
+  {-0.178374,0.207062},
+  {1.539364,-0.706954},
+  {0.683015,-0.203145},
+  {0.214058,-0.228743},
+  {0.816114,-0.336901},
+  {1.083669,0.601556},
+  {0.243885,0.366600},
+  {-0.376040,0.342849},
+  {0.049959,-0.020917},
+  {-0.249481,1.559691},
+  {0.260203,0.448585},
+  {0.400041,0.204926},
+  {0.103935,-0.828622},
+  {-1.743587,-0.564881},
+  {1.227175,-0.006252},
+  {0.517290,0.681785},
+  {0.041937,-1.277299},
+  {0.884991,1.022953},
+  {-0.395354,0.177096},
+  {0.659057,-0.417478},
+  {-1.433312,-1.086898},
+  {-0.307188,0.459477},
+  {1.083389,-0.395616},
+  {0.931207,-0.529729},
+  {-0.691098,-0.682569},
+  {-0.107824,-0.121179},
+  {0.162237,0.278125},
+  {-0.187331,-0.078223},
+  {0.539435,-0.468066},
+  {-0.037026,-0.169309},
+  {-0.032828,0.774350},
+  {1.004977,0.207932},
+  {-1.375620,-0.465708},
+  {-0.853797,-0.492372},
+  {0.857050,-0.067048},
+  {-1.358066,-0.056983},
+  {0.205638,0.517628},
+  {0.134978,-1.457460},
+  {-0.628057,-0.198079},
+  {1.020819,0.168767},
+  {-0.660697,0.430602},
+  {-1.207856,0.350159},
+  {0.211552,0.334102},
+  {1.569613,0.644036},
+  {0.625801,-0.806877},
+  {0.753956,-0.280829},
+  {0.800271,0.796731},
+  {-0.157847,0.366712},
+  {-0.520191,-0.177564},
+  {-1.880639,0.111041},
+  {0.565178,-0.025211},
+  {0.867760,0.267054},
+  {-1.699681,0.127302},
+  {0.925459,0.105993},
+  {-0.381951,-0.290209},
+  {-0.008579,-0.672418},
+  {-0.226066,0.111930},
+  {-0.511046,-0.180645},
+  {-0.150570,-0.920002},
+  {0.456257,1.157604},
+  {0.285512,-0.521834},
+  {0.197973,0.250159},
+  {-0.574980,-1.048345},
+  {0.065042,0.539600},
+  {-0.080347,0.440878},
+  {0.334152,1.807252},
+  {0.870739,-0.406652},
+  {0.176466,0.116783},
+  {-0.373632,-0.833253},
+  {-0.411070,-0.622612},
+  {0.490742,0.472114},
+  {-0.144185,0.440259},
+  {-0.911075,1.395547},
+  {-0.963359,0.070059},
+  {0.472861,0.954686},
+  {0.144494,0.457410},
+  {0.724328,0.010123},
+  {1.405964,0.660263},
+  {0.629468,-1.148403},
+  {-0.365955,0.044107},
+  {1.302156,-0.349987},
+  {0.559796,0.286848},
+  {-1.408563,1.083378},
+  {0.176937,0.040345},
+  {-0.339737,-1.036991},
+  {-0.000428,0.120110},
+  {0.174082,-0.440745},
+  {-0.812662,0.308663},
+  {-0.344535,0.731337},
+  {-0.687735,-0.481504},
+  {-0.167853,0.616992},
+  {-0.032443,-0.661320},
+  {-0.744886,-0.239760},
+  {0.372373,0.085475},
+  {-1.440036,0.895442},
+  {-0.277006,-0.398549},
+  {-0.370569,-0.322067},
+  {0.103481,-0.007568},
+  {-0.106426,0.323058},
+  {-0.483987,-0.268954},
+  {0.292168,0.040605},
+  {0.074066,0.134120},
+  {0.153317,-1.287651},
+  {-1.203918,-0.967637},
+  {-0.317271,0.386501},
+  {0.954049,-0.099558},
+  {0.462192,-0.061542},
+  {-0.062967,0.369906},
+  {-0.884488,0.712304},
+  {0.186711,-0.348097},
+  {-0.352553,-1.659383},
+  {-0.486478,-1.015527},
+  {0.251005,0.060654},
+  {-0.383225,0.840563},
+  {-0.808342,-0.888829},
+  {-0.227572,0.129202},
+  {-0.314270,-0.775019},
+  {-1.545768,-0.570873},
+  {0.545677,0.182432},
+  {0.081540,-0.429030},
+  {-0.106779,-0.216418},
+  {0.450044,0.045841},
+  {0.905832,-0.902027},
+  {0.457874,-0.063177},
+  {0.116610,-0.016288},
+  {-1.167063,0.372052},
+  {0.982923,-0.259440},
+  {-0.922239,0.212051},
+  {-0.529454,-0.435260},
+  {-0.213398,0.659482},
+  {0.235217,-0.582746},
+  {0.622280,0.032259},
+  {0.593666,0.351868},
+  {-0.873997,-0.448480},
+  {-0.945217,1.031911},
+  {-0.039626,0.351279},
+  {1.166869,-0.022261},
+  {0.104525,0.891744},
+  {-0.833076,0.326978},
+  {1.038616,0.221851},
+  {0.210548,0.797819},
+  {-0.610088,-0.922245},
+  {-0.343548,-0.954441},
+  {0.159815,-0.755620},
+  {-1.254248,0.310110},
+  {0.112621,0.338769},
+  {0.509586,-0.114230},
+  {0.458902,-0.012483},
+  {-0.077531,0.845512},
+  {-0.024838,-0.325136},
+  {0.099325,-0.797450},
+  {-0.149184,0.461116},
+  {-0.229381,-0.113607},
+  {-0.790994,0.906154},
+  {1.110214,0.040753},
+  {-0.312241,0.102262},
+  {-0.492226,-0.169707},
+  {0.154426,0.445431},
+  {0.915648,0.371803},
+  {-0.997727,-0.598569},
+  {-0.694967,-0.288512},
+  {0.440323,-0.276589},
+  {-0.606794,-1.515034},
+  {-0.336494,0.022852},
+  {0.119489,-0.371741},
+  {-0.695836,0.229833},
+  {-0.161236,-1.197827},
+  {0.902952,0.341914},
+  {-0.478975,-0.883342},
+  {0.010275,0.473193},
+  {-0.257723,0.343809},
+  {-1.647461,-0.658151},
+  {1.203630,0.311324},
+  {-0.520208,-0.077408},
+  {-0.042387,-0.201717},
+  {0.732624,-0.442372},
+  {-0.025341,0.263186},
+  {-0.585464,0.089537},
+  {-1.270729,0.861931},
+  {0.365129,0.609487},
+  {1.133617,-1.306806},
+  {-0.010529,-0.948779},
+  {-1.495597,1.148781},
+  {-0.029070,-0.136818},
+  {0.206800,0.008509},
+  {-0.794964,0.295312},
+  {0.338531,-0.540493},
+  {-0.405923,-0.474873},
+  {0.979782,0.070233},
+  {-1.358570,-3.041284},
+  {-2.044437,-0.337722},
+  {0.467839,-0.830266},
+  {0.885020,0.766034},
+  {0.628159,0.150322},
+  {0.155384,1.033378},
+  {0.499468,-0.472419},
+  {-0.017379,0.135709},
+  {1.044006,0.107473},
+  {0.069893,1.038512},
+  {0.052506,-0.202886},
+  {0.725175,-0.396198},
+  {-1.435707,0.436358},
+  {-0.537693,0.135514},
+  {0.874197,1.596120},
+  {0.692789,-0.072948},
+  {1.514427,0.422330},
+  {0.356388,0.004602},
+  {-0.424132,1.742008},
+  {1.161560,0.621060},
+  {-1.253631,0.873246},
+  {0.830477,-0.113869},
+  {-0.089117,1.005543},
+  {-0.119315,0.415317},
+  {0.530735,-0.551322},
+  {0.468530,-0.096115},
+  {0.465401,0.845196},
+  {-1.226917,1.079224},
+  {-0.340842,-0.903031},
+  {1.019357,-0.845306},
+  {-0.542261,-0.981142},
+  {0.745563,-0.146286},
+  {0.146678,1.522813},
+  {0.489313,0.877646},
+  {0.622197,0.410875},
+  {-0.332401,1.742686},
+  {-0.530628,0.179136},
+  {0.214410,0.379434},
+  {-1.320653,0.366324},
+  {-0.135837,-0.625588},
+  {0.018205,0.579573},
+  {0.113747,0.193869},
+  {0.826568,-0.342809},
+  {0.517217,0.388353},
+  {0.511517,-1.261484},
+  {0.069570,1.590514},
+  {0.524966,1.277127},
+  {-0.604102,0.356745},
+  {-0.289114,1.192349},
+  {-1.224444,0.781320},
+  {0.797974,0.660886},
+  {0.358733,0.016464},
+  {-0.201142,0.232487},
+  {1.024496,-0.588845},
+  {-0.513361,1.122263},
+  {-0.918694,0.121980},
+  {-0.195506,-0.020095},
+  {0.331440,-0.501190},
+  {0.266567,1.455573},
+  {0.740847,0.632486},
+  {-0.395862,0.862711},
+  {-0.542915,-0.406950},
+  {-0.187643,0.516822},
+  {-0.777298,-0.688838},
+  {1.561877,0.175345},
+  {0.042752,0.261983},
+  {-0.477959,0.013431},
+  {-0.378112,-0.612150},
+  {0.517772,-0.504068},
+  {0.534609,-0.171057},
+  {0.581429,-0.511870},
+  {1.573305,0.690322},
+  {0.371148,0.371632},
+  {0.775532,-1.827403},
+  {0.699914,-0.106911},
+  {-0.563281,-0.400668},
+  {0.120288,0.692679},
+  {-0.216988,0.919587},
+  {-0.032172,-0.042166},
+  {0.257666,-0.073362},
+  {-0.829215,0.807044},
+  {0.043528,-0.370050},
+  {0.726681,-0.109935},
+  {0.199629,-0.260646},
+  {-0.064800,0.952449},
+  {-0.366864,0.342468},
+  {-0.213579,0.473732},
+  {0.475745,-0.522349},
+  {-0.578518,0.470114},
+  {0.131571,0.070506},
+  {0.199747,1.295036},
+  {0.163703,0.315885},
+  {0.730185,-0.561563},
+  {0.155160,-0.466836},
+  {0.209743,-0.938351},
+  {-0.332044,0.339460},
+  {-0.334248,-0.438717},
+  {-0.177906,-0.445812},
+  {-0.403888,0.515655},
+  {-0.529417,1.448326},
+  {0.751148,-0.069385},
+  {-0.543366,1.195889},
+  {-0.565148,0.963886},
+  {1.462286,-0.220984},
+  {1.482440,-0.287540},
+  {-0.577094,-0.718976},
+  {-1.677120,-0.951714},
+  {1.349836,0.330001},
+  {0.047546,-0.005764},
+  {-0.087343,-0.860869},
+  {0.969527,-0.058331},
+  {0.640526,-0.460373},
+  {-0.620476,0.177907},
+  {0.646331,0.313684},
+  {-0.865669,-0.430395},
+  {-1.109093,0.284577},
+  {0.623313,1.066345},
+  {-0.942186,0.297467},
+  {0.386541,-0.886178},
+  {-1.337573,0.110937},
+  {0.411021,-0.972933},
+  {-0.731420,-1.565217},
+  {0.115932,0.032862},
+  {0.647009,-0.702312},
+  {0.368068,0.376174},
+  {1.769808,-0.289011},
+  {-0.186158,0.373612},
+  {-1.327035,-0.080788},
+  {-1.039836,-0.777259},
+  {-0.020857,0.135255},
+  {-0.342180,-0.853006},
+  {0.599834,0.159697},
+  {-1.190980,-0.408167},
+  {-0.953700,-0.055447},
+  {0.242964,0.103171},
+  {-0.330887,0.495570},
+  {-0.736320,-0.023509},
+  {0.572782,0.531094},
+  {1.955315,0.650087},
+  {0.489044,-0.003831},
+  {-0.573902,-1.761131},
+  {-0.258057,-0.141214},
+  {0.092342,0.110264},
+  {0.813360,1.816915},
+  {1.221027,-0.215925},
+  {-0.103234,0.313383},
+  {0.078699,-0.198435},
+  {-0.581828,-0.816310},
+  {0.283286,-0.081822},
+  {0.302095,-0.251803},
+  {-0.406478,-0.593376},
+  {-1.326431,0.230793},
+  {-0.180609,0.370457},
+  {0.552601,0.177024},
+  {-1.333465,0.065461},
+  {0.599845,-0.602277},
+  {1.077753,-1.104753},
+  {0.809628,0.038772},
+  {0.024962,-0.314990},
+  {-0.988391,1.568123},
+  {0.338240,0.004098},
+  {-0.412518,0.731701},
+  {-0.313828,0.854789},
+  {1.524806,-1.562020},
+  {-1.169150,0.061988},
+  {-0.463460,-1.121006},
+  {-0.688317,0.548066},
+  {1.066755,-1.657319},
+  {-0.098140,-0.618434},
+  {0.432144,-0.550599},
+  {-0.078023,1.897759},
+  {0.527062,-1.127072},
+  {0.386297,0.274681},
+  {1.092527,-0.621702},
+  {0.544097,-0.200129},
+  {0.619517,0.186827},
+  {-0.894467,0.710752},
+  {-0.516944,-0.474122},
+  {-0.178624,-0.241885},
+  {-1.103791,0.206812},
+  {-0.750328,-0.465599},
+  {-1.049783,-0.059999},
+  {-0.238415,-0.584913},
+  {0.841484,0.498381},
+  {0.772949,-0.257598},
+  {0.631129,-0.010723},
+  {0.638257,-0.000321},
+  {0.484532,-1.725015},
+  {0.429875,0.794608},
+  {0.098118,-0.679536},
+  {0.252370,-1.123608},
+  {0.256356,0.128045},
+  {-1.654829,-0.677293},
+  {0.341717,0.901616},
+  {-1.530022,-0.071391},
+  {1.584247,0.385784},
+  {-0.134925,-0.596211},
+  {-0.306823,-0.640632},
+  {0.680138,1.001415},
+  {0.855363,0.466031},
+  {1.047399,-0.967652},
+  {0.874714,0.771008},
+  {0.023131,0.930381},
+  {-1.094853,-0.870464},
+  {0.718843,-0.226276},
+  {-0.135767,0.433719},
+  {0.058625,-1.398816},
+  {-1.478618,-0.590113},
+  {-1.706239,-0.238334},
+  {-0.278994,1.505897},
+  {-0.649649,0.049328},
+  {0.357204,-0.249715},
+  {-0.178715,0.811732},
+  {1.233743,0.677688},
+  {0.404137,1.022936},
+  {0.656525,0.330724},
+  {0.607732,-1.362354},
+  {-0.127905,-0.419755},
+  {-0.152615,-0.700967},
+  {-0.352367,-0.973191},
+  {-0.720073,-1.323530},
+  {-0.127801,-0.477660},
+  {-0.092400,0.491723},
+  {0.341948,-0.814883},
+  {-0.040942,-0.194408},
+  {-0.510947,0.165069},
+  {-0.386948,0.041816},
+  {-0.391543,0.095043},
+  {0.814066,-0.413210},
+  {0.652218,-0.465334},
+  {-0.144483,0.331067},
+  {0.230318,-0.335014},
+  {-0.085459,-0.090830},
+  {-0.458532,0.005534},
+  {0.602005,0.549709},
+  {-0.656597,-0.039494},
+  {-0.529460,-0.586545},
+  {0.459330,0.016754},
+  {-0.902031,-0.240948},
+  {-0.046894,0.151840},
+  {0.377669,1.389795},
+  {0.397125,0.524265},
+  {-0.388316,0.810665},
+  {1.536130,-0.018437},
+  {-0.324880,0.392937},
+  {-0.402622,1.137794},
+  {0.298408,-0.266189},
+  {0.681114,-0.071383},
+  {-0.272913,-0.092683},
+  {1.575728,0.022775},
+  {0.194788,-0.335136},
+  {0.519039,0.062735},
+  {-0.764728,0.146452},
+  {0.236471,-1.427158},
+  {0.995246,0.767302},
+  {-0.349678,0.736569},
+  {0.118835,0.421198},
+  {-1.078159,0.402561},
+  {-0.764007,-0.533382},
+  {-0.455951,1.354001},
+  {0.541724,0.107812},
+  {0.517193,0.011113},
+  {0.192692,0.927513},
+  {-0.639680,-0.461272},
+  {-0.497412,0.005693},
+  {0.035037,0.968771},
+  {0.427440,-0.147090},
+  {-1.412140,-0.121905},
+  {0.344535,0.038231},
+  {0.256825,0.088627},
+  {-0.859248,-0.787997},
+  {-0.127159,-1.105511},
+  {1.125815,-0.063713},
+  {-1.355366,-0.913897},
+  {0.567869,0.633445},
+  {0.784268,-0.756031},
+  {-0.417336,0.300105},
+  {-1.430904,0.105505},
+  {-0.042593,-0.153161},
+  {0.213039,0.587233},
+  {0.028565,0.513513},
+  {-0.041316,-1.552297},
+  {0.458964,1.495922},
+  {0.559308,-1.214681},
+  {1.049392,0.519859},
+  {0.290751,0.410285},
+  {-0.235969,0.075235},
+  {0.827775,0.234283},
+  {-0.353105,0.368130},
+  {1.152140,0.124431},
+  {-0.676463,-0.451120},
+  {0.431903,0.156522},
+  {-1.146142,0.821383},
+  {-0.231929,0.460321},
+  {0.331103,0.291431},
+  {-0.486103,-1.028895},
+  {0.247142,-0.577083},
+  {0.643317,0.642730},
+  {-0.038357,-0.731389},
+  {-0.529627,-0.518347},
+  {-0.458770,-0.602541},
+  {0.717108,-1.502174},
+  {1.639891,-0.046797},
+  {0.367167,-0.575410},
+  {0.200877,-0.125050},
+  {1.282175,-0.037682},
+  {-0.094635,-0.888363},
+  {0.413420,1.283817},
+  {0.132756,0.300671},
+  {-0.367404,1.005577},
+  {0.511375,-0.097647},
+  {-0.375077,0.423522},
+  {0.382736,0.001469},
+  {0.044349,-1.190297},
+  {-1.190740,0.471491},
+  {0.835772,0.424912},
+  {1.030520,0.464877},
+  {-0.529949,0.824068},
+  {-0.099363,0.508190},
+  {-1.371466,0.242051},
+  {0.916338,-1.128584},
+  {0.785841,-1.448629},
+  {0.407546,0.603846},
+  {0.575293,-0.166221},
+  {0.886545,0.439648},
+  {-0.226133,0.961934},
+  {-0.165523,0.076377},
+  {-0.678735,-0.898540},
+  {-0.053888,1.308609},
+  {0.584848,0.060583},
+  {0.083871,-0.233156},
+  {0.004868,0.283304},
+  {0.552259,0.868118},
+  {0.500338,-0.610468},
+  {-0.043386,-0.346571},
+  {-0.498805,0.288491},
+  {0.438704,-0.106490},
+  {0.415201,-0.503631},
+  {0.032692,0.644929},
+  {0.101192,0.299544},
+  {0.381060,-1.411974},
+  {-0.859828,-0.958490},
+  {-0.680687,0.892740},
+  {0.112933,0.002252},
+  {-0.278048,-0.241376},
+  {-2.217421,-0.418946},
+  {0.671425,0.447137},
+  {1.852803,-0.254499},
+  {-0.777766,0.350337},
+  {0.058883,-0.792590},
+  {1.819335,0.931958},
+  {-0.140655,0.687205},
+  {-0.454620,0.532005},
+  {0.520396,-0.641183},
+  {-0.614732,-0.794939},
+  {-0.555090,0.194826},
+  {-0.867211,-0.430899},
+  {0.114316,0.279198},
+  {0.906085,0.126300},
+  {-1.652861,-0.398311},
+  {0.720231,0.310120},
+  {0.616857,-0.224845},
+  {-0.355100,0.825606},
+  {-0.443765,-0.588850},
+  {0.548479,0.069557},
+  {0.311662,0.550548},
+  {1.211246,-0.191114},
+  {-0.220659,1.110956},
+  {-0.359286,-0.164330},
+  {0.789602,-0.070392},
+  {0.566583,-0.827020},
+  {0.595349,-0.690691},
+  {0.189841,0.431550},
+  {-0.289571,-0.607088},
+  {0.621366,-0.321307},
+  {0.186891,-0.852539},
+  {0.232188,-1.220607},
+  {-0.612862,0.059821},
+  {-0.105208,0.298759},
+  {-0.329366,-1.318732},
+  {0.320709,0.096560},
+  {0.140400,-1.134450},
+  {-1.507197,-1.015648},
+  {0.397460,0.411895},
+  {-0.815200,-0.096281},
+  {0.168722,0.671290},
+  {-0.859969,0.821381},
+  {0.171885,-0.220966},
+  {-0.093656,-1.361741},
+  {-0.527003,0.899775},
+  {0.390672,-1.707368},
+  {0.729568,-0.255314},
+  {0.688398,0.539302},
+  {-0.397821,0.236694},
+  {-0.255357,0.443405},
+  {1.355847,0.620758},
+  {1.705390,0.158142},
+  {1.290421,-0.602823},
+  {-0.732108,-0.318124},
+  {0.541361,0.046519},
+  {-0.502741,-1.050050},
+  {0.252136,-0.639033},
+  {0.878938,0.856368},
+  {-0.690850,1.354681},
+  {0.104990,0.071316},
+  {0.447853,-0.020789},
+  {-0.009859,-0.006837},
+  {-0.719030,0.285837},
+  {-0.045532,1.180974},
+  {-0.413249,-0.120820},
+  {0.590697,0.086396},
+  {-0.312210,0.058620},
+  {0.038969,-0.080060},
+  {0.668350,0.562553},
+  {-0.339013,0.060135},
+  {-0.907438,-0.823162},
+  {-0.119806,-0.877603},
+  {-0.478883,-0.143292},
+  {-0.320699,0.212539},
+  {0.100108,0.485710},
+  {-0.392466,-0.806866},
+  {0.001016,0.076458},
+  {-0.592774,0.343524},
+  {1.462533,-0.066516},
+  {-0.569967,0.315363},
+  {-0.481084,0.337295},
+  {-0.087391,0.658159},
+  {-0.302733,0.653680},
+  {0.413127,0.535186},
+  {-0.582368,0.582489},
+  {1.018942,0.463516},
+  {-0.061175,-0.350878},
+  {-1.630071,-0.232123},
+  {1.208054,0.322525},
+  {0.230705,0.582932},
+  {-0.217847,0.575781},
+  {0.893442,0.630389},
+  {-0.174874,0.390805},
+  {0.956859,0.734961},
+  {0.438679,0.368285},
+  {1.409507,-0.272855},
+  {-0.021050,0.944726},
+  {-0.227605,-1.004858},
+  {0.346623,0.582952},
+  {0.576312,0.318435},
+  {1.094793,-0.629266},
+  {-1.088802,0.041459},
+  {-0.500393,0.442719},
+  {-0.271167,0.374385},
+  {0.241921,0.418248},
+  {-0.627281,-1.002708},
+  {-1.147085,-0.423343},
+  {0.728013,-0.479764},
+  {0.055815,-0.515315},
+  {0.496916,0.348340},
+  {0.640592,-0.044396},
+  {-0.823480,-0.081510},
+  {-0.658153,0.363340},
+  {0.549048,0.679255},
+  {0.379224,0.498001},
+  {0.531963,0.993990},
+  {0.503592,0.389701},
+  {-0.354800,0.131830},
+  {0.447769,-0.726391},
+  {-0.226749,0.070274},
+  {1.525876,0.048507},
+  {0.423583,0.515601},
+  {0.281501,0.333000},
+  {-0.581471,-0.653560},
+  {0.356261,0.210534},
+  {-1.831239,-2.179264},
+  {-0.207313,2.443682},
+  {0.581231,0.219500},
+  {0.244048,-0.433631},
+  {0.234179,-0.519635},
+  {0.321517,-0.667325},
+  {0.331807,0.023669},
+  {0.150836,0.951006},
+  {0.850205,-0.427679},
+  {-0.266342,0.492303},
+  {0.421612,-0.671137},
+  {0.097019,-0.343781},
+  {0.353095,0.071768},
+  {0.399844,1.140014},
+  {-0.092161,0.421038},
+  {0.951596,0.997798},
+  {0.233831,-0.888818},
+  {-0.914231,0.468451},
+  {-0.320417,0.768939},
+  {0.010017,-0.067670},
+  {-0.641204,0.499319},
+  {0.464514,-0.342039},
+  {0.806917,0.412848},
+  {-0.389667,-0.723328},
+  {1.504390,-0.862004},
+  {-0.077352,-0.895115},
+  {-0.618964,0.190222},
+  {0.301279,0.239691},
+  {-1.242100,0.120618},
+  {0.930139,0.521412},
+  {0.529753,-0.277023},
+  {-0.884634,-0.158847},
+  {0.636505,-0.971609},
+  {-0.835765,0.991747},
+  {0.277340,-0.861971},
+  {1.021073,1.142868},
+  {-0.705786,0.603524},
+  {0.156000,-0.793177},
+  {0.066289,-0.265637},
+  {-1.395549,-0.477809},
+  {-0.398661,0.403177},
+  {-0.459976,-0.843605},
+  {0.984018,-0.852629},
+  {0.218633,-0.126745},
+  {-0.282519,0.221063},
+  {-0.030076,0.666546},
+  {-0.069338,0.189674},
+  {0.437178,0.500713},
+  {0.391939,0.145078},
+  {-1.572762,0.700506},
+  {-1.015432,0.377474},
+  {-0.840338,0.937558},
+  {0.342004,0.167650},
+  {-0.060252,0.117581},
+  {0.472117,0.635502},
+  {0.104385,-0.161998},
+  {1.188391,-1.588144},
+  {-1.256569,-0.943382},
+  {-1.338045,-1.795011},
+  {0.423467,-0.663819},
+  {0.202217,0.684588},
+  {0.233240,1.011311},
+  {-0.758494,0.433929},
+  {0.926118,-0.054441},
+  {0.564314,-0.974460},
+  {0.726559,-1.559723},
+  {-0.541272,-0.563339},
+  {0.749341,-0.459923},
+  {-0.592150,-0.292360},
+  {-1.425995,-1.199563},
+  {0.630984,0.173879},
+  {-0.496013,0.849446},
+  {0.730005,-0.623744},
+  {0.339948,0.700938},
+  {0.318261,-1.431390},
+  {0.179177,-0.081351},
+  {0.422595,0.110693},
+  {0.525183,-0.014276},
+  {0.791773,-0.477120},
+  {0.337622,-0.907080},
+  {-0.961643,0.350677},
+  {-0.419235,0.114661},
+  {-0.036426,-0.074521},
+  {-0.851223,0.150299},
+  {-1.402542,-0.652643},
+  {-0.444904,0.206768},
+  {0.649220,0.699797},
+  {0.159030,0.332804},
+  {0.252170,-0.574764},
+  {0.214542,-0.070060},
+  {0.672585,-0.214337},
+  {0.317019,0.014172},
+  {-0.760543,0.267257},
+  {1.642791,0.243831},
+  {-1.046533,-0.098091},
+  {-0.043117,0.019885},
+  {0.017252,-1.446676},
+  {0.264861,0.685846},
+  {0.517324,0.010126},
+  {0.343672,0.470516},
+  {0.031183,0.226200},
+  {-0.069854,-0.562667},
+  {0.527272,0.532637},
+  {-0.858228,0.534935},
+  {0.364460,0.740142},
+  {-0.140402,-0.483472},
+  {0.017139,0.061624},
+  {-0.294724,1.396053},
+  {-0.540405,-0.124744},
+  {-0.216948,-0.080703},
+  {0.142776,-0.316044},
+  {-0.253452,-0.078581},
+  {-0.025665,0.377449},
+  {0.170569,0.657816},
+  {0.558146,0.230644},
+  {-0.811005,0.844136},
+  {1.274885,-0.602096},
+  {-0.256525,0.339416},
+  {-0.445608,-0.526104},
+  {-0.679020,-0.428087},
+  {-0.585500,0.611806},
+  {0.321104,1.015454},
+  {0.088048,0.254566},
+  {-0.194493,-0.085023},
+  {0.235160,0.956288},
+  {0.814722,0.247546},
+  {-0.785712,0.033330},
+  {1.303812,-0.323498},
+  {0.900592,0.189877},
+  {0.557885,-0.981445},
+  {0.472523,0.784359},
+  {0.761798,-0.989764},
+  {0.391552,0.560236},
+  {0.697718,-0.307289},
+  {-0.302544,0.328754},
+  {-1.050820,-0.691314},
+  {-0.647732,-0.054507},
+  {0.021808,0.443342},
+  {-1.449923,-0.824803},
+  {0.190423,-0.098085},
+  {0.631746,-0.468679},
+  {0.040293,-1.576056},
+  {-0.372698,0.455461},
+  {0.220583,0.009939},
+  {-0.270850,-0.097216},
+  {-0.505603,0.942481},
+  {-0.821008,0.456088},
+  {-0.903589,-0.879087},
+  {-1.037097,0.467356},
+  {-0.106833,1.072424},
+  {0.863947,0.585468},
+  {0.005151,0.434652},
+  {-0.400947,-1.251142},
+  {0.189981,0.404356},
+  {-0.285439,0.379628},
+  {0.087294,-0.869496},
+  {-0.192137,0.869642},
+  {-0.692827,-0.385168},
+  {-0.562495,0.217508},
+  {0.542657,-0.510556},
+  {0.464191,-0.475241},
+  {-0.360873,0.439250},
+  {0.855123,0.200659},
+  {-0.610447,0.408358},
+  {0.908977,1.265472},
+  {0.594758,-1.492478},
+  {0.029868,-0.283152},
+  {-0.742647,-0.959861},
+  {-1.058543,-0.718420},
+  {0.030062,0.074846},
+  {0.484401,-1.125483},
+  {-0.284086,0.159763},
+  {-1.080775,-0.140955},
+  {-0.174126,-0.086363},
+  {0.739286,-0.217804},
+  {0.141377,-0.665255},
+  {0.920503,-0.318352},
+  {0.312659,0.743913},
+  {0.276399,0.154918},
+  {0.663342,-0.243720},
+  {0.208475,1.070727},
+  {1.547443,-0.539637},
+  {-0.480355,-0.378719},
+  {-0.286722,-0.944048},
+  {-0.939835,0.257670},
+  {-0.970612,-0.234679},
+  {-0.869842,1.134333},
+  {0.129012,-1.323594},
+  {-0.847059,0.612807},
+  {0.143607,0.167211},
+  {-0.644289,-0.020060},
+  {0.597720,-0.525289},
+  {0.344575,0.696561},
+  {0.032192,-0.316594},
+  {-0.527359,0.248141},
+  {0.057843,-1.004926},
+  {0.174263,-0.084976},
+  {-0.103775,-0.357881},
+  {0.591409,0.244348},
+  {-1.185070,-0.186006},
+  {0.643666,0.679958},
+  {-0.560183,-0.180895},
+  {-0.730927,0.972640},
+  {0.414448,-0.245573},
+  {-0.715735,-0.063948},
+  {0.602288,-0.368285},
+  {-0.595310,-0.096140},
+  {0.154414,-0.239226},
+  {-0.643521,-1.322612},
+  {-0.372893,0.644678},
+  {-0.871536,-1.116017},
+  {-0.355362,-0.495611},
+  {0.807998,-0.506884},
+  {-1.512365,1.149375},
+  {-0.663902,-0.483402},
+  {-0.027985,0.740126},
+  {-0.627528,0.621482},
+  {0.273277,0.398212},
+  {0.646616,1.375140},
+  {-0.691492,1.019221},
+  {0.666217,0.443858},
+  {0.695471,0.183591},
+  {-0.505856,-0.531083},
+  {0.770952,0.230695},
+  {-0.598738,0.451612},
+  {0.301636,-1.123508},
+  {0.345123,-0.300982},
+  {-0.371200,0.114885},
+  {0.040179,0.024051},
+  {-0.193750,0.538700},
+  {-0.540208,0.170493},
+  {-0.732932,-0.668738},
+  {-1.222816,0.434783},
+  {0.056403,0.263628},
+  {0.248752,1.012811},
+  {-0.511117,-0.049178},
+  {-0.044573,-0.975817},
+  {0.398627,0.462711},
+  {-0.260856,-0.068978},
+  {-0.280710,-0.321223},
+  {-1.899199,-1.720357},
+  {-0.214145,0.610662},
+  {0.860637,-0.542982},
+  {1.479895,0.512347},
+  {-0.634684,-0.205669},
+  {-0.774042,0.960716},
+  {0.254752,-0.070188},
+  {0.048949,0.072511},
+  {-0.076806,0.217678},
+  {-0.398325,0.011892},
+  {0.947991,0.795319},
+  {1.507949,-0.647927},
+  {-0.067973,0.815859},
+  {0.021869,-1.330399},
+  {0.260440,-0.736693},
+  {0.047665,1.669888},
+  {0.051714,-0.750557},
+  {0.461558,0.446945},
+  {1.025170,0.357000},
+  {0.045956,-0.325779},
+  {-0.173120,0.700485},
+  {0.536135,-0.477065},
+  {0.128767,-0.204009},
+  {-0.760650,-1.142806},
+  {0.136669,-1.190282},
+  {0.497392,-1.408788},
+  {-0.148019,0.206583},
+  {-0.501879,-0.488139},
+  {0.009399,-0.681400},
+  {0.701198,-0.538127},
+  {0.180453,0.485088},
+  {-0.265001,0.156447},
+  {-0.640031,0.482786},
+  {-0.518979,-0.541837},
+  {-0.032891,-0.430068},
+  {-0.461893,-0.277698},
+  {0.262606,0.260080},
+  {0.041808,-0.123995},
+  {-0.440511,0.223938},
+  {-0.106192,-1.594211},
+  {-0.418230,0.723012},
+  {0.073327,-0.112584},
+  {-0.418561,-0.692791},
+  {0.368207,0.185128},
+  {0.168326,0.239815},
+  {0.114983,-0.779877},
+  {-0.513697,-0.218598},
+  {-0.509730,-1.001503},
+  {-0.257517,0.486916},
+  {-0.939828,0.965026},
+  {-1.454300,-0.203483},
+  {-0.492785,-0.713430},
+  {0.301437,-0.797414},
+  {0.238702,-0.386490},
+  {-0.944933,0.181264},
+  {0.443444,1.104281},
+  {0.703275,-1.091732},
+  {-0.739420,0.369381},
+  {-0.541723,0.306867},
+  {-0.421282,-0.067401},
+  {-0.359663,-0.430076},
+  {-0.365976,-0.386311},
+  {-1.235840,-0.744903},
+  {-0.582278,0.165135},
+  {0.258208,0.795858},
+  {0.656751,-0.199973},
+  {-0.661437,-1.236283},
+  {-0.183853,0.537246},
+  {-0.698045,0.604539},
+  {-0.705045,0.847084},
+  {-1.459402,0.628008},
+  {0.692337,1.236132},
+  {-0.260324,0.599788},
+  {-0.010288,-0.048783},
+  {0.066315,0.077396},
+  {0.258401,-1.300776},
+  {-0.606507,0.626366},
+  {0.918692,0.313908},
+  {0.301100,0.600185},
+  {0.756285,-0.134042},
+  {0.419008,0.068592},
+  {0.678707,0.297421},
+  {-0.762643,0.544065},
+  {0.811504,0.550301},
+  {-0.128498,0.753596},
+  {-0.506348,-0.102907},
+  {-0.361289,-0.120066},
+  {0.772548,0.007574},
+  {-0.403729,0.699871},
+  {0.438742,2.197012},
+  {-1.157543,-0.354945},
+  {0.220848,0.508695},
+  {0.354803,-0.410951},
+  {1.084506,0.972850},
+  {0.092344,1.433922},
+  {0.506397,0.385787},
+  {1.217549,0.293367},
+  {-0.334559,-0.101333},
+  {-0.406466,-0.023401},
+  {0.356600,-1.141455},
+  {-0.011750,0.287641},
+  {-0.050458,0.686041},
+  {-1.213470,0.430009},
+  {0.551580,-0.801972},
+  {0.065996,-0.224313},
+  {0.281099,-1.068458},
+  {-0.096408,0.757440},
+  {1.583368,0.056612},
+  {0.087061,0.328131},
+  {-0.394441,-1.372195},
+  {0.512555,-0.342829},
+  {-0.073289,-0.416035},
+  {0.913218,-1.088553},
+  {-0.698006,0.235712},
+  {-0.230038,-0.514247},
+  {-0.040607,-0.916763},
+  {0.632154,-0.540679},
+  {-0.887651,-1.009355},
+  {-0.632470,-1.022231},
+  {0.190182,1.032801},
+  {-0.027089,0.692375},
+  {-0.675473,0.192100},
+  {-1.255069,0.423638},
+  {-0.195848,0.109171},
+  {0.292869,-1.505548},
+  {0.515116,-0.182036},
+  {-0.690289,0.288317},
+  {1.434559,-0.687078},
+  {-0.461406,-1.224466},
+  {-0.374814,0.354303},
+  {0.616066,0.664220},
+  {-0.312574,-0.753793},
+  {-0.010131,0.316177},
+  {0.677541,-0.304399},
+  {0.362407,-0.542312},
+  {0.421985,-0.426462},
+  {1.074806,0.427175},
+  {0.714370,-0.383605},
+  {0.981694,-0.101514},
+  {-0.580749,0.366888},
+  {0.150148,1.272927},
+  {0.102605,1.472671},
+  {0.133743,-0.162327},
+  {0.098048,0.154761},
+  {0.138915,0.424027},
+  {-0.068587,-0.269135},
+  {0.151768,-0.574258},
+  {0.705147,0.504406},
+  {-0.199471,-0.747309},
+  {0.660886,1.191666},
+  {-0.434080,0.337494},
+  {0.065750,-1.195325},
+  {-0.022976,0.447841},
+  {0.105985,0.089817},
+  {-0.084156,-0.318798},
+  {0.072991,-0.327037},
+  {-0.128438,0.126156},
+  {-0.405562,-0.076535},
+  {-0.426691,-0.173649},
+  {-1.860770,-0.948092},
+  {-0.127870,-0.262563},
+  {-1.138050,-0.096580},
+  {0.370414,-1.870972},
+  {-0.169835,0.059237},
+  {0.107617,0.823066},
+  {-1.055285,-0.282586},
+  {-1.207492,0.630350},
+  {0.199582,0.096160},
+  {0.726497,0.068093},
+  {-0.532842,-0.156855},
+  {1.093617,0.601716},
+  {-1.528594,-0.081629},
+  {-0.210981,-0.742901},
+  {0.320628,-1.275187},
+  {-0.959229,-1.040017},
+  {-0.435513,-1.345417},
+  {0.883669,0.681837},
+  {-1.529650,-0.446392},
+  {-0.720045,1.701187},
+  {-1.098947,0.930781},
+  {-0.652223,-0.676971},
+  {0.540277,0.620405},
+  {-0.084783,-0.516229},
+  {-0.645938,-0.752328},
+  {0.592236,-0.445923},
+  {0.987580,-0.654351},
+  {0.631582,-0.687112},
+  {-0.747723,-0.216685},
+  {-0.242519,0.244150},
+  {-0.503676,-0.402645},
+  {-1.298327,1.084137},
+  {-0.362467,0.491899},
+  {-0.033132,-0.268392},
+  {-0.126278,0.423416},
+  {-1.031263,-0.085027},
+  {0.243811,-0.366720},
+  {0.639498,0.129467},
+  {-0.335136,1.108368},
+  {-0.512740,1.873530},
+  {0.643081,0.099739},
+  {-0.255082,0.612374},
+  {-0.175646,0.130710},
+  {0.108781,1.292291},
+  {-0.614601,0.259555},
+  {0.168058,0.048234},
+  {-0.574672,0.318310},
+  {-0.216721,-0.336900},
+  {-0.005054,0.439731},
+  {-0.850990,0.370968},
+  {-0.067698,0.383192},
+  {0.383593,-0.525092},
+  {-0.061197,0.459613},
+  {1.361076,-0.818933},
+  {-0.505306,-0.543337},
+  {0.635340,-0.050133},
+  {-1.114203,0.161483},
+  {-0.176448,-0.346756},
+  {0.120352,0.445743},
+  {-0.245858,-0.834506},
+  {-0.920717,0.600234},
+  {-0.297926,0.695282},
+  {1.293254,0.324459},
+  {-0.963549,0.214107},
+  {0.291750,0.306301},
+  {-0.020635,-0.108404},
+  {-0.625249,0.393424},
+  {-0.678041,-0.306473},
+  {1.267072,-0.004506},
+  {0.022893,0.861164},
+  {-0.623908,0.323349},
+  {0.368754,0.620841},
+  {-0.528447,-0.141905},
+  {0.088043,1.543236},
+  {-0.899354,-0.855242},
+  {-0.026557,-0.453395},
+  {0.027462,1.047341},
+  {0.769418,-1.229816},
+  {1.440973,-0.699249},
+  {0.073809,-0.849225},
+  {0.260617,-0.050471},
+  {-0.343781,-0.188150},
+  {0.196896,0.184787},
+  {0.186939,-0.670752},
+  {0.922055,1.559028},
+  {0.501239,-0.571159},
+  {-0.501999,0.117773},
+  {-0.919095,0.778399},
+  {0.351764,-0.823198},
+  {0.148608,0.329635},
+  {1.115657,-0.601348},
+  {-0.356139,-0.377287},
+  {0.082008,-0.934193},
+  {0.413781,-0.481072},
+  {0.159484,0.219529},
+  {0.769932,-0.473240},
+  {-0.127988,-0.380868},
+  {0.633024,-0.074308},
+  {0.422594,-1.072281},
+  {-0.962782,0.898361},
+  {0.606030,-0.243257},
+  {0.060875,-0.778985},
+  {-0.615502,0.659961},
+  {0.690715,-0.017834},
+  {0.475395,-0.359472},
+  {-0.974448,-0.511066},
+  {0.692056,-0.796830},
+  {0.464684,-0.250498},
+  {-0.473990,0.157603},
+  {-0.221502,-0.380543},
+  {0.776700,0.874519},
+  {0.278098,-0.390918},
+  {-0.020204,0.129496},
+  {-0.492732,-1.203373},
+  {-0.192923,0.392172},
+  {-0.456686,-1.096002},
+  {0.225734,-0.338651},
+  {-0.423440,-0.151675},
+  {0.047326,0.697747},
+  {-1.402831,0.389770},
+  {-0.481669,-0.607328},
+  {0.707638,-0.420784},
+  {-0.585504,0.372906},
+  {0.884026,0.946783},
+  {-0.890221,-0.123712},
+  {-0.946448,-1.331909},
+  {-0.161589,0.672376},
+  {-0.428532,0.326757},
+  {-0.478465,-0.457691},
+  {-0.054022,1.405670},
+  {-0.333135,0.375169},
+  {-0.372505,0.854525},
+  {1.535750,0.415969},
+  {0.295118,-0.716003},
+  {-0.336206,-0.196896},
+  {0.743605,0.229018},
+  {0.792000,-1.768616},
+  {-1.354626,0.963126},
+  {-1.405782,0.680236},
+  {-0.237975,-0.000923},
+  {-0.690345,-1.003080},
+  {-1.313895,-0.033107},
+  {-0.614969,0.864382},
+  {0.990158,1.112463},
+  {-1.001071,-0.634240},
+  {0.594301,0.062948},
+  {-0.534023,0.563650},
+  {0.605461,-0.096271},
+  {0.236832,-0.313801},
+  {-0.493347,-0.201958},
+  {-0.520262,-0.387792},
+  {-0.912513,-1.199020},
+  {-0.129950,-0.310796},
+  {-0.541204,-0.716691},
+  {-0.081170,0.596112},
+  {0.737798,1.145168},
+  {-0.928121,-0.998200},
+  {0.669610,1.145227},
+  {0.832308,0.318849},
+  {-0.039104,-0.614171},
+  {0.755613,-0.876583},
+  {-1.016801,0.001975},
+  {-0.050756,0.076366},
+  {0.630505,-0.239083},
+  {0.197191,-0.747906},
+  {-0.372266,-0.592826},
+  {-1.529025,0.438443},
+  {-0.412525,-0.849941},
+  {0.829853,0.127465},
+  {0.283020,0.119718},
+  {1.891486,-0.325311},
+  {-0.585484,-0.410801},
+  {0.059833,-0.092511},
+  {-0.831938,-0.638384},
+  {-0.235357,0.183885},
+  {-0.347581,-1.189650},
+  {0.014281,-0.758982},
+  {0.350777,-0.963252},
+  {-0.065657,-0.156335},
+  {-0.165794,0.022285},
+  {0.747007,-0.478210},
+  {0.567832,-0.106546},
+  {0.396140,0.016729},
+  {-0.272671,0.066605},
+  {1.376385,0.510745},
+  {-0.060046,0.644132},
+  {0.775174,-0.161923},
+  {0.685821,0.001454},
+  {-1.561711,0.881058},
+  {1.787424,-0.058002},
+  {0.336836,-0.858057},
+  {-0.331450,-0.740409},
+  {-2.109117,0.353266},
+  {-0.216311,0.071157},
+  {0.114973,-0.504866},
+  {-0.622727,-0.587637},
+  {-1.153190,0.816906},
+  {-1.426416,1.516651},
+  {-1.307579,0.228991},
+  {-0.770577,-0.045774},
+  {0.372744,0.808508},
+  {0.120187,-0.103078},
+  {-0.195718,-0.374301},
+  {1.075698,1.295923},
+  {-0.361592,-0.873742},
+  {-0.418061,-1.279100},
+  {0.784779,-1.675948},
+  {1.268633,-0.865789},
+  {-0.519273,0.090093},
+  {-0.262722,-0.402864},
+  {-0.951638,0.084945},
+  {-0.355352,-0.351439},
+  {0.285010,0.056406},
+  {-0.950448,-0.397773},
+  {-0.464651,0.160215},
+  {1.109933,-0.480592},
+  {-1.419546,1.158028},
+  {0.905718,0.111670},
+  {-0.237821,0.135966},
+  {-1.259691,0.323498},
+  {-0.470925,-0.541165},
+  {0.102619,-0.372763},
+  {-0.712979,-0.457720},
+  {0.970056,0.171370},
+  {-1.135346,-0.461788},
+  {-0.633181,1.008828},
+  {1.176038,-1.068340},
+  {0.500422,-0.673381},
+  {0.894371,-0.164669},
+  {0.483704,0.314087},
+  {-1.188251,-0.842904},
+  {-0.157257,0.172253},
+  {-0.898239,0.677601},
+  {-0.279064,-1.615232},
+  {-0.992485,0.177739},
+  {-0.476199,-0.218263},
+  {-0.132737,1.169939},
+  {-1.302813,0.651199},
+  {-0.310092,0.900820},
+  {0.049591,-0.876856},
+  {-0.107885,-0.364864},
+  {-0.126501,-0.848695},
+  {1.113648,0.511673},
+  {0.264047,0.194513},
+  {-0.056919,0.273691},
+  {0.703939,-0.054764},
+  {-1.272536,-0.341796},
+  {-0.119178,-0.654156},
+  {0.132597,-0.130565},
+  {0.899426,0.459049},
+  {-0.391768,-1.166623},
+  {-0.225483,-0.557438},
+  {-0.167593,0.661089},
+  {-1.659540,-0.002336},
+  {0.794658,0.033512},
+  {-1.069324,0.241018},
+  {-0.918777,1.380683},
+  {0.332766,0.468339},
+  {1.686444,-0.943082},
+  {-0.547574,-0.948940},
+  {0.030771,0.036540},
+  {-0.833640,-1.376152},
+  {-1.243536,0.371659},
+  {-0.237937,-0.425704},
+  {0.259845,1.519797},
+  {-0.911238,-0.668074},
+  {-0.013456,0.176795},
+  {-0.882968,-0.341753},
+  {0.854397,0.383916},
+  {0.235472,0.285590},
+  {-0.359982,0.097074},
+  {-0.131102,-1.300127},
+  {0.266605,0.174879},
+  {-0.294888,0.138128},
+  {-0.108081,0.172793},
+  {-0.478603,-0.057927},
+  {-0.712859,1.038960},
+  {0.209788,0.449368},
+  {0.387551,-0.640651},
+  {0.003760,-0.340271},
+  {-0.061907,0.617510},
+  {0.392158,-0.953156},
+  {0.726593,-0.189035},
+  {0.597882,-0.274553},
+  {0.666026,0.048594},
+  {0.284210,0.946907},
+  {0.305420,0.165142},
+  {0.404228,0.231668},
+  {-0.017939,-1.142982},
+  {1.139064,-0.458041},
+  {-0.819369,0.895217},
+  {-0.047318,0.285829},
+  {-0.568780,-0.190502},
+  {-0.606370,-0.099547},
+  {1.424332,0.802029},
+  {-0.821119,0.250209},
+  {-1.376602,1.326391},
+  {-1.098387,1.606694},
+  {0.496951,-0.357961},
+  {0.210738,0.046687},
+  {0.369485,-0.157254},
+  {-0.544895,-0.402399},
+  {-0.882763,-0.055791},
+  {-0.357232,0.166177},
+  {-0.615774,-0.069649},
+  {-0.767183,-0.112721},
+  {0.375762,-0.020422},
+  {-0.098314,0.398756},
+  {0.176510,0.550347},
+  {1.200922,-0.003930},
+  {1.325052,-0.313705},
+  {-0.150081,1.250977},
+  {2.057610,0.216751},
+  {-0.238246,0.229506},
+  {0.857400,-0.572607},
+  {-0.562334,1.100413},
+  {0.384247,-1.554662},
+  {0.067540,0.515121},
+  {1.340051,-0.351801},
+  {-0.422137,-0.315044},
+  {0.860255,-0.025928},
+  {-0.499608,-0.491812},
+  {-0.466429,-1.328300},
+  {-0.323761,0.241738},
+  {0.393656,-0.847954},
+  {0.459800,1.193975},
+  {0.310703,-0.636093},
+  {-0.445585,0.424384},
+  {0.846073,0.364936},
+  {-0.259331,-0.399480},
+  {0.436216,-0.067255},
+  {-0.733748,-0.699265},
+  {0.324053,1.497643},
+  {0.615826,0.748861},
+  {1.193295,-1.242813},
+  {-0.466988,0.156967},
+  {0.611477,0.193048},
+  {-0.055928,-0.158672},
+  {0.975226,-0.459924},
+  {-0.655781,-0.693858},
+  {1.324562,-0.668467},
+  {0.864872,-2.109563},
+  {0.717141,-0.626098},
+  {-1.302740,0.096267},
+  {1.116621,-0.009268},
+  {0.100593,1.267514},
+  {0.425933,-0.009823},
+  {-0.173129,-0.174238},
+  {0.153032,0.109386},
+  {-0.318603,0.546064},
+  {0.289912,0.429496},
+  {0.155977,0.603650},
+  {-0.776808,0.920140},
+  {-0.878454,-0.082128},
+  {0.608451,1.174464},
+  {0.353067,-0.103951},
+  {-0.452806,0.168395},
+  {1.339559,0.439086},
+  {-0.020182,-1.321645},
+  {0.118079,-0.311166},
+  {-0.272936,0.134373},
+  {0.373963,-1.299783},
+  {0.054969,0.261178},
+  {-0.239239,-0.615398},
+  {-1.001020,-1.146200},
+  {0.449862,-1.228006},
+  {0.323008,0.572236},
+  {-1.653429,0.189960},
+  {-1.049711,-0.245348},
+  {0.976135,0.169753},
+  {0.706318,-0.614142},
+  {1.130571,1.122720},
+  {-0.180019,-0.492531},
+  {0.585209,-0.465400},
+  {-0.786602,0.685904},
+  {0.096573,0.109326},
+  {-0.141775,-0.749653},
+  {-0.059186,-0.316195},
+  {-1.462725,-1.202917},
+  {-1.236354,0.418481},
+  {0.151833,0.157247},
+  {0.691259,0.080574},
+  {0.483058,-1.638888},
+  {0.128021,1.112820},
+  {-0.191649,1.303981},
+  {-0.086171,-1.095404},
+  {-0.568276,0.304373},
+  {2.181999,-0.551641},
+  {-1.035423,-0.289490},
+  {0.155008,-0.150995},
+  {-1.103950,-1.857698},
+  {-0.668989,-0.467956},
+  {-0.185524,0.446566},
+  {-0.643301,-0.258359},
+  {0.087981,-0.547687},
+  {-0.516929,0.605263},
+  {0.342129,0.093293},
+  {2.011109,0.019105},
+  {0.363808,0.781133},
+  {-1.536479,1.337943},
+  {0.435211,-0.631518},
+  {-0.556866,-0.694405},
+  {1.114228,-0.174913},
+  {0.538381,-0.752450},
+  {0.550732,-0.407947},
+  {0.022731,-0.085540},
+  {0.188773,0.308336},
+  {0.487134,-0.164736},
+  {0.186646,1.139253},
+  {0.045252,-1.157604},
+  {1.084051,-0.890305},
+  {0.619163,-0.150592},
+  {0.354104,0.841673},
+  {0.229173,-2.117542},
+  {-0.396302,-0.148405},
+  {-0.233108,0.645852},
+  {-0.409376,0.680217},
+  {0.561133,-1.591081},
+  {0.132287,1.114235},
+  {-0.167495,-0.729692},
+  {-0.563572,-1.003719},
+  {-1.407809,0.049666},
+  {0.259140,-1.152104},
+  {0.876016,0.966907},
+  {1.109627,0.127202},
+  {0.900875,0.161930},
+  {-0.239223,-0.745766},
+  {-0.049711,-0.106964},
+  {-1.172386,1.606319},
+  {1.580091,-0.165441},
+  {-0.105897,0.096532},
+  {0.514744,-0.441290},
+  {-0.410128,1.642280},
+  {1.025580,-0.241450},
+  {0.570167,0.040530},
+  {0.871560,-0.323875},
+  {-0.234388,-1.244179},
+  {0.675376,0.964659},
+  {0.374233,0.149805},
+  {-0.789252,1.310412},
+  {-0.284409,1.148222},
+  {-0.660847,0.363166},
+  {0.782152,0.454305},
+  {0.172868,0.088907},
+  {-0.278771,0.023603},
+  {0.293272,0.372982},
+  {0.311987,0.322549},
+  {0.606624,0.527143},
+  {0.192137,0.430538},
+  {-0.324541,0.343529},
+  {-0.158355,0.734556},
+  {-0.137073,-0.403531},
+  {-0.250048,0.162757},
+  {0.447298,0.471529},
+  {-0.874570,-0.929687},
+  {0.556881,0.694617},
+  {0.202336,0.104962},
+  {-1.529270,0.384855},
+  {0.164846,-0.749040},
+  {-0.712317,-0.291645},
+  {-0.649720,-0.482616},
+  {-0.157974,0.405484},
+  {0.057860,0.996968},
+  {0.618568,-0.192818},
+  {-0.569099,0.526239},
+  {0.535368,-2.569703},
+  {0.287562,-0.200457},
+  {-0.774001,-0.447806},
+  {-0.677427,0.757377},
+  {0.440255,1.722018},
+  {0.221734,0.363236},
+  {-1.142799,0.246628},
+  {-0.000987,0.084137},
+  {0.177699,-0.161609},
+  {0.219112,0.145815},
+  {1.192557,-0.513284},
+  {-1.063099,-0.407821},
+  {0.344825,0.059121},
+  {0.324140,-1.340732},
+  {-0.385376,0.564923},
+  {1.112126,0.068623},
+  {1.217525,-0.793810},
+  {-0.173809,0.211866},
+  {0.008904,0.344939},
+  {-0.551659,-0.020264},
+  {0.409603,0.130882},
+  {-0.460838,0.011734},
+  {0.767436,-0.389044},
+  {-0.317004,1.030325},
+  {0.765716,1.202983},
+  {-0.899111,-0.543610},
+  {-0.281986,-0.684544},
+  {-0.364272,0.091067},
+  {-0.944820,0.735864},
+  {-0.473074,0.236066},
+  {0.590428,-0.001307},
+  {0.902710,0.060698},
+  {-0.479309,0.186699},
+  {-0.622708,0.120223},
+  {-0.552450,-0.012236},
+  {0.431918,1.303160},
+  {0.050594,-0.525912},
+  {0.362519,0.624894},
+  {-0.941750,0.479853},
+  {-0.146931,-0.166574},
+  {-0.222338,-0.578684},
+  {0.516931,0.696953},
+  {-0.950476,0.567101},
+  {0.021004,0.707791},
+  {1.023076,1.585372},
+  {-0.379172,-0.455007},
+  {0.999678,-1.125859},
+  {1.112727,1.119853},
+  {-1.229585,-0.372180},
+  {0.485929,1.072664},
+  {-0.533969,-0.058251},
+  {-0.780870,-0.083022},
+  {0.197475,-0.090851},
+  {0.869964,-0.537793},
+  {0.041044,0.400725},
+  {0.337632,0.010040},
+  {0.995867,-0.413684},
+  {-0.197465,-0.816039},
+  {0.113805,1.162790},
+  {-0.869838,0.460479},
+  {-0.720627,0.136898},
+  {-0.555949,0.348150},
+  {-1.010460,0.876235},
+  {0.288385,0.442596},
+  {0.628015,0.092587},
+  {1.017268,1.102030},
+  {0.136902,0.765530},
+  {-1.074543,-0.048865},
+  {-1.177793,-0.693738},
+  {0.527523,0.145117},
+  {-0.760523,0.203876},
+  {0.938313,1.041252},
+  {0.539914,-0.157041},
+  {-0.572504,-0.177670},
+  {-0.180789,-0.215865},
+  {0.138948,-0.228659},
+  {-0.294927,-0.979739},
+  {-0.295661,-1.044591},
+  {0.151225,-1.389272},
+  {-0.756423,-0.423643},
+  {-0.061934,-0.301791},
+  {-0.270853,-0.240812},
+  {-0.803715,0.821259},
+  {-0.697601,0.617383},
+  {0.289209,-0.053389},
+  {-0.896823,0.262431},
+  {-0.295344,-0.261914},
+  {0.058281,0.044589},
+  {-1.008325,0.176720},
+  {0.175546,-0.335204},
+  {0.631611,-0.600731},
+  {-0.433719,-1.128985},
+  {-0.409720,-0.312795},
+  {0.323113,0.261763},
+  {0.036730,0.115460},
+  {0.059806,0.466118},
+  {-0.435466,0.810298},
+  {1.362624,-0.053060},
+  {0.017303,0.016551},
+  {-0.831908,-0.085054},
+  {-0.047121,-1.210964},
+  {-0.492066,0.242858},
+  {0.390794,0.069634},
+  {0.814141,-0.385739},
+  {0.000600,1.161953},
+  {-0.825328,-1.076807},
+  {-0.137587,-0.380351},
+  {-1.033185,0.376119},
+  {-0.942623,0.986463},
+  {-0.615904,0.634404},
+  {0.405671,0.449572},
+  {-0.610933,0.735977},
+  {-0.318879,0.163802},
+  {-0.507174,-0.284257},
+  {0.727653,-0.764991},
+  {0.553744,0.406244},
+  {0.109977,-0.425145},
+  {0.007260,0.694717},
+  {-0.589111,-0.324782},
+  {1.296184,-0.280316},
+  {0.273412,-0.063905},
+  {0.628945,0.335630},
+  {-0.149412,-0.710817},
+  {1.448227,-0.686517},
+  {0.812279,1.204193},
+  {-0.323526,0.612276},
+  {1.317114,-0.397886},
+  {-0.905302,-0.684715},
+  {-0.018889,0.460583},
+  {0.413307,0.079909},
+  {0.196694,-0.264636},
+  {0.237990,0.380848},
+  {1.110570,0.186631},
+  {1.100941,0.944369},
+  {-0.268469,-0.372955},
+  {0.654447,-1.005281},
+  {-0.867087,0.494783},
+  {-0.307357,0.224308},
+  {1.126564,-0.447765},
+  {-1.441809,-0.432263},
+  {0.829316,-0.254776},
+  {0.276601,0.028482},
+  {0.321513,0.477089},
+  {-0.326903,-0.065775},
+  {0.181178,0.425015},
+  {-0.021201,-0.632189},
+  {0.196787,-0.270172},
+  {0.482211,0.760539},
+  {-0.021529,0.350678},
+  {0.538731,0.792097},
+  {-0.792762,-1.073304},
+  {0.269102,0.466839},
+  {-0.457873,-0.267988},
+  {-1.086786,-1.382579},
+  {-0.902461,-0.333688},
+  {1.449862,0.549708},
+  {1.103982,-0.815866},
+  {-0.331610,-0.126280},
+  {-0.434605,-0.574026},
+  {-0.564428,0.451053},
+  {1.065076,-0.142613},
+  {-1.067355,-0.781069},
+  {0.415735,0.395771},
+  {-0.257126,-0.498318},
+  {0.229113,-0.904408},
+  {0.475347,0.932772},
+  {-0.126197,-0.312728},
+  {0.015972,1.513573},
+  {0.072260,-0.478380},
+  {0.199441,-1.515994},
+  {0.801702,-0.148107},
+  {0.732459,-0.716389},
+  {-1.055474,0.377686},
+  {0.882117,-0.319396},
+  {-0.389893,0.614071},
+  {-0.426814,0.453146},
+  {-1.280709,0.307466},
+  {0.465162,-0.568253},
+  {-0.105649,0.264185},
+  {0.207625,0.360816},
+  {-1.212366,0.121881},
+  {0.229992,-0.215450},
+  {0.416004,-0.583465},
+  {0.716912,-0.118409},
+  {0.096084,-0.512867},
+  {0.186247,0.032560},
+  {0.028022,-0.556780},
+  {1.150752,-0.299593},
+  {-1.619091,-0.453159},
+  {-0.212540,-1.038386},
+  {0.255212,-0.885610},
+  {-0.279565,0.220245},
+  {-0.933030,1.702921},
+  {1.098960,-0.501176},
+  {0.621376,-0.194441},
+  {-0.046707,-0.191768},
+  {0.820383,-1.152666},
+  {-0.625110,1.133264},
+  {0.136433,-0.774816},
+  {0.450809,-0.089682},
+  {-2.456335,0.966943},
+  {0.912559,-0.737705},
+  {-0.981240,-0.672716},
+  {-0.364111,-0.695029},
+  {-0.339351,1.566577},
+  {-1.639069,1.051843},
+  {0.305872,0.958157},
+  {-0.506132,0.126778},
+  {0.213442,0.269895},
+  {0.219518,0.742494},
+  {0.850854,0.816322},
+  {0.239080,0.545993},
+  {-0.092504,0.731571},
+  {0.440567,-1.122125},
+  {0.610520,-0.413122},
+  {-0.578101,-0.718322},
+  {-0.222974,1.427200},
+  {0.545492,-0.056598},
+  {0.627889,1.317222},
+  {-0.048461,-0.116290},
+  {-0.394290,-0.229413},
+  {-0.462502,-0.045762},
+  {-0.200809,0.574322},
+  {0.339283,-0.584942},
+  {-0.393629,1.095376},
+  {-0.371673,-0.655765},
+  {-0.260952,-0.654112},
+  {1.083400,0.823028},
+  {-0.952867,-0.473551},
+  {-0.018485,0.260282},
+  {0.387338,0.088609},
+  {-0.988637,-0.394637},
+  {-0.651919,-0.458630},
+  {1.482098,0.311456},
+  {0.617416,0.339357},
+  {0.024986,-0.654472},
+  {-0.633096,-1.253554},
+  {0.316704,-1.543150},
+  {-0.309558,-0.064486},
+  {-0.027012,-1.213059},
+  {0.155906,-0.785986},
+  {-0.021507,-0.082515},
+  {1.588522,-1.195031},
+  {-0.385961,-0.717514},
+  {0.813259,0.823171},
+  {1.542545,-0.583962},
+  {0.699293,1.152578},
+  {-2.520775,-0.740568},
+  {1.650931,0.444675},
+  {-0.894331,-1.449709},
+  {-0.606002,-0.786614},
+  {0.612772,0.153705},
+  {-0.921274,0.922913},
+  {0.440139,0.658577},
+  {-0.229417,0.728289},
+  {1.547479,-2.279597},
+  {-0.319338,-0.157973},
+  {-1.461973,1.054925},
+  {-0.679512,-0.422229},
+  {-0.320076,-0.624900},
+  {-0.272455,-0.652699},
+  {-0.050571,-0.713983},
+  {-0.389856,-0.423589},
+  {-0.973979,0.062857},
+  {1.550694,-0.360476},
+  {0.159432,-0.127434},
+  {-0.372704,0.494970},
+  {0.300625,-0.256622},
+  {-1.003412,0.402113},
+  {-0.075613,-1.686128},
+  {0.482382,-0.480330},
+  {0.093242,-0.754616},
+  {0.281740,0.184726},
+  {-1.393960,-0.547393},
+  {0.536805,-0.148686},
+  {-0.465176,0.255458},
+  {0.306821,0.035537},
+  {0.559831,-0.109144},
+  {-0.714140,0.108895},
+  {0.217559,0.447498},
+  {-0.314098,-0.724385},
+  {-1.492888,-0.993242},
+  {-0.428441,-0.227405},
+  {0.188548,0.658179},
+  {0.768091,1.556233},
+  {-1.545457,-1.086941},
+  {0.140440,0.092669},
+  {0.537909,-0.495652},
+  {0.332552,-0.612271},
+  {-0.511223,-0.340514},
+  {0.079385,-0.114250},
+  {-1.463661,0.057599},
+  {0.223999,0.976185},
+  {-0.543545,0.027883},
+  {0.979747,0.489620},
+  {-1.192039,-0.798037},
+  {0.730126,-0.056639},
+  {-0.267151,0.693524},
+  {0.558097,0.153657},
+  {-0.696618,-1.338386},
+  {-0.909832,-0.096288},
+  {0.882699,0.742963},
+  {-0.275874,-0.809979},
+  {-0.053137,-0.168546},
+  {-0.422878,-0.367399},
+  {1.557298,0.459112},
+  {0.246203,-1.167259},
+  {-0.504330,-0.532256},
+  {0.987550,-0.885807},
+  {0.683296,-0.854008},
+  {-0.999180,0.227098},
+  {-0.668949,-0.025123},
+  {0.025665,-0.317833},
+  {1.113571,0.491572},
+  {-0.168884,1.194192},
+  {0.093188,-1.044563},
+  {1.753660,-0.163939},
+  {0.555963,-0.609948},
+  {0.794400,0.059530},
+  {-0.335538,1.145340},
+  {-0.230857,-0.288830},
+  {-0.449282,0.390382},
+  {0.306169,0.184478},
+  {-0.346556,-0.363817},
+  {-0.831726,0.067839},
+  {1.276276,-0.466759},
+  {0.244800,0.473109},
+  {-0.215391,-0.292773},
+  {-0.273257,0.201723},
+  {0.842924,-0.698762},
+  {-0.729074,0.256315},
+  {-1.456625,0.252573},
+  {0.559147,-0.282695},
+  {0.994685,0.128463},
+  {0.300242,-0.524755},
+  {0.229392,-0.252261},
+  {-0.262222,1.375848},
+  {-0.629900,0.580724},
+  {-0.886522,0.229244},
+  {0.175535,-0.159406},
+  {-0.005415,0.158939},
+  {0.950522,0.379940},
+  {0.346992,0.559263},
+  {-0.822353,0.315018},
+  {1.106625,-0.737253},
+  {-0.252764,-0.041978},
+  {-0.652043,1.078668},
+  {0.544128,-0.877090},
+  {-0.435260,-0.777845},
+  {-0.142025,0.692931},
+  {-0.031940,-0.162408},
+  {-0.737664,0.759069},
+  {0.018416,-0.910539},
+  {0.501767,0.015715},
+  {-0.525217,-0.909641},
+  {0.502059,1.002820},
+  {0.550277,0.890858},
+  {0.563253,-0.901443},
+  {-0.482929,-0.468226},
+  {0.459780,-1.053824},
+  {0.679393,-0.444330},
+  {-1.560609,0.500156},
+  {0.326860,-0.233930},
+  {0.014115,1.226398},
+  {-0.841667,0.256632},
+  {-0.986458,0.214088},
+  {0.561778,-0.293625},
+  {-0.166624,-0.623391},
+  {0.072308,-1.647830},
+  {0.261475,0.207571},
+  {-0.439805,-0.515374},
+  {-0.903760,0.247456},
+  {-0.992315,-0.455678},
+  {-0.736917,-0.314349},
+  {-0.760237,-0.334644},
+  {-0.808025,0.764268},
+  {0.962557,-0.746572},
+  {-0.497432,0.389293},
+  {-0.627429,0.078673},
+  {0.281879,-0.521353},
+  {-0.041629,0.996509},
+  {0.148478,-0.832781},
+  {0.241113,0.180056},
+  {0.427418,-1.070871},
+  {-0.528049,-0.483790},
+  {-0.523555,-0.270324},
+  {-0.304426,-0.037406},
+  {-0.137959,1.438044},
+  {0.928138,-0.431107},
+  {0.158206,0.475620},
+  {0.290347,-0.571426},
+  {0.518227,-0.212278},
+  {1.434704,-0.008646},
+  {0.870633,0.309615},
+  {-0.408402,-0.358914},
+  {-0.932732,1.867362},
+  {-1.106557,0.682544},
+  {0.700628,0.050873},
+  {0.606759,0.318505},
+  {1.100808,0.865530},
+  {1.167061,0.859812},
+  {-0.457106,0.360329},
+  {-0.412289,0.264824},
+  {0.121729,0.471512},
+  {-1.263924,0.036896},
+  {0.592224,-0.981550},
+  {-1.358297,-1.589214},
+  {0.370305,0.206402},
+  {-0.033672,-0.610428},
+  {0.084157,-1.167364},
+  {-0.925039,0.239143},
+  {0.529815,1.166401},
+  {0.059166,0.526304},
+  {-1.093501,1.010147},
+  {1.095547,-0.668412},
+  {-0.013464,-0.212740},
+  {0.318854,0.079713},
+  {-0.582878,0.209336},
+  {0.654810,0.042878},
+  {1.084759,0.085261},
+  {-0.816288,0.517988},
+  {-0.922044,-0.145496},
+  {-0.413527,-0.094974},
+  {0.921929,0.223829},
+  {0.834340,-0.632027},
+  {0.740097,0.472727},
+  {0.109634,-0.761616},
+  {0.181177,0.801596},
+  {-0.139230,0.351644},
+  {-0.919758,1.187038},
+  {-0.538770,-0.565291},
+  {1.101719,0.094469},
+  {0.063713,1.074669},
+  {0.544651,-0.008236},
+  {-0.043402,-0.182157},
+  {-0.337167,-0.066716},
+  {-0.942704,-0.275433},
+  {-1.247517,0.659809},
+  {0.260576,-0.850054},
+  {0.328842,-0.795337},
+  {-1.158718,0.621543},
+  {0.696945,-1.559381},
+  {-0.387067,-0.638698},
+  {-0.196632,0.228895},
+  {0.300199,0.872357},
+  {0.989715,1.032305},
+  {-0.595253,0.281982},
+  {-0.591831,-0.041140},
+  {0.274069,-0.351900},
+  {-0.204608,-0.274791},
+  {0.111010,1.228848},
+  {-1.030237,-0.321911},
+  {0.451188,-0.908440},
+  {-1.157873,-1.048536},
+  {-0.773016,-0.742834},
+  {-0.068020,0.052725},
+  {0.424745,-0.757197},
+  {-0.495433,-0.890633},
+  {0.095193,-0.673641},
+  {-0.838353,0.958686},
+  {-0.070324,0.364606},
+  {0.240110,-0.379039},
+  {0.814811,0.773006},
+  {-0.123048,0.360797},
+  {-0.383944,-0.049565},
+  {-0.384357,0.170201},
+  {0.027846,-0.520829},
+  {0.509019,-0.721829},
+  {1.510086,-0.121824},
+  {0.461037,-0.152050},
+  {-0.062760,0.456919},
+  {0.903696,-0.632184},
+  {0.147880,-1.655441},
+  {0.107131,0.254212},
+  {-1.168225,0.436568},
+  {1.645891,0.720458},
+  {0.637719,-0.054386},
+  {-0.674512,-0.595368},
+  {-1.647293,-0.454644},
+  {-1.427878,-1.542565},
+  {-1.299486,-0.638739},
+  {-0.789832,0.890510},
+  {-0.971617,0.239988},
+  {1.162886,0.122570},
+  {0.296613,0.157020},
+  {-0.651558,-1.195472},
+  {-0.483987,-0.676177},
+  {-1.459346,0.226026},
+  {-1.565833,-0.705405},
+  {0.562608,-0.783332},
+  {-0.335643,0.629401},
+  {0.601555,-0.527161},
+  {0.172194,-0.279522},
+  {1.396232,1.176078},
+  {1.057625,-0.239732},
+  {0.925509,-0.621106},
+  {-0.112643,-0.176105},
+  {-0.224907,-0.088044},
+  {-0.615717,0.351970},
+  {-1.022447,-0.343888},
+  {-0.611137,0.278950},
+  {-0.611510,-0.059484},
+  {-0.585823,-0.678989},
+  {-0.601954,-0.562345},
+  {-0.262591,1.266941},
+  {-0.772093,0.174441},
+  {-0.587666,0.893304},
+  {0.111368,1.608418},
+  {0.714706,-0.534446},
+  {-0.771247,0.120513},
+  {0.318155,0.438540},
+  {2.023913,0.190916},
+  {-0.212721,0.773555},
+  {0.232401,0.319443},
+  {-0.251844,-1.318009},
+  {0.162669,0.403618},
+  {0.827621,-0.529870},
+  {0.250448,-1.073482},
+  {0.059679,-0.063302},
+  {-0.194909,0.064858},
+  {0.480359,0.527630},
+  {0.037879,0.460448},
+  {0.486415,-0.957618},
+  {0.451010,-0.068816},
+  {0.968128,0.192947},
+  {0.831207,-0.164804},
+  {0.144330,-1.177113},
+  {-1.046468,-0.117025},
+  {1.453514,0.529669},
+  {0.462780,0.519148},
+  {0.355027,0.727646},
+  {0.355796,0.311839},
+  {1.776668,0.186074},
+  {-1.419462,-0.435581},
+  {-0.360595,-0.117783},
+  {-0.309289,0.349530},
+  {-0.530039,-0.873192},
+  {-0.106943,0.925020},
+  {1.306105,0.027449},
+  {0.580964,0.705161},
+  {1.478512,-0.101863},
+  {-0.202531,0.738568},
+  {-0.493564,-0.930668},
+  {0.268006,0.343200},
+  {0.459762,1.566772},
+  {-0.160910,0.379268},
+  {0.629888,-0.503718},
+  {1.381070,-0.364317},
+  {0.307948,-0.047268},
+  {0.796512,-0.935058},
+  {-0.700082,-0.972416},
+  {-0.298262,-0.605478},
+  {-0.323136,1.541209},
+  {-0.195020,0.416722},
+  {-0.086115,0.749763},
+  {0.435675,-0.521759},
+  {-0.104943,-0.146577},
+  {1.092303,0.546935},
+  {0.274549,0.086542},
+  {0.505962,0.274669},
+  {-0.720219,-0.028282},
+  {0.761485,0.999235},
+  {0.953266,0.149321},
+  {0.633826,0.108976},
+  {-0.930898,0.531887},
+  {-0.401657,1.460128},
+  {-1.032822,0.380031},
+  {0.199604,0.147336},
+  {-0.633607,-0.055812},
+  {-0.316084,-0.492567},
+  {-0.775544,-0.393868},
+  {-0.304902,0.496941},
+  {0.587243,0.404586},
+  {0.535787,-0.290660},
+  {0.526786,-0.492909},
+  {0.032885,-0.335402},
+  {0.254548,0.025119},
+  {-0.007256,0.956603},
+  {-0.781701,0.182978},
+  {-0.594395,-0.051752},
+  {1.137163,0.417077},
+  {-0.725425,1.703746},
+  {0.203050,-0.823786},
+  {-0.093223,-0.599492},
+  {-0.171074,0.434182},
+  {0.446139,-1.024946},
+  {1.307526,-0.924091},
+  {0.165343,-0.061759},
+  {0.847232,-0.364522},
+  {-1.687820,-0.966855},
+  {0.367350,1.007379},
+  {0.462134,-0.629192},
+  {1.480619,0.308647},
+  {-0.480776,-0.412441},
+  {-0.032728,0.426328},
+  {-0.723946,0.349359},
+  {-0.695635,0.225437},
+  {0.093643,0.801008},
+  {-1.148551,-0.246205},
+  {-0.049321,-0.459364},
+  {-0.241512,1.553192},
+  {1.138608,1.302721},
+  {0.263139,-0.527765},
+  {0.172326,0.638467},
+  {-0.425811,0.438227},
+  {-0.932956,0.082939},
+  {-0.145653,-0.835906},
+  {0.099492,-1.396676},
+  {-0.730089,-1.456065},
+  {0.328898,0.922454},
+  {-0.479136,0.168375},
+  {-0.693307,-1.117508},
+  {0.434907,0.255777},
+  {0.159500,-0.075837},
+  {0.606847,-1.786357},
+  {0.114103,-0.890503},
+  {0.475339,-0.639335},
+  {-0.501279,0.909314},
+  {-0.461021,0.340318},
+  {-2.371022,0.240045},
+  {-0.663024,-0.078565},
+  {0.408487,0.747418},
+  {-0.039952,0.544522},
+  {-0.346095,-1.181014},
+  {1.313543,1.313791},
+  {-0.286968,0.049342},
+  {-0.985057,0.416389},
+  {0.567016,-0.890193},
+  {-0.029613,-1.097792},
+  {-0.274942,1.279869},
+  {0.840626,-0.071335},
+  {1.103612,-0.346434},
+  {-0.971668,0.314411},
+  {-0.401788,-0.159312},
+  {0.876157,-1.020020},
+  {-0.187758,-0.633080},
+  {-0.737539,0.950549},
+  {-0.537099,1.220313},
+  {-0.354796,0.504951},
+  {0.516333,0.303805},
+  {0.744535,-0.050407},
+  {-0.305368,0.196347},
+  {-0.539320,-0.584686},
+  {0.578355,0.192718},
+  {-1.251327,0.031665},
+  {-0.988681,-1.128213},
+  {-1.076868,1.127315},
+  {-0.652836,-0.331953},
+  {-0.922967,0.220209},
+  {0.721116,-0.345270},
+  {0.102160,-0.184497},
+  {0.724131,-0.729485},
+  {0.311939,1.406437},
+  {-0.687354,-0.482095},
+  {-0.746110,0.490688},
+  {-0.290505,-0.930634},
+  {1.203664,0.171541},
+  {0.798127,0.241126},
+  {-0.347300,0.167841},
+  {-0.383096,0.527781},
+  {0.231403,-0.662014},
+  {1.208195,-0.842100},
+  {0.118811,0.382395},
+  {-0.971162,-0.657731},
+  {-0.109055,-1.321417},
+  {-0.166172,1.000512},
+  {0.245685,0.853006},
+  {1.179090,0.148636},
+  {-0.722005,0.218807},
+  {-0.356529,0.394081},
+  {0.283431,-1.474497},
+  {-0.528565,-0.181279},
+  {-0.309054,-0.447532},
+  {-0.302059,-0.835447},
+  {0.063289,0.197125},
+  {0.873344,0.283293},
+  {-0.827399,0.327898},
+  {-1.445307,0.015543},
+  {1.134014,0.449569},
+  {0.026380,-0.550346},
+  {-0.107964,0.656922},
+  {0.551898,-0.361890},
+  {1.354513,-1.238748},
+  {0.259696,1.783583},
+  {-0.954792,0.686831},
+  {-0.745327,-0.404158},
+  {0.454100,-0.837450},
+  {0.087043,-0.950885},
+  {0.505512,0.460524},
+  {0.404887,0.789404},
+  {-0.037236,0.441461},
+  {1.725802,0.267412},
+  {0.797967,0.244751},
+  {-0.978130,0.515460},
+  {0.542536,-0.075439},
+  {0.712379,-0.497695},
+  {-0.212806,0.608145},
+  {0.577898,-0.192766},
+  {0.489932,0.990213},
+  {0.119053,-0.729816},
+  {1.097182,-0.576013},
+  {-1.201042,-0.794151},
+  {-0.120795,0.066962},
+  {0.146414,0.603197},
+  {0.026528,-0.603082},
+  {-0.800504,0.268076},
+  {-0.343166,-0.407044},
+  {-0.102762,-0.303068},
+  {0.129492,1.346782},
+  {-0.258398,0.169313},
+  {1.243914,-0.592895},
+  {1.095122,0.260779},
+  {-0.600781,-0.189894},
+  {0.240113,0.082414},
+  {0.353061,0.355369},
+  {0.420819,-0.911021},
+  {0.696589,0.394239},
+  {-0.682780,0.358780},
+  {0.063955,-1.517855},
+  {-0.322178,-0.074134},
+  {-0.974101,1.406756},
+  {-0.526017,-0.353056},
+  {-0.640417,0.340377},
+  {-0.182126,-0.411452},
+  {-0.488776,-1.599695},
+  {1.517429,0.767395},
+  {0.603698,-0.721522},
+  {0.541078,-0.821337},
+  {0.110168,0.163595},
+  {0.212353,-0.539387},
+  {0.117418,-0.754495},
+  {-0.155305,-0.255334},
+  {-0.119331,0.141361},
+  {-1.467100,-0.792509},
+  {0.202781,0.268023},
+  {-0.814643,-0.407787},
+  {0.137034,-0.791640},
+  {-0.789811,-0.493989},
+  {-0.336780,-0.653000},
+  {-0.759226,-0.386969},
+  {0.455847,0.617339},
+  {1.664504,-0.591428},
+  {-0.206955,0.421407},
+  {-0.567116,0.215310},
+  {-0.634151,-0.216379},
+  {-0.474751,0.577085},
+  {0.580540,0.007682},
+  {0.431102,-0.313646},
+  {0.037617,-0.541906},
+  {0.586028,0.437426},
+  {1.122127,1.192700},
+  {0.679301,0.617392},
+  {-0.266514,0.750701},
+  {1.021989,0.573764},
+  {-0.471908,-1.137463},
+  {-0.275688,-1.347824},
+  {-0.260820,0.857808},
+  {-0.353317,-0.507878},
+  {1.482158,-0.115137},
+  {0.989099,-1.264611},
+  {-0.181237,-0.731317},
+  {-1.272231,0.000604},
+  {-0.050286,-0.518716},
+  {0.906532,0.073988},
+  {-0.725282,-0.708613},
+  {1.130826,0.492829},
+  {0.382025,0.118885},
+  {-0.289855,0.327266},
+  {-0.356868,-0.127456},
+  {-0.497037,0.347544},
+  {0.916516,-0.011213},
+  {0.795788,0.833036},
+  {-1.108708,0.654990},
+  {1.098447,-0.380100},
+  {-0.699273,0.774193},
+  {0.342752,-0.535842},
+  {0.047643,-0.227671},
+  {1.274331,0.341689},
+  {0.895537,-0.407677},
+  {-0.778889,-0.038155},
+  {0.698568,0.098739},
+  {1.916364,-0.661903},
+  {-0.845148,0.287349},
+  {0.837011,-1.241308},
+  {0.022716,-0.396469},
+  {-0.020420,-0.034983},
+  {-0.285681,-0.753360},
+  {-0.118651,-1.527316},
+  {-0.176143,0.446362},
+  {0.130017,-0.415744},
+  {0.318507,0.552840},
+  {-0.603890,0.207048},
+  {-0.523459,0.105243},
+  {-0.002344,-0.410590},
+  {0.476249,-1.748434},
+  {0.110030,-0.295667},
+  {-0.776678,-0.699187},
+  {-0.336088,0.120044},
+  {-0.132220,0.564894},
+  {-0.400230,-1.465552},
+  {-0.899290,0.326598},
+  {-1.442301,-0.087643},
+  {-0.008753,-0.630739},
+  {0.390787,0.192346},
+  {-0.340743,-0.440807},
+  {-1.539744,1.205671},
+  {0.627614,0.398445},
+  {0.127486,0.357655},
+  {0.135552,0.764774},
+  {0.518036,-0.218960},
+  {1.049276,-0.090579},
+  {-0.008401,1.454761},
+  {0.003514,0.918229},
+  {0.302454,0.976231},
+  {-0.961992,-0.017294},
+  {0.076837,0.668940},
+  {-0.348232,0.509916},
+  {-1.436588,0.235003},
+  {-0.084113,-0.570737},
+  {0.635977,0.515143},
+  {-0.580761,0.004320},
+  {-0.130124,0.718512},
+  {-1.064332,0.805427},
+  {1.314300,-0.425192},
+  {-0.597376,0.040773},
+  {-0.369787,0.951658},
+  {1.179303,0.302642},
+  {0.309178,0.951243},
+  {0.683143,-0.691633},
+  {0.595706,-0.308229},
+  {1.452309,0.693933},
+  {-0.597845,0.801738},
+  {0.458518,-0.343717},
+  {-0.149173,-0.241056},
+  {0.979689,0.240095},
+  {-0.599037,0.543307},
+  {0.354471,-1.145843},
+  {-0.020165,-0.398078},
+  {-0.123823,1.399765},
+  {0.024307,0.255874},
+  {0.390943,0.200198},
+  {0.660994,-0.236146},
+  {0.874927,0.787643},
+  {0.171618,0.136452},
+  {0.225134,0.175814},
+  {-1.009673,0.213737},
+  {0.778509,-0.536733},
+  {0.659917,-1.701921},
+  {-1.047737,-0.614887},
+  {-0.561108,0.215661},
+  {-0.185832,-0.245792},
+  {-0.486231,0.531170},
+  {0.116419,-0.145595},
+  {0.019939,-0.695158},
+  {0.144234,-0.507506},
+  {-0.396990,-0.833085},
+  {0.375825,-1.907635},
+  {-0.080535,0.196175},
+  {0.007163,0.589929},
+  {-1.106312,-0.916138},
+  {1.084560,-1.289281},
+  {0.700913,-0.454858},
+  {1.690164,-0.645198},
+  {0.472295,0.365814},
+  {-0.354035,-1.187006},
+  {-0.363422,-0.700427},
+  {-0.409595,-0.297748},
+  {0.222860,-0.488023},
+  {1.154380,-0.023766},
+  {-0.572994,0.995388},
+  {-0.522744,0.915831},
+  {-0.102298,0.075968},
+  {-1.113661,0.277819},
+  {-0.541258,0.942888},
+  {0.144149,-1.421493},
+  {-0.813628,0.518374},
+  {0.438114,-0.583365},
+  {-0.306953,-0.083300},
+  {-0.965428,-0.187021},
+  {-1.651694,0.301327},
+  {-0.358049,0.160427},
+  {0.494740,0.212273},
+  {-0.475793,0.129843},
+  {-0.513566,0.206706},
+  {-0.789498,-0.454014},
+  {-0.506331,-0.677233},
+  {-1.191360,-0.684613},
+  {-0.473632,-0.505620},
+  {1.704961,-0.000282},
+  {-0.748426,0.044751},
+  {0.722466,-0.271562},
+  {-0.114380,-0.029615},
+  {0.881983,0.732634},
+  {-2.466091,0.797042},
+  {0.107247,-1.069177},
+  {0.365094,-0.240360},
+  {0.860761,-0.392398},
+  {0.419712,1.024297},
+  {-0.733678,-0.114491},
+  {-0.387299,-0.698591},
+  {-1.111876,-0.894044},
+  {-0.338478,0.432863},
+  {0.374858,0.592964},
+  {0.132022,-0.172552},
+  {-0.566581,0.486986},
+  {-0.361814,-0.127256},
+  {-0.495429,-1.119817},
+  {-0.373163,0.277704},
+  {-0.451895,-0.150489},
+  {0.676212,0.462474},
+  {0.731097,0.067339},
+  {-0.391580,-0.221534},
+  {0.702811,0.805510},
+  {0.306927,-0.330470},
+  {0.202033,-0.281253},
+  {0.670677,-1.640630},
+  {-0.171426,0.129238},
+  {0.855865,-0.001158},
+  {0.902835,-0.314898},
+  {0.258288,-0.817972},
+  {-0.246663,-0.050172},
+  {-1.298989,1.057827},
+  {-0.194878,-0.869015},
+  {-0.989629,-0.909738},
+  {-0.566145,-0.028838},
+  {-0.537190,-0.250192},
+  {1.007348,0.083241},
+  {0.351506,-0.080267},
+  {0.167228,-0.274140},
+  {0.523975,-0.383455},
+  {-0.693140,-0.400584},
+  {-1.377034,-0.099976},
+  {0.687119,0.508089},
+  {0.624748,-0.713680},
+  {0.524963,0.852304},
+  {-0.365119,1.391765},
+  {-0.098955,-0.773518},
+  {0.099686,0.092521},
+  {-0.191519,0.113134},
+  {-0.246630,-0.849187},
+  {0.372718,-0.028201},
+  {0.209208,0.168457},
+  {0.531034,0.810682},
+  {-2.065181,-0.403745},
+  {1.662412,-1.025271},
+  {0.116164,-1.358371},
+  {0.871266,0.684274},
+  {-0.601819,0.436820},
+  {0.379071,-0.950469},
+  {-1.481672,1.328396},
+  {-0.215309,0.881097},
+  {1.543692,-1.302871},
+  {0.566876,-0.346706},
+  {-0.107790,0.187282},
+  {-0.050962,0.305967},
+  {2.234456,0.245861},
+  {0.922211,0.315870},
+  {0.170718,0.332505},
+  {-0.173235,0.269735},
+  {-0.034479,-0.147379},
+  {-0.910476,0.549261},
+  {-1.482071,0.073635},
+  {-1.006192,-0.257727},
+  {1.380736,0.159414},
+  {0.133536,-0.518567},
+  {0.452510,-0.297029},
+  {0.506554,0.634800},
+  {-0.223515,-0.113593},
+  {1.640303,-0.303890},
+  {0.451081,-0.579022},
+  {-0.423077,-0.310128},
+  {-0.515610,0.197095},
+  {1.449878,-0.575191},
+  {0.595091,-0.861876},
+  {0.467010,0.214356},
+  {1.126815,-0.412791},
+  {-0.768978,0.928791},
+  {0.662096,0.992854},
+  {-0.870112,0.867863},
+  {-0.444760,0.695527},
+  {0.545433,0.548246},
+  {0.900893,1.440884},
+  {1.009321,-1.093170},
+  {0.002783,-0.661035},
+  {0.446845,-0.962453},
+  {1.071007,0.104193},
+  {0.701488,0.155886},
+  {-1.495756,-1.595266},
+  {0.037920,-0.027757},
+  {-0.816584,0.442122},
+  {1.024597,0.061760},
+  {0.372463,0.656436},
+  {0.193900,-1.113707},
+  {0.702296,0.063060},
+  {-0.387018,0.640494},
+  {0.472535,0.526097},
+  {-0.113295,-0.461936},
+  {-0.549302,-0.072353},
+  {0.113877,1.728784},
+  {-0.503031,0.465992},
+  {-1.800512,0.344290},
+  {-0.291058,0.191364},
+  {-1.383239,-0.639046},
+  {0.301438,0.939880},
+  {-0.887944,0.532416},
+  {-0.337686,-1.497391},
+  {-0.273128,0.170892},
+  {-0.187554,1.292625},
+  {-0.335620,0.813804},
+  {0.302649,0.115870},
+  {-0.125463,0.244516},
+  {0.775593,0.754042},
+  {0.726695,-0.656969},
+  {0.888387,-1.134760},
+  {1.275522,-0.250979},
+  {-0.736736,-0.023197},
+  {-0.722655,0.071534},
+  {0.398133,-0.225856},
+  {-0.158094,-0.713822},
+  {-0.187789,1.530984},
+  {0.066136,-0.285781},
+  {0.337437,0.069203},
+  {-1.522060,0.359290},
+  {-0.410925,0.715260},
+  {-0.348957,0.792795},
+  {-0.822869,0.817856},
+  {0.215875,-0.611351},
+  {-0.606455,0.320282},
+  {1.436453,-0.107341},
+  {-0.330349,-1.194834},
+  {0.572256,1.303348},
+  {1.090097,1.118251},
+  {0.745744,-0.906311},
+  {-1.122036,-0.363927},
+  {-0.352830,0.069443},
+  {0.173709,0.298217},
+  {1.233522,0.305900},
+  {0.226477,-0.043980},
+  {-0.722420,0.493256},
+  {0.557195,0.058823},
+  {-1.094416,-0.312172},
+  {0.071648,0.977559},
+  {-0.387061,0.773792},
+  {0.338082,-0.019251},
+  {0.163224,-0.330960},
+  {0.610427,0.371691},
+  {0.323763,-0.522994},
+  {-0.668372,-0.370236},
+  {1.242604,0.090453},
+  {-1.050305,-0.440150},
+  {0.388379,-0.214487},
+  {-0.479460,-0.280957},
+  {-0.581688,0.708546},
+  {-0.651918,-0.699252},
+  {-1.289294,0.894307},
+  {0.430920,1.134885},
+  {-0.140695,0.119391},
+  {-0.113397,0.141629},
+  {-0.224160,-0.849461},
+  {0.145152,1.010905},
+  {0.114341,0.319432},
+  {-0.731503,0.963791},
+  {-0.805791,-0.234161},
+  {-0.097786,-0.078454},
+  {1.247790,0.056807},
+  {-0.066401,-0.334968},
+  {0.675039,-0.744820},
+  {-0.181113,-0.290322},
+  {0.651336,0.530368},
+  {-1.249633,-0.321314},
+  {-0.289785,0.448466},
+  {0.666290,1.196834},
+  {0.623286,-0.328105},
+  {-0.469083,0.311728},
+  {-0.641303,-0.664674},
+  {-0.033907,-0.670533},
+  {0.177868,1.697506},
+  {-0.216707,0.202837},
+  {-0.186939,-0.529367},
+  {0.022609,-0.126800},
+  {0.203477,-0.579855},
+  {-0.230490,1.011908},
+  {0.162921,1.168193},
+  {0.885725,-0.666452},
+  {0.277346,0.026881},
+  {0.127636,-0.291993},
+  {0.343859,0.254767},
+  {0.937021,-0.240389},
+  {-0.450499,-0.519208},
+  {0.026306,0.871227},
+  {-0.532201,0.361956},
+  {0.510303,-0.387441},
+  {-0.746218,0.107938},
+  {-0.043113,0.416857},
+  {-0.765734,-0.057674},
+  {-0.976013,-0.471322},
+  {-0.608322,-0.386790},
+  {-0.153345,-0.142873},
+  {0.282707,-0.174705},
+  {0.908893,-0.288510},
+  {1.248578,-0.267686},
+  {-0.733607,-0.318778},
+  {0.711804,0.106524},
+  {0.730638,-0.818837},
+  {-0.143297,0.775292},
+  {0.826449,-0.764265},
+  {-1.053740,0.429313},
+  {0.093451,-0.285474},
+  {0.092797,-1.313155},
+  {-0.990341,-0.497315},
+  {0.566588,0.912216},
+  {-0.641365,-1.513570},
+  {-0.399701,0.419908},
+  {0.550336,0.454210},
+  {1.130919,-1.011306},
+  {-0.648588,0.724713},
+  {1.530720,-0.329322},
+  {0.240109,0.297342},
+  {-0.803036,-0.672687},
+  {0.558095,0.210214},
+  {-0.415771,0.335389},
+  {-0.446871,-0.080301},
+  {0.439153,0.420859},
+  {0.454300,-0.120721},
+  {0.210916,-0.112178},
+  {-0.409692,-0.248721},
+  {-0.879181,-0.650745},
+  {0.314275,0.157443},
+  {-0.127992,0.459773},
+  {0.189201,-0.437353},
+  {-0.199317,0.335634},
+  {0.926867,-1.219475},
+  {0.990475,0.115756},
+  {-0.596768,0.519271},
+  {0.544668,0.177830},
+  {0.025311,0.718018},
+  {0.865983,-0.396329},
+  {0.931238,0.051218},
+  {-1.306796,0.890281},
+  {-0.038267,0.417608},
+  {0.423411,0.011136},
+  {-0.591386,-0.028572},
+  {-0.659057,-0.868477},
+  {-0.454503,-0.183610},
+  {-1.296091,0.623354},
+  {-0.369003,-1.032546},
+  {0.687142,-0.539728},
+  {0.702910,0.311785},
+  {0.486632,-0.654871},
+  {-0.698156,0.479333},
+  {-0.286491,0.023513},
+  {-0.061237,0.264710},
+  {0.815363,-0.724906},
+  {0.080431,0.452235},
+  {0.209167,-0.366842},
+  {0.238600,-1.015582},
+  {0.236585,1.119290},
+  {0.115878,-0.511488},
+  {0.417193,-0.342133},
+  {-0.132619,-0.383681},
+  {-0.309108,-0.467185},
+  {0.389856,-0.296845},
+  {0.862805,-0.845385},
+  {0.163740,-1.328876},
+  {0.841628,-1.134586},
+  {-1.314638,0.983453},
+  {0.007594,-0.151851},
+  {0.491880,0.589396},
+  {0.410562,-0.533815},
+  {0.152744,-0.382076},
+  {-0.814165,-0.726665},
+  {-1.054786,0.399620},
+  {-0.604055,0.219815},
+  {0.195637,-1.204522},
+  {-0.218163,0.389220},
+  {-1.060887,-0.365853},
+  {0.076152,0.972619},
+  {0.106557,-0.550138},
+  {0.350506,-0.580934},
+  {0.899491,-1.202793},
+  {0.006987,-0.237220},
+  {-0.621779,0.109460},
+  {0.758860,0.378667},
+  {0.665073,0.149904},
+  {0.514973,-1.076146},
+  {-0.531363,-0.151537},
+  {-0.160327,-0.372274},
+  {1.439986,-1.868230},
+  {0.189739,0.119885},
+  {0.203151,1.214735},
+  {0.227369,-0.449251},
+  {-0.320953,1.173650},
+  {0.362700,-0.413635},
+  {0.104156,0.742685},
+  {0.786895,0.217765},
+  {0.461444,-0.383361},
+  {-0.026425,0.050263},
+  {-0.700833,-0.176479},
+  {0.516268,-0.266494},
+  {0.542822,-0.196286},
+  {0.972150,0.282374},
+  {0.373345,-1.661969},
+  {0.848982,-0.275416},
+  {-0.147993,0.557783},
+  {-1.235018,-0.425926},
+  {-0.990208,-0.819959},
+  {-0.502916,0.897826},
+  {-0.963431,0.100756},
+  {-0.539236,-0.495820},
+  {0.043163,-0.313743},
+  {0.268113,-0.401802},
+  {0.094456,0.929705},
+  {0.434827,0.666465},
+  {-0.285961,0.540364},
+  {-0.067659,0.148652},
+  {-0.343734,1.625959},
+  {0.941489,-0.334072},
+  {-0.339727,-0.526445},
+  {0.793149,0.946932},
+  {-0.398235,0.623877},
+  {0.264790,-0.715621},
+  {-1.011724,0.322794},
+  {1.384937,0.455970},
+  {1.454257,0.048507},
+  {-0.306816,-1.428050},
+  {0.370468,0.733515},
+  {0.850482,0.067026},
+  {-0.026520,0.315161},
+  {0.553367,-1.038959},
+  {-1.381139,0.169341},
+  {-0.126396,0.774954},
+  {0.579820,-0.324341},
+  {0.690277,-0.552866},
+  {0.042603,0.250999},
+  {0.234958,-0.328548},
+  {-0.034987,-0.427424},
+  {0.017550,1.027859},
+  {0.639405,0.074327},
+  {-1.079853,0.773206},
+  {-0.255093,-0.538056},
+  {-0.516779,0.552364},
+  {0.588249,-0.122769},
+  {-0.180270,-0.526765},
+  {0.281459,-0.573820},
+  {-0.597178,0.884251},
+  {-1.459452,0.521668},
+  {0.475132,0.670896},
+  {0.364260,-0.003726},
+  {0.162263,1.430702},
+  {1.002323,1.191997},
+  {0.593734,1.105144},
+  {0.455673,-1.069412},
+  {-0.566892,-0.153912},
+  {-0.401493,0.730293},
+  {-0.616850,-0.357030},
+  {0.131704,0.877433},
+  {0.448159,0.531570},
+  {0.707994,0.388152},
+  {-1.120399,-1.558184},
+  {0.205040,0.110543},
+  {0.667577,0.900941},
+  {-1.023609,-0.438459},
+  {0.592556,-0.786459},
+  {-0.218398,-0.203380},
+  {0.274252,0.404389},
+  {-0.458191,1.011445},
+  {0.222179,0.858687},
+  {0.029628,-0.040130},
+  {-0.290997,-0.035703},
+  {0.309122,-1.492022},
+  {-1.010844,0.589316},
+  {-0.356162,0.305040},
+  {0.261650,0.718863},
+  {0.434287,0.022466},
+  {-0.076320,-0.343857},
+  {0.183141,1.026684},
+  {0.784650,0.184908},
+  {0.701212,0.267810},
+  {0.525909,1.299042},
+  {-1.685660,0.350329},
+  {-0.593831,-0.228072},
+  {0.017935,0.860203},
+  {0.840364,-1.130071},
+  {1.015367,1.442451},
+  {-0.901634,-0.746853},
+  {0.199565,-0.821338},
+  {-0.313785,0.748286},
+  {0.090435,0.856189},
+  {-0.393746,1.621984},
+  {-0.703148,0.813511},
+  {-1.461475,0.879518},
+  {0.943104,-0.598617},
+  {0.393415,-0.321067},
+  {0.352488,-0.808631},
+  {-0.262355,0.074378},
+  {0.444508,0.028535},
+  {-1.235967,0.087614},
+  {-0.366743,0.274720},
+  {-1.534213,1.187011},
+  {-1.288413,1.152383},
+  {-0.176366,0.392408},
+  {-0.479891,-1.289108},
+  {0.006065,-2.244152},
+  {-0.200774,0.584892},
+  {0.841201,0.359442},
+  {0.042903,0.605595},
+  {-0.050008,0.526026},
+  {0.545172,0.114942},
+  {-0.741202,0.452490},
+  {-0.662675,0.502251},
+  {-0.293925,0.361124},
+  {-0.174266,0.891888},
+  {0.214914,-0.044729},
+  {1.076459,-0.324856},
+  {0.028362,-0.712596},
+  {0.119129,0.420191},
+  {0.290109,-1.690392},
+  {-0.534984,-0.709829},
+  {0.928031,0.340022},
+  {0.329803,-0.001821},
+  {-0.789933,-0.997637},
+  {0.525651,-0.947355},
+  {0.800005,0.294846},
+  {-0.940716,-0.342722},
+  {1.153485,-0.757920},
+  {-0.372701,-0.015358},
+  {0.413703,0.474207},
+  {0.554610,-0.587293},
+  {0.609088,0.282538},
+  {-0.389165,-0.999838},
+  {-0.501062,0.425428},
+  {0.506568,0.864824},
+  {0.467536,0.041527},
+  {0.413553,-0.972673},
+  {-0.784710,-0.456333},
+  {-0.591675,-0.081141},
+  {-0.000096,-0.918489},
+  {-0.741971,-0.673887},
+  {0.423698,0.133942},
+  {-0.353825,-0.248892},
+  {0.265903,1.104794},
+  {1.155745,-0.487131},
+  {-1.230837,1.182218},
+  {-0.039358,-1.024105},
+  {-0.126243,-0.422831},
+  {0.083741,1.333631},
+  {-0.582043,-0.167835},
+  {-0.651064,-0.716060},
+  {-0.933496,1.031392},
+  {0.285776,0.119386},
+  {1.790267,1.839585},
+  {0.673148,-0.036901},
+  {0.060941,0.392402},
+  {0.439779,0.335930},
+  {0.482075,-0.508116},
+  {0.166439,-0.478669},
+  {1.468145,0.050076},
+  {0.697232,0.408675},
+  {-0.276139,0.399703},
+  {0.376897,-0.613126},
+  {0.465563,-1.169737},
+  {-1.834874,0.539662},
+  {-0.091337,0.444562},
+  {-0.997118,0.098997},
+  {-0.233274,-0.598737},
+  {-0.989027,-1.117883},
+  {0.624755,0.428710},
+  {-0.375702,-1.212512},
+  {-1.056685,0.388795},
+  {-0.909594,0.317522},
+  {-0.356905,-0.074151},
+  {0.524995,0.703629},
+  {0.314174,-0.403816},
+  {-0.491192,1.182237},
+  {-0.926085,-1.084090},
+  {-0.017806,0.842876},
+  {0.440742,-0.130747},
+  {0.272952,0.081986},
+  {0.441477,-0.697158},
+  {0.259341,-2.099767},
+  {0.831863,-0.033636},
+  {-0.502615,-1.206727},
+  {0.555998,0.859499},
+  {-2.056364,0.396201},
+  {0.341466,0.784581},
+  {0.343672,1.187463},
+  {1.274795,-0.151500},
+  {-0.628121,1.454649},
+  {0.565032,-0.448605},
+  {-0.207750,-0.820005},
+  {1.175663,0.211856},
+  {-1.633000,1.122887},
+  {-0.291601,2.700069},
+  {-0.622804,1.831482},
+  {-0.301059,0.509034},
+  {-0.427513,0.001459},
+  {-0.341017,-0.116875},
+  {0.022551,-0.314193},
+  {-0.918960,-0.674715},
+  {-0.129296,-0.117801},
+  {0.786287,-1.378251},
+  {-0.451442,-1.084505},
+  {0.942049,-0.109402},
+  {-0.219356,-0.655816},
+  {-0.878586,0.229613},
+  {0.675175,-0.893381},
+  {-0.932964,-1.161234},
+  {0.214065,-0.396179},
+  {-0.277875,1.353829},
+  {0.086688,-0.992670},
+  {0.266658,1.190433},
+  {-0.665654,0.447818},
+  {-1.073475,-0.902468},
+  {0.561274,1.066952},
+  {0.439581,1.398037},
+  {-0.038367,-0.253666},
+  {-0.180841,-0.607550},
+  {-0.663332,0.315716},
+  {-0.204138,-0.260854},
+  {1.300259,0.483273},
+  {0.488196,-1.506948},
+  {-1.576188,-0.122042},
+  {-0.161309,-0.070824},
+  {-0.163122,-0.342865},
+  {-0.647706,1.966371},
+  {-0.912235,-1.511959},
+  {0.246138,-0.881132},
+  {-0.400870,-0.146707},
+  {1.873068,-0.401651},
+  {-0.246960,1.020948},
+  {-0.309774,-0.749670},
+  {-1.658745,0.706234},
+  {0.137746,0.464169},
+  {-0.128249,1.229660},
+  {0.485569,-0.862653},
+  {-0.314748,-0.798912},
+  {0.596327,-2.260403},
+  {-0.739134,-0.774303},
+  {0.559885,2.133758},
+  {-0.378982,-0.458096},
+  {-0.645429,-0.411828},
+  {0.442957,0.412317},
+  {0.062638,-0.130068},
+  {0.913193,0.872129},
+  {-0.000645,-0.659925},
+  {-0.611296,0.051654},
+  {0.463594,0.106210},
+  {-0.172544,0.250975},
+  {-0.820128,0.059186},
+  {1.244089,-0.241306},
+  {-0.606408,0.162598},
+  {-0.516257,-0.453431},
+  {0.379360,-0.010924},
+  {1.694404,-0.098512},
+  {0.740398,-1.163674},
+  {-0.086404,0.808617},
+  {-0.788179,0.497859},
+  {0.518954,1.316377},
+  {-0.268101,-0.000552},
+  {-0.011397,0.127380},
+  {-0.776983,1.310111},
+  {1.155819,-0.536423},
+  {0.325867,0.129875},
+  {-0.305559,1.698206},
+  {1.469264,1.171590},
+  {0.052020,1.645200},
+  {-0.475098,0.752333},
+  {-0.478576,1.051189},
+  {0.209720,-0.846175},
+  {0.336027,1.281707},
+  {-0.457927,0.978607},
+  {0.434299,0.603314},
+  {0.819164,-0.707148},
+  {0.285992,0.200020},
+  {0.903948,0.841191},
+  {-0.374723,0.784422},
+  {0.270358,-0.432780},
+  {-1.131503,-0.204865},
+  {0.998721,-0.562161},
+  {2.709929,0.333403},
+  {0.277214,-0.599034},
+  {-1.049311,0.119009},
+  {-0.022257,-0.188019},
+  {1.186738,0.666140},
+  {0.855026,-0.173047},
+  {-0.518785,0.244153},
+  {1.443967,0.472201},
+  {0.268845,0.765957},
+  {-0.262575,-0.227543},
+  {-0.178477,-0.237919},
+  {0.718803,-1.198294},
+  {0.296576,-0.928266},
+  {-0.265587,0.333848},
+  {0.004683,0.050916},
+  {0.746835,-0.077362},
+  {-0.848756,0.639052},
+  {-0.435768,0.677006},
+  {-0.761960,-0.673618},
+  {0.483697,-0.006953},
+  {0.859446,0.342013},
+  {0.652033,1.150497},
+  {0.279404,0.172724},
+  {-1.654868,-0.062761},
+  {-0.628006,1.229600},
+  {0.434866,0.453249},
+  {0.674872,-0.018098},
+  {-0.880481,0.632858},
+  {0.357744,-1.100971},
+  {0.576850,-0.473425},
+  {1.084853,-0.458153},
+  {-0.135107,-0.068785},
+  {-0.519318,-1.097185},
+  {-0.391322,-0.857973},
+  {0.105697,0.637781},
+  {1.012647,0.768231},
+  {0.032431,-0.712690},
+  {-0.204606,-0.459269},
+  {0.385121,0.683265},
+  {0.360634,-0.324071},
+  {0.146076,-0.206186},
+  {-0.206886,-0.280858},
+  {0.331549,-0.657394},
+  {0.877392,0.663666},
+  {0.395278,0.505377},
+  {0.756041,0.859819},
+  {-0.571644,-0.580026},
+  {0.612494,-0.767403},
+  {0.440062,-0.276920},
+  {0.205130,0.951105},
+  {-0.082089,0.424510},
+  {-0.388500,-0.817454},
+  {-0.297097,-0.030734},
+  {0.564334,0.170313},
+  {-0.046735,-1.039128},
+  {0.236019,-0.606694},
+  {0.580484,0.228738},
+  {0.732596,1.402753},
+  {0.684455,0.312711},
+  {-0.114287,0.351727},
+  {0.132644,0.482891},
+  {-0.052996,0.413845},
+  {-0.092510,0.323390},
+  {-1.249163,0.744762},
+  {-0.144000,-0.150784},
+  {0.245751,-0.037541},
+  {-0.265020,0.824606},
+  {0.166448,-0.503386},
+  {0.221548,1.011519},
+  {0.705554,0.734803},
+  {-0.449412,0.766934},
+  {-0.041904,0.103437},
+  {-0.589535,0.745306},
+  {0.178707,0.543289},
+  {-0.049604,0.417483},
+  {-1.320194,0.671440},
+  {0.618327,0.293337},
+  {-0.035204,-0.955884},
+  {0.696789,0.975314},
+  {0.335561,-0.397880},
+  {-0.101238,-0.789334},
+  {-1.353433,0.224343},
+  {-1.536268,0.154368},
+  {0.290941,0.264984},
+  {0.054972,0.497049},
+  {0.249733,0.304852},
+  {0.072880,0.649790},
+  {-1.092497,-0.508302},
+  {-0.580980,-0.404179},
+  {0.684158,1.161387},
+  {1.027268,0.419341},
+  {-0.575905,0.422229},
+  {-0.586725,0.243471},
+  {1.044492,0.197131},
+  {-0.818624,-0.339106},
+  {1.028786,0.649399},
+  {0.128927,0.552989},
+  {-0.381191,-0.812393},
+  {0.255808,-0.783620},
+  {-1.000067,-0.814667},
+  {0.937145,0.594671},
+  {-0.138406,0.009326},
+  {0.646863,0.329219},
+  {0.114717,0.727041},
+  {0.534733,-0.274257},
+  {-0.076583,2.064369},
+  {-0.061055,0.387069},
+  {0.587603,-0.573761},
+  {-1.432342,0.080705},
+  {0.517872,-0.933701},
+  {0.257925,-1.369532},
+  {-0.882056,0.033029},
+  {0.272729,-0.396548},
+  {0.898916,0.232792},
+  {-0.323588,0.996638},
+  {1.414689,-0.936268},
+  {-0.063766,0.848570},
+  {-0.631058,-1.026964},
+  {0.144042,-0.577972},
+  {0.620716,-0.672317},
+  {1.311640,0.177935},
+  {0.355140,-0.394373},
+  {-0.892820,0.040002},
+  {0.669596,-1.423798},
+  {-0.728338,0.281565},
+  {-0.158685,-0.108162},
+  {0.294872,0.143540},
+  {0.154297,0.845158},
+  {-0.614381,0.567366},
+  {0.342103,1.116219},
+  {0.264975,-1.064063},
+  {-0.177622,-0.849517},
+  {-0.539107,0.444928},
+  {0.552126,-0.015861},
+  {-0.212621,0.081190},
+  {-0.653462,-0.566566},
+  {0.092306,-0.221675},
+  {1.100202,0.129533},
+  {1.004146,0.906987},
+  {-0.450678,-0.139092},
+  {-0.041574,0.880738},
+  {1.077768,0.691243},
+  {0.683594,1.009049},
+  {-0.782169,1.735141},
+  {0.450257,0.439635},
+  {0.529029,0.258264},
+  {1.138549,1.986809},
+  {-1.302507,0.020303},
+  {-0.283556,0.445303},
+  {-0.718645,-0.162901},
+  {-0.043436,0.596306},
+  {-0.253106,1.007761},
+  {0.511255,-0.417590},
+  {0.747033,0.272022},
+  {-0.558437,-0.347778},
+  {0.160240,-0.682185},
+  {-0.958911,-0.030034},
+  {-0.156077,0.031554},
+  {-1.151408,0.317689},
+  {-0.063615,0.309607},
+  {0.652097,-0.090736},
+  {0.093596,0.162455},
+  {-0.179022,1.654394},
+  {-0.242415,-1.079423},
+  {0.397297,-1.272118},
+  {-0.182965,0.130558},
+  {-1.227359,0.503225},
+  {0.010313,0.859745},
+  {-0.230950,-0.566212},
+  {-0.237624,0.329725},
+  {0.962370,-0.180738},
+  {-0.382887,-0.314282},
+  {-0.606405,1.263377},
+  {0.178244,-0.050770},
+  {1.157081,-0.144043},
+  {1.081460,-0.125683},
+  {0.287172,0.296327},
+  {-0.145758,0.931086},
+  {-0.235046,0.421208},
+  {-0.476461,0.823257},
+  {-0.425877,-0.436417},
+  {-0.164299,0.097882},
+  {0.438670,0.627963},
+  {-0.690073,0.733569},
+  {0.386280,-0.534213},
+  {-1.074264,-0.832657},
+  {0.059724,0.429346},
+  {0.241225,-1.310186},
+  {-0.041200,-2.185164},
+  {0.104350,0.419205},
+  {0.259056,-0.248550},
+  {1.271667,0.475120},
+  {-0.218242,1.164193},
+  {0.346768,-0.150378},
+  {-0.846548,0.308488},
+  {-1.063304,-0.776317},
+  {1.166478,-0.454347},
+  {0.033053,0.179463},
+  {-0.332293,-0.312112},
+  {-0.403124,-0.863969},
+  {-0.115242,0.881201},
+  {-0.443942,-0.049482},
+  {0.576722,0.121133},
+  {1.115690,-0.395430},
+  {-0.967709,-0.283118},
+  {0.238138,0.015244},
+  {-0.346183,-0.321679},
+  {-0.184817,-0.803985},
+  {0.428226,-0.424139},
+  {0.294728,1.082187},
+  {0.146915,-0.379303},
+  {-0.524167,0.099747},
+  {0.586104,-0.292682},
+  {0.078394,0.960573},
+  {1.670460,0.570454},
+  {0.535695,0.279784},
+  {-0.059247,1.179067},
+  {0.193284,0.103453},
+  {0.198475,1.316057},
+  {-0.354204,-0.801039},
+  {-1.095112,-0.629114},
+  {-0.739693,0.109626},
+  {-0.669776,-1.101214},
+  {-1.119037,-0.827679},
+  {-0.697044,0.582501},
+  {0.670182,-0.339850},
+  {1.052632,-1.151181},
+  {-0.013924,-0.148582},
+  {0.676350,-0.382496},
+  {-0.609900,0.145339},
+  {-0.467053,-1.060301},
+  {0.329805,1.116336},
+  {-0.657195,-0.381897},
+  {0.144469,0.365412},
+  {-0.455678,0.492839},
+  {0.164257,-0.588328},
+  {-0.215978,-0.137108},
+  {0.885806,0.550884},
+  {-0.512770,-0.358695},
+  {-0.059087,0.164926},
+  {-0.401278,-0.857801},
+  {0.648031,-0.168120},
+  {-0.175814,-0.106801},
+  {1.103215,-0.147023},
+  {-0.173378,-1.161128},
+  {0.048200,0.186641},
+  {0.382578,0.367532},
+  {0.470646,0.681831},
+  {-0.094808,0.385076},
+  {-0.227419,-0.100211},
+  {0.752327,1.031990},
+  {0.325679,-0.929947},
+  {-1.252363,0.747342},
+  {0.611128,0.470173},
+  {-0.717586,-0.267591},
+  {-1.351702,0.677071},
+  {-0.216029,0.531468},
+  {0.115357,0.016478},
+  {-1.068851,1.084321},
+  {0.464010,0.510275},
+  {1.225770,-0.765537},
+  {0.508388,-0.879914},
+  {-0.865601,-0.344538},
+  {0.685346,0.515833},
+  {-0.637203,-0.617789},
+  {0.279486,-0.543520},
+  {0.897987,-0.208160},
+  {-0.677693,-0.780875},
+  {-0.760403,0.397810},
+  {0.184177,0.176928},
+  {-1.069590,-0.614911},
+  {-0.132476,0.356640},
+  {-0.036611,-1.348685},
+  {0.173300,0.074283},
+  {0.665913,0.252531},
+  {0.876800,0.368352},
+  {0.239620,1.213974},
+  {0.392571,0.197044},
+  {1.445377,1.168005},
+  {-0.351908,-1.245911},
+  {-0.200333,-0.246884},
+  {1.165079,0.269904},
+  {1.102148,0.936739},
+  {0.415018,-0.692267},
+  {0.695930,-0.610682},
+  {0.337706,-0.194200},
+  {-0.406360,-0.428313},
+  {2.001919,0.298601},
+  {0.040240,0.021280},
+  {0.476985,-0.207150},
+  {-0.955785,2.342469},
+  {0.167188,0.627934},
+  {0.278484,-0.586048},
+  {-0.908941,0.243936},
+  {-0.146000,-0.877617},
+  {0.192032,-0.244236},
+  {0.975606,0.244268},
+  {-0.170990,0.257347},
+  {0.764497,-0.551919},
+  {0.058791,0.682466},
+  {0.065943,-0.984803},
+  {-0.912431,0.368831},
+  {0.855040,0.067306},
+  {0.749915,-0.835586},
+  {0.838403,-1.238493},
+  {-1.483938,-0.123001},
+  {-0.557550,-0.923933},
+  {-0.771014,0.386390},
+  {0.273899,-0.385988},
+  {0.750930,-0.659754},
+  {0.777048,1.433688},
+  {-0.209220,0.937272},
+  {0.205420,-0.235356},
+  {0.414937,0.418160},
+  {0.718236,-0.451301},
+  {-0.186269,-1.322922},
+  {-1.920077,0.476052},
+  {-1.398596,0.784435},
+  {-0.256580,0.180031},
+  {-0.532659,0.457304},
+  {-0.384892,-0.039057},
+  {-0.055613,-0.548142},
+  {0.527916,0.194822},
+  {0.823368,-0.281136},
+  {0.619060,-1.874924},
+  {1.444115,0.480538},
+  {-0.819634,0.380911},
+  {-0.423061,-0.352648},
+  {0.834671,1.128296},
+  {-0.327942,-0.116678},
+  {-0.313019,0.264847},
+  {-0.887367,-0.196781},
+  {0.102331,-0.425392},
+  {0.586136,-0.513125},
+  {-0.392544,0.760032},
+  {0.048821,-0.120578},
+  {-0.659257,1.355152},
+  {0.071198,-0.123784},
+  {-0.611575,-0.162787},
+  {0.600874,0.427984},
+  {-0.438527,-0.718199},
+  {1.021030,-0.206658},
+  {-0.040177,0.469484},
+  {-0.097920,0.431053},
+  {-0.227448,0.032859},
+  {0.438377,-0.490723},
+  {-0.127967,-0.318678},
+  {0.530951,-0.205032},
+  {0.306926,-1.611728},
+  {-0.155619,0.005610},
+  {0.364185,1.075986},
+  {-0.355830,1.056994},
+  {-0.416081,0.881061},
+  {-0.168114,0.891871},
+  {0.318273,0.022034},
+  {0.045802,-0.498750},
+  {0.874723,-0.261830},
+  {2.041322,0.581367},
+  {-0.434688,-0.889884},
+  {-0.625497,-1.424039},
+  {-0.916101,-0.012513},
+  {0.301928,-0.119459},
+  {0.054875,0.719308},
+  {0.113292,-0.985813},
+  {-0.256198,1.240920},
+  {0.110794,0.058590},
+  {0.475235,0.043136},
+  {0.265904,0.466909},
+  {0.569717,1.513256},
+  {2.460579,0.347629},
+  {-0.583997,-0.395316},
+  {1.412936,-0.136881},
+  {0.257743,-0.020675},
+  {-0.773710,0.598378},
+  {-0.155740,0.175291},
+  {0.708158,-0.303414},
+  {0.128797,-1.688465},
+  {-0.944673,0.178251},
+  {-0.419667,-0.800480},
+  {1.015229,0.451624},
+  {-0.563132,-0.098941},
+  {1.022619,0.269203},
+  {0.544089,-0.558886},
+  {0.285403,-0.945592},
+  {-0.249927,-0.639200},
+  {0.616154,0.448953},
+  {1.538937,0.176176},
+  {-1.072722,-0.731432},
+  {2.202183,-1.085427},
+  {-0.187007,0.862339},
+  {-0.009781,-0.919787},
+  {0.882595,-0.224292},
+  {0.328335,-1.466478},
+  {-0.425207,-0.406182},
+  {0.230537,0.884368},
+  {-0.295215,-0.639698},
+  {-1.490884,0.427221},
+  {1.247354,0.295467},
+  {-0.810296,0.889553},
+  {1.136726,0.000428},
+  {-0.448626,-0.265578},
+  {-0.375165,-0.970000},
+  {-0.029743,1.329743},
+  {0.191118,-0.149061},
+  {-1.198112,0.166633},
+  {-1.072263,0.604945},
+  {1.319951,0.678233},
+  {-0.286881,1.447051},
+  {-0.000431,-0.790107},
+  {-0.927154,-0.720568},
+  {1.244388,0.126044},
+  {0.361372,-0.563810},
+  {1.786158,0.068526},
+  {0.652693,-0.233381},
+  {-0.956019,-0.446398},
+  {-1.257622,-0.253433},
+  {0.262294,0.421673},
+  {1.178025,0.259483},
+  {-0.138056,0.076554},
+  {-0.338284,-0.760501},
+  {0.238752,-0.363470},
+  {-0.467720,-0.613917},
+  {1.727196,-2.032936},
+  {0.453188,1.148454},
+  {-0.860575,-0.211261},
+  {-0.134673,-0.149191},
+  {0.089986,-0.837997},
+  {-0.421324,0.572281},
+  {-0.154263,0.793297},
+  {-0.068541,-1.226925},
+  {-1.024731,1.765286},
+  {0.321293,-0.655162},
+  {-0.381602,0.084867},
+  {-0.761043,0.072325},
+  {-0.153164,-0.580169},
+  {1.095428,-0.725517},
+  {-1.360859,-0.509727},
+  {-0.015713,1.146405},
+  {0.080499,0.991718},
+  {-0.037406,0.203660},
+  {0.437657,0.772791},
+  {-0.335827,-0.643198},
+  {-0.748036,1.554296},
+  {0.056139,0.540525},
+  {0.855326,1.251389},
+  {1.512833,0.127560},
+  {-0.335811,-0.685869},
+  {0.049175,-0.612331},
+  {0.744695,0.303599},
+  {0.086665,0.554790},
+  {-1.437300,-0.698848},
+  {1.208241,0.809530},
+  {-0.368646,0.188188},
+  {0.918053,2.303752},
+  {0.542692,0.198394},
+  {0.895487,-1.142547},
+  {1.427584,-0.139881},
+  {0.366063,-0.559492},
+  {0.615816,-0.518515},
+  {1.683531,0.689662},
+  {-0.561367,0.740093},
+  {0.136173,0.685102},
+  {0.676639,0.746691},
+  {0.409337,-1.146213},
+  {-0.636375,0.027888},
+  {0.588745,0.274056},
+  {-0.722872,0.098504},
+  {-0.671533,0.012166},
+  {1.011527,0.719796},
+  {0.081135,-0.237933},
+  {-0.318500,0.963256},
+  {-0.817222,0.191993},
+  {-0.244338,0.114244},
+  {-0.596279,-0.365810},
+  {-0.075441,1.479957},
+  {-0.791400,0.528275},
+  {0.028476,-0.288631},
+  {0.165929,-0.171160},
+  {0.275183,0.915583},
+  {0.295522,-0.680658},
+  {0.488326,0.104785},
+  {-0.735568,-0.701452},
+  {-0.082936,-1.234151},
+  {-0.944770,0.415823},
+  {-0.723673,0.661138},
+  {0.020222,-0.209032},
+  {0.744207,1.798693},
+  {-0.650645,0.033519},
+  {-1.346394,-1.296518},
+  {0.979960,-1.559900},
+  {0.346991,-0.097270},
+  {0.844271,-0.832661},
+  {-0.627946,-0.340953},
+  {0.648317,-0.668772},
+  {1.035056,0.096494},
+  {-0.374343,0.301709},
+  {-1.959191,0.184104},
+  {0.354760,0.554715},
+  {0.461264,-0.291802},
+  {-1.445191,-0.676835},
+  {-0.390066,0.002849},
+  {-1.243483,-0.254016},
+  {0.756660,-0.152519},
+  {0.449951,-0.361801},
+  {0.032053,0.448066},
+  {0.301092,-0.018617},
+  {0.919110,-1.106308},
+  {0.688230,-0.751883},
+  {1.443475,0.290925},
+  {-0.336814,-0.202997},
+  {0.194678,0.132777},
+  {0.438428,-0.932498},
+  {-0.005527,-1.612383},
+  {-0.065145,-0.331485},
+  {0.569241,0.575176},
+  {-0.973392,0.141843},
+  {-2.301017,0.881275},
+  {0.784561,0.317932},
+  {-0.077933,0.914512},
+  {0.087316,-0.135682},
+  {0.092940,-1.181121},
+  {-1.310608,0.288132},
+  {-0.892082,-1.676985},
+  {0.916083,0.042083},
+  {-1.244578,0.624427},
+  {-0.334890,0.718718},
+  {-0.741767,-0.347100},
+  {-0.416327,-0.223633},
+  {0.086690,0.939596},
+  {0.888409,-0.085335},
+  {0.625874,1.037141},
+  {0.722036,-1.315310},
+  {-0.335910,-0.880128},
+  {-0.565481,-0.047599},
+  {0.935371,-0.398854},
+  {-0.727068,0.164967},
+  {-0.431810,-0.025259},
+  {0.528973,0.176538},
+  {-0.620117,-0.164306},
+  {0.113693,-0.756706},
+  {-0.026549,-0.082517},
+  {0.366109,-0.935198},
+  {0.574120,-0.696891},
+  {-0.329320,-1.004717},
+  {0.167355,-1.385869},
+  {-1.184704,0.231683},
+  {-1.687510,0.741804},
+  {0.460393,0.417694},
+  {0.913381,-0.623551},
+  {-0.025182,0.652840},
+  {0.149389,1.580919},
+  {0.046797,0.067857},
+  {0.445068,-0.193108},
+  {-0.087060,0.449112},
+  {0.444716,1.154858},
+  {-1.680048,-1.100377},
+  {0.060122,1.288340},
+  {1.811764,0.294464},
+  {0.172455,1.302739},
+  {-1.053456,-0.391417},
+  {-0.932098,-1.179288},
+  {0.822615,0.311778},
+  {-0.593686,-0.517305},
+  {0.592373,-0.858691},
+  {-0.941357,0.211116},
+  {-1.091715,-0.037219},
+  {0.397495,0.181766},
+  {-0.339179,-0.444183},
+  {0.202008,-0.835547},
+  {0.707791,0.284963},
+  {1.127548,0.443368},
+  {0.320918,0.693486},
+  {-0.408938,-0.202700},
+  {-0.474738,-1.197323},
+  {0.196347,-0.186877},
+  {0.133286,-0.981743},
+  {0.454869,-0.118595},
+  {-0.708891,0.915489},
+  {-0.124946,0.257625},
+  {-0.013053,-1.262217},
+  {-0.816680,0.357514},
+  {-1.325378,-0.000513},
+  {-0.471835,-1.666112},
+  {0.006822,0.861943},
+  {-0.609116,0.665514},
+  {-0.022823,-0.921185},
+  {0.334153,-0.307869},
+  {-0.200664,0.039748},
+  {-1.341585,-1.016766},
+  {-1.478115,-0.168005},
+  {0.493183,-0.315358},
+  {0.320896,-0.265798},
+  {-0.410948,0.749325},
+  {0.493700,0.609085},
+  {1.511312,-0.136707},
+  {-0.369151,-1.186832},
+  {0.053669,-0.453470},
+  {-0.344181,0.465001},
+  {-0.409580,1.225758},
+  {-0.040541,0.314214},
+  {-0.563372,0.154451},
+  {-0.296031,0.128113},
+  {-0.170489,-0.237342},
+  {0.484353,0.541345},
+  {-0.281269,-1.163252},
+  {-0.441618,-0.191346},
+  {-0.766963,-1.158696},
+  {0.683851,-0.047111},
+  {0.085014,-1.047429},
+  {0.435402,-1.193670},
+  {0.723781,0.086784},
+  {0.117848,0.731946},
+  {-1.001471,-0.568533},
+  {1.623786,-0.472448},
+  {-0.405629,-0.440914},
+  {-0.867240,0.860770},
+  {-1.370369,-0.367847},
+  {-1.068700,0.049127},
+  {-0.506801,0.070046},
+  {-0.571468,-0.279030},
+  {-0.936487,0.177180},
+  {1.208152,0.335738},
+  {0.547493,0.278008},
+  {-0.676350,0.122804},
+  {0.881113,-0.622278},
+  {-0.997446,0.228682},
+  {0.374538,-1.112491},
+  {0.018405,2.294138},
+  {0.190651,-0.275758},
+  {-1.066702,1.292937},
+  {0.453821,1.500667},
+  {-0.003891,-0.058122},
+  {0.483079,1.838471},
+  {-0.535369,-0.173664},
+  {-1.069100,-0.694773},
+  {-0.112032,-1.188326},
+  {0.855142,0.212202},
+  {-1.308295,-0.165234},
+  {-0.899488,-0.114441},
+  {-0.146224,0.097630},
+  {-0.510277,0.887175},
+  {0.821703,0.158980},
+  {0.853827,-0.985330},
+  {0.451970,0.343768},
+  {0.077419,-1.075895},
+  {-0.613300,0.876653},
+  {-0.747934,0.101782},
+  {0.456308,-0.448831},
+  {0.704574,0.516584},
+  {-0.123099,0.328140},
+  {0.934254,-0.065327},
+  {-0.598220,-0.151876},
+  {0.247193,-0.320853},
+  {0.710846,0.595196},
+  {1.133704,-0.279589},
+  {-0.213979,0.300774},
+  {-0.136586,-0.481220},
+  {-0.818138,0.623683},
+  {0.492634,-0.509161},
+  {0.233986,-0.216658},
+  {-1.803974,-0.101863},
+  {0.338246,-0.233200},
+  {1.210916,-0.191023},
+  {-0.419416,0.400604},
+  {0.174883,0.361058},
+  {0.041907,-0.084804},
+  {-0.565089,-0.646098},
+  {0.808848,-0.495713},
+  {-0.880710,-0.067991},
+  {0.466173,-0.432444},
+  {0.326814,0.655068},
+  {1.323321,-1.755300},
+  {-0.246832,0.422534},
+  {0.488638,0.630369},
+  {-0.672349,-0.571405},
+  {0.929277,0.597525},
+  {0.295168,1.180543},
+  {-0.443439,-0.167602},
+  {0.850886,0.731905},
+  {-0.130536,-1.019228},
+  {0.667789,-0.245031},
+  {-0.048100,0.713830},
+  {-0.693496,1.039212},
+  {-0.470569,-0.156852},
+  {1.071015,-0.851179},
+  {-0.141749,-0.228665},
+  {0.133398,0.157939},
+  {-0.920078,-0.522450},
+  {-1.336102,-2.023545},
+  {0.189471,-0.546281},
+  {0.600537,-0.493998},
+  {0.253657,0.643392},
+  {-0.844469,1.910885},
+  {0.805807,0.277348},
+  {0.113829,-0.394163},
+  {0.706544,0.990309},
+  {0.166811,-1.066923},
+  {0.713167,0.883103},
+  {1.297380,-0.698009},
+  {0.182918,0.196844},
+  {-0.582698,0.320323},
+  {1.179693,1.053822},
+  {1.973986,0.861945},
+  {0.831394,0.372738},
+  {0.036404,-1.044186},
+  {-0.322784,0.736748},
+  {0.465765,1.236812},
+  {-0.094890,-0.910340},
+  {0.534838,0.087896},
+  {-0.423018,0.473497},
+  {0.446821,-0.345740},
+  {1.370136,-0.313957},
+  {0.605235,-0.218558},
+  {-0.312323,-0.331415},
+  {-0.957650,-0.174169},
+  {0.438262,0.355984},
+  {-0.630817,-0.585063},
+  {0.844182,0.027599},
+  {0.255999,0.290238},
+  {0.195645,-0.309908},
+  {-0.361390,0.759387},
+  {0.793257,-0.590533},
+  {-0.272252,-0.825983},
+  {-0.524775,1.002337},
+  {1.025595,0.035075},
+  {0.144336,0.133347},
+  {-0.053176,-0.873734},
+  {-1.072797,-0.022777},
+  {-0.201704,-0.812261},
+  {0.406989,0.690699},
+  {0.167489,0.337122},
+  {0.954502,0.132945},
+  {-0.234877,-1.122684},
+  {-0.713308,0.242610},
+  {0.993134,-0.224591},
+  {0.195455,0.240318},
+  {0.176161,0.919258},
+  {-1.200962,0.602950},
+  {0.146329,-0.178380},
+  {1.905485,0.926800},
+  {-1.213910,-0.046545},
+  {-0.712013,0.163252},
+  {0.701015,0.587351},
+  {0.475746,-0.236882},
+  {0.681216,1.077988},
+  {1.005624,0.206876},
+  {0.503490,0.797294},
+  {-0.740207,-0.178577},
+  {0.049749,0.215896},
+  {0.121691,0.231312},
+  {0.307603,1.696005},
+  {0.149964,-0.357488},
+  {-0.833350,1.591904},
+  {-1.066643,-0.227741},
+  {-0.130385,0.289346},
+  {0.171775,1.229285},
+  {0.499181,0.204163},
+  {0.365325,0.432717},
+  {-1.116102,1.193373},
+  {0.816269,0.322493},
+  {0.044289,-0.038741},
+  {-0.081816,-0.660226},
+  {0.209952,-0.440067},
+  {-0.585770,-1.303251},
+  {-0.470685,0.187163},
+  {-0.273317,-0.063477},
+  {1.701860,-0.310642},
+  {0.235376,0.741904},
+  {-1.391462,-0.818046},
+  {0.891559,0.276066},
+  {0.397528,-0.407250},
+  {-0.245719,0.703900},
+  {0.408310,-1.425978},
+  {0.984774,0.218506},
+  {-0.226844,0.404807},
+  {-0.478742,-0.640515},
+  {0.194719,1.070898},
+  {-0.421489,-1.495545},
+  {-0.285219,-0.021769},
+  {0.805010,-0.178533},
+  {-1.462175,-0.074131},
+  {-0.012403,-0.230968},
+  {1.614191,-0.155847},
+  {1.208571,-1.196227},
+  {-0.757660,1.376246},
+  {0.948323,-0.100899},
+  {-0.537264,0.178661},
+  {-0.225242,-0.390378},
+  {-2.111611,-0.388815},
+  {0.591711,0.721370},
+  {-0.486270,-0.043296},
+  {-0.354134,0.102331},
+  {0.494296,0.500110},
+  {0.977534,0.912976},
+  {0.083083,0.580670},
+  {0.047811,-0.201119},
+  {-0.101871,1.602735},
+  {-0.299291,-0.338615},
+  {-0.517633,-0.181010},
+  {0.557599,-1.494308},
+  {-1.180601,-0.754826},
+  {0.843726,1.285523},
+  {0.248651,1.227134},
+  {0.385419,-1.487426},
+  {0.329802,0.523718},
+  {0.832042,2.344297},
+  {-0.483497,-0.042848},
+  {-0.571850,0.444970},
+  {0.578707,-0.332521},
+  {-0.383466,0.231784},
+  {0.026002,1.355058},
+  {0.290971,-0.253279},
+  {-0.280147,-0.381802},
+  {0.068319,-1.243266},
+  {1.056405,-0.214847},
+  {-0.804678,0.348259},
+  {-0.311298,-0.374442},
+  {-0.727188,1.198522},
+  {0.089518,0.348222},
+  {0.016808,0.138825},
+  {-0.165610,0.734759},
+  {-0.607876,0.020547},
+  {-0.381076,0.319154},
+  {0.771585,2.282850},
+  {-0.679082,-0.535810},
+  {0.922199,-0.104349},
+  {0.883859,0.707429},
+  {0.297841,-0.513259},
+  {-0.084643,0.804522},
+  {0.051716,0.095978},
+  {-0.214681,-0.166287},
+  {0.681025,0.064098},
+  {1.880843,0.324433},
+  {0.035759,0.351759},
+  {-0.184237,1.372837},
+  {0.089526,-0.380857},
+  {1.314891,0.090765},
+  {-0.166000,-0.408904},
+  {-0.487537,-0.303936},
+  {1.403138,-0.027080},
+  {0.874409,-1.421801},
+  {-1.455847,-0.180022},
+  {1.082291,1.664879},
+  {0.071012,0.797922},
+  {0.252097,-0.345585},
+  {0.278979,0.328135},
+  {0.096045,-0.823268},
+  {0.240866,0.568270},
+  {0.623840,0.074629},
+  {1.197388,-0.864621},
+  {0.010140,0.536038},
+  {-0.936742,-0.311617},
+  {0.229416,0.009804},
+  {-0.867776,1.059319},
+  {0.613966,0.475140},
+  {-0.213434,0.139105},
+  {0.725146,-0.742290},
+  {0.106239,0.386418},
+  {0.189119,-0.313432},
+  {-0.506237,-0.211804},
+  {0.625359,0.120521},
+  {0.723693,-0.672366},
+  {-0.960395,0.399574},
+  {0.120116,0.211127},
+  {0.862921,-0.124087},
+  {1.083842,1.379676},
+  {-0.596075,-0.150507},
+  {1.813520,0.153563},
+  {0.821543,0.716422},
+  {0.905501,0.148319},
+  {-0.281616,0.736664},
+  {0.523724,0.771024},
+  {0.736386,0.335333},
+  {0.704974,-1.258289},
+  {0.230135,0.149167},
+  {-0.183667,0.141978},
+  {0.343212,-0.472806},
+  {0.502101,-0.030266},
+  {0.302980,-0.873466},
+  {-0.047585,0.202728},
+  {-0.490690,-1.793145},
+  {0.072517,0.500160},
+  {0.574135,0.273335},
+  {-0.679558,-0.481851},
+  {-0.391140,0.833001},
+  {0.007197,-0.476483},
+  {0.755864,0.699900},
+  {0.023659,0.256314},
+  {-0.219938,-0.203388},
+  {-0.489864,0.259189},
+  {-1.006033,-0.103282},
+  {0.158715,-0.664053},
+  {-0.300183,-1.039796},
+  {-1.321861,-0.637445},
+  {-0.720415,-0.327571},
+  {0.251887,-0.485211},
+  {0.078411,-0.322993},
+  {0.056805,-0.293353},
+  {0.315853,-0.085568},
+  {0.222705,0.310332},
+  {-0.182731,-0.397738},
+  {-0.180319,0.561981},
+  {0.598215,-0.364178},
+  {-1.249949,-1.177746},
+  {-0.456053,-0.685671},
+  {0.954583,0.571800},
+  {1.014219,-1.278695},
+  {1.266613,0.223437},
+  {-0.283420,-0.474797},
+  {0.693306,-0.029207},
+  {0.273299,0.133892},
+  {0.532101,-0.320308},
+  {-0.594831,0.406073},
+  {-0.005518,0.766143},
+  {0.147701,0.838501},
+  {-0.745052,0.749668},
+  {0.936722,0.046095},
+  {-0.921153,-0.296284},
+  {0.230717,1.078411},
+  {-0.104489,0.089344},
+  {0.184105,0.646882},
+  {0.829563,-0.030537},
+  {0.646903,-1.032258},
+  {-0.266078,-0.192410},
+  {0.430983,-0.751174},
+  {-0.369734,0.154678},
+  {1.027273,-1.123325},
+  {-0.284810,-0.673581},
+  {-0.198272,0.710599},
+  {-0.664385,0.828056},
+  {-1.078880,0.714872},
+  {-0.474676,0.242386},
+  {0.680091,-0.410467},
+  {-0.127690,-0.562865},
+  {-0.234136,-1.291910},
+  {-0.304469,-0.626725},
+  {0.530474,0.566233},
+  {-0.109255,-0.557004},
+  {0.087012,0.988810},
+  {-0.750837,-1.577521},
+  {0.347408,-0.389814},
+  {1.437412,0.283755},
+  {-0.159056,1.128835},
+  {0.004413,-0.144927},
+  {0.088644,-0.027569},
+  {-0.079487,-0.229503},
+  {0.870379,-0.028245},
+  {-0.138882,1.645245},
+  {-0.177149,-0.495996},
+  {-0.040567,-0.960823},
+  {0.701093,-0.753669},
+  {-0.268945,0.477653},
+  {0.519034,-0.856936},
+  {1.010434,0.014817},
+  {0.314739,0.141389},
+  {0.838768,0.270923},
+  {-0.922034,0.148587},
+  {0.537647,1.022497},
+  {-0.184456,0.248540},
+  {-0.702941,0.129272},
+  {-1.199959,-0.484713},
+  {0.775146,0.641877},
+  {1.355787,-0.061010},
+  {-0.273411,-0.344273},
+  {-0.079652,-0.580078},
+  {-0.294108,0.383430},
+  {-0.663756,0.764663},
+  {-0.029209,0.187390},
+  {0.458825,0.020946},
+  {-0.759974,-0.072059},
+  {-0.762552,2.339859},
+  {-0.691081,0.637021},
+  {0.066676,-0.267145},
+  {-0.000870,-0.130399},
+  {-0.128295,-0.090600},
+  {0.434282,-1.040424},
+  {0.064080,0.311479},
+  {0.445593,-1.427874},
+  {0.309938,0.341331},
+  {-0.668997,0.293917},
+  {1.532275,0.452357},
+  {1.468994,0.022104},
+  {-0.581643,1.003752},
+  {0.923086,0.272041},
+  {0.469483,0.205555},
+  {0.066270,1.032433},
+  {-0.223936,0.193990},
+  {0.722656,0.900099},
+  {-0.460502,0.026773},
+  {0.264304,0.263321},
+  {0.011564,0.998830},
+  {-0.852220,-0.735707},
+  {-0.367962,0.277292},
+  {0.912905,-0.022560},
+  {0.474794,-0.033505},
+  {0.383646,0.014366},
+  {-0.147667,-0.066343},
+  {0.496019,-0.698605},
+  {0.466197,0.778409},
+  {-0.005985,-0.917034},
+  {0.364603,-1.005913},
+  {-1.127720,-0.496130},
+  {0.530754,-0.710343},
+  {0.817573,-0.478350},
+  {1.542207,1.147533},
+  {-1.015912,-0.392767},
+  {-0.528064,-1.332638},
+  {-1.655403,0.790160},
+  {-0.192199,0.863973},
+  {-0.148335,1.398748},
+  {0.231018,-0.580136},
+  {-0.028057,0.350163},
+  {-0.078239,-0.095824},
+  {-0.368671,-0.118777},
+  {0.143814,0.563598},
+  {-0.286646,-1.756129},
+  {0.331342,0.411717},
+  {0.402591,0.419929},
+  {0.267689,0.344904},
+  {-0.737596,0.808101},
+  {-1.479648,-0.212449},
+  {0.354386,1.310559},
+  {-0.676218,-1.049757},
+  {-0.115748,-1.162720},
+  {-0.325709,-1.636897},
+  {0.093754,0.067673},
+  {-0.266273,-1.083043},
+  {-0.366387,-0.814048},
+  {-0.315910,0.796504},
+  {1.358526,0.414087},
+  {-0.674816,-0.587575},
+  {-1.084357,-0.761996},
+  {1.170537,-1.118362},
+  {-0.888671,-0.372056},
+  {0.206631,-0.197368},
+  {0.151309,-0.017645},
+  {-0.639638,-0.158684},
+  {-0.818429,-0.799644},
+  {0.193617,0.138892},
+  {-0.330140,0.508120},
+  {-1.023892,-0.005087},
+  {-0.492779,-0.242526},
+  {1.190477,0.548598},
+  {0.380355,-0.428248},
+  {-0.443627,0.322194},
+  {0.643475,-0.610225},
+  {1.639932,0.217874},
+  {-0.075206,-0.891935},
+  {0.472977,0.806206},
+  {-0.049387,0.521157},
+  {0.775513,1.120129},
+  {-0.820993,-0.580519},
+  {0.787248,0.471905},
+  {1.982564,-0.239183},
+  {0.036994,-0.084856},
+  {0.397587,-0.108305},
+  {0.717829,-0.658020},
+  {0.096854,-1.073618},
+  {-0.247410,0.105690},
+  {-0.636805,-0.001866},
+  {0.249262,0.170546},
+  {-1.384929,-0.181014},
+  {0.394318,-0.470332},
+  {0.312685,-0.971393},
+  {0.126831,1.201348},
+  {-0.741448,-0.364570},
+  {0.885990,-0.170062},
+  {0.946030,0.048529},
+  {-0.814388,0.775904},
+  {0.365165,-0.393381},
+  {-0.910022,-0.285627},
+  {-1.692124,-0.058729},
+  {-1.176468,0.344140},
+  {-0.680828,-0.802456},
+  {1.430130,-1.167865},
+  {-1.009736,-0.292885},
+  {0.780604,0.117665},
+  {-1.183708,-0.191115},
+  {-1.109502,-2.955782},
+  {-0.679155,-0.425963},
+  {-0.478117,-0.857997},
+  {0.559869,1.189793},
+  {0.693475,0.705402},
+  {-0.069617,-0.231592},
+  {-0.824859,-0.475262},
+  {-0.613227,0.171012},
+  {-0.972368,-0.750733},
+  {0.572478,-0.362034},
+  {0.400015,0.093211},
+  {-0.664619,-0.115371},
+  {1.629905,1.260396},
+  {-0.887239,-0.880451},
+  {-0.475993,1.783962},
+  {-0.535449,0.374335},
+  {-0.268655,0.381528},
+  {-0.048788,0.080243},
+  {-0.263956,0.156544},
+  {-0.201047,-0.681716},
+  {0.007541,-0.270714},
+  {0.968368,-1.040116},
+  {1.598093,-0.868513},
+  {0.608883,-0.925775},
+  {-0.292500,0.359309},
+  {0.781647,-1.854675},
+  {-0.048384,-0.358500},
+  {-0.045277,0.182846},
+  {0.702542,-0.682803},
+  {-1.310088,0.288354},
+  {-1.111262,-0.253839},
+  {-0.610601,0.629673},
+  {-0.077137,-0.288207},
+  {-1.248534,-0.678787},
+  {0.589672,-0.209868},
+  {0.328118,0.280762},
+  {-0.130254,0.359489},
+  {-1.191280,-0.282377},
+  {-0.727137,0.795181},
+  {-0.332298,0.545214},
+  {0.449265,0.809670},
+  {-1.176652,0.024432},
+  {-0.444225,0.247852},
+  {-0.493719,-0.443957},
+  {0.490093,-0.462030},
+  {0.894083,-0.428290},
+  {-0.808464,0.061714},
+  {-0.438031,-0.880389},
+  {-0.374120,-0.133532},
+  {0.109504,0.714367},
+  {1.199793,-0.870295},
+  {-0.016396,1.234340},
+  {0.176536,0.170704},
+  {1.583727,-1.037287},
+  {-0.408359,0.192187},
+  {-0.716863,-0.030518},
+  {-0.087939,-0.157292},
+  {0.233970,-0.789071},
+  {0.448874,-0.318136},
+  {-0.001706,0.203524},
+  {-0.583113,0.483299},
+  {0.032509,-1.159109},
+  {0.243543,-1.545598},
+  {0.963137,-1.858378},
+  {-0.433912,0.106663},
+  {-0.584636,-0.554822},
+  {-0.169820,0.694442},
+  {-0.694692,-1.420531},
+  {0.124368,0.308158},
+  {-0.371740,-1.256747},
+  {-0.371259,-0.345713},
+  {-0.080108,-0.248600},
+  {-0.508996,-0.502867},
+  {-0.259720,-1.107589},
+  {-0.479506,-0.625836},
+  {-0.966428,-1.108758},
+  {0.199396,0.684562},
+  {-0.139579,-0.532375},
+  {-0.671940,1.263705},
+  {0.583387,-0.545125},
+  {0.594017,0.135560},
+  {0.295089,-0.517450},
+  {0.227495,-0.116494},
+  {-0.278437,0.070346},
+  {1.252146,0.161429},
+  {-0.719420,-0.400126},
+  {0.411649,0.672294},
+  {-0.067492,-0.147642},
+  {0.773465,0.447213},
+  {-0.096564,0.687259},
+  {0.223581,-0.672181},
+  {-1.189369,-1.012300},
+  {0.378992,-1.602545},
+  {0.528201,-0.184505},
+  {0.555361,-0.073704},
+  {0.641793,-0.149102},
+  {0.614789,0.145011},
+  {-0.014245,0.835852},
+  {-0.433430,-0.150091},
+  {1.265735,-0.171617},
+  {0.424119,0.261458},
+  {0.543597,-0.019062},
+  {0.106955,-0.352852},
+  {0.259824,-1.044464},
+  {-0.134395,1.294968},
+  {0.614190,0.103061},
+  {-0.472730,0.440592},
+  {0.026255,1.541770},
+  {-0.680532,0.748520},
+  {-1.652447,-0.981050},
+  {1.530492,0.410946},
+  {0.590749,-0.057968},
+  {-0.204753,-0.053539},
+  {-0.146540,0.407365},
+  {-0.589178,-0.794021},
+  {1.057477,0.390612},
+  {-0.318475,0.110593},
+  {0.860875,-0.484007},
+  {-0.853862,-0.303066},
+  {-0.640767,-0.247635},
+  {-0.661993,0.487274},
+  {-0.132963,-0.470698},
+  {0.276424,0.103581},
+  {0.269608,-1.122638},
+  {-1.094199,0.419837},
+  {0.466955,-0.942801},
+  {1.061330,-0.773058},
+  {0.504520,0.613301},
+  {0.975902,0.530381},
+  {-0.030956,0.526710},
+  {0.231220,-1.339298},
+  {-0.011487,0.006031},
+  {-0.018207,-1.410146},
+  {-0.042725,-1.430596},
+  {0.082844,0.468408},
+  {-0.592661,0.098480},
+  {0.011226,0.279928},
+  {0.032576,-1.292298},
+  {-1.290445,0.847037},
+  {0.901504,-0.435370},
+  {-0.728679,-1.694385},
+  {0.869029,1.438773},
+  {0.348432,0.771641},
+  {0.433021,-0.359444},
+  {-0.716851,-1.686122},
+  {0.654974,-0.546823},
+  {-0.288514,0.307206},
+  {0.656826,0.217168},
+  {-0.688401,0.403697},
+  {-0.151237,-0.641147},
+  {0.280761,-0.025080},
+  {1.352524,0.262260},
+  {-1.020794,0.502821},
+  {-0.308908,-0.753609},
+  {-1.227055,-0.566285},
+  {1.246124,-1.216215},
+  {-0.096449,-0.082642},
+  {-0.582940,0.409202},
+  {-0.297638,0.527261},
+  {-0.473862,-0.847413},
+  {0.493371,0.316474},
+  {-0.505728,-0.462956},
+  {-0.595404,-0.478184},
+  {0.282216,-0.370408},
+  {-0.648353,2.154436},
+  {0.388833,-1.448003},
+  {0.520432,0.059147},
+  {-0.013529,0.455994},
+  {0.939385,-0.134557},
+  {0.620260,0.444285},
+  {0.242877,-0.212567},
+  {0.864014,1.110652},
+  {-0.433176,0.148295},
+  {-0.467423,0.654889},
+  {0.385444,0.838910},
+  {-0.451962,-0.686281},
+  {-0.028356,1.160879},
+  {-0.420737,0.282096},
+  {0.276441,0.183335},
+  {0.644401,0.809729},
+  {-0.038628,-0.032380},
+  {-0.689183,0.615413},
+  {0.685082,0.193192},
+  {0.603120,-0.720557},
+  {0.575454,-0.298269},
+  {-0.336636,0.032836},
+  {1.167203,-0.640395},
+  {-1.086856,-0.481934},
+  {1.008476,1.002123},
+  {-0.884676,0.816595},
+  {1.107577,-0.884024},
+  {0.478516,-0.707394},
+  {0.258192,-0.748370},
+  {-0.741356,0.392670},
+  {0.705741,-0.514239},
+  {0.153360,0.250206},
+  {0.332233,0.401451},
+  {-0.810436,0.247146},
+  {0.382241,0.492063},
+  {-0.120140,-0.666149},
+  {0.219067,-0.351762},
+  {0.503475,0.143766},
+  {1.810909,-0.522492},
+  {0.914236,1.024772},
+  {-0.001545,0.951413},
+  {-0.361359,-0.703397},
+  {-0.790543,-0.080398},
+  {-0.124326,0.712994},
+  {0.989520,0.282750},
+  {-0.639085,-0.593687},
+  {0.532412,0.985720},
+  {-0.814493,-0.684384},
+  {-0.335779,-0.770313},
+  {-1.021545,0.405681},
+  {-0.711770,-1.295042},
+  {0.875563,-0.431312},
+  {-1.424888,0.070227},
+  {0.041671,0.512540},
+  {0.560060,-1.156517},
+  {0.495886,0.815220},
+  {0.932619,0.063747},
+  {0.015802,-0.313213},
+  {0.849039,0.928043},
+  {-1.711563,-0.070807},
+  {-0.666807,-0.065413},
+  {1.336124,0.298359},
+  {-1.465749,1.267894},
+  {0.643581,0.208283},
+  {-0.027162,0.285537},
+  {0.727538,0.592374},
+  {-1.035589,0.161733},
+  {-0.093690,-1.111324},
+  {-0.118812,-0.492105},
+  {-0.310044,0.136076},
+  {0.423281,0.738354},
+  {-0.332121,-1.129243},
+  {0.821705,-1.094517},
+  {0.034405,-0.125589},
+  {-1.061441,-0.025527},
+  {0.262581,0.337586},
+  {0.089369,-0.030417},
+  {0.001538,-0.262250},
+  {-0.603561,0.120004},
+  {-0.666026,-0.523188},
+  {-0.604976,0.661149},
+  {0.424495,0.063530},
+  {-0.459048,0.273275},
+  {-0.759139,-1.058355},
+  {0.788408,-0.233671},
+  {0.420774,-0.023008},
+  {-0.057270,-0.647363},
+  {0.332215,-0.161691},
+  {-0.241240,0.285908},
+  {-2.248124,-1.075027},
+  {1.897230,1.332517},
+  {-1.000960,-0.341355},
+  {-0.764357,0.742789},
+  {-0.430048,0.351628},
+  {-0.758480,-1.168399},
+  {-0.435465,-1.025082},
+  {-0.031475,1.442605},
+  {-0.098961,0.902862},
+  {-1.182562,1.622450},
+  {-0.779323,0.082419},
+  {0.456925,0.197176},
+  {-0.508334,-0.322065},
+  {0.508929,1.414049},
+  {0.831596,-0.269084},
+  {-0.557522,0.829015},
+  {-0.307706,1.811900},
+  {0.522715,0.538211},
+  {-0.007168,-0.369323},
+  {-0.617961,0.598800},
+  {-0.978429,-1.276183},
+  {-0.311683,-0.168769},
+  {0.813820,-0.732024},
+  {1.620090,0.776415},
+  {-0.244712,-0.030740},
+  {0.423419,0.437735},
+  {-0.438972,0.722604},
+  {-0.882370,-0.599715},
+  {0.861613,0.144139},
+  {0.794431,-0.119300},
+  {0.174561,0.355555},
+  {-0.691546,0.900205},
+  {0.994296,1.262278},
+  {-0.693701,0.809946},
+  {0.153439,0.433443},
+  {-0.125105,-0.519678},
+  {0.091914,0.929540},
+  {0.307382,1.281497},
+  {-0.219573,-0.230141},
+  {0.323594,0.781383},
+  {0.898631,0.775206},
+  {0.511558,-0.475861},
+  {0.097796,-0.356711},
+  {0.279638,1.045159},
+  {1.270842,-0.511080},
+  {-0.082679,0.240138},
+  {0.568139,-0.004501},
+  {0.109403,-0.183895},
+  {-0.739424,1.048188},
+  {-0.054909,-0.730640},
+  {-0.107852,-0.216831},
+  {0.685852,-0.120568},
+  {1.372181,0.079369},
+  {-0.057168,-1.475400},
+  {1.379104,-0.416757},
+  {0.674217,0.132367},
+  {0.823818,0.008095},
+  {-0.227594,-1.181870},
+  {0.154429,-0.278722},
+  {-0.380589,1.327236},
+  {0.953822,-0.415279},
+  {0.523925,-0.065958},
+  {-0.336928,0.243956},
+  {0.552334,0.546455},
+  {1.968980,-0.255377},
+  {0.071926,-0.528260},
+  {-0.242553,0.409914},
+  {0.794756,-0.821838},
+  {0.670664,-0.016080},
+  {-0.195775,-0.420098},
+  {-0.437345,-0.444139},
+  {0.929108,0.038056},
+  {-0.034900,0.359362},
+  {-0.646337,0.250061},
+  {0.164494,-0.964178},
+  {0.217552,-0.079574},
+  {0.616784,-0.219605},
+  {0.274625,0.461819},
+  {0.600045,0.609724},
+  {-0.227316,0.212501},
+  {-0.681566,-0.149931},
+  {0.613788,0.331795},
+  {-0.746826,-0.495927},
+  {-0.352302,-0.492596},
+  {-0.234966,-0.714624},
+  {0.209031,0.429705},
+  {0.909196,-0.574662},
+  {-0.264863,1.129618},
+  {-0.418314,0.193085},
+  {0.140225,-0.055672},
+  {-0.259935,0.107007},
+  {0.577398,-0.501482},
+  {-0.700274,0.431435},
+  {-0.320978,-1.214359},
+  {0.040677,-0.504970},
+  {0.621603,0.489428},
+  {-0.775181,0.755810},
+  {-0.449114,-0.259854},
+  {-0.964709,-0.189900},
+  {0.571927,-0.612827},
+  {-0.510919,0.532547},
+  {1.043521,0.076593},
+  {0.559284,1.091596},
+  {0.385705,-0.620434},
+  {-0.281876,1.139602},
+  {0.696445,0.461885},
+  {0.144423,-0.355093},
+  {-1.477952,0.389119},
+  {1.033198,-0.665606},
+  {0.301267,0.413149},
+  {-0.437421,1.527053},
+  {-0.688981,0.779191},
+  {-0.736537,-0.869510},
+  {0.633416,0.485837},
+  {-0.217942,-0.604167},
+  {0.052318,-0.432202},
+  {-0.404016,0.007563},
+  {0.371806,0.924113},
+  {0.685100,0.792052},
+  {0.338713,-1.831682},
+  {0.116368,-0.901689},
+  {0.859729,-0.187662},
+  {0.532246,-0.609526},
+  {-0.252737,0.583202},
+  {0.802405,-0.891543},
+  {-0.657884,-1.409923},
+  {-1.011401,-0.576367},
+  {-0.518947,0.454590},
+  {-0.760309,0.886904},
+  {0.551054,0.077816},
+  {-0.056155,-0.399365},
+  {-1.188687,-0.144384},
+  {0.348530,-0.718497},
+  {0.040766,0.421674},
+  {0.054193,-1.058049},
+  {-0.703027,0.823753},
+  {0.674644,0.568892},
+  {0.653971,-0.029957},
+  {-0.330844,0.894927},
+  {-0.355906,0.469251},
+  {-0.548867,1.196719},
+  {-0.316741,-0.112885},
+  {-0.050654,-1.074386},
+  {-0.458463,-0.052899},
+  {-0.323981,-0.056114},
+  {-1.226962,-0.781318},
+  {-0.793700,0.814978},
+  {0.588809,0.468163},
+  {0.297339,0.292342},
+  {-1.189165,-0.848667},
+  {-0.401703,-0.893584},
+  {0.275424,0.119550},
+  {-0.152022,-0.594732},
+  {-0.937268,0.649621},
+  {0.139979,0.423321},
+  {-0.267033,-0.061451},
+  {0.460158,0.411101},
+  {0.102352,0.520000},
+  {-0.670053,0.131062},
+  {-0.547779,-1.300149},
+  {1.065430,-1.272432},
+  {0.850852,-1.537153},
+  {-0.127321,-0.412569},
+  {0.497995,-0.760964},
+  {0.618018,-0.962779},
+  {-0.367868,0.358651},
+  {0.418133,-0.031711},
+  {0.827988,-0.299697},
+  {0.418025,-0.080342},
+  {0.227770,-0.733112},
+  {-0.522901,0.220810},
+  {0.036422,-0.204918},
+  {1.192243,-0.320297},
+  {0.640624,-2.005424},
+  {1.277127,0.447780},
+  {-0.277087,0.657680},
+  {-0.277141,0.773988},
+  {-1.130237,0.935414},
+  {0.284414,0.813877},
+  {-0.174957,1.139543},
+  {0.300714,-0.749478},
+  {1.404330,-1.232405},
+  {-0.313154,-0.213062},
+  {0.652658,0.241568},
+  {1.120691,0.518463},
+  {0.224488,-0.153773},
+  {0.375402,0.482763},
+  {0.435975,0.236790},
+  {1.127072,-0.422277},
+  {0.580361,1.063162},
+  {-0.955583,0.064231},
+  {-1.802524,0.616951},
+  {0.463128,-0.562220},
+  {0.556800,0.473310},
+  {0.658684,-0.639963},
+  {-0.085954,-1.135439},
+  {-0.243128,-0.126796},
+  {-0.207362,-0.333691},
+  {0.056183,-0.707808},
+  {0.902377,-0.681407},
+  {0.152853,0.619626},
+  {-0.603487,0.293431},
+  {0.133038,-0.379933},
+  {0.264123,-0.101897},
+  {0.861720,1.091886},
+  {-0.479815,-0.165089},
+  {-0.508836,0.900798},
+  {-1.131878,0.459296},
+  {0.037585,1.004276},
+  {-0.480040,0.214050},
+  {0.156506,-0.222274},
+  {0.690720,0.133503},
+  {0.429938,-0.394251},
+  {-0.791723,-0.605653},
+  {-0.554200,-0.418231},
+  {-0.655144,-0.346624},
+  {0.054409,0.359821},
+  {-0.198795,-0.563282},
+  {0.006104,0.725420},
+  {-0.447277,0.540059},
+  {-0.240985,0.280044},
+  {0.637304,-0.116014},
+  {1.381762,0.955712},
+  {-0.148803,0.395996},
+  {0.461393,0.840140},
+  {-0.627308,-0.418263},
+  {-2.171597,-0.599572},
+  {0.080969,0.894764},
+  {0.237331,-0.687851},
+  {0.226158,-0.331895},
+  {0.210506,-0.350461},
+  {-0.043257,-0.021596},
+  {0.551392,0.221253},
+  {0.410879,-0.257200},
+  {0.735420,0.692801},
+  {-0.812522,0.436671},
+  {-1.425556,-0.022695},
+  {1.337264,-0.118216},
+  {-0.196561,-1.121436},
+  {-1.635570,-0.545684},
+  {-0.259296,0.302864},
+  {0.233845,0.231713},
+  {-1.369904,0.069084},
+  {0.310104,0.568822},
+  {-0.074240,-0.389091},
+  {0.513558,0.016256},
+  {0.154059,-0.551779},
+  {0.139022,0.002589},
+  {1.252789,-1.075694},
+  {-0.357876,0.779981},
+  {-0.057981,-0.578702},
+  {-0.348248,-0.564724},
+  {-0.281181,0.160394},
+  {0.755197,-1.493796},
+  {0.349744,-0.585402},
+  {-0.097265,0.568082},
+  {-1.207000,0.702378},
+  {-1.086582,0.502455},
+  {-0.274557,-0.175564},
+  {-0.663327,-1.099270},
+  {0.025018,-0.858302},
+  {0.251512,0.181174},
+  {0.948731,0.438021},
+  {0.278818,-0.736799},
+  {0.384640,0.133641},
+  {-0.269113,0.522492},
+  {-0.192256,0.710115},
+  {0.052306,0.974402},
+  {0.154651,-0.268357},
+  {-0.131640,0.099690},
+  {-1.309976,-0.291957},
+  {0.346624,0.382487},
+  {0.516366,0.707133},
+  {0.697076,1.540016},
+  {0.490790,-0.397012},
+  {1.123760,0.916850},
+  {0.515663,0.434250},
+  {-1.638678,-0.176421},
+  {1.167902,-0.355185},
+  {-0.264941,1.971705},
+  {0.745419,-0.542922},
+  {-0.754792,-0.652504},
+  {1.369699,-0.283123},
+  {-0.372842,-0.062135},
+  {-0.746602,-1.311843},
+  {0.620061,-0.729972},
+  {-0.014445,-0.658271},
+  {0.344167,0.003698},
+  {-0.842281,1.037953},
+  {-0.843122,-0.523207},
+  {-0.318300,-0.179022},
+  {-0.323143,0.019886},
+  {0.430288,0.041221},
+  {0.360478,0.640265},
+  {0.483503,-0.160184},
+  {0.244137,1.233902},
+  {-0.545883,0.318665},
+  {0.247693,-0.469566},
+  {-0.321296,0.284737},
+  {1.147200,0.641921},
+  {1.216635,0.890397},
+  {0.486701,0.456830},
+  {0.550060,-0.222243},
+  {-1.397045,0.187919},
+  {0.912252,-0.441861},
+  {1.245188,-0.318386},
+  {-1.140431,0.133960},
+  {-0.223423,-0.543275},
+  {-0.259693,0.710342},
+  {0.100516,0.525350},
+  {-0.101837,-0.378891},
+  {0.004744,-0.651883},
+  {0.701837,0.505055},
+  {1.259750,0.414716},
+  {1.619510,-0.525369},
+  {-0.927012,0.502818},
+  {-0.687559,0.774157},
+  {-1.015032,0.154981},
+  {0.783957,0.857966},
+  {1.055951,1.123508},
+  {0.124867,-1.198195},
+  {-0.122501,-0.319462},
+  {0.522490,1.035699},
+  {0.047462,-1.064514},
+  {-0.069016,-0.011192},
+  {-0.061777,0.932923},
+  {-0.496995,0.483659},
+  {0.960503,0.102691},
+  {-0.858251,-0.587168},
+  {-0.679635,-1.149459},
+  {0.778286,0.086740},
+  {-0.797912,0.786926},
+  {0.043148,-1.618909},
+  {0.354889,1.345281},
+  {1.176276,-0.529673},
+  {0.612892,1.322230},
+  {0.784053,-1.188249},
+  {-0.921667,1.036610},
+  {-0.328724,-0.039212},
+  {0.462540,1.173392},
+  {-0.104801,-0.346268},
+  {-0.531985,0.372684},
+  {-0.788000,0.243345},
+  {0.882742,-0.834651},
+  {0.691050,0.394536},
+  {-0.122631,0.586303},
+  {-1.264893,-0.525182},
+  {0.461967,0.151354},
+  {0.776068,0.123712},
+  {0.063297,0.200959},
+  {0.136792,-0.138604},
+  {-0.573293,0.711280},
+  {0.738962,-1.300857},
+  {0.159731,-0.141142},
+  {-0.359106,-0.029247},
+  {-1.076380,0.376036},
+  {0.572506,-0.942929},
+  {0.367264,0.437083},
+  {-0.507908,-0.742628},
+  {-0.012061,0.227037},
+  {-0.747644,-0.353159},
+  {-0.998729,-0.220973},
+  {-0.587253,-0.390827},
+  {-0.094152,0.756393},
+  {0.448719,0.149999},
+  {-0.218918,-0.048559},
+  {-0.015560,-0.440495},
+  {1.434334,-1.392218},
+  {0.077947,-0.359505},
+  {1.786997,-0.312543},
+  {0.255695,-0.381884},
+  {-0.301675,-0.104294},
+  {0.700752,0.109512},
+  {0.170083,1.699975},
+  {-0.434933,0.267685},
+  {0.402053,-0.343667},
+  {0.698429,0.834043},
+  {-0.331847,-0.731839},
+  {-1.146666,-0.701629},
+  {-0.002935,0.704111},
+  {0.205245,0.690760},
+  {-0.683238,0.215240},
+  {-0.646288,0.694404},
+  {0.325711,-0.046830},
+  {0.592448,-0.308384},
+  {1.529366,-0.987481},
+  {-0.295320,-0.271241},
+  {0.729563,-0.167488},
+  {0.642193,-0.120176},
+  {-1.548146,0.885333},
+  {0.351531,0.897226},
+  {1.595430,1.246450},
+  {-0.486378,-0.288596},
+  {-0.302011,0.618312},
+  {0.182741,0.420557},
+  {1.113837,0.316246},
+  {0.527597,0.254757},
+  {1.415948,-0.051085},
+  {0.520356,-0.721367},
+  {-0.144424,0.705921},
+  {-0.070251,-1.038962},
+  {-0.218357,1.041630},
+  {0.729530,-0.690915},
+  {0.128689,0.314481},
+  {-0.117418,0.402299},
+  {0.241349,-0.167075},
+  {0.360539,0.711009},
+  {-0.001491,0.204478},
+  {0.487177,-0.385142},
+  {0.480899,0.083528},
+  {0.905059,-0.668149},
+  {0.473028,0.683468},
+  {0.048413,-0.513762},
+  {0.392684,-0.016979},
+  {0.008658,-0.397690},
+  {0.312022,-0.290086},
+  {-0.224513,-0.203352},
+  {-0.700904,1.285464},
+  {-0.209541,0.152510},
+  {-0.689456,0.082655},
+  {-0.090242,0.461600},
+  {-0.012036,-0.301713},
+  {-0.301809,1.238924},
+  {-0.329893,-0.021590},
+  {0.223851,0.421586},
+  {0.317937,1.311734},
+  {0.075659,-1.100616},
+  {0.582116,0.136126},
+  {-0.364256,-0.625304},
+  {0.014662,-0.234577},
+  {-1.092968,0.618389},
+  {-0.238227,-0.574362},
+  {-0.417061,-1.373738},
+  {-0.534463,0.792450},
+  {-0.112449,-0.282805},
+  {-0.579626,0.953945},
+  {-0.737441,-1.782889},
+  {-0.761315,-0.665039},
+  {-0.230262,0.334866},
+  {-1.640518,0.345659},
+  {-0.183278,1.207714},
+  {-0.155715,0.262073},
+  {0.495034,0.977896},
+  {0.267491,0.395822},
+  {0.020021,-0.525175},
+  {-0.409405,0.155372},
+  {-0.637273,0.397385},
+  {0.569432,-0.826493},
+  {-0.300224,-0.571919},
+  {-0.419535,0.627416},
+  {-0.670691,0.736638},
+  {0.148186,0.842415},
+  {-1.898319,0.635542},
+  {-0.194627,-0.501422},
+  {0.649891,0.952195},
+  {-0.213436,-0.681949},
+  {-0.868013,-1.363636},
+  {0.613184,-1.017739},
+  {-0.840052,-1.564144},
+  {0.723446,-0.354610},
+  {0.654592,-0.818130},
+  {-0.712827,-0.762259},
+  {0.166346,0.489915},
+  {-0.302822,-0.693097},
+  {1.358446,-1.355483},
+  {-1.139428,0.086305},
+  {-1.082740,1.498861},
+  {-0.329648,0.147864},
+  {-0.174769,-0.118863},
+  {0.845277,-0.480739},
+  {-0.289794,-0.173351},
+  {0.837552,-0.021153},
+  {-0.033429,0.650532},
+  {-0.718426,-0.668466},
+  {-0.238433,0.483005},
+  {-0.720576,-0.226939},
+  {-0.565185,-0.899305},
+  {-0.586429,-0.847011},
+  {0.948211,-1.151628},
+  {0.079392,-1.199359},
+  {-0.196210,-0.018502},
+  {0.092218,-0.902690},
+  {0.545633,-0.702880},
+  {0.953190,-0.244621},
+  {-0.122974,-0.872691},
+  {1.001723,0.399548},
+  {0.773129,0.292586},
+  {0.369522,1.099643},
+  {-0.128016,0.145086},
+  {0.432098,-0.694186},
+  {0.830267,-0.548718},
+  {0.960296,-0.000663},
+  {0.811884,0.184881},
+  {-1.071500,0.409177},
+  {0.738243,0.409131},
+  {0.073622,0.031693},
+  {-0.046745,0.274024},
+  {-0.115489,-0.411869},
+  {0.216582,-0.319286},
+  {0.753995,-0.498359},
+  {-0.216480,-1.134280},
+  {-0.021988,-0.433786},
+  {-0.327947,0.395941},
+  {0.075096,-0.558661},
+  {-1.031386,-0.090874},
+  {0.661876,0.234726},
+  {-0.032586,-0.957959},
+  {0.675562,-0.062058},
+  {0.089478,0.117239},
+  {0.758516,-1.036737},
+  {0.363183,-0.269026},
+  {0.465104,0.683736},
+  {0.515043,0.202359},
+  {1.572937,-1.193864},
+  {-0.456658,-0.051996},
+  {-0.262883,-0.004140},
+  {1.536223,-0.941011},
+  {0.241501,-1.081946},
+  {0.376242,-0.059869},
+  {1.661854,-0.122313},
+  {-0.171189,-0.902749},
+  {0.163209,0.109854},
+  {0.838006,-0.570945},
+  {-0.403151,0.401615},
+  {-0.941536,0.224667},
+  {0.254770,0.119757},
+  {0.010017,0.650252},
+  {-0.849219,-0.093818},
+  {0.438965,0.528280},
+  {0.585909,0.170241},
+  {-0.231668,-0.647083},
+  {-0.812408,-0.241565},
+  {-0.270441,-0.747414},
+  {0.351427,-0.136789},
+  {-0.454502,-1.594160},
+  {-0.128552,-0.381218},
+  {0.852571,0.550196},
+  {-0.082519,-0.975152},
+  {-0.118825,-0.587947},
+  {0.118019,0.174990},
+  {0.977679,0.989980},
+  {-0.687867,0.152383},
+  {1.597743,0.880373},
+  {-0.926928,-0.305081},
+  {-0.676320,0.054946},
+  {-0.480725,-0.568788},
+  {-0.366417,1.067759},
+  {0.017773,1.235424},
+  {1.404835,-1.087228},
+  {-0.967946,0.352186},
+  {-1.229937,-0.317813},
+  {-0.051257,-0.039613},
+  {-0.580332,-1.096354},
+  {1.377717,0.775992},
+  {-0.525138,-0.051334},
+  {0.341863,0.010390},
+  {-0.994051,0.551957},
+  {0.554196,0.888456},
+  {-0.096138,-0.120533},
+  {0.772601,-0.270712},
+  {0.643594,-0.087350},
+  {0.409067,-0.299266},
+  {-0.679971,-0.342567},
+  {0.589620,0.703170},
+  {0.636779,1.389787},
+  {-0.824128,-0.335895},
+  {0.607159,0.420643},
+  {1.373971,-0.342893},
+  {-0.910657,0.837440},
+  {1.034973,-0.352405},
+  {1.085682,1.920129},
+  {0.064748,0.257708},
+  {0.862755,0.755955},
+  {-0.684932,0.094005},
+  {0.112119,-1.441972},
+  {1.163420,-0.049867},
+  {-0.635217,0.609453},
+  {-0.238855,0.480435},
+  {1.449328,-0.098448},
+  {0.784127,-0.652244},
+  {0.769041,-0.937921},
+  {0.835573,0.295585},
+  {-0.062899,1.494506},
+  {-0.062220,0.228891},
+  {0.481334,-0.470990},
+  {-0.505073,0.374573},
+  {-0.099382,-0.967523},
+  {1.186319,-0.831618},
+  {-0.399300,0.931511},
+  {-1.524902,-0.985501},
+  {-0.615012,0.547274},
+  {0.268857,-0.076929},
+  {-0.897427,1.088771},
+  {1.055351,0.095282},
+  {1.708821,-0.076167},
+  {-0.739946,-0.354375},
+  {0.373417,0.855748},
+  {0.131967,0.285461},
+  {-0.364408,-1.708271},
+  {-1.014175,0.495565},
+  {0.505787,1.003443},
+  {0.391683,-0.524584},
+  {0.752228,0.882360},
+  {-0.394883,1.502965},
+  {-0.997717,-0.172972},
+  {-0.230813,0.301756},
+  {0.669804,-0.121530},
+  {-0.070862,-0.368520},
+  {1.320153,-0.521160},
+  {-1.390873,0.259563},
+  {1.146922,0.597540},
+  {0.281829,-0.449891},
+  {0.295038,0.408987},
+  {-0.202209,-1.183362},
+  {-0.399018,-0.672154},
+  {1.004778,-1.104954},
+  {0.143005,0.049996},
+  {0.232512,0.669719},
+  {0.094630,-0.576997},
+  {0.667844,0.367973},
+  {-0.537996,0.626066},
+  {1.033757,-0.285931},
+  {0.992368,-0.514368},
+  {-0.319021,0.248041},
+  {1.579195,-0.231515},
+  {-0.582862,0.913516},
+  {-1.085018,0.556959},
+  {-0.024787,0.559586},
+  {0.402267,0.959849},
+  {-0.032095,-0.548640},
+  {-1.150115,-0.539607},
+  {0.385566,-0.409285},
+  {-1.471116,0.537079},
+  {0.392795,-1.486643},
+  {0.328634,-0.040776},
+  {-0.084120,0.830458},
+  {-0.524122,0.922066},
+  {-0.416595,-0.044276},
+  {0.100140,0.462444},
+  {-0.590881,1.340948},
+  {-0.891718,0.723849},
+  {0.337707,-0.670773},
+  {0.721537,0.536058},
+  {0.059957,0.287448},
+  {0.400511,-0.763103},
+  {-0.550953,-0.197097},
+  {0.591824,0.441947},
+  {0.447746,-0.502807},
+  {-0.167608,-0.888259},
+  {1.103233,-1.437809},
+  {0.199023,0.063524},
+  {0.202555,0.322043},
+  {-0.976584,-0.396812},
+  {0.372419,-0.791595},
+  {1.289941,0.357281},
+  {-0.228916,-1.001487},
+  {1.049654,-0.610849},
+  {-1.054080,-0.370253},
+  {0.859058,-0.644741},
+  {-0.377507,0.207554},
+  {-0.559546,0.074691},
+  {-1.074664,1.355183},
+  {0.305625,0.198544},
+  {-0.606985,0.356763},
+  {0.242896,-0.375304},
+  {-0.749774,-0.181054},
+  {-0.342246,-0.259054},
+  {1.589396,1.010118},
+  {1.140405,-0.864599},
+  {-1.096629,-0.377337},
+  {-0.496940,0.605907},
+  {-0.664267,-0.651997},
+  {0.951590,0.175420},
+  {-1.117929,-0.261231},
+  {-0.534170,0.241918},
+  {-0.781527,0.244559},
+  {-0.271591,0.486803},
+  {-1.256120,0.858586},
+  {-0.421249,0.405847},
+  {0.479353,-0.525636},
+  {0.209101,0.142047},
+  {-0.083113,0.886645},
+  {-0.471083,-0.416663},
+  {0.011834,-0.389550},
+  {0.669072,-1.245624},
+  {-0.598668,0.117422},
+  {-0.173989,-0.056465},
+  {-0.922954,0.482571},
+  {0.522571,-0.365634},
+  {0.042361,1.106480},
+  {0.655395,-0.034779},
+  {0.631652,-0.294389},
+  {1.527036,-0.058525},
+  {-0.249208,0.459807},
+  {-0.887983,-0.627558},
+  {-0.289353,-1.411403},
+  {0.054751,2.470137},
+  {-0.248717,1.053043},
+  {-0.735576,0.010779},
+  {-0.514003,-0.279226},
+  {0.305765,1.274540},
+  {0.534981,0.774853},
+  {0.392611,-0.644576},
+  {-0.468937,1.078119},
+  {-0.541705,1.414380},
+  {0.277103,0.165488},
+  {-0.387851,-0.830792},
+  {-1.253914,0.532510},
+  {-0.221315,1.797991},
+  {0.274370,0.277949},
+  {-1.765567,0.046853},
+  {-0.327146,-0.297614},
+  {-0.984489,-0.168465},
+  {-0.660634,-0.450022},
+  {0.198917,-0.218025},
+  {-0.677175,-0.172085},
+  {0.644052,0.285876},
+  {0.088023,0.232635},
+  {-0.451399,-1.512956},
+  {-0.377844,-0.626486},
+  {-0.362430,-0.127407},
+  {-0.840019,0.380215},
+  {0.114939,0.878416},
+  {0.470442,-0.105566},
+  {-0.585039,0.237390},
+  {-0.815600,-0.504437},
+  {-0.161445,0.036143},
+  {0.296359,1.325861},
+  {-0.322171,-1.669738},
+  {1.477603,0.776825},
+  {0.381550,-0.635687},
+  {-0.694525,-0.559498},
+  {-1.930663,-0.704911},
+  {-0.449682,-0.545347},
+  {0.026977,-0.127266},
+  {0.233908,0.544153},
+  {-0.863452,-0.074155},
+  {-0.649361,2.113175},
+  {-1.059833,0.624585},
+  {0.846892,-1.573266},
+  {-0.217441,-0.559443},
+  {-0.160678,1.002391},
+  {0.804081,-0.338683},
+  {-1.541742,0.230370},
+  {-0.503421,-0.416987},
+  {1.028147,0.529024},
+  {-0.596178,0.738456},
+  {-1.173493,0.202724},
+  {-0.297988,-0.661943},
+  {0.302419,0.866482},
+  {-0.521944,-1.270284},
+  {-0.436218,-0.097784},
+  {-0.264531,-0.550600},
+  {1.014478,-0.038692},
+  {-0.999085,0.486181},
+  {1.440740,-0.371893},
+  {-0.042694,0.067326},
+  {0.093956,-0.957300},
+  {-0.375195,-0.970154},
+  {-0.251632,-1.304492},
+  {-0.414494,1.099568},
+  {0.017527,0.168563},
+  {-1.263777,0.285450},
+  {0.068131,0.327754},
+  {1.105079,0.539763},
+  {0.981225,-0.468582},
+  {0.551992,-0.036035},
+  {1.124159,-0.005432},
+  {0.611806,-0.979175},
+  {0.483684,-0.518734},
+  {-0.366983,0.455012},
+  {-1.008954,0.471497},
+  {-0.133646,-0.509659},
+  {-1.029489,0.006309},
+  {0.530972,-0.509375},
+  {1.140833,0.249621},
+  {-0.211773,0.138957},
+  {-0.537149,1.254415},
+  {-0.213279,0.065513},
+  {-1.082796,0.529235},
+  {0.350453,0.444304},
+  {0.031279,-0.234978},
+  {-0.543908,0.234837},
+  {0.487194,1.375390},
+  {0.215563,-0.549211},
+  {0.072623,0.165267},
+  {0.801105,-0.987048},
+  {0.269412,0.711896},
+  {0.027622,0.562303},
+  {-0.813866,-0.782547},
+  {-0.093912,0.227673},
+  {-0.172055,0.060514},
+  {0.074656,-0.266314},
+  {1.217632,-0.605089},
+  {-0.535103,-0.616239},
+  {0.151379,-0.076634},
+  {0.642760,-0.481053},
+  {0.035701,-0.056708},
+  {0.980441,-1.299210},
+  {-0.856956,-1.002073},
+  {0.598486,0.466839},
+  {-0.386966,-1.046460},
+  {0.625117,-0.115207},
+  {-0.260750,-0.041046},
+  {0.076652,-0.932881},
+  {0.265818,0.764649},
+  {0.421985,-0.714312},
+  {-0.601085,0.964101},
+  {0.467187,-0.124653},
+  {-0.387454,0.211856},
+  {-0.157263,-0.585296},
+  {0.418027,-0.077462},
+  {1.583309,-0.609096},
+  {0.884257,0.515131},
+  {0.138889,-0.138020},
+  {-0.169847,0.059272},
+  {0.540075,0.309144},
+  {0.557179,1.418778},
+  {0.610912,0.512799},
+  {-0.873253,0.692568},
+  {0.120274,-0.853970},
+  {-0.586573,-0.561751},
+  {-0.672660,0.694987},
+  {1.109601,0.008173},
+  {1.003841,-0.652223},
+  {0.874688,0.367941},
+  {-0.330203,0.745219},
+  {-0.753140,0.915769},
+  {-0.696116,0.227309},
+  {0.346841,0.100445},
+  {0.740158,-0.250985},
+  {-0.397857,0.594584},
+  {1.110536,0.339610},
+  {0.345296,-0.347319},
+  {-0.907915,-0.471159},
+  {-0.649958,1.565001},
+  {0.775790,-0.287460},
+  {1.032125,0.130026},
+  {0.907496,1.390180},
+  {0.298254,-1.588717},
+  {-0.259348,0.502732},
+  {0.220840,-0.783740},
+  {-0.138042,-0.590126},
+  {0.426154,-0.091085},
+  {0.405208,0.611676},
+  {-0.204049,-0.083068},
+  {0.159682,0.740970},
+  {0.942561,0.693500},
+  {-0.610743,0.303196},
+  {0.172349,1.598668},
+  {1.627400,-0.281164},
+  {0.551930,0.098748},
+  {-0.388243,0.433245},
+  {-1.235033,0.763915},
+  {-0.744667,-0.561124},
+  {-0.592271,-0.641181},
+  {0.156840,0.347964},
+  {-0.023119,0.533539},
+  {0.011757,1.073952},
+  {-1.186307,0.280738},
+  {0.756950,1.492111},
+  {-0.877649,0.112185},
+  {-0.585789,-0.254425},
+  {0.038438,-0.550157},
+  {0.314995,0.322778},
+  {-0.134760,0.871567},
+  {-1.044096,-0.636270},
+  {0.590711,0.558388},
+  {0.209019,0.293453},
+  {-0.599300,0.026492},
+  {1.033710,-0.675529},
+  {-1.954583,0.594947},
+  {-0.182764,0.343157},
+  {0.859978,0.329311},
+  {0.646436,-0.806192},
+  {-0.046664,0.909861},
+  {1.093129,0.536020},
+  {0.872300,0.678087},
+  {-0.123750,0.457168},
+  {0.551871,-0.941036},
+  {0.794294,-0.407648},
+  {-1.538821,-0.171563},
+  {-1.035249,0.118770},
+  {-0.348383,-0.118152},
+  {-0.226615,-0.889496},
+  {1.341554,0.160355},
+  {-0.351517,-0.424568},
+  {-0.070817,0.414649},
+  {-0.442786,0.423882},
+  {-0.388425,1.093738},
+  {-0.582796,0.676209},
+  {0.752177,0.821946},
+  {-1.006474,0.412201},
+  {-0.416449,-0.072394},
+  {-0.911661,1.041543},
+  {0.003509,0.102477},
+  {0.196127,0.591685},
+  {0.326262,-0.526969},
+  {-1.042304,0.505778},
+  {-1.505353,-1.006878},
+  {-0.951996,-1.085898},
+  {-0.317499,0.045335},
+  {-0.099205,0.858056},
+  {0.764524,1.480639},
+  {0.517856,0.207770},
+  {-0.742181,0.240161},
+  {-0.555104,-0.871874},
+  {-0.699238,-0.986373},
+  {-0.763561,-1.000094},
+  {0.670026,-0.733751},
+  {0.662880,-0.655407},
+  {0.119571,-1.657008},
+  {-0.223206,-1.113342},
+  {0.487176,0.474053},
+  {0.192200,1.888510},
+  {0.611398,-0.667669},
+  {-1.403757,0.409866},
+  {0.024463,-0.041370},
+  {-0.609262,0.806420},
+  {-0.907307,1.198974},
+  {0.162117,-1.544459},
+  {-0.796786,0.537950},
+  {-0.387992,-0.266020},
+  {-0.225214,-0.058790},
+  {0.753621,0.972150},
+  {-0.615864,1.401833},
+  {-0.819524,-0.597168},
+  {0.647379,-0.468126},
+  {-0.655050,-0.432251},
+  {-0.069667,-1.062873},
+  {0.359295,0.145826},
+  {0.647484,0.920104},
+  {-0.101287,-0.687857},
+  {0.695485,0.112454},
+  {0.685476,-0.236214},
+  {0.374271,-0.144157},
+  {-1.779720,-0.300198},
+  {0.145786,0.213707},
+  {0.038580,-0.033343},
+  {0.672791,1.277813},
+  {0.479531,1.053826},
+  {-0.907617,-0.059189},
+  {-0.172751,0.074425},
+  {-0.349068,0.726073},
+  {0.008332,0.348492},
+  {0.319315,-0.391381},
+  {0.402430,0.078896},
+  {-0.391121,0.722606},
+  {0.081394,0.035975},
+  {0.604639,0.636573},
+  {-0.598326,-0.581740},
+  {-1.369758,1.353076},
+  {-1.032156,-0.428532},
+  {-0.405163,0.809273},
+  {-0.638386,-0.671499},
+  {-1.571366,-0.098790},
+  {-0.047946,-0.327424},
+  {-0.535140,1.485649},
+  {0.572495,-0.533611},
+  {0.769134,-0.416792},
+  {-0.122776,0.855205},
+  {0.281802,-0.669203},
+  {0.694392,-0.350054},
+  {-0.516665,0.498350},
+  {-1.145787,0.669606},
+  {-0.587504,-1.078295},
+  {-0.906257,1.099786},
+  {0.713687,-0.104260},
+  {0.500828,-1.120030},
+  {0.201346,0.446714},
+  {0.571867,0.307374},
+  {-0.307728,1.383134},
+  {-0.066681,0.450119},
+  {-0.848761,-1.038823},
+  {1.032712,0.224183},
+  {0.061333,-0.310979},
+  {0.468093,0.223010},
+  {-0.199854,-0.913527},
+  {-0.857930,0.211259},
+  {-0.587648,-0.245449},
+  {0.353839,-0.297458},
+  {0.888759,-0.874265},
+  {0.403853,-0.386048},
+  {0.278338,0.103402},
+  {-0.538262,-0.477405},
+  {-0.028885,1.451692},
+  {0.309332,0.336400},
+  {-0.000990,0.952112},
+  {0.551432,0.708093},
+  {0.885608,0.394472},
+  {0.630507,0.873531},
+  {2.009406,0.830925},
+  {0.270462,0.962180},
+  {-0.188686,0.224709},
+  {-0.176674,-0.183785},
+  {0.140600,1.093924},
+  {0.189660,-0.420077},
+  {-0.523965,-0.625934},
+  {-0.336031,0.037125},
+  {0.082479,-0.028029},
+  {-0.186355,-0.412999},
+  {0.082385,1.314585},
+  {-0.916720,0.023372},
+  {0.361526,0.970313},
+  {-1.036301,0.902711},
+  {0.753404,-1.144667},
+  {1.331139,0.200917},
+  {0.079871,0.568019},
+  {0.105169,-0.612822},
+  {-1.203528,-0.279910},
+  {0.681629,-0.484965},
+  {1.737185,-1.163903},
+  {-0.073538,-0.938369},
+  {0.199483,0.191980},
+  {-0.463281,0.147863},
+  {0.502202,1.383967},
+  {0.662814,-0.696233},
+  {0.322913,-0.224863},
+  {-0.039758,-0.433784},
+  {-0.241469,0.133004},
+  {0.631311,-0.203045},
+  {-0.490926,0.738562},
+  {-0.738987,-0.807033},
+  {-0.559719,-1.710482},
+  {0.414458,-1.114866},
+  {0.217559,-1.101081},
+  {2.001337,-0.837311},
+  {-0.309366,-1.325185},
+  {-0.421962,-0.105397},
+  {-0.254192,0.250041},
+  {0.149750,1.424141},
+  {0.574641,-0.960555},
+  {1.300898,0.408217},
+  {1.120122,-0.397386},
+  {0.988203,-0.705869},
+  {0.025219,-0.318984},
+  {-0.787385,0.484271},
+  {0.244498,-1.167668},
+  {-0.293105,1.187101},
+  {-1.315942,-0.787983},
+  {0.014455,0.371305},
+  {0.454436,-0.013107},
+  {-0.983662,0.592077},
+  {-0.500665,0.485289},
+  {-0.822873,-0.988985},
+  {-0.684186,0.119209},
+  {-0.770508,0.745145},
+  {0.751135,0.857208},
+  {0.580580,-0.403847},
+  {-0.261483,0.001789},
+  {-0.599543,0.700149},
+  {-0.134033,0.276866},
+  {1.292787,0.681824},
+  {0.571468,-0.079806},
+  {-0.420807,-0.237937},
+  {-1.393211,-1.148364},
+  {-0.826257,-0.341136},
+  {-1.430113,-0.469738},
+  {0.254639,-0.935916},
+  {0.477547,-0.063091},
+  {0.143719,-0.656087},
+  {-1.043832,-1.865735},
+  {-0.223533,-0.255380},
+  {-0.347852,1.319428},
+  {0.216353,0.217898},
+  {0.751324,-0.392111},
+  {0.126306,0.463054},
+  {0.421776,0.953244},
+  {0.101965,0.723898},
+  {0.711760,0.644511},
+  {1.214540,-0.992251},
+  {-0.900924,0.851336},
+  {-0.768326,-0.273583},
+  {0.611353,-0.777963},
+  {-0.644784,-0.597365},
+  {-0.866147,-0.077811},
+  {1.171992,-0.373912},
+  {0.166663,0.845840},
+  {-0.051581,-0.037914},
+  {-0.044931,0.952456},
+  {1.025787,0.092280},
+  {0.682561,1.339457},
+  {-0.392748,0.417949},
+  {0.032937,0.238781},
+  {-0.620218,-0.190434},
+  {-0.281839,0.385357},
+  {-1.841805,0.735532},
+  {0.803464,0.390506},
+  {-0.520705,-1.106509},
+  {-0.231873,-0.372118},
+  {1.238221,-0.126795},
+  {0.021599,0.567909},
+  {0.135681,0.509549},
+  {-0.372477,0.993091},
+  {-0.463447,2.094221},
+  {-1.084856,0.187484},
+  {-0.146659,-0.233581},
+  {0.020933,-0.106898},
+  {0.829958,0.011197},
+  {-0.094014,-0.883021},
+  {0.547873,-0.450064},
+  {0.202885,1.034507},
+  {0.994910,0.329836},
+  {1.331541,-0.281977},
+  {0.228948,-2.008565},
+  {-0.478031,0.427230},
+  {1.083612,-1.020268},
+  {-0.249602,1.393039},
+  {-0.012306,0.044320},
+  {0.574595,-0.315582},
+  {0.774972,-0.431653},
+  {0.270253,1.094467},
+  {0.120273,-0.263953},
+  {1.016864,0.431796},
+  {-0.309168,-0.270309},
+  {-1.523819,0.385376},
+  {-0.763456,0.512232},
+  {0.336560,0.850508},
+  {0.042057,-0.438179},
+  {0.847706,-0.456465},
+  {0.742120,0.530981},
+  {-0.373430,-1.277644},
+  {0.670180,-1.752892},
+  {-0.817789,0.218930},
+  {0.452251,-0.077324},
+  {-0.072623,-0.105395},
+  {-1.412266,-1.332875},
+  {0.357278,0.516348},
+  {-0.043991,-1.067616},
+  {1.180654,-0.141604},
+  {0.105626,-0.698556},
+  {0.368029,0.262566},
+  {-0.920419,0.474313},
+  {-0.223634,0.572453},
+  {0.361011,0.280134},
+  {0.558817,0.182521},
+  {0.561101,0.605270},
+  {0.229716,-0.019313},
+  {-0.434761,-0.308359},
+  {-0.245133,0.726120},
+  {-0.390881,-1.251642},
+  {-0.250035,-1.268882},
+  {1.655818,-0.092527},
+  {-0.910120,0.060578},
+  {-0.188804,-0.314052},
+  {1.215279,-0.127738},
+  {-0.878795,0.285774},
+  {0.369799,-0.207177},
+  {0.389388,0.134644},
+  {0.047652,0.563269},
+  {0.447321,-0.865163},
+  {-0.080775,-0.368620},
+  {-1.003217,-0.560501},
+  {0.115756,0.065585},
+  {0.736376,-0.286535},
+  {-0.305092,0.029092},
+  {0.016444,-0.133073},
+  {-0.385179,-0.465072},
+  {-0.411212,-0.129245},
+  {-2.027827,0.247035},
+  {-0.408223,-0.432254},
+  {-0.623146,-0.096782},
+  {0.066094,0.359122},
+  {-0.658791,1.673232},
+  {0.345053,0.994307},
+  {0.475042,-0.520856},
+  {-0.629916,0.001245},
+  {0.231530,-0.112516},
+  {-0.310512,0.763089},
+  {0.351545,-0.857181},
+  {-1.282645,0.358697},
+  {0.265706,-0.200202},
+  {-1.020432,-0.205901},
+  {-0.450405,0.863954},
+  {0.535266,-1.489977},
+  {0.116972,-0.830045},
+  {-0.574343,0.203469},
+  {-1.234327,0.190012},
+  {-0.671839,0.202848},
+  {-0.511748,0.717934},
+  {-0.667350,-0.498889},
+  {0.062991,-0.257410},
+  {1.387187,0.166053},
+  {0.038892,-0.294788},
+  {-0.197843,-1.474079},
+  {0.842538,0.954516},
+  {0.190780,-0.445425},
+  {0.986009,0.305338},
+  {-0.043897,-0.600633},
+  {1.275066,0.500597},
+  {0.688402,0.940529},
+  {0.681829,1.527615},
+  {1.058668,0.147151},
+  {1.057440,0.219391},
+  {0.279102,0.711516},
+  {-0.735985,-0.916082},
+  {-0.795380,0.473156},
+  {-0.188000,-0.126179},
+  {-0.130109,1.022084},
+  {-0.255161,-0.611966},
+  {-0.712545,0.512778},
+  {-0.390866,-0.023470},
+  {0.585919,0.072051},
+  {0.265748,-0.113116},
+  {-0.954015,0.396356},
+  {1.150886,0.526901},
+  {0.918889,-0.335352},
+  {0.908329,-0.918572},
+  {0.829812,1.271961},
+  {0.385431,0.764974},
+  {0.842191,0.817413},
+  {-0.211592,-0.300848},
+  {0.085412,-0.503896},
+  {-0.295625,-1.210188},
+  {0.553279,-0.752066},
+  {-0.336870,-0.023617},
+  {-0.117579,0.194043},
+  {-0.439305,0.074470},
+  {-0.871696,0.517667},
+  {1.132128,-0.352925},
+  {1.659963,0.078571},
+  {-0.718459,1.770532},
+  {-0.815585,0.052456},
+  {0.462433,-0.846664},
+  {0.112519,-0.115914},
+  {0.351286,0.311147},
+  {0.445398,1.030217},
+  {-1.336584,0.196926},
+  {1.720238,-0.567869},
+  {-0.036464,0.802003},
+  {-0.783873,-0.818943},
+  {1.240642,0.976164},
+  {0.760370,0.622208},
+  {0.716383,0.043453},
+  {0.007335,0.445271},
+  {-1.912350,0.369577},
+  {0.471466,-0.281855},
+  {-1.259278,0.458071},
+  {-0.505514,0.551813},
+  {0.808326,0.336688},
+  {0.134236,0.795999},
+  {-1.110478,0.657803},
+  {0.788157,-1.379746},
+  {-0.602157,-0.601484},
+  {-0.601597,-0.629413},
+  {-0.562336,-0.375857},
+  {-0.115154,-0.348384},
+  {-1.337893,-0.034902},
+  {-0.421096,-0.451334},
+  {0.828483,1.195515},
+  {-1.170578,-0.527504},
+  {-0.310432,0.760422},
+  {-1.197816,0.709533},
+  {-0.127652,-0.091019},
+  {0.069065,-0.305886},
+  {-0.078245,-0.633251},
+  {0.088257,0.108119},
+  {-0.449101,0.132235},
+  {-0.124084,1.428966},
+  {-0.281890,0.234157},
+  {-0.525617,0.582656},
+  {-0.816034,0.676694},
+  {0.126295,-0.336684},
+  {0.148247,0.687522},
+  {-0.650085,0.552353},
+  {1.047440,-0.871696},
+  {-0.652720,0.124596},
+  {0.143902,-0.299925},
+  {-0.045092,-0.377154},
+  {0.337776,-0.360983},
+  {-1.034746,-0.453121},
+  {0.446298,-0.614523},
+  {-0.576398,-0.186150},
+  {-0.660111,0.507337},
+  {-0.212991,-0.067267},
+  {-0.472959,0.233856},
+  {0.757097,0.921087},
+  {-0.371281,-0.873578},
+  {-0.462358,-0.546336},
+  {1.046260,0.861505},
+  {0.188323,-0.927420},
+  {-0.394811,-0.928531},
+  {-0.745356,1.802213},
+  {-0.144337,1.288925},
+  {0.042964,0.393180},
+  {-1.051774,-0.538140},
+  {-0.859913,-0.181454},
+  {-0.768838,-0.081829},
+  {-0.410304,-0.505518},
+  {0.513469,-0.829740},
+  {0.143379,-0.353562},
+  {0.259461,-0.349013},
+  {-0.693666,0.506081},
+  {-0.142532,-1.125624},
+  {0.027827,0.093478},
+  {0.755859,-1.261207},
+  {-0.805314,0.460203},
+  {0.565516,0.049003},
+  {-0.290886,-0.435227},
+  {0.177884,1.134761},
+  {-0.790097,-1.155042},
+  {0.609440,-0.427450},
+  {-1.456648,0.430752},
+  {0.731694,0.148750},
+  {-1.096537,-0.659722},
+  {-0.045365,-0.812621},
+  {-0.052870,-0.012892},
+  {-0.186133,-1.655777},
+  {-1.233724,0.005300},
+  {0.227544,-0.206169},
+  {0.444051,-1.393497},
+  {0.145246,-0.470748},
+  {0.321554,-0.540005},
+  {0.574299,0.947717},
+  {-0.851562,0.821642},
+  {-0.224767,0.375636},
+  {-1.247393,-1.880826},
+  {0.869151,0.644628},
+  {1.350218,-0.621884},
+  {0.386796,-0.520246},
+  {-0.978645,0.272595},
+  {0.065436,-0.430137},
+  {-0.790944,0.646567},
+  {-0.368160,0.501998},
+  {-0.401020,0.148140},
+  {-0.046369,-0.202567},
+  {0.058994,-0.870889},
+  {-0.652756,1.932327},
+  {0.172676,-1.271166},
+  {0.413797,0.955612},
+  {0.814433,0.006399},
+  {0.328790,1.584645},
+  {0.709699,0.490172},
+  {-0.774854,-0.005901},
+  {0.730751,-2.130532},
+  {0.585216,-0.058045},
+  {0.745170,-0.426331},
+  {-0.547863,0.536897},
+  {0.291419,0.183834},
+  {0.370049,-0.225214},
+  {0.720345,0.700864},
+  {-0.658056,0.512990},
+  {-0.197299,-0.572787},
+  {-0.980329,-0.373197},
+  {-0.102615,-0.600997},
+  {0.551575,0.035526},
+  {0.227213,-1.755647},
+  {-0.720773,1.473189},
+  {1.078551,0.494038},
+  {-0.590708,-0.726487},
+  {0.174511,0.593049},
+  {-1.113569,-0.861532},
+  {-0.863915,-0.407862},
+  {-1.489835,0.680252},
+  {0.605744,-0.755458},
+  {0.019818,-1.444399},
+  {1.537532,0.420513},
+  {0.454858,0.278244},
+  {-1.167997,0.522964},
+  {0.636516,0.864054},
+  {0.904913,0.954676},
+  {-0.172054,1.515377},
+  {-0.323955,-0.109815},
+  {-0.408556,-0.110050},
+  {-0.074129,0.608238},
+  {0.907023,0.611414},
+  {0.527238,-0.111692},
+  {-1.210925,1.026236},
+  {0.414338,-1.508815},
+  {0.865041,0.205104},
+  {-0.519846,0.335515},
+  {0.025669,0.894116},
+  {-0.069780,0.825868},
+  {-0.977589,0.602818},
+  {-1.474683,-1.465573},
+  {-0.906716,-1.172873},
+  {0.633533,-0.164525},
+  {1.348636,-0.597077},
+  {-0.676391,-0.863396},
+  {0.836835,0.681102},
+  {0.597157,-0.230220},
+  {0.394546,0.387985},
+  {-0.930641,0.087960},
+  {-0.591838,-0.300588},
+  {-0.886742,0.109750},
+  {-1.099630,-1.113304},
+  {-0.728393,-0.212042},
+  {0.763934,-0.639567},
+  {0.298122,-0.353191},
+  {-0.190079,-0.338979},
+  {0.348171,0.548532},
+  {-0.524688,-0.411727},
+  {0.233072,-0.517023},
+  {0.062224,-0.491644},
+  {-1.043832,0.098989},
+  {-0.476795,-1.490535},
+  {0.329321,0.234013},
+  {0.221229,0.925059},
+  {-0.390816,0.510160},
+  {0.875961,0.263989},
+  {0.269341,0.588287},
+  {-0.104352,1.572109},
+  {-0.466807,-0.291013},
+  {0.052197,0.507006},
+  {-1.203065,0.707042},
+  {-1.156324,0.471411},
+  {0.754021,-0.321351},
+  {-0.351852,0.063256},
+  {1.050723,-0.239489},
+  {0.095218,-0.048337},
+  {-1.306553,-0.315263},
+  {0.445850,-0.782225},
+  {2.486118,-0.184109},
+  {-0.450901,0.744972},
+  {0.815191,-0.335411},
+  {-0.842677,-0.284237},
+  {0.315266,-0.974383},
+  {0.075656,-0.930034},
+  {-0.265583,0.430262},
+  {-0.066361,-0.215722},
+  {0.460555,-0.264005},
+  {0.338359,-1.339680},
+  {-0.711655,0.100374},
+  {-0.092740,1.377253},
+  {-0.072264,-0.288660},
+  {-0.052467,0.772709},
+  {0.293775,0.090349},
+  {0.824527,1.267417},
+  {-0.112363,0.132903},
+  {-0.363463,0.969263},
+  {-1.642345,0.744705},
+  {-0.477562,1.379558},
+  {-0.589734,-0.589188},
+  {-0.466736,-0.970264},
+  {0.010874,0.547445},
+  {1.722207,0.884766},
+  {0.098718,-0.666330},
+  {-0.296542,-1.569936},
+  {1.125261,-0.712730},
+  {-0.975173,0.932793},
+  {0.634325,1.085860},
+  {0.217421,0.671107},
+  {0.305540,-1.001059},
+  {0.798078,0.480317},
+  {1.662060,-0.279516},
+  {0.613269,-0.820772},
+  {-0.367006,0.253467},
+  {-0.506871,0.590810},
+  {2.014429,-0.631055},
+  {-1.851417,-0.047491},
+  {0.237869,-0.702116},
+  {-0.850494,0.647305},
+  {0.129418,-0.098577},
+  {-0.842460,0.401123},
+  {0.289509,-0.445374},
+  {-0.192546,0.423623},
+  {0.132945,-0.395475},
+  {1.171623,-0.137565},
+  {-0.672710,0.703577},
+  {0.289266,0.112169},
+  {0.388150,-1.503414},
+  {-0.632542,-1.193749},
+  {-0.836479,-1.570629},
+  {-0.117854,0.799663},
+  {-1.031422,0.769983},
+  {1.141551,1.223726},
+  {-0.136202,0.032976},
+  {0.539139,-0.362692},
+  {0.386391,-0.404400},
+  {-0.807908,0.672289},
+  {-0.273757,0.409065},
+  {0.072317,0.218765},
+  {0.315393,-0.161862},
+  {0.109827,0.280521},
+  {1.124393,-0.880358},
+  {1.062493,-0.861810},
+  {-0.694576,0.955105},
+  {-0.704939,0.712260},
+  {0.620207,0.404908},
+  {-0.149497,0.008919},
+  {0.213315,0.753410},
+  {0.882143,0.344575},
+  {-0.580178,-0.062246},
+  {0.588335,0.732016},
+  {-0.923274,0.056641},
+  {-0.172440,-0.095349},
+  {-1.135217,0.278840},
+  {0.775523,-0.339523},
+  {-0.314081,-0.344806},
+  {-0.764043,-0.198468},
+  {-0.089438,-0.785644},
+  {-1.040912,1.061657},
+  {0.895079,-0.034029},
+  {-0.526144,-1.937661},
+  {-0.207926,-1.120596},
+  {-0.091010,-0.505344},
+  {0.284329,0.647329},
+  {1.276309,-0.095555},
+  {-1.225333,0.215700},
+  {0.090999,0.073973},
+  {0.870768,-0.363724},
+  {0.248731,0.020068},
+  {-0.548422,-0.119689},
+  {0.920298,-0.082783},
+  {-0.467797,1.355912},
+  {1.329022,-0.309356},
+  {-1.728073,-0.120729},
+  {0.624453,0.563478},
+  {-0.698755,0.502237},
+  {0.401369,-1.301986},
+  {-0.924123,-0.248924},
+  {0.419063,-0.429884},
+  {-0.417802,0.312480},
+  {0.303873,0.281815},
+  {-0.216253,-0.382458},
+  {0.871156,0.437237},
+  {0.076165,-0.075358},
+  {0.978428,0.177972},
+  {-0.387862,-0.666285},
+  {-0.385355,-1.084756},
+  {-0.039386,0.090518},
+  {-0.110409,-0.131921},
+  {-0.266880,-0.746409},
+  {-0.628974,0.648673},
+  {-0.473564,-0.126878},
+  {0.061978,-0.647717},
+  {-0.282066,-0.853113},
+  {-0.118735,1.327370},
+  {1.149891,1.209448},
+  {0.352147,-0.388989},
+  {1.769291,-0.319750},
+  {0.764107,-0.667852},
+  {-0.587102,-0.210417},
+  {1.015087,0.052787},
+  {-0.035987,1.195230},
+  {0.892858,0.405185},
+  {-0.756342,-0.517984},
+  {0.623213,-0.595297},
+  {0.604408,1.193989},
+  {0.953219,0.110624},
+  {0.152238,0.507352},
+  {-0.094461,-0.308558},
+  {0.384838,-0.277351},
+  {0.025861,-0.759865},
+  {-0.657839,0.460731},
+  {-0.194513,0.533848},
+  {1.023904,-0.500503},
+  {-0.359781,0.642104},
+  {-0.404128,-0.973247},
+  {0.908211,-0.748690},
+  {1.828527,0.178212},
+  {0.993783,0.377209},
+  {0.497713,0.653823},
+  {1.349187,-0.664650},
+  {0.867764,-0.677804},
+  {0.784912,-0.648229},
+  {0.855189,0.283978},
+  {-0.177741,0.486565},
+  {0.171991,-1.590330},
+  {-0.341884,-0.551188},
+  {0.552575,-1.140915},
+  {0.234083,-0.731475},
+  {-0.841477,0.261885},
+  {-0.463546,1.015421},
+  {-0.655670,-0.933363},
+  {0.091412,-0.144388},
+  {0.777763,-1.143306},
+  {0.393413,0.247097},
+  {-0.859657,1.263778},
+  {-0.091360,-0.695528},
+  {0.453558,0.447697},
+  {-0.285448,-0.091432},
+  {0.575826,0.771546},
+  {-0.185321,-0.400092},
+  {-0.927254,-0.065710},
+  {-0.404850,0.199127},
+  {1.175847,-0.727493},
+  {-0.646317,-0.100079},
+  {-0.146116,0.997661},
+  {0.940721,0.331262},
+  {-0.176631,-0.432014},
+  {-0.158682,0.007962},
+  {0.403128,0.862988},
+  {-1.286299,-0.553118},
+  {-0.625140,-0.416925},
+  {0.164739,0.127397},
+  {-1.296657,0.431593},
+  {0.110012,0.621031},
+  {0.131967,0.747297},
+  {-0.417073,-0.528516},
+  {-0.058879,0.064701},
+  {0.878022,0.417763},
+  {-0.593777,-0.749282},
+  {-1.488954,-0.088751},
+  {0.327350,0.729740},
+  {0.288635,0.711133},
+  {-0.516210,0.772244},
+  {0.646623,-0.360133},
+  {0.517444,-1.050468},
+  {0.275757,-0.042346},
+  {1.091949,-0.723761},
+  {-0.581401,0.804300},
+  {-0.281716,0.298812},
+  {0.389729,-1.352334},
+  {0.968056,-0.125904},
+  {1.044800,0.400574},
+  {0.876008,0.171549},
+  {-0.861513,-0.111525},
+  {1.321833,0.560932},
+  {-0.756588,0.179387},
+  {-1.030283,-0.202424},
+  {-1.125655,0.034160},
+  {-1.018706,0.236765},
+  {-1.619937,1.162817},
+  {0.587348,0.547688},
+  {-1.197305,-0.512869},
+  {-0.043864,-1.074949},
+  {-0.830876,0.394422},
+  {0.164382,-0.058257},
+  {-1.269143,0.168948},
+  {0.160676,-0.664515},
+  {-0.505345,-1.100780},
+  {-0.245201,0.068290},
+  {-1.306518,-0.678766},
+  {-0.425379,0.392774},
+  {-0.258367,0.204147},
+  {0.045519,-0.256474},
+  {-2.017382,0.265548},
+  {-0.452550,0.579091},
+  {-0.340566,-0.079455},
+  {-0.463289,-0.473197},
+  {-0.304125,-1.146060},
+  {-1.079937,0.770227},
+  {0.697733,-1.635291},
+  {0.794379,-0.590399},
+  {2.066159,0.237608},
+  {0.203241,0.228367},
+  {0.209470,-0.821393},
+  {1.064899,-0.383132},
+  {0.799363,-0.151461},
+  {-0.607846,0.619438},
+  {-0.440935,-0.199774},
+  {1.095711,0.112102},
+  {-0.687980,-0.399792},
+  {-0.489549,0.143813},
+  {0.567918,0.022705},
+  {0.838391,-1.106572},
+  {1.085598,2.516036},
+  {-0.699425,-0.521144},
+  {-1.195329,-0.973063},
+  {-0.455357,0.190010},
+  {-0.365438,-0.562397},
+  {-0.303810,-1.368273},
+  {0.466171,-0.926118},
+  {-0.428213,0.660771},
+  {0.847118,1.179101},
+  {0.431831,0.765670},
+  {0.216519,0.066846},
+  {0.050229,-1.132895},
+  {-0.591341,-0.135568},
+  {-1.016589,0.499351},
+  {0.619695,1.239771},
+  {-0.860305,0.327144},
+  {0.794001,-0.673587},
+  {-0.198357,0.818361},
+  {1.168914,-0.014642},
+  {0.448577,1.053050},
+  {0.292636,-0.202807},
+  {0.769249,0.583713},
+  {0.416304,-0.914883},
+  {0.462558,-0.935260},
+  {0.088227,-0.958327},
+  {0.594615,1.182851},
+  {-0.204744,0.504845},
+  {-0.244805,-0.381424},
+  {-0.737471,-1.320935},
+  {-0.528289,-0.573258},
+  {-0.105260,-0.673370},
+  {-0.635278,-0.500940},
+  {0.839401,-0.789100},
+  {-0.900784,0.142913},
+  {-0.611013,1.205516},
+  {-0.341594,0.707921},
+  {-0.549906,-0.191784},
+  {-0.351525,0.601229},
+  {0.696679,-0.084436},
+  {0.249797,-0.466641},
+  {-0.112995,0.982649},
+  {-0.103804,0.028549},
+  {1.300759,0.562159},
+  {0.188050,0.252173},
+  {0.106742,0.672221},
+  {1.403964,0.196841},
+  {0.178249,1.119562},
+  {0.478215,0.501237},
+  {-0.603436,-0.402843},
+  {0.938323,-0.147083},
+  {-1.344410,-0.465496},
+  {-0.274058,0.037370},
+  {0.302808,0.701736},
+  {0.522547,-1.063970},
+  {0.214000,-1.234162},
+  {0.115400,-0.182797},
+  {0.613710,-1.188964},
+  {-0.059478,-0.884451},
+  {-0.020643,0.621642},
+  {-0.485842,-0.203300},
+  {-0.574101,1.824857},
+  {-1.110800,0.465908},
+  {-0.009223,-0.878354},
+  {-0.970119,-0.234322},
+  {2.232488,-0.241458},
+  {-0.817618,-0.215082},
+  {0.985711,-1.312330},
+  {-0.043408,0.166327},
+  {0.685598,-1.189246},
+  {-0.863629,1.000956},
+  {0.363370,0.558049},
+  {-0.275515,-1.251793},
+  {-0.783958,-0.159861},
+  {-0.265416,1.423040},
+  {-0.303787,0.078342},
+  {-0.942708,0.058797},
+  {-0.126596,-0.043927},
+  {0.940185,-0.514732},
+  {-1.717989,-0.302336},
+  {0.392299,-0.472739},
+  {-0.605450,-0.153565},
+  {0.172246,1.273566},
+  {0.973775,-0.571675},
+  {0.412459,0.246981},
+  {0.750398,0.637567},
+  {-0.131172,-0.812034},
+  {-0.412718,-0.312419},
+  {-1.084367,0.469211},
+  {-0.750192,0.239366},
+  {-0.807903,0.025000},
+  {0.169366,1.110027},
+  {0.341377,-0.550559},
+  {1.503539,-0.645394},
+  {-0.546320,-0.503335},
+  {0.349192,0.240205},
+  {1.054660,-1.886768},
+  {0.052298,0.500975},
+  {-0.010100,-0.988941},
+  {0.166413,-0.383006},
+  {0.843436,0.918938},
+  {-0.595515,0.371500},
+  {-0.309942,1.492045},
+  {0.605896,-0.550874},
+  {0.379367,-0.626731},
+  {-0.236509,0.601141},
+  {-0.378510,-0.419328},
+  {0.478068,0.010601},
+  {-0.675805,-0.583364},
+  {-0.210744,0.418466},
+  {-0.189950,0.501288},
+  {-0.463660,0.303614},
+  {-0.537675,-0.958237},
+  {-1.015898,-0.270030},
+  {0.198231,0.122265},
+  {1.116642,-0.840185},
+  {-1.101533,1.812925},
+  {-0.561163,-0.261127},
+  {1.012467,0.890354},
+  {-0.529417,0.082287},
+  {0.009180,0.806196},
+  {0.789673,0.029863},
+  {1.003828,0.373652},
+  {0.814418,0.309315},
+  {-0.606146,-0.168860},
+  {0.056299,0.365320},
+  {0.093105,-0.068656},
+  {0.755631,-0.057552},
+  {0.081025,-0.900634},
+  {-0.016102,0.247733},
+  {0.884746,0.342390},
+  {-0.875936,0.681588},
+  {0.098843,-0.487980},
+  {-0.376775,-0.427447},
+  {0.381212,0.542140},
+  {0.530379,-0.369676},
+  {0.709660,0.380700},
+  {-1.112918,0.335488},
+  {-0.171830,0.036069},
+  {-1.019468,0.441974},
+  {0.552776,1.116890},
+  {-0.256032,1.029227},
+  {0.709352,0.980046},
+  {-0.721419,-0.145083},
+  {-1.190310,-1.516095},
+  {-1.099134,-0.241831},
+  {-1.177761,0.420445},
+  {0.618117,1.070602},
+  {1.308669,-0.017416},
+  {-0.186330,-0.148709},
+  {-1.075173,1.134706},
+  {-0.474658,-0.073558},
+  {-0.417598,-0.815183},
+  {0.452627,-0.086364},
+  {-0.099908,0.206006},
+  {1.159685,-0.593182},
+  {-0.620191,0.221127},
+  {1.099579,0.166276},
+  {-0.224604,-0.878283},
+  {0.361899,0.449122},
+  {0.782647,-1.303460},
+  {1.024841,0.701208},
+  {-0.575269,0.369847},
+  {0.185542,0.396025},
+  {-0.475507,0.042582},
+  {-0.644299,1.072212},
+  {0.024074,0.094974},
+  {1.065494,1.061942},
+  {-0.103903,0.047036},
+  {-1.507948,1.355023},
+  {0.488277,-0.387922},
+  {-0.670998,0.516623},
+  {1.043637,1.027954},
+  {-0.814702,-0.705341},
+  {1.113500,-0.824085},
+  {-0.446971,0.387174},
+  {0.085304,0.134263},
+  {-0.032566,0.373506},
+  {-0.715275,0.920719},
+  {0.856968,-0.363303},
+  {-0.531281,-0.778124},
+  {-0.273956,0.840519},
+  {-1.738353,0.489447},
+  {-0.868719,0.482146},
+  {-0.324818,0.031145},
+  {0.538558,0.494144},
+  {-0.353669,0.337685},
+  {0.231094,0.720309},
+  {-0.836142,0.106659},
+  {0.595464,0.423801},
+  {0.883973,-0.601154},
+  {0.723997,0.934565},
+  {-0.355962,0.152775},
+  {-0.127005,1.104947},
+  {0.969229,-0.149105},
+  {-1.201512,0.674038},
+  {0.146767,-0.498363},
+  {-0.035950,0.557077},
+  {-0.459134,-0.914077},
+  {0.763345,0.524424},
+  {0.011704,-2.017428},
+  {-0.849172,1.506112},
+  {-0.250493,-1.045756},
+  {-0.121860,-0.690564},
+  {-0.155904,0.608851},
+  {-1.229102,-0.406017},
+  {1.226610,1.085280},
+  {-0.805206,0.629291},
+  {-0.069214,0.730650},
+  {1.064779,0.264552},
+  {-0.006544,-0.494682},
+  {0.457170,-0.951151},
+  {-0.410514,0.789954},
+  {0.565477,-0.255665},
+  {0.734690,-0.988831},
+  {-1.062641,0.225151},
+  {-0.385230,0.821491},
+  {0.371702,-0.110034},
+  {-0.057454,0.128720},
+  {-0.081977,1.037915},
+  {0.311523,1.253425},
+  {-0.502448,0.093294},
+  {0.615595,-2.344534},
+  {0.653408,-1.185627},
+  {0.867888,-0.434547},
+  {-0.240755,0.331160},
+  {-1.197783,0.687314},
+  {0.521806,0.208657},
+  {-0.554643,0.428899},
+  {0.057554,-0.366342},
+  {-0.357134,0.156007},
+  {0.334822,0.737721},
+  {1.436037,-0.287579},
+  {-0.612891,0.136375},
+  {0.789853,-0.141415},
+  {0.525511,0.179881},
+  {0.123147,0.811655},
+  {0.113730,0.769911},
+  {0.182976,-0.119810},
+  {0.628026,-0.801001},
+  {-0.469332,-0.992844},
+  {0.420309,0.553148},
+  {-1.170904,-0.099700},
+  {-0.146831,-0.313078},
+  {0.388133,0.790864},
+  {0.282657,0.691093},
+  {1.559222,0.832869},
+  {0.381183,0.380482},
+  {0.489654,-0.943613},
+  {0.054295,-0.253576},
+  {0.455407,0.344980},
+  {0.570221,-0.475851},
+  {-0.223240,0.744998},
+  {-0.530980,0.687077},
+  {-0.449808,-0.821267},
+  {-0.330739,0.448330},
+  {0.804212,-0.577691},
+  {0.158454,0.805972},
+  {-0.108758,-0.954099},
+  {-0.439021,0.197579},
+  {-0.539345,0.439251},
+  {0.651230,0.754042},
+  {-0.355923,-1.137383},
+  {-0.177306,0.749586},
+  {0.441287,-0.286658},
+  {-0.902108,0.227320},
+  {-1.284466,1.638574},
+  {-0.036202,0.181132},
+  {-1.497482,0.003437},
+  {-0.061348,-0.006829},
+  {-0.005529,-0.741155},
+  {0.215731,0.852106},
+  {1.581736,0.051235},
+  {0.515924,0.070864},
+  {-0.482895,1.204395},
+  {-0.025352,-0.128358},
+  {1.549274,-0.306254},
+  {0.574087,0.073902},
+  {-0.521191,0.521923},
+  {-0.316768,-1.246159},
+  {0.374086,-0.736770},
+  {0.657694,0.176918},
+  {-0.873769,0.767673},
+  {1.284637,0.593571},
+  {0.129845,-0.097307},
+  {-0.554935,0.847270},
+  {0.103939,0.668202},
+  {0.803857,1.265275},
+  {0.337945,-0.680761},
+  {-0.332438,0.818654},
+  {0.815651,-0.086611},
+  {0.898750,0.267473},
+  {0.332558,0.854873},
+  {0.033251,-0.369557},
+  {-0.994826,0.728912},
+  {0.320312,0.989656},
+  {-0.968790,-0.524464},
+  {0.050254,-1.200479},
+  {1.284280,0.052694},
+  {-0.551391,1.260977},
+  {-0.243554,-0.369087},
+  {0.248510,-1.259281},
+  {-0.100092,0.030010},
+  {0.639801,-0.080694},
+  {-0.453774,0.601667},
+  {0.157292,0.534592},
+  {0.350959,0.051935},
+  {-0.757799,-0.971434},
+  {0.493319,-0.446165},
+  {0.614688,-0.582649},
+  {0.074603,-0.299675},
+  {0.882269,-0.187581},
+  {0.372823,0.368325},
+  {0.114711,-0.315413},
+  {-0.451795,0.002528},
+  {0.124370,-2.011045},
+  {0.144513,-0.674410},
+  {-0.887191,0.318651},
+  {0.276441,-0.028075},
+  {-0.656448,0.802020},
+  {-0.278558,0.378958},
+  {-1.030818,-0.732686},
+  {0.993217,-0.426098},
+  {0.539963,-0.880491},
+  {0.259553,0.120942},
+  {0.980649,0.629225},
+  {0.549393,-0.007366},
+  {1.775229,-0.150526},
+  {-0.505972,0.223503},
+  {-0.705733,-0.590672},
+  {0.617949,-0.169851},
+  {-0.057909,0.846471},
+  {0.008234,-0.314480},
+  {-0.096775,1.283379},
+  {-0.962696,-0.439218},
+  {-0.259974,0.118526},
+  {0.250173,-0.150096},
+  {0.910862,-0.680728},
+  {-0.415913,-0.191966},
+  {-0.396152,-0.497643},
+  {-0.771449,-0.213775},
+  {-0.301254,-0.272266},
+  {0.926896,-0.570671},
+  {-0.591745,0.146475},
+  {1.086466,-0.131236},
+  {-0.844351,-1.562438},
+  {-0.990476,0.070498},
+  {-0.077338,-0.863886},
+  {0.136252,-0.505947},
+  {-0.382066,-1.286926},
+  {0.669333,-0.074047},
+  {1.276768,-0.175578},
+  {0.350866,0.997669},
+  {0.615194,-1.606065},
+  {-1.052562,-0.334451},
+  {0.299494,-1.071920},
+  {0.549473,0.191316},
+  {-1.676270,-0.096974},
+  {0.265582,0.159041},
+  {0.244795,1.792395},
+  {1.008245,-0.322289},
+  {-0.702334,0.432326},
+  {-1.037780,0.165330},
+  {1.538379,0.489235},
+  {0.703589,-0.819391},
+  {-0.628913,-0.514712},
+  {0.569468,0.511478},
+  {-1.707972,0.273521},
+  {0.317935,0.288596},
+  {-0.284997,-2.009373},
+  {-0.740532,0.559777},
+  {0.537857,0.332833},
+  {0.429478,-0.292228},
+  {0.285689,1.118983},
+  {-0.631836,-0.066223},
+  {0.592196,-1.045784},
+  {0.226062,0.549405},
+  {0.309204,0.291148},
+  {0.328950,-0.651208},
+  {-0.175570,0.128113},
+  {-1.071762,-0.222013},
+  {-0.246732,0.503570},
+  {0.562434,-0.087614},
+  {-1.083738,0.163863},
+  {0.138512,-0.058985},
+  {-0.738895,0.011677},
+  {1.499974,0.103210},
+  {0.355002,-0.338290},
+  {-0.256904,-0.343176},
+  {-0.015659,-0.417844},
+  {0.208660,0.606469},
+  {-0.734477,0.817951},
+  {-0.867542,0.663637},
+  {-1.304717,-0.388440},
+  {0.704185,0.760198},
+  {-1.316292,-0.295106},
+  {0.218730,0.983686},
+  {0.818713,-1.046025},
+  {-0.583046,0.551182},
+  {1.265510,-1.016420},
+  {-0.761852,0.033767},
+  {-0.745320,-0.492837},
+  {0.934553,0.066774},
+  {-0.819204,0.242431},
+  {0.611336,-0.031476},
+  {0.096080,-0.848272},
+  {-0.106150,-0.492336},
+  {-0.383184,-0.269763},
+  {0.132107,0.766301},
+  {0.212758,-0.088413},
+  {-0.422718,1.161167},
+  {0.736935,-0.974879},
+  {-0.910351,0.495623},
+  {0.997377,0.717006},
+  {1.989167,-0.180638},
+  {-0.518269,1.156765},
+  {-1.168705,0.352030},
+  {0.875218,-0.727473},
+  {0.110928,0.594784},
+  {-0.893894,0.190021},
+  {-0.063990,-0.588675},
+  {0.271381,-0.362008},
+  {-1.002002,0.472853},
+  {-0.262505,-1.738222},
+  {-0.726954,-0.594786},
+  {1.196291,1.072635},
+  {-0.121522,-0.341266},
+  {-0.041270,0.655770},
+  {0.198658,0.212242},
+  {0.259623,-0.910297},
+  {-0.906628,-0.709528},
+  {0.763820,-0.135300},
+  {1.075767,0.169487},
+  {-0.535647,-0.428838},
+  {0.184472,0.911065},
+  {-1.106756,0.326421},
+  {-0.568826,-0.976099},
+  {-1.131721,-0.119743},
+  {-1.014501,0.157798},
+  {-0.188462,-0.981151},
+  {0.998759,-0.198788},
+  {-0.831733,-0.686713},
+  {0.940988,-0.639840},
+  {0.432728,-0.625815},
+  {-0.373126,-0.262423},
+  {0.717374,0.275913},
+  {0.267194,-0.410032},
+  {-0.244544,-0.599248},
+  {-0.372515,-0.727035},
+  {1.133795,0.095964},
+  {0.188813,0.214390},
+  {-0.491510,0.110745},
+  {-0.112035,1.669554},
+  {-0.692933,0.354110},
+  {-0.777650,-0.649853},
+  {0.206946,-0.549717},
+  {0.060381,-0.218033},
+  {-0.923367,1.095193},
+  {-0.086790,0.112154},
+  {0.173823,-0.663045},
+  {0.246195,0.466305},
+  {0.046693,-0.524645},
+  {-1.283808,-0.478148},
+  {0.964145,-0.018176},
+  {0.171523,-1.351762},
+  {-0.679412,-0.388570},
+  {0.550322,-0.537612},
+  {0.731997,-1.087005},
+  {-0.454207,-0.599756},
+  {-0.187639,0.654378},
+  {-0.844323,-0.003906},
+  {-0.145352,-0.604780},
+  {1.621990,-1.918143},
+  {-0.151221,0.586071},
+  {-2.341130,-1.090539},
+  {0.085287,0.722866},
+  {-0.323067,0.087640},
+  {1.363234,-0.722450},
+  {-1.625929,-0.003371},
+  {-1.349280,0.497928},
+  {-0.763448,0.084800},
+  {0.968353,0.485273},
+  {-0.654131,0.368048},
+  {0.906649,0.966963},
+  {0.502693,-0.801039},
+  {-0.106512,-0.017897},
+  {-0.357878,0.507848},
+  {0.596556,-0.386384},
+  {-1.350622,-0.075382},
+  {-1.132769,-0.094515},
+  {0.784254,1.026684},
+  {-1.195967,-0.498431},
+  {-1.486993,1.041977},
+  {-0.861464,1.155882},
+  {0.454096,-0.743460},
+  {0.135509,0.255852},
+  {0.328982,0.287838},
+  {-0.351451,-1.454514},
+  {-1.163104,0.800600},
+  {-0.159101,-0.818017},
+  {0.570768,-0.511169},
+  {0.261905,0.321343},
+  {-0.961814,-0.663710},
+  {1.707887,-0.051143},
+  {-1.670659,-0.504308},
+  {0.921242,0.016788},
+  {0.340322,-0.915290},
+  {0.166781,-0.511569},
+  {-0.158216,-0.111283},
+  {-0.283839,-0.287862},
+  {0.628406,0.668089},
+  {-0.332001,-1.189296},
+  {0.017396,0.278010},
+  {-0.009861,0.703837},
+  {0.292750,0.126056},
+  {-1.187099,-1.326938},
+  {-0.183012,-0.223564},
+  {-0.566881,0.719534},
+  {-0.083212,-0.380213},
+  {0.070757,-0.303190},
+  {-0.121132,0.687038},
+  {0.322541,-0.477786},
+  {0.129674,-0.807120},
+  {-0.418168,0.229298},
+  {-0.546595,0.883441},
+  {0.637606,0.900993},
+  {-0.022450,-0.668027},
+  {1.165285,-0.042859},
+  {0.394648,1.776434},
+  {-0.119592,-0.949967},
+  {-0.380534,-0.700304},
+  {-0.428653,0.876593},
+  {-0.010833,0.445818},
+  {-2.068289,0.926831},
+  {-0.056759,-1.011635},
+  {0.951500,0.730713},
+  {-0.735857,-0.974632},
+  {-0.441883,-0.113780},
+  {0.403497,-0.698566},
+  {-0.583007,-0.225655},
+  {0.845352,1.129219},
+  {1.029108,0.170238},
+  {0.677910,-0.154584},
+  {-0.866846,-0.610082},
+  {0.620796,0.585499},
+  {-0.175772,-0.410802},
+  {0.738516,0.222083},
+  {0.340440,-0.224279},
+  {0.514320,-0.118299},
+  {0.643830,0.931380},
+  {0.823034,0.678161},
+  {-0.025896,-0.374766},
+  {-0.296529,0.078295},
+  {-0.197529,1.188479},
+  {-0.561245,1.938594},
+  {-0.891056,-0.514375},
+  {-0.583395,1.256778},
+  {0.358371,0.149749},
+  {0.713595,0.243942},
+  {-0.424386,-0.267761},
+  {0.801126,-0.010966},
+  {-0.860760,0.599409},
+  {-0.132413,0.845348},
+  {-0.366124,1.094189},
+  {0.098452,1.013495},
+  {-0.594768,1.698599},
+  {-0.214296,0.107876},
+  {0.435504,-0.097577},
+  {0.484505,0.098009},
+  {0.395685,1.294490},
+  {-0.288240,0.457515},
+  {0.454454,0.065128},
+  {0.611166,1.360646},
+  {0.479140,1.245248},
+  {1.573051,0.996718},
+  {0.353760,-0.558113},
+  {-0.300835,-0.238335},
+  {-1.239956,-0.500976},
+  {0.687230,-1.586164},
+  {0.984939,0.909665},
+  {0.095002,-0.407167},
+  {-0.722139,0.986728},
+  {0.656063,0.152251},
+  {-1.206285,0.300682},
+  {-0.445228,-1.320390},
+  {0.868370,0.652878},
+  {0.480469,-0.416396},
+  {0.844269,-0.152263},
+  {-0.854423,-2.170806},
+  {0.451749,-0.005347},
+  {0.076050,-0.938747},
+  {0.414240,0.282529},
+  {-0.314277,0.634230},
+  {-0.352751,1.885884},
+  {-0.331918,0.293480},
+  {-0.611542,-0.591605},
+  {-0.032914,-0.878914},
+  {0.182686,0.511677},
+  {0.282213,-0.654782},
+  {0.180992,-0.735602},
+  {0.434231,-0.167422},
+  {-0.416232,0.478046},
+  {-0.150081,-0.445287},
+  {-0.321248,-0.468089},
+  {0.620043,0.101055},
+  {-0.728128,-0.213253},
+  {-1.353567,-0.307609},
+  {0.725953,-0.761898},
+  {0.531030,-0.335851},
+  {-0.913209,-0.639658},
+  {-0.309075,0.414710},
+  {-0.120038,1.012719},
+  {0.402300,-0.164851},
+  {-0.404268,-0.373224},
+  {-0.619788,-0.509276},
+  {-1.967288,-0.882356},
+  {0.774993,0.863349},
+  {0.170683,-0.823057},
+  {-1.277681,-0.649139},
+  {-0.150491,0.048295},
+  {0.655999,-0.224661},
+  {-0.328017,1.448516},
+  {-0.168569,-0.611396},
+  {-1.867020,-0.315154},
+  {-0.172188,0.758110},
+  {-0.688985,0.441307},
+  {-0.344957,0.468144},
+  {0.467038,-1.260435},
+  {-0.002124,0.251853},
+  {0.532495,-0.325352},
+  {-0.436167,0.212400},
+  {-0.226487,0.643460},
+  {1.280616,-1.277356},
+  {-0.015069,1.146608},
+  {0.145602,0.831614},
+  {-1.259462,0.772211},
+  {-0.348614,0.234378},
+  {0.236966,-0.423945},
+  {0.171916,0.116998},
+  {-0.380486,-0.447256},
+  {-0.069114,-0.908586},
+  {0.006162,0.030039},
+  {-0.360495,0.129786},
+  {-0.449148,0.342152},
+  {-0.637659,0.279006},
+  {-0.475733,0.146527},
+  {0.774150,-0.450019},
+  {0.384453,0.905140},
+  {0.539473,0.294686},
+  {0.963547,0.772764},
+  {-0.577154,0.243345},
+  {-0.990744,-0.184541},
+  {0.361697,-0.706210},
+  {-1.300668,-1.074359},
+  {-0.350468,-0.053975},
+  {-1.253670,1.152225},
+  {0.645014,-1.229474},
+  {-0.947043,-0.775451},
+  {0.731531,0.761002},
+  {-0.704281,-0.492722},
+  {-2.122805,1.221006},
+  {-0.886448,0.215374},
+  {-0.063047,1.035249},
+  {-0.130030,-1.597369},
+  {-1.588580,-0.164693},
+  {0.243675,0.189793},
+  {1.045297,-1.178104},
+  {0.389365,-0.556548},
+  {0.475483,-1.559555},
+  {-0.335436,0.300775},
+  {-0.972000,-0.175491},
+  {-0.133305,1.090422},
+  {1.581001,0.260800},
+  {-0.075648,1.263143},
+  {1.516818,-0.971175},
+  {0.169816,-0.200516},
+  {-1.034590,0.153998},
+  {-1.097372,0.044848},
+  {-0.579664,-0.209895},
+  {-0.053491,-0.037996},
+  {1.254129,-1.166188},
+  {-1.171324,-1.423655},
+  {0.425314,-0.416050},
+  {-0.615369,0.303270},
+  {-0.110978,-0.122135},
+  {0.204478,0.019416},
+  {-0.802350,0.427858},
+  {-1.296030,-0.172149},
+  {-0.506648,0.402006},
+  {-0.190420,0.046755},
+  {0.243431,0.240358},
+  {-0.507131,0.100200},
+  {-0.454722,-0.946433},
+  {0.725846,0.693385},
+  {-0.194304,1.034517},
+  {-0.639409,-1.491172},
+  {-0.370464,-1.316069},
+  {0.026346,1.232204},
+  {-0.045298,-1.867401},
+  {1.566024,-1.070478},
+  {-0.525522,0.424209},
+  {-0.390620,0.469335},
+  {-0.748788,-0.640077},
+  {-0.861505,1.668542},
+  {0.942889,1.164779},
+  {0.168485,-0.273375},
+  {-1.415495,1.078624},
+  {-0.973990,-0.245288},
+  {-0.406225,0.204616},
+  {-1.107687,0.132306},
+  {-0.922430,0.271948},
+  {-0.770345,0.248383},
+  {-0.262733,-0.459021},
+  {-1.543574,0.237828},
+  {0.427934,1.167747},
+  {0.838651,-0.645278},
+  {0.003714,0.143614},
+  {-0.365774,0.832688},
+  {0.120564,0.594678},
+  {0.995994,-0.565695},
+  {-0.126425,0.174578},
+  {0.947284,-0.717938},
+  {1.291500,0.893980},
+  {0.094097,0.331983},
+  {-1.520554,1.050692},
+  {0.429938,0.967334},
+  {1.062959,1.335563},
+  {-1.374009,0.443307},
+  {-0.133662,0.424658},
+  {-0.351652,0.475247},
+  {-0.774004,1.216356},
+  {-0.929932,-1.357864},
+  {-1.093596,-0.304936},
+  {0.421699,1.120944},
+  {-0.347581,-1.700207},
+  {1.759930,0.663514},
+  {-0.091702,0.155358},
+  {0.037256,0.562375},
+  {-0.880499,0.164302},
+  {-0.851232,0.905426},
+  {-0.576845,0.536598},
+  {-0.671018,0.273580},
+  {0.527832,0.179628},
+  {-0.088704,-0.382192},
+  {-0.475693,-0.489545},
+  {0.813913,-0.007911},
+  {0.866953,1.168459},
+  {0.342727,0.090489},
+  {-0.102248,0.577989},
+  {0.548149,0.018512},
+  {-0.439522,-0.100163},
+  {-0.187621,-0.065630},
+  {-0.323931,-0.323939},
+  {-0.346097,-0.211944},
+  {0.183836,1.796108},
+  {-0.314326,0.290377},
+  {0.221068,-0.314679},
+  {-0.807497,0.876966},
+  {1.656237,-1.284909},
+  {0.429140,0.610550},
+  {-0.692503,-1.275180},
+  {0.148498,-0.742160},
+  {0.471384,-0.117794},
+  {-0.337555,0.201199},
+  {0.276186,0.288946},
+  {0.242827,-0.076791},
+  {1.846708,-0.086855},
+  {-0.069953,0.656462},
+  {0.115995,0.180799},
+  {-0.284735,0.545367},
+  {0.633690,-0.122335},
+  {-0.909572,-1.230068},
+  {0.080008,0.996363},
+  {0.694586,-0.073983},
+  {-0.882830,-1.068673},
+  {0.189491,1.853682},
+  {-1.424492,0.427126},
+  {0.689818,1.018190},
+  {0.475888,-0.235734},
+  {0.272150,0.265798},
+  {0.032696,0.054859},
+  {-0.596591,-0.418400},
+  {-0.330926,1.472477},
+  {0.830467,0.554452},
+  {0.141106,-0.441457},
+  {0.871720,0.179847},
+  {0.295633,-0.724683},
+  {-0.435067,0.340489},
+  {0.350137,1.011308},
+  {-0.193628,0.339546},
+  {0.698882,0.568895},
+  {0.714853,-0.257131},
+  {-0.262342,-0.470386},
+  {-0.636850,-0.532836},
+  {-0.147885,-0.767427},
+  {0.750463,-0.213164},
+  {-0.548790,0.050549},
+  {-1.033421,-0.901535},
+  {1.500041,-1.549836},
+  {-0.432532,0.497503},
+  {1.038156,0.874007},
+  {0.463656,0.085929},
+  {-0.089563,-0.381914},
+  {-0.081148,1.037969},
+  {0.548773,0.429676},
+  {-0.491311,-0.637343},
+  {-2.438709,-0.051842},
+  {1.225795,-0.902596},
+  {-0.445842,0.452895},
+  {0.109824,0.055383},
+  {-0.232239,0.462964},
+  {0.237473,-0.816454},
+  {-0.073903,0.108264},
+  {-0.412081,0.634950},
+  {0.526763,-0.598860},
+  {0.633333,0.185228},
+  {-0.230045,-0.696161},
+  {-1.147548,-0.875395},
+  {-0.126686,-0.787857},
+  {-0.478097,-0.754376},
+  {-1.022308,-0.408585},
+  {-0.269342,-0.318111},
+  {-0.634583,0.035421},
+  {0.976029,0.481457},
+  {0.490922,1.815942},
+  {-0.325872,0.000525},
+  {-0.552517,0.029422},
+  {-0.493102,-0.053374},
+  {-1.503537,-0.460894},
+  {1.108601,-0.232398},
+  {-0.695587,-1.170494},
+  {-1.077017,-0.195150},
+  {0.199615,0.188295},
+  {0.984679,-0.566367},
+  {1.297710,-0.537764},
+  {-0.743610,1.332962},
+  {0.611631,-1.230295},
+  {0.535225,-0.203019},
+  {-1.456897,0.798777},
+  {-0.000363,-0.238487},
+  {0.922337,0.150983},
+  {0.215997,0.386013},
+  {0.536468,0.167675},
+  {0.223258,0.110369},
+  {0.661156,0.422147},
+  {-0.247800,-0.854418},
+  {0.653356,0.093449},
+  {0.412471,0.099614},
+  {0.008260,-0.284842},
+  {0.602377,0.832860},
+  {-0.140841,0.066235},
+  {0.373272,-0.127086},
+  {0.881863,-0.583065},
+  {-0.689000,0.206484},
+  {1.005700,-0.372850},
+  {-0.405465,-0.531119},
+  {-0.647395,-0.657215},
+  {0.062044,-1.065059},
+  {-0.727797,0.903809},
+  {-0.566777,-0.706294},
+  {-0.632129,0.467014},
+  {0.899076,0.126889},
+  {0.385478,1.186605},
+  {0.703954,-0.241354},
+  {0.283012,0.853681},
+  {-0.971216,-0.982086},
+  {0.102070,-0.510027},
+  {-0.474635,0.615183},
+  {-1.176123,0.165700},
+  {0.656442,-0.454286},
+  {-0.470031,0.269875},
+  {-0.570072,0.651427},
+  {0.160737,0.443575},
+  {-0.102227,-1.423956},
+  {0.063696,0.787943},
+  {0.435511,-1.119014},
+  {-0.192739,-0.355147},
+  {-0.353761,-0.790623},
+  {-1.113609,0.176838},
+  {0.250330,-0.046952},
+  {0.615718,0.870463},
+  {0.400504,0.431724},
+  {1.162029,-0.731667},
+  {0.568344,-1.078877},
+  {0.085425,-0.443310},
+  {0.207902,1.284480},
+  {0.334856,0.462654},
+  {-0.335173,1.595103},
+  {-0.929111,-0.555447},
+  {0.011277,0.456913},
+  {-0.040002,0.130483},
+  {0.973999,0.191361},
+  {-0.303043,0.236946},
+  {0.643394,-0.426236},
+  {0.323195,-1.152534},
+  {0.747335,-1.247994},
+  {0.294046,-0.113540},
+  {-0.253140,-0.990029},
+  {1.250059,0.248076},
+  {-0.521407,-0.594040},
+  {0.808065,0.500768},
+  {-0.017087,1.026674},
+  {0.006366,-0.327461},
+  {-0.349676,-1.622236},
+  {-0.438362,0.532035},
+  {-0.660037,-0.474255},
+  {0.162498,0.533545},
+  {1.633542,-0.132034},
+  {-0.318215,0.175327},
+  {1.192031,-0.516092},
+  {0.778273,2.231759},
+  {-0.011893,-0.581060},
+  {-1.029364,-0.695297},
+  {-0.173287,0.110115},
+  {0.635321,0.005894},
+  {-0.363303,0.267814},
+  {0.757333,0.531349},
+  {-0.454391,-0.388071},
+  {0.250888,-1.427019},
+  {0.180933,-1.456074},
+  {0.679743,-0.683070},
+  {-0.313584,-0.254765},
+  {-0.030301,0.911933},
+  {0.128000,0.628659},
+  {-0.443625,-0.158499},
+  {1.973744,-0.920044},
+  {0.893488,-0.150660},
+  {0.931910,0.910991},
+  {0.042853,-0.026324},
+  {-0.313634,-0.520955},
+  {-0.671536,-0.215733},
+  {0.556569,0.028198},
+  {1.117075,0.254181},
+  {-0.910888,0.046416},
+  {-0.442587,-0.710371},
+  {0.417335,0.155742},
+  {-0.390962,1.821362},
+  {0.041557,0.535249},
+  {0.118388,-1.118331},
+  {-1.008590,0.173649},
+  {0.933494,-0.410314},
+  {-1.828304,-0.246922},
+  {0.948599,0.110863},
+  {0.563454,-0.219323},
+  {0.190125,-1.330677},
+  {0.649893,0.077576},
+  {0.752153,0.957161},
+  {0.145088,0.727431},
+  {-0.266557,-0.271793},
+  {-0.021569,0.947269},
+  {-0.193472,0.296913},
+  {0.872543,0.792483},
+  {0.567036,-1.219657},
+  {-0.243654,0.348594},
+  {1.193936,0.547621},
+  {0.457518,0.539115},
+  {0.476268,0.389504},
+  {0.481768,-1.579726},
+  {-0.125194,0.075938},
+  {0.973247,-0.247002},
+  {-0.843604,0.794316},
+  {0.516310,0.192748},
+  {-0.156413,-0.385387},
+  {0.670795,0.673320},
+  {0.715695,0.154379},
+  {-1.280764,-0.035405},
+  {0.336530,1.477179},
+  {0.379120,1.083063},
+  {-0.395949,-0.490567},
+  {-0.541033,0.318875},
+  {1.380447,1.144061},
+  {-1.155728,-0.451759},
+  {-0.119609,0.530847},
+  {0.112070,-0.418582},
+  {-0.073277,-0.967746},
+  {-0.568655,0.359419},
+  {-0.644562,1.301028},
+  {-0.972656,-0.051257},
+  {0.565598,0.063147},
+  {0.226373,-1.303766},
+  {-0.053945,0.745209},
+  {-0.902083,-0.659843},
+  {1.127191,1.430759},
+  {-0.593266,-0.302685},
+  {-0.258176,0.542044},
+  {-0.416106,-0.838782},
+  {-0.513205,-0.035953},
+  {0.242585,-0.897682},
+  {-0.942517,1.556742},
+  {-0.845536,-0.691953},
+  {1.195428,-0.996093},
+  {2.193852,-0.065919},
+  {0.924832,-0.176276},
+  {2.032670,0.127016},
+  {-0.102169,0.484681},
+  {-0.035450,-1.188934},
+  {0.429058,0.816624},
+  {-0.470365,0.209900},
+  {1.204684,0.408525},
+  {-1.114052,0.414965},
+  {-0.544975,1.493659},
+  {1.142379,0.058358},
+  {-1.591466,0.057853},
+  {-0.396774,-0.466300},
+  {0.278815,0.305556},
+  {0.398613,-0.065548},
+  {0.671438,0.213874},
+  {-1.240631,0.575082},
+  {0.694327,-1.107893},
+  {-0.789778,-0.245106},
+  {1.082148,0.219531},
+  {0.152659,-0.295388},
+  {1.491724,1.028192},
+  {0.264360,-2.175691},
+  {0.311309,0.322370},
+  {-1.010542,-0.856291},
+  {1.053519,-0.514131},
+  {0.635882,0.553160},
+  {0.210920,-0.544505},
+  {-0.390892,0.472470},
+  {-1.002592,0.835210},
+  {-0.380769,1.290713},
+  {-1.474071,-0.592612},
+  {-1.467829,-0.275493},
+  {-0.484917,-0.266843},
+  {1.358912,-0.290679},
+  {-0.760563,0.421103},
+  {0.606959,0.863622},
+  {-0.587442,0.924857},
+  {-0.967521,-0.513563},
+  {-0.083623,0.137413},
+  {-0.366754,0.279873},
+  {-0.664209,-0.109312},
+  {-0.807642,-1.778743},
+  {0.805218,0.540964},
+  {0.176385,-0.486583},
+  {0.173106,-0.536233},
+  {0.000016,0.458630},
+  {-0.370551,-0.189795},
+  {0.285176,0.463441},
+  {0.240888,-0.349790},
+  {0.108800,-1.538375},
+  {0.043605,-2.269263},
+  {-0.272421,-0.006057},
+  {0.246002,0.570891},
+  {0.096239,1.069368},
+  {0.120818,-0.952900},
+  {-0.717973,0.329944},
+  {0.667827,0.340873},
+  {1.111960,-0.209056},
+  {-0.189543,-0.273671},
+  {0.227323,1.114953},
+  {-0.126011,0.855705},
+  {-0.076941,-0.519865},
+  {0.663803,0.416814},
+  {-1.438996,0.380905},
+  {0.894368,-1.006748},
+  {0.577437,-0.173548},
+  {1.291229,1.496509},
+  {-0.272941,-0.641907},
+  {-0.724711,0.930725},
+  {0.076404,-0.563913},
+  {-1.000032,0.407691},
+  {-0.566778,0.243748},
+  {0.053640,-1.146169},
+  {0.056950,-0.137659},
+  {0.346461,0.676644},
+  {1.134174,0.689609},
+  {0.667048,0.155867},
+  {-0.320707,-0.534195},
+  {0.003425,0.485725},
+  {-0.047785,-0.403591},
+  {-0.508202,-0.573405},
+  {0.249207,0.572682},
+  {-0.257244,0.012521},
+  {0.677142,-0.089546},
+  {0.020521,1.116257},
+  {0.752646,1.008726},
+  {-0.505273,-0.214467},
+  {-0.574463,0.394588},
+  {-0.062090,0.170994},
+  {-1.058119,0.845956},
+  {0.671211,0.127179},
+  {0.669598,0.396192},
+  {-1.024867,-0.406429},
+  {-0.919537,-1.145803},
+  {0.835666,-1.895036},
+  {-1.151913,0.473192},
+  {0.555942,0.438244},
+  {-0.109398,-0.855773},
+  {-0.287955,-0.851273},
+  {-0.240201,0.972916},
+  {0.263522,1.213921},
+  {0.260295,0.650558},
+  {0.211509,0.528461},
+  {0.224630,0.145409},
+  {0.998198,-0.616575},
+  {-0.241487,-0.203747},
+  {0.176697,0.282204},
+  {-1.171878,-0.213805},
+  {-0.379528,0.635300},
+  {-1.216967,0.179625},
+  {-0.880248,-0.542043},
+  {-0.062630,1.538727},
+  {-0.418366,0.221704},
+  {-0.204577,-0.588521},
+  {0.468903,0.240225},
+  {0.962490,0.035097},
+  {-1.212926,-0.343519},
+  {1.920868,0.684370},
+  {1.041078,0.532627},
+  {0.283895,-0.418711},
+  {-1.397285,0.823509},
+  {0.297481,-0.725686},
+  {-0.495904,0.086877},
+  {-0.863560,-0.351497},
+  {0.531538,1.820775},
+  {-1.045262,0.780107},
+  {0.974250,-0.849368},
+  {0.380715,-1.227674},
+  {0.781374,-0.931283},
+  {-0.112700,0.323563},
+  {0.188277,0.095565},
+  {-0.780066,-0.535792},
+  {-0.559995,0.628452},
+  {-0.217922,-0.893528},
+  {0.759105,-0.418794},
+  {0.649615,0.790668},
+  {0.067538,-0.565015},
+  {-0.002673,0.883082},
+  {0.194140,0.176718},
+  {-0.940190,1.442042},
+  {0.619299,0.056097},
+  {0.468398,0.509592},
+  {-0.711271,0.043840},
+  {-0.998983,-0.728807},
+  {0.325337,0.466913},
+  {0.077430,0.279358},
+  {-0.673751,0.162800},
+  {-0.231974,0.235378},
+  {0.910689,-0.797473},
+  {-1.622605,-0.841817},
+  {0.432091,-1.018767},
+  {-0.539186,-0.324225},
+  {-0.242040,0.155646},
+  {1.252015,0.593035},
+  {0.188151,-0.739432},
+  {0.534619,0.511769},
+  {0.345659,0.476703},
+  {-0.474379,0.580542},
+  {-0.760683,-0.293209},
+  {-0.917086,0.574522},
+  {-0.423170,-0.878440},
+  {0.040276,0.362034},
+  {0.008902,-0.223798},
+  {0.002946,-0.186733},
+  {-0.727363,0.046058},
+  {0.494353,-0.235286},
+  {0.720284,0.433101},
+  {1.295036,0.230127},
+  {-0.419453,0.141825},
+  {-0.485166,0.030742},
+  {-0.579491,-0.809389},
+  {0.297978,1.166165},
+  {0.107656,0.089250},
+  {-0.419769,0.749546},
+  {0.101102,0.988807},
+  {-0.007293,-0.739409},
+  {-0.673602,0.874056},
+  {0.488981,-0.019753},
+  {-0.544172,1.634457},
+  {-1.110920,-0.678521},
+  {-1.387117,-0.567418},
+  {-1.186982,-0.625841},
+  {-0.131011,-0.534074},
+  {0.455097,0.393563},
+  {0.737161,-1.031238},
+  {0.817935,-0.327775},
+  {-0.385625,-0.012476},
+  {-0.802613,0.038609},
+  {-0.194642,-0.009339},
+  {0.377562,-1.207033},
+  {-0.660416,-0.454296},
+  {-0.706623,0.381842},
+  {-0.116607,0.548143},
+  {0.288850,-1.075507},
+  {0.276881,0.463193},
+  {0.829630,0.529055},
+  {0.299449,-0.575188},
+  {-0.231345,0.351412},
+  {1.003362,-1.460585},
+  {0.451130,-1.124930},
+  {0.322338,0.099733},
+  {-0.254205,-0.042471},
+  {0.211873,-0.537793},
+  {0.550656,-1.202402},
+  {0.302071,-0.529459},
+  {0.484872,-0.424805},
+  {-0.676112,1.242723},
+  {0.196295,0.986675},
+  {-0.006182,0.043626},
+  {1.004458,-1.101313},
+  {-0.508022,-0.307337},
+  {-0.069604,-0.270549},
+  {-0.936588,0.401472},
+  {0.395051,-0.291762},
+  {0.249364,-0.460210},
+  {0.470524,-1.377845},
+  {-0.031948,-0.316301},
+  {0.398084,0.453870},
+  {-0.084745,0.044352},
+  {-0.653237,0.563452},
+  {-0.052125,0.128803},
+  {-0.427875,0.636993},
+  {1.058874,0.376406},
+  {-0.282247,-1.483023},
+  {-0.125176,-0.032568},
+  {1.794146,-1.232187},
+  {-0.187983,-0.345985},
+  {0.123095,-0.261032},
+  {-0.415461,-1.090493},
+  {-0.500346,-0.804478},
+  {-0.513241,1.041086},
+  {-1.784888,0.501072},
+  {-0.235262,-0.395913},
+  {-0.874197,0.136517},
+  {0.802032,0.092163},
+  {0.172660,-1.036619},
+  {-0.740904,0.535180},
+  {0.617676,0.005886},
+  {-0.693840,-0.522827},
+  {-0.803188,-0.240073},
+  {-0.728556,-0.632434},
+  {-0.149941,0.193266},
+  {0.476898,-0.368260},
+  {-0.031225,-0.120384},
+  {-0.073972,0.464808},
+  {0.160690,0.537959},
+  {-0.450836,0.102038},
+  {-0.216212,1.235659},
+  {0.164200,0.192175},
+  {-0.265676,0.384622},
+  {0.213530,-0.157196},
+  {-0.833550,-0.048440},
+  {0.003577,0.903917},
+  {-0.060957,0.001082},
+  {-0.422697,-0.291104},
+  {-0.436963,0.617239},
+  {-0.560838,-0.652536},
+  {-0.389877,-1.335308},
+  {0.221871,-0.727966},
+  {0.366452,-0.156117},
+  {0.048762,0.817719},
+  {1.364032,-1.028170},
+  {-0.199738,-0.597666},
+  {-0.048452,0.186324},
+  {0.317672,1.640253},
+  {1.030187,1.004812},
+  {0.186677,0.155142},
+  {-0.128456,-0.513439},
+  {1.114846,-0.127393},
+  {-0.365605,-0.311630},
+  {-0.081923,0.648966},
+  {0.060946,1.009555},
+  {0.545678,0.076880},
+  {-0.990208,-1.026702},
+  {-0.840658,0.552260},
+  {-1.316496,0.415412},
+  {0.233111,-0.268865},
+  {-1.081822,0.126111},
+  {-0.893361,0.121170},
+  {0.637557,-0.768942},
+  {-0.981313,-0.937625},
+  {0.366842,-0.491230},
+  {-0.296605,-0.122075},
+  {-0.694637,-0.691831},
+  {-0.346922,1.010405},
+  {0.265549,-0.072721},
+  {0.553767,0.365723},
+  {-0.886712,0.109635},
+  {-0.548347,-0.303784},
+  {-0.124639,0.349517},
+  {-0.989650,0.330316},
+  {0.762642,0.298664},
+  {-0.179434,1.111018},
+  {0.040421,0.525211},
+  {-0.040726,-0.517622},
+  {-0.436258,-0.419372},
+  {-0.614376,-1.002123},
+  {0.714119,-0.753994},
+  {-0.514783,-0.369145},
+  {0.074207,-1.001150},
+  {0.344306,-0.309130},
+  {0.149015,0.765323},
+  {-0.296244,0.136197},
+  {0.962661,1.268011},
+  {0.023783,-1.186554},
+  {0.123632,0.492674},
+  {0.856406,0.442632},
+  {0.232322,-0.486339},
+  {0.191689,0.265950},
+  {0.179934,-0.748107},
+  {-1.701289,-0.051015},
+  {-0.259518,1.342912},
+  {-1.092688,0.126797},
+  {0.646145,1.070342},
+  {-0.102832,0.212320},
+  {0.371741,1.059808},
+  {0.329041,0.597689},
+  {1.172615,0.542162},
+  {-0.190803,0.345770},
+  {0.694535,-0.143332},
+  {1.565777,-0.517105},
+  {-1.157503,-0.395621},
+  {0.977210,0.015425},
+  {-0.257104,0.098762},
+  {-1.333003,0.368782},
+  {0.061883,0.379086},
+  {0.445949,-0.575541},
+  {0.417953,0.289093},
+  {0.289993,-0.020798},
+  {-1.440368,0.472769},
+  {1.148131,1.054014},
+  {-0.556081,0.000779},
+  {0.327782,0.192655},
+  {-0.039300,-0.677965},
+  {0.740380,-0.491050},
+  {-0.072859,-1.870999},
+  {-0.464327,-0.233392},
+  {0.037757,-0.291647},
+  {-0.124848,-0.199890},
+  {0.429504,1.065232},
+  {-0.841457,0.469673},
+  {-0.636712,0.263585},
+  {0.958690,-0.322036},
+  {-0.209246,0.211522},
+  {0.228839,-1.553564},
+  {0.544155,0.188110},
+  {0.738006,0.016440},
+  {0.586748,0.001516},
+  {0.360613,0.505248},
+  {-0.257556,-0.316652},
+  {-0.203123,0.066133},
+  {0.707979,-0.756344},
+  {-0.583274,-0.479593},
+  {-0.810371,-0.061860},
+  {0.273421,-0.865636},
+  {-0.823282,0.610077},
+  {0.094723,0.544387},
+  {-0.008236,0.290898},
+  {0.646489,0.296314},
+  {-0.205770,-0.509249},
+  {-0.052562,0.594927},
+  {0.444777,0.441814},
+  {0.100155,-0.501991},
+  {-0.232563,-0.082230},
+  {-0.081497,-0.962312},
+  {0.041276,0.987394},
+  {1.069935,-1.329858},
+  {-0.076026,-0.887274},
+  {0.086993,0.014743},
+  {-0.179174,0.280143},
+  {0.565349,-0.420367},
+  {0.521928,-1.241770},
+  {0.916126,1.435687},
+  {0.637655,-0.516147},
+  {-1.043603,0.819465},
+  {-0.883656,-0.205474},
+  {-0.644741,0.180014},
+  {0.622506,-0.334192},
+  {-0.241486,-0.600670},
+  {-1.499588,0.650466},
+  {-0.201187,-0.192333},
+  {0.480999,-0.530799},
+  {-1.738026,-0.145849},
+  {0.998277,0.673428},
+  {-0.144344,-0.233893},
+  {-0.059109,-0.308362},
+  {0.269830,1.562885},
+  {-0.013641,-0.506529},
+  {-0.278890,0.111794},
+  {0.066036,0.843526},
+  {-0.042208,1.107633},
+  {-0.014597,0.485376},
+  {0.183473,-1.283402},
+  {-0.039860,-0.602430},
+  {0.759903,0.034461},
+  {-0.520732,0.826968},
+  {0.093097,0.518453},
+  {-0.047591,0.588031},
+  {-0.808060,-0.728578},
+  {-1.845584,0.914242},
+  {0.266263,0.716752},
+  {-1.253357,-1.118286},
+  {0.705217,0.050021},
+  {0.743902,-0.448512},
+  {0.216893,0.073955},
+  {0.385487,0.994616},
+  {0.178511,0.204042},
+  {-0.523429,-0.483543},
+  {0.274570,0.042189},
+  {-0.187481,0.727858},
+  {-1.040426,-0.720766},
+  {-0.359936,1.093006},
+  {-0.665247,-0.950281},
+  {-1.001936,0.289410},
+  {1.381124,0.376211},
+  {0.995092,-0.174666},
+  {1.360198,-2.217745},
+  {-0.554387,-1.676721},
+  {-0.233175,-0.582371},
+  {-0.388060,-0.034116},
+  {1.342218,0.537788},
+  {0.249304,1.296082},
+  {-1.475857,-1.157512},
+  {-0.197745,-0.568437},
+  {0.824403,0.507678},
+  {0.819198,-0.920770},
+  {0.385495,-0.200380},
+  {-0.503672,0.548119},
+  {-1.111840,-1.633640},
+  {-1.163537,-0.037715},
+  {0.292674,-0.654745},
+  {-0.962338,-0.407980},
+  {-0.123743,0.028162},
+  {-0.253323,0.014822},
+  {0.479730,-0.823812},
+  {-1.207221,0.300687},
+  {0.996807,-1.482183},
+  {-0.338063,0.564877},
+  {0.920558,-0.084443},
+  {1.293720,0.577197},
+  {-0.967375,0.013719},
+  {-0.481738,0.429749},
+  {-0.943010,-0.544458},
+  {0.060644,0.029556},
+  {1.271225,0.072382},
+  {1.345314,-0.606930},
+  {-0.113264,0.048617},
+  {-0.471231,0.591903},
+  {0.450025,-0.255396},
+  {1.082117,-0.457752},
+  {-0.437023,0.619777},
+  {0.199128,0.415873},
+  {-0.738844,-1.578600},
+  {-0.460504,-0.497232},
+  {0.365693,0.851386},
+  {1.155773,0.416016},
+  {1.362762,-0.089273},
+  {0.045085,-0.410653},
+  {-0.352391,1.194551},
+  {0.269619,-0.845695},
+  {-0.937635,-0.041440},
+  {-0.291614,0.210214},
+  {-0.590964,0.334029},
+  {0.041430,-0.582846},
+  {-0.049634,-0.333992},
+  {0.587620,0.926445},
+  {0.019148,-0.708333},
+  {-0.897879,1.311240},
+  {-0.362442,1.068789},
+  {0.417690,0.948938},
+  {1.014004,-0.315357},
+  {-0.426504,0.852104},
+  {0.879939,1.426273},
+  {1.147532,-0.513129},
+  {-0.010543,-0.559115},
+  {-0.935264,-0.274738},
+  {0.047804,-0.517361},
+  {-1.287619,-0.019239},
+  {-0.829546,-0.280842},
+  {-0.731296,0.823460},
+  {-0.891822,0.427640},
+  {0.589846,0.227553},
+  {0.224689,0.571736},
+  {-0.991209,-1.790480},
+  {-0.009287,0.367028},
+  {-0.551808,-1.155483},
+  {-0.158887,-0.504851},
+  {-1.006753,1.691039},
+  {0.139125,1.656709},
+  {0.311493,-1.358651},
+  {-0.000659,-0.397979},
+  {0.168687,-0.256026},
+  {-1.042776,0.605335},
+  {-0.319026,1.219072},
+  {1.837911,0.271572},
+  {0.239919,0.877257},
+  {-0.037115,-0.596589},
+  {-0.745878,1.264467},
+  {0.010089,0.390431},
+  {-0.581987,-0.175623},
+  {-0.649250,0.127701},
+  {-0.927358,-0.445949},
+  {0.969864,-0.227424},
+  {0.341977,0.252902},
+  {0.135549,-0.495303},
+  {-0.434902,-0.375805},
+  {0.365613,0.090189},
+  {-0.599520,-0.108817},
+  {-0.486901,0.808199},
+  {0.802453,0.113674},
+  {-0.985303,0.348679},
+  {0.272472,-0.315188},
+  {0.653225,-0.102477},
+  {-1.075974,0.333581},
+  {0.197104,-0.038665},
+  {0.362767,0.959841},
+  {-0.336212,-0.991636},
+  {0.341808,-0.200085},
+  {0.350307,-1.046523},
+  {0.941919,-0.790265},
+  {-0.391904,-0.269616},
+  {-0.583731,-0.576541},
+  {-0.767887,0.168764},
+  {0.804567,-0.160216},
+  {1.321056,0.602316},
+  {-0.188219,-0.925499},
+  {-0.025028,-0.134455},
+  {0.409337,0.135734},
+  {0.934364,0.899781},
+  {0.443336,-0.454010},
+  {0.267522,1.651923},
+  {-0.021616,-0.240785},
+  {-0.389671,0.913717},
+  {1.028459,-0.957200},
+  {0.917363,0.369138},
+  {0.528539,0.496175},
+  {0.086018,0.410356},
+  {-0.761042,0.621316},
+  {0.674682,-0.212507},
+  {-0.658861,-0.532391},
+  {0.285689,-0.034456},
+  {0.547369,0.588551},
+  {-0.665673,-0.523220},
+  {-0.044039,0.016680},
+  {0.770642,1.488234},
+  {1.180668,-0.468981},
+  {-0.046869,-0.474722},
+  {-0.575480,1.143743},
+  {0.493793,-0.521459},
+  {-0.181592,0.068195},
+  {-0.893649,-0.629530},
+  {0.739301,-0.072214},
+  {0.372672,0.080329},
+  {0.913631,-1.018692},
+  {-0.517839,0.093767},
+  {0.621679,0.306497},
+  {0.074540,0.055095},
+  {0.723377,-0.915493},
+  {0.022777,-0.462031},
+  {0.093992,0.364776},
+  {-0.161938,-1.408632},
+  {-0.700315,-0.305135},
+  {0.067748,-0.187459},
+  {0.483409,-0.713985},
+  {0.928152,-0.381167},
+  {-0.857084,1.583029},
+  {-1.318696,0.516152},
+  {0.062040,0.590523},
+  {0.832742,-0.065744},
+  {0.190616,0.184008},
+  {0.718808,0.579103},
+  {0.091621,-0.167070},
+  {-0.496135,1.776628},
+  {-0.776281,-0.967919},
+  {-0.340838,-1.252051},
+  {0.509865,0.890890},
+  {0.011224,1.492168},
+  {-0.370739,0.707013},
+  {-0.707116,1.492027},
+  {-1.470031,-1.128868},
+  {-1.199963,0.304341},
+  {0.178199,-1.144514},
+  {0.827291,0.129026},
+  {-1.809214,0.424594},
+  {-0.056250,-1.086321},
+  {-0.806620,0.594545},
+  {0.614157,0.789597},
+  {-0.230539,-0.152551},
+  {0.305055,0.383843},
+  {-0.572786,-0.383604},
+  {0.699148,0.289711},
+  {1.471148,1.731421},
+  {0.221494,-0.119078},
+  {0.134051,0.860560},
+  {-0.199285,1.539492},
+  {0.327753,-0.263169},
+  {0.070554,-0.500086},
+  {0.607835,1.349017},
+  {0.298997,0.241897},
+  {0.128546,0.517720},
+  {-0.933511,-0.304699},
+  {-0.222248,-0.319890},
+  {0.219134,1.083726},
+  {0.732430,-0.081472},
+  {-0.274968,0.590110},
+  {-0.774399,1.437671},
+  {1.398432,-0.474460},
+  {0.731892,0.666366},
+  {0.286832,-0.212891},
+  {0.820630,1.301418},
+  {0.413562,1.052060},
+  {-0.226316,-0.541971},
+  {-1.042872,-0.345541},
+  {-0.858989,-1.096863},
+  {1.880585,-0.233188},
+  {-0.807930,-1.151544},
+  {0.394861,-0.330062},
+  {-0.085289,-1.629366},
+  {0.640853,-0.152655},
+  {0.183194,-0.254060},
+  {-1.443384,1.394728},
+  {-0.011702,0.646342},
+  {0.736446,-1.332796},
+  {0.621335,-0.574106},
+  {-0.338450,-1.567302},
+  {-0.332211,0.110908},
+  {-1.017165,-1.522539},
+  {-0.140315,2.030807},
+  {0.044867,-1.101171},
+  {0.189708,0.085158},
+  {-1.830584,0.387522},
+  {-1.017359,0.484883},
+  {0.275108,0.181996},
+  {-0.327957,1.214680},
+  {0.336969,-0.766226},
+  {-0.562675,0.180997},
+  {1.310744,0.585186},
+  {0.080051,2.094519},
+  {0.211201,0.942647},
+  {0.568763,-0.272394},
+  {0.152587,-0.595240},
+  {1.275315,0.622396},
+  {0.813283,-0.132745},
+  {0.407696,1.569844},
+  {0.039364,0.287794},
+  {0.244642,-0.641218},
+  {0.886477,1.006243},
+  {0.948847,0.187471},
+  {-0.626010,0.160922},
+  {0.962612,0.504401},
+  {0.875536,-0.815369},
+  {0.175947,-1.244808},
+  {-0.070131,0.461325},
+  {0.202225,-1.039772},
+  {-0.325603,0.232979},
+  {-0.747171,-1.024781},
+  {-0.079451,0.376832},
+  {0.336329,1.142868},
+  {0.213160,0.231289},
+  {-0.691300,-0.017983},
+  {0.057278,-0.387798},
+  {0.073555,1.006174},
+  {0.490772,0.337166},
+  {0.685390,-0.318414},
+  {0.637094,0.808315},
+  {0.523969,2.121595},
+  {0.721264,-0.482325},
+  {-0.145401,-0.605792},
+  {-0.233810,-0.053732},
+  {1.269554,0.710916},
+  {1.057321,-1.046691},
+  {0.464363,-0.270764},
+  {0.840490,1.150537},
+  {-0.620898,-1.419891},
+  {-0.857446,-0.039502},
+  {-0.770707,-1.876256},
+  {0.950801,1.087080},
+  {1.432451,-0.030974},
+  {0.490360,-0.567231},
+  {-0.268067,-1.435917},
+  {-1.183652,0.279454},
+  {0.884853,-0.220426},
+  {-0.528640,-0.111193},
+  {-1.097008,0.128877},
+  {-1.181036,-0.940732},
+  {0.775628,0.000761},
+  {1.472129,0.938313},
+  {-0.651045,-0.150514},
+  {0.253945,0.727849},
+  {-0.625689,-0.863395},
+  {-0.857663,-0.204035},
+  {0.229410,0.785159},
+  {0.415385,-0.811285},
+  {0.135788,0.541017},
+  {0.540449,0.302355},
+  {-0.375243,-0.075659},
+  {-0.126218,-1.254478},
+  {-0.842535,-0.102853},
+  {-0.944249,0.424586},
+  {1.011823,-0.620988},
+  {1.012036,0.169655},
+  {0.512690,0.312651},
+  {-0.628804,0.539718},
+  {0.567513,0.109352},
+  {0.934259,-0.533472},
+  {-0.633715,-1.496096},
+  {-0.416398,-0.918620},
+  {0.421463,-1.209687},
+  {0.314672,-0.470088},
+  {-0.834237,-0.445546},
+  {-0.485232,-0.247145},
+  {-0.136325,-0.141431},
+  {-0.006273,1.250196},
+  {0.266229,-0.648711},
+  {-0.945678,-0.027143},
+  {0.782856,-0.470187},
+  {0.305630,0.658933},
+  {-1.111016,0.700723},
+  {-0.365320,0.254061},
+  {-0.175023,0.308741},
+  {0.744562,0.103704},
+  {0.557819,0.264705},
+  {-1.130397,-0.307616},
+  {0.190300,0.843572},
+  {0.871835,-0.864320},
+  {1.025579,0.117274},
+  {-0.714639,-1.413594},
+  {-0.394212,0.630346},
+  {-0.402052,0.309273},
+  {1.048158,0.495032},
+  {-1.458614,0.390078},
+  {-1.348655,-0.157187},
+  {0.627460,0.517239},
+  {0.616428,0.013392},
+  {0.066659,0.172077},
+  {0.177589,1.104288},
+  {-0.202342,0.342469},
+  {-0.896507,-0.597822},
+  {-2.067867,-1.208733},
+  {-0.022428,0.203426},
+  {0.303756,0.349684},
+  {0.627717,0.858736},
+  {-0.745760,-0.181848},
+  {-0.496215,1.429290},
+  {-0.011943,-1.057738},
+  {0.536641,1.349276},
+  {-0.528001,-0.098934},
+  {-1.063109,0.581999},
+  {-1.256061,0.808575},
+  {-0.601466,0.399072},
+  {0.563718,-0.264581},
+  {-0.237276,-0.677165},
+  {-0.348054,1.673165},
+  {0.064061,-0.618610},
+  {-0.161228,0.795589},
+  {-0.924021,-1.050412},
+  {0.197726,0.353867},
+  {-0.151410,-1.246225},
+  {-0.714340,0.549384},
+  {1.556261,-1.468342},
+  {0.468479,-0.903354},
+  {-0.483340,1.187727},
+  {0.077127,-0.093447},
+  {0.064972,0.945303},
+  {-0.092409,0.145919},
+  {1.315321,0.437219},
+  {0.090724,0.761955},
+  {0.781174,0.978083},
+  {-0.308962,-0.268376},
+  {0.696462,-0.805879},
+  {0.966927,1.486179},
+  {-1.249165,-1.299388},
+  {1.239842,0.109267},
+  {-0.340003,0.701168},
+  {-1.633695,0.438179},
+  {0.257196,0.023754},
+  {0.005382,-0.652799},
+  {0.698827,-1.245465},
+  {1.057062,-0.264028},
+  {-0.335223,-0.503241},
+  {0.175219,-1.082885},
+  {-0.274187,-0.933890},
+  {-0.240526,-2.221268},
+  {-0.007571,0.808866},
+  {0.162060,0.252737},
+  {0.481541,0.726904},
+  {-0.555236,0.591634},
+  {-0.136039,-0.497365},
+  {-0.914324,-0.971380},
+  {-0.330625,0.159913},
+  {0.231296,-1.098666},
+  {0.393929,-1.169035},
+  {-0.664998,0.348284},
+  {0.579266,-0.439099},
+  {0.782286,-0.483201},
+  {-0.036705,0.243544},
+  {-0.470027,-0.758332},
+  {-1.089025,0.282651},
+  {-0.536396,-0.779503},
+  {0.584009,0.036838},
+  {0.777240,-0.758248},
+  {-0.410388,0.482134},
+  {-0.240905,-0.322910},
+  {1.052859,0.448321},
+  {0.744819,0.688556},
+  {-0.323975,-0.312544},
+  {1.688688,0.125085},
+  {0.767757,0.027399},
+  {-0.165767,0.087836},
+  {-0.295850,-1.950460},
+  {0.035816,0.245902},
+  {-0.180130,-1.262665},
+  {0.117034,0.019373},
+  {0.309583,-0.084634},
+  {0.160314,0.617106},
+  {-0.223874,-0.405101},
+  {0.391423,-0.984880},
+  {-0.583522,-0.208371},
+  {0.314564,1.000927},
+  {1.528070,-0.488905},
+  {0.682797,-0.214904},
+  {-0.961746,0.561929},
+  {-0.044529,-0.357871},
+  {-0.881485,-0.203306},
+  {1.081847,-0.376245},
+  {0.828899,1.159757},
+  {-0.396282,0.868155},
+  {0.013008,-0.796971},
+  {1.839981,0.128022},
+  {0.861759,-0.389782},
+  {0.939432,0.185296},
+  {0.402922,-1.121553},
+  {-0.878636,-1.122818},
+  {1.213472,0.848105},
+  {0.264317,-0.326819},
+  {0.669519,-0.620270},
+  {0.703125,-0.958242},
+  {-0.367984,-0.413227},
+  {-0.561993,0.902582},
+  {0.709199,0.095548},
+  {-0.624048,-0.624104},
+  {0.367587,0.743255},
+  {0.349618,-0.082040},
+  {0.353670,-0.602772},
+  {-0.121469,0.186655},
+  {0.966288,-0.989082},
+  {0.615847,1.087146},
+  {0.049469,-0.498055},
+  {0.161550,0.553359},
+  {-0.061135,-0.214648},
+  {0.046340,1.148951},
+  {-0.104857,0.135405},
+  {0.575610,1.613613},
+  {0.294077,0.716711},
+  {0.590764,-0.458646},
+  {0.533655,-0.474675},
+  {-0.200094,0.220235},
+  {0.538978,-0.112814},
+  {-0.596995,0.556408},
+  {0.538951,-2.449696},
+  {0.092171,-0.864222},
+  {1.336939,0.991303},
+  {0.333067,0.173662},
+  {-0.153896,0.523270},
+  {-0.582494,0.868651},
+  {0.018634,0.130106},
+  {-0.392325,-0.082136},
+  {0.011480,0.421792},
+  {-0.427424,-0.661210},
+  {0.942397,0.587290},
+  {-0.291423,0.402361},
+  {-0.624678,0.855158},
+  {0.427905,-0.996070},
+  {-0.282753,-0.652971},
+  {-1.240070,1.256909},
+  {0.815396,-0.668763},
+  {0.069285,0.238819},
+  {0.077701,0.317614},
+  {1.331490,0.009543},
+  {1.194605,-0.196271},
+  {0.230566,0.449264},
+  {0.385677,1.158774},
+  {-0.340860,-0.164507},
+  {-0.842850,-0.564676},
+  {-1.758840,0.064669},
+  {-0.772174,0.091618},
+  {1.140984,-0.811770},
+  {-0.283852,-0.741705},
+  {0.846224,0.293317},
+  {-0.901372,1.090597},
+  {1.033877,-1.064114},
+  {-1.186147,0.598334},
+  {-0.967792,1.113083},
+  {0.974157,0.994512},
+  {0.313614,-0.240645},
+  {-0.063238,-0.036188},
+  {-0.886378,-0.081582},
+  {0.155813,-1.314707},
+  {0.005821,0.803969},
+  {0.031398,1.138370},
+  {0.020663,-1.412936},
+  {0.051696,0.849846},
+  {-0.754989,-0.899231},
+  {0.394988,0.540404},
+  {-0.440672,-0.180217},
+  {1.164193,-0.163753},
+  {0.201996,-0.935543},
+  {-0.757096,0.768721},
+  {-0.851269,0.282609},
+  {-0.032236,-0.457477},
+  {0.242147,-0.379077},
+  {-0.369603,-0.280814},
+  {0.521168,-0.299217},
+  {-0.383667,0.998399},
+  {-0.273344,-0.133382},
+  {-0.197726,0.033374},
+  {0.399979,0.840030},
+  {-0.349378,-0.387395},
+  {1.124925,-0.570043},
+  {0.418603,0.905447},
+  {0.470094,-0.957354},
+  {0.799573,0.109228},
+  {0.261391,-0.587899},
+  {0.115105,0.568951},
+  {-0.511340,1.109997},
+  {0.183765,1.450929},
+  {0.528498,-0.666337},
+  {0.342372,-0.375714},
+  {-1.148716,0.543099},
+  {-0.747361,-0.454390},
+  {-0.510703,-0.904779},
+  {0.494719,0.007910},
+  {-0.178977,-0.714179},
+  {-0.178152,-0.715379},
+  {-0.282468,0.236082},
+  {-1.500059,-0.596371},
+  {0.070261,0.659727},
+  {-0.930558,0.499131},
+  {0.889396,0.872062},
+  {1.504564,-0.762497},
+  {-0.316940,-0.491494},
+  {-0.366178,-0.120892},
+  {-1.136140,-0.665677},
+  {0.792450,0.494536},
+  {-0.058379,-0.131564},
+  {0.318553,-0.170468},
+  {-0.442968,-0.453066},
+  {-0.086122,0.487054},
+  {-0.002152,0.609175},
+  {-0.198518,-0.485488},
+  {0.401525,1.306812},
+  {-0.871198,-0.567593},
+  {-1.415314,-0.301627},
+  {1.094900,0.063995},
+  {-0.495128,0.213385},
+  {0.001405,-0.320934},
+  {-0.324564,-0.183506},
+  {0.122253,-0.766486},
+  {0.984696,0.267844},
+  {0.390885,-0.724844},
+  {-0.295282,0.211369},
+  {-0.452752,0.149217},
+  {-1.129899,1.635510},
+  {0.401396,0.319009},
+  {-0.558456,0.761582},
+  {0.516621,-0.299728},
+  {1.170774,0.462117},
+  {0.617850,0.230530},
+  {-0.616788,-0.704169},
+  {0.921282,-0.768237},
+  {-0.341409,0.311033},
+  {1.237788,-0.817666},
+  {0.485433,-1.114476},
+  {-0.342288,-0.175267},
+  {0.536632,1.147849},
+  {0.173754,0.023311},
+  {0.019679,-0.413100},
+  {0.597239,-0.651007},
+  {0.649898,-0.023947},
+  {0.784239,0.588037},
+  {0.830428,-0.495560},
+  {-1.123475,1.667920},
+  {-0.757155,0.047444},
+  {-1.536651,0.080233},
+  {-0.600005,0.260676},
+  {0.220305,-1.151817},
+  {-0.957182,0.202521},
+  {0.051226,-0.029891},
+  {0.929447,0.384707},
+  {-0.422607,-0.106100},
+  {0.353436,0.656718},
+  {-1.698234,-0.708923},
+  {0.303429,-0.258709},
+  {-0.088662,0.015699},
+  {-0.107934,-0.261967},
+  {0.273168,1.400901},
+  {0.727049,-0.003312},
+  {0.353597,0.715919},
+  {-0.952026,-0.067464},
+  {-0.145977,-0.817247},
+  {0.424964,-0.919265},
+  {0.216841,-0.912514},
+  {0.817183,-0.911165},
+  {-0.818262,-0.517903},
+  {0.313475,-0.796077},
+  {-0.461417,0.089258},
+  {0.281792,-0.291761},
+  {0.256943,-0.778188},
+  {0.692420,-1.751276},
+  {-0.667443,-1.761493},
+  {0.064327,0.039954},
+  {0.393151,-0.403340},
+  {0.452610,-1.766216},
+  {-1.336807,-0.219532},
+  {0.984460,-0.595093},
+  {-0.702228,0.759469},
+  {-0.464956,0.036841},
+  {0.212799,0.031216},
+  {-0.802860,-0.547493},
+  {-0.158662,0.903760},
+  {0.085684,-0.487384},
+  {0.396768,-0.742668},
+  {0.947527,-0.110617},
+  {-0.879301,0.044952},
+  {1.116675,-0.038127},
+  {-0.722818,1.392444},
+  {-0.373075,0.108044},
+  {0.341487,0.570356},
+  {0.441689,-0.298432},
+  {-0.916256,0.631859},
+  {-0.115507,0.498266},
+  {0.487754,0.201490},
+  {1.238389,-0.100924},
+  {0.271103,0.682797},
+  {-0.148481,0.589360},
+  {-1.194668,-0.756352},
+  {0.264142,0.313523},
+  {0.562690,-0.166170},
+  {-0.527054,0.196752},
+  {-1.636821,-0.651796},
+  {0.182204,0.101729},
+  {-1.710289,-0.320628},
+  {0.053238,-0.006688},
+  {0.879077,-0.416623},
+  {0.459898,-0.350816},
+  {-0.856786,0.761817},
+  {0.575136,0.370224},
+  {-0.710682,-1.661932},
+  {0.336980,0.262314},
+  {-0.579270,1.290335},
+  {1.163348,0.112616},
+  {-0.596616,-0.104548},
+  {-0.584829,0.611158},
+  {-0.507069,0.090728},
+  {-1.061880,0.073344},
+  {-0.141397,0.660130},
+  {1.132322,0.001417},
+  {-0.578203,1.455008},
+  {0.430346,-0.353417},
+  {0.774728,-0.360911},
+  {0.089974,0.151366},
+  {-0.258221,-0.281586},
+  {0.380590,-0.050307},
+  {0.805828,1.610702},
+  {-2.417115,-0.796571},
+  {0.513097,-0.330322},
+  {-0.384140,0.768697},
+  {-0.343898,0.186101},
+  {-1.280400,-0.294454},
+  {0.497601,-1.076587},
+  {0.969059,0.648983},
+  {0.415521,-0.271362},
+  {-0.023547,-0.051680},
+  {0.697681,0.077273},
+  {1.467525,-0.087120},
+  {0.914526,0.512467},
+  {0.673227,-0.608451},
+  {0.868157,-0.438369},
+  {-0.641897,-0.582166},
+  {-0.395403,-0.726859},
+  {0.708135,0.058289},
+  {0.155302,-0.353393},
+  {-0.604680,-0.269021},
+  {0.555662,-0.222243},
+  {-0.691591,-1.012201},
+  {0.593126,-0.482201},
+  {0.938501,-0.141245},
+  {-0.285179,-0.282197},
+  {-0.332866,-0.838107},
+  {-0.299353,0.907257},
+  {-0.502252,0.130212},
+  {0.509899,0.203982},
+  {0.432764,-1.036891},
+  {0.320100,0.302258},
+  {-0.715537,0.630849},
+  {1.399467,0.189787},
+  {0.257626,0.021932},
+  {-0.112331,0.217707},
+  {-1.289427,1.432804},
+  {-0.390872,-0.357403},
+  {0.236182,0.303781},
+  {0.802511,0.330483},
+  {-1.028297,-0.403086},
+  {-0.147910,-0.288479},
+  {0.978197,-0.775374},
+  {0.868229,1.459663},
+  {0.452224,0.498722},
+  {0.746035,-0.670797},
+  {-0.360626,0.630983},
+  {-0.148420,-0.258364},
+  {-0.536846,0.526774},
+  {-0.736656,0.599485},
+  {0.251565,0.410096},
+  {-0.817544,0.436993},
+  {-0.361899,-0.266149},
+  {0.106065,1.119062},
+  {-0.001893,-0.840154},
+  {-0.174058,0.288847},
+  {0.450589,-0.520516},
+  {0.330658,-0.272313},
+  {0.560301,0.149574},
+  {-0.927905,-0.026315},
+  {-0.130635,0.149914},
+  {-0.167674,0.479912},
+  {0.163863,-0.914797},
+  {-0.236233,0.492833},
+  {-0.439716,-0.273501},
+  {1.097053,0.570964},
+  {-1.090225,-0.751110},
+  {-0.622561,-1.038814},
+  {0.309323,-1.010214},
+  {-0.204232,-0.589475},
+  {-0.039192,0.034730},
+  {-0.672256,0.289962},
+  {1.195556,-0.759149},
+  {0.701010,-0.946209},
+  {-0.211877,-0.021206},
+  {0.834771,0.269014},
+  {0.310538,0.897536},
+  {-0.416299,-0.103346},
+  {0.263666,-0.033155},
+  {1.199319,0.739114},
+  {0.209693,-0.011071},
+  {1.463650,-1.052988},
+  {-0.101228,-0.167856},
+  {1.234120,-0.942573},
+  {0.196785,0.954050},
+  {0.829042,0.153133},
+  {0.357430,0.139137},
+  {-1.233805,0.986066},
+  {-0.587524,0.933536},
+  {1.124220,0.284460},
+  {0.369787,-0.213798},
+  {-0.012298,1.911852},
+  {-1.586387,0.267615},
+  {0.696006,-0.464801},
+  {-0.624327,1.280676},
+  {0.367066,0.324597},
+  {0.000432,0.067311},
+  {0.390603,1.101625},
+  {0.256944,-0.623323},
+  {0.543036,0.814041},
+  {0.002517,-0.822681},
+  {-1.222231,0.151677},
+  {1.087153,-0.651828},
+  {-0.140421,-0.309047},
+  {-1.276460,-0.479672},
+  {0.907053,0.734263},
+  {-1.468305,1.325843},
+  {-0.742062,1.724340},
+  {0.602905,0.826894},
+  {-0.234395,0.552366},
+  {-0.319795,-0.300154},
+  {0.766130,0.375387},
+  {-0.565094,-0.908181},
+  {-0.002303,0.803038},
+  {0.606245,-0.886099},
+  {-0.375411,-0.501269},
+  {1.137430,0.498844},
+  {1.400551,1.243294},
+  {-0.572345,0.330001},
+  {-0.831085,0.224646},
+  {-1.193440,0.029548},
+  {-1.017357,0.114069},
+  {0.036078,0.403207},
+  {1.394122,-0.032985},
+  {-0.220085,0.427158},
+  {-1.279987,-0.411288},
+  {0.377185,0.243313},
+  {0.004243,-0.857524},
+  {1.036016,-0.532137},
+  {0.245228,-1.150637},
+  {1.467709,-0.614337},
+  {-0.512344,0.162373},
+  {-1.104046,-0.167139},
+  {-0.224718,-0.143013},
+  {-0.256979,0.070597},
+  {0.089855,-0.271238},
+  {-0.734984,0.724372},
+  {-0.217210,0.319333},
+  {0.718725,0.347974},
+  {0.251565,0.741094},
+  {0.290149,0.659867},
+  {0.408272,-0.032915},
+  {0.079918,0.470449},
+  {-1.011348,-0.572926},
+  {0.265858,-0.244285},
+  {0.498660,-1.173075},
+  {-0.489052,0.268982},
+  {0.803724,-0.240363},
+  {-0.448072,0.003395},
+  {0.190085,0.738899},
+  {-1.320261,-0.384362},
+  {-0.851492,-0.388560},
+  {0.421440,-0.177958},
+  {-0.701418,0.243165},
+  {-0.274377,0.336519},
+  {-0.432270,0.059413},
+  {0.723602,-1.369028},
+  {0.003061,1.025321},
+  {0.439715,0.455140},
+  {0.247416,-0.318078},
+  {-0.295679,-0.309351},
+  {-1.069923,0.563669},
+  {0.778952,0.003877},
+  {-0.650501,0.383655},
+  {0.290488,-0.280076},
+  {-0.318266,-0.503424},
+  {0.200569,-0.451626},
+  {-0.058511,1.000852},
+  {-0.501142,1.127454},
+  {0.840729,0.860918},
+  {0.404423,1.184485},
+  {0.080599,0.337071},
+  {0.265972,-0.831970},
+  {-0.792118,-0.632130},
+  {-1.312815,-0.150298},
+  {0.384463,0.434096},
+  {-0.473277,-0.646626},
+  {0.726083,0.524943},
+  {0.232413,-1.349094},
+  {-0.132578,-0.328246},
+  {0.192057,-0.949313},
+  {-0.294124,1.799810},
+  {-0.646249,-0.365151},
+  {-1.142885,-0.860267},
+  {0.952542,0.463949},
+  {-0.843407,0.603740},
+  {0.245604,0.005612},
+  {0.876790,-0.725446},
+  {-1.264255,-0.509446},
+  {0.935016,-0.003417},
+  {0.253759,-0.252225},
+  {-0.504993,0.338401},
+  {1.002041,0.260841},
+  {0.156989,-0.135302},
+  {-1.024724,-0.400709},
+  {-0.112462,-1.205456},
+  {0.334260,0.781035},
+  {0.183794,0.683842},
+  {-0.865777,0.383277},
+  {-0.505670,0.667817},
+  {-0.088249,0.840903},
+  {1.101360,1.926043},
+  {-0.308625,-0.138154},
+  {0.609676,-0.715983},
+  {-0.645769,-0.287890},
+  {0.369474,-0.729993},
+  {0.186644,0.541750},
+  {0.463282,0.674407},
+  {0.216844,-0.852488},
+  {0.856090,0.940839},
+  {1.001064,0.394220},
+  {-0.837133,-0.154497},
+  {-0.390434,0.439008},
+  {0.680226,-0.317541},
+  {0.098053,0.117416},
+  {0.071014,-0.649889},
+  {-0.262387,-0.155264},
+  {0.388413,0.769428},
+  {0.158413,0.941346},
+  {0.671325,-0.266932},
+  {0.970945,-0.618071},
+  {0.233638,0.572923},
+  {0.060161,-0.256486},
+  {-0.637504,0.063894},
+  {0.934414,-0.427341},
+  {-0.467026,0.652522},
+  {-0.863576,0.149723},
+  {-0.771443,-0.816274},
+  {0.511701,-0.479018},
+  {-0.257457,0.087086},
+  {0.290638,0.016947},
+  {-0.386981,-0.727179},
+  {-1.098515,-0.274432},
+  {-0.557208,1.426296},
+  {-0.613355,0.019539},
+  {-0.419196,-0.251018},
+  {-0.832714,0.502052},
+  {0.128755,0.655366},
+  {0.256114,0.273034},
+  {-1.125167,-0.906505},
+  {0.388043,-0.540845},
+  {-0.937881,2.105264},
+  {-0.202089,1.002912},
+  {0.723756,-0.449443},
+  {0.233778,0.527703},
+  {-0.057235,1.884349},
+  {1.157345,-0.412072},
+  {-0.955458,-1.385361},
+  {0.053114,0.627971},
+  {0.827722,0.375269},
+  {-0.181816,0.772748},
+  {-1.626276,0.442130},
+  {-0.435385,-0.179652},
+  {1.089080,-0.426374},
+  {1.017264,0.699838},
+  {-1.020426,-0.298556},
+  {0.676783,0.459662},
+  {-0.739834,0.763761},
+  {0.721741,-1.206326},
+  {-0.951135,-0.270497},
+  {-0.457913,-1.038211},
+  {1.712993,-0.468750},
+  {-0.543171,1.050327},
+  {-0.541388,0.741480},
+  {1.399220,-0.146602},
+  {-0.246873,1.307922},
+  {-0.314164,-0.681691},
+  {-0.361125,0.096600},
+  {0.468431,-0.456516},
+  {-1.208053,0.471189},
+  {-0.369852,-0.310925},
+  {-0.655492,-0.981961},
+  {1.982648,0.257313},
+  {0.350295,-0.328245},
+  {-0.408155,0.164967},
+  {1.186227,0.615053},
+  {1.538608,0.853998},
+  {-1.014463,-0.266268},
+  {-0.038058,1.267679},
+  {1.226620,-0.039905},
+  {0.128462,-0.723152},
+  {1.117944,-0.485275},
+  {0.110495,0.512575},
+  {0.613947,-0.332562},
+  {1.183653,-0.135030},
+  {-0.545671,-1.236704},
+  {-0.368847,0.282388},
+  {0.354177,-0.397370},
+  {-0.221450,0.619409},
+  {-0.212607,-0.070614},
+  {-0.746339,0.421409},
+  {-0.796334,0.416425},
+  {0.281155,-0.847141},
+  {1.084794,-0.633466},
+  {-1.416468,-0.504705},
+  {-0.413320,-0.218964},
+  {-0.006619,1.498092},
+  {0.592891,0.110515},
+  {0.202503,-0.802352},
+  {-1.044280,-0.551926},
+  {-0.551728,0.074422},
+  {-1.621229,-0.887687},
+  {-0.034501,-0.177771},
+  {0.643751,-0.498982},
+  {0.537422,0.214707},
+  {0.859316,0.230005},
+  {0.984145,0.642774},
+  {-0.446523,-0.283910},
+  {0.698656,-0.512658},
+  {-0.413664,0.370197},
+  {0.012230,0.057244},
+  {-0.124965,0.707693},
+  {-1.668994,0.589325},
+  {0.431439,0.916868},
+  {0.357835,-0.007437},
+  {0.091721,-1.193125},
+  {1.085117,0.362418},
+  {-0.815710,-0.704111},
+  {0.368599,0.417522},
+  {-0.153068,0.701186},
+  {0.633497,1.153006},
+  {-0.640502,-0.448321},
+  {-0.288243,-1.008288},
+  {-0.241203,0.571272},
+  {-0.700623,0.003668},
+  {0.762784,-0.271363},
+  {-0.675450,-0.536786},
+  {-1.095720,0.963368},
+  {-0.545080,-0.052652},
+  {0.425995,1.045991},
+  {0.747089,-0.106197},
+  {0.705921,0.481355},
+  {-0.231552,-0.495818},
+  {-0.035338,0.271549},
+  {-1.434181,-0.462102},
+  {-0.234651,-0.659026},
+  {0.293521,0.578445},
+  {-0.159469,-0.371527},
+  {0.947780,-0.184427},
+  {-0.575724,1.293055},
+  {1.217078,0.776812},
+  {0.077462,0.005225},
+  {0.031218,0.312440},
+  {-0.254340,-1.261328},
+  {-0.545078,0.114315},
+  {0.214459,0.265649},
+  {0.665158,-0.572889},
+  {0.156845,-0.494711},
+  {-0.805048,-0.829465},
+  {-1.377436,-0.234879},
+  {-0.680977,1.091655},
+  {0.991115,-0.327044},
+  {-0.636966,-0.868296},
+  {-0.468122,0.139195},
+  {-0.023171,-0.344042},
+  {0.779795,0.665803},
+  {0.288043,-0.640526},
+  {-0.377837,-0.768582},
+  {1.312911,0.154017},
+  {0.594896,0.205326},
+  {0.546600,-0.380945},
+  {-0.348857,-0.048100},
+  {-0.719583,0.758329},
+  {0.366828,0.580990},
+  {0.370738,0.785391},
+  {-0.058071,-1.293254},
+  {-0.886575,0.757403},
+  {0.424991,-0.722256},
+  {0.284736,0.076029},
+  {1.316231,-1.073572},
+  {-0.783294,0.805530},
+  {0.389834,-0.129104},
+  {1.095639,-0.075839},
+  {0.935852,-0.373630},
+  {-0.885108,-0.020762},
+  {0.158064,0.217629},
+  {-0.640319,-0.386929},
+  {-0.909168,-0.373835},
+  {0.010911,-0.101003},
+  {-0.277750,-0.148550},
+  {0.521820,1.009048},
+  {-0.512451,-0.513281},
+  {-0.008047,0.202402},
+  {0.741191,-0.666179},
+  {0.763195,0.771867},
+  {0.390221,0.297205},
+  {0.625399,0.489404},
+  {1.023425,0.108867},
+  {-0.703103,0.629155},
+  {-0.103211,-0.285761},
+  {-0.390588,1.375767},
+  {0.454617,-0.110921},
+  {0.317920,-0.896351},
+  {0.649451,-0.067138},
+  {-0.121899,-0.655986},
+  {0.358821,-1.041252},
+  {-0.222857,-0.303574},
+  {-0.568716,-0.089093},
+  {-0.192284,-0.838715},
+  {1.222415,-0.016245},
+  {0.526310,-0.627056},
+  {-0.068488,-1.753668},
+  {-1.039387,-0.320863},
+  {0.020520,0.318572},
+  {0.496641,-0.577605},
+  {-0.968605,-0.480527},
+  {0.285637,1.389404},
+  {0.944869,0.885298},
+  {0.638385,-0.710974},
+  {-0.279932,0.152341},
+  {-0.743228,-1.024093},
+  {-0.486215,-0.168400},
+  {-0.114585,1.020039},
+  {0.056702,-0.528896},
+  {-0.949243,-0.844536},
+  {1.129499,0.153529},
+  {-1.146171,-0.448270},
+  {-0.600020,-0.088151},
+  {1.026368,-0.907166},
+  {1.049642,1.198028},
+  {-0.732045,-0.405919},
+  {0.210230,-0.786201},
+  {0.310585,0.342437},
+  {0.067431,0.566931},
+  {-0.587248,0.255356},
+  {-0.170138,1.277977},
+  {-0.258523,-1.186042},
+  {-0.773006,-1.019886},
+  {-0.448797,-0.188137},
+  {-0.091370,0.772927},
+  {0.244919,-0.106617},
+  {-0.774478,-0.520363},
+  {0.440259,0.217792},
+  {0.363108,0.753145},
+  {-0.266081,0.238928},
+  {-1.127392,0.360823},
+  {-0.261177,1.592192},
+  {0.699450,0.113524},
+  {-0.655141,0.291248},
+  {-0.436259,-0.058521},
+  {0.384314,0.487647},
+  {0.039816,-1.110978},
+  {0.404230,0.678814},
+  {-0.949673,-0.269000},
+  {-0.248331,-1.005033},
+  {-0.540079,0.606271},
+  {0.444702,0.146360},
+  {1.015384,-1.065484},
+  {-1.877784,-1.198948},
+  {0.489736,1.350612},
+  {-0.710135,-0.775063},
+  {0.593538,-0.900296},
+  {-0.098286,-1.049735},
+  {-0.108973,0.545483},
+  {0.062642,-0.684699},
+  {0.098171,0.140806},
+  {-0.959390,-0.170130},
+  {0.461162,1.804670},
+  {1.124557,0.055315},
+  {0.189370,-1.658841},
+  {0.186242,-0.841503},
+  {0.633026,-0.735853},
+  {0.857498,-0.201044},
+  {-0.218993,-0.016715},
+  {-0.765959,0.455723},
+  {0.217731,-0.073306},
+  {-0.436889,0.159793},
+  {-0.023781,-0.349387},
+  {-0.248361,0.055098},
+  {-0.771684,0.303200},
+  {-0.211929,1.024403},
+  {0.104045,-1.383657},
+  {-0.416710,0.061459},
+  {-0.436209,-0.471431},
+  {-1.510879,-0.277018},
+  {0.200120,1.225231},
+  {-0.328469,0.600453},
+  {0.127003,-0.602157},
+  {0.987188,0.212941},
+  {0.670236,0.123304},
+  {0.422322,0.157453},
+  {0.152338,-0.945760},
+  {-0.025870,-0.413677},
+  {-0.268227,-0.778529},
+  {0.480173,0.907527},
+  {-0.888884,-1.439385},
+  {-1.351376,-1.091003},
+  {0.222836,-0.086297},
+  {0.573336,-1.360066},
+  {-0.806399,-0.498281},
+  {-0.595494,0.831074},
+  {0.908191,0.307062},
+  {-0.459795,-0.710666},
+  {-0.094751,-0.206448},
+  {-0.024242,-0.951987},
+  {-0.318051,0.362327},
+  {-0.063917,-0.408062},
+  {-0.003055,1.006656},
+  {1.000114,-0.003844},
+  {0.433414,0.153418},
+  {-0.146174,-0.778023},
+  {-0.002596,-0.081254},
+  {-0.372852,-0.562314},
+  {0.813749,-0.171006},
+  {0.516876,-0.334962},
+  {0.130150,-0.220825},
+  {-0.399139,-0.678091},
+  {-0.184451,-0.949755},
+  {-0.188671,0.303505},
+  {0.037500,-0.099776},
+  {0.773437,0.244504},
+  {0.445884,-0.043319},
+  {0.316367,-0.273157},
+  {-0.746967,0.698428},
+  {-0.191399,0.086704},
+  {1.316252,1.332223},
+  {0.445639,0.004308},
+  {-0.087606,0.111263},
+  {-0.891735,0.020169},
+  {0.193313,-0.606729},
+  {0.731145,-0.605570},
+  {-0.692633,0.021142},
+  {-0.444493,0.208281},
+  {-0.466215,-0.817877},
+  {-0.624077,-0.305184},
+  {0.280254,1.208432},
+  {0.014983,0.902646},
+  {0.006548,0.008337},
+  {0.044097,0.697776},
+  {-0.171889,-0.146767},
+  {0.265368,0.009346},
+  {1.059121,0.446341},
+  {1.888582,-0.599794},
+  {-0.562391,0.519765},
+  {-1.251330,-0.838557},
+  {-2.137730,-0.631450},
+  {0.182187,0.499127},
+  {0.764443,0.756613},
+  {0.631286,0.584558},
+  {1.111431,-0.772644},
+  {0.076405,0.183672},
+  {-0.058883,-0.335039},
+  {-0.703857,0.073318},
+  {0.757167,0.909054},
+  {-0.611251,-0.894211},
+  {-0.330231,0.304851},
+  {-0.364020,-0.938645},
+  {-0.104970,0.914045},
+  {0.093519,1.357853},
+  {-0.770065,-0.085731},
+  {1.319136,0.816044},
+  {0.058947,-0.406575},
+  {-0.396587,-0.503710},
+  {0.220349,-0.336425},
+  {-0.501066,0.255245},
+  {1.323531,-1.916640},
+  {-0.596563,0.742761},
+  {0.713492,-0.603602},
+  {0.051641,-0.788488},
+  {-0.027644,-0.011744},
+  {0.313449,0.369693},
+  {-0.874394,-0.458299},
+  {0.156414,-0.301505},
+  {-0.817243,-0.129309},
+  {0.387262,1.050022},
+  {-0.730068,0.280044},
+  {0.562581,0.907164},
+  {0.467513,0.105385},
+  {0.244667,0.168116},
+  {0.639852,0.033501},
+  {0.208643,0.034229},
+  {0.947509,-1.095182},
+  {0.730262,1.390582},
+  {-0.409880,-1.003160},
+  {0.401874,1.156874},
+  {-0.714656,-1.740182},
+  {-0.430680,-0.361054},
+  {-0.188850,0.396311},
+  {0.796301,-0.592325},
+  {-1.140359,-0.833160},
+  {-0.015264,-0.656368},
+  {1.098273,-0.926714},
+  {0.514728,-0.216690},
+  {0.098571,-0.636577},
+  {-0.910064,0.415927},
+  {-0.440682,0.758024},
+  {0.127293,0.104132},
+  {-0.981800,-0.277406},
+  {0.899617,-0.979514},
+  {0.602636,0.426296},
+  {0.150065,0.494543},
+  {0.232962,0.763611},
+  {0.467684,0.140699},
+  {-1.574619,0.669059},
+  {0.882179,-0.011036},
+  {0.097422,0.257114},
+  {-0.102244,-0.259914},
+  {0.490538,0.105090},
+  {-0.996295,0.948638},
+  {0.083436,0.900836},
+  {0.438195,0.350201},
+  {-0.679329,-0.713746},
+  {0.529187,1.286256},
+  {-0.954747,-0.283946},
+  {-0.130941,-0.382040},
+  {-0.158855,-1.450548},
+  {-0.250052,-0.982319},
+  {-0.268123,-0.627128},
+  {0.444598,1.229273},
+  {1.187865,0.972354},
+  {1.162571,0.615927},
+  {-0.053069,-0.762640},
+  {0.568529,0.950631},
+  {0.704832,-0.363101},
+  {-0.821986,-0.831900},
+  {0.321775,-0.386797},
+  {0.318484,-0.462144},
+  {-0.981095,-0.085616},
+  {-0.827586,-0.611532},
+  {-0.767987,0.213131},
+  {1.465830,0.359996},
+  {0.063406,-0.101972},
+  {0.103066,-0.104108},
+  {-0.332640,-0.565526},
+  {0.153801,0.192602},
+  {-0.180607,-0.683069},
+  {-1.020433,-0.029838},
+  {-1.056090,-0.281924},
+  {0.711217,1.040632},
+  {-0.779687,-0.286412},
+  {-1.227989,0.344829},
+  {-0.325886,-0.117333},
+  {0.010627,0.905134},
+  {-0.179905,-0.040737},
+  {-0.034126,0.635378},
+  {-0.551102,-0.611186},
+  {1.349050,0.713766},
+  {-1.950842,0.993737},
+  {-0.285493,0.919628},
+  {-0.839695,-1.284912},
+  {0.867960,0.118154},
+  {-0.524136,-0.534178},
+  {-0.606047,-0.077576},
+  {0.997701,-0.360559},
+  {-0.143819,-0.521362},
+  {0.277948,0.011120},
+  {0.781126,-0.650844},
+  {0.514107,-0.291052},
+  {-0.605037,0.018662},
+  {0.595003,-0.358330},
+  {-0.892601,-0.794597},
+  {-1.068990,-1.057503},
+  {-0.833229,1.270529},
+  {-0.334875,0.977099},
+  {-0.663629,0.338105},
+  {0.554117,-0.088210},
+  {-0.667932,1.031071},
+  {-0.082927,-0.130890},
+  {-0.543973,-0.272414},
+  {1.397328,0.081006},
+  {0.369186,0.137642},
+  {-1.393635,0.792070},
+  {-0.582444,-0.031794},
+  {-0.053332,-0.043677},
+  {-0.372722,-0.230031},
+  {1.135177,0.092456},
+  {0.280377,-0.188462},
+  {-0.486260,-0.151009},
+  {1.265662,0.491554},
+  {-0.473461,0.147609},
+  {-0.239905,-0.801906},
+  {-0.220706,0.501078},
+  {0.640279,-0.721218},
+  {-0.349523,-0.466126},
+  {0.322248,0.690068},
+  {0.360951,0.602485},
+  {0.312384,-0.548838},
+  {-1.562549,0.675293},
+  {0.282446,0.191236},
+  {-0.251916,0.509349},
+  {-1.270286,-1.114868},
+  {-0.429550,-0.631172},
+  {0.636991,1.337931},
+  {-0.239257,-0.528962},
+  {0.203516,0.107619},
+  {-0.158954,0.175905},
+  {0.017560,-0.973022},
+  {1.063318,-0.351026},
+  {-0.500848,0.195306},
+  {-0.407674,-0.547799},
+  {0.311455,-0.233779},
+  {0.950908,0.750602},
+  {0.087365,-0.326519},
+  {-0.921551,-0.059790},
+  {-0.237386,0.904391},
+  {0.579191,-1.093121},
+  {1.114219,0.472145},
+  {1.464486,-0.047726},
+  {0.230240,-0.507439},
+  {0.214072,0.384204},
+  {0.227012,1.628634},
+  {0.862830,-0.777709},
+  {0.499309,0.503287},
+  {0.194024,-0.094408},
+  {-0.333249,-1.050169},
+  {-0.510589,-1.637118},
+  {-0.885624,-0.982164},
+  {1.742562,-1.274337},
+  {0.089119,-1.079374},
+  {-0.446537,-0.098650},
+  {0.360210,-0.124113},
+  {-0.658511,0.326397},
+  {-0.544164,0.579137},
+  {-0.251213,0.155793},
+  {0.335646,0.461865},
+  {0.443714,-0.380484},
+  {-0.217890,0.767709},
+  {-1.477727,-0.131848},
+  {-0.670288,-0.482916},
+  {1.276010,-0.242181},
+  {-0.569009,-0.344377},
+  {0.258112,0.099654},
+  {-0.470833,-0.107608},
+  {0.077847,-1.011430},
+  {-0.095550,-1.610504},
+  {-0.245212,-0.779197},
+  {0.507037,0.270557},
+  {-0.210576,-0.406151},
+  {0.334297,0.471540},
+  {0.940615,-0.817298},
+  {0.807612,-0.335314},
+  {-0.967504,1.005527},
+  {-0.419911,-0.427284},
+  {1.058308,0.377315},
+  {-0.640751,-0.100329},
+  {-0.206736,-1.490178},
+  {-0.908508,0.534514},
+  {0.236230,-0.674558},
+  {0.040694,0.194800},
+  {0.926613,-0.976837},
+  {-0.400272,0.398158},
+  {1.213940,-0.431001},
+  {-0.154429,-0.506394},
+  {0.263405,-0.666924},
+  {-0.587860,-1.305488},
+  {-0.626593,0.117810},
+  {0.343828,1.396967},
+  {0.083446,-0.263320},
+  {-0.486981,-0.263767},
+  {-0.353650,0.590502},
+  {0.546912,0.129352},
+  {-0.148903,-0.442021},
+  {0.148692,0.307489},
+  {0.456169,0.695536},
+  {-0.306257,0.742800},
+  {0.843344,-0.137786},
+  {-0.403558,-0.081928},
+  {0.004422,0.767584},
+  {0.602551,-0.925966},
+  {0.808077,0.677800},
+  {-0.920983,0.444859},
+  {0.709114,-0.150759},
+  {0.774244,0.583938},
+  {-0.007792,-0.664973},
+  {0.811944,-0.309259},
+  {0.744698,-0.075886},
+  {-0.510442,-0.065905},
+  {-0.015831,-0.190166},
+  {0.713298,-0.160445},
+  {-0.693444,0.164467},
+  {0.504515,0.718341},
+  {-0.357876,0.683165},
+  {-0.509067,0.349283},
+  {0.027786,0.967045},
+  {0.001332,-0.162389},
+  {-0.917110,0.767740},
+  {0.095917,-0.158809},
+  {-0.542706,0.715325},
+  {0.730792,0.659037},
+  {-0.010585,-0.228058},
+  {0.500959,-0.152128},
+  {0.079144,0.005812},
+  {-1.190054,-0.493119},
+  {0.184814,1.759480},
+  {0.491137,-0.172917},
+  {-1.489489,-0.538351},
+  {0.038032,0.828474},
+  {-0.790134,0.518021},
+  {1.008854,0.645478},
+  {0.307948,0.009483},
+  {-0.329913,0.936288},
+  {0.018155,-0.235603},
+  {-0.321219,-1.203784},
+  {0.428175,-0.218314},
+  {-0.362877,-0.370190},
+  {0.444549,-0.342885},
+  {-0.049808,0.501963},
+  {0.674179,-0.185107},
+  {0.599912,-1.732999},
+  {0.088862,0.782982},
+  {-0.107951,0.180743},
+  {-0.122355,1.267863},
+  {0.550598,-0.112575},
+  {-0.000421,0.525225},
+  {1.443725,0.501908},
+  {-0.409289,0.574812},
+  {-0.039830,0.421113},
+  {0.508459,-1.005977},
+  {-1.445393,-1.149261},
+  {-0.631553,-0.319625},
+  {-0.909902,0.054411},
+  {0.339123,2.211716},
+  {-1.144259,0.907937},
+  {0.767662,0.182702},
+  {-0.001103,-0.936672},
+  {0.724690,-0.821044},
+  {-0.127908,0.396448},
+  {-1.259213,-0.942427},
+  {0.270614,0.534192},
+  {0.302353,-0.606736},
+  {0.368202,0.117501},
+  {-0.621508,-0.599182},
+  {-0.389050,0.382474},
+  {0.276748,-0.206800},
+  {0.692974,-2.222835},
+  {0.281160,0.177410},
+  {0.692791,0.111511},
+  {0.641347,0.456632},
+  {-0.024490,0.649549},
+  {-0.110421,-1.172916},
+  {-1.093464,-0.732331},
+  {-0.355374,-0.282145},
+  {0.758283,-0.156623},
+  {-1.392806,-0.020595},
+  {0.062043,-0.332704},
+  {0.072246,-0.407848},
+  {0.764714,-0.922699},
+  {0.324736,0.223764},
+  {0.322471,-0.791710},
+  {-0.310998,0.871270},
+  {0.409121,0.452691},
+  {-0.507904,0.540686},
+  {0.247319,0.370197},
+  {0.289584,0.022769},
+  {0.918507,-0.797867},
+  {-0.002342,-0.653221},
+  {0.665966,0.086050},
+  {-0.105914,0.520572},
+  {0.661266,-0.788971},
+  {-0.016104,1.032441},
+  {-1.079144,0.763598},
+  {0.286110,-0.408518},
+  {-0.702570,-0.278708},
+  {0.418026,-1.825956},
+  {-0.699938,0.339054},
+  {-0.549577,-0.472606},
+  {-0.958419,-0.399456},
+  {0.931910,0.405273},
+  {-0.061580,-0.001784},
+  {-0.235095,-0.195635},
+  {0.396945,-0.793988},
+  {-0.120105,0.741895},
+  {0.967101,-1.193312},
+  {0.408000,0.328582},
+  {0.121563,0.074206},
+  {0.794018,0.365534},
+  {1.427377,-0.303106},
+  {-1.185743,-0.469011},
+  {-1.014410,-0.160477},
+  {0.891003,-0.675965},
+  {-0.449822,0.835702},
+  {0.168080,-0.372203},
+  {0.231932,-0.813300},
+  {0.695524,0.543724},
+  {-1.150522,-0.300759},
+  {-1.130058,-0.194783},
+  {-0.158590,0.163209},
+  {0.318411,-1.215333},
+  {-0.130949,1.027326},
+  {-0.022279,-0.079554},
+  {-0.819798,-1.296138},
+  {0.045197,0.904739},
+  {2.069130,-0.927992},
+  {-0.409507,0.500071},
+  {-0.320066,-1.146465},
+  {0.541117,0.115373},
+  {-0.789460,-0.165824},
+  {0.540866,-0.330202},
+  {-0.794487,-0.094771},
+  {-0.857677,0.866646},
+  {-1.027897,-0.906066},
+  {-0.990814,-0.484744},
+  {-1.118999,1.518096},
+  {0.368560,0.062309},
+  {-0.472288,-0.358193},
+  {0.818078,0.355593},
+  {0.432227,0.535003},
+  {0.881773,-0.248469},
+  {0.386008,-0.326813},
+  {0.729605,-0.034809},
+  {-1.973023,-0.054177},
+  {-0.155383,0.156626},
+  {-0.654563,0.363333},
+  {-0.629236,0.253927},
+  {0.047558,-0.270537},
+  {0.876852,1.219813},
+  {0.676330,0.747201},
+  {1.527175,-0.031846},
+  {0.058820,0.330611},
+  {-1.429720,-0.026237},
+  {0.145607,-0.314241},
+  {-1.057689,-0.330500},
+  {0.140384,-0.134579},
+  {-0.954319,0.012254},
+  {0.454891,-1.125468},
+  {2.357209,-0.042871},
+  {-1.230701,0.477340},
+  {-0.320824,-0.139064},
+  {-0.761107,0.100853},
+  {-0.288901,-0.086378},
+  {-0.428826,1.158555},
+  {0.547848,-1.217274},
+  {-0.445240,-0.070165},
+  {-1.133672,0.465347},
+  {0.623461,0.635773},
+  {1.003495,-0.575461},
+  {-0.028313,-1.236159},
+  {-0.362889,0.221756},
+  {-0.439814,-0.193680},
+  {0.519280,1.102878},
+  {0.752761,0.423081},
+  {0.166261,-0.338834},
+  {-0.310806,-0.151127},
+  {-0.160761,0.442555},
+  {0.654292,-0.498436},
+  {0.080171,-0.983075},
+  {0.630524,0.050145},
+  {-1.094236,0.845830},
+  {-0.395812,-1.350396},
+  {0.362922,-1.130889},
+  {0.657214,0.160993},
+  {-1.055868,0.691473},
+  {-0.077860,-0.396539},
+  {0.272831,0.186593},
+  {-0.963077,1.436838},
+  {-1.491045,0.983782},
+  {-0.445406,-1.055664},
+  {-0.560002,0.315656},
+  {-1.094953,0.428742},
+  {1.355583,-0.101228},
+  {-0.610726,-0.903339},
+  {0.220781,0.133283},
+  {-0.385599,-0.105530},
+  {1.569466,0.694499},
+  {-0.949049,0.657375},
+  {0.293380,-0.197649},
+  {-0.121347,-1.023660},
+  {0.142107,1.869948},
+  {0.240700,1.753354},
+  {0.155119,-0.787710},
+  {0.072108,0.802771},
+  {-0.518774,-0.835932},
+  {0.686448,0.413265},
+  {-0.075227,0.357503},
+  {-0.367060,-0.293209},
+  {1.198188,0.228709},
+  {0.086829,0.401398},
+  {0.402488,-0.001439},
+  {1.875893,1.073098},
+  {-0.997759,-1.144125},
+  {-0.046681,0.959887},
+  {-0.059867,0.850184},
+  {-0.456443,-0.686195},
+  {-0.245116,-0.874781},
+  {-0.652563,-1.042379},
+  {-0.538923,0.202282},
+  {-0.076387,-0.432216},
+  {0.434154,-0.289432},
+  {0.791833,1.524970},
+  {-1.011962,0.122749},
+  {0.443728,0.583743},
+  {-0.476166,-0.164564},
+  {0.865760,1.395544},
+  {0.458453,0.486414},
+  {-1.083056,-0.554460},
+  {-0.320430,1.151998},
+  {-0.522975,0.380352},
+  {-0.800879,-0.410712},
+  {-1.160173,-0.225969},
+  {-0.727965,-0.082624},
+  {-0.078411,0.553021},
+  {0.825728,-0.312162},
+  {-1.384057,0.781615},
+  {-0.368922,0.233514},
+  {0.279253,-0.378687},
+  {0.403824,0.290804},
+  {-0.229572,-0.601070},
+  {-0.626745,-0.384230},
+  {-1.287989,-0.222999},
+  {0.484008,-0.010462},
+  {0.301750,-0.985000},
+  {-0.633804,0.825349},
+  {0.394338,-0.576349},
+  {0.468509,0.024264},
+  {0.255173,-0.901778},
+  {0.346377,-0.280184},
+  {0.110180,0.975376},
+  {-0.753469,-0.647554},
+  {0.651564,-0.547723},
+  {-0.144017,0.548258},
+  {-0.046057,-0.679254},
+  {-0.688028,0.887658},
+  {-0.445831,-0.479626},
+  {-0.456182,0.267624},
+  {-0.799260,0.204550},
+  {0.563612,-0.771680},
+  {0.352540,0.832719},
+  {-0.186709,-0.571833},
+  {-0.293953,-0.033501},
+  {-0.817521,0.420114},
+  {-1.095604,-0.434751},
+  {1.279435,-0.039357},
+  {-0.247834,0.165422},
+  {0.921388,0.559970},
+  {-0.060142,0.715675},
+  {0.740212,1.014127},
+  {-0.452908,0.311206},
+  {-0.067195,-0.201576},
+  {-1.385389,-0.762611},
+  {-1.021316,-1.118405},
+  {1.760285,0.265590},
+  {-0.914306,0.241406},
+  {-1.244930,-0.148217},
+  {-0.866724,0.107860},
+  {0.289939,-1.543434},
+  {0.245372,0.941026},
+  {0.353275,-0.177928},
+  {-0.031020,1.110706},
+  {0.377406,-0.075570},
+  {-0.164487,1.047496},
+  {-0.499391,-0.473578},
+  {0.300038,-0.640920},
+  {-0.628968,0.062134},
+  {0.489684,-0.638970},
+  {-0.015019,0.460942},
+  {-0.638345,-1.058916},
+  {-0.916723,0.886223},
+  {-0.333517,0.053708},
+  {0.736499,-0.159192},
+  {-0.594457,0.367349},
+  {-1.222093,-0.085438},
+  {0.251137,-0.073996},
+  {0.161582,0.194835},
+  {-0.380923,0.667572},
+  {-0.679757,-0.361005},
+  {-0.028839,0.205199},
+  {1.091436,-1.342332},
+  {-0.221619,-0.241515},
+  {-1.053060,0.026055},
+  {0.644250,-1.217245},
+  {-1.450051,0.901819},
+  {-0.920654,-0.715461},
+  {-0.130068,1.003309},
+  {1.031255,0.523672},
+  {-0.136103,-1.381621},
+  {-0.011925,-0.254506},
+  {-0.960022,1.478489},
+  {0.103113,-1.121767},
+  {-0.272495,0.511347},
+  {0.286424,0.059268},
+  {1.022935,0.594292},
+  {0.591589,0.954365},
+  {0.350593,-0.458349},
+  {-0.050092,0.359806},
+  {-1.176490,0.825566},
+  {-0.680308,-1.571630},
+  {0.664836,-1.675775},
+  {0.341383,-0.000495},
+  {-0.036233,0.927286},
+  {-1.339825,-0.242439},
+  {-0.295042,-1.175472},
+  {0.327445,-0.305612},
+  {-1.334769,0.363978},
+  {-0.428302,-1.062567},
+  {0.329631,0.597784},
+  {0.869728,-1.290804},
+  {0.836562,0.583755},
+  {-0.647207,-0.128658},
+  {-0.438580,-0.636896},
+  {-0.104333,1.364442},
+  {0.134730,-0.418112},
+  {-0.297180,-0.005213},
+  {-0.277926,-0.075135},
+  {-0.356162,-1.540321},
+  {-0.315842,-0.300644},
+  {-1.054645,0.153170},
+  {-0.247471,0.149554},
+  {1.167076,-0.050294},
+  {-1.150539,-0.133037},
+  {1.375072,-0.851715},
+  {0.074937,-0.949878},
+  {-0.757522,-0.348698},
+  {-0.904564,0.281156},
+  {-0.601026,-0.749410},
+  {-0.559856,0.573678},
+  {-1.146828,0.569818},
+  {0.867965,0.745430},
+  {-1.303702,-0.904121},
+  {0.878923,-0.963699},
+  {-0.201701,-0.181087},
+  {0.623439,-1.377927},
+  {-0.196558,-0.155427},
+  {0.545429,0.059872},
+  {-0.546805,-0.394397},
+  {-0.673582,0.666513},
+  {-0.904560,0.345434},
+  {-0.404512,0.602264},
+  {0.037119,0.766632},
+  {0.114462,0.094188},
+  {0.152701,0.227803},
+  {0.192302,0.350055},
+  {-0.806506,0.365440},
+  {1.434434,0.090690},
+  {-0.927956,0.028970},
+  {-0.935372,-0.873602},
+  {-0.008948,-0.719395},
+  {0.984091,-0.139250},
+  {-0.659274,0.742974},
+  {-0.389700,0.424576},
+  {-0.417964,-0.791927},
+  {-0.496517,-0.670771},
+  {-0.839619,-0.452674},
+  {0.353229,-0.699395},
+  {0.160866,0.370645},
+  {-1.017395,1.246349},
+  {-0.215995,-0.034148},
+  {-0.917350,0.216393},
+  {0.676833,-1.047976},
+  {0.260097,0.124759},
+  {0.217774,-0.111813},
+  {0.676580,-0.052744},
+  {0.283784,0.299891},
+  {-0.063002,-0.428329},
+  {0.105711,-0.622631},
+  {-0.355259,-0.471869},
+  {0.266862,0.081740},
+  {-1.059721,0.037092},
+  {-0.335785,-0.856030},
+  {0.165769,0.484277},
+  {-0.709411,-0.235252},
+  {0.027820,0.592038},
+  {0.069184,0.501440},
+  {1.395272,2.336471},
+  {0.930130,0.779630},
+  {0.985494,0.017321},
+  {0.462865,-0.679985},
+  {-0.562682,-0.638530},
+  {-0.220520,-1.015673},
+  {0.447075,0.614206},
+  {-0.113999,0.348454},
+  {-0.330527,-1.009147},
+  {0.389321,-0.059019},
+  {0.160636,1.179804},
+  {0.951858,0.075998},
+  {0.220489,0.169580},
+  {1.011409,-1.264994},
+  {0.431117,-0.022166},
+  {1.354951,0.693625},
+  {0.365787,0.922387},
+  {-0.335963,0.354223},
+  {-0.231851,1.246409},
+  {0.039846,-0.434578},
+  {-0.640260,-0.246655},
+  {1.010049,-0.948681},
+  {0.420819,0.066446},
+  {-0.792475,-0.850887},
+  {-0.136391,-0.217795},
+  {-0.306861,-1.044193},
+  {0.599871,0.242422},
+  {0.837296,-0.704235},
+  {-1.036397,0.218225},
+  {-0.362114,-0.270397},
+  {-0.815529,-0.643457},
+  {-0.346423,0.137188},
+  {-0.533657,0.614111},
+  {0.894783,0.792716},
+  {0.996665,0.135734},
+  {-1.810934,-0.175269},
+  {0.231803,0.610888},
+  {-0.033074,-0.878133},
+  {1.029652,-0.537181},
+  {0.969218,-0.136601},
+  {0.637612,0.569671},
+  {-0.856078,0.008827},
+  {-0.884361,0.905464},
+  {0.266886,0.602131},
+  {0.724282,0.927329},
+  {0.656946,1.176936},
+  {0.385285,0.453920},
+  {0.428491,1.218457},
+  {-0.534283,-0.476385},
+  {1.265943,-0.071326},
+  {1.205410,0.119519},
+  {0.729693,0.805513},
+  {0.792140,0.259950},
+  {0.032696,0.915109},
+  {0.577120,-0.330747},
+  {0.393790,-0.488283},
+  {-0.285168,-0.266736},
+  {-1.092401,0.351137},
+  {-0.410238,-0.455906},
+  {-0.112126,-1.848342},
+  {-0.694043,0.586241},
+  {-0.282187,-0.084074},
+  {0.208143,-0.690431},
+  {-0.294220,-0.077478},
+  {0.114810,-0.640660},
+  {0.317942,0.617271},
+  {-1.111586,0.978228},
+  {0.522150,1.274807},
+  {-0.714204,0.099528},
+  {-0.270756,-0.875450},
+  {0.562005,-0.039459},
+  {0.705905,0.860567},
+  {0.762285,1.074943},
+  {-0.776165,-0.025768},
+  {-0.459283,-0.636944},
+  {0.185427,-0.185363},
+  {0.204738,0.186381},
+  {0.973185,0.077738},
+  {-0.292046,-0.508409},
+  {0.513353,-0.271946},
+  {0.003043,0.871596},
+  {0.688854,0.660598},
+  {0.210751,0.387266},
+  {-0.279586,-1.103817},
+  {-0.688930,0.757404},
+  {0.565899,-0.300622},
+  {0.174615,0.399735},
+  {0.138945,0.695770},
+  {0.223658,0.384469},
+  {-1.073520,-0.360915},
+  {-0.489023,-0.405400},
+  {-0.605479,-1.167890},
+  {-0.411600,0.781236},
+  {-1.073459,1.248510},
+  {0.810854,-0.254195},
+  {1.234502,-0.806495},
+  {0.260701,1.174122},
+  {-0.372537,1.946493},
+  {0.314475,0.895673},
+  {-1.009274,0.473788},
+  {-0.182152,-0.423023},
+  {0.252709,2.433176},
+  {0.355098,0.295953},
+  {-0.547349,0.145758},
+  {-0.602792,0.126766},
+  {-0.736203,-0.064009},
+  {0.927410,-0.913014},
+  {0.685445,0.595637},
+  {-1.650825,-0.447151},
+  {0.274037,0.349263},
+  {0.465722,0.789074},
+  {-0.162240,-0.368575},
+  {-0.699205,-0.695247},
+  {-1.299655,-0.834587},
+  {-0.112135,0.439572},
+  {-0.554151,0.008035},
+  {0.843647,-0.401783},
+  {-0.043751,-0.334123},
+  {1.091176,0.919460},
+  {-0.122626,-0.120011},
+  {0.282004,0.565924},
+  {1.054618,0.582818},
+  {-0.770044,0.182383},
+  {-0.377127,-0.662357},
+  {0.699934,-0.416461},
+  {0.725721,-2.274378},
+  {-0.285218,-0.376295},
+  {-0.046947,0.662061},
+  {-0.150529,-0.552474},
+  {0.366969,-0.279145},
+  {-0.522761,0.138649},
+  {0.359948,-1.543065},
+  {-1.101930,-0.354878},
+  {0.338112,-0.700804},
+  {-0.408526,0.129634},
+  {0.649985,-0.651205},
+  {0.418800,-0.999764},
+  {0.357306,-1.544311},
+  {-0.381705,-0.067610},
+  {-0.161721,0.259118},
+  {-0.606741,0.789184},
+  {0.281002,0.526998},
+  {0.011339,-0.794455},
+  {-1.830912,-0.398614},
+  {-0.550333,0.484507},
+  {0.380872,0.240877},
+  {-0.333808,0.561707},
+  {-0.306073,-0.400679},
+  {0.455130,0.236129},
+  {-1.028073,-0.645612},
+  {-0.594235,-0.259487},
+  {-0.990751,0.305760},
+  {0.006477,-1.019058},
+  {0.269924,-0.321009},
+  {-0.232176,-0.961120},
+  {-0.595080,-0.028841},
+  {1.278412,0.318883},
+  {0.447321,1.388019},
+  {0.532051,0.673116},
+  {-1.563452,-0.046970},
+  {-0.449587,0.019068},
+  {0.606453,-0.602681},
+  {1.166692,-0.056815},
+  {-0.500489,0.600240},
+  {-0.500505,-0.287763},
+  {0.713353,-0.974392},
+  {0.627625,-0.903950},
+  {0.360888,0.126583},
+  {-0.455974,-0.380084},
+  {-0.104278,-0.465263},
+  {0.651519,0.420961},
+  {0.788706,0.245607},
+  {0.070684,-0.600027},
+  {0.647984,-0.619099},
+  {0.649698,-1.690212},
+  {0.318449,0.028318},
+  {-1.471110,1.370645},
+  {1.207134,-0.322368},
+  {-0.685125,0.769329},
+  {1.287764,0.797221},
+  {-0.996293,1.087134},
+  {0.442161,-0.195315},
+  {0.121135,0.058126},
+  {1.045922,0.679832},
+  {0.873562,0.306245},
+  {-0.946556,-1.014899},
+  {-1.098702,-0.429317},
+  {-0.259191,0.604008},
+  {-0.446836,-0.599038},
+  {0.079361,-0.237178},
+  {-0.530503,0.677970},
+  {-0.601736,0.605187},
+  {-0.160833,0.081568},
+  {-0.692943,-1.922262},
+  {-1.351586,-0.764923},
+  {-0.910394,1.516147},
+  {-0.447204,0.696053},
+  {-1.603351,0.949397},
+  {0.853493,-0.313292},
+  {-0.782020,0.417463},
+  {-0.229522,0.508701},
+  {0.760533,-0.023716},
+  {0.227146,0.243735},
+  {-0.842789,0.148573},
+  {0.517921,-0.314691},
+  {0.692720,0.314784},
+  {0.280511,0.102037},
+  {0.665274,-0.165350},
+  {0.082569,0.733769},
+  {0.296156,1.171633},
+  {1.047696,0.574972},
+  {1.019455,0.327643},
+  {0.590864,-0.069291},
+  {0.058153,-0.552653},
+  {0.532137,-0.655718},
+  {0.030514,0.631288},
+  {0.014617,0.384621},
+  {1.061152,0.155026},
+  {-1.531251,0.473269},
+  {0.989563,0.018146},
+  {-0.456740,0.513566},
+  {0.652150,0.217298},
+  {0.305406,-0.295892},
+  {-2.437038,-0.899029},
+  {0.129350,0.230154},
+  {-0.072882,-0.255708},
+  {1.735334,-0.122027},
+  {0.357863,-0.822077},
+  {-0.260330,-1.094809},
+  {-0.618916,0.441565},
+  {-0.692015,0.582413},
+  {-0.962700,-0.265797},
+  {-0.354149,0.603085},
+  {-0.086914,-0.518697},
+  {-0.573745,-0.565417},
+  {0.606341,0.808186},
+  {-0.799331,0.580242},
+  {-0.096986,0.161126},
+  {0.633315,0.549819},
+  {-0.144446,0.177149},
+  {0.781768,0.531140},
+  {0.338951,-0.899343},
+  {0.498622,-0.161978},
+  {-1.030481,0.406074},
+  {-0.853416,0.247330},
+  {-0.021314,0.430044},
+  {-0.792349,-0.084728},
+  {0.661328,1.015329},
+  {-0.127205,0.562281},
+  {0.597676,0.621570},
+  {0.134817,0.231554},
+  {-0.159303,-0.083000},
+  {1.241670,-0.215870},
+  {0.511646,-0.487637},
+  {0.396153,0.003545},
+  {-0.879940,-0.429533},
+  {-0.720669,0.339226},
+  {-0.316744,0.113981},
+  {-0.177206,1.125024},
+  {-1.768052,-1.277820},
+  {0.241700,-0.037855},
+  {-0.839180,0.779339},
+  {-0.368304,-0.224287},
+  {-0.788630,0.576087},
+  {0.842764,-0.512279},
+  {-0.162576,0.392872},
+  {-0.704226,0.243854},
+  {0.131859,-0.414154},
+  {-0.819482,-1.100527},
+  {-0.470748,0.467712},
+  {-0.316207,0.030052},
+  {-0.235583,-0.156785},
+  {-0.557592,-0.375994},
+  {-0.784024,0.716792},
+  {-0.032535,0.712314},
+  {-0.122718,0.060842},
+  {0.256587,-0.063350},
+  {1.593900,-0.262349},
+  {-0.241222,1.230849},
+  {0.595739,0.423673},
+  {0.891444,0.670761},
+  {0.005808,0.459865},
+  {0.340771,-0.696366},
+  {-0.238902,0.415223},
+  {-0.572688,-0.354505},
+  {-0.059561,0.494342},
+  {0.693758,-0.277854},
+  {-0.037608,-0.300489},
+  {0.644744,1.106841},
+  {0.232660,0.485564},
+  {2.011315,0.810211},
+  {1.047770,-0.099242},
+  {1.206122,0.597776},
+  {-1.206184,0.417061},
+  {-0.522987,0.244164},
+  {-0.036536,0.528486},
+  {-0.624421,-0.312582},
+  {0.898749,0.177874},
+  {1.192713,-0.990058},
+  {0.498853,-0.556840},
+  {0.589997,-1.001501},
+  {0.623528,-0.219887},
+  {0.082308,0.170954},
+  {-0.289952,0.937628},
+  {-0.907912,-0.664638},
+  {0.010034,-0.573764},
+  {0.911873,0.898607},
+  {0.204328,0.208605},
+  {0.886008,0.671941},
+  {-0.238965,-0.470697},
+  {-0.047580,-1.367534},
+  {0.445139,0.183575},
+  {-0.257686,1.029901},
+  {0.650779,0.298196},
+  {-1.048885,0.864492},
+  {0.018705,1.086719},
+  {0.353729,-0.758869},
+  {0.135370,-0.483281},
+  {-1.076019,0.680627},
+  {1.100044,0.598223},
+  {-1.294965,1.147402},
+  {-0.106790,0.436389},
+  {-0.743914,1.121257},
+  {-0.871260,1.178553},
+  {0.204845,-0.486308},
+  {0.361820,-0.974340},
+  {-0.206131,0.818694},
+  {0.788987,0.506632},
+  {0.344848,-1.206124},
+  {1.204349,-0.052713},
+  {0.485916,-0.425330},
+  {-0.356002,1.018318},
+  {-0.627702,0.255646},
+  {-1.301431,0.413334},
+  {0.247930,-0.302713},
+  {-1.193767,0.508636},
+  {0.802304,-0.014054},
+  {0.225364,0.597259},
+  {1.130788,0.014869},
+  {-0.375125,-0.713056},
+  {-0.887297,-1.193802},
+  {0.911819,0.357139},
+  {0.102299,1.114198},
+  {0.346137,0.583719},
+  {-0.295741,-0.163232},
+  {0.306565,0.062372},
+  {-0.387799,0.117200},
+  {-0.078818,0.039897},
+  {-0.951657,-0.147061},
+  {0.531560,-0.532658},
+  {-0.922460,0.370301},
+  {-0.800399,0.384196},
+  {0.207158,1.049643},
+  {-0.855953,0.709615},
+  {0.833019,0.272167},
+  {0.272961,0.796026},
+  {0.862792,0.320292},
+  {-2.027771,-0.518041},
+  {0.382846,-0.137945},
+  {-0.116166,-0.315429},
+  {-0.168185,-0.144519},
+  {0.531779,0.133622},
+  {-0.516350,-0.152330},
+  {-0.127356,-1.375547},
+  {-0.105342,0.100885},
+  {0.525022,-0.939381},
+  {-0.066998,0.440557},
+  {-0.397364,0.443860},
+  {0.503200,0.746156},
+  {-0.431620,0.075595},
+  {-0.841891,0.743002},
+  {1.371081,-0.365098},
+  {-0.010784,-0.465652},
+  {0.020112,-0.041097},
+  {0.826739,0.182882},
+  {-0.613873,0.704830},
+  {-0.568370,0.143343},
+  {0.387460,-0.545298},
+  {0.021157,-0.747607},
+  {1.302628,0.905500},
+  {0.261942,-0.033071},
+  {0.376649,0.470807},
+  {-0.612337,-0.531302},
+  {0.841322,0.076988},
+  {-0.153153,0.320945},
+  {-0.874257,-0.702040},
+  {0.165278,-1.657980},
+  {-0.147901,-1.012033},
+  {-1.277508,0.406026},
+  {0.962158,-0.812888},
+  {0.570132,-0.249752},
+  {0.178017,0.240519},
+  {0.221700,-1.244702},
+  {-1.203450,0.112039},
+  {0.203837,-0.704907},
+  {0.134167,-0.222161},
+  {-0.462939,-1.592425},
+  {-0.032346,0.235999},
+  {0.386704,-0.786325},
+  {-0.693315,0.928200},
+  {-2.135864,0.434740},
+  {1.006662,1.715587},
+  {-0.142810,-0.802204},
+  {0.458850,0.565148},
+  {-0.338997,1.517529},
+  {-0.803918,0.696678},
+  {-0.048029,0.081896},
+  {0.172872,-1.381249},
+  {-0.463157,0.151494},
+  {0.014982,-0.330029},
+  {0.131682,0.900381},
+  {1.245995,-0.694195},
+  {0.723281,0.823227},
+  {-1.268782,0.935669},
+  {-0.323588,0.329887},
+  {-0.826465,0.789808},
+  {0.969452,0.147947},
+  {-0.086800,-0.739140},
+  {0.330504,-0.580053},
+  {0.613212,-0.291821},
+  {1.508769,0.762460},
+  {0.427432,-0.078387},
+  {0.241827,-0.720148},
+  {0.103200,0.692154},
+  {0.237121,-0.186097},
+  {0.383141,0.836269},
+  {-1.686991,-0.116805},
+  {0.357785,0.936704},
+  {0.009202,-0.259852},
+  {-0.364276,0.361380},
+  {-0.452860,1.136152},
+  {-0.503536,0.666926},
+  {1.115614,0.371158},
+  {-0.140742,0.824371},
+  {-0.082390,-0.656057},
+  {-1.230565,0.359913},
+  {0.005553,-0.198844},
+  {1.238036,-0.548324},
+  {-0.707677,-0.575827},
+  {0.561192,-0.372388},
+  {0.495972,1.965641},
+  {0.693577,-0.278012},
+  {-0.501385,0.209282},
+  {1.174469,-1.508376},
+  {0.645479,-1.112553},
+  {0.216551,1.222801},
+  {0.317056,-0.152965},
+  {0.192083,0.034963},
+  {-0.110488,-0.462419},
+  {-0.666300,-0.015961},
+  {-1.752495,0.399985},
+  {-0.469240,0.924181},
+  {-0.274931,0.641528},
+  {-0.312214,-0.016273},
+  {-0.517574,-0.530389},
+  {0.833532,0.046255},
+  {0.684154,-0.745428},
+  {-0.955607,0.071248},
+  {-0.251567,0.985285},
+  {-0.121152,-0.148834},
+  {-0.009011,0.787854},
+  {-0.649552,0.048180},
+  {-0.425329,0.878791},
+  {0.393766,0.793184},
+  {0.526353,-1.044814},
+  {-0.425715,0.097562},
+  {0.345638,-0.549481},
+  {0.697957,-0.674357},
+  {0.905744,0.301798},
+  {0.974970,0.602490},
+  {-0.901499,-0.882178},
+  {-0.019264,-0.630321},
+  {-0.421427,0.049030},
+  {-0.217801,-1.297212},
+  {0.182897,-0.126145},
+  {0.128832,-1.435972},
+  {-0.107732,-0.836753},
+  {-0.777310,0.461033},
+  {0.206962,-0.196436},
+  {1.346730,-0.307975},
+  {0.401943,0.332010},
+  {0.044175,0.580896},
+  {0.186951,0.580326},
+  {0.198179,0.439384},
+  {-0.265917,0.422116},
+  {0.364858,1.826492},
+  {0.891892,-0.698183},
+  {1.583665,-1.221355},
+  {-0.190341,0.962946},
+  {-0.174967,-0.009207},
+  {0.729038,-0.307764},
+  {0.043398,-1.428511},
+  {-0.680441,0.960596},
+  {0.250274,0.295808},
+  {0.032164,-0.418385},
+  {-0.197256,-0.704446},
+  {-1.712183,-1.163529},
+  {-0.268695,-0.200849},
+  {2.306987,2.318621},
+  {0.060264,0.224934},
+  {0.578235,0.321018},
+  {0.028329,-0.398577},
+  {-0.468995,0.372626},
+  {-0.486544,1.004021},
+  {-1.324421,-0.240098},
+  {-0.516670,0.486116},
+  {1.493896,-0.392662},
+  {0.129571,-0.570646},
+  {0.163091,-0.300952},
+  {-0.249986,0.337349},
+  {-0.795421,-0.775087},
+  {-1.050828,-0.478171},
+  {-0.687893,-1.095394},
+  {0.446193,-0.334549},
+  {0.207191,1.248893},
+  {1.304610,0.004308},
+  {-0.531389,-0.521206},
+  {0.856143,-0.371803},
+  {-0.436616,1.111738},
+  {-1.420017,-0.184266},
+  {1.140460,-1.630379},
+  {0.161864,0.404858},
+  {-0.253171,-0.606452},
+  {-1.208974,1.509948},
+  {-0.954164,-1.303938},
+  {-0.048128,0.715313},
+  {0.256096,-0.413618},
+  {0.282291,1.407356},
+  {0.056407,0.582285},
+  {0.394826,0.319440},
+  {-0.481465,-1.111214},
+  {0.591739,0.508274},
+  {0.032651,0.767816},
+  {-0.134227,0.328188},
+  {0.092560,-0.469654},
+  {0.797004,-0.160862},
+  {0.769209,1.001893},
+  {0.898712,0.476407},
+  {-0.606030,0.660273},
+  {0.035930,-0.406220},
+  {0.549958,0.477784},
+  {0.930700,0.739616},
+  {-0.352887,0.120378},
+  {1.456712,-0.987803},
+  {-2.326077,-0.576206},
+  {0.005039,-0.663576},
+  {0.271949,0.400765},
+  {1.016654,-0.532382},
+  {0.578166,0.345697},
+  {1.335427,-0.691842},
+  {0.346829,-1.486777},
+  {-1.153416,-1.026001},
+  {0.223860,0.210608},
+  {-0.190999,-0.519098},
+  {-0.198968,0.263295},
+  {0.651483,0.398883},
+  {-0.549925,-0.275894},
+  {-1.229674,-0.017529},
+  {-1.383489,0.757820},
+  {-0.253172,0.217579},
+  {-0.816223,-0.232510},
+  {0.104862,0.528907},
+  {0.079655,0.495187},
+  {-1.060489,0.302825},
+  {-0.137642,0.212762},
+  {0.674357,0.008222},
+  {-0.048395,0.926425},
+  {0.412030,-0.840911},
+  {0.237129,0.647045},
+  {0.339638,-0.335510},
+  {0.284322,1.034499},
+  {-1.397022,-0.292628},
+  {-0.146085,0.519480},
+  {-0.041487,-0.555443},
+  {0.577501,-0.304147},
+  {0.311928,-0.446547},
+  {0.635509,-0.519239},
+  {-1.033277,-1.288549},
+  {0.731980,0.033399},
+  {-1.854763,-0.310873},
+  {-0.244777,0.164482},
+  {0.177305,-1.028995},
+  {-0.848186,-1.102416},
+  {0.208618,0.238623},
+  {0.141655,-0.253353},
+  {0.171815,0.430131},
+  {-0.300252,0.385949},
+  {-0.002417,0.000851},
+  {0.140724,0.631155},
+  {-0.361690,-0.341663},
+  {0.452532,1.566797},
+  {-0.983234,-0.383707},
+  {-0.919083,-0.153251},
+  {-0.570362,-0.004002},
+  {0.012526,0.451240},
+  {1.078805,0.115248},
+  {-0.303834,-0.334887},
+  {0.111197,-0.445325},
+  {0.190372,0.714853},
+  {0.826630,-0.758796},
+  {-0.855694,-0.601218},
+  {-0.240251,0.838381},
+  {0.169116,0.269469},
+  {-0.758837,-0.535851},
+  {0.833886,0.712264},
+  {-1.228975,-1.041728},
+  {-0.454220,1.116119},
+  {1.266360,0.991548},
+  {0.399368,0.572129},
+  {0.284363,0.183403},
+  {0.852430,-0.069496},
+  {-0.634331,0.143028},
+  {0.704158,-0.787308},
+  {-0.348563,-0.322614},
+  {-0.926186,0.376325},
+  {0.743159,0.167845},
+  {2.017916,1.018183},
+  {0.808439,-0.898639},
+  {-0.362709,-0.359190},
+  {-0.263045,-1.681332},
+  {-0.155017,-0.596109},
+  {-0.058238,-0.339211},
+  {-1.052586,-0.827454},
+  {0.083530,-0.579545},
+  {0.798530,0.075240},
+  {-0.671206,-0.110130},
+  {-0.032062,-0.960990},
+  {0.473355,0.406486},
+  {0.724043,0.644396},
+  {-0.324565,0.679171},
+  {-0.260678,0.183511},
+  {-0.340520,-0.690654},
+  {-0.490994,-1.070487},
+  {-0.102180,-0.653080},
+  {1.588020,1.305983},
+  {-0.284747,0.210628},
+  {-0.084555,0.093298},
+  {-0.200014,0.790467},
+  {-0.717793,0.363149},
+  {0.131695,-0.446003},
+  {0.914407,0.814170},
+  {-0.202136,-0.003753},
+  {1.277709,0.898150},
+  {0.656615,-0.393242},
+  {-0.156783,0.685943},
+  {-0.206718,0.503998},
+  {0.201327,0.404118},
+  {0.042250,-0.107335},
+  {-0.870850,0.210164},
+  {0.381354,0.642557},
+  {-0.595277,0.854957},
+  {0.322635,0.139045},
+  {1.736598,0.188796},
+  {0.862338,-0.908735},
+  {0.952138,-1.054378},
+  {0.771591,0.755734},
+  {0.080442,-0.425273},
+  {0.711784,0.796568},
+  {0.221518,0.711452},
+  {-0.754410,0.214646},
+  {0.297972,-0.998691},
+  {-0.023798,-0.667344},
+  {-0.064961,-0.853014},
+  {0.082753,0.438751},
+  {-0.829817,-0.535958},
+  {0.179596,0.170377},
+  {-0.232841,0.874216},
+  {1.184970,0.506020},
+  {0.638693,-1.085547},
+  {0.618905,0.086848},
+  {0.091035,-1.093523},
+  {1.586531,-0.145763},
+  {0.781375,-0.734368},
+  {-0.439204,-0.368124},
+  {0.884153,-0.881938},
+  {0.443501,0.046392},
+  {-0.000463,-2.010197},
+  {-1.341146,0.413517},
+  {-0.115972,-0.617283},
+  {0.576521,-0.591029},
+  {0.262853,0.282668},
+  {0.454027,-0.299344},
+  {0.561599,-1.411193},
+  {0.847940,-0.386760},
+  {0.162330,-1.607905},
+  {0.019188,0.449590},
+  {0.667390,0.097850},
+  {1.070732,-0.511950},
+  {0.837035,0.531196},
+  {0.366102,-0.046720},
+  {-0.715692,0.543561},
+  {-0.021125,-0.195383},
+  {0.548797,-1.182353},
+  {1.307617,-0.209852},
+  {0.563610,0.627996},
+  {0.085233,0.093108},
+  {-0.445645,1.093604},
+  {-0.920394,1.114292},
+  {-0.394214,0.442132},
+  {-0.175037,0.756531},
+  {-1.486353,0.249107},
+  {0.036325,-1.007293},
+  {-0.348203,0.752406},
+  {-0.502838,0.733700},
+  {-0.386542,-0.143784},
+  {-0.289604,1.540041},
+  {-0.112224,0.139364},
+  {-0.060213,-0.734811},
+  {0.401407,1.469775},
+  {0.455272,0.162539},
+  {-0.151403,0.737257},
+  {0.767557,-0.397638},
+  {-0.392108,-0.373642},
+  {0.602157,-0.607477},
+  {-0.745662,-0.034958},
+  {-1.102743,0.087956},
+  {-1.559189,0.464934},
+  {-1.466796,0.183389},
+  {-1.075429,-0.243765},
+  {-0.902469,-0.918449},
+  {0.135849,0.153793},
+  {-0.867781,-0.363082},
+  {1.109122,0.450055},
+  {-0.862578,0.592056},
+  {-0.417136,0.030326},
+  {1.119029,0.172928},
+  {-0.460388,1.450624},
+  {-0.383553,-0.286544},
+  {0.769042,0.259261},
+  {-0.624490,1.200131},
+  {-1.122671,-0.736922},
+  {-1.806449,0.235413},
+  {-0.034734,-1.440604},
+  {0.183904,-0.178401},
+  {0.345460,-0.134209},
+  {-0.048553,-0.107624},
+  {-1.055511,-0.230159},
+  {-0.770478,1.603207},
+  {0.225398,1.413173},
+  {-0.771651,-0.881477},
+  {0.297900,-0.163596},
+  {-0.747235,0.837724},
+  {1.266946,-0.261761},
+  {0.714842,-0.900438},
+  {0.566732,-0.227364},
+  {-0.266881,-0.036107},
+  {-0.791542,0.149132},
+  {-1.792347,-0.319528},
+  {-0.653766,0.011991},
+  {1.200644,0.555262},
+  {0.282989,-0.753802},
+  {0.528717,0.482407},
+  {-0.546723,-0.455929},
+  {0.266867,0.694730},
+  {0.516831,0.923688},
+  {0.182959,-1.056826},
+  {-1.486910,-0.208888},
+  {1.201567,0.192398},
+  {-1.757454,-0.151676},
+  {1.324179,-0.469352},
+  {0.040209,0.160468},
+  {0.654096,-0.624048},
+  {0.357661,0.980737},
+  {0.058591,-0.693167},
+  {-0.122160,-1.377046},
+  {0.281492,0.331693},
+  {-0.082028,0.294920},
+  {1.769671,0.812195},
+  {0.098679,0.119134},
+  {-1.443098,-1.187373},
+  {-0.280626,-0.135435},
+  {0.589831,0.260585},
+  {-0.540208,-0.744497},
+  {0.140753,0.497638},
+  {-1.508149,-0.600368},
+  {-0.545563,1.017052},
+  {0.626888,-0.915797},
+  {-0.053717,-0.598712},
+  {-0.550529,0.572603},
+  {0.159770,1.587399},
+  {-1.196120,0.802992},
+  {-0.515035,0.547389},
+  {-0.008116,0.409647},
+  {-1.058518,0.054808},
+  {-0.042508,-0.559489},
+  {0.011590,0.322688},
+  {1.052709,0.384123},
+  {0.425621,-0.744465},
+  {-1.279637,1.410061},
+  {0.107505,-1.717265},
+  {-0.850488,-0.542529},
+  {-0.969962,0.197049},
+  {0.045225,-1.201257},
+  {-0.701234,0.348909},
+  {0.254005,-0.689191},
+  {0.696662,0.251047},
+  {1.158640,-0.473769},
+  {-0.674666,0.000070},
+  {-1.079858,-0.744986},
+  {-0.956900,-0.604828},
+  {0.336681,0.096805},
+  {0.749376,0.408288},
+  {-0.341699,-0.132789},
+  {-0.566410,-0.063452},
+  {-0.307095,0.690775},
+  {1.362382,-0.954373},
+  {0.027733,0.171340},
+  {-0.043149,-0.889067},
+  {-0.759746,-0.387685},
+  {-0.014074,0.110098},
+  {1.941074,1.179552},
+  {-0.316348,1.024601},
+  {0.686783,-0.662860},
+  {-0.480265,-0.318199},
+  {-0.301052,0.547353},
+  {-0.658741,0.133439},
+  {0.219759,0.560583},
+  {-0.128545,-0.937591},
+  {0.937029,0.858481},
+  {0.636270,-0.195326},
+  {-0.333245,-0.881758},
+  {0.799974,0.622142},
+  {-0.008765,-0.681762},
+  {-0.344503,-0.152322},
+  {-0.269002,-0.978158},
+  {-1.401038,0.473890},
+  {-0.254753,-0.199118},
+  {0.501615,-0.004429},
+  {0.223899,0.481336},
+  {-0.846760,0.430996},
+  {-0.061397,-1.110077},
+  {-1.262684,-0.975124},
+  {-0.255968,0.443139},
+  {0.165242,2.157322},
+  {0.171348,-0.113452},
+  {0.784235,0.826362},
+  {-0.930326,-0.142924},
+  {-1.016804,-1.041038},
+  {0.053696,0.188937},
+  {-1.831388,-0.308341},
+  {0.956302,-0.422604},
+  {-0.814804,-1.598612},
+  {0.125995,-0.841216},
+  {1.222502,-0.172663},
+  {-0.066590,0.294008},
+  {1.467924,0.078648},
+  {-0.594113,0.074105},
+  {0.454844,0.418237},
+  {-0.355792,-1.712601},
+  {0.280973,0.482542},
+  {-1.677893,-0.708101},
+  {-0.143138,-0.222046},
+  {0.185764,-0.182096},
+  {-1.591763,0.811301},
+  {-0.872062,0.528511},
+  {0.531152,0.105743},
+  {-0.405518,-0.243221},
+  {-0.285285,-0.724835},
+  {1.211926,-0.938313},
+  {-0.311116,0.708844},
+  {0.452738,0.246767},
+  {-0.734349,-0.015975},
+  {0.504125,-0.297089},
+  {-0.550223,-0.407948},
+  {1.386104,-1.647487},
+  {-0.532341,-0.778504},
+  {-1.609207,-0.322142},
+  {0.151805,0.083478},
+  {0.045700,0.360312},
+  {-0.209418,0.028573},
+  {-0.028010,-0.531229},
+  {-0.297919,-0.606391},
+  {-0.227399,-0.036008},
+  {-1.071328,0.802874},
+  {1.611743,-0.469932},
+  {-0.639568,1.269852},
+  {1.007945,0.734555},
+  {0.278845,1.802139},
+  {-0.074947,1.028369},
+  {0.512044,-1.046021},
+  {0.400092,0.083723},
+  {-0.560397,-0.243498},
+  {0.036739,0.207770},
+  {0.571326,0.324339},
+  {0.186415,-0.351682},
+  {-0.457269,0.176103},
+  {0.021670,-0.065631},
+  {0.511796,-0.018099},
+  {1.735932,-1.412607},
+  {-0.650731,-1.358326},
+  {0.575977,0.636595},
+  {0.654576,-0.152643},
+  {-0.490564,0.772623},
+  {-0.524959,-0.161241},
+  {-0.658197,-0.312236},
+  {0.163393,-0.340469},
+  {0.656293,0.638867},
+  {0.501754,-0.811553},
+  {0.440917,0.449741},
+  {1.556753,0.811315},
+  {0.841730,-0.772732},
+  {0.660040,-0.888669},
+  {-0.782535,-0.242943},
+  {1.033138,-1.092518},
+  {-0.069224,0.487574},
+  {0.387082,-0.053341},
+  {-0.254564,-0.830744},
+  {-0.007638,-0.247230},
+  {-0.661025,0.930161},
+  {0.606968,-0.680955},
+  {-0.137605,0.289561},
+  {0.863396,0.128169},
+  {-0.349560,-0.836361},
+  {-1.438246,-1.537779},
+  {-0.460247,-1.009597},
+  {0.728357,-0.362308},
+  {-0.050639,-0.243558},
+  {-0.679497,0.781298},
+  {0.658934,0.412632},
+  {0.670115,0.267368},
+  {0.123810,-0.916516},
+  {0.868722,-1.620722},
+  {-0.145830,0.480333},
+  {-1.145276,-0.014976},
+  {-0.108175,-1.215163},
+  {-0.449991,-0.695477},
+  {0.354733,0.823464},
+  {-0.039724,-0.098980},
+  {0.013556,0.499284},
+  {-1.312451,-0.054851},
+  {-0.830864,0.524224},
+  {0.486311,-0.717254},
+  {0.643189,-0.177630},
+  {0.273871,0.698640},
+  {0.853247,-0.305921},
+  {-1.129702,0.190997},
+  {0.373702,-1.523299},
+  {-0.301040,0.189571},
+  {-0.224603,0.155915},
+  {0.831177,-0.779143},
+  {1.389989,-0.223985},
+  {-0.321807,-0.258173},
+  {-0.366492,-0.422011},
+  {-0.384236,0.224358},
+  {-1.063747,-0.704562},
+  {-0.555400,0.187686},
+  {0.271893,0.617246},
+  {-0.610279,-0.700190},
+  {-0.551170,0.213321},
+  {1.648215,0.778172},
+  {-0.025453,-0.830363},
+  {-0.219132,-0.100106},
+  {-1.131840,0.570620},
+  {0.351216,0.049910},
+  {-0.316256,-0.207403},
+  {-0.050467,1.734194},
+  {-0.654866,0.299421},
+  {0.150861,-0.684421},
+  {-0.561852,0.297147},
+  {-0.126410,0.789246},
+  {-0.127865,-0.749320},
+  {0.162245,1.241481},
+  {1.336352,-0.647051},
+  {-0.605969,0.480636},
+  {-1.072146,0.585871},
+  {0.768267,0.008915},
+  {-0.399790,0.263734},
+  {-1.004410,0.473403},
+  {0.145836,0.570952},
+  {0.647171,0.532919},
+  {1.021832,-0.194468},
+  {-0.166667,0.643500},
+  {-0.062712,0.359724},
+  {0.260920,1.286259},
+  {0.702274,-0.475356},
+  {-0.995690,-0.674690},
+  {1.214113,0.161147},
+  {-0.054271,-0.030268},
+  {0.135363,0.245079},
+  {-0.193862,-0.856533},
+  {-0.446497,0.195088},
+  {0.909234,0.465749},
+  {0.027739,-0.240682},
+  {0.202885,-0.391204},
+  {-0.915654,-1.517288},
+  {0.032038,0.801794},
+  {-0.565640,-1.125811},
+  {-0.746958,0.080219},
+  {1.012414,-0.176261},
+  {0.925715,0.171622},
+  {0.504816,0.886424},
+  {-0.055414,-1.707216},
+  {0.331249,1.448197},
+  {0.325529,-0.748697},
+  {0.006156,-0.885744},
+  {0.843520,-0.760984},
+  {1.008421,-0.221801},
+  {-0.978591,1.867998},
+  {0.351767,1.119610},
+  {-0.152918,1.039013},
+  {-0.595093,0.442284},
+  {0.844670,-0.308379},
+  {0.716920,-0.336382},
+  {0.461792,-0.273735},
+  {0.097085,-0.336706},
+  {-0.119997,0.705377},
+  {0.216905,-0.214695},
+  {-0.163907,0.691365},
+  {0.046850,-0.395489},
+  {-0.622611,-0.633670},
+  {0.073035,-0.563313},
+  {-1.652085,-0.637483},
+  {0.004529,-0.510007},
+  {-0.756162,-0.373366},
+  {0.224175,0.104698},
+  {0.240622,0.087521},
+  {0.051187,0.920317},
+  {1.667764,0.411180},
+  {-0.117246,-0.234740},
+  {-0.082710,-0.477874},
+  {0.040677,-0.399180},
+  {-0.950192,0.484832},
+  {0.746072,-0.140056},
+  {-1.349141,0.607029},
+  {0.548435,-0.191376},
+  {0.190776,-1.480638},
+  {0.719537,1.345205},
+  {1.446202,-0.580025},
+  {0.053474,0.978262},
+  {0.786674,0.753003},
+  {-0.996297,0.640894},
+  {1.383403,0.136313},
+  {0.608127,0.754792},
+  {-0.827608,-0.016325},
+  {-0.924064,-0.682900},
+  {-1.054567,-0.001422},
+  {1.185203,1.589105},
+  {0.496944,0.349206},
+  {-0.169828,-0.384878},
+  {-0.285749,0.247343},
+  {-0.719044,-1.465544},
+  {0.064705,-0.715851},
+  {-0.313329,1.540674},
+  {-0.565377,-0.220547},
+  {-0.959113,-0.696998},
+  {-0.265068,0.828256},
+  {-0.231885,-0.521362},
+  {0.084903,-0.990582},
+  {0.419140,-0.095240},
+  {0.278788,-0.044144},
+  {0.586966,0.431494},
+  {1.209696,0.763105},
+  {-1.666831,-0.629313},
+  {-0.497822,0.832480},
+  {-0.142951,-0.554920},
+  {-0.275496,-1.050326},
+  {-0.478618,-0.636370},
+  {0.782930,0.504903},
+  {-0.082104,-1.564349},
+  {-0.211217,0.853166},
+  {1.084067,0.782337},
+  {-0.055275,0.277204},
+  {0.880825,-0.475584},
+  {-0.949252,0.084678},
+  {-0.211708,0.245726},
+  {1.704036,0.424302},
+  {0.077734,-0.365634},
+  {0.216536,0.821771},
+  {0.375309,-0.657953},
+  {-0.659413,-0.187937},
+  {-0.499583,-0.274513},
+  {1.229467,-0.033242},
+  {-0.267309,0.993163},
+  {0.865415,0.210650},
+  {-0.823692,-0.069652},
+  {-0.540393,-0.407260},
+  {-0.708647,-0.380446},
+  {-0.456284,-0.443381},
+  {-1.262311,-0.764377},
+  {-0.321781,0.630733},
+  {-0.588639,-0.187851},
+  {-0.568256,0.499750},
+  {0.373187,0.006208},
+  {0.707336,0.348158},
+  {1.672811,-0.006168},
+  {-0.123496,0.243460},
+  {-0.436994,0.521309},
+  {0.221835,0.213596},
+  {-0.110805,0.604376},
+  {-0.453414,-0.656775},
+  {-0.342502,-0.092188},
+  {0.282574,1.154633},
+  {-0.805164,0.800347},
+  {0.792364,0.263727},
+  {-0.117166,-0.150103},
+  {-0.284043,1.115365},
+  {0.454632,-1.305995},
+  {-0.027046,-0.148701},
+  {0.158758,-1.399725},
+  {-0.035824,1.192414},
+  {-0.761856,0.094855},
+  {-0.008090,0.994581},
+  {-0.259027,-0.931982},
+  {-0.978369,-0.050289},
+  {0.339204,-0.785655},
+  {-0.301449,0.823972},
+  {0.745963,0.972562},
+  {1.820135,0.926824},
+  {-0.182639,0.155852},
+  {-0.307134,0.062589},
+  {-0.356943,1.592747},
+  {-0.810041,-0.170031},
+  {0.924231,-0.092920},
+  {-0.511708,-0.739995},
+  {0.217789,0.214683},
+  {0.727853,0.509274},
+  {0.540418,0.119559},
+  {1.247327,0.541364},
+  {0.750281,0.697049},
+  {0.211089,0.231808},
+  {0.542634,0.268686},
+  {0.250232,0.727131},
+  {-1.260513,0.624552},
+  {0.606138,-0.194470},
+  {0.114722,0.116973},
+  {-0.552551,-0.850632},
+  {-0.586970,-0.054372},
+  {0.199770,-0.540281},
+  {-1.122043,-0.794103},
+  {1.090813,0.071042},
+  {-0.304107,0.113772},
+  {0.555280,0.023257},
+  {0.066496,-1.087529},
+  {0.735559,1.299498},
+  {-0.523713,-0.325003},
+  {0.558212,-1.053250},
+  {-0.542305,-0.417328},
+  {0.228459,-0.174137},
+  {0.882993,1.180572},
+  {-0.210242,0.141900},
+  {0.530180,-0.288710},
+  {-0.867478,-0.490810},
+  {0.680940,0.052579},
+  {-0.190379,-0.716328},
+  {2.098467,0.446381},
+  {-0.802407,0.021896},
+  {-0.050531,0.152073},
+  {-0.548937,-0.769984},
+  {1.160574,1.151177},
+  {-0.844446,-1.831308},
+  {0.469147,0.201575},
+  {0.915001,0.416576},
+  {0.447789,-1.554800},
+  {0.498533,-0.152030},
+  {0.333739,0.365833},
+  {0.523884,0.261510},
+  {0.102519,-2.132332},
+  {1.322340,0.237185},
+  {-0.666061,0.182718},
+  {-0.547886,0.110171},
+  {-0.885832,-0.119981},
+  {-0.220295,0.279038},
+  {0.672774,-0.493978},
+  {0.201961,0.278770},
+  {-0.698567,1.015529},
+  {-0.547559,0.238427},
+  {-0.900760,-0.019301},
+  {0.850664,0.808783},
+  {-0.435736,0.345590},
+  {-0.166500,0.514461},
+  {-0.734562,-1.054797},
+  {-0.480065,0.153198},
+  {1.169755,0.209574},
+  {1.069664,0.606532},
+  {-0.708567,-0.040850},
+  {0.652199,-0.079326},
+  {-0.719968,0.322006},
+  {-0.514982,0.234570},
+  {-1.101919,-0.339730},
+  {0.150537,0.654555},
+  {-0.736618,-0.262166},
+  {-0.856246,-0.452481},
+  {1.287460,-0.187745},
+  {-0.217413,-0.915828},
+  {0.609253,-0.743804},
+  {-1.171250,-0.922717},
+  {0.150368,0.415436},
+  {1.201096,-0.573735},
+  {-0.115596,0.661219},
+  {1.042194,-0.088547},
+  {0.005057,-0.396937},
+  {-1.158327,-0.358233},
+  {0.623459,-0.169205},
+  {0.388201,0.751152},
+  {0.895239,0.665853},
+  {0.354939,0.105708},
+  {-0.587396,-1.923318},
+  {-0.061833,0.531589},
+  {0.604179,-0.251531},
+  {0.494426,0.338236},
+  {-0.271009,-0.331057},
+  {-0.256580,0.492214},
+  {-0.088714,-0.383933},
+  {1.123027,0.719944},
+  {0.375988,0.313174},
+  {0.236084,0.230468},
+  {0.003886,-0.712924},
+  {0.104498,1.606752},
+  {-0.532576,0.330591},
+  {-0.488381,-1.352006},
+  {0.161545,1.723053},
+  {-0.710498,-0.276665},
+  {-0.986647,0.482909},
+  {1.434283,0.726346},
+  {0.068419,1.131931},
+  {0.442032,-0.394590},
+  {-0.239756,0.143242},
+  {1.643873,-0.058546},
+  {-1.003878,-0.192841},
+  {0.122247,-0.079203},
+  {-0.252594,-1.356311},
+  {-0.869489,-0.064070},
+  {-1.961857,-0.185462},
+  {-1.899979,0.496400},
+  {-0.109843,0.709934},
+  {0.827485,-0.498313},
+  {0.209843,1.037273},
+  {-1.581375,-1.119497},
+  {0.290475,1.032399},
+  {0.668792,0.476572},
+  {-0.433339,-0.944385},
+  {0.323084,0.537194},
+  {-0.221663,0.003856},
+  {1.383254,-0.497884},
+  {-1.198460,-0.892147},
+  {-0.750552,0.230349},
+  {-0.637159,0.240327},
+  {1.023382,1.174099},
+  {0.449877,1.718353},
+  {0.110701,-1.119723},
+  {0.188672,-0.085627},
+  {-0.767622,0.429697},
+  {0.022888,-0.290090},
+  {0.029017,-0.575055},
+  {0.569277,-0.179878},
+  {-1.100726,0.865245},
+  {-0.544482,0.275123},
+  {-0.336701,-0.933121},
+  {0.051869,0.544727},
+  {0.845421,-0.138977},
+  {-0.855811,0.654785},
+  {0.146789,-1.087976},
+  {-0.213152,0.076521},
+  {1.014701,0.369228},
+  {0.303512,-0.346069},
+  {0.019167,0.409554},
+  {0.812617,-0.834358},
+  {1.338190,-0.103966},
+  {0.776275,0.019837},
+  {-0.804914,-0.226097},
+  {-1.210668,-1.599920},
+  {-0.354872,1.508185},
+  {-0.577729,-0.030264},
+  {1.140923,-0.684538},
+  {-1.087623,0.646425},
+  {-1.213811,1.245787},
+  {-0.747429,0.088243},
+  {-1.028906,1.421081},
+  {0.269063,0.871054},
+  {-1.154534,0.036896},
+  {0.616763,0.386360},
+  {-0.112931,-0.217046},
+  {0.465623,-0.396933},
+  {0.167084,-1.587480},
+  {1.067098,1.142031},
+  {-0.726521,0.527343},
+  {0.521179,0.754796},
+  {1.965600,-0.951334},
+  {-0.493864,0.148753},
+  {-0.789453,-0.495132},
+  {1.154057,0.025690},
+  {0.226936,0.017755},
+  {-0.397219,0.138528},
+  {0.825606,-0.364112},
+  {-0.550409,0.454887},
+  {0.168085,-0.192830},
+  {1.037240,0.172213},
+  {-0.623615,-1.192414},
+  {-1.394999,0.433780},
+  {-0.517121,0.276487},
+  {-0.717265,-1.106185},
+  {1.173780,0.500190},
+  {1.189896,0.347666},
+  {-0.367490,0.332201},
+  {1.428207,0.822697},
+  {0.450744,1.052459},
+  {-0.703437,0.894070},
+  {0.915143,0.151831},
+  {-0.076742,0.733596},
+  {0.524063,-0.923572},
+  {0.182666,-1.514815},
+  {-0.096585,-0.475288},
+  {0.933516,0.325996},
+  {0.262816,-1.152226},
+  {-1.298289,1.056797},
+  {0.290436,0.293651},
+  {-0.796841,0.007490},
+  {-0.001210,-0.482373},
+  {-0.372255,-0.003545},
+  {-0.951811,0.424592},
+  {0.428500,-0.154131},
+  {-0.016110,0.104156},
+  {0.714483,-0.096403},
+  {-0.497021,0.177252},
+  {0.119749,-1.519028},
+  {1.655545,-1.336578},
+  {0.765918,-0.329551},
+  {1.142739,1.110006},
+  {0.715838,0.057273},
+  {0.978170,0.262785},
+  {0.989103,0.268928},
+  {-0.844677,0.128637},
+  {-0.709728,-0.957801},
+  {1.655370,0.576793},
+  {-0.701566,-0.455455},
+  {1.472421,0.138446},
+  {-0.068813,0.104376},
+  {-0.307454,0.024655},
+  {-1.584193,0.460054},
+  {-0.636200,0.303211},
+  {-0.547006,-0.100346},
+  {0.033197,-0.233433},
+  {0.036871,-1.428877},
+  {-1.282191,-0.020832},
+  {-0.226060,0.575992},
+  {0.539645,0.580925},
+  {-0.515746,0.640159},
+  {0.122624,0.379262},
+  {-0.298237,-0.430135},
+  {0.582305,0.104006},
+  {0.761337,0.778517},
+  {-0.116138,-0.079724},
+  {0.056869,0.497983},
+  {0.534546,-0.781835},
+  {1.373099,0.424074},
+  {-0.326885,-0.553422},
+  {0.466659,0.459637},
+  {0.057961,0.638324},
+  {1.220616,0.000019},
+  {-0.396984,1.437168},
+  {0.217722,0.458254},
+  {0.517229,-0.226219},
+  {0.266293,0.723080},
+  {0.316267,-0.496743},
+  {0.395212,0.100780},
+  {0.208948,-0.868054},
+  {0.494479,0.422566},
+  {0.090251,0.077638},
+  {-0.006175,-0.650019},
+  {-0.244839,-0.682264},
+  {-0.168110,0.761099},
+  {-0.705272,0.959809},
+  {0.345444,-0.191354},
+  {-1.338302,-0.620916},
+  {-0.913269,-0.357629},
+  {-0.326929,-0.599831},
+  {-0.886159,-0.329607},
+  {-0.352269,-0.326190},
+  {0.517424,-0.679915},
+  {-0.256276,0.568007},
+  {-0.018477,0.625619},
+  {-1.188829,-0.540793},
+  {-0.063814,0.082350},
+  {-0.574465,-0.281673},
+  {-1.431945,-0.967747},
+  {-1.319540,-0.350255},
+  {0.385732,0.441168},
+  {0.648657,-0.187545},
+  {-0.413140,-0.199861},
+  {-0.860812,0.630549},
+  {-0.526107,-0.254688},
+  {1.561758,-0.918379},
+  {0.478789,-0.553762},
+  {0.577887,0.031411},
+  {-0.123129,-1.310582},
+  {0.467329,-0.373385},
+  {-0.158891,-0.519788},
+  {0.413279,-0.717616},
+  {-0.090683,0.008334},
+  {-0.201974,-0.766771},
+  {0.467733,-0.252969},
+  {1.537250,-0.785099},
+  {1.055945,1.034578},
+  {0.855592,-1.000192},
+  {0.049488,1.476671},
+  {0.485982,-1.096695},
+  {-0.417544,-0.230928},
+  {0.650111,-0.343016},
+  {-0.697971,-0.973262},
+  {0.665104,0.431052},
+  {0.312919,1.312641},
+  {0.441995,-0.145228},
+  {0.314576,0.658067},
+  {-0.499512,-0.180834},
+  {0.274381,-0.633668},
+  {-1.253873,0.337280},
+  {0.429498,-0.073320},
+  {-0.721886,-0.291230},
+  {2.130391,-0.609516},
+  {0.264504,-0.772070},
+  {0.197991,0.156987},
+  {0.012200,0.176025},
+  {0.511819,0.264211},
+  {0.846034,-0.534889},
+  {-0.019510,0.783356},
+  {0.369750,-0.658338},
+  {0.067036,-0.850373},
+  {-0.187688,0.650173},
+  {-0.550258,0.977643},
+  {0.310795,-0.493400},
+  {-1.002795,-0.323754},
+  {-0.687753,0.520814},
+  {-0.273234,-0.055023},
+  {1.420085,-0.258885},
+  {-1.197577,0.045913},
+  {0.069913,-0.134013},
+  {-0.662290,-0.003455},
+  {-0.451015,-0.580987},
+  {1.162251,-0.128787},
+  {-0.397880,-0.417766},
+  {0.970358,0.047251},
+  {-0.999546,-0.615866},
+  {-0.667909,0.655248},
+  {0.171279,-1.041255},
+  {0.490597,-0.745594},
+  {-0.163106,-0.467833},
+  {0.685498,-0.884569},
+  {0.021264,-0.159166},
+  {-0.284385,0.390590},
+  {-0.406411,0.147308},
+  {-0.887529,-0.424785},
+  {0.800653,0.320601},
+  {-0.237328,0.229176},
+  {-0.356110,-0.871456},
+  {-0.469616,-0.563785},
+  {0.540253,0.000454},
+  {0.766091,-0.692660},
+  {1.265823,-1.121352},
+  {-0.519969,-0.763516},
+  {-0.908685,1.223205},
+  {0.378901,-0.148434},
+  {0.734892,-0.017845},
+  {0.630235,0.605463},
+  {0.484549,0.798393},
+  {0.889189,-0.588511},
+  {-1.209300,-0.615938},
+  {0.745912,0.216205},
+  {-0.361015,0.030537},
+  {-0.140569,0.491194},
+  {0.206099,0.823077},
+  {1.382085,0.511459},
+  {0.822290,1.501179},
+  {0.580893,0.246972},
+  {-0.058519,-0.069856},
+  {-0.623353,-0.877999},
+  {0.911648,0.144101},
+  {0.264720,-1.072727},
+  {-0.788517,-0.665520},
+  {0.884159,-0.498943},
+  {-0.328181,-1.628856},
+  {-0.854272,-0.298947},
+  {0.369952,-0.228915},
+  {0.466766,-0.533842},
+  {-0.856672,0.555703},
+  {-1.666030,0.205364},
+  {-1.163374,0.020615},
+  {-0.460905,0.147512},
+  {-1.150163,-0.171924},
+  {-1.086664,1.156968},
+  {0.221459,0.371883},
+  {-0.140640,-0.413140},
+  {0.015694,-0.876451},
+  {0.084676,-0.170816},
+  {1.728853,-0.133309},
+  {0.505786,0.017453},
+  {0.738540,-1.225824},
+  {-0.732059,0.505571},
+  {0.586809,0.992493},
+  {-0.201427,0.147962},
+  {-0.669290,0.191411},
+  {-0.670438,0.813079},
+  {-0.396987,0.005979},
+  {-0.248870,0.602922},
+  {0.019785,-1.162706},
+  {0.258091,-0.507443},
+  {-0.293495,-0.206140},
+  {-1.416552,-0.047997},
+  {0.863624,-0.614726},
+  {0.618458,-0.667468},
+  {-0.068763,-0.452185},
+  {0.518270,0.013776},
+  {0.095323,0.282178},
+  {-0.501060,1.250301},
+  {0.495096,-0.240239},
+  {0.841004,0.186255},
+  {0.979204,-0.843511},
+  {0.159362,-0.525116},
+  {-1.076816,-0.329245},
+  {0.590261,0.475905},
+  {-0.042284,0.849452},
+  {-0.176301,0.436022},
+  {-0.007701,1.259334},
+  {-1.508466,-0.903273},
+  {1.741680,0.724148},
+  {-0.829550,0.878517},
+  {0.549818,0.385023},
+  {-0.586413,0.711769},
+  {-0.731277,0.072802},
+  {0.732751,-0.781661},
+  {1.453798,0.653282},
+  {-0.547525,0.163118},
+  {1.321736,0.284994},
+  {0.967075,0.447090},
+  {0.449005,-1.871133},
+  {0.049354,-0.499692},
+  {0.623433,1.594496},
+  {-0.006018,-0.366873},
+  {-0.476288,-0.645067},
+  {-0.185525,1.921269},
+  {0.691321,-1.097974},
+  {-1.417428,0.364298},
+  {0.995453,0.433032},
+  {0.645331,-0.069612},
+  {0.587566,-0.248929},
+  {-0.015891,0.435682},
+  {0.300868,0.560848},
+  {0.593525,0.847680},
+  {-1.032251,0.705217},
+  {-1.236513,-0.605437},
+  {0.480328,0.151749},
+  {-0.327914,-0.239973},
+  {0.645026,1.272340},
+  {1.041862,-0.097846},
+  {-0.444069,0.694695},
+  {0.748340,-0.242565},
+  {-0.392311,-0.564402},
+  {0.955277,-0.330417},
+  {0.766884,-1.099700},
+  {0.270925,-0.271814},
+  {0.991722,-1.258038},
+  {-1.300449,-0.021881},
+  {-0.648161,-0.316676},
+  {0.189458,0.566763},
+  {-1.087335,0.525761},
+  {-0.096931,0.439582},
+  {-0.004232,-0.614384},
+  {-1.011860,0.920394},
+  {-0.096274,-0.360917},
+  {0.126764,-0.317622},
+  {1.075920,-2.092266},
+  {-0.745683,0.670968},
+  {-0.427878,0.479526},
+  {1.421614,1.297357},
+  {-0.182187,0.907850},
+  {0.576038,-0.390017},
+  {-0.774510,0.092694},
+  {1.486913,0.472625},
+  {-0.985614,-0.039686},
+  {0.497321,0.513824},
+  {-0.226054,-0.465794},
+  {0.263041,-0.071887},
+  {0.284301,-0.781556},
+  {0.312159,-1.389565},
+  {-0.473675,1.103600},
+  {0.066062,-0.020374},
+  {0.153187,-0.821651},
+  {0.252598,-0.505776},
+  {-0.588915,-0.507526},
+  {0.746750,0.865902},
+  {-0.198729,0.371388},
+  {0.192385,-0.115625},
+  {-0.301964,1.093953},
+  {-0.372911,0.616029},
+  {-0.146635,-0.921548},
+  {0.449273,-0.739387},
+  {0.901099,0.774089},
+  {0.266051,0.377341},
+  {0.591555,0.563182},
+  {0.636632,-0.227791},
+  {1.160072,0.570171},
+  {0.176682,0.068412},
+  {-0.005833,0.132717},
+  {0.004802,-0.842799},
+  {1.604389,-0.379789},
+  {0.484633,-0.421334},
+  {0.185324,0.164699},
+  {0.040009,0.495247},
+  {-0.126941,-0.436956},
+  {1.077300,1.615921},
+  {-0.092967,-0.177670},
+  {0.562370,-0.425568},
+  {-0.812328,-0.831640},
+  {0.504950,-0.415654},
+  {0.634659,-1.051510},
+  {-0.509551,-0.741446},
+  {0.461403,-0.823263},
+  {0.741515,-0.178576},
+  {-1.803048,0.240838},
+  {0.965793,0.671290},
+  {0.485702,0.199620},
+  {-0.033739,0.468502},
+  {0.995017,0.457605},
+  {-0.891019,-1.422089},
+  {0.213272,1.349124},
+  {0.957810,-0.529870},
+  {1.144436,0.631099},
+  {-0.608364,-0.008161},
+  {-0.183913,-0.622132},
+  {0.259485,1.794263},
+  {-1.893936,0.887524},
+  {0.869948,0.279483},
+  {1.330244,-0.234150},
+  {-0.698793,-1.869186},
+  {-0.023907,-0.584283},
+  {0.889881,-1.321943},
+  {0.739625,-0.348848},
+  {-0.445268,0.106291},
+  {0.826921,0.698815},
+  {-0.290005,0.699820},
+  {-0.344072,-0.323324},
+  {-0.411819,-0.585410},
+  {-0.018909,-0.290762},
+  {0.505112,-0.327444},
+  {-0.118789,-0.034296},
+  {1.369287,0.043394},
+  {-1.463384,-0.619034},
+  {-0.230005,1.632769},
+  {-0.715552,1.059146},
+  {0.500928,-0.212733},
+  {0.920560,-0.635359},
+  {-0.588473,0.687934},
+  {-0.213108,-0.623500},
+  {-1.114112,1.581999},
+  {1.450259,-0.777587},
+  {-0.240633,0.524103},
+  {-0.437009,-0.672738},
+  {-0.672158,-0.442712},
+  {-1.001309,0.772701},
+  {-0.448667,0.061504},
+  {0.258287,-0.116766},
+  {-1.022620,0.057617},
+  {-0.132288,1.008135},
+  {1.073702,-1.840446},
+  {1.048816,-0.795525},
+  {0.549427,-0.386099},
+  {0.536366,-1.205694},
+  {-0.187059,1.950097},
+  {0.301988,-0.179036},
+  {-0.553248,1.508990},
+  {-1.704598,0.083126},
+  {-0.872153,-0.082539},
+  {-0.436999,0.247757},
+  {-0.535663,0.218898},
+  {1.740084,-1.134760},
+  {1.769763,0.915663},
+  {-0.562986,-0.099149},
+  {1.793889,-0.797788},
+  {-0.178126,-0.267732},
+  {0.631260,-1.067603},
+  {0.824120,0.547277},
+  {0.414803,0.795777},
+  {1.524148,-0.914855},
+  {0.122641,-0.801623},
+  {0.240361,-0.440083},
+  {0.297449,2.260062},
+  {-0.047492,-0.415373},
+  {1.113301,-0.107794},
+  {-0.278272,-0.153044},
+  {-0.795337,0.227249},
+  {-0.362846,0.602121},
+  {0.954406,1.716838},
+  {-0.259979,-0.099052},
+  {-0.032074,-0.033958},
+  {-1.944759,-1.116393},
+  {-0.489102,0.214741},
+  {-0.522574,1.262638},
+  {0.863974,-0.082520},
+  {0.484891,1.178134},
+  {0.703921,0.461285},
+  {-1.885850,-0.134840},
+  {0.185955,0.977271},
+  {0.324373,0.280497},
+  {-0.540469,0.740809},
+  {-0.490823,0.276430},
+  {1.048976,-0.306852},
+  {-0.872366,0.408507},
+  {-0.522883,0.166499},
+  {0.244488,-0.257421},
+  {-1.040009,-0.423785},
+  {-0.755068,0.536125},
+  {-0.684830,0.823324},
+  {0.564522,0.356330},
+  {-0.595022,0.388829},
+  {-0.144106,0.215685},
+  {0.035723,-0.053939},
+  {-0.353620,-1.153940},
+  {1.247211,-0.730838},
+  {1.664593,0.096993},
+  {0.991357,-0.265930},
+  {-1.524475,1.193607},
+  {0.404257,-1.329731},
+  {-0.893348,-0.573884},
+  {-0.456101,1.026453},
+  {0.114008,-0.620093},
+  {0.505622,0.342661},
+  {0.550962,0.586929},
+  {0.809653,-0.405812},
+  {-0.028734,-0.834741},
+  {-0.155816,-1.209146},
+  {1.153799,1.158627},
+  {-0.190132,0.358644},
+  {-0.802479,-0.235259},
+  {0.090976,-0.943619},
+  {0.728902,-0.942158},
+  {1.160826,-0.138895},
+  {0.377593,-0.778267},
+  {0.070475,0.710161},
+  {-0.141220,-1.059658},
+  {0.833144,0.183631},
+  {-0.769879,0.085471},
+  {0.940921,0.622870},
+  {0.717500,0.267314},
+  {-0.671317,-0.402610},
+  {-0.190394,0.893239},
+  {0.197755,0.923891},
+  {1.199303,-0.372345},
+  {-0.196247,0.422832},
+  {0.254665,-0.230619},
+  {1.194773,-0.045428},
+  {-0.165593,-1.152962},
+  {0.457136,-0.280145},
+  {-0.302551,0.117955},
+  {1.065757,0.136590},
+  {-0.403169,-1.378557},
+  {-0.555648,0.009076},
+  {-0.654869,-0.527972},
+  {0.007930,0.308520},
+  {0.267582,-0.462596},
+  {-1.321099,1.596624},
+  {0.201720,0.549905},
+  {0.573367,-0.507021},
+  {0.816064,0.368670},
+  {-0.014020,0.027474},
+  {0.437790,0.322314},
+  {0.228108,-0.622273},
+  {-0.462938,-1.714444},
+  {0.645504,0.655548},
+  {-0.129067,-1.174696},
+  {-0.363463,0.121620},
+  {0.064644,-0.373728},
+  {0.829669,-0.093423},
+  {1.987522,1.409714},
+  {0.402627,0.461663},
+  {-0.517408,1.461400},
+  {-0.194346,0.371817},
+  {-0.095302,1.127603},
+  {0.854504,0.243799},
+  {-0.175436,0.956797},
+  {0.765841,0.740974},
+  {-0.311100,0.344987},
+  {0.505908,-1.150500},
+  {0.570032,-0.062613},
+  {-0.145633,0.780485},
+  {-0.162999,0.361546},
+  {-0.290794,1.229566},
+  {0.262506,-0.308712},
+  {-0.060761,-1.319020},
+  {-0.374195,0.429511},
+  {-0.086799,0.375579},
+  {-0.695934,1.544833},
+  {-0.553200,0.563327},
+  {0.270544,0.934228},
+  {0.336961,0.195811},
+  {0.665743,0.096687},
+  {-0.076057,1.056521},
+  {0.798484,-0.357557},
+  {0.241616,-1.011969},
+  {-1.077322,-0.558872},
+  {0.442441,-0.655746},
+  {0.244793,-0.618180},
+  {0.103232,0.499368},
+  {-0.227070,0.190847},
+  {0.550947,-0.745656},
+  {-1.079964,0.299129},
+  {0.779327,-1.277451},
+  {-1.628750,0.145433},
+  {0.240864,-1.102978},
+  {-1.270518,0.131556},
+  {0.775651,-0.293631},
+  {-0.240939,-1.275808},
+  {0.223459,0.026144},
+  {-0.742946,0.387688},
+  {0.012050,-0.095382},
+  {-0.342335,-0.145945},
+  {-0.474094,-0.504738},
+  {-0.202108,0.823645},
+  {1.541322,-0.601652},
+  {0.433840,-0.201410},
+  {0.098066,0.014597},
+  {-0.773606,-0.954702},
+  {0.318751,-0.263447},
+  {0.397180,-0.536216},
+  {-1.235381,0.558129},
+  {0.769004,-0.940717},
+  {-0.235040,-0.468838},
+  {-0.564520,-0.384393},
+  {-0.005423,1.188288},
+  {-0.985059,0.199438},
+  {-0.189449,-0.528242},
+  {-0.388491,-1.042069},
+  {0.430704,-0.535256},
+  {-0.591624,-0.007859},
+  {0.592677,-0.737538},
+  {-0.381401,-0.351623},
+  {0.491357,-0.380019},
+  {-0.483469,1.474160},
+  {-0.125849,0.369908},
+  {0.078613,-0.121651},
+  {-0.353110,-0.717969},
+  {0.872719,-0.606648},
+  {-0.428882,0.846706},
+  {0.175737,-0.707301},
+  {0.420668,-0.670445},
+  {0.181614,-0.047297},
+  {0.921628,-0.508933},
+  {0.592896,0.669205},
+  {-0.330365,-0.380564},
+  {0.650241,1.309658},
+  {0.236892,-0.200631},
+  {-1.285455,-1.072231},
+  {0.258253,-0.458396},
+  {0.580260,-0.058791},
+  {-0.198798,0.297518},
+  {-0.081461,1.105449},
+  {-0.972283,0.637500},
+  {-0.752549,-0.092627},
+  {-0.787857,-1.415530},
+  {1.506419,1.017351},
+  {0.585529,0.375103},
+  {0.637950,-0.354231},
+  {0.542343,-0.978832},
+  {-0.631439,0.380096},
+  {0.387861,-0.406235},
+  {-0.458367,0.221299},
+  {0.982058,-1.106305},
+  {0.250386,-0.654296},
+  {0.176148,-0.799581},
+  {-1.154337,0.577434},
+  {0.743221,-0.164562},
+  {0.147461,0.563461},
+  {0.262860,-0.187851},
+  {0.080463,-1.267225},
+  {-0.842093,0.465417},
+  {-1.150684,0.413909},
+  {-0.697233,-0.258542},
+  {1.008287,0.072083},
+  {-0.788413,-0.051451},
+  {-0.039100,0.376908},
+  {0.314799,-0.081361},
+  {-0.961472,-1.372276},
+  {0.190966,-0.194039},
+  {-0.415721,0.883995},
+  {-0.001280,-1.035261},
+  {-0.578034,0.253532},
+  {0.718858,0.130658},
+  {0.169064,-0.650773},
+  {1.019305,0.470424},
+  {-0.779577,-1.527926},
+  {-1.397568,-0.116837},
+  {0.151050,-0.025676},
+  {-0.946740,-0.996213},
+  {0.946883,0.374918},
+  {0.120331,0.668101},
+  {-0.158538,-0.647519},
+  {1.011966,-0.291368},
+  {-0.414841,0.899555},
+  {-0.613882,-0.444467},
+  {0.133879,-1.173510},
+  {-0.713934,0.659541},
+  {0.632421,-0.324801},
+  {-0.929352,-0.825345},
+  {-0.939329,-0.154669},
+  {0.135173,0.015513},
+  {1.221067,0.948110},
+  {-0.389186,-0.513496},
+  {0.296118,1.574228},
+  {-0.296515,-0.024812},
+  {1.003795,0.323161},
+  {-0.435951,0.654561},
+  {-0.490652,-0.418108},
+  {0.752490,-0.105439},
+  {-0.337112,0.345660},
+  {-0.567309,1.101450},
+  {0.959341,-1.200654},
+  {0.928823,0.018668},
+  {0.251045,-0.478851},
+  {0.947048,-1.373055},
+  {0.155776,-1.054964},
+  {-0.380913,-0.118574},
+  {0.042293,-0.476657},
+  {0.200067,-0.039548},
+  {-0.386089,-0.409839},
+  {0.799759,-0.629364},
+  {1.030871,-0.758805},
+  {0.191216,-0.009835},
+  {1.064252,0.456354},
+  {-0.739292,0.213518},
+  {-0.957471,0.766434},
+  {1.289907,1.080144},
+  {0.839509,-0.415417},
+  {-0.126717,-0.220462},
+  {-0.493196,0.136442},
+  {-0.740415,-0.205084},
+  {-0.451410,-0.124071},
+  {0.590748,-1.389196},
+  {1.048353,-0.143902},
+  {1.382293,0.237621},
+  {-0.817723,-1.004158},
+  {0.025907,-0.953813},
+  {-0.134011,0.870525},
+  {-0.796710,0.808375},
+  {1.063805,-0.573200},
+  {0.608984,0.022332},
+  {0.705208,1.520836},
+  {-0.449768,0.364173},
+  {-0.121032,-0.081536},
+  {-0.222846,1.764236},
+  {-2.317731,-0.242630},
+  {0.003012,2.291217},
+  {-0.731425,0.097707},
+  {0.267980,0.021976},
+  {-0.052570,-0.060891},
+  {1.328129,1.291555},
+  {-0.535779,-0.699093},
+  {-0.321002,0.511984},
+  {-0.118378,0.976733},
+  {-0.483034,-0.250304},
+  {-1.164027,0.342938},
+  {0.152236,0.157467},
+  {-0.219252,0.092701},
+  {0.666655,-0.396142},
+  {-0.662523,-0.345241},
+  {0.362952,-0.167473},
+  {-0.619415,0.020731},
+  {1.119113,0.580225},
+  {-1.234932,0.059510},
+  {-0.979695,0.650857},
+  {0.248844,0.475403},
+  {0.152068,0.896504},
+  {-0.025802,-0.188693},
+  {-0.312432,0.713030},
+  {0.318940,1.325683},
+  {-1.388616,-0.069398},
+  {0.563331,0.129599},
+  {0.556248,0.372978},
+  {-0.387270,-0.410561},
+  {0.381157,0.174884},
+  {0.205704,0.309849},
+  {0.546306,1.544967},
+  {-1.502442,0.568854},
+  {-1.441137,-0.654132},
+  {0.236177,0.806135},
+  {-0.458600,-0.272605},
+  {1.645150,-0.472139},
+  {1.230134,-0.639721},
+  {0.194120,-0.166522},
+  {0.117438,-0.763945},
+  {0.775048,-0.144419},
+  {0.582774,-0.338508},
+  {-0.451656,-0.308490},
+  {-0.997512,0.221620},
+  {0.518933,0.834596},
+  {0.072709,0.691029},
+  {-0.072488,-0.926413},
+  {0.455952,1.521838},
+  {0.452472,-1.063857},
+  {0.509717,0.548683},
+  {0.555750,-0.567077},
+  {0.044489,0.772517},
+  {-1.065137,1.047399},
+  {-0.057517,0.426841},
+  {-0.048828,-0.066677},
+  {-0.090397,-1.373149},
+  {0.299498,-1.074127},
+  {0.508632,0.940645},
+  {-0.075787,-0.866339},
+  {1.162672,0.315994},
+  {-0.398345,-0.537812},
+  {-0.364908,-0.483622},
+  {0.461687,0.527551},
+  {-0.162621,0.230750},
+  {1.072227,1.602365},
+  {-0.866570,1.022571},
+  {1.183777,0.054456},
+  {-0.901192,-0.614876},
+  {0.207856,-1.230461},
+  {-0.218150,-0.421866},
+  {-0.416722,0.161147},
+  {0.434887,0.939654},
+  {-0.141095,-0.011220},
+  {-1.002557,-0.906183},
+  {-0.336980,0.143558},
+  {1.524689,-0.734075},
+  {-1.673018,-0.011837},
+  {-0.399086,0.379387},
+  {0.022946,0.360077},
+  {1.334352,-0.058248},
+  {0.582118,0.104689},
+  {-0.235530,-0.117603},
+  {-0.685178,1.207036},
+  {-0.505037,0.394430},
+  {1.041913,-0.754037},
+  {0.157290,-0.635867},
+  {0.420463,0.059918},
+  {-0.672484,-0.106277},
+  {-0.342000,-0.887734},
+  {0.037279,-1.312576},
+  {0.196471,-0.690414},
+  {0.628345,0.600837},
+  {1.905626,0.213228},
+  {0.002845,0.911432},
+  {-0.273556,-0.817731},
+  {-0.734045,-0.814594},
+  {-0.278813,1.362944},
+  {-0.490799,0.681619},
+  {0.823281,0.924446},
+  {0.382131,0.054887},
+  {0.207567,0.197565},
+  {-0.198756,-2.356373},
+  {-0.146667,1.116811},
+  {-1.225286,0.261605},
+  {-1.600163,-0.215777},
+  {0.188098,0.034549},
+  {0.059091,0.203517},
+  {0.539660,-0.144263},
+  {0.559525,-0.197091},
+  {-0.995693,0.479884},
+  {-0.140240,0.304529},
+  {-0.933852,1.657169},
+  {-0.378402,0.686321},
+  {-0.133646,-0.711732},
+  {0.356331,0.032003},
+  {0.167839,-1.094820},
+  {0.495340,0.695848},
+  {-0.324402,2.032407},
+  {0.345523,-0.708782},
+  {0.651872,1.141485},
+  {-0.804705,0.431775},
+  {0.073119,-0.202232},
+  {-0.389707,-0.229234},
+  {-0.264997,1.293800},
+  {0.443424,0.482117},
+  {0.331831,-1.277015},
+  {-1.021430,-1.437496},
+  {0.034502,-1.757843},
+  {-0.222381,-0.925680},
+  {0.029757,0.759219},
+  {0.025235,0.100197},
+  {0.204608,0.007049},
+  {0.108738,-0.526643},
+  {0.063573,-1.456564},
+  {-0.344489,0.271249},
+  {-0.605927,-1.137269},
+  {-0.505740,-0.805053},
+  {0.607392,0.236317},
+  {-0.004607,0.308809},
+  {0.148965,0.107110},
+  {-0.116365,-1.014452},
+  {0.054350,-0.377083},
+  {1.753877,0.889535},
+  {-1.155775,0.390584},
+  {-0.077606,0.065922},
+  {0.550225,0.202540},
+  {1.695931,-1.527247},
+  {0.112023,1.588761},
+  {-0.397930,-0.627045},
+  {-0.761887,0.846351},
+  {-0.202916,0.218434},
+  {0.028378,1.479997},
+  {-0.484383,-0.042392},
+  {-0.104811,0.833990},
+  {-0.860957,0.498545},
+  {1.074833,-0.971359},
+  {0.286261,-0.574891},
+  {0.415268,0.659014},
+  {-0.123245,-0.459360},
+  {0.596546,-0.406837},
+  {1.301351,-0.741688},
+  {0.925065,-0.414523},
+  {0.443874,-0.870857},
+  {0.416989,-0.113289},
+  {0.117815,0.264440},
+  {-0.569040,-0.606823},
+  {-0.071240,0.617613},
+  {1.082605,0.798463},
+  {-0.300080,0.104141},
+  {-0.190657,-0.215200},
+  {-0.109927,-1.077320},
+  {-0.865215,-0.747596},
+  {0.026072,0.657730},
+  {-0.602460,-0.765455},
+  {-0.120662,-0.176552},
+  {-0.020959,0.700393},
+  {-0.532963,1.578641},
+  {0.660906,-0.761852},
+  {0.204630,0.671138},
+  {1.378102,1.047063},
+  {0.561706,0.261408},
+  {-0.260495,0.707119},
+  {0.122258,-1.309491},
+  {0.348012,-0.204710},
+  {0.590837,-0.752105},
+  {1.641608,-0.346800},
+  {-0.873873,0.418680},
+  {-0.277803,0.003063},
+  {1.257064,0.252787},
+  {0.675850,0.403955},
+  {-0.418536,0.803833},
+  {-0.164660,0.169753},
+  {0.850197,0.896004},
+  {0.819463,-0.702546},
+  {0.422036,0.045786},
+  {0.453763,-0.574596},
+  {-0.166787,-0.756407},
+  {0.523826,0.600864},
+  {-0.115417,0.177982},
+  {-0.055416,0.683982},
+  {-0.270215,0.340186},
+  {0.195431,1.313902},
+  {-0.443910,-0.182965},
+  {-0.071393,-0.364572},
+  {-0.707667,0.098065},
+  {0.778016,-0.604885},
+  {-0.229268,-0.776824},
+  {-0.512173,-1.134451},
+  {0.252034,0.380931},
+  {-0.003544,0.019841},
+  {-0.058631,0.109133},
+  {-0.128306,-0.186545},
+  {-0.293227,1.213620},
+  {-0.779521,0.232263},
+  {0.060435,0.186679},
+  {0.990281,-0.912743},
+  {-1.301892,0.111320},
+  {-0.034738,-0.546598},
+  {-0.566775,-0.661059},
+  {-0.925700,-1.136595},
+  {0.568009,-0.694776},
+  {-0.857730,1.198007},
+  {-0.037984,-0.146860},
+  {-0.252787,-0.038902},
+  {-0.568219,-0.219940},
+  {0.303626,0.948180},
+  {-0.038566,-0.531735},
+  {-0.103828,-0.538015},
+  {0.260650,-0.359314},
+  {-0.327697,0.416712},
+  {-1.116063,0.090095},
+  {-1.293285,-0.837186},
+  {-0.482711,-0.182843},
+  {0.059427,0.514144},
+  {0.566554,-0.141405},
+  {-1.308599,0.222065},
+  {0.119560,-0.441928},
+  {-0.228916,-0.884073},
+  {0.381615,-0.358756},
+  {0.207154,1.337287},
+  {-0.260877,-0.510744},
+  {-0.240457,0.257392},
+  {-0.147033,-0.616898},
+  {0.252767,0.555545},
+  {1.142911,0.946975},
+  {-0.145901,-0.472828},
+  {0.263985,0.594191},
+  {0.275152,-0.360078},
+  {-0.378772,0.233403},
+  {0.060201,-1.295192},
+  {0.711630,-0.480067},
+  {-0.727486,-0.316626},
+  {-1.024395,-0.820563},
+  {0.229158,0.571038},
+  {-0.195501,0.125831},
+  {-0.134340,-0.536494},
+  {-0.265465,-1.168649},
+  {-1.253822,0.766807},
+  {-0.908661,0.099254},
+  {-0.303613,-0.289008},
+  {-0.312701,-1.039648},
+  {-0.560653,0.439198},
+  {-0.592471,-0.580957},
+  {-1.482518,0.450587},
+  {1.765973,-0.280969},
+  {-2.102702,0.355270},
+  {0.543240,1.121485},
+  {0.960646,0.575538},
+  {-0.328846,-1.412944},
+  {-0.158343,1.897285},
+  {1.102149,-1.023840},
+  {0.757352,-0.148155},
+  {-0.543007,0.817050},
+  {0.860867,0.780749},
+  {-0.209900,-0.052244},
+  {0.033218,0.744034},
+  {0.846613,0.704981},
+  {1.311109,-1.502775},
+  {0.749682,-0.026687},
+  {-0.670479,-0.906180},
+  {-0.449276,-0.235328},
+  {-1.029479,-0.800321},
+  {-0.552364,0.362018},
+  {0.571044,-0.294024},
+  {0.303263,-0.977773},
+  {-1.872468,0.396964},
+  {-0.955788,-0.245566},
+  {-0.953171,0.032204},
+  {-0.140014,0.562421},
+  {-0.238861,-1.034260},
+  {0.016618,-0.778735},
+  {0.641832,-1.328999},
+  {-0.555008,0.001675},
+  {0.177758,0.407400},
+  {0.378772,-0.737130},
+  {-0.947272,0.646346},
+  {0.530960,0.259863},
+  {-0.901216,-0.065121},
+  {-0.322799,-1.319203},
+  {1.054523,0.101474},
+  {1.428788,-0.349216},
+  {0.349194,1.127674},
+  {-0.452166,-0.174773},
+  {-1.118452,0.641579},
+  {0.089249,-0.175187},
+  {0.266167,0.234908},
+  {0.087406,-0.807926},
+  {-1.697266,0.627200},
+  {-1.079827,-0.422557},
+  {-0.372603,0.642134},
+  {0.131330,0.888119},
+  {0.792349,0.278774},
+  {-0.246192,0.080661},
+  {-0.353288,0.005239},
+  {-0.134266,-0.384476},
+  {-0.828652,0.066405},
+  {-0.548264,-0.080022},
+  {-0.120933,-0.875978},
+  {0.903563,-0.743197},
+  {-0.567596,-0.824528},
+  {-0.206943,-0.203413},
+  {0.232509,0.801755},
+  {0.398309,-1.779415},
+  {-0.186675,-0.863868},
+  {1.305872,0.428744},
+  {-1.716046,0.133683},
+  {-0.450440,0.029653},
+  {-0.506766,0.145657},
+  {-0.967946,-0.295591},
+  {0.257046,-0.199603},
+  {0.490026,0.741449},
+  {-0.482293,0.888983},
+  {0.433545,0.021292},
+  {0.395731,-0.152964},
+  {-0.127526,0.629495},
+  {0.948778,0.420625},
+  {0.080788,0.918771},
+  {-0.601768,-0.511523},
+  {0.056685,-0.188264},
+  {0.077067,-0.297327},
+  {0.362971,-0.552698},
+  {0.500014,-0.566048},
+  {0.681482,0.264552},
+  {-0.610054,-0.646848},
+  {0.265600,0.541288},
+  {0.026679,0.942537},
+  {-1.762192,-0.407303},
+  {-0.902743,-0.036230},
+  {0.474591,-0.525614},
+  {0.067020,-0.220233},
+  {-0.618935,0.644017},
+  {-0.247249,0.460334},
+  {0.455640,-0.078102},
+  {0.204557,0.186035},
+  {-0.502683,-0.745109},
+  {0.603414,2.160750},
+  {0.949033,-0.309626},
+  {0.143544,-0.468590},
+  {-1.617425,-0.599765},
+  {-0.338967,0.795837},
+  {-0.575392,0.117471},
+  {1.113309,0.741864},
+  {0.491207,-1.773106},
+  {-0.796479,-1.166586},
+  {1.776758,-0.487393},
+  {0.665706,-0.686534},
+  {-0.733067,0.665936},
+  {-1.191914,-0.753852},
+  {-0.861479,-0.028041},
+  {0.528864,0.362282},
+  {0.372907,-0.759873},
+  {-0.326107,-0.368006},
+  {1.034767,-0.488401},
+  {-0.020672,0.121155},
+  {-0.763290,-0.252682},
+  {-0.581453,0.977660},
+  {-0.422611,0.734330},
+  {0.410968,-0.697525},
+  {0.256227,0.884536},
+  {-0.271733,0.028247},
+  {-0.553155,0.558822},
+  {0.591687,0.681808},
+  {-0.295964,-0.252254},
+  {-0.861694,0.270864},
+  {-0.212098,0.137016},
+  {0.563568,0.156760},
+  {-0.959209,-0.885105},
+  {1.242799,-0.806484},
+  {-1.749964,0.424195},
+  {-0.811421,0.090595},
+  {-1.270889,0.077082},
+  {-0.507043,0.606896},
+  {-0.573533,0.304032},
+  {-0.073649,1.058108},
+  {0.042070,-0.145220},
+  {-0.668327,1.142738},
+  {0.669062,-0.322129},
+  {0.021137,-0.503492},
+  {-0.193499,0.358862},
+  {-0.508566,0.260507},
+  {0.084811,-0.605995},
+  {1.557960,-1.120053},
+  {1.643320,-0.421612},
+  {-0.480576,-0.823660},
+  {0.231449,0.151004},
+  {0.398016,0.209073},
+  {0.045075,0.672618},
+  {-0.008618,0.247177},
+  {-1.053566,0.352608},
+  {0.116426,1.141890},
+  {0.792719,-0.667965},
+  {0.331232,1.168582},
+  {-0.196787,0.038326},
+  {-1.109405,0.145585},
+  {0.925101,-0.146615},
+  {0.420151,-0.522343},
+  {-0.006697,0.762735},
+  {-0.508807,-0.069119},
+  {0.925127,0.708615},
+  {-0.110840,-0.048132},
+  {-0.364342,0.472781},
+  {-0.885346,1.332877},
+  {-0.247386,1.012912},
+  {-1.386080,0.289459},
+  {0.225626,-1.466751},
+  {-0.274328,-0.634428},
+  {0.221469,0.108111},
+  {-0.288359,0.596638},
+  {0.406563,-1.159590},
+  {-0.781803,0.171775},
+  {-0.266993,1.093298},
+  {0.188762,-0.887276},
+  {-1.385732,0.271974},
+  {-0.535123,-0.445177},
+  {-0.405735,0.672560},
+  {0.184163,0.241237},
+  {0.218489,-0.629709},
+  {-0.080616,0.521363},
+  {-0.263647,-1.969656},
+  {-0.000105,-1.140732},
+  {0.345163,0.238108},
+  {-0.724603,-0.973090},
+  {0.166771,2.574467},
+  {-0.442168,-0.073635},
+  {0.087945,0.845359},
+  {0.179795,-0.061662},
+  {-0.317741,-0.537081},
+  {-0.444731,-0.240390},
+  {0.451603,-0.608631},
+  {0.311307,-1.277915},
+  {-1.138521,0.364751},
+  {0.634037,-0.538308},
+  {0.336605,-0.705948},
+  {0.112277,0.892130},
+  {-1.254259,0.041164},
+  {-0.032781,1.144167},
+  {-0.022324,0.649488},
+  {-0.344520,-1.047174},
+  {0.317010,-0.433506},
+  {0.814095,-0.340343},
+  {0.022872,0.077959},
+  {0.249692,0.224696},
+  {1.305443,0.613798},
+  {-0.581707,0.071940},
+  {-0.258272,-1.904325},
+  {0.601451,-0.060804},
+  {-0.118601,0.938334},
+  {0.303851,0.393623},
+  {0.736692,-0.211060},
+  {-0.272122,-0.490145},
+  {0.222637,-0.021387},
+  {-0.311633,0.735060},
+  {-0.199568,0.759139},
+  {-1.013715,-0.780787},
+  {-1.135842,-0.735749},
+  {0.387608,0.235686},
+  {0.083913,-0.711059},
+  {0.163113,-0.233968},
+  {0.180869,-1.193578},
+  {-0.541856,0.511090},
+  {0.718738,-0.971796},
+  {0.918659,-0.884243},
+  {0.235544,-1.235024},
+  {0.685277,0.219639},
+  {0.854647,-0.421738},
+  {-0.028494,-0.255750},
+  {-0.526021,-0.508404},
+  {-0.492737,-0.753063},
+  {0.462732,-0.859153},
+  {-0.133400,0.676276},
+  {0.450487,0.025040},
+  {-0.561239,0.571686},
+  {-0.642541,-0.609117},
+  {1.075468,-0.169765},
+  {0.574631,-0.097372},
+  {0.338229,-0.024071},
+  {-0.525317,0.025844},
+  {0.487080,0.416213},
+  {-1.007587,-0.270080},
+  {0.343576,-1.099756},
+  {-0.699170,0.043134},
+  {-1.044511,0.757733},
+  {-0.575676,-0.749373},
+  {0.305846,-0.161683},
+  {0.811672,0.079546},
+  {-0.192293,0.436743},
+  {-0.693445,-0.830657},
+  {0.968077,1.051416},
+  {-0.769386,-1.502744},
+  {-0.255967,-1.803842},
+  {-0.470924,-0.998421},
+  {-0.824508,-1.845973},
+  {0.045837,-0.401762},
+  {0.360613,0.910411},
+  {-0.337096,-0.237348},
+  {-0.484460,0.113391},
+  {0.305826,-0.010794},
+  {0.147090,0.500318},
+  {0.225740,-0.205529},
+  {-1.264348,-0.329185},
+  {-1.194871,-0.957492},
+  {0.650858,-0.758139},
+  {-1.280834,0.080681},
+  {0.625022,-0.858635},
+  {1.711320,0.093822},
+  {-1.151505,0.996810},
+  {1.790324,0.687198},
+  {0.656644,1.704101},
+  {-0.376292,-0.352113},
+  {-0.126730,0.661884},
+  {0.252564,-0.254102},
+  {-0.661905,1.131852},
+  {-0.368894,0.146481},
+  {-0.798706,-1.083358},
+  {-0.454165,1.240990},
+  {-0.039095,-0.119828},
+  {0.632847,-0.423721},
+  {-0.380750,-0.363220},
+  {-0.262391,-0.622616},
+  {-0.859738,0.564480},
+  {-0.750698,0.139456},
+  {0.947125,0.430152},
+  {0.677915,0.729907},
+  {-0.239181,0.435498},
+  {0.466691,-0.384876},
+  {0.532654,-0.083163},
+  {0.542034,0.653067},
+  {0.208817,-0.330605},
+  {-0.130409,0.034659},
+  {-2.320815,-0.033099},
+  {0.871427,0.273985},
+  {0.194936,1.108967},
+  {-0.285382,0.345010},
+  {1.195251,1.573778},
+  {0.713952,1.087552},
+  {-0.415100,0.517458},
+  {1.196398,0.021875},
+  {0.802508,1.907587},
+  {0.299614,-0.173952},
+  {-0.608050,-0.581877},
+  {0.977775,0.565290},
+  {-0.192386,0.145355},
+  {-0.665472,0.535100},
+  {-0.151025,0.022383},
+  {-0.250835,0.788190},
+  {0.764801,0.467007},
+  {0.298350,-1.467544},
+  {-0.017556,-1.063610},
+  {1.562445,-0.529165},
+  {-0.520377,0.378911},
+  {0.058748,1.831556},
+  {-1.071124,0.601172},
+  {-0.878448,-0.254107},
+  {-0.154485,-0.985552},
+  {-0.887400,0.327273},
+  {-0.705357,-1.472086},
+  {-0.740599,-0.067128},
+  {0.711410,-1.034293},
+  {-0.333938,0.630428},
+  {1.278035,0.397289},
+  {0.210056,-0.257437},
+  {-0.585602,-0.005302},
+  {0.203850,0.195065},
+  {-1.060016,0.172660},
+  {0.771525,-0.917467},
+  {-0.723919,-0.412679},
+  {0.232786,-0.197431},
+  {1.194496,-0.581625},
+  {1.340972,0.360705},
+  {0.975104,0.097678},
+  {1.133589,0.133129},
+  {-0.298991,0.302132},
+  {-0.784508,-0.922366},
+  {0.322948,-0.119337},
+  {0.110163,-0.145440},
+  {1.574654,0.287009},
+  {-0.189796,-0.018106},
+  {-0.174887,-0.498104},
+  {-0.080131,-0.165148},
+  {-0.657113,0.318723},
+  {-0.433595,0.705876},
+  {0.857977,-0.158599},
+  {-0.482497,0.036595},
+  {-0.576244,-0.193566},
+  {0.296959,-0.488391},
+  {0.405842,-0.070404},
+  {0.590507,0.533184},
+  {0.587150,1.314828},
+  {-0.211139,-1.292577},
+  {-1.010083,-0.313106},
+  {-0.863307,0.569579},
+  {0.997553,-0.971260},
+  {0.472407,1.098185},
+  {-1.119245,-1.232905},
+  {0.618522,1.245082},
+  {-0.262763,-0.278210},
+  {-0.105775,0.170132},
+  {1.269669,-0.240590},
+  {0.170976,0.601526},
+  {0.188523,-0.015175},
+  {-1.326050,1.007456},
+  {-0.090769,0.040268},
+  {0.418566,0.135730},
+  {-0.182901,0.036998},
+  {-0.333515,0.424837},
+  {0.428316,0.383354},
+  {-0.794054,-0.779979},
+  {0.263906,0.439720},
+  {0.162836,0.989119},
+  {-0.071999,0.354381},
+  {-0.291458,-0.020139},
+  {0.449140,0.931136},
+  {-0.694063,-0.246796},
+  {-0.862572,0.091815},
+  {0.028864,-0.095157},
+  {0.724161,0.223737},
+  {0.047003,1.150192},
+  {-1.174734,-0.534178},
+  {0.591572,-0.393347},
+  {-0.219495,0.747091},
+  {-0.136702,-0.163781},
+  {-1.060912,0.069882},
+  {0.029668,0.042101},
+  {0.131750,0.093846},
+  {0.871290,1.182361},
+  {1.253828,0.378833},
+  {1.186058,-1.172422},
+  {-0.063604,0.553535},
+  {1.002073,-0.209174},
+  {0.444720,-0.729126},
+  {-0.206357,0.032391},
+  {-0.700775,-0.526320},
+  {-0.737105,0.314376},
+  {0.592877,0.135543},
+  {-0.663426,0.630024},
+  {1.260741,0.446146},
+  {-0.705061,-1.146632},
+  {0.428181,0.432223},
+  {-0.213335,0.151536},
+  {0.520582,0.924886},
+  {0.577738,-0.057536},
+  {-0.751351,1.533813},
+  {-0.156074,0.562951},
+  {0.046758,-0.037720},
+  {-0.217340,0.168171},
+  {0.241340,0.494540},
+  {0.506104,-0.317633},
+  {-0.655820,0.567359},
+  {0.480759,-1.112311},
+  {0.386474,-1.201118},
+  {-1.449230,-0.518502},
+  {-0.706211,0.406803},
+  {-1.560129,-0.422456},
+  {-0.077915,-0.197029},
+  {-1.004173,-0.827722},
+  {0.500350,1.832784},
+  {1.097967,-0.612166},
+  {-0.131651,0.635959},
+  {-0.049192,0.986648},
+  {0.349039,0.570957},
+  {-0.171897,-0.308825},
+  {-1.215161,-0.958771},
+  {0.571949,0.628435},
+  {0.729169,0.139248},
+  {0.709536,0.696363},
+  {0.097966,0.586873},
+  {0.397300,0.024276},
+  {0.236370,0.090813},
+  {0.514880,0.171434},
+  {0.793476,-0.258985},
+  {-0.515502,-0.496673},
+  {0.473964,0.129542},
+  {-0.354065,-0.227705},
+  {0.656057,0.340024},
+  {-0.176111,0.646745},
+  {0.688527,0.624363},
+  {-0.533171,-0.007906},
+  {-1.490044,-0.019393},
+  {0.062044,0.744611},
+  {0.830698,-0.386727},
+  {-0.110515,0.456228},
+  {1.417382,-0.674755},
+  {0.459868,0.925687},
+  {-0.836631,0.488354},
+  {-0.019731,-0.693838},
+  {1.289891,-0.627465},
+  {0.055161,-0.256309},
+  {0.468467,-0.780689},
+  {0.717432,-0.802497},
+  {-0.085141,-0.309899},
+  {0.930132,0.556225},
+  {0.405997,-0.271818},
+  {-0.768176,-0.288646},
+  {0.100647,0.538259},
+  {0.907866,0.140152},
+  {-0.368110,-0.402555},
+  {-0.228629,-0.940188},
+  {-0.569401,0.233255},
+  {-1.022570,0.000617},
+  {-0.324842,0.052006},
+  {-0.269973,0.777187},
+  {-0.035408,-0.139996},
+  {0.473745,0.160440},
+  {-1.354914,-0.289104},
+  {-0.475516,-0.054631},
+  {-0.041168,-0.128649},
+  {0.427951,-0.409020},
+  {1.363959,-0.447370},
+  {-0.703075,1.016340},
+  {-0.075306,-0.369703},
+  {0.230086,-0.722273},
+  {1.792416,-0.645114},
+  {-0.093824,-0.242755},
+  {-1.292877,-1.080529},
+  {1.196220,0.155053},
+  {0.173557,-0.177454},
+  {-0.634131,-0.976788},
+  {-0.379141,0.884947},
+  {-0.536256,0.697163},
+  {0.552100,-0.096580},
+  {-0.696552,0.923878},
+  {0.118458,0.110518},
+  {-0.582715,-0.173407},
+  {-0.956599,1.799081},
+  {-0.843667,-0.384598},
+  {0.764067,-0.865968},
+  {1.000620,-0.160073},
+  {0.953401,1.628974},
+  {-0.888514,-0.891334},
+  {-0.680686,0.247835},
+  {-0.754843,0.258330},
+  {-0.675973,0.394557},
+  {-0.190745,0.303396},
+  {-0.170964,1.405210},
+  {0.926068,-0.197468},
+  {0.672418,0.927374},
+  {0.197025,-0.069306},
+  {0.354251,-0.267216},
+  {0.290035,-0.073490},
+  {0.110947,0.354887},
+  {0.443680,-0.098480},
+  {-0.294424,0.866491},
+  {-0.841475,-0.422685},
+  {0.266968,0.062065},
+  {1.515674,-0.060925},
+  {0.176005,0.140636},
+  {0.404577,-0.509459},
+  {0.515552,0.061269},
+  {0.853981,-0.954393},
+  {1.019148,-1.441008},
+  {0.163838,0.376008},
+  {0.288430,0.184545},
+  {0.067683,1.030477},
+  {-0.499583,0.343582},
+  {0.009995,-0.042159},
+  {-0.621239,1.076062},
+  {-0.939004,0.349109},
+  {0.798145,0.400775},
+  {0.435127,0.287123},
+  {0.202232,-0.459503},
+  {-0.115217,-0.562763},
+  {0.415476,-0.178029},
+  {1.158389,1.432155},
+  {0.936251,-0.718354},
+  {0.848607,-0.413887},
+  {0.391567,-0.379341},
+  {-0.299960,0.021999},
+  {-0.500304,-0.145804},
+  {0.809236,0.749736},
+  {0.827454,0.361110},
+  {0.433617,-1.060374},
+  {0.897989,0.043762},
+  {-1.028161,0.704788},
+  {-0.194029,-0.081497},
+  {0.651930,-0.779738},
+  {-0.210318,0.138924},
+  {-0.224011,-0.719656},
+  {-0.690712,-0.403295},
+  {-0.421069,0.703604},
+  {-0.492768,-0.402452},
+  {-0.811297,0.602505},
+  {-1.785654,0.521719},
+  {0.587757,-0.400209},
+  {0.043330,-0.684632},
+  {0.384072,1.455485},
+  {1.259714,0.400161},
+  {0.761448,0.079450},
+  {-0.053741,-0.471277},
+  {0.412257,0.180934},
+  {0.519025,-0.912317},
+  {1.338382,-1.089903},
+  {-0.120862,1.387350},
+  {0.046935,1.216046},
+  {0.078641,0.418476},
+  {-0.826729,-0.603339},
+  {-1.169826,-0.905686},
+  {-0.319044,-0.337864},
+  {-0.000338,-0.036139},
+  {-0.070890,0.167189},
+  {-0.364559,-0.483024},
+  {-0.845227,0.663173},
+  {-0.358604,0.991618},
+  {-0.544255,0.196842},
+  {1.734390,0.066961},
+  {0.304854,-0.438655},
+  {0.570055,1.368692},
+  {0.680056,0.502049},
+  {1.473820,-0.240434},
+  {0.143943,0.150471},
+  {-0.601375,1.462794},
+  {-0.130329,0.130809},
+  {-0.816240,-0.613083},
+  {-0.363673,0.906229},
+  {-0.137845,0.310958},
+  {0.028385,0.813332},
+  {0.797503,-1.224658},
+  {0.193431,-0.529715},
+  {-0.088177,-0.203006},
+  {-0.475714,-0.792887},
+  {0.226096,-0.128947},
+  {0.184089,-0.068373},
+  {0.887181,0.224031},
+  {-0.216778,0.056027},
+  {-1.168135,-0.932106},
+  {0.564475,-0.495475},
+  {-0.673622,1.542024},
+  {-0.610914,-0.581747},
+  {-0.089544,-0.439327},
+  {0.714516,-0.660308},
+  {1.223961,-0.522664},
+  {0.661751,-0.105839},
+  {-0.630532,-0.064537},
+  {-1.161529,1.098738},
+  {-0.427223,-0.021232},
+  {-0.026751,0.416435},
+  {0.362154,-0.386305},
+  {0.208456,0.633020},
+  {0.045405,1.111140},
+  {1.425449,-1.110883},
+  {0.707444,0.651275},
+  {-0.500077,0.697821},
+  {0.203707,0.456913},
+  {-0.853159,1.120343},
+  {0.834138,-1.031290},
+  {0.617247,-0.697880},
+  {-0.043978,-0.182348},
+  {0.543946,-0.336939},
+  {-0.357450,-0.588382},
+  {0.063896,0.467717},
+  {-1.005923,0.946648},
+  {0.848093,0.260463},
+  {-0.603198,0.472919},
+  {0.824311,1.081034},
+  {-1.794170,-0.412169},
+  {-1.188588,-0.303771},
+  {-0.599378,-0.512405},
+  {-0.764410,0.839242},
+  {-1.630732,-1.206763},
+  {0.475393,1.662433},
+  {0.287510,0.340842},
+  {-0.361590,-0.457253},
+  {0.259458,0.427517},
+  {-0.962593,-0.157040},
+  {-1.043433,0.709428},
+  {-0.124816,0.350705},
+  {-1.784117,-0.277703},
+  {-0.816757,0.881473},
+  {1.130899,0.072276},
+  {0.508338,-0.545349},
+  {0.248984,-1.013667},
+  {0.303921,-0.296289},
+  {0.907752,-0.325327},
+  {-0.706874,-0.148790},
+  {-1.511246,-1.230174},
+  {-0.034105,1.186995},
+  {0.791315,-0.061800},
+  {-0.115356,-0.013607},
+  {0.614068,-0.643597},
+  {-1.434752,-0.837895},
+  {-0.262646,-0.486002},
+  {0.425083,-1.154407},
+  {-0.888865,0.643359},
+  {0.354696,-0.522025},
+  {0.516178,-0.483834},
+  {-0.383349,-0.393546},
+  {0.627820,1.304975},
+  {-1.536539,0.297887},
+  {0.522986,-0.438700},
+  {0.570505,0.136875},
+  {1.225639,0.726921},
+  {0.046321,0.004620},
+  {-0.978947,0.165502},
+  {0.673976,0.355861},
+  {-0.565507,0.154310},
+  {0.184185,0.636983},
+  {0.669884,0.339459},
+  {-0.272178,0.155650},
+  {0.946849,-0.018712},
+  {1.554380,-0.573908},
+  {-1.650752,-0.797470},
+  {0.149065,-0.449614},
+  {0.000874,0.687892},
+  {-0.496167,-0.407806},
+  {-0.311445,-0.715590},
+  {-0.129442,0.092998},
+  {1.038462,1.427624},
+  {0.969798,-0.841165},
+  {-0.638606,0.246169},
+  {-0.007508,-0.280498},
+  {0.113839,-0.195910},
+  {1.042036,0.726260},
+  {-0.200482,0.235256},
+  {-0.406369,-0.249998},
+  {0.286145,-1.006218},
+  {0.210969,0.512718},
+  {-0.859586,-0.839554},
+  {0.139226,0.146909},
+  {0.695305,-0.442922},
+  {-0.681479,0.678879},
+  {0.573686,0.732063},
+  {0.409687,-0.487551},
+  {-0.740833,0.407906},
+  {-0.627461,-0.094149},
+  {0.717096,-0.324215},
+  {-1.040547,0.209955},
+  {0.390960,0.716126},
+  {0.087138,0.229283},
+  {-0.453888,-0.488261},
+  {-0.309646,-0.346751},
+  {-0.129650,0.732543},
+  {-0.170771,0.525447},
+  {0.514311,0.262524},
+  {0.791326,-1.098801},
+  {0.026081,-0.432545},
+  {0.695147,0.619485},
+  {-0.160913,-0.305334},
+  {-0.388194,0.428275},
+  {-0.857131,0.383539},
+  {-0.127692,-0.568071},
+  {-0.153925,-1.205867},
+  {-0.131234,-0.794515},
+  {0.509942,0.661891},
+  {-0.411283,-0.325822},
+  {-0.557037,0.549357},
+  {0.276122,-0.018714},
+  {-0.459507,0.586174},
+  {0.946074,0.411524},
+  {-0.517742,-0.440520},
+  {0.518675,-0.707372},
+  {0.346846,-0.672055},
+  {0.552754,1.465565},
+  {-0.084615,0.414643},
+  {0.452343,-0.941522},
+  {0.346356,0.291833},
+  {-0.280410,1.026607},
+  {0.938494,-0.769506},
+  {-0.559070,-0.210613},
+  {-1.005965,1.379425},
+  {1.003043,-1.111699},
+  {-0.675980,-0.769700},
+  {0.000281,1.375752},
+  {0.304516,-1.251364},
+  {-0.821937,-0.484556},
+  {-0.859102,-1.335838},
+  {0.058085,-0.346139},
+  {0.003970,-0.523620},
+  {-0.142542,0.689615},
+  {-0.916600,0.902236},
+  {0.486899,0.086527},
+  {-0.428760,0.270439},
+  {0.358628,-0.635933},
+  {-0.564581,-0.585300},
+  {0.873809,0.369030},
+  {-0.178501,0.513622},
+  {1.498494,0.604123},
+  {-0.119000,0.391230},
+  {-0.893021,-0.149327},
+  {-1.342297,-1.126706},
+  {0.373536,0.861215},
+  {0.256534,1.148103},
+  {0.899039,-0.560694},
+  {0.054489,0.862495},
+  {-0.293322,-0.433164},
+  {-0.232534,-0.152667},
+  {0.571215,-0.491188},
+  {0.200082,1.008588},
+  {-0.535039,-0.070187},
+  {-0.374009,-0.006474},
+  {0.968621,-1.673820},
+  {-0.250826,-0.592453},
+  {-0.768210,-1.143156},
+  {0.506240,0.456245},
+  {0.517084,-0.666774},
+  {0.212136,-0.465469},
+  {1.318910,-0.330234},
+  {0.021991,0.039870},
+  {-0.393252,0.086292},
+  {0.707893,-0.244737},
+  {0.499235,-0.784132},
+  {0.007350,-0.371172},
+  {1.522063,0.906834},
+  {-0.242588,-1.852291},
+  {0.221807,-0.033887},
+  {0.323357,0.072972},
+  {0.960496,0.074214},
+  {0.760485,-0.415787},
+  {1.011444,-1.408695},
+  {-0.765112,0.167737},
+  {0.051886,0.271979},
+  {-0.082595,0.361773},
+  {0.870305,0.283143},
+  {0.225699,0.608936},
+  {-1.312811,-0.998105},
+  {-0.653488,0.900398},
+  {-1.438955,0.084821},
+  {-0.412878,-0.723466},
+  {-0.272037,0.361482},
+  {-0.694861,0.082223},
+  {0.850862,1.180117},
+  {-0.283139,0.336570},
+  {-0.271481,0.069012},
+  {-0.029517,-1.101000},
+  {0.634905,-0.821237},
+  {0.149412,-0.139163},
+  {-0.484147,0.270160},
+  {-0.761418,0.079378},
+  {-0.072847,0.937568},
+  {-1.307853,-1.009845},
+  {0.297282,0.648821},
+  {-0.091781,-1.985271},
+  {-0.606219,0.151353},
+  {-0.429607,-0.025052},
+  {-0.332890,1.175599},
+  {-1.118603,0.141680},
+  {-0.097394,-0.858219},
+  {0.016748,0.173787},
+  {0.499711,0.334283},
+  {0.294804,-0.100448},
+  {-0.226681,1.320937},
+  {0.445101,-0.020208},
+  {0.298761,0.661325},
+  {0.366419,0.625208},
+  {-0.610404,-0.402482},
+  {-0.196988,-1.143042},
+  {-0.140385,-0.419017},
+  {0.112807,0.888080},
+  {0.266033,0.057014},
+  {-0.728926,-0.934920},
+  {-0.140320,-0.094250},
+  {1.177336,-0.396966},
+  {0.420952,0.653529},
+  {0.796815,0.416470},
+  {0.811086,-0.565463},
+  {0.367195,0.333449},
+  {-0.400751,1.975824},
+  {1.216133,-0.533538},
+  {-0.061920,-0.453391},
+  {-0.711951,-0.449488},
+  {-0.102566,-0.455585},
+  {0.285088,-0.802786},
+  {0.808552,-0.322926},
+  {-0.602289,0.632072},
+  {-0.661576,-1.758596},
+  {-0.146488,-0.548057},
+  {-0.206403,-0.017511},
+  {-0.450221,-1.498859},
+  {0.932314,-1.134894},
+  {0.656476,0.145769},
+  {0.235734,0.094820},
+  {-0.722074,0.001788},
+  {-0.957129,0.829923},
+  {-1.219129,-0.094515},
+  {0.433577,0.505638},
+  {0.667379,-0.080276},
+  {-0.481288,-0.154287},
+  {0.832150,0.696951},
+  {0.845959,0.070575},
+  {0.511181,-0.543340},
+  {1.404294,0.382848},
+  {0.652795,-0.156181},
+  {-0.114089,-0.125219},
+  {0.105672,-0.192649},
+  {1.581463,-0.060738},
+  {1.179013,0.318857},
+  {-0.514448,-0.186117},
+  {-0.004286,0.388816},
+  {0.553462,1.141917},
+  {-0.108260,-0.709488},
+  {0.366715,0.522898},
+  {1.011547,0.255626},
+  {0.510127,-0.556431},
+  {1.387465,-1.491813},
+  {-0.030602,0.643039},
+  {0.252861,0.370345},
+  {0.158032,-0.485250},
+  {1.505481,-0.401738},
+  {-0.425678,1.475448},
+  {0.558642,0.266556},
+  {-0.761068,-0.757845},
+  {-0.236187,0.096478},
+  {-0.299872,-1.335299},
+  {-1.133420,0.013509},
+  {0.020291,0.311569},
+  {0.852593,-0.665722},
+  {-0.523899,0.543296},
+  {-0.258387,0.397797},
+  {-1.620860,0.323925},
+  {1.104585,-1.383714},
+  {0.683798,0.260786},
+  {-1.928301,-0.180178},
+  {-1.028854,0.442835},
+  {0.657349,-0.494352},
+  {-0.277212,0.670959},
+  {-0.180849,0.531330},
+  {-1.227284,-0.792597},
+  {0.563598,-0.076574},
+  {-0.437456,0.229217},
+  {0.929340,0.015725},
+  {0.074666,0.424629},
+  {0.534245,-0.350823},
+  {0.389638,-0.082153},
+  {0.500066,-0.103981},
+  {0.517706,0.482821},
+  {-0.748255,1.069502},
+  {0.473974,-0.018833},
+  {0.395953,0.000067},
+  {0.154909,0.296848},
+  {0.200809,0.287738},
+  {-0.607075,-0.544885},
+  {-0.267287,0.616905},
+  {-0.323802,1.280877},
+  {0.255228,0.082953},
+  {0.888876,-0.780725},
+  {-1.507838,-0.628624},
+  {0.117847,0.741004},
+  {0.951439,2.158240},
+  {0.255605,-0.694650},
+  {0.403436,-0.019320},
+  {0.028617,-1.122894},
+  {-0.559034,-0.279798},
+  {-0.151086,1.482814},
+  {0.401004,-1.215030},
+  {-0.010857,-0.722506},
+  {-0.779211,0.186412},
+  {0.839532,0.388371},
+  {-0.519503,-0.769165},
+  {0.886356,-0.068777},
+  {-0.666874,0.232912},
+  {-0.769333,0.407110},
+  {-0.156172,0.626609},
+  {-0.845403,0.246838},
+  {-0.921500,-1.513649},
+  {-0.659432,-0.352143},
+  {-0.456287,0.822831},
+  {-0.264057,0.594756},
+  {-0.381242,0.749825},
+  {0.584222,-0.010185},
+  {0.717621,0.407810},
+  {0.126997,0.610555},
+  {0.121083,-0.601804},
+  {0.338280,-1.296916},
+  {-0.998988,0.202698},
+  {0.271413,0.241189},
+  {-0.660860,-0.922695},
+  {0.217074,0.091244},
+  {-0.829182,-0.173802},
+  {-1.686936,0.133783},
+  {0.085111,-1.036699},
+  {-0.835207,-0.547288},
+  {-1.001460,0.163306},
+  {-0.009840,-0.897352},
+  {-0.221570,0.248621},
+  {-0.104666,-0.544456},
+  {0.492826,1.224533},
+  {-0.303816,0.203433},
+  {-0.035890,-0.396120},
+  {-0.911609,0.154966},
+  {-0.477369,-0.149520},
+  {0.829666,0.383750},
+  {0.288714,-0.400195},
+  {0.825822,1.060236},
+  {-0.565369,0.570078},
+  {0.725772,0.524669},
+  {-1.427359,0.510741},
+  {0.185095,0.075540},
+  {0.123475,-0.291902},
+  {0.273887,-0.125613},
+  {-0.173428,1.043319},
+  {0.321986,0.197724},
+  {-0.846527,-0.708152},
+  {0.008510,-0.342922},
+  {0.627415,-0.580544},
+  {0.845050,1.241589},
+  {0.585281,0.461177},
+  {0.359324,-0.420843},
+  {0.049152,1.106094},
+  {0.581734,-0.166265},
+  {0.003368,1.019929},
+  {1.025792,-0.545836},
+  {-0.566680,0.838736},
+  {0.217046,-0.554830},
+  {0.746989,0.330831},
+  {-0.477775,-1.838477},
+  {1.209384,0.537204},
+  {0.084745,-0.402040},
+  {0.453664,0.663259},
+  {-0.949609,0.481791},
+  {-1.018870,0.244091},
+  {-0.100135,-0.408291},
+  {0.145723,-0.390015},
+  {0.591639,-0.187299},
+  {-0.072565,0.022234},
+  {-0.090558,0.900594},
+  {-0.115991,-1.076001},
+  {-0.047715,0.945083},
+  {-0.153139,1.232195},
+  {0.395757,-0.137489},
+  {0.500312,-0.165208},
+  {-0.446434,-1.255448},
+  {0.744826,0.719971},
+  {0.101905,0.317928},
+  {-1.113815,1.181345},
+  {-0.826383,-0.342046},
+  {0.698280,-0.256223},
+  {-0.376007,0.253217},
+  {-0.351381,-0.465508},
+  {0.347951,0.252016},
+  {1.060703,-0.456476},
+  {-0.487386,1.010946},
+  {0.082913,1.363434},
+  {0.144076,0.505970},
+  {0.788440,0.349740},
+  {0.359451,0.412744},
+  {-0.133783,0.371278},
+  {0.132375,0.736016},
+  {0.675589,-0.281074},
+  {1.388233,0.041104},
+  {-0.111974,-0.788585},
+  {-0.719106,0.429423},
+  {0.285667,0.906691},
+  {-0.412522,-0.263860},
+  {-0.379611,-1.850579},
+  {-0.882381,0.633164},
+  {-0.350683,0.326832},
+  {0.113319,0.299109},
+  {0.030724,-0.533961},
+  {-0.229546,1.599082},
+  {0.791774,0.219618},
+  {-0.083769,-0.825250},
+  {-0.250508,0.384164},
+  {1.622536,0.627566},
+  {0.269926,1.457477},
+  {0.027500,0.077387},
+  {-0.040952,-0.869704},
+  {0.249097,0.799744},
+  {-0.855749,-1.207818},
+  {0.031174,0.232988},
+  {0.470634,-0.176486},
+  {-1.322606,-0.574727},
+  {0.618473,-1.051757},
+  {0.044093,-1.194452},
+  {-0.856825,-0.363124},
+  {-0.740040,0.491909},
+  {1.049228,-0.383126},
+  {0.269759,-0.756658},
+  {0.411827,-0.187708},
+  {-0.021801,-0.730890},
+  {-0.338874,-0.436049},
+  {0.439729,-0.211741},
+  {-0.464913,0.405662},
+  {0.813909,1.691059},
+  {-0.432949,-0.328759},
+  {0.016182,0.617470},
+  {-0.000084,-0.630506},
+  {1.013115,0.113926},
+  {1.045430,-0.431612},
+  {-0.149045,-0.540305},
+  {-0.168907,1.023595},
+  {-0.681722,-0.870885},
+  {0.148709,-0.519793},
+  {0.083637,-0.233137},
+  {-0.006738,-0.358652},
+  {-1.132096,-0.196676},
+  {0.755618,-0.630740},
+  {1.172062,0.331256},
+  {-0.074557,-1.505289},
+  {1.261753,-0.254490},
+  {0.432557,-0.043824},
+  {0.233409,-0.174214},
+  {0.046213,0.259837},
+  {-0.956389,0.034619},
+  {0.336500,0.085573},
+  {1.029807,-1.168944},
+  {0.148733,-0.666186},
+  {0.504364,0.591615},
+  {-0.244863,-0.431764},
+  {-1.287166,-0.010764},
+  {0.206851,-1.199483},
+  {-1.130227,-0.926562},
+  {0.045319,-0.640907},
+  {1.744857,0.365060},
+  {-0.337659,0.254251},
+  {-1.241628,0.474563},
+  {-0.098000,0.043348},
+  {0.135789,0.720002},
+  {0.079954,-0.567468},
+  {0.209679,0.580221},
+  {0.129076,-0.638995},
+  {-0.259201,0.098160},
+  {0.684000,0.742712},
+  {-1.058322,1.121174},
+  {-1.133869,-0.077823},
+  {-0.786057,-0.192047},
+  {0.043596,-0.730099},
+  {-0.468971,-0.508530},
+  {-0.166478,0.964301},
+  {-0.421994,0.534392},
+  {0.801013,0.327796},
+  {0.626465,-0.857809},
+  {-0.316640,0.963254},
+  {-0.686444,-0.349580},
+  {-0.411887,0.006307},
+  {-0.044218,-0.684096},
+  {1.448337,-0.256645},
+  {0.224336,-0.436483},
+  {0.025337,-0.347815},
+  {-0.407366,0.419951},
+  {-0.132820,0.348857},
+  {0.371735,-0.864264},
+  {0.086483,-0.338426},
+  {0.585107,0.270821},
+  {0.326869,0.548646},
+  {-0.326146,-0.463299},
+  {1.143470,-0.087656},
+  {-0.098858,1.246934},
+  {-0.036904,0.191940},
+  {0.287535,-0.291944},
+  {0.369159,0.063018},
+  {-1.317075,-0.193187},
+  {0.378189,0.176271},
+  {0.856049,-0.716794},
+  {0.077633,0.519224},
+  {-0.699016,-0.029019},
+  {0.295033,0.961106},
+  {0.197367,0.762655},
+  {0.114262,-0.106428},
+  {0.589365,-0.677044},
+  {-0.241511,0.228210},
+  {-0.430454,-0.895877},
+  {0.702252,0.370365},
+  {1.742418,-0.318825},
+  {0.735371,-0.917391},
+  {0.798335,-0.370615},
+  {-0.537492,0.369018},
+  {1.236422,0.065891},
+  {-0.266399,-0.351783},
+  {0.423548,0.165331},
+  {0.077228,0.536433},
+  {-0.174825,0.148350},
+  {0.199017,-0.554067},
+  {-0.965766,-0.545608},
+  {0.554513,0.053499},
+  {0.037865,0.091226},
+  {0.586746,0.403764},
+  {1.063461,-0.711465},
+  {0.627927,0.180048},
+  {1.849318,0.366474},
+  {-0.787943,-0.066363},
+  {-0.225401,0.838693},
+  {0.780419,1.099950},
+  {-0.583530,-0.334410},
+  {0.435296,-0.110910},
+  {-0.395316,0.522476},
+  {-0.296867,1.030867},
+  {0.180194,0.365723},
+  {-0.565612,0.105022},
+  {-0.071050,-0.637618},
+  {1.036443,1.254893},
+  {-0.357016,0.150407},
+  {-0.105283,0.193076},
+  {0.137034,0.727374},
+  {0.395267,-0.224436},
+  {-0.148716,0.241524},
+  {-0.185222,0.387931},
+  {1.193605,-0.847551},
+  {0.250426,-0.707717},
+  {0.140128,-0.294992},
+  {0.023456,0.023879},
+  {0.557191,-1.088329},
+  {-0.705496,-0.351205},
+  {0.706976,1.287748},
+  {0.207298,-0.734820},
+  {0.124706,0.189566},
+  {0.797376,1.215020},
+  {-0.329404,-0.576281},
+  {0.648951,0.195529},
+  {-0.597548,0.519029},
+  {0.212921,0.436097},
+  {-0.330959,0.311842},
+  {-2.163917,-0.881882},
+  {-1.070369,0.664018},
+  {0.473269,-0.101973},
+  {0.378465,-0.822488},
+  {1.361181,0.418143},
+  {-1.012859,-0.712103},
+  {0.870152,-1.346827},
+  {0.653007,-0.617410},
+  {0.497337,-0.775725},
+  {-0.260237,0.259267},
+  {-0.743430,-0.591395},
+  {-0.674841,-0.191339},
+  {-0.584851,-0.214106},
+  {0.225244,0.160024},
+  {1.161423,0.256300},
+  {-1.640086,-0.242275},
+  {-0.180871,-0.679693},
+  {-1.243241,-0.228350},
+  {0.599251,0.947940},
+  {1.146590,-0.156590},
+  {-0.647330,0.051065},
+  {1.949584,-0.583944},
+  {-0.242692,1.238130},
+  {0.039443,0.740763},
+  {-1.458523,0.089037},
+  {-0.153975,-0.381741},
+  {-0.317357,-0.610750},
+  {0.237125,1.346517},
+  {-0.201768,0.320696},
+  {0.606654,1.023548},
+  {0.810015,0.801355},
+  {-0.870015,0.018496},
+  {0.005406,0.866319},
+  {-0.020676,-0.167982},
+  {-0.341657,0.564725},
+  {-0.720214,-0.704252},
+  {0.656031,-0.457047},
+  {0.070486,0.044186},
+  {-0.170715,-0.739585},
+  {0.184302,-1.788002},
+  {0.715592,-0.376628},
+  {-0.363081,-0.119088},
+  {-0.100914,0.119614},
+  {0.005834,-0.268860},
+  {-0.129771,0.331506},
+  {0.143287,-0.198036},
+  {-0.304611,0.217426},
+  {-0.594381,-0.825000},
+  {-0.365556,-0.258829},
+  {-0.214172,1.162243},
+  {-1.194364,0.810341},
+  {-0.325733,-0.570507},
+  {-0.614001,-0.663556},
+  {0.118437,-0.291858},
+  {0.502611,-0.601088},
+  {0.659081,-0.217369},
+  {-0.446278,-0.786148},
+  {0.022241,0.272441},
+  {0.590431,0.909812},
+  {-0.505353,0.055519},
+  {-1.032100,-0.102485},
+  {0.514653,0.094284},
+  {0.017452,-0.117900},
+  {-0.434090,-0.360114},
+  {-0.795938,0.951701},
+  {1.526127,-0.592844},
+  {-0.389825,-0.453072},
+  {0.384166,-1.012017},
+  {1.182901,-0.350927},
+  {-0.650756,-0.215167},
+  {-0.920064,0.382095},
+  {0.325262,0.053581},
+  {-0.367365,-0.250609},
+  {-0.792805,-0.159176},
+  {0.364886,1.149926},
+  {-0.952999,-0.523706},
+  {-0.590878,-0.928414},
+  {1.302134,0.020920},
+  {0.271231,1.409444},
+  {-0.421610,0.925520},
+  {1.193167,0.706521},
+  {-0.333416,0.336865},
+  {0.018979,0.278195},
+  {0.454613,0.518481},
+  {-0.039562,-0.760878},
+  {0.452849,0.034856},
+  {-0.363828,-0.532211},
+  {-0.120648,0.354305},
+  {0.124415,0.897220},
+  {0.079466,-0.085179},
+  {0.550458,0.796151},
+  {0.118218,0.662074},
+  {-0.355235,-0.199056},
+  {0.436312,0.191719},
+  {1.566220,-0.116118},
+  {-0.836157,-0.768313},
+  {1.586808,0.178922},
+  {-0.280443,-0.468900},
+  {-0.326042,0.010218},
+  {0.566632,1.593287},
+  {1.012295,-1.739928},
+  {-0.076488,0.044391},
+  {0.483599,-0.125041},
+  {-1.492059,0.640508},
+  {-0.678092,-0.179653},
+  {-0.373386,-0.340247},
+  {-0.832028,0.600061},
+  {-0.567324,-1.027965},
+  {-0.083357,0.199339},
+  {-0.734433,0.929912},
+  {0.570454,0.573202},
+  {-0.365270,0.716633},
+  {-0.417190,-0.754130},
+  {-0.854980,-0.194668},
+  {-0.798654,-0.640999},
+  {-0.386871,0.854369},
+  {-0.317394,-0.378946},
+  {0.845760,-0.762026},
+  {-0.238503,0.628650},
+  {-0.476581,-1.193935},
+  {0.372842,0.363358},
+  {1.929276,0.425483},
+  {0.560945,-0.892123},
+  {0.832559,1.026749},
+  {0.332159,-0.899940},
+  {0.729769,-0.406694},
+  {1.773252,-1.453081},
+  {0.014471,0.518545},
+  {-0.032728,-0.153441},
+  {-0.418525,-0.263385},
+  {1.483183,1.053228},
+  {-1.108048,-0.126405},
+  {-0.882071,0.557002},
+  {-0.299469,0.621888},
+  {-1.390889,0.791123},
+  {0.087246,-0.444939},
+  {-0.971593,0.855966},
+  {0.288585,-1.387271},
+  {-0.019311,0.732536},
+  {0.575029,-0.900371},
+  {-0.849454,-0.021176},
+  {0.102055,0.741000},
+  {0.639938,0.250506},
+  {0.031515,-1.559311},
+  {0.184749,0.007297},
+  {-0.615292,0.150555},
+  {-1.045878,0.504486},
+  {0.648174,0.248709},
+  {-1.923251,-0.525706},
+  {-0.139883,-0.496519},
+  {-0.273595,0.733709},
+  {-0.554049,-0.638829},
+  {-0.388154,-0.721417},
+  {0.302342,-0.922345},
+  {0.301997,0.247964},
+  {0.783229,-0.118560},
+  {0.015568,-1.688273},
+  {-0.203951,-0.271846},
+  {-0.464304,-0.803130},
+  {0.788053,0.525790},
+  {-0.310437,0.810294},
+  {0.734484,-0.122955},
+  {0.078820,-0.755273},
+  {0.689406,0.380790},
+  {-0.879125,-0.800241},
+  {0.916797,-0.158671},
+  {-0.955580,0.370290},
+  {1.053886,0.183747},
+  {-1.024297,0.502801},
+  {0.821289,-0.323075},
+  {-0.197416,-0.199129},
+  {0.128673,-0.204273},
+  {-0.047906,0.532305},
+  {-0.332497,-0.459762},
+  {-0.921215,0.010891},
+  {-1.187693,0.237371},
+  {-0.907113,-1.114225},
+  {-0.391416,0.334680},
+  {0.484839,-0.022006},
+  {0.279699,-0.155898},
+  {0.232580,0.635441},
+  {0.442647,-0.512038},
+  {0.457949,-0.744347},
+  {-0.420994,-0.605339},
+  {0.607157,1.329146},
+  {-0.274663,0.330222},
+  {-0.146928,0.998094},
+  {0.634872,-0.085303},
+  {0.038862,0.137135},
+  {0.874375,0.481656},
+  {-0.078049,0.930253},
+  {0.211922,0.365963},
+  {-0.057426,-1.256802},
+  {-0.249915,0.102113},
+  {0.074635,0.926036},
+  {-0.919523,0.156604},
+  {0.321808,-0.463000},
+  {-0.336447,0.591209},
+  {0.069922,0.186182},
+  {-0.098125,0.286970},
+  {-0.945924,0.199885},
+  {1.251790,-0.588337},
+  {-0.103392,-0.063531},
+  {-1.495706,0.300232},
+  {0.161476,-0.532461},
+  {-0.229976,0.007762},
+  {0.102294,0.640865},
+  {-0.046165,-0.345694},
+  {0.152871,-0.139371},
+  {-0.621642,0.466272},
+  {0.502189,-0.429932},
+  {0.381534,0.850587},
+  {1.047882,0.364581},
+  {0.166650,-0.533360},
+  {-0.147243,0.870267},
+  {0.264328,-0.088269},
+  {0.241229,0.219450},
+  {-0.674579,0.991554},
+  {-0.952101,0.726952},
+  {0.000481,-0.050198},
+  {-0.237754,0.641076},
+  {-0.058228,-0.524298},
+  {1.097294,-0.979438},
+  {-1.219292,-0.095890},
+  {0.265504,-0.684968},
+  {-0.779660,0.555899},
+  {0.571050,-0.072841},
+  {0.669225,1.701574},
+  {-1.191487,0.111178},
+  {0.909199,0.891876},
+  {-0.395837,-0.258702},
+  {0.093876,-0.469630},
+  {-0.423132,0.835933},
+  {-0.273781,-0.809838},
+  {0.379980,0.848947},
+  {1.264064,-0.035597},
+  {-0.801897,0.295423},
+  {0.817880,-0.017036},
+  {-0.105681,0.855247},
+  {0.486284,-0.619853},
+  {-0.032531,0.489774},
+  {0.211010,0.529908},
+  {0.661884,2.635604},
+  {0.539633,1.054015},
+  {-0.523203,0.144841},
+  {0.642130,-0.062279},
+  {0.773169,-0.295494},
+  {1.236025,0.138371},
+  {-0.902266,-0.091117},
+  {0.126149,1.096640},
+  {-0.361577,0.548790},
+  {0.082879,-0.449861},
+  {-0.084813,1.095634},
+  {1.546048,1.536377},
+  {0.856924,0.635732},
+  {0.834506,0.824424},
+  {-0.021495,-0.526435},
+  {-0.838356,0.515902},
+  {-0.473372,-0.161548},
+  {-0.778314,1.424876},
+  {-0.230595,-0.748969},
+  {-1.592887,-0.737746},
+  {-0.938554,-0.530306},
+  {-1.572545,-0.791394},
+  {0.435546,-0.376083},
+  {0.525145,0.213393},
+  {0.367887,-1.044275},
+  {-0.719915,0.061255},
+  {0.304958,-0.204748},
+  {1.210495,-0.112141},
+  {-0.086723,0.129535},
+  {-1.281467,0.522155},
+  {-0.333647,-0.274983},
+  {-0.554049,0.413201},
+  {0.753145,0.891878},
+  {0.274075,-0.707382},
+  {-0.062669,0.788726},
+  {0.466273,-0.501215},
+  {0.024895,0.354051},
+  {0.798756,0.455852},
+  {-0.020206,-0.029112},
+  {0.339560,1.851831},
+  {0.152438,0.738243},
+  {0.183936,-0.781268},
+  {-0.103182,0.713654},
+  {0.875376,-0.483562},
+  {0.015320,-0.460793},
+  {0.060661,-0.643523},
+  {-2.264353,0.105116},
+  {-0.789343,0.615718},
+  {-0.243310,0.060137},
+  {1.699891,-0.863147},
+  {-0.512188,-0.107884},
+  {0.715462,-0.746962},
+  {-0.168059,0.396399},
+  {-1.855221,0.474742},
+  {1.117193,-0.177673},
+  {0.605124,0.264148},
+  {-0.158801,-0.269563},
+  {-0.026259,1.643594},
+  {-0.612630,-0.403823},
+  {-2.104756,1.120870},
+  {0.439319,-0.326207},
+  {-0.729839,-0.030055},
+  {-0.197924,-0.161142},
+  {0.859821,0.172257},
+  {-0.082605,1.518575},
+  {-1.076389,-1.744869},
+  {-0.219282,1.053450},
+  {-0.545467,0.263106},
+  {0.717580,-0.589610},
+  {-0.704720,-0.962831},
+  {0.404192,0.274100},
+  {-0.559766,-0.674194},
+  {-0.846818,1.766523},
+  {0.413603,0.183993},
+  {0.258588,0.447021},
+  {0.711449,-0.254685},
+  {-0.039759,0.029436},
+  {-0.128433,-0.269298},
+  {-1.025894,1.345869},
+  {-0.912975,0.052240},
+  {0.755264,-0.206240},
+  {0.044141,0.949915},
+  {-1.565117,-0.595266},
+  {0.200074,-1.417585},
+  {-0.158238,-0.081043},
+  {-0.503170,-0.078182},
+  {0.362525,-0.194696},
+  {0.259960,-0.907605},
+  {-0.105310,-1.933984},
+  {-0.899535,-0.440019},
+  {0.163533,0.065331},
+  {-0.571787,-1.130394},
+  {0.301250,-0.094735},
+  {0.104414,-1.423818},
+  {-0.146865,-0.198913},
+  {-0.497490,0.758248},
+  {0.466122,-0.416899},
+  {-0.940500,0.639487},
+  {-0.440392,0.809788},
+  {-2.223726,0.948796},
+  {-0.313709,1.585454},
+  {0.206535,-0.868710},
+  {0.910526,-1.174225},
+  {-0.495236,0.167135},
+  {-0.575404,0.007086},
+  {-0.255414,0.937178},
+  {-0.296419,-0.082039},
+  {1.002712,1.059056},
+  {-1.200725,1.009362},
+  {-1.031906,1.427611},
+  {0.064588,-0.744817},
+  {1.290310,0.659770},
+  {0.251141,-0.190253},
+  {-0.586866,-0.099783},
+  {1.514305,0.076462},
+  {-0.292877,-0.034932},
+  {0.086519,-1.537324},
+  {0.558554,-1.027847},
+  {0.016688,-0.294418},
+  {-0.464068,0.572870},
+  {-1.031390,0.702926},
+  {-0.993327,0.280797},
+  {0.407376,1.270542},
+  {-0.291421,-0.688110},
+  {0.842434,1.685884},
+  {-0.464356,-1.287623},
+  {0.680357,-0.473646},
+  {0.694717,0.571415},
+  {0.391202,-0.560555},
+  {-0.169632,-0.035731},
+  {-0.203948,0.790613},
+  {-0.670035,-0.264796},
+  {-0.090461,0.101945},
+  {-0.311617,0.481222},
+  {-0.344817,0.135445},
+  {-1.162870,0.142668},
+  {-0.487890,-0.544005},
+  {0.732853,0.690509},
+  {0.585005,-1.244755},
+  {0.503757,-0.316446},
+  {0.869989,-0.370224},
+  {0.351113,-0.041060},
+  {0.021720,-0.728370},
+  {-0.706755,-0.494790},
+  {-0.103364,-1.238782},
+  {-0.355559,-0.533147},
+  {0.166720,-0.864956},
+  {0.334983,0.100261},
+  {-0.848547,0.637065},
+  {-0.317559,0.657728},
+  {0.409242,0.262048},
+  {0.596688,0.826314},
+  {-0.458137,0.110997},
+  {-0.682732,-0.219886},
+  {-0.408569,0.043952},
+  {-0.320255,-1.596813},
+  {0.387040,-0.699110},
+  {0.198430,-0.538138},
+  {0.856802,-0.708255},
+  {0.756612,-0.653997},
+  {-0.356619,-0.562844},
+  {0.271806,1.194806},
+  {-0.175223,-1.368711},
+  {-0.153117,-0.398840},
+  {0.706898,-0.328442},
+  {0.034251,-0.107789},
+  {0.277096,0.757656},
+  {-0.144774,0.378035},
+  {-1.538711,0.603603},
+  {0.206118,0.430155},
+  {0.622510,0.173831},
+  {0.046042,0.058330},
+  {-0.577057,0.162875},
+  {0.685647,-0.647830},
+  {-0.910460,0.504792},
+  {-0.200849,-0.954877},
+  {0.475974,-0.438454},
+  {0.340606,0.030790},
+  {-0.278135,0.194854},
+  {0.707024,-0.623755},
+  {-0.091069,-2.189701},
+  {-0.273684,-0.897539},
+  {0.050275,0.334330},
+  {-1.301614,-0.241288},
+  {0.376532,1.392280},
+  {0.848500,0.658936},
+  {-0.354567,-0.729838},
+  {0.779270,-0.651632},
+  {-1.525730,0.876681},
+  {0.587723,-1.383307},
+  {-0.741497,0.254969},
+  {0.873264,0.197479},
+  {-0.480964,1.299430},
+  {-0.431708,0.130537},
+  {0.323680,-0.448970},
+  {-0.803705,-0.383630},
+  {0.259853,-0.171842},
+  {-0.074427,-1.423999},
+  {0.213413,-0.806918},
+  {0.319758,-0.629784},
+  {0.197369,-0.175039},
+  {0.374164,-2.020326},
+  {0.234205,0.212423},
+  {0.442106,-0.486910},
+  {-0.970864,0.312143},
+  {0.994610,0.634741},
+  {0.048931,0.205781},
+  {0.369340,-0.247351},
+  {-0.458195,0.094655},
+  {-0.853393,0.397950},
+  {-0.222113,-0.020140},
+  {0.855104,1.002182},
+  {-0.949021,0.731330},
+  {-0.073219,1.402526},
+  {-0.151223,-0.492186},
+  {-1.375457,-0.136411},
+  {-0.466811,0.022190},
+  {1.087376,0.106868},
+  {-0.744528,-0.413374},
+  {-0.342038,0.049102},
+  {-1.494273,-0.271438},
+  {-0.125528,0.601419},
+  {-0.111221,-0.380202},
+  {0.641612,0.273790},
+  {-0.883504,0.517323},
+  {-0.843544,0.433726},
+  {0.070544,0.613134},
+  {-1.407600,-0.044330},
+  {-0.492451,0.995879},
+  {0.983269,0.143963},
+  {0.221852,0.495000},
+  {-0.791657,0.614310},
+  {0.703727,-0.571992},
+  {-0.071284,0.875682},
+  {1.641568,-0.631850},
+  {-0.083871,0.250629},
+  {-0.229893,-1.203232},
+  {-0.382616,1.669525},
+  {0.486753,-1.096469},
+  {-0.599193,-0.121324},
+  {1.105338,0.376484},
+  {-0.433136,-0.568643},
+  {1.262118,0.303337},
+  {-0.180750,-0.251747},
+  {0.232196,0.634354},
+  {0.526905,0.692507},
+  {-0.416640,-0.134469},
+  {-0.945404,0.290901},
+  {1.452757,0.222601},
+  {-0.057791,-0.455470},
+  {-0.853629,-0.583719},
+  {-0.233342,0.161093},
+  {-0.968813,0.500752},
+  {-0.861537,0.075586},
+  {1.474493,-0.284338},
+  {-0.754792,0.807480},
+  {-0.643724,1.545286},
+  {-0.922333,-0.131210},
+  {-1.068958,-0.426784},
+  {-1.011546,0.020778},
+  {0.787292,0.193200},
+  {1.276891,0.812940},
+  {-0.001378,1.525040},
+  {-0.482745,0.059566},
+  {0.640762,-0.003003},
+  {-0.842820,-0.681972},
+  {-1.136885,1.104554},
+  {0.707249,0.574867},
+  {0.404579,0.578500},
+  {0.772682,0.950729},
+  {-0.758872,-0.442283},
+  {-0.134508,0.287088},
+  {-1.217763,-0.136208},
+  {0.067001,0.006883},
+  {-1.117236,-0.517592},
+  {1.074093,-1.371225},
+  {0.434892,-0.753326},
+  {-1.657469,-0.184451},
+  {-0.563524,0.887134},
+  {0.594674,-0.128692},
+  {-0.861165,0.393858},
+  {0.740365,-0.155010},
+  {-0.542431,-0.137020},
+  {-0.160958,0.367545},
+  {1.061826,-0.276971},
+  {-0.771112,0.145356},
+  {1.963119,0.088410},
+  {0.024542,0.144405},
+  {-1.161727,0.028527},
+  {-0.629890,-1.011632},
+  {-0.523735,0.451983},
+  {0.226956,-0.663835},
+  {-0.709942,0.411619},
+  {-0.862071,-0.723057},
+  {-0.430194,0.705340},
+  {0.489380,-0.913195},
+  {-0.913531,-0.125404},
+  {0.580276,-0.084090},
+  {-0.795566,0.423792},
+  {0.195894,-0.952419},
+  {0.206701,0.058895},
+  {0.343643,0.988757},
+  {0.111858,1.155224},
+  {-0.402678,0.396630},
+  {-0.085481,1.087237},
+  {-0.626447,0.384020},
+  {-1.545255,1.402500},
+  {-0.382681,1.101254},
+  {-0.570465,-0.881833},
+  {-0.067170,0.447168},
+  {-0.402078,-0.107883},
+  {-0.063022,1.237664},
+  {0.357641,-0.210884},
+  {0.173106,1.169455},
+  {0.371232,-0.555801},
+  {0.426061,1.683925},
+  {-0.862561,0.481593},
+  {-1.295345,0.677131},
+  {0.882575,-0.080920},
+  {1.076227,0.081224},
+  {0.217811,0.806447},
+  {0.642645,-0.244275},
+  {-0.137093,-0.322132},
+  {0.246084,-0.089603},
+  {0.827582,-0.845716},
+  {0.373640,-0.242160},
+  {-1.221390,0.390996},
+  {-0.147700,0.855458},
+  {-0.301463,-0.077718},
+  {-0.477683,-1.468176},
+  {-0.708449,0.284200},
+  {0.341767,1.177536},
+  {0.073596,-0.373099},
+  {-0.418003,0.011618},
+  {0.659790,0.501637},
+  {0.517335,-0.383893},
+  {-0.504534,0.584654},
+  {-0.700111,-0.051171},
+  {0.235161,-1.457844},
+  {0.447664,-0.556099},
+  {0.669581,1.662563},
+  {0.635083,-0.024530},
+  {-0.426292,-0.598758},
+  {0.380072,-1.112453},
+  {-0.081336,0.145480},
+  {-0.907122,0.871629},
+  {0.131628,1.573776},
+  {-0.384249,0.507013},
+  {-0.799491,0.657805},
+  {-0.243014,0.812674},
+  {-0.280861,-1.138266},
+  {0.252573,-0.763178},
+  {-0.829438,0.152104},
+  {0.238524,-0.277766},
+  {2.523618,-0.842357},
+  {-0.699246,-0.801106},
+  {1.166441,0.831885},
+  {0.413058,0.094339},
+  {-0.446019,0.307323},
+  {-0.725646,-0.489846},
+  {-0.253605,-1.246224},
+  {0.912358,-0.556724},
+  {1.278255,0.012615},
+  {-0.078776,-1.194235},
+  {-0.366774,-2.136559},
+  {0.776158,0.034121},
+  {0.124952,0.735158},
+  {0.495498,-0.287894},
+  {0.645361,0.435278},
+  {-0.027172,-0.196745},
+  {-0.091825,0.181205},
+  {-0.449690,0.202206},
+  {0.615196,-0.763464},
+  {0.006443,-0.808811},
+  {-0.778937,-0.464757},
+  {-0.661201,-0.076723},
+  {0.142220,0.639184},
+  {0.043606,0.256401},
+  {1.185320,0.179074},
+  {0.964460,1.638016},
+  {-0.439314,-1.027129},
+  {-0.974713,-0.701040},
+  {0.626450,1.670174},
+  {0.849683,0.000633},
+  {-0.758821,0.643905},
+  {0.533524,-0.276729},
+  {-0.287200,0.229033},
+  {0.976720,0.691516},
+  {0.413251,-0.414654},
+  {-0.105930,0.582164},
+  {1.083972,0.127931},
+  {-0.008602,0.396564},
+  {-1.014633,-0.766216},
+  {-0.567769,-0.603326},
+  {-0.671345,-0.870915},
+  {-0.436383,0.159432},
+  {0.789563,-1.405331},
+  {-0.012052,0.291490},
+  {-1.064900,0.499255},
+  {1.857613,0.173601},
+  {-0.166943,-0.593651},
+  {0.813628,0.624637},
+  {-0.792895,-0.334087},
+  {-0.371264,-1.463375},
+  {0.232055,1.514775},
+  {-0.480078,-0.932215},
+  {0.493973,0.190971},
+  {0.477380,0.232577},
+  {0.240390,-0.359935},
+  {0.082890,-0.564972},
+  {0.142401,0.071885},
+  {0.415193,-0.076906},
+  {1.294283,0.031845},
+  {0.184350,0.522837},
+  {-0.985097,0.515890},
+  {-0.321414,0.266318},
+  {-0.040275,-1.090636},
+  {1.454251,-0.464461},
+  {-1.341400,-0.556900},
+  {1.112672,-1.294695},
+  {0.684248,-0.569627},
+  {0.110519,1.620119},
+  {-0.074092,-1.501786},
+  {0.836840,0.582174},
+  {-0.312866,-0.163083},
+  {-0.348387,0.846036},
+  {-0.401781,-0.683929},
+  {-0.477886,0.419644},
+  {0.380085,1.371967},
+  {-0.151815,-1.437845},
+  {0.362655,1.699131},
+  {-0.285574,-0.328342},
+  {-0.373046,0.552420},
+  {0.524496,-0.274919},
+  {0.162426,-0.591347},
+  {0.247988,-1.248758},
+  {0.179873,-0.495477},
+  {0.332481,0.187029},
+  {-0.680053,-0.795562},
+  {-0.297790,-1.228507},
+  {0.433604,0.362610},
+  {-0.912981,-0.317793},
+  {0.356607,-0.401878},
+  {-0.457215,1.277897},
+  {0.423863,-0.907331},
+  {1.369555,0.294154},
+  {-0.558227,-0.787342},
+  {-0.700928,-0.002200},
+  {0.475999,0.053324},
+  {0.759515,-0.511097},
+  {-0.214352,-1.108068},
+  {-0.823262,0.181915},
+  {-1.481847,-0.145536},
+  {-0.838811,-0.827068},
+  {-0.354237,-0.929419},
+  {-0.003615,0.497626},
+  {1.165999,0.676843},
+  {0.626492,0.510292},
+  {0.158529,0.168647},
+  {1.189623,0.008902},
+  {0.281004,-1.174505},
+  {0.610236,-0.754183},
+  {-0.669239,0.615970},
+  {0.300373,-0.608739},
+  {1.205115,-0.072012},
+  {0.272992,-0.140035},
+  {-0.478646,-0.534863},
+  {-1.353538,0.265825},
+  {-0.199615,-1.529628},
+  {-0.219052,1.418831},
+  {-0.138797,0.344504},
+  {0.170086,-0.026321},
+  {-0.196733,0.535114},
+  {-1.033414,-0.221792},
+  {0.028438,0.044914},
+  {-0.884678,0.622154},
+  {0.822835,-2.043658},
+  {0.344915,-1.053158},
+  {-0.644134,-0.574558},
+  {-1.332407,0.519250},
+  {0.036381,0.475286},
+  {-0.303382,0.982412},
+  {-0.353411,0.250417},
+  {0.139548,-0.642938},
+  {1.414632,-0.370112},
+  {0.532912,-0.264381},
+  {0.342811,0.344477},
+  {0.501145,-0.288626},
+  {0.311541,0.560236},
+  {-0.413902,-0.733376},
+  {0.591928,-0.533218},
+  {-0.311692,-0.614243},
+  {0.357470,-1.610867},
+  {-0.400828,-0.474021},
+  {0.291392,1.248851},
+  {0.016993,-0.633725},
+  {-0.525249,0.450546},
+  {0.801819,1.070688},
+  {-1.296271,-0.616623},
+  {-0.393605,-0.448016},
+  {-0.165781,0.199731},
+  {-0.066457,0.457058},
+  {0.245912,0.367495},
+  {-0.614678,0.338112},
+  {0.424687,-0.042103},
+  {-0.016281,0.164701},
+  {-0.388587,-0.005404},
+  {-0.616791,0.044666},
+  {0.164994,-0.591148},
+  {1.130053,0.244749},
+  {-0.764096,-0.677907},
+  {0.001894,0.070851},
+  {0.970162,-0.004036},
+  {0.294438,-0.848449},
+  {-0.085147,-1.038641},
+  {0.146574,-1.020098},
+  {0.731212,1.172352},
+  {-0.966413,0.010182},
+  {0.022011,0.098571},
+  {-0.062500,0.809517},
+  {0.613554,0.896113},
+  {-1.702897,-0.428981},
+  {-0.295817,-0.095047},
+  {0.363999,1.299666},
+  {-0.185637,0.710197},
+  {0.667850,-0.579586},
+  {-0.091486,-1.745092},
+  {0.278540,-0.322231},
+  {-1.393286,0.017571},
+  {-0.909896,-0.550217},
+  {-0.227978,-0.287231},
+  {-0.041531,-0.572542},
+  {0.598923,-1.109982},
+  {0.528515,0.294793},
+  {1.420346,-0.167967},
+  {0.339044,-0.296742},
+  {-0.427926,-0.195084},
+  {2.320888,-0.602119},
+  {0.316394,-0.195310},
+  {0.392226,-0.018758},
+  {-0.347128,-0.012198},
+  {0.885682,0.291685},
+  {0.694113,-0.213884},
+  {1.098109,0.434729},
+  {0.126689,0.353735},
+  {-0.540018,-0.289525},
+  {-0.878448,1.391600},
+  {-0.019977,0.206745},
+  {0.873189,-0.483586},
+  {0.121439,-0.209070},
+  {0.648235,-0.185503},
+  {-0.009043,-0.764272},
+  {0.372579,0.872373},
+  {0.472101,-0.192603},
+  {-0.407035,-0.893065},
+  {-1.367142,-0.975043},
+  {0.746200,-0.328607},
+  {0.388173,-1.625638},
+  {0.884013,-0.528696},
+  {0.705324,0.779519},
+  {0.408395,-0.377831},
+  {1.083901,0.395567},
+  {0.781733,-0.146787},
+  {-0.068884,-0.865584},
+  {0.156537,0.742738},
+  {0.113212,0.987732},
+  {1.521997,0.329659},
+  {-0.192594,-0.352522},
+  {-0.976653,0.187491},
+  {0.817131,0.071363},
+  {0.699118,0.409109},
+  {-0.297057,-0.940273},
+  {-0.936432,-1.106289},
+  {0.626260,-0.241420},
+  {-0.260488,0.166791},
+  {0.701135,-1.061037},
+  {-0.554144,-1.046121},
+  {0.513165,0.663304},
+  {-0.011168,0.147376},
+  {0.037910,1.201414},
+  {0.140816,1.384849},
+  {-0.242984,-1.207828},
+  {-0.107482,0.575915},
+  {0.451083,0.174602},
+  {0.269525,-0.536069},
+  {0.211411,-0.104573},
+  {-0.204415,-0.512769},
+  {0.628925,-0.352539},
+  {1.033395,0.036681},
+  {-0.675614,-0.143876},
+  {-0.621722,-0.934906},
+  {0.211877,-0.248810},
+  {-0.352170,0.551980},
+  {-1.116948,0.321283},
+  {-0.826697,1.581404},
+  {-0.195648,0.310111},
+  {-0.938570,-0.616930},
+  {-0.451007,0.525622},
+  {-0.120274,0.851907},
+  {0.045607,-0.373985},
+  {-0.214821,0.266194},
+  {0.171364,-0.008571},
+  {0.301965,-0.705054},
+  {-1.165181,-0.235733},
+  {-0.650434,-0.274030},
+  {0.122090,0.561616},
+  {0.435428,-0.782393},
+  {-0.004740,-0.125884},
+  {-0.321219,-0.415579},
+  {-1.199688,0.284728},
+  {-0.533240,0.015463},
+  {0.304348,-0.073971},
+  {-0.733804,-0.444715},
+  {-0.725423,0.204256},
+  {0.604231,-0.689961},
+  {-0.756920,-0.218757},
+  {0.956018,0.954204},
+  {0.169414,-0.152566},
+  {0.481613,-0.565409},
+  {0.371303,0.288803},
+  {-0.794294,-1.147211},
+  {-1.706341,0.716376},
+  {-0.627696,0.291968},
+  {-0.121333,-1.001299},
+  {0.550558,-0.282856},
+  {-0.349733,-0.561486},
+  {0.578835,0.339123},
+  {0.420234,-0.741495},
+  {0.144577,0.277881},
+  {0.031130,-0.728796},
+  {-0.564058,1.498556},
+  {1.015670,0.422366},
+  {-0.063266,0.346276},
+  {0.551090,-1.963699},
+  {0.934465,-0.385555},
+  {0.422983,1.159449},
+  {0.101278,-1.667219},
+  {-0.308766,0.332842},
+  {0.150898,-0.097385},
+  {-0.862758,-1.060237},
+  {-0.687885,-1.141096},
+  {-0.862829,-0.505841},
+  {0.558943,-0.778417},
+  {0.549535,-0.363780},
+  {0.072778,0.637066},
+  {0.286029,0.322126},
+  {0.330171,-0.854661},
+  {-1.348837,-0.420251},
+  {-0.198428,-0.371513},
+  {-0.525214,0.301414},
+  {-0.667387,0.022208},
+  {-0.574674,0.529466},
+  {2.371918,-0.496606},
+  {0.257499,-0.783288},
+  {0.156324,0.286932},
+  {0.087484,0.531503},
+  {0.093291,0.317147},
+  {-0.427160,-2.024729},
+  {-0.044421,1.046526},
+  {0.978931,0.464268},
+  {-1.373383,-0.073722},
+  {-2.321501,-0.976402},
+  {0.683655,0.655822},
+  {0.352602,-0.192715},
+  {0.339613,0.269168},
+  {-0.472547,-1.432907},
+  {-0.231035,0.019309},
+  {-0.094858,1.060712},
+  {0.681354,-1.324615},
+  {0.864079,0.416811},
+  {-0.558628,0.087251},
+  {-0.365315,0.133957},
+  {0.107680,2.348517},
+  {0.198383,1.253961},
+  {-1.268406,0.952837},
+  {-0.992758,-0.560084},
+  {0.672959,0.572037},
+  {-0.449041,1.977002},
+  {0.522614,0.339234},
+  {0.085229,-0.360501},
+  {0.640099,0.726865},
+  {-0.091502,-0.015738},
+  {-1.201696,1.035130},
+  {-0.109550,-0.696829},
+  {1.168720,1.005732},
+  {-0.249323,1.263522},
+  {0.724024,0.109230},
+  {0.265328,0.012693},
+  {-0.842707,-1.113746},
+  {-1.256092,-0.822533},
+  {-0.075814,-0.052293},
+  {-0.128797,-0.411582},
+  {-0.653104,-0.788771},
+  {0.939494,0.157740},
+  {1.072504,0.885641},
+  {0.163190,0.818505},
+  {0.706255,0.687324},
+  {0.384361,-0.313490},
+  {0.508228,-1.395336},
+  {0.359982,0.352805},
+  {-0.256236,0.825832},
+  {0.029179,-0.324424},
+  {0.486841,0.728258},
+  {0.817556,0.065814},
+  {1.494148,0.828882},
+  {-0.050180,-0.893645},
+  {-0.636544,-1.178485},
+  {-0.720967,0.391549},
+  {-1.307682,0.078339},
+  {-0.605757,-0.944323},
+  {-0.731348,-0.094258},
+  {0.396463,0.209925},
+  {0.209509,-0.607296},
+  {0.119597,-0.249649},
+  {-0.200995,-0.099649},
+  {-0.567400,-0.345251},
+  {-0.857138,0.181769},
+  {-0.941646,-0.854838},
+  {-1.128753,0.837338},
+  {-0.657241,-0.759242},
+  {-0.188936,0.670672},
+  {-0.306598,-0.482202},
+  {0.912207,-0.517195},
+  {1.164901,-0.427966},
+  {-0.009895,-1.020774},
+  {0.025765,1.322707},
+  {0.150524,1.732201},
+  {-0.439267,-0.498603},
+  {-0.368177,0.524348},
+  {-0.630978,-0.521041},
+  {-0.231973,-0.184883},
+  {0.067075,1.310441},
+  {-0.105442,1.412885},
+  {0.331006,-1.363233},
+  {0.791599,0.084396},
+  {-0.890726,-1.246866},
+  {-0.542651,-0.106851},
+  {0.107314,0.092753},
+  {-0.732606,0.153913},
+  {-0.330158,0.495539},
+  {0.489401,1.064049},
+  {-0.417820,1.261110},
+  {-1.631694,-0.818434},
+  {-0.620724,-0.895058},
+  {0.426467,-1.064865},
+  {0.467471,-0.278711},
+  {0.817514,-0.321221},
+  {0.096475,-0.494918},
+  {0.152146,0.351492},
+  {-0.498145,1.133315},
+  {0.303055,-0.317239},
+  {0.103959,0.019469},
+  {0.092448,0.918901},
+  {-0.993398,0.147710},
+  {-0.995629,0.413023},
+  {1.220671,-1.202642},
+  {0.724379,1.575400},
+  {0.811431,0.466068},
+  {0.499664,-0.880995},
+  {0.558109,0.769554},
+  {-0.702879,-1.050569},
+  {-0.353375,-0.936081},
+  {0.360053,-0.464839},
+  {-0.779252,-0.780140},
+  {0.090785,-0.637723},
+  {-0.304972,0.459278},
+  {0.736270,-0.110646},
+  {-0.109772,0.206927},
+  {-0.478619,-0.042280},
+  {-0.876631,0.510703},
+  {-0.906729,-0.217556},
+  {-1.537449,-0.267733},
+  {-0.978123,-0.957757},
+  {-0.714696,0.975507},
+  {0.812617,-0.332136},
+  {-0.725724,-0.236311},
+  {-0.100842,1.337503},
+  {0.080524,1.176672},
+  {0.771711,-0.341004},
+  {-0.423299,-0.455648},
+  {2.158161,-0.512129},
+  {1.151039,-1.024555},
+  {0.642063,0.018575},
+  {-1.054085,0.401372},
+  {-0.288785,0.630494},
+  {0.347641,-0.610670},
+  {1.408482,0.059692},
+  {-0.379421,-0.208655},
+  {-0.483324,-0.878070},
+  {0.602104,-0.394601},
+  {-0.004706,-0.642013},
+  {-0.358424,-0.253404},
+  {0.411569,-0.129959},
+  {1.228551,0.006102},
+  {0.531607,-0.018854},
+  {-1.380934,-0.627088},
+  {0.547267,-0.039238},
+  {0.746745,0.351671},
+  {0.303177,-0.387336},
+  {-0.796387,-1.614076},
+  {0.464988,0.970223},
+  {0.191287,0.066696},
+  {-0.220325,0.790812},
+  {0.303741,1.089789},
+  {0.448117,-0.011489},
+  {0.419576,0.169210},
+  {0.541446,-0.813073},
+  {-0.746604,-0.394798},
+  {-0.535124,-0.399080},
+  {1.212820,1.210170},
+  {-0.608420,0.220226},
+  {-1.418918,1.368314},
+  {0.931166,0.677711},
+  {0.682432,-0.895030},
+  {-0.693349,0.261801},
+  {0.258131,-2.168849},
+  {0.867516,0.563051},
+  {-0.096511,-0.462814},
+  {-0.689393,-0.230999},
+  {-0.369812,0.249233},
+  {0.046717,0.954072},
+  {-0.032594,0.551930},
+  {-0.766079,-0.071566},
+  {0.793508,-0.748283},
+  {0.241679,0.608403},
+  {0.498824,0.196015},
+  {0.386018,-0.774475},
+  {-0.291054,-0.131220},
+  {-0.436014,0.049768},
+  {-0.006478,0.331976},
+  {-1.126995,0.403371},
+  {0.674118,-1.006190},
+  {0.727574,-0.631312},
+  {0.115880,0.143336},
+  {-0.181566,0.695052},
+  {-0.233203,-0.086295},
+  {0.112809,-0.045588},
+  {0.543264,0.808170},
+  {-0.581874,-0.471845},
+  {0.340867,-0.485032},
+  {0.165312,0.013926},
+  {-0.162445,0.725280},
+  {-0.499103,-1.248448},
+  {0.033577,0.051456},
+  {-1.045131,-0.235899},
+  {-1.110962,-0.102827},
+  {-0.274189,1.259956},
+  {-0.791826,1.100141},
+  {0.324671,0.829447},
+  {0.800825,-0.584404},
+  {0.849667,-0.944107},
+  {0.288553,0.174365},
+  {-0.215377,1.086802},
+  {0.392650,-0.010487},
+  {0.748435,-1.137606},
+  {0.034898,-0.302699},
+  {0.636265,0.119519},
+  {0.837150,-0.690876},
+  {-0.092518,0.354308},
+  {0.084607,-0.381048},
+  {0.970579,0.659439},
+  {-0.564493,-0.616213},
+  {-0.403944,-0.133496},
+  {1.350834,0.527610},
+  {-0.742367,-0.805350},
+  {0.624140,0.366381},
+  {0.005646,-0.563460},
+  {0.268050,-1.292687},
+  {0.547784,-0.463622},
+  {-0.659049,-0.130209},
+  {0.283018,0.527990},
+  {1.418480,1.297302},
+  {0.488656,0.974499},
+  {0.551555,-0.669995},
+  {0.015860,-0.360077},
+  {0.438938,1.527582},
+  {-0.729915,-1.304140},
+  {0.025131,0.002452},
+  {-1.484426,0.708978},
+  {-0.804342,0.051125},
+  {0.990833,-0.309900},
+  {-0.023686,0.762213},
+  {-0.617502,0.277137},
+  {-1.488232,0.224413},
+  {-0.082550,0.224711},
+  {0.610967,-0.436610},
+  {-0.019999,1.299875},
+  {-0.323230,1.244962},
+  {-0.812947,1.719798},
+  {0.333300,-0.174474},
+  {0.115682,-1.155270},
+  {-0.695856,0.388529},
+  {-0.543434,-0.096509},
+  {-0.096049,0.107245},
+  {-0.199971,0.163067},
+  {-0.067111,0.395370},
+  {1.026571,-0.210498},
+  {-0.233456,0.753581},
+  {0.051242,-0.861376},
+  {0.567777,-0.613727},
+  {0.987200,-0.366176},
+  {-0.409966,-0.600319},
+  {-0.021597,-0.362028},
+  {-0.285392,-1.023961},
+  {0.324897,-0.397392},
+  {-0.592783,-1.366636},
+  {1.513069,0.094527},
+  {-0.044122,0.361806},
+  {0.677076,-0.471443},
+  {-0.333290,0.236344},
+  {0.108895,-0.098454},
+  {0.103235,-0.195197},
+  {0.650796,-0.537053},
+  {-0.131204,-0.326541},
+  {0.520322,0.172370},
+  {0.210147,-0.555893},
+  {-1.082301,-0.048132},
+  {-1.964090,-0.466588},
+  {0.328335,-0.553112},
+  {0.708616,0.426767},
+  {1.323439,-0.348617},
+  {0.360543,0.545349},
+  {-0.719946,-0.639191},
+  {0.592925,0.790534},
+  {0.402184,-0.204855},
+  {0.907703,-1.809146},
+  {-0.387200,0.273777},
+  {-1.602303,0.588109},
+  {0.867147,0.107290},
+  {0.824226,0.764841},
+  {-0.538419,-0.797958},
+  {0.814390,0.065650},
+  {-1.453486,-0.528528},
+  {-0.672247,-0.514976},
+  {-0.052375,0.190079},
+  {-0.094941,0.604553},
+  {0.088500,0.393075},
+  {0.195693,0.876814},
+  {-0.184889,-1.487501},
+  {-0.270364,0.104600},
+  {0.102034,0.660195},
+  {-0.091355,-0.465751},
+  {-0.135152,-0.520824},
+  {-0.022116,-0.821371},
+  {0.570832,0.492145},
+  {0.066106,0.238053},
+  {-0.184571,0.890977},
+  {0.288094,-1.019289},
+  {-0.022496,-0.473805},
+  {1.126320,1.508352},
+  {-0.531990,0.461793},
+  {-0.594808,0.080021},
+  {0.290982,-0.692523},
+  {-0.890167,0.818541},
+  {-0.162518,0.512516},
+  {-0.062089,0.662125},
+  {-0.469694,0.836419},
+  {0.590828,-0.375129},
+  {-1.549634,1.352916},
+  {-0.257487,0.526662},
+  {0.554513,-0.496139},
+  {-0.489056,-1.265723},
+  {0.233948,-0.647727},
+  {0.333881,0.673747},
+  {0.721218,0.641171},
+  {0.166479,1.234207},
+  {0.251689,-0.854045},
+  {0.503304,-0.772030},
+  {-0.397815,1.070705},
+  {-0.454466,-0.093432},
+  {0.509756,0.581621},
+  {-0.636769,0.173815},
+  {-0.434115,-0.379772},
+  {0.360372,0.416251},
+  {-0.816916,0.336363},
+  {-0.481516,-0.148237},
+  {-0.344201,1.129372},
+  {-0.745381,-0.145303},
+  {-0.237741,-1.131222},
+  {0.083772,-0.220665},
+  {0.519841,-0.090807},
+  {-0.074125,-0.928286},
+  {-0.280099,-1.361722},
+  {-0.233499,-0.378497},
+  {0.373073,-1.241461},
+  {-1.426124,0.070811},
+  {-0.509544,0.495983},
+  {0.099959,-0.668754},
+  {0.270905,1.556735},
+  {-0.390670,0.537248},
+  {-0.058168,0.187165},
+  {-0.406095,-0.397041},
+  {0.121194,-0.343134},
+  {-0.451420,0.715020},
+  {-0.116938,-0.147192},
+  {-0.333465,0.135991},
+  {-0.741996,-0.453454},
+  {-0.481034,-0.484738},
+  {-0.782498,0.231260},
+  {0.024518,0.585927},
+  {-0.450470,-0.353688},
+  {0.594174,-0.126300},
+  {-0.794772,0.420486},
+  {1.314513,-0.513466},
+  {-0.370453,0.760489},
+  {0.150855,-0.339750},
+  {-0.135993,-0.778609},
+  {-0.276600,-0.086547},
+  {0.113501,-0.451234},
+  {0.807762,-0.310844},
+  {0.789981,0.544938},
+  {-0.304444,0.191596},
+  {-1.155565,-0.682987},
+  {0.312056,1.172277},
+  {0.148072,-0.646764},
+  {-1.017788,0.784066},
+  {0.908108,-2.113397},
+  {-0.647792,-0.940894},
+  {-0.147613,0.439221},
+  {-1.081613,0.980868},
+  {0.632143,-0.374708},
+  {-0.495802,-0.113519},
+  {-0.001556,0.150950},
+  {-1.307628,-0.508955},
+  {-0.300870,0.315066},
+  {-1.083447,-0.140177},
+  {-0.100772,0.376783},
+  {-0.477322,1.014067},
+  {-0.567785,-0.305888},
+  {-0.836664,1.106455},
+  {-0.015276,0.006448},
+  {0.616278,0.239966},
+  {0.030009,-1.107782},
+  {-0.770995,-0.138155},
+  {-0.681094,-0.519193},
+  {-0.882058,-0.080711},
+  {0.248760,-0.979030},
+  {0.000043,-0.366665},
+  {0.400810,-0.085567},
+  {0.641021,-0.084098},
+  {0.533652,0.288318},
+  {0.894862,-0.065116},
+  {0.123370,0.978511},
+  {-0.180674,0.803822},
+  {0.728752,-0.234438},
+  {-1.319526,0.158393},
+  {-0.205442,-0.299613},
+  {-0.383721,-0.335137},
+  {-1.028570,0.223713},
+  {0.932332,-0.634004},
+  {0.157887,-0.980576},
+  {0.889136,0.047845},
+  {-0.087490,-1.077315},
+  {1.004223,-0.574276},
+  {-0.563213,-0.079366},
+  {0.609176,0.143015},
+  {1.007697,-0.230920},
+  {-0.432129,-0.855668},
+  {-0.751450,-0.419138},
+  {-0.531787,0.218861},
+  {1.240797,0.009179},
+  {0.098613,1.024921},
+  {-0.418097,-0.610862},
+  {0.638017,-0.556955},
+  {-0.882736,0.678364},
+  {-0.101406,0.188363},
+  {0.575997,-0.320782},
+  {-0.184244,-0.946120},
+  {0.854262,0.058870},
+  {0.623265,0.222449},
+  {0.026415,0.979594},
+  {0.482302,0.001502},
+  {-0.278778,-0.147706},
+  {0.640003,0.194414},
+  {0.438042,-0.226420},
+  {0.136500,0.092192},
+  {-0.202665,0.686749},
+  {0.522478,0.318777},
+  {-0.913607,0.461100},
+  {0.058242,-0.589196},
+  {-0.125264,0.196658},
+  {0.455045,0.102476},
+  {-0.248191,-0.131455},
+  {-0.497535,0.250805},
+  {0.168700,0.673232},
+  {0.711314,-0.106036},
+  {0.651818,-0.851557},
+  {0.977553,-1.253093},
+  {0.286839,1.317582},
+  {-0.371842,-1.093583},
+  {-0.301749,1.329315},
+  {-0.403959,-0.126875},
+  {-0.217582,0.112597},
+  {0.122512,-0.547045},
+  {0.538957,1.455939},
+  {-0.051608,0.121125},
+  {-0.483043,0.988090},
+  {0.497165,-0.191173},
+  {-0.703290,0.550797},
+  {0.658044,0.757078},
+  {-0.412660,-0.052012},
+  {-0.252273,0.092307},
+  {-1.322972,0.140665},
+  {-0.203724,0.534689},
+  {0.116356,0.483238},
+  {0.554228,1.157456},
+  {0.327654,1.316895},
+  {0.250489,-1.294149},
+  {0.982871,0.689230},
+  {0.192154,-0.292214},
+  {-0.669868,-0.373672},
+  {-1.188747,-0.038297},
+  {-1.090901,0.731469},
+  {0.764236,-0.485868},
+  {0.275150,1.088652},
+  {0.976241,-0.963219},
+  {-0.581240,-1.282012},
+  {0.320197,0.407777},
+  {0.748587,0.046703},
+  {0.467881,-0.329966},
+  {-1.102496,0.283212},
+  {1.062265,1.008907},
+  {-0.606597,0.619235},
+  {-0.156865,-0.044052},
+  {-0.002704,-0.036497},
+  {0.706197,-0.423776},
+  {-0.257156,0.973133},
+  {0.487914,1.074381},
+  {-0.885602,-1.777507},
+  {-0.940260,0.448708},
+  {0.932505,0.236523},
+  {1.804253,0.372704},
+  {-1.578130,0.083653},
+  {-0.626332,1.026166},
+  {1.193807,-0.043563},
+  {-0.505137,-1.317739},
+  {-0.508528,0.107232},
+  {-0.487782,0.645512},
+  {-0.437935,-0.346208},
+  {0.632623,1.393825},
+  {0.487853,0.179346},
+  {0.015868,0.802943},
+  {-0.172107,-0.530354},
+  {-0.438663,0.597939},
+  {-0.523518,-0.769340},
+  {-0.309114,-0.877138},
+  {-0.805692,0.319938},
+  {0.980487,0.415193},
+  {0.086533,-0.000662},
+  {0.083456,0.469788},
+  {2.350354,0.199267},
+  {-1.117492,1.031942},
+  {-1.874684,-1.438324},
+  {-1.506923,-0.254100},
+  {-0.442244,-0.212173},
+  {0.622220,0.078493},
+  {0.442782,0.738116},
+  {0.382808,1.370781},
+  {-0.572913,-0.327280},
+  {0.033002,-1.591756},
+  {-1.011466,-0.707980},
+  {-0.540779,-0.501728},
+  {-0.430794,-0.139464},
+  {0.953393,-0.835771},
+  {-0.569549,-1.511300},
+  {-1.023529,-1.226598},
+  {-0.030465,0.795517},
+  {-0.123311,-0.051937},
+  {-0.428708,-0.079562},
+  {-1.177091,0.332774},
+  {-1.004645,-0.843150},
+  {-0.038739,1.507680},
+  {0.090651,0.221051},
+  {0.109970,0.073002},
+  {1.310602,0.693833},
+  {0.072228,1.417407},
+  {-0.104879,0.467846},
+  {-1.441396,0.816322},
+  {-0.151793,0.678658},
+  {-0.096420,0.855195},
+  {0.430901,1.154121},
+  {-0.250084,-0.013302},
+  {0.587835,0.733677},
+  {0.477520,-0.424982},
+  {-0.504096,-1.402798},
+  {-1.013512,0.267668},
+  {-0.363026,-0.005476},
+  {-0.718136,-0.118798},
+  {-0.446816,-0.602576},
+  {-0.797358,-0.024473},
+  {0.633098,0.624564},
+  {0.021270,1.205089},
+  {0.266963,1.498017},
+  {-0.508527,0.054780},
+  {-0.043710,0.286613},
+  {-0.142768,0.551359},
+  {0.220664,-1.355083},
+  {0.521431,-0.476980},
+  {0.141075,0.083285},
+  {-0.059602,-0.756118},
+  {-0.451512,-0.258693},
+  {-0.730176,1.521289},
+  {-1.362482,0.104512},
+  {0.270994,0.327411},
+  {-0.363492,-0.868879},
+  {0.672515,-0.270446},
+  {-1.342101,0.237073},
+  {0.508772,-0.377732},
+  {-0.713798,-0.466147},
+  {0.368961,0.592551},
+  {0.299261,2.116040},
+  {-0.672263,-0.279814},
+  {-1.007523,1.276007},
+  {0.227684,-0.462034},
+  {0.387360,-0.328996},
+  {0.352344,0.109850},
+  {-0.554321,-0.079454},
+  {-1.105078,0.393291},
+  {1.734659,0.308959},
+  {-0.308866,0.349966},
+  {-0.493334,1.891041},
+  {0.107295,-0.199193},
+  {0.015633,1.669639},
+  {-0.192819,0.360563},
+  {1.300187,0.043971},
+  {-0.195297,-0.619241},
+  {-0.120101,-1.056832},
+  {-0.447948,-0.495157},
+  {-0.326704,-0.483233},
+  {-1.035520,1.157850},
+  {-0.498165,1.806892},
+  {-0.145448,0.642467},
+  {-0.405584,1.352826},
+  {-0.421562,0.606142},
+  {0.294387,1.309778},
+  {-0.154054,0.079388},
+  {0.536240,0.173272},
+  {-0.024006,1.108828},
+  {0.874482,-1.013605},
+  {0.377186,-0.667107},
+  {1.113183,0.945097},
+  {-0.623475,-0.893737},
+  {-0.192779,-1.241070},
+  {0.632202,0.599329},
+  {-0.998820,-0.803084},
+  {1.383370,0.376201},
+  {-0.083581,0.942494},
+  {-0.173566,-0.198364},
+  {0.074235,-0.314876},
+  {-0.556586,0.347212},
+  {0.490005,0.416503},
+  {0.331992,-0.555958},
+  {-0.691485,-0.331265},
+  {-0.796966,-0.358733},
+  {-0.252577,0.543161},
+  {-0.861375,0.772953},
+  {0.133135,1.007422},
+  {0.110358,-0.029927},
+  {-1.330897,0.730045},
+  {0.393907,0.863772},
+  {-0.741439,0.432644},
+  {0.576414,-1.086511},
+  {-0.053779,1.091841},
+  {0.727738,-0.274889},
+  {-0.147372,0.359935},
+  {-1.596102,0.038969},
+  {0.002325,-0.748844},
+  {1.142039,-0.398003},
+  {-0.334125,-0.639994},
+  {0.207807,0.496680},
+  {-0.364096,-0.594810},
+  {1.762264,0.531826},
+  {-0.749354,0.980400},
+  {-1.280578,1.031222},
+  {0.206510,0.566433},
+  {-0.682051,-0.394535},
+  {-0.551294,1.174139},
+  {0.313715,-1.149243},
+  {0.656347,0.386459},
+  {0.735878,0.178740},
+  {-0.293578,-0.287406},
+  {-0.179112,-0.387732},
+  {0.213178,-0.962025},
+  {-0.344776,-0.181182},
+  {0.641578,-0.406269},
+  {-1.401786,-0.171097},
+  {0.286238,-0.125231},
+  {0.252492,-0.547389},
+  {0.120026,0.720419},
+  {1.337138,0.195949},
+  {-0.660370,0.703330},
+  {0.092159,-0.695855},
+  {-0.620594,0.229351},
+  {1.055181,0.111751},
+  {1.006880,0.293700},
+  {-0.093249,0.555442},
+  {-0.399694,0.811308},
+  {-1.684486,-0.633970},
+  {0.080918,0.511860},
+  {-0.439946,0.019865},
+  {-0.390984,-1.044203},
+  {-0.685936,-1.231559},
+  {-0.204744,-0.679722},
+  {-0.859863,0.460715},
+  {-0.246945,0.401049},
+  {0.193542,1.129638},
+  {-0.255188,0.214659},
+  {0.484590,-0.289803},
+  {0.830376,-1.338483},
+  {-0.649905,-0.117391},
+  {-0.796076,-0.304220},
+  {0.353714,0.110796},
+  {1.064357,0.203116},
+  {0.772181,0.613989},
+  {-0.595196,0.130421},
+  {0.714852,-0.201961},
+  {-0.246157,1.317799},
+  {-0.188331,1.819959},
+  {-0.255805,-0.742062},
+  {-0.138330,-0.228130},
+  {0.447635,0.068326},
+  {0.167371,0.023899},
+  {0.541047,-0.398183},
+  {1.279247,-0.892511},
+  {0.970960,-0.571617},
+  {0.064149,-0.440132},
+  {-0.091864,0.479401},
+  {-0.178907,-0.263349},
+  {-0.460228,0.072292},
+  {-0.022178,0.024037},
+  {0.042415,0.943316},
+  {-0.639441,0.125048},
+  {0.773008,1.096997},
+  {0.127606,0.363171},
+  {0.870742,-0.533857},
+  {-0.763648,0.812840},
+  {0.461366,0.041432},
+  {-0.006986,-0.606103},
+  {0.535399,0.207011},
+  {-0.584722,-1.519249},
+  {0.121278,-0.207252},
+  {1.085226,-0.059229},
+  {0.129751,0.594549},
+  {-0.110785,1.298075},
+  {-0.828154,0.282231},
+  {0.357325,0.161702},
+  {-0.286592,0.378964},
+  {0.132628,0.276829},
+  {-0.793980,1.023088},
+  {-0.957162,0.460617},
+  {-0.032594,-0.412238},
+  {0.060784,0.629413},
+  {1.100209,0.447011},
+  {-0.198523,0.062691},
+  {-0.709541,0.204258},
+  {0.020197,-1.320956},
+  {-0.215897,-1.623511},
+  {0.748680,0.160824},
+  {-0.504640,0.232847},
+  {-0.269767,-0.738709},
+  {0.392299,0.153438},
+  {0.160576,-0.386143},
+  {0.357881,0.613915},
+  {-1.268598,-0.067517},
+  {-0.666996,0.396000},
+  {-0.761129,-1.835104},
+  {-0.128240,0.064241},
+  {-0.200634,-0.545752},
+  {0.111993,0.186523},
+  {-0.162610,-0.333088},
+  {-0.548141,0.520658},
+  {0.016143,-0.863869},
+  {-0.569927,1.339376},
+  {0.616225,-0.058848},
+  {-0.664092,-0.932852},
+  {-0.309768,-0.158927},
+  {0.459254,1.205541},
+  {-0.809099,-0.795062},
+  {-0.182439,-0.025138},
+  {-0.916346,-0.341971},
+  {0.829546,-0.066365},
+  {0.855095,-0.587404},
+  {-0.275741,1.185855},
+  {-0.816888,0.228774},
+  {-1.253625,-0.671337},
+  {-0.336773,-0.885292},
+  {-1.419712,0.386946},
+  {0.256469,-0.112479},
+  {-0.195782,0.897473},
+  {-0.448164,0.230629},
+  {-0.137292,-0.954298},
+  {0.044064,-1.420896},
+  {0.346739,-0.728567},
+  {-0.486216,0.932718},
+  {-0.234357,-0.424851},
+  {-0.893944,-1.580683},
+  {0.224420,-0.109758},
+  {-0.525390,-0.659896},
+  {-0.082822,-1.111491},
+  {-0.027127,0.600399},
+  {0.417077,-0.941458},
+  {-0.672273,-0.776712},
+  {-0.375658,-0.673124},
+  {-0.128259,0.669274},
+  {0.274039,-0.162639},
+  {0.531405,0.328816},
+  {-0.173541,-0.344658},
+  {0.109632,-0.652172},
+  {0.745372,-0.988494},
+  {0.323987,0.395099},
+  {-0.220000,-0.137398},
+  {0.004579,-0.872426},
+  {0.251476,-0.625225},
+  {1.333603,-0.551770},
+  {0.081311,-0.544503},
+  {0.326594,-0.007595},
+  {-0.823281,1.430717},
+  {0.572531,0.791617},
+  {0.063804,-0.438730},
+  {-0.804912,-0.338880},
+  {0.533428,-0.017895},
+  {-2.355835,-0.084042},
+  {-0.020945,0.576270},
+  {-1.338558,0.102208},
+  {-1.341976,0.904601},
+  {0.494760,0.485739},
+  {-0.067460,2.005861},
+  {-0.249791,0.460139},
+  {0.735361,0.697345},
+  {-0.007071,-0.683978},
+  {0.116523,-0.146979},
+  {0.082917,-0.544381},
+  {-0.183656,-0.015491},
+  {-0.125475,0.097676},
+  {0.216174,0.367420},
+  {-0.825492,0.033576},
+  {0.392395,0.018111},
+  {-1.196534,-0.398387},
+  {0.858381,-0.236375},
+  {0.427010,-0.140906},
+  {0.549912,1.102720},
+  {0.013097,-0.589424},
+  {-0.486318,-0.182311},
+  {0.597453,0.811553},
+  {-0.394496,0.945556},
+  {0.194762,-0.392322},
+  {-0.245420,-1.255616},
+  {0.591577,-0.107335},
+  {-0.065784,-1.591483},
+  {-0.463762,-0.160668},
+  {-0.789821,-0.048679},
+  {-0.275537,0.448439},
+  {1.110561,1.009790},
+  {0.527317,-1.005654},
+  {1.115740,-0.604145},
+  {-0.557221,1.170167},
+  {0.014607,-0.908701},
+  {0.869524,-0.104916},
+  {0.670785,-0.073642},
+  {0.275557,-0.344125},
+  {-0.677464,0.205771},
+  {1.468200,-2.040479},
+  {-0.644867,-0.260612},
+  {-0.885294,-0.600743},
+  {-1.083463,0.305217},
+  {0.192783,0.054288},
+  {-1.442832,-0.464161},
+  {-0.430593,0.193934},
+  {1.037362,-0.157372},
+  {0.396271,0.148627},
+  {-0.590031,-0.536029},
+  {-0.903929,-0.929530},
+  {0.502786,-0.088813},
+  {0.556812,0.044700},
+  {0.140136,-0.196190},
+  {0.247448,-0.454580},
+  {0.858752,0.511401},
+  {-0.226488,-0.387412},
+  {-0.588826,0.225291},
+  {0.122682,-0.776759},
+  {-0.494520,0.407446},
+  {-0.991127,0.502398},
+  {0.655983,-0.129177},
+  {-1.425441,-0.191821},
+  {-1.341352,0.064542},
+  {-1.072479,1.113384},
+  {0.041286,2.051621},
+  {-0.242983,0.516347},
+  {-0.237060,-1.113874},
+  {-0.023272,1.377334},
+  {-1.899043,0.594030},
+  {0.467479,1.264261},
+  {0.663846,-0.112813},
+  {0.692125,-0.625121},
+  {-0.298478,-0.083012},
+  {-0.964078,-0.081148},
+  {-0.470905,0.411913},
+  {1.474979,-0.154895},
+  {0.661302,-0.012302},
+  {-0.965442,0.514810},
+  {0.318276,0.457882},
+  {-0.542257,-1.222535},
+  {0.062860,0.023413},
+  {0.085049,1.158655},
+  {1.247453,-0.154635},
+  {0.178202,0.204762},
+  {0.844883,0.791503},
+  {0.233726,-0.984440},
+  {0.164056,0.642663},
+  {-0.322448,0.327553},
+  {-0.126490,0.319918},
+  {-0.158159,-1.372744},
+  {1.298184,-0.764151},
+  {0.018998,0.522201},
+  {-0.962200,0.169821},
+  {-0.176380,1.186852},
+  {-0.034894,0.510674},
+  {0.098506,-0.900306},
+  {0.336179,-0.133751},
+  {0.337938,0.195812},
+  {0.012498,0.889530},
+  {-0.625594,-0.298426},
+  {0.694907,0.251068},
+  {-0.113195,0.672439},
+  {-0.753666,0.051040},
+  {0.141270,0.049792},
+  {-0.067074,0.245343},
+  {-1.587448,-1.120145},
+  {0.136902,0.397052},
+  {0.012719,0.888125},
+  {-0.899053,-0.232361},
+  {-0.572945,0.118157},
+  {0.689248,-0.024022},
+  {-0.369033,1.314103},
+  {1.171046,-0.441653},
+  {0.148432,0.000953},
+  {0.474619,1.318479},
+  {-0.789100,-0.189436},
+  {1.168206,-0.870973},
+  {-0.471363,0.375174},
+  {0.506161,-0.536559},
+  {1.423200,0.042084},
+  {-0.929433,-1.633785},
+  {-1.295439,0.135491},
+  {-1.538034,-0.008372},
+  {-1.271645,-1.051796},
+  {0.554905,-0.373024},
+  {-0.643509,-0.327706},
+  {-0.419714,1.107479},
+  {0.466287,-0.239969},
+  {-0.653212,0.139871},
+  {-1.451830,-0.344354},
+  {-0.907859,-0.216021},
+  {0.944616,0.366605},
+  {0.059977,0.109431},
+  {1.031953,-1.164485},
+  {0.449597,-2.254492},
+  {-0.703591,-0.293462},
+  {0.705176,0.000026},
+  {0.129751,-0.129761},
+  {-0.500724,0.070967},
+  {0.708266,-0.279742},
+  {0.057621,-0.165775},
+  {-0.918908,0.311085},
+  {0.103258,0.736145},
+  {0.327648,0.004814},
+  {-0.462488,-1.311553},
+  {-0.800705,-0.250875},
+  {0.725654,-0.503263},
+  {0.070847,0.104229},
+  {-0.617014,-0.723182},
+  {-1.389549,-0.393330},
+  {0.968007,-0.009708},
+  {0.139527,1.299372},
+  {0.248082,0.601290},
+  {0.953040,-0.996260},
+  {1.309783,-1.016336},
+  {-0.934166,0.729653},
+  {-0.388471,0.682112},
+  {-0.240315,0.888481},
+  {-1.098614,-0.034184},
+  {-0.421662,-0.755789},
+  {0.307964,0.867011},
+  {0.444477,0.930219},
+  {1.603805,-0.402639},
+  {-0.089754,1.413485},
+  {0.230484,0.488389},
+  {0.354216,0.348765},
+  {-0.322557,-0.563235},
+  {-0.185066,0.795538},
+  {-0.550469,0.168640},
+  {-0.331680,-0.810292},
+  {-0.678005,-0.138885},
+  {0.888325,0.259799},
+  {-0.261157,1.314246},
+  {-0.724085,0.698159},
+  {-0.487339,0.343089},
+  {0.256545,0.306148},
+  {1.087370,1.360731},
+  {0.909221,0.906951},
+  {0.840193,0.271044},
+  {-0.449186,-0.712406},
+  {-0.100897,-0.905420},
+  {-1.281902,-0.335234},
+  {0.740303,0.011500},
+  {0.899467,-0.124748},
+  {0.536766,-0.366208},
+  {-0.643354,0.691747},
+  {-0.261056,-0.256182},
+  {0.272516,-0.258403},
+  {0.631447,-0.167719},
+  {-0.196437,-0.052842},
+  {1.508024,-0.936465},
+  {-0.180365,-1.378710},
+  {-0.249668,0.002152},
+  {1.598053,1.741993},
+  {-1.056432,0.117693},
+  {0.515300,1.069078},
+  {-0.212007,-1.048830},
+  {0.335613,0.489364},
+  {-0.796184,-1.069425},
+  {0.083158,0.697802},
+  {-1.235153,-0.772422},
+  {-0.357202,-0.012821},
+  {-0.593893,-1.181373},
+  {0.050524,-0.401930},
+  {0.074720,0.364095},
+  {-0.079716,-1.693522},
+  {0.100870,-0.312204},
+  {0.947544,0.242623},
+  {-0.643159,-0.717020},
+  {0.224527,0.733617},
+  {0.216476,1.876947},
+  {0.332304,-0.401619},
+  {1.189563,-1.382521},
+  {0.908890,-0.674780},
+  {0.437119,-0.298161},
+  {-0.058059,-0.200793},
+  {0.362838,0.619364},
+  {0.117785,0.015330},
+  {-1.151039,-0.121108},
+  {-0.542608,0.263258},
+  {-0.605341,1.175677},
+  {-0.526847,0.683678},
+  {-0.003684,-0.546691},
+  {0.101077,-0.028945},
+  {-0.699619,0.028653},
+  {-0.287565,0.909150},
+  {-0.003493,0.475101},
+  {0.110908,-0.450847},
+  {0.822169,-0.268593},
+  {-1.331173,0.303365},
+  {0.354079,1.195309},
+  {1.074010,-0.113039},
+  {1.358327,0.349989},
+  {0.328412,0.126190},
+  {0.251235,0.427830},
+  {-0.681032,-0.654465},
+  {0.947471,-0.314890},
+  {-0.506438,0.044035},
+  {0.437633,-0.586149},
+  {0.108011,0.609608},
+  {-0.313954,0.566877},
+  {-0.057536,-1.682225},
+  {0.588066,0.182714},
+  {1.063758,-0.640294},
+  {0.843978,-0.415465},
+  {1.201541,1.527708},
+  {-0.299630,-0.584595},
+  {0.591297,0.504796},
+  {-0.056764,-0.947796},
+  {-0.517348,-0.289759},
+  {-0.288464,0.617447},
+  {0.348633,-1.043987},
+  {0.054553,-0.520532},
+  {-0.090965,-0.147650},
+  {0.086384,-0.577068},
+  {-0.102547,-1.253433},
+  {0.635189,0.519118},
+  {-0.720591,-1.495902},
+  {0.080849,0.205010},
+  {0.751958,-0.190846},
+  {-0.538937,-0.320929},
+  {-0.612417,0.554560},
+  {-0.851261,0.869392},
+  {1.198195,-0.529736},
+  {0.057548,-0.579206},
+  {-1.025654,-0.151350},
+  {0.303841,-0.211254},
+  {0.446343,-1.552067},
+  {0.315397,-0.808794},
+  {-0.063785,0.774825},
+  {0.783816,-0.157279},
+  {-0.693511,0.332481},
+  {-0.234900,0.528764},
+  {0.596556,0.333542},
+  {1.373749,-0.817280},
+  {-0.295436,-0.145692},
+  {0.006813,0.157722},
+  {0.516578,-0.790212},
+  {0.478924,-0.959898},
+  {0.370258,0.489034},
+  {0.713319,-0.586588},
+  {0.332856,0.078227},
+  {-0.425185,-0.677807},
+  {-0.149519,0.199877},
+  {1.263811,-0.509766},
+  {0.233085,-0.479083},
+  {0.856984,0.232124},
+  {-0.398816,0.118417},
+  {0.725782,0.573860},
+  {-0.423177,-0.195038},
+  {0.479589,-0.152071},
+  {-0.606474,1.399722},
+  {-2.041557,0.729519},
+  {-0.617790,-0.668932},
+  {0.137657,-1.422402},
+  {-0.786831,-0.619224},
+  {-0.149759,-0.165667},
+  {0.190154,0.929670},
+  {-0.287768,1.169585},
+  {1.061637,0.067450},
+  {-0.140288,-0.424489},
+  {0.785589,-0.241400},
+  {-0.992917,0.456275},
+  {0.543095,-0.526169},
+  {0.262447,0.354750},
+  {0.115837,-1.383394},
+  {-0.765803,-0.645191},
+  {0.382408,-0.004403},
+  {0.124288,-0.280736},
+  {1.156532,0.881587},
+  {1.088618,0.321389},
+  {-2.279889,-0.488846},
+  {-1.135730,0.591114},
+  {-1.093988,-0.708227},
+  {-0.153356,0.947910},
+  {0.191071,-0.367728},
+  {0.332287,0.126137},
+  {-0.150579,-0.128056},
+  {-0.515071,1.279206},
+  {-0.471647,0.450751},
+  {-0.177599,0.084528},
+  {0.405248,-1.192993},
+  {-1.199598,-1.871218},
+  {-1.009935,0.125214},
+  {0.860742,-0.062698},
+  {-0.657040,-1.041627},
+  {0.026116,-0.059837},
+  {-1.346135,1.113968},
+  {-0.624805,0.301187},
+  {0.274945,0.937253},
+  {0.478006,0.733921},
+  {-0.612665,-0.715399},
+  {-0.016013,0.268927},
+  {0.319591,0.208865},
+  {1.344190,-0.216045},
+  {0.130151,1.142744},
+  {0.172902,-0.626551},
+  {-1.349281,-0.008253},
+  {0.621623,0.463895},
+  {0.184316,0.698054},
+  {-0.585348,-1.744754},
+  {0.109077,0.127077},
+  {0.216486,0.290303},
+  {0.785660,0.927775},
+  {0.384514,-0.692532},
+  {0.727702,-0.034449},
+  {-0.057908,0.127263},
+  {0.271526,0.524594},
+  {-0.858654,-0.086733},
+  {0.464001,0.064140},
+  {0.227926,1.431933},
+  {0.138844,0.005704},
+  {0.141627,-0.127211},
+  {-1.003825,0.034579},
+  {-0.388278,0.179387},
+  {0.158985,0.905558},
+  {-1.242335,0.519667},
+  {-0.047141,0.947802},
+  {0.336262,-1.612058},
+  {0.614542,-0.464413},
+  {0.982166,-1.628173},
+  {-0.870128,-0.651271},
+  {0.486409,0.436105},
+  {0.108930,1.638884},
+  {-0.021817,-0.425794},
+  {0.039699,-0.387185},
+  {-1.225415,-0.377385},
+  {0.391090,-0.505627},
+  {0.651504,-0.883661},
+  {-0.276837,0.691315},
+  {0.383239,0.054891},
+  {0.297223,-0.197196},
+  {1.388005,-0.270560},
+  {-1.400360,0.278525},
+  {-2.093290,0.098416},
+  {0.610011,1.401331},
+  {-0.945061,-0.541204},
+  {0.412258,-1.330328},
+  {0.173694,-1.109422},
+  {-0.159121,-1.744757},
+  {0.285345,1.096001},
+  {0.128427,-0.244146},
+  {0.067905,-0.156659},
+  {-1.018499,-0.578789},
+  {0.505971,0.765807},
+  {1.015914,0.376986},
+  {0.790707,-1.646495},
+  {0.487164,-0.607104},
+  {-0.697297,-0.367804},
+  {-0.565402,0.674289},
+  {1.188518,0.712744},
+  {-0.592933,-0.373505},
+  {-0.203660,1.226443},
+  {-0.098045,-0.097690},
+  {0.433178,-1.020054},
+  {-0.430052,-0.776739},
+  {0.324026,-0.937248},
+  {0.701878,-0.493328},
+  {0.230826,0.826293},
+  {0.004731,0.068967},
+  {-0.498959,0.400514},
+  {-0.513084,-1.025155},
+  {0.421206,-1.417798},
+  {-0.981820,-0.435834},
+  {0.506125,0.020348},
+  {-0.235266,-0.135010},
+  {0.838326,-0.650392},
+  {-0.396983,-0.682428},
+  {0.182128,0.408830},
+  {0.727117,-0.622519},
+  {-0.068542,0.310867},
+  {0.442916,0.767343},
+  {0.044007,-1.159112},
+  {0.493622,-0.162111},
+  {0.380900,-1.503298},
+  {0.423037,0.548507},
+  {-1.568571,0.528272},
+  {0.547764,-0.029898},
+  {-0.356876,0.578955},
+  {0.515241,0.565923},
+  {0.167784,1.612647},
+  {0.169705,0.087695},
+  {1.177100,0.004351},
+  {-0.689952,0.053029},
+  {0.154453,1.419159},
+  {-0.546385,1.058132},
+  {0.021626,-0.754253},
+  {0.741607,-0.361204},
+  {-0.057849,0.999592},
+  {-0.015000,1.519017},
+  {-0.384562,0.938159},
+  {1.000041,1.295279},
+  {-1.069485,-0.177887},
+  {-0.656125,-0.402525},
+  {-0.338546,0.308619},
+  {-0.201887,0.631236},
+  {-0.576348,-1.438422},
+  {0.094374,-0.332953},
+  {1.717504,0.411315},
+  {-0.139432,0.242414},
+  {1.030451,-0.541582},
+  {-0.132491,0.928665},
+  {-0.929343,0.330223},
+  {0.212063,-0.999967},
+  {-1.546734,1.473279},
+  {0.895231,-0.122118},
+  {-0.024873,0.397475},
+  {-0.471758,0.171216},
+  {-0.384773,0.411799},
+  {1.604132,0.192566},
+  {-0.352284,-1.692873},
+  {-0.127207,-0.166561},
+  {-0.087210,-0.289254},
+  {0.069733,0.733600},
+  {-0.481091,-0.748068},
+  {0.025913,-0.282440},
+  {0.385995,-0.269872},
+  {0.807898,0.547847},
+  {0.920522,-0.253019},
+  {0.590344,0.287209},
+  {-0.264166,-1.420356},
+  {0.741891,-0.453230},
+  {-0.005511,-0.334318},
+  {0.584215,-0.105380},
+  {1.235921,0.737084},
+  {0.073373,0.196251},
+  {0.050188,0.318437},
+  {0.326590,0.608379},
+  {-0.322564,0.284616},
+  {-0.646108,-0.359319},
+  {0.322070,0.143369},
+  {-0.863728,-0.775195},
+  {0.831176,0.342701},
+  {0.032958,-0.098237},
+  {0.571168,-0.012336},
+  {0.182689,0.790901},
+  {-0.425154,-0.855671},
+  {-0.898454,0.187687},
+  {-0.526788,0.506000},
+  {0.653615,0.022943},
+  {-0.027712,0.795147},
+  {-0.439436,0.442340},
+  {0.706258,-1.337857},
+  {0.478575,0.834826},
+  {-1.198496,-0.435258},
+  {-0.626551,-0.689605},
+  {0.463850,-1.046754},
+  {0.616860,0.015892},
+  {-0.036480,-0.180819},
+  {-0.850951,0.360575},
+  {-0.778725,0.021580},
+  {-0.003573,0.011854},
+  {0.901575,1.139995},
+  {-1.397778,-0.965160},
+  {0.828026,-0.382807},
+  {-0.014620,0.930159},
+  {-1.300195,-0.110779},
+  {0.749689,0.981340},
+  {0.030482,0.848674},
+  {0.187375,-0.097744},
+  {0.209488,-0.196027},
+  {0.347616,-0.395632},
+  {0.329045,0.511381},
+  {1.124516,-0.961421},
+  {-0.221487,-0.120998},
+  {-1.498910,1.138313},
+  {-0.900081,0.195057},
+  {0.353490,-0.370964},
+  {0.461766,-0.958569},
+  {-0.156196,-1.009013},
+  {-0.303470,0.211825},
+  {0.970393,0.376784},
+  {0.495209,0.940894},
+  {-0.760660,-0.732722},
+  {-0.277112,-0.555909},
+  {0.336774,-0.081721},
+  {-0.764784,1.256559},
+  {0.729786,0.187455},
+  {-1.516521,-0.580250},
+  {-0.060807,1.773198},
+  {0.384536,-0.806667},
+  {-0.704657,-0.622280},
+  {-0.801176,0.052175},
+  {-0.590213,1.990490},
+  {-0.177006,-0.136596},
+  {-0.043811,-1.299593},
+  {-0.581471,0.077527},
+  {0.234488,-0.891170},
+  {-0.346771,1.199070},
+  {0.082643,1.293400},
+  {0.936822,0.025082},
+  {-0.731120,-0.476702},
+  {-0.934721,-0.022417},
+  {0.222389,0.501521},
+  {-0.120435,0.461318},
+  {-0.065142,0.306212},
+  {0.295570,-0.442311},
+  {0.993401,0.404579},
+  {-0.453363,0.509552},
+  {0.282236,0.306297},
+  {-0.536249,-0.901250},
+  {-0.425114,0.194843},
+  {-0.519253,1.853919},
+  {-0.710138,0.608713},
+  {0.021883,-0.406892},
+  {-0.119297,1.104563},
+  {-1.009286,0.692377},
+  {-1.312874,0.446078},
+  {0.820048,0.144155},
+  {0.594350,-0.518111},
+  {0.445168,-0.296112},
+  {0.528797,0.275437},
+  {-0.975129,1.054113},
+  {-0.141110,-0.278283},
+  {-1.108218,0.758768},
+  {-0.720411,0.105147},
+  {0.012397,0.377536},
+  {-0.600491,-0.143086},
+  {-0.953860,-0.409408},
+  {0.207974,-0.533590},
+  {0.505393,-0.929868},
+  {0.693728,-0.168896},
+  {1.295575,0.330245},
+  {0.197670,-0.003298},
+  {-0.644899,-0.599500},
+  {0.369732,-0.579213},
+  {-0.403831,-1.208236},
+  {0.102628,0.417057},
+  {0.225578,1.013419},
+  {-0.251294,-0.004769},
+  {0.889491,1.815880},
+  {-1.038993,0.521891},
+  {0.764166,-0.213457},
+  {-0.562020,-1.509213},
+  {0.211293,-0.936981},
+  {-0.463538,1.090030},
+  {-0.553620,-0.791400},
+  {0.611880,-0.306484},
+  {0.044468,-0.166676},
+  {-0.023328,-1.778915},
+  {-0.214294,-0.414020},
+  {-0.756939,-1.513298},
+  {0.250125,-0.882986},
+  {1.120913,-0.169637},
+  {0.645831,-0.162204},
+  {1.177705,-0.888318},
+  {0.363945,-0.029949},
+  {0.402238,-0.546777},
+  {-0.094455,-0.101378},
+  {0.164174,0.060548},
+  {-0.169991,-1.176339},
+  {-0.374419,-0.123020},
+  {-0.914397,-0.405280},
+  {-0.853371,-0.380429},
+  {1.609595,1.394657},
+  {0.488861,0.494798},
+  {0.158526,0.345015},
+  {0.803121,0.150331},
+  {-0.081292,0.181697},
+  {0.393064,-0.478711},
+  {0.279182,0.092095},
+  {0.430334,-0.073225},
+  {0.014806,0.588098},
+  {0.913267,0.970571},
+  {0.646704,0.609592},
+  {0.566444,0.775254},
+  {-0.335177,1.080688},
+  {0.127562,1.140199},
+  {0.165559,-0.264557},
+  {-1.069915,-0.891586},
+  {0.507922,-0.743511},
+  {-0.734341,1.039713},
+  {-0.738939,-0.058723},
+  {0.759593,-1.014583},
+  {0.555667,-1.733928},
+  {-1.367914,-1.030299},
+  {0.188542,-0.418601},
+  {0.793444,-0.741383},
+  {-0.040384,0.198946},
+  {1.361842,-0.048743},
+  {-0.225959,0.500185},
+  {-0.613758,-0.930241},
+  {-1.065079,-1.626019},
+  {-1.661331,0.447628},
+  {-1.178209,-1.594785},
+  {0.385772,0.687990},
+  {0.320431,0.326874},
+  {-0.209635,0.241160},
+  {-0.478316,-0.322029},
+  {-1.574782,0.928755},
+  {-0.150281,0.335387},
+  {0.346979,0.106675},
+  {-0.979085,-0.448834},
+  {-0.484871,-0.130679},
+  {-0.882404,-0.284669},
+  {-0.135947,1.428153},
+  {0.289974,0.663804},
+  {-0.832558,-0.786738},
+  {0.566306,1.650858},
+  {-0.618622,-0.104784},
+  {-0.597685,-0.212515},
+  {1.865293,1.206891},
+  {0.617878,-0.378103},
+  {-0.276038,1.353459},
+  {0.879395,0.084117},
+  {-0.648554,-0.500746},
+  {0.603251,-0.759062},
+  {-1.056790,0.769620},
+  {0.451470,-0.190342},
+  {1.668428,-1.349133},
+  {-0.399983,-1.187873},
+  {-0.876715,0.206248},
+  {0.800569,-0.255028},
+  {0.108497,1.535395},
+  {-0.321630,0.307984},
+  {-0.010085,-1.543582},
+  {0.733422,-0.807197},
+  {-0.527735,0.361278},
+  {0.546397,-0.913698},
+  {0.386942,-0.026931},
+  {-0.683948,1.644054},
+  {-0.713074,-0.760496},
+  {0.729880,0.611484},
+  {-0.324111,-0.185442},
+  {0.513507,0.655970},
+  {0.973032,0.708102},
+  {0.162839,-1.911128},
+  {0.171333,0.442628},
+  {0.793978,0.363283},
+  {0.139764,-0.553196},
+  {1.477350,0.571024},
+  {0.046847,-0.083842},
+  {0.774276,0.538647},
+  {-1.232450,-0.279392},
+  {0.998783,0.699271},
+  {-2.497752,0.890340},
+  {-0.686000,-0.489450},
+  {-0.622210,0.728997},
+  {-0.896078,-0.269973},
+  {0.254307,0.947307},
+  {1.029120,0.030115},
+  {-0.457637,0.586413},
+  {-0.570341,0.796948},
+  {-0.326200,0.703162},
+  {0.718013,-0.641897},
+  {-0.347796,-0.117920},
+  {0.980266,-0.427121},
+  {0.715130,0.436598},
+  {-0.354809,-0.981161},
+  {0.609447,0.117866},
+  {-1.117899,1.185150},
+  {-0.070233,0.421426},
+  {0.362961,-0.220281},
+  {0.091918,-0.947668},
+  {-0.918369,0.893874},
+  {1.165251,0.420864},
+  {1.432566,-0.178810},
+  {-0.356868,-0.188257},
+  {-0.815491,-0.404427},
+  {-1.070312,-1.216305},
+  {-0.318984,-0.583511},
+  {1.848678,0.453940},
+  {-0.708129,0.177312},
+  {-0.893931,1.710539},
+  {0.093921,0.348349},
+  {1.105949,0.999284},
+  {0.967769,-0.721817},
+  {0.937282,0.156570},
+  {1.436906,1.511836},
+  {0.508619,-0.010131},
+  {-0.069583,-0.309253},
+  {0.108287,0.135978},
+  {-0.739620,-0.139477},
+  {-0.651608,1.778285},
+  {0.027295,-0.276027},
+  {0.751467,0.405693},
+  {-0.350001,1.687277},
+  {0.358628,-0.135793},
+  {1.669210,-0.094304},
+  {0.563354,0.389800},
+  {-0.248111,-0.198466},
+  {0.074279,-0.311566},
+  {0.205118,-0.722409},
+  {0.284728,0.431713},
+  {-0.299721,0.775480},
+  {0.288778,1.204617},
+  {-2.612038,1.096907},
+  {0.138972,0.125366},
+  {0.298215,0.304176},
+  {-0.193236,1.529766},
+  {0.485275,-0.982963},
+  {0.725341,-0.936405},
+  {-0.065237,0.208370},
+  {0.125534,-0.205573},
+  {-1.821296,0.674082},
+  {-0.275038,0.327760},
+  {-0.727191,-1.227306},
+  {-0.865239,0.939065},
+  {-0.803833,1.620915},
+  {-0.842433,-1.108209},
+  {-0.401148,-0.736410},
+  {-0.115040,-1.629236},
+  {-2.049102,-0.888722},
+  {0.563586,-1.881832},
+  {0.500135,0.870559},
+  {-0.623029,-1.087557},
+  {0.560799,-0.777685},
+  {-0.023666,-0.920057},
+  {0.514122,-0.387123},
+  {0.330311,-0.267867},
+  {0.141501,-0.770913},
+  {0.895122,1.295559},
+  {0.235886,-0.142025},
+  {-1.600266,1.392146},
+  {0.062394,-0.199017},
+  {0.105093,0.847228},
+  {-0.004692,-0.611023},
+  {-1.105202,-0.676440},
+  {-0.803199,0.080607},
+  {1.068037,-1.432548},
+  {-0.073955,0.534296},
+  {-1.544967,-0.292418},
+  {-0.018596,0.600587},
+  {0.693918,0.111383},
+  {0.875333,0.538827},
+  {0.810163,0.603066},
+  {-0.991128,0.633334},
+  {1.410649,-0.273373},
+  {-1.402586,0.048299},
+  {-0.476167,-0.040214},
+  {1.133741,0.893093},
+  {-1.976746,0.495152},
+  {-0.762297,-0.434453},
+  {-0.407391,0.458918},
+  {0.081289,-0.693117},
+  {-0.901769,-0.566278},
+  {0.294244,0.018293},
+  {-1.778410,0.169995},
+  {-0.065897,-0.565356},
+  {-0.067741,-0.386928},
+  {-0.042227,-0.470778},
+  {-0.724262,-0.448146},
+  {0.799391,-0.353504},
+  {0.736085,-0.189575},
+  {-0.170609,-0.001362},
+  {-0.876784,-0.416884},
+  {-1.194944,-1.159666},
+  {0.378294,-0.050373},
+  {2.029991,0.034750},
+  {0.488729,0.272216},
+  {0.100163,0.084453},
+  {0.619746,0.787200},
+  {1.516011,0.190597},
+  {0.242183,-0.282804},
+  {1.348479,0.195434},
+  {1.574083,0.044098},
+  {-1.648078,0.005385},
+  {-0.240798,0.327597},
+  {-0.072394,-0.742375},
+  {-0.357626,-0.537052},
+  {-1.019427,-1.502025},
+  {0.265137,1.275985},
+  {-1.408237,0.487417},
+  {0.488564,0.094077},
+  {0.538473,0.089383},
+  {0.822984,-0.041699},
+  {0.446649,0.965423},
+  {0.425275,0.258184},
+  {0.293588,-0.009747},
+  {-1.901312,0.094518},
+  {0.055270,0.104028},
+  {0.717610,-0.083141},
+  {-1.028907,0.529666},
+  {0.276336,-1.707147},
+  {0.518490,0.271655},
+  {-0.157786,-0.735939},
+  {-0.642959,0.105473},
+  {-0.194654,0.744489},
+  {1.057427,0.578372},
+  {-0.078556,0.535382},
+  {0.275007,0.425924},
+  {-1.493477,0.323239},
+  {0.384662,-0.732389},
+  {-0.458062,-0.246727},
+  {-0.009941,-0.256232},
+  {-0.431288,0.694332},
+  {1.237922,-0.196164},
+  {0.049717,-0.417202},
+  {-0.828197,0.209999},
+  {-1.328594,-0.698908},
+  {0.817510,1.298454},
+  {0.021412,-0.376025},
+  {0.656062,-0.479696},
+  {0.739794,-0.697219},
+  {0.359927,0.330324},
+  {0.490626,-1.394430},
+  {0.003006,-0.052538},
+  {0.188833,0.728305},
+  {-1.187172,0.758908},
+  {-0.519732,-1.148840},
+  {-0.411235,-1.217214},
+  {0.955021,-0.430176},
+  {-0.523480,-0.587903},
+  {-1.227340,0.033012},
+  {0.122805,-0.649916},
+  {0.990446,-0.160799},
+  {0.217109,0.439570},
+  {0.197974,-0.855599},
+  {-1.016884,-0.834066},
+  {-0.685161,0.797699},
+  {0.718871,0.735908},
+  {-2.084638,-0.653982},
+  {0.229928,0.252590},
+  {0.876971,-1.135835},
+  {0.208727,-1.096199},
+  {0.189714,0.324005},
+  {0.559235,0.891645},
+  {-0.337588,1.226503},
+  {-0.633028,1.304579},
+  {0.352611,0.118112},
+  {0.755508,-1.202909},
+  {-0.368064,0.379022},
+  {0.187482,0.040502},
+  {-0.489215,-0.316624},
+  {-0.148897,1.794500},
+  {0.617933,0.380534},
+  {0.724284,0.929908},
+  {-0.101068,0.829591},
+  {0.239707,0.830689},
+  {1.419880,-0.703233},
+  {0.428630,-0.738185},
+  {0.188227,-0.067175},
+  {0.848946,-0.139604},
+  {1.358890,-0.759908},
+  {-0.598246,-1.356423},
+  {0.708571,-0.747022},
+  {-1.307309,-1.158771},
+  {1.114919,0.003653},
+  {0.247448,0.759891},
+  {0.629880,-0.013493},
+  {0.581883,-0.841438},
+  {-0.348783,0.559365},
+  {0.553004,0.045767},
+  {-0.689707,0.334441},
+  {0.783204,0.262356},
+  {1.422351,-0.205031},
+  {2.033491,0.619792},
+  {-0.663187,-0.541048},
+  {0.546304,0.061896},
+  {0.954720,1.149216},
+  {-0.559310,0.175198},
+  {1.274649,1.348253},
+  {-0.247850,-0.207347},
+  {1.742038,1.103291},
+  {0.043844,-0.424239},
+  {0.614981,-0.080676},
+  {-0.517806,1.025811},
+  {0.801125,-0.606164},
+  {0.473503,0.520220},
+  {-0.308974,0.331494},
+  {-1.295514,-0.646832},
+  {-0.472990,-0.230161},
+  {0.174489,-0.366097},
+  {-0.118363,-0.163279},
+  {-0.200880,-0.899742},
+  {0.998390,-0.199202},
+  {-0.622541,-0.695766},
+  {0.669754,-0.206478},
+  {0.106122,0.549600},
+  {0.591344,0.214104},
+  {0.488377,0.644834},
+  {1.136572,1.169122},
+  {0.323891,0.444824},
+  {-0.562209,-0.060314},
+  {0.213956,-1.280496},
+  {-0.321971,-1.103028},
+  {0.672409,-0.083641},
+  {0.495207,0.706465},
+  {-0.494982,1.309929},
+  {0.994709,-0.975631},
+  {0.059966,-0.007228},
+  {1.295286,0.210362},
+  {-1.155912,0.093655},
+  {-0.270843,0.470326},
+  {0.756844,0.345241},
+  {0.514597,0.140073},
+  {-0.621769,0.148131},
+  {0.357821,-0.203675},
+  {-0.273598,-0.884954},
+  {-0.849266,-0.397208},
+  {-0.405585,-1.645132},
+  {-0.010028,-0.355219},
+  {-0.143243,0.535060},
+  {-0.489155,0.541734},
+  {-1.917934,0.442072},
+  {1.120600,0.609251},
+  {-0.806215,-0.431671},
+  {1.317120,-1.219868},
+  {0.067240,1.040216},
+  {-0.567193,-1.387665},
+  {0.795042,0.402961},
+  {-1.025794,-0.277941},
+  {0.649983,1.281336},
+  {-0.256848,0.005927},
+  {0.607023,0.715590},
+  {0.540951,-0.424004},
+  {-0.353391,1.289066},
+  {1.755964,-0.674437},
+  {-0.664991,-0.691634},
+  {-0.096792,0.422837},
+  {-1.167967,0.555492},
+  {0.152719,-0.072909},
+  {0.116643,0.226822},
+  {-0.630662,-0.558520},
+  {0.414169,-0.530572},
+  {0.717343,-0.343964},
+  {0.485011,-0.965124},
+  {0.132872,-1.176696},
+  {-0.542650,-0.059320},
+  {-0.771646,-0.399126},
+  {-0.848580,0.963529},
+  {0.186147,0.262803},
+  {0.352650,0.664986},
+  {0.993840,0.913475},
+  {-0.484132,-0.800343},
+  {0.680518,0.491133},
+  {-0.187661,0.025441},
+  {-0.647229,0.234518},
+  {1.007825,-0.196186},
+  {0.956857,-1.015468},
+  {-0.722691,-1.369092},
+  {0.254518,0.088674},
+  {0.029979,-0.009861},
+  {0.301615,0.155056},
+  {0.039314,0.343316},
+  {0.145456,1.183385},
+  {0.775872,0.441937},
+  {-0.305562,-1.261231},
+  {-0.509677,-1.261546},
+  {-0.452788,-0.152168},
+  {-0.024417,0.566667},
+  {0.156338,0.402470},
+  {0.451700,-0.516105},
+  {0.517440,0.675626},
+  {0.108431,0.416795},
+  {-0.764284,-0.532834},
+  {1.206985,0.069426},
+  {-0.932342,1.046480},
+  {-0.777393,0.052027},
+  {-1.092549,0.033582},
+  {0.197445,-0.491148},
+  {-0.411677,-0.336139},
+  {-0.037210,-0.926280},
+  {-0.708483,0.693739},
+  {0.664921,-1.385649},
+  {-1.353380,1.021171},
+  {-0.241049,-0.683939},
+  {-0.029907,0.167199},
+  {-1.608903,-0.559216},
+  {-0.181052,0.821785},
+  {1.590072,-1.518116},
+  {1.057565,-0.689682},
+  {-1.281043,-0.980591},
+  {0.304693,-1.080609},
+  {-0.240484,0.707799},
+  {-0.768310,-0.067520},
+  {0.843861,-0.009503},
+  {0.807601,-0.431015},
+  {-0.512754,-0.550360},
+  {1.284096,-1.260585},
+  {-0.922574,0.298207},
+  {-0.393917,-0.519193},
+  {0.127912,-0.984685},
+  {-0.144986,0.035279},
+  {0.188536,0.393360},
+  {0.259745,-0.309148},
+  {-0.677779,-0.595934},
+  {-0.037591,-0.101627},
+  {-0.309109,0.365495},
+  {-0.102452,1.566645},
+  {1.387901,-0.195166},
+  {-0.446879,-0.526524},
+  {0.997398,-0.882687},
+  {0.031554,0.124163},
+  {-0.931075,0.093264},
+  {0.482681,1.855809},
+  {-0.010467,0.925571},
+  {0.169549,0.122786},
+  {-0.090570,-0.028792},
+  {0.849088,-1.107529},
+  {0.050598,0.536702},
+  {-0.571372,0.390521},
+  {0.337937,0.089426},
+  {-0.070935,-0.296006},
+  {-0.543102,-0.683296},
+  {-0.082528,1.188412},
+  {-0.075670,0.684850},
+  {0.217929,0.127319},
+  {0.244448,0.690258},
+  {-0.526178,0.479326},
+  {-0.126780,1.089720},
+  {0.456035,-0.008824},
+  {-0.236651,0.009875},
+  {-0.671016,-0.961407},
+  {0.700866,0.834313},
+  {-0.049151,0.411310},
+  {0.069039,0.176343},
+  {1.372698,0.367522},
+  {-0.107484,0.090397},
+  {-1.242871,0.580082},
+  {0.352131,0.516255},
+  {-0.409130,-0.283403},
+  {0.399885,-0.173183},
+  {-0.911535,-1.057501},
+  {-0.134356,-0.571363},
+  {-0.200745,-0.714382},
+  {0.247331,-1.213185},
+  {-0.183543,0.319417},
+  {-0.359287,-0.789582},
+  {-0.258945,-0.568476},
+  {0.371024,-0.265164},
+  {-0.075029,-1.608623},
+  {0.082652,2.076230},
+  {-1.223628,-1.586630},
+  {0.405567,0.823574},
+  {0.054968,0.521170},
+  {-1.478086,0.062628},
+  {0.111418,-0.029518},
+  {-1.266318,0.854860},
+  {0.944464,-0.835138},
+  {0.460958,0.185149},
+  {-0.058453,0.047748},
+  {0.078237,-0.159788},
+  {0.734696,0.268869},
+  {0.027735,-1.024541},
+  {0.228605,-1.028311},
+  {-0.264515,0.187069},
+  {0.016598,0.390539},
+  {0.080454,0.084167},
+  {-0.373853,-0.258455},
+  {0.496835,-0.132385},
+  {-1.257065,0.046987},
+  {0.335159,0.020590},
+  {0.466133,0.439269},
+  {0.014981,1.110095},
+  {0.785194,0.155149},
+  {-0.920996,-0.294657},
+  {-0.108107,0.667374},
+  {-0.074103,0.487597},
+  {0.309323,0.450575},
+  {1.192132,0.937428},
+  {-0.334944,-0.222933},
+  {0.412831,-1.114841},
+  {0.239488,-0.354992},
+  {0.444740,-0.426829},
+  {-0.133782,0.466919},
+  {-0.488809,0.609075},
+  {0.312304,-0.261759},
+  {-0.790404,-0.962166},
+  {-0.274962,-0.943480},
+  {-0.063458,0.313199},
+  {0.754376,-0.624958},
+  {0.894785,0.254635},
+  {-0.454480,-0.679299},
+  {-0.017854,-0.594485},
+  {-0.423178,-0.160964},
+  {-0.458684,-0.155883},
+  {-0.663973,0.506733},
+  {0.541449,-0.654020},
+  {0.172654,0.253066},
+  {1.021464,-0.901336},
+  {0.111092,-0.491099},
+  {0.252050,-0.769468},
+  {-0.617856,0.312547},
+  {-0.409293,-1.120223},
+  {0.039604,-0.485376},
+  {-1.493487,0.335907},
+  {0.274749,0.723980},
+  {-0.203481,-0.723032},
+  {-0.495656,-0.759281},
+  {1.456744,-1.628369},
+  {-0.975111,0.016837},
+  {-0.622091,1.044867},
+  {-0.434081,-0.462833},
+  {-0.315109,-0.189411},
+  {0.081910,-0.831801},
+  {-0.414067,0.096517},
+  {0.024855,-0.006315},
+  {-0.505820,0.029401},
+  {0.677997,-0.561131},
+  {1.161094,-0.385332},
+  {0.171413,-1.071286},
+  {0.796474,0.125143},
+  {0.737257,0.495755},
+  {-0.760664,0.609637},
+  {0.050209,0.872019},
+  {-0.779293,-0.049293},
+  {-0.084521,-0.987525},
+  {0.836932,0.679155},
+  {0.295252,-0.767659},
+  {-0.018792,0.419797},
+  {-1.163658,0.443970},
+  {-0.266127,-0.327858},
+  {0.087685,-1.161947},
+  {-0.369729,0.762725},
+  {0.172665,-0.329469},
+  {0.330880,0.749120},
+  {-0.816435,-0.491657},
+  {0.111348,-1.505915},
+  {0.209077,0.184622},
+  {-2.342060,-0.110587},
+  {0.307412,0.700396},
+  {0.113512,-0.465633},
+  {-0.646155,0.716656},
+  {-0.638825,-1.478782},
+  {0.450901,-0.035870},
+  {0.035266,1.827315},
+  {0.737470,-0.119507},
+  {-0.228202,0.108246},
+  {0.825314,0.200114},
+  {0.487949,0.471538},
+  {-0.357296,0.391417},
+  {0.180314,0.346172},
+  {0.559934,0.139351},
+  {-1.305116,0.414318},
+  {0.716210,0.212909},
+  {-0.013896,1.197851},
+  {-1.824869,-0.867501},
+  {-0.515474,0.050329},
+  {-0.414146,-0.076725},
+  {0.708817,-1.133978},
+  {-0.639175,0.428318},
+  {1.050038,0.727185},
+  {-0.702393,0.513455},
+  {0.276582,0.809652},
+  {0.077934,0.198272},
+  {2.196177,0.991960},
+  {-0.440575,-1.385910},
+  {0.706450,-0.276282},
+  {-0.391529,0.375718},
+  {0.486569,-0.694199},
+  {-0.074971,-1.160590},
+  {0.662076,0.018694},
+  {0.336811,-0.550141},
+  {-0.387020,-0.397890},
+  {-0.096345,0.269838},
+  {-0.026117,-0.057475},
+  {0.158403,-0.187549},
+  {0.420344,-0.129844},
+  {0.190663,-0.087482},
+  {-0.366855,0.893119},
+  {-0.249219,0.316325},
+  {-0.117221,-0.587177},
+  {-1.294407,1.470405},
+  {0.418475,-0.548199},
+  {1.001920,-0.042350},
+  {-0.292716,-0.515533},
+  {-1.153163,0.988116},
+  {-0.289238,-0.720697},
+  {-0.106232,-1.124727},
+  {-0.965999,0.865133},
+  {-0.401036,0.078021},
+  {-1.109930,-0.864017},
+  {0.297575,0.865459},
+  {0.995143,0.682193},
+  {-0.599609,-1.702099},
+  {0.883933,-0.307388},
+  {0.802376,-0.004978},
+  {-0.401257,0.112706},
+  {0.384942,-1.000741},
+  {-0.989461,0.937746},
+  {0.964376,-0.361083},
+  {1.014743,-0.689544},
+  {-1.640868,0.131432},
+  {0.631133,-0.101351},
+  {0.185813,0.273002},
+  {-1.225259,-0.530792},
+  {1.054923,0.095617},
+  {-0.207572,0.807720},
+  {0.950261,-0.272710},
+  {-0.842451,1.027046},
+  {-0.948909,0.464619},
+  {-0.652197,-0.593345},
+  {0.386114,0.647057},
+  {-0.348600,-0.148170},
+  {0.035874,-0.075556},
+  {-0.566582,0.252229},
+  {-1.150907,0.142389},
+  {-0.373560,0.708924},
+  {0.179962,0.177331},
+  {0.017741,1.577087},
+  {-0.489230,-0.574279},
+  {-0.239784,0.779613},
+  {-0.897308,-0.203218},
+  {0.925241,0.527958},
+  {1.036630,0.416062},
+  {0.888976,0.209959},
+  {0.455977,0.361892},
+  {0.395073,0.243300},
+  {0.499225,0.860184},
+  {1.188627,0.506501},
+  {-0.358162,-0.525381},
+  {1.769127,-0.519498},
+  {-0.973750,0.263258},
+  {0.081556,-0.101205},
+  {1.293777,0.240134},
+  {0.128978,-1.442584},
+  {0.092528,-0.197125},
+  {-0.117172,-0.490877},
+  {-0.946199,-0.606982},
+  {0.652803,-0.511129},
+  {0.043937,-0.032281},
+  {0.284060,0.005765},
+  {-0.734968,-1.145450},
+  {-0.025606,-0.626951},
+  {-0.375895,0.717175},
+  {0.438582,0.918001},
+  {0.038609,-1.114450},
+  {1.118108,0.106149},
+  {1.272686,0.846763},
+  {0.633646,-0.105666},
+  {-0.205043,0.210912},
+  {-0.334164,-0.085337},
+  {-0.206717,0.894467},
+  {-0.085313,1.097756},
+  {-0.399149,-0.100234},
+  {-0.149590,0.007444},
+  {0.494023,-1.223272},
+  {-1.126557,-0.292829},
+  {1.506312,-0.733856},
+  {0.129777,-0.464705},
+  {-0.430088,0.615048},
+  {1.070713,1.226466},
+  {-0.500223,-0.890256},
+  {0.241018,-0.691634},
+  {-0.425803,-1.598684},
+  {-0.349414,0.668187},
+  {-0.759980,-1.039801},
+  {0.099818,0.588593},
+  {0.661566,-0.452644},
+  {-0.276551,-0.245314},
+  {0.062076,0.738192},
+  {-0.436350,-1.545334},
+  {-0.338107,0.327650},
+  {-0.671510,-0.169933},
+  {-0.250838,-0.394788},
+  {-0.716007,0.057696},
+  {0.716020,0.323465},
+  {0.287767,-0.496472},
+  {-1.361017,-1.022037},
+  {-0.389014,-0.327876},
+  {0.005581,0.230345},
+  {1.057323,0.344696},
+  {0.404404,0.524537},
+  {0.213022,1.094306},
+  {-0.594658,-0.593064},
+  {-0.748241,0.800080},
+  {-0.115638,-0.166546},
+  {-0.107154,-0.697047},
+  {-0.458238,-0.452683},
+  {-0.336989,-0.047009},
+  {-1.289175,1.647780},
+  {0.150375,-0.407781},
+  {0.597241,-0.547383},
+  {0.443295,0.936489},
+  {0.590847,-0.187656},
+  {-1.212900,0.882074},
+  {0.484389,-0.686777},
+  {1.149782,-0.194390},
+  {-1.172668,0.032417},
+  {0.260298,-1.012974},
+  {-0.294107,-1.012750},
+  {0.801182,0.633359},
+  {0.239464,0.241602},
+  {-0.881659,-1.163284},
+  {0.489810,-0.463799},
+  {0.565567,0.113305},
+  {-0.556349,-1.347072},
+  {-1.062547,-0.931198},
+  {-0.738569,-0.353611},
+  {1.317955,-1.099776},
+  {0.148693,-0.201014},
+  {0.133189,0.681195},
+  {-0.120725,0.135954},
+  {0.109002,-0.457197},
+  {-0.694733,0.709827},
+  {0.529587,0.628810},
+  {-1.078803,0.606417},
+  {-0.135627,1.108991},
+  {0.037637,-1.260746},
+  {-1.080624,1.191058},
+  {0.359973,0.135705},
+  {0.232936,0.269440},
+  {0.002593,-0.783674},
+  {-0.069699,1.212021},
+  {-0.664211,-0.740183},
+  {0.165729,0.041761},
+  {-0.317411,0.070021},
+  {-0.172353,-0.428702},
+  {0.332293,-0.774738},
+  {-0.917322,-0.820716},
+  {-0.058246,-0.746256},
+  {0.477261,-0.232573},
+  {-0.644001,0.166028},
+  {-0.429890,0.847238},
+  {-0.056154,-1.187696},
+  {-0.879377,-0.311314},
+  {-0.187718,-0.505879},
+  {0.145068,0.268477},
+  {0.344934,-0.459281},
+  {-0.892009,-0.676237},
+  {-0.648511,-0.152063},
+  {0.285463,0.019339},
+  {-0.020319,-0.901552},
+  {-0.937522,0.163649},
+  {-0.431348,-0.446665},
+  {-0.614010,-0.352647},
+  {0.890186,-0.313942},
+  {0.187972,0.408152},
+  {-0.040763,-0.587026},
+  {-1.192632,-0.395902},
+  {-0.089341,0.188121},
+  {-1.109439,0.101585},
+  {-1.721289,-1.011886},
+  {-0.451708,0.401072},
+  {-0.878256,-0.235344},
+  {0.572753,-0.329785},
+  {-1.136417,1.039607},
+  {-0.433782,-0.120676},
+  {0.567816,0.084631},
+  {0.546969,-0.179829},
+  {0.225644,-0.412318},
+  {0.171741,0.816235},
+  {-1.141608,-0.629613},
+  {-0.537893,-0.566981},
+  {0.734572,1.390754},
+  {0.099797,-0.210714},
+  {-0.603835,-0.911116},
+  {-0.919496,0.154357},
+  {-0.200722,-0.585775},
+  {0.721968,0.331313},
+  {0.561601,0.473508},
+  {0.550664,-0.258516},
+  {-0.237893,0.651197},
+  {-0.756266,0.166779},
+  {-0.705900,0.481691},
+  {-0.006736,0.003238},
+  {0.955769,0.739538},
+  {-1.102150,-2.203276},
+  {-0.152229,-0.119703},
+  {-0.498020,0.338978},
+  {1.435975,0.240195},
+  {0.009239,2.011670},
+  {0.176554,0.774631},
+  {-0.793129,0.211589},
+  {-0.072293,0.240170},
+  {0.881402,0.528900},
+  {0.458104,0.297768},
+  {1.425877,-0.725340},
+  {-1.097623,-0.304087},
+  {-0.127377,-0.767495},
+  {-0.019548,0.382421},
+  {0.498701,1.214140},
+  {0.443213,-0.118249},
+  {-0.071224,-0.014039},
+  {0.630956,-1.420196},
+  {1.092859,-0.858199},
+  {0.601709,-0.454233},
+  {0.061239,-0.833424},
+  {-0.018905,0.604909},
+  {0.465324,-1.778430},
+  {-0.755851,0.803587},
+  {1.085178,-0.492003},
+  {0.820772,-0.064660},
+  {0.125793,-1.132899},
+  {0.315742,-0.133927},
+  {0.890772,0.347966},
+  {0.509473,-0.904259},
+  {0.313390,-1.242697},
+  {-0.183140,-0.195672},
+  {-0.664699,-0.149961},
+  {1.498274,-0.991017},
+  {-1.516974,-0.399403},
+  {-0.916197,0.142253},
+  {0.040795,-0.428170},
+  {-0.845305,0.260543},
+  {1.148172,1.459513},
+  {-0.079861,0.168896},
+  {0.687934,0.865708},
+  {-0.536824,0.124210},
+  {-0.692623,-1.014247},
+  {-1.316924,-0.789046},
+  {0.636503,-0.209795},
+  {0.552650,0.090913},
+  {-0.033354,0.150511},
+  {1.249451,-0.206799},
+  {0.901957,-0.045704},
+  {-0.268462,0.797655},
+  {-0.295622,-0.834320},
+  {-0.623560,0.392378},
+  {0.753139,-0.171098},
+  {-0.315586,-0.093971},
+  {-0.171782,0.310994},
+  {-0.584684,-1.313163},
+  {0.305928,1.064417},
+  {0.262624,-0.763970},
+  {-0.460683,-1.066815},
+  {0.775057,0.025142},
+  {-0.476420,0.420022},
+  {-0.123804,-0.614338},
+  {0.107369,-0.775216},
+  {1.000481,-0.185825},
+  {0.204721,0.528385},
+  {0.234913,0.036659},
+  {-0.580442,0.580949},
+  {1.199714,-0.639281},
+  {-0.175095,-1.293234},
+  {0.211567,-1.011604},
+  {0.534241,0.104124},
+  {0.475270,0.112080},
+  {-0.296861,0.570522},
+  {-0.006516,-0.807378},
+  {1.324154,0.366234},
+  {0.385646,0.663829},
+  {0.952289,-0.020348},
+  {-0.107272,-0.904948},
+  {-0.430374,-0.791322},
+  {0.023816,0.049091},
+  {-0.739512,-0.394887},
+  {0.267303,0.220767},
+  {0.585441,-0.615484},
+  {-0.174586,-0.975560},
+  {-0.857831,0.240895},
+  {-0.578808,0.608267},
+  {-0.618652,-0.737440},
+  {-1.703410,1.076574},
+  {0.239973,-0.524723},
+  {-0.877083,0.885381},
+  {0.364504,-1.546471},
+  {0.843914,1.160001},
+  {1.150505,1.071204},
+  {-0.370583,-0.153527},
+  {-0.146237,-1.166747},
+  {1.580330,0.835601},
+  {1.183807,-0.290036},
+  {0.408171,0.697836},
+  {-1.363711,1.276123},
+  {0.003091,-0.751142},
+  {0.892821,1.683361},
+  {-0.181868,0.148855},
+  {0.247007,-0.270453},
+  {-0.864199,-0.144221},
+  {0.131680,-1.468996},
+  {1.015785,0.628468},
+  {0.080450,-0.687172},
+  {-0.209898,0.096785},
+  {0.759138,-0.425614},
+  {-0.758907,-0.363425},
+  {0.295546,-0.675126},
+  {0.137910,0.585381},
+  {-0.615761,-0.004313},
+  {0.900616,0.336981},
+  {1.909880,-0.158311},
+  {-0.634418,-0.790108},
+  {-0.475383,0.335938},
+  {-0.438158,1.008165},
+  {-0.066609,-0.342591},
+  {1.040649,0.129256},
+  {-0.317508,0.138331},
+  {-0.934472,0.287414},
+  {-0.822846,-0.707184},
+  {0.013228,0.200951},
+  {-0.192966,0.231664},
+  {0.702280,-0.035047},
+  {1.601308,-0.110163},
+  {0.968228,0.484041},
+  {0.267920,1.208324},
+  {0.387431,0.257585},
+  {0.137627,-0.038053},
+  {-0.533791,-0.592955},
+  {-0.208416,-0.090015},
+  {1.242265,-0.575457},
+  {-0.093360,0.612640},
+  {0.474705,1.164073},
+  {-0.223268,-0.303550},
+  {0.725415,0.987524},
+  {-0.792211,0.833725},
+  {-0.127078,0.253060},
+  {1.032843,-0.053796},
+  {-0.611660,0.688883},
+  {0.020020,-0.682951},
+  {-0.061453,1.055994},
+  {0.159875,0.842203},
+  {1.073916,0.515861},
+  {-1.002761,0.703949},
+  {-0.433069,-0.241907},
+  {-0.485950,0.355489},
+  {0.046573,0.251588},
+  {0.594776,1.519930},
+  {-0.353550,-0.125344},
+  {0.019352,-0.371083},
+  {0.567640,-0.653759},
+  {-0.250529,0.176770},
+  {-0.406982,0.103083},
+  {0.373635,0.728257},
+  {1.588916,-0.649808},
+  {-0.478022,-0.050687},
+  {0.377243,0.193279},
+  {-0.036592,-0.246075},
+  {1.520919,1.009384},
+  {0.159340,0.341124},
+  {-0.463280,0.378020},
+  {-0.035160,0.543988},
+  {0.118358,0.710502},
+  {-0.619443,0.780539},
+  {0.191851,0.377155},
+  {-0.776310,-0.116329},
+  {-0.276307,-0.043138},
+  {-1.211908,0.346911},
+  {0.079369,-0.858422},
+  {0.016724,0.926178},
+  {1.256652,-0.481102},
+  {-0.806248,0.229023},
+  {0.044788,0.119707},
+  {-0.262081,0.272806},
+  {0.932057,-0.006805},
+  {0.544372,-0.095148},
+  {-1.383816,-1.364462},
+  {-0.358308,1.050147},
+  {0.273473,-0.855889},
+  {-0.003535,0.064740},
+  {-0.833668,-1.139499},
+  {-0.191707,0.659760},
+  {-0.462448,0.173778},
+  {-0.025911,0.309467},
+  {-0.460535,0.971118},
+  {1.307444,1.320250},
+  {1.627809,0.805101},
+  {0.508275,-0.630378},
+  {-0.234563,1.086843},
+  {-0.122915,0.361400},
+  {-0.915180,0.611521},
+  {-0.286575,-0.818160},
+  {0.182178,0.788028},
+  {0.604783,-0.208278},
+  {0.359150,1.039738},
+  {-0.992256,0.972576},
+  {0.106132,-1.299370},
+  {-0.162884,1.643172},
+  {-0.338271,0.643220},
+  {-0.862948,-0.463959},
+  {0.326343,0.010285},
+  {-0.098661,-0.720012},
+  {0.058748,0.476613},
+  {-0.313979,0.106628},
+  {0.342506,-1.683328},
+  {-0.675662,0.430103},
+  {-0.378889,-0.229145},
+  {1.071848,0.353785},
+  {-0.028918,-0.457589},
+  {0.480169,1.182056},
+  {-0.186146,0.337164},
+  {0.032820,-0.383106},
+  {-0.716018,0.172634},
+  {-0.408182,-0.131892},
+  {0.656507,-1.192520},
+  {-0.081387,-1.758375},
+  {0.157451,0.629884},
+  {-0.501019,0.814047},
+  {-0.998292,-0.030481},
+  {-0.562935,0.654219},
+  {0.092469,-0.943344},
+  {0.875478,0.782977},
+  {0.136500,0.716997},
+  {-0.130205,0.061150},
+  {0.772493,-0.787669},
+  {-0.069071,-1.069128},
+  {0.020852,0.155118},
+  {-0.691191,-0.378006},
+  {0.037354,-0.996423},
+  {1.281753,-0.929153},
+  {-0.426147,-0.438014},
+  {0.112682,1.190760},
+  {-0.025867,-0.051631},
+  {0.855843,0.245861},
+  {-1.283729,0.078821},
+  {0.082616,0.423985},
+  {0.650177,0.257912},
+  {-0.288642,-0.113135},
+  {-0.309283,0.956368},
+  {0.275866,0.777270},
+  {1.063946,-0.850517},
+  {-0.114175,-0.925831},
+  {-0.197025,0.160165},
+  {0.188163,0.770923},
+  {0.725416,-0.238262},
+  {0.532756,0.332611},
+  {0.110235,0.733467},
+  {0.568374,-0.980107},
+  {0.264085,-0.102002},
+  {0.128516,0.242100},
+  {-0.326246,0.476676},
+  {0.177628,1.005675},
+  {0.183542,-0.730819},
+  {0.560809,0.026720},
+  {-0.555138,-0.837223},
+  {-1.111326,-0.738718},
+  {-0.573157,1.307743},
+  {0.039276,-0.375639},
+  {-0.610247,0.441594},
+  {0.288641,-0.912492},
+  {1.190911,0.545295},
+  {0.782747,0.523818},
+  {-0.489349,-0.232879},
+  {-0.020657,-0.703896},
+  {0.073902,0.609629},
+  {0.772461,-0.210514},
+  {-0.035950,0.573090},
+  {0.973263,0.098002},
+  {0.573650,-0.286151},
+  {-0.420773,0.322248},
+  {0.828456,-0.527977},
+  {1.858361,0.248676},
+  {-0.216404,0.356862},
+  {-0.646708,-0.483857},
+  {-0.093864,-0.293461},
+  {0.583492,-0.646171},
+  {-1.115405,-0.181960},
+  {1.366417,-1.845473},
+  {-0.794050,0.390124},
+  {0.467227,0.144103},
+  {0.059131,1.012538},
+  {0.365336,0.237803},
+  {-0.484233,-0.485568},
+  {-1.005855,-0.440960},
+  {0.502362,-0.343204},
+  {-0.153506,-0.221922},
+  {1.040348,0.847320},
+  {0.875955,0.856994},
+  {0.134586,-0.579993},
+  {0.979287,-0.133640},
+  {0.552321,0.102281},
+  {0.541191,-1.039863},
+  {-1.155057,-0.141459},
+  {-0.136017,0.538894},
+  {-0.816461,0.275250},
+  {-0.724677,0.192772},
+  {0.326787,-0.010919},
+  {0.117003,1.159378},
+  {0.504487,-0.285180},
+  {-0.855043,0.300502},
+  {0.497492,1.177945},
+  {-1.019849,-0.391640},
+  {0.294492,-0.148558},
+  {-1.105971,-1.574034},
+  {-0.549529,0.276093},
+  {1.612157,0.358384},
+  {-0.490901,-0.027039},
+  {0.169836,1.390746},
+  {-0.194342,-0.284269},
+  {-0.171289,0.586009},
+  {0.440634,-0.241719},
+  {-0.866231,0.075171},
+  {0.604738,0.501042},
+  {-1.268727,0.181187},
+  {0.970697,0.307040},
+  {1.049433,0.365987},
+  {-0.498752,0.386423},
+  {-0.025266,-0.505426},
+  {-0.073175,0.049414},
+  {-0.182412,1.089200},
+  {-0.323381,-0.689772},
+  {0.110545,-1.103422},
+  {-0.264985,1.043266},
+  {-0.572449,1.384650},
+  {0.364356,0.676386},
+  {0.022608,0.196732},
+  {1.158744,2.048316},
+  {0.765193,-0.520691},
+  {0.612272,0.175707},
+  {0.822290,-0.539943},
+  {-0.029847,0.542674},
+  {-0.046485,-0.527074},
+  {-0.247289,-0.309464},
+  {-0.123121,0.695817},
+  {-0.585551,1.109341},
+  {1.091744,-0.323955},
+  {-0.258755,0.608515},
+  {-0.359400,-0.617556},
+  {0.213343,0.803480},
+  {0.723600,-0.553256},
+  {-0.919498,1.614200},
+  {0.151235,-0.057427},
+  {0.507107,0.231984},
+  {-0.423361,-0.409427},
+  {0.846366,1.210201},
+  {-0.481114,-0.023277},
+  {-0.021299,0.801072},
+  {0.087164,0.162119},
+  {0.648244,-0.593489},
+  {-1.033972,-0.776052},
+  {-0.910048,0.009627},
+  {1.145802,-0.064943},
+  {-0.863007,0.893723},
+  {-0.063187,0.408214},
+  {0.097570,0.371056},
+  {0.055008,0.378266},
+  {0.760486,-0.116970},
+  {0.175700,-0.711182},
+  {-1.061988,-1.515268},
+  {-0.366716,1.634002},
+  {-1.127267,0.259187},
+  {-0.105613,-1.658119},
+  {-0.956148,0.078537},
+  {-0.789998,-0.046661},
+  {-0.555772,0.241221},
+  {-0.361317,0.374073},
+  {0.542807,-0.644804},
+  {-0.067211,-0.306273},
+  {-0.313289,-0.762354},
+  {0.944145,0.011802},
+  {0.344604,0.581157},
+  {-0.238694,-1.260077},
+  {-0.499531,-0.040909},
+  {1.081440,-0.013408},
+  {-1.020259,-0.402582},
+  {0.168469,-0.449379},
+  {-0.322218,-0.352819},
+  {0.417512,0.125277},
+  {-0.179187,0.773391},
+  {0.934511,0.154665},
+  {0.668175,1.139319},
+  {-1.109726,-0.697647},
+  {-0.058986,-0.618589},
+  {1.224662,-0.691357},
+  {-0.344564,1.430847},
+  {-0.198289,0.080758},
+  {0.248374,-0.855443},
+  {0.510391,0.972455},
+  {-0.236303,-0.325335},
+  {0.461915,-0.112654},
+  {-1.113610,-1.548437},
+  {-1.242013,-0.824333},
+  {-0.071317,0.322042},
+  {-0.489653,-0.266651},
+  {0.049223,-0.240123},
+  {-0.017929,0.190162},
+  {-0.643566,-0.146084},
+  {0.581599,0.459194},
+  {-0.885802,-0.729123},
+  {0.659102,1.113099},
+  {0.604221,0.372455},
+  {0.150965,-0.404922},
+  {0.024189,-0.589169},
+  {0.181120,-2.232684},
+  {-0.109871,-0.604952},
+  {-0.441800,-1.783353},
+  {1.351005,0.201968},
+  {0.226026,0.178360},
+  {0.052492,0.086991},
+  {1.777618,1.068832},
+  {-0.332651,0.317066},
+  {0.541455,-0.685652},
+  {0.392310,1.079179},
+  {-0.427805,-0.269735},
+  {0.498657,-0.582363},
+  {0.940945,0.355367},
+  {0.265536,-1.458500},
+  {0.449227,0.874282},
+  {0.227071,-0.627270},
+  {-0.093351,-0.097808},
+  {-1.145261,-0.218075},
+  {0.484358,1.069822},
+  {0.996167,0.219158},
+  {0.164768,0.888018},
+  {-0.524378,-0.335536},
+  {0.408570,0.683742},
+  {0.520097,-0.352789},
+  {0.528279,0.701878},
+  {0.254929,0.657117},
+  {-0.913148,-0.518469},
+  {-0.444215,-0.199164},
+  {0.123173,0.541502},
+  {0.623248,0.013648},
+  {0.876430,0.188051},
+  {-0.745054,-0.440719},
+  {1.370839,-0.341183},
+  {-0.557997,0.053702},
+  {0.504211,-0.772695},
+  {1.925599,-0.732382},
+  {1.134615,0.354443},
+  {-0.823694,0.010852},
+  {-0.010443,-0.137324},
+  {0.583601,-0.844533},
+  {0.664869,1.118130},
+  {-0.000382,0.444552},
+  {-0.646392,1.280645},
+  {1.497105,0.917277},
+  {-0.230933,-0.814139},
+  {-0.618821,-0.230543},
+  {0.004494,-0.586885},
+  {0.188155,0.759926},
+  {0.400992,-0.852580},
+  {0.916116,0.173815},
+  {0.164091,-0.226974},
+  {0.428332,-1.030586},
+  {-1.450546,-0.165323},
+  {-0.743664,-0.984256},
+  {1.239929,0.021010},
+  {0.169317,0.059045},
+  {1.351634,0.648103},
+  {-0.725472,0.514575},
+  {0.682044,0.646209},
+  {-0.254000,-0.088715},
+  {0.820242,0.000807},
+  {-0.199804,-1.335055},
+  {0.568600,-0.573050},
+  {-0.372125,1.120332},
+  {-0.080109,-0.217794},
+  {-0.077319,0.183705},
+  {0.610015,-0.768326},
+  {0.531406,-0.197264},
+  {0.374272,0.746575},
+  {0.811771,-0.070560},
+  {0.456952,0.828381},
+  {-1.114625,-0.778551},
+  {-0.677564,-1.195200},
+  {-0.032155,-0.146667},
+  {0.160033,-1.240192},
+  {0.784846,-0.048669},
+  {0.226182,-0.040282},
+  {-1.385046,-0.704092},
+  {0.539381,-1.102437},
+  {0.385233,0.702485},
+  {0.229480,0.119168},
+  {-1.160470,0.285107},
+  {-0.541554,0.585548},
+  {-0.348345,0.770643},
+  {-0.277295,0.505369},
+  {0.072372,0.074768},
+  {-1.171783,-0.243523},
+  {0.704349,0.708709},
+  {0.059024,0.631281},
+  {0.065354,1.504243},
+  {-0.835199,0.568548},
+  {-0.460690,1.264099},
+  {-1.828812,-1.061787},
+  {0.003831,0.815100},
+  {-1.209037,0.131804},
+  {0.842161,-0.991327},
+  {0.138250,-0.926978},
+  {-0.127969,0.712464},
+  {-0.350826,1.252760},
+  {0.556596,0.709099},
+  {-0.880338,-0.882393},
+  {0.633947,0.831589},
+  {1.535985,0.012752},
+  {-0.110222,-1.560059},
+  {-0.473637,-0.328046},
+  {-0.183194,0.641908},
+  {-1.074374,0.106450},
+  {0.837744,-1.048600},
+  {0.080980,-1.310010},
+  {0.538448,-1.136176},
+  {-0.596666,-0.628378},
+  {-0.594768,0.340720},
+  {0.251058,-0.190293},
+  {-0.061235,0.142368},
+  {0.563618,-0.663220},
+  {-0.994710,0.799951},
+  {-0.013219,-0.077868},
+  {-0.260975,0.436012},
+  {0.701558,-1.555042},
+  {0.218937,-0.839333},
+  {0.189052,-0.893478},
+  {-0.825828,-0.108326},
+  {0.179960,-0.454794},
+  {-0.189811,-0.729981},
+  {0.258641,0.734701},
+  {1.033546,-0.851021},
+  {-0.481548,1.060999},
+  {0.550961,-0.495215},
+  {-0.720159,0.605927},
+  {-0.918472,-1.437412},
+  {0.238061,0.359825},
+  {-0.669119,-0.477539},
+  {-0.393230,1.100341},
+  {-0.294604,0.625805},
+  {1.183505,0.325424},
+  {0.656797,0.302560},
+  {-0.264583,1.659226},
+  {0.944444,0.759065},
+  {0.363301,-0.931562},
+  {0.321250,0.144317},
+  {0.056304,0.033562},
+  {0.396821,-0.081704},
+  {-0.146098,-0.157071},
+  {-0.567406,0.542368},
+  {0.087811,-1.191284},
+  {0.645851,-1.129586},
+  {-0.480500,0.559676},
+  {-0.512098,-0.692533},
+  {-0.576949,-0.178230},
+  {-0.312055,-1.312385},
+  {-0.661092,-0.003298},
+  {1.385371,0.073527},
+  {0.749575,0.121531},
+  {0.451503,-0.172923},
+  {-1.720465,0.533779},
+  {-0.558727,-0.163352},
+  {1.161200,1.410997},
+  {0.343344,-0.099791},
+  {-0.065168,-2.180713},
+  {0.350066,0.806381},
+  {-0.286234,-0.192670},
+  {0.073187,0.263513},
+  {-0.757331,-0.586757},
+  {0.984908,0.277915},
+  {1.028605,0.961379},
+  {0.644807,0.258389},
+  {0.606982,0.266423},
+  {-0.090490,0.787222},
+  {0.184171,0.023188},
+  {0.350628,0.158079},
+  {0.778608,0.188059},
+  {-0.930078,1.186364},
+  {-0.671489,-0.012170},
+  {-0.081454,0.351651},
+  {1.178337,0.477150},
+  {-0.455728,-0.782186},
+  {0.891922,0.565029},
+  {1.160296,-0.280368},
+  {0.653268,0.357551},
+  {1.540297,1.202347},
+  {0.245353,0.959049},
+  {0.243214,-0.407234},
+  {-0.450652,1.435352},
+  {-0.707209,1.169824},
+  {-0.087597,0.734600},
+  {0.280094,-0.507072},
+  {-0.362702,0.385568},
+  {-0.298647,-0.445275},
+  {1.484539,-0.134123},
+  {-0.714418,-0.484541},
+  {0.183658,-0.100520},
+  {-1.304078,-0.615248},
+  {-0.145906,-0.378490},
+  {-1.139469,0.513238},
+  {-1.002350,-0.857683},
+  {-0.662826,1.027047},
+  {0.866330,-0.714924},
+  {0.134961,-0.170331},
+  {-1.346329,-0.335113},
+  {-1.486651,0.211276},
+  {-0.033975,0.498228},
+  {0.808639,0.410672},
+  {-0.183830,0.673398},
+  {0.283445,0.591164},
+  {-0.775002,-0.358194},
+  {-0.559984,0.245061},
+  {0.448254,-0.351589},
+  {-0.307253,0.317585},
+  {0.110474,-0.551974},
+  {1.435987,-0.093767},
+  {-0.899370,-0.601259},
+  {0.050750,-0.801049},
+  {-0.248103,-0.266506},
+  {-0.722677,0.408100},
+  {0.439215,0.082929},
+  {0.326781,0.560803},
+  {-0.435041,0.157077},
+  {0.616733,-0.929936},
+  {-1.000230,0.585819},
+  {0.197016,-0.325485},
+  {-0.661867,-0.863923},
+  {-0.149218,-0.118129},
+  {-0.048844,-0.426240},
+  {-0.048809,-1.036530},
+  {1.234970,-1.198487},
+  {-0.564061,0.812790},
+  {0.518469,-0.899248},
+  {-1.011805,-0.436426},
+  {-0.731235,0.119354},
+  {-0.748153,-0.686550},
+  {-0.765046,-0.353657},
+  {-0.836584,0.509778},
+  {0.848860,-0.573605},
+  {0.275349,-0.980142},
+  {-0.086480,0.350212},
+  {0.561023,0.614301},
+  {0.295835,-0.062431},
+  {-0.169997,1.796229},
+  {1.411584,-0.157918},
+  {-0.820578,-0.083208},
+  {0.363949,-1.059952},
+  {-1.105712,-0.108223},
+  {0.022597,-1.059282},
+  {-0.599310,-1.113121},
+  {1.271478,0.088851},
+  {-0.351697,1.037394},
+  {0.708869,1.367619},
+  {1.616188,0.268445},
+  {-0.055062,0.051147},
+  {0.089420,0.984126},
+  {1.037123,0.467659},
+  {0.285018,1.056293},
+  {0.076872,0.167609},
+  {0.466394,0.073944},
+  {-1.120238,-0.403795},
+  {-0.605089,0.022859},
+  {0.279943,1.026083},
+  {0.103397,0.277845},
+  {-0.243145,0.104500},
+  {0.333394,-0.637974},
+  {-0.115601,1.088147},
+  {-0.792947,0.234692},
+  {-0.789909,-0.934349},
+  {-0.734755,0.478295},
+  {1.709832,-0.280996},
+  {0.744538,-0.906727},
+  {0.250604,0.999609},
+  {-0.503783,0.558645},
+  {0.495996,0.365936},
+  {0.142156,-0.574836},
+  {0.512751,0.192158},
+  {1.235956,0.332711},
+  {0.023924,-0.429072},
+  {1.193035,-0.496755},
+  {0.507106,0.569391},
+  {-0.957161,-1.168585},
+  {-0.107514,0.423613},
+  {-0.739674,-0.701516},
+  {0.904520,-0.072935},
+  {-0.102696,-0.928840},
+  {-0.431224,0.774089},
+  {0.546826,0.645864},
+  {-1.462693,-0.997040},
+  {0.045656,0.881963},
+  {1.235724,0.605226},
+  {0.485086,-0.077597},
+  {-0.269521,-0.825996},
+  {-1.322636,0.198827},
+  {-0.755254,0.130400},
+  {0.905988,-0.026561},
+  {0.398511,-0.221909},
+  {0.101731,-0.824604},
+  {-0.772005,-0.034138},
+  {0.255018,0.583319},
+  {-0.099606,-0.618148},
+  {-1.244045,0.403242},
+  {0.290003,0.145494},
+  {0.525354,0.224848},
+  {0.953469,0.330420},
+  {-0.529456,0.842453},
+  {-0.558430,-0.068691},
+  {0.816181,-1.027805},
+  {0.473286,0.705963},
+  {-0.374642,-0.541333},
+  {0.450463,-0.658926},
+  {-0.817825,-0.087311},
+  {-0.506713,0.154635},
+  {-0.234898,0.576703},
+  {-0.308701,-0.353461},
+  {-1.064488,-0.829382},
+  {-0.948916,1.358909},
+  {0.873385,0.041247},
+  {-0.975031,0.341437},
+  {0.465089,-0.305899},
+  {-1.322672,-0.257483},
+  {-1.628600,0.631921},
+  {1.432280,-0.394926},
+  {-0.278556,0.212714},
+  {-0.350961,-1.579332},
+  {-0.404100,0.750536},
+  {0.368782,0.707155},
+  {0.075936,-1.267203},
+  {-0.831914,-0.096899},
+  {-0.333046,-1.207398},
+  {0.347681,1.157404},
+  {-0.578348,-0.070195},
+  {-0.129107,1.292968},
+  {0.170815,0.528093},
+  {0.446822,-0.070859},
+  {0.606865,-1.535666},
+  {0.948290,-0.884917},
+  {-0.045336,-0.805774},
+  {0.469737,-0.474745},
+  {-0.491228,1.119829},
+  {-0.441045,0.412691},
+  {-0.263473,0.314737},
+  {-0.249778,-0.497140},
+  {1.067664,0.185250},
+  {0.464393,0.962226},
+  {1.268074,-0.124376},
+  {-0.050562,0.440929},
+  {1.169404,0.656123},
+  {-0.881702,0.319503},
+  {-1.052664,1.076097},
+  {-0.492302,0.583617},
+  {0.558011,-0.848022},
+  {-0.723854,0.330486},
+  {-0.451609,0.208036},
+  {0.033972,0.322249},
+  {0.081812,0.909632},
+  {0.438240,-0.140270},
+  {-1.769997,0.783168},
+  {0.841427,0.381585},
+  {-0.535555,1.054986},
+  {0.480827,-0.859746},
+  {-0.590138,-1.197696},
+  {1.838550,-0.341772},
+  {0.314785,0.598647},
+  {0.966481,0.829249},
+  {-0.603204,1.197482},
+  {0.287894,-0.764641},
+  {0.245047,0.646047},
+  {0.703114,0.023655},
+  {-0.751477,-0.640445},
+  {0.128946,0.238554},
+  {-0.248008,-0.661997},
+  {-1.358426,0.542743},
+  {-0.077018,0.562820},
+  {-0.992383,-0.265463},
+  {0.815603,-0.609510},
+  {0.402195,0.111800},
+  {0.098221,0.243275},
+  {0.465141,-0.894786},
+  {-0.195025,0.818069},
+  {0.163013,0.020456},
+  {0.019287,0.280488},
+  {-1.292419,-0.472930},
+  {-1.176423,-0.206148},
+  {-0.517755,-0.206153},
+  {-0.221025,-0.087351},
+  {0.613520,0.874127},
+  {0.125680,-0.160756},
+  {0.959133,-0.888381},
+  {-0.119945,0.682721},
+  {0.994469,1.538646},
+  {0.666825,0.194733},
+  {-0.037507,-0.858152},
+  {1.210323,-0.049750},
+  {-1.064716,-0.617205},
+  {0.945401,-2.387452},
+  {0.158818,0.160687},
+  {-0.482974,0.394775},
+  {-0.858639,0.219751},
+  {0.294519,0.146071},
+  {1.044995,-0.604510},
+  {0.823595,0.998153},
+  {0.038470,1.230760},
+  {1.575698,-0.815523},
+  {0.148811,0.410763},
+  {-0.389223,0.867009},
+  {-0.126203,0.541746},
+  {1.678347,0.380927},
+  {0.429547,-1.024259},
+  {-0.266202,0.332225},
+  {-1.617040,-1.222720},
+  {-0.563409,-0.661385},
+  {-0.219464,-0.002245},
+  {0.314463,0.656447},
+  {-0.300489,0.532422},
+  {-1.675190,0.759753},
+  {0.428757,0.171765},
+  {-0.011795,-0.359087},
+  {-0.887617,0.835305},
+  {-0.810371,1.602856},
+  {0.409307,-0.461949},
+  {0.199920,-0.987035},
+  {0.123417,0.693076},
+  {-0.100030,-1.106335},
+  {1.582451,-1.165881},
+  {-0.704681,-0.668353},
+  {0.760863,1.026244},
+  {-0.191075,0.266052},
+  {-0.668103,0.170235},
+  {-0.012904,-0.286498},
+  {-0.501481,0.788971},
+  {0.668517,0.968752},
+  {-1.047200,-0.400916},
+  {-0.533675,0.024010},
+  {-0.986899,-0.229436},
+  {0.627433,1.110767},
+  {-0.365978,0.023073},
+  {0.663772,-0.100048},
+  {1.049500,0.285839},
+  {-0.643717,-0.106911},
+  {0.591250,-0.125807},
+  {-0.639040,-0.106044},
+  {0.037507,-0.832752},
+  {0.328107,-0.285961},
+  {-0.627469,-0.265954},
+  {-0.052279,0.075179},
+  {-0.231068,0.046103},
+  {1.172718,0.580020},
+  {-0.255252,0.819326},
+  {-0.169260,-0.100791},
+  {-0.756299,0.608835},
+  {-0.181330,-0.094706},
+  {0.479515,-0.363664},
+  {1.236969,0.858327},
+  {-0.975062,0.641956},
+  {1.244166,0.412330},
+  {-0.243528,-0.367673},
+  {-0.352109,-0.345661},
+  {-0.198278,0.348731},
+  {-0.264499,0.354155},
+  {1.043070,-1.080189},
+  {-0.158193,0.645892},
+  {-0.341817,-0.186282},
+  {-0.152951,-0.679947},
+  {-0.281572,0.534695},
+  {-0.012417,0.328755},
+  {-0.265771,-0.525037},
+  {-0.161336,1.444940},
+  {0.995682,0.203988},
+  {-0.537981,0.988658},
+  {-0.529871,1.194728},
+  {0.831686,0.030963},
+  {0.356165,-0.026852},
+  {-0.577640,-0.518094},
+  {-1.028778,-0.136226},
+  {1.046369,-0.334105},
+  {-0.005565,-1.329268},
+  {-0.821778,-0.563742},
+  {1.142928,0.091294},
+  {0.682693,-1.263949},
+  {0.380228,-0.658545},
+  {0.843082,0.932597},
+  {-0.345522,0.249836},
+  {0.446026,-1.368423},
+  {-0.918192,1.002040},
+  {-0.661288,-0.984786},
+  {-0.590316,-0.129025},
+  {0.777157,0.056676},
+  {-0.264574,-0.214260},
+  {-0.816790,0.067197},
+  {-0.585520,-0.519243},
+  {-1.193762,-0.976993},
+  {0.583269,0.827641},
+  {0.394747,-0.120571},
+  {-0.049132,-0.030678},
+  {-0.484051,0.178199},
+  {-0.283985,-0.097271},
+  {0.105214,-0.205086},
+  {0.341469,1.602652},
+  {0.269129,0.846228},
+  {-0.386895,-0.161324},
+  {0.950400,0.840099},
+  {-0.753280,0.687107},
+  {0.466935,-0.616318},
+  {-0.287216,-0.420626},
+  {-1.046482,-0.085754},
+  {0.284436,-0.869538},
+  {0.897849,0.423417},
+  {0.921429,-0.765774},
+  {0.763842,-0.209293},
+  {0.617392,0.912271},
+  {-0.177456,-0.132474},
+  {0.806300,0.356169},
+  {0.336841,-0.384476},
+  {0.283514,-1.204551},
+  {-1.051563,0.410899},
+  {-0.962639,0.824742},
+  {-0.270251,-0.887304},
+  {0.165904,-0.610252},
+  {-0.333379,0.607510},
+  {0.600463,0.941986},
+  {0.997552,0.235415},
+  {-1.187420,-0.233916},
+  {0.897561,-0.197762},
+  {0.319458,-0.794006},
+  {1.832876,-1.005851},
+  {0.117741,0.084043},
+  {-0.277336,-0.585939},
+  {-0.220366,0.332784},
+  {-0.955706,-0.663342},
+  {-0.874698,-0.661934},
+  {-0.977466,0.530857},
+  {-0.670765,0.717771},
+  {1.169043,0.801325},
+  {-0.313282,0.543873},
+  {1.361090,-0.016967},
+  {-0.045271,0.468467},
+  {-0.872414,0.191454},
+  {-0.622985,1.003125},
+  {-1.506511,-0.683927},
+  {-0.860689,-0.551287},
+  {-0.871940,-0.866821},
+  {0.624825,0.683967},
+  {1.592190,0.116308},
+  {0.126634,0.042754},
+  {0.051162,1.220215},
+  {0.758876,0.604646},
+  {0.941573,0.080765},
+  {-0.195989,0.676589},
+  {-0.499377,0.152671},
+  {0.658630,0.605302},
+  {-0.358647,1.735287},
+  {1.364593,0.503183},
+  {0.210822,-0.166494},
+  {-0.861761,0.367387},
+  {-0.458178,0.060156},
+  {0.427491,0.042062},
+  {0.086057,-0.088052},
+  {0.162160,-0.189039},
+  {-0.734105,1.173913},
+  {1.009910,-0.268308},
+  {0.511028,0.449041},
+  {-0.638741,1.917117},
+  {-0.396037,-0.155032},
+  {-0.997269,-0.575873},
+  {0.535088,0.441734},
+  {-0.543414,-0.751851},
+  {-1.416398,-0.066365},
+  {-0.053821,1.180805},
+  {0.282290,0.897749},
+  {0.759861,-0.479464},
+  {0.990860,-0.835886},
+  {0.536881,-0.128652},
+  {-0.235283,1.638562},
+  {-0.048821,-1.424798},
+  {-1.013434,-0.285478},
+  {0.380225,0.037058},
+  {0.083666,0.162508},
+  {-0.638680,-0.529640},
+  {0.063698,0.202676},
+  {0.126295,-0.106833},
+  {-0.705436,0.875691},
+  {1.560148,-0.744106},
+  {0.506902,0.182486},
+  {-0.216431,0.488020},
+  {0.088319,0.537304},
+  {0.744745,0.260296},
+  {-0.266826,0.163056},
+  {-0.680731,1.666494},
+  {0.716172,-0.824289},
+  {0.576971,1.097574},
+  {-0.306776,0.425233},
+  {0.559360,0.770270},
+  {0.306141,-0.569606},
+  {0.641368,0.473688},
+  {-0.534869,0.305556},
+  {0.479480,-1.319807},
+  {-0.369422,0.008258},
+  {-1.015711,0.415351},
+  {0.334729,-0.161003},
+  {0.111812,-0.232136},
+  {1.115033,0.418084},
+  {0.372638,0.159681},
+  {0.228723,0.086318},
+  {0.183488,0.840287},
+  {-0.032699,-0.968931},
+  {0.497496,0.382361},
+  {-0.737920,0.301958},
+  {-0.390336,-0.313842},
+  {-1.358576,-0.824571},
+  {-0.296870,-0.221777},
+  {-1.204408,-0.178874},
+  {0.430879,0.540454},
+  {-0.129484,-0.943346},
+  {0.111495,-0.347794},
+  {0.241006,0.882070},
+  {0.259517,-0.153651},
+  {0.359138,0.493153},
+  {-0.117222,-0.896891},
+  {0.130265,-0.611169},
+  {-0.564621,-0.942626},
+  {0.109644,0.919373},
+  {-0.765497,-0.454155},
+  {1.351302,-0.499722},
+  {-0.388550,0.828392},
+  {1.338169,1.025334},
+  {-0.017090,-0.296752},
+  {-0.180796,0.374854},
+  {0.418456,0.346593},
+  {-0.739752,0.202709},
+  {-0.167847,-0.921766},
+  {0.747846,-0.289610},
+  {0.366519,-1.205982},
+  {0.238487,-0.366714},
+  {-0.757299,0.554594},
+  {-0.815610,-0.092068},
+  {0.238967,0.595734},
+  {-0.637637,-0.039172},
+  {-0.511671,-0.025446},
+  {1.327343,-0.892339},
+  {0.787727,0.725476},
+  {0.193989,-0.948691},
+  {-0.435612,0.747976},
+  {0.973745,0.043831},
+  {-0.081442,-1.261099},
+  {0.972757,0.437030},
+  {-0.906525,0.511164},
+  {0.286286,-0.007231},
+  {-0.724918,0.317117},
+  {-0.010738,-1.408628},
+  {-0.892791,-0.413062},
+  {-1.145404,-1.000462},
+  {-0.054472,-0.656673},
+  {-0.397352,-1.006708},
+  {1.272339,0.348268},
+  {-0.072337,0.462120},
+  {0.263024,0.820054},
+  {-1.350094,-1.060760},
+  {0.318931,1.224979},
+  {-0.743524,0.081760},
+  {0.782937,0.494788},
+  {-0.380764,0.038653},
+  {0.366967,-1.110074},
+  {-0.539220,-0.289508},
+  {-0.750016,-0.379700},
+  {-1.056018,0.760600},
+  {-0.014371,0.051682},
+  {0.646769,-1.206138},
+  {-0.192194,-0.268590},
+  {0.211900,-0.061502},
+  {0.667021,0.717522},
+  {-0.988574,0.469784},
+  {0.909208,-0.187655},
+  {-0.264537,0.459019},
+  {0.283053,-0.771236},
+  {0.977605,0.326370},
+  {0.188691,-0.116146},
+  {-0.841161,-1.507667},
+  {-0.622058,0.275580},
+  {0.827556,0.636424},
+  {0.829953,-0.934848},
+  {-0.974846,-0.484086},
+  {1.038897,0.572127},
+  {-1.470389,0.655402},
+  {-0.031678,-0.280099},
+  {0.345680,1.131225},
+  {1.521886,0.475562},
+  {-0.095613,0.225868},
+  {0.587360,0.098605},
+  {-0.910606,-0.220681},
+  {0.695483,0.270633},
+  {1.392499,-0.534474},
+  {-0.380665,-0.132181},
+  {0.739761,-0.804516},
+  {0.247837,0.364872},
+  {-0.504840,0.279031},
+  {0.577741,-0.499917},
+  {-0.877160,-0.500081},
+  {0.470665,0.626683},
+  {-0.845048,-0.661755},
+  {0.573259,0.452514},
+  {1.463281,0.460497},
+  {-0.140814,-1.014287},
+  {0.792857,0.139124},
+  {0.095435,-1.194781},
+  {-0.168013,-0.617225},
+  {-0.669563,-0.438816},
+  {0.970599,1.334226},
+  {-0.389379,-0.250410},
+  {0.337426,1.425473},
+  {0.040593,0.759876},
+  {-0.692656,-0.593318},
+  {0.644505,-0.808285},
+  {0.343813,0.483264},
+  {0.262818,-0.442864},
+  {0.401180,-0.354012},
+  {0.042798,0.576953},
+  {1.057127,-0.234653},
+  {-0.543273,0.116899},
+  {-0.261085,0.760538},
+  {0.917617,0.504692},
+  {-0.505622,-0.461514},
+  {-0.397714,0.102581},
+  {0.841617,0.258265},
+  {-1.224217,1.200595},
+  {0.549822,-0.854504},
+  {-0.331807,0.249164},
+  {-0.969781,1.050829},
+  {-1.102970,-0.743287},
+  {0.391551,-1.364767},
+  {-0.291293,0.652954},
+  {-1.597162,-0.453738},
+  {-0.347804,-0.281488},
+  {-0.384993,-0.354367},
+  {-0.893094,-0.032469},
+  {-1.033837,0.258447},
+  {-0.059178,-0.196922},
+  {-0.727165,1.094397},
+  {-0.050880,-0.416205},
+  {-1.801534,0.759659},
+  {-0.013259,-0.907752},
+  {-0.663571,-0.737940},
+  {0.248589,-0.087161},
+  {1.713345,1.020552},
+  {0.274155,-0.077844},
+  {0.684280,0.290232},
+  {0.467950,-1.380906},
+  {-0.134793,0.354306},
+  {0.641834,-0.147045},
+  {1.549775,1.034824},
+  {1.011992,0.136162},
+  {1.032606,-0.470594},
+  {0.002512,-0.501699},
+  {0.263132,-0.873676},
+  {0.596802,0.698595},
+  {0.644208,-1.026820},
+  {-0.241748,-0.120648},
+  {0.400545,0.692764},
+  {0.723725,-1.171937},
+  {-0.065336,0.082173},
+  {0.087121,0.777870},
+  {0.137719,0.862409},
+  {0.600762,-0.256252},
+  {-0.496334,1.522049},
+  {1.415523,-0.361800},
+  {0.195888,0.140839},
+  {-0.201059,-0.957306},
+  {0.833613,-0.884474},
+  {-1.923963,-0.511931},
+  {-0.401694,-0.750599},
+  {-0.057871,-1.554591},
+  {0.136921,-0.610025},
+  {-0.692221,0.232519},
+  {-0.963772,-0.406412},
+  {-1.011556,0.388904},
+  {0.196652,0.402592},
+  {-0.236942,0.249439},
+  {0.197316,0.749347},
+  {0.260643,1.518230},
+  {-0.261184,-0.019793},
+  {0.953847,0.003123},
+  {-0.488447,-0.693489},
+  {0.100561,-0.839624},
+  {-0.387958,0.029235},
+  {-0.056287,0.849571},
+  {0.146328,-0.596042},
+  {-0.442422,-0.081224},
+  {1.467301,1.058274},
+  {-0.842963,-0.823609},
+  {0.361145,0.235648},
+  {2.244235,-0.417005},
+  {0.557178,0.494236},
+  {-0.286937,0.446261},
+  {-0.797514,0.125949},
+  {-0.396846,-0.492949},
+  {0.791338,0.112081},
+  {0.731112,0.815339},
+  {0.124238,1.042459},
+  {0.178620,-0.243480},
+  {-0.297767,-0.499014},
+  {0.089431,-1.045263},
+  {0.876765,1.478866},
+  {-0.433655,-0.416072},
+  {0.076538,0.452756},
+  {0.276575,-0.657696},
+  {0.710620,0.425570},
+  {-0.348002,-1.521084},
+  {0.463074,-0.794634},
+  {1.420303,0.458714},
+  {-0.799261,0.730155},
+  {-0.282421,-0.450125},
+  {-1.215153,0.133084},
+  {0.429525,0.137792},
+  {-0.046368,-0.348350},
+  {1.182696,-0.476907},
+  {-0.354102,-0.016664},
+  {0.228567,-0.048909},
+  {0.317271,-0.110712},
+  {0.000535,0.097966},
+  {0.358389,-0.986634},
+  {0.233837,-0.517393},
+  {-0.702710,-1.470436},
+  {0.301747,-0.361704},
+  {-0.116303,0.152185},
+  {0.321548,0.456944},
+  {0.426785,0.809817},
+  {0.862019,-0.752446},
+  {0.503493,-0.196673},
+  {-0.188695,1.043960},
+  {-0.634846,0.615436},
+  {-0.773059,-0.768587},
+  {0.735760,-0.078372},
+  {0.076222,-0.103925},
+  {-0.837846,-1.879631},
+  {0.311214,0.005395},
+  {-0.256265,0.525394},
+  {-0.759509,0.445865},
+  {-0.425542,0.964997},
+  {0.621631,0.218384},
+  {0.749916,0.486092},
+  {0.735936,-0.741326},
+  {-0.550580,0.175995},
+  {0.441750,0.922190},
+  {-0.284205,0.780467},
+  {0.111299,-0.940763},
+  {-0.488491,0.739998},
+  {-0.538022,0.602799},
+  {-0.458050,-0.227355},
+  {1.218009,1.485198},
+  {0.293776,0.548771},
+  {0.621581,0.201245},
+  {0.029869,-0.484299},
+  {0.297470,-0.678649},
+  {-0.652890,-0.572565},
+  {0.708517,0.135724},
+  {-0.759185,1.020900},
+  {0.089393,1.254895},
+  {-0.163606,-0.225901},
+  {1.028091,-0.979818},
+  {-0.463887,-0.461716},
+  {-0.472972,1.295955},
+  {-1.499760,-0.100153},
+  {-0.316495,0.182810},
+  {-0.029037,1.390832},
+  {-1.052626,0.016877},
+  {0.140853,-1.064090},
+  {0.077518,0.160558},
+  {-0.789567,0.126484},
+  {0.237999,0.933535},
+  {-0.625411,-0.154393},
+  {-0.651849,0.477355},
+  {0.313835,-0.871245},
+  {0.063692,0.733038},
+  {-0.125890,-1.321408},
+  {0.782127,0.731970},
+  {0.067632,1.028553},
+  {0.390798,-0.202231},
+  {0.859910,-0.547214},
+  {0.303427,0.117133},
+  {-1.221034,0.106196},
+  {-0.556539,-0.005747},
+  {-0.581574,-0.064757},
+  {-0.093350,-1.416022},
+  {-0.371514,0.863009},
+  {-0.228865,-0.911086},
+  {0.226620,0.868273},
+  {-0.022400,0.968063},
+  {-0.282417,-1.206830},
+  {0.517815,-0.318365},
+  {0.433595,-1.277757},
+  {0.650281,0.282816},
+  {0.696810,-0.618460},
+  {-0.018515,-1.174056},
+  {0.528708,-0.383014},
+  {0.465366,-0.166643},
+  {-1.111839,-0.208049},
+  {1.260600,-0.904770},
+  {0.114190,0.595080},
+  {-0.772035,1.160945},
+  {-0.072465,-0.121030},
+  {0.740277,0.073001},
+  {-0.031995,-1.003071},
+  {0.309444,-0.284262},
+  {0.256298,0.217717},
+  {-0.714797,0.139100},
+  {1.365575,-0.321842},
+  {0.609559,1.219424},
+  {-0.656153,0.923034},
+  {0.306127,0.569498},
+  {-0.185454,-0.769265},
+  {0.640850,-0.158718},
+  {-1.334112,-0.208599},
+  {-0.368937,-0.719614},
+  {0.154071,0.481000},
+  {0.369258,-1.256445},
+  {-1.053810,1.454169},
+  {-0.166292,-0.690521},
+  {0.434216,-0.485381},
+  {0.446152,0.316255},
+  {0.598136,-0.692985},
+  {0.194634,0.723444},
+  {0.033284,-0.674910},
+  {-0.677093,-0.480733},
+  {0.483942,0.055658},
+  {-0.380847,1.698802},
+  {-0.739697,-0.967901},
+  {0.181901,-0.283096},
+  {-0.385252,-0.218986},
+  {0.571349,1.211891},
+  {0.208035,-0.801372},
+  {-0.001354,0.011905},
+  {0.481477,-0.622890},
+  {1.126983,0.720045},
+  {0.366125,0.725890},
+  {0.172974,0.276534},
+  {-0.297515,-0.000297},
+  {0.716860,-0.694652},
+  {0.896244,-0.218171},
+  {0.166865,-0.781466},
+  {-0.782709,-0.862993},
+  {-0.004288,1.019110},
+  {-0.509804,0.230849},
+  {-0.987740,0.724671},
+  {-0.816786,-1.334751},
+  {-0.406238,-0.684850},
+  {0.680826,0.080398},
+  {-0.045664,0.409165},
+  {1.857790,-0.268328},
+  {0.265866,1.576185},
+  {-0.633796,-0.378996},
+  {0.441580,0.420835},
+  {0.594992,-0.103592},
+  {-0.350224,1.054242},
+  {-0.454100,0.966540},
+  {-0.553087,0.060871},
+  {-0.473446,-0.638460},
+  {0.348962,-0.726140},
+  {0.403723,-0.092776},
+  {0.168148,-0.187260},
+  {-0.047057,-0.712472},
+  {0.546338,0.364816},
+  {0.918003,-0.461675},
+  {-0.907751,-1.659162},
+  {0.690737,0.688165},
+  {1.115170,-0.620245},
+  {-0.424054,-0.378832},
+  {-0.295589,0.438479},
+  {-1.181545,-0.526172},
+  {-0.191356,0.363078},
+  {1.256819,0.772957},
+  {0.660880,-0.127556},
+  {-0.770033,1.086703},
+  {-0.221948,-0.024302},
+  {0.376195,0.665919},
+  {0.855315,1.296681},
+  {0.064168,-1.090223},
+  {1.198266,-0.123963},
+  {0.222219,0.832714},
+  {0.265471,0.660817},
+  {0.926886,0.106470},
+  {-0.116532,-0.351282},
+  {0.282755,1.394651},
+  {1.976995,0.625415},
+  {0.086001,0.874691},
+  {-1.158765,-0.296382},
+  {0.821879,0.330819},
+  {1.473645,0.454222},
+  {0.373012,0.334324},
+  {0.784090,-1.194075},
+  {-0.049292,-0.080586},
+  {-0.326299,-1.150056},
+  {-0.376097,-0.297711},
+  {0.400420,0.699295},
+  {-0.401832,0.718915},
+  {0.513962,1.314126},
+  {-1.223199,0.822673},
+  {-0.198511,0.577317},
+  {-0.931176,-0.141243},
+  {-0.328271,-0.297043},
+  {0.058682,0.063005},
+  {-1.537647,-1.357544},
+  {0.991342,-0.020237},
+  {0.389384,-0.358624},
+  {-0.286835,0.522531},
+  {-0.921756,-1.109047},
+  {-0.005216,0.585698},
+  {0.073284,-0.240263},
+  {-0.608758,1.045577},
+  {-0.127535,1.243989},
+  {1.069722,-0.381090},
+  {0.658169,-0.466652},
+  {0.110592,-0.898093},
+  {-0.344192,0.315264},
+  {-1.253943,0.576829},
+  {-0.988689,0.289650},
+  {0.323581,0.406835},
+  {0.753623,-1.395921},
+  {-0.526975,0.375853},
+  {-0.228419,0.642204},
+  {-0.911534,-0.802450},
+  {-0.714417,-0.277566},
+  {-0.248413,-0.669371},
+  {0.558370,-0.525797},
+  {-0.676306,-0.233652},
+  {0.187377,-0.245513},
+  {-0.115084,-0.722299},
+  {-0.778514,-0.521242},
+  {1.510762,0.186472},
+  {-0.112162,0.741817},
+  {0.168038,0.036480},
+  {0.473081,-0.613676},
+  {0.017735,-1.619743},
+  {0.125184,-0.943553},
+  {0.545184,-0.381330},
+  {0.093888,0.932584},
+  {0.298593,-1.014602},
+  {1.317871,-0.453601},
+  {0.446039,0.296345},
+  {-0.003700,-0.215325},
+  {0.357740,-1.726941},
+  {0.056925,-0.146512},
+  {0.242151,-0.224778},
+  {0.333254,1.380770},
+  {1.576821,-0.423607},
+  {0.293532,0.300461},
+  {-0.192775,-0.819195},
+  {-0.724187,0.864495},
+  {-0.256047,0.693948},
+  {0.227372,0.048857},
+  {0.384743,-0.022614},
+  {0.334230,0.059078},
+  {-0.084885,0.245805},
+  {-0.956303,-1.202349},
+  {-0.673081,-0.715653},
+  {-1.070653,-0.327304},
+  {-0.147279,0.735590},
+  {-1.051301,2.081734},
+  {0.743641,0.675310},
+  {0.497307,-0.052339},
+  {-1.137150,-0.681605},
+  {0.958912,-0.359105},
+  {-0.011346,-1.133356},
+  {-0.675276,0.676611},
+  {-0.088049,-0.368402},
+  {1.029195,0.986048},
+  {0.769677,0.565289},
+  {-0.142346,1.404113},
+  {-1.105935,0.105231},
+  {0.137296,-0.042361},
+  {0.064376,1.281022},
+  {0.891722,-0.662071},
+  {-0.274474,1.361238},
+  {0.501089,0.037064},
+  {-1.079683,0.260584},
+  {-0.657026,-0.608459},
+  {-1.321491,0.137369},
+  {-0.147387,1.485629},
+  {0.701370,-0.338272},
+  {-0.937117,-1.890266},
+  {-0.002981,-0.309410},
+  {-0.450557,0.756156},
+  {-0.207628,0.767636},
+  {-0.017018,-1.057447},
+  {-0.516946,0.622016},
+  {-0.439782,-0.660634},
+  {0.465733,0.369621},
+  {-1.107081,0.963995},
+  {-1.304264,-0.056408},
+  {0.326753,0.871892},
+  {0.607911,-0.097462},
+  {0.368739,-0.185021},
+  {1.177421,0.378663},
+  {-0.059318,-0.122919},
+  {0.024356,-0.157050},
+  {-0.952570,-0.640217},
+  {-0.285763,0.974177},
+  {-0.222286,-0.638367},
+  {1.350695,0.832729},
+  {0.426047,0.068965},
+  {-1.235143,-0.255727},
+  {0.097972,-1.280044},
+  {0.613868,0.569266},
+  {0.792483,-0.388408},
+  {-0.611795,-0.757664},
+  {0.066523,-1.342460},
+  {1.152646,0.059112},
+  {-0.407404,-0.164086},
+  {0.998551,-0.553072},
+  {-0.230242,-0.414397},
+  {1.100387,-0.474447},
+  {-0.136452,-0.266361},
+  {-0.783866,-0.608098},
+  {-0.626331,0.731900},
+  {0.453871,0.483000},
+  {0.118882,-0.076636},
+  {-0.010890,1.832384},
+  {-0.275781,0.534932},
+  {-0.758412,0.302367},
+  {0.774181,-0.666316},
+  {-1.239903,-0.018154},
+  {-0.826897,-0.159508},
+  {0.294782,0.329762},
+  {-0.310305,0.173462},
+  {-0.484331,0.577130},
+  {0.528037,-0.079597},
+  {-1.165040,0.643362},
+  {0.218828,-1.879045},
+  {0.340559,0.534394},
+  {1.027003,-0.862991},
+  {0.265023,0.582110},
+  {0.533497,0.424652},
+  {-0.143533,-0.668350},
+  {-0.043478,1.242700},
+  {0.140689,-0.328515},
+  {0.594427,0.952587},
+  {0.328719,0.131913},
+  {1.647645,0.451601},
+  {0.807728,0.547755},
+  {-0.398431,1.090855},
+  {0.071550,0.529582},
+  {0.696988,0.096969},
+  {-0.315803,0.602702},
+  {-0.053510,0.368662},
+  {-0.783694,-0.369834},
+  {-0.513209,-0.183077},
+  {-0.389552,-0.423163},
+  {0.250511,-0.197899},
+  {1.072604,1.141232},
+  {-0.256157,0.324126},
+  {-0.845304,1.344024},
+  {1.607235,-0.083729},
+  {0.216531,-0.229193},
+  {-1.849789,0.283520},
+  {-0.273563,-0.437125},
+  {0.439165,0.820069},
+  {-0.071710,0.044047},
+  {-0.036628,0.811854},
+  {0.949810,0.092324},
+  {0.223015,-0.302363},
+  {-1.151938,0.219130},
+  {-0.602013,-0.159929},
+  {-0.479745,-0.467518},
+  {-0.596418,1.115315},
+  {1.155356,0.976269},
+  {-0.339066,0.667014},
+  {-0.537118,-0.328546},
+  {0.231632,-0.251679},
+  {-0.564684,-0.151955},
+  {0.404261,0.591546},
+  {0.156538,-0.119747},
+  {-0.265291,0.441799},
+  {-0.710732,0.990762},
+  {-0.037181,-0.893433},
+  {-0.608993,0.072250},
+  {-0.431612,-0.294577},
+  {-0.449292,-0.627379},
+  {1.118185,-0.219789},
+  {-1.095315,-0.141630},
+  {-0.906823,1.379934},
+  {-0.355207,0.170146},
+  {0.012266,-0.140593},
+  {0.582558,0.200710},
+  {-0.264941,0.654223},
+  {0.490653,0.262090},
+  {-0.806158,0.423760},
+  {-0.916022,-0.095727},
+  {-1.435559,-0.430004},
+  {-1.383499,0.819679},
+  {-0.476148,-0.799760},
+  {-0.086440,-0.288405},
+  {0.468541,-0.026429},
+  {-0.513250,-0.142815},
+  {-0.903017,0.571624},
+  {-0.097263,0.834344},
+  {-1.345370,-0.677137},
+  {1.710559,-0.271618},
+  {-0.490398,-0.719281},
+  {-0.660807,0.868829},
+  {-0.612810,-0.703682},
+  {0.992913,0.444834},
+  {0.083612,0.800845},
+  {-0.140036,-0.531708},
+  {-1.676151,0.726057},
+  {1.115666,0.611399},
+  {-0.454838,0.031736},
+  {0.338107,0.033385},
+  {-1.179649,0.975904},
+  {-0.362644,-0.703524},
+  {0.265567,-0.598433},
+  {0.612009,-0.911296},
+  {0.669627,0.732675},
+  {0.299979,-1.083474},
+  {-0.001796,0.450980},
+  {-0.312085,-0.240890},
+  {-0.157834,-0.452017},
+  {-1.005825,-1.124619},
+  {1.514761,-0.139328},
+  {0.205847,-0.624360},
+  {-0.788916,-0.431594},
+  {0.185577,0.530159},
+  {-0.998640,-0.120038},
+  {-0.701757,-0.385069},
+  {0.127492,0.278129},
+  {0.644093,-0.318252},
+  {1.349703,0.815553},
+  {1.178677,0.257816},
+  {0.290177,1.567018},
+  {0.815353,0.069366},
+  {0.428406,0.751920},
+  {-0.358682,-0.000313},
+  {0.898652,-0.035994},
+  {0.007882,-0.203406},
+  {1.143951,0.676206},
+  {-1.579231,-0.510529},
+  {-0.029383,0.067530},
+  {-0.207513,-0.651686},
+  {-0.171590,0.197287},
+  {1.106950,0.639104},
+  {-1.153861,0.109446},
+  {0.128439,1.245168},
+  {-1.709516,0.155977},
+  {0.698242,0.511780},
+  {0.188021,0.140058},
+  {0.214542,-0.603858},
+  {-0.585161,-0.999378},
+  {-0.125116,-0.107497},
+  {1.169544,-0.068827},
+  {-0.641184,-0.795741},
+  {0.299439,-0.994491},
+  {-1.270881,0.080905},
+  {0.638892,0.320804},
+  {-0.045967,0.343003},
+  {0.572705,-0.597459},
+  {-1.076651,0.926168},
+  {1.591514,-0.239336},
+  {-0.151223,0.296796},
+  {-0.547906,-0.598357},
+  {0.194930,-1.469040},
+  {-1.066167,-0.488868},
+  {0.375923,-0.458435},
+  {0.118752,-0.176519},
+  {-1.119040,-0.877881},
+  {0.317179,1.106286},
+  {-0.524586,0.380106},
+  {0.449438,-0.812248},
+  {0.218978,-0.240793},
+  {0.920874,1.099158},
+  {0.337065,-1.042434},
+  {0.165176,-0.575666},
+  {0.124061,0.064366},
+  {-0.972349,-0.449360},
+  {0.438009,-0.607478},
+  {1.340508,0.164007},
+  {-0.611231,-0.045868},
+  {-1.894545,0.313067},
+  {0.026078,-0.046337},
+  {-0.993251,0.529082},
+  {0.338591,-0.050854},
+  {0.276524,-1.876008},
+  {0.553549,-0.641581},
+  {-1.274207,1.314869},
+  {0.082555,0.483468},
+  {0.480747,0.004671},
+  {0.129514,0.227370},
+  {0.488707,-0.498655},
+  {-0.672859,0.446981},
+  {-0.389134,0.220936},
+  {0.678780,0.388861},
+  {0.004714,0.113091},
+  {0.098152,0.402314},
+  {-0.584163,0.655414},
+  {1.069824,0.053944},
+  {1.426146,-0.171673},
+  {-0.492434,0.430442},
+  {0.387326,-0.723692},
+  {0.923225,0.315823},
+  {-0.436266,-0.179644},
+  {0.679013,0.839753},
+  {0.121002,0.328185},
+  {0.686624,0.263510},
+  {-1.014880,0.226535},
+  {0.496357,0.676631},
+  {-0.685878,0.475997},
+  {-0.816184,-0.690225},
+  {0.624418,-0.640938},
+  {0.981859,-0.263799},
+  {1.266654,-0.559957},
+  {-0.447318,-1.692190},
+  {-1.632760,-0.647412},
+  {1.237379,1.188506},
+  {0.224983,-0.193860},
+  {0.265301,0.088248},
+  {1.487341,-0.210028},
+  {0.975147,-1.738118},
+  {-0.315739,-1.563346},
+  {0.759571,-0.834275},
+  {0.248891,-0.487193},
+  {0.593097,0.883254},
+  {-0.295665,-0.091338},
+  {0.242557,-0.870492},
+  {0.076878,-0.401879},
+  {-1.275364,-0.748062},
+  {-1.030366,-0.635397},
+  {-0.059741,0.281073},
+  {0.647269,0.569318},
+  {0.091019,-0.383699},
+  {1.550738,-0.017491},
+  {0.558012,-0.883251},
+  {1.344487,0.781872},
+  {0.425354,-0.544888},
+  {0.443166,-0.622855},
+  {0.402391,-0.428524},
+  {0.322402,0.140907},
+  {0.665183,0.150628},
+  {0.264571,0.063423},
+  {-0.180192,1.228519},
+  {0.176187,0.609708},
+  {-0.686995,-0.858999},
+  {0.403250,1.127242},
+  {-0.460433,0.622449},
+  {0.957213,0.125857},
+  {-0.214465,-0.254392},
+  {0.953570,-0.146560},
+  {0.351196,-0.097209},
+  {0.363350,0.991605},
+  {-0.842097,0.750050},
+  {0.173444,0.393799},
+  {0.644241,0.891357},
+  {0.518479,0.829535},
+  {-0.793455,-0.868437},
+  {-0.451662,0.080692},
+  {1.713382,0.806600},
+  {-0.986818,0.371536},
+  {-0.732506,-0.086137},
+  {-0.287972,1.333554},
+  {-0.505251,-0.388335},
+  {0.182226,-0.170677},
+  {0.656847,-0.151742},
+  {0.240621,-0.408503},
+  {-1.207747,0.579227},
+  {-0.480071,-1.477118},
+  {0.397312,1.160838},
+  {-0.478893,0.085660},
+  {-1.201398,-0.484779},
+  {-0.875166,1.306590},
+  {-0.048226,0.168645},
+  {0.575978,0.334768},
+  {0.268464,-0.584981},
+  {0.172204,0.362164},
+  {-0.573584,0.837555},
+  {0.097430,0.693442},
+  {0.710075,0.430611},
+  {0.279881,0.500559},
+  {-0.495316,-0.284207},
+  {-0.024375,-0.582689},
+  {0.503912,0.590465},
+  {0.543956,-0.751481},
+  {-0.113901,0.583382},
+  {-0.424219,0.552384},
+  {-0.209784,0.254702},
+  {2.524661,-1.007793},
+  {0.453447,-0.787107},
+  {0.129431,0.856054},
+  {-0.725614,-0.060954},
+  {-0.076847,-0.411651},
+  {-0.585319,-0.607995},
+  {0.354620,-0.943508},
+  {0.004873,0.874609},
+  {0.584256,0.295973},
+  {-0.751269,-0.621494},
+  {1.252094,0.523044},
+  {0.412384,-0.071193},
+  {1.460668,-0.424840},
+  {-1.668383,-0.125918},
+  {-0.140575,-0.793958},
+  {-0.602913,-1.530258},
+  {-0.485749,0.647443},
+  {0.327012,0.012391},
+  {-0.065556,-1.534338},
+  {0.040087,0.692505},
+  {0.331535,0.606771},
+  {-1.081422,0.655871},
+  {0.112370,0.095884},
+  {0.544109,-0.418467},
+  {0.883949,0.869171},
+  {-0.053113,1.005180},
+  {0.084581,0.070706},
+  {1.176918,0.868754},
+  {0.340621,-0.290651},
+  {1.069518,-0.145240},
+  {-0.305978,-0.255205},
+  {0.264782,0.828990},
+  {0.076048,0.311651},
+  {1.020387,-0.341573},
+  {1.171179,0.317841},
+  {0.039440,-0.343955},
+  {-0.196474,-1.120097},
+  {0.173672,-0.637267},
+  {0.869413,0.499800},
+  {0.402750,-0.274691},
+  {-0.195399,-0.716727},
+  {-0.697868,-0.592886},
+  {1.005820,-0.833437},
+  {1.667014,-0.928567},
+  {0.112603,0.637979},
+  {-0.378046,-0.094991},
+  {-0.264513,0.562337},
+  {-0.281534,-0.171989},
+  {0.184469,0.954685},
+  {-0.184794,-0.419611},
+  {0.042573,-0.035524},
+  {0.526333,0.216558},
+  {0.221470,-0.570724},
+  {0.952384,0.824810},
+  {0.377462,-0.439426},
+  {0.552507,0.406306},
+  {0.356019,-0.448320},
+  {-1.181908,0.315880},
+  {1.237299,-1.380363},
+  {-0.266766,1.166820},
+  {-0.543319,-0.487425},
+  {0.853891,1.002771},
+  {0.094524,-1.085172},
+  {-0.122670,-0.819704},
+  {0.507893,1.214830},
+  {0.066840,0.391217},
+  {-0.627340,-1.028818},
+  {0.048450,0.066480},
+  {1.252207,-1.088292},
+  {1.914396,-0.390461},
+  {0.783587,-0.456659},
+  {-1.087500,-0.414070},
+  {-0.017378,-0.330487},
+  {0.822467,0.523086},
+  {0.544551,-0.396871},
+  {0.505004,-0.302542},
+  {0.655396,0.309852},
+  {0.744048,-0.677621},
+  {0.632487,0.637052},
+  {0.382478,-0.487032},
+  {-0.253994,1.037147},
+  {1.056620,0.110571},
+  {-1.000220,0.890575},
+  {0.227128,-0.051171},
+  {0.249166,-0.869667},
+  {0.362158,0.942859},
+  {0.170629,0.370184},
+  {-0.428655,-0.104012},
+  {0.827800,-0.147575},
+  {0.050820,-0.016864},
+  {1.169503,0.264916},
+  {1.055638,-1.029984},
+  {-0.213356,-0.446858},
+  {0.883660,-0.272743},
+  {-0.179240,1.234001},
+  {-1.124872,-1.414740},
+  {0.620017,0.524664},
+  {0.429714,-1.144124},
+  {0.071774,0.024483},
+  {0.236817,0.493902},
+  {-0.345272,0.403117},
+  {-0.245305,0.443081},
+  {0.456796,0.439895},
+  {0.127632,-1.065099},
+  {1.004045,0.187642},
+  {0.910957,0.711730},
+  {0.270826,0.181679},
+  {0.554230,-0.318570},
+  {0.415953,0.287152},
+  {0.249620,-1.683391},
+  {-0.183154,-0.452854},
+  {0.914111,-0.432673},
+  {-1.329404,-0.200816},
+  {0.408647,0.357466},
+  {0.342816,0.128307},
+  {-0.372446,-0.517950},
+  {-0.268470,-0.945823},
+  {0.058636,0.446404},
+  {0.077650,-0.641117},
+  {0.500659,0.569755},
+  {-1.264154,-0.108240},
+  {-0.323458,1.076444},
+  {0.286058,-0.812280},
+  {1.130102,-0.533853},
+  {0.820155,0.813720},
+  {-0.369292,0.599253},
+  {-0.401040,-1.122319},
+  {0.015961,0.999207},
+  {0.113009,0.151940},
+  {-0.326797,-1.045239},
+  {-0.631927,-0.213249},
+  {-0.232764,-0.353310},
+  {-0.277962,0.172006},
+  {-1.384869,0.322627},
+  {0.657043,0.378613},
+  {1.632659,-0.311238},
+  {-0.128560,0.380120},
+  {-0.021658,0.595562},
+  {0.055891,0.020949},
+  {0.360843,-1.355132},
+  {-0.441202,0.653312},
+  {-0.903583,-0.602887},
+  {0.589411,-0.501421},
+  {0.009663,0.497738},
+  {0.955606,0.137016},
+  {-0.829489,0.248268},
+  {-0.623087,0.554453},
+  {-0.983462,-0.470261},
+  {-0.093188,-0.254457},
+  {0.281605,-0.015601},
+  {1.143487,-0.512110},
+  {-0.259302,0.254954},
+  {-1.333991,0.113816},
+  {1.056834,0.224210},
+  {0.478784,-1.143913},
+  {1.172144,0.054436},
+  {0.126576,-0.617074},
+  {0.129731,0.567838},
+  {0.992712,0.311224},
+  {-0.080398,0.093624},
+  {-0.333385,0.321406},
+  {-0.857085,0.136303},
+  {-0.193071,0.112527},
+  {0.174651,-0.824896},
+  {-0.044413,-0.225567},
+  {0.889937,0.174611},
+  {0.221331,-0.846178},
+  {-0.911343,-0.217177},
+  {-0.598798,1.486589},
+  {0.678465,-0.562484},
+  {1.906944,0.211159},
+  {-0.148741,0.420947},
+  {0.875071,0.723028},
+  {0.500603,0.175314},
+  {-0.669264,0.505343},
+  {-0.162355,0.492007},
+  {0.405254,0.188295},
+  {0.730781,-0.170657},
+  {0.219461,-0.487510},
+  {-0.607648,-0.266311},
+  {1.031809,-1.878717},
+  {0.262365,0.080670},
+  {0.704439,-0.342870},
+  {0.526865,0.107263},
+  {0.449751,-0.350958},
+  {-0.250292,-0.244899},
+  {0.322347,-0.066403},
+  {0.250252,0.152062},
+  {-0.123904,0.252763},
+  {0.097518,0.668475},
+  {-0.756972,0.544061},
+  {-0.482034,-1.042969},
+  {0.216007,-0.057989},
+  {-0.076012,-0.157728},
+  {-0.193643,0.281670},
+  {-0.047023,-1.385414},
+  {0.425208,0.198825},
+  {-1.128706,1.130083},
+  {0.749280,0.273274},
+  {-0.885277,-0.437183},
+  {-0.045310,0.493993},
+  {0.689210,0.481689},
+  {-0.836367,-0.212518},
+  {0.933511,-0.551367},
+  {0.323157,0.145200},
+  {-0.381780,0.425335},
+  {-0.043935,0.669080},
+  {0.950537,-0.788988},
+  {0.888065,0.870818},
+  {0.198948,1.131985},
+  {0.333668,1.531210},
+  {0.329099,1.260233},
+  {0.619784,-0.971239},
+  {-0.362197,0.842451},
+  {-0.107082,0.572070},
+  {-1.273638,-0.219990},
+  {-0.220258,0.341964},
+  {-0.110476,-0.229104},
+  {1.871605,1.085818},
+  {-0.667567,-0.510587},
+  {-0.081589,-0.002145},
+  {-0.485358,-0.264608},
+  {-0.021298,-1.378931},
+  {1.061728,-0.050554},
+  {0.063661,-0.078720},
+  {0.540324,-0.679083},
+  {0.040479,-1.175746},
+  {-1.651713,0.175791},
+  {-1.061321,-0.905733},
+  {-0.144548,-0.403863},
+  {-0.212951,-0.162069},
+  {-0.202079,0.210548},
+  {-0.481286,-0.089389},
+  {0.534427,0.293422},
+  {-0.077023,-0.592110},
+  {0.748204,-0.933897},
+  {0.789813,0.023419},
+  {0.364097,-0.688288},
+  {-0.817344,-0.232389},
+  {-1.106773,-0.011376},
+  {-1.149018,0.589183},
+  {-0.237988,0.461070},
+  {0.144291,-0.866590},
+  {-0.319867,-0.741546},
+  {0.467556,-0.563525},
+  {0.787965,-0.067020},
+  {-0.377218,0.346134},
+  {-0.439111,-0.729340},
+  {0.111481,-0.725684},
+  {-0.345130,0.303179},
+  {0.221511,-0.444748},
+  {-0.139828,1.064259},
+  {-0.102410,1.595486},
+  {-0.033213,-1.118558},
+  {0.003251,0.259777},
+  {-0.418818,0.218547},
+  {0.196030,-0.238166},
+  {0.317481,0.810128},
+  {0.685667,-1.193565},
+  {-0.230818,1.499649},
+  {0.527567,1.628496},
+  {0.418979,-0.163575},
+  {0.943900,0.909605},
+  {-1.191709,-0.027791},
+  {0.834602,1.596546},
+  {0.285289,0.562981},
+  {-0.270156,-0.195083},
+  {-0.731085,-0.510584},
+  {0.054180,0.401694},
+  {0.222936,-0.465566},
+  {0.708946,0.905168},
+  {0.274867,-0.023564},
+  {0.255887,-1.523657},
+  {-0.438371,-0.835342},
+  {-0.388636,0.420745},
+  {0.575120,0.350653},
+  {0.165252,-1.180423},
+  {-0.106785,-0.106601},
+  {-0.163290,0.059107},
+  {-0.048709,-0.263100},
+  {0.309147,-0.042611},
+  {-0.927395,0.617546},
+  {0.809214,1.027300},
+  {-0.146042,0.142650},
+  {-0.784247,-1.284659},
+  {-0.278628,-0.344565},
+  {0.036556,0.842948},
+  {0.912256,0.120918},
+  {-1.159161,-0.897982},
+  {1.183806,0.116039},
+  {0.080759,-0.670877},
+  {1.106555,0.968417},
+  {-0.748972,-0.332161},
+  {0.015659,-0.238382},
+  {0.072921,0.945789},
+  {0.720423,-0.655437},
+  {-1.184291,-1.204869},
+  {0.005271,-0.500795},
+  {-0.947286,0.565118},
+  {0.402954,-0.272249},
+  {-0.051205,-1.269563},
+  {-0.244921,-0.403400},
+  {0.688696,-0.966522},
+  {-1.332749,1.102022},
+  {0.248091,-0.614807},
+  {0.542833,0.089974},
+  {0.092234,-1.064895},
+  {-0.142784,-0.393747},
+  {-1.915675,0.230426},
+  {0.189830,0.787094},
+  {-0.630199,0.176279},
+  {-1.014131,1.143947},
+  {-0.520987,-0.274620},
+  {0.207558,-0.600789},
+  {0.091016,-0.244461},
+  {-0.130663,0.121426},
+  {0.004404,0.214764},
+  {1.305978,0.539062},
+  {1.085432,0.406738},
+  {-1.147405,0.986932},
+  {-0.527963,0.040514},
+  {1.048821,0.402675},
+  {0.871429,1.049595},
+  {1.770856,-0.090866},
+  {-0.518070,0.716500},
+  {0.487361,0.022371},
+  {-0.686924,-0.549181},
+  {0.340429,0.907657},
+  {-0.394719,1.043237},
+  {0.202132,-0.329431},
+  {-0.569046,0.377140},
+  {-0.446943,0.699826},
+  {-1.179740,-0.505842},
+  {0.356706,0.439865},
+  {-0.598450,0.446083},
+  {-1.374043,0.679741},
+  {-0.021589,-1.611401},
+  {0.410296,0.014703},
+  {1.604389,0.059808},
+  {-1.673347,-0.607599},
+  {-0.050574,0.534932},
+  {1.712505,1.284287},
+  {-0.342150,-0.043176},
+  {0.055806,0.223800},
+  {0.355618,-0.311415},
+  {-0.271235,0.683074},
+  {-0.775743,1.125752},
+  {-0.378310,-1.640378},
+  {-1.038677,0.190076},
+  {1.174409,-0.118801},
+  {0.331030,-0.048922},
+  {0.728780,-0.295898},
+  {0.693699,-0.972498},
+  {0.174966,-1.152868},
+  {-0.876610,-0.017480},
+  {-0.062463,0.606038},
+  {0.974421,1.248637},
+  {1.417309,-0.262139},
+  {0.011829,1.068245},
+  {-0.812946,2.785479},
+  {0.861911,0.248256},
+  {-0.567134,0.287479},
+  {-1.000297,0.453402},
+  {-0.007071,0.201681},
+  {-0.152146,1.342125},
+  {0.671739,0.150808},
+  {1.116866,0.838904},
+  {0.759212,-1.364876},
+  {-1.013891,1.460428},
+  {-0.226149,-1.126365},
+  {-0.451954,-0.444787},
+  {-0.021515,1.034266},
+  {-0.571367,-0.692007},
+  {-0.349616,0.140445},
+  {0.168654,0.087815},
+  {-0.129953,0.445421},
+  {0.410578,0.912573},
+  {-0.217475,-0.669581},
+  {-0.222785,1.245619},
+  {1.558435,0.605819},
+  {-0.488581,-0.336896},
+  {-0.247095,0.691559},
+  {-0.272835,-0.264770},
+  {0.675699,0.032700},
+  {-0.600614,0.262450},
+  {0.180303,-0.367078},
+  {0.919067,1.375550},
+  {0.152099,-0.550776},
+  {-0.201242,0.036053},
+  {0.764895,-1.477231},
+  {0.396961,0.220377},
+  {-0.306654,0.876105},
+  {-0.991493,0.187414},
+  {-0.307614,0.684635},
+  {-0.773884,0.106210},
+  {-1.566911,0.170510},
+  {0.361833,-0.141857},
+  {-0.600408,-0.446279},
+  {1.421652,0.535651},
+  {0.798181,1.741752},
+  {0.828463,-1.351656},
+  {1.064522,0.356219},
+  {-0.261882,-0.068944},
+  {-0.274206,-0.863308},
+  {-0.472305,-0.610240},
+  {1.169302,0.073319},
+  {0.212464,-0.516636},
+  {0.072813,0.172732},
+  {-0.402815,-0.754899},
+  {0.240675,0.006754},
+  {-0.413280,0.162876},
+  {-0.878790,-0.579111},
+  {-0.490272,-1.206031},
+  {-0.500456,-0.219817},
+  {0.069254,-1.439473},
+  {0.914958,0.485123},
+  {0.759158,-0.336522},
+  {0.798766,-0.831419},
+  {0.572361,-0.465976},
+  {-0.130641,-0.259763},
+  {-0.529278,0.642024},
+  {0.169663,1.957850},
+  {0.290362,1.466387},
+  {0.486745,-0.303996},
+  {-0.739829,0.729494},
+  {-1.119647,-0.438709},
+  {1.199651,0.132905},
+  {-0.028488,0.166904},
+  {0.294118,1.343646},
+  {-1.078798,-0.045417},
+  {-0.144834,0.724221},
+  {-0.286147,0.584877},
+  {-1.025536,1.281690},
+  {1.349738,0.051777},
+  {-0.163706,0.861461},
+  {1.304346,-1.415064},
+  {-0.220065,0.578733},
+  {-0.073421,-0.292662},
+  {-0.407989,1.100458},
+  {0.306779,-0.903447},
+  {-0.053132,-0.864616},
+  {-0.613827,0.320417},
+  {-0.157362,-0.152289},
+  {-0.363881,-0.696127},
+  {-0.644928,-0.357587},
+  {0.523401,-0.545460},
+  {-0.284975,0.437116},
+  {-0.332811,0.194424},
+  {0.886436,-0.283097},
+  {-0.353503,1.253798},
+  {0.777206,1.140778},
+  {-0.176515,1.349269},
+  {0.200192,0.474405},
+  {-0.090735,0.782045},
+  {0.108052,-0.393573},
+  {-0.097758,0.133294},
+  {-0.521819,-0.069948},
+  {0.495179,0.903907},
+  {-1.635143,0.044403},
+  {-1.044754,0.995099},
+  {-0.029236,0.231209},
+  {-0.763150,-0.740411},
+  {0.666666,0.948566},
+  {-0.996496,0.103076},
+  {0.066595,0.386752},
+  {1.079913,-0.587405},
+  {-0.126881,0.324364},
+  {0.242668,0.274037},
+  {-0.167854,-0.463373},
+  {1.254502,-1.338299},
+  {-0.814549,-0.540325},
+  {0.604115,0.960306},
+  {-0.762464,0.255581},
+  {-0.145291,-0.151457},
+  {0.539461,0.564589},
+  {0.452901,-0.644154},
+  {-0.121667,0.123363},
+  {0.172408,0.943437},
+  {0.349217,-0.431470},
+  {0.193653,-0.286326},
+  {0.373892,-0.225571},
+  {-0.469563,-0.051636},
+  {0.703894,0.076285},
+  {-0.342531,-0.919488},
+  {-0.093593,0.467140},
+  {-0.370503,-0.159512},
+  {-0.427136,0.822814},
+  {0.484980,0.660569},
+  {0.380112,1.642120},
+  {0.741086,-1.181946},
+  {-0.861984,-0.551848},
+  {-0.326551,0.051893},
+  {-0.673266,0.128672},
+  {0.477538,-0.448337},
+  {0.424523,-0.099635},
+  {-0.200313,0.300309},
+  {-0.319153,-1.021980},
+  {-0.640520,-0.659841},
+  {-0.189198,0.771204},
+  {0.163659,-0.315306},
+  {0.756345,0.736886},
+  {-0.321533,0.169677},
+  {-1.755957,0.206259},
+  {-2.116119,1.256344},
+  {-0.750604,0.344105},
+  {0.267358,-0.320943},
+  {1.438068,-0.187643},
+  {-0.629031,-0.059064},
+  {0.769031,0.174502},
+  {0.611810,0.637876},
+  {0.509224,1.423682},
+  {0.029716,-0.226301},
+  {-0.529129,-0.458146},
+  {0.588062,0.568816},
+  {-0.261343,0.028227},
+  {0.000322,-0.506508},
+  {-0.454871,-0.212809},
+  {-1.170607,0.073436},
+  {1.134318,0.212980},
+  {-1.039946,1.151672},
+  {0.904145,-0.236109},
+  {0.572173,-0.222902},
+  {0.354798,-0.056846},
+  {0.617914,-0.121507},
+  {-0.485005,-0.789432},
+  {0.555901,1.045454},
+  {-0.342510,0.662108},
+  {0.477863,0.919492},
+  {-0.886891,-0.151806},
+  {0.073477,0.660208},
+  {-0.836821,-0.492241},
+  {0.868206,0.057640},
+  {-0.278170,-0.344302},
+  {1.740416,0.163213},
+  {0.710730,0.125488},
+  {0.283223,0.313698},
+  {0.549759,-0.103777},
+  {0.979863,0.559804},
+  {-0.290891,-0.894974},
+  {0.187074,-1.035208},
+  {0.722918,-1.398915},
+  {-0.581228,0.581626},
+  {0.289505,-0.332083},
+  {0.489170,-0.566258},
+  {-0.889190,-0.521928},
+  {-0.262424,0.143982},
+  {-1.279355,-0.724648},
+  {0.257297,0.851178},
+  {-0.306166,-0.469346},
+  {0.045235,-0.453040},
+  {0.285296,0.528722},
+  {-0.568471,-0.086437},
+  {-0.449844,0.791630},
+  {0.440313,0.203210},
+  {-0.715834,0.084234},
+  {-0.535316,-0.471520},
+  {0.545214,0.542797},
+  {0.858170,-0.392007},
+  {0.459011,0.277321},
+  {0.630900,0.621847},
+  {-0.661226,-1.433006},
+  {0.657691,-0.355625},
+  {-0.083747,0.737402},
+  {-0.427198,-0.957863},
+  {-0.194041,1.158089},
+  {-0.546119,-0.629835},
+  {1.668000,1.040309},
+  {-0.407113,-1.748223},
+  {0.586268,0.131234},
+  {0.824612,0.043758},
+  {0.077720,0.434675},
+  {-0.878529,0.066930},
+  {-0.910217,-0.770628},
+  {-0.399495,0.223856},
+  {-0.776131,0.072596},
+  {0.968979,-0.378461},
+  {-0.788724,-0.419890},
+  {-0.717876,-0.129177},
+  {0.649467,-0.543748},
+  {-0.083694,-0.154461},
+  {0.433057,0.341816},
+  {-0.109326,0.473616},
+  {-0.306007,0.525211},
+  {1.334709,0.792284},
+  {0.450165,0.092275},
+  {1.269496,-0.283253},
+  {-0.987681,0.679147},
+  {0.700508,-0.765557},
+  {0.020683,0.657076},
+  {0.556750,0.196350},
+  {-1.036465,0.515704},
+  {0.529448,0.036856},
+  {-1.108420,-0.332631},
+  {-0.792801,-0.226293},
+  {-0.806708,-0.100053},
+  {-0.810484,-0.306346},
+  {-0.181914,-0.053941},
+  {-0.967090,0.696498},
+  {1.192545,-0.294435},
+  {-0.566689,-1.356403},
+  {-0.828942,-0.407377},
+  {-0.621438,1.217900},
+  {-1.028343,0.521929},
+  {1.025599,-0.656932},
+  {0.138542,0.489792},
+  {-0.202065,1.257500},
+  {0.043756,-0.176369},
+  {0.685895,-0.249690},
+  {0.549922,0.885082},
+  {-0.189354,-1.551150},
+  {-1.118100,0.020367},
+  {0.474848,1.184561},
+  {-0.050645,1.195300},
+  {0.867725,-0.380298},
+  {1.033550,0.154888},
+  {-0.477175,-0.457725},
+  {1.148061,0.585421},
+  {0.380830,-0.754913},
+  {-0.106258,0.080392},
+  {-0.092959,-0.386023},
+  {-0.358937,-0.724895},
+  {-1.374994,1.067211},
+  {0.460321,0.527363},
+  {-1.238789,-0.089993},
+  {1.464682,0.876127},
+  {-1.234731,1.128579},
+  {0.724792,-0.450972},
+  {-1.521916,0.809717},
+  {-0.388497,-0.174976},
+  {0.086236,0.748876},
+  {1.100546,-0.528230},
+  {0.226367,0.697463},
+  {0.744283,1.254010},
+  {-0.249234,-0.694237},
+  {0.167903,0.298213},
+  {-0.228874,-0.560931},
+  {0.394532,0.449698},
+  {-0.344909,-0.227098},
+  {-0.415043,-1.065131},
+  {0.126645,1.162114},
+  {1.370732,-0.619147},
+  {0.823699,-0.552124},
+  {0.345714,-0.232139},
+  {0.894510,-0.203477},
+  {0.475686,-1.010735},
+  {0.661874,0.478840},
+  {-0.521820,-0.526937},
+  {1.314386,0.651335},
+  {-0.319251,-0.196685},
+  {-0.505632,0.967049},
+  {0.590235,0.712258},
+  {1.380347,1.137978},
+  {0.152855,-0.242439},
+  {0.291709,-0.255131},
+  {1.260959,-0.491270},
+  {-1.089113,-0.159145},
+  {0.435095,-0.676862},
+  {-0.340494,0.469703},
+  {1.302442,-0.532868},
+  {-0.378602,-0.400420},
+  {0.925227,-0.607976},
+  {0.251869,0.591035},
+  {-0.646873,-0.636483},
+  {-0.328268,-0.897893},
+  {1.089412,-0.159031},
+  {0.814358,2.220698},
+  {0.772924,-0.691036},
+  {-0.784735,1.137714},
+  {-0.042070,-0.600536},
+  {0.592465,-0.209877},
+  {0.769297,1.296465},
+  {0.448652,-0.198575},
+  {0.025998,0.141744},
+  {0.485850,-1.270583},
+  {-0.846149,-0.038597},
+  {-0.277242,-0.731952},
+  {0.198053,-1.496392},
+  {-0.073055,0.046129},
+  {0.574797,-1.238401},
+  {0.133512,0.156586},
+  {0.105417,1.088396},
+  {0.143785,0.480135},
+  {0.306526,-0.884781},
+  {0.722423,-0.916666},
+  {-0.657561,0.272999},
+  {-0.557441,1.138685},
+  {-0.782249,-1.293763},
+  {0.453444,0.532557},
+  {1.013185,-0.405740},
+  {-0.094466,0.752667},
+  {1.286455,-0.593367},
+  {-0.298950,0.306095},
+  {1.181346,0.559262},
+  {0.461658,-0.639042},
+  {-1.291839,-0.121779},
+  {-0.326193,0.113747},
+  {-1.154270,-0.089857},
+  {-0.351472,-1.491822},
+  {0.720080,-0.419379},
+  {-0.672820,0.094205},
+  {0.812964,-0.064953},
+  {-1.294077,1.076364},
+  {-0.133796,-0.745281},
+  {-0.393393,0.385628},
+  {-0.602521,-0.377900},
+  {0.528132,-0.164217},
+  {0.505215,-0.104243},
+  {0.765574,0.926339},
+  {2.024634,-0.477364},
+  {0.017166,0.179716},
+  {0.399008,-1.200177},
+  {-1.090208,0.311701},
+  {-0.158439,-0.916668},
+  {1.058774,0.191072},
+  {-0.464662,-0.983746},
+  {0.540500,-0.331676},
+  {0.139759,-0.346498},
+  {-0.331954,0.206804},
+  {-0.956494,0.357149},
+  {-0.944290,-0.414694},
+  {1.172465,-0.536726},
+  {-0.541046,0.365657},
+  {0.276923,1.402963},
+  {-0.242318,0.269377},
+  {0.965338,-0.785207},
+  {-0.718256,-0.028312},
+  {0.231175,0.665614},
+  {-0.947264,-0.913082},
+  {-0.501002,1.094529},
+  {0.352224,-0.272040},
+  {0.397494,0.185641},
+  {-0.151725,0.717844},
+  {0.839893,0.459279},
+  {0.801901,-0.313492},
+  {-0.684958,0.226865},
+  {-0.212219,-0.213841},
+  {0.892238,-0.435760},
+  {1.314788,-0.271844},
+  {0.836362,0.043882},
+  {-0.957485,-0.948085},
+  {1.079672,0.119647},
+  {-0.513333,0.529166},
+  {0.438430,-0.923301},
+  {0.175442,-0.539418},
+  {-0.003292,-0.268481},
+  {-0.438336,0.598716},
+  {0.174795,0.663858},
+  {0.409033,1.094613},
+  {0.766143,0.882464},
+  {0.116399,0.720590},
+  {-0.563363,0.971493},
+  {-1.542577,0.365604},
+  {0.514771,-0.458050},
+  {-0.346020,0.184177},
+  {-1.029390,0.631160},
+  {0.916323,0.569872},
+  {0.330674,-0.403426},
+  {-0.815112,0.338683},
+  {-0.233795,-0.536290},
+  {-0.156529,-1.368641},
+  {-0.263744,0.144793},
+  {0.546089,0.239988},
+  {-0.176949,-0.463405},
+  {-0.369226,-1.044596},
+  {-0.505317,-0.388794},
+  {-0.451340,0.812733},
+  {0.325007,0.206856},
+  {-0.810237,-1.085805},
+  {0.165055,0.996302},
+  {-0.931375,0.613591},
+  {-0.126483,-0.744854},
+  {0.397855,0.364294},
+  {0.287751,-0.500914},
+  {-0.053719,0.982818},
+  {-0.553468,0.292330},
+  {0.179430,-0.597617},
+  {-1.198685,-0.800000},
+  {1.186764,-0.992792},
+  {0.724964,0.103448},
+  {0.963127,0.232599},
+  {0.092029,0.364811},
+  {0.023554,0.358368},
+  {-0.156919,-0.181441},
+  {0.186716,0.206933},
+  {0.533803,-0.467186},
+  {-0.459122,0.140642},
+  {0.994366,-0.893881},
+  {0.452242,0.282844},
+  {-1.757045,-0.228025},
+  {0.966083,-0.036048},
+  {-0.134917,-0.207168},
+  {0.124213,-0.129237},
+  {-0.080806,-0.024992},
+  {-0.799884,-0.669277},
+  {-0.620681,-0.397588},
+  {-0.352503,-0.044189},
+  {0.092370,0.364939},
+  {0.449970,1.026360},
+  {0.529612,0.063033},
+  {-1.083693,-0.194379},
+  {0.369823,-0.277191},
+  {-0.177423,-0.619947},
+  {0.562466,1.467675},
+  {-0.573227,0.920231},
+  {0.552988,-0.530708},
+  {0.844829,-1.136412},
+  {0.558908,0.169169},
+  {0.626978,-0.115006},
+  {0.351068,-0.464366},
+  {-0.762156,-0.066833},
+  {-0.117971,0.052717},
+  {-0.570717,0.761831},
+  {-0.514255,0.164156},
+  {0.013305,-0.055138},
+  {-0.245547,0.642430},
+  {0.216396,0.005143},
+  {-0.507045,-0.685026},
+  {1.118325,0.364330},
+  {-0.590687,-0.140389},
+  {0.013596,0.844098},
+  {-0.399225,0.716323},
+  {-0.417137,-0.565919},
+  {0.092852,0.416915},
+  {-0.943451,-0.152195},
+  {-1.020240,0.801126},
+  {-0.611728,0.436773},
+  {-0.019905,-1.332957},
+  {-0.690646,-0.464269},
+  {0.907830,-0.494683},
+  {-0.281882,-0.749796},
+  {-1.546127,-1.007659},
+  {0.830144,-0.015166},
+  {-0.390510,-1.043779},
+  {0.117684,-0.482510},
+  {0.924184,1.260658},
+  {-1.061867,1.221469},
+  {-0.815122,-0.023800},
+  {-0.103022,0.298058},
+  {-0.252904,0.230901},
+  {0.021567,-0.875517},
+  {0.248461,0.093681},
+  {0.264196,0.004397},
+  {-0.311626,-0.620671},
+  {0.280419,0.771652},
+  {-0.018466,0.219481},
+  {1.700853,-0.112003},
+  {-0.882344,0.018746},
+  {-0.006374,0.087725},
+  {-0.100868,0.209463},
+  {0.512129,0.523700},
+  {-0.317199,0.307879},
+  {0.294301,-0.330502},
+  {0.601020,-0.125700},
+  {-0.739890,-0.023356},
+  {-1.444838,0.568493},
+  {-0.134116,-0.671218},
+  {1.005881,0.367029},
+  {-0.738930,0.646782},
+  {-0.342683,-0.504731},
+  {0.716899,-0.539596},
+  {0.738524,0.070291},
+  {0.386202,0.440067},
+  {1.345032,0.180183},
+  {-0.018880,-0.031769},
+  {-0.378806,-0.171766},
+  {-0.286278,-0.617444},
+  {-0.080975,-0.526326},
+  {0.700062,-0.604598},
+  {-0.885363,0.470310},
+  {-1.156147,-0.054617},
+  {0.133744,-0.226376},
+  {-0.240292,-1.157249},
+  {0.063137,-0.793579},
+  {0.030749,-0.302199},
+  {0.090525,0.483558},
+  {0.073085,-0.481644},
+  {-0.223842,-2.140667},
+  {0.031752,0.005003},
+  {1.231275,-0.530212},
+  {1.038917,-0.422673},
+  {0.394114,0.524978},
+  {-1.097829,0.484170},
+  {0.431677,0.251181},
+  {1.225130,-0.837454},
+  {-0.186695,1.110229},
+  {0.338671,0.141820},
+  {-0.023210,1.021750},
+  {0.990528,-1.624820},
+  {0.011025,-0.247794},
+  {-0.339063,0.407060},
+  {0.384226,0.510580},
+  {-0.757315,-0.246458},
+  {-1.582920,0.107500},
+  {-1.012034,0.035645},
+  {1.968999,0.055935},
+  {-1.424400,-1.006629},
+  {-0.381551,-0.428135},
+  {0.437026,0.843355},
+  {0.179125,0.109344},
+  {-0.449217,1.913849},
+  {0.427694,-0.425086},
+  {-0.211741,-0.700567},
+  {-0.188227,-0.847564},
+  {-0.594710,1.483595},
+  {-0.072411,0.766453},
+  {1.150670,0.617209},
+  {-0.386818,-0.026636},
+  {-0.385528,-1.273407},
+  {-0.361319,0.734053},
+  {0.098469,-0.126693},
+  {-1.389158,1.163252},
+  {-0.460623,0.471711},
+  {0.338909,-0.460817},
+  {0.130190,0.607843},
+  {0.207546,0.467445},
+  {-0.587233,-0.598555},
+  {0.608060,0.186716},
+  {1.153664,0.245205},
+  {0.328400,0.759055},
+  {-0.694971,0.220107},
+  {-0.338761,-1.561954},
+  {-0.594066,-0.121286},
+  {-0.422942,-0.435408},
+  {-0.514954,-0.135974},
+  {-0.685185,0.540584},
+  {-0.824955,1.303292},
+  {0.226211,-0.342887},
+  {-0.598595,-1.523227},
+  {0.678569,0.475931},
+  {0.630242,0.483559},
+  {-0.620338,0.518139},
+  {0.919177,-0.181962},
+  {0.507928,-0.566914},
+  {-0.488096,0.812728},
+  {-0.364813,0.705453},
+  {-1.369744,0.240855},
+  {0.714938,-0.709527},
+  {0.582868,0.091790},
+  {-0.180208,0.726072},
+  {0.452558,0.415231},
+  {0.495553,-1.877462},
+  {0.582132,-0.333465},
+  {0.833380,-0.489799},
+  {0.267983,0.623820},
+  {-1.556596,0.244596},
+  {0.566314,0.288588},
+  {-0.067564,1.023165},
+  {0.505347,0.922345},
+  {-0.470138,-0.951912},
+  {0.660978,0.761539},
+  {0.621641,0.135908},
+  {1.400944,0.226884},
+  {0.652989,-0.565545},
+  {0.237052,-0.192473},
+  {0.953481,-0.437290},
+  {-0.532917,0.753979},
+  {-0.401020,0.182003},
+  {-0.774883,0.538031},
+  {-0.320697,-0.549711},
+  {1.663374,0.724379},
+  {0.588294,1.303208},
+  {1.044164,-0.361746},
+  {-0.145359,-1.690668},
+  {-0.825189,1.215719},
+  {-1.088180,-0.300943},
+  {-0.430774,0.622501},
+  {0.316668,0.544425},
+  {0.504829,-0.457687},
+  {-0.834387,-0.240484},
+  {-0.306896,0.687505},
+  {0.268810,1.644408},
+  {-0.780049,1.087894},
+  {-1.538673,-0.201769},
+  {0.535403,0.605154},
+  {0.019388,-0.435640},
+  {-0.440314,-0.055865},
+  {1.298971,1.128651},
+  {0.177042,1.260625},
+  {-0.854552,0.621748},
+  {-0.677730,0.607538},
+  {0.203182,0.219196},
+  {1.347539,0.528045},
+  {-1.261542,0.367327},
+  {-0.137496,0.330269},
+  {0.960711,1.133014},
+  {0.687000,0.111912},
+  {-0.181358,1.091956},
+  {0.223343,-0.483492},
+  {-0.273860,0.362866},
+  {-0.011742,-0.136568},
+  {0.275521,-1.429957},
+  {-0.273297,-0.074082},
+  {0.290409,-0.066311},
+  {-0.228273,-0.362296},
+  {-1.378862,-0.444713},
+  {0.241775,0.546076},
+  {0.039962,-0.186289},
+  {-0.036983,-0.286490},
+  {0.091318,-1.140707},
+  {0.511967,-0.298166},
+  {-0.103362,0.567148},
+  {-1.507135,-0.446682},
+  {-0.002256,-0.382378},
+  {0.793055,0.713325},
+  {0.519248,-0.273429},
+  {0.373212,1.206027},
+  {-0.186569,0.345384},
+  {-1.037811,0.160379},
+  {0.100911,0.728662},
+  {0.348187,1.397238},
+  {1.053003,0.787660},
+  {0.851118,-0.072377},
+  {0.885419,-2.014642},
+  {0.224168,-0.873868},
+  {0.866546,-1.231568},
+  {-0.196727,0.530071},
+  {-0.510674,-0.434893},
+  {0.256375,-0.296321},
+  {1.333570,1.516369},
+  {0.216969,1.545445},
+  {0.164709,0.254986},
+  {0.100115,-0.605479},
+  {0.086380,0.234960},
+  {0.907601,-0.649032},
+  {-1.199984,0.075438},
+  {1.186217,-0.332770},
+  {-0.270511,-1.202410},
+  {0.826974,0.035252},
+  {0.331603,-0.037377},
+  {0.476641,0.109902},
+  {-0.174187,-0.546405},
+  {0.159829,-0.563128},
+  {-0.251076,-0.337193},
+  {0.587231,0.086443},
+  {-0.004139,-0.062337},
+  {0.847037,-1.213560},
+  {0.720797,-0.302577},
+  {-0.313615,1.223469},
+  {-0.385838,0.548932},
+  {-0.681006,0.375296},
+  {-0.002250,-0.626297},
+  {0.044566,-0.714328},
+  {-0.785516,0.625881},
+  {1.008274,-0.326630},
+  {-0.475841,0.809907},
+  {-0.189279,-0.144121},
+  {-0.147481,-0.167430},
+  {0.297717,-0.662249},
+  {0.903221,-0.828173},
+  {-0.076715,-0.103500},
+  {-0.220609,0.037787},
+  {0.500891,0.420473},
+  {0.273765,-1.134860},
+  {0.469416,-0.299483},
+  {0.490976,0.584688},
+  {0.840863,0.462752},
+  {-0.374205,-0.498565},
+  {0.970595,1.606044},
+  {0.351297,0.387913},
+  {-1.301970,1.173260},
+  {0.132588,1.491314},
+  {-1.181621,-0.261585},
+  {-1.361050,0.972321},
+  {-0.153063,-1.707550},
+  {0.758497,0.123412},
+  {0.238820,0.155025},
+  {-0.254726,0.301346},
+  {-1.010450,1.160231},
+  {-1.240972,0.287896},
+  {0.784458,-0.105589},
+  {-0.536336,-0.405889},
+  {-0.146211,0.253732},
+  {-0.878979,0.549278},
+  {0.065870,-0.198147},
+  {-0.954775,1.043484},
+  {0.557617,1.047797},
+  {0.493106,-0.919198},
+  {-0.170124,0.314583},
+  {0.688442,0.122648},
+  {-1.023681,-0.111431},
+  {0.801745,-1.821817},
+  {-0.723679,0.440206},
+  {-0.453669,-0.190110},
+  {-0.581141,0.078254},
+  {-0.941791,-0.060551},
+  {0.890659,0.122601},
+  {0.963847,0.066347},
+  {0.759853,-0.199802},
+  {-0.106224,0.458618},
+  {1.065279,0.399051},
+  {-0.321525,0.808861},
+  {-1.208707,0.585097},
+  {0.866323,-0.559539},
+  {0.474646,0.039294},
+  {1.902251,0.915424},
+  {-0.455613,-0.414985},
+  {-0.246282,-0.640345},
+  {-0.333131,0.196717},
+  {-0.493399,-0.772411},
+  {0.204786,-0.870497},
+  {0.309500,-0.533279},
+  {0.910107,0.510703},
+  {-0.056168,-0.123584},
+  {-0.491468,-0.572133},
+  {0.375774,1.162053},
+  {0.063430,1.272410},
+  {-1.406177,-0.010975},
+  {-0.087637,-0.226010},
+  {-0.563296,0.452261},
+  {-0.449694,-0.554259},
+  {0.707040,0.188047},
+  {1.601323,-0.206911},
+  {-0.923501,0.574700},
+  {-0.966020,0.679890},
+  {0.268570,0.368709},
+  {0.212696,-0.904453},
+  {0.194974,0.488184},
+  {0.470565,0.918929},
+  {-0.684581,-0.142648},
+  {-0.844954,-0.189146},
+  {-0.542152,-0.747252},
+  {0.495473,0.403557},
+  {-0.688008,-0.913830},
+  {-0.059830,0.517971},
+  {-2.171862,1.024477},
+  {-1.249624,-0.015772},
+  {0.015926,0.734811},
+  {0.457707,-0.081584},
+  {-0.009916,-0.098752},
+  {0.810571,-0.772556},
+  {1.274648,0.151342},
+  {1.083434,-0.643550},
+  {1.044509,0.338194},
+  {-0.378948,0.039118},
+  {-0.075820,-1.730294},
+  {0.774083,0.620047},
+  {-0.066915,-1.689347},
+  {0.731451,-0.094387},
+  {0.259309,-0.417934},
+  {-0.498563,0.708930},
+  {0.774393,1.168883},
+  {-0.172278,-0.053409},
+  {-0.293542,-0.414288},
+  {1.373904,0.468393},
+  {-0.086211,0.448331},
+  {0.141485,-0.030337},
+  {-0.107671,0.406149},
+  {0.098529,0.748433},
+  {-0.267386,-0.031872},
+  {-0.748722,-0.653857},
+  {0.004819,0.286587},
+  {0.320934,0.502389},
+  {0.434680,0.257350},
+  {0.042256,-0.018636},
+  {-0.305369,0.076753},
+  {-0.205572,-0.818070},
+  {0.936762,0.858510},
+  {-0.423207,0.799304},
+  {0.072296,0.374763},
+  {-0.156480,-0.604657},
+  {-0.968287,0.266390},
+  {1.115752,-0.133177},
+  {0.666615,-0.815890},
+  {0.472277,0.132071},
+  {-0.193603,0.875236},
+  {0.318294,-0.031684},
+  {1.004666,-0.833170},
+  {0.262337,-0.253264},
+  {0.691983,2.042454},
+  {0.209886,-0.290278},
+  {0.278291,1.124044},
+  {-0.207172,1.567355},
+  {0.238977,-0.323462},
+  {-0.223252,-0.119456},
+  {0.303814,1.004795},
+  {1.200940,0.213197},
+  {-0.687440,-1.084798},
+  {-0.198295,0.195513},
+  {0.046763,0.521581},
+  {-0.510831,-0.423679},
+  {0.244499,-0.628926},
+  {0.698044,-0.623503},
+  {0.416896,-0.041211},
+  {-0.350345,-0.226075},
+  {0.695417,0.604628},
+  {-0.383804,0.383435},
+  {0.086188,-0.192144},
+  {0.781463,-1.146905},
+  {0.098847,-0.660911},
+  {-0.335006,0.419788},
+  {1.122026,-0.064158},
+  {0.384520,-0.618539},
+  {0.479143,-1.027819},
+  {1.107169,-0.524087},
+  {0.383901,-0.402677},
+  {0.194053,0.255903},
+  {0.477393,0.074827},
+  {-0.410776,-0.444651},
+  {-1.991022,-0.394045},
+  {0.216143,-0.334173},
+  {-0.563452,0.819894},
+  {-0.311190,0.640443},
+  {-0.243058,0.560057},
+  {-0.546188,-0.070783},
+  {-0.615962,0.363862},
+  {0.240774,0.912485},
+  {0.219238,-0.849157},
+  {-0.885919,-1.007370},
+  {0.190039,0.543608},
+  {1.070954,0.179088},
+  {0.554915,-0.018668},
+  {1.371742,-0.335006},
+  {-0.645975,0.229713},
+  {-0.736469,0.669922},
+  {0.001929,-0.033222},
+  {0.701460,-0.205447},
+  {0.486977,0.824796},
+  {1.258540,-0.391141},
+  {-0.036946,0.293066},
+  {0.670274,-0.247172},
+  {-1.768643,0.859413},
+  {0.290706,-0.231858},
+  {-0.102970,-0.041794},
+  {-0.418989,-0.849960},
+  {0.098567,0.921322},
+  {-0.459667,-0.893404},
+  {-0.804486,1.022065},
+  {-0.978005,-1.097316},
+  {0.774600,-0.328074},
+  {-0.242046,0.003126},
+  {-0.056869,-0.164227},
+  {-0.521315,0.145929},
+  {0.311763,-0.783776},
+  {0.116789,0.376795},
+  {0.518519,-0.236313},
+  {0.134501,-1.013336},
+  {-1.199793,-0.823016},
+  {0.122597,0.539057},
+  {0.664613,0.256397},
+  {-0.316770,0.490154},
+  {-1.263702,-0.252355},
+  {0.550430,0.282031},
+  {1.070783,-0.094371},
+  {0.587430,-0.613368},
+  {0.684523,0.740690},
+  {-1.023715,0.345296},
+  {0.107663,0.265091},
+  {0.215299,-0.153788},
+  {-0.342020,-1.389234},
+  {1.512062,0.110530},
+  {-0.255843,-0.304788},
+  {0.344653,0.472651},
+  {1.604399,0.282072},
+  {-0.123394,-1.073324},
+  {0.823059,0.235494},
+  {1.005127,-0.422945},
+  {1.087857,0.942103},
+  {0.388606,0.630055},
+  {-0.489398,0.271613},
+  {0.662806,-0.072930},
+  {-0.505174,-0.083009},
+  {-1.099044,-0.087619},
+  {1.682942,0.105597},
+  {-0.963602,-1.159610},
+  {1.770411,-0.665544},
+  {0.274943,-0.029549},
+  {-0.368023,0.498046},
+  {0.382125,0.110398},
+  {0.143411,-0.471052},
+  {-0.962301,-0.125190},
+  {-0.382881,-0.300460},
+  {-0.702084,-1.028932},
+  {0.609839,-0.269770},
+  {-0.322227,-0.046758},
+  {0.196679,-0.841992},
+  {0.389128,0.554504},
+  {-0.138058,-0.153224},
+  {0.225274,0.357098},
+  {-0.326247,-0.149102},
+  {0.189830,2.038718},
+  {0.622165,-0.578665},
+  {-0.555788,-1.517656},
+  {0.223546,-0.956908},
+  {0.036102,-0.216316},
+  {-0.527827,-0.790654},
+  {-0.703457,1.216742},
+  {1.896473,0.420610},
+  {-0.919048,-1.717801},
+  {-0.564716,-0.463391},
+  {0.072924,0.515583},
+  {1.213858,1.273362},
+  {-0.585628,-1.777402},
+  {0.315143,0.314280},
+  {1.599076,0.263103},
+  {0.551870,-0.508782},
+  {0.198278,-0.171192},
+  {0.370793,0.390001},
+  {0.186273,-0.685544},
+  {-1.334139,-0.047514},
+  {0.859364,1.107470},
+  {1.108595,-0.249803},
+  {-0.767836,0.024632},
+  {-0.755180,0.202525},
+  {0.558701,-0.646325},
+  {-0.864527,-0.056300},
+  {-0.568031,0.020910},
+  {-0.192644,-0.239731},
+  {0.335820,0.941753},
+  {-0.905318,0.078626},
+  {1.348554,-0.274217},
+  {0.718711,0.937416},
+  {0.701784,1.186619},
+  {0.783715,0.942788},
+  {0.511822,-0.269353},
+  {0.262749,0.224861},
+  {-0.369690,0.087992},
+  {0.119908,0.245625},
+  {-0.755046,-0.352329},
+  {1.050758,-1.220104},
+  {1.112945,-0.869696},
+  {0.154116,-0.398725},
+  {-0.682546,-0.178220},
+  {0.000616,-1.176764},
+  {0.582237,-0.360093},
+  {-0.048804,-0.182963},
+  {0.343632,-1.302243},
+  {-0.059123,1.169904},
+  {-0.849233,0.417740},
+  {0.802972,0.824939},
+  {-0.259347,1.401916},
+  {0.262680,1.027712},
+  {0.119396,0.842189},
+  {0.789537,0.288341},
+  {0.873023,-0.678867},
+  {-0.282999,-0.803959},
+  {0.032434,-0.332495},
+  {0.362466,-0.869451},
+  {1.303907,-0.351392},
+  {-0.261026,-0.184508},
+  {0.069724,0.222538},
+  {-1.692123,-0.176506},
+  {0.182023,-0.297168},
+  {1.166731,0.974402},
+  {0.182690,0.901593},
+  {-2.707181,0.294289},
+  {-0.422655,0.616411},
+  {0.818191,-0.536655},
+  {0.200265,-0.152867},
+  {-0.571663,-0.576991},
+  {-1.149922,0.237294},
+  {0.683474,0.514764},
+  {-0.327411,-0.298380},
+  {0.543399,1.134105},
+  {0.221413,-0.885642},
+  {1.120697,-0.024074},
+  {-0.727365,0.561341},
+  {-0.060173,-0.140444},
+  {0.010505,-0.532622},
+  {0.085622,0.854726},
+  {0.776915,0.627544},
+  {-0.480372,1.612013},
+  {0.035874,0.948871},
+  {-0.202889,0.071192},
+  {1.071655,0.563884},
+  {-0.856493,0.157759},
+  {1.465912,0.740984},
+  {-0.975957,0.149083},
+  {0.017006,0.661242},
+  {0.677641,0.736448},
+  {-0.055937,1.619199},
+  {0.017620,0.501037},
+  {-0.329608,-0.642669},
+  {0.460941,-0.086157},
+  {-0.677150,-0.999700},
+  {1.085090,0.487071},
+  {0.766686,0.736476},
+  {0.245465,-0.602065},
+  {0.259054,-0.926270},
+  {0.241794,0.493962},
+  {0.213145,-0.717582},
+  {-0.164479,1.252053},
+  {1.520899,0.765972},
+  {-0.262001,-0.514990},
+  {0.394009,0.530819},
+  {-0.398782,0.610431},
+  {0.061806,-0.058270},
+  {0.630771,1.025669},
+  {-0.235617,0.164118},
+  {-0.497122,0.651216},
+  {0.906863,0.812694},
+  {0.942602,0.037286},
+  {0.353956,-0.268639},
+  {0.721879,-1.407883},
+  {0.336154,-1.490511},
+  {0.463325,-0.409685},
+  {-0.654404,0.164448},
+  {1.353668,-1.381831},
+  {0.902985,1.291975},
+  {-0.673638,1.082945},
+  {0.096381,0.069481},
+  {0.268580,-0.006480},
+  {0.351301,0.210100},
+  {-0.111290,0.763114},
+  {0.482922,0.206619},
+  {0.265563,0.454462},
+  {-1.242255,-1.027363},
+  {-1.082879,0.470826},
+  {0.192528,-1.507715},
+  {-1.393900,0.462004},
+  {-0.328719,0.813496},
+  {0.736296,0.834899},
+  {0.401170,-0.096215},
+  {0.570525,-0.070442},
+  {-0.633878,-0.590925},
+  {0.147991,0.069756},
+  {0.368475,0.553471},
+  {-0.936644,-0.634945},
+  {-0.209835,0.061014},
+  {0.376984,0.415601},
+  {-0.053992,0.927934},
+  {-0.664815,-0.230709},
+  {-0.368558,-0.869841},
+  {0.869019,0.207397},
+  {-0.077032,0.015291},
+  {-1.041657,-1.084937},
+  {-0.040849,-1.191117},
+  {-0.040502,-0.637029},
+  {-0.113547,-0.036059},
+  {-0.376653,0.011245},
+  {-0.611166,-0.722246},
+  {-0.252785,0.199909},
+  {-0.554396,-0.777145},
+  {1.508706,1.960357},
+  {0.802878,-1.058245},
+  {-0.668372,-0.380450},
+  {0.934698,0.328675},
+  {-0.484190,-0.777490},
+  {-1.096700,-0.599480},
+  {0.133311,-0.708274},
+  {-0.037022,-0.697705},
+  {-0.094335,-0.104415},
+  {0.578229,-0.473142},
+  {0.521239,0.402009},
+  {-0.601727,-0.589783},
+  {1.068671,-0.802095},
+  {-0.179212,0.761986},
+  {-0.098283,-0.660154},
+  {-1.325546,0.733457},
+  {1.204701,0.635880},
+  {0.071453,0.547081},
+  {0.116252,0.809687},
+  {-0.289209,-0.786678},
+  {0.060218,-0.093927},
+  {1.040621,0.201639},
+  {0.663944,-1.404113},
+  {0.323341,0.022382},
+  {-1.173198,1.186145},
+  {0.631958,0.811309},
+  {0.140914,-0.812980},
+  {0.918574,-0.388552},
+  {0.137629,0.245151},
+  {0.286895,-1.006635},
+  {-0.883709,0.464159},
+  {1.149660,0.500635},
+  {0.869576,-0.471720},
+  {0.820353,0.381747},
+  {-0.764649,-0.632796},
+  {-1.436934,-0.113737},
+  {-2.086755,0.084057},
+  {1.010455,-0.246709},
+  {-0.149211,-1.532015},
+  {0.496285,0.442942},
+  {0.101726,-0.696911},
+  {0.536346,-0.055237},
+  {-1.001254,-0.165978},
+  {0.527046,1.269435},
+  {0.251018,-0.408625},
+  {-0.398318,1.683260},
+  {-0.838820,-0.091386},
+  {1.301904,1.505187},
+  {0.156433,-0.483412},
+  {-0.888996,-0.920372},
+  {1.318649,0.539760},
+  {0.608943,1.036337},
+  {-0.290264,-1.659074},
+  {-0.100778,0.034840},
+  {-0.597380,-0.927067},
+  {2.662626,-0.397478},
+  {1.115005,-0.106991},
+  {0.838668,-0.032934},
+  {-0.046413,0.184593},
+  {0.262956,-0.070027},
+  {0.126185,1.919012},
+  {-0.267772,-0.664473},
+  {0.614649,0.179683},
+  {-0.527418,0.106321},
+  {-0.240424,1.418708},
+  {-0.112591,-0.348458},
+  {1.337480,-0.026564},
+  {-0.112471,0.124444},
+  {-0.491147,0.252096},
+  {-0.291925,-0.069114},
+  {0.572380,0.425877},
+  {0.216700,0.480072},
+  {0.002923,-0.590032},
+  {-0.221473,0.797032},
+  {-0.450239,-0.109167},
+  {-0.138495,0.363282},
+  {0.536702,0.942890},
+  {-0.385188,-0.255577},
+  {-0.195874,-0.396227},
+  {-0.149959,-0.045442},
+  {0.175505,0.639732},
+  {-0.871016,0.558898},
+  {-0.166986,0.487026},
+  {0.015097,0.188443},
+  {1.593731,-0.064295},
+  {-1.302004,1.334270},
+  {0.647612,0.649894},
+  {-0.466297,-1.438770},
+  {-0.082164,-0.271981},
+  {-0.369005,0.109265},
+  {0.012960,1.067369},
+  {0.008171,-0.522336},
+  {1.072758,0.533772},
+  {0.010905,-0.615835},
+  {-0.267041,0.338341},
+  {-0.163231,-0.172623},
+  {-0.298143,-0.844671},
+  {-0.996324,0.395993},
+  {0.351228,0.210237},
+  {-0.408737,1.852449},
+  {1.371179,-0.270106},
+  {0.698624,-0.186227},
+  {0.764440,-1.018351},
+  {-0.417185,-0.489324},
+  {-0.254638,-0.780647},
+  {-0.589837,-1.171805},
+  {1.132576,-0.812185},
+  {0.071797,0.075910},
+  {-0.142160,-0.205967},
+  {-0.131813,-1.570445},
+  {-0.646197,-0.501273},
+  {-0.343572,-0.550584},
+  {-0.384814,0.182407},
+  {1.396442,-0.058372},
+  {1.089823,0.806014},
+  {0.613392,0.111495},
+  {-0.619374,-0.997811},
+  {0.937457,0.236635},
+  {-1.783063,-0.017353},
+  {0.639293,1.721414},
+  {-0.973684,-0.595704},
+  {0.588127,2.077128},
+  {-0.508637,0.421534},
+  {-0.204767,-0.116534},
+  {-0.925742,-0.808087},
+  {-0.247853,0.383247},
+  {0.122339,-0.377588},
+  {-0.245016,1.239323},
+  {-1.251013,1.414176},
+  {-0.595604,0.183438},
+  {0.165761,0.973419},
+  {-0.360977,0.533837},
+  {-0.156010,1.266329},
+  {-0.361477,-0.706989},
+  {-1.278243,-0.570395},
+  {0.188787,-0.241089},
+  {0.695269,-0.016308},
+  {0.336792,1.128790},
+  {-0.195083,-0.486791},
+  {0.435703,-1.218875},
+  {-0.892865,0.992856},
+  {-0.503019,-0.799460},
+  {0.305161,-0.872681},
+  {0.824504,0.670722},
+  {-0.057163,-0.737607},
+  {-0.459377,-0.426213},
+  {0.661363,-0.123470},
+  {0.291500,-0.574575},
+  {0.736858,-0.048679},
+  {-1.798391,-0.674830},
+  {-1.124265,-0.210419},
+  {0.305464,0.240427},
+  {0.660762,0.390722},
+  {-2.191616,-0.299109},
+  {0.764942,-0.333123},
+  {-0.766828,-0.575533},
+  {0.609647,-0.179405},
+  {0.010595,-0.673221},
+  {0.496617,0.041268},
+  {0.961196,-0.055449},
+  {-0.225309,0.834606},
+  {1.114384,-0.055796},
+  {-0.222813,-0.099848},
+  {-0.120519,0.033593},
+  {1.015066,-0.116109},
+  {-0.906373,0.667821},
+  {-1.147539,-1.158675},
+  {-0.339648,-0.873359},
+  {-0.489429,-0.652974},
+  {-0.607693,0.915098},
+  {-0.739589,-0.880921},
+  {-0.519588,0.827766},
+  {0.166684,-0.028429},
+  {-0.621222,-0.143460},
+  {0.186200,-0.213188},
+  {-0.815053,-0.375461},
+  {0.459186,0.134372},
+  {0.218895,0.177810},
+  {0.028394,-0.083888},
+  {-0.673259,-0.245137},
+  {1.213576,-0.494994},
+  {-0.504661,1.291076},
+  {0.485929,0.212768},
+  {-0.050601,1.330620},
+  {-0.127089,1.121260},
+  {-0.062864,1.184358},
+  {0.388036,0.065984},
+  {0.639649,0.940623},
+  {0.345500,-0.926372},
+  {0.294821,0.080969},
+  {-0.675096,0.401880},
+  {-0.457889,-1.034898},
+  {0.546379,-0.123306},
+  {1.925229,0.617684},
+  {0.036275,0.153092},
+  {0.438382,-0.367055},
+  {-1.510804,-0.350652},
+  {0.511549,0.357008},
+  {0.058650,-0.056035},
+  {0.426843,0.291233},
+  {0.647381,1.340631},
+  {-0.459728,0.946206},
+  {-0.626630,0.024277},
+  {-0.023095,-0.808970},
+  {0.409768,-1.094577},
+  {-0.364498,0.100205},
+  {0.584196,-0.029047},
+  {-1.299973,-1.205881},
+  {-1.467178,1.165527},
+  {0.651701,-0.056131},
+  {0.591321,0.585146},
+  {1.050908,-0.864838},
+  {-1.010467,0.869663},
+  {0.286195,0.382027},
+  {-0.407370,0.606735},
+  {0.731817,-0.248191},
+  {0.594029,0.949877},
+  {1.107643,0.816630},
+  {0.112756,-0.800629},
+  {-0.936598,-0.635692},
+  {0.320902,-1.154471},
+  {0.362662,0.687527},
+  {-0.772593,-0.345974},
+  {-0.301668,-0.298240},
+  {-0.317592,1.336231},
+  {-0.396778,-0.334856},
+  {-0.506675,-0.312185},
+  {-1.281432,0.149600},
+  {0.401639,-0.418585},
+  {0.782846,0.722927},
+  {0.344150,0.854286},
+  {-0.014517,0.567740},
+  {0.108356,0.024531},
+  {0.902085,-0.055156},
+  {0.826237,-0.713395},
+  {0.244866,0.044681},
+  {-0.176188,0.891915},
+  {-0.420097,-0.253119},
+  {0.417268,0.290663},
+  {0.163310,-0.245311},
+  {-0.182683,-0.297175},
+  {0.631826,-0.030011},
+  {-0.109512,-0.088560},
+  {1.429108,0.225297},
+  {0.155576,0.083817},
+  {1.613520,0.239461},
+  {0.127288,-0.420358},
+  {0.477950,0.504352},
+  {1.328754,-0.163013},
+  {-0.568880,-0.751232},
+  {-0.482506,-1.538834},
+  {-0.059557,0.412963},
+  {0.350223,-0.360451},
+  {0.833328,1.009992},
+  {-0.066145,-0.506290},
+  {-1.529181,0.414709},
+  {1.240990,0.206763},
+  {-1.129462,0.769895},
+  {-0.481806,0.484887},
+  {0.595993,0.725062},
+  {-0.285575,1.347548},
+  {2.330541,-0.013789},
+  {-1.797866,0.257308},
+  {0.905498,0.146234},
+  {-0.319323,-1.413330},
+  {-0.175398,-1.142782},
+  {-0.862556,0.482210},
+  {0.223448,0.729414},
+  {0.578396,-0.016839},
+  {-0.318659,-0.617867},
+  {0.157744,0.530414},
+  {0.123166,-0.362401},
+  {1.806366,0.187194},
+  {0.141849,0.128567},
+  {0.233317,0.139137},
+  {-0.195036,-0.613837},
+  {1.714962,1.593262},
+  {-0.732866,-0.038927},
+  {0.307565,-0.920340},
+  {0.373395,-0.516143},
+  {0.826920,-0.612844},
+  {-0.388779,-0.390229},
+  {-0.862877,0.788258},
+  {0.495550,0.670739},
+  {-0.545650,0.635220},
+  {-0.230298,0.414062},
+  {-0.719266,-0.811359},
+  {-0.999942,1.684412},
+  {0.527479,0.543823},
+  {-0.743616,0.101886},
+  {-0.199070,0.115074},
+  {-0.870949,0.256787},
+  {0.142208,0.122864},
+  {1.178514,-0.092691},
+  {0.516611,0.664212},
+  {-0.414682,1.125980},
+  {0.378510,-0.100979},
+  {0.283304,-0.277420},
+  {-0.208157,-0.202171},
+  {-0.440988,-0.820237},
+  {1.298009,-0.850293},
+  {0.779159,-0.461672},
+  {0.149934,1.508017},
+  {0.095404,-0.092000},
+  {-0.337095,-0.317412},
+  {-0.629736,-0.111690},
+  {-0.399381,0.078341},
+  {-0.479442,-0.187099},
+  {-0.760090,0.125670},
+  {-0.610029,-0.278563},
+  {0.649156,0.494456},
+  {-0.672965,0.631743},
+  {-0.016562,0.306273},
+  {-0.609100,0.137436},
+  {0.652638,1.047158},
+  {0.026014,-0.348532},
+  {0.423324,-0.479491},
+  {-0.383879,0.485369},
+  {-0.598911,-0.835369},
+  {0.115294,-0.571799},
+  {-0.125615,0.202125},
+  {-0.909276,-0.587717},
+  {-0.727220,0.093925},
+  {-0.134042,-0.601821},
+  {-0.187468,-0.669988},
+  {0.370470,0.393121},
+  {-0.691281,0.520446},
+  {-0.548105,-0.687475},
+  {1.223865,0.276014},
+  {-0.770862,-0.529642},
+  {-0.147001,-0.466523},
+  {-0.573650,0.453058},
+  {-0.592723,0.439779},
+  {-0.455307,-0.206169},
+  {1.320446,0.684046},
+  {-0.935463,-0.447754},
+  {0.703593,-1.016309},
+  {-0.891936,-0.175935},
+  {0.328758,-0.396236},
+  {0.094338,0.221705},
+  {-1.404257,-0.190658},
+  {-0.100089,1.039360},
+  {-0.966548,0.827384},
+  {-1.253737,-1.014768},
+  {-0.346418,-1.267854},
+  {-0.158700,1.164901},
+  {-0.034736,0.009220},
+  {0.545952,-0.246464},
+  {0.717271,-0.093260},
+  {0.676085,-0.863656},
+  {0.493132,-0.105922},
+  {-0.533072,0.636553},
+  {-0.216843,0.884234},
+  {0.111424,0.082110},
+  {1.028141,0.146957},
+  {-0.446215,0.136231},
+  {0.730978,-0.275731},
+  {0.042365,0.048442},
+  {-0.370711,-0.543378},
+  {0.106057,1.265886},
+  {0.379243,-0.330497},
+  {1.108852,-0.723866},
+  {-0.110398,0.511860},
+  {-0.106902,0.174878},
+  {1.148426,-0.603670},
+  {-0.128195,0.280598},
+  {0.764800,-0.358176},
+  {-0.266245,0.816531},
+  {0.114914,-0.539096},
+  {0.114034,-0.367231},
+  {2.141155,-1.484656},
+  {-0.724135,-0.856970},
+  {0.266306,-0.874060},
+  {0.846456,0.435570},
+  {0.066472,0.252900},
+  {-1.088643,-1.133248},
+  {-0.566947,0.767431},
+  {0.619468,-0.550164},
+  {0.029218,1.459059},
+  {1.301080,0.095710},
+  {1.753613,-0.553147},
+  {1.516418,-0.318869},
+  {0.861448,-0.472804},
+  {-1.047020,-0.037668},
+  {-0.123383,0.272455},
+  {-0.124143,1.500702},
+  {0.378722,0.458093},
+  {-1.369372,-0.010599},
+  {-1.027065,0.948843},
+  {0.152530,-0.545888},
+  {-0.239192,0.716174},
+  {0.874709,-1.022073},
+  {-0.259942,-0.432089},
+  {0.315777,-0.677813},
+  {-0.187516,0.604001},
+  {-0.350366,-0.868253},
+  {0.358178,0.239084},
+  {-0.355413,0.043801},
+  {-0.114867,0.567550},
+  {0.031781,0.301042},
+  {-0.447827,-0.086481},
+  {0.347362,-0.347636},
+  {1.466736,-1.298975},
+  {1.198740,-0.131404},
+  {1.300932,0.897703},
+  {0.490673,-0.229079},
+  {-0.330844,-0.232505},
+  {0.025943,0.810266},
+  {-0.261850,-0.280763},
+  {-0.607853,1.415846},
+  {0.498158,-1.107135},
+  {0.674920,-1.200670},
+  {-0.527907,0.318037},
+  {-0.097676,0.532536},
+  {-0.475594,0.848160},
+  {1.642276,-0.891873},
+  {-0.019197,-0.109536},
+  {0.784795,0.260554},
+  {-0.431823,-0.907632},
+  {-0.763132,-0.342258},
+  {0.570806,-0.517628},
+  {-0.522336,0.403684},
+  {0.307563,-1.143478},
+  {0.825753,0.031997},
+  {0.368023,-0.139664},
+  {2.021968,-0.943570},
+  {0.245160,-0.269865},
+  {1.303964,0.871270},
+  {-0.453218,0.819811},
+  {0.594784,0.655540},
+  {-0.891577,-0.373922},
+  {0.538908,-0.710190},
+  {0.930254,0.481708},
+  {0.307017,-0.652410},
+  {-0.201791,-0.804746},
+  {-0.740248,-0.045989},
+  {0.865316,0.507359},
+  {0.112008,0.675150},
+  {0.390570,-0.737997},
+  {0.588187,-0.739911},
+  {-0.557253,0.208247},
+  {-1.425644,-0.743117},
+  {0.400609,-1.036328},
+  {0.703460,0.720835},
+  {-1.235671,0.360834},
+  {0.977538,0.800469},
+  {-0.215826,-0.917093},
+  {0.464002,-0.108658},
+  {-0.170525,1.430161},
+  {0.249880,0.881905},
+  {0.039538,0.515360},
+  {0.589463,1.687736},
+  {-0.918504,0.398258},
+  {0.885603,-0.419459},
+  {-0.103454,0.517781},
+  {-1.403384,0.991157},
+  {-1.129402,-0.084304},
+  {0.631421,-0.053522},
+  {1.013885,-0.201949},
+  {0.677556,0.891074},
+  {0.761542,-0.055830},
+  {1.043183,0.841930},
+  {0.116780,0.047638},
+  {-0.379538,0.850317},
+  {0.899566,-1.508949},
+  {-0.360145,-0.726620},
+  {-0.394237,0.504382},
+  {1.299661,-0.904075},
+  {0.037135,-1.543567},
+  {0.025721,-1.294574},
+  {-0.201345,-0.573420},
+  {-0.805476,1.100473},
+  {-0.222557,0.815637},
+  {0.745171,-0.443108},
+  {-0.051322,0.385340},
+  {0.415288,0.967950},
+  {0.567228,0.929748},
+  {-0.981482,0.368396},
+  {-0.322623,0.925524},
+  {0.036004,-1.359715},
+  {-1.239654,0.547052},
+  {0.569381,0.209552},
+  {0.999405,0.435894},
+  {0.209398,-0.035708},
+  {-0.616545,-1.367319},
+  {-0.032505,0.893263},
+  {-0.753972,-0.284855},
+  {-1.122253,0.694921},
+  {0.062416,0.560687},
+  {-0.867416,0.682553},
+  {-0.093222,0.154366},
+  {-0.881648,0.429238},
+  {-0.190308,-2.089628},
+  {0.066021,0.756615},
+  {0.514725,-0.798372},
+  {0.053171,-1.408616},
+  {0.209844,0.661365},
+  {-0.353419,0.830578},
+  {0.283011,-0.510899},
+  {1.844187,0.067852},
+  {0.452893,0.042450},
+  {1.522679,0.732928},
+  {0.455406,-0.622942},
+  {0.434744,-0.877805},
+  {0.156233,0.549888},
+  {-0.488361,0.683512},
+  {-0.709181,-0.074767},
+  {1.094457,-1.430172},
+  {-1.090533,-1.200256},
+  {0.467875,-1.396375},
+  {-0.216862,0.998395},
+  {0.845417,0.461581},
+  {-0.243621,-1.037224},
+  {1.009367,-0.804843},
+  {-0.733158,-0.634989},
+  {-0.317695,0.187141},
+  {1.042970,-0.479150},
+  {0.574917,-0.396721},
+  {-0.753535,0.501924},
+  {0.176516,0.011773},
+  {-0.252053,-0.567245},
+  {0.523082,0.913279},
+  {-1.555099,0.401929},
+  {-0.437464,0.181542},
+  {-0.873226,0.044419},
+  {0.219685,1.157821},
+  {-0.254417,-1.517094},
+  {0.091563,-0.354438},
+  {-0.528333,-0.170731},
+  {0.995211,0.678314},
+  {-0.898812,-0.064997},
+  {-0.013840,0.293050},
+  {-0.839259,-0.587023},
+  {-0.945978,-0.617619},
+  {-0.895625,0.302625},
+  {1.051869,0.573372},
+  {-0.825980,-0.122912},
+  {0.163980,1.256745},
+  {0.706734,0.124522},
+  {-0.361175,0.101887},
+  {1.057818,-0.426948},
+  {-0.675053,1.031729},
+  {0.206726,0.279056},
+  {0.389211,-0.301896},
+  {1.063765,0.619761},
+  {0.352544,0.613860},
+  {0.128183,-0.129278},
+  {-0.839177,0.102129},
+  {-1.009067,0.298734},
+  {0.002993,-0.360330},
+  {1.224970,-0.160513},
+  {1.106708,-0.229533},
+  {-1.032136,-0.377685},
+  {-0.236230,0.001354},
+  {0.410400,0.222334},
+  {0.392320,1.483927},
+  {0.665122,0.691449},
+  {-0.455393,-0.602445},
+  {-1.351692,0.738197},
+  {-0.766579,0.268302},
+  {1.589365,0.864385},
+  {0.070446,0.850433},
+  {-0.308235,-0.135000},
+  {-0.292362,-1.347597},
+  {1.555687,-0.715862},
+  {-0.014022,-0.045398},
+  {-0.446291,1.226295},
+  {-1.032951,-0.093507},
+  {-0.899258,1.039720},
+  {-1.078121,-0.867005},
+  {0.520897,0.494706},
+  {-0.211998,-0.448273},
+  {0.580937,-0.430233},
+  {0.179600,0.873513},
+  {0.808713,-1.022514},
+  {0.555485,0.127189},
+  {0.880953,-0.143050},
+  {1.149157,0.917433},
+  {-0.893810,0.428443},
+  {-1.266854,-0.409126},
+  {-0.626689,0.378355},
+  {-0.164413,-0.184089},
+  {-0.898300,0.593376},
+  {-0.547055,0.834128},
+  {-1.142588,-0.422562},
+  {-0.284378,-0.254682},
+  {0.791523,-0.756468},
+  {0.485108,-0.001937},
+  {-1.059758,-0.298921},
+  {0.575755,0.321922},
+  {0.126469,0.056855},
+  {0.481604,-0.118000},
+  {-0.161121,-0.348846},
+  {-0.018420,0.600699},
+  {1.149129,-0.048108},
+  {-0.542935,-1.132408},
+  {0.615102,0.119735},
+  {-0.401196,-0.056096},
+  {0.240128,-0.191069},
+  {-0.230665,0.650328},
+  {-1.043812,0.267771},
+  {-0.337422,-1.346232},
+  {-1.272762,0.339037},
+  {-0.577232,0.042670},
+  {-0.024654,1.721493},
+  {-0.290755,-0.294420},
+  {0.050099,-0.241641},
+  {0.523826,-0.443739},
+  {1.259578,0.041380},
+  {1.203733,-0.585998},
+  {0.759313,-0.279728},
+  {-0.270898,0.554221},
+  {0.319001,0.630204},
+  {-1.012906,-1.065616},
+  {-0.064960,-0.895967},
+  {-0.439101,-0.524601},
+  {0.648934,-0.701096},
+  {0.990764,-1.487838},
+  {0.266843,0.072485},
+  {-1.337164,-0.177902},
+  {0.882257,-0.971672},
+  {0.443937,1.419520},
+  {0.489435,0.600496},
+  {-1.048080,0.668837},
+  {0.080006,-0.024016},
+  {0.393861,-0.144830},
+  {0.029134,-0.594013},
+  {0.020636,0.866641},
+  {-0.695757,-0.655914},
+  {-0.145142,-0.618203},
+  {-0.302988,-0.495213},
+  {-0.462676,1.085804},
+  {0.153729,-0.610300},
+  {-0.098602,1.025134},
+  {-0.571255,-1.464634},
+  {-0.761817,0.959088},
+  {-0.975994,-0.370398},
+  {-0.313675,0.590253},
+  {0.297074,0.390224},
+  {-0.582347,-0.270186},
+  {-0.652665,-1.353611},
+  {-0.019627,0.000436},
+  {0.117063,0.851400},
+  {-0.123453,-0.339978},
+  {-0.071860,-0.712601},
+  {-0.150279,0.705257},
+  {0.346280,-0.008366},
+  {-0.959111,0.297700},
+  {0.620350,-0.430125},
+  {-0.047112,0.050720},
+  {1.805691,-0.047197},
+  {1.715418,-0.183448},
+  {-1.158967,2.090597},
+  {0.743999,-1.778906},
+  {0.025331,-0.388354},
+  {0.518336,-0.327919},
+  {1.166154,-0.289812},
+  {0.029288,1.018113},
+  {0.007631,-0.292880},
+  {-1.468947,0.677554},
+  {0.948800,-0.363516},
+  {0.363116,-1.186390},
+  {0.033570,-0.368930},
+  {-1.920066,-0.183494},
+  {1.245028,1.360201},
+  {0.157701,0.511411},
+  {-0.725534,0.913929},
+  {-0.642394,0.108628},
+  {1.433083,0.355667},
+  {-0.351948,0.578183},
+  {0.229656,-1.065693},
+  {-0.231833,0.177390},
+  {1.099345,-0.553877},
+  {-1.922732,0.038200},
+  {-0.200014,1.349928},
+  {0.725471,-1.057210},
+  {0.242414,0.445252},
+  {-0.886991,-0.408397},
+  {0.510536,0.822131},
+  {-0.260030,0.343419},
+  {-0.214564,-1.138471},
+  {-0.008637,-0.579129},
+  {-0.761397,-0.872982},
+  {0.350951,0.624380},
+  {0.900611,0.816234},
+  {-0.522778,0.207549},
+  {-0.760791,0.034648},
+  {0.375186,0.362076},
+  {0.112175,0.831388},
+  {-1.242682,-0.022903},
+  {0.331423,0.701496},
+  {0.253687,-0.488079},
+  {-0.873518,0.279186},
+  {0.231592,-0.385780},
+  {-0.701089,-0.501785},
+  {-0.241921,-1.391418},
+  {0.019241,0.106733},
+  {0.591344,-1.051357},
+  {0.745421,-0.610140},
+  {-0.606596,0.169312},
+  {-0.372797,-0.501536},
+  {-0.768757,0.841569},
+  {-0.348190,0.051062},
+  {0.063387,0.584047},
+  {0.329073,-0.791211},
+  {0.514938,0.740972},
+  {0.273985,-0.582246},
+  {-0.967329,0.578559},
+  {0.415417,0.124701},
+  {-0.098539,0.385786},
+  {-0.004510,-0.248503},
+  {0.555897,0.242153},
+  {1.579329,0.015322},
+  {0.230998,1.990804},
+  {0.363098,0.553719},
+  {1.562863,0.478130},
+  {0.026208,0.305355},
+  {1.116516,0.360515},
+  {-0.982566,-0.465728},
+  {-0.508676,-0.878270},
+  {-0.144291,0.415225},
+  {-1.350074,-0.098142},
+  {1.616341,-1.518052},
+  {0.104774,0.015461},
+  {0.374867,-1.531420},
+  {-0.416475,-0.114543},
+  {-0.739622,-1.138037},
+  {-0.923005,1.062459},
+  {-0.664320,-0.280073},
+  {-1.156293,-0.337499},
+  {-0.689945,0.344369},
+  {1.058939,0.443670},
+  {-1.285207,0.147568},
+  {0.475596,0.835141},
+  {-0.239945,1.476067},
+  {0.025039,0.541449},
+  {-0.101321,-0.682732},
+  {-0.546186,-0.130474},
+  {-0.433541,0.503623},
+  {0.464975,1.359146},
+  {-0.567927,0.964406},
+  {-1.219789,-1.539823},
+  {-0.016740,0.669833},
+  {0.182447,-0.271553},
+  {-1.320623,1.306323},
+  {-0.000075,-0.219999},
+  {-1.536075,0.914474},
+  {-1.404556,-1.020084},
+  {-0.150083,0.236011},
+  {0.516978,0.585327},
+  {0.241503,0.030283},
+  {-0.329743,0.849644},
+  {-0.537257,1.132562},
+  {0.817902,-0.281236},
+  {1.432319,0.095690},
+  {0.632687,-0.576622},
+  {-0.734149,0.271036},
+  {0.459345,-0.277828},
+  {0.305288,-0.697961},
+  {-1.187887,0.415304},
+  {0.796687,-0.667703},
+  {0.059859,0.503282},
+  {-0.674526,0.557001},
+  {0.761860,-0.342605},
+  {-0.553691,-0.066432},
+  {0.158447,0.486740},
+  {0.871085,-0.243732},
+  {-0.618374,0.322577},
+  {0.211178,-0.228494},
+  {0.256709,-0.631463},
+  {0.136058,-0.407427},
+  {0.386538,-0.076609},
+  {0.363731,0.067482},
+  {-0.693882,0.964447},
+  {1.052294,-0.778507},
+  {-0.404876,-1.906265},
+  {0.357725,-0.223712},
+  {-0.899349,-0.135851},
+  {0.297922,-0.353175},
+  {0.378138,0.542955},
+  {0.948882,-0.008489},
+  {-1.168557,-0.095203},
+  {0.196487,1.331091},
+  {-1.592780,-0.195128},
+  {0.496292,0.257436},
+  {0.094574,0.257786},
+  {0.179735,0.175672},
+  {-0.773849,-0.867187},
+  {-0.218875,-0.151987},
+  {-1.457404,0.561553},
+  {-0.766543,-1.240765},
+  {-0.311424,-0.241690},
+  {1.593359,-0.990696},
+  {-1.347961,-0.110373},
+  {0.087199,-0.249410},
+  {-0.381577,0.193060},
+  {1.290974,0.330803},
+  {-0.264855,-0.062533},
+  {1.932407,-0.669281},
+  {1.404137,-0.854353},
+  {0.032966,-0.375454},
+  {-0.665186,-0.403770},
+  {-0.669869,0.889790},
+  {0.897455,-0.188428},
+  {0.730249,1.021129},
+  {-0.843537,-0.297006},
+  {0.429220,-0.539707},
+  {0.449427,-0.771936},
+  {-0.429601,0.576114},
+  {0.055077,-0.604795},
+  {-0.278586,0.300688},
+  {0.067531,-1.925382},
+  {-0.924128,-0.958812},
+  {-0.337994,-0.727637},
+  {-0.457529,1.034296},
+  {0.370646,-0.836115},
+  {-0.467752,0.409464},
+  {-0.334921,-0.540654},
+  {0.832486,0.959241},
+  {0.746558,0.657005},
+  {-0.318685,-1.230673},
+  {-0.169521,0.642337},
+  {0.789263,0.831460},
+  {0.223756,0.414123},
+  {-0.325954,-0.321332},
+  {0.075028,0.967698},
+  {0.216434,-0.716844},
+  {-0.776716,0.826807},
+  {-0.074531,0.812789},
+  {-0.537597,1.026980},
+  {0.152495,0.982402},
+  {0.413097,-0.552747},
+  {0.611235,-0.071720},
+  {-0.491325,-0.356869},
+  {-0.486791,-0.626587},
+  {0.204293,-0.436972},
+  {-0.211208,-0.432147},
+  {-0.561132,1.073539},
+  {-0.070137,-0.184257},
+  {-1.115610,-0.477053},
+  {1.018256,0.435396},
+  {0.301658,-0.197887},
+  {-0.147236,1.059088},
+  {-0.888603,0.328241},
+  {-1.070295,-0.599636},
+  {0.316661,0.365444},
+  {-0.212919,-0.409418},
+  {-0.753071,0.087512},
+  {0.404576,0.038580},
+  {-1.504748,-0.267729},
+  {-0.313997,-0.930065},
+  {-0.236354,-1.238931},
+  {-0.376294,0.405383},
+  {1.291459,-0.346108},
+  {-0.297634,0.589772},
+  {0.110657,-0.512851},
+  {-1.955329,-0.456873},
+  {-1.247619,0.482959},
+  {0.083895,-0.640105},
+  {-0.396012,1.108095},
+  {0.909912,-0.470332},
+  {-0.049822,-0.096660},
+  {0.363109,0.186229},
+  {-0.314218,-0.256700},
+  {-0.295377,-0.825150},
+  {-0.122935,0.847107},
+  {0.254378,0.637229},
+  {0.103655,1.262402},
+  {0.673758,-0.803048},
+  {0.318196,-0.206245},
+  {0.385547,0.450488},
+  {-1.392342,0.052822},
+  {-0.665772,0.103675},
+  {0.426712,-1.222266},
+  {-0.075608,-0.769710},
+  {-0.548068,-0.642260},
+  {0.647223,0.860224},
+  {0.483236,0.514534},
+  {0.398769,0.050907},
+  {1.229950,0.745029},
+  {0.911489,1.188746},
+  {-0.099161,-0.697764},
+  {0.247348,-0.284992},
+  {-0.248089,-0.862396},
+  {0.846203,-1.166603},
+  {0.906759,0.708414},
+  {-1.122335,-0.402972},
+  {-0.118882,-0.437190},
+  {-0.430711,0.992516},
+  {-0.985280,-0.933490},
+  {0.753059,-1.029240},
+  {0.074035,1.011795},
+  {-0.554878,-0.736494},
+  {0.137578,-0.170962},
+  {0.010941,0.160870},
+  {-0.287390,-0.081999},
+  {-0.915608,-0.288509},
+  {1.009344,0.455340},
+  {-1.170750,0.374210},
+  {-0.509900,0.696984},
+  {-0.073667,0.542572},
+  {0.508428,-0.509940},
+  {0.162651,-0.619031},
+  {-0.894067,-0.370045},
+  {-1.100994,0.144700},
+  {-0.361678,0.973850},
+  {-0.592640,0.709252},
+  {0.482369,0.464118},
+  {0.646740,0.794370},
+  {-1.518095,-0.047480},
+  {-2.480153,0.558073},
+  {0.171995,-0.118977},
+  {-0.307031,-0.408313},
+  {0.667857,0.886201},
+  {1.215072,-1.815363},
+  {0.636451,-0.999552},
+  {1.038871,0.746703},
+  {0.799771,-0.633650},
+  {-0.478658,0.963576},
+  {0.660793,-0.396006},
+  {-0.366382,-0.010134},
+  {-0.126455,0.550368},
+  {-0.295040,-0.019897},
+  {-0.189119,0.144486},
+  {-0.409427,-0.246134},
+  {-0.749594,1.158845},
+  {-0.619952,-0.568661},
+  {0.418661,-0.682120},
+  {0.022881,-0.611217},
+  {0.745549,-0.999202},
+  {0.223803,-1.326778},
+  {-0.512690,-0.409827},
+  {0.730464,0.154411},
+  {0.304366,0.129614},
+  {1.037600,-0.642403},
+  {-1.589766,0.575436},
+  {1.303312,1.195870},
+  {-0.048468,-0.161105},
+  {-0.583344,0.721412},
+  {-0.598792,-1.629398},
+  {-1.184964,0.686923},
+  {-0.206515,0.128982},
+  {-1.354328,0.347421},
+  {-0.305114,-0.063748},
+  {-0.148754,1.025688},
+  {1.386647,-0.299267},
+  {0.623479,0.660380},
+  {0.111936,-0.215479},
+  {0.164504,-0.448971},
+  {-1.298132,-0.229643},
+  {-0.544931,0.273312},
+  {0.708111,1.131149},
+  {-1.025639,0.983595},
+  {-0.874828,0.448445},
+  {0.083092,0.131569},
+  {-0.199073,0.111786},
+  {0.471144,-0.582538},
+  {-0.002063,-1.209889},
+  {0.036177,-0.191428},
+  {0.048523,-0.482262},
+  {-0.591823,0.022019},
+  {-0.957858,0.379499},
+  {-0.388964,-0.030605},
+  {-1.067693,-0.564523},
+  {0.683215,0.452901},
+  {-0.417523,-0.888896},
+  {0.116388,-0.001175},
+  {-0.530451,-0.402808},
+  {-0.501828,-0.447776},
+  {-0.312741,-0.320066},
+  {0.239558,0.274188},
+  {0.413057,-0.479391},
+  {0.804059,0.228824},
+  {0.251042,-0.392509},
+  {-0.977828,-0.114416},
+  {0.706358,0.019025},
+  {-0.604572,-0.619421},
+  {-0.965764,0.532922},
+  {-0.557196,-0.448498},
+  {0.117221,-2.151584},
+  {0.339451,0.235127},
+  {1.163795,0.355797},
+  {-0.724402,0.409418},
+  {0.255004,0.576204},
+  {-0.258374,0.349667},
+  {1.028698,-0.794530},
+  {0.527963,1.589823},
+  {0.719742,-0.748712},
+  {0.368928,-0.686335},
+  {0.065692,0.585041},
+  {-0.125019,-0.273104},
+  {-0.241274,-0.481545},
+  {0.254201,0.650913},
+  {-0.612250,0.134043},
+  {-0.040628,1.546205},
+  {-0.153613,-0.158336},
+  {0.573747,-0.368891},
+  {0.247576,-0.546121},
+  {-0.327529,-0.227120},
+  {0.909237,0.293783},
+  {-0.641484,1.032472},
+  {0.945376,-0.976555},
+  {-0.097696,-1.005641},
+  {0.280105,0.778472},
+  {0.129635,-0.266768},
+  {0.163724,-0.064104},
+  {0.234504,-0.013251},
+  {-0.745244,2.072479},
+  {-1.437508,0.815776},
+  {-0.742229,-0.540598},
+  {0.532092,-0.390349},
+  {0.231447,-0.072878},
+  {0.459868,-0.668039},
+  {-1.085061,0.706084},
+  {0.666810,-0.686744},
+  {0.881553,0.001870},
+  {0.028822,-1.283565},
+  {-0.420608,0.313733},
+  {-0.114939,-0.901210},
+  {-0.382738,0.663378},
+  {-0.159187,0.391378},
+  {0.413518,0.011760},
+  {-1.145054,-0.174115},
+  {0.657089,-0.093871},
+  {0.439769,-0.078178},
+  {-0.876726,-1.290887},
+  {-0.194151,-0.120212},
+  {-0.573588,-0.601036},
+  {0.480740,-0.445964},
+  {0.246870,0.914457},
+  {1.507856,-0.333776},
+  {1.176638,0.254658},
+  {0.571415,0.268885},
+  {-0.635128,0.650310},
+  {0.383027,-0.382331},
+  {0.464641,-0.511072},
+  {0.874510,-0.963842},
+  {-0.540770,-0.325872},
+  {0.253789,-0.123098},
+  {-0.270305,0.172002},
+  {-1.031316,0.278028},
+  {-0.332885,-0.499473},
+  {0.120825,-0.860634},
+  {-0.643136,-0.068827},
+  {-0.040357,0.200742},
+  {-0.933480,0.185052},
+  {0.771612,-0.286406},
+  {0.939360,-0.140307},
+  {0.028340,0.302658},
+  {-1.188171,-0.068560},
+  {-0.180113,0.072284},
+  {-0.550815,-0.947792},
+  {-0.643721,-0.045899},
+  {0.092203,-0.288068},
+  {0.439139,0.467489},
+  {0.682732,-0.634377},
+  {-0.736317,-0.107723},
+  {-0.237552,-1.170557},
+  {-1.265348,-0.851037},
+  {-0.117957,-0.085973},
+  {1.102227,-0.027409},
+  {0.201656,0.258550},
+  {-0.341302,0.345698},
+  {-0.226687,0.021001},
+  {0.300950,0.747520},
+  {-0.548719,-0.764005},
+  {0.342371,0.650129},
+  {-0.197264,-0.406966},
+  {0.253969,0.590828},
+  {-0.654232,-0.911205},
+  {-0.069347,-0.649115},
+  {-0.302273,-0.962710},
+  {-0.858735,-0.734358},
+  {0.824973,0.347623},
+  {0.561939,-0.332102},
+  {-0.149910,-0.141332},
+  {-0.329960,-0.276681},
+  {-0.477825,0.796294},
+  {-0.929950,-1.013256},
+  {0.660669,-1.277091},
+  {0.992162,0.447772},
+  {-0.304259,1.500934},
+  {-0.057727,0.903363},
+  {0.674917,0.876704},
+  {-0.634144,-0.191583},
+  {0.845197,-1.233301},
+  {-1.661000,0.075804},
+  {-0.514972,0.235703},
+  {0.140527,0.185480},
+  {-0.234079,-1.451824},
+  {-0.405753,0.462321},
+  {1.170499,0.117621},
+  {0.131879,0.114231},
+  {0.965116,-0.378527},
+  {0.206708,-0.220844},
+  {-0.187811,0.488983},
+  {-0.661154,-0.013639},
+  {-1.372899,-0.391042},
+  {-0.208436,0.141927},
+  {-0.900758,0.338770},
+  {-1.061068,-0.473609},
+  {-0.442850,-0.150059},
+  {-0.656915,-0.213440},
+  {-0.519110,0.388374},
+  {0.552973,0.412297},
+  {0.246784,0.360372},
+  {0.037668,-0.058916},
+  {-1.348537,-0.018245},
+  {-0.618509,0.055222},
+  {0.618511,-0.123750},
+  {-0.034437,-0.099757},
+  {0.323428,-0.652759},
+  {0.154987,0.899311},
+  {1.781830,-0.153147},
+  {0.035979,1.188616},
+  {0.488400,0.697546},
+  {-0.446666,0.281943},
+  {-0.453892,0.528215},
+  {-0.688147,-1.008588},
+  {-0.390631,0.389458},
+  {-1.194630,-0.928712},
+  {0.678735,-0.466324},
+  {0.976499,-0.038259},
+  {1.396877,-0.138085},
+  {-1.430019,0.335065},
+  {-0.055289,-0.927780},
+  {0.485662,0.485284},
+  {0.201981,0.537132},
+  {0.363088,1.731858},
+  {-0.668758,0.465720},
+  {0.077665,0.666078},
+  {-1.566421,0.040135},
+  {-0.355676,-1.374433},
+  {-1.271148,0.473298},
+  {-0.709383,-1.088175},
+  {0.072900,-0.383878},
+  {-0.221073,0.694508},
+  {0.979392,0.358300},
+  {-0.468658,-1.257957},
+  {-0.986421,-0.688206},
+  {0.774736,0.025302},
+  {-0.350405,-1.379404},
+  {0.265043,-0.179214},
+  {0.632730,0.655965},
+  {-0.580958,0.073589},
+  {-0.674751,-0.329321},
+  {-0.157258,0.366028},
+  {-0.167454,0.458918},
+  {0.360995,-0.045800},
+  {0.541670,0.414036},
+  {-0.953282,0.396081},
+  {-0.640341,-0.815884},
+  {0.099247,0.488115},
+  {1.028320,-1.065518},
+  {-0.608843,-0.394921},
+  {-0.660332,0.127980},
+  {1.215143,-0.784662},
+  {-0.597942,0.410855},
+  {-0.460977,-1.731878},
+  {-1.125346,-0.522925},
+  {0.160018,-0.890953},
+  {0.354174,0.463096},
+  {0.432617,0.091890},
+  {-0.537692,0.916233},
+  {-0.231298,-1.123082},
+  {0.448289,0.048934},
+  {0.141959,0.248023},
+  {-0.239098,1.258853},
+  {0.659532,0.029834},
+  {1.296697,-0.068587},
+  {-0.566528,0.709376},
+  {-0.408385,-0.069338},
+  {-0.390137,0.783384},
+  {-1.620428,-0.505653},
+  {0.410443,-0.303323},
+  {-0.550195,-0.764973},
+  {-0.576556,0.263301},
+  {-0.600212,0.262565},
+  {-0.122290,-0.126754},
+  {0.331186,-1.519006},
+  {-0.345319,-0.461422},
+  {-0.572596,0.480422},
+  {1.103205,0.915259},
+  {0.118307,1.801626},
+  {-0.764045,0.235550},
+  {-0.022141,1.201361},
+  {0.028013,0.044403},
+  {0.488177,0.026615},
+  {-0.623776,-0.232662},
+  {-0.961218,0.888319},
+  {0.486462,-0.519644},
+  {0.199430,-0.047332},
+  {0.947899,1.148955},
+  {0.169357,-1.336189},
+  {-0.930552,-0.016437},
+  {-0.518731,0.323647},
+  {1.068277,-0.408039},
+  {0.873528,-0.510827},
+  {-0.062329,-0.013528},
+  {0.016866,0.267559},
+  {1.056129,-1.027253},
+  {-0.539801,0.935748},
+  {0.096848,-0.037621},
+  {-0.095070,-0.255447},
+  {-0.848099,0.443100},
+  {0.639670,-0.048560},
+  {0.923418,-0.283416},
+  {1.456548,-1.294075},
+  {-1.764045,-0.439263},
+  {0.461557,0.172525},
+  {-0.436138,0.071867},
+  {-0.673432,0.538713},
+  {0.312169,0.260254},
+  {0.103237,-0.512787},
+  {-1.493843,0.399438},
+  {0.819913,1.366162},
+  {-0.016400,1.497652},
+  {0.215513,-0.225488},
+  {-0.017414,-0.407048},
+  {-0.020617,0.629335},
+  {0.224152,0.982394},
+  {-0.511165,-0.579162},
+  {0.007663,0.124781},
+  {0.108301,0.792560},
+  {0.158005,0.407386},
+  {-0.182543,-0.165334},
+  {1.159181,-0.510782},
+  {0.280196,-1.062985},
+  {0.236496,-0.145702},
+  {-0.422758,1.424397},
+  {-0.331449,-0.193450},
+  {0.192874,-0.427651},
+  {0.112059,0.188264},
+  {-0.272202,0.107938},
+  {-0.760328,-0.363161},
+  {-0.726426,1.597634},
+  {-0.071579,0.949224},
+  {0.308458,0.255762},
+  {1.021180,-0.266580},
+  {0.143714,0.679690},
+  {0.402213,-0.431472},
+  {0.325377,-0.219868},
+  {1.102590,0.967718},
+  {0.358516,-0.734835},
+  {0.014624,0.178090},
+  {0.448299,-0.407042},
+  {-0.611858,-0.011623},
+  {1.077674,-0.250480},
+  {-0.299770,0.274045},
+  {-0.091250,0.162794},
+  {0.263684,0.580732},
+  {-0.524096,0.453355},
+  {1.220175,-0.439485},
+  {0.505437,0.769273},
+  {-0.448804,-0.993002},
+  {-0.443388,-0.483274},
+  {-0.523477,-0.401425},
+  {-0.313273,-0.056149},
+  {0.050769,0.557578},
+  {-0.702026,-0.345979},
+  {-0.323416,0.362591},
+  {0.804164,0.415913},
+  {0.366415,0.231610},
+  {-0.674289,2.719386},
+  {-0.390476,-0.001017},
+  {0.634584,0.043129},
+  {-0.165932,-0.088890},
+  {-0.084003,0.164003},
+  {0.326900,-0.176912},
+  {0.846530,-0.575045},
+  {0.379000,-0.560151},
+  {-0.045598,-1.256528},
+  {0.004132,-0.330289},
+  {0.801731,0.102068},
+  {0.310208,-0.016975},
+  {0.804024,-0.848600},
+  {0.530551,0.564239},
+  {-0.217442,-0.406346},
+  {0.482194,-0.354971},
+  {1.013284,0.341576},
+  {-0.189813,-0.158867},
+  {0.057823,0.314484},
+  {-0.385227,0.961346},
+  {-0.252099,0.877088},
+  {-0.150246,0.399242},
+  {0.227240,-0.011056},
+  {-0.906256,0.232546},
+  {0.447790,0.615224},
+  {0.710736,0.413033},
+  {0.332351,0.394525},
+  {-1.111575,-0.892920},
+  {0.671354,0.236546},
+  {-0.530462,0.833944},
+  {-0.487734,-0.933744},
+  {-0.279573,0.015821},
+  {0.150636,0.941044},
+  {-0.490255,-1.718709},
+  {-0.562611,-0.050636},
+  {0.161397,-0.336955},
+  {-0.581458,0.013550},
+  {1.301819,-0.243034},
+  {0.328760,-0.383835},
+  {-0.558614,0.312557},
+  {-0.994847,-0.123656},
+  {-0.946885,-0.460904},
+  {-0.150270,0.629816},
+  {0.059610,-0.005996},
+  {-0.577683,-0.466143},
+  {-0.471025,-0.278965},
+  {-0.148945,-0.324783},
+  {1.276411,0.305076},
+  {0.980279,-0.070273},
+  {1.162642,0.100148},
+  {1.843762,0.357636},
+  {-1.342349,-0.353233},
+  {-0.436687,-0.095269},
+  {-0.805848,0.606225},
+  {0.871641,-1.329340},
+  {0.184974,1.265810},
+  {-0.244617,-0.882645},
+  {-0.907868,-0.039793},
+  {1.031712,0.603956},
+  {-0.320916,0.296021},
+  {0.769198,0.408169},
+  {0.273306,-1.560085},
+  {-0.845221,-0.120352},
+  {-0.292803,-0.487164},
+  {-1.188451,1.021220},
+  {0.712612,-0.904145},
+  {1.536593,0.458014},
+  {0.948114,-0.292910},
+  {0.183039,-0.763955},
+  {2.157607,-0.224608},
+  {-0.273569,-0.394222},
+  {-0.431183,0.416926},
+  {0.132424,-0.348722},
+  {0.753581,1.216860},
+  {-0.337171,-0.893545},
+  {-1.120653,-0.243974},
+  {1.019687,0.181340},
+  {1.477047,-0.821085},
+  {0.046624,-0.107856},
+  {0.433614,-0.195993},
+  {-0.405870,-1.017501},
+  {-0.050243,0.119354},
+  {-0.671673,0.243350},
+  {-0.315893,1.721316},
+  {-0.083615,0.238805},
+  {-1.037536,0.577163},
+  {-0.913802,-0.523424},
+  {1.219618,-0.315761},
+  {1.146100,0.517259},
+  {-0.895445,-1.015857},
+  {0.514174,0.575290},
+  {-0.123435,0.745106},
+  {0.702053,0.848669},
+  {-0.342611,-0.957096},
+  {-0.289839,-0.316382},
+  {-0.397795,0.021996},
+  {-0.677843,0.971322},
+  {0.361514,-0.183216},
+  {0.080051,-0.295673},
+  {1.160202,-0.910675},
+  {-0.150463,0.736822},
+  {-0.709405,-0.203295},
+  {-0.350063,0.552303},
+  {-0.721111,0.319029},
+  {-0.253701,-0.103668},
+  {-0.750172,-0.320345},
+  {-1.206247,-0.063426},
+  {-1.373506,0.124767},
+  {0.508866,0.460720},
+  {-1.336954,0.210008},
+  {-0.631641,-0.072041},
+  {0.928787,-1.037158},
+  {0.032754,1.022849},
+  {0.666725,-0.698994},
+  {-0.426685,0.073876},
+  {0.641602,0.815373},
+  {0.375179,-0.463772},
+  {-0.233340,1.332766},
+  {-0.588562,0.673215},
+  {-1.583380,0.174935},
+  {0.183747,-0.026180},
+  {-0.037925,-0.435531},
+  {0.421545,-1.077913},
+  {0.739201,0.256848},
+  {0.278009,-0.012421},
+  {1.071530,-1.464473},
+  {0.879311,0.140050},
+  {0.690285,-0.379450},
+  {-0.359215,0.696639},
+  {0.445641,1.003849},
+  {-0.471426,0.216653},
+  {0.747519,-0.191435},
+  {0.609888,1.087821},
+  {-0.114237,0.707995},
+  {0.310145,-0.068274},
+  {0.238114,0.520310},
+  {0.188092,-0.863861},
+  {-0.272074,0.545071},
+  {-0.584299,0.335263},
+  {0.568218,0.803199},
+  {-0.430740,0.419229},
+  {-0.900838,0.175793},
+  {0.241127,0.980598},
+  {0.229357,-0.402579},
+  {-0.005071,0.451806},
+  {-0.169403,0.001801},
+  {0.498114,0.632898},
+  {0.880223,-0.529746},
+  {-0.868428,0.322017},
+  {-0.934466,0.316410},
+  {-0.153631,-0.037373},
+  {-0.402630,-0.960009},
+  {0.069345,1.147181},
+  {0.538025,0.497931},
+  {-0.752724,0.353508},
+  {1.119766,0.340039},
+  {2.267532,-0.419679},
+  {0.867285,-0.861810},
+  {-0.219850,0.147761},
+  {-1.333873,0.140060},
+  {0.349306,-0.296989},
+  {1.246670,-0.360293},
+  {0.448126,1.393103},
+  {0.458653,-0.009429},
+  {0.897902,0.163413},
+  {-0.423687,0.569503},
+  {0.533119,-0.220683},
+  {-0.561732,-0.975309},
+  {0.881865,0.101322},
+  {-0.304062,0.840913},
+  {0.773744,-0.251265},
+  {0.767785,-0.089005},
+  {0.093558,0.166969},
+  {-0.144223,0.543223},
+  {0.599210,-0.139195},
+  {-0.757562,0.974285},
+  {1.287608,-1.166102},
+  {0.851889,0.840470},
+  {-0.060754,1.083686},
+  {0.613368,0.304015},
+  {-0.379987,-0.439814},
+  {-0.329733,-0.112941},
+  {-0.424859,-0.739637},
+  {-1.793210,-1.188762},
+  {-0.635379,-0.904453},
+  {0.257752,-1.166231},
+  {0.795667,-1.099593},
+  {0.943045,-0.741673},
+  {0.132503,-0.740775},
+  {-0.441437,-0.158045},
+  {0.625827,-0.791281},
+  {0.206786,0.183906},
+  {0.838373,-0.394791},
+  {0.800490,0.460415},
+  {0.158553,0.035947},
+  {0.941686,1.030037},
+  {-0.449424,0.181222},
+  {-0.064192,0.321760},
+  {-0.818197,-0.517869},
+  {-1.001442,-0.964262},
+  {-0.341690,0.209038},
+  {0.769880,-0.509106},
+  {-1.800834,-0.977495},
+  {0.934141,-0.956871},
+  {-0.544929,-0.234843},
+  {0.052514,-0.188411},
+  {0.020671,0.409432},
+  {-0.446867,0.177584},
+  {-0.018809,0.439592},
+  {-1.004284,-1.141000},
+  {0.165529,-0.054725},
+  {0.209767,0.617396},
+  {-0.141390,-0.133027},
+  {-0.035609,0.141281},
+  {-0.178184,1.191617},
+  {0.543428,0.601854},
+  {-0.095008,-0.455613},
+  {-0.059113,0.233037},
+  {0.233059,-0.139516},
+  {0.272380,-1.266193},
+  {0.618656,0.116292},
+  {-0.009285,0.623049},
+  {0.096660,0.123946},
+  {-1.580974,0.525244},
+  {0.206597,1.002594},
+  {0.089974,-0.500957},
+  {1.895818,0.543035},
+  {-0.305681,0.122755},
+  {0.221252,0.227730},
+  {-0.820677,-0.365112},
+  {0.947046,0.458062},
+  {0.542810,-0.838007},
+  {-0.052196,-0.075847},
+  {0.814450,-0.744863},
+  {-0.567190,0.264126},
+  {0.237717,0.018269},
+  {-0.703420,0.405742},
+  {0.614185,0.753346},
+  {-1.418353,0.214996},
+  {-0.860688,0.915467},
+  {-0.360367,-0.260405},
+  {1.472941,0.435927},
+  {0.446222,0.730291},
+  {-0.144925,-0.561438},
+  {-1.750887,-0.525869},
+  {0.340149,-0.191235},
+  {0.377149,0.915875},
+  {0.114776,0.838241},
+  {1.129547,-0.141350},
+  {0.184851,-0.695700},
+  {-0.534036,-0.634324},
+  {-0.340427,0.321547},
+  {-0.404642,-0.697021},
+  {-0.253808,-0.192746},
+  {-0.596530,-0.932647},
+  {-0.838994,-0.405391},
+  {-0.755491,-0.342310},
+  {-0.057286,-0.358306},
+  {-1.447241,1.301361},
+  {-1.313619,-1.013152},
+  {-0.571824,0.109239},
+  {-0.260698,0.606990},
+  {0.070246,0.534229},
+  {0.597517,-0.037879},
+  {-1.094173,-0.410137},
+  {-0.254631,-0.246340},
+  {0.431483,-0.376672},
+  {0.519113,0.214955},
+  {-0.076563,0.738583},
+  {0.205809,-1.447609},
+  {-0.810528,-0.234393},
+  {0.229555,0.246711},
+  {0.927126,0.590173},
+  {-0.466521,-1.469152},
+  {0.695727,1.527739},
+  {-1.704484,-0.591690},
+  {0.307858,0.231491},
+  {-0.995968,0.318885},
+  {0.661263,-0.555950},
+  {-0.712018,0.863494},
+  {0.187289,-0.103648},
+  {0.148728,0.440236},
+  {-0.416693,0.421814},
+  {-0.285165,-1.497392},
+  {-1.351142,-0.185347},
+  {0.484214,-0.136529},
+  {0.573682,-1.192687},
+  {0.410345,-0.315465},
+  {0.848424,0.671905},
+  {-1.103233,0.644873},
+  {1.299410,0.565215},
+  {-0.461676,0.064235},
+  {-1.379040,-0.432968},
+  {-1.015434,-1.145416},
+  {0.129534,0.363062},
+  {0.104220,0.288515},
+  {1.543944,-1.307105},
+  {0.221840,0.109014},
+  {-0.184143,0.370434},
+  {0.058980,0.873678},
+  {0.551447,-0.039445},
+  {-0.270308,0.105572},
+  {0.469465,-0.104565},
+  {0.015573,0.788276},
+  {0.749307,1.602021},
+  {-0.203181,-0.465786},
+  {0.133115,-1.936805},
+  {-0.429016,-0.726444},
+  {-0.149023,-0.362963},
+  {0.397963,-0.235261},
+  {1.558527,0.044457},
+  {-0.972298,0.805232},
+  {-0.807760,-0.399592},
+  {0.280215,0.243919},
+  {0.137227,-1.792080},
+  {-0.651625,0.507164},
+  {0.275789,-0.969788},
+  {-0.254710,-0.494221},
+  {-0.568344,-0.391331},
+  {-0.403117,-0.847222},
+  {0.850632,0.551661},
+  {0.375400,0.202567},
+  {0.407655,0.339162},
+  {-0.077186,-0.944989},
+  {0.853879,0.321790},
+  {-0.878723,1.078369},
+  {0.402514,0.134404},
+  {-0.636014,0.028282},
+  {-0.306382,-0.725383},
+  {0.596217,0.775472},
+  {0.743227,0.136710},
+  {0.318624,0.141530},
+  {-2.436086,1.380653},
+  {-1.525091,-0.330171},
+  {0.786829,-0.068407},
+  {-0.268204,0.051274},
+  {0.026261,-0.264944},
+  {0.284678,0.800642},
+  {1.139380,-0.635677},
+  {0.531484,1.095444},
+  {0.061698,-1.585712},
+  {-0.200152,-0.292121},
+  {0.511662,1.497851},
+  {-1.734319,0.421699},
+  {0.730265,-0.139450},
+  {-0.853009,-0.131672},
+  {0.279669,0.232947},
+  {-0.265099,-0.688263},
+  {-0.929645,-0.286772},
+  {-0.125102,-1.125642},
+  {1.064545,0.166148},
+  {0.733526,-0.916868},
+  {-0.934886,0.513751},
+  {1.207510,1.425677},
+  {-0.027745,0.571540},
+  {-1.475919,-1.304595},
+  {0.891606,-0.522466},
+  {-1.132359,-0.916251},
+  {0.769611,1.058327},
+  {-0.787181,-0.146081},
+  {-0.219027,0.104576},
+  {-0.095533,0.083469},
+  {-0.115227,0.014563},
+  {-1.070410,0.746173},
+  {1.109839,-1.229791},
+  {-0.326565,0.830876},
+  {0.286977,0.532019},
+  {-0.769394,0.226197},
+  {0.754521,0.827572},
+  {-0.361735,-0.367817},
+  {-0.546435,-0.902863},
+  {0.746461,-0.939287},
+  {-0.625963,1.456091},
+  {-0.244332,0.173159},
+  {0.735755,0.338783},
+  {1.161011,-0.592912},
+  {0.316221,-0.277843},
+  {-0.515322,-0.171536},
+  {-0.073174,0.804972},
+  {1.050407,-1.065537},
+  {0.484378,0.954140},
+  {0.939704,-0.717131},
+  {-0.746289,0.125873},
+  {0.306167,0.822975},
+  {-0.688430,-0.009492},
+  {0.473809,-0.195759},
+  {-0.291123,-0.887642},
+  {-1.113639,-0.205191},
+  {0.507462,-1.139016},
+  {-1.047570,1.061075},
+  {0.076114,0.502083},
+  {-0.009567,0.771579},
+  {0.277710,-1.082459},
+  {-0.030487,-0.792313},
+  {-0.005490,-0.038347},
+  {-0.070947,-0.641452},
+  {0.064114,-1.279288},
+  {-0.735976,-0.177716},
+  {-1.173461,-0.963224},
+  {0.642447,-1.215458},
+  {-0.542537,-0.779186},
+  {0.208617,0.707524},
+  {-0.815926,0.734432},
+  {-1.362503,0.826668},
+  {0.171331,-0.098047},
+  {0.299502,-0.977795},
+  {-1.423973,0.972393},
+  {1.079616,-1.087319},
+  {-0.301928,0.824269},
+  {1.239375,0.407183},
+  {0.060999,-0.016179},
+  {0.804982,-0.385257},
+  {-0.012938,0.677340},
+  {-0.121473,1.046107},
+  {-0.173294,-0.590221},
+  {0.680903,0.172555},
+  {0.901474,-0.638362},
+  {-0.754168,0.954427},
+  {-1.017190,0.458050},
+  {-0.893258,-0.651492},
+  {-1.223616,0.734166},
+  {-0.551561,0.465105},
+  {-0.472743,-1.538767},
+  {-0.643332,0.237332},
+  {-1.403355,-0.712716},
+  {-0.696300,0.281854},
+  {0.063601,0.242936},
+  {0.140091,-0.361881},
+  {-0.466220,0.056740},
+  {0.400082,0.655608},
+  {-0.218787,0.165453},
+  {0.162508,0.460463},
+  {0.196531,0.805585},
+  {0.867586,-0.796481},
+  {-0.103192,-0.372709},
+  {1.480107,-0.244144},
+  {-0.377288,-0.616448},
+  {0.827771,0.615012},
+  {0.241670,-0.067976},
+  {0.159564,-0.039752},
+  {0.202995,-0.531926},
+  {-0.635295,-0.300095},
+  {-0.112240,-0.452463},
+  {-0.005874,-1.283824},
+  {-0.902111,-0.502776},
+  {0.246129,0.198008},
+  {0.478389,0.145563},
+  {0.441332,0.687473},
+  {-0.247149,0.184176},
+  {-0.789643,-0.991969},
+  {-1.231853,-0.521080},
+  {0.419307,-1.074857},
+  {0.844709,0.320482},
+  {1.197865,0.314086},
+  {-0.515979,0.581945},
+  {-0.331012,-0.496182},
+  {-0.030485,0.691218},
+  {-0.148168,0.839336},
+  {-0.386217,-0.545061},
+  {0.377549,-2.132758},
+  {-0.636174,-0.065140},
+  {-0.578408,0.476528},
+  {-0.770655,0.716478},
+  {-0.315434,0.652659},
+  {-0.095634,0.084278},
+  {-0.454542,0.493002},
+  {-0.466113,-0.638183},
+  {-0.452908,0.032110},
+  {0.612871,-0.006891},
+  {-0.519763,-0.980015},
+  {0.216004,1.044187},
+  {-0.522556,-1.037992},
+  {0.191915,-0.608267},
+  {1.409379,-0.193706},
+  {-0.007437,-0.406039},
+  {-0.109688,-0.212492},
+  {0.014242,-0.315274},
+  {-1.498715,-0.045784},
+  {0.823582,-0.518037},
+  {0.453221,-0.453072},
+  {0.308668,0.963767},
+  {-0.639039,-0.106259},
+  {-0.295817,-1.112948},
+  {0.149772,1.651655},
+  {-0.190802,0.742309},
+  {-0.697535,0.406187},
+  {0.803067,-0.505165},
+  {-0.543679,-0.703909},
+  {-0.455789,0.354645},
+  {-0.801542,-0.036586},
+  {0.803856,-0.099847},
+  {-1.193883,-0.353241},
+  {1.075654,0.052465},
+  {-0.258694,-0.040366},
+  {-0.699399,-0.209583},
+  {-0.215574,-0.004929},
+  {0.632563,0.109047},
+  {-0.472713,1.246852},
+  {0.558519,0.764899},
+  {-1.312153,-0.650642},
+  {0.319234,0.096798},
+  {-0.116014,1.918017},
+  {0.348943,-0.098542},
+  {-0.517133,-0.367209},
+  {-0.032548,-1.034303},
+  {0.328535,-0.909280},
+  {0.458397,1.012904},
+  {0.159957,0.751975},
+  {0.448532,1.165521},
+  {-0.289242,-1.073650},
+  {0.221077,0.996689},
+  {0.271276,0.400481},
+  {-0.293484,0.257531},
+  {0.380645,-0.869409},
+  {1.060007,-1.185366},
+  {-0.683863,-0.654862},
+  {0.335272,0.036245},
+  {-0.230655,0.834185},
+  {-0.012915,-0.531325},
+  {0.024833,-1.050938},
+  {-0.708008,0.918939},
+  {-0.825306,-0.060127},
+  {0.253139,0.491280},
+  {0.680471,0.175579},
+  {-0.198326,-0.665312},
+  {-0.922970,-0.808154},
+  {0.156470,-0.797370},
+  {-0.783536,-0.469965},
+  {0.341051,0.873579},
+  {-2.007647,0.681225},
+  {0.364041,-0.508894},
+  {-0.015955,0.350543},
+  {-0.291678,-0.998941},
+  {0.239003,-0.487403},
+  {-0.327758,-0.508257},
+  {-0.539391,-0.798760},
+  {-0.540462,-0.564731},
+  {-0.620798,0.707924},
+  {0.256000,0.452068},
+  {0.385059,1.172229},
+  {0.360328,-0.171884},
+  {-0.572500,0.532958},
+  {0.648164,0.071339},
+  {-1.027705,-1.054336},
+  {0.522261,-0.590621},
+  {-0.019556,0.572396},
+  {0.607990,0.481700},
+  {-1.322499,0.788470},
+  {-0.684229,-0.473861},
+  {-1.265839,1.105980},
+  {-0.581971,-0.124401},
+  {0.444034,0.102150},
+  {0.794992,0.031055},
+  {0.603776,0.000266},
+  {0.877366,0.024301},
+  {0.277579,0.682971},
+  {-0.109226,0.230966},
+  {-0.935434,0.116535},
+  {-0.083082,0.334694},
+  {0.362059,-0.024471},
+  {0.753738,0.122144},
+  {0.304294,1.505981},
+  {0.271106,-0.317919},
+  {-0.465618,-0.059502},
+  {-0.373175,-0.755986},
+  {0.387614,-0.416476},
+  {-0.748802,-0.395856},
+  {-0.013579,-1.476338},
+  {-0.366869,0.317716},
+  {-0.979219,-0.200391},
+  {-0.153407,-0.447562},
+  {-0.255245,0.351090},
+  {0.998840,-0.545270},
+  {0.186904,-0.240711},
+  {0.153329,-0.943938},
+  {0.247078,0.571677},
+  {0.192360,1.104895},
+  {-0.551067,0.802267},
+  {-0.124506,0.860949},
+  {-0.139002,-0.104195},
+  {-0.642611,-0.508259},
+  {0.157868,0.859140},
+  {0.019725,0.207020},
+  {-0.653316,1.187525},
+  {1.329306,-0.509686},
+  {0.694674,0.256705},
+  {0.202853,0.851294},
+  {-0.441419,1.428209},
+  {0.156150,-0.080560},
+  {0.715021,-0.899171},
+  {-0.239049,-0.631319},
+  {0.195295,0.575186},
+  {-1.311572,-0.865187},
+  {0.570106,0.651064},
+  {0.208959,-1.023329},
+  {0.906490,-0.109625},
+  {-0.781286,-0.253333},
+  {0.231546,0.707965},
+  {-1.265833,1.067884},
+  {0.815263,1.165205},
+  {1.466715,0.385384},
+  {0.535490,0.581761},
+  {-0.472358,-0.470277},
+  {0.983264,0.384383},
+  {0.727058,0.443847},
+  {-0.416272,-0.472738},
+  {0.376082,-0.134460},
+  {-0.503839,-0.901079},
+  {0.682625,1.008080},
+  {-1.386979,-1.091660},
+  {0.213387,0.535684},
+  {-0.957192,-0.557212},
+  {-0.067069,-1.051855},
+  {-0.101157,-0.178941},
+  {-1.306964,-0.631127},
+  {0.926961,-0.083734},
+  {-0.264348,-0.487315},
+  {0.627269,-0.923797},
+  {1.086963,0.082439},
+  {-0.149566,-1.399193},
+  {0.389143,-0.198131},
+  {-0.031070,0.505173},
+  {1.081145,-0.421980},
+  {-0.365429,-0.412667},
+  {-0.376916,0.370359},
+  {0.531009,1.324279},
+  {0.522575,-0.338998},
+  {0.502957,-0.482424},
+  {-0.562535,-0.545277},
+  {-0.397874,-0.045620},
+  {-0.210300,-0.937677},
+  {0.678832,-1.456153},
+  {-0.290273,0.095165},
+  {0.631624,0.517150},
+  {-0.411457,0.459952},
+  {1.217812,-0.542939},
+  {0.073630,-0.234428},
+  {0.054958,-0.570539},
+  {-1.128586,0.230127},
+  {0.720559,0.058370},
+  {-1.035968,0.077082},
+  {-0.608327,-0.358758},
+  {0.269851,0.489804},
+  {-0.406969,-0.549994},
+  {0.527270,-0.654157},
+  {1.027706,-0.593285},
+  {-0.471971,-0.594411},
+  {0.040449,-0.467310},
+  {-0.290221,0.851614},
+  {-0.226635,-0.794078},
+  {0.447274,0.236763},
+  {-0.785187,-0.067945},
+  {0.712972,0.436643},
+  {-0.088441,1.299909},
+  {0.475924,0.408473},
+  {0.209117,0.539048},
+  {0.714783,-0.513016},
+  {0.106957,0.344444},
+  {-0.517943,0.098828},
+  {1.248470,0.110160},
+  {-0.164676,0.715642},
+  {0.116579,0.701060},
+  {-0.338202,1.285789},
+  {0.252122,0.401489},
+  {0.208841,0.077311},
+  {0.254678,0.806815},
+  {0.234503,-0.687878},
+  {-0.017710,1.099931},
+  {1.248068,-1.577695},
+  {-2.177322,0.634684},
+  {0.383749,-0.488257},
+  {0.626473,0.894318},
+  {0.950392,-1.224503},
+  {-1.592308,0.183474},
+  {-0.883620,0.459040},
+  {0.335251,-0.492958},
+  {-1.452049,0.645747},
+  {0.654540,-0.613036},
+  {-0.786306,0.621635},
+  {-0.835920,1.214810},
+  {-0.402804,-0.379300},
+  {-0.167140,-1.088577},
+  {2.017823,-0.733220},
+  {1.277852,0.045432},
+  {-0.655324,-0.273020},
+  {-0.502679,-1.294652},
+  {0.139179,0.305881},
+  {0.476464,0.374818},
+  {-1.204706,0.929919},
+  {-0.703096,0.426476},
+  {-0.170932,-0.224981},
+  {-0.351279,-0.400379},
+  {0.267640,0.852748},
+  {0.272721,-0.274755},
+  {0.394744,0.261766},
+  {-0.427077,-1.197927},
+  {0.469152,-0.246978},
+  {-0.068939,-0.212535},
+  {0.567020,0.581239},
+  {1.773606,-1.261858},
+  {0.258176,-1.131465},
+  {-1.103839,-0.289925},
+  {1.177229,-0.690317},
+  {0.137438,-0.884592},
+  {0.116897,-0.623741},
+  {1.231751,-1.044646},
+  {0.653054,-0.008248},
+  {-1.025754,0.353121},
+  {0.152087,-0.684942},
+  {0.970565,0.373987},
+  {-0.392564,-0.069188},
+  {-0.268254,0.066466},
+  {1.288850,-0.546856},
+  {-0.879522,1.075044},
+  {0.398109,0.957102},
+  {0.937518,-0.970381},
+  {1.315683,0.004675},
+  {0.656915,0.923958},
+  {0.964084,0.332777},
+  {-0.544967,-0.260763},
+  {0.161974,-0.230332},
+  {0.086070,1.573961},
+  {-0.383494,0.130120},
+  {1.082890,0.057498},
+  {-1.410456,-0.461719},
+  {0.540485,0.691271},
+  {-0.278103,0.291339},
+  {0.180835,0.081187},
+  {0.648822,-0.143641},
+  {-1.616721,0.284309},
+  {0.850766,-0.295949},
+  {-0.452081,-0.318424},
+  {-0.672436,0.363193},
+  {0.330021,-0.103062},
+  {-1.201214,0.695691},
+  {-0.176974,-0.049101},
+  {0.034254,-0.001430},
+  {-0.581966,-1.404542},
+  {1.233772,0.845893},
+  {0.770042,-0.222329},
+  {-0.134528,1.408050},
+  {0.981347,0.143636},
+  {0.145948,1.099040},
+  {0.710827,0.052673},
+  {0.557771,-0.481154},
+  {-0.146756,-1.008837},
+  {-0.689552,-0.880902},
+  {0.001022,0.756353},
+  {0.222483,0.013501},
+  {0.905978,0.432735},
+  {-0.497583,-0.437051},
+  {0.010372,-0.231759},
+  {-0.834391,0.245930},
+  {0.869406,-1.488002},
+  {-1.420173,0.137089},
+  {0.055164,0.678866},
+  {0.811665,1.025276},
+  {0.375303,0.608999},
+  {-0.615345,-0.077846},
+  {-0.186463,0.319902},
+  {0.005719,0.915684},
+  {0.318663,-0.507730},
+  {-0.803895,0.451266},
+  {0.160835,0.158185},
+  {1.633081,0.429963},
+  {-0.791587,0.563798},
+  {-0.778932,-0.083845},
+  {-0.746995,0.259063},
+  {-0.374430,0.379522},
+  {-0.025126,-0.204688},
+  {-0.991074,0.045919},
+  {-0.136845,-0.414905},
+  {0.899845,1.310109},
+  {-0.868625,-0.129578},
+  {1.148100,0.070605},
+  {-0.810213,-0.433737},
+  {1.207818,-0.151042},
+  {-0.515970,-0.141577},
+  {-0.161548,0.388756},
+  {-0.679441,-0.108745},
+  {-0.858860,0.144068},
+  {-0.111455,-0.935162},
+  {-0.512453,0.281827},
+  {0.802022,-0.977459},
+  {-0.488174,0.273547},
+  {-0.555684,0.973625},
+  {-1.467122,1.287905},
+  {0.769233,-0.351832},
+  {0.214904,0.347022},
+  {0.942995,0.470266},
+  {-1.265858,-1.103599},
+  {0.786352,-0.915630},
+  {0.377453,0.259392},
+  {0.364408,-0.253769},
+  {-0.939662,0.510476},
+  {-0.611435,0.630746},
+  {0.496403,0.350935},
+  {0.780776,-0.376306},
+  {0.329368,-0.560035},
+  {-0.104896,-0.414545},
+  {0.459736,-0.818950},
+  {0.101952,0.759826},
+  {0.234506,0.195742},
+  {1.165165,1.081672},
+  {-0.741395,-0.556266},
+  {0.136652,-0.063647},
+  {-0.380017,0.025288},
+  {-1.149874,1.004539},
+  {0.233882,0.583344},
+  {1.407491,-0.873973},
+  {0.124950,0.137739},
+  {0.077742,0.655085},
+  {0.756326,0.693924},
+  {-0.978230,-0.590244},
+  {-0.318209,-0.151183},
+  {1.590341,0.137861},
+  {-0.091311,-0.581231},
+  {0.362381,-0.416706},
+  {0.646778,-0.246347},
+  {0.432081,-0.436533},
+  {0.467351,0.177888},
+  {-0.192966,1.332833},
+  {-0.364669,0.036797},
+  {-0.426350,0.041546},
+  {-0.468050,0.813732},
+  {-1.082121,-0.356209},
+  {0.795313,0.513634},
+  {0.286996,0.171098},
+  {0.534304,-0.756041},
+  {-0.676098,0.413430},
+  {-0.707209,0.964446},
+  {-0.144614,-0.627121},
+  {1.280522,-1.317728},
+  {-0.159645,-0.237936},
+  {-0.582439,-0.659814},
+  {-0.070758,-1.089956},
+  {-0.148674,-1.374329},
+  {-0.179882,0.506686},
+  {0.086493,-0.791614},
+  {0.489759,-0.403031},
+  {-0.314327,-0.111422},
+  {-0.412931,0.493597},
+  {0.253975,0.712494},
+  {0.449653,0.383925},
+  {-0.170046,-0.209558},
+  {0.146663,0.741047},
+  {-0.391870,-0.091945},
+  {-0.442016,0.119528},
+  {-0.802004,-1.400078},
+  {-0.352020,-0.673484},
+  {1.178405,0.222166},
+  {0.401656,-0.176436},
+  {-0.270939,-0.198899},
+  {-0.695723,-0.566735},
+  {0.834854,-1.471402},
+  {-0.289106,0.437823},
+  {0.251627,0.054241},
+  {0.029125,-0.307041},
+  {-1.487735,1.231129},
+  {0.333572,-0.223186},
+  {0.038154,1.081929},
+  {-0.087970,-1.036150},
+  {0.592180,0.133148},
+  {0.093161,-0.294506},
+  {-0.296535,0.495623},
+  {-0.522146,1.313928},
+  {-0.714640,-0.532988},
+  {0.398263,0.293071},
+  {-0.596224,1.223075},
+  {0.479882,-1.180554},
+  {-0.065416,-0.710133},
+  {-0.889315,-0.315524},
+  {0.962241,-0.055537},
+  {-0.221264,0.112333},
+  {0.322420,-0.571722},
+  {1.192841,0.558100},
+  {0.521199,0.138154},
+  {0.716695,0.106324},
+  {0.711628,-0.260564},
+  {0.189505,-0.382577},
+  {-0.438235,-0.546217},
+  {0.077497,-0.092175},
+  {-0.202673,-0.048951},
+  {1.487370,-0.747006},
+  {-1.031527,-0.820128},
+  {-1.649929,-0.105742},
+  {-0.347869,-0.458435},
+  {-0.029234,-1.320993},
+  {1.253876,0.585886},
+  {0.436760,2.430056},
+  {0.545664,0.470634},
+  {0.901732,-0.856095},
+  {0.662886,0.977089},
+  {1.075384,-0.075824},
+  {0.209674,0.063782},
+  {-0.126499,0.482599},
+  {-0.507162,0.208925},
+  {0.247866,-0.354774},
+  {0.054885,-1.024517},
+  {0.204562,0.827382},
+  {-0.883562,-0.740692},
+  {0.849976,-0.019489},
+  {0.263688,0.251006},
+  {-0.330082,-0.061291},
+  {-0.083851,1.370921},
+  {0.295784,0.875275},
+  {-0.425539,-0.283223},
+  {-0.640975,0.136141},
+  {-0.173006,0.465478},
+  {-0.895481,0.477515},
+  {0.229261,1.220279},
+  {-0.407060,1.466588},
+  {1.295396,0.176855},
+  {-0.632605,0.786648},
+  {-1.121659,0.268616},
+  {-0.847703,-0.305246},
+  {1.663789,1.656323},
+  {-0.523322,-0.547465},
+  {-0.792665,0.115445},
+  {-0.824945,0.042476},
+  {0.901073,0.249932},
+  {1.130116,-1.907218},
+  {-0.859768,-1.577612},
+  {-0.191384,0.566792},
+  {0.676686,-0.623231},
+  {-0.793064,-0.852185},
+  {0.027490,-0.460866},
+  {0.540012,-1.738204},
+  {-0.751769,-1.401695},
+  {-0.652675,-2.187214},
+  {0.546582,0.366436},
+  {0.191392,-0.194236},
+  {0.143155,0.472797},
+  {-0.850023,-0.135606},
+  {-0.377306,0.072815},
+  {1.283611,0.519238},
+  {0.216310,0.401307},
+  {0.612385,0.376774},
+  {0.509529,-1.018581},
+  {0.718140,-0.664603},
+  {-0.092749,-0.580942},
+  {0.408930,-0.062835},
+  {-0.082806,-1.497458},
+  {-0.474417,-0.431005},
+  {-0.261473,0.207407},
+  {-0.241734,0.107672},
+  {-1.042802,-0.161642},
+  {0.155338,0.029191},
+  {0.742596,0.009836},
+  {1.004603,-0.548445},
+  {-0.772076,0.004202},
+  {0.684254,-1.908420},
+  {-0.643584,-0.503343},
+  {-0.602398,0.352084},
+  {0.637940,0.050408},
+  {-0.282541,-0.673629},
+  {-0.218095,-0.677067},
+  {0.028687,-0.173118},
+  {0.599385,0.120223},
+  {-0.635225,1.055321},
+  {-0.321093,-1.072140},
+  {0.301278,-0.518003},
+  {-0.301802,0.560499},
+  {0.404168,-0.160419},
+  {0.439423,-0.123051},
+  {-0.001024,-0.084182},
+  {-0.222399,0.398534},
+  {-0.032543,0.290847},
+  {-0.686894,0.642376},
+  {-0.376391,-0.292043},
+  {1.291833,-0.282113},
+  {-0.432943,0.047899},
+  {-0.268253,-1.565101},
+  {-0.079616,-0.299536},
+  {0.117126,-0.616435},
+  {0.920777,-1.547713},
+  {0.672508,-0.938412},
+  {-0.127227,0.039824},
+  {0.497527,0.137301},
+  {-1.150554,-0.242356},
+  {0.526140,0.662427},
+  {0.332716,0.387359},
+  {0.193252,-0.748491},
+  {0.879236,1.244841},
+  {-0.320852,0.438523},
+  {0.655207,0.250311},
+  {0.798317,-0.037761},
+  {1.759320,0.543552},
+  {0.796490,0.394488},
+  {-0.426451,0.104660},
+  {-0.596812,0.295484},
+  {-0.586590,-0.761865},
+  {-1.204936,1.145020},
+  {-0.858949,0.734240},
+  {0.417170,-1.861530},
+  {-1.380253,0.411880},
+  {0.940440,-1.547216},
+  {0.392789,0.067926},
+  {0.752023,-0.870322},
+  {0.120743,-0.084171},
+  {0.226500,-0.038959},
+  {-0.199741,0.982130},
+  {-1.435202,1.924533},
+  {-0.681303,-0.685655},
+  {-0.017819,0.316710},
+  {-0.419371,0.291876},
+  {-0.419993,-0.704322},
+  {-0.167402,-0.653200},
+  {0.689883,1.667397},
+  {0.656809,-0.191279},
+  {1.349286,0.707932},
+  {-0.417382,-0.503832},
+  {-0.314839,0.076203},
+  {0.018604,0.103821},
+  {-0.670877,0.305072},
+  {0.238125,-0.177294},
+  {-0.711169,0.115679},
+  {0.098621,-0.114667},
+  {-0.836724,0.797509},
+  {-1.266489,0.300376},
+  {-1.574358,-0.601570},
+  {0.109701,-0.625894},
+  {0.799278,-2.008089},
+  {0.734900,1.439041},
+  {-0.172757,0.297516},
+  {0.123756,0.251462},
+  {-0.605374,0.019162},
+  {-0.277414,0.527217},
+  {1.598600,-0.465976},
+  {0.478046,-0.621558},
+  {-0.032111,0.513916},
+  {-0.406663,0.473997},
+  {0.377026,-1.022417},
+  {0.261630,-0.600598},
+  {0.192450,-0.761462},
+  {-0.945120,1.662247},
+  {1.445931,-0.381166},
+  {0.796386,-0.527247},
+  {0.570342,-0.165144},
+  {-0.260445,0.197738},
+  {-0.396075,0.035099},
+  {0.438589,0.193911},
+  {0.279975,0.803087},
+  {-0.718632,-0.043015},
+  {-0.073136,-0.144147},
+  {0.091844,-1.245899},
+  {1.133630,1.064059},
+  {0.333917,-1.059628},
+  {-0.475974,0.272878},
+  {1.618769,0.338515},
+  {-0.026654,0.173819},
+  {-0.832746,-1.291872},
+  {1.459739,-1.787186},
+  {0.152053,0.719499},
+  {-0.845311,0.148728},
+  {0.096770,0.236791},
+  {0.788550,0.590381},
+  {0.589643,0.130083},
+  {0.556591,1.302659},
+  {-0.149560,0.050103},
+  {0.917707,-0.486145},
+  {-0.059802,1.519826},
+  {-1.072536,0.667091},
+  {-0.111194,1.228050},
+  {-0.229775,0.154698},
+  {-0.371433,0.541268},
+  {0.403110,0.104249},
+  {-0.766373,-1.209893},
+  {-0.133097,0.781221},
+  {0.018198,-0.190757},
+  {0.547760,-0.448064},
+  {-0.733735,0.187525},
+  {0.308738,0.575826},
+  {0.120420,-0.748615},
+  {-0.162974,-1.656815},
+  {0.495299,1.294132},
+  {0.284833,0.326106},
+  {0.304357,-0.029696},
+  {-0.114308,-0.998843},
+  {1.147646,0.007336},
+  {0.889660,0.377428},
+  {1.101746,-0.075572},
+  {-0.630002,0.224827},
+  {-0.447421,-0.680766},
+  {-0.398164,-0.758312},
+  {1.162091,0.872670},
+  {-0.153320,0.100257},
+  {-1.053855,-0.142606},
+  {-0.151297,-1.709248},
+  {-0.088670,-0.030046},
+  {-0.039511,-0.751111},
+  {-0.268719,0.233002},
+  {0.107060,0.944089},
+  {-0.528369,0.218636},
+  {0.379463,-1.271446},
+  {0.845463,-0.200500},
+  {0.449410,-0.308035},
+  {-1.125393,-1.368811},
+  {-0.707799,0.752393},
+  {0.224584,0.957984},
+  {-0.076844,-0.185815},
+  {-0.276454,-0.875122},
+  {-0.308372,-0.078258},
+  {0.710906,-0.432983},
+  {0.086967,-0.475256},
+  {-0.484939,-0.239784},
+  {0.527071,1.381910},
+  {1.207738,0.764537},
+  {-1.166732,0.156223},
+  {-0.928368,-0.713470},
+  {0.232623,0.248816},
+  {0.234335,-0.713494},
+  {0.506899,-0.538864},
+  {0.923647,0.164175},
+  {0.589798,0.487695},
+  {-0.068928,-0.289141},
+  {0.770468,0.393273},
+  {-0.850038,1.509075},
+  {-0.050092,-1.065967},
+  {0.044840,-0.642072},
+  {1.538218,-0.718189},
+  {-0.483958,0.310072},
+  {0.883513,0.423129},
+  {0.577394,-0.913756},
+  {0.369553,-0.000248},
+  {1.306622,-0.676905},
+  {-0.161439,-0.092252},
+  {0.124913,0.545292},
+  {-0.055785,-0.270095},
+  {-0.654485,1.619946},
+  {0.010064,-0.415884},
+  {0.561868,-0.574773},
+  {0.417682,0.121106},
+  {0.447357,-1.403651},
+  {0.036032,0.849953},
+  {-0.310738,-0.139296},
+  {-0.340548,1.709065},
+  {0.324753,-0.829858},
+  {-0.482715,1.278533},
+  {0.027337,0.634282},
+  {0.543259,-1.129644},
+  {-0.176542,0.641092},
+  {0.513499,0.270266},
+  {0.592728,1.200615},
+  {-0.168299,0.071350},
+  {-0.028778,-1.609077},
+  {0.100068,-0.177816},
+  {0.179793,0.405800},
+  {-0.550998,-0.189012},
+  {-0.374629,-0.335207},
+  {0.489373,-0.863435},
+  {-0.909667,-0.243295},
+  {-1.905582,0.828148},
+  {-0.322044,0.578390},
+  {0.172952,0.392945},
+  {-1.349845,-0.593467},
+  {0.385443,-0.834331},
+  {-0.520047,-0.256327},
+  {-0.168864,-0.011272},
+  {0.705916,0.337266},
+  {-0.613837,0.309663},
+  {0.732870,0.082069},
+  {-0.446717,0.037997},
+  {0.503221,-0.919048},
+  {-1.227801,-0.644395},
+  {-0.110226,0.472814},
+  {-0.153520,-1.426752},
+  {-0.372143,-0.995245},
+  {0.041903,1.617146},
+  {-1.716966,-0.094746},
+  {0.110050,0.506537},
+  {0.441591,0.285438},
+  {-0.422717,0.030475},
+  {-0.546275,1.427064},
+  {0.597491,-0.001582},
+  {-0.227799,0.278393},
+  {-0.711928,-0.389254},
+  {-0.316276,-0.045449},
+  {-0.246906,0.142129},
+  {-0.017644,0.530840},
+  {-0.846558,0.285732},
+  {0.024601,1.550225},
+  {0.135991,-0.281795},
+  {1.076094,-0.393152},
+  {0.469595,0.373539},
+  {0.700686,-0.192217},
+  {-1.044613,-0.031666},
+  {-0.172857,0.037056},
+  {0.216986,-0.221328},
+  {1.202936,0.262729},
+  {0.736136,0.660856},
+  {0.310616,-0.895782},
+  {0.756943,-0.860938},
+  {0.491193,0.919560},
+  {-0.391990,-1.038218},
+  {0.630603,0.076034},
+  {-1.672313,0.931548},
+  {0.031370,-0.235708},
+  {-0.059540,-0.730453},
+  {1.751460,-0.083331},
+  {-0.312742,1.042875},
+  {-1.327894,-0.601739},
+  {1.130657,-0.489036},
+  {-0.578349,-0.452027},
+  {0.442817,-0.010612},
+  {0.568033,0.646896},
+  {-0.209657,0.511084},
+  {0.185712,-0.492029},
+  {1.604476,-0.325909},
+  {-0.804376,-0.713345},
+  {-1.315856,0.385873},
+  {-0.221093,1.328622},
+  {-0.759605,0.387801},
+  {0.152179,-0.162878},
+  {-0.218474,-0.005204},
+  {0.375890,-0.799244},
+  {0.637063,-1.137409},
+  {0.594361,0.315677},
+  {0.645739,0.636245},
+  {0.658041,-0.321056},
+  {0.070071,1.391222},
+  {0.721141,-0.400061},
+  {-0.352948,0.195410},
+  {-1.271695,0.849227},
+  {-0.501393,-0.054339},
+  {0.423696,1.085774},
+  {-1.135309,0.703848},
+  {-0.274176,0.653380},
+  {-0.316789,-0.988309},
+  {0.711998,1.178853},
+  {0.467890,0.383039},
+  {-0.361315,0.586150},
+  {-1.992977,0.823878},
+  {0.390939,0.167472},
+  {0.110536,0.002095},
+  {-1.247517,-0.665658},
+  {0.121696,0.179633},
+  {-1.365006,0.556461},
+  {0.408822,-0.155980},
+  {-0.730116,0.123973},
+  {0.684268,-1.776762},
+  {-0.649453,-0.171713},
+  {-0.372612,-0.050829},
+  {0.376350,0.556347},
+  {-0.100789,-0.048297},
+  {0.535745,-0.486194},
+  {-0.461672,-0.184145},
+  {0.397655,-0.685573},
+  {-0.322562,-0.405548},
+  {-0.139347,0.980121},
+  {0.383183,-0.416704},
+  {0.405772,0.305710},
+  {1.287783,1.488584},
+  {0.032704,0.960170},
+  {-0.996629,-0.613880},
+  {0.344951,0.741074},
+  {0.012855,0.279797},
+  {0.059268,0.437106},
+  {1.099804,-0.690001},
+  {2.066302,-1.011066},
+  {-1.138329,0.358600},
+  {0.915106,0.661313},
+  {-0.890883,-0.368142},
+  {-1.368238,0.378705},
+  {-0.336150,0.507975},
+  {-0.706113,0.234963},
+  {-0.606888,-0.970039},
+  {-0.527169,0.523949},
+  {0.018031,-0.474310},
+  {0.741809,-0.091430},
+  {-0.009929,0.576888},
+  {0.874371,0.333460},
+  {-0.254588,0.654464},
+  {0.261702,1.313061},
+  {-1.277335,1.378973},
+  {-0.138901,-0.173082},
+  {0.924853,0.129874},
+  {-0.387252,0.001449},
+  {0.101334,-0.534299},
+  {1.166440,-0.414895},
+  {1.069226,0.257124},
+  {0.900367,-0.135723},
+  {1.218319,-0.472790},
+  {0.508176,-0.583053},
+  {0.556299,0.001431},
+  {0.941767,0.240470},
+  {1.019062,-1.238945},
+  {-1.044413,0.547817},
+  {0.739657,0.372119},
+  {-1.127057,-0.032632},
+  {1.021823,-2.155687},
+  {0.154893,-0.768565},
+  {0.222839,-0.891271},
+  {-0.021271,-0.349137},
+  {-0.498438,-0.404658},
+  {0.713753,-1.281305},
+  {0.516202,-0.400977},
+  {0.375070,-0.381473},
+  {0.611029,-0.695506},
+  {0.329870,0.978420},
+  {-0.440990,-0.627980},
+  {1.106160,-0.673187},
+  {0.330761,0.960060},
+  {0.002016,-0.375526},
+  {-0.418742,-0.230493},
+  {0.889310,0.259182},
+  {-0.743094,0.859461},
+  {-0.639141,0.046149},
+  {-0.825368,1.113567},
+  {-0.183710,-1.099516},
+  {-0.688241,0.048768},
+  {-0.567826,0.016499},
+  {-0.252604,-0.505972},
+  {0.125737,-0.032586},
+  {-0.289104,0.481842},
+  {0.197078,-0.361814},
+  {1.702697,-0.135121},
+  {-0.313162,-0.195712},
+  {0.373467,-0.638017},
+  {0.265985,0.688793},
+  {-0.930620,-0.543390},
+  {0.266031,0.127381},
+  {-1.131799,-0.707161},
+  {0.294857,-1.044248},
+  {0.844394,-1.509590},
+  {-0.012985,0.455971},
+  {0.934720,0.325752},
+  {0.477097,-0.617656},
+  {-0.186792,0.919832},
+  {0.661168,-1.463831},
+  {-0.052266,-0.007023},
+  {-0.417000,-0.630278},
+  {-0.201517,0.049327},
+  {0.324582,0.488122},
+  {-1.135622,1.088472},
+  {-0.839457,0.576660},
+  {0.776228,-0.246711},
+  {-0.060646,0.204187},
+  {-1.666099,-0.412724},
+  {-0.302620,0.413709},
+  {0.134609,-0.417098},
+  {0.667218,-0.505744},
+  {0.310204,-0.163001},
+  {2.227881,0.439271},
+  {-0.402395,-0.165319},
+  {-0.381247,0.233719},
+  {-0.070232,-0.083912},
+  {0.705271,0.505574},
+  {-0.574528,-0.237527},
+  {-0.097888,0.687548},
+  {-0.287092,-0.392327},
+  {0.771057,-2.105183},
+  {-0.424797,-0.712019},
+  {-1.141051,-0.262563},
+  {1.245465,-0.173175},
+  {-0.809671,0.478984},
+  {0.420857,-1.118626},
+  {-0.774501,0.206551},
+  {-0.371353,-0.523965},
+  {-0.475349,0.782751},
+  {0.354270,0.297627},
+  {0.429063,-0.301249},
+  {-0.253951,-0.024314},
+  {0.542049,0.210328},
+  {-1.288145,0.902746},
+  {-0.610673,-0.457713},
+  {0.560486,-0.045507},
+  {1.012326,0.160808},
+  {0.739327,0.227113},
+  {0.440689,-0.364347},
+  {0.043907,-0.902520},
+  {0.107084,-0.850966},
+  {-0.864312,-0.936915},
+  {-0.983595,1.279503},
+  {-0.826804,-0.510867},
+  {0.410159,-0.166249},
+  {0.234942,0.048679},
+  {-0.440864,-1.871740},
+  {-0.277232,0.058905},
+  {0.865167,-1.085117},
+  {0.323421,0.865950},
+  {0.078567,0.487181},
+  {-0.106628,0.112398},
+  {-0.701141,-0.631292},
+  {-0.241547,-0.907031},
+  {-1.058655,1.194515},
+  {-0.245933,-0.291151},
+  {0.090384,-0.078327},
+  {-1.804471,0.305652},
+  {-0.710208,-0.044177},
+  {-1.637185,0.634789},
+  {0.322701,0.202198},
+  {0.592642,0.027099},
+  {0.106661,0.220082},
+  {0.374884,0.031143},
+  {0.466431,0.144924},
+  {-0.435113,-0.045018},
+  {-0.812143,0.850339},
+  {-0.723946,0.392704},
+  {-2.151521,-0.712553},
+  {0.450893,-0.280685},
+  {0.819631,0.669219},
+  {0.173790,-0.823862},
+  {1.252888,-0.450119},
+  {-0.760925,0.126633},
+  {0.100797,0.669706},
+  {0.636397,0.644360},
+  {0.314358,0.426072},
+  {0.399418,-0.772800},
+  {-0.648593,-0.341262},
+  {-0.247134,0.264055},
+  {1.077773,0.975354},
+  {0.523563,-0.791219},
+  {-0.796902,-0.163962},
+  {-0.615911,0.149349},
+  {0.954916,-1.262222},
+  {0.678034,1.207517},
+  {-0.372992,-0.431473},
+  {-1.124813,-1.597092},
+  {-0.447033,-0.087720},
+  {-0.720631,0.709710},
+  {0.384703,0.910101},
+  {-0.247341,-1.476532},
+  {-1.241862,1.322373},
+  {-0.310325,0.816418},
+  {-0.050700,-0.416219},
+  {0.309471,-0.192610},
+  {0.371081,0.778064},
+  {-0.510419,-1.055190},
+  {0.127094,0.388637},
+  {-0.255658,-0.020784},
+  {-0.239095,-0.235771},
+  {0.860355,0.144748},
+  {0.175697,0.666209},
+  {0.161710,-1.018808},
+  {0.208616,-0.113253},
+  {0.322261,-0.153970},
+  {0.115609,0.527421},
+  {-1.142425,-0.174532},
+  {-0.867659,-0.160025},
+  {0.702013,-0.499588},
+  {-0.305717,-0.468403},
+  {1.015578,-0.486232},
+  {0.012654,0.647932},
+  {0.650411,0.663774},
+  {0.064881,0.712345},
+  {-0.408083,-0.026499},
+  {0.129269,0.557035},
+  {-1.311066,0.784364},
+  {-0.811294,-0.539442},
+  {-0.783403,-0.385913},
+  {0.661821,0.125770},
+  {-0.659564,0.069575},
+  {0.995148,0.349592},
+  {0.148861,-0.577855},
+  {1.019181,-0.324607},
+  {0.569564,-0.397281},
+  {0.908002,0.954231},
+  {1.214742,-0.616921},
+  {-0.173224,0.454581},
+  {-2.116294,-0.837803},
+  {-0.363546,0.105419},
+  {0.440872,0.067274},
+  {-0.101457,0.086710},
+  {0.335032,1.011214},
+  {-0.212784,1.709394},
+  {-0.609104,0.294062},
+  {0.257849,-0.420324},
+  {-1.753260,-0.996065},
+  {0.233278,0.392532},
+  {0.347599,0.585661},
+  {0.445643,-0.462247},
+  {1.049963,0.117133},
+  {0.839655,-0.356217},
+  {0.703241,0.033581},
+  {0.271280,-0.196860},
+  {0.065959,-0.921553},
+  {0.405906,-0.688962},
+  {0.098046,0.333902},
+  {-0.014572,0.211136},
+  {-0.737884,0.177744},
+  {-0.649906,-1.604793},
+  {0.293595,0.706452},
+  {-0.066643,1.517094},
+  {0.441195,-0.173964},
+  {1.195227,0.123771},
+  {-1.135443,-1.413717},
+  {0.006356,-1.017804},
+  {0.722946,0.103556},
+  {-0.003354,0.488708},
+  {0.474062,0.159755},
+  {0.324770,0.895972},
+  {-0.553939,0.154297},
+  {-0.103416,0.898922},
+  {-1.072220,-0.410260},
+  {-0.053047,-0.030047},
+  {0.070087,-0.725415},
+  {0.165223,-0.558910},
+  {0.782904,-0.136372},
+  {-0.041688,-0.135373},
+  {0.334520,-0.033481},
+  {0.801873,-0.133751},
+  {0.209301,0.597294},
+  {0.618379,1.223616},
+  {0.888198,-0.672384},
+  {-1.214205,0.041896},
+  {-0.207532,-0.540674},
+  {0.992363,-1.169905},
+  {0.940801,-0.242385},
+  {-0.708174,0.635987},
+  {-0.369966,0.143612},
+  {1.281108,0.086508},
+  {0.250887,-0.332167},
+  {-0.515793,-0.631672},
+  {1.136276,0.346349},
+  {-0.464252,1.668219},
+  {0.525805,-0.141030},
+  {0.999260,1.590780},
+  {0.605581,-0.060022},
+  {1.056390,-0.048178},
+  {-0.968752,0.185265},
+  {-1.340377,-0.330139},
+  {-1.046545,0.051473},
+  {-0.450882,0.258781},
+  {0.243010,0.998613},
+  {0.421506,-0.706489},
+  {0.656187,-0.851819},
+  {-1.749329,-0.182724},
+  {0.266263,0.302166},
+  {0.344290,-0.491448},
+  {0.946706,1.671205},
+  {1.056879,-0.219540},
+  {0.627745,-0.729454},
+  {0.433355,-0.250281},
+  {-0.200019,-1.300245},
+  {1.255424,-1.022037},
+  {-0.061801,-0.646340},
+  {-0.232252,0.533970},
+  {-0.395477,0.369443},
+  {-0.623953,-0.526531},
+  {-0.820382,1.716970},
+  {0.140594,0.061758},
+  {-1.036810,0.403211},
+  {-0.469993,-0.107368},
+  {1.205792,0.275994},
+  {0.959943,0.019721},
+  {0.573598,0.123293},
+  {-1.420059,-1.132904},
+  {0.290727,0.167288},
+  {0.365799,0.542990},
+  {0.516968,-0.612634},
+  {0.160027,-0.390477},
+  {-0.347292,0.029547},
+  {-0.004609,1.121404},
+  {-0.335175,-0.015666},
+  {0.908113,0.229171},
+  {0.545009,1.480549},
+  {-1.220973,1.093788},
+  {0.479628,-1.425169},
+  {-0.513786,1.062727},
+  {0.357421,-0.804394},
+  {-1.061941,0.223873},
+  {-0.385252,0.110396},
+  {-1.640287,-0.021951},
+  {0.623028,-0.060477},
+  {-0.550756,0.678768},
+  {0.135673,0.837449},
+  {0.751838,-0.180054},
+  {0.954815,-0.866757},
+  {0.604536,1.476877},
+  {-0.286459,0.372774},
+  {0.376627,-0.910916},
+  {1.217027,0.101736},
+  {0.011181,-0.874826},
+  {-0.722030,0.489939},
+  {0.311409,-0.260903},
+  {0.226439,-0.416559},
+  {-0.217666,0.618687},
+  {-0.882251,-0.420330},
+  {0.562126,-0.226552},
+  {-0.133127,-0.134644},
+  {0.969153,-0.508304},
+  {0.405205,-0.871967},
+  {-1.017625,0.079112},
+  {-0.736203,-0.949411},
+  {0.250579,0.868592},
+  {0.584736,0.487773},
+  {-0.200735,0.406254},
+  {-0.169967,-0.174164},
+  {-0.926833,-0.008126},
+  {-1.276335,-0.436210},
+  {-1.055847,-0.464811},
+  {1.382819,-0.892263},
+  {0.549810,-0.254992},
+  {-1.222183,-0.947043},
+  {0.548589,-0.517754},
+  {0.330987,1.018993},
+  {0.025173,0.069526},
+  {0.574042,-1.129914},
+  {1.165371,-0.221953},
+  {-0.047741,-0.296772},
+  {0.651998,0.263669},
+  {-0.694023,0.443470},
+  {-0.956615,-0.672689},
+  {0.016381,-0.458048},
+  {0.982982,-0.048522},
+  {0.181067,-0.514465},
+  {-0.391139,-0.223578},
+  {0.161096,-0.653129},
+  {-0.351802,-0.290479},
+  {-0.314563,0.489580},
+  {-0.146600,0.217679},
+  {-0.626463,-1.314274},
+  {-0.425276,0.036105},
+  {0.653590,-0.842355},
+  {0.326039,-0.509672},
+  {-0.469673,0.286035},
+  {-0.123351,0.467094},
+  {0.413046,1.210950},
+  {-1.022797,-0.785435},
+  {0.675002,0.772235},
+  {-0.862771,-0.220066},
+  {-0.231169,-0.567071},
+  {-0.022879,-1.662436},
+  {0.191818,-0.220743},
+  {-0.011754,-1.811256},
+  {0.535316,-0.223392},
+  {0.073030,1.008182},
+  {0.433603,1.040546},
+  {0.057488,-0.260627},
+  {-0.750304,-0.190874},
+  {-1.484162,-0.249188},
+  {0.555514,-0.171803},
+  {0.541373,0.623842},
+  {-0.324439,-0.112460},
+  {0.079769,-0.353481},
+  {0.330382,1.054412},
+  {-0.106034,0.995793},
+  {-0.382467,0.382232},
+  {-0.036929,-0.393942},
+  {0.511558,-1.203157},
+  {-0.669114,-0.507821},
+  {-0.717810,-0.040914},
+  {-1.754621,0.344004},
+  {-0.597845,-1.199356},
+  {1.760979,0.700903},
+  {0.625006,-0.444735},
+  {-0.348717,-0.247748},
+  {0.174249,0.142504},
+  {0.819233,0.294173},
+  {-0.031325,-0.221121},
+  {0.591852,0.560305},
+  {-0.018918,-0.672425},
+  {0.779234,-0.181712},
+  {-1.059580,0.442549},
+  {-0.326264,1.377449},
+  {-0.788614,-1.350767},
+  {0.216709,0.414704},
+  {0.220819,0.108199},
+  {-0.359007,0.600802},
+  {-0.309663,0.778317},
+  {0.757247,0.732882},
+  {-0.492180,0.313444},
+  {-0.869761,-1.301811},
+  {-0.125626,-0.676394},
+  {0.295449,-0.241053},
+  {1.054322,0.797473},
+  {-0.287078,-0.504316},
+  {-0.537100,-0.231610},
+  {0.613905,-0.234007},
+  {0.741154,0.141237},
+  {0.626367,-0.853201},
+  {0.755579,-0.402972},
+  {0.791054,0.600208},
+  {-0.063499,-0.518131},
+  {-0.489265,-0.036842},
+  {-0.949063,0.023314},
+  {-0.515292,-0.340645},
+  {1.479585,0.191550},
+  {-0.606714,-0.320708},
+  {0.466669,0.522580},
+  {-0.863079,1.451320},
+  {0.528683,0.847398},
+  {0.542235,-0.755739},
+  {0.118265,0.135243},
+  {-0.740312,-0.861944},
+  {-0.435756,0.830366},
+  {-0.109372,-0.213866},
+  {-0.553930,-0.845500},
+  {-1.099287,-0.297620},
+  {0.106898,-0.424559},
+  {-0.378716,0.193142},
+  {0.213494,1.033237},
+  {-0.853118,-0.760434},
+  {-0.206960,0.322096},
+  {0.515476,-0.382595},
+  {-0.452647,0.010086},
+  {-0.802250,-0.678852},
+  {0.294123,0.686175},
+  {0.858965,0.189241},
+  {0.605752,-1.104271},
+  {1.481873,0.508996},
+  {-1.116676,0.289812},
+  {-0.707222,-0.382630},
+  {-0.079025,1.156617},
+  {0.639524,-0.001944},
+  {-0.088679,-1.253192},
+  {-0.321477,0.741010},
+  {0.995588,-0.064482},
+  {-0.881360,1.360842},
+  {-0.297000,-0.072434},
+  {0.060998,0.138554},
+  {0.421436,-0.022213},
+  {0.600608,-0.843743},
+  {-0.093266,-0.799977},
+  {-0.270330,-0.551698},
+  {-0.586570,0.075585},
+  {0.535896,-0.937339},
+  {-0.196885,-1.152215},
+  {-0.824956,-0.668942},
+  {-0.259150,0.564970},
+  {1.163106,-0.343775},
+  {-0.211627,0.887391},
+  {-1.519484,-0.692918},
+  {0.630723,-0.711066},
+  {-0.804122,-0.662480},
+  {0.839553,1.605451},
+  {-0.326213,0.368434},
+  {0.059140,-1.102124},
+  {0.237029,0.146990},
+  {-0.696770,-0.008057},
+  {-1.171176,0.075899},
+  {-0.147349,0.040450},
+  {0.129807,-1.078745},
+  {-1.346480,-0.102841},
+  {1.923088,-0.340920},
+  {0.604509,-0.631306},
+  {0.830188,0.900687},
+  {-0.244172,-0.131295},
+  {-1.297096,0.273955},
+  {-0.851825,1.248525},
+  {-0.198894,-0.720303},
+  {0.603852,0.405432},
+  {0.164840,0.543281},
+  {1.671773,0.067980},
+  {0.038583,0.297031},
+  {0.507509,-0.744625},
+  {0.359393,0.748717},
+  {-0.212608,-0.358101},
+  {0.126437,1.165712},
+  {-0.248434,-0.585575},
+  {-0.263564,1.882286},
+  {0.197666,-0.007268},
+  {1.382641,-2.141275},
+  {0.372177,-1.454355},
+  {-1.179644,0.104261},
+  {1.106674,-0.282933},
+  {-0.265928,-0.626704},
+  {-0.561107,0.452555},
+  {-1.300538,0.287714},
+  {-1.015374,0.573758},
+  {-0.607617,-0.309770},
+  {-0.023152,-0.760109},
+  {-0.194123,0.599047},
+  {0.647420,-0.037263},
+  {0.106358,0.238426},
+  {-0.392097,0.094144},
+  {0.661177,0.412145},
+  {-1.399599,1.957816},
+  {0.148234,0.471031},
+  {0.286092,0.528837},
+  {-0.391787,0.921074},
+  {0.195292,0.118754},
+  {-0.136761,0.298155},
+  {-0.378985,-0.604095},
+  {1.371422,-0.622111},
+  {0.857070,0.509011},
+  {0.066269,-0.029824},
+  {-1.377703,0.529433},
+  {-0.694186,-0.441324},
+  {-0.257793,1.275458},
+  {-0.672277,-0.654115},
+  {-0.809306,0.145106},
+  {0.670659,-0.012692},
+  {0.157773,0.013152},
+  {-0.462958,-0.012297},
+  {0.827130,1.661564},
+  {0.397882,0.120724},
+  {1.117614,1.225687},
+  {0.476878,0.490050},
+  {0.724769,1.113002},
+  {0.586609,-0.560797},
+  {-1.361147,0.474845},
+  {-0.007226,0.580620},
+  {-0.701521,0.864232},
+  {0.994535,0.306268},
+  {0.370349,1.237807},
+  {-0.242788,-1.443067},
+  {0.473815,-0.479609},
+  {-0.389546,0.026009},
+  {-0.338480,0.878802},
+  {0.435504,-0.420076},
+  {0.889075,0.161873},
+  {0.138696,-0.566162},
+  {0.217055,0.953271},
+  {0.839538,0.048184},
+  {-0.059206,-1.142293},
+  {0.665060,-0.676547},
+  {0.221557,0.086282},
+  {-1.173015,0.335912},
+  {0.457360,-0.040303},
+  {0.575889,-1.213594},
+  {0.658439,-0.011276},
+  {-1.457696,-0.189237},
+  {-0.800412,0.566585},
+  {-0.102734,-0.661830},
+  {-0.348242,0.424874},
+  {0.353335,1.852790},
+  {1.435363,0.984674},
+  {0.405182,-0.313471},
+  {-0.641495,1.885674},
+  {1.945466,1.286943},
+  {-1.031042,-0.000691},
+  {-0.513774,-1.070626},
+  {1.364844,-0.285854},
+  {-0.121790,-1.095977},
+  {-1.249687,0.021067},
+  {-0.075555,0.781338},
+  {0.954208,-0.915902},
+  {-1.027627,-0.406509},
+  {-1.513386,0.885096},
+  {-0.487952,-0.456337},
+  {-1.052057,0.867359},
+  {-0.145713,0.278056},
+  {-0.756226,-0.964303},
+  {-0.446097,-0.089467},
+  {0.169928,-0.361224},
+  {0.397326,-0.307696},
+  {-0.034144,-0.246857},
+  {-0.696100,-0.538312},
+  {-0.534972,0.210185},
+  {0.816251,-0.647654},
+  {-0.705987,-0.908852},
+  {-0.615467,-1.097666},
+  {-0.159338,-0.149510},
+  {-0.937470,0.880936},
+  {-0.320957,-0.048574},
+  {-0.372401,-0.285898},
+  {-0.358402,-0.568311},
+  {0.708385,-1.254534},
+  {0.829644,0.011912},
+  {0.285381,-1.031588},
+  {0.017740,-0.349993},
+  {-0.022239,-0.439243},
+  {-1.430300,-0.497895},
+  {0.170766,-0.701765},
+  {0.175088,0.629816},
+  {-0.098450,0.984733},
+  {-0.506275,0.273047},
+  {0.386685,0.226191},
+  {-0.849597,0.026814},
+  {0.331172,-0.400903},
+  {-0.166717,0.322664},
+  {0.840811,0.163583},
+  {-1.492836,0.838920},
+  {-1.518271,0.133282},
+  {0.411785,0.665886},
+  {-1.288775,0.573578},
+  {-0.679826,0.216065},
+  {1.072059,0.678109},
+  {0.327039,0.057915},
+  {0.748172,-1.016021},
+  {0.766777,0.338616},
+  {-0.154979,1.088221},
+  {-0.233660,-0.592573},
+  {0.733229,-0.356964},
+  {-0.716623,0.333791},
+  {0.201190,-0.773714},
+  {0.312616,-0.148537},
+  {0.290474,-0.743141},
+  {-0.227709,-0.668733},
+  {-1.515149,1.270848},
+  {0.226198,-0.729829},
+  {-0.181346,-1.271070},
+  {-1.045326,-0.092295},
+  {1.642772,-1.645010},
+  {1.017090,-1.591010},
+  {0.095373,-1.289559},
+  {1.964387,0.348377},
+  {-0.950861,0.367564},
+  {0.556953,0.768761},
+  {-0.203486,0.439205},
+  {0.491570,0.168439},
+  {-0.687148,-0.295486},
+  {-0.740794,-0.566119},
+  {-0.024076,0.456466},
+  {0.109395,-0.274543},
+  {-0.793800,-1.014024},
+  {0.292454,0.541633},
+  {-0.595307,0.963837},
+  {-0.657843,-0.867296},
+  {0.204862,-0.344086},
+  {-0.578269,-0.345403},
+  {-0.780437,-0.385625},
+  {-0.273820,0.505994},
+  {1.004484,-0.156356},
+  {-0.868964,0.266448},
+  {0.143031,-0.803470},
+  {0.101618,-0.081850},
+  {0.193181,-0.062062},
+  {-0.861275,0.852923},
+  {0.288135,-0.426406},
+  {-0.928134,0.099686},
+  {-0.181721,1.615686},
+  {-0.136660,0.020212},
+  {0.072772,0.114802},
+  {0.202198,-0.238392},
+  {-0.251007,0.316880},
+  {0.349716,-0.792136},
+  {-1.213064,-0.842004},
+  {0.862678,-0.028549},
+  {-0.973473,0.006869},
+  {0.233388,-0.345947},
+  {1.041065,0.708671},
+  {0.324049,-1.771873},
+  {-0.185275,0.653364},
+  {0.628341,0.054329},
+  {-0.164341,0.487005},
+  {0.393343,-0.037375},
+  {-0.532730,1.366482},
+  {0.106510,0.798337},
+  {-0.801100,-0.368808},
+  {0.492501,-0.594827},
+  {-0.157276,-0.210969},
+  {1.430722,-0.123353},
+  {0.869858,-0.330376},
+  {-0.870905,-0.576319},
+  {0.488152,-0.077766},
+  {-1.352852,-0.983699},
+  {-0.071516,0.008669},
+  {0.038294,-0.659775},
+  {-0.638838,-1.453811},
+  {0.365078,0.936548},
+  {-0.176761,0.029567},
+  {-0.637139,0.811721},
+  {0.199638,-0.298378},
+  {-0.555570,0.019142},
+  {-0.091645,0.610158},
+  {0.877453,0.174360},
+  {-0.568953,0.103565},
+  {-0.832229,0.324979},
+  {0.712774,0.870009},
+  {-0.278872,-0.588582},
+  {0.435542,0.494374},
+  {-0.065868,0.021952},
+  {1.423758,-0.393834},
+  {-0.477059,0.827165},
+  {0.627414,-0.276227},
+  {1.000520,0.682515},
+  {0.607696,0.206943},
+  {-0.154464,0.495945},
+  {-0.124329,-0.829138},
+  {-0.087112,-0.220509},
+  {-0.465875,-0.382839},
+  {-1.017272,0.487396},
+  {-0.547511,0.237748},
+  {-0.038977,0.393638},
+  {1.026923,-0.597241},
+  {-0.621617,-0.717375},
+  {0.667387,0.914740},
+  {-0.608364,-0.851361},
+  {0.615870,0.510211},
+  {0.292743,0.514543},
+  {0.347583,1.275365},
+  {0.200986,-0.420921},
+  {1.374615,-0.215986},
+  {-0.414803,0.434964},
+  {-1.476929,-1.362368},
+  {0.636865,0.488148},
+  {1.114926,0.262444},
+  {0.082692,-0.670997},
+  {1.966723,1.124746},
+  {-0.046586,-1.173584},
+  {-0.363377,-0.208166},
+  {0.501587,0.594431},
+  {-0.168038,0.767871},
+  {0.323440,0.680381},
+  {1.067349,0.560431},
+  {-0.772885,-1.138626},
+  {0.518494,0.322721},
+  {0.685843,-0.056191},
+  {0.787104,-0.784384},
+  {0.609174,-0.220906},
+  {-0.006505,0.671218},
+  {0.460238,-0.684338},
+  {0.438095,1.508562},
+  {0.009417,0.237749},
+  {0.393314,1.196541},
+  {-0.583606,1.070722},
+  {-0.169269,-0.926174},
+  {-0.066992,-0.301332},
+  {0.497741,-1.198867},
+  {-1.090838,0.548678},
+  {-0.004155,-0.024343},
+  {-0.612437,-0.656401},
+  {-0.663257,-0.093885},
+  {-0.174069,0.911494},
+  {0.367565,0.610990},
+  {-0.144097,-0.435430},
+  {1.104616,-1.845717},
+  {-0.972594,0.334831},
+  {-0.794574,-0.392847},
+  {0.311997,0.561151},
+  {0.586292,-0.042105},
+  {-1.605228,-0.279692},
+  {-0.382017,2.388282},
+  {1.055212,0.335750},
+  {0.209281,0.138650},
+  {-0.385178,-0.272430},
+  {0.548245,-0.025245},
+  {-0.638262,-0.021417},
+  {-1.294383,-0.197757},
+  {0.423815,0.591952},
+  {-0.071987,-0.562847},
+  {-0.126977,1.038596},
+  {0.496448,0.840634},
+  {-1.185477,0.042048},
+  {-0.823043,-0.368610},
+  {1.008274,-0.231597},
+  {-0.660260,0.296490},
+  {-0.743515,0.208480},
+  {0.379941,-1.003447},
+  {0.968945,0.294877},
+  {-0.698481,-1.144907},
+  {-1.162786,0.387927},
+  {-0.293235,0.428785},
+  {0.718636,-0.315848},
+  {0.107103,-0.828505},
+  {0.356476,-0.645877},
+  {0.505071,-0.331163},
+  {-0.649298,-0.398312},
+  {-0.090610,-0.074341},
+  {0.200451,-0.421806},
+  {0.908067,-0.168388},
+  {-0.846288,0.033026},
+  {-0.189659,-0.925072},
+  {-0.023812,0.459475},
+  {1.602866,0.714233},
+  {-0.575714,-0.238446},
+  {0.846762,-0.832419},
+  {0.120918,0.182480},
+  {-0.570597,-0.373300},
+  {0.419728,0.612563},
+  {-0.320002,-0.948555},
+  {0.318035,-0.186493},
+  {-0.127286,0.112951},
+  {-0.141023,0.135715},
+  {1.060583,0.677137},
+  {0.101330,0.199317},
+  {0.803035,-0.452390},
+  {-0.340576,0.650283},
+  {0.902556,-0.144691},
+  {-0.893404,0.858889},
+  {-0.007600,-0.345112},
+  {0.111926,-0.168442},
+  {1.039893,-0.469075},
+  {0.240538,-0.826278},
+  {0.826768,0.578478},
+  {1.046184,0.665426},
+  {0.038550,0.215966},
+  {-0.635648,0.508181},
+  {-0.146230,0.638788},
+  {-0.362399,-0.629495},
+  {0.542586,0.843847},
+  {0.167182,-0.792296},
+  {-0.855717,0.083743},
+  {-1.036334,-0.085065},
+  {-0.324723,-0.030988},
+  {-1.833660,-0.410648},
+  {-0.001357,-0.829866},
+  {-0.104752,-0.284616},
+  {-0.816835,-1.210435},
+  {-0.052255,-0.543345},
+  {-0.367505,0.092323},
+  {-0.736559,-0.520296},
+  {0.201749,0.054396},
+  {-0.199049,0.602651},
+  {0.404682,-0.309862},
+  {-0.317471,1.036744},
+  {-0.098938,-0.818030},
+  {-0.814101,-1.260633},
+  {0.763575,0.457821},
+  {0.358938,-0.131199},
+  {-0.301845,0.650210},
+  {-0.029168,-0.595484},
+  {-0.369691,0.223720},
+  {0.194581,0.025750},
+  {-0.460265,0.156045},
+  {0.305830,0.208558},
+  {0.223866,0.641668},
+  {0.026609,0.558788},
+  {0.356247,0.373533},
+  {0.237883,-1.069953},
+  {0.147891,-0.805516},
+  {0.188977,-0.068435},
+  {0.292733,-0.380567},
+  {0.221952,1.563443},
+  {0.345474,-0.145997},
+  {0.562837,0.992170},
+  {0.931969,1.306009},
+  {1.241908,0.118149},
+  {0.565906,-0.246496},
+  {-0.585196,0.203570},
+  {0.711276,-0.200387},
+  {-0.376149,0.513875},
+  {1.192035,-0.156803},
+  {-0.862564,0.588024},
+  {0.388852,-1.356642},
+  {0.725190,0.687537},
+  {0.257052,0.151601},
+  {0.411402,0.594166},
+  {-0.047136,-1.330878},
+  {1.164207,-0.046186},
+  {-0.200303,0.780709},
+  {-1.433552,0.524817},
+  {0.560902,0.219424},
+  {1.472746,0.370998},
+  {0.004523,0.852842},
+  {-0.707314,-0.502471},
+  {-0.705225,-0.568235},
+  {-1.031248,0.407625},
+  {1.060594,0.382613},
+  {1.464419,-0.586019},
+  {-0.605902,-0.458757},
+  {0.929307,0.153506},
+  {-0.016372,0.282450},
+  {-1.208132,-0.830801},
+  {-0.126240,-0.367972},
+  {-0.499330,0.674812},
+  {1.438503,0.217270},
+  {0.740691,0.305890},
+  {-0.108512,0.515161},
+  {-0.078081,-0.658439},
+  {0.032558,-0.295751},
+  {-0.340864,-0.476425},
+  {-0.013541,1.071300},
+  {-0.316971,0.276887},
+  {-0.154365,-0.266247},
+  {0.612401,0.295050},
+  {0.668963,-0.540567},
+  {0.158289,0.472776},
+  {-0.166571,1.587298},
+  {-0.159732,0.238475},
+  {0.347017,0.964527},
+  {0.004723,1.073330},
+  {0.829038,-0.522273},
+  {-0.541649,0.245743},
+  {-0.766282,-1.376811},
+  {1.171373,-0.879527},
+  {0.569829,0.378677},
+  {0.416307,0.145570},
+  {-0.123077,-0.283547},
+  {-0.896898,0.201798},
+  {-0.435349,-0.464885},
+  {1.650033,0.637224},
+  {0.965961,0.150970},
+  {1.166701,0.751840},
+  {-0.127525,0.401022},
+  {0.092153,0.492356},
+  {-0.022106,0.491025},
+  {0.385129,1.227755},
+  {-0.436923,0.728795},
+  {-0.022073,-0.802340},
+  {1.216361,-1.280683},
+  {-0.519844,-0.069400},
+  {0.409208,-0.807452},
+  {-0.368572,0.226689},
+  {0.076268,0.839854},
+  {0.287471,-0.764709},
+  {1.363614,0.454507},
+  {-1.102576,0.253968},
+  {-0.046986,-0.270808},
+  {-0.736602,0.092040},
+  {1.165091,-0.216918},
+  {0.127164,0.453077},
+  {-0.886593,0.861856},
+  {0.158112,-0.594493},
+  {-0.030994,0.470361},
+  {-0.261688,0.126497},
+  {0.600867,0.028243},
+  {-0.982395,0.004090},
+  {-0.507128,-0.005293},
+  {-0.731200,-1.445173},
+  {-1.293737,-0.514366},
+  {0.105943,-0.405240},
+  {0.207327,-0.755563},
+  {-0.023598,0.754680},
+  {1.402186,-0.206298},
+  {-0.127333,0.036313},
+  {1.399904,-0.297810},
+  {-0.974748,0.286854},
+  {1.124209,1.335946},
+  {-0.128752,0.673476},
+  {0.713310,0.757828},
+  {-0.843100,-0.537106},
+  {-0.715673,0.477791},
+  {-0.382188,-0.826056},
+  {0.390282,-0.250610},
+  {0.514525,1.058072},
+  {-0.896554,1.141563},
+  {0.829613,0.348516},
+  {0.238624,0.417594},
+  {-0.105300,-1.182838},
+  {1.532616,-0.028817},
+  {-0.894122,-0.090487},
+  {-0.389445,0.360247},
+  {1.821895,0.589262},
+  {-1.125450,0.413939},
+  {0.161053,1.207355},
+  {-0.222854,0.366948},
+  {0.533803,0.516122},
+  {-0.531179,-0.721872},
+  {-0.763610,0.387296},
+  {-1.006094,-0.714480},
+  {-0.053524,2.039535},
+  {0.715739,-0.315490},
+  {0.112799,-0.374255},
+  {0.012495,-0.075747},
+  {0.777265,-1.168285},
+  {-0.030666,-0.933422},
+  {-0.621612,0.877107},
+  {1.613176,-0.222628},
+  {0.762815,0.849391},
+  {-0.616282,0.927940},
+  {-0.508595,-0.736129},
+  {-0.282486,0.049873},
+  {0.685474,-0.516179},
+  {-0.167842,-1.278946},
+  {-0.341434,0.561593},
+  {-0.450187,0.553444},
+  {-0.284804,0.812548},
+  {0.660818,0.289406},
+  {-0.851014,-1.087384},
+  {-0.046101,1.015682},
+  {-0.127992,-0.773456},
+  {0.306108,-0.585527},
+  {0.058395,1.365709},
+  {-1.008366,-0.490221},
+  {0.982199,0.335153},
+  {-0.577732,0.243236},
+  {0.835171,1.062171},
+  {0.861717,-0.878783},
+  {0.076238,0.653993},
+  {0.882457,-1.182033},
+  {0.395471,0.707660},
+  {0.175015,0.113237},
+  {-0.326660,-0.420746},
+  {-0.270266,-0.064866},
+  {1.219132,0.257211},
+  {0.532239,-1.366118},
+  {-0.063139,0.364975},
+  {-0.538459,-0.301802},
+  {-0.066699,1.443469},
+  {1.349248,-0.063832},
+  {0.640151,-0.177954},
+  {-0.281434,-0.418631},
+  {0.205809,0.035216},
+  {-0.593818,-0.007308},
+  {0.083672,-0.018417},
+  {0.229748,-1.197985},
+  {0.617426,-0.238514},
+  {0.627780,1.027152},
+  {-0.525954,0.502738},
+  {-0.494039,0.268553},
+  {-0.565555,1.133933},
+  {0.692407,-0.156891},
+  {-1.132269,-1.404156},
+  {0.952331,0.232551},
+  {0.542762,0.026346},
+  {-0.223407,-0.463245},
+  {-0.889800,-1.076883},
+  {1.183630,0.315594},
+  {-0.424457,-2.145227},
+  {2.273507,0.093040},
+  {1.217376,-0.209756},
+  {-0.118041,0.061581},
+  {-0.281683,-0.337646},
+  {0.681924,-0.618740},
+  {0.366107,0.349009},
+  {0.162105,-0.360180},
+  {0.626527,-0.551253},
+  {-0.406674,1.130650},
+  {-0.210328,-0.182414},
+  {0.362503,-0.512021},
+  {-0.628315,-0.024001},
+  {0.504299,0.803734},
+  {1.120537,0.920166},
+  {0.908672,-0.033387},
+  {-0.253838,1.298045},
+  {0.481005,0.131980},
+  {-0.135943,0.437193},
+  {0.267186,0.026759},
+  {0.542714,-0.264004},
+  {-1.206726,-0.419685},
+  {-0.699274,0.238968},
+  {0.463989,-0.510916},
+  {0.043349,-0.214415},
+  {0.160823,0.541792},
+  {-0.242431,-0.210894},
+  {0.511331,-0.176104},
+  {1.048913,0.488046},
+  {0.365260,-0.066836},
+  {-1.066309,-0.093985},
+  {0.542119,0.501833},
+  {-1.244972,-0.372142},
+  {-0.753972,-0.096356},
+  {-0.291842,0.016194},
+  {-0.477053,-0.804632},
+  {-0.078449,-0.379581},
+  {0.753739,-0.537456},
+  {0.100513,-0.310604},
+  {1.368776,0.717445},
+  {0.764968,-0.075108},
+  {0.053403,0.448399},
+  {0.582609,-0.788861},
+  {0.049464,-0.413320},
+  {-1.015383,-0.153174},
+  {-1.441094,1.226203},
+  {-0.935850,0.636812},
+  {0.714004,-0.531381},
+  {-0.467397,0.354665},
+  {-0.132670,0.678550},
+  {0.491754,-0.263982},
+  {0.137027,-0.063034},
+  {-0.320801,0.061453},
+  {-0.682060,0.697585},
+  {0.772583,-0.400500},
+  {-0.702765,0.154811},
+  {0.248536,-0.291513},
+  {1.213524,-1.416038},
+  {-0.169976,-0.794819},
+  {0.012138,0.740188},
+  {0.700987,-0.962213},
+  {0.654398,1.372495},
+  {0.267751,0.491715},
+  {0.380491,-0.409166},
+  {0.697133,-0.296663},
+  {-0.210519,0.303294},
+  {-0.557089,0.942688},
+  {0.250830,0.597076},
+  {0.836891,0.383697},
+  {-0.781979,-1.371013},
+  {-0.312390,-0.764450},
+  {-0.475572,0.060645},
+  {0.756715,-0.479073},
+  {-0.018402,0.967757},
+  {-1.118602,0.402060},
+  {-0.050789,0.033776},
+  {-0.378991,-0.301264},
+  {0.550866,-0.472333},
+  {0.695695,-0.564736},
+  {-1.022700,0.001319},
+  {-0.995349,-0.179992},
+  {-0.160696,-0.561579},
+  {-1.238996,1.005039},
+  {0.164585,0.869884},
+  {-0.474996,0.425370},
+  {-0.437417,1.116224},
+  {-0.429658,0.009218},
+  {-0.525544,-0.272148},
+  {0.695156,-0.102539},
+  {-0.850466,-0.358257},
+  {0.079718,-1.212420},
+  {0.484277,0.505628},
+  {0.433427,0.521144},
+  {1.357588,-0.280115},
+  {-1.050502,0.461743},
+  {0.092603,0.569536},
+  {0.031757,0.460663},
+  {-0.412955,0.613726},
+  {-0.236422,-0.089493},
+  {0.459335,0.304540},
+  {-0.753505,-0.235785},
+  {0.355571,-0.811544},
+  {0.221435,-0.954573},
+  {-2.346443,1.114150},
+  {-0.490478,0.349986},
+  {-0.652118,0.839932},
+  {0.946405,-0.288780},
+  {0.892454,0.348067},
+  {0.154899,0.070845},
+  {-0.145795,0.359580},
+  {1.398316,-0.468739},
+  {1.048537,0.085309},
+  {-0.840074,-0.159959},
+  {-0.514107,0.060504},
+  {-1.325402,-0.340374},
+  {0.838967,0.991954},
+  {-1.218276,-1.408265},
+  {0.335541,-0.565783},
+  {-0.954269,0.937467},
+  {-0.559335,-0.134362},
+  {1.943719,-1.403866},
+  {-0.460487,-0.682805},
+  {0.681467,-0.850286},
+  {-0.644147,0.907500},
+  {-0.369335,0.124141},
+  {-0.290076,-0.249195},
+  {-1.372572,0.399371},
+  {-0.216078,0.112425},
+  {0.202706,-0.571132},
+  {0.007932,0.238452},
+  {0.622883,-0.361681},
+  {-1.659769,-0.052142},
+  {0.913395,-0.548796},
+  {-1.546375,-0.177939},
+  {0.033195,0.124151},
+  {-1.002228,0.568683},
+  {-0.552731,-0.057954},
+  {-1.386417,-0.250903},
+  {-0.685426,0.169422},
+  {-0.419053,-0.687470},
+  {0.203790,1.177844},
+  {0.101606,0.434861},
+  {1.212102,-1.394154},
+  {-0.376188,0.550320},
+  {0.845756,0.440839},
+  {0.313480,-0.822269},
+  {-0.806734,-0.209968},
+  {0.235863,-0.633919},
+  {-0.345711,-1.139946},
+  {0.420142,0.087180},
+  {0.522750,0.494215},
+  {-0.415381,-0.544665},
+  {-0.805989,-0.717142},
+  {0.591845,-0.006759},
+  {-1.082991,-0.056471},
+  {-1.529968,1.037963},
+  {-0.255855,-1.785748},
+  {-0.454847,-0.034732},
+  {-0.272457,0.141042},
+  {-0.539356,0.233351},
+  {-1.123501,0.381575},
+  {-1.362791,-0.485143},
+  {0.867246,-0.554638},
+  {-0.592859,-0.071347},
+  {0.029115,0.338592},
+  {0.892906,-0.530447},
+  {-0.942275,-0.950575},
+  {0.681004,-0.812727},
+  {-0.682861,-0.748591},
+  {0.852113,0.476257},
+  {0.789010,-0.330489},
+  {0.615453,0.653533},
+  {1.319493,-1.499355},
+  {0.423842,-0.348825},
+  {0.157478,-0.767351},
+  {1.477448,1.666978},
+  {0.067225,-0.415903},
+  {0.744507,-0.884219},
+  {0.040268,0.058540},
+  {-1.735353,0.366785},
+  {0.153680,0.237515},
+  {0.667468,0.542703},
+  {0.436021,0.493232},
+  {0.563348,-1.182141},
+  {-0.003835,-0.322843},
+  {-0.656232,-0.176493},
+  {-0.873231,0.360992},
+  {0.136123,1.085468},
+  {-0.510539,0.320659},
+  {-0.312098,0.046118},
+  {-0.421199,-1.437631},
+  {-0.215423,0.161690},
+  {1.307419,-0.284457},
+  {-0.563560,-0.119780},
+  {-1.600169,0.228748},
+  {-1.421886,0.023649},
+  {-0.189495,0.797349},
+  {-0.165802,0.372003},
+  {-0.221700,-0.219905},
+  {0.534275,-0.120511},
+  {-0.248351,-0.805280},
+  {0.034413,0.744190},
+  {-0.642193,-0.452466},
+  {-0.599072,-0.680422},
+  {-1.724224,0.426709},
+  {-0.790234,-0.730923},
+  {0.088659,-1.035535},
+  {-0.275351,-0.733153},
+  {-1.102652,-0.046605},
+  {-0.757406,0.374197},
+  {1.053567,-1.538006},
+  {0.088439,-0.294301},
+  {0.516494,0.576207},
+  {0.909468,-0.056118},
+  {0.067821,-0.686035},
+  {-1.044428,0.968891},
+  {0.557625,-0.843896},
+  {-0.446400,0.872971},
+  {0.354836,1.692407},
+  {-1.197610,-0.164863},
+  {1.193169,-0.074590},
+  {0.564380,-0.167004},
+  {1.458768,0.101084},
+  {-1.659323,-0.179509},
+  {-0.637948,-1.333850},
+  {0.521633,-0.111609},
+  {0.159952,0.245567},
+  {0.557457,0.552443},
+  {-0.541189,-0.269047},
+  {0.178323,0.718181},
+  {-0.148046,1.282756},
+  {0.396217,-0.918592},
+  {-1.196000,-1.302291},
+  {-1.147016,1.087835},
+  {-0.697901,0.120563},
+  {-0.416445,-0.085792},
+  {-0.575136,1.047383},
+  {-0.108410,0.806852},
+  {0.103438,0.190436},
+  {-0.514501,0.205539},
+  {-1.158432,0.436651},
+  {1.837359,0.282446},
+  {2.898165,0.605520},
+  {-0.638636,-1.383828},
+  {-0.422205,-1.159697},
+  {0.439481,1.089898},
+  {-0.440211,0.267563},
+  {0.055757,-0.465994},
+  {0.203813,-1.372535},
+  {-0.369227,-0.991863},
+  {0.502829,0.205971},
+  {-0.168711,0.991037},
+  {-0.441042,-0.002326},
+  {0.323292,-0.197988},
+  {0.245345,0.967783},
+  {-1.106120,-0.247019},
+  {-0.701892,-0.940481},
+  {0.089337,0.099586},
+  {-0.484300,0.499526},
+  {1.270932,0.213534},
+  {0.769257,0.759910},
+  {-0.001945,0.582357},
+  {-1.013147,0.480989},
+  {0.541451,0.216142},
+  {0.984260,-0.129450},
+  {0.593683,-0.154239},
+  {-1.381179,1.039958},
+  {0.586204,-0.209757},
+  {0.373642,0.368349},
+  {0.322644,0.122887},
+  {-0.760574,0.101006},
+  {-0.369533,0.356949},
+  {0.793169,0.343188},
+  {-0.088122,-0.026515},
+  {-0.134987,-0.622070},
+  {-0.209032,0.730416},
+  {-0.633736,-0.964829},
+  {0.004523,0.680249},
+  {-0.251489,-0.161656},
+  {-1.236883,0.834379},
+  {0.158569,-0.243367},
+  {-0.728852,0.382640},
+  {0.132910,-0.265206},
+  {0.491294,1.636521},
+  {-1.199529,-0.648592},
+  {0.655339,-0.600365},
+  {-0.088940,0.359795},
+  {-0.344506,1.674392},
+  {-0.074931,-0.684859},
+  {-0.600775,0.495819},
+  {0.546661,-0.283537},
+  {0.816700,1.018373},
+  {1.345432,0.093005},
+  {-0.429347,-1.242027},
+  {-0.195153,0.520674},
+  {0.051187,-0.285221},
+  {-0.157695,0.732045},
+  {0.525571,0.750470},
+  {-1.647741,0.695828},
+  {0.729457,-1.305992},
+  {-0.156214,0.275815},
+  {-0.271609,-1.109912},
+  {-0.884156,1.468249},
+  {0.772042,-0.843589},
+  {1.124620,0.188741},
+  {-0.613738,-1.412528},
+  {1.392810,0.203713},
+  {0.414216,-0.811126},
+  {0.049929,-0.015404},
+  {-1.845246,0.585689},
+  {0.311221,-0.174248},
+  {0.322036,0.428788},
+  {0.323903,-1.877702},
+  {0.723333,-0.843178},
+  {-1.316829,-0.626211},
+  {-0.457250,-0.296858},
+  {0.460788,-0.256206},
+  {1.858779,0.618149},
+  {1.520473,0.618939},
+  {0.182818,-0.609792},
+  {0.093293,-0.511200},
+  {-0.796530,0.280311},
+  {0.314653,0.441506},
+  {0.145929,-0.171299},
+  {0.989340,-0.023398},
+  {0.382977,0.962526},
+  {-0.234472,0.204414},
+  {-0.168631,0.970621},
+  {-0.359397,-0.238005},
+  {-1.160084,-0.108981},
+  {1.026957,0.611603},
+  {0.594561,0.074036},
+  {-0.703831,-0.612982},
+  {-0.920383,0.335892},
+  {0.779956,-0.290330},
+  {0.160028,-0.530884},
+  {-0.462821,-0.124964},
+  {-0.021306,-0.500310},
+  {-0.640899,-0.880880},
+  {-0.168131,0.249834},
+  {-0.181111,0.256184},
+  {0.201675,-1.172094},
+  {-1.107592,-0.654002},
+  {0.618958,-1.100837},
+  {-0.613276,-0.606221},
+  {0.589475,0.793413},
+  {-0.799120,-1.033400},
+  {0.461943,0.180295},
+  {-0.992388,0.078304},
+  {0.249753,-0.552251},
+  {1.140054,0.813340},
+  {-0.380441,-0.427859},
+  {0.140464,-0.478517},
+  {-0.693361,1.211238},
+  {0.156036,-0.216601},
+  {0.403554,-1.008049},
+  {-0.867654,1.706051},
+  {-0.451461,0.206311},
+  {-1.312167,-0.321273},
+  {0.304323,1.501758},
+  {-1.237910,0.416220},
+  {-0.246990,-0.517017},
+  {0.921878,1.665267},
+  {0.680523,0.333206},
+  {-0.250695,-0.780680},
+  {0.017056,-1.185064},
+  {0.833909,-0.065707},
+  {-1.048432,-0.304359},
+  {-0.079640,0.971286},
+  {0.860137,1.148088},
+  {-0.222327,0.443586},
+  {0.569845,0.484530},
+  {0.709289,0.527264},
+  {-0.437060,1.058135},
+  {0.441519,0.926605},
+  {0.563086,-0.036039},
+  {0.731869,1.018196},
+  {0.715868,-0.555336},
+  {0.083263,-0.392260},
+  {-0.432371,0.271707},
+  {-0.323319,0.838910},
+  {-0.250503,-0.369677},
+  {-0.341576,-0.046356},
+  {1.703584,0.832092},
+  {0.305570,0.700940},
+  {0.313809,0.320696},
+  {-0.232152,-0.195104},
+  {-0.160822,0.383805},
+  {-0.782644,0.821497},
+  {0.317483,0.561839},
+  {0.292112,-0.787810},
+  {0.682217,-0.036886},
+  {-0.234958,-0.342815},
+  {1.489802,0.394218},
+  {-0.780212,0.082822},
+  {0.012921,1.219529},
+  {-0.309442,1.310485},
+  {0.805021,0.916130},
+  {-0.164403,-0.490808},
+  {-2.442305,0.477766},
+  {0.306204,0.782185},
+  {-0.642253,0.034201},
+  {-0.734342,0.374860},
+  {-0.534225,-0.141448},
+  {-1.039800,0.243934},
+  {-0.758901,0.139142},
+  {0.772172,-0.221432},
+  {-0.227259,-0.494436},
+  {-0.797240,0.203608},
+  {-0.526939,-1.003768},
+  {0.604457,-0.836335},
+  {-1.042733,-1.031733},
+  {0.351133,-1.552611},
+  {0.193510,-0.593573},
+  {-0.158616,-0.000909},
+  {0.477336,0.765709},
+  {0.294301,-0.549073},
+  {2.252452,0.421725},
+  {-0.648990,-0.424124},
+  {-0.564920,-0.189999},
+  {-0.270131,0.078961},
+  {0.772736,0.336949},
+  {0.313340,-0.927747},
+  {-0.573263,0.583021},
+  {0.470820,-1.055331},
+  {0.581432,0.212701},
+  {-0.711626,0.384798},
+  {0.162031,-0.175657},
+  {0.742236,-0.643734},
+  {0.803206,-0.132745},
+  {0.613025,-0.690771},
+  {0.291435,1.290752},
+  {0.501168,0.658611},
+  {-1.443138,-0.434044},
+  {0.661785,0.822570},
+  {-1.374180,0.778183},
+  {0.382538,-0.753720},
+  {-0.517099,0.294458},
+  {0.849115,0.536175},
+  {1.511322,-0.255960},
+  {-0.446477,-0.510725},
+  {0.351935,-0.058662},
+  {-0.309950,-0.683659},
+  {-0.315003,0.260157},
+  {0.056499,-0.463872},
+  {-0.865618,-0.396466},
+  {-1.294184,0.061282},
+  {1.011925,0.144531},
+  {0.932576,-0.379779},
+  {1.018562,0.158520},
+  {-0.048017,0.052001},
+  {-0.917482,-1.278635},
+  {-0.098721,-0.152092},
+  {1.017871,0.028110},
+  {-0.268018,-0.393909},
+  {0.293293,0.208300},
+  {-0.580657,-0.411407},
+  {1.031302,0.428409},
+  {1.910617,-0.467351},
+  {-0.831919,1.592028},
+  {0.663417,-0.384198},
+  {1.046530,-0.066088},
+  {0.351843,0.024416},
+  {0.571277,-0.833007},
+  {-0.079296,-0.149397},
+  {0.413530,-0.701706},
+  {0.210312,-0.385820},
+  {-0.140847,-0.268188},
+  {0.139115,1.298546},
+  {-1.143262,-0.441174},
+  {-0.027645,0.535143},
+  {-0.405058,-0.616212},
+  {0.316847,-0.050931},
+  {0.349966,-0.763656},
+  {-0.103767,0.410991},
+  {-1.917632,-0.571364},
+  {-0.242820,-1.010565},
+  {-0.127771,-0.753536},
+  {0.604908,-0.475209},
+  {0.013372,0.837038},
+  {0.608820,0.079690},
+  {-0.142643,-0.181203},
+  {-0.281800,-0.574404},
+  {1.254414,0.387417},
+  {0.880432,-0.334068},
+  {-0.222264,-1.359749},
+  {-0.157873,0.904339},
+  {-0.249764,-0.463576},
+  {0.667664,0.499756},
+  {-0.267900,0.673011},
+  {0.640840,1.260412},
+  {0.484117,-0.429452},
+  {0.592152,-0.003510},
+  {0.506192,-0.201848},
+  {1.247699,0.171432},
+  {0.353386,0.996887},
+  {0.078137,-0.308590},
+  {-0.018745,-1.037419},
+  {1.093397,0.245313},
+  {0.750051,1.199990},
+  {-0.094081,-0.586781},
+  {0.051596,-0.731723},
+  {0.455013,1.276353},
+  {-0.195394,-0.845165},
+  {-0.520628,0.355488},
+  {-0.688832,-0.070661},
+  {0.375953,0.177470},
+  {1.142021,0.354608},
+  {-0.475901,0.038190},
+  {0.364796,0.118211},
+  {-0.675976,-0.263314},
+  {-0.552894,0.232846},
+  {-0.464710,-0.158232},
+  {-0.258691,-0.053579},
+  {0.279914,-0.374251},
+  {-0.442636,-0.032047},
+  {-0.444012,-0.548113},
+  {-0.360146,0.089110},
+  {0.490385,0.171563},
+  {1.123041,-0.550139},
+  {0.543533,0.079109},
+  {-0.637200,-1.014626},
+  {0.046707,-0.245370},
+  {-0.257292,1.703984},
+  {-0.071662,-0.589401},
+  {0.108536,0.405153},
+  {-0.344097,0.282119},
+  {-0.245578,0.106487},
+  {-0.401110,-1.258960},
+  {0.107488,0.353920},
+  {0.608643,-0.021585},
+  {0.440527,-1.022432},
+  {0.213325,0.187777},
+  {-0.052628,-0.281017},
+  {0.235210,0.007120},
+  {-1.235719,0.155901},
+  {-0.268724,1.113432},
+  {-0.121335,0.019839},
+  {0.189913,1.015487},
+  {0.865889,0.697982},
+  {0.197149,0.792114},
+  {-0.117071,0.639035},
+  {-1.306955,0.275980},
+  {0.252452,0.322515},
+  {-0.529397,-0.478036},
+  {0.936446,-1.395706},
+  {0.400833,0.024500},
+  {-0.502883,-0.102895},
+  {0.273595,0.753245},
+  {-0.343074,0.091902},
+  {0.304226,-0.867240},
+  {-0.180509,-1.078705},
+  {-0.205455,0.858649},
+  {0.774539,0.517635},
+  {-0.823959,0.593452},
+  {0.732369,0.153099},
+  {0.672588,-0.633125},
+  {0.002290,-0.941901},
+  {0.176569,-0.579932},
+  {0.171845,-0.870413},
+  {-0.293425,0.175049},
+  {-0.137718,0.217686},
+  {1.044936,0.061606},
+  {-0.758815,0.807341},
+  {-0.336751,-0.164385},
+  {1.008626,0.256348},
+  {-0.723706,0.047971},
+  {-0.050905,-0.353985},
+  {0.390970,-0.158517},
+  {0.119335,0.109838},
+  {-0.041174,-0.673703},
+  {-0.556070,-0.401985},
+  {-0.509192,0.543375},
+  {0.625149,-0.084801},
+  {-0.744969,0.178757},
+  {-0.163163,0.168014},
+  {-0.749477,0.577796},
+  {-0.154530,0.089817},
+  {0.437073,-0.946214},
+  {-0.116608,-1.099246},
+  {0.666880,0.264435},
+  {0.474793,-0.843138},
+  {0.617247,0.069116},
+  {0.294487,0.030065},
+  {-0.337986,0.559117},
+  {-0.227776,0.882621},
+  {1.101572,-1.080786},
+  {0.070565,-0.664384},
+  {-0.451764,-0.457432},
+  {-0.576313,-0.841245},
+  {0.068010,0.274456},
+  {-0.710972,1.045372},
+  {-0.080175,-0.636644},
+  {-1.167785,-0.908857},
+  {-0.040623,0.027782},
+  {2.470891,-0.352323},
+  {0.225188,-0.216579},
+  {-0.911285,-0.883839},
+  {1.575339,0.857027},
+  {-0.480260,0.028266},
+  {-1.400611,-0.208040},
+  {-0.607262,0.315214},
+  {-1.413554,-0.086775},
+  {-0.078748,0.091694},
+  {-0.823326,-0.045219},
+  {0.179688,0.157220},
+  {0.503945,-0.069413},
+  {0.384609,1.810637},
+  {-0.036682,0.018567},
+  {-0.630811,-0.597114},
+  {-0.672791,-0.931285},
+  {1.222804,1.107029},
+  {-0.313392,0.591602},
+  {1.095544,1.771690},
+  {-0.798560,1.745435},
+  {1.543951,0.832816},
+  {0.126556,1.114287},
+  {0.213435,1.321216},
+  {-0.224136,-1.359183},
+  {1.477972,-0.350192},
+  {-0.077844,-0.795493},
+  {-0.231997,-0.564458},
+  {0.801618,-0.460815},
+  {-1.183569,1.681266},
+  {0.800365,-1.537642},
+  {-0.329589,-0.279386},
+  {0.146069,-0.294189},
+  {0.197825,0.827717},
+  {-0.649584,1.974452},
+  {-1.281819,1.044606},
+  {0.908785,-0.571095},
+  {1.096563,-0.008991},
+  {1.743241,0.314216},
+  {0.653207,0.687347},
+  {-0.304444,-0.200533},
+  {0.317770,0.204985},
+  {1.680031,-1.270921},
+  {0.013470,0.101117},
+  {0.035178,0.125471},
+  {-0.496304,-1.027426},
+  {-0.803857,-0.277048},
+  {0.785028,-0.689768},
+  {0.339297,0.190250},
+  {0.464936,-0.560609},
+  {-0.775980,-0.128567},
+  {-0.724656,0.021571},
+  {0.116261,-1.049885},
+  {-0.856403,0.530206},
+  {0.067380,-0.690871},
+  {-0.101626,0.190740},
+  {-0.230450,0.733674},
+  {1.510300,-0.232611},
+  {-0.558900,0.743672},
+  {0.328636,-0.130287},
+  {0.037062,0.836783},
+  {0.228297,-1.114284},
+  {0.591880,-0.742029},
+  {1.016332,0.389831},
+  {0.501144,0.220041},
+  {-0.682226,0.173825},
+  {0.194447,-0.220124},
+  {-0.201636,0.483213},
+  {-0.346227,0.693268},
+  {0.089963,0.776428},
+  {0.784136,-0.216991},
+  {1.351173,0.460213},
+  {0.948340,0.389235},
+  {0.856649,-0.280823},
+  {-0.281458,-0.467549},
+  {0.712758,-0.473551},
+  {-0.113624,-0.180662},
+  {0.827903,-0.935301},
+  {0.384431,0.183861},
+  {-0.116835,0.143097},
+  {0.437151,0.673442},
+  {-0.259116,1.211244},
+  {-0.832708,0.005765},
+  {0.579745,-0.839210},
+  {-0.272578,0.846526},
+  {0.006319,-0.191822},
+  {-0.543038,-2.053956},
+  {0.577765,-0.226179},
+  {-0.864414,0.264531},
+  {-0.081640,-0.316889},
+  {-0.733387,-0.029103},
+  {-0.856447,0.102918},
+  {1.118355,-0.516612},
+  {-0.953002,0.614206},
+  {0.317643,0.733096},
+  {-0.268814,0.548796},
+  {1.819432,-1.055275},
+  {-0.311760,0.400650},
+  {0.198343,-1.247555},
+  {-0.027410,0.778872},
+  {-0.508919,0.444286},
+  {-1.171694,0.019824},
+  {1.248879,0.012588},
+  {-0.703571,-1.267101},
+  {-0.351630,0.717535},
+  {0.712341,0.238149},
+  {-0.921778,0.823704},
+  {0.183744,-0.465176},
+  {0.967624,0.110433},
+  {0.638384,-0.733964},
+  {0.023469,-0.341078},
+  {0.457953,0.148002},
+  {-0.387642,0.886603},
+  {-0.069635,-0.580919},
+  {-0.059943,-1.223428},
+  {0.912288,0.393697},
+  {0.642983,0.930647},
+  {0.910222,0.601928},
+  {-0.445410,-0.667141},
+  {-1.572064,0.279244},
+  {1.978238,0.802084},
+  {-0.397479,-0.061574},
+  {0.410751,0.408608},
+  {-0.708602,-0.186290},
+  {-0.230716,0.939863},
+  {0.243815,0.220266},
+  {0.510986,0.986593},
+  {-0.697529,0.649296},
+  {-0.586676,-0.694978},
+  {1.365805,0.060623},
+  {0.669724,0.191354},
+  {1.712433,0.794664},
+  {1.420112,0.316341},
+  {0.241010,0.642880},
+  {-0.543402,-0.040763},
+  {0.566228,-0.271359},
+  {-0.161257,0.334876},
+  {0.599455,1.548617},
+  {-0.164632,-0.789523},
+  {-0.166458,-1.089323},
+  {-0.603273,-0.989075},
+  {0.528595,0.451579},
+  {-0.312701,0.087580},
+  {0.052067,-0.329935},
+  {-0.422394,-0.867374},
+  {0.543689,0.209453},
+  {-0.559684,-1.177563},
+  {0.467575,-0.097401},
+  {0.369629,-0.501474},
+  {0.404819,0.203655},
+  {1.147670,0.855509},
+  {-0.639961,0.122152},
+  {0.634182,-0.589714},
+  {-1.383792,0.081240},
+  {-0.762136,-0.308434},
+  {0.795235,-0.419563},
+  {-0.464381,1.585393},
+  {1.078462,0.518624},
+  {0.096101,-0.470606},
+  {-1.483047,-0.692461},
+  {-0.298531,0.776764},
+  {0.119121,-0.885261},
+  {0.117578,0.531321},
+  {-0.917483,1.214456},
+  {0.103637,-0.543026},
+  {-0.029330,-0.442023},
+  {0.667382,-0.559059},
+  {0.454800,1.315120},
+  {-0.121242,1.135188},
+  {-0.488542,0.095236},
+  {1.029647,0.289141},
+  {-0.103825,-0.536353},
+  {0.328875,0.038776},
+  {0.506639,-0.670018},
+  {0.579004,0.162704},
+  {0.390291,0.091227},
+  {-1.290292,-0.652858},
+  {-0.408826,0.011857},
+  {0.767200,0.888858},
+  {1.439873,0.872966},
+  {1.146577,0.749942},
+  {0.081693,-0.305140},
+  {-0.129388,1.025387},
+  {-0.634484,-0.843138},
+  {0.172444,0.005313},
+  {-0.657469,-0.089850},
+  {-0.760529,-0.081906},
+  {-0.426315,-1.084558},
+  {-0.979330,-0.160143},
+  {-0.044730,0.574946},
+  {-1.527934,0.139190},
+  {-0.115705,-0.468978},
+  {0.394550,-0.231006},
+  {0.586208,-0.529691},
+  {0.437290,-1.153886},
+  {0.808557,1.623821},
+  {-1.472277,0.306073},
+  {0.113523,-0.990164},
+  {-0.436942,-0.152251},
+  {0.906011,-0.455300},
+  {-0.137609,-0.290251},
+  {0.467302,-0.253409},
+  {-0.677977,-0.643365},
+  {-0.258209,0.117683},
+  {0.237770,0.579862},
+  {0.361357,0.184037},
+  {-0.768527,-0.431966},
+  {-0.374232,0.070814},
+  {-0.271652,0.701989},
+  {-1.650963,1.243199},
+  {0.817481,-0.130520},
+  {0.093297,1.182986},
+  {-0.740615,0.357099},
+  {0.190737,1.086730},
+  {-0.326431,-0.458982},
+  {0.123048,1.118810},
+  {-0.006755,0.087656},
+  {0.321461,0.525849},
+  {-0.567447,-0.412553},
+  {-0.516657,-1.118277},
+  {-0.343009,-0.119105},
+  {0.491223,1.372952},
+  {0.179821,0.053473},
+  {-0.238648,0.029409},
+  {0.222945,0.156960},
+  {0.310281,0.281777},
+  {-0.992198,-0.975749},
+  {-0.432296,-0.289497},
+  {-1.121582,-0.621216},
+  {-0.079473,-0.549632},
+  {0.673944,0.250442},
+  {-1.170647,0.816044},
+  {0.009351,-0.038545},
+  {0.202295,0.376773},
+  {0.207996,-0.767330},
+  {-0.683128,0.462706},
+  {0.363351,0.668791},
+  {-0.236248,0.234738},
+  {0.236777,0.097248},
+  {-0.079751,-0.322131},
+  {0.422070,0.380715},
+  {0.465275,-0.117293},
+  {0.914394,0.070100},
+  {-0.328927,-1.087863},
+  {0.009725,-0.714301},
+  {0.694105,-0.275872},
+  {0.038939,-1.079395},
+  {0.761932,1.210910},
+  {0.753418,0.067086},
+  {-0.215663,-0.159486},
+  {-0.187086,0.872605},
+  {-0.142958,0.220448},
+  {0.273894,-0.555399},
+  {-0.650689,-0.402346},
+  {0.897581,0.328779},
+  {-0.338363,1.002994},
+  {-0.328070,0.563372},
+  {-0.550288,0.856980},
+  {-0.977701,-1.482775},
+  {2.446075,-0.651519},
+  {0.653114,0.245545},
+  {0.481750,1.570437},
+  {-0.925317,0.286313},
+  {0.723354,0.222318},
+  {0.684692,-1.247687},
+  {-0.189216,-0.475236},
+  {-0.640211,0.212953},
+  {-0.053677,0.669794},
+  {-0.330972,-0.472563},
+  {0.194653,-1.044945},
+  {-0.541368,-0.021547},
+  {0.683410,-0.394597},
+  {0.106472,-0.419672},
+  {0.760465,0.199993},
+  {-1.179110,0.112292},
+  {0.055066,0.377698},
+  {0.909270,-1.560735},
+  {0.401362,1.350247},
+  {0.187297,-0.004588},
+  {-0.039523,1.088870},
+  {-0.268140,0.216489},
+  {0.164274,1.288643},
+  {-1.308630,0.008255},
+  {-0.828187,0.539431},
+  {0.171691,1.194553},
+  {0.299761,-0.052910},
+  {1.722756,-0.697963},
+  {-0.251873,-0.722015},
+  {0.079270,-0.072157},
+  {-0.932151,-0.304344},
+  {0.207095,0.052868},
+  {1.088320,-1.003559},
+  {0.850424,-0.709885},
+  {0.649069,-1.639259},
+  {0.383301,-0.409913},
+  {0.170324,-0.407571},
+  {0.752730,0.520546},
+  {0.243588,0.101737},
+  {-0.487145,0.946709},
+  {-0.484323,-0.380167},
+  {0.224305,-0.272019},
+  {0.059913,-0.726160},
+  {-0.285819,-0.028296},
+  {-1.484445,-0.022900},
+  {0.166353,0.255178},
+  {-1.161566,0.903064},
+  {0.494498,0.797073},
+  {-0.297146,-0.147285},
+  {-0.236315,0.665692},
+  {-0.085679,0.279219},
+  {-0.870393,0.141386},
+  {-0.014293,-0.542938},
+  {-0.365326,0.980887},
+  {0.203701,-0.711214},
+  {-0.407262,0.445812},
+  {1.421543,-0.606156},
+  {1.347169,0.048977},
+  {-1.433734,0.817061},
+  {1.146370,-0.793382},
+  {0.319925,-0.854738},
+  {0.438860,2.145962},
+  {1.166341,-0.365637},
+  {0.683141,0.055309},
+  {-1.130258,0.470611},
+  {-0.142316,0.723606},
+  {-1.167357,0.251633},
+  {-0.061046,-0.144651},
+  {-0.028701,-0.462089},
+  {-0.018132,0.169646},
+  {-0.671335,0.900461},
+  {0.116801,-0.593090},
+  {0.085282,-0.067586},
+  {-0.411836,0.548411},
+  {0.260672,-1.297764},
+  {-0.232586,-0.692774},
+  {-0.797251,0.519497},
+  {0.493274,0.128724},
+  {-0.452326,-0.942666},
+  {-1.259305,0.165846},
+  {-0.397245,-0.650621},
+  {-0.827247,-0.027941},
+  {0.400771,0.899915},
+  {-1.510673,-0.552102},
+  {-0.016118,-1.664885},
+  {0.468835,-0.256144},
+  {-0.095802,-0.449476},
+  {-0.334430,-1.538678},
+  {0.005072,0.053176},
+  {0.276647,-0.648527},
+  {0.087667,0.067103},
+  {0.853516,0.367063},
+  {0.694817,-0.772811},
+  {0.402106,-0.764670},
+  {0.563088,0.747578},
+  {-0.268367,1.277181},
+  {-0.749042,-0.032805},
+  {1.254513,0.221049},
+  {-0.610276,0.267629},
+  {-0.316447,1.420839},
+  {-1.922798,-0.390022},
+  {0.556385,0.484709},
+  {0.027270,0.139172},
+  {-0.726247,-0.156295},
+  {-0.120574,1.445949},
+  {0.876597,0.011245},
+  {-0.056240,-0.228567},
+  {-0.008902,-0.187852},
+  {0.322713,-0.491207},
+  {-0.362863,0.473453},
+  {-0.712861,-0.365141},
+  {-0.742098,-0.136880},
+  {0.111748,1.005100},
+  {-0.464041,-0.288319},
+  {-0.591913,0.416452},
+  {0.517190,0.391430},
+  {1.195625,0.788324},
+  {0.410152,0.138649},
+  {-1.371791,1.228180},
+  {-0.101232,0.141153},
+  {-0.710496,-0.154048},
+  {-0.808498,-0.383805},
+  {-0.018569,-0.202316},
+  {1.184777,-1.079341},
+  {-1.306705,0.345682},
+  {-0.154691,0.011843},
+  {0.661710,0.500578},
+  {-0.343929,0.779614},
+  {0.543034,1.214597},
+  {-1.348330,0.139834},
+  {0.117324,0.850516},
+  {-0.108573,-0.567512},
+  {-0.543670,-0.506252},
+  {0.763259,-0.023357},
+  {-0.124683,-0.687557},
+  {-0.298014,0.912602},
+  {0.205308,0.618330},
+  {1.529908,-0.085205},
+  {0.956008,-0.652740},
+  {-0.068925,-1.092457},
+  {-0.637354,-0.419358},
+  {1.268680,-0.243073},
+  {-0.136088,-0.425454},
+  {-1.136538,1.501422},
+  {-0.865629,0.163418},
+  {1.489446,-0.425663},
+  {-0.176186,-0.697113},
+  {0.053611,-0.207498},
+  {0.453244,0.901965},
+  {0.045845,1.465057},
+  {0.863726,-0.540462},
+  {-0.043928,0.683414},
+  {0.115106,-1.021701},
+  {0.247975,0.286382},
+  {0.801124,0.684719},
+  {-0.492425,-0.671975},
+  {-0.738085,-0.372832},
+  {0.246402,0.622964},
+  {1.316755,0.124231},
+  {0.061890,0.559458},
+  {-0.016314,0.518483},
+  {0.065088,-0.564502},
+  {-1.075867,-0.098767},
+  {0.178467,0.098481},
+  {-0.008945,-0.802168},
+  {-0.811757,0.814761},
+  {1.059392,-0.846953},
+  {-0.343747,0.373055},
+  {0.758821,-1.176281},
+  {-0.647837,-0.951149},
+  {-0.817682,0.112162},
+  {1.173084,-0.558803},
+  {-0.604647,0.144875},
+  {-0.132176,0.361366},
+  {-0.668269,0.061026},
+  {0.246659,0.201436},
+  {1.226810,-0.619724},
+  {-0.468072,-0.019591},
+  {0.966661,0.482886},
+  {0.583820,0.926226},
+  {0.852546,0.572840},
+  {-0.649207,-0.545958},
+  {0.255183,-0.155787},
+  {-0.025898,0.078114},
+  {-0.201309,-0.225492},
+  {0.525905,0.410706},
+  {0.177865,1.477507},
+  {2.457610,-1.850447},
+  {0.151478,1.000617},
+  {1.360119,-0.754828},
+  {0.157215,-0.492841},
+  {-0.566692,1.324305},
+  {0.620154,0.754623},
+  {0.074979,-0.860552},
+  {-0.222454,0.021736},
+  {-1.408236,-1.307141},
+  {-0.544968,0.463417},
+  {-0.595774,-0.743040},
+  {0.559990,0.480234},
+  {-1.168589,-0.203965},
+  {0.281098,-0.105368},
+  {0.641682,-0.360390},
+  {0.836257,-0.373430},
+  {-0.805041,0.752649},
+  {0.441466,-0.719064},
+  {-1.832253,1.143759},
+  {-0.247786,-0.438656},
+  {-0.870375,0.850503},
+  {-0.375699,0.159219},
+  {-1.124725,0.793712},
+  {-0.723709,0.342564},
+  {-0.633437,-0.558060},
+  {-0.135905,-0.355088},
+  {-2.183977,-0.007379},
+  {1.116177,0.159945},
+  {1.490166,0.480268},
+  {0.164575,-0.726484},
+  {-0.520145,0.297363},
+  {-0.641292,-0.643205},
+  {-0.067693,-0.128819},
+  {0.413410,0.031469},
+  {-0.760742,1.425786},
+  {0.085627,-0.041021},
+  {0.114922,0.384508},
+  {-0.225939,-0.065478},
+  {0.023267,1.057989},
+  {1.470100,-0.598823},
+  {0.723707,-1.348607},
+  {0.035084,-1.125010},
+  {-0.454672,0.069253},
+  {0.809724,-0.071756},
+  {0.083234,0.221237},
+  {-0.377449,1.091443},
+  {0.402802,0.357787},
+  {-0.684853,-0.705112},
+  {-0.625051,-0.136144},
+  {1.018437,-0.307444},
+  {-0.339611,0.577613},
+  {-0.559291,-0.331159},
+  {-0.661887,0.404697},
+  {-0.412244,-0.877878},
+  {-0.591570,-0.072583},
+  {-0.437359,0.868594},
+  {0.926766,-0.479234},
+  {-0.939874,0.960508},
+  {-0.216226,-2.190387},
+  {0.373954,-0.239234},
+  {0.735172,-0.368192},
+  {0.925092,0.361395},
+  {0.238858,-1.067577},
+  {0.211254,0.055615},
+  {0.067811,-0.232802},
+  {-0.256948,-1.231779},
+  {-0.231535,-1.085856},
+  {1.027191,0.635764},
+  {-1.039482,-0.284762},
+  {0.802325,0.903988},
+  {-0.407235,-0.165035},
+  {-0.645411,0.570917},
+  {-0.631895,-0.866667},
+  {-0.413516,-0.479763},
+  {-0.327054,0.889851},
+  {-0.660647,1.168247},
+  {-0.054201,-0.157478},
+  {0.021347,1.157376},
+  {-0.281979,0.310791},
+  {1.078613,-0.998599},
+  {0.978329,-0.316584},
+  {0.227859,-0.057813},
+  {0.879319,1.029731},
+  {0.007877,-0.338237},
+  {-0.023282,0.856635},
+  {0.802926,0.658965},
+  {-0.654637,-0.321326},
+  {-0.486953,-0.278102},
+  {0.399871,-0.703921},
+  {0.137966,-0.143648},
+  {-1.382161,-0.633032},
+  {0.994994,0.454662},
+  {-0.563795,-0.296766},
+  {0.395332,-0.055457},
+  {0.879708,-0.963628},
+  {-0.321128,-0.149853},
+  {-0.072034,-0.491397},
+  {0.094058,-0.301073},
+  {0.846232,0.232090},
+  {0.286858,-0.066615},
+  {-0.642041,0.413146},
+  {0.464097,0.354731},
+  {0.102751,1.804440},
+  {0.377422,0.609243},
+  {0.654797,-0.435679},
+  {0.472210,-0.209745},
+  {-0.641060,-0.154395},
+  {-1.512229,0.312514},
+  {-0.668791,-1.337721},
+  {-0.568657,-0.277971},
+  {0.842358,1.337541},
+  {-0.633354,0.123400},
+  {-0.236926,1.438454},
+  {-0.524131,0.461021},
+  {-0.027427,0.041582},
+  {-0.630328,-0.951639},
+  {0.467582,-0.775196},
+  {-0.645079,-0.410044},
+  {1.050603,1.068060},
+  {-0.144830,0.117018},
+  {-0.428974,-0.059010},
+  {0.343620,-1.481687},
+  {-0.117022,0.802153},
+  {0.371381,0.568841},
+  {-0.713658,-0.166011},
+  {-0.262867,-0.772913},
+  {1.097425,0.118692},
+  {-0.682499,0.040285},
+  {-0.088318,-0.101135},
+  {0.596149,0.381073},
+  {-1.594536,0.711970},
+  {-0.520008,0.491471},
+  {0.042324,0.355744},
+  {-0.736938,-0.529835},
+  {-0.648401,0.855958},
+  {-0.338084,-0.351747},
+  {0.672677,0.892670},
+  {0.361092,-0.678357},
+  {2.079292,0.329758},
+  {0.234354,0.449063},
+  {0.246854,-0.747312},
+  {-0.254858,-0.378022},
+  {0.391048,0.078144},
+  {-1.322392,1.109864},
+  {-0.392252,1.133680},
+  {0.317787,-1.119124},
+  {-1.125500,0.590658},
+  {0.651714,-0.019948},
+  {-0.188271,-0.587491},
+  {0.512942,0.238828},
+  {-0.089800,0.880141},
+  {-0.020669,-0.745277},
+  {-0.393933,0.425016},
+  {-0.706385,-0.337056},
+  {-0.072274,-0.466942},
+  {1.361972,1.600456},
+  {-0.536411,0.143837},
+  {-1.315825,-0.345262},
+  {0.586610,-0.105453},
+  {0.361835,-0.310457},
+  {0.162424,-0.455937},
+  {-0.266229,0.468748},
+  {0.608348,0.237188},
+  {-0.338820,0.469070},
+  {0.825241,-0.122825},
+  {-1.296042,-1.106153},
+  {0.782186,1.012854},
+  {0.546063,0.108291},
+  {-0.675564,-0.118591},
+  {0.959435,-0.617240},
+  {0.253049,0.642651},
+  {-0.717033,0.421230},
+  {0.065648,-0.236145},
+  {0.787941,-0.725300},
+  {-0.214982,-0.330445},
+  {-0.005308,0.843855},
+  {0.569761,-1.404632},
+  {-0.847684,0.288276},
+  {-1.351673,0.398555},
+  {-0.653094,0.359977},
+  {-0.451479,-0.175236},
+  {0.250162,1.082506},
+  {1.720280,-0.173550},
+  {0.043283,0.495568},
+  {-0.467075,-0.286571},
+  {-0.516911,0.372184},
+  {-0.644850,0.027566},
+  {0.412044,-0.228306},
+  {0.441079,-0.818598},
+  {0.597972,0.496661},
+  {-0.751802,0.592583},
+  {-0.172332,-0.063214},
+  {-0.486652,0.453796},
+  {-0.789048,0.001233},
+  {-0.037757,-0.424086},
+  {0.610775,0.085934},
+  {1.357820,0.385392},
+  {0.772897,0.561994},
+  {-0.547971,0.343509},
+  {-0.305912,-0.659965},
+  {-0.150391,0.051106},
+  {-0.659545,0.811236},
+  {1.156720,-1.403491},
+  {0.250035,0.752173},
+  {-1.033130,1.467901},
+  {-0.081366,0.567584},
+  {-0.189016,0.757573},
+  {-0.062907,0.109766},
+  {0.519387,-0.073148},
+  {0.852716,1.480028},
+  {-0.332826,-0.335259},
+  {0.699783,1.177709},
+  {-1.501976,-0.869618},
+  {0.011903,0.566373},
+  {0.240645,0.815848},
+  {0.022006,0.778674},
+  {-0.311565,-0.232334},
+  {0.412026,0.252313},
+  {-0.541887,0.196055},
+  {1.576042,1.850318},
+  {0.801784,0.173800},
+  {-0.910855,-0.685674},
+  {2.049228,-0.222369},
+  {-0.354029,1.030187},
+  {0.323162,-0.505727},
+  {-0.125605,-0.829970},
+  {0.512979,0.187703},
+  {-1.013040,-1.303101},
+  {0.013997,0.121938},
+  {0.058118,0.257561},
+  {-0.258403,0.395440},
+  {-0.670940,1.122375},
+  {-1.432201,-0.379968},
+  {-0.814277,-0.812373},
+  {-0.559929,0.609962},
+  {0.363925,0.849823},
+  {0.621028,-0.837635},
+  {-0.240268,-0.472030},
+  {0.072362,1.038756},
+  {0.227193,-0.732684},
+  {-0.658857,0.208278},
+  {-1.534011,0.239111},
+  {-0.154706,-0.173726},
+  {-1.368605,-1.607920},
+  {0.111885,0.436946},
+  {-0.125141,1.156338},
+  {-0.468032,-1.283854},
+  {-0.095271,-1.024174},
+  {-0.298550,0.045489},
+  {0.683411,0.029385},
+  {0.549679,-0.031146},
+  {0.498454,-0.530899},
+  {-0.477430,0.323974},
+  {0.791994,0.089182},
+  {0.361261,0.618991},
+  {0.562423,0.394355},
+  {0.244952,0.570213},
+  {0.006620,2.036926},
+  {-1.886519,-0.587302},
+  {0.648386,0.606893},
+  {-1.081200,1.050888},
+  {0.376747,-0.048129},
+  {-0.587935,0.543545},
+  {1.449966,-0.385258},
+  {0.268650,1.464783},
+  {-0.781591,-0.348916},
+  {0.585803,-0.636496},
+  {0.978237,1.172719},
+  {0.668928,-0.068851},
+  {-1.466985,0.045779},
+  {-1.179510,1.101713},
+  {0.904752,0.497169},
+  {0.097355,-0.293205},
+  {-0.172173,-0.181016},
+  {-0.501643,-0.080642},
+  {0.581053,-0.218558},
+  {-0.895757,0.375873},
+  {-0.483364,0.120657},
+  {-0.423777,0.643739},
+  {0.124416,-1.106641},
+  {-1.457878,-0.321679},
+  {0.659524,-0.761259},
+  {0.364923,-0.166847},
+  {-1.388401,-0.199159},
+  {1.588209,-0.604498},
+  {1.309079,-0.352915},
+  {-0.347980,0.189430},
+  {0.911844,-1.078087},
+  {0.278893,-0.835737},
+  {-0.982551,-0.254161},
+  {-0.431526,0.412463},
+  {-0.477069,0.486325},
+  {0.573694,0.715416},
+  {1.143420,2.072284},
+  {-0.857854,-0.906373},
+  {-0.297631,0.413436},
+  {-0.467294,-0.331288},
+  {0.982162,-0.975864},
+  {0.285199,0.043006},
+  {-0.812961,0.340233},
+  {1.431540,1.133126},
+  {0.102308,0.190565},
+  {1.476116,0.637898},
+  {0.434583,0.580426},
+  {0.046831,-0.794218},
+  {-0.341083,0.192367},
+  {-0.279135,-0.299876},
+  {0.296558,0.569512},
+  {0.147472,0.329278},
+  {-1.388735,1.020627},
+  {0.602259,0.386248},
+  {-0.528118,1.134901},
+  {-0.181877,-0.564929},
+  {-0.553234,0.469098},
+  {-1.455098,-0.185264},
+  {0.800772,0.396759},
+  {-1.234805,0.736313},
+  {0.761554,-0.175533},
+  {-0.650272,-1.001478},
+  {0.515606,-0.160728},
+  {1.523529,0.422419},
+  {0.327472,0.391494},
+  {0.747341,0.126178},
+  {0.796575,0.604781},
+  {-0.579325,0.723723},
+  {0.188695,-0.270173},
+  {0.608637,-0.176246},
+  {0.357106,-0.187142},
+  {-0.476938,0.579994},
+  {-0.159003,-0.546717},
+  {0.805633,0.436189},
+  {-0.000267,-0.078362},
+  {0.388497,0.613782},
+  {-0.616919,0.325909},
+  {-0.139824,0.506477},
+  {-0.357327,-0.352587},
+  {0.465315,0.517060},
+  {-0.402298,0.401676},
+  {-1.052840,1.068351},
+  {0.089254,-0.088566},
+  {1.553712,-0.490081},
+  {0.796169,0.313496},
+  {0.221044,0.079029},
+  {0.735658,0.515442},
+  {0.088796,-0.414440},
+  {0.177135,0.018821},
+  {-0.136482,0.116556},
+  {0.998341,1.750061},
+  {1.539176,-0.444703},
+  {-0.005825,-1.174685},
+  {-0.546142,-1.060067},
+  {-0.238276,-0.411240},
+  {1.270839,1.815292},
+  {0.238926,-0.014318},
+  {-0.433391,1.175325},
+  {0.365434,0.514461},
+  {0.549538,-0.875982},
+  {-0.052031,0.088336},
+  {0.056105,0.755373},
+  {-0.739169,1.345512},
+  {0.022259,0.310272},
+  {-0.143530,0.226380},
+  {0.377260,-2.217078},
+  {1.266910,0.770192},
+  {-1.430207,-0.389470},
+  {0.373033,0.954533},
+  {-0.032998,0.458503},
+  {0.033109,0.876798},
+  {1.254053,-0.868324},
+  {-0.750205,-1.243251},
+  {0.178780,-0.059218},
+  {-0.138437,-1.864862},
+  {-0.057342,0.724688},
+  {0.255896,1.443441},
+  {0.554522,-0.149032},
+  {0.535395,0.518631},
+  {0.178084,-1.333335},
+  {-1.146268,-0.525930},
+  {-0.444915,-0.179534},
+  {-1.827258,0.610506},
+  {-0.970571,0.433014},
+  {-0.851848,-1.408017},
+  {-0.010547,0.425406},
+  {-0.438689,-0.641632},
+  {0.982537,0.523425},
+  {0.194053,0.040519},
+  {-2.164144,-0.712796},
+  {-0.286878,-1.289071},
+  {-1.189324,0.191043},
+  {-0.178947,0.227410},
+  {0.543007,-0.209633},
+  {-0.504561,0.558697},
+  {-0.476418,-0.360136},
+  {-0.066349,0.311321},
+  {0.205228,0.537992},
+  {-0.431381,0.691561},
+  {0.373215,-0.698683},
+  {-0.021947,-0.774605},
+  {0.587365,-1.799103},
+  {0.808319,-0.623221},
+  {1.089104,0.969406},
+  {-0.309144,0.148429},
+  {-0.370805,0.696824},
+  {0.232746,0.498690},
+  {0.207694,0.370303},
+  {-0.921240,-1.399620},
+  {-0.553996,0.380382},
+  {-0.578575,0.448331},
+  {0.429058,-0.213727},
+  {-0.710646,-0.159683},
+  {1.620601,0.839856},
+  {-0.118776,0.365243},
+  {1.473897,0.572852},
+  {0.186774,0.121951},
+  {0.610082,-0.416502},
+  {-0.680911,0.926587},
+  {-0.677998,0.322929},
+  {0.386026,0.195354},
+  {0.127726,0.580091},
+  {0.103026,-0.655300},
+  {-0.285589,0.668215},
+  {-0.304495,0.862677},
+  {0.676639,-0.908045},
+  {-0.101844,-1.374433},
+  {0.111932,-0.315504},
+  {-0.786232,0.096354},
+  {0.412804,1.171453},
+  {0.242855,0.419671},
+  {-1.122453,0.072119},
+  {-0.954008,-1.360665},
+  {0.490884,-0.394485},
+  {1.407058,-0.197984},
+  {0.516526,-0.041076},
+  {-0.356944,0.119194},
+  {0.114765,-0.432646},
+  {-0.616070,-0.812770},
+  {-1.283144,0.352879},
+  {-0.675260,0.248547},
+  {0.037469,0.111532},
+  {1.808690,0.215876},
+  {-0.262605,0.390434},
+  {-0.528473,-0.590598},
+  {0.067823,1.025179},
+  {-0.134779,0.388853},
+  {-0.856184,-0.137929},
+  {-1.322880,-0.587829},
+  {0.255339,0.957455},
+  {0.691181,0.120283},
+  {-0.138113,-0.681550},
+  {-0.839258,-0.647184},
+  {0.717937,-0.342172},
+  {-0.002496,0.085833},
+  {0.066570,0.376295},
+  {-1.184694,-0.306608},
+  {-0.765986,-0.240214},
+  {-1.484250,-0.148429},
+  {-0.381439,1.124766},
+  {-0.350007,0.336370},
+  {0.235697,-1.183933},
+  {1.443619,0.581121},
+  {0.491068,-0.099921},
+  {0.093451,0.902716},
+  {0.505893,1.686718},
+  {-0.385501,-1.017724},
+  {-0.541630,0.466243},
+  {0.186522,-0.926013},
+  {-0.447201,-0.317000},
+  {-0.142966,-1.103298},
+  {0.144505,-0.006342},
+  {1.660683,-0.528652},
+  {-0.863812,-0.656971},
+  {0.373327,-0.447680},
+  {0.064399,-0.006573},
+  {0.273959,-0.067186},
+  {0.158321,-0.040345},
+  {-0.809976,1.524938},
+  {0.265150,0.968352},
+  {-0.561451,0.122076},
+  {-0.238906,0.602495},
+  {-0.682023,-1.518610},
+  {0.226352,0.239321},
+  {0.249679,-0.450287},
+  {1.424126,-0.421314},
+  {0.347601,-1.256083},
+  {-0.161817,-0.558341},
+  {-0.698010,1.392321},
+  {0.854525,-0.180275},
+  {-0.607136,-0.163008},
+  {-0.201352,-0.463324},
+  {0.177265,0.445976},
+  {-1.139061,-0.711736},
+  {0.071346,0.954147},
+  {-0.007381,-0.234975},
+  {0.122223,0.301816},
+  {0.744879,-0.147205},
+  {0.885961,0.569310},
+  {-0.584466,0.194479},
+  {-0.356190,-0.486432},
+  {-0.604637,0.312954},
+  {-0.571192,0.009307},
+  {-1.645607,-1.013357},
+  {0.767907,0.911892},
+  {-0.292811,-0.436490},
+  {0.754294,-0.258061},
+  {-0.020915,-0.553060},
+  {0.513940,0.367752},
+  {-0.039909,-0.308901},
+  {-0.426255,-0.427997},
+  {0.031096,-0.350317},
+  {0.183359,0.337084},
+  {-1.442484,0.931023},
+  {0.285229,0.747264},
+  {1.284922,-0.542352},
+  {-0.580213,-0.744180},
+  {-1.258930,1.722668},
+  {-0.259699,-0.002504},
+  {0.488400,0.053418},
+  {0.626716,-0.067078},
+  {-0.262059,-0.661936},
+  {-0.826681,1.076488},
+  {-0.313348,0.452737},
+  {0.751086,-0.240226},
+  {-0.201071,-0.293798},
+  {0.498236,0.533344},
+  {0.445915,-0.498216},
+  {-0.476964,-0.992134},
+  {0.124767,0.528058},
+  {-0.175549,0.108257},
+  {-0.983469,1.220194},
+  {-1.365000,0.620389},
+  {0.126352,1.586583},
+  {0.698377,-0.366504},
+  {-0.972605,-0.070712},
+  {-0.173680,0.387337},
+  {-1.296066,-0.326749},
+  {0.074632,1.409292},
+  {0.273771,0.567147},
+  {1.247218,0.334758},
+  {0.109021,0.319268},
+  {0.782710,0.115378},
+  {0.481173,-0.827708},
+  {-0.539717,-0.877906},
+  {0.746934,1.005647},
+  {-0.621987,0.129283},
+  {0.413268,0.131652},
+  {-1.265124,0.249034},
+  {-0.352113,0.553744},
+  {0.639651,-0.490536},
+  {-0.207383,-0.516105},
+  {0.300740,0.271305},
+  {-0.778036,-0.864931},
+  {0.237860,-0.011126},
+  {0.147210,0.427180},
+  {-0.038382,1.535662},
+  {-1.191819,0.386445},
+  {0.553605,0.469841},
+  {0.060159,0.320722},
+  {0.628356,0.798504},
+  {0.141494,0.747546},
+  {0.356586,-0.813978},
+  {-0.526579,0.129332},
+  {-0.142047,-0.183652},
+  {0.142306,-1.230296},
+  {0.163303,0.973984},
+  {0.741797,-0.963034},
+  {-0.953978,1.630063},
+  {0.782292,0.927006},
+  {0.269555,-0.483264},
+  {-0.225813,-0.846876},
+  {-0.147398,0.037824},
+  {-1.151203,0.182452},
+  {-0.051871,1.116905},
+  {0.618385,0.772501},
+  {-0.806309,-0.676225},
+  {0.314484,0.962604},
+  {-0.877810,0.165547},
+  {-0.278775,0.828332},
+  {-0.193032,0.607956},
+  {0.481850,0.406728},
+  {0.189260,0.564026},
+  {0.101573,-0.153646},
+  {0.141078,0.577827},
+  {0.442071,-0.654711},
+  {-0.497890,-0.069597},
+  {-0.896127,0.092677},
+  {1.379386,-1.739856},
+  {0.049072,0.076701},
+  {-0.000871,-0.137247},
+  {-1.069033,1.216272},
+  {1.305900,-1.105981},
+  {-0.038746,0.948692},
+  {0.097514,-0.182169},
+  {0.504969,0.301159},
+  {-0.070645,-0.338149},
+  {-0.648749,1.116034},
+  {0.019086,0.366446},
+  {0.061191,-0.513735},
+  {-0.412078,0.343295},
+  {-1.006799,-0.785297},
+  {0.728767,-0.194047},
+  {-0.294156,0.632371},
+  {-0.674312,-1.092083},
+  {-0.662882,-0.689872},
+  {-1.090220,-0.610777},
+  {0.103421,0.205088},
+  {0.654995,-0.196212},
+  {0.811050,-1.173118},
+  {0.047948,0.235323},
+  {0.657132,0.634237},
+  {0.807551,0.684801},
+  {0.066354,-0.968132},
+  {-0.109448,-0.718459},
+  {-1.570057,0.383556},
+  {1.177749,-0.333918},
+  {-0.076754,-0.018363},
+  {1.147423,0.535147},
+  {-1.099482,-1.047722},
+  {0.202256,0.611263},
+  {0.355965,0.186135},
+  {0.638869,0.248176},
+  {0.423701,0.167180},
+  {0.140065,-1.046322},
+  {-0.128061,0.389472},
+  {-0.073327,-0.620858},
+  {0.551739,-0.001060},
+  {-0.010351,-0.343739},
+  {0.273292,0.077655},
+  {0.018582,-0.649334},
+  {0.858083,-0.239483},
+  {0.434152,-0.516887},
+  {-1.191059,0.970440},
+  {-1.078976,-1.186674},
+  {1.220491,0.830858},
+  {0.392834,-0.620787},
+  {0.570976,1.188011},
+  {0.659424,-0.514683},
+  {0.396493,0.413003},
+  {1.064244,-1.299914},
+  {-0.395576,-0.151052},
+  {-1.016292,-0.124868},
+  {0.339642,0.187616},
+  {-0.732745,0.330348},
+  {0.064742,0.443943},
+  {0.986493,-0.439466},
+  {0.469584,-0.447904},
+  {0.721960,0.754263},
+  {0.157520,-0.324514},
+  {-0.114010,-0.285823},
+  {-0.771222,-0.402135},
+  {0.327920,0.786586},
+  {-0.761432,-0.278662},
+  {0.019400,-0.367941},
+  {1.070777,0.601845},
+  {0.456113,-0.819699},
+  {0.879266,-1.927595},
+  {0.205047,-0.103213},
+  {0.499241,0.410470},
+  {0.833646,-1.356775},
+  {0.148523,0.231443},
+  {0.561257,-0.947881},
+  {0.003637,-0.389497},
+  {0.433277,0.984572},
+  {-0.048365,-0.418898},
+  {-0.136111,-1.207308},
+  {1.922850,1.447618},
+  {0.384710,0.640459},
+  {0.139125,0.130501},
+  {0.571578,-0.186558},
+  {0.682121,0.751595},
+  {0.321521,-1.559149},
+  {-0.371364,-0.545437},
+  {0.621527,0.318470},
+  {-0.035350,0.128997},
+  {0.478967,0.282489},
+  {-1.726296,0.075075},
+  {-0.410562,-0.229728},
+  {0.248913,0.103229},
+  {-1.158596,0.232259},
+  {0.162925,0.185782},
+  {0.954972,-0.172445},
+  {-1.023235,-0.827372},
+  {0.386385,0.418922},
+  {-1.535752,-0.171385},
+  {-0.052104,0.779521},
+  {0.578034,-0.561471},
+  {0.132959,0.311450},
+  {-0.343702,-0.401046},
+  {0.245350,0.969726},
+  {0.396674,0.108288},
+  {-1.432259,0.419970},
+  {0.341158,0.317464},
+  {-0.330617,-0.606965},
+  {-0.152268,-0.472867},
+  {-0.060637,0.458003},
+  {-0.571015,-0.285286},
+  {-0.689380,-0.890630},
+  {1.280908,0.748947},
+  {-0.541963,0.307449},
+  {1.509660,0.796404},
+  {1.759599,-0.190714},
+  {0.431596,-0.064444},
+  {0.781975,-0.726109},
+  {-0.225672,-0.453357},
+  {-1.213446,0.029801},
+  {-0.502440,0.933800},
+  {0.526578,0.291420},
+  {0.147412,0.134833},
+  {0.512102,0.625511},
+  {1.456875,1.380586},
+  {-0.290328,-1.063807},
+  {0.101380,-0.817843},
+  {0.113163,0.126724},
+  {1.215953,0.725106},
+  {0.201676,0.845303},
+  {0.239325,-0.398681},
+  {0.164998,-0.338345},
+  {-0.108562,-0.506582},
+  {-0.489327,0.543874},
+  {0.661906,-0.354970},
+  {-0.265596,0.563607},
+  {-0.884218,0.854292},
+  {1.321217,-1.368510},
+  {0.081827,-1.410110},
+  {-0.219351,0.885236},
+  {-0.982823,0.858992},
+  {-1.274274,-1.011328},
+  {-1.067975,0.067140},
+  {0.436583,-0.052909},
+  {-0.404171,-0.153187},
+  {-0.582062,0.600456},
+  {0.023155,0.627493},
+  {-0.685279,-0.017384},
+  {0.548277,-0.244152},
+  {-0.115240,0.053806},
+  {0.060231,0.740503},
+  {-0.145329,0.863530},
+  {-1.448378,0.298489},
+  {0.240402,-0.369060},
+  {1.430967,1.095404},
+  {0.331176,0.532789},
+  {0.065128,0.165151},
+  {-0.301511,-0.764322},
+  {1.104458,0.230971},
+  {-0.659759,-0.691340},
+  {-0.814781,-0.814180},
+  {0.417795,1.175324},
+  {0.289451,0.400148},
+  {-0.418076,0.131680},
+  {-1.362387,0.205250},
+  {-0.014391,0.377274},
+  {-1.409865,-1.379234},
+  {0.541087,1.912687},
+  {-0.029290,-0.841498},
+  {0.466166,0.092614},
+  {0.184014,-0.060701},
+  {0.809956,1.648975},
+  {-0.773957,0.556490},
+  {-0.526512,-0.408391},
+  {0.241741,0.658692},
+  {-0.542720,1.687133},
+  {-0.516997,-0.467089},
+  {0.739354,0.421007},
+  {-0.042296,-0.146626},
+  {-0.269594,-0.550475},
+  {-1.523314,-1.306939},
+  {0.250566,0.617745},
+  {0.504463,-0.722584},
+  {-0.179117,-0.083309},
+  {1.874666,0.664473},
+  {0.786372,-0.183692},
+  {-0.791371,-0.105155},
+  {0.546627,-0.378284},
+  {-0.682557,0.353458},
+  {-1.551750,-1.178922},
+  {0.004591,-0.364755},
+  {0.595242,-0.129436},
+  {-0.525592,-0.317380},
+  {-0.090858,-0.976245},
+  {-0.485468,0.291478},
+  {0.149195,0.432197},
+  {-0.614205,-0.776327},
+  {-0.282117,0.839998},
+  {-0.805384,-0.020502},
+  {0.822789,-1.368598},
+  {-0.626826,0.998920},
+  {0.496481,-0.497299},
+  {1.668775,0.382570},
+  {0.548438,-1.033250},
+  {1.007271,0.933075},
+  {0.183149,-0.380990},
+  {1.293787,-0.119620},
+  {0.774773,0.143392},
+  {-0.274284,-0.302211},
+  {0.451132,-0.154428},
+  {-0.025212,0.110100},
+  {-1.359157,0.348165},
+  {0.013577,0.207362},
+  {1.101108,1.741819},
+  {-1.147832,-0.970628},
+  {-0.792563,-0.451914},
+  {-0.065555,0.248664},
+  {-1.252769,0.225012},
+  {0.954973,-1.085338},
+  {0.121842,-0.845815},
+  {-1.622493,0.134620},
+  {-0.785575,-1.165826},
+  {-0.155585,-0.299899},
+  {0.204921,1.247232},
+  {0.190846,0.982351},
+  {-0.086519,0.188154},
+  {0.911527,-0.410064},
+  {-0.589303,0.001458},
+  {-0.461175,-0.753628},
+  {-0.703909,-0.266743},
+  {-0.552377,-0.836142},
+  {-0.316481,-0.804232},
+  {-1.208979,-0.807974},
+  {-0.405595,-0.324402},
+  {0.556275,0.511671},
+  {0.755633,-0.192398},
+  {0.361233,-0.288166},
+  {-0.271475,-0.290048},
+  {0.036496,1.048269},
+  {-0.230503,0.604447},
+  {1.000254,-0.234682},
+  {0.120851,-0.393787},
+  {-1.135812,-0.005555},
+  {0.117785,0.102412},
+  {0.269803,0.306705},
+  {-1.000569,-0.211454},
+  {-0.921295,-0.318864},
+  {0.015830,-0.276718},
+  {0.855560,0.052771},
+  {-0.331353,0.532554},
+  {-0.998449,-0.148572},
+  {1.087764,1.700836},
+  {-0.433519,1.028843},
+  {0.238422,-0.076953},
+  {-0.789252,-0.068322},
+  {0.231041,0.257196},
+  {-0.119942,0.994053},
+  {-1.624463,0.592305},
+  {0.489505,0.330256},
+  {-0.791727,-0.240149},
+  {0.023486,0.405492},
+  {-0.712725,1.139520},
+  {-0.397841,0.392477},
+  {-0.172113,-0.103673},
+  {-0.916898,-0.115494},
+  {-0.740514,-0.159728},
+  {0.030016,0.438515},
+  {-0.189621,0.505697},
+  {-0.312361,-0.485750},
+  {0.395219,-0.191466},
+  {-0.681995,0.910094},
+  {-0.886425,0.038644},
+  {-0.363377,0.254644},
+  {1.213012,0.273619},
+  {0.387538,-0.267483},
+  {0.184534,-0.031493},
+  {-0.082584,0.185597},
+  {-0.168003,-1.103117},
+  {-0.130390,0.133329},
+  {-0.641604,-1.152805},
+  {0.930567,0.868625},
+  {-0.667303,0.040410},
+  {0.885582,-0.805815},
+  {1.203275,0.842920},
+  {-1.398472,-0.587075},
+  {-1.319309,-0.535182},
+  {0.187520,0.267047},
+  {1.366326,0.361960},
+  {0.099778,-0.157978},
+  {-0.133780,-0.185177},
+  {0.536479,-0.703430},
+  {-1.744925,0.483704},
+  {-0.188968,-0.117653},
+  {0.100862,-0.201597},
+  {1.112205,0.886361},
+  {1.065932,0.187435},
+  {-0.515742,-1.160125},
+  {-0.302570,0.686457},
+  {0.650096,-0.027069},
+  {-0.038160,1.315195},
+  {0.325478,-0.873972},
+  {-1.071418,0.172045},
+  {0.086233,-0.410727},
+  {0.062731,0.419938},
+  {-0.067950,0.160374},
+  {-0.871875,-0.789548},
+  {-0.533510,0.417835},
+  {0.549437,-0.061798},
+  {0.230347,0.244062},
+  {-0.664741,-0.647699},
+  {0.866195,-0.509121},
+  {-0.455236,-1.065637},
+  {-0.098402,-0.964385},
+  {0.972477,0.831164},
+  {1.126182,1.212522},
+  {-1.214912,-0.489044},
+  {-0.145521,-0.082823},
+  {0.172649,0.507886},
+  {0.816966,0.723179},
+  {0.286767,0.813230},
+  {-0.292067,0.442358},
+  {-0.242028,0.403211},
+  {0.810219,-0.296835},
+  {-0.965484,0.781090},
+  {0.030609,1.430429},
+  {-0.113167,-0.735173},
+  {0.679344,0.038494},
+  {-0.296711,1.173452},
+  {0.205363,0.307279},
+  {0.236531,-0.902335},
+  {1.474420,1.009479},
+  {-0.794636,-1.088974},
+  {-0.600780,-0.630495},
+  {-0.120746,0.153255},
+  {-0.074198,-1.159780},
+  {0.479216,-0.756744},
+  {-0.061359,-0.464196},
+  {0.266948,0.499785},
+  {0.466252,-0.801677},
+  {-0.739398,-1.104281},
+  {-0.209888,0.342897},
+  {0.317751,0.652312},
+  {-0.108828,-0.502183},
+  {0.311654,-0.272723},
+  {-1.213448,0.887512},
+  {-0.156897,0.247416},
+  {0.684845,0.663784},
+  {-0.834150,-1.557275},
+  {-0.111679,-0.539638},
+  {-0.629201,-0.244997},
+  {0.345529,-0.729459},
+  {-0.573635,0.569731},
+  {0.202781,1.168916},
+  {0.299240,0.698863},
+  {-0.303744,0.092127},
+  {-0.770121,-0.010426},
+  {0.785242,-0.473798},
+  {-0.258107,-1.614886},
+  {-0.364306,0.445393},
+  {-0.030830,-0.396489},
+  {-0.861569,-0.618809},
+  {-0.467142,-0.065045},
+  {1.496496,0.390095},
+  {-0.664346,-0.666512},
+  {-1.078531,-0.683208},
+  {-1.035570,0.332805},
+  {0.334032,0.923234},
+  {-0.352618,1.163516},
+  {0.487088,0.813483},
+  {-0.108438,0.111755},
+  {-0.242763,-0.716151},
+  {0.048218,-0.411570},
+  {-0.682291,-0.100047},
+  {-0.347302,-0.541596},
+  {-0.055860,0.329776},
+  {-0.486827,0.763519},
+  {0.936834,0.378179},
+  {0.560789,-0.581682},
+  {0.062925,-1.147451},
+  {0.370209,0.604113},
+  {0.303006,0.781933},
+  {-0.771395,1.640898},
+  {0.367795,-0.936096},
+  {-0.948469,-0.645591},
+  {-1.338969,0.458720},
+  {-0.119671,0.943494},
+  {-0.504578,1.348833},
+  {0.087662,0.180008},
+  {-0.400353,-0.940478},
+  {-1.020622,0.010305},
+  {-0.572008,0.916672},
+  {0.777239,-0.920403},
+  {-0.246385,-1.900782},
+  {0.368677,-0.397907},
+  {-0.213803,1.423726},
+  {-0.529380,0.287280},
+  {0.674833,0.865517},
+  {0.214032,0.083444},
+  {-1.354788,0.121986},
+  {-0.147398,-0.259880},
+  {-0.236661,0.083370},
+  {1.070576,-0.674437},
+  {-1.696654,-0.863431},
+  {-0.288571,-0.088433},
+  {-1.178608,0.352638},
+  {-0.686168,-0.664879},
+  {-0.727181,0.139968},
+  {0.704379,0.011108},
+  {-0.097122,-0.414411},
+  {0.833092,-0.416375},
+  {1.679856,-0.186026},
+  {-0.188038,-0.789648},
+  {0.788024,1.319672},
+  {-0.111910,-0.429271},
+  {0.026979,-0.973063},
+  {-0.822299,-0.468297},
+  {-0.020743,-0.075185},
+  {-0.196015,-0.653514},
+  {-0.531606,0.126889},
+  {0.683125,0.196602},
+  {-0.642640,-1.115938},
+  {0.216297,0.501497},
+  {-0.798830,-0.596719},
+  {0.118774,-0.356140},
+  {-1.144614,-0.125928},
+  {0.782631,0.924172},
+  {-1.170188,-0.199186},
+  {-1.219077,1.060124},
+  {-0.426246,0.782024},
+  {0.022011,1.753737},
+  {-1.176024,1.096339},
+  {0.892655,0.511964},
+  {0.162166,0.613459},
+  {0.089108,0.600362},
+  {0.727923,0.549506},
+  {0.043496,-0.772287},
+  {0.545886,-1.494124},
+  {-0.208190,-0.121938},
+  {0.457878,-0.436767},
+  {0.202868,1.137949},
+  {0.442543,-0.970062},
+  {-0.938356,0.524556},
+  {-0.206104,-0.650013},
+  {-0.241362,-0.130104},
+  {0.825974,0.375147},
+  {-1.030467,0.349799},
+  {0.165765,0.053764},
+  {0.539089,0.219063},
+  {-0.920803,-0.360764},
+  {-1.501808,0.467059},
+  {0.010156,-0.026508},
+  {0.296985,1.309064},
+  {0.255845,0.369301},
+  {0.282236,0.181767},
+  {-0.599911,0.417191},
+  {-0.124009,-0.052300},
+  {1.762523,-0.638097},
+  {1.559969,-0.392161},
+  {0.788940,-1.012021},
+  {-0.889773,0.829916},
+  {-0.758505,0.629368},
+  {0.149425,0.205740},
+  {-1.489133,0.519999},
+  {0.274081,-0.473210},
+  {-0.400278,-0.605729},
+  {-0.034848,-0.711428},
+  {0.797203,0.653726},
+  {0.684081,0.306657},
+  {-0.898558,0.487512},
+  {0.531034,-0.804407},
+  {-0.189209,0.079728},
+  {-0.236203,0.887653},
+  {-1.055849,-0.030049},
+  {0.157577,0.262297},
+  {0.816064,0.614824},
+  {-0.517684,-0.651690},
+  {0.817597,0.142859},
+  {0.632049,0.746048},
+  {-0.004080,-0.044616},
+  {-0.443800,-0.623657},
+  {-1.950154,0.292959},
+  {0.849712,0.756986},
+  {-0.331359,0.267557},
+  {0.110510,0.822703},
+  {1.123170,-0.844141},
+  {-0.779840,0.699576},
+  {0.039398,0.256364},
+  {0.701604,-1.071505},
+  {0.068249,-0.334658},
+  {-0.092711,-0.747982},
+  {0.279999,0.476331},
+  {-0.250376,-0.152404},
+  {-0.633183,-0.303464},
+  {-0.871779,-0.289203},
+  {0.520590,0.441538},
+  {0.411185,0.050415},
+  {0.299688,0.061898},
+  {0.006655,0.250882},
+  {0.663987,-0.250278},
+  {-0.435304,0.428809},
+  {-0.954020,0.275075},
+  {-0.534693,-0.019677},
+  {-0.454147,-0.287202},
+  {-0.410159,0.876545},
+  {0.167473,0.702159},
+  {-0.798929,-0.035521},
+  {0.321676,0.347692},
+  {0.817898,0.460273},
+  {-0.129380,0.029044},
+  {0.252003,-0.312483},
+  {-0.794911,2.260189},
+  {1.196671,-0.508444},
+  {0.658018,0.454661},
+  {-0.110961,1.988064},
+  {1.027958,-0.139970},
+  {0.371965,0.512944},
+  {-0.889717,-0.561569},
+  {-0.385539,1.492987},
+  {0.182554,-0.293347},
+  {-0.678913,-0.180265},
+  {-0.619095,0.804020},
+  {-0.246786,0.065080},
+  {0.732415,0.287005},
+  {-0.433814,0.359104},
+  {-1.062615,0.398734},
+  {-0.068996,-0.161415},
+  {0.177600,-0.169124},
+  {-1.098818,0.257113},
+  {-0.199506,-0.234330},
+  {-0.457931,-0.929827},
+  {1.267319,-0.665283},
+  {0.569162,0.128109},
+  {-0.894920,-0.343725},
+  {-1.047250,0.194854},
+  {0.145325,1.000184},
+  {-0.485785,0.176002},
+  {0.416958,0.181212},
+  {-0.538063,1.408044},
+  {0.396945,0.376793},
+  {-0.650388,0.600960},
+  {-0.336692,0.041523},
+  {0.762633,0.056195},
+  {-0.101801,1.060078},
+  {0.008753,0.341367},
+  {1.213057,0.650804},
+  {-0.242555,0.605359},
+  {-0.096545,0.505888},
+  {-0.218160,0.065450},
+  {-0.392291,-0.153585},
+  {-0.382276,-0.435595},
+  {-0.566462,0.503745},
+  {0.742303,0.092767},
+  {-0.706119,-0.446348},
+  {0.846034,-0.169926},
+  {-0.800204,0.067673},
+  {0.393443,-0.252153},
+  {-1.189230,-0.417032},
+  {-0.258718,-0.577801},
+  {0.148415,-0.218861},
+  {-0.242399,-0.722251},
+  {-0.554846,0.266552},
+  {-0.154566,0.345374},
+  {-0.178620,-0.620674},
+  {-1.452684,0.547125},
+  {0.742394,-0.579851},
+  {-0.535252,0.818573},
+  {-0.373753,-0.844847},
+  {-0.307951,-0.485154},
+  {-1.055151,-0.234469},
+  {-0.617500,0.155782},
+  {-0.632949,-0.514511},
+  {0.321217,-0.177787},
+  {0.810575,0.867079},
+  {-0.739780,0.080659},
+  {-0.702951,-0.542686},
+  {-0.849406,-0.434737},
+  {-0.107667,1.546333},
+  {-0.481642,0.249243},
+  {-0.434692,0.925578},
+  {-0.649042,0.190168},
+  {0.543056,0.387398},
+  {0.229006,1.749723},
+  {-0.659196,1.496811},
+  {-1.112472,-1.378348},
+  {-0.347713,0.655806},
+  {-0.333020,-0.442177},
+  {-0.010896,0.243385},
+  {0.396435,-0.937387},
+  {-1.542977,-0.081353},
+  {-0.988957,-1.301314},
+  {-0.671717,0.385106},
+  {-0.475757,-0.051430},
+  {-0.152665,-0.430897},
+  {0.226653,-1.286005},
+  {-0.121291,-0.593614},
+  {-0.416353,0.289417},
+  {0.641212,-0.014396},
+  {0.625740,0.289628},
+  {0.109355,-0.864110},
+  {-1.304982,0.864331},
+  {0.540706,-0.034820},
+  {1.160577,0.426277},
+  {0.897177,0.120431},
+  {0.166315,0.025191},
+  {-1.194892,-0.817293},
+  {-0.018821,-0.365376},
+  {0.419874,-0.904719},
+  {-0.376988,1.270798},
+  {0.591134,-0.413071},
+  {0.765301,0.183033},
+  {0.425363,-2.200343},
+  {0.282538,-0.115302},
+  {0.471367,-0.189218},
+  {0.072332,-1.738241},
+  {0.705167,1.306461},
+  {0.517418,-0.123308},
+  {0.665696,0.768678},
+  {0.799159,0.744041},
+  {0.388496,0.054943},
+  {-0.509369,-0.466480},
+  {-0.932773,-0.129384},
+  {-1.766512,0.342952},
+  {-0.411573,-0.953764},
+  {-0.376695,-0.388200},
+  {0.253429,0.762383},
+  {-0.238802,-0.837494},
+  {-0.568870,0.170795},
+  {0.970388,1.303336},
+  {-0.483732,-0.759695},
+  {-0.067874,-0.877486},
+  {0.361803,-0.828496},
+  {0.148481,-0.631609},
+  {0.188760,0.682836},
+  {0.233787,1.072984},
+  {0.607324,0.052559},
+  {-0.462668,-0.875849},
+  {0.513511,-0.625931},
+  {0.029210,-0.447513},
+  {0.480831,0.480287},
+  {-0.664907,-0.973077},
+  {0.188319,-1.203828},
+  {0.022725,-0.215416},
+  {-0.426508,0.568704},
+  {0.696166,-0.153401},
+  {-0.888605,0.283359},
+  {-1.887684,-0.631214},
+  {-0.027258,-0.755818},
+  {0.463172,0.099262},
+  {0.176597,0.408871},
+  {0.139626,0.475139},
+  {-0.512137,-0.095797},
+  {0.142498,0.791082},
+  {1.714745,0.050486},
+  {-0.151700,1.001408},
+  {-0.187926,-1.189337},
+  {-1.047952,0.351206},
+  {-0.605363,0.923878},
+  {-0.880344,-0.236752},
+  {0.158545,0.536012},
+  {-0.702132,-0.383830},
+  {-0.232765,-0.434727},
+  {-0.332018,0.111265},
+  {-0.115645,1.224794},
+  {1.130556,1.039947},
+  {-0.684674,0.389432},
+  {-0.495957,-0.819223},
+  {-0.287520,0.044088},
+  {-0.120997,-0.373808},
+  {0.344498,-0.861474},
+  {-0.287849,-0.627099},
+  {-1.624836,1.107974},
+  {-0.161896,0.734496},
+  {0.922077,0.415761},
+  {-0.092261,-0.792858},
+  {0.740678,0.637053},
+  {0.009040,-1.221702},
+  {-0.151925,-1.520832},
+  {-0.926963,1.228550},
+  {1.592761,-0.740545},
+  {0.975686,-0.204006},
+  {-0.510445,-0.013318},
+  {-0.116722,-1.460534},
+  {0.050564,-0.696307},
+  {0.238704,-0.306242},
+  {-0.056267,-0.039088},
+  {0.367015,0.155718},
+  {0.828479,0.364074},
+  {-0.066791,-0.263206},
+  {-0.206769,-0.176020},
+  {0.607347,-0.204373},
+  {-0.328140,0.234530},
+  {-0.149728,0.964312},
+  {-0.673761,-0.476774},
+  {-0.531880,1.004618},
+  {-0.115795,-0.702836},
+  {0.150798,-1.577178},
+  {-0.261606,-0.115086},
+  {-0.466822,-0.540959},
+  {0.188110,-0.368671},
+  {1.054299,0.152076},
+  {0.955712,-0.861367},
+  {-0.203463,1.366727},
+  {0.633374,0.651992},
+  {-1.391364,0.818343},
+  {0.956846,1.464320},
+  {-0.393481,0.977886},
+  {0.069476,1.092029},
+  {-0.819219,0.095735},
+  {-0.358142,-0.433980},
+  {0.880563,0.408356},
+  {-0.110838,0.733042},
+  {0.767039,0.273039},
+  {0.484175,1.024151},
+  {0.506067,-0.462739},
+  {0.138992,0.524270},
+  {0.438017,-0.334267},
+  {-0.480006,-1.227354},
+  {-0.549142,0.321805},
+  {0.558154,0.085036},
+  {-1.561828,1.403826},
+  {0.792447,-1.514236},
+  {0.340796,0.383640},
+  {-1.368843,-0.478391},
+  {0.058797,0.152301},
+  {-1.186850,0.309630},
+  {0.008511,0.569976},
+  {0.499503,0.907362},
+  {-0.582328,-1.193703},
+  {0.457649,0.390902},
+  {0.080038,0.404945},
+  {0.509056,-1.101939},
+  {-0.172094,0.524935},
+  {-0.856769,-1.342524},
+  {0.600361,0.564700},
+  {0.669194,-0.792939},
+  {1.645031,-1.295386},
+  {-0.563368,-1.044735},
+  {1.573442,0.369752},
+  {-0.476873,1.693162},
+  {0.009118,-0.394260},
+  {-1.892748,0.376392},
+  {0.527800,0.693088},
+  {0.174069,1.074548},
+  {0.421630,-0.272748},
+  {-0.328084,0.643263},
+  {-1.074268,-0.336496},
+  {1.380511,-0.549909},
+  {0.446078,-0.836703},
+  {0.094413,0.555130},
+  {2.359104,0.198856},
+  {-0.171100,1.095922},
+  {0.554416,-0.723893},
+  {-1.692759,-0.111848},
+  {-0.968574,-0.811231},
+  {-1.243309,-0.641704},
+  {0.374876,-0.441376},
+  {-0.298878,0.934476},
+  {0.959066,0.185512},
+  {-0.372387,0.626353},
+  {-0.200447,0.974171},
+  {-0.656902,-0.411072},
+  {0.606477,0.609449},
+  {0.596347,-0.335998},
+  {-0.680908,-0.373738},
+  {-0.714886,-0.319760},
+  {-1.232879,-0.543364},
+  {0.597159,0.750747},
+  {-0.092650,0.649143},
+  {1.312315,0.577498},
+  {0.949531,0.577766},
+  {-0.536287,-0.256933},
+  {0.026927,0.209819},
+  {-0.506280,0.975751},
+  {-0.100592,-0.496428},
+  {0.703664,0.977937},
+  {0.439077,0.642939},
+  {-1.186330,-0.562701},
+  {0.834602,-0.346392},
+  {-1.140063,1.278697},
+  {-0.176394,-0.177266},
+  {-1.911734,-0.158996},
+  {-0.938247,-1.139427},
+  {0.430852,-0.519788},
+  {0.552453,0.347402},
+  {0.397558,-0.621711},
+  {0.395750,-0.030026},
+  {-0.318682,0.526152},
+  {-0.086843,0.198691},
+  {-0.463806,1.322882},
+  {0.021087,0.405731},
+  {-0.997044,-0.774766},
+  {-0.693620,0.425756},
+  {-0.093692,0.639838},
+  {0.605591,0.305130},
+  {-1.280314,0.984296},
+  {-0.058598,-1.163590},
+  {0.649775,-0.003839},
+  {-0.268283,0.754608},
+  {-1.297487,0.615832},
+  {0.619815,-0.088227},
+  {-0.447024,0.734463},
+  {0.342713,0.254090},
+  {-0.076577,1.067338},
+  {-0.580665,-0.362452},
+  {0.233286,-0.620338},
+  {-0.934433,0.379823},
+  {0.933342,0.231465},
+  {-0.859952,0.114437},
+  {-0.856929,0.585641},
+  {-0.943033,-0.113384},
+  {1.038475,0.201911},
+  {-0.469030,-0.388884},
+  {-0.118337,-0.297191},
+  {-0.702286,-0.240531},
+  {-0.513404,-0.591197},
+  {0.324736,0.499129},
+  {0.131897,-0.425180},
+  {-0.464172,1.168790},
+  {-0.606129,0.482431},
+  {-0.947150,-0.266069},
+  {0.443681,-1.910554},
+  {-0.022401,-0.327754},
+  {0.551598,0.923532},
+  {0.223361,-0.385604},
+  {0.185751,0.593156},
+  {-0.184030,0.754766},
+  {1.395817,0.028574},
+  {0.475188,0.054661},
+  {-0.277480,0.125616},
+  {-0.496862,-1.147994},
+  {-0.004339,-1.205962},
+  {-0.143203,-0.265497},
+  {0.125309,-0.043515},
+  {0.366992,0.512033},
+  {0.824571,0.106918},
+  {-1.068985,0.132551},
+  {1.832261,0.084296},
+  {0.263801,-1.200894},
+  {-1.508048,0.915831},
+  {0.482696,-0.426293},
+  {0.033090,-1.904729},
+  {-2.108846,-0.435991},
+  {-0.176570,0.183011},
+  {-0.552305,0.353128},
+  {-0.238016,0.185723},
+  {-1.105006,-0.940637},
+  {-0.819965,-0.929777},
+  {0.157431,0.682561},
+  {-0.217550,0.640647},
+  {0.203090,-0.654541},
+  {-0.077923,1.061114},
+  {0.255508,-1.220831},
+  {-0.166887,-0.641701},
+  {-0.366592,0.125942},
+  {-1.173483,0.813176},
+  {0.808734,-0.982589},
+  {-0.278042,1.861455},
+  {-0.065514,0.269957},
+  {0.906470,0.226526},
+  {-0.120529,-0.080793},
+  {0.417512,0.156899},
+  {-0.907569,-0.097119},
+  {0.263494,-0.109026},
+  {0.189893,-0.050584},
+  {-0.790905,0.939795},
+  {-0.170601,-0.628612},
+  {0.350909,-0.626418},
+  {-0.386598,-0.927327},
+  {-0.453768,0.023829},
+  {0.914262,0.275209},
+  {-0.562420,-0.398459},
+  {-0.630268,1.978496},
+  {0.221322,1.406665},
+  {0.469280,0.011328},
+  {1.173789,0.177916},
+  {-0.299844,0.272473},
+  {0.251780,-0.111125},
+  {-0.773700,1.126264},
+  {-0.141209,0.420552},
+  {0.799946,-0.075850},
+  {-1.245327,0.658100},
+  {0.291694,0.510028},
+  {-0.794185,-0.184348},
+  {0.558676,-0.725595},
+  {0.104020,0.146003},
+  {0.687901,0.258342},
+  {0.447092,1.306396},
+  {0.252250,-0.596987},
+  {-0.576601,0.104527},
+  {-0.528980,0.897886},
+  {0.319621,0.007942},
+  {-0.271045,-1.032491},
+  {0.106805,-1.171924},
+  {-0.117934,-0.002040},
+  {0.937400,0.094878},
+  {0.767345,0.456467},
+  {-0.248117,1.399906},
+  {-0.019431,0.029962},
+  {-0.553835,-0.199065},
+  {0.973482,-0.555913},
+  {-1.158272,0.011195},
+  {0.289042,-0.022439},
+  {-0.242274,0.051491},
+  {-0.784552,0.046357},
+  {0.089161,-0.070526},
+  {-0.347404,-0.479778},
+  {-0.387975,-0.227373},
+  {0.209500,-1.064529},
+  {1.636459,-0.994817},
+  {0.962069,-0.828699},
+  {0.599537,0.180033},
+  {0.403511,-1.375267},
+  {-0.030051,0.364420},
+  {0.255406,-0.152639},
+  {-0.842737,-0.083531},
+  {0.265162,-0.110579},
+  {0.023556,-1.674108},
+  {0.998462,-0.391540},
+  {-0.236300,-0.679450},
+  {-0.135786,0.684768},
+  {-0.166010,0.165157},
+  {0.727715,-0.372501},
+  {-0.189725,0.488845},
+  {-0.295131,-0.024017},
+  {0.260305,-0.897897},
+  {0.282883,-0.374545},
+  {-0.131905,0.759994},
+  {0.642608,-0.501903},
+  {0.235753,-0.019992},
+  {0.234917,-0.917430},
+  {-0.187950,-0.955321},
+  {-1.679033,-0.077540},
+  {0.057969,-0.182145},
+  {0.806970,0.187450},
+  {-1.255149,-1.161657},
+  {0.071722,-1.622885},
+  {0.743520,-0.598178},
+  {-0.541128,0.760663},
+  {-0.690128,-0.163725},
+  {-0.713829,1.032708},
+  {-0.184282,0.073560},
+  {-1.631399,-1.104151},
+  {-0.287196,-1.050644},
+  {-0.861881,0.837003},
+  {0.658268,-0.445585},
+  {-0.492519,-0.822022},
+  {-0.042083,0.453774},
+  {-1.060994,0.621202},
+  {0.552598,-0.448519},
+  {0.547632,-0.643752},
+  {-0.180073,-0.870508},
+  {-0.301082,0.100829},
+  {-0.185883,0.378342},
+  {-1.021355,-0.041632},
+  {0.835251,0.146685},
+  {0.367444,1.012175},
+  {-0.336391,0.016233},
+  {-1.065102,0.040814},
+  {-0.949472,0.846319},
+  {1.291102,0.795366},
+  {-0.487972,1.266731},
+  {0.385963,-1.232202},
+  {-0.274804,-0.575065},
+  {0.142511,0.996808},
+  {-1.127767,0.320745},
+  {-1.464213,-0.001272},
+  {-1.263870,-0.925822},
+  {0.440001,1.508906},
+  {-1.938712,-1.470684},
+  {-0.186008,0.087603},
+  {0.166957,-0.114873},
+  {-0.546288,0.060052},
+  {-0.451944,-0.677336},
+  {0.110307,-0.073643},
+  {-2.575184,-0.348193},
+  {0.686896,-0.114358},
+  {0.104536,-0.295687},
+  {1.742926,0.023467},
+  {-0.764176,0.383341},
+  {0.143325,0.194010},
+  {0.520979,0.503754},
+  {1.008110,-0.184279},
+  {0.707282,0.233438},
+  {-1.342322,-0.476836},
+  {-0.162102,-0.516986},
+  {-1.555440,0.272954},
+  {1.012432,-0.043494},
+  {-0.081673,1.117860},
+  {0.403470,0.057254},
+  {-0.517038,-0.110340},
+  {0.475128,0.752501},
+  {-0.489141,-0.553330},
+  {-0.636345,-0.926923},
+  {0.379515,0.423726},
+  {0.263556,-0.838201},
+  {1.364556,-0.420440},
+  {-0.269874,0.091490},
+  {-1.434258,0.014961},
+  {-0.590992,0.091827},
+  {-0.308413,0.016741},
+  {0.349648,-1.591085},
+  {-0.118712,1.184347},
+  {0.187251,1.433784},
+  {0.562964,1.318689},
+  {-0.861674,-0.392680},
+  {0.002905,0.622487},
+  {-0.151723,-1.179258},
+  {-0.070747,0.053384},
+  {0.525404,-0.554260},
+  {-0.343545,-0.118922},
+  {-0.507229,-0.864504},
+  {0.500450,-0.403323},
+  {0.377233,0.949879},
+  {-0.833561,-0.056483},
+  {-0.725906,-0.705636},
+  {0.922402,-0.108117},
+  {0.242458,-0.509338},
+  {1.107595,0.489720},
+  {-1.198374,-0.015819},
+  {-0.413664,-0.441380},
+  {0.218345,-1.315292},
+  {0.497907,-0.042786},
+  {1.204892,-0.699516},
+  {-0.555751,0.313409},
+  {0.379257,-0.609355},
+  {0.950328,-0.278547},
+  {-0.755355,0.813622},
+  {0.513696,-0.533451},
+  {-0.495311,0.409720},
+  {0.112153,-1.160556},
+  {0.353378,0.752034},
+  {0.459675,-0.527592},
+  {0.546631,0.123779},
+  {0.828528,0.384762},
+  {-0.369489,0.154474},
+  {-0.505704,0.615962},
+  {-0.473887,0.076201},
+  {0.008357,-0.357277},
+  {0.129246,-0.337053},
+  {-0.257137,-0.189718},
+  {-1.475479,0.652016},
+  {0.204440,-0.454342},
+  {1.032094,-0.103206},
+  {-1.053839,0.656926},
+  {0.190919,-0.204573},
+  {-0.069636,-0.090363},
+  {-1.022143,0.421546},
+  {0.117690,-0.596925},
+  {0.668920,-0.202848},
+  {0.414527,0.111164},
+  {0.569160,-0.332882},
+  {-0.740114,-0.838751},
+  {-0.811449,0.332958},
+  {0.165041,-0.548386},
+  {0.586089,1.162788},
+  {-0.441744,0.705830},
+  {0.345507,0.417786},
+  {-0.150969,-0.217414},
+  {0.980970,-0.395728},
+  {0.202029,0.053837},
+  {-0.567949,-0.756414},
+  {0.838055,-0.962655},
+  {0.185033,-0.842624},
+  {0.505452,-0.230980},
+  {0.500792,-1.312236},
+  {0.098343,0.520689},
+  {-0.927027,-0.045385},
+  {0.569641,0.548063},
+  {-0.798887,1.354409},
+  {-1.055338,0.516666},
+  {-1.035704,0.360430},
+  {-0.184264,0.067661},
+  {0.570477,0.590137},
+  {0.551827,0.899930},
+  {0.533855,1.304288},
+  {0.350958,-0.358284},
+  {-1.384382,-0.753483},
+  {0.601123,-2.156966},
+  {-0.554389,0.059956},
+  {-0.871086,-0.106200},
+  {0.558179,0.180493},
+  {0.531430,-0.025180},
+  {-0.795320,0.260424},
+  {0.692222,-0.238340},
+  {0.169459,0.823660},
+  {0.299030,0.761034},
+  {-0.698652,-0.351722},
+  {0.368231,0.434130},
+  {0.185790,-1.403230},
+  {-0.799883,-0.119406},
+  {0.736042,0.392089},
+  {-0.666826,-0.832812},
+  {-0.513339,0.050691},
+  {-0.587525,0.355240},
+  {-0.517997,0.850523},
+  {-0.899883,0.695032},
+  {-0.206738,0.938988},
+  {-0.699376,-0.248451},
+  {0.788660,-0.329191},
+  {-0.803143,0.755641},
+  {-0.347574,-0.096980},
+  {0.655063,-0.198669},
+  {0.324775,-0.654269},
+  {0.921286,-0.437049},
+  {0.744575,-0.148011},
+  {-1.499490,0.208673},
+  {1.813010,1.936063},
+  {-0.330382,0.942141},
+  {-0.175160,0.095578},
+  {-0.688972,0.621992},
+  {-0.710787,0.337475},
+  {0.082558,-0.051458},
+  {0.108929,-1.049616},
+  {0.411274,0.385344},
+  {0.016239,-0.562674},
+  {0.921934,0.406952},
+  {0.524669,-0.237757},
+  {-0.660776,-0.152646},
+  {-0.149333,0.000891},
+  {-0.254695,-0.615310},
+  {-0.756202,0.840237},
+  {-0.309718,-0.633714},
+  {-0.218646,-1.024427},
+  {-0.085284,0.238786},
+  {-0.127700,-0.176234},
+  {0.641768,-0.561286},
+  {-1.032711,-0.515069},
+  {1.363094,-0.095828},
+  {1.534582,0.380000},
+  {0.805601,0.320919},
+  {0.701193,-0.161937},
+  {0.262605,-0.457002},
+  {0.345692,-0.485455},
+  {0.973676,1.050191},
+  {0.563517,-0.896698},
+  {-1.052935,-0.655316},
+  {-0.231460,-0.146481},
+  {-0.979474,0.060279},
+  {-1.088586,-0.421800},
+  {0.161069,1.003289},
+  {0.090253,-0.088947},
+  {-0.547361,-1.206487},
+  {0.246441,1.106913},
+  {-0.706636,-0.015038},
+  {0.132891,1.002612},
+  {-0.295681,0.231105},
+  {-1.153732,-0.996986},
+  {-0.501629,-0.644197},
+  {0.295345,-0.691762},
+  {-1.440078,-0.607401},
+  {0.101169,0.934845},
+  {0.071043,-0.644190},
+  {0.614922,-0.503042},
+  {1.037925,-0.411965},
+  {-0.852186,0.229310},
+  {0.299200,-0.324206},
+  {-0.088801,-0.474293},
+  {-2.187987,-0.562442},
+  {0.874113,-0.747951},
+  {0.575873,-0.728991},
+  {-0.846189,0.157840},
+  {-1.429388,0.899668},
+  {0.146948,-0.004011},
+  {1.408618,-0.212564},
+  {-0.215899,-0.253146},
+  {1.498321,-0.772136},
+  {-0.877108,-0.120817},
+  {1.817143,0.201466},
+  {-0.209176,0.538539},
+  {1.517331,-0.539165},
+  {-0.251656,0.628209},
+  {-0.629867,1.537735},
+  {0.022098,1.206070},
+  {-0.360631,-0.347506},
+  {0.752599,0.256274},
+  {0.417381,-0.329550},
+  {-1.519437,-1.728036},
+  {-0.414089,-0.630542},
+  {-0.364826,0.403330},
+  {0.581478,0.594084},
+  {0.663563,0.961159},
+  {0.825272,1.573900},
+  {-0.367023,-0.988905},
+  {-0.073497,0.708838},
+  {1.148249,-0.415716},
+  {-0.101004,0.106337},
+  {-0.928442,-1.408122},
+  {0.469680,-0.047484},
+  {-0.960126,-0.904661},
+  {-1.132264,-0.188708},
+  {-0.016658,-0.199830},
+  {-1.075654,-0.338366},
+  {0.061431,1.126846},
+  {-1.081800,-0.415970},
+  {1.123256,-0.127503},
+  {-1.145737,-0.191834},
+  {-0.793043,-0.118410},
+  {-1.196367,1.014650},
+  {1.527032,-1.381034},
+  {0.647338,-0.080257},
+  {-0.804731,0.453449},
+  {-0.516077,0.480638},
+  {0.530282,-0.739929},
+  {0.269033,-1.963435},
+  {1.477697,0.784988},
+  {0.311743,0.788590},
+  {-0.325671,0.653941},
+  {-0.233521,-0.206602},
+  {-0.278201,0.128288},
+  {1.135366,-1.284597},
+  {-0.763170,-0.012900},
+  {0.438701,0.811553},
+  {-0.249020,-0.316173},
+  {0.561871,-0.138876},
+  {0.726334,1.041021},
+  {0.098118,-0.710592},
+  {-0.572228,0.067081},
+  {0.734250,0.106212},
+  {-0.105387,0.013023},
+  {-0.089425,0.237119},
+  {-0.955892,0.328177},
+  {-0.219179,0.170715},
+  {0.931844,-0.349402},
+  {-0.006197,-1.310244},
+  {1.151184,0.469394},
+  {1.308615,1.117283},
+  {-0.431605,0.200205},
+  {0.191977,-0.367832},
+  {0.236475,0.821365},
+  {-0.941490,0.282290},
+  {-0.006772,0.760460},
+  {0.184771,-0.364421},
+  {-0.329091,-1.396452},
+  {-0.459936,0.172703},
+  {-0.153217,1.302087},
+  {0.098202,-0.527384},
+  {-1.355245,0.009842},
+  {-0.924139,0.157557},
+  {-0.100397,-0.408893},
+  {0.217141,-0.593144},
+  {-0.156430,1.211818},
+  {0.011004,-0.314417},
+  {0.131301,-0.060106},
+  {0.399402,-0.219055},
+  {0.392387,-0.631019},
+  {-0.341266,0.461355},
+  {0.426031,-0.852869},
+  {-0.101110,0.790776},
+  {-0.436091,1.765631},
+  {0.568398,0.767510},
+  {-0.271711,-0.480995},
+  {-0.249560,-0.882825},
+  {-0.381369,1.034425},
+  {-0.503866,0.598387},
+  {0.876082,-1.385329},
+  {0.063173,0.213468},
+  {0.543796,-0.225159},
+  {-0.032141,0.017681},
+  {0.493171,0.162913},
+  {0.686035,0.268915},
+  {0.175293,1.136665},
+  {0.157721,0.697172},
+  {-1.127321,0.592262},
+  {0.166970,-0.343138},
+  {0.194866,0.189738},
+  {-0.288449,1.476208},
+  {-0.421817,1.014786},
+  {0.126023,-0.775427},
+  {0.394521,-0.989582},
+  {-1.089528,-0.055308},
+  {0.200147,0.011439},
+  {1.903990,0.358153},
+  {0.664392,-0.905588},
+  {0.539781,0.841634},
+  {0.582682,0.671146},
+  {-0.024278,-0.572103},
+  {0.185635,-0.697631},
+  {0.106066,0.699490},
+  {0.246818,0.300906},
+  {1.189828,-0.227730},
+  {-0.013825,-0.769516},
+  {-0.684393,0.018085},
+  {1.218080,-1.701471},
+  {0.424389,-0.592234},
+  {1.403248,-0.017446},
+  {0.013415,-0.977801},
+  {0.369274,0.430111},
+  {0.381919,1.117175},
+  {0.816133,-0.715540},
+  {0.035215,-0.105043},
+  {0.556964,-0.135119},
+  {-0.673203,1.053060},
+  {-0.516621,0.494257},
+  {0.450111,-0.035975},
+  {-0.421140,1.411773},
+  {-0.535489,0.037563},
+  {-0.574600,-1.377926},
+  {0.032767,-0.640636},
+  {-0.459555,-0.203066},
+  {-0.434567,0.545250},
+  {0.650357,0.652128},
+  {-0.892425,1.283559},
+  {0.692184,0.557113},
+  {0.751736,-0.211262},
+  {0.313737,-0.163152},
+  {-0.247115,-0.034955},
+  {0.491416,-1.537278},
+  {0.930530,-1.108210},
+  {-0.556112,-1.391934},
+  {-0.961302,0.326983},
+  {1.662905,-0.278552},
+  {-0.313318,-1.433712},
+  {-1.000577,0.559144},
+  {0.216728,0.878720},
+  {0.487019,-0.649528},
+  {-0.623891,-0.371940},
+  {-0.040803,0.208126},
+  {0.315032,0.149693},
+  {-0.198370,-1.011750},
+  {-0.824018,1.104106},
+  {-0.353701,0.822379},
+  {-0.123394,-1.055204},
+  {-0.737870,-0.757284},
+  {-0.634799,-0.464904},
+  {-1.763571,-0.369890},
+  {0.047103,0.948021},
+  {0.847644,0.119019},
+  {0.504559,-0.136831},
+  {0.049168,0.250676},
+  {-0.407130,0.581465},
+  {-0.424114,-0.237635},
+  {-0.576690,-0.447438},
+  {-0.534590,-0.285313},
+  {-0.525026,0.509418},
+  {0.991170,0.776430},
+  {0.082037,-0.154868},
+  {-0.738468,1.113500},
+  {-1.376870,-0.237227},
+  {0.182010,0.599488},
+  {-0.012601,0.360641},
+  {-0.874033,0.846574},
+  {-0.453102,0.527465},
+  {-0.140117,0.979272},
+  {0.469908,-0.563083},
+  {0.494906,0.205413},
+  {-0.152124,1.445632},
+  {-1.070697,-0.417032},
+  {0.620584,1.098607},
+  {0.647829,-0.212808},
+  {0.329902,0.206018},
+  {0.769611,0.068876},
+  {0.595618,-1.179969},
+  {0.134816,1.155849},
+  {0.132816,-0.826840},
+  {-0.204456,-0.005218},
+  {0.565919,-0.406434},
+  {1.076761,0.279015},
+  {-0.824357,-0.318681},
+  {0.536584,1.190336},
+  {-0.837780,-0.783722},
+  {-0.365623,-0.592565},
+  {0.140732,-0.354577},
+  {-0.318893,0.197879},
+  {-0.650844,0.142190},
+  {0.611141,-0.819490},
+  {0.824394,-1.997252},
+  {1.188414,-0.772520},
+  {0.495803,0.456638},
+  {-0.793332,1.358671},
+  {-1.208357,0.747812},
+  {0.639802,-0.096943},
+  {0.128095,-0.588363},
+  {0.114812,0.593784},
+  {-0.189818,-0.088502},
+  {-0.281234,0.074641},
+  {-0.318011,0.468384},
+  {-0.032031,0.092814},
+  {0.280203,0.824080},
+  {0.375190,0.631836},
+  {0.434939,-0.102007},
+  {-0.537006,-1.514559},
+  {0.203213,-0.319343},
+  {-0.141183,-1.038148},
+  {-0.218501,-0.477195},
+  {-0.338538,-0.751898},
+  {-0.686068,0.283823},
+  {0.062352,1.559887},
+  {-0.241352,-1.511161},
+  {0.720157,-0.832961},
+  {0.558763,-0.548703},
+  {0.263548,0.902844},
+  {0.842079,-0.167704},
+  {-0.542509,0.454977},
+  {0.903157,0.620579},
+  {0.964410,0.047286},
+  {-0.955672,0.944376},
+  {0.860074,1.300853},
+  {0.512725,0.794600},
+  {-0.450602,0.516415},
+  {-0.447504,0.181518},
+  {-0.437303,0.401800},
+  {-0.578495,-0.043247},
+  {0.617911,-0.345819},
+  {-0.552715,-1.044463},
+  {-0.867800,-0.875333},
+  {0.481378,-0.046626},
+  {0.191387,-0.016629},
+  {-0.518826,-0.671362},
+  {-0.076694,0.392508},
+  {0.019799,-0.500523},
+  {1.539289,0.191522},
+  {0.268896,0.472991},
+  {-0.122127,-0.508825},
+  {0.314364,-0.019904},
+  {-0.144547,0.440958},
+  {0.265538,0.198174},
+  {0.863341,-0.176679},
+  {0.122943,-0.154642},
+  {0.043506,0.107960},
+  {0.099631,-0.078301},
+  {-0.560396,0.316725},
+  {1.286545,0.635450},
+  {-0.358192,-0.438848},
+  {1.039133,-0.132411},
+  {1.186643,0.405783},
+  {-1.001651,-0.156892},
+  {-1.179719,-0.490621},
+  {-0.721972,0.717535},
+  {-1.029560,-0.455562},
+  {-0.077975,0.563804},
+  {-0.813295,0.621995},
+  {0.618189,0.598485},
+  {-1.199978,-0.777894},
+  {-0.290504,0.990481},
+  {-0.031754,0.345115},
+  {-0.368322,1.005785},
+  {0.599679,-0.895852},
+  {-0.590234,-0.096684},
+  {-0.496663,-0.691375},
+  {0.088853,0.700215},
+  {-0.183732,0.242244},
+  {-0.643606,-0.335184},
+  {0.121277,-0.906499},
+  {0.241237,1.352691},
+  {-0.254636,-0.459023},
+  {-0.621434,-0.262442},
+  {-1.261593,0.823850},
+  {0.524973,0.145684},
+  {0.664583,-0.298579},
+  {0.609610,-0.078780},
+  {0.203934,-0.123287},
+  {-0.774268,-0.471319},
+  {-0.207046,1.271445},
+  {-0.236533,-0.485094},
+  {-0.597981,1.115511},
+  {-0.406298,0.760957},
+  {0.694472,-0.379866},
+  {-0.372914,0.292032},
+  {0.784017,0.922657},
+  {0.297901,0.163029},
+  {-0.904827,-0.819312},
+  {0.561786,0.562537},
+  {-0.239547,0.126229},
+  {-1.407316,-0.320167},
+  {-0.134303,-1.366530},
+  {-0.531725,-0.336818},
+  {0.623285,0.322439},
+  {-0.335097,0.897800},
+  {0.695935,-0.312405},
+  {0.095367,0.409572},
+  {-0.765337,-0.211423},
+  {-1.131867,-0.623383},
+  {-0.267968,-0.286704},
+  {-0.404970,-0.309191},
+  {1.379609,0.251604},
+  {0.331291,0.143124},
+  {-0.913650,0.804486},
+  {-1.218644,0.871913},
+  {0.039236,0.744136},
+  {1.449769,0.975760},
+  {-0.210467,0.262295},
+  {0.405987,0.424655},
+  {0.999384,0.627690},
+  {1.164600,0.133861},
+  {-0.175488,1.427081},
+  {-1.744108,0.555451},
+  {0.302610,-0.688230},
+  {-0.529522,-1.322584},
+  {-0.223304,-0.289473},
+  {0.668378,0.179522},
+  {0.084177,0.492469},
+  {0.266502,-0.068043},
+  {0.764533,-0.106614},
+  {-0.317832,0.270595},
+  {-0.444143,-0.228776},
+  {0.108340,-0.373711},
+  {-0.027397,-0.010145},
+  {-0.613227,0.902768},
+  {-0.557055,0.429239},
+  {0.373258,-0.228158},
+  {-0.631503,-0.356203},
+  {0.643938,-0.284783},
+  {-0.784050,-0.572626},
+  {-0.207974,-0.145033},
+  {0.006310,0.173822},
+  {-0.106005,0.111244},
+  {2.363675,-0.471391},
+  {0.972607,0.013920},
+  {1.130367,-0.608325},
+  {-0.479318,-0.017402},
+  {-0.647306,0.746952},
+  {1.365227,0.174166},
+  {0.586382,-0.751731},
+  {-0.467157,1.701264},
+  {-0.531539,0.869207},
+  {-0.610338,0.132307},
+  {0.356638,0.108132},
+  {-0.568649,-0.676443},
+  {0.089214,-0.008608},
+  {-0.984149,0.709467},
+  {0.597348,0.413095},
+  {0.139796,1.022797},
+  {-1.032483,-0.315232},
+  {0.021779,-1.284263},
+  {0.891663,-0.443996},
+  {-0.684480,-0.817773},
+  {0.401035,0.351907},
+  {0.217196,-0.252169},
+  {-1.349881,-0.517501},
+  {0.816430,-0.091990},
+  {-0.502108,-0.698291},
+  {-0.086025,0.915485},
+  {-0.682122,-0.322046},
+  {0.706000,0.763462},
+  {0.796854,0.455243},
+  {1.366467,1.196075},
+  {0.417067,-0.256263},
+  {0.015371,0.451181},
+  {-0.400583,0.178607},
+  {0.179912,-0.117066},
+  {0.597156,-0.688654},
+  {-0.661676,-0.820197},
+  {0.085683,-0.217177},
+  {-0.706450,-1.381830},
+  {0.028548,1.200703},
+  {-0.920667,0.289784},
+  {0.160350,-0.351146},
+  {-0.804724,-0.618602},
+  {0.024888,0.647150},
+  {-0.098113,0.173361},
+  {0.697754,0.291105},
+  {-1.408036,1.022388},
+  {0.469920,0.445517},
+  {0.384059,0.532228},
+  {-0.151818,0.944132},
+  {-0.090433,0.327546},
+  {-0.879679,-1.070965},
+  {-0.495967,0.063480},
+  {-0.358409,-0.789978},
+  {-0.699352,-0.883109},
+  {-1.947079,0.913473},
+  {-0.641222,-0.030654},
+  {-1.419634,-0.263358},
+  {-0.287427,1.075618},
+  {1.041925,0.333373},
+  {1.035917,-0.384391},
+  {-0.742460,0.756039},
+  {0.484778,0.439710},
+  {-0.454690,-0.553386},
+  {-0.860744,-0.035129},
+  {-0.063566,0.489990},
+  {0.107992,0.565035},
+  {-0.016311,0.236242},
+  {0.309996,0.522161},
+  {0.839932,1.127528},
+  {0.213453,-1.064570},
+  {-0.716013,0.561550},
+  {-0.277888,-0.545995},
+  {-0.080229,-0.275056},
+  {-1.231363,-0.438038},
+  {-0.221378,1.152323},
+  {0.465562,-0.015422},
+  {-0.636983,-1.776097},
+  {0.994972,1.153935},
+  {-0.840363,-1.044283},
+  {-0.147775,-0.659287},
+  {-1.008426,1.195206},
+  {0.221680,0.312210},
+  {0.391826,0.267132},
+  {-0.300629,0.352818},
+  {1.088779,0.848130},
+  {-0.087740,-1.562253},
+  {-0.636828,0.356063},
+  {0.255724,-0.928242},
+  {0.197228,-1.313775},
+  {-0.363243,-0.477933},
+  {0.342319,1.332603},
+  {-0.687342,-0.697300},
+  {0.588366,-0.220649},
+  {0.718963,1.534212},
+  {0.378261,-0.815048},
+  {0.008267,-0.048339},
+  {-0.337132,-0.394747},
+  {-0.429718,-1.955695},
+  {0.422312,0.648188},
+  {-0.225384,-1.038982},
+  {-0.074649,-0.432788},
+  {1.197830,0.224400},
+  {0.179256,0.174055},
+  {0.324657,-0.153234},
+  {-0.008755,-0.720614},
+  {1.171336,1.386902},
+  {-0.502534,0.544987},
+  {-0.874559,-0.045977},
+  {0.641911,0.309244},
+  {-0.852252,-0.189481},
+  {0.905778,-0.240689},
+  {0.805296,0.190095},
+  {0.583950,0.500505},
+  {0.927808,-0.289025},
+  {-0.161069,-1.142641},
+  {-0.829648,-1.067679},
+  {0.160495,-0.177610},
+  {-0.669901,0.538416},
+  {-0.417880,-0.610111},
+  {-0.641121,0.118270},
+  {-0.307481,0.182497},
+  {-0.098936,-0.300794},
+  {0.079945,-1.126696},
+  {0.767377,-0.205567},
+  {-0.229164,-0.681283},
+  {-0.938784,0.869544},
+  {0.729480,-0.893640},
+  {0.318684,0.291873},
+  {-0.063858,-1.269459},
+  {-0.394907,0.032640},
+  {0.041145,-0.695384},
+  {0.903121,-0.762764},
+  {-0.236944,-1.403906},
+  {0.010014,-0.107070},
+  {-0.144645,0.624289},
+  {0.889531,-0.018986},
+  {0.956051,1.297021},
+  {-0.096103,-0.738099},
+  {-0.795984,-1.097452},
+  {-0.394740,0.151985},
+  {0.109809,-0.515633},
+  {1.331729,-1.680084},
+  {1.546974,0.279037},
+  {-1.785160,-0.221012},
+  {0.122575,-0.919889},
+  {-0.788030,1.561325},
+  {-0.205935,0.088416},
+  {-0.265662,0.431570},
+  {0.115537,0.899615},
+  {0.471598,0.669058},
+  {-0.214156,0.254611},
+  {0.970194,1.044374},
+  {-0.486194,0.026669},
+  {0.232387,0.010928},
+  {0.162715,0.243238},
+  {-0.554603,0.305242},
+  {0.050873,0.089235},
+  {0.866591,0.431844},
+  {-0.137254,0.419949},
+  {-0.444023,-0.814751},
+  {0.405856,0.278733},
+  {-0.006847,-0.084791},
+  {0.661887,0.366497},
+  {0.036938,-1.474893},
+  {0.074623,0.527883},
+  {-0.932561,-1.217377},
+  {-0.579955,-0.770222},
+  {0.496777,-0.398753},
+  {0.415390,0.029064},
+  {-0.368869,0.318877},
+  {-0.083926,0.115238},
+  {-0.165148,0.315531},
+  {-0.201764,-1.548454},
+  {-0.837318,-1.399309},
+  {0.078016,-0.732903},
+  {-0.094333,-0.160290},
+  {0.732228,-1.029345},
+  {0.690766,0.425063},
+  {-0.896572,-0.514863},
+  {0.781318,-0.797095},
+  {-0.121511,0.255802},
+  {1.919578,-0.769384},
+  {-0.060926,0.430455},
+  {-0.409906,-0.249459},
+  {-0.460218,-0.783980},
+  {-0.191177,0.609070},
+  {1.020451,-0.427484},
+  {0.388170,-0.559406},
+  {0.583320,0.030542},
+  {-1.179019,0.739794},
+  {1.513305,0.344903},
+  {-1.082705,-0.638275},
+  {-0.426897,0.254435},
+  {-0.481466,0.047423},
+  {0.330028,-0.364721},
+  {0.571710,0.131679},
+  {0.796521,-1.303731},
+  {-0.192941,-0.043661},
+  {-0.182032,1.445423},
+  {-0.370906,0.132620},
+  {1.865372,-0.256694},
+  {0.122110,-0.042592},
+  {-0.484049,0.625328},
+  {0.498676,-0.447230},
+  {-0.698297,-0.450146},
+  {0.197802,0.388351},
+  {-0.270285,0.053455},
+  {0.113784,-0.200340},
+  {0.144229,0.267333},
+  {0.085266,1.105437},
+  {-0.021050,1.100430},
+  {1.668020,-1.591069},
+  {1.074784,-0.878131},
+  {-0.687458,-1.410101},
+  {0.945055,0.057837},
+  {-0.968993,-0.249526},
+  {-0.095768,-0.004312},
+  {0.539684,-0.120041},
+  {-0.690336,-0.784441},
+  {-0.070364,0.818636},
+  {0.306879,-0.280708},
+  {-0.072888,0.404632},
+  {-1.158507,1.076282},
+  {-1.311557,0.016792},
+  {-1.276006,0.450810},
+  {0.052812,-0.238705},
+  {1.449476,-0.258773},
+  {-0.935995,-0.005463},
+  {-0.355631,0.492401},
+  {-0.612492,0.524131},
+  {0.838550,0.621703},
+  {0.198766,-1.213802},
+  {0.114797,-0.883231},
+  {0.323205,-0.912574},
+  {-0.492987,0.031387},
+  {0.613420,-1.264507},
+  {-0.452913,-0.543444},
+  {0.252574,0.848988},
+  {0.177081,1.145831},
+  {-0.172781,-0.088674},
+  {-0.380519,-0.210205},
+  {-0.333186,-1.162848},
+  {0.424112,-0.009379},
+  {-0.876016,0.594356},
+  {0.191680,-0.347826},
+  {-0.001609,-0.647491},
+  {-0.410415,-0.735499},
+  {-0.001733,-0.310524},
+  {-0.323841,0.482596},
+  {-0.242955,0.027559},
+  {0.502454,0.491188},
+  {0.014760,0.136650},
+  {0.969240,-0.064603},
+  {-0.230129,-0.410373},
+  {0.068982,0.158729},
+  {-0.264938,1.121409},
+  {-0.330733,-1.289736},
+  {-0.310857,-0.416680},
+  {-0.995101,0.426949},
+  {0.044670,-0.644963},
+  {-0.370186,-0.419359},
+  {-0.198722,0.626537},
+  {0.250446,-0.321014},
+  {-0.199294,0.428196},
+  {0.287559,0.661812},
+  {-0.819334,-0.182923},
+  {0.627230,0.073635},
+  {-0.254799,0.086437},
+  {0.629778,-0.238849},
+  {-0.214531,-0.833867},
+  {-0.370971,-1.340886},
+  {-0.838782,0.085272},
+  {0.699287,0.326143},
+  {0.969557,0.265905},
+  {0.224255,1.026885},
+  {-0.705422,0.039940},
+  {2.677294,0.824637},
+  {-0.872479,0.726054},
+  {-0.356049,-0.644072},
+  {1.247068,-0.283382},
+  {-0.052734,0.460700},
+  {-0.219080,-0.773459},
+  {-0.404964,1.015079},
+  {-0.613011,-0.740705},
+  {-0.224677,0.053237},
+  {0.894221,0.740370},
+  {1.156185,-0.712990},
+  {0.292658,-0.216708},
+  {-0.066752,1.055119},
+  {1.357077,0.220257},
+  {0.460298,0.433686},
+  {-1.604282,0.281681},
+  {0.013828,-0.330717},
+  {0.170076,-0.933305},
+  {1.041761,-0.252779},
+  {-0.246114,-0.576060},
+  {1.480525,0.007697},
+  {0.441859,0.826016},
+  {0.295619,-1.276915},
+  {0.915688,0.319889},
+  {0.022048,0.222383},
+  {1.378602,-1.120309},
+  {-0.027128,0.227251},
+  {-0.029159,0.234012},
+  {-1.232345,-1.709367},
+  {0.443828,0.107305},
+  {-0.853740,-1.028442},
+  {0.423166,-0.208449},
+  {0.437276,0.123764},
+  {-0.405086,-0.566809},
+  {-0.459850,-0.615080},
+  {0.015966,-0.560154},
+  {-0.524545,0.824488},
+  {0.590298,1.680262},
+  {-0.074765,1.037196},
+  {1.410833,-0.872378},
+  {0.595534,-0.084257},
+  {0.283239,-0.652858},
+  {-0.046879,-0.046124},
+  {-0.369435,0.393944},
+  {1.852725,0.076027},
+  {-1.092554,-0.019375},
+  {-1.380574,-1.233999},
+  {0.377688,0.527289},
+  {-0.179858,0.250972},
+  {0.411598,0.469015},
+  {0.284770,-0.983034},
+  {0.950896,-0.086210},
+  {0.315096,0.753994},
+  {-0.153846,-0.582036},
+  {-0.642368,-0.187750},
+  {0.048072,0.639136},
+  {-0.556765,-1.105212},
+  {0.180486,-0.178092},
+  {0.924552,-0.298329},
+  {-0.232289,-1.459794},
+  {-0.210924,-0.352326},
+  {-0.743565,0.331766},
+  {0.804067,-0.756999},
+  {-1.120228,1.402332},
+  {-0.563865,-0.766699},
+  {-1.241026,-0.016935},
+  {-1.083249,0.663982},
+  {-0.696610,0.197940},
+  {0.240815,-1.001368},
+  {0.338313,-1.016316},
+  {-0.333358,-0.619444},
+  {0.114418,-0.274406},
+  {-0.048887,0.026654},
+  {0.319559,-0.940490},
+  {-0.772192,-0.627506},
+  {0.732077,0.628962},
+  {-0.517531,-0.461387},
+  {0.366764,-0.719179},
+  {0.537746,0.869680},
+  {0.349716,-0.212016},
+  {-1.339703,0.494797},
+  {-0.261270,0.480154},
+  {-1.071839,-2.066688},
+  {-0.370999,-0.038925},
+  {-0.747227,0.085586},
+  {-0.942602,-0.057338},
+  {-0.072358,1.097723},
+  {-0.205848,-1.136328},
+  {0.597227,0.197329},
+  {0.676518,0.381645},
+  {-0.874854,-0.479414},
+  {-1.999738,-0.565455},
+  {-0.664048,-0.574682},
+  {0.186569,0.411274},
+  {-0.110267,-0.357864},
+  {0.302705,-1.743357},
+  {-0.319344,-0.476152},
+  {-0.640334,-0.720226},
+  {-0.910033,-0.422789},
+  {-0.208408,0.548207},
+  {-0.964300,0.002179},
+  {0.824444,0.424217},
+  {-1.032269,-0.762202},
+  {0.105175,0.447058},
+  {-0.012006,0.049305},
+  {-0.937920,0.289750},
+  {-1.253273,0.757789},
+  {-0.762061,0.328438},
+  {-0.241415,1.027135},
+  {0.243270,0.013979},
+  {-1.109143,-0.208914},
+  {0.090512,-0.386316},
+  {1.503883,0.622403},
+  {0.175205,1.011719},
+  {0.386237,-0.727356},
+  {1.030490,-0.207293},
+  {-0.934681,-0.637268},
+  {0.390874,0.381332},
+  {0.183902,1.098244},
+  {-0.785477,1.103963},
+  {0.665390,0.256809},
+  {0.263688,-0.503673},
+  {-0.166081,-0.926605},
+  {-0.557337,0.532023},
+  {-0.195427,1.271505},
+  {-0.474249,0.447195},
+  {0.443875,1.233854},
+  {-0.269777,-0.979940},
+  {-0.022060,0.544843},
+  {0.313713,-0.853284},
+  {-0.096390,2.008847},
+  {0.439922,-0.335096},
+  {0.896690,-0.588963},
+  {-0.844743,0.183750},
+  {0.781349,-0.755606},
+  {-0.765362,0.170504},
+  {-1.628206,-0.216829},
+  {0.500102,-0.059625},
+  {-0.304791,0.107158},
+  {0.557697,-0.477804},
+  {0.583642,0.627863},
+  {-0.121640,-0.409209},
+  {-1.120829,-1.076884},
+  {-0.536931,0.178972},
+  {-0.417448,-0.458302},
+  {0.718477,-1.059868},
+  {0.610038,-0.423881},
+  {0.999029,-0.368049},
+  {-0.197010,0.618818},
+  {-0.092802,0.280660},
+  {-0.884475,0.746423},
+  {-0.218251,0.164965},
+  {-0.421409,0.312894},
+  {-0.658414,0.399046},
+  {0.745212,-0.200538},
+  {0.941667,-0.785267},
+  {0.521849,0.859422},
+  {-0.473471,0.762251},
+  {0.397426,-0.176657},
+  {-0.323150,0.760653},
+  {-0.998414,1.716395},
+  {0.740360,-0.938944},
+  {0.023348,1.116443},
+  {1.069598,-0.382364},
+  {-1.043662,0.236812},
+  {-0.382172,-0.980040},
+  {-0.349019,0.364638},
+  {-0.298100,-1.107602},
+  {0.456000,0.116486},
+  {0.877536,0.868085},
+  {0.048209,-1.069550},
+  {0.661781,-1.278720},
+  {0.359336,0.813250},
+  {-0.123966,-0.468063},
+  {0.430191,0.023114},
+  {-0.135566,-0.319366},
+  {0.968871,-0.115512},
+  {-0.394328,-0.170491},
+  {-0.009694,-1.061476},
+  {0.046248,-0.139918},
+  {0.368727,0.177700},
+  {0.414373,-0.767674},
+  {0.759806,0.895111},
+  {-1.039452,-0.596694},
+  {0.098206,0.950569},
+  {-1.174535,-0.768597},
+  {0.623601,-0.766489},
+  {1.209239,-0.052878},
+  {-0.452015,-0.009341},
+  {0.690382,0.542857},
+  {-0.108723,0.123140},
+  {-0.529691,0.324165},
+  {1.478203,-0.911289},
+  {1.068649,-0.374113},
+  {0.299869,0.396780},
+  {0.430316,0.155351},
+  {0.013919,-0.121839},
+  {0.039700,0.017585},
+  {-0.571082,-0.704321},
+  {-0.736133,1.469112},
+  {0.703268,-0.091642},
+  {0.386893,0.603817},
+  {0.172514,-0.849675},
+  {0.607745,0.054904},
+  {0.271231,-0.590061},
+  {0.913552,-0.116009},
+  {-1.138750,0.486391},
+  {-0.076353,-0.638643},
+  {-0.498974,0.588957},
+  {-0.246757,-1.191164},
+  {-0.997522,0.317823},
+  {-0.041872,0.542933},
+  {1.096147,0.311412},
+  {-0.397941,-0.073418},
+  {-0.674415,-0.476303},
+  {0.129485,-0.144863},
+  {-0.320564,-0.468116},
+  {-0.409642,-0.561575},
+  {0.221420,-0.215094},
+  {-0.958367,0.609774},
+  {-0.465613,0.040251},
+  {0.382094,-1.384503},
+  {0.918899,0.048990},
+  {-0.078886,0.735926},
+  {-0.090336,-0.471819},
+  {-0.263712,-0.599983},
+  {0.620502,-0.130819},
+  {-0.335282,0.318506},
+  {0.052591,0.963759},
+  {-0.671888,0.668188},
+  {-0.372171,-0.042465},
+  {0.471828,-0.469881},
+  {-0.393130,-1.355191},
+  {0.245535,-0.797273},
+  {-0.293227,-0.997773},
+  {-0.191794,-0.927120},
+  {0.484915,-1.363790},
+  {0.318464,0.435871},
+  {-0.854547,-0.351262},
+  {-0.218097,-0.360717},
+  {0.263629,-0.076017},
+  {-0.414797,0.096633},
+  {0.897394,-0.109831},
+  {0.962227,-0.804732},
+  {0.151329,1.627499},
+  {0.990435,0.235665},
+  {0.290903,0.311037},
+  {0.160010,-0.053403},
+  {-0.069998,0.302710},
+  {0.084036,0.853274},
+  {0.560929,-0.560850},
+  {-0.106112,0.314448},
+  {-0.421578,-0.268470},
+  {-0.785387,-0.750187},
+  {-1.189174,-0.084856},
+  {0.466530,0.976102},
+  {0.880929,-0.457008},
+  {-0.729195,-0.675082},
+  {0.104374,-0.633442},
+  {0.757444,-0.949991},
+  {0.008917,0.692426},
+  {-0.338838,0.532756},
+  {0.794670,0.717730},
+  {-0.709404,1.043684},
+  {0.579162,0.487640},
+  {-0.404886,0.060629},
+  {1.349450,-0.355399},
+  {0.770612,-1.464736},
+  {0.347219,0.274775},
+  {0.354646,-0.020434},
+  {0.465359,-0.985538},
+  {0.385781,1.068191},
+  {-0.106262,1.103081},
+  {-0.599815,-0.997276},
+  {-0.492767,-0.081408},
+  {-0.245567,0.057807},
+  {0.120883,0.308476},
+  {-1.143013,-0.054048},
+  {0.398061,0.717026},
+  {-0.600222,0.456605},
+  {-0.984594,-0.328664},
+  {0.330060,0.028399},
+  {0.273902,-1.559059},
+  {0.491818,0.871726},
+  {-0.827789,-0.540048},
+  {0.065844,0.068222},
+  {-0.808401,1.160869},
+  {-1.274150,-0.355051},
+  {0.561683,0.271525},
+  {-0.413291,-0.224445},
+  {-0.344482,-0.270754},
+  {-0.669051,0.246237},
+  {-0.049024,-0.250489},
+  {0.977734,-0.366526},
+  {-0.742840,0.329251},
+  {-0.793661,-0.540377},
+  {-0.164454,-0.041182},
+  {0.796305,-0.095571},
+  {-0.168732,0.018351},
+  {-0.010513,1.211849},
+  {-0.994831,-0.709750},
+  {-1.282949,0.285938},
+  {0.864976,0.026893},
+  {-0.160674,-0.991054},
+  {0.235256,0.436919},
+  {1.212801,-0.909780},
+  {0.529844,0.976362},
+  {0.946160,-0.680521},
+  {0.094877,0.672648},
+  {-0.675454,-0.322118},
+  {0.305372,-0.550007},
+  {0.912401,1.035879},
+  {1.131467,-0.138706},
+  {-0.253731,-0.964860},
+  {0.051329,-1.529624},
+  {-0.113924,0.173806},
+  {0.884102,0.159153},
+  {-0.227632,0.877234},
+  {1.010051,-1.543880},
+  {0.809937,-0.173659},
+  {0.332144,-0.243052},
+  {-0.906095,0.676593},
+  {0.073033,-1.548259},
+  {0.458666,0.050823},
+  {-0.289121,1.068049},
+  {-0.383643,0.011142},
+  {0.134420,0.076707},
+  {0.466514,-0.043312},
+  {0.438283,-1.522376},
+  {0.163508,-0.193750},
+  {0.487026,0.542501},
+  {-0.200524,0.459230},
+  {0.262819,1.505884},
+  {0.653087,-0.201042},
+  {0.233565,-0.547870},
+  {-1.017089,0.878535},
+  {0.228269,-0.679254},
+  {1.248531,-0.791408},
+  {0.439579,1.697946},
+  {0.592039,-0.339903},
+  {-0.109908,0.453321},
+  {-1.115247,0.010700},
+  {-0.164818,1.131623},
+  {2.025510,-0.505251},
+  {-0.309346,-1.373256},
+  {0.537120,-0.360283},
+  {-0.104894,0.296882},
+  {0.024801,0.978248},
+  {-0.937777,-1.070944},
+  {-0.198826,-0.783295},
+  {-1.127480,-0.610347},
+  {0.298001,0.024948},
+  {0.145368,0.794536},
+  {0.612907,-0.059654},
+  {0.782929,-0.048403},
+  {-0.435378,-1.436197},
+  {0.169811,0.516786},
+  {-0.116510,0.319035},
+  {0.538300,0.841565},
+  {-0.155311,0.492565},
+  {0.620200,0.730660},
+  {-0.015916,0.419497},
+  {0.164181,-1.630272},
+  {0.824648,0.320043},
+  {-1.560239,0.572704},
+  {-0.252823,0.296962},
+  {-0.746081,0.958339},
+  {0.082239,-1.217646},
+  {-0.567736,0.000241},
+  {0.427482,0.476159},
+  {-0.459043,1.161889},
+  {0.254120,-0.488463},
+  {-0.023313,-0.723543},
+  {-0.293002,-0.169112},
+  {0.089490,-0.261529},
+  {0.247961,0.791363},
+  {-1.110516,-0.166830},
+  {0.983670,-1.198302},
+  {0.519375,-0.785171},
+  {-0.619925,0.150262},
+  {0.569926,0.149914},
+  {0.719057,-0.514677},
+  {0.458531,-0.475477},
+  {0.571393,1.036797},
+  {-0.827266,-1.069063},
+  {-0.208821,0.601468},
+  {0.601543,-0.246378},
+  {-0.545977,-0.481944},
+  {-0.142618,-0.493885},
+  {0.104624,-0.885512},
+  {-0.806208,-1.172703},
+  {-0.327891,-0.764616},
+  {-0.111412,0.778570},
+  {-0.025417,-0.823612},
+  {-0.064253,0.146300},
+  {0.897841,0.233453},
+  {0.170462,-0.208221},
+  {0.469815,0.534622},
+  {0.464492,0.082733},
+  {0.852167,-0.277563},
+  {0.042076,-0.252323},
+  {-0.639666,-0.218750},
+  {0.344882,-0.710013},
+  {-0.897684,0.020080},
+  {0.969355,-0.131562},
+  {-1.412936,0.152039},
+  {0.762647,-1.063394},
+  {-0.706248,-0.458628},
+  {-0.193334,0.251486},
+  {-0.278574,-0.609158},
+  {-0.000444,0.167283},
+  {-0.191255,-0.598270},
+  {0.113407,0.082497},
+  {1.361065,0.155568},
+  {-0.171486,0.161889},
+  {1.639261,-0.316890},
+  {-0.129987,-0.110577},
+  {-0.802764,1.330457},
+  {-0.147106,0.095728},
+  {0.820872,1.110744},
+  {-0.391447,0.136340},
+  {0.927357,0.908692},
+  {1.225880,-0.741652},
+  {0.166896,-2.018048},
+  {-0.072197,-0.734190},
+  {-0.188537,0.562295},
+  {-0.419001,0.597966},
+  {1.012061,-0.032231},
+  {-1.265661,-0.098692},
+  {-0.363672,0.493087},
+  {-1.277901,0.568014},
+  {0.094125,0.641038},
+  {0.366210,-0.871913},
+  {-0.406243,1.248265},
+  {-0.265139,0.291993},
+  {-0.711300,-0.517739},
+  {0.551969,0.211300},
+  {0.863097,0.620748},
+  {-0.791252,0.292823},
+  {-0.859584,-0.514999},
+  {-0.222594,0.242104},
+  {-0.529240,1.091900},
+  {0.056589,-0.206772},
+  {-0.206678,0.117667},
+  {-0.372107,0.346623},
+  {0.197375,0.175770},
+  {0.109383,-0.285298},
+  {-0.128606,-0.575351},
+  {-1.350885,-0.629351},
+  {-0.549311,-0.890107},
+  {-0.052058,-0.399744},
+  {0.117226,-0.822548},
+  {-0.522921,-0.747784},
+  {0.696853,0.225147},
+  {1.404505,0.031853},
+  {-0.199716,0.923465},
+  {-0.366027,-0.965298},
+  {0.254400,0.565191},
+  {0.720813,-0.011776},
+  {0.048742,0.485636},
+  {0.463885,-0.445094},
+  {-0.354658,-0.258331},
+  {-0.512308,0.875492},
+  {0.109512,-0.704183},
+  {-0.359123,-0.222049},
+  {2.094077,-0.596104},
+  {0.099119,0.151596},
+  {1.272189,-0.870022},
+  {-1.203661,0.080126},
+  {-0.402370,-0.038618},
+  {-1.465566,0.187786},
+  {-0.188615,-0.551253},
+  {-0.144342,-0.651031},
+  {0.466536,-0.902577},
+  {0.442013,-0.756855},
+  {0.651331,0.059349},
+  {-0.580323,-0.556246},
+  {1.443369,0.532876},
+  {-0.410520,0.142482},
+  {-0.638481,-1.620247},
+  {1.107948,0.449859},
+  {-0.053538,0.595051},
+  {-0.660756,0.271631},
+  {-0.110972,0.102598},
+  {-0.853215,0.693121},
+  {-0.815886,0.697183},
+  {0.444707,0.103685},
+  {-0.147454,1.248558},
+  {-0.304216,0.147728},
+  {-0.380406,0.389584},
+  {0.869539,-0.442373},
+  {0.367415,0.370479},
+  {-0.860426,0.294945},
+  {-0.310280,-0.101136},
+  {-0.724660,-0.542268},
+  {0.084686,-0.384017},
+  {0.620385,-0.343553},
+  {0.193432,-0.835223},
+  {0.342748,0.073244},
+  {-0.208107,0.866350},
+  {-0.433622,-0.098584},
+  {-1.050180,0.800354},
+  {1.140817,-0.095778},
+  {0.074059,0.720540},
+  {0.324579,-0.250899},
+  {0.908664,-0.424491},
+  {-0.349658,0.492219},
+  {-0.416368,-0.443491},
+  {-0.093378,0.249512},
+  {-1.388730,0.610637},
+  {0.516564,-1.098854},
+  {-0.860684,0.484278},
+  {-0.183881,-0.463325},
+  {-0.461003,-0.667445},
+  {0.768848,0.198854},
+  {0.229416,-1.256209},
+  {0.480655,-0.403404},
+  {0.479239,-0.007571},
+  {-1.318306,0.738942},
+  {1.469443,-0.959983},
+  {0.253482,0.333056},
+  {0.017190,1.742204},
+  {-0.519932,0.898752},
+  {-0.452267,-0.316200},
+  {0.022717,1.692417},
+  {0.796237,-0.765617},
+  {-0.812041,-0.198540},
+  {0.884469,-0.078862},
+  {0.030191,-0.787176},
+  {1.126078,-0.516637},
+  {-1.102333,0.446474},
+  {0.446080,-0.315343},
+  {-0.062631,-0.265291},
+  {-0.853606,-0.044797},
+  {1.077386,-0.224226},
+  {-0.147136,-0.399345},
+  {0.166629,-0.401479},
+  {0.257271,0.174285},
+  {-0.244527,-0.825127},
+  {-0.798872,0.420259},
+  {0.491059,0.151109},
+  {-1.041543,-1.289491},
+  {-0.331789,-1.527598},
+  {-0.083175,0.394579},
+  {-0.323992,0.766890},
+  {0.902158,0.010174},
+  {1.662799,-0.272640},
+  {-0.497409,-0.677542},
+  {-0.849235,0.346076},
+  {0.747101,0.412698},
+  {1.611062,0.866991},
+  {0.163223,-0.262013},
+  {0.741905,0.535948},
+  {-0.239992,0.315095},
+  {1.073907,0.578535},
+  {-0.344179,0.817836},
+  {-0.620181,-0.707425},
+  {0.834661,0.312322},
+  {-1.019361,-0.609310},
+  {1.785614,-0.162301},
+  {0.529534,0.672965},
+  {0.486672,0.153629},
+  {-0.288024,-0.719498},
+  {0.413983,0.270909},
+  {1.374466,0.087559},
+  {0.163283,0.494934},
+  {-0.234819,0.954579},
+  {0.012206,-0.678054},
+  {1.572847,-1.076632},
+  {-0.599282,-0.633372},
+  {1.095665,-0.655620},
+  {-0.684687,-0.201969},
+  {-0.549440,0.045874},
+  {0.322676,0.581203},
+  {0.148109,0.304196},
+  {-0.253076,0.734066},
+  {-0.251967,0.042417},
+  {0.045715,-0.031266},
+  {1.116937,1.123835},
+  {0.483493,0.290907},
+  {0.068072,0.333893},
+  {-0.429817,-0.931647},
+  {-0.480528,-0.164660},
+  {-0.775073,0.535179},
+  {-0.275572,-0.740592},
+  {0.448695,-0.532992},
+  {0.393924,-0.730806},
+  {-0.932048,-1.011165},
+  {-0.001888,0.395913},
+  {-0.030311,0.267041},
+  {0.251709,-0.163471},
+  {0.758127,1.170676},
+  {-0.971904,0.719459},
+  {-0.677315,1.283372},
+  {0.015133,0.474236},
+  {0.250784,0.239230},
+  {-0.284132,0.714203},
+  {0.344950,0.419915},
+  {1.583594,-0.064074},
+  {0.576677,0.349100},
+  {0.125629,0.022908},
+  {0.377394,-0.234506},
+  {-0.563284,-0.715614},
+  {0.101048,-0.920563},
+  {0.608430,0.161613},
+  {-0.928742,-0.992338},
+  {-0.294843,-0.399957},
+  {-0.365761,0.504701},
+  {0.306154,0.060709},
+  {0.715237,0.113832},
+  {-0.231447,-0.747493},
+  {-0.137875,0.022192},
+  {0.270512,-0.373718},
+  {-0.284239,-0.283799},
+  {0.279434,0.240517},
+  {0.968853,-1.661595},
+  {0.795511,0.040827},
+  {0.756925,-0.008006},
+  {0.410158,0.188364},
+  {0.212647,0.160361},
+  {-0.274239,0.135422},
+  {-0.748007,0.121514},
+  {1.889864,-0.426021},
+  {-1.118363,0.603299},
+  {-1.079087,0.214901},
+  {0.881102,0.533797},
+  {0.977096,0.271883},
+  {-0.593182,-0.608447},
+  {-0.831317,-0.259562},
+  {-1.046078,-0.378692},
+  {-0.521179,1.064548},
+  {0.310178,-0.242294},
+  {-0.276422,-0.319965},
+  {-0.581592,-1.175487},
+  {0.078785,0.414402},
+  {0.384824,-0.029560},
+  {0.350595,-0.015079},
+  {-0.505694,0.346891},
+  {-0.244162,-0.431912},
+  {0.179140,0.408671},
+  {-1.683719,-0.175195},
+  {-0.439600,-0.848327},
+  {0.214818,-0.535441},
+  {0.799181,1.313585},
+  {-0.476475,1.275140},
+  {-0.281987,-0.003127},
+  {-0.659120,0.672635},
+  {-0.061892,-0.705050},
+  {-1.224782,0.446358},
+  {0.016139,0.676888},
+  {0.102488,0.468285},
+  {0.270256,1.292447},
+  {-0.872090,0.046884},
+  {0.843556,-0.407998},
+  {1.131680,-0.756558},
+  {0.414796,-1.380356},
+  {-0.696230,-1.001295},
+  {-0.356978,0.947810},
+  {0.203772,-1.057518},
+  {-0.328018,0.786771},
+  {0.943286,1.338451},
+  {-1.157899,-0.594093},
+  {0.126929,1.437347},
+  {1.125664,-0.410598},
+  {1.476748,-0.336433},
+  {0.391183,0.754958},
+  {-0.538390,1.039711},
+  {0.539183,0.253245},
+  {-0.738926,-1.328143},
+  {0.843172,-0.517204},
+  {-1.094296,0.432451},
+  {-0.207836,0.579061},
+  {-0.780287,-0.213072},
+  {0.251006,-0.069137},
+  {0.847453,0.521498},
+  {-0.110487,-0.550587},
+  {1.366744,0.051771},
+  {0.111898,-0.116679},
+  {0.457595,0.211260},
+  {-0.224542,-0.247515},
+  {-0.075318,-0.913189},
+  {0.413131,0.636904},
+  {0.442816,-0.725927},
+  {-0.269415,-1.101203},
+  {1.238631,-0.048564},
+  {-0.867622,-0.029135},
+  {-1.272665,-0.426738},
+  {-0.358993,1.214374},
+  {0.223994,0.430413},
+  {-0.069366,-0.065533},
+  {-1.151986,-0.046081},
+  {-0.034817,-0.587513},
+  {0.820362,-0.805810},
+  {-0.002677,-0.479108},
+  {-0.501825,-0.402321},
+  {0.479133,0.520280},
+  {-0.023935,0.157521},
+  {-0.805270,-0.213889},
+  {-0.652714,-1.133157},
+  {0.141114,0.750052},
+  {-0.870557,0.131878},
+  {-0.537313,0.243984},
+  {0.270492,1.388730},
+  {0.351691,-1.026747},
+  {0.265859,-0.073035},
+  {0.876907,0.008793},
+  {-0.015669,0.222651},
+  {-0.458046,-0.172892},
+  {0.480864,-0.236468},
+  {-0.304051,0.883748},
+  {1.386217,0.196728},
+  {-0.448091,0.725679},
+  {0.279281,1.432388},
+  {-1.090792,-0.202419},
+  {0.531809,-0.405696},
+  {-0.038049,0.323853},
+  {-0.027231,-0.016436},
+  {-0.716140,-0.504110},
+  {0.323352,-0.270107},
+  {-0.253368,-1.019154},
+  {-0.779463,-0.217103},
+  {-0.579380,-0.994819},
+  {1.349996,0.012975},
+  {0.343522,-0.422818},
+  {0.277107,-1.468269},
+  {1.635924,-0.133051},
+  {-0.184484,0.613490},
+  {0.452174,1.169168},
+  {-0.116411,0.804015},
+  {-0.040472,0.200894},
+  {-0.451595,0.380316},
+  {-0.018660,-0.980569},
+  {1.037949,1.233064},
+  {1.095728,0.983920},
+  {0.472751,-0.243982},
+  {0.234380,0.303549},
+  {-0.706062,1.365919},
+  {-1.056416,-0.147830},
+  {0.003918,0.621718},
+  {-0.866214,-0.038261},
+  {0.019575,-0.379413},
+  {0.205000,0.142153},
+  {-0.272811,0.136060},
+  {-1.150797,-1.754010},
+  {0.777102,0.334033},
+  {0.144743,0.082452},
+  {0.409845,1.246999},
+  {-0.848828,-0.844270},
+  {0.336356,1.069431},
+  {-0.261880,0.472035},
+  {-0.274440,-0.250428},
+  {0.096055,1.333042},
+  {-1.150019,-0.005824},
+  {-0.345565,1.491009},
+  {0.434845,0.644814},
+  {-0.995453,0.103214},
+  {-0.248426,-0.545754},
+  {0.087275,1.536388},
+  {-1.950359,0.672084},
+  {0.687779,0.938171},
+  {0.592318,-0.358229},
+  {0.719642,-0.071983},
+  {-0.080845,0.708763},
+  {0.136255,-1.235083},
+  {-0.251003,-0.912274},
+  {-0.884002,-0.310324},
+  {0.031525,0.320763},
+  {0.556086,-0.250977},
+  {0.090584,0.172983},
+  {-0.360676,0.948733},
+  {-0.090851,0.465571},
+  {-0.059321,0.271202},
+  {0.377821,0.928997},
+  {-2.122083,-0.662680},
+  {0.606876,-0.740523},
+  {0.304647,-1.075289},
+  {0.104366,0.294334},
+  {-0.618571,-1.125453},
+  {0.347400,-0.197963},
+  {0.740467,-0.980580},
+  {0.567211,0.587097},
+  {-0.009102,0.368841},
+  {0.365819,1.246754},
+  {0.408926,-0.573655},
+  {0.629943,0.031990},
+  {-0.888191,-1.455036},
+  {-0.192010,-1.721713},
+  {-0.525795,-0.883365},
+  {-0.688342,-0.233976},
+  {-1.231810,0.919714},
+  {-0.171857,0.047815},
+  {0.829192,0.498064},
+  {-0.164813,0.833731},
+  {-0.835674,1.420757},
+  {0.117641,0.408307},
+  {0.061907,-0.340905},
+  {0.328647,0.483077},
+  {-0.334550,-0.634442},
+  {-1.143177,0.176319},
+  {0.945986,-0.429932},
+  {0.962872,-0.156957},
+  {0.316408,-0.309555},
+  {-0.071834,0.467993},
+  {0.374919,0.531204},
+  {-0.061652,-0.441122},
+  {0.296652,-0.735807},
+  {0.635521,0.547129},
+  {-0.820187,-0.119987},
+  {-0.256993,-0.874678},
+  {-1.176903,0.375631},
+  {-0.389114,1.458620},
+  {-1.499695,1.086553},
+  {0.662846,-0.346478},
+  {1.134804,0.260529},
+  {-0.353432,0.041867},
+  {0.599759,-0.706760},
+  {0.233411,-0.191501},
+  {0.069271,-0.371072},
+  {-0.299719,-0.158599},
+  {0.156862,0.287897},
+  {0.044521,-1.565973},
+  {0.647652,-0.050318},
+  {-0.625813,0.313538},
+  {-0.305193,0.707469},
+  {-0.889292,-0.615903},
+  {0.108968,0.323345},
+  {0.891658,0.530089},
+  {-0.619121,0.542110},
+  {-0.173821,-0.076271},
+  {-0.066656,-0.380613},
+  {1.201157,-0.868830},
+  {-0.269634,-0.547771},
+  {-0.166608,0.337899},
+  {-0.580004,0.028538},
+  {-0.178471,0.256375},
+  {0.479790,-0.353481},
+  {-0.141978,-0.140536},
+  {0.573456,-1.096426},
+  {-1.407537,0.376742},
+  {-0.000291,-0.159343},
+  {0.566129,1.021878},
+  {0.592375,0.213044},
+  {-1.093385,-0.195052},
+  {-1.227213,-0.283957},
+  {-1.107600,-0.512341},
+  {0.405843,-0.034674},
+  {-0.628223,-1.573836},
+  {-0.424388,-1.127573},
+  {1.352502,0.703620},
+  {0.260965,0.940215},
+  {0.564688,-0.617820},
+  {0.627958,-1.090734},
+  {-0.519309,-0.170822},
+  {-0.018574,0.160240},
+  {0.581393,0.735974},
+  {-1.723723,-0.001348},
+  {0.426947,0.152603},
+  {1.732577,-0.140408},
+  {0.733090,-1.014674},
+  {0.548625,-0.606929},
+  {-0.104524,-0.976971},
+  {0.002059,0.365576},
+  {-0.437915,-0.973652},
+  {0.409557,-0.489978},
+  {-0.000720,0.508669},
+  {0.256095,-1.595859},
+  {0.287175,0.564402},
+  {0.876617,-1.300599},
+  {-0.980624,0.538104},
+  {-0.197058,-0.835753},
+  {0.293510,1.023684},
+  {-1.124246,-0.346680},
+  {1.728107,0.223808},
+  {0.608823,0.314713},
+  {-0.678436,-0.934938},
+  {0.467041,-0.286489},
+  {0.304061,0.659360},
+  {0.433362,-0.114714},
+  {0.470833,0.482791},
+  {0.136415,0.001946},
+  {-0.192213,1.062735},
+  {1.160425,1.197857},
+  {0.570082,-0.708591},
+  {-0.674925,-0.979498},
+  {0.258815,-0.140179},
+  {0.765330,0.060888},
+  {-1.138194,-0.547729},
+  {-0.342221,-0.331377},
+  {0.487680,-0.431774},
+  {0.195766,-0.563726},
+  {-0.515654,-2.231175},
+  {-0.514830,1.422505},
+  {-0.818513,0.454493},
+  {0.380391,0.182849},
+  {-0.069606,1.071475},
+  {-1.175893,0.278782},
+  {-1.024879,-0.018088},
+  {0.047685,-0.767415},
+  {-0.451445,0.575550},
+  {0.806845,-0.635450},
+  {0.137154,0.051450},
+  {0.484762,0.473028},
+  {1.476065,-0.375153},
+  {0.038745,0.227390},
+  {1.613348,-0.285214},
+  {0.027663,-0.441607},
+  {0.327132,0.393034},
+  {0.097041,1.118078},
+  {-1.373910,-0.535039},
+  {-0.830631,0.886098},
+  {0.712699,0.117282},
+  {-0.435669,0.900266},
+  {-0.230984,0.260017},
+  {-1.134322,0.277879},
+  {1.217344,0.070220},
+  {-0.322548,0.229832},
+  {-0.912984,1.081382},
+  {0.945157,-0.653585},
+  {0.109940,-0.208093},
+  {-0.750971,-0.827736},
+  {0.077654,-0.623765},
+  {1.218827,-0.344685},
+  {-0.313002,0.296601},
+  {0.400554,0.568839},
+  {0.304519,-0.601576},
+  {0.373664,1.261417},
+  {0.019345,0.795808},
+  {-0.078023,-0.626856},
+  {0.116647,0.074558},
+  {0.563238,-0.563330},
+  {-2.463399,0.442332},
+  {-0.109267,0.048086},
+  {0.519121,0.180174},
+  {0.193848,-0.161425},
+  {-0.042920,0.296486},
+  {0.073707,-1.348922},
+  {0.617742,-0.148470},
+  {0.261979,-0.030175},
+  {1.197662,-1.031986},
+  {-0.180963,0.326171},
+  {-0.182722,0.138127},
+  {0.333006,-0.298385},
+  {0.118052,0.145749},
+  {-0.378857,-0.353684},
+  {-0.874132,-0.138412},
+  {1.049590,-0.258466},
+  {-0.227425,0.931924},
+  {0.060564,0.378351},
+  {0.371015,-0.349550},
+  {-0.143444,-0.217476},
+  {-0.247485,-0.046193},
+  {-0.765423,0.386454},
+  {0.075810,0.747783},
+  {-0.562521,-0.075906},
+  {0.409856,-0.469514},
+  {-0.135998,-0.492786},
+  {0.986502,-0.462649},
+  {-0.068894,0.801619},
+  {-0.162736,0.525729},
+  {-0.453916,0.283674},
+  {-0.123426,-1.358265},
+  {1.200608,-0.396901},
+  {0.577734,-0.019945},
+  {-0.436619,0.346352},
+  {0.830315,0.899719},
+  {-0.064963,1.026769},
+  {-0.019483,-1.140266},
+  {-0.248584,0.297740},
+  {-0.203858,0.942282},
+  {-0.081061,-0.362369},
+  {0.963064,0.245140},
+  {-0.061346,0.970336},
+  {-1.223766,-1.442024},
+  {-0.659296,-0.305137},
+  {-0.168098,0.526909},
+  {0.244864,0.201375},
+  {-1.037356,-0.409374},
+  {-0.342768,0.074298},
+  {-0.126356,0.583275},
+  {0.700812,0.148717},
+  {1.123453,-0.594402},
+  {-0.880209,-0.000771},
+  {0.508231,0.583812},
+  {0.461500,-1.305179},
+  {-0.352762,-0.342643},
+  {0.026590,1.641167},
+  {0.172356,-0.551779},
+  {0.624259,1.319173},
+  {-0.343181,0.521502},
+  {-0.377493,0.564330},
+  {0.463338,0.107471},
+  {-1.020304,0.501309},
+  {1.214700,-0.385908},
+  {0.246930,0.896288},
+  {-1.150099,0.525414},
+  {0.598091,-0.621490},
+  {-0.551424,0.044236},
+  {0.503002,0.175473},
+  {-0.326038,0.203589},
+  {0.000174,-0.755465},
+  {-0.076286,0.193240},
+  {0.751071,-0.851721},
+  {-1.638472,-0.078066},
+  {0.277348,0.196780},
+  {0.017669,-0.946993},
+  {-0.808836,0.460763},
+  {0.389572,-0.585954},
+  {-0.536593,-0.448112},
+  {0.668181,-0.374583},
+  {-0.103420,-0.222061},
+  {0.033553,0.915602},
+  {-0.727955,-0.942821},
+  {0.227992,-0.544748},
+  {0.215369,0.016803},
+  {-0.331175,-0.358666},
+  {-0.369147,-1.683768},
+  {0.287561,1.754403},
+  {0.730502,1.075420},
+  {0.098139,0.193287},
+  {-0.220536,-0.547638},
+  {-0.708086,0.229183},
+  {-0.066645,0.221207},
+  {-0.544498,0.224689},
+  {0.909845,0.066686},
+  {-0.417147,-1.561040},
+  {-0.588530,-0.271389},
+  {0.765381,0.630382},
+  {-1.536043,0.954170},
+  {-0.007504,-0.251426},
+  {0.320371,-0.415162},
+  {-1.079865,-0.015651},
+  {1.246319,-0.288800},
+  {1.664357,0.873397},
+  {1.274888,-0.286462},
+  {0.089238,0.521546},
+  {-0.850328,-0.204610},
+  {-1.344064,-0.175840},
+  {1.059629,0.597417},
+  {1.396640,-0.558153},
+  {-1.299523,-0.700533},
+  {-0.303029,-0.016323},
+  {-0.571055,-0.101430},
+  {0.240632,-0.156008},
+  {-0.210472,-0.676508},
+  {-0.377210,-0.257232},
+  {-0.458563,0.394798},
+  {-1.298114,0.535994},
+  {0.348716,1.486169},
+  {-0.551518,0.095552},
+  {-0.454461,0.613793},
+  {0.589896,0.608956},
+  {0.024315,-0.615423},
+  {0.108640,0.657051},
+  {0.277486,0.095590},
+  {0.112263,0.590235},
+  {-1.676875,0.295265},
+  {-0.641851,0.429911},
+  {0.112035,-0.999186},
+  {0.407359,1.310697},
+  {0.123607,-0.285048},
+  {-0.584768,0.856268},
+  {0.365845,-1.606895},
+  {0.118025,0.980790},
+  {0.976487,-0.548793},
+  {-0.608533,0.177190},
+  {-0.254552,0.490015},
+  {-0.764686,-0.476040},
+  {0.339780,0.307140},
+  {1.071418,-0.394981},
+  {0.343840,-0.138409},
+  {0.050959,0.206412},
+  {-0.132190,1.024308},
+  {-0.531174,-0.997495},
+  {0.107836,0.197144},
+  {0.006508,0.051268},
+  {-1.180682,-0.078210},
+  {-0.301054,0.221919},
+  {-0.198790,-2.154487},
+  {1.281974,-0.406055},
+  {0.248667,0.220739},
+  {-0.151733,0.572224},
+  {-0.887702,-0.282886},
+  {-0.035221,0.961347},
+  {-1.071469,0.514402},
+  {-1.341250,0.603023},
+  {-0.080709,0.493279},
+  {0.437681,-0.565973},
+  {0.221259,1.582183},
+  {-0.409386,0.729511},
+  {0.982076,-0.071098},
+  {-1.001791,-0.519130},
+  {-0.121082,-0.007075},
+  {-0.339436,1.234458},
+  {1.513595,0.969100},
+  {-0.583819,0.253911},
+  {0.177078,-0.732721},
+  {1.010067,0.995855},
+  {-1.355505,0.888006},
+  {-0.332757,0.204762},
+  {0.021403,1.025592},
+  {-1.217885,0.139156},
+  {0.889080,0.092179},
+  {-1.102149,0.293526},
+  {0.435463,-0.449178},
+  {0.080275,0.169176},
+  {-0.709930,-1.149043},
+  {0.196490,-0.626610},
+  {0.000069,-0.943691},
+  {0.223655,0.039723},
+  {-0.560770,-0.882470},
+  {-0.807256,0.094114},
+  {-0.058225,-0.349692},
+  {-0.500905,-1.096078},
+  {-0.962775,0.327158},
+  {0.282785,-0.401214},
+  {0.361234,-0.934402},
+  {0.576734,-0.359076},
+  {-1.413799,0.265539},
+  {-1.117609,-0.837082},
+  {0.180753,-0.472530},
+  {-0.120835,-0.959192},
+  {-0.157811,0.176422},
+  {-0.850684,0.325782},
+  {0.828223,0.792925},
+  {0.054204,0.579626},
+  {-1.121286,-0.414842},
+  {-0.113676,0.001080},
+  {0.642904,0.453393},
+  {-1.026285,0.939691},
+  {0.521202,0.352828},
+  {0.456312,-0.206836},
+  {0.058434,-0.053600},
+  {0.115901,0.497408},
+  {1.204157,-0.447713},
+  {0.345992,-0.395337},
+  {0.164925,1.328079},
+  {0.069910,0.657455},
+  {0.884794,0.478670},
+  {0.805589,0.626931},
+  {-0.169274,-0.328030},
+  {-0.535077,0.102330},
+  {-0.946526,0.154656},
+  {0.358642,-1.362812},
+  {-0.676983,-0.652080},
+  {0.992864,-0.004017},
+  {-0.410549,0.342659},
+  {-1.235267,0.713491},
+  {-0.398621,0.103696},
+  {-0.820035,0.801927},
+  {1.200059,0.099361},
+  {0.165502,0.725726},
+  {-0.591579,0.903920},
+  {-0.843723,0.547834},
+  {0.773809,0.403580},
+  {-0.110340,-0.128695},
+  {-0.642852,0.256573},
+  {0.020826,-0.020841},
+  {-2.163248,0.136883},
+  {-0.964862,0.387295},
+  {0.687709,0.453517},
+  {-0.112839,-0.567023},
+  {-0.409633,0.580404},
+  {-0.395668,1.251119},
+  {0.347308,-0.652184},
+  {1.734678,-0.822788},
+  {0.601811,-0.259379},
+  {0.378296,-0.866471},
+  {0.498403,-0.656762},
+  {0.504824,0.489810},
+  {0.639843,0.108016},
+  {-0.224104,0.234376},
+  {0.009714,-1.168003},
+  {0.019711,0.237093},
+  {0.442850,0.092101},
+  {0.202559,0.660920},
+  {-0.738652,-1.371965},
+  {-1.297719,0.932182},
+  {0.739608,1.592722},
+  {0.287503,-0.045919},
+  {1.222096,-0.184544},
+  {-0.022342,-1.348633},
+  {-0.384473,0.250028},
+  {0.001750,-0.224717},
+  {-0.339904,-0.227850},
+  {-0.775438,-1.310795},
+  {0.571535,0.293371},
+  {-0.324597,0.227490},
+  {0.169930,1.145261},
+  {-1.551123,-0.199599},
+  {0.903788,-0.358227},
+  {-0.622574,-0.635810},
+  {-0.045168,1.216837},
+  {0.093370,2.013175},
+  {-0.171013,-0.524670},
+  {0.035948,0.841222},
+  {-0.592962,0.383082},
+  {0.304794,-0.702133},
+  {0.779021,0.240417},
+  {1.021212,0.841250},
+  {-0.373074,-0.296006},
+  {-0.522088,1.139662},
+  {-0.268210,-0.251780},
+  {-0.668865,-0.925004},
+  {-0.197566,0.255127},
+  {1.441911,1.117605},
+  {0.359801,0.069378},
+  {0.485969,-1.028166},
+  {0.009410,1.004055},
+  {-0.386974,-1.624570},
+  {0.923300,0.143629},
+  {0.181342,0.541303},
+  {0.292919,0.079149},
+  {0.324985,-0.714574},
+  {1.032349,-0.142324},
+  {-0.163295,0.054984},
+  {-1.028432,-0.229401},
+  {0.459060,-0.443054},
+  {-0.236741,-0.785944},
+  {-0.703899,-1.736899},
+  {-0.586833,-0.513491},
+  {-1.517056,-0.084420},
+  {0.292003,-0.016637},
+  {0.700051,-0.583601},
+  {0.526109,0.250151},
+  {-0.227784,-0.209721},
+  {1.818833,-0.253432},
+  {-0.360458,-0.668042},
+  {0.666832,-0.166561},
+  {-0.358616,-0.418329},
+  {-0.412887,0.836863},
+  {0.467107,0.455230},
+  {0.592494,1.202728},
+  {-0.049518,-0.533706},
+  {-1.002130,0.544990},
+  {-0.257809,-0.145484},
+  {-0.507467,-0.453834},
+  {0.291788,0.724311},
+  {-0.135188,0.157332},
+  {0.631982,0.964860},
+  {-1.346895,0.067204},
+  {-0.288235,0.488706},
+  {-2.477087,1.241502},
+  {-0.518612,-0.435361},
+  {0.955342,0.489972},
+  {1.169275,0.407173},
+  {0.213697,0.494150},
+  {1.485172,0.045033},
+  {0.153003,0.092241},
+  {-0.308640,-0.601813},
+  {-0.228943,0.489280},
+  {-1.169407,-1.772660},
+  {0.178640,0.792597},
+  {-0.165417,0.292843},
+  {1.369952,-1.611009},
+  {0.852707,-0.827966},
+  {0.821978,-0.004446},
+  {0.649031,-0.812858},
+  {0.973973,-0.310191},
+  {-0.044568,-1.440362},
+  {0.765165,-0.538318},
+  {0.073737,0.997220},
+  {1.234533,0.305244},
+  {0.063294,0.158006},
+  {0.169849,0.859146},
+  {-0.719410,-1.068298},
+  {0.116258,-0.709057},
+  {-0.930144,-0.632747},
+  {-0.181414,-0.975216},
+  {0.795997,0.192359},
+  {0.066111,-1.055039},
+  {-0.298799,-0.559138},
+  {-0.603013,-0.082259},
+  {0.209757,1.372754},
+  {0.347500,0.495824},
+  {0.676474,-0.072774},
+  {0.550261,-1.227179},
+  {-0.263165,0.041038},
+  {-0.546702,-0.491019},
+  {0.738601,-0.021821},
+  {-0.575464,-0.045919},
+  {0.123871,-0.075287},
+  {-1.083198,-1.254586},
+  {-0.183814,-1.052704},
+  {-0.881953,0.291254},
+  {0.295336,-0.371557},
+  {0.023762,-0.165479},
+  {0.922082,0.683317},
+  {0.324383,-0.491146},
+  {1.171481,-0.557506},
+  {0.470032,0.663233},
+  {-0.433687,0.881275},
+  {0.569872,1.163325},
+  {-1.147629,1.276498},
+  {-1.667829,0.173502},
+  {1.509836,-0.393443},
+  {0.061339,-0.994588},
+  {1.297176,-0.289000},
+  {-0.222211,1.274974},
+  {0.171856,-0.708127},
+  {-0.762371,0.928647},
+  {0.489001,-0.717858},
+  {0.273726,-0.144006},
+  {0.089858,0.479527},
+  {-0.415939,-0.754283},
+  {-0.820428,-1.308644},
+  {0.246597,0.476980},
+  {-0.061898,-0.518679},
+  {-0.002501,-0.563025},
+  {0.160470,-0.497633},
+  {0.654653,-0.058246},
+  {-0.346737,0.304705},
+  {-0.730579,-0.133753},
+  {0.332384,0.151924},
+  {-0.769060,0.340191},
+  {-0.946356,0.802338},
+  {-0.185563,-0.701926},
+  {-0.018478,0.385360},
+  {-0.763889,-0.171119},
+  {0.136434,-1.151131},
+  {0.944360,0.351269},
+  {0.234035,0.460682},
+  {-0.126511,-0.343346},
+  {-0.129577,0.714668},
+  {0.831803,1.425489},
+  {-0.311698,0.471973},
+  {0.374336,-0.532622},
+  {-1.287929,0.086859},
+  {-0.960906,-0.551099},
+  {-1.322977,0.426687},
+  {0.566247,-1.476259},
+  {-0.042332,-0.595204},
+  {-0.217199,0.570666},
+  {-0.336883,0.586814},
+  {0.991186,1.090638},
+  {-0.112997,0.343201},
+  {0.936285,0.699872},
+  {1.134616,0.605336},
+  {-0.332672,0.412190},
+  {-0.131705,-0.706994},
+  {0.966135,0.922373},
+  {1.133423,-0.652360},
+  {-1.177552,-0.186519},
+  {0.708659,-0.078514},
+  {-0.951753,-0.658081},
+  {0.498906,0.236519},
+  {0.282086,-1.164112},
+  {0.256290,-0.187041},
+  {0.292859,-0.420021},
+  {0.670422,-0.359978},
+  {-0.031479,-0.211732},
+  {-0.243913,-0.094388},
+  {-0.214352,0.162763},
+  {-0.671425,1.172721},
+  {-0.345164,-0.766127},
+  {-0.628780,-0.950380},
+  {-0.275698,0.202610},
+  {-0.358559,0.974356},
+  {0.409593,0.965904},
+  {-0.287768,-0.284934},
+  {-0.817917,0.034221},
+  {0.282824,-0.083509},
+  {0.266940,0.414989},
+  {-0.839039,0.602647},
+  {-0.030358,-0.143335},
+  {-0.461787,-1.323753},
+  {-0.947434,0.034506},
+  {0.206777,0.393953},
+  {0.110051,0.039027},
+  {-0.255445,-0.418588},
+  {-0.824977,-0.529115},
+  {-0.847940,0.003400},
+  {-0.227448,-0.605217},
+  {-0.658428,-0.129496},
+  {-0.070069,-0.874316},
+  {-0.452178,-0.509891},
+  {0.006794,0.737596},
+  {-0.173131,-0.491329},
+  {-0.018882,0.037139},
+  {1.012352,-1.428883},
+  {0.341480,-0.177353},
+  {0.088907,1.263644},
+  {-0.007106,-0.035769},
+  {0.494848,-0.291677},
+  {1.029770,1.640336},
+  {-0.019924,-0.576639},
+  {1.078143,0.161988},
+  {-1.158261,-0.009208},
+  {-0.920354,0.385655},
+  {-0.103172,-0.424669},
+  {-0.128917,0.361840},
+  {0.451312,-0.151329},
+  {0.486818,-0.792695},
+  {0.173666,-0.625128},
+  {-1.227586,0.233996},
+  {-0.567889,0.022017},
+  {-0.012878,0.076646},
+  {-0.423646,0.335511},
+  {-0.989293,1.156415},
+  {-0.977194,0.382489},
+  {-1.465169,0.221222},
+  {-0.821043,-0.880370},
+  {0.953556,0.320459},
+  {-0.493348,1.015682},
+  {-0.041491,-1.401656},
+  {0.110917,-1.090802},
+  {-0.787109,0.792470},
+  {-1.183552,-0.605356},
+  {-0.466455,0.123053},
+  {1.377708,0.488188},
+  {1.036160,-0.429887},
+  {-0.195443,0.367498},
+  {-0.649320,-0.214917},
+  {0.818471,-0.314367},
+  {-1.095956,-1.066370},
+  {1.010551,1.357206},
+  {-0.522272,-1.266004},
+  {0.742807,-0.658170},
+  {0.137677,-0.996820},
+  {-0.269035,-0.313754},
+  {0.231487,1.580343},
+  {0.050224,-0.237917},
+  {0.022147,0.008968},
+  {-0.118094,-0.562883},
+  {0.746369,-0.220601},
+  {0.103125,-1.486236},
+  {-0.018752,0.345496},
+  {-0.026367,0.124820},
+  {-0.095584,0.426964},
+  {0.299398,-0.036745},
+  {0.876858,0.071707},
+  {0.080784,0.101691},
+  {-0.365802,-0.832668},
+  {-0.066045,-0.042815},
+  {-1.336839,-0.309595},
+  {-1.855670,0.090094},
+  {0.142864,0.213680},
+  {0.170087,-0.748118},
+  {0.757840,-0.487161},
+  {-0.008566,0.015099},
+  {-0.574190,0.366625},
+  {0.850847,-0.670065},
+  {-0.088781,-0.552472},
+  {0.065881,-0.562275},
+  {2.174229,-0.693270},
+  {0.545383,0.173825},
+  {0.179404,-1.118853},
+  {-0.706263,0.644413},
+  {-0.201256,0.026020},
+  {0.371367,0.027994},
+  {0.695924,-0.856474},
+  {-0.068587,-0.377147},
+  {-1.335474,-0.381794},
+  {-0.705342,-0.264330},
+  {1.211854,0.734180},
+  {0.689579,-0.829674},
+  {0.236230,-0.519350},
+  {-0.373274,-0.203030},
+  {0.522275,0.190464},
+  {-0.984102,0.184132},
+  {0.608537,0.528305},
+  {0.645580,-0.632723},
+  {0.106191,-1.924526},
+  {-0.860820,0.172286},
+  {-0.017002,-0.413171},
+  {-0.870914,-0.915141},
+  {-0.032162,-0.022238},
+  {1.063524,0.208230},
+  {0.208620,0.392565},
+  {1.534353,0.353688},
+  {0.503624,0.611747},
+  {1.441714,0.373080},
+  {-1.685419,0.553616},
+  {-1.251072,1.088477},
+  {0.030551,0.653043},
+  {0.348223,-0.875562},
+  {-0.158646,-1.827145},
+  {-0.599854,-1.150166},
+  {-0.622279,1.015380},
+  {-0.045192,0.068378},
+  {0.289380,0.241892},
+  {0.780663,-0.317637},
+  {-0.624796,-0.111034},
+  {0.156313,0.625074},
+  {-0.887464,0.338653},
+  {0.276127,-1.089799},
+  {0.393729,-0.259418},
+  {0.290756,0.344205},
+  {-1.690691,0.271341},
+  {1.070050,-0.375246},
+  {-0.518340,-0.146201},
+  {-0.136899,-0.031255},
+  {-0.732118,0.763056},
+  {0.595604,-0.170473},
+  {0.313932,0.752164},
+  {1.258402,-0.021841},
+  {-1.271193,0.594328},
+  {1.074153,0.128659},
+  {0.478066,-0.276071},
+  {-0.358573,0.984028},
+  {0.423156,0.233965},
+  {-0.177399,0.151124},
+  {0.079737,0.146108},
+  {-0.800067,-0.511673},
+  {0.506933,-0.549296},
+  {0.699370,-0.759465},
+  {0.195093,1.236176},
+  {0.557245,1.418542},
+  {0.287210,1.479131},
+  {0.668788,-0.448889},
+  {-0.463056,0.926393},
+  {1.124722,-0.224757},
+  {1.118837,-0.244739},
+  {-0.214775,0.121754},
+  {-0.086324,-0.784099},
+  {1.274702,0.512876},
+  {1.060185,1.325123},
+  {0.193620,0.390433},
+  {-0.286823,0.231843},
+  {-0.351578,0.727546},
+  {-1.647569,0.062221},
+  {0.356859,-0.256082},
+  {0.266346,0.400761},
+  {-0.225153,-0.791734},
+  {0.522282,0.074414},
+  {-0.375861,-0.448761},
+  {-0.533274,0.056055},
+  {-0.400783,-0.040651},
+  {0.436361,0.406416},
+  {0.165936,0.403954},
+  {0.851735,1.253902},
+  {-0.996147,0.302040},
+  {0.979640,0.288274},
+  {-0.020106,-0.155534},
+  {-0.392568,-0.327217},
+  {-0.200327,0.496539},
+  {-0.233763,-0.423968},
+  {-0.976208,-0.408918},
+  {-0.571268,-0.378235},
+  {0.224025,-0.154206},
+  {-0.176338,0.225973},
+  {0.355614,-0.189466},
+  {-0.450087,0.567394},
+  {-0.659818,1.574000},
+  {-0.724889,0.197115},
+  {-1.355431,-0.664189},
+  {-0.203199,0.667343},
+  {-0.361135,0.152712},
+  {-0.007547,-0.222527},
+  {-0.546892,-0.387338},
+  {1.044558,-0.663379},
+  {0.326269,-0.004359},
+  {-0.012900,0.714057},
+  {-0.032278,-0.204936},
+  {-0.152106,0.539984},
+  {-0.484380,-0.174141},
+  {-0.480804,-0.521659},
+  {0.019051,-0.512885},
+  {-0.371011,-0.457457},
+  {0.637777,-0.575044},
+  {1.426366,0.512612},
+  {0.266994,0.797655},
+  {-0.824664,-0.336600},
+  {-0.422137,-0.905715},
+  {0.656471,0.209458},
+  {-0.864761,-0.058947},
+  {1.312581,0.409720},
+  {0.093477,1.303098},
+  {-0.495575,0.491653},
+  {0.616295,0.289625},
+  {0.019085,0.370022},
+  {-1.785266,0.062761},
+  {-0.110044,-0.749797},
+  {1.685633,0.914155},
+  {0.759099,0.624272},
+  {-0.950030,1.223722},
+  {0.414424,-0.410528},
+  {0.183760,-0.081691},
+  {-0.402176,-0.026614},
+  {-0.349344,-0.746451},
+  {-0.669819,0.784265},
+  {0.124418,0.632759},
+  {0.541258,-1.198492},
+  {-0.866841,0.005112},
+  {-0.420861,0.310081},
+  {-0.492845,2.040430},
+  {0.289183,-0.025633},
+  {0.333462,-0.545470},
+  {0.620450,-0.664730},
+  {-0.966239,0.477068},
+  {-0.280518,0.588544},
+  {0.855581,0.526154},
+  {0.176645,-0.532816},
+  {0.243194,-0.347975},
+  {0.121295,1.046375},
+  {0.468586,-0.344088},
+  {-0.350739,-0.403584},
+  {-0.631745,-0.782817},
+  {-0.949273,-1.150875},
+  {0.922169,-1.684543},
+  {-0.345543,-0.015945},
+  {0.837118,0.348048},
+  {-0.849669,0.097854},
+  {-0.950003,-0.284938},
+  {-0.827245,1.274905},
+  {0.582750,0.674266},
+  {0.863202,-0.250190},
+  {0.661880,0.368907},
+  {0.037276,-0.913114},
+  {0.165824,1.259230},
+  {0.058122,0.701148},
+  {-0.309547,-0.432040},
+  {-0.596559,-0.618049},
+  {0.889281,0.852314},
+  {0.257575,-0.140190},
+  {0.466566,-1.164941},
+  {-0.846649,-0.024130},
+  {-0.006130,-0.345342},
+  {0.554810,-0.369790},
+  {0.132936,-1.245072},
+  {-0.708319,-0.243577},
+  {-0.938221,0.593895},
+  {-0.035179,0.513441},
+  {-0.049975,1.127913},
+  {-0.672031,0.159578},
+  {-0.023330,1.155255},
+  {0.143090,1.023505},
+  {0.115199,0.309062},
+  {-1.199697,0.879078},
+  {0.519932,0.063135},
+  {0.186381,0.036151},
+  {-0.474750,1.313004},
+  {-1.041353,0.036701},
+  {-0.089927,-0.772333},
+  {0.090568,-0.837483},
+  {-0.048569,-0.259303},
+  {1.571934,-0.955589},
+  {-0.022494,-0.250567},
+  {-0.308409,0.008499},
+  {-0.198203,-0.449276},
+  {-0.294832,-0.776042},
+  {0.258584,-0.160882},
+  {0.168586,-0.668421},
+  {-0.607039,-0.175648},
+  {-1.595333,0.275002},
+  {0.354293,-1.433081},
+  {-1.076825,0.444679},
+  {0.112063,0.403675},
+  {-0.019937,-0.526304},
+  {0.878192,1.126714},
+  {-0.555291,-0.177409},
+  {0.618919,-1.270440},
+  {-0.718783,-0.636622},
+  {1.023238,-0.542857},
+  {0.482907,0.146108},
+  {1.333821,1.330160},
+  {1.132981,-0.772368},
+  {-0.543637,-0.834221},
+  {0.775740,0.171336},
+  {0.801106,-0.771147},
+  {-0.561803,0.079096},
+  {0.652019,-0.040842},
+  {-0.654772,-0.774603},
+  {0.405766,-0.335507},
+  {-0.131693,-0.202866},
+  {-1.261224,0.358867},
+  {0.573502,0.072986},
+  {-0.658929,-0.659778},
+  {-0.667468,-0.367979},
+  {1.363660,0.358243},
+  {0.355715,0.497317},
+  {0.186055,-0.513256},
+  {-0.427157,-0.478966},
+  {1.490717,-0.058493},
+  {-0.952606,-0.205605},
+  {1.437961,0.595822},
+  {1.113979,0.821148},
+  {-1.993044,0.178065},
+  {0.062770,-1.172124},
+  {-0.601798,-0.508838},
+  {0.404892,0.157432},
+  {0.446296,-0.198539},
+  {-2.000248,-0.062555},
+  {0.418983,-0.605122},
+  {1.044428,1.430575},
+  {-0.225956,0.016324},
+  {0.516675,0.456090},
+  {-0.117366,-0.642548},
+  {0.821745,0.347570},
+  {0.439764,0.695177},
+  {-0.216506,-0.082014},
+  {1.389264,-0.080676},
+  {-0.185223,-0.603367},
+  {-0.860185,-0.740634},
+  {-0.146111,-0.173600},
+  {-0.208919,0.975808},
+  {-0.323668,-0.191408},
+  {0.325369,0.387206},
+  {-1.016963,0.031901},
+  {-0.607601,-1.373026},
+  {-0.029588,1.154785},
+  {-0.134545,-0.252350},
+  {0.776553,-0.133224},
+  {0.543461,0.280061},
+  {-0.890756,-0.743419},
+  {-1.170665,1.021231},
+  {0.518692,-0.016268},
+  {0.959604,0.190010},
+  {-0.985259,-0.574513},
+  {0.772275,-0.572044},
+  {-0.989352,-0.007084},
+  {-0.843395,-0.709321},
+  {-0.701267,0.196028},
+  {-0.479826,0.888804},
+  {1.012193,1.019070},
+  {0.706742,0.197803},
+  {-0.979845,-0.049822},
+  {-0.200635,-0.291375},
+  {0.049786,-0.795526},
+  {1.237530,0.009952},
+  {-1.067907,0.940046},
+  {-0.112405,-0.397752},
+  {-0.046100,-0.102711},
+  {0.453746,0.537092},
+  {-0.187188,-0.759559},
+  {0.717383,-0.561168},
+  {-0.164953,-0.323824},
+  {-0.166557,0.021823},
+  {-0.783368,-0.429656},
+  {0.794975,-0.230617},
+  {-0.527327,-0.780894},
+  {-0.872325,0.014350},
+  {0.054789,0.241499},
+  {0.738298,-0.228210},
+  {0.060773,0.996415},
+  {0.241621,-1.596309},
+  {0.445850,0.578241},
+  {0.315976,1.201028},
+  {-1.511131,-0.670994},
+  {-0.110134,0.130493},
+  {-0.265378,0.556605},
+  {-0.552998,0.389953},
+  {0.085908,0.759607},
+  {-1.029355,0.404668},
+  {0.516605,-0.500285},
+  {-0.014747,0.186171},
+  {-0.662889,0.914909},
+  {1.133404,0.043481},
+  {0.942736,-1.022847},
+  {-1.367925,0.662538},
+  {0.202927,-0.261840},
+  {-0.080038,0.255562},
+  {0.334206,0.344507},
+  {0.909260,0.161783},
+  {0.279950,-0.442240},
+  {-0.132812,1.284395},
+  {0.561415,-0.874174},
+  {-0.040063,0.004187},
+  {0.139506,0.273340},
+  {0.678991,-0.833389},
+  {-1.242484,-0.045382},
+  {0.256214,-0.213426},
+  {-0.587563,-0.587595},
+  {0.078473,0.384032},
+  {-0.277039,1.136410},
+  {-0.092972,-1.062368},
+  {-0.023888,-0.080233},
+  {-0.452956,-0.444322},
+  {1.328310,-0.992490},
+  {-0.474930,0.347850},
+  {0.523240,-0.003848},
+  {-0.051859,0.435035},
+  {0.353494,-0.243220},
+  {-1.096435,1.075703},
+  {-0.289883,0.126013},
+  {1.309579,0.419419},
+  {-0.249474,-1.277937},
+  {0.370228,-0.619822},
+  {-0.162931,-0.986185},
+  {0.529442,0.663374},
+  {0.206235,-0.141314},
+  {0.327230,0.297918},
+  {0.258588,-0.423171},
+  {-0.397341,0.502437},
+  {0.021206,0.592566},
+  {-0.289367,0.413864},
+  {0.910642,0.392091},
+  {-1.057228,-0.461395},
+  {1.001500,0.315649},
+  {-0.090014,-0.918110},
+  {0.318253,0.558070},
+  {0.211192,-0.014893},
+  {0.522386,-0.366099},
+  {0.090398,-0.703867},
+  {1.622834,0.018082},
+  {-0.071737,-1.007484},
+  {-0.664638,-0.104874},
+  {-0.189868,-0.515833},
+  {0.358739,0.281609},
+  {-0.622523,0.089106},
+  {0.361331,0.095296},
+  {1.085784,0.080787},
+  {0.478981,-0.441729},
+  {1.068931,0.439744},
+  {-0.628892,0.424033},
+  {-0.196324,0.379911},
+  {-0.789710,-0.283177},
+  {-0.806679,-1.377374},
+  {1.599832,1.186046},
+  {0.412645,0.144409},
+  {0.327430,1.119619},
+  {1.057958,1.303142},
+  {0.432599,0.474891},
+  {0.284130,-0.147951},
+  {0.137384,-0.946542},
+  {-1.047473,0.054293},
+  {-0.143269,-0.396173},
+  {0.134200,-1.117673},
+  {0.904095,-0.967660},
+  {0.784155,-0.589834},
+  {-0.329207,-1.584818},
+  {1.336969,-0.965850},
+  {0.562061,0.584660},
+  {-0.860259,-0.550482},
+  {0.553302,0.170503},
+  {0.384839,0.442235},
+  {-0.123665,0.795758},
+  {-2.267570,1.579904},
+  {-0.985957,0.263810},
+  {-0.114123,-0.105293},
+  {-0.073897,-0.131005},
+  {0.394013,0.420781},
+  {1.294967,-0.725636},
+  {0.392888,-0.237295},
+  {0.708169,-0.947210},
+  {0.598124,-0.131921},
+  {0.392268,1.238404},
+  {0.565937,-1.492817},
+  {-0.620915,0.218253},
+  {-0.187653,-0.500112},
+  {-0.225466,-0.457223},
+  {0.298875,0.099610},
+  {0.214690,-0.399322},
+  {-0.679138,-0.038895},
+  {0.118053,0.472370},
+  {-0.488826,-0.872846},
+  {-1.119422,-0.036171},
+  {-0.075847,-0.265969},
+  {-1.290590,-1.483111},
+  {0.903551,1.081328},
+  {-0.903254,-0.425745},
+  {-1.654210,-0.592746},
+  {-0.834468,0.360416},
+  {-0.517414,-0.268347},
+  {0.219221,-0.942583},
+  {-0.159846,0.647089},
+  {0.022067,-0.112729},
+  {1.161820,-1.200230},
+  {-1.140920,-0.081036},
+  {-1.039243,-0.377205},
+  {0.314333,0.565306},
+  {-1.575490,0.432187},
+  {0.468719,0.702260},
+  {-0.496647,-0.982869},
+  {0.807580,0.126209},
+  {-1.232223,-0.694859},
+  {0.344013,0.146694},
+  {0.352479,-0.248874},
+  {0.500112,0.240281},
+  {0.150882,0.007734},
+  {1.025832,0.271827},
+  {0.087793,-0.911808},
+  {0.239715,-0.182878},
+  {-0.488536,-1.404765},
+  {0.245387,-0.004696},
+  {-0.830521,0.880491},
+  {0.083542,0.285857},
+  {0.921577,-0.685627},
+  {0.695468,-0.133940},
+  {0.939971,1.828094},
+  {0.789922,0.759310},
+  {0.403211,0.030107},
+  {0.016796,0.689851},
+  {1.084819,-0.186630},
+  {-0.903993,-0.024230},
+  {0.712283,-1.107485},
+  {-0.931592,0.898492},
+  {-0.696849,1.388040},
+  {0.542043,-1.230688},
+  {-0.217901,1.160492},
+  {-0.093252,-0.025223},
+  {-0.766154,0.653670},
+  {-0.042860,0.814345},
+  {-0.196778,-0.716831},
+  {0.540037,0.172703},
+  {-0.361556,-0.529404},
+  {-0.422260,-0.060487},
+  {0.516217,-0.838463},
+  {0.084237,0.024053},
+  {-0.942743,-0.718373},
+  {-0.665473,-0.812679},
+  {-0.055540,0.324464},
+  {-1.050179,0.765823},
+  {0.374960,0.619826},
+  {0.099384,0.440820},
+  {-1.375869,0.145126},
+  {-1.168991,-0.089796},
+  {-0.464068,0.467425},
+  {0.141780,1.426938},
+  {0.483327,1.031467},
+  {-0.966008,-0.779106},
+  {-0.735806,0.516178},
+  {-0.139286,0.109933},
+  {1.469544,0.847398},
+  {0.027674,-0.409753},
+  {-0.025074,-1.939206},
+  {-0.240214,-0.034248},
+  {0.650895,-0.982693},
+  {0.425554,-0.059190},
+  {-0.496271,0.495123},
+  {-1.237870,1.392917},
+  {0.256191,-0.155617},
+  {0.586083,-0.158262},
+  {-0.078923,-0.643073},
+  {-0.331194,-1.453308},
+  {-0.144171,-0.906848},
+  {0.966641,-0.220992},
+  {-0.423391,0.041833},
+  {-0.824277,0.698242},
+  {-0.861274,0.529953},
+  {0.179762,-1.130919},
+  {-0.996767,-0.193545},
+  {0.453175,1.234067},
+  {1.485681,0.094392},
+  {1.051655,0.052776},
+  {-0.134871,0.796853},
+  {0.864630,-0.781504},
+  {0.780484,-0.400513},
+  {0.331109,0.578865},
+  {0.776426,-1.263769},
+  {0.572772,-0.326729},
+  {0.372413,0.005622},
+  {0.941942,-1.305397},
+  {0.303917,-1.556093},
+  {0.189437,1.234819},
+  {0.508129,0.382806},
+  {-1.116871,-0.360450},
+  {0.422168,-0.982315},
+  {0.594919,0.466410},
+  {1.035624,0.463855},
+  {-0.783077,-0.390978},
+  {1.236459,1.182626},
+  {-0.387814,-0.332232},
+  {0.086563,1.162983},
+  {-0.346845,-0.245300},
+  {0.221111,-0.315026},
+  {-0.125533,-0.386266},
+  {1.007383,-1.514431},
+  {0.408173,-0.652894},
+  {-0.444993,0.620328},
+  {-0.081295,0.024145},
+  {-1.171356,0.146286},
+  {-0.654750,-0.194256},
+  {1.094476,0.948711},
+  {-0.885556,-0.313736},
+  {-0.013248,0.284773},
+  {-0.687804,-0.472138},
+  {-0.155912,-1.113625},
+  {-0.819529,0.183507},
+  {1.128618,1.019696},
+  {-0.355820,-0.271205},
+  {-1.577226,0.085216},
+  {0.538217,-0.298420},
+  {0.076116,-0.620804},
+  {0.154589,-1.126306},
+  {0.598211,0.261215},
+  {-1.007944,1.678870},
+  {0.224117,-0.226210},
+  {-1.489159,0.965365},
+  {-0.297128,-0.374228},
+  {0.750106,0.539997},
+  {0.386862,0.676595},
+  {0.966769,-0.407596},
+  {0.384334,-1.359028},
+  {-0.664215,-0.143987},
+  {0.039815,-0.249599},
+  {-1.121556,0.013060},
+  {0.991496,1.175812},
+  {-0.353957,-0.926145},
+  {0.416137,0.633272},
+  {-0.347908,-0.060762},
+  {-1.001857,-1.669313},
+  {0.715754,-0.308980},
+  {0.493890,0.621634},
+  {0.080629,-0.165597},
+  {0.066092,-0.718772},
+  {-0.340841,0.667852},
+  {0.031320,-1.351725},
+  {0.793912,0.365991},
+  {0.094964,0.747321},
+  {-1.342909,0.528676},
+  {-0.173577,-0.344160},
+  {-0.196297,-0.688651},
+  {0.159112,0.542697},
+  {0.329935,0.154517},
+  {1.185337,0.700728},
+  {-0.704310,-0.402117},
+  {-0.316785,-0.310172},
+  {-1.232388,-1.015449},
+  {-0.043209,0.901854},
+  {-0.340189,-2.254502},
+  {-0.603832,0.362719},
+  {0.962932,-0.001934},
+  {1.768897,0.121106},
+  {0.679471,0.866237},
+  {-0.737197,-1.149965},
+  {1.225298,-0.618371},
+  {-0.296798,-1.468710},
+  {-1.678878,0.063437},
+  {0.479002,0.192428},
+  {0.346018,-1.538752},
+  {-1.206099,-0.295383},
+  {1.053135,0.455640},
+  {-0.560954,0.547959},
+  {0.643517,-0.909463},
+  {-0.098024,-0.246867},
+  {0.931635,-0.252753},
+  {0.148997,-0.323576},
+  {0.050144,-0.171018},
+  {-0.267956,0.294251},
+  {0.333497,0.911259},
+  {-0.365215,0.268823},
+  {0.144195,-0.701040},
+  {-1.526851,-0.129927},
+  {1.142833,0.635755},
+  {-0.586324,0.067496},
+  {1.134076,-0.946287},
+  {-0.493528,-0.592981},
+  {-0.425575,0.286177},
+  {0.092149,0.506148},
+  {-0.271803,-1.297036},
+  {0.026268,0.441668},
+  {1.237103,0.694613},
+  {0.582480,-0.500776},
+  {-0.919241,0.616013},
+  {0.539933,-0.765108},
+  {-0.238804,-0.015991},
+  {0.251532,1.010740},
+  {0.018575,1.538529},
+  {1.164247,0.775468},
+  {-0.724490,0.704236},
+  {0.572185,-0.261278},
+  {-0.165192,-0.473733},
+  {-0.275442,-0.214077},
+  {0.529682,0.079349},
+  {-1.043063,0.590297},
+  {-0.312898,0.982987},
+  {-0.347152,-0.300360},
+  {0.198617,-1.545474},
+  {-0.137123,0.206520},
+  {1.406277,0.504897},
+  {-0.230632,-0.020974},
+  {1.165849,1.286086},
+  {0.567973,0.251033},
+  {0.730319,-0.018651},
+  {-1.173668,0.011321},
+  {-0.036457,-0.751900},
+  {-0.615665,0.447886},
+  {-0.452895,-0.069779},
+  {0.673152,-0.178631},
+  {-0.327908,-0.701133},
+  {0.721903,-0.259445},
+  {0.096390,-0.755208},
+  {0.558453,-0.050797},
+  {0.264645,0.199839},
+  {-0.894315,0.312986},
+  {-0.216785,-0.394039},
+  {-1.143224,0.400516},
+  {-1.356620,0.072608},
+  {1.362480,-0.018613},
+  {1.142226,-0.983870},
+  {0.627630,0.620440},
+  {0.660075,-0.739872},
+  {0.579792,-1.280997},
+  {0.651826,0.602429},
+  {1.895455,-0.274354},
+  {-0.906672,-0.429069},
+  {-0.803452,0.029061},
+  {0.481015,1.138218},
+  {1.032808,-0.296512},
+  {-0.832241,0.455665},
+  {0.539383,1.075476},
+  {-0.438440,0.887938},
+  {0.424835,-0.368019},
+  {-0.135554,0.584722},
+  {0.599934,1.286793},
+  {-1.006594,0.727090},
+  {0.911023,0.076265},
+  {0.337550,1.120384},
+  {-0.895655,0.047860},
+  {0.266564,-0.467233},
+  {-0.048357,0.118508},
+  {-0.702445,-0.560325},
+  {0.480256,-1.121399},
+  {0.654894,0.949342},
+  {-0.417652,-0.110876},
+  {0.709040,-0.321438},
+  {-0.238239,-0.984386},
+  {-0.301674,-0.706961},
+  {0.472112,1.348416},
+  {-0.288396,-0.181889},
+  {-0.450683,-0.267402},
+  {-0.308414,-1.071811},
+  {-0.417105,0.973953},
+  {-1.553241,-0.142268},
+  {0.128366,0.111307},
+  {-0.927474,-0.051060},
+  {1.101826,-0.477989},
+  {-0.242754,0.084899},
+  {-0.746846,1.115605},
+  {-1.127438,-0.172875},
+  {-0.155172,-0.399688},
+  {-1.837735,0.530750},
+  {-1.374064,0.363114},
+  {-0.097395,0.053473},
+  {0.609195,-0.274619},
+  {1.734941,0.890505},
+  {0.779686,-0.972688},
+  {0.585193,-1.045163},
+  {0.248025,-0.300921},
+  {-0.152088,0.863592},
+  {0.576776,-0.435392},
+  {-0.660678,-1.619638},
+  {-0.049095,0.111165},
+  {-0.054992,0.933530},
+  {0.502694,0.260923},
+  {-0.330115,-0.374907},
+  {0.738413,0.897929},
+  {-0.134611,-0.079508},
+  {-0.501918,0.744600},
+  {1.092964,0.366548},
+  {-0.569112,-0.575195},
+  {-0.361389,-0.543941},
+  {-0.246589,1.583851},
+  {0.115483,0.436651},
+  {0.709692,-0.027134},
+  {-0.201305,-0.325035},
+  {-0.081069,-0.613508},
+  {-0.204912,0.899014},
+  {-0.052638,-0.313595},
+  {-0.055242,-0.450843},
+  {-1.021730,-0.600249},
+  {0.649428,0.166285},
+  {-0.566037,-0.062804},
+  {0.020980,0.775753},
+  {-0.665180,0.091810},
+  {0.475532,0.480182},
+  {-0.392908,0.497955},
+  {-0.911233,-1.270771},
+  {0.008075,-0.360294},
+  {0.692020,-0.075024},
+  {-0.731113,-0.013576},
+  {0.768481,0.871268},
+  {-0.414806,-0.177137},
+  {-0.085437,-0.311006},
+  {0.611962,0.398797},
+  {-1.456806,0.915209},
+  {0.234176,-0.108086},
+  {0.392467,-0.300692},
+  {-1.290682,-0.075481},
+  {0.661390,0.746033},
+  {-0.613522,-0.349294},
+  {-0.658477,1.050708},
+  {-0.966256,-0.650581},
+  {-0.356483,-0.515624},
+  {0.776759,1.027077},
+  {-1.230686,-1.756435},
+  {1.443473,0.351437},
+  {-1.627666,0.332377},
+  {-0.893450,0.724938},
+  {-1.214274,0.674931},
+  {0.575030,-1.220913},
+  {0.436178,-0.146204},
+  {0.255927,-0.642819},
+  {0.837765,0.357972},
+  {0.413942,0.336704},
+  {-0.491814,0.029299},
+  {0.577770,-0.709864},
+  {0.618412,-0.094846},
+  {1.113511,0.720462},
+  {-1.276252,-1.169819},
+  {-0.221518,0.034718},
+  {1.175932,0.480262},
+  {-1.089821,-0.091391},
+  {-0.050210,0.483209},
+  {0.570865,-0.312307},
+  {0.218860,-0.555332},
+  {0.085193,0.903061},
+  {-0.177520,-0.161550},
+  {-0.920380,-0.285077},
+  {1.144318,-0.822307},
+  {-0.443889,-0.246271},
+  {1.751176,0.442665},
+  {-0.171192,0.036515},
+  {1.478796,0.623020},
+  {0.988539,-0.047767},
+  {-0.656993,1.766078},
+  {0.175814,-0.815643},
+  {0.621924,0.409207},
+  {-0.576310,0.039971},
+  {-1.353919,-0.486915},
+  {-0.387561,-1.061818},
+  {-0.119924,1.290992},
+  {-0.230595,-0.112278},
+  {-0.740619,-0.035881},
+  {0.143479,-1.215912},
+  {0.210367,1.334086},
+  {-0.308564,-0.243013},
+  {-0.152059,-0.489945},
+  {-0.321632,0.092499},
+  {1.924499,-0.416900},
+  {-0.096596,-0.427458},
+  {0.269636,0.757454},
+  {-0.150174,-0.186291},
+  {0.865667,-0.424643},
+  {0.370408,0.371389},
+  {-0.766370,-0.272893},
+  {-0.222344,0.995829},
+  {-0.468779,1.033146},
+  {-0.149001,0.896831},
+  {-0.755959,-1.024279},
+  {1.217738,-0.762323},
+  {0.534823,0.219960},
+  {-0.070087,-0.996893},
+  {0.319844,-0.482557},
+  {0.360326,-1.036808},
+  {0.175977,0.088674},
+  {-1.461705,0.208011},
+  {0.077773,-0.162524},
+  {0.054694,-0.539832},
+  {-0.096807,0.513069},
+  {-0.100006,0.909039},
+  {1.406467,-0.680385},
+  {-0.474095,0.657180},
+  {-0.266534,-0.258199},
+  {-0.155174,0.776743},
+  {-0.786856,-1.189942},
+  {-0.191945,-0.142069},
+  {1.405201,0.141338},
+  {0.792400,0.879229},
+  {0.517136,-0.068225},
+  {-0.073672,0.710877},
+  {-0.308993,-0.293807},
+  {-0.242238,0.739423},
+  {0.319612,1.603955},
+  {0.275246,-1.560017},
+  {0.990727,0.848362},
+  {0.559344,-0.346077},
+  {-1.078959,-0.356477},
+  {-0.070324,0.894042},
+  {-0.528587,0.035779},
+  {-1.258713,0.379885},
+  {-0.290864,0.053989},
+  {-0.225357,-0.508803},
+  {-0.752478,-0.581330},
+  {0.126417,-0.906446},
+  {-0.993092,0.097985},
+  {0.016474,1.418872},
+  {-0.886978,1.124599},
+  {-0.864118,0.032904},
+  {0.105550,0.529514},
+  {-0.447701,-0.032437},
+  {-0.815386,0.312394},
+  {1.531759,0.864403},
+  {0.463851,-0.299624},
+  {1.193057,-0.699033},
+  {-0.904051,1.118158},
+  {-0.019004,-0.938424},
+  {0.479988,-0.435766},
+  {0.614927,0.556017},
+  {-0.620773,0.176160},
+  {-0.040731,-0.961046},
+  {1.396722,0.475938},
+  {-0.651834,-0.578144},
+  {-1.231469,0.391926},
+  {0.074102,0.218066},
+  {-0.780426,0.939099},
+  {0.266873,0.597431},
+  {0.035461,-0.147601},
+  {-0.041518,-1.551616},
+  {-0.652796,0.186071},
+  {-0.515741,0.854016},
+  {0.260025,-0.565384},
+  {-0.507427,-1.442764},
+  {1.156603,-0.625163},
+  {-0.277430,-0.146397},
+  {0.786110,-0.385100},
+  {0.187860,0.259149},
+  {-0.708870,0.857568},
+  {0.258114,-0.517658},
+  {-1.593806,1.354268},
+  {0.769054,1.115951},
+  {-0.320025,0.831390},
+  {0.362127,-0.478752},
+  {0.463627,-0.562727},
+  {0.105345,-0.459347},
+  {-1.973697,-0.097140},
+  {-0.329367,0.850698},
+  {-0.703448,-0.335789},
+  {0.450011,1.121062},
+  {0.654028,-0.721941},
+  {0.397198,0.029445},
+  {0.299006,0.140008},
+  {-1.278916,-0.883708},
+  {-0.442195,0.297563},
+  {0.159308,-0.023143},
+  {0.282331,-0.269534},
+  {1.455855,0.834365},
+  {0.520331,-0.449560},
+  {-0.163163,0.285191},
+  {-0.485547,-0.381264},
+  {0.182946,-0.895494},
+  {-1.239939,0.220402},
+  {-0.161033,-0.885029},
+  {-1.573787,-0.436694},
+  {0.431696,-0.262095},
+  {-0.044572,-0.808512},
+  {-1.515339,-0.713970},
+  {-0.072136,-0.707279},
+  {0.083839,0.736988},
+  {0.609676,-0.073344},
+  {-0.218284,0.410031},
+  {-0.145884,-0.759804},
+  {1.449489,0.119417},
+  {-0.924116,-0.784971},
+  {0.396728,-0.420324},
+  {0.442812,0.065814},
+  {0.300979,0.512297},
+  {0.720141,0.898594},
+  {-0.335842,-0.181875},
+  {-0.558501,-0.374812},
+  {-0.124859,0.840644},
+  {-0.457252,-0.211346},
+  {-0.502385,-0.919004},
+  {-0.681491,0.752273},
+  {-0.596193,-1.541557},
+  {0.244109,-0.338625},
+  {0.598338,-0.141999},
+  {-0.132257,0.405104},
+  {-0.402130,0.664641},
+  {-0.985068,0.337142},
+  {0.289973,0.153776},
+  {-0.086672,0.267755},
+  {-1.157864,1.082877},
+  {0.138765,1.203857},
+  {0.157440,-0.081841},
+  {0.183486,1.244150},
+  {-1.021782,-0.631884},
+  {-0.147782,-0.684714},
+  {0.196621,0.546394},
+  {-0.631778,-0.068033},
+  {-0.138504,-0.409385},
+  {-0.600232,0.098769},
+  {-0.817953,0.213884},
+  {0.961003,0.245662},
+  {0.790531,0.562720},
+  {-0.703499,1.039309},
+  {0.479667,-1.119048},
+  {-0.013366,0.839971},
+  {-0.034365,0.640450},
+  {-1.399523,0.355804},
+  {0.260801,0.147967},
+  {0.065808,0.546078},
+  {-0.347448,0.098553},
+  {0.821639,0.246355},
+  {-1.628820,-0.597563},
+  {-0.248049,0.428404},
+  {-0.053644,1.339589},
+  {-0.477780,-0.236885},
+  {0.582341,-0.895865},
+  {0.551673,-0.940215},
+  {0.810823,0.355256},
+  {-0.718213,-0.553310},
+  {0.761180,-1.567887},
+  {-1.354477,0.587993},
+  {-0.280057,0.265041},
+  {-0.485069,-0.830335},
+  {-0.898486,-0.123829},
+  {-0.065445,-0.810844},
+  {-0.075952,0.012324},
+  {0.489889,-0.201254},
+  {0.502262,-0.204768},
+  {0.228861,0.614161},
+  {0.686882,0.221387},
+  {-0.191478,-0.314977},
+  {-0.163156,0.201862},
+  {0.981396,-0.176446},
+  {0.031663,0.040162},
+  {0.765293,0.204843},
+  {-1.423840,0.580181},
+  {0.661978,-0.453962},
+  {-0.198973,-0.676154},
+  {0.975239,0.071402},
+  {0.514612,1.173023},
+  {0.395354,-0.237298},
+  {0.218742,-0.040218},
+  {1.092119,0.149444},
+  {-0.066491,1.171302},
+  {0.600378,-0.193844},
+  {-0.522677,-0.422476},
+  {-0.450177,-0.922771},
+  {0.814332,0.819734},
+  {0.611399,0.414148},
+  {-0.102235,1.090889},
+  {0.172764,0.367310},
+  {-0.386690,0.711734},
+  {-0.308570,0.399715},
+  {-0.067773,0.037268},
+  {0.897905,-0.893449},
+  {0.499070,-0.204820},
+  {1.054001,0.253654},
+  {-1.022458,-0.025210},
+  {0.791977,-0.988702},
+  {0.083416,-0.657610},
+  {-0.203881,-0.187619},
+  {1.728950,0.829113},
+  {-0.980056,0.458782},
+  {-0.475889,-0.471833},
+  {-0.597087,-0.425042},
+  {1.065324,0.775118},
+  {0.503802,-0.715574},
+  {0.017682,-0.631690},
+  {-0.846011,-0.086879},
+  {-1.073453,-0.572789},
+  {0.668645,0.492660},
+  {0.202993,0.029645},
+  {-0.464086,0.246619},
+  {-0.899470,-0.353428},
+  {0.399672,-0.546029},
+  {-0.121598,1.584198},
+  {0.616540,0.126347},
+  {1.654014,-0.991907},
+  {0.329572,-0.377064},
+  {-0.771268,0.203136},
+  {0.866739,-0.212090},
+  {-0.105599,0.598985},
+  {0.124672,0.816280},
+  {0.148568,-0.916659},
+  {0.156576,-0.534549},
+  {0.963588,1.376216},
+  {0.514055,-0.130478},
+  {-0.228784,0.663864},
+  {0.478723,-0.412546},
+  {-0.851050,-1.062536},
+  {0.424482,0.064766},
+  {-0.229494,0.000992},
+  {1.328704,-0.161219},
+  {-0.001671,1.095202},
+  {0.127424,0.140526},
+  {0.072691,0.881068},
+  {-0.449420,-1.174092},
+  {-0.002478,0.730130},
+  {-0.264893,1.106372},
+  {-0.113501,0.098044},
+  {0.445563,-1.652426},
+  {-0.648095,-0.615132},
+  {-0.791597,0.312268},
+  {-0.592599,0.128912},
+  {0.193724,-0.027621},
+  {-0.246776,1.475506},
+  {0.154953,0.056356},
+  {-0.256764,-0.209585},
+  {1.243059,0.094700},
+  {-1.263590,1.488868},
+  {-0.715768,1.026954},
+  {-0.069072,-0.394451},
+  {-0.054306,0.165971},
+  {-0.905233,0.403129},
+  {-0.220554,-0.122628},
+  {0.364791,0.286679},
+  {0.785926,-0.769723},
+  {-0.735274,2.193241},
+  {1.277747,0.699746},
+  {0.279424,0.904941},
+  {-0.202973,0.086592},
+  {-0.778679,-0.431290},
+  {0.160730,-0.785100},
+  {-0.503414,-0.322093},
+  {0.592752,-0.398302},
+  {-0.224174,0.376569},
+  {-0.504882,0.240802},
+  {0.639766,0.479862},
+  {-0.548174,0.076778},
+  {0.839506,-1.051851},
+  {-0.614694,0.201207},
+  {0.946087,0.430684},
+  {-0.128392,0.666809},
+  {0.392418,0.875509},
+  {-0.468207,-0.038870},
+  {-0.222987,-1.094249},
+  {-0.745045,-0.662640},
+  {-0.282590,-0.848140},
+  {0.273818,-0.451490},
+  {-0.107371,0.883462},
+  {1.090884,-0.618116},
+  {0.320881,-0.288501},
+  {-0.802570,-0.344983},
+  {0.293442,0.998732},
+  {-0.027360,0.016971},
+  {-0.520384,1.021780},
+  {-1.029293,0.643514},
+  {0.544240,-0.294024},
+  {0.814885,0.293088},
+  {-0.217184,-1.607462},
+  {1.042856,-0.193162},
+  {-0.482617,0.001200},
+  {1.290766,0.396281},
+  {0.541096,0.190732},
+  {-0.185152,0.422218},
+  {-0.395013,-0.856063},
+  {0.129098,-0.208842},
+  {-1.216610,0.501032},
+  {-0.578368,-0.077011},
+  {-0.142931,-0.107519},
+  {-0.049935,-1.347985},
+  {-0.169092,-0.532516},
+  {0.473700,-0.739075},
+  {-0.372626,-0.612488},
+  {0.695860,0.589931},
+  {0.090898,0.189706},
+  {1.451253,0.155602},
+  {0.630673,1.074650},
+  {0.523568,1.240808},
+  {-0.333037,-1.525041},
+  {0.828902,0.384816},
+  {0.705692,-0.123515},
+  {-0.161236,-1.091553},
+  {-0.905419,1.093307},
+  {-0.353888,-0.534408},
+  {0.604700,-1.082505},
+  {0.014201,-0.516866},
+  {-2.169492,1.453974},
+  {1.951017,0.818724},
+  {0.494091,-0.791937},
+  {0.118409,-0.206657},
+  {1.085713,0.213897},
+  {0.301931,-0.566131},
+  {-0.259674,0.527941},
+  {0.980986,0.596725},
+  {-0.596668,-1.134933},
+  {0.625839,0.458710},
+  {-0.334225,-0.120566},
+  {1.771062,-1.026789},
+  {0.151459,-1.012159},
+  {-0.330544,0.845122},
+  {-1.728633,-1.435125},
+  {0.140577,-0.610380},
+  {0.822159,0.635061},
+  {-0.201738,0.393073},
+  {0.440206,-0.257053},
+  {0.260232,-0.046157},
+  {-0.020715,0.469076},
+  {-0.449526,-0.525654},
+  {1.069078,1.418019},
+  {-0.433268,-0.165652},
+  {-0.085426,-0.660526},
+  {-0.843452,-1.075621},
+  {0.160153,-0.609560},
+  {0.532025,-0.402982},
+  {1.053319,-0.606113},
+  {-0.912064,0.532538},
+  {0.288336,-0.224900},
+  {1.049554,-0.798748},
+  {0.062931,0.248464},
+  {1.171278,-0.296591},
+  {-0.258426,-0.410351},
+  {0.945094,0.478489},
+  {-1.461804,1.046522},
+  {-0.633659,0.358206},
+  {0.250690,1.106278},
+  {0.430452,-0.309765},
+  {-0.308992,0.553894},
+  {0.779977,0.398830},
+  {-0.294969,0.376904},
+  {0.220612,0.065218},
+  {-0.920859,-0.345626},
+  {0.187574,0.099608},
+  {-1.349871,-0.183671},
+  {0.130552,0.361476},
+  {-0.141677,0.506033},
+  {0.618300,1.618166},
+  {0.475492,0.079416},
+  {0.714330,-0.370986},
+  {-0.573479,0.180490},
+  {-0.137712,-0.060913},
+  {0.515423,-0.368048},
+  {0.244133,1.174597},
+  {-0.525398,0.663225},
+  {0.578443,-0.543669},
+  {1.201958,0.923160},
+  {-0.111823,-0.487590},
+  {-0.073718,0.190523},
+  {0.649657,-0.659715},
+  {-0.409310,0.134954},
+  {-1.326234,-1.272925},
+  {1.305404,0.226864},
+  {-0.392474,-0.933792},
+  {-0.007464,-1.287274},
+  {-0.446668,-0.005931},
+  {0.098037,-1.037468},
+  {1.342139,0.517189},
+  {0.428876,0.529115},
+  {0.527585,-0.589122},
+  {0.132382,0.288948},
+  {-0.088091,-0.529385},
+  {-0.211020,0.106296},
+  {-0.618083,-0.302373},
+  {1.818536,0.685940},
+  {-0.922613,-0.342791},
+  {-1.840156,0.792622},
+  {-0.553622,-0.586101},
+  {0.623642,-1.195093},
+  {-1.132636,0.579581},
+  {0.093510,-0.770117},
+  {-0.885828,-1.187070},
+  {-0.293717,-0.805523},
+  {0.400295,-0.348303},
+  {0.607811,-0.144559},
+  {-0.692936,-0.145218},
+  {0.725639,-0.758167},
+  {-0.143427,-1.162858},
+  {0.782318,-0.861163},
+  {-0.606077,-0.183103},
+  {0.022532,-0.331872},
+  {-0.240756,-1.411801},
+  {0.278457,0.187169},
+  {0.424589,0.760281},
+  {0.483186,-0.084917},
+  {-1.213938,-0.432077},
+  {-0.429109,0.225001},
+  {0.175712,0.073672},
+  {1.027955,0.430115},
+  {-0.106412,-1.172744},
+  {-0.400012,0.691001},
+  {0.488778,0.654797},
+  {0.674586,0.222262},
+  {-0.040199,0.757857},
+  {0.335755,-0.779464},
+  {-0.011836,0.511340},
+  {-0.287985,0.242453},
+  {-0.323989,-0.022321},
+  {-1.788818,-0.594621},
+  {-0.126588,-0.670139},
+  {-0.582553,-0.282272},
+  {-0.172383,-1.483735},
+  {0.097068,0.374952},
+  {1.145251,-0.041021},
+  {-0.661188,-0.015538},
+  {0.478935,-0.798933},
+  {0.483136,-0.932957},
+  {-0.692102,0.831164},
+  {0.387143,-0.210910},
+  {-0.369834,-0.499064},
+  {-0.552389,0.968678},
+  {0.706835,0.672863},
+  {0.884666,-1.374115},
+  {-0.892116,-0.645080},
+  {0.212438,-0.363604},
+  {0.120562,0.094899},
+  {-0.607090,0.509514},
+  {0.391938,-0.197226},
+  {1.477689,-0.894952},
+  {0.067956,0.305202},
+  {-0.377072,-1.118688},
+  {0.238509,-0.640692},
+  {0.985068,-1.082955},
+  {1.406457,0.016522},
+  {-0.195835,0.951245},
+  {-0.668623,0.196354},
+  {0.629538,-0.359206},
+  {-2.110332,-0.600784},
+  {0.218971,-0.422251},
+  {0.327340,-0.702791},
+  {-0.506006,-0.186140},
+  {0.342203,0.477097},
+  {-0.211730,-0.864108},
+  {-0.065807,0.211029},
+  {-0.227760,0.316405},
+  {0.086344,0.613594},
+  {0.237860,1.320884},
+  {0.473216,-0.549211},
+  {0.498238,-0.583895},
+  {0.286832,0.326195},
+  {-0.476474,0.218899},
+  {-0.563894,0.557927},
+  {0.272322,0.469703},
+  {-0.749019,-0.736560},
+  {0.161585,0.085403},
+  {0.056852,0.115904},
+  {-0.388830,-0.672548},
+  {0.884869,-0.590201},
+  {0.566593,0.608661},
+  {-0.516091,-0.918691},
+  {1.642885,1.310890},
+  {0.696677,0.124297},
+  {0.445759,2.250527},
+  {0.322959,0.688997},
+  {0.016110,-0.780982},
+  {1.171736,0.361072},
+  {1.343905,1.272841},
+  {0.592350,0.019416},
+  {0.152619,-0.147421},
+  {-0.704640,0.341073},
+  {1.099323,-0.430740},
+  {-0.840177,-0.697932},
+  {-1.442964,0.718412},
+  {0.164263,0.523929},
+  {-0.111350,-0.289444},
+  {1.050958,0.639940},
+  {-0.763601,-0.206712},
+  {-0.631193,-0.041356},
+  {0.663994,0.322670},
+  {-0.258825,1.093934},
+  {0.337754,-0.472584},
+  {-0.618973,0.215902},
+  {0.770590,-1.183008},
+  {1.114851,-0.199457},
+  {1.027480,1.933290},
+  {-0.609203,1.103349},
+  {-0.541345,0.547887},
+  {0.276828,-0.095631},
+  {1.215758,-0.061026},
+  {-0.865888,-0.313945},
+  {0.134350,-0.986536},
+  {0.333627,0.278205},
+  {0.229353,-0.313560},
+  {0.822267,-0.147288},
+  {1.790442,-0.772786},
+  {0.614975,-0.867141},
+  {0.824009,-0.340756},
+  {0.242416,0.525339},
+  {-0.913436,1.352899},
+  {0.085737,0.921626},
+  {0.600046,0.518829},
+  {0.840608,-0.399042},
+  {0.744769,0.036632},
+  {-0.040337,0.836790},
+  {0.069399,0.963537},
+  {0.190218,-1.028734},
+  {0.357859,-0.557734},
+  {-0.160823,-0.761802},
+  {0.679527,0.810942},
+  {-0.334324,0.388009},
+  {0.635341,-0.443085},
+  {1.119667,1.031693},
+  {0.702179,-0.010668},
+  {0.687804,0.335793},
+  {-1.218997,0.360120},
+  {-0.015499,0.167078},
+  {0.772188,-0.754889},
+  {1.119482,0.633941},
+  {0.789910,-0.165533},
+  {-0.352196,-0.008508},
+  {0.863554,0.258157},
+  {0.200500,0.053978},
+  {-0.201635,0.202142},
+  {-0.195493,0.605893},
+  {-0.351966,-0.907111},
+  {-0.185199,-1.375999},
+  {-0.288755,0.112778},
+  {-0.601478,0.546465},
+  {-0.254146,0.433599},
+  {1.287544,0.188691},
+  {0.748493,0.772074},
+  {-0.185359,-0.704725},
+  {0.297589,-0.523805},
+  {-1.228142,0.231061},
+  {-0.238207,-1.513225},
+  {-1.093305,-0.811754},
+  {-1.360744,-0.232347},
+  {0.770614,2.942337},
+  {-1.054750,-0.772966},
+  {0.639057,-0.927998},
+  {-0.300836,-0.163147},
+  {-0.393160,-0.264180},
+  {-0.502845,1.088386},
+  {-0.790613,0.905711},
+  {-0.312306,-0.234891},
+  {0.024799,0.486804},
+  {-0.059798,1.341482},
+  {-0.463482,0.141503},
+  {-0.142495,0.482216},
+  {-0.584915,0.774424},
+  {0.727377,0.857342},
+  {-0.250533,-0.538912},
+  {-0.708249,-0.711566},
+  {-1.633626,-0.948018},
+  {-0.654737,0.568716},
+  {-0.452462,0.609938},
+  {0.103789,0.356140},
+  {-0.028716,0.443183},
+  {1.028940,0.846843},
+  {-1.932886,-0.497384},
+  {-0.029238,-0.196571},
+  {0.059763,-0.375114},
+  {-0.336361,-0.329419},
+  {0.088773,-0.164776},
+  {0.765711,0.371364},
+  {0.204439,0.390603},
+  {-0.110530,1.504023},
+  {-0.431800,0.089282},
+  {-0.819449,-0.350066},
+  {-0.974220,0.564947},
+  {0.125759,0.339755},
+  {0.317493,-0.006911},
+  {-1.013535,-0.202630},
+  {0.112258,0.117162},
+  {-0.531978,0.042502},
+  {-0.940156,0.121649},
+  {-0.725521,0.466195},
+  {-0.416124,0.485405},
+  {0.336967,0.057276},
+  {-0.421566,-0.168387},
+  {-0.015320,0.831380},
+  {-1.056343,-0.068795},
+  {0.549310,-1.282829},
+  {-0.194868,0.315490},
+  {0.003948,-0.561034},
+  {0.479671,-0.065741},
+  {-0.425547,0.760606},
+  {0.488399,-0.579394},
+  {-0.424074,-0.366667},
+  {0.044047,1.152952},
+  {-0.830197,-0.460495},
+  {-0.814327,0.057209},
+  {1.553867,-0.219049},
+  {0.774422,0.590411},
+  {0.363240,-0.485420},
+  {0.185316,0.168755},
+  {-0.564670,-0.244371},
+  {0.792661,-0.638865},
+  {-0.024050,-0.436980},
+  {1.350849,-0.888220},
+  {-0.143934,0.300172},
+  {0.586975,0.568336},
+  {-0.081438,-0.547728},
+  {0.492427,0.008414},
+  {0.215698,-0.171356},
+  {0.462206,0.692607},
+  {-0.431732,-0.509402},
+  {-1.299840,-1.348103},
+  {-0.738818,-0.011450},
+  {-0.193146,-1.086403},
+  {0.998385,-0.142121},
+  {-0.217947,-0.430734},
+  {-0.035329,-1.851256},
+  {-0.353180,0.927875},
+  {0.107119,0.623563},
+  {0.012206,-0.271749},
+  {-0.307655,0.692549},
+  {-0.622138,-0.761409},
+  {0.442970,-0.480029},
+  {0.796093,0.551437},
+  {0.009668,-0.449114},
+  {-0.116923,-0.003272},
+  {0.747452,0.198782},
+  {1.585947,-0.584168},
+  {0.062659,-2.154515},
+  {-1.470887,-0.702686},
+  {-0.377002,-0.215950},
+  {-1.380013,0.062652},
+  {0.664140,0.181371},
+  {1.034914,1.310640},
+  {0.810257,-0.623334},
+  {0.768412,-0.116447},
+  {-0.043917,1.459535},
+  {-0.441852,-0.598940},
+  {0.028953,-0.184729},
+  {-0.076069,0.867122},
+  {-0.752365,-0.121888},
+  {0.348209,-0.710583},
+  {1.006050,-0.709281},
+  {0.321016,0.506845},
+  {-1.004044,0.592095},
+  {1.476868,1.249852},
+  {0.404023,-0.215948},
+  {-0.786363,0.092388},
+  {0.312994,-1.676486},
+  {0.877315,0.390367},
+  {0.304297,1.872417},
+  {0.488998,-0.499786},
+  {0.018221,-0.372451},
+  {-1.630813,0.961882},
+  {-0.677563,0.211437},
+  {-0.795802,0.135461},
+  {0.520392,0.265735},
+  {0.785026,0.446039},
+  {-0.362354,-0.016902},
+  {-0.318927,-0.455923},
+  {-0.333291,0.675215},
+  {-1.334583,0.593424},
+  {1.430517,-0.375052},
+  {-0.502683,-0.736192},
+  {-0.710810,-0.141498},
+  {-0.252294,0.092360},
+  {0.626259,-0.169977},
+  {-0.267358,-0.042655},
+  {0.193435,0.364396},
+  {0.847771,-0.951427},
+  {-0.521408,0.066863},
+  {1.582067,-0.274576},
+  {-0.618104,0.064801},
+  {0.613930,-0.093315},
+  {0.117743,0.435939},
+  {1.262775,0.798231},
+  {-0.609864,0.402638},
+  {-0.433813,-0.204178},
+  {0.343590,-0.619007},
+  {-0.178302,0.528886},
+  {0.558275,-0.569073},
+  {-0.158423,-0.646560},
+  {0.527513,0.661901},
+  {-0.991489,0.090190},
+  {-0.352216,-0.296703},
+  {-0.809827,-0.667036},
+  {-0.509143,0.613069},
+  {-0.175233,0.802702},
+  {-0.393206,-0.142194},
+  {0.443495,-0.739842},
+  {-0.493505,-0.346109},
+  {0.291099,0.973915},
+  {-0.121100,-0.623550},
+  {0.464915,-0.564442},
+  {-0.544471,0.680835},
+  {-0.476296,0.594486},
+  {-0.646494,-0.116102},
+  {-0.912840,0.857731},
+  {0.608502,0.100114},
+  {0.831568,-1.091763},
+  {0.233161,0.780343},
+  {-0.197179,0.037707},
+  {-0.367386,-0.575712},
+  {-0.755259,0.477536},
+  {0.467144,-0.619239},
+  {-0.321884,0.010948},
+  {0.452682,0.145276},
+  {-0.220426,-0.550002},
+  {-0.256978,0.137362},
+  {0.680658,-0.565345},
+  {-1.750026,-0.017867},
+  {-0.323665,-0.262173},
+  {-0.097985,0.422237},
+  {-1.404647,-0.993924},
+  {-0.588194,0.571803},
+  {-1.200961,0.921556},
+  {0.193916,2.152188},
+  {1.013266,-0.106129},
+  {0.235823,2.080106},
+  {-0.108434,-0.729457},
+  {-0.408723,-0.348886},
+  {-0.302859,1.484877},
+  {-0.312681,-0.505828},
+  {0.018735,-0.122920},
+  {0.355886,-0.484280},
+  {-0.135969,0.761103},
+  {0.390779,1.771250},
+  {-0.145102,-1.388635},
+  {-0.416709,-0.621879},
+  {0.126479,-0.899692},
+  {-1.448828,0.318005},
+  {0.672198,0.308803},
+  {-1.764904,0.014698},
+  {0.467586,0.731148},
+  {-0.866142,-0.129121},
+  {1.095405,1.415374},
+  {-0.288686,1.532333},
+  {-0.694974,-0.572545},
+  {-0.296954,-0.918548},
+  {0.185017,-0.335333},
+  {0.106725,-0.810778},
+  {-0.266406,-0.574720},
+  {1.024931,0.523381},
+  {0.111210,1.033764},
+  {1.104428,0.317206},
+  {0.138012,-0.485474},
+  {-0.075850,-0.936313},
+  {-0.691784,0.547524},
+  {-0.960452,-0.600781},
+  {-0.806045,-0.461982},
+  {1.408073,-0.255135},
+  {0.150425,-0.658298},
+  {0.240710,-0.413124},
+  {0.206125,1.431848},
+  {-0.706788,-0.747984},
+  {0.209810,0.344959},
+  {0.940145,1.819041},
+  {-0.423045,1.613672},
+  {0.691372,0.408910},
+  {0.291379,1.694717},
+  {-0.022473,-0.483715},
+  {1.506409,-0.487754},
+  {-0.950211,0.174272},
+  {0.437884,0.334518},
+  {-0.059121,-0.187999},
+  {-0.706148,0.532011},
+  {1.247993,-0.173918},
+  {0.403025,-0.456743},
+  {0.101642,-0.201338},
+  {0.220295,0.098694},
+  {-0.544353,-1.008343},
+  {0.706586,-0.476523},
+  {0.291079,-0.150127},
+  {-0.041337,-0.659792},
+  {-0.493954,-0.757686},
+  {-0.198818,-0.425300},
+  {0.765368,-0.713655},
+  {0.129659,-0.656772},
+  {0.752741,0.605671},
+  {0.059329,1.098435},
+  {-0.095906,-1.236300},
+  {-0.192572,-0.654089},
+  {0.060002,-0.407818},
+  {1.023894,-0.192512},
+  {-0.012820,-0.526931},
+  {-0.853581,-0.349135},
+  {0.422981,-0.199832},
+  {-0.884115,-1.022837},
+  {0.051870,2.156258},
+  {0.511633,0.370017},
+  {1.100921,0.287222},
+  {-1.091726,-0.326993},
+  {1.065161,-0.088250},
+  {1.295012,0.347661},
+  {-0.186661,0.274683},
+  {0.453460,0.453078},
+  {-0.019832,-1.655232},
+  {0.033441,-0.077400},
+  {0.083820,-0.808385},
+  {0.161770,1.034907},
+  {-0.408970,0.435216},
+  {0.710238,0.172596},
+  {0.070505,0.071455},
+  {-0.157619,1.133331},
+  {0.934837,0.290817},
+  {-0.142153,-1.033463},
+  {-0.805522,-0.609104},
+  {-0.713519,0.333743},
+  {0.766007,0.180658},
+  {-0.210227,-0.404890},
+  {-1.432711,0.510194},
+  {-1.527153,-0.138670},
+  {-1.413773,-1.392381},
+  {1.162048,-1.121023},
+  {0.375536,0.334633},
+  {0.277678,0.377802},
+  {0.353273,-0.438537},
+  {-0.000468,0.519358},
+  {-1.862624,-0.213202},
+  {0.231657,-0.206180},
+  {0.579498,1.438150},
+  {-0.818714,0.244540},
+  {-0.414526,-0.963580},
+  {1.434481,-0.200950},
+  {-0.706870,-0.490200},
+  {-0.445819,0.232220},
+  {0.014789,0.903088},
+  {0.823644,0.019996},
+  {-0.257175,1.092355},
+  {0.233427,1.236390},
+  {-1.569737,0.596411},
+  {0.289963,-0.304775},
+  {-0.652898,-0.307950},
+  {0.677093,0.468114},
+  {0.199346,-0.368715},
+  {-0.122099,-0.856128},
+  {0.527088,-0.699184},
+  {0.098459,-0.383729},
+  {0.127642,0.100256},
+  {-0.743423,-0.133080},
+  {-1.904618,-0.208222},
+  {-0.311420,0.441420},
+  {0.314336,-0.480474},
+  {-0.822712,-0.862232},
+  {-0.009480,1.146566},
+  {-0.001370,-0.736855},
+  {-0.643167,-0.430793},
+  {-1.377535,0.367134},
+  {0.117747,-0.018534},
+  {0.118661,-0.605605},
+  {-0.428251,0.078424},
+  {-0.755322,0.026743},
+  {0.108427,-0.429369},
+  {-0.546590,-0.242576},
+  {-1.123375,0.034104},
+  {-0.178010,0.215736},
+  {0.555579,-0.157472},
+  {0.008256,-1.040877},
+  {0.300994,0.502246},
+  {-0.596434,-0.574450},
+  {0.650520,-0.251038},
+  {-1.202669,0.119406},
+  {1.207843,-0.367324},
+  {-0.839307,-0.511398},
+  {-1.142954,0.350094},
+  {1.745947,-0.663306},
+  {-0.197524,-0.058007},
+  {0.604840,0.358341},
+  {-0.629763,-1.061339},
+  {0.714119,-0.671946},
+  {-0.957979,0.108516},
+  {-0.204673,-0.841928},
+  {-0.224796,1.403409},
+  {0.057728,-0.276108},
+  {0.022420,0.907590},
+  {-0.442873,-0.197745},
+  {0.070502,0.367408},
+  {1.111314,-0.115300},
+  {-1.214722,0.435263},
+  {-0.623381,-0.183199},
+  {0.842462,0.271952},
+  {0.223962,-0.253993},
+  {0.784241,-0.623105},
+  {-0.460386,0.244667},
+  {0.057513,-0.844943},
+  {0.252052,1.072527},
+  {0.045339,0.090347},
+  {-1.550655,-0.849565},
+  {0.698342,1.719761},
+  {0.625755,-0.059108},
+  {0.461099,0.873655},
+  {-0.178899,-0.905113},
+  {0.378758,0.050943},
+  {-0.024118,0.005723},
+  {0.139377,-1.441619},
+  {0.746170,-0.864942},
+  {2.244304,0.225823},
+  {0.941294,0.456267},
+  {0.681838,0.479907},
+  {0.555077,0.448809},
+  {0.113034,0.326665},
+  {0.290276,-0.323618},
+  {-0.310803,-0.740078},
+  {0.288215,0.147328},
+  {0.122018,-0.901168},
+  {1.102202,-1.702754},
+  {-0.681899,1.076125},
+  {-0.823461,-0.531651},
+  {0.608237,-0.372707},
+  {-0.681661,-0.191809},
+  {0.079867,-1.266244},
+  {-0.317741,-0.703671},
+  {0.034086,0.942178},
+  {0.168887,0.177944},
+  {-0.613740,0.025035},
+  {1.089925,0.392534},
+  {0.075943,0.040485},
+  {0.566377,-0.156880},
+  {0.660386,0.045064},
+  {-0.906557,0.350211},
+  {-0.616084,0.671656},
+  {-0.353653,-0.928423},
+  {1.334011,-0.377983},
+  {0.733590,0.190001},
+  {-0.583415,-0.285064},
+  {1.339272,0.266120},
+  {-0.537001,-0.258520},
+  {-0.448141,-0.050157},
+  {0.740691,0.648732},
+  {1.056314,-0.629005},
+  {-1.160330,0.410656},
+  {0.633715,-0.113482},
+  {0.220648,-0.289338},
+  {-1.356221,-1.047442},
+  {-0.799830,-0.402114},
+  {-0.855423,-0.218579},
+  {0.533292,-0.955058},
+  {-0.590952,-0.359871},
+  {-1.003588,-0.950145},
+  {0.031010,-0.073887},
+  {-0.970717,0.112552},
+  {0.905541,0.082191},
+  {1.109198,0.621634},
+  {0.061115,-0.182655},
+  {0.519211,0.584771},
+  {0.453454,1.105118},
+  {0.307900,-0.290329},
+  {-1.310764,-1.192390},
+  {-0.990446,-0.449249},
+  {-0.636245,-1.136897},
+  {0.194571,-0.105070},
+  {0.972256,0.693447},
+  {-0.291198,1.374025},
+  {0.144387,1.382765},
+  {-0.101333,-0.022509},
+  {-0.474852,0.062917},
+  {-0.543704,-0.461692},
+  {0.714138,-0.106485},
+  {0.040096,0.285104},
+  {0.590028,1.369938},
+  {0.501543,-0.043429},
+  {2.614600,1.102147},
+  {0.255439,-1.183224},
+  {-1.069301,0.552063},
+  {0.505847,0.666774},
+  {0.018523,2.289326},
+  {-0.261409,-0.381025},
+  {-0.633168,-0.802063},
+  {-0.221651,-0.314856},
+  {0.314198,1.603044},
+  {1.173064,1.017943},
+  {-0.665682,-0.159433},
+  {-1.758748,-0.064417},
+  {1.147580,0.950364},
+  {0.550126,-0.366558},
+  {0.065759,0.113614},
+  {0.956481,1.179104},
+  {0.433038,-0.684553},
+  {-0.367835,-0.136092},
+  {-1.108652,-0.501821},
+  {0.014093,-0.724897},
+  {0.474274,0.071691},
+  {-0.878852,-0.454418},
+  {-0.111987,0.397469},
+  {0.980863,0.508451},
+  {0.567833,-0.325126},
+  {0.117299,-0.350239},
+  {0.496458,-0.149528},
+  {-0.712447,0.404552},
+  {0.050514,-0.370253},
+  {0.209666,-0.591714},
+  {-0.392540,-1.209119},
+  {-0.075244,0.496292},
+  {-0.294131,-1.102998},
+  {-0.209255,0.078796},
+  {0.109577,-0.306647},
+  {-0.214269,0.731213},
+  {1.862247,0.688064},
+  {-0.992337,0.128817},
+  {0.056261,2.006550},
+  {-0.259084,0.729512},
+  {0.491870,-0.795017},
+  {0.176987,0.094347},
+  {-0.319391,0.300136},
+  {-0.069294,-0.021210},
+  {1.038121,-1.099239},
+  {1.734655,-0.131408},
+  {0.361025,1.818288},
+  {-0.758635,-0.906905},
+  {1.433721,-0.082347},
+  {-0.327756,-1.150218},
+  {0.449566,0.413723},
+  {0.983053,-0.867287},
+  {-0.937329,-0.376043},
+  {-0.126866,-0.124008},
+  {-0.438458,-0.453466},
+  {-0.101627,0.012617},
+  {0.582181,-0.133631},
+  {0.121428,-0.222195},
+  {-0.608804,0.004610},
+  {-0.280329,-0.071507},
+  {0.776663,-0.049369},
+  {0.603737,-0.528278},
+  {-1.155587,0.324328},
+  {-1.123362,-0.454602},
+  {0.767449,-0.921822},
+  {-0.352388,-0.357436},
+  {0.309848,0.070129},
+  {-0.656513,-0.652553},
+  {-0.381851,0.355358},
+  {0.495213,0.523033},
+  {1.153773,1.092873},
+  {0.668633,-0.859082},
+  {-0.746353,-0.312026},
+  {1.048775,0.535930},
+  {0.279033,-0.054578},
+  {-0.111243,-0.422662},
+  {-0.136422,0.053799},
+  {-0.056102,0.342915},
+  {-1.088014,-0.730922},
+  {0.878624,-0.890989},
+  {-0.729911,-0.058834},
+  {-1.333908,-1.160115},
+  {-0.684287,-0.253154},
+  {-1.079448,-0.270283},
+  {0.151333,-1.649204},
+  {0.253875,0.108594},
+  {0.235712,0.387503},
+  {-0.899825,0.496213},
+  {-0.610484,-0.533034},
+  {0.496822,-0.243569},
+  {-0.524167,0.235972},
+  {-1.610220,-0.155522},
+  {-0.796686,1.243795},
+  {-0.581308,-0.236754},
+  {-0.209195,-0.037144},
+  {0.184881,-0.083576},
+  {0.396540,-0.490520},
+  {0.508980,1.096300},
+  {-0.094454,0.369221},
+  {0.680896,1.252947},
+  {-0.440938,-0.853486},
+  {-0.157199,-1.304081},
+  {-1.447599,0.971928},
+  {0.626587,0.396517},
+  {0.836229,0.966611},
+  {1.381874,-0.246085},
+  {-0.414028,-0.280956},
+  {0.980019,-0.334138},
+  {-1.644429,-0.389069},
+  {0.225519,0.368235},
+  {1.116159,-0.726131},
+  {-0.733320,0.355245},
+  {0.988265,-1.747007},
+  {0.840822,0.138793},
+  {-0.117871,0.688465},
+  {0.657025,0.157528},
+  {-0.117520,0.629271},
+  {-0.645882,-0.938485},
+  {0.980639,0.197481},
+  {0.320092,-0.621575},
+  {1.315216,0.186380},
+  {-1.150480,-1.020916},
+  {1.148288,-0.445450},
+  {-0.049133,0.097262},
+  {0.210559,-0.338083},
+  {-0.164647,1.698560},
+  {-0.134143,-0.581370},
+  {-0.100706,0.043457},
+  {-0.251067,-0.907292},
+  {0.551859,-0.013725},
+  {0.299242,-0.340345},
+  {-0.247395,1.075102},
+  {-0.032695,-1.479628},
+  {0.250204,0.334675},
+  {0.859668,-0.605057},
+  {0.362075,0.166596},
+  {0.432570,-0.747261},
+  {0.674745,-0.020640},
+  {0.361038,0.375811},
+  {0.009795,0.744204},
+  {-0.437627,-0.150132},
+  {-1.149837,0.074239},
+  {-0.717292,-1.450907},
+  {1.485412,0.238923},
+  {-0.577879,-0.010250},
+  {0.641200,-0.964459},
+  {-0.088981,0.206840},
+  {0.593610,-0.502221},
+  {-1.008813,0.283182},
+  {-0.009605,-0.090918},
+  {-1.338922,0.333185},
+  {-1.074846,-1.517178},
+  {0.539697,-0.906593},
+  {0.275416,-0.647435},
+  {1.139667,1.074978},
+  {0.070698,-0.375933},
+  {0.008435,1.196329},
+  {-0.222550,0.250323},
+  {0.275090,-0.128200},
+  {0.279230,0.576149},
+  {-0.362237,0.693913},
+  {-0.614259,0.504714},
+  {0.812049,-1.100580},
+  {-0.370461,0.966923},
+  {1.198670,-0.644836},
+  {-0.031461,0.128519},
+  {-0.122097,0.053159},
+  {1.315332,-1.008152},
+  {-0.754167,-0.305309},
+  {-0.485979,0.476556},
+  {0.823664,1.071616},
+  {-0.183654,-0.551620},
+  {0.748615,0.994233},
+  {-0.119972,0.065139},
+  {-0.849627,-1.159702},
+  {-0.444765,0.256956},
+  {0.209474,-0.472828},
+  {-0.525549,-1.027303},
+  {1.757616,0.445698},
+  {0.160525,0.088103},
+  {0.435382,0.227305},
+  {0.218477,0.170341},
+  {-0.580507,-0.450303},
+  {0.398378,0.017052},
+  {-0.031351,-0.247548},
+  {-2.316506,-1.483557},
+  {-0.443973,-0.691774},
+  {-0.510807,0.699816},
+  {-1.037649,0.345879},
+  {-1.257505,0.629094},
+  {-0.000852,-0.321557},
+  {-0.373482,-0.402662},
+  {-0.022826,-1.218651},
+  {0.025138,0.767667},
+  {0.356935,-1.465306},
+  {-0.020640,-0.323252},
+  {0.602591,-0.289913},
+  {0.046297,0.283469},
+  {-0.283535,-0.047672},
+  {-0.166785,-0.277583},
+  {-2.385793,1.082178},
+  {-0.050855,0.483435},
+  {-0.239055,-0.165545},
+  {0.505107,0.359352},
+  {-0.855951,-1.185629},
+  {-0.394709,0.226833},
+  {1.257326,-0.916278},
+  {-0.745575,-0.046165},
+  {-2.243851,-0.696840},
+  {0.551393,0.147983},
+  {0.291053,-0.204270},
+  {0.161488,-0.475875},
+  {-0.528262,0.575247},
+  {-0.986426,0.773656},
+  {-0.744878,-0.909927},
+  {0.320911,0.629702},
+  {-0.323660,-0.506678},
+  {0.028159,-0.259382},
+  {0.460460,-0.163144},
+  {-0.813206,-0.350558},
+  {1.044790,0.293066},
+  {-0.132596,1.665505},
+  {0.395208,-1.153663},
+  {0.924725,-0.269132},
+  {-0.982288,-0.672640},
+  {0.021874,0.182806},
+  {0.249894,0.425458},
+  {-0.636470,-0.070118},
+  {0.024546,-0.394318},
+  {-0.114422,-0.016105},
+  {0.604817,0.799636},
+  {0.172222,0.798172},
+  {-0.091129,0.328291},
+  {0.590852,1.199025},
+  {-1.487713,0.087366},
+  {-1.108675,-0.555536},
+  {-0.692600,0.090637},
+  {0.911874,0.392273},
+  {0.402013,0.091871},
+  {-2.169173,0.338864},
+  {0.067482,-1.073878},
+  {-0.036547,1.460194},
+  {0.266305,0.645196},
+  {0.003120,0.423355},
+  {-0.238731,0.052394},
+  {-1.065448,-0.598678},
+  {0.055241,0.168619},
+  {0.562618,1.551298},
+  {-0.301688,-0.337400},
+  {0.547448,0.323789},
+  {0.788771,0.516224},
+  {0.132486,0.681322},
+  {-0.323760,-0.904475},
+  {-0.871126,-0.916061},
+  {-1.544630,0.204207},
+  {-0.082182,0.441189},
+  {-0.325721,0.084840},
+  {-0.000671,-0.910962},
+  {-1.548705,-0.305130},
+  {1.464460,1.600289},
+  {-1.349656,0.526047},
+  {-1.552741,0.906982},
+  {-0.519449,-0.233318},
+  {0.355732,0.331088},
+  {-0.489145,0.230703},
+  {-0.970139,0.363476},
+  {-1.624033,-0.509895},
+  {0.174146,0.821782},
+  {0.724604,-1.376511},
+  {1.393602,-0.607327},
+  {-0.510112,1.657338},
+  {0.015431,-0.001536},
+  {-0.130508,-1.555322},
+  {0.000549,-0.198261},
+  {0.311467,1.081502},
+  {0.243611,-1.360408},
+  {-0.894903,-0.713205},
+  {0.388720,-0.109925},
+  {0.521072,0.398730},
+  {0.574843,0.157766},
+  {-0.617189,-0.437769},
+  {-0.211497,0.748437},
+  {0.702855,0.433536},
+  {0.432827,-0.382179},
+  {0.447150,1.156332},
+  {-0.241624,0.581731},
+  {1.292169,0.119941},
+  {0.294642,-0.871407},
+  {0.078200,-0.381604},
+  {1.032330,0.908219},
+  {0.814741,-0.010627},
+  {-0.355983,-0.219502},
+  {-0.243898,-0.682654},
+  {0.635359,-1.737373},
+  {-0.107756,-0.345466},
+  {-1.263305,-0.370563},
+  {0.175980,0.376202},
+  {1.108166,-0.738982},
+  {-0.840360,-0.285063},
+  {-0.324492,-0.354966},
+  {0.478240,0.505811},
+  {0.319641,0.856630},
+  {-0.332756,0.510426},
+  {2.005001,0.405899},
+  {0.155406,-1.227927},
+  {0.289207,0.937761},
+  {0.051751,-0.221727},
+  {0.149748,0.268723},
+  {-1.025125,0.344019},
+  {0.582839,-0.321769},
+  {-0.775607,1.441111},
+  {0.027304,-0.584074},
+  {0.863740,0.627974},
+  {-1.060986,0.321724},
+  {-0.281804,-0.212668},
+  {-0.329657,0.371799},
+  {0.531848,-0.158105},
+  {0.026672,-0.486360},
+  {-0.218047,0.635491},
+  {0.666709,0.993036},
+  {0.459120,0.452677},
+  {0.248002,0.115551},
+  {0.206833,-1.105758},
+  {-1.569637,-0.151421},
+  {0.180787,0.166870},
+  {1.226875,1.017497},
+  {-1.217281,-0.448781},
+  {-1.565721,0.396797},
+  {-0.217848,-0.273230},
+  {-0.526096,0.662491},
+  {-1.229207,0.003437},
+  {0.383000,-0.372112},
+  {1.650689,0.790800},
+  {0.536051,1.136376},
+  {-0.392390,-0.182759},
+  {-0.163732,-1.005985},
+  {-1.140970,0.475364},
+  {0.184716,-1.063705},
+  {0.945672,-0.647324},
+  {0.317886,-0.600098},
+  {-0.396886,0.775971},
+  {0.101952,-0.090515},
+  {0.276508,1.253623},
+  {-0.416748,0.718122},
+  {-0.099947,-0.530635},
+  {-1.499713,0.042544},
+  {0.397603,-0.268105},
+  {0.204542,-1.122999},
+  {-0.983787,-0.646320},
+  {0.250761,-0.124317},
+  {0.473183,0.341900},
+  {-0.705158,0.158472},
+  {0.371776,0.467056},
+  {0.257410,-1.623932},
+  {0.092234,-1.078695},
+  {-0.295587,0.833320},
+  {-0.531598,-0.934193},
+  {0.124603,-0.162051},
+  {-0.040780,-0.840548},
+  {0.785678,0.974760},
+  {-0.282413,0.507355},
+  {0.057080,-0.754205},
+  {-0.817044,0.275642},
+  {0.449437,0.089153},
+  {-0.482425,0.004603},
+  {1.564964,-1.225545},
+  {-0.296003,1.012181},
+  {0.691527,0.516007},
+  {0.861031,-0.816600},
+  {0.276897,-0.215415},
+  {-0.478248,1.152079},
+  {-0.243767,0.552381},
+  {-0.615166,0.120121},
+  {-0.258476,-0.311377},
+  {-0.105806,-1.233470},
+  {0.933500,0.163247},
+  {0.430437,1.092868},
+  {-1.072369,-0.214236},
+  {-0.893004,0.971634},
+  {-0.207458,-0.661337},
+  {0.591135,0.252093},
+  {-0.044583,0.323754},
+  {0.455226,0.549888},
+  {1.492632,0.101093},
+  {-0.299396,-0.684097},
+  {0.378218,-0.334619},
+  {0.232610,-0.041219},
+  {0.051506,0.557403},
+  {1.217142,-1.249841},
+  {0.292157,1.470057},
+  {0.044903,0.071167},
+  {-0.290396,0.496778},
+  {-0.181920,0.671063},
+  {-0.579713,-1.039686},
+  {-1.356184,0.198084},
+  {0.175306,1.691410},
+  {1.030813,-0.581909},
+  {-0.959255,-0.444030},
+  {-0.357172,-0.625541},
+  {0.681264,0.143548},
+  {-0.065022,-1.255416},
+  {-0.025972,0.751640},
+  {0.195418,0.198967},
+  {-0.581082,1.283469},
+  {0.990660,0.778059},
+  {-0.282029,1.107940},
+  {-0.273763,0.542701},
+  {0.995269,0.786820},
+  {-0.232447,0.365286},
+  {0.704749,1.074984},
+  {0.644010,0.101394},
+  {0.378756,-0.170049},
+  {0.796258,0.096740},
+  {0.728484,0.048925},
+  {-0.029005,1.135049},
+  {-1.414461,0.100530},
+  {0.195218,1.644827},
+  {-1.140545,0.941779},
+  {-0.380364,-0.295396},
+  {-0.489642,0.720380},
+  {0.491530,1.084624},
+  {0.771087,0.723882},
+  {-0.079504,-0.260956},
+  {0.512847,0.722547},
+  {0.807801,-0.638746},
+  {-0.235408,-2.425129},
+  {-0.331496,-0.883682},
+  {-0.331335,0.149970},
+  {0.777123,0.876489},
+  {1.812793,-0.280792},
+  {-0.603163,0.962356},
+  {-0.433949,0.895134},
+  {0.611068,-0.002651},
+  {-0.050707,-0.939219},
+  {0.333190,-0.695877},
+  {1.033787,-0.977412},
+  {1.029110,0.572951},
+  {-0.703830,0.009984},
+  {-0.605666,0.240015},
+  {-0.892166,-0.256507},
+  {0.310084,-0.876146},
+  {1.405525,0.188992},
+  {-0.818726,0.673212},
+  {0.010904,-1.077932},
+  {-1.260912,0.553293},
+  {-0.193185,0.554862},
+  {-0.169833,-0.541666},
+  {0.022431,-0.220661},
+  {-0.072948,0.560653},
+  {-0.643691,-0.722108},
+  {-0.414350,-0.104367},
+  {0.708357,0.463080},
+  {0.714304,-0.151360},
+  {-0.658587,-0.887861},
+  {0.149199,0.432913},
+  {-0.530458,0.445705},
+  {1.826116,1.011888},
+  {0.656833,0.119869},
+  {-0.563687,0.624626},
+  {-0.525881,0.838023},
+  {0.361541,0.559821},
+  {-1.743937,0.165666},
+  {-1.349337,1.152104},
+  {-0.049679,0.493514},
+  {1.987946,-0.325951},
+  {0.055513,0.426012},
+  {-1.269326,0.122713},
+  {-0.773301,-0.328201},
+  {0.863300,0.397242},
+  {1.404658,0.490418},
+  {0.697909,-1.272366},
+  {0.346984,0.771560},
+  {-0.275198,1.462558},
+  {0.614286,-0.583483},
+  {0.491689,-0.121321},
+  {0.868958,-0.218826},
+  {0.802647,0.609581},
+  {-0.178894,-0.484794},
+  {1.554270,-0.459034},
+  {-0.578008,-0.604401},
+  {0.141200,-0.810175},
+  {0.444930,1.801883},
+  {-0.510472,0.370071},
+  {0.280709,-1.144972},
+  {0.020627,-1.159767},
+  {-0.815817,-0.708195},
+  {1.525475,-1.186390},
+  {0.277199,0.101433},
+  {-0.263937,-0.366057},
+  {-0.084328,-0.735973},
+  {-1.014961,-0.808112},
+  {-0.463739,0.359998},
+  {-0.195469,-0.339523},
+  {-0.016981,0.736436},
+  {-0.265756,0.651378},
+  {1.181170,0.229175},
+  {0.508341,-0.387702},
+  {0.232816,0.750349},
+  {0.118147,0.881985},
+  {0.775509,-1.072872},
+  {0.126875,-0.169368},
+  {0.733796,-1.038803},
+  {-0.002779,1.199573},
+  {-0.771687,-0.819622},
+  {-0.160414,1.766988},
+  {-0.554493,-0.822178},
+  {-0.966927,-0.264584},
+  {-1.666005,0.562460},
+  {-1.142024,-0.696414},
+  {0.406841,0.433538},
+  {-0.370948,-1.115653},
+  {0.136048,0.160321},
+  {0.288581,1.454045},
+  {0.877842,-0.195856},
+  {-0.788680,-1.099470},
+  {-0.132225,1.177897},
+  {0.090549,0.626800},
+  {-0.773979,-0.074852},
+  {0.684609,0.690323},
+  {0.177050,-1.167072},
+  {-0.324256,-0.482870},
+  {-0.176754,-0.424217},
+  {-1.014998,-0.298680},
+  {-0.474555,-0.796117},
+  {0.283239,0.175760},
+  {0.614617,0.095776},
+  {-0.294539,-0.581832},
+  {-0.411225,-0.981276},
+  {0.042082,0.873893},
+  {-0.603924,0.401098},
+  {-0.783720,-0.094055},
+  {-0.750818,1.155413},
+  {-0.229883,-0.177973},
+  {-0.439507,0.600696},
+  {1.064919,0.193246},
+  {-0.304774,0.765127},
+  {-0.423589,1.423282},
+  {0.226341,0.048299},
+  {-0.491662,0.021729},
+  {-1.190822,-0.192527},
+  {0.236763,-1.021980},
+  {0.347245,0.305465},
+  {0.437791,-0.174323},
+  {0.293884,-1.183318},
+  {0.090410,-0.351897},
+  {0.127531,0.572262},
+  {-1.046283,-0.452403},
+  {0.940061,-0.475348},
+  {-0.986271,0.443950},
+  {0.220640,1.032270},
+  {0.286851,-0.234600},
+  {0.875448,-0.665507},
+  {0.054512,0.468117},
+  {-0.130507,1.089372},
+  {-0.035702,0.486985},
+  {0.069264,-0.306520},
+  {-0.066945,-0.482707},
+  {0.452421,0.252962},
+  {0.597328,-0.457166},
+  {-0.475184,-0.265545},
+  {0.663543,-0.025896},
+  {0.284485,0.141732},
+  {0.041567,-0.957668},
+  {0.290973,-0.844633},
+  {-0.681949,-1.232429},
+  {0.017290,0.318637},
+  {-0.575524,-0.211416},
+  {0.508609,0.616042},
+  {0.019156,1.014363},
+  {-0.230623,-0.152963},
+  {0.390757,0.179639},
+  {-0.076114,0.571760},
+  {-0.385456,0.807338},
+  {1.161341,-1.117539},
+  {0.108692,-0.217050},
+  {0.124773,-0.057939},
+  {0.460042,-0.075353},
+  {0.381092,-0.249534},
+  {0.421018,0.484359},
+  {0.008405,-0.001483},
+  {-1.033700,0.064492},
+  {0.168744,-0.730623},
+  {-0.456130,-0.563921},
+  {-0.042797,-0.009800},
+  {0.296420,0.994668},
+  {-0.431712,-0.260015},
+  {-0.851644,0.160001},
+  {0.315681,-0.696367},
+  {2.018690,1.186418},
+  {-0.250355,-0.220666},
+  {0.748427,-0.192764},
+  {-0.047138,-0.852542},
+  {0.211458,1.086426},
+  {0.871051,-0.574737},
+  {-0.562745,0.929652},
+  {0.283267,-0.955651},
+  {-1.076759,-0.129783},
+  {0.675245,0.669145},
+  {-0.702168,-0.896492},
+  {-0.291861,0.305292},
+  {-0.395244,0.389980},
+  {1.207996,0.801305},
+  {0.975263,-0.313611},
+  {-1.106120,0.102991},
+  {0.171218,0.482130},
+  {0.049836,0.344150},
+  {-0.574798,0.577927},
+  {0.172133,0.333449},
+  {-1.172473,0.893130},
+  {1.350215,-0.102154},
+  {0.456540,0.882785},
+  {0.794284,-1.919899},
+  {0.870210,0.114615},
+  {0.286346,0.295210},
+  {0.213541,1.053429},
+  {0.087514,-0.244276},
+  {-0.872078,0.726523},
+  {0.614549,0.116808},
+  {-0.631306,-1.519765},
+  {-0.542784,1.390314},
+  {0.087673,0.809103},
+  {-1.379197,-0.585950},
+  {0.481568,0.087880},
+  {-0.119636,-0.372124},
+  {0.016361,-0.024546},
+  {0.371448,-0.472289},
+  {-0.572025,0.092977},
+  {0.848296,0.441249},
+  {-0.453304,0.205288},
+  {-0.271298,0.488850},
+  {-0.281843,-0.272080},
+  {-0.630517,-0.095495},
+  {-0.762736,-0.986147},
+  {0.057032,0.993819},
+  {-0.237911,-1.264914},
+  {0.382413,-0.189031},
+  {1.303322,-0.407785},
+  {0.538644,0.342608},
+  {0.330098,-0.259188},
+  {-1.271100,-0.197699},
+  {1.826721,0.415414},
+  {0.508481,-0.379909},
+  {-0.724041,-0.599641},
+  {-1.260518,-1.057946},
+  {-0.374209,-0.096198},
+  {0.392033,1.122224},
+  {-0.810644,0.587815},
+  {0.365400,1.456110},
+  {0.729153,0.098419},
+  {-0.225790,-0.539353},
+  {-0.858060,0.189621},
+  {0.376242,-0.480459},
+  {0.232259,-0.269844},
+  {0.129211,1.283390},
+  {-0.948935,0.157627},
+  {0.613247,0.455174},
+  {-0.868574,0.557501},
+  {0.133104,1.933073},
+  {0.493281,-0.734954},
+  {-0.317203,0.085507},
+  {-0.072179,-0.635623},
+  {-0.985795,1.545802},
+  {0.274456,-0.767398},
+  {0.728872,0.296392},
+  {0.593057,0.123323},
+  {-0.183197,1.056002},
+  {-0.032735,-0.029408},
+  {0.677645,0.164514},
+  {0.091211,-0.485727},
+  {-2.498205,0.808644},
+  {0.996395,0.003573},
+  {0.266711,-0.454450},
+  {-0.263794,-0.040333},
+  {0.354992,-0.771940},
+  {1.172659,-0.469942},
+  {-0.367261,-0.704077},
+  {-0.143653,0.755396},
+  {1.250809,-0.502261},
+  {1.019959,-0.368994},
+  {1.590169,-0.138417},
+  {0.177393,0.277887},
+  {-0.611047,0.094640},
+  {-0.549878,-0.036917},
+  {0.807628,0.821926},
+  {-0.010075,0.421684},
+  {-1.108953,-0.164506},
+  {-1.299036,-0.726626},
+  {0.671054,-0.292631},
+  {0.742427,-0.086543},
+  {-1.439898,-0.338884},
+  {-0.130204,0.124819},
+  {0.283823,0.657034},
+  {-0.109731,-1.711867},
+  {-0.245196,0.209915},
+  {0.134997,-0.672792},
+  {0.052287,-0.037615},
+  {0.660337,-0.488347},
+  {-0.874463,-0.641201},
+  {-0.570408,0.594626},
+  {0.681125,1.678168},
+  {0.795936,-1.473398},
+  {0.778924,-0.690375},
+  {0.431527,-0.973408},
+  {-0.440928,-0.786162},
+  {0.032495,-0.001239},
+  {0.384671,0.422006},
+  {-0.232534,0.009146},
+  {-0.797171,0.074804},
+  {0.273856,-1.269545},
+  {-0.171058,-0.791818},
+  {1.061619,-0.008526},
+  {1.034158,-0.217879},
+  {-1.073993,0.364692},
+  {0.025259,0.399442},
+  {-0.054965,0.068811},
+  {-0.267747,-0.643064},
+  {1.461066,-0.012076},
+  {-0.836750,1.168916},
+  {0.751557,0.373319},
+  {0.284049,-0.561823},
+  {0.913427,0.006951},
+  {0.604871,0.613051},
+  {0.938690,0.069825},
+  {0.501171,-0.252792},
+  {0.173783,0.437109},
+  {-0.295979,-0.584728},
+  {0.268176,-0.073450},
+  {-0.039777,0.110535},
+  {0.448278,-0.594228},
+  {-0.298566,-0.370610},
+  {0.359251,1.950238},
+  {0.585298,-0.306953},
+  {0.002142,-0.517386},
+  {0.039309,0.239663},
+  {-0.535150,0.901889},
+  {0.909644,-0.597911},
+  {1.686969,-0.229593},
+  {-0.675714,-0.593584},
+  {-0.388048,-1.333594},
+  {0.141555,-0.868886},
+  {0.566275,0.216197},
+  {0.132033,0.260242},
+  {0.623869,0.696830},
+  {0.374297,-0.755016},
+  {-0.375173,-0.919679},
+  {0.062230,0.203455},
+  {-1.171487,1.698409},
+  {-0.657380,-0.503744},
+  {0.414301,0.170470},
+  {-0.611193,-0.370376},
+  {0.470375,-0.330994},
+  {-0.990314,0.032083},
+  {-1.312575,-0.450515},
+  {0.164736,-0.128481},
+  {-0.912458,-1.485285},
+  {-0.073236,-0.747723},
+  {0.278586,-0.044914},
+  {-0.449681,-1.314391},
+  {0.509207,1.963487},
+  {0.443624,-1.487975},
+  {0.605531,0.966878},
+  {0.884828,1.743505},
+  {-0.335874,-0.307016},
+  {-0.615678,0.670790},
+  {0.953036,0.532101},
+  {0.825614,0.299899},
+  {0.399454,-0.946779},
+  {-0.563757,-0.802924},
+  {-0.023567,0.554864},
+  {0.046483,-0.362895},
+  {-0.330303,0.001323},
+  {0.433488,0.570663},
+  {-0.127014,1.545073},
+  {0.235044,-0.692703},
+  {0.339960,-0.764085},
+  {0.765956,-0.657851},
+  {1.077800,-0.036173},
+  {0.431734,-0.931291},
+  {0.205175,1.147130},
+  {-0.058883,-0.741478},
+  {0.538996,0.374879},
+  {-0.435105,0.405032},
+  {0.930107,0.775706},
+  {0.158508,-0.559880},
+  {-0.043020,-0.139690},
+  {0.218128,-0.940794},
+  {0.107406,-0.191890},
+  {-0.040673,-0.450419},
+  {0.710685,-0.272868},
+  {0.214608,-0.733148},
+  {-0.440708,-0.166709},
+  {0.216889,-1.104968},
+  {0.114942,0.352891},
+  {0.515426,0.834965},
+  {-0.186585,-0.424557},
+  {1.257561,-0.686647},
+  {-0.278166,-1.068819},
+  {0.045243,-0.149820},
+  {-0.806871,0.387979},
+  {0.040414,-0.705648},
+  {-0.016666,1.472054},
+  {-0.427683,0.185384},
+  {0.017081,0.122558},
+  {-1.422488,0.695789},
+  {0.084603,1.586049},
+  {-0.226098,-0.072565},
+  {-0.689706,0.246104},
+  {0.644654,0.604549},
+  {-0.260322,1.463776},
+  {-0.430197,0.702709},
+  {-0.736554,1.401740},
+  {0.204332,-0.375610},
+  {-0.939807,1.309502},
+  {-0.037928,0.882787},
+  {-0.338569,0.066617},
+  {0.075071,0.541251},
+  {0.172982,1.021832},
+  {0.431851,-0.387000},
+  {0.307106,-0.919275},
+  {0.988648,-0.253024},
+  {-0.673928,0.782128},
+  {-0.688000,-0.918977},
+  {-0.027596,0.365924},
+  {-0.017926,1.175705},
+  {0.199711,-0.926633},
+  {0.739217,-0.155412},
+  {-0.592162,0.021539},
+  {0.080983,-0.276297},
+  {0.537674,-0.246176},
+  {0.015238,0.398952},
+  {-0.027734,-0.249279},
+  {-1.378429,0.127339},
+  {-0.809060,1.028061},
+  {0.218043,-0.052562},
+  {0.856957,1.006954},
+  {-1.011526,0.164596},
+  {0.476552,0.826400},
+  {0.022545,0.496168},
+  {-0.593984,0.825097},
+  {-0.170301,-0.015034},
+  {0.206013,0.981045},
+  {0.558955,-2.047671},
+  {-0.285619,-0.535242},
+  {0.338595,-0.054516},
+  {-0.320398,0.326921},
+  {-1.165209,-0.830182},
+  {-0.247664,-0.461885},
+  {0.566396,-0.099876},
+  {-0.062142,0.605779},
+  {0.862879,0.021585},
+  {-0.964586,-0.456012},
+  {0.383126,-0.226075},
+  {1.125091,0.452775},
+  {0.287649,1.076596},
+  {0.090020,0.540193},
+  {-0.329572,1.895356},
+  {0.883979,-0.133990},
+  {0.777596,0.934683},
+  {0.305673,-0.097759},
+  {0.445752,0.546775},
+  {0.438676,-0.401466},
+  {0.515517,0.663239},
+  {-0.861769,-0.334754},
+  {-1.155387,1.376435},
+  {0.693576,0.380899},
+  {-0.233764,-1.427252},
+  {-0.512225,0.275704},
+  {-1.300603,-0.025943},
+  {-0.886231,0.393107},
+  {0.203813,-1.151956},
+  {1.065475,0.274747},
+  {1.298933,-0.171110},
+  {-0.034164,-0.546428},
+  {1.344656,0.280082},
+  {0.303208,-0.150756},
+  {-0.278895,0.217139},
+  {0.774302,0.280649},
+  {-0.397168,-0.748535},
+  {-0.154686,-0.416415},
+  {0.108531,-0.707248},
+  {1.044479,0.517916},
+  {-1.079087,-0.181141},
+  {-0.618875,-0.601089},
+  {-0.903401,1.369553},
+  {-0.434703,1.004383},
+  {0.084219,-0.594635},
+  {0.760134,0.396506},
+  {-0.868353,0.425362},
+  {0.190516,-0.470775},
+  {0.130523,-0.050180},
+  {1.613252,-0.894441},
+  {-1.230645,0.027123},
+  {-0.207136,1.406158},
+  {0.097428,0.373589},
+  {1.101023,0.803449},
+  {1.891159,-1.054308},
+  {-0.158666,-0.325728},
+  {0.218607,-0.427098},
+  {0.581789,-0.007118},
+  {0.407515,0.254448},
+  {0.153202,-1.566655},
+  {1.270156,0.791481},
+  {-0.807984,-1.293868},
+  {-0.631812,0.190605},
+  {1.684536,0.502642},
+  {-0.623167,-0.326260},
+  {0.460536,1.490078},
+  {-0.633215,-0.730038},
+  {0.455857,-0.569264},
+  {1.113987,0.512264},
+  {-0.303183,-0.813196},
+  {1.242308,0.346664},
+  {0.235454,0.588078},
+  {0.884906,-0.682330},
+  {-0.870385,0.197874},
+  {-0.392108,1.132213},
+  {0.139987,0.749446},
+  {0.057771,-0.617700},
+  {-0.090352,0.118191},
+  {0.007506,0.480385},
+  {-0.183661,-0.349638},
+  {-0.201963,1.476555},
+  {-0.705242,-0.479413},
+  {0.975864,0.280884},
+  {0.972210,0.753330},
+  {0.338783,-0.040685},
+  {-0.054492,0.060498},
+  {-0.159293,0.819645},
+  {-1.053555,0.401428},
+  {0.115345,-0.107756},
+  {-0.194026,0.187454},
+  {0.439241,-0.428716},
+  {-0.065278,-1.075082},
+  {-0.272430,0.840665},
+  {-0.259244,0.669703},
+  {0.033760,-1.203906},
+  {0.088858,-0.092993},
+  {-0.855095,-0.299047},
+  {-0.255525,0.089061},
+  {-0.202798,0.134231},
+  {0.574524,0.323405},
+  {-0.355686,-0.509011},
+  {-0.238557,0.035684},
+  {-0.381287,-0.557626},
+  {0.657797,0.952902},
+  {-0.077875,0.403221},
+  {-0.237508,1.411722},
+  {0.652551,-0.088574},
+  {-0.013073,0.581057},
+  {0.570232,-0.572671},
+  {1.442937,-1.109803},
+  {0.997920,-0.010095},
+  {-0.152155,0.277499},
+  {-0.584876,-0.218181},
+  {0.717679,-0.143585},
+  {-0.075248,-0.695632},
+  {-1.576641,-0.266963},
+  {-0.228247,-1.087442},
+  {-0.672358,-0.340599},
+  {-0.682509,-0.975534},
+  {0.412126,0.155315},
+  {0.540229,-0.913902},
+  {-0.949688,-0.498559},
+  {0.038080,-0.334697},
+  {-0.844788,0.671919},
+  {-0.340829,-1.268134},
+  {0.033822,1.867938},
+  {-0.995863,-0.338217},
+  {0.179299,-0.122295},
+  {-0.037869,-0.933049},
+  {-0.750164,-0.719282},
+  {-0.833977,1.003917},
+  {0.932833,0.760645},
+  {0.867564,0.655081},
+  {-0.504874,-0.636730},
+  {0.714318,-1.290905},
+  {-0.672831,0.341525},
+  {0.278639,0.168889},
+  {-1.057328,-0.938548},
+  {-0.028958,0.765673},
+  {0.659485,-0.427439},
+  {-0.688018,0.905752},
+  {0.593115,-1.081085},
+  {1.020607,-1.035200},
+  {-0.288406,0.254196},
+  {0.681091,-0.195788},
+  {-0.405965,0.877370},
+  {0.247328,-1.348181},
+  {0.193907,-0.618541},
+  {0.104252,-0.480525},
+  {-1.219477,-0.511557},
+  {-0.355216,0.903456},
+  {-1.510029,-0.513418},
+  {-0.622239,1.647319},
+  {1.211936,-0.279494},
+  {-0.944064,0.760953},
+  {0.165329,0.746784},
+  {1.123063,0.150372},
+  {0.591389,0.426566},
+  {-0.763105,0.099885},
+  {-0.233567,-0.051927},
+  {0.451271,0.672933},
+  {-0.319276,-0.725166},
+  {0.090943,0.256992},
+  {-0.740401,0.083129},
+  {-0.493689,0.594996},
+  {-1.160349,0.225323},
+  {-0.120932,-0.308355},
+  {-0.242434,0.784263},
+  {-0.564637,-0.499833},
+  {-0.094070,-0.250553},
+  {-0.953770,-0.371332},
+  {1.661581,0.171338},
+  {0.341775,0.270245},
+  {0.118130,0.083808},
+  {-0.079126,-0.216981},
+  {0.338884,0.258435},
+  {0.264433,-0.841639},
+  {0.232893,-1.129943},
+  {1.240106,-0.052206},
+  {0.209045,0.058734},
+  {0.520361,0.888685},
+  {-0.349822,-0.636562},
+  {0.594371,1.144844},
+  {0.075638,0.714484},
+  {-0.784900,-0.809998},
+  {0.662100,-0.092575},
+  {0.056696,0.432525},
+  {-1.239459,0.384416},
+  {-0.006458,0.746883},
+  {-0.290814,-0.506631},
+  {0.561491,-0.077239},
+  {-1.024084,0.663394},
+  {-0.157999,-0.050504},
+  {1.085344,-0.554264},
+  {-0.708002,0.222259},
+  {-0.593735,-0.009698},
+  {0.223185,0.251755},
+  {-1.023014,0.387383},
+  {0.397333,0.864350},
+  {1.103984,0.475520},
+  {0.352685,-0.245976},
+  {0.549224,0.087034},
+  {-0.472024,0.633377},
+  {-0.620719,-0.384944},
+  {-0.442898,-0.177685},
+  {-1.124416,1.350868},
+  {0.618839,0.158407},
+  {0.718180,0.334085},
+  {-0.107034,-1.414157},
+  {0.390844,-0.348879},
+  {0.416452,-0.381163},
+  {0.016589,0.693169},
+  {0.210261,1.649291},
+  {0.151838,0.205813},
+  {-0.595573,-0.768804},
+  {-0.160431,-0.717857},
+  {-0.510800,-0.293505},
+  {-0.818709,0.437824},
+  {0.545773,0.032159},
+  {0.676537,-0.059850},
+  {-0.311443,-1.175198},
+  {0.157728,-1.121027},
+  {0.012740,0.536150},
+  {-0.639492,0.488597},
+  {-0.070496,-0.204313},
+  {0.234541,0.328949},
+  {0.236419,-0.139396},
+  {-0.288891,0.889796},
+  {0.148007,1.176270},
+  {0.546853,0.583059},
+  {-0.361551,1.330611},
+  {1.183964,1.397033},
+  {-0.993293,0.519104},
+  {-0.712212,-0.401528},
+  {0.445422,-1.006540},
+  {0.778229,-0.924857},
+  {0.140488,-0.120001},
+  {-0.930823,0.679986},
+  {0.269149,-1.501842},
+  {0.630853,-0.526320},
+  {0.957876,-0.802863},
+  {0.190233,-1.009434},
+  {-0.185559,0.932629},
+  {0.050613,-0.086777},
+  {0.020035,-0.059037},
+  {-0.511718,-0.355513},
+  {-0.795821,0.050420},
+  {-0.656840,1.891314},
+  {-0.055379,0.405881},
+  {0.539094,0.845218},
+  {-1.014806,0.375225},
+  {-0.503707,1.354756},
+  {0.124660,-1.563966},
+  {-0.465392,-0.054315},
+  {-0.437257,0.566359},
+  {-0.082575,-0.150215},
+  {-0.133522,0.536886},
+  {0.594595,1.933791},
+  {0.914843,-0.872862},
+  {-0.247467,-0.433828},
+  {-0.064788,0.077212},
+  {0.778095,-0.045493},
+  {0.366523,1.293263},
+  {0.094333,0.230801},
+  {-0.614536,0.463331},
+  {0.430178,1.113947},
+  {-0.150038,0.174521},
+  {0.438024,0.254990},
+  {0.480884,-1.856722},
+  {-0.666409,-0.255484},
+  {-0.457158,-0.599194},
+  {-0.450171,0.118477},
+  {0.497637,-0.101183},
+  {-1.705586,0.405099},
+  {0.259566,0.922599},
+  {0.672946,-0.407264},
+  {0.324409,0.900242},
+  {-0.243075,-0.163768},
+  {0.051280,0.490307},
+  {0.571128,0.105678},
+  {0.345743,-1.177099},
+  {-0.869364,-0.068202},
+  {-0.334410,0.647972},
+  {0.476318,-0.010292},
+  {-0.404522,0.623306},
+  {-1.162121,-1.071830},
+  {-0.627528,-0.384318},
+  {-0.337665,-1.341870},
+  {0.041529,0.841819},
+  {-0.201762,-0.736758},
+  {0.184452,-0.757867},
+  {-0.709406,-0.513657},
+  {-0.135826,-1.416885},
+  {-0.764527,-0.630076},
+  {-0.759073,1.284986},
+  {-0.016376,-1.529208},
+  {1.348773,-0.176343},
+  {-0.604174,0.991312},
+  {-0.281693,-1.131040},
+  {0.070203,0.284520},
+  {-1.229019,-0.521961},
+  {-0.321063,-0.524171},
+  {-0.284333,-0.886437},
+  {0.325590,-0.528520},
+  {0.254426,-0.232536},
+  {0.263271,-0.448853},
+  {-0.872268,0.657765},
+  {-0.819516,-0.328243},
+  {-0.259070,0.625280},
+  {-0.590739,-0.670188},
+  {0.493374,0.019055},
+  {1.344704,-0.174393},
+  {-1.182374,-1.425261},
+  {-0.666870,0.434800},
+  {-0.225687,0.069924},
+  {0.375164,1.016698},
+  {0.327044,-0.675835},
+  {0.497187,0.790896},
+  {-0.054661,-0.971456},
+  {0.260230,0.159026},
+  {-1.246029,-0.535410},
+  {-0.124982,0.871965},
+  {1.010443,1.001963},
+  {0.452742,-0.029144},
+  {0.117958,-0.136449},
+  {0.148605,-0.229105},
+  {0.251393,0.825563},
+  {0.730487,0.258166},
+  {-0.610108,0.505836},
+  {0.797900,0.109366},
+  {-0.107968,0.039054},
+  {0.252653,-0.138314},
+  {0.035959,0.047755},
+  {-1.412453,-0.353756},
+  {-0.174516,-1.100457},
+  {-0.405645,0.021713},
+  {-1.214659,-0.958074},
+  {-0.598051,-0.067393},
+  {0.459193,-0.091313},
+  {-0.584458,-0.757231},
+  {-0.806303,-0.669604},
+  {0.808333,0.602605},
+  {-0.258282,-0.747621},
+  {0.089092,-0.642856},
+  {-0.730287,0.033052},
+  {0.087943,-0.788594},
+  {0.341008,-0.211460},
+  {0.000571,0.004990},
+  {0.670368,-0.386947},
+  {0.557711,-0.002995},
+  {-0.293485,-0.872980},
+  {-0.783528,0.580868},
+  {-1.146005,1.580005},
+  {-0.361812,1.094479},
+  {0.124733,0.413218},
+  {-0.158285,-0.637446},
+  {0.364533,0.669450},
+  {-0.382480,0.147327},
+  {-1.131368,-0.908078},
+  {-0.134073,0.755815},
+  {0.085353,0.234990},
+  {0.038784,-0.362630},
+  {-1.186840,-0.015796},
+  {0.464353,0.494665},
+  {-0.835406,0.374020},
+  {-0.321494,0.250667},
+  {0.327866,0.142119},
+  {0.104908,0.694259},
+  {0.081477,-0.930475},
+  {-1.022207,0.157953},
+  {1.114196,-0.318852},
+  {-0.153446,-0.083414},
+  {-0.004149,-1.802615},
+  {0.061545,-0.040178},
+  {-0.799257,-0.743362},
+  {-0.208531,-0.357144},
+  {-0.319060,1.569294},
+  {0.077045,-0.067189},
+  {-0.161677,0.635664},
+  {-1.405501,-0.763577},
+  {-0.397846,0.381495},
+  {-0.609449,0.151477},
+  {0.790843,0.583281},
+  {-0.125419,-0.673059},
+  {0.048552,-0.170964},
+  {0.251041,1.361702},
+  {0.146372,-0.095489},
+  {0.636802,0.172758},
+  {0.019193,0.213042},
+  {-1.039100,-1.241302},
+  {-0.564480,-0.945689},
+  {0.486241,-0.284521},
+  {0.331050,-1.330519},
+  {-0.267252,-0.434646},
+  {0.766397,-0.345934},
+  {-0.200744,0.569833},
+  {-0.041749,1.160658},
+  {-0.166904,0.567353},
+  {-0.647654,-0.482519},
+  {1.259189,0.238637},
+  {-0.061864,-1.133994},
+  {0.709167,0.066215},
+  {0.421481,0.512487},
+  {0.539837,0.885868},
+  {-0.840289,-1.137802},
+  {1.081907,-0.754870},
+  {0.139268,-0.120622},
+  {1.964821,1.068368},
+  {0.623684,0.427752},
+  {-0.307559,-0.061760},
+  {-0.075474,-0.859298},
+  {0.856064,-0.238438},
+  {0.100253,0.302974},
+  {-0.637176,-0.566873},
+  {-0.008290,0.282227},
+  {1.214723,0.715509},
+  {-0.162779,-1.789175},
+  {-0.134063,0.710633},
+  {-0.519932,0.522329},
+  {0.204941,0.159361},
+  {-0.482306,-0.376938},
+  {-0.188561,0.397104},
+  {0.440798,0.479065},
+  {0.765870,0.912747},
+  {-0.419145,-1.087277},
+  {0.200862,0.291699},
+  {1.606653,0.419064},
+  {-0.231721,-0.095246},
+  {-0.709828,-0.172976},
+  {0.156692,-0.203509},
+  {-1.074669,0.010797},
+  {0.247751,-0.531622},
+  {0.596496,-0.743859},
+  {-0.167848,0.769772},
+  {-0.600885,-0.306912},
+  {-1.540693,0.221595},
+  {0.449488,-0.651038},
+  {-0.250910,-0.287887},
+  {-0.367598,0.361719},
+  {0.494129,0.106607},
+  {-0.074593,-1.892982},
+  {0.883074,0.395411},
+  {-1.092268,0.178541},
+  {-0.087335,-0.713201},
+  {-0.276838,-0.297331},
+  {0.652034,-0.294585},
+  {0.545522,-0.253011},
+  {0.923416,0.397211},
+  {-1.625554,-0.069215},
+  {0.004244,-0.025244},
+  {0.961205,1.110819},
+  {-0.183857,-0.022013},
+  {0.193756,0.316726},
+  {-2.046393,-0.164273},
+  {-0.368365,-0.635641},
+  {-0.977759,0.639374},
+  {-0.511194,0.291523},
+  {-0.240401,0.676329},
+  {0.444406,0.962063},
+  {-0.276425,1.306324},
+  {-0.632475,-0.521505},
+  {-2.202754,-0.707231},
+  {0.036750,-1.180940},
+  {1.569251,-0.049689},
+  {0.398289,0.888255},
+  {0.348308,-1.632712},
+  {-0.564295,-0.266565},
+  {0.269295,-0.357566},
+  {0.717308,-0.386385},
+  {0.055096,1.001055},
+  {-0.316491,0.558610},
+  {-0.104349,-0.364259},
+  {-0.628408,0.275177},
+  {-0.793190,-0.708380},
+  {0.273673,-0.761222},
+  {-0.324338,0.469933},
+  {-0.879443,1.299100},
+  {-1.259126,0.852917},
+  {-0.076886,-0.512190},
+  {0.102022,-0.181585},
+  {0.519581,0.053206},
+  {0.001434,-0.202726},
+  {-1.015981,0.459688},
+  {1.125770,0.940926},
+  {0.312231,0.424855},
+  {-0.499418,-0.502875},
+  {0.517807,0.069577},
+  {-0.973119,0.268788},
+  {0.374483,-0.502729},
+  {0.003039,-0.024829},
+  {-0.040855,1.072277},
+  {-0.951793,-0.475118},
+  {-0.710944,-0.003773},
+  {-0.114791,1.219599},
+  {-0.245796,0.792555},
+  {-0.003881,0.164329},
+  {0.352843,0.700678},
+  {1.098609,-0.455416},
+  {0.890404,-0.589496},
+  {0.004892,-0.535082},
+  {1.442431,-0.702892},
+  {-0.366707,-1.095639},
+  {1.025595,0.172890},
+  {0.938371,0.195878},
+  {0.126380,0.673834},
+  {-0.578430,0.938407},
+  {-0.502260,0.910490},
+  {0.254066,0.433385},
+  {-0.220341,1.040807},
+  {1.453578,0.343099},
+  {-0.608675,-0.498692},
+  {0.073501,0.011211},
+  {-0.829259,0.377760},
+  {-0.079486,-1.685480},
+  {1.145159,-0.985214},
+  {0.098902,-0.864296},
+  {0.393820,1.649395},
+  {-0.734563,0.744368},
+  {-0.147095,-1.257531},
+  {-1.627407,-1.136028},
+  {0.467873,1.041606},
+  {0.757500,-0.414132},
+  {0.831162,-1.034454},
+  {0.816375,0.500999},
+  {0.702928,1.649657},
+  {0.080263,-0.721470},
+  {-1.187533,-0.047103},
+  {-0.150313,1.708622},
+  {0.493906,-0.679800},
+  {0.594035,-0.186757},
+  {-0.240079,1.222442},
+  {-0.360900,0.050265},
+  {0.144905,0.624081},
+  {1.181170,0.285112},
+  {0.290493,0.604750},
+  {1.092495,0.412827},
+  {0.562585,0.524007},
+  {0.341804,0.235361},
+  {-1.162588,-0.993807},
+  {0.413398,0.629788},
+  {-0.085675,0.234139},
+  {0.096242,-0.149101},
+  {-0.237502,-0.226784},
+  {1.018918,0.053213},
+  {-0.242669,-0.787538},
+  {0.756043,-0.235274},
+  {0.919413,0.564605},
+  {1.108872,0.879978},
+  {-0.581288,0.281426},
+  {-0.326461,1.233718},
+  {-0.079129,-1.162175},
+  {0.349478,-0.844907},
+  {0.027088,-0.819916},
+  {0.170056,0.187616},
+  {0.502767,-0.666850},
+  {0.961324,-0.584669},
+  {0.710063,0.119446},
+  {0.239278,0.976768},
+  {-0.014996,0.524941},
+  {0.008554,0.179727},
+  {-0.393247,-0.037826},
+  {0.718612,-0.978392},
+  {-0.225419,-0.038771},
+  {-0.227036,-0.165385},
+  {0.121599,-0.197455},
+  {1.134869,0.485862},
+  {-0.947191,-0.134063},
+  {-0.654587,1.189330},
+  {0.443246,-0.706134},
+  {-0.830123,-0.240530},
+  {-0.113430,1.241655},
+  {-0.108660,-1.135730},
+  {0.036003,-0.841002},
+  {-0.157794,0.185786},
+  {-0.483079,0.099628},
+  {0.280081,0.479144},
+  {1.939184,-0.257319},
+  {-0.687604,0.274654},
+  {0.281510,0.228436},
+  {-0.028762,-0.144790},
+  {-0.171744,0.621507},
+  {-0.370458,-0.435995},
+  {-0.369755,0.546579},
+  {1.695030,0.039443},
+  {1.240829,-0.834031},
+  {0.295979,-0.031126},
+  {-0.422307,-0.218957},
+  {0.139370,0.067480},
+  {0.184715,-0.646348},
+  {-0.818519,0.518805},
+  {-0.103088,0.886249},
+  {-0.138199,-0.692871},
+  {-0.039802,0.305166},
+  {0.227665,0.707830},
+  {0.407761,-0.090334},
+  {-0.148850,1.035646},
+  {0.706539,0.838360},
+  {-1.216193,0.118999},
+  {-1.145744,-0.154962},
+  {-1.072350,0.028873},
+  {0.816804,-0.037296},
+  {-0.223583,0.078154},
+  {0.551985,-0.137222},
+  {-0.434480,-0.170241},
+  {-0.717792,0.161839},
+  {0.404747,-0.083635},
+  {0.457787,0.137080},
+  {-0.205589,0.734910},
+  {-0.788705,1.504406},
+  {0.647835,-0.940490},
+  {1.096260,-0.020625},
+  {-0.515190,0.721472},
+  {0.151921,0.029406},
+  {-1.071512,-0.382693},
+  {-0.666773,0.643925},
+  {0.473907,0.434675},
+  {0.281689,0.152364},
+  {1.231462,0.143107},
+  {0.422616,0.642618},
+  {-0.860802,1.066102},
+  {0.180806,-0.160456},
+  {-0.171602,1.259847},
+  {-1.080608,-1.537974},
+  {0.247965,-0.391762},
+  {-0.597206,-0.026325},
+  {0.806679,0.506041},
+  {-0.448461,-0.551637},
+  {0.609211,1.564775},
+  {-0.584254,-0.421677},
+  {-0.115819,0.092741},
+  {0.630211,-0.423075},
+  {0.219037,0.467483},
+  {0.330857,0.747908},
+  {-0.653036,0.009290},
+  {-0.785070,-0.874116},
+  {1.707815,0.381228},
+  {0.023747,-1.518223},
+  {-0.937137,-0.965197},
+  {0.640566,0.933056},
+  {-0.594679,-0.574540},
+  {0.296794,-0.291891},
+  {-0.714825,0.378028},
+  {0.757843,0.220650},
+  {1.019762,2.070884},
+  {1.052090,-0.108974},
+  {0.617214,-1.030121},
+  {0.234111,1.070887},
+  {0.325029,1.415523},
+  {-1.411232,-0.591198},
+  {0.955943,0.862474},
+  {-1.524439,0.478968},
+  {0.161252,-0.000874},
+  {-1.682225,-0.113368},
+  {-0.714802,0.379857},
+  {0.815552,-0.386556},
+  {0.565304,0.508925},
+  {0.033944,-0.055679},
+  {-0.160544,-0.364665},
+  {1.167740,-0.747209},
+  {-0.114289,-0.426222},
+  {0.998961,-0.781649},
+  {0.480485,-0.325437},
+  {0.818972,1.053668},
+  {-0.759151,0.662107},
+  {-0.533949,1.213625},
+  {-0.348061,-0.399280},
+  {-0.612857,0.282472},
+  {-0.155041,0.177124},
+  {1.564518,0.497387},
+  {-0.259280,0.598564},
+  {-0.330630,-0.194511},
+  {-0.927641,0.683062},
+  {-0.492680,0.187990},
+  {-0.486909,0.556354},
+  {-1.016376,0.123981},
+  {0.605410,0.661383},
+  {-1.259776,-0.139097},
+  {0.687748,-0.124519},
+  {1.076749,1.172916},
+  {0.826104,0.453227},
+  {0.916044,0.484496},
+  {-0.220030,0.081309},
+  {-0.762988,-0.501734},
+  {0.156663,-0.397336},
+  {-0.645976,-0.464085},
+  {0.013181,-0.690831},
+  {1.418278,-0.223876},
+  {0.138929,0.135069},
+  {0.576396,-0.082604},
+  {0.341489,0.166084},
+  {0.239311,0.512591},
+  {-0.705057,0.281017},
+  {-0.216695,0.700219},
+  {-0.052454,-1.245938},
+  {-0.553732,-1.127581},
+  {-0.875834,0.839077},
+  {0.590675,-0.603937},
+  {1.115400,0.110295},
+  {-0.433421,0.192051},
+  {0.724311,-0.663050},
+  {-0.511338,-0.678864},
+  {0.319840,-0.020854},
+  {-1.173155,0.013443},
+  {0.379830,0.418095},
+  {-1.047586,0.754616},
+  {-0.458533,-0.744747},
+  {0.039738,0.740735},
+  {-0.448691,-1.323799},
+  {-0.614500,0.274110},
+  {-0.954928,1.710574},
+  {-1.115993,0.162485},
+  {1.193523,-0.172836},
+  {-0.813587,-0.815742},
+  {0.432139,-0.761635},
+  {0.539046,-0.256594},
+  {0.293082,0.217539},
+  {0.390536,-0.019131},
+  {-0.520508,-0.341834},
+  {-0.124911,-0.157248},
+  {-0.637428,-0.090345},
+  {-1.047505,0.197182},
+  {1.028592,0.057271},
+  {0.228695,-0.421307},
+  {0.160562,0.065647},
+  {-0.125276,0.570122},
+  {0.771720,-0.929429},
+  {-0.885627,-0.643624},
+  {0.674625,0.505683},
+  {-0.361914,-0.577650},
+  {0.053097,-0.825371},
+  {1.336278,-0.384586},
+  {0.004049,0.906965},
+  {-1.072504,0.415022},
+  {0.802524,-0.826920},
+  {-0.955720,0.142124},
+  {-0.125373,1.113202},
+  {0.334120,0.836902},
+  {0.835931,-0.122422},
+  {1.106213,-0.047726},
+  {2.296859,0.078391},
+  {0.366122,-0.430429},
+  {0.701139,-0.605645},
+  {-0.146080,-1.767753},
+  {0.016836,1.135654},
+  {-0.176842,-0.909804},
+  {0.161320,0.030687},
+  {0.095294,-0.085024},
+  {-0.777534,-0.732828},
+  {-0.415510,0.843213},
+  {-0.064383,1.441395},
+  {-0.077757,-0.848909},
+  {0.344072,-0.405862},
+  {-0.685213,-0.152876},
+  {2.219878,-0.147536},
+  {-0.259629,-0.346784},
+  {-0.154063,-0.256064},
+  {-0.347575,-0.135536},
+  {-0.507167,-0.471854},
+  {1.053886,1.000078},
+  {0.899577,0.115105},
+  {-0.044331,-0.789282},
+  {-0.151879,-1.288516},
+  {0.121111,-1.153694},
+  {1.329053,0.966325},
+  {-0.678745,0.814417},
+  {-0.257457,-0.282341},
+  {-0.962823,-0.351230},
+  {0.873445,0.133721},
+  {0.627689,-0.454924},
+  {-0.255754,-0.414715},
+  {0.018030,1.186715},
+  {-0.957481,0.875629},
+  {-0.117672,-0.173647},
+  {0.174636,-0.871127},
+  {-0.384196,0.778462},
+  {0.082789,0.383797},
+  {-0.701027,-1.355462},
+  {0.668719,0.695236},
+  {-0.042132,2.102093},
+  {1.413857,-0.300645},
+  {-0.112820,-0.849034},
+  {-0.612251,0.816555},
+  {0.608860,0.226898},
+  {-0.179368,-0.087384},
+  {0.040499,0.002180},
+  {-0.737672,0.256065},
+  {-0.161481,0.832177},
+  {1.099151,0.426534},
+  {-0.235701,-0.127462},
+  {-0.152026,-0.390955},
+  {-0.543015,-0.478542},
+  {-1.160759,0.623038},
+  {-0.202691,0.593749},
+  {1.786126,-0.318883},
+  {1.316698,0.020550},
+  {0.169104,-0.060324},
+  {1.045560,-0.056788},
+  {1.020056,-0.597922},
+  {-1.645949,0.293017},
+  {0.923375,-0.090014},
+  {-0.844203,-0.218401},
+  {-0.239957,0.368485},
+  {-0.309986,0.239761},
+  {-1.016587,-0.062435},
+  {-0.767244,0.118052},
+  {0.277478,0.074426},
+  {0.683305,-1.041466},
+  {-0.808274,-1.614546},
+  {0.394355,0.811173},
+  {0.796282,-1.296704},
+  {-0.714204,0.137774},
+  {0.196927,0.370427},
+  {-0.376269,-0.542680},
+  {0.791492,-0.123199},
+  {0.321249,0.521318},
+  {1.046344,0.661679},
+  {-0.141206,-0.238853},
+  {-0.383405,0.290032},
+  {0.376350,0.432868},
+  {-0.049260,-0.368856},
+  {0.408613,-0.014061},
+  {-0.326055,0.816902},
+  {-0.026001,-0.589331},
+  {-0.072918,0.200475},
+  {0.331867,-1.316811},
+  {0.435541,-0.935694},
+  {0.510818,1.141595},
+  {-0.190277,-1.450792},
+  {0.173657,-0.279898},
+  {0.438387,-0.236168},
+  {-0.079822,-1.188886},
+  {0.332160,-0.026150},
+  {-0.156566,-0.711998},
+  {1.519541,0.155118},
+  {-0.252771,0.027134},
+  {-0.051493,0.730522},
+  {1.034388,-0.494617},
+  {0.585226,-0.142609},
+  {-0.056058,0.636934},
+  {0.427097,-0.139863},
+  {0.142636,-0.376670},
+  {0.261685,-0.129577},
+  {0.622429,-0.458139},
+  {0.558685,-1.457037},
+  {-0.302307,-0.237556},
+  {0.667578,-0.893159},
+  {0.394038,-0.616568},
+  {-1.053062,-0.607413},
+  {-0.102774,0.550373},
+  {-0.151209,-0.605143},
+  {0.982131,-0.044701},
+  {0.872422,0.300385},
+  {-1.738852,-0.042787},
+  {-0.927014,0.312879},
+  {1.133143,0.059571},
+  {-1.447607,-0.203064},
+  {0.844638,-0.610940},
+  {-0.131441,-0.383945},
+  {0.185690,0.504708},
+  {0.873802,-0.522457},
+  {-0.241741,-0.833009},
+  {-0.527447,-0.384432},
+  {-0.313053,0.007224},
+  {-0.144519,-1.752126},
+  {-0.350914,0.331914},
+  {0.019446,0.830710},
+  {-0.361050,0.087871},
+  {0.136350,-0.729097},
+  {-0.727329,-1.483267},
+  {0.506054,-0.485436},
+  {0.062342,0.447545},
+  {0.577105,0.248545},
+  {-0.160478,0.636342},
+  {0.874559,0.051499},
+  {0.105072,-0.821176},
+  {-0.398886,0.154675},
+  {-0.622607,0.598468},
+  {-0.199183,-0.205099},
+  {-0.450282,-0.153537},
+  {0.663143,-0.304326},
+  {-0.184256,-1.048931},
+  {-0.162581,0.645661},
+  {-1.044422,-0.455806},
+  {-1.229037,-0.793770},
+  {-2.194331,-0.034931},
+  {0.302824,0.337893},
+  {-0.190657,0.691359},
+  {0.829411,0.226586},
+  {-0.425507,-0.020147},
+  {-0.664468,0.683717},
+  {-0.671081,-0.230903},
+  {-0.907480,-1.183741},
+  {0.554297,-0.117632},
+  {0.096878,0.871193},
+  {-1.083314,0.379586},
+  {-0.234206,-0.116224},
+  {1.369810,0.686732},
+  {-0.721421,-1.029317},
+  {-0.368926,0.569493},
+  {1.046382,0.740596},
+  {0.360666,0.448457},
+  {0.480405,0.359113},
+  {-0.086104,-0.363264},
+  {0.238387,0.695863},
+  {-0.736684,1.072959},
+  {0.386997,-0.744110},
+  {-0.437168,-0.232638},
+  {-1.153335,-0.780908},
+  {-0.684055,0.692340},
+  {0.289389,0.249867},
+  {-1.698004,0.639394},
+  {0.394495,0.268874},
+  {-0.603894,0.330558},
+  {1.253198,0.211305},
+  {-0.322306,0.240516},
+  {0.102897,0.083584},
+  {0.309184,-1.627874},
+  {-0.390228,0.139204},
+  {-0.089614,0.647020},
+  {-0.121180,-1.208862},
+  {0.826558,-0.115660},
+  {0.495726,-0.898881},
+  {-0.312265,0.328451},
+  {-0.575407,-0.648683},
+  {-0.432874,-0.055634},
+  {0.299794,-0.672465},
+  {0.755398,-1.216531},
+  {-0.785094,0.381940},
+  {1.177524,-0.442002},
+  {-0.690561,-0.399181},
+  {0.280850,1.343907},
+  {-0.409116,0.423859},
+  {1.752878,0.134327},
+  {0.051034,-0.396984},
+  {0.519335,0.260097},
+  {0.669303,-0.512912},
+  {-0.121664,-0.181888},
+  {1.193699,-0.767988},
+  {1.019133,-0.321132},
+  {0.967335,-0.098405},
+  {1.413661,-0.166381},
+  {-0.125145,0.663141},
+  {0.401551,-0.358640},
+  {-0.253575,0.814815},
+  {-0.102327,-0.276315},
+  {-0.122363,-0.012399},
+  {0.113221,0.159392},
+  {0.425525,-2.019792},
+  {-2.296354,0.492443},
+  {-0.954148,-0.237086},
+  {0.238738,-0.639157},
+  {-1.761694,-0.164252},
+  {0.737287,0.200460},
+  {-0.162938,-0.768438},
+  {-0.782868,-0.626567},
+  {-2.246589,-0.509916},
+  {-0.310067,-0.836668},
+  {-1.464033,-0.333291},
+  {1.315826,-0.280998},
+  {0.002046,1.347203},
+  {1.070363,0.251329},
+  {0.246476,0.663615},
+  {-0.845820,-0.236884},
+  {0.093058,0.749687},
+  {-1.111095,1.211477},
+  {0.009610,0.450174},
+  {0.915608,0.234386},
+  {0.143672,0.205552},
+  {1.527516,0.145242},
+  {0.460513,1.555029},
+  {-0.555127,-0.285376},
+  {0.145695,0.896220},
+  {1.217480,-0.305496},
+  {0.414556,-0.502992},
+  {0.603741,-0.844504},
+  {0.129219,0.575608},
+  {-0.283013,1.040908},
+  {-1.255234,-0.534709},
+  {1.088903,0.197861},
+  {-0.058756,0.425937},
+  {0.123779,-1.040665},
+  {0.637367,-0.271180},
+  {-0.103176,-1.697012},
+  {-0.158588,0.656751},
+  {-0.967854,-0.951648},
+  {0.086897,-0.516020},
+  {-0.373714,-0.748635},
+  {0.596132,-0.522697},
+  {-0.983889,-0.989551},
+  {-0.467885,-0.141256},
+  {0.830302,0.458530},
+  {-0.760114,0.632394},
+  {-0.274484,1.063399},
+  {0.388037,0.224930},
+  {1.249109,-0.166835},
+  {-0.449788,-0.325036},
+  {0.042710,-0.844489},
+  {0.146003,1.006131},
+  {-0.220865,-0.302253},
+  {1.058335,1.753412},
+  {0.002717,-0.206278},
+  {-0.435205,0.096155},
+  {0.045458,0.308059},
+  {0.985575,-0.174125},
+  {0.888946,0.271600},
+  {-0.928001,0.303726},
+  {0.508220,0.392928},
+  {1.126653,0.623124},
+  {-0.026042,-0.803140},
+  {-0.924908,1.178639},
+  {0.420452,1.218289},
+  {0.232925,-0.244339},
+  {-0.786826,0.421704},
+  {-1.480250,-0.437413},
+  {-0.876270,-1.154740},
+  {-1.039014,0.278444},
+  {0.540032,-0.043074},
+  {-0.333186,0.620742},
+  {0.264837,0.039240},
+  {-0.323505,0.012675},
+  {-0.409204,-0.767399},
+  {0.025022,0.921557},
+  {0.331678,0.765442},
+  {0.655658,0.673464},
+  {0.122603,1.712084},
+  {0.671768,1.118615},
+  {-0.304646,-0.327486},
+  {0.200620,0.635266},
+  {1.151679,-0.567691},
+  {0.063835,-0.149801},
+  {1.857157,0.061181},
+  {-0.314228,-0.969461},
+  {1.172970,0.214697},
+  {-0.123463,0.139130},
+  {-1.037067,0.729725},
+  {0.375812,-0.068514},
+  {0.007778,0.344010},
+  {-0.498291,0.686760},
+  {-0.021774,0.153344},
+  {-0.106309,0.126358},
+  {-1.635683,-0.251761},
+  {0.280908,0.489367},
+  {-0.706807,0.816537},
+  {-0.831300,-0.192401},
+  {0.178349,-0.073416},
+  {0.680202,-0.971835},
+  {-1.256339,-0.648133},
+  {0.699942,0.382164},
+  {-0.150262,-0.545250},
+  {-0.612851,-1.036643},
+  {0.778548,0.694659},
+  {0.419950,-0.302441},
+  {0.364074,1.256622},
+  {-0.157228,-0.261850},
+  {-0.107384,-0.158219},
+  {0.493916,-0.735154},
+  {-0.157863,0.679501},
+  {-0.238097,0.159096},
+  {-0.151747,-0.515968},
+  {-0.196244,0.393762},
+  {0.981312,-0.958934},
+  {-0.172524,0.221805},
+  {-1.038868,-0.156395},
+  {-0.540427,-0.434566},
+  {0.143654,-0.576748},
+  {1.394838,0.011972},
+  {-0.567336,1.449890},
+  {0.016188,-0.586559},
+  {0.018122,0.164911},
+  {0.282832,-0.041033},
+  {0.516311,-0.903365},
+  {-0.074153,0.774443},
+  {0.525149,-0.511892},
+  {-0.064105,0.462937},
+  {-0.550807,-0.740917},
+  {-0.159709,0.095051},
+  {0.856954,0.712022},
+  {0.184713,-0.093683},
+  {0.562640,-0.866336},
+  {1.091445,0.202260},
+  {0.504672,-0.248524},
+  {0.172117,0.391537},
+  {-0.067218,-0.440004},
+  {0.287740,1.212661},
+  {-0.562285,-0.146228},
+  {0.218122,0.047461},
+  {0.593255,-0.355369},
+  {-0.533896,-0.299014},
+  {-0.568450,-0.278213},
+  {0.203598,0.537438},
+  {-0.938066,0.704581},
+  {-0.917601,0.791035},
+  {-0.839964,-0.649079},
+  {1.307890,0.264572},
+  {-0.599850,-0.634273},
+  {0.460067,-0.969037},
+  {-0.646018,0.708979},
+  {-0.452636,0.224816},
+  {0.494858,0.238132},
+  {-0.011522,-1.346647},
+  {0.000576,-0.737202},
+  {0.100013,-0.266210},
+  {1.318841,0.403066},
+  {-0.639935,-0.303449},
+  {0.675628,-0.063920},
+  {-0.097399,0.502298},
+  {1.924211,-0.661343},
+  {-0.193195,-0.836120},
+  {-0.879425,-1.065778},
+  {-0.777720,0.991738},
+  {0.449743,-0.615344},
+  {-0.163401,-0.484593},
+  {-0.295979,0.797219},
+  {-0.293076,0.655861},
+  {-0.012079,-1.170280},
+  {0.217685,-0.808306},
+  {0.521063,0.052078},
+  {-0.051550,-0.734594},
+  {-0.035872,-1.275539},
+  {-0.111903,0.457933},
+  {1.585142,-1.073931},
+  {-0.630589,-0.097644},
+  {0.196150,-0.329361},
+  {0.786858,-0.651981},
+  {0.353044,-0.508077},
+  {0.633349,0.050938},
+  {0.292792,-1.147545},
+  {-1.636248,0.076500},
+  {0.121149,0.667182},
+  {-0.485428,0.822637},
+  {0.042791,0.346486},
+  {-0.406830,0.061469},
+  {0.260006,0.078180},
+  {0.480654,-0.228662},
+  {0.069106,0.904044},
+  {0.689995,-0.355703},
+  {1.356396,0.165978},
+  {-1.216395,-0.167056},
+  {0.806751,-0.082865},
+  {1.379444,0.548229},
+  {0.082448,-0.566330},
+  {-0.153881,-0.613327},
+  {-0.400828,-1.175044},
+  {0.007904,0.187198},
+  {0.017020,0.469228},
+  {-0.635306,0.814212},
+  {-0.686244,-1.695371},
+  {0.635513,-0.061291},
+  {-0.425817,0.149979},
+  {0.251848,-0.710921},
+  {-0.046316,0.161009},
+  {0.286905,-0.673584},
+  {-0.816487,-0.090565},
+  {-0.587562,1.125426},
+  {-0.388150,-0.088164},
+  {-0.855313,-1.030685},
+  {0.137949,0.442570},
+  {-0.500305,0.481672},
+  {-0.569691,-0.277656},
+  {1.232236,2.015065},
+  {-0.544907,-1.314194},
+  {-1.063375,-0.275894},
+  {-0.061552,-0.173145},
+  {0.552244,0.176811},
+  {-0.276732,-0.699921},
+  {-1.723753,-0.289518},
+  {-1.246463,1.183601},
+  {-0.500170,0.373240},
+  {0.651110,0.202271},
+  {-1.201287,-0.164245},
+  {-0.252490,0.060805},
+  {0.267841,0.166147},
+  {0.217199,0.233845},
+  {0.487467,1.765281},
+  {-1.323439,1.017541},
+  {-1.689664,0.253096},
+  {0.024758,0.480120},
+  {0.663608,0.503539},
+  {0.951764,-0.395559},
+  {0.811294,0.409032},
+  {-0.687545,0.241462},
+  {-0.320659,0.006277},
+  {-0.239229,1.109935},
+  {1.192667,0.419789},
+  {0.461142,0.131372},
+  {0.087449,0.030492},
+  {1.724236,-1.133479},
+  {-0.233717,0.474440},
+  {-0.107867,-0.340221},
+  {-0.260094,-0.871921},
+  {1.512797,-0.186811},
+  {-1.150296,0.161701},
+  {1.270353,-1.064373},
+  {-0.208916,-0.609819},
+  {0.266445,-0.850148},
+  {-0.191666,-1.143687},
+  {0.624237,0.402745},
+  {-0.146100,-0.313531},
+  {-0.394306,-0.512183},
+  {0.748664,1.567171},
+  {1.172201,-0.075086},
+  {-0.203625,-0.403359},
+  {0.801120,0.219087},
+  {0.483011,-0.186969},
+  {-0.822249,0.790955},
+  {-0.826600,0.057749},
+  {-0.340349,-1.708476},
+  {-0.612349,0.017105},
+  {-0.405678,0.770708},
+  {-0.882441,-0.884726},
+  {-0.760047,0.956302},
+  {-0.134529,-0.806649},
+  {-0.616061,-0.717116},
+  {-0.786351,0.960517},
+  {0.995470,0.823887},
+  {0.803940,-0.068840},
+  {-0.780356,0.796537},
+  {0.754690,0.462261},
+  {0.558489,-1.826939},
+  {0.565941,-0.533679},
+  {-0.349220,-0.565535},
+  {-0.117447,-0.033437},
+  {0.306679,0.561986},
+  {-0.452673,0.002558},
+  {0.656129,-0.312644},
+  {-0.137241,0.808405},
+  {0.023718,-0.818979},
+  {0.316627,0.723533},
+  {0.245948,-0.220425},
+  {0.018669,-0.033499},
+  {-0.384480,-0.064193},
+  {1.059643,1.011290},
+  {0.255465,0.122262},
+  {0.892933,0.377851},
+  {-1.057426,-1.072620},
+  {0.376262,0.020682},
+  {-0.318577,-1.103330},
+  {0.820800,0.258835},
+  {0.084963,-0.566530},
+  {-0.270657,0.173413},
+  {-0.630122,0.411348},
+  {-0.140339,0.070918},
+  {-0.580496,1.695575},
+  {0.184591,-0.255626},
+  {-1.595309,0.220755},
+  {-1.086653,-0.518954},
+  {-0.092904,-1.828520},
+  {-1.560213,-0.345541},
+  {-0.107258,0.421123},
+  {1.333753,0.427132},
+  {0.651096,-0.307819},
+  {1.547703,0.021547},
+  {-0.938925,0.799421},
+  {0.161495,1.637137},
+  {-0.566160,0.009561},
+  {0.765734,1.847262},
+  {-0.099619,1.217570},
+  {-1.646296,1.143879},
+  {-0.341561,0.208659},
+  {-0.829797,-0.078640},
+  {0.230420,0.260061},
+  {-1.115321,-0.415304},
+  {-0.759305,1.137078},
+  {0.119318,0.326539},
+  {0.634494,-0.172025},
+  {0.951927,1.084809},
+  {-0.481045,-0.125166},
+  {-0.147533,-1.237017},
+  {-0.194932,0.304319},
+  {-0.055354,-0.773023},
+  {-0.610176,0.526057},
+  {-1.442512,0.301773},
+  {0.806472,0.525891},
+  {0.442248,0.868214},
+  {-0.735627,-0.085293},
+  {-0.527279,-0.419674},
+  {-0.485876,-0.318730},
+  {0.619257,-0.096117},
+  {0.256008,-0.511587},
+  {0.402021,0.667654},
+  {1.085013,0.181906},
+  {-1.075699,-0.590304},
+  {0.149918,0.698889},
+  {1.232178,-0.974211},
+  {0.299137,-0.807070},
+  {-0.363717,1.920628},
+  {0.520819,-1.006913},
+  {0.237037,-0.181282},
+  {-0.473254,0.538424},
+  {-0.693209,0.205641},
+  {0.196816,-1.365328},
+  {1.294426,-0.457957},
+  {-1.201707,0.159986},
+  {-0.434547,1.602358},
+  {0.640590,-1.134317},
+  {0.145536,-0.201253},
+  {-0.295678,-0.144970},
+  {0.474340,0.506270},
+  {0.626337,0.119856},
+  {-0.389066,-1.331761},
+  {1.112996,-0.698493},
+  {0.218681,0.173533},
+  {1.403960,-0.330757},
+  {0.473726,0.286873},
+  {-0.065860,-0.094907},
+  {0.245194,-0.785259},
+  {-0.737379,0.731098},
+  {0.888062,0.554072},
+  {1.481762,-0.047101},
+  {0.422688,0.158868},
+  {0.569769,-0.263568},
+  {-1.225339,-0.094437},
+  {-1.449739,0.636898},
+  {-0.257917,-0.053649},
+  {0.155706,-0.122416},
+  {0.953568,0.325125},
+  {-0.798452,1.472069},
+  {0.052703,-0.295397},
+  {0.456338,-0.736016},
+  {0.529491,-0.568515},
+  {-0.233975,1.120665},
+  {-0.680203,-1.295243},
+  {-0.466273,-0.062131},
+  {-0.131288,1.168066},
+  {-0.385004,-1.409355},
+  {-0.314060,-0.015362},
+  {-0.874063,-0.686612},
+  {-0.445655,-1.003053},
+  {0.928618,0.248422},
+  {0.478245,-0.872451},
+  {-0.240218,0.229832},
+  {-0.207487,1.315485},
+  {0.708097,-0.459610},
+  {0.324259,-1.091280},
+  {-1.452807,0.091208},
+  {1.395570,-1.863330},
+  {0.999160,-1.241401},
+  {0.280141,-0.706033},
+  {-0.925961,0.469675},
+  {-0.688460,-0.963031},
+  {0.119873,0.226830},
+  {-0.106209,-0.158092},
+  {0.677296,-0.307387},
+  {0.390625,0.002007},
+  {-1.651675,0.216743},
+  {0.079875,0.792000},
+  {0.235602,0.452420},
+  {0.777284,-0.266590},
+  {-0.895642,-0.021410},
+  {0.254087,0.034999},
+  {-0.270512,-0.127041},
+  {-0.256159,-0.869917},
+  {0.373497,1.048321},
+  {-0.762650,-0.290650},
+  {-0.578370,-0.111365},
+  {-1.982232,-0.062361},
+  {0.578377,-0.656604},
+  {-0.468886,0.154771},
+  {0.844443,1.791920},
+  {0.097667,-1.339984},
+  {0.210075,1.094129},
+  {-0.206117,0.067388},
+  {0.421055,0.203273},
+  {0.584588,0.986430},
+  {0.133407,-0.641132},
+  {-1.170174,-0.263451},
+  {-0.157218,-0.021621},
+  {1.475833,-0.127775},
+  {0.078896,0.799595},
+  {-1.587069,-0.475999},
+  {0.695471,0.483917},
+  {0.025792,-0.441905},
+  {1.007477,0.041037},
+  {-0.181478,-0.017029},
+  {0.036815,-0.111715},
+  {-0.465989,0.179141},
+  {0.794247,0.927431},
+  {0.285622,-0.418923},
+  {-0.068971,-0.305474},
+  {-0.463998,-0.444865},
+  {0.699853,-1.012322},
+  {0.151237,1.087834},
+  {-0.146684,0.233955},
+  {0.567227,-0.089576},
+  {-0.224722,0.477183},
+  {1.199889,1.553201},
+  {0.760053,0.017195},
+  {0.261229,0.445578},
+  {-0.705770,-1.755211},
+  {0.290944,0.079387},
+  {0.133894,-0.691097},
+  {-0.059663,2.211638},
+  {0.370996,-0.939649},
+  {0.112302,1.366692},
+  {0.188262,-0.356295},
+  {-0.612580,0.733432},
+  {0.619933,0.144186},
+  {0.278577,0.110054},
+  {0.225926,0.612772},
+  {-0.729589,0.857299},
+  {1.264619,0.408863},
+  {-0.628055,-1.407078},
+  {-0.514858,-0.744270},
+  {0.619405,1.047669},
+  {-0.199934,0.731997},
+  {0.418989,-0.042346},
+  {0.785841,-0.113664},
+  {-0.932752,-0.678127},
+  {-0.806044,0.573963},
+  {0.587483,0.194597},
+  {-0.103663,0.283307},
+  {-0.433701,1.184546},
+  {0.790999,0.223614},
+  {1.419865,1.046606},
+  {-0.830056,0.788822},
+  {-0.242103,-0.605081},
+  {-1.753848,-0.814530},
+  {0.527669,0.991027},
+  {-0.240201,-0.427279},
+  {0.856250,0.646151},
+  {1.153696,0.714506},
+  {0.866539,0.692044},
+  {0.203711,0.315015},
+  {-0.285981,-0.182996},
+  {0.789261,-0.986318},
+  {-0.144656,0.102805},
+  {-0.151745,-0.054796},
+  {-0.093111,0.849218},
+  {0.517938,0.271205},
+  {0.552012,-0.102406},
+  {1.085765,0.387176},
+  {0.084600,1.884932},
+  {-0.054731,-0.030402},
+  {1.382310,-0.885943},
+  {0.098738,0.889079},
+  {1.144495,-0.059725},
+  {-0.899532,0.664015},
+  {-0.181939,0.217922},
+  {0.321437,0.396019},
+  {0.285473,-1.089756},
+  {0.586511,0.295108},
+  {-0.372205,0.500376},
+  {-0.078211,0.182058},
+  {0.011147,-0.495137},
+  {0.896627,-0.426638},
+  {-0.092586,-0.308805},
+  {0.601102,1.063945},
+  {0.749759,-1.427166},
+  {1.055874,0.699219},
+  {-0.903965,-0.438794},
+  {-0.707729,0.384313},
+  {-0.101038,0.921657},
+  {-0.485551,0.820867},
+  {0.236179,-0.929859},
+  {1.125738,-0.530163},
+  {0.077800,-1.861208},
+  {-0.730572,0.920142},
+  {-0.898268,0.339665},
+  {-0.317154,0.181412},
+  {-0.160429,-1.323295},
+  {-0.400514,-0.563102},
+  {-0.014542,0.576620},
+  {-0.381432,-0.415218},
+  {-0.377208,0.718852},
+  {-0.705579,1.318340},
+  {1.530143,-0.271100},
+  {-0.221327,-0.588484},
+  {-0.022733,-0.642035},
+  {0.030789,-0.791981},
+  {-0.766666,-0.492790},
+  {-0.749544,-0.073490},
+  {0.447054,-0.800807},
+  {1.070489,0.825108},
+  {-0.727046,0.726992},
+  {-0.060446,-1.037320},
+  {-0.328770,0.190905},
+  {-0.128967,-0.434271},
+  {-0.186546,0.312983},
+  {0.935917,-0.100236},
+  {-0.047536,-0.213380},
+  {0.082069,-0.603080},
+  {-0.913393,-0.849605},
+  {-0.457231,-0.796030},
+  {0.682990,0.778589},
+  {0.209229,-0.807062},
+  {0.272420,1.125802},
+  {0.036284,1.629727},
+  {0.104411,-0.167382},
+  {-0.626081,-0.031098},
+  {-0.351775,-1.618939},
+  {0.413605,0.257989},
+  {-0.370629,0.161392},
+  {-0.330446,0.806375},
+  {0.390219,-0.746819},
+  {-0.509487,-0.047151},
+  {-0.273129,-0.108304},
+  {-0.319689,-0.338005},
+  {0.842067,0.281057},
+  {0.055884,0.234417},
+  {-0.365933,0.614457},
+  {-0.454615,1.448888},
+  {-0.699608,-1.033875},
+  {-0.372957,0.671612},
+  {-0.133444,-0.030193},
+  {-0.924223,0.603383},
+  {-0.516276,0.204182},
+  {-0.382316,-0.235633},
+  {-0.187827,-1.054536},
+  {-0.442085,0.354249},
+  {0.622665,0.610810},
+  {0.265960,-0.284553},
+  {0.040194,-0.911782},
+  {-0.509020,0.860569},
+  {0.600634,-1.182167},
+  {0.151219,0.454662},
+  {-0.418144,0.065874},
+  {-1.569977,1.023171},
+  {0.266306,0.219226},
+  {0.791286,0.244977},
+  {-0.241393,0.875145},
+  {-0.318656,-1.030454},
+  {-0.022462,0.214741},
+  {-0.619332,0.153986},
+  {-1.020611,-1.628587},
+  {0.479077,0.439942},
+  {1.740772,1.610355},
+  {0.003287,0.194352},
+  {0.566085,0.121822},
+  {-1.147140,0.412844},
+  {1.376034,0.118976},
+  {0.420202,-1.038233},
+  {0.373144,0.162301},
+  {0.794360,0.106407},
+  {-0.962990,-0.802783},
+  {0.056256,0.007095},
+  {-0.708347,-0.662442},
+  {-0.959655,1.323960},
+  {-0.529900,0.259971},
+  {1.193998,0.563030},
+  {0.939263,1.103177},
+  {-0.385987,0.149407},
+  {-0.476455,-1.133539},
+  {0.308749,0.266472},
+  {-0.497402,0.161375},
+  {-0.740784,0.032059},
+  {-0.760730,-0.593766},
+  {-0.063348,-0.060021},
+  {0.633546,-1.329736},
+  {0.834383,0.497996},
+  {-0.600352,0.731318},
+  {-0.447242,0.431888},
+  {-1.343652,-0.365840},
+  {0.777551,-0.685316},
+  {-0.680872,-0.406050},
+  {-0.586652,-0.305786},
+  {-0.554828,0.022048},
+  {-0.699549,-0.247367},
+  {1.389279,-0.742174},
+  {-0.065282,-1.308684},
+  {-0.261274,-0.493450},
+  {-0.733425,0.887315},
+  {-0.025220,-0.501261},
+  {0.241883,-0.683133},
+  {-0.140739,0.262319},
+  {-2.045143,-1.409459},
+  {1.343072,0.855186},
+  {-0.035921,-0.283506},
+  {0.106737,0.720865},
+  {0.406583,0.040440},
+  {0.214985,1.947726},
+  {0.438985,-0.798479},
+  {-0.217059,0.167267},
+  {1.243574,0.015551},
+  {-0.125817,-0.046205},
+  {-1.183831,-1.384855},
+  {-0.322551,0.251363},
+  {-0.722839,0.595898},
+  {0.551627,-0.760119},
+  {1.054220,0.065259},
+  {0.591739,-0.191866},
+  {0.296816,-0.332836},
+  {1.165112,-0.248075},
+  {0.248393,-0.545047},
+  {1.311024,-0.407092},
+  {0.591438,-1.621612},
+  {-0.052964,-0.001681},
+  {-0.298430,-0.248136},
+  {0.275239,-0.088719},
+  {-0.147969,-0.645551},
+  {-0.505692,0.261343},
+  {0.309140,0.959088},
+  {0.921434,0.629677},
+  {0.748760,1.088213},
+  {-0.680151,-0.335191},
+  {-0.613400,0.493749},
+  {0.727131,-0.030512},
+  {-0.379323,-1.035416},
+  {-0.211766,-0.796419},
+  {-0.454060,0.049283},
+  {-0.049881,0.070106},
+  {-0.279312,0.046965},
+  {-0.397766,0.760498},
+  {0.520312,-0.439711},
+  {0.331968,-1.409079},
+  {0.427486,0.218783},
+  {1.003588,-0.080820},
+  {1.556979,-0.423669},
+  {0.619977,0.469522},
+  {-0.045054,-0.809393},
+  {-0.528064,-0.036637},
+  {-0.482697,0.131513},
+  {-0.460037,0.505505},
+  {-0.324516,-0.389828},
+  {0.460368,-0.314426},
+  {-0.560330,-0.324922},
+  {-0.376507,-0.059857},
+  {-0.851451,-0.423302},
+  {0.336302,-0.960355},
+  {1.612286,-1.262715},
+  {0.637618,-0.176273},
+  {0.382746,0.450728},
+  {0.643770,0.137805},
+  {-0.321537,1.065434},
+  {-0.913438,-1.344611},
+  {0.123579,-0.525252},
+  {-0.684321,-0.050399},
+  {0.092025,-0.049197},
+  {0.230247,-0.846072},
+  {-0.567252,1.537805},
+  {-0.113614,-0.004427},
+  {0.694251,-0.089008},
+  {-0.303172,-0.350574},
+  {0.609402,-0.434146},
+  {0.107243,-0.651101},
+  {1.272207,-0.348857},
+  {-0.502908,0.151282},
+  {-0.145185,-1.741187},
+  {0.660613,-0.230215},
+  {0.178185,-0.686348},
+  {1.272619,-0.158281},
+  {-0.280741,0.764747},
+  {0.044990,-0.769996},
+  {0.417010,0.096608},
+  {0.062595,1.686842},
+  {2.151472,0.043530},
+  {0.715346,1.734442},
+  {0.098966,-0.998731},
+  {0.599808,0.342824},
+  {-0.343734,0.708030},
+  {-0.128109,-0.806256},
+  {0.761198,0.210038},
+  {-0.138642,0.040832},
+  {-0.062262,0.648355},
+  {1.277507,0.552877},
+  {-0.927193,-0.325931},
+  {-0.249534,-0.771760},
+  {0.521253,-0.650575},
+  {0.616145,1.180146},
+  {-0.318551,-0.126697},
+  {-0.526436,-0.915103},
+  {1.171009,1.586755},
+  {-1.579776,-0.032072},
+  {0.379730,-0.424383},
+  {0.219217,-0.851723},
+  {0.557224,0.464978},
+  {-0.216519,0.253208},
+  {0.972628,0.385579},
+  {0.412359,0.086125},
+  {0.876441,-0.274872},
+  {-0.407527,-0.657947},
+  {0.541719,0.812008},
+  {0.772499,0.092084},
+  {0.502839,0.363918},
+  {0.146701,0.081139},
+  {-0.007951,-0.624450},
+  {-0.605555,-1.647412},
+  {-0.169302,-0.077049},
+  {-0.244837,-0.620332},
+  {0.764241,-0.522473},
+  {-1.133782,0.258060},
+  {0.948375,0.016726},
+  {1.587208,-0.235768},
+  {0.424286,0.560435},
+  {0.366718,-0.229027},
+  {0.114061,-0.120273},
+  {-0.032553,-0.706649},
+  {-1.656256,0.469776},
+  {-0.800075,0.163134},
+  {0.184989,-0.490187},
+  {-0.066939,0.069671},
+  {-0.124030,-0.278587},
+  {0.098588,-0.516323},
+  {0.641825,0.433273},
+  {0.039826,-1.896522},
+  {0.544579,0.174252},
+  {-1.136703,0.508232},
+  {0.473606,-0.928168},
+  {-0.262024,0.277016},
+  {-0.525881,-0.940302},
+  {0.774239,0.928604},
+  {0.475874,-0.471899},
+  {-0.803854,0.030975},
+  {-0.993059,-1.988145},
+  {0.006261,-0.462312},
+  {0.304373,-0.219476},
+  {-0.064896,0.411816},
+  {-0.565623,0.410175},
+  {0.451946,0.896558},
+  {0.579193,-0.666237},
+  {1.111956,-0.324559},
+  {0.958126,0.875141},
+  {-2.376995,0.139360},
+  {-0.174255,-0.647183},
+  {0.014742,0.174545},
+  {-0.527097,-1.346987},
+  {1.514308,1.010371},
+  {0.148586,0.574571},
+  {-0.282640,0.894507},
+  {-0.099804,0.189072},
+  {-0.371499,-0.000976},
+  {0.094502,1.606489},
+  {-0.417943,0.639646},
+  {0.660216,-0.605938},
+  {-0.545899,-0.550059},
+  {1.076567,-0.745220},
+  {0.405227,0.711701},
+  {-0.366586,0.196052},
+  {0.860394,0.269181},
+  {-1.127270,0.202607},
+  {0.136211,0.475897},
+  {0.459787,0.495293},
+  {0.544301,-0.482145},
+  {0.365063,0.234250},
+  {-0.593792,-0.434170},
+  {-0.426111,-1.761006},
+  {0.869614,-0.020494},
+  {-0.467603,0.072709},
+  {-0.324193,-0.665541},
+  {0.777996,-0.277466},
+  {-0.283302,0.615438},
+  {-1.708614,0.792042},
+  {0.621137,-0.463159},
+  {0.521234,0.742400},
+  {-0.133299,-0.939262},
+  {-0.160119,-0.770287},
+  {-0.512796,0.969515},
+  {0.315453,-1.192219},
+  {1.288366,0.188477},
+  {0.555009,0.515260},
+  {0.190975,-0.611313},
+  {0.181731,0.979969},
+  {1.256390,-0.748626},
+  {-0.335278,-0.480621},
+  {-0.671001,0.965038},
+  {-0.104705,0.209754},
+  {-0.085875,-1.716713},
+  {-1.640847,-0.669974},
+  {0.447848,-0.348934},
+  {0.265837,1.298157},
+  {0.752559,1.353997},
+  {-1.107378,1.884381},
+  {-0.974856,0.729668},
+  {-0.408192,0.715443},
+  {0.256093,-1.141904},
+  {-1.426772,0.454018},
+  {-0.379814,-0.020252},
+  {0.808918,-0.270355},
+  {0.032856,-0.539366},
+  {-1.792033,-0.556382},
+  {-0.749878,0.045814},
+  {-1.284019,0.264061},
+  {-0.644668,0.334991},
+  {0.167439,0.463690},
+  {0.781219,0.368265},
+  {-0.260223,-0.044352},
+  {-0.071616,-0.070425},
+  {-1.084332,0.404648},
+  {-1.607982,-0.417932},
+  {0.755238,-0.174306},
+  {0.185585,1.881097},
+  {-0.015098,0.559027},
+  {-0.177597,-0.752248},
+  {-0.550116,-1.060073},
+  {-0.358345,-0.425293},
+  {0.348800,-0.817303},
+  {-0.881309,-0.246413},
+  {0.925273,-0.021585},
+  {-0.725402,0.242012},
+  {0.185628,0.275909},
+  {-0.422986,1.393526},
+  {0.628901,-0.118229},
+  {0.317355,-0.260886},
+  {0.700872,-0.179362},
+  {-0.261562,-0.299310},
+  {0.255547,0.459484},
+  {0.874547,-0.523117},
+  {1.173201,1.024590},
+  {-0.996085,-0.014251},
+  {-0.936499,-0.186035},
+  {-0.124365,-0.515926},
+  {-1.063564,-0.984708},
+  {0.564578,-1.758164},
+  {-0.798557,-0.294069},
+  {-0.100377,0.060186},
+  {-0.199967,-0.488498},
+  {0.888361,-0.509741},
+  {0.983519,1.571630},
+  {0.112599,1.056708},
+  {0.873252,0.482406},
+  {0.452934,-0.285808},
+  {-0.043803,-0.750535},
+  {0.403150,0.892230},
+  {-0.396320,-0.357763},
+  {-0.332699,-0.116355},
+  {0.593079,0.468945},
+  {0.284203,0.714000},
+  {0.215099,-0.285505},
+  {-1.147423,0.160707},
+  {-0.762612,1.411527},
+  {0.472681,0.269305},
+  {0.255840,-0.160359},
+  {-0.055088,1.194371},
+  {-0.698704,-0.799073},
+  {-1.285369,0.675681},
+  {1.004399,-0.126013},
+  {-0.548650,0.989301},
+  {-0.348031,0.143843},
+  {0.019998,-0.340962},
+  {1.023248,0.761331},
+  {-0.902970,-1.223627},
+  {-0.279665,0.623119},
+  {-0.366014,0.496679},
+  {-0.813344,-0.457467},
+  {-0.372345,0.539890},
+  {-0.485404,-0.267196},
+  {0.536624,0.644437},
+  {1.607247,0.297879},
+  {0.220415,0.883121},
+  {-0.610471,-0.507677},
+  {0.457363,0.253781},
+  {-0.258994,0.833024},
+  {-0.261108,-1.096423},
+  {-0.890548,-0.267881},
+  {-0.514366,-0.459512},
+  {0.812269,-0.123179},
+  {-0.034540,0.119925},
+  {-0.180841,0.846220},
+  {-0.752312,-0.637519},
+  {1.026199,1.242000},
+  {0.197854,-1.717988},
+  {0.475428,0.194479},
+  {0.292648,-0.864272},
+  {0.947169,-0.161454},
+  {-0.464096,-0.510604},
+  {1.153502,0.164372},
+  {0.487626,-1.698067},
+  {-0.435832,-0.248461},
+  {0.986247,0.332766},
+  {0.573550,0.450706},
+  {0.217594,-0.594628},
+  {0.411145,0.714235},
+  {-0.635136,1.259112},
+  {0.505637,0.257079},
+  {1.088652,0.088325},
+  {-0.412997,1.426823},
+  {0.773139,0.811379},
+  {1.222511,-1.367456},
+  {0.062337,0.036862},
+  {-0.941056,-0.307414},
+  {-0.219902,0.345179},
+  {-0.822663,-0.150728},
+  {-0.830573,0.243392},
+  {0.184643,-1.254941},
+  {0.044543,2.065648},
+  {-0.303212,0.177042},
+  {-1.024625,-0.575737},
+  {-1.766237,-0.128839},
+  {1.166984,-1.325277},
+  {0.296716,-0.350582},
+  {0.108368,-0.173239},
+  {0.820007,-0.685029},
+  {-1.179457,-1.230915},
+  {0.373694,-0.295121},
+  {0.792136,0.427746},
+  {0.908489,0.134038},
+  {0.112420,0.145958},
+  {-0.528428,-0.719873},
+  {-1.018138,-0.106810},
+  {0.487126,0.785684},
+  {-0.459239,1.922989},
+  {0.315122,-0.019843},
+  {0.271436,1.009157},
+  {-0.561563,-0.748185},
+  {-0.823416,-0.551511},
+  {-0.966122,-1.600366},
+  {0.213364,-0.578518},
+  {0.495633,-0.444785},
+  {-0.527658,1.519762},
+  {-0.069264,0.878791},
+  {-0.269854,0.404970},
+  {-0.610037,-0.956304},
+  {0.484475,0.633773},
+  {-0.168591,-0.969952},
+  {0.484383,1.817719},
+  {0.141585,0.111118},
+  {-1.199097,-0.051283},
+  {-0.528354,0.347269},
+  {0.475852,0.415654},
+  {0.228798,0.835716},
+  {-0.253920,0.038539},
+  {1.462540,-0.489890},
+  {-0.104670,-0.701368},
+  {-0.022712,-0.856311},
+  {-1.130025,0.873925},
+  {-0.019534,-0.883438},
+  {-0.193835,0.406293},
+  {-0.387684,0.052551},
+  {1.298327,-0.709101},
+  {-0.310405,0.001679},
+  {-0.481614,-0.685795},
+  {-1.062058,-0.520206},
+  {-1.344745,-0.153656},
+  {-0.831422,0.037292},
+  {0.400435,1.234084},
+  {0.727975,0.204297},
+  {0.824147,-0.809614},
+  {0.702855,-0.127743},
+  {-1.649216,1.142318},
+  {0.341254,0.448017},
+  {-0.898656,-0.789927},
+  {1.058227,-0.602215},
+  {-1.095050,-0.894509},
+  {-0.599427,-0.153097},
+  {-0.102633,0.228645},
+  {0.508210,0.665789},
+  {-0.535104,0.147440},
+  {-1.277860,-1.283381},
+  {-0.023286,0.344266},
+  {-0.632160,0.903716},
+  {0.360618,-0.187216},
+  {-0.390545,0.532805},
+  {-0.595274,1.078196},
+  {0.211172,-0.862871},
+  {0.328564,-0.792903},
+  {0.829098,0.198476},
+  {-0.566607,1.373401},
+  {-0.019308,0.285081},
+  {-0.888302,0.700636},
+  {0.148316,0.138057},
+  {1.181460,0.019935},
+  {0.392411,0.162331},
+  {-0.247861,0.263792},
+  {0.505014,-0.182329},
+  {0.628016,1.287511},
+  {0.212292,1.024624},
+  {0.687431,1.089767},
+  {0.564834,-0.028119},
+  {0.371715,-1.099486},
+  {0.357609,0.070059},
+  {2.215728,0.181810},
+  {0.836665,-0.244650},
+  {-0.220496,0.330559},
+  {0.676588,0.472829},
+  {-0.829341,-0.226416},
+  {0.744014,-0.881448},
+  {-0.729316,-0.218085},
+  {-0.984519,-0.858390},
+  {-0.487788,0.244053},
+  {-0.671190,-0.312322},
+  {0.049124,0.288241},
+  {-1.004947,0.620259},
+  {-0.321884,-0.417017},
+  {-0.493885,0.523531},
+  {-0.059619,-0.791344},
+  {-0.457605,0.691495},
+  {0.170169,-0.246006},
+  {1.075328,-0.540974},
+  {-0.079762,0.947477},
+  {-0.010670,-0.267796},
+  {0.943646,0.021645},
+  {-0.285628,-0.533131},
+  {-0.326849,0.040866},
+  {-1.421573,-0.739533},
+  {1.107711,-0.003967},
+  {1.000615,-0.065396},
+  {0.312538,-0.117636},
+  {-0.125344,-0.171464},
+  {-1.212099,-0.453897},
+  {0.288620,-0.519846},
+  {-0.248802,-1.402444},
+  {-0.310674,0.442311},
+  {0.098956,0.041407},
+  {-0.145050,1.286205},
+  {-0.429898,0.190147},
+  {-1.606072,0.685533},
+  {0.367341,0.528374},
+  {-0.074278,-0.544411},
+  {0.109107,0.601468},
+  {-0.454410,0.957520},
+  {0.453384,0.097285},
+  {-1.143893,0.610775},
+  {1.249307,-0.776195},
+  {0.494955,1.337840},
+  {0.242363,0.197588},
+  {-0.114836,-0.076961},
+  {-0.517306,0.086171},
+  {0.536084,0.234221},
+  {-0.269984,-0.404274},
+  {0.607933,-0.179944},
+  {1.480986,0.514357},
+  {-1.274472,-0.307237},
+  {0.687074,1.058117},
+  {-0.400117,0.313936},
+  {-0.791993,-0.417857},
+  {-0.561613,-0.645294},
+  {0.656279,-0.373169},
+  {0.740039,-0.034331},
+  {-0.240484,-0.434931},
+  {-0.485973,0.426967},
+  {0.234931,1.122127},
+  {0.391140,-0.409224},
+  {0.549154,0.884721},
+  {-0.915296,-0.762616},
+  {0.305934,-0.771631},
+  {-0.760185,0.255838},
+  {0.140172,0.086197},
+  {-0.136659,-1.801038},
+  {-0.285519,-1.066988},
+  {-0.359939,1.554395},
+  {0.289408,0.825934},
+  {0.461379,-0.152002},
+  {-0.806281,0.378343},
+  {-1.253917,-1.287774},
+  {-0.911462,-0.640941},
+  {0.986825,0.222918},
+  {0.108762,0.707578},
+  {0.028426,1.052636},
+  {0.337372,0.262425},
+  {-0.074310,-0.230538},
+  {-0.746241,-0.364158},
+  {0.184766,0.326757},
+  {0.299052,0.408284},
+  {0.454029,0.336521},
+  {-0.418725,-0.640634},
+  {-0.358958,0.325470},
+  {-0.113820,1.106193},
+  {0.097508,-0.640975},
+  {0.004309,0.013634},
+  {-0.103721,-0.180842},
+  {0.500274,0.105109},
+  {1.541197,0.972081},
+  {0.441451,-0.455017},
+  {0.040723,-0.995386},
+  {0.963317,-0.421559},
+  {1.402597,0.107761},
+  {1.587690,0.790156},
+  {-0.360062,0.069757},
+  {0.272024,-0.645917},
+  {0.182518,-0.169444},
+  {-0.720138,0.570094},
+  {-0.219343,-0.714791},
+  {0.364707,0.085334},
+  {1.238324,-0.048266},
+  {-0.069206,0.421442},
+  {-0.369665,0.405097},
+  {-0.125755,1.815291},
+  {1.339344,-0.722225},
+  {0.212585,0.318092},
+  {0.198631,-0.060546},
+  {0.526265,0.353971},
+  {-0.432338,0.914161},
+  {-0.259149,-0.485961},
+  {0.186000,-1.204080},
+  {0.143559,0.179813},
+  {0.174681,-0.217002},
+  {-0.535888,0.862929},
+  {0.138733,0.315051},
+  {-0.281155,-0.621632},
+  {0.825205,1.046364},
+  {-1.448150,0.028607},
+  {1.043647,-0.708319},
+  {0.579024,-0.187058},
+  {0.462025,-0.051373},
+  {0.080543,-0.987185},
+  {-0.422065,1.038899},
+  {1.245455,0.673572},
+  {0.120575,-0.872393},
+  {-0.935692,-0.049482},
+  {0.833592,0.112002},
+  {-0.280053,-0.923684},
+  {-0.352881,-0.159811},
+  {0.006592,0.880995},
+  {-0.334637,0.319727},
+  {1.600511,0.559890},
+  {-0.063299,0.518006},
+  {0.767673,-0.342292},
+  {0.894664,-1.056244},
+  {0.218239,-1.485107},
+  {1.313901,-0.284383},
+  {0.416552,0.516669},
+  {-0.945374,-0.353124},
+  {-1.444466,-0.478877},
+  {0.595701,-0.530269},
+  {0.321203,-0.859422},
+  {-0.202144,0.563280},
+  {-0.921581,-0.435354},
+  {-0.709879,-0.080659},
+  {0.850755,0.425879},
+  {0.371517,-0.722259},
+  {-0.655815,-0.005035},
+  {0.270087,0.539163},
+  {-0.233616,0.091892},
+  {0.062617,-0.648446},
+  {0.581563,-0.013480},
+  {-0.959711,2.092442},
+  {-1.236567,-0.286320},
+  {0.048573,-0.041422},
+  {-0.491037,-1.454069},
+  {1.001908,0.754578},
+  {-0.301879,0.407477},
+  {0.642198,0.246582},
+  {0.224810,0.092193},
+  {-0.272613,0.953599},
+  {-0.427767,1.107148},
+  {-0.212575,-0.673377},
+  {0.074416,-0.040497},
+  {0.889662,0.397214},
+  {-0.188469,0.498567},
+  {0.687591,1.144973},
+  {1.150738,-0.377170},
+  {-0.700195,0.414603},
+  {-1.226960,-0.280948},
+  {0.047836,-1.929469},
+  {-0.082189,-0.056623},
+  {-0.601386,-0.154564},
+  {-0.462696,0.956185},
+  {0.425110,0.342661},
+  {-0.840692,0.701600},
+  {-0.504892,0.547409},
+  {0.111847,0.714410},
+  {0.239928,-0.645067},
+  {-0.108924,-0.190042},
+  {-0.383790,0.092672},
+  {-1.208346,0.551190},
+  {0.603143,0.029640},
+  {-1.009036,-0.200890},
+  {-0.446945,-1.003718},
+  {0.765485,-1.039887},
+  {-0.480552,-0.196850},
+  {-0.203509,-0.820593},
+  {0.688553,0.072149},
+  {0.703177,-0.301738},
+  {0.086873,0.336471},
+  {-0.087231,-0.206545},
+  {0.269569,-0.857498},
+  {0.233124,0.128947},
+  {-0.484636,0.170069},
+  {-0.537166,0.776772},
+  {0.175699,-0.230826},
+  {0.085410,-0.018865},
+  {0.034945,-0.185273},
+  {0.569387,0.834000},
+  {0.947868,-0.930988},
+  {-0.100640,0.458731},
+  {1.002459,0.121581},
+  {1.059436,-0.068274},
+  {-0.421766,-0.185124},
+  {0.812700,-0.879198},
+  {1.381454,-0.394813},
+  {0.765729,-0.434247},
+  {-0.715909,-0.355391},
+  {0.073886,1.283928},
+  {0.489919,-0.471248},
+  {0.194977,1.066605},
+  {-0.578221,-0.425253},
+  {-0.406449,1.355422},
+  {-0.264036,-1.141037},
+  {-0.684424,0.475471},
+  {-0.556184,1.217787},
+  {-0.098804,0.291072},
+  {-2.004840,-0.218550},
+  {0.675484,0.712235},
+  {-0.467058,0.550342},
+  {-0.743855,2.418363},
+  {-0.778534,0.962859},
+  {-0.835465,-0.887622},
+  {0.044832,1.405487},
+  {0.309662,-1.836249},
+  {0.206982,-0.439087},
+  {0.960534,-2.043925},
+  {-0.543298,1.356592},
+  {0.928993,-0.616757},
+  {0.549173,0.603967},
+  {-0.430636,-0.012406},
+  {0.260641,0.304006},
+  {0.440114,-0.450592},
+  {0.231095,0.277928},
+  {0.209124,-0.466697},
+  {-0.960677,-1.002757},
+  {1.075456,-0.462500},
+  {-0.606526,0.152494},
+  {-0.182662,-0.659743},
+  {1.384662,-0.357479},
+  {-1.330588,-1.047178},
+  {0.502764,0.377201},
+  {-0.247289,0.855959},
+  {-0.012699,-0.113936},
+  {0.364142,0.075726},
+  {-0.269392,1.005615},
+  {1.370532,0.307236},
+  {1.142868,0.386704},
+  {0.440215,-0.324471},
+  {-0.033589,-0.638411},
+  {-0.327272,1.068003},
+  {-0.543571,-0.273416},
+  {-0.365062,-0.542959},
+  {1.250943,0.688743},
+  {0.472615,-0.098602},
+  {1.445136,0.536558},
+  {0.784735,-0.170791},
+  {0.064371,-0.779831},
+  {0.308675,-0.603152},
+  {1.586819,0.666450},
+  {0.639744,-1.202155},
+  {-0.627964,1.088006},
+  {-0.476573,0.282566},
+  {0.027772,0.994415},
+  {0.334959,1.192618},
+  {0.504855,0.281254},
+  {0.413815,0.195150},
+  {-0.592291,1.052660},
+  {0.079286,-1.324581},
+  {0.235540,-0.732265},
+  {-0.005819,-0.171668},
+  {0.067451,-0.441117},
+  {0.607046,-0.160835},
+  {-0.162694,0.829134},
+  {0.421080,0.189770},
+  {-0.116096,-0.441471},
+  {-1.205497,-0.460146},
+  {0.111566,0.707898},
+  {-0.674216,0.010199},
+  {-0.516917,-0.340492},
+  {-0.253736,-0.133809},
+  {0.293164,-0.493820},
+  {0.094884,1.329867},
+  {0.888509,0.028852},
+  {0.507446,0.428109},
+  {0.777171,-1.230643},
+  {0.888975,-0.258522},
+  {0.494596,0.073523},
+  {-0.528695,-0.616262},
+  {-0.133796,1.596729},
+  {0.042732,0.994114},
+  {0.187107,-0.683293},
+  {1.709562,-0.422073},
+  {-0.501284,-0.984705},
+  {0.979104,0.114013},
+  {0.619612,0.148485},
+  {0.265311,0.436067},
+  {-1.104922,0.399318},
+  {-0.844686,0.364787},
+  {0.045931,-1.764657},
+  {0.234470,0.330008},
+  {-0.745766,0.634961},
+  {1.040822,-1.192880},
+  {-0.924936,-0.069478},
+  {-0.559008,1.068087},
+  {-0.001940,-1.409943},
+  {-0.963420,-0.425440},
+  {-0.355644,-0.262865},
+  {-0.325353,0.688031},
+  {-0.505974,0.930113},
+  {-0.513432,0.014631},
+  {-0.641167,-0.464992},
+  {0.989676,0.899411},
+  {0.475176,1.152172},
+  {-0.649576,-0.471232},
+  {-0.544376,0.273234},
+  {-1.936626,0.360009},
+  {-0.788292,-0.146180},
+  {0.029239,0.663837},
+  {0.089389,-0.405482},
+  {-1.006432,0.041522},
+  {0.065737,0.170432},
+  {-0.536108,0.463754},
+  {0.249146,-0.505395},
+  {0.371547,-0.812264},
+  {-0.037906,-1.072131},
+  {0.484523,-1.128252},
+  {-0.715915,-0.328589},
+  {-0.274512,0.228612},
+  {-0.058716,0.021879},
+  {0.702693,-0.158524},
+  {-0.151997,0.473194},
+  {-0.852896,-0.326452},
+  {-0.100443,0.365915},
+  {-0.955887,0.394822},
+  {-0.208727,-0.344079},
+  {-0.131318,0.157507},
+  {0.210001,0.434525},
+  {-1.062122,-0.117708},
+  {-0.346687,-0.182016},
+  {0.654369,-0.500059},
+  {-0.307734,-0.826574},
+  {0.155367,1.735056},
+  {1.858707,-0.541347},
+  {-0.268982,0.440984},
+  {0.216965,-1.158686},
+  {-0.431159,-1.260753},
+  {-1.785308,-0.584553},
+  {0.261771,0.584204},
+  {1.451317,-0.742810},
+  {-0.004668,-0.752829},
+  {-0.024921,1.245290},
+  {0.595504,0.565095},
+  {0.960266,-0.329771},
+  {0.326327,0.550239},
+  {-0.863137,0.203973},
+  {-0.380078,-0.435468},
+  {1.090459,-0.823282},
+  {-0.356638,0.283852},
+  {0.682541,0.012101},
+  {-0.308431,0.770005},
+  {1.199072,0.069286},
+  {-1.046700,1.675759},
+  {-0.077715,0.534336},
+  {-0.222926,0.910906},
+  {0.261806,0.566523},
+  {0.420022,-0.553801},
+  {-1.412877,0.700632},
+  {0.797401,0.323269},
+  {-0.694224,0.960901},
+  {0.533299,0.850659},
+  {-0.991622,1.002736},
+  {-0.028049,0.666471},
+  {0.715754,-0.271882},
+  {0.578916,0.553135},
+  {0.231987,0.123384},
+  {-0.109185,-1.359211},
+  {-0.398565,0.173967},
+  {-0.043014,-0.665217},
+  {-1.225856,0.628940},
+  {-0.929289,-1.132390},
+  {1.603272,0.818561},
+  {-0.103226,-0.692397},
+  {0.141116,1.383120},
+  {-0.400579,0.668820},
+  {0.143826,-0.222660},
+  {0.333041,-0.807693},
+  {-0.320005,0.808184},
+  {0.629822,-0.286580},
+  {-0.772778,1.724556},
+  {1.386505,0.462035},
+  {-0.229246,-1.474260},
+  {-0.503459,1.044767},
+  {-0.250001,0.561403},
+  {0.012072,-0.058950},
+  {0.756583,0.503015},
+  {-0.335019,-0.761904},
+  {-0.682864,0.003814},
+  {0.068344,0.231416},
+  {0.256777,-0.369994},
+  {-0.282520,-0.095213},
+  {-0.187083,-0.559020},
+  {-0.026183,-0.522028},
+  {-0.650853,-0.769108},
+  {0.035804,-0.431890},
+  {0.030008,-0.399347},
+  {-0.287980,-0.145851},
+  {-0.677012,-0.560565},
+  {-1.049641,-0.861592},
+  {0.312580,0.091289},
+  {-0.963485,0.211167},
+  {0.287165,-0.371532},
+  {0.555650,-0.838435},
+  {0.395525,-0.449511},
+  {0.252774,-0.490994},
+  {-0.688084,-0.314271},
+  {-0.402613,0.309283},
+  {0.511800,-0.453051},
+  {1.035475,-0.441895},
+  {-0.655559,0.204947},
+  {-0.683300,-0.428916},
+  {0.387642,0.043918},
+  {-0.179349,-0.651814},
+  {-0.493107,1.155292},
+  {-0.030356,0.289986},
+  {0.652280,1.046866},
+  {0.057809,1.266974},
+  {0.215742,1.064339},
+  {0.447729,-0.632852},
+  {0.279966,-0.339154},
+  {-0.166371,-1.026682},
+  {0.421910,0.351254},
+  {-0.254637,-0.154264},
+  {-1.334090,-0.110719},
+  {-0.566168,-1.155950},
+  {-0.558998,0.207397},
+  {-0.055417,0.648158},
+  {-0.241039,-0.287178},
+  {-0.582347,-1.040992},
+  {-0.289176,0.447352},
+  {0.564223,-0.500253},
+  {0.200212,0.121773},
+  {0.752287,0.131198},
+  {-0.586207,-0.250267},
+  {0.752385,-1.118821},
+  {-0.454050,0.686154},
+  {0.421964,-0.071049},
+  {0.385670,0.105139},
+  {-0.883155,0.420629},
+  {0.582838,0.829220},
+  {1.599990,0.302506},
+  {-0.711621,-0.048242},
+  {-0.769061,-0.939823},
+  {-0.570805,1.221850},
+  {0.746084,0.370521},
+  {-1.095763,0.542099},
+  {0.507870,-0.028658},
+  {-0.006494,-0.140681},
+  {1.123004,0.639325},
+  {0.023228,-0.243014},
+  {2.006419,-0.925360},
+  {0.244315,0.241295},
+  {0.714233,0.041423},
+  {0.930361,1.159843},
+  {-0.439284,-1.104778},
+  {-2.044038,1.046255},
+  {-0.247643,-0.295368},
+  {-0.496474,-0.188701},
+  {0.427399,-0.103610},
+  {-0.048929,-0.755309},
+  {-0.378127,-0.657410},
+  {0.647217,0.149609},
+  {0.628906,-1.593151},
+  {-0.581867,-0.372896},
+  {-0.483963,-0.772021},
+  {-1.279053,-0.372171},
+  {-0.505264,-0.021054},
+  {-1.130825,0.247607},
+  {0.329896,1.593840},
+  {-0.312292,-0.619026},
+  {-0.024599,0.020700},
+  {-0.647591,-0.690874},
+  {1.248162,1.039611},
+  {-0.252032,0.173910},
+  {0.311838,-0.632350},
+  {-1.024234,0.131065},
+  {0.035961,-1.216873},
+  {0.477173,0.507557},
+  {-1.295462,-0.451069},
+  {-0.377181,1.110673},
+  {0.706351,-0.382557},
+  {-0.134564,-0.499312},
+  {0.566652,-0.673370},
+  {-0.967847,-0.852623},
+  {-0.139758,-2.138448},
+  {-0.176702,0.054714},
+  {0.043205,0.100348},
+  {-1.012144,-0.515393},
+  {0.620692,-0.001168},
+  {-0.231469,0.384359},
+  {0.167537,0.294412},
+  {-0.061414,-0.366999},
+  {0.731633,0.876544},
+  {1.154343,0.803758},
+  {0.412281,0.559052},
+  {-0.371725,-1.273328},
+  {0.957476,-1.378973},
+  {0.289512,-0.991069},
+  {-0.578394,-1.421610},
+  {0.015914,0.322132},
+  {0.106358,-1.449675},
+  {-0.069120,0.739722},
+  {0.531874,-0.371638},
+  {0.657279,0.323686},
+  {0.037083,-0.796566},
+  {1.061708,-0.965017},
+  {0.413730,0.054267},
+  {0.521430,1.075811},
+  {0.856354,-0.905745},
+  {0.373586,-0.270185},
+  {0.791206,-0.986693},
+  {0.729893,0.860268},
+  {0.043905,-0.429560},
+  {-0.656692,-1.039828},
+  {0.555913,1.767401},
+  {0.303388,-0.323869},
+  {-0.125446,-0.255745},
+  {1.117126,0.195974},
+  {-0.992980,0.304440},
+  {-0.382740,0.426044},
+  {-0.223638,-0.152487},
+  {1.023637,-0.350714},
+  {0.245655,-0.157361},
+  {-0.111659,-0.614165},
+  {0.354600,0.026794},
+  {-0.027813,0.532690},
+  {0.245690,0.739772},
+  {-0.504872,-0.794998},
+  {-0.809269,-1.094385},
+  {-1.001891,-0.480770},
+  {-0.465059,0.023020},
+  {0.229876,-0.151501},
+  {-1.141435,-0.029146},
+  {-0.937562,-0.801157},
+  {-0.195200,-2.144830},
+  {0.101337,0.587135},
+  {0.153064,-0.325187},
+  {-0.583504,-1.060043},
+  {-0.098906,-0.330180},
+  {-0.216563,-0.818141},
+  {-0.211935,-0.707920},
+  {0.636668,0.028993},
+  {-0.758271,-0.108885},
+  {-0.706584,0.097759},
+  {1.376119,0.384825},
+  {0.420516,1.213370},
+  {1.030631,-0.077473},
+  {-1.252726,1.002692},
+  {0.487495,0.456548},
+  {0.682253,0.398622},
+  {0.147446,-0.079877},
+  {0.722369,-0.614144},
+  {0.378631,-0.601790},
+  {0.075497,0.837757},
+  {0.199081,0.445597},
+  {0.535089,0.570803},
+  {-0.122319,0.373349},
+  {-0.321298,0.741177},
+  {0.903177,-0.013977},
+  {-0.583050,-0.924612},
+  {0.066698,1.396794},
+  {0.408667,0.958962},
+  {-0.738580,-1.497866},
+  {0.600777,-0.398895},
+  {0.254742,0.347824},
+  {-0.265817,0.876722},
+  {0.907423,0.129822},
+  {-0.114962,-0.826617},
+  {-0.240360,-0.143947},
+  {0.148077,-0.071668},
+  {-0.212910,1.016550},
+  {-0.013388,-1.067770},
+  {0.046668,-0.442470},
+  {0.256538,-0.318212},
+  {-0.250360,1.417343},
+  {-0.775082,1.038648},
+  {1.220756,-0.342349},
+  {-0.032158,-0.172829},
+  {0.922113,0.382379},
+  {1.047628,0.944538},
+  {0.885199,-0.041166},
+  {-1.458274,0.373000},
+  {0.855979,0.373876},
+  {0.431145,0.483826},
+  {-0.019854,-1.320043},
+  {0.213858,-0.134150},
+  {-1.273584,-0.203977},
+  {-0.916604,0.918129},
+  {-0.768406,-1.109353},
+  {-0.278667,-0.372253},
+  {0.878634,0.434317},
+  {-1.182409,0.691791},
+  {-0.166143,0.370502},
+  {-0.371636,-0.617445},
+  {0.836100,-1.092805},
+  {0.179593,2.209969},
+  {-0.760372,-0.186876},
+  {0.580655,0.070447},
+  {0.637695,-1.328039},
+  {-0.210008,0.169876},
+  {0.107828,-1.200689},
+  {0.689020,0.461975},
+  {0.799638,-0.225619},
+  {0.549319,0.257945},
+  {-0.169926,-0.062423},
+  {-1.000681,-1.230883},
+  {-0.280677,-0.889594},
+  {-0.365240,0.176973},
+  {-0.496268,-1.327882},
+  {-0.051553,1.031328},
+  {-1.118158,1.437687},
+  {0.069181,-0.263582},
+  {0.034310,0.657226},
+  {-0.665250,-0.249209},
+  {-0.265277,-0.231715},
+  {0.768583,-0.439151},
+  {-0.516311,1.258394},
+  {-1.062635,-0.480988},
+  {0.768868,1.387988},
+  {-0.133561,-0.253474},
+  {0.174635,-0.763359},
+  {0.207988,0.224757},
+  {0.171049,1.245499},
+  {-0.923550,1.085739},
+  {0.631564,-1.467559},
+  {-0.160409,0.068830},
+  {-0.008023,-1.455924},
+  {0.180831,-0.762764},
+  {0.303099,2.221159},
+  {0.032024,0.734284},
+  {0.086762,-0.565552},
+  {-0.273328,1.536368},
+  {-0.101105,-0.703900},
+  {0.023821,-0.404259},
+  {0.138986,-0.943679},
+  {-0.511459,0.739696},
+  {-1.031153,0.329790},
+  {-0.038206,-0.799769},
+  {0.440881,-0.555912},
+  {0.023990,-0.531059},
+  {0.659228,-0.843024},
+  {-0.826474,-0.770692},
+  {0.946334,-1.545003},
+  {0.261025,-0.113739},
+  {0.048911,-1.179110},
+  {0.060770,-0.859467},
+  {-0.785178,-0.587693},
+  {-0.381189,0.094381},
+  {0.630990,-0.822901},
+  {0.013473,-0.408986},
+  {-1.789311,0.714900},
+  {1.519795,-0.195693},
+  {-0.701243,0.864168},
+  {-0.915110,0.072452},
+  {-1.261997,1.360065},
+  {-0.163284,0.527620},
+  {0.649672,-0.335824},
+  {0.610109,0.962789},
+  {1.048801,-0.879891},
+  {-1.064425,-1.265436},
+  {0.105428,-0.129546},
+  {1.539402,-0.029218},
+  {-0.431054,-0.384473},
+  {0.440965,-1.503971},
+  {-0.553600,0.461140},
+  {0.432415,-0.588674},
+  {0.466966,0.767686},
+  {-1.282511,-0.822551},
+  {-0.405750,-0.169677},
+  {-0.529296,-0.256420},
+  {0.333425,-0.212289},
+  {0.351865,-1.052035},
+  {-0.372759,-0.324327},
+  {0.496838,0.426941},
+  {0.521469,0.729775},
+  {-0.360286,0.330552},
+  {-0.939280,-0.731402},
+  {-0.589460,0.375702},
+  {0.473278,0.562849},
+  {0.907852,0.477585},
+  {-1.161415,0.674441},
+  {-0.978026,0.108291},
+  {-0.646718,0.244958},
+  {-0.037385,-0.220525},
+  {-0.453012,0.255493},
+  {0.903459,-0.255742},
+  {-0.099331,0.318876},
+  {0.002754,-0.225539},
+  {0.134105,-0.165745},
+  {1.240310,-0.105975},
+  {0.009197,0.949681},
+  {-0.673977,0.458706},
+  {0.679855,-0.534481},
+  {-0.073767,0.277108},
+  {0.277924,-0.047804},
+  {0.415045,-0.608651},
+  {0.122556,0.982192},
+  {-0.446661,-0.313225},
+  {1.173726,1.220580},
+  {-1.593188,0.789350},
+  {-1.834105,-1.079304},
+  {0.107095,-0.091381},
+  {1.110756,0.061581},
+  {-0.917192,0.734789},
+  {0.348696,-1.323831},
+  {0.010933,1.090009},
+  {-0.106413,-0.322089},
+  {-0.860837,-0.506303},
+  {0.627199,0.541836},
+  {-0.139889,-0.512866},
+  {0.637993,0.510208},
+  {-1.167249,-0.146076},
+  {-0.862119,0.394909},
+  {-1.240754,0.494548},
+  {-0.376744,0.672959},
+  {-0.999381,0.637653},
+  {-1.391600,0.390940},
+  {0.955660,-0.769621},
+  {0.310879,-0.798671},
+  {0.408795,-0.452281},
+  {-0.974719,-0.029192},
+  {0.311104,0.273352},
+  {0.026062,-0.858645},
+  {0.556329,0.206713},
+  {0.094267,-1.481594},
+  {-0.356078,0.544259},
+  {-0.033796,-0.245353},
+  {0.203784,0.331156},
+  {0.096733,2.575388},
+  {-0.381793,0.290671},
+  {-0.116102,-0.156839},
+  {0.161793,0.594064},
+  {-0.321204,-1.339815},
+  {-1.090421,-0.762797},
+  {0.787900,0.459478},
+  {0.243785,0.940882},
+  {-0.153906,0.841058},
+  {-0.936971,1.541452},
+  {-0.439278,-0.322908},
+  {-1.066801,-0.222840},
+  {0.629434,-0.352457},
+  {-0.202999,0.278222},
+  {-0.505916,0.969990},
+  {0.396149,-0.315510},
+  {-0.829205,-0.140890},
+  {-0.660853,-0.447071},
+  {-0.699586,0.850048},
+  {-0.706088,0.377818},
+  {-0.876828,0.869990},
+  {0.937227,-0.354026},
+  {-1.149567,-0.878271},
+  {-0.807950,-0.806797},
+  {-0.733349,-1.050036},
+  {0.134549,-1.452923},
+  {0.623023,0.412688},
+  {0.119168,-1.377420},
+  {0.682589,0.820573},
+  {0.800743,-0.117315},
+  {-0.930976,-0.305719},
+  {0.007050,0.193402},
+  {1.580681,0.605792},
+  {0.281324,0.201371},
+  {0.005740,1.007009},
+  {0.993450,-0.268242},
+  {0.289972,-0.080020},
+  {0.206252,0.023882},
+  {-0.015665,-2.024198},
+  {0.371283,-1.340106},
+  {-0.213033,-0.457500},
+  {0.263077,-0.366399},
+  {0.710898,-1.090262},
+  {0.677746,-1.151681},
+  {1.238201,-0.610042},
+  {0.325461,-1.103737},
+  {-0.980765,-0.488024},
+  {-0.077484,0.774584},
+  {0.496364,0.004649},
+  {0.643821,1.447878},
+  {-0.743024,-1.112741},
+  {-0.195607,0.639318},
+  {-0.080202,0.412438},
+  {0.916875,0.189103},
+  {-0.106268,0.390295},
+  {0.715604,-0.486286},
+  {0.115849,1.370489},
+  {-0.576103,1.129486},
+  {0.935521,-0.616187},
+  {-0.914664,0.196014},
+  {0.360647,0.177486},
+  {0.442306,-0.048782},
+  {-1.345507,0.159373},
+  {-1.024007,-1.295577},
+  {0.303087,-0.450638},
+  {0.225152,-0.356881},
+  {-0.503513,-0.770894},
+  {-0.333461,-1.843134},
+  {-0.432863,-0.889999},
+  {-0.784493,-0.566774},
+  {0.410618,0.701420},
+  {0.136290,-1.037936},
+  {0.145021,0.974063},
+  {0.529589,0.128197},
+  {-0.676674,-0.971814},
+  {-0.270406,1.019808},
+  {0.096367,-0.838265},
+  {0.318717,-0.762441},
+  {0.397090,0.756928},
+  {0.648969,0.667148},
+  {-0.913693,-0.162627},
+  {0.119623,0.022965},
+  {0.555892,0.378100},
+  {0.900717,0.703179},
+  {-0.046262,-0.721821},
+  {-1.181653,0.505205},
+  {0.465203,-0.477470},
+  {0.046090,-0.627510},
+  {-0.363122,-0.091161},
+  {0.953653,1.039114},
+  {-0.789380,-0.928026},
+  {0.162396,0.803479},
+  {-0.835156,-0.260672},
+  {0.250119,-0.467056},
+  {0.218336,0.454615},
+  {0.209926,1.190928},
+  {-1.178592,-0.891917},
+  {0.550639,-0.793167},
+  {-1.985065,-1.044282},
+  {-0.196421,-0.054591},
+  {0.084188,-0.363259},
+  {-0.505210,-0.803844},
+  {1.240644,-0.301110},
+  {0.512258,-0.469191},
+  {-1.549377,0.756018},
+  {-0.614481,-0.080973},
+  {-0.744195,-0.048617},
+  {0.879512,-0.837412},
+  {-1.089793,1.223308},
+  {1.011531,0.192099},
+  {0.335207,-0.361593},
+  {0.976295,-0.603421},
+  {-0.220526,-0.371096},
+  {-1.002946,0.716884},
+  {-0.444541,-0.037052},
+  {-0.477626,0.295812},
+  {-1.046918,-2.279811},
+  {0.133746,-0.120300},
+  {0.279460,0.397052},
+  {-0.663998,0.035170},
+  {1.121487,0.680845},
+  {1.108689,1.142655},
+  {0.380884,1.253683},
+  {0.106635,-0.096270},
+  {0.651713,-1.297000},
+  {0.481130,-0.876693},
+  {-2.086800,0.062748},
+  {0.502741,0.743331},
+  {-0.634120,0.417364},
+  {0.332408,-1.807629},
+  {0.288393,-0.248269},
+  {-0.589845,0.528027},
+  {-0.953016,0.010891},
+  {1.215645,-1.463684},
+  {0.179478,-0.118753},
+  {0.304072,0.579308},
+  {-0.786558,-1.384700},
+  {1.545828,0.671325},
+  {-1.103380,0.496542},
+  {0.566262,0.207667},
+  {0.168035,-0.084493},
+  {-0.745029,0.787807},
+  {-0.008405,0.486130},
+  {-1.256400,-0.811337},
+  {-0.421056,-0.997844},
+  {-0.129980,-0.010057},
+  {0.683615,0.299871},
+  {0.171174,-0.371855},
+  {0.239929,-0.288358},
+  {0.736989,0.844517},
+  {0.502939,-0.293006},
+  {-0.078536,-0.030891},
+  {0.889214,0.617627},
+  {0.107697,-0.504655},
+  {-0.322943,-0.180390},
+  {-0.659880,-0.211751},
+  {-0.425630,1.220749},
+  {1.564708,1.804423},
+  {-0.562868,0.198486},
+  {-0.064851,-0.014952},
+  {-0.685409,0.304867},
+  {1.341588,0.203554},
+  {0.391212,-0.841740},
+  {0.700891,0.658326},
+  {-0.301305,0.902339},
+  {-0.046588,0.019530},
+  {0.415121,-0.949705},
+  {-0.410635,-0.231837},
+  {0.615095,1.334066},
+  {-0.067261,0.324586},
+  {0.167043,-1.136141},
+  {0.422422,0.696197},
+  {0.584087,0.667480},
+  {-0.551074,0.249301},
+  {0.421860,-0.454014},
+  {-0.585820,-0.664637},
+  {-0.071516,0.815123},
+  {-0.541864,0.195446},
+  {0.866604,-1.519052},
+  {-1.811300,0.473683},
+  {-0.412564,0.863621},
+  {-0.125827,-0.223240},
+  {0.963505,0.064195},
+  {0.096324,-0.017230},
+  {-0.559212,0.385040},
+  {-0.071234,0.362721},
+  {-0.783611,-1.711285},
+  {-0.466996,-0.665663},
+  {-0.422348,0.153831},
+  {0.031726,0.347303},
+  {0.126585,0.194805},
+  {1.089699,-0.115948},
+  {0.261952,1.193404},
+  {-0.062577,0.658827},
+  {1.046650,1.250723},
+  {0.343986,-0.385875},
+  {0.398418,-1.112678},
+  {0.397788,0.432553},
+  {-0.081351,-0.869887},
+  {0.115778,-1.810748},
+  {1.089135,0.283668},
+  {0.348676,-0.215081},
+  {0.990831,0.340013},
+  {-0.429526,0.150394},
+  {-0.209451,-0.426354},
+  {1.251426,0.387939},
+  {-0.941099,-0.048392},
+  {0.553432,0.490465},
+  {0.820341,-0.892655},
+  {-0.469979,0.215954},
+  {-0.111752,-0.518634},
+  {-0.322742,0.282748},
+  {-0.131831,-0.096259},
+  {0.928465,0.491990},
+  {-0.131168,0.713177},
+  {1.182858,-0.137778},
+  {0.498624,0.596945},
+  {-0.340255,1.333451},
+  {-0.263143,-0.178530},
+  {-0.853000,-0.367513},
+  {0.645533,0.217256},
+  {-0.222484,-0.050816},
+  {-0.889767,0.961630},
+  {-0.559303,-0.335849},
+  {0.755808,1.224325},
+  {-0.295347,-0.382986},
+  {0.154238,0.489334},
+  {0.806167,0.600666},
+  {-1.440967,0.906005},
+  {0.400307,-1.289369},
+  {-1.322768,0.271201},
+  {0.721328,-0.415260},
+  {0.328246,0.162043},
+  {1.063849,-0.169918},
+  {0.661691,0.188712},
+  {-0.393050,-0.106635},
+  {-0.924026,-0.264599},
+  {-0.379871,-0.638547},
+  {1.648221,0.026247},
+  {1.111263,0.149709},
+  {0.176878,-1.278937},
+  {0.734091,0.194270},
+  {0.643210,-0.024985},
+  {-0.703541,-0.377990},
+  {0.786560,0.295150},
+  {1.646656,-0.147934},
+  {-0.361062,0.674906},
+  {-0.317120,0.143807},
+  {-1.310888,-0.164024},
+  {0.035068,0.189815},
+  {-0.787682,0.694272},
+  {-0.057575,-0.198782},
+  {0.037946,-1.261234},
+  {0.789551,0.167209},
+  {0.163492,1.280868},
+  {1.486117,0.344385},
+  {-0.259139,-0.046155},
+  {-0.720616,-0.687107},
+  {0.332266,0.269337},
+  {0.677660,-0.080123},
+  {0.221776,0.671525},
+  {-1.286564,-1.026638},
+  {-0.137566,-0.439496},
+  {1.253971,-1.647977},
+  {-1.082200,-0.445719},
+  {-0.166409,-0.650523},
+  {-0.453263,0.213402},
+  {-0.017712,-0.128208},
+  {-0.032769,-0.405644},
+  {-0.219371,-0.017666},
+  {-0.799480,-1.769117},
+  {-0.532850,0.965634},
+  {-0.686125,-1.467377},
+  {-0.633034,-0.389067},
+  {-0.150331,0.782007},
+  {-0.691980,0.730198},
+  {-0.597063,-0.279026},
+  {0.834946,0.396175},
+  {-0.078053,-0.123351},
+  {-0.571384,-0.618287},
+  {0.325004,0.114546},
+  {0.411609,1.274331},
+  {0.206788,-0.139653},
+  {-1.090128,0.800625},
+  {-0.412709,0.694443},
+  {-0.162932,1.311011},
+  {0.397417,-0.737950},
+  {-0.100183,0.447697},
+  {1.213408,-1.126972},
+  {0.034492,0.978029},
+  {-0.872335,-0.584584},
+  {0.568310,0.904579},
+  {-0.453700,0.703082},
+  {-1.230769,0.813793},
+  {-0.851555,0.357280},
+  {0.604006,0.281641},
+  {0.411237,0.367925},
+  {-0.750405,-1.252638},
+  {0.260416,0.091677},
+  {0.333514,-1.104021},
+  {0.782219,0.587118},
+  {-0.200975,-0.528729},
+  {-0.332689,-1.636132},
+  {-0.415304,-0.010511},
+  {-0.121022,0.354709},
+  {0.994143,0.280846},
+  {0.138590,-0.213242},
+  {-0.193256,-0.095752},
+  {-0.441602,0.259315},
+  {0.948753,0.001788},
+  {0.898141,-0.750677},
+  {1.346054,0.626588},
+  {0.381400,-0.493532},
+  {-1.338972,0.327082},
+  {0.220140,-0.344755},
+  {0.656912,-0.469924},
+  {1.263170,0.096743},
+  {0.070575,-0.775336},
+  {0.716447,1.747781},
+  {0.298510,0.135103},
+  {0.022491,0.885968},
+  {0.142852,0.482053},
+  {-0.434061,-0.439810},
+  {0.694127,0.094622},
+  {0.448201,-0.299757},
+  {0.087507,0.008116},
+  {0.250792,0.103017},
+  {-0.059841,-0.687843},
+  {-0.071647,0.860597},
+  {0.728315,0.820186},
+  {-0.640044,0.101480},
+  {0.211384,0.028702},
+  {-0.457781,0.490619},
+  {-0.178352,-0.304710},
+  {-0.563754,-0.733470},
+  {-0.770274,0.082873},
+  {-0.762355,1.140889},
+  {0.797291,0.304485},
+  {-0.057014,-0.903306},
+  {-0.158813,0.075113},
+  {-0.874554,0.299985},
+  {-1.282132,-0.277777},
+  {0.150378,-1.322159},
+  {0.433856,-0.000391},
+  {0.119086,-0.850105},
+  {0.204912,0.316619},
+  {-0.757190,-0.377894},
+  {-0.896753,1.076560},
+  {1.182092,-0.196822},
+  {0.699797,0.526050},
+  {0.405838,-0.496715},
+  {-0.834600,-0.037964},
+  {0.545939,0.047411},
+  {-0.771625,0.127979},
+  {0.625542,0.978054},
+  {0.578050,1.339611},
+  {-0.854615,-0.162544},
+  {0.803070,-1.575209},
+  {-0.722438,0.809655},
+  {0.812986,-0.021617},
+  {0.617012,0.621875},
+  {-0.694562,-0.359274},
+  {0.819084,0.571131},
+  {0.605917,-0.877233},
+  {-0.166467,-0.432090},
+  {-0.763237,0.021539},
+  {-1.007144,0.682364},
+  {-0.012074,-1.138787},
+  {-0.793479,0.734741},
+  {0.950373,-0.774179},
+  {0.714255,-0.444826},
+  {-1.824486,-1.178179},
+  {0.286283,-1.022538},
+  {0.371641,0.412646},
+  {1.221297,-0.075273},
+  {0.513217,0.452413},
+  {0.015385,-0.341663},
+  {-0.926360,0.470885},
+  {-0.515633,0.282595},
+  {-0.876782,0.148065},
+  {-0.204097,-0.416771},
+  {0.581214,0.730282},
+  {0.150986,-0.721883},
+  {-0.919574,-0.518872},
+  {-1.025393,1.032902},
+  {-0.571691,-0.523905},
+  {0.336729,0.277443},
+  {0.077651,0.017905},
+  {-0.049717,0.473017},
+  {-0.410902,-0.770257},
+  {-0.847206,0.198044},
+  {0.356753,0.100081},
+  {0.580691,0.400755},
+  {0.718459,0.870265},
+  {0.779366,0.466430},
+  {-1.046243,-1.317550},
+  {-0.248241,-0.184969},
+  {0.626921,0.660065},
+  {0.772665,-1.467408},
+  {0.189100,0.479679},
+  {-1.027175,1.032229},
+  {-0.110106,-0.214123},
+  {-0.434741,0.523121},
+  {-0.947316,0.197282},
+  {0.241363,0.711876},
+  {-0.790393,-0.270092},
+  {-0.264741,0.345775},
+  {0.814247,-0.835493},
+  {0.947799,0.460240},
+  {0.505144,0.380228},
+  {-0.473087,-0.638790},
+  {0.543595,-0.001347},
+  {-0.682112,0.627895},
+  {-0.405487,0.778655},
+  {0.090159,-1.164412},
+  {-1.021743,-1.421425},
+  {-0.149220,-0.891920},
+  {0.763872,-0.387818},
+  {0.447078,0.686021},
+  {0.054443,0.941294},
+  {0.946171,-0.217788},
+  {-0.490974,1.129098},
+  {0.729449,0.252452},
+  {0.815682,-0.189074},
+  {0.788805,-1.240450},
+  {0.942122,-1.379303},
+  {-0.702094,0.893805},
+  {-1.031257,0.993462},
+  {-0.515607,-1.598744},
+  {-1.242896,0.696992},
+  {0.462112,-1.234721},
+  {-1.005724,0.703223},
+  {0.475509,1.468536},
+  {0.087152,0.401476},
+  {-1.961801,0.527485},
+  {-0.277783,0.792785},
+  {0.499758,-0.094692},
+  {0.592984,-0.740657},
+  {-0.369076,-0.004060},
+  {0.610104,-0.671913},
+  {-0.127590,0.291879},
+  {-0.769939,-0.549296},
+  {-0.110371,-0.651391},
+  {-0.324962,-0.638560},
+  {-0.366826,1.409327},
+  {0.365052,-0.587005},
+  {-0.316704,-0.411182},
+  {-0.769326,-0.018427},
+  {0.918326,-0.205236},
+  {1.455609,1.087051},
+  {0.844860,-0.653147},
+  {1.020463,0.280075},
+  {0.559389,-0.768862},
+  {-1.792332,-0.215746},
+  {0.196068,-0.074482},
+  {-0.613620,-0.906514},
+  {-0.602302,1.210484},
+  {1.537292,0.306783},
+  {-0.008903,-0.974294},
+  {-0.532771,-0.265199},
+  {-0.018499,-0.535834},
+  {-0.014195,0.748767},
+  {0.353076,-0.075319},
+  {0.434187,0.928206},
+  {-0.355526,0.282319},
+  {0.211333,0.311046},
+  {-0.589182,-0.031620},
+  {1.002223,0.023921},
+  {-0.601628,-0.329293},
+  {0.424415,0.068179},
+  {-1.155585,0.516343},
+  {0.515025,0.512588},
+  {-0.779358,0.737289},
+  {-0.532136,-0.528990},
+  {0.246092,0.038006},
+  {-1.225133,0.620487},
+  {-0.200500,-0.297832},
+  {-0.419124,-0.629269},
+  {0.857102,-0.394516},
+  {-0.627349,0.023525},
+  {-0.480722,0.194265},
+  {-0.967646,-0.289770},
+  {-0.811645,0.778058},
+  {-0.330038,0.486357},
+  {-0.188439,0.216193},
+  {0.089880,-0.920053},
+  {0.123710,-0.395635},
+  {0.590314,0.051432},
+  {-0.400984,0.472685},
+  {-0.482473,-0.081664},
+  {1.021624,1.195570},
+  {-0.641330,-0.310074},
+  {-0.191657,-0.668057},
+  {0.057035,0.868019},
+  {0.161342,0.290908},
+  {-0.914313,1.611466},
+  {0.752373,1.180590},
+  {-0.023547,1.358874},
+  {-0.891893,0.622478},
+  {-0.627566,-0.215932},
+  {0.569484,-0.032047},
+  {0.151811,0.537318},
+  {0.643493,-0.211765},
+  {-0.277706,0.641965},
+  {-0.055308,0.040286},
+  {0.133963,-0.238700},
+  {-0.927043,0.438230},
+  {0.737539,-1.090991},
+  {-0.258609,0.790912},
+  {-0.248323,-0.881598},
+  {0.220905,1.051752},
+  {0.439683,-0.240808},
+  {-0.081260,-0.429267},
+  {-0.893930,-0.301145},
+  {0.216628,0.563682},
+  {0.495748,-0.625961},
+  {-0.484015,-1.195660},
+  {-0.717614,-0.328233},
+  {-0.601530,-0.572201},
+  {-0.055818,0.060060},
+  {0.301962,0.128367},
+  {-0.314449,-0.022201},
+  {-1.088724,0.633684},
+  {-0.576006,0.352197},
+  {-0.476385,-0.096264},
+  {-1.326078,-0.103745},
+  {-0.458658,-0.228827},
+  {0.123811,0.703156},
+  {-1.208584,0.467840},
+  {0.733960,0.272324},
+  {-0.531940,0.601927},
+  {-0.203491,0.765397},
+  {0.282851,0.489174},
+  {-1.410437,0.224490},
+  {-0.438276,-0.013360},
+  {-0.061401,-0.259781},
+  {-0.014421,-0.307778},
+  {-0.475161,1.111264},
+  {0.769111,0.441227},
+  {0.172795,-0.268608},
+  {0.979869,0.135185},
+  {-0.528977,-0.205653},
+  {-0.045259,0.027604},
+  {0.722821,0.789841},
+  {-0.039846,-0.938385},
+  {0.589344,0.223276},
+  {-1.022671,-0.084817},
+  {0.041763,-1.074842},
+  {-0.588962,0.459411},
+  {0.305630,-0.951329},
+  {-0.688286,-0.717012},
+  {-0.239280,-0.054100},
+  {0.466996,-0.578716},
+  {0.515927,-0.146469},
+  {0.728230,1.345576},
+  {0.418004,1.320527},
+  {-0.518194,0.757005},
+  {0.012964,-1.615714},
+  {-0.952324,-0.315730},
+  {-0.857139,0.027421},
+  {0.114293,0.309591},
+  {-0.844651,-0.223144},
+  {-0.928183,1.192097},
+  {-1.023982,-0.343621},
+  {-1.048939,-0.345626},
+  {0.164567,0.377517},
+  {0.836105,-0.111800},
+  {0.071700,0.607273},
+  {0.144912,0.349067},
+  {0.722128,-0.075779},
+  {-0.279779,-0.260383},
+  {-0.049156,1.120738},
+  {-0.640154,-0.228391},
+  {-0.039753,0.150724},
+  {-0.415397,-0.463677},
+  {-0.723847,-0.209406},
+  {-0.524332,-1.037805},
+  {0.171327,-1.435469},
+  {-0.089687,-0.415936},
+  {-1.225215,0.133157},
+  {-0.018497,-0.644647},
+  {0.396236,-0.355851},
+  {0.225700,0.899203},
+  {0.287114,-0.691831},
+  {0.674085,-0.073870},
+  {2.000654,-0.623437},
+  {-0.252822,-0.415741},
+  {0.052088,0.016210},
+  {-0.332988,-0.849652},
+  {0.026695,-0.376094},
+  {0.742096,0.969579},
+  {-1.635731,0.339533},
+  {-0.208349,0.686132},
+  {0.828001,-0.603493},
+  {-0.078836,-0.444070},
+  {1.364974,0.631664},
+  {-0.160620,0.335231},
+  {-1.378768,-0.907673},
+  {-0.293646,0.072013},
+  {1.524592,-1.461770},
+  {0.083610,-1.746190},
+  {0.102486,0.149103},
+  {0.691698,0.227990},
+  {0.028614,-0.864596},
+  {-0.152066,0.125449},
+  {-1.205134,1.186200},
+  {0.848843,-0.061847},
+  {1.081665,0.049303},
+  {-0.108837,-0.099148},
+  {0.262042,-0.490003},
+  {-0.254991,0.361463},
+  {-0.477565,0.096211},
+  {-0.137706,-1.119345},
+  {0.538644,0.486454},
+  {0.035114,0.001732},
+  {-0.695087,0.063591},
+  {-1.648017,0.977367},
+  {-0.224997,0.395787},
+  {-0.727539,-0.234162},
+  {0.078225,-0.026224},
+  {0.772412,-0.439717},
+  {-0.403974,0.204029},
+  {-1.104881,-0.012786},
+  {-0.672931,-0.415948},
+  {-0.863229,-2.233172},
+  {1.063307,-0.258525},
+  {-0.529432,-0.708843},
+  {-0.176069,-1.026002},
+  {-0.384993,-0.904576},
+  {0.042330,-1.765663},
+  {0.851313,1.091533},
+  {0.180840,0.453570},
+  {0.337128,0.182821},
+  {1.363286,-1.181451},
+  {1.137031,-0.433505},
+  {-1.325181,-0.200399},
+  {0.394546,0.006217},
+  {0.723817,-0.068463},
+  {1.050909,0.065058},
+  {0.084242,-0.420440},
+  {-0.238302,0.258881},
+  {0.174215,-0.677729},
+  {-0.711756,0.276335},
+  {-0.129577,-0.515158},
+  {0.866331,0.116316},
+  {1.575856,0.566488},
+  {0.235497,-0.285233},
+  {-0.831974,-0.236821},
+  {-0.817600,1.539514},
+  {-0.485036,0.295694},
+  {-1.575127,0.044856},
+  {0.181119,0.710358},
+  {-0.056993,-0.238132},
+  {0.091941,0.490274},
+  {0.339556,1.201109},
+  {-1.241956,1.033717},
+  {-0.653462,-1.105622},
+  {-0.351127,0.017888},
+  {-0.240821,-0.475748},
+  {-0.456277,0.573568},
+  {-0.419904,-1.058360},
+  {0.052939,-0.291801},
+  {-0.975645,0.317124},
+  {-0.277843,1.312881},
+  {-0.980414,-0.689515},
+  {-0.328660,0.125761},
+  {0.002261,0.540834},
+  {0.289127,-0.906076},
+  {-0.583909,0.091516},
+  {-0.105622,0.534255},
+  {0.498881,-1.752227},
+  {-0.372611,-0.300411},
+  {0.805897,1.430785},
+  {1.128088,-0.203904},
+  {-0.080504,-0.025175},
+  {0.109551,0.071366},
+  {-1.018953,0.755951},
+  {0.666092,0.991101},
+  {0.947680,-0.016049},
+  {2.030778,-1.308712},
+  {-0.536376,-0.093177},
+  {-0.979295,-0.287391},
+  {-0.720582,-0.666863},
+  {-1.329793,-0.141597},
+  {1.120330,0.296339},
+  {-0.683593,-1.193189},
+  {-0.890008,-0.339326},
+  {0.108370,0.364104},
+  {0.761248,0.181091},
+  {0.852765,1.409425},
+  {-0.232370,1.404779},
+  {-0.951683,-0.337612},
+  {-2.093378,-0.985796},
+  {-0.708897,0.096981},
+  {-0.369032,-0.081507},
+  {0.668578,0.410819},
+  {-1.449941,1.474340},
+  {-0.077746,-0.719201},
+  {-0.522293,-0.151163},
+  {-0.458998,-0.377810},
+  {-0.371088,-0.656185},
+  {-0.692675,0.536793},
+  {-0.856001,0.770941},
+  {0.787694,-0.616170},
+  {0.666946,-1.360541},
+  {0.649554,-0.692776},
+  {-1.149561,-0.060654},
+  {-1.017696,-1.553694},
+  {0.594676,-0.308209},
+  {-0.414485,0.300271},
+  {0.914811,-1.373936},
+  {0.593489,-0.368620},
+  {-0.414122,0.825231},
+  {-0.946035,-0.712426},
+  {-0.027283,-0.856090},
+  {0.824075,-0.537887},
+  {-0.670569,-1.076879},
+  {1.250980,-0.782317},
+  {0.225270,-0.377829},
+  {0.977247,1.198198},
+  {-0.255252,0.458703},
+  {0.859036,2.174261},
+  {-0.392631,0.739821},
+  {-0.219855,0.169863},
+  {0.412017,0.686208},
+  {0.191456,0.548503},
+  {0.762538,-0.306864},
+  {-0.618637,-0.991173},
+  {-0.286232,-1.189813},
+  {0.409556,0.705714},
+  {0.604650,-0.285883},
+  {-0.037553,-0.284563},
+  {-1.752832,0.885716},
+  {0.662262,0.178240},
+  {-0.668130,-0.398971},
+  {2.333495,-0.030369},
+  {0.431917,-0.014914},
+  {-0.339628,-0.075137},
+  {0.979382,0.620025},
+  {0.024547,-0.548793},
+  {-1.198934,0.571377},
+  {0.089618,0.417351},
+  {-0.696845,0.721676},
+  {0.227661,-0.375026},
+  {-0.168858,-0.092691},
+  {0.407953,-0.657836},
+  {0.508885,-0.088453},
+  {0.062845,-0.270386},
+  {-0.087209,-0.221708},
+  {-1.042531,0.650343},
+  {-0.637231,0.804756},
+  {-0.316632,0.521297},
+  {-0.284839,0.380972},
+  {0.756041,0.089078},
+  {0.367135,-0.050171},
+  {0.673788,-0.328597},
+  {-0.475960,1.277835},
+  {0.050328,-0.406764},
+  {-1.253687,0.528663},
+  {1.121088,-0.753455},
+  {0.576634,0.414912},
+  {1.154879,-0.107302},
+  {0.079544,0.382389},
+  {0.259826,-0.087435},
+  {1.064498,0.528704},
+  {-0.698877,-1.021912},
+  {1.273747,0.566923},
+  {-0.151776,1.226809},
+  {-0.116914,0.456137},
+  {-0.758612,0.838042},
+  {0.174788,0.207897},
+  {-1.054368,-0.062673},
+  {0.303920,0.414262},
+  {0.444540,-1.599911},
+  {-0.263430,0.748950},
+  {0.673118,0.295838},
+  {0.558813,-1.015097},
+  {-0.182189,0.099479},
+  {-0.290746,-0.204886},
+  {-0.429349,-0.670610},
+  {-1.054783,-0.017990},
+  {0.438704,1.112183},
+  {1.172061,0.466392},
+  {0.572237,0.341187},
+  {0.617213,-0.632464},
+  {0.122765,0.496952},
+  {-0.366828,0.476781},
+  {0.023184,0.226708},
+  {-0.410027,-1.070367},
+  {-1.411039,0.798430},
+  {0.635652,-1.202681},
+  {1.131089,-0.782675},
+  {0.310544,0.006326},
+  {0.525788,-1.242739},
+  {0.347988,0.586708},
+  {-1.343655,1.265193},
+  {0.573006,0.820707},
+  {-0.145902,-0.883328},
+  {0.129940,0.855404},
+  {0.877836,-0.239222},
+  {-0.451520,-0.558787},
+  {0.326841,-1.498916},
+  {-0.472055,-0.088465},
+  {0.420626,0.747670},
+  {0.365096,-0.779117},
+  {0.779887,-1.025049},
+  {0.268789,0.955912},
+  {0.427846,0.416261},
+  {0.351268,1.579771},
+  {0.085293,-1.166684},
+  {0.108972,-1.064624},
+  {-0.566448,-0.214947},
+  {-0.132223,-0.361406},
+  {-0.136036,0.118975},
+  {0.427266,0.217945},
+  {0.189904,-0.598306},
+  {0.020599,0.225899},
+  {-1.566003,0.465088},
+  {-0.151238,-0.690998},
+  {0.644967,-1.305515},
+  {-1.005521,0.212625},
+  {-0.201626,0.124733},
+  {0.712140,0.508869},
+  {0.934268,0.418607},
+  {1.930008,-0.584650},
+  {-0.667467,1.471271},
+  {0.925854,0.010608},
+  {-0.540775,-0.332686},
+  {-1.356718,0.347897},
+  {1.008829,0.621137},
+  {1.266918,-0.344629},
+  {-1.128488,-0.418674},
+  {0.157524,0.139078},
+  {-0.080731,-1.515912},
+  {0.138870,1.536295},
+  {0.096079,-0.738967},
+  {0.055822,0.790336},
+  {0.775557,-0.154829},
+  {-0.762535,-0.407425},
+  {-1.166020,0.176498},
+  {-0.001453,0.874596},
+  {0.086572,0.749436},
+  {-0.497314,1.108861},
+  {1.253067,0.882093},
+  {0.043620,0.847310},
+  {1.124285,0.394422},
+  {-0.028010,-0.424847},
+  {0.502442,-0.944102},
+  {-0.624064,-0.633988},
+  {-1.314388,-0.197072},
+  {-0.878207,1.312132},
+  {0.164886,-0.109184},
+  {-1.477262,-0.055125},
+  {-0.030013,-0.699816},
+  {-1.298661,1.409137}
+};
\ No newline at end of file
diff --git a/codec2/branches/0.7/src/octave.c b/codec2/branches/0.7/src/octave.c
new file mode 100644 (file)
index 0000000..738982c
--- /dev/null
@@ -0,0 +1,143 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: octave.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 28 2012
+
+  Functions to save C arrays in GNU Octave matrix format.  The output text
+  file can be directly read into Octave using "load filename".
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "octave.h"
+
+#ifdef ARM_MATH_CM4
+#include "Trace.h"
+#endif
+
+#define OCTAVE_BUFSIZE 2048
+
+
+void flush_buffer(FILE* f, char* buffer,size_t* buf_idx_ptr)
+{
+#ifdef ARM_MATH_CM4
+    trace_write(buffer,*buf_idx_ptr);
+#else
+    fwrite(buffer,*buf_idx_ptr,1,f);
+#endif
+    *buf_idx_ptr = 0;
+}
+
+void handle_buffer(FILE* f, char* buffer,const size_t max_buf, size_t* buf_idx_ptr, size_t l)
+{
+    *buf_idx_ptr += l;
+    if (*buf_idx_ptr > max_buf - 64)
+    {
+        flush_buffer(f, buffer,buf_idx_ptr);
+    }
+}
+
+signed int printf_buffer(FILE* f, char* buffer,const size_t max_buf, size_t* buf_idx_ptr, const char *pFormat, ...)
+{
+    va_list    ap;
+    signed int rc;
+
+    va_start(ap, pFormat);
+    rc = vsnprintf(&buffer[*buf_idx_ptr], max_buf - *buf_idx_ptr, pFormat, ap);
+    va_end(ap);
+    if (rc>0)
+    {
+        handle_buffer(f, buffer,max_buf,buf_idx_ptr,rc);
+    }
+    return rc;
+}
+
+
+void printf_header(FILE* f, char* buffer,const size_t max_buf, size_t* buf_idx_ptr, const char *name, const char *dtype, int rows, int cols, int isFloat)
+{
+#ifdef ARM_MATH_CM4
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# hex: %s\n", isFloat?"true":"false");
+#endif    
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# name: %s\n", name);
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# type: %s\n",dtype);
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# rows: %d\n", rows);
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, buf_idx_ptr, "# columns: %d\n", cols);
+}
+void octave_save_int(FILE *f, char name[], int data[], int rows, int cols)
+{
+    int r,c;
+    char buffer[OCTAVE_BUFSIZE];
+    size_t buf_idx = 0;
+
+    printf_header(f, buffer, OCTAVE_BUFSIZE, &buf_idx, name, "matrix", rows, cols, 0);
+
+    for(r=0; r<rows; r++) {
+        for(c=0; c<cols; c++)
+            printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, " %d", data[r*cols+c]);
+        printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, "\n");
+    }
+
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, "\n\n");
+    flush_buffer(f, buffer, &buf_idx);
+}
+
+void octave_save_float(FILE *f, char name[], float data[], int rows, int cols, int col_len)
+{
+    int r,c;
+    char buffer[OCTAVE_BUFSIZE];
+    size_t buf_idx = 0;
+
+    printf_header(f, buffer, OCTAVE_BUFSIZE, &buf_idx, name, "matrix", rows, cols, 1);
+
+    for(r=0; r<rows; r++) {
+        for(c=0; c<cols; c++)
+            printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, " %f", data[r*col_len+c]);
+        printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, "\n");
+    }
+
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, "\n\n");
+    flush_buffer(f, buffer, &buf_idx);
+}
+
+
+void octave_save_complex(FILE *f, char name[], COMP data[], int rows, int cols, int col_len)
+{
+    int r,c;
+    char buffer[OCTAVE_BUFSIZE];
+    size_t buf_idx = 0;
+
+
+    printf_header(f, buffer, OCTAVE_BUFSIZE, &buf_idx, name, "complex matrix", rows, cols, 1);
+
+    for(r=0; r<rows; r++) {
+
+        for(c=0; c<cols; c++)
+        {
+            printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, " (%f,%f)", data[r*col_len+c].real, data[r*col_len+c].imag);
+        }
+        printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, "\n");
+    }
+    printf_buffer(f, buffer, OCTAVE_BUFSIZE, &buf_idx, "\n\n");
+    flush_buffer(f, buffer, &buf_idx);
+}
diff --git a/codec2/branches/0.7/src/octave.h b/codec2/branches/0.7/src/octave.h
new file mode 100644 (file)
index 0000000..6c0ff0d
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: octave.h
+  AUTHOR......: David Rowe
+  DATE CREATED: April 28 2012
+
+  Functions to save C arrays in Octave matrix format.  the output text
+  file can be directly read into octave using "load filename".
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __OCTAVE__
+#define __OCTAVE__
+
+#include "comp.h"
+
+void octave_save_int(FILE *f, char name[], int data[], int rows, int cols);
+void octave_save_float(FILE *f, char name[], float data[], int rows, int cols, int col_len);
+void octave_save_complex(FILE *f, char name[], COMP data[], int rows, int cols, int col_len);
+
+#endif
diff --git a/codec2/branches/0.7/src/ofdm.c b/codec2/branches/0.7/src/ofdm.c
new file mode 100644 (file)
index 0000000..05295c9
--- /dev/null
@@ -0,0 +1,781 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: ofdm.c
+  AUTHORS.....: David Rowe & Steve Sampson
+  DATE CREATED: June 2017
+
+  A Library of functions that implement a BPSK/QPSK OFDM modem
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2017 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+#include <complex.h>
+
+#include "comp.h"
+#include "ofdm_internal.h"
+#include "codec2_ofdm.h"
+
+/* Static Prototypes */
+
+static void matrix_vector_multiply(struct OFDM *, complex float *, complex float *);
+static void matrix_vector_conjugate_multiply(struct OFDM *, complex float *, complex float *);
+static complex float vector_sum(complex float *, int);
+static complex float qpsk_mod(int *);
+static void qpsk_demod(complex float, int *);
+static void ofdm_txframe(struct OFDM *, complex float [OFDM_SAMPLESPERFRAME], complex float *);
+static int coarse_sync(struct OFDM *, complex float *, int);
+
+/* Defines */
+
+#define max( a, b ) ( ((a) > (b)) ? (a) : (b) )
+#define min( a, b ) ( ((a) < (b)) ? (a) : (b) )
+
+/* Constants */
+
+/*
+ * QPSK Quadrant bit-pair values - Gray Coded
+ *
+ *   0.0 -  89.9 = 00
+ *  90.0 - 179.9 = 01
+ * 180.0 - 269.9 = 11
+ * 270.0 - 359.9 = 10
+ */
+static const complex float constellation[] = {
+     1.0f + 0.0f * I,
+     0.0f + 1.0f * I,
+     0.0f - 1.0f * I,
+    -1.0f + 0.0f * I
+};
+
+/*
+ * These pilots are compatible with Octave version
+ */
+static const char pilotvalues[] = {
+    -1, -1, 1, 1, -1, -1, -1, 1, -1,
+     1, -1, 1, 1,  1,  1,  1, 1,  1
+};
+
+/* Functions */
+
+/* Gray coded QPSK modulation function */
+
+static complex float qpsk_mod(int *bits) {
+    return constellation[(bits[1] << 1) | bits[0]];
+}
+
+/* Gray coded QPSK demodulation function */
+
+static void qpsk_demod(complex float symbol, int *bits) {
+    complex float rotate = symbol * cexpf(I * (M_PI / 4.0f));
+    bits[0] = crealf(rotate) < 0.0f;
+    bits[1] = cimagf(rotate) < 0.0f;
+}
+
+/* convert frequency domain into time domain */
+
+static void matrix_vector_multiply(struct OFDM *ofdm, complex float *result, complex float *vector) {
+    int row, col;
+
+    for (row = 0; row < OFDM_M; row++) {
+        result[row] = 0.0f + 0.0f * I;
+
+        for (col = 0; col < (OFDM_NC + 2); col++) {
+            result[row] = result[row] + (vector[col] * (ofdm->W[col][row] / (float) OFDM_M)); /* complex result */
+        }
+    }
+}
+
+/* convert time domain into frequency domain */
+
+static void matrix_vector_conjugate_multiply(struct OFDM *ofdm, complex float *result, complex float *vector) {
+    int row, col;
+
+    for (col = 0; col < (OFDM_NC + 2); col++) {
+        result[col] = 0.0f + 0.0f * I;
+
+        for (row = 0; row < OFDM_M; row++) {
+            result[col] = result[col] + (vector[row] * conjf(ofdm->W[col][row])); /* complex result */
+        }
+    }
+}
+
+static complex float vector_sum(complex float *a, int num_elements) {
+    int i;
+
+    complex float sum = 0.0f + 0.0f * I;
+
+    for (i = 0; i < num_elements; i++) {
+        sum = sum + a[i];
+    }
+
+    return sum;
+}
+
+/*
+ * Correlates the OFDM pilot symbol samples with a window of received
+ * samples to determine the most likely timing offset.  Combines two
+ * frames pilots so we need at least Nsamperframe+M+Ncp samples in rx.
+ */
+
+static int coarse_sync(struct OFDM *ofdm, complex float *rx, int length) {
+    complex float csam;
+    int Ncorr = length - (OFDM_SAMPLESPERFRAME + (OFDM_M + OFDM_NCP));
+    float corr[Ncorr];
+    int i, j;
+
+    for (i = 0; i < Ncorr; i++) {
+        complex float temp = 0.0f + 0.0f * I;
+
+        for (j = 0; j < (OFDM_M + OFDM_NCP); j++) {
+            csam = conjf(ofdm->pilot_samples[j]);
+            temp = temp + (rx[i + j] * csam);
+            temp = temp + (rx[i + j + OFDM_SAMPLESPERFRAME] * csam);
+        }
+
+        corr[i] = cabsf(temp);
+    }
+
+    /* find the max magnitude and its index */
+
+    float mag = 0.0f;
+    int t_est = 0;
+
+    for (i = 0; i < Ncorr; i++) {
+        if (corr[i] > mag) {
+            mag = corr[i];
+            t_est = i;
+        }
+    }
+
+    return t_est;
+}
+
+/*
+ * ----------------------------------------------
+ * ofdm_txframe - modulates one frame of symbols
+ * ----------------------------------------------
+ */
+
+static void ofdm_txframe(struct OFDM *ofdm, complex float tx[OFDM_SAMPLESPERFRAME],
+        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];
+    int i, j, k, m;
+
+    /* initialize aframe to complex zero */
+
+    for (i = 0; i < OFDM_NS; i++) {
+        for (j = 0; j < (OFDM_NC + 2); j++) {
+            aframe[i][j] = 0.0f + 0.0f * I;
+        }
+    }
+
+    /* copy in a row of complex pilots to first row */
+
+    for (i = 0; i < (OFDM_NC + 2); i++) {
+        aframe[0][i] = ofdm->pilots[i];
+    }
+
+    /* Place symbols in multi-carrier frame with pilots */
+    /* This will place boundary values of complex zero around data */
+
+    for (i = 1; i <= OFDM_ROWSPERFRAME; i++) {
+
+        /* copy in the Nc complex values with [0 Nc 0] or (Nc + 2) total */
+
+        for (j = 1; j < (OFDM_NC + 1); j++) {
+            aframe[i][j] = tx_sym_lin[((i - 1) * OFDM_NC) + (j - 1)];
+        }
+    }
+
+    /* OFDM up-convert symbol by symbol so we can add CP */
+
+    for (i = 0, m = 0; i < OFDM_NS; i++, m += (OFDM_M + OFDM_NCP)) {
+        matrix_vector_multiply(ofdm, asymbol, aframe[i]);
+
+        /* Copy the last Ncp columns to the front */
+
+        for (j = (OFDM_M - OFDM_NCP), k = 0; j < OFDM_M; j++, k++) {
+            asymbol_cp[k] = asymbol[j];
+        }
+
+        /* Now copy the whole row after it */
+
+        for (j = OFDM_NCP, k = 0; k < OFDM_M; j++, k++) {
+            asymbol_cp[j] = asymbol[k];
+        }
+
+        /* Now move row to the tx reference */
+
+        for (j = 0; j < (OFDM_M + OFDM_NCP); j++) {
+            tx[m + j] = asymbol_cp[j];
+        }
+    }
+}
+
+/*
+ * ------------
+ * ofdm_create
+ * ------------
+ *
+ * Returns OFDM data structure on success
+ * Return NULL on fail
+ */
+
+struct OFDM *ofdm_create() {
+    struct OFDM *ofdm;
+    int i, j;
+
+    if ((ofdm = (struct OFDM *) malloc(sizeof (struct OFDM))) == NULL) {
+        return NULL;
+    }
+
+    /* store complex BPSK pilot symbols */
+
+    for (i = 0; i < (OFDM_NC + 2); i++) {
+        ofdm->pilots[i] = ((float) pilotvalues[i]) + 0.0f * I;
+    }
+
+    /* carrier tables for up and down conversion */
+
+    int Nlower = floorf((OFDM_CENTRE - OFDM_RS * (OFDM_NC / 2)) / OFDM_RS);
+
+    for (i = 0, j = Nlower; i < (OFDM_NC + 2); i++, j++) {
+        /*
+         * 2 * pi * j/144  j=19..36
+         * j = 1 kHz to 2 kHz (1.5 kHz center)
+         */
+
+        ofdm->w[i] = TAU * (float) j / (OFDM_FS / OFDM_RS);
+    }
+
+    for (i = 0; i < (OFDM_NC + 2); i++) {
+        for (j = 0; j < OFDM_M; j++) {
+            ofdm->W[i][j] = cexpf(I * ofdm->w[i] * j);
+        }
+    }
+
+    for (i = 0; i < (OFDM_NS + 3); i++) {
+        for (j = 0; j < (OFDM_NC + 2); j++) {
+            ofdm->rx_sym[i][j] = 0.0f + 0.0f * I;
+        }
+    }
+
+    /* default settings of options and states */
+
+    ofdm->verbose = 0;
+    ofdm->timing_en = true;
+    ofdm->foff_est_en = true;
+    ofdm->phase_est_en = true;
+
+    ofdm->foff_est_gain = 0.01f;
+    ofdm->foff_est_hz = 0.0f;
+    ofdm->sample_point = 0;
+    ofdm->timing_est = 0;
+    ofdm->nin = OFDM_SAMPLESPERFRAME;
+
+    /* create the OFDM waveform */
+
+    complex float temp[OFDM_M];
+
+    matrix_vector_multiply(ofdm, temp, ofdm->pilots);
+
+    /*
+     * pilot_samples is 160 samples, as we copy the last 16 to the front
+     */
+
+    /* first copy the last Cyclic Prefix (CP) values */
+
+    for (i = 0, j = (OFDM_M - OFDM_NCP); i < OFDM_NCP; i++, j++) {
+        ofdm->pilot_samples[i] = temp[j];
+    }
+
+    /* Now copy the whole thing after the above */
+
+    for (i = OFDM_NCP, j = 0; j < OFDM_M; i++, j++) {
+        ofdm->pilot_samples[i] = temp[j];
+    }
+
+    return ofdm; /* Success */
+}
+
+void ofdm_destroy(struct OFDM *ofdm) {
+    free(ofdm);
+}
+
+int ofdm_get_nin(struct OFDM *ofdm) {
+    return ofdm->nin;
+}
+
+int ofdm_get_samples_per_frame() {
+    return OFDM_SAMPLESPERFRAME;
+}
+
+int ofdm_get_max_samples_per_frame() {
+    return OFDM_MAX_SAMPLESPERFRAME;
+}
+
+void ofdm_set_verbose(struct OFDM *ofdm, int level) {
+    ofdm->verbose = level;
+}
+
+void ofdm_set_timing_enable(struct OFDM *ofdm, bool val) {
+    ofdm->timing_en = val;
+
+    if (ofdm->timing_en == false) {
+        /* manually set ideal timing instant */
+        ofdm->sample_point = (OFDM_NCP - 1);
+    }
+}
+
+void ofdm_set_foff_est_enable(struct OFDM *ofdm, bool val) {
+    ofdm->foff_est_en = val;
+}
+
+void ofdm_set_phase_est_enable(struct OFDM *ofdm, bool val) {
+    ofdm->phase_est_en = val;
+}
+
+void ofdm_set_off_est_hz(struct OFDM *ofdm, float val) {
+    ofdm->foff_est_hz = val;
+}
+
+/*
+ * --------------------------------------
+ * ofdm_mod - modulates one frame of bits
+ * --------------------------------------
+ */
+
+void ofdm_mod(struct OFDM *ofdm, COMP result[OFDM_SAMPLESPERFRAME], const int *tx_bits) {
+    int length = OFDM_BITSPERFRAME / OFDM_BPS;
+    complex float tx[OFDM_SAMPLESPERFRAME];
+    complex float tx_sym_lin[length];
+    int dibit[2];
+    int s, i;
+
+    if (OFDM_BPS == 1) {
+        /* Here we will have Nbitsperframe / 1 */
+
+        for (s = 0; s < length; s++) {
+            tx_sym_lin[s] = (float) (2 * tx_bits[s] - 1) + 0.0f * I;
+        }
+    } else if (OFDM_BPS == 2) {
+        /* Here we will have Nbitsperframe / 2 */
+
+        for (s = 0, i = 0; i < length; s += 2, i++) {
+            dibit[0] = tx_bits[s + 1] & 0x1;
+            dibit[1] = tx_bits[s] & 0x1;
+            tx_sym_lin[i] = qpsk_mod(dibit);
+        }
+    }
+
+    ofdm_txframe(ofdm, tx, tx_sym_lin);
+
+    /* convert to comp */
+
+    for (i = 0; i < OFDM_SAMPLESPERFRAME; i++) {
+        result[i].real = crealf(tx[i]);
+        result[i].imag = cimagf(tx[i]);
+    }
+}
+
+/*
+ * ------------------------------------------
+ * ofdm_demod - Demodulates one frame of bits
+ * ------------------------------------------
+ */
+
+void ofdm_demod(struct OFDM *ofdm, int *rx_bits, COMP *rxbuf_in) {
+    complex float aphase_est_pilot_rect;
+    float aphase_est_pilot[OFDM_NC + 2];
+    float aamp_est_pilot[OFDM_NC + 2];
+    float freq_err_hz;
+    int i, j, k, rr, st, en, ft_est;
+
+    /* shift the buffer left based on nin */
+
+    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;
+    }
+
+    /*
+     * get user and calculated freq offset
+     */
+
+    float woff_est = TAU * ofdm->foff_est_hz / OFDM_FS;
+
+    /* update timing estimate -------------------------------------------------- */
+
+    if (ofdm->timing_en == true) {
+        /* update timing at start of every frame */
+
+        st = ((OFDM_M + OFDM_NCP) + OFDM_SAMPLESPERFRAME) - floorf(OFDM_FTWINDOWWIDTH / 2) + ofdm->timing_est;
+        en = st + OFDM_SAMPLESPERFRAME - 1 + (OFDM_M + OFDM_NCP) + OFDM_FTWINDOWWIDTH;
+
+        complex float work[(en - st)];
+
+        /*
+         * Adjust for the frequency error by shifting the phase
+         * using a conjugate multiply
+         */
+
+        for (i = st, j = 0; i < en; i++, j++) {
+            work[j] = ofdm->rxbuf[i] * cexpf(-I * woff_est * i);
+        }
+
+        ft_est = coarse_sync(ofdm, work, (en - st));
+        ofdm->timing_est += (ft_est - ceilf(OFDM_FTWINDOWWIDTH / 2));
+
+        if (ofdm->verbose > 1) {
+            fprintf(stdout, "  ft_est: %2d timing_est: %2d sample_point: %2d\n", ft_est, ofdm->timing_est, ofdm->sample_point);
+        }
+
+        /* Black magic to keep sample_point inside cyclic prefix.  Or something like that. */
+
+        ofdm->sample_point = max(ofdm->timing_est + (OFDM_NCP / 4), ofdm->sample_point);
+        ofdm->sample_point = min(ofdm->timing_est + OFDM_NCP, ofdm->sample_point);
+    }
+
+    /*
+     * Convert the time-domain samples to the frequency-domain using the rx_sym
+     * data matrix. This will be 18 carriers of 11 symbols.
+     *
+     * You will notice there are 18 BPSK symbols for each pilot symbol, and that there
+     * are 16 QPSK symbols for each data symbol.
+     *
+     *  XXXXXXXXXXXXXXXX  <-- Timing Slip
+     * PPPPPPPPPPPPPPPPPP <-- Previous Frames Pilot
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD      Ignore these past data symbols
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     * PPPPPPPPPPPPPPPPPP <-- This Frames Pilot
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD      These are the current data symbols to be decoded
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     * PPPPPPPPPPPPPPPPPP <-- Next Frames Pilot
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD      Ignore these next data symbols
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     *  DDDDDDDDDDDDDDDD
+     * PPPPPPPPPPPPPPPPPP <-- Future Frames Pilot
+     *  XXXXXXXXXXXXXXXX  <-- Timing Slip
+     *
+     * So this algorithm will have seven data symbols and four pilot symbols to process.
+     * The average of the four pilot symbols is our phase estimation.
+     */
+
+    for (i = 0; i < (OFDM_NS + 3); i++) {
+        for (j = 0; j < (OFDM_NC + 2); j++) {
+            ofdm->rx_sym[i][j] = 0.0f + 0.0f * I;
+        }
+    }
+
+    /*
+     * "Previous" pilot symbol is one modem frame above.
+     */
+
+    st = (OFDM_M + OFDM_NCP) + 1 + ofdm->sample_point;
+    en = st + OFDM_M;
+
+    complex float work[OFDM_M];
+
+    /* down-convert at current timing instant---------------------------------- */
+
+    for (j = st, k = 0; j < en; j++, k++) {
+        work[k] = ofdm->rxbuf[j] * cexpf(-I * woff_est * j);
+    }
+
+    /*
+     * Each symbol is of course (OFDM_M + OFDM_NCP) samples long and
+     * becomes 18 carriers after DFT.
+     *
+     * We put this 18 carrier pilot symbol at the top of our matrix:
+     *
+     * 0 ................... 17
+     *
+     * +----------------------+
+     * |    Previous Pilot    |  rx_sym[0]
+     * +----------------------+
+     * |                      |
+     *
+     */
+
+    matrix_vector_conjugate_multiply(ofdm, ofdm->rx_sym[0], work);
+
+    /*
+     * "This" pilot comes after the extra symbol alloted at the top, and after
+     * the "previous" pilot and previous data symbols (let's call it, the previous
+     * modem frame).
+     *
+     * So we will now be starting at "this" pilot symbol, and continuing to the
+     * "next" pilot symbol.
+     *
+     * In this routine we also process the current data symbols.
+     */
+
+    for (rr = 0; rr < (OFDM_NS + 1); rr++) {
+        st = (OFDM_M + OFDM_NCP) + OFDM_SAMPLESPERFRAME + (rr * (OFDM_M + OFDM_NCP)) + 1 + ofdm->sample_point;
+        en = st + OFDM_M;
+
+        /* down-convert at current timing instant---------------------------------- */
+
+        for (j = st, k = 0; j < en; j++, k++) {
+            work[k] = ofdm->rxbuf[j] * cexpf(-I * woff_est * j);
+        }
+
+        /*
+         * We put these 18 carrier symbols into our matrix after the previous pilot:
+         *
+         * 0 ................... 17
+         *
+         * |    Previous Pilot    |  rx_sym[0]
+         * +----------------------+
+         * |      This Pilot      |  rx_sym[1]
+         * +----------------------+
+         * |         Data         |  rx_sym[2]
+         * +----------------------+
+         * |         Data         |  rx_sym[3]
+         * +----------------------+
+         * |         Data         |  rx_sym[4]
+         * +----------------------+
+         * |         Data         |  rx_sym[5]
+         * +----------------------+
+         * |         Data         |  rx_sym[6]
+         * +----------------------+
+         * |         Data         |  rx_sym[7]
+         * +----------------------+
+         * |         Data         |  rx_sym[8]
+         * +----------------------+
+         * |      Next Pilot      |  rx_sym[9]
+         * +----------------------+
+         * |                      |  rx_sym[10]
+         */
+
+        matrix_vector_conjugate_multiply(ofdm, ofdm->rx_sym[rr + 1], work);
+    }
+
+    /*
+     * OK, now we want to process to the "future" pilot symbol. This is after
+     * the "next" modem frame.
+     *
+     * We are ignoring the data symbols between the "next" pilot and "future" pilot.
+     * We only want the "future" pilot symbol, to perform the averaging of all pilots.
+     */
+
+    st = (OFDM_M + OFDM_NCP) + (3 * OFDM_SAMPLESPERFRAME) + 1 + ofdm->sample_point;
+    en = st + OFDM_M;
+
+    /* down-convert at current timing instant---------------------------------- */
+
+    for (j = st, k = 0; j < en; j++, k++) {
+        work[k] = ofdm->rxbuf[j] * cexpf(-I * woff_est * j);
+    }
+
+    /*
+     * We put the future pilot after all the previous symbols in the matrix:
+     *
+     * 0 ................... 17
+     *
+     * |                      |  rx_sym[9]
+     * +----------------------+
+     * |     Future Pilot     |  rx_sym[10]
+     * +----------------------+
+     */
+
+    matrix_vector_conjugate_multiply(ofdm, ofdm->rx_sym[OFDM_NS + 2], work);
+
+    /*
+     * We are finished now with the DFT and down conversion
+     * From here on down we are in baseband frequency domain
+     */
+
+    /* est freq err based on all carriers ------------------------------------ */
+
+    if (ofdm->foff_est_en == true) {
+        /*
+         * sym[1] is (this) pilot symbol, sym[9] is (next) pilot symbol.
+         *
+         * By subtracting the two averages of these pilots, we find the frequency
+         * by the change in phase over time.
+         */
+
+        complex float freq_err_rect = conjf(vector_sum(ofdm->rx_sym[1],
+                OFDM_NC + 2)) * vector_sum(ofdm->rx_sym[OFDM_NS + 1], OFDM_NC + 2);
+
+        /* prevent instability in atan(im/re) when real part near 0 */
+
+        freq_err_rect = freq_err_rect + 1E-6f;
+
+        freq_err_hz = cargf(freq_err_rect) * OFDM_RS / (TAU * OFDM_NS);
+        ofdm->foff_est_hz += (ofdm->foff_est_gain * freq_err_hz);
+    }
+
+    /* OK - now estimate and correct pilot phase  ---------------------------------- */
+
+    for (i = 0; i < (OFDM_NC + 2); i++) {
+        aphase_est_pilot[i] = 10.0f;
+        aamp_est_pilot[i] = 0.0f;
+    }
+
+    /*
+     * Basically we divide the 18 pilots into groups of 3
+     *
+     * Then average the phase surrounding each of the data symbols.
+     */
+
+    for (i = 1; i < (OFDM_NC + 1); i++) {
+        complex float symbol[3];
+
+        for (j = (i - 1), k = 0; j < (i + 2); j++, k++) {
+            symbol[k] = ofdm->rx_sym[1][j] * conjf(ofdm->pilots[j]); /* this pilot conjugate */
+        }
+
+        aphase_est_pilot_rect = vector_sum(symbol, 3);
+
+        for (j = (i - 1), k = 0; j < (i + 2); j++, k++) {
+            symbol[k] = ofdm->rx_sym[OFDM_NS + 1][j] * conjf(ofdm->pilots[j]); /* next pilot conjugate */
+        }
+
+        aphase_est_pilot_rect = aphase_est_pilot_rect + vector_sum(symbol, 3);
+
+        /* use next step of pilots in past and future */
+
+        for (j = (i - 1), k = 0; j < (i + 2); j++, k++) {
+            symbol[k] = ofdm->rx_sym[0][j] * ofdm->pilots[j]; /* previous pilot */
+        }
+
+        aphase_est_pilot_rect = aphase_est_pilot_rect + vector_sum(symbol, 3);
+
+        for (j = (i - 1), k = 0; j < (i + 2); j++, k++) {
+            symbol[k] = ofdm->rx_sym[OFDM_NS + 2][j] * ofdm->pilots[j]; /* last pilot */
+        }
+
+        aphase_est_pilot_rect = aphase_est_pilot_rect + vector_sum(symbol, 3);
+        aphase_est_pilot[i] = cargf(aphase_est_pilot_rect);
+
+        /* TODO David: WTF 12.0 constant?  Something to do with LDPC input scaling? */
+
+        aamp_est_pilot[i] = cabsf(aphase_est_pilot_rect / 12.0f);
+    }
+
+    /*
+     * correct phase offset using phase estimate, and demodulate
+     * bits, separate loop as it runs across cols (carriers) to get
+     * frame bit ordering correct
+     */
+
+    complex float rx_corr;
+    int abit[2];
+    int bit_index = 0;
+
+    for (rr = 0; rr < OFDM_ROWSPERFRAME; rr++) {
+        /*
+         * Note the i has an index of 1 to 16, so we ignore carriers 0 and 17.
+         *
+         * Also note we are using sym[2..8] or the seven data symbols.
+         */
+
+        for (i = 1; i < (OFDM_NC + 1); i++) {
+            if (ofdm->phase_est_en == true) {
+                rx_corr = ofdm->rx_sym[rr + 2][i] * cexpf(-I * aphase_est_pilot[i]);
+            } else {
+                rx_corr = ofdm->rx_sym[rr + 2][i];
+            }
+
+            /*
+             * For testing, we want to save these complex data values
+             * without the pilots. Thus, the name rx (no pilot) np
+             */
+
+            ofdm->rx_np[(rr * OFDM_NC) + (i - 1)] = rx_corr;
+
+            /*
+             * Note even though amp ests are the same for each col,
+             * the FEC decoder likes to have one amplitude per symbol
+             * so convenient to log them all
+             */
+
+            ofdm->rx_amp[(rr * OFDM_NC) + (i - 1)] = aamp_est_pilot[i];
+
+            /*
+             * Note like amps in this implementation phase ests are the
+             * same for each col, but we log them for each symbol anyway
+             */
+
+            ofdm->aphase_est_pilot_log[(rr * OFDM_NC) + (i - 1)] = aphase_est_pilot[i];
+
+            if (OFDM_BPS == 1) {
+                rx_bits[bit_index++] = crealf(rx_corr) > 0.0f;
+            } else if (OFDM_BPS == 2) {
+                /*
+                 * Only one final task, decode what quadrant the phase
+                 * is in, and return the dibits
+                 */
+                qpsk_demod(rx_corr, abit);
+                rx_bits[bit_index++] = abit[1];
+                rx_bits[bit_index++] = abit[0];
+            }
+        }
+    }
+
+    /* Adjust nin to take care of sample clock offset */
+
+    ofdm->nin = OFDM_SAMPLESPERFRAME;
+
+    if (ofdm->timing_en == true) {
+        int thresh = (OFDM_M + OFDM_NCP) / 8;
+        int tshift = (OFDM_M + OFDM_NCP) / 4;
+
+        if (ofdm->timing_est > thresh) {
+            ofdm->nin = OFDM_SAMPLESPERFRAME + tshift;
+            ofdm->timing_est -= tshift;
+            ofdm->sample_point -= tshift;
+        } else if (ofdm->timing_est < -thresh) {
+            ofdm->nin = OFDM_SAMPLESPERFRAME - tshift;
+            ofdm->timing_est += tshift;
+            ofdm->sample_point += tshift;
+        }
+    }
+}
+
diff --git a/codec2/branches/0.7/src/ofdm_internal.h b/codec2/branches/0.7/src/ofdm_internal.h
new file mode 100644 (file)
index 0000000..3ba9b69
--- /dev/null
@@ -0,0 +1,103 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: ofdm_internal.h
+  AUTHORS.....: David Rowe & Steve Sampson
+  DATE CREATED: June 2017
+
+  OFDM Internal definitions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2017 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef OFDM_INTERNAL_H
+#define OFDM_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <complex.h>
+#include <stdbool.h>
+
+#ifndef M_PI
+#define M_PI        3.14159265358979323846f  /* math constant */
+#endif
+
+#define TAU         (2.0f * M_PI)            /* mathematical constant */
+
+#define OFDM_NC     16
+#define OFDM_TS     0.018f
+#define OFDM_RS     (1.0f / OFDM_TS)
+#define OFDM_FS     8000.0f
+#define OFDM_BPS    2
+#define OFDM_TCP    0.002f
+#define OFDM_NS     8
+#define OFDM_CENTRE 1500.0f
+
+/* To prevent C99 warning */
+
+#define OFDM_M      144
+#define OFDM_NCP    16
+
+#ifdef OLD_STYLE
+/* This will produce a warning in C99 as (int) makes these variable */
+
+#define OFDM_M      ((int)(OFDM_FS / OFDM_RS))
+#define OFDM_NCP    ((int)(OFDM_TCP * OFDM_FS))
+#endif
+
+#define OFDM_FTWINDOWWIDTH       11
+#define OFDM_BITSPERFRAME        ((OFDM_NS - 1) * (OFDM_NC * OFDM_BPS))
+#define OFDM_ROWSPERFRAME        (OFDM_BITSPERFRAME / (OFDM_NC * OFDM_BPS))
+#define OFDM_SAMPLESPERFRAME     (OFDM_NS * (OFDM_M + OFDM_NCP))
+#define OFDM_MAX_SAMPLESPERFRAME (OFDM_SAMPLESPERFRAME + (OFDM_M + OFDM_NCP)/4)
+#define OFDM_RXBUF               (3 * OFDM_SAMPLESPERFRAME + 3 * (OFDM_M + OFDM_NCP))
+
+struct OFDM {
+    float foff_est_gain;
+    float foff_est_hz;
+
+    int verbose;
+    int sample_point;
+    int timing_est;
+    int nin;
+
+    bool timing_en;
+    bool foff_est_en;
+    bool phase_est_en;
+
+    complex float pilot_samples[OFDM_M + OFDM_NCP];
+    complex float W[OFDM_NC + 2][OFDM_M];
+    complex float rxbuf[OFDM_RXBUF];
+    complex float pilots[OFDM_NC + 2];
+    float w[OFDM_NC + 2];
+    
+    /* Demodulator data */
+
+    complex float rx_sym[OFDM_NS + 3][OFDM_NC + 2];
+    complex float rx_np[OFDM_ROWSPERFRAME * OFDM_NC];
+    float rx_amp[OFDM_ROWSPERFRAME * OFDM_NC];
+    float aphase_est_pilot_log[OFDM_ROWSPERFRAME * OFDM_NC];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/src/os.h b/codec2/branches/0.7/src/os.h
new file mode 100644 (file)
index 0000000..14b4713
--- /dev/null
@@ -0,0 +1,53 @@
+/* Generate using fir1(47,1/2) in Octave */
+
+static const float fdmdv_os_filter[]= {
+    -0.0008215855034550382,
+    -0.0007833023901802921,
+     0.001075563790768233,
+     0.001199092367787555,
+    -0.001765309502928316,
+    -0.002055372115328064,
+     0.002986877604154257,
+     0.003462567920638414,
+    -0.004856570111126334,
+    -0.005563143845031497,
+     0.007533613299748122,
+     0.008563932468880897,
+    -0.01126857129039911,
+    -0.01280782411693687,
+     0.01651443896361847,
+     0.01894875110322284,
+    -0.02421604439474981,
+    -0.02845107338464062,
+     0.03672973563400258,
+     0.04542046150312214,
+    -0.06189165826716491,
+    -0.08721876380763803,
+     0.1496157094199961,
+     0.4497962274137046,
+     0.4497962274137046,
+     0.1496157094199961,
+    -0.08721876380763803,
+    -0.0618916582671649,
+     0.04542046150312216,
+     0.03672973563400257,
+    -0.02845107338464062,
+    -0.02421604439474984,
+     0.01894875110322284,
+     0.01651443896361848,
+    -0.01280782411693687,
+    -0.0112685712903991,
+     0.008563932468880899,
+     0.007533613299748123,
+    -0.005563143845031501,
+    -0.004856570111126346,
+     0.003462567920638419,
+     0.002986877604154259,
+    -0.002055372115328063,
+    -0.001765309502928318,
+     0.001199092367787557,
+     0.001075563790768233,
+    -0.0007833023901802925,
+    -0.0008215855034550383
+};
+
diff --git a/codec2/branches/0.7/src/pack.c b/codec2/branches/0.7/src/pack.c
new file mode 100644 (file)
index 0000000..1c07230
--- /dev/null
@@ -0,0 +1,140 @@
+/*
+  Copyright (C) 2010 Perens LLC <bruce@perens.com>
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "defines.h"
+#include "quantise.h"
+#include <stdio.h>
+
+/* Compile-time constants */
+/* Size of unsigned char in bits. Assumes 8 bits-per-char. */
+static const unsigned int      WordSize = 8;
+
+/* Mask to pick the bit component out of bitIndex. */
+static const unsigned int      IndexMask = 0x7;
+
+/* Used to pick the word component out of bitIndex. */
+static const unsigned int      ShiftRight = 3;
+
+/** Pack a bit field into a bit string, encoding the field in Gray code.
+ *
+ * The output is an array of unsigned char data. The fields are efficiently
+ * packed into the bit string. The Gray coding is a naive attempt to reduce
+ * the effect of single-bit errors, we expect to do a better job as the
+ * codec develops.
+ *
+ * This code would be simpler if it just set one bit at a time in the string,
+ * but would hit the same cache line more often. I'm not sure the complexity
+ * gains us anything here.
+ *
+ * Although field is currently of int type rather than unsigned for
+ * compatibility with the rest of the code, indices are always expected to
+ * be >= 0.
+ */
+void
+pack(
+ unsigned char *       bitArray, /* The output bit string. */
+ unsigned int *                bitIndex, /* Index into the string in BITS, not bytes.*/
+ int                   field,    /* The bit field to be packed. */
+ unsigned int          fieldWidth/* Width of the field in BITS, not bytes. */
+ )
+{
+    pack_natural_or_gray(bitArray, bitIndex, field, fieldWidth, 1);
+}
+
+void
+pack_natural_or_gray(
+ unsigned char *       bitArray,  /* The output bit string. */
+ unsigned int *                bitIndex,  /* Index into the string in BITS, not bytes.*/
+ int                   field,     /* The bit field to be packed. */
+ unsigned int          fieldWidth,/* Width of the field in BITS, not bytes. */
+ unsigned int           gray       /* non-zero for gray coding */
+ )
+{
+  if (gray) {
+    /* Convert the field to Gray code */
+    field = (field >> 1) ^ field;
+  }
+
+  do {
+    unsigned int       bI = *bitIndex;
+    unsigned int       bitsLeft = WordSize - (bI & IndexMask);
+    unsigned int       sliceWidth =
+                        bitsLeft < fieldWidth ? bitsLeft : fieldWidth;
+    unsigned int       wordIndex = bI >> ShiftRight;
+
+    bitArray[wordIndex] |=
+     ((unsigned char)((field >> (fieldWidth - sliceWidth))
+     << (bitsLeft - sliceWidth)));
+
+    *bitIndex = bI + sliceWidth;
+    fieldWidth -= sliceWidth;
+  } while ( fieldWidth != 0 );
+}
+
+/** Unpack a field from a bit string, converting from Gray code to binary.
+ *
+ */
+int
+unpack(
+ const unsigned char * bitArray, /* The input bit string. */
+ unsigned int *                bitIndex, /* Index into the string in BITS, not bytes.*/
+ unsigned int          fieldWidth/* Width of the field in BITS, not bytes. */
+ )
+{
+    return unpack_natural_or_gray(bitArray, bitIndex, fieldWidth, 1);
+}
+
+/** Unpack a field from a bit string, to binary, optionally using
+ * natural or Gray code.
+ *
+ */
+int
+unpack_natural_or_gray(
+ const unsigned char * bitArray,  /* The input bit string. */
+ unsigned int *                bitIndex,  /* Index into the string in BITS, not bytes.*/
+ unsigned int          fieldWidth,/* Width of the field in BITS, not bytes. */
+ unsigned int           gray       /* non-zero for Gray coding */
+ )
+{
+  unsigned int field = 0;
+  unsigned int t;
+
+  do {
+    unsigned int       bI = *bitIndex;
+    unsigned int       bitsLeft = WordSize - (bI & IndexMask);
+    unsigned int       sliceWidth =
+                        bitsLeft < fieldWidth ? bitsLeft : fieldWidth;
+
+    field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & ((1 << sliceWidth) - 1)) << (fieldWidth - sliceWidth));
+
+    *bitIndex = bI + sliceWidth;
+    fieldWidth -= sliceWidth;
+  } while ( fieldWidth != 0 );
+
+  if (gray) {
+    /* Convert from Gray code to binary. Works for maximum 8-bit fields. */
+    t = field ^ (field >> 8);
+    t ^= (t >> 4);
+    t ^= (t >> 2);
+    t ^= (t >> 1);
+  }
+  else {
+    t = field;
+  }
+
+  return t;
+}
diff --git a/codec2/branches/0.7/src/phase.c b/codec2/branches/0.7/src/phase.c
new file mode 100644 (file)
index 0000000..e486613
--- /dev/null
@@ -0,0 +1,289 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: phase.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 1/2/09
+
+  Functions for modelling and synthesising phase.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not,see <http://www.gnu.org/licenses/>.
+*/
+
+#include "defines.h"
+#include "phase.h"
+#include "kiss_fft.h"
+#include "comp.h"
+#include "comp_prim.h"
+#include "sine.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*---------------------------------------------------------------------------*\
+
+  sample_phase()
+
+  Samples phase at centre of each harmonic from and array of FFT_ENC
+  DFT samples.
+
+\*---------------------------------------------------------------------------*/
+
+void sample_phase(MODEL *model, 
+                  COMP H[], 
+                  COMP A[]        /* LPC analysis filter in freq domain */
+                  )                  
+{
+    int   m, b;
+    float r;
+
+    r = TWO_PI/(FFT_ENC);
+
+    /* Sample phase at harmonics */
+
+    for(m=1; m<=model->L; m++) {
+        b = (int)(m*model->Wo/r + 0.5);
+        H[m] = cconj(A[b]);      /* synth filter 1/A is opposite phase to analysis filter */
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+   phase_synth_zero_order()
+
+   Synthesises phases based on SNR and a rule based approach.  No phase
+   parameters are required apart from the SNR (which can be reduced to a
+   1 bit V/UV decision per frame).
+
+   The phase of each harmonic is modelled as the phase of a synthesis
+   filter excited by an impulse.  In many Codec 2 modes the synthesis
+   filter is a LPC filter. Unlike the first order model the position
+   of the impulse is not transmitted, so we create an excitation pulse
+   train using a rule based approach.
+
+   Consider a pulse train with a pulse starting time n=0, with pulses
+   repeated at a rate of Wo, the fundamental frequency.  A pulse train
+   in the time domain is equivalent to harmonics in the frequency
+   domain.  We can make an excitation pulse train using a sum of
+   sinsusoids:
+
+     for(m=1; m<=L; m++)
+       ex[n] = cos(m*Wo*n)
+
+   Note: the Octave script ../octave/phase.m is an example of this if
+   you would like to try making a pulse train.
+
+   The phase of each excitation harmonic is:
+
+     arg(E[m]) = mWo
+
+   where E[m] are the complex excitation (freq domain) samples,
+   arg(x), just returns the phase of a complex sample x.
+
+   As we don't transmit the pulse position for this model, we need to
+   synthesise it.  Now the excitation pulses occur at a rate of Wo.
+   This means the phase of the first harmonic advances by N_SAMP samples
+   over a synthesis frame of N_SAMP samples.  For example if Wo is pi/20
+   (200 Hz), then over a 10ms frame (N_SAMP=80 samples), the phase of the
+   first harmonic would advance (pi/20)*80 = 4*pi or two complete
+   cycles.
+
+   We generate the excitation phase of the fundamental (first
+   harmonic):
+
+     arg[E[1]] = Wo*N_SAMP;
+
+   We then relate the phase of the m-th excitation harmonic to the
+   phase of the fundamental as:
+
+     arg(E[m]) = m*arg(E[1])
+
+   This E[m] then gets passed through the LPC synthesis filter to
+   determine the final harmonic phase.
+
+   Comparing to speech synthesised using original phases:
+
+   - Through headphones speech synthesised with this model is not as
+     good. Through a loudspeaker it is very close to original phases.
+
+   - If there are voicing errors, the speech can sound clicky or
+     staticy.  If V speech is mistakenly declared UV, this model tends to
+     synthesise impulses or clicks, as there is usually very little shift or
+     dispersion through the LPC synthesis filter.
+
+   - When combined with LPC amplitude modelling there is an additional
+     drop in quality.  I am not sure why, theory is interformant energy
+     is raised making any phase errors more obvious.
+
+   NOTES:
+
+     1/ This synthesis model is effectively the same as a simple LPC-10
+     vocoders, and yet sounds much better.  Why? Conventional wisdom
+     (AMBE, MELP) says mixed voicing is required for high quality
+     speech.
+
+     2/ I am pretty sure the Lincoln Lab sinusoidal coding guys (like xMBE
+     also from MIT) first described this zero phase model, I need to look
+     up the paper.
+
+     3/ Note that this approach could cause some discontinuities in
+     the phase at the edge of synthesis frames, as no attempt is made
+     to make sure that the phase tracks are continuous (the excitation
+     phases are continuous, but not the final phases after filtering
+     by the LPC spectra).  Technically this is a bad thing.  However
+     this may actually be a good thing, disturbing the phase tracks a
+     bit.  More research needed, e.g. test a synthesis model that adds
+     a small delta-W to make phase tracks line up for voiced
+     harmonics.
+
+\*---------------------------------------------------------------------------*/
+
+void phase_synth_zero_order(
+    int    n_samp,
+    MODEL *model,
+    float *ex_phase,            /* excitation phase of fundamental        */
+    COMP   H[]                  /* L synthesis filter freq domain samples */
+
+)
+{
+    int   m;
+    float new_phi;
+    COMP  Ex[MAX_AMP+1];         /* excitation samples */
+    COMP  A_[MAX_AMP+1];         /* synthesised harmonic samples */
+
+    /*
+       Update excitation fundamental phase track, this sets the position
+       of each pitch pulse during voiced speech.  After much experiment
+       I found that using just this frame's Wo improved quality for UV
+       sounds compared to interpolating two frames Wo like this:
+
+       ex_phase[0] += (*prev_Wo+model->Wo)*N_SAMP/2;
+    */
+
+    ex_phase[0] += (model->Wo)*n_samp;
+    ex_phase[0] -= TWO_PI*floorf(ex_phase[0]/TWO_PI + 0.5);
+
+    for(m=1; m<=model->L; m++) {
+
+        /* generate excitation */
+
+        if (model->voiced) {
+
+            Ex[m].real = cosf(ex_phase[0]*m);
+            Ex[m].imag = sinf(ex_phase[0]*m);
+        }
+        else {
+
+            /* When a few samples were tested I found that LPC filter
+               phase is not needed in the unvoiced case, but no harm in
+               keeping it.
+            */
+            float phi = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX;
+            Ex[m].real = cosf(phi);
+            Ex[m].imag = sinf(phi);
+        }
+
+        /* filter using LPC filter */
+
+        A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag;
+        A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag;
+
+        /* modify sinusoidal phase */
+
+        new_phi = atan2f(A_[m].imag, A_[m].real+1E-12);
+        model->phi[m] = new_phi;
+    }
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: mag_to_phase
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Algorithm for http://www.dsprelated.com/showcode/20.php ported to C.  See
+  also Octave function mag_to_phase.m
+
+  Given a magnitude spectrum in dB, returns a minimum-phase phase
+  spectra.
+
+\*---------------------------------------------------------------------------*/
+
+void mag_to_phase(float phase[],             /* Nfft/2+1 output phase samples in radians       */
+                  float Gdbfk[],             /* Nfft/2+1 postive freq amplitudes samples in dB */
+                  int Nfft, 
+                  codec2_fft_cfg fft_fwd_cfg,
+                  codec2_fft_cfg fft_inv_cfg
+                  )
+{
+    COMP Sdb[Nfft], c[Nfft], cf[Nfft], Cf[Nfft];
+    int  Ns = Nfft/2+1;
+    int  i;
+
+    /* install negative frequency components, 1/Nfft takes into
+       account kiss fft lack of scaling on ifft */
+
+    Sdb[0].real = Gdbfk[0];
+    Sdb[0].imag = 0.0;
+    for(i=1; i<Ns; i++) {
+        Sdb[i].real = Sdb[Nfft-i].real = Gdbfk[i];
+        Sdb[i].imag = Sdb[Nfft-i].imag = 0.0;
+    }
+
+    /* compute real cepstrum from log magnitude spectrum */
+
+    codec2_fft(fft_inv_cfg, Sdb, c);
+    for(i=0; i<Nfft; i++) {
+        c[i].real /= (float)Nfft;
+        c[i].imag /= (float)Nfft;
+    }
+
+    /* Fold cepstrum to reflect non-min-phase zeros inside unit circle */
+
+    cf[0] = c[0];
+    for(i=1; i<Ns-1; i++) {
+        cf[i] = cadd(c[i],c[Nfft-i]);
+    }
+    cf[Ns-1] = c[Ns-1];
+    for(i=Ns; i<Nfft; i++) {
+        cf[i].real = 0.0;
+        cf[i].imag = 0.0;
+    }
+
+    /* Cf = dB_magnitude + j * minimum_phase */
+
+    codec2_fft(fft_fwd_cfg, cf, Cf);
+
+    /*  The maths says we are meant to be using log(x), not 20*log10(x),
+        so we need to scale the phase to account for this:
+        log(x) = 20*log10(x)/scale */
+                          
+    float scale = (20.0/logf(10.0));
+    
+    for(i=0; i<Ns; i++) {
+        phase[i] = Cf[i].imag/scale;
+    }
+
+    
+}
diff --git a/codec2/branches/0.7/src/phase.h b/codec2/branches/0.7/src/phase.h
new file mode 100644 (file)
index 0000000..92909f0
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: phase.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 1/2/09
+
+  Functions for modelling phase.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __PHASE__
+#define __PHASE__
+
+#include "codec2_fft.h"
+#include "comp.h"
+
+void sample_phase(MODEL *model, COMP filter_phase[], COMP A[]);
+void phase_synth_zero_order(int n_samp, MODEL *model, float *ex_phase, COMP filter_phase[]);
+
+void mag_to_phase(float phase[], float Gdbfk[], int Nfft, codec2_fft_cfg fwd_cfg, codec2_fft_cfg inv_cfg);
+
+#endif
diff --git a/codec2/branches/0.7/src/phaseexp.c b/codec2/branches/0.7/src/phaseexp.c
new file mode 100644 (file)
index 0000000..d6b3350
--- /dev/null
@@ -0,0 +1,1461 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: phaseexp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2012
+
+  Experimental functions for quantising, modelling and synthesising phase.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not,see <http://www.gnu.org/licenses/>.
+*/
+
+#include "defines.h"
+#include "phase.h"
+#include "kiss_fft.h"
+#include "comp.h"
+
+#include <assert.h>
+#include <ctype.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Bruce Perens' funcs to load codebook files */
+
+struct codebook {
+    unsigned int        k;
+    unsigned int        log2m;
+    unsigned int        m;
+    COMP                *cb;
+    unsigned int         offset;
+};
+
+static const char format[] =
+"The table format must be:\n"
+"\tTwo integers describing the dimensions of the codebook.\n"
+"\tThen, enough numbers to fill the specified dimensions.\n";
+
+float get_float(FILE * in, const char * name, char * * cursor, char * buffer, int size)
+{
+  for ( ; ; ) {
+    char *     s = *cursor;
+    char       c;
+
+    while ( (c = *s) != '\0' && !isdigit(c) && c != '-' && c != '.' )
+      s++;
+
+    /* Comments start with "#" and continue to the end of the line. */
+    if ( c != '\0' && c != '#' ) {
+      char *   end = 0;
+      float    f = 0;
+
+      f = strtod(s, &end);
+
+      if ( end != s )
+        *cursor = end;
+      return f;
+    }
+
+    if ( fgets(buffer, size, in) == NULL ) {
+      fprintf(stderr, "%s: Format error. %s\n", name, format);
+      exit(1);
+    }
+    *cursor = buffer;
+  }
+}
+
+static struct codebook *load(const char * name)
+{
+    FILE               *file;
+    char               line[2048];
+    char               *cursor = line;
+    struct codebook    *b = malloc(sizeof(struct codebook));
+    int                        i;
+    int                        size;
+    float               angle;
+
+    file = fopen(name, "rt");
+    assert(file != NULL);
+
+    *cursor = '\0';
+
+    b->k = (int)get_float(file, name, &cursor, line, sizeof(line));
+    b->m = (int)get_float(file, name ,&cursor, line, sizeof(line));
+    size = b->k * b->m;
+
+    b->cb = (COMP *)malloc(size * sizeof(COMP));
+
+    for ( i = 0; i < size; i++ ) {
+       angle = get_float(file, name, &cursor, line, sizeof(line));
+       b->cb[i].real = cos(angle);
+       b->cb[i].imag = sin(angle);
+    }
+
+    fclose(file);
+
+    return b;
+}
+
+
+/* states for phase experiments */
+
+struct PEXP {
+    float            phi1;
+    float            phi_prev[MAX_AMP];
+    float            Wo_prev;
+    int              frames;
+    float            snr;
+    float            var;
+    int              var_n;
+    struct codebook *vq1,*vq2,*vq3,*vq4,*vq5;
+    float            vq_var;
+    int              vq_var_n;
+    MODEL            prev_model;
+    int              state;
+};
+
+
+/*---------------------------------------------------------------------------* \
+
+  phase_experiment_create()
+
+  Inits states for phase quantisation experiments.
+
+\*---------------------------------------------------------------------------*/
+
+struct PEXP * phase_experiment_create() {
+    struct PEXP *pexp;
+    int i;
+
+    pexp = (struct PEXP *)malloc(sizeof(struct PEXP));
+    assert (pexp != NULL);
+
+    pexp->phi1 = 0;
+    for(i=0; i<MAX_AMP; i++)
+       pexp->phi_prev[i] = 0.0;
+    pexp->Wo_prev = 0.0;
+    pexp->frames = 0;
+    pexp->snr = 0.0;
+    pexp->var = 0.0;
+    pexp->var_n = 0;
+
+    /* smoothed 10th order for 1st 1 khz */
+    //pexp->vq1 = load("../unittest/ph1_10_1024.txt");
+    //pexp->vq1->offset = 0;
+
+    /* load experimental phase VQ */
+
+    //pexp->vq1 = load("../unittest/testn1_20_1024.txt");
+    pexp->vq1 = load("../unittest/test.txt");
+    //pexp->vq2 = load("../unittest/testn21_40_1024.txt");
+    pexp->vq2 = load("../unittest/test11_20_1024.txt");
+    pexp->vq3 = load("../unittest/test21_30_1024.txt");
+    pexp->vq4 = load("../unittest/test31_40_1024.txt");
+    pexp->vq5 = load("../unittest/test41_60_1024.txt");
+    pexp->vq1->offset = 0;
+    pexp->vq2->offset = 10;
+    pexp->vq3->offset = 20;
+    pexp->vq4->offset = 30;
+    pexp->vq5->offset = 40;
+
+    pexp->vq_var = 0.0;
+    pexp->vq_var_n = 0;
+
+    pexp->state = 0;
+
+    return pexp;
+}
+
+
+/*---------------------------------------------------------------------------* \
+
+  phase_experiment_destroy()
+
+\*---------------------------------------------------------------------------*/
+
+void phase_experiment_destroy(struct PEXP *pexp) {
+    assert(pexp != NULL);
+    if (pexp->snr != 0.0)
+       printf("snr: %4.2f dB\n", pexp->snr/pexp->frames);
+    if (pexp->var != 0.0)
+       printf("var...: %4.3f  std dev...: %4.3f (%d non zero phases)\n",
+              pexp->var/pexp->var_n, sqrt(pexp->var/pexp->var_n), pexp->var_n);
+    if (pexp->vq_var != 0.0)
+       printf("vq var: %4.3f  vq std dev: %4.3f (%d non zero phases)\n",
+              pexp->vq_var/pexp->vq_var_n, sqrt(pexp->vq_var/pexp->vq_var_n), pexp->vq_var_n);
+    free(pexp);
+}
+
+
+/*---------------------------------------------------------------------------* \
+
+  Various test and experimental functions ................
+
+\*---------------------------------------------------------------------------*/
+
+
+static void predict_phases(struct PEXP *pexp, MODEL *model, int start, int end) {
+    int i;
+
+    for(i=start; i<=end; i++) {
+       model->phi[i] = pexp->phi_prev[i] + N_SAMP*i*model->Wo;
+    }
+
+}
+static float refine_Wo(struct PEXP     *pexp,
+                      MODEL           *model,
+                      int              start,
+                      int              end);
+
+/* Fancy state based phase prediction.  Actually works OK on most utterances,
+   but could use some tuning.  Breaks down a bit on mmt1. */
+
+static void predict_phases_state(struct PEXP *pexp, MODEL *model, int start, int end) {
+    int i, next_state;
+    float best_Wo, dWo;
+
+    //best_Wo = refine_Wo(pexp, model, start, end);
+    //best_Wo = (model->Wo + pexp->Wo_prev)/2.0;
+    best_Wo = model->Wo;
+
+    dWo = fabs(model->Wo - pexp->Wo_prev)/model->Wo;
+    next_state = pexp->state;
+    switch(pexp->state) {
+    case 0:
+       if (dWo < 0.1) {
+           /* UV -> V transition, so start with phases in lock.  They will
+              drift a bit over voiced track which is kinda what we want, so
+              we don't get clicky speech.
+           */
+           next_state = 1;
+           for(i=start; i<=end; i++)
+               pexp->phi_prev[i] = i*pexp->phi1;
+       }
+
+       break;
+    case 1:
+       if (dWo > 0.1)
+           next_state = 0;
+       break;
+    }
+    pexp->state = next_state;
+
+    if (pexp->state == 0)
+       for(i=start; i<=end; i++) {
+           model->phi[i] = PI*(1.0 - 2.0*rand()/RAND_MAX);
+       }
+    else
+       for(i=start; i<=end; i++) {
+           model->phi[i] = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
+       }
+    printf("state %d\n", pexp->state);
+}
+
+static void struct_phases(struct PEXP *pexp, MODEL *model, int start, int end) {
+    int i;
+
+    for(i=start; i<=end; i++)
+       model->phi[i] = pexp->phi1*i;
+
+}
+
+
+static void predict_phases2(struct PEXP *pexp, MODEL *model, int start, int end) {
+    int i;
+    float pred, str, diff;
+
+    for(i=start; i<=end; i++) {
+       pred = pexp->phi_prev[i] + N_SAMP*i*model->Wo;
+       str = pexp->phi1*i;
+       diff = str - pred;
+       diff = atan2(sin(diff), cos(diff));
+       if (diff > 0)
+           pred += PI/16;
+       else
+           pred -= PI/16;
+       model->phi[i] = pred;
+    }
+
+}
+
+static void quant_phase(float *phase, float min, float max, int bits) {
+    int   levels = 1 << bits;
+    int   index;
+    float norm, step;
+
+    norm = (*phase - min)/(max - min);
+    index = floor(levels*norm);
+
+    //printf("phase %f norm %f index %d ", *phase, norm, index);
+    if (index < 0 ) index = 0;
+    if (index > (levels-1)) index = levels-1;
+    //printf("index %d ", index);
+    step = (max - min)/levels;
+    *phase = min + step*index + 0.5*step;
+    //printf("step %f phase %f\n", step, *phase);
+}
+
+static void quant_phases(MODEL *model, int start, int end, int bits) {
+    int i;
+
+    for(i=start; i<=end; i++) {
+       quant_phase(&model->phi[i], -PI, PI, bits);
+    }
+}
+
+#if 0
+/* Bubblesort to find highest amplitude harmonics */
+
+struct AMPINDEX {
+    float amp;
+    int   index;
+};
+
+static void bubbleSort(struct AMPINDEX numbers[], int array_size)
+{
+    int i, j;
+    struct AMPINDEX temp;
+
+  for (i = (array_size - 1); i > 0; i--)
+  {
+    for (j = 1; j <= i; j++)
+    {
+       //printf("i %d j %d %f %f \n", i, j, numbers[j-1].amp, numbers[j].amp);
+      if (numbers[j-1].amp < numbers[j].amp)
+      {
+        temp = numbers[j-1];
+        numbers[j-1] = numbers[j];
+        numbers[j] = temp;
+      }
+    }
+  }
+}
+
+static void print_pred_error(struct PEXP *pexp, MODEL *model, int start, int end, float mag_thresh) {
+    int   i;
+    float mag;
+
+    mag = 0.0;
+    for(i=start; i<=end; i++)
+       mag += model->A[i]*model->A[i];
+    mag = 10*log10(mag/(end-start));
+
+    if (mag > mag_thresh) {
+       for(i=start; i<=end; i++) {
+           float pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
+           float err = pred - model->phi[i];
+           err = atan2(sin(err),cos(err));
+           printf("%f\n",err);
+       }
+       //printf("\n");
+    }
+
+}
+
+
+static void rand_phases(MODEL *model, int start, int end) {
+    int i;
+
+    for(i=start; i<=end; i++)
+       model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX);
+
+}
+
+static void fixed_bits_per_frame(struct PEXP *pexp, MODEL *model, int m, int budget) {
+    int res, finished;
+
+    res = 3;
+    finished = 0;
+
+    while(!finished) {
+       if (m > model->L/2)
+           res = 2;
+       if (((budget - res) < 0) || (m > model->L))
+           finished = 1;
+       else {
+           quant_phase(&model->phi[m], -PI, PI, res);
+           budget -= res;
+           m++;
+       }
+    }
+    printf("m: %d L: %d budget: %d\n", m, model->L, budget);
+    predict_phases(pexp, model, m, model->L);
+    //rand_phases(model, m, model->L);
+}
+
+/* used to plot histogram of quantisation error, for 3 bits, 8 levels,
+   should be uniform between +/- PI/8 */
+
+static void check_phase_quant(MODEL *model, float tol)
+{
+    int m;
+    float phi_before[MAX_AMP];
+
+    for(m=1; m<=model->L; m++)
+       phi_before[m] = model->phi[m];
+
+    quant_phases(model, 1, model->L, 3);
+
+    for(m=1; m<=model->L; m++) {
+       float err = phi_before[m] - model->phi[m];
+       printf("%f\n", err);
+       if (fabs(err) > tol)
+           exit(0);
+    }
+}
+
+
+static float est_phi1(MODEL *model, int start, int end)
+{
+    int m;
+    float delta, s, c, phi1_est;
+
+    if (end > model->L)
+       end = model->L;
+
+    s = c = 0.0;
+    for(m=start; m<end; m++) {
+       delta = model->phi[m+1] - model->phi[m];
+       s += sin(delta);
+       c += cos(delta);
+    }
+
+    phi1_est = atan2(s,c);
+
+    return phi1_est;
+}
+
+static void print_phi1_pred_error(MODEL *model, int start, int end)
+{
+    int m;
+    float phi1_est;
+
+    phi1_est = est_phi1(model, start, end);
+
+    for(m=start; m<end; m++) {
+       float err = model->phi[m+1] - model->phi[m] - phi1_est;
+       err = atan2(sin(err),cos(err));
+       printf("%f\n", err);
+    }
+}
+
+
+static void first_order_band(MODEL *model, int start, int end, float phi1_est)
+{
+    int   m;
+    float pred_err, av_pred_err;
+    float c,s;
+
+    s = c = 0.0;
+    for(m=start; m<end; m++) {
+       pred_err = model->phi[m] - phi1_est*m;
+       s += sin(pred_err);
+       c += cos(pred_err);
+    }
+
+    av_pred_err = atan2(s,c);
+    for(m=start; m<end; m++) {
+       model->phi[m] = av_pred_err + phi1_est*m;
+       model->phi[m] = atan2(sin(model->phi[m]), cos(model->phi[m]));
+    }
+
+}
+
+
+static void sub_linear(MODEL *model, int start, int end, float phi1_est)
+{
+    int   m;
+
+    for(m=start; m<end; m++) {
+       model->phi[m] = m*phi1_est;
+    }
+}
+
+
+static void top_amp(struct PEXP *pexp, MODEL *model, int start, int end, int n_harm, int pred)
+{
+    int removed = 0, not_removed = 0;
+    int top, i, j;
+    struct AMPINDEX sorted[MAX_AMP];
+
+    /* sort into ascending order of amplitude */
+
+    printf("\n");
+    for(i=start,j=0; i<end; i++,j++) {
+       sorted[j].amp = model->A[i];
+       sorted[j].index = i;
+       printf("%f ", model->A[i]);
+    }
+    bubbleSort(sorted, end-start);
+
+    printf("\n");
+    for(j=0; j<n_harm; j++)
+       printf("%d %f\n", j, sorted[j].amp);
+
+    /* keep phase of top n_harm, predict others */
+
+    for(i=start; i<end; i++) {
+       top = 0;
+       for(j=0; j<n_harm; j++) {
+           if (model->A[i] == sorted[j].amp) {
+               top = 1;
+               assert(i == sorted[j].index);
+           }
+       }
+
+       #define ALTTOP
+       #ifdef ALTTOP
+       model->phi[i] = 0.0; /* make sure */
+       if (top) {
+           model->phi[i] = i*pexp->phi1;
+           removed++;
+       }
+       else {
+           model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX); // note: try rand for higher harms
+           removed++;
+       }
+       #else
+       if (!top) {
+           model->phi[i] = 0.0; /* make sure */
+           if (pred)  {
+               //model->phi[i] = pexp->phi_prev[i] + i*N_SAMP*(model->Wo + pexp->Wo_prev)/2.0;
+               model->phi[i] = i*model->phi[1];
+           }
+           else
+               model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX); // note: try rand for higher harms
+           removed++;
+       }
+       else {
+           /* need to make this work thru budget of bits */
+           quant_phase(&model->phi[i], -PI, PI, 3);
+           not_removed++;
+       }
+       #endif
+    }
+    printf("dim: %d rem %d not_rem %d\n", end-start, removed, not_removed);
+
+}
+
+
+static void limit_prediction_error(struct PEXP *pexp, MODEL *model, int start, int end, float limit)
+{
+    int   i;
+    float pred, pred_error, error;
+
+    for(i=start; i<=end; i++) {
+       pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
+       pred_error = pred - model->phi[i];
+       pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI);
+       quant_phase(&pred_error, -limit, limit, 2);
+
+       error = pred - pred_error - model->phi[i];
+       error -= TWO_PI*floor((error+PI)/TWO_PI);
+       printf("%f\n", pred_error);
+       model->phi[i] = pred - pred_error;
+    }
+}
+
+
+static void quant_prediction_error(struct PEXP *pexp, MODEL *model, int start, int end, float limit)
+{
+    int   i;
+    float pred, pred_error;
+
+    for(i=start; i<=end; i++) {
+       pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
+       pred_error = pred - model->phi[i];
+       pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI);
+
+       printf("%f\n", pred_error);
+       model->phi[i] = pred - pred_error;
+    }
+}
+
+static void print_sparse_pred_error(struct PEXP *pexp, MODEL *model, int start, int end, float mag_thresh)
+{
+    int    i, index;
+    float  mag, pred, error;
+    float  sparse_pe[MAX_AMP];
+
+    mag = 0.0;
+    for(i=start; i<=end; i++)
+       mag += model->A[i]*model->A[i];
+    mag = 10*log10(mag/(end-start));
+
+    if (mag > mag_thresh) {
+       for(i=0; i<MAX_AMP; i++) {
+           sparse_pe[i] = 0.0;
+       }
+
+       for(i=start; i<=end; i++) {
+           pred = pexp->phi_prev[i] + N_SAMP*i*(model->Wo + pexp->Wo_prev)/2.0;
+           error = pred - model->phi[i];
+           error = atan2(sin(error),cos(error));
+
+           index = MAX_AMP*i*model->Wo/PI;
+           assert(index < MAX_AMP);
+           sparse_pe[index] = error;
+       }
+
+       /* dump spare phase vector in polar format */
+
+       for(i=0; i<MAX_AMP; i++)
+           printf("%f ", sparse_pe[i]);
+       printf("\n");
+    }
+}
+
+static void predict_phases1(struct PEXP *pexp, MODEL *model, int start, int end) {
+    int i;
+    float best_Wo;
+
+    best_Wo = refine_Wo(pexp, model, 1, model->L);
+
+    for(i=start; i<=end; i++) {
+       model->phi[i] = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
+    }
+}
+
+
+#endif
+
+static void update_snr_calc(struct PEXP *pexp, MODEL *model, float before[])
+{
+    int m;
+    float signal, noise, diff;
+
+    signal = 0.0; noise = 0.0;
+    for(m=1; m<=model->L; m++) {
+       signal += model->A[m]*model->A[m];
+       diff = cos(model->phi[m]) - cos(before[m]);
+       noise  += pow(model->A[m]*diff, 2.0);
+       diff = sin(model->phi[m]) - sin(before[m]);
+       noise  += pow(model->A[m]*diff, 2.0);
+       //printf("%f %f\n", before[m], model->phi[m]);
+    }
+    //printf("%f %f snr = %f\n", signal, noise, 10.0*log10(signal/noise));
+    pexp->snr += 10.0*log10(signal/noise);
+}
+
+
+static void update_variance_calc(struct PEXP *pexp, MODEL *model, float before[])
+{
+    int m;
+    float diff;
+
+    for(m=1; m<model->L; m++) {
+        diff = model->phi[m] - before[m];
+        diff = atan2(sin(diff), cos(diff));
+        pexp->var += diff*diff;
+    }
+    pexp->var_n += model->L;
+}
+
+void print_vec(COMP cb[], int d, int e)
+{
+    int i,j;
+
+    for(j=0; j<e; j++) {
+       for(i=0; i<d; i++)
+           printf("%f %f ", cb[j*d+i].real, cb[j*d+i].imag);
+       printf("\n");
+    }
+}
+
+static COMP cconj(COMP a)
+{
+    COMP res;
+
+    res.real = a.real;
+    res.imag = -a.imag;
+
+    return res;
+}
+
+static COMP cadd(COMP a, COMP b)
+{
+    COMP res;
+
+    res.real = a.real + b.real;
+    res.imag = a.imag + b.imag;
+
+    return res;
+}
+
+static COMP cmult(COMP a, COMP b)
+{
+    COMP res;
+
+    res.real = a.real*b.real - a.imag*b.imag;
+    res.imag = a.real*b.imag + a.imag*b.real;
+
+    return res;
+}
+
+static int vq_phase(COMP cb[], COMP vec[], float weights[], int d, int e, float *se)
+{
+   float   error;      /* current error                */
+   int     besti;      /* best index so far            */
+   float   best_error; /* best error so far            */
+   int    i,j;
+   int     ignore;
+   COMP    diffr;
+   float   diffp, metric, best_metric;
+
+   besti = 0;
+   best_metric = best_error = 1E32;
+   for(j=0; j<e; j++) {
+       error = 0.0;
+       metric = 0.0;
+       for(i=0; i<d; i++) {
+           ignore = (vec[i].real == 0.0) && (vec[i].imag == 0.0);
+           if (!ignore) {
+               diffr = cmult(cb[j*d+i], cconj(vec[i]));
+               diffp = atan2(diffr.imag, diffr.real);
+               error  += diffp*diffp;
+               metric += weights[i]*weights[i]*diffp*diffp;
+               //metric += weights[i]*diffp*diffp;
+               //metric = log10(weights[i]*fabs(diffp));
+               //printf("diffp %f metric %f\n", diffp, metric);
+               //if (metric < log10(PI/(8.0*sqrt(3.0))))
+               //   metric = log10(PI/(8.0*sqrt(3.0)));
+           }
+       }
+       if (metric < best_metric) {
+           best_metric = metric;
+           best_error = error;
+           besti = j;
+       }
+   }
+
+   *se += best_error;
+
+   return(besti);
+}
+
+
+static float refine_Wo(struct PEXP     *pexp,
+                      MODEL           *model,
+                      int              start,
+                      int              end)
+
+{
+    int i;
+    float Wo_est, best_var, Wo, var, pred, error, best_Wo;
+
+    /* test variance over a range of Wo values */
+
+    Wo_est = (model->Wo + pexp->Wo_prev)/2.0;
+    best_var = 1E32;
+    best_Wo = Wo_est;
+    for(Wo=0.97*Wo_est; Wo<=1.03*Wo_est; Wo+=0.001*Wo_est) {
+
+       /* predict phase and sum differences between harmonics */
+
+       var = 0.0;
+       for(i=start; i<=end; i++) {
+           pred = pexp->phi_prev[i] + N_SAMP*i*Wo;
+           error = pred - model->phi[i];
+           error = atan2(sin(error),cos(error));
+           var += error*error;
+       }
+
+       if (var < best_var) {
+           best_var = var;
+           best_Wo = Wo;
+       }
+    }
+
+    return best_Wo;
+}
+
+
+static void split_vq(COMP sparse_pe_out[], struct PEXP *pexp, struct codebook *vq, float weights[], COMP sparse_pe_in[])
+{
+    int i, j, non_zero, vq_ind;
+
+    //printf("\n offset %d k %d m %d  j: ", vq->offset, vq->k, vq->m);
+    vq_ind = vq_phase(vq->cb, &sparse_pe_in[vq->offset], &weights[vq->offset], vq->k, vq->m, &pexp->vq_var);
+
+    non_zero = 0;
+    for(i=0, j=vq->offset; i<vq->k; i++,j++) {
+       //printf("%f ", atan2(sparse_pe[i].imag, sparse_pe[i].real));
+       if ((sparse_pe_in[j].real != 0.0) && (sparse_pe_in[j].imag != 0.0)) {
+           //printf("%d ", j);
+           sparse_pe_out[j] = vq->cb[vq->k * vq_ind + i];
+           non_zero++;
+       }
+    }
+    pexp->vq_var_n += non_zero;
+}
+
+
+static void sparse_vq_pred_error(struct PEXP     *pexp,
+                                MODEL           *model
+)
+{
+    int              i, index;
+    float            pred, error, error_q_angle, best_Wo;
+    COMP             sparse_pe_in[MAX_AMP], sparse_pe_out[MAX_AMP];
+    float            weights[MAX_AMP];
+    COMP             error_q_rect;
+
+     best_Wo = refine_Wo(pexp, model, 1, model->L);
+    //best_Wo = (model->Wo + pexp->Wo_prev)/2.0;
+
+     /* transform to sparse pred error vector */
+
+    for(i=0; i<MAX_AMP; i++) {
+       sparse_pe_in[i].real = 0.0;
+       sparse_pe_in[i].imag = 0.0;
+       sparse_pe_out[i].real = 0.0;
+       sparse_pe_out[i].imag = 0.0;
+    }
+
+    //printf("\n");
+    for(i=1; i<=model->L; i++) {
+       pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
+       error = pred - model->phi[i];
+
+       index = MAX_AMP*i*model->Wo/PI;
+       assert(index < MAX_AMP);
+       sparse_pe_in[index].real = cos(error);
+       sparse_pe_in[index].imag = sin(error);
+       sparse_pe_out[index] = sparse_pe_in[index];
+       weights[index] = model->A[i];
+       //printf("%d ", index);
+    }
+
+    /* vector quantise */
+
+    split_vq(sparse_pe_out, pexp, pexp->vq1, weights, sparse_pe_in);
+    split_vq(sparse_pe_out, pexp, pexp->vq2, weights, sparse_pe_in);
+    split_vq(sparse_pe_out, pexp, pexp->vq3, weights, sparse_pe_in);
+    split_vq(sparse_pe_out, pexp, pexp->vq4, weights, sparse_pe_in);
+    split_vq(sparse_pe_out, pexp, pexp->vq5, weights, sparse_pe_in);
+
+    /* transform quantised phases back */
+
+    for(i=1; i<=model->L; i++) {
+       pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
+
+       index = MAX_AMP*i*model->Wo/PI;
+       assert(index < MAX_AMP);
+       error_q_rect  = sparse_pe_out[index];
+       error_q_angle = atan2(error_q_rect.imag, error_q_rect.real);
+       model->phi[i] = pred - error_q_angle;
+       model->phi[i] = atan2(sin(model->phi[i]), cos(model->phi[i]));
+    }
+}
+
+
+/*
+  This functions tests theory that some bands can be combined together
+  due to less frequency resolution at higher frequencies.  This will
+  reduce the amount of information we need to encode.
+*/
+
+void smooth_phase(struct PEXP *pexp, MODEL *model, int mode)
+{
+    int    m, i, j, index, step, v, en, nav, st;
+    COMP   sparse_pe_in[MAX_AMP], av;
+    COMP   sparse_pe_out[MAX_AMP];
+    COMP   smoothed[MAX_AMP];
+    float  best_Wo, pred, err;
+    float  weights[MAX_AMP];
+    float  avw, smoothed_weights[MAX_AMP];
+    COMP   smoothed_in[MAX_AMP], smoothed_out[MAX_AMP];
+
+    best_Wo = refine_Wo(pexp, model, 1, model->L);
+
+    for(m=0; m<MAX_AMP; m++) {
+       sparse_pe_in[m].real = sparse_pe_in[m].imag = 0.0;
+       sparse_pe_out[m].real = sparse_pe_out[m].imag = 0.0;
+    }
+
+    /* set up sparse array */
+
+    for(m=1; m<=model->L; m++) {
+       pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
+       err = model->phi[m] - pred;
+       err = atan2(sin(err),cos(err));
+
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       sparse_pe_in[index].real = model->A[m]*cos(err);
+       sparse_pe_in[index].imag = model->A[m]*sin(err);
+       sparse_pe_out[index] = sparse_pe_in[index];
+       weights[index] = model->A[m];
+    }
+
+    /* now combine samples at high frequencies to reduce dimension */
+
+    step = 2;
+    st = 0;
+    for(i=st,v=0; i<MAX_AMP; i+=step,v++) {
+
+       /* average over one band */
+
+       av.real = 0.0; av.imag = 0.0; avw = 0.0; nav = 0;
+       en = i+step;
+       if (en > (MAX_AMP-1))
+           en = MAX_AMP-1;
+       for(j=i; j<en; j++) {
+           if ((sparse_pe_in[j].real != 0.0) &&(sparse_pe_in[j].imag != 0.0) ) {
+               av = cadd(av, sparse_pe_in[j]);
+               avw += weights[j];
+               nav++;
+           }
+       }
+       if (nav) {
+           smoothed[v] = av;
+           smoothed_weights[v] = avw/nav;
+       }
+       else
+           smoothed[v].real = smoothed[v].imag = 0.0;
+    }
+
+    if (mode == 2) {
+       for(i=0; i<MAX_AMP; i++) {
+           smoothed_in[i] = smoothed[i];
+           smoothed_out[i] = smoothed_in[i];
+       }
+       split_vq(smoothed_out, pexp, pexp->vq1, smoothed_weights, smoothed_in);
+       for(i=0; i<MAX_AMP; i++)
+           smoothed[i] = smoothed_out[i];
+    }
+
+    /* set all samples to smoothed average */
+
+    for(i=st,v=0; i<MAX_AMP; i+=step,v++) {
+       en = i+step;
+       if (en > (MAX_AMP-1))
+           en = MAX_AMP-1;
+       for(j=i; j<en; j++)
+           sparse_pe_out[j] = smoothed[v];
+       if (mode == 1)
+           printf("%f ", atan2(smoothed[v].imag, smoothed[v].real));
+    }
+    if (mode == 1)
+       printf("\n");
+
+    /* convert back to Am */
+
+    for(m=1; m<=model->L; m++) {
+       index = MAX_AMP*m*model->Wo/PI;
+       assert(index < MAX_AMP);
+       pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
+       err = atan2(sparse_pe_out[index].imag, sparse_pe_out[index].real);
+       model->phi[m] = pred + err;
+    }
+
+}
+
+/*
+  Another version of a functions that tests the theory that some bands
+  can be combined together due to less frequency resolution at higher
+  frequencies.  This will reduce the amount of information we need to
+  encode.
+*/
+
+void smooth_phase2(struct PEXP *pexp, MODEL *model) {
+    float m;
+    float step;
+    int   a,b,h,i;
+    float best_Wo, pred, err, s,c, phi1_;
+
+    best_Wo = refine_Wo(pexp, model, 1, model->L);
+
+    step = (float)model->L/30;
+    printf("\nL: %d step: %3.2f am,bm: ", model->L, step);
+    for(m=(float)model->L/4; m<=model->L; m+=step) {
+       a = floor(m);
+       b = floor(m+step);
+       if (b > model->L) b = model->L;
+       h = b-a;
+
+       printf("%d,%d,(%d)  ", a, b, h);
+       c = s = 0.0;
+       if (h>1) {
+           for(i=a; i<b; i++) {
+               pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
+               err = model->phi[i] - pred;
+               c += cos(err); s += sin(err);
+           }
+           phi1_ = atan2(s,c);
+           for(i=a; i<b; i++) {
+               pred = pexp->phi_prev[i] + N_SAMP*i*best_Wo;
+               printf("%d: %4.3f -> ", i, model->phi[i]);
+               model->phi[i] = pred + phi1_;
+               model->phi[i] = atan2(sin(model->phi[i]),cos(model->phi[i]));
+               printf("%4.3f  ", model->phi[i]);
+           }
+       }
+    }
+}
+
+
+#define MAX_BINS 40
+//static float bins[] = {2600.0, 2800.0, 3000.0, 3200.0, 3400.0, 3600.0, 3800.0, 4000.0};
+static float bins[] = {/*
+
+                       1000.0, 1100.0, 1200.0, 1300.0, 1400.0,
+                      1500.0, 1600.0, 1700.0, 1800.0, 1900.0,*/
+
+    2000.0, 2400.0, 2800.0,
+    3000.0, 3400.0, 3600.0, 4000.0};
+
+void smooth_phase3(struct PEXP *pexp, MODEL *model) {
+    int    m, i;
+    int   nbins;
+    int   b;
+    float f, best_Wo, pred, err;
+    COMP  av[MAX_BINS];
+
+    nbins = sizeof(bins)/sizeof(float);
+    best_Wo = refine_Wo(pexp, model, 1, model->L);
+
+    /* clear all bins */
+
+    for(i=0; i<MAX_BINS; i++) {
+       av[i].real = 0.0;
+       av[i].imag = 0.0;
+    }
+
+    /* add phases into each bin */
+
+    for(m=1; m<=model->L; m++) {
+       f = m*model->Wo*FS/TWO_PI;
+       if (f > bins[0]) {
+
+           /* find bin  */
+
+           b = MAX_BINS;
+           for(i=0; i<nbins; i++)
+               if ((f > bins[i]) && (f <= bins[i+1]))
+                   b = i;
+           assert(b < MAX_BINS);
+
+           /* est predicted phase from average */
+
+           pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
+           err = model->phi[m] - pred;
+           av[b].real += cos(err); av[b].imag += sin(err);
+       }
+
+    }
+
+    /* use averages to est phases */
+
+    for(m=1; m<=model->L; m++) {
+       f = m*model->Wo*FS/TWO_PI;
+       if (f > bins[0]) {
+
+           /* find bin */
+
+            b = MAX_BINS; 
+           for(i=0; i<nbins; i++)
+               if ((f > bins[i]) && (f <= bins[i+1]))
+                   b = i;
+           assert(b < MAX_BINS);
+
+           /* add predicted phase error to this bin */
+
+           printf("L %d m %d f %4.f b %d\n", model->L, m, f, b);
+
+           pred = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
+           err = atan2(av[b].imag, av[b].real);
+           printf(" %d: %4.3f -> ", m, model->phi[m]);
+           model->phi[m] = pred + err;
+           model->phi[m] = atan2(sin(model->phi[m]),cos(model->phi[m]));
+           printf("%4.3f\n", model->phi[m]);
+       }
+    }
+    printf("\n");
+}
+
+
+/*
+   Try to code the phase of the largest amplitude in each band.  Randomise the
+   phase of the other harmonics. The theory is that only the largest harmonic
+   will be audible.
+*/
+
+void cb_phase1(struct PEXP *pexp, MODEL *model) {
+    int   m, i;
+    int   nbins;
+    int   b;
+    float f, best_Wo;
+    float max_val[MAX_BINS];
+    int   max_ind[MAX_BINS];
+
+    nbins = sizeof(bins)/sizeof(float);
+    best_Wo = refine_Wo(pexp, model, 1, model->L);
+
+    for(i=0; i<nbins; i++)
+       max_val[i] = 0.0;
+
+    /* determine max amplitude for each bin */
+
+    for(m=1; m<=model->L; m++) {
+       f = m*model->Wo*FS/TWO_PI;
+       if (f > bins[0]) {
+
+           /* find bin  */
+
+           b = MAX_BINS;
+           for(i=0; i<nbins; i++)
+               if ((f > bins[i]) && (f <= bins[i+1]))
+                   b = i;
+           assert(b < MAX_BINS);
+
+           if (model->A[m] > max_val[b]) {
+               max_val[b] = model->A[m];
+               max_ind[b] = m;
+           }
+       }
+
+    }
+
+    /* randomise phase of other harmonics */
+
+    for(m=1; m<=model->L; m++) {
+       f = m*model->Wo*FS/TWO_PI;
+       if (f > bins[0]) {
+
+           /* find bin */
+
+           b = MAX_BINS;
+           for(i=0; i<nbins; i++)
+               if ((f > bins[i]) && (f <= bins[i+1]))
+                   b = i;
+           assert(b < MAX_BINS);
+
+           if (m != max_ind[b])
+               model->phi[m] = pexp->phi_prev[m] + N_SAMP*m*best_Wo;
+       }
+    }
+}
+
+
+/*
+   Theory is only the phase of the envelope of signal matters within a
+   Critical Band. So we estimate the position of an impulse that
+   approximates the envelope of the signal.
+*/
+
+void cb_phase2(struct PEXP *pexp, MODEL *model) {
+    int   st, m, i, a, b, step;
+    float diff,w,c,s;
+    float A[MAX_AMP];
+
+    for(m=1; m<=model->L; m++) {
+       A[m] = model->A[m];
+       model->A[m] = 0;
+    }
+
+    st = 2*model->L/4;
+    step = 3;
+    model->phi[1] = pexp->phi_prev[1] + (pexp->Wo_prev+model->Wo)*N_SAMP/2.0;
+
+    printf("L=%d ", model->L);
+    for(m=st; m<st+step*2; m+=step) {
+       a = m; b=a+step;
+       if (b > model->L)
+           b = model->L;
+
+       c = s = 0;
+       for(i=a; i<b-1; i++) {
+           printf("diff %d,%d ", i, i+1);
+           diff = model->phi[i+1] - model->phi[i];
+           //w = (model->A[i+1] + model->A[i])/2;
+           w = 1.0;
+           c += w*cos(diff); s += w*sin(diff);
+       }
+       // float phi1_ = atan2(s,c);
+       printf("replacing: ");
+       for(i=a; i<b; i++) {
+           //model->phi[i] = i*phi1_;
+           //model->phi[i] = i*model->phi[1];
+           //model->phi[i] = m*(pexp->Wo_prev+model->Wo)*N_SAMP/2.0;
+           model->A[m] = A[m];
+           printf("%d ", i);
+       }
+       printf(" . ");
+    }
+    printf("\n");
+}
+
+
+static void smooth_phase4(MODEL *model) {
+    int    m;
+    float  phi_m, phi_m_1;
+
+    if (model->L > 25) {
+       printf("\nL %d\n", model->L);
+       for(m=model->L/2; m<=model->L; m+=2) {
+           if ((m+1) <= model->L) {
+               phi_m   = (model->phi[m] - model->phi[m+1])/2.0;
+               phi_m_1 = (model->phi[m+1] - model->phi[m])/2.0;
+               model->phi[m] = phi_m;
+               model->phi[m+1] = phi_m_1;
+               printf("%d %4.3f %4.3f  ", m, phi_m, phi_m_1);
+           }
+       }
+    }
+
+}
+
+/* try repeating last frame, just advance phases to account for time shift */
+
+static void repeat_phases(struct PEXP *pexp, MODEL *model) {
+    int m;
+
+    *model = pexp->prev_model;
+    for(m=1; m<=model->L; m++)
+       model->phi[m] += N_SAMP*m*model->Wo;
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  phase_experiment()
+
+  Phase quantisation experiments.
+
+\*---------------------------------------------------------------------------*/
+
+void phase_experiment(struct PEXP *pexp, MODEL *model, char *arg) {
+    int              m;
+    float            before[MAX_AMP];
+
+    assert(pexp != NULL);
+    memcpy(before, &model->phi[0], sizeof(float)*MAX_AMP);
+
+    if (strcmp(arg,"q3") == 0) {
+       quant_phases(model, 1, model->L, 3);
+       update_snr_calc(pexp, model, before);
+       update_variance_calc(pexp, model, before);
+    }
+
+    if (strcmp(arg,"dec2") == 0) {
+       if ((pexp->frames % 2) != 0) {
+           predict_phases(pexp, model, 1, model->L);
+           update_snr_calc(pexp, model, before);
+           update_variance_calc(pexp, model, before);
+       }
+    }
+
+    if (strcmp(arg,"repeat") == 0) {
+       if ((pexp->frames % 2) != 0) {
+           repeat_phases(pexp, model);
+           update_snr_calc(pexp, model, before);
+           update_variance_calc(pexp, model, before);
+       }
+    }
+
+    if (strcmp(arg,"vq") == 0) {
+       sparse_vq_pred_error(pexp, model);
+       update_snr_calc(pexp, model, before);
+       update_variance_calc(pexp, model, before);
+    }
+
+    if (strcmp(arg,"pred") == 0)
+       predict_phases_state(pexp, model, 1, model->L);
+
+    if (strcmp(arg,"pred1k") == 0)
+       predict_phases(pexp, model, 1, model->L/4);
+
+    if (strcmp(arg,"smooth") == 0) {
+       smooth_phase(pexp, model,0);
+       update_snr_calc(pexp, model, before);
+    }
+    if (strcmp(arg,"smoothtrain") == 0)
+       smooth_phase(pexp, model,1);
+    if (strcmp(arg,"smoothvq") == 0) {
+       smooth_phase(pexp, model,2);
+       update_snr_calc(pexp, model, before);
+    }
+
+    if (strcmp(arg,"smooth2") == 0)
+       smooth_phase2(pexp, model);
+    if (strcmp(arg,"smooth3") == 0)
+       smooth_phase3(pexp, model);
+    if (strcmp(arg,"smooth4") == 0)
+       smooth_phase4(model);
+    if (strcmp(arg,"vqsmooth3") == 0)  {
+       sparse_vq_pred_error(pexp, model);
+       smooth_phase3(pexp, model);
+    }
+
+    if (strcmp(arg,"cb1") == 0) {
+       cb_phase1(pexp, model);
+       update_snr_calc(pexp, model, before);
+    }
+
+    if (strcmp(arg,"top") == 0) {
+       //top_amp(pexp, model, 1, model->L/4, 4, 1);
+       //top_amp(pexp, model, model->L/4, model->L/3, 4, 1);
+       //top_amp(pexp, model, model->L/3+1, model->L/2, 4, 1);
+       //top_amp(pexp, model, model->L/2, model->L, 6, 1);
+        //rand_phases(model, model->L/2, 3*model->L/4);
+       //struct_phases(pexp, model, model->L/2, 3*model->L/4);
+       //update_snr_calc(pexp, model, before);
+    }
+
+    if (strcmp(arg,"pred23") == 0) {
+       predict_phases2(pexp, model, model->L/2, model->L);
+       update_snr_calc(pexp, model, before);
+    }
+
+    if (strcmp(arg,"struct23") == 0) {
+       struct_phases(pexp, model, model->L/2, 3*model->L/4 );
+       update_snr_calc(pexp, model, before);
+    }
+
+    if (strcmp(arg,"addnoise") == 0) {
+       int m;
+       float max;
+
+       max = 0;
+       for(m=1; m<=model->L; m++)
+           if (model->A[m] > max)
+               max = model->A[m];
+       max = 20.0*log10(max);
+       for(m=1; m<=model->L; m++)
+           if (20.0*log10(model->A[m]) < (max-20)) {
+               model->phi[m] += (PI/4)*(1.0 -2.0*rand()/RAND_MAX);
+               //printf("m %d\n", m);
+           }
+    }
+
+    /* normalise phases */
+
+    for(m=1; m<=model->L; m++)
+       model->phi[m] = atan2(sin(model->phi[m]), cos(model->phi[m]));
+
+    /* update states */
+
+    //best_Wo = refine_Wo(pexp, model,  model->L/2, model->L);
+    pexp->phi1 += N_SAMP*model->Wo;
+
+    for(m=1; m<=model->L; m++)
+       pexp->phi_prev[m] = model->phi[m];
+    pexp->Wo_prev = model->Wo;
+    pexp->frames++;
+    pexp->prev_model = *model;
+}
+
+#ifdef OLD_STUFF
+    //quant_phases(model, 1, model->L, 3);
+    //update_variance_calc(pexp, model, before);
+    //print_sparse_pred_error(pexp, model, 1, model->L, 40.0);
+
+    //sparse_vq_pred_error(pexp, model);
+
+    //quant_phases(model, model->L/4+1, model->L, 3);
+
+    //predict_phases1(pexp, model, 1, model->L/4);
+    //quant_phases(model, model->L/4+1, model->L, 3);
+
+    //quant_phases(model, 1, model->L/8, 3);
+
+    //update_snr_calc(pexp, model, before);
+    //update_variance_calc(pexp, model, before);
+
+    //fixed_bits_per_frame(pexp, model, 40);
+    //struct_phases(pexp, model, 1, model->L/4);
+    //rand_phases(model, 10, model->L);
+    //for(m=1; m<=model->L; m++)
+    // model->A[m] = 0.0;
+    //model->A[model->L/2] = 1000;
+    //repeat_phases(model, 20);
+    //predict_phases(pexp, model, 1, model->L/4);
+    //quant_phases(model, 1, 10, 3);
+    //quant_phases(model, 10, 20, 2);
+    //repeat_phases(model, 20);
+    //rand_phases(model, 3*model->L/4, model->L);
+    // print_phi1_pred_error(model, 1, model->L);
+    //predict_phases(pexp, model, 1, model->L/4);
+    //first_order_band(model, model->L/4, model->L/2);
+    //first_order_band(model, model->L/2, 3*model->L/4);
+    //if (fabs(model->Wo - pexp->Wo_prev)< 0.1*model->Wo)
+
+    //print_pred_error(pexp, model, 1, model->L, 40.0);
+    //print_sparse_pred_error(pexp, model, 1, model->L, 40.0);
+
+    //phi1_est = est_phi1(model, 1, model->L/4);
+    //print_phi1_pred_error(model, 1, model->L/4);
+
+    //first_order_band(model, 1, model->L/4, phi1_est);
+    //sub_linear(model, 1, model->L/4, phi1_est);
+
+    //top_amp(pexp, model, 1, model->L/4, 4);
+    //top_amp(pexp, model, model->L/4, model->L/2, 4);
+
+    //first_order_band(model, 1, model->L/4, phi1_est);
+    //first_order_band(model, model->L/4, model->L/2, phi1_est);
+
+    //if (fabs(model->Wo - pexp->Wo_prev) > 0.2*model->Wo)
+    // rand_phases(model, model->L/2, model->L);
+
+    //top_amp(pexp, model, 1, model->L/4, 4);
+    //top_amp(pexp, model, model->L/4, model->L/2, 8);
+    //top_amp(pexp, model, model->L/4+1, model->L/2, 10, 1);
+    //top_amp(pexp, model, 1, model->L/4, 10, 1);
+    //top_amp(pexp, model, model->L/4+1, 3*model->L/4, 10, 1);
+    //top_amp(pexp, model, 1, 3*model->L/4, 20, 1);
+
+    #ifdef REAS_CAND1
+    predict_phases(pexp, model, 1, model->L/4);
+    top_amp(pexp, model, model->L/4+1, 3*model->L/4, 10, 1);
+    rand_phases(model, 3*model->L/4+1, model->L);
+    #endif
+
+    #ifdef REAS_CAND2
+    if ((pexp->frames % 2) == 0) {
+       //printf("quant\n");
+       predict_phases(pexp, model, 1, model->L/4);
+       //top_amp(pexp, model, model->L/4+1, 3*model->L/4, 20, 1);
+       top_amp(pexp, model,  model->L/4+1, 7*model->L/8, 20, 1);
+       rand_phases(model, 7*model->L/8+1, model->L);
+     }
+    else {
+       //printf("predict\n");
+       predict_phases(pexp, model, 1, model->L);
+    }
+    #endif
+
+    //#define REAS_CAND3
+    #ifdef REAS_CAND3
+    if ((pexp->frames % 3) != 0) {
+       printf("pred\n");
+       predict_phases(pexp, model, 1, model->L);
+    }
+    else {
+       predict_phases(pexp, model, 1, model->L/4);
+       fixed_bits_per_frame(pexp, model, model->L/4+1, 60);
+    }
+    #endif
+    //predict_phases(pexp, model, model->L/4, model->L);
+
+
+    //print_pred_error(pexp, model, 1, model->L);
+    //limit_prediction_error(pexp, model, model->L/2, model->L, PI/2);
+#endif
diff --git a/codec2/branches/0.7/src/phaseexp.h b/codec2/branches/0.7/src/phaseexp.h
new file mode 100644 (file)
index 0000000..865e8ae
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: phaseexp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2012
+
+  Experimental functions for quantising, modelling and synthesising phase.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __PHASEEXP__
+#define __PHASEEXP__
+
+#include "kiss_fft.h"
+
+struct PEXP;
+
+struct PEXP * phase_experiment_create();
+void phase_experiment_destroy(struct PEXP *pexp);
+void phase_experiment(struct PEXP *pexp, MODEL *model, char *arg);
+
+#endif
diff --git a/codec2/branches/0.7/src/pilot_coeff.h b/codec2/branches/0.7/src/pilot_coeff.h
new file mode 100644 (file)
index 0000000..85af696
--- /dev/null
@@ -0,0 +1,41 @@
+/* Generated by pilot_coeff_file() Octave function */
+
+// const removed since this provides gain
+// on the STM32F4 platform
+
+#ifdef CORTEX_M4
+/* const */ float pilot_coeff[]={
+#else
+const float pilot_coeff[]={
+#endif
+  0.00223001,
+  0.00301037,
+  0.00471258,
+  0.0075934,
+  0.0118145,
+  0.0174153,
+  0.0242969,
+  0.0322204,
+  0.0408199,
+  0.0496286,
+  0.0581172,
+  0.0657392,
+  0.0719806,
+  0.0764066,
+  0.0787022,
+  0.0787022,
+  0.0764066,
+  0.0719806,
+  0.0657392,
+  0.0581172,
+  0.0496286,
+  0.0408199,
+  0.0322204,
+  0.0242969,
+  0.0174153,
+  0.0118145,
+  0.0075934,
+  0.00471258,
+  0.00301037,
+  0.00223001
+};
diff --git a/codec2/branches/0.7/src/pilots_coh.h b/codec2/branches/0.7/src/pilots_coh.h
new file mode 100644 (file)
index 0000000..9271195
--- /dev/null
@@ -0,0 +1,6 @@
+/* Generated by write_pilot_file() Octave function */
+
+float pilots_coh[][PILOTS_NC]={
+  {  1.000000,  -1.000000,  1.000000,  -1.000000,  1.000000,  -1.000000,  -1.000000},
+  {  -1.000000,  1.000000,  1.000000,  -1.000000,  1.000000,  1.000000,  1.000000}
+};
\ No newline at end of file
diff --git a/codec2/branches/0.7/src/postfilter.c b/codec2/branches/0.7/src/postfilter.c
new file mode 100644 (file)
index 0000000..7c1a606
--- /dev/null
@@ -0,0 +1,142 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: postfilter.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 13/09/09
+
+  Postfilter to improve sound quality for speech with high levels of
+  background noise.  Unlike mixed-excitation models requires no bits
+  to be transmitted to handle background noise.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "defines.h"
+#include "comp.h"
+#include "dump.h"
+#include "sine.h"
+#include "postfilter.h"
+
+/*---------------------------------------------------------------------------*\
+
+                                DEFINES
+
+\*---------------------------------------------------------------------------*/
+
+#define BG_THRESH 40.0     /* only consider low levels signals for bg_est */
+#define BG_BETA    0.1     /* averaging filter constant                   */
+#define BG_MARGIN  6.0     /* harmonics this far above BG noise are
+                             randomised.  Helped make bg noise less
+                             spikey (impulsive) for mmt1, but speech was
+                              perhaps a little rougher.
+                          */
+
+/*---------------------------------------------------------------------------*\
+
+  postfilter()
+
+  The post filter is designed to help with speech corrupted by
+  background noise.  The zero phase model tends to make speech with
+  background noise sound "clicky".  With high levels of background
+  noise the low level inter-formant parts of the spectrum will contain
+  noise rather than speech harmonics, so modelling them as voiced
+  (i.e. a continuous, non-random phase track) is inaccurate.
+
+  Some codecs (like MBE) have a mixed voicing model that breaks the
+  spectrum into voiced and unvoiced regions.  Several bits/frame
+  (5-12) are required to transmit the frequency selective voicing
+  information.  Mixed excitation also requires accurate voicing
+  estimation (parameter estimators always break occasionally under
+  exceptional conditions).
+
+  In our case we use a post filter approach which requires no
+  additional bits to be transmitted.  The decoder measures the average
+  level of the background noise during unvoiced frames.  If a harmonic
+  is less than this level it is made unvoiced by randomising it's
+  phases.
+
+  This idea is rather experimental.  Some potential problems that may
+  happen:
+
+  1/ If someone says "aaaaaaaahhhhhhhhh" will background estimator track
+     up to speech level?  This would be a bad thing.
+
+  2/ If background noise suddenly dissapears from the source speech does
+     estimate drop quickly?  What is noise suddenly re-appears?
+
+  3/ Background noise with a non-flat sepctrum.  Current algorithm just
+     comsiders scpetrum as a whole, but this could be broken up into
+     bands, each with their own estimator.
+
+  4/ Males and females with the same level of background noise.  Check
+     performance the same.  Changing Wo affects width of each band, may
+     affect bg energy estimates.
+
+  5/ Not sure what happens during long periods of voiced speech
+     e.g. "sshhhhhhh"
+
+\*---------------------------------------------------------------------------*/
+
+void postfilter(
+  MODEL *model,
+  float *bg_est
+)
+{
+  int   m, uv;
+  float e, thresh;
+
+  /* determine average energy across spectrum */
+
+  e = 1E-12;
+  for(m=1; m<=model->L; m++)
+      e += model->A[m]*model->A[m];
+
+  assert(e > 0.0);
+  e = 10.0*log10f(e/model->L);
+
+  /* If beneath threhold, update bg estimate.  The idea
+     of the threshold is to prevent updating during high level
+     speech. */
+
+  if ((e < BG_THRESH) && !model->voiced)
+      *bg_est =  *bg_est*(1.0 - BG_BETA) + e*BG_BETA;
+
+  /* now mess with phases during voiced frames to make any harmonics
+     less then our background estimate unvoiced.
+  */
+
+  uv = 0;
+  thresh = powf(10.0, (*bg_est + BG_MARGIN)/20.0);
+  if (model->voiced)
+      for(m=1; m<=model->L; m++)
+         if (model->A[m] < thresh) {
+             model->phi[m] = TWO_PI*(float)codec2_rand()/CODEC2_RAND_MAX;
+             uv++;
+         }
+
+#ifdef DUMP
+  dump_bg(e, *bg_est, 100.0*uv/model->L);
+#endif
+
+}
diff --git a/codec2/branches/0.7/src/postfilter.h b/codec2/branches/0.7/src/postfilter.h
new file mode 100644 (file)
index 0000000..156714e
--- /dev/null
@@ -0,0 +1,33 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: postfilter.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 13/09/09
+
+  Postfilter header file.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __POSTFILTER__
+#define __POSTFILTER__
+
+void postfilter(MODEL *model, float *bg_est);
+
+#endif
diff --git a/codec2/branches/0.7/src/quantise.c b/codec2/branches/0.7/src/quantise.c
new file mode 100644 (file)
index 0000000..8afed7b
--- /dev/null
@@ -0,0 +1,2055 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: quantise.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 31/5/92
+
+  Quantisation functions for the sinusoidal coder.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "defines.h"
+#include "dump.h"
+#include "quantise.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "codec2_fft.h"
+#include "phase.h"
+#include "mbest.h"
+
+#undef PROFILE
+#include "machdep.h"
+
+#define LSP_DELTA1 0.01         /* grid spacing for LSP root searches */
+
+/*---------------------------------------------------------------------------*\
+
+                          FUNCTION HEADERS
+
+\*---------------------------------------------------------------------------*/
+
+float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[],
+                       int m_pitch, int order);
+
+/*---------------------------------------------------------------------------*\
+
+                             FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+int lsp_bits(int i) {
+    return lsp_cb[i].log2m;
+}
+
+int lspd_bits(int i) {
+    return lsp_cbd[i].log2m;
+}
+
+#ifndef CORTEX_M4
+int mel_bits(int i) {
+    return mel_cb[i].log2m;
+}
+
+int lspmelvq_cb_bits(int i) {
+    return lspmelvq_cb[i].log2m;
+}
+#endif
+
+#ifdef __EXPERIMENTAL__
+int lspdt_bits(int i) {
+    return lsp_cbdt[i].log2m;
+}
+#endif
+
+int lsp_pred_vq_bits(int i) {
+    return lsp_cbjvm[i].log2m;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  quantise_init
+
+  Loads the entire LSP quantiser comprised of several vector quantisers
+  (codebooks).
+
+\*---------------------------------------------------------------------------*/
+
+void quantise_init()
+{
+}
+
+/*---------------------------------------------------------------------------*\
+
+  quantise
+
+  Quantises vec by choosing the nearest vector in codebook cb, and
+  returns the vector index.  The squared error of the quantised vector
+  is added to se.
+
+\*---------------------------------------------------------------------------*/
+
+long quantise(const float * cb, float vec[], float w[], int k, int m, float *se)
+/* float   cb[][K];    current VQ codebook             */
+/* float   vec[];      vector to quantise              */
+/* float   w[];         weighting vector                */
+/* int    k;           dimension of vectors            */
+/* int     m;          size of codebook                */
+/* float   *se;                accumulated squared error       */
+{
+   float   e;          /* current error                */
+   long           besti;       /* best index so far            */
+   float   beste;      /* best error so far            */
+   long           j;
+   int     i;
+   float   diff;
+
+   besti = 0;
+   beste = 1E32;
+   for(j=0; j<m; j++) {
+       e = 0.0;
+       for(i=0; i<k; i++) {
+           diff = cb[j*k+i]-vec[i];
+           e += powf(diff*w[i],2.0);
+       }
+       if (e < beste) {
+           beste = e;
+           besti = j;
+       }
+   }
+
+   *se += beste;
+
+   return(besti);
+}
+
+
+
+/*---------------------------------------------------------------------------*\
+
+  encode_lspds_scalar()
+
+  Scalar/VQ LSP difference quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+void encode_lspds_scalar(
+                int   indexes[],
+                float lsp[],
+                int   order
+)
+{
+    int   i,k,m;
+    float lsp_hz[order];
+    float lsp__hz[order];
+    float dlsp[order];
+    float dlsp_[order];
+    float wt[order];
+    const float *cb;
+    float se;
+
+    for(i=0; i<order; i++) {
+       wt[i] = 1.0;
+    }
+
+    /* convert from radians to Hz so we can use human readable
+       frequencies */
+
+    for(i=0; i<order; i++)
+       lsp_hz[i] = (4000.0/PI)*lsp[i];
+
+    //printf("\n");
+
+    wt[0] = 1.0;
+    for(i=0; i<order; i++) {
+
+       /* find difference from previous qunatised lsp */
+
+       if (i)
+           dlsp[i] = lsp_hz[i] - lsp__hz[i-1];
+       else
+           dlsp[0] = lsp_hz[0];
+
+       k = lsp_cbd[i].k;
+       m = lsp_cbd[i].m;
+       cb = lsp_cbd[i].cb;
+       indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se);
+       dlsp_[i] = cb[indexes[i]*k];
+
+
+       if (i)
+           lsp__hz[i] = lsp__hz[i-1] + dlsp_[i];
+       else
+           lsp__hz[0] = dlsp_[0];
+
+       //printf("%d lsp %3.2f dlsp %3.2f dlsp_ %3.2f lsp_ %3.2f\n", i, lsp_hz[i], dlsp[i], dlsp_[i], lsp__hz[i]);
+    }
+
+}
+
+
+void decode_lspds_scalar(
+                float lsp_[],
+                int   indexes[],
+                int   order
+)
+{
+    int   i,k;
+    float lsp__hz[order];
+    float dlsp_[order];
+    const float *cb;
+
+     for(i=0; i<order; i++) {
+
+       k = lsp_cbd[i].k;
+       cb = lsp_cbd[i].cb;
+       dlsp_[i] = cb[indexes[i]*k];
+
+       if (i)
+           lsp__hz[i] = lsp__hz[i-1] + dlsp_[i];
+       else
+           lsp__hz[0] = dlsp_[0];
+
+       lsp_[i] = (PI/4000.0)*lsp__hz[i];
+
+       //printf("%d dlsp_ %3.2f lsp_ %3.2f\n", i, dlsp_[i], lsp__hz[i]);
+    }
+
+}
+
+#ifdef __EXPERIMENTAL__
+/*---------------------------------------------------------------------------*\
+
+  lspvq_quantise
+
+  Vector LSP quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+void lspvq_quantise(
+  float lsp[],
+  float lsp_[],
+  int   order
+)
+{
+    int   i,k,m,ncb, nlsp;
+    float  wt[order], lsp_hz[order];
+    const float *cb;
+    float se;
+    int   index;
+
+    for(i=0; i<order; i++) {
+       wt[i] = 1.0;
+       lsp_hz[i] = 4000.0*lsp[i]/PI;
+    }
+
+    /* scalar quantise LSPs 1,2,3,4 */
+
+    /* simple uniform scalar quantisers */
+
+   for(i=0; i<4; i++) {
+       k = lsp_cb[i].k;
+       m = lsp_cb[i].m;
+       cb = lsp_cb[i].cb;
+       index = quantise(cb, &lsp_hz[i], wt, k, m, &se);
+       lsp_[i] = cb[index*k]*PI/4000.0;
+    }
+
+   //#define WGHT
+#ifdef WGHT
+    for(i=4; i<9; i++) {
+       wt[i] = 1.0/(lsp[i]-lsp[i-1]) + 1.0/(lsp[i+1]-lsp[i]);
+       //printf("wt[%d] = %f\n", i, wt[i]);
+    }
+    wt[9] = 1.0/(lsp[i]-lsp[i-1]);
+#endif
+
+    /* VQ LSPs 5,6,7,8,9,10 */
+
+    ncb = 4;
+    nlsp = 4;
+    k = lsp_cbjnd[ncb].k;
+    m = lsp_cbjnd[ncb].m;
+    cb = lsp_cbjnd[ncb].cb;
+    index = quantise(cb, &lsp_hz[nlsp], &wt[nlsp], k, m, &se);
+    for(i=4; i<order; i++) {
+       lsp_[i] = cb[index*k+i-4]*(PI/4000.0);
+       //printf("%4.f (%4.f) ", lsp_hz[i], cb[index*k+i-4]);
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  lspjnd_quantise
+
+  Experimental JND LSP quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+void lspjnd_quantise(float lsps[], float lsps_[], int order)
+{
+    int   i,k,m;
+    float  wt[order], lsps_hz[order];
+    const float *cb;
+    float se = 0.0;
+    int   index;
+
+    for(i=0; i<order; i++) {
+       wt[i] = 1.0;
+    }
+
+    /* convert to Hz */
+
+    for(i=0; i<order; i++) {
+       lsps_hz[i] = lsps[i]*(4000.0/PI);
+       lsps_[i] = lsps[i];
+    }
+
+    /* simple uniform scalar quantisers */
+
+    for(i=0; i<4; i++) {
+       k = lsp_cbjnd[i].k;
+       m = lsp_cbjnd[i].m;
+       cb = lsp_cbjnd[i].cb;
+       index = quantise(cb, &lsps_hz[i], wt, k, m, &se);
+       lsps_[i] = cb[index*k]*(PI/4000.0);
+    }
+
+    /* VQ LSPs 5,6,7,8,9,10 */
+
+    k = lsp_cbjnd[4].k;
+    m = lsp_cbjnd[4].m;
+    cb = lsp_cbjnd[4].cb;
+    index = quantise(cb, &lsps_hz[4], &wt[4], k, m, &se);
+    //printf("k = %d m = %d c[0] %f cb[k] %f\n", k,m,cb[0],cb[k]);
+    //printf("index = %4d: ", index);
+    for(i=4; i<order; i++) {
+       lsps_[i] = cb[index*k+i-4]*(PI/4000.0);
+       //printf("%4.f (%4.f) ", lsps_hz[i], cb[index*k+i-4]);
+    }
+    //printf("\n");
+}
+
+void compute_weights(const float *x, float *w, int ndim);
+
+/*---------------------------------------------------------------------------*\
+
+  lspdt_quantise
+
+  LSP difference in time quantiser.  Split VQ, encoding LSPs 1-4 with
+  one VQ, and LSPs 5-10 with a second.  Update of previous lsp memory
+  is done outside of this function to handle dT between 10 or 20ms
+  frames.
+
+  mode        action
+  ------------------
+
+  LSPDT_ALL   VQ LSPs 1-4 and 5-10
+  LSPDT_LOW   Just VQ LSPs 1-4, for LSPs 5-10 just copy previous
+  LSPDT_HIGH  Just VQ LSPs 5-10, for LSPs 1-4 just copy previous
+
+\*---------------------------------------------------------------------------*/
+
+void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode)
+{
+    int   i;
+    float wt[LPC_ORD];
+    float lsps_dt[LPC_ORD];
+#ifdef TRY_LSPDT_VQ
+    int k,m;
+    int   index;
+    const float *cb;
+    float se = 0.0;
+#endif // TRY_LSPDT_VQ
+
+    //compute_weights(lsps, wt, LPC_ORD);
+    for(i=0; i<LPC_ORD; i++) {
+    wt[i] = 1.0;
+    }
+
+    //compute_weights(lsps, wt, LPC_ORD );
+
+    for(i=0; i<LPC_ORD; i++) {
+       lsps_dt[i] = lsps[i] - lsps__prev[i];
+       lsps_[i] = lsps__prev[i];
+    }
+
+    //#define TRY_LSPDT_VQ
+#ifdef TRY_LSPDT_VQ
+    /* this actually improves speech a bit, but 40ms updates works surprsingly well.... */
+    k = lsp_cbdt[0].k;
+    m = lsp_cbdt[0].m;
+    cb = lsp_cbdt[0].cb;
+    index = quantise(cb, lsps_dt, wt, k, m, &se);
+    for(i=0; i<LPC_ORD; i++) {
+       lsps_[i] += cb[index*k + i];
+    }
+#endif
+
+}
+#endif
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define MAX_ENTRIES 16384
+
+void compute_weights(const float *x, float *w, int ndim)
+{
+  int i;
+  w[0] = MIN(x[0], x[1]-x[0]);
+  for (i=1;i<ndim-1;i++)
+    w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]);
+  w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], PI-x[ndim-1]);
+
+  for (i=0;i<ndim;i++)
+    w[i] = 1./(.01+w[i]);
+  //w[0]*=3;
+  //w[1]*=2;
+}
+
+#ifdef __EXPERIMENTAL__
+/* LSP weight calculation ported from m-file function kindly submitted
+   by Anssi, OH3GDD */
+
+void compute_weights_anssi_mode2(const float *x, float *w, int ndim)
+{
+  int i;
+  float d[LPC_ORD];
+
+  assert(ndim == LPC_ORD);
+
+  for(i=0; i<LPC_ORD; i++)
+      d[i] = 1.0;
+
+  d[0] = x[1];
+  for (i=1; i<LPC_ORD-1; i++)
+      d[i] = x[i+1] - x[i-1];
+  d[LPC_ORD-1] = PI - x[8];
+  for (i=0; i<LPC_ORD; i++) {
+        if (x[i]<((400.0/4000.0)*PI))
+            w[i]=5.0/(0.01+d[i]);
+        else if (x[i]<((700.0/4000.0)*PI))
+            w[i]=4.0/(0.01+d[i]);
+        else if (x[i]<((1200.0/4000.0)*PI))
+            w[i]=3.0/(0.01+d[i]);
+        else if (x[i]<((2000.0/4000.0)*PI))
+            w[i]=2.0/(0.01+d[i]);
+        else
+            w[i]=1.0/(0.01+d[i]);
+
+        w[i]=powf(w[i]+0.3, 0.66);
+  }
+}
+#endif
+
+int find_nearest(const float *codebook, int nb_entries, float *x, int ndim)
+{
+  int i, j;
+  float min_dist = 1e15;
+  int nearest = 0;
+
+  for (i=0;i<nb_entries;i++)
+  {
+    float dist=0;
+    for (j=0;j<ndim;j++)
+      dist += (x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]);
+    if (dist<min_dist)
+    {
+      min_dist = dist;
+      nearest = i;
+    }
+  }
+  return nearest;
+}
+
+int find_nearest_weighted(const float *codebook, int nb_entries, float *x, const float *w, int ndim)
+{
+  int i, j;
+  float min_dist = 1e15;
+  int nearest = 0;
+
+  for (i=0;i<nb_entries;i++)
+  {
+    float dist=0;
+    for (j=0;j<ndim;j++)
+      dist += w[j]*(x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]);
+    if (dist<min_dist)
+    {
+      min_dist = dist;
+      nearest = i;
+    }
+  }
+  return nearest;
+}
+
+void lspjvm_quantise(float *x, float *xq, int order)
+{
+  int i, n1, n2, n3;
+  float err[order], err2[order], err3[order];
+  float w[order], w2[order], w3[order];
+  const float *codebook1 = lsp_cbjvm[0].cb;
+  const float *codebook2 = lsp_cbjvm[1].cb;
+  const float *codebook3 = lsp_cbjvm[2].cb;
+
+  w[0] = MIN(x[0], x[1]-x[0]);
+  for (i=1;i<order-1;i++)
+    w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]);
+  w[order-1] = MIN(x[order-1]-x[order-2], PI-x[order-1]);
+
+  compute_weights(x, w, order);
+
+  n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, order);
+
+  for (i=0;i<order;i++)
+  {
+    xq[i] = codebook1[order*n1+i];
+    err[i] = x[i] - xq[i];
+  }
+  for (i=0;i<order/2;i++)
+  {
+    err2[i] = err[2*i];
+    err3[i] = err[2*i+1];
+    w2[i] = w[2*i];
+    w3[i] = w[2*i+1];
+  }
+  n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, order/2);
+  n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, order/2);
+
+  for (i=0;i<order/2;i++)
+  {
+    xq[2*i] += codebook2[order*n2/2+i];
+    xq[2*i+1] += codebook3[order*n3/2+i];
+  }
+}
+
+
+#ifndef CORTEX_M4
+/* simple (non mbest) 6th order LSP MEL VQ quantiser.  Returns MSE of result */
+
+float lspmelvq_quantise(float *x, float *xq, int order)
+{
+  int i, n1, n2, n3;
+  float err[order];
+  const float *codebook1 = lspmelvq_cb[0].cb;
+  const float *codebook2 = lspmelvq_cb[1].cb;
+  const float *codebook3 = lspmelvq_cb[2].cb;
+  float tmp[order];
+  float mse;
+
+  assert(order == lspmelvq_cb[0].k);
+
+  n1 = find_nearest(codebook1, lspmelvq_cb[0].m, x, order);
+
+  for (i=0; i<order; i++) {
+    tmp[i] = codebook1[order*n1+i];
+    err[i] = x[i] - tmp[i];
+  }
+
+  n2 = find_nearest(codebook2, lspmelvq_cb[1].m, err, order);
+
+  for (i=0; i<order; i++) {
+    tmp[i] += codebook2[order*n2+i];
+    err[i] = x[i] - tmp[i];
+  }
+
+  n3 = find_nearest(codebook3, lspmelvq_cb[2].m, err, order);
+
+  mse = 0.0;
+  for (i=0; i<order; i++) {
+    tmp[i] += codebook3[order*n3+i];
+    err[i] = x[i] - tmp[i];
+    mse += err[i]*err[i];
+  }
+
+  for (i=0; i<order; i++) {
+      xq[i] = tmp[i];
+  }
+
+  return mse;
+}
+
+/* 3 stage VQ LSP quantiser useing mbest search.  Design and guidance kindly submitted by Anssi, OH3GDD */
+
+float lspmelvq_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries)
+{
+  int i, j, n1, n2, n3;
+  const float *codebook1 = lspmelvq_cb[0].cb;
+  const float *codebook2 = lspmelvq_cb[1].cb;
+  const float *codebook3 = lspmelvq_cb[2].cb;
+  struct MBEST *mbest_stage1, *mbest_stage2, *mbest_stage3;
+  float target[ndim];
+  float w[ndim];
+  int   index[MBEST_STAGES];
+  float mse, tmp;
+
+  for(i=0; i<ndim; i++)
+      w[i] = 1.0;
+
+  mbest_stage1 = mbest_create(mbest_entries);
+  mbest_stage2 = mbest_create(mbest_entries);
+  mbest_stage3 = mbest_create(mbest_entries);
+  for(i=0; i<MBEST_STAGES; i++)
+      index[i] = 0;
+
+  /* Stage 1 */
+
+  mbest_search(codebook1, x, w, ndim, lspmelvq_cb[0].m, mbest_stage1, index);
+  MBEST_PRINT("Stage 1:", mbest_stage1);
+
+
+  /* Stage 2 */
+
+  for (j=0; j<mbest_entries; j++) {
+      index[1] = n1 = mbest_stage1->list[j].index[0];
+      for(i=0; i<ndim; i++)
+         target[i] = x[i] - codebook1[ndim*n1+i];
+      mbest_search(codebook2, target, w, ndim, lspmelvq_cb[1].m, mbest_stage2, index);
+  }
+  MBEST_PRINT("Stage 2:", mbest_stage2);
+
+  /* Stage 3 */
+
+  for (j=0; j<mbest_entries; j++) {
+      index[2] = n1 = mbest_stage2->list[j].index[1];
+      index[1] = n2 = mbest_stage2->list[j].index[0];
+      for(i=0; i<ndim; i++)
+         target[i] = x[i] - codebook1[ndim*n1+i] - codebook2[ndim*n2+i];
+      mbest_search(codebook3, target, w, ndim, lspmelvq_cb[2].m, mbest_stage3, index);
+  }
+  MBEST_PRINT("Stage 3:", mbest_stage3);
+
+  n1 = mbest_stage3->list[0].index[2];
+  n2 = mbest_stage3->list[0].index[1];
+  n3 = mbest_stage3->list[0].index[0];
+  mse = 0.0;
+  for (i=0;i<ndim;i++) {
+      tmp = codebook1[ndim*n1+i] + codebook2[ndim*n2+i] + codebook3[ndim*n3+i];
+      mse += (x[i]-tmp)*(x[i]-tmp);
+      xq[i] = tmp;
+  }
+
+  mbest_destroy(mbest_stage1);
+  mbest_destroy(mbest_stage2);
+  mbest_destroy(mbest_stage3);
+
+  indexes[0] = n1; indexes[1] = n2; indexes[2] = n3;
+
+  return mse;
+}
+
+
+void lspmelvq_decode(int *indexes, float *xq, int ndim)
+{
+  int i, n1, n2, n3;
+  const float *codebook1 = lspmelvq_cb[0].cb;
+  const float *codebook2 = lspmelvq_cb[1].cb;
+  const float *codebook3 = lspmelvq_cb[2].cb;
+
+  n1 = indexes[0]; n2 = indexes[1]; n3 = indexes[2];
+  for (i=0;i<ndim;i++) {
+      xq[i] = codebook1[ndim*n1+i] + codebook2[ndim*n2+i] + codebook3[ndim*n3+i];
+  }
+}
+#endif
+
+
+int check_lsp_order(float lsp[], int order)
+{
+    int   i;
+    float tmp;
+    int   swaps = 0;
+
+    for(i=1; i<order; i++)
+       if (lsp[i] < lsp[i-1]) {
+           //fprintf(stderr, "swap %d\n",i);
+           swaps++;
+           tmp = lsp[i-1];
+           lsp[i-1] = lsp[i]-0.1;
+           lsp[i] = tmp+0.1;
+            i = 1; /* start check again, as swap may have caused out of order */
+       }
+
+    return swaps;
+}
+
+void force_min_lsp_dist(float lsp[], int order)
+{
+    int   i;
+
+    for(i=1; i<order; i++)
+       if ((lsp[i]-lsp[i-1]) < 0.01) {
+           lsp[i] += 0.01;
+       }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+   lpc_post_filter()
+
+   Applies a post filter to the LPC synthesis filter power spectrum
+   Pw, which supresses the inter-formant energy.
+
+   The algorithm is from p267 (Section 8.6) of "Digital Speech",
+   edited by A.M. Kondoz, 1994 published by Wiley and Sons.  Chapter 8
+   of this text is on the MBE vocoder, and this is a freq domain
+   adaptation of post filtering commonly used in CELP.
+
+   I used the Octave simulation lpcpf.m to get an understanding of the
+   algorithm.
+
+   Requires two more FFTs which is significantly more MIPs.  However
+   it should be possible to implement this more efficiently in the
+   time domain.  Just not sure how to handle relative time delays
+   between the synthesis stage and updating these coeffs.  A smaller
+   FFT size might also be accetable to save CPU.
+
+   TODO:
+   [ ] sync var names between Octave and C version
+   [ ] doc gain normalisation
+   [ ] I think the first FFT is not rqd as we do the same
+       thing in aks_to_M2().
+
+\*---------------------------------------------------------------------------*/
+
+void lpc_post_filter(codec2_fftr_cfg fftr_fwd_cfg, float Pw[], float ak[],
+                     int order, int dump, float beta, float gamma, int bass_boost, float E)
+{
+    int   i;
+    float x[FFT_ENC];   /* input to FFTs                */
+    COMP  Ww[FFT_ENC/2+1];  /* weighting spectrum           */
+    float Rw[FFT_ENC/2+1];  /* R = WA                       */
+    float e_before, e_after, gain;
+    float Pfw;
+    float max_Rw, min_Rw;
+    float coeff;
+    PROFILE_VAR(tstart, tfft1, taw, tfft2, tww, tr);
+
+    PROFILE_SAMPLE(tstart);
+
+    /* Determine weighting filter spectrum W(exp(jw)) ---------------*/
+
+    for(i=0; i<FFT_ENC; i++) {
+       x[i] = 0.0;
+    }
+
+    x[0]  = ak[0];
+    coeff = gamma;
+    for(i=1; i<=order; i++) {
+       x[i] = ak[i] * coeff;
+        coeff *= gamma;
+    }
+    codec2_fftr(fftr_fwd_cfg, x, Ww);
+
+    PROFILE_SAMPLE_AND_LOG(tfft2, taw, "        fft2");
+
+    for(i=0; i<FFT_ENC/2; i++) {
+       Ww[i].real = Ww[i].real*Ww[i].real + Ww[i].imag*Ww[i].imag;
+    }
+
+    PROFILE_SAMPLE_AND_LOG(tww, tfft2, "        Ww");
+
+    /* Determined combined filter R = WA ---------------------------*/
+
+    max_Rw = 0.0; min_Rw = 1E32;
+    for(i=0; i<FFT_ENC/2; i++) {
+       Rw[i] = sqrtf(Ww[i].real * Pw[i]);
+       if (Rw[i] > max_Rw)
+           max_Rw = Rw[i];
+       if (Rw[i] < min_Rw)
+           min_Rw = Rw[i];
+
+    }
+
+    PROFILE_SAMPLE_AND_LOG(tr, tww, "        R");
+
+    #ifdef DUMP
+    if (dump)
+      dump_Rw(Rw);
+    #endif
+
+    /* create post filter mag spectrum and apply ------------------*/
+
+    /* measure energy before post filtering */
+
+    e_before = 1E-4;
+    for(i=0; i<FFT_ENC/2; i++)
+       e_before += Pw[i];
+
+    /* apply post filter and measure energy  */
+
+    #ifdef DUMP
+    if (dump)
+       dump_Pwb(Pw);
+    #endif
+
+
+    e_after = 1E-4;
+    for(i=0; i<FFT_ENC/2; i++) {
+        Pfw = powf(Rw[i], beta);
+        Pw[i] *= Pfw * Pfw;
+        e_after += Pw[i];
+    }
+    gain = e_before/e_after;
+
+    /* apply gain factor to normalise energy, and LPC Energy */
+
+    gain *= E;
+    for(i=0; i<FFT_ENC/2; i++) {
+       Pw[i] *= gain;
+    }
+
+    if (bass_boost) {
+        /* add 3dB to first 1 kHz to account for LP effect of PF */
+
+        for(i=0; i<FFT_ENC/8; i++) {
+            Pw[i] *= 1.4*1.4;
+        }
+    }
+
+    PROFILE_SAMPLE_AND_LOG2(tr, "        filt");
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+   aks_to_M2()
+
+   Transforms the linear prediction coefficients to spectral amplitude
+   samples.  This function determines A(m) from the average energy per
+   band using an FFT.
+
+\*---------------------------------------------------------------------------*/
+
+void aks_to_M2(
+  codec2_fftr_cfg  fftr_fwd_cfg,
+  float         ak[],       /* LPC's */
+  int           order,
+  MODEL        *model,      /* sinusoidal model parameters for this frame */
+  float         E,          /* energy term */
+  float        *snr,        /* signal to noise ratio for this frame in dB */
+  int           dump,        /* true to dump sample to dump file */
+  int           sim_pf,      /* true to simulate a post filter */
+  int           pf,          /* true to enable actual LPC post filter */
+  int           bass_boost,  /* enable LPC filter 0-1kHz 3dB boost */
+  float         beta,
+  float         gamma,       /* LPC post filter parameters */
+  COMP          Aw[]         /* output power spectrum */
+)
+{
+  int i,m;             /* loop variables */
+  int am,bm;           /* limits of current band */
+  float r;             /* no. rads/bin */
+  float Em;            /* energy in band */
+  float Am;            /* spectral amplitude sample */
+  float signal, noise;
+  PROFILE_VAR(tstart, tfft, tpw, tpf);
+
+  PROFILE_SAMPLE(tstart);
+
+  r = TWO_PI/(FFT_ENC);
+
+  /* Determine DFT of A(exp(jw)) --------------------------------------------*/
+  {
+      float a[FFT_ENC];  /* input to FFT for power spectrum */
+
+      for(i=0; i<FFT_ENC; i++) {
+          a[i] = 0.0;
+      }
+
+      for(i=0; i<=order; i++)
+          a[i] = ak[i];
+      codec2_fftr(fftr_fwd_cfg, a, Aw);
+  }
+  PROFILE_SAMPLE_AND_LOG(tfft, tstart, "      fft");
+
+  /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/
+
+  float Pw[FFT_ENC/2];
+
+#ifndef ARM_MATH_CM4
+  for(i=0; i<FFT_ENC/2; i++) {
+    Pw[i] = 1.0/(Aw[i].real*Aw[i].real + Aw[i].imag*Aw[i].imag + 1E-6);
+  }
+#else
+  // this difference may seem strange, but the gcc for STM32F4 generates almost 5 times
+  // faster code with the two loops: 1120 ms -> 242 ms
+  // so please leave it as is or improve further
+  // since this code is called 4 times it results in almost 4ms gain (21ms -> 17ms per audio frame decode @ 1300 )
+
+  for(i=0; i<FFT_ENC/2; i++)
+  {
+      Pw[i] = Aw[i].real * Aw[i].real + Aw[i].imag * Aw[i].imag  + 1E-6;
+  }
+  for(i=0; i<FFT_ENC/2; i++) {
+      Pw[i] = 1.0/(Pw[i]);
+  }
+#endif
+
+  PROFILE_SAMPLE_AND_LOG(tpw, tfft, "      Pw");
+
+  if (pf)
+      lpc_post_filter(fftr_fwd_cfg, Pw, ak, order, dump, beta, gamma, bass_boost, E);
+  else {
+      for(i=0; i<FFT_ENC/2; i++) {
+          Pw[i] *= E;
+      }
+  }
+
+  PROFILE_SAMPLE_AND_LOG(tpf, tpw, "      LPC post filter");
+
+  #ifdef DUMP
+  if (dump)
+      dump_Pw(Pw);
+  #endif
+
+  /* Determine magnitudes from P(w) ----------------------------------------*/
+
+  /* when used just by decoder {A} might be all zeroes so init signal
+     and noise to prevent log(0) errors */
+
+  signal = 1E-30; noise = 1E-32;
+
+  for(m=1; m<=model->L; m++) {
+      am = (int)((m - 0.5)*model->Wo/r + 0.5);
+      bm = (int)((m + 0.5)*model->Wo/r + 0.5);
+
+      // FIXME: With arm_rfft_fast_f32 we have to use this
+      // otherwise sometimes a to high bm is calculated
+      // which causes trouble later in the calculation
+      // chain
+      // it seems for some reason model->Wo is calculated somewhat too high
+      if (bm>FFT_ENC/2)
+      {
+          bm = FFT_ENC/2;
+      }
+      Em = 0.0;
+
+      for(i=am; i<bm; i++)
+          Em += Pw[i];
+      Am = sqrtf(Em);
+
+      signal += model->A[m]*model->A[m];
+      noise  += (model->A[m] - Am)*(model->A[m] - Am);
+
+      /* This code significantly improves perf of LPC model, in
+         particular when combined with phase0.  The LPC spectrum tends
+         to track just under the peaks of the spectral envelope, and
+         just above nulls.  This algorithm does the reverse to
+         compensate - raising the amplitudes of spectral peaks, while
+         attenuating the null.  This enhances the formants, and
+         supresses the energy between formants. */
+
+      if (sim_pf) {
+          if (Am > model->A[m])
+              Am *= 0.7;
+          if (Am < model->A[m])
+              Am *= 1.4;
+      }
+      model->A[m] = Am;
+  }
+  *snr = 10.0*log10f(signal/noise);
+
+  PROFILE_SAMPLE_AND_LOG2(tpf, "      rec");
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_Wo()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Encodes Wo using a WO_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+int encode_Wo(C2CONST *c2const, float Wo, int bits)
+{
+    int   index, Wo_levels = 1<<bits;
+    float Wo_min = c2const->Wo_min;
+    float Wo_max = c2const->Wo_max;
+    float norm;
+
+    norm = (Wo - Wo_min)/(Wo_max - Wo_min);
+    index = floorf(Wo_levels * norm + 0.5);
+    if (index < 0 ) index = 0;
+    if (index > (Wo_levels-1)) index = Wo_levels-1;
+
+    return index;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_Wo()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Decodes Wo using a WO_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_Wo(C2CONST *c2const, int index, int bits)
+{
+    float Wo_min = c2const->Wo_min;
+    float Wo_max = c2const->Wo_max;
+    float step;
+    float Wo;
+    int   Wo_levels = 1<<bits;
+
+    step = (Wo_max - Wo_min)/Wo_levels;
+    Wo   = Wo_min + step*(index);
+
+    return Wo;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_log_Wo()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Encodes Wo in the log domain using a WO_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+int encode_log_Wo(C2CONST *c2const, float Wo, int bits)
+{
+    int   index, Wo_levels = 1<<bits;
+    float Wo_min = c2const->Wo_min;
+    float Wo_max = c2const->Wo_max;
+    float norm;
+
+    norm = (log10f(Wo) - log10f(Wo_min))/(log10f(Wo_max) - log10f(Wo_min));
+    index = floorf(Wo_levels * norm + 0.5);
+    if (index < 0 ) index = 0;
+    if (index > (Wo_levels-1)) index = Wo_levels-1;
+
+    return index;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_log_Wo()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Decodes Wo using a WO_LEVELS quantiser in the log domain.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_log_Wo(C2CONST *c2const, int index, int bits)
+{
+    float Wo_min = c2const->Wo_min;
+    float Wo_max = c2const->Wo_max;
+    float step;
+    float Wo;
+    int   Wo_levels = 1<<bits;
+
+    step = (log10f(Wo_max) - log10f(Wo_min))/Wo_levels;
+    Wo   = log10f(Wo_min) + step*(index);
+
+    return powf(10,Wo);
+}
+
+#if 0
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_Wo_dt()
+  AUTHOR......: David Rowe
+  DATE CREATED: 6 Nov 2011
+
+  Encodes Wo difference from last frame.
+
+\*---------------------------------------------------------------------------*/
+
+int encode_Wo_dt(C2CONST *c2const, float Wo, float prev_Wo)
+{
+    int   index, mask, max_index, min_index;
+    float Wo_min = c2const->Wo_min;
+    float Wo_max = c2const->Wo_max;
+    float norm;
+
+    norm = (Wo - prev_Wo)/(Wo_max - Wo_min);
+    index = floorf(WO_LEVELS * norm + 0.5);
+    //printf("ENC index: %d ", index);
+
+    /* hard limit */
+
+    max_index = (1 << (WO_DT_BITS-1)) - 1;
+    min_index = - (max_index+1);
+    if (index > max_index) index = max_index;
+    if (index < min_index) index = min_index;
+    //printf("max_index: %d  min_index: %d hard index: %d ",
+    //    max_index,  min_index, index);
+
+    /* mask so that only LSB WO_DT_BITS remain, bit WO_DT_BITS is the sign bit */
+
+    mask = ((1 << WO_DT_BITS) - 1);
+    index &= mask;
+    //printf("mask: 0x%x index: 0x%x\n", mask, index);
+
+    return index;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_Wo_dt()
+  AUTHOR......: David Rowe
+  DATE CREATED: 6 Nov 2011
+
+  Decodes Wo using WO_DT_BITS difference from last frame.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_Wo_dt(C2CONST *c2const, int index, float prev_Wo)
+{
+    float Wo_min = c2const->Wo_min;
+    float Wo_max = c2const->Wo_max;
+    float step;
+    float Wo;
+    int   mask;
+
+    /* sign extend index */
+
+    //printf("DEC index: %d ");
+    if (index & (1 << (WO_DT_BITS-1))) {
+       mask = ~((1 << WO_DT_BITS) - 1);
+       index |= mask;
+    }
+    //printf("DEC mask: 0x%x  index: %d \n", mask, index);
+
+    step = (Wo_max - Wo_min)/WO_LEVELS;
+    Wo   = prev_Wo + step*(index);
+
+    /* bit errors can make us go out of range leading to all sorts of
+       probs like seg faults */
+
+    if (Wo > Wo_max) Wo = Wo_max;
+    if (Wo < Wo_min) Wo = Wo_min;
+
+    return Wo;
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: speech_to_uq_lsps()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Analyse a windowed frame of time domain speech to determine LPCs
+  which are the converted to LSPs for quantisation and transmission
+  over the channel.
+
+\*---------------------------------------------------------------------------*/
+
+float speech_to_uq_lsps(float lsp[],
+                       float ak[],
+                       float Sn[],
+                       float w[],
+                       int m_pitch,
+                        int   order
+)
+{
+    int   i, roots;
+    float Wn[m_pitch];
+    float R[order+1];
+    float e, E;
+
+    e = 0.0;
+    for(i=0; i<m_pitch; i++) {
+       Wn[i] = Sn[i]*w[i];
+       e += Wn[i]*Wn[i];
+    }
+
+    /* trap 0 energy case as LPC analysis will fail */
+
+    if (e == 0.0) {
+       for(i=0; i<order; i++)
+           lsp[i] = (PI/order)*(float)i;
+       return 0.0;
+    }
+
+    autocorrelate(Wn, R, m_pitch, order);
+    levinson_durbin(R, ak, order);
+
+    E = 0.0;
+    for(i=0; i<=order; i++)
+       E += ak[i]*R[i];
+
+    /* 15 Hz BW expansion as I can't hear the difference and it may help
+       help occasional fails in the LSP root finding.  Important to do this
+       after energy calculation to avoid -ve energy values.
+    */
+
+    for(i=0; i<=order; i++)
+       ak[i] *= powf(0.994,(float)i);
+
+    roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1);
+    if (roots != order) {
+       /* if root finding fails use some benign LSP values instead */
+       for(i=0; i<order; i++)
+           lsp[i] = (PI/order)*(float)i;
+    }
+
+    return E;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_lsps_scalar()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Thirty-six bit sclar LSP quantiser. From a vector of unquantised
+  (floating point) LSPs finds the quantised LSP indexes.
+
+\*---------------------------------------------------------------------------*/
+
+void encode_lsps_scalar(int indexes[], float lsp[], int order)
+{
+    int    i,k,m;
+    float  wt[1];
+    float  lsp_hz[order];
+    const float * cb;
+    float se;
+
+    /* convert from radians to Hz so we can use human readable
+       frequencies */
+
+    for(i=0; i<order; i++)
+       lsp_hz[i] = (4000.0/PI)*lsp[i];
+
+    /* scalar quantisers */
+
+    wt[0] = 1.0;
+    for(i=0; i<order; i++) {
+       k = lsp_cb[i].k;
+       m = lsp_cb[i].m;
+       cb = lsp_cb[i].cb;
+       indexes[i] = quantise(cb, &lsp_hz[i], wt, k, m, &se);
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_lsps_scalar()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  From a vector of quantised LSP indexes, returns the quantised
+  (floating point) LSPs.
+
+\*---------------------------------------------------------------------------*/
+
+void decode_lsps_scalar(float lsp[], int indexes[], int order)
+{
+    int    i,k;
+    float  lsp_hz[order];
+    const float * cb;
+
+    for(i=0; i<order; i++) {
+       k = lsp_cb[i].k;
+       cb = lsp_cb[i].cb;
+       lsp_hz[i] = cb[indexes[i]*k];
+    }
+
+    /* convert back to radians */
+
+    for(i=0; i<order; i++)
+       lsp[i] = (PI/4000.0)*lsp_hz[i];
+}
+
+
+#ifndef CORTEX_M4
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_mels_scalar()
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Low bit rate mel coeff encoder.
+
+\*---------------------------------------------------------------------------*/
+
+void encode_mels_scalar(int indexes[], float mels[], int order)
+{
+    int    i,m;
+    float  wt[1];
+    const float * cb;
+    float se, mel_, dmel;
+
+    /* scalar quantisers */
+
+    wt[0] = 1.0;
+    for(i=0; i<order; i++) {
+       m = mel_cb[i].m;
+       cb = mel_cb[i].cb;
+        if (i%2) {
+            /* on odd mels quantise difference */
+            mel_ = mel_cb[i-1].cb[indexes[i-1]];
+            dmel = mels[i] - mel_;
+            indexes[i] = quantise(cb, &dmel, wt, 1, m, &se);
+            //printf("%d mel: %f mel_: %f dmel: %f index: %d\n", i, mels[i], mel_, dmel, indexes[i]);
+        }
+        else {
+            indexes[i] = quantise(cb, &mels[i], wt, 1, m, &se);
+            //printf("%d mel: %f dmel: %f index: %d\n", i, mels[i], 0.0, indexes[i]);
+        }
+
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_mels_scalar()
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  From a vector of quantised mel indexes, returns the quantised
+  (floating point) mels.
+
+\*---------------------------------------------------------------------------*/
+
+void decode_mels_scalar(float mels[], int indexes[], int order)
+{
+    int    i;
+    const float * cb;
+
+    for(i=0; i<order; i++) {
+       cb = mel_cb[i].cb;
+        if (i%2) {
+            /* on odd mels quantise difference */
+            mels[i] = mels[i-1] + cb[indexes[i]];
+        }
+        else
+            mels[i] = cb[indexes[i]];
+    }
+
+}
+
+#endif
+
+#ifdef __EXPERIMENTAL__
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_lsps_diff_freq_vq()
+  AUTHOR......: David Rowe
+  DATE CREATED: 15 November 2011
+
+  Twenty-five bit LSP quantiser.  LSPs 1-4 are quantised with scalar
+  LSP differences (in frequency, i.e difference from the previous
+  LSP).  LSPs 5-10 are quantised with a VQ trained generated using
+  vqtrainjnd.c
+
+\*---------------------------------------------------------------------------*/
+
+void encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order)
+{
+    int    i,k,m;
+    float  lsp_hz[order];
+    float lsp__hz[order];
+    float dlsp[order];
+    float dlsp_[order];
+    float wt[order];
+    const float * cb;
+    float se;
+
+    for(i=0; i<order; i++) {
+       wt[i] = 1.0;
+    }
+
+    /* convert from radians to Hz so we can use human readable
+       frequencies */
+
+    for(i=0; i<order; i++)
+       lsp_hz[i] = (4000.0/PI)*lsp[i];
+
+    /* scalar quantisers for LSP differences 1..4 */
+
+    wt[0] = 1.0;
+    for(i=0; i<4; i++) {
+       if (i)
+           dlsp[i] = lsp_hz[i] - lsp__hz[i-1];
+       else
+           dlsp[0] = lsp_hz[0];
+
+       k = lsp_cbd[i].k;
+       m = lsp_cbd[i].m;
+       cb = lsp_cbd[i].cb;
+       indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se);
+       dlsp_[i] = cb[indexes[i]*k];
+
+       if (i)
+           lsp__hz[i] = lsp__hz[i-1] + dlsp_[i];
+       else
+           lsp__hz[0] = dlsp_[0];
+    }
+
+    /* VQ LSPs 5,6,7,8,9,10 */
+
+    k = lsp_cbjnd[4].k;
+    m = lsp_cbjnd[4].m;
+    cb = lsp_cbjnd[4].cb;
+    indexes[4] = quantise(cb, &lsp_hz[4], &wt[4], k, m, &se);
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_lsps_diff_freq_vq()
+  AUTHOR......: David Rowe
+  DATE CREATED: 15 Nov 2011
+
+  From a vector of quantised LSP indexes, returns the quantised
+  (floating point) LSPs.
+
+\*---------------------------------------------------------------------------*/
+
+void decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order)
+{
+    int    i,k,m;
+    float  dlsp_[order];
+    float  lsp__hz[order];
+    const float * cb;
+
+    /* scalar LSP differences */
+
+    for(i=0; i<4; i++) {
+       cb = lsp_cbd[i].cb;
+       dlsp_[i] = cb[indexes[i]];
+       if (i)
+           lsp__hz[i] = lsp__hz[i-1] + dlsp_[i];
+       else
+           lsp__hz[0] = dlsp_[0];
+    }
+
+    /* VQ */
+
+    k = lsp_cbjnd[4].k;
+    m = lsp_cbjnd[4].m;
+    cb = lsp_cbjnd[4].cb;
+    for(i=4; i<order; i++)
+       lsp__hz[i] = cb[indexes[4]*k+i-4];
+
+    /* convert back to radians */
+
+    for(i=0; i<order; i++)
+       lsp_[i] = (PI/4000.0)*lsp__hz[i];
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_lsps_diff_time()
+  AUTHOR......: David Rowe
+  DATE CREATED: 12 Sep 2012
+
+  Encode difference from preious frames's LSPs using
+  3,3,2,2,2,2,1,1,1,1 scalar quantisers (18 bits total).
+
+\*---------------------------------------------------------------------------*/
+
+void encode_lsps_diff_time(int indexes[],
+                              float lsps[],
+                              float lsps__prev[],
+                              int order)
+{
+    int    i,k,m;
+    float  lsps_dt[order];
+    float  wt[LPC_MAX];
+    const  float * cb;
+    float  se;
+
+    /* Determine difference in time and convert from radians to Hz so
+       we can use human readable frequencies */
+
+    for(i=0; i<order; i++) {
+       lsps_dt[i] = (4000/PI)*(lsps[i] - lsps__prev[i]);
+    }
+
+    /* scalar quantisers */
+
+    wt[0] = 1.0;
+    for(i=0; i<order; i++) {
+       k = lsp_cbdt[i].k;
+       m = lsp_cbdt[i].m;
+       cb = lsp_cbdt[i].cb;
+       indexes[i] = quantise(cb, &lsps_dt[i], wt, k, m, &se);
+    }
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_lsps_diff_time()
+  AUTHOR......: David Rowe
+  DATE CREATED: 15 Nov 2011
+
+  From a quantised LSP indexes, returns the quantised
+  (floating point) LSPs.
+
+\*---------------------------------------------------------------------------*/
+
+void decode_lsps_diff_time(
+                             float lsps_[],
+                             int indexes[],
+                             float lsps__prev[],
+                             int order)
+{
+    int    i,k,m;
+    const  float * cb;
+
+    for(i=0; i<order; i++)
+       lsps_[i] = lsps__prev[i];
+
+    for(i=0; i<order; i++) {
+       k = lsp_cbdt[i].k;
+       cb = lsp_cbdt[i].cb;
+       lsps_[i] += (PI/4000.0)*cb[indexes[i]*k];
+    }
+
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_lsps_vq()
+  AUTHOR......: David Rowe
+  DATE CREATED: 15 Feb 2012
+
+  Multi-stage VQ LSP quantiser developed by Jean-Marc Valin.
+
+\*---------------------------------------------------------------------------*/
+
+void encode_lsps_vq(int *indexes, float *x, float *xq, int order)
+{
+  int i, n1, n2, n3;
+  float err[order], err2[order], err3[order];
+  float w[order], w2[order], w3[order];
+  const float *codebook1 = lsp_cbjvm[0].cb;
+  const float *codebook2 = lsp_cbjvm[1].cb;
+  const float *codebook3 = lsp_cbjvm[2].cb;
+
+  w[0] = MIN(x[0], x[1]-x[0]);
+  for (i=1;i<order-1;i++)
+    w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]);
+  w[order-1] = MIN(x[order-1]-x[order-2], PI-x[order-1]);
+
+  compute_weights(x, w, order);
+
+  n1 = find_nearest(codebook1, lsp_cbjvm[0].m, x, order);
+
+  for (i=0;i<order;i++)
+  {
+    xq[i]  = codebook1[order*n1+i];
+    err[i] = x[i] - xq[i];
+  }
+  for (i=0;i<order/2;i++)
+  {
+    err2[i] = err[2*i];
+    err3[i] = err[2*i+1];
+    w2[i] = w[2*i];
+    w3[i] = w[2*i+1];
+  }
+  n2 = find_nearest_weighted(codebook2, lsp_cbjvm[1].m, err2, w2, order/2);
+  n3 = find_nearest_weighted(codebook3, lsp_cbjvm[2].m, err3, w3, order/2);
+
+  indexes[0] = n1;
+  indexes[1] = n2;
+  indexes[2] = n3;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_lsps_vq()
+  AUTHOR......: David Rowe
+  DATE CREATED: 15 Feb 2012
+
+\*---------------------------------------------------------------------------*/
+
+void decode_lsps_vq(int *indexes, float *xq, int order, int stages)
+{
+  int i, n1, n2, n3;
+  const float *codebook1 = lsp_cbjvm[0].cb;
+  const float *codebook2 = lsp_cbjvm[1].cb;
+  const float *codebook3 = lsp_cbjvm[2].cb;
+
+  n1 = indexes[0];
+  n2 = indexes[1];
+  n3 = indexes[2];
+
+  for (i=0;i<order;i++) {
+      xq[i] = codebook1[order*n1+i];
+  }
+
+  if (stages != 1) {
+      for (i=0;i<order/2;i++) {
+          xq[2*i] += codebook2[order*n2/2+i];
+          xq[2*i+1] += codebook3[order*n3/2+i];
+      }
+  }
+
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: bw_expand_lsps()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Applies Bandwidth Expansion (BW) to a vector of LSPs.  Prevents any
+  two LSPs getting too close together after quantisation.  We know
+  from experiment that LSP quantisation errors < 12.5Hz (25Hz step
+  size) are inaudible so we use that as the minimum LSP separation.
+
+\*---------------------------------------------------------------------------*/
+
+void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high)
+{
+    int i;
+
+    for(i=1; i<4; i++) {
+
+       if ((lsp[i] - lsp[i-1]) < min_sep_low*(PI/4000.0))
+           lsp[i] = lsp[i-1] + min_sep_low*(PI/4000.0);
+
+    }
+
+    /* As quantiser gaps increased, larger BW expansion was required
+       to prevent twinkly noises.  This may need more experiment for
+       different quanstisers.
+    */
+
+    for(i=4; i<order; i++) {
+       if (lsp[i] - lsp[i-1] < min_sep_high*(PI/4000.0))
+           lsp[i] = lsp[i-1] + min_sep_high*(PI/4000.0);
+    }
+}
+
+void bw_expand_lsps2(float lsp[],
+                   int   order
+)
+{
+    int i;
+
+    for(i=1; i<4; i++) {
+
+       if ((lsp[i] - lsp[i-1]) < 100.0*(PI/4000.0))
+           lsp[i] = lsp[i-1] + 100.0*(PI/4000.0);
+
+    }
+
+    /* As quantiser gaps increased, larger BW expansion was required
+       to prevent twinkly noises.  This may need more experiment for
+       different quanstisers.
+    */
+
+    for(i=4; i<order; i++) {
+       if (lsp[i] - lsp[i-1] < 200.0*(PI/4000.0))
+           lsp[i] = lsp[i-1] + 200.0*(PI/4000.0);
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: locate_lsps_jnd_steps()
+  AUTHOR......: David Rowe
+  DATE CREATED: 27/10/2011
+
+  Applies a form of Bandwidth Expansion (BW) to a vector of LSPs.
+  Listening tests have determined that "quantising" the position of
+  each LSP to the non-linear steps below introduces a "just noticable
+  difference" in the synthesised speech.
+
+  This operation can be used before quantisation to limit the input
+  data to the quantiser to a number of discrete steps.
+
+  This operation can also be used during quantisation as a form of
+  hysteresis in the calculation of quantiser error.  For example if
+  the quantiser target of lsp1 is 500 Hz, candidate vectors with lsp1
+  of 515 and 495 Hz sound effectively the same.
+
+\*---------------------------------------------------------------------------*/
+
+void locate_lsps_jnd_steps(float lsps[], int order)
+{
+    int   i;
+    float lsp_hz, step;
+
+    assert(order == 10);
+
+    /* quantise to 25Hz steps */
+
+    step = 25;
+    for(i=0; i<2; i++) {
+       lsp_hz = lsps[i]*4000.0/PI;
+       lsp_hz = floorf(lsp_hz/step + 0.5)*step;
+       lsps[i] = lsp_hz*PI/4000.0;
+       if (i) {
+           if (lsps[i] == lsps[i-1])
+               lsps[i]   += step*PI/4000.0;
+
+       }
+    }
+
+    /* quantise to 50Hz steps */
+
+    step = 50;
+    for(i=2; i<4; i++) {
+       lsp_hz = lsps[i]*4000.0/PI;
+       lsp_hz = floorf(lsp_hz/step + 0.5)*step;
+       lsps[i] = lsp_hz*PI/4000.0;
+       if (i) {
+           if (lsps[i] == lsps[i-1])
+               lsps[i] += step*PI/4000.0;
+
+       }
+    }
+
+    /* quantise to 100Hz steps */
+
+    step = 100;
+    for(i=4; i<10; i++) {
+       lsp_hz = lsps[i]*4000.0/PI;
+       lsp_hz = floorf(lsp_hz/step + 0.5)*step;
+       lsps[i] = lsp_hz*PI/4000.0;
+       if (i) {
+           if (lsps[i] == lsps[i-1])
+               lsps[i] += step*PI/4000.0;
+
+       }
+    }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: apply_lpc_correction()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Apply first harmonic LPC correction at decoder.  This helps improve
+  low pitch males after LPC modelling, like hts1a and morig.
+
+\*---------------------------------------------------------------------------*/
+
+void apply_lpc_correction(MODEL *model)
+{
+    if (model->Wo < (PI*150.0/4000)) {
+       model->A[1] *= 0.032;
+    }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_energy()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Encodes LPC energy using an E_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+int encode_energy(float e, int bits)
+{
+    int   index, e_levels = 1<<bits;
+    float e_min = E_MIN_DB;
+    float e_max = E_MAX_DB;
+    float norm;
+
+    e = 10.0*log10f(e);
+    norm = (e - e_min)/(e_max - e_min);
+    index = floorf(e_levels * norm + 0.5);
+    if (index < 0 ) index = 0;
+    if (index > (e_levels-1)) index = e_levels-1;
+
+    return index;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_energy()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Decodes energy using a E_LEVELS quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_energy(int index, int bits)
+{
+    float e_min = E_MIN_DB;
+    float e_max = E_MAX_DB;
+    float step;
+    float e;
+    int   e_levels = 1<<bits;
+
+    step = (e_max - e_min)/e_levels;
+    e    = e_min + step*(index);
+    e    = powf(10.0,e/10.0);
+
+    return e;
+}
+
+#ifdef NOT_USED
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_amplitudes()
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/2010
+
+  Given the amplitude quantiser indexes recovers the harmonic
+  amplitudes.
+
+\*---------------------------------------------------------------------------*/
+
+float decode_amplitudes(codec2_fft_cfg  fft_fwd_cfg,
+                       MODEL *model,
+                       float  ak[],
+                       int    lsp_indexes[],
+                       int    energy_index,
+                       float  lsps[],
+                       float *e
+)
+{
+    float snr;
+
+    decode_lsps_scalar(lsps, lsp_indexes, LPC_ORD);
+    bw_expand_lsps(lsps, LPC_ORD);
+    lsp_to_lpc(lsps, ak, LPC_ORD);
+    *e = decode_energy(energy_index);
+    aks_to_M2(ak, LPC_ORD, model, *e, &snr, 1, 0, 0, 1);
+    apply_lpc_correction(model);
+
+    return snr;
+}
+#endif
+
+static float ge_coeff[2] = {0.8, 0.9};
+
+void compute_weights2(const float *x, const float *xp, float *w)
+{
+  w[0] = 30;
+  w[1] = 1;
+  if (x[1]<0)
+  {
+     w[0] *= .6;
+     w[1] *= .3;
+  }
+  if (x[1]<-10)
+  {
+     w[0] *= .3;
+     w[1] *= .3;
+  }
+  /* Higher weight if pitch is stable */
+  if (fabsf(x[0]-xp[0])<.2)
+  {
+     w[0] *= 2;
+     w[1] *= 1.5;
+  } else if (fabsf(x[0]-xp[0])>.5) /* Lower if not stable */
+  {
+     w[0] *= .5;
+  }
+
+  /* Lower weight for low energy */
+  if (x[1] < xp[1]-10)
+  {
+     w[1] *= .5;
+  }
+  if (x[1] < xp[1]-20)
+  {
+     w[1] *= .5;
+  }
+
+  //w[0] = 30;
+  //w[1] = 1;
+
+  /* Square the weights because it's applied on the squared error */
+  w[0] *= w[0];
+  w[1] *= w[1];
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: quantise_WoE()
+  AUTHOR......: Jean-Marc Valin & David Rowe
+  DATE CREATED: 29 Feb 2012
+
+  Experimental joint Wo and LPC energy vector quantiser developed by
+  Jean-Marc Valin.  Exploits correlations between the difference in
+  the log pitch and log energy from frame to frame.  For example
+  both the pitch and energy tend to only change by small amounts
+  during voiced speech, however it is important that these changes be
+  coded carefully.  During unvoiced speech they both change a lot but
+  the ear is less sensitve to errors so coarser quantisation is OK.
+
+  The ear is sensitive to log energy and loq pitch so we quantise in
+  these domains.  That way the error measure used to quantise the
+  values is close to way the ear senses errors.
+
+  See http://jmspeex.livejournal.com/10446.html
+
+\*---------------------------------------------------------------------------*/
+
+void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[])
+{
+  int          i, n1;
+  float        x[2];
+  float        err[2];
+  float        w[2];
+  const float *codebook1 = ge_cb[0].cb;
+  int          nb_entries = ge_cb[0].m;
+  int          ndim = ge_cb[0].k;
+  float Wo_min = c2const->Wo_min;
+  float Wo_max = c2const->Wo_max;
+  float Fs = c2const->Fs;
+
+  /* VQ is only trained for Fs = 8000 Hz */
+
+  assert(Fs == 8000);
+
+  x[0] = log10f((model->Wo/PI)*4000.0/50.0)/log10f(2);
+  x[1] = 10.0*log10f(1e-4 + *e);
+
+  compute_weights2(x, xq, w);
+  for (i=0;i<ndim;i++)
+    err[i] = x[i]-ge_coeff[i]*xq[i];
+  n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim);
+
+  for (i=0;i<ndim;i++)
+  {
+    xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i];
+    err[i] -= codebook1[ndim*n1+i];
+  }
+
+  /*
+    x = log2(4000*Wo/(PI*50));
+    2^x = 4000*Wo/(PI*50)
+    Wo = (2^x)*(PI*50)/4000;
+  */
+
+  model->Wo = powf(2.0, xq[0])*(PI*50.0)/4000.0;
+
+  /* bit errors can make us go out of range leading to all sorts of
+     probs like seg faults */
+
+  if (model->Wo > Wo_max) model->Wo = Wo_max;
+  if (model->Wo < Wo_min) model->Wo = Wo_min;
+
+  model->L  = PI/model->Wo; /* if we quantise Wo re-compute L */
+
+  *e = powf(10.0, xq[1]/10.0);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: encode_WoE()
+  AUTHOR......: Jean-Marc Valin & David Rowe
+  DATE CREATED: 11 May 2012
+
+  Joint Wo and LPC energy vector quantiser developed my Jean-Marc
+  Valin.  Returns index, and updated states xq[].
+
+\*---------------------------------------------------------------------------*/
+
+int encode_WoE(MODEL *model, float e, float xq[])
+{
+  int          i, n1;
+  float        x[2];
+  float        err[2];
+  float        w[2];
+  const float *codebook1 = ge_cb[0].cb;
+  int          nb_entries = ge_cb[0].m;
+  int          ndim = ge_cb[0].k;
+
+  assert((1<<WO_E_BITS) == nb_entries);
+
+  if (e < 0.0) e = 0;  /* occasional small negative energies due LPC round off I guess */
+
+  x[0] = log10f((model->Wo/PI)*4000.0/50.0)/log10f(2);
+  x[1] = 10.0*log10f(1e-4 + e);
+
+  compute_weights2(x, xq, w);
+  for (i=0;i<ndim;i++)
+    err[i] = x[i]-ge_coeff[i]*xq[i];
+  n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim);
+
+  for (i=0;i<ndim;i++)
+  {
+    xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i];
+    err[i] -= codebook1[ndim*n1+i];
+  }
+
+  //printf("enc: %f %f (%f)(%f) \n", xq[0], xq[1], e, 10.0*log10(1e-4 + e));
+  return n1;
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: decode_WoE()
+  AUTHOR......: Jean-Marc Valin & David Rowe
+  DATE CREATED: 11 May 2012
+
+  Joint Wo and LPC energy vector quantiser developed my Jean-Marc
+  Valin.  Given index and states xq[], returns Wo & E, and updates
+  states xq[].
+
+\*---------------------------------------------------------------------------*/
+
+void decode_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[], int n1)
+{
+  int          i;
+  const float *codebook1 = ge_cb[0].cb;
+  int          ndim = ge_cb[0].k;
+  float Wo_min = c2const->Wo_min;
+  float Wo_max = c2const->Wo_max;
+
+  for (i=0;i<ndim;i++)
+  {
+    xq[i] = ge_coeff[i]*xq[i] + codebook1[ndim*n1+i];
+  }
+
+  //printf("dec: %f %f\n", xq[0], xq[1]);
+  model->Wo = powf(2.0, xq[0])*(PI*50.0)/4000.0;
+
+  /* bit errors can make us go out of range leading to all sorts of
+     probs like seg faults */
+
+  if (model->Wo > Wo_max) model->Wo = Wo_max;
+  if (model->Wo < Wo_min) model->Wo = Wo_min;
+
+  model->L  = PI/model->Wo; /* if we quantise Wo re-compute L */
+
+  *e = powf(10.0, xq[1]/10.0);
+}
+
diff --git a/codec2/branches/0.7/src/quantise.h b/codec2/branches/0.7/src/quantise.h
new file mode 100644 (file)
index 0000000..4baa87c
--- /dev/null
@@ -0,0 +1,141 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: quantise.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 31/5/92
+
+  Quantisation functions for the sinusoidal coder.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __QUANTISE__
+#define __QUANTISE__
+
+#include "codec2_fft.h"
+#include "comp.h"
+
+#define WO_BITS     7
+#define WO_LEVELS   (1<<WO_BITS)
+#define WO_DT_BITS  3
+
+#define E_BITS      5
+#define E_LEVELS    (1<<E_BITS)
+#define E_MIN_DB   -10.0
+#define E_MAX_DB    40.0
+
+#define LSP_SCALAR_INDEXES    10
+#define LSPD_SCALAR_INDEXES    10
+#define LSP_PRED_VQ_INDEXES    3
+#define LSP_DIFF_FREQ_INDEXES  5
+#define LSP_DIFF_TIME_BITS     7
+
+#define LSPDT_ALL   0
+#define LSPDT_LOW   1
+#define LSPDT_HIGH  2
+
+#define WO_E_BITS   8
+
+#define LPCPF_GAMMA 0.5
+#define LPCPF_BETA  0.2
+
+void quantise_init();
+float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order,
+                          int lsp,float ak[]);
+void aks_to_M2(codec2_fftr_cfg fftr_fwd_cfg, float ak[], int order, MODEL *model,
+              float E, float *snr, int dump, int sim_pf,
+               int pf, int bass_boost, float beta, float gamma, COMP Aw[]);
+
+int   encode_Wo(C2CONST *c2const, float Wo, int bits);
+float decode_Wo(C2CONST *c2const, int index, int bits);
+int   encode_log_Wo(C2CONST *c2const, float Wo, int bits);
+float decode_log_Wo(C2CONST *c2const, int index, int bits);
+#if 0
+int   encode_Wo_dt(C2CONST *c2const, float Wo, float prev_Wo);
+float decode_Wo_dt(C2CONST *c2const, int index, float prev_Wo);
+#endif
+void  encode_lsps_scalar(int indexes[], float lsp[], int order);
+void  decode_lsps_scalar(float lsp[], int indexes[], int order);
+void  encode_lspds_scalar(int indexes[], float lsp[], int order);
+void  decode_lspds_scalar(float lsp[], int indexes[], int order);
+void  encode_lsps_diff_freq_vq(int indexes[], float lsp[], int order);
+void  decode_lsps_diff_freq_vq(float lsp_[], int indexes[], int order);
+void  encode_lsps_diff_time(int indexes[],
+                           float lsp[],
+                           float lsp__prev[],
+                           int order);
+void decode_lsps_diff_time(float lsp_[],
+                          int indexes[],
+                          float lsp__prev[],
+                          int order);
+
+void encode_lsps_vq(int *indexes, float *x, float *xq, int order);
+void decode_lsps_vq(int *indexes, float *xq, int order, int stages);
+
+long quantise(const float * cb, float vec[], float w[], int k, int m, float *se);
+void lspvq_quantise(float lsp[], float lsp_[], int order);
+void lspjnd_quantise(float lsp[], float lsp_[], int order);
+void lspdt_quantise(float lsps[], float lsps_[], float lsps__prev[], int mode);
+void lspjvm_quantise(float lsps[], float lsps_[], int order);
+void lspanssi_quantise(float lsps[], float lsps_[], int order, int mbest_entries);
+float lspmelvq_quantise(float *x, float *xq, int order);
+
+float lspmelvq_mbest_encode(int *indexes, float *x, float *xq, int ndim, int mbest_entries);
+void lspmelvq_decode(int *indexes, float *xq, int ndim);
+
+void encode_mels_scalar(int mel_indexes[], float mels[], int order);
+void decode_mels_scalar(float mels[], int mel_indexes[], int order);
+
+void quantise_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[]);
+int  encode_WoE(MODEL *model, float e, float xq[]);
+void decode_WoE(C2CONST *c2const, MODEL *model, float *e, float xq[], int n1);
+
+int encode_energy(float e, int bits);
+float decode_energy(int index, int bits);
+
+void pack(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits);
+void pack_natural_or_gray(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits, unsigned int gray);
+int  unpack(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits);
+int  unpack_natural_or_gray(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits, unsigned int gray);
+
+int lsp_bits(int i);
+int lspd_bits(int i);
+int lspdt_bits(int i);
+int lsp_pred_vq_bits(int i);
+int mel_bits(int i);
+int lspmelvq_cb_bits(int i);
+
+void apply_lpc_correction(MODEL *model);
+float speech_to_uq_lsps(float lsp[],
+                       float ak[],
+                       float Sn[],
+                       float w[],
+                       int m_pitch,
+                        int   order
+                       );
+int check_lsp_order(float lsp[], int lpc_order);
+void bw_expand_lsps(float lsp[], int order, float min_sep_low, float min_sep_high);
+void bw_expand_lsps2(float lsp[], int order);
+void locate_lsps_jnd_steps(float lsp[], int order);
+float decode_amplitudes(MODEL *model,
+                       float  ak[],
+                       int    lsp_indexes[],
+                       int    energy_index,
+                       float  lsps[],
+                       float *e);
+
+#endif
diff --git a/codec2/branches/0.7/src/resample.c b/codec2/branches/0.7/src/resample.c
new file mode 100644 (file)
index 0000000..1f31fe1
--- /dev/null
@@ -0,0 +1,160 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: resample.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 5/3/2016
+
+  Resamples a stream of 16 bit shorts.
+
+    $ gcc resample.c -o resample -lm -lsamplerate -Wall
+
+\*---------------------------------------------------------------------------*/
+
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#define BUF_PERIOD 0.02   /* length of processingbuffer in seconds */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <samplerate.h>
+
+/* returns number of output samples generated by resampling */
+
+int resample(SRC_STATE *src,
+             short      output_short[],
+             short      input_short[],
+             int        output_sample_rate,
+             int        input_sample_rate,
+             int        length_output_short,  /* maximum output array length in samples */
+             int        length_input_short,
+             int       *input_samples_used,
+             int        last
+            )
+{
+    SRC_DATA src_data;
+    float    input[length_input_short];
+    float    output[length_output_short];
+    int      ret;
+
+    assert(src != NULL);
+
+    src_short_to_float_array(input_short, input, length_input_short);
+
+    src_data.data_in = input;
+    src_data.data_out = output;
+    src_data.input_frames = length_input_short;
+    src_data.output_frames = length_output_short;
+    src_data.end_of_input = last;
+    src_data.src_ratio = (float)output_sample_rate/input_sample_rate;
+    //printf("ratio: %f\n",  src_data.src_ratio);
+
+    ret = src_process(src, &src_data);
+    assert(ret == 0);
+
+    assert(src_data.output_frames_gen <= length_output_short);
+    src_float_to_short_array(output, output_short, src_data.output_frames_gen);
+
+    *input_samples_used = src_data.input_frames_used;
+    return src_data.output_frames_gen;
+}
+
+
+int main(int argc, char *argv[]) {
+    FILE       *fin, *fout;
+    SRC_STATE  *src;
+    int         FsIn, FsOut;
+    int         length_input_short, length_output_short;
+    int         src_error, nin, left_over, nread;
+
+    if (argc < 5) {
+       printf("usage: resample FsIn FsOut InputFileOfShorts OutputFileOfShortsn");
+       printf("e.g    resample 1E6 1E5 Fs1E6HzInputShortFile.raw Fs1E5HzOutputShortFile.raw\n");
+       printf("e.g    SampleGenerator | resample 1E6 1E5 | SampleConsumer\n");
+       exit(1);
+    }
+
+    FsIn  = (int)atof(argv[1]);
+    FsOut = (int)atof(argv[2]);
+
+    length_input_short = BUF_PERIOD*FsIn;
+    length_output_short = BUF_PERIOD*FsOut;
+    //printf("FsIn: %d FsOut: %d length_input_short: %d length_output_short: %d\n",
+    //       FsIn, FsOut, length_input_short, length_output_short);
+
+    short input_short[length_input_short];
+    short output_short[length_output_short];
+
+    if (strcmp(argv[3], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[3],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input speech file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    if (strcmp(argv[4], "-") == 0) fout = stdout;
+    else if ( (fout = fopen(argv[4],"wb")) == NULL ) {
+       fprintf(stderr, "Error opening output speech file: %s: %s.\n",
+         argv[3], strerror(errno));
+       exit(1);
+    }
+
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error);
+    assert(src != NULL);
+
+    nin = length_input_short;
+    left_over = 0;
+    while((nread = fread(&input_short[left_over], sizeof(short), nin, fin)) == nin) {
+        length_output_short = resample(src, 
+                                       output_short, 
+                                       input_short, 
+                                       FsOut,
+                                       FsIn,
+                                       length_output_short,
+                                       length_input_short,
+                                       &nin,
+                                       0);
+        left_over = length_input_short - nin;
+        memcpy(input_short, &input_short[nin], left_over);
+        //printf("length_output_short: %d length_input_short: %d nin: %d left_over: %d\n", 
+        //       length_output_short, length_input_short, nin, left_over);
+        fwrite(output_short, sizeof(short), length_output_short, fout);
+    }
+
+    length_output_short = resample(src, 
+                                   output_short, 
+                                   input_short, 
+                                   FsOut,
+                                   FsIn,
+                                   length_output_short,
+                                   length_input_short,
+                                   &nin,
+                                   1);
+    fwrite(output_short, sizeof(short), length_output_short, fout);
+
+    fclose(fin);
+    fclose(fout);
+
+    src_delete(src);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/src/rn.h b/codec2/branches/0.7/src/rn.h
new file mode 100644 (file)
index 0000000..934f458
--- /dev/null
@@ -0,0 +1,964 @@
+/* Generated by rn_file() Octave function */
+
+const float gt_alpha5_root[]={
+  2.86997e-05,
+  2.2286e-05,
+  1.82863e-05,
+  1.42303e-05,
+  1.04905e-05,
+  6.70859e-06,
+  3.05918e-06,
+  -6.22187e-07,
+  -4.22748e-06,
+  -7.85603e-06,
+  -1.14317e-05,
+  -1.50227e-05,
+  -1.85712e-05,
+  -2.21275e-05,
+  -2.56455e-05,
+  -2.91642e-05,
+  -3.26453e-05,
+  -3.61199e-05,
+  -3.95556e-05,
+  -4.29778e-05,
+  -4.63581e-05,
+  -4.97179e-05,
+  -5.3032e-05,
+  -5.63184e-05,
+  -5.95548e-05,
+  -6.27565e-05,
+  -6.59032e-05,
+  -6.90085e-05,
+  -7.20538e-05,
+  -7.50509e-05,
+  -7.7983e-05,
+  -8.08605e-05,
+  -8.36678e-05,
+  -8.64141e-05,
+  -8.9085e-05,
+  -9.16888e-05,
+  -9.42119e-05,
+  -9.66619e-05,
+  -9.9026e-05,
+  -0.000101311,
+  -0.000103505,
+  -0.000105614,
+  -0.000107627,
+  -0.00010955,
+  -0.000111372,
+  -0.000113099,
+  -0.00011472,
+  -0.000116241,
+  -0.000117652,
+  -0.000118959,
+  -0.000120152,
+  -0.000121235,
+  -0.000122201,
+  -0.000123053,
+  -0.000123784,
+  -0.000124397,
+  -0.000124884,
+  -0.00012525,
+  -0.000125487,
+  -0.000125598,
+  -0.000125578,
+  -0.000125428,
+  -0.000125145,
+  -0.000124729,
+  -0.000124185,
+  -0.000123518,
+  -0.000122709,
+  -0.000121766,
+  -0.000120685,
+  -0.000119471,
+  -0.000118119,
+  -0.000116633,
+  -0.000115009,
+  -0.000113251,
+  -0.000111356,
+  -0.000109326,
+  -0.00010716,
+  -0.00010486,
+  -0.000102424,
+  -9.98553e-05,
+  -9.71528e-05,
+  -9.43199e-05,
+  -9.13551e-05,
+  -8.82623e-05,
+  -8.50404e-05,
+  -8.16936e-05,
+  -7.82211e-05,
+  -7.46271e-05,
+  -7.09109e-05,
+  -6.70773e-05,
+  -6.31256e-05,
+  -5.90607e-05,
+  -5.48823e-05,
+  -5.05954e-05,
+  -4.62001e-05,
+  -4.17016e-05,
+  -3.71002e-05,
+  -3.24015e-05,
+  -2.7606e-05,
+  -2.27195e-05,
+  -1.77428e-05,
+  -1.2682e-05,
+  -7.53795e-06,
+  -2.31702e-06,
+  2.97965e-06,
+  8.34567e-06,
+  1.37796e-05,
+  1.9275e-05,
+  2.483e-05,
+  3.04382e-05,
+  3.60975e-05,
+  4.18011e-05,
+  4.75467e-05,
+  5.33273e-05,
+  5.91403e-05,
+  6.49787e-05,
+  7.08393e-05,
+  7.67152e-05,
+  8.26029e-05,
+  8.84957e-05,
+  9.43895e-05,
+  0.000100278,
+  0.000106157,
+  0.00011202,
+  0.000117864,
+  0.000123681,
+  0.000129468,
+  0.000135218,
+  0.000140929,
+  0.000146583,
+  0.000152183,
+  0.000157725,
+  0.000163202,
+  0.000168608,
+  0.000173938,
+  0.000179183,
+  0.00018434,
+  0.0001894,
+  0.00019436,
+  0.000199211,
+  0.000203949,
+  0.000208568,
+  0.000213063,
+  0.000217426,
+  0.000221654,
+  0.00022574,
+  0.000229678,
+  0.000233463,
+  0.000237089,
+  0.000240551,
+  0.000243843,
+  0.000246959,
+  0.000249895,
+  0.000252644,
+  0.000255202,
+  0.000257562,
+  0.000259721,
+  0.000261672,
+  0.000263411,
+  0.000264933,
+  0.000266234,
+  0.000267308,
+  0.000268152,
+  0.00026876,
+  0.000269128,
+  0.000269253,
+  0.000269129,
+  0.000268754,
+  0.000268123,
+  0.000267232,
+  0.000266079,
+  0.000264658,
+  0.000262968,
+  0.000261006,
+  0.000258767,
+  0.000256251,
+  0.000253453,
+  0.000250373,
+  0.000247007,
+  0.000243354,
+  0.000239412,
+  0.00023518,
+  0.000230655,
+  0.000225837,
+  0.000220723,
+  0.000215314,
+  0.000209608,
+  0.000203605,
+  0.000197304,
+  0.000190706,
+  0.000183812,
+  0.000176621,
+  0.000169145,
+  0.000161363,
+  0.000153275,
+  0.000144895,
+  0.000136224,
+  0.000127266,
+  0.00011802,
+  0.000108491,
+  9.8679e-05,
+  8.85877e-05,
+  7.82196e-05,
+  6.7577e-05,
+  5.66636e-05,
+  4.54822e-05,
+  3.40369e-05,
+  2.23311e-05,
+  1.03695e-05,
+  -1.844e-06,
+  -1.43041e-05,
+  -2.70061e-05,
+  -3.99444e-05,
+  -5.31139e-05,
+  -6.65082e-05,
+  -8.01218e-05,
+  -9.39481e-05,
+  -0.000107981,
+  -0.000122213,
+  -0.000136638,
+  -0.000151248,
+  -0.000166036,
+  -0.000180995,
+  -0.000196115,
+  -0.00021139,
+  -0.000226811,
+  -0.000242369,
+  -0.000258056,
+  -0.000273861,
+  -0.000289776,
+  -0.000305792,
+  -0.000321898,
+  -0.000338084,
+  -0.000354342,
+  -0.00037066,
+  -0.000387027,
+  -0.000403434,
+  -0.00041987,
+  -0.000436324,
+  -0.000452784,
+  -0.00046924,
+  -0.00048568,
+  -0.000502091,
+  -0.000518464,
+  -0.000534785,
+  -0.000551043,
+  -0.000567225,
+  -0.000583319,
+  -0.000599314,
+  -0.000615196,
+  -0.000630955,
+  -0.000646575,
+  -0.000662049,
+  -0.000677361,
+  -0.000692506,
+  -0.000707464,
+  -0.00072229,
+  -0.000736922,
+  -0.000751266,
+  -0.000765372,
+  -0.000779217,
+  -0.000792798,
+  -0.000806094,
+  -0.000819098,
+  -0.000831793,
+  -0.000844168,
+  -0.000856207,
+  -0.000867898,
+  -0.000879227,
+  -0.00089018,
+  -0.000900744,
+  -0.000910906,
+  -0.000920652,
+  -0.00092997,
+  -0.000938844,
+  -0.000947263,
+  -0.000955214,
+  -0.000962682,
+  -0.000969654,
+  -0.000976119,
+  -0.000982062,
+  -0.00098747,
+  -0.000992332,
+  -0.000996634,
+  -0.00100036,
+  -0.00100351,
+  -0.00100606,
+  -0.001008,
+  -0.00100932,
+  -0.00101,
+  -0.00101005,
+  -0.00100943,
+  -0.00100816,
+  -0.0010062,
+  -0.00100356,
+  -0.00100021,
+  -0.000996162,
+  -0.000991392,
+  -0.000985892,
+  -0.000979654,
+  -0.000972668,
+  -0.000964925,
+  -0.000956415,
+  -0.000947131,
+  -0.000937065,
+  -0.000926208,
+  -0.000914552,
+  -0.00090209,
+  -0.000888816,
+  -0.000874721,
+  -0.0008598,
+  -0.000844046,
+  -0.000827453,
+  -0.000810015,
+  -0.000791726,
+  -0.000772581,
+  -0.000752576,
+  -0.000731704,
+  -0.000709965,
+  -0.00068735,
+  -0.000663865,
+  -0.000639509,
+  -0.000614269,
+  -0.000588146,
+  -0.000561139,
+  -0.000533246,
+  -0.000504468,
+  -0.000474802,
+  -0.000444251,
+  -0.000412813,
+  -0.00038049,
+  -0.000347281,
+  -0.000313189,
+  -0.000278215,
+  -0.000242361,
+  -0.000205629,
+  -0.000168024,
+  -0.000129546,
+  -9.02024e-05,
+  -4.99954e-05,
+  -8.93026e-06,
+  3.2988e-05,
+  7.57537e-05,
+  0.000119361,
+  0.000163804,
+  0.000209075,
+  0.000255167,
+  0.000302074,
+  0.000349786,
+  0.000398297,
+  0.000447596,
+  0.000497676,
+  0.000548526,
+  0.000600136,
+  0.000652497,
+  0.000705598,
+  0.000759427,
+  0.000813972,
+  0.000869223,
+  0.000925166,
+  0.000981789,
+  0.00103908,
+  0.00109702,
+  0.00115561,
+  0.00121482,
+  0.00127464,
+  0.00133505,
+  0.00139605,
+  0.00145762,
+  0.00151973,
+  0.00158238,
+  0.00164555,
+  0.00170922,
+  0.00177337,
+  0.00183799,
+  0.00190305,
+  0.00196854,
+  0.00203445,
+  0.00210075,
+  0.00216742,
+  0.00223445,
+  0.00230181,
+  0.00236949,
+  0.00243747,
+  0.00250572,
+  0.00257423,
+  0.00264296,
+  0.00271192,
+  0.00278107,
+  0.00285039,
+  0.00291986,
+  0.00298947,
+  0.00305918,
+  0.00312898,
+  0.00319884,
+  0.00326874,
+  0.00333866,
+  0.00340857,
+  0.00347846,
+  0.00354831,
+  0.00361808,
+  0.00368775,
+  0.00375731,
+  0.00382673,
+  0.00389599,
+  0.00396506,
+  0.00403393,
+  0.00410256,
+  0.00417094,
+  0.00423904,
+  0.00430684,
+  0.00437431,
+  0.00444144,
+  0.0045082,
+  0.00457457,
+  0.00464052,
+  0.00470603,
+  0.00477108,
+  0.00483565,
+  0.00489972,
+  0.00496325,
+  0.00502623,
+  0.00508865,
+  0.00515046,
+  0.00521166,
+  0.00527223,
+  0.00533213,
+  0.00539135,
+  0.00544987,
+  0.00550766,
+  0.00556472,
+  0.005621,
+  0.00567651,
+  0.00573121,
+  0.00578508,
+  0.00583811,
+  0.00589028,
+  0.00594157,
+  0.00599196,
+  0.00604143,
+  0.00608996,
+  0.00613754,
+  0.00618415,
+  0.00622977,
+  0.00627439,
+  0.00631798,
+  0.00636054,
+  0.00640204,
+  0.0064425,
+  0.00648186,
+  0.00652009,
+  0.00655722,
+  0.00659322,
+  0.00662808,
+  0.00666179,
+  0.00669433,
+  0.00672571,
+  0.00675589,
+  0.00678488,
+  0.00681266,
+  0.00683921,
+  0.00686454,
+  0.00688863,
+  0.00691147,
+  0.00693305,
+  0.00695336,
+  0.0069724,
+  0.00699016,
+  0.00700663,
+  0.00702181,
+  0.00703569,
+  0.00704826,
+  0.00705952,
+  0.00706947,
+  0.00707809,
+  0.0070854,
+  0.00709138,
+  0.00709604,
+  0.00709937,
+  0.00710136,
+  0.00710203,
+  0.00710136,
+  0.00709937,
+  0.00709604,
+  0.00709138,
+  0.0070854,
+  0.00707809,
+  0.00706947,
+  0.00705952,
+  0.00704826,
+  0.00703569,
+  0.00702181,
+  0.00700663,
+  0.00699016,
+  0.0069724,
+  0.00695336,
+  0.00693305,
+  0.00691147,
+  0.00688863,
+  0.00686454,
+  0.00683921,
+  0.00681266,
+  0.00678488,
+  0.00675589,
+  0.00672571,
+  0.00669433,
+  0.00666179,
+  0.00662808,
+  0.00659322,
+  0.00655722,
+  0.00652009,
+  0.00648186,
+  0.0064425,
+  0.00640204,
+  0.00636054,
+  0.00631798,
+  0.00627439,
+  0.00622977,
+  0.00618415,
+  0.00613754,
+  0.00608996,
+  0.00604143,
+  0.00599196,
+  0.00594157,
+  0.00589028,
+  0.00583811,
+  0.00578508,
+  0.00573121,
+  0.00567651,
+  0.005621,
+  0.00556472,
+  0.00550766,
+  0.00544987,
+  0.00539135,
+  0.00533213,
+  0.00527223,
+  0.00521166,
+  0.00515046,
+  0.00508865,
+  0.00502623,
+  0.00496325,
+  0.00489972,
+  0.00483565,
+  0.00477108,
+  0.00470603,
+  0.00464052,
+  0.00457457,
+  0.0045082,
+  0.00444144,
+  0.00437431,
+  0.00430684,
+  0.00423904,
+  0.00417094,
+  0.00410256,
+  0.00403393,
+  0.00396506,
+  0.00389599,
+  0.00382673,
+  0.00375731,
+  0.00368775,
+  0.00361808,
+  0.00354831,
+  0.00347846,
+  0.00340857,
+  0.00333866,
+  0.00326874,
+  0.00319884,
+  0.00312898,
+  0.00305918,
+  0.00298947,
+  0.00291986,
+  0.00285039,
+  0.00278107,
+  0.00271192,
+  0.00264296,
+  0.00257423,
+  0.00250572,
+  0.00243747,
+  0.00236949,
+  0.00230181,
+  0.00223445,
+  0.00216742,
+  0.00210075,
+  0.00203445,
+  0.00196854,
+  0.00190305,
+  0.00183799,
+  0.00177337,
+  0.00170922,
+  0.00164555,
+  0.00158238,
+  0.00151973,
+  0.00145762,
+  0.00139605,
+  0.00133505,
+  0.00127464,
+  0.00121482,
+  0.00115561,
+  0.00109702,
+  0.00103908,
+  0.000981789,
+  0.000925166,
+  0.000869223,
+  0.000813972,
+  0.000759427,
+  0.000705598,
+  0.000652497,
+  0.000600136,
+  0.000548526,
+  0.000497676,
+  0.000447596,
+  0.000398297,
+  0.000349786,
+  0.000302074,
+  0.000255167,
+  0.000209075,
+  0.000163804,
+  0.000119361,
+  7.57537e-05,
+  3.2988e-05,
+  -8.93026e-06,
+  -4.99954e-05,
+  -9.02024e-05,
+  -0.000129546,
+  -0.000168024,
+  -0.000205629,
+  -0.000242361,
+  -0.000278215,
+  -0.000313189,
+  -0.000347281,
+  -0.00038049,
+  -0.000412813,
+  -0.000444251,
+  -0.000474802,
+  -0.000504468,
+  -0.000533246,
+  -0.000561139,
+  -0.000588146,
+  -0.000614269,
+  -0.000639509,
+  -0.000663865,
+  -0.00068735,
+  -0.000709965,
+  -0.000731704,
+  -0.000752576,
+  -0.000772581,
+  -0.000791726,
+  -0.000810015,
+  -0.000827453,
+  -0.000844046,
+  -0.0008598,
+  -0.000874721,
+  -0.000888816,
+  -0.00090209,
+  -0.000914552,
+  -0.000926208,
+  -0.000937065,
+  -0.000947131,
+  -0.000956415,
+  -0.000964925,
+  -0.000972668,
+  -0.000979654,
+  -0.000985892,
+  -0.000991392,
+  -0.000996162,
+  -0.00100021,
+  -0.00100356,
+  -0.0010062,
+  -0.00100816,
+  -0.00100943,
+  -0.00101005,
+  -0.00101,
+  -0.00100932,
+  -0.001008,
+  -0.00100606,
+  -0.00100351,
+  -0.00100036,
+  -0.000996634,
+  -0.000992332,
+  -0.00098747,
+  -0.000982062,
+  -0.000976119,
+  -0.000969654,
+  -0.000962682,
+  -0.000955214,
+  -0.000947263,
+  -0.000938844,
+  -0.00092997,
+  -0.000920652,
+  -0.000910906,
+  -0.000900744,
+  -0.00089018,
+  -0.000879227,
+  -0.000867898,
+  -0.000856207,
+  -0.000844168,
+  -0.000831793,
+  -0.000819098,
+  -0.000806094,
+  -0.000792798,
+  -0.000779217,
+  -0.000765372,
+  -0.000751266,
+  -0.000736922,
+  -0.00072229,
+  -0.000707464,
+  -0.000692506,
+  -0.000677361,
+  -0.000662049,
+  -0.000646575,
+  -0.000630955,
+  -0.000615196,
+  -0.000599314,
+  -0.000583319,
+  -0.000567225,
+  -0.000551043,
+  -0.000534785,
+  -0.000518464,
+  -0.000502091,
+  -0.00048568,
+  -0.00046924,
+  -0.000452784,
+  -0.000436324,
+  -0.00041987,
+  -0.000403434,
+  -0.000387027,
+  -0.00037066,
+  -0.000354342,
+  -0.000338084,
+  -0.000321898,
+  -0.000305792,
+  -0.000289776,
+  -0.000273861,
+  -0.000258056,
+  -0.000242369,
+  -0.000226811,
+  -0.00021139,
+  -0.000196115,
+  -0.000180995,
+  -0.000166036,
+  -0.000151248,
+  -0.000136638,
+  -0.000122213,
+  -0.000107981,
+  -9.39481e-05,
+  -8.01218e-05,
+  -6.65082e-05,
+  -5.31139e-05,
+  -3.99444e-05,
+  -2.70061e-05,
+  -1.43041e-05,
+  -1.844e-06,
+  1.03695e-05,
+  2.23311e-05,
+  3.40369e-05,
+  4.54822e-05,
+  5.66636e-05,
+  6.7577e-05,
+  7.82196e-05,
+  8.85877e-05,
+  9.8679e-05,
+  0.000108491,
+  0.00011802,
+  0.000127266,
+  0.000136224,
+  0.000144895,
+  0.000153275,
+  0.000161363,
+  0.000169145,
+  0.000176621,
+  0.000183812,
+  0.000190706,
+  0.000197304,
+  0.000203605,
+  0.000209608,
+  0.000215314,
+  0.000220723,
+  0.000225837,
+  0.000230655,
+  0.00023518,
+  0.000239412,
+  0.000243354,
+  0.000247007,
+  0.000250373,
+  0.000253453,
+  0.000256251,
+  0.000258767,
+  0.000261006,
+  0.000262968,
+  0.000264658,
+  0.000266079,
+  0.000267232,
+  0.000268123,
+  0.000268754,
+  0.000269129,
+  0.000269253,
+  0.000269128,
+  0.00026876,
+  0.000268152,
+  0.000267308,
+  0.000266234,
+  0.000264933,
+  0.000263411,
+  0.000261672,
+  0.000259721,
+  0.000257562,
+  0.000255202,
+  0.000252644,
+  0.000249895,
+  0.000246959,
+  0.000243843,
+  0.000240551,
+  0.000237089,
+  0.000233463,
+  0.000229678,
+  0.00022574,
+  0.000221654,
+  0.000217426,
+  0.000213063,
+  0.000208568,
+  0.000203949,
+  0.000199211,
+  0.00019436,
+  0.0001894,
+  0.00018434,
+  0.000179183,
+  0.000173938,
+  0.000168608,
+  0.000163202,
+  0.000157725,
+  0.000152183,
+  0.000146583,
+  0.000140929,
+  0.000135218,
+  0.000129468,
+  0.000123681,
+  0.000117864,
+  0.00011202,
+  0.000106157,
+  0.000100278,
+  9.43895e-05,
+  8.84957e-05,
+  8.26029e-05,
+  7.67152e-05,
+  7.08393e-05,
+  6.49787e-05,
+  5.91403e-05,
+  5.33273e-05,
+  4.75467e-05,
+  4.18011e-05,
+  3.60975e-05,
+  3.04382e-05,
+  2.483e-05,
+  1.9275e-05,
+  1.37796e-05,
+  8.34567e-06,
+  2.97965e-06,
+  -2.31702e-06,
+  -7.53795e-06,
+  -1.2682e-05,
+  -1.77428e-05,
+  -2.27195e-05,
+  -2.7606e-05,
+  -3.24015e-05,
+  -3.71002e-05,
+  -4.17016e-05,
+  -4.62001e-05,
+  -5.05954e-05,
+  -5.48823e-05,
+  -5.90607e-05,
+  -6.31256e-05,
+  -6.70773e-05,
+  -7.09109e-05,
+  -7.46271e-05,
+  -7.82211e-05,
+  -8.16936e-05,
+  -8.50404e-05,
+  -8.82623e-05,
+  -9.13551e-05,
+  -9.43199e-05,
+  -9.71528e-05,
+  -9.98553e-05,
+  -0.000102424,
+  -0.00010486,
+  -0.00010716,
+  -0.000109326,
+  -0.000111356,
+  -0.000113251,
+  -0.000115009,
+  -0.000116633,
+  -0.000118119,
+  -0.000119471,
+  -0.000120685,
+  -0.000121766,
+  -0.000122709,
+  -0.000123518,
+  -0.000124185,
+  -0.000124729,
+  -0.000125145,
+  -0.000125428,
+  -0.000125578,
+  -0.000125598,
+  -0.000125487,
+  -0.00012525,
+  -0.000124884,
+  -0.000124397,
+  -0.000123784,
+  -0.000123053,
+  -0.000122201,
+  -0.000121235,
+  -0.000120152,
+  -0.000118959,
+  -0.000117652,
+  -0.000116241,
+  -0.00011472,
+  -0.000113099,
+  -0.000111372,
+  -0.00010955,
+  -0.000107627,
+  -0.000105614,
+  -0.000103505,
+  -0.000101311,
+  -9.9026e-05,
+  -9.66619e-05,
+  -9.42119e-05,
+  -9.16888e-05,
+  -8.9085e-05,
+  -8.64141e-05,
+  -8.36678e-05,
+  -8.08605e-05,
+  -7.7983e-05,
+  -7.50509e-05,
+  -7.20538e-05,
+  -6.90085e-05,
+  -6.59032e-05,
+  -6.27565e-05,
+  -5.95548e-05,
+  -5.63184e-05,
+  -5.3032e-05,
+  -4.97179e-05,
+  -4.63581e-05,
+  -4.29778e-05,
+  -3.95556e-05,
+  -3.61199e-05,
+  -3.26453e-05,
+  -2.91642e-05,
+  -2.56455e-05,
+  -2.21275e-05,
+  -1.85712e-05,
+  -1.50227e-05,
+  -1.14317e-05,
+  -7.85603e-06,
+  -4.22748e-06,
+  -6.22187e-07,
+  3.05918e-06,
+  6.70859e-06,
+  1.04905e-05,
+  1.42303e-05,
+  1.82863e-05,
+  2.2286e-05
+};
diff --git a/codec2/branches/0.7/src/rn_coh.h b/codec2/branches/0.7/src/rn_coh.h
new file mode 100644 (file)
index 0000000..d4b3c81
--- /dev/null
@@ -0,0 +1,604 @@
+/* Generated by rn_file() Octave function */
+
+const float gt_alpha5_root_coh[]={
+  4.05576e-05,
+  2.58255e-05,
+  1.58964e-05,
+  5.78773e-06,
+  -3.71244e-06,
+  -1.33229e-05,
+  -2.2664e-05,
+  -3.20611e-05,
+  -4.12734e-05,
+  -5.04935e-05,
+  -5.9545e-05,
+  -6.85565e-05,
+  -7.73902e-05,
+  -8.6137e-05,
+  -9.46835e-05,
+  -0.000103097,
+  -0.000111281,
+  -0.000119289,
+  -0.000127034,
+  -0.000134559,
+  -0.000141789,
+  -0.000148756,
+  -0.000155393,
+  -0.000161723,
+  -0.000167689,
+  -0.000173315,
+  -0.00017854,
+  -0.000183382,
+  -0.000187794,
+  -0.000191793,
+  -0.000195333,
+  -0.000198429,
+  -0.000201038,
+  -0.000203173,
+  -0.000204797,
+  -0.000205922,
+  -0.000206515,
+  -0.00020659,
+  -0.000206117,
+  -0.000205109,
+  -0.000203541,
+  -0.000201427,
+  -0.000198743,
+  -0.000195505,
+  -0.000191693,
+  -0.000187324,
+  -0.000182382,
+  -0.000176885,
+  -0.000170822,
+  -0.00016421,
+  -0.000157041,
+  -0.000149335,
+  -0.000141089,
+  -0.000132323,
+  -0.000123038,
+  -0.000113258,
+  -0.000102985,
+  -9.22439e-05,
+  -8.10442e-05,
+  -6.94109e-05,
+  -5.73536e-05,
+  -4.49012e-05,
+  -3.20661e-05,
+  -1.88794e-05,
+  -5.35615e-06,
+  8.47105e-06,
+  2.25833e-05,
+  3.69472e-05,
+  5.15418e-05,
+  6.63317e-05,
+  8.12934e-05,
+  9.63895e-05,
+  0.000111594,
+  0.000126869,
+  0.000142183,
+  0.000157497,
+  0.000172781,
+  0.000187996,
+  0.000203111,
+  0.000218088,
+  0.000232892,
+  0.000247474,
+  0.000261806,
+  0.000275847,
+  0.000289559,
+  0.000302903,
+  0.000315839,
+  0.00032833,
+  0.000340339,
+  0.000351824,
+  0.000362751,
+  0.00037308,
+  0.000382774,
+  0.000391795,
+  0.000400108,
+  0.000407675,
+  0.000414464,
+  0.000420437,
+  0.000425565,
+  0.000429812,
+  0.000433151,
+  0.000435544,
+  0.000436975,
+  0.000437401,
+  0.000436865,
+  0.000435237,
+  0.00043246,
+  0.000428592,
+  0.000423608,
+  0.000417497,
+  0.00041024,
+  0.000401823,
+  0.000392231,
+  0.000381449,
+  0.000369471,
+  0.000356284,
+  0.000341885,
+  0.000326267,
+  0.00030943,
+  0.000291373,
+  0.000272099,
+  0.000251612,
+  0.000229921,
+  0.000207034,
+  0.000182964,
+  0.000157726,
+  0.000131338,
+  0.000103821,
+  7.51956e-05,
+  4.54842e-05,
+  1.4721e-05,
+  -1.7067e-05,
+  -4.98479e-05,
+  -8.35883e-05,
+  -0.000118248,
+  -0.00015379,
+  -0.000190167,
+  -0.000227336,
+  -0.000265248,
+  -0.000303856,
+  -0.000343104,
+  -0.000382942,
+  -0.00042331,
+  -0.000464152,
+  -0.000505403,
+  -0.000547003,
+  -0.000588883,
+  -0.000630979,
+  -0.000673218,
+  -0.000715533,
+  -0.000757849,
+  -0.000800092,
+  -0.000842187,
+  -0.000884054,
+  -0.000925613,
+  -0.000966788,
+  -0.00100749,
+  -0.00104765,
+  -0.00108717,
+  -0.00112597,
+  -0.00116397,
+  -0.00120108,
+  -0.0012372,
+  -0.00127227,
+  -0.00130617,
+  -0.00133884,
+  -0.00137017,
+  -0.00140008,
+  -0.00142848,
+  -0.00145528,
+  -0.0014804,
+  -0.00150374,
+  -0.00152522,
+  -0.00154475,
+  -0.00156225,
+  -0.00157763,
+  -0.00159081,
+  -0.00160171,
+  -0.00161024,
+  -0.00161633,
+  -0.0016199,
+  -0.00162088,
+  -0.00161917,
+  -0.00161472,
+  -0.00160744,
+  -0.00159729,
+  -0.00158419,
+  -0.00156807,
+  -0.00154888,
+  -0.00152655,
+  -0.00150103,
+  -0.00147227,
+  -0.00144021,
+  -0.00140482,
+  -0.00136604,
+  -0.00132384,
+  -0.00127818,
+  -0.00122903,
+  -0.00117635,
+  -0.00112013,
+  -0.00106033,
+  -0.000996946,
+  -0.000929956,
+  -0.000859348,
+  -0.000785117,
+  -0.000707261,
+  -0.000625779,
+  -0.00054068,
+  -0.000451952,
+  -0.000359651,
+  -0.000263788,
+  -0.00016436,
+  -6.13947e-05,
+  4.5076e-05,
+  0.000155016,
+  0.000268384,
+  0.000385134,
+  0.000505217,
+  0.000628582,
+  0.000755171,
+  0.000884923,
+  0.00101777,
+  0.00115366,
+  0.00129249,
+  0.00143421,
+  0.00157873,
+  0.00172596,
+  0.00187583,
+  0.00202822,
+  0.00218306,
+  0.00234023,
+  0.00249965,
+  0.00266119,
+  0.00282475,
+  0.00299023,
+  0.00315749,
+  0.00332643,
+  0.00349691,
+  0.00366882,
+  0.00384202,
+  0.00401639,
+  0.0041918,
+  0.0043681,
+  0.00454516,
+  0.00472285,
+  0.00490101,
+  0.00507951,
+  0.00525821,
+  0.00543695,
+  0.0056156,
+  0.005794,
+  0.00597201,
+  0.00614947,
+  0.00632623,
+  0.00650216,
+  0.00667708,
+  0.00685086,
+  0.00702335,
+  0.00719439,
+  0.00736383,
+  0.00753153,
+  0.00769734,
+  0.00786111,
+  0.00802269,
+  0.00818194,
+  0.00833872,
+  0.00849289,
+  0.0086443,
+  0.00879283,
+  0.00893832,
+  0.00908066,
+  0.00921971,
+  0.00935534,
+  0.00948743,
+  0.00961585,
+  0.00974049,
+  0.00986123,
+  0.00997795,
+  0.0100905,
+  0.0101989,
+  0.0103029,
+  0.0104025,
+  0.0104976,
+  0.0105881,
+  0.0106738,
+  0.0107548,
+  0.010831,
+  0.0109022,
+  0.0109684,
+  0.0110295,
+  0.0110855,
+  0.0111364,
+  0.011182,
+  0.0112224,
+  0.0112575,
+  0.0112872,
+  0.0113115,
+  0.0113305,
+  0.0113441,
+  0.0113522,
+  0.0113549,
+  0.0113522,
+  0.0113441,
+  0.0113305,
+  0.0113115,
+  0.0112872,
+  0.0112575,
+  0.0112224,
+  0.011182,
+  0.0111364,
+  0.0110855,
+  0.0110295,
+  0.0109684,
+  0.0109022,
+  0.010831,
+  0.0107548,
+  0.0106738,
+  0.0105881,
+  0.0104976,
+  0.0104025,
+  0.0103029,
+  0.0101989,
+  0.0100905,
+  0.00997795,
+  0.00986123,
+  0.00974049,
+  0.00961585,
+  0.00948743,
+  0.00935534,
+  0.00921971,
+  0.00908066,
+  0.00893832,
+  0.00879283,
+  0.0086443,
+  0.00849289,
+  0.00833872,
+  0.00818194,
+  0.00802269,
+  0.00786111,
+  0.00769734,
+  0.00753153,
+  0.00736383,
+  0.00719439,
+  0.00702335,
+  0.00685086,
+  0.00667708,
+  0.00650216,
+  0.00632623,
+  0.00614947,
+  0.00597201,
+  0.005794,
+  0.0056156,
+  0.00543695,
+  0.00525821,
+  0.00507951,
+  0.00490101,
+  0.00472285,
+  0.00454516,
+  0.0043681,
+  0.0041918,
+  0.00401639,
+  0.00384202,
+  0.00366882,
+  0.00349691,
+  0.00332643,
+  0.00315749,
+  0.00299023,
+  0.00282475,
+  0.00266119,
+  0.00249965,
+  0.00234023,
+  0.00218306,
+  0.00202822,
+  0.00187583,
+  0.00172596,
+  0.00157873,
+  0.00143421,
+  0.00129249,
+  0.00115366,
+  0.00101777,
+  0.000884923,
+  0.000755171,
+  0.000628582,
+  0.000505217,
+  0.000385134,
+  0.000268384,
+  0.000155016,
+  4.5076e-05,
+  -6.13947e-05,
+  -0.00016436,
+  -0.000263788,
+  -0.000359651,
+  -0.000451952,
+  -0.00054068,
+  -0.000625779,
+  -0.000707261,
+  -0.000785117,
+  -0.000859348,
+  -0.000929956,
+  -0.000996946,
+  -0.00106033,
+  -0.00112013,
+  -0.00117635,
+  -0.00122903,
+  -0.00127818,
+  -0.00132384,
+  -0.00136604,
+  -0.00140482,
+  -0.00144021,
+  -0.00147227,
+  -0.00150103,
+  -0.00152655,
+  -0.00154888,
+  -0.00156807,
+  -0.00158419,
+  -0.00159729,
+  -0.00160744,
+  -0.00161472,
+  -0.00161917,
+  -0.00162088,
+  -0.0016199,
+  -0.00161633,
+  -0.00161024,
+  -0.00160171,
+  -0.00159081,
+  -0.00157763,
+  -0.00156225,
+  -0.00154475,
+  -0.00152522,
+  -0.00150374,
+  -0.0014804,
+  -0.00145528,
+  -0.00142848,
+  -0.00140008,
+  -0.00137017,
+  -0.00133884,
+  -0.00130617,
+  -0.00127227,
+  -0.0012372,
+  -0.00120108,
+  -0.00116397,
+  -0.00112597,
+  -0.00108717,
+  -0.00104765,
+  -0.00100749,
+  -0.000966788,
+  -0.000925613,
+  -0.000884054,
+  -0.000842187,
+  -0.000800092,
+  -0.000757849,
+  -0.000715533,
+  -0.000673218,
+  -0.000630979,
+  -0.000588883,
+  -0.000547003,
+  -0.000505403,
+  -0.000464152,
+  -0.00042331,
+  -0.000382942,
+  -0.000343104,
+  -0.000303856,
+  -0.000265248,
+  -0.000227336,
+  -0.000190167,
+  -0.00015379,
+  -0.000118248,
+  -8.35883e-05,
+  -4.98479e-05,
+  -1.7067e-05,
+  1.4721e-05,
+  4.54842e-05,
+  7.51956e-05,
+  0.000103821,
+  0.000131338,
+  0.000157726,
+  0.000182964,
+  0.000207034,
+  0.000229921,
+  0.000251612,
+  0.000272099,
+  0.000291373,
+  0.00030943,
+  0.000326267,
+  0.000341885,
+  0.000356284,
+  0.000369471,
+  0.000381449,
+  0.000392231,
+  0.000401823,
+  0.00041024,
+  0.000417497,
+  0.000423608,
+  0.000428592,
+  0.00043246,
+  0.000435237,
+  0.000436865,
+  0.000437401,
+  0.000436975,
+  0.000435544,
+  0.000433151,
+  0.000429812,
+  0.000425565,
+  0.000420437,
+  0.000414464,
+  0.000407675,
+  0.000400108,
+  0.000391795,
+  0.000382774,
+  0.00037308,
+  0.000362751,
+  0.000351824,
+  0.000340339,
+  0.00032833,
+  0.000315839,
+  0.000302903,
+  0.000289559,
+  0.000275847,
+  0.000261806,
+  0.000247474,
+  0.000232892,
+  0.000218088,
+  0.000203111,
+  0.000187996,
+  0.000172781,
+  0.000157497,
+  0.000142183,
+  0.000126869,
+  0.000111594,
+  9.63895e-05,
+  8.12934e-05,
+  6.63317e-05,
+  5.15418e-05,
+  3.69472e-05,
+  2.25833e-05,
+  8.47105e-06,
+  -5.35615e-06,
+  -1.88794e-05,
+  -3.20661e-05,
+  -4.49012e-05,
+  -5.73536e-05,
+  -6.94109e-05,
+  -8.10442e-05,
+  -9.22439e-05,
+  -0.000102985,
+  -0.000113258,
+  -0.000123038,
+  -0.000132323,
+  -0.000141089,
+  -0.000149335,
+  -0.000157041,
+  -0.00016421,
+  -0.000170822,
+  -0.000176885,
+  -0.000182382,
+  -0.000187324,
+  -0.000191693,
+  -0.000195505,
+  -0.000198743,
+  -0.000201427,
+  -0.000203541,
+  -0.000205109,
+  -0.000206117,
+  -0.00020659,
+  -0.000206515,
+  -0.000205922,
+  -0.000204797,
+  -0.000203173,
+  -0.000201038,
+  -0.000198429,
+  -0.000195333,
+  -0.000191793,
+  -0.000187794,
+  -0.000183382,
+  -0.00017854,
+  -0.000173315,
+  -0.000167689,
+  -0.000161723,
+  -0.000155393,
+  -0.000148756,
+  -0.000141789,
+  -0.000134559,
+  -0.000127034,
+  -0.000119289,
+  -0.000111281,
+  -0.000103097,
+  -9.46835e-05,
+  -8.6137e-05,
+  -7.73902e-05,
+  -6.85565e-05,
+  -5.9545e-05,
+  -5.04935e-05,
+  -4.12734e-05,
+  -3.20611e-05,
+  -2.2664e-05,
+  -1.33229e-05,
+  -3.71244e-06,
+  5.78773e-06,
+  1.58964e-05,
+  2.58255e-05
+};
diff --git a/codec2/branches/0.7/src/rxdec_coeff.h b/codec2/branches/0.7/src/rxdec_coeff.h
new file mode 100644 (file)
index 0000000..a08cf9f
--- /dev/null
@@ -0,0 +1,35 @@
+/* Generated by rxdec_file() Octave function */
+
+const float rxdec_coeff[]={
+  -0.00125472,
+  -0.00204605,
+  -0.0019897,
+  0.000163906,
+  0.00490937,
+  0.00986375,
+  0.0096718,
+  -0.000480351,
+  -0.019311,
+  -0.0361822,
+  -0.0341251,
+  0.000827866,
+  0.0690577,
+  0.152812,
+  0.222115,
+  0.249004,
+  0.222115,
+  0.152812,
+  0.0690577,
+  0.000827866,
+  -0.0341251,
+  -0.0361822,
+  -0.019311,
+  -0.000480351,
+  0.0096718,
+  0.00986375,
+  0.00490937,
+  0.000163906,
+  -0.0019897,
+  -0.00204605,
+  -0.00125472
+};
diff --git a/codec2/branches/0.7/src/sim.sh b/codec2/branches/0.7/src/sim.sh
new file mode 100755 (executable)
index 0000000..10152d9
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/sh
+# sim.sh
+# David Rowe 10 Sep 2009
+
+# Process a source file using the codec 2 simulation.  An output
+# speech file is generated for each major processing step, from the
+# unquantised siusoidal model to fully quantised.  This way we can
+# listen to the effect of each processing step.  Use listensim.sh to
+# test the output files.
+
+../src/c2sim ../raw/$1.raw -o $1_uq.raw
+../src/c2sim ../raw/$1.raw --phase0 -o $1_phase0.raw --postfilter
+../src/c2sim ../raw/$1.raw --lpc 10 -o $1_lpc10.raw --postfilter
+../src/c2sim ../raw/$1.raw --phase0 --lpc 10 -o $1_phase0_lpc10.raw --postfilter
+../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --dec -o $1_phase0_lpc10_dec.raw --postfilter
+../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp --dec -o $1_phase0_lsp_dec.raw --postfilter
+
+#../src/c2sim ../raw/$1.raw --lpc 10 --lsp -o $1_lsp.raw
+#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 -o $1_phase0_lpc10.raw --postfilter
+#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp.raw --postfilter
+#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp_dec.raw --postfilter --dec
+
diff --git a/codec2/branches/0.7/src/sine.c b/codec2/branches/0.7/src/sine.c
new file mode 100644 (file)
index 0000000..72e3996
--- /dev/null
@@ -0,0 +1,687 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sine.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 19/8/2010
+
+  Sinusoidal analysis and synthesis functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 1990-2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*---------------------------------------------------------------------------*\
+
+                               INCLUDES
+
+\*---------------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "defines.h"
+#include "sine.h"
+#include "kiss_fft.h"
+
+#define HPF_BETA 0.125
+
+/*---------------------------------------------------------------------------*\
+
+                               HEADERS
+
+\*---------------------------------------------------------------------------*/
+
+void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax,
+                        float pstep);
+
+/*---------------------------------------------------------------------------*\
+
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+C2CONST c2const_create(int Fs) {
+    C2CONST c2const;
+
+    assert((Fs == 8000) || (Fs = 16000));
+    c2const.Fs = Fs;
+    c2const.n_samp = Fs*N_S;
+    c2const.max_amp = floor(Fs*P_MIN_S/2);
+    c2const.p_min = floor(Fs*P_MIN_S);
+    c2const.p_max = floor(Fs*P_MAX_S);
+    c2const.m_pitch = floor(Fs*M_PITCH_S);
+    c2const.Wo_min = TWO_PI/c2const.p_max;
+    c2const.Wo_max = TWO_PI/c2const.p_min;
+
+    if (Fs == 8000) {
+        c2const.nw = 279;
+    } else {
+        c2const.nw = 511;  /* actually a bit shorter in time but lets us maintain constant FFT size */
+    }
+
+    c2const.tw = Fs*TW_S;
+
+    fprintf(stderr, "max_amp: %d m_pitch: %d\n", c2const.n_samp, c2const.m_pitch);
+    fprintf(stderr, "p_min: %d p_max: %d\n", c2const.p_min, c2const.p_max);
+    fprintf(stderr, "Wo_min: %f Wo_max: %f\n", c2const.Wo_min, c2const.Wo_max);
+    fprintf(stderr, "nw: %d tw: %d\n", c2const.nw, c2const.tw);
+
+    return c2const;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: make_analysis_window
+  AUTHOR......: David Rowe
+  DATE CREATED: 11/5/94
+
+  Init function that generates the time domain analysis window and it's DFT.
+
+\*---------------------------------------------------------------------------*/
+
+void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[])
+{
+  float m;
+  COMP  wshift[FFT_ENC];
+  COMP  temp;
+  int   i,j;
+  int   m_pitch = c2const->m_pitch;
+  int   nw      = c2const->nw;
+
+  /*
+     Generate Hamming window centered on M-sample pitch analysis window
+
+  0            M/2           M-1
+  |-------------|-------------|
+        |-------|-------|
+            nw samples
+
+     All our analysis/synthsis is centred on the M/2 sample.
+  */
+
+  m = 0.0;
+  for(i=0; i<m_pitch/2-nw/2; i++)
+    w[i] = 0.0;
+  for(i=m_pitch/2-nw/2,j=0; i<m_pitch/2+nw/2; i++,j++) {
+    w[i] = 0.5 - 0.5*cosf(TWO_PI*j/(nw-1));
+    m += w[i]*w[i];
+  }
+  for(i=m_pitch/2+nw/2; i<m_pitch; i++)
+    w[i] = 0.0;
+
+  /* Normalise - makes freq domain amplitude estimation straight
+     forward */
+
+  m = 1.0/sqrtf(m*FFT_ENC);
+  for(i=0; i<m_pitch; i++) {
+    w[i] *= m;
+  }
+
+  /*
+     Generate DFT of analysis window, used for later processing.  Note
+     we modulo FFT_ENC shift the time domain window w[], this makes the
+     imaginary part of the DFT W[] equal to zero as the shifted w[] is
+     even about the n=0 time axis if nw is odd.  Having the imag part
+     of the DFT W[] makes computation easier.
+
+     0                      FFT_ENC-1
+     |-------------------------|
+
+      ----\               /----
+           \             /
+            \           /          <- shifted version of window w[n]
+             \         /
+              \       /
+               -------
+
+     |---------|     |---------|
+       nw/2              nw/2
+  */
+
+  for(i=0; i<FFT_ENC; i++) {
+    wshift[i].real = 0.0;
+    wshift[i].imag = 0.0;
+  }
+  for(i=0; i<nw/2; i++)
+    wshift[i].real = w[i+m_pitch/2];
+  for(i=FFT_ENC-nw/2,j=m_pitch/2-nw/2; i<FFT_ENC; i++,j++)
+   wshift[i].real = w[j];
+
+  codec2_fft(fft_fwd_cfg, wshift, W);
+
+  /*
+      Re-arrange W[] to be symmetrical about FFT_ENC/2.  Makes later
+      analysis convenient.
+
+   Before:
+
+
+     0                 FFT_ENC-1
+     |----------|---------|
+     __                   _
+       \                 /
+        \_______________/
+
+   After:
+
+     0                 FFT_ENC-1
+     |----------|---------|
+               ___
+              /   \
+     ________/     \_______
+
+  */
+
+
+  for(i=0; i<FFT_ENC/2; i++) {
+    temp.real = W[i].real;
+    temp.imag = W[i].imag;
+    W[i].real = W[i+FFT_ENC/2].real;
+    W[i].imag = W[i+FFT_ENC/2].imag;
+    W[i+FFT_ENC/2].real = temp.real;
+    W[i+FFT_ENC/2].imag = temp.imag;
+  }
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: hpf
+  AUTHOR......: David Rowe
+  DATE CREATED: 16 Nov 2010
+
+  High pass filter with a -3dB point of about 160Hz.
+
+    y(n) = -HPF_BETA*y(n-1) + x(n) - x(n-1)
+
+\*---------------------------------------------------------------------------*/
+
+float hpf(float x, float states[])
+{
+    states[0] = -HPF_BETA*states[0] + x - states[1];
+    states[1] = x;
+
+    return states[0];
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: dft_speech
+  AUTHOR......: David Rowe
+  DATE CREATED: 27/5/94
+
+  Finds the DFT of the current speech input speech frame.
+
+\*---------------------------------------------------------------------------*/
+
+// TODO: we can either go for a faster FFT using fftr and some stack usage
+// or we can reduce stack usage to almost zero on STM32 by switching to fft_inplace
+#if 1
+void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[])
+{
+    int  i;
+    int  m_pitch = c2const->m_pitch;
+    int   nw      = c2const->nw;
+
+    for(i=0; i<FFT_ENC; i++) {
+        Sw[i].real = 0.0;
+        Sw[i].imag = 0.0;
+    }
+
+    /* Centre analysis window on time axis, we need to arrange input
+       to FFT this way to make FFT phases correct */
+
+    /* move 2nd half to start of FFT input vector */
+
+    for(i=0; i<nw/2; i++)
+        Sw[i].real = Sn[i+m_pitch/2]*w[i+m_pitch/2];
+
+    /* move 1st half to end of FFT input vector */
+
+    for(i=0; i<nw/2; i++)
+        Sw[FFT_ENC-nw/2+i].real = Sn[i+m_pitch/2-nw/2]*w[i+m_pitch/2-nw/2];
+
+    codec2_fft_inplace(fft_fwd_cfg, Sw);
+}
+#else
+void dft_speech(codec2_fftr_cfg fftr_fwd_cfg, COMP Sw[], float Sn[], float w[])
+{
+    int  i;
+  float sw[FFT_ENC];
+
+  for(i=0; i<FFT_ENC; i++) {
+    sw[i] = 0.0;
+  }
+
+  /* Centre analysis window on time axis, we need to arrange input
+     to FFT this way to make FFT phases correct */
+
+  /* move 2nd half to start of FFT input vector */
+
+  for(i=0; i<nw/2; i++)
+    sw[i] = Sn[i+m_pitch/2]*w[i+m_pitch/2];
+
+  /* move 1st half to end of FFT input vector */
+
+  for(i=0; i<nw/2; i++)
+    sw[FFT_ENC-nw/2+i] = Sn[i+m_pitch/2-nw/2]*w[i+m_pitch/2-nw/2];
+
+  codec2_fftr(fftr_fwd_cfg, sw, Sw);
+}
+#endif
+
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: two_stage_pitch_refinement
+  AUTHOR......: David Rowe
+  DATE CREATED: 27/5/94
+
+  Refines the current pitch estimate using the harmonic sum pitch
+  estimation technique.
+
+\*---------------------------------------------------------------------------*/
+
+void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[])
+{
+  float pmin,pmax,pstep;       /* pitch refinment minimum, maximum and step */
+
+  /* Coarse refinement */
+
+  pmax = TWO_PI/model->Wo + 5;
+  pmin = TWO_PI/model->Wo - 5;
+  pstep = 1.0;
+  hs_pitch_refinement(model,Sw,pmin,pmax,pstep);
+
+  /* Fine refinement */
+
+  pmax = TWO_PI/model->Wo + 1;
+  pmin = TWO_PI/model->Wo - 1;
+  pstep = 0.25;
+  hs_pitch_refinement(model,Sw,pmin,pmax,pstep);
+
+  /* Limit range */
+
+  if (model->Wo < TWO_PI/c2const->p_max)
+    model->Wo = TWO_PI/c2const->p_max;
+  if (model->Wo > TWO_PI/c2const->p_min)
+    model->Wo = TWO_PI/c2const->p_min;
+
+  model->L = floorf(PI/model->Wo);
+
+  /* trap occasional round off issues with floorf() */
+  if (model->Wo*model->L >= PI) {
+      model->L--;
+  }
+  assert(model->Wo*model->L < PI);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: hs_pitch_refinement
+ AUTHOR......: David Rowe
+ DATE CREATED: 27/5/94
+
+ Harmonic sum pitch refinement function.
+
+ pmin   pitch search range minimum
+ pmax  pitch search range maximum
+ step   pitch search step size
+ model current pitch estimate in model.Wo
+
+ model         refined pitch estimate in model.Wo
+
+\*---------------------------------------------------------------------------*/
+
+void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float pstep)
+{
+  int m;               /* loop variable */
+  int b;               /* bin for current harmonic centre */
+  float E;             /* energy for current pitch*/
+  float Wo;            /* current "test" fundamental freq. */
+  float Wom;           /* Wo that maximises E */
+  float Em;            /* mamimum energy */
+  float r, one_on_r;   /* number of rads/bin */
+  float p;             /* current pitch */
+
+  /* Initialisation */
+
+  model->L = PI/model->Wo;     /* use initial pitch est. for L */
+  Wom = model->Wo;
+  Em = 0.0;
+  r = TWO_PI/FFT_ENC;
+  one_on_r = 1.0/r;
+
+  /* Determine harmonic sum for a range of Wo values */
+
+  for(p=pmin; p<=pmax; p+=pstep) {
+    E = 0.0;
+    Wo = TWO_PI/p;
+
+    /* Sum harmonic magnitudes */
+    for(m=1; m<=model->L; m++) {
+        b = (int)(m*Wo*one_on_r + 0.5);
+        E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag;
+    }
+    /* Compare to see if this is a maximum */
+
+    if (E > Em) {
+      Em = E;
+      Wom = Wo;
+    }
+  }
+
+  model->Wo = Wom;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: estimate_amplitudes
+  AUTHOR......: David Rowe
+  DATE CREATED: 27/5/94
+
+  Estimates the complex amplitudes of the harmonics.
+
+\*---------------------------------------------------------------------------*/
+
+void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase)
+{
+  int   i,m;           /* loop variables */
+  int   am,bm;         /* bounds of current harmonic */
+  int   b;             /* DFT bin of centre of current harmonic */
+  float den;           /* denominator of amplitude expression */
+  float r, one_on_r;   /* number of rads/bin */
+  int   offset;
+  COMP  Am;
+
+  r = TWO_PI/FFT_ENC;
+  one_on_r = 1.0/r;
+
+  for(m=1; m<=model->L; m++) {
+    den = 0.0;
+    am = (int)((m - 0.5)*model->Wo*one_on_r + 0.5);
+    bm = (int)((m + 0.5)*model->Wo*one_on_r + 0.5);
+    b = (int)(m*model->Wo/r + 0.5);
+
+    /* Estimate ampltude of harmonic */
+
+    den = 0.0;
+    Am.real = Am.imag = 0.0;
+    offset = FFT_ENC/2 - (int)(m*model->Wo*one_on_r + 0.5);
+    for(i=am; i<bm; i++) {
+      den += Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag;
+      Am.real += Sw[i].real*W[i + offset].real;
+      Am.imag += Sw[i].imag*W[i + offset].real;
+    }
+
+    model->A[m] = sqrtf(den);
+
+    if (est_phase) {
+
+        /* Estimate phase of harmonic, this is expensive in CPU for
+           embedded devicesso we make it an option */
+
+        model->phi[m] = atan2f(Sw[b].imag,Sw[b].real);
+    }
+  }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  est_voicing_mbe()
+
+  Returns the error of the MBE cost function for a fiven F0.
+
+  Note: I think a lot of the operations below can be simplified as
+  W[].imag = 0 and has been normalised such that den always equals 1.
+
+\*---------------------------------------------------------------------------*/
+
+float est_voicing_mbe(
+                      C2CONST *c2const,
+                      MODEL *model,
+                      COMP   Sw[],
+                      COMP   W[]
+                      )
+{
+    int   l,al,bl,m;    /* loop variables */
+    COMP  Am;             /* amplitude sample for this band */
+    int   offset;         /* centers Hw[] about current harmonic */
+    float den;            /* denominator of Am expression */
+    float error;          /* accumulated error between original and synthesised */
+    float Wo;
+    float sig, snr;
+    float elow, ehigh, eratio;
+    float sixty;
+    COMP   Ew;
+    Ew.real = 0;
+    Ew.imag = 0;
+
+    sig = 1E-4;
+    for(l=1; l<=model->L/4; l++) {
+       sig += model->A[l]*model->A[l];
+    }
+
+    Wo = model->Wo;
+    error = 1E-4;
+
+    /* Just test across the harmonics in the first 1000 Hz */
+
+    int l_1000hz = model->L*1000.0/(c2const->Fs/2);
+    for(l=1; l<=l_1000hz; l++) {
+       Am.real = 0.0;
+       Am.imag = 0.0;
+       den = 0.0;
+       al = ceilf((l - 0.5)*Wo*FFT_ENC/TWO_PI);
+       bl = ceilf((l + 0.5)*Wo*FFT_ENC/TWO_PI);
+
+       /* Estimate amplitude of harmonic assuming harmonic is totally voiced */
+
+        offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5;
+       for(m=al; m<bl; m++) {
+           Am.real += Sw[m].real*W[offset+m].real;
+           Am.imag += Sw[m].imag*W[offset+m].real;
+           den += W[offset+m].real*W[offset+m].real;
+        }
+
+        Am.real = Am.real/den;
+        Am.imag = Am.imag/den;
+
+        /* Determine error between estimated harmonic and original */
+
+        offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5;
+        for(m=al; m<bl; m++) {
+           Ew.real = Sw[m].real - Am.real*W[offset+m].real;
+           Ew.imag = Sw[m].imag - Am.imag*W[offset+m].real;
+           error += Ew.real*Ew.real;
+           error += Ew.imag*Ew.imag;
+       }
+    }
+
+    snr = 10.0*log10f(sig/error);
+    if (snr > V_THRESH)
+       model->voiced = 1;
+    else
+       model->voiced = 0;
+
+    /* post processing, helps clean up some voicing errors ------------------*/
+
+    /*
+       Determine the ratio of low freqency to high frequency energy,
+       voiced speech tends to be dominated by low frequency energy,
+       unvoiced by high frequency. This measure can be used to
+       determine if we have made any gross errors.
+    */
+
+    int l_2000hz = model->L*2000.0/(c2const->Fs/2);
+    int l_4000hz = model->L*4000.0/(c2const->Fs/2);
+    elow = ehigh = 1E-4;
+    for(l=1; l<=l_2000hz; l++) {
+       elow += model->A[l]*model->A[l];
+    }
+    for(l=l_2000hz; l<=l_4000hz; l++) {
+       ehigh += model->A[l]*model->A[l];
+    }
+    eratio = 10.0*log10f(elow/ehigh);
+
+    /* Look for Type 1 errors, strongly V speech that has been
+       accidentally declared UV */
+
+    if (model->voiced == 0)
+       if (eratio > 10.0)
+           model->voiced = 1;
+
+    /* Look for Type 2 errors, strongly UV speech that has been
+       accidentally declared V */
+
+    if (model->voiced == 1) {
+       if (eratio < -10.0)
+           model->voiced = 0;
+
+       /* A common source of Type 2 errors is the pitch estimator
+          gives a low (50Hz) estimate for UV speech, which gives a
+          good match with noise due to the close harmoonic spacing.
+          These errors are much more common than people with 50Hz3
+          pitch, so we have just a small eratio threshold. */
+
+       sixty = 60.0*TWO_PI/c2const->Fs;
+       if ((eratio < -4.0) && (model->Wo <= sixty))
+           model->voiced = 0;
+    }
+    //printf(" v: %d snr: %f eratio: %3.2f %f\n",model->voiced,snr,eratio,dF0);
+
+    return snr;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: make_synthesis_window
+  AUTHOR......: David Rowe
+  DATE CREATED: 11/5/94
+
+  Init function that generates the trapezoidal (Parzen) sythesis window.
+
+\*---------------------------------------------------------------------------*/
+
+void make_synthesis_window(C2CONST *c2const, float Pn[])
+{
+  int   i;
+  float win;
+  int   n_samp = c2const->n_samp;
+  int   tw     = c2const->tw;
+
+  /* Generate Parzen window in time domain */
+
+  win = 0.0;
+  for(i=0; i<n_samp/2-tw; i++)
+    Pn[i] = 0.0;
+  win = 0.0;
+  for(i=n_samp/2-tw; i<n_samp/2+tw; win+=1.0/(2*tw), i++ )
+    Pn[i] = win;
+  for(i=n_samp/2+tw; i<3*n_samp/2-tw; i++)
+    Pn[i] = 1.0;
+  win = 1.0;
+  for(i=3*n_samp/2-tw; i<3*n_samp/2+tw; win-=1.0/(2*tw), i++)
+    Pn[i] = win;
+  for(i=3*n_samp/2+tw; i<2*n_samp; i++)
+    Pn[i] = 0.0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: synthesise
+  AUTHOR......: David Rowe
+  DATE CREATED: 20/2/95
+
+  Synthesise a speech signal in the frequency domain from the
+  sinusodal model parameters.  Uses overlap-add with a trapezoidal
+  window to smoothly interpolate betwen frames.
+
+\*---------------------------------------------------------------------------*/
+
+void synthesise(
+  int    n_samp,
+  codec2_fftr_cfg fftr_inv_cfg,
+  float  Sn_[],                /* time domain synthesised signal              */
+  MODEL *model,                /* ptr to model parameters for this frame      */
+  float  Pn[],         /* time domain Parzen window                   */
+  int    shift          /* flag used to handle transition frames       */
+)
+{
+    int   i,l,j,b;             /* loop variables */
+    COMP  Sw_[FFT_DEC/2+1];    /* DFT of synthesised signal */
+    float sw_[FFT_DEC];                /* synthesised signal */
+
+    if (shift) {
+       /* Update memories */
+       for(i=0; i<n_samp-1; i++) {
+           Sn_[i] = Sn_[i+n_samp];
+       }
+       Sn_[n_samp-1] = 0.0;
+    }
+
+    for(i=0; i<FFT_DEC/2+1; i++) {
+       Sw_[i].real = 0.0;
+       Sw_[i].imag = 0.0;
+    }
+
+    /* Now set up frequency domain synthesised speech */
+
+    for(l=1; l<=model->L; l++) {
+        b = (int)(l*model->Wo*FFT_DEC/TWO_PI + 0.5);
+        if (b > ((FFT_DEC/2)-1)) {
+            b = (FFT_DEC/2)-1;
+        }
+        Sw_[b].real = model->A[l]*cosf(model->phi[l]);
+        Sw_[b].imag = model->A[l]*sinf(model->phi[l]);
+    }
+
+    /* Perform inverse DFT */
+
+    codec2_fftri(fftr_inv_cfg, Sw_,sw_);
+
+    /* Overlap add to previous samples */
+
+    #ifdef USE_KISS_FFT
+    #define    FFTI_FACTOR ((float)1.0)
+    #else
+    #define    FFTI_FACTOR ((float32_t)FFT_DEC)
+    #endif
+
+    for(i=0; i<n_samp-1; i++) {
+        Sn_[i] += sw_[FFT_DEC-n_samp+1+i]*Pn[i] * FFTI_FACTOR;
+    }
+
+    if (shift)
+        for(i=n_samp-1,j=0; i<2*n_samp; i++,j++)
+            Sn_[i] = sw_[j]*Pn[i] * FFTI_FACTOR;
+    else
+        for(i=n_samp-1,j=0; i<2*n_samp; i++,j++)
+            Sn_[i] += sw_[j]*Pn[i] * FFTI_FACTOR;
+}
+
+
+/* todo: this should probably be in some states rather than a static */
+static unsigned long next = 1;
+
+int codec2_rand(void) {
+    next = next * 1103515245 + 12345;
+    return((unsigned)(next/65536) % 32768);
+}
+
diff --git a/codec2/branches/0.7/src/sine.h b/codec2/branches/0.7/src/sine.h
new file mode 100644 (file)
index 0000000..774f020
--- /dev/null
@@ -0,0 +1,49 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sine.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 1/11/94
+
+  Header file for sinusoidal analysis and synthesis functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SINE__
+#define __SINE__
+
+#include "defines.h"
+#include "comp.h"
+#include "codec2_fft.h"
+
+C2CONST c2const_create(int Fs);
+
+void make_analysis_window(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, float w[], COMP W[]);
+float hpf(float x, float states[]);
+void dft_speech(C2CONST *c2const, codec2_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]);
+void two_stage_pitch_refinement(C2CONST *c2const, MODEL *model, COMP Sw[]);
+void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase);
+float est_voicing_mbe(C2CONST *c2const, MODEL *model, COMP Sw[], COMP W[]);
+void make_synthesis_window(C2CONST *c2const, float Pn[]);
+void synthesise(int n_samp, codec2_fftr_cfg fftr_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift);
+
+#define CODEC2_RAND_MAX 32767
+int codec2_rand(void);
+
+#endif
diff --git a/codec2/branches/0.7/src/ssbfilt_coeff.h b/codec2/branches/0.7/src/ssbfilt_coeff.h
new file mode 100644 (file)
index 0000000..457f03a
--- /dev/null
@@ -0,0 +1,107 @@
+/* 600 - 2600 Hz FIR filter coeffs */
+/* Generated by make_ssbfilt Octave script */
+
+#define SSBFILT_N 100
+
+float ssbfilt_coeff[]={
+  0.000065,
+  -0.000030,
+  0.000041,
+  0.000010,
+  -0.000128,
+  -0.000072,
+  -0.000007,
+  -0.000095,
+  -0.000063,
+  0.000016,
+  -0.000000,
+  0.000022,
+  -0.000115,
+  -0.000233,
+  -0.000023,
+  -0.000315,
+  -0.000725,
+  0.000073,
+  0.000380,
+  -0.000345,
+  0.000895,
+  0.002401,
+  0.001241,
+  0.001409,
+  0.003106,
+  0.001236,
+  -0.001117,
+  -0.001091,
+  -0.003184,
+  -0.005981,
+  -0.006904,
+  -0.007920,
+  -0.005588,
+  -0.002546,
+  -0.003476,
+  0.005155,
+  0.017465,
+  0.010772,
+  0.013033,
+  0.035082,
+  0.018466,
+  -0.010261,
+  0.016676,
+  0.004890,
+  -0.076807,
+  -0.055969,
+  -0.007360,
+  -0.155769,
+  -0.203150,
+  0.179458,
+  0.475523,
+  0.179458,
+  -0.203150,
+  -0.155769,
+  -0.007360,
+  -0.055969,
+  -0.076807,
+  0.004890,
+  0.016676,
+  -0.010261,
+  0.018466,
+  0.035082,
+  0.013033,
+  0.010772,
+  0.017465,
+  0.005155,
+  -0.003476,
+  -0.002546,
+  -0.005588,
+  -0.007920,
+  -0.006904,
+  -0.005981,
+  -0.003184,
+  -0.001091,
+  -0.001117,
+  0.001236,
+  0.003106,
+  0.001409,
+  0.001241,
+  0.002401,
+  0.000895,
+  -0.000345,
+  0.000380,
+  0.000073,
+  -0.000725,
+  -0.000315,
+  -0.000023,
+  -0.000233,
+  -0.000115,
+  0.000022,
+  -0.000000,
+  0.000016,
+  -0.000063,
+  -0.000095,
+  -0.000007,
+  -0.000072,
+  -0.000128,
+  0.000010,
+  0.000041,
+  -0.000030
+};
\ No newline at end of file
diff --git a/codec2/branches/0.7/src/tdma.h b/codec2/branches/0.7/src/tdma.h
new file mode 100644 (file)
index 0000000..96e837c
--- /dev/null
@@ -0,0 +1,85 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tdma.h
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 18 September 2016
+
+  Skeletion of the API for the TDMA FSK modem
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 Brady O'Brien
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __CODEC_2_TDMA_H
+#define __CODEC_2_TDMA_H
+
+#include "fsk.h"
+#include "freedv_vhf_framing.h"
+
+//typedef void (*tdma_cb_rx_frame)()
+
+/* The state for an individual slot */
+enum slot_state {
+    rx_no_sync,         /* Not synched */
+    rx_sync,            /* Sunk */
+    tx_client,          /* TX but timed from a different master */
+    tx_master           /* TX in master mode */
+};
+
+/* The state of the entire TDMA modem */
+enum tdma_state {
+    no_sync,            /* No sync */
+    pilot_sync,         /* Pilot modem has gotten sync, but slots haven't*/
+    slot_sync,          /* One or more slots are sunk */
+    master_sync,        /* This modem is the TDMA master */
+};
+
+/* TDMA frame type */
+enum tdma_frame_type{
+    frame_master,
+    frame_client,
+};
+
+/* TDMA frame struct */
+struct TDMA_FRAME {
+    enum tdma_frame_type type;      /* Type of frame */
+    int slot_idx;                   /* Index of slot from where frame was rx-ed */
+    uint8_t frame_payload[];        /* Frame payload. TODO: figure out how to sling payloads around */
+};
+
+/* TDMA slot struct */
+
+struct TDMA_SLOT {
+    struct FSK * fsk;               /* The FSK modem for this slot */
+    enum slot_state state;          /* Current local slot state */
+    int slot_local_frame_offset;    /* Where the RX frame starts, in samples, from the perspective of the modem */
+    struct TDMA_SLOT * next_slot;   /* Next slot in a linked list of slots */
+
+};
+
+/* TDMA modem */
+struct TDMA_MODEM {
+    struct FSK * fsk_pilot;         /* Pilot modem */
+    enum tdma_state state;          /* Current state of modem */
+    struct TDMA_SLOT * slots;       /* Linked list of slot structs */
+
+    int total_slot_count;
+
+};
+
+#endif
diff --git a/codec2/branches/0.7/src/test_bits.h b/codec2/branches/0.7/src/test_bits.h
new file mode 100644 (file)
index 0000000..d1c01a0
--- /dev/null
@@ -0,0 +1,164 @@
+/* Generated by test_bits_file() Octave function */
+
+const int test_bits[]={
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1
+};
diff --git a/codec2/branches/0.7/src/test_bits_coh.h b/codec2/branches/0.7/src/test_bits_coh.h
new file mode 100644 (file)
index 0000000..b01299c
--- /dev/null
@@ -0,0 +1,564 @@
+/* Generated by test_bits_coh_file() Octave function */
+
+const int test_bits_coh[]={
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  0,
+  0,
+  0,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  0,
+  1,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  0,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  0,
+  0,
+  0,
+  0,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  0,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  1,
+  0,
+  0,
+  1,
+  1,
+  1,
+  0
+};
diff --git a/codec2/branches/0.7/src/test_bits_ofdm.h b/codec2/branches/0.7/src/test_bits_ofdm.h
new file mode 100644 (file)
index 0000000..00fdd99
--- /dev/null
@@ -0,0 +1,229 @@
+/* Generated by test_bits_ofdm_file() Octave function */
+
+const int test_bits_ofdm[]={
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 0,
+ 1,
+ 0,
+ 0,
+ 1,
+ 1,
+ 0,
+ 1,
+ 1,
+ 0,
+ 0,
+ 0,
+ 1
+};
+
diff --git a/codec2/branches/0.7/src/varicode.c b/codec2/branches/0.7/src/varicode.c
new file mode 100644 (file)
index 0000000..7d0ec1a
--- /dev/null
@@ -0,0 +1,486 @@
+//==========================================================================
+// Name:            varicode.h
+// Purpose:         Varicode encoded and decode functions
+// Created:         Nov 24, 2012
+// Authors:         David Rowe
+//
+// To test:
+//          $ gcc varicode.c -o varicode -DVARICODE_UNITTEST -Wall
+//          $ ./varicode
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "varicode.h"
+#include "varicode_table.h"
+
+
+/*
+  output is an unpacked array of bits of maximum size max_out.  Note
+  unpacked arrays are a more suitable form for modulator input.
+
+  Code 1 covers the entire ASCII char set.
+*/
+
+int varicode_encode1(short varicode_out[], char ascii_in[], int max_out, int n_in) {
+    int            n_out, index, n_zeros, v_len;
+    unsigned short byte1, byte2, packed;
+
+    n_out = 0;
+
+    while(n_in && (n_out < max_out)) {
+
+        assert((unsigned int)(*ascii_in) < 128);
+
+        index = 2*(unsigned int)(*ascii_in);
+        byte1 = varicode_table1[index];
+        byte2 = varicode_table1[index+1];
+        packed = (byte1 << 8) + byte2;
+
+        //printf("n_in: %d ascii_in: %c index: %d packed 0x%x\n", n_in, *ascii_in, index, packed);
+        ascii_in++;
+
+        n_zeros = 0;
+        v_len = 0;
+        while ((n_zeros < 2) && (n_out < max_out) && (v_len <= VARICODE_MAX_BITS)) {
+            if (packed & 0x8000) {
+                *varicode_out = 1;
+                n_zeros = 0;
+            }
+            else {
+                *varicode_out = 0;
+                n_zeros++;
+            }
+            //printf("packed: 0x%x *varicode_out: %d n_zeros: %d v_len: %d\n", packed, *varicode_out, n_zeros,v_len );
+            packed <<= 1;
+            varicode_out++;
+            n_out++;
+            v_len++;
+        }
+        assert(v_len <= VARICODE_MAX_BITS);
+
+        n_in--;
+    }
+
+    return n_out;
+}
+
+
+/*
+  Code 2 covers a subset, but is more efficient that Code 1 (282
+  compared to 1315 bits on unittest) Unsupported characters are
+  replaced by spaces.  We encode/decode two bits at a time.
+*/
+
+int varicode_encode2(short varicode_out[], char ascii_in[], int max_out, int n_in) {
+    int            n_out, n_zeros, v_len, i;
+    unsigned short packed;
+
+    n_out = 0;
+
+    while(n_in && (n_out < max_out)) {
+
+        packed = varicode_table2[0]; // default to space if char not found
+
+        // see if our character exists
+        for(i=0; i<sizeof(varicode_table2); i+=2) {
+            if (varicode_table2[i] == *ascii_in)
+                packed = (unsigned short)varicode_table2[i+1] << 8;
+        }
+
+        //printf("n_in: %d ascii_in: %c index: %d packed 0x%x\n", n_in, *ascii_in, index, packed);
+        ascii_in++;
+
+        n_zeros = 0;
+        v_len = 0;
+        while ((n_zeros < 2) && (n_out < max_out) && (v_len <= VARICODE_MAX_BITS)) {
+            if (packed & 0x8000)
+                varicode_out[0] = 1;
+            else
+                varicode_out[0] = 0;
+
+            if (packed & 0x4000)
+                varicode_out[1] = 1;
+            else
+                varicode_out[1] = 0;
+
+            if (packed & 0xc000)
+                n_zeros = 0;
+            else
+                n_zeros += 2;
+
+            //printf("packed: 0x%x *varicode_out: %d n_zeros: %d v_len: %d\n", packed, *varicode_out, n_zeros,v_len );
+            packed <<= 2;
+            varicode_out +=2;
+            n_out += 2;
+            v_len += 2;
+        }
+        assert(v_len <= VARICODE_MAX_BITS);
+
+        n_in--;
+    }
+
+    assert((n_out % 2) == 0);  /* outputs two bits at a time */
+
+    return n_out;
+}
+
+
+int varicode_encode(short varicode_out[], char ascii_in[], int max_out, int n_in, int code_num) {
+
+    assert((code_num ==1) || (code_num ==2));
+
+    if (code_num == 1)
+        return varicode_encode1(varicode_out, ascii_in, max_out, n_in);
+    else
+       return  varicode_encode2(varicode_out, ascii_in, max_out, n_in);
+}
+
+
+void varicode_decode_init(struct VARICODE_DEC *dec_states, int code_num)
+{
+    assert((code_num ==1) || (code_num == 2));
+
+    dec_states->state = 0;
+    dec_states->n_zeros = 0;
+    dec_states->v_len = 0;
+    dec_states->packed = 0;
+    dec_states->code_num = code_num;
+    dec_states->n_in = 0;
+    dec_states->in[0] = dec_states->in[1] = 0;
+}
+
+
+void varicode_set_code_num(struct VARICODE_DEC *dec_states, int code_num)
+{
+    assert((code_num == 1) || (code_num == 2));
+    dec_states->code_num = code_num;
+}
+
+
+/* Code 1 decode function, accepts one bit at a time */
+
+static int decode_one_bit(struct VARICODE_DEC *s, char *single_ascii, short varicode_in, int long_code)
+{
+    int            found=0, i;
+    unsigned short byte1, byte2;
+
+    //printf("decode_one_bit : state: %d varicode_in: %d packed: 0x%x n_zeros: %d\n",
+    //       s->state, varicode_in, s->packed, s->n_zeros);
+
+    if (s->state == 0) {
+        if (!varicode_in)
+            return 0;
+        else
+            s->state = 1;
+    }
+
+    if (s->state == 1) {
+        if (varicode_in) {
+            s->packed |= (0x8000 >> s->v_len);
+            s->n_zeros = 0;
+        }
+        else {
+            s->n_zeros++;
+        }
+        s->v_len++;
+        found = 0;
+
+        /* end of character code */
+
+        if (s->n_zeros == 2) {
+            if (s->v_len) {
+                /* run thru table but note with bit errors we might not actually find a match */
+
+                byte1 = s->packed >> 8;
+                //printf("looking for byte1 : 0x%x ... ", byte1);
+                byte2 = s->packed & 0xff;
+
+                for(i=0; i<128; i++) {
+                    if ((byte1 == varicode_table1[2*i]) && (byte2 == varicode_table1[2*i+1])) {
+                        found = 1;
+                        *single_ascii = i;
+                    }
+                }
+            }
+            varicode_decode_init(s, s->code_num);
+        }
+
+        /* code can run too long if we have a bit error */
+
+        if (s->v_len > VARICODE_MAX_BITS)
+            varicode_decode_init(s, s->code_num);
+    }
+
+    return found;
+}
+
+
+/* Code 2 decode function, accepts two bits at a time */
+
+static int decode_two_bits(struct VARICODE_DEC *s, char *single_ascii, short varicode_in1, short varicode_in2)
+{
+    int            found=0, i;
+    unsigned short byte1;
+
+    if (s->state == 0) {
+        if (!(varicode_in1 || varicode_in2))
+            return 0;
+        else
+            s->state = 1;
+    }
+
+    if (s->state == 1) {
+        if (varicode_in1)
+            s->packed |= (0x8000 >> s->v_len);
+        if (varicode_in2)
+            s->packed |= (0x4000 >> s->v_len);
+        if (varicode_in1 || varicode_in2)
+            s->n_zeros = 0;
+        else
+            s->n_zeros+=2;
+
+        s->v_len+=2;
+
+        found = 0;
+
+        /* end of character code */
+
+        if (s->n_zeros == 2) {
+            if (s->v_len) {
+                /* run thru table but note with bit errors we might not actually find a match */
+
+                byte1 = s->packed >> 8;
+                //printf("looking for byte1 : 0x%x ... ", byte1);
+                for(i=0; i<sizeof(varicode_table2); i+=2) {
+                    //printf("byte1: 0x%x 0x%x\n", byte1, (unsigned char)varicode_table2[i+1]);
+                    if (byte1 == (unsigned char)varicode_table2[i+1]) {
+                        found = 1;
+                        *single_ascii = varicode_table2[i];
+                        //printf("found: %d i=%d char=%c ", found, i, *single_ascii);
+                    }
+                }
+            }
+            varicode_decode_init(s, s->code_num);
+        }
+
+        /* code can run too long if we have a bit error */
+
+        if (s->v_len > VARICODE_MAX_BITS)
+            varicode_decode_init(s, s->code_num);
+    }
+
+    return found;
+}
+
+
+int varicode_decode1(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in) {
+    int            output, n_out;
+    char           single_ascii = 0;
+
+    n_out = 0;
+
+    //printf("varicode_decode: n_in: %d\n", n_in);
+
+    while(n_in && (n_out < max_out)) {
+        output = decode_one_bit(dec_states, &single_ascii, varicode_in[0], 0);
+        varicode_in++;
+        n_in--;
+
+        if (output) {
+            *ascii_out++ = single_ascii;
+            n_out++;
+        }
+    }
+
+    return n_out;
+}
+
+
+int varicode_decode2(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in) {
+    int            output, n_out;
+    char           single_ascii = 0;
+
+    n_out = 0;
+
+    //printf("varicode_decode2: n_in: %d varicode_in[0] %d dec_states->n_in: %d\n", n_in, varicode_in[0], dec_states->n_in);
+    //printf("%d ", varicode_in[0]);
+    while(n_in && (n_out < max_out)) {
+
+        // keep two bit buffer so we can process two at a time
+
+        dec_states->in[0] = dec_states->in[1];
+        dec_states->in[1] = varicode_in[0];
+        dec_states->n_in++;
+        varicode_in++;
+        n_in--;
+
+        if (dec_states->n_in == 2) {
+            output = decode_two_bits(dec_states, &single_ascii, dec_states->in[0], dec_states->in[1]);
+
+            dec_states->n_in = 0;
+
+            if (output) {
+                //printf("  output: %d single_ascii: 0x%x %c\n", output, (int)single_ascii, single_ascii);
+                *ascii_out++ = single_ascii;
+                n_out++;
+            }
+        }
+    }
+
+    return n_out;
+}
+
+
+int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in) {
+    if (dec_states->code_num == 1)
+        return varicode_decode1(dec_states, ascii_out, varicode_in, max_out, n_in);
+    else
+        return varicode_decode2(dec_states, ascii_out, varicode_in, max_out, n_in);
+}
+
+
+#ifdef VARICODE_UNITTEST
+void test_varicode(int code_num) {
+    char *ascii_in;
+    short *varicode;
+    int  i, n_varicode_bits_out, n_ascii_chars_out, length, half, n_out, j, len;
+    char *ascii_out;
+    struct VARICODE_DEC dec_states;
+
+    if (code_num == 1) {
+        printf("long code:\n");
+        length = sizeof(varicode_table1)/2;
+    }
+    else {
+        printf("short code:\n");
+        length = sizeof(varicode_table2)/2;
+    }
+    //length = 10;
+    ascii_in = (char*)malloc(length);
+    varicode = (short*)malloc(VARICODE_MAX_BITS*sizeof(short)*length);
+    ascii_out = (char*)malloc(length);
+
+    // 1. test all Varicode codes -------------------------------------------------------------
+
+    if (code_num == 1) {
+        for(i=0; i<length; i++)
+            ascii_in[i] = (char)i;
+    }
+    else {
+        for(i=0; i<length; i++)
+            ascii_in[i] = varicode_table2[2*i];
+    }
+    //printf("  ascii_in: %s\n", ascii_in);
+    n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*length, length, code_num);
+
+    printf("  n_varicode_bits_out: %d\n", n_varicode_bits_out);
+    //for(i=0; i<n_varicode_bits_out; i++) {
+    //    printf("%d \n", varicode[i]);
+    //}
+
+    // split decode in half to test how it preserves state between calls
+
+    varicode_decode_init(&dec_states, code_num);
+    half = n_varicode_bits_out/2;
+    n_ascii_chars_out  = varicode_decode(&dec_states, ascii_out, varicode, length, half);
+    // printf("  n_ascii_chars_out: %d\n", n_ascii_chars_out);
+
+    n_ascii_chars_out += varicode_decode(&dec_states, &ascii_out[n_ascii_chars_out],
+                                         &varicode[half], length-n_ascii_chars_out, n_varicode_bits_out - half);
+    assert(n_ascii_chars_out == length);
+
+    printf("  n_ascii_chars_out: %d\n", n_ascii_chars_out);
+    printf("  average bits/character: %3.2f\n", (float)n_varicode_bits_out/n_ascii_chars_out);
+
+    //printf("ascii_out: %s\n", ascii_out);
+
+    if (memcmp(ascii_in, ascii_out, length) == 0)
+        printf("  Test 1 Pass\n");
+    else
+        printf("  Test 1 Fail\n");
+
+    // 2. Test some ascii with a run of zeros -----------------------------------------------------
+
+    sprintf(ascii_in, "CQ CQ CQ this is VK5DGR");
+
+    assert(strlen(ascii_in) < length);
+    if (code_num == 2)
+        for(i=0; i<strlen(ascii_in); i++)
+            ascii_in[i] = tolower(ascii_in[i]);
+
+    for(i=0; i<3; i++) {
+        n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*length, strlen(ascii_in), code_num);
+        n_ascii_chars_out   = varicode_decode(&dec_states, ascii_out, varicode, length, n_varicode_bits_out);
+        ascii_out[n_ascii_chars_out] = 0;
+
+        printf("  ascii_out: %s\n", ascii_out);
+        if (strcmp(ascii_in, ascii_out) == 0)
+            printf("  Test 2 Pass\n");
+        else
+            printf("  Test 2 Fail\n");
+
+        memset(varicode, 0, sizeof(short)*20);
+        n_ascii_chars_out = varicode_decode(&dec_states, ascii_out, varicode, length, 20);
+        assert(n_ascii_chars_out == 0);
+    }
+
+    // 3. Test receiving one bit at a time -----------------------------------------------------
+
+    sprintf(ascii_in, "s=vk5dgr qth=adelaide");
+    len = strlen(ascii_in);
+    ascii_in[len] = 13;
+    ascii_in[len+1] = 0;
+
+    assert(strlen(ascii_in) < length);
+    if (code_num == 2)
+        for(i=0; i<strlen(ascii_in); i++)
+            ascii_in[i] = tolower(ascii_in[i]);
+
+    for(i=0; i<3; i++) {
+        n_varicode_bits_out = varicode_encode(varicode, ascii_in, VARICODE_MAX_BITS*length, strlen(ascii_in), code_num);
+        printf("n_varicode_bits_out: %d\n", n_varicode_bits_out);
+
+        n_ascii_chars_out = 0;
+        for(j=0; j<n_varicode_bits_out; j++) {
+            n_out = varicode_decode(&dec_states, &ascii_out[n_ascii_chars_out], &varicode[j], 1, 1);
+            if (n_out)
+                n_ascii_chars_out++;
+        }
+        ascii_out[n_ascii_chars_out] = 0;
+
+        printf("  ascii_out: %s\n", ascii_out);
+        if (strcmp(ascii_in, ascii_out) == 0)
+            printf("  Test 3 Pass\n");
+        else
+            printf("  Test 3 Fail\n");
+    }
+
+    free(ascii_in);
+    free(ascii_out);
+    free(varicode);
+}
+
+int main(void) {
+    test_varicode(1);
+    test_varicode(2);
+    return 0;
+}
+#endif
diff --git a/codec2/branches/0.7/src/varicode.h b/codec2/branches/0.7/src/varicode.h
new file mode 100644 (file)
index 0000000..d9fb441
--- /dev/null
@@ -0,0 +1,52 @@
+//==========================================================================
+// Name:            varicode.h
+// Purpose:         Varicode encoded and decode functions
+// Created:         Nov 24, 2012
+// Authors:         David Rowe
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __VARICODE__
+#define __VARICODE__
+
+#ifdef __cplusplus
+extern "C" {
+
+#endif
+
+#define VARICODE_MAX_BITS (10+2) /* max varicode bits for each ascii character */
+                                 /* 10 bits for code plus 2 0 bits for inter-character space */
+
+struct VARICODE_DEC {
+    int            state;
+    int            n_zeros;
+    int            v_len;
+    unsigned short packed;
+    int            code_num;
+    int            n_in;
+    int            in[2];
+};
+
+int varicode_encode(short varicode_out[], char ascii_in[], int max_out, int n_in, int code_num);
+void varicode_decode_init(struct VARICODE_DEC *dec_states, int code_num);
+int varicode_decode(struct VARICODE_DEC *dec_states, char ascii_out[], short varicode_in[], int max_out, int n_in);
+void varicode_set_code_num(struct VARICODE_DEC *dec_states, int code_num);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/src/varicode_table.h b/codec2/branches/0.7/src/varicode_table.h
new file mode 100644 (file)
index 0000000..2d22adc
--- /dev/null
@@ -0,0 +1,338 @@
+//==========================================================================
+// Name:            varicode_table.h
+// Purpose:         Varicode look up table
+// Created:         Nov 24, 2012
+// Authors:         Clint Turner, KA7OEI,  Peter Martinez, G3PLX
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+/* The following table defines the PKS31 varicode.  There are 128 entries,
+corresponding to ASCII characters 0-127 with two bytes for each entry.  The bits
+for the varicode are to be shifted out MSB-first for both bytes, with the first byte
+in the table being the first one to be sent.
+
+More than one zero in sequence signifies the end of the character (i.e.
+two zeroes are the intercharacter sequence, so at least two zeroes should always be
+sent before the next character is sent.
+
+This file is constructed with information from the article "PSK31 Fundamentals"
+by Peter Martinez, G3PLX by Clint Turner, KA7OEI
+*/
+unsigned char const varicode_table1[256] =     {
+    0b10101010,
+    0b11000000, // 0 NUL
+    0b10110110,
+    0b11000000, // 1 SOH
+    0b10111011,
+    0b01000000, // 2 STX
+    0b11011101,
+    0b11000000, // 3 ETX
+    0b10111010,
+    0b11000000, // 4 EOT
+    0b11010111,
+    0b11000000, // 5 ENQ
+    0b10111011,
+    0b11000000, // 6 ACK
+    0b10111111,
+    0b01000000, // 7 BEL
+    0b10111111,
+    0b11000000, // 8 BS
+    0b11101111,
+    0b00000000, // 9 HT
+    0b11101000,
+    0b00000000, // 10 LF
+    0b11011011,
+    0b11000000, // 11 VT
+    0b10110111,
+    0b01000000, // 12 FF
+    0b11111000,
+    0b00000000, // 13 CR
+    0b11011101,
+    0b01000000, // 14 SO
+    0b11101010,
+    0b11000000, // 15 SI
+    0b10111101,
+    0b11000000, // 16 DLE
+    0b10111101,
+    0b01000000, // 17 DC1
+    0b11101011,
+    0b01000000, // 18 DC2
+    0b11101011,
+    0b11000000, // 19 DC3
+    0b11010110,
+    0b11000000, // 20 DC4
+    0b11011010,
+    0b11000000, // 21 NAK
+    0b11011011,
+    0b01000000, // 22 SYN
+    0b11010101,
+    0b11000000, // 23 ETB
+    0b11011110,
+    0b11000000, // 24 CAN
+    0b11011111,
+    0b01000000, // 25 EM
+    0b11101101,
+    0b11000000, // 26 SUB
+    0b11010101,
+    0b01000000, // 27 ESC
+    0b11010111,
+    0b01000000, // 28 FS
+    0b11101110,
+    0b11000000, // 29 GS
+    0b10111110,
+    0b11000000, // 30 RS
+    0b11011111,
+    0b11000000, // 31 US
+    0b10000000,
+    0b00000000, // 32 SP
+    0b11111111,
+    0b10000000, // 33 !
+    0b10101111,
+    0b10000000, // 34 "
+    0b11111010,
+    0b10000000, // 35 #
+    0b11101101,
+    0b10000000, // 36 $
+    0b10110101,
+    0b01000000, // 37 %
+    0b10101110,
+    0b11000000, // 38 &
+    0b10111111,
+    0b10000000, // 39 '
+    0b11111011,
+    0b00000000, // 40 (
+    0b11110111,
+    0b00000000, // 41 )
+    0b10110111,
+    0b10000000, // 42 *
+    0b11101111,
+    0b10000000, // 43 +
+    0b11101010,
+    0b00000000, // 44 ,
+    0b11010100,
+    0b00000000, // 45 -
+    0b10101110,
+    0b00000000, // 46 .
+    0b11010111,
+    0b10000000, // 47 /
+    0b10110111,
+    0b00000000, // 48 0
+    0b10111101,
+    0b00000000, // 49 1
+    0b11101101,
+    0b00000000, // 50 2
+    0b11111111,
+    0b00000000, // 51 3
+    0b10111011,
+    0b10000000, // 52 4
+    0b10101101,
+    0b10000000, // 53 5
+    0b10110101,
+    0b10000000, // 54 6
+    0b11010110,
+    0b10000000, // 55 7
+    0b11010101,
+    0b10000000, // 56 8
+    0b11011011,
+    0b10000000, // 57 9
+    0b11110101,
+    0b00000000, // 58 :
+    0b11011110,
+    0b10000000, // 59 ;
+    0b11110110,
+    0b10000000, // 60 <
+    0b10101010,
+    0b00000000, // 61 =
+    0b11101011,
+    0b10000000, // 62 >
+    0b10101011,
+    0b11000000, // 63 ?
+    0b10101111,
+    0b01000000, // 64 @
+    0b11111010,
+    0b00000000, // 65 A
+    0b11101011,
+    0b00000000, // 66 B
+    0b10101101,
+    0b00000000, // 67 C
+    0b10110101,
+    0b00000000, // 68 D
+    0b11101110,
+    0b00000000, // 69 E
+    0b11011011,
+    0b00000000, // 70 F
+    0b11111101,
+    0b00000000, // 71 G
+    0b10101010,
+    0b10000000, // 72 H
+    0b11111110,
+    0b00000000, // 73 I
+    0b11111110,
+    0b10000000, // 74 J
+    0b10111110,
+    0b10000000, // 75 K
+    0b11010111,
+    0b00000000, // 76 L
+    0b10111011,
+    0b00000000, // 77 M
+    0b11011101,
+    0b00000000, // 78 N
+    0b10101011,
+    0b00000000, // 79 O
+    0b11010101,
+    0b00000000, // 80 P
+    0b11101110,
+    0b10000000, // 81 Q
+    0b10101111,
+    0b00000000, // 82 R
+    0b11011110,
+    0b00000000, // 83 S
+    0b11011010,
+    0b00000000, // 84 T
+    0b10101011,
+    0b10000000, // 85 U
+    0b11011010,
+    0b10000000, // 86 V
+    0b10101110,
+    0b10000000, // 87 W
+    0b10111010,
+    0b10000000, // 88 X
+    0b10111101,
+    0b10000000, // 89 Y
+    0b10101011,
+    0b01000000, // 90 Z
+    0b11111011,
+    0b10000000, // 91 [
+    0b11110111,
+    0b10000000, // 92 "\"
+    0b11111101,
+    0b10000000, // 93 ]
+    0b10101111,
+    0b11000000, // 94 ^
+    0b10110110,
+    0b10000000, // 95 _ (underline)
+    0b10110111,
+    0b11000000, // 96 `
+    0b10110000,
+    0b00000000, // 97 a
+    0b10111110,
+    0b00000000, // 98 b
+    0b10111100,
+    0b00000000, // 99 c
+    0b10110100,
+    0b00000000, // 100 d
+    0b11000000,
+    0b00000000, // 101 e
+    0b11110100,
+    0b00000000, // 102 f
+    0b10110110,
+    0b00000000, // 103 g
+    0b10101100,
+    0b00000000, // 104 h
+    0b11010000,
+    0b00000000, // 105 i
+    0b11110101,
+    0b10000000, // 106 j
+    0b10111111,
+    0b00000000, // 107 k
+    0b11011000,
+    0b00000000, // 108 l
+    0b11101100,
+    0b00000000, // 109 m
+    0b11110000,
+    0b00000000, // 110 n
+    0b11100000,
+    0b00000000, // 111 o
+    0b11111100,
+    0b00000000, // 112 p
+    0b11011111,
+    0b10000000, // 113 q
+    0b10101000,
+    0b00000000, // 114 r
+    0b10111000,
+    0b00000000, // 115 s
+    0b10100000,
+    0b00000000, // 116 t
+    0b11011100,
+    0b00000000, // 117 u
+    0b11110110,
+    0b00000000, // 118 v
+    0b11010110,
+    0b00000000, // 119 w
+    0b11011111,
+    0b00000000, // 120 x
+    0b10111010,
+    0b00000000, // 121 y
+    0b11101010,
+    0b10000000, // 122 z
+    0b10101101,
+    0b11000000, // 123 {
+    0b11011101,
+    0b10000000, // 124 |
+    0b10101101,
+    0b01000000, // 125 }
+    0b10110101,
+    0b11000000, // 126 ~
+    0b11101101,
+    0b01000000, // 127 (del)
+};
+
+// This code was used on FDMDV version 1, and is more compact that Code 1, but only covers a subset
+// of the ASCII cahacter set
+
+char const varicode_table2[] = {
+
+    ' ' ,0b11000000,
+    13  ,0b01000000, // CR, end of message
+    '=' ,0b10000000,
+    '1' ,0b11110000,
+    '2' ,0b01110000,
+    '3' ,0b10110000,
+    '4' ,0b11010000,
+    '5' ,0b01010000,
+    '6' ,0b10010000,
+    '7' ,0b11100000,
+    '8' ,0b01100000,
+    '9' ,0b10100000,
+    'a' ,0b11111100,
+    'b' ,0b01111100,
+    'c' ,0b10111100,
+    'd' ,0b11011100,
+    'e' ,0b01011100,
+    'f' ,0b10011100,
+    'g' ,0b11101100,
+    'h' ,0b01101100,
+    'i' ,0b10101100,
+    'j' ,0b11110100,
+    'k' ,0b01110100,
+    'l' ,0b10110100,
+    'm' ,0b11010100,
+    'n' ,0b01010100,
+    'o' ,0b10010100,
+    'p' ,0b11100100,
+    'q' ,0b01100100,
+    'r' ,0b10100100,
+    's' ,0b11111000,
+    't' ,0b01111000,
+    'u' ,0b10111000,
+    'v' ,0b11011000,
+    'w' ,0b01011000,
+    'x' ,0b10011000,
+    'y' ,0b11101000,
+    'z' ,0b01101000,
+    '0' ,0b10101000
+};
+
diff --git a/codec2/branches/0.7/src/vhf_deframe_c2.c b/codec2/branches/0.7/src/vhf_deframe_c2.c
new file mode 100644 (file)
index 0000000..2818a3e
--- /dev/null
@@ -0,0 +1,113 @@
+
+/*---------------------------------------------------------------------------*\
+
+  FILE........: vhf_deframe_c2.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 8 March 2016
+
+  C tool to extract codec2 data from freedv VHF 2400A/B/whatever frames
+   
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "freedv_vhf_framing.h"
+
+int main(int argc,char *argv[]){
+    struct freedv_vhf_deframer * deframer;
+    FILE *fin,*fout;
+    uint8_t *bitbuf;
+    uint8_t *c2buf;
+    uint8_t zbuf[] = {0,0,0,0,0,0,0,0};
+    int count = 0;
+    int frame_fmt = 0;
+    int fsize,c2size;
+    
+    if(argc<3){
+        fprintf(stderr,"usage: %s (A|B) InputOneBitPerCharFile OutputC2File\n",argv[0]);
+        exit(1);
+    }
+    
+    if(strcmp(argv[1],"A")==0){
+        frame_fmt = FREEDV_VHF_FRAME_A;
+    } else if (strcmp(argv[1],"B")==0) {
+        frame_fmt = FREEDV_HF_FRAME_B;
+    } else {
+        fprintf(stderr,"usage: %s (A|B) InputOneBitPerCharFile OutputC2File\n",argv[0]);
+        exit(1);
+    }
+    
+    /* Open files */
+    if(strcmp(argv[2],"-")==0){
+        fin = stdin;
+    }else{
+        fin = fopen(argv[2],"r");
+    }
+       
+    if(strcmp(argv[3],"-")==0){
+        fout = stdout;
+    }else{
+        fout = fopen(argv[3],"w");
+    }
+
+    /* Set up deframer */
+    deframer = fvhff_create_deframer(frame_fmt,0);
+    
+    if(fin==NULL || fout==NULL || deframer==NULL){
+        fprintf(stderr,"Couldn't open test vector files\n");
+        goto cleanup;
+    }
+    
+    c2size = fvhff_get_codec2_size(deframer);
+    fsize = fvhff_get_frame_size(deframer);
+    
+    /* allocate buffers for processing */
+    bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*fsize);
+    c2buf = (uint8_t*)malloc(sizeof(uint8_t)*c2size);
+    
+    /* Deframe! */
+    while( fread(bitbuf,sizeof(uint8_t),fsize,fin) == fsize ){
+        if(fvhff_deframe_bits(deframer,c2buf,NULL,NULL,bitbuf))
+            fwrite(c2buf,sizeof(uint8_t),c2size,fout);
+        else
+            fwrite(zbuf,sizeof(uint8_t),c2size,fout);
+        
+        if(fin == stdin || fout == stdin){
+            fflush(fin);
+            fflush(fout);
+        }
+               if(count%100==0){
+                       fprintf(stderr,"BER Estimate: %f\n",((float)deframer->total_uw_err)/((float)deframer->total_uw_bits));
+               }
+    }
+    
+    free(bitbuf);
+    free(c2buf);
+    
+    cleanup:
+    fclose(fin);
+    fclose(fout);
+    fvhff_destroy_deframer(deframer);
+    exit(0);
+}
+
diff --git a/codec2/branches/0.7/src/vhf_frame_c2.c b/codec2/branches/0.7/src/vhf_frame_c2.c
new file mode 100644 (file)
index 0000000..9fae67d
--- /dev/null
@@ -0,0 +1,106 @@
+
+/*---------------------------------------------------------------------------*\
+
+  FILE........: vhf_deframe_c2.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 8 March 2016
+
+  C tool to extract codec2 data from freedv VHF 2400A/B/whatever frames
+   
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "freedv_vhf_framing.h"
+
+int main(int argc,char *argv[]){
+    struct freedv_vhf_deframer * deframer;
+    FILE *fin,*fout;
+    uint8_t *bitbuf;
+    uint8_t *c2buf;
+    int frame_fmt = 0;
+    int fsize,c2size;
+    
+    if(argc<3){
+        fprintf(stderr,"usage: %s (A|B) InpuC2File OutputOneBitPerCharFile\n",argv[0]);
+        exit(1);
+    }
+    
+    if(strcmp(argv[1],"A")==0){
+        frame_fmt = FREEDV_VHF_FRAME_A;
+    } else if (strcmp(argv[1],"B")==0) {
+        frame_fmt = FREEDV_HF_FRAME_B;
+    } else {
+        fprintf(stderr,"usage: %s (A|B) InpuC2File OutputOneBitPerCharFile\n",argv[0]);
+        exit(1);
+    }
+    
+    /* Open files */
+    if(strcmp(argv[2],"-")==0){
+        fin = stdin;
+    }else{
+        fin = fopen(argv[2],"r");
+    }
+       
+    if(strcmp(argv[3],"-")==0){
+        fout = stdout;
+    }else{
+        fout = fopen(argv[3],"w");
+    }
+
+    /* Set up deframer */
+    deframer = fvhff_create_deframer(frame_fmt,0);
+    
+    if(fin==NULL || fout==NULL || deframer==NULL){
+        fprintf(stderr,"Couldn't open test vector files\n");
+        goto cleanup;
+    }
+    
+    c2size = fvhff_get_codec2_size(deframer);
+    fsize = fvhff_get_frame_size(deframer);
+    
+    /* allocate buffers for processing */
+    bitbuf = (uint8_t*)malloc(sizeof(uint8_t)*fsize);
+    c2buf = (uint8_t*)malloc(sizeof(uint8_t)*c2size);
+    
+    /* Deframe! */
+    while( fread(c2buf,sizeof(uint8_t),c2size,fin) == c2size ){
+        fvhff_frame_bits(frame_fmt,bitbuf,c2buf,NULL,NULL);
+        fwrite(bitbuf,sizeof(uint8_t),fsize,fout);
+        
+        if(fin == stdin || fout == stdin){
+            fflush(fin);
+            fflush(fout);
+        }
+    }
+    
+    free(bitbuf);
+    free(c2buf);
+    
+    cleanup:
+    fclose(fin);
+    fclose(fout);
+    fvhff_destroy_deframer(deframer);
+    exit(0);
+}
+
diff --git a/codec2/branches/0.7/stm32/MENU.txt b/codec2/branches/0.7/stm32/MENU.txt
new file mode 100644 (file)
index 0000000..9ab120c
--- /dev/null
@@ -0,0 +1,45 @@
+UI layout
+=========
+
+There are two buttons for UI operation, SELECT and BACK. Outside of the menu,
+these simply cycle between the available modes. The current mode is announced
+(morse code) after a short delay.
+
+Holding down SELECT puts you in menu mode. The POWER LED will now flash to
+indicate this. To navigate, press the SELECT and BACK buttons momentarily to
+move up and down in the menu. Again, after a pause the item will be read out.
+Holding SELECT or BACK either chooses the option, or backs out.
+
+Pressing PTT while in a menu exits the entire menu tree without saving
+changes to flash storage.
+
+The menu structure looks like this:
+
+    -> Root menu:
+        |---> "MODE": Boot-up Operating mode
+        |       |---> "ANA":    Analogue mode
+        |       |---> "1600":   FreeDV 1600
+        |       '---> "TONE":   Test tone
+        |
+        |---> "TOT": Time-out timer
+        |       |---> "TIME":   Total time-out period (0 == disabled)
+        |       |               0-10 minutes in 5 second steps
+        |       '---> "WARN":   Warning beep period (0 == disabled)
+        |                       0-${TIME} seconds in 5 second steps
+        |
+        '---> "UI": User interface options
+                |---> "FREQ":   Morse frequency
+                |               50-2000 Hz in 50Hz steps
+                |---> "WPM":    Morse send speed (PARIS standard)
+                |               5-60 WPM in 5 WPM steps
+                '---> "VOL":    Menu volume
+                                1-15 units.
+
+Settings are saved when you hold down BACK to leave the root menu.
+
+Factory Reset
+=============
+
+To perform a factory reset, hold down BACK whilst powering the device on. A
+loud beep should be heard and the SYNC LED should flash. Release, and the
+device should boot up with factory defaults.
diff --git a/codec2/branches/0.7/stm32/Makefile b/codec2/branches/0.7/stm32/Makefile
new file mode 100644 (file)
index 0000000..d7086dd
--- /dev/null
@@ -0,0 +1,919 @@
+# Makefile for stm32f4 Codec 2 test programs
+
+# Include local definitions if they exist.
+-include local.mak
+
+###################################################
+
+FLOAT_TYPE=hard
+
+###################################################
+
+CROSS_COMPILE ?= arm-none-eabi-
+CC=$(BINPATH)$(CROSS_COMPILE)gcc
+AS=$(BINPATH)$(CROSS_COMPILE)as
+OBJCOPY=$(BINPATH)$(CROSS_COMPILE)objcopy
+SIZE=$(BINPATH)$(CROSS_COMPILE)size
+SUDO ?= sudo
+
+###################################################
+
+CFLAGS  = -std=gnu11 -O0 -g -Wall -Tstm32_flash.ld -DSTM32F40_41xxx -DCORTEX_M4
+CFLAGS += -mlittle-endian -mthumb -mthumb-interwork -nostartfiles -mcpu=cortex-m4 -Wno-unused-function
+
+ifeq ($(FLOAT_TYPE), hard)
+CFLAGS += -fsingle-precision-constant -Wdouble-promotion
+CFLAGS += -fdata-sections -ffunction-sections -Xlinker --gc-sections
+CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard -D__FPU_PRESENT=1 -D__FPU_USED=1
+else
+CFLAGS += -msoft-float
+endif
+
+###################################################
+
+# Definitions for the STM32F4 Standard Peripheral Library
+
+PERIPHLIBURL    = http://www.st.com/resource/en/firmware
+PERIPHLIBZIP    = stm32f4_dsp_stdperiph_lib.zip
+PERIPHLIBVER   = V1.8.0
+PERIPHLIBNAME  = STM32F4xx_DSP_StdPeriph_Lib
+PERIPHLIBDIR   = $(PERIPHLIBNAME)
+CMSIS          = $(PERIPHLIBDIR)/Libraries/CMSIS
+STM32F4LIB     = $(PERIPHLIBDIR)/Libraries/STM32F4xx_StdPeriph_Driver
+STM32F4TEMPLATE        = $(PERIPHLIBDIR)/Project/STM32F4xx_StdPeriph_Templates
+DSPLIB          = $(PERIPHLIBDIR)/Libraries/CMSIS/DSP_Lib
+
+CFLAGS         += -DUSE_STDPERIPH_DRIVER -I$(STM32F4LIB)/inc -I$(STM32F4TEMPLATE)
+CFLAGS         += -I$(CMSIS)/Include -I$(CMSIS)/Device/ST/STM32F4xx/Include
+CFLAGS         += -DARM_MATH_CM4
+
+# Precious files that should be preserved at all cost!
+.PRECIOUS: dl/$(PERIPHLIBZIP)
+
+STM32F4LIB_SRCS=\
+$(STM32F4LIB)/src/misc.c\
+$(STM32F4LIB)/src/stm32f4xx_adc.c\
+$(STM32F4LIB)/src/stm32f4xx_can.c\
+$(STM32F4LIB)/src/stm32f4xx_cec.c\
+$(STM32F4LIB)/src/stm32f4xx_crc.c\
+$(STM32F4LIB)/src/stm32f4xx_cryp_aes.c\
+$(STM32F4LIB)/src/stm32f4xx_cryp.c\
+$(STM32F4LIB)/src/stm32f4xx_cryp_des.c\
+$(STM32F4LIB)/src/stm32f4xx_cryp_tdes.c\
+$(STM32F4LIB)/src/stm32f4xx_dac.c\
+$(STM32F4LIB)/src/stm32f4xx_dbgmcu.c\
+$(STM32F4LIB)/src/stm32f4xx_dcmi.c\
+$(STM32F4LIB)/src/stm32f4xx_dma2d.c\
+$(STM32F4LIB)/src/stm32f4xx_dma.c\
+$(STM32F4LIB)/src/stm32f4xx_exti.c\
+$(STM32F4LIB)/src/stm32f4xx_flash.c\
+$(STM32F4LIB)/src/stm32f4xx_flash_ramfunc.c\
+$(STM32F4LIB)/src/stm32f4xx_fmpi2c.c\
+$(STM32F4LIB)/src/stm32f4xx_fsmc.c\
+$(STM32F4LIB)/src/stm32f4xx_gpio.c\
+$(STM32F4LIB)/src/stm32f4xx_hash.c\
+$(STM32F4LIB)/src/stm32f4xx_hash_md5.c\
+$(STM32F4LIB)/src/stm32f4xx_hash_sha1.c\
+$(STM32F4LIB)/src/stm32f4xx_i2c.c\
+$(STM32F4LIB)/src/stm32f4xx_iwdg.c\
+$(STM32F4LIB)/src/stm32f4xx_ltdc.c\
+$(STM32F4LIB)/src/stm32f4xx_pwr.c\
+$(STM32F4LIB)/src/stm32f4xx_qspi.c\
+$(STM32F4LIB)/src/stm32f4xx_rcc.c\
+$(STM32F4LIB)/src/stm32f4xx_rng.c\
+$(STM32F4LIB)/src/stm32f4xx_rtc.c\
+$(STM32F4LIB)/src/stm32f4xx_sai.c\
+$(STM32F4LIB)/src/stm32f4xx_sdio.c\
+$(STM32F4LIB)/src/stm32f4xx_spdifrx.c\
+$(STM32F4LIB)/src/stm32f4xx_spi.c\
+$(STM32F4LIB)/src/stm32f4xx_syscfg.c\
+$(STM32F4LIB)/src/stm32f4xx_tim.c\
+$(STM32F4LIB)/src/stm32f4xx_usart.c\
+$(STM32F4LIB)/src/stm32f4xx_wwdg.c
+
+# Not compiling for now
+# $(STM32F4LIB)/src/stm32f4xx_fmc.c
+
+STM32F4LIB_OBJS = $(STM32F4LIB_SRCS:.c=.o)
+
+CMSIS_SRCS=\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_abs_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_add_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_dot_prod_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_mult_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_negate_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_offset_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_scale_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_shift_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_shift_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_shift_q7.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_f32.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_q15.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_q31.c\
+$(CMSIS)/DSP_Lib/Source/BasicMathFunctions/arm_sub_q7.c\
+$(CMSIS)/DSP_Lib/Source/CommonTables/arm_common_tables.c\
+$(CMSIS)/DSP_Lib/Source/CommonTables/arm_const_structs.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_f32.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q15.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_conj_q31.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_f32.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q15.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_dot_prod_q31.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_f32.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q15.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_q31.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_f32.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q15.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mag_squared_q31.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_f32.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q15.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_cmplx_q31.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_f32.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q15.c\
+$(CMSIS)/DSP_Lib/Source/ComplexMathFunctions/arm_cmplx_mult_real_q31.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_f32.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q15.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_pid_reset_q31.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_f32.c\
+$(CMSIS)/DSP_Lib/Source/ControllerFunctions/arm_sin_cos_q31.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_cos_f32.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_cos_q15.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_cos_q31.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sin_f32.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sin_q15.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sin_q31.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q15.c\
+$(CMSIS)/DSP_Lib/Source/FastMathFunctions/arm_sqrt_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_32x64_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_fast_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df1_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_f64.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_df2T_init_f64.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_biquad_cascade_stereo_df2T_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_opt_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_fast_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_opt_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_opt_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_fast_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_opt_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_partial_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_conv_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_opt_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_fast_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_opt_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_correlate_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_fast_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_decimate_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_fast_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_init_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_interpolate_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_lattice_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_init_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_fir_sparse_q7.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_iir_lattice_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_norm_q31.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_q15.c\
+$(CMSIS)/DSP_Lib/Source/FilteringFunctions/arm_lms_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_add_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_add_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_cmplx_mult_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_inverse_f64.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_fast_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_mult_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_scale_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_sub_q31.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_f32.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q15.c\
+$(CMSIS)/DSP_Lib/Source/MatrixFunctions/arm_mat_trans_q31.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_f32.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_q15.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_q31.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_max_q7.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_f32.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_q15.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_q31.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_mean_q7.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_f32.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_q15.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_q31.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_min_q7.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_f32.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_q15.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_q31.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_power_q7.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_rms_f32.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_rms_q15.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_rms_q31.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_std_f32.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_std_q15.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_std_q31.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_var_f32.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_var_q15.c\
+$(CMSIS)/DSP_Lib/Source/StatisticsFunctions/arm_var_q31.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_f32.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_q15.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_q31.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_copy_q7.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_f32.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_q15.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_q31.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_fill_q7.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_float_to_q15.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_float_to_q31.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_float_to_q7.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q15_to_float.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q15_to_q31.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q15_to_q7.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q31_to_float.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q31_to_q15.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q31_to_q7.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q7_to_float.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q7_to_q15.c\
+$(CMSIS)/DSP_Lib/Source/SupportFunctions/arm_q7_to_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_bitreversal.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix2_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix4_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_cfft_radix8_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_dct4_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_fast_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_init_f32.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_init_q31.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_q15.c\
+$(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_rfft_q31.c\
+
+
+CMSIS_OBJS = $(CMSIS_SRCS:.c=.o) $(CMSIS)/DSP_Lib/Source/TransformFunctions/arm_bitreversal2.o
+
+###################################################
+
+# Codec 2
+
+CODEC2_SRC=../src
+CODEC2_SRCS=\
+$(CODEC2_SRC)/lpc.c \
+$(CODEC2_SRC)/nlp.c \
+$(CODEC2_SRC)/postfilter.c \
+$(CODEC2_SRC)/sine.c \
+$(CODEC2_SRC)/codec2.c \
+$(CODEC2_SRC)/codec2_fft.c \
+$(CODEC2_SRC)/kiss_fft.c \
+$(CODEC2_SRC)/kiss_fftr.c \
+$(CODEC2_SRC)/interp.c \
+$(CODEC2_SRC)/lsp.c \
+$(CODEC2_SRC)/phase.c \
+$(CODEC2_SRC)/quantise.c \
+$(CODEC2_SRC)/pack.c \
+$(CODEC2_SRC)/codebook.c \
+$(CODEC2_SRC)/codebookd.c \
+$(CODEC2_SRC)/codebookjvm.c \
+$(CODEC2_SRC)/codebookge.c \
+$(CODEC2_SRC)/dump.c \
+$(CODEC2_SRC)/fdmdv.c \
+$(CODEC2_SRC)/freedv_api.c \
+$(CODEC2_SRC)/varicode.c \
+$(CODEC2_SRC)/golay23.c \
+$(CODEC2_SRC)/fsk.c \
+$(CODEC2_SRC)/fmfsk.c \
+$(CODEC2_SRC)/freedv_vhf_framing.c \
+$(CODEC2_SRC)/freedv_data_channel.c
+
+CFLAGS += -D__EMBEDDED__
+
+#enable this for dump files to help verify optimisation
+#CFLAGS += -DDUMP
+
+CFLAGS += -I../src
+CFLAGS += -I../unittest
+CFLAGS += -Iinc
+
+FFT_TEST_SRCS = \
+$(DSPLIB)/Examples/arm_fft_bin_example/GCC/arm_fft_bin_data.c \
+fft_test.c \
+src/startup_stm32f4xx.s \
+src/system_stm32f4xx.c \
+stm32f4_machdep.c \
+gdb_stdio.c \
+../src/kiss_fft.c
+
+###################################################
+
+vpath %.c src
+vpath %.a lib
+
+ROOT=$(shell pwd)
+
+# Library paths
+
+LIBPATHS =
+
+# Libraries to link
+
+LIBS = -lg -lnosys -lm 
+#Uncomment for standard arm semihosting
+#LIBS = -lg -lrdimon -lm --specs=rdimon.specs
+
+# startup file
+
+SRCS += src/startup_stm32f4xx.s src/init.c
+
+OBJS = $(SRCS:.c=.o)
+
+all: libstm32f4.a codec2_profile.bin fft_test.bin dac_ut.bin dac_play.bin adc_rec.bin pwm_ut.bin fdmdv_profile.bin sm1000_leds_switches_ut.bin sm1000.bin adcdac_ut.bin freedv_tx_profile.bin freedv_rx_profile.bin adc_sd.bin usb_vcp_ut.bin tuner_ut.bin fast_dac_ut.bin adc_sfdr_ut.bin adc_rec_usb.bin si5351_ut.bin mco_ut.bin sm2000_stw.bin sm2000_adcdump.bin sm2000_rxdemo.bin
+
+# Rule for making directories automatically.
+# Note we don't use -p as it's a GNU extension.
+%/.md:
+       parent=$(shell dirname $(@D) ); \
+               [ -d $${parent} ] || $(MAKE) $${parent}/.md
+       [ -d $(@D) ] || mkdir $(@D)
+       touch $@
+
+dl/$(PERIPHLIBZIP): dl/.md
+       wget -O$@.part -c $(PERIPHLIBURL)/$(PERIPHLIBZIP)
+       mv $@.part $@
+       touch $@
+
+$(PERIPHLIBDIR)/.unpack: dl/$(PERIPHLIBZIP)
+       test ! -d $(PERIPHLIBDIR)_$(PERIPHLIBVER) || \
+               rm -fr $(PERIPHLIBDIR)_$(PERIPHLIBVER)
+       unzip dl/$(PERIPHLIBZIP)
+       test ! -d $(PERIPHLIBDIR) || rm -fr $(PERIPHLIBDIR)
+       mv $(PERIPHLIBDIR)_$(PERIPHLIBVER) $(PERIPHLIBDIR)
+       touch $@
+
+$(CMSIS_OBJS) $(STM32F4LIB_OBJS): $(PERIPHLIBDIR)/.unpack
+
+libstm32f4.a: $(CMSIS_OBJS) $(STM32F4LIB_OBJS)
+       find $(PERIPHLIBDIR) -type f -name '*.o' -exec $(AR) crs libstm32f4.a {} ";"
+
+# Kludgy target to build a file with CFLAGS -O3
+%.O3.o: %.c
+       $(CC) $(CPPFLAGS) $(CFLAGS) -O3 -c -o $@ $<
+
+# Kludgy target to build a file with CFLAGS -DPROFILE
+%.profile.o: %.c
+       $(CC) $(CPPFLAGS) $(CFLAGS) -DPROFILE -c -o $@ $<
+
+# Rule for building .bin files from a .elf
+%.bin: %.elf
+       $(OBJCOPY) -O binary $< $@
+
+# Rule for programming the SM1000
+%.pgm: %.bin
+       $(SUDO) dfu-util -d 0483:df11 -c 1 -i 0 -a 0 -s 0x08000000 -D $<
+
+####################################################
+
+CODEC2_PROFILE_SRCS=\
+src/codec2_profile.c \
+src/gdb_stdio.c \
+src/stm32f4_machdep.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+src/system_stm32f4xx.c
+CODEC2_PROFILE_SRCS += $(CODEC2_SRCS)
+
+codec2_profile.elf: $(CODEC2_PROFILE_SRCS:.c=.profile.o) libstm32f4.a
+       $(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
+
+fft_test.elf: $(FFT_TEST_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+DAC_UT_SRCS=\
+src/dac_ut.c \
+../src/fifo.c \
+src/stm32f4_dac.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+dac_ut.elf: $(DAC_UT_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+FAST_DAC_UT_SRCS=\
+src/fast_dac_ut.c \
+../src/fifo.c \
+src/iir_duc.c \
+src/gdb_stdio.c \
+src/stm32f4_dacduc.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+fast_dac_ut.elf: $(FAST_DAC_UT_SRCS:.c=.O3.o) libstm32f4.a
+       $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+ADCDAC_UT_SRCS=\
+src/adcdac_ut.c \
+../src/fifo.c \
+src/stm32f4_dac.c \
+src/stm32f4_adc.c \
+src/sm1000_leds_switches.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+adcdac_ut.elf: $(ADCDAC_UT_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+DAC_PLAY_SRCS=\
+src/dac_play.c \
+../src/fifo.c \
+gdb_stdio.c \
+src/stm32f4_dac.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+dac_play.elf: $(DAC_PLAY_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) -O0 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+ADC_REC_SRCS=\
+src/adc_rec.c \
+../src/fifo.c \
+gdb_stdio.c \
+src/stm32f4_adc.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+adc_rec.elf: $(ADC_REC_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+ADC_SD_SRCS=\
+src/adc_sd.c \
+../src/fifo.c \
+gdb_stdio.c \
+src/stm32f4_adc.c \
+src/stm32f4_dac.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+adc_sd.elf: $(ADC_SD_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+PWM_UT_SRCS=\
+gdb_stdio.c \
+src/stm32f4_pwm.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+pwm_ut.elf: $(PWM_UT_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+POWER_UT_SRCS=\
+src/power_ut.c \
+gdb_stdio.c \
+../src/fifo.c \
+src/stm32f4_adc.c \
+src/stm32f4_dac.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+src/stm32f4_machdep.c \
+
+POWER_UT_SRCS += $(CODEC2_SRCS)
+
+power_ut.elf: $(POWER_UT_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+USB_VCP=\
+usb_conf/usb_bsp.c \
+usb_conf/usbd_desc.c \
+usb_conf/usbd_usr.c \
+usb_lib/cdc/usbd_cdc_core.c \
+usb_lib/cdc/usbd_cdc_vcp.c \
+usb_lib/core/usbd_core.c \
+usb_lib/core/usbd_ioreq.c \
+usb_lib/core/usbd_req.c \
+usb_lib/otg/usb_core.c \
+usb_lib/otg/usb_dcd.c \
+usb_lib/otg/usb_dcd_int.c
+
+USB_VCP_UT=\
+src/usb_vcp_ut.c \
+src/stm32f4_usb_vcp.c \
+src/sm1000_leds_switches.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+USB_VCP_UT+=$(USB_VCP)
+
+CFLAGS += -DUSE_USB_OTG_FS -DUSE_ULPI_PHY -Iusb_conf -Iusb_lib/cdc -Iusb_lib/core -Iusb_lib/otg
+
+usb_vcp_ut.elf: $(USB_VCP_UT:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+ADC_REC_USB_SRCS=\
+src/adc_rec_usb.c \
+../src/fifo.c \
+src/stm32f4_adc.c \
+src/stm32f4_usb_vcp.c \
+src/sm1000_leds_switches.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+ADC_REC_USB_SRCS+=$(USB_VCP)
+
+adc_rec_usb.elf: $(ADC_REC_USB_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+
+FDMDV_PROFILE_SRCS=\
+src/fdmdv_profile.c \
+gdb_stdio.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+src/stm32f4_machdep.c
+
+FDMDV_PROFILE_SRCS += $(CODEC2_SRCS)
+
+fdmdv_profile.elf: $(FDMDV_PROFILE_SRCS:.c=.profile.o) libstm32f4.a
+       $(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
+
+SM1000_LEDS_SWITCHES_UT_SRCS=\
+src/sm1000_leds_switches_ut.c \
+src/sm1000_leds_switches.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+sm1000_leds_switches_ut.elf: $(SM1000_LEDS_SWITCHES_UT_SRCS:.c=.o) \
+               libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+SM1000_SRCS=\
+src/sm1000_main.c \
+src/tone.c \
+src/sfx.c \
+src/sounds.c \
+src/morse.c \
+src/menu.c \
+src/tot.c \
+src/sm1000_leds_switches.c \
+../src/fifo.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/stm32f4_vrom.c \
+src/init.c
+
+SM1000_SRCS += $(CODEC2_SRCS)
+
+src/stm32f4_dac.o: src/stm32f4_dac.c
+       $(CC) $(CFLAGS)  $^ -c -o $@
+
+src/stm32f4_adc.o: src/stm32f4_adc.c
+       $(CC) $(CFLAGS)  $^ -c -o $@
+
+sm1000.elf: $(SM1000_SRCS:.c=.O3.o) src/stm32f4_dac.O3.o \
+               src/stm32f4_adc.O3.o libstm32f4.a
+       $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+FREEDV_TX_PROFILE_SRCS=\
+src/freedv_tx_profile.c \
+src/stm32f4_machdep.c \
+gdb_stdio.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+FREEDV_TX_PROFILE_SRCS += $(CODEC2_SRCS)
+
+freedv_tx_profile.elf: $(FREEDV_TX_PROFILE_SRCS:.c=.profile.o) libstm32f4.a
+       $(CC) $(CFLAGS) -DPROFILE $^ -o $@ $(LIBPATHS) $(LIBS)
+
+FREEDV_RX_PROFILE_SRCS=\
+src/freedv_rx_profile.c \
+src/stm32f4_machdep.c \
+gdb_stdio.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+FREEDV_RX_PROFILE_SRCS += $(CODEC2_SRCS)
+
+freedv_rx_profile.elf: $(FREEDV_RX_PROFILE_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+FDMDV_DUMP_RT_SRCS=\
+src/fdmdv_dump_rt.c \
+src/sm1000_leds_switches.c \
+../src/fifo.c \
+src/debugblinky.c \
+gdb_stdio.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+FDMDV_DUMP_RT_SRCS += $(CODEC2_SRCS)
+
+fdmdv_dump_rt.elf: $(FDMDV_DUMP_RT_SRCS:.c=.O3.o) \
+               src/stm32f4_dac.O3.o src/stm32f4_adc.o libstm32f4.a
+       $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------
+
+TUNER_UT_SRCS=\
+src/tuner_ut.c \
+gdb_stdio.c \
+../src/fifo.c \
+src/stm32f4_dac.c \
+src/iir_tuner.c \
+src/sm1000_leds_switches.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+../src/fm.c
+
+# this needs to be compiled without the optimiser or ugly things happen
+# would be nice to work out why as ISRs need to run fast
+
+src/stm32f4_adc_tuner.o: src/stm32f4_adc_tuner.c
+       $(CC) $(CFLAGS) $^ -c -o $@
+
+tuner_ut.elf: $(TUNER_UT_SRCS:.c=.O3.o) \
+               src/stm32f4_adc_tuner.o libstm32f4.a
+       $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------
+
+ADC_SFDR_UT_SRCS=\
+src/adc_sfdr_ut.c \
+gdb_stdio.c \
+../src/fifo.c \
+src/iir_tuner.c \
+src/sm1000_leds_switches.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+
+adc_sfdr_ut.elf: $(ADC_SFDR_UT_SRCS:.c=.O3.o) src/stm32f4_adc_tuner.o \
+               libstm32f4.a
+       $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+
+FM_LODUC_PLAY_SRCS=\
+src/fm_loduc_play.c \
+gdb_stdio.c \
+../src/fifo.c \
+../src/fm.c \
+src/debugblinky.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c
+
+src/stm32f4_dacloduc.o: src/stm32f4_dacloduc.c
+       $(CC) $(CFLAGS)  $^ -c -o $@ 
+
+fm_loduc_play.elf: $(FM_LODUC_PLAY_SRCS) src/stm32f4_dacloduc.o
+       $(CC) $(CFLAGS) -O3 $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------------
+
+SI5351_UT_SRCS=\
+src/si5351_ut.c \
+src/new_i2c.c \
+src/si53xx.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+
+si5351_ut.elf: $(SI5351_UT_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------------
+
+MCO_UT_SRCS=\
+src/mco_ut.c \
+src/tm_stm32f4_mco_output.c \
+src/tm_stm32f4_gpio.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c \
+
+mco_ut.elf: $(MCO_UT_SRCS:.c=.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------------
+
+# ---------------------------------------------------------------------------------
+
+SM2000_RXDEMO_SRCS=\
+src/sm2000_rxdemo.c \
+src/sm1000_leds_switches.c \
+src/debugblinky.c \
+src/new_i2c.c \
+src/si53xx.c \
+src/stm32f4_dac.c \
+src/stm32f4_adc.c \
+../src/fifo.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c 
+
+SM2000_RXDEMO_SRCS+=$(CODEC2_SRCS)
+
+sm2000_rxdemo.elf: $(SM2000_RXDEMO_SRCS:.c=.O3.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------------
+
+SM2000_STW_SRCS=\
+src/sm2000_stw.c \
+src/sm1000_leds_switches.c \
+src/debugblinky.c \
+src/new_i2c.c \
+src/si53xx.c \
+src/stm32f4_dac.c \
+src/stm32f4_adc.c \
+../src/fifo.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c 
+
+SM2000_STW_SRCS+=$(CODEC2_SRCS)
+
+#SM2000_STW_SRCS+=$(USB_VCP)
+
+sm2000_stw.elf: $(SM2000_STW_SRCS:.c=.O3.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------------
+
+SM2000_ADCDUMP_SRCS=\
+src/sm2000_adc_dump.c \
+src/sm1000_leds_switches.c \
+src/debugblinky.c \
+src/new_i2c.c \
+src/si53xx.c \
+src/stm32f4_dac.c \
+src/stm32f4_usb_vcp.c \
+src/stm32f4_adc.c \
+../src/fifo.c \
+src/system_stm32f4xx.c \
+src/startup_stm32f4xx.s \
+src/init.c 
+
+SM2000_ADCDUMP_SRCS_SRCS+=$(CODEC2_SRCS)
+
+SM2000_ADCDUMP_SRCS+=$(USB_VCP)
+
+sm2000_adcdump.elf: $(SM2000_ADCDUMP_SRCS:.c=.O3.o) libstm32f4.a
+       $(CC) $(CFLAGS) $^ -o $@ $(LIBPATHS) $(LIBS)
+
+# ---------------------------------------------------------------------------------
+
+# Objects that require the peripheral library
+src/sm1000_main.o: $(PERIPHLIBDIR)/.unpack
+src/codec2_profile.o: $(PERIPHLIBDIR)/.unpack
+
+# ---------------------------------------------------------------------------------
+
+clean:
+       rm -f *.elf *.bin
+       rm -f libstm32f4.a
+       find . ../src -type f -name '*.o' | xargs rm -f
diff --git a/codec2/branches/0.7/stm32/README.txt b/codec2/branches/0.7/stm32/README.txt
new file mode 100644 (file)
index 0000000..227979f
--- /dev/null
@@ -0,0 +1,133 @@
+README.txt
+codec2 support for the stm32f4
+David Rowe Jan 2016
+
+Quickstart
+==========
+
+The Makefile generates several programs used in Codec 2 development on
+the STM32F4, including sm1000.bin, the firmware for the SM1000.
+
+1. Install the toolchain, on Ubuntu 14 this is:
+
+   $ sudo apt-get install gcc-arm-none-eabi
+
+2. $ make (and cross your fingers)
+
+Not quite so Quickstart
+=======================
+
+Note: This section needs some editing.  It deals with the running the
+semi-hosting used for development system.
+
+gdb_stdio system
+----------------
+
+stutil contains a gdb server that talks to the target firmware.
+stutil has been patched to allow "semihosting": stdio requests on the
+target are re-directed to the host PC.  So if you call printf on the
+target, it appears on the host PC console.  With printf/fread/fwrite
+and gdb it makes developing on bare metal just like developing on any
+command line gcc system.
+
+The root path for files accessed by the target is the path st-util is
+run from.
+
+Getting Started
+---------------
+
+. Install arm toolchain binary
+
+   $ cd ~
+   $ wget https://launchpad.net/gcc-arm-embedded/4.7/4.7-2013-q1-update/+download/gcc-arm-none-eabi-4_7-2013q1-20130313-linux.tar.bz2
+   $ tar xjf gcc-arm-none-eabi-4_7-2013q1-20130313-linux.tar.bz2
+
+. Build codec2 unit test:
+
+   $ cd codec2_dev/stm32
+   In Makefile: edit the BINPATH variable for your toolchain location
+                edit PERIPHLIBVER for the current version of the peripheral
+                 library, currently V1.3.0
+                delete power_ut.elf target from the all: target
+   $ make
+   after make downloads the peripheral library, you will get a compile error:
+   #error "Please select first the target STM32F4xx device used in your application (in stm32f4xx.h file)"
+   edit STM32F4xx_DSP_StdPeriph_Lib_V1.3.0/Libraries/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h
+   and at the top of that file, uncomment the appropriate line for your target
+   processor.
+   $ make
+
+. Build stlink:
+
+   $ cd ~
+   $ git clone https://github.com/shenki/stlink.git
+   $ cd stlink
+   ~/stlink$ sudo apt-get install libusb-1.0-0-dev libelf-dev automake
+   ~/stlink$ ./autogen.sh
+   ~/stlink$ ./configure
+   ~/stlink$ make
+
+. Place a copy of hts1a.raw in the stlink directory and start st-util:
+
+   ~/stlink$ cp ~/codec2-dev/raw/hts1a.raw stm_in.raw
+   ~/stlink$ sudo ./st-util -f /home/david/codec2-dev/stm32/stm32f4_codec2.elf
+
+. In _another_ console start gdb:
+
+   $ ~/codec2-dev/stm32$ ~/gcc-arm-none-eabi-4_7-2013q1/bin/arm-none-eabi-gdb stm32f4_codec2.elf
+
+   (gdb) tar ext :4242
+
+   (gdb) load
+   `/home/david/codec2-dev/stm32/fft_test.elf' has changed; re-reading symbols.
+    Loading section .isr_vector, size 0x188 lma 0x8000000
+    Loading section .text, size 0x1a4b4 lma 0x8000188
+    Loading section .data, size 0x28f0 lma 0x801a63c
+    Start address 0x800a885, load size 118572
+    Transfer rate: 13 KB/sec, 10779 bytes/write.
+
+. Power cycle Discovery.
+
+. Stop st-util using ctrl-C, then restart st-util
+
+. Back to gdb:
+
+    (gdb) tar ext :4242
+    A program is being debugged already.  Kill it? (y or n) y
+    Remote connection closed
+    (gdb) tar ext :4242
+    Remote debugging using :4242
+    Reset_Handler () at lib/startup_stm32f4xx.s:69
+    69   movs  r1, #0
+
+   (gdb) c
+   Continuing.
+
+. gdb will prints various debug messages, and the codec output file
+  will be written to ~/stlink.
+
+  ~/stlink$ play -r 8000 -s -2 stm_out.raw
+
+Process
+-------
+
+1. Profiling macros, grep on TIMER_xxxx
+
+2. Enable DUMP variable in Makefile to dump files, note profiling
+   times will be corrupted by this due to latency in talking to Host
+
+3. Compare outputs using octave/diff_codec.  Example:
+
+   octave:> diff_codec("~/stlink/ref/hts1a_out_1300.raw", "~/stlink/hts1a_out_1300.raw","~/stlink/stm32f4", "~/stlink/ref/stm32f4")
+
+Gotcha
+------
+
+Using printf rather than gdb_stdio_printf, regular stdio functions are
+stubbed out so will link, just nothing will happen.
+
+TODO
+----
+
+ + check if "CFLAGS:  -mlittle-endian -mthumb -mthumb-interwork" needed
+ + double check if _fini hack is OK (src/init.c)
diff --git a/codec2/branches/0.7/stm32/inc/debugblinky.h b/codec2/branches/0.7/stm32/inc/debugblinky.h
new file mode 100644 (file)
index 0000000..f2bb2da
--- /dev/null
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: debugblinky.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 12 August 2014
+
+  Configures Port E GPIO pins used for debug blinkies, and control lines
+  for SM2000 +12V switching.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __DEBUGBLINKY__
+#define __DEBUGBLINKY__
+
+void init_debug_blinky(void);
+void txrx_12V(int state);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/gdb_stdio.h b/codec2/branches/0.7/stm32/inc/gdb_stdio.h
new file mode 100644 (file)
index 0000000..eafabca
--- /dev/null
@@ -0,0 +1,47 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: gdb_stdio.h
+  AUTHOR......: David Rowe
+  DATE CREATED: April 23 2013
+
+  Some stdio I/O functions that perform I/O on the host using gdb.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __GDB_STDIO__
+#define __GDB_STDIO__
+
+#include <stdio.h>
+#include <stdarg.h>
+
+void gdb_stdio_fprintf(FILE *file, const char *format, ...);
+void gdb_stdio_printf(const char *format, ...);
+FILE *gdb_stdio_fopen(char file_name[], char mode[]);
+void gdb_stdio_fclose(FILE *file);
+int gdb_stdio_fwrite(void *ptr, int size, int nmemb, FILE *file);
+int gdb_stdio_fread(void *ptr, int size, int nmemb, FILE *file);
+
+#define printf gdb_stdio_printf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#define fread gdb_stdio_fread
+#define fwrite gdb_stdio_fwrite
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/iir_duc.h b/codec2/branches/0.7/stm32/inc/iir_duc.h
new file mode 100644 (file)
index 0000000..b20b0b5
--- /dev/null
@@ -0,0 +1,37 @@
+ /*---------------------------------------------------------------------------*\
+
+  FILE........: iir_duc.h
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 6 Mar 2015
+
+  Interapolator/Filter for IF upconversion
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 Brady O'Brien
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __IIR_DUC_H
+#define __IIR_DUC_H
+#include "comp.h"
+
+void iir_upconv(float modin[],unsigned short dac_out[]);
+void iir_upconv_fixp(int modin[], unsigned short dac_out[]);
+void upconv_48c_80r(COMP comp_8[],int real_80[],int count);
+void upconv_8c_80r(COMP comp_8[],float real_80[],int count);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/iir_tuner.h b/codec2/branches/0.7/stm32/inc/iir_tuner.h
new file mode 100644 (file)
index 0000000..7788a8d
--- /dev/null
@@ -0,0 +1,36 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: iir_tuner.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 20 Feb 2015
+
+  Header file for IIR tuner function.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __IIR_TUNER__
+#define __IIR_TUNER__
+
+#define IIR_TUNER_DEC_50_10_FILT_MEM 100
+
+void iir_tuner(float dec_50[], unsigned short adc_buf[]);
+void iir_tuner_dec_50_to_10(float dec_10[], float dec_50[], int n);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/menu.h b/codec2/branches/0.7/stm32/inc/menu.h
new file mode 100644 (file)
index 0000000..f93601b
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef _MENU_H
+#define _MENU_H
+/*!
+ * Callback driven menu handler.
+ *
+ * The following is an implementation of a callback-driven menu system.
+ * It supports arbitrary levels of menus (limited by size of return stack)
+ * and supports arbitrary user events.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+
+#define MENU_STACK_SZ  8       /*!< Size of the menu return stack */
+
+#define MENU_EVT_ENTERED 0     /*!< Menu item has been entered */
+#define MENU_EVT_RETURNED 1    /*!< We have returned from a submenu */
+
+/*! Menu state structure */
+struct menu_t {
+       /*! The last seen menu item */
+       const struct menu_item_t*               last;
+       /*! Currently selected item index */
+       uint32_t                                current;
+       /*! Current menu item stack */
+       struct menu_stack_item_t {
+               const struct menu_item_t*       item;
+               uint32_t                        index;
+       }                                       stack[MENU_STACK_SZ];
+       /*! Present depth of the stack */
+       uint8_t                                 stack_depth;
+};
+
+/*! Menu item structure */
+struct menu_item_t {
+       /*! Morse-code label for the menu item */
+       const char*             label;
+       /*! Event callback pointer for menu item */
+       void                    (*event_cb)(
+                       struct menu_t* const menu,
+                       uint32_t event);
+       /*! Children of this menu item */
+       const struct menu_item_t** const        children;
+       uint32_t                                num_children;
+       /*! Arbitrary data */
+       union menu_item_data_t {
+               /*! Arbitrary pointer */
+               const void*                     p;
+               /*! Arbitrary unsigned integer */
+               uintptr_t                       ui;
+               /*! Arbitrary signed integer */
+               intptr_t                        si;
+       }                                       data;
+};
+
+/*!
+ * Return the Nth item on the stack.
+ */
+const struct menu_item_t* const menu_item(
+               const struct menu_t* const menu, uint8_t index);
+
+/*!
+ * Enter a (sub)-menu.
+ * @retval     -1      Stack is full
+ * @retval     0       Success
+ */
+int menu_enter(struct menu_t* const menu,
+               const struct menu_item_t* const item);
+
+/*! Return from a (sub)-menu */
+void menu_leave(struct menu_t* const menu);
+
+/*!
+ * Execute the callback for the current item with a user-supplied event.
+ */
+void menu_exec(struct menu_t* const menu, uint32_t event);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/morse.h b/codec2/branches/0.7/stm32/inc/morse.h
new file mode 100644 (file)
index 0000000..632f2e2
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef _MORSE_H
+#define _MORSE_H
+/*!
+ * Morse code library.
+ *
+ * This implements a state machine for playing back morse code messages.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "sfx.h"
+
+/*!
+ * Maximum length of a morse symbol, including gaps and termination.
+ * Allowing for 8 actual sub-symbols (dahs and dits), that's up to
+ * 8 gaps between plus a terminator.
+ */
+#define MORSE_SYM_LEN  (17)
+
+/*!
+ * Morse code playback state machine
+ */
+struct morse_player_t {
+       /*! Symbol being transmitted */
+       struct sfx_note_t       sym[MORSE_SYM_LEN];
+       /*!
+        * Pointer to the string being emitted.  Playback is finished
+        * when this is NULL.
+        */
+       const char*             msg;
+       /*! Sound effect player state machine */
+       struct sfx_player_t     sfx_player;
+       /*! "Dit" period in milliseconds */
+       uint16_t                dit_time;
+       /*! Tone frequency */
+       uint16_t                freq;
+};
+
+/*!
+ * Play a morse code message.
+ * @param      morse_player    Morse code player state machine
+ * @param      msg             Message to play back (NULL == stop)
+ */
+void morse_play(struct morse_player_t* const morse_player,
+               const char* msg);
+
+/*!
+ * Retrieve the next sample to be played.
+ */
+int16_t morse_next(struct morse_player_t* const morse_player);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/new_i2c.h b/codec2/branches/0.7/stm32/inc/new_i2c.h
new file mode 100644 (file)
index 0000000..a37444d
--- /dev/null
@@ -0,0 +1,107 @@
+/* 
+ * File:   new_i2c.h
+ * Author: leon (zs6lmg@gmail.com or leon@lrlabs.com)
+ *
+ * Created on March 17, 2016, 6:09 PM
+ * 
+ * GNU license apply.
+ * 
+ */
+
+/*
+  Copyright (C) 2016 Leon
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef NEWI2C_H
+#define        NEWI2C_H
+
+#include <stdint.h>
+
+//
+// I2C1 device Enable
+//
+#define I2C_D1 0
+// I2C1 only PORTB
+// SCL - B6 or B8
+// SDA - B7 or B9
+#if I2C_D1
+#define I2C_DEVICE I2C1
+#define I2C_DX_P_SCK GPIOB
+#define I2C_DX_P_SDA GPIOB
+#define I2C_DX_SCK 6
+#define I2C_DX_SDA 9
+// could not get macro expansion in gcc to play with us
+#define I2C_DX_CLK_SCK RCC_AHB1Periph_GPIOB
+#define I2C_DX_CLK_SDA RCC_AHB1Periph_GPIOB
+#endif
+
+//
+// I2C2 device Enable
+//
+#define I2C_D2 0
+// I2C2 on PORTB, PORTF and PORTH
+// SCL - B10 F1 H4
+// SDA - B11 F0 H5
+#if I2C_D2
+#define I2C_DEVICE I2C2
+#define I2C_DX_P_SCK GPIOB
+#define I2C_DX_P_SDA GPIOB
+#define I2C_DX_SCK 10
+#define I2C_DX_SDA 11
+// could not get macro expansion in gcc to play with us
+#define I2C_DX_CLK_SCK RCC_AHB1Periph_GPIOB
+#define I2C_DX_CLK_SDA RCC_AHB1Periph_GPIOB
+#endif
+
+//
+// I2C3 device Enable
+//
+#define I2C_D3 1
+// I2C2 on PORTA and PORTH
+// SCL - A8 H7
+// SDA - C9 H8
+#if I2C_D3
+#define I2C_DEVICE I2C3
+#define I2C_DX_P_SCK GPIOA
+#define I2C_DX_P_SDA GPIOC
+#define I2C_DX_SCK 8
+#define I2C_DX_SDA 9
+// could not get macro expansion in gcc to play with us
+#define I2C_DX_CLK_SCK RCC_AHB1Periph_GPIOA
+#define I2C_DX_CLK_SDA RCC_AHB1Periph_GPIOC
+#endif
+
+
+
+
+#define I2C_SPEED                100000
+#define I2C_STIMEOUT             ((uint32_t)0x1000)
+#define I2C_LTIMEOUT             ((uint32_t)(300 * 0x1000))
+
+// software I2C model for testing
+// 
+#define I2Cmodel 1
+
+//void I2C_GPIO_Init(void);
+void I2C_Setup(void);
+
+uint32_t I2C_NewWriteRegister(uint8_t Addr,uint8_t Register,uint8_t Value);
+uint32_t I2C_NewWriteRegisterN(uint8_t Addr,uint8_t Register,uint8_t *Value,uint8_t N);
+uint32_t I2C_NewReadRegister(uint8_t Addr,uint8_t Register);
+uint32_t I2C_NewReadRegisterN(uint8_t Addr,uint8_t Register,uint8_t *buffer, uint8_t N);
+
+#endif /* NEWI2C_H */
+
diff --git a/codec2/branches/0.7/stm32/inc/sfx.h b/codec2/branches/0.7/stm32/inc/sfx.h
new file mode 100644 (file)
index 0000000..9745018
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef _SFX_H
+#define _SFX_H
+/*!
+ * Sound effect player library.
+ *
+ * This implements a state machine for playing back various monophonic
+ * sound effects such as morse code symbols, clicks and alert tones.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "tone.h"
+
+/*!
+ * A sound effect "note"
+ */
+struct sfx_note_t {
+       /*! Note frequency.  0 == pause */
+       uint16_t        freq;
+       /*! Note duration in msec.   0 == end of effect */
+       uint16_t        duration;
+};
+
+/*!
+ * Sound effect player state machine
+ */
+struct sfx_player_t {
+       /*!
+        * Pointer to the current "note".  When this is NULL,
+        * playback is complete.
+        */
+       const struct sfx_note_t*        note;
+       /*! Tone generator state machine */
+       struct tone_gen_t               tone_gen;
+};
+
+/*!
+ * Start playing a particular effect.
+ * @param      sfx_player      Effect player state machine
+ * @param      effect          Pointer to sound effect (NULL == stop)
+ */
+void sfx_play(struct sfx_player_t* const sfx_player,
+               const struct sfx_note_t* effect);
+
+/*!
+ * Retrieve the next sample to be played.
+ */
+int16_t sfx_next(struct sfx_player_t* const sfx_player);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/si53xx.h b/codec2/branches/0.7/stm32/inc/si53xx.h
new file mode 100644 (file)
index 0000000..b43af79
--- /dev/null
@@ -0,0 +1,315 @@
+/*------------------------------------------------------------------------------
+ * 
+ * Ported to stm32F4xx non c++ by Leon Lessing leon@lrlabs.com or zs6lmg@gmail.com
+ * 
+ * 
+ * Copyright (C) 2015-2016 Jason Milldrum <milldrum@gmail.com>
+ *                         Dana H. Myers <k6jq@comcast.net>
+ *
+ * Many defines derived from clk-si5351.h in the Linux kernel.
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Rabeeh Khoury <rabeeh@solid-run.com>
+ *
+ * do_div() macro derived from /include/asm-generic/div64.h in
+ * the Linux kernel.
+ * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * 
+ *------------------------------------------------------------------------------
+*/
+
+
+#ifndef SI53XX_H_
+#define SI53XX_H_
+
+#include <stdint.h>
+
+
+#define SI5351_BUS_BASE_ADDR                   0x60
+#define SI5351_XTAL_FREQ                       25000000
+#define SI5351_PLL_FIXED                       90000000000ULL
+#define SI5351_FREQ_MULT                       100ULL
+#define SI5351_DEFAULT_CLK                     1000000000ULL
+
+#define SI5351_PLL_VCO_MIN                     600000000
+#define SI5351_PLL_VCO_MAX                     900000000
+#define SI5351_MULTISYNTH_MIN_FREQ             1000000
+#define SI5351_MULTISYNTH_DIVBY4_FREQ          150000000
+#define SI5351_MULTISYNTH_MAX_FREQ             160000000
+#define SI5351_MULTISYNTH_SHARE_MAX            112500000
+#define SI5351_MULTISYNTH67_MAX_FREQ           SI5351_MULTISYNTH_DIVBY4_FREQ
+#define SI5351_CLKOUT_MIN_FREQ                 8000
+#define SI5351_CLKOUT_MAX_FREQ                 SI5351_MULTISYNTH_MAX_FREQ
+#define SI5351_CLKOUT67_MAX_FREQ               SI5351_MULTISYNTH67_MAX_FREQ
+
+#define SI5351_PLL_A_MIN                       15
+#define SI5351_PLL_A_MAX                       90
+#define SI5351_PLL_B_MAX                       (SI5351_PLL_C_MAX-1)
+#define SI5351_PLL_C_MAX                       1048575
+#define SI5351_MULTISYNTH_A_MIN                        6
+#define SI5351_MULTISYNTH_A_MAX                        1800
+#define SI5351_MULTISYNTH67_A_MAX              254
+#define SI5351_MULTISYNTH_B_MAX                        (SI5351_MULTISYNTH_C_MAX-1)
+#define SI5351_MULTISYNTH_C_MAX                        1048575
+#define SI5351_MULTISYNTH_P1_MAX               ((1<<18)-1)
+#define SI5351_MULTISYNTH_P2_MAX               ((1<<20)-1)
+#define SI5351_MULTISYNTH_P3_MAX               ((1<<20)-1)
+
+#define SI5351_DEVICE_STATUS                   0
+#define SI5351_INTERRUPT_STATUS                        1
+#define SI5351_INTERRUPT_MASK                  2
+#define SI5351_STATUS_SYS_INIT                 (1<<7)
+#define SI5351_STATUS_LOL_B                    (1<<6)
+#define SI5351_STATUS_LOL_A                    (1<<5)
+#define SI5351_STATUS_LOS                      (1<<4)
+#define SI5351_OUTPUT_ENABLE_CTRL              3
+#define SI5351_OEB_PIN_ENABLE_CTRL             9
+#define SI5351_PLL_INPUT_SOURCE                        15
+#define SI5351_CLKIN_DIV_MASK                  (3<<6)
+#define SI5351_CLKIN_DIV_1                     (0<<6)
+#define SI5351_CLKIN_DIV_2                     (1<<6)
+#define SI5351_CLKIN_DIV_4                     (2<<6)
+#define SI5351_CLKIN_DIV_8                     (3<<6)
+#define SI5351_PLLB_SOURCE                     (1<<3)
+#define SI5351_PLLA_SOURCE                     (1<<2)
+
+#define SI5351_CLK0_CTRL                       16
+#define SI5351_CLK1_CTRL                       17
+#define SI5351_CLK2_CTRL                       18
+#define SI5351_CLK3_CTRL                       19
+#define SI5351_CLK4_CTRL                       20
+#define SI5351_CLK5_CTRL                       21
+#define SI5351_CLK6_CTRL                       22
+#define SI5351_CLK7_CTRL                       23
+#define SI5351_CLK_POWERDOWN                   (1<<7)
+#define SI5351_CLK_INTEGER_MODE                        (1<<6)
+#define SI5351_CLK_PLL_SELECT                  (1<<5)
+#define SI5351_CLK_INVERT                      (1<<4)
+#define SI5351_CLK_INPUT_MASK                  (3<<2)
+#define SI5351_CLK_INPUT_XTAL                  (0<<2)
+#define SI5351_CLK_INPUT_CLKIN                 (1<<2)
+#define SI5351_CLK_INPUT_MULTISYNTH_0_4        (2<<2)
+#define SI5351_CLK_INPUT_MULTISYNTH_N          (3<<2)
+#define SI5351_CLK_DRIVE_STRENGTH_MASK         (3<<0)
+#define SI5351_CLK_DRIVE_STRENGTH_2MA          (0<<0)
+#define SI5351_CLK_DRIVE_STRENGTH_4MA          (1<<0)
+#define SI5351_CLK_DRIVE_STRENGTH_6MA          (2<<0)
+#define SI5351_CLK_DRIVE_STRENGTH_8MA          (3<<0)
+
+#define SI5351_CLK3_0_DISABLE_STATE            24
+#define SI5351_CLK7_4_DISABLE_STATE            25
+#define SI5351_CLK_DISABLE_STATE_MASK          3
+#define SI5351_CLK_DISABLE_STATE_LOW           0
+#define SI5351_CLK_DISABLE_STATE_HIGH          1
+#define SI5351_CLK_DISABLE_STATE_FLOAT         2
+#define SI5351_CLK_DISABLE_STATE_NEVER         3
+
+#define SI5351_PARAMETERS_LENGTH               8
+#define SI5351_PLLA_PARAMETERS                 26
+#define SI5351_PLLB_PARAMETERS                 34
+#define SI5351_CLK0_PARAMETERS                 42
+#define SI5351_CLK1_PARAMETERS                 50
+#define SI5351_CLK2_PARAMETERS                 58
+#define SI5351_CLK3_PARAMETERS                 66
+#define SI5351_CLK4_PARAMETERS                 74
+#define SI5351_CLK5_PARAMETERS                 82
+#define SI5351_CLK6_PARAMETERS                 90
+#define SI5351_CLK7_PARAMETERS                 91
+#define SI5351_CLK6_7_OUTPUT_DIVIDER           92
+#define SI5351_OUTPUT_CLK_DIV_MASK             (7 << 4)
+#define SI5351_OUTPUT_CLK6_DIV_MASK            (7 << 0)
+#define SI5351_OUTPUT_CLK_DIV_SHIFT            4
+#define SI5351_OUTPUT_CLK_DIV6_SHIFT           0
+#define SI5351_OUTPUT_CLK_DIV_1                        0
+#define SI5351_OUTPUT_CLK_DIV_2                        1
+#define SI5351_OUTPUT_CLK_DIV_4                        2
+#define SI5351_OUTPUT_CLK_DIV_8                        3
+#define SI5351_OUTPUT_CLK_DIV_16               4
+#define SI5351_OUTPUT_CLK_DIV_32               5
+#define SI5351_OUTPUT_CLK_DIV_64               46
+#define SI5351_OUTPUT_CLK_DIV_128              7
+#define SI5351_OUTPUT_CLK_DIVBY4               (3<<2)
+
+#define SI5351_SSC_PARAM0                      149
+#define SI5351_SSC_PARAM1                      150
+#define SI5351_SSC_PARAM2                      151
+#define SI5351_SSC_PARAM3                      152
+#define SI5351_SSC_PARAM4                      153
+#define SI5351_SSC_PARAM5                      154
+#define SI5351_SSC_PARAM6                      155
+#define SI5351_SSC_PARAM7                      156
+#define SI5351_SSC_PARAM8                      157
+#define SI5351_SSC_PARAM9                      158
+#define SI5351_SSC_PARAM10                     159
+#define SI5351_SSC_PARAM11                     160
+#define SI5351_SSC_PARAM12                     161
+
+#define SI5351_VXCO_PARAMETERS_LOW             162
+#define SI5351_VXCO_PARAMETERS_MID              163
+#define SI5351_VXCO_PARAMETERS_HIGH             164
+
+#define SI5351_CLK0_PHASE_OFFSET               165
+#define SI5351_CLK1_PHASE_OFFSET               166
+#define SI5351_CLK2_PHASE_OFFSET               167
+#define SI5351_CLK3_PHASE_OFFSET               168
+#define SI5351_CLK4_PHASE_OFFSET               169
+#define SI5351_CLK5_PHASE_OFFSET               170
+
+#define SI5351_PLL_RESET                       177
+#define SI5351_PLL_RESET_B                     (1<<7)
+#define SI5351_PLL_RESET_A                     (1<<5)
+
+#define SI5351_CRYSTAL_LOAD                    183
+#define SI5351_CRYSTAL_LOAD_MASK               (3<<6)
+#define SI5351_CRYSTAL_LOAD_0PF                 (0<<6) 
+#define SI5351_CRYSTAL_LOAD_6PF                 (1<<6)
+#define SI5351_CRYSTAL_LOAD_8PF                (2<<6)
+#define SI5351_CRYSTAL_LOAD_10PF               (3<<6)
+
+#define SI5351_FANOUT_ENABLE                   187
+#define SI5351_CLKIN_ENABLE                    (1<<7)
+#define SI5351_XTAL_ENABLE                     (1<<6)
+#define SI5351_MULTISYNTH_ENABLE               (1<<4)
+
+/* Macro definitions */
+
+#define RFRAC_DENOM ((1L << 20) - 1)
+
+/*
+ * Based on former asm-ppc/div64.h and asm-m68knommu/div64.h
+ *
+ * The semantics of do_div() are:
+ *
+ * uint32_t do_div(uint64_t *n, uint32_t base)
+ * {
+ *      uint32_t remainder = *n % base;
+ *      *n = *n / base;
+ *      return remainder;
+ * }
+ *
+ * NOTE: macro parameter n is evaluated multiple times,
+ *       beware of side effects!
+ */
+
+# define do_div(n,base) ({                                      \
+        uint64_t __base = (base);                               \
+        uint64_t __rem;                                         \
+        __rem = ((uint64_t)(n)) % __base;                       \
+        (n) = ((uint64_t)(n)) / __base;                         \
+        __rem;                                                  \
+ })
+
+/* Enum definitions */
+
+/*
+ * enum si5351_variant - SiLabs Si5351 chip variant
+ * @SI5351_VARIANT_A: Si5351A (8 output clocks, XTAL input)
+ * @SI5351_VARIANT_A3: Si5351A MSOP10 (3 output clocks, XTAL input)
+ * @SI5351_VARIANT_B: Si5351B (8 output clocks, XTAL/VXCO input)
+ * @SI5351_VARIANT_C: Si5351C (8 output clocks, XTAL/CLKIN input)
+ */
+ enum si5351_variant {SI5351_VARIANT_A, SI5351_VARIANT_A3,     SI5351_VARIANT_B,
+   SI5351_VARIANT_C};
+
+ enum si5351_clock {SI5351_CLK0, SI5351_CLK1, SI5351_CLK2, SI5351_CLK3,
+       SI5351_CLK4, SI5351_CLK5, SI5351_CLK6, SI5351_CLK7, SI5351_CLKNONE};
+
+ enum si5351_pll {SI5351_PLLA, SI5351_PLLB};
+
+ enum si5351_drive {SI5351_DRIVE_2MA, SI5351_DRIVE_4MA, SI5351_DRIVE_6MA,
+   SI5351_DRIVE_8MA};
+
+ enum si5351_clock_source {SI5351_CLK_SRC_XTAL, SI5351_CLK_SRC_CLKIN,
+   SI5351_CLK_SRC_MS0, SI5351_CLK_SRC_MS};
+
+ enum si5351_clock_disable {SI5351_CLK_DISABLE_LOW, SI5351_CLK_DISABLE_HIGH,
+   SI5351_CLK_DISABLE_HI_Z, SI5351_CLK_DISABLE_NEVER};
+
+ enum si5351_clock_fanout {SI5351_FANOUT_CLKIN, SI5351_FANOUT_XO,
+   SI5351_FANOUT_MS};
+
+ enum si5351_pll_input{SI5351_PLL_INPUT_XO, SI5351_PLL_INPUT_CLKIN};
+
+/* Struct definitions */
+
+struct Si5351RegSet {
+    uint32_t p1;
+    uint32_t p2;
+    uint32_t p3;
+};
+
+struct Si5351Status {
+    uint8_t SYS_INIT;
+    uint8_t LOL_B;
+    uint8_t LOL_A;
+    uint8_t LOS;
+    uint8_t REVID;
+};
+
+struct Si5351IntStatus {
+    uint8_t SYS_INIT_STKY;
+    uint8_t LOL_B_STKY;
+    uint8_t LOL_A_STKY;
+    uint8_t LOS_STKY;
+};
+
+typedef struct {
+    struct Si5351Status dev_status;
+    struct Si5351IntStatus dev_int_status;
+    uint64_t plla_freq;
+    uint64_t pllb_freq;
+    uint64_t clk0_freq;
+    uint64_t clk1_freq;
+    uint64_t clk2_freq;
+    uint8_t clk0_int_mode, clk1_int_mode, clk2_int_mode;
+    int32_t ref_correction;
+    uint8_t lock_plla, lock_pllb;
+    uint32_t xtal_freq;
+    uint32_t I2C_ErrorCode;
+    uint8_t I2C_add;
+} T_Si5351_data;
+
+
+
+T_Si5351_data   Si5351_Config;
+
+/* private routines */
+
+
+void si5351_write(uint8_t REGaddr, uint8_t data);
+void si5351_write_bulk(uint8_t REGaddr, uint8_t bytes, uint8_t *data);
+uint8_t si5351_read(uint8_t REGaddr);
+uint64_t si5351_multisynth_calc(uint64_t freq, uint64_t pll_freq, struct Si5351RegSet *reg);
+void si5351_set_ms_source(enum si5351_clock clk, enum si5351_pll pll);
+void si5351_set_ms(enum si5351_clock clk, struct Si5351RegSet ms_reg, uint8_t int_mode, uint8_t r_div, uint8_t div_by_4);
+void si5351_set_pll(uint64_t pll_freq, enum si5351_pll target_pll);
+void si5351_ms_div(enum si5351_clock clk, uint8_t r_div, uint8_t div_by_4);
+void si5351_set_int(enum si5351_clock clk, uint8_t enable);
+uint64_t si5351_pll_calc(uint64_t freq, struct Si5351RegSet *reg, int32_t correction);
+uint8_t si5351_select_r_div(uint64_t *freq);
+
+
+/* public routines */
+
+
+
+void si5351_init(uint8_t I2C_Address,  uint8_t xtal_load_c, uint32_t ref_osc_freq);
+void si5351_pll_reset(enum si5351_pll target_pll);
+void si5351_set_clock_pwr(enum si5351_clock clk, uint8_t pwr);
+void si5351_set_clock_invert(enum si5351_clock clk, uint8_t inv);
+uint8_t si5351_set_freq(uint64_t freq_in_Hz_times_100, uint64_t pll_freq, enum si5351_clock clk);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/sine.h b/codec2/branches/0.7/stm32/inc/sine.h
new file mode 100644 (file)
index 0000000..3a3ce46
--- /dev/null
@@ -0,0 +1,48 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sine.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 1/11/94
+
+  Header file for sinusoidal analysis and synthesis functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SINE__
+#define __SINE__
+
+#include "defines.h"
+#include "comp.h"
+#include "kiss_fft.h"
+
+void make_analysis_window(kiss_fft_cfg fft_fwd_cfg, float w[], COMP W[]);
+float hpf(float x, float states[]);
+void dft_speech(kiss_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[]);
+void two_stage_pitch_refinement(MODEL *model, COMP Sw[]);
+void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase);
+float est_voicing_mbe(MODEL *model, COMP Sw[], COMP W[], COMP Sw_[],COMP Ew[],
+                     float prev_Wo);
+void make_synthesis_window(float Pn[]);
+void synthesise(kiss_fft_cfg fft_inv_cfg, float Sn_[], MODEL *model, float Pn[], int shift);
+
+#define CODEC2_RAND_MAX 32767
+int codec2_rand(void);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/sm1000_leds_switches.h b/codec2/branches/0.7/stm32/inc/sm1000_leds_switches.h
new file mode 100644 (file)
index 0000000..a5cbc2a
--- /dev/null
@@ -0,0 +1,86 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sm1000_leds_switches.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 18 July 2014
+
+  Functions for controlling LEDs and reading switches on SM1000.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LEDS_SWITCHES__
+#define __LEDS_SWITCHES__
+
+#include <stdint.h>
+
+void sm1000_leds_switches_init(void);
+
+#define        LED_ON  1       /*!< Turn LED on */
+#define LED_OFF        0       /*!< Turn LED off */
+#define LED_INV        -1      /*!< Invert LED state */
+
+void led_pwr(int state);
+void led_ptt(int state);
+void led_rt(int state);
+void led_err(int state);
+void not_cptt(int state);
+
+int switch_ptt(void);
+int switch_select(void);
+int switch_back(void);
+int ext_ptt(void);
+
+#define DEBOUNCE_DELAY 50 /*!< Delay to wait while switch bounces */
+
+#define SW_STEADY   0   /*!< Switch is in steady-state */
+#define SW_DEBOUNCE 1   /*!< Switch is being debounced */
+
+/*! Switch debounce and logic handling */
+struct switch_t {
+    /*! Debounce/hold timer */
+    uint32_t    timer;
+    /*! Current/debounced observed switch state */
+    uint8_t     sw;
+    /*! Raw observed switch state (during debounce) */
+    uint8_t     raw;
+    /*! Last steady-state switch state */
+    uint8_t     last;
+    /*! Debouncer state */
+    uint8_t     state;
+};
+
+/*! Update the state of a switch */
+void switch_update(struct switch_t* const sw, uint8_t state);
+
+/*! Acknowledge the current state of the switch */
+void switch_ack(struct switch_t* const sw);
+
+/*! Return how long the switch has been pressed in ticks. */
+uint32_t switch_pressed(const struct switch_t* const sw);
+
+/*! Return non-zero if the switch has been released. */
+int switch_released(const struct switch_t* const sw);
+
+/*! Count the tick timers on the switches. */
+void switch_tick(struct switch_t* const sw);
+
+void ColorfulRingOfDeath(int code);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/sounds.h b/codec2/branches/0.7/stm32/inc/sounds.h
new file mode 100644 (file)
index 0000000..9ccfeb7
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _SOUNDS_H
+#define _SOUNDS_H
+/*!
+ * Sound effect library.
+ *
+ * This provides some sound effects for the SM1000 UI.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "sfx.h"
+
+/*! Start-up tune / selected tune */
+extern const struct sfx_note_t sound_startup[];
+
+/*! Returned tune */
+extern const struct sfx_note_t sound_returned[];
+
+/*! Click sound */
+extern const struct sfx_note_t sound_click[];
+
+/*! Death march tune */
+extern const struct sfx_note_t sound_death_march[];
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/stm32f4_adc.h b/codec2/branches/0.7/stm32/inc/stm32f4_adc.h
new file mode 100644 (file)
index 0000000..9578873
--- /dev/null
@@ -0,0 +1,46 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_adc.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 30 May 2014
+
+  Two channel FIFO buffered ADC driver module for STM32F4.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STM32F4_ADC__
+#define __STM32F4_ADC__
+
+#define ADC_BUF_SZ   320
+
+/* divisors for various sample rates */
+
+#define ADC_FS_8KHZ 10500
+#define ADC_FS_16KHZ 5250
+#define ADC_FS_48KHZ 1750
+#define ADC_FS_96KHZ 875
+
+void adc_open(int fs_divisor, int fifo_sz);
+int adc1_read(short buf[], int n); /* ADC1 Pin PA1 */
+int adc2_read(short buf[], int n); /* ADC2 Pin PA2 */
+int adc1_samps();
+int adc2_samps();
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/stm32f4_adc_tuner.h b/codec2/branches/0.7/stm32/inc/stm32f4_adc_tuner.h
new file mode 100644 (file)
index 0000000..a258b9d
--- /dev/null
@@ -0,0 +1,40 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_adc_tuner.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 19 Feb 2015
+
+  Single channel ADC driver module for STM32F4 that samples pin PA1 at
+  2 MHz and down converts to 50 kHz, with "tuning" centred at 500 kHz.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STM32F4_ADC_TUNER__
+#define __STM32F4_ADC_TUNER__
+
+#define ADC_TUNER_M  45   /* decimation rate */
+#define ADC_TUNER_N  160
+#define ADC_TUNER_BUF_SZ  (ADC_TUNER_M*ADC_TUNER_N)
+
+void adc_open(int fifo_sz);
+int adc1_read(short buf[], int n); /* ADC1 Pin PA1 */
+void adc_set_tuner_en(short flag); /* disable tuner to get raw ADC samples written to fifo */
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/stm32f4_dac.h b/codec2/branches/0.7/stm32/inc/stm32f4_dac.h
new file mode 100644 (file)
index 0000000..9cb240b
--- /dev/null
@@ -0,0 +1,46 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_dac.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 June 2013
+
+  Two channel FIFO buffered DAC driver module for STM32F4.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STM32F4_DAC__
+#define __STM32F4_DAC__
+
+#define DAC_BUF_SZ   320
+
+/* divisors for various sample rates */
+
+#define DAC_FS_8KHZ 10500
+#define DAC_FS_16KHZ 5250
+#define DAC_FS_48KHZ 1750
+#define DAC_FS_96KHZ 875
+
+void dac_open(int fs_divisor, int fifo_sz);
+int dac1_write(short buf[], int n); /* DAC1 pin PA4 */
+int dac1_free();
+int dac2_write(short buf[], int n); /* DAC2 pin PA5 */
+int dac2_free();
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/stm32f4_dacduc.h b/codec2/branches/0.7/stm32/inc/stm32f4_dacduc.h
new file mode 100644 (file)
index 0000000..6a1ba20
--- /dev/null
@@ -0,0 +1,42 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_dac.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 June 2013
+
+  Two channel FIFO buffered DAC driver module for STM32F4. DAC1 is fixed at
+  Fs=2Mhz
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __STM32F4_DAC__
+#define __STM32F4_DAC__
+
+#define DUC_N 160
+#define DUC_M  25
+#define DUC_48N 96                     //This is 3/5th DUC_N
+#define DAC_DUC_BUF_SZ DUC_M*DUC_N
+#define DAC_BUF_SZ 2048
+
+void fast_dac_open(int dac1_fifo_size,int dac2_fifo_size);
+int dac1_write(short buf[], int n); /* DAC1 pin PA4 */
+int dac2_write(short buf[], int n); /* DAC2 pin PA5 */
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/stm32f4_usb_vcp.h b/codec2/branches/0.7/stm32/inc/stm32f4_usb_vcp.h
new file mode 100644 (file)
index 0000000..d742ebc
--- /dev/null
@@ -0,0 +1,24 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_usb_vcp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 4 Sep 2014
+
+  USB Virtual COM Port (VCP) module.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef __STM32F4_USB_VCP__
+#define __STM32F4_USB_VCP__
+
+#include <stdint.h>
+
+void usb_vcp_init(void);
+
+int VCP_get_char(uint8_t *buf);
+int VCP_get_string(uint8_t *buf);
+void VCP_put_char(uint8_t buf);
+void VCP_send_str(uint8_t* buf);
+void VCP_send_buffer(uint8_t* buf, int len);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/stm32f4_vrom.h b/codec2/branches/0.7/stm32/inc/stm32f4_vrom.h
new file mode 100644 (file)
index 0000000..e878b9c
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef _STM32F4_VROM_H_
+#define _STM32F4_VROM_H_
+/*!
+ * STM32F4 Virtual EEPROM driver
+ *
+ * This module implements a crude virtual EEPROM device stored in on-board
+ * flash.  The STM32F405 has 4 16kB flash sectors starting at address
+ * 0x80000000, followed by a 64kB sector, then 128kB sectors.
+ *
+ * The Cortex M4 core maps these all to address 0x00000000 when booting
+ * from normal flash, so the first sector is reserved for interrupt
+ * vectors.
+ *
+ * Everything else however is free game, and so we use these smaller
+ * sectors to store our configuration.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+#include <errno.h>
+
+/*!
+ * Read data from a virtual EEPROM.
+ * @param      rom             ROM ID to start reading.
+ * @param      offset          Address offset into ROM to start reading.
+ * @param      size            Number of bytes to read from ROM.
+ * @param      out             Buffer to write ROM content to.
+ * @returns                    Number of bytes read from ROM.
+ * @retval     -ENXIO          No valid data found for address.
+ * @retval     -ESPIPE         Offset past end of ROM.
+ */
+int vrom_read(uint8_t rom, uint16_t offset, uint16_t size, void* out);
+
+/*!
+ * Write data to a virtual EEPROM.
+ * @param      rom             ROM ID to start writing.
+ * @param      offset          Address offset into ROM to start writing.
+ * @param      size            Number of bytes to write to ROM.
+ * @param      in              Buffer to write ROM content from.
+ * @returns                    Number of bytes written to ROM.
+ * @retval     -EIO            Programming failed
+ * @retval     -ENOSPC         No free blocks available
+ */
+int vrom_write(uint8_t rom, uint16_t offset, uint16_t size,
+               const void* in);
+
+/*!
+ * Erase a virtual EEPROM.
+ * @param      rom             ROM ID to erase.
+ * @returns                    Number of bytes written to ROM.
+ * @retval     -EIO            Programming failed
+ * @retval     -ENOSPC         No free blocks available
+ */
+int vrom_erase(uint8_t rom);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/stm32f4xx_conf.h b/codec2/branches/0.7/stm32/inc/stm32f4xx_conf.h
new file mode 100644 (file)
index 0000000..69047b1
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_conf.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    19-September-2011
+  * @brief   Library configuration file.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_CONF_H
+#define __STM32F4xx_CONF_H
+
+#if defined  (HSE_VALUE)
+/* Redefine the HSE value; it's equal to 8 MHz on the STM32F4-DISCOVERY Kit */
+ #undef HSE_VALUE
+ #define HSE_VALUE    ((uint32_t)8000000)
+#endif /* HSE_VALUE */
+
+/* Includes ------------------------------------------------------------------*/
+/* Uncomment the line below to enable peripheral header file inclusion */
+#include "stm32f4xx_adc.h"
+#include "stm32f4xx_can.h"
+#include "stm32f4xx_crc.h"
+#include "stm32f4xx_cryp.h"
+#include "stm32f4xx_dac.h"
+#include "stm32f4xx_dbgmcu.h"
+#include "stm32f4xx_dcmi.h"
+#include "stm32f4xx_dma.h"
+#include "stm32f4xx_exti.h"
+#include "stm32f4xx_flash.h"
+#include "stm32f4xx_fsmc.h"
+#include "stm32f4xx_hash.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_i2c.h"
+#include "stm32f4xx_iwdg.h"
+#include "stm32f4xx_pwr.h"
+#include "stm32f4xx_rcc.h"
+#include "stm32f4xx_rng.h"
+#include "stm32f4xx_rtc.h"
+#include "stm32f4xx_sdio.h"
+#include "stm32f4xx_spi.h"
+#include "stm32f4xx_syscfg.h"
+#include "stm32f4xx_tim.h"
+#include "stm32f4xx_usart.h"
+#include "stm32f4xx_wwdg.h"
+#include "misc.h" /* High level functions for NVIC and SysTick (add-on to CMSIS functions) */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* If an external clock source is used, then the value of the following define
+   should be set to the value of the external clock source, else, if no external
+   clock is used, keep this define commented */
+/*#define I2S_EXTERNAL_CLOCK_VAL   12288000 */ /* Value of the external clock in Hz */
+
+
+/* Uncomment the line below to expanse the "assert_param" macro in the
+   Standard Peripheral Library drivers code */
+/* #define USE_FULL_ASSERT    1 */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef  USE_FULL_ASSERT
+
+/**
+  * @brief  The assert_param macro is used for function's parameters check.
+  * @param  expr: If expr is false, it calls assert_failed function
+  *   which reports the name of the source file and the source
+  *   line number of the call that failed.
+  *   If expr is true, it returns no value.
+  * @retval None
+  */
+  #define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+  void assert_failed(uint8_t* file, uint32_t line);
+#else
+  #define assert_param(expr) ((void)0)
+#endif /* USE_FULL_ASSERT */
+
+#endif /* __STM32F4xx_CONF_H */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/inc/tm_stm32f4_gpio.h b/codec2/branches/0.7/stm32/inc/tm_stm32f4_gpio.h
new file mode 100644 (file)
index 0000000..4626878
--- /dev/null
@@ -0,0 +1,429 @@
+/** 
+ * @author  Tilen Majerle
+ * @email   tilen@majerle.eu
+ * @website http://stm32f4-discovery.com
+ * @link    http://stm32f4-discovery.com/2015/03/library-53-gpio-for-stm32f4
+ * @version v1.5
+ * @ide     Keil uVision
+ * @license GNU GPL v3
+ * @brief   GPIO Library for STM32F4xx devices
+ *
+@verbatim
+   ----------------------------------------------------------------------
+    Copyright (C) Tilen Majerle, 2015
+    
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    any later version.
+     
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+    
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+   ----------------------------------------------------------------------
+@endverbatim
+ */
+#ifndef TM_GPIO_H
+#define TM_GPIO_H 150
+
+/* C++ detection */
+#ifdef __cplusplus
+extern "C" {
+#endif
+       
+/**
+ * @addtogroup TM_STM32F4xx_Libraries
+ * @{
+ */
+
+/**
+ * @defgroup TM_GPIO
+ * @brief    TM GPIO Library for STM32F4xx - http://stm32f4-discovery.com/2015/03/library-53-gpio-for-stm32f4
+ * @{
+ *
+ * GPIO library can be used for GPIO pins. 
+ *
+ * It features fast initialization methods as well pin input/output methods.
+ *
+ * It can be used as replacement for STD/HAL drivers GPIO library.
+ *
+ * \par Changelog
+ *
+@verbatim
+ Version 1.5
+  - June 10 2015
+  - Added 2 new functions for getting used GPIO pins
+  
+ Version 1.4
+  - April 28, 2015
+  - Added support for PORT locking
+  
+ Version 1.3
+  - March 23, 2015
+  - Totally independent from HAL / SPD drivers
+  - Library can be used with any drivers or totally itself
+  
+ Version 1.2
+  - March 10, 2015
+  - Added functions TM_GPIO_SetPinAsInput and TM_GPIO_SetPinAsOutput
+  - Added functions TM_GPIO_GetPortSource and TM_GPIO_GetPinSource
+0
+ Version 1.1
+  - March 09, 2015
+  - Added function to deinit pin. Pin is set to analog input which allows lowest current consumption
+  
+ Version 1.0
+  - March 08, 2015
+  - Initial release
+@endverbatim
+ *
+ * \par Dependencies
+ *
+@verbatim
+ - STM32F4xx
+ - STM32F4xx GPIO
+ - defines.h
+@endverbatim
+ */
+
+#include "stm32f4xx.h"
+#include "stm32f4xx_gpio.h"
+#include "defines.h"
+
+/**
+ * @defgroup TM_GPIO_Macros
+ * @brief    GPIO Library macros
+ * @{
+ */
+
+/**
+ * @brief GPIO Pins declarations 
+ * @note  For HAL drivers compatibility
+ */
+  
+#ifndef GPIO_PIN_0
+#define GPIO_PIN_0             ((uint16_t)0x0001)
+#define GPIO_PIN_1             ((uint16_t)0x0002)
+#define GPIO_PIN_2             ((uint16_t)0x0004)
+#define GPIO_PIN_3             ((uint16_t)0x0008)
+#define GPIO_PIN_4             ((uint16_t)0x0010)
+#define GPIO_PIN_5             ((uint16_t)0x0020)
+#define GPIO_PIN_6             ((uint16_t)0x0040)
+#define GPIO_PIN_7             ((uint16_t)0x0080)
+#define GPIO_PIN_8             ((uint16_t)0x0100)
+#define GPIO_PIN_9             ((uint16_t)0x0200)
+#define GPIO_PIN_10            ((uint16_t)0x0400)
+#define GPIO_PIN_11            ((uint16_t)0x0800)
+#define GPIO_PIN_12            ((uint16_t)0x1000)
+#define GPIO_PIN_13            ((uint16_t)0x2000)
+#define GPIO_PIN_14            ((uint16_t)0x4000)
+#define GPIO_PIN_15            ((uint16_t)0x8000)
+#define GPIO_PIN_ALL   ((uint16_t)0xFFFF)
+#endif
+
+/**
+ * @brief GPIO Pins declarations 
+ * @note  For STD Periph drivers compatibility
+ */
+
+#ifndef GPIO_Pin_0
+#define GPIO_Pin_0             ((uint16_t)0x0001)
+#define GPIO_Pin_1             ((uint16_t)0x0002)
+#define GPIO_Pin_2             ((uint16_t)0x0004)
+#define GPIO_Pin_3             ((uint16_t)0x0008)
+#define GPIO_Pin_4             ((uint16_t)0x0010)
+#define GPIO_Pin_5             ((uint16_t)0x0020)
+#define GPIO_Pin_6             ((uint16_t)0x0040)
+#define GPIO_Pin_7             ((uint16_t)0x0080)
+#define GPIO_Pin_8             ((uint16_t)0x0100)
+#define GPIO_Pin_9             ((uint16_t)0x0200)
+#define GPIO_Pin_10            ((uint16_t)0x0400)
+#define GPIO_Pin_11            ((uint16_t)0x0800)
+#define GPIO_Pin_12            ((uint16_t)0x1000)
+#define GPIO_Pin_13            ((uint16_t)0x2000)
+#define GPIO_Pin_14            ((uint16_t)0x4000)
+#define GPIO_Pin_15            ((uint16_t)0x8000)
+#define GPIO_Pin_All   ((uint16_t)0xFFFF)
+#endif
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup TM_GPIO_Typedefs
+ * @brief    GPIO Typedefs used for GPIO library for initialization purposes
+ * @{
+ */
+
+/**
+ * @brief GPIO Mode enumeration
+ */
+typedef enum {
+       TM_GPIO_Mode_IN = 0x00,  /*!< GPIO Pin as General Purpose Input */
+       TM_GPIO_Mode_OUT = 0x01, /*!< GPIO Pin as General Purpose Output */
+       TM_GPIO_Mode_AF = 0x02,  /*!< GPIO Pin as Alternate Function */
+       TM_GPIO_Mode_AN = 0x03,  /*!< GPIO Pin as Analog */
+} TM_GPIO_Mode_t;
+
+/**
+ * @brief GPIO Output type enumeration
+ */
+typedef enum {
+       TM_GPIO_OType_PP = 0x00, /*!< GPIO Output Type Push-Pull */
+       TM_GPIO_OType_OD = 0x01  /*!< GPIO Output Type Open-Drain */
+} TM_GPIO_OType_t;
+
+/**
+ * @brief  GPIO Speed enumeration
+ */
+typedef enum {
+       TM_GPIO_Speed_Low = 0x00,    /*!< GPIO Speed Low */
+       TM_GPIO_Speed_Medium = 0x01, /*!< GPIO Speed Medium */
+       TM_GPIO_Speed_Fast = 0x02,   /*!< GPIO Speed Fast */
+       TM_GPIO_Speed_High = 0x03    /*!< GPIO Speed High */
+} TM_GPIO_Speed_t;
+
+/**
+ * @brief GPIO pull resistors enumeration
+ */
+typedef enum {
+       TM_GPIO_PuPd_NOPULL = 0x00, /*!< No pull resistor */
+       TM_GPIO_PuPd_UP = 0x01,     /*!< Pull up resistor enabled */
+       TM_GPIO_PuPd_DOWN = 0x02    /*!< Pull down resistor enabled */
+} TM_GPIO_PuPd_t;
+
+/**
+ * @} TM_GPIO_Typedefs
+ */
+
+/**
+ * @defgroup TM_GPIO_Functions
+ * @brief    GPIO Functions
+ * @{
+ */
+/**
+ * @brief  Initializes GPIO pins(s)
+ * @note   This function also enables clock for GPIO port
+ * @param  GPIOx: Pointer to GPIOx port you will use for initialization
+ * @param  GPIO_Pin: GPIO pin(s) you will use for initialization
+ * @param  GPIO_Mode: Select GPIO mode. This parameter can be a value of @ref TM_GPIO_Mode_t enumeration
+ * @param  GPIO_OType: Select GPIO Output type. This parameter can be a value of @ref TM_GPIO_OType_t enumeration
+ * @param  GPIO_PuPd: Select GPIO pull resistor. This parameter can be a value of @ref TM_GPIO_PuPd_t enumeration
+ * @param  GPIO_Speed: Select GPIO speed. This parameter can be a value of @ref TM_GPIO_Speed_t enumeration
+ * @retval None
+ */
+void TM_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed);
+
+/**
+ * @brief  Initializes GPIO pins(s) as alternate function
+ * @note   This function also enables clock for GPIO port
+ * @param  GPIOx: Pointer to GPIOx port you will use for initialization
+ * @param  GPIO_Pin: GPIO pin(s) you will use for initialization
+ * @param  GPIO_OType: Select GPIO Output type. This parameter can be a value of @ref TM_GPIO_OType_t enumeration
+ * @param  GPIO_PuPd: Select GPIO pull resistor. This parameter can be a value of @ref TM_GPIO_PuPd_t enumeration
+ * @param  GPIO_Speed: Select GPIO speed. This parameter can be a value of @ref TM_GPIO_Speed_t enumeration
+ * @param  Alternate: Alternate function you will use
+ * @retval None
+ */
+void TM_GPIO_InitAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed, uint8_t Alternate);
+
+/**
+ * @brief  Deinitializes pin(s)
+ * @note   Pins(s) will be set as analog mode to get low power consumption
+ * @param  GPIOx: GPIOx PORT where you want to set pin as input
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them as input
+ * @retval None
+ */
+void TM_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/**
+ * @brief  Sets pin(s) as input 
+ * @note   Pins HAVE to be initialized first using @ref TM_GPIO_Init() or @ref TM_GPIO_InitAlternate() function
+ * @note   This is just an option for fast input mode
+ * @param  GPIOx: GPIOx PORT where you want to set pin as input
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them as input
+ * @retval None
+ */
+void TM_GPIO_SetPinAsInput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/**
+ * @brief  Sets pin(s) as output
+ * @note   Pins HAVE to be initialized first using @ref TM_GPIO_Init() or @ref TM_GPIO_InitAlternate() function
+ * @note   This is just an option for fast output mode 
+ * @param  GPIOx: GPIOx PORT where you want to set pin as output
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them as output
+ * @retval None
+ */
+void TM_GPIO_SetPinAsOutput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/**
+ * @brief  Sets pin(s) as analog
+ * @note   Pins HAVE to be initialized first using @ref TM_GPIO_Init() or @ref TM_GPIO_InitAlternate() function
+ * @note   This is just an option for fast analog mode 
+ * @param  GPIOx: GPIOx PORT where you want to set pin as analog
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them as analog
+ * @retval None
+ */
+void TM_GPIO_SetPinAsAnalog(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/** 
+ * @brief  Sets pin(s) as alternate function
+ * @note   For proper alternate function, you should first init pin using @ref TM_GPIO_InitAlternate() function.
+ *            This functions is only used for changing GPIO mode
+ * @param  GPIOx: GPIOx PORT where you want to set pin as alternate
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them as alternate
+ * @retval None
+ */
+void TM_GPIO_SetPinAsAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/**
+ * @brief  Sets pull resistor settings to GPIO pin(s)
+ * @note   Pins HAVE to be initialized first using @ref TM_GPIO_Init() or @ref TM_GPIO_InitAlternate() function
+ * @param  *GPIOx: GPIOx PORT where you want to select pull resistor
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them as output
+ * @param  GPIO_PuPd: Pull resistor option. This parameter can be a value of @ref TM_GPIO_PuPd_t enumeration
+ * @retval None
+ */
+void TM_GPIO_SetPullResistor(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_PuPd_t GPIO_PuPd);
+
+/**
+ * @brief  Sets pin(s) low
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to set pin low
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them low
+ * @retval None
+ */
+#define TM_GPIO_SetPinLow(GPIOx, GPIO_Pin)                     ((GPIOx)->BSRRH = (GPIO_Pin))
+
+/**
+ * @brief  Sets pin(s) high
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to set pin high
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them high
+ * @retval None
+ */
+#define TM_GPIO_SetPinHigh(GPIOx, GPIO_Pin)            ((GPIOx)->BSRRL = (GPIO_Pin))
+
+/**
+ * @brief  Sets pin(s) value
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to set pin value
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to set them value
+ * @param  val: If parameter is 0 then pin will be low, otherwise high
+ * @retval None
+ */
+#define TM_GPIO_SetPinValue(GPIOx, GPIO_Pin, val)      ((val) ? TM_GPIO_SetPinHigh(GPIOx, GPIO_Pin) : TM_GPIO_SetPinLow(GPIOx, GPIO_Pin))
+
+/**
+ * @brief  Toggles pin(s)
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to toggle pin value
+ * @param  GPIO_Pin: Select GPIO pin(s). You can select more pins with | (OR) operator to toggle them all at a time
+ * @retval None
+ */
+#define TM_GPIO_TogglePinValue(GPIOx, GPIO_Pin)                ((GPIOx)->ODR ^= (GPIO_Pin))
+
+/**
+ * @brief  Sets value to entire GPIO PORT
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to set value
+ * @param  value: Value for GPIO OUTPUT data
+ * @retval None
+ */
+#define TM_GPIO_SetPortValue(GPIOx, value)                     ((GPIOx)->ODR = (value))
+
+/**
+ * @brief  Gets input data bit
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to read input bit value
+ * @param  GPIO_Pin: GPIO pin where you want to read value
+ * @retval 1 in case pin is high, or 0 if low
+ */
+#define TM_GPIO_GetInputPinValue(GPIOx, GPIO_Pin)      (((GPIOx)->IDR & (GPIO_Pin)) == 0 ? 0 : 1)
+
+/**
+ * @brief  Gets output data bit
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to read output bit value
+ * @param  GPIO_Pin: GPIO pin where you want to read value
+ * @retval 1 in case pin is high, or 0 if low
+ */
+#define TM_GPIO_GetOutputPinValue(GPIOx, GPIO_Pin)     (((GPIOx)->ODR & (GPIO_Pin)) == 0 ? 0 : 1)
+
+/**
+ * @brief  Gets input value from entire GPIO PORT
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to read input data value
+ * @retval Entire PORT INPUT register
+ */
+#define TM_GPIO_GetPortInputValue(GPIOx)                       ((GPIOx)->IDR)
+
+/**
+ * @brief  Gets output value from entire GPIO PORT
+ * @note   Defined as macro to get maximum speed using register access
+ * @param  GPIOx: GPIOx PORT where you want to read output data value
+ * @retval Entire PORT OUTPUT register
+ */
+#define TM_GPIO_GetPortOutputValue(GPIOx)                      ((GPIOx)->ODR)
+
+/**
+ * @brief  Gets port source from desired GPIOx PORT
+ * @note   Meant for private use, unless you know what are you doing
+ * @param  GPIOx: GPIO PORT for calculating port source
+ * @retval Calculated port source for GPIO
+ */
+uint16_t TM_GPIO_GetPortSource(GPIO_TypeDef* GPIOx);
+
+/**
+ * @brief  Gets pin source from desired GPIO pin
+ * @note   Meant for private use, unless you know what are you doing
+ * @param  GPIO_Pin: GPIO pin for calculating port source
+ * @retval Calculated pin source for GPIO pin
+ */
+uint16_t TM_GPIO_GetPinSource(uint16_t GPIO_Pin);
+
+/**
+ * @brief  Locks GPIOx register for future changes
+ * @note   You are not able to config GPIO registers until new MCU reset occurs
+ * @param  *GPIOx: GPIOx PORT where you want to lock config registers
+ * @param  GPIO_Pin: GPIO pin(s) where you want to lock config registers
+ * @retval None
+ */
+void TM_GPIO_Lock(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
+
+/** 
+ * @brief  Gets bit separated pins which were used at least once in library and were not deinitialized
+ * @param  *GPIOx: Pointer to GPIOx peripheral where to check used GPIO pins
+ * @retval Bit values for used pins
+ */
+uint16_t TM_GPIO_GetUsedPins(GPIO_TypeDef* GPIOx);
+
+/** 
+ * @brief  Gets bit separated pins which were not used at in library or were deinitialized
+ * @param  *GPIOx: Pointer to GPIOx peripheral where to check used GPIO pins
+ * @retval Bit values for free pins
+ */
+uint16_t TM_GPIO_GetFreePins(GPIO_TypeDef* GPIOx);
+
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+/**
+ * @}
+ */
+
+/* C++ detection */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/tm_stm32f4_mco_output.h b/codec2/branches/0.7/stm32/inc/tm_stm32f4_mco_output.h
new file mode 100644 (file)
index 0000000..3ce2f0b
--- /dev/null
@@ -0,0 +1,188 @@
+/**\r
+ * @author  Tilen Majerle\r
+ * @email   tilen@majerle.eu\r
+ * @website http://stm32f4-discovery.com\r
+ * @link    http://stm32f4-discovery.com/2014/10/library-40-output-clocks-stm32f4/\r
+ * @version v1.1\r
+ * @ide     Keil uVision\r
+ * @license GNU GPL v3\r
+ * @brief   MCO Output for STM32F4xx\r
+ *     \r
+@verbatim\r
+   ----------------------------------------------------------------------\r
+    Copyright (C) Tilen Majerle, 2015\r
+    \r
+    This program is free software: you can redistribute it and/or modify\r
+    it under the terms of the GNU General Public License as published by\r
+    the Free Software Foundation, either version 3 of the License, or\r
+    any later version.\r
+     \r
+    This program is distributed in the hope that it will be useful,\r
+    but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+    GNU General Public License for more details.\r
+    \r
+    You should have received a copy of the GNU General Public License\r
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+   ----------------------------------------------------------------------\r
+@endverbatim\r
+ */\r
+#ifndef TM_MCOOUTPUT_H\r
+#define TM_MCOOUTPUT_H 110\r
+\r
+/* C++ detection */\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/**\r
+ * @addtogroup TM_STM32F4xx_Libraries\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @defgroup TM_MCO\r
+ * @brief    MCO Output clock for STM32F4xx - http://stm32f4-discovery.com/2014/10/library-40-output-clocks-stm32f4/\r
+ * @{\r
+ *\r
+ * This library allows you to output different frequencies. They are split into 2 different output sections.\r
+ *\r
+ * \par MCO1 output = PA8\r
+ *\r
+ * MCO1 output\r
+ *     - Pin PA8\r
+ *     - HSI: High Speed Internal clock, 16MHz RC oscillator\r
+ *     - HSE: High Speed External clock, external crystal or user clock\r
+ *     - LSE: External 32738Hz low-speed oscillator or ceramic resonator\r
+ *     - PLLCLK: Output from PLL\r
+ *\r
+ * \par MCO2 output = PC9\r
+ *\r
+ * MCO2 output\r
+ *     - Pin PC9\r
+ *     - SYSCLK: Output system core clock\r
+ *     - PLLI2SCLK: Accurate clock for high-quality audio performance in I2S and SAI interfaces\r
+ *     - HSE: High Speed External clock, external crystal or user clock\r
+ *     - PLLCLK: Output from PLL\r
+ *\r
+ * \par Changelog\r
+ *\r
+@verbatim\r
+ Version 1.1\r
+  - March 11, 2015\r
+  - Support for my new GPIO library\r
+\r
+ Version 1.0\r
+  - First release\r
+@endverbatim\r
+ *\r
+ * \par Dependencies\r
+ *\r
+@verbatim\r
+ - STM32F4xx\r
+ - STM32F4xx RCC\r
+ - defines.h\r
+ - TM GPIO\r
+@endverbatim\r
+ */\r
+#include "stm32f4xx.h"\r
+#include "stm32f4xx_rcc.h"\r
+#include "defines.h"\r
+#include "tm_stm32f4_gpio.h"\r
+\r
\r
+/**\r
+ * @defgroup TM_MCO_Typedefs\r
+ * @brief    Library Typedefs\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief  Prescaler values for output clock\r
+ */\r
+typedef enum {\r
+       TM_MCOOUTPUT_Prescaler_1, /*!< Output original value of clock on MCO pin */\r
+       TM_MCOOUTPUT_Prescaler_2, /*!< Output clock is original / 2 */\r
+       TM_MCOOUTPUT_Prescaler_3, /*!< Output clock is original / 3 */\r
+       TM_MCOOUTPUT_Prescaler_4, /*!< Output clock is original / 4 */\r
+       TM_MCOOUTPUT_Prescaler_5  /*!< Output clock is original / 5 */\r
+} TM_MCOOUTPUT_Prescaler_t;\r
+\r
+/**\r
+ * @brief  Possible output clocks on MCO1 pin\r
+ */\r
+typedef enum {\r
+       TM_MCOOUTPUT1_Source_HSI,   /*!< High Speed Internal clock, 16MHz RC oscillator */\r
+       TM_MCOOUTPUT1_Source_HSE,   /*!< High Speed External clock, external crystal or user clock */\r
+       TM_MCOOUTPUT1_Source_LSE,   /*!< External 32738Hz low-speed oscillator or ceramic resonator */\r
+       TM_MCOOUTPUT1_Source_PLLCLK /*!< Output from PLL */\r
+} TM_MCOOUTPUT1_Source_t;\r
+\r
+/**\r
+ * @brief  Possible output clocks on MCO2 pin\r
+ */\r
+typedef enum {\r
+       TM_MCOOUTPUT2_Source_SYSCLK,    /*!< System core clock */\r
+       TM_MCOOUTPUT2_Source_PLLI2SCLK, /*!< Accurate clock for high-quality audio performance in I2S and SAI interfaces */\r
+       TM_MCOOUTPUT2_Source_HSE,       /*!< High Speed External clock, external crystal or user clock */\r
+       TM_MCOOUTPUT2_Source_PLLCLK     /*!< Output from PLL */\r
+} TM_MCOOUTPUT2_Source_t;\r
+\r
+/**\r
+ * @}\r
+ */\r
+\r
+/**\r
+ * @defgroup TM_MCO_Functions\r
+ * @brief    Library Functions\r
+ * @{\r
+ */\r
+\r
+/**\r
+ * @brief  Initializes and prepares MCO1 pin to output clock\r
+ * @param  None\r
+ * @retval None\r
+ */\r
+void TM_MCOOUTPUT_InitMCO1(void);\r
+\r
+/**\r
+ * @brief  Sets output for MCO1 pin\r
+ * @param  Source: Clock source to output. This parameter can be a value of @ref TM_MCOOUTPUT1_Source_t enumeration.\r
+ * @param  Prescaler: Prescaler used for clock. This parameter can be a value of @ref TM_MCOOUTPUT_Prescaler_t enumeration.\r
+ * @retval None\r
+ */\r
+void TM_MCOOUTPUT_SetOutput1(TM_MCOOUTPUT1_Source_t Source, TM_MCOOUTPUT_Prescaler_t Prescaler);\r
+\r
+/**\r
+ * @brief  Initializes and prepares MCO2 pin to output clock\r
+ * @param  None\r
+ * @retval None\r
+ */\r
+void TM_MCOOUTPUT_InitMCO2(void);\r
\r
+/**\r
+ * @brief  Sets output for MCO2 pin\r
+ * @param  Source: Clock source to output. This parameter can be a value of @ref TM_MCOOUTPUT2_Source_t enumeration.\r
+ * @param  Prescaler: Prescaler used for clock. This parameter can be a value of @ref TM_MCOOUTPUT_Prescaler_t enumeration.\r
+ * @retval None\r
+ */\r
+void TM_MCOOUTPUT_SetOutput2(TM_MCOOUTPUT2_Source_t Source, TM_MCOOUTPUT_Prescaler_t Prescaler);\r
+\r
+/**\r
+ * @}\r
+ */\r
\r
+/**\r
+ * @}\r
+ */\r
\r
+/**\r
+ * @}\r
+ */\r
+\r
+/* C++ detection */\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/codec2/branches/0.7/stm32/inc/tone.h b/codec2/branches/0.7/stm32/inc/tone.h
new file mode 100644 (file)
index 0000000..b7441ca
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef _TONE_H
+#define _TONE_H
+/*!
+ * Fixed-point tone generator.
+ *
+ * The code here implements a simple fixed-point tone generator that uses
+ * integer arithmetic to generate a sinusoid at a fixed sample rate of
+ * 16kHz.
+ *
+ * To set the initial state of the state machine, you specify a frequency
+ * and duration using tone_reset.  The corresponding C file embeds a
+ * sinusoid look-up table.  The total number of samples is computed for
+ * the given time and used to initialise 'remain', 'time' is initialised
+ * to 0, and 'step' gives the amount to increment 'time' by each iteration.
+ *
+ * The samples are retrieved by repeatedly calling tone_next.  This
+ * advances 'time' and decrements 'remain'.  The tone is complete when
+ * 'remain' is zero.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+
+/*! Tone sampling rate in Hz. */
+#define TONE_FS        16000
+
+/*!
+ * Tone generator state.  This holds the current state of the tone
+ * generator in order to decide what sample to release next.
+ */
+struct tone_gen_t {
+       /*! Current sample.  (Q12) */
+       uint32_t        sample;
+       /*!
+        * Time remaining in samples. (integer)  Playback is finished
+        * when this reaches zero.
+        */
+       uint16_t        remain;
+       /*!
+        * Subsample step (Q12).  This is the number of samples (or part
+        * thereof) to advance "sample".  Special case: when zero, sample
+        * is not advanced, silence is generated instead.
+        */
+       uint16_t        step;
+};
+
+/*!
+ * Re-set the tone generator.
+ *
+ * @param      tone_gen        Tone generator to reset.
+ * @param      freq            Frequency in Hz, 0 = silence.
+ * @param      duration        Duration in milliseconds.  0 to stop.
+ */
+void tone_reset(
+       struct tone_gen_t* const tone_gen,
+       uint16_t freq, uint16_t duration);
+
+/*!
+ * Retrieve the next sample from the tone generator.
+ * @param      tone_gen        Tone generator to update.
+ */
+int16_t tone_next(
+       struct tone_gen_t* const tone_gen);
+
+/*!
+ * Retrieve the current time in milliseconds.
+ */
+uint32_t tone_msec(const struct tone_gen_t* const tone_gen);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/inc/tot.h b/codec2/branches/0.7/stm32/inc/tot.h
new file mode 100644 (file)
index 0000000..ad635b0
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef _TOT_H
+#define _TOT_H
+/*!
+ * Time-out timer.
+ *
+ * This is a simple time-out timer for ensuring a maximum transmission
+ * time is observed.  The time-out timer is configured with a total time
+ * in "ticks", which get counted down in an interrupt.
+ *
+ * When the "warning" level is reached, a flag is repeatedly set permit
+ * triggering of LEDs/sounds to warn the user that time is nearly up.
+ *
+ * Upon timeout, a separate flag is set to indicate timeout has taken
+ * place.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdint.h>
+
+/*!
+ * Time-out timer state machine
+ */
+struct tot_t {
+       /*!
+        * Number of ticks remaining, if non-zero, transmission is
+        * in progress.
+        */
+       uint32_t        remaining;
+       /*!
+        * Number of ticks remaining, before next warning.
+        */
+       uint32_t        warn_remain;
+       /*!
+        * Timeout timer tick period.  Used to reset the ticks counter.
+        */
+       uint32_t        tick_period;
+       /*!
+        * Number of ticks between the remaining warnings.
+        */
+       uint16_t        remain_warn_ticks;
+       /*!
+        * Event tick timer.  Used to slow down the source timer.
+        */
+       uint16_t        ticks;
+       /*!
+        * Event flags.
+        */
+       uint16_t        event;
+};
+
+/*!
+ * Time-out timer has been started.
+ */
+#define        TOT_EVT_START           (1 << 0)
+
+/*!
+ * Start of warning period reached.
+ */
+#define        TOT_EVT_WARN            (1 << 1)
+
+/*!
+ * Next warning is due.
+ */
+#define TOT_EVT_WARN_NEXT      (1 << 2)
+
+/*!
+ * Time-out reached.
+ */
+#define TOT_EVT_TIMEOUT                (1 << 3)
+
+/*!
+ * Timer sequence complete
+ */
+#define TOT_EVT_DONE           (1 << 4)
+
+/*!
+ * Reset the time-out timer.  This zeroes the counter and event flags.
+ */
+void tot_reset(struct tot_t * const tot);
+
+/*!
+ * Start the time-out timer ticking.
+ */
+void tot_start(struct tot_t * const tot, uint32_t tot_ticks,
+               uint16_t warn_ticks);
+
+/*!
+ * Count a time-out timer tick.
+ */
+static inline void tot_tick(struct tot_t * const tot)
+{
+       if (tot->ticks)
+               tot->ticks--;
+}
+
+/*!
+ * Update the time-out timer state.
+ */
+void tot_update(struct tot_t * const tot);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/src/adc_rec.c b/codec2/branches/0.7/stm32/src/adc_rec.c
new file mode 100644 (file)
index 0000000..047e37c
--- /dev/null
@@ -0,0 +1,76 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: adc_rec.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 30 May 2014
+
+  Records a 16 kHz sample rate raw file from one of the ADC channels,
+  which are connected to pins PA1 (ADC1) and PA2 (ADC2).
+
+  Note the semi-hosting system isn't fast enough to transfer 2 16 kHz
+  streams at once.
+
+  ~/stlink$ sudo ./st-util -f ~/codec2-dev/stm32/adc_rec.elf
+  ~/codec2-dev/stm32$ ~/gcc-arm-none-eabi-4_7-2013q1/bin/arm-none-eabi-gdb adc_rec.elf
+
+  (when finished)
+  $ play -r 16000 -s -2 ~/stlink/adc.raw
+
+  adc1 -> "from radio"
+  adc2 -> "mic amp"
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "stm32f4_adc.h"
+#include "gdb_stdio.h"
+#include "stm32f4xx_gpio.h"
+
+#define REC_TIME_SECS 10
+#define  N  (ADC_BUF_SZ*6)
+#define FS  16000
+
+extern int adc_overflow1;
+extern int adc_overflow2;
+
+int main(void){
+    short  buf[N];
+    FILE  *fadc;
+    int    i, bufs;
+
+    fadc = fopen("adc.raw", "wb");
+    if (fadc == NULL) {
+        printf("Error opening input file: adc.raw\n\nTerminating....\n");
+        exit(1);
+    }
+    bufs = FS*REC_TIME_SECS/N;
+
+    printf("Starting!\n");
+    adc_open(ADC_FS_16KHZ, 4*N);
+
+    for(i=0; i<bufs; i++) {
+        while(adc2_read(buf, N) == -1);
+        fwrite(buf, sizeof(short), N, fadc);
+        printf("adc_overflow1: %d  adc_overflow2: %d   \n", adc_overflow1, adc_overflow2);
+    }
+    fclose(fadc);
+
+    printf("Finished!\n");
+}
diff --git a/codec2/branches/0.7/stm32/src/adc_rec_usb.c b/codec2/branches/0.7/stm32/src/adc_rec_usb.c
new file mode 100644 (file)
index 0000000..e86bdff
--- /dev/null
@@ -0,0 +1,85 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: adc_rec_usb.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Nov 2015
+
+  Records a 16 kHz sample rate raw file from one of the ADC channels,
+  which are connected to pins PA1 (ADC1) and PA2 (ADC2).  Uploads to the
+  host PC via the STM32F4 USB port, which appears as /dev/ttyACM0.
+
+  On the SM1000:
+    ADC1 -> PA1 -> "from radio"
+    ADC2 -> PA2 -> "mic amp"
+
+  I used this to record:
+    $ sudo dd if=/dev/ttyACM0 of=test.raw count=100
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <math.h>
+#include "stm32f4_adc.h"
+#include "stm32f4_usb_vcp.h"
+#include "sm1000_leds_switches.h"
+
+#define  N  (ADC_BUF_SZ*6)
+
+/* test tone parameters */
+
+#define  FREQ 999.0    /* make sure no alignment with frame boundaries */
+#define  FS   16000.0
+#define  AMP  10000.0
+
+extern int adc_overflow1;
+extern int adc_overflow2;
+
+int main(void){
+    short  buf[N];
+    #ifdef TEST_TONE
+    float  phase = 0.0;
+    float  sam;
+    int    i;
+    #endif
+
+    usb_vcp_init();
+    adc_open(ADC_FS_96KHZ, 4*N);
+    sm1000_leds_switches_init();
+
+    /* set up test buffer, lets us test USB comms indep of ADC, record to a file
+       then play back/examine waveform to make sure no clicks */
+
+    while(1) {
+        while(adc1_read(buf, N) == -1);
+
+        #ifdef TEST_TONE
+        for(i=0; i<N; i++) {
+            phase += 2.0*M_PI*FREQ/FS;
+            phase -= 2.0*M_PI*floor(phase/(2.0*M_PI));
+            sam = AMP*cos(phase);
+            buf[i] = (short)sam;
+        }
+        #endif
+
+        led_pwr(1);
+        VCP_send_buffer((uint8_t*)buf, sizeof(buf));
+        led_pwr(0);
+    }
+}
diff --git a/codec2/branches/0.7/stm32/src/adc_sd.c b/codec2/branches/0.7/stm32/src/adc_sd.c
new file mode 100644 (file)
index 0000000..d3085d8
--- /dev/null
@@ -0,0 +1,75 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: adc_sd.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 30 May 2014
+
+  Measures the std deviation of the ADC signals.  Used to check noise
+  levels on each ADC.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <math.h>
+#include "stm32f4_adc.h"
+#include "stm32f4_dac.h"
+#include "gdb_stdio.h"
+
+#define REC_TIME_SECS 10
+#define  N  (ADC_BUF_SZ*4)
+#define FS  16000
+
+static float calc_sd(short x[], int n) {
+    float sum, mean, sum_diff, sd;
+    int   i;
+
+    sum = 0.0;
+    for(i=0; i<n;i++) {
+        sum += (float)x[i];
+    }
+    mean = sum/n;
+
+    sum_diff = 0.0;
+    for(i=0; i<n;i++) {
+        sum_diff += ((float)x[i] - mean)*((float)x[i] - mean);
+    }
+
+    sd = sqrtf(sum_diff/n);
+
+    return sd;
+}
+
+int main(void){
+    short  buf[N];
+    float  sd1, sd2;
+
+    adc_open(ADC_FS_16KHZ, 2*N);
+
+    printf("Starting!\n");
+    while(1) {
+        while(adc1_read(buf, N) == -1);
+        sd1 = calc_sd(buf, N);
+        while(adc2_read(buf, N) == -1);
+        sd2 = calc_sd(buf, N);
+
+        printf("adc1: %5.1f adc2: %5.1f\n", (double)sd1, (double)sd2);
+    }
+
+}
diff --git a/codec2/branches/0.7/stm32/src/adc_sfdr_ut.c b/codec2/branches/0.7/stm32/src/adc_sfdr_ut.c
new file mode 100644 (file)
index 0000000..d090034
--- /dev/null
@@ -0,0 +1,89 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: adc_sfdr_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: August 2015
+
+  Unit test for high speed ADC SFDR testing.  Samples ADC1 from in PA1 at
+  Fs=2 MHz and write raw samples to a file, in discontinuus blocks of
+  ADC_TUNER_BUF_SZ/2 samples.  The blocks are discontinuous as we
+  don'thave the bandwitdh back to the host to support continuous sampling.
+
+  To process the blocks, fread() ADC_TUNER_BUF_SZ/2 samples at a time,
+  abs(fft) and sum results from next block.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include "gdb_stdio.h"
+#include "stm32f4_dac.h"
+#include "stm32f4_adc_tuner.h"
+#include "iir_tuner.h"
+#include "sm1000_leds_switches.h"
+#include "../src/codec2_fm.h"
+#include "stm32f4xx.h"
+
+#define BUFS          10
+#define FS            2E6
+#define N             1024
+
+extern int adc_overflow1;
+
+int main(void) {
+    unsigned short unsigned_buf[N];
+    short          buf[N];
+    int            sam;
+    int            i, j, fifo_sz;
+    FILE          *fadc;
+
+    fadc = fopen("adc.raw", "wb");
+    if (fadc == NULL) {
+        printf("Error opening output file: adc.raw\n\nTerminating....\n");
+        exit(1);
+    }
+    fifo_sz = ADC_TUNER_BUF_SZ;
+    printf("Starting! bufs: %d %d\n", BUFS, fifo_sz);
+
+    adc_open(fifo_sz);
+    adc_set_tuner_en(0); /* dump raw samples, no tuner */
+
+    sm1000_leds_switches_init();
+
+    for (i=0; i<BUFS; i++) {
+        while(adc1_read((short*)unsigned_buf, N) == -1);
+
+        /* convert to signed */
+
+        for(j=0; j<N; j++) {
+            sam = (int)unsigned_buf[j] - 32768;
+            buf[j] = sam;
+        }
+
+        /* most of the time will be spent here */
+
+        GPIOE->ODR |= (1 << 3);
+        fwrite(buf, sizeof(short), N, fadc);
+        GPIOE->ODR &= ~(1 << 3);
+    }
+    fclose(fadc);
+
+    printf("Finished!\n");
+}
diff --git a/codec2/branches/0.7/stm32/src/adcdac_ut.c b/codec2/branches/0.7/stm32/src/adcdac_ut.c
new file mode 100644 (file)
index 0000000..d83087d
--- /dev/null
@@ -0,0 +1,70 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: adcdac_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: May 31 201310 Aug 2014
+
+  Echoes ADC2 input (mic) to DAC2 output (speaker) on SM1000.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include "stm32f4_dac.h"
+#include "stm32f4_adc.h"
+#include "sm1000_leds_switches.h"
+
+#define SINE_SAMPLES   32
+
+
+/* 32 sample sine wave which at Fs=16kHz will be 500Hz.  Note samples
+   are 16 bit 2's complement, the DAC driver convertsto 12 bit
+   unsigned. */
+
+short aSine[] = {
+     -16,    6384,   12528,   18192,   23200,   27232,   30256,   32128,
+   32752,   32128,   30256,   27232,   23152,   18192,   12528,    6384,
+     -16,   -6416,  -12560,  -18224,  -23184,  -27264,  -30288,  -32160,
+  -32768,  -32160,  -30288,  -27264,  -23184,  -18224,  -12560,   -6416
+};
+
+int main(void) {
+    short buf[SINE_SAMPLES];
+    int   i;
+
+    dac_open(ADC_FS_16KHZ,4*DAC_BUF_SZ);
+    adc_open(ADC_FS_16KHZ, 4*ADC_BUF_SZ);
+    sm1000_leds_switches_init();
+
+    while (1) {
+
+        /* keep DAC FIFOs topped up */
+
+        while(adc2_read(buf, SINE_SAMPLES) == -1);
+
+        if (!switch_select()) {
+            for(i=0; i<SINE_SAMPLES; i++)
+                buf[i] = aSine[i];
+        }
+
+        dac2_write(buf, SINE_SAMPLES);
+    }
+
+}
+
diff --git a/codec2/branches/0.7/stm32/src/codec2_profile.c b/codec2/branches/0.7/stm32/src/codec2_profile.c
new file mode 100644 (file)
index 0000000..5537bad
--- /dev/null
@@ -0,0 +1,181 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: codec2_profile.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 30 May 2013
+
+  Profiling Codec 2 operation on the STM32F4.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "gdb_stdio.h"
+#include "codec2.h"
+#include "dump.h"
+#include "sine.h"
+#include "machdep.h"
+
+#ifdef __EMBEDDED__
+#define printf gdb_stdio_printf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#define fread gdb_stdio_fread
+#define fwrite gdb_stdio_fwrite
+#endif
+
+static void c2demo(int mode, char inputfile[], char outputfile[])
+{
+    struct CODEC2 *codec2;
+    short         *inbuf, *outbuf;
+    unsigned char *bits;
+    int            nsam, nbit;
+    FILE          *fin, *fout;
+    int            frame;
+    PROFILE_VAR(enc_start, dec_start);
+
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    outbuf = (short*)malloc(nsam*sizeof(short));
+    inbuf = (short*)malloc(nsam*sizeof(short));
+    nbit = codec2_bits_per_frame(codec2);
+    bits = (unsigned char*)malloc(nbit*sizeof(char));
+
+    fin = fopen(inputfile, "rb");
+    if (fin == NULL) {
+        printf("Error opening input file: %s\n\nTerminating....\n",inputfile);
+        exit(1);
+    }
+
+    fout = fopen(outputfile, "wb");
+    if (fout == NULL) {
+        printf("Error opening output file: %s\n\nTerminating....\n",outputfile);
+        exit(1);
+    }
+
+    #ifdef DUMP
+    dump_on("stm32f4");
+    #endif
+    frame = 0;
+
+    while (fread(inbuf, sizeof(short), nsam, fin) == nsam) {
+        PROFILE_SAMPLE(enc_start);
+        codec2_encode(codec2, bits, inbuf);
+        PROFILE_SAMPLE_AND_LOG(dec_start, enc_start, "  enc");
+       codec2_decode(codec2, outbuf, bits);
+        PROFILE_SAMPLE_AND_LOG2(dec_start, "  dec");
+        PROFILE_SAMPLE_AND_LOG2(enc_start, "  enc & dec");
+        fwrite((char*)outbuf, sizeof(short), nsam, fout);
+        printf("frame: %d\n", ++frame);
+        machdep_profile_print_logged_samples();
+    }
+
+    #ifdef DUMP
+    dump_off("sm32f4");
+    #endif
+
+    fclose(fin);
+    fclose(fout);
+    free(inbuf);
+    free(outbuf);
+    free(bits);
+    codec2_destroy(codec2);
+}
+
+#define SPEED_TEST_SAMPLES 24000
+
+static void c2speedtest(int mode, char inputfile[])
+{
+    struct CODEC2 *codec2;
+    short         *inbuf, *outbuf, *pinbuf;
+    unsigned char *bits;
+    int            nsam, nbit, nframes;
+    FILE          *fin;
+    int            f, nread;
+
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    nframes = SPEED_TEST_SAMPLES/nsam;
+    outbuf = (short*)malloc(nsam*sizeof(short));
+    inbuf = (short*)malloc(SPEED_TEST_SAMPLES*sizeof(short));
+    nbit = codec2_bits_per_frame(codec2);
+    bits = (unsigned char*)malloc(nbit*sizeof(char));
+
+    fin = fopen(inputfile, "rb");
+    if (fin == NULL) {
+        printf("Error opening input file: %s\nTerminating....\n",inputfile);
+        exit(1);
+    }
+
+    nread = fread(inbuf, sizeof(short), SPEED_TEST_SAMPLES, fin);
+    if (nread != SPEED_TEST_SAMPLES) {
+        printf("error reading %s, %d samples reqd, %d read\n",
+               inputfile, SPEED_TEST_SAMPLES, nread);
+    }
+    fclose(fin);
+
+    pinbuf = inbuf;
+    for(f=0; f<nframes; f++) {
+       GPIOD->ODR = (1 << 13);
+        codec2_encode(codec2, bits, pinbuf);
+        pinbuf += nsam;
+       GPIOD->ODR &= ~(1 << 13);
+       codec2_decode(codec2, outbuf, bits);
+    }
+
+    free(inbuf);
+    free(outbuf);
+    free(bits);
+    codec2_destroy(codec2);
+}
+
+void gpio_init() {
+    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // enable the clock to GPIOD
+    GPIOD->MODER = (1 << 26);            // set pin 13 to be general
+                                         // purpose output
+}
+
+int main(int argc, char *argv[]) {
+    gpio_init();
+    machdep_profile_init ();
+
+    printf("Starting c2demo\n");
+
+    /* File I/O test for profiling or (with #define DUMP)
+       dumping states for optimisation and tiuning */
+
+    c2demo(CODEC2_MODE_1600, "stm_in.raw", "stm_out.raw");
+
+    printf("Starting c2 speed test\n");
+
+    /* Another test of execution speed. Look at PD13 with a
+       oscilliscope.  On time is enc, off is dec */
+
+    c2speedtest(CODEC2_MODE_1600, "stm_in.raw");
+
+    printf("Finished\n");
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/stm32/src/dac_it.c b/codec2/branches/0.7/stm32/src/dac_it.c
new file mode 100644 (file)
index 0000000..a2925fa
--- /dev/null
@@ -0,0 +1,205 @@
+/**
+  ******************************************************************************
+  * @file    DMA/DMA_FLASHToRAM/stm32f4xx_it.c
+  * @author  MCD Application Team
+  * @version V1.1.0
+  * @date    18-January-2013
+  * @brief   Main Interrupt Service Routines.
+  *          This file provides template for all exceptions handler and
+  *          peripherals interrupt service routine.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
+  *
+  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+  * You may not use this file except in compliance with the License.
+  * You may obtain a copy of the License at:
+  *
+  *        http://www.st.com/software_license_agreement_liberty_v2
+  *
+  * Unless required by applicable law or agreed to in writing, software
+  * distributed under the License is distributed on an "AS IS" BASIS,
+  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  * See the License for the specific language governing permissions and
+  * limitations under the License.
+  *
+  ******************************************************************************
+  */
+int interrupts;
+
+
+/* Includes ------------------------------------------------------------------*/
+#include "dac_it.h"
+
+/** @addtogroup STM32F4xx_StdPeriph_Examples
+  * @{
+  */
+
+/** @addtogroup DMA_FLASHToRAM
+  * @{
+  */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/******************************************************************************/
+/*            Cortex-M4 Processor Exceptions Handlers                         */
+/******************************************************************************/
+
+/**
+  * @brief   This function handles NMI exception.
+  * @param  None
+  * @retval None
+  */
+void NMI_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles Hard Fault exception.
+  * @param  None
+  * @retval None
+  */
+void HardFault_Handler(void)
+{
+  /* Go to infinite loop when Hard Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles Memory Manage exception.
+  * @param  None
+  * @retval None
+  */
+void MemManage_Handler(void)
+{
+  /* Go to infinite loop when Memory Manage exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles Bus Fault exception.
+  * @param  None
+  * @retval None
+  */
+void BusFault_Handler(void)
+{
+  /* Go to infinite loop when Bus Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles Usage Fault exception.
+  * @param  None
+  * @retval None
+  */
+void UsageFault_Handler(void)
+{
+  /* Go to infinite loop when Usage Fault exception occurs */
+  while (1)
+  {
+  }
+}
+
+/**
+  * @brief  This function handles SVCall exception.
+  * @param  None
+  * @retval None
+  */
+void SVC_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles Debug Monitor exception.
+  * @param  None
+  * @retval None
+  */
+void DebugMon_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles PendSVC exception.
+  * @param  None
+  * @retval None
+  */
+void PendSV_Handler(void)
+{
+}
+
+/**
+  * @brief  This function handles SysTick Handler.
+  * @param  None
+  * @retval None
+  */
+void SysTick_Handler(void)
+{
+}
+
+/******************************************************************************/
+/*                 STM32F4xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32f40xx.s/startup_stm32f427x.s).                         */
+/******************************************************************************/
+
+/**
+  * @brief  This function handles DMA Stream interrupt request.
+  * @param  None
+  * @retval None
+  */
+void DMA1_Stream6_IRQHandler(void)
+{
+
+  /* Transfer half empty interrupt */
+
+  if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6) != RESET))
+  {
+      /* fill first half from fifo */
+
+      fifo_read(DMA1_Stream6_fifo, dac_buf, DAC_BUF_SZ/2);
+
+      /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+      DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_HTIF6);
+
+      interrupts++;
+  }
+
+  /* Transfer complete interrupt */
+
+  if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6) != RESET))
+  {
+      /* fill second half from fifo */
+
+      fifo_read(DMA1_Stream6_fifo, &dac_buf[DAC_BUF_SZ/2], DAC_BUF_SZ/2);
+
+      /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+      DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);
+
+      interrupts++;
+  }
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/src/dac_play.c b/codec2/branches/0.7/stm32/src/dac_play.c
new file mode 100644 (file)
index 0000000..267029d
--- /dev/null
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: dac_play.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 June 2013
+
+  Plays a 16 kHz sample rate raw file to the STM32F4 DACs. DAC1 is
+  connected to pin PA4, DAC2 is connected to pin PA5.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include "stm32f4_dac.h"
+#include "gdb_stdio.h"
+
+#define N    (5*DAC_BUF_SZ)
+
+int main(void) {
+    short  buf[N];
+    FILE  *fplay;
+
+    dac_open(DAC_FS_16KHZ, 2*N);
+
+    while(1) {
+        fplay = fopen("stm_in.raw", "rb");
+        if (fplay == NULL) {
+            printf("Error opening input file: stm_in.raw\n\nTerminating....\n");
+            exit(1);
+        }
+
+        printf("Starting!\n");
+
+        while(fread(buf, sizeof(short), N, fplay) == N) {
+            while(dac1_write(buf, N) == -1);
+            while(dac2_write(buf, N) == -1);
+        }
+
+        printf("Finished!\n");
+        fclose(fplay);
+    }
+
+    /* let FIFO empty */
+
+    while(1);
+}
+
diff --git a/codec2/branches/0.7/stm32/src/dac_ut.c b/codec2/branches/0.7/stm32/src/dac_ut.c
new file mode 100644 (file)
index 0000000..4ab56c8
--- /dev/null
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: dac_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: May 31 2013
+
+  Plays a 500 Hz sine wave sampled at 16 kHz out of PA5 on a Discovery board,
+  or the speaker output of the SM1000.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include "stm32f4_dac.h"
+
+#define SINE_SAMPLES   32
+
+/* 32 sample sine wave which at Fs=16kHz will be 500Hz.  Note samples
+   are 16 bit 2's complement, the DAC driver convertsto 12 bit
+   unsigned. */
+
+short aSine[] = {
+     -16,    6384,   12528,   18192,   23200,   27232,   30256,   32128,
+   32752,   32128,   30256,   27232,   23152,   18192,   12528,    6384,
+     -16,   -6416,  -12560,  -18224,  -23184,  -27264,  -30288,  -32160,
+  -32768,  -32160,  -30288,  -27264,  -23184,  -18224,  -12560,   -6416
+};
+
+int main(void) {
+
+    dac_open(DAC_FS_16KHZ, 4*DAC_BUF_SZ);
+
+    while (1) {
+
+        /* keep DAC FIFOs topped up */
+
+        dac1_write((short*)aSine, SINE_SAMPLES);
+        dac2_write((short*)aSine, SINE_SAMPLES);
+    }
+
+}
diff --git a/codec2/branches/0.7/stm32/src/dac_ut_fast.c b/codec2/branches/0.7/stm32/src/dac_ut_fast.c
new file mode 100644 (file)
index 0000000..9c75059
--- /dev/null
@@ -0,0 +1,37 @@
+/*---------------------------------------------------------------------------*\\r
+\r
+  FILE........: dac_ut_fast.c\r
+  AUTHOR......: David Rowe\r
+  DATE CREATED: Sep 2015\r
+\r
+  Plays a Fs/4 sine wave sampled out of PA5 on a Discovery board, used for \r
+  testing high speed DAC operation, e.g. for IF/RF generation.\r
+\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+  Copyright (C) 2015 David Rowe\r
+\r
+  All rights reserved.\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU Lesser General Public License version 2.1, as\r
+  published by the Free Software Foundation.  This program is\r
+  distributed in the hope that it will be useful, but WITHOUT ANY\r
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\r
+  License for more details.\r
+\r
+  You should have received a copy of the GNU Lesser General Public License\r
+  along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#include <assert.h>\r
+#include "stm32f4_dac.h"\r
+\r
+\r
+int main(void) {\r
+    dac_open(4*DAC_BUF_SZ);\r
+    while (1);\r
+}\r
+\r
diff --git a/codec2/branches/0.7/stm32/src/debugblinky.c b/codec2/branches/0.7/stm32/src/debugblinky.c
new file mode 100644 (file)
index 0000000..992c8b0
--- /dev/null
@@ -0,0 +1,57 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: debugblinky.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 12 August 2014
+
+  Configures GPIO pins used for debug blinkies
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stm32f4xx.h"
+
+void init_debug_blinky(void) {
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    /* PE0-3 used to indicate activity, PE4-5 for SM2000 +12V rail switching */
+
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
+
+    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
+    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
+    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
+    GPIO_Init(GPIOE, &GPIO_InitStruct);
+}
+
+/* SM2000: 0 for +12V RX power, 1 for +12V TX power  */
+
+void txrx_12V(int state) {
+    if (state) {
+        GPIOE->ODR &= ~(1 << 5); /* +12VRXENB off */
+        GPIOE->ODR |=  (1 << 4); /* +12VTXENB on */
+    }
+    else {
+        GPIOE->ODR &= ~(1 << 4); /* +12VTXENB off */
+        GPIOE->ODR |=  (1 << 5); /* +12VRXENB on */
+    }
+}
+
diff --git a/codec2/branches/0.7/stm32/src/fast_dac_ut.c b/codec2/branches/0.7/stm32/src/fast_dac_ut.c
new file mode 100644 (file)
index 0000000..cce4edb
--- /dev/null
@@ -0,0 +1,116 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: dac_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: May 31 2013
+
+  Plays a 500 Hz sine wave sampled at 16 kHz out of PA5 on a Discovery board,
+  or the speaker output of the SM1000.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include "stm32f4_dacduc.h"
+#include "iir_duc.h"
+#include "stm32f4xx.h"
+#include <stm32f4xx_tim.h>
+#include <stm32f4xx_rcc.h>
+#include "gdb_stdio.h"
+#include "comp.h"
+#include <string.h> 
+//#include "gmsk_test_dat_m4.h"
+#define SINE_SAMPLES  32
+
+
+/* 32 sample sine wave which at Fs=16kHz will be 500Hz.  Note samples
+   are 16 bit 2's complement, the DAC driver convertsto 12 bit
+   unsigned. */
+
+short aWave[] = {4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,
+       4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,4095,0,};
+
+short aSine[] = {1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1601, 0, 1600, 3200, 1600, 0, 1600, 3200, 1601, 0
+};
+
+//Sine at Fs/4
+float f4sine[] = {1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,
+1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,
+1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,
+1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,1,0,-1,0,};
+
+//Intermediate 80k real before tx
+int tx_imm[DUC_N];
+
+//Complex input to chain
+#define COMP_IN_SZ (DUC_48N)
+COMP comp_in[COMP_IN_SZ];
+
+unsigned short outbuf[DAC_DUC_BUF_SZ];
+
+void setup_timer()
+{
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
+
+    TIM_TimeBaseInitTypeDef timerInitStructure;
+    timerInitStructure.TIM_Prescaler = 84;
+    timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
+    timerInitStructure.TIM_Period = 0x8FFFFFFF;
+    timerInitStructure.TIM_ClockDivision = 0;
+    timerInitStructure.TIM_RepetitionCounter = 0;
+    TIM_TimeBaseInit(TIM2, &timerInitStructure);
+    TIM_Cmd(TIM2, ENABLE);
+}
+
+int main(void) {
+    int tstart,tup,tend,cyc,i;
+
+    memset((void*)outbuf,0,sizeof(short)*DAC_DUC_BUF_SZ);
+    setup_timer();
+    fast_dac_open(2*DAC_DUC_BUF_SZ,2*DAC_BUF_SZ);
+    tstart=tend=tup=cyc=0;
+    //Initalize complex input with signal at zero
+    for(i=0;i<COMP_IN_SZ;i++){
+        comp_in[i].real=1;
+        comp_in[i].imag=0;
+    }
+    while (1) {
+       cyc++;
+        //if(cyc>GMSK_TEST_LEN)
+        //    cyc=0;
+       if(cyc%10000==0){
+                printf("48c80r takes %d uSecs\n",tup-tstart);
+               printf("iir upconvert takes %d uSecs\n",tend-tup);
+       }
+        tstart = TIM_GetCounter(TIM2);
+
+        upconv_48c_80r(comp_in,tx_imm,1);
+
+       tup = TIM_GetCounter(TIM2);
+
+       iir_upconv_fixp(tx_imm,outbuf);
+
+       tend = TIM_GetCounter(TIM2);
+
+        //Sit and spin until we can get more samples into the dac
+       while(dac1_write((short*)outbuf,DAC_DUC_BUF_SZ)<0);
+    }
+
+}
diff --git a/codec2/branches/0.7/stm32/src/fdmdv_dump_rt.c b/codec2/branches/0.7/stm32/src/fdmdv_dump_rt.c
new file mode 100644 (file)
index 0000000..52ca977
--- /dev/null
@@ -0,0 +1,154 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_dump_rt.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 9 Sep 2014
+
+ Runs the fdmdv demod in real time for a few seconds then dumps some
+ modem info to a text file for plotting in Octave.  Way to verify the
+ "from radio" SM1000 hardware, ADC, and demod on the SM1000.
+
+ Requires FreeDV signal to be sent to CN6 of SM1000.
+
+ Octave:
+
+   load scatter.txt
+   l=length(scatter)
+   plot(scatter(:,1:2:l),scatter(:,2:2:l),'+')
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include <stm32f4xx_gpio.h>
+#include "stm32f4_adc.h"
+#include "stm32f4_dac.h"
+#include "freedv_api.h"
+#include "codec2_fdmdv.h"
+#include "sm1000_leds_switches.h"
+#include "gdb_stdio.h"
+
+#ifdef __EMBEDDED__
+#define printf gdb_stdio_printf
+#define fprintf gdb_stdio_fprintf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#define fread gdb_stdio_fread
+#define fwrite gdb_stdio_fwrite
+#endif
+
+#define FREEDV_NSAMPLES_16K (2*FREEDV_NSAMPLES)
+#define START_LOG_FRAMES 100
+#define LOG_FRAMES       10
+#define STOP_LOG_FRAMES  (START_LOG_FRAMES+LOG_FRAMES)
+#define NC  16
+
+int main(void) {
+    struct freedv *f;
+    short          adc16k[FDMDV_OS_TAPS_16K+FREEDV_NSAMPLES_16K];
+    short          dac16k[FREEDV_NSAMPLES_16K];
+    short          adc8k[FREEDV_NSAMPLES];
+    short          dac8k[FDMDV_OS_TAPS_8K+FREEDV_NSAMPLES];
+
+    int            nin, nout, i, j, frames, lines;
+
+    COMP          *symb, *psymb;
+
+    /* init all the drivers for various peripherals */
+
+    sm1000_leds_switches_init();
+    dac_open(4*DAC_BUF_SZ);
+    adc_open(4*ADC_BUF_SZ);
+    f = freedv_open(FREEDV_MODE_1600);
+
+    /* clear filter memories */
+
+    for(i=0; i<FDMDV_OS_TAPS_16K; i++)
+       adc16k[i] = 0.0;
+    for(i=0; i<FDMDV_OS_TAPS_8K; i++)
+       dac8k[i] = 0.0;
+
+    /* allocate storage for the symbols */
+
+#define TMP
+#ifdef TMP
+    symb = (COMP*)malloc(sizeof(COMP)*(NC+1)*(STOP_LOG_FRAMES - START_LOG_FRAMES));
+    assert(symb != NULL);
+    psymb = symb;
+    frames = 0;
+    lines = 0;
+#endif
+    while(1)  {
+
+        /* Receive --------------------------------------------------------------------------*/
+
+        /* ADC1 is the demod in signal from the radio rx, DAC2 is the SM1000 speaker */
+
+        nin = freedv_nin(f);
+        nout = nin;
+        f->total_bit_errors = 0;
+
+        if (adc1_read(&adc16k[FDMDV_OS_TAPS_16K], 2*nin) == 0) {
+            GPIOE->ODR = (1 << 3);
+            fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], nin);
+            nout = freedv_rx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);
+            fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], nout);
+            dac2_write(dac16k, 2*nout);
+            led_ptt(0); led_rt(f->fdmdv_stats.sync); led_err(f->total_bit_errors);
+            GPIOE->ODR &= ~(1 << 3);
+
+#define TMP1
+#ifdef TMP1
+            if (f->fdmdv_stats.sync)
+                frames++;
+            if ((frames >= START_LOG_FRAMES) && (lines < LOG_FRAMES)) {
+                for(i=0; i<=f->fdmdv_stats.Nc; i++)
+                    psymb[i] = f->fdmdv_stats.rx_symbols[i];
+                psymb += (f->fdmdv_stats.Nc+1);
+                lines++;
+            }
+
+            if (frames >= STOP_LOG_FRAMES) {
+                FILE *ft = fopen("scatter.txt", "wt");
+                assert(ft != NULL);
+                printf("Writing scatter file....\n");
+                for(j=0; j<LOG_FRAMES; j++) {
+                    for(i=0; i<=f->fdmdv_stats.Nc; i++) {
+                        fprintf(ft, "%f\t%f\t",
+                                (double)symb[j*(f->fdmdv_stats.Nc+1)+i].real,
+                                (double)symb[j*(f->fdmdv_stats.Nc+1)+i].imag);
+                        printf("line: %d\n", j);
+                    }
+                    fprintf(ft, "\n");
+                }
+                fclose(ft);
+                printf("SNR = %3.2f dB\nfinished!\n", (double)f->fdmdv_stats.snr_est);
+                while(1);
+            }
+#endif
+        }
+
+    } /* while(1) ... */
+}
+
diff --git a/codec2/branches/0.7/stm32/src/fdmdv_profile.c b/codec2/branches/0.7/stm32/src/fdmdv_profile.c
new file mode 100644 (file)
index 0000000..a663e60
--- /dev/null
@@ -0,0 +1,149 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_profile.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 18 July 2014
+
+  Profiling FDMDV modem operation on the STM32F4.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "gdb_stdio.h"
+#include "codec2_fdmdv.h"
+#include "dump.h"
+#include "sine.h"
+#include "machdep.h"
+
+#ifdef __EMBEDDED__
+#define printf gdb_stdio_printf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#define fread gdb_stdio_fread
+#define fwrite gdb_stdio_fwrite
+#endif
+
+#define TEST_FRAMES 25
+#define CHANNEL_BUF_SIZE (10*FDMDV_NOM_SAMPLES_PER_FRAME)
+
+static int  channel_count = 0;
+static COMP channel[CHANNEL_BUF_SIZE];
+
+static void channel_in(COMP tx_fdm[], int nout) {
+    int i;
+
+    /* add M_PITCH tx samples to end of buffer */
+
+    assert((channel_count + nout) < CHANNEL_BUF_SIZE);
+    for(i=0; i<nout; i++)
+        channel[channel_count+i] = tx_fdm[i];
+    channel_count += M_PITCH;
+}
+
+static void channel_out(COMP rx_fdm[], int nin) {
+    int i,j;
+
+    /* take nin samples from start of buffer */
+
+    for(i=0; i<nin; i++) {
+        rx_fdm[i] = channel[i];
+    }
+
+    /* shift buffer back */
+
+    for(i=0,j=nin; j<channel_count; i++,j++)
+        channel[i] = channel[j];
+    channel_count -= nin;
+}
+
+int main(int argc, char *argv[]) {
+    struct FDMDV       *fdmdv;
+    int                 bits_per_fdmdv_frame,  bits_per_codec_frame;
+    int                *tx_bits;
+    int                *rx_bits;
+    int                *codec_bits;
+    COMP                tx_fdm[2*FDMDV_NOM_SAMPLES_PER_FRAME];
+    COMP                rx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME];
+    int                 i, j, nin, reliable_sync_bit[2], sync_bit, bit_errors, ntest_bits, test_frame_sync;
+    short              *error_pattern;
+    struct MODEM_STATS  stats;
+    PROFILE_VAR(mod_start, demod_start);
+
+    machdep_profile_init ();
+    fdmdv = fdmdv_create(FDMDV_NC);
+
+    bits_per_fdmdv_frame = fdmdv_bits_per_frame(fdmdv);
+    bits_per_codec_frame = 2*fdmdv_bits_per_frame(fdmdv);
+    tx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame); assert(tx_bits != NULL);
+    rx_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame); assert(rx_bits != NULL);
+    codec_bits = (int*)malloc(sizeof(int)*bits_per_codec_frame); assert(rx_bits != NULL);
+    error_pattern = (short*)malloc(fdmdv_error_pattern_size(fdmdv)*sizeof(int)); assert(error_pattern != NULL);
+
+    nin = FDMDV_NOM_SAMPLES_PER_FRAME;
+    test_frame_sync = 0;
+
+    for(i=0; i<TEST_FRAMES; i++) {
+       fdmdv_get_test_bits(fdmdv, tx_bits);
+       fdmdv_get_test_bits(fdmdv, &tx_bits[bits_per_fdmdv_frame]);
+
+        PROFILE_SAMPLE(mod_start);
+
+       fdmdv_mod(fdmdv, tx_fdm, tx_bits, &sync_bit);
+       assert(sync_bit == 1);
+       fdmdv_mod(fdmdv, &tx_fdm[FDMDV_NOM_SAMPLES_PER_FRAME], &tx_bits[bits_per_fdmdv_frame], &sync_bit);
+       assert(sync_bit == 0);
+        channel_in(tx_fdm, 2*FDMDV_NOM_SAMPLES_PER_FRAME);
+
+        PROFILE_SAMPLE_AND_LOG(demod_start, mod_start, "  mod");
+
+        for(j=0; j<2; j++) {
+            channel_out(rx_fdm, nin);
+            fdmdv_demod(fdmdv, rx_bits, &reliable_sync_bit[j], rx_fdm, &nin);
+            if (reliable_sync_bit[j] == 0)
+                memcpy(codec_bits, rx_bits, bits_per_fdmdv_frame*sizeof(int));
+            else {
+                memcpy(&codec_bits[bits_per_fdmdv_frame], rx_bits, bits_per_fdmdv_frame*sizeof(int));
+                fdmdv_put_test_bits(fdmdv, &test_frame_sync, error_pattern, &bit_errors, &ntest_bits, codec_bits);
+                fdmdv_put_test_bits(fdmdv, &test_frame_sync, error_pattern, &bit_errors, &ntest_bits, &codec_bits[bits_per_fdmdv_frame]);
+            }
+        }
+        PROFILE_SAMPLE_AND_LOG2(demod_start, "  demod");
+        PROFILE_SAMPLE_AND_LOG2(mod_start, "  mod & demod");
+
+        fdmdv_get_demod_stats(fdmdv, &stats);
+
+        printf("frame: %d sync: %d reliable_sync_bit: %d %d SNR: %3.2f test_frame_sync: %d\n",
+               i, stats.sync, reliable_sync_bit[0], reliable_sync_bit[1], (double)stats.snr_est,
+               test_frame_sync);
+        machdep_profile_print_logged_samples();
+    }
+
+    fdmdv_destroy(fdmdv);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/fft_test.c b/codec2/branches/0.7/stm32/src/fft_test.c
new file mode 100644 (file)
index 0000000..a357cc5
--- /dev/null
@@ -0,0 +1,176 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010 ARM Limited. All rights reserved.
+*
+* $Date:        29. November 2010
+* $Revision:   V1.0.3
+*
+* Project:         CMSIS DSP Library
+* Title:           arm_fft_bin_example_f32.c
+*
+* Description: Example code demonstrating calculation of Max energy bin of
+*                              frequency domain of input signal.
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+*
+* Version 1.0.3 2010/11/29
+*    Re-organized the CMSIS folders and updated documentation.
+*
+* Version 1.0.1 2010/10/05 KK
+*    Production release and review comments incorporated.
+*
+* Version 1.0.0 2010/09/20 KK
+*    Production release and review comments incorporated.
+* ------------------------------------------------------------------- */
+
+/**
+ * @ingroup groupExamples
+ */
+
+/**
+ * @defgroup FrequencyBin Frequency Bin Example
+ *
+ * \par Description
+ * \par
+ * Demonstrates the calculation of the maximum energy bin in the frequency
+ * domain of the input signal with the use of Complex FFT, Complex
+ * Magnitude, and Maximum functions.
+ *
+ * \par Algorithm:
+ * \par
+ * The input test signal contains a 10 kHz signal with uniformly distributed white noise.
+ * Calculating the FFT of the input signal will give us the maximum energy of the
+ * bin corresponding to the input frequency of 10 kHz.
+ *
+ * \par Block Diagram:
+ * \image html FFTBin.gif "Block Diagram"
+ * \par
+ * The figure below shows the time domain signal of 10 kHz signal with
+ * uniformly distributed white noise, and the next figure shows the input
+ * in the frequency domain. The bin with maximum energy corresponds to 10 kHz signal.
+ * \par
+ * \image html FFTBinInput.gif "Input signal in Time domain"
+ * \image html FFTBinOutput.gif "Input signal in Frequency domain"
+ *
+ * \par Variables Description:
+ * \par
+ * \li \c testInput_f32_10khz points to the input data
+ * \li \c testOutput points to the output data
+ * \li \c fftSize length of FFT
+ * \li \c ifftFlag flag for the selection of CFFT/CIFFT
+ * \li \c doBitReverse Flag for selection of normal order or bit reversed order
+ * \li \c refIndex reference index value at which maximum energy of bin ocuurs
+ * \li \c testIndex calculated index value at which maximum energy of bin ocuurs
+ *
+ * \par CMSIS DSP Software Library Functions Used:
+ * \par
+ * - arm_cfft_radix4_init_f32()
+ * - arm_cfft_radix4_f32()
+ * - arm_cmplx_mag_f32()
+ * - arm_max_f32()
+ *
+ * <b> Refer  </b>
+ * \link arm_fft_bin_example_f32.c \endlink
+ *
+ */
+
+
+/** \example arm_fft_bin_example_f32.c
+  */
+
+
+#include "arm_math.h"
+#include "gdb_stdio.h"
+#include "machdep.h"
+#include "kiss_fft.h"
+
+#define TEST_LENGTH_SAMPLES 1024
+
+/* -------------------------------------------------------------------
+* External Input and Output buffer Declarations for FFT Bin Example
+* ------------------------------------------------------------------- */
+extern float32_t testInput_f32_10khz[TEST_LENGTH_SAMPLES];
+static float32_t testOutput[TEST_LENGTH_SAMPLES/2];
+static float32_t kiss_complex_out[TEST_LENGTH_SAMPLES];
+
+/* ------------------------------------------------------------------
+* Global variables for FFT Bin Example
+* ------------------------------------------------------------------- */
+uint32_t fftSize = TEST_LENGTH_SAMPLES/2;
+uint32_t ifftFlag = 0;
+uint32_t doBitReverse = 1;
+
+/* Reference index at which max energy of bin ocuurs */
+uint32_t refIndex = 213, testIndex = 0;
+
+/* ----------------------------------------------------------------------
+* Max magnitude FFT Bin test
+* ------------------------------------------------------------------- */
+
+void SystemInit(void);
+
+int main(void)
+{
+
+       arm_status status;
+       arm_cfft_radix2_instance_f32 S;
+       float32_t maxValue;
+        unsigned int fft_start, kiss_fft_start;
+        kiss_fft_cfg fft_fwd_cfg;
+
+        SystemInit();
+        machdep_profile_init();
+        fft_fwd_cfg = kiss_fft_alloc(fftSize, 0, NULL, NULL);
+        kiss_fft_start = machdep_profile_sample();
+        kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)testInput_f32_10khz,
+                 (kiss_fft_cpx *)kiss_complex_out);
+        machdep_profile_sample_and_log(kiss_fft_start, "  kiss_fft");
+
+       status = ARM_MATH_SUCCESS;
+
+       /* Initialize the CFFT/CIFFT module */
+       status = arm_cfft_radix2_init_f32(&S, fftSize, ifftFlag, doBitReverse);
+
+       /* Process the data through the CFFT/CIFFT module */
+        fft_start = machdep_profile_sample();
+        arm_cfft_radix2_f32(&S, testInput_f32_10khz);
+        machdep_profile_sample_and_log(fft_start, "  fft");
+        machdep_profile_print_logged_samples();
+
+       /* Process the data through the Complex Magnitude Module for
+       calculating the magnitude at each bin */
+       arm_cmplx_mag_f32(testInput_f32_10khz, testOutput,fftSize);
+
+       /* Calculates maxValue and returns corresponding BIN value */
+       arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);
+
+       if(testIndex !=  refIndex)
+       {
+               status = ARM_MATH_TEST_FAILURE;
+       }
+
+       /* ----------------------------------------------------------------------
+       ** Loop here if the signals fail the PASS check.
+       ** This denotes a test failure
+       ** ------------------------------------------------------------------- */
+
+       if( status != ARM_MATH_SUCCESS)
+       {
+               while(1);
+       }
+
+    while(1);                             /* main function does not return */
+
+    return 0;
+}
+
+ /** \endlink */
+
+
+/*
+ * Dummy function to avoid compiler error
+ */
+void _init() { }
+
+
+
diff --git a/codec2/branches/0.7/stm32/src/freedv_rx_profile.c b/codec2/branches/0.7/stm32/src/freedv_rx_profile.c
new file mode 100644 (file)
index 0000000..52ad6d2
--- /dev/null
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_rx_profile.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 13 August 2014
+
+  Profiling freedv_rx() operation on the STM32F4.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define PROFILE
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "gdb_stdio.h"
+#include "freedv_api.h"
+#include "machdep.h"
+#include "codec2_fdmdv.h"
+
+#ifdef __EMBEDDED__
+#define printf gdb_stdio_printf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#define fread gdb_stdio_fread
+#define fwrite gdb_stdio_fwrite
+#define fprintf gdb_stdio_fprintf
+#endif
+
+#define FREEDV_NSAMPLES_16K (2*FREEDV_NSAMPLES)
+
+int main(int argc, char *argv[]) {
+    struct freedv *f;
+    FILE          *fin, *fout, *ftotal;
+    int            frame, nin_16k, nin, i, nout = 0;
+    int            n_samples, n_samples_16k;
+    int            sync;
+    float          snr_est;
+
+    PROFILE_VAR(fdmdv_16_to_8_start, freedv_rx_start, fdmdv_8_to_16_start);
+
+    machdep_profile_init();
+
+    f = freedv_open(FREEDV_MODE_1600);
+    n_samples = freedv_get_n_speech_samples(f);
+    n_samples_16k = 2*n_samples;
+
+    short          adc16k[FDMDV_OS_TAPS_16K+n_samples_16k];
+    short          dac16k[n_samples_16k];
+    short          adc8k[n_samples];
+    short          dac8k[FDMDV_OS_TAPS_8K+n_samples];
+
+    // Receive ---------------------------------------------------------------------
+
+    frame = 0;
+
+    fin = fopen("mod_16k.raw", "rb");
+    if (fin == NULL) {
+        printf("Error opening input file\n");
+        exit(1);
+    }
+
+    fout = fopen("speechout_16k.raw", "wb");
+    if (fout == NULL) {
+        printf("Error opening output file\n");
+        exit(1);
+    }
+
+    ftotal = fopen("total.txt", "wt");
+    assert(ftotal != NULL);
+
+    /* clear filter memories */
+
+    for(i=0; i<FDMDV_OS_TAPS_16K; i++)
+       adc16k[i] = 0.0;
+    for(i=0; i<FDMDV_OS_TAPS_8K; i++)
+       dac8k[i] = 0.0;
+
+    nin = freedv_nin(f);
+    nin_16k = 2*nin;
+    nout = nin;
+    while (fread(&adc16k[FDMDV_OS_TAPS_16K], sizeof(short), nin_16k, fin) == nin_16k) {
+
+        PROFILE_SAMPLE(fdmdv_16_to_8_start);
+
+        fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], nin);
+
+        PROFILE_SAMPLE_AND_LOG(freedv_rx_start, fdmdv_16_to_8_start, "  fdmdv_16_to_8");
+
+        nout = freedv_rx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);
+        nin = freedv_nin(f); nin_16k = 2*nin;
+
+        PROFILE_SAMPLE_AND_LOG(fdmdv_8_to_16_start, freedv_rx_start, "  freedv_rx");
+
+        fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], nout);
+
+        PROFILE_SAMPLE_AND_LOG2(fdmdv_8_to_16_start, "  fdmdv_8_to_16");
+
+        fprintf(ftotal, "%d\n", machdep_profile_sample() - fdmdv_16_to_8_start);
+        machdep_profile_print_logged_samples();
+
+        fwrite(dac16k, sizeof(short), 2*nout, fout);
+        freedv_get_modem_stats(f, &sync, &snr_est);
+        printf("frame: %d nin_16k: %d sync: %d SNR: %3.2f \n",
+               ++frame, nin_16k, sync, (double)snr_est);
+    }
+
+    fclose(fin);
+    fclose(fout);
+    fclose(ftotal);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/freedv_tx_profile.c b/codec2/branches/0.7/stm32/src/freedv_tx_profile.c
new file mode 100644 (file)
index 0000000..c1c0b02
--- /dev/null
@@ -0,0 +1,90 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: freedv_tx_profile.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 13 August 2014
+
+  Profiling freedv_tx() operation on the STM32F4.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "gdb_stdio.h"
+#include "freedv_api.h"
+#include "machdep.h"
+
+#ifdef __EMBEDDED__
+#define printf gdb_stdio_printf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#define fread gdb_stdio_fread
+#define fwrite gdb_stdio_fwrite
+#endif
+
+int main(int argc, char *argv[]) {
+    struct freedv *f;
+    FILE          *fin, *fout;
+    int            frame, n_samples;
+    PROFILE_VAR(freedv_start);
+
+    machdep_profile_init();
+
+    f = freedv_open(FREEDV_MODE_1600);
+    n_samples = freedv_get_n_speech_samples(f);
+    short inbuf[n_samples], outbuf[n_samples];
+
+    // Transmit ---------------------------------------------------------------------
+
+    fin = fopen("stm_in.raw", "rb");
+    if (fin == NULL) {
+        printf("Error opening input file\n");
+        exit(1);
+    }
+
+    fout = fopen("mod.raw", "wb");
+    if (fout == NULL) {
+        printf("Error opening output file\n");
+        exit(1);
+    }
+
+    frame = 0;
+
+    while (fread(inbuf, sizeof(short), n_samples, fin) == n_samples) {
+        PROFILE_SAMPLE(freedv_start);
+        freedv_tx(f, outbuf, inbuf);
+        PROFILE_SAMPLE_AND_LOG2(freedv_start, "  freedv_tx");
+
+        fwrite(outbuf, sizeof(short), n_samples, fout);
+        printf("frame: %d\n", ++frame);
+        machdep_profile_print_logged_samples();
+   }
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/gdb_stdio.c b/codec2/branches/0.7/stm32/src/gdb_stdio.c
new file mode 100644 (file)
index 0000000..46245e4
--- /dev/null
@@ -0,0 +1,125 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: gdb_stdio.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 23 2013
+
+  Some stdio I/O functions that perform I/O on the host using gdb.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include "gdb_stdio.h"
+
+#define MAX_STR 2048
+
+/* command codes we use to signal host */
+
+#define GDB_STDIO_PRINTF  1
+#define GDB_STDIO_FOPEN   2
+#define GDB_STDIO_FCLOSE  3
+#define GDB_STDIO_FWRITE  4
+#define GDB_STDIO_FREAD   5
+#define GDB_STDIO_FPRINTF 6
+
+/* globals we use to communicate with host */
+
+volatile int   gdb_stdio_func = 0;
+volatile int   gdb_stdio_ret;
+volatile char *gdb_stdio_pstr1;
+volatile char *gdb_stdio_pstr2;
+volatile int   gdb_stdio_strlen1;
+volatile int   gdb_stdio_strlen2;
+volatile FILE *gdb_stdio_file;
+volatile void *gdb_stdio_ptr;
+volatile int   gdb_stdio_size;
+volatile int   gdb_stdio_nmem;
+
+void gdb_stdio_fprintf(FILE *file, const char *format, ...) {
+    va_list arg;
+    char str[MAX_STR];
+
+    va_start(arg, format);
+    vsnprintf(str, MAX_STR, format, arg);
+    va_end(arg);
+    gdb_stdio_file = file;
+    gdb_stdio_pstr1 = str;
+    gdb_stdio_strlen1 = strlen(str);
+
+    gdb_stdio_func = GDB_STDIO_FPRINTF;
+    while(gdb_stdio_func);
+}
+
+void gdb_stdio_printf(const char *format, ...) {
+    va_list arg;
+    char str[MAX_STR];
+
+    va_start(arg, format);
+    vsnprintf(str, MAX_STR, format, arg);
+    va_end(arg);
+    gdb_stdio_pstr1 = str;
+    gdb_stdio_strlen1 = strlen(str);
+
+    gdb_stdio_func = GDB_STDIO_PRINTF;
+    while(gdb_stdio_func);
+}
+
+FILE *gdb_stdio_fopen(char file_name[], char mode[]) {
+    gdb_stdio_pstr1 = file_name;
+    gdb_stdio_pstr2 = mode;
+    gdb_stdio_strlen1 = strlen(file_name);
+    gdb_stdio_strlen2 = strlen(mode);
+
+    gdb_stdio_func = GDB_STDIO_FOPEN;
+    while(gdb_stdio_func);
+    return (FILE*)gdb_stdio_ret;
+}
+
+void gdb_stdio_fclose(FILE *file) {
+    gdb_stdio_file = file;
+
+    gdb_stdio_func = GDB_STDIO_FCLOSE;
+    while(gdb_stdio_func);
+}
+
+int gdb_stdio_fwrite(void *ptr, int size, int nmem, FILE *file) {
+    gdb_stdio_ptr = ptr;
+    gdb_stdio_size = size;
+    gdb_stdio_nmem = nmem;
+    gdb_stdio_file = file;
+
+    gdb_stdio_func = GDB_STDIO_FWRITE;
+    while(gdb_stdio_func);
+    return gdb_stdio_ret;
+}
+
+int gdb_stdio_fread(void *ptr, int size, int nmem, FILE *file) {
+    gdb_stdio_ptr = ptr;
+    gdb_stdio_size = size;
+    gdb_stdio_nmem = nmem;
+    gdb_stdio_file = file;
+
+    gdb_stdio_func = GDB_STDIO_FREAD;
+    while(gdb_stdio_func);
+    return gdb_stdio_ret;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/iir_duc.c b/codec2/branches/0.7/stm32/src/iir_duc.c
new file mode 100644 (file)
index 0000000..2c93059
--- /dev/null
@@ -0,0 +1,371 @@
+ /*---------------------------------------------------------------------------*\
+
+  FILE........: iir_duc.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 6 Mar 2015
+
+  Interapolator/Filter for IF upconversion
+
+  Unit testing:
+
+    ~/codec2-dev/stm32$ gcc -D__UNITTEST__ -Iinc src/iir_duc.c -o iir_duc -lm -Wall -I../src/
+    ~/codec2-dev/stm32$ ./iir_duc
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 Brady O'Brien
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stm32f4_dacduc.h"
+#include "iir_duc.h"
+
+#define BETA1                    0.99002                       // B1MUL/(2**B1SHFT)
+#define B1MUL                   32441
+#define B1SMUL                  -38328
+#define B1SHFT                  15                             // 10 bits gives us plenty of headroom between 31 bits of int and 14 bits of ADC
+#define B2MUL                   24593                          // This actually matches BETA2 exactly with the supplied BETA1
+#define B2SHFT                  15                             // 10 is also the lowest we can go without beta1=1
+#define BETA2                    (1.0 - (1.0-BETA1)*DUC_M)     // B2MUL/(2**B2SHFT)
+#define IN_SCALE                 2.0                            //Input scaling factor. Should be as large as the amplitude of the incoming samples
+#define DAC_SCALE                4096                           //Maximum output to DAC
+#define DAC_SCALE_2             2040
+
+
+//IIR and FIR filter states. Global for go fast.
+float f_1,f_2,f;
+int   n_1,n_2,n,m_1,m_2,m;
+
+/*
+   Upconvert and bandpass filter a chunk of spectrum from Fs/M to Fs. We're going for 700khz here.
+   modin needs to be DUC_N long and dac_out needs to be DUC_N*DUC_M long. This
+*/
+
+void iir_upconv(float modin[], unsigned short dac_out[]){
+    int i,j,k;
+    int m;
+    k=0;
+    //Iterate through input samples and apply pre-eq FIR, interpolate, and apply BPF IIR
+    for(i=0;i<DUC_N;i++){
+        f = modin[i]+f_2*BETA2;
+        f_2 = f_1;
+        f_1 = modin[i];                                             //Scale fir output and convert to fixed.
+        m = (int)((f/(IN_SCALE))*DAC_SCALE_2);                      //Scale fir output and convert to fixed
+        n = m + ((B1SMUL*n_1)>>B1SHFT) - ((B1MUL*n_2)>>B1SHFT);   //Apply one cycle of IIR. This feeds the fir-ed sample into the output filter
+        n_2 = n_1;
+        n_1 = n;
+        dac_out[k]=(unsigned short)(n+DAC_SCALE_2);
+        k++;
+        //now do the rest of the filtering. Because we're zero-stuffing we can neglect the sample from the fir filter.
+        for(j=1;j<DUC_M;j++,k++){
+            n = ((B1SMUL*n_1)>>B1SHFT) - ((B1MUL*n_2)>>B1SHFT);
+            n_2 = n_1;
+            n_1 = n;
+            dac_out[k]=(unsigned short)((n)+DAC_SCALE_2);
+        }
+    }
+}
+
+/*
+   Upconvert and bandpass filter a chunk of spectrum from Fs/M to Fs. We're going for 700khz here.
+   modin needs to be DUC_N long and dac_out needs to be DUC_N*DUC_M long. This
+*/
+
+void iir_upconv_fixp(int modin[], unsigned short dac_out[]){
+    int i,j,k;
+    int l;
+    k=0;
+    //Iterate through input samples and apply pre-eq FIR, interpolate, and apply BPF IIR
+    for(i=0;i<DUC_N;i++){
+        l = modin[i];//(modin[i]*10)>>4;
+        m = l+((m_2*B2MUL)>>B2SHFT);
+        m_2 = m_1;
+        m_1 = l;                                             //Scale fir output and convert to fixed.
+        //m = (int)((f/(IN_SCALE))*DAC_SCALE_2);                      //Scale fir output and convert to fixed
+        n = m + ((B1SMUL*n_1)>>B1SHFT) - ((B1MUL*n_2)>>B1SHFT);   //Apply one cycle of IIR. This feeds the fir-ed sample into the output filter
+        n_2 = n_1;
+        n_1 = n;
+        dac_out[k]=(unsigned short)(n+DAC_SCALE_2);
+        k++;
+        //now do the rest of the filtering. Because we're zero-stuffing we can neglect the sample from the fir filter.
+        for(j=1;j<DUC_M;j++,k++){
+            n = ((B1SMUL*n_1)>>B1SHFT) - ((B1MUL*n_2)>>B1SHFT);
+            n_2 = n_1;
+            n_1 = n;
+            dac_out[k]=(unsigned short)((n)+DAC_SCALE_2);
+        }
+    }
+}
+
+#define F48C80R_LEN 25
+#define F48C80R_MUL 4096
+static int js3 = 0;                           //Index for downsampling
+static int js5 = 0;                           //Index for upsampling
+static unsigned int w48c80r;                  //Phase for real to comp conversion
+static int ptr_48c80r;                        //Pointer in fir delay lines
+static int fir_48c80r[];                      //Fir filter coeffs
+static int fir_48c80r_re[F48C80R_LEN*2];      //Real delay line. Can probably be made much smaller.
+static int fir_48c80r_im[F48C80R_LEN*2];      //Imag delay line. Can probably be made much smaller.
+static int * sel_48c80r[2] = {fir_48c80r_re,fir_48c80r_im};    //Selector used to optimize out branches in inner loops
+
+/*
+   Interpolate and shift from 48k complex to 80k real, centered on Fs/4.
+    comp_8 - Input samples - 8Kc complex - must be DUC_48N*count long
+    upout - Output samples - must be DUC_N*count long
+    count - how many chunks of samples must be processed
+*/
+
+void upconv_48c_80r(COMP comp_48[],int real_80[],int count){
+    int i,j,k;         //Loop counters
+    int ret;         //Temp vars
+    int nr,ni;         //Temp vars
+    int inidx = 0;     //Input index
+    int outidx = 0;
+    int ncs_48c80r[3];
+    for(i=0;i<count;i++){ //Iterate through sample blocks
+        for(j=0;j<DUC_N*3;j++){ //Iterate through high rate intermediate
+            if(js5==0){              //Upsample by 5
+                nr=(int)(comp_48[inidx].real*F48C80R_MUL);
+                ni=(int)(comp_48[inidx].imag*F48C80R_MUL);
+                fir_48c80r_re[ptr_48c80r] = nr;
+                fir_48c80r_im[ptr_48c80r] = ni;
+                fir_48c80r_re[ptr_48c80r+F48C80R_LEN] = nr;
+                fir_48c80r_im[ptr_48c80r+F48C80R_LEN] = ni;
+                inidx++;
+                js5=5;
+                if(ptr_48c80r>=F48C80R_LEN)
+                    ptr_48c80r-=F48C80R_LEN;
+            }
+            if(js3==0){               //Downsample by 3
+                ni=0;
+                /*This loop computes the FIR filter. It only computes from either the re or the im delay line,
+                    depending on comp->re phase It also skips all 'zeros' in the delay line */
+                for(k=js5;k<F48C80R_LEN;k+=5)
+                    ni+=(fir_48c80r[k]*sel_48c80r[w48c80r&0x1][ptr_48c80r+k]);
+                ncs_48c80r[0]=ni;
+                ncs_48c80r[2]=-ni;
+                ret=(ncs_48c80r[w48c80r&0x2]);
+                real_80[outidx]=ret>>14; //Scale back result; should probably just return int
+                outidx++;
+                js3=3;
+                w48c80r+=3;
+            }
+            ptr_48c80r++;
+            js3--;
+            js5--;
+        }
+    }
+}
+
+#define F8C80R_LEN 42                                     //Number of taps in the 8C80R filters
+#define F8C80R_MUL 4096
+static int int1r,int2r,int3r,int4r,int5r,cmb1r,cmb2r,cmb3r,cmb4r,cmb5r; //States for re combs and integrators
+static int int1i,int2i,int3i,int4i,int5i,cmb1i,cmb2i,cmb3i,cmb4i,cmb5i; //States for im combs and integrators
+static int ptr_8c80r;                                       //circular buffer ptr fir_8c80r_re
+static int w8c80r = 0;                                      //Omega for upconversion
+
+static int fir_8c80r_cic_i[];                               //FIR Coeffs
+static int fir_8c80r_re[F8C80R_LEN*2];                      //FIR delay line for re
+static int fir_8c80r_im[F8C80R_LEN*2];                      //FIR delay line for im
+
+/*
+   Interpolate and shift from 8k complex to 80k real, centered on Fs/4.
+    comp_8 - Input samples - 8Kc complex - must be (DUC_N/10)*count long
+    upout - Output samples - must be DUC_N*count long
+    count - how many chunks of samples must be processed
+*/
+
+void upconv_8c_80r(COMP comp_8[],float real_80[],int count){
+    int i,j,k;                           //Loop indices
+    float ret;                     //Temporary variables
+    int nr,ni;
+    int cmbr,cmbi,cmbrr,cmbii,rein,imin; //More temporaries
+    int inidx = 0;                       //Index of input
+    int outidx = 0;                      //Index of output
+    for(i=0;i<count;i++){                //Iterate through chunks of samples
+        for(j=0;j<DUC_N/5;j++){
+            if(j&0x1){ //If j is odd, stuff a zero, otherwise get a sample
+                nr = 0;
+                ni = 0;
+            } else {
+                nr = (int)(comp_8[inidx].real*F8C80R_MUL);
+                ni = (int)(comp_8[inidx].imag*F8C80R_MUL);
+                inidx++;
+            }
+            // Put the sample in the delay line
+            fir_8c80r_re[ptr_8c80r]=nr;
+            fir_8c80r_im[ptr_8c80r]=ni;
+            fir_8c80r_re[ptr_8c80r+F8C80R_LEN]=nr;
+            fir_8c80r_im[ptr_8c80r+F8C80R_LEN]=ni;
+            nr=0; ni=0;
+            //Some special initilization voodoo is done here.
+            //We skip all of the zeros by setting up the loop this way
+            for(k=(j&0x1);k<F8C80R_LEN;k+=2){
+                nr+=(fir_8c80r_cic_i[k]*fir_8c80r_re[ptr_8c80r+k])>>14;
+                ni+=(fir_8c80r_cic_i[k]*fir_8c80r_im[ptr_8c80r+k])>>14;
+            }
+            ptr_8c80r++;                          //Spin the dealy line index
+            if(ptr_8c80r>=F8C80R_LEN)
+                ptr_8c80r=0;
+            rein=nr;
+            imin=ni;
+            cmbr =  rein - cmb1r; cmb1r = rein;   //Comb 1 real
+            cmbrr = cmbr - cmb2r; cmb2r = cmbr;   //Comb 2 real
+            cmbr = cmbrr - cmb3r; cmb3r = cmbrr;  //Comb 3 real
+            cmbrr = cmbr - cmb4r; cmb4r = cmbr;   //Comb 4 real
+           cmbr = cmbrr - cmb5r; cmb5r = cmbrr;
+
+            cmbi =  imin - cmb1i; cmb1i = imin;   //Comb 1 im
+            cmbii = cmbi - cmb2i; cmb2i = cmbi;   //Comb 2 im
+            cmbi = cmbii - cmb3i; cmb3i = cmbii;  //Comb 3 im
+            cmbii = cmbi - cmb4i; cmb4i = cmbi;   //Comb 4 im
+            cmbi = cmbii - cmb5i; cmb5i = cmbii;   //Comb 4 im
+            //Do first cycle of integration
+            int1r = cmbr + int1r;                //Integrator stage 1 re
+            int2r = int1r + int2r;                //Integrator stage 2 re
+            int3r = int2r + int3r;                //Integrator stage 3 re
+            int4r = int3r + int4r;                //Integrator stage 4 re
+            int5i = int4i + int5i;
+
+            int1i = cmbi + int1i;                //Integrator stage 1 im
+            int2i = int1i + int2i;                //Integrator stage 2 im
+            int3i = int2i + int3i;                //Integrator stage 3 im
+            int4i = int3i + int4i;                //Integrator stage 4 im
+            int5r = int4r + int5r;
+            //Convert this complex into real and cancel out the gain from CIC
+            //This should probably spit out integers instead of going back to float
+            switch(w8c80r&0x3){                   //Do comp->real conversion by hand
+                case 0:ret=(float)(-int5i>>7);break;
+                case 1:ret=(float)(int5r>>7);break;
+                case 2:ret=(float)(int5i>>7);break;
+                case 3:ret=(float)(-int5r>>7);break;
+            }
+            real_80[outidx] = ret/8192;   //Divide by 4096 to cancel out gain
+            outidx++;
+            w8c80r++;     //spin omega
+            //Next 4 stages of integration. Stage 1 can be ignored because of zero stuffing.
+            for(k=1;k<5;k++){
+                int2r = int1r + int2r;            //Integrator stage 2 re
+                int3r = int2r + int3r;            //Integrator stage 3 re
+                int4r = int3r + int4r;            //Integrator stage 4 re
+               int5r = int4r + int5r;
+                int2i = int1i + int2i;            //Integrator stage 2 im
+                int3i = int2i + int3i;            //Integrator stage 3 im
+                int4i = int3i + int4i;            //Integrator stage 4 im
+               int5i = int4i + int5i;
+                switch(w8c80r&0x3){               //Do comp->real conversion by hand
+                    case 0:ret=(float)(-int5i>>7);break;
+                    case 1:ret=(float)(int5r>>7);break;
+                    case 2:ret=(float)(int5i>>7);break;
+                    case 3:ret=(float)(-int5r>>7);break;
+                }
+                real_80[outidx] = ret/8192;  //Cancel out gain from all that.
+                outidx++;
+               w8c80r++;
+            }
+        }
+    }
+}
+
+#ifdef __UNITTEST__
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#define FS     80000
+#define AMP_MAX 1
+
+#define NOUT_BUFS    500
+#define NIN          (NOUT_BUFS*DUC_N)
+#define NOUT         (NIN*DUC_M)
+
+void synth_line(float us[], float f, float amp, int n) {
+    float w, sam;
+    int   i;
+
+    w = 2*M_PI*f/(float)FS;
+
+    for(i=0; i<n; i++) {
+        sam = amp*AMP_MAX*cos(w*i);
+        us[i] += sam;
+    }
+}
+
+COMP       in[48000];
+int       s[NIN];
+float      fout[NIN];
+unsigned short todac[NOUT];
+
+int main(void) {
+    float          w;
+    FILE          *f;
+    int            i;
+
+    for(i=0;i<48000;i++){
+        //Tone at Fs/4 +/- 3K
+       w = 2.*M_PI*1000./(float)(FS/10);
+        in[i].real=cos((float)i*w);
+        //in[i].imag=.1*sin((float)i*w);
+        //in[i].real=0;
+        //in[i].real=1;
+        in[i].imag=0;
+    }
+
+    //Impulse to give us an idea of our filter bands
+    in[0].imag=0.70710678118;
+    in[0].real=0.70710678118;
+
+    //interpolate from 8k comp to 80k real
+    upconv_48c_80r(in,s,NOUT_BUFS);
+    for(i=0;i<NOUT_BUFS;i++)
+        iir_upconv_fixp(&s[i*(DUC_N)],&todac[i*(DUC_N*DUC_M)]);
+
+    f = fopen("iir_duc_s.txt", "wt");  assert(f != NULL);
+    for(i=0; i<NIN; i++)
+        fprintf(f, "%d\n", s[i]);
+    fprintf(f, "\n");
+    fclose(f);
+
+    f = fopen("iir_duc.txt", "wt");  assert(f != NULL);
+    for(i=0; i<NOUT; i++)
+        fprintf(f, "%d\n", todac[i]);
+    fprintf(f, "\n");
+    fclose(f);
+    return 0;
+}
+
+#endif
+
+
+//Coeffs for fixed point fir LPF and CIC precompensation
+static int fir_8c80r_cic_i[] = {
+    0,    0,   -2,   16,  -16,  -20,   26,   37,  -47,  -68,
+   83,  116, -139, -187,  219,  294, -339, -461,  528,  766,
+ -882,-1540, 1730, 6117, 6117, 1730,-1540, -882,  766,  528,
+ -461, -339,  294,  219, -187, -139,  116,   83,  -68,  -47,
+   37,   26,
+};
+
+//Coeffs for fir filter used in 48k comp to 80k real conversion
+static int fir_48c80r[] = {
+  -21,  -41,  -74, -109, -115,  -42,  153,  493,  958, 1483,
+ 1970, 2316, 2441, 2316, 1970, 1483,  958,  493,  153,  -42,
+ -115, -109,  -74,  -41,  -21,
+};
+
+
diff --git a/codec2/branches/0.7/stm32/src/iir_tuner.c b/codec2/branches/0.7/stm32/src/iir_tuner.c
new file mode 100644 (file)
index 0000000..8421995
--- /dev/null
@@ -0,0 +1,325 @@
+ /*---------------------------------------------------------------------------*\
+
+  FILE........: iir_tuner.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 20 Feb 2015
+
+  Filter/decimator function, broken out to this file so we can unit
+  test easily.
+
+  Unit testing:
+
+    ~/codec2-dev/stm32$ gcc -D__UNITTEST__ -Iinc src/iir_tuner.c -o iir_tuner -lm -Wall
+    ~/codec2-dev/stm32$ ./iir_tuner
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef __UNITTEST__
+
+#include <assert.h>
+#include <math.h>
+#include <stdio.h>
+
+#endif
+
+#include "stm32f4_adc_tuner.h"
+#include "iir_tuner.h"
+
+/* Filter coefficients of IIR tuner (BETA1) and FIR equaliser (BETA2).
+   Note neat trick to relate BETA2 to BETA1 by the decimation rate */
+
+#define BETA1                    .9990234375                   // B1MUL/(2**B1SHFT)
+#define B1MUL                   1023
+#define B1SMUL                  1204
+#define B1SHFT                  10                             // 10 bits gives us plenty of headroom between 31 bits of int and 14 bits of ADC
+#define B2MUL                   979                            // This actually matches BETA2 exactly with the supplied BETA1
+#define B2SHFT                  10                             // 10 is also the lowest we can go without beta1=1
+#define BETA2                    (1.0 - (1.0-BETA1)*ADC_TUNER_M)// B2MUL/(2**B2SHFT)
+
+#define FIXED_IIR                                               //Define this to compile a fixed point IIR filter
+
+/* filter states - we keep them global due to the need for speed */
+
+#ifdef FIXED_IIR
+int n_2, n_1, o_2, o_1;
+#else
+float y_2, y_1, z_2, z_1;
+#endif
+
+/*
+   ADC -> signed conversion - IIR BPF - Decimate - FIR Equaliser -> FIFO
+*/
+
+void iir_tuner(
+               float          dec_50[],   // ADC_TUNER_N/2 output samples
+               unsigned short adc_buf[]   // ADC_TUNER_BUF_SZ/2 input samples
+) 
+{
+    int i, j, k;
+#ifndef FIXED_IIR
+    float x, y, z;
+#endif
+    int n, m, o;
+
+    for(i=0, j=0; i<ADC_TUNER_BUF_SZ/2; j++) {
+
+        /* IIR BPF centred at Fs/4.  All your MIPs are belong to this
+           loop. */
+        for(k=0; k<ADC_TUNER_M; k++,i++) {
+            #ifdef FIXED_IIR
+            m = (int)adc_buf[i];
+            n = m - ((B1SMUL*n_1)>>B1SHFT) - ((B1MUL*n_2)>>B1SHFT);
+            n_2 = n_1;
+            n_1 = n;
+            #else
+           x = (int)adc_buf[i] - 32768;
+           y = x - (BETA1*y_2);
+           y_2 = y_1;
+            y_1 = y;
+            #endif
+        }
+
+        /* Equaliser FIR filter, notch at Fs/(4*ADC_TUNER_M) to smooth out
+           IIR BPF passband response */
+        #ifdef FIXED_IIR
+       o = n + ((B2MUL*o_2)>>B2SHFT);
+       dec_50[j] = (float)o;
+       o_2 = o_1;
+       o_1 = n;
+        #else
+       z=y+BETA2*z_2;
+       dec_50[j] = z;
+        z_2 = z_1;
+        z_1 = y;
+        #endif
+
+    }
+}
+
+
+/* BPF at 12.5 kHz +/- 2000 Hz, and decimate down to Fs = 10kHz */
+
+static float fir_50_to_10[];
+void iir_tuner_dec_50_to_10(float dec_10[], float dec_50[], int n) {
+    int   i,j,k;
+    float acc;
+
+    for(i=0,k=0; i<n; i+=5,k++) {
+        acc = 0.0;
+        for(j=0; j<IIR_TUNER_DEC_50_10_FILT_MEM; j++)
+            acc += dec_50[i-j]*fir_50_to_10[j];
+        dec_10[k] = acc;
+    }
+
+}
+
+
+#ifdef __UNITTEST__
+
+#define FS      2000000
+#define AMP_MAX 32767
+
+#define NOUT_BUFS    100
+#define NOUT         (NOUT_BUFS*ADC_TUNER_N)
+#define NIN          (NOUT*ADC_TUNER_M)
+
+void synth_line(unsigned short us[], float f, float amp, int n) {
+    float w, sam;
+    int   i;
+
+    w = 2*M_PI*f/(float)FS;
+
+    for(i=0; i<n; i++) {
+        sam = amp*AMP_MAX*cos(w*i);
+        us[i] += (unsigned short)(sam + 0.5);
+    }
+}
+
+
+int main(void) {
+    float          f1,f2,f3,f4;
+    unsigned short s[NIN];
+    float          dec_50[IIR_TUNER_DEC_50_10_FILT_MEM+NOUT];
+    float          dec_10[NOUT/5];
+    FILE          *f;
+    int            i,j,k;
+    short          dec_10_short;
+
+    /* test Fs=2E6 unsigned short to Fs=50E3 float tuner/resampler -----------------------*/
+
+    f1 = 700E3;
+    f2 = f1 + 8E3;       /* wanted */
+    f3 = f1 - 7E3;       /* wanted */
+    f4 = f1 - 207E3;     /* out of band, should be greatly attenuated */
+
+    for(i=0; i<NIN; i++)
+        s[i] = 32767;
+    synth_line(s, f1, 1, NIN);
+    //synth_line(s, f3, 0.1, NIN);
+    //synth_line(s, f4, 0.2, NIN);
+    for(i=0, j=0; i<NIN; i+=ADC_TUNER_BUF_SZ/2, j+=ADC_TUNER_N/2) {
+        iir_tuner(&dec_50[j], &s[i]);
+    }
+
+    f = fopen("iir_tuner_s.txt", "wt");  assert(f != NULL);
+    for(i=0; i<NIN; i++)
+        fprintf(f, "%d\n", s[i]);
+    fprintf(f, "\n");
+    fclose(f);
+
+    f = fopen("iir_tuner.txt", "wt");  assert(f != NULL);
+    for(i=0; i<NOUT; i++)
+        fprintf(f, "%f\n", dec_50[i]);
+    fprintf(f, "\n");
+    fclose(f);
+
+    /* test FS=2E6 unsigned short -> Fs=10kHz short ---------------------------------------------*/
+
+    for(i=0; i<NIN; i++)
+        s[i] = 32767;
+    for(i=1; i<NIN; i+=4)
+        s[i] += 32767;
+    for(i=3; i<NIN; i+=4)
+        s[i] -= 32767;
+
+    for(i=0, j=0, k=0; i<NIN; i+=ADC_TUNER_BUF_SZ/2, j+=ADC_TUNER_N/2, k+=(ADC_TUNER_N/2)/5) {
+        iir_tuner(&dec_50[IIR_TUNER_DEC_50_10_FILT_MEM+j], &s[i]);
+        iir_tuner_dec_50_to_10(&dec_10[k], &dec_50[IIR_TUNER_DEC_50_10_FILT_MEM+j], ADC_TUNER_N/2);
+    }
+
+    f = fopen("iir_tuner2.txt", "wt");  assert(f != NULL);
+    for(i=0; i<NOUT/5; i++) {
+        dec_10_short = dec_10[i]/ADC_TUNER_M;
+        fprintf(f, "%d\n", dec_10_short);
+    }
+    fprintf(f, "\n");
+    fclose(f);
+
+    return 0;
+}
+
+#endif
+
+/* Band pass FIR filter coefficents centred on Fs/4, used before Fs=50kHz to Fs=10kHz */
+
+static float fir_50_to_10[] = {
+    -1.71502876e-07,
+    -3.93029078e-05,
+    -5.30743362e-04,
+    1.17938704e-04,
+    1.09727519e-03,
+    -1.90605585e-04,
+    -1.61350037e-03,
+    2.37746793e-04,
+    1.86947117e-03,
+    -2.28459776e-04,
+    -1.56457257e-03,
+    1.33627883e-04,
+    4.28669971e-04,
+    5.51555269e-05,
+    1.60217953e-03,
+    -3.09989338e-04,
+    -4.22595074e-03,
+    5.63604865e-04,
+    6.71504730e-03,
+    -7.23797964e-04,
+    -8.02135199e-03,
+    7.03165104e-04,
+    7.05924883e-03,
+    -4.54750532e-04,
+    -3.11212393e-03,
+    2.24463518e-08,
+    -3.75334414e-03,
+    5.63496992e-04,
+    1.24113249e-02,
+    -1.08145162e-03,
+    -2.06694342e-02,
+    1.38572694e-03,
+    2.55955103e-02,
+    -1.34897285e-03,
+    -2.41472078e-02,
+    9.32473244e-04,
+    1.39715800e-02,
+    -2.09763900e-04,
+    5.83111135e-03,
+    -6.44614872e-04,
+    -3.42028021e-02,
+    1.40049434e-03,
+    6.80569757e-02,
+    -1.83898122e-03,
+    -1.02710848e-01,
+    1.82014182e-03,
+    1.32754277e-01,
+    -1.32936318e-03,
+    -1.53163914e-01,
+    4.86473969e-04,
+    1.60393264e-01,
+    4.86473969e-04,
+    -1.53163914e-01,
+    -1.32936318e-03,
+    1.32754277e-01,
+    1.82014182e-03,
+    -1.02710848e-01,
+    -1.83898122e-03,
+    6.80569757e-02,
+    1.40049434e-03,
+    -3.42028021e-02,
+    -6.44614872e-04,
+    5.83111135e-03,
+    -2.09763900e-04,
+    1.39715800e-02,
+    9.32473244e-04,
+    -2.41472078e-02,
+    -1.34897285e-03,
+    2.55955103e-02,
+    1.38572694e-03,
+    -2.06694342e-02,
+    -1.08145162e-03,
+    1.24113249e-02,
+    5.63496992e-04,
+    -3.75334414e-03,
+    2.24463518e-08,
+    -3.11212393e-03,
+    -4.54750532e-04,
+    7.05924883e-03,
+    7.03165104e-04,
+    -8.02135199e-03,
+    -7.23797964e-04,
+    6.71504730e-03,
+    5.63604865e-04,
+    -4.22595074e-03,
+    -3.09989338e-04,
+    1.60217953e-03,
+    5.51555269e-05,
+    4.28669971e-04,
+    1.33627883e-04,
+    -1.56457257e-03,
+    -2.28459776e-04,
+    1.86947117e-03,
+    2.37746793e-04,
+    -1.61350037e-03,
+    -1.90605585e-04,
+    1.09727519e-03,
+    1.17938704e-04,
+    -5.30743362e-04,
+    -3.93029078e-05,
+    -1.71502876e-07
+};
+
diff --git a/codec2/branches/0.7/stm32/src/init.c b/codec2/branches/0.7/stm32/src/init.c
new file mode 100644 (file)
index 0000000..527141d
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ * Dummy function to avoid compiler error
+ */
+void _init() {
+
+}
+void _fini() {
+
+}
+
diff --git a/codec2/branches/0.7/stm32/src/mco_ut.c b/codec2/branches/0.7/stm32/src/mco_ut.c
new file mode 100644 (file)
index 0000000..7ef7e7a
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+     mco_ut.c
+     
+     Slightly modified version of : 
+       http://stm32f4-discovery.net/2014/10/library-40-output-clocks-stm32f4/
+     Outputs the HSI oscillator on MCO1, pin PA8, which is SCL3 on the SM2000, can
+     be probed around R124.  Used to track down a USB boot loader bug, suspect the
+     HSI on this particular STM32F407 is out so the boot loader is failing on USB
+     discovery/enumeration and forcing a reset.
+*/
+
+/* Include core modules */
+#include "stm32f4xx.h"
+/* Include my libraries here */
+#include "defines.h"
+#include "tm_stm32f4_mco_output.h"
+int main(void) {
+    /* Initialize system */
+    SystemInit();
+    /* Initialize MCO1 output, pin PA8 */
+    TM_MCOOUTPUT_InitMCO1();
+    
+    /* Initialize MCO2 output, pin PC9 */
+    TM_MCOOUTPUT_InitMCO2();
+    
+    /* Set MCO1 output = HSI with prescaler 2 = 16MHz / 2 = 8MHz*/
+    TM_MCOOUTPUT_SetOutput1(TM_MCOOUTPUT1_Source_HSI, TM_MCOOUTPUT_Prescaler_2);
+    
+    /* Set MCO2 output = SYSCLK / 4 */
+    TM_MCOOUTPUT_SetOutput2(TM_MCOOUTPUT2_Source_SYSCLK, TM_MCOOUTPUT_Prescaler_4);
+    while (1) {
+        
+    }
+}
+
diff --git a/codec2/branches/0.7/stm32/src/menu.c b/codec2/branches/0.7/stm32/src/menu.c
new file mode 100644 (file)
index 0000000..cb8ba97
--- /dev/null
@@ -0,0 +1,98 @@
+/*!
+ * Callback driven menu handler.
+ *
+ * The following is an implementation of a callback-driven menu system.
+ * It supports arbitrary levels of menus (limited by size of return stack)
+ * and supports arbitrary user events.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "menu.h"
+#include <stdlib.h>
+
+/*!
+ * Return the Nth item on the stack.
+ */
+static const struct menu_stack_item_t* const menu_stack(
+               const struct menu_t* const menu,
+               uint8_t index)
+{
+       if (menu->stack_depth <= index)
+               return NULL;
+
+       return &(menu->stack[menu->stack_depth - index - 1]);
+}
+
+/*!
+ * Return the Nth item on the stack.
+ */
+const struct menu_item_t* const menu_item(
+               const struct menu_t* const menu, uint8_t index)
+{
+       const struct menu_stack_item_t* const current
+               = menu_stack(menu, index);
+
+       if (!current)
+               return NULL;
+       return current->item;
+}
+
+/*!
+ * Enter a (sub)-menu.
+ */
+int menu_enter(struct menu_t* const menu,
+               const struct menu_item_t* const item)
+{
+       if (menu->stack_depth == MENU_STACK_SZ)
+               return -1;
+
+       menu->stack[menu->stack_depth].item = item;
+       menu->stack[menu->stack_depth].index = menu->current;
+       menu->stack_depth++;
+
+       (item->event_cb)(menu, MENU_EVT_ENTERED);
+
+       return 0;
+}
+
+/*!
+ * Return from a (sub)-menu.
+ */
+void menu_leave(struct menu_t* const menu)
+{
+       if (!menu->stack_depth)
+               return; /* Already out of the menu */
+
+       menu->last = menu_item(menu, 0);
+       menu->stack_depth--;
+
+       const struct menu_stack_item_t* current = menu_stack(menu, 0);
+       if (current && current->item) {
+               menu->current = current->index;
+               (current->item->event_cb)(menu, MENU_EVT_RETURNED);
+       }
+}
+
+/*!
+ * Execute the callback for the current item with a user-supplied event.
+ */
+void menu_exec(struct menu_t* const menu, uint32_t event)
+{
+       const struct menu_item_t* item = menu_item(menu, 0);
+       if (item && item->event_cb)
+               (item->event_cb)(menu, event);
+}
diff --git a/codec2/branches/0.7/stm32/src/morse.c b/codec2/branches/0.7/stm32/src/morse.c
new file mode 100644 (file)
index 0000000..2522993
--- /dev/null
@@ -0,0 +1,175 @@
+/*!
+ * Morse code library.
+ *
+ * This implements a state machine for playing back morse code messages.
+ * 
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include "morse.h"
+
+#include <stdio.h>
+
+/*! Symbol table element definition */
+struct morse_sym_table_t {
+       uint8_t code; uint8_t len;
+};
+
+/*! Symbol table: "digits" */
+static const struct morse_sym_table_t morse_digits[] = {
+       {       .code = 0xf8,   .len = 5        },      /* 0: ----- */
+       {       .code = 0x78,   .len = 5        },      /* 1: .---- */
+       {       .code = 0x38,   .len = 5        },      /* 2: ..--- */
+       {       .code = 0x18,   .len = 5        },      /* 3: ...-- */
+       {       .code = 0x08,   .len = 5        },      /* 4: ....- */
+       {       .code = 0x00,   .len = 5        },      /* 5: ..... */
+       {       .code = 0x80,   .len = 5        },      /* 6: -.... */
+       {       .code = 0xc0,   .len = 5        },      /* 7: --... */
+       {       .code = 0xe0,   .len = 5        },      /* 8: ---.. */
+       {       .code = 0xf0,   .len = 5        },      /* 9: ----. */
+};
+
+/*! Symbol table: "letters" */
+static const struct morse_sym_table_t morse_letters[] = {
+       {       .code = 0x40,   .len = 2        },      /* A: .-    */
+       {       .code = 0x80,   .len = 4        },      /* B: -...  */
+       {       .code = 0xa0,   .len = 4        },      /* C: -.-.  */
+       {       .code = 0x80,   .len = 3        },      /* D: -..   */
+       {       .code = 0x00,   .len = 1        },      /* E: .     */
+       {       .code = 0x20,   .len = 4        },      /* F: ..-.  */
+       {       .code = 0xc0,   .len = 3        },      /* G: --.   */
+       {       .code = 0x00,   .len = 4        },      /* H: ....  */
+       {       .code = 0x00,   .len = 2        },      /* I: ..    */
+       {       .code = 0x70,   .len = 4        },      /* J: .---  */
+       {       .code = 0xa0,   .len = 3        },      /* K: -.-   */
+       {       .code = 0x40,   .len = 4        },      /* L: .-..  */
+       {       .code = 0xc0,   .len = 2        },      /* M: --    */
+       {       .code = 0x80,   .len = 2        },      /* N: -.    */
+       {       .code = 0xe0,   .len = 3        },      /* O: ---   */
+       {       .code = 0x60,   .len = 4        },      /* P: .--.  */
+       {       .code = 0xd0,   .len = 4        },      /* Q: --.-  */
+       {       .code = 0x40,   .len = 3        },      /* R: .-.   */
+       {       .code = 0x00,   .len = 3        },      /* S: ...   */
+       {       .code = 0x80,   .len = 1        },      /* T: -     */
+       {       .code = 0x20,   .len = 3        },      /* U: ..-   */
+       {       .code = 0x10,   .len = 4        },      /* V: ...-  */
+       {       .code = 0x60,   .len = 3        },      /* W: .--   */
+       {       .code = 0x90,   .len = 4        },      /* X: -..-  */
+       {       .code = 0xb0,   .len = 4        },      /* Y: -.--  */
+       {       .code = 0xc0,   .len = 4        },      /* Z: --..  */
+};
+
+static void morse_next_sym(struct morse_player_t* const morse_player)
+{
+       struct sfx_player_t* sfx_player = &(morse_player->sfx_player);
+
+       if (!morse_player->msg) {
+               sfx_play(sfx_player, NULL);
+               return;
+       }
+
+       uint8_t sym_rem = 0;
+       uint8_t sym_code = 0;
+       const struct morse_sym_table_t* sym = NULL;
+       const char* c = morse_player->msg;
+
+       while(!sym) {
+               if ((*c >= 'A') && (*c <= 'Z'))
+                       /* Play a letter. (capitals) */
+                       sym = &morse_letters[*c - 'A'];
+               else if ((*c >= 'a') && (*c <= 'z'))
+                       /* Play a letter. (lowercase) */
+                       sym = &morse_letters[*c - 'a'];
+               else if ((*c >= '0') && (*c <= '9'))
+                       /* Play a digit. */
+                       sym = &morse_digits[*c - '0'];
+               else if (*c == 0) {
+                       morse_player->msg = NULL;
+                       return;
+               }
+               c++;
+       }
+       morse_player->msg = c;
+
+       struct sfx_note_t* note = morse_player->sym;
+       sym_rem = sym->len;
+       sym_code = sym->code;
+
+       while(sym_rem) {
+               note->freq = morse_player->freq;
+               if (sym_code & 0x80)
+                       /* Play a "dah" */
+                       note->duration = morse_player->dit_time*3;
+               else
+                       /* Play a "dit" */
+                       note->duration = morse_player->dit_time;
+               note++;
+               sym_code <<= 1;
+               sym_rem--;
+
+               /* A gap follows */
+               note->freq = 0;
+
+               if (sym_rem) {
+                       /* More of the character */
+                       note->duration = morse_player->dit_time;
+                       note++;
+               }
+       }
+
+       /* What comes next? */
+       if (*c == ' ') {
+               /* End of word */
+               note->duration = morse_player->dit_time*7;
+               note++;
+       } else if (*c) {
+               /* End of character */
+               note->duration = morse_player->dit_time*3;
+               note++;
+       }
+
+       /* Terminate the sequence */
+       note->freq = 0;
+       note->duration = 0;
+
+       /* Set the player up */
+       sfx_play(sfx_player, morse_player->sym);
+}
+
+/*!
+ * Start playing a particular effect.
+ * @param      sfx_player      Effect player state machine
+ * @param      effect          Pointer to sound effect (NULL == stop)
+ */
+void morse_play(struct morse_player_t* const morse_player,
+               const char* msg)
+{
+       morse_player->msg = msg;
+       morse_next_sym(morse_player);
+}
+
+/*!
+ * Retrieve the next sample to be played.
+ */
+int16_t morse_next(struct morse_player_t* const morse_player)
+{
+       if (!morse_player)
+               return(0);
+       if (!morse_player->sfx_player.note)
+               morse_next_sym(morse_player);
+       return sfx_next(&(morse_player->sfx_player));
+}
diff --git a/codec2/branches/0.7/stm32/src/new_i2c.c b/codec2/branches/0.7/stm32/src/new_i2c.c
new file mode 100644 (file)
index 0000000..abc5170
--- /dev/null
@@ -0,0 +1,430 @@
+/* 
+ * File:   new_i2c.h
+ * Author: leon (zs6lmg@gmail.com or leon@lrlabs.com)
+ *
+ * Created on March 17, 2016, 6:09 PM
+ * 
+ * GNU license apply.
+ * 
+ */
+
+
+/*
+  Copyright (C) 2016 Leon
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stm32f4xx.h"
+#include "stm32f4xx_conf.h"
+#include "new_i2c.h"
+//#include "cds_i2s.h"
+
+//
+//
+//
+#define CONCAT_(x,y) x##y
+#define CONCAT(x,y) CONCAT_(x,y)
+//
+//
+//
+
+//
+//
+//
+//
+#define I2C_SDA_AFPIN_ID CONCAT(GPIO_PinSource,I2C_DX_SDA)
+#define I2C_SCK_AFPIN_ID CONCAT(GPIO_PinSource,I2C_DX_SCK)
+#define I2C_SDA_PIN_ID CONCAT(GPIO_Pin_,I2C_DX_SDA)
+#define I2C_SCK_PIN_ID CONCAT(GPIO_Pin_,I2C_DX_SCK)
+
+
+/* definition to expand macro then apply to pragma message */
+// Verify that my shortcuts are actually working
+//#define VALUE_TO_STRING(x) #x
+//#define VALUE(x) VALUE_TO_STRING(x)
+//
+//#define VAR_NAME_VALUE(var) #var "="  VALUE(var)
+//#pragma message(VAR_NAME_VALUE(I2C_SCK_AFPIN_ID))
+//#pragma message(VAR_NAME_VALUE(I2C_SDA_AFPIN_ID))
+
+/*
+ * @brief Setup I2C interface pins
+ * PB6 is SCL
+ * PB9 is SDA
+ * 
+ * @param       None
+ * 
+ * @return      None
+ */
+void I2C_Setup(void) {
+    I2C_InitTypeDef I2C_Init_S;
+    GPIO_InitTypeDef GPIO_Init_P;
+    // setup the clock for the GPIO device
+    RCC_AHB1PeriphClockCmd(I2C_DX_CLK_SCK|I2C_DX_CLK_SDA, ENABLE);
+    // enable clock for the i2c device
+#if I2C_D1
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
+    // Performing a Reset
+    //RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+    //RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
+    //RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);
+#elif I2C_D3
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C3, ENABLE);
+#else
+#error "Problem on I2C"
+#endif
+    // setup the pins
+    GPIO_Init_P.GPIO_Pin=I2C_SDA_PIN_ID;
+    GPIO_Init_P.GPIO_Mode=GPIO_Mode_AF;
+    GPIO_Init_P.GPIO_Speed=GPIO_Speed_50MHz;
+    GPIO_Init_P.GPIO_OType=GPIO_OType_OD;
+    GPIO_Init_P.GPIO_PuPd=GPIO_PuPd_NOPULL;
+    GPIO_Init(I2C_DX_P_SDA, &GPIO_Init_P);
+    //
+    //
+    GPIO_Init_P.GPIO_Pin=I2C_SCK_PIN_ID;
+    GPIO_Init(I2C_DX_P_SCK, &GPIO_Init_P);
+    // assign alternate functions
+#if I2C_D1
+    GPIO_PinAFConfig(I2C_DX_P_SDA, I2C_SDA_AFPIN_ID, GPIO_AF_I2C1);
+    GPIO_PinAFConfig(I2C_DX_P_SCK, I2C_SCK_AFPIN_ID, GPIO_AF_I2C1);
+#elif I2C_D3
+    GPIO_PinAFConfig(I2C_DX_P_SDA, I2C_SDA_AFPIN_ID, GPIO_AF_I2C3);
+    GPIO_PinAFConfig(I2C_DX_P_SCK, I2C_SCK_AFPIN_ID, GPIO_AF_I2C3);
+#else
+#error "Device not defined"
+#endif
+    //
+    I2C_Cmd(I2C_DEVICE, DISABLE);
+    I2C_DeInit(I2C_DEVICE);
+    //
+    //
+    I2C_Init_S.I2C_Mode=I2C_Mode_I2C;
+    I2C_Init_S.I2C_DutyCycle=I2C_DutyCycle_2;
+    I2C_Init_S.I2C_Ack=I2C_Ack_Enable;
+    I2C_Init_S.I2C_OwnAddress1=0x00;
+    I2C_Init_S.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;
+    I2C_Init_S.I2C_ClockSpeed=I2C_SPEED;
+    I2C_Cmd(I2C_DEVICE, ENABLE);
+    I2C_Init(I2C_DEVICE, &I2C_Init_S);
+}
+
+
+
+uint32_t I2C_timeout(uint32_t retval) {
+    I2C_GenerateSTOP(I2C_DEVICE, ENABLE);
+    I2C_SoftwareResetCmd(I2C_DEVICE, ENABLE);
+    I2C_SoftwareResetCmd(I2C_DEVICE, DISABLE);
+    I2C_DeInit(I2C_DEVICE);
+    I2C_Setup();
+    return(retval);
+}
+
+
+
+/**
+ * @brief  Writes a Byte to a given register through the control interface (I2C)
+ * @param  Addr: I2C address to write to.
+ * @param  Register: Register inside device to write to.
+ * @param  Value: the Byte value to be written into destination register.
+ * @return 0 all ok.
+ *  0x101 i2c busy.
+ *  0x102 master mode not selected.
+ *  0x103 master transmitter mode.
+ *  0x104 send data failed.
+ *  0x105 no reply from device.
+ */
+uint32_t I2C_NewWriteRegister(uint8_t Addr, uint8_t Register, uint8_t Value) {
+    uint32_t result = 0;
+
+    /* check if bus is busy */
+    __IO uint32_t Timeout = I2C_LTIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_BUSY )) {
+        if ((Timeout--) == 0) return 0x101;
+    }
+    I2C_GenerateSTART(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_MODE_SELECT)) {
+        if ((Timeout--) == 0) return 0x102;
+    }
+    I2C_Send7bitAddress(I2C_DEVICE,Addr,I2C_Direction_Transmitter);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
+        if ((Timeout--) == 0) return 0x103;
+    }
+    I2C_SendData(I2C_DEVICE, Register);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_BYTE_TRANSMITTING)) {
+        if ((Timeout--) == 0) return 0x104;
+    }
+    I2C_SendData(I2C_DEVICE, Value);
+    // Wait for reply
+    Timeout = I2C_LTIMEOUT;
+    while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_BTF)) {
+        if ((Timeout--) == 0) return 0x105;
+    }
+    I2C_GenerateSTOP(I2C_DEVICE, ENABLE);
+    return result;
+}
+
+/**
+ * @brief  Writes more than 1 bytes to a given register through the control interface (I2C)
+ * @param  Addr: I2C address to write to.
+ * @param  Register: Register inside device to write to.
+ * @param  Value: the Byte(s) to be written into destination register.
+ * @param  N: Number of byte(s) to write
+ * @return 0 all ok.
+ *  0x101 i2c busy.
+ *  0x102 master mode not selected.
+ *  0x103 master transmitter mode.
+ *  0x104 send data failed.
+ *  0x105 no reply from device.
+ */
+uint32_t I2C_NewWriteRegisterN(uint8_t Addr, uint8_t Register, uint8_t *Value, uint8_t N) {
+    uint32_t result = 0;
+
+    /* check if bus is busy */
+    __IO uint8_t i;
+    __IO uint32_t Timeout = I2C_LTIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_BUSY )) {
+        if ((Timeout--) == 0) return 0x101;
+    }
+    I2C_GenerateSTART(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_MODE_SELECT)) {
+        if ((Timeout--) == 0) return 0x102;
+    }
+    I2C_Send7bitAddress(I2C_DEVICE,Addr,I2C_Direction_Transmitter);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
+        if ((Timeout--) == 0) return 0x103;
+    }
+    I2C_SendData(I2C_DEVICE, Register);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_BYTE_TRANSMITTING)) {
+        if ((Timeout--) == 0) return 0x104;
+    }
+    for (i = 0; i < N; i++) {
+        I2C_SendData(I2C_DEVICE, *(Value++));
+        // Wait for reply
+        Timeout = I2C_LTIMEOUT;
+        while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_BTF)) {
+            if ((Timeout--) == 0) return 0x105;
+        }
+    }
+    I2C_GenerateSTOP(I2C_DEVICE, ENABLE);
+    return result;
+}
+
+
+
+/**
+ * @brief  Reads a Byte to a given register via I2C
+ * @param  Addr: I2C address.
+ * @param  Register: Register inside device to read.
+ * @return value read.
+ *  0x101 i2c busy.
+ *  0x102 master mode not selected.
+ *  0x103 master transmitter mode.
+ *  0x104 send data failed.
+ *  0x105 no reply from device.
+ *  0x106 direction receive.
+ *  0x107 data register not empty.
+ *  0x108 waiting data.
+ */
+uint32_t I2C_NewReadRegister(uint8_t Addr,uint8_t Register) {
+    uint32_t result = 0;
+    __IO uint32_t Timeout = I2C_LTIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE,I2C_FLAG_BUSY)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x101);
+    }
+    I2C_GenerateSTART(I2C_DEVICE, ENABLE);
+#if (I2Cmodel == 1)
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_GetFlagStatus(I2C_DEVICE,I2C_FLAG_SB)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x102);
+    }
+    I2C_AcknowledgeConfig(I2C_DEVICE, DISABLE);
+    I2C_Send7bitAddress(I2C_DEVICE, Addr, I2C_Direction_Transmitter);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_ADDR)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x103);
+    }
+    (void) I2C_DEVICE->SR2;
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_TXE)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x104);
+    }
+    I2C_SendData(I2C_DEVICE, Register);
+    Timeout = I2C_STIMEOUT;
+    while ( (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_TXE)) ||
+            (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_BTF))
+          )  {
+        if ((Timeout--) == 0) return I2C_timeout(0x105);
+    }
+    I2C_GenerateSTART(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_SB)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x106);
+    }
+    I2C_Send7bitAddress(I2C_DEVICE, Addr, I2C_Direction_Receiver);
+    Timeout = I2C_STIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_ADDR) == RESET) {
+        if ((Timeout--) == 0) return I2C_timeout(0x107);
+    }
+    (void) I2C_DEVICE->SR2;
+    while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_RXNE)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x108);
+    }
+    I2C_GenerateSTOP(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    result = I2C_ReceiveData(I2C_DEVICE );
+    Timeout = I2C_STIMEOUT;
+    while (I2C_DEVICE ->CR1 & I2C_CR1_STOP ) {
+        if ((Timeout--) == 0) return I2C_timeout(0x109);
+    }
+    I2C_AcknowledgeConfig(I2C_DEVICE, ENABLE);
+    I2C_ClearFlag(I2C_DEVICE, I2C_FLAG_AF );
+#else
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_MODE_SELECT)) {
+        if ((Timeout--) == 0) return 0x102;
+    }
+    I2C_Send7bitAddress(I2C_DEVICE,Addr,I2C_Direction_Transmitter);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
+        if ((Timeout--) == 0) return 0x103;
+    }
+    I2C_SendData(I2C_DEVICE, Register);
+    Timeout = I2C_STIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE,I2C_FLAG_BTF) == RESET) {
+            if ((Timeout--) == 0) return 0x104;
+    }
+    I2C_GenerateSTART(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_MODE_SELECT)) {
+        if ((Timeout--) == 0) return 0x105;
+    }
+    I2C_Send7bitAddress(I2C_DEVICE,Addr,I2C_Direction_Receiver);
+    Timeout = I2C_STIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_ADDR) == RESET) {
+        if ((Timeout--) == 0) return 0x106;
+    }
+    I2C_AcknowledgeConfig(I2C_DEVICE,DISABLE);
+    (void) I2C_DEVICE->SR2;
+    I2C_GenerateSTOP(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE,I2C_FLAG_RXNE) == RESET) {
+        if ((Timeout--) == 0) return 0x107;
+    }
+    result = I2C_ReceiveData(I2C_DEVICE );
+    Timeout = I2C_STIMEOUT;
+    while (I2C_DEVICE ->CR1 & I2C_CR1_STOP ) {
+        if ((Timeout--) == 0) return 0x108;
+    }
+    I2C_AcknowledgeConfig(I2C_DEVICE, ENABLE);
+    I2C_ClearFlag(I2C_DEVICE, I2C_FLAG_AF );
+#endif
+    return result;
+}
+
+/**
+ * @brief  Reads more than one byte from a given register via I2C
+ * @param  Addr: I2C address.
+ * @param  Register: Register inside device to read.
+ * @return value read.
+ *  0x101 i2c busy.
+ *  0x102 master mode not selected.
+ *  0x103 master transmitter mode.
+ *  0x104 send data failed.
+ *  0x105 no reply from device.
+ *  0x106 direction receive.
+ *  0x107 data register not empty.
+ *  0x108 waiting data.
+ */
+uint32_t I2C_NewReadRegisterN(uint8_t Addr,uint8_t Register,uint8_t *buffer, uint8_t N) {
+    uint32_t result = 0;
+    uint8_t     cnt;
+    __IO uint32_t Timeout = I2C_LTIMEOUT;
+    if ( (N==0)||(N>64) ) return 0x109;
+    while (I2C_GetFlagStatus(I2C_DEVICE,I2C_FLAG_BUSY)) {
+        if ((Timeout--) == 0) return 0x101;
+    }
+    I2C_GenerateSTART(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_MODE_SELECT)) {
+        if ((Timeout--) == 0) return 0x102;
+    }
+    if(N==1) {
+        // ACK disable
+        I2C_AcknowledgeConfig(I2C_DEVICE, DISABLE);
+    } else {
+        // ACK enable
+        I2C_AcknowledgeConfig(I2C_DEVICE, ENABLE);
+    }
+    I2C_Send7bitAddress(I2C_DEVICE,Addr,I2C_Direction_Transmitter);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_CheckEvent(I2C_DEVICE,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) {
+        if ((Timeout--) == 0) return 0x103;
+    }
+    (void) I2C_DEVICE->SR2;
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_TXE)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x104);
+    }
+    I2C_SendData(I2C_DEVICE, Register);
+    Timeout = I2C_STIMEOUT;
+    while ( (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_TXE)) ||
+            (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_BTF))
+          )  {
+        if ((Timeout--) == 0) return I2C_timeout(0x105);
+    }
+    I2C_GenerateSTART(I2C_DEVICE, ENABLE);
+    Timeout = I2C_STIMEOUT;
+    while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_SB)) {
+        if ((Timeout--) == 0) return I2C_timeout(0x106);
+    }
+    I2C_Send7bitAddress(I2C_DEVICE, Addr, I2C_Direction_Receiver);
+    Timeout = I2C_STIMEOUT;
+    while (I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_ADDR) == RESET) {
+        if ((Timeout--) == 0) return I2C_timeout(0x107);
+    }
+    (void) I2C_DEVICE->SR2;
+    for (cnt=0; cnt<N; cnt++) {
+        if((cnt+1) >= N) {
+            // ACK disable
+            I2C_AcknowledgeConfig(I2C_DEVICE, DISABLE);
+            // Stop-Sequenz
+            I2C_GenerateSTOP(I2C_DEVICE, ENABLE);
+        }
+        Timeout = I2C_STIMEOUT;
+        while (!I2C_GetFlagStatus(I2C_DEVICE, I2C_FLAG_RXNE)) {
+            if ((Timeout--) == 0) return I2C_timeout(0x108);
+        }
+        result=I2C_ReceiveData(I2C_DEVICE);
+        Timeout = I2C_STIMEOUT;
+        while (I2C_DEVICE ->CR1 & I2C_CR1_STOP ) {
+            if ((Timeout--) == 0) return I2C_timeout(0x109);
+        }
+        *buffer=(uint8_t)(result & 0xff);
+        buffer++;
+        Timeout = I2C_STIMEOUT;
+    }
+    I2C_AcknowledgeConfig(I2C_DEVICE, ENABLE);
+    //I2C_ClearFlag(I2C_DEVICE, I2C_FLAG_AF );
+    if (result<0x100) result=0;
+    return result;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/power_ut.c b/codec2/branches/0.7/stm32/src/power_ut.c
new file mode 100644 (file)
index 0000000..9733823
--- /dev/null
@@ -0,0 +1,135 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: power_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 30 May 2014
+
+  Runs Codec 2, ADC, and DAC, to fully exercise STM32C so we can a feel for
+  run-time power consumption for SM1000 and hence dimension regulators.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "stm32f4_adc.h"
+#include "stm32f4_dac.h"
+#include "gdb_stdio.h"
+#include "codec2.h"
+#include "dump.h"
+#include "sine.h"
+#include "machdep.h"
+
+#ifdef __EMBEDDED__
+#define printf gdb_stdio_printf
+#define fopen gdb_stdio_fopen
+#define fclose gdb_stdio_fclose
+#define fread gdb_stdio_fread
+#define fwrite gdb_stdio_fwrite
+#endif
+
+#define SPEED_TEST_SAMPLES 24000
+
+/* modification of test used to measure codec2 execuation speed.  We read/write ADC/DAC
+   but dont do anything with the samples, as they are at 16 kHz and codec needs 8 kHz.  Just
+   trying to exercise everything to get a feel for power consumption */
+
+static void c2speedtest(int mode, char inputfile[])
+{
+    struct CODEC2 *codec2;
+    short         *inbuf, *outbuf, *pinbuf, *dummy_buf;
+    unsigned char *bits;
+    int            nsam, nbit, nframes;
+    FILE          *fin;
+    int            f, nread;
+
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    nframes = SPEED_TEST_SAMPLES/nsam;
+    outbuf = (short*)malloc(nsam*sizeof(short));
+    inbuf = (short*)malloc(SPEED_TEST_SAMPLES*sizeof(short));
+    nbit = codec2_bits_per_frame(codec2);
+    bits = (unsigned char*)malloc(nbit*sizeof(char));
+    dummy_buf = (short*)malloc(2*nsam*sizeof(short));
+
+    fin = fopen(inputfile, "rb");
+    if (fin == NULL) {
+        printf("Error opening input file: %s\nTerminating....\n",inputfile);
+        exit(1);
+    }
+
+    printf("reading samples ....\n");
+    nread = fread(inbuf, sizeof(short), SPEED_TEST_SAMPLES, fin);
+    if (nread != SPEED_TEST_SAMPLES) {
+        printf("error reading %s, %d samples reqd, %d read\n",
+               inputfile, SPEED_TEST_SAMPLES, nread);
+    }
+    fclose(fin);
+
+    pinbuf = inbuf;
+    for(f=0; f<nframes; f++) {
+        //printf("read ADC\n");
+        while(adc1_read(dummy_buf, nsam*2) == -1);  /* runs at Fs = 16kHz */
+
+        //printf("Codec 2 enc\n");
+       GPIOD->ODR = (1 << 13);
+        codec2_encode(codec2, bits, pinbuf);
+        pinbuf += nsam;
+       GPIOD->ODR &= ~(1 << 13);
+        //printf("Codec 2 dec\n");
+       codec2_decode(codec2, outbuf, bits);
+
+        //printf("write to DAC\n");
+        while(dac1_write(dummy_buf, nsam*2) == -1); /* runs at Fs = 16kHz */
+        //printf(".");
+    }
+
+    free(inbuf);
+    free(outbuf);
+    free(bits);
+    codec2_destroy(codec2);
+}
+
+void gpio_init() {
+    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // enable the clock to GPIOD
+    GPIOD->MODER = (1 << 26);            // set pin 13 to be general
+                                         // purpose output
+}
+
+int main(int argc, char *argv[]) {
+    SystemInit();
+    gpio_init();
+    machdep_profile_init ();
+    adc_open(4*DAC_BUF_SZ);
+    dac_open(4*DAC_BUF_SZ);
+
+    printf("Starting power_ut\n");
+
+    c2speedtest(CODEC2_MODE_1600, "stm_in.raw");
+
+    printf("Finished\n");
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/sfx.c b/codec2/branches/0.7/stm32/src/sfx.c
new file mode 100644 (file)
index 0000000..f80c8d1
--- /dev/null
@@ -0,0 +1,67 @@
+/*!
+ * Sound effect player library.
+ *
+ * This implements a state machine for playing back various monophonic
+ * sound effects such as morse code symbols, clicks and alert tones.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include "sfx.h"
+
+static void sfx_next_tone(struct sfx_player_t* const sfx_player)
+{
+       struct tone_gen_t* tone_gen = &(sfx_player->tone_gen);
+       const struct sfx_note_t* note = sfx_player->note;
+
+       if (!note) {
+               tone_reset(tone_gen, 0, 0);
+       } else {
+               tone_reset(tone_gen, note->freq, note->duration);
+
+               if (!note->duration)
+                       /* We are done */
+                       sfx_player->note = NULL;
+               else
+                       /* Move to next note */
+                       sfx_player->note++;
+       }
+}
+
+/*!
+ * Start playing a particular effect.
+ * @param      sfx_player      Effect player state machine
+ * @param      effect          Pointer to sound effect (NULL == stop)
+ */
+void sfx_play(struct sfx_player_t* const sfx_player,
+               const struct sfx_note_t* effect)
+{
+       sfx_player->note = effect;
+       sfx_next_tone(sfx_player);
+}
+
+/*!
+ * Retrieve the next sample to be played.
+ */
+int16_t sfx_next(struct sfx_player_t* const sfx_player)
+{
+       if (!sfx_player)
+               return(0);
+       if (!sfx_player->tone_gen.remain)
+               sfx_next_tone(sfx_player);
+       return tone_next(&(sfx_player->tone_gen));
+}
diff --git a/codec2/branches/0.7/stm32/src/si5351_ut.c b/codec2/branches/0.7/stm32/src/si5351_ut.c
new file mode 100644 (file)
index 0000000..d79a4da
--- /dev/null
@@ -0,0 +1,45 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: si5351_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2016
+
+  Generates a 10MHz signal on CLK0 ouput of Si5351, should be visible in 
+  attenuated form on SP7/SP7 of SM2000.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include "new_i2c.h"
+#include "si53xx.h"
+//#include "gdb_stdio.h"
+//#define printf gdb_stdio_printf
+
+int main(void) {
+
+    //printf("starting\n");
+    I2C_Setup();
+    si5351_init(0, SI5351_CRYSTAL_LOAD_6PF, 0);
+    si5351_set_freq(1000000000ULL, 0, SI5351_CLK0);
+    // int ret = si5351_set_freq(1000000000ULL, 0, SI5351_CLK0);
+    //printf(" ret = %d\n", ret);
+
+    while(1);
+}
diff --git a/codec2/branches/0.7/stm32/src/si53xx.c b/codec2/branches/0.7/stm32/src/si53xx.c
new file mode 100644 (file)
index 0000000..48576a3
--- /dev/null
@@ -0,0 +1,856 @@
+/*------------------------------------------------------------------------------
+ * 
+ * Ported to stm32F4xx non c++ by Leon Lessing leon@lrlabs.com or zs6lmg@gmail.com
+ * 
+ * 
+ * Copyright (C) 2015-2016 Jason Milldrum <milldrum@gmail.com>
+ *                         Dana H. Myers <k6jq@comcast.net>
+ *
+ * Many defines derived from clk-si5351.h in the Linux kernel.
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ * Rabeeh Khoury <rabeeh@solid-run.com>
+ *
+ * do_div() macro derived from /include/asm-generic/div64.h in
+ * the Linux kernel.
+ * Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * 
+ * 
+ *------------------------------------------------------------------------------
+*/
+
+#include "stm32f4xx.h"
+#include "stm32f4xx_conf.h"
+//#include "system.h"
+
+#include "new_i2c.h"
+//#include "inc/xprintf.h"
+#include "stdlib.h"
+#include "string.h"
+#include "math.h"
+#include "si53xx.h"
+
+
+void si5351_write(uint8_t REGaddr, uint8_t data) {
+    // ignoring errors
+    // Waiting for the bite
+    Si5351_Config.I2C_ErrorCode=I2C_NewWriteRegister(Si5351_Config.I2C_add, REGaddr, data);
+
+    /*
+    printf("  si5351_write: REGaddr: 0x%02x data...: 0x%02x", REGaddr, data);
+    if (Si5351_Config.I2C_ErrorCode > 0xff)
+        printf("  ErrorCode: 0x%02x\n", Si5351_Config.I2C_ErrorCode);
+    else
+        printf("\n");
+    */
+}
+
+void si5351_write_bulk(uint8_t REGaddr, uint8_t bytes, uint8_t *data) {
+    Si5351_Config.I2C_ErrorCode=I2C_NewWriteRegisterN(Si5351_Config.I2C_add, REGaddr, data, bytes);
+}
+
+
+uint8_t si5351_read(uint8_t REGaddr) {
+    uint8_t reg_val;
+    Si5351_Config.I2C_ErrorCode=I2C_NewReadRegister(Si5351_Config.I2C_add,REGaddr);
+    //printf("  si5351_read.: REGaddr: 0x%02x", REGaddr);
+    if (Si5351_Config.I2C_ErrorCode>0xff) {
+        reg_val=0;
+        //printf(" ErrorCode: 0x%02x\n", Si5351_Config.I2C_ErrorCode);
+    } else {
+        reg_val=(uint8_t)(Si5351_Config.I2C_ErrorCode & 0xff);
+        Si5351_Config.I2C_ErrorCode=0;
+        //printf(" reg_val: 0x%02x\n", reg_val);
+    }
+    return reg_val;
+}
+
+/*------------------------------------------------------------------------------
+ * @brief si5351_init(uint8_t xtal_load_c, uint32_t ref_osc_freq)
+ * Setup communications to the Si5351 and set the crystal
+ * load capacitance.
+ *
+ * @param I2C_Address - enter I2C address here, use 0 to use .h file defined value
+ * 
+ * @param xtal_load_c - Crystal load capacitance. Use the SI5351_CRYSTAL_LOAD_*PF
+ * defines in the header file
+ * 
+ * @param ref_osc_freq - Crystal/reference oscillator frequency in 1 Hz increments.
+ * Defaults to 25000000 if a 0 is used here.
+ * 
+ *------------------------------------------------------------------------------
+ */
+void si5351_init(uint8_t I2C_Address, uint8_t xtal_load_c, uint32_t ref_osc_freq) {
+    //printf("si5351_init\n");
+
+    Si5351_Config.clk0_freq=0;
+    Si5351_Config.lock_plla = SI5351_CLKNONE;
+    Si5351_Config.lock_pllb = SI5351_CLKNONE;
+    Si5351_Config.clk0_int_mode = 0;
+    Si5351_Config.clk1_int_mode = 0;
+    Si5351_Config.clk2_int_mode = 0;
+    Si5351_Config.plla_freq = 0;
+    Si5351_Config.pllb_freq = 0;
+    Si5351_Config.clk0_freq = 0;
+    Si5351_Config.clk1_freq = 0;
+    Si5351_Config.clk2_freq = 0;
+    Si5351_Config.xtal_freq = SI5351_XTAL_FREQ;
+    Si5351_Config.I2C_add = SI5351_BUS_BASE_ADDR << 1;
+    if (I2C_Address != 0) Si5351_Config.I2C_add=I2C_Address << 1;
+    // Set crystal load capacitance
+    uint8_t reg_val = 0x12; // 0b010010 reserved value bits
+    reg_val |= xtal_load_c;
+    si5351_write(SI5351_CRYSTAL_LOAD, reg_val);
+
+    // DR: test of I2C
+    reg_val = si5351_read(SI5351_CRYSTAL_LOAD);
+    //printf("reg_val: 0x%02x\n", reg_val);
+
+    // Change the ref osc freq if different from default
+    // Divide down if greater than 30 MHz
+    if (ref_osc_freq != 0) {
+        uint8_t reg_val;
+        reg_val = si5351_read(SI5351_PLL_INPUT_SOURCE);
+        //
+        // Clear the bits first
+        reg_val &= ~(SI5351_CLKIN_DIV_MASK);
+        if(ref_osc_freq <= 30000000) {
+            Si5351_Config.xtal_freq = ref_osc_freq;
+            reg_val |= SI5351_CLKIN_DIV_1;
+        } else if(ref_osc_freq > 30000000 && ref_osc_freq <= 60000000) {
+            Si5351_Config.xtal_freq = ref_osc_freq / 2;
+            reg_val |= SI5351_CLKIN_DIV_2;
+        } else if(ref_osc_freq > 60000000 && ref_osc_freq <= 100000000) {
+            Si5351_Config.xtal_freq = ref_osc_freq / 4;
+            reg_val |= SI5351_CLKIN_DIV_4;
+        }
+        si5351_write(SI5351_PLL_INPUT_SOURCE, reg_val);
+    }
+    // Initialize the CLK outputs according to flowchart in datasheet
+    // First, turn them off
+    si5351_write(16, 0x80);
+    si5351_write(17, 0x80);
+    si5351_write(18, 0x80);
+
+    // Turn the clocks back on...
+    si5351_write(16, 0x0c);
+    si5351_write(17, 0x0c);
+    si5351_write(18, 0x0c);
+
+    // Then reset the PLLs
+    si5351_pll_reset(SI5351_PLLA);
+    si5351_pll_reset(SI5351_PLLB);
+}
+
+
+
+
+/*------------------------------------------------------------------------------
+ * @brief si5351_set_freq(uint64_t freq, uint64_t pll_freq, enum si5351_clock output)
+ * Sets the clock frequency of the specified CLK output
+ *
+ * @param freq - Output frequency in 0.01 Hz increments, so for 10MHz 
+ *               use 1000000000ULL
+ * 
+ * @param pll_freq - Frequency of the PLL driving the Multisynth
+ *   Use a 0 to have the function choose a PLL frequency
+ * 
+ * @param clk - Clock output
+ *   (use the si5351_clock enum)
+ *------------------------------------------------------------------------------
+ */
+uint8_t si5351_set_freq(uint64_t freq, uint64_t pll_freq, enum si5351_clock clk) {
+    struct Si5351RegSet ms_reg;
+    enum si5351_pll target_pll;
+    uint8_t write_pll = 0;
+    uint8_t r_div = SI5351_OUTPUT_CLK_DIV_1;
+    uint8_t int_mode = 0;
+    uint8_t div_by_4 = 0;
+
+    //printf("si5351_set_freq:\n");
+
+    // PLL bounds checking
+    if(pll_freq != 0) {
+        if ((pll_freq < SI5351_PLL_VCO_MIN * SI5351_FREQ_MULT)
+                || (pll_freq > SI5351_PLL_VCO_MAX * SI5351_FREQ_MULT)) {
+            return 1;
+        }
+    }
+
+    //printf("freq: 0x%0x 0x%0x\n", (uint32_t)(freq >> 32), (uint32_t)(freq & 0xffffffff));
+
+    // Lower bounds check
+    if(freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT) {
+        freq = SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT;
+    }
+
+    // Upper bounds check
+    if(freq > SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT) {
+        freq = SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT;
+    }
+
+    //printf("freq: 0x%0x 0x%0x\n", (uint32_t)(freq >> 32), (uint32_t)(freq & 0xffffffff));
+
+    // Select the proper R div value
+    r_div = si5351_select_r_div(&freq);
+
+    // Calculate the synth parameters
+    // If pll_freq is 0 and freq < 150 MHz, let the algorithm pick a PLL frequency
+    if ((pll_freq) && (freq < SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT)) {
+        si5351_multisynth_calc(freq, pll_freq, &ms_reg);
+        write_pll = 0;
+        div_by_4 = 0;
+        int_mode = 0;
+
+        switch(clk)      {
+            case SI5351_CLK0:
+                    Si5351_Config.clk0_freq = freq;
+                    break;
+            case SI5351_CLK1:
+                    Si5351_Config.clk1_freq = freq;
+                    break;
+            case SI5351_CLK2:
+                    Si5351_Config.clk2_freq = freq;
+                    break;
+            default:
+                    break;
+        }
+    } else {
+        // The PLL must be calculated and set by firmware when 150 MHz <= freq <= 160 MHz
+        if(freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) {
+            pll_freq = si5351_multisynth_calc(freq, 0, &ms_reg);
+            write_pll = 1;
+            div_by_4 = 1;
+            int_mode = 1;
+        }
+
+        // Determine which PLL to use
+        // CLK0 gets PLLA, CLK1 gets PLLB
+        // CLK2 gets PLLB if necessary
+        // Only good for Si5351A3 variant at the moment
+        switch(clk) {
+            case SI5351_CLK0:
+                    //printf("case SI5351_CLK0\n");
+                    pll_freq = si5351_multisynth_calc(freq, 0, &ms_reg);
+                    target_pll = SI5351_PLLA;
+                    write_pll = 1;
+                    si5351_set_ms_source(SI5351_CLK0, SI5351_PLLA);
+
+                    //printf("pll_freq: 0x%0x 0x%0x\n", (uint32_t)(pll_freq >> 32), (uint32_t)(pll_freq & 0xffffffff));
+                    //printf("freq: 0x%0x 0x%0x\n", (uint32_t)(freq >> 32), (uint32_t)(freq & 0xffffffff));
+
+                    Si5351_Config.plla_freq = pll_freq;
+                    Si5351_Config.clk0_freq = freq;
+                    break;
+            case SI5351_CLK1:
+                    // Check to see if PLLB is locked due to other output being < 1.024 MHz or >= 112.5 MHz
+                    if(Si5351_Config.lock_pllb == SI5351_CLK2) {
+                        // We can't have a 2nd output < 1.024 MHz or >= 112.5 MHz on the same PLL unless exact same freq, so exit
+                        if((freq >= SI5351_MULTISYNTH_SHARE_MAX * SI5351_FREQ_MULT
+                                || freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 128)
+                                && freq != Si5351_Config.clk2_freq) {
+                            Si5351_Config.clk1_freq = 0;
+                            return 1;
+                        } else {
+                            // Else, set multisynth to same PLL freq as CLK2
+                            pll_freq = Si5351_Config.pllb_freq;
+                            si5351_multisynth_calc(freq, pll_freq, &ms_reg);
+                            write_pll = 0;
+                            si5351_set_ms_source(SI5351_CLK1, SI5351_PLLB);
+                        }
+                    } else {
+                        Si5351_Config.pllb_freq = pll_freq;
+                        pll_freq = si5351_multisynth_calc(freq, 0, &ms_reg);
+                        write_pll = 1;
+                        si5351_set_ms_source(SI5351_CLK1, SI5351_PLLB);
+                    }
+
+                    if(freq >= SI5351_MULTISYNTH_SHARE_MAX * SI5351_FREQ_MULT
+                            || freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 128) {
+                        Si5351_Config.lock_pllb = SI5351_CLK1;
+
+                        // Recalc and rewrite the multisynth parameters on CLK2
+                        if(Si5351_Config.clk2_freq != 0) {
+                            struct Si5351RegSet ms_temp_reg;
+                            r_div = si5351_select_r_div(&Si5351_Config.clk2_freq);
+                            si5351_multisynth_calc(Si5351_Config.clk2_freq, \
+                                    Si5351_Config.pllb_freq, &ms_temp_reg);
+                            si5351_set_ms(SI5351_CLK2, ms_temp_reg, 0, r_div, 0);
+                        }
+                    } else {
+                        Si5351_Config.lock_pllb = SI5351_CLKNONE;
+                    }
+
+                    target_pll = SI5351_PLLB;
+                    Si5351_Config.clk1_freq = freq;
+                    break;
+            case SI5351_CLK2:
+                    // Check to see if PLLB is locked due to other output being < 1.024 MHz or >= 112.5 MHz
+                    if(Si5351_Config.lock_pllb == SI5351_CLK1) {
+                        // We can't have a 2nd output < 1.024 MHz  or >= 112.5 MHz on the same PLL unless exact same freq, so exit
+                        if((freq >= SI5351_MULTISYNTH_SHARE_MAX * SI5351_FREQ_MULT
+                                || freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 128)
+                                && freq != Si5351_Config.clk2_freq) {
+                            Si5351_Config.clk2_freq = 0;
+                            return 1;
+                        } else {
+                            // Else, set multisynth to same PLL freq as CLK1
+                            pll_freq = Si5351_Config.pllb_freq;
+                            si5351_multisynth_calc(freq, pll_freq, &ms_reg);
+                            write_pll = 0;
+                            si5351_set_ms_source(SI5351_CLK2, SI5351_PLLB);
+                        }
+                    } else {
+                        // need to account for CLK2 set before CLK1
+                        Si5351_Config.pllb_freq = pll_freq;
+                        pll_freq = si5351_multisynth_calc(freq, 0, &ms_reg);
+                        write_pll = 1;
+                        si5351_set_ms_source(SI5351_CLK2, SI5351_PLLB);
+                    }
+
+                    if(freq >= SI5351_MULTISYNTH_SHARE_MAX * SI5351_FREQ_MULT 
+                            || freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 128) {
+                        Si5351_Config.lock_pllb = SI5351_CLK2;
+
+                        if(Si5351_Config.clk1_freq != 0) {
+                            // Recalc and rewrite the multisynth parameters on CLK1
+                            struct Si5351RegSet ms_temp_reg;
+                            r_div = si5351_select_r_div(&Si5351_Config.clk1_freq);
+                            si5351_multisynth_calc(Si5351_Config.clk1_freq, Si5351_Config.pllb_freq, &ms_temp_reg);
+                            si5351_set_ms(SI5351_CLK1, ms_temp_reg, 0, r_div, 0);
+                        }
+                    } else {
+                        Si5351_Config.lock_pllb = SI5351_CLKNONE;
+                    }
+
+                    target_pll = SI5351_PLLB;
+                    Si5351_Config.clk2_freq = freq;
+                    break;
+            default:
+                    return 1;
+        }
+    }
+
+    // Set multisynth registers (MS must be set before PLL)
+    si5351_set_ms(clk, ms_reg, int_mode, r_div, div_by_4);
+
+    // Set PLL if necessary
+    if (write_pll == 1) {
+        si5351_set_pll(pll_freq, target_pll);
+    }
+
+    return 0;
+}
+
+/*------------------------------------------------------------------------------
+ * @brief si5351_set_pll(uint64_t pll_freq, enum si5351_pll target_pll)
+ *
+ * Set the specified PLL to a specific oscillation frequency
+ *
+ * @param pll_freq - Desired PLL frequency
+ * 
+ * @param target_pll - Which PLL to set
+ *     (use the si5351_pll enum)
+ *------------------------------------------------------------------------------
+ */
+void si5351_set_pll(uint64_t pll_freq, enum si5351_pll target_pll) {
+  struct Si5351RegSet pll_reg;
+
+  si5351_pll_calc(pll_freq, &pll_reg, Si5351_Config.ref_correction);
+
+  // Derive the register values to write
+
+  // Prepare an array for parameters to be written to
+  uint8_t *params;
+  uint8_t buffer[20];
+  uint8_t i = 0;
+  uint8_t temp;
+  params = (uint8_t *)&buffer;
+
+  // Registers 26-27
+  temp = ((pll_reg.p3 >> 8) & 0xFF);
+  params[i++] = temp;
+
+  temp = (uint8_t)(pll_reg.p3  & 0xFF);
+  params[i++] = temp;
+
+  // Register 28
+  temp = (uint8_t)((pll_reg.p1 >> 16) & 0x03);
+  params[i++] = temp;
+
+  // Registers 29-30
+  temp = (uint8_t)((pll_reg.p1 >> 8) & 0xFF);
+  params[i++] = temp;
+
+  temp = (uint8_t)(pll_reg.p1  & 0xFF);
+  params[i++] = temp;
+
+  // Register 31
+  temp = (uint8_t)((pll_reg.p3 >> 12) & 0xF0);
+  temp += (uint8_t)((pll_reg.p2 >> 16) & 0x0F);
+  params[i++] = temp;
+
+  // Registers 32-33
+  temp = (uint8_t)((pll_reg.p2 >> 8) & 0xFF);
+  params[i++] = temp;
+
+  temp = (uint8_t)(pll_reg.p2  & 0xFF);
+  params[i++] = temp;
+
+  // Write the parameters
+  if (target_pll == SI5351_PLLA) {
+    si5351_write_bulk(SI5351_PLLA_PARAMETERS, i, params);
+  } else if (target_pll == SI5351_PLLB) {
+    si5351_write_bulk(SI5351_PLLB_PARAMETERS, i, params);
+  }
+}
+
+
+
+
+/*------------------------------------------------------------------------------
+ * @brief  si5351_pll_reset(enum si5351_pll target_pll)
+ * target_pll - Which PLL to reset
+ *     (use the si5351_pll enum)
+ *
+ * Apply a reset to the indicated PLL.
+ * @param SI5351_PLL_RESET_A or SI5351_PLL_RESET_B
+ * 
+ * @return none
+ *------------------------------------------------------------------------------
+ */
+void si5351_pll_reset(enum si5351_pll target_pll) {
+    if(target_pll == SI5351_PLLA) {
+        si5351_write(SI5351_PLL_RESET, SI5351_PLL_RESET_A);
+    } else if(target_pll == SI5351_PLLB) {
+        si5351_write(SI5351_PLL_RESET, SI5351_PLL_RESET_B);
+    }
+}
+
+/*------------------------------------------------------------------------------
+ * @brief set_int(enum si5351_clock clk, uint8_t int_mode)
+ * Set the indicated multisynth into integer mode.
+ *
+ * @param clk - Clock output
+ *   (use the si5351_clock enum)
+ * 
+ * @param enable - Set to 1 to enable, 0 to disable
+ *
+ *------------------------------------------------------------------------------
+ */
+void si5351_set_int(enum si5351_clock clk, uint8_t enable){
+    uint8_t reg_val;
+    reg_val = si5351_read(SI5351_CLK0_CTRL + (uint8_t)clk);
+
+    if(enable == 1) {
+            reg_val |= (SI5351_CLK_INTEGER_MODE);
+    } else {
+            reg_val &= ~(SI5351_CLK_INTEGER_MODE);
+    }
+
+    si5351_write(SI5351_CLK0_CTRL + (uint8_t)clk, reg_val);
+
+    // Integer mode indication
+    switch(clk) {
+       case SI5351_CLK0:
+               Si5351_Config.clk0_int_mode = enable;
+               break;
+       case SI5351_CLK1:
+               Si5351_Config.clk1_int_mode = enable;
+               break;
+       case SI5351_CLK2:
+               Si5351_Config.clk2_int_mode = enable;
+               break;
+       default:
+               break;
+    }
+}
+
+
+/*------------------------------------------------------------------------------
+ * @brief si5351_set_clock_pwr(enum si5351_clock clk, uint8_t pwr)
+ * Enable or disable power to a clock output (a power
+ * saving feature).
+ *
+ * @param clk - Clock output
+ *   (use the si5351_clock enum)
+ * 
+ * @param pwr - Set to 1 to enable, 0 to disable
+ *
+ *------------------------------------------------------------------------------
+ */
+void si5351_set_clock_pwr(enum si5351_clock clk, uint8_t pwr) {
+    uint8_t reg_val;
+    reg_val = si5351_read(SI5351_CLK0_CTRL + (uint8_t)clk);
+    if(pwr == 1) {
+        reg_val &= 0b01111111;
+    } else {
+        reg_val |= 0b10000000;
+    }
+    si5351_write(SI5351_CLK0_CTRL + (uint8_t)clk, reg_val);
+}
+
+/*------------------------------------------------------------------------------
+ * @brief si5351_set_clock_invert(enum si5351_clock clk, uint8_t inv)
+ * Enable to invert the clock output waveform.
+ *
+ * @param clk - Clock output
+ *   (use the si5351_clock enum)
+ * 
+ * @param inv - Set to 1 to enable, 0 to disable
+ *
+ * -----------------------------------------------------------------------------
+ */
+void si5351_set_clock_invert(enum si5351_clock clk, uint8_t inv) {
+    uint8_t reg_val;
+    reg_val = si5351_read(SI5351_CLK0_CTRL + (uint8_t)clk);
+    if(inv == 1) {
+        reg_val |= (SI5351_CLK_INVERT);
+    } else {
+        reg_val &= ~(SI5351_CLK_INVERT);
+    }
+    si5351_write(SI5351_CLK0_CTRL + (uint8_t)clk, reg_val);
+}
+
+
+/*------------------------------------------------------------------------------
+ * @brief si5351_set_ms(enum si5351_clock clk, struct Si5351RegSet ms_reg,
+ *  uint8_t int_mode, uint8_t r_div, uint8_t div_by_4)
+ *
+ * Set the specified multisynth parameters. Not normally needed, but public for advanced users.
+ *
+ * @param clk - Clock output
+ *   (use the si5351_clock enum)
+ * 
+ * @param int_mode - Set integer mode
+ *  Set to 1 to enable, 0 to disable
+ * 
+ * @param r_div - Desired r_div ratio
+ * 
+ * @param div_by_4 - Set Divide By 4 mode
+ *   Set to 1 to enable, 0 to disable
+ *------------------------------------------------------------------------------
+ */
+void si5351_set_ms(enum si5351_clock clk, struct Si5351RegSet ms_reg, uint8_t int_mode, uint8_t r_div, uint8_t div_by_4) {
+    uint8_t *params;
+    uint8_t buffer[20];
+    uint8_t i = 0;
+    uint8_t temp;
+    uint8_t reg_val;
+
+    params = (uint8_t *)&buffer;
+    // Registers 42-43 for CLK0
+    temp = (uint8_t)((ms_reg.p3 >> 8) & 0xFF);
+    params[i++] = temp;
+
+    temp = (uint8_t)(ms_reg.p3  & 0xFF);
+    params[i++] = temp;
+
+    // Register 44 for CLK0
+    reg_val = si5351_read((SI5351_CLK0_PARAMETERS + 2) + (clk * 8));
+    reg_val &= ~(0x03);
+    temp = reg_val | ((uint8_t)((ms_reg.p1 >> 16) & 0x03));
+    params[i++] = temp;
+
+    // Registers 45-46 for CLK0
+    temp = (uint8_t)((ms_reg.p1 >> 8) & 0xFF);
+    params[i++] = temp;
+
+    temp = (uint8_t)(ms_reg.p1  & 0xFF);
+    params[i++] = temp;
+
+    // Register 47 for CLK0
+    temp = (uint8_t)((ms_reg.p3 >> 12) & 0xF0);
+    temp += (uint8_t)((ms_reg.p2 >> 16) & 0x0F);
+    params[i++] = temp;
+
+    // Registers 48-49 for CLK0
+    temp = (uint8_t)((ms_reg.p2 >> 8) & 0xFF);
+    params[i++] = temp;
+
+    temp = (uint8_t)(ms_reg.p2  & 0xFF);
+    params[i++] = temp;
+
+    // Write the parameters
+    switch (clk) {
+        case SI5351_CLK0:
+                si5351_write_bulk(SI5351_CLK0_PARAMETERS, i, params);
+                break;
+        case SI5351_CLK1:
+                si5351_write_bulk(SI5351_CLK1_PARAMETERS, i, params);
+                break;
+        case SI5351_CLK2:
+                si5351_write_bulk(SI5351_CLK2_PARAMETERS, i, params);
+                break;
+        case SI5351_CLK3:
+                si5351_write_bulk(SI5351_CLK3_PARAMETERS, i, params);
+                break;
+        case SI5351_CLK4:
+                si5351_write_bulk(SI5351_CLK4_PARAMETERS, i, params);
+                break;
+        case SI5351_CLK5:
+                si5351_write_bulk(SI5351_CLK5_PARAMETERS, i, params);
+                break;
+        case SI5351_CLK6:
+                si5351_write_bulk(SI5351_CLK6_PARAMETERS, i, params);
+                break;
+        case SI5351_CLK7:
+                si5351_write_bulk(SI5351_CLK7_PARAMETERS, i, params);
+                break;
+        case SI5351_CLKNONE:
+                return;
+    }
+
+    si5351_set_int(clk, int_mode);
+    si5351_ms_div(clk, r_div, div_by_4);
+}
+
+void si5351_ms_div(enum si5351_clock clk, uint8_t r_div, uint8_t div_by_4) {
+    uint8_t reg_val, reg_addr;
+
+    switch(clk) {
+        case SI5351_CLK0:
+                reg_addr = SI5351_CLK0_PARAMETERS + 2;
+                break;
+        case SI5351_CLK1:
+                reg_addr = SI5351_CLK1_PARAMETERS + 2;
+                break;
+        case SI5351_CLK2:
+                reg_addr = SI5351_CLK2_PARAMETERS + 2;
+                break;
+        case SI5351_CLK3:
+                reg_addr = SI5351_CLK3_PARAMETERS + 2;
+                break;
+        case SI5351_CLK4:
+                reg_addr = SI5351_CLK4_PARAMETERS + 2;
+                break;
+        case SI5351_CLK5:
+                reg_addr = SI5351_CLK5_PARAMETERS + 2;
+                break;
+        case SI5351_CLK6:
+                return;
+        case SI5351_CLK7:
+                return;
+        case SI5351_CLKNONE:
+                return;
+       default:
+               return;
+    }
+
+    reg_val = si5351_read(reg_addr);
+
+    // Clear the relevant bits
+    reg_val &= ~(0x7c);
+
+    if(div_by_4 == 0) {
+            reg_val &= ~(SI5351_OUTPUT_CLK_DIVBY4);
+    } else {
+            reg_val |= (SI5351_OUTPUT_CLK_DIVBY4);
+    }
+
+    reg_val |= (r_div << SI5351_OUTPUT_CLK_DIV_SHIFT);
+
+    si5351_write(reg_addr, reg_val);
+}
+
+/*------------------------------------------------------------------------------
+ * @brief set_ms_source(enum si5351_clock clk, enum si5351_pll pll)
+ * Set the desired PLL source for a multisynth.
+ *
+ * @param clk - Clock output
+ *   (use the si5351_clock enum)
+ * 
+ * @param pll - Which PLL to use as the source
+ *     (use the si5351_pll enum)
+ *
+ *------------------------------------------------------------------------------
+ */
+void si5351_set_ms_source(enum si5351_clock clk, enum si5351_pll pll) {
+    uint8_t reg_val;
+
+    reg_val = si5351_read(SI5351_CLK0_CTRL + (uint8_t)clk);
+
+    if(pll == SI5351_PLLA) {
+            reg_val &= ~(SI5351_CLK_PLL_SELECT);
+    } else if (pll == SI5351_PLLB) {
+            reg_val |= SI5351_CLK_PLL_SELECT;
+    }
+    si5351_write(SI5351_CLK0_CTRL + (uint8_t)clk, reg_val);
+}
+
+uint64_t si5351_multisynth_calc(uint64_t freq, uint64_t pll_freq, struct Si5351RegSet *reg) {
+    uint64_t lltmp;
+    uint32_t a, b, c, p1, p2, p3;
+    uint8_t divby4;
+    uint8_t ret_val = 0;
+
+    // Multisynth bounds checking
+    if (freq > SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT) {
+        freq = SI5351_MULTISYNTH_MAX_FREQ * SI5351_FREQ_MULT;
+    }
+    if (freq < SI5351_MULTISYNTH_MIN_FREQ * SI5351_FREQ_MULT) {
+        freq = SI5351_MULTISYNTH_MIN_FREQ * SI5351_FREQ_MULT;
+    }
+
+    divby4 = 0;
+    if (freq >= SI5351_MULTISYNTH_DIVBY4_FREQ * SI5351_FREQ_MULT) {
+        divby4 = 1;
+    }
+
+    if(pll_freq == 0) {
+        // Find largest integer divider for max
+        // VCO frequency and given target frequency
+        if(divby4 == 0) {
+            lltmp = SI5351_PLL_VCO_MAX * SI5351_FREQ_MULT;
+            do_div(lltmp, freq);
+            a = (uint32_t)lltmp;
+        } else {
+            a = 4;
+        }
+
+        b = 0;
+        c = 1;
+        pll_freq = a * freq;
+    } else {
+        // Preset PLL, so return the actual freq for these params instead of PLL freq
+        ret_val = 1;
+        // Determine integer part of feedback equation
+        a = pll_freq / freq;
+        if (a < SI5351_MULTISYNTH_A_MIN) {
+            freq = pll_freq / SI5351_MULTISYNTH_A_MIN;
+        }
+        if (a > SI5351_MULTISYNTH_A_MAX) {
+            freq = pll_freq / SI5351_MULTISYNTH_A_MAX;
+        }
+        b = (pll_freq % freq * RFRAC_DENOM) / freq;
+        c = b ? RFRAC_DENOM : 1;
+    }
+
+    // Calculate parameters
+    if (divby4 == 1) {
+        p3 = 1;
+        p2 = 0;
+        p1 = 0;
+    } else {
+        p1 = 128 * a + ((128 * b) / c) - 512;
+        p2 = 128 * b - c * ((128 * b) / c);
+        p3 = c;
+    }
+
+    reg->p1 = p1;
+    reg->p2 = p2;
+    reg->p3 = p3;
+
+    if(ret_val == 0) {
+        return pll_freq;
+    } else {
+        return freq;
+    }
+}
+
+uint64_t si5351_pll_calc(uint64_t freq, struct Si5351RegSet *reg, int32_t correction) {
+    uint64_t ref_freq = Si5351_Config.xtal_freq * SI5351_FREQ_MULT;
+    uint32_t a, b, c, p1, p2, p3;
+    uint64_t lltmp, denom;
+
+
+    // Factor calibration value into nominal crystal frequency
+    // Measured in parts-per-billion
+
+    ref_freq = ref_freq + (int32_t)((((((int64_t)correction) << 31) / 1000000000LL) * ref_freq) >> 31);
+
+    // PLL bounds checking
+    if (freq < SI5351_PLL_VCO_MIN * SI5351_FREQ_MULT) {
+        freq = SI5351_PLL_VCO_MIN * SI5351_FREQ_MULT;
+    }
+    if (freq > SI5351_PLL_VCO_MAX * SI5351_FREQ_MULT) {
+        freq = SI5351_PLL_VCO_MAX * SI5351_FREQ_MULT;
+    }
+
+    // Determine integer part of feedback equation
+    a = freq / ref_freq;
+
+    if (a < SI5351_PLL_A_MIN) {
+        freq = ref_freq * SI5351_PLL_A_MIN;
+    }
+    if (a > SI5351_PLL_A_MAX) {
+        freq = ref_freq * SI5351_PLL_A_MAX;
+    }
+
+    // Find best approximation for b/c = fVCO mod fIN
+    denom = 1000ULL * 1000ULL;
+    lltmp = freq % ref_freq;
+    lltmp *= denom;
+    do_div(lltmp, ref_freq);
+
+    b = (((uint64_t)(freq % ref_freq)) * RFRAC_DENOM) / ref_freq;
+    c = b ? RFRAC_DENOM : 1;
+
+       // Calculate parameters
+    p1 = 128 * a + ((128 * b) / c) - 512;
+    p2 = 128 * b - c * ((128 * b) / c);
+    p3 = c;
+
+    // Recalculate frequency as fIN * (a + b/c)
+    lltmp  = ref_freq;
+    lltmp *= b;
+    do_div(lltmp, c);
+    freq = lltmp;
+    freq += ref_freq * a;
+
+    reg->p1 = p1;
+    reg->p2 = p2;
+    reg->p3 = p3;
+
+    return freq;
+}
+
+uint8_t si5351_select_r_div(uint64_t *freq) {
+    uint8_t r_div = SI5351_OUTPUT_CLK_DIV_1;
+
+    // Choose the correct R divider
+    if((*freq >= SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT) 
+            && (*freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 2)) {
+        r_div = SI5351_OUTPUT_CLK_DIV_128;
+        *freq *= 128ULL;
+    } else if ((*freq >= SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 2)
+            && (*freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 4)) {
+        r_div = SI5351_OUTPUT_CLK_DIV_64;
+        *freq *= 64ULL;
+    } else if ((*freq >= SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 4)
+            && (*freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 8)) {
+        r_div = SI5351_OUTPUT_CLK_DIV_32;
+        *freq *= 32ULL;
+    } else if ((*freq >= SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 8)
+            && (*freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 16)) {
+        r_div = SI5351_OUTPUT_CLK_DIV_16;
+        *freq *= 16ULL;
+    } else if ((*freq >= SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 16)
+            && (*freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 32)) {
+        r_div = SI5351_OUTPUT_CLK_DIV_8;
+        *freq *= 8ULL;
+    } else if ((*freq >= SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 32)
+            && (*freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 64)) {
+        r_div = SI5351_OUTPUT_CLK_DIV_4;
+        *freq *= 4ULL;
+    } else if ((*freq >= SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 64)
+            && (*freq < SI5351_CLKOUT_MIN_FREQ * SI5351_FREQ_MULT * 128)) {
+        r_div = SI5351_OUTPUT_CLK_DIV_2;
+        *freq *= 2ULL;
+    }
+
+    return r_div;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/sine.c b/codec2/branches/0.7/stm32/src/sine.c
new file mode 100644 (file)
index 0000000..be4df00
--- /dev/null
@@ -0,0 +1,648 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sine.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 19/8/2010
+
+  Sinusoidal analysis and synthesis functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 1990-2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*---------------------------------------------------------------------------*\
+
+                               INCLUDES
+
+\*---------------------------------------------------------------------------*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "defines.h"
+#include "sine.h"
+#include "kiss_fft.h"
+
+#define HPF_BETA 0.125
+
+/*---------------------------------------------------------------------------*\
+
+                               HEADERS
+
+\*---------------------------------------------------------------------------*/
+
+void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax,
+                        float pstep);
+
+/*---------------------------------------------------------------------------*\
+
+                               FUNCTIONS
+
+\*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: make_analysis_window
+  AUTHOR......: David Rowe
+  DATE CREATED: 11/5/94
+
+  Init function that generates the time domain analysis window and it's DFT.
+
+\*---------------------------------------------------------------------------*/
+
+void make_analysis_window(kiss_fft_cfg fft_fwd_cfg, float w[], COMP W[])
+{
+  float m;
+  COMP  wshift[FFT_ENC];
+  COMP  temp;
+  int   i,j;
+
+  /*
+     Generate Hamming window centered on M-sample pitch analysis window
+
+  0            M/2           M-1
+  |-------------|-------------|
+        |-------|-------|
+            NW samples
+
+     All our analysis/synthsis is centred on the M/2 sample.
+  */
+
+  m = 0.0;
+  for(i=0; i<M/2-NW/2; i++)
+    w[i] = 0.0;
+  for(i=M/2-NW/2,j=0; i<M/2+NW/2; i++,j++) {
+    w[i] = 0.5 - 0.5*cosf(TWO_PI*j/(NW-1));
+    m += w[i]*w[i];
+  }
+  for(i=M/2+NW/2; i<M; i++)
+    w[i] = 0.0;
+
+  /* Normalise - makes freq domain amplitude estimation straight
+     forward */
+
+  m = 1.0/sqrtf(m*FFT_ENC);
+  for(i=0; i<M; i++) {
+    w[i] *= m;
+  }
+
+  /*
+     Generate DFT of analysis window, used for later processing.  Note
+     we modulo FFT_ENC shift the time domain window w[], this makes the
+     imaginary part of the DFT W[] equal to zero as the shifted w[] is
+     even about the n=0 time axis if NW is odd.  Having the imag part
+     of the DFT W[] makes computation easier.
+
+     0                      FFT_ENC-1
+     |-------------------------|
+
+      ----\               /----
+           \             /
+            \           /          <- shifted version of window w[n]
+             \         /
+              \       /
+               -------
+
+     |---------|     |---------|
+       NW/2              NW/2
+  */
+
+  for(i=0; i<FFT_ENC; i++) {
+    wshift[i].real = 0.0;
+    wshift[i].imag = 0.0;
+  }
+  for(i=0; i<NW/2; i++)
+    wshift[i].real = w[i+M/2];
+  for(i=FFT_ENC-NW/2,j=M/2-NW/2; i<FFT_ENC; i++,j++)
+   wshift[i].real = w[j];
+
+  kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)wshift, (kiss_fft_cpx *)W);
+
+  /*
+      Re-arrange W[] to be symmetrical about FFT_ENC/2.  Makes later
+      analysis convenient.
+
+   Before:
+
+
+     0                 FFT_ENC-1
+     |----------|---------|
+     __                   _
+       \                 /
+        \_______________/
+
+   After:
+
+     0                 FFT_ENC-1
+     |----------|---------|
+               ___
+              /   \
+     ________/     \_______
+
+  */
+
+
+  for(i=0; i<FFT_ENC/2; i++) {
+    temp.real = W[i].real;
+    temp.imag = W[i].imag;
+    W[i].real = W[i+FFT_ENC/2].real;
+    W[i].imag = W[i+FFT_ENC/2].imag;
+    W[i+FFT_ENC/2].real = temp.real;
+    W[i+FFT_ENC/2].imag = temp.imag;
+  }
+
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: hpf
+  AUTHOR......: David Rowe
+  DATE CREATED: 16 Nov 2010
+
+  High pass filter with a -3dB point of about 160Hz.
+
+    y(n) = -HPF_BETA*y(n-1) + x(n) - x(n-1)
+
+\*---------------------------------------------------------------------------*/
+
+float hpf(float x, float states[])
+{
+    states[0] += -HPF_BETA*states[0] + x - states[1];
+    states[1] = x;
+
+    return states[0];
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: dft_speech
+  AUTHOR......: David Rowe
+  DATE CREATED: 27/5/94
+
+  Finds the DFT of the current speech input speech frame.
+
+\*---------------------------------------------------------------------------*/
+
+void dft_speech(kiss_fft_cfg fft_fwd_cfg, COMP Sw[], float Sn[], float w[])
+{
+  int  i;
+  COMP sw[FFT_ENC];
+
+  for(i=0; i<FFT_ENC; i++) {
+    sw[i].real = 0.0;
+    sw[i].imag = 0.0;
+  }
+
+  /* Centre analysis window on time axis, we need to arrange input
+     to FFT this way to make FFT phases correct */
+
+  /* move 2nd half to start of FFT input vector */
+
+  for(i=0; i<NW/2; i++)
+    sw[i].real = Sn[i+M/2]*w[i+M/2];
+
+  /* move 1st half to end of FFT input vector */
+
+  for(i=0; i<NW/2; i++)
+    sw[FFT_ENC-NW/2+i].real = Sn[i+M/2-NW/2]*w[i+M/2-NW/2];
+
+  kiss_fft(fft_fwd_cfg, (kiss_fft_cpx *)sw, (kiss_fft_cpx *)Sw);
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: two_stage_pitch_refinement
+  AUTHOR......: David Rowe
+  DATE CREATED: 27/5/94
+
+  Refines the current pitch estimate using the harmonic sum pitch
+  estimation technique.
+
+\*---------------------------------------------------------------------------*/
+
+void two_stage_pitch_refinement(MODEL *model, COMP Sw[])
+{
+  float pmin,pmax,pstep;       /* pitch refinment minimum, maximum and step */
+
+  /* Coarse refinement */
+
+  pmax = TWO_PI/model->Wo + 5;
+  pmin = TWO_PI/model->Wo - 5;
+  pstep = 1.0;
+  hs_pitch_refinement(model,Sw,pmin,pmax,pstep);
+
+  /* Fine refinement */
+
+  pmax = TWO_PI/model->Wo + 1;
+  pmin = TWO_PI/model->Wo - 1;
+  pstep = 0.25;
+  hs_pitch_refinement(model,Sw,pmin,pmax,pstep);
+
+  /* Limit range */
+
+  if (model->Wo < TWO_PI/P_MAX)
+    model->Wo = TWO_PI/P_MAX;
+  if (model->Wo > TWO_PI/P_MIN)
+    model->Wo = TWO_PI/P_MIN;
+
+  model->L = floor(PI/model->Wo);
+}
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: hs_pitch_refinement
+ AUTHOR......: David Rowe
+ DATE CREATED: 27/5/94
+
+ Harmonic sum pitch refinement function.
+
+ pmin   pitch search range minimum
+ pmax  pitch search range maximum
+ step   pitch search step size
+ model current pitch estimate in model.Wo
+
+ model         refined pitch estimate in model.Wo
+
+\*---------------------------------------------------------------------------*/
+
+void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float pstep)
+{
+  int m;               /* loop variable */
+  int b;               /* bin for current harmonic centre */
+  float E;             /* energy for current pitch*/
+  float Wo;            /* current "test" fundamental freq. */
+  float Wom;           /* Wo that maximises E */
+  float Em;            /* mamimum energy */
+  float r, one_on_r;   /* number of rads/bin */
+  float p;             /* current pitch */
+
+  /* Initialisation */
+
+  model->L = PI/model->Wo;     /* use initial pitch est. for L */
+  Wom = model->Wo;
+  Em = 0.0;
+  r = TWO_PI/FFT_ENC;
+  one_on_r = 1.0/r;
+
+  /* Determine harmonic sum for a range of Wo values */
+
+  for(p=pmin; p<=pmax; p+=pstep) {
+    E = 0.0;
+    Wo = TWO_PI/p;
+
+    /* Sum harmonic magnitudes */
+    for(m=1; m<=model->L; m++) {
+        b = (int)(m*Wo*one_on_r + 0.5);
+        E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag;
+    }
+    /* Compare to see if this is a maximum */
+
+    if (E > Em) {
+      Em = E;
+      Wom = Wo;
+    }
+  }
+
+  model->Wo = Wom;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: estimate_amplitudes
+  AUTHOR......: David Rowe
+  DATE CREATED: 27/5/94
+
+  Estimates the complex amplitudes of the harmonics.
+
+\*---------------------------------------------------------------------------*/
+
+void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[], int est_phase)
+{
+  int   i,m;           /* loop variables */
+  int   am,bm;         /* bounds of current harmonic */
+  int   b;             /* DFT bin of centre of current harmonic */
+  float den;           /* denominator of amplitude expression */
+  float r, one_on_r;   /* number of rads/bin */
+  int   offset;
+  COMP  Am;
+
+  r = TWO_PI/FFT_ENC;
+  one_on_r = 1.0/r;
+
+  for(m=1; m<=model->L; m++) {
+    den = 0.0;
+    am = (int)((m - 0.5)*model->Wo*one_on_r + 0.5);
+    bm = (int)((m + 0.5)*model->Wo*one_on_r + 0.5);
+    b = (int)(m*model->Wo/r + 0.5);
+
+    /* Estimate ampltude of harmonic */
+
+    den = 0.0;
+    Am.real = Am.imag = 0.0;
+    offset = FFT_ENC/2 - (int)(m*model->Wo*one_on_r + 0.5);
+    for(i=am; i<bm; i++) {
+      den += Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag;
+      Am.real += Sw[i].real*W[i + offset].real;
+      Am.imag += Sw[i].imag*W[i + offset].real;
+    }
+
+    model->A[m] = sqrtf(den);
+
+    if (est_phase) {
+
+        /* Estimate phase of harmonic, this is expensive in CPU for
+           embedded devicesso we make it an option */
+
+        model->phi[m] = atan2(Sw[b].imag,Sw[b].real);
+    }
+  }
+}
+
+/*---------------------------------------------------------------------------*\
+
+  est_voicing_mbe()
+
+  Returns the error of the MBE cost function for a fiven F0.
+
+  Note: I think a lot of the operations below can be simplified as
+  W[].imag = 0 and has been normalised such that den always equals 1.
+
+\*---------------------------------------------------------------------------*/
+
+float est_voicing_mbe(
+    MODEL *model,
+    COMP   Sw[],
+    COMP   W[],
+    COMP   Sw_[],         /* DFT of all voiced synthesised signal  */
+                          /* useful for debugging/dump file        */
+    COMP   Ew[],          /* DFT of error                          */
+    float prev_Wo)
+{
+    int   i,l,al,bl,m;    /* loop variables */
+    COMP  Am;             /* amplitude sample for this band */
+    int   offset;         /* centers Hw[] about current harmonic */
+    float den;            /* denominator of Am expression */
+    float error;          /* accumulated error between original and synthesised */
+    float Wo;
+    float sig, snr;
+    float elow, ehigh, eratio;
+    float sixty;
+
+    sig = 1E-4;
+    for(l=1; l<=model->L/4; l++) {
+       sig += model->A[l]*model->A[l];
+    }
+    for(i=0; i<FFT_ENC; i++) {
+       Sw_[i].real = 0.0;
+       Sw_[i].imag = 0.0;
+       Ew[i].real = 0.0;
+       Ew[i].imag = 0.0;
+    }
+
+    Wo = model->Wo;
+    error = 1E-4;
+
+    /* Just test across the harmonics in the first 1000 Hz (L/4) */
+
+    for(l=1; l<=model->L/4; l++) {
+       Am.real = 0.0;
+       Am.imag = 0.0;
+       den = 0.0;
+       al = ceil((l - 0.5)*Wo*FFT_ENC/TWO_PI);
+       bl = ceil((l + 0.5)*Wo*FFT_ENC/TWO_PI);
+
+       /* Estimate amplitude of harmonic assuming harmonic is totally voiced */
+
+        offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5;
+       for(m=al; m<bl; m++) {
+           Am.real += Sw[m].real*W[offset+m].real;
+           Am.imag += Sw[m].imag*W[offset+m].real;
+           den += W[offset+m].real*W[offset+m].real;
+        }
+
+        Am.real = Am.real/den;
+        Am.imag = Am.imag/den;
+
+        /* Determine error between estimated harmonic and original */
+
+        offset = FFT_ENC/2 - l*Wo*FFT_ENC/TWO_PI + 0.5;
+        for(m=al; m<bl; m++) {
+           Sw_[m].real = Am.real*W[offset+m].real;
+           Sw_[m].imag = Am.imag*W[offset+m].real;
+           Ew[m].real = Sw[m].real - Sw_[m].real;
+           Ew[m].imag = Sw[m].imag - Sw_[m].imag;
+           error += Ew[m].real*Ew[m].real;
+           error += Ew[m].imag*Ew[m].imag;
+       }
+    }
+
+    snr = 10.0*log10f(sig/error);
+    if (snr > V_THRESH)
+       model->voiced = 1;
+    else
+       model->voiced = 0;
+
+    /* post processing, helps clean up some voicing errors ------------------*/
+
+    /*
+       Determine the ratio of low freqency to high frequency energy,
+       voiced speech tends to be dominated by low frequency energy,
+       unvoiced by high frequency. This measure can be used to
+       determine if we have made any gross errors.
+    */
+
+    elow = ehigh = 1E-4;
+    for(l=1; l<=model->L/2; l++) {
+       elow += model->A[l]*model->A[l];
+    }
+    for(l=model->L/2; l<=model->L; l++) {
+       ehigh += model->A[l]*model->A[l];
+    }
+    eratio = 10.0*log10f(elow/ehigh);
+
+    /* Look for Type 1 errors, strongly V speech that has been
+       accidentally declared UV */
+
+    if (model->voiced == 0)
+       if (eratio > 10.0)
+           model->voiced = 1;
+
+    /* Look for Type 2 errors, strongly UV speech that has been
+       accidentally declared V */
+
+    if (model->voiced == 1) {
+       if (eratio < -10.0)
+           model->voiced = 0;
+
+       /* A common source of Type 2 errors is the pitch estimator
+          gives a low (50Hz) estimate for UV speech, which gives a
+          good match with noise due to the close harmoonic spacing.
+          These errors are much more common than people with 50Hz3
+          pitch, so we have just a small eratio threshold. */
+
+       sixty = 60.0*TWO_PI/FS;
+       if ((eratio < -4.0) && (model->Wo <= sixty))
+           model->voiced = 0;
+    }
+    //printf(" v: %d snr: %f eratio: %3.2f %f\n",model->voiced,snr,eratio,dF0);
+
+    return snr;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: make_synthesis_window
+  AUTHOR......: David Rowe
+  DATE CREATED: 11/5/94
+
+  Init function that generates the trapezoidal (Parzen) sythesis window.
+
+\*---------------------------------------------------------------------------*/
+
+void make_synthesis_window(float Pn[])
+{
+  int   i;
+  float win;
+
+  /* Generate Parzen window in time domain */
+
+  win = 0.0;
+  for(i=0; i<N/2-TW; i++)
+    Pn[i] = 0.0;
+  win = 0.0;
+  for(i=N/2-TW; i<N/2+TW; win+=1.0/(2*TW), i++ )
+    Pn[i] = win;
+  for(i=N/2+TW; i<3*N/2-TW; i++)
+    Pn[i] = 1.0;
+  win = 1.0;
+  for(i=3*N/2-TW; i<3*N/2+TW; win-=1.0/(2*TW), i++)
+    Pn[i] = win;
+  for(i=3*N/2+TW; i<2*N; i++)
+    Pn[i] = 0.0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: synthesise
+  AUTHOR......: David Rowe
+  DATE CREATED: 20/2/95
+
+  Synthesise a speech signal in the frequency domain from the
+  sinusodal model parameters.  Uses overlap-add with a trapezoidal
+  window to smoothly interpolate betwen frames.
+
+\*---------------------------------------------------------------------------*/
+
+void synthesise(
+  kiss_fft_cfg fft_inv_cfg,
+  float  Sn_[],                /* time domain synthesised signal              */
+  MODEL *model,                /* ptr to model parameters for this frame      */
+  float  Pn[],         /* time domain Parzen window                   */
+  int    shift          /* flag used to handle transition frames       */
+)
+{
+    int   i,l,j,b;     /* loop variables */
+    COMP  Sw_[FFT_DEC];        /* DFT of synthesised signal */
+    COMP  sw_[FFT_DEC];        /* synthesised signal */
+
+    if (shift) {
+       /* Update memories */
+       for(i=0; i<N-1; i++) {
+           Sn_[i] = Sn_[i+N];
+       }
+       Sn_[N-1] = 0.0;
+    }
+
+    for(i=0; i<FFT_DEC; i++) {
+       Sw_[i].real = 0.0;
+       Sw_[i].imag = 0.0;
+    }
+
+    /*
+      Nov 2010 - found that synthesis using time domain cos() functions
+      gives better results for synthesis frames greater than 10ms.  Inverse
+      FFT synthesis using a 512 pt FFT works well for 10ms window.  I think
+      (but am not sure) that the problem is related to the quantisation of
+      the harmonic frequencies to the FFT bin size, e.g. there is a
+      8000/512 Hz step between FFT bins.  For some reason this makes
+      the speech from longer frame > 10ms sound poor.  The effect can also
+      be seen when synthesising test signals like single sine waves, some
+      sort of amplitude modulation at the frame rate.
+
+      Another possibility is using a larger FFT size (1024 or 2048).
+    */
+
+#define FFT_SYNTHESIS
+#ifdef FFT_SYNTHESIS
+    /* Now set up frequency domain synthesised speech */
+    for(l=1; l<=model->L; l++) {
+    //for(l=model->L/2; l<=model->L; l++) {
+    //for(l=1; l<=model->L/4; l++) {
+       b = (int)(l*model->Wo*FFT_DEC/TWO_PI + 0.5);
+       if (b > ((FFT_DEC/2)-1)) {
+               b = (FFT_DEC/2)-1;
+       }
+       Sw_[b].real = model->A[l]*cosf(model->phi[l]);
+       Sw_[b].imag = model->A[l]*sinf(model->phi[l]);
+       Sw_[FFT_DEC-b].real = Sw_[b].real;
+       Sw_[FFT_DEC-b].imag = -Sw_[b].imag;
+    }
+
+    /* Perform inverse DFT */
+
+    kiss_fft(fft_inv_cfg, (kiss_fft_cpx *)Sw_, (kiss_fft_cpx *)sw_);
+#else
+    /*
+       Direct time domain synthesis using the cos() function.  Works
+       well at 10ms and 20ms frames rates.  Note synthesis window is
+       still used to handle overlap-add between adjacent frames.  This
+       could be simplified as we don't need to synthesise where Pn[]
+       is zero.
+    */
+    for(l=1; l<=model->L; l++) {
+       for(i=0,j=-N+1; i<N-1; i++,j++) {
+           Sw_[FFT_DEC-N+1+i].real += 2.0*model->A[l]*cos(j*model->Wo*l + model->phi[l]);
+       }
+       for(i=N-1,j=0; i<2*N; i++,j++)
+           Sw_[j].real += 2.0*model->A[l]*cos(j*model->Wo*l + model->phi[l]);
+    }
+#endif
+
+    /* Overlap add to previous samples */
+
+    for(i=0; i<N-1; i++) {
+       Sn_[i] += sw_[FFT_DEC-N+1+i].real*Pn[i];
+    }
+
+    if (shift)
+       for(i=N-1,j=0; i<2*N; i++,j++)
+           Sn_[i] = sw_[j].real*Pn[i];
+    else
+       for(i=N-1,j=0; i<2*N; i++,j++)
+           Sn_[i] += sw_[j].real*Pn[i];
+}
+
+
+static unsigned long next = 1;
+
+int codec2_rand(void) {
+    next = next * 1103515245 + 12345;
+    return((unsigned)(next/65536) % 32768);
+}
+
diff --git a/codec2/branches/0.7/stm32/src/sm1000_leds_switches.c b/codec2/branches/0.7/stm32/src/sm1000_leds_switches.c
new file mode 100644 (file)
index 0000000..e8f6ffc
--- /dev/null
@@ -0,0 +1,229 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sm1000_leds_switches.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 18 July 2014
+
+  Functions for controlling LEDs and reading switches on the SM1000.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define _CPTT          GPIO_Pin_10
+#define LED_PWR        GPIO_Pin_12
+#define LED_PTT        GPIO_Pin_13
+#define LED_RT         GPIO_Pin_14
+#define LED_ERR        GPIO_Pin_15
+#define SWITCH_PTT     GPIO_Pin_7
+#define SWITCH_SELECT  GPIO_Pin_0
+#define SWITCH_BACK    GPIO_Pin_1
+#define EXT_PTT        GPIO_Pin_8
+
+#include <stm32f4xx.h>
+#include <stm32f4xx_gpio.h>
+#include "sm1000_leds_switches.h"
+
+void sm1000_leds_switches_init(void) {
+    GPIO_InitTypeDef GPIO_InitStruct;
+
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
+
+    /* output pins */
+
+    GPIO_InitStruct.GPIO_Pin = LED_PWR | LED_PTT | LED_RT | LED_ERR | _CPTT;
+    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
+    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
+    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
+    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
+    GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+    /* input pins */
+
+    GPIO_InitStruct.GPIO_Pin = SWITCH_PTT | SWITCH_SELECT | SWITCH_BACK;
+    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
+    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; /* we have our own external pull ups */
+    GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+    GPIO_InitStruct.GPIO_Pin = EXT_PTT;
+    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
+    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
+    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;     /* use internal pull up */
+    GPIO_Init(GPIOD, &GPIO_InitStruct);
+
+
+}
+
+void led_pwr(int state) {
+    if (state > 0)
+        GPIOD->ODR |= (1 << 12);
+    else if (state < 0)
+        GPIOD->ODR ^= (1 << 12);
+    else
+        GPIOD->ODR &= ~(1 << 12);
+}
+
+void led_ptt(int state) {
+    if (state > 0)
+        GPIOD->ODR |= (1 << 13);
+    else if (state < 0)
+        GPIOD->ODR |= (1 << 13);
+    else
+        GPIOD->ODR &= ~(1 << 13);
+}
+
+void led_rt(int state) {
+    if (state > 0)
+        GPIOD->ODR |= (1 << 14);
+    else if (state < 0)
+        GPIOD->ODR ^= (1 << 14);
+    else
+        GPIOD->ODR &= ~(1 << 14);
+}
+
+void led_err(int state) {
+    if (state > 0)
+        GPIOD->ODR |= (1 << 15);
+    else if (state < 0)
+        GPIOD->ODR ^= (1 << 15);
+    else
+        GPIOD->ODR &= ~(1 << 15);
+}
+
+void not_cptt(int state) {
+    if (state)
+        GPIOD->ODR |= (1 << 10);
+    else
+        GPIOD->ODR &= ~(1 << 10);
+}
+
+int switch_ptt(void) {
+    return GPIOD->IDR & (1 << 7);
+}
+
+int switch_select(void) {
+    return GPIOD->IDR & (1 << 0);
+}
+
+int switch_back(void) {
+    return GPIOD->IDR & (1 << 1);
+}
+
+int ext_ptt(void) {
+    return GPIOD->IDR & (1 << 8);
+}
+
+/*
+  FUNCTION: ColorfulRingOfDeath()
+  AUTHOR..: xenovacivus
+
+  Colourful ring of death, blink LEDs like crazy forever if something
+  really nasty happens.  Adapted from USB Virtual COM Port (VCP)
+  module adapted from code I found here:
+
+    https://github.com/xenovacivus/STM32DiscoveryVCP
+
+  Call this to indicate a failure.  Blinks the STM32F4 discovery LEDs
+  in sequence.  At 168Mhz, the blinking will be very fast - about 5
+  Hz.  Keep that in mind when debugging, knowing the clock speed
+  might help with debugging.
+*/
+
+int mycode; /* examine this with debugger if it dies */
+
+void ColorfulRingOfDeath(int code) {
+    mycode = code;
+    uint16_t ring = 1;
+    while (1) {
+        uint32_t count = 0;
+        while (count++ < 5000000);
+
+        GPIOD->BSRRH = (ring << 12);
+        ring = ring << 1;
+        if (ring >= 1<<4) {
+            ring = 1;
+        }
+        GPIOD->BSRRL = (ring << 12);
+    }
+}
+void HardFault_Handler(void) { ColorfulRingOfDeath(1); }
+void MemManage_Handler(void) { ColorfulRingOfDeath(2); }
+void BusFault_Handler(void)  { ColorfulRingOfDeath(3); }
+void UsageFault_Handler(void){ ColorfulRingOfDeath(4); }
+
+
+void switch_tick(struct switch_t* const sw)
+{
+    if (sw->sw != sw->raw) {
+        /* State transition, reset timer */
+        if (sw->state == SW_STEADY)
+            sw->last = sw->sw;
+        sw->state = SW_DEBOUNCE;
+        sw->timer = DEBOUNCE_DELAY;
+        sw->sw = sw->raw;
+    } else if (sw->state == SW_DEBOUNCE) {
+        if (sw->timer > 0) {
+            /* Steady so far, keep waiting */
+            sw->timer--;
+        } else {
+            /* Steady state reached */
+            sw->state = SW_STEADY;
+        }
+    } else if (sw->sw) {
+        /* Hold state.  Yes this will wrap, but who cares? */
+        sw->timer++;
+    }
+}
+
+void switch_update(struct switch_t* const sw, uint8_t state)
+{
+    sw->raw = state;
+    if (sw->raw == sw->sw)
+        return;
+
+    if (sw->state == SW_STEADY)
+        sw->last = sw->sw;
+    sw->timer = DEBOUNCE_DELAY;
+    sw->sw = sw->raw;
+    sw->state = SW_DEBOUNCE;
+}
+
+uint32_t switch_pressed(const struct switch_t* const sw)
+{
+    if ((sw->state == SW_STEADY) && sw->sw)
+        return sw->timer;
+    return 0;
+}
+
+int switch_released(const struct switch_t* const sw)
+{
+    if (sw->state != SW_STEADY)
+        return 0;
+    if (!sw->last)
+        return 0;
+    if (sw->sw)
+        return 0;
+    return 1;
+}
+
+void switch_ack(struct switch_t* const sw)
+{
+    if (sw->state == SW_STEADY)
+        sw->last = sw->sw;
+}
diff --git a/codec2/branches/0.7/stm32/src/sm1000_leds_switches_ut.c b/codec2/branches/0.7/stm32/src/sm1000_leds_switches_ut.c
new file mode 100644 (file)
index 0000000..9209bfc
--- /dev/null
@@ -0,0 +1,41 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sm1000_leds_switches_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: August 5 2014
+
+  Unit Test program for the SM1000 switches and LEDs driver.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include "sm1000_leds_switches.h"
+
+int main(void) {
+    sm1000_leds_switches_init();
+
+    while(1) {
+        led_pwr(switch_select());
+        led_ptt(switch_ptt());
+        led_rt(switch_back());
+        led_err(!switch_back());
+    }
+}
+
diff --git a/codec2/branches/0.7/stm32/src/sm1000_main.c b/codec2/branches/0.7/stm32/src/sm1000_main.c
new file mode 100644 (file)
index 0000000..565b3c6
--- /dev/null
@@ -0,0 +1,1249 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sm1000_main.c
+  AUTHOR......: David Rowe
+  DATE CREATED: August 5 2014
+
+  Main program for SM1000.
+
+  TODO
+
+  [ ] make led blink 1-2-3 times for "mode"
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "stm32f4_adc.h"
+#include "stm32f4_dac.h"
+#include "stm32f4_vrom.h"
+#include "freedv_api.h"
+#include "codec2_fdmdv.h"
+#include "sm1000_leds_switches.h"
+#include <stm32f4xx_gpio.h>
+#include <stm32f4xx_rcc.h>
+#include <stdlib.h>
+
+#include "sfx.h"
+#include "sounds.h"
+#include "morse.h"
+#include "menu.h"
+#include "tot.h"
+
+#define FREEDV_NSAMPLES_16K (2*FREEDV_NSAMPLES)
+
+#define MENU_LED_PERIOD  100
+#define ANNOUNCE_DELAY  1500
+#define HOLD_DELAY      1000
+#define MENU_DELAY      1000
+
+#define STATE_RX        0x00    /*!< Receive state: normal operation */
+#define STATE_TX        0x10    /*!< Transmit state: normal operation */
+#define STATE_RX_TOT    0x01    /*!< Receive state: after time-out */
+#define STATE_MENU      0x20    /*!< Menu state: normal operation */
+
+/*!
+ * State machine states.  We consider our state depending on what events
+ * are in effect at the start of the main() loop.  For buttons, we have
+ * the following events:
+ *
+ *     PRESS:   Short-succession down-and-up event. (<1 second)
+ *     DOWN:    Button press event with no release.
+ *     UP:      Button release event.
+ *     HOLD:    Button press for a minimum duration of 1 second without
+ *              release.
+ *
+ * We also have some other state machines:
+ *     TOT:
+ *         IDLE:        No time-out event
+ *         WARN:        Warning period reached event
+ *         WARN_TICK:   Next warning tick due event
+ *         TIMEOUT:     Cease transmit event
+ *
+ * We consider ourselves to be in one of a few finite states:
+ *
+ *     STATE_RX:    Normal receive state.
+ *             Conditions:    !PTT.DOWN, !SELECT.HOLD
+ *
+ *             We receive samples via the TRX ADC and pass those
+ *             to SPEAKER DAC after demodulation/filtering.
+ *
+ *             On SELECT.HOLD:      go to STATE_MENU
+ *             On SELECT.PRESS:     next mode, stay in STATE_RX
+ *             On BACK.PRESS:       prev mode, stay in STATE_RX
+ *             On PTT.DOWN:         reset TOT, go to STATE_TX
+ *
+ *     STATE_TX:    Normal transmit state.
+ *             Conditions:    PTT.DOWN, !TOT.TIMEOUT
+ *
+ *             We receive samples via the MIC ADC and pass those
+ *             to TRX DAC after modulation/filtering.
+ *
+ *             On PTT.UP:           reset TOT, go to STATE_RX
+ *             On TOT.WARN_TICK:    play tick noise,
+ *                                  reset WARN_TICK event,
+ *                                  stay in STATE_TX
+ *             On TOT.TIMEOUT:      play timeout tune,
+ *                                  reset TIMEOUT event
+ *                                  go to STATE_RX_TOT.
+ *
+ *     STATE_RX_TOT:    Receive after time-out state.
+ *             Conditions:    PTT.DOWN
+ *
+ *             We receive samples via the TRX ADC and pass those
+ *             to SPEAKER DAC after demodulation/filtering.
+ *
+ *             On PTT.UP:           reset TOT, go to STATE_RX
+ *
+ *    STATE_MENU:   Menu operation state.  Operation is dictated by
+ *                  the menu state machine, when we exit that state
+ *                  machine, we return to STATE_RX.
+ */
+uint8_t core_state = STATE_RX;
+
+#define MAX_MODES  3
+#define ANALOG     0
+#define DV         1
+#define TONE       2
+
+struct switch_t sw_select;  /*!< Switch driver for SELECT button */
+struct switch_t sw_back;    /*!< Switch driver for BACK button */
+struct switch_t sw_ptt;     /*!< Switch driver for PTT buttons */
+
+struct tot_t tot;           /*!< Time-out timer */
+
+unsigned int announceTicker = 0;
+unsigned int menuLEDTicker = 0;
+unsigned int menuTicker = 0;
+unsigned int menuExit = 0;
+
+/*!
+ * User preferences
+ */
+static struct prefs_t {
+    /*! Serial number */
+    uint64_t serial;
+    /*! Time-out timer period, in seconds increment */
+    uint16_t tot_period;
+    /*! Time-out timer warning period, in seconds increment */
+    uint16_t tot_warn_period;
+    /*! Menu frequency */
+    uint16_t menu_freq;
+    /*! Menu speed */
+    uint8_t menu_speed;
+    /*! Menu volume (attenuation) */
+    uint8_t menu_vol;
+    /*! Default operating mode */
+    uint8_t op_mode;
+} prefs;
+
+/*! Preferences changed flag */
+int prefs_changed = 0;
+
+/*! Number of preference images kept */
+#define PREFS_IMG_NUM       (2)
+/*! Base ROM ID for preferences */
+#define PREFS_IMG_BASE      (0)
+/*! Minimum serial number */
+#define PREFS_SERIAL_MIN    8
+/*! Maximum serial number */
+#define PREFS_SERIAL_MAX    UINT64_MAX
+
+/*! Preference serial numbers, by slot */
+static uint64_t prefs_serial[PREFS_IMG_NUM];
+
+struct tone_gen_t tone_gen;
+struct sfx_player_t sfx_player;
+struct morse_player_t morse_player;
+
+void SysTick_Handler(void);
+
+/*! Menu item root */
+static const struct menu_item_t menu_root;
+
+#define MENU_EVT_NEXT   0x10    /*!< Increment the current item */
+#define MENU_EVT_PREV   0x11    /*!< Decrement the current item */
+#define MENU_EVT_SELECT 0x20    /*!< Select current item */
+#define MENU_EVT_BACK   0x21    /*!< Go back one level */
+#define MENU_EVT_EXIT   0x30    /*!< Exit menu */
+
+/*!
+ * Software-mix two 16-bit samples.
+ */
+int16_t software_mix(int16_t a, int16_t b) {
+    int32_t s = a + b;
+    if (s < INT16_MIN)
+        return INT16_MIN;   /* Clip! */
+    if (s > INT16_MAX)
+        return INT16_MAX;   /* Clip! */
+    return s;
+}
+
+/*! Compare current serial with oldest and newest */
+void compare_prefs(int* const oldest, int* const newest, int idx)
+{
+    if (newest && prefs_serial[idx]) {
+        if ((*newest < 0)
+                || (prefs_serial[idx] > prefs_serial[*newest])
+                || ((prefs_serial[idx] == PREFS_SERIAL_MIN)
+                    && (prefs_serial[*newest] == PREFS_SERIAL_MAX)))
+            *newest = idx;
+    }
+
+    if (oldest) {
+        if ((*oldest < 0)
+                || (!prefs_serial[idx])
+                || (prefs_serial[idx] < prefs_serial[*oldest])
+                || ((prefs_serial[idx] == PREFS_SERIAL_MAX)
+                    && (prefs_serial[*oldest] == PREFS_SERIAL_MIN)))
+            *oldest = idx;
+    }
+}
+
+/*! Find oldest and newest images */
+void find_prefs(int* const oldest, int* const newest)
+{
+    int i;
+    if (newest) *newest = -1;
+    if (oldest) *oldest = -1;
+    for (i = 0; i < PREFS_IMG_NUM; i++)
+        compare_prefs(oldest, newest, i);
+}
+
+/*! Load preferences from flash */
+int load_prefs()
+{
+    struct prefs_t image[PREFS_IMG_NUM];
+    int newest = -1;
+    int i;
+
+    /* Load all copies into RAM */
+    for (i = 0; i < PREFS_IMG_NUM; i++) {
+        int res = vrom_read(PREFS_IMG_BASE + i, 0,
+                sizeof(image[i]), &image[i]);
+        if (res == sizeof(image[i])) {
+            prefs_serial[i] = image[i].serial;
+            compare_prefs(NULL, &newest, i);
+        } else {
+            prefs_serial[i] = 0;
+        }
+    }
+
+    if (newest < 0)
+        /* No newest image was found */
+        return -ENOENT;
+
+    /* Load from the latest image */
+    memcpy(&prefs, &image[newest], sizeof(prefs));
+    return 0;
+}
+
+int main(void) {
+    struct freedv *f;
+    int            nin, nout, i;
+    int            n_samples, n_samples_16k;
+
+    /* Menu data */
+    struct menu_t   menu;
+
+    /* Outgoing sample counter */
+    int spk_nsamples = 0;
+
+    /* Current runtime operation mode */
+    int op_mode = ANALOG;
+
+    /* init all the drivers for various peripherals */
+
+    SysTick_Config(SystemCoreClock/1000); /* 1 kHz SysTick */
+    sm1000_leds_switches_init();
+
+    /* Enable CRC clock */
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);
+
+    /* Set up ADCs/DACs */
+    dac_open(DAC_FS_16KHZ, 4*DAC_BUF_SZ);
+    adc_open(ADC_FS_16KHZ, 4*ADC_BUF_SZ);
+
+    /* Set up FreeDV modem */
+    f = freedv_open(FREEDV_MODE_1600);
+    n_samples = freedv_get_n_speech_samples(f);
+    n_samples_16k = 2*n_samples;
+
+    short          adc16k[FDMDV_OS_TAPS_16K+n_samples_16k];
+    short          dac16k[n_samples_16k];
+    short          adc8k[n_samples];
+    short          dac8k[FDMDV_OS_TAPS_8K+n_samples];
+
+    /* put outputs into a known state */
+
+    led_pwr(1); led_ptt(0); led_rt(0); led_err(0); not_cptt(1);
+
+    /* clear filter memories */
+
+    for(i=0; i<FDMDV_OS_TAPS_16K; i++)
+        adc16k[i] = 0.0;
+    for(i=0; i<FDMDV_OS_TAPS_8K; i++)
+        dac8k[i] = 0.0;
+
+    if (!switch_back()) {
+        /* Play tone to acknowledge, wait for release */
+        tone_reset(&tone_gen, 1200, 1000);
+        while(!switch_back()) {
+            int dac_rem = dac2_free();
+            if (dac_rem) {
+                if (dac_rem > n_samples_16k)
+                    dac_rem = n_samples_16k;
+
+                for (i = 0; i < dac_rem; i++)
+                    dac16k[i] = tone_next(&tone_gen);
+                dac2_write(dac16k, dac_rem);
+            }
+            if (!menuLEDTicker) {
+                menuLEDTicker = MENU_LED_PERIOD;
+                led_rt(LED_INV);
+            }
+        }
+
+        /* Button released, do an EEPROM erase */
+        for (i = 0; i < PREFS_IMG_NUM; i++)
+            vrom_erase(i + PREFS_IMG_BASE);
+    }
+    led_rt(LED_OFF);
+    tone_reset(&tone_gen, 0, 0);
+    tot_reset(&tot);
+
+    /* Try to load preferences from flash */
+    if (load_prefs() < 0) {
+        /* Fail!  Load defaults. */
+        memset(&prefs, 0, sizeof(prefs));
+        prefs.op_mode = ANALOG;
+        prefs.menu_vol = 2;
+        prefs.menu_speed = 60;  /* 20 WPM */
+        prefs.menu_freq = 800;
+        prefs.tot_period = 0; /* Disable time-out timer */
+        prefs.tot_warn_period = 15;
+    }
+
+    /* Set up time-out timer, 100msec ticks */
+    tot.tick_period        = 100;
+    tot.remain_warn_ticks  = 10;
+
+    /* Clear out switch states */
+    memset(&sw_select, 0, sizeof(sw_select));
+    memset(&sw_back, 0, sizeof(sw_back));
+    memset(&sw_ptt, 0, sizeof(sw_ptt));
+
+    /* Clear out menu state */
+    memset(&menu, 0, sizeof(menu));
+
+    morse_player.freq = prefs.menu_freq;
+    morse_player.dit_time = prefs.menu_speed;
+    morse_player.msg = NULL;
+    op_mode = prefs.op_mode;
+
+    /* play a start-up tune. */
+    sfx_play(&sfx_player, sound_startup);
+
+    while(1) {
+        /* Read switch states */
+        switch_update(&sw_select,   (!switch_select()) ? 1 : 0);
+        switch_update(&sw_back,     (!switch_back()) ? 1 : 0);
+        switch_update(&sw_ptt,      (switch_ptt() ||
+                                        (!ext_ptt())) ? 1 : 0);
+
+        /* Update time-out timer state */
+        tot_update(&tot);
+
+        /* State machine updates */
+        switch(core_state) {
+            case STATE_RX:
+                {
+                    uint8_t mode_changed = 0;
+
+                    if (!menuTicker) {
+                        if (menuExit) {
+                            /* We've just exited a menu, wait for release of BACK */
+                            if (switch_released(&sw_back))
+                                menuExit = 0;
+                        } else if (switch_pressed(&sw_ptt)) {
+                            /* Cancel any announcement if scheduled */
+                            if (announceTicker && morse_player.msg) {
+                                announceTicker = 0;
+                                morse_play(&morse_player, NULL);
+                            }
+                            /* Start time-out timer if enabled */
+                            if (prefs.tot_period)
+                                tot_start(&tot, prefs.tot_period*10,
+                                        prefs.tot_warn_period*10);
+                            /* Enter transmit state */
+                            core_state = STATE_TX;
+                        } else if (switch_pressed(&sw_select) > HOLD_DELAY) {
+                            /* Enter the menu */
+                            led_pwr(1); led_ptt(0); led_rt(0);
+                            led_err(0); not_cptt(1);
+
+                            menu_enter(&menu, &menu_root);
+                            menuTicker = MENU_DELAY;
+                            core_state = STATE_MENU;
+                            prefs_changed = 0;
+                        } else if (switch_released(&sw_select)) {
+                            /* Shortcut: change current mode */
+                            op_mode = (op_mode + 1) % MAX_MODES;
+                            mode_changed = 1;
+                        } else if (switch_released(&sw_back)) {
+                            /* Shortcut: change current mode */
+                            op_mode = (op_mode - 1) % MAX_MODES;
+                            mode_changed = 1;
+                        }
+
+                        if (mode_changed) {
+                            /* Announce the new mode */
+                            if (op_mode == ANALOG)
+                                morse_play(&morse_player, "ANA");
+                            else if (op_mode == DV)
+                                morse_play(&morse_player, "1600");
+                            else if (op_mode == TONE)
+                                morse_play(&morse_player, "TONE");
+                            sfx_play(&sfx_player, sound_click);
+                        }
+                    }
+                }
+                break;
+            case STATE_TX:
+                {
+                    if (!switch_pressed(&sw_ptt)) {
+                        /* PTT released, leave transmit mode */
+                        tot_reset(&tot);
+                        core_state = STATE_RX;
+                    } else if (tot.event & TOT_EVT_TIMEOUT) {
+                        /* Time-out reached */
+                        sfx_play(&sfx_player, sound_death_march);
+                        tot.event &= ~TOT_EVT_TIMEOUT;
+                        core_state = STATE_RX_TOT;
+                    } else if (tot.event & TOT_EVT_WARN_NEXT) {
+                        /* Re-set warning flag */
+                        tot.event &= ~TOT_EVT_WARN_NEXT;
+                        /* Schedule a click tone */
+                        sfx_play(&sfx_player, sound_click);
+                    }
+                }
+                break;
+            case STATE_RX_TOT:
+                if (switch_released(&sw_ptt)) {
+                    /* PTT released, leave transmit mode */
+                    tot_reset(&tot);
+                    core_state = STATE_RX;
+                }
+                break;
+            case STATE_MENU:
+                if (!menuTicker) {
+                    /* We are in a menu */
+                    static uint8_t press_ack = 0;
+                    uint8_t save_settings = 0;
+
+                    if (press_ack == 1) {
+                        if ((sw_select.state == SW_STEADY)
+                                && (!sw_select.sw))
+                            press_ack = 0;
+                    } else if (press_ack == 2) {
+                        if ((sw_back.state == SW_STEADY)
+                                && (!sw_back.sw))
+                            press_ack = 0;
+                    } else {
+                        if (switch_pressed(&sw_select) > HOLD_DELAY) {
+                            menu_exec(&menu, MENU_EVT_SELECT);
+                            press_ack = 1;
+                            menuTicker = MENU_DELAY;
+                        } else if (switch_pressed(&sw_back) > HOLD_DELAY) {
+                            menu_exec(&menu, MENU_EVT_BACK);
+                            press_ack = 2;
+                            menuTicker = MENU_DELAY;
+
+                            if (!menu.stack_depth)
+                                save_settings = prefs_changed;
+
+                        } else if (switch_released(&sw_select)) {
+                            menu_exec(&menu, MENU_EVT_NEXT);
+                            menuTicker = MENU_DELAY;
+                        } else if (switch_released(&sw_back)) {
+                            menu_exec(&menu, MENU_EVT_PREV);
+                            menuTicker = MENU_DELAY;
+                        } else if (switch_released(&sw_ptt)) {
+                            while(menu.stack_depth > 0)
+                                menu_exec(&menu, MENU_EVT_EXIT);
+                            sfx_play(&sfx_player, sound_returned);
+                        }
+
+                        /* If exited, put the LED back */
+                        if (!menu.stack_depth) {
+                            menuLEDTicker = 0;
+                            menuTicker = 0;
+                            led_pwr(LED_ON);
+                            morse_play(&morse_player, NULL);
+                            menuExit = 1;
+                            if (save_settings) {
+                                int oldest = -1;
+                                int res;
+                                /* Copy the settings in */
+                                prefs.menu_freq = morse_player.freq;
+                                prefs.menu_speed = morse_player.dit_time;
+                                /* Increment serial number */
+                                prefs.serial++;
+                                /* Find the oldest image */
+                                find_prefs(&oldest, NULL);
+                                if (oldest < 0)
+                                    oldest = 0; /* No current image */
+
+                                /* Write new settings over it */
+                                res = vrom_write(oldest + PREFS_IMG_BASE, 0,
+                                        sizeof(prefs), &prefs);
+                                if (res >= 0)
+                                    prefs_serial[oldest] = prefs.serial;
+                            }
+                            /* Go back to receive state */
+                            core_state = STATE_RX;
+                        }
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+
+        /* Acknowledge switch events */
+        switch_ack(&sw_select);
+        switch_ack(&sw_back);
+        switch_ack(&sw_ptt);
+
+        switch (core_state) {
+            case STATE_MENU:
+                if (!menuLEDTicker) {
+                    led_pwr(LED_INV);
+                    menuLEDTicker = MENU_LED_PERIOD;
+                }
+                break;
+            case STATE_TX:
+            /* Transmit -------------------------------------------------------------------------*/
+
+                /* ADC2 is the SM1000 microphone, DAC1 is the modulator signal we send to radio tx */
+
+                if (adc2_read(&adc16k[FDMDV_OS_TAPS_16K], n_samples_16k) == 0) {
+                    GPIOE->ODR = (1 << 3);
+
+                    /* clipping indicator */
+
+                    led_err(0);
+                    for (i=0; i<n_samples_16k; i++) {
+                        if (abs(adc16k[FDMDV_OS_TAPS_16K+i]) > 28000)
+                            led_err(1);
+                    }
+
+                    fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], n_samples);
+
+                    if (op_mode == ANALOG) {
+                        for(i=0; i<n_samples; i++)
+                            dac8k[FDMDV_OS_TAPS_8K+i] = adc8k[i];
+                        fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], n_samples);
+                        dac1_write(dac16k, n_samples_16k);
+                    }
+                    if (op_mode == DV) {
+                        freedv_tx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);
+                        for(i=0; i<n_samples; i++)
+                            dac8k[FDMDV_OS_TAPS_8K+i] *= 0.398; /* 8dB back off from peak */
+                        fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], n_samples);
+                        dac1_write(dac16k, n_samples_16k);
+                    }
+                    if (op_mode == TONE) {
+                        if (!tone_gen.remain)
+                            /*
+                             * Somewhat ugly, but UINT16_MAX is effectively
+                             * infinite.
+                             */
+                            tone_reset(&tone_gen, 500, UINT16_MAX);
+                        int len = dac1_free();
+                        if (len > n_samples_16k)
+                            len = n_samples_16k;
+                        for(i=0; i<len; i++)
+                            /* 8dB back off from peak */
+                            dac16k[i] = tone_next(&tone_gen)*0.398;
+                        dac1_write(dac16k, len);
+                    }
+
+                    led_ptt(1); led_rt(0); led_err(0); not_cptt(0);
+                    GPIOE->ODR &= ~(1 << 3);
+                }
+                break;
+
+            case STATE_RX:
+            case STATE_RX_TOT:
+                /* Receive --------------------------------------------------------------------------*/
+
+                not_cptt(1);
+                led_ptt(0);
+
+                /* ADC1 is the demod in signal from the radio rx, DAC2 is the SM1000 speaker */
+
+                if (op_mode == ANALOG) {
+
+                    if (adc1_read(&adc16k[FDMDV_OS_TAPS_16K], n_samples_16k) == 0) {
+                        fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], n_samples);
+                        for(i=0; i<n_samples; i++)
+                            dac8k[FDMDV_OS_TAPS_8K+i] = adc8k[i];
+                        fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], n_samples);
+                        spk_nsamples = n_samples_16k;
+                        led_rt(0); led_err(0);
+                   }
+                }
+                else {
+
+                    /* regular DV mode */
+
+                    nin = freedv_nin(f);
+                    nout = nin;
+                    freedv_set_total_bit_errors(f, 0);
+                    if (adc1_read(&adc16k[FDMDV_OS_TAPS_16K], 2*nin) == 0) {
+                        GPIOE->ODR = (1 << 3);
+                        fdmdv_16_to_8_short(adc8k, &adc16k[FDMDV_OS_TAPS_16K], nin);
+                        nout = freedv_rx(f, &dac8k[FDMDV_OS_TAPS_8K], adc8k);
+                        fdmdv_8_to_16_short(dac16k, &dac8k[FDMDV_OS_TAPS_8K], nout);
+                        spk_nsamples = 2*nout;
+                        led_rt(freedv_get_sync(f)); led_err(freedv_get_total_bit_errors(f));
+                        GPIOE->ODR &= ~(1 << 3);
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+
+        /* Write audio to speaker output */
+        if (spk_nsamples || sfx_player.note || morse_player.msg) {
+            /* Make a note of our playback position */
+            int16_t* play_ptr = dac16k;
+
+            if (!spk_nsamples)
+                spk_nsamples = dac2_free();
+
+            /*
+             * There is audio to play on the external speaker.  If there
+             * is a sound or announcement, software-mix it into the outgoing
+             * buffer.
+             */
+            if (sfx_player.note) {
+                int i;
+                if (menu.stack_depth) {
+                    /* Exclusive */
+                    for (i = 0; i < spk_nsamples; i++)
+                        dac16k[i] = sfx_next(&sfx_player) >> prefs.menu_vol;
+                } else {
+                    /* Software mix */
+                    for (i = 0; i < spk_nsamples; i++)
+                        dac16k[i] = software_mix(dac16k[i],
+                                sfx_next(&sfx_player) >> prefs.menu_vol);
+                }
+                if (!sfx_player.note && morse_player.msg)
+                    announceTicker = ANNOUNCE_DELAY;
+            } else if (!announceTicker && morse_player.msg) {
+                int i;
+                if (menu.stack_depth) {
+                    for (i = 0; i < spk_nsamples; i++)
+                        dac16k[i] = morse_next(&morse_player) >> prefs.menu_vol;
+                } else {
+                    for (i = 0; i < spk_nsamples; i++)
+                        dac16k[i] = software_mix(dac16k[i],
+                                morse_next(&morse_player) >> prefs.menu_vol);
+                }
+            }
+
+            while (spk_nsamples) {
+                /* Get the number of samples to be played this time around */
+                int n_rem = dac2_free();
+                if (spk_nsamples < n_rem)
+                    n_rem = spk_nsamples;
+                /* Play the audio */
+                dac2_write(play_ptr, n_rem);
+                spk_nsamples -= n_rem;
+                play_ptr += n_rem;
+            }
+
+            /* Clear out buffer */
+            memset(dac16k, 0, sizeof(dac16k));
+        }
+
+    } /* while(1) ... */
+}
+
+/*
+ * SysTick Interrupt Handler
+ */
+
+void SysTick_Handler(void)
+{
+    switch_tick(&sw_select);
+    switch_tick(&sw_back);
+    switch_tick(&sw_ptt);
+    if (menuTicker > 0) {
+        menuTicker--;
+    }
+    if (menuLEDTicker > 0) {
+        menuLEDTicker--;
+    }
+    if (announceTicker > 0) {
+        announceTicker--;
+    }
+    tot_tick(&tot);
+}
+
+/* ---------------------------- Menu data --------------------------- */
+
+/*!
+ * Default handler for menu callback.
+ */
+static void menu_default_cb(struct menu_t* const menu, uint32_t event)
+{
+    /* Get the current menu item */
+    const struct menu_item_t* item = menu_item(menu, 0);
+    uint8_t announce = 0;
+
+    switch(event) {
+        case MENU_EVT_ENTERED:
+            sfx_play(&sfx_player, sound_startup);
+            /* Choose first item */
+            menu->current = 0;
+        case MENU_EVT_RETURNED:
+            announce = 1;
+            break;
+        case MENU_EVT_NEXT:
+            sfx_play(&sfx_player, sound_click);
+            menu->current = (menu->current + 1) % item->num_children;
+            announce = 1;
+            break;
+        case MENU_EVT_PREV:
+            sfx_play(&sfx_player, sound_click);
+            menu->current = (menu->current - 1) % item->num_children;
+            announce = 1;
+            break;
+        case MENU_EVT_SELECT:
+            /* Enter the sub-menu */
+            menu_enter(menu, item->children[menu->current]);
+            break;
+        case MENU_EVT_BACK:
+            /* Exit the menu */
+            sfx_play(&sfx_player, sound_returned);
+        case MENU_EVT_EXIT:
+            menu_leave(menu);
+            break;
+        default:
+            break;
+    }
+
+    if (announce) {
+        /* Announce the label of the selected child */
+        morse_play(&morse_player,
+                item->children[menu->current]->label);
+    }
+}
+
+/* Root menu item forward declarations */
+static const struct menu_item_t const* menu_root_children[];
+/* Root item definition */
+static const struct menu_item_t menu_root = {
+    .label          = "MENU",
+    .event_cb       = menu_default_cb,
+    .children       = menu_root_children,
+    .num_children   = 2,
+};
+
+/* Child declarations */
+static const struct menu_item_t menu_op_mode;
+static const struct menu_item_t menu_tot;
+static const struct menu_item_t menu_ui;
+static const struct menu_item_t const* menu_root_children[] = {
+    &menu_op_mode,
+    &menu_tot,
+    &menu_ui,
+};
+
+
+/* Operation Mode menu forward declarations */
+static void menu_op_mode_cb(struct menu_t* const menu, uint32_t event);
+static struct menu_item_t const* menu_op_mode_children[];
+/* Operation mode menu */
+static const struct menu_item_t menu_op_mode = {
+    .label          = "MODE",
+    .event_cb       = menu_op_mode_cb,
+    .children       = menu_op_mode_children,
+    .num_children   = 3,
+};
+/* Children */
+static const struct menu_item_t menu_op_mode_analog = {
+    .label          = "ANA",
+    .event_cb       = NULL,
+    .children       = NULL,
+    .num_children   = 0,
+    .data           = {
+        .ui         = ANALOG,
+    },
+};
+static const struct menu_item_t menu_op_mode_dv16k = {
+    .label          = "1600",
+    .event_cb       = NULL,
+    .children       = NULL,
+    .num_children   = 0,
+    .data           = {
+        .ui         = DV,
+    },
+};
+/* static const struct menu_item_t menu_op_mode_dv700b
+    .label          = "700",
+    .event_cb       = NULL,
+    .children       = NULL,
+    .num_children   = 0,
+    .data           = {
+        .ui         = DV,
+    },
+};*/
+static const struct menu_item_t menu_op_mode_tone = {
+    .label          = "TONE",
+    .event_cb       = NULL,
+    .children       = NULL,
+    .num_children   = 0,
+    .data           = {
+        .ui         = TONE,
+    },
+};
+static struct menu_item_t const* menu_op_mode_children[] = {
+    &menu_op_mode_analog,
+    &menu_op_mode_dv16k,
+    /* &menu_op_mode_dv700b, */
+    &menu_op_mode_tone,
+};
+/* Callback function */
+static void menu_op_mode_cb(struct menu_t* const menu, uint32_t event)
+{
+    const struct menu_item_t* item = menu_item(menu, 0);
+    uint8_t announce = 0;
+
+    switch(event) {
+        case MENU_EVT_ENTERED:
+            sfx_play(&sfx_player, sound_startup);
+            /* Choose current item */
+            switch(prefs.op_mode) {
+                case DV:
+                    menu->current = 1;
+                    break;
+                case TONE:
+                    menu->current = 2;
+                    break;
+                default:
+                    menu->current = 0;
+            }
+        case MENU_EVT_RETURNED:
+            /* Shouldn't happen, but we handle it anyway */
+            announce = 1;
+            break;
+        case MENU_EVT_NEXT:
+            sfx_play(&sfx_player, sound_click);
+            menu->current = (menu->current + 1) % item->num_children;
+            announce = 1;
+            break;
+        case MENU_EVT_PREV:
+            sfx_play(&sfx_player, sound_click);
+            menu->current = (menu->current - 1) % item->num_children;
+            announce = 1;
+            break;
+        case MENU_EVT_SELECT:
+            /* Choose the selected mode */
+            prefs.op_mode = item->children[menu->current]->data.ui;
+            /* Play the "selected" tune and return. */
+            sfx_play(&sfx_player, sound_startup);
+            prefs_changed = 1;
+            menu_leave(menu);
+            break;
+        case MENU_EVT_BACK:
+            /* Exit the menu */
+            sfx_play(&sfx_player, sound_returned);
+        case MENU_EVT_EXIT:
+            menu_leave(menu);
+            break;
+        default:
+            break;
+    }
+
+    if (announce) {
+        /* Announce the label of the selected child */
+        morse_play(&morse_player,
+                item->children[menu->current]->label);
+    }
+}
+
+
+/* Time-out timer menu forward declarations */
+static struct menu_item_t const* menu_tot_children[];
+/* Operation mode menu */
+static const struct menu_item_t menu_tot = {
+    .label          = "TOT",
+    .event_cb       = menu_default_cb,
+    .children       = menu_tot_children,
+    .num_children   = 2,
+};
+/* Children */
+static const struct menu_item_t menu_tot_time;
+static const struct menu_item_t menu_tot_warn;
+static struct menu_item_t const* menu_tot_children[] = {
+    &menu_tot_time,
+    &menu_tot_warn,
+};
+
+/* TOT time menu forward declarations */
+static void menu_tot_time_cb(struct menu_t* const menu, uint32_t event);
+/* TOT time menu */
+static const struct menu_item_t menu_tot_time = {
+    .label          = "TIME",
+    .event_cb       = menu_tot_time_cb,
+    .children       = NULL,
+    .num_children   = 0,
+};
+
+/* Callback function */
+static void menu_tot_time_cb(struct menu_t* const menu, uint32_t event)
+{
+    uint8_t announce = 0;
+
+    switch(event) {
+        case MENU_EVT_ENTERED:
+            sfx_play(&sfx_player, sound_startup);
+            /* Get the current period */
+            menu->current = prefs.tot_period;
+        case MENU_EVT_RETURNED:
+            /* Shouldn't happen, but we handle it anyway */
+            announce = 1;
+            break;
+        case MENU_EVT_NEXT:
+            sfx_play(&sfx_player, sound_click);
+            /* Adjust the frequency up by 50 Hz */
+            if (prefs.tot_period < 600)
+                prefs.tot_period += 5;
+            announce = 1;
+            break;
+        case MENU_EVT_PREV:
+            sfx_play(&sfx_player, sound_click);
+            if (prefs.tot_period > 0)
+                prefs.tot_period -= 5;
+            announce = 1;
+            break;
+        case MENU_EVT_SELECT:
+            /* Play the "selected" tune and return. */
+            sfx_play(&sfx_player, sound_startup);
+            prefs_changed = 1;
+            menu_leave(menu);
+            break;
+        case MENU_EVT_BACK:
+            /* Restore the mode and exit the menu */
+            sfx_play(&sfx_player, sound_returned);
+        case MENU_EVT_EXIT:
+            prefs.tot_period = menu->current;
+            menu_leave(menu);
+            break;
+        default:
+            break;
+    }
+
+    if (announce) {
+        /* Render the text, thankfully we don't need re-entrancy */
+        static char period[5];
+        snprintf(period, 4, "%d", prefs.tot_period);
+        /* Announce the period */
+        morse_play(&morse_player, period);
+    }
+};
+
+/* TOT warning time menu forward declarations */
+static void menu_tot_warn_cb(struct menu_t* const menu, uint32_t event);
+/* TOT warning time menu */
+static const struct menu_item_t menu_tot_warn = {
+    .label          = "WARN",
+    .event_cb       = menu_tot_warn_cb,
+    .children       = NULL,
+    .num_children   = 0,
+};
+
+/* Callback function */
+static void menu_tot_warn_cb(struct menu_t* const menu, uint32_t event)
+{
+    uint8_t announce = 0;
+
+    switch(event) {
+        case MENU_EVT_ENTERED:
+            sfx_play(&sfx_player, sound_startup);
+            /* Get the current period */
+            if (prefs.tot_warn_period < prefs.tot_period)
+                menu->current = prefs.tot_warn_period;
+            else
+                menu->current = prefs.tot_period;
+        case MENU_EVT_RETURNED:
+            /* Shouldn't happen, but we handle it anyway */
+            announce = 1;
+            break;
+        case MENU_EVT_NEXT:
+            sfx_play(&sfx_player, sound_click);
+            /* Adjust the frequency up by 50 Hz */
+            if (prefs.tot_warn_period < prefs.tot_period)
+                prefs.tot_warn_period += 5;
+            announce = 1;
+            break;
+        case MENU_EVT_PREV:
+            sfx_play(&sfx_player, sound_click);
+            if (prefs.tot_warn_period > 0)
+                prefs.tot_warn_period -= 5;
+            announce = 1;
+            break;
+        case MENU_EVT_SELECT:
+            /* Play the "selected" tune and return. */
+            sfx_play(&sfx_player, sound_startup);
+            prefs_changed = 1;
+            menu_leave(menu);
+            break;
+        case MENU_EVT_BACK:
+            /* Restore the mode and exit the menu */
+            sfx_play(&sfx_player, sound_returned);
+        case MENU_EVT_EXIT:
+            prefs.tot_warn_period = menu->current;
+            menu_leave(menu);
+            break;
+        default:
+            break;
+    }
+
+    if (announce) {
+        /* Render the text, thankfully we don't need re-entrancy */
+        static char period[5];
+        snprintf(period, 4, "%d", prefs.tot_warn_period);
+        /* Announce the period */
+        morse_play(&morse_player, period);
+    }
+};
+
+/* UI menu forward declarations */
+static struct menu_item_t const* menu_ui_children[];
+/* Operation mode menu */
+static const struct menu_item_t menu_ui = {
+    .label          = "UI",
+    .event_cb       = menu_default_cb,
+    .children       = menu_ui_children,
+    .num_children   = 3,
+};
+/* Children */
+static const struct menu_item_t menu_ui_freq;
+static const struct menu_item_t menu_ui_speed;
+static const struct menu_item_t menu_ui_vol;
+static struct menu_item_t const* menu_ui_children[] = {
+    &menu_ui_freq,
+    &menu_ui_speed,
+    &menu_ui_vol,
+};
+
+/* UI Frequency menu forward declarations */
+static void menu_ui_freq_cb(struct menu_t* const menu, uint32_t event);
+/* UI Frequency menu */
+static const struct menu_item_t menu_ui_freq = {
+    .label          = "FREQ",
+    .event_cb       = menu_ui_freq_cb,
+    .children       = NULL,
+    .num_children   = 0,
+};
+/* Callback function */
+static void menu_ui_freq_cb(struct menu_t* const menu, uint32_t event)
+{
+    uint8_t announce = 0;
+
+    switch(event) {
+        case MENU_EVT_ENTERED:
+            sfx_play(&sfx_player, sound_startup);
+            /* Get the current frequency */
+            menu->current = morse_player.freq;
+        case MENU_EVT_RETURNED:
+            /* Shouldn't happen, but we handle it anyway */
+            announce = 1;
+            break;
+        case MENU_EVT_NEXT:
+            sfx_play(&sfx_player, sound_click);
+            /* Adjust the frequency up by 50 Hz */
+            if (morse_player.freq < 2000)
+                morse_player.freq += 50;
+            announce = 1;
+            break;
+        case MENU_EVT_PREV:
+            sfx_play(&sfx_player, sound_click);
+            if (morse_player.freq > 50)
+                morse_player.freq -= 50;
+            announce = 1;
+            break;
+        case MENU_EVT_SELECT:
+            /* Play the "selected" tune and return. */
+            sfx_play(&sfx_player, sound_startup);
+            prefs_changed = 1;
+            menu_leave(menu);
+            break;
+        case MENU_EVT_BACK:
+            /* Restore the mode and exit the menu */
+            sfx_play(&sfx_player, sound_returned);
+        case MENU_EVT_EXIT:
+            morse_player.freq = menu->current;
+            menu_leave(menu);
+            break;
+        default:
+            break;
+    }
+
+    if (announce) {
+        /* Render the text, thankfully we don't need re-entrancy */
+        static char freq[5];
+        snprintf(freq, 4, "%d", morse_player.freq);
+        /* Announce the frequency */
+        morse_play(&morse_player, freq);
+    }
+};
+
+/* UI Speed menu forward declarations */
+static void menu_ui_speed_cb(struct menu_t* const menu, uint32_t event);
+/* UI Speed menu */
+static const struct menu_item_t menu_ui_speed = {
+    .label          = "WPM",
+    .event_cb       = menu_ui_speed_cb,
+    .children       = NULL,
+    .num_children   = 0,
+};
+/* Callback function */
+static void menu_ui_speed_cb(struct menu_t* const menu, uint32_t event)
+{
+    uint8_t announce = 0;
+
+    /* Get the current WPM */
+    uint16_t curr_wpm = 1200 / morse_player.dit_time;
+
+    switch(event) {
+        case MENU_EVT_ENTERED:
+            sfx_play(&sfx_player, sound_startup);
+            /* Get the current frequency */
+            menu->current = morse_player.dit_time;
+        case MENU_EVT_RETURNED:
+            /* Shouldn't happen, but we handle it anyway */
+            announce = 1;
+            break;
+        case MENU_EVT_NEXT:
+            sfx_play(&sfx_player, sound_click);
+            /* Increment WPM by 5 */
+            if (curr_wpm < 60)
+                curr_wpm += 5;
+            announce = 1;
+            break;
+        case MENU_EVT_PREV:
+            sfx_play(&sfx_player, sound_click);
+            if (curr_wpm > 5)
+                curr_wpm -= 5;
+            announce = 1;
+            break;
+        case MENU_EVT_SELECT:
+            /* Play the "selected" tune and return. */
+            sfx_play(&sfx_player, sound_startup);
+            prefs_changed = 1;
+            menu_leave(menu);
+            break;
+        case MENU_EVT_BACK:
+            /* Restore the mode and exit the menu */
+            sfx_play(&sfx_player, sound_returned);
+        case MENU_EVT_EXIT:
+            morse_player.dit_time = menu->current;
+            menu_leave(menu);
+            break;
+        default:
+            break;
+    }
+
+    if (announce) {
+        /* Render the text, thankfully we don't need re-entrancy */
+        static char wpm[5];
+        snprintf(wpm, 4, "%d", curr_wpm);
+        /* Set the new parameter */
+        morse_player.dit_time = 1200 / curr_wpm;
+        /* Announce the words per minute */
+        morse_play(&morse_player, wpm);
+    }
+};
+
+/* UI volume menu forward declarations */
+static void menu_ui_vol_cb(struct menu_t* const menu, uint32_t event);
+/* UI volume menu */
+static const struct menu_item_t menu_ui_vol = {
+    .label          = "VOL",
+    .event_cb       = menu_ui_vol_cb,
+    .children       = NULL,
+    .num_children   = 0,
+};
+/* Callback function */
+static void menu_ui_vol_cb(struct menu_t* const menu, uint32_t event)
+{
+    uint8_t announce = 0;
+
+    switch(event) {
+        case MENU_EVT_ENTERED:
+            sfx_play(&sfx_player, sound_startup);
+            /* Get the current volume */
+            menu->current = prefs.menu_vol;
+        case MENU_EVT_RETURNED:
+            /* Shouldn't happen, but we handle it anyway */
+            announce = 1;
+            break;
+        case MENU_EVT_NEXT:
+            sfx_play(&sfx_player, sound_click);
+            if (prefs.menu_vol > 0)
+                prefs.menu_vol--;
+            announce = 1;
+            break;
+        case MENU_EVT_PREV:
+            sfx_play(&sfx_player, sound_click);
+            if (prefs.menu_vol < 14)
+                prefs.menu_vol++;
+            announce = 1;
+            break;
+        case MENU_EVT_SELECT:
+            /* Play the "selected" tune and return. */
+            sfx_play(&sfx_player, sound_startup);
+            menu_leave(menu);
+            prefs_changed = 1;
+            break;
+        case MENU_EVT_BACK:
+            /* Restore the mode and exit the menu */
+            sfx_play(&sfx_player, sound_returned);
+        case MENU_EVT_EXIT:
+            prefs.menu_vol = menu->current;
+            menu_leave(menu);
+            break;
+        default:
+            break;
+    }
+
+    if (announce) {
+        /* Render the text, thankfully we don't need re-entrancy */
+        static char vol[3];
+        snprintf(vol, 3, "%d", 15 - prefs.menu_vol);
+        /* Announce the volume level */
+        morse_play(&morse_player, vol);
+    }
+};
diff --git a/codec2/branches/0.7/stm32/src/sm2000_adc_dump.c b/codec2/branches/0.7/stm32/src/sm2000_adc_dump.c
new file mode 100644 (file)
index 0000000..353f7d9
--- /dev/null
@@ -0,0 +1,113 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sm2000_stw.c
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2016
+
+  Test program to support SM2000 "set to work" - tetsing and bring up.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include "new_i2c.h"
+#include "si53xx.h"
+#include "debugblinky.h"
+#include "sm1000_leds_switches.h"
+#include "stm32f4_dac.h"
+#include "stm32f4_adc.h"
+#include "stm32f4_usb_vcp.h"
+
+#define SINE_SAMPLES   24
+
+/* 32 sample sine wave which at Fs=16kHz will be 500Hz.  Note samples
+   are 16 bit 2's complement, the DAC driver convertsto 12 bit
+   unsigned. */
+
+short aSine[] = {
+     5000,  -2500,  -2500, 5000,  -2500,  -2500, 
+     5000,  -2500,  -2500, 5000,  -2500,  -2500, 
+     5000,  -2500,  -2500, 5000,  -2500,  -2500, 
+     5000,  -2500,  -2500, 5000,  -2500,  -2500
+};
+short zeros[SINE_SAMPLES];
+
+int main(void) {
+    int ptt, i;
+    uint64_t freq_in_Hz_times_100;
+
+    for(i=0; i<SINE_SAMPLES; i++)
+        aSine[i] *= 1.5;
+
+    sm1000_leds_switches_init();
+    led_pwr(1);
+    led_ptt(0);
+
+    init_debug_blinky();
+    txrx_12V(0);
+
+    I2C_Setup();
+    si5351_init(0, SI5351_CRYSTAL_LOAD_6PF, 0);
+    freq_in_Hz_times_100 = 1070000000ULL - 3200000ULL;
+    // int ret = si5351_set_freq(freq_in_Hz_times_100, 0, SI5351_CLK0);
+    si5351_set_freq(freq_in_Hz_times_100, 0, SI5351_CLK0);
+
+    //dac_open(DAC_FS_96KHZ, 4*DAC_BUF_SZ);
+    adc_open(ADC_FS_96KHZ, 10*ADC_BUF_SZ);
+    
+    usb_vcp_init();
+
+    while(1) {
+        ptt = switch_ptt();
+        led_ptt(ptt);
+        txrx_12V(ptt);
+
+        /*
+        if (ptt)
+            dac1_write((short*)aSine, SINE_SAMPLES);
+        else
+            dac1_write((short*)zeros, SINE_SAMPLES);
+        */
+
+        /* read another buffer from USB when DAC empties */
+        /* note assumes USB host write two bytes at a time */
+        /* and assumes enough bytes are available, need to test that
+           host is throttled appropriately */
+
+        int n = adc1_samps();
+        if (n) {
+            uint16_t  buf[n];
+            uint8_t   b;
+            adc1_read((short*)buf,n);
+            for(i=0; i<n; i++) {
+                               b = (uint8_t)(buf[i]&0xFF);
+                               VCP_put_char(b);
+                               b = (uint8_t)((buf[i]>>8)&0xFF);
+                               VCP_put_char(b);
+                //VCP_get_char(&b);
+                //uint16_t s = b << 8;
+                //VCP_get_char(&b);
+                //s += b;
+                //buf[i] = s;
+            }
+            //dac1_write((short*)buf, n);
+        }
+                
+    }
+}
diff --git a/codec2/branches/0.7/stm32/src/sm2000_rxdemo.c b/codec2/branches/0.7/stm32/src/sm2000_rxdemo.c
new file mode 100644 (file)
index 0000000..048b014
--- /dev/null
@@ -0,0 +1,153 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sm2000_stw.c
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2016
+
+  Test program to support SM2000 "set to work" - tetsing and bring up.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include "new_i2c.h"
+#include "si53xx.h"
+#include "debugblinky.h"
+#include "sm1000_leds_switches.h"
+#include "stm32f4_dac.h"
+#include "stm32f4_adc.h"
+//#include "stm32f4_usb_vcp.h"
+#include "fsk.h"
+#include "freedv_vhf_framing.h"
+#include "freedv_api.h"
+#include "golay23.h"
+#include "string.h"
+
+#include "malloc.h"
+
+extern void initialise_monitor_handles(void);
+volatile size_t tos;
+
+size_t stack_size(){
+    volatile int x = 0;
+    return tos-((size_t)&x);
+}
+
+//float modbuf[4040];
+//short speechbuf[320];
+
+int main(void) {
+    int ptt;
+    uint64_t freq_in_Hz_times_100;
+    struct freedv * fdv;
+    struct FSK * fsk;
+    volatile int z = 0;
+    tos = (size_t)&z;
+    //initialise_monitor_handles();
+    //printf("Testing\n");
+    sm1000_leds_switches_init();
+    led_pwr(1);
+    
+    init_debug_blinky();
+    txrx_12V(0);
+
+    
+    I2C_Setup();
+    si5351_init(0, SI5351_CRYSTAL_LOAD_6PF, 0);
+    freq_in_Hz_times_100 = 1070000000ULL - 3200000ULL;
+    // int ret = si5351_set_freq(freq_in_Hz_times_100, 0, SI5351_CLK0);
+    si5351_set_freq(freq_in_Hz_times_100, 0, SI5351_CLK0);
+    
+    /* Open up the FreeDV thing */
+       fdv = freedv_open(FREEDV_MODE_2400A);
+       /* Set 96k samp rate to allow for 32k fsk signal */
+    freedv_set_alt_modem_samp_rate(fdv,96000);
+    /* Get the FSK struct and set up freq estimator params */
+    fsk = freedv_get_fsk(fdv);
+    fsk_set_est_limits(fsk,28000,34000);
+    fsk->f1_tx = 32000-1800;
+    
+    float * modbuf = malloc(sizeof(float)*(freedv_get_n_max_modem_samples(fdv)+10));
+    short * speechbuf = malloc(sizeof(short)*freedv_get_n_speech_samples(fdv));
+    //short buf[ADC_BUF_SZ*4];
+    dac_open(DAC_FS_16KHZ*2, DAC_BUF_SZ*4);
+    adc_open(ADC_FS_96KHZ, ADC_BUF_SZ*11);
+    //usb_vcp_init();
+    int mbptr = 0;
+       int spstate;
+       ptt = 0;
+       int nin = freedv_nin(fdv);
+       spstate = 0;
+    for(int i=0;i<freedv_get_n_max_modem_samples(fdv);i++){
+        modbuf[i]=0;
+    }
+    while(1) {
+               if(switch_ptt() && (!spstate)){
+                       ptt = ptt ? 0 : 1;
+                       mbptr = 0;
+               }
+               spstate = switch_ptt();
+               
+        txrx_12V(ptt);
+        
+        if(ptt){
+               }else{
+                       int n = adc1_samps();
+            if (n) {
+                if((n+mbptr)>nin){
+                    n = nin-mbptr;
+                }
+                //In it's own scope so buf is deallocated after it's used 
+                {
+                    short buf[n];
+                    adc1_read(buf,n);
+                    for(int i=0;i<n&&mbptr<nin;i++,mbptr++){
+                        modbuf[mbptr] = buf[i];
+                        //printf("%d\n",stack_size(tos));
+                    }
+                }
+               
+                               if(mbptr>=nin){
+                                       mbptr = 0;
+                                       led_rt(1);
+                                       freedv_floatrx(fdv,speechbuf,modbuf);
+                    led_rt(0);
+    
+                                       if(freedv_get_sync(fdv)){
+                                               led_err(1);
+                                       }else{
+                                               led_err(0);
+                                       }
+                                       if(freedv_nin(fdv)!=nin){
+                                               led_ptt(1);
+                                       }else{
+                                               led_ptt(0);
+                                       }
+                                       nin = freedv_nin(fdv);
+                                       
+                               }
+                       }
+            if(dac2_free()>freedv_get_n_speech_samples(fdv)){
+                dac2_write(speechbuf,freedv_get_n_speech_samples(fdv));
+            }
+               }
+    }
+}
diff --git a/codec2/branches/0.7/stm32/src/sm2000_stw.c b/codec2/branches/0.7/stm32/src/sm2000_stw.c
new file mode 100644 (file)
index 0000000..448644f
--- /dev/null
@@ -0,0 +1,169 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: sm2000_stw.c
+  AUTHOR......: David Rowe
+  DATE CREATED: June 2016
+
+  Test program to support SM2000 "set to work" - tetsing and bring up.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdint.h>
+#include "new_i2c.h"
+#include "si53xx.h"
+#include "debugblinky.h"
+#include "sm1000_leds_switches.h"
+#include "stm32f4_dac.h"
+#include "stm32f4_adc.h"
+//#include "stm32f4_usb_vcp.h"
+#include "fsk.h"
+#include "freedv_vhf_framing.h"
+#include "golay23.h"
+#include "string.h"
+#define SINE_SAMPLES   24
+
+/* 32 sample sine wave which at Fs=16kHz will be 500Hz.  Note samples
+   are 16 bit 2's complement, the DAC driver convertsto 12 bit
+   unsigned. */
+
+short aSine[] = {
+     5000,  -2500,  -2500, 5000,  -2500,  -2500, 
+     5000,  -2500,  -2500, 5000,  -2500,  -2500, 
+     5000,  -2500,  -2500, 5000,  -2500,  -2500, 
+     5000,  -2500,  -2500, 5000,  -2500,  -2500
+};
+short zeros[SINE_SAMPLES];
+
+uint8_t bit_buf[] = { 1,0,1,1,0,0,0,1,
+                  1,0,1,1,0,1,0,1,
+                  0,1,0,0,1,0,1,1,
+                  1,0,0,0,0,0,0,1,
+                  1,1,0,0,0,0,0,1,
+                  1,0,1,0,0,0,0,1,
+                  1,0,0,1,0,0,0,1,
+                  1,0,0,0,1,0,0,1,
+                  1,0,0,0,0,1,0,1,
+                  1,0,0,0,0,0,1,1,
+                  1,0,0,0,0,0,1,1,
+                  1,0,0,0,0,0,1,1, };
+                  
+int main(void) {
+    int ptt, i;
+    uint64_t freq_in_Hz_times_100;
+    struct FSK * fsk;
+    struct freedv_vhf_deframer * deframer;
+    float * mod_buf;
+    
+    sm1000_leds_switches_init();
+    led_pwr(1);
+    
+    fsk = fsk_create_hbr(96000,1200,10,4,32000-1800,1200);
+    fsk_set_est_limits(fsk,29000,35000);
+    deframer = fvhff_create_deframer(FREEDV_VHF_FRAME_A,1);
+    if(fsk==NULL){
+               led_err(1);
+               while(1);
+       }
+    mod_buf = malloc(sizeof(float)*fsk->Nmem);
+    init_debug_blinky();
+    txrx_12V(0);
+
+    I2C_Setup();
+    si5351_init(0, SI5351_CRYSTAL_LOAD_6PF, 0);
+    freq_in_Hz_times_100 = 1070000000ULL - 3200000ULL;
+    si5351_set_freq(freq_in_Hz_times_100, 0, SI5351_CLK0);
+
+    dac_open(DAC_FS_96KHZ, 2000);
+    adc_open(ADC_FS_96KHZ, 2000);
+
+    //usb_vcp_init();
+    int mbptr = 0;
+       int golay_ctr = 0;
+       uint8_t c2_buffer[8];
+       int k;
+       int spstate;
+       ptt = 1;
+       int nin = fsk_nin(fsk);
+       spstate = 0;
+    while(1) {
+               if(switch_ptt() && (!spstate)){
+                       ptt = ptt ? 0 : 1;
+                       mbptr = 0;
+               }
+               spstate = switch_ptt();
+               
+        led_ptt(ptt);
+        txrx_12V(ptt);
+        
+        if(ptt){
+                       int n = dac1_free();
+                       if (n) {
+                               int16_t  buf[n];
+                               for(i=0; i<n && mbptr<fsk->N; i++,mbptr++) {
+                                       buf[i] = (short)(mod_buf[mbptr]*700);
+                               }
+                               dac1_write((short*)buf, i);
+                       }
+                       if(mbptr>=fsk->N){
+                               /* Encode frame index into golay codeword to protect from test BER*/
+                               k = golay23_encode((golay_ctr)&0x0FFF);
+                               c2_buffer[5] = (k    )&0xFF;
+                               c2_buffer[1] = (k>>8 )&0xFF;
+                               c2_buffer[0] = (k>>16)&0x7F;
+                               /* Frame the bits */
+                               fvhff_frame_bits(FREEDV_VHF_FRAME_A, bit_buf, c2_buffer,NULL,NULL);
+                               /* Mod the FSK */
+                               fsk_mod(fsk,mod_buf,bit_buf);
+                               mbptr = 0;
+                               golay_ctr++;
+                       }
+               }else{
+                       
+                       int n = adc1_samps();
+                       if (n) {
+                               int16_t buf[n];
+                               adc1_read(buf,n);
+                               for(i=0; i<n && mbptr<nin; i++,mbptr++){
+                                       mod_buf[mbptr] = ((float)buf[i]);
+                               }
+                               if(mbptr>=nin){
+                                       led_rt(1);
+                                       fsk_demod(fsk,bit_buf,mod_buf);
+                                       led_rt(0);
+                                       if(fvhff_deframe_bits(deframer,c2_buffer,NULL,NULL,bit_buf)){
+                                               led_err(1);             
+                                       }else{
+                                               //led_err(0);
+                                               led_err(0);
+                                       }
+                                       mbptr = 0;
+                                       if(fsk_nin(fsk)!=nin){
+                                               led_ptt(1);
+                                       }else{
+                                               led_ptt(0);
+                                       }
+                                       nin = fsk_nin(fsk);
+                                       
+                               }
+                       }
+               }
+    }
+}
diff --git a/codec2/branches/0.7/stm32/src/sounds.c b/codec2/branches/0.7/stm32/src/sounds.c
new file mode 100644 (file)
index 0000000..54848b8
--- /dev/null
@@ -0,0 +1,62 @@
+/*!
+ * Sound effect library.
+ *
+ * This provides some sound effects for the SM1000 UI.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "sounds.h"
+
+const struct sfx_note_t sound_startup[] = {
+       {.freq = 600, .duration = 80},
+       {.freq = 800, .duration = 80},
+       {.freq = 1000, .duration = 80},
+       {.freq = 0, .duration = 0}
+};
+
+const struct sfx_note_t sound_returned[] = {
+       {.freq = 1000, .duration = 80},
+       {.freq = 800, .duration = 80},
+       {.freq = 600, .duration = 80},
+       {.freq = 0, .duration = 0}
+};
+
+const struct sfx_note_t sound_click[] = {
+       {.freq = 1200, .duration = 10},
+       {.freq = 0, .duration = 0}
+};
+
+const struct sfx_note_t sound_death_march[] = {
+       {.freq  = 340,  .duration = 400},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 340,  .duration = 400},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 340,  .duration = 400},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 420,  .duration = 400},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 400,  .duration = 300},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 340,  .duration = 120},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 340,  .duration = 120},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 300,  .duration = 200},
+       {.freq  = 0,    .duration = 80},
+       {.freq  = 340,  .duration = 400},
+       {.freq  = 0,    .duration = 0},
+};
diff --git a/codec2/branches/0.7/stm32/src/startup_stm32f4xx.s b/codec2/branches/0.7/stm32/src/startup_stm32f4xx.s
new file mode 100644 (file)
index 0000000..c5c6770
--- /dev/null
@@ -0,0 +1,512 @@
+/**
+  ******************************************************************************
+  * @file      startup_stm32f4xx.s
+  * @author    MCD Application Team
+  * @version   V1.0.0
+  * @date      30-September-2011
+  * @brief     STM32F4xx Devices vector table for Atollic TrueSTUDIO toolchain.
+  *            This module performs:
+  *                - Set the initial SP
+  *                - Set the initial PC == Reset_Handler,
+  *                - Set the vector table entries with the exceptions ISR address
+  *                - Configure the clock system and the external SRAM mounted on
+  *                  STM324xG-EVAL board to be used as data memory (optional,
+  *                  to be enabled by user)
+  *                - Branches to main in the C library (which eventually
+  *                  calls main()).
+  *            After Reset the Cortex-M4 processor is in Thread mode,
+  *            priority is Privileged, and the Stack is set to Main.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+  .syntax unified
+  .cpu cortex-m3
+  .fpu softvfp
+  .thumb
+
+.global  g_pfnVectors
+.global  Default_Handler
+
+/* start address for the initialization values of the .data section.
+defined in linker script */
+.word  _sidata
+/* start address for the .data section. defined in linker script */
+.word  _sdata
+/* end address for the .data section. defined in linker script */
+.word  _edata
+/* start address for the .bss section. defined in linker script */
+.word  _sbss
+/* end address for the .bss section. defined in linker script */
+.word  _ebss
+/* stack used for SystemInit_ExtMemCtl; always internal RAM used */
+
+/**
+ * @brief  This is the code that gets called when the processor first
+ *          starts execution following a reset event. Only the absolutely
+ *          necessary set is performed, after which the application
+ *          supplied main() routine is called.
+ * @param  None
+ * @retval : None
+*/
+
+    .section  .text.Reset_Handler
+  .weak  Reset_Handler
+  .type  Reset_Handler, %function
+Reset_Handler:
+
+/* Copy the data segment initializers from flash to SRAM */
+  movs  r1, #0
+  b  LoopCopyDataInit
+
+CopyDataInit:
+  ldr  r3, =_sidata
+  ldr  r3, [r3, r1]
+  str  r3, [r0, r1]
+  adds  r1, r1, #4
+
+LoopCopyDataInit:
+  ldr  r0, =_sdata
+  ldr  r3, =_edata
+  adds  r2, r0, r1
+  cmp  r2, r3
+  bcc  CopyDataInit
+  ldr  r2, =_sbss
+  b  LoopFillZerobss
+/* Zero fill the bss segment. */
+FillZerobss:
+  movs  r3, #0
+  str  r3, [r2], #4
+
+LoopFillZerobss:
+  ldr  r3, = _ebss
+  cmp  r2, r3
+  bcc  FillZerobss
+
+/* Call the clock system intitialization function.*/
+  bl  SystemInit
+/* Call static constructors */
+    bl __libc_init_array
+/* Call the application's entry point.*/
+  bl  main
+  bx  lr
+.size  Reset_Handler, .-Reset_Handler
+
+/**
+ * @brief  This is the code that gets called when the processor receives an
+ *         unexpected interrupt.  This simply enters an infinite loop, preserving
+ *         the system state for examination by a debugger.
+ * @param  None
+ * @retval None
+*/
+    .section  .text.Default_Handler,"ax",%progbits
+Default_Handler:
+Infinite_Loop:
+  b  Infinite_Loop
+  .size  Default_Handler, .-Default_Handler
+/******************************************************************************
+*
+* The minimal vector table for a Cortex M3. Note that the proper constructs
+* must be placed on this to ensure that it ends up at physical address
+* 0x0000.0000.
+*
+*******************************************************************************/
+   .section  .isr_vector,"a",%progbits
+  .type  g_pfnVectors, %object
+  .size  g_pfnVectors, .-g_pfnVectors
+
+
+g_pfnVectors:
+  .word  _estack
+  .word  Reset_Handler
+  .word  NMI_Handler
+  .word  HardFault_Handler
+  .word  MemManage_Handler
+  .word  BusFault_Handler
+  .word  UsageFault_Handler
+  .word  0
+  .word  0
+  .word  0
+  .word  0
+  .word  SVC_Handler
+  .word  DebugMon_Handler
+  .word  0
+  .word  PendSV_Handler
+  .word  SysTick_Handler
+
+  /* External Interrupts */
+  .word     WWDG_IRQHandler                   /* Window WatchDog              */
+  .word     PVD_IRQHandler                    /* PVD through EXTI Line detection */
+  .word     TAMP_STAMP_IRQHandler             /* Tamper and TimeStamps through the EXTI line */
+  .word     RTC_WKUP_IRQHandler               /* RTC Wakeup through the EXTI line */
+  .word     FLASH_IRQHandler                  /* FLASH                        */
+  .word     RCC_IRQHandler                    /* RCC                          */
+  .word     EXTI0_IRQHandler                  /* EXTI Line0                   */
+  .word     EXTI1_IRQHandler                  /* EXTI Line1                   */
+  .word     EXTI2_IRQHandler                  /* EXTI Line2                   */
+  .word     EXTI3_IRQHandler                  /* EXTI Line3                   */
+  .word     EXTI4_IRQHandler                  /* EXTI Line4                   */
+  .word     DMA1_Stream0_IRQHandler           /* DMA1 Stream 0                */
+  .word     DMA1_Stream1_IRQHandler           /* DMA1 Stream 1                */
+  .word     DMA1_Stream2_IRQHandler           /* DMA1 Stream 2                */
+  .word     DMA1_Stream3_IRQHandler           /* DMA1 Stream 3                */
+  .word     DMA1_Stream4_IRQHandler           /* DMA1 Stream 4                */
+  .word     DMA1_Stream5_IRQHandler           /* DMA1 Stream 5                */
+  .word     DMA1_Stream6_IRQHandler           /* DMA1 Stream 6                */
+  .word     ADC_IRQHandler                    /* ADC1, ADC2 and ADC3s         */
+  .word     CAN1_TX_IRQHandler                /* CAN1 TX                      */
+  .word     CAN1_RX0_IRQHandler               /* CAN1 RX0                     */
+  .word     CAN1_RX1_IRQHandler               /* CAN1 RX1                     */
+  .word     CAN1_SCE_IRQHandler               /* CAN1 SCE                     */
+  .word     EXTI9_5_IRQHandler                /* External Line[9:5]s          */
+  .word     TIM1_BRK_TIM9_IRQHandler          /* TIM1 Break and TIM9          */
+  .word     TIM1_UP_TIM10_IRQHandler          /* TIM1 Update and TIM10        */
+  .word     TIM1_TRG_COM_TIM11_IRQHandler     /* TIM1 Trigger and Commutation and TIM11 */
+  .word     TIM1_CC_IRQHandler                /* TIM1 Capture Compare         */
+  .word     TIM2_IRQHandler                   /* TIM2                         */
+  .word     TIM3_IRQHandler                   /* TIM3                         */
+  .word     TIM4_IRQHandler                   /* TIM4                         */
+  .word     I2C1_EV_IRQHandler                /* I2C1 Event                   */
+  .word     I2C1_ER_IRQHandler                /* I2C1 Error                   */
+  .word     I2C2_EV_IRQHandler                /* I2C2 Event                   */
+  .word     I2C2_ER_IRQHandler                /* I2C2 Error                   */
+  .word     SPI1_IRQHandler                   /* SPI1                         */
+  .word     SPI2_IRQHandler                   /* SPI2                         */
+  .word     USART1_IRQHandler                 /* USART1                       */
+  .word     USART2_IRQHandler                 /* USART2                       */
+  .word     USART3_IRQHandler                 /* USART3                       */
+  .word     EXTI15_10_IRQHandler              /* External Line[15:10]s        */
+  .word     RTC_Alarm_IRQHandler              /* RTC Alarm (A and B) through EXTI Line */
+  .word     OTG_FS_WKUP_IRQHandler            /* USB OTG FS Wakeup through EXTI line */
+  .word     TIM8_BRK_TIM12_IRQHandler         /* TIM8 Break and TIM12         */
+  .word     TIM8_UP_TIM13_IRQHandler          /* TIM8 Update and TIM13        */
+  .word     TIM8_TRG_COM_TIM14_IRQHandler     /* TIM8 Trigger and Commutation and TIM14 */
+  .word     TIM8_CC_IRQHandler                /* TIM8 Capture Compare         */
+  .word     DMA1_Stream7_IRQHandler           /* DMA1 Stream7                 */
+  .word     FSMC_IRQHandler                   /* FSMC                         */
+  .word     SDIO_IRQHandler                   /* SDIO                         */
+  .word     TIM5_IRQHandler                   /* TIM5                         */
+  .word     SPI3_IRQHandler                   /* SPI3                         */
+  .word     UART4_IRQHandler                  /* UART4                        */
+  .word     UART5_IRQHandler                  /* UART5                        */
+  .word     TIM6_DAC_IRQHandler               /* TIM6 and DAC1&2 underrun errors */
+  .word     TIM7_IRQHandler                   /* TIM7                         */
+  .word     DMA2_Stream0_IRQHandler           /* DMA2 Stream 0                */
+  .word     DMA2_Stream1_IRQHandler           /* DMA2 Stream 1                */
+  .word     DMA2_Stream2_IRQHandler           /* DMA2 Stream 2                */
+  .word     DMA2_Stream3_IRQHandler           /* DMA2 Stream 3                */
+  .word     DMA2_Stream4_IRQHandler           /* DMA2 Stream 4                */
+  .word     ETH_IRQHandler                    /* Ethernet                     */
+  .word     ETH_WKUP_IRQHandler               /* Ethernet Wakeup through EXTI line */
+  .word     CAN2_TX_IRQHandler                /* CAN2 TX                      */
+  .word     CAN2_RX0_IRQHandler               /* CAN2 RX0                     */
+  .word     CAN2_RX1_IRQHandler               /* CAN2 RX1                     */
+  .word     CAN2_SCE_IRQHandler               /* CAN2 SCE                     */
+  .word     OTG_FS_IRQHandler                 /* USB OTG FS                   */
+  .word     DMA2_Stream5_IRQHandler           /* DMA2 Stream 5                */
+  .word     DMA2_Stream6_IRQHandler           /* DMA2 Stream 6                */
+  .word     DMA2_Stream7_IRQHandler           /* DMA2 Stream 7                */
+  .word     USART6_IRQHandler                 /* USART6                       */
+  .word     I2C3_EV_IRQHandler                /* I2C3 event                   */
+  .word     I2C3_ER_IRQHandler                /* I2C3 error                   */
+  .word     OTG_HS_EP1_OUT_IRQHandler         /* USB OTG HS End Point 1 Out   */
+  .word     OTG_HS_EP1_IN_IRQHandler          /* USB OTG HS End Point 1 In    */
+  .word     OTG_HS_WKUP_IRQHandler            /* USB OTG HS Wakeup through EXTI */
+  .word     OTG_HS_IRQHandler                 /* USB OTG HS                   */
+  .word     DCMI_IRQHandler                   /* DCMI                         */
+  .word     CRYP_IRQHandler                   /* CRYP crypto                  */
+  .word     HASH_RNG_IRQHandler               /* Hash and Rng                 */
+  .word     FPU_IRQHandler                    /* FPU                          */
+
+
+/*******************************************************************************
+*
+* Provide weak aliases for each Exception handler to the Default_Handler.
+* As they are weak aliases, any function with the same name will override
+* this definition.
+*
+*******************************************************************************/
+   .weak      NMI_Handler
+   .thumb_set NMI_Handler,Default_Handler
+
+   .weak      HardFault_Handler
+   .thumb_set HardFault_Handler,Default_Handler
+
+   .weak      MemManage_Handler
+   .thumb_set MemManage_Handler,Default_Handler
+
+   .weak      BusFault_Handler
+   .thumb_set BusFault_Handler,Default_Handler
+
+   .weak      UsageFault_Handler
+   .thumb_set UsageFault_Handler,Default_Handler
+
+   .weak      SVC_Handler
+   .thumb_set SVC_Handler,Default_Handler
+
+   .weak      DebugMon_Handler
+   .thumb_set DebugMon_Handler,Default_Handler
+
+   .weak      PendSV_Handler
+   .thumb_set PendSV_Handler,Default_Handler
+
+   .weak      SysTick_Handler
+   .thumb_set SysTick_Handler,Default_Handler
+
+   .weak      WWDG_IRQHandler
+   .thumb_set WWDG_IRQHandler,Default_Handler
+
+   .weak      PVD_IRQHandler
+   .thumb_set PVD_IRQHandler,Default_Handler
+
+   .weak      TAMP_STAMP_IRQHandler
+   .thumb_set TAMP_STAMP_IRQHandler,Default_Handler
+
+   .weak      RTC_WKUP_IRQHandler
+   .thumb_set RTC_WKUP_IRQHandler,Default_Handler
+
+   .weak      FLASH_IRQHandler
+   .thumb_set FLASH_IRQHandler,Default_Handler
+
+   .weak      RCC_IRQHandler
+   .thumb_set RCC_IRQHandler,Default_Handler
+
+   .weak      EXTI0_IRQHandler
+   .thumb_set EXTI0_IRQHandler,Default_Handler
+
+   .weak      EXTI1_IRQHandler
+   .thumb_set EXTI1_IRQHandler,Default_Handler
+
+   .weak      EXTI2_IRQHandler
+   .thumb_set EXTI2_IRQHandler,Default_Handler
+
+   .weak      EXTI3_IRQHandler
+   .thumb_set EXTI3_IRQHandler,Default_Handler
+
+   .weak      EXTI4_IRQHandler
+   .thumb_set EXTI4_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream0_IRQHandler
+   .thumb_set DMA1_Stream0_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream1_IRQHandler
+   .thumb_set DMA1_Stream1_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream2_IRQHandler
+   .thumb_set DMA1_Stream2_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream3_IRQHandler
+   .thumb_set DMA1_Stream3_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream4_IRQHandler
+   .thumb_set DMA1_Stream4_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream5_IRQHandler
+   .thumb_set DMA1_Stream5_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream6_IRQHandler
+   .thumb_set DMA1_Stream6_IRQHandler,Default_Handler
+
+   .weak      ADC_IRQHandler
+   .thumb_set ADC_IRQHandler,Default_Handler
+
+   .weak      CAN1_TX_IRQHandler
+   .thumb_set CAN1_TX_IRQHandler,Default_Handler
+
+   .weak      CAN1_RX0_IRQHandler
+   .thumb_set CAN1_RX0_IRQHandler,Default_Handler
+
+   .weak      CAN1_RX1_IRQHandler
+   .thumb_set CAN1_RX1_IRQHandler,Default_Handler
+
+   .weak      CAN1_SCE_IRQHandler
+   .thumb_set CAN1_SCE_IRQHandler,Default_Handler
+
+   .weak      EXTI9_5_IRQHandler
+   .thumb_set EXTI9_5_IRQHandler,Default_Handler
+
+   .weak      TIM1_BRK_TIM9_IRQHandler
+   .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler
+
+   .weak      TIM1_UP_TIM10_IRQHandler
+   .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler
+
+   .weak      TIM1_TRG_COM_TIM11_IRQHandler
+   .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler
+
+   .weak      TIM1_CC_IRQHandler
+   .thumb_set TIM1_CC_IRQHandler,Default_Handler
+
+   .weak      TIM2_IRQHandler
+   .thumb_set TIM2_IRQHandler,Default_Handler
+
+   .weak      TIM3_IRQHandler
+   .thumb_set TIM3_IRQHandler,Default_Handler
+
+   .weak      TIM4_IRQHandler
+   .thumb_set TIM4_IRQHandler,Default_Handler
+
+   .weak      I2C1_EV_IRQHandler
+   .thumb_set I2C1_EV_IRQHandler,Default_Handler
+
+   .weak      I2C1_ER_IRQHandler
+   .thumb_set I2C1_ER_IRQHandler,Default_Handler
+
+   .weak      I2C2_EV_IRQHandler
+   .thumb_set I2C2_EV_IRQHandler,Default_Handler
+
+   .weak      I2C2_ER_IRQHandler
+   .thumb_set I2C2_ER_IRQHandler,Default_Handler
+
+   .weak      SPI1_IRQHandler
+   .thumb_set SPI1_IRQHandler,Default_Handler
+
+   .weak      SPI2_IRQHandler
+   .thumb_set SPI2_IRQHandler,Default_Handler
+
+   .weak      USART1_IRQHandler
+   .thumb_set USART1_IRQHandler,Default_Handler
+
+   .weak      USART2_IRQHandler
+   .thumb_set USART2_IRQHandler,Default_Handler
+
+   .weak      USART3_IRQHandler
+   .thumb_set USART3_IRQHandler,Default_Handler
+
+   .weak      EXTI15_10_IRQHandler
+   .thumb_set EXTI15_10_IRQHandler,Default_Handler
+
+   .weak      RTC_Alarm_IRQHandler
+   .thumb_set RTC_Alarm_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_WKUP_IRQHandler
+   .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler
+
+   .weak      TIM8_BRK_TIM12_IRQHandler
+   .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler
+
+   .weak      TIM8_UP_TIM13_IRQHandler
+   .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler
+
+   .weak      TIM8_TRG_COM_TIM14_IRQHandler
+   .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler
+
+   .weak      TIM8_CC_IRQHandler
+   .thumb_set TIM8_CC_IRQHandler,Default_Handler
+
+   .weak      DMA1_Stream7_IRQHandler
+   .thumb_set DMA1_Stream7_IRQHandler,Default_Handler
+
+   .weak      FSMC_IRQHandler
+   .thumb_set FSMC_IRQHandler,Default_Handler
+
+   .weak      SDIO_IRQHandler
+   .thumb_set SDIO_IRQHandler,Default_Handler
+
+   .weak      TIM5_IRQHandler
+   .thumb_set TIM5_IRQHandler,Default_Handler
+
+   .weak      SPI3_IRQHandler
+   .thumb_set SPI3_IRQHandler,Default_Handler
+
+   .weak      UART4_IRQHandler
+   .thumb_set UART4_IRQHandler,Default_Handler
+
+   .weak      UART5_IRQHandler
+   .thumb_set UART5_IRQHandler,Default_Handler
+
+   .weak      TIM6_DAC_IRQHandler
+   .thumb_set TIM6_DAC_IRQHandler,Default_Handler
+
+   .weak      TIM7_IRQHandler
+   .thumb_set TIM7_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream0_IRQHandler
+   .thumb_set DMA2_Stream0_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream1_IRQHandler
+   .thumb_set DMA2_Stream1_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream2_IRQHandler
+   .thumb_set DMA2_Stream2_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream3_IRQHandler
+   .thumb_set DMA2_Stream3_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream4_IRQHandler
+   .thumb_set DMA2_Stream4_IRQHandler,Default_Handler
+
+   .weak      ETH_IRQHandler
+   .thumb_set ETH_IRQHandler,Default_Handler
+
+   .weak      ETH_WKUP_IRQHandler
+   .thumb_set ETH_WKUP_IRQHandler,Default_Handler
+
+   .weak      CAN2_TX_IRQHandler
+   .thumb_set CAN2_TX_IRQHandler,Default_Handler
+
+   .weak      CAN2_RX0_IRQHandler
+   .thumb_set CAN2_RX0_IRQHandler,Default_Handler
+
+   .weak      CAN2_RX1_IRQHandler
+   .thumb_set CAN2_RX1_IRQHandler,Default_Handler
+
+   .weak      CAN2_SCE_IRQHandler
+   .thumb_set CAN2_SCE_IRQHandler,Default_Handler
+
+   .weak      OTG_FS_IRQHandler
+   .thumb_set OTG_FS_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream5_IRQHandler
+   .thumb_set DMA2_Stream5_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream6_IRQHandler
+   .thumb_set DMA2_Stream6_IRQHandler,Default_Handler
+
+   .weak      DMA2_Stream7_IRQHandler
+   .thumb_set DMA2_Stream7_IRQHandler,Default_Handler
+
+   .weak      USART6_IRQHandler
+   .thumb_set USART6_IRQHandler,Default_Handler
+
+   .weak      I2C3_EV_IRQHandler
+   .thumb_set I2C3_EV_IRQHandler,Default_Handler
+
+   .weak      I2C3_ER_IRQHandler
+   .thumb_set I2C3_ER_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_EP1_OUT_IRQHandler
+   .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_EP1_IN_IRQHandler
+   .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_WKUP_IRQHandler
+   .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler
+
+   .weak      OTG_HS_IRQHandler
+   .thumb_set OTG_HS_IRQHandler,Default_Handler
+
+   .weak      DCMI_IRQHandler
+   .thumb_set DCMI_IRQHandler,Default_Handler
+
+   .weak      CRYP_IRQHandler
+   .thumb_set CRYP_IRQHandler,Default_Handler
+
+   .weak      HASH_RNG_IRQHandler
+   .thumb_set HASH_RNG_IRQHandler,Default_Handler
+
+   .weak      FPU_IRQHandler
+   .thumb_set FPU_IRQHandler,Default_Handler
+
+/*******************   (C)   COPYRIGHT   2011   STMicroelectronics   *****END   OF   FILE****/
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_adc.c b/codec2/branches/0.7/stm32/src/stm32f4_adc.c
new file mode 100644 (file)
index 0000000..d1da87b
--- /dev/null
@@ -0,0 +1,281 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_adc.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 4 June 2013
+
+  Two channel ADC driver module for STM32F4.  Pin PA1 connects to ADC1, pin
+  PA2 connects to ADC2.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stm32f4xx_adc.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_rcc.h"
+
+#include "codec2_fifo.h"
+#include "stm32f4_adc.h"
+#include "debugblinky.h"
+
+struct FIFO *adc1_fifo;
+struct FIFO *adc2_fifo;
+unsigned short adc_buf[ADC_BUF_SZ];
+int adc_overflow1, adc_overflow2;
+int half,full;
+
+#define ADCx_DR_ADDRESS          ((uint32_t)0x4001204C)
+#define DMA_CHANNELx             DMA_Channel_0
+#define DMA_STREAMx              DMA2_Stream0
+#define ADCx                     ADC1
+
+void adc_configure();
+
+static void tim2_config(int fs_divisor);
+
+void adc_open(int fs_divisor, int fifo_sz) {
+    adc1_fifo = fifo_create(fifo_sz);
+    assert(adc1_fifo != NULL);
+    adc2_fifo = fifo_create(fifo_sz);
+    assert(adc2_fifo != NULL);
+
+    tim2_config(fs_divisor);
+    adc_configure();
+    init_debug_blinky();
+}
+
+/* n signed 16 bit samples in buf[] if return != -1 */
+
+int adc1_read(short buf[], int n) {
+    return fifo_read(adc1_fifo, buf, n);
+}
+
+/* n signed 16 bit samples in buf[] if return != -1 */
+
+int adc2_read(short buf[], int n) {
+    return fifo_read(adc2_fifo, buf, n);
+}
+
+/* Returns number of signed 16 bit samples in the FIFO currently */
+int adc1_samps(){
+       return fifo_used(adc1_fifo);
+}
+
+/* Returns number of signed 16 bit samples in the FIFO currently */
+int adc2_samps(){
+       return fifo_used(adc2_fifo);
+}
+
+static void tim2_config(int fs_divisor)
+{
+  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
+
+  /* TIM2 Periph clock enable */
+  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
+
+  /* --------------------------------------------------------
+
+  TIM2 input clock (TIM2CLK) is set to 2 * APB1 clock (PCLK1), since
+  APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig
+  13 clock tree figure in DM0031020.pdf).
+
+     Sample rate Fs = 2*PCLK1/TIM_ClockDivision
+                    = (HCLK/2)/TIM_ClockDivision
+
+  ----------------------------------------------------------- */
+
+  /* Time base configuration */
+
+  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
+  TIM_TimeBaseStructure.TIM_Period = fs_divisor - 1;
+  TIM_TimeBaseStructure.TIM_Prescaler = 0;
+  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
+
+  /* TIM2 TRGO selection */
+
+  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
+
+  /* TIM2 enable counter */
+
+  TIM_Cmd(TIM2, ENABLE);
+}
+
+
+void adc_configure(){
+    ADC_InitTypeDef  ADC_init_structure;
+    GPIO_InitTypeDef GPIO_initStructre;
+    DMA_InitTypeDef  DMA_InitStructure;
+    NVIC_InitTypeDef NVIC_InitStructure;
+
+    // Clock configuration
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
+    RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOAEN,ENABLE);
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
+
+    // Analog pin configuration ADC1->PA1, ADC2->PA2
+
+    GPIO_initStructre.GPIO_Pin =  GPIO_Pin_1 | GPIO_Pin_2;
+    GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN;
+    GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL;
+    GPIO_Init(GPIOA,&GPIO_initStructre);
+
+    // ADC structure configuration
+
+    ADC_DeInit();
+    ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Left;
+    ADC_init_structure.ADC_Resolution = ADC_Resolution_12b;
+    ADC_init_structure.ADC_ContinuousConvMode = DISABLE;
+    ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
+    ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
+    ADC_init_structure.ADC_NbrOfConversion = 2;
+    ADC_init_structure.ADC_ScanConvMode = ENABLE;
+    ADC_Init(ADCx,&ADC_init_structure);
+
+    // Select the channel to be read from
+
+    ADC_RegularChannelConfig(ADCx,ADC_Channel_1,1,ADC_SampleTime_144Cycles);
+    ADC_RegularChannelConfig(ADCx,ADC_Channel_2,2,ADC_SampleTime_144Cycles);
+    //ADC_VBATCmd(ENABLE);
+
+    /* DMA  configuration **************************************/
+
+    DMA_DeInit(DMA_STREAMx);
+    DMA_InitStructure.DMA_Channel = DMA_CHANNELx;
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADCx_DR_ADDRESS;
+    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)adc_buf;
+    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
+    DMA_InitStructure.DMA_BufferSize = ADC_BUF_SZ;
+    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+    DMA_Init(DMA_STREAMx, &DMA_InitStructure);
+
+    /* Enable DMA request after last transfer (Single-ADC mode) */
+
+    ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE);
+
+    /* Enable ADC1 DMA */
+
+    ADC_DMACmd(ADCx, ENABLE);
+
+    /* DMA2_Stream0 enable */
+
+    DMA_Cmd(DMA_STREAMx, ENABLE);
+
+    /* Enable DMA Half & Complete interrupts */
+
+    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);
+
+    /* Enable the DMA Stream IRQ Channel */
+
+    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+
+    // Enable and start ADC conversion
+
+    ADC_Cmd(ADC1,ENABLE);
+    ADC_SoftwareStartConv(ADC1);
+}
+
+/*
+  This function handles DMA Stream interrupt request.
+*/
+
+void DMA2_Stream0_IRQHandler(void) {
+    int i, j, sam;
+    short signed_buf1[ADC_BUF_SZ/2];
+    short signed_buf2[ADC_BUF_SZ/2];
+
+    GPIOE->ODR |= (1 << 0);
+
+    /* Half transfer interrupt */
+
+    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0) != RESET) {
+        half++;
+
+        /* convert to signed */
+
+        for(i=0, j=0; i<ADC_BUF_SZ/2; i+=2,j++) {
+            sam = (int)adc_buf[i] - 32768;
+            signed_buf1[j] = sam;
+            sam = (int)adc_buf[i+1] - 32768;
+            signed_buf2[j] = sam;
+        }
+        /* write first half to fifo */
+
+        if (fifo_write(adc1_fifo, signed_buf1, ADC_BUF_SZ/4) == -1) {
+            adc_overflow1++;
+        }
+        if (fifo_write(adc2_fifo, signed_buf2, ADC_BUF_SZ/4) == -1) {
+            adc_overflow2++;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0);
+    }
+
+    /* Transfer complete interrupt */
+
+    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET) {
+        full++;
+
+        /* convert to signed */
+
+        for(i=0, j=0; i<ADC_BUF_SZ/2; i+=2,j++) {
+            sam = (int)adc_buf[ADC_BUF_SZ/2 + i] - 32768;
+            signed_buf1[j] = sam;
+            sam = (int)adc_buf[ADC_BUF_SZ/2 + i+1] - 32768;
+            signed_buf2[j] = sam;
+        }
+
+        /* write second half to fifo */
+
+        if (fifo_write(adc1_fifo, signed_buf1, ADC_BUF_SZ/4) == -1) {
+            adc_overflow1++;
+        }
+        if (fifo_write(adc2_fifo, signed_buf2, ADC_BUF_SZ/4) == -1) {
+            adc_overflow2++;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
+    }
+
+    GPIOE->ODR &= ~(1 << 0);
+}
+
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_adc_tuner.c b/codec2/branches/0.7/stm32/src/stm32f4_adc_tuner.c
new file mode 100644 (file)
index 0000000..f3de154
--- /dev/null
@@ -0,0 +1,289 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_adc_tuner.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 19 Feb 2015
+
+  Single channel ADC driver module for STM32F4 that samples pin PA1 at
+  2 MHz and down converts to 50 kHz, with "tuning" centred at 500 kHz.
+
+  See codec2-dev/octave.m for a simulation model.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stm32f4xx_adc.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_rcc.h"
+
+#include "codec2_fifo.h"
+#include "stm32f4_adc_tuner.h"
+#include "debugblinky.h"
+#include "iir_tuner.h"
+
+struct FIFO *adc1_fifo;
+unsigned short adc_buf[ADC_TUNER_BUF_SZ], *padc_buf;
+int adc_overflow1;
+int half,full;
+static short tuner_en = 1;
+
+#define ADCx_DR_ADDRESS          ((uint32_t)0x4001204C)
+#define DMA_CHANNELx             DMA_Channel_0
+#define DMA_STREAMx              DMA2_Stream0
+#define ADCx                     ADC1
+
+void adc_configure();
+
+static void tim2_config(void);
+
+//#define DUMMY_SIGNAL
+#ifdef DUMMY_SIGNAL
+unsigned short sine[ADC_TUNER_BUF_SZ];
+#endif
+
+void adc_open(int fifo_sz) {
+    adc1_fifo = fifo_create(fifo_sz);
+    assert(adc1_fifo != NULL);
+
+    tim2_config();
+    adc_configure();
+    init_debug_blinky();
+}
+
+
+/* n signed 16 bit samples in buf[] if return != -1 */
+
+int adc1_read(short buf[], int n) {
+    return fifo_read(adc1_fifo, buf, n);
+}
+
+
+void adc_set_tuner_en(short flag)
+{
+    tuner_en = flag;
+}
+
+static void tim2_config(void)
+{
+  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
+
+  /* TIM2 Periph clock enable */
+  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
+
+  /* --------------------------------------------------------
+
+  TIM2 input clock (TIM2CLK) is set to 2 * APB1 clock (PCLK1), since
+  APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig
+  13 clock tree figure in DM0031020.pdf).
+
+     Sample rate Fs = 2*PCLK1/)TIM_ClockDivision+1)
+                    = (HCLK/2)/(TIM_ClockDivision+1)
+
+  Note from David: The +1 was discovered empirically, still not sure
+  if it's right.
+
+  ----------------------------------------------------------- */
+
+  /* Time base configuration */
+
+  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
+  TIM_TimeBaseStructure.TIM_Period = 41;
+  TIM_TimeBaseStructure.TIM_Prescaler = 0;
+  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
+
+  /* TIM2 TRGO selection */
+
+  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);
+
+  /* TIM2 enable counter */
+
+  TIM_Cmd(TIM2, ENABLE);
+}
+
+
+void adc_configure() {
+    ADC_InitTypeDef  ADC_init_structure;
+    GPIO_InitTypeDef GPIO_initStructre;
+    DMA_InitTypeDef  DMA_InitStructure;
+    NVIC_InitTypeDef NVIC_InitStructure;
+
+    // Clock configuration
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
+    RCC_AHB1PeriphClockCmd(RCC_AHB1ENR_GPIOAEN,ENABLE);
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
+
+    // Analog pin configuration ADC1->PA1
+
+    GPIO_initStructre.GPIO_Pin =  GPIO_Pin_1;
+    GPIO_initStructre.GPIO_Mode = GPIO_Mode_AN;
+    GPIO_initStructre.GPIO_PuPd = GPIO_PuPd_NOPULL;
+    GPIO_Init(GPIOA,&GPIO_initStructre);
+
+    // ADC structure configuration
+
+    ADC_DeInit();
+    ADC_init_structure.ADC_DataAlign = ADC_DataAlign_Left;
+    ADC_init_structure.ADC_Resolution = ADC_Resolution_12b;
+    ADC_init_structure.ADC_ContinuousConvMode = DISABLE;
+    ADC_init_structure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
+    ADC_init_structure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
+    ADC_init_structure.ADC_NbrOfConversion = 1;
+    ADC_Init(ADCx,&ADC_init_structure);
+
+    // Select the channel to be read from
+
+    ADC_RegularChannelConfig(ADCx,ADC_Channel_1,1,ADC_SampleTime_3Cycles);
+
+    /* DMA  configuration **************************************/
+
+    DMA_DeInit(DMA_STREAMx);
+    DMA_InitStructure.DMA_Channel = DMA_CHANNELx;
+    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADCx_DR_ADDRESS;
+    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)adc_buf;
+    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
+    DMA_InitStructure.DMA_BufferSize = ADC_TUNER_BUF_SZ;
+    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+    DMA_Init(DMA_STREAMx, &DMA_InitStructure);
+
+    /* Enable DMA request after last transfer (Single-ADC mode) */
+
+    ADC_DMARequestAfterLastTransferCmd(ADCx, ENABLE);
+
+    /* Enable ADC1 DMA */
+
+    ADC_DMACmd(ADCx, ENABLE);
+
+    /* DMA2_Stream0 enable */
+
+    DMA_Cmd(DMA_STREAMx, ENABLE);
+
+    /* Enable DMA Half & Complete interrupts */
+
+    DMA_ITConfig(DMA2_Stream0, DMA_IT_TC | DMA_IT_HT, ENABLE);
+
+    /* Enable the DMA Stream IRQ Channel */
+
+    NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+
+    // Enable and start ADC conversion
+
+    ADC_Cmd(ADC1,ENABLE);
+    ADC_SoftwareStartConv(ADC1);
+
+    padc_buf = adc_buf;
+
+    #ifdef DUMMY_SIGNAL
+    int i;
+
+    /* Fs/4 sine wave, right in the middle of the pass band ! */
+
+    for(i=0; i<ADC_TUNER_BUF_SZ; i++)
+        sine[i] = 32767;
+    for(i=1; i<ADC_TUNER_BUF_SZ; i+=4)
+        sine[i] += 32767/4;
+    for(i=3; i<ADC_TUNER_BUF_SZ; i+=4)
+        sine[i] -= 32767/4;
+    padc_buf = sine;
+    #endif
+
+}
+
+
+/*
+  This function handles DMA Stream interrupt request.
+
+  ADC_TUNER_BUF_SZ = 45 * 160 = 7200, so one interrupt every 7200/2 = 3600 samples
+  or interrupts at a rate of 2E6/3600 = 555.56 Hz.
+*/
+
+void DMA2_Stream0_IRQHandler(void) {
+    float dec_buf[ADC_TUNER_N/2];
+
+    /* PE0 is asserted high for the duration of this ISR */
+
+    GPIOE->ODR |= (1 << 0);
+
+    /* Half transfer interrupt */
+
+    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_HTIF0) != RESET) {
+        half++;
+
+        if (tuner_en) {
+            iir_tuner(dec_buf, padc_buf);
+
+            /* write first half to fifo.  Note we are writing ADC_TUNER_N/2 floats,
+               which is equivalent to ADC_TUNER_N shorts.  */
+
+           if (fifo_write(adc1_fifo, (short*)dec_buf, ADC_TUNER_N) == -1) {
+                adc_overflow1++;
+            }
+        }
+        else // note: we dump signed shorts when tuner off
+            fifo_write(adc1_fifo, (short*)padc_buf, ADC_TUNER_BUF_SZ/2); 
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_HTIF0);
+    }
+
+    /* Transfer complete interrupt */
+
+    if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) != RESET) {
+        full++;
+
+        if (tuner_en) {
+            iir_tuner(dec_buf, &padc_buf[ADC_TUNER_BUF_SZ/2]);
+
+            /* write second half to fifo */
+
+            if (fifo_write(adc1_fifo, (short*)dec_buf, ADC_TUNER_N) == -1) {
+              adc_overflow1++;
+            }
+        }
+        else
+            fifo_write(adc1_fifo, (short*)&padc_buf[ADC_TUNER_BUF_SZ/2], ADC_TUNER_BUF_SZ/2);
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
+    }
+
+    GPIOE->ODR &= ~(1 << 0);
+}
+
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_dac.c b/codec2/branches/0.7/stm32/src/stm32f4_dac.c
new file mode 100644 (file)
index 0000000..2a8d8e6
--- /dev/null
@@ -0,0 +1,406 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_dac.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 June 2013
+
+  DAC driver module for STM32F4. DAC1 is connected to pin PA4, DAC2
+  is connected to pin PA5.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "stm32f4xx.h"
+#include "codec2_fifo.h"
+#include "stm32f4_dac.h"
+#include "debugblinky.h"
+
+/* write to these registers for 12 bit left aligned data, as per data sheet
+   make sure 4 least sig bits set to 0 */
+
+#define DAC_DHR12R1_ADDRESS    0x40007408
+#define DAC_DHR12R2_ADDRESS    0x40007414
+
+#define DAC_MAX      4096            /* maximum amplitude */
+
+/* y=mx+c mapping of samples16 bit shorts to DAC samples.  Table: 74
+   of data sheet indicates With DAC buffer on, DAC range is limited to
+   0x0E0 to 0xF1C at VREF+ = 3.6 V, we have Vref=3.3V which is close.
+ */
+
+#define M ((3868.0-224.0)/65536.0)
+#define C 2047.0
+
+static struct FIFO *dac1_fifo;
+static struct FIFO *dac2_fifo;
+
+static unsigned short dac1_buf[DAC_BUF_SZ];
+static unsigned short dac2_buf[DAC_BUF_SZ];
+
+static void tim6_config(int fs_divisor);
+static void dac1_config(void);
+static void dac2_config(void);
+
+int dac_underflow;
+
+
+void dac_open(int fs_divisor, int fifo_size) {
+
+    memset(dac1_buf, 32768, sizeof(short)*DAC_BUF_SZ);
+    memset(dac2_buf, 32768, sizeof(short)*DAC_BUF_SZ);
+
+    /* Create fifos */
+
+    dac1_fifo = fifo_create(fifo_size);
+    dac2_fifo = fifo_create(fifo_size);
+    assert(dac1_fifo != NULL);
+    assert(dac2_fifo != NULL);
+
+    /* Turn on the clocks we need -----------------------------------------------*/
+
+    /* DMA1 clock enable */
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
+    /* GPIOA clock enable (to be used with DAC) */
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
+    /* DAC Periph clock enable */
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
+
+    /* GPIO Pin configuration DAC1->PA.4, DAC2->PA.5 configuration --------------*/
+
+    GPIO_InitTypeDef GPIO_InitStructure;
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
+    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+    GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+    /* Timer and DAC 1 & 2 Configuration ----------------------------------------*/
+
+    tim6_config(fs_divisor);
+    dac1_config();
+    dac2_config();
+
+    init_debug_blinky();
+}
+
+/* Call these puppies to send samples to the DACs.  For your
+   convenience they accept signed 16 bit samples. */
+
+int dac1_write(short buf[], int n) {
+    return fifo_write(dac1_fifo, buf, n);
+}
+
+int dac2_write(short buf[], int n) {
+    return fifo_write(dac2_fifo, buf, n);
+}
+
+int dac1_free() {
+    return fifo_free(dac1_fifo);
+}
+
+int dac2_free() {
+    return fifo_free(dac2_fifo);
+}
+
+static void tim6_config(int fs_divisor)
+{
+  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
+
+  /* TIM6 Periph clock enable */
+  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
+
+  /* --------------------------------------------------------
+
+  TIM6 input clock (TIM6CLK) is set to 2 * APB1 clock (PCLK1), since
+  APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig
+  13 clock tree figure in DM0031020.pdf).
+
+     Sample rate Fs = 2*PCLK1/TIM_ClockDivision
+                    = (HCLK/2)/TIM_ClockDivision
+
+  ----------------------------------------------------------- */
+
+  /* Time base configuration */
+
+  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
+  TIM_TimeBaseStructure.TIM_Period = fs_divisor - 1;
+  TIM_TimeBaseStructure.TIM_Prescaler = 0;
+  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
+
+  /* TIM6 TRGO selection */
+
+  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
+
+  /* TIM6 enable counter */
+
+  TIM_Cmd(TIM6, ENABLE);
+}
+
+static void dac1_config(void)
+{
+  DAC_InitTypeDef  DAC_InitStructure;
+  DMA_InitTypeDef  DMA_InitStructure;
+  NVIC_InitTypeDef NVIC_InitStructure;
+
+  /* DAC channel 1 Configuration */
+
+  /*
+     This line fixed a bug that cost me 5 days, bad wave amplitude
+     value, and some STM32F4 periph library bugs caused triangle wave
+     geneartion to be enable resulting in a low level tone on the
+     SM1000, that we thought was caused by analog issues like layour
+     or power supply biasing
+  */
+  DAC_StructInit(&DAC_InitStructure);
+
+  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
+  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
+  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
+  DAC_Init(DAC_Channel_1, &DAC_InitStructure);
+
+  /* DMA1_Stream5 channel7 configuration **************************************/
+  /* Table 35 page 219 of the monster data sheet */
+
+  DMA_DeInit(DMA1_Stream5);
+  DMA_InitStructure.DMA_Channel = DMA_Channel_7;
+  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R1_ADDRESS;
+  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac1_buf;
+  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
+  DMA_InitStructure.DMA_BufferSize = DAC_BUF_SZ;
+  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+  DMA_Init(DMA1_Stream5, &DMA_InitStructure);
+
+  /* Enable DMA Half & Complete interrupts */
+
+  DMA_ITConfig(DMA1_Stream5, DMA_IT_TC | DMA_IT_HT, ENABLE);
+
+  /* Enable the DMA Stream IRQ Channel */
+
+  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  /* Enable DMA1_Stream5 */
+
+  DMA_Cmd(DMA1_Stream5, ENABLE);
+
+  /* Enable DAC Channel 1 */
+
+  DAC_Cmd(DAC_Channel_1, ENABLE);
+
+  /* Enable DMA for DAC Channel 1 */
+
+  DAC_DMACmd(DAC_Channel_1, ENABLE);
+}
+
+static void dac2_config(void)
+{
+  DAC_InitTypeDef  DAC_InitStructure;
+  DMA_InitTypeDef DMA_InitStructure;
+  NVIC_InitTypeDef NVIC_InitStructure;
+
+  /* DAC channel 2 Configuration (see notes in dac1_config() above) */
+
+  DAC_StructInit(&DAC_InitStructure);
+  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
+  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
+  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
+  DAC_Init(DAC_Channel_2, &DAC_InitStructure);
+
+  /* DMA1_Stream6 channel7 configuration **************************************/
+
+  DMA_DeInit(DMA1_Stream6);
+  DMA_InitStructure.DMA_Channel = DMA_Channel_7;
+  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R2_ADDRESS;
+  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac2_buf;
+  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
+  DMA_InitStructure.DMA_BufferSize = DAC_BUF_SZ;
+  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+  DMA_Init(DMA1_Stream6, &DMA_InitStructure);
+
+  /* Enable DMA Half & Complete interrupts */
+
+  DMA_ITConfig(DMA1_Stream6, DMA_IT_TC | DMA_IT_HT, ENABLE);
+
+  /* Enable the DMA Stream IRQ Channel */
+
+  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  /* Enable DMA1_Stream6 */
+
+  DMA_Cmd(DMA1_Stream6, ENABLE);
+
+  /* Enable DAC Channel 2 */
+
+  DAC_Cmd(DAC_Channel_2, ENABLE);
+
+  /* Enable DMA for DAC Channel 2 */
+
+  DAC_DMACmd(DAC_Channel_2, ENABLE);
+
+}
+
+/******************************************************************************/
+/*                 STM32F4xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32f40xx.s/startup_stm32f427x.s).                         */
+/******************************************************************************/
+
+/*
+  This function handles DMA1 Stream 5 interrupt request for DAC1.
+*/
+
+void DMA1_Stream5_IRQHandler(void) {
+    int i, j, sam;
+    short signed_buf[DAC_BUF_SZ/2];
+
+    GPIOE->ODR |= (1 << 1);
+
+    /* Transfer half empty interrupt - refill first half */
+
+    if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5) != RESET) {
+        /* fill first half from fifo */
+
+        if (fifo_read(dac1_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);
+            dac_underflow++;
+        }
+
+        /* convert to unsigned */
+
+        for(i=0; i<DAC_BUF_SZ/2; i++) {
+            sam = (int)(M*(float)signed_buf[i] + C);
+            dac1_buf[i] = (unsigned short)sam;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_HTIF5);
+    }
+
+    /* Transfer complete interrupt - refill 2nd half */
+
+    if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5) != RESET) {
+        /* fill second half from fifo */
+
+        if (fifo_read(dac1_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);
+            dac_underflow++;
+        }
+
+        /* convert to unsigned */
+
+        for(i=0, j=DAC_BUF_SZ/2; i<DAC_BUF_SZ/2; i++,j++) {
+            sam = (int)(M*(float)signed_buf[i] + C);
+            dac1_buf[j] = (unsigned short)sam;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5);
+    }
+
+    GPIOE->ODR &= ~(1 << 1);
+}
+
+/*
+  This function handles DMA1 Stream 6 interrupt request for DAC2.
+*/
+
+void DMA1_Stream6_IRQHandler(void) {
+    int i, j, sam;
+    short signed_buf[DAC_BUF_SZ/2];
+
+    GPIOE->ODR |= (1 << 2);
+
+    /* Transfer half empty interrupt - refill first half */
+
+    if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6) != RESET) {
+        /* fill first half from fifo */
+
+        if (fifo_read(dac2_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);
+            dac_underflow++;
+        }
+
+        /* convert to unsigned */
+
+        for(i=0; i<DAC_BUF_SZ/2; i++) {
+            sam = (int)(M*(float)signed_buf[i] + C);
+            dac2_buf[i] = (unsigned short)sam;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_HTIF6);
+    }
+
+    /* Transfer complete interrupt - refill 2nd half */
+
+    if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6) != RESET) {
+        /* fill second half from fifo */
+
+        if (fifo_read(dac2_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);
+            dac_underflow++;
+        }
+
+        /* convert to unsigned  */
+
+        for(i=0, j=DAC_BUF_SZ/2; i<DAC_BUF_SZ/2; i++,j++) {
+            sam = (int)(M*(float)signed_buf[i] + C);
+            dac2_buf[j] = (unsigned short)sam;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);
+    }
+
+    GPIOE->ODR &= ~(1 << 2);
+}
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_dacduc.c b/codec2/branches/0.7/stm32/src/stm32f4_dacduc.c
new file mode 100644 (file)
index 0000000..2c51909
--- /dev/null
@@ -0,0 +1,416 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_dac.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 1 June 2013
+
+  DAC driver module for STM32F4. DAC1 if fixed at Fs of 2Mhz.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "stm32f4xx.h"
+#include "codec2_fifo.h"
+#include "stm32f4_dacduc.h"
+#include "debugblinky.h"
+
+/* write to these registers for 12 bit left aligned data, as per data sheet
+   make sure 4 least sig bits set to 0 */
+
+#define DAC_DHR12R1_ADDRESS    0x40007408
+#define DAC_DHR12R2_ADDRESS    0x40007414
+
+#define DAC_MAX      4096            /* maximum amplitude */
+
+/* y=mx+c mapping of samples16 bit shorts to DAC samples.  Table: 74
+   of data sheet indicates With DAC buffer on, DAC range is limited to
+   0x0E0 to 0xF1C at VREF+ = 3.6 V, we have Vref=3.3V which is close.
+ */
+
+#define M ((3868.0-224.0)/65536.0)
+#define C 2047.0
+
+
+static struct FIFO *dac1_fifo;
+static struct FIFO *dac2_fifo;
+
+static unsigned short dac1_buf[DAC_DUC_BUF_SZ];
+static unsigned short dac2_buf[DAC_BUF_SZ];
+
+static void tim6_config(void);
+static void tim7_config(void);
+static void dac1_config(void);
+static void dac2_config(void);
+
+int dac_underflow;
+
+void fast_dac_open(int dac1_fifo_size,int dac2_fifo_size) {
+
+    memset(dac1_buf, 32768, sizeof(short)*DAC_DUC_BUF_SZ);
+    memset(dac2_buf, 32768, sizeof(short)*DAC_BUF_SZ);
+
+    /* Create fifos */
+
+    dac1_fifo = fifo_create(dac1_fifo_size);
+    dac2_fifo = fifo_create(dac2_fifo_size);
+    assert(dac1_fifo != NULL);
+    assert(dac2_fifo != NULL);
+
+    /* Turn on the clocks we need -----------------------------------------------*/
+
+    /* DMA1 clock enable */
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
+    /* GPIOA clock enable (to be used with DAC) */
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
+    /* DAC Periph clock enable */
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
+
+    /* GPIO Pin configuration DAC1->PA.4, DAC2->PA.5 configuration --------------*/
+
+    GPIO_InitTypeDef GPIO_InitStructure;
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
+    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+    GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+    /* Timer and DAC 1 & 2 Configuration ----------------------------------------*/
+    tim7_config();
+    tim6_config();
+    dac1_config();
+    dac2_config();
+
+    init_debug_blinky();
+}
+
+
+/* Call these puppies to send samples to the DACs.  For your
+   convenience they accept signed 16 bit samples. */
+
+int dac1_write(short buf[], int n) {
+    return fifo_write(dac1_fifo, buf, n);
+}
+
+int dac2_write(short buf[], int n) {
+    return fifo_write(dac2_fifo, buf, n);
+}
+
+static void tim6_config(void)
+{
+  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
+
+  /* TIM6 Periph clock enable */
+  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
+
+  /* --------------------------------------------------------
+
+  TIM6 input clock (TIM6CLK) is set to 2 * APB1 clock (PCLK1), since
+  APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig
+  13 clock tree figure in DM0031020.pdf).
+
+     Sample rate Fs = 2*PCLK1/TIM_ClockDivision
+                    = (HCLK/2)/TIM_ClockDivision
+
+  ----------------------------------------------------------- */
+
+  /* Time base configuration */
+
+  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
+  TIM_TimeBaseStructure.TIM_Period = 5250;
+  TIM_TimeBaseStructure.TIM_Prescaler = 0;
+  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
+
+  /* TIM6 TRGO selection */
+
+  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
+
+  /* TIM6 enable counter */
+
+  TIM_Cmd(TIM6, ENABLE);
+}
+
+/* Sets up tim7 to run at a high sample rate */
+void tim7_config(void)
+{
+  /* Set up tim7 */
+
+
+  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
+
+  /* TIM7 Periph clock enable */
+  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
+
+  /* --------------------------------------------------------
+
+
+  TIM7 input clock (TIM7CLK) is set to 2 * APB1 clock (PCLK1), since
+  APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig
+  13 clock tree figure in DM0031020.pdf).
+
+     Sample rate Fs = 2*PCLK1/TIM_ClockDivision
+                    = (HCLK/2)/TIM_ClockDivision
+
+  ----------------------------------------------------------- */
+
+  /* Time base configuration */
+
+  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
+  TIM_TimeBaseStructure.TIM_Period = 41;
+  TIM_TimeBaseStructure.TIM_Prescaler = 0;
+  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+  TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure);
+
+  /* TIM7 TRGO selection */
+
+  TIM_SelectOutputTrigger(TIM7, TIM_TRGOSource_Update);
+
+  /* TIM7 enable counter */
+
+  TIM_Cmd(TIM7, ENABLE);
+}
+
+static void dac1_config(void)
+{
+  DAC_InitTypeDef  DAC_InitStructure;
+  DMA_InitTypeDef  DMA_InitStructure;
+  NVIC_InitTypeDef NVIC_InitStructure;
+
+  /* DAC channel 1 Configuration */
+
+  /*
+     This line fixed a bug that cost me 5 days, bad wave amplitude
+     value, and some STM32F4 periph library bugs caused triangle wave
+     geneartion to be enable resulting in a low level tone on the
+     SM1000, that we thought was caused by analog issues like layour
+     or power supply biasing
+  */
+  DAC_StructInit(&DAC_InitStructure);
+
+  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T7_TRGO;
+  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
+
+  /*External buffering is needed to get nice square samples at Fs=2Mhz. See DM00129215.pdf */
+  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;
+  DAC_Init(DAC_Channel_1, &DAC_InitStructure);
+
+  /* DMA1_Stream5 channel7 configuration **************************************/
+  /* Table 35 page 219 of the monster data sheet */
+
+  DMA_DeInit(DMA1_Stream5);
+  DMA_InitStructure.DMA_Channel = DMA_Channel_7;
+  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R1_ADDRESS;
+  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac1_buf;
+  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
+  DMA_InitStructure.DMA_BufferSize = DAC_DUC_BUF_SZ;
+  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+  DMA_Init(DMA1_Stream5, &DMA_InitStructure);
+
+  /* Enable DMA Half & Complete interrupts */
+
+  DMA_ITConfig(DMA1_Stream5, DMA_IT_TC | DMA_IT_HT, ENABLE);
+
+  /* Enable the DMA Stream IRQ Channel */
+
+  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  /* Enable DMA1_Stream5 */
+
+  DMA_Cmd(DMA1_Stream5, ENABLE);
+
+  /* Enable DAC Channel 1 */
+
+  DAC_Cmd(DAC_Channel_1, ENABLE);
+
+  /* Enable DMA for DAC Channel 1 */
+
+  DAC_DMACmd(DAC_Channel_1, ENABLE);
+}
+
+static void dac2_config(void)
+{
+  DAC_InitTypeDef  DAC_InitStructure;
+  DMA_InitTypeDef DMA_InitStructure;
+  NVIC_InitTypeDef NVIC_InitStructure;
+
+  /* DAC channel 2 Configuration (see notes in dac1_config() above) */
+
+  DAC_StructInit(&DAC_InitStructure);
+  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
+  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
+  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;
+  DAC_Init(DAC_Channel_2, &DAC_InitStructure);
+
+  /* DMA1_Stream6 channel7 configuration **************************************/
+
+  DMA_DeInit(DMA1_Stream6);
+  DMA_InitStructure.DMA_Channel = DMA_Channel_7;
+  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R2_ADDRESS;
+  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac2_buf;
+  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
+  DMA_InitStructure.DMA_BufferSize = DAC_BUF_SZ;
+  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
+  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
+  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+  DMA_Init(DMA1_Stream6, &DMA_InitStructure);
+
+  /* Enable DMA Half & Complete interrupts */
+
+  DMA_ITConfig(DMA1_Stream6, DMA_IT_TC | DMA_IT_HT, ENABLE);
+
+  /* Enable the DMA Stream IRQ Channel */
+
+  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream6_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  /* Enable DMA1_Stream6 */
+
+  DMA_Cmd(DMA1_Stream6, ENABLE);
+
+  /* Enable DAC Channel 2 */
+
+  DAC_Cmd(DAC_Channel_2, ENABLE);
+
+  /* Enable DMA for DAC Channel 2 */
+
+  DAC_DMACmd(DAC_Channel_2, ENABLE);
+
+}
+
+/******************************************************************************/
+/*                 STM32F4xx Peripherals Interrupt Handlers                   */
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
+/*  available peripheral interrupt handler's name please refer to the startup */
+/*  file (startup_stm32f40xx.s/startup_stm32f427x.s).                         */
+/******************************************************************************/
+
+/*
+  This function handles DMA1 Stream 5 interrupt request for DAC1.
+*/
+
+void DMA1_Stream5_IRQHandler(void) {
+    GPIOE->ODR |= (1 << 1);
+
+    /* Transfer half empty interrupt - refill first half */
+
+    if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5) != RESET) {
+        /* fill first half from fifo */
+       fifo_read(dac1_fifo, (short*)dac1_buf, DAC_DUC_BUF_SZ/2);
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+        DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_HTIF5);
+    }
+
+    /* Transfer complete interrupt - refill 2nd half */
+
+    if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5) != RESET) {
+        /* fill second half from fifo */
+       fifo_read(dac1_fifo, (short*)(dac1_buf+DAC_DUC_BUF_SZ/2), DAC_DUC_BUF_SZ/2);
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+        DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5);
+    }
+
+    GPIOE->ODR &= ~(1 << 1);
+}
+
+/*
+  This function handles DMA1 Stream 6 interrupt request for DAC2.
+*/
+
+void DMA1_Stream6_IRQHandler(void) {
+    int i, j, sam;
+    short signed_buf[DAC_BUF_SZ/2];
+
+    GPIOE->ODR |= (1 << 2);
+
+    /* Transfer half empty interrupt - refill first half */
+
+    if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_HTIF6) != RESET) {
+        /* fill first half from fifo */
+
+        if (fifo_read(dac2_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);
+            dac_underflow++;
+        }
+
+        /* convert to unsigned */
+
+        for(i=0; i<DAC_BUF_SZ/2; i++) {
+            sam = (int)(M*(float)signed_buf[i] + C);
+            dac2_buf[i] = (unsigned short)sam;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_HTIF6);
+    }
+
+    /* Transfer complete interrupt - refill 2nd half */
+
+    if(DMA_GetITStatus(DMA1_Stream6, DMA_IT_TCIF6) != RESET) {
+        /* fill second half from fifo */
+
+        if (fifo_read(dac2_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);
+            dac_underflow++;
+        }
+
+        /* convert to unsigned  */
+
+        for(i=0, j=DAC_BUF_SZ/2; i<DAC_BUF_SZ/2; i++,j++) {
+            sam = (int)(M*(float)signed_buf[i] + C);
+            dac2_buf[j] = (unsigned short)sam;
+        }
+
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */
+
+        DMA_ClearITPendingBit(DMA1_Stream6, DMA_IT_TCIF6);
+    }
+
+    GPIOE->ODR &= ~(1 << 2);
+}
+
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_dacloduc.c b/codec2/branches/0.7/stm32/src/stm32f4_dacloduc.c
new file mode 100644 (file)
index 0000000..a9b93f0
--- /dev/null
@@ -0,0 +1,276 @@
+/*---------------------------------------------------------------------------*\\r
+\r
+  FILE........: stm32f4_dacloduc.c\r
+  AUTHOR......: David Rowe\r
+  DATE CREATED: Sep 2015\r
+\r
+  Experimental DAC driver module for STM32F4 that includes a low IF\r
+  Digital Up Converter (DUC).  The Fs=96kHz signal is mixed up by a\r
+  (real) 24 kHz (Fs/4) local oscillator, then output by DAC1.\r
+\r
+  DAC1 is connected to pin PA4.\r
+\r
+\*---------------------------------------------------------------------------*/\r
+\r
+/*\r
+  Copyright (C) 2015 David Rowe\r
+\r
+  All rights reserved.\r
+\r
+  This program is free software; you can redistribute it and/or modify\r
+  it under the terms of the GNU Lesser General Public License version 2.1, as\r
+  published by the Free Software Foundation.  This program is\r
+  distributed in the hope that it will be useful, but WITHOUT ANY\r
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public\r
+  License for more details.\r
+\r
+  You should have received a copy of the GNU Lesser General Public License\r
+  along with this program; if not, see <http://www.gnu.org/licenses/>.\r
+*/\r
+\r
+#include <assert.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <math.h>\r
+#include "stm32f4xx.h"\r
+#include "codec2_fifo.h"\r
+#include "stm32f4_dac.h"\r
+#include "debugblinky.h"\r
+\r
+/* write to these registers for 12 bit left aligned data, as per data sheet \r
+   make sure 4 least sig bits set to 0 */\r
+\r
+#define DAC_DHR12R1_ADDRESS    0x40007408\r
+\r
+#define DAC_MAX      4096            /* maximum amplitude */\r
+\r
+/* y=mx+c mapping of samples16 bit shorts to DAC samples.  Table: 74\r
+   of data sheet indicates With DAC buffer on, DAC range is limited to\r
+   0x0E0 to 0xF1C at VREF+ = 3.6 V, we have Vref=3.3V which is close.\r
+ */\r
+\r
+#define M ((3868.0-224.0)/65536.0)\r
+#define C 2047.0\r
+\r
+static struct FIFO *dac1_fifo;\r
+\r
+static unsigned short dac1_buf[DAC_BUF_SZ];\r
+\r
+static void tim6_config(void);\r
+static void dac1_config(void);\r
+\r
+int dac_underflow;\r
+\r
+short signed_buf[DAC_BUF_SZ/2];\r
+\r
+#define MAX_AMP 32767\r
+\r
+void dac_open(int fifo_size) {\r
+    memset(dac1_buf, 32768, sizeof(short)*DAC_BUF_SZ);\r
+\r
+    /* Create fifo */\r
+\r
+    dac1_fifo = fifo_create(fifo_size);\r
+    assert(dac1_fifo != NULL);\r
+\r
+    /* Turn on the clocks we need -----------------------------------------------*/\r
+\r
+    /* DMA1 clock enable */\r
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);\r
+    /* GPIOA clock enable (to be used with DAC) */\r
+    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);                         \r
+    /* DAC Periph clock enable */\r
+    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);\r
+\r
+    /* GPIO Pin configuration DAC1->PA.4 configuration --------------------------*/\r
+\r
+    GPIO_InitTypeDef GPIO_InitStructure;\r
+    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;\r
+    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;\r
+    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\r
+    GPIO_Init(GPIOA, &GPIO_InitStructure);\r
+\r
+    /* Timer and DAC 1 Configuration --------------------------------------------*/\r
+\r
+    tim6_config();  \r
+    dac1_config();\r
+\r
+    init_debug_blinky();\r
+}\r
+\r
+/* Call these puppies to send samples to the DACs.  For your\r
+   convenience they accept signed 16 bit samples. */\r
+\r
+int dac1_write(short buf[], int n) {   \r
+    return fifo_write(dac1_fifo, buf, n);\r
+}\r
+\r
+static void tim6_config(void)\r
+{\r
+  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;\r
+\r
+  /* TIM6 Periph clock enable */\r
+  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);\r
+  \r
+  /* --------------------------------------------------------\r
+  \r
+  TIM6 input clock (TIM6CLK) is set to 2 * APB1 clock (PCLK1), since\r
+  APB1 prescaler is different from 1 (see system_stm32f4xx.c and Fig\r
+  13 clock tree figure in DM0031020.pdf).\r
+\r
+     Sample rate Fs = 2*PCLK1/TIM_ClockDivision \r
+                    = (HCLK/2)/TIM_ClockDivision\r
+                    = 84E6/TIM_ClockDivision (usually)\r
+\r
+  ----------------------------------------------------------- */\r
+\r
+  /* Time base configuration */\r
+\r
+  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); \r
+  TIM_TimeBaseStructure.TIM_Period = 875-1;         /* 96 kHz */\r
+  TIM_TimeBaseStructure.TIM_Prescaler = 0;       \r
+  TIM_TimeBaseStructure.TIM_ClockDivision = 0;    \r
+  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  \r
+  TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);\r
+\r
+  /* TIM6 TRGO selection */\r
+\r
+  TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);\r
+  \r
+  /* TIM6 enable counter */\r
+\r
+  TIM_Cmd(TIM6, ENABLE);\r
+}\r
+\r
+static void dac1_config(void)\r
+{\r
+  DAC_InitTypeDef  DAC_InitStructure;\r
+  DMA_InitTypeDef  DMA_InitStructure;\r
+  NVIC_InitTypeDef NVIC_InitStructure;\r
+  \r
+  /* DAC channel 1 Configuration */\r
+\r
+  /* \r
+     This line fixed a bug that cost me 5 days, bad wave amplitude\r
+     value, and some STM32F4 periph library bugs caused triangle wave\r
+     generation to be enable resulting in a low level tone on the\r
+     SM1000, that we thought was caused by analog issues like layout\r
+     or power supply biasing\r
+  */\r
+  DAC_StructInit(&DAC_InitStructure); \r
+\r
+  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO; \r
+  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;\r
+  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable;\r
+  DAC_Init(DAC_Channel_1, &DAC_InitStructure);\r
+\r
+  /* DMA1_Stream5 channel7 configuration **************************************/\r
+  /* Table 35 page 219 of the monster data sheet */\r
+\r
+  DMA_DeInit(DMA1_Stream5);\r
+  DMA_InitStructure.DMA_Channel = DMA_Channel_7;  \r
+  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)DAC_DHR12R1_ADDRESS;\r
+  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dac1_buf;\r
+  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;\r
+  DMA_InitStructure.DMA_BufferSize = DAC_BUF_SZ;\r
+  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;\r
+  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;\r
+  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;\r
+  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;\r
+  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;\r
+  DMA_InitStructure.DMA_Priority = DMA_Priority_High;\r
+  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         \r
+  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;\r
+  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;\r
+  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;\r
+  DMA_Init(DMA1_Stream5, &DMA_InitStructure);\r
+\r
+  /* Enable DMA Half & Complete interrupts */\r
+\r
+  DMA_ITConfig(DMA1_Stream5, DMA_IT_TC | DMA_IT_HT, ENABLE);\r
+\r
+  /* Enable the DMA Stream IRQ Channel */\r
+\r
+  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;\r
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;\r
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;\r
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;\r
+  NVIC_Init(&NVIC_InitStructure);     \r
+\r
+  /* Enable DMA1_Stream5 */\r
+\r
+  DMA_Cmd(DMA1_Stream5, ENABLE);\r
+\r
+  /* Enable DAC Channel 1 */\r
+\r
+  DAC_Cmd(DAC_Channel_1, ENABLE);\r
+\r
+  /* Enable DMA for DAC Channel 1 */\r
+\r
+  DAC_DMACmd(DAC_Channel_1, ENABLE);\r
+}\r
+\r
+\r
+/******************************************************************************/\r
+/*                 STM32F4xx Peripherals Interrupt Handlers                   */\r
+/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */\r
+/*  available peripheral interrupt handler's name please refer to the startup */\r
+/*  file (startup_stm32f40xx.s/startup_stm32f427x.s).                         */\r
+/******************************************************************************/\r
+\r
+/*\r
+  This function handles DMA1 Stream 5 interrupt request for DAC1.\r
+*/\r
+\r
+void DMA1_Stream5_IRQHandler(void) {\r
+    int i, j, sam;\r
+    short signed_buf[DAC_BUF_SZ/2];\r
+\r
+    GPIOE->ODR |= (1 << 1);\r
+\r
+    /* Transfer half empty interrupt - refill first half */\r
+\r
+    if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_HTIF5) != RESET) {\r
+\r
+        /* fill first half from fifo */\r
+\r
+        if (fifo_read(dac1_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);\r
+            dac_underflow++;\r
+        }\r
+\r
+        for(i=0; i<DAC_BUF_SZ/2; i++) {\r
+            sam = (int)(M*(float)signed_buf[i] + C);\r
+            dac1_buf[i] = (unsigned short)sam;\r
+        }\r
+\r
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */\r
+\r
+        DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_HTIF5);  \r
+    }\r
+\r
+    /* Transfer complete interrupt - refill 2nd half */\r
+\r
+    if(DMA_GetITStatus(DMA1_Stream5, DMA_IT_TCIF5) != RESET) {\r
+\r
+        /* fill second half from fifo */\r
+\r
+        if (fifo_read(dac1_fifo, signed_buf, DAC_BUF_SZ/2) == -1) {\r
+            memset(signed_buf, 0, sizeof(short)*DAC_BUF_SZ/2);\r
+            dac_underflow++;\r
+        }\r
+\r
+        for(i=0, j=DAC_BUF_SZ/2; i<DAC_BUF_SZ/2; i++, j++) {\r
+            sam = (int)(M*(float)signed_buf[i] + C);\r
+            dac1_buf[j] = (unsigned short)sam;\r
+        }\r
+\r
+        /* Clear DMA Stream Transfer Complete interrupt pending bit */\r
+\r
+        DMA_ClearITPendingBit(DMA1_Stream5, DMA_IT_TCIF5);  \r
+    }\r
+\r
+    GPIOE->ODR &= ~(1 << 1);\r
+}\r
+\r
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_machdep.c b/codec2/branches/0.7/stm32/src/stm32f4_machdep.c
new file mode 100644 (file)
index 0000000..76b8fb6
--- /dev/null
@@ -0,0 +1,86 @@
+
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_machdep.c
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2 2013
+
+  STM32F4 implementation of the machine dependant timer functions,
+  e.g. profiling using a clock cycle counter..
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include "machdep.h"
+#include "gdb_stdio.h"
+
+volatile unsigned int *DWT_CYCCNT   = (volatile unsigned int *)0xE0001004;
+volatile unsigned int *DWT_CONTROL  = (volatile unsigned int *)0xE0001000;
+volatile unsigned int *SCB_DEMCR    = (volatile unsigned int *)0xE000EDFC;
+
+#define CORE_CLOCK 168E6
+#define BUF_SZ     4096
+
+static char buf[BUF_SZ];
+
+void machdep_profile_init(void)
+{
+    static int enabled = 0;
+
+    if (!enabled) {
+        *SCB_DEMCR = *SCB_DEMCR | 0x01000000;
+        *DWT_CYCCNT = 0; // reset the counter
+        *DWT_CONTROL = *DWT_CONTROL | 1 ; // enable the counter
+
+        enabled = 1;
+    }
+    *buf = 0;
+}
+
+void machdep_profile_reset(void)
+{
+    *DWT_CYCCNT = 0; // reset the counter
+}
+
+unsigned int machdep_profile_sample(void) {
+    return *DWT_CYCCNT;
+}
+
+/* log to a buffer, we only call printf after timing finished as it is slow */
+
+unsigned int machdep_profile_sample_and_log(unsigned int start, char s[])
+{
+    char  tmp[80];
+    float msec;
+
+    unsigned int dwt = *DWT_CYCCNT - start;
+    msec = 1000.0*(float)dwt/CORE_CLOCK;
+    sprintf(tmp, "%s %5.2f msecs\n",s,(double)msec);
+    if ((strlen(buf) + strlen(tmp)) < BUF_SZ)
+        strcat(buf, tmp);
+    return *DWT_CYCCNT;
+}
+
+void machdep_profile_print_logged_samples(void)
+{
+    gdb_stdio_printf("%s", buf);
+    *buf = 0;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_pwm.c b/codec2/branches/0.7/stm32/src/stm32f4_pwm.c
new file mode 100644 (file)
index 0000000..3bc3ea7
--- /dev/null
@@ -0,0 +1,236 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_pwm.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 26 June 2013
+
+  PWM  driver module for STM32F4.
+
+  TODO:
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "gdb_stdio.h"
+
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_rcc.h"
+
+#define TIM1_CCR3_ADDRESS    0x4001003C
+//#define TIM1_CCR3_ADDRESS    0x4001223C
+#define SINE_SAMPLES         32
+
+TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
+TIM_OCInitTypeDef  TIM_OCInitStructure;
+uint16_t uhTimerPeriod;
+uint16_t aSRC_Buffer[SINE_SAMPLES] = {0, 0, 0};
+
+/* 32 sample sine wave which at Fs=16kHz will be 500Hz.  Not sampels
+   are 16 bit 2's complement, the DAC driver convertsto 12 bit
+   unsigned. */
+
+short aSine[SINE_SAMPLES] = {
+    -16,    6384,   12528,  18192,   23200,   27232,   30256,   32128,   32752,   32128,
+    30256,   27232,   23152,   18192,   12528,    6384,     -16,   -6416,  -12560,  -18224,
+    -23184,  -27264,  -30288,  -32160,  -32768,  -32160,  -30288,  -27264,  -23184,  -18224,
+    -12560,   -6416
+};
+
+void Timer1Config();
+
+#define FS  16000
+
+int main(void){
+    Timer1Config();
+    while(1);
+}
+
+/* DR: TIM_Config configures a couple of I/O pins for PWM output from
+   Timer1 Channel 3.  Note I dont think any of this is needed, except
+   perhaps to check timer frequency.  Can be removed down the track. */
+
+/**
+  * @brief  Configure the TIM1 Pins.
+  * @param  None
+  * @retval None
+  */
+static void TIM_Config(void)
+{
+  GPIO_InitTypeDef GPIO_InitStructure;
+
+  /* GPIOA and GPIOB clock enable */
+  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);
+
+  /* GPIOA Configuration: Channel 3 as alternate function push-pull */
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
+  GPIO_Init(GPIOA, &GPIO_InitStructure);
+  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_TIM1);
+
+  /* GPIOB Configuration: Channel 3N as alternate function push-pull */
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
+  GPIO_Init(GPIOB, &GPIO_InitStructure);
+  GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_TIM1);
+
+#ifdef DR_OFF
+  /* DMA clock enable */
+  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);
+
+  DMA_DeInit(DMA2_Stream6);
+  DMA_InitStructure.DMA_Channel = DMA_Channel_6;
+  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(TIM1_CCR3_ADDRESS) ;
+  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)aSRC_Buffer;
+  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
+  DMA_InitStructure.DMA_BufferSize = SINE_SAMPLES;
+  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
+  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
+  DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
+  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
+  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
+  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
+  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
+  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
+  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
+
+  DMA_Init(DMA2_Stream6, &DMA_InitStructure);
+#endif
+}
+
+void Timer1Config() {
+    /* TIM Configuration */
+
+    TIM_Config();
+
+    /* TIM1 example -------------------------------------------------
+
+       TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2
+       prescaler is different from 1.
+       TIM1CLK = 2 * PCLK2
+       PCLK2 = HCLK / 2
+       => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock
+
+       TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock
+       SystemCoreClock is set to 168 MHz for STM32F4xx devices.
+
+       The objective is to configure TIM1 channel 3 to generate complementary PWM
+       signal with a frequency equal to F KHz:
+       - TIM1_Period = (SystemCoreClock / F) - 1
+
+       The number of this repetitive requests is defined by the TIM1 Repetion counter,
+       each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new
+       value defined by the aSRC_Buffer.
+
+       Note:
+       SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
+       Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
+       function to update SystemCoreClock variable value. Otherwise, any configuration
+       based on this variable will be incorrect.
+       -----------------------------------------------------------------------------*/
+
+    /* Compute the value to be set in ARR regiter to generate signal frequency at FS */
+
+#ifdef TMP
+    uhTimerPeriod = (SystemCoreClock / FS ) - 1;
+    //gdb_stdio_printf("uhTimerPeriod = %d\n", uhTimerPeriod);
+
+    /* Compute CCR1 values to generate a duty cycle at 50% */
+
+    for(i=0; i<SINE_SAMPLES; i++) {
+        aSRC_Buffer[i] = uhTimerPeriod *((int)aSine[i] + 32768)/(32768*2);
+    }
+#else
+    uhTimerPeriod = (SystemCoreClock / 28000000) - 1;
+    aSRC_Buffer[0] =   uhTimerPeriod/2 + 1;
+
+#endif
+
+    /* TIM1 clock enable */
+
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
+
+    /* Time Base configuration */
+
+    TIM_DeInit(TIM1);
+    TIM_TimeBaseStructure.TIM_Prescaler = 0;
+    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+    TIM_TimeBaseStructure.TIM_Period = uhTimerPeriod;
+    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
+
+    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
+
+
+    #define TMP2
+#ifdef TMP2
+    /* Channel 3 Configuration in PWM mode */
+
+    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
+    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
+    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
+    TIM_OCInitStructure.TIM_Pulse = aSRC_Buffer[0];
+    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
+    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
+    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
+    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
+
+    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
+
+    /* Enable preload feature */
+    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
+#else
+    /* Channel 3 Configuration in PWM mode */
+
+    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
+    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
+    //TIM_OCInitStructure.TIM_Pulse = aSRC_Buffer[0];
+
+    //TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
+    //TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
+
+    //TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
+    //TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
+    //TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
+
+    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
+
+    //TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
+#endif
+
+    /* TIM1 counter enable */
+    TIM_Cmd(TIM1, ENABLE);
+
+    /* DMA enable*/
+    //DMA_Cmd(DMA2_Stream6, ENABLE);
+
+    /* TIM1 Update DMA Request enable */
+    //TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE);
+
+    /* Main Output Enable */
+    TIM_CtrlPWMOutputs(TIM1, ENABLE);
+}
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_usb_vcp.c b/codec2/branches/0.7/stm32/src/stm32f4_usb_vcp.c
new file mode 100644 (file)
index 0000000..f30ecfb
--- /dev/null
@@ -0,0 +1,90 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: stm32f4_usb_vcp.c
+  AUTHOR......: xenovacivus
+  DATE CREATED: 3 Sep 2014
+
+  USB Virtual COM Port (VCP) module adapted from code I found here:
+
+    https://github.com/xenovacivus/STM32DiscoveryVCP
+
+\*---------------------------------------------------------------------------*/
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_rcc.h"
+#include "stm32f4xx_exti.h"
+#include "usbd_cdc_core.h"
+#include "usbd_usr.h"
+#include "usbd_desc.h"
+#include "usbd_cdc_vcp.h"
+#include "usb_dcd_int.h"
+#include "sm1000_leds_switches.h"
+#include "stm32f4_usb_vcp.h"
+
+/*
+ * The USB data must be 4 byte aligned if DMA is enabled. This macro handles
+ * the alignment, if necessary (it's actually magic, but don't tell anyone).
+ */
+__ALIGN_BEGIN USB_OTG_CORE_HANDLE  USB_OTG_dev __ALIGN_END;
+
+
+/*
+ * Define prototypes for interrupt handlers here. The conditional "extern"
+ * ensures the weak declarations from startup_stm32f4xx.c are overridden.
+ */
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void OTG_FS_IRQHandler(void);
+void OTG_FS_WKUP_IRQHandler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+void usb_vcp_init() {
+       /* Setup USB */
+       USBD_Init(&USB_OTG_dev,
+                   USB_OTG_FS_CORE_ID,
+                   &USR_desc,
+                   &USBD_CDC_cb,
+                   &USR_cb);
+}
+
+
+/*
+ * Interrupt Handlers
+ */
+
+void NMI_Handler(void)       {}
+void SVC_Handler(void)       {}
+void DebugMon_Handler(void)  {}
+void PendSV_Handler(void)    {}
+
+void OTG_FS_IRQHandler(void)
+{
+  USBD_OTG_ISR_Handler (&USB_OTG_dev);
+}
+
+void OTG_FS_WKUP_IRQHandler(void)
+{
+  if(USB_OTG_dev.cfg.low_power)
+  {
+    *(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ;
+    SystemInit();
+    USB_OTG_UngateClock(&USB_OTG_dev);
+  }
+  EXTI_ClearITPendingBit(EXTI_Line18);
+}
diff --git a/codec2/branches/0.7/stm32/src/stm32f4_vrom.c b/codec2/branches/0.7/stm32/src/stm32f4_vrom.c
new file mode 100644 (file)
index 0000000..5b66126
--- /dev/null
@@ -0,0 +1,724 @@
+/*!
+ * STM32F4 Virtual EEPROM driver
+ *
+ * This module implements a crude virtual EEPROM device stored in on-board
+ * flash.  The STM32F405 has 4 16kB flash sectors starting at address
+ * 0x80000000, followed by a 64kB sector, then 128kB sectors.
+ *
+ * The Cortex M4 core maps these all to address 0x00000000 when booting
+ * from normal flash, so the first sector is reserved for interrupt
+ * vectors.
+ *
+ * Everything else however is free game, and so we use these smaller
+ * sectors to store our configuration.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "stm32f4_vrom.h"
+#include "stm32f4xx_flash.h"
+#include "stm32f4xx_crc.h"
+
+#define VROM_SECT_SZ           (16384) /*!< Size of a flash sector */
+#define VROM_SECT_CNT          (3)     /*!< Number of sectors */
+#define VROM_BLOCK_SZ          (256)   /*!< Size of a flash block */
+
+/*!
+ * Starting address for the flash area
+ */
+#define VROM_START_ADDR                (0x08004000)
+
+/*!
+ * Number of blocks we can fit per sector, including the index block.
+ */
+#define VROM_BLOCK_CNT         (VROM_SECT_SZ / VROM_BLOCK_SZ)
+
+/*!
+ * Number of application blocks we can fit per sector.
+ */
+#define VROM_SECT_APP_BLOCK_CNT        (VROM_BLOCK_CNT - 1)
+
+/*!
+ * Total number of application blocks we can fit in flash.
+ */
+#define VROM_APP_BLOCK_CNT     (VROM_SECT_CNT * VROM_SECT_APP_BLOCK_CNT)
+
+/*!
+ * Maximum number of erase cycles per sector.
+ * Table 42 (page 109) of STM32F405 datasheet (DocID022152 Rev 5).
+ */
+#define VROM_MAX_CYCLES                (10000)
+
+/*!
+ * EEPROM block header.
+ */
+struct __attribute__ ((__packed__)) vrom_block_hdr_t {
+       /*!
+        * CRC32 checksum of the data, offset, size and ROM ID.
+        * A CRC32 of 0x00000000 indicates an obsoleted block.
+        * A CRC32 of 0xffffffff indicates an erased block.
+        */
+       uint32_t                crc32;
+       /*!
+        * ROM ID.
+        */
+       uint8_t                 rom;
+       /*!
+        * Block number in the virtual EEPROM.
+        */
+       uint8_t                 idx;
+       /*!
+        * Number of bytes from the virtual EEPROM stored in this block.
+        */
+       uint8_t                 size;
+       /*!
+        * Reserved for future use.
+        */
+       uint8_t                 reserved;
+};
+
+/*!
+ * The size of a block header in bytes.
+ */
+#define VROM_BLOCK_HDR_SZ      (sizeof(struct vrom_block_hdr_t))
+
+/*!
+ * The amount of data available for application use.
+ */
+#define VROM_DATA_SZ           (VROM_BLOCK_SZ - VROM_BLOCK_HDR_SZ)
+
+/*!
+ * EEPROM data block.
+ */
+struct __attribute__ ((__packed__)) vrom_data_block_t {
+       /*! Block header */
+       struct vrom_block_hdr_t         header;
+
+       /*! Block data */
+       uint8_t                         data[VROM_DATA_SZ];
+};
+
+/*!
+ * The first block in a sector is the sector index block.  This indicates
+ * the used/free state of the entire block and counts the number of
+ * erase cycles for the sector.  The index block has no header.
+ */
+struct __attribute__ ((__packed__)) vrom_sector_idx_t {
+       /*!
+        * Number of erase cycles remaining for the sector.
+        * 0xffffffff == unprogrammed.
+        */
+       uint32_t                cycles_remain;
+       /*!
+        * Block metadata flags.  One for each data block in the sector.
+        * Does not include the index block.
+        */
+       uint16_t                flags[VROM_SECT_APP_BLOCK_CNT];
+};
+
+#define VROM_SFLAGS_USED       (1 << 0)        /*!< Block in use */
+
+/*!
+ * Return the address of a virtual EEPROM sector header.
+ */
+static const struct vrom_sector_idx_t* vrom_get_sector_hdr(uint8_t sector)
+{
+       return (const struct vrom_sector_idx_t*)(
+                       VROM_START_ADDR + (VROM_SECT_SZ * sector));
+}
+
+/*!
+ * Return the address of a virtual EEPROM block.
+ */
+static const struct vrom_data_block_t* vrom_get_block(
+               uint8_t sector, uint8_t block)
+{
+       return (const struct vrom_data_block_t*)(
+                       (void*)vrom_get_sector_hdr(sector)
+                       + (VROM_BLOCK_SZ * (block + 1)));
+}
+
+/*!
+ * Compute the CRC32 of a block.
+ */
+static uint32_t vrom_crc32(
+               const struct vrom_data_block_t* const block)
+{
+       struct vrom_data_block_t temp_block;
+       uint32_t size = sizeof(temp_block);
+       const uint8_t* in = (const uint8_t*)(&temp_block);
+       uint32_t tmp;
+       uint32_t crc;
+
+       memcpy(&temp_block, block, sizeof(temp_block));
+       temp_block.header.crc32 = 0;
+
+       CRC_ResetDR();
+       while(size) {
+               tmp = 0;
+               if (size) {
+                       tmp |= (uint32_t)(*(in++)) << 24;
+                       size--;
+               }
+               if (size) {
+                       tmp |= (uint32_t)(*(in++)) << 16;
+                       size--;
+               }
+               if (size) {
+                       tmp |= (uint32_t)(*(in++)) << 8;
+                       size--;
+               }
+               if (size) {
+                       tmp |= (uint32_t)(*(in++));
+                       size--;
+               }
+               crc = CRC_CalcCRC(tmp);
+       }
+       return crc;
+}
+
+/*!
+ * Find the block storing the given index.
+ */
+static const struct vrom_data_block_t* vrom_find(uint8_t rom, uint8_t idx)
+{
+       int sector, block;
+
+       for (sector = 0; sector < VROM_SECT_CNT; sector++) {
+               const struct vrom_sector_idx_t* sect_hdr
+                       = vrom_get_sector_hdr(sector);
+               if (sect_hdr->cycles_remain == UINT32_MAX)
+                       /* unformatted */
+                       continue;
+               for (block = 0; block < VROM_SECT_APP_BLOCK_CNT; block++) {
+                       const struct vrom_data_block_t* block_ptr;
+                       if (sect_hdr->flags[block] == UINT16_MAX)
+                               /* unformatted */
+                               continue;
+                       if (sect_hdr->flags[block] == 0)
+                               /* obsolete */
+                               continue;
+
+                       block_ptr = vrom_get_block(sector, block);
+
+                       /* Verify the content */
+                       if (vrom_crc32(block_ptr)
+                                       != block_ptr->header.crc32)
+                               /* corrupt */
+                               continue;
+
+                       if (block_ptr->header.rom != rom)
+                               /* different ROM */
+                               continue;
+
+                       if (block_ptr->header.idx != idx)
+                               /* wrong index */
+                               continue;
+
+                       return block_ptr;
+               }
+       }
+       return NULL;
+}
+
+/*!
+ * Get the sector number of a given address.
+ */
+static uint8_t vrom_sector_num(const void* address)
+{
+       /* Get the offset from the base address */
+       uint32_t offset = (uint32_t)address - VROM_START_ADDR;
+       return offset / VROM_SECT_SZ;
+}
+
+/*!
+ * Get the block number of a given address.
+ */
+static uint8_t vrom_block_num(const void* address)
+{
+       /* Get the sector number */
+       uint8_t sector = vrom_sector_num(address);
+
+       /* Get the offset from the sector base */
+       uint32_t offset = (uint32_t)(address
+                       - (const void*)vrom_get_sector_hdr(sector));
+       offset /= VROM_BLOCK_SZ;
+       return offset - 1;
+}
+
+/*!
+ * (Erase and) Format a sector.
+ *
+ * @retval     -EIO    Erase failed
+ * @retval     -EPERM  Erase counter depleted.
+ */
+static int vrom_format_sector(const struct vrom_sector_idx_t* sector)
+{
+       uint8_t sector_num = vrom_sector_num(sector);
+       uint32_t cycles_remain = VROM_MAX_CYCLES;
+       if (sector->cycles_remain != UINT32_MAX) {
+               if (sector->cycles_remain == 0)
+                       /* This sector is exhausted */
+                       return -EPERM;
+
+               /* This sector has been formatted before */
+               cycles_remain = sector->cycles_remain - 1;
+               if (FLASH_EraseSector(sector_num + 1, VoltageRange_3))
+                       /* Erase failed */
+                       return -EIO;
+       }
+
+       /* Program the new sector cycle counter */
+       if (FLASH_ProgramWord((uint32_t)sector,
+                               cycles_remain) == FLASH_COMPLETE)
+               return 0;       /* All good */
+       /* If we get here, then programming failed */
+       return -EIO;
+}
+
+/*!
+ * Find the next available block.
+ */
+static const struct vrom_data_block_t* vrom_find_free(uint8_t run_gc)
+{
+       int sector;
+       if (run_gc) {
+               for (sector = 0; sector < VROM_SECT_CNT; sector++) {
+                       uint8_t block;
+                       uint8_t used = 0;
+                       const struct vrom_sector_idx_t* sect_hdr
+                               = vrom_get_sector_hdr(sector);
+                       if (sect_hdr->cycles_remain == UINT32_MAX)
+                               /* Already erased */
+                               continue;
+                       if (sect_hdr->cycles_remain == 0)
+                               /* Depleted */
+                               continue;
+
+                       for (block = 0; block < VROM_SECT_APP_BLOCK_CNT;
+                                       block++) {
+                               if (sect_hdr->flags[block]) {
+                                       used = 1;
+                                       break;
+                               }
+                       }
+
+                       if (!used) {
+                               /* We can format this */
+                               vrom_format_sector(sect_hdr);
+                       }
+               }
+       }
+
+       for (sector = 0; sector < VROM_SECT_CNT; sector++) {
+               uint8_t block;
+               const struct vrom_sector_idx_t* sect_hdr
+                       = vrom_get_sector_hdr(sector);
+               if (sect_hdr->cycles_remain == UINT32_MAX) {
+                       /* Unformatted sector. */
+                       if (vrom_format_sector(sect_hdr))
+                               /* Couldn't format, keep looking */
+                               continue;
+               }
+               for (block = 0; block < VROM_SECT_APP_BLOCK_CNT; block++) {
+                       if (sect_hdr->flags[block] == UINT16_MAX)
+                               /* Success */
+                               return vrom_get_block(sector, block);
+               }
+       }
+
+       /* No blocks free, but have we done garbage collection? */
+       if (!run_gc)
+               return vrom_find_free(1);
+
+       /* If we get here, then we weren't able to find a free block */
+       return NULL;
+}
+
+/*!
+ * Set flags for a block
+ */
+static int vrom_set_flags(const struct vrom_data_block_t* block,
+               uint16_t flags)
+{
+       const struct vrom_sector_idx_t* sector =
+               vrom_get_sector_hdr(vrom_sector_num(block));
+       uint8_t block_num = vrom_block_num(block);
+
+       /* Compute the new flags settings */
+       flags = sector->flags[block_num] & ~flags;
+
+       /* Write them */
+       if (FLASH_ProgramHalfWord(
+                       (uint32_t)(&(sector->flags[block_num])),
+                       flags) != FLASH_COMPLETE)
+               return -EIO;
+       return 0;
+}
+
+/*!
+ * Mark a block as being obsolete
+ */
+static int vrom_mark_obsolete(const struct vrom_data_block_t* block)
+{
+       /* Blank out the CRC */
+       if (FLASH_ProgramWord((uint32_t)(&(block->header.crc32)), 0)
+                       != FLASH_COMPLETE)
+               return -EIO;
+       /* Blank out the ROM ID */
+       if (FLASH_ProgramByte((uint32_t)(&(block->header.rom)), 0)
+                       != FLASH_COMPLETE)
+               return -EIO;
+       /* Blank out the index */
+       if (FLASH_ProgramByte((uint32_t)(&(block->header.idx)), 0)
+                       != FLASH_COMPLETE)
+               return -EIO;
+       /* Blank out the size */
+       if (FLASH_ProgramByte((uint32_t)&(block->header.size), 0)
+                       != FLASH_COMPLETE)
+               return -EIO;
+       /* Blank out the reserved byte */
+       if (FLASH_ProgramByte((uint32_t)&(block->header.reserved), 0)
+                       != FLASH_COMPLETE)
+               return -EIO;
+       /* Blank out the flags */
+       return vrom_set_flags(block, -1);
+}
+
+/*!
+ * Write a new block.
+ */
+static int vrom_write_block(uint8_t rom, uint8_t idx, uint8_t size,
+               const uint8_t* in)
+{
+       /* Find a new home for the block */
+       const struct vrom_data_block_t* block = vrom_find_free(0);
+       struct vrom_data_block_t new_block;
+       uint8_t* out = (uint8_t*)(block);
+       uint32_t rem = sizeof(new_block);
+       int res;
+
+       if (!block)
+               return -ENOSPC;
+
+       /* Prepare the new block */
+       memset(&new_block, 0xff, sizeof(new_block));
+       new_block.header.rom = rom;
+       new_block.header.idx = idx;
+       new_block.header.size = size;
+       memcpy(new_block.data, in, size);
+       new_block.header.crc32 = vrom_crc32(&new_block);
+
+       /* Start writing out the block */
+       in = (uint8_t*)(&new_block);
+       rem = VROM_BLOCK_SZ;
+       while(rem) {
+               if (*out != *in) {
+                       if (FLASH_ProgramByte((uint32_t)out, *in)
+                                       != FLASH_COMPLETE)
+                               /* Failed! */
+                               return -EIO;
+               }
+               in++;
+               out++;
+               rem--;
+       }
+       res = vrom_set_flags(block, VROM_SFLAGS_USED);
+       if (res < 0)
+               return res;
+       return size;
+}
+
+/*!
+ * Re-write the given block if needed.
+ */
+static int vrom_rewrite_block(const struct vrom_data_block_t* block,
+               uint8_t size, const uint8_t* in)
+{
+       uint8_t obsolete = 0;
+       uint8_t rom = block->header.rom;
+       uint8_t idx = block->header.idx;
+       const uint8_t* cmp_block = block->data;
+       const uint8_t* cmp_in = in;
+       uint8_t cmp_sz = size;
+       int res;
+       while(cmp_sz) {
+               if (*cmp_block != *cmp_in) {
+                       obsolete = 1;
+                       break;
+               }
+               cmp_sz--;
+               cmp_block++;
+               cmp_in++;
+       }
+
+       if (!obsolete)
+               /* The block is fine, leave it be. */
+               return size;
+
+       /* Mark the block as obsolete */
+       res = vrom_mark_obsolete(block);
+       if (res)
+               return res;
+       return vrom_write_block(rom, idx, size, in);
+}
+
+/*!
+ * Overwrite the start of a block.
+ */
+static int vrom_overwrite_block(
+               const struct vrom_data_block_t* block,
+               uint8_t offset, uint8_t size, const uint8_t* in)
+{
+       uint8_t data[VROM_DATA_SZ];
+       uint16_t block_sz = block->header.size;
+       int res;
+
+       if (!offset && (size >= block->header.size))
+               /* Complete overwrite */
+               return vrom_rewrite_block(block, size, in);
+
+       if (offset) {
+               /* Overwrite end of block, possible expansion */
+               block_sz = offset + size;
+               if (block_sz > VROM_DATA_SZ)
+                       block_sz = VROM_DATA_SZ;
+               memcpy(data, block->data, offset);
+               memcpy(&data[offset], in, block_sz - offset);
+       } else {
+               /* Overwrite start of block, no size change */
+               memcpy(data, in, size);
+               memcpy(&data[size], &(block->data[size]),
+                               block_sz - size);
+       }
+
+       res = vrom_rewrite_block(block, block_sz, data);
+       if (res < 0)
+               return res;
+       return block_sz;
+}
+
+/*!
+ * Write data to the virtual EEPROM.
+ */
+static int vrom_write_internal(uint8_t rom,
+               uint16_t offset, uint16_t size, const uint8_t* in)
+{
+       /* Figure out our starting block and offset */
+       uint8_t block_idx       = offset / VROM_DATA_SZ;
+       uint8_t block_offset    = offset % VROM_DATA_SZ;
+       int count = 0;
+
+       /* Locate the first block */
+       const struct vrom_data_block_t* block = vrom_find(rom, block_idx);
+
+       uint8_t block_sz = VROM_DATA_SZ;
+       if (block_sz > (size + block_offset))
+               block_sz = size + block_offset;
+
+       if (!block) {
+               /* Create a new block */
+               uint8_t data[VROM_DATA_SZ];
+               int res;
+               memset(data, 0xff, sizeof(data));
+               memcpy(&data[block_offset], in,
+                               block_sz-block_offset);
+               res = vrom_write_block(rom, block_idx, block_sz, data);
+               if (res < 0)
+                       return res;
+       } else {
+               /* Overwrite block */
+               int res = vrom_overwrite_block(block, block_offset,
+                               block_sz, in);
+               if (res < 0)
+                       return res;
+               count += block_sz;
+       }
+
+       block_idx++;
+       size -= block_sz - block_offset;
+
+       while(size) {
+               /* Work out how much data to write */
+               if (size < VROM_DATA_SZ)
+                       block_sz = size;
+               else
+                       block_sz = VROM_DATA_SZ;
+
+               int res;
+
+               /* Is there a block covering this range? */
+               block = vrom_find(rom, block_idx);
+               if (block)
+                       res = vrom_overwrite_block(
+                                       block, 0, block_sz, in);
+               else
+                       res = vrom_write_block(rom, block_idx,
+                                       block_sz, in);
+
+               if (res < 0)
+                       return res;
+
+               /* Successful write */
+               count += res;
+               size -= res;
+               in += res;
+               offset += res;
+       }
+       return count;
+}
+
+/*!
+ * Read data from a virtual EEPROM.
+ * @param      rom             ROM ID to start reading.
+ * @param      offset          Address offset into ROM to start reading.
+ * @param      size            Number of bytes to read from ROM.
+ * @param      out             Buffer to write ROM content to.
+ * @returns                    Number of bytes read from ROM.
+ * @retval     -ENXIO          ROM not found
+ * @retval     -ESPIPE         Offset past end of ROM.
+ */
+int vrom_read(uint8_t rom, uint16_t offset, uint16_t size, void* out)
+{
+       /* Figure out our starting block and offset */
+       uint8_t block_idx       = offset / VROM_DATA_SZ;
+       uint8_t block_offset    = offset % VROM_DATA_SZ;
+       uint8_t block_sz;
+       int count = 0;
+       uint8_t* out_ptr = (uint8_t*)out;
+
+       /* Locate the first block */
+       const struct vrom_data_block_t* block = vrom_find(rom, block_idx);
+
+       if (!block)
+               return -ENXIO;
+
+       if (block_offset >= block->header.size)
+               return -ESPIPE;
+
+       /* Copy the initial bytes */
+       block_sz = block->header.size - block_offset;
+       if (block_sz > size)
+               block_sz = size;
+       memcpy(out_ptr, &(block->data[block_offset]), block_sz);
+       out_ptr += block_sz;
+       size -= block_sz;
+       count += block_sz;
+
+       if (size) {
+               /* Look for the next block */
+               block = vrom_find(rom, ++block_idx);
+               while(size && block) {
+                       if (block->header.size <= size)
+                               block_sz = block->header.size;
+                       else
+                               block_sz = size;
+                       memcpy(out_ptr, block->data, block_sz);
+                       out_ptr += block_sz;
+                       size -= block_sz;
+                       count += block_sz;
+
+                       block = vrom_find(rom, ++block_idx);
+               }
+       }
+
+       return count;
+}
+
+/*!
+ * Write data to a virtual EEPROM.
+ * @param      rom             ROM ID to start writing.
+ * @param      offset          Address offset into ROM to start writing.
+ * @param      size            Number of bytes to write to ROM.
+ * @param      in              Buffer to write ROM content from.
+ * @returns                    Number of bytes written to ROM.
+ * @retval     -EIO            Programming failed
+ * @retval     -ENOSPC         No free blocks available
+ */
+int vrom_write(uint8_t rom, uint16_t offset, uint16_t size,
+               const void* in)
+{
+       int res;
+       FLASH_Unlock();
+       FLASH_ClearFlag(FLASH_FLAG_EOP
+                       | FLASH_FLAG_OPERR
+                       | FLASH_FLAG_WRPERR
+                       | FLASH_FLAG_PGAERR
+                       | FLASH_FLAG_PGPERR
+                       | FLASH_FLAG_PGSERR);
+       res = vrom_write_internal(rom, offset, size, in);
+       FLASH_Lock();
+       return res;
+}
+
+/*!
+ * Erase a virtual EEPROM.
+ * @param      rom             ROM ID to erase.
+ * @returns                    Number of bytes written to ROM.
+ * @retval     -EIO            Programming failed
+ * @retval     -ENOSPC         No free blocks available
+ */
+int vrom_erase(uint8_t rom)
+{
+       int sector, block;
+       FLASH_Unlock();
+       FLASH_ClearFlag(FLASH_FLAG_EOP
+                       | FLASH_FLAG_OPERR
+                       | FLASH_FLAG_WRPERR
+                       | FLASH_FLAG_PGAERR
+                       | FLASH_FLAG_PGPERR
+                       | FLASH_FLAG_PGSERR);
+       for (sector = 0; sector < VROM_SECT_CNT; sector++) {
+               const struct vrom_sector_idx_t* sect_hdr
+                       = vrom_get_sector_hdr(sector);
+               if (sect_hdr->cycles_remain == UINT32_MAX)
+                       /* unformatted */
+                       continue;
+               for (block = 0; block < VROM_SECT_APP_BLOCK_CNT; block++) {
+                       int res;
+                       const struct vrom_data_block_t* block_ptr;
+                       if (sect_hdr->flags[block] == UINT16_MAX)
+                               /* unformatted */
+                               continue;
+                       if (sect_hdr->flags[block] == 0)
+                               /* obsolete */
+                               continue;
+
+                       block_ptr = vrom_get_block(sector, block);
+
+                       /* Verify the content */
+                       if (vrom_crc32(block_ptr)
+                                       != block_ptr->header.crc32)
+                               /* corrupt */
+                               continue;
+
+                       if (block_ptr->header.rom != rom)
+                               /* different ROM */
+                               continue;
+
+                       /*
+                        * Block is valid, for the correct ROM.  Mark it
+                        * obsolete.
+                        */
+                       res = vrom_mark_obsolete(block_ptr);
+                       if (res)
+                               return res;
+               }
+       }
+       return 0;
+}
diff --git a/codec2/branches/0.7/stm32/src/system_stm32f4xx.c b/codec2/branches/0.7/stm32/src/system_stm32f4xx.c
new file mode 100644 (file)
index 0000000..b26dd20
--- /dev/null
@@ -0,0 +1,584 @@
+/**
+ ******************************************************************************
+ * @file    system_stm32f4xx.c
+ * @author  MCD Application Team
+ * @version V1.0.1
+ * @date    10-July-2012
+ * @brief   CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
+ *          This file contains the system clock configuration for STM32F4xx devices,
+ *          and is generated by the clock configuration tool
+ *          stm32f4xx_Clock_Configuration_V1.0.1.xls
+ *
+ * 1.  This file provides two functions and one global variable to be called from
+ *     user application:
+ *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
+ *                      and Divider factors, AHB/APBx prescalers and Flash settings),
+ *                      depending on the configuration made in the clock xls tool.
+ *                      This function is called at startup just after reset and
+ *                      before branch to main program. This call is made inside
+ *                      the "startup_stm32f4xx.s" file.
+ *
+ *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ *                                  by the user application to setup the SysTick
+ *                                  timer or configure other parameters.
+ *
+ *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ *                                 be called whenever the core clock is changed
+ *                                 during program execution.
+ *
+ * 2. After each device reset the HSI (16 MHz) is used as system clock source.
+ *    Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to
+ *    configure the system clock before to branch to main program.
+ *
+ * 3. If the system clock source selected by user fails to startup, the SystemInit()
+ *    function will do nothing and HSI still used as system clock source. User can
+ *    add some code to deal with this issue inside the SetSysClock() function.
+ *
+ * 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define
+ *    in "stm32f4xx.h" file. When HSE is used as system clock source, directly or
+ *    through PLL, and you are using different crystal you have to adapt the HSE
+ *    value to your own configuration.
+ *
+ * 5. This file configures the system clock as follows:
+ *=============================================================================
+ *=============================================================================
+ *        Supported STM32F4xx device revision    | Rev A
+ *-----------------------------------------------------------------------------
+ *        System Clock source                    | PLL (HSE)
+ *-----------------------------------------------------------------------------
+ *        SYSCLK(Hz)                             | 168000000
+ *-----------------------------------------------------------------------------
+ *        HCLK(Hz)                               | 168000000
+ *-----------------------------------------------------------------------------
+ *        AHB Prescaler                          | 1
+ *-----------------------------------------------------------------------------
+ *        APB1 Prescaler                         | 4
+ *-----------------------------------------------------------------------------
+ *        APB2 Prescaler                         | 2
+ *-----------------------------------------------------------------------------
+ *        HSE Frequency(Hz)                      | 8000000
+ *-----------------------------------------------------------------------------
+ *        PLL_M                                  | 8
+ *-----------------------------------------------------------------------------
+ *        PLL_N                                  | 336
+ *-----------------------------------------------------------------------------
+ *        PLL_P                                  | 2
+ *-----------------------------------------------------------------------------
+ *        PLL_Q                                  | 7
+ *-----------------------------------------------------------------------------
+ *        PLLI2S_N                               | 352
+ *-----------------------------------------------------------------------------
+ *        PLLI2S_R                               | 2
+ *-----------------------------------------------------------------------------
+ *        I2S input clock(Hz)                    | 176000000
+ *                                               |
+ *        To achieve the following I2S config:   |
+ *         - Master clock output (MCKO): OFF     |
+ *         - Frame wide                : 16bit   |
+ *         - Error %                   : 0,0000  |
+ *         - Prescaler Odd factor (ODD): 1       |
+ *         - Linear prescaler (DIV)    : 14      |
+ *-----------------------------------------------------------------------------
+ *        VDD(V)                                 | 3,3
+ *-----------------------------------------------------------------------------
+ *        Main regulator output voltage          | Scale1 mode
+ *-----------------------------------------------------------------------------
+ *        Flash Latency(WS)                      | 5
+ *-----------------------------------------------------------------------------
+ *        Prefetch Buffer                        | OFF
+ *-----------------------------------------------------------------------------
+ *        Instruction cache                      | ON
+ *-----------------------------------------------------------------------------
+ *        Data cache                             | ON
+ *-----------------------------------------------------------------------------
+ *        Require 48MHz for USB OTG FS,          | Enabled
+ *        SDIO and RNG clock                     |
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32f4xx_system
+ * @{
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32f4xx.h"
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Defines
+ * @{
+ */
+
+/************************* Miscellaneous Configuration ************************/
+/*!< Uncomment the following line if you need to use external SRAM mounted
+     on STM324xG_EVAL board as data memory  */
+/* #define DATA_IN_ExtSRAM */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+     Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
+                                   This value must be a multiple of 0x200. */
+/******************************************************************************/
+
+/************************* PLL Parameters *************************************/
+/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
+#define PLL_M      8
+#define PLL_N      336
+
+/* SYSCLK = PLL_VCO / PLL_P */
+#define PLL_P      2
+
+/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
+#define PLL_Q      7
+
+/* PLLI2S_VCO = (HSE_VALUE Or HSI_VALUE / PLL_M) * PLLI2S_N
+   I2SCLK = PLLI2S_VCO / PLLI2S_R */
+#define START_I2SCLOCK         0
+#define PLLI2S_N               352
+#define PLLI2S_R               2
+
+/******************************************************************************/
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Variables
+ * @{
+ */
+
+uint32_t SystemCoreClock = 168000000;
+
+__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+static void SetSysClock(void);
+#ifdef DATA_IN_ExtSRAM
+static void SystemInit_ExtMemCtl(void);
+#endif /* DATA_IN_ExtSRAM */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32F4xx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief  Setup the microcontroller system
+ *         Initialize the Embedded Flash Interface, the PLL and update the
+ *         SystemFrequency variable.
+ * @param  None
+ * @retval None
+ */
+void SystemInit(void)
+{
+       /* FPU settings ------------------------------------------------------------*/
+#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+       SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
+#endif
+       /* Reset the RCC clock configuration to the default reset state ------------*/
+       /* Set HSION bit */
+       RCC->CR |= (uint32_t)0x00000001;
+
+       /* Reset CFGR register */
+       RCC->CFGR = 0x00000000;
+
+       /* Reset HSEON, CSSON and PLLON bits */
+       RCC->CR &= (uint32_t)0xFEF6FFFF;
+
+       /* Reset PLLCFGR register */
+       RCC->PLLCFGR = 0x24003010;
+
+       /* Reset HSEBYP bit */
+       RCC->CR &= (uint32_t)0xFFFBFFFF;
+
+       /* Disable all interrupts */
+       RCC->CIR = 0x00000000;
+
+#ifdef DATA_IN_ExtSRAM
+       SystemInit_ExtMemCtl();
+#endif /* DATA_IN_ExtSRAM */
+
+       /* Configure the System clock source, PLL Multiplier and Divider factors,
+     AHB/APBx prescalers and Flash settings ----------------------------------*/
+       SetSysClock();
+
+       /* Configure the Vector Table location add offset address ------------------*/
+#ifdef VECT_TAB_SRAM
+       SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
+#else
+       SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+}
+
+/**
+ * @brief  Update SystemCoreClock variable according to Clock Register Values.
+ *         The SystemCoreClock variable contains the core clock (HCLK), it can
+ *         be used by the user application to setup the SysTick timer or configure
+ *         other parameters.
+ *
+ * @note   Each time the core clock (HCLK) changes, this function must be called
+ *         to update SystemCoreClock variable value. Otherwise, any configuration
+ *         based on this variable will be incorrect.
+ *
+ * @note   - The system frequency computed by this function is not the real
+ *           frequency in the chip. It is calculated based on the predefined
+ *           constant and the selected clock source:
+ *
+ *           - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
+ *
+ *           - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
+ *
+ *           - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
+ *             or HSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ *         (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value
+ *             16 MHz) but the real value may vary depending on the variations
+ *             in voltage and temperature.
+ *
+ *         (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value
+ *              25 MHz), user has to ensure that HSE_VALUE is same as the real
+ *              frequency of the crystal used. Otherwise, this function may
+ *              have wrong result.
+ *
+ *         - The result of this function could be not correct when using fractional
+ *           value for HSE crystal.
+ *
+ * @param  None
+ * @retval None
+ */
+void SystemCoreClockUpdate(void)
+{
+       uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
+
+       /* Get SYSCLK source -------------------------------------------------------*/
+       tmp = RCC->CFGR & RCC_CFGR_SWS;
+
+       switch (tmp)
+       {
+       case 0x00:  /* HSI used as system clock source */
+               SystemCoreClock = HSI_VALUE;
+               break;
+       case 0x04:  /* HSE used as system clock source */
+               SystemCoreClock = HSE_VALUE;
+               break;
+       case 0x08:  /* PLL used as system clock source */
+
+               /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
+         SYSCLK = PLL_VCO / PLL_P
+                */
+               pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
+               pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
+
+               if (pllsource != 0)
+               {
+                       /* HSE used as PLL clock source */
+                       pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+               }
+               else
+               {
+                       /* HSI used as PLL clock source */
+                       pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
+               }
+
+               pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
+               SystemCoreClock = pllvco/pllp;
+               break;
+       default:
+               SystemCoreClock = HSI_VALUE;
+               break;
+       }
+       /* Compute HCLK frequency --------------------------------------------------*/
+       /* Get HCLK prescaler */
+       tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
+       /* HCLK frequency */
+       SystemCoreClock >>= tmp;
+}
+
+/**
+ * @brief  Configures the System clock source, PLL Multiplier and Divider factors,
+ *         AHB/APBx prescalers and Flash settings
+ * @Note   This function should be called only once the RCC clock configuration
+ *         is reset to the default reset state (done in SystemInit() function).
+ * @param  None
+ * @retval None
+ */
+static void SetSysClock(void)
+{
+       /******************************************************************************/
+       /*            PLL (clocked by HSE) used as System clock source                */
+       /******************************************************************************/
+       __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
+
+       /* Enable HSE */
+       RCC->CR |= ((uint32_t)RCC_CR_HSEON);
+
+       /* Wait till HSE is ready and if Time out is reached exit */
+       do
+       {
+               HSEStatus = RCC->CR & RCC_CR_HSERDY;
+               StartUpCounter++;
+       } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
+
+       if ((RCC->CR & RCC_CR_HSERDY) != RESET)
+       {
+               HSEStatus = (uint32_t)0x01;
+       }
+       else
+       {
+               HSEStatus = (uint32_t)0x00;
+       }
+
+       if (HSEStatus == (uint32_t)0x01)
+       {
+               /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */
+               RCC->APB1ENR |= RCC_APB1ENR_PWREN;
+               PWR->CR |= PWR_CR_VOS;
+
+               /* HCLK = SYSCLK / 1*/
+               RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
+
+               /* PCLK2 = HCLK / 2*/
+               RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
+
+               /* PCLK1 = HCLK / 4*/
+               RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
+
+               /* Configure the main PLL */
+               RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
+                               (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
+
+               /* Enable the main PLL */
+               RCC->CR |= RCC_CR_PLLON;
+
+               /* Wait till the main PLL is ready */
+               while((RCC->CR & RCC_CR_PLLRDY) == 0)
+               {
+               }
+
+               /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
+               FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
+
+               /* Select the main PLL as system clock source */
+               RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
+               RCC->CFGR |= RCC_CFGR_SW_PLL;
+
+               /* Wait till the main PLL is used as system clock source */
+               while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
+               {
+               }
+       }
+       else
+       { /* If HSE fails to start-up, the application will have wrong clock
+         configuration. User can add here some code to deal with this error */
+       }
+
+
+       /******************************************************************************/
+       /*                          I2S clock configuration                           */
+       /******************************************************************************/
+
+#if START_I2SCLOCK
+       /* PLLI2S clock used as I2S clock source */
+       RCC->CFGR &= ~RCC_CFGR_I2SSRC;
+
+       /* Configure PLLI2S */
+       RCC->PLLI2SCFGR = (PLLI2S_N << 6) | (PLLI2S_R << 28);
+
+       /* Enable PLLI2S */
+       RCC->CR |= ((uint32_t)RCC_CR_PLLI2SON);
+
+       /* Wait till PLLI2S is ready */
+       while((RCC->CR & RCC_CR_PLLI2SRDY) == 0)
+       {
+       }
+#endif
+}
+
+/**
+ * @brief  Setup the external memory controller. Called in startup_stm32f4xx.s
+ *          before jump to __main
+ * @param  None
+ * @retval None
+ */
+#ifdef DATA_IN_ExtSRAM
+/**
+ * @brief  Setup the external memory controller.
+ *         Called in startup_stm32f4xx.s before jump to main.
+ *         This function configures the external SRAM mounted on STM324xG_EVAL board
+ *         This SRAM will be used as program data memory (including heap and stack).
+ * @param  None
+ * @retval None
+ */
+void SystemInit_ExtMemCtl(void)
+{
+       /*-- GPIOs Configuration -----------------------------------------------------*/
+       /*
+ +-------------------+--------------------+------------------+------------------+
+ +                       SRAM pins assignment                                   +
+ +-------------------+--------------------+------------------+------------------+
+ | PD0  <-> FSMC_D2  | PE0  <-> FSMC_NBL0 | PF0  <-> FSMC_A0 | PG0 <-> FSMC_A10 |
+ | PD1  <-> FSMC_D3  | PE1  <-> FSMC_NBL1 | PF1  <-> FSMC_A1 | PG1 <-> FSMC_A11 |
+ | PD4  <-> FSMC_NOE | PE3  <-> FSMC_A19  | PF2  <-> FSMC_A2 | PG2 <-> FSMC_A12 |
+ | PD5  <-> FSMC_NWE | PE4  <-> FSMC_A20  | PF3  <-> FSMC_A3 | PG3 <-> FSMC_A13 |
+ | PD8  <-> FSMC_D13 | PE7  <-> FSMC_D4   | PF4  <-> FSMC_A4 | PG4 <-> FSMC_A14 |
+ | PD9  <-> FSMC_D14 | PE8  <-> FSMC_D5   | PF5  <-> FSMC_A5 | PG5 <-> FSMC_A15 |
+ | PD10 <-> FSMC_D15 | PE9  <-> FSMC_D6   | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 |
+ | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7   | PF13 <-> FSMC_A7 |------------------+
+ | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8   | PF14 <-> FSMC_A8 |
+ | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9   | PF15 <-> FSMC_A9 |
+ | PD14 <-> FSMC_D0  | PE13 <-> FSMC_D10  |------------------+
+ | PD15 <-> FSMC_D1  | PE14 <-> FSMC_D11  |
+ |                   | PE15 <-> FSMC_D12  |
+ +-------------------+--------------------+
+        */
+       /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
+       RCC->AHB1ENR   = 0x00000078;
+
+       /* Connect PDx pins to FSMC Alternate function */
+       GPIOD->AFR[0]  = 0x00cc00cc;
+       GPIOD->AFR[1]  = 0xcc0ccccc;
+       /* Configure PDx pins in Alternate function mode */
+       GPIOD->MODER   = 0xaaaa0a0a;
+       /* Configure PDx pins speed to 100 MHz */
+       GPIOD->OSPEEDR = 0xffff0f0f;
+       /* Configure PDx pins Output type to push-pull */
+       GPIOD->OTYPER  = 0x00000000;
+       /* No pull-up, pull-down for PDx pins */
+       GPIOD->PUPDR   = 0x00000000;
+
+       /* Connect PEx pins to FSMC Alternate function */
+       GPIOE->AFR[0]  = 0xc00cc0cc;
+       GPIOE->AFR[1]  = 0xcccccccc;
+       /* Configure PEx pins in Alternate function mode */
+       GPIOE->MODER   = 0xaaaa828a;
+       /* Configure PEx pins speed to 100 MHz */
+       GPIOE->OSPEEDR = 0xffffc3cf;
+       /* Configure PEx pins Output type to push-pull */
+       GPIOE->OTYPER  = 0x00000000;
+       /* No pull-up, pull-down for PEx pins */
+       GPIOE->PUPDR   = 0x00000000;
+
+       /* Connect PFx pins to FSMC Alternate function */
+       GPIOF->AFR[0]  = 0x00cccccc;
+       GPIOF->AFR[1]  = 0xcccc0000;
+       /* Configure PFx pins in Alternate function mode */
+       GPIOF->MODER   = 0xaa000aaa;
+       /* Configure PFx pins speed to 100 MHz */
+       GPIOF->OSPEEDR = 0xff000fff;
+       /* Configure PFx pins Output type to push-pull */
+       GPIOF->OTYPER  = 0x00000000;
+       /* No pull-up, pull-down for PFx pins */
+       GPIOF->PUPDR   = 0x00000000;
+
+       /* Connect PGx pins to FSMC Alternate function */
+       GPIOG->AFR[0]  = 0x00cccccc;
+       GPIOG->AFR[1]  = 0x000000c0;
+       /* Configure PGx pins in Alternate function mode */
+       GPIOG->MODER   = 0x00080aaa;
+       /* Configure PGx pins speed to 100 MHz */
+       GPIOG->OSPEEDR = 0x000c0fff;
+       /* Configure PGx pins Output type to push-pull */
+       GPIOG->OTYPER  = 0x00000000;
+       /* No pull-up, pull-down for PGx pins */
+       GPIOG->PUPDR   = 0x00000000;
+
+       /*-- FSMC Configuration ------------------------------------------------------*/
+       /* Enable the FSMC interface clock */
+       RCC->AHB3ENR         = 0x00000001;
+
+       /* Configure and enable Bank1_SRAM2 */
+       FSMC_Bank1->BTCR[2]  = 0x00001015;
+       FSMC_Bank1->BTCR[3]  = 0x00010603;
+       FSMC_Bank1E->BWTR[2] = 0x0fffffff;
+       /*
+  Bank1_SRAM2 is configured as follow:
+
+  p.FSMC_AddressSetupTime = 3;
+  p.FSMC_AddressHoldTime = 0;
+  p.FSMC_DataSetupTime = 6;
+  p.FSMC_BusTurnAroundDuration = 1;
+  p.FSMC_CLKDivision = 0;
+  p.FSMC_DataLatency = 0;
+  p.FSMC_AccessMode = FSMC_AccessMode_A;
+
+  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2;
+  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM;
+  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
+  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
+  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
+  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
+  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
+  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;
+  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
+        */
+}
+#endif /* DATA_IN_ExtSRAM */
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/src/timer_ut.c b/codec2/branches/0.7/stm32/src/timer_ut.c
new file mode 100644 (file)
index 0000000..1e9dcc4
--- /dev/null
@@ -0,0 +1,179 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: timer_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 3 Jan 2014
+
+  Unit test STM32F4 timer hardware.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_rcc.h"
+
+#include "gdb_stdio.h"
+
+#define TIM1_CCR3_ADDRESS    0x4001223C
+
+TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
+TIM_OCInitTypeDef  TIM_OCInitStructure;
+TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
+uint16_t uhTimerPeriod;
+uint16_t aSRC_Buffer[3] = {0, 0, 0};
+
+void Timer1Config();
+#define FS  3500000
+
+int main(void){
+    Timer1Config();
+ }
+
+/* DR: TIM_Config configures a couple of I/O pins for PWM output from
+   Timer1 Channel 3.  Note I dont think any of this is needed, except
+   perhaps to check timer frequency.  Can be removed down the track. */
+
+/**
+  * @brief  Configure the TIM1 Pins.
+  * @param  None
+  * @retval None
+  */
+static void TIM_Config(void)
+{
+  GPIO_InitTypeDef GPIO_InitStructure;
+
+  /* GPIOA and GPIOB clock enable */
+  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB, ENABLE);
+
+  /* GPIOA Configuration: Channel 3 as alternate function push-pull */
+  /* Discovery board pin PA10 */
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
+  GPIO_Init(GPIOA, &GPIO_InitStructure);
+  GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_TIM1);
+
+  /* GPIOB Configuration: Channel 3N as alternate function push-pull */
+  /* Discovery board pin PB15 */
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
+  GPIO_Init(GPIOB, &GPIO_InitStructure);
+  GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_TIM1);
+}
+
+void Timer1Config() {
+
+    /* TIM Configuration */
+
+    TIM_Config();
+
+    /* TIM1 example -------------------------------------------------
+
+       TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2
+       prescaler is different from 1.
+       TIM1CLK = 2 * PCLK2
+       PCLK2 = HCLK / 2
+       => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock
+
+       TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock
+       SystemCoreClock is set to 168 MHz for STM32F4xx devices.
+
+       The objective is to configure TIM1 channel 3 to generate complementary PWM
+       signal with a frequency equal to F KHz:
+       - TIM1_Period = (SystemCoreClock / F) - 1
+
+       The number of this repetitive requests is defined by the TIM1 Repetion counter,
+       each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new
+       value defined by the aSRC_Buffer.
+
+       Note:
+       SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file.
+       Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate()
+       function to update SystemCoreClock variable value. Otherwise, any configuration
+       based on this variable will be incorrect.
+       -----------------------------------------------------------------------------*/
+
+    /* Compute the value to be set in ARR regiter to generate signal frequency at FS Hz */
+    uhTimerPeriod = (SystemCoreClock / FS ) - 1;
+    /* Compute CCR1 value to generate a duty cycle at 50% */
+    aSRC_Buffer[0] = (uint16_t) (((uint32_t) 5 * (uhTimerPeriod - 1)) / 10);
+    /* Compute CCR1 value to generate a duty cycle at 37.5% */
+    aSRC_Buffer[1] = (uint16_t) (((uint32_t) 375 * (uhTimerPeriod - 1)) / 1000);
+    /* Compute CCR1 value to generate a duty cycle at 25% */
+    aSRC_Buffer[2] = (uint16_t) (((uint32_t) 25 * (uhTimerPeriod - 1)) / 100);
+
+    /* TIM1 Peripheral Configuration -------------------------------------------*/
+    /* TIM1 clock enable */
+    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
+
+    /* Time Base configuration */
+
+    TIM_DeInit(TIM1);
+    TIM_TimeBaseStructure.TIM_Prescaler = 0;
+    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
+    TIM_TimeBaseStructure.TIM_Period = uhTimerPeriod;
+    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
+    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
+
+    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
+
+    /* Channel 3 Configuration in PWM mode */
+
+    /* I think we just ned to enable channel 3 somehow, but without
+       (or optionally with) actual ouput to a GPIO pin.  */
+
+    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
+    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
+    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
+    TIM_OCInitStructure.TIM_Pulse = aSRC_Buffer[0];
+    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
+    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
+    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
+    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
+
+    TIM_OC3Init(TIM1, &TIM_OCInitStructure);
+
+    /* Enable preload feature */
+    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
+
+    /* Automatic Output enable, Break, dead time and lock configuration*/
+    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
+    TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
+    //TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;
+    TIM_BDTRInitStructure.TIM_DeadTime = 11;
+    //TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
+    //TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
+    TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
+
+    TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
+
+    /* TIM1 counter enable */
+    TIM_Cmd(TIM1, ENABLE);
+
+    /* Main Output Enable */
+    TIM_CtrlPWMOutputs(TIM1, ENABLE);
+}
+
diff --git a/codec2/branches/0.7/stm32/src/tm_stm32f4_gpio.c b/codec2/branches/0.7/stm32/src/tm_stm32f4_gpio.c
new file mode 100644 (file)
index 0000000..7089632
--- /dev/null
@@ -0,0 +1,238 @@
+/**    
+ * |----------------------------------------------------------------------
+ * | Copyright (C) Tilen Majerle, 2015
+ * | 
+ * | This program is free software: you can redistribute it and/or modify
+ * | it under the terms of the GNU General Public License as published by
+ * | the Free Software Foundation, either version 3 of the License, or
+ * | any later version.
+ * |  
+ * | This program is distributed in the hope that it will be useful,
+ * | but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * | GNU General Public License for more details.
+ * | 
+ * | You should have received a copy of the GNU General Public License
+ * | along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * |----------------------------------------------------------------------
+ */
+#include "tm_stm32f4_gpio.h"
+
+/* Private function */
+static uint16_t GPIO_UsedPins[11] = {0,0,0,0,0,0,0,0,0,0,0};
+
+/* Private functions */
+void TM_GPIO_INT_EnableClock(GPIO_TypeDef* GPIOx);
+void TM_GPIO_INT_DisableClock(GPIO_TypeDef* GPIOx);
+void TM_GPIO_INT_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed);
+
+void TM_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed) {        
+       /* Check input */
+       if (GPIO_Pin == 0x00) {
+               return;
+       }
+       
+       /* Enable clock for GPIO */
+       TM_GPIO_INT_EnableClock(GPIOx);
+       
+       /* Do initialization */
+       TM_GPIO_INT_Init(GPIOx, GPIO_Pin, GPIO_Mode, GPIO_OType, GPIO_PuPd, GPIO_Speed);
+}
+
+void TM_GPIO_InitAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed, uint8_t Alternate) {
+       uint32_t pinpos;
+
+       /* Check input */
+       if (GPIO_Pin == 0x00) {
+               return;
+       }
+       
+       /* Enable GPIOx clock */
+       TM_GPIO_INT_EnableClock(GPIOx);
+       
+       /* Set alternate functions for all pins */
+       for (pinpos = 0; pinpos < 0x10; pinpos++) {
+               /* Check pin */
+               if ((GPIO_Pin & (1 << pinpos)) == 0) {
+                       continue;
+               }
+               
+               /* Set alternate function */
+               GPIOx->AFR[pinpos >> 0x03] = (GPIOx->AFR[pinpos >> 0x03] & ~(0x0F << (4 * (pinpos & 0x07)))) | (Alternate << (4 * (pinpos & 0x07)));
+       }
+       
+       /* Do initialization */
+       TM_GPIO_INT_Init(GPIOx, GPIO_Pin, TM_GPIO_Mode_AF, GPIO_OType, GPIO_PuPd, GPIO_Speed);
+}
+
+void TM_GPIO_DeInit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       uint8_t ptr = TM_GPIO_GetPortSource(GPIOx);
+       
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 11 bits combination for analog mode */
+                       GPIOx->MODER |= (0x03 << (2 * i));
+                       
+                       /* Pin is not used */
+                       GPIO_UsedPins[ptr] &= ~(1 << i);
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsInput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 00 bits combination for input */
+                       GPIOx->MODER &= ~(0x03 << (2 * i));
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsOutput(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 01 bits combination for output */
+                       GPIOx->MODER = (GPIOx->MODER & ~(0x03 << (2 * i))) | (0x01 << (2 * i));
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsAnalog(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       /* Go through all pins */
+       for (i = 0x00; i < 0x10; i++) {
+               /* Pin is set */
+               if (GPIO_Pin & (1 << i)) {
+                       /* Set 11 bits combination for analog mode */
+                       GPIOx->MODER |= (0x03 << (2 * i));
+               }
+       }
+}
+
+void TM_GPIO_SetPinAsAlternate(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint8_t i;
+       
+       /* Set alternate functions for all pins */
+       for (i = 0; i < 0x10; i++) {
+               /* Check pin */
+               if ((GPIO_Pin & (1 << i)) == 0) {
+                       continue;
+               }
+               
+               /* Set alternate mode */
+               GPIOx->MODER = (GPIOx->MODER & ~(0x03 << (2 * i))) | (0x02 << (2 * i));
+       }
+}
+
+void TM_GPIO_SetPullResistor(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_PuPd_t GPIO_PuPd) {
+       uint8_t pinpos;
+       
+       /* Go through all pins */
+       for (pinpos = 0; pinpos < 0x10; pinpos++) {
+               /* Check if pin available */
+               if ((GPIO_Pin & (1 << pinpos)) == 0) {
+                       continue;
+               }
+
+               /* Set GPIO PUPD register */
+               GPIOx->PUPDR = (GPIOx->PUPDR & ~(0x03 << (2 * pinpos))) | ((uint32_t)(GPIO_PuPd << (2 * pinpos)));
+       }
+}
+
+void TM_GPIO_Lock(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) {
+       uint32_t d;
+       
+       /* Set GPIO pin with 16th bit set to 1 */
+       d = 0x00010000 | GPIO_Pin;
+       
+       /* Write to LCKR register */
+       GPIOx->LCKR = d;
+       GPIOx->LCKR = GPIO_Pin;
+       GPIOx->LCKR = d;
+       
+       /* Read twice */
+       (void)GPIOx->LCKR;
+       (void)GPIOx->LCKR;
+}
+
+uint16_t TM_GPIO_GetPinSource(uint16_t GPIO_Pin) {
+       uint16_t pinsource = 0;
+       
+       /* Get pinsource */
+       while (GPIO_Pin > 1) {
+               /* Increase pinsource */
+               pinsource++;
+               /* Shift right */
+               GPIO_Pin >>= 1;
+       }
+       
+       /* Return source */
+       return pinsource;
+}
+
+uint16_t TM_GPIO_GetPortSource(GPIO_TypeDef* GPIOx) {
+       /* Get port source number */
+       /* Offset from GPIOA                       Difference between 2 GPIO addresses */
+       return ((uint32_t)GPIOx - (GPIOA_BASE)) / ((GPIOB_BASE) - (GPIOA_BASE));
+}
+
+/* Private functions */
+void TM_GPIO_INT_EnableClock(GPIO_TypeDef* GPIOx) {
+       /* Set bit according to the 1 << portsourcenumber */
+       RCC->AHB1ENR |= (1 << TM_GPIO_GetPortSource(GPIOx));
+}
+
+void TM_GPIO_INT_DisableClock(GPIO_TypeDef* GPIOx) {
+       /* Clear bit according to the 1 << portsourcenumber */
+       RCC->AHB1ENR &= ~(1 << TM_GPIO_GetPortSource(GPIOx));
+}
+
+void TM_GPIO_INT_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed) {
+       uint8_t pinpos;
+       uint8_t ptr = TM_GPIO_GetPortSource(GPIOx);
+       
+       /* Go through all pins */
+       for (pinpos = 0; pinpos < 0x10; pinpos++) {
+               /* Check if pin available */
+               if ((GPIO_Pin & (1 << pinpos)) == 0) {
+                       continue;
+               }
+               
+               /* Pin is used */
+               GPIO_UsedPins[ptr] |= 1 << pinpos;
+               
+               /* Set GPIO PUPD register */
+               GPIOx->PUPDR = (GPIOx->PUPDR & ~(0x03 << (2 * pinpos))) | ((uint32_t)(GPIO_PuPd << (2 * pinpos)));
+               
+               /* Set GPIO MODE register */
+               GPIOx->MODER = (GPIOx->MODER & ~((uint32_t)(0x03 << (2 * pinpos)))) | ((uint32_t)(GPIO_Mode << (2 * pinpos)));
+               
+               /* Set only if output or alternate functions */
+               if (GPIO_Mode == TM_GPIO_Mode_OUT || GPIO_Mode == TM_GPIO_Mode_AF) {            
+                       /* Set GPIO OTYPE register */
+                       GPIOx->OTYPER = (GPIOx->OTYPER & ~(uint16_t)(0x01 << pinpos)) | ((uint16_t)(GPIO_OType << pinpos));
+                       
+                       /* Set GPIO OSPEED register */
+                       GPIOx->OSPEEDR = (GPIOx->OSPEEDR & ~((uint32_t)(0x03 << (2 * pinpos)))) | ((uint32_t)(GPIO_Speed << (2 * pinpos)));
+               }
+       }
+}
+
+uint16_t TM_GPIO_GetUsedPins(GPIO_TypeDef* GPIOx) {
+       /* Return used */
+       return GPIO_UsedPins[TM_GPIO_GetPortSource(GPIOx)];
+}
+
+uint16_t TM_GPIO_GetFreePins(GPIO_TypeDef* GPIOx) {
+       /* Return free pins */
+       return ~GPIO_UsedPins[TM_GPIO_GetPortSource(GPIOx)];
+}
diff --git a/codec2/branches/0.7/stm32/src/tm_stm32f4_mco_output.c b/codec2/branches/0.7/stm32/src/tm_stm32f4_mco_output.c
new file mode 100644 (file)
index 0000000..3261bda
--- /dev/null
@@ -0,0 +1,128 @@
+/**    \r
+ * |----------------------------------------------------------------------\r
+ * | Copyright (C) Tilen Majerle, 2014\r
+ * | \r
+ * | This program is free software: you can redistribute it and/or modify\r
+ * | it under the terms of the GNU General Public License as published by\r
+ * | the Free Software Foundation, either version 3 of the License, or\r
+ * | any later version.\r
+ * |  \r
+ * | This program is distributed in the hope that it will be useful,\r
+ * | but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * | GNU General Public License for more details.\r
+ * | \r
+ * | You should have received a copy of the GNU General Public License\r
+ * | along with this program.  If not, see <http://www.gnu.org/licenses/>.\r
+ * |----------------------------------------------------------------------\r
+ */\r
+#include "tm_stm32f4_mco_output.h"\r
+\r
+void TM_MCOOUTPUT_InitMCO1(void) {\r
+       /* Enable PA8 */\r
+       TM_GPIO_Init(GPIOA, GPIO_PIN_8, TM_GPIO_Mode_AF, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);\r
+}\r
+\r
+void TM_MCOOUTPUT_InitMCO2(void) {\r
+       /* Enable PC9 */\r
+       TM_GPIO_Init(GPIOC, GPIO_PIN_9, TM_GPIO_Mode_AF, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);\r
+}\r
+\r
+void TM_MCOOUTPUT_SetOutput1(TM_MCOOUTPUT1_Source_t Source, TM_MCOOUTPUT_Prescaler_t Prescaler) {\r
+       uint32_t presc = 0, src = 0;\r
+       \r
+       /* Get prescaler */\r
+       switch (Prescaler) {\r
+               case TM_MCOOUTPUT_Prescaler_1:\r
+                       presc = RCC_MCO1Div_1;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_2:\r
+                       presc = RCC_MCO1Div_2;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_3:\r
+                       presc = RCC_MCO1Div_3;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_4:\r
+                       presc = RCC_MCO1Div_4;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_5:\r
+                       presc = RCC_MCO1Div_5;\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       /* Get source */\r
+       switch (Source) {\r
+               case TM_MCOOUTPUT1_Source_HSE:\r
+                       src = RCC_MCO1Source_HSE;\r
+               \r
+                       /* Enable RCC HSE oscillator */\r
+                       RCC_HSEConfig(RCC_HSE_ON);\r
+                       break;\r
+               case TM_MCOOUTPUT1_Source_HSI:\r
+                       src = RCC_MCO1Source_HSI;\r
+                       break;\r
+               case TM_MCOOUTPUT1_Source_PLLCLK:\r
+                       src = RCC_MCO1Source_PLLCLK;\r
+                       break;\r
+               case TM_MCOOUTPUT1_Source_LSE:          \r
+                       src = RCC_MCO1Source_LSE;\r
+               \r
+                       /* Start LSE clock if available */\r
+                       RCC_LSEConfig(RCC_LSE_ON);\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       \r
+       /* Set source and prescaler  */\r
+       RCC_MCO1Config(src, presc);\r
+}\r
+\r
+void TM_MCOOUTPUT_SetOutput2(TM_MCOOUTPUT2_Source_t Source, TM_MCOOUTPUT_Prescaler_t Prescaler) {\r
+       uint32_t presc, src;\r
+       \r
+       /* Get prescaler */\r
+       switch (Prescaler) {\r
+               case TM_MCOOUTPUT_Prescaler_1:\r
+                       presc = RCC_MCO2Div_1;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_2:\r
+                       presc = RCC_MCO2Div_2;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_3:\r
+                       presc = RCC_MCO2Div_3;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_4:\r
+                       presc = RCC_MCO2Div_4;\r
+                       break;\r
+               case TM_MCOOUTPUT_Prescaler_5:\r
+                       presc = RCC_MCO2Div_5;\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       /* Get clock source */\r
+       switch (Source) {\r
+               case TM_MCOOUTPUT2_Source_SYSCLK:\r
+                       src = RCC_MCO2Source_SYSCLK;\r
+                       break;\r
+               case TM_MCOOUTPUT2_Source_PLLI2SCLK:\r
+                       src = RCC_MCO2Source_PLLI2SCLK;\r
+                       break;\r
+               case TM_MCOOUTPUT2_Source_HSE:\r
+                       src = RCC_MCO2Source_HSE;\r
+                       break;\r
+               case TM_MCOOUTPUT2_Source_PLLCLK:\r
+                       src = RCC_MCO2Source_PLLCLK;\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       \r
+       /* Set source and prescaler  */\r
+       RCC_MCO2Config(src, presc);\r
+}\r
diff --git a/codec2/branches/0.7/stm32/src/tone.c b/codec2/branches/0.7/stm32/src/tone.c
new file mode 100644 (file)
index 0000000..ab56792
--- /dev/null
@@ -0,0 +1,151 @@
+/*!
+ * Fixed-point tone generator.
+ *
+ * The code here implements a simple fixed-point tone generator that uses
+ * integer arithmetic to generate a sinusoid at a fixed sample rate of
+ * 16kHz.
+ *
+ * To set the initial state of the state machine, you specify a frequency
+ * and duration using tone_reset.  The corresponding C file embeds a
+ * sinusoid look-up table.  The total number of samples is computed for
+ * the given time and used to initialise 'remain', 'time' is initialised
+ * to 0, and 'step' gives the amount to increment 'time' by each iteration.
+ *
+ * The samples are retrieved by repeatedly calling tone_next.  This
+ * advances 'time' and decrements 'remain'.  The tone is complete when
+ * 'remain' is zero.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "tone.h"
+
+/*! Fixed-point shift factor */
+#define TONE_SHIFT     (12)
+
+/*! Static compiled quarter-sinusoid. */
+static const int16_t partial_sine[] = {
+   830,   2488,   4140,   5781,   7407,   9014,  10598,  12155,
+ 13681,  15171,  16623,  18031,  19394,  20707,  21967,  23170,
+ 24314,  25395,  26411,  27360,  28238,  29043,  29774,  30429,
+ 31006,  31503,  31919,  32253,  32504,  32672,  32756
+};
+
+/*! Length of quarter-sinusoid in samples */
+#define TONE_PART_SINE_LEN     (sizeof(partial_sine)\
+                       /sizeof(partial_sine[0]))
+
+/*! Total length of sinusoid */
+#define TONE_SINE_LEN  ((TONE_PART_SINE_LEN*4)+4)
+
+/*!
+ * Generate a sine from the quarter-waveform.
+ */
+static int16_t tone_sine(uint8_t sample)
+{
+       /* Key points */
+       if ((sample % (TONE_SINE_LEN/2)) == 0)
+               /* Zero crossings */
+               return 0;
+       if (sample == TONE_SINE_LEN/4)
+               /* Maximum */
+               return INT16_MAX;
+       if (sample == (3*TONE_SINE_LEN)/4)
+               /* Minimum */
+               return INT16_MIN;
+
+       if (sample < TONE_SINE_LEN/4)
+               /* First quarter of sine wave */
+               return partial_sine[sample-1];
+
+       if (sample < (TONE_SINE_LEN/2))
+               /* Second quarter */
+               return partial_sine[(TONE_SINE_LEN/2)-sample-1];
+       if (sample < ((3*TONE_SINE_LEN)/4))
+               /* Third quarter */
+               return -partial_sine[(sample-3) % TONE_PART_SINE_LEN];
+       if (sample < TONE_SINE_LEN)
+               /* Final quarter */
+               return -partial_sine[TONE_SINE_LEN-sample-1];
+       /* We should not get here */
+       return 0;
+}
+
+/*!
+ * Re-set the tone generator.
+ *
+ * @param      tone_gen        Tone generator to reset.
+ * @param      freq            Frequency in Hz, 0 = silence.
+ * @param      duration        Duration in milliseconds.  0 to stop.
+ */
+void tone_reset(
+       struct tone_gen_t* const tone_gen,
+       uint16_t freq, uint16_t duration)
+{
+       if (freq)
+               /* Compute the time step */
+               tone_gen->step = (((2*freq*TONE_SINE_LEN) << TONE_SHIFT)
+                               / ((2*TONE_FS) + 1) + 1);
+       else
+               /* DC tone == silence */
+               tone_gen->step = 0;
+
+       /* Compute remaining samples */
+       tone_gen->remain = (uint16_t)(
+                       ((uint32_t)(TONE_FS * duration)) / 1000);
+
+       /* Initialise the sample counter */
+       tone_gen->sample = 0;
+}
+
+/*!
+ * Retrieve the next sample from the tone generator.
+ * @param      tone_gen        Tone generator to update.
+ */
+int16_t tone_next(
+       struct tone_gen_t* const tone_gen)
+{
+       if (!tone_gen)
+               return 0;
+       if (!tone_gen->remain)
+               return 0;
+       if (!tone_gen->step) {
+               /* Special case, emit silence */
+               tone_gen->remain--;
+               return 0;
+       }
+
+       /* Compute sample index */
+       uint16_t sample_int = ((tone_gen->sample) >> TONE_SHIFT)
+                               % TONE_SINE_LEN;
+
+       /* Advance tone generator state */
+       tone_gen->sample += tone_gen->step;
+       tone_gen->remain--;
+
+       return tone_sine(sample_int);
+}
+
+/*!
+ * Retrieve the current time in milliseconds.
+ */
+uint32_t tone_msec(const struct tone_gen_t* const tone_gen)
+{
+       uint64_t ms = tone_gen->sample;
+       ms *= 1000;
+       ms /= TONE_FS;
+       return ms >> TONE_SHIFT;
+}
diff --git a/codec2/branches/0.7/stm32/src/tot.c b/codec2/branches/0.7/stm32/src/tot.c
new file mode 100644 (file)
index 0000000..1fce495
--- /dev/null
@@ -0,0 +1,90 @@
+/*!
+ * Time-out timer.
+ *
+ * This is a simple time-out timer for ensuring a maximum transmission
+ * time is observed.  The time-out timer is configured with a total time
+ * in "ticks", which get counted down in an interrupt.
+ *
+ * When the "warning" level is reached, a flag is repeatedly set permit
+ * triggering of LEDs/sounds to warn the user that time is nearly up.
+ *
+ * Upon timeout, a separate flag is set to indicate timeout has taken
+ * place.
+ *
+ * Author Stuart Longland <me@vk4msl.id.au>
+ * Copyright (C) 2015 FreeDV project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.  This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "tot.h"
+
+/*!
+ * Reset the time-out timer.  This zeroes the counter and event flags.
+ */
+void tot_reset(struct tot_t * const tot)
+{
+       tot->event              = 0;
+       tot->remaining          = 0;
+       tot->warn_remain        = 0;
+       tot->ticks              = 0;
+}
+
+/*!
+ * Start the time-out timer ticking.
+ */
+void tot_start(struct tot_t * const tot, uint32_t tot_ticks,
+               uint16_t warn_ticks)
+{
+       tot->event              = TOT_EVT_START;
+       tot->warn_remain        = tot_ticks - warn_ticks;
+       tot->remaining          = tot_ticks;
+       tot->ticks              = tot->tick_period;
+}
+
+/*!
+ * Update the time-out timer state.
+ */
+void tot_update(struct tot_t * const tot)
+{
+       if (!tot->event)
+               /* We are not active */
+               return;
+
+       if (tot->event & TOT_EVT_DONE)
+               /* We are done, do not process */
+               return;
+
+       if (tot->ticks)
+               /* Wait for a tick to pass */
+               return;
+
+       /* One "tick" has passed */
+       if (!tot->remaining) {
+               /* Time-out reached, reset all flags except timeout */
+               tot->event      |= TOT_EVT_TIMEOUT | TOT_EVT_DONE;
+               return;
+       } else {
+               tot->remaining--;
+       }
+
+       if (!tot->warn_remain) {
+               /* Warning period has passed */
+               tot->event      |= TOT_EVT_WARN | TOT_EVT_WARN_NEXT;
+               tot->warn_remain = tot->remain_warn_ticks;
+       } else {
+               tot->warn_remain--;
+       }
+
+       tot->ticks = tot->tick_period;
+}
diff --git a/codec2/branches/0.7/stm32/src/tuner_ut.c b/codec2/branches/0.7/stm32/src/tuner_ut.c
new file mode 100644 (file)
index 0000000..9c752c0
--- /dev/null
@@ -0,0 +1,122 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tuner_ut.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 20 Feb 2015
+
+  Unit test for high speed ADC radio tuner, samples signal centred at
+  500kHz using Fs=2 MHz and uploads to host at Fs=10 kHz.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include "gdb_stdio.h"
+#include "stm32f4_dac.h"
+#include "stm32f4_adc_tuner.h"
+#include "iir_tuner.h"
+#include "sm1000_leds_switches.h"
+#include "../src/codec2_fm.h"
+#include "stm32f4xx.h"
+
+#define REC_TIME_SECS 10
+#define FS            50000
+#define N             5000
+
+extern int adc_overflow1;
+
+int main(void) {
+    float  tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM+N/2];
+    float  fm_out[N/2];
+    //float  dec_10[(N/2)/5];
+    short  dec_10_short[(N/2)];
+    int    bufs, i, j, k, fifo_sz, bn;
+    FILE  *ftuner;
+    struct FM *fm;
+
+    ftuner = fopen("tuner.raw", "wb");
+    if (ftuner == NULL) {
+        printf("Error opening input file: tuner.raw\n\nTerminating....\n");
+        exit(1);
+    }
+    bufs = FS*REC_TIME_SECS/N;
+    fifo_sz = ((4*N/ADC_TUNER_N)+1)*ADC_TUNER_N;
+    printf("Starting! bufs: %d %d\n", bufs, fifo_sz);
+
+    //dac_open(DAC_BUF_SZ);
+    adc_open(fifo_sz);
+    sm1000_leds_switches_init();
+
+    fm         = fm_create(N/2);
+    fm->Fs     = 44400.0;
+    fm->fm_max = 3000.0;
+    fm->fd     = 5000.0;
+    fm->fc     = fm->Fs/4;
+
+    i = 0; bn = 0;
+    while(1) {
+        /* wait for buffer of Fs=50kHz tuner output samples */
+
+        while(adc1_read((short *)&tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM], N) == -1);
+
+        /* The semi-hosting system can only handle Fs=16kHz and below so resample down
+           to Fs=10 kHz and convert to shorts */
+
+        #ifdef SSB
+        iir_tuner_dec_50_to_10(dec_10, &tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM], N/2);
+        for(j=0; j<IIR_TUNER_DEC_50_10_FILT_MEM; j++)
+            tuner_out[j] = tuner_out[j+N/2];
+        for(j=0; j<(N/2)/5; j++)
+            dec_10_short[j] = dec_10[j]/ADC_TUNER_M;
+        #else
+        GPIOE->ODR |= (1 << 3);
+        /*
+        for(j=0; j<N/2; j++)
+            tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM+j] = 0;
+        for(j=1; j<N/2; j+=4)
+            tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM+j] = 100;
+        for(j=3; j<N/2; j+=4)
+            tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM+j] = -100;
+        */
+        fm_demod(fm, fm_out, &tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM]);
+        GPIOE->ODR &= ~(1 << 3);
+
+        for(j=0,k=0; j<N/2; j+=5,k++)
+            dec_10_short[k+bn] = 16384*fm_out[j];
+        bn += (N/2)/5;
+        #endif
+
+        if ((bn == N/2) && (i < bufs)) {
+            //for(j=0; j<N/2; j++)
+            //    dec_10_short[j] = tuner_out[IIR_TUNER_DEC_50_10_FILT_MEM+j];
+            fwrite(dec_10_short, sizeof(short), (N/2), ftuner);
+            bn = 0;
+            i += 5;
+            //fwrite(dec_10_short, sizeof(short), (N/2)/5, ftuner);
+            //printf("%d %d\n", i, adc_overflow1);
+        }
+        if (i == bufs) {
+            printf("finished! %d\n", adc_overflow1);
+            fclose(ftuner);
+            i++;
+        }
+    }
+}
+
diff --git a/codec2/branches/0.7/stm32/src/usb_vcp_ut.c b/codec2/branches/0.7/stm32/src/usb_vcp_ut.c
new file mode 100644 (file)
index 0000000..d060a73
--- /dev/null
@@ -0,0 +1,96 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: usb_vcp_ut.c
+  AUTHOR......: xenovacivus
+  DATE CREATED: 31 August 2014
+
+  USB Virtual COM Port (VCP) unit test that I found here:
+
+    https://github.com/xenovacivus/STM32DiscoveryVCP
+
+  Remarkably, it compiled and ran first time, and even the LEDs blink
+  as advertised, they just happen to match the LEDs on the SM1000!
+  However the speed was capped at about 130 kB/s.  After a lot of
+  messing around I found suggestions in the comments from a similar
+  library here:
+
+    http://stm32f4-discovery.com/2014/08/library-24-virtual-com-port-vcp-stm32f4xx/
+
+  The key was changing APP_RX_DATA_SIZE in usbd_conf.h to 10000.  I
+  guess the previous size of 2048 was constraing the length of USB
+  packets, and the USB overhead meant slow throughput.  I could
+  achieve a max of 450 kB/s with this change, about 1/3 of the
+  theoretical 1.5 MB/s max for USB FS (12 Mbit/s).
+
+  I used this to test grabbing data from the STM32F4 Discovery:
+    $ sudo dd if=/dev/ttyACM0 of=/dev/null count=100
+    4+96 records in
+    44+1 records out
+    22615 bytes (23 kB) copied, 0.150884 s, 150 kB/s
+
+  However I occasionally see:
+    $ sudo dd if=/dev/ttyACM0 of=/dev/null count=100
+      dd: failed to open ‘/dev/ttyACM0’: Device or resource busy
+
+  Googling found some suggestion that this is due to "modem manager", however I
+  removed MM and the problem still exists.
+
+\*---------------------------------------------------------------------------*/
+
+#include <stm32f4xx.h>
+#include <stm32f4xx_gpio.h>
+#include "stm32f4_usb_vcp.h"
+#include "sm1000_leds_switches.h"
+
+volatile uint32_t ticker, buf_ticker;
+
+#define N 640*6
+
+short buf[N];
+
+int main(void) {
+    int i;
+
+    for(i=0; i<N; i++)
+        buf[i] = 0;
+    
+    sm1000_leds_switches_init();
+    usb_vcp_init();
+    SysTick_Config(SystemCoreClock/1000);
+
+    while (1) {
+
+        /* Blink the discovery red LED at 1Hz */
+
+        if (ticker > 500) {
+            GPIOD->BSRRH = GPIO_Pin_13;
+        }
+        if (ticker > 1000) {
+            ticker = 0;
+            GPIOD->BSRRL = GPIO_Pin_13;
+        }
+
+        /* Every 40ms send a buffer, simulates 16 bit samples at Fs=96kHz */
+
+        if (buf_ticker > 40) {
+            buf_ticker = 0;
+            led_pwr(1);
+            VCP_send_buffer((uint8_t*)buf, sizeof(buf));
+            led_pwr(0);
+        }
+
+    }
+
+    return 0;
+}
+
+/*
+ * Interrupt Handler
+ */
+
+void SysTick_Handler(void)
+{
+       ticker++;
+        buf_ticker++;
+}
+
diff --git a/codec2/branches/0.7/stm32/src/usb_vsp_ut.c b/codec2/branches/0.7/stm32/src/usb_vsp_ut.c
new file mode 100644 (file)
index 0000000..8f0c9f4
--- /dev/null
@@ -0,0 +1,192 @@
+
+#define HSE_VALUE ((uint32_t)8000000) /* STM32 discovery uses a 8Mhz external crystal */
+
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_rcc.h"
+#include "stm32f4xx_exti.h"
+#include "usbd_cdc_core.h"
+#include "usbd_usr.h"
+#include "usbd_desc.h"
+#include "usbd_cdc_vcp.h"
+#include "usb_dcd_int.h"
+
+volatile uint32_t ticker, downTicker;
+
+/*
+ * The USB data must be 4 byte aligned if DMA is enabled. This macro handles
+ * the alignment, if necessary (it's actually magic, but don't tell anyone).
+ */
+__ALIGN_BEGIN USB_OTG_CORE_HANDLE  USB_OTG_dev __ALIGN_END;
+
+
+void init();
+void ColorfulRingOfDeath(void);
+
+/*
+ * Define prototypes for interrupt handlers here. The conditional "extern"
+ * ensures the weak declarations from startup_stm32f4xx.c are overridden.
+ */
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+void SysTick_Handler(void);
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void OTG_FS_IRQHandler(void);
+void OTG_FS_WKUP_IRQHandler(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+int main(void)
+{
+       /* Set up the system clocks */
+       SystemInit();
+
+       /* Initialize USB, IO, SysTick, and all those other things you do in the morning */
+       init();
+
+
+       while (1)
+       {
+               /* Blink the orange LED at 1Hz */
+               if (500 == ticker)
+               {
+                       GPIOD->BSRRH = GPIO_Pin_13;
+               }
+               else if (1000 == ticker)
+               {
+                       ticker = 0;
+                       GPIOD->BSRRL = GPIO_Pin_13;
+               }
+
+
+               /* If there's data on the virtual serial port:
+                *  - Echo it back
+                *  - Turn the green LED on for 10ms
+                */
+               uint8_t theByte;
+               if (VCP_get_char(&theByte))
+               {
+                       VCP_put_char(theByte);
+
+
+                       GPIOD->BSRRL = GPIO_Pin_12;
+                       downTicker = 10;
+               }
+               if (0 == downTicker)
+               {
+                       GPIOD->BSRRH = GPIO_Pin_12;
+               }
+       }
+
+       return 0;
+}
+
+
+void init()
+{
+       /* STM32F4 discovery LEDs */
+       GPIO_InitTypeDef LED_Config;
+
+       /* Always remember to turn on the peripheral clock...  If not, you may be up till 3am debugging... */
+       RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
+       LED_Config.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
+       LED_Config.GPIO_Mode = GPIO_Mode_OUT;
+       LED_Config.GPIO_OType = GPIO_OType_PP;
+       LED_Config.GPIO_Speed = GPIO_Speed_25MHz;
+       LED_Config.GPIO_PuPd = GPIO_PuPd_NOPULL;
+       GPIO_Init(GPIOD, &LED_Config);
+
+
+
+       /* Setup SysTick or CROD! */
+       if (SysTick_Config(SystemCoreClock / 1000))
+       {
+               ColorfulRingOfDeath();
+       }
+
+
+       /* Setup USB */
+       USBD_Init(&USB_OTG_dev,
+                   USB_OTG_FS_CORE_ID,
+                   &USR_desc,
+                   &USBD_CDC_cb,
+                   &USR_cb);
+
+       return;
+}
+
+/*
+ * Call this to indicate a failure.  Blinks the STM32F4 discovery LEDs
+ * in sequence.  At 168Mhz, the blinking will be very fast - about 5 Hz.
+ * Keep that in mind when debugging, knowing the clock speed might help
+ * with debugging.
+ */
+void ColorfulRingOfDeath(void)
+{
+       uint16_t ring = 1;
+       while (1)
+       {
+               uint32_t count = 0;
+               while (count++ < 500000);
+
+               GPIOD->BSRRH = (ring << 12);
+               ring = ring << 1;
+               if (ring >= 1<<4)
+               {
+                       ring = 1;
+               }
+               GPIOD->BSRRL = (ring << 12);
+       }
+}
+
+/*
+ * Interrupt Handlers
+ */
+
+void SysTick_Handler(void)
+{
+       ticker++;
+       if (downTicker > 0)
+       {
+               downTicker--;
+       }
+}
+
+void NMI_Handler(void)       {}
+void HardFault_Handler(void) { ColorfulRingOfDeath(); }
+void MemManage_Handler(void) { ColorfulRingOfDeath(); }
+void BusFault_Handler(void)  { ColorfulRingOfDeath(); }
+void UsageFault_Handler(void){ ColorfulRingOfDeath(); }
+void SVC_Handler(void)       {}
+void DebugMon_Handler(void)  {}
+void PendSV_Handler(void)    {}
+
+void OTG_FS_IRQHandler(void)
+{
+  USBD_OTG_ISR_Handler (&USB_OTG_dev);
+}
+
+void OTG_FS_WKUP_IRQHandler(void)
+{
+  if(USB_OTG_dev.cfg.low_power)
+  {
+    *(uint32_t *)(0xE000ED10) &= 0xFFFFFFF9 ;
+    SystemInit();
+    USB_OTG_UngateClock(&USB_OTG_dev);
+  }
+  EXTI_ClearITPendingBit(EXTI_Line18);
+}
diff --git a/codec2/branches/0.7/stm32/stlink/elfsym.c b/codec2/branches/0.7/stm32/stlink/elfsym.c
new file mode 100644 (file)
index 0000000..f2d6ab5
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+  elfsym.c
+
+  Read symbol adresses from a .elf file.
+
+  Based on libelf-howto.c from: http://em386.blogspot.com
+
+  Unit test with:
+
+  gcc elfsym.c -o elfsym -D__UNITTEST__ -Wall -lelf
+  ./elfsym elf_file.elf
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <libelf.h>
+#include <gelf.h>
+#include "elfsym.h"
+
+#define ERR -1
+
+int elfsym_open(char file[]) {
+    int fd;                    /* File Descriptor             */
+    char *base_ptr;            /* ptr to our object in memory */
+    struct stat elf_stats;     /* fstat struct                */
+
+    if((fd = open(file, O_RDWR)) == ERR) {
+        printf("couldnt open %s\n", file);
+        return ERR;
+    }
+
+    if((fstat(fd, &elf_stats))) {
+        printf("could not fstat %s\n", file);
+        close(fd);
+        return ERR;
+    }
+
+    if((base_ptr = (char *) malloc(elf_stats.st_size)) == NULL) {
+        fprintf(stderr, "could not malloc\n");
+        close(fd);
+        return ERR;
+    }
+
+    if((read(fd, base_ptr, elf_stats.st_size)) < elf_stats.st_size) {
+        fprintf(stderr, "could not read %s\n", file);
+        free(base_ptr);
+        close(fd);
+        return ERR;
+    }
+
+    /* Check libelf version first */
+
+    if(elf_version(EV_CURRENT) == EV_NONE) {
+        fprintf(stderr, "WARNING Elf Library is out of date!\n");
+    }
+
+    free(base_ptr);
+
+    return fd;
+}
+
+
+void elfsym_close(int fd) {
+    close(fd);
+}
+
+unsigned int elfsym_get_symbol_address(int fd, char symbol_name[])
+{
+    Elf_Scn     *scn;              /* Section Descriptor          */
+    Elf_Data    *edata;            /* Data Descriptor             */
+    GElf_Sym     sym;             /* Symbol                      */
+    GElf_Shdr    shdr;             /* Section Header              */
+    Elf         *elf;              /* Our Elf pointer for libelf  */
+    unsigned int symbol_address;
+    int          symbol_count;
+    int          i;
+
+    /* Iterate through section headers, stop when we find symbols,
+       and check for match */
+
+    elf = elf_begin(fd, ELF_C_READ, NULL);
+    if (elf == 0) {
+        fprintf(stderr, "could not elf_begin\n");
+    }
+    symbol_address = 0;
+    scn = NULL;
+
+    while((scn = elf_nextscn(elf, scn)) != 0) {
+        gelf_getshdr(scn, &shdr);
+
+        // When we find a section header marked SHT_SYMTAB stop and get symbols
+        edata = NULL;
+        if(shdr.sh_type == SHT_SYMTAB) {
+            // edata points to our symbol table
+            edata = elf_getdata(scn, edata);
+
+            // how many symbols are there? this number comes from the size of
+            // the section divided by the entry size
+            symbol_count = shdr.sh_size / shdr.sh_entsize;
+
+            // loop through to grab all symbols
+            for(i = 0; i < symbol_count; i++) {
+                // libelf grabs the symbol data using gelf_getsym()
+                gelf_getsym(edata, i, &sym);
+
+                if (strcmp(symbol_name,
+                           elf_strptr(elf, shdr.sh_link, sym.st_name)) == 0) {
+                    symbol_address = sym.st_value;
+                }
+            }
+
+        }
+    }
+
+    return symbol_address;
+}
+
+#ifdef __UNITTEST__
+
+int main(int argc, char *argv[])
+{
+    int           fd;
+    unsigned int  flag_addr, ptr_addr, file_addr, len_addr;
+
+    fd = elfsym_open(argv[1]);
+    flag_addr = elfsym_get_symbol_address(fd, "syscalls_gdb_flag");
+    ptr_addr = elfsym_get_symbol_address(fd, "syscalls_gdb_ptr");
+    file_addr = elfsym_get_symbol_address(fd, "syscalls_gdb_file");
+    len_addr = elfsym_get_symbol_address(fd, "syscalls_gdb_len");
+    elfsym_close(fd);
+
+    printf("flag_addr: 0x%x\n", flag_addr);
+    printf("ptr_addr: 0x%x\n", ptr_addr);
+    printf("file_addr: 0x%x\n", file_addr);
+    printf("len_addr: 0x%x\n", len_addr);
+
+    return 0;
+}
+
+#endif
diff --git a/codec2/branches/0.7/stm32/stlink/elfsym.h b/codec2/branches/0.7/stm32/stlink/elfsym.h
new file mode 100644 (file)
index 0000000..fcd287a
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+  elfsym.h
+
+  Read symbol adresses from a .elf file.
+*/
+
+#ifndef __ELFSYM__
+#define __ELFSYM__
+
+int elfsym_open(char file[]);
+void elfsym_close(int fd);
+unsigned int elfsym_get_symbol_address(int fd, char symbol_name[]);
+
+#endif
diff --git a/codec2/branches/0.7/stm32/stlink/stlink.patch b/codec2/branches/0.7/stm32/stlink/stlink.patch
new file mode 100644 (file)
index 0000000..6f87450
--- /dev/null
@@ -0,0 +1,428 @@
+diff --git Makefile.am Makefile.am
+index a315dd7..7406216 100644
+--- Makefile.am
++++ Makefile.am
+@@ -7,7 +7,7 @@ bin_PROGRAMS = st-flash st-util
+ noinst_LIBRARIES      = libstlink.a
+ st_flash_SOURCES = flash/main.c
+-st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h
++st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c gdbserver/elfsym.c mingw/mingw.c mingw/mingw.h
+ CFILES = \
+       src/stlink-common.c \
+@@ -24,14 +24,14 @@ HFILES     = \
+ libstlink_a_SOURCES   =       $(CFILES) $(HFILES)
+-libstlink_a_CPPFLAGS  = -std=gnu99 -Wall -Wextra -O2
++libstlink_a_CPPFLAGS  = -std=gnu99 -Wall -Wextra -g
+ libstlink_a_LIBADD = $(LIBOBJS)
+ st_flash_LDADD        =       libstlink.a
+-st_flash_CPPFLAGS     = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
++st_flash_CPPFLAGS     = -std=gnu99 -Wall -Wextra -g  -I$(top_srcdir)/src -I$(top_srcdir)/mingw
+-st_util_LDADD =       libstlink.a
+-st_util_CPPFLAGS      = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
++st_util_LDADD =       libstlink.a -lelf
++st_util_CPPFLAGS      = -std=gnu99 -Wall -Wextra -g -I$(top_srcdir)/src -I$(top_srcdir)/mingw
+ EXTRA_DIST = autogen.sh
+diff --git gdbserver/Makefile gdbserver/Makefile
+index bd5c73d..6763388 100644
+--- gdbserver/Makefile
++++ gdbserver/Makefile
+@@ -1,12 +1,11 @@
+ PRG := st-util
+-OBJS = gdb-remote.o gdb-server.o
++OBJS = gdb-remote.o gdb-server.o elfsym.o
+ CFLAGS+=-g -Wall -Werror -std=gnu99 -I../src
+ LDFLAGS=-L.. -lstlink
+ # libusb location
+-LDFLAGS+=`pkg-config --libs libusb-1.0`
+-CFLAGS+=`pkg-config --cflags libusb-1.0`
++LDFLAGS+=`pkg-config --libs libusb-1.0` -lelfCFLAGS+=`pkg-config --cflags libusb-1.0`
+ all: $(PRG)
+diff --git gdbserver/gdb-server.c gdbserver/gdb-server.c
+index f92fc05..e54d136 100644
+--- gdbserver/gdb-server.c
++++ gdbserver/gdb-server.c
+@@ -1,11 +1,12 @@
+ /* -*- tab-width:8 -*- */
+-#define DEBUG 0
++//#define DEBUG 0
+ /*
+  Copyright (C)  2011 Peter Zotov <whitequark@whitequark.org>
+  Use of this source code is governed by a BSD-style
+  license that can be found in the LICENSE file.
+ */
++#include <assert.h>
+ #include <getopt.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -20,14 +21,29 @@
+ #include <arpa/inet.h>
+ #include <signal.h>
+ #endif
++#include <sys/stat.h>
++#include <unistd.h>
++#include <fcntl.h>
+ #include <stlink-common.h>
+ #include "gdb-remote.h"
++#include "elfsym.h"
+ #define DEFAULT_LOGGING_LEVEL 50
+ #define DEFAULT_GDB_LISTEN_PORT 4242
++/* stdio command codes from target */
++
++#define GDB_STDIO_PRINTF  1
++#define GDB_STDIO_FOPEN   2
++#define GDB_STDIO_FCLOSE  3
++#define GDB_STDIO_FWRITE  4
++#define GDB_STDIO_FREAD   5
++#define GDB_STDIO_FPRINTF 6
++
++#define MAX_STR 256
++
+ #define STRINGIFY_inner(name) #name
+ #define STRINGIFY(name) STRINGIFY_inner(name)
+@@ -46,11 +62,12 @@ typedef struct _st_state_t {
+     // "/dev/serial/by-id/usb-FTDI_TTL232R-3V3_FTE531X6-if00-port0" is only 58 chars
+     char devicename[100];
+     int logging_level;
+-      int listen_port;
++    int listen_port;
++    char elf_filename[255];
+ } st_state_t;
+-int serve(stlink_t *sl, int port);
++int serve(stlink_t *sl, int port, char *elf_filename);
+ char* make_memory_map(stlink_t *sl);
+@@ -76,13 +93,14 @@ int parse_options(int argc, char** argv, st_state_t *st) {
+       "  -p 4242, --listen_port=1234\n"
+       "\t\t\tSet the gdb server listen port. "
+       "(default port: " STRINGIFY(DEFAULT_GDB_LISTEN_PORT) ")\n"
++      "  -f <elf_filename>\tenable File I/O of target executable elf_filename"
+       ;
+     int option_index = 0;
+     int c;
+     int q;
+-    while ((c = getopt_long(argc, argv, "hv::d:s:1p:", long_options, &option_index)) != -1) {
++    while ((c = getopt_long(argc, argv, "hv::d:s:1p:1f:", long_options, &option_index)) != -1) {
+         switch (c) {
+         case 0:
+             printf("XXXXX Shouldn't really normally come here, only if there's no corresponding option\n");
+@@ -110,25 +128,29 @@ int parse_options(int argc, char** argv, st_state_t *st) {
+                 strcpy(st->devicename, optarg);
+             }
+             break;
+-              case '1':
+-                      st->stlink_version = 1;
+-                      break;
+-              case 's':
+-                      sscanf(optarg, "%i", &q);
+-                      if (q < 0 || q > 2) {
+-                              fprintf(stderr, "stlink version %d unknown!\n", q);
+-                              exit(EXIT_FAILURE);
+-                      }
+-                      st->stlink_version = q;
+-                      break;
+-              case 'p':
+-                      sscanf(optarg, "%i", &q);
+-                      if (q < 0) {
+-                              fprintf(stderr, "Can't use a negative port to listen on: %d\n", q);
+-                              exit(EXIT_FAILURE);
+-                      }
+-                      st->listen_port = q;
+-                      break;
++        case '1':
++            st->stlink_version = 1;
++            break;
++        case 's':
++            sscanf(optarg, "%i", &q);
++            if (q < 0 || q > 2) {
++                fprintf(stderr, "stlink version %d unknown!\n", q);
++                exit(EXIT_FAILURE);
++            }
++            st->stlink_version = q;
++            break;
++        case 'p':
++            sscanf(optarg, "%i", &q);
++            if (q < 0) {
++                fprintf(stderr, "Can't use a negative port to listen on: %d\n", q);
++                exit(EXIT_FAILURE);
++            }
++            st->listen_port = q;
++            break;
++        case 'f':
++            sscanf(optarg, "%s", st->elf_filename);
++            printf("-f arg; %s\n", st->elf_filename);
++            break;
+         }
+     }
+@@ -162,7 +184,7 @@ int main(int argc, char** argv) {
+               sl = stlink_v1_open(state.logging_level);
+               if(sl == NULL) return 1;
+               break;
+-    }
++        }
+       printf("Chip ID is %08x, Core ID is  %08x.\n", sl->chip_id, sl->core_id);
+@@ -177,7 +199,7 @@ int main(int argc, char** argv) {
+       }
+ #endif
+-      while(serve(sl, state.listen_port) == 0);
++      while(serve(sl, state.listen_port, state.elf_filename) == 0);
+ #ifdef __MINGW32__
+ winsock_error:
+@@ -625,7 +647,179 @@ error:
+       return error;
+ }
+-int serve(stlink_t *sl, int port) {
++static unsigned int func_addr, ret_addr, pstr1_addr, pstr2_addr;
++static unsigned int strlen1_addr, strlen2_addr, file_addr, ptr_addr;
++static unsigned int size_addr, nmem_addr;
++
++static void write_buffer(stlink_t *sl, int target_addr, char* buf, size_t size) {
++    /* write the buffer right after the loader */
++    size_t chunk = size & ~0x3;
++    size_t rem   = size & 0x3;
++
++    if (chunk) {
++        memcpy(sl->q_buf, buf, chunk);
++        stlink_write_mem32(sl, target_addr, chunk);
++    }
++    if (rem) {
++        memcpy(sl->q_buf, buf+chunk, rem);
++        stlink_write_mem8(sl, target_addr+chunk, rem);
++    }
++}
++
++static void read_buffer(stlink_t *sl, int target_addr, char* buf, size_t size) {
++    unsigned adj_start = target_addr % 4;
++    unsigned count_rnd = (size + adj_start + 4 - 1) / 4 * 4;
++    size_t i;
++
++    stlink_read_mem32(sl, target_addr - adj_start, count_rnd);
++
++    for(i=0; i<size; i++)
++        buf[i] = sl->q_buf[i + adj_start];
++}
++
++static void fileio(stlink_t *sl)
++{
++    int   func, pstr1, pstr2, strlen1, strlen2, ptr, size, nmem;
++    int   ret = 0;
++    FILE *file;
++    char  file_name[MAX_STR];
++    char  mode[MAX_STR];
++    char *buf;
++
++    stlink_read_mem32(sl, func_addr, 4);
++    func = read_uint32(sl->q_buf, 0);
++
++    /* func != 0 means target has requested a system call */
++
++    switch(func) {
++
++    case GDB_STDIO_PRINTF:
++        stlink_read_mem32(sl, pstr1_addr, 4);
++        pstr1 = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, strlen1_addr, 4);
++        strlen1 = read_uint32(sl->q_buf, 0);
++        buf = (char*)malloc(strlen1+1);
++        assert(buf != NULL);
++        read_buffer(sl, pstr1, buf, strlen1);
++        buf[strlen1] = 0;
++      #ifdef DEBUG
++        //printf("gdb_stdio printf pstr1: 0x%0x strlen1: %d  buf: %s\n", pstr1, strlen1, buf);
++        #endif
++        fputs(buf, stdout);
++        free(buf);
++
++       break;
++
++    case GDB_STDIO_FPRINTF:
++        stlink_read_mem32(sl, file_addr, 4);
++        file = (FILE*)read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, pstr1_addr, 4);
++        pstr1 = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, strlen1_addr, 4);
++        strlen1 = read_uint32(sl->q_buf, 0);
++        buf = (char*)malloc(strlen1+1);
++        assert(buf != NULL);
++        read_buffer(sl, pstr1, buf, strlen1);
++        buf[strlen1] = 0;
++      #ifdef DEBUG
++        //printf("gdb_stdio fprintf pstr1: 0x%0x strlen1: %d  buf: %s file: 0x%x\n", pstr1, strlen1, buf, (unsigned int)file);
++        #endif
++        fputs(buf, file);
++        free(buf);
++
++       break;
++
++    case GDB_STDIO_FOPEN:
++        stlink_read_mem32(sl, pstr1_addr, 4);
++        pstr1 = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, strlen1_addr, 4);
++        strlen1 = read_uint32(sl->q_buf, 0);
++        assert(strlen1 < MAX_STR);
++        read_buffer(sl, pstr1, file_name, strlen1);
++        file_name[strlen1] = 0;
++
++        stlink_read_mem32(sl, pstr2_addr, 4);
++        pstr2 = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, strlen2_addr, 4);
++        strlen2 = read_uint32(sl->q_buf, 0);
++        assert(strlen2 < MAX_STR);
++        read_buffer(sl, pstr2, mode, strlen2);
++        mode[strlen2] = 0;
++
++        file = fopen(file_name, mode);
++
++        ret = (int)file;
++      #ifdef DEBUG
++        printf("gdb_stdio fopen file_name: %s mode: %s file: 0x%x\n", file_name, mode, (unsigned int)file);
++        #endif
++        break;
++
++    case GDB_STDIO_FCLOSE:
++        stlink_read_mem32(sl, file_addr, 4);
++        file = (FILE*)read_uint32(sl->q_buf, 0);
++        fclose(file);
++
++      #ifdef DEBUG
++        printf("gdb_stdio fclose file: 0x%x\n", (unsigned int)file);
++        #endif
++        break;
++
++    case GDB_STDIO_FWRITE:
++        stlink_read_mem32(sl, ptr_addr, 4);
++        ptr = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, size_addr, 4);
++        size = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, nmem_addr, 4);
++        nmem = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, file_addr, 4);
++        file = (FILE*)read_uint32(sl->q_buf, 0);
++
++        buf = (char*)malloc(size*nmem);
++        assert(buf != NULL);
++        read_buffer(sl, ptr, buf, size*nmem);
++        ret = fwrite(buf, size, nmem, file);
++        free(buf);
++      #ifdef DEBUG
++        printf("gdb_stdio fwrite ptr: 0x%x size: %d nmem: %d file: 0x%x\n", 
++               ptr, size, nmem, (unsigned int)file);
++        #endif
++        break;
++
++    case GDB_STDIO_FREAD:
++        stlink_read_mem32(sl, ptr_addr, 4);
++        ptr = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, size_addr, 4);
++        size = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, nmem_addr, 4);
++        nmem = read_uint32(sl->q_buf, 0);
++        stlink_read_mem32(sl, file_addr, 4);
++        file = (FILE*)read_uint32(sl->q_buf, 0);
++
++        buf = (char*)malloc(size*nmem);
++        assert(buf != NULL);
++        ret = fread(buf, size, nmem, file);
++        write_buffer(sl, ptr, buf, size*nmem);
++        free(buf);
++
++      #ifdef DEBUG
++        printf("gdb_stdio fread ptr: 0x%x size: %d nmem: %d file: 0x%x\n", 
++               ptr, size, nmem, (unsigned int)file);
++        #endif
++        break;
++    }
++       
++    if (func) {
++        memcpy(sl->q_buf, &ret, sizeof(int));
++        stlink_write_mem32(sl, ret_addr, 4);
++
++        func = 0;
++        memcpy(sl->q_buf, &func, sizeof(int));
++        stlink_write_mem32(sl, func_addr, 4);
++    }
++}
++
++
++int serve(stlink_t *sl, int port, char *elf_filename) {
+       int sock = socket(AF_INET, SOCK_STREAM, 0);
+       if(sock < 0) {
+               perror("socket");
+@@ -650,7 +844,33 @@ int serve(stlink_t *sl, int port) {
+               perror("listen");
+               return 1;
+       }
+-
++
++        /* init for file I/O */
++
++        func_addr = ret_addr = pstr1_addr = pstr2_addr = strlen1_addr = strlen2_addr = 0;
++        file_addr = ptr_addr = size_addr = nmem_addr = 0;
++
++        printf("elf_filename: %s----------------------------------\n", elf_filename);
++        if (*elf_filename != 0) {
++            int fd = elfsym_open(elf_filename);
++            if (fd == -1)
++                exit(0);
++            func_addr = elfsym_get_symbol_address(fd, "gdb_stdio_func");
++            ret_addr = elfsym_get_symbol_address(fd, "gdb_stdio_ret");
++            pstr1_addr = elfsym_get_symbol_address(fd, "gdb_stdio_pstr1");
++            pstr2_addr = elfsym_get_symbol_address(fd, "gdb_stdio_pstr2");
++            strlen1_addr = elfsym_get_symbol_address(fd, "gdb_stdio_strlen1");
++            strlen2_addr = elfsym_get_symbol_address(fd, "gdb_stdio_strlen2");
++            file_addr = elfsym_get_symbol_address(fd, "gdb_stdio_file");
++            ptr_addr = elfsym_get_symbol_address(fd, "gdb_stdio_ptr");
++            size_addr = elfsym_get_symbol_address(fd, "gdb_stdio_size");
++            nmem_addr = elfsym_get_symbol_address(fd, "gdb_stdio_nmem");
++            elfsym_close(fd);
++            #ifdef DEBUG
++            printf("func_addr: 0x%x\n", func_addr);
++            #endif
++        }
++
+ start_again:
+       stlink_force_debug(sl);
+       stlink_reset(sl);
+@@ -924,8 +1144,13 @@ start_again:
+                               if(sl->core_stat == STLINK_CORE_HALTED) {
+                                       break;
+                               }
++                                
++                                /* file I/O if enabled */
++
++                                if (*elf_filename != 0)
++                                    fileio(sl);
+-                              usleep(100000);
++                              usleep(10000);
+                       }
+                       reply = strdup("S05"); // TRAP
diff --git a/codec2/branches/0.7/stm32/stm32_flash.ld b/codec2/branches/0.7/stm32/stm32_flash.ld
new file mode 100644 (file)
index 0000000..44f4792
--- /dev/null
@@ -0,0 +1,142 @@
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20020000;    /* end of 128K RAM on AHB bus*/
+
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0;      /* required amount of heap  */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+  /* ISR vectors *must* be placed here as they get mapped to address 0 */
+  VECTOR (rx)     : ORIGIN = 0x08000000, LENGTH = 16K
+  /* Virtual EEPROM area, we use the remaining 16kB blocks for this. */
+  EEPROM (rx)     : ORIGIN = 0x08004000, LENGTH = 48K
+  /* The rest of flash is used for program data */
+  FLASH (rx)      : ORIGIN = 0x08010000, LENGTH = 960K
+  /* Backup memory area */
+  BKPSRAM (rwx)   : ORIGIN = 0x40024000, LENGTH = 4K
+  /* Memory area */
+  RAM (rwx)       : ORIGIN = 0x20000000, LENGTH = 128K
+  /* Core Coupled Memory */
+  CCM (rwx)       : ORIGIN = 0x10000000, LENGTH = 64K
+}
+
+SECTIONS
+{
+  .isr_vector :
+  {
+    . = ALIGN(4);
+    KEEP(*(.isr_vector))
+    . = ALIGN(4);
+  } >VECTOR
+
+
+  .eeprom :
+  {
+    . = ALIGN(4);
+    KEEP(*(.eeprom))   /* special section for persistent data */
+    . = ORIGIN(EEPROM) + LENGTH(EEPROM) - 1;
+    BYTE(0xFF)
+    . = ALIGN(4);
+  } >EEPROM = 0xff
+
+  .bkpsram :
+  {
+    . = ALIGN(4);
+    KEEP(*(.bkpsram))
+    . = ALIGN(4);
+  } > BKPSRAM
+
+  .text :
+  {
+    . = ALIGN(4);
+    *(.text)           /* .text sections (code) */
+    *(.text*)          /* .text* sections (code) */
+    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
+    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
+    *(.glue_7)         /* glue arm to thumb code */
+    *(.glue_7t)        /* glue thumb to arm code */
+    *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    . = ALIGN(4);
+    _etext = .;        /* define a global symbols at end of code */
+    _exit = .;
+  } >FLASH
+
+
+   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH
+    .ARM : {
+    __exidx_start = .;
+      *(.ARM.exidx*)
+      __exidx_end = .;
+    } >FLASH
+
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array*))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  } >FLASH
+  .init_array :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array*))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  } >FLASH
+  .fini_array :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array*))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >FLASH
+
+  /* used by the startup to initialize data */
+  _sidata = .;
+
+  /* Initialized data sections goes into RAM, load LMA copy after code */
+  .data : AT ( _sidata )
+  {
+    . = ALIGN(4);
+    _sdata = .;        /* create a global symbol at data start */
+    *(.data)           /* .data sections */
+    *(.data*)          /* .data* sections */
+
+    . = ALIGN(4);
+    _edata = .;        /* define a global symbol at data end */
+  } >RAM
+
+  /* Uninitialized data section */
+  . = ALIGN(4);
+  .bss :
+  {
+    /* This is used by the startup in order to initialize the .bss secion */
+    _sbss = .;         /* define a global symbol at bss start */
+    __bss_start__ = _sbss;
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+
+    . = ALIGN(4);
+    _ebss = .;         /* define a global symbol at bss end */
+    __bss_end__ = _ebss;
+  } >RAM
+
+  /* User_heap_stack section, used to check that there is enough RAM left */
+  ._user_heap_stack :
+  {
+    . = ALIGN(4);
+    PROVIDE ( end = . );
+    PROVIDE ( _end = . );
+    . = . + _Min_Heap_Size;
+    . = . + _Min_Stack_Size;
+    . = ALIGN(4);
+  } >RAM
+}
diff --git a/codec2/branches/0.7/stm32/stm32_ram.ld b/codec2/branches/0.7/stm32/stm32_ram.ld
new file mode 100644 (file)
index 0000000..88c735a
--- /dev/null
@@ -0,0 +1,116 @@
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x20020000;    /* end of 128K RAM on AHB bus*/
+
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0;      /* required amount of heap  */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+  FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 1024K
+  RAM (rwx)       : ORIGIN = 0x20000000, LENGTH = 128K
+  CCM (rwx)       : ORIGIN = 0x10000000, LENGTH = 64K
+}
+
+SECTIONS
+{
+  .isr_vector :
+  {
+    . = ALIGN(4);
+    KEEP(*(.isr_vector))
+    . = ALIGN(4);
+  } >RAM
+
+  .text :
+  {
+    . = ALIGN(4);
+    *(.text)           /* .text sections (code) */
+    *(.text*)          /* .text* sections (code) */
+    *(.rodata)         /* .rodata sections (constants, strings, etc.) */
+    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */
+    *(.glue_7)         /* glue arm to thumb code */
+    *(.glue_7t)        /* glue thumb to arm code */
+       *(.eh_frame)
+
+    KEEP (*(.init))
+    KEEP (*(.fini))
+
+    . = ALIGN(4);
+    _etext = .;        /* define a global symbols at end of code */
+    _exit = .;
+  } >RAM
+
+
+   .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >RAM
+    .ARM : {
+    __exidx_start = .;
+      *(.ARM.exidx*)
+      __exidx_end = .;
+    } >RAM
+
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array*))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  } >RAM
+  .init_array :
+  {
+    PROVIDE_HIDDEN (__init_array_start = .);
+    KEEP (*(SORT(.init_array.*)))
+    KEEP (*(.init_array*))
+    PROVIDE_HIDDEN (__init_array_end = .);
+  } >RAM
+  .fini_array :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array*))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  } >RAM
+
+  /* used by the startup to initialize data */
+  _sidata = .;
+
+  /* Initialized data sections goes into RAM, load LMA copy after code */
+  .data : AT ( _sidata )
+  {
+    . = ALIGN(4);
+    _sdata = .;        /* create a global symbol at data start */
+    *(.data)           /* .data sections */
+    *(.data*)          /* .data* sections */
+
+    . = ALIGN(4);
+    _edata = .;        /* define a global symbol at data end */
+  } >RAM
+
+  /* Uninitialized data section */
+  . = ALIGN(4);
+  .bss :
+  {
+    /* This is used by the startup in order to initialize the .bss secion */
+    _sbss = .;         /* define a global symbol at bss start */
+    __bss_start__ = _sbss;
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+
+    . = ALIGN(4);
+    _ebss = .;         /* define a global symbol at bss end */
+    __bss_end__ = _ebss;
+  } >RAM
+
+  /* User_heap_stack section, used to check that there is enough RAM left */
+  ._user_heap_stack :
+  {
+    . = ALIGN(4);
+    PROVIDE ( end = . );
+    PROVIDE ( _end = . );
+    . = . + _Min_Heap_Size;
+    . = . + _Min_Stack_Size;
+    . = ALIGN(4);
+  } >RAM
+}
diff --git a/codec2/branches/0.7/stm32/usb_conf/usb_bsp.c b/codec2/branches/0.7/stm32/usb_conf/usb_bsp.c
new file mode 100644 (file)
index 0000000..e16e150
--- /dev/null
@@ -0,0 +1,337 @@
+/**
+  ******************************************************************************
+  * @file    usb_bsp.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    19-September-2011
+  * @brief   This file is responsible to offer board support package and is
+  *          configurable by user.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_bsp.h"
+#include "usbd_conf.h"
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx_gpio.h"
+#include "stm32f4xx_exti.h"
+#include "stm32f4xx_rcc.h"
+#include "misc.h"
+
+
+void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev) {
+
+}
+
+void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state) {
+
+}
+
+
+/**
+* @brief  USB_OTG_BSP_Init
+*         Initilizes BSP configurations
+* @param  None
+* @retval None
+*/
+
+void USB_OTG_BSP_Init(USB_OTG_CORE_HANDLE *pdev)
+{
+  GPIO_InitTypeDef GPIO_InitStructure;
+
+#ifndef USE_ULPI_PHY
+#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+  EXTI_InitTypeDef EXTI_InitStructure;
+  NVIC_InitTypeDef NVIC_InitStructure;
+#endif
+#endif
+
+
+ #ifdef USE_USB_OTG_FS
+
+  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA , ENABLE);
+
+  /* Configure SOF VBUS ID DM DP Pins */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8  |
+    GPIO_Pin_9  |
+      GPIO_Pin_11 |
+        GPIO_Pin_12;
+
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
+  GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+  GPIO_PinAFConfig(GPIOA,GPIO_PinSource8,GPIO_AF_OTG1_FS) ;
+  GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_OTG1_FS) ;
+  GPIO_PinAFConfig(GPIOA,GPIO_PinSource11,GPIO_AF_OTG1_FS) ;
+  GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_OTG1_FS) ;
+
+  /* this for ID line debug */
+
+
+  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10;
+  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
+  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_Init(GPIOA, &GPIO_InitStructure);
+  GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_OTG1_FS) ;
+
+  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
+  RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_OTG_FS, ENABLE) ;
+ #else // USE_USB_OTG_HS
+
+  #ifdef USE_ULPI_PHY // ULPI
+  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
+                         RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOH |
+                           RCC_AHB1Periph_GPIOI, ENABLE);
+
+
+  GPIO_PinAFConfig(GPIOA,GPIO_PinSource3, GPIO_AF_OTG2_HS) ; // D0
+  GPIO_PinAFConfig(GPIOA,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // CLK
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // D1
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource1, GPIO_AF_OTG2_HS) ; // D2
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource5, GPIO_AF_OTG2_HS) ; // D7
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_HS) ; // D3
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // D4
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_OTG2_HS) ; // D5
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_HS) ; // D6
+  GPIO_PinAFConfig(GPIOH,GPIO_PinSource4, GPIO_AF_OTG2_HS) ; // NXT
+  GPIO_PinAFConfig(GPIOI,GPIO_PinSource11,GPIO_AF_OTG2_HS) ; // DIR
+  GPIO_PinAFConfig(GPIOC,GPIO_PinSource0, GPIO_AF_OTG2_HS) ; // STP
+
+  // CLK
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+  // D0
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3  ;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
+  GPIO_Init(GPIOA, &GPIO_InitStructure);
+
+
+
+  // D1 D2 D3 D4 D5 D6 D7
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1  |
+    GPIO_Pin_5 | GPIO_Pin_10 |
+      GPIO_Pin_11| GPIO_Pin_12 |
+        GPIO_Pin_13 ;
+
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
+  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
+  GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+
+  // STP
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0  ;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_Init(GPIOC, &GPIO_InitStructure);
+
+  //NXT
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_Init(GPIOH, &GPIO_InitStructure);
+
+
+  //DIR
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_Init(GPIOI, &GPIO_InitStructure);
+
+
+  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS |
+                         RCC_AHB1Periph_OTG_HS_ULPI, ENABLE) ;
+
+  #else
+   #ifdef USE_I2C_PHY
+  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOB , ENABLE);
+  /* Configure RESET INTN SCL SDA (Phy/I2C) Pins */
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |
+    GPIO_Pin_1 |
+      GPIO_Pin_10 |
+        GPIO_Pin_11;
+
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource0,GPIO_AF_OTG2_FS) ;
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource1,GPIO_AF_OTG2_FS) ;
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource10,GPIO_AF_OTG2_FS) ;
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource11,GPIO_AF_OTG2_FS);
+  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ;
+
+   #else
+
+  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB , ENABLE);
+
+  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12  |
+    GPIO_Pin_13 |
+      GPIO_Pin_14 |
+        GPIO_Pin_15;
+
+  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
+  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
+  GPIO_Init(GPIOB, &GPIO_InitStructure);
+
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource12, GPIO_AF_OTG2_FS) ;
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_OTG2_FS) ;
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource14,GPIO_AF_OTG2_FS) ;
+  GPIO_PinAFConfig(GPIOB,GPIO_PinSource15,GPIO_AF_OTG2_FS) ;
+  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_OTG_HS, ENABLE) ;
+   #endif
+  #endif // USE_ULPI_PHY
+
+ #endif //USB_OTG_HS
+
+
+  /* enable the PWR clock */
+  RCC_APB1PeriphResetCmd(RCC_APB1Periph_PWR, ENABLE);
+
+  /* Configure the Key button in EXTI mode */
+  //STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);
+
+#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+  EXTI_ClearITPendingBit(EXTI_Line18);
+
+  EXTI_InitStructure.EXTI_Line = EXTI_Line18;
+  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+  EXTI_Init(&EXTI_InitStructure);
+
+  EXTI_ClearITPendingBit(EXTI_Line18);
+
+  NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_WKUP_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  EXTI_ClearITPendingBit(EXTI_Line18);
+#endif
+
+#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+  EXTI_ClearITPendingBit(EXTI_Line20);
+
+  EXTI_InitStructure.EXTI_Line = EXTI_Line20;
+  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
+  EXTI_Init(&EXTI_InitStructure);
+
+  EXTI_ClearITPendingBit(EXTI_Line20);
+
+  NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_WKUP_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  EXTI_ClearITPendingBit(EXTI_Line20);
+#endif
+
+  EXTI_ClearITPendingBit(EXTI_Line0);
+}
+/**
+* @brief  USB_OTG_BSP_EnableInterrupt
+*         Enabele USB Global interrupt
+* @param  None
+* @retval None
+*/
+void USB_OTG_BSP_EnableInterrupt(USB_OTG_CORE_HANDLE *pdev)
+{
+  NVIC_InitTypeDef NVIC_InitStructure;
+
+  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
+#ifdef USE_USB_OTG_HS
+  NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_IRQn;
+#else
+  NVIC_InitStructure.NVIC_IRQChannel = OTG_FS_IRQn;
+#endif
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
+  NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_OUT_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+
+  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
+  NVIC_InitStructure.NVIC_IRQChannel = OTG_HS_EP1_IN_IRQn;
+  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
+  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
+  NVIC_Init(&NVIC_InitStructure);
+#endif
+}
+/**
+* @brief  USB_OTG_BSP_uDelay
+*         This function provides delay time in micro sec
+* @param  usec : Value of delay required in micro sec
+* @retval None
+*/
+void USB_OTG_BSP_uDelay (const uint32_t usec)
+{
+  uint32_t count = 0;
+  const uint32_t utime = (120 * usec / 7);
+  do
+  {
+    if ( ++count > utime )
+    {
+      return ;
+    }
+  }
+  while (1);
+}
+
+
+/**
+* @brief  USB_OTG_BSP_mDelay
+*          This function provides delay time in milli sec
+* @param  msec : Value of delay required in milli sec
+* @retval None
+*/
+void USB_OTG_BSP_mDelay (const uint32_t msec)
+{
+  USB_OTG_BSP_uDelay(msec * 1000);
+}
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_conf/usb_bsp.h b/codec2/branches/0.7/stm32/usb_conf/usb_bsp.h
new file mode 100644 (file)
index 0000000..736f3d0
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+  ******************************************************************************
+  * @file    usb_bsp.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   Specific api's relative to the used hardware platform
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_BSP__H__
+#define __USB_BSP__H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "stm32f4xx.h"
+
+/** @addtogroup USB_OTG_DRIVER
+  * @{
+  */
+
+/** @defgroup USB_BSP
+  * @brief This file is the
+  * @{
+  */
+
+
+/** @defgroup USB_BSP_Exported_Defines
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_BSP_Exported_Types
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_BSP_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_BSP_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_BSP_Exported_FunctionsPrototype
+  * @{
+  */
+void BSP_Init(void);
+
+void USB_OTG_BSP_Init (USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_BSP_uDelay (const uint32_t usec);
+void USB_OTG_BSP_mDelay (const uint32_t msec);
+void USB_OTG_BSP_EnableInterrupt (USB_OTG_CORE_HANDLE *pdev);
+#ifdef USE_HOST_MODE
+void USB_OTG_BSP_ConfigVBUS(USB_OTG_CORE_HANDLE *pdev);
+void USB_OTG_BSP_DriveVBUS(USB_OTG_CORE_HANDLE *pdev,uint8_t state);
+#endif
+/**
+  * @}
+  */
+
+#endif //__USB_BSP__H__
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_conf/usb_conf.h b/codec2/branches/0.7/stm32/usb_conf/usb_conf.h
new file mode 100644 (file)
index 0000000..9fa5459
--- /dev/null
@@ -0,0 +1,287 @@
+/**
+  ******************************************************************************
+  * @file    usb_conf.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   general low level driver configuration
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CONF__H__
+#define __USB_CONF__H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+  * @{
+  */
+
+/** @defgroup USB_CONF
+  * @brief USB low level driver configuration file
+  * @{
+  */
+
+/** @defgroup USB_CONF_Exported_Defines
+  * @{
+  */
+
+/* USB Core and PHY interface configuration.
+   Tip: To avoid modifying these defines each time you need to change the USB
+        configuration, you can declare the needed define in your toolchain
+        compiler preprocessor.
+   */
+#ifndef USE_USB_OTG_FS
+ //#define USE_USB_OTG_FS
+#endif /* USE_USB_OTG_FS */
+
+#ifndef USE_USB_OTG_HS
+ //#define USE_USB_OTG_HS
+#endif /* USE_USB_OTG_HS */
+
+#ifndef USE_ULPI_PHY
+ //#define USE_ULPI_PHY
+#endif /* USE_ULPI_PHY */
+
+#ifndef USE_EMBEDDED_PHY
+ //#define USE_EMBEDDED_PHY
+#endif /* USE_EMBEDDED_PHY */
+
+#ifndef USE_I2C_PHY
+ //#define USE_I2C_PHY
+#endif /* USE_I2C_PHY */
+
+
+#ifdef USE_USB_OTG_FS
+ #define USB_OTG_FS_CORE
+#endif
+
+#ifdef USE_USB_OTG_HS
+ #define USB_OTG_HS_CORE
+#endif
+
+/*******************************************************************************
+*                      FIFO Size Configuration in Device mode
+*
+*  (i) Receive data FIFO size = RAM for setup packets +
+*                   OUT endpoint control information +
+*                   data OUT packets + miscellaneous
+*      Space = ONE 32-bits words
+*     --> RAM for setup packets = 10 spaces
+*        (n is the nbr of CTRL EPs the device core supports)
+*     --> OUT EP CTRL info      = 1 space
+*        (one space for status information written to the FIFO along with each
+*        received packet)
+*     --> data OUT packets      = (Largest Packet Size / 4) + 1 spaces
+*        (MINIMUM to receive packets)
+*     --> OR data OUT packets  = at least 2*(Largest Packet Size / 4) + 1 spaces
+*        (if high-bandwidth EP is enabled or multiple isochronous EPs)
+*     --> miscellaneous = 1 space per OUT EP
+*        (one space for transfer complete status information also pushed to the
+*        FIFO with each endpoint's last packet)
+*
+*  (ii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
+*       that particular IN EP. More space allocated in the IN EP Tx FIFO results
+*       in a better performance on the USB and can hide latencies on the AHB.
+*
+*  (iii) TXn min size = 16 words. (n  : Transmit FIFO index)
+*   (iv) When a TxFIFO is not used, the Configuration should be as follows:
+*       case 1 :  n > m    and Txn is not used    (n,m  : Transmit FIFO indexes)
+*       --> Txm can use the space allocated for Txn.
+*       case2  :  n < m    and Txn is not used    (n,m  : Transmit FIFO indexes)
+*       --> Txn should be configured with the minimum space of 16 words
+*  (v) The FIFO is used optimally when used TxFIFOs are allocated in the top
+*       of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
+*******************************************************************************/
+
+/*******************************************************************************
+*                     FIFO Size Configuration in Host mode
+*
+*  (i) Receive data FIFO size = (Largest Packet Size / 4) + 1 or
+*                             2x (Largest Packet Size / 4) + 1,  If a
+*                             high-bandwidth channel or multiple isochronous
+*                             channels are enabled
+*
+*  (ii) For the host nonperiodic Transmit FIFO is the largest maximum packet size
+*      for all supported nonperiodic OUT channels. Typically, a space
+*      corresponding to two Largest Packet Size is recommended.
+*
+*  (iii) The minimum amount of RAM required for Host periodic Transmit FIFO is
+*        the largest maximum packet size for all supported periodic OUT channels.
+*        If there is at least one High Bandwidth Isochronous OUT endpoint,
+*        then the space must be at least two times the maximum packet size for
+*        that channel.
+*******************************************************************************/
+
+/****************** USB OTG HS CONFIGURATION **********************************/
+#ifdef USB_OTG_HS_CORE
+ #define RX_FIFO_HS_SIZE                          512
+ #define TX0_FIFO_HS_SIZE                         512
+ #define TX1_FIFO_HS_SIZE                         512
+ #define TX2_FIFO_HS_SIZE                          0
+ #define TX3_FIFO_HS_SIZE                          0
+ #define TX4_FIFO_HS_SIZE                          0
+ #define TX5_FIFO_HS_SIZE                          0
+ #define TXH_NP_HS_FIFOSIZ                         96
+ #define TXH_P_HS_FIFOSIZ                          96
+
+ //#define USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+ //#define USB_OTG_HS_SOF_OUTPUT_ENABLED
+
+ //#define USB_OTG_INTERNAL_VBUS_ENABLED
+ #define USB_OTG_EXTERNAL_VBUS_ENABLED
+
+ #ifdef USE_ULPI_PHY
+  #define USB_OTG_ULPI_PHY_ENABLED
+ #endif
+ #ifdef USE_EMBEDDED_PHY
+   #define USB_OTG_EMBEDDED_PHY_ENABLED
+ #endif
+ #ifdef USE_I2C_PHY
+  #define USB_OTG_I2C_PHY_ENABLED
+ #endif
+//#define USB_OTG_HS_INTERNAL_DMA_ENABLED
+ #define USB_OTG_HS_DEDICATED_EP1_ENABLED
+#endif
+
+/****************** USB OTG FS CONFIGURATION **********************************/
+#ifdef USB_OTG_FS_CORE
+ #define RX_FIFO_FS_SIZE                          128
+ #define TX0_FIFO_FS_SIZE                          64
+ #define TX1_FIFO_FS_SIZE                         128
+ #define TX2_FIFO_FS_SIZE                          0
+ #define TX3_FIFO_FS_SIZE                          0
+ #define TXH_NP_FS_FIFOSIZ                         96
+ #define TXH_P_FS_FIFOSIZ                          96
+
+ //#define USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+ //#define USB_OTG_FS_SOF_OUTPUT_ENABLED
+#endif
+
+/****************** USB OTG MODE CONFIGURATION ********************************/
+//#define USE_HOST_MODE
+#define USE_DEVICE_MODE
+//#define USE_OTG_MODE
+
+
+#ifndef USB_OTG_FS_CORE
+ #ifndef USB_OTG_HS_CORE
+    #error  "USB_OTG_HS_CORE or USB_OTG_FS_CORE should be defined"
+ #endif
+#endif
+
+
+#ifndef USE_DEVICE_MODE
+ #ifndef USE_HOST_MODE
+    #error  "USE_DEVICE_MODE or USE_HOST_MODE should be defined"
+ #endif
+#endif
+
+#ifndef USE_USB_OTG_HS
+ #ifndef USE_USB_OTG_FS
+    #error  "USE_USB_OTG_HS or USE_USB_OTG_FS should be defined"
+ #endif
+#else //USE_USB_OTG_HS
+ #ifndef USE_ULPI_PHY
+  #ifndef USE_EMBEDDED_PHY
+   #ifndef USE_I2C_PHY
+     #error  "USE_ULPI_PHY or USE_EMBEDDED_PHY or USE_I2C_PHY should be defined"
+   #endif
+  #endif
+ #endif
+#endif
+
+/****************** C Compilers dependant keywords ****************************/
+/* In HS mode and when the DMA is used, all variables and data structures dealing
+   with the DMA during the transaction process should be 4-bytes aligned */
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined   (__GNUC__)        /* GNU Compiler */
+    #define __ALIGN_END    __attribute__ ((aligned (4)))
+    #define __ALIGN_BEGIN
+  #else
+    #define __ALIGN_END
+    #if defined   (__CC_ARM)      /* ARM Compiler */
+      #define __ALIGN_BEGIN    __align(4)
+    #elif defined (__ICCARM__)    /* IAR Compiler */
+      #define __ALIGN_BEGIN
+    #elif defined  (__TASKING__)  /* TASKING Compiler */
+      #define __ALIGN_BEGIN    __align(4)
+    #endif /* __CC_ARM */
+  #endif /* __GNUC__ */
+#else
+  #define __ALIGN_BEGIN
+  #define __ALIGN_END
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+/* __packed keyword used to decrease the data type alignment to 1-byte */
+#if defined (__CC_ARM)         /* ARM Compiler */
+  #define __packed    __packed
+#elif defined (__ICCARM__)     /* IAR Compiler */
+  #define __packed    __packed
+#elif defined   ( __GNUC__ )   /* GNU Compiler */
+  #define __packed    __attribute__ ((__packed__))
+#elif defined   (__TASKING__)  /* TASKING Compiler */
+  #define __packed    __unaligned
+#endif /* __CC_ARM */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_CONF_Exported_Types
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_CONF_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_CONF_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_CONF_Exported_FunctionsPrototype
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+#endif //__USB_CONF__H__
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_conf/usbd_conf.h b/codec2/branches/0.7/stm32/usb_conf/usbd_conf.h
new file mode 100644 (file)
index 0000000..9fc6d51
--- /dev/null
@@ -0,0 +1,97 @@
+/**
+  ******************************************************************************
+  * @file    usbd_conf.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   USB Device configuration file
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CONF__H__
+#define __USBD_CONF__H__
+
+/** @defgroup USB_CONF_Exported_Defines
+  * @{
+  */
+#define USBD_CFG_MAX_NUM                1
+#define USBD_ITF_MAX_NUM                1
+#define USB_MAX_STR_DESC_SIZ            100
+
+/** @defgroup USB_VCP_Class_Layer_Parameter
+  * @{
+  */
+#define CDC_IN_EP                       0x81  /* EP1 for data IN */
+#define CDC_OUT_EP                      0x01  /* EP1 for data OUT */
+#define CDC_CMD_EP                      0x82  /* EP2 for CDC commands */
+
+/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
+#ifdef USE_USB_OTG_HS
+ #define CDC_DATA_MAX_PACKET_SIZE       512  /* Endpoint IN & OUT Packet size */
+ #define CDC_CMD_PACKET_SZE             8    /* Control Endpoint Packet size */
+
+ #define CDC_IN_FRAME_INTERVAL          40   /* Number of micro-frames between IN transfers */
+ #define APP_RX_DATA_SIZE               2048 /* Total size of IN buffer:
+                                                APP_RX_DATA_SIZE*8/MAX_BAUDARATE*1000 should be > CDC_IN_FRAME_INTERVAL*8 */
+#else
+ #define CDC_DATA_MAX_PACKET_SIZE       64   /* Endpoint IN & OUT Packet size */
+ #define CDC_CMD_PACKET_SZE             8    /* Control Endpoint Packet size */
+
+ #define CDC_IN_FRAME_INTERVAL          5    /* Number of frames between IN transfers */
+
+ //#define APP_RX_DATA_SIZE               2048 /* Total size of IN buffer:  */
+ #define APP_RX_DATA_SIZE               10000 
+
+#endif /* USE_USB_OTG_HS */
+
+#define APP_FOPS                        VCP_fops
+/**
+  * @}
+  */
+
+/** @defgroup USB_CONF_Exported_Types
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_CONF_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_CONF_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_CONF_Exported_FunctionsPrototype
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+#endif //__USBD_CONF__H__
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_conf/usbd_desc.c b/codec2/branches/0.7/stm32/usb_conf/usbd_desc.c
new file mode 100644 (file)
index 0000000..c252633
--- /dev/null
@@ -0,0 +1,324 @@
+/**
+  ******************************************************************************
+  * @file    usbd_desc.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    19-September-2011
+  * @brief   This file provides the USBD descriptors and string formating method.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include <assert.h>
+#include "usbd_core.h"
+#include "usbd_desc.h"
+#include "usbd_req.h"
+#include "usbd_conf.h"
+#include "usb_regs.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_DESC
+  * @brief USBD descriptors module
+  * @{
+  */
+
+/** @defgroup USBD_DESC_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_DESC_Private_Defines
+  * @{
+  */
+
+#define USBD_VID                        0x0483
+
+#define USBD_PID                        0x5740
+
+/** @defgroup USB_String_Descriptors
+  * @{
+  */
+#define USBD_LANGID_STRING              0x409
+#define USBD_MANUFACTURER_STRING        "STMicroelectronics"
+
+#define USBD_PRODUCT_HS_STRING          "STM32 Virtual ComPort in HS mode"
+#define USBD_SERIALNUMBER_HS_STRING     "00000000050B"
+
+#define USBD_PRODUCT_FS_STRING          "STM32 Virtual ComPort in FS Mode"
+#define USBD_SERIALNUMBER_FS_STRING     "00000000050C"
+
+#define USBD_CONFIGURATION_HS_STRING    "VCP Config"
+#define USBD_INTERFACE_HS_STRING        "VCP Interface"
+
+#define USBD_CONFIGURATION_FS_STRING    "VCP Config"
+#define USBD_INTERFACE_FS_STRING        "VCP Interface"
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_DESC_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_DESC_Private_Variables
+  * @{
+  */
+
+USBD_DEVICE USR_desc =
+{
+  USBD_USR_DeviceDescriptor,
+  USBD_USR_LangIDStrDescriptor,
+  USBD_USR_ManufacturerStrDescriptor,
+  USBD_USR_ProductStrDescriptor,
+  USBD_USR_SerialStrDescriptor,
+  USBD_USR_ConfigStrDescriptor,
+  USBD_USR_InterfaceStrDescriptor,
+
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN uint8_t USBD_DeviceDesc[USB_SIZ_DEVICE_DESC] __ALIGN_END =
+  {
+    0x12,                       /*bLength */
+    USB_DEVICE_DESCRIPTOR_TYPE, /*bDescriptorType*/
+    0x00,                       /*bcdUSB */
+    0x02,
+    0x00,                       /*bDeviceClass*/
+    0x00,                       /*bDeviceSubClass*/
+    0x00,                       /*bDeviceProtocol*/
+    USB_OTG_MAX_EP0_SIZE,      /*bMaxPacketSize*/
+    LOBYTE(USBD_VID),           /*idVendor*/
+    HIBYTE(USBD_VID),           /*idVendor*/
+    LOBYTE(USBD_PID),           /*idVendor*/
+    HIBYTE(USBD_PID),           /*idVendor*/
+    0x00,                       /*bcdDevice rel. 2.00*/
+    0x02,
+    USBD_IDX_MFC_STR,           /*Index of manufacturer  string*/
+    USBD_IDX_PRODUCT_STR,       /*Index of product string*/
+    USBD_IDX_SERIAL_STR,        /*Index of serial number string*/
+    USBD_CFG_MAX_NUM            /*bNumConfigurations*/
+  } ; /* USB_DeviceDescriptor */
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
+{
+  USB_LEN_DEV_QUALIFIER_DESC,
+  USB_DESC_TYPE_DEVICE_QUALIFIER,
+  0x00,
+  0x02,
+  0x00,
+  0x00,
+  0x00,
+  0x40,
+  0x01,
+  0x00,
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB Standard Device Descriptor */
+__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID] __ALIGN_END =
+{
+     USB_SIZ_STRING_LANGID,
+     USB_DESC_TYPE_STRING,
+     LOBYTE(USBD_LANGID_STRING),
+     HIBYTE(USBD_LANGID_STRING),
+};
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_DESC_Private_FunctionPrototypes
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_DESC_Private_Functions
+  * @{
+  */
+
+/**
+* @brief  USBD_USR_DeviceDescriptor
+*         return the device descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length)
+{
+  *length = sizeof(USBD_DeviceDesc);
+  return USBD_DeviceDesc;
+}
+
+/**
+* @brief  USBD_USR_LangIDStrDescriptor
+*         return the LangID string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length)
+{
+  *length =  sizeof(USBD_LangIDDesc);
+  return USBD_LangIDDesc;
+}
+
+
+/**
+* @brief  USBD_USR_ProductStrDescriptor
+*         return the product string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_USR_ProductStrDescriptor( uint8_t speed , uint16_t *length)
+{
+
+  if(speed == 0)
+  {
+    USBD_GetString ((uint8_t*)USBD_PRODUCT_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t*)USBD_PRODUCT_FS_STRING, USBD_StrDesc, length);
+  }
+
+  assert(*length < USB_MAX_STR_DESC_SIZ);
+
+  return USBD_StrDesc;
+}
+
+/**
+* @brief  USBD_USR_ManufacturerStrDescriptor
+*         return the manufacturer string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_USR_ManufacturerStrDescriptor( uint8_t speed , uint16_t *length)
+{
+  USBD_GetString ((uint8_t*)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
+  assert(*length < USB_MAX_STR_DESC_SIZ);
+  return USBD_StrDesc;
+}
+
+/**
+* @brief  USBD_USR_SerialStrDescriptor
+*         return the serial number string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length)
+{
+  if(speed  == USB_OTG_SPEED_HIGH)
+  {
+    USBD_GetString ((uint8_t*)USBD_SERIALNUMBER_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t*)USBD_SERIALNUMBER_FS_STRING, USBD_StrDesc, length);
+  }
+  assert(*length < USB_MAX_STR_DESC_SIZ);
+  return USBD_StrDesc;
+}
+
+/**
+* @brief  USBD_USR_ConfigStrDescriptor
+*         return the configuration string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length)
+{
+  if(speed  == USB_OTG_SPEED_HIGH)
+  {
+    USBD_GetString ((uint8_t*)USBD_CONFIGURATION_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t*)USBD_CONFIGURATION_FS_STRING, USBD_StrDesc, length);
+  }
+  assert(*length < USB_MAX_STR_DESC_SIZ);
+  return USBD_StrDesc;
+}
+
+
+/**
+* @brief  USBD_USR_InterfaceStrDescriptor
+*         return the interface string descriptor
+* @param  speed : current device speed
+* @param  length : pointer to data length variable
+* @retval pointer to descriptor buffer
+*/
+uint8_t *  USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length)
+{
+  if(speed == 0)
+  {
+    USBD_GetString ((uint8_t*)USBD_INTERFACE_HS_STRING, USBD_StrDesc, length);
+  }
+  else
+  {
+    USBD_GetString ((uint8_t*)USBD_INTERFACE_FS_STRING, USBD_StrDesc, length);
+  }
+  assert(*length < USB_MAX_STR_DESC_SIZ);
+  return USBD_StrDesc;
+}
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_conf/usbd_desc.h b/codec2/branches/0.7/stm32/usb_conf/usbd_desc.h
new file mode 100644 (file)
index 0000000..30c6f97
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+  ******************************************************************************
+  * @file    usbd_desc.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    19-September-2011
+  * @brief   header file for the usbd_desc.c file
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USB_DESC_H
+#define __USB_DESC_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_def.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USB_DESC
+  * @brief general defines for the usb device library file
+  * @{
+  */
+
+/** @defgroup USB_DESC_Exported_Defines
+  * @{
+  */
+#define USB_DEVICE_DESCRIPTOR_TYPE              0x01
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE       0x02
+#define USB_STRING_DESCRIPTOR_TYPE              0x03
+#define USB_INTERFACE_DESCRIPTOR_TYPE           0x04
+#define USB_ENDPOINT_DESCRIPTOR_TYPE            0x05
+#define USB_SIZ_DEVICE_DESC                     18
+#define USB_SIZ_STRING_LANGID                   4
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_DESC_Exported_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_DESC_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USBD_DESC_Exported_Variables
+  * @{
+  */
+extern  uint8_t USBD_DeviceDesc  [USB_SIZ_DEVICE_DESC];
+extern  uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ];
+extern  uint8_t USBD_OtherSpeedCfgDesc[USB_LEN_CFG_DESC];
+extern  uint8_t USBD_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC];
+extern  uint8_t USBD_LangIDDesc[USB_SIZ_STRING_LANGID];
+extern  USBD_DEVICE USR_desc;
+/**
+  * @}
+  */
+
+/** @defgroup USBD_DESC_Exported_FunctionsPrototype
+  * @{
+  */
+
+
+uint8_t *     USBD_USR_DeviceDescriptor( uint8_t speed , uint16_t *length);
+uint8_t *     USBD_USR_LangIDStrDescriptor( uint8_t speed , uint16_t *length);
+uint8_t *     USBD_USR_ManufacturerStrDescriptor ( uint8_t speed , uint16_t *length);
+uint8_t *     USBD_USR_ProductStrDescriptor ( uint8_t speed , uint16_t *length);
+uint8_t *     USBD_USR_SerialStrDescriptor( uint8_t speed , uint16_t *length);
+uint8_t *     USBD_USR_ConfigStrDescriptor( uint8_t speed , uint16_t *length);
+uint8_t *     USBD_USR_InterfaceStrDescriptor( uint8_t speed , uint16_t *length);
+
+#ifdef USB_SUPPORT_USER_STRING_DESC
+uint8_t *     USBD_USR_USRStringDesc (uint8_t speed, uint8_t idx , uint16_t *length);
+#endif /* USB_SUPPORT_USER_STRING_DESC */
+
+/**
+  * @}
+  */
+
+#endif /* __USBD_DESC_H */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_conf/usbd_usr.c b/codec2/branches/0.7/stm32/usb_conf/usbd_usr.c
new file mode 100644 (file)
index 0000000..24c5f17
--- /dev/null
@@ -0,0 +1,126 @@
+/**
+  ******************************************************************************
+  * @file    usbd_usr.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    19-September-2011
+  * @brief   This file includes the user application layer
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+#include "usbd_usr.h"
+#include "usbd_ioreq.h"
+
+USBD_Usr_cb_TypeDef USR_cb =
+{
+  USBD_USR_Init,
+  USBD_USR_DeviceReset,
+  USBD_USR_DeviceConfigured,
+  USBD_USR_DeviceSuspended,
+  USBD_USR_DeviceResumed,
+
+  USBD_USR_DeviceConnected,
+  USBD_USR_DeviceDisconnected,
+};
+
+
+/**
+* @brief  USBD_USR_Init
+*         Displays the message on LCD for host lib initialization
+* @param  None
+* @retval None
+*/
+void USBD_USR_Init(void)
+{
+
+}
+
+/**
+* @brief  USBD_USR_DeviceReset
+*         Displays the message on LCD on device Reset Event
+* @param  speed : device speed
+* @retval None
+*/
+void USBD_USR_DeviceReset(uint8_t speed )
+{
+ switch (speed)
+ {
+   case USB_OTG_SPEED_HIGH:
+     break;
+
+  case USB_OTG_SPEED_FULL:
+     break;
+ default:
+     break;
+
+ }
+}
+
+
+/**
+* @brief  USBD_USR_DeviceConfigured
+*         Displays the message on LCD on device configuration Event
+* @param  None
+* @retval Staus
+*/
+void USBD_USR_DeviceConfigured (void)
+{
+}
+
+
+/**
+* @brief  USBD_USR_DeviceConnected
+*         Displays the message on LCD on device connection Event
+* @param  None
+* @retval Staus
+*/
+void USBD_USR_DeviceConnected (void)
+{
+}
+
+
+/**
+* @brief  USBD_USR_DeviceDisonnected
+*         Displays the message on LCD on device disconnection Event
+* @param  None
+* @retval Staus
+*/
+void USBD_USR_DeviceDisconnected (void)
+{
+}
+
+/**
+* @brief  USBD_USR_DeviceSuspended
+*         Displays the message on LCD on device suspend Event
+* @param  None
+* @retval None
+*/
+void USBD_USR_DeviceSuspended(void)
+{
+  /* Users can do their application actions here for the USB-Reset */
+}
+
+
+/**
+* @brief  USBD_USR_DeviceResumed
+*         Displays the message on LCD on device resume Event
+* @param  None
+* @retval None
+*/
+void USBD_USR_DeviceResumed(void)
+{
+  /* Users can do their application actions here for the USB-Reset */
+}
+
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_core.c b/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_core.c
new file mode 100644 (file)
index 0000000..d587d86
--- /dev/null
@@ -0,0 +1,811 @@
+/**
+  ******************************************************************************
+  * @file    usbd_cdc_core.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   This file provides the high layer firmware functions to manage the
+  *          following functionalities of the USB CDC Class:
+  *           - Initialization and Configuration of high and low layer
+  *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
+  *           - OUT/IN data transfer
+  *           - Command IN transfer (class requests management)
+  *           - Error management
+  *
+  *  @verbatim
+  *
+  *          ===================================================================
+  *                                CDC Class Driver Description
+  *          ===================================================================
+  *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
+  *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
+  *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
+  *           This driver implements the following aspects of the specification:
+  *             - Device descriptor management
+  *             - Configuration descriptor management
+  *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
+  *             - Requests management (as described in section 6.2 in specification)
+  *             - Abstract Control Model compliant
+  *             - Union Functional collection (using 1 IN endpoint for control)
+  *             - Data interface class
+
+  *           @note
+  *             For the Abstract Control Model, this core allows only transmitting the requests to
+  *             lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and
+  *             perform relative actions.
+  *
+  *           These aspects may be enriched or modified for a specific user application.
+  *
+  *            This driver doesn't implement the following aspects of the specification
+  *            (but it is possible to manage these features with some modifications on this driver):
+  *             - Any class-specific aspect relative to communication classes should be managed by user application.
+  *             - All communication classes other than PSTN are not managed
+  *
+  *  @endverbatim
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_core.h"
+#include "usbd_desc.h"
+#include "usbd_req.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup usbd_cdc
+  * @brief usbd core module
+  * @{
+  */
+
+/** @defgroup usbd_cdc_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup usbd_cdc_Private_Defines
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup usbd_cdc_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup usbd_cdc_Private_FunctionPrototypes
+  * @{
+  */
+
+/*********************************************
+   CDC Device library callbacks
+ *********************************************/
+static uint8_t  usbd_cdc_Init        (void  *pdev, uint8_t cfgidx);
+static uint8_t  usbd_cdc_DeInit      (void  *pdev, uint8_t cfgidx);
+static uint8_t  usbd_cdc_Setup       (void  *pdev, USB_SETUP_REQ *req);
+static uint8_t  usbd_cdc_EP0_RxReady  (void *pdev);
+static uint8_t  usbd_cdc_DataIn      (void *pdev, uint8_t epnum);
+static uint8_t  usbd_cdc_DataOut     (void *pdev, uint8_t epnum);
+static uint8_t  usbd_cdc_SOF         (void *pdev);
+
+/*********************************************
+   CDC specific management functions
+ *********************************************/
+static void Handle_USBAsynchXfer  (void *pdev);
+static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
+#ifdef USE_USB_OTG_HS
+static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
+#endif
+/**
+  * @}
+  */
+
+/** @defgroup usbd_cdc_Private_Variables
+  * @{
+  */
+extern CDC_IF_Prop_TypeDef  APP_FOPS;
+extern uint8_t USBD_DeviceDesc   [USB_SIZ_DEVICE_DESC];
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN static __IO uint32_t  usbd_cdc_AltSet  __ALIGN_END = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t USB_Rx_Buffer   [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t APP_Rx_Buffer   [APP_RX_DATA_SIZE] __ALIGN_END ;
+
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ;
+
+uint32_t APP_Rx_ptr_in  = 0;
+uint32_t APP_Rx_ptr_out = 0;
+uint32_t APP_Rx_length  = 0;
+
+uint8_t  USB_Tx_State = 0;
+
+static uint32_t cdcCmd = 0xFF;
+static uint32_t cdcLen = 0;
+
+/* CDC interface class callbacks structure */
+USBD_Class_cb_TypeDef  USBD_CDC_cb =
+{
+  usbd_cdc_Init,
+  usbd_cdc_DeInit,
+  usbd_cdc_Setup,
+  NULL,                 /* EP0_TxSent, */
+  usbd_cdc_EP0_RxReady,
+  usbd_cdc_DataIn,
+  usbd_cdc_DataOut,
+  usbd_cdc_SOF,
+  NULL,
+  NULL,
+  USBD_cdc_GetCfgDesc,
+#ifdef USE_USB_OTG_HS
+  USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */
+#endif /* USE_USB_OTG_HS  */
+};
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+/* USB CDC device Configuration Descriptor */
+__ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
+{
+  /*Configuration Descriptor*/
+  0x09,   /* bLength: Configuration Descriptor size */
+  USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
+  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
+  0x00,
+  0x02,   /* bNumInterfaces: 2 interface */
+  0x01,   /* bConfigurationValue: Configuration value */
+  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
+  0xC0,   /* bmAttributes: self powered */
+  0x32,   /* MaxPower 0 mA */
+
+  /*---------------------------------------------------------------------------*/
+
+  /*Interface Descriptor */
+  0x09,   /* bLength: Interface Descriptor size */
+  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
+  /* Interface descriptor type */
+  0x00,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x01,   /* bNumEndpoints: One endpoints used */
+  0x02,   /* bInterfaceClass: Communication Interface Class */
+  0x02,   /* bInterfaceSubClass: Abstract Control Model */
+  0x01,   /* bInterfaceProtocol: Common AT commands */
+  0x00,   /* iInterface: */
+
+  /*Header Functional Descriptor*/
+  0x05,   /* bLength: Endpoint Descriptor size */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x00,   /* bDescriptorSubtype: Header Func Desc */
+  0x10,   /* bcdCDC: spec release number */
+  0x01,
+
+  /*Call Management Functional Descriptor*/
+  0x05,   /* bFunctionLength */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
+  0x00,   /* bmCapabilities: D0+D1 */
+  0x01,   /* bDataInterface: 1 */
+
+  /*ACM Functional Descriptor*/
+  0x04,   /* bFunctionLength */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
+  0x02,   /* bmCapabilities */
+
+  /*Union Functional Descriptor*/
+  0x05,   /* bFunctionLength */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x06,   /* bDescriptorSubtype: Union func desc */
+  0x00,   /* bMasterInterface: Communication class interface */
+  0x01,   /* bSlaveInterface0: Data Class Interface */
+
+  /*Endpoint 2 Descriptor*/
+  0x07,                           /* bLength: Endpoint Descriptor size */
+  USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+  CDC_CMD_EP,                     /* bEndpointAddress */
+  0x03,                           /* bmAttributes: Interrupt */
+  LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
+  HIBYTE(CDC_CMD_PACKET_SZE),
+#ifdef USE_USB_OTG_HS
+  0x10,                           /* bInterval: */
+#else
+  0xFF,                           /* bInterval: */
+#endif /* USE_USB_OTG_HS */
+
+  /*---------------------------------------------------------------------------*/
+
+  /*Data class interface descriptor*/
+  0x09,   /* bLength: Endpoint Descriptor size */
+  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
+  0x01,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x02,   /* bNumEndpoints: Two endpoints used */
+  0x0A,   /* bInterfaceClass: CDC */
+  0x00,   /* bInterfaceSubClass: */
+  0x00,   /* bInterfaceProtocol: */
+  0x00,   /* iInterface: */
+
+  /*Endpoint OUT Descriptor*/
+  0x07,   /* bLength: Endpoint Descriptor size */
+  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
+  CDC_OUT_EP,                        /* bEndpointAddress */
+  0x02,                              /* bmAttributes: Bulk */
+  LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
+  HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
+  0x00,                              /* bInterval: ignore for Bulk transfer */
+
+  /*Endpoint IN Descriptor*/
+  0x07,   /* bLength: Endpoint Descriptor size */
+  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
+  CDC_IN_EP,                         /* bEndpointAddress */
+  0x02,                              /* bmAttributes: Bulk */
+  LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
+  HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
+  0x00                               /* bInterval: ignore for Bulk transfer */
+} ;
+
+#ifdef USE_USB_OTG_HS
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
+{
+  0x09,   /* bLength: Configuation Descriptor size */
+  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
+  USB_CDC_CONFIG_DESC_SIZ,
+  0x00,
+  0x02,   /* bNumInterfaces: 2 interfaces */
+  0x01,   /* bConfigurationValue: */
+  0x04,   /* iConfiguration: */
+  0xC0,   /* bmAttributes: */
+  0x32,   /* MaxPower 100 mA */
+
+  /*Interface Descriptor */
+  0x09,   /* bLength: Interface Descriptor size */
+  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
+  /* Interface descriptor type */
+  0x00,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x01,   /* bNumEndpoints: One endpoints used */
+  0x02,   /* bInterfaceClass: Communication Interface Class */
+  0x02,   /* bInterfaceSubClass: Abstract Control Model */
+  0x01,   /* bInterfaceProtocol: Common AT commands */
+  0x00,   /* iInterface: */
+
+  /*Header Functional Descriptor*/
+  0x05,   /* bLength: Endpoint Descriptor size */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x00,   /* bDescriptorSubtype: Header Func Desc */
+  0x10,   /* bcdCDC: spec release number */
+  0x01,
+
+  /*Call Management Functional Descriptor*/
+  0x05,   /* bFunctionLength */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
+  0x00,   /* bmCapabilities: D0+D1 */
+  0x01,   /* bDataInterface: 1 */
+
+  /*ACM Functional Descriptor*/
+  0x04,   /* bFunctionLength */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
+  0x02,   /* bmCapabilities */
+
+  /*Union Functional Descriptor*/
+  0x05,   /* bFunctionLength */
+  0x24,   /* bDescriptorType: CS_INTERFACE */
+  0x06,   /* bDescriptorSubtype: Union func desc */
+  0x00,   /* bMasterInterface: Communication class interface */
+  0x01,   /* bSlaveInterface0: Data Class Interface */
+
+  /*Endpoint 2 Descriptor*/
+  0x07,                           /* bLength: Endpoint Descriptor size */
+  USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
+  CDC_CMD_EP,                     /* bEndpointAddress */
+  0x03,                           /* bmAttributes: Interrupt */
+  LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
+  HIBYTE(CDC_CMD_PACKET_SZE),
+  0xFF,                           /* bInterval: */
+
+  /*---------------------------------------------------------------------------*/
+
+  /*Data class interface descriptor*/
+  0x09,   /* bLength: Endpoint Descriptor size */
+  USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
+  0x01,   /* bInterfaceNumber: Number of Interface */
+  0x00,   /* bAlternateSetting: Alternate setting */
+  0x02,   /* bNumEndpoints: Two endpoints used */
+  0x0A,   /* bInterfaceClass: CDC */
+  0x00,   /* bInterfaceSubClass: */
+  0x00,   /* bInterfaceProtocol: */
+  0x00,   /* iInterface: */
+
+  /*Endpoint OUT Descriptor*/
+  0x07,   /* bLength: Endpoint Descriptor size */
+  USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
+  CDC_OUT_EP,                        /* bEndpointAddress */
+  0x02,                              /* bmAttributes: Bulk */
+  0x40,                              /* wMaxPacketSize: */
+  0x00,
+  0x00,                              /* bInterval: ignore for Bulk transfer */
+
+  /*Endpoint IN Descriptor*/
+  0x07,   /* bLength: Endpoint Descriptor size */
+  USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
+  CDC_IN_EP,                        /* bEndpointAddress */
+  0x02,                             /* bmAttributes: Bulk */
+  0x40,                             /* wMaxPacketSize: */
+  0x00,
+  0x00                              /* bInterval */
+};
+#endif /* USE_USB_OTG_HS  */
+
+/**
+  * @}
+  */
+
+/** @defgroup usbd_cdc_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  usbd_cdc_Init
+  *         Initilaize the CDC interface
+  * @param  pdev: device instance
+  * @param  cfgidx: Configuration index
+  * @retval status
+  */
+static uint8_t  usbd_cdc_Init (void  *pdev,
+                               uint8_t cfgidx)
+{
+  uint8_t *pbuf;
+
+  /* Open EP IN */
+  DCD_EP_Open(pdev,
+              CDC_IN_EP,
+              CDC_DATA_IN_PACKET_SIZE,
+              USB_OTG_EP_BULK);
+
+  /* Open EP OUT */
+  DCD_EP_Open(pdev,
+              CDC_OUT_EP,
+              CDC_DATA_OUT_PACKET_SIZE,
+              USB_OTG_EP_BULK);
+
+  /* Open Command IN EP */
+  DCD_EP_Open(pdev,
+              CDC_CMD_EP,
+              CDC_CMD_PACKET_SZE,
+              USB_OTG_EP_INT);
+
+  pbuf = (uint8_t *)USBD_DeviceDesc;
+  pbuf[4] = DEVICE_CLASS_CDC;
+  pbuf[5] = DEVICE_SUBCLASS_CDC;
+
+  /* Initialize the Interface physical components */
+  APP_FOPS.pIf_Init();
+
+  /* Prepare Out endpoint to receive next packet */
+  DCD_EP_PrepareRx(pdev,
+                   CDC_OUT_EP,
+                   (uint8_t*)(USB_Rx_Buffer),
+                   CDC_DATA_OUT_PACKET_SIZE);
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  usbd_cdc_Init
+  *         DeInitialize the CDC layer
+  * @param  pdev: device instance
+  * @param  cfgidx: Configuration index
+  * @retval status
+  */
+static uint8_t  usbd_cdc_DeInit (void  *pdev,
+                                 uint8_t cfgidx)
+{
+  /* Open EP IN */
+  DCD_EP_Close(pdev,
+              CDC_IN_EP);
+
+  /* Open EP OUT */
+  DCD_EP_Close(pdev,
+              CDC_OUT_EP);
+
+  /* Open Command IN EP */
+  DCD_EP_Close(pdev,
+              CDC_CMD_EP);
+
+  /* Restore default state of the Interface physical components */
+  APP_FOPS.pIf_DeInit();
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  usbd_cdc_Setup
+  *         Handle the CDC specific requests
+  * @param  pdev: instance
+  * @param  req: usb requests
+  * @retval status
+  */
+static uint8_t  usbd_cdc_Setup (void  *pdev,
+                                USB_SETUP_REQ *req)
+{
+  uint16_t len = 0;
+  uint8_t  *pbuf;
+
+  switch (req->bmRequest & USB_REQ_TYPE_MASK)
+  {
+    /* CDC Class Requests -------------------------------*/
+  case USB_REQ_TYPE_CLASS :
+      /* Check if the request is a data setup packet */
+      if (req->wLength)
+      {
+        /* Check if the request is Device-to-Host */
+        if (req->bmRequest & 0x80)
+        {
+          /* Get the data to be sent to Host from interface layer */
+          APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
+
+          /* Send the data to the host */
+          USBD_CtlSendData (pdev,
+                            CmdBuff,
+                            req->wLength);
+        }
+        else /* Host-to-Device requeset */
+        {
+          /* Set the value of the current command to be processed */
+          cdcCmd = req->bRequest;
+          cdcLen = req->wLength;
+
+          /* Prepare the reception of the buffer over EP0
+          Next step: the received data will be managed in usbd_cdc_EP0_TxSent()
+          function. */
+          USBD_CtlPrepareRx (pdev,
+                             CmdBuff,
+                             req->wLength);
+        }
+      }
+      else /* No Data request */
+      {
+        /* Transfer the command to the interface layer */
+        APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
+      }
+
+      return USBD_OK;
+
+    default:
+      USBD_CtlError (pdev, req);
+      return USBD_FAIL;
+
+
+
+    /* Standard Requests -------------------------------*/
+  case USB_REQ_TYPE_STANDARD:
+    switch (req->bRequest)
+    {
+    case USB_REQ_GET_DESCRIPTOR:
+      if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
+      {
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+        pbuf = usbd_cdc_Desc;
+#else
+        pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
+#endif
+        len = MIN(USB_CDC_DESC_SIZ , req->wLength);
+      }
+
+      USBD_CtlSendData (pdev,
+                        pbuf,
+                        len);
+      break;
+
+    case USB_REQ_GET_INTERFACE :
+      USBD_CtlSendData (pdev,
+                        (uint8_t *)&usbd_cdc_AltSet,
+                        1);
+      break;
+
+    case USB_REQ_SET_INTERFACE :
+      if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
+      {
+        usbd_cdc_AltSet = (uint8_t)(req->wValue);
+      }
+      else
+      {
+        /* Call the error management function (command will be nacked */
+        USBD_CtlError (pdev, req);
+      }
+      break;
+    }
+  }
+  return USBD_OK;
+}
+
+/**
+  * @brief  usbd_cdc_EP0_RxReady
+  *         Data received on control endpoint
+  * @param  pdev: device device instance
+  * @retval status
+  */
+static uint8_t  usbd_cdc_EP0_RxReady (void  *pdev)
+{
+  if (cdcCmd != NO_CMD)
+  {
+    /* Process the data */
+    APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
+
+    /* Reset the command variable to default value */
+    cdcCmd = NO_CMD;
+  }
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  usbd_audio_DataIn
+  *         Data sent on non-control IN endpoint
+  * @param  pdev: device instance
+  * @param  epnum: endpoint number
+  * @retval status
+  */
+static uint8_t  usbd_cdc_DataIn (void *pdev, uint8_t epnum)
+{
+  uint16_t USB_Tx_ptr;
+  uint16_t USB_Tx_length;
+
+  if (USB_Tx_State == 1)
+  {
+    if (APP_Rx_length == 0)
+    {
+      USB_Tx_State = 0;
+    }
+    else
+    {
+      if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){
+        USB_Tx_ptr = APP_Rx_ptr_out;
+        USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
+
+        APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;
+        APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
+      }
+      else
+      {
+        USB_Tx_ptr = APP_Rx_ptr_out;
+        USB_Tx_length = APP_Rx_length;
+
+        APP_Rx_ptr_out += APP_Rx_length;
+        APP_Rx_length = 0;
+      }
+
+      /* Prepare the available data buffer to be sent on IN endpoint */
+      DCD_EP_Tx (pdev,
+                 CDC_IN_EP,
+                 (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
+                 USB_Tx_length);
+    }
+  }
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  usbd_audio_DataOut
+  *         Data received on non-control Out endpoint
+  * @param  pdev: device instance
+  * @param  epnum: endpoint number
+  * @retval status
+  */
+static uint8_t  usbd_cdc_DataOut (void *pdev, uint8_t epnum)
+{
+  uint16_t USB_Rx_Cnt;
+
+  /* Get the received data buffer and update the counter */
+  USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count;
+
+  /* USB data will be immediately processed, this allow next USB traffic being
+     NAKed till the end of the application Xfer */
+  APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt);
+
+  /* Prepare Out endpoint to receive next packet */
+  DCD_EP_PrepareRx(pdev,
+                   CDC_OUT_EP,
+                   (uint8_t*)(USB_Rx_Buffer),
+                   CDC_DATA_OUT_PACKET_SIZE);
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  usbd_audio_SOF
+  *         Start Of Frame event management
+  * @param  pdev: instance
+  * @param  epnum: endpoint number
+  * @retval status
+  */
+static uint8_t  usbd_cdc_SOF (void *pdev)
+{
+  static uint32_t FrameCount = 0;
+
+  if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
+  {
+    /* Reset the frame counter */
+    FrameCount = 0;
+
+    /* Check the data to be sent through IN pipe */
+    Handle_USBAsynchXfer(pdev);
+  }
+
+  return USBD_OK;
+}
+
+/**
+  * @brief  Handle_USBAsynchXfer
+  *         Send data to USB
+  * @param  pdev: instance
+  * @retval None
+  */
+static void Handle_USBAsynchXfer (void *pdev)
+{
+  uint16_t USB_Tx_ptr;
+  uint16_t USB_Tx_length;
+
+  if(USB_Tx_State != 1)
+  {
+    if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
+    {
+      APP_Rx_ptr_out = 0;
+    }
+
+    if(APP_Rx_ptr_out == APP_Rx_ptr_in)
+    {
+      USB_Tx_State = 0;
+      return;
+    }
+
+    if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
+    {
+      APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;
+
+    }
+    else
+    {
+      APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;
+
+    }
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+     APP_Rx_length &= ~0x03;
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+    if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE)
+    {
+      USB_Tx_ptr = APP_Rx_ptr_out;
+      USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
+
+      APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;
+      APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
+    }
+    else
+    {
+      USB_Tx_ptr = APP_Rx_ptr_out;
+      USB_Tx_length = APP_Rx_length;
+
+      APP_Rx_ptr_out += APP_Rx_length;
+      APP_Rx_length = 0;
+    }
+    USB_Tx_State = 1;
+
+    DCD_EP_Tx (pdev,
+               CDC_IN_EP,
+               (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
+               USB_Tx_length);
+  }
+
+}
+
+/**
+  * @brief  USBD_cdc_GetCfgDesc
+  *         Return configuration descriptor
+  * @param  speed : current device speed
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
+{
+  *length = sizeof (usbd_cdc_CfgDesc);
+  return usbd_cdc_CfgDesc;
+}
+
+/**
+  * @brief  USBD_cdc_GetCfgDesc
+  *         Return configuration descriptor
+  * @param  speed : current device speed
+  * @param  length : pointer data length
+  * @retval pointer to descriptor buffer
+  */
+#ifdef USE_USB_OTG_HS
+static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
+{
+  *length = sizeof (usbd_cdc_OtherCfgDesc);
+  return usbd_cdc_OtherCfgDesc;
+}
+#endif
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_core.h b/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_core.h
new file mode 100644 (file)
index 0000000..43af268
--- /dev/null
@@ -0,0 +1,137 @@
+/**
+  ******************************************************************************
+  * @file    usbd_cdc_core.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   header file for the usbd_cdc_core.c file.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+
+#ifndef __USB_CDC_CORE_H_
+#define __USB_CDC_CORE_H_
+
+#include  "usbd_ioreq.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup usbd_cdc
+  * @brief This file is the Header file for USBD_cdc.c
+  * @{
+  */
+
+
+/** @defgroup usbd_cdc_Exported_Defines
+  * @{
+  */
+#define USB_CDC_CONFIG_DESC_SIZ                (67)
+#define USB_CDC_DESC_SIZ                       (67-9)
+
+#define CDC_DESCRIPTOR_TYPE                     0x21
+
+#define DEVICE_CLASS_CDC                        0x02
+#define DEVICE_SUBCLASS_CDC                     0x00
+
+
+#define USB_DEVICE_DESCRIPTOR_TYPE              0x01
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE       0x02
+#define USB_STRING_DESCRIPTOR_TYPE              0x03
+#define USB_INTERFACE_DESCRIPTOR_TYPE           0x04
+#define USB_ENDPOINT_DESCRIPTOR_TYPE            0x05
+
+#define STANDARD_ENDPOINT_DESC_SIZE             0x09
+
+#define CDC_DATA_IN_PACKET_SIZE                 *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 57)
+
+#define CDC_DATA_OUT_PACKET_SIZE                *(uint16_t *)(((USB_OTG_CORE_HANDLE *)pdev)->dev.pConfig_descriptor + 64)
+
+/*---------------------------------------------------------------------*/
+/*  CDC definitions                                                    */
+/*---------------------------------------------------------------------*/
+
+/**************************************************/
+/* CDC Requests                                   */
+/**************************************************/
+#define SEND_ENCAPSULATED_COMMAND               0x00
+#define GET_ENCAPSULATED_RESPONSE               0x01
+#define SET_COMM_FEATURE                        0x02
+#define GET_COMM_FEATURE                        0x03
+#define CLEAR_COMM_FEATURE                      0x04
+#define SET_LINE_CODING                         0x20
+#define GET_LINE_CODING                         0x21
+#define SET_CONTROL_LINE_STATE                  0x22
+#define SEND_BREAK                              0x23
+#define NO_CMD                                  0xFF
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+  * @{
+  */
+typedef struct _CDC_IF_PROP
+{
+  uint16_t (*pIf_Init)     (void);
+  uint16_t (*pIf_DeInit)   (void);
+  uint16_t (*pIf_Ctrl)     (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
+  uint16_t (*pIf_DataTx)   (uint8_t* Buf, uint32_t Len);
+  uint16_t (*pIf_DataRx)   (uint8_t* Buf, uint32_t Len);
+}
+CDC_IF_Prop_TypeDef;
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CORE_Exported_Variables
+  * @{
+  */
+
+extern USBD_Class_cb_TypeDef  USBD_CDC_cb;
+/**
+  * @}
+  */
+
+/** @defgroup USB_CORE_Exported_Functions
+  * @{
+  */
+/**
+  * @}
+  */
+
+#endif  // __USB_CDC_CORE_H_
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_vcp.c b/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_vcp.c
new file mode 100644 (file)
index 0000000..5f96919
--- /dev/null
@@ -0,0 +1,280 @@
+/**
+ ******************************************************************************
+ * @file    usbd_cdc_vcp.c
+ * @author  MCD Application Team
+ * @version V1.0.0
+ * @date    22-July-2011
+ * @brief   Generic media access Layer.
+ ******************************************************************************
+ * @attention
+ *
+ * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+ * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+ * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+ * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+ * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+ * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+ *
+ * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+ ******************************************************************************
+ */
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+#pragma     data_alignment = 4
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_cdc_vcp.h"
+#include "stm32f4xx_conf.h"
+#include "stm32f4xx_usart.h"
+
+/* Private variables ---------------------------------------------------------*/
+LINE_CODING linecoding = {
+               115200, /* baud rate*/
+               0x00, /* stop bits-1*/
+               0x00, /* parity - none*/
+               0x08 /* nb. of bits 8*/
+};
+
+USART_InitTypeDef USART_InitStructure;
+
+/* These are external variables imported from CDC core to be used for IN
+ transfer management. */
+extern uint8_t APP_Rx_Buffer[]; /* Write CDC received data in this buffer.
+ These data will be sent over USB IN endpoint
+ in the CDC core functions. */
+extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to
+ start address when writing received data
+ in the buffer APP_Rx_Buffer. */
+
+/* Private function prototypes -----------------------------------------------*/
+static uint16_t VCP_Init(void);
+static uint16_t VCP_DeInit(void);
+static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len);
+static uint16_t VCP_DataTx(uint8_t* Buf, uint32_t Len);
+static uint16_t VCP_DataRx(uint8_t* Buf, uint32_t Len);
+
+CDC_IF_Prop_TypeDef VCP_fops = { VCP_Init, VCP_DeInit, VCP_Ctrl, VCP_DataTx,
+               VCP_DataRx };
+
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @brief  VCP_Init
+ *         Initializes the Media on the STM32
+ * @param  None
+ * @retval Result of the opeartion (USBD_OK in all cases)
+ */
+static uint16_t VCP_Init(void) {
+       return USBD_OK;
+}
+
+/**
+ * @brief  VCP_DeInit
+ *         DeInitializes the Media on the STM32
+ * @param  None
+ * @retval Result of the opeartion (USBD_OK in all cases)
+ */
+static uint16_t VCP_DeInit(void) {
+       return USBD_OK;
+}
+
+/**
+ * @brief  VCP_Ctrl
+ *         Manage the CDC class requests
+ * @param  Cmd: Command code
+ * @param  Buf: Buffer containing command data (request parameters)
+ * @param  Len: Number of data to be sent (in bytes)
+ * @retval Result of the opeartion (USBD_OK in all cases)
+ */
+static uint16_t VCP_Ctrl(uint32_t Cmd, uint8_t* Buf, uint32_t Len) {
+       switch (Cmd) {
+       case SEND_ENCAPSULATED_COMMAND:
+               /* Not  needed for this driver */
+               break;
+
+       case GET_ENCAPSULATED_RESPONSE:
+               /* Not  needed for this driver */
+               break;
+
+       case SET_COMM_FEATURE:
+               /* Not  needed for this driver */
+               break;
+
+       case GET_COMM_FEATURE:
+               /* Not  needed for this driver */
+               break;
+
+       case CLEAR_COMM_FEATURE:
+               /* Not  needed for this driver */
+               break;
+
+       case SET_LINE_CODING:
+               /* Not  needed for this driver */
+               break;
+
+       case GET_LINE_CODING:
+               Buf[0] = (uint8_t) (linecoding.bitrate);
+               Buf[1] = (uint8_t) (linecoding.bitrate >> 8);
+               Buf[2] = (uint8_t) (linecoding.bitrate >> 16);
+               Buf[3] = (uint8_t) (linecoding.bitrate >> 24);
+               Buf[4] = linecoding.format;
+               Buf[5] = linecoding.paritytype;
+               Buf[6] = linecoding.datatype;
+               break;
+
+       case SET_CONTROL_LINE_STATE:
+               /* Not  needed for this driver */
+               break;
+
+       case SEND_BREAK:
+               /* Not  needed for this driver */
+               break;
+
+       default:
+               break;
+       }
+
+       return USBD_OK;
+}
+
+/**
+ * @brief  putchar
+ *         Sends one char over the USB serial link.
+ * @param  buf: char to be sent
+ * @retval none
+ */
+
+void VCP_put_char(uint8_t buf) {
+       VCP_DataTx(&buf, 1);
+}
+
+void VCP_send_str(uint8_t* buf) {
+       uint32_t i = 0;
+       while (*(buf + i)) {
+               i++;
+       }
+       VCP_DataTx(buf, i);
+}
+
+void VCP_send_buffer(uint8_t* buf, int len) {
+       VCP_DataTx(buf, len);
+}
+
+/**
+ * @brief  VCP_DataTx
+ *         CDC received data to be send over USB IN endpoint are managed in
+ *         this function.
+ * @param  Buf: Buffer of data to be sent
+ * @param  Len: Number of data to be sent (in bytes)
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
+ */
+static uint16_t VCP_DataTx(uint8_t* Buf, uint32_t Len) {
+       uint32_t i = 0;
+       while (i < Len) {
+               APP_Rx_Buffer[APP_Rx_ptr_in] = *(Buf + i);
+               APP_Rx_ptr_in++;
+               i++;
+               /* To avoid buffer overflow */
+               if (APP_Rx_ptr_in == APP_RX_DATA_SIZE) {
+                       APP_Rx_ptr_in = 0;
+               }
+       }
+
+       return USBD_OK;
+}
+
+/**
+ * @brief  VCP_DataRx
+ *         Data received over USB OUT endpoint are sent over CDC interface
+ *         through this function.
+ *
+ *         @note
+ *         This function will block any OUT packet reception on USB endpoint
+ *         until exiting this function. If you exit this function before transfer
+ *         is complete on CDC interface (ie. using DMA controller) it will result
+ *         in receiving more data while previous ones are still not sent.
+ *
+ * @param  Buf: Buffer of data to be received
+ * @param  Len: Number of data received (in bytes)
+ * @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
+ */
+
+#define APP_TX_BUF_SIZE 128
+uint8_t APP_Tx_Buffer[APP_TX_BUF_SIZE];
+uint32_t APP_tx_ptr_head;
+uint32_t APP_tx_ptr_tail;
+
+static uint16_t VCP_DataRx(uint8_t* Buf, uint32_t Len) {
+       uint32_t i;
+
+       for (i = 0; i < Len; i++) {
+               APP_Tx_Buffer[APP_tx_ptr_head] = *(Buf + i);
+               APP_tx_ptr_head++;
+               if (APP_tx_ptr_head == APP_TX_BUF_SIZE)
+                       APP_tx_ptr_head = 0;
+
+               if (APP_tx_ptr_head == APP_tx_ptr_tail)
+                       return USBD_FAIL;
+       }
+
+       return USBD_OK;
+}
+
+int VCP_get_char(uint8_t *buf) {
+       if (APP_tx_ptr_head == APP_tx_ptr_tail)
+               return 0;
+
+       *buf = APP_Tx_Buffer[APP_tx_ptr_tail];
+       APP_tx_ptr_tail++;
+       if (APP_tx_ptr_tail == APP_TX_BUF_SIZE)
+               APP_tx_ptr_tail = 0;
+
+       return 1;
+}
+
+int VCP_get_string(uint8_t *buf) {
+       if (APP_tx_ptr_head == APP_tx_ptr_tail)
+               return 0;
+
+       while (!APP_Tx_Buffer[APP_tx_ptr_tail]
+                       || APP_Tx_Buffer[APP_tx_ptr_tail] == '\n'
+                       || APP_Tx_Buffer[APP_tx_ptr_tail] == '\r') {
+               APP_tx_ptr_tail++;
+               if (APP_tx_ptr_tail == APP_TX_BUF_SIZE)
+                       APP_tx_ptr_tail = 0;
+               if (APP_tx_ptr_head == APP_tx_ptr_tail)
+                       return 0;
+       }
+
+       int i = 0;
+       do {
+               *(buf + i) = APP_Tx_Buffer[i + APP_tx_ptr_tail];
+               i++;
+
+               if ((APP_tx_ptr_tail + i) == APP_TX_BUF_SIZE)
+                       i = -APP_tx_ptr_tail;
+               if (APP_tx_ptr_head == (APP_tx_ptr_tail + i))
+                       return 0;
+
+       } while (APP_Tx_Buffer[APP_tx_ptr_tail + i]
+                       && APP_Tx_Buffer[APP_tx_ptr_tail + i] != '\n'
+                       && APP_Tx_Buffer[APP_tx_ptr_tail + i] != '\r');
+
+       *(buf + i) = 0;
+       APP_tx_ptr_tail += i;
+       if (APP_tx_ptr_tail >= APP_TX_BUF_SIZE)
+               APP_tx_ptr_tail -= APP_TX_BUF_SIZE;
+       return i;
+}
+
+/**
+ * @brief  EVAL_COM_IRQHandler
+ *
+ * @param  None.
+ * @retval None.
+ */
+void EVAL_COM_IRQHandler(void) {
+
+}
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_vcp.h b/codec2/branches/0.7/stm32/usb_lib/cdc/usbd_cdc_vcp.h
new file mode 100644 (file)
index 0000000..78f2c03
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+  ******************************************************************************
+  * @file    usbd_cdc_vcp.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   Header for usbd_cdc_vcp.c file.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CDC_VCP_H
+#define __USBD_CDC_VCP_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_conf.h"
+
+#include "usbd_cdc_core.h"
+#include "usbd_conf.h"
+#include <stdint.h>
+
+/* Exported typef ------------------------------------------------------------*/
+/* The following structures groups all needed parameters to be configured for the
+   ComPort. These parameters can modified on the fly by the host through CDC class
+   command class requests. */
+typedef struct
+{
+  uint32_t bitrate;
+  uint8_t  format;
+  uint8_t  paritytype;
+  uint8_t  datatype;
+}LINE_CODING;
+
+/* Exported constants --------------------------------------------------------*/
+/* The following define is used to route the USART IRQ handler to be used.
+   The IRQ handler function is implemented in the usbd_cdc_vcp.c file. */
+#ifdef USE_STM322xG_EVAL
+ #define EVAL_COM_IRQHandler            USART3_IRQHandler
+#elif defined(USE_STM3210C_EVAL)
+ #define EVAL_COM_IRQHandler            USART2_IRQHandler
+#endif /* USE_STM322xG_EVAL */
+
+void VCP_put_char(uint8_t buf);
+void VCP_send_str(uint8_t* buf);
+int VCP_get_char(uint8_t *buf);
+int VCP_get_string(uint8_t *buf);
+void VCP_send_buffer(uint8_t* buf, int len);
+
+#define DEFAULT_CONFIG                  0
+#define OTHER_CONFIG                    1
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __USBD_CDC_VCP_H */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_core.c b/codec2/branches/0.7/stm32/usb_lib/core/usbd_core.c
new file mode 100644 (file)
index 0000000..4b5781f
--- /dev/null
@@ -0,0 +1,476 @@
+/**
+  ******************************************************************************
+  * @file    usbd_core.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   This file provides all the USBD core functions.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+#include "usbd_req.h"
+#include "usbd_ioreq.h"
+#include "usb_dcd_int.h"
+#include "usb_bsp.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+* @{
+*/
+
+
+/** @defgroup USBD_CORE
+* @brief usbd core module
+* @{
+*/
+
+/** @defgroup USBD_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBD_CORE_Private_Defines
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USBD_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+
+/** @defgroup USBD_CORE_Private_FunctionPrototypes
+* @{
+*/
+static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev);
+static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE  *pdev);
+static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE  *pdev);
+static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE  *pdev);
+static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE  *pdev);
+#ifdef VBUS_SENSING_ENABLED
+static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE  *pdev);
+static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE  *pdev);
+#endif
+static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE  *pdev);
+static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE  *pdev);
+/**
+* @}
+*/
+
+/** @defgroup USBD_CORE_Private_Variables
+* @{
+*/
+
+
+
+USBD_DCD_INT_cb_TypeDef USBD_DCD_INT_cb =
+{
+  USBD_DataOutStage,
+  USBD_DataInStage,
+  USBD_SetupStage,
+  USBD_SOF,
+  USBD_Reset,
+  USBD_Suspend,
+  USBD_Resume,
+  USBD_IsoINIncomplete,
+  USBD_IsoOUTIncomplete,
+#ifdef VBUS_SENSING_ENABLED
+USBD_DevConnected,
+USBD_DevDisconnected,
+#endif
+};
+
+USBD_DCD_INT_cb_TypeDef  *USBD_DCD_INT_fops = &USBD_DCD_INT_cb;
+/**
+* @}
+*/
+
+/** @defgroup USBD_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief  USBD_Init
+*         Initailizes the device stack and load the class driver
+* @param  pdev: device instance
+* @param  core_address: USB OTG core ID
+* @param  class_cb: Class callback structure address
+* @param  usr_cb: User callback structure address
+* @retval None
+*/
+void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
+               USB_OTG_CORE_ID_TypeDef coreID,
+               USBD_DEVICE *pDevice,
+               USBD_Class_cb_TypeDef *class_cb,
+               USBD_Usr_cb_TypeDef *usr_cb)
+{
+  /* Hardware Init */
+  USB_OTG_BSP_Init(pdev);
+
+  USBD_DeInit(pdev);
+
+  /*Register class and user callbacks */
+  pdev->dev.class_cb = class_cb;
+  pdev->dev.usr_cb = usr_cb;
+  pdev->dev.usr_device = pDevice;
+
+  /* set USB OTG core params */
+  DCD_Init(pdev , coreID);
+
+  /* Upon Init call usr callback */
+  pdev->dev.usr_cb->Init();
+
+  /* Enable Interrupts */
+  USB_OTG_BSP_EnableInterrupt(pdev);
+}
+
+/**
+* @brief  USBD_DeInit
+*         Re-Initialize th deviuce library
+* @param  pdev: device instance
+* @retval status: status
+*/
+USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev)
+{
+  /* Software Init */
+
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_SetupStage
+*         Handle the setup stage
+* @param  pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_SetupStage(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_SETUP_REQ req;
+
+  USBD_ParseSetupRequest(pdev , &req);
+
+  switch (req.bmRequest & 0x1F)
+  {
+  case USB_REQ_RECIPIENT_DEVICE:
+    USBD_StdDevReq (pdev, &req);
+    break;
+
+  case USB_REQ_RECIPIENT_INTERFACE:
+    USBD_StdItfReq(pdev, &req);
+    break;
+
+  case USB_REQ_RECIPIENT_ENDPOINT:
+    USBD_StdEPReq(pdev, &req);
+    break;
+
+  default:
+    DCD_EP_Stall(pdev , req.bmRequest & 0x80);
+    break;
+  }
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_DataOutStage
+*         Handle data out stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+static uint8_t USBD_DataOutStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+  USB_OTG_EP *ep;
+
+  if(epnum == 0)
+  {
+    ep = &pdev->dev.out_ep[0];
+    if ( pdev->dev.device_state == USB_OTG_EP0_DATA_OUT)
+    {
+      if(ep->rem_data_len > ep->maxpacket)
+      {
+        ep->rem_data_len -=  ep->maxpacket;
+
+        if(pdev->cfg.dma_enable == 1)
+        {
+          /* in slave mode this, is handled by the RxSTSQLvl ISR */
+          ep->xfer_buff += ep->maxpacket;
+        }
+        USBD_CtlContinueRx (pdev,
+                            ep->xfer_buff,
+                            MIN(ep->rem_data_len ,ep->maxpacket));
+      }
+      else
+      {
+        if((pdev->dev.class_cb->EP0_RxReady != NULL)&&
+           (pdev->dev.device_status == USB_OTG_CONFIGURED))
+        {
+          pdev->dev.class_cb->EP0_RxReady(pdev);
+        }
+        USBD_CtlSendStatus(pdev);
+      }
+    }
+  }
+  else if((pdev->dev.class_cb->DataOut != NULL)&&
+          (pdev->dev.device_status == USB_OTG_CONFIGURED))
+  {
+    pdev->dev.class_cb->DataOut(pdev, epnum);
+  }
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_DataInStage
+*         Handle data in stage
+* @param  pdev: device instance
+* @param  epnum: endpoint index
+* @retval status
+*/
+static uint8_t USBD_DataInStage(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+  USB_OTG_EP *ep;
+
+  if(epnum == 0)
+  {
+    ep = &pdev->dev.in_ep[0];
+    if ( pdev->dev.device_state == USB_OTG_EP0_DATA_IN)
+    {
+      if(ep->rem_data_len > ep->maxpacket)
+      {
+        ep->rem_data_len -=  ep->maxpacket;
+        if(pdev->cfg.dma_enable == 1)
+        {
+          /* in slave mode this, is handled by the TxFifoEmpty ISR */
+          ep->xfer_buff += ep->maxpacket;
+        }
+        USBD_CtlContinueSendData (pdev,
+                                  ep->xfer_buff,
+                                  ep->rem_data_len);
+      }
+      else
+      { /* last packet is MPS multiple, so send ZLP packet */
+        if((ep->total_data_len % ep->maxpacket == 0) &&
+           (ep->total_data_len >= ep->maxpacket) &&
+             (ep->total_data_len < ep->ctl_data_len ))
+        {
+
+          USBD_CtlContinueSendData(pdev , NULL, 0);
+          ep->ctl_data_len = 0;
+        }
+        else
+        {
+          if((pdev->dev.class_cb->EP0_TxSent != NULL)&&
+             (pdev->dev.device_status == USB_OTG_CONFIGURED))
+          {
+            pdev->dev.class_cb->EP0_TxSent(pdev);
+          }
+          USBD_CtlReceiveStatus(pdev);
+        }
+      }
+    }
+  }
+  else if((pdev->dev.class_cb->DataIn != NULL)&&
+          (pdev->dev.device_status == USB_OTG_CONFIGURED))
+  {
+    pdev->dev.class_cb->DataIn(pdev, epnum);
+  }
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_Reset
+*         Handle Reset event
+* @param  pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Reset(USB_OTG_CORE_HANDLE  *pdev)
+{
+  /* Open EP0 OUT */
+  DCD_EP_Open(pdev,
+              0x00,
+              USB_OTG_MAX_EP0_SIZE,
+              EP_TYPE_CTRL);
+
+  /* Open EP0 IN */
+  DCD_EP_Open(pdev,
+              0x80,
+              USB_OTG_MAX_EP0_SIZE,
+              EP_TYPE_CTRL);
+
+  /* Upon Reset call usr call back */
+  pdev->dev.device_status = USB_OTG_DEFAULT;
+  pdev->dev.usr_cb->DeviceReset(pdev->cfg.speed);
+
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_Resume
+*         Handle Resume event
+* @param  pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Resume(USB_OTG_CORE_HANDLE  *pdev)
+{
+  /* Upon Resume call usr call back */
+  pdev->dev.usr_cb->DeviceResumed();
+  pdev->dev.device_status = USB_OTG_CONFIGURED;
+  return USBD_OK;
+}
+
+
+/**
+* @brief  USBD_Suspend
+*         Handle Suspend event
+* @param  pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_Suspend(USB_OTG_CORE_HANDLE  *pdev)
+{
+
+  pdev->dev.device_status  = USB_OTG_SUSPENDED;
+  /* Upon Resume call usr call back */
+  pdev->dev.usr_cb->DeviceSuspended();
+  return USBD_OK;
+}
+
+
+/**
+* @brief  USBD_SOF
+*         Handle SOF event
+* @param  pdev: device instance
+* @retval status
+*/
+
+static uint8_t USBD_SOF(USB_OTG_CORE_HANDLE  *pdev)
+{
+  if(pdev->dev.class_cb->SOF)
+  {
+    pdev->dev.class_cb->SOF(pdev);
+  }
+  return USBD_OK;
+}
+/**
+* @brief  USBD_SetCfg
+*        Configure device and start the interface
+* @param  pdev: device instance
+* @param  cfgidx: configuration index
+* @retval status
+*/
+
+USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE  *pdev, uint8_t cfgidx)
+{
+  pdev->dev.class_cb->Init(pdev, cfgidx);
+
+  /* Upon set config call usr call back */
+  pdev->dev.usr_cb->DeviceConfigured();
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_ClrCfg
+*         Clear current configuration
+* @param  pdev: device instance
+* @param  cfgidx: configuration index
+* @retval status: USBD_Status
+*/
+USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE  *pdev, uint8_t cfgidx)
+{
+  pdev->dev.class_cb->DeInit(pdev, cfgidx);
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_IsoINIncomplete
+*         Handle iso in incomplete event
+* @param  pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_IsoINIncomplete(USB_OTG_CORE_HANDLE  *pdev)
+{
+  pdev->dev.class_cb->IsoINIncomplete(pdev);
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_IsoOUTIncomplete
+*         Handle iso out incomplete event
+* @param  pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_IsoOUTIncomplete(USB_OTG_CORE_HANDLE  *pdev)
+{
+  pdev->dev.class_cb->IsoOUTIncomplete(pdev);
+  return USBD_OK;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+/**
+* @brief  USBD_DevConnected
+*         Handle device connection event
+* @param  pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_DevConnected(USB_OTG_CORE_HANDLE  *pdev)
+{
+  pdev->dev.usr_cb->DeviceConnected();
+  return USBD_OK;
+}
+
+/**
+* @brief  USBD_DevDisconnected
+*         Handle device disconnection event
+* @param  pdev: device instance
+* @retval status
+*/
+static uint8_t USBD_DevDisconnected(USB_OTG_CORE_HANDLE  *pdev)
+{
+  pdev->dev.usr_cb->DeviceDisconnected();
+  pdev->dev.class_cb->DeInit(pdev, 0);
+  return USBD_OK;
+}
+#endif
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_core.h b/codec2/branches/0.7/stm32/usb_lib/core/usbd_core.h
new file mode 100644 (file)
index 0000000..1fc8366
--- /dev/null
@@ -0,0 +1,114 @@
+/**
+  ******************************************************************************
+  * @file    usbd_core.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   Header file for usbd_core.c
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CORE_H
+#define __USBD_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+#include "usbd_def.h"
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USBD_CORE
+  * @brief This file is the Header file for usbd_core.c file
+  * @{
+  */
+
+
+/** @defgroup USBD_CORE_Exported_Defines
+  * @{
+  */
+
+typedef enum {
+  USBD_OK   = 0,
+  USBD_BUSY,
+  USBD_FAIL,
+}USBD_Status;
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_CORE_Exported_TypesDefinitions
+  * @{
+  */
+
+
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_CORE_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CORE_Exported_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_CORE_Exported_FunctionsPrototype
+  * @{
+  */
+void USBD_Init(USB_OTG_CORE_HANDLE *pdev,
+               USB_OTG_CORE_ID_TypeDef coreID,
+               USBD_DEVICE *pDevice,
+               USBD_Class_cb_TypeDef *class_cb,
+               USBD_Usr_cb_TypeDef *usr_cb);
+
+USBD_Status USBD_DeInit(USB_OTG_CORE_HANDLE *pdev);
+
+USBD_Status USBD_ClrCfg(USB_OTG_CORE_HANDLE  *pdev, uint8_t cfgidx);
+
+USBD_Status USBD_SetCfg(USB_OTG_CORE_HANDLE  *pdev, uint8_t cfgidx);
+
+/**
+  * @}
+  */
+
+#endif /* __USBD_CORE_H */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_def.h b/codec2/branches/0.7/stm32/usb_lib/core/usbd_def.h
new file mode 100644 (file)
index 0000000..40620c9
--- /dev/null
@@ -0,0 +1,149 @@
+/**
+  ******************************************************************************
+  * @file    usbd_def.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   general defines for the usb device library
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USBD_DEF_H
+#define __USBD_DEF_H
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_conf.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USB_DEF
+  * @brief general defines for the usb device library file
+  * @{
+  */
+
+/** @defgroup USB_DEF_Exported_Defines
+  * @{
+  */
+
+#ifndef NULL
+#define NULL    0
+#endif
+
+#define  USB_LEN_DEV_QUALIFIER_DESC                     0x0A
+#define  USB_LEN_DEV_DESC                               0x12
+#define  USB_LEN_CFG_DESC                               0x09
+#define  USB_LEN_IF_DESC                                0x09
+#define  USB_LEN_EP_DESC                                0x07
+#define  USB_LEN_OTG_DESC                               0x03
+
+#define  USBD_IDX_LANGID_STR                            0x00
+#define  USBD_IDX_MFC_STR                               0x01
+#define  USBD_IDX_PRODUCT_STR                           0x02
+#define  USBD_IDX_SERIAL_STR                            0x03
+#define  USBD_IDX_CONFIG_STR                            0x04
+#define  USBD_IDX_INTERFACE_STR                         0x05
+
+#define  USB_REQ_TYPE_STANDARD                          0x00
+#define  USB_REQ_TYPE_CLASS                             0x20
+#define  USB_REQ_TYPE_VENDOR                            0x40
+#define  USB_REQ_TYPE_MASK                              0x60
+
+#define  USB_REQ_RECIPIENT_DEVICE                       0x00
+#define  USB_REQ_RECIPIENT_INTERFACE                    0x01
+#define  USB_REQ_RECIPIENT_ENDPOINT                     0x02
+#define  USB_REQ_RECIPIENT_MASK                         0x03
+
+#define  USB_REQ_GET_STATUS                             0x00
+#define  USB_REQ_CLEAR_FEATURE                          0x01
+#define  USB_REQ_SET_FEATURE                            0x03
+#define  USB_REQ_SET_ADDRESS                            0x05
+#define  USB_REQ_GET_DESCRIPTOR                         0x06
+#define  USB_REQ_SET_DESCRIPTOR                         0x07
+#define  USB_REQ_GET_CONFIGURATION                      0x08
+#define  USB_REQ_SET_CONFIGURATION                      0x09
+#define  USB_REQ_GET_INTERFACE                          0x0A
+#define  USB_REQ_SET_INTERFACE                          0x0B
+#define  USB_REQ_SYNCH_FRAME                            0x0C
+
+#define  USB_DESC_TYPE_DEVICE                              1
+#define  USB_DESC_TYPE_CONFIGURATION                       2
+#define  USB_DESC_TYPE_STRING                              3
+#define  USB_DESC_TYPE_INTERFACE                           4
+#define  USB_DESC_TYPE_ENDPOINT                            5
+#define  USB_DESC_TYPE_DEVICE_QUALIFIER                    6
+#define  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION           7
+
+
+#define USB_CONFIG_REMOTE_WAKEUP                           2
+#define USB_CONFIG_SELF_POWERED                            1
+
+#define USB_FEATURE_EP_HALT                                0
+#define USB_FEATURE_REMOTE_WAKEUP                          1
+#define USB_FEATURE_TEST_MODE                              2
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_DEF_Exported_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_DEF_Exported_Macros
+  * @{
+  */
+#define  SWAPBYTE(addr)        (((uint16_t)(*((uint8_t *)(addr)))) + \
+                               (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8))
+
+#define LOBYTE(x)  ((uint8_t)(x & 0x00FF))
+#define HIBYTE(x)  ((uint8_t)((x & 0xFF00) >>8))
+/**
+  * @}
+  */
+
+/** @defgroup USBD_DEF_Exported_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_DEF_Exported_FunctionsPrototype
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+#endif /* __USBD_DEF_H */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_ioreq.c b/codec2/branches/0.7/stm32/usb_lib/core/usbd_ioreq.c
new file mode 100644 (file)
index 0000000..ea7cacf
--- /dev/null
@@ -0,0 +1,237 @@
+/**
+  ******************************************************************************
+  * @file    usbd_ioreq.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   This file provides the IO requests APIs for control endpoints.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_ioreq.h"
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_IOREQ
+  * @brief control I/O requests module
+  * @{
+  */
+
+/** @defgroup USBD_IOREQ_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_IOREQ_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_IOREQ_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_IOREQ_Private_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_IOREQ_Private_FunctionPrototypes
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_IOREQ_Private_Functions
+  * @{
+  */
+
+/**
+* @brief  USBD_CtlSendData
+*         send data on the ctl pipe
+* @param  pdev: device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be sent
+* @retval status
+*/
+USBD_Status  USBD_CtlSendData (USB_OTG_CORE_HANDLE  *pdev,
+                               uint8_t *pbuf,
+                               uint16_t len)
+{
+  USBD_Status ret = USBD_OK;
+
+  pdev->dev.in_ep[0].total_data_len = len;
+  pdev->dev.in_ep[0].rem_data_len   = len;
+  pdev->dev.device_state = USB_OTG_EP0_DATA_IN;
+
+  DCD_EP_Tx (pdev, 0, pbuf, len);
+
+  return ret;
+}
+
+/**
+* @brief  USBD_CtlContinueSendData
+*         continue sending data on the ctl pipe
+* @param  pdev: device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be sent
+* @retval status
+*/
+USBD_Status  USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE  *pdev,
+                                       uint8_t *pbuf,
+                                       uint16_t len)
+{
+  USBD_Status ret = USBD_OK;
+
+  DCD_EP_Tx (pdev, 0, pbuf, len);
+
+
+  return ret;
+}
+
+/**
+* @brief  USBD_CtlPrepareRx
+*         receive data on the ctl pipe
+* @param  pdev: USB OTG device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be received
+* @retval status
+*/
+USBD_Status  USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE  *pdev,
+                                  uint8_t *pbuf,
+                                  uint16_t len)
+{
+  USBD_Status ret = USBD_OK;
+
+  pdev->dev.out_ep[0].total_data_len = len;
+  pdev->dev.out_ep[0].rem_data_len   = len;
+  pdev->dev.device_state = USB_OTG_EP0_DATA_OUT;
+
+  DCD_EP_PrepareRx (pdev,
+                    0,
+                    pbuf,
+                    len);
+
+
+  return ret;
+}
+
+/**
+* @brief  USBD_CtlContinueRx
+*         continue receive data on the ctl pipe
+* @param  pdev: USB OTG device instance
+* @param  buff: pointer to data buffer
+* @param  len: length of data to be received
+* @retval status
+*/
+USBD_Status  USBD_CtlContinueRx (USB_OTG_CORE_HANDLE  *pdev,
+                                          uint8_t *pbuf,
+                                          uint16_t len)
+{
+  USBD_Status ret = USBD_OK;
+
+  DCD_EP_PrepareRx (pdev,
+                    0,
+                    pbuf,
+                    len);
+  return ret;
+}
+/**
+* @brief  USBD_CtlSendStatus
+*         send zero lzngth packet on the ctl pipe
+* @param  pdev: USB OTG device instance
+* @retval status
+*/
+USBD_Status  USBD_CtlSendStatus (USB_OTG_CORE_HANDLE  *pdev)
+{
+  USBD_Status ret = USBD_OK;
+  pdev->dev.device_state = USB_OTG_EP0_STATUS_IN;
+  DCD_EP_Tx (pdev,
+             0,
+             NULL,
+             0);
+
+  USB_OTG_EP0_OutStart(pdev);
+
+  return ret;
+}
+
+/**
+* @brief  USBD_CtlReceiveStatus
+*         receive zero lzngth packet on the ctl pipe
+* @param  pdev: USB OTG device instance
+* @retval status
+*/
+USBD_Status  USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE  *pdev)
+{
+  USBD_Status ret = USBD_OK;
+  pdev->dev.device_state = USB_OTG_EP0_STATUS_OUT;
+  DCD_EP_PrepareRx ( pdev,
+                    0,
+                    NULL,
+                    0);
+
+  USB_OTG_EP0_OutStart(pdev);
+
+  return ret;
+}
+
+
+/**
+* @brief  USBD_GetRxCount
+*         returns the received data length
+* @param  pdev: USB OTG device instance
+*         epnum: endpoint index
+* @retval Rx Data blength
+*/
+uint16_t  USBD_GetRxCount (USB_OTG_CORE_HANDLE  *pdev , uint8_t epnum)
+{
+  return pdev->dev.out_ep[epnum].xfer_count;
+}
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_ioreq.h b/codec2/branches/0.7/stm32/usb_lib/core/usbd_ioreq.h
new file mode 100644 (file)
index 0000000..6858eba
--- /dev/null
@@ -0,0 +1,115 @@
+/**
+  ******************************************************************************
+  * @file    usbd_ioreq.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   header file for the usbd_ioreq.c file
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USBD_IOREQ_H_
+#define __USBD_IOREQ_H_
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usbd_def.h"
+#include  "usbd_core.h"
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USBD_IOREQ
+  * @brief header file for the usbd_ioreq.c file
+  * @{
+  */
+
+/** @defgroup USBD_IOREQ_Exported_Defines
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_IOREQ_Exported_Types
+  * @{
+  */
+
+
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_IOREQ_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_IOREQ_Exported_Variables
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype
+  * @{
+  */
+
+USBD_Status  USBD_CtlSendData (USB_OTG_CORE_HANDLE  *pdev,
+                               uint8_t *buf,
+                               uint16_t len);
+
+USBD_Status  USBD_CtlContinueSendData (USB_OTG_CORE_HANDLE  *pdev,
+                               uint8_t *pbuf,
+                               uint16_t len);
+
+USBD_Status USBD_CtlPrepareRx (USB_OTG_CORE_HANDLE  *pdev,
+                               uint8_t *pbuf,
+                               uint16_t len);
+
+USBD_Status  USBD_CtlContinueRx (USB_OTG_CORE_HANDLE  *pdev,
+                              uint8_t *pbuf,
+                              uint16_t len);
+
+USBD_Status  USBD_CtlSendStatus (USB_OTG_CORE_HANDLE  *pdev);
+
+USBD_Status  USBD_CtlReceiveStatus (USB_OTG_CORE_HANDLE  *pdev);
+
+uint16_t  USBD_GetRxCount (USB_OTG_CORE_HANDLE  *pdev ,
+                           uint8_t epnum);
+
+/**
+  * @}
+  */
+
+#endif /* __USBD_IOREQ_H_ */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_req.c b/codec2/branches/0.7/stm32/usb_lib/core/usbd_req.c
new file mode 100644 (file)
index 0000000..40fca32
--- /dev/null
@@ -0,0 +1,868 @@
+/**
+  ******************************************************************************
+  * @file    usbd_req.c
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   This file provides the standard USB requests following chapter 9.
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_req.h"
+#include "usbd_ioreq.h"
+#include "usbd_desc.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+
+/** @defgroup USBD_REQ
+  * @brief USB standard requests module
+  * @{
+  */
+
+/** @defgroup USBD_REQ_Private_TypesDefinitions
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_REQ_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_REQ_Private_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_REQ_Private_Variables
+  * @{
+  */
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END  = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint32_t  USBD_default_cfg __ALIGN_END  = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint32_t  USBD_cfg_status __ALIGN_END  = 0;
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+  #if defined ( __ICCARM__ ) /*!< IAR Compiler */
+    #pragma data_alignment=4
+  #endif
+#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
+__ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ;
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_REQ_Private_FunctionPrototypes
+  * @{
+  */
+static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE  *pdev,
+                               USB_SETUP_REQ *req);
+
+static void USBD_SetAddress(USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req);
+
+static void USBD_SetConfig(USB_OTG_CORE_HANDLE  *pdev,
+                           USB_SETUP_REQ *req);
+
+static void USBD_GetConfig(USB_OTG_CORE_HANDLE  *pdev,
+                           USB_SETUP_REQ *req);
+
+static void USBD_GetStatus(USB_OTG_CORE_HANDLE  *pdev,
+                           USB_SETUP_REQ *req);
+
+static void USBD_SetFeature(USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req);
+
+static void USBD_ClrFeature(USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req);
+
+static uint8_t USBD_GetLen(uint8_t *buf);
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_REQ_Private_Functions
+  * @{
+  */
+
+
+/**
+* @brief  USBD_StdDevReq
+*         Handle standard usb device requests
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+USBD_Status  USBD_StdDevReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req)
+{
+  USBD_Status ret = USBD_OK;
+
+  switch (req->bRequest)
+  {
+  case USB_REQ_GET_DESCRIPTOR:
+
+    USBD_GetDescriptor (pdev, req) ;
+    break;
+
+  case USB_REQ_SET_ADDRESS:
+    USBD_SetAddress(pdev, req);
+    break;
+
+  case USB_REQ_SET_CONFIGURATION:
+    USBD_SetConfig (pdev , req);
+    break;
+
+  case USB_REQ_GET_CONFIGURATION:
+    USBD_GetConfig (pdev , req);
+    break;
+
+  case USB_REQ_GET_STATUS:
+    USBD_GetStatus (pdev , req);
+    break;
+
+
+  case USB_REQ_SET_FEATURE:
+    USBD_SetFeature (pdev , req);
+    break;
+
+  case USB_REQ_CLEAR_FEATURE:
+    USBD_ClrFeature (pdev , req);
+    break;
+
+  default:
+    USBD_CtlError(pdev , req);
+    break;
+  }
+
+  return ret;
+}
+
+/**
+* @brief  USBD_StdItfReq
+*         Handle standard usb interface requests
+* @param  pdev: USB OTG device instance
+* @param  req: usb request
+* @retval status
+*/
+USBD_Status  USBD_StdItfReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req)
+{
+  USBD_Status ret = USBD_OK;
+
+  switch (pdev->dev.device_status)
+  {
+  case USB_OTG_CONFIGURED:
+
+    if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
+    {
+      pdev->dev.class_cb->Setup (pdev, req);
+
+      if((req->wLength == 0)&& (ret == USBD_OK))
+      {
+         USBD_CtlSendStatus(pdev);
+      }
+    }
+    else
+    {
+       USBD_CtlError(pdev , req);
+    }
+    break;
+
+  default:
+     USBD_CtlError(pdev , req);
+    break;
+  }
+  return ret;
+}
+
+/**
+* @brief  USBD_StdEPReq
+*         Handle standard usb endpoint requests
+* @param  pdev: USB OTG device instance
+* @param  req: usb request
+* @retval status
+*/
+USBD_Status  USBD_StdEPReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req)
+{
+
+  uint8_t   ep_addr;
+  USBD_Status ret = USBD_OK;
+
+  ep_addr  = LOBYTE(req->wIndex);
+
+  switch (req->bRequest)
+  {
+
+  case USB_REQ_SET_FEATURE :
+
+    switch (pdev->dev.device_status)
+    {
+    case USB_OTG_ADDRESSED:
+      if ((ep_addr != 0x00) && (ep_addr != 0x80))
+      {
+        DCD_EP_Stall(pdev , ep_addr);
+      }
+      break;
+
+    case USB_OTG_CONFIGURED:
+      if (req->wValue == USB_FEATURE_EP_HALT)
+      {
+        if ((ep_addr != 0x00) && (ep_addr != 0x80))
+        {
+          DCD_EP_Stall(pdev , ep_addr);
+
+        }
+      }
+      pdev->dev.class_cb->Setup (pdev, req);
+      USBD_CtlSendStatus(pdev);
+
+      break;
+
+    default:
+      USBD_CtlError(pdev , req);
+      break;
+    }
+    break;
+
+  case USB_REQ_CLEAR_FEATURE :
+
+    switch (pdev->dev.device_status)
+    {
+    case USB_OTG_ADDRESSED:
+      if ((ep_addr != 0x00) && (ep_addr != 0x80))
+      {
+        DCD_EP_Stall(pdev , ep_addr);
+      }
+      break;
+
+    case USB_OTG_CONFIGURED:
+      if (req->wValue == USB_FEATURE_EP_HALT)
+      {
+        if ((ep_addr != 0x00) && (ep_addr != 0x80))
+        {
+          DCD_EP_ClrStall(pdev , ep_addr);
+          pdev->dev.class_cb->Setup (pdev, req);
+        }
+        USBD_CtlSendStatus(pdev);
+      }
+      break;
+
+    default:
+       USBD_CtlError(pdev , req);
+      break;
+    }
+    break;
+
+  case USB_REQ_GET_STATUS:
+    switch (pdev->dev.device_status)
+    {
+    case USB_OTG_ADDRESSED:
+      if ((ep_addr != 0x00) && (ep_addr != 0x80))
+      {
+        DCD_EP_Stall(pdev , ep_addr);
+      }
+      break;
+
+    case USB_OTG_CONFIGURED:
+
+
+      if ((ep_addr & 0x80)== 0x80)
+      {
+        if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall)
+        {
+          USBD_ep_status = 0x0001;
+        }
+        else
+        {
+          USBD_ep_status = 0x0000;
+        }
+      }
+      else if ((ep_addr & 0x80)== 0x00)
+      {
+        if(pdev->dev.out_ep[ep_addr].is_stall)
+        {
+          USBD_ep_status = 0x0001;
+        }
+
+        else
+        {
+          USBD_ep_status = 0x0000;
+        }
+      }
+      USBD_CtlSendData (pdev,
+                        (uint8_t *)&USBD_ep_status,
+                        2);
+      break;
+
+    default:
+       USBD_CtlError(pdev , req);
+      break;
+    }
+    break;
+
+  default:
+    break;
+  }
+  return ret;
+}
+/**
+* @brief  USBD_GetDescriptor
+*         Handle Get Descriptor requests
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE  *pdev,
+                               USB_SETUP_REQ *req)
+{
+  uint16_t len;
+  uint8_t *pbuf;
+
+  switch (req->wValue >> 8)
+  {
+  case USB_DESC_TYPE_DEVICE:
+    pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len);
+    if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT))
+    {
+      len = 8;
+    }
+    break;
+
+  case USB_DESC_TYPE_CONFIGURATION:
+      pbuf   = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
+#ifdef USB_OTG_HS_CORE
+    if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&&
+       (pdev->cfg.phy_itface  == USB_OTG_ULPI_PHY))
+    {
+      pbuf   = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
+    }
+#endif
+    pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
+    pdev->dev.pConfig_descriptor = pbuf;
+    break;
+
+  case USB_DESC_TYPE_STRING:
+    switch ((uint8_t)(req->wValue))
+    {
+    case USBD_IDX_LANGID_STR:
+     pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len);
+      break;
+
+    case USBD_IDX_MFC_STR:
+      pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len);
+      break;
+
+    case USBD_IDX_PRODUCT_STR:
+      pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len);
+      break;
+
+    case USBD_IDX_SERIAL_STR:
+      pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len);
+      break;
+
+    case USBD_IDX_CONFIG_STR:
+      pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len);
+      break;
+
+    case USBD_IDX_INTERFACE_STR:
+      pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len);
+      break;
+
+    default:
+#ifdef USB_SUPPORT_USER_STRING_DESC
+      pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len);
+      break;
+#else
+       USBD_CtlError(pdev , req);
+      return;
+#endif /* USBD_CtlError(pdev , req); */
+    }
+    break;
+  case USB_DESC_TYPE_DEVICE_QUALIFIER:
+#ifdef USB_OTG_HS_CORE
+    if(pdev->cfg.speed == USB_OTG_SPEED_HIGH  )
+    {
+
+      pbuf   = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
+
+      USBD_DeviceQualifierDesc[4]= pbuf[14];
+      USBD_DeviceQualifierDesc[5]= pbuf[15];
+      USBD_DeviceQualifierDesc[6]= pbuf[16];
+
+      pbuf = USBD_DeviceQualifierDesc;
+      len  = USB_LEN_DEV_QUALIFIER_DESC;
+      break;
+    }
+    else
+    {
+      USBD_CtlError(pdev , req);
+      return;
+    }
+#else
+      USBD_CtlError(pdev , req);
+      return;
+#endif
+
+  case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
+#ifdef USB_OTG_HS_CORE
+
+    if(pdev->cfg.speed == USB_OTG_SPEED_HIGH  )
+    {
+      pbuf   = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
+      pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
+      break;
+    }
+    else
+    {
+      USBD_CtlError(pdev , req);
+      return;
+    }
+#else
+      USBD_CtlError(pdev , req);
+      return;
+#endif
+
+
+  default:
+     USBD_CtlError(pdev , req);
+    return;
+  }
+
+  if((len != 0)&& (req->wLength != 0))
+  {
+
+    len = MIN(len , req->wLength);
+
+    USBD_CtlSendData (pdev,
+                      pbuf,
+                      len);
+  }
+
+}
+
+/**
+* @brief  USBD_SetAddress
+*         Set device address
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_SetAddress(USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req)
+{
+  uint8_t  dev_addr;
+
+  if ((req->wIndex == 0) && (req->wLength == 0))
+  {
+    dev_addr = (uint8_t)(req->wValue) & 0x7F;
+
+    if (pdev->dev.device_status == USB_OTG_CONFIGURED)
+    {
+      USBD_CtlError(pdev , req);
+    }
+    else
+    {
+      pdev->dev.device_address = dev_addr;
+      DCD_EP_SetAddress(pdev, dev_addr);
+      USBD_CtlSendStatus(pdev);
+
+      if (dev_addr != 0)
+      {
+        pdev->dev.device_status  = USB_OTG_ADDRESSED;
+      }
+      else
+      {
+        pdev->dev.device_status  = USB_OTG_DEFAULT;
+      }
+    }
+  }
+  else
+  {
+     USBD_CtlError(pdev , req);
+  }
+}
+
+/**
+* @brief  USBD_SetConfig
+*         Handle Set device configuration request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_SetConfig(USB_OTG_CORE_HANDLE  *pdev,
+                           USB_SETUP_REQ *req)
+{
+
+  static uint8_t  cfgidx;
+
+  cfgidx = (uint8_t)(req->wValue);
+
+  if (cfgidx > USBD_CFG_MAX_NUM )
+  {
+     USBD_CtlError(pdev , req);
+  }
+  else
+  {
+    switch (pdev->dev.device_status)
+    {
+    case USB_OTG_ADDRESSED:
+      if (cfgidx)
+      {
+        pdev->dev.device_config = cfgidx;
+        pdev->dev.device_status = USB_OTG_CONFIGURED;
+        USBD_SetCfg(pdev , cfgidx);
+        USBD_CtlSendStatus(pdev);
+      }
+      else
+      {
+         USBD_CtlSendStatus(pdev);
+      }
+      break;
+
+    case USB_OTG_CONFIGURED:
+      if (cfgidx == 0)
+      {
+        pdev->dev.device_status = USB_OTG_ADDRESSED;
+        pdev->dev.device_config = cfgidx;
+        USBD_ClrCfg(pdev , cfgidx);
+        USBD_CtlSendStatus(pdev);
+
+      }
+      else  if (cfgidx != pdev->dev.device_config)
+      {
+        /* Clear old configuration */
+        USBD_ClrCfg(pdev , pdev->dev.device_config);
+
+        /* set new configuration */
+        pdev->dev.device_config = cfgidx;
+        USBD_SetCfg(pdev , cfgidx);
+        USBD_CtlSendStatus(pdev);
+      }
+      else
+      {
+        USBD_CtlSendStatus(pdev);
+      }
+      break;
+
+    default:
+       USBD_CtlError(pdev , req);
+      break;
+    }
+  }
+}
+
+/**
+* @brief  USBD_GetConfig
+*         Handle Get device configuration request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_GetConfig(USB_OTG_CORE_HANDLE  *pdev,
+                           USB_SETUP_REQ *req)
+{
+
+  if (req->wLength != 1)
+  {
+     USBD_CtlError(pdev , req);
+  }
+  else
+  {
+    switch (pdev->dev.device_status )
+    {
+    case USB_OTG_ADDRESSED:
+
+      USBD_CtlSendData (pdev,
+                        (uint8_t *)&USBD_default_cfg,
+                        1);
+      break;
+
+    case USB_OTG_CONFIGURED:
+
+      USBD_CtlSendData (pdev,
+                        &pdev->dev.device_config,
+                        1);
+      break;
+
+    default:
+       USBD_CtlError(pdev , req);
+      break;
+    }
+  }
+}
+
+/**
+* @brief  USBD_GetStatus
+*         Handle Get Status request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_GetStatus(USB_OTG_CORE_HANDLE  *pdev,
+                           USB_SETUP_REQ *req)
+{
+
+  switch (pdev->dev.device_status)
+  {
+  case USB_OTG_ADDRESSED:
+  case USB_OTG_CONFIGURED:
+
+    if (pdev->dev.DevRemoteWakeup)
+    {
+      USBD_cfg_status = USB_CONFIG_SELF_POWERED | USB_CONFIG_REMOTE_WAKEUP;
+    }
+    else
+    {
+      USBD_cfg_status = USB_CONFIG_SELF_POWERED;
+    }
+
+    USBD_CtlSendData (pdev,
+                      (uint8_t *)&USBD_cfg_status,
+                      1);
+    break;
+
+  default :
+    USBD_CtlError(pdev , req);
+    break;
+  }
+}
+
+
+/**
+* @brief  USBD_SetFeature
+*         Handle Set device feature request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_SetFeature(USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req)
+{
+
+  USB_OTG_DCTL_TypeDef     dctl;
+  uint8_t test_mode = 0;
+
+  if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
+  {
+    pdev->dev.DevRemoteWakeup = 1;
+    pdev->dev.class_cb->Setup (pdev, req);
+    USBD_CtlSendStatus(pdev);
+  }
+
+  else if ((req->wValue == USB_FEATURE_TEST_MODE) &&
+           ((req->wIndex & 0xFF) == 0))
+  {
+    dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+
+    test_mode = req->wIndex >> 8;
+    switch (test_mode)
+    {
+    case 1: // TEST_J
+      dctl.b.tstctl = 1;
+      break;
+
+    case 2: // TEST_K
+      dctl.b.tstctl = 2;
+      break;
+
+    case 3: // TEST_SE0_NAK
+      dctl.b.tstctl = 3;
+      break;
+
+    case 4: // TEST_PACKET
+      dctl.b.tstctl = 4;
+      break;
+
+    case 5: // TEST_FORCE_ENABLE
+      dctl.b.tstctl = 5;
+      break;
+    }
+    USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
+    USBD_CtlSendStatus(pdev);
+  }
+
+}
+
+
+/**
+* @brief  USBD_ClrFeature
+*         Handle clear device feature request
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval status
+*/
+static void USBD_ClrFeature(USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req)
+{
+  switch (pdev->dev.device_status)
+  {
+  case USB_OTG_ADDRESSED:
+  case USB_OTG_CONFIGURED:
+    if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
+    {
+      pdev->dev.DevRemoteWakeup = 0;
+      pdev->dev.class_cb->Setup (pdev, req);
+      USBD_CtlSendStatus(pdev);
+    }
+    break;
+
+  default :
+     USBD_CtlError(pdev , req);
+    break;
+  }
+}
+
+/**
+* @brief  USBD_ParseSetupRequest
+*         Copy buffer into setup structure
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval None
+*/
+
+void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req)
+{
+  req->bmRequest     = *(uint8_t *)  (pdev->dev.setup_packet);
+  req->bRequest      = *(uint8_t *)  (pdev->dev.setup_packet +  1);
+  req->wValue        = SWAPBYTE      (pdev->dev.setup_packet +  2);
+  req->wIndex        = SWAPBYTE      (pdev->dev.setup_packet +  4);
+  req->wLength       = SWAPBYTE      (pdev->dev.setup_packet +  6);
+
+  pdev->dev.in_ep[0].ctl_data_len = req->wLength  ;
+  pdev->dev.device_state = USB_OTG_EP0_SETUP;
+}
+
+/**
+* @brief  USBD_CtlError
+*         Handle USB low level Error
+* @param  pdev: device instance
+* @param  req: usb request
+* @retval None
+*/
+
+void USBD_CtlError( USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req)
+{
+  if((req->bmRequest & 0x80) == 0x80)
+  {
+    DCD_EP_Stall(pdev , 0x80);
+  }
+  else
+  {
+    if(req->wLength == 0)
+    {
+       DCD_EP_Stall(pdev , 0x80);
+    }
+    else
+    {
+      DCD_EP_Stall(pdev , 0);
+    }
+  }
+  USB_OTG_EP0_OutStart(pdev);
+}
+
+
+/**
+  * @brief  USBD_GetString
+  *         Convert Ascii string into unicode one
+  * @param  desc : descriptor buffer
+  * @param  unicode : Formatted string buffer (unicode)
+  * @param  len : descriptor length
+  * @retval None
+  */
+void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
+{
+  uint8_t idx = 0;
+
+  if (desc != NULL)
+  {
+    *len =  USBD_GetLen(desc) * 2 + 2;
+    unicode[idx++] = *len;
+    unicode[idx++] =  USB_DESC_TYPE_STRING;
+
+    while (*desc != NULL)
+    {
+      unicode[idx++] = *desc++;
+      unicode[idx++] =  0x00;
+    }
+  }
+}
+
+/**
+  * @brief  USBD_GetLen
+  *         return the string length
+   * @param  buf : pointer to the ascii string buffer
+  * @retval string length
+  */
+static uint8_t USBD_GetLen(uint8_t *buf)
+{
+    uint8_t  len = 0;
+
+    while (*buf != NULL)
+    {
+        len++;
+        buf++;
+    }
+
+    return len;
+}
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_req.h b/codec2/branches/0.7/stm32/usb_lib/core/usbd_req.h
new file mode 100644 (file)
index 0000000..f73bb45
--- /dev/null
@@ -0,0 +1,102 @@
+/**
+  ******************************************************************************
+  * @file    usbd_req.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   header file for the usbd_req.c file
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+
+#ifndef __USB_REQUEST_H_
+#define __USB_REQUEST_H_
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usbd_def.h"
+#include  "usbd_core.h"
+#include  "usbd_conf.h"
+
+
+/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
+  * @{
+  */
+
+/** @defgroup USBD_REQ
+  * @brief header file for the usbd_ioreq.c file
+  * @{
+  */
+
+/** @defgroup USBD_REQ_Exported_Defines
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup USBD_REQ_Exported_Types
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_REQ_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USBD_REQ_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USBD_REQ_Exported_FunctionsPrototype
+  * @{
+  */
+
+USBD_Status  USBD_StdDevReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req);
+USBD_Status  USBD_StdItfReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req);
+USBD_Status  USBD_StdEPReq (USB_OTG_CORE_HANDLE  *pdev, USB_SETUP_REQ  *req);
+void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE  *pdev,
+                                    USB_SETUP_REQ *req);
+
+void USBD_CtlError( USB_OTG_CORE_HANDLE  *pdev,
+                            USB_SETUP_REQ *req);
+
+void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len);
+/**
+  * @}
+  */
+
+#endif /* __USB_REQUEST_H_ */
+
+/**
+  * @}
+  */
+
+/**
+* @}
+*/
+
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/core/usbd_usr.h b/codec2/branches/0.7/stm32/usb_lib/core/usbd_usr.h
new file mode 100644 (file)
index 0000000..976cc13
--- /dev/null
@@ -0,0 +1,135 @@
+/**
+  ******************************************************************************
+  * @file    usbd_usr.h
+  * @author  MCD Application Team
+  * @version V1.0.0
+  * @date    22-July-2011
+  * @brief   Header file for usbd_usr.c
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_USR_H__
+#define __USBD_USR_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbd_core.h"
+
+
+/** @addtogroup USBD_USER
+  * @{
+  */
+
+/** @addtogroup USBD_MSC_DEMO_USER_CALLBACKS
+  * @{
+  */
+
+/** @defgroup USBD_USR
+  * @brief This file is the Header file for usbd_usr.c
+  * @{
+  */
+
+
+/** @defgroup USBD_USR_Exported_Types
+  * @{
+  */
+
+extern  USBD_Usr_cb_TypeDef USR_cb;
+extern  USBD_Usr_cb_TypeDef USR_FS_cb;
+extern  USBD_Usr_cb_TypeDef USR_HS_cb;
+
+
+
+/**
+  * @}
+  */
+
+
+
+/** @defgroup USBD_USR_Exported_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_USR_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USBD_USR_Exported_Variables
+  * @{
+  */
+
+void     USBD_USR_Init(void);
+void     USBD_USR_DeviceReset (uint8_t speed);
+void     USBD_USR_DeviceConfigured (void);
+void     USBD_USR_DeviceSuspended(void);
+void     USBD_USR_DeviceResumed(void);
+
+void     USBD_USR_DeviceConnected(void);
+void     USBD_USR_DeviceDisconnected(void);
+
+void     USBD_USR_FS_Init(void);
+void     USBD_USR_FS_DeviceReset (uint8_t speed);
+void     USBD_USR_FS_DeviceConfigured (void);
+void     USBD_USR_FS_DeviceSuspended(void);
+void     USBD_USR_FS_DeviceResumed(void);
+
+void     USBD_USR_FS_DeviceConnected(void);
+void     USBD_USR_FS_DeviceDisconnected(void);
+
+void     USBD_USR_HS_Init(void);
+void     USBD_USR_HS_DeviceReset (uint8_t speed);
+void     USBD_USR_HS_DeviceConfigured (void);
+void     USBD_USR_HS_DeviceSuspended(void);
+void     USBD_USR_HS_DeviceResumed(void);
+
+void     USBD_USR_HS_DeviceConnected(void);
+void     USBD_USR_HS_DeviceDisconnected(void);
+
+/**
+  * @}
+  */
+
+/** @defgroup USBD_USR_Exported_FunctionsPrototype
+  * @{
+  */
+/**
+  * @}
+  */
+
+#endif /*__USBD_USR_H__*/
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
+
+
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_core.c b/codec2/branches/0.7/stm32/usb_lib/otg/usb_core.c
new file mode 100644 (file)
index 0000000..1832106
--- /dev/null
@@ -0,0 +1,2187 @@
+/**
+  ******************************************************************************
+  * @file    usb_core.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   USB-OTG Core Layer
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_CORE
+* @brief This file includes the USB-OTG Core Layer
+* @{
+*/
+
+
+/** @defgroup USB_CORE_Private_Defines
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_FunctionPrototypes
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_CORE_Private_Functions
+* @{
+*/
+
+/**
+* @brief  USB_OTG_EnableCommonInt
+*         Initializes the commmon interrupts, used in both device and modes
+* @param  pdev : Selected device
+* @retval None
+*/
+static void USB_OTG_EnableCommonInt(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTMSK_TypeDef  int_mask;
+
+  int_mask.d32 = 0;
+  /* Clear any pending USB_OTG Interrupts */
+#ifndef USE_OTG_MODE
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GOTGINT, 0xFFFFFFFF);
+#endif
+  /* Clear any pending interrupts */
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF);
+  /* Enable the interrupts in the INTMSK */
+  int_mask.b.wkupintr = 1;
+  int_mask.b.usbsuspend = 1;
+
+#ifdef USE_OTG_MODE
+  int_mask.b.otgintr = 1;
+  int_mask.b.sessreqintr = 1;
+  int_mask.b.conidstschng = 1;
+#endif
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32);
+}
+
+/**
+* @brief  USB_OTG_CoreReset : Soft reset of the core
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+static USB_OTG_STS USB_OTG_CoreReset(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  __IO USB_OTG_GRSTCTL_TypeDef  greset;
+  uint32_t count = 0;
+
+  greset.d32 = 0;
+  /* Wait for AHB master IDLE state. */
+  do
+  {
+    USB_OTG_BSP_uDelay(3);
+    greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL);
+    if (++count > 200000)
+    {
+      return USB_OTG_OK;
+    }
+  }
+  while (greset.b.ahbidle == 0);
+  /* Core Soft Reset */
+  count = 0;
+  greset.b.csftrst = 1;
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32 );
+  do
+  {
+    greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL);
+    if (++count > 200000)
+    {
+      break;
+    }
+  }
+  while (greset.b.csftrst == 1);
+  /* Wait for 3 PHY Clocks*/
+  USB_OTG_BSP_uDelay(3);
+  return status;
+}
+
+/**
+* @brief  USB_OTG_WritePacket : Writes a packet into the Tx FIFO associated
+*         with the EP
+* @param  pdev : Selected device
+* @param  src : source pointer
+* @param  ch_ep_num : end point number
+* @param  bytes : No. of bytes
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev,
+                                uint8_t             *src,
+                                uint8_t             ch_ep_num,
+                                uint16_t            len)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  if (pdev->cfg.dma_enable == 0)
+  {
+    uint32_t count32b= 0 , i= 0;
+    __IO uint32_t *fifo;
+
+    count32b =  (len + 3) / 4;
+    fifo = pdev->regs.DFIFO[ch_ep_num];
+    for (i = 0; i < count32b; i++, src+=4)
+    {
+      USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) );
+    }
+  }
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_ReadPacket : Reads a packet from the Rx FIFO
+* @param  pdev : Selected device
+* @param  dest : Destination Pointer
+* @param  bytes : No. of bytes
+* @retval None
+*/
+void *USB_OTG_ReadPacket(USB_OTG_CORE_HANDLE *pdev,
+                         uint8_t *dest,
+                         uint16_t len)
+{
+  uint32_t i=0;
+  uint32_t count32b = (len + 3) / 4;
+
+  __IO uint32_t *fifo = pdev->regs.DFIFO[0];
+
+  for ( i = 0; i < count32b; i++, dest += 4 )
+  {
+    *(__packed uint32_t *)dest = USB_OTG_READ_REG32(fifo);
+
+  }
+  return ((void *)dest);
+}
+
+/**
+* @brief  USB_OTG_SelectCore
+*         Initialize core registers address.
+* @param  pdev : Selected device
+* @param  coreID : USB OTG Core ID
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_SelectCore(USB_OTG_CORE_HANDLE *pdev,
+                               USB_OTG_CORE_ID_TypeDef coreID)
+{
+  uint32_t i , baseAddress = 0;
+  USB_OTG_STS status = USB_OTG_OK;
+
+  pdev->cfg.dma_enable       = 0;
+
+  /* at startup the core is in FS mode */
+  pdev->cfg.speed            = USB_OTG_SPEED_FULL;
+  pdev->cfg.mps              = USB_OTG_FS_MAX_PACKET_SIZE ;
+
+  /* initialize device cfg following its address */
+  if (coreID == USB_OTG_FS_CORE_ID)
+  {
+    baseAddress                = USB_OTG_FS_BASE_ADDR;
+    pdev->cfg.coreID           = USB_OTG_FS_CORE_ID;
+    pdev->cfg.host_channels    = 8 ;
+    pdev->cfg.dev_endpoints    = 4 ;
+    pdev->cfg.TotalFifoSize    = 320; /* in 32-bits */
+    pdev->cfg.phy_itface       = USB_OTG_EMBEDDED_PHY;
+
+#ifdef USB_OTG_FS_SOF_OUTPUT_ENABLED
+    pdev->cfg.Sof_output       = 1;
+#endif
+
+#ifdef USB_OTG_FS_LOW_PWR_MGMT_SUPPORT
+    pdev->cfg.low_power        = 1;
+#endif
+  }
+  else if (coreID == USB_OTG_HS_CORE_ID)
+  {
+    baseAddress                = USB_OTG_HS_BASE_ADDR;
+    pdev->cfg.coreID           = USB_OTG_HS_CORE_ID;
+    pdev->cfg.host_channels    = 12 ;
+    pdev->cfg.dev_endpoints    = 6 ;
+    pdev->cfg.TotalFifoSize    = 1280;/* in 32-bits */
+
+#ifdef USB_OTG_ULPI_PHY_ENABLED
+    pdev->cfg.phy_itface       = USB_OTG_ULPI_PHY;
+#else
+ #ifdef USB_OTG_EMBEDDED_PHY_ENABLED
+    pdev->cfg.phy_itface       = USB_OTG_EMBEDDED_PHY;
+ #else
+   #ifdef USB_OTG_I2C_PHY_ENABLED
+    pdev->cfg.phy_itface       = USB_OTG_I2C_PHY;
+   #endif
+ #endif
+#endif
+
+#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
+    pdev->cfg.dma_enable       = 1;
+#endif
+
+#ifdef USB_OTG_HS_SOF_OUTPUT_ENABLED
+    pdev->cfg.Sof_output       = 1;
+#endif
+
+#ifdef USB_OTG_HS_LOW_PWR_MGMT_SUPPORT
+    pdev->cfg.low_power        = 1;
+#endif
+
+  }
+
+  pdev->regs.GREGS = (USB_OTG_GREGS *)(baseAddress + \
+    USB_OTG_CORE_GLOBAL_REGS_OFFSET);
+  pdev->regs.DREGS =  (USB_OTG_DREGS  *)  (baseAddress + \
+    USB_OTG_DEV_GLOBAL_REG_OFFSET);
+
+  for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+  {
+    pdev->regs.INEP_REGS[i]  = (USB_OTG_INEPREGS *)  \
+      (baseAddress + USB_OTG_DEV_IN_EP_REG_OFFSET + \
+        (i * USB_OTG_EP_REG_OFFSET));
+    pdev->regs.OUTEP_REGS[i] = (USB_OTG_OUTEPREGS *) \
+      (baseAddress + USB_OTG_DEV_OUT_EP_REG_OFFSET + \
+        (i * USB_OTG_EP_REG_OFFSET));
+  }
+  pdev->regs.HREGS = (USB_OTG_HREGS *)(baseAddress + \
+    USB_OTG_HOST_GLOBAL_REG_OFFSET);
+  pdev->regs.HPRT0 = (uint32_t *)(baseAddress + USB_OTG_HOST_PORT_REGS_OFFSET);
+
+  for (i = 0; i < pdev->cfg.host_channels; i++)
+  {
+    pdev->regs.HC_REGS[i] = (USB_OTG_HC_REGS *)(baseAddress + \
+      USB_OTG_HOST_CHAN_REGS_OFFSET + \
+        (i * USB_OTG_CHAN_REGS_OFFSET));
+  }
+  for (i = 0; i < pdev->cfg.host_channels; i++)
+  {
+    pdev->regs.DFIFO[i] = (uint32_t *)(baseAddress + USB_OTG_DATA_FIFO_OFFSET +\
+      (i * USB_OTG_DATA_FIFO_SIZE));
+  }
+  pdev->regs.PCGCCTL = (uint32_t *)(baseAddress + USB_OTG_PCGCCTL_OFFSET);
+
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_CoreInit
+*         Initializes the USB_OTG controller registers and prepares the core
+*         device mode or host mode operation.
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_CoreInit(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_GUSBCFG_TypeDef  usbcfg;
+  USB_OTG_GCCFG_TypeDef    gccfg;
+  USB_OTG_GI2CCTL_TypeDef  i2cctl;
+  USB_OTG_GAHBCFG_TypeDef  ahbcfg;
+
+  usbcfg.d32 = 0;
+  gccfg.d32 = 0;
+  ahbcfg.d32 = 0;
+
+
+
+  if (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY)
+  {
+    gccfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GCCFG);
+    gccfg.b.pwdn = 0;
+
+    if (pdev->cfg.Sof_output)
+    {
+      gccfg.b.sofouten = 1;
+    }
+    USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32);
+
+    /* Init The ULPI Interface */
+    usbcfg.d32 = 0;
+    usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+    usbcfg.b.physel            = 0; /* HS Interface */
+#ifdef USB_OTG_INTERNAL_VBUS_ENABLED
+    usbcfg.b.ulpi_ext_vbus_drv = 0; /* Use internal VBUS */
+#else
+ #ifdef USB_OTG_EXTERNAL_VBUS_ENABLED
+    usbcfg.b.ulpi_ext_vbus_drv = 1; /* Use external VBUS */
+ #endif
+#endif
+    usbcfg.b.term_sel_dl_pulse = 0; /* Data line pulsing using utmi_txvalid */
+    usbcfg.b.ulpi_utmi_sel     = 1; /* ULPI seleInterfacect */
+
+    usbcfg.b.phyif             = 0; /* 8 bits */
+    usbcfg.b.ddrsel            = 0; /* single data rate */
+
+    usbcfg.b.ulpi_fsls = 0;
+    usbcfg.b.ulpi_clk_sus_m = 0;
+    USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+
+    /* Reset after a PHY select  */
+    USB_OTG_CoreReset(pdev);
+
+    if(pdev->cfg.dma_enable == 1)
+    {
+
+      ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/
+      ahbcfg.b.dmaenable = 1;
+      USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32);
+
+    }
+  }
+  else /* FS interface (embedded Phy or I2C Phy) */
+  {
+
+    usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);;
+    usbcfg.b.physel  = 1; /* FS Interface */
+    USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+    /* Reset after a PHY select and set Host mode */
+    USB_OTG_CoreReset(pdev);
+    /* Enable the I2C interface and deactivate the power down*/
+    gccfg.d32 = 0;
+    gccfg.b.pwdn = 1;
+
+    if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY)
+    {
+      gccfg.b.i2cifen = 1;
+    }
+    gccfg.b.vbussensingA = 1 ;
+    gccfg.b.vbussensingB = 1 ;
+#ifndef VBUS_SENSING_ENABLED
+    gccfg.b.disablevbussensing = 1;
+#endif
+
+    if(pdev->cfg.Sof_output)
+    {
+      gccfg.b.sofouten = 1;
+    }
+
+    USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GCCFG, gccfg.d32);
+    USB_OTG_BSP_mDelay(20);
+    /* Program GUSBCFG.OtgUtmifsSel to I2C*/
+    usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+    if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY)
+    {
+      usbcfg.b.otgutmifssel = 1;
+    }
+
+    USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+
+    if(pdev->cfg.phy_itface == USB_OTG_I2C_PHY)
+    {
+      /*Program GI2CCTL.I2CEn*/
+      i2cctl.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GI2CCTL);
+      i2cctl.b.i2cdevaddr = 1;
+      i2cctl.b.i2cen = 0;
+      i2cctl.b.dat_se0 = 1;
+      i2cctl.b.addr = 0x2D;
+      USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32);
+
+      USB_OTG_BSP_mDelay(200);
+
+      i2cctl.b.i2cen = 1;
+      USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GI2CCTL, i2cctl.d32);
+      USB_OTG_BSP_mDelay(200);
+    }
+  }
+  /* case the HS core is working in FS mode */
+  if(pdev->cfg.dma_enable == 1)
+  {
+
+    ahbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GAHBCFG);
+    ahbcfg.b.hburstlen = 5; /* 64 x 32-bits*/
+    ahbcfg.b.dmaenable = 1;
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32);
+
+  }
+  /* initialize OTG features */
+#ifdef  USE_OTG_MODE
+  usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+  usbcfg.b.hnpcap = 1;
+  usbcfg.b.srpcap = 1;
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+  USB_OTG_EnableCommonInt(pdev);
+#endif
+  return status;
+}
+/**
+* @brief  USB_OTG_EnableGlobalInt
+*         Enables the controller's Global Int in the AHB Config reg
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableGlobalInt(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_GAHBCFG_TypeDef  ahbcfg;
+
+  ahbcfg.d32 = 0;
+  ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+  USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, 0, ahbcfg.d32);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_DisableGlobalInt
+*         Enables the controller's Global Int in the AHB Config reg
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_GAHBCFG_TypeDef  ahbcfg;
+  ahbcfg.d32 = 0;
+  ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
+  USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GAHBCFG, ahbcfg.d32, 0);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_FlushTxFifo : Flush a Tx FIFO
+* @param  pdev : Selected device
+* @param  num : FO num
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_FlushTxFifo (USB_OTG_CORE_HANDLE *pdev , uint32_t num )
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  __IO USB_OTG_GRSTCTL_TypeDef  greset;
+
+  uint32_t count = 0;
+  greset.d32 = 0;
+  greset.b.txfflsh = 1;
+  greset.b.txfnum  = num;
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 );
+  do
+  {
+    greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL);
+    if (++count > 200000)
+    {
+      break;
+    }
+  }
+  while (greset.b.txfflsh == 1);
+  /* Wait for 3 PHY Clocks*/
+  USB_OTG_BSP_uDelay(3);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_FlushRxFifo : Flush a Rx FIFO
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_FlushRxFifo( USB_OTG_CORE_HANDLE *pdev )
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  __IO USB_OTG_GRSTCTL_TypeDef  greset;
+  uint32_t count = 0;
+
+  greset.d32 = 0;
+  greset.b.rxfflsh = 1;
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GRSTCTL, greset.d32 );
+  do
+  {
+    greset.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRSTCTL);
+    if (++count > 200000)
+    {
+      break;
+    }
+  }
+  while (greset.b.rxfflsh == 1);
+  /* Wait for 3 PHY Clocks*/
+  USB_OTG_BSP_uDelay(3);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_SetCurrentMode : Set ID line
+* @param  pdev : Selected device
+* @param  mode :  (Host/device)
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE *pdev , uint8_t mode)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_GUSBCFG_TypeDef  usbcfg;
+
+  usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+  usbcfg.b.force_host = 0;
+  usbcfg.b.force_dev = 0;
+
+  if ( mode == HOST_MODE)
+  {
+    usbcfg.b.force_host = 1;
+  }
+  else if ( mode == DEVICE_MODE)
+  {
+    usbcfg.b.force_dev = 1;
+  }
+
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32);
+  USB_OTG_BSP_mDelay(50);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_GetMode : Get current mode
+* @param  pdev : Selected device
+* @retval current mode
+*/
+uint32_t USB_OTG_GetMode(USB_OTG_CORE_HANDLE *pdev)
+{
+  return (USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS ) & 0x1);
+}
+
+
+/**
+* @brief  USB_OTG_IsDeviceMode : Check if it is device mode
+* @param  pdev : Selected device
+* @retval num_in_ep
+*/
+uint8_t USB_OTG_IsDeviceMode(USB_OTG_CORE_HANDLE *pdev)
+{
+  return (USB_OTG_GetMode(pdev) != HOST_MODE);
+}
+
+
+/**
+* @brief  USB_OTG_IsHostMode : Check if it is host mode
+* @param  pdev : Selected device
+* @retval num_in_ep
+*/
+uint8_t USB_OTG_IsHostMode(USB_OTG_CORE_HANDLE *pdev)
+{
+  return (USB_OTG_GetMode(pdev) == HOST_MODE);
+}
+
+
+/**
+* @brief  USB_OTG_ReadCoreItr : returns the Core Interrupt register
+* @param  pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadCoreItr(USB_OTG_CORE_HANDLE *pdev)
+{
+  uint32_t v = 0;
+  v = USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTSTS);
+  v &= USB_OTG_READ_REG32(&pdev->regs.GREGS->GINTMSK);
+  return v;
+}
+
+
+/**
+* @brief  USB_OTG_ReadOtgItr : returns the USB_OTG Interrupt register
+* @param  pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadOtgItr (USB_OTG_CORE_HANDLE *pdev)
+{
+  return (USB_OTG_READ_REG32 (&pdev->regs.GREGS->GOTGINT));
+}
+
+#ifdef USE_HOST_MODE
+/**
+* @brief  USB_OTG_CoreInitHost : Initializes USB_OTG controller for host mode
+* @param  pdev : Selected device
+* @retval status
+*/
+USB_OTG_STS USB_OTG_CoreInitHost(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS                     status = USB_OTG_OK;
+  USB_OTG_FSIZ_TypeDef            nptxfifosize;
+  USB_OTG_FSIZ_TypeDef            ptxfifosize;
+  USB_OTG_HCFG_TypeDef            hcfg;
+
+#ifdef USE_OTG_MODE
+  USB_OTG_OTGCTL_TypeDef          gotgctl;
+#endif
+
+  uint32_t                        i = 0;
+
+  nptxfifosize.d32 = 0;
+  ptxfifosize.d32 = 0;
+#ifdef USE_OTG_MODE
+  gotgctl.d32 = 0;
+#endif
+  hcfg.d32 = 0;
+
+
+  /* configure charge pump IO */
+  USB_OTG_BSP_ConfigVBUS(pdev);
+
+  /* Restart the Phy Clock */
+  USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0);
+
+  /* Initialize Host Configuration Register */
+  USB_OTG_InitFSLSPClkSel(pdev , HCFG_48_MHZ); /* in init phase */
+
+  hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+  hcfg.b.fslssupp = 0;
+  USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32);
+
+  /* Configure data FIFO sizes */
+  /* Rx FIFO */
+#ifdef USB_OTG_FS_CORE
+  if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID)
+  {
+    /* set Rx FIFO size */
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE);
+    nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE;
+    nptxfifosize.b.depth = TXH_NP_FS_FIFOSIZ;
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32);
+
+    ptxfifosize.b.startaddr = RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ;
+    ptxfifosize.b.depth     = TXH_P_FS_FIFOSIZ;
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);
+  }
+#endif
+#ifdef USB_OTG_HS_CORE
+   if (pdev->cfg.coreID == USB_OTG_HS_CORE_ID)
+  {
+   /* set Rx FIFO size */
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE);
+    nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE;
+    nptxfifosize.b.depth = TXH_NP_HS_FIFOSIZ;
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32);
+
+    ptxfifosize.b.startaddr = RX_FIFO_HS_SIZE + TXH_NP_HS_FIFOSIZ;
+    ptxfifosize.b.depth     = TXH_P_HS_FIFOSIZ;
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->HPTXFSIZ, ptxfifosize.d32);
+  }
+#endif
+
+#ifdef USE_OTG_MODE
+  /* Clear Host Set HNP Enable in the USB_OTG Control Register */
+  gotgctl.b.hstsethnpen = 1;
+  USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GOTGCTL, gotgctl.d32, 0);
+#endif
+
+  /* Make sure the FIFOs are flushed. */
+  USB_OTG_FlushTxFifo(pdev, 0x10 );         /* all Tx FIFOs */
+  USB_OTG_FlushRxFifo(pdev);
+
+
+  /* Clear all pending HC Interrupts */
+  for (i = 0; i < pdev->cfg.host_channels; i++)
+  {
+    USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCINT, 0xFFFFFFFF );
+    USB_OTG_WRITE_REG32( &pdev->regs.HC_REGS[i]->HCGINTMSK, 0 );
+  }
+#ifndef USE_OTG_MODE
+  USB_OTG_DriveVbus(pdev, 1);
+#endif
+
+  USB_OTG_EnableHostInt(pdev);
+  return status;
+}
+
+/**
+* @brief  USB_OTG_IsEvenFrame
+*         This function returns the frame number for sof packet
+* @param  pdev : Selected device
+* @retval Frame number
+*/
+uint8_t USB_OTG_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev)
+{
+  return !(USB_OTG_READ_REG32(&pdev->regs.HREGS->HFNUM) & 0x1);
+}
+
+/**
+* @brief  USB_OTG_DriveVbus : set/reset vbus
+* @param  pdev : Selected device
+* @param  state : VBUS state
+* @retval None
+*/
+void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state)
+{
+  USB_OTG_HPRT0_TypeDef     hprt0;
+
+  hprt0.d32 = 0;
+
+  /* enable disable the external charge pump */
+  USB_OTG_BSP_DriveVBUS(pdev, state);
+
+  /* Turn on the Host port power. */
+  hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
+  if ((hprt0.b.prtpwr == 0 ) && (state == 1 ))
+  {
+    hprt0.b.prtpwr = 1;
+    USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+  }
+  if ((hprt0.b.prtpwr == 1 ) && (state == 0 ))
+  {
+    hprt0.b.prtpwr = 0;
+    USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+  }
+
+  USB_OTG_BSP_mDelay(200);
+}
+/**
+* @brief  USB_OTG_EnableHostInt: Enables the Host mode interrupts
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableHostInt(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS       status = USB_OTG_OK;
+  USB_OTG_GINTMSK_TypeDef  intmsk;
+  intmsk.d32 = 0;
+  /* Disable all interrupts. */
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTMSK, 0);
+
+  /* Clear any pending interrupts. */
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF);
+
+  /* Enable the common interrupts */
+  USB_OTG_EnableCommonInt(pdev);
+
+  if (pdev->cfg.dma_enable == 0)
+  {
+    intmsk.b.rxstsqlvl  = 1;
+  }
+  intmsk.b.portintr   = 1;
+  intmsk.b.hcintr     = 1;
+  intmsk.b.disconnect = 1;
+  intmsk.b.sofintr    = 1;
+  intmsk.b.incomplisoout  = 1;
+  USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32);
+  return status;
+}
+
+/**
+* @brief  USB_OTG_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
+*         HCFG register on the PHY type
+* @param  pdev : Selected device
+* @param  freq : clock frequency
+* @retval None
+*/
+void USB_OTG_InitFSLSPClkSel(USB_OTG_CORE_HANDLE *pdev , uint8_t freq)
+{
+  USB_OTG_HCFG_TypeDef   hcfg;
+
+  hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
+  hcfg.b.fslspclksel = freq;
+  USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HCFG, hcfg.d32);
+}
+
+
+/**
+* @brief  USB_OTG_ReadHPRT0 : Reads HPRT0 to modify later
+* @param  pdev : Selected device
+* @retval HPRT0 value
+*/
+uint32_t USB_OTG_ReadHPRT0(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_HPRT0_TypeDef  hprt0;
+
+  hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
+  hprt0.b.prtena = 0;
+  hprt0.b.prtconndet = 0;
+  hprt0.b.prtenchng = 0;
+  hprt0.b.prtovrcurrchng = 0;
+  return hprt0.d32;
+}
+
+
+/**
+* @brief  USB_OTG_ReadHostAllChannels_intr : Register PCD Callbacks
+* @param  pdev : Selected device
+* @retval Status
+*/
+uint32_t USB_OTG_ReadHostAllChannels_intr (USB_OTG_CORE_HANDLE *pdev)
+{
+  return (USB_OTG_READ_REG32 (&pdev->regs.HREGS->HAINT));
+}
+
+
+/**
+* @brief  USB_OTG_ResetPort : Reset Host Port
+* @param  pdev : Selected device
+* @retval status
+* @note : (1)The application must wait at least 10 ms (+ 10 ms security)
+*   before clearing the reset bit.
+*/
+uint32_t USB_OTG_ResetPort(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_HPRT0_TypeDef  hprt0;
+
+  hprt0.d32 = USB_OTG_ReadHPRT0(pdev);
+  hprt0.b.prtrst = 1;
+  USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+  USB_OTG_BSP_mDelay (10);                                /* See Note #1 */
+  hprt0.b.prtrst = 0;
+  USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32);
+  USB_OTG_BSP_mDelay (20);
+  return 1;
+}
+
+
+/**
+* @brief  USB_OTG_HC_Init : Prepares a host channel for transferring packets
+* @param  pdev : Selected device
+* @param  hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_Init(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  uint32_t intr_enable = 0;
+  USB_OTG_HCGINTMSK_TypeDef  hcintmsk;
+  USB_OTG_GINTMSK_TypeDef    gintmsk;
+  USB_OTG_HCCHAR_TypeDef     hcchar;
+  USB_OTG_HCINTn_TypeDef     hcint;
+
+
+  gintmsk.d32 = 0;
+  hcintmsk.d32 = 0;
+  hcchar.d32 = 0;
+
+  /* Clear old interrupt conditions for this host channel. */
+  hcint.d32 = 0xFFFFFFFF;
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCINT, hcint.d32);
+
+  /* Enable channel interrupts required for this transfer. */
+  hcintmsk.d32 = 0;
+
+  if (pdev->cfg.dma_enable == 1)
+  {
+    hcintmsk.b.ahberr = 1;
+  }
+
+  switch (pdev->host.hc[hc_num].ep_type)
+  {
+  case EP_TYPE_CTRL:
+  case EP_TYPE_BULK:
+    hcintmsk.b.xfercompl = 1;
+    hcintmsk.b.stall = 1;
+    hcintmsk.b.xacterr = 1;
+    hcintmsk.b.datatglerr = 1;
+    hcintmsk.b.nak = 1;
+    if (pdev->host.hc[hc_num].ep_is_in)
+    {
+      hcintmsk.b.bblerr = 1;
+    }
+    else
+    {
+      hcintmsk.b.nyet = 1;
+      if (pdev->host.hc[hc_num].do_ping)
+      {
+        hcintmsk.b.ack = 1;
+      }
+    }
+    break;
+  case EP_TYPE_INTR:
+    hcintmsk.b.xfercompl = 1;
+    hcintmsk.b.nak = 1;
+    hcintmsk.b.stall = 1;
+    hcintmsk.b.xacterr = 1;
+    hcintmsk.b.datatglerr = 1;
+    hcintmsk.b.frmovrun = 1;
+
+    if (pdev->host.hc[hc_num].ep_is_in)
+    {
+      hcintmsk.b.bblerr = 1;
+    }
+
+    break;
+  case EP_TYPE_ISOC:
+    hcintmsk.b.xfercompl = 1;
+    hcintmsk.b.frmovrun = 1;
+    hcintmsk.b.ack = 1;
+
+    if (pdev->host.hc[hc_num].ep_is_in)
+    {
+      hcintmsk.b.xacterr = 1;
+      hcintmsk.b.bblerr = 1;
+    }
+    break;
+  }
+
+
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCGINTMSK, hcintmsk.d32);
+
+
+  /* Enable the top level host channel interrupt. */
+  intr_enable = (1 << hc_num);
+  USB_OTG_MODIFY_REG32(&pdev->regs.HREGS->HAINTMSK, 0, intr_enable);
+
+  /* Make sure host channel interrupts are enabled. */
+  gintmsk.b.hcintr = 1;
+  USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, gintmsk.d32);
+
+  /* Program the HCCHAR register */
+  hcchar.d32 = 0;
+  hcchar.b.devaddr = pdev->host.hc[hc_num].dev_addr;
+  hcchar.b.epnum   = pdev->host.hc[hc_num].ep_num;
+  hcchar.b.epdir   = pdev->host.hc[hc_num].ep_is_in;
+  hcchar.b.lspddev = (pdev->host.hc[hc_num].speed == HPRT0_PRTSPD_LOW_SPEED);
+  hcchar.b.eptype  = pdev->host.hc[hc_num].ep_type;
+  hcchar.b.mps     = pdev->host.hc[hc_num].max_packet;
+  if (pdev->host.hc[hc_num].ep_type == HCCHAR_INTR)
+  {
+    hcchar.b.oddfrm  = 1;
+  }
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_HC_StartXfer : Start transfer
+* @param  pdev : Selected device
+* @param  hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_StartXfer(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_HCCHAR_TypeDef   hcchar;
+  USB_OTG_HCTSIZn_TypeDef  hctsiz;
+  USB_OTG_HNPTXSTS_TypeDef hnptxsts;
+  USB_OTG_HPTXSTS_TypeDef  hptxsts;
+  USB_OTG_GINTMSK_TypeDef  intmsk;
+  uint16_t                 len_words = 0;
+
+  uint16_t num_packets;
+  uint16_t max_hc_pkt_count;
+
+  max_hc_pkt_count = 256;
+  hctsiz.d32 = 0;
+  hcchar.d32 = 0;
+  intmsk.d32 = 0;
+
+  /* Compute the expected number of packets associated to the transfer */
+  if (pdev->host.hc[hc_num].xfer_len > 0)
+  {
+    num_packets = (pdev->host.hc[hc_num].xfer_len + \
+      pdev->host.hc[hc_num].max_packet - 1) / pdev->host.hc[hc_num].max_packet;
+
+    if (num_packets > max_hc_pkt_count)
+    {
+      num_packets = max_hc_pkt_count;
+      pdev->host.hc[hc_num].xfer_len = num_packets * \
+        pdev->host.hc[hc_num].max_packet;
+    }
+  }
+  else
+  {
+    num_packets = 1;
+  }
+  if (pdev->host.hc[hc_num].ep_is_in)
+  {
+    pdev->host.hc[hc_num].xfer_len = num_packets * \
+      pdev->host.hc[hc_num].max_packet;
+  }
+  /* Initialize the HCTSIZn register */
+  hctsiz.b.xfersize = pdev->host.hc[hc_num].xfer_len;
+  hctsiz.b.pktcnt = num_packets;
+  hctsiz.b.pid = pdev->host.hc[hc_num].data_pid;
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32);
+
+  if (pdev->cfg.dma_enable == 1)
+  {
+    USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCDMA, (unsigned int)pdev->host.hc[hc_num].xfer_buff);
+  }
+
+
+  hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+  hcchar.b.oddfrm = USB_OTG_IsEvenFrame(pdev);
+
+  /* Set host channel enable */
+  hcchar.b.chen = 1;
+  hcchar.b.chdis = 0;
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+
+  if (pdev->cfg.dma_enable == 0) /* Slave mode */
+  {
+    if((pdev->host.hc[hc_num].ep_is_in == 0) &&
+        (pdev->host.hc[hc_num].xfer_len > 0))
+    {
+      switch(pdev->host.hc[hc_num].ep_type)
+      {
+        /* Non periodic transfer */
+      case EP_TYPE_CTRL:
+      case EP_TYPE_BULK:
+
+        hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+        len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4;
+
+        /* check if there is enough space in FIFO space */
+        if(len_words > hnptxsts.b.nptxfspcavail)
+        {
+          /* need to process data in nptxfempty interrupt */
+          intmsk.b.nptxfempty = 1;
+          USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+        }
+
+        break;
+        /* Periodic transfer */
+      case EP_TYPE_INTR:
+      case EP_TYPE_ISOC:
+        hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+        len_words = (pdev->host.hc[hc_num].xfer_len + 3) / 4;
+        /* check if there is enough space in FIFO space */
+        if(len_words > hptxsts.b.ptxfspcavail) /* split the transfer */
+        {
+          /* need to process data in ptxfempty interrupt */
+          intmsk.b.ptxfempty = 1;
+          USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
+        }
+        break;
+
+      default:
+        break;
+      }
+
+      /* Write packet into the Tx FIFO. */
+      USB_OTG_WritePacket(pdev,
+                          pdev->host.hc[hc_num].xfer_buff ,
+                          hc_num, pdev->host.hc[hc_num].xfer_len);
+    }
+  }
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_HC_Halt : Halt channel
+* @param  pdev : Selected device
+* @param  hc_num : channel number
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_HC_Halt(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_HNPTXSTS_TypeDef            nptxsts;
+  USB_OTG_HPTXSTS_TypeDef             hptxsts;
+  USB_OTG_HCCHAR_TypeDef              hcchar;
+
+  nptxsts.d32 = 0;
+  hptxsts.d32 = 0;
+  hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+  hcchar.b.chen = 1;
+  hcchar.b.chdis = 1;
+
+  /* Check for space in the request queue to issue the halt. */
+  if (hcchar.b.eptype == HCCHAR_CTRL || hcchar.b.eptype == HCCHAR_BULK)
+  {
+    nptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
+    if (nptxsts.b.nptxqspcavail == 0)
+    {
+      hcchar.b.chen = 0;
+    }
+  }
+  else
+  {
+    hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
+    if (hptxsts.b.ptxqspcavail == 0)
+    {
+      hcchar.b.chen = 0;
+    }
+  }
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+  return status;
+}
+
+/**
+* @brief  Issue a ping token
+* @param  None
+* @retval : None
+*/
+USB_OTG_STS USB_OTG_HC_DoPing(USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num)
+{
+  USB_OTG_STS               status = USB_OTG_OK;
+  USB_OTG_HCCHAR_TypeDef    hcchar;
+  USB_OTG_HCTSIZn_TypeDef   hctsiz;
+
+  hctsiz.d32 = 0;
+  hctsiz.b.dopng = 1;
+  hctsiz.b.pktcnt = 1;
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCTSIZ, hctsiz.d32);
+
+  hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR);
+  hcchar.b.chen = 1;
+  hcchar.b.chdis = 0;
+  USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[hc_num]->HCCHAR, hcchar.d32);
+  return status;
+}
+
+/**
+* @brief  Stop the device and clean up fifo's
+* @param  None
+* @retval : None
+*/
+void USB_OTG_StopHost(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_HCCHAR_TypeDef  hcchar;
+  uint32_t                i;
+
+  USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINTMSK , 0);
+  USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HAINT,      0xFFFFFFFF);
+  /* Flush out any leftover queued requests. */
+
+  for (i = 0; i < pdev->cfg.host_channels; i++)
+  {
+    hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR);
+    hcchar.b.chen = 0;
+    hcchar.b.chdis = 1;
+    hcchar.b.epdir = 0;
+    USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[i]->HCCHAR, hcchar.d32);
+  }
+
+  /* Flush the FIFO */
+  USB_OTG_FlushRxFifo(pdev);
+  USB_OTG_FlushTxFifo(pdev ,  0x10 );
+}
+#endif
+#ifdef USE_DEVICE_MODE
+/*         PCD Core Layer       */
+
+/**
+* @brief  USB_OTG_InitDevSpeed :Initializes the DevSpd field of DCFG register
+*         depending the PHY type and the enumeration speed of the device.
+* @param  pdev : Selected device
+* @retval : None
+*/
+void USB_OTG_InitDevSpeed(USB_OTG_CORE_HANDLE *pdev , uint8_t speed)
+{
+  USB_OTG_DCFG_TypeDef   dcfg;
+
+  dcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCFG);
+  dcfg.b.devspd = speed;
+  USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCFG, dcfg.d32);
+}
+
+
+/**
+* @brief  USB_OTG_CoreInitDev : Initializes the USB_OTG controller registers
+*         for device mode
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_CoreInitDev (USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS             status       = USB_OTG_OK;
+  USB_OTG_DEPCTL_TypeDef  depctl;
+  uint32_t i;
+  USB_OTG_DCFG_TypeDef    dcfg;
+  USB_OTG_FSIZ_TypeDef    nptxfifosize;
+  USB_OTG_FSIZ_TypeDef    txfifosize;
+  USB_OTG_DIEPMSK_TypeDef msk;
+  USB_OTG_DTHRCTL_TypeDef dthrctl;
+
+  depctl.d32 = 0;
+  dcfg.d32 = 0;
+  nptxfifosize.d32 = 0;
+  txfifosize.d32 = 0;
+  msk.d32 = 0;
+
+  /* Restart the Phy Clock */
+  USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, 0);
+  /* Device configuration register */
+  dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
+  dcfg.b.perfrint = DCFG_FRAME_INTERVAL_80;
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32 );
+
+#ifdef USB_OTG_FS_CORE
+  if(pdev->cfg.coreID == USB_OTG_FS_CORE_ID  )
+  {
+
+    /* Set Full speed phy */
+    USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_FULL);
+
+    /* set Rx FIFO size */
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_FS_SIZE);
+
+    /* EP0 TX*/
+    nptxfifosize.b.depth     = TX0_FIFO_FS_SIZE;
+    nptxfifosize.b.startaddr = RX_FIFO_FS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 );
+
+
+    /* EP1 TX*/
+    txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
+    txfifosize.b.depth = TX1_FIFO_FS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 );
+
+
+    /* EP2 TX*/
+    txfifosize.b.startaddr += txfifosize.b.depth;
+    txfifosize.b.depth = TX2_FIFO_FS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 );
+
+
+    /* EP3 TX*/
+    txfifosize.b.startaddr += txfifosize.b.depth;
+    txfifosize.b.depth = TX3_FIFO_FS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 );
+  }
+#endif
+#ifdef USB_OTG_HS_CORE
+  if(pdev->cfg.coreID == USB_OTG_HS_CORE_ID  )
+  {
+
+    /* Set High speed phy */
+
+    if(pdev->cfg.phy_itface  == USB_OTG_ULPI_PHY)
+    {
+       USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH);
+    }
+    else /* set High speed phy in Full speed mode */
+    {
+      USB_OTG_InitDevSpeed (pdev , USB_OTG_SPEED_PARAM_HIGH_IN_FULL);
+    }
+
+    /* set Rx FIFO size */
+    USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRXFSIZ, RX_FIFO_HS_SIZE);
+
+    /* EP0 TX*/
+    nptxfifosize.b.depth     = TX0_FIFO_HS_SIZE;
+    nptxfifosize.b.startaddr = RX_FIFO_HS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF0_HNPTXFSIZ, nptxfifosize.d32 );
+
+
+    /* EP1 TX*/
+    txfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;
+    txfifosize.b.depth = TX1_FIFO_HS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[0], txfifosize.d32 );
+
+
+    /* EP2 TX*/
+    txfifosize.b.startaddr += txfifosize.b.depth;
+    txfifosize.b.depth = TX2_FIFO_HS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[1], txfifosize.d32 );
+
+
+    /* EP3 TX*/
+    txfifosize.b.startaddr += txfifosize.b.depth;
+    txfifosize.b.depth = TX3_FIFO_HS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[2], txfifosize.d32 );
+
+    /* EP4 TX*/
+    txfifosize.b.startaddr += txfifosize.b.depth;
+    txfifosize.b.depth = TX4_FIFO_HS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[3], txfifosize.d32 );
+
+
+    /* EP5 TX*/
+    txfifosize.b.startaddr += txfifosize.b.depth;
+    txfifosize.b.depth = TX5_FIFO_HS_SIZE;
+    USB_OTG_WRITE_REG32( &pdev->regs.GREGS->DIEPTXF[4], txfifosize.d32 );
+  }
+#endif
+  /* Flush the FIFOs */
+  USB_OTG_FlushTxFifo(pdev , 0x10); /* all Tx FIFOs */
+  USB_OTG_FlushRxFifo(pdev);
+  /* Clear all pending Device Interrupts */
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 );
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 );
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 );
+
+  for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+  {
+    depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[i]->DIEPCTL);
+    if (depctl.b.epena)
+    {
+      depctl.d32 = 0;
+      depctl.b.epdis = 1;
+      depctl.b.snak = 1;
+    }
+    else
+    {
+      depctl.d32 = 0;
+    }
+    USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPCTL, depctl.d32);
+    USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPTSIZ, 0);
+    USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+  }
+  for (i = 0; i <  pdev->cfg.dev_endpoints; i++)
+  {
+    USB_OTG_DEPCTL_TypeDef  depctl;
+    depctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[i]->DOEPCTL);
+    if (depctl.b.epena)
+    {
+      depctl.d32 = 0;
+      depctl.b.epdis = 1;
+      depctl.b.snak = 1;
+    }
+    else
+    {
+      depctl.d32 = 0;
+    }
+    USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPCTL, depctl.d32);
+    USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPTSIZ, 0);
+    USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+  }
+  msk.d32 = 0;
+  msk.b.txfifoundrn = 1;
+  USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPMSK, msk.d32, msk.d32);
+
+  if (pdev->cfg.dma_enable == 1)
+  {
+    dthrctl.d32 = 0;
+    dthrctl.b.non_iso_thr_en = 1;
+    dthrctl.b.iso_thr_en = 1;
+    dthrctl.b.tx_thr_len = 64;
+    dthrctl.b.rx_thr_en = 1;
+    dthrctl.b.rx_thr_len = 64;
+    USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DTHRCTL, dthrctl.d32);
+  }
+  USB_OTG_EnableDevInt(pdev);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_EnableDevInt : Enables the Device mode interrupts
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EnableDevInt(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_GINTMSK_TypeDef  intmsk;
+
+  intmsk.d32 = 0;
+
+  /* Disable all interrupts. */
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTMSK, 0);
+  /* Clear any pending interrupts */
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, 0xFFFFFFFF);
+  /* Enable the common interrupts */
+  USB_OTG_EnableCommonInt(pdev);
+
+  if (pdev->cfg.dma_enable == 0)
+  {
+    intmsk.b.rxstsqlvl = 1;
+  }
+
+  /* Enable interrupts matching to the Device mode ONLY */
+  intmsk.b.usbsuspend = 1;
+  intmsk.b.usbreset   = 1;
+  intmsk.b.enumdone   = 1;
+  intmsk.b.inepintr   = 1;
+  intmsk.b.outepintr  = 1;
+  intmsk.b.sofintr    = 1;
+
+  intmsk.b.incomplisoin    = 1;
+  intmsk.b.incomplisoout    = 1;
+#ifdef VBUS_SENSING_ENABLED
+  intmsk.b.sessreqintr    = 1;
+  intmsk.b.otgintr    = 1;
+#endif
+  USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_GetDeviceSpeed
+*         Get the device speed from the device status register
+* @param  None
+* @retval status
+*/
+enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_DSTS_TypeDef  dsts;
+  enum USB_OTG_SPEED speed = USB_SPEED_UNKNOWN;
+
+
+  dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+  switch (dsts.b.enumspd)
+  {
+  case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+    speed = USB_SPEED_HIGH;
+    break;
+  case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+  case DSTS_ENUMSPD_FS_PHY_48MHZ:
+    speed = USB_SPEED_FULL;
+    break;
+
+  case DSTS_ENUMSPD_LS_PHY_6MHZ:
+    speed = USB_SPEED_LOW;
+    break;
+  }
+
+  return speed;
+}
+/**
+* @brief  enables EP0 OUT to receive SETUP packets and configures EP0
+*   for transmitting packets
+* @param  None
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS  USB_OTG_EP0Activate(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_STS             status = USB_OTG_OK;
+  USB_OTG_DSTS_TypeDef    dsts;
+  USB_OTG_DEPCTL_TypeDef  diepctl;
+  USB_OTG_DCTL_TypeDef    dctl;
+
+  dctl.d32 = 0;
+  /* Read the Device Status and Endpoint 0 Control registers */
+  dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+  diepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL);
+  /* Set the MPS of the IN EP based on the enumeration speed */
+  switch (dsts.b.enumspd)
+  {
+  case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
+  case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
+  case DSTS_ENUMSPD_FS_PHY_48MHZ:
+    diepctl.b.mps = DEP0CTL_MPS_64;
+    break;
+  case DSTS_ENUMSPD_LS_PHY_6MHZ:
+    diepctl.b.mps = DEP0CTL_MPS_8;
+    break;
+  }
+  USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[0]->DIEPCTL, diepctl.d32);
+  dctl.b.cgnpinnak = 1;
+  USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, dctl.d32);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_EPActivate : Activates an EP
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPActivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_DEPCTL_TypeDef  depctl;
+  USB_OTG_DAINT_TypeDef  daintmsk;
+  __IO uint32_t *addr;
+
+
+  depctl.d32 = 0;
+  daintmsk.d32 = 0;
+  /* Read DEPCTLn register */
+  if (ep->is_in == 1)
+  {
+    addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL;
+    daintmsk.ep.in = 1 << ep->num;
+  }
+  else
+  {
+    addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL;
+    daintmsk.ep.out = 1 << ep->num;
+  }
+  /* If the EP is already active don't change the EP Control
+  * register. */
+  depctl.d32 = USB_OTG_READ_REG32(addr);
+  if (!depctl.b.usbactep)
+  {
+    depctl.b.mps    = ep->maxpacket;
+    depctl.b.eptype = ep->type;
+    depctl.b.txfnum = ep->tx_fifo_num;
+    depctl.b.setd0pid = 1;
+    depctl.b.usbactep = 1;
+    USB_OTG_WRITE_REG32(addr, depctl.d32);
+  }
+  /* Enable the Interrupt for this EP */
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+  if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID))
+  {
+    USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, 0, daintmsk.d32);
+  }
+  else
+#endif
+    USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, 0, daintmsk.d32);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_EPDeactivate : Deactivates an EP
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_DEPCTL_TypeDef  depctl;
+  USB_OTG_DAINT_TypeDef  daintmsk;
+  __IO uint32_t *addr;
+
+  depctl.d32 = 0;
+  daintmsk.d32 = 0;
+  /* Read DEPCTLn register */
+  if (ep->is_in == 1)
+  {
+    addr = &pdev->regs.INEP_REGS[ep->num]->DIEPCTL;
+    daintmsk.ep.in = 1 << ep->num;
+  }
+  else
+  {
+    addr = &pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL;
+    daintmsk.ep.out = 1 << ep->num;
+  }
+  depctl.b.usbactep = 0;
+  USB_OTG_WRITE_REG32(addr, depctl.d32);
+  /* Disable the Interrupt for this EP */
+
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+  if((ep->num == 1)&&(pdev->cfg.coreID == USB_OTG_HS_CORE_ID))
+  {
+    USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DEACHMSK, daintmsk.d32, 0);
+  }
+  else
+#endif
+    USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DAINTMSK, daintmsk.d32, 0);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_EPStartXfer : Handle the setup for data xfer for an EP and
+*         starts the xfer
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPStartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_DEPCTL_TypeDef     depctl;
+  USB_OTG_DEPXFRSIZ_TypeDef  deptsiz;
+  USB_OTG_DSTS_TypeDef       dsts;
+  uint32_t fifoemptymsk = 0;
+
+  depctl.d32 = 0;
+  deptsiz.d32 = 0;
+  /* IN endpoint */
+  if (ep->is_in == 1)
+  {
+    depctl.d32  = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPCTL));
+    deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ));
+    /* Zero Length Packet? */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = 0;
+      deptsiz.b.pktcnt = 1;
+    }
+    else
+    {
+      /* Program the transfer size and packet count
+      * as follows: xfersize = N * maxpacket +
+      * short_packet pktcnt = N + (short_packet
+      * exist ? 1 : 0)
+      */
+      deptsiz.b.xfersize = ep->xfer_len;
+      deptsiz.b.pktcnt = (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
+
+      if (ep->type == EP_TYPE_ISOC)
+      {
+        deptsiz.b.mc = 1;
+      }
+    }
+    USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPTSIZ, deptsiz.d32);
+
+    if (pdev->cfg.dma_enable == 1)
+    {
+      USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr);
+    }
+    else
+    {
+      if (ep->type != EP_TYPE_ISOC)
+      {
+        /* Enable the Tx FIFO Empty Interrupt for this EP */
+        if (ep->xfer_len > 0)
+        {
+          fifoemptymsk = 1 << ep->num;
+          USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk);
+        }
+      }
+    }
+
+
+    if (ep->type == EP_TYPE_ISOC)
+    {
+      dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+      if (((dsts.b.soffn)&0x1) == 0)
+      {
+        depctl.b.setd1pid = 1;
+      }
+      else
+      {
+        depctl.b.setd0pid = 1;
+      }
+    }
+
+    /* EP enable, IN data in FIFO */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+    USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPCTL, depctl.d32);
+
+    if (ep->type == EP_TYPE_ISOC)
+    {
+      USB_OTG_WritePacket(pdev, ep->xfer_buff, ep->num, ep->xfer_len);
+    }
+  }
+  else
+  {
+    /* OUT endpoint */
+    depctl.d32  = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL));
+    deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ));
+    /* Program the transfer size and packet count as follows:
+    * pktcnt = N
+    * xfersize = N * maxpacket
+    */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = ep->maxpacket;
+      deptsiz.b.pktcnt = 1;
+    }
+    else
+    {
+      deptsiz.b.pktcnt = (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
+      deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
+    }
+    USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32);
+
+    if (pdev->cfg.dma_enable == 1)
+    {
+      USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr);
+    }
+
+    if (ep->type == EP_TYPE_ISOC)
+    {
+      if (ep->even_odd_frame)
+      {
+        depctl.b.setd1pid = 1;
+      }
+      else
+      {
+        depctl.b.setd0pid = 1;
+      }
+    }
+    /* EP enable */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+    USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL, depctl.d32);
+  }
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_EP0StartXfer : Handle the setup for a data xfer for EP0 and
+*         starts the xfer
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+  USB_OTG_STS                 status = USB_OTG_OK;
+  USB_OTG_DEPCTL_TypeDef      depctl;
+  USB_OTG_DEP0XFRSIZ_TypeDef  deptsiz;
+  USB_OTG_INEPREGS          *in_regs;
+  uint32_t fifoemptymsk = 0;
+
+  depctl.d32   = 0;
+  deptsiz.d32  = 0;
+  /* IN endpoint */
+  if (ep->is_in == 1)
+  {
+    in_regs = pdev->regs.INEP_REGS[0];
+    depctl.d32  = USB_OTG_READ_REG32(&in_regs->DIEPCTL);
+    deptsiz.d32 = USB_OTG_READ_REG32(&in_regs->DIEPTSIZ);
+    /* Zero Length Packet? */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = 0;
+      deptsiz.b.pktcnt = 1;
+
+    }
+    else
+    {
+      if (ep->xfer_len > ep->maxpacket)
+      {
+        ep->xfer_len = ep->maxpacket;
+        deptsiz.b.xfersize = ep->maxpacket;
+      }
+      else
+      {
+        deptsiz.b.xfersize = ep->xfer_len;
+      }
+      deptsiz.b.pktcnt = 1;
+    }
+    USB_OTG_WRITE_REG32(&in_regs->DIEPTSIZ, deptsiz.d32);
+
+    if (pdev->cfg.dma_enable == 1)
+    {
+      USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[ep->num]->DIEPDMA, ep->dma_addr);
+    }
+
+    /* EP enable, IN data in FIFO */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+    USB_OTG_WRITE_REG32(&in_regs->DIEPCTL, depctl.d32);
+
+
+
+    if (pdev->cfg.dma_enable == 0)
+    {
+      /* Enable the Tx FIFO Empty Interrupt for this EP */
+      if (ep->xfer_len > 0)
+      {
+        {
+          fifoemptymsk |= 1 << ep->num;
+          USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, 0, fifoemptymsk);
+        }
+      }
+    }
+  }
+  else
+  {
+    /* OUT endpoint */
+    depctl.d32  = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+    deptsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ);
+    /* Program the transfer size and packet count as follows:
+    * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
+    * pktcnt = N           */
+    if (ep->xfer_len == 0)
+    {
+      deptsiz.b.xfersize = ep->maxpacket;
+      deptsiz.b.pktcnt = 1;
+    }
+    else
+    {
+      ep->xfer_len = ep->maxpacket;
+      deptsiz.b.xfersize = ep->maxpacket;
+      deptsiz.b.pktcnt = 1;
+    }
+    USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPTSIZ, deptsiz.d32);
+    if (pdev->cfg.dma_enable == 1)
+    {
+      USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[ep->num]->DOEPDMA, ep->dma_addr);
+    }
+    /* EP enable */
+    depctl.b.cnak = 1;
+    depctl.b.epena = 1;
+    USB_OTG_WRITE_REG32 (&(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL), depctl.d32);
+
+  }
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_EPSetStall : Set the EP STALL
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPSetStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_DEPCTL_TypeDef  depctl;
+  __IO uint32_t *depctl_addr;
+
+  depctl.d32 = 0;
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+    depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+    /* set the disable and stall bits */
+    if (depctl.b.epena)
+    {
+      depctl.b.epdis = 1;
+    }
+    depctl.b.stall = 1;
+    USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+  }
+  else
+  {
+    depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+    depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+    /* set the stall bit */
+    depctl.b.stall = 1;
+    USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+  }
+  return status;
+}
+
+
+/**
+* @brief  Clear the EP STALL
+* @param  pdev : Selected device
+* @retval USB_OTG_STS : status
+*/
+USB_OTG_STS USB_OTG_EPClearStall(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep)
+{
+  USB_OTG_STS status = USB_OTG_OK;
+  USB_OTG_DEPCTL_TypeDef  depctl;
+  __IO uint32_t *depctl_addr;
+
+  depctl.d32 = 0;
+
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+  }
+  else
+  {
+    depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+  }
+  depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+  /* clear the stall bits */
+  depctl.b.stall = 0;
+  if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK)
+  {
+    depctl.b.setd0pid = 1; /* DATA0 */
+  }
+  USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+  return status;
+}
+
+
+/**
+* @brief  USB_OTG_ReadDevAllOutEp_itr : returns OUT endpoint interrupt bits
+* @param  pdev : Selected device
+* @retval OUT endpoint interrupt bits
+*/
+uint32_t USB_OTG_ReadDevAllOutEp_itr(USB_OTG_CORE_HANDLE *pdev)
+{
+  uint32_t v;
+  v  = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT);
+  v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK);
+  return ((v & 0xffff0000) >> 16);
+}
+
+
+/**
+* @brief  USB_OTG_ReadDevOutEP_itr : returns Device OUT EP Interrupt register
+* @param  pdev : Selected device
+* @param  ep : end point number
+* @retval Device OUT EP Interrupt register
+*/
+uint32_t USB_OTG_ReadDevOutEP_itr(USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+  uint32_t v;
+  v  = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT);
+  v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOEPMSK);
+  return v;
+}
+
+
+/**
+* @brief  USB_OTG_ReadDevAllInEPItr : Get int status register
+* @param  pdev : Selected device
+* @retval int status register
+*/
+uint32_t USB_OTG_ReadDevAllInEPItr(USB_OTG_CORE_HANDLE *pdev)
+{
+  uint32_t v;
+  v = USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINT);
+  v &= USB_OTG_READ_REG32(&pdev->regs.DREGS->DAINTMSK);
+  return (v & 0xffff);
+}
+
+/**
+* @brief  configures EPO to receive SETUP packets
+* @param  None
+* @retval : None
+*/
+void USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_DEP0XFRSIZ_TypeDef  doeptsize0;
+  doeptsize0.d32 = 0;
+  doeptsize0.b.supcnt = 3;
+  doeptsize0.b.pktcnt = 1;
+  doeptsize0.b.xfersize = 8 * 3;
+  USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPTSIZ, doeptsize0.d32 );
+
+  if (pdev->cfg.dma_enable == 1)
+  {
+    USB_OTG_DEPCTL_TypeDef  doepctl;
+    doepctl.d32 = 0;
+    USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPDMA,
+                        (uint32_t)&pdev->dev.setup_packet);
+
+    /* EP enable */
+    doepctl.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[0]->DOEPCTL);
+    doepctl.b.epena = 1;
+    doepctl.d32 = 0x80008000;
+    USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[0]->DOEPCTL, doepctl.d32);
+  }
+}
+
+/**
+* @brief  USB_OTG_RemoteWakeup : active remote wakeup signalling
+* @param  None
+* @retval : None
+*/
+void USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev)
+{
+
+  USB_OTG_DCTL_TypeDef     dctl;
+  USB_OTG_DSTS_TypeDef     dsts;
+  USB_OTG_PCGCCTL_TypeDef  power;
+
+  if (pdev->dev.DevRemoteWakeup)
+  {
+    dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+    if(dsts.b.suspsts == 1)
+    {
+      if(pdev->cfg.low_power)
+      {
+        /* un-gate USB Core clock */
+        power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL);
+        power.b.gatehclk = 0;
+        power.b.stoppclk = 0;
+        USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+      }
+      /* active Remote wakeup signaling */
+      dctl.d32 = 0;
+      dctl.b.rmtwkupsig = 1;
+      USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, 0, dctl.d32);
+      USB_OTG_BSP_mDelay(5);
+      USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
+    }
+  }
+}
+
+
+/**
+* @brief  USB_OTG_UngateClock : active USB Core clock
+* @param  None
+* @retval : None
+*/
+void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev)
+{
+  if(pdev->cfg.low_power)
+  {
+
+    USB_OTG_DSTS_TypeDef     dsts;
+    USB_OTG_PCGCCTL_TypeDef  power;
+
+    dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+    if(dsts.b.suspsts == 1)
+    {
+      /* un-gate USB Core clock */
+      power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL);
+      power.b.gatehclk = 0;
+      power.b.stoppclk = 0;
+      USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+
+    }
+  }
+}
+
+/**
+* @brief  Stop the device and clean up fifo's
+* @param  None
+* @retval : None
+*/
+void USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev)
+{
+  uint32_t i;
+
+  pdev->dev.device_status = 1;
+
+  for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+  {
+    USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+    USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+  }
+
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, 0 );
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, 0 );
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, 0 );
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+
+  /* Flush the FIFO */
+  USB_OTG_FlushRxFifo(pdev);
+  USB_OTG_FlushTxFifo(pdev ,  0x10 );
+}
+
+/**
+* @brief  returns the EP Status
+* @param  pdev : Selected device
+*         ep : endpoint structure
+* @retval : EP status
+*/
+
+uint32_t USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep)
+{
+  USB_OTG_DEPCTL_TypeDef  depctl;
+  __IO uint32_t *depctl_addr;
+  uint32_t Status = 0;
+
+  depctl.d32 = 0;
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+    depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+    if (depctl.b.stall == 1)
+      Status = USB_OTG_EP_TX_STALL;
+    else if (depctl.b.naksts == 1)
+      Status = USB_OTG_EP_TX_NAK;
+    else
+      Status = USB_OTG_EP_TX_VALID;
+
+  }
+  else
+  {
+    depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+    depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+    if (depctl.b.stall == 1)
+      Status = USB_OTG_EP_RX_STALL;
+    else if (depctl.b.naksts == 1)
+      Status = USB_OTG_EP_RX_NAK;
+    else
+      Status = USB_OTG_EP_RX_VALID;
+  }
+
+  /* Return the current status */
+  return Status;
+}
+
+/**
+* @brief  Set the EP Status
+* @param  pdev : Selected device
+*         Status : new Status
+*         ep : EP structure
+* @retval : None
+*/
+void USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status)
+{
+  USB_OTG_DEPCTL_TypeDef  depctl;
+  __IO uint32_t *depctl_addr;
+
+  depctl.d32 = 0;
+
+  /* Process for IN endpoint */
+  if (ep->is_in == 1)
+  {
+    depctl_addr = &(pdev->regs.INEP_REGS[ep->num]->DIEPCTL);
+    depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+    if (Status == USB_OTG_EP_TX_STALL)
+    {
+      USB_OTG_EPSetStall(pdev, ep); return;
+    }
+    else if (Status == USB_OTG_EP_TX_NAK)
+      depctl.b.snak = 1;
+    else if (Status == USB_OTG_EP_TX_VALID)
+    {
+      if (depctl.b.stall == 1)
+      {
+        ep->even_odd_frame = 0;
+        USB_OTG_EPClearStall(pdev, ep);
+        return;
+      }
+      depctl.b.cnak = 1;
+      depctl.b.usbactep = 1;
+      depctl.b.epena = 1;
+    }
+    else if (Status == USB_OTG_EP_TX_DIS)
+      depctl.b.usbactep = 0;
+  }
+  else /* Process for OUT endpoint */
+  {
+    depctl_addr = &(pdev->regs.OUTEP_REGS[ep->num]->DOEPCTL);
+    depctl.d32 = USB_OTG_READ_REG32(depctl_addr);
+
+    if (Status == USB_OTG_EP_RX_STALL)  {
+      depctl.b.stall = 1;
+    }
+    else if (Status == USB_OTG_EP_RX_NAK)
+      depctl.b.snak = 1;
+    else if (Status == USB_OTG_EP_RX_VALID)
+    {
+      if (depctl.b.stall == 1)
+      {
+        ep->even_odd_frame = 0;
+        USB_OTG_EPClearStall(pdev, ep);
+        return;
+      }
+      depctl.b.cnak = 1;
+      depctl.b.usbactep = 1;
+      depctl.b.epena = 1;
+    }
+    else if (Status == USB_OTG_EP_RX_DIS)
+    {
+      depctl.b.usbactep = 0;
+    }
+  }
+
+  USB_OTG_WRITE_REG32(depctl_addr, depctl.d32);
+}
+
+#endif
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_core.h b/codec2/branches/0.7/stm32/usb_lib/otg/usb_core.h
new file mode 100644 (file)
index 0000000..acd1f1c
--- /dev/null
@@ -0,0 +1,408 @@
+/**
+  ******************************************************************************
+  * @file    usb_core.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   Header of the Core Layer
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_CORE_H__
+#define __USB_CORE_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+#include "usb_regs.h"
+#include "usb_defines.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+  * @{
+  */
+
+/** @defgroup USB_CORE
+  * @brief usb otg driver core layer
+  * @{
+  */
+
+
+/** @defgroup USB_CORE_Exported_Defines
+  * @{
+  */
+
+#define USB_OTG_EP0_IDLE                          0
+#define USB_OTG_EP0_SETUP                         1
+#define USB_OTG_EP0_DATA_IN                       2
+#define USB_OTG_EP0_DATA_OUT                      3
+#define USB_OTG_EP0_STATUS_IN                     4
+#define USB_OTG_EP0_STATUS_OUT                    5
+#define USB_OTG_EP0_STALL                         6
+
+#define USB_OTG_EP_TX_DIS       0x0000
+#define USB_OTG_EP_TX_STALL     0x0010
+#define USB_OTG_EP_TX_NAK       0x0020
+#define USB_OTG_EP_TX_VALID     0x0030
+
+#define USB_OTG_EP_RX_DIS       0x0000
+#define USB_OTG_EP_RX_STALL     0x1000
+#define USB_OTG_EP_RX_NAK       0x2000
+#define USB_OTG_EP_RX_VALID     0x3000
+/**
+  * @}
+  */
+#define   MAX_DATA_LENGTH                        0xFF
+
+/** @defgroup USB_CORE_Exported_Types
+  * @{
+  */
+
+
+typedef enum {
+  USB_OTG_OK = 0,
+  USB_OTG_FAIL
+}USB_OTG_STS;
+
+typedef enum {
+  HC_IDLE = 0,
+  HC_XFRC,
+  HC_HALTED,
+  HC_NAK,
+  HC_NYET,
+  HC_STALL,
+  HC_XACTERR,
+  HC_BBLERR,
+  HC_DATATGLERR,
+}HC_STATUS;
+
+typedef enum {
+  URB_IDLE = 0,
+  URB_DONE,
+  URB_NOTREADY,
+  URB_ERROR,
+  URB_STALL
+}URB_STATE;
+
+typedef enum {
+  CTRL_START = 0,
+  CTRL_XFRC,
+  CTRL_HALTED,
+  CTRL_NAK,
+  CTRL_STALL,
+  CTRL_XACTERR,
+  CTRL_BBLERR,
+  CTRL_DATATGLERR,
+  CTRL_FAIL
+}CTRL_STATUS;
+
+
+typedef struct USB_OTG_hc
+{
+  uint8_t       dev_addr ;
+  uint8_t       ep_num;
+  uint8_t       ep_is_in;
+  uint8_t       speed;
+  uint8_t       do_ping;
+  uint8_t       ep_type;
+  uint16_t      max_packet;
+  uint8_t       data_pid;
+  uint8_t       *xfer_buff;
+  uint32_t      xfer_len;
+  uint32_t      xfer_count;
+  uint8_t       toggle_in;
+  uint8_t       toggle_out;
+  uint32_t       dma_addr;
+}
+USB_OTG_HC , *PUSB_OTG_HC;
+
+typedef struct USB_OTG_ep
+{
+  uint8_t        num;
+  uint8_t        is_in;
+  uint8_t        is_stall;
+  uint8_t        type;
+  uint8_t        data_pid_start;
+  uint8_t        even_odd_frame;
+  uint16_t       tx_fifo_num;
+  uint32_t       maxpacket;
+  /* transaction level variables*/
+  uint8_t        *xfer_buff;
+  uint32_t       dma_addr;
+  uint32_t       xfer_len;
+  uint32_t       xfer_count;
+  /* Transfer level variables*/
+  uint32_t       rem_data_len;
+  uint32_t       total_data_len;
+  uint32_t       ctl_data_len;
+
+}
+
+USB_OTG_EP , *PUSB_OTG_EP;
+
+
+
+typedef struct USB_OTG_core_cfg
+{
+  uint8_t       host_channels;
+  uint8_t       dev_endpoints;
+  uint8_t       speed;
+  uint8_t       dma_enable;
+  uint16_t      mps;
+  uint16_t      TotalFifoSize;
+  uint8_t       phy_itface;
+  uint8_t       Sof_output;
+  uint8_t       low_power;
+  uint8_t       coreID;
+
+}
+USB_OTG_CORE_CFGS, *PUSB_OTG_CORE_CFGS;
+
+
+
+typedef  struct  usb_setup_req {
+
+    uint8_t   bmRequest;
+    uint8_t   bRequest;
+    uint16_t  wValue;
+    uint16_t  wIndex;
+    uint16_t  wLength;
+} USB_SETUP_REQ;
+
+typedef struct _Device_TypeDef
+{
+  uint8_t  *(*GetDeviceDescriptor)( uint8_t speed , uint16_t *length);
+  uint8_t  *(*GetLangIDStrDescriptor)( uint8_t speed , uint16_t *length);
+  uint8_t  *(*GetManufacturerStrDescriptor)( uint8_t speed , uint16_t *length);
+  uint8_t  *(*GetProductStrDescriptor)( uint8_t speed , uint16_t *length);
+  uint8_t  *(*GetSerialStrDescriptor)( uint8_t speed , uint16_t *length);
+  uint8_t  *(*GetConfigurationStrDescriptor)( uint8_t speed , uint16_t *length);
+  uint8_t  *(*GetInterfaceStrDescriptor)( uint8_t speed , uint16_t *length);
+} USBD_DEVICE, *pUSBD_DEVICE;
+
+typedef struct USB_OTG_hPort
+{
+  void (*Disconnect) (void *phost);
+  void (*Connect) (void *phost);
+  uint8_t ConnStatus;
+  uint8_t DisconnStatus;
+  uint8_t ConnHandled;
+  uint8_t DisconnHandled;
+} USB_OTG_hPort_TypeDef;
+
+typedef struct _Device_cb
+{
+  uint8_t  (*Init)         (void *pdev , uint8_t cfgidx);
+  uint8_t  (*DeInit)       (void *pdev , uint8_t cfgidx);
+ /* Control Endpoints*/
+  uint8_t  (*Setup)        (void *pdev , USB_SETUP_REQ  *req);
+  uint8_t  (*EP0_TxSent)   (void *pdev );
+  uint8_t  (*EP0_RxReady)  (void *pdev );
+  /* Class Specific Endpoints*/
+  uint8_t  (*DataIn)       (void *pdev , uint8_t epnum);
+  uint8_t  (*DataOut)      (void *pdev , uint8_t epnum);
+  uint8_t  (*SOF)          (void *pdev);
+  uint8_t  (*IsoINIncomplete)  (void *pdev);
+  uint8_t  (*IsoOUTIncomplete)  (void *pdev);
+
+  uint8_t  *(*GetConfigDescriptor)( uint8_t speed , uint16_t *length);
+#ifdef USB_OTG_HS_CORE
+  uint8_t  *(*GetOtherConfigDescriptor)( uint8_t speed , uint16_t *length);
+#endif
+
+#ifdef USB_SUPPORT_USER_STRING_DESC
+  uint8_t  *(*GetUsrStrDescriptor)( uint8_t speed ,uint8_t index,  uint16_t *length);
+#endif
+
+} USBD_Class_cb_TypeDef;
+
+
+
+typedef struct _USBD_USR_PROP
+{
+  void (*Init)(void);
+  void (*DeviceReset)(uint8_t speed);
+  void (*DeviceConfigured)(void);
+  void (*DeviceSuspended)(void);
+  void (*DeviceResumed)(void);
+
+  void (*DeviceConnected)(void);
+  void (*DeviceDisconnected)(void);
+
+}
+USBD_Usr_cb_TypeDef;
+
+typedef struct _DCD
+{
+  uint8_t        device_config;
+  uint8_t        device_state;
+  uint8_t        device_status;
+  uint8_t        device_address;
+  uint32_t       DevRemoteWakeup;
+  USB_OTG_EP     in_ep   [USB_OTG_MAX_TX_FIFOS];
+  USB_OTG_EP     out_ep  [USB_OTG_MAX_TX_FIFOS];
+  uint8_t        setup_packet [8*3];
+  USBD_Class_cb_TypeDef         *class_cb;
+  USBD_Usr_cb_TypeDef           *usr_cb;
+  USBD_DEVICE                   *usr_device;
+  uint8_t        *pConfig_descriptor;
+ }
+DCD_DEV , *DCD_PDEV;
+
+
+typedef struct _HCD
+{
+  uint8_t                  Rx_Buffer [MAX_DATA_LENGTH];
+  __IO uint32_t            ConnSts;
+  __IO uint32_t            ErrCnt[USB_OTG_MAX_TX_FIFOS];
+  __IO uint32_t            XferCnt[USB_OTG_MAX_TX_FIFOS];
+  __IO HC_STATUS           HC_Status[USB_OTG_MAX_TX_FIFOS];
+  __IO URB_STATE           URB_State[USB_OTG_MAX_TX_FIFOS];
+  USB_OTG_HC               hc [USB_OTG_MAX_TX_FIFOS];
+  uint16_t                 channel [USB_OTG_MAX_TX_FIFOS];
+  USB_OTG_hPort_TypeDef    *port_cb;
+}
+HCD_DEV , *USB_OTG_USBH_PDEV;
+
+
+typedef struct _OTG
+{
+  uint8_t    OTG_State;
+  uint8_t    OTG_PrevState;
+  uint8_t    OTG_Mode;
+}
+OTG_DEV , *USB_OTG_USBO_PDEV;
+
+typedef struct USB_OTG_handle
+{
+  USB_OTG_CORE_CFGS    cfg;
+  USB_OTG_CORE_REGS    regs;
+#ifdef USE_DEVICE_MODE
+  DCD_DEV     dev;
+#endif
+#ifdef USE_HOST_MODE
+  HCD_DEV     host;
+#endif
+#ifdef USE_OTG_MODE
+  OTG_DEV     otg;
+#endif
+}
+USB_OTG_CORE_HANDLE , *PUSB_OTG_CORE_HANDLE;
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_CORE_Exported_Macros
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup USB_CORE_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_CORE_Exported_FunctionsPrototype
+  * @{
+  */
+
+
+USB_OTG_STS  USB_OTG_CoreInit        (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_SelectCore      (USB_OTG_CORE_HANDLE *pdev,
+                                      USB_OTG_CORE_ID_TypeDef coreID);
+USB_OTG_STS  USB_OTG_EnableGlobalInt (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_DisableGlobalInt(USB_OTG_CORE_HANDLE *pdev);
+void*           USB_OTG_ReadPacket   (USB_OTG_CORE_HANDLE *pdev ,
+    uint8_t *dest,
+    uint16_t len);
+USB_OTG_STS  USB_OTG_WritePacket     (USB_OTG_CORE_HANDLE *pdev ,
+    uint8_t *src,
+    uint8_t ch_ep_num,
+    uint16_t len);
+USB_OTG_STS  USB_OTG_FlushTxFifo     (USB_OTG_CORE_HANDLE *pdev , uint32_t num);
+USB_OTG_STS  USB_OTG_FlushRxFifo     (USB_OTG_CORE_HANDLE *pdev);
+
+uint32_t     USB_OTG_ReadCoreItr     (USB_OTG_CORE_HANDLE *pdev);
+uint32_t     USB_OTG_ReadOtgItr      (USB_OTG_CORE_HANDLE *pdev);
+uint8_t      USB_OTG_IsHostMode      (USB_OTG_CORE_HANDLE *pdev);
+uint8_t      USB_OTG_IsDeviceMode    (USB_OTG_CORE_HANDLE *pdev);
+uint32_t     USB_OTG_GetMode         (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_PhyInit         (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_SetCurrentMode  (USB_OTG_CORE_HANDLE *pdev,
+    uint8_t mode);
+
+/*********************** HOST APIs ********************************************/
+#ifdef USE_HOST_MODE
+USB_OTG_STS  USB_OTG_CoreInitHost    (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_EnableHostInt   (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_HC_Init         (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS  USB_OTG_HC_Halt         (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS  USB_OTG_HC_StartXfer    (USB_OTG_CORE_HANDLE *pdev, uint8_t hc_num);
+USB_OTG_STS  USB_OTG_HC_DoPing       (USB_OTG_CORE_HANDLE *pdev , uint8_t hc_num);
+uint32_t     USB_OTG_ReadHostAllChannels_intr    (USB_OTG_CORE_HANDLE *pdev);
+uint32_t     USB_OTG_ResetPort       (USB_OTG_CORE_HANDLE *pdev);
+uint32_t     USB_OTG_ReadHPRT0       (USB_OTG_CORE_HANDLE *pdev);
+void         USB_OTG_DriveVbus       (USB_OTG_CORE_HANDLE *pdev, uint8_t state);
+void         USB_OTG_InitFSLSPClkSel (USB_OTG_CORE_HANDLE *pdev ,uint8_t freq);
+uint8_t      USB_OTG_IsEvenFrame     (USB_OTG_CORE_HANDLE *pdev) ;
+void         USB_OTG_StopHost        (USB_OTG_CORE_HANDLE *pdev);
+#endif
+/********************* DEVICE APIs ********************************************/
+#ifdef USE_DEVICE_MODE
+USB_OTG_STS  USB_OTG_CoreInitDev         (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_EnableDevInt        (USB_OTG_CORE_HANDLE *pdev);
+uint32_t     USB_OTG_ReadDevAllInEPItr           (USB_OTG_CORE_HANDLE *pdev);
+enum USB_OTG_SPEED USB_OTG_GetDeviceSpeed (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_EP0Activate (USB_OTG_CORE_HANDLE *pdev);
+USB_OTG_STS  USB_OTG_EPActivate  (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS  USB_OTG_EPDeactivate(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS  USB_OTG_EPStartXfer (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS  USB_OTG_EP0StartXfer(USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS  USB_OTG_EPSetStall          (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+USB_OTG_STS  USB_OTG_EPClearStall        (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep);
+uint32_t     USB_OTG_ReadDevAllOutEp_itr (USB_OTG_CORE_HANDLE *pdev);
+uint32_t     USB_OTG_ReadDevOutEP_itr    (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+uint32_t     USB_OTG_ReadDevAllInEPItr   (USB_OTG_CORE_HANDLE *pdev);
+void         USB_OTG_InitDevSpeed        (USB_OTG_CORE_HANDLE *pdev , uint8_t speed);
+uint8_t      USBH_IsEvenFrame (USB_OTG_CORE_HANDLE *pdev);
+void         USB_OTG_EP0_OutStart(USB_OTG_CORE_HANDLE *pdev);
+void         USB_OTG_ActiveRemoteWakeup(USB_OTG_CORE_HANDLE *pdev);
+void         USB_OTG_UngateClock(USB_OTG_CORE_HANDLE *pdev);
+void         USB_OTG_StopDevice(USB_OTG_CORE_HANDLE *pdev);
+void         USB_OTG_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , USB_OTG_EP *ep , uint32_t Status);
+uint32_t     USB_OTG_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,USB_OTG_EP *ep);
+#endif
+/**
+  * @}
+  */
+
+#endif  /* __USB_CORE_H__ */
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd.c b/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd.c
new file mode 100644 (file)
index 0000000..bab0146
--- /dev/null
@@ -0,0 +1,475 @@
+/**
+  ******************************************************************************
+  * @file    usb_dcd.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   Peripheral Device Interface Layer
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+#include "usb_conf.h"
+#ifdef USE_DEVICE_MODE
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+#include "usb_bsp.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD
+* @brief This file is the interface between EFSL ans Host mass-storage class
+* @{
+*/
+
+
+/** @defgroup USB_DCD_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_DCD_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_FunctionPrototypes
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Private_Functions
+* @{
+*/
+
+
+
+void DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+              USB_OTG_CORE_ID_TypeDef coreID)
+{
+  uint32_t i;
+  USB_OTG_EP *ep;
+
+  USB_OTG_SelectCore (pdev , coreID);
+
+  pdev->dev.device_status = USB_OTG_DEFAULT;
+  pdev->dev.device_address = 0;
+
+  /* Init ep structure */
+  for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+  {
+    ep = &pdev->dev.in_ep[i];
+    /* Init ep structure */
+    ep->is_in = 1;
+    ep->num = i;
+    ep->tx_fifo_num = i;
+    /* Control until ep is actvated */
+    ep->type = EP_TYPE_CTRL;
+    ep->maxpacket =  USB_OTG_MAX_EP0_SIZE;
+    ep->xfer_buff = 0;
+    ep->xfer_len = 0;
+  }
+
+  for (i = 0; i < pdev->cfg.dev_endpoints; i++)
+  {
+    ep = &pdev->dev.out_ep[i];
+    /* Init ep structure */
+    ep->is_in = 0;
+    ep->num = i;
+    ep->tx_fifo_num = i;
+    /* Control until ep is activated */
+    ep->type = EP_TYPE_CTRL;
+    ep->maxpacket = USB_OTG_MAX_EP0_SIZE;
+    ep->xfer_buff = 0;
+    ep->xfer_len = 0;
+  }
+
+  USB_OTG_DisableGlobalInt(pdev);
+
+  /*Init the Core (common init.) */
+  USB_OTG_CoreInit(pdev);
+
+
+  /* Force Device Mode*/
+  USB_OTG_SetCurrentMode(pdev, DEVICE_MODE);
+
+  /* Init Device */
+  USB_OTG_CoreInitDev(pdev);
+
+
+  /* Enable USB Global interrupt */
+  USB_OTG_EnableGlobalInt(pdev);
+}
+
+
+/**
+* @brief  Configure an EP
+* @param pdev : Device instance
+* @param epdesc : Endpoint Descriptor
+* @retval : status
+*/
+uint32_t DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
+                     uint8_t ep_addr,
+                     uint16_t ep_mps,
+                     uint8_t ep_type)
+{
+  USB_OTG_EP *ep;
+
+  if ((ep_addr & 0x80) == 0x80)
+  {
+    ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+  }
+  else
+  {
+    ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+  }
+  ep->num   = ep_addr & 0x7F;
+
+  ep->is_in = (0x80 & ep_addr) != 0;
+  ep->maxpacket = ep_mps;
+  ep->type = ep_type;
+  if (ep->is_in)
+  {
+    /* Assign a Tx FIFO */
+    ep->tx_fifo_num = ep->num;
+  }
+  /* Set initial data PID. */
+  if (ep_type == USB_OTG_EP_BULK )
+  {
+    ep->data_pid_start = 0;
+  }
+  USB_OTG_EPActivate(pdev , ep );
+  return 0;
+}
+/**
+* @brief  called when an EP is disabled
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @retval : status
+*/
+uint32_t DCD_EP_Close(USB_OTG_CORE_HANDLE *pdev , uint8_t  ep_addr)
+{
+  USB_OTG_EP *ep;
+
+  if ((ep_addr&0x80) == 0x80)
+  {
+    ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+  }
+  else
+  {
+    ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+  }
+  ep->num   = ep_addr & 0x7F;
+  ep->is_in = (0x80 & ep_addr) != 0;
+  USB_OTG_EPDeactivate(pdev , ep );
+  return 0;
+}
+
+
+/**
+* @brief  DCD_EP_PrepareRx
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @param pbuf: pointer to Rx buffer
+* @param buf_len: data length
+* @retval : status
+*/
+uint32_t   DCD_EP_PrepareRx( USB_OTG_CORE_HANDLE *pdev,
+                            uint8_t   ep_addr,
+                            uint8_t *pbuf,
+                            uint16_t  buf_len)
+{
+  USB_OTG_EP *ep;
+
+  ep = &pdev->dev.out_ep[ep_addr & 0x7F];
+
+  /*setup and start the Xfer */
+  ep->xfer_buff = pbuf;
+  ep->xfer_len = buf_len;
+  ep->xfer_count = 0;
+  ep->is_in = 0;
+  ep->num = ep_addr & 0x7F;
+
+  if (pdev->cfg.dma_enable == 1)
+  {
+    ep->dma_addr = (uint32_t)pbuf;
+  }
+
+  if ( ep->num == 0 )
+  {
+    USB_OTG_EP0StartXfer(pdev , ep);
+  }
+  else
+  {
+    USB_OTG_EPStartXfer(pdev, ep );
+  }
+  return 0;
+}
+
+/**
+* @brief  Transmit data over USB
+* @param pdev: device instance
+* @param ep_addr: endpoint address
+* @param pbuf: pointer to Tx buffer
+* @param buf_len: data length
+* @retval : status
+*/
+uint32_t  DCD_EP_Tx ( USB_OTG_CORE_HANDLE *pdev,
+                     uint8_t   ep_addr,
+                     uint8_t   *pbuf,
+                     uint32_t   buf_len)
+{
+  USB_OTG_EP *ep;
+
+  ep = &pdev->dev.in_ep[ep_addr & 0x7F];
+
+  /* Setup and start the Transfer */
+  ep->is_in = 1;
+  ep->num = ep_addr & 0x7F;
+  ep->xfer_buff = pbuf;
+  ep->dma_addr = (uint32_t)pbuf;
+  ep->xfer_count = 0;
+  ep->xfer_len  = buf_len;
+
+  if ( ep->num == 0 )
+  {
+    USB_OTG_EP0StartXfer(pdev , ep);
+  }
+  else
+  {
+    USB_OTG_EPStartXfer(pdev, ep );
+  }
+  return 0;
+}
+
+
+/**
+* @brief  Stall an endpoint.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t  DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev, uint8_t   epnum)
+{
+  USB_OTG_EP *ep;
+  if ((0x80 & epnum) == 0x80)
+  {
+    ep = &pdev->dev.in_ep[epnum & 0x7F];
+  }
+  else
+  {
+    ep = &pdev->dev.out_ep[epnum];
+  }
+
+  ep->is_stall = 1;
+  ep->num   = epnum & 0x7F;
+  ep->is_in = ((epnum & 0x80) == 0x80);
+
+  USB_OTG_EPSetStall(pdev , ep);
+  return (0);
+}
+
+
+/**
+* @brief  Clear stall condition on endpoints.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t  DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+  USB_OTG_EP *ep;
+  if ((0x80 & epnum) == 0x80)
+  {
+    ep = &pdev->dev.in_ep[epnum & 0x7F];
+  }
+  else
+  {
+    ep = &pdev->dev.out_ep[epnum];
+  }
+
+  ep->is_stall = 0;
+  ep->num   = epnum & 0x7F;
+  ep->is_in = ((epnum & 0x80) == 0x80);
+
+  USB_OTG_EPClearStall(pdev , ep);
+  return (0);
+}
+
+
+/**
+* @brief  This Function flushes the FIFOs.
+* @param pdev: device instance
+* @param epnum: endpoint address
+* @retval : status
+*/
+uint32_t  DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum)
+{
+
+  if ((epnum & 0x80) == 0x80)
+  {
+    USB_OTG_FlushTxFifo(pdev, epnum & 0x7F);
+  }
+  else
+  {
+    USB_OTG_FlushRxFifo(pdev);
+  }
+
+  return (0);
+}
+
+
+/**
+* @brief  This Function set USB device address
+* @param pdev: device instance
+* @param address: new device address
+* @retval : status
+*/
+void  DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev, uint8_t address)
+{
+  USB_OTG_DCFG_TypeDef  dcfg;
+  dcfg.d32 = 0;
+  dcfg.b.devaddr = address;
+  USB_OTG_MODIFY_REG32( &pdev->regs.DREGS->DCFG, 0, dcfg.d32);
+}
+
+/**
+* @brief  Connect device (enable internal pull-up)
+* @param pdev: device instance
+* @retval : None
+*/
+void  DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev)
+{
+#ifndef USE_OTG_MODE
+  USB_OTG_DCTL_TypeDef  dctl;
+  dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+  /* Connect device */
+  dctl.b.sftdiscon  = 0;
+  USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
+  USB_OTG_BSP_mDelay(3);
+#endif
+}
+
+
+/**
+* @brief  Disconnect device (disable internal pull-up)
+* @param pdev: device instance
+* @retval : None
+*/
+void  DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev)
+{
+#ifndef USE_OTG_MODE
+  USB_OTG_DCTL_TypeDef  dctl;
+  dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
+  /* Disconnect device for 3ms */
+  dctl.b.sftdiscon  = 1;
+  USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
+  USB_OTG_BSP_mDelay(3);
+#endif
+}
+
+
+/**
+* @brief  returns the EP Status
+* @param  pdev : Selected device
+*         epnum : endpoint address
+* @retval : EP status
+*/
+
+uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,uint8_t epnum)
+{
+  USB_OTG_EP *ep;
+  uint32_t Status = 0;
+
+  if ((0x80 & epnum) == 0x80)
+  {
+    ep = &pdev->dev.in_ep[epnum & 0x7F];
+  }
+  else
+  {
+    ep = &pdev->dev.out_ep[epnum];
+  }
+
+  Status = USB_OTG_GetEPStatus(pdev ,ep);
+
+  /* Return the current status */
+  return Status;
+}
+
+/**
+* @brief  Set the EP Status
+* @param  pdev : Selected device
+*         Status : new Status
+*         epnum : EP address
+* @retval : None
+*/
+void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum , uint32_t Status)
+{
+  USB_OTG_EP *ep;
+
+  if ((0x80 & epnum) == 0x80)
+  {
+    ep = &pdev->dev.in_ep[epnum & 0x7F];
+  }
+  else
+  {
+    ep = &pdev->dev.out_ep[epnum];
+  }
+
+   USB_OTG_SetEPStatus(pdev ,ep , Status);
+}
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+#endif
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd.h b/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd.h
new file mode 100644 (file)
index 0000000..9a23dc6
--- /dev/null
@@ -0,0 +1,158 @@
+/**
+  ******************************************************************************
+  * @file    usb_dcd.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   Peripheral Driver Header file
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __DCD_H__
+#define __DCD_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_core.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD
+* @brief This file is the
+* @{
+*/
+
+
+/** @defgroup USB_DCD_Exported_Defines
+* @{
+*/
+#define USB_OTG_EP_CONTROL                       0
+#define USB_OTG_EP_ISOC                          1
+#define USB_OTG_EP_BULK                          2
+#define USB_OTG_EP_INT                           3
+#define USB_OTG_EP_MASK                          3
+
+/*  Device Status */
+#define USB_OTG_DEFAULT                          1
+#define USB_OTG_ADDRESSED                        2
+#define USB_OTG_CONFIGURED                       3
+#define USB_OTG_SUSPENDED                        4
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Exported_Types
+* @{
+*/
+/********************************************************************************
+Data structure type
+********************************************************************************/
+typedef struct
+{
+  uint8_t  bLength;
+  uint8_t  bDescriptorType;
+  uint8_t  bEndpointAddress;
+  uint8_t  bmAttributes;
+  uint16_t wMaxPacketSize;
+  uint8_t  bInterval;
+}
+EP_DESCRIPTOR , *PEP_DESCRIPTOR;
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_Exported_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USB_DCD_Exported_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USB_DCD_Exported_FunctionsPrototype
+* @{
+*/
+/********************************************************************************
+EXPORTED FUNCTION FROM THE USB-OTG LAYER
+********************************************************************************/
+void       DCD_Init(USB_OTG_CORE_HANDLE *pdev ,
+                    USB_OTG_CORE_ID_TypeDef coreID);
+
+void        DCD_DevConnect (USB_OTG_CORE_HANDLE *pdev);
+void        DCD_DevDisconnect (USB_OTG_CORE_HANDLE *pdev);
+void        DCD_EP_SetAddress (USB_OTG_CORE_HANDLE *pdev,
+                               uint8_t address);
+uint32_t    DCD_EP_Open(USB_OTG_CORE_HANDLE *pdev ,
+                     uint8_t ep_addr,
+                     uint16_t ep_mps,
+                     uint8_t ep_type);
+
+uint32_t    DCD_EP_Close  (USB_OTG_CORE_HANDLE *pdev,
+                                uint8_t  ep_addr);
+
+
+uint32_t   DCD_EP_PrepareRx ( USB_OTG_CORE_HANDLE *pdev,
+                        uint8_t   ep_addr,
+                        uint8_t *pbuf,
+                        uint16_t  buf_len);
+
+uint32_t    DCD_EP_Tx (USB_OTG_CORE_HANDLE *pdev,
+                               uint8_t  ep_addr,
+                               uint8_t  *pbuf,
+                               uint32_t   buf_len);
+uint32_t    DCD_EP_Stall (USB_OTG_CORE_HANDLE *pdev,
+                              uint8_t   epnum);
+uint32_t    DCD_EP_ClrStall (USB_OTG_CORE_HANDLE *pdev,
+                                  uint8_t epnum);
+uint32_t    DCD_EP_Flush (USB_OTG_CORE_HANDLE *pdev,
+                               uint8_t epnum);
+uint32_t    DCD_Handle_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+uint32_t DCD_GetEPStatus(USB_OTG_CORE_HANDLE *pdev ,
+                         uint8_t epnum);
+
+void DCD_SetEPStatus (USB_OTG_CORE_HANDLE *pdev ,
+                      uint8_t epnum ,
+                      uint32_t Status);
+
+/**
+* @}
+*/
+
+
+#endif //__DCD_H__
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd_int.c b/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd_int.c
new file mode 100644 (file)
index 0000000..82567eb
--- /dev/null
@@ -0,0 +1,889 @@
+/**
+  ******************************************************************************
+  * @file    usb_dcd_int.c
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   Peripheral Device interrupt subroutines
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+#include "usb_conf.h"
+#ifdef USE_DEVICE_MODE
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd_int.h"
+/** @addtogroup USB_OTG_DRIVER
+* @{
+*/
+
+/** @defgroup USB_DCD_INT
+* @brief This file contains the interrupt subroutines for the Device mode.
+* @{
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+
+/** @defgroup USB_DCD_INT_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_FunctionPrototypes
+* @{
+*/
+/* static functions */
+static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum);
+
+/* Interrupt Handlers */
+static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum);
+
+static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev);
+
+static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
+#ifdef VBUS_SENSING_ENABLED
+static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
+static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev);
+#endif
+
+/**
+* @}
+*/
+
+
+/** @defgroup USB_DCD_INT_Private_Functions
+* @{
+*/
+
+
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+/**
+* @brief  USBD_OTG_EP1OUT_ISR_Handler
+*         handles all USB Interrupts
+* @param  pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+
+  USB_OTG_DOEPINTn_TypeDef  doepint;
+  USB_OTG_DEPXFRSIZ_TypeDef  deptsiz;
+
+  doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT);
+  doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK);
+
+  /* Transfer complete */
+  if ( doepint.b.xfercompl )
+  {
+    /* Clear the bit in DOEPINTn for this interrupt */
+    CLEAR_OUT_EP_INTR(1, xfercompl);
+    if (pdev->cfg.dma_enable == 1)
+    {
+      deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ));
+      /*ToDo : handle more than one single MPS size packet */
+      pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \
+        deptsiz.b.xfersize;
+    }
+    /* Inform upper layer: data ready */
+    /* RX COMPLETE */
+    USBD_DCD_INT_fops->DataOutStage(pdev , 1);
+
+  }
+
+  /* Endpoint disable  */
+  if ( doepint.b.epdisabled )
+  {
+    /* Clear the bit in DOEPINTn for this interrupt */
+    CLEAR_OUT_EP_INTR(1, epdisabled);
+  }
+  /* AHB Error */
+  if ( doepint.b.ahberr )
+  {
+    CLEAR_OUT_EP_INTR(1, ahberr);
+  }
+  return 1;
+}
+
+/**
+* @brief  USBD_OTG_EP1IN_ISR_Handler
+*         handles all USB Interrupts
+* @param  pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+
+  USB_OTG_DIEPINTn_TypeDef  diepint;
+  uint32_t fifoemptymsk, msk, emp;
+
+  msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
+  emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
+  msk |= ((emp >> 1 ) & 0x1) << 7;
+  diepint.d32  = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;
+
+  if ( diepint.b.xfercompl )
+  {
+    fifoemptymsk = 0x1 << 1;
+    USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
+    CLEAR_IN_EP_INTR(1, xfercompl);
+    /* TX COMPLETE */
+    USBD_DCD_INT_fops->DataInStage(pdev , 1);
+  }
+  if ( diepint.b.ahberr )
+  {
+    CLEAR_IN_EP_INTR(1, ahberr);
+  }
+  if ( diepint.b.epdisabled )
+  {
+    CLEAR_IN_EP_INTR(1, epdisabled);
+  }
+  if ( diepint.b.timeout )
+  {
+    CLEAR_IN_EP_INTR(1, timeout);
+  }
+  if (diepint.b.intktxfemp)
+  {
+    CLEAR_IN_EP_INTR(1, intktxfemp);
+  }
+  if (diepint.b.intknepmis)
+  {
+    CLEAR_IN_EP_INTR(1, intknepmis);
+  }
+  if (diepint.b.inepnakeff)
+  {
+    CLEAR_IN_EP_INTR(1, inepnakeff);
+  }
+  if (diepint.b.emptyintr)
+  {
+    DCD_WriteEmptyTxFifo(pdev , 1);
+    CLEAR_IN_EP_INTR(1, emptyintr);
+  }
+  return 1;
+}
+#endif
+
+/**
+* @brief  STM32_USBF_OTG_ISR_Handler
+*         handles all USB Interrupts
+* @param  pdev: device instance
+* @retval status
+*/
+uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef  gintr_status;
+  uint32_t retval = 0;
+
+  if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
+  {
+    gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
+    if (!gintr_status.d32) /* avoid spurious interrupt */
+    {
+      return 0;
+    }
+
+    if (gintr_status.b.outepintr)
+    {
+      retval |= DCD_HandleOutEP_ISR(pdev);
+    }
+
+    if (gintr_status.b.inepint)
+    {
+      retval |= DCD_HandleInEP_ISR(pdev);
+    }
+
+    if (gintr_status.b.modemismatch)
+    {
+      USB_OTG_GINTSTS_TypeDef  gintsts;
+
+      /* Clear interrupt */
+      gintsts.d32 = 0;
+      gintsts.b.modemismatch = 1;
+      USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+    }
+
+    if (gintr_status.b.wkupintr)
+    {
+      retval |= DCD_HandleResume_ISR(pdev);
+    }
+
+    if (gintr_status.b.usbsuspend)
+    {
+      retval |= DCD_HandleUSBSuspend_ISR(pdev);
+    }
+    if (gintr_status.b.sofintr)
+    {
+      retval |= DCD_HandleSof_ISR(pdev);
+
+    }
+
+    if (gintr_status.b.rxstsqlvl)
+    {
+      retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);
+
+    }
+
+    if (gintr_status.b.usbreset)
+    {
+      retval |= DCD_HandleUsbReset_ISR(pdev);
+
+    }
+    if (gintr_status.b.enumdone)
+    {
+      retval |= DCD_HandleEnumDone_ISR(pdev);
+    }
+
+    if (gintr_status.b.incomplisoin)
+    {
+      retval |= DCD_IsoINIncomplete_ISR(pdev);
+    }
+
+    if (gintr_status.b.incomplisoout)
+    {
+      retval |= DCD_IsoOUTIncomplete_ISR(pdev);
+    }
+#ifdef VBUS_SENSING_ENABLED
+    if (gintr_status.b.sessreqintr)
+    {
+      retval |= DCD_SessionRequest_ISR(pdev);
+    }
+
+    if (gintr_status.b.otgintr)
+    {
+      retval |= DCD_OTG_ISR(pdev);
+    }
+#endif
+  }
+  return retval;
+}
+
+#ifdef VBUS_SENSING_ENABLED
+/**
+* @brief  DCD_SessionRequest_ISR
+*         Indicates that the USB_OTG controller has detected a connection
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef  gintsts;
+  USBD_DCD_INT_fops->DevConnected (pdev);
+
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.sessreqintr = 1;
+  USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+  return 1;
+}
+
+/**
+* @brief  DCD_OTG_ISR
+*         Indicates that the USB_OTG controller has detected an OTG event:
+*                 used to detect the end of session i.e. disconnection
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+
+  USB_OTG_GOTGINT_TypeDef  gotgint;
+
+  gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
+
+  if (gotgint.b.sesenddet)
+  {
+    USBD_DCD_INT_fops->DevDisconnected (pdev);
+  }
+  /* Clear OTG interrupt */
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
+  return 1;
+}
+#endif
+/**
+* @brief  DCD_HandleResume_ISR
+*         Indicates that the USB_OTG controller has detected a resume or
+*                 remote Wake-up sequence
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef  gintsts;
+  USB_OTG_DCTL_TypeDef     devctl;
+  USB_OTG_PCGCCTL_TypeDef  power;
+
+  if(pdev->cfg.low_power)
+  {
+    /* un-gate USB Core clock */
+    power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL);
+    power.b.gatehclk = 0;
+    power.b.stoppclk = 0;
+    USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
+  }
+
+  /* Clear the Remote Wake-up Signaling */
+  devctl.d32 = 0;
+  devctl.b.rmtwkupsig = 1;
+  USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0);
+
+  /* Inform upper layer by the Resume Event */
+  USBD_DCD_INT_fops->Resume (pdev);
+
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.wkupintr = 1;
+  USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+  return 1;
+}
+
+/**
+* @brief  USB_OTG_HandleUSBSuspend_ISR
+*         Indicates that SUSPEND state has been detected on the USB
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef  gintsts;
+  USB_OTG_PCGCCTL_TypeDef  power;
+  USB_OTG_DSTS_TypeDef     dsts;
+
+  USBD_DCD_INT_fops->Suspend (pdev);
+
+  dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
+
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.usbsuspend = 1;
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+  if((pdev->cfg.low_power) && (dsts.b.suspsts == 1))
+  {
+       /*  switch-off the clocks */
+    power.d32 = 0;
+    power.b.stoppclk = 1;
+    USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
+
+    power.b.gatehclk = 1;
+    USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
+
+    /* Request to enter Sleep mode after exit from current ISR */
+    SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
+  }
+  return 1;
+}
+
+/**
+* @brief  DCD_HandleInEP_ISR
+*         Indicates that an IN EP has a pending Interrupt
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_DIEPINTn_TypeDef  diepint;
+
+  uint32_t ep_intr;
+  uint32_t epnum = 0;
+  uint32_t fifoemptymsk;
+  diepint.d32 = 0;
+  ep_intr = USB_OTG_ReadDevAllInEPItr(pdev);
+
+  while ( ep_intr )
+  {
+    if (ep_intr&0x1) /* In ITR */
+    {
+      diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */
+      if ( diepint.b.xfercompl )
+      {
+        fifoemptymsk = 0x1 << epnum;
+        USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
+        CLEAR_IN_EP_INTR(epnum, xfercompl);
+        /* TX COMPLETE */
+        USBD_DCD_INT_fops->DataInStage(pdev , epnum);
+
+        if (pdev->cfg.dma_enable == 1)
+        {
+          if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN))
+          {
+            /* prepare to rx more setup packets */
+            USB_OTG_EP0_OutStart(pdev);
+          }
+        }
+      }
+      if ( diepint.b.ahberr )
+      {
+        CLEAR_IN_EP_INTR(epnum, ahberr);
+      }
+      if ( diepint.b.timeout )
+      {
+        CLEAR_IN_EP_INTR(epnum, timeout);
+      }
+      if (diepint.b.intktxfemp)
+      {
+        CLEAR_IN_EP_INTR(epnum, intktxfemp);
+      }
+      if (diepint.b.intknepmis)
+      {
+        CLEAR_IN_EP_INTR(epnum, intknepmis);
+      }
+      if (diepint.b.inepnakeff)
+      {
+        CLEAR_IN_EP_INTR(epnum, inepnakeff);
+      }
+      if ( diepint.b.epdisabled )
+      {
+        CLEAR_IN_EP_INTR(epnum, epdisabled);
+      }
+      if (diepint.b.emptyintr)
+      {
+
+        DCD_WriteEmptyTxFifo(pdev , epnum);
+
+        CLEAR_IN_EP_INTR(epnum, emptyintr);
+      }
+    }
+    epnum++;
+    ep_intr >>= 1;
+  }
+
+  return 1;
+}
+
+/**
+* @brief  DCD_HandleOutEP_ISR
+*         Indicates that an OUT EP has a pending Interrupt
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  uint32_t ep_intr;
+  USB_OTG_DOEPINTn_TypeDef  doepint;
+  USB_OTG_DEPXFRSIZ_TypeDef  deptsiz;
+  uint32_t epnum = 0;
+
+  doepint.d32 = 0;
+
+  /* Read in the device interrupt bits */
+  ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev);
+
+  while ( ep_intr )
+  {
+    if (ep_intr&0x1)
+    {
+
+      doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum);
+
+      /* Transfer complete */
+      if ( doepint.b.xfercompl )
+      {
+        /* Clear the bit in DOEPINTn for this interrupt */
+        CLEAR_OUT_EP_INTR(epnum, xfercompl);
+        if (pdev->cfg.dma_enable == 1)
+        {
+          deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ));
+          /*ToDo : handle more than one single MPS size packet */
+          pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \
+            deptsiz.b.xfersize;
+        }
+        /* Inform upper layer: data ready */
+        /* RX COMPLETE */
+        USBD_DCD_INT_fops->DataOutStage(pdev , epnum);
+
+        if (pdev->cfg.dma_enable == 1)
+        {
+          if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT))
+          {
+            /* prepare to rx more setup packets */
+            USB_OTG_EP0_OutStart(pdev);
+          }
+        }
+      }
+      /* Endpoint disable  */
+      if ( doepint.b.epdisabled )
+      {
+        /* Clear the bit in DOEPINTn for this interrupt */
+        CLEAR_OUT_EP_INTR(epnum, epdisabled);
+      }
+      /* AHB Error */
+      if ( doepint.b.ahberr )
+      {
+        CLEAR_OUT_EP_INTR(epnum, ahberr);
+      }
+      /* Setup Phase Done (control EPs) */
+      if ( doepint.b.setup )
+      {
+
+        /* inform the upper layer that a setup packet is available */
+        /* SETUP COMPLETE */
+        USBD_DCD_INT_fops->SetupStage(pdev);
+        CLEAR_OUT_EP_INTR(epnum, setup);
+      }
+    }
+    epnum++;
+    ep_intr >>= 1;
+  }
+  return 1;
+}
+
+/**
+* @brief  DCD_HandleSof_ISR
+*         Handles the SOF Interrupts
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef  GINTSTS;
+
+
+  USBD_DCD_INT_fops->SOF(pdev);
+
+  /* Clear interrupt */
+  GINTSTS.d32 = 0;
+  GINTSTS.b.sofintr = 1;
+  USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32);
+
+  return 1;
+}
+
+/**
+* @brief  DCD_HandleRxStatusQueueLevel_ISR
+*         Handles the Rx Status Queue Level Interrupt
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTMSK_TypeDef  int_mask;
+  USB_OTG_DRXSTS_TypeDef   status;
+  USB_OTG_EP *ep;
+
+  /* Disable the Rx Status Queue Level interrupt */
+  int_mask.d32 = 0;
+  int_mask.b.rxstsqlvl = 1;
+  USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0);
+
+  /* Get the Status from the top of the FIFO */
+  status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP );
+
+  ep = &pdev->dev.out_ep[status.b.epnum];
+
+  switch (status.b.pktsts)
+  {
+  case STS_GOUT_NAK:
+    break;
+  case STS_DATA_UPDT:
+    if (status.b.bcnt)
+    {
+      USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);
+      ep->xfer_buff += status.b.bcnt;
+      ep->xfer_count += status.b.bcnt;
+    }
+    break;
+  case STS_XFER_COMP:
+    break;
+  case STS_SETUP_COMP:
+    break;
+  case STS_SETUP_UPDT:
+    /* Copy the setup packet received in FIFO into the setup buffer in RAM */
+    USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8);
+    ep->xfer_count += status.b.bcnt;
+    break;
+  default:
+    break;
+  }
+
+  /* Enable the Rx Status Queue Level interrupt */
+  USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32);
+
+  return 1;
+}
+
+/**
+* @brief  DCD_WriteEmptyTxFifo
+*         check FIFO for the next packet to be loaded
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
+{
+  USB_OTG_DTXFSTSn_TypeDef  txstatus;
+  USB_OTG_EP *ep;
+  uint32_t len = 0;
+  uint32_t len32b;
+  txstatus.d32 = 0;
+
+  ep = &pdev->dev.in_ep[epnum];
+
+  len = ep->xfer_len - ep->xfer_count;
+
+  if (len > ep->maxpacket)
+  {
+    len = ep->maxpacket;
+  }
+
+  len32b = (len + 3) / 4;
+  txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
+
+
+
+  while  (txstatus.b.txfspcavail > len32b &&
+          ep->xfer_count < ep->xfer_len &&
+            ep->xfer_len != 0)
+  {
+    /* Write the FIFO */
+    len = ep->xfer_len - ep->xfer_count;
+
+    if (len > ep->maxpacket)
+    {
+      len = ep->maxpacket;
+    }
+    len32b = (len + 3) / 4;
+
+    USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
+
+    ep->xfer_buff  += len;
+    ep->xfer_count += len;
+
+    txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
+  }
+
+  return 1;
+}
+
+/**
+* @brief  DCD_HandleUsbReset_ISR
+*         This interrupt occurs when a USB Reset is detected
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_DAINT_TypeDef    daintmsk;
+  USB_OTG_DOEPMSK_TypeDef  doepmsk;
+  USB_OTG_DIEPMSK_TypeDef  diepmsk;
+  USB_OTG_DCFG_TypeDef     dcfg;
+  USB_OTG_DCTL_TypeDef     dctl;
+  USB_OTG_GINTSTS_TypeDef  gintsts;
+  uint32_t i;
+
+  dctl.d32 = 0;
+  daintmsk.d32 = 0;
+  doepmsk.d32 = 0;
+  diepmsk.d32 = 0;
+  dcfg.d32 = 0;
+  gintsts.d32 = 0;
+
+  /* Clear the Remote Wake-up Signaling */
+  dctl.b.rmtwkupsig = 1;
+  USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
+
+  /* Flush the Tx FIFO */
+  USB_OTG_FlushTxFifo(pdev ,  0 );
+
+  for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
+  {
+    USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
+    USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
+  }
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
+
+  daintmsk.ep.in = 1;
+  daintmsk.ep.out = 1;
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 );
+
+  doepmsk.b.setup = 1;
+  doepmsk.b.xfercompl = 1;
+  doepmsk.b.ahberr = 1;
+  doepmsk.b.epdisabled = 1;
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 );
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 );
+#endif
+  diepmsk.b.xfercompl = 1;
+  diepmsk.b.timeout = 1;
+  diepmsk.b.epdisabled = 1;
+  diepmsk.b.ahberr = 1;
+  diepmsk.b.intknepmis = 1;
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 );
+#ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 );
+#endif
+  /* Reset Device Address */
+  dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
+  dcfg.b.devaddr = 0;
+  USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32);
+
+
+  /* setup EP0 to receive SETUP packets */
+  USB_OTG_EP0_OutStart(pdev);
+
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.usbreset = 1;
+  USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+  /*Reset internal state machine */
+  USBD_DCD_INT_fops->Reset(pdev);
+  return 1;
+}
+
+/**
+* @brief  DCD_HandleEnumDone_ISR
+*         Read the device status register and set the device speed
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef  gintsts;
+  USB_OTG_GUSBCFG_TypeDef  gusbcfg;
+
+  USB_OTG_EP0Activate(pdev);
+
+  /* Set USB turn-around time based on device speed and PHY interface. */
+  gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
+
+  /* Full or High speed */
+  if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH)
+  {
+    pdev->cfg.speed            = USB_OTG_SPEED_HIGH;
+    pdev->cfg.mps              = USB_OTG_HS_MAX_PACKET_SIZE ;
+    gusbcfg.b.usbtrdtim = 9;
+  }
+  else
+  {
+    pdev->cfg.speed            = USB_OTG_SPEED_FULL;
+    pdev->cfg.mps              = USB_OTG_FS_MAX_PACKET_SIZE ;
+    gusbcfg.b.usbtrdtim = 5;
+  }
+
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
+
+  /* Clear interrupt */
+  gintsts.d32 = 0;
+  gintsts.b.enumdone = 1;
+  USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 );
+  return 1;
+}
+
+
+/**
+* @brief  DCD_IsoINIncomplete_ISR
+*         handle the ISO IN incomplete interrupt
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef gintsts;
+
+  gintsts.d32 = 0;
+
+  USBD_DCD_INT_fops->IsoINIncomplete (pdev);
+
+  /* Clear interrupt */
+  gintsts.b.incomplisoin = 1;
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+
+  return 1;
+}
+
+/**
+* @brief  DCD_IsoOUTIncomplete_ISR
+*         handle the ISO OUT incomplete interrupt
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
+{
+  USB_OTG_GINTSTS_TypeDef gintsts;
+
+  gintsts.d32 = 0;
+
+  USBD_DCD_INT_fops->IsoOUTIncomplete (pdev);
+
+  /* Clear interrupt */
+  gintsts.b.incomplisoout = 1;
+  USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
+  return 1;
+}
+/**
+* @brief  DCD_ReadDevInEP
+*         Reads ep flags
+* @param  pdev: device instance
+* @retval status
+*/
+static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
+{
+  uint32_t v, msk, emp;
+  msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK);
+  emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
+  msk |= ((emp >> epnum) & 0x1) << 7;
+  v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk;
+  return v;
+}
+
+
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+#endif
+
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd_int.h b/codec2/branches/0.7/stm32/usb_lib/otg/usb_dcd_int.h
new file mode 100644 (file)
index 0000000..3cbebd8
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+  ******************************************************************************
+  * @file    usb_dcd_int.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   Peripheral Device Interface Layer
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef USB_DCD_INT_H__
+#define USB_DCD_INT_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_dcd.h"
+
+
+
+/** @addtogroup USB_OTG_DRIVER
+  * @{
+  */
+
+/** @defgroup USB_DCD_INT
+  * @brief This file is the
+  * @{
+  */
+
+
+/** @defgroup USB_DCD_INT_Exported_Defines
+  * @{
+  */
+
+typedef struct _USBD_DCD_INT
+{
+  uint8_t (* DataOutStage) (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+  uint8_t (* DataInStage)  (USB_OTG_CORE_HANDLE *pdev , uint8_t epnum);
+  uint8_t (* SetupStage) (USB_OTG_CORE_HANDLE *pdev);
+  uint8_t (* SOF) (USB_OTG_CORE_HANDLE *pdev);
+  uint8_t (* Reset) (USB_OTG_CORE_HANDLE *pdev);
+  uint8_t (* Suspend) (USB_OTG_CORE_HANDLE *pdev);
+  uint8_t (* Resume) (USB_OTG_CORE_HANDLE *pdev);
+  uint8_t (* IsoINIncomplete) (USB_OTG_CORE_HANDLE *pdev);
+  uint8_t (* IsoOUTIncomplete) (USB_OTG_CORE_HANDLE *pdev);
+
+  uint8_t (* DevConnected) (USB_OTG_CORE_HANDLE *pdev);
+  uint8_t (* DevDisconnected) (USB_OTG_CORE_HANDLE *pdev);
+
+}USBD_DCD_INT_cb_TypeDef;
+
+extern USBD_DCD_INT_cb_TypeDef *USBD_DCD_INT_fops;
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_DCD_INT_Exported_Types
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_DCD_INT_Exported_Macros
+  * @{
+  */
+
+#define CLEAR_IN_EP_INTR(epnum,intr) \
+  diepint.d32=0; \
+  diepint.b.intr = 1; \
+  USB_OTG_WRITE_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT,diepint.d32);
+
+#define CLEAR_OUT_EP_INTR(epnum,intr) \
+  doepint.d32=0; \
+  doepint.b.intr = 1; \
+  USB_OTG_WRITE_REG32(&pdev->regs.OUTEP_REGS[epnum]->DOEPINT,doepint.d32);
+
+/**
+  * @}
+  */
+
+/** @defgroup USB_DCD_INT_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_DCD_INT_Exported_FunctionsPrototype
+  * @{
+  */
+
+uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev);
+
+/**
+  * @}
+  */
+
+
+#endif // USB_DCD_INT_H__
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_defines.h b/codec2/branches/0.7/stm32/usb_lib/otg/usb_defines.h
new file mode 100644 (file)
index 0000000..70f9952
--- /dev/null
@@ -0,0 +1,244 @@
+/**
+  ******************************************************************************
+  * @file    usb_defines.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   Header of the Core Layer
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_DEF_H__
+#define __USB_DEF_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include  "usb_conf.h"
+
+/** @addtogroup USB_OTG_DRIVER
+  * @{
+  */
+
+/** @defgroup USB_DEFINES
+  * @brief This file is the
+  * @{
+  */
+
+
+/** @defgroup USB_DEFINES_Exported_Defines
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup _CORE_DEFINES_
+  * @{
+  */
+
+#define USB_OTG_SPEED_PARAM_HIGH 0
+#define USB_OTG_SPEED_PARAM_HIGH_IN_FULL 1
+#define USB_OTG_SPEED_PARAM_FULL 3
+
+#define USB_OTG_SPEED_HIGH      0
+#define USB_OTG_SPEED_FULL      1
+
+#define USB_OTG_ULPI_PHY      1
+#define USB_OTG_EMBEDDED_PHY  2
+#define USB_OTG_I2C_PHY       3
+
+/**
+  * @}
+  */
+
+
+/** @defgroup _GLOBAL_DEFINES_
+  * @{
+  */
+#define GAHBCFG_TXFEMPTYLVL_EMPTY              1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY          0
+#define GAHBCFG_GLBINT_ENABLE                  1
+#define GAHBCFG_INT_DMA_BURST_SINGLE           0
+#define GAHBCFG_INT_DMA_BURST_INCR             1
+#define GAHBCFG_INT_DMA_BURST_INCR4            3
+#define GAHBCFG_INT_DMA_BURST_INCR8            5
+#define GAHBCFG_INT_DMA_BURST_INCR16           7
+#define GAHBCFG_DMAENABLE                      1
+#define GAHBCFG_TXFEMPTYLVL_EMPTY              1
+#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY          0
+#define GRXSTS_PKTSTS_IN                       2
+#define GRXSTS_PKTSTS_IN_XFER_COMP             3
+#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR          5
+#define GRXSTS_PKTSTS_CH_HALTED                7
+/**
+  * @}
+  */
+
+
+/** @defgroup _OnTheGo_DEFINES_
+  * @{
+  */
+#define MODE_HNP_SRP_CAPABLE                   0
+#define MODE_SRP_ONLY_CAPABLE                  1
+#define MODE_NO_HNP_SRP_CAPABLE                2
+#define MODE_SRP_CAPABLE_DEVICE                3
+#define MODE_NO_SRP_CAPABLE_DEVICE             4
+#define MODE_SRP_CAPABLE_HOST                  5
+#define MODE_NO_SRP_CAPABLE_HOST               6
+#define A_HOST                                 1
+#define A_SUSPEND                              2
+#define A_PERIPHERAL                           3
+#define B_PERIPHERAL                           4
+#define B_HOST                                 5
+#define DEVICE_MODE                            0
+#define HOST_MODE                              1
+#define OTG_MODE                               2
+/**
+  * @}
+  */
+
+
+/** @defgroup __DEVICE_DEFINES_
+  * @{
+  */
+#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ     0
+#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ     1
+#define DSTS_ENUMSPD_LS_PHY_6MHZ               2
+#define DSTS_ENUMSPD_FS_PHY_48MHZ              3
+
+#define DCFG_FRAME_INTERVAL_80                 0
+#define DCFG_FRAME_INTERVAL_85                 1
+#define DCFG_FRAME_INTERVAL_90                 2
+#define DCFG_FRAME_INTERVAL_95                 3
+
+#define DEP0CTL_MPS_64                         0
+#define DEP0CTL_MPS_32                         1
+#define DEP0CTL_MPS_16                         2
+#define DEP0CTL_MPS_8                          3
+
+#define EP_SPEED_LOW                           0
+#define EP_SPEED_FULL                          1
+#define EP_SPEED_HIGH                          2
+
+#define EP_TYPE_CTRL                           0
+#define EP_TYPE_ISOC                           1
+#define EP_TYPE_BULK                           2
+#define EP_TYPE_INTR                           3
+#define EP_TYPE_MSK                            3
+
+#define STS_GOUT_NAK                           1
+#define STS_DATA_UPDT                          2
+#define STS_XFER_COMP                          3
+#define STS_SETUP_COMP                         4
+#define STS_SETUP_UPDT                         6
+/**
+  * @}
+  */
+
+
+/** @defgroup __HOST_DEFINES_
+  * @{
+  */
+#define HC_PID_DATA0                           0
+#define HC_PID_DATA2                           1
+#define HC_PID_DATA1                           2
+#define HC_PID_SETUP                           3
+
+#define HPRT0_PRTSPD_HIGH_SPEED                0
+#define HPRT0_PRTSPD_FULL_SPEED                1
+#define HPRT0_PRTSPD_LOW_SPEED                 2
+
+#define HCFG_30_60_MHZ                         0
+#define HCFG_48_MHZ                            1
+#define HCFG_6_MHZ                             2
+
+#define HCCHAR_CTRL                            0
+#define HCCHAR_ISOC                            1
+#define HCCHAR_BULK                            2
+#define HCCHAR_INTR                            3
+
+#define  MIN(a, b)      (((a) < (b)) ? (a) : (b))
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_DEFINES_Exported_Types
+  * @{
+  */
+
+typedef enum
+{
+  USB_OTG_HS_CORE_ID = 0,
+  USB_OTG_FS_CORE_ID = 1
+}USB_OTG_CORE_ID_TypeDef;
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_DEFINES_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_DEFINES_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_DEFINES_Exported_FunctionsPrototype
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+/** @defgroup Internal_Macro's
+  * @{
+  */
+#define USB_OTG_READ_REG32(reg)  (*(__IO uint32_t *)reg)
+#define USB_OTG_WRITE_REG32(reg,value) (*(__IO uint32_t *)reg = value)
+#define USB_OTG_MODIFY_REG32(reg,clear_mask,set_mask) \
+  USB_OTG_WRITE_REG32(reg, (((USB_OTG_READ_REG32(reg)) & ~clear_mask) | set_mask ) )
+
+/********************************************************************************
+                              ENUMERATION TYPE
+********************************************************************************/
+enum USB_OTG_SPEED {
+  USB_SPEED_UNKNOWN = 0,
+  USB_SPEED_LOW,
+  USB_SPEED_FULL,
+  USB_SPEED_HIGH
+};
+
+#endif //__USB_DEFINES__H__
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/stm32/usb_lib/otg/usb_regs.h b/codec2/branches/0.7/stm32/usb_lib/otg/usb_regs.h
new file mode 100644 (file)
index 0000000..57e478c
--- /dev/null
@@ -0,0 +1,1206 @@
+/**
+  ******************************************************************************
+  * @file    usb_regs.h
+  * @author  MCD Application Team
+  * @version V2.0.0
+  * @date    22-July-2011
+  * @brief   hardware registers
+  ******************************************************************************
+  * @attention
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USB_OTG_REGS_H__
+#define __USB_OTG_REGS_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usb_conf.h"
+
+
+/** @addtogroup USB_OTG_DRIVER
+  * @{
+  */
+
+/** @defgroup USB_REGS
+  * @brief This file is the
+  * @{
+  */
+
+
+/** @defgroup USB_REGS_Exported_Defines
+  * @{
+  */
+
+#define USB_OTG_HS_BASE_ADDR                 0x40040000
+#define USB_OTG_FS_BASE_ADDR                 0x50000000
+
+#define USB_OTG_CORE_GLOBAL_REGS_OFFSET      0x000
+#define USB_OTG_DEV_GLOBAL_REG_OFFSET        0x800
+#define USB_OTG_DEV_IN_EP_REG_OFFSET         0x900
+#define USB_OTG_EP_REG_OFFSET                0x20
+#define USB_OTG_DEV_OUT_EP_REG_OFFSET        0xB00
+#define USB_OTG_HOST_GLOBAL_REG_OFFSET       0x400
+#define USB_OTG_HOST_PORT_REGS_OFFSET        0x440
+#define USB_OTG_HOST_CHAN_REGS_OFFSET        0x500
+#define USB_OTG_CHAN_REGS_OFFSET             0x20
+#define USB_OTG_PCGCCTL_OFFSET               0xE00
+#define USB_OTG_DATA_FIFO_OFFSET             0x1000
+#define USB_OTG_DATA_FIFO_SIZE               0x1000
+
+
+#define USB_OTG_MAX_TX_FIFOS                 15
+
+#define USB_OTG_HS_MAX_PACKET_SIZE           512
+#define USB_OTG_FS_MAX_PACKET_SIZE           64
+#define USB_OTG_MAX_EP0_SIZE                 64
+/**
+  * @}
+  */
+
+/** @defgroup USB_REGS_Exported_Types
+  * @{
+  */
+
+/** @defgroup __USB_OTG_Core_register
+  * @{
+  */
+typedef struct _USB_OTG_GREGS  //000h
+{
+  __IO uint32_t GOTGCTL;      /* USB_OTG Control and Status Register    000h*/
+  __IO uint32_t GOTGINT;      /* USB_OTG Interrupt Register             004h*/
+  __IO uint32_t GAHBCFG;      /* Core AHB Configuration Register    008h*/
+  __IO uint32_t GUSBCFG;      /* Core USB Configuration Register    00Ch*/
+  __IO uint32_t GRSTCTL;      /* Core Reset Register                010h*/
+  __IO uint32_t GINTSTS;      /* Core Interrupt Register            014h*/
+  __IO uint32_t GINTMSK;      /* Core Interrupt Mask Register       018h*/
+  __IO uint32_t GRXSTSR;      /* Receive Sts Q Read Register        01Ch*/
+  __IO uint32_t GRXSTSP;      /* Receive Sts Q Read & POP Register  020h*/
+  __IO uint32_t GRXFSIZ;      /* Receive FIFO Size Register         024h*/
+  __IO uint32_t DIEPTXF0_HNPTXFSIZ;   /* EP0 / Non Periodic Tx FIFO Size Register 028h*/
+  __IO uint32_t HNPTXSTS;     /* Non Periodic Tx FIFO/Queue Sts reg 02Ch*/
+  __IO uint32_t GI2CCTL;      /* I2C Access Register                030h*/
+  uint32_t Reserved34;  /* PHY Vendor Control Register        034h*/
+  __IO uint32_t GCCFG;        /* General Purpose IO Register        038h*/
+  __IO uint32_t CID;          /* User ID Register                   03Ch*/
+  uint32_t  Reserved40[48];   /* Reserved                      040h-0FFh*/
+  __IO uint32_t HPTXFSIZ; /* Host Periodic Tx FIFO Size Reg     100h*/
+  __IO uint32_t DIEPTXF[USB_OTG_MAX_TX_FIFOS];/* dev Periodic Transmit FIFO */
+}
+USB_OTG_GREGS;
+/**
+  * @}
+  */
+
+
+/** @defgroup __device_Registers
+  * @{
+  */
+typedef struct _USB_OTG_DREGS // 800h
+{
+  __IO uint32_t DCFG;         /* dev Configuration Register   800h*/
+  __IO uint32_t DCTL;         /* dev Control Register         804h*/
+  __IO uint32_t DSTS;         /* dev Status Register (RO)     808h*/
+  uint32_t Reserved0C;           /* Reserved                     80Ch*/
+  __IO uint32_t DIEPMSK;   /* dev IN Endpoint Mask         810h*/
+  __IO uint32_t DOEPMSK;  /* dev OUT Endpoint Mask        814h*/
+  __IO uint32_t DAINT;     /* dev All Endpoints Itr Reg    818h*/
+  __IO uint32_t DAINTMSK; /* dev All Endpoints Itr Mask   81Ch*/
+  uint32_t  Reserved20;          /* Reserved                     820h*/
+  uint32_t Reserved9;       /* Reserved                     824h*/
+  __IO uint32_t DVBUSDIS;    /* dev VBUS discharge Register  828h*/
+  __IO uint32_t DVBUSPULSE;  /* dev VBUS Pulse Register      82Ch*/
+  __IO uint32_t DTHRCTL;     /* dev thr                      830h*/
+  __IO uint32_t DIEPEMPMSK; /* dev empty msk             834h*/
+  __IO uint32_t DEACHINT;    /* dedicated EP interrupt       838h*/
+  __IO uint32_t DEACHMSK;    /* dedicated EP msk             83Ch*/
+  uint32_t Reserved40;      /* dedicated EP mask           840h*/
+  __IO uint32_t DINEP1MSK;  /* dedicated EP mask           844h*/
+  uint32_t  Reserved44[15];      /* Reserved                 844-87Ch*/
+  __IO uint32_t DOUTEP1MSK; /* dedicated EP msk            884h*/
+}
+USB_OTG_DREGS;
+/**
+  * @}
+  */
+
+
+/** @defgroup __IN_Endpoint-Specific_Register
+  * @{
+  */
+typedef struct _USB_OTG_INEPREGS
+{
+  __IO uint32_t DIEPCTL; /* dev IN Endpoint Control Reg 900h + (ep_num * 20h) + 00h*/
+  uint32_t Reserved04;             /* Reserved                       900h + (ep_num * 20h) + 04h*/
+  __IO uint32_t DIEPINT; /* dev IN Endpoint Itr Reg     900h + (ep_num * 20h) + 08h*/
+  uint32_t Reserved0C;             /* Reserved                       900h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t DIEPTSIZ; /* IN Endpoint Txfer Size   900h + (ep_num * 20h) + 10h*/
+  __IO uint32_t DIEPDMA; /* IN Endpoint DMA Address Reg    900h + (ep_num * 20h) + 14h*/
+  __IO uint32_t DTXFSTS;/*IN Endpoint Tx FIFO Status Reg 900h + (ep_num * 20h) + 18h*/
+  uint32_t Reserved18;             /* Reserved  900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_INEPREGS;
+/**
+  * @}
+  */
+
+
+/** @defgroup __OUT_Endpoint-Specific_Registers
+  * @{
+  */
+typedef struct _USB_OTG_OUTEPREGS
+{
+  __IO uint32_t DOEPCTL;       /* dev OUT Endpoint Control Reg  B00h + (ep_num * 20h) + 00h*/
+  __IO uint32_t DOUTEPFRM;   /* dev OUT Endpoint Frame number B00h + (ep_num * 20h) + 04h*/
+  __IO uint32_t DOEPINT;              /* dev OUT Endpoint Itr Reg      B00h + (ep_num * 20h) + 08h*/
+  uint32_t Reserved0C;                    /* Reserved                         B00h + (ep_num * 20h) + 0Ch*/
+  __IO uint32_t DOEPTSIZ; /* dev OUT Endpoint Txfer Size   B00h + (ep_num * 20h) + 10h*/
+  __IO uint32_t DOEPDMA;              /* dev OUT Endpoint DMA Address  B00h + (ep_num * 20h) + 14h*/
+  uint32_t Reserved18[2];                 /* Reserved B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/
+}
+USB_OTG_OUTEPREGS;
+/**
+  * @}
+  */
+
+
+/** @defgroup __Host_Mode_Register_Structures
+  * @{
+  */
+typedef struct _USB_OTG_HREGS
+{
+  __IO uint32_t HCFG;             /* Host Configuration Register    400h*/
+  __IO uint32_t HFIR;      /* Host Frame Interval Register   404h*/
+  __IO uint32_t HFNUM;         /* Host Frame Nbr/Frame Remaining 408h*/
+  uint32_t Reserved40C;                   /* Reserved                       40Ch*/
+  __IO uint32_t HPTXSTS;   /* Host Periodic Tx FIFO/ Queue Status 410h*/
+  __IO uint32_t HAINT;   /* Host All Channels Interrupt Register 414h*/
+  __IO uint32_t HAINTMSK;   /* Host All Channels Interrupt Mask 418h*/
+}
+USB_OTG_HREGS;
+/**
+  * @}
+  */
+
+
+/** @defgroup __Host_Channel_Specific_Registers
+  * @{
+  */
+typedef struct _USB_OTG_HC_REGS
+{
+  __IO uint32_t HCCHAR;
+  __IO uint32_t HCSPLT;
+  __IO uint32_t HCINT;
+  __IO uint32_t HCGINTMSK;
+  __IO uint32_t HCTSIZ;
+  __IO uint32_t HCDMA;
+  uint32_t Reserved[2];
+}
+USB_OTG_HC_REGS;
+/**
+  * @}
+  */
+
+
+/** @defgroup __otg_Core_registers
+  * @{
+  */
+typedef struct USB_OTG_core_regs //000h
+{
+  USB_OTG_GREGS         *GREGS;
+  USB_OTG_DREGS         *DREGS;
+  USB_OTG_HREGS         *HREGS;
+  USB_OTG_INEPREGS      *INEP_REGS[USB_OTG_MAX_TX_FIFOS];
+  USB_OTG_OUTEPREGS     *OUTEP_REGS[USB_OTG_MAX_TX_FIFOS];
+  USB_OTG_HC_REGS       *HC_REGS[USB_OTG_MAX_TX_FIFOS];
+  __IO uint32_t         *HPRT0;
+  __IO uint32_t         *DFIFO[USB_OTG_MAX_TX_FIFOS];
+  __IO uint32_t         *PCGCCTL;
+}
+USB_OTG_CORE_REGS , *PUSB_OTG_CORE_REGS;
+typedef union _USB_OTG_OTGCTL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t sesreqscs :
+    1;
+uint32_t sesreq :
+    1;
+uint32_t Reserved2_7 :
+    6;
+uint32_t hstnegscs :
+    1;
+uint32_t hnpreq :
+    1;
+uint32_t hstsethnpen :
+    1;
+uint32_t devhnpen :
+    1;
+uint32_t Reserved12_15 :
+    4;
+uint32_t conidsts :
+    1;
+uint32_t Reserved17 :
+    1;
+uint32_t asesvld :
+    1;
+uint32_t bsesvld :
+    1;
+uint32_t currmod :
+    1;
+uint32_t Reserved21_31 :
+    11;
+  }
+  b;
+} USB_OTG_OTGCTL_TypeDef ;
+typedef union _USB_OTG_GOTGINT_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t Reserved0_1 :
+    2;
+uint32_t sesenddet :
+    1;
+uint32_t Reserved3_7 :
+    5;
+uint32_t sesreqsucstschng :
+    1;
+uint32_t hstnegsucstschng :
+    1;
+uint32_t reserver10_16 :
+    7;
+uint32_t hstnegdet :
+    1;
+uint32_t adevtoutchng :
+    1;
+uint32_t debdone :
+    1;
+uint32_t Reserved31_20 :
+    12;
+  }
+  b;
+} USB_OTG_GOTGINT_TypeDef ;
+typedef union _USB_OTG_GAHBCFG_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t glblintrmsk :
+    1;
+uint32_t hburstlen :
+    4;
+uint32_t dmaenable :
+    1;
+uint32_t Reserved :
+    1;
+uint32_t nptxfemplvl_txfemplvl :
+    1;
+uint32_t ptxfemplvl :
+    1;
+uint32_t Reserved9_31 :
+    23;
+  }
+  b;
+} USB_OTG_GAHBCFG_TypeDef ;
+typedef union _USB_OTG_GUSBCFG_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t toutcal :
+    3;
+uint32_t phyif :
+    1;
+uint32_t ulpi_utmi_sel :
+    1;
+uint32_t fsintf :
+    1;
+uint32_t physel :
+    1;
+uint32_t ddrsel :
+    1;
+uint32_t srpcap :
+    1;
+uint32_t hnpcap :
+    1;
+uint32_t usbtrdtim :
+    4;
+uint32_t nptxfrwnden :
+    1;
+uint32_t phylpwrclksel :
+    1;
+uint32_t otgutmifssel :
+    1;
+uint32_t ulpi_fsls :
+    1;
+uint32_t ulpi_auto_res :
+    1;
+uint32_t ulpi_clk_sus_m :
+    1;
+uint32_t ulpi_ext_vbus_drv :
+    1;
+uint32_t ulpi_int_vbus_indicator :
+    1;
+uint32_t term_sel_dl_pulse :
+    1;
+uint32_t Reserved :
+    6;
+uint32_t force_host :
+    1;
+uint32_t force_dev :
+    1;
+uint32_t corrupt_tx :
+    1;
+  }
+  b;
+} USB_OTG_GUSBCFG_TypeDef ;
+typedef union _USB_OTG_GRSTCTL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t csftrst :
+    1;
+uint32_t hsftrst :
+    1;
+uint32_t hstfrm :
+    1;
+uint32_t intknqflsh :
+    1;
+uint32_t rxfflsh :
+    1;
+uint32_t txfflsh :
+    1;
+uint32_t txfnum :
+    5;
+uint32_t Reserved11_29 :
+    19;
+uint32_t dmareq :
+    1;
+uint32_t ahbidle :
+    1;
+  }
+  b;
+} USB_OTG_GRSTCTL_TypeDef ;
+typedef union _USB_OTG_GINTMSK_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t Reserved0 :
+    1;
+uint32_t modemismatch :
+    1;
+uint32_t otgintr :
+    1;
+uint32_t sofintr :
+    1;
+uint32_t rxstsqlvl :
+    1;
+uint32_t nptxfempty :
+    1;
+uint32_t ginnakeff :
+    1;
+uint32_t goutnakeff :
+    1;
+uint32_t Reserved8 :
+    1;
+uint32_t i2cintr :
+    1;
+uint32_t erlysuspend :
+    1;
+uint32_t usbsuspend :
+    1;
+uint32_t usbreset :
+    1;
+uint32_t enumdone :
+    1;
+uint32_t isooutdrop :
+    1;
+uint32_t eopframe :
+    1;
+uint32_t Reserved16 :
+    1;
+uint32_t epmismatch :
+    1;
+uint32_t inepintr :
+    1;
+uint32_t outepintr :
+    1;
+uint32_t incomplisoin :
+    1;
+uint32_t incomplisoout :
+    1;
+uint32_t Reserved22_23 :
+    2;
+uint32_t portintr :
+    1;
+uint32_t hcintr :
+    1;
+uint32_t ptxfempty :
+    1;
+uint32_t Reserved27 :
+    1;
+uint32_t conidstschng :
+    1;
+uint32_t disconnect :
+    1;
+uint32_t sessreqintr :
+    1;
+uint32_t wkupintr :
+    1;
+  }
+  b;
+} USB_OTG_GINTMSK_TypeDef ;
+typedef union _USB_OTG_GINTSTS_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t curmode :
+    1;
+uint32_t modemismatch :
+    1;
+uint32_t otgintr :
+    1;
+uint32_t sofintr :
+    1;
+uint32_t rxstsqlvl :
+    1;
+uint32_t nptxfempty :
+    1;
+uint32_t ginnakeff :
+    1;
+uint32_t goutnakeff :
+    1;
+uint32_t Reserved8 :
+    1;
+uint32_t i2cintr :
+    1;
+uint32_t erlysuspend :
+    1;
+uint32_t usbsuspend :
+    1;
+uint32_t usbreset :
+    1;
+uint32_t enumdone :
+    1;
+uint32_t isooutdrop :
+    1;
+uint32_t eopframe :
+    1;
+uint32_t intimerrx :
+    1;
+uint32_t epmismatch :
+    1;
+uint32_t inepint:
+    1;
+uint32_t outepintr :
+    1;
+uint32_t incomplisoin :
+    1;
+uint32_t incomplisoout :
+    1;
+uint32_t Reserved22_23 :
+    2;
+uint32_t portintr :
+    1;
+uint32_t hcintr :
+    1;
+uint32_t ptxfempty :
+    1;
+uint32_t Reserved27 :
+    1;
+uint32_t conidstschng :
+    1;
+uint32_t disconnect :
+    1;
+uint32_t sessreqintr :
+    1;
+uint32_t wkupintr :
+    1;
+  }
+  b;
+} USB_OTG_GINTSTS_TypeDef ;
+typedef union _USB_OTG_DRXSTS_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t epnum :
+    4;
+uint32_t bcnt :
+    11;
+uint32_t dpid :
+    2;
+uint32_t pktsts :
+    4;
+uint32_t fn :
+    4;
+uint32_t Reserved :
+    7;
+  }
+  b;
+} USB_OTG_DRXSTS_TypeDef ;
+typedef union _USB_OTG_GRXSTS_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t chnum :
+    4;
+uint32_t bcnt :
+    11;
+uint32_t dpid :
+    2;
+uint32_t pktsts :
+    4;
+uint32_t Reserved :
+    11;
+  }
+  b;
+} USB_OTG_GRXFSTS_TypeDef ;
+typedef union _USB_OTG_FSIZ_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t startaddr :
+    16;
+uint32_t depth :
+    16;
+  }
+  b;
+} USB_OTG_FSIZ_TypeDef ;
+typedef union _USB_OTG_HNPTXSTS_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t nptxfspcavail :
+    16;
+uint32_t nptxqspcavail :
+    8;
+uint32_t nptxqtop_terminate :
+    1;
+uint32_t nptxqtop_timer :
+    2;
+uint32_t nptxqtop :
+    2;
+uint32_t chnum :
+    2;
+uint32_t Reserved :
+    1;
+  }
+  b;
+} USB_OTG_HNPTXSTS_TypeDef ;
+typedef union _USB_OTG_DTXFSTSn_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t txfspcavail :
+    16;
+uint32_t Reserved :
+    16;
+  }
+  b;
+} USB_OTG_DTXFSTSn_TypeDef ;
+typedef union _USB_OTG_GI2CCTL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t rwdata :
+    8;
+uint32_t regaddr :
+    8;
+uint32_t addr :
+    7;
+uint32_t i2cen :
+    1;
+uint32_t ack :
+    1;
+uint32_t i2csuspctl :
+    1;
+uint32_t i2cdevaddr :
+    2;
+uint32_t dat_se0:
+    1;
+uint32_t Reserved :
+    1;
+uint32_t rw :
+    1;
+uint32_t bsydne :
+    1;
+  }
+  b;
+} USB_OTG_GI2CCTL_TypeDef ;
+typedef union _USB_OTG_GCCFG_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t Reserved_in :
+    16;
+uint32_t pwdn :
+    1;
+uint32_t i2cifen :
+    1;
+uint32_t vbussensingA :
+    1;
+uint32_t vbussensingB :
+    1;
+uint32_t sofouten :
+    1;
+uint32_t disablevbussensing :
+    1;
+uint32_t Reserved_out :
+    10;
+  }
+  b;
+} USB_OTG_GCCFG_TypeDef ;
+
+typedef union _USB_OTG_DCFG_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t devspd :
+    2;
+uint32_t nzstsouthshk :
+    1;
+uint32_t Reserved3 :
+    1;
+uint32_t devaddr :
+    7;
+uint32_t perfrint :
+    2;
+uint32_t Reserved13_17 :
+    5;
+uint32_t epmscnt :
+    4;
+  }
+  b;
+} USB_OTG_DCFG_TypeDef ;
+typedef union _USB_OTG_DCTL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t rmtwkupsig :
+    1;
+uint32_t sftdiscon :
+    1;
+uint32_t gnpinnaksts :
+    1;
+uint32_t goutnaksts :
+    1;
+uint32_t tstctl :
+    3;
+uint32_t sgnpinnak :
+    1;
+uint32_t cgnpinnak :
+    1;
+uint32_t sgoutnak :
+    1;
+uint32_t cgoutnak :
+    1;
+uint32_t Reserved :
+    21;
+  }
+  b;
+} USB_OTG_DCTL_TypeDef ;
+typedef union _USB_OTG_DSTS_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t suspsts :
+    1;
+uint32_t enumspd :
+    2;
+uint32_t errticerr :
+    1;
+uint32_t Reserved4_7:
+    4;
+uint32_t soffn :
+    14;
+uint32_t Reserved22_31 :
+    10;
+  }
+  b;
+} USB_OTG_DSTS_TypeDef ;
+typedef union _USB_OTG_DIEPINTn_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercompl :
+    1;
+uint32_t epdisabled :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t timeout :
+    1;
+uint32_t intktxfemp :
+    1;
+uint32_t intknepmis :
+    1;
+uint32_t inepnakeff :
+    1;
+uint32_t emptyintr :
+    1;
+uint32_t txfifoundrn :
+    1;
+uint32_t Reserved08_31 :
+    23;
+  }
+  b;
+} USB_OTG_DIEPINTn_TypeDef ;
+typedef union _USB_OTG_DIEPINTn_TypeDef   USB_OTG_DIEPMSK_TypeDef ;
+typedef union _USB_OTG_DOEPINTn_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercompl :
+    1;
+uint32_t epdisabled :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t setup :
+    1;
+uint32_t Reserved04_31 :
+    28;
+  }
+  b;
+} USB_OTG_DOEPINTn_TypeDef ;
+typedef union _USB_OTG_DOEPINTn_TypeDef   USB_OTG_DOEPMSK_TypeDef ;
+
+typedef union _USB_OTG_DAINT_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t in :
+    16;
+uint32_t out :
+    16;
+  }
+  ep;
+} USB_OTG_DAINT_TypeDef ;
+
+typedef union _USB_OTG_DTHRCTL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t non_iso_thr_en :
+    1;
+uint32_t iso_thr_en :
+    1;
+uint32_t tx_thr_len :
+    9;
+uint32_t Reserved11_15 :
+    5;
+uint32_t rx_thr_en :
+    1;
+uint32_t rx_thr_len :
+    9;
+uint32_t Reserved26_31 :
+    6;
+  }
+  b;
+} USB_OTG_DTHRCTL_TypeDef ;
+typedef union _USB_OTG_DEPCTL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t mps :
+    11;
+uint32_t reserved :
+    4;
+uint32_t usbactep :
+    1;
+uint32_t dpid :
+    1;
+uint32_t naksts :
+    1;
+uint32_t eptype :
+    2;
+uint32_t snp :
+    1;
+uint32_t stall :
+    1;
+uint32_t txfnum :
+    4;
+uint32_t cnak :
+    1;
+uint32_t snak :
+    1;
+uint32_t setd0pid :
+    1;
+uint32_t setd1pid :
+    1;
+uint32_t epdis :
+    1;
+uint32_t epena :
+    1;
+  }
+  b;
+} USB_OTG_DEPCTL_TypeDef ;
+typedef union _USB_OTG_DEPXFRSIZ_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfersize :
+    19;
+uint32_t pktcnt :
+    10;
+uint32_t mc :
+    2;
+uint32_t Reserved :
+    1;
+  }
+  b;
+} USB_OTG_DEPXFRSIZ_TypeDef ;
+typedef union _USB_OTG_DEP0XFRSIZ_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfersize :
+    7;
+uint32_t Reserved7_18 :
+    12;
+uint32_t pktcnt :
+    2;
+uint32_t Reserved20_28 :
+    9;
+uint32_t supcnt :
+    2;
+    uint32_t Reserved31;
+  }
+  b;
+} USB_OTG_DEP0XFRSIZ_TypeDef ;
+typedef union _USB_OTG_HCFG_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t fslspclksel :
+    2;
+uint32_t fslssupp :
+    1;
+  }
+  b;
+} USB_OTG_HCFG_TypeDef ;
+typedef union _USB_OTG_HFRMINTRVL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t frint :
+    16;
+uint32_t Reserved :
+    16;
+  }
+  b;
+} USB_OTG_HFRMINTRVL_TypeDef ;
+
+typedef union _USB_OTG_HFNUM_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t frnum :
+    16;
+uint32_t frrem :
+    16;
+  }
+  b;
+} USB_OTG_HFNUM_TypeDef ;
+typedef union _USB_OTG_HPTXSTS_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t ptxfspcavail :
+    16;
+uint32_t ptxqspcavail :
+    8;
+uint32_t ptxqtop_terminate :
+    1;
+uint32_t ptxqtop_timer :
+    2;
+uint32_t ptxqtop :
+    2;
+uint32_t chnum :
+    2;
+uint32_t ptxqtop_odd :
+    1;
+  }
+  b;
+} USB_OTG_HPTXSTS_TypeDef ;
+typedef union _USB_OTG_HPRT0_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t prtconnsts :
+    1;
+uint32_t prtconndet :
+    1;
+uint32_t prtena :
+    1;
+uint32_t prtenchng :
+    1;
+uint32_t prtovrcurract :
+    1;
+uint32_t prtovrcurrchng :
+    1;
+uint32_t prtres :
+    1;
+uint32_t prtsusp :
+    1;
+uint32_t prtrst :
+    1;
+uint32_t Reserved9 :
+    1;
+uint32_t prtlnsts :
+    2;
+uint32_t prtpwr :
+    1;
+uint32_t prttstctl :
+    4;
+uint32_t prtspd :
+    2;
+uint32_t Reserved19_31 :
+    13;
+  }
+  b;
+} USB_OTG_HPRT0_TypeDef ;
+typedef union _USB_OTG_HAINT_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t chint :
+    16;
+uint32_t Reserved :
+    16;
+  }
+  b;
+} USB_OTG_HAINT_TypeDef ;
+typedef union _USB_OTG_HAINTMSK_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t chint :
+    16;
+uint32_t Reserved :
+    16;
+  }
+  b;
+} USB_OTG_HAINTMSK_TypeDef ;
+typedef union _USB_OTG_HCCHAR_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t mps :
+    11;
+uint32_t epnum :
+    4;
+uint32_t epdir :
+    1;
+uint32_t Reserved :
+    1;
+uint32_t lspddev :
+    1;
+uint32_t eptype :
+    2;
+uint32_t multicnt :
+    2;
+uint32_t devaddr :
+    7;
+uint32_t oddfrm :
+    1;
+uint32_t chdis :
+    1;
+uint32_t chen :
+    1;
+  }
+  b;
+} USB_OTG_HCCHAR_TypeDef ;
+typedef union _USB_OTG_HCSPLT_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t prtaddr :
+    7;
+uint32_t hubaddr :
+    7;
+uint32_t xactpos :
+    2;
+uint32_t compsplt :
+    1;
+uint32_t Reserved :
+    14;
+uint32_t spltena :
+    1;
+  }
+  b;
+} USB_OTG_HCSPLT_TypeDef ;
+typedef union _USB_OTG_HCINTn_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercompl :
+    1;
+uint32_t chhltd :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t stall :
+    1;
+uint32_t nak :
+    1;
+uint32_t ack :
+    1;
+uint32_t nyet :
+    1;
+uint32_t xacterr :
+    1;
+uint32_t bblerr :
+    1;
+uint32_t frmovrun :
+    1;
+uint32_t datatglerr :
+    1;
+uint32_t Reserved :
+    21;
+  }
+  b;
+} USB_OTG_HCINTn_TypeDef ;
+typedef union _USB_OTG_HCTSIZn_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfersize :
+    19;
+uint32_t pktcnt :
+    10;
+uint32_t pid :
+    2;
+uint32_t dopng :
+    1;
+  }
+  b;
+} USB_OTG_HCTSIZn_TypeDef ;
+typedef union _USB_OTG_HCGINTMSK_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t xfercompl :
+    1;
+uint32_t chhltd :
+    1;
+uint32_t ahberr :
+    1;
+uint32_t stall :
+    1;
+uint32_t nak :
+    1;
+uint32_t ack :
+    1;
+uint32_t nyet :
+    1;
+uint32_t xacterr :
+    1;
+uint32_t bblerr :
+    1;
+uint32_t frmovrun :
+    1;
+uint32_t datatglerr :
+    1;
+uint32_t Reserved :
+    21;
+  }
+  b;
+} USB_OTG_HCGINTMSK_TypeDef ;
+typedef union _USB_OTG_PCGCCTL_TypeDef
+{
+  uint32_t d32;
+  struct
+  {
+uint32_t stoppclk :
+    1;
+uint32_t gatehclk :
+    1;
+uint32_t Reserved :
+    30;
+  }
+  b;
+} USB_OTG_PCGCCTL_TypeDef ;
+
+/**
+  * @}
+  */
+
+
+/** @defgroup USB_REGS_Exported_Macros
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_REGS_Exported_Variables
+  * @{
+  */
+/**
+  * @}
+  */
+
+/** @defgroup USB_REGS_Exported_FunctionsPrototype
+  * @{
+  */
+/**
+  * @}
+  */
+
+
+#endif //__USB_OTG_REGS_H__
+
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
+
diff --git a/codec2/branches/0.7/unittest/CMakeLists.txt b/codec2/branches/0.7/unittest/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a4b06b9
--- /dev/null
@@ -0,0 +1,97 @@
+add_definitions(-DFLOATING_POINT -DVAR_ARRAYS)
+include_directories(../src)
+
+add_executable(genres genres.c ../src/lpc.c)
+target_link_libraries(genres codec2)
+
+add_executable(genlsp genlsp.c ../src/lpc.c ../src/lsp.c)
+target_link_libraries(genlsp codec2)
+
+add_executable(extract extract.c)
+target_link_libraries(extract codec2)
+
+add_executable(vqtrain vqtrain.c)
+target_link_libraries(vqtrain codec2)
+
+add_executable(polar2rect polar2rect.c)
+target_link_libraries(polar2rect codec2)
+
+add_executable(vq_train_jvm vq_train_jvm.c)
+target_link_libraries(vq_train_jvm codec2)
+
+set(CODEBOOKS ../src/codebook.c ../src/codebookd.c ../src/codebookvq.c ../src/codebookdt.c ../src/codebookjvm.c  ../src/codebookge.c)
+
+add_executable(tnlp tnlp.c ../src/sine.c ../src/nlp.c ../src/kiss_fft.c ../src/dump.c)
+target_link_libraries(tnlp codec2)
+
+add_executable(scalarlsptest scalarlsptest.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c ${CODEBOOKS})
+target_link_libraries(scalarlsptest codec2)
+
+add_executable(tfdmdv tfdmdv.c ../src/fdmdv.c ../src/kiss_fft.c ../src/octave.c)
+target_link_libraries(tfdmdv codec2)
+
+add_executable(tcohpsk tcohpsk.c ../src/cohpsk.c ../src/octave.c)
+target_link_libraries(tcohpsk codec2)
+
+add_executable(test_cohpsk_ch test_cohpsk_ch.c ../src/cohpsk.c ../src/octave.c)
+target_link_libraries(test_cohpsk_ch codec2)
+
+add_executable(t16_8 t16_8.c ../src/fdmdv.c ../src/kiss_fft.c)
+target_link_libraries(t16_8 codec2)
+
+add_executable(t16_8_short t16_8_short.c ../src/fdmdv.c ../src/kiss_fft.c)
+target_link_libraries(t16_8_short codec2)
+
+add_executable(tfsk tfsk.c ../src/kiss_fft.c ../src/kiss_fftr.c ../src/octave.c ../src/modem_probe.c)
+target_link_libraries(tfsk m)
+
+add_executable(tfmfsk tfmfsk.c ../src/octave.c ../src/modem_probe.c)
+target_link_libraries(tfmfsk m)
+
+add_executable(tdeframer tdeframer.c)
+target_link_libraries(tdeframer m codec2)
+
+add_executable(tofdm tofdm.c ../src/ofdm.c ../src/octave.c)
+target_link_libraries(tofdm m)
+
+add_executable(tfreedv_data_channel tfreedv_data_channel.c)
+target_link_libraries(tfreedv_data_channel codec2)
+
+add_executable(create_interleaver create_interleaver.c)
+target_link_libraries(create_interleaver codec2)
+
+add_executable(tprede tprede.c ../src/lpc.c)
+target_link_libraries(tprede codec2)
+
+add_executable(pre pre.c ../src/lpc.c)
+target_link_libraries(pre codec2)
+
+add_executable(de de.c ../src/lpc.c)
+target_link_libraries(de codec2)
+
+add_executable(tfifo tfifo.c ../src/fifo.c)
+target_link_libraries(tfifo codec2 ${CMAKE_THREAD_LIBS_INIT})
+
+add_executable(speexnoisesup speexnoisesup.c)
+target_link_libraries(speexnoisesup ${SPEEXDSP_LIBRARY})
+set_target_properties(speexnoisesup
+    PROPERTIES INCLUDE_DIRECTORIES ${SPEEXDSP_INCLUDE_DIR}
+)
+
+add_executable(fdmdv_mem fdmdv_mem.c)
+
+add_executable(raw2h raw2h.c)
+target_link_libraries(raw2h codec2)
+
+add_definitions(-D__UNITTEST__)
+add_executable(c2validate c2validate.c)
+target_link_libraries(c2validate codec2)
+
+add_executable(tnewamp1 tnewamp1.c ../src/quantise.c ../src/newamp1.c ../src/mbest.c ../src/kiss_fft.c ../src/sine.c ../src/nlp.c ../src/dump.c ../src/octave.c ${CODEBOOKS})
+target_link_libraries(tnewamp1 codec2)
+
+add_executable(tsrc tsrc.c)
+target_link_libraries(tsrc samplerate)
+
+add_executable(tlininterp tlininterp.c)
+add_executable(tdec tdec.c)
diff --git a/codec2/branches/0.7/unittest/Makefile.am b/codec2/branches/0.7/unittest/Makefile.am
new file mode 100644 (file)
index 0000000..998446f
--- /dev/null
@@ -0,0 +1,114 @@
+AM_CFLAGS = -I../src -fPIC -g  -DFLOATING_POINT -DVAR_ARRAYS -O2 -Wall
+AUTOMAKE_OPTS = gnu
+NAME = libcodec2
+AM_CPPFLAGS = $(AM_CFLAGS)
+
+noinst_PROGRAMS = genres genlsp extract vqtrain vqtrainjnd tnlp tinterp tquant vq_train_jvm scalarlsptest tfdmdv t48_8 lspsync create_interleaver tlspsens vqtrainph genphdata genampdata polar2rect vqtrainsp tprede pre de tfifo raw2h c2validate
+
+genres_SOURCES = genres.c ../src/lpc.c
+genres_LDADD = $(lib_LTLIBRARIES) 
+genres_LDFLAGS = $(LIBS)
+
+genlsp_SOURCES = genlsp.c ../src/lpc.c ../src/lsp.c
+genlsp_LDADD = $(lib_LTLIBRARIES) 
+genlsp_LDFLAGS = $(LIBS)
+
+extract_SOURCES = extract.c
+extract_LDADD = $(lib_LTLIBRARIES) 
+extract_LDFLAGS = $(LIBS) 
+
+vqtrain_SOURCES = vqtrain.c
+vqtrain_LDADD = $(lib_LTLIBRARIES) 
+vqtrain_LDFLAGS = $(LIBS)
+
+vqtrainjnd_SOURCES = vqtrainjnd.c
+vqtrainjnd_LDADD = $(lib_LTLIBRARIES) 
+vqtrainjnd_LDFLAGS = $(LIBS)
+
+vqtrainph_SOURCES = vqtrainph.c
+vqtrainph_LDADD = $(lib_LTLIBRARIES) 
+vqtrainph_LDFLAGS = $(LIBS)
+
+vqtrainsp_SOURCES = vqtrainsp.c
+vqtrainsp_LDADD = $(lib_LTLIBRARIES) 
+vqtrainsp_LDFLAGS = $(LIBS)
+
+genphdata_SOURCES = genphdata.c
+genphdata_LDADD = $(lib_LTLIBRARIES) 
+genphdata_LDFLAGS = $(LIBS)
+
+genampdata_SOURCES = genampdata.c
+genampdata_LDADD = $(lib_LTLIBRARIES) 
+genampdata_LDFLAGS = $(LIBS)
+
+polar2rect_SOURCES = polar2rect.c
+polar2rect_LDADD = $(lib_LTLIBRARIES) 
+polar2rect_LDFLAGS = $(LIBS)
+
+vq_train_jvm_SOURCES = vq_train_jvm.c
+vq_train_jvm_LDADD = $(lib_LTLIBRARIES) 
+vq_train_jvm_LDFLAGS = $(LIBS)
+
+CODEBOOKS = ../src/codebook.c ../src/codebookd.c ../src/codebookvq.c ../src/codebookjnd.c ../src/codebookdt.c ../src/codebookjvm.c ../src/codebookvqanssi.c ../src/codebookge.c
+
+tnlp_SOURCES = tnlp.c ../src/sine.c ../src/nlp.c ../src/kiss_fft.c ../src/dump.c
+tnlp_LDADD = $(lib_LTLIBRARIES) 
+tnlp_LDFLAGS = $(LIBS)
+
+tinterp_SOURCES = tinterp.c ../src/sine.c ../src/kiss_fft.c ../src/interp.c ../src/lpc.c ../src/lsp.c ../src/quantise.c $(CODEBOOKS) ../src/dump.c
+tinterp_LDADD = $(lib_LTLIBRARIES) 
+tinterp_LDFLAGS = $(LIBS)
+
+tquant_SOURCES = tquant.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c $(CODEBOOKS)
+tquant_LDADD = $(lib_LTLIBRARIES) 
+tquant_LDFLAGS = $(LIBS)
+
+scalarlsptest_SOURCES = scalarlsptest.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c $(CODEBOOKS)
+scalarlsptest_LDADD = $(lib_LTLIBRARIES) 
+scalarlsptest_LDFLAGS = $(LIBS)
+
+tfdmdv_SOURCES = tfdmdv.c ../src/fdmdv.c ../src/kiss_fft.c ../src/octave.c
+tfdmdv_LDADD = $(lib_LTLIBRARIES) 
+tfdmdv_LDFLAGS = $(LIBS)
+
+t48_8_SOURCES = t48_8.c ../src/fdmdv.c ../src/kiss_fft.c
+t48_8_LDADD = $(lib_LTLIBRARIES) 
+t48_8_LDFLAGS = $(LIBS)
+
+lspsync_SOURCES = lspsync.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c \
+../src/codec2.c ../src/sine.c ../src/nlp.c ../src/postfilter.c ../src/phase.c ../src/interp.c ../src/pack.c $(CODEBOOKS)
+lspsync_LDADD = $(lib_LTLIBRARIES) 
+lspsync_LDFLAGS = $(LIBS)
+
+create_interleaver_SOURCES = create_interleaver.c 
+create_interleaver_LDADD = $(lib_LTLIBRARIES) 
+create_interleaver_LDFLAGS = $(LIBS)
+
+tlspsens_SOURCES = tlspsens.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c ../src/codec2.c ../src/sine.c ../src/nlp.c ../src/pack.c ../src/interp.c ../src/postfilter.c ../src/phase.c $(CODEBOOKS)
+tlspsens_LDADD = $(lib_LTLIBRARIES) 
+tlspsens_LDFLAGS = $(LIBS)
+
+tprede_SOURCES = tprede.c ../src/lpc.c 
+tprede_LDADD = $(lib_LTLIBRARIES) 
+tprede_LDFLAGS = $(LIBS)
+
+pre_SOURCES = pre.c ../src/lpc.c 
+pre_LDADD = $(lib_LTLIBRARIES) 
+pre_LDFLAGS = $(LIBS)
+
+de_SOURCES = de.c ../src/lpc.c 
+de_LDADD = $(lib_LTLIBRARIES) 
+de_LDFLAGS = $(LIBS)
+
+tfifo_SOURCES = tfifo.c ../src/fifo.c
+tfifo_LDADD = $(lib_LTLIBRARIES) -lpthread
+tfifo_LDFLAGS = $(LIBS)
+
+raw2h_SOURCES = raw2h.c
+raw2h_LDADD = $(lib_LTLIBRARIES)
+raw2h_LDFLAGS = $(LIBS)
+
+c2validate_CFLAGS = -D__UNITTEST__
+c2validate_SOURCES = c2validate.c
+c2validate_LDADD = $(lib_LTLIBRARIES) ../src/libcodec2.la
+c2validate_LDFLAGS = $(LIBS) 
\ No newline at end of file
diff --git a/codec2/branches/0.7/unittest/Makefile.in b/codec2/branches/0.7/unittest/Makefile.in
new file mode 100644 (file)
index 0000000..aac2791
--- /dev/null
@@ -0,0 +1,1090 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005  Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = genres$(EXEEXT) genlsp$(EXEEXT) extract$(EXEEXT) \
+       vqtrain$(EXEEXT) vqtrainjnd$(EXEEXT) tnlp$(EXEEXT) \
+       tinterp$(EXEEXT) tquant$(EXEEXT) vq_train_jvm$(EXEEXT) \
+       scalarlsptest$(EXEEXT) tfdmdv$(EXEEXT) t48_8$(EXEEXT) \
+       lspsync$(EXEEXT) create_interleaver$(EXEEXT) tlspsens$(EXEEXT) \
+       vqtrainph$(EXEEXT) genphdata$(EXEEXT) genampdata$(EXEEXT) \
+       polar2rect$(EXEEXT) vqtrainsp$(EXEEXT) tprede$(EXEEXT) \
+       pre$(EXEEXT) de$(EXEEXT) tfifo$(EXEEXT) raw2h$(EXEEXT) \
+       c2validate$(EXEEXT)
+subdir = unittest
+DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+       $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_c2validate_OBJECTS = c2validate-c2validate.$(OBJEXT)
+c2validate_OBJECTS = $(am_c2validate_OBJECTS)
+c2validate_DEPENDENCIES = ../src/libcodec2.la
+am_create_interleaver_OBJECTS = create_interleaver.$(OBJEXT)
+create_interleaver_OBJECTS = $(am_create_interleaver_OBJECTS)
+create_interleaver_DEPENDENCIES =
+am_de_OBJECTS = de.$(OBJEXT) lpc.$(OBJEXT)
+de_OBJECTS = $(am_de_OBJECTS)
+de_DEPENDENCIES =
+am_extract_OBJECTS = extract.$(OBJEXT)
+extract_OBJECTS = $(am_extract_OBJECTS)
+extract_DEPENDENCIES =
+am_genampdata_OBJECTS = genampdata.$(OBJEXT)
+genampdata_OBJECTS = $(am_genampdata_OBJECTS)
+genampdata_DEPENDENCIES =
+am_genlsp_OBJECTS = genlsp.$(OBJEXT) lpc.$(OBJEXT) lsp.$(OBJEXT)
+genlsp_OBJECTS = $(am_genlsp_OBJECTS)
+genlsp_DEPENDENCIES =
+am_genphdata_OBJECTS = genphdata.$(OBJEXT)
+genphdata_OBJECTS = $(am_genphdata_OBJECTS)
+genphdata_DEPENDENCIES =
+am_genres_OBJECTS = genres.$(OBJEXT) lpc.$(OBJEXT)
+genres_OBJECTS = $(am_genres_OBJECTS)
+genres_DEPENDENCIES =
+am__objects_1 = codebook.$(OBJEXT) codebookd.$(OBJEXT) \
+       codebookvq.$(OBJEXT) codebookjnd.$(OBJEXT) \
+       codebookdt.$(OBJEXT) codebookjvm.$(OBJEXT) \
+       codebookvqanssi.$(OBJEXT) codebookge.$(OBJEXT)
+am_lspsync_OBJECTS = lspsync.$(OBJEXT) quantise.$(OBJEXT) \
+       lpc.$(OBJEXT) lsp.$(OBJEXT) dump.$(OBJEXT) kiss_fft.$(OBJEXT) \
+       codec2.$(OBJEXT) sine.$(OBJEXT) nlp.$(OBJEXT) \
+       postfilter.$(OBJEXT) phase.$(OBJEXT) interp.$(OBJEXT) \
+       pack.$(OBJEXT) $(am__objects_1)
+lspsync_OBJECTS = $(am_lspsync_OBJECTS)
+lspsync_DEPENDENCIES =
+am_polar2rect_OBJECTS = polar2rect.$(OBJEXT)
+polar2rect_OBJECTS = $(am_polar2rect_OBJECTS)
+polar2rect_DEPENDENCIES =
+am_pre_OBJECTS = pre.$(OBJEXT) lpc.$(OBJEXT)
+pre_OBJECTS = $(am_pre_OBJECTS)
+pre_DEPENDENCIES =
+am_raw2h_OBJECTS = raw2h.$(OBJEXT)
+raw2h_OBJECTS = $(am_raw2h_OBJECTS)
+raw2h_DEPENDENCIES =
+am_scalarlsptest_OBJECTS = scalarlsptest.$(OBJEXT) quantise.$(OBJEXT) \
+       lpc.$(OBJEXT) lsp.$(OBJEXT) dump.$(OBJEXT) kiss_fft.$(OBJEXT) \
+       $(am__objects_1)
+scalarlsptest_OBJECTS = $(am_scalarlsptest_OBJECTS)
+scalarlsptest_DEPENDENCIES =
+am_t48_8_OBJECTS = t48_8.$(OBJEXT) fdmdv.$(OBJEXT) kiss_fft.$(OBJEXT)
+t48_8_OBJECTS = $(am_t48_8_OBJECTS)
+t48_8_DEPENDENCIES =
+am_tfdmdv_OBJECTS = tfdmdv.$(OBJEXT) fdmdv.$(OBJEXT) \
+       kiss_fft.$(OBJEXT) octave.$(OBJEXT)
+tfdmdv_OBJECTS = $(am_tfdmdv_OBJECTS)
+tfdmdv_DEPENDENCIES =
+am_tfifo_OBJECTS = tfifo.$(OBJEXT) fifo.$(OBJEXT)
+tfifo_OBJECTS = $(am_tfifo_OBJECTS)
+tfifo_DEPENDENCIES =
+am_tinterp_OBJECTS = tinterp.$(OBJEXT) sine.$(OBJEXT) \
+       kiss_fft.$(OBJEXT) interp.$(OBJEXT) lpc.$(OBJEXT) \
+       lsp.$(OBJEXT) quantise.$(OBJEXT) $(am__objects_1) \
+       dump.$(OBJEXT)
+tinterp_OBJECTS = $(am_tinterp_OBJECTS)
+tinterp_DEPENDENCIES =
+am_tlspsens_OBJECTS = tlspsens.$(OBJEXT) quantise.$(OBJEXT) \
+       lpc.$(OBJEXT) lsp.$(OBJEXT) dump.$(OBJEXT) kiss_fft.$(OBJEXT) \
+       codec2.$(OBJEXT) sine.$(OBJEXT) nlp.$(OBJEXT) pack.$(OBJEXT) \
+       interp.$(OBJEXT) postfilter.$(OBJEXT) phase.$(OBJEXT) \
+       $(am__objects_1)
+tlspsens_OBJECTS = $(am_tlspsens_OBJECTS)
+tlspsens_DEPENDENCIES =
+am_tnlp_OBJECTS = tnlp.$(OBJEXT) sine.$(OBJEXT) nlp.$(OBJEXT) \
+       kiss_fft.$(OBJEXT) dump.$(OBJEXT)
+tnlp_OBJECTS = $(am_tnlp_OBJECTS)
+tnlp_DEPENDENCIES =
+am_tprede_OBJECTS = tprede.$(OBJEXT) lpc.$(OBJEXT)
+tprede_OBJECTS = $(am_tprede_OBJECTS)
+tprede_DEPENDENCIES =
+am_tquant_OBJECTS = tquant.$(OBJEXT) quantise.$(OBJEXT) lpc.$(OBJEXT) \
+       lsp.$(OBJEXT) dump.$(OBJEXT) kiss_fft.$(OBJEXT) \
+       $(am__objects_1)
+tquant_OBJECTS = $(am_tquant_OBJECTS)
+tquant_DEPENDENCIES =
+am_vq_train_jvm_OBJECTS = vq_train_jvm.$(OBJEXT)
+vq_train_jvm_OBJECTS = $(am_vq_train_jvm_OBJECTS)
+vq_train_jvm_DEPENDENCIES =
+am_vqtrain_OBJECTS = vqtrain.$(OBJEXT)
+vqtrain_OBJECTS = $(am_vqtrain_OBJECTS)
+vqtrain_DEPENDENCIES =
+am_vqtrainjnd_OBJECTS = vqtrainjnd.$(OBJEXT)
+vqtrainjnd_OBJECTS = $(am_vqtrainjnd_OBJECTS)
+vqtrainjnd_DEPENDENCIES =
+am_vqtrainph_OBJECTS = vqtrainph.$(OBJEXT)
+vqtrainph_OBJECTS = $(am_vqtrainph_OBJECTS)
+vqtrainph_DEPENDENCIES =
+am_vqtrainsp_OBJECTS = vqtrainsp.$(OBJEXT)
+vqtrainsp_OBJECTS = $(am_vqtrainsp_OBJECTS)
+vqtrainsp_DEPENDENCIES =
+DEFAULT_INCLUDES = -I. -I$(srcdir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+       $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+       $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(c2validate_SOURCES) $(create_interleaver_SOURCES) \
+       $(de_SOURCES) $(extract_SOURCES) $(genampdata_SOURCES) \
+       $(genlsp_SOURCES) $(genphdata_SOURCES) $(genres_SOURCES) \
+       $(lspsync_SOURCES) $(polar2rect_SOURCES) $(pre_SOURCES) \
+       $(raw2h_SOURCES) $(scalarlsptest_SOURCES) $(t48_8_SOURCES) \
+       $(tfdmdv_SOURCES) $(tfifo_SOURCES) $(tinterp_SOURCES) \
+       $(tlspsens_SOURCES) $(tnlp_SOURCES) $(tprede_SOURCES) \
+       $(tquant_SOURCES) $(vq_train_jvm_SOURCES) $(vqtrain_SOURCES) \
+       $(vqtrainjnd_SOURCES) $(vqtrainph_SOURCES) \
+       $(vqtrainsp_SOURCES)
+DIST_SOURCES = $(c2validate_SOURCES) $(create_interleaver_SOURCES) \
+       $(de_SOURCES) $(extract_SOURCES) $(genampdata_SOURCES) \
+       $(genlsp_SOURCES) $(genphdata_SOURCES) $(genres_SOURCES) \
+       $(lspsync_SOURCES) $(polar2rect_SOURCES) $(pre_SOURCES) \
+       $(raw2h_SOURCES) $(scalarlsptest_SOURCES) $(t48_8_SOURCES) \
+       $(tfdmdv_SOURCES) $(tfifo_SOURCES) $(tinterp_SOURCES) \
+       $(tlspsens_SOURCES) $(tnlp_SOURCES) $(tprede_SOURCES) \
+       $(tquant_SOURCES) $(vq_train_jvm_SOURCES) $(vqtrain_SOURCES) \
+       $(vqtrainjnd_SOURCES) $(vqtrainph_SOURCES) \
+       $(vqtrainsp_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AM_CFLAGS = -I../src -fPIC -g  -DFLOATING_POINT -DVAR_ARRAYS -O2 -Wall
+AUTOMAKE_OPTS = gnu
+NAME = libcodec2
+AM_CPPFLAGS = $(AM_CFLAGS)
+genres_SOURCES = genres.c ../src/lpc.c
+genres_LDADD = $(lib_LTLIBRARIES) 
+genres_LDFLAGS = $(LIBS)
+genlsp_SOURCES = genlsp.c ../src/lpc.c ../src/lsp.c
+genlsp_LDADD = $(lib_LTLIBRARIES) 
+genlsp_LDFLAGS = $(LIBS)
+extract_SOURCES = extract.c
+extract_LDADD = $(lib_LTLIBRARIES) 
+extract_LDFLAGS = $(LIBS) 
+vqtrain_SOURCES = vqtrain.c
+vqtrain_LDADD = $(lib_LTLIBRARIES) 
+vqtrain_LDFLAGS = $(LIBS)
+vqtrainjnd_SOURCES = vqtrainjnd.c
+vqtrainjnd_LDADD = $(lib_LTLIBRARIES) 
+vqtrainjnd_LDFLAGS = $(LIBS)
+vqtrainph_SOURCES = vqtrainph.c
+vqtrainph_LDADD = $(lib_LTLIBRARIES) 
+vqtrainph_LDFLAGS = $(LIBS)
+vqtrainsp_SOURCES = vqtrainsp.c
+vqtrainsp_LDADD = $(lib_LTLIBRARIES) 
+vqtrainsp_LDFLAGS = $(LIBS)
+genphdata_SOURCES = genphdata.c
+genphdata_LDADD = $(lib_LTLIBRARIES) 
+genphdata_LDFLAGS = $(LIBS)
+genampdata_SOURCES = genampdata.c
+genampdata_LDADD = $(lib_LTLIBRARIES) 
+genampdata_LDFLAGS = $(LIBS)
+polar2rect_SOURCES = polar2rect.c
+polar2rect_LDADD = $(lib_LTLIBRARIES) 
+polar2rect_LDFLAGS = $(LIBS)
+vq_train_jvm_SOURCES = vq_train_jvm.c
+vq_train_jvm_LDADD = $(lib_LTLIBRARIES) 
+vq_train_jvm_LDFLAGS = $(LIBS)
+CODEBOOKS = ../src/codebook.c ../src/codebookd.c ../src/codebookvq.c ../src/codebookjnd.c ../src/codebookdt.c ../src/codebookjvm.c ../src/codebookvqanssi.c ../src/codebookge.c
+tnlp_SOURCES = tnlp.c ../src/sine.c ../src/nlp.c ../src/kiss_fft.c ../src/dump.c
+tnlp_LDADD = $(lib_LTLIBRARIES) 
+tnlp_LDFLAGS = $(LIBS)
+tinterp_SOURCES = tinterp.c ../src/sine.c ../src/kiss_fft.c ../src/interp.c ../src/lpc.c ../src/lsp.c ../src/quantise.c $(CODEBOOKS) ../src/dump.c
+tinterp_LDADD = $(lib_LTLIBRARIES) 
+tinterp_LDFLAGS = $(LIBS)
+tquant_SOURCES = tquant.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c $(CODEBOOKS)
+tquant_LDADD = $(lib_LTLIBRARIES) 
+tquant_LDFLAGS = $(LIBS)
+scalarlsptest_SOURCES = scalarlsptest.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c $(CODEBOOKS)
+scalarlsptest_LDADD = $(lib_LTLIBRARIES) 
+scalarlsptest_LDFLAGS = $(LIBS)
+tfdmdv_SOURCES = tfdmdv.c ../src/fdmdv.c ../src/kiss_fft.c ../src/octave.c
+tfdmdv_LDADD = $(lib_LTLIBRARIES) 
+tfdmdv_LDFLAGS = $(LIBS)
+t48_8_SOURCES = t48_8.c ../src/fdmdv.c ../src/kiss_fft.c
+t48_8_LDADD = $(lib_LTLIBRARIES) 
+t48_8_LDFLAGS = $(LIBS)
+lspsync_SOURCES = lspsync.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c \
+../src/codec2.c ../src/sine.c ../src/nlp.c ../src/postfilter.c ../src/phase.c ../src/interp.c ../src/pack.c $(CODEBOOKS)
+
+lspsync_LDADD = $(lib_LTLIBRARIES) 
+lspsync_LDFLAGS = $(LIBS)
+create_interleaver_SOURCES = create_interleaver.c 
+create_interleaver_LDADD = $(lib_LTLIBRARIES) 
+create_interleaver_LDFLAGS = $(LIBS)
+tlspsens_SOURCES = tlspsens.c ../src/quantise.c ../src/lpc.c ../src/lsp.c ../src/dump.c ../src/kiss_fft.c ../src/codec2.c ../src/sine.c ../src/nlp.c ../src/pack.c ../src/interp.c ../src/postfilter.c ../src/phase.c $(CODEBOOKS)
+tlspsens_LDADD = $(lib_LTLIBRARIES) 
+tlspsens_LDFLAGS = $(LIBS)
+tprede_SOURCES = tprede.c ../src/lpc.c 
+tprede_LDADD = $(lib_LTLIBRARIES) 
+tprede_LDFLAGS = $(LIBS)
+pre_SOURCES = pre.c ../src/lpc.c 
+pre_LDADD = $(lib_LTLIBRARIES) 
+pre_LDFLAGS = $(LIBS)
+de_SOURCES = de.c ../src/lpc.c 
+de_LDADD = $(lib_LTLIBRARIES) 
+de_LDFLAGS = $(LIBS)
+tfifo_SOURCES = tfifo.c ../src/fifo.c
+tfifo_LDADD = $(lib_LTLIBRARIES) -lpthread
+tfifo_LDFLAGS = $(LIBS)
+raw2h_SOURCES = raw2h.c
+raw2h_LDADD = $(lib_LTLIBRARIES)
+raw2h_LDFLAGS = $(LIBS)
+c2validate_CFLAGS = -D__UNITTEST__
+c2validate_SOURCES = c2validate.c
+c2validate_LDADD = $(lib_LTLIBRARIES) ../src/libcodec2.la
+c2validate_LDFLAGS = $(LIBS) 
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+       @for dep in $?; do \
+         case '$(am__configure_deps)' in \
+           *$$dep*) \
+             cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+               && exit 0; \
+             exit 1;; \
+         esac; \
+       done; \
+       echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  unittest/Makefile'; \
+       cd $(top_srcdir) && \
+         $(AUTOMAKE) --gnu  unittest/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+       @case '$?' in \
+         *config.status*) \
+           cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+         *) \
+           echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+           cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+       esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+       cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstPROGRAMS:
+       @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+         f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+         echo " rm -f $$p $$f"; \
+         rm -f $$p $$f ; \
+       done
+c2validate$(EXEEXT): $(c2validate_OBJECTS) $(c2validate_DEPENDENCIES) 
+       @rm -f c2validate$(EXEEXT)
+       $(LINK) $(c2validate_LDFLAGS) $(c2validate_OBJECTS) $(c2validate_LDADD) $(LIBS)
+create_interleaver$(EXEEXT): $(create_interleaver_OBJECTS) $(create_interleaver_DEPENDENCIES) 
+       @rm -f create_interleaver$(EXEEXT)
+       $(LINK) $(create_interleaver_LDFLAGS) $(create_interleaver_OBJECTS) $(create_interleaver_LDADD) $(LIBS)
+de$(EXEEXT): $(de_OBJECTS) $(de_DEPENDENCIES) 
+       @rm -f de$(EXEEXT)
+       $(LINK) $(de_LDFLAGS) $(de_OBJECTS) $(de_LDADD) $(LIBS)
+extract$(EXEEXT): $(extract_OBJECTS) $(extract_DEPENDENCIES) 
+       @rm -f extract$(EXEEXT)
+       $(LINK) $(extract_LDFLAGS) $(extract_OBJECTS) $(extract_LDADD) $(LIBS)
+genampdata$(EXEEXT): $(genampdata_OBJECTS) $(genampdata_DEPENDENCIES) 
+       @rm -f genampdata$(EXEEXT)
+       $(LINK) $(genampdata_LDFLAGS) $(genampdata_OBJECTS) $(genampdata_LDADD) $(LIBS)
+genlsp$(EXEEXT): $(genlsp_OBJECTS) $(genlsp_DEPENDENCIES) 
+       @rm -f genlsp$(EXEEXT)
+       $(LINK) $(genlsp_LDFLAGS) $(genlsp_OBJECTS) $(genlsp_LDADD) $(LIBS)
+genphdata$(EXEEXT): $(genphdata_OBJECTS) $(genphdata_DEPENDENCIES) 
+       @rm -f genphdata$(EXEEXT)
+       $(LINK) $(genphdata_LDFLAGS) $(genphdata_OBJECTS) $(genphdata_LDADD) $(LIBS)
+genres$(EXEEXT): $(genres_OBJECTS) $(genres_DEPENDENCIES) 
+       @rm -f genres$(EXEEXT)
+       $(LINK) $(genres_LDFLAGS) $(genres_OBJECTS) $(genres_LDADD) $(LIBS)
+lspsync$(EXEEXT): $(lspsync_OBJECTS) $(lspsync_DEPENDENCIES) 
+       @rm -f lspsync$(EXEEXT)
+       $(LINK) $(lspsync_LDFLAGS) $(lspsync_OBJECTS) $(lspsync_LDADD) $(LIBS)
+polar2rect$(EXEEXT): $(polar2rect_OBJECTS) $(polar2rect_DEPENDENCIES) 
+       @rm -f polar2rect$(EXEEXT)
+       $(LINK) $(polar2rect_LDFLAGS) $(polar2rect_OBJECTS) $(polar2rect_LDADD) $(LIBS)
+pre$(EXEEXT): $(pre_OBJECTS) $(pre_DEPENDENCIES) 
+       @rm -f pre$(EXEEXT)
+       $(LINK) $(pre_LDFLAGS) $(pre_OBJECTS) $(pre_LDADD) $(LIBS)
+raw2h$(EXEEXT): $(raw2h_OBJECTS) $(raw2h_DEPENDENCIES) 
+       @rm -f raw2h$(EXEEXT)
+       $(LINK) $(raw2h_LDFLAGS) $(raw2h_OBJECTS) $(raw2h_LDADD) $(LIBS)
+scalarlsptest$(EXEEXT): $(scalarlsptest_OBJECTS) $(scalarlsptest_DEPENDENCIES) 
+       @rm -f scalarlsptest$(EXEEXT)
+       $(LINK) $(scalarlsptest_LDFLAGS) $(scalarlsptest_OBJECTS) $(scalarlsptest_LDADD) $(LIBS)
+t48_8$(EXEEXT): $(t48_8_OBJECTS) $(t48_8_DEPENDENCIES) 
+       @rm -f t48_8$(EXEEXT)
+       $(LINK) $(t48_8_LDFLAGS) $(t48_8_OBJECTS) $(t48_8_LDADD) $(LIBS)
+tfdmdv$(EXEEXT): $(tfdmdv_OBJECTS) $(tfdmdv_DEPENDENCIES) 
+       @rm -f tfdmdv$(EXEEXT)
+       $(LINK) $(tfdmdv_LDFLAGS) $(tfdmdv_OBJECTS) $(tfdmdv_LDADD) $(LIBS)
+tfifo$(EXEEXT): $(tfifo_OBJECTS) $(tfifo_DEPENDENCIES) 
+       @rm -f tfifo$(EXEEXT)
+       $(LINK) $(tfifo_LDFLAGS) $(tfifo_OBJECTS) $(tfifo_LDADD) $(LIBS)
+tinterp$(EXEEXT): $(tinterp_OBJECTS) $(tinterp_DEPENDENCIES) 
+       @rm -f tinterp$(EXEEXT)
+       $(LINK) $(tinterp_LDFLAGS) $(tinterp_OBJECTS) $(tinterp_LDADD) $(LIBS)
+tlspsens$(EXEEXT): $(tlspsens_OBJECTS) $(tlspsens_DEPENDENCIES) 
+       @rm -f tlspsens$(EXEEXT)
+       $(LINK) $(tlspsens_LDFLAGS) $(tlspsens_OBJECTS) $(tlspsens_LDADD) $(LIBS)
+tnlp$(EXEEXT): $(tnlp_OBJECTS) $(tnlp_DEPENDENCIES) 
+       @rm -f tnlp$(EXEEXT)
+       $(LINK) $(tnlp_LDFLAGS) $(tnlp_OBJECTS) $(tnlp_LDADD) $(LIBS)
+tprede$(EXEEXT): $(tprede_OBJECTS) $(tprede_DEPENDENCIES) 
+       @rm -f tprede$(EXEEXT)
+       $(LINK) $(tprede_LDFLAGS) $(tprede_OBJECTS) $(tprede_LDADD) $(LIBS)
+tquant$(EXEEXT): $(tquant_OBJECTS) $(tquant_DEPENDENCIES) 
+       @rm -f tquant$(EXEEXT)
+       $(LINK) $(tquant_LDFLAGS) $(tquant_OBJECTS) $(tquant_LDADD) $(LIBS)
+vq_train_jvm$(EXEEXT): $(vq_train_jvm_OBJECTS) $(vq_train_jvm_DEPENDENCIES) 
+       @rm -f vq_train_jvm$(EXEEXT)
+       $(LINK) $(vq_train_jvm_LDFLAGS) $(vq_train_jvm_OBJECTS) $(vq_train_jvm_LDADD) $(LIBS)
+vqtrain$(EXEEXT): $(vqtrain_OBJECTS) $(vqtrain_DEPENDENCIES) 
+       @rm -f vqtrain$(EXEEXT)
+       $(LINK) $(vqtrain_LDFLAGS) $(vqtrain_OBJECTS) $(vqtrain_LDADD) $(LIBS)
+vqtrainjnd$(EXEEXT): $(vqtrainjnd_OBJECTS) $(vqtrainjnd_DEPENDENCIES) 
+       @rm -f vqtrainjnd$(EXEEXT)
+       $(LINK) $(vqtrainjnd_LDFLAGS) $(vqtrainjnd_OBJECTS) $(vqtrainjnd_LDADD) $(LIBS)
+vqtrainph$(EXEEXT): $(vqtrainph_OBJECTS) $(vqtrainph_DEPENDENCIES) 
+       @rm -f vqtrainph$(EXEEXT)
+       $(LINK) $(vqtrainph_LDFLAGS) $(vqtrainph_OBJECTS) $(vqtrainph_LDADD) $(LIBS)
+vqtrainsp$(EXEEXT): $(vqtrainsp_OBJECTS) $(vqtrainsp_DEPENDENCIES) 
+       @rm -f vqtrainsp$(EXEEXT)
+       $(LINK) $(vqtrainsp_LDFLAGS) $(vqtrainsp_OBJECTS) $(vqtrainsp_LDADD) $(LIBS)
+
+mostlyclean-compile:
+       -rm -f *.$(OBJEXT)
+
+distclean-compile:
+       -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/c2validate-c2validate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebook.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebookd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebookdt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebookge.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebookjnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebookjvm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebookvq.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codebookvqanssi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/codec2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/create_interleaver.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/de.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fdmdv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fifo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genampdata.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genlsp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genphdata.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genres.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kiss_fft.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lpc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lspsync.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/octave.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pack.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phase.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/polar2rect.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/postfilter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/quantise.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/raw2h.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scalarlsptest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t48_8.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfdmdv.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfifo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tinterp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlspsens.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tnlp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tprede.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tquant.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vq_train_jvm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vqtrain.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vqtrainjnd.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vqtrainph.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vqtrainsp.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@   if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+
+c2validate-c2validate.o: c2validate.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(c2validate_CFLAGS) $(CFLAGS) -MT c2validate-c2validate.o -MD -MP -MF "$(DEPDIR)/c2validate-c2validate.Tpo" -c -o c2validate-c2validate.o `test -f 'c2validate.c' || echo '$(srcdir)/'`c2validate.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/c2validate-c2validate.Tpo" "$(DEPDIR)/c2validate-c2validate.Po"; else rm -f "$(DEPDIR)/c2validate-c2validate.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='c2validate.c' object='c2validate-c2validate.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(c2validate_CFLAGS) $(CFLAGS) -c -o c2validate-c2validate.o `test -f 'c2validate.c' || echo '$(srcdir)/'`c2validate.c
+
+c2validate-c2validate.obj: c2validate.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(c2validate_CFLAGS) $(CFLAGS) -MT c2validate-c2validate.obj -MD -MP -MF "$(DEPDIR)/c2validate-c2validate.Tpo" -c -o c2validate-c2validate.obj `if test -f 'c2validate.c'; then $(CYGPATH_W) 'c2validate.c'; else $(CYGPATH_W) '$(srcdir)/c2validate.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/c2validate-c2validate.Tpo" "$(DEPDIR)/c2validate-c2validate.Po"; else rm -f "$(DEPDIR)/c2validate-c2validate.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='c2validate.c' object='c2validate-c2validate.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(c2validate_CFLAGS) $(CFLAGS) -c -o c2validate-c2validate.obj `if test -f 'c2validate.c'; then $(CYGPATH_W) 'c2validate.c'; else $(CYGPATH_W) '$(srcdir)/c2validate.c'; fi`
+
+lpc.o: ../src/lpc.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpc.o -MD -MP -MF "$(DEPDIR)/lpc.Tpo" -c -o lpc.o `test -f '../src/lpc.c' || echo '$(srcdir)/'`../src/lpc.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/lpc.Tpo" "$(DEPDIR)/lpc.Po"; else rm -f "$(DEPDIR)/lpc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/lpc.c' object='lpc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpc.o `test -f '../src/lpc.c' || echo '$(srcdir)/'`../src/lpc.c
+
+lpc.obj: ../src/lpc.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lpc.obj -MD -MP -MF "$(DEPDIR)/lpc.Tpo" -c -o lpc.obj `if test -f '../src/lpc.c'; then $(CYGPATH_W) '../src/lpc.c'; else $(CYGPATH_W) '$(srcdir)/../src/lpc.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/lpc.Tpo" "$(DEPDIR)/lpc.Po"; else rm -f "$(DEPDIR)/lpc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/lpc.c' object='lpc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lpc.obj `if test -f '../src/lpc.c'; then $(CYGPATH_W) '../src/lpc.c'; else $(CYGPATH_W) '$(srcdir)/../src/lpc.c'; fi`
+
+lsp.o: ../src/lsp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lsp.o -MD -MP -MF "$(DEPDIR)/lsp.Tpo" -c -o lsp.o `test -f '../src/lsp.c' || echo '$(srcdir)/'`../src/lsp.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/lsp.Tpo" "$(DEPDIR)/lsp.Po"; else rm -f "$(DEPDIR)/lsp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/lsp.c' object='lsp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lsp.o `test -f '../src/lsp.c' || echo '$(srcdir)/'`../src/lsp.c
+
+lsp.obj: ../src/lsp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lsp.obj -MD -MP -MF "$(DEPDIR)/lsp.Tpo" -c -o lsp.obj `if test -f '../src/lsp.c'; then $(CYGPATH_W) '../src/lsp.c'; else $(CYGPATH_W) '$(srcdir)/../src/lsp.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/lsp.Tpo" "$(DEPDIR)/lsp.Po"; else rm -f "$(DEPDIR)/lsp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/lsp.c' object='lsp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lsp.obj `if test -f '../src/lsp.c'; then $(CYGPATH_W) '../src/lsp.c'; else $(CYGPATH_W) '$(srcdir)/../src/lsp.c'; fi`
+
+quantise.o: ../src/quantise.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT quantise.o -MD -MP -MF "$(DEPDIR)/quantise.Tpo" -c -o quantise.o `test -f '../src/quantise.c' || echo '$(srcdir)/'`../src/quantise.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/quantise.Tpo" "$(DEPDIR)/quantise.Po"; else rm -f "$(DEPDIR)/quantise.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/quantise.c' object='quantise.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o quantise.o `test -f '../src/quantise.c' || echo '$(srcdir)/'`../src/quantise.c
+
+quantise.obj: ../src/quantise.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT quantise.obj -MD -MP -MF "$(DEPDIR)/quantise.Tpo" -c -o quantise.obj `if test -f '../src/quantise.c'; then $(CYGPATH_W) '../src/quantise.c'; else $(CYGPATH_W) '$(srcdir)/../src/quantise.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/quantise.Tpo" "$(DEPDIR)/quantise.Po"; else rm -f "$(DEPDIR)/quantise.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/quantise.c' object='quantise.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o quantise.obj `if test -f '../src/quantise.c'; then $(CYGPATH_W) '../src/quantise.c'; else $(CYGPATH_W) '$(srcdir)/../src/quantise.c'; fi`
+
+dump.o: ../src/dump.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dump.o -MD -MP -MF "$(DEPDIR)/dump.Tpo" -c -o dump.o `test -f '../src/dump.c' || echo '$(srcdir)/'`../src/dump.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/dump.Tpo" "$(DEPDIR)/dump.Po"; else rm -f "$(DEPDIR)/dump.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/dump.c' object='dump.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dump.o `test -f '../src/dump.c' || echo '$(srcdir)/'`../src/dump.c
+
+dump.obj: ../src/dump.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT dump.obj -MD -MP -MF "$(DEPDIR)/dump.Tpo" -c -o dump.obj `if test -f '../src/dump.c'; then $(CYGPATH_W) '../src/dump.c'; else $(CYGPATH_W) '$(srcdir)/../src/dump.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/dump.Tpo" "$(DEPDIR)/dump.Po"; else rm -f "$(DEPDIR)/dump.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/dump.c' object='dump.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o dump.obj `if test -f '../src/dump.c'; then $(CYGPATH_W) '../src/dump.c'; else $(CYGPATH_W) '$(srcdir)/../src/dump.c'; fi`
+
+kiss_fft.o: ../src/kiss_fft.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kiss_fft.o -MD -MP -MF "$(DEPDIR)/kiss_fft.Tpo" -c -o kiss_fft.o `test -f '../src/kiss_fft.c' || echo '$(srcdir)/'`../src/kiss_fft.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/kiss_fft.Tpo" "$(DEPDIR)/kiss_fft.Po"; else rm -f "$(DEPDIR)/kiss_fft.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/kiss_fft.c' object='kiss_fft.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kiss_fft.o `test -f '../src/kiss_fft.c' || echo '$(srcdir)/'`../src/kiss_fft.c
+
+kiss_fft.obj: ../src/kiss_fft.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT kiss_fft.obj -MD -MP -MF "$(DEPDIR)/kiss_fft.Tpo" -c -o kiss_fft.obj `if test -f '../src/kiss_fft.c'; then $(CYGPATH_W) '../src/kiss_fft.c'; else $(CYGPATH_W) '$(srcdir)/../src/kiss_fft.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/kiss_fft.Tpo" "$(DEPDIR)/kiss_fft.Po"; else rm -f "$(DEPDIR)/kiss_fft.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/kiss_fft.c' object='kiss_fft.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o kiss_fft.obj `if test -f '../src/kiss_fft.c'; then $(CYGPATH_W) '../src/kiss_fft.c'; else $(CYGPATH_W) '$(srcdir)/../src/kiss_fft.c'; fi`
+
+codec2.o: ../src/codec2.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codec2.o -MD -MP -MF "$(DEPDIR)/codec2.Tpo" -c -o codec2.o `test -f '../src/codec2.c' || echo '$(srcdir)/'`../src/codec2.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codec2.Tpo" "$(DEPDIR)/codec2.Po"; else rm -f "$(DEPDIR)/codec2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codec2.c' object='codec2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codec2.o `test -f '../src/codec2.c' || echo '$(srcdir)/'`../src/codec2.c
+
+codec2.obj: ../src/codec2.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codec2.obj -MD -MP -MF "$(DEPDIR)/codec2.Tpo" -c -o codec2.obj `if test -f '../src/codec2.c'; then $(CYGPATH_W) '../src/codec2.c'; else $(CYGPATH_W) '$(srcdir)/../src/codec2.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codec2.Tpo" "$(DEPDIR)/codec2.Po"; else rm -f "$(DEPDIR)/codec2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codec2.c' object='codec2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codec2.obj `if test -f '../src/codec2.c'; then $(CYGPATH_W) '../src/codec2.c'; else $(CYGPATH_W) '$(srcdir)/../src/codec2.c'; fi`
+
+sine.o: ../src/sine.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sine.o -MD -MP -MF "$(DEPDIR)/sine.Tpo" -c -o sine.o `test -f '../src/sine.c' || echo '$(srcdir)/'`../src/sine.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/sine.Tpo" "$(DEPDIR)/sine.Po"; else rm -f "$(DEPDIR)/sine.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/sine.c' object='sine.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sine.o `test -f '../src/sine.c' || echo '$(srcdir)/'`../src/sine.c
+
+sine.obj: ../src/sine.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sine.obj -MD -MP -MF "$(DEPDIR)/sine.Tpo" -c -o sine.obj `if test -f '../src/sine.c'; then $(CYGPATH_W) '../src/sine.c'; else $(CYGPATH_W) '$(srcdir)/../src/sine.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/sine.Tpo" "$(DEPDIR)/sine.Po"; else rm -f "$(DEPDIR)/sine.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/sine.c' object='sine.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o sine.obj `if test -f '../src/sine.c'; then $(CYGPATH_W) '../src/sine.c'; else $(CYGPATH_W) '$(srcdir)/../src/sine.c'; fi`
+
+nlp.o: ../src/nlp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nlp.o -MD -MP -MF "$(DEPDIR)/nlp.Tpo" -c -o nlp.o `test -f '../src/nlp.c' || echo '$(srcdir)/'`../src/nlp.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/nlp.Tpo" "$(DEPDIR)/nlp.Po"; else rm -f "$(DEPDIR)/nlp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/nlp.c' object='nlp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nlp.o `test -f '../src/nlp.c' || echo '$(srcdir)/'`../src/nlp.c
+
+nlp.obj: ../src/nlp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nlp.obj -MD -MP -MF "$(DEPDIR)/nlp.Tpo" -c -o nlp.obj `if test -f '../src/nlp.c'; then $(CYGPATH_W) '../src/nlp.c'; else $(CYGPATH_W) '$(srcdir)/../src/nlp.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/nlp.Tpo" "$(DEPDIR)/nlp.Po"; else rm -f "$(DEPDIR)/nlp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/nlp.c' object='nlp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nlp.obj `if test -f '../src/nlp.c'; then $(CYGPATH_W) '../src/nlp.c'; else $(CYGPATH_W) '$(srcdir)/../src/nlp.c'; fi`
+
+postfilter.o: ../src/postfilter.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT postfilter.o -MD -MP -MF "$(DEPDIR)/postfilter.Tpo" -c -o postfilter.o `test -f '../src/postfilter.c' || echo '$(srcdir)/'`../src/postfilter.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/postfilter.Tpo" "$(DEPDIR)/postfilter.Po"; else rm -f "$(DEPDIR)/postfilter.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/postfilter.c' object='postfilter.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o postfilter.o `test -f '../src/postfilter.c' || echo '$(srcdir)/'`../src/postfilter.c
+
+postfilter.obj: ../src/postfilter.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT postfilter.obj -MD -MP -MF "$(DEPDIR)/postfilter.Tpo" -c -o postfilter.obj `if test -f '../src/postfilter.c'; then $(CYGPATH_W) '../src/postfilter.c'; else $(CYGPATH_W) '$(srcdir)/../src/postfilter.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/postfilter.Tpo" "$(DEPDIR)/postfilter.Po"; else rm -f "$(DEPDIR)/postfilter.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/postfilter.c' object='postfilter.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o postfilter.obj `if test -f '../src/postfilter.c'; then $(CYGPATH_W) '../src/postfilter.c'; else $(CYGPATH_W) '$(srcdir)/../src/postfilter.c'; fi`
+
+phase.o: ../src/phase.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT phase.o -MD -MP -MF "$(DEPDIR)/phase.Tpo" -c -o phase.o `test -f '../src/phase.c' || echo '$(srcdir)/'`../src/phase.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/phase.Tpo" "$(DEPDIR)/phase.Po"; else rm -f "$(DEPDIR)/phase.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/phase.c' object='phase.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o phase.o `test -f '../src/phase.c' || echo '$(srcdir)/'`../src/phase.c
+
+phase.obj: ../src/phase.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT phase.obj -MD -MP -MF "$(DEPDIR)/phase.Tpo" -c -o phase.obj `if test -f '../src/phase.c'; then $(CYGPATH_W) '../src/phase.c'; else $(CYGPATH_W) '$(srcdir)/../src/phase.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/phase.Tpo" "$(DEPDIR)/phase.Po"; else rm -f "$(DEPDIR)/phase.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/phase.c' object='phase.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o phase.obj `if test -f '../src/phase.c'; then $(CYGPATH_W) '../src/phase.c'; else $(CYGPATH_W) '$(srcdir)/../src/phase.c'; fi`
+
+interp.o: ../src/interp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT interp.o -MD -MP -MF "$(DEPDIR)/interp.Tpo" -c -o interp.o `test -f '../src/interp.c' || echo '$(srcdir)/'`../src/interp.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/interp.Tpo" "$(DEPDIR)/interp.Po"; else rm -f "$(DEPDIR)/interp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/interp.c' object='interp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o interp.o `test -f '../src/interp.c' || echo '$(srcdir)/'`../src/interp.c
+
+interp.obj: ../src/interp.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT interp.obj -MD -MP -MF "$(DEPDIR)/interp.Tpo" -c -o interp.obj `if test -f '../src/interp.c'; then $(CYGPATH_W) '../src/interp.c'; else $(CYGPATH_W) '$(srcdir)/../src/interp.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/interp.Tpo" "$(DEPDIR)/interp.Po"; else rm -f "$(DEPDIR)/interp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/interp.c' object='interp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o interp.obj `if test -f '../src/interp.c'; then $(CYGPATH_W) '../src/interp.c'; else $(CYGPATH_W) '$(srcdir)/../src/interp.c'; fi`
+
+pack.o: ../src/pack.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pack.o -MD -MP -MF "$(DEPDIR)/pack.Tpo" -c -o pack.o `test -f '../src/pack.c' || echo '$(srcdir)/'`../src/pack.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/pack.Tpo" "$(DEPDIR)/pack.Po"; else rm -f "$(DEPDIR)/pack.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/pack.c' object='pack.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pack.o `test -f '../src/pack.c' || echo '$(srcdir)/'`../src/pack.c
+
+pack.obj: ../src/pack.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pack.obj -MD -MP -MF "$(DEPDIR)/pack.Tpo" -c -o pack.obj `if test -f '../src/pack.c'; then $(CYGPATH_W) '../src/pack.c'; else $(CYGPATH_W) '$(srcdir)/../src/pack.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/pack.Tpo" "$(DEPDIR)/pack.Po"; else rm -f "$(DEPDIR)/pack.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/pack.c' object='pack.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pack.obj `if test -f '../src/pack.c'; then $(CYGPATH_W) '../src/pack.c'; else $(CYGPATH_W) '$(srcdir)/../src/pack.c'; fi`
+
+codebook.o: ../src/codebook.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebook.o -MD -MP -MF "$(DEPDIR)/codebook.Tpo" -c -o codebook.o `test -f '../src/codebook.c' || echo '$(srcdir)/'`../src/codebook.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebook.Tpo" "$(DEPDIR)/codebook.Po"; else rm -f "$(DEPDIR)/codebook.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebook.c' object='codebook.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebook.o `test -f '../src/codebook.c' || echo '$(srcdir)/'`../src/codebook.c
+
+codebook.obj: ../src/codebook.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebook.obj -MD -MP -MF "$(DEPDIR)/codebook.Tpo" -c -o codebook.obj `if test -f '../src/codebook.c'; then $(CYGPATH_W) '../src/codebook.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebook.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebook.Tpo" "$(DEPDIR)/codebook.Po"; else rm -f "$(DEPDIR)/codebook.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebook.c' object='codebook.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebook.obj `if test -f '../src/codebook.c'; then $(CYGPATH_W) '../src/codebook.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebook.c'; fi`
+
+codebookd.o: ../src/codebookd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookd.o -MD -MP -MF "$(DEPDIR)/codebookd.Tpo" -c -o codebookd.o `test -f '../src/codebookd.c' || echo '$(srcdir)/'`../src/codebookd.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookd.Tpo" "$(DEPDIR)/codebookd.Po"; else rm -f "$(DEPDIR)/codebookd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookd.c' object='codebookd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookd.o `test -f '../src/codebookd.c' || echo '$(srcdir)/'`../src/codebookd.c
+
+codebookd.obj: ../src/codebookd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookd.obj -MD -MP -MF "$(DEPDIR)/codebookd.Tpo" -c -o codebookd.obj `if test -f '../src/codebookd.c'; then $(CYGPATH_W) '../src/codebookd.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookd.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookd.Tpo" "$(DEPDIR)/codebookd.Po"; else rm -f "$(DEPDIR)/codebookd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookd.c' object='codebookd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookd.obj `if test -f '../src/codebookd.c'; then $(CYGPATH_W) '../src/codebookd.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookd.c'; fi`
+
+codebookvq.o: ../src/codebookvq.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookvq.o -MD -MP -MF "$(DEPDIR)/codebookvq.Tpo" -c -o codebookvq.o `test -f '../src/codebookvq.c' || echo '$(srcdir)/'`../src/codebookvq.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookvq.Tpo" "$(DEPDIR)/codebookvq.Po"; else rm -f "$(DEPDIR)/codebookvq.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookvq.c' object='codebookvq.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookvq.o `test -f '../src/codebookvq.c' || echo '$(srcdir)/'`../src/codebookvq.c
+
+codebookvq.obj: ../src/codebookvq.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookvq.obj -MD -MP -MF "$(DEPDIR)/codebookvq.Tpo" -c -o codebookvq.obj `if test -f '../src/codebookvq.c'; then $(CYGPATH_W) '../src/codebookvq.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookvq.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookvq.Tpo" "$(DEPDIR)/codebookvq.Po"; else rm -f "$(DEPDIR)/codebookvq.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookvq.c' object='codebookvq.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookvq.obj `if test -f '../src/codebookvq.c'; then $(CYGPATH_W) '../src/codebookvq.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookvq.c'; fi`
+
+codebookjnd.o: ../src/codebookjnd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookjnd.o -MD -MP -MF "$(DEPDIR)/codebookjnd.Tpo" -c -o codebookjnd.o `test -f '../src/codebookjnd.c' || echo '$(srcdir)/'`../src/codebookjnd.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookjnd.Tpo" "$(DEPDIR)/codebookjnd.Po"; else rm -f "$(DEPDIR)/codebookjnd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookjnd.c' object='codebookjnd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookjnd.o `test -f '../src/codebookjnd.c' || echo '$(srcdir)/'`../src/codebookjnd.c
+
+codebookjnd.obj: ../src/codebookjnd.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookjnd.obj -MD -MP -MF "$(DEPDIR)/codebookjnd.Tpo" -c -o codebookjnd.obj `if test -f '../src/codebookjnd.c'; then $(CYGPATH_W) '../src/codebookjnd.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookjnd.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookjnd.Tpo" "$(DEPDIR)/codebookjnd.Po"; else rm -f "$(DEPDIR)/codebookjnd.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookjnd.c' object='codebookjnd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookjnd.obj `if test -f '../src/codebookjnd.c'; then $(CYGPATH_W) '../src/codebookjnd.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookjnd.c'; fi`
+
+codebookdt.o: ../src/codebookdt.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookdt.o -MD -MP -MF "$(DEPDIR)/codebookdt.Tpo" -c -o codebookdt.o `test -f '../src/codebookdt.c' || echo '$(srcdir)/'`../src/codebookdt.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookdt.Tpo" "$(DEPDIR)/codebookdt.Po"; else rm -f "$(DEPDIR)/codebookdt.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookdt.c' object='codebookdt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookdt.o `test -f '../src/codebookdt.c' || echo '$(srcdir)/'`../src/codebookdt.c
+
+codebookdt.obj: ../src/codebookdt.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookdt.obj -MD -MP -MF "$(DEPDIR)/codebookdt.Tpo" -c -o codebookdt.obj `if test -f '../src/codebookdt.c'; then $(CYGPATH_W) '../src/codebookdt.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookdt.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookdt.Tpo" "$(DEPDIR)/codebookdt.Po"; else rm -f "$(DEPDIR)/codebookdt.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookdt.c' object='codebookdt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookdt.obj `if test -f '../src/codebookdt.c'; then $(CYGPATH_W) '../src/codebookdt.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookdt.c'; fi`
+
+codebookjvm.o: ../src/codebookjvm.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookjvm.o -MD -MP -MF "$(DEPDIR)/codebookjvm.Tpo" -c -o codebookjvm.o `test -f '../src/codebookjvm.c' || echo '$(srcdir)/'`../src/codebookjvm.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookjvm.Tpo" "$(DEPDIR)/codebookjvm.Po"; else rm -f "$(DEPDIR)/codebookjvm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookjvm.c' object='codebookjvm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookjvm.o `test -f '../src/codebookjvm.c' || echo '$(srcdir)/'`../src/codebookjvm.c
+
+codebookjvm.obj: ../src/codebookjvm.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookjvm.obj -MD -MP -MF "$(DEPDIR)/codebookjvm.Tpo" -c -o codebookjvm.obj `if test -f '../src/codebookjvm.c'; then $(CYGPATH_W) '../src/codebookjvm.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookjvm.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookjvm.Tpo" "$(DEPDIR)/codebookjvm.Po"; else rm -f "$(DEPDIR)/codebookjvm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookjvm.c' object='codebookjvm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookjvm.obj `if test -f '../src/codebookjvm.c'; then $(CYGPATH_W) '../src/codebookjvm.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookjvm.c'; fi`
+
+codebookvqanssi.o: ../src/codebookvqanssi.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookvqanssi.o -MD -MP -MF "$(DEPDIR)/codebookvqanssi.Tpo" -c -o codebookvqanssi.o `test -f '../src/codebookvqanssi.c' || echo '$(srcdir)/'`../src/codebookvqanssi.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookvqanssi.Tpo" "$(DEPDIR)/codebookvqanssi.Po"; else rm -f "$(DEPDIR)/codebookvqanssi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookvqanssi.c' object='codebookvqanssi.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookvqanssi.o `test -f '../src/codebookvqanssi.c' || echo '$(srcdir)/'`../src/codebookvqanssi.c
+
+codebookvqanssi.obj: ../src/codebookvqanssi.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookvqanssi.obj -MD -MP -MF "$(DEPDIR)/codebookvqanssi.Tpo" -c -o codebookvqanssi.obj `if test -f '../src/codebookvqanssi.c'; then $(CYGPATH_W) '../src/codebookvqanssi.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookvqanssi.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookvqanssi.Tpo" "$(DEPDIR)/codebookvqanssi.Po"; else rm -f "$(DEPDIR)/codebookvqanssi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookvqanssi.c' object='codebookvqanssi.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookvqanssi.obj `if test -f '../src/codebookvqanssi.c'; then $(CYGPATH_W) '../src/codebookvqanssi.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookvqanssi.c'; fi`
+
+codebookge.o: ../src/codebookge.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookge.o -MD -MP -MF "$(DEPDIR)/codebookge.Tpo" -c -o codebookge.o `test -f '../src/codebookge.c' || echo '$(srcdir)/'`../src/codebookge.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookge.Tpo" "$(DEPDIR)/codebookge.Po"; else rm -f "$(DEPDIR)/codebookge.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookge.c' object='codebookge.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookge.o `test -f '../src/codebookge.c' || echo '$(srcdir)/'`../src/codebookge.c
+
+codebookge.obj: ../src/codebookge.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT codebookge.obj -MD -MP -MF "$(DEPDIR)/codebookge.Tpo" -c -o codebookge.obj `if test -f '../src/codebookge.c'; then $(CYGPATH_W) '../src/codebookge.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookge.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/codebookge.Tpo" "$(DEPDIR)/codebookge.Po"; else rm -f "$(DEPDIR)/codebookge.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/codebookge.c' object='codebookge.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o codebookge.obj `if test -f '../src/codebookge.c'; then $(CYGPATH_W) '../src/codebookge.c'; else $(CYGPATH_W) '$(srcdir)/../src/codebookge.c'; fi`
+
+fdmdv.o: ../src/fdmdv.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fdmdv.o -MD -MP -MF "$(DEPDIR)/fdmdv.Tpo" -c -o fdmdv.o `test -f '../src/fdmdv.c' || echo '$(srcdir)/'`../src/fdmdv.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fdmdv.Tpo" "$(DEPDIR)/fdmdv.Po"; else rm -f "$(DEPDIR)/fdmdv.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/fdmdv.c' object='fdmdv.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fdmdv.o `test -f '../src/fdmdv.c' || echo '$(srcdir)/'`../src/fdmdv.c
+
+fdmdv.obj: ../src/fdmdv.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fdmdv.obj -MD -MP -MF "$(DEPDIR)/fdmdv.Tpo" -c -o fdmdv.obj `if test -f '../src/fdmdv.c'; then $(CYGPATH_W) '../src/fdmdv.c'; else $(CYGPATH_W) '$(srcdir)/../src/fdmdv.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fdmdv.Tpo" "$(DEPDIR)/fdmdv.Po"; else rm -f "$(DEPDIR)/fdmdv.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/fdmdv.c' object='fdmdv.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fdmdv.obj `if test -f '../src/fdmdv.c'; then $(CYGPATH_W) '../src/fdmdv.c'; else $(CYGPATH_W) '$(srcdir)/../src/fdmdv.c'; fi`
+
+octave.o: ../src/octave.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT octave.o -MD -MP -MF "$(DEPDIR)/octave.Tpo" -c -o octave.o `test -f '../src/octave.c' || echo '$(srcdir)/'`../src/octave.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/octave.Tpo" "$(DEPDIR)/octave.Po"; else rm -f "$(DEPDIR)/octave.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/octave.c' object='octave.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o octave.o `test -f '../src/octave.c' || echo '$(srcdir)/'`../src/octave.c
+
+octave.obj: ../src/octave.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT octave.obj -MD -MP -MF "$(DEPDIR)/octave.Tpo" -c -o octave.obj `if test -f '../src/octave.c'; then $(CYGPATH_W) '../src/octave.c'; else $(CYGPATH_W) '$(srcdir)/../src/octave.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/octave.Tpo" "$(DEPDIR)/octave.Po"; else rm -f "$(DEPDIR)/octave.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/octave.c' object='octave.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o octave.obj `if test -f '../src/octave.c'; then $(CYGPATH_W) '../src/octave.c'; else $(CYGPATH_W) '$(srcdir)/../src/octave.c'; fi`
+
+fifo.o: ../src/fifo.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fifo.o -MD -MP -MF "$(DEPDIR)/fifo.Tpo" -c -o fifo.o `test -f '../src/fifo.c' || echo '$(srcdir)/'`../src/fifo.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fifo.Tpo" "$(DEPDIR)/fifo.Po"; else rm -f "$(DEPDIR)/fifo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/fifo.c' object='fifo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fifo.o `test -f '../src/fifo.c' || echo '$(srcdir)/'`../src/fifo.c
+
+fifo.obj: ../src/fifo.c
+@am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT fifo.obj -MD -MP -MF "$(DEPDIR)/fifo.Tpo" -c -o fifo.obj `if test -f '../src/fifo.c'; then $(CYGPATH_W) '../src/fifo.c'; else $(CYGPATH_W) '$(srcdir)/../src/fifo.c'; fi`; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/fifo.Tpo" "$(DEPDIR)/fifo.Po"; else rm -f "$(DEPDIR)/fifo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='../src/fifo.c' object='fifo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o fifo.obj `if test -f '../src/fifo.c'; then $(CYGPATH_W) '../src/fifo.c'; else $(CYGPATH_W) '$(srcdir)/../src/fifo.c'; fi`
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+       -rm -f libtool
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+       list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+         test -n "$$unique" || unique=$$empty_fix; \
+         $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+           $$tags $$unique; \
+       fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+               $(TAGS_FILES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+       unique=`for i in $$list; do \
+           if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+         done | \
+         $(AWK) '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(CTAGS_ARGS)$$tags$$unique" \
+         || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+            $$tags $$unique
+
+GTAGS:
+       here=`$(am__cd) $(top_builddir) && pwd` \
+         && cd $(top_srcdir) \
+         && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+       -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+       @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+       topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+       list='$(DISTFILES)'; for file in $$list; do \
+         case $$file in \
+           $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+           $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+         esac; \
+         if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+         dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+         if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+           dir="/$$dir"; \
+           $(mkdir_p) "$(distdir)$$dir"; \
+         else \
+           dir=''; \
+         fi; \
+         if test -d $$d/$$file; then \
+           if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+             cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+           fi; \
+           cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+         else \
+           test -f $(distdir)/$$file \
+           || cp -p $$d/$$file $(distdir)/$$file \
+           || exit 1; \
+         fi; \
+       done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+         `test -z '$(STRIP)' || \
+           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+       @echo "This command is intended for maintainers to use"
+       @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+       mostlyclean-am
+
+distclean: distclean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+       distclean-libtool distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+       -rm -rf ./$(DEPDIR)
+       -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+       mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+       clean-libtool clean-noinstPROGRAMS ctags distclean \
+       distclean-compile distclean-generic distclean-libtool \
+       distclean-tags distdir dvi dvi-am html html-am info info-am \
+       install install-am install-data install-data-am install-exec \
+       install-exec-am install-info install-info-am install-man \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags uninstall uninstall-am \
+       uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/codec2/branches/0.7/unittest/README b/codec2/branches/0.7/unittest/README
new file mode 100644 (file)
index 0000000..0e8776b
--- /dev/null
@@ -0,0 +1,43 @@
+README
+for codec2/unittest
+Created David Rowe 31 July 2012
+
+Training (experimental) sparse phase VQs:
+
+1/ In ../src/phase.c phase_experiment() enable:
+
+   print_sparse_pred_error()
+
+   and 'make' c2sim (in src)
+
+2/ Run over a training database:
+
+  $ ./c2sim /xhome1/codec2/samples/train.spc --phaseexp > train_phtrain.txt
+
+  a) check stats in Octave:
+     octave> load ../src/train_phtrain.txt
+     octave> std(nonzeros(train_phtrain(:,1:20)))
+     octave> hist(nonzeros(train_phtrain(:,1:20)),20)
+3/ Extract and convert to floats vector you wish to train for example
+   first 20 (out of MAX_AMP == 80):
+
+  $ ./extract ../src/train_phtrain.txt train_phtrain.flt 1 20
+
+4/ Convert to rectangular:
+
+  $ ./polar2rect train_phtrain.flt train_phtrainr.flt
+
+5/ Run this program:
+
+  $ ./vqtrainph train_phtrainr.flt 20 1024 vq.txt
+
+  Ouput is vq.txt
+
+Tests
+-----
+
++ build up insmallest possible stesp
++ impl errors v alg errors
++ use actual phase data as codebook
++ test vq with rand phases first or known data
+
diff --git a/codec2/branches/0.7/unittest/c2validate.c b/codec2/branches/0.7/unittest/c2validate.c
new file mode 100644 (file)
index 0000000..5906017
--- /dev/null
@@ -0,0 +1,103 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: c2validate.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 10 April 2013
+
+  Encodes and decodes an array of speech samples using Codec 2 and compares
+  it to a previously stored output to validate Codec operation.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "codec2.h"
+#ifdef __UNITTEST__
+#include "hts1a.h"
+#include "hts1a_1300.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef __EMBEDDED__
+#include "gdb_stdio.h"
+#define fopen gdb_stdio_fopen
+#define fwrite gdb_stdio_fwrite
+#define fclose gdb_stdio_fclose
+#endif
+
+int c2validate(int mode, short input_samples[], short output_samples[], char outfile[], int nsamples)
+{
+    struct CODEC2 *codec2;
+    short         *pinput, *poutput, *outbuf;
+    unsigned char *bits;
+    int            nsam, nbit;
+    int            nframes, i, result, j;
+    FILE          *fout;
+
+    codec2 = codec2_create(mode);
+    nsam = codec2_samples_per_frame(codec2);
+    outbuf = (short*)malloc(nsam*sizeof(short));
+    nbit = codec2_bits_per_frame(codec2);
+    bits = (unsigned char*)malloc(nbit*sizeof(char));
+    if (strlen(outfile))
+        fout = fopen(outfile, "wb");
+    else
+        fout = NULL;
+
+    nframes = nsamples/nsam;
+    pinput  = input_samples;
+    poutput = output_samples;
+    result = 1;
+
+    for(i=0; i<nframes; i++) {
+       codec2_encode(codec2, bits, pinput);
+       codec2_decode(codec2, outbuf, bits);
+        for(j=0; j<nsam; j++) {
+            if (outbuf[j] != poutput[j])
+                result = 0;
+        }
+        if (fout != NULL)
+            fwrite(outbuf, sizeof(short), nsam, fout);
+        pinput += nsam;
+        poutput += nsam;
+    }
+
+    if (fout != NULL)
+        fclose(fout);
+    free(outbuf);
+    free(bits);
+    codec2_destroy(codec2);
+
+    return result;
+}
+
+#ifdef __UNITTEST__
+int main(int argc, char *argv[])
+{
+    int ret;
+
+    ret = c2validate(CODEC2_MODE_1300, hts1a_raw, hts1a_1300, "", sizeof(hts1a_raw)/sizeof(short));
+    if (ret)
+        printf("Pass\n");
+    else
+        printf("Fail\n");
+    return 0;
+}
+#endif
diff --git a/codec2/branches/0.7/unittest/c2validate.h b/codec2/branches/0.7/unittest/c2validate.h
new file mode 100644 (file)
index 0000000..38f7bf7
--- /dev/null
@@ -0,0 +1,33 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: c2validate.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 10 April 2013
+
+  Encodes and decodes an array of speech samples using Codec 2 and compares
+  it to a previously stored output to validate Codec operation.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2013 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __C2VALIDATE__
+
+int c2validate(int mode, short input_samples[], short output_samples[], char outfile[], int nsamples);
+
+#endif
diff --git a/codec2/branches/0.7/unittest/create_interleaver.c b/codec2/branches/0.7/unittest/create_interleaver.c
new file mode 100644 (file)
index 0000000..7fb1ae5
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+  create_interleaver.c
+  David Rowe
+  May 27 2012
+
+  Creates an interleaver for Codec 2.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main(int argc, char * argv[]) {
+    int   m,i, src_bit, dest_bit;
+    FILE *f;
+    int  *interleaver;
+
+    if (argc != 3) {
+       printf("usage: %s InterleaverBits InterleaverFile\n", argv[0]);
+       exit(1);
+    }
+
+    m = atoi(argv[1]);
+    f = fopen(argv[2],"wt");
+    assert(f != NULL);
+
+
+    interleaver = (int*)malloc(m*sizeof(int));
+    assert(interleaver != NULL);
+    for(i=0; i<m; i++)
+       interleaver[i] = -1;
+
+    src_bit = 0;
+    while(src_bit != m) {
+       dest_bit = ((float)rand()/RAND_MAX)*m;
+       if (interleaver[dest_bit] == -1) {
+           interleaver[dest_bit] = src_bit;
+           src_bit++;
+       }
+    }
+
+    for(i=0; i<m; i++) {
+       fprintf(f, "%d\n", interleaver[i]);
+    }
+
+    fclose(f);
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/de.c b/codec2/branches/0.7/unittest/de.c
new file mode 100644 (file)
index 0000000..9726743
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+   de.c
+   David Rowe
+   Sep 26 2012
+
+   Takes audio from a file, de-emphasises, and sends to output file.
+*/
+
+#include <assert.h>
+#include <errno.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "lpc.h"
+
+#define N 80
+
+int main(int argc, char *argv[]) {
+    FILE  *fin, *fout;
+    short  buf[N];
+    float  Sn[N], Sn_de[N];
+    float  de_mem = 0.0;
+    int    i;
+
+    if (argc != 3) {
+       printf("usage: de InputRawSpeechFile OutputRawSpeechFile\n");
+       printf("e.g    de input.raw output.raw");
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input speech 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 speech file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    while(fread(buf, sizeof(short), N, fin) == N) {
+       for(i=0; i<N; i++)
+           Sn[i] = buf[i];
+       de_emp(Sn_de, Sn, &de_mem, N);
+       for(i=0; i<N; i++)
+           buf[i] = Sn_de[i];
+       fwrite(buf, sizeof(short), N, fout);
+    }
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/dvdongle2.c b/codec2/branches/0.7/unittest/dvdongle2.c
new file mode 100644 (file)
index 0000000..0635fac
--- /dev/null
@@ -0,0 +1,385 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: dvdongle2.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 28 Oct 2010
+
+  Program to encode and decode raw speech samples using the AMBE codec
+  implemented on a DV Dongle.
+
+  The DV Dongle connects to a USB port and provides encoding and
+  decoding of compressed audio using the DVSI AMBE2000 full duplex
+  vocoder DSP chip.
+
+  Refs:
+
+    [1] http://www.dvdongle.com/
+    [2] http://www.moetronix.com/files/dvdongletechref100.pdf
+    [3] http://www.dvsinc.com/manuals/AMBE-2000_manual.pdf
+    [4] http://www.moetronix.com/files/ambetest103.zip
+
+  Serial code based on ser.c sample from http://www.captain.at
+
+  Compile with:
+
+    gcc dvdongle2.c -o dvdongle2 -Wall -g -O2
+
+  Note: This program is not very stable, it sometimes stops part way
+  through processing an utterance.  I made it just good enough to work
+  most of the time, as my purpose was just to process a few sample
+  files.
+
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 1990-2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <termios.h>
+
+#define MAX_STR                  1024
+#define LEN_TARGET_NAME_RESPONSE 14
+#define N                        160
+
+/* message parsing state machine states */
+
+#define MSGSTATE_HDR1 0
+#define MSGSTATE_HDR2 1
+#define MSGSTATE_DATA 2
+
+#define LENGTH_MASK 0x1FFF    /* mask for message length            */
+#define TYPE_MASK   0xE0      /* mask for upper byte of header      */
+#define TYPE_C      0x20      /* compressed speech from target      */
+#define TYPE_UC     0x40      /* uncompressed speech from target    */
+
+#define MAX_MSG_LEN 8192
+
+/* Control items sent to DV Dongle */
+
+char target_name[]     = {0x04, 0x20, 0x01, 0x00};
+
+/* note [2] appears to be in error, specifies run as 0x02, stop as 0x01 */
+
+char run_state_stop[]  = {0x05, 0x00, 0x18, 0x00, 0x00};
+char run_state_run[]   = {0x05, 0x00, 0x18, 0x00, 0x01};
+
+/* Control item codes from DV Dongle */
+
+char data_item_0[]     = {0x42, 0x81};
+char data_item_1[]     = {0x32, 0xa0};
+char run_state[]       = {0x05, 0x00};
+char idle[]            = {0x00, 0x00};
+
+typedef struct {
+    short header;
+    char  power;
+    char  control1;
+    short rate[5];
+    short unused[3];
+    short dtmf;
+    short control2;
+    short channel_data[12];
+} COMPRESSED;
+
+COMPRESSED c_in;
+COMPRESSED c_out;
+FILE *fin, *fout, *f;
+int    fd, c_msg, uc_msg;
+
+int initport(int fd) {
+    struct termios options;
+
+    // Set the options for the port...
+
+    cfmakeraw(&options);
+    cfsetispeed(&options, B230400);
+    cfsetospeed(&options, B230400);
+    options.c_cflag |= (CLOCAL | CREAD);
+    tcsetattr(fd, TCSANOW, &options);
+
+    return 1;
+}
+
+int getbaud(int fd) {
+    struct termios termAttr;
+    int     inputSpeed = -1;
+    speed_t baudRate;
+
+    tcgetattr(fd, &termAttr);
+
+    /* Get the input speed */
+
+    baudRate = cfgetispeed(&termAttr);
+    switch (baudRate) {
+       case B0:      inputSpeed = 0; break;
+       case B50:     inputSpeed = 50; break;
+       case B110:    inputSpeed = 110; break;
+       case B134:    inputSpeed = 134; break;
+       case B150:    inputSpeed = 150; break;
+       case B200:    inputSpeed = 200; break;
+       case B300:    inputSpeed = 300; break;
+       case B600:    inputSpeed = 600; break;
+       case B1200:   inputSpeed = 1200; break;
+       case B1800:   inputSpeed = 1800; break;
+       case B2400:   inputSpeed = 2400; break;
+       case B4800:   inputSpeed = 4800; break;
+       case B9600:   inputSpeed = 9600; break;
+       case B19200:  inputSpeed = 19200; break;
+       case B38400:  inputSpeed = 38400; break;
+       case B57600:  inputSpeed = 38400; break;
+       case B115200:  inputSpeed = 38400; break;
+       case B230400:  inputSpeed = 230400; break;
+    }
+
+    return inputSpeed;
+}
+
+void write_dongle(int fd, char *data, int len) {
+    int n;
+    //printf("  writing %d bytes\n", len);
+    n = write(fd, data, len);
+    if (n < 0) {
+       perror("write failed");
+       exit(1);
+    }
+}
+
+void read_dongle(int fd, char *data, int len) {
+    int n;
+    //printf("  reading %d bytes  \n", len);
+
+    n = read(fd, data, len);
+    if (n < 0) {
+       perror("read failed");
+       exit(1);
+    }
+    //printf("  read %d bytes\n", len);
+}
+
+void parse_message(int msg_type, int msg_len, char msg_data[]) {
+    short buf[N];
+    COMPRESSED *c_out;
+
+    //printf("msg_type: 0x%02x  msg_len: %d\n", msg_type, msg_len);
+
+    /* echo compressed speech frames back to target */
+
+    if (msg_type == TYPE_C) {
+       c_out = (COMPRESSED*)msg_data;
+#ifdef TMP
+       printf("control1 0x%04x\n", c_out->control1 & 0xff);
+       printf("rate[0]  0x%04x\n", c_out->rate[0]);
+       printf("rate[1]  0x%04x\n", c_out->rate[1]);
+       printf("rate[2]  0x%04x\n", c_out->rate[2]);
+       printf("rate[3]  0x%04x\n", c_out->rate[3]);
+       printf("rate[4]  0x%04x\n", c_out->rate[4]);
+       printf("control2 0x%04x\n", c_out->control2 & 0xffff);
+       printf("cd[0]    0x%04x\n", c_out->channel_data[0] & 0xffff);
+       printf("cd[1]    0x%04x\n", c_out->channel_data[1] & 0xffff);
+       printf("cd[2]    0x%04x\n", c_out->channel_data[2] & 0xffff);
+       printf("cd[3]    0x%04x\n", c_out->channel_data[3] & 0xffff);
+       printf("cd[4]    0x%04x\n", c_out->channel_data[4] & 0xffff);
+       printf("cd[5]    0x%04x\n", c_out->channel_data[5] & 0xffff);
+       printf("cd[6]    0x%04x\n", c_out->channel_data[6] & 0xffff);
+       printf("uc_msg %d\n", uc_msg);
+#endif
+       printf("bit errors %d\n", c_out->unused[2]);
+       memcpy(&c_in.channel_data,
+              &c_out->channel_data,
+              sizeof(c_in.channel_data));
+
+       write_dongle(fd, data_item_1, sizeof(data_item_1));
+       write_dongle(fd, (char*)&c_in, sizeof(c_in));
+
+       c_msg++;
+    }
+
+    /* write speech buffers to disk */
+
+    if (msg_type == TYPE_UC) {
+
+       if (fout != NULL) {
+           fwrite(msg_data, sizeof(char), msg_len-2, fout);
+           printf("msg_len %d\n", msg_len);
+       }
+
+       if (fin != NULL)
+           fread(buf, sizeof(short), N, fin);
+       else
+           memset(buf, 0, sizeof(buf));
+
+       write_dongle(fd, data_item_0, sizeof(data_item_0));
+       write_dongle(fd, (char*)buf, sizeof(buf));
+
+       uc_msg++;
+    }
+}
+
+int main(int argc, char **argv) {
+    char   response[MAX_STR];
+    int    i;
+    int    state, next_state;
+    short  header;
+    int    msg_type, msg_length;
+    char   msg_data[MAX_MSG_LEN];
+    int    n, length;
+    int    r;
+
+    char   data;
+
+    f = fopen("/tmp/log.txt", "wt");
+    assert(f != NULL);
+
+    /* open and configure serial port */
+
+    fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
+    if (fd == -1) {
+       perror("open_port: Unable to open /dev/ttyS0 - ");
+       exit(1);
+    } else {
+       fcntl(fd, F_SETFL, 0);
+    }
+
+    initport(fd);
+
+    fin = NULL;
+    if (argc >= 2) {
+       fin = fopen(argv[1],"rb");
+       assert(fin != NULL);
+    }
+    fout = NULL;
+    if (argc == 3) {
+       fout = fopen(argv[2],"wb");
+       assert(fout != NULL);
+    }
+
+    /* check DV Dongle is alive */
+
+    write_dongle(fd, target_name, sizeof(target_name));
+    read_dongle(fd, response, LEN_TARGET_NAME_RESPONSE);
+    if (strcmp(&response[4],"DV Dongle") != 0) {
+       printf("DV Dongle not responding\n");
+       exit(1);
+    }
+    printf("Found DV Dongle....\n");
+
+    c_in.header    = 0x13ec;
+    c_in.power     = 0x0;
+    c_in.control1  = 0x0;
+
+#define RATE2000
+#ifdef RATE2000
+    c_in.rate[0]   = 0x0028;  /* 2000 bit/s, no FEC */
+    c_in.rate[1]   = 0x0000;
+    c_in.rate[2]   = 0x0000;
+    c_in.rate[3]   = 0x0000;
+    c_in.rate[4]   = 0x6248;
+#endif
+
+#ifdef RATE3600_1200
+    c_in.rate[0]   = 0x5048;  /* 3600 bit/s, 1200 bit/s FEC */
+    c_in.rate[1]   = 0x0001;
+    c_in.rate[2]   = 0x0000;
+    c_in.rate[3]   = 0x2412;
+    c_in.rate[4]   = 0x6860;
+#endif
+
+    c_in.unused[0] = 0x0;
+    c_in.unused[1] = 0x0;
+    c_in.unused[2] = 0x0;
+    c_in.dtmf      = 0x00ff;
+    c_in.control2  = 0x8000;
+
+    /* put codec in run mode */
+
+    write_dongle(fd, run_state_run, sizeof(run_state_run));
+    //write_dongle(fd, data_item_1, sizeof(data_item_1));
+    //write_dongle(fd, (char*)&c_in, sizeof(c_in));
+
+    state = MSGSTATE_HDR1;
+    header = msg_type = msg_length = n = length = 0;
+    c_msg = uc_msg = 0;
+
+    for(i=0; i<100000; i++) {
+       /*
+          We can only reliably read one byte at a time.  Until I
+          realised this there was "much wailing and gnashing of
+          teeth".  Trying to read() n bytes read() returns n but may
+          actually reads some number between 1 and n.  So it may only
+          read 1 byte int data[] but return n.
+       */
+       r = read(fd, &data, 1);
+       assert(r == 1);
+
+       /* used state machine design from ambetest103.zip, SerialPort.cpp */
+
+       next_state = state;
+       switch(state) {
+       case MSGSTATE_HDR1:
+           header = data;
+           next_state = MSGSTATE_HDR2;
+           break;
+       case MSGSTATE_HDR2:
+           header |= data<<8;
+           msg_length = header & LENGTH_MASK;
+           msg_type = header & TYPE_MASK;
+           //printf("%0x %d\n", msg_type, msg_length);
+           if (length == 2) {
+               parse_message(msg_type, msg_length, msg_data);
+               next_state = MSGSTATE_HDR1;
+           }
+           else {
+               if (msg_length == 0x0)
+                   length = 8192;
+               else
+                   length = msg_length - 2;
+               n = 0;
+               next_state = MSGSTATE_DATA;
+           }
+           break;
+       case MSGSTATE_DATA:
+           msg_data[n++] = data;
+           length--;
+           if (length == 0) {
+               parse_message(msg_type, msg_length, msg_data);
+               next_state = MSGSTATE_HDR1;
+           }
+           break;
+       }
+       state = next_state;
+    }
+
+    printf("finished, c_msg = %d uc_msg = %d\n", c_msg, uc_msg);
+
+    write_dongle(fd, run_state_stop, sizeof(run_state_stop));
+
+    close(fd);
+    if (fin != NULL)
+       fclose(fin);
+    if (fout != NULL)
+       fclose(fout);
+    fclose(f);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/extract.c b/codec2/branches/0.7/unittest/extract.c
new file mode 100644 (file)
index 0000000..5fbb3ca
--- /dev/null
@@ -0,0 +1,126 @@
+/*--------------------------------------------------------------------------*\
+
+       FILE........: extract.c
+       AUTHOR......: David Rowe
+       DATE CREATED: 23/2/95
+
+       This program extracts a float file of vectors from a text file
+       of vectors.  The float files are easier to process quickly
+       during VQ training.  A subset of the text file VQ may be
+       extracted to faciltate split VQ of scaler VQ design.
+
+\*--------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define        MAX_STR 2048            /* maximum string length                */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+
+void scan_line(FILE *fp, float f[], int n);
+
+int main(int argc, char *argv[]) {
+    FILE   *ftext;     /* text file of vectors                         */
+    FILE   *ffloat;    /* float file of vectors                        */
+    int    st,en;      /* start and end values of vector to copy       */
+    float  *buf;       /* ptr to vector read from ftext                */
+    long   lines;      /* lines read so far                            */
+
+    if (argc != 5) {
+       printf("usage: %s TextFile FloatFile start(1 .. 10) end(1 .. 10)\n", argv[0]);
+       exit(1);
+    }
+
+    /* read command line arguments and open files */
+
+    ftext = fopen(argv[1],"rt");
+    if (ftext == NULL) {
+       printf("Error opening text file: %s\n",argv[1]);
+       exit(1);
+    }
+
+    ffloat = fopen(argv[2],"wb");
+    if (ffloat == NULL) {
+       printf("Error opening float file: %s\n",argv[2]);
+       exit(1);
+    }
+
+    st = atoi(argv[3]);
+    en = atoi(argv[4]);
+
+    buf = (float*)malloc(en*sizeof(float));
+    if (buf == NULL) {
+       printf("Error in malloc()\n");
+       exit(1);
+    }
+
+    lines = 0;
+    while(!feof(ftext)) {
+       scan_line(ftext, buf, en);
+       if (!feof(ftext)) {
+           fwrite(&buf[st-1], sizeof(float), en-st+1, ffloat);
+           printf("\r%ld lines",++lines);
+       }
+    }
+    printf("\n");
+
+    /* clean up and exit */
+
+    free(buf);
+    fclose(ftext);
+    fclose(ffloat);
+
+    return 0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: scan_line()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 20/2/95
+
+       This function reads a vector of floats from a line in a text file.
+
+\*---------------------------------------------------------------------------*/
+
+void scan_line(FILE *fp, float f[], int n)
+/*  FILE   *fp;                file ptr to text file           */
+/*  float  f[];        array of floats to return       */
+/*  int    n;          number of floats in line        */
+{
+    char   s[MAX_STR];
+    char   *ps,*pe;
+    int           i;
+
+    memset(s, 0, MAX_STR);
+    ps = pe = fgets(s,MAX_STR,fp);
+    if (ps == NULL)
+       return;
+    for(i=0; i<n; i++) {
+       while( isspace(*pe)) pe++;
+       while( !isspace(*pe)) pe++;
+       sscanf(ps,"%f",&f[i]);
+       ps = pe;
+    }
+}
+
diff --git a/codec2/branches/0.7/unittest/fdmdv_mem.c b/codec2/branches/0.7/unittest/fdmdv_mem.c
new file mode 100644 (file)
index 0000000..82018f3
--- /dev/null
@@ -0,0 +1,63 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: fdmdv_mem.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 25 June 2014
+
+  Prints out the memory used by the FDMDV modem states.  Used to optimise
+  memory use for thw STM32F4 port.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2014 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "fdmdv_internal.h"
+
+extern float pilot_coeff[];
+
+int main(int argc, char *argv[])
+{
+    struct FDMDV *fdmdv;
+
+    printf("struct FDMDV..........: %ld\n", sizeof(struct FDMDV));
+    printf("prev_tx_symbols.......: %ld\n", sizeof(fdmdv->prev_tx_symbols));
+    printf("tx_filter_memory......: %ld\n", sizeof(fdmdv->tx_filter_memory));
+    printf("phase_tx..............: %ld\n", sizeof(fdmdv->phase_tx));
+    printf("freq..................: %ld\n", sizeof(fdmdv->freq));
+    printf("pilot_lut.............: %ld\n", sizeof(fdmdv->pilot_lut));
+    printf("pilot_baseband1.......: %ld\n", sizeof(fdmdv->pilot_baseband1));
+    printf("pilot_baseband2.......: %ld\n", sizeof(fdmdv->pilot_baseband2));
+    printf("pilot_lpf1............: %ld\n", sizeof(fdmdv->pilot_lpf1));
+    printf("pilot_lpf2............: %ld\n", sizeof(fdmdv->pilot_lpf2));
+    printf("S1....................: %ld\n", sizeof(fdmdv->S1));
+    printf("S2....................: %ld\n", sizeof(fdmdv->S2));
+    printf("phase_rx..............: %ld\n", sizeof(fdmdv->phase_rx));
+    printf("rx_fdm_mem............: %ld\n", sizeof(fdmdv->rx_fdm_mem));
+    printf("rx_filter_mem_timing..: %ld\n", sizeof(fdmdv->rx_filter_mem_timing));
+    printf("phase_difference......: %ld\n", sizeof(fdmdv->phase_difference));
+    printf("prev_rx_symbols.......: %ld\n", sizeof(fdmdv->prev_rx_symbols));
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/ge_train.c b/codec2/branches/0.7/unittest/ge_train.c
new file mode 100644 (file)
index 0000000..33e314b
--- /dev/null
@@ -0,0 +1,299 @@
+/*
+ ge_train.c
+ Jean Marc Valin Feb 2012
+
+ Joint pitch and energy VQ training program
+
+ usage:
+
+   cat GE | ./ge_train 2 1000000 8 > quantized
+
+ The first column is the log2 of the pitch compared to the lowest freq,
+ so log2(wo/pi*4000/50) where wo is the frequency your patch outputs. The
+ second column is the energy in dB, so 10*log10(1e-4+E)
+*/
+
+/*
+  Copyright (C) 2012 Jean-Marc Valin
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <valgrind/memcheck.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+//#define COEF 0.0
+
+static float COEF[2] = {0.8, 0.9};
+//static float COEF[2] = {0.0, 0.};
+
+#define MAX_ENTRIES 16384
+
+void compute_weights2(const float *x, const float *xp, float *w, int ndim)
+{
+  w[0] = 30;
+  w[1] = 1;
+  if (x[1]<0)
+  {
+     w[0] *= .6;
+     w[1] *= .3;
+  }
+  if (x[1]<-10)
+  {
+     w[0] *= .3;
+     w[1] *= .3;
+  }
+  /* Higher weight if pitch is stable */
+  if (fabs(x[0]-xp[0])<.2)
+  {
+     w[0] *= 2;
+     w[1] *= 1.5;
+  } else if (fabs(x[0]-xp[0])>.5) /* Lower if not stable */
+  {
+     w[0] *= .5;
+  }
+
+  /* Lower weight for low energy */
+  if (x[1] < xp[1]-10)
+  {
+     w[1] *= .5;
+  }
+  if (x[1] < xp[1]-20)
+  {
+     w[1] *= .5;
+  }
+
+  //w[0] = 30;
+  //w[1] = 1;
+
+  /* Square the weights because it's applied on the squared error */
+  w[0] *= w[0];
+  w[1] *= w[1];
+
+}
+
+int find_nearest_weighted(const float *codebook, int nb_entries, float *x, const float *w, int ndim)
+{
+  int i, j;
+  float min_dist = 1e15;
+  int nearest = 0;
+
+  for (i=0;i<nb_entries;i++)
+  {
+    float dist=0;
+    for (j=0;j<ndim;j++)
+      dist += w[j]*(x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]);
+    if (dist<min_dist)
+    {
+      min_dist = dist;
+      nearest = i;
+    }
+  }
+  return nearest;
+}
+
+int quantize_ge(const float *x, const float *codebook1, int nb_entries, float *xq, int ndim)
+{
+  int i, n1;
+  float err[ndim];
+  float w[ndim];
+
+  compute_weights2(x, xq, w, ndim);
+
+  for (i=0;i<ndim;i++)
+    err[i] = x[i]-COEF[i]*xq[i];
+  n1 = find_nearest_weighted(codebook1, nb_entries, err, w, ndim);
+
+  for (i=0;i<ndim;i++)
+  {
+    xq[i] = COEF[i]*xq[i] + codebook1[ndim*n1+i];
+    err[i] -= codebook1[ndim*n1+i];
+  }
+  return 0;
+}
+
+void split(float *codebook, int nb_entries, int ndim)
+{
+  int i,j;
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim;j++)
+    {
+      float delta = .01*(rand()/(float)RAND_MAX-.5);
+      codebook[i*ndim+j] += delta;
+      codebook[(i+nb_entries)*ndim+j] = codebook[i*ndim+j] - delta;
+    }
+  }
+}
+
+
+void update_weighted(float *data, float *weight, int nb_vectors, float *codebook, int nb_entries, int ndim)
+{
+  int i,j;
+  float count[MAX_ENTRIES][ndim];
+  int nearest[nb_vectors];
+
+  //fprintf(stderr, "weighted: %d %d\n", nb_entries, ndim);
+  for (i=0;i<nb_entries;i++)
+    for (j=0;j<ndim;j++)
+      count[i][j] = 0;
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    nearest[i] = find_nearest_weighted(codebook, nb_entries, data+i*ndim, weight+i*ndim, ndim);
+  }
+  for (i=0;i<nb_entries*ndim;i++)
+    codebook[i] = 0;
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    int n = nearest[i];
+    for (j=0;j<ndim;j++)
+    {
+      float w = sqrt(weight[i*ndim+j]);
+      count[n][j]+=w;
+      codebook[n*ndim+j] += w*data[i*ndim+j];
+    }
+  }
+
+  //float w2=0;
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim;j++)
+      codebook[i*ndim+j] *= (1./count[i][j]);
+    //w2 += (count[i]/(float)nb_vectors)*(count[i]/(float)nb_vectors);
+  }
+  //fprintf(stderr, "%f / %d\n", 1./w2, nb_entries);
+}
+
+void vq_train_weighted(float *data, float *weight, int nb_vectors, float *codebook, int nb_entries, int ndim)
+{
+  int i, j, e;
+  e = 1;
+  for (j=0;j<ndim;j++)
+    codebook[j] = 0;
+  for (i=0;i<nb_vectors;i++)
+    for (j=0;j<ndim;j++)
+      codebook[j] += data[i*ndim+j];
+  for (j=0;j<ndim;j++)
+    codebook[j] *= (1./nb_vectors);
+
+
+  while (e< nb_entries)
+  {
+#if 1
+    split(codebook, e, ndim);
+    e<<=1;
+#else
+    split1(codebook, e, data, nb_vectors, ndim);
+    e++;
+#endif
+    fprintf(stderr, "%d\n", e);
+    for (j=0;j<10;j++)
+      update_weighted(data, weight, nb_vectors, codebook, e, ndim);
+  }
+}
+
+
+int main(int argc, char **argv)
+{
+  int i,j;
+  int nb_vectors, nb_entries, ndim;
+  float *data, *pred, *codebook, *codebook2, *codebook3;
+  float *weight, *weight2, *weight3;
+  float *delta;
+  double err[2] = {0, 0};
+  double werr[2] = {0, 0};
+  double wsum[2] = {0, 0};
+
+  ndim = atoi(argv[1]);
+  nb_vectors = atoi(argv[2]);
+  nb_entries = 1<<atoi(argv[3]);
+
+  data = malloc(nb_vectors*ndim*sizeof(*data));
+  weight = malloc(nb_vectors*ndim*sizeof(*weight));
+  weight2 = malloc(nb_vectors*ndim*sizeof(*weight2));
+  weight3 = malloc(nb_vectors*ndim*sizeof(*weight3));
+  pred = malloc(nb_vectors*ndim*sizeof(*pred));
+  codebook = malloc(nb_entries*ndim*sizeof(*codebook));
+  codebook2 = malloc(nb_entries*ndim*sizeof(*codebook2));
+  codebook3 = malloc(nb_entries*ndim*sizeof(*codebook3));
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    if (feof(stdin))
+      break;
+    for (j=0;j<ndim;j++)
+    {
+      scanf("%f ", &data[i*ndim+j]);
+    }
+  }
+  nb_vectors = i;
+  VALGRIND_CHECK_MEM_IS_DEFINED(data, nb_entries*ndim);
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    if (i==0)
+       compute_weights2(data+i*ndim, data+i*ndim, weight+i*ndim, ndim);
+    else
+       compute_weights2(data+i*ndim, data+(i-1)*ndim, weight+i*ndim, ndim);
+  }
+  for (i=0;i<ndim;i++)
+    pred[i] = data[i];
+  for (i=1;i<nb_vectors;i++)
+  {
+    for (j=0;j<ndim;j++)
+      pred[i*ndim+j] = data[i*ndim+j] - COEF[j]*data[(i-1)*ndim+j];
+  }
+
+  VALGRIND_CHECK_MEM_IS_DEFINED(pred, nb_entries*ndim);
+  vq_train_weighted(pred, weight, nb_vectors, codebook, nb_entries, ndim);
+  printf("%d %d\n", ndim, nb_entries);
+  for (i=0;i<nb_entries;i++)
+  {
+   for (j=0;j<ndim;j++)
+    {
+      printf("%f ", codebook[i*ndim+j]);
+    }
+    printf("\n");
+  }
+
+  delta = malloc(nb_vectors*ndim*sizeof(*data));
+  float xq[2] = {0,0};
+  for (i=0;i<nb_vectors;i++)
+  {
+    //int nearest = find_nearest_weighted(codebook, nb_entries, &pred[i*ndim], &weight[i*ndim], ndim);
+    quantize_ge(&data[i*ndim], codebook, nb_entries, xq, ndim);
+    //printf("%f %f\n", xq[0], xq[1]);
+    for (j=0;j<ndim;j++)
+    {
+      delta[i*ndim+j] = xq[j]-data[i*ndim+j];
+      err[j] += (delta[i*ndim+j])*(delta[i*ndim+j]);
+      werr[j] += weight[i*ndim+j]*(delta[i*ndim+j])*(delta[i*ndim+j]);
+      wsum[j] += weight[i*ndim+j];
+      //delta[i*ndim+j] = pred[i*ndim+j] - codebook[nearest*ndim+j];
+      //printf("%f ", delta[i*ndim+j]);
+      //err[j] += (delta[i*ndim+j])*(delta[i*ndim+j]);
+    }
+    //printf("\n");
+  }
+  fprintf(stderr, "GE RMS error: %f %f\n", sqrt(err[0]/nb_vectors), sqrt(err[1]/nb_vectors));
+  fprintf(stderr, "Weighted GE error: %f %f\n", sqrt(werr[0]/wsum[0]), sqrt(werr[1]/wsum[1]));
+
+  return 0;
+}
diff --git a/codec2/branches/0.7/unittest/genampdata.c b/codec2/branches/0.7/unittest/genampdata.c
new file mode 100644 (file)
index 0000000..3fa2d2e
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+  genampdata.c
+
+  Generates test sparse amplitude data for vqtrainsp testing.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include <assert.h>
+#include "../src/defines.h"
+
+typedef struct {
+    float real;
+    float imag;
+} COMP;
+
+#define NVEC 200000
+#define D    2
+#define E    8
+
+int main(void) {
+    FILE *f=fopen("testamp.flt", "wb");
+    int   i, m, L, index;
+    float amp, noisey_amp, pitch, Wo;
+    float sparse_pe[MAX_AMP];
+
+    #ifdef TEST1
+    /* D fixed amplitude vectors of E elements long,
+       with D=2, E=8:
+
+       $ ./vqtrainsp testamp.flt 2 8 test.txt
+
+       test.txt should be same as training data.
+    */
+    for(i=0; i<E; i++) {
+       amp = i+1;
+       for(int j=0; j<D; j++)
+           fwrite(&amp, sizeof(float), 1, f);
+    }
+    #endif
+
+    #ifdef TEST2
+    /*
+       Bunch of amps uniformly distributed between -1 and 1.  With e
+       entry "codebook" (1 dimensional vector or scalar):
+
+       $ ./vqtrainsp testamp.flt 1 e test.txt
+
+
+       should get std dev of 1/(e*sqrt(3))
+    */
+
+    for(i=0; i<NVEC; i++) {
+       amp = 1.0 - 2.0*rand()/RAND_MAX;
+       fwrite(&amp, sizeof(float), 1, f);
+    }
+    #endif
+
+    #define TEST3
+    #ifdef TEST3
+    /*
+       Data for testing training of spare amplitudes.  Similar to TEST1, each
+       sparse vector is set to the same amplitude.
+
+       /vqtrainsp testamp.flt 20 8 test.txt
+
+    */
+
+    for(i=0; i<NVEC; i++) {
+       for(amp=1.0; amp<=8.0; amp++) {
+           pitch = P_MIN + (P_MAX-P_MIN)*((float)rand()/RAND_MAX);
+           Wo = TWO_PI/pitch;
+           L = floor(PI/Wo);
+           //printf("pitch %f Wo %f L %d\n", pitch, Wo, L);
+
+           for(m=0; m<MAX_AMP; m++) {
+               sparse_pe[m] = 0.0;
+           }
+
+           for(m=1; m<=L; m++) {
+               index = MAX_AMP*m*Wo/PI;
+               assert(index < MAX_AMP);
+               noisey_amp = amp + 0.2*(1.0 - 2.0*rand()/RAND_MAX);
+               sparse_pe[index] = noisey_amp;
+               #ifdef DBG
+               if (m < MAX_AMP/8)
+                   printf(" %4.3f ", noisey_amp);
+               #endif
+           }
+            #ifdef DBG
+           printf("\n");
+           #endif
+
+           fwrite(sparse_pe, sizeof(float), MAX_AMP/8, f);
+       }
+    }
+
+    #endif
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/genlsp.c b/codec2/branches/0.7/unittest/genlsp.c
new file mode 100644 (file)
index 0000000..4d003cb
--- /dev/null
@@ -0,0 +1,183 @@
+/*--------------------------------------------------------------------------*\
+
+       FILE........: genlsp.c
+       AUTHOR......: David Rowe
+       DATE CREATED: 23/2/95
+
+       This program genrates a text file of LSP vectors from an input
+       speech file.
+
+\*--------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define P      12      /* LP order                                     */
+#define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */
+#define NW     279     /* frame size in samples                        */
+#define        N       80      /* frame to frame shift                         */
+#define THRESH 40.0    /* threshold energy/sample for frame inclusion  */
+#define PI         3.141592654 /* mathematical constant                */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "lpc.h"       /* LPC analysis functions                       */
+#include "lsp.h"       /* LSP encode/decode functions                  */
+
+int switch_present(sw,argc,argv)
+  char sw[];     /* switch in string form */
+  int argc;      /* number of command line arguments */
+  char *argv[];  /* array of command line arguments in string form */
+{
+  int i;       /* loop variable */
+
+  for(i=1; i<argc; i++)
+    if (!strcmp(sw,argv[i]))
+      return(i);
+
+  return 0;
+}
+
+int main(int argc, char *argv[]) {
+    FILE   *fspc;      /* input file ptr for test database             */
+    FILE   *flsp;      /* output text file of LSPs                     */
+    short  buf[N];     /* input frame of speech samples                */
+    float  Sn[NW];     /* float input speech samples                   */
+    float  ak[P+1];    /* LPCs for current frame                       */
+    float  lsp[P];     /* LSPs for current frame                       */
+    float  lsp_prev[P];        /* LSPs for previous frame                      */
+    float  E;          /* frame energy                                 */
+    long   f;          /* number of frames                             */
+    long   af;         /* number frames with "active" speech           */
+    float  Eres;       /* LPC residual energy                          */
+    int    i;
+    int    roots;
+    int    unstables;
+    int    lspd, log, lspdt;
+    float  diff;
+
+    /* Initialise ------------------------------------------------------*/
+
+    if (argc < 3) {
+       printf("usage: %s RawFile LSPTextFile [--lspd] [--log] [--lspdt] \n", argv[0]);
+       exit(1);
+    }
+
+    /* Open files */
+
+    fspc = fopen(argv[1],"rb");
+    if (fspc == NULL) {
+       printf("Error opening input SPC file: %s",argv[1]);
+       exit(1);
+    }
+
+    flsp = fopen(argv[2],"wt");
+    if (flsp == NULL) {
+       printf("Error opening output LSP file: %s",argv[2]);
+       exit(1);
+    }
+
+    lspd = switch_present("--lspd", argc, argv);
+    log = switch_present("--log", argc, argv);
+    lspdt = switch_present("--lspdt", argc, argv);
+
+    for(i=0; i<NW; i++)
+       Sn[i] = 0.0;
+
+    /* Read SPC file, and determine aks[] for each frame ------------------*/
+
+    f = af = 0;
+    unstables = 0;
+    while(fread(buf,sizeof(short),N,fspc) == N) {
+
+       for(i=0; i<NW-N; i++)
+           Sn[i] = Sn[i+N];
+       E = 0.0;
+       for(i=0; i<N; i++) {
+           Sn[i+NW-N] = buf[i];
+           E += Sn[i]*Sn[i];
+       }
+
+       E = 0.0;
+       for(i=0; i<NW; i++) {
+           E += Sn[i]*Sn[i];
+       }
+       E = 10.0*log10(E/NW);
+
+       /* If energy high enough, include this frame */
+
+       f++;
+       if (E > THRESH) {
+           af++;
+           printf("Active Frame: %ld  unstables: %d\n",af, unstables);
+
+           find_aks(Sn, ak, NW, P, &Eres);
+           roots = lpc_to_lsp(ak, P , lsp, 5, LSP_DELTA1);
+           if (roots == P) {
+               if (lspd) {
+                   if (log) {
+                       fprintf(flsp,"%f ",log10(lsp[0]));
+                       for(i=1; i<P; i++) {
+                           diff = lsp[i]-lsp[i-1];
+                           if (diff < (PI/4000.0)*25.0) diff = (PI/4000.0)*25.0;
+                           fprintf(flsp,"%f ",log10(diff));
+                       }
+                   }
+                   else {
+                       fprintf(flsp,"%f ",lsp[0]);
+                       for(i=1; i<P; i++)
+                           fprintf(flsp,"%f ",lsp[i]-lsp[i-1]);
+                   }
+
+                   fprintf(flsp,"\n");
+
+               }
+               else if (lspdt) {
+                   for(i=0; i<P; i++)
+                       fprintf(flsp,"%f ",lsp[i]-lsp_prev[i]);
+                   fprintf(flsp,"\n");
+
+               }
+               else {
+                   if (log) {
+                       for(i=0; i<P; i++)
+                           fprintf(flsp,"%f ",log10(lsp[i]));
+                       fprintf(flsp,"\n");
+                   }
+                   else {
+                       for(i=0; i<P; i++)
+                           fprintf(flsp,"%f ",lsp[i]);
+                       fprintf(flsp,"\n");
+                   }
+
+               }
+               memcpy(lsp_prev, lsp, sizeof(lsp));
+           }
+           else
+               unstables++;
+       }
+    }
+
+    printf("%3.2f %% active frames\n", 100.0*(float)af/f);
+    fclose(fspc);
+    fclose(flsp);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/genphdata.c b/codec2/branches/0.7/unittest/genphdata.c
new file mode 100644 (file)
index 0000000..2e0ce22
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+  genphdata.c
+
+  Generates test phase data for vqtrainph testing.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include <assert.h>
+#include "../src/defines.h"
+
+typedef struct {
+    float real;
+    float imag;
+} COMP;
+
+#define NVEC 100000
+#define D    2
+#define E    8
+
+int main(void) {
+    FILE *f=fopen("testph.flt", "wb");
+    int   i, m, L, index;
+    float angle, noisey_angle, pitch, Wo;
+    COMP  sparse_pe[MAX_AMP];
+
+    #ifdef TEST1
+    COMP  c;
+    for(i=0; i<D*E; i++) {
+       c.real = cos(i*TWO_PI/(M*D));
+       c.imag = sin(i*TWO_PI/(M*D));
+       fwrite(&c, sizeof(COMP), 1, f);
+    }
+    #endif
+
+    #ifdef TEST2
+    /*
+       Bunch of random phases, should get std dev per element of
+       pi/(sqrt(3)*pow(2,b/D)), or 0.321 for (b=5, D=2):
+
+       ./vqtrainph testph.flt 2 32 test.txt
+    */
+
+    for(i=0; i<NVEC; i++) {
+       angle = PI*(1.0 - 2.0*rand()/RAND_MAX);
+       c.real = cos(angle);
+       c.imag = sin(angle);
+       fwrite(&c, sizeof(COMP), 1, f);
+    }
+    #endif
+
+    #define TEST3
+    #ifdef TEST3
+    /*
+       Data for testing training in sparse phases. No correlation, so
+       should be same performance as TEST2.  Attempting to train a
+       MAX_AMP/4 = 20 (first 1 kHz) phase quantiser.
+
+    */
+
+    angle = 0;
+    for(i=0; i<NVEC; i++) {
+       pitch = P_MIN + (P_MAX-P_MIN)*((float)rand()/RAND_MAX);
+       //pitch = 40;
+       Wo = TWO_PI/pitch;
+       L = floor(PI/Wo);
+       //printf("pitch %f Wo %f L %d\n", pitch, Wo, L);
+
+       for(m=0; m<MAX_AMP; m++) {
+           sparse_pe[m].real = 0.0;
+           sparse_pe[m].imag = 0.0;
+       }
+
+       angle += PI/8;
+       for(m=1; m<=L; m++) {
+           noisey_angle = angle + (PI/16)*(1.0 - 2.0*rand()/RAND_MAX);
+           //angle = (PI/16)*(1.0 - 2.0*rand()/RAND_MAX);
+           index = MAX_AMP*m*Wo/PI;
+           assert(index < MAX_AMP);
+           sparse_pe[index].real = cos(noisey_angle);
+           sparse_pe[index].imag = sin(noisey_angle);
+       }
+
+       fwrite(&sparse_pe, sizeof(COMP), MAX_AMP/4, f);
+    }
+
+    #endif
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/genres.c b/codec2/branches/0.7/unittest/genres.c
new file mode 100644 (file)
index 0000000..9068781
--- /dev/null
@@ -0,0 +1,99 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: genres.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/8/09
+
+  Generates a file of LPC residual samples from original speech.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <lpc.h>
+
+#define N 160
+#define P 1
+
+int main(int argc, char *argv[])
+{
+  FILE *fin,*fres;      /* input and output files */
+  short buf[N];         /* buffer of 16 bit speech samples */
+  float Sn[P+N];        /* input speech samples */
+  float res[N];         /* residual after LPC filtering */
+  float E;
+  float ak[P+1];        /* LP coeffs */
+
+  int frames;           /* frames processed so far */
+  int i;                /* loop variables */
+
+  if (argc < 3) {
+    printf("usage: %s InputFile ResidualFile\n", argv[0]);
+    exit(1);
+  }
+
+  /* Open files */
+
+  if (strcmp(argv[1], "-")  == 0) fin = stdin;
+  else if ((fin = fopen(argv[1],"rb")) == NULL) {
+    printf("Error opening input file: %s\n",argv[1]);
+    exit(0);
+  }
+
+  if (strcmp(argv[2], "-") == 0) fres = stdout;
+  else if ((fres = fopen(argv[2],"wb")) == NULL) {
+    printf("Error opening output residual file: %s\n",argv[2]);
+    exit(0);
+  }
+
+  /* Initialise */
+
+  frames = 0;
+  for(i=0; i<P; i++) {
+    Sn[i] = 0.0;
+  }
+
+  /* Main loop */
+
+  while( (fread(buf,sizeof(short),N,fin)) == N) {
+    frames++;
+    for(i=0; i<P; i++)
+      Sn[i] = Sn[i+N];
+    for(i=0; i<N; i++)
+      Sn[P+i] = (float)buf[i];
+
+    /* Determine {ak} and filter to find residual */
+
+    find_aks(&Sn[P], ak, N, P, &E);
+    inverse_filter(&Sn[P], ak, N, res, P);
+    for(i=0; i<N; i++)
+      buf[i] = (short)res[i];
+    fwrite(buf,sizeof(short),N,fres);
+
+    if (fres == stdout) fflush(stdout);
+    if (fin == stdin) fflush(stdin);
+  }
+
+  fclose(fin);
+  fclose(fres);
+
+  return 0;
+}
diff --git a/codec2/branches/0.7/unittest/hts1a.h b/codec2/branches/0.7/unittest/hts1a.h
new file mode 100644 (file)
index 0000000..2e40397
--- /dev/null
@@ -0,0 +1,8002 @@
+short hts1a_raw[] = {
+-14,
+-14,
+-8,
+-7,
+-11,
+-15,
+-14,
+-16,
+-24,
+-26,
+-25,
+-26,
+-22,
+-22,
+-24,
+-19,
+-19,
+-19,
+-26,
+-28,
+-28,
+-21,
+-16,
+-14,
+-19,
+-19,
+-18,
+-18,
+-16,
+-18,
+-26,
+-28,
+-35,
+-28,
+-19,
+-12,
+-12,
+-14,
+-15,
+-21,
+-16,
+-12,
+-9,
+-11,
+-5,
+-8,
+-7,
+-5,
+-8,
+-8,
+-7,
+3,
+3,
+-1,
+-2,
+-5,
+-1,
+-7,
+-5,
+-4,
+-4,
+-7,
+-5,
+-9,
+-8,
+-12,
+-21,
+-21,
+-28,
+-28,
+-24,
+-25,
+-29,
+-29,
+-31,
+-32,
+-28,
+-31,
+-35,
+-26,
+-35,
+-31,
+-28,
+-32,
+-26,
+-21,
+-22,
+-16,
+-15,
+-14,
+-18,
+-12,
+-19,
+-12,
+-12,
+-16,
+-15,
+-16,
+-16,
+-16,
+-12,
+-15,
+-12,
+-18,
+-18,
+-15,
+-19,
+-18,
+-16,
+-14,
+-15,
+-16,
+-16,
+-16,
+-14,
+-16,
+-11,
+-4,
+-8,
+-8,
+-9,
+-8,
+-15,
+-12,
+-11,
+-12,
+-9,
+-11,
+-8,
+-11,
+-14,
+-11,
+-18,
+-16,
+-14,
+-14,
+-9,
+-5,
+-8,
+-15,
+-16,
+-14,
+-16,
+-18,
+-15,
+-31,
+-32,
+-19,
+-15,
+-12,
+-16,
+-15,
+-18,
+-14,
+-12,
+-12,
+-16,
+-24,
+-25,
+-19,
+-18,
+-22,
+-21,
+-19,
+-16,
+-16,
+-14,
+-16,
+-24,
+-24,
+-19,
+-24,
+-24,
+-19,
+-21,
+-24,
+-25,
+-28,
+-25,
+-25,
+-26,
+-18,
+-12,
+-22,
+-25,
+-26,
+-25,
+-24,
+-24,
+-22,
+-21,
+-19,
+-16,
+-15,
+-12,
+-12,
+-14,
+-8,
+-12,
+-11,
+-5,
+-1,
+0,
+0,
+-1,
+-4,
+-4,
+-5,
+-7,
+-7,
+-11,
+-8,
+-11,
+-5,
+-4,
+-2,
+-8,
+-5,
+-12,
+-14,
+-14,
+-14,
+-12,
+-12,
+-7,
+-16,
+-21,
+-22,
+-22,
+-25,
+-28,
+-24,
+-31,
+-32,
+-33,
+-33,
+-35,
+-31,
+-29,
+-32,
+-36,
+-36,
+-35,
+-35,
+-32,
+-26,
+-35,
+-29,
+-22,
+-18,
+-11,
+-16,
+-14,
+-14,
+-11,
+-8,
+-8,
+-12,
+-11,
+-24,
+-25,
+-12,
+-8,
+-7,
+-9,
+-5,
+-9,
+-8,
+-4,
+-7,
+-5,
+-11,
+-11,
+-4,
+-5,
+-5,
+-8,
+-4,
+-8,
+-4,
+-8,
+-14,
+-8,
+-9,
+-12,
+-11,
+-15,
+-22,
+-21,
+-19,
+-22,
+-15,
+-22,
+-18,
+-15,
+-16,
+-18,
+-12,
+-14,
+-21,
+-19,
+-16,
+-19,
+-21,
+-22,
+-21,
+-25,
+-19,
+-26,
+-21,
+-19,
+-21,
+-19,
+-16,
+-15,
+-18,
+-9,
+-8,
+-9,
+-8,
+-14,
+-19,
+-15,
+-16,
+-16,
+-16,
+-12,
+-11,
+-12,
+-11,
+-11,
+-7,
+-19,
+-18,
+-14,
+-28,
+-28,
+-26,
+-28,
+-31,
+-31,
+-24,
+-25,
+-26,
+-29,
+-28,
+-31,
+-28,
+-24,
+-21,
+-19,
+-21,
+-16,
+-24,
+-24,
+-18,
+-16,
+-19,
+-12,
+-9,
+-12,
+-14,
+-12,
+-7,
+-9,
+-9,
+-5,
+-5,
+-9,
+-7,
+-5,
+-5,
+-4,
+-21,
+-25,
+-12,
+-5,
+5,
+10,
+10,
+-1,
+-2,
+3,
+-4,
+-7,
+-8,
+-5,
+-11,
+-12,
+-25,
+-26,
+-24,
+-33,
+-32,
+-29,
+-35,
+-36,
+-33,
+-38,
+-42,
+-38,
+-38,
+-36,
+-36,
+-33,
+-32,
+-38,
+-32,
+-28,
+-22,
+-18,
+-14,
+-9,
+-15,
+-9,
+-8,
+-11,
+-2,
+-2,
+-5,
+-2,
+3,
+-2,
+-1,
+-4,
+-7,
+-12,
+-12,
+-12,
+-16,
+-15,
+-11,
+-11,
+-8,
+-7,
+-5,
+-9,
+-12,
+-12,
+-18,
+-19,
+-26,
+-26,
+-22,
+-22,
+-24,
+-21,
+-15,
+-12,
+-14,
+-18,
+-16,
+-15,
+-26,
+-26,
+-28,
+-26,
+-26,
+-25,
+-28,
+-25,
+-14,
+-12,
+-14,
+-18,
+-24,
+-14,
+-9,
+-5,
+-7,
+-9,
+-7,
+-8,
+-14,
+-11,
+-8,
+-15,
+-8,
+-7,
+-5,
+-2,
+-5,
+-5,
+-8,
+-15,
+-15,
+-16,
+-33,
+-35,
+-25,
+-15,
+-14,
+-18,
+-22,
+-18,
+-22,
+-24,
+-29,
+-31,
+-32,
+-33,
+-31,
+-36,
+-31,
+-25,
+-31,
+-33,
+-28,
+-26,
+-22,
+-25,
+-25,
+-16,
+-18,
+-16,
+-15,
+-15,
+-14,
+-11,
+-7,
+-5,
+-4,
+-8,
+-4,
+-5,
+-8,
+-4,
+0,
+-7,
+-1,
+-1,
+-9,
+-11,
+-12,
+-14,
+-15,
+-9,
+-8,
+-7,
+-5,
+-11,
+-12,
+-12,
+-19,
+-15,
+-16,
+-16,
+-12,
+-18,
+-19,
+-19,
+-18,
+-15,
+-19,
+-24,
+-19,
+-25,
+-28,
+-26,
+-26,
+-26,
+-28,
+-26,
+-22,
+-21,
+-25,
+-19,
+-16,
+-16,
+-9,
+-9,
+-12,
+-7,
+-11,
+-7,
+-12,
+-15,
+-18,
+-24,
+-16,
+-16,
+-12,
+-19,
+-18,
+-16,
+-25,
+-24,
+-22,
+-25,
+-21,
+-25,
+-24,
+-24,
+-19,
+-15,
+-26,
+-19,
+-14,
+-19,
+-16,
+-18,
+-26,
+-28,
+-16,
+-4,
+10,
+15,
+12,
+13,
+10,
+8,
+8,
+-7,
+-11,
+-19,
+-29,
+-31,
+-33,
+-29,
+-26,
+-26,
+-26,
+-22,
+-15,
+-16,
+-15,
+-19,
+-18,
+-19,
+-12,
+-15,
+-21,
+-21,
+-24,
+-22,
+-19,
+-19,
+-15,
+-16,
+-16,
+-24,
+-18,
+-25,
+-24,
+-24,
+-26,
+-21,
+-22,
+-22,
+-18,
+-16,
+-19,
+-22,
+-22,
+-19,
+-24,
+-19,
+-16,
+-19,
+-15,
+-16,
+-12,
+-4,
+-9,
+-19,
+-12,
+-15,
+-19,
+-16,
+-16,
+-15,
+-14,
+-12,
+-12,
+-11,
+-8,
+-9,
+-9,
+-12,
+-11,
+-11,
+-8,
+-9,
+-5,
+5,
+-1,
+-1,
+-4,
+-8,
+-8,
+-8,
+-9,
+-8,
+-7,
+-11,
+-19,
+-19,
+-18,
+-26,
+-21,
+-24,
+-24,
+-26,
+-35,
+-32,
+-36,
+-31,
+-26,
+-28,
+-26,
+-25,
+-22,
+-26,
+-35,
+-35,
+-36,
+-45,
+-45,
+-33,
+-28,
+-19,
+-16,
+-9,
+-14,
+-12,
+-5,
+-11,
+-8,
+-7,
+-5,
+-5,
+2,
+-2,
+-5,
+0,
+-7,
+-5,
+-11,
+-14,
+-14,
+-8,
+-8,
+-7,
+-9,
+-11,
+-11,
+-15,
+-15,
+-14,
+-12,
+-14,
+-18,
+-16,
+-9,
+-12,
+-12,
+-14,
+-16,
+-22,
+-25,
+-26,
+-31,
+-29,
+-26,
+-29,
+-25,
+-22,
+-19,
+-18,
+-24,
+-21,
+-24,
+-19,
+-12,
+-15,
+-15,
+-16,
+-15,
+-14,
+-16,
+-15,
+-16,
+-24,
+-19,
+-22,
+-26,
+-24,
+-19,
+-18,
+-19,
+-15,
+-11,
+-5,
+-2,
+-2,
+-4,
+-7,
+-4,
+-8,
+-8,
+-11,
+-15,
+-11,
+-9,
+-7,
+-9,
+-4,
+2,
+-8,
+-1,
+-2,
+-12,
+-9,
+-15,
+-21,
+-31,
+-38,
+-32,
+-32,
+-35,
+-31,
+-28,
+-33,
+-32,
+-35,
+-33,
+-33,
+-36,
+-36,
+-42,
+-45,
+-43,
+-33,
+-29,
+-25,
+-21,
+-14,
+-12,
+-11,
+-16,
+-15,
+-12,
+-14,
+-15,
+-15,
+-9,
+-2,
+-2,
+0,
+-5,
+-4,
+-2,
+0,
+8,
+9,
+10,
+12,
+3,
+6,
+5,
+9,
+3,
+-7,
+-9,
+-25,
+-32,
+-25,
+-11,
+-1,
+2,
+-1,
+-9,
+-15,
+-12,
+-15,
+-21,
+-29,
+-35,
+-39,
+-39,
+-31,
+-33,
+-33,
+-26,
+-28,
+-29,
+-31,
+-33,
+-26,
+-24,
+-22,
+-24,
+-21,
+-18,
+-15,
+-18,
+-26,
+-25,
+-22,
+-18,
+-21,
+-24,
+-26,
+-35,
+-28,
+-26,
+-26,
+-24,
+-22,
+-16,
+-18,
+-22,
+-15,
+-22,
+-24,
+-16,
+-14,
+-11,
+-4,
+3,
+5,
+3,
+8,
+8,
+6,
+0,
+6,
+3,
+-5,
+0,
+6,
+-5,
+-5,
+-8,
+-11,
+-14,
+-19,
+-21,
+-24,
+-25,
+-28,
+-28,
+-22,
+-28,
+-38,
+-38,
+-26,
+-26,
+-22,
+-32,
+-31,
+-26,
+-18,
+-12,
+-11,
+-9,
+-16,
+-21,
+-19,
+-16,
+-16,
+-18,
+-12,
+-12,
+-8,
+-7,
+-15,
+-16,
+-16,
+-19,
+-21,
+-22,
+-22,
+-22,
+-25,
+-32,
+-29,
+-35,
+-32,
+-33,
+-33,
+-29,
+-25,
+-18,
+-15,
+-16,
+-12,
+-12,
+-8,
+-2,
+0,
+6,
+2,
+0,
+5,
+2,
+-5,
+-1,
+-5,
+-8,
+-8,
+-8,
+-9,
+-15,
+-12,
+-11,
+-5,
+-9,
+-18,
+-19,
+-22,
+-16,
+-14,
+-11,
+-2,
+-2,
+-8,
+-16,
+-21,
+-22,
+-19,
+-24,
+-24,
+-16,
+-16,
+-12,
+-7,
+-8,
+-5,
+-8,
+-16,
+-24,
+-29,
+-35,
+-36,
+-36,
+-38,
+-41,
+-38,
+-43,
+-41,
+-39,
+-35,
+-32,
+-31,
+-32,
+-32,
+-28,
+-24,
+-24,
+-19,
+-16,
+-18,
+-12,
+-2,
+-1,
+5,
+5,
+-9,
+-25,
+-21,
+-15,
+-14,
+-15,
+-14,
+-18,
+-16,
+-12,
+-11,
+-5,
+-2,
+-7,
+-11,
+-7,
+-18,
+-11,
+-5,
+-2,
+0,
+-2,
+0,
+0,
+-5,
+-11,
+-14,
+-12,
+-14,
+-14,
+-16,
+-18,
+-18,
+-29,
+-38,
+-38,
+-42,
+-46,
+-38,
+-35,
+-32,
+-31,
+-16,
+-5,
+0,
+12,
+19,
+20,
+17,
+20,
+20,
+16,
+16,
+12,
+5,
+-7,
+-15,
+-14,
+-22,
+-25,
+-26,
+-26,
+-32,
+-38,
+-43,
+-45,
+-49,
+-55,
+-56,
+-52,
+-56,
+-48,
+-39,
+-33,
+-28,
+-31,
+-24,
+-29,
+-32,
+-26,
+-16,
+-7,
+-14,
+-11,
+-11,
+-16,
+-18,
+-29,
+-28,
+-24,
+-14,
+-11,
+-15,
+-4,
+-11,
+-12,
+-5,
+-2,
+3,
+5,
+2,
+10,
+5,
+6,
+2,
+-1,
+-7,
+-7,
+-12,
+-14,
+-16,
+-22,
+-21,
+-18,
+-19,
+-22,
+-11,
+-1,
+3,
+2,
+2,
+3,
+6,
+-2,
+-7,
+-15,
+-18,
+-24,
+-26,
+-31,
+-38,
+-41,
+-39,
+-36,
+-39,
+-33,
+-26,
+-24,
+-18,
+-19,
+-21,
+-19,
+-18,
+-16,
+-21,
+-21,
+-15,
+-14,
+-18,
+-24,
+-25,
+-31,
+-38,
+-43,
+-45,
+-46,
+-43,
+-39,
+-33,
+-28,
+-19,
+-11,
+-8,
+-4,
+5,
+12,
+12,
+17,
+16,
+9,
+9,
+10,
+6,
+8,
+-4,
+3,
+0,
+-5,
+-11,
+-14,
+-28,
+-26,
+-15,
+-24,
+-32,
+-32,
+-28,
+-32,
+-28,
+-18,
+-22,
+-22,
+-15,
+-15,
+-24,
+-25,
+-26,
+-25,
+-16,
+-16,
+-18,
+-22,
+-21,
+-26,
+-29,
+-25,
+-22,
+-19,
+-16,
+-9,
+-4,
+2,
+6,
+10,
+3,
+2,
+0,
+-7,
+-7,
+-14,
+-16,
+-15,
+-22,
+-26,
+-29,
+-25,
+-25,
+-22,
+-29,
+-35,
+-25,
+-19,
+-14,
+-15,
+-12,
+-15,
+-26,
+-24,
+-29,
+-28,
+-26,
+-26,
+-29,
+-32,
+-38,
+-42,
+-38,
+-33,
+-29,
+-25,
+-25,
+-21,
+-14,
+-5,
+5,
+6,
+8,
+6,
+2,
+0,
+-1,
+-9,
+-16,
+-18,
+-19,
+-22,
+-22,
+-21,
+-15,
+-18,
+-22,
+-11,
+-8,
+-11,
+-7,
+5,
+2,
+-2,
+-4,
+-5,
+-7,
+-5,
+6,
+-7,
+-9,
+-8,
+-19,
+-22,
+-24,
+-26,
+-29,
+-33,
+-29,
+-25,
+-24,
+-21,
+-21,
+-24,
+-29,
+-28,
+-26,
+-25,
+-21,
+-26,
+-26,
+-25,
+-31,
+-31,
+-38,
+-39,
+-38,
+-33,
+-21,
+-9,
+-5,
+-4,
+5,
+3,
+-2,
+-7,
+-8,
+-9,
+-15,
+-16,
+-16,
+-22,
+-21,
+-24,
+-24,
+-16,
+-22,
+-21,
+-24,
+-26,
+-22,
+-16,
+-9,
+-11,
+-2,
+6,
+2,
+-4,
+-9,
+-16,
+-21,
+-21,
+-21,
+-24,
+-22,
+-22,
+-19,
+-18,
+-16,
+-12,
+-14,
+-12,
+-4,
+-2,
+-4,
+-8,
+-5,
+-5,
+-11,
+0,
+2,
+-7,
+-8,
+-12,
+-14,
+-19,
+-24,
+-25,
+-28,
+-9,
+-5,
+-29,
+-33,
+-22,
+-22,
+-21,
+-15,
+-18,
+-24,
+-21,
+-26,
+-29,
+-25,
+-33,
+-29,
+-29,
+-29,
+-31,
+-28,
+-28,
+-25,
+-24,
+-21,
+-25,
+-14,
+-7,
+-5,
+-16,
+-19,
+-21,
+-28,
+-33,
+-38,
+-36,
+-26,
+-25,
+-22,
+-8,
+-5,
+0,
+5,
+10,
+16,
+13,
+10,
+8,
+5,
+-4,
+-1,
+-7,
+-11,
+-18,
+-28,
+-31,
+-42,
+-43,
+-38,
+-38,
+-22,
+-11,
+-8,
+-7,
+6,
+6,
+3,
+13,
+8,
+-7,
+-2,
+-9,
+-16,
+-11,
+-15,
+-18,
+-24,
+-28,
+-24,
+-25,
+-22,
+-25,
+-28,
+-25,
+-38,
+-39,
+-35,
+-36,
+-14,
+-25,
+-42,
+-16,
+-9,
+-29,
+-28,
+-26,
+-31,
+-29,
+-39,
+-29,
+-12,
+-7,
+-1,
+-2,
+-4,
+0,
+2,
+-5,
+-15,
+-21,
+-35,
+-32,
+-22,
+-19,
+-18,
+-19,
+-5,
+6,
+0,
+-14,
+-26,
+-11,
+0,
+-19,
+-24,
+-24,
+-25,
+-25,
+-31,
+-35,
+-32,
+-19,
+-5,
+-7,
+-1,
+0,
+6,
+8,
+0,
+-8,
+-5,
+9,
+9,
+6,
+2,
+9,
+13,
+-7,
+-26,
+-36,
+-35,
+-42,
+-56,
+-49,
+-42,
+-42,
+-36,
+-28,
+-12,
+-12,
+-21,
+-18,
+-24,
+-19,
+-22,
+-25,
+-24,
+-21,
+-18,
+-15,
+-15,
+-8,
+-7,
+3,
+-4,
+-11,
+-22,
+-22,
+-16,
+-24,
+-21,
+-7,
+-22,
+-31,
+-16,
+-21,
+-11,
+-12,
+-21,
+-26,
+-28,
+-19,
+-28,
+-31,
+-25,
+-38,
+-38,
+-29,
+-33,
+-38,
+-33,
+-9,
+10,
+19,
+5,
+-4,
+-4,
+-1,
+-12,
+-21,
+-18,
+-16,
+-16,
+-19,
+-8,
+-5,
+-7,
+-2,
+0,
+12,
+16,
+15,
+2,
+-14,
+-12,
+-22,
+-29,
+-42,
+-36,
+-25,
+-16,
+-18,
+-19,
+-12,
+6,
+2,
+2,
+9,
+-4,
+-11,
+-19,
+-25,
+-24,
+-28,
+-35,
+-43,
+-35,
+-25,
+-41,
+-45,
+-42,
+-39,
+-35,
+-41,
+-33,
+-29,
+-18,
+-2,
+-19,
+-32,
+-12,
+3,
+-8,
+-11,
+-26,
+-35,
+-29,
+-29,
+-24,
+-15,
+-9,
+-8,
+-1,
+2,
+0,
+-1,
+-2,
+2,
+-1,
+-8,
+-9,
+-18,
+-21,
+-26,
+-32,
+-35,
+-26,
+-15,
+-9,
+-7,
+-2,
+-2,
+2,
+13,
+12,
+-2,
+-11,
+-15,
+-18,
+-28,
+-29,
+-24,
+-28,
+-32,
+-31,
+-28,
+-15,
+-9,
+-21,
+-4,
+10,
+-7,
+-5,
+-14,
+-18,
+-9,
+-21,
+-25,
+-29,
+-32,
+-36,
+-31,
+-16,
+-24,
+-18,
+-18,
+-22,
+-25,
+-32,
+-31,
+-12,
+-8,
+-8,
+2,
+-2,
+15,
+9,
+-14,
+-9,
+-9,
+0,
+-1,
+-22,
+-24,
+-18,
+-32,
+-29,
+-29,
+-39,
+-33,
+-24,
+-41,
+-33,
+-18,
+-33,
+-28,
+-32,
+-28,
+-24,
+-35,
+-32,
+-24,
+-21,
+-14,
+-21,
+-25,
+-18,
+-9,
+-8,
+-11,
+0,
+3,
+5,
+-5,
+-14,
+-19,
+-15,
+-9,
+2,
+-2,
+0,
+12,
+10,
+19,
+22,
+8,
+-2,
+-5,
+-9,
+-22,
+-16,
+-5,
+-16,
+-21,
+-19,
+-16,
+-16,
+-26,
+-29,
+-28,
+-25,
+-1,
+-2,
+-15,
+-19,
+-29,
+-35,
+-35,
+-38,
+-36,
+-38,
+-29,
+-46,
+-56,
+-38,
+-45,
+-62,
+-55,
+-48,
+-33,
+-42,
+-79,
+-93,
+33,
+207,
+203,
+112,
+30,
+-29,
+-28,
+-70,
+-148,
+-176,
+-96,
+-69,
+-87,
+-32,
+-45,
+-24,
+46,
+64,
+76,
+46,
+43,
+60,
+39,
+20,
+12,
+6,
+-35,
+-26,
+-28,
+-67,
+-8,
+-18,
+-55,
+6,
+-38,
+-75,
+-24,
+-5,
+-5,
+-25,
+-25,
+-35,
+22,
+93,
+23,
+-28,
+-55,
+-83,
+-42,
+-83,
+-103,
+-56,
+-22,
+44,
+3,
+-33,
+6,
+8,
+12,
+17,
+-5,
+-131,
+-189,
+100,
+265,
+40,
+49,
+135,
+-59,
+12,
+51,
+-123,
+-87,
+-182,
+-298,
+-226,
+-192,
+-205,
+-198,
+-49,
+30,
+39,
+183,
+238,
+183,
+141,
+187,
+132,
+83,
+176,
+16,
+-116,
+-90,
+-118,
+-138,
+-189,
+-123,
+-137,
+-147,
+-9,
+-28,
+49,
+125,
+66,
+29,
+43,
+46,
+-70,
+-100,
+-75,
+-121,
+-117,
+-109,
+-58,
+-28,
+29,
+77,
+74,
+128,
+118,
+63,
+12,
+56,
+158,
+90,
+0,
+-29,
+-127,
+-103,
+-33,
+-137,
+-140,
+-18,
+-43,
+-66,
+-7,
+-45,
+-73,
+6,
+42,
+-35,
+-111,
+-104,
+-92,
+-147,
+-526,
+-1264,
+-1575,
+-765,
+438,
+997,
+1207,
+1339,
+1320,
+1748,
+2310,
+2055,
+1176,
+299,
+-434,
+-1009,
+-1257,
+-1632,
+-2439,
+-2960,
+-2928,
+-2615,
+-2054,
+-1308,
+-736,
+-303,
+445,
+1377,
+2112,
+2587,
+2728,
+2464,
+2061,
+1838,
+1525,
+888,
+182,
+-511,
+-1203,
+-1516,
+-1425,
+-1447,
+-1556,
+-1386,
+-1076,
+-642,
+-16,
+437,
+547,
+662,
+915,
+1092,
+1055,
+883,
+519,
+53,
+-259,
+-472,
+-771,
+-1037,
+-1070,
+-981,
+-814,
+-511,
+-203,
+2,
+251,
+519,
+616,
+631,
+648,
+582,
+476,
+391,
+271,
+-18,
+-305,
+-348,
+-399,
+-478,
+-389,
+-348,
+-351,
+-222,
+-121,
+-386,
+-1735,
+-3442,
+-2533,
+573,
+2049,
+2601,
+3434,
+2708,
+2736,
+4175,
+4209,
+2551,
+296,
+-1119,
+-2477,
+-3494,
+-3361,
+-4179,
+-5485,
+-5636,
+-4580,
+-3316,
+-2031,
+-22,
+1181,
+1763,
+3271,
+4874,
+5510,
+5224,
+4612,
+3186,
+1425,
+652,
+-147,
+-1598,
+-2834,
+-3484,
+-3818,
+-3613,
+-2537,
+-1594,
+-1278,
+-574,
+734,
+1997,
+2818,
+3281,
+3233,
+2488,
+1960,
+1561,
+520,
+-672,
+-1616,
+-2288,
+-2651,
+-2450,
+-2115,
+-2137,
+-1772,
+-998,
+-341,
+312,
+891,
+1208,
+1322,
+1574,
+1687,
+1285,
+810,
+427,
+-18,
+-404,
+-664,
+-1030,
+-1306,
+-1064,
+-656,
+-397,
+-182,
+-16,
+170,
+514,
+922,
+1023,
+956,
+915,
+626,
+-42,
+-1701,
+-4508,
+-5074,
+-1033,
+2559,
+2488,
+3256,
+3525,
+2940,
+5224,
+6208,
+3992,
+-50,
+-2480,
+-3034,
+-4628,
+-4714,
+-5427,
+-7560,
+-7667,
+-5645,
+-2855,
+-1414,
+621,
+2572,
+3066,
+5038,
+7469,
+7951,
+6155,
+4438,
+2841,
+544,
+-373,
+-1233,
+-3376,
+-5177,
+-5271,
+-4414,
+-3653,
+-2121,
+-788,
+-392,
+720,
+2701,
+3972,
+4022,
+3914,
+3451,
+2206,
+1426,
+796,
+-632,
+-2163,
+-3381,
+-4159,
+-4113,
+-3045,
+-1776,
+-1312,
+-743,
+275,
+1098,
+1851,
+2335,
+2131,
+1527,
+1259,
+1200,
+713,
+73,
+-516,
+-1176,
+-1677,
+-1755,
+-1672,
+-1670,
+-1336,
+-625,
+37,
+718,
+1435,
+1620,
+1412,
+1445,
+1137,
+438,
+388,
+645,
+505,
+194,
+-907,
+-3965,
+-7195,
+-5524,
+1111,
+4509,
+3145,
+3535,
+3294,
+3846,
+7424,
+7315,
+3111,
+-1601,
+-3095,
+-3366,
+-4972,
+-5281,
+-7332,
+-9647,
+-8219,
+-4862,
+-1956,
+-808,
+1125,
+2677,
+3750,
+7120,
+9202,
+7949,
+5515,
+3979,
+2538,
+716,
+-4,
+-1881,
+-5029,
+-6072,
+-5264,
+-4448,
+-3573,
+-2254,
+-1472,
+-802,
+1513,
+3981,
+4536,
+4289,
+4083,
+3336,
+2484,
+2141,
+963,
+-1417,
+-3088,
+-3937,
+-4523,
+-3991,
+-2694,
+-2023,
+-1694,
+-593,
+580,
+1431,
+2310,
+2417,
+1777,
+1433,
+1598,
+1241,
+374,
+-69,
+-753,
+-1490,
+-1449,
+-1357,
+-1625,
+-1628,
+-1176,
+-845,
+-356,
+723,
+1418,
+1370,
+1530,
+1663,
+1222,
+1057,
+1140,
+345,
+-576,
+-628,
+-1435,
+-4343,
+-6010,
+-2139,
+2712,
+2651,
+2832,
+3744,
+2781,
+5433,
+7295,
+4184,
+117,
+-2377,
+-2990,
+-4553,
+-4853,
+-5022,
+-7143,
+-6439,
+-4074,
+-2314,
+-1340,
+-260,
+822,
+720,
+2570,
+4741,
+4967,
+4932,
+4619,
+4026,
+2856,
+2222,
+1221,
+-911,
+-1898,
+-2510,
+-2962,
+-2593,
+-1870,
+-1447,
+-1553,
+-1085,
+-648,
+-342,
+240,
+418,
+505,
+623,
+1054,
+1416,
+1337,
+1193,
+544,
+-101,
+-348,
+-407,
+-426,
+-604,
+-573,
+-519,
+-297,
+9,
+-235,
+-589,
+-927,
+-952,
+-563,
+-310,
+9,
+168,
+219,
+369,
+245,
+40,
+-235,
+-451,
+-287,
+46,
+415,
+683,
+836,
+842,
+670,
+489,
+316,
+166,
+54,
+-36,
+-65,
+36,
+-96,
+-883,
+-1693,
+-1570,
+-756,
+-117,
+340,
+975,
+1918,
+2596,
+2086,
+1068,
+199,
+-509,
+-625,
+-662,
+-529,
+71,
+-33,
+-597,
+-1067,
+-1512,
+-1670,
+-1870,
+-1901,
+-1547,
+-974,
+-269,
+142,
+260,
+272,
+56,
+-164,
+-24,
+509,
+1019,
+1292,
+1496,
+1616,
+1660,
+1613,
+1357,
+966,
+660,
+605,
+597,
+480,
+275,
+-134,
+-671,
+-1134,
+-1376,
+-1473,
+-1534,
+-1564,
+-1496,
+-1237,
+-812,
+-402,
+-128,
+64,
+267,
+431,
+522,
+479,
+332,
+320,
+468,
+565,
+548,
+407,
+180,
+-63,
+-264,
+-455,
+-638,
+-685,
+-574,
+-358,
+-32,
+238,
+328,
+329,
+371,
+427,
+438,
+448,
+424,
+383,
+441,
+482,
+29,
+-1189,
+-2337,
+-1898,
+-396,
+261,
+599,
+1708,
+2529,
+2347,
+1500,
+312,
+-430,
+-148,
+278,
+227,
+432,
+471,
+-532,
+-1710,
+-2265,
+-2405,
+-2323,
+-2014,
+-1597,
+-1182,
+-690,
+-406,
+-567,
+-617,
+-358,
+-89,
+343,
+1088,
+1780,
+1952,
+1833,
+1659,
+1418,
+1391,
+1493,
+1446,
+1302,
+1180,
+911,
+415,
+-45,
+-492,
+-962,
+-1186,
+-1142,
+-1095,
+-1100,
+-1196,
+-1422,
+-1556,
+-1353,
+-995,
+-586,
+-59,
+257,
+287,
+287,
+197,
+3,
+-36,
+156,
+418,
+737,
+932,
+759,
+427,
+165,
+-84,
+-252,
+-225,
+-148,
+-84,
+34,
+39,
+-96,
+-169,
+-168,
+-72,
+63,
+179,
+360,
+539,
+485,
+-67,
+-1439,
+-2707,
+-1793,
+379,
+1014,
+1030,
+2144,
+2711,
+2106,
+1211,
+-4,
+-525,
+364,
+955,
+628,
+584,
+170,
+-1432,
+-2769,
+-2892,
+-2525,
+-2075,
+-1551,
+-1390,
+-1363,
+-1025,
+-944,
+-1087,
+-615,
+145,
+594,
+1099,
+1758,
+1969,
+1712,
+1453,
+1289,
+1384,
+1843,
+2083,
+1800,
+1387,
+975,
+400,
+-86,
+-260,
+-446,
+-681,
+-781,
+-918,
+-1183,
+-1481,
+-1768,
+-1877,
+-1558,
+-1020,
+-515,
+-28,
+192,
+9,
+-261,
+-322,
+-178,
+98,
+444,
+706,
+805,
+761,
+492,
+145,
+-5,
+6,
+20,
+53,
+81,
+27,
+-103,
+-249,
+-325,
+-219,
+-9,
+139,
+291,
+473,
+547,
+400,
+42,
+-904,
+-2367,
+-2330,
+-46,
+1336,
+924,
+1518,
+2371,
+1895,
+1372,
+564,
+-271,
+454,
+1397,
+1020,
+578,
+328,
+-986,
+-2542,
+-2821,
+-2398,
+-1994,
+-1564,
+-1564,
+-1956,
+-1922,
+-1598,
+-1434,
+-879,
+175,
+771,
+983,
+1429,
+1726,
+1615,
+1534,
+1616,
+1721,
+2049,
+2369,
+2073,
+1426,
+888,
+304,
+-192,
+-219,
+-94,
+-284,
+-630,
+-961,
+-1359,
+-1618,
+-1696,
+-1748,
+-1454,
+-778,
+-324,
+-128,
+-18,
+-195,
+-423,
+-382,
+-226,
+70,
+483,
+701,
+628,
+428,
+210,
+10,
+-22,
+114,
+227,
+272,
+257,
+169,
+25,
+-75,
+-138,
+-118,
+102,
+328,
+287,
+159,
+135,
+-135,
+-1224,
+-2588,
+-2139,
+243,
+1339,
+861,
+1548,
+2238,
+1746,
+1333,
+575,
+20,
+917,
+1538,
+977,
+662,
+405,
+-964,
+-2463,
+-2640,
+-2228,
+-1890,
+-1544,
+-1616,
+-1970,
+-1980,
+-1750,
+-1567,
+-867,
+258,
+771,
+834,
+1153,
+1445,
+1448,
+1465,
+1600,
+1732,
+2025,
+2283,
+1981,
+1387,
+883,
+305,
+-131,
+-60,
+112,
+-138,
+-472,
+-713,
+-1204,
+-1632,
+-1686,
+-1616,
+-1274,
+-676,
+-513,
+-574,
+-314,
+-246,
+-516,
+-545,
+-349,
+-28,
+512,
+853,
+680,
+427,
+319,
+192,
+159,
+289,
+343,
+264,
+254,
+193,
+-29,
+-143,
+-148,
+-107,
+152,
+371,
+271,
+-62,
+-913,
+-2303,
+-2531,
+-572,
+992,
+788,
+1179,
+2054,
+1888,
+1608,
+1079,
+285,
+625,
+1391,
+1211,
+911,
+815,
+-239,
+-1829,
+-2473,
+-2303,
+-1946,
+-1557,
+-1548,
+-1949,
+-2143,
+-1976,
+-1775,
+-1202,
+-178,
+458,
+614,
+910,
+1272,
+1374,
+1395,
+1466,
+1518,
+1745,
+2114,
+2090,
+1680,
+1224,
+657,
+53,
+-175,
+-52,
+-45,
+-203,
+-454,
+-892,
+-1329,
+-1492,
+-1447,
+-1204,
+-814,
+-655,
+-631,
+-406,
+-247,
+-334,
+-468,
+-526,
+-358,
+83,
+466,
+547,
+455,
+343,
+228,
+230,
+309,
+335,
+371,
+394,
+352,
+231,
+64,
+-60,
+-48,
+104,
+202,
+-11,
+-747,
+-2004,
+-2576,
+-1166,
+550,
+643,
+737,
+1650,
+1868,
+1642,
+1375,
+674,
+546,
+1071,
+1077,
+943,
+1115,
+595,
+-841,
+-1963,
+-2249,
+-2154,
+-1810,
+-1444,
+-1523,
+-1822,
+-1890,
+-1813,
+-1512,
+-726,
+32,
+333,
+650,
+1095,
+1306,
+1343,
+1429,
+1450,
+1429,
+1627,
+1802,
+1692,
+1440,
+1016,
+360,
+-106,
+-130,
+-84,
+-157,
+-290,
+-645,
+-1068,
+-1270,
+-1301,
+-1210,
+-984,
+-715,
+-532,
+-436,
+-353,
+-370,
+-471,
+-464,
+-363,
+-165,
+206,
+496,
+517,
+400,
+306,
+192,
+166,
+284,
+373,
+383,
+386,
+383,
+319,
+224,
+135,
+127,
+115,
+-491,
+-1799,
+-2388,
+-1161,
+363,
+522,
+420,
+1024,
+1442,
+1559,
+1517,
+1026,
+750,
+863,
+628,
+452,
+800,
+684,
+-348,
+-1405,
+-1942,
+-2143,
+-2044,
+-1704,
+-1476,
+-1461,
+-1526,
+-1621,
+-1422,
+-716,
+5,
+325,
+585,
+1013,
+1288,
+1380,
+1476,
+1487,
+1409,
+1382,
+1354,
+1255,
+1174,
+968,
+519,
+129,
+-52,
+-240,
+-438,
+-441,
+-399,
+-604,
+-941,
+-1258,
+-1284,
+-315,
+394,
+-628,
+-1085,
+-532,
+-675,
+-126,
+-277,
+-1573,
+-522,
+598,
+237,
+407,
+805,
+1075,
+653,
+318,
+362,
+-59,
+-56,
+-240,
+-233,
+312,
+-489,
+-2514,
+-4669,
+-4202,
+-712,
+2020,
+3805,
+4136,
+2529,
+3440,
+5718,
+5515,
+3867,
+1626,
+-647,
+-2193,
+-2176,
+-1803,
+-3276,
+-5465,
+-7012,
+-7661,
+-6402,
+-3818,
+-2200,
+-1338,
+105,
+1535,
+3292,
+5837,
+7231,
+6633,
+5443,
+4310,
+3120,
+2167,
+863,
+-1674,
+-4124,
+-5139,
+-5305,
+-4852,
+-3473,
+-1936,
+-1080,
+-52,
+1583,
+2812,
+3833,
+4309,
+3278,
+2191,
+1920,
+1330,
+168,
+-1132,
+-2559,
+-3548,
+-3413,
+-3045,
+-3000,
+-2440,
+-1105,
+424,
+1562,
+2003,
+1718,
+1409,
+1794,
+1922,
+959,
+-191,
+-649,
+-329,
+-22,
+-2232,
+-7587,
+-10133,
+-6123,
+3815,
+11010,
+10048,
+7655,
+4465,
+7798,
+10768,
+5766,
+-1615,
+-9642,
+-12287,
+-10166,
+-6666,
+-6229,
+-9606,
+-9109,
+-5832,
+-1326,
+4475,
+7162,
+6468,
+5722,
+6975,
+8255,
+7576,
+5333,
+919,
+-3576,
+-5125,
+-4751,
+-4305,
+-4140,
+-4257,
+-4346,
+-2541,
+1238,
+4948,
+7386,
+6832,
+4496,
+3434,
+2708,
+1527,
+-206,
+-3454,
+-6091,
+-5990,
+-4237,
+-2710,
+-1963,
+-1253,
+-324,
+1191,
+2740,
+2787,
+2061,
+1796,
+1911,
+1408,
+-65,
+-1632,
+-2642,
+-2612,
+-2111,
+-2132,
+-2119,
+-703,
+1824,
+2113,
+-3052,
+-10217,
+-9285,
+2474,
+15080,
+14696,
+9168,
+3569,
+1871,
+8840,
+7733,
+-863,
+-10981,
+-16373,
+-12835,
+-7172,
+-2606,
+-4832,
+-7242,
+-3728,
+1232,
+7185,
+9862,
+7265,
+2730,
+1101,
+4013,
+4560,
+2412,
+-866,
+-5642,
+-6610,
+-3630,
+-702,
+380,
+20,
+-726,
+-825,
+2400,
+6645,
+7202,
+4332,
+728,
+-1582,
+-1799,
+-535,
+-1312,
+-4539,
+-5701,
+-4256,
+-1013,
+2246,
+2495,
+1214,
+859,
+1630,
+1894,
+788,
+-715,
+-1510,
+-1008,
+-797,
+-1376,
+-2139,
+-2347,
+-1166,
+64,
+874,
+1826,
+2927,
+1167,
+-7529,
+-13865,
+-7119,
+8693,
+17405,
+11376,
+5806,
+-706,
+3910,
+12384,
+4898,
+-5841,
+-15567,
+-15268,
+-9199,
+-2915,
+-2,
+-6828,
+-7298,
+-645,
+4931,
+9593,
+8510,
+3404,
+-1029,
+1545,
+5927,
+3179,
+704,
+-3058,
+-7267,
+-5092,
+-1456,
+523,
+578,
+803,
+476,
+128,
+4503,
+7132,
+4843,
+2484,
+-314,
+-2661,
+-1629,
+-312,
+-2667,
+-4845,
+-4645,
+-3556,
+-106,
+3033,
+2307,
+815,
+1327,
+2202,
+1608,
+238,
+-1347,
+-2299,
+-1676,
+-1349,
+-2026,
+-2123,
+-993,
+185,
+601,
+1363,
+2536,
+1356,
+-6385,
+-14216,
+-8118,
+9341,
+18113,
+10028,
+5714,
+-662,
+2201,
+13868,
+5555,
+-6998,
+-16122,
+-13932,
+-7484,
+-3936,
+-511,
+-7031,
+-7875,
+1569,
+7356,
+9852,
+7233,
+2382,
+-812,
+2168,
+7258,
+2096,
+-2579,
+-3745,
+-6101,
+-3546,
+-123,
+70,
+-1707,
+-134,
+2587,
+1895,
+4233,
+5028,
+2090,
+1861,
+1389,
+-720,
+-1444,
+-1278,
+-3112,
+-4277,
+-3164,
+-2898,
+-1520,
+861,
+1640,
+1528,
+1967,
+2726,
+1695,
+329,
+-492,
+-1697,
+-1969,
+-1929,
+-2346,
+-2041,
+-600,
+480,
+449,
+1232,
+2001,
+-2082,
+-11654,
+-11999,
+3894,
+17853,
+11683,
+5279,
+1994,
+-1245,
+12112,
+9934,
+-5184,
+-14616,
+-13918,
+-5837,
+-3437,
+-2238,
+-7345,
+-9704,
+1457,
+9286,
+8837,
+4980,
+1010,
+1222,
+4271,
+7312,
+1819,
+-5336,
+-4002,
+-3308,
+-1866,
+-985,
+-3300,
+-3466,
+-199,
+5187,
+4104,
+1751,
+2997,
+2126,
+3600,
+3670,
+-678,
+-3106,
+-1891,
+-1261,
+-2368,
+-2264,
+-3919,
+-3476,
+176,
+1251,
+1354,
+400,
+691,
+2138,
+1896,
+1695,
+-373,
+-2231,
+-1989,
+-1816,
+-1622,
+-1393,
+-557,
+-261,
+839,
+1234,
+-6099,
+-13830,
+-6704,
+12207,
+17650,
+5219,
+4873,
+2652,
+5438,
+14840,
+2038,
+-11781,
+-14722,
+-7010,
+-2482,
+-5104,
+-8182,
+-11393,
+-3796,
+9197,
+8387,
+2298,
+752,
+2771,
+7659,
+8564,
+3986,
+-5080,
+-5073,
+893,
+-749,
+-2984,
+-6554,
+-6884,
+-950,
+4891,
+4912,
+-866,
+561,
+5333,
+7261,
+5833,
+-1037,
+-4326,
+-1758,
+1554,
+-393,
+-5394,
+-5454,
+-3454,
+179,
+2665,
+-1061,
+-2457,
+677,
+3635,
+4058,
+1347,
+-451,
+-846,
+-346,
+-403,
+-2221,
+-2535,
+-1778,
+-671,
+454,
+-2159,
+-10071,
+-12945,
+-179,
+17116,
+12061,
+403,
+7550,
+7610,
+11287,
+11279,
+-5843,
+-14361,
+-7034,
+-1442,
+-6719,
+-11613,
+-12495,
+-8241,
+4100,
+9619,
+-682,
+-1891,
+5146,
+9786,
+11057,
+5758,
+-974,
+-3229,
+3852,
+2712,
+-6304,
+-8209,
+-8290,
+-4368,
+1412,
+1119,
+-2455,
+-1243,
+5528,
+8521,
+7421,
+3537,
+-1505,
+772,
+3590,
+-341,
+-4257,
+-4940,
+-4165,
+-2414,
+-583,
+-3011,
+-4147,
+39,
+2313,
+2528,
+2055,
+1207,
+1947,
+2715,
+1007,
+-2408,
+-2377,
+-414,
+-1230,
+-1867,
+-3633,
+-9724,
+-12863,
+-3041,
+14045,
+10335,
+-2909,
+9310,
+13964,
+12254,
+12191,
+-3180,
+-10105,
+-345,
+-192,
+-11763,
+-16662,
+-13357,
+-7749,
+648,
+2417,
+-6327,
+-892,
+9776,
+11498,
+8643,
+4306,
+4143,
+5477,
+7138,
+935,
+-8335,
+-6130,
+-4015,
+-5890,
+-6088,
+-6166,
+-3580,
+1133,
+4766,
+3210,
+4129,
+8211,
+5810,
+3999,
+3155,
+502,
+-186,
+-1683,
+-4503,
+-5169,
+-3667,
+-3607,
+-4424,
+-3364,
+-1626,
+496,
+2096,
+1967,
+2167,
+3503,
+3642,
+1586,
+-283,
+-332,
+-32,
+-1544,
+-4229,
+-7899,
+-12648,
+-8414,
+7338,
+10181,
+-4368,
+4177,
+17458,
+13517,
+13236,
+4243,
+-5162,
+1964,
+2892,
+-11114,
+-17844,
+-12323,
+-7832,
+-6496,
+-4604,
+-7565,
+-3331,
+7284,
+7605,
+3611,
+5653,
+10209,
+9934,
+7845,
+4885,
+-679,
+-230,
+-329,
+-7610,
+-9785,
+-6780,
+-5146,
+-4804,
+-3114,
+-808,
+1753,
+6140,
+6461,
+4152,
+5323,
+6386,
+4387,
+857,
+-710,
+-1095,
+-2162,
+-3546,
+-6282,
+-6035,
+-3066,
+-2787,
+-2956,
+-1881,
+510,
+2940,
+3258,
+2654,
+2028,
+2429,
+2474,
+1033,
+-233,
+-2762,
+-7034,
+-11056,
+-7771,
+4646,
+5433,
+-5715,
+3990,
+16374,
+11856,
+10648,
+5494,
+-18,
+5462,
+1544,
+-10835,
+-12677,
+-6704,
+-7160,
+-10246,
+-8169,
+-7359,
+-3156,
+2089,
+-420,
+260,
+6647,
+8892,
+6911,
+7202,
+8552,
+5729,
+4090,
+1688,
+-3204,
+-3246,
+-3532,
+-7259,
+-7538,
+-4539,
+-3069,
+-2792,
+-884,
+932,
+3421,
+5464,
+3526,
+3536,
+5345,
+4133,
+2168,
+584,
+-281,
+-1044,
+-2500,
+-4101,
+-4951,
+-3804,
+-3109,
+-3549,
+-2503,
+-910,
+410,
+1643,
+2037,
+1937,
+2188,
+2788,
+2315,
+-572,
+-6503,
+-9657,
+-1302,
+7699,
+-1541,
+-6680,
+9781,
+13307,
+6279,
+7430,
+3430,
+3365,
+5749,
+-4342,
+-10037,
+-4328,
+-4039,
+-10940,
+-9452,
+-4717,
+-5445,
+-3381,
+-2392,
+-2448,
+2723,
+4173,
+2037,
+4710,
+9437,
+7904,
+4223,
+5554,
+4404,
+1385,
+-43,
+-3303,
+-4253,
+-3654,
+-5194,
+-5691,
+-3290,
+-1456,
+-2081,
+-498,
+1909,
+2226,
+3394,
+3325,
+2560,
+4033,
+3472,
+1280,
+1159,
+354,
+-1428,
+-2003,
+-2912,
+-3889,
+-3756,
+-3522,
+-3245,
+-2163,
+-801,
+-58,
+556,
+1671,
+2327,
+2137,
+1292,
+-3214,
+-7879,
+-365,
+8792,
+-2058,
+-6971,
+10764,
+11376,
+2080,
+7475,
+5194,
+2926,
+4953,
+-5039,
+-7315,
+-715,
+-5646,
+-12680,
+-6937,
+-1755,
+-6613,
+-5901,
+-2174,
+-1343,
+2238,
+575,
+-682,
+5661,
+9086,
+4503,
+2478,
+7910,
+6936,
+1933,
+1266,
+-19,
+-835,
+-2541,
+-5805,
+-4897,
+-2034,
+-3317,
+-5455,
+-1761,
+1654,
+-167,
+-301,
+2165,
+3287,
+3091,
+2318,
+1799,
+3063,
+3081,
+-334,
+-481,
+970,
+-1720,
+-3691,
+-3239,
+-2820,
+-2991,
+-3206,
+-2470,
+-811,
+529,
+173,
+716,
+2623,
+1564,
+-3845,
+-6581,
+2529,
+8041,
+-5370,
+-4499,
+13582,
+7503,
+-109,
+8820,
+5684,
+4438,
+3673,
+-6724,
+-2925,
+1272,
+-9126,
+-12206,
+-2956,
+-2350,
+-9067,
+-5194,
+-1653,
+-1288,
+390,
+-2551,
+530,
+6921,
+4657,
+798,
+5477,
+10107,
+4739,
+2049,
+4361,
+2961,
+561,
+-2843,
+-4325,
+-1612,
+-2273,
+-6381,
+-5260,
+-109,
+-1162,
+-3773,
+-522,
+1928,
+1069,
+328,
+1702,
+3025,
+2946,
+2046,
+955,
+2895,
+2338,
+-1672,
+-1136,
+-243,
+-2378,
+-3644,
+-2902,
+-1987,
+-2112,
+-1495,
+-920,
+270,
+1683,
+595,
+-992,
+-4240,
+-4096,
+5163,
+3365,
+-8693,
+2644,
+13871,
+721,
+2637,
+10991,
+4279,
+5176,
+1215,
+-4254,
+1188,
+-1917,
+-10538,
+-7706,
+-284,
+-6409,
+-9875,
+-1970,
+-2217,
+-3228,
+-2424,
+-2575,
+1869,
+3423,
+1156,
+1937,
+7458,
+7611,
+2627,
+5239,
+6736,
+2968,
+897,
+-186,
+-48,
+-1270,
+-3511,
+-4529,
+-2943,
+-1507,
+-4284,
+-3616,
+-532,
+-870,
+-1332,
+-877,
+1520,
+2161,
+605,
+2045,
+3158,
+2852,
+1636,
+554,
+1527,
+479,
+-1720,
+-2091,
+-1287,
+-1420,
+-2853,
+-1994,
+-642,
+-702,
+-651,
+-305,
+809,
+-1228,
+-6310,
+-3284,
+6444,
+57,
+-9694,
+6692,
+12322,
+-2264,
+4655,
+10553,
+3995,
+5217,
+-66,
+-1294,
+2509,
+-3061,
+-9247,
+-4914,
+871,
+-7968,
+-9271,
+-1035,
+-3443,
+-5114,
+-3791,
+-1539,
+1162,
+829,
+660,
+2385,
+7135,
+5285,
+1660,
+6675,
+7080,
+2594,
+1368,
+2909,
+2358,
+-1581,
+-2121,
+-1548,
+-1810,
+-3079,
+-4944,
+-2309,
+-1422,
+-3854,
+-2656,
+-14,
+115,
+-634,
+735,
+2188,
+2383,
+1821,
+1231,
+2298,
+1998,
+6,
+-378,
+210,
+-244,
+-1924,
+-1735,
+-317,
+-1118,
+-1969,
+-886,
+5,
+-368,
+-410,
+-812,
+-3948,
+-5540,
+1489,
+4735,
+-7002,
+-3001,
+13628,
+3594,
+-3100,
+10227,
+7590,
+2375,
+2916,
+1211,
+1479,
+-631,
+-3134,
+-6350,
+-1802,
+-978,
+-10207,
+-6177,
+-1046,
+-4499,
+-6925,
+-3423,
+1443,
+-1421,
+-584,
+2444,
+2882,
+5009,
+3294,
+3499,
+5559,
+5411,
+3077,
+1096,
+4451,
+2750,
+-1703,
+-631,
+383,
+-1183,
+-4035,
+-2959,
+-1350,
+-3069,
+-3804,
+-2694,
+-236,
+-904,
+-1864,
+513,
+1545,
+1463,
+455,
+1019,
+2475,
+970,
+230,
+551,
+798,
+211,
+-916,
+-468,
+-216,
+-352,
+-1036,
+-1298,
+-138,
+-232,
+-750,
+-580,
+40,
+-1001,
+-5521,
+-4688,
+5193,
+3492,
+-9220,
+1094,
+13917,
+1137,
+-3168,
+7172,
+9020,
+2400,
+-2739,
+3367,
+3104,
+-2930,
+-2350,
+-4632,
+-2215,
+-2432,
+-6993,
+-6593,
+-3793,
+228,
+-5689,
+-6176,
+2457,
+1840,
+-1003,
+-1275,
+4305,
+5439,
+333,
+2841,
+4258,
+4558,
+3512,
+1238,
+3254,
+2559,
+1884,
+-421,
+-1639,
+1150,
+-1170,
+-3158,
+-3000,
+-1500,
+-1025,
+-3848,
+-2200,
+-277,
+-804,
+-1328,
+-773,
+1228,
+162,
+-96,
+884,
+812,
+1234,
+386,
+645,
+708,
+381,
+633,
+-624,
+-126,
+146,
+-872,
+-957,
+-586,
+223,
+-698,
+-781,
+544,
+261,
+200,
+-328,
+-2742,
+-4169,
+1605,
+6106,
+-3718,
+-5298,
+7649,
+6832,
+-1261,
+-1390,
+4067,
+6767,
+-470,
+-1764,
+1864,
+-38,
+257,
+-2297,
+-3900,
+-2558,
+-1958,
+-1561,
+-6583,
+-4334,
+516,
+-2266,
+-3226,
+-2200,
+2206,
+1794,
+-1454,
+1915,
+2658,
+3157,
+2576,
+1949,
+3410,
+1896,
+3450,
+2310,
+117,
+1588,
+1002,
+917,
+-1493,
+-1639,
+129,
+-2106,
+-2237,
+-2421,
+-1808,
+-1254,
+-2307,
+-727,
+-923,
+-651,
+449,
+46,
+471,
+268,
+1098,
+710,
+-117,
+1031,
+362,
+-192,
+-90,
+398,
+471,
+-775,
+-349,
+271,
+125,
+-277,
+-403,
+-31,
+162,
+682,
+-104,
+-477,
+441,
+534,
+682,
+136,
+-219,
+114,
+-447,
+-2159,
+-2436,
+1852,
+1779,
+-2721,
+-567,
+1960,
+1799,
+1184,
+-179,
+1457,
+1266,
+629,
+1852,
+-82,
+-866,
+-345,
+61,
+-696,
+-3194,
+-1676,
+-726,
+-1898,
+-1857,
+-1936,
+-516,
+-494,
+-253,
+808,
+-301,
+554,
+1218,
+1193,
+1286,
+398,
+1408,
+1364,
+843,
+1215,
+506,
+400,
+94,
+496,
+632,
+-447,
+-192,
+-387,
+-386,
+-505,
+-1087,
+-390,
+-591,
+-458,
+-196,
+-703,
+-257,
+-225,
+87,
+90,
+-470,
+210,
+258,
+-121,
+-270,
+-150,
+267,
+-203,
+-43,
+302,
+-101,
+47,
+244,
+209,
+63,
+142,
+353,
+64,
+-158,
+-79,
+312,
+-121,
+-985,
+-253,
+224,
+-389,
+-603,
+-351,
+-28,
+56,
+376,
+220,
+-222,
+353,
+635,
+478,
+441,
+85,
+-219,
+-768,
+-570,
+876,
+771,
+-478,
+-189,
+482,
+529,
+329,
+211,
+618,
+210,
+-94,
+575,
+101,
+-511,
+-508,
+-454,
+-437,
+-1064,
+-996,
+-845,
+-1071,
+-617,
+-593,
+-579,
+-382,
+-58,
+471,
+253,
+135,
+289,
+926,
+1221,
+374,
+432,
+626,
+645,
+834,
+325,
+203,
+84,
+-69,
+-36,
+-344,
+-247,
+-287,
+-308,
+-257,
+-498,
+-158,
+-109,
+-198,
+51,
+-60,
+-96,
+-138,
+-56,
+98,
+-11,
+54,
+-73,
+-188,
+-216,
+-209,
+-5,
+-219,
+-244,
+-28,
+-33,
+68,
+-84,
+-84,
+80,
+73,
+119,
+-16,
+66,
+277,
+234,
+102,
+-55,
+-16,
+47,
+2,
+-93,
+-193,
+-113,
+-55,
+50,
+-53,
+-307,
+-24,
+213,
+98,
+37,
+-31,
+-7,
+158,
+335,
+243,
+22,
+-138,
+-114,
+100,
+-46,
+-12,
+59,
+-209,
+-89,
+-387,
+-869,
+-338,
+349,
+214,
+-232,
+57,
+417,
+335,
+312,
+414,
+604,
+151,
+63,
+478,
+22,
+-329,
+-402,
+-315,
+-355,
+-754,
+-553,
+-526,
+-538,
+-332,
+-424,
+-199,
+-28,
+5,
+-42,
+94,
+415,
+271,
+316,
+136,
+90,
+485,
+233,
+202,
+189,
+-7,
+119,
+61,
+238,
+200,
+-237,
+-254,
+-49,
+136,
+64,
+-79,
+20,
+129,
+93,
+9,
+163,
+95,
+-203,
+-49,
+-24,
+-295,
+-223,
+-110,
+-223,
+-396,
+-499,
+-400,
+-240,
+-33,
+98,
+-1,
+54,
+179,
+134,
+97,
+78,
+77,
+83,
+197,
+296,
+85,
+70,
+180,
+-124,
+-99,
+192,
+-128,
+-218,
+57,
+-193,
+-181,
+74,
+-113,
+-140,
+-164,
+-338,
+-179,
+243,
+366,
+-42,
+-277,
+-104,
+326,
+618,
+-14,
+-451,
+-82,
+427,
+529,
+-158,
+-205,
+119,
+80,
+131,
+-334,
+-213,
+29,
+-440,
+-203,
+-304,
+-836,
+-890,
+-169,
+646,
+-67,
+-447,
+172,
+636,
+871,
+527,
+643,
+608,
+262,
+642,
+401,
+-199,
+-569,
+-523,
+23,
+-393,
+-1005,
+-848,
+-468,
+-303,
+-376,
+-237,
+-406,
+-287,
+127,
+-24,
+32,
+107,
+294,
+410,
+155,
+369,
+735,
+1157,
+894,
+228,
+386,
+77,
+-355,
+-358,
+-547,
+-555,
+-441,
+-222,
+-250,
+-179,
+108,
+136,
+345,
+287,
+162,
+-33,
+-328,
+-152,
+-376,
+-598,
+-557,
+-479,
+-116,
+-18,
+-29,
+-179,
+-58,
+306,
+129,
+206,
+138,
+67,
+337,
+284,
+462,
+255,
+127,
+401,
+97,
+33,
+-124,
+-90,
+194,
+-120,
+-174,
+-185,
+-107,
+-46,
+-546,
+-587,
+-11,
+101,
+-488,
+-414,
+-205,
+-223,
+604,
+237,
+-778,
+-128,
+197,
+-56,
+346,
+-42,
+-471,
+543,
+625,
+42,
+398,
+270,
+352,
+612,
+226,
+-97,
+-545,
+-986,
+-945,
+180,
+328,
+-916,
+-487,
+557,
+1254,
+725,
+-351,
+751,
+1211,
+679,
+478,
+-325,
+-431,
+-253,
+-48,
+-569,
+-1721,
+-1248,
+-523,
+-457,
+-1384,
+-1587,
+255,
+138,
+-553,
+-114,
+-66,
+592,
+657,
+497,
+609,
+570,
+1263,
+1060,
+490,
+405,
+734,
+1057,
+-32,
+-239,
+210,
+68,
+-104,
+-819,
+-495,
+-219,
+-666,
+-557,
+-737,
+-389,
+-352,
+-536,
+-222,
+-397,
+50,
+74,
+-90,
+59,
+-155,
+548,
+417,
+-70,
+325,
+411,
+649,
+248,
+204,
+645,
+186,
+219,
+112,
+-70,
+-109,
+-446,
+-278,
+-542,
+-702,
+-586,
+-596,
+-352,
+-617,
+-462,
+-216,
+-222,
+25,
+-247,
+-18,
+456,
+500,
+543,
+379,
+531,
+935,
+1053,
+335,
+25,
+672,
+318,
+-28,
+-816,
+-2456,
+-1516,
+306,
+-121,
+-1684,
+-1292,
+1694,
+2342,
+236,
+60,
+2252,
+3274,
+1020,
+-188,
+1232,
+1227,
+-252,
+-1636,
+-1516,
+-904,
+-1924,
+-2779,
+-2848,
+-2019,
+-1439,
+-2150,
+-1854,
+-683,
+309,
+118,
+-339,
+1142,
+2092,
+1617,
+1234,
+1834,
+2791,
+2007,
+1289,
+1677,
+1789,
+1272,
+289,
+217,
+270,
+-317,
+-828,
+-1357,
+-1162,
+-1102,
+-1626,
+-1775,
+-1529,
+-903,
+-1022,
+-1267,
+-600,
+-113,
+-67,
+-274,
+162,
+766,
+571,
+349,
+359,
+1031,
+1385,
+534,
+396,
+1299,
+1418,
+144,
+-242,
+669,
+265,
+-870,
+-965,
+-404,
+-662,
+-1479,
+-1228,
+-777,
+-889,
+-1008,
+-862,
+-344,
+42,
+110,
+54,
+404,
+1167,
+1098,
+571,
+942,
+1528,
+1010,
+363,
+766,
+584,
+-897,
+-1931,
+-1206,
+-25,
+-637,
+-1718,
+-533,
+1422,
+900,
+-67,
+1286,
+2403,
+1732,
+659,
+1009,
+1558,
+228,
+-802,
+-877,
+-925,
+-1503,
+-2632,
+-2514,
+-2009,
+-2026,
+-2343,
+-2281,
+-906,
+-525,
+-892,
+-334,
+718,
+1351,
+805,
+1249,
+2375,
+2283,
+1903,
+1872,
+2457,
+2290,
+1439,
+1279,
+1129,
+860,
+43,
+-607,
+-550,
+-942,
+-1455,
+-1851,
+-1708,
+-1513,
+-1901,
+-1768,
+-1313,
+-951,
+-920,
+-816,
+-144,
+112,
+93,
+227,
+495,
+816,
+757,
+554,
+582,
+1324,
+1474,
+458,
+711,
+1433,
+798,
+-86,
+145,
+626,
+-513,
+-1102,
+-339,
+-651,
+-1347,
+-1325,
+-907,
+-1033,
+-1323,
+-828,
+-642,
+-444,
+-113,
+-33,
+411,
+789,
+969,
+827,
+980,
+1337,
+1112,
+1075,
+727,
+374,
+27,
+-933,
+-1200,
+-696,
+-79,
+-913,
+-1343,
+905,
+997,
+-110,
+963,
+1732,
+1617,
+723,
+866,
+1238,
+71,
+-341,
+-839,
+-1040,
+-1214,
+-2238,
+-2186,
+-1978,
+-1808,
+-2140,
+-2121,
+-819,
+-845,
+-894,
+-189,
+489,
+830,
+605,
+1397,
+1894,
+1789,
+1928,
+1903,
+2286,
+2038,
+1530,
+1394,
+1204,
+891,
+-12,
+-249,
+-227,
+-934,
+-1386,
+-1439,
+-1292,
+-1607,
+-1796,
+-1363,
+-1213,
+-1135,
+-1015,
+-678,
+-307,
+-260,
+-90,
+165,
+466,
+520,
+431,
+665,
+667,
+502,
+727,
+1115,
+806,
+367,
+1021,
+1166,
+173,
+83,
+558,
+-42,
+-816,
+-562,
+-464,
+-1091,
+-1190,
+-917,
+-975,
+-1025,
+-924,
+-692,
+-450,
+-291,
+-193,
+142,
+595,
+626,
+686,
+970,
+1082,
+990,
+805,
+867,
+843,
+319,
+17,
+-195,
+-859,
+-952,
+-270,
+-365,
+-1005,
+-184,
+815,
+199,
+328,
+1211,
+1085,
+894,
+789,
+633,
+384,
+-89,
+-576,
+-976,
+-924,
+-1469,
+-2074,
+-1662,
+-1558,
+-1801,
+-1713,
+-1090,
+-713,
+-758,
+-223,
+244,
+524,
+791,
+986,
+1443,
+1626,
+1612,
+1636,
+1802,
+1817,
+1365,
+1225,
+1156,
+713,
+267,
+23,
+-169,
+-603,
+-894,
+-988,
+-1146,
+-1236,
+-1325,
+-1250,
+-1073,
+-1022,
+-940,
+-717,
+-448,
+-366,
+-295,
+-28,
+160,
+192,
+305,
+522,
+591,
+553,
+554,
+502,
+492,
+703,
+751,
+373,
+354,
+735,
+388,
+-164,
+102,
+87,
+-564,
+-675,
+-444,
+-706,
+-992,
+-816,
+-678,
+-750,
+-689,
+-505,
+-259,
+-150,
+-116,
+176,
+438,
+465,
+560,
+815,
+880,
+638,
+615,
+851,
+466,
+-58,
+207,
+19,
+-777,
+-959,
+-577,
+-66,
+-379,
+-678,
+444,
+939,
+363,
+565,
+1241,
+1237,
+565,
+407,
+598,
+155,
+-564,
+-972,
+-849,
+-1078,
+-1833,
+-1883,
+-1422,
+-1428,
+-1737,
+-1373,
+-620,
+-553,
+-545,
+46,
+621,
+725,
+734,
+1186,
+1600,
+1530,
+1380,
+1579,
+1777,
+1428,
+1053,
+1111,
+992,
+452,
+61,
+49,
+-175,
+-716,
+-967,
+-907,
+-1025,
+-1335,
+-1370,
+-1115,
+-1063,
+-1161,
+-979,
+-622,
+-477,
+-475,
+-219,
+156,
+240,
+243,
+503,
+785,
+734,
+650,
+795,
+826,
+557,
+315,
+452,
+605,
+60,
+-329,
+190,
+153,
+-550,
+-494,
+-135,
+-389,
+-811,
+-593,
+-314,
+-597,
+-669,
+-386,
+-167,
+-210,
+-266,
+78,
+299,
+187,
+206,
+471,
+554,
+353,
+455,
+582,
+393,
+261,
+217,
+119,
+-53,
+-186,
+-361,
+-647,
+-732,
+-604,
+-236,
+-86,
+-325,
+388,
+1004,
+599,
+871,
+1273,
+1200,
+945,
+645,
+653,
+224,
+-325,
+-740,
+-1025,
+-1149,
+-1776,
+-1976,
+-1733,
+-1752,
+-1781,
+-1622,
+-985,
+-698,
+-570,
+27,
+500,
+829,
+990,
+1336,
+1726,
+1749,
+1748,
+1770,
+1867,
+1667,
+1258,
+1130,
+910,
+447,
+-38,
+-286,
+-509,
+-991,
+-1326,
+-1383,
+-1461,
+-1615,
+-1615,
+-1384,
+-1196,
+-1080,
+-838,
+-482,
+-175,
+-14,
+216,
+546,
+721,
+771,
+874,
+1017,
+977,
+800,
+710,
+674,
+476,
+139,
+50,
+37,
+-290,
+-491,
+-485,
+-547,
+-501,
+-539,
+-647,
+-450,
+-303,
+-443,
+-355,
+5,
+6,
+-121,
+158,
+337,
+213,
+237,
+445,
+488,
+373,
+371,
+309,
+216,
+257,
+166,
+-93,
+-67,
+-25,
+-487,
+-577,
+-237,
+-757,
+-1373,
+-832,
+-334,
+-368,
+-174,
+226,
+1135,
+1470,
+1102,
+1724,
+2099,
+1709,
+1214,
+900,
+893,
+-62,
+-961,
+-1193,
+-1544,
+-2098,
+-2837,
+-2650,
+-2327,
+-2490,
+-2272,
+-1748,
+-890,
+-508,
+-179,
+742,
+1418,
+1785,
+1945,
+2451,
+2852,
+2549,
+2342,
+2263,
+2071,
+1439,
+723,
+422,
+-70,
+-780,
+-1397,
+-1652,
+-1795,
+-2228,
+-2373,
+-2126,
+-1836,
+-1672,
+-1380,
+-736,
+-179,
+146,
+496,
+999,
+1399,
+1449,
+1470,
+1602,
+1565,
+1249,
+881,
+663,
+364,
+-144,
+-546,
+-764,
+-1006,
+-1224,
+-1274,
+-1323,
+-1236,
+-962,
+-746,
+-407,
+-120,
+80,
+463,
+721,
+747,
+843,
+993,
+900,
+669,
+618,
+533,
+236,
+-48,
+-107,
+-201,
+-458,
+-556,
+-542,
+-529,
+-465,
+-437,
+-307,
+-188,
+-438,
+-662,
+-305,
+-39,
+-849,
+-1609,
+-263,
+1428,
+228,
+-375,
+2323,
+3098,
+1664,
+1745,
+2553,
+2535,
+1112,
+77,
+-77,
+-756,
+-1720,
+-3222,
+-3587,
+-2878,
+-3439,
+-4100,
+-3459,
+-1755,
+-1227,
+-1445,
+83,
+1728,
+2314,
+2379,
+2965,
+3941,
+3821,
+3266,
+2732,
+2490,
+2154,
+755,
+-389,
+-760,
+-1169,
+-2230,
+-3181,
+-2864,
+-2619,
+-2872,
+-2717,
+-1946,
+-927,
+-441,
+68,
+922,
+1777,
+2357,
+2318,
+2405,
+2664,
+2408,
+1643,
+895,
+553,
+-104,
+-1131,
+-1816,
+-2166,
+-2399,
+-2609,
+-2615,
+-2416,
+-1697,
+-736,
+-598,
+40,
+1632,
+2103,
+1854,
+2137,
+2549,
+2345,
+1456,
+902,
+564,
+-128,
+-821,
+-1510,
+-1762,
+-1629,
+-1827,
+-1897,
+-1407,
+-639,
+-298,
+-256,
+342,
+1237,
+1516,
+948,
+881,
+1300,
+285,
+-601,
+-106,
+-1005,
+-2152,
+-765,
+366,
+-225,
+105,
+1800,
+2667,
+2263,
+2358,
+2609,
+1902,
+1309,
+383,
+-1178,
+-2028,
+-2431,
+-3415,
+-4550,
+-4205,
+-3344,
+-3426,
+-2845,
+-1330,
+27,
+949,
+1939,
+3073,
+3622,
+4112,
+4210,
+3486,
+2987,
+2535,
+1477,
+2,
+-942,
+-1447,
+-2432,
+-3129,
+-3225,
+-3139,
+-2816,
+-2288,
+-1557,
+-826,
+190,
+1229,
+1697,
+2171,
+2713,
+2848,
+2494,
+1998,
+1574,
+810,
+-38,
+-777,
+-1573,
+-2133,
+-2414,
+-2554,
+-2640,
+-2453,
+-1750,
+-916,
+-403,
+165,
+1489,
+2218,
+1984,
+2950,
+3358,
+1847,
+1268,
+1173,
+3,
+-1163,
+-1755,
+-2176,
+-2690,
+-2518,
+-1972,
+-1908,
+-1192,
+22,
+618,
+1019,
+1695,
+2107,
+1666,
+1636,
+2010,
+1092,
+94,
+-263,
+-1376,
+-1768,
+-457,
+-1731,
+-5151,
+-3981,
+955,
+2337,
+-400,
+750,
+5303,
+6160,
+5173,
+3503,
+1711,
+2310,
+1724,
+-1812,
+-6147,
+-6323,
+-3861,
+-5816,
+-7464,
+-5990,
+-3493,
+-1001,
+97,
+1540,
+2770,
+5367,
+7786,
+5898,
+4386,
+4606,
+4302,
+1937,
+-1267,
+-2217,
+-3112,
+-3790,
+-4215,
+-5298,
+-4526,
+-2551,
+-773,
+-546,
+-32,
+2599,
+3965,
+3955,
+3518,
+3064,
+2937,
+2131,
+893,
+-1169,
+-2477,
+-2268,
+-2844,
+-3763,
+-3940,
+-2899,
+-1616,
+-1023,
+-181,
+607,
+1586,
+2617,
+3023,
+3070,
+2914,
+2991,
+2172,
+623,
+-310,
+-1374,
+-2183,
+-2752,
+-3338,
+-3214,
+-2667,
+-1629,
+-816,
+-278,
+799,
+1765,
+2420,
+2415,
+2095,
+1811,
+1020,
+509,
+175,
+-542,
+-1258,
+-1676,
+-1622,
+-1721,
+-1740,
+-1068,
+-852,
+-2054,
+-2617,
+929,
+5290,
+4343,
+2568,
+4316,
+5511,
+5146,
+3002,
+-412,
+-2276,
+-2717,
+-3204,
+-6159,
+-8896,
+-7253,
+-4846,
+-3602,
+-2969,
+-1694,
+1159,
+3995,
+6267,
+6021,
+4739,
+5447,
+5599,
+3839,
+720,
+-1621,
+-2390,
+-3349,
+-4039,
+-4975,
+-5170,
+-3395,
+-1315,
+139,
+701,
+2083,
+4056,
+4738,
+4561,
+3559,
+2429,
+1602,
+507,
+-1149,
+-3232,
+-4042,
+-3810,
+-3787,
+-3580,
+-3000,
+-1677,
+-99,
+1293,
+2238,
+2416,
+2580,
+2706,
+3382,
+4128,
+2082,
+-743,
+-502,
+-239,
+-2169,
+-3426,
+-3827,
+-3585,
+-2181,
+-999,
+-751,
+-658,
+1255,
+3304,
+2794,
+1816,
+1619,
+1680,
+1241,
+8,
+-1322,
+-2153,
+-1180,
+-321,
+-1526,
+-2302,
+-1478,
+-72,
+363,
+-230,
+-426,
+-82,
+-103,
+-77,
+2541,
+4581,
+3326,
+3631,
+4197,
+3161,
+2512,
+785,
+-1567,
+-3641,
+-4417,
+-4491,
+-6115,
+-6640,
+-5357,
+-3878,
+-2181,
+-630,
+1004,
+2187,
+3811,
+5725,
+5413,
+4276,
+3600,
+2869,
+1625,
+-298,
+-1819,
+-3206,
+-3817,
+-3270,
+-3022,
+-2734,
+-1844,
+-175,
+1408,
+2225,
+2944,
+3158,
+3145,
+3144,
+2440,
+1057,
+-421,
+-1236,
+-1857,
+-2701,
+-3165,
+-3225,
+-2780,
+-1898,
+-937,
+-298,
+-206,
+87,
+1419,
+3719,
+4816,
+3523,
+2068,
+1482,
+881,
+-351,
+-2295,
+-3896,
+-4219,
+-3195,
+-2016,
+-1842,
+-1410,
+9,
+1300,
+1732,
+1636,
+1591,
+1442,
+1292,
+1060,
+905,
+951,
+40,
+-693,
+-286,
+-671,
+-1437,
+-1264,
+-383,
+371,
+148,
+623,
+1538,
+-1352,
+-5744,
+-4090,
+1312,
+2921,
+1799,
+1479,
+2488,
+5347,
+7009,
+4782,
+210,
+-1976,
+-191,
+-607,
+-4050,
+-6603,
+-6961,
+-5451,
+-3585,
+-2599,
+-3395,
+-3123,
+320,
+3569,
+4271,
+3628,
+3813,
+4892,
+5331,
+4548,
+2148,
+-569,
+-1301,
+-1040,
+-1894,
+-3494,
+-4162,
+-3511,
+-2160,
+-805,
+-235,
+-93,
+737,
+2313,
+3162,
+2711,
+2027,
+1466,
+942,
+786,
+684,
+-712,
+-2331,
+-1677,
+-1330,
+-2395,
+-1867,
+-539,
+-52,
+-62,
+434,
+820,
+233,
+735,
+1092,
+-206,
+-628,
+-8,
+124,
+-546,
+-681,
+-390,
+-814,
+-535,
+90,
+-5,
+-80,
+381,
+1054,
+919,
+810,
+759,
+221,
+373,
+445,
+-358,
+-1278,
+-1213,
+15,
+517,
+240,
+469,
+618,
+117,
+-366,
+-1994,
+-3771,
+-679,
+3229,
+1528,
+-90,
+1057,
+1545,
+2429,
+2774,
+1183,
+-1064,
+-1624,
+94,
+-409,
+-2670,
+-2848,
+-2292,
+-1846,
+-1057,
+-812,
+-1316,
+-1070,
+454,
+1003,
+468,
+747,
+1275,
+1268,
+1598,
+1792,
+975,
+808,
+942,
+410,
+441,
+-32,
+-622,
+-261,
+-436,
+-603,
+-474,
+-709,
+-641,
+-368,
+-305,
+-310,
+-242,
+-165,
+-29,
+114,
+107,
+193,
+187,
+158,
+287,
+194,
+100,
+51,
+-28,
+-31,
+-70,
+-19,
+-33,
+-143,
+-165,
+-225,
+-240,
+-244,
+-273,
+-283,
+-269,
+-118,
+-7,
+34,
+68,
+94,
+196,
+267,
+258,
+202,
+136,
+102,
+29,
+-72,
+-179,
+-281,
+-298,
+-274,
+-227,
+-161,
+-15,
+162,
+227,
+236,
+268,
+332,
+335,
+237,
+132,
+8,
+-77,
+-130,
+-179,
+-220,
+-267,
+-270,
+-218,
+-159,
+-65,
+46,
+111,
+144,
+187,
+226,
+197,
+129,
+56,
+-14,
+-93,
+-179,
+-259,
+-280,
+-256,
+-236,
+-198,
+-168,
+-134,
+-41,
+51,
+66,
+42,
+50,
+76,
+107,
+156,
+168,
+144,
+124,
+110,
+76,
+-5,
+-50,
+-72,
+-130,
+-219,
+-284,
+-253,
+-181,
+-118,
+-75,
+-56,
+-9,
+77,
+144,
+175,
+176,
+206,
+247,
+240,
+187,
+85,
+-15,
+-79,
+-158,
+-240,
+-274,
+-283,
+-257,
+-178,
+-96,
+-36,
+44,
+131,
+196,
+206,
+180,
+175,
+134,
+61,
+-26,
+-116,
+-179,
+-195,
+-188,
+-215,
+-250,
+-209,
+-137,
+-97,
+-62,
+-22,
+-5,
+32,
+84,
+114,
+93,
+100,
+142,
+135,
+84,
+33,
+3,
+-8,
+-9,
+-22,
+-60,
+-79,
+-50,
+-5,
+17,
+2,
+-1,
+6,
+23,
+40,
+43,
+25,
+26,
+42,
+29,
+-15,
+-55,
+-104,
+-134,
+-147,
+-203,
+-244,
+-220,
+-175,
+-118,
+-58,
+-5,
+44,
+95,
+136,
+135,
+134,
+132,
+115,
+60,
+-4,
+-46,
+-72,
+-110,
+-124,
+-135,
+-159,
+-145,
+-93,
+-46,
+-21,
+44,
+107,
+141,
+151,
+132,
+111,
+110,
+100,
+44,
+-15,
+-43,
+-67,
+-92,
+-107,
+-110,
+-96,
+-80,
+-58,
+-15,
+13,
+44,
+67,
+68,
+42,
+23,
+19,
+-15,
+-49,
+-86,
+-101,
+-121,
+-131,
+-141,
+-159,
+-165,
+-152,
+-120,
+-92,
+-52,
+13,
+67,
+107,
+139,
+151,
+141,
+117,
+76,
+36,
+10,
+-16,
+-35,
+-73,
+-75,
+-56,
+-46,
+-49,
+-58,
+-46,
+-15,
+17,
+40,
+43,
+53,
+59,
+49,
+34,
+12,
+-9,
+-19,
+-43,
+-79,
+-116,
+-130,
+-134,
+-123,
+-100,
+-96,
+-77,
+-48,
+-12,
+30,
+44,
+59,
+60,
+47,
+40,
+25,
+20,
+22,
+15,
+6,
+-14,
+-24,
+-29,
+-35,
+-36,
+-43,
+-45,
+-41,
+-33,
+-18,
+-9,
+3,
+6,
+-2,
+-4,
+3,
+9,
+17,
+20,
+17,
+10,
+3,
+5,
+3,
+-12,
+-24,
+-31,
+-36,
+-45,
+-52,
+-48,
+-55,
+-59,
+-60,
+-55,
+-53,
+-53,
+-63,
+-65,
+-60,
+-50,
+-43,
+-48,
+-35,
+-24,
+-25,
+-35,
+-41,
+-39,
+-33,
+-16,
+-2,
+12,
+27,
+42,
+57,
+68,
+66,
+61,
+51,
+44,
+25,
+0,
+-9,
+-31,
+-49,
+-53,
+-52,
+-36,
+-39,
+-41,
+-7,
+27,
+25,
+15,
+27,
+32,
+23,
+20,
+5,
+-18,
+-26,
+-36,
+-39,
+-50,
+-62,
+-63,
+-62,
+-55,
+-50,
+-41,
+-33,
+-25,
+-14,
+-1,
+5,
+9,
+15,
+5,
+-7,
+-18,
+-26,
+-33,
+-46,
+-56,
+-73,
+-82,
+-66,
+-67,
+-50,
+-38,
+-22,
+-7,
+17,
+30,
+37,
+36,
+29,
+19,
+13,
+12,
+-7,
+-25,
+-41,
+-42,
+-38,
+-49,
+-49,
+-35,
+-26,
+-8,
+6,
+0,
+0,
+-2,
+-5,
+-1,
+-4,
+-2,
+-12,
+-12,
+-15,
+-16,
+-19,
+-24,
+-35,
+-39,
+-48,
+-46,
+-35,
+-25,
+-4,
+13,
+25,
+27,
+3,
+2,
+30,
+27,
+-1,
+-1,
+-16,
+-25,
+-18,
+-36,
+-42,
+-48,
+-62,
+-56,
+-48,
+-53,
+-46,
+-36,
+-26,
+-15,
+-8,
+12,
+23,
+29,
+25,
+13,
+5,
+5,
+0,
+-16,
+-12,
+-19,
+-25,
+-24,
+-29,
+-29,
+-39,
+-33,
+-25,
+-33,
+-19,
+-5,
+-11,
+-22,
+-24,
+-18,
+-25,
+-32,
+-39,
+-39,
+-32,
+-41,
+-36,
+-43,
+-39,
+-18,
+-11,
+-7,
+-12,
+-8,
+-4,
+-7,
+0,
+5,
+-4,
+2,
+6,
+-2,
+-5,
+-19,
+-25,
+-29,
+-33,
+-39,
+-36,
+-25,
+-24,
+-12,
+-7,
+5,
+13,
+16,
+34,
+29,
+3,
+-1,
+-1,
+-14,
+-16,
+-18,
+-19,
+-19,
+-26,
+-22,
+-32,
+-26,
+-26,
+-28,
+-14,
+-11,
+-5,
+-2,
+-4,
+0,
+-9,
+-15,
+-16,
+-28,
+-28,
+-32,
+-48,
+-56,
+-52,
+-55,
+-56,
+-56,
+-48,
+-41,
+-31,
+-22,
+-8,
+-2,
+-1,
+9,
+10,
+-1,
+3,
+-7,
+-1,
+0,
+2,
+-1,
+-11,
+-16,
+-28,
+-38,
+-45,
+-41,
+-42,
+-24,
+-15,
+5,
+9,
+-9,
+-19,
+-62,
+-192,
+-328,
+125,
+1057,
+514,
+-579,
+277,
+-138,
+-1499,
+-18,
+595,
+-276,
+67,
+-332,
+-853,
+761,
+1310,
+-301,
+-237,
+513,
+762,
+540,
+-164,
+57,
+-1481,
+-1500,
+396,
+-1350,
+-365,
+1445,
+-933,
+136,
+1200,
+-686,
+876,
+1901,
+166,
+-349,
+-244,
+-198,
+-1073,
+-1085,
+187,
+-481,
+294,
+893,
+-877,
+-4,
+659,
+-7,
+-7,
+-178,
+73,
+-62,
+463,
+223,
+-523,
+500,
+209,
+318,
+199,
+-818,
+398,
+-28,
+-508,
+320,
+-635,
+-127,
+226,
+-688,
+83,
+-65,
+-426,
+214,
+-318,
+-297,
+425,
+134,
+29,
+311,
+-21,
+115,
+316,
+-417,
+-84,
+127,
+-294,
+407,
+219,
+-470,
+-110,
+221,
+-148,
+-176,
+231,
+-189,
+180,
+194,
+-562,
+172,
+71,
+110,
+90,
+-645,
+107,
+-58,
+267,
+646,
+-467,
+349,
+628,
+-366,
+-205,
+-16,
+-235,
+-386,
+-322,
+-31,
+22,
+54,
+316,
+-226,
+219,
+689,
+-186,
+272,
+-288,
+-679,
+37,
+-351,
+17,
+-284,
+-130,
+95,
+-312,
+347,
+-15,
+563,
+439,
+-696,
+54,
+-113,
+-233,
+-212,
+-246,
+190,
+-33,
+91,
+-76,
+-106,
+192,
+88,
+117,
+196,
+432,
+56,
+-100,
+279,
+0,
+-65,
+-243,
+-412,
+-49,
+-193,
+-361,
+121,
+104,
+-280,
+102,
+-89,
+-120,
+488,
+-7,
+-145,
+194,
+261,
+-270,
+-314,
+396,
+-185,
+-93,
+271,
+81,
+134,
+-317,
+13,
+-158,
+-549,
+445,
+388,
+-53,
+-2,
+-550,
+-332,
+88,
+-237,
+-131,
+-45,
+36,
+386,
+-128,
+-243,
+90,
+145,
+686,
+-259,
+-511,
+217,
+-213,
+422,
+-318,
+-277,
+809,
+-339,
+131,
+-73,
+-577,
+354,
+296,
+527,
+-158,
+-488,
+-89,
+-196,
+203,
+-252,
+-86,
+146,
+-242,
+264,
+-39,
+56,
+287,
+-470,
+-624,
+-666,
+71,
+632,
+221,
+292,
+189,
+390,
+39,
+-600,
+-80,
+-182,
+-79,
+182,
+44,
+-33,
+-700,
+101,
+319,
+-417,
+895,
+459,
+-155,
+550,
+-325,
+-645,
+-325,
+-94,
+-491,
+-460,
+284,
+-193,
+182,
+669,
+325,
+-58,
+122,
+520,
+-504,
+-423,
+169,
+169,
+360,
+-165,
+-195,
+-404,
+-161,
+42,
+-1156,
+-581,
+449,
+434,
+301,
+-41,
+405,
+544,
+298,
+-87,
+-716,
+46,
+322,
+-460,
+-590,
+-164,
+-28,
+-530,
+-140,
+141,
+138,
+776,
+514,
+-121,
+-461,
+380,
+1170,
+257,
+-32,
+10,
+-174,
+-114,
+-369,
+-771,
+-925,
+148,
+571,
+-413,
+-89,
+539,
+17,
+-87,
+6,
+-716,
+-392,
+683,
+124,
+-436,
+233,
+473,
+66,
+-198,
+-329,
+-478,
+-26,
+588,
+0,
+-475,
+362,
+483,
+-189,
+-145,
+-310,
+-516,
+-4,
+63,
+-461,
+-269,
+413,
+360,
+507,
+805,
+291,
+447,
+580,
+-383,
+-723,
+-312,
+-141,
+-270,
+-638,
+-824,
+-416,
+-89,
+-277,
+-126,
+476,
+1006,
+1010,
+898,
+1040,
+320,
+-185,
+-148,
+-794,
+-989,
+-1019,
+-972,
+-450,
+-210,
+17,
+-31,
+83,
+90,
+-138,
+415,
+219,
+-162,
+597,
+1156,
+1003,
+108,
+-376,
+-202,
+-291,
+-216,
+-644,
+-1095,
+-404,
+282,
+248,
+-150,
+145,
+371,
+-104,
+305,
+261,
+-512,
+-267,
+-101,
+-549,
+-553,
+59,
+260,
+350,
+557,
+-114,
+-223,
+495,
+388,
+278,
+414,
+177,
+22,
+23,
+29,
+-12,
+-65,
+90,
+-250,
+-756,
+-60,
+533,
+142,
+-76,
+-157,
+-181,
+193,
+-77,
+-1185,
+-1054,
+54,
+333,
+-124,
+-750,
+-431,
+700,
+1449,
+1017,
+-877,
+-1236,
+415,
+277,
+-586,
+-126,
+373,
+326,
+85,
+410,
+132,
+-361,
+185,
+-293,
+-440,
+915,
+1344,
+155,
+-698,
+262,
+519,
+-270,
+-431,
+-678,
+-693,
+-556,
+-294,
+78,
+-182,
+-325,
+-478,
+-675,
+-55,
+248,
+-404,
+-395,
+415,
+907,
+614,
+-206,
+-14,
+699,
+387,
+-135,
+-276,
+192,
+759,
+456,
+-263,
+-420,
+340,
+585,
+-128,
+-208,
+-114,
+111,
+781,
+93,
+-675,
+-99,
+-7,
+-560,
+-835,
+-647,
+-638,
+-199,
+853,
+291,
+-198,
+666,
+439,
+-127,
+-266,
+-457,
+-229,
+-134,
+-103,
+-678,
+-1277,
+-120,
+782,
+461,
+-101,
+124,
+985,
+421,
+-76,
+-128,
+-329,
+493,
+806,
+653,
+363,
+349,
+687,
+-593,
+-945,
+-67,
+-495,
+-1020,
+-1158,
+-869,
+-436,
+359,
+757,
+-753,
+-1234,
+42,
+680,
+217,
+-504,
+-137,
+609,
+934,
+333,
+-750,
+-252,
+867,
+632,
+-327,
+-104,
+951,
+1184,
+548,
+-529,
+-618,
+565,
+969,
+-179,
+-967,
+-184,
+680,
+735,
+-87,
+-1227,
+-985,
+125,
+-7,
+-1102,
+-794,
+676,
+669,
+-28,
+-332,
+-1333,
+-1237,
+513,
+1204,
+335,
+318,
+1758,
+420,
+-2489,
+-1776,
+76,
+-359,
+-1987,
+-1489,
+925,
+2204,
+2995,
+2332,
+306,
+1254,
+3049,
+1171,
+-1367,
+-1189,
+-468,
+-1397,
+-2357,
+-2116,
+-1536,
+-1060,
+-750,
+-790,
+-788,
+-75,
+638,
+683,
+699,
+383,
+91,
+642,
+911,
+258,
+-376,
+-362,
+-271,
+-167,
+241,
+296,
+308,
+650,
+945,
+999,
+883,
+953,
+946,
+418,
+-453,
+-808,
+-461,
+-706,
+-1258,
+-988,
+-434,
+-52,
+66,
+-123,
+151,
+679,
+428,
+-481,
+-509,
+771,
+714,
+-512,
+-1035,
+-1486,
+-726,
+-31,
+-1281,
+-1212,
+1309,
+2854,
+-717,
+-5541,
+-2528,
+4411,
+4364,
+-965,
+-2135,
+1605,
+6128,
+6542,
+901,
+-2670,
+955,
+3056,
+-1970,
+-6739,
+-4304,
+-1117,
+-2714,
+-3398,
+-2501,
+-995,
+1508,
+2242,
+360,
+-608,
+1734,
+2558,
+452,
+-246,
+119,
+-35,
+-26,
+448,
+260,
+60,
+1385,
+1602,
+292,
+541,
+1344,
+673,
+-386,
+-482,
+-556,
+-744,
+-250,
+-352,
+-906,
+-236,
+1023,
+238,
+-1847,
+-1223,
+598,
+466,
+107,
+156,
+44,
+587,
+1174,
+431,
+-1296,
+-1827,
+-647,
+-169,
+-780,
+-1298,
+-1319,
+-43,
+2335,
+3246,
+1074,
+-2402,
+-6047,
+-7079,
+-1059,
+4745,
+1480,
+-734,
+4822,
+9405,
+9224,
+5118,
+-67,
+-1939,
+-822,
+-1629,
+-6357,
+-8638,
+-5218,
+-2163,
+-2139,
+-2847,
+-1910,
+727,
+2801,
+3025,
+1442,
+682,
+1915,
+2640,
+1630,
+-328,
+-1203,
+-831,
+-587,
+-253,
+102,
+145,
+388,
+1416,
+1997,
+1157,
+750,
+902,
+285,
+-634,
+-968,
+-935,
+-1489,
+-1441,
+-559,
+-307,
+98,
+255,
+-79,
+393,
+757,
+383,
+-92,
+224,
+977,
+612,
+-250,
+-768,
+-1037,
+-1196,
+-1434,
+-1257,
+-528,
+53,
+-83,
+128,
+1382,
+1759,
+1323,
+-341,
+-8125,
+-13054,
+-157,
+15976,
+6087,
+-6341,
+5951,
+14103,
+11032,
+4159,
+-6743,
+-10446,
+-3027,
+1775,
+-9133,
+-16626,
+-6476,
+3326,
+1674,
+-3781,
+-1209,
+4156,
+6635,
+7114,
+2682,
+-1791,
+1685,
+5147,
+898,
+-4427,
+-3907,
+-1369,
+-1268,
+-375,
+-530,
+-1009,
+1666,
+3818,
+2716,
+1439,
+2971,
+2807,
+-334,
+-836,
+548,
+-1022,
+-3429,
+-2739,
+-1867,
+-1887,
+-494,
+346,
+44,
+972,
+2167,
+1438,
+-239,
+-396,
+-202,
+-971,
+-1043,
+-826,
+-696,
+13,
+401,
+-335,
+-805,
+129,
+226,
+-515,
+410,
+1208,
+717,
+88,
+-5350,
+-13627,
+-8527,
+10641,
+17424,
+-276,
+-2734,
+12987,
+14423,
+8109,
+-1717,
+-11484,
+-8209,
+-128,
+-4410,
+-16396,
+-14255,
+-1867,
+5154,
+1136,
+-2316,
+3394,
+8584,
+10376,
+6841,
+-603,
+-2497,
+2138,
+1684,
+-4646,
+-7354,
+-4663,
+-2188,
+-675,
+945,
+795,
+1892,
+5103,
+6024,
+3291,
+1198,
+1634,
+500,
+-1851,
+-2889,
+-3691,
+-3739,
+-1530,
+228,
+-833,
+-215,
+2780,
+3205,
+1946,
+1246,
+642,
+-103,
+-849,
+-1823,
+-3171,
+-2957,
+-1587,
+-1554,
+-1490,
+-322,
+710,
+1122,
+1530,
+1998,
+1508,
+689,
+476,
+669,
+754,
+-720,
+-4025,
+-6837,
+-7325,
+-6367,
+-2698,
+6174,
+12964,
+9699,
+7442,
+11835,
+10703,
+3935,
+-2704,
+-7836,
+-10023,
+-10369,
+-10922,
+-12144,
+-10017,
+-3153,
+3001,
+3870,
+4798,
+9021,
+10308,
+7988,
+4810,
+1285,
+-1649
+};
diff --git a/codec2/branches/0.7/unittest/hts1a_1300.h b/codec2/branches/0.7/unittest/hts1a_1300.h
new file mode 100644 (file)
index 0000000..a254ecc
--- /dev/null
@@ -0,0 +1,8002 @@
+short hts1a_1300[] = {
+0,
+1,
+1,
+2,
+2,
+3,
+2,
+2,
+2,
+3,
+2,
+4,
+2,
+2,
+-1,
+0,
+-2,
+0,
+2,
+2,
+-3,
+-2,
+-5,
+-2,
+-4,
+-1,
+-5,
+-5,
+-10,
+-11,
+-15,
+-9,
+-8,
+0,
+-4,
+-5,
+-10,
+-5,
+0,
+1,
+-3,
+7,
+3,
+2,
+0,
+6,
+10,
+12,
+5,
+8,
+9,
+7,
+13,
+13,
+5,
+19,
+23,
+14,
+3,
+0,
+7,
+10,
+9,
+0,
+-11,
+-18,
+-15,
+-16,
+-15,
+-27,
+-37,
+-46,
+-40,
+-37,
+-49,
+-80,
+-73,
+-65,
+-43,
+-10,
+39,
+72,
+88,
+82,
+82,
+66,
+57,
+34,
+38,
+32,
+28,
+17,
+28,
+7,
+1,
+-12,
+-1,
+-13,
+-2,
+-9,
+-11,
+-24,
+-16,
+-26,
+-16,
+-24,
+-11,
+-17,
+-11,
+-21,
+-14,
+-26,
+-11,
+-9,
+6,
+-11,
+-3,
+-9,
+2,
+-5,
+10,
+11,
+23,
+2,
+8,
+5,
+24,
+14,
+29,
+9,
+21,
+14,
+21,
+11,
+12,
+9,
+22,
+4,
+16,
+0,
+5,
+-2,
+-1,
+-12,
+2,
+-6,
+-13,
+-29,
+-22,
+-37,
+-25,
+-32,
+-29,
+-42,
+-45,
+-60,
+-51,
+-59,
+-45,
+-19,
+23,
+57,
+80,
+69,
+65,
+49,
+40,
+34,
+38,
+20,
+10,
+5,
+5,
+-6,
+-5,
+-10,
+-3,
+-7,
+-15,
+-20,
+-21,
+-16,
+-9,
+-17,
+-18,
+-21,
+-20,
+-9,
+-5,
+-5,
+-7,
+-19,
+-15,
+-4,
+2,
+6,
+-3,
+-3,
+1,
+8,
+7,
+16,
+12,
+7,
+3,
+5,
+15,
+22,
+15,
+17,
+12,
+16,
+6,
+13,
+-3,
+8,
+12,
+9,
+1,
+7,
+-1,
+6,
+-5,
+-1,
+-7,
+-9,
+-20,
+-17,
+-20,
+-3,
+-8,
+-1,
+-27,
+-35,
+-46,
+-36,
+-34,
+-21,
+-23,
+2,
+20,
+43,
+41,
+52,
+41,
+37,
+36,
+41,
+24,
+16,
+7,
+1,
+-18,
+-14,
+-22,
+-6,
+-4,
+-5,
+-8,
+-7,
+-15,
+-14,
+-20,
+-10,
+-21,
+-13,
+-3,
+-2,
+-7,
+0,
+1,
+-4,
+-10,
+-3,
+-1,
+-1,
+-4,
+-2,
+4,
+13,
+15,
+11,
+3,
+-4,
+3,
+4,
+2,
+7,
+13,
+9,
+9,
+9,
+6,
+0,
+1,
+-1,
+-1,
+3,
+5,
+1,
+0,
+-5,
+-2,
+-12,
+4,
+-7,
+-3,
+-11,
+-8,
+-6,
+-10,
+-14,
+-8,
+-16,
+-12,
+-19,
+-19,
+-20,
+-3,
+0,
+10,
+23,
+25,
+27,
+45,
+30,
+28,
+19,
+24,
+13,
+0,
+-15,
+-20,
+-17,
+-4,
+-9,
+-6,
+-5,
+-10,
+-9,
+0,
+-1,
+-7,
+-14,
+-14,
+-6,
+-6,
+4,
+0,
+-5,
+1,
+4,
+6,
+4,
+-1,
+3,
+-8,
+-4,
+1,
+11,
+9,
+12,
+6,
+1,
+1,
+10,
+6,
+-2,
+-3,
+9,
+7,
+4,
+4,
+0,
+-8,
+0,
+-3,
+-1,
+-2,
+-1,
+-6,
+-19,
+-10,
+-18,
+-13,
+-15,
+-14,
+-11,
+-6,
+-4,
+0,
+7,
+18,
+16,
+38,
+34,
+32,
+23,
+17,
+7,
+-6,
+-24,
+-17,
+-16,
+-9,
+-6,
+-5,
+-12,
+-3,
+-12,
+-5,
+-6,
+-5,
+-15,
+-6,
+-3,
+2,
+1,
+13,
+0,
+4,
+0,
+0,
+-1,
+7,
+6,
+11,
+4,
+2,
+4,
+9,
+5,
+7,
+-4,
+-1,
+0,
+7,
+-1,
+-7,
+1,
+1,
+1,
+0,
+-5,
+-10,
+-9,
+-9,
+-6,
+-13,
+-13,
+-9,
+-7,
+-10,
+-5,
+-3,
+10,
+12,
+27,
+21,
+26,
+17,
+13,
+9,
+2,
+-4,
+5,
+-10,
+-4,
+-18,
+-11,
+-15,
+-5,
+-6,
+2,
+-9,
+-5,
+-17,
+-15,
+-4,
+13,
+0,
+0,
+4,
+15,
+7,
+2,
+-4,
+0,
+-7,
+10,
+5,
+13,
+11,
+8,
+4,
+8,
+0,
+-1,
+0,
+3,
+-2,
+1,
+-3,
+0,
+0,
+-12,
+-14,
+-18,
+-15,
+-14,
+-15,
+-16,
+-7,
+3,
+9,
+7,
+12,
+17,
+24,
+25,
+27,
+16,
+10,
+-8,
+-2,
+-8,
+-8,
+-14,
+-10,
+-13,
+-2,
+-7,
+2,
+-12,
+-4,
+-9,
+3,
+-2,
+4,
+-2,
+13,
+1,
+7,
+-9,
+1,
+0,
+13,
+6,
+11,
+0,
+9,
+-2,
+6,
+-9,
+3,
+-9,
+10,
+-5,
+-7,
+-4,
+5,
+-22,
+-8,
+-28,
+-14,
+-23,
+-11,
+-16,
+7,
+13,
+31,
+24,
+35,
+27,
+33,
+16,
+20,
+5,
+3,
+-20,
+-6,
+-13,
+-2,
+-17,
+-10,
+-18,
+-2,
+-7,
+1,
+-10,
+-5,
+-12,
+-2,
+-6,
+4,
+-5,
+6,
+-3,
+-2,
+-9,
+-1,
+-5,
+1,
+0,
+3,
+-8,
+0,
+-5,
+0,
+-6,
+-13,
+-11,
+3,
+-4,
+-10,
+-18,
+-4,
+0,
+6,
+4,
+17,
+26,
+35,
+38,
+35,
+34,
+24,
+15,
+6,
+-2,
+0,
+0,
+5,
+0,
+-6,
+-10,
+-13,
+-12,
+-6,
+-10,
+-6,
+-2,
+-3,
+-13,
+-13,
+-8,
+-9,
+-9,
+-4,
+-10,
+-10,
+-8,
+-7,
+-15,
+-8,
+-8,
+-14,
+-11,
+-8,
+-9,
+-4,
+-20,
+-13,
+-3,
+-4,
+-11,
+-19,
+-16,
+1,
+4,
+15,
+21,
+39,
+45,
+56,
+49,
+48,
+30,
+26,
+8,
+4,
+-4,
+-5,
+-3,
+1,
+-5,
+-7,
+-17,
+-8,
+-4,
+-2,
+-11,
+-1,
+-5,
+-4,
+-9,
+-10,
+-7,
+-9,
+-13,
+-7,
+-2,
+-8,
+-10,
+-14,
+-19,
+-12,
+-4,
+-6,
+-10,
+-11,
+-11,
+-14,
+-9,
+-11,
+-4,
+-8,
+-5,
+-11,
+-17,
+-16,
+-6,
+-3,
+15,
+15,
+38,
+45,
+56,
+53,
+49,
+32,
+31,
+11,
+14,
+-7,
+-5,
+-10,
+1,
+-10,
+-8,
+-22,
+-5,
+-10,
+-7,
+-21,
+-2,
+-12,
+2,
+-13,
+-1,
+-11,
+-4,
+-17,
+4,
+0,
+1,
+-7,
+0,
+-6,
+11,
+5,
+4,
+-7,
+2,
+-10,
+1,
+-8,
+-3,
+-7,
+1,
+-11,
+-13,
+-26,
+-16,
+-29,
+-11,
+-12,
+2,
+11,
+27,
+32,
+37,
+32,
+43,
+27,
+25,
+12,
+9,
+-4,
+-11,
+-25,
+-20,
+-18,
+-11,
+-13,
+-8,
+-8,
+-8,
+-16,
+-14,
+-5,
+4,
+6,
+10,
+5,
+8,
+7,
+4,
+16,
+8,
+2,
+4,
+9,
+13,
+15,
+4,
+0,
+0,
+-3,
+-1,
+-2,
+-7,
+-6,
+-1,
+-6,
+-12,
+-20,
+-21,
+-29,
+-29,
+-16,
+-14,
+-3,
+9,
+16,
+26,
+31,
+43,
+37,
+31,
+23,
+15,
+7,
+-5,
+-22,
+-23,
+-23,
+-18,
+-18,
+-16,
+-18,
+-5,
+-10,
+-9,
+-16,
+-7,
+-6,
+7,
+1,
+12,
+7,
+18,
+9,
+11,
+0,
+5,
+0,
+15,
+8,
+23,
+8,
+7,
+-6,
+3,
+-8,
+10,
+-4,
+6,
+-10,
+2,
+-18,
+-1,
+-12,
+-13,
+-32,
+-24,
+-28,
+-15,
+-29,
+1,
+-6,
+15,
+21,
+45,
+41,
+47,
+32,
+31,
+14,
+12,
+-11,
+-9,
+-19,
+-15,
+-23,
+-16,
+-28,
+-10,
+-15,
+-5,
+-19,
+-12,
+-11,
+3,
+-4,
+4,
+1,
+7,
+7,
+1,
+-1,
+4,
+6,
+16,
+10,
+14,
+13,
+11,
+8,
+7,
+5,
+7,
+5,
+3,
+4,
+1,
+-9,
+-7,
+-8,
+-15,
+-11,
+-20,
+-22,
+-26,
+-26,
+-28,
+-23,
+-17,
+-2,
+5,
+30,
+39,
+56,
+47,
+46,
+29,
+23,
+3,
+7,
+-7,
+-1,
+-22,
+-22,
+-33,
+-25,
+-30,
+-19,
+-17,
+-11,
+-22,
+-2,
+-5,
+0,
+-6,
+12,
+2,
+19,
+2,
+11,
+8,
+16,
+13,
+16,
+4,
+14,
+5,
+13,
+0,
+7,
+-1,
+5,
+-3,
+7,
+-1,
+-2,
+-6,
+-4,
+-16,
+-6,
+-12,
+-7,
+-13,
+-12,
+-23,
+-22,
+-30,
+-20,
+-23,
+-6,
+-1,
+15,
+18,
+29,
+33,
+42,
+36,
+44,
+36,
+34,
+21,
+7,
+-7,
+-11,
+-19,
+-28,
+-32,
+-23,
+-25,
+-16,
+-25,
+-23,
+-26,
+-25,
+-12,
+-4,
+-1,
+0,
+3,
+7,
+4,
+7,
+7,
+12,
+14,
+4,
+15,
+16,
+15,
+15,
+14,
+5,
+8,
+4,
+6,
+4,
+6,
+11,
+4,
+6,
+5,
+-4,
+-10,
+-9,
+-4,
+-5,
+-8,
+-12,
+-17,
+-24,
+-30,
+-28,
+-30,
+-32,
+-28,
+-22,
+-16,
+-5,
+6,
+15,
+27,
+44,
+52,
+61,
+50,
+46,
+36,
+31,
+17,
+1,
+-5,
+-9,
+-15,
+-18,
+-28,
+-26,
+-34,
+-34,
+-32,
+-25,
+-24,
+-19,
+-17,
+-12,
+-9,
+0,
+-6,
+7,
+0,
+13,
+9,
+15,
+12,
+16,
+10,
+14,
+13,
+22,
+14,
+17,
+0,
+9,
+1,
+7,
+7,
+16,
+4,
+9,
+-7,
+-2,
+-7,
+4,
+-2,
+3,
+-3,
+-4,
+-22,
+-9,
+-18,
+-11,
+-19,
+-4,
+-16,
+-22,
+-33,
+-31,
+-40,
+-29,
+-32,
+-14,
+-8,
+17,
+26,
+51,
+45,
+57,
+53,
+60,
+53,
+53,
+36,
+31,
+16,
+12,
+-7,
+-18,
+-32,
+-36,
+-44,
+-39,
+-45,
+-36,
+-41,
+-35,
+-31,
+-24,
+-28,
+-17,
+-14,
+-2,
+-6,
+0,
+8,
+18,
+18,
+19,
+24,
+18,
+11,
+19,
+12,
+15,
+18,
+20,
+19,
+18,
+13,
+9,
+4,
+8,
+6,
+5,
+0,
+1,
+-5,
+0,
+3,
+4,
+6,
+4,
+6,
+3,
+-5,
+-7,
+-16,
+-18,
+-19,
+-12,
+-4,
+-7,
+-14,
+-24,
+-32,
+-42,
+-39,
+-43,
+-39,
+-30,
+-29,
+-25,
+-20,
+-5,
+3,
+16,
+33,
+49,
+68,
+79,
+81,
+84,
+77,
+70,
+58,
+41,
+26,
+9,
+-1,
+-16,
+-30,
+-39,
+-49,
+-53,
+-50,
+-52,
+-51,
+-46,
+-40,
+-41,
+-36,
+-33,
+-27,
+-18,
+-10,
+3,
+9,
+9,
+16,
+13,
+14,
+10,
+14,
+14,
+11,
+7,
+10,
+21,
+23,
+19,
+16,
+12,
+7,
+2,
+3,
+7,
+8,
+7,
+10,
+10,
+15,
+14,
+6,
+2,
+-5,
+-1,
+-4,
+-3,
+-3,
+-3,
+1,
+-1,
+-2,
+-3,
+-12,
+-16,
+-18,
+-12,
+-11,
+-10,
+-6,
+-3,
+-12,
+-19,
+-19,
+-23,
+-24,
+-22,
+-22,
+-34,
+-39,
+-33,
+-31,
+-18,
+-2,
+21,
+51,
+69,
+82,
+92,
+87,
+86,
+77,
+61,
+42,
+19,
+0,
+-11,
+-21,
+-33,
+-43,
+-46,
+-50,
+-54,
+-59,
+-53,
+-47,
+-42,
+-34,
+-26,
+-16,
+-10,
+-1,
+0,
+-2,
+-1,
+9,
+10,
+15,
+22,
+27,
+16,
+3,
+7,
+2,
+11,
+16,
+15,
+16,
+11,
+10,
+4,
+3,
+8,
+4,
+10,
+6,
+6,
+8,
+3,
+0,
+-1,
+2,
+-1,
+-2,
+-4,
+-4,
+-3,
+0,
+-3,
+-6,
+-7,
+-8,
+-13,
+-15,
+-13,
+-12,
+-14,
+-12,
+-15,
+-17,
+-24,
+-32,
+-36,
+-41,
+-40,
+-26,
+-12,
+7,
+25,
+41,
+63,
+79,
+80,
+82,
+70,
+63,
+50,
+24,
+7,
+-6,
+-17,
+-35,
+-38,
+-33,
+-38,
+-40,
+-45,
+-45,
+-31,
+-30,
+-24,
+-17,
+-18,
+-13,
+-5,
+3,
+3,
+6,
+5,
+8,
+7,
+10,
+11,
+9,
+11,
+9,
+8,
+6,
+5,
+10,
+11,
+10,
+10,
+10,
+4,
+6,
+7,
+6,
+5,
+7,
+11,
+9,
+9,
+11,
+9,
+4,
+1,
+-2,
+-3,
+3,
+4,
+0,
+-6,
+-13,
+-15,
+-22,
+-26,
+-25,
+-25,
+-19,
+-18,
+-22,
+-27,
+-28,
+-35,
+-36,
+-35,
+-19,
+-1,
+21,
+39,
+64,
+69,
+73,
+70,
+64,
+47,
+34,
+15,
+1,
+-13,
+-16,
+-31,
+-30,
+-39,
+-32,
+-29,
+-17,
+-19,
+-21,
+-17,
+-3,
+-16,
+-7,
+-8,
+3,
+-2,
+4,
+-4,
+0,
+-12,
+0,
+6,
+5,
+0,
+7,
+4,
+9,
+0,
+17,
+6,
+8,
+7,
+12,
+8,
+17,
+2,
+5,
+1,
+6,
+5,
+7,
+5,
+6,
+-2,
+-3,
+-3,
+0,
+-11,
+0,
+1,
+0,
+-6,
+-9,
+-18,
+-6,
+-8,
+-9,
+-14,
+-4,
+-14,
+-19,
+-29,
+-28,
+-29,
+-23,
+-22,
+-7,
+3,
+25,
+39,
+59,
+66,
+68,
+59,
+51,
+30,
+16,
+-2,
+-14,
+-25,
+-26,
+-40,
+-24,
+-25,
+-12,
+-16,
+-13,
+-17,
+-10,
+-21,
+-10,
+-14,
+-1,
+-9,
+3,
+0,
+1,
+-8,
+5,
+-8,
+-2,
+-3,
+14,
+6,
+17,
+1,
+11,
+5,
+4,
+-10,
+15,
+3,
+12,
+7,
+14,
+8,
+15,
+2,
+8,
+-4,
+9,
+0,
+5,
+-5,
+8,
+-6,
+0,
+-6,
+0,
+-15,
+-10,
+-23,
+-15,
+-15,
+-6,
+-20,
+-12,
+-20,
+-17,
+-27,
+-18,
+-14,
+7,
+13,
+32,
+42,
+56,
+43,
+45,
+34,
+26,
+10,
+-2,
+-14,
+-10,
+-25,
+-21,
+-22,
+-12,
+-18,
+-11,
+-9,
+-17,
+-12,
+-7,
+-15,
+-1,
+0,
+-1,
+-1,
+1,
+-12,
+-8,
+2,
+8,
+12,
+7,
+9,
+4,
+4,
+3,
+7,
+4,
+12,
+6,
+10,
+15,
+15,
+3,
+-3,
+-5,
+3,
+6,
+6,
+0,
+1,
+-4,
+-3,
+-9,
+-13,
+-10,
+-9,
+-9,
+-4,
+-9,
+-12,
+-20,
+-23,
+-26,
+-27,
+-26,
+-12,
+2,
+19,
+38,
+45,
+48,
+54,
+44,
+26,
+15,
+6,
+-5,
+-10,
+-17,
+-21,
+-18,
+-18,
+-21,
+-16,
+-12,
+-14,
+-9,
+-9,
+-16,
+-7,
+3,
+2,
+0,
+1,
+-3,
+9,
+12,
+1,
+-3,
+0,
+3,
+16,
+10,
+8,
+10,
+13,
+4,
+2,
+7,
+15,
+5,
+5,
+3,
+1,
+-6,
+1,
+-4,
+-6,
+-7,
+-3,
+-20,
+-7,
+-17,
+-12,
+-18,
+-14,
+-21,
+-25,
+-34,
+-20,
+-22,
+-2,
+18,
+44,
+52,
+70,
+50,
+47,
+22,
+4,
+-6,
+-12,
+-21,
+-17,
+-20,
+-10,
+-18,
+-16,
+-15,
+-10,
+-11,
+-9,
+-5,
+0,
+-8,
+-2,
+0,
+-4,
+-3,
+-1,
+4,
+7,
+13,
+12,
+8,
+0,
+7,
+5,
+10,
+5,
+9,
+9,
+6,
+-9,
+-1,
+0,
+7,
+-1,
+7,
+-5,
+0,
+-18,
+-14,
+-14,
+2,
+-2,
+-9,
+-34,
+-27,
+-34,
+-18,
+-22,
+4,
+9,
+47,
+47,
+67,
+53,
+50,
+20,
+11,
+-18,
+-2,
+-33,
+-14,
+-16,
+-5,
+-14,
+2,
+-21,
+0,
+-11,
+0,
+-21,
+0,
+-11,
+-1,
+-10,
+5,
+-17,
+5,
+-8,
+13,
+-3,
+9,
+-1,
+17,
+-1,
+18,
+2,
+16,
+2,
+21,
+1,
+18,
+-5,
+10,
+-7,
+9,
+-12,
+8,
+-17,
+-5,
+-29,
+-14,
+-31,
+-3,
+-27,
+-16,
+-35,
+-11,
+-9,
+32,
+16,
+54,
+43,
+46,
+14,
+20,
+-19,
+3,
+-11,
+5,
+-25,
+-2,
+-17,
+-4,
+-25,
+7,
+-17,
+2,
+-19,
+1,
+-6,
+11,
+-17,
+0,
+-9,
+28,
+1,
+16,
+-9,
+9,
+2,
+23,
+7,
+20,
+0,
+13,
+-3,
+14,
+-7,
+9,
+-4,
+3,
+-14,
+0,
+-21,
+3,
+-11,
+-12,
+-23,
+-17,
+-42,
+-20,
+-45,
+-46,
+-39,
+-24,
+-22,
+11,
+-2,
+39,
+89,
+134,
+120,
+101,
+57,
+24,
+3,
+1,
+-50,
+-71,
+-68,
+-47,
+-53,
+-38,
+-30,
+-33,
+-19,
+-9,
+-27,
+-3,
+-3,
+-14,
+-9,
+11,
+12,
+13,
+0,
+19,
+29,
+13,
+16,
+25,
+19,
+18,
+18,
+24,
+15,
+23,
+26,
+13,
+16,
+18,
+11,
+3,
+-4,
+-2,
+-3,
+-28,
+-30,
+-22,
+-42,
+-41,
+-34,
+-50,
+-35,
+-34,
+-69,
+-66,
+-76,
+-101,
+-94,
+-109,
+-80,
+16,
+103,
+192,
+318,
+337,
+259,
+220,
+156,
+64,
+6,
+-55,
+-127,
+-185,
+-195,
+-185,
+-182,
+-146,
+-143,
+-137,
+-71,
+-18,
+3,
+22,
+42,
+46,
+58,
+66,
+57,
+53,
+44,
+30,
+21,
+11,
+8,
+-1,
+6,
+7,
+15,
+24,
+30,
+33,
+39,
+42,
+40,
+47,
+63,
+59,
+47,
+31,
+14,
+-5,
+-19,
+-28,
+-45,
+-46,
+-55,
+-55,
+-65,
+-72,
+-87,
+-100,
+-97,
+-100,
+-99,
+-127,
+-147,
+-166,
+-184,
+-204,
+-177,
+-157,
+-17,
+398,
+737,
+863,
+867,
+696,
+510,
+337,
+155,
+-43,
+-288,
+-535,
+-694,
+-732,
+-710,
+-658,
+-558,
+-493,
+-392,
+-178,
+40,
+186,
+298,
+359,
+366,
+397,
+439,
+372,
+242,
+150,
+30,
+-79,
+-127,
+-173,
+-207,
+-219,
+-151,
+-86,
+-12,
+69,
+136,
+170,
+198,
+223,
+227,
+212,
+183,
+145,
+68,
+8,
+-23,
+-56,
+-76,
+-84,
+-104,
+-137,
+-199,
+-222,
+-219,
+-193,
+-154,
+-109,
+-85,
+-48,
+-34,
+-45,
+-79,
+-106,
+-163,
+-189,
+-284,
+-388,
+-491,
+-520,
+-528,
+-492,
+-334,
+-181,
+337,
+1588,
+2517,
+2790,
+2658,
+2100,
+1398,
+804,
+193,
+-514,
+-1413,
+-2214,
+-2762,
+-2872,
+-2689,
+-2341,
+-1805,
+-1254,
+-671,
+197,
+1134,
+1850,
+2271,
+2443,
+2238,
+1863,
+1564,
+1131,
+361,
+-457,
+-1179,
+-1843,
+-2236,
+-2234,
+-2109,
+-1937,
+-1485,
+-755,
+-24,
+787,
+1557,
+2039,
+2226,
+2373,
+2324,
+1994,
+1476,
+844,
+37,
+-724,
+-1258,
+-1640,
+-1935,
+-1977,
+-1798,
+-1435,
+-968,
+-344,
+216,
+675,
+1089,
+1400,
+1518,
+1429,
+1249,
+876,
+412,
+-33,
+-430,
+-785,
+-1070,
+-1170,
+-1277,
+-1314,
+-1269,
+-1110,
+-978,
+-804,
+-609,
+-641,
+-697,
+-651,
+-552,
+-494,
+-325,
+135,
+500,
+2215,
+5495,
+6796,
+6052,
+5042,
+3147,
+1215,
+116,
+-1002,
+-3144,
+-5589,
+-6520,
+-6317,
+-5735,
+-4288,
+-2890,
+-2091,
+-759,
+1408,
+3363,
+4471,
+4948,
+4826,
+3928,
+3044,
+2389,
+1098,
+-649,
+-2099,
+-3161,
+-3899,
+-4013,
+-3612,
+-3199,
+-2637,
+-1418,
+9,
+1187,
+2276,
+3095,
+3361,
+3341,
+3278,
+2863,
+1960,
+1001,
+31,
+-1000,
+-1789,
+-2155,
+-2455,
+-2552,
+-2271,
+-1698,
+-1070,
+-305,
+507,
+1062,
+1471,
+1806,
+1930,
+1752,
+1427,
+964,
+339,
+-303,
+-834,
+-1274,
+-1591,
+-1681,
+-1594,
+-1359,
+-1020,
+-649,
+-326,
+-41,
+192,
+413,
+493,
+346,
+-75,
+-535,
+-949,
+-1245,
+-1428,
+-1321,
+-980,
+-317,
+2528,
+6139,
+7000,
+6364,
+5218,
+3303,
+1706,
+628,
+-795,
+-3546,
+-5920,
+-6498,
+-6545,
+-6103,
+-4835,
+-3917,
+-3066,
+-1293,
+1199,
+3039,
+3927,
+4666,
+4768,
+4350,
+4274,
+3789,
+2220,
+377,
+-1035,
+-2202,
+-3198,
+-3586,
+-3753,
+-3980,
+-3515,
+-2339,
+-1137,
+-45,
+1100,
+2067,
+2672,
+3234,
+3600,
+3294,
+2586,
+1853,
+987,
+2,
+-850,
+-1499,
+-2112,
+-2413,
+-2256,
+-1928,
+-1532,
+-945,
+-262,
+366,
+972,
+1480,
+1667,
+1590,
+1400,
+1114,
+714,
+239,
+-184,
+-534,
+-877,
+-1107,
+-1193,
+-1275,
+-1284,
+-1066,
+-770,
+-586,
+-439,
+-277,
+-199,
+-166,
+-58,
+-137,
+-537,
+-864,
+-1068,
+-1254,
+-1350,
+-1073,
+-581,
+291,
+3441,
+7266,
+8090,
+7061,
+5406,
+3345,
+1467,
+10,
+-1669,
+-4631,
+-6887,
+-6956,
+-6475,
+-5812,
+-4678,
+-3607,
+-2441,
+-531,
+2202,
+3894,
+4422,
+4836,
+4817,
+4194,
+3508,
+2578,
+947,
+-906,
+-1956,
+-2704,
+-3506,
+-3806,
+-3708,
+-3506,
+-2837,
+-1548,
+-261,
+710,
+1659,
+2504,
+2934,
+3179,
+3249,
+2844,
+2061,
+1358,
+616,
+-247,
+-975,
+-1414,
+-1790,
+-1969,
+-1781,
+-1391,
+-1000,
+-548,
+140,
+701,
+1053,
+1344,
+1397,
+1199,
+923,
+652,
+241,
+-257,
+-572,
+-828,
+-1058,
+-1161,
+-1162,
+-1141,
+-996,
+-631,
+-296,
+-10,
+279,
+423,
+307,
+137,
+-64,
+-363,
+-676,
+-897,
+-1239,
+-1631,
+-1853,
+-1864,
+-1797,
+-1355,
+-681,
+342,
+2668,
+6898,
+9692,
+9193,
+7285,
+4881,
+2444,
+230,
+-1644,
+-4223,
+-7340,
+-8228,
+-7415,
+-6573,
+-5662,
+-4441,
+-2955,
+-1304,
+1388,
+3742,
+4299,
+4524,
+4932,
+4858,
+4111,
+3152,
+1788,
+-254,
+-1512,
+-2051,
+-2934,
+-3781,
+-3890,
+-3579,
+-3057,
+-1982,
+-708,
+-11,
+683,
+1632,
+2286,
+2472,
+2621,
+2660,
+2229,
+1872,
+1752,
+1188,
+366,
+-264,
+-774,
+-1311,
+-1553,
+-1552,
+-1748,
+-1830,
+-1453,
+-964,
+-523,
+-8,
+474,
+765,
+1050,
+1356,
+1343,
+1042,
+833,
+623,
+350,
+90,
+-155,
+-527,
+-898,
+-1037,
+-1049,
+-1037,
+-957,
+-808,
+-603,
+-439,
+-291,
+-303,
+-458,
+-601,
+-511,
+-491,
+-695,
+-960,
+-1106,
+-1124,
+-1013,
+-616,
+-129,
+1213,
+5183,
+8228,
+7688,
+5918,
+3998,
+2165,
+464,
+-1063,
+-2909,
+-5096,
+-5447,
+-4841,
+-4942,
+-5007,
+-4437,
+-3402,
+-1980,
+-204,
+1295,
+1952,
+2731,
+3668,
+3893,
+3588,
+3107,
+2463,
+1659,
+952,
+248,
+-785,
+-1655,
+-2032,
+-2130,
+-2199,
+-2108,
+-1876,
+-1482,
+-1012,
+-360,
+102,
+458,
+793,
+1145,
+1295,
+1284,
+1138,
+1002,
+843,
+739,
+622,
+451,
+377,
+481,
+375,
+155,
+-17,
+-117,
+-238,
+-274,
+-402,
+-593,
+-772,
+-748,
+-776,
+-836,
+-809,
+-643,
+-500,
+-319,
+-144,
+7,
+123,
+323,
+472,
+579,
+574,
+458,
+214,
+-122,
+-464,
+-744,
+-859,
+-976,
+-1160,
+-1370,
+-1517,
+-1518,
+-1444,
+-982,
+-524,
+1029,
+4637,
+6859,
+5961,
+4565,
+3378,
+2129,
+1090,
+-15,
+-1187,
+-2183,
+-2343,
+-2444,
+-3464,
+-4397,
+-4442,
+-4000,
+-3218,
+-2264,
+-1375,
+-581,
+369,
+1273,
+1793,
+2064,
+2506,
+2839,
+2890,
+2653,
+2186,
+1589,
+1011,
+404,
+-166,
+-700,
+-1027,
+-1311,
+-1499,
+-1686,
+-1744,
+-1678,
+-1455,
+-1118,
+-694,
+-282,
+102,
+418,
+670,
+812,
+971,
+1153,
+1304,
+1331,
+1250,
+1065,
+836,
+544,
+266,
+-3,
+-156,
+-180,
+-268,
+-519,
+-707,
+-805,
+-809,
+-840,
+-840,
+-795,
+-698,
+-521,
+-314,
+-146,
+-32,
+10,
+49,
+-12,
+-107,
+-245,
+-376,
+-365,
+-344,
+-348,
+-490,
+-668,
+-736,
+-795,
+-556,
+-286,
+348,
+2825,
+5387,
+5002,
+3315,
+2393,
+1505,
+702,
+211,
+-402,
+-751,
+-684,
+-948,
+-2080,
+-3432,
+-3953,
+-3680,
+-3103,
+-2450,
+-1818,
+-1127,
+-419,
+-9,
+145,
+370,
+965,
+1734,
+2356,
+2572,
+2423,
+2145,
+1741,
+1238,
+753,
+441,
+293,
+89,
+-239,
+-724,
+-1212,
+-1515,
+-1602,
+-1528,
+-1360,
+-1120,
+-814,
+-541,
+-344,
+-138,
+109,
+394,
+709,
+981,
+1141,
+1192,
+1141,
+1008,
+851,
+720,
+599,
+454,
+287,
+95,
+-114,
+-311,
+-473,
+-583,
+-621,
+-636,
+-712,
+-775,
+-779,
+-784,
+-771,
+-761,
+-763,
+-783,
+-811,
+-779,
+-618,
+-374,
+-158,
+-116,
+-126,
+-142,
+-180,
+-17,
+183,
+843,
+2996,
+4968,
+4288,
+2646,
+1929,
+1208,
+464,
+249,
+54,
+97,
+424,
+-99,
+-1685,
+-3049,
+-3497,
+-3422,
+-3049,
+-2480,
+-1883,
+-1313,
+-971,
+-995,
+-1134,
+-862,
+-44,
+911,
+1655,
+2068,
+2191,
+2109,
+1843,
+1522,
+1281,
+1239,
+1303,
+1226,
+867,
+312,
+-232,
+-667,
+-949,
+-1075,
+-1019,
+-885,
+-784,
+-781,
+-840,
+-844,
+-719,
+-468,
+-182,
+102,
+358,
+515,
+586,
+572,
+552,
+521,
+510,
+525,
+508,
+444,
+316,
+152,
+-43,
+-233,
+-378,
+-474,
+-520,
+-567,
+-643,
+-757,
+-884,
+-985,
+-1056,
+-1022,
+-850,
+-637,
+-464,
+-411,
+-391,
+-371,
+-257,
+90,
+368,
+1460,
+3843,
+4975,
+3682,
+2294,
+1470,
+670,
+290,
+146,
+-168,
+-205,
+-298,
+-1151,
+-2520,
+-3381,
+-3395,
+-2867,
+-2241,
+-1657,
+-1224,
+-844,
+-576,
+-415,
+-281,
+229,
+991,
+1680,
+2012,
+2055,
+1855,
+1640,
+1354,
+1090,
+820,
+679,
+499,
+236,
+-195,
+-618,
+-944,
+-1077,
+-1123,
+-1024,
+-908,
+-695,
+-525,
+-369,
+-278,
+-117,
+80,
+334,
+530,
+688,
+723,
+751,
+652,
+579,
+443,
+379,
+294,
+223,
+63,
+-111,
+-338,
+-485,
+-601,
+-615,
+-630,
+-594,
+-629,
+-644,
+-725,
+-794,
+-872,
+-788,
+-650,
+-486,
+-471,
+-540,
+-571,
+-526,
+-364,
+-37,
+309,
+1862,
+4190,
+4600,
+3152,
+2067,
+1274,
+715,
+616,
+523,
+145,
+-155,
+-547,
+-1396,
+-2551,
+-3151,
+-3128,
+-2715,
+-2181,
+-1744,
+-1572,
+-1324,
+-954,
+-541,
+-102,
+497,
+1104,
+1662,
+1956,
+2016,
+1834,
+1620,
+1420,
+1287,
+1066,
+814,
+492,
+208,
+-116,
+-426,
+-722,
+-859,
+-916,
+-843,
+-804,
+-724,
+-686,
+-553,
+-410,
+-212,
+-34,
+169,
+325,
+453,
+488,
+492,
+437,
+464,
+415,
+396,
+282,
+183,
+3,
+-131,
+-280,
+-386,
+-526,
+-568,
+-646,
+-701,
+-839,
+-898,
+-980,
+-910,
+-809,
+-687,
+-610,
+-516,
+-430,
+-315,
+-150,
+167,
+562,
+2306,
+4506,
+4563,
+3127,
+2021,
+1106,
+548,
+416,
+226,
+-298,
+-721,
+-1105,
+-1838,
+-2796,
+-3160,
+-2969,
+-2491,
+-1878,
+-1259,
+-868,
+-516,
+-136,
+260,
+592,
+1021,
+1463,
+1763,
+1817,
+1633,
+1225,
+923,
+715,
+559,
+317,
+100,
+-186,
+-453,
+-747,
+-894,
+-966,
+-885,
+-728,
+-518,
+-383,
+-221,
+-79,
+98,
+282,
+440,
+522,
+588,
+604,
+577,
+468,
+399,
+310,
+258,
+162,
+39,
+-141,
+-279,
+-357,
+-398,
+-430,
+-458,
+-513,
+-578,
+-673,
+-753,
+-848,
+-811,
+-683,
+-575,
+-540,
+-541,
+-543,
+-532,
+-355,
+-14,
+501,
+2415,
+4789,
+4874,
+3247,
+1809,
+813,
+340,
+298,
+5,
+-896,
+-1698,
+-2031,
+-2557,
+-3148,
+-3246,
+-2873,
+-2215,
+-1395,
+-706,
+-313,
+16,
+617,
+1239,
+1719,
+2007,
+2086,
+1953,
+1662,
+1308,
+898,
+448,
+0,
+-343,
+-637,
+-864,
+-1045,
+-1159,
+-1080,
+-895,
+-587,
+-272,
+58,
+315,
+587,
+663,
+658,
+714,
+798,
+799,
+685,
+474,
+191,
+-66,
+-284,
+-456,
+-592,
+-671,
+-709,
+-692,
+-605,
+-521,
+-430,
+-361,
+-321,
+-307,
+-343,
+-402,
+-452,
+-385,
+-431,
+-538,
+-653,
+-767,
+-798,
+-722,
+-333,
+74,
+2319,
+6417,
+7237,
+4578,
+1893,
+80,
+-534,
+-305,
+-518,
+-2023,
+-3525,
+-3760,
+-3773,
+-3936,
+-3578,
+-2753,
+-1490,
+63,
+1233,
+1601,
+1711,
+2132,
+2565,
+2695,
+2518,
+1948,
+1219,
+528,
+-152,
+-810,
+-1410,
+-1721,
+-1920,
+-1947,
+-1724,
+-1397,
+-867,
+-186,
+379,
+817,
+1180,
+1475,
+1649,
+1664,
+1540,
+1277,
+916,
+479,
+9,
+-409,
+-756,
+-979,
+-1131,
+-1198,
+-1176,
+-971,
+-620,
+-254,
+26,
+163,
+125,
+128,
+93,
+-31,
+-292,
+-478,
+-635,
+-953,
+-1380,
+-1583,
+-1644,
+-1419,
+-1152,
+-399,
+251,
+4499,
+10959,
+10640,
+5605,
+940,
+-1797,
+-1900,
+-912,
+-1437,
+-4530,
+-6791,
+-6083,
+-4884,
+-3823,
+-2752,
+-1802,
+-493,
+1411,
+3196,
+3629,
+3332,
+3298,
+3084,
+2571,
+1731,
+518,
+-743,
+-1456,
+-1563,
+-1716,
+-1912,
+-1821,
+-1440,
+-688,
+139,
+720,
+993,
+1170,
+1393,
+1542,
+1498,
+1215,
+727,
+218,
+-303,
+-680,
+-897,
+-986,
+-982,
+-935,
+-801,
+-570,
+-336,
+-50,
+215,
+398,
+461,
+412,
+177,
+-178,
+-514,
+-799,
+-1120,
+-1238,
+-1446,
+-1914,
+-2206,
+-2069,
+-1724,
+-1218,
+-675,
+403,
+1587,
+10391,
+17960,
+12996,
+4106,
+-3204,
+-5756,
+-3983,
+-2049,
+-4025,
+-10017,
+-11376,
+-7444,
+-3275,
+-60,
+751,
+750,
+1933,
+5097,
+7442,
+6069,
+3469,
+1246,
+87,
+103,
+-526,
+-2235,
+-4086,
+-4202,
+-2776,
+-1238,
+-34,
+354,
+956,
+2050,
+2908,
+3065,
+2242,
+1311,
+557,
+-49,
+-425,
+-1171,
+-1757,
+-1790,
+-1290,
+-594,
+-357,
+-284,
+-212,
+122,
+809,
+1042,
+818,
+168,
+-69,
+474,
+421,
+-452,
+-1605,
+-2380,
+-2274,
+-1574,
+-1230,
+-2216,
+-2752,
+-2511,
+-1407,
+-640,
+312,
+676,
+4389,
+19943,
+23784,
+11922,
+-2128,
+-11491,
+-10505,
+-5286,
+-2405,
+-8670,
+-16588,
+-12890,
+-4652,
+2789,
+5901,
+4161,
+3109,
+5802,
+10495,
+9957,
+4443,
+-427,
+-3507,
+-3885,
+-3529,
+-4689,
+-6813,
+-7109,
+-4011,
+-349,
+1936,
+2980,
+3045,
+3496,
+4643,
+5230,
+4065,
+1849,
+-118,
+-1173,
+-1445,
+-2042,
+-2893,
+-3375,
+-2894,
+-1254,
+274,
+1038,
+1307,
+2290,
+2781,
+2132,
+1267,
+106,
+-630,
+-884,
+-1637,
+-2480,
+-3193,
+-3014,
+-2220,
+-1334,
+-981,
+-1771,
+-2146,
+-1551,
+-431,
+200,
+527,
+742,
+3176,
+17053,
+21910,
+10382,
+-1289,
+-7789,
+-6810,
+-3716,
+-4452,
+-11521,
+-16921,
+-10358,
+-1918,
+2356,
+3087,
+1882,
+3618,
+8258,
+11358,
+8237,
+2385,
+-273,
+-1011,
+-759,
+-2180,
+-5560,
+-7378,
+-5592,
+-2185,
+-744,
+-524,
+8,
+1316,
+3802,
+5109,
+4298,
+2707,
+1756,
+1418,
+649,
+-450,
+-1740,
+-2189,
+-1271,
+-1100,
+-1679,
+-1844,
+-1360,
+-592,
+-325,
+-144,
+133,
+745,
+1554,
+1549,
+852,
+513,
+308,
+-135,
+-795,
+-1430,
+-1921,
+-2655,
+-3667,
+-3859,
+-3421,
+-2082,
+-855,
+743,
+1367,
+11088,
+21800,
+14144,
+3001,
+-2687,
+-3697,
+-1984,
+-3637,
+-10176,
+-15992,
+-11894,
+-4093,
+-1757,
+-1223,
+-662,
+2685,
+8279,
+10945,
+8109,
+3635,
+2661,
+2783,
+892,
+-2400,
+-6211,
+-7154,
+-4982,
+-2746,
+-2283,
+-2438,
+-971,
+1750,
+3884,
+4493,
+3457,
+2951,
+3329,
+2881,
+1281,
+-590,
+-1789,
+-2085,
+-2185,
+-2296,
+-2621,
+-2183,
+-1219,
+-538,
+-59,
+510,
+1243,
+1925,
+1929,
+1515,
+982,
+511,
+-433,
+-1173,
+-1845,
+-2172,
+-2228,
+-2871,
+-3663,
+-3279,
+-2056,
+-670,
+256,
+1334,
+2850,
+15158,
+19429,
+7039,
+-384,
+-1970,
+-1342,
+-1607,
+-6796,
+-13500,
+-14145,
+-6652,
+-2427,
+-3188,
+-2202,
+996,
+6164,
+9815,
+8518,
+5061,
+3964,
+4637,
+2691,
+-1290,
+-4764,
+-6237,
+-5122,
+-3867,
+-4382,
+-4340,
+-2171,
+954,
+2885,
+3430,
+3650,
+4302,
+5176,
+4711,
+2169,
+3,
+-958,
+-1485,
+-2344,
+-3327,
+-3815,
+-3159,
+-1939,
+-888,
+-331,
+405,
+1484,
+2494,
+2693,
+2133,
+1396,
+838,
+-47,
+-874,
+-1956,
+-2849,
+-2975,
+-3277,
+-3840,
+-3478,
+-2275,
+-834,
+246,
+1425,
+2537,
+15180,
+18376,
+5188,
+410,
+802,
+554,
+-1236,
+-7656,
+-13700,
+-12256,
+-5313,
+-3930,
+-5878,
+-3184,
+1356,
+6062,
+8660,
+6908,
+5229,
+6261,
+6295,
+2669,
+-1615,
+-3864,
+-4683,
+-4685,
+-5191,
+-6164,
+-4786,
+-1257,
+803,
+1647,
+2717,
+4277,
+5751,
+5444,
+3534,
+1693,
+788,
+240,
+-1209,
+-2868,
+-3856,
+-3683,
+-2945,
+-2398,
+-2127,
+-1237,
+221,
+1625,
+2252,
+2363,
+2177,
+2139,
+1646,
+747,
+-682,
+-1592,
+-1973,
+-2640,
+-4154,
+-4457,
+-3691,
+-2213,
+-1609,
+358,
+9,
+8796,
+19973,
+8801,
+323,
+3725,
+4003,
+1287,
+-4158,
+-11215,
+-12123,
+-6560,
+-4893,
+-8680,
+-7000,
+-1262,
+2843,
+5584,
+5846,
+5210,
+7061,
+8286,
+5502,
+1735,
+34,
+-1179,
+-2711,
+-4369,
+-6004,
+-5869,
+-4326,
+-3324,
+-2591,
+-387,
+2387,
+3383,
+4066,
+4520,
+4303,
+4319,
+3839,
+1928,
+-212,
+-929,
+-1713,
+-3166,
+-3950,
+-4068,
+-3727,
+-2636,
+-1732,
+-858,
+429,
+1712,
+2271,
+2567,
+2489,
+2242,
+1508,
+525,
+-534,
+-1480,
+-3190,
+-4176,
+-4399,
+-3711,
+-3319,
+-1318,
+-1529,
+5824,
+18263,
+8980,
+1129,
+6565,
+5402,
+1529,
+-2393,
+-8897,
+-9751,
+-5403,
+-5862,
+-10492,
+-7777,
+-1518,
+366,
+2076,
+3696,
+4427,
+7644,
+8718,
+5220,
+2988,
+3238,
+1518,
+-1549,
+-3359,
+-4583,
+-5273,
+-4773,
+-4814,
+-4600,
+-2655,
+-692,
+471,
+2320,
+4827,
+5642,
+5031,
+4951,
+4328,
+3095,
+1691,
+-433,
+-2141,
+-2810,
+-3720,
+-4751,
+-4605,
+-3658,
+-2743,
+-1551,
+-321,
+614,
+1792,
+2448,
+2382,
+2240,
+1606,
+743,
+87,
+-1379,
+-3091,
+-3718,
+-3446,
+-3437,
+-2448,
+-1598,
+213,
+13754,
+13943,
+1573,
+6057,
+9324,
+2801,
+-23,
+-4927,
+-8617,
+-5726,
+-5704,
+-11215,
+-10704,
+-3695,
+-2220,
+-2605,
+1165,
+3401,
+5816,
+8504,
+6316,
+4585,
+6307,
+4747,
+594,
+-1023,
+-1896,
+-3709,
+-4527,
+-5028,
+-5585,
+-4224,
+-2220,
+-1274,
+293,
+1942,
+2965,
+3680,
+4734,
+4718,
+3363,
+2892,
+2290,
+475,
+-716,
+-1845,
+-2946,
+-3263,
+-3337,
+-3567,
+-3026,
+-1758,
+-982,
+-436,
+702,
+1028,
+1410,
+1741,
+899,
+309,
+291,
+-996,
+-2445,
+-3047,
+-2952,
+-3078,
+-1523,
+-2030,
+2577,
+15559,
+9454,
+1329,
+10378,
+8861,
+812,
+-178,
+-5162,
+-7416,
+-4607,
+-8367,
+-13138,
+-8360,
+-2930,
+-5048,
+-4060,
+1923,
+3453,
+5460,
+7466,
+5185,
+6214,
+8049,
+3818,
+813,
+1270,
+-554,
+-3504,
+-4259,
+-4876,
+-4876,
+-3386,
+-3386,
+-3113,
+-156,
+1431,
+1404,
+2648,
+3661,
+3690,
+3786,
+3546,
+2712,
+1647,
+1033,
+-233,
+-1897,
+-2276,
+-2634,
+-3387,
+-2877,
+-2404,
+-2222,
+-1388,
+-525,
+-72,
+513,
+771,
+515,
+361,
+372,
+-1054,
+-2250,
+-2155,
+-2433,
+-2983,
+-1100,
+-1463,
+1833,
+14674,
+9493,
+994,
+11938,
+10503,
+-113,
+849,
+-2621,
+-6603,
+-4210,
+-8873,
+-13590,
+-7446,
+-3923,
+-8350,
+-5775,
+1855,
+2051,
+2889,
+6569,
+5468,
+6885,
+9044,
+3845,
+1981,
+4585,
+840,
+-3160,
+-2258,
+-3339,
+-4931,
+-3915,
+-4280,
+-4171,
+-1115,
+-336,
+-844,
+1792,
+3382,
+2470,
+3089,
+3456,
+2413,
+2294,
+1580,
+-213,
+-464,
+-689,
+-2154,
+-2373,
+-1735,
+-1924,
+-1759,
+-1042,
+-263,
+-271,
+-470,
+311,
+122,
+-736,
+-585,
+-908,
+-1820,
+-2145,
+-2413,
+-2727,
+-1706,
+-627,
+-619,
+4874,
+12214,
+7923,
+4151,
+10217,
+8801,
+1832,
+-249,
+-2252,
+-3941,
+-5356,
+-8809,
+-10597,
+-8087,
+-4985,
+-7232,
+-7340,
+-455,
+1766,
+511,
+3545,
+5644,
+6035,
+7060,
+5689,
+3666,
+4528,
+4075,
+-346,
+-2183,
+-702,
+-2923,
+-5332,
+-3956,
+-3938,
+-3891,
+-1722,
+-1618,
+-1007,
+2233,
+3124,
+2092,
+3473,
+4677,
+3158,
+2354,
+2344,
+896,
+13,
+-353,
+-1920,
+-2500,
+-1876,
+-2429,
+-2904,
+-1931,
+-1548,
+-1647,
+-1143,
+-884,
+-587,
+-356,
+-508,
+-603,
+-570,
+-880,
+-1604,
+-1523,
+-1037,
+-233,
+392,
+246,
+7721,
+12282,
+3714,
+4320,
+10768,
+5362,
+-326,
+-905,
+-1597,
+-3500,
+-6473,
+-8522,
+-9139,
+-6295,
+-5259,
+-8560,
+-4871,
+1286,
+254,
+-49,
+3842,
+6419,
+5774,
+5068,
+5505,
+4977,
+4533,
+3102,
+-292,
+-514,
+212,
+-2991,
+-5293,
+-3514,
+-2846,
+-4594,
+-4048,
+-1929,
+-1453,
+-380,
+842,
+1019,
+2564,
+4031,
+2872,
+2666,
+4105,
+3307,
+1387,
+1469,
+1130,
+-486,
+-1134,
+-1432,
+-2295,
+-2313,
+-2289,
+-2707,
+-2354,
+-1718,
+-2015,
+-1659,
+-910,
+-1114,
+-1046,
+-671,
+-781,
+-696,
+-1066,
+-920,
+-494,
+630,
+-299,
+2946,
+11838,
+6153,
+756,
+9967,
+9690,
+956,
+-307,
+1845,
+-422,
+-4869,
+-5636,
+-7078,
+-7135,
+-4922,
+-8414,
+-8790,
+-2391,
+-1148,
+-3767,
+-1233,
+4544,
+4553,
+2606,
+5319,
+6810,
+5740,
+4969,
+3580,
+2641,
+2352,
+620,
+-2410,
+-2839,
+-1672,
+-3703,
+-5513,
+-3556,
+-2440,
+-3208,
+-2349,
+-432,
+345,
+1085,
+2191,
+2337,
+2745,
+3717,
+2847,
+1849,
+2422,
+2079,
+335,
+-214,
+-200,
+-1094,
+-1711,
+-1872,
+-2344,
+-2092,
+-1723,
+-2328,
+-2458,
+-1317,
+-1102,
+-1879,
+-1257,
+-123,
+-629,
+-738,
+-453,
+-109,
+594,
+1436,
+277,
+2464,
+11940,
+6632,
+-1004,
+8264,
+10307,
+345,
+-2750,
+2361,
+611,
+-7160,
+-6461,
+-5327,
+-7288,
+-6340,
+-7520,
+-7649,
+-3079,
+-742,
+-3018,
+-1572,
+5171,
+5207,
+1733,
+5350,
+8233,
+5364,
+3687,
+4600,
+3696,
+1606,
+583,
+-1252,
+-2373,
+-1724,
+-3315,
+-5337,
+-3644,
+-2214,
+-3828,
+-3650,
+-742,
+30,
+-493,
+992,
+2447,
+2577,
+2805,
+3105,
+2993,
+3033,
+2781,
+1472,
+929,
+1016,
+-326,
+-1571,
+-1491,
+-1549,
+-2321,
+-2736,
+-2195,
+-1921,
+-2231,
+-2236,
+-1424,
+-1151,
+-1565,
+-1131,
+-567,
+-966,
+-660,
+-647,
+-512,
+129,
+1163,
+-39,
+2185,
+9519,
+3970,
+1406,
+8300,
+7218,
+904,
+922,
+4135,
+-220,
+-3955,
+-2012,
+-3738,
+-5164,
+-4935,
+-5977,
+-5533,
+-3731,
+-3711,
+-4401,
+-1222,
+1074,
+-614,
+576,
+3421,
+3648,
+2696,
+3423,
+4231,
+3550,
+2987,
+2061,
+1263,
+1521,
+290,
+-1497,
+-1411,
+-887,
+-2235,
+-3156,
+-2033,
+-1655,
+-2231,
+-1780,
+-914,
+-406,
+-37,
+398,
+721,
+1364,
+1844,
+1608,
+1558,
+1991,
+1915,
+1263,
+920,
+1012,
+455,
+-182,
+-375,
+-600,
+-1079,
+-1270,
+-1304,
+-1347,
+-1242,
+-1019,
+-991,
+-693,
+-437,
+-596,
+-480,
+54,
+-152,
+-430,
+-113,
+13,
+-468,
+-500,
+-521,
+-375,
+-321,
+46,
+-615,
+1857,
+5276,
+1047,
+1304,
+5364,
+3720,
+427,
+969,
+2866,
+60,
+-1980,
+-856,
+-1994,
+-2713,
+-2620,
+-3138,
+-3432,
+-2515,
+-1677,
+-2598,
+-1889,
+111,
+16,
+-190,
+914,
+1912,
+1649,
+1546,
+2185,
+1917,
+1525,
+1621,
+1180,
+585,
+440,
+444,
+-330,
+-841,
+-637,
+-867,
+-1331,
+-1271,
+-1064,
+-1109,
+-1007,
+-648,
+-539,
+-378,
+38,
+310,
+399,
+644,
+932,
+1043,
+1017,
+1087,
+1034,
+896,
+724,
+493,
+249,
+71,
+-7,
+-260,
+-565,
+-549,
+-526,
+-607,
+-669,
+-547,
+-426,
+-399,
+-283,
+-164,
+-120,
+-9,
+41,
+53,
+-42,
+-73,
+-112,
+-179,
+-342,
+-426,
+-469,
+-497,
+-554,
+-574,
+-701,
+-484,
+-266,
+-66,
+-354,
+757,
+2832,
+1417,
+142,
+2007,
+3958,
+2079,
+28,
+1105,
+1712,
+464,
+-647,
+-819,
+-992,
+-1518,
+-1511,
+-1828,
+-2259,
+-1935,
+-1445,
+-1378,
+-1419,
+-869,
+-216,
+-39,
+212,
+606,
+932,
+966,
+1093,
+1317,
+1159,
+923,
+869,
+781,
+471,
+155,
+48,
+-163,
+-431,
+-536,
+-624,
+-717,
+-739,
+-679,
+-574,
+-466,
+-297,
+-136,
+0,
+162,
+282,
+383,
+443,
+478,
+521,
+500,
+418,
+335,
+257,
+194,
+91,
+7,
+-59,
+-114,
+-170,
+-186,
+-240,
+-312,
+-257,
+-154,
+-145,
+-165,
+-121,
+-32,
+-7,
+24,
+81,
+90,
+89,
+174,
+205,
+111,
+67,
+89,
+81,
+-9,
+-51,
+-70,
+-155,
+-284,
+-278,
+-327,
+-429,
+-396,
+-341,
+-381,
+-430,
+-352,
+-310,
+-272,
+-204,
+-85,
+-150,
+80,
+662,
+335,
+-1,
+222,
+524,
+319,
+344,
+1942,
+1990,
+525,
+363,
+1053,
+1318,
+421,
+50,
+91,
+-476,
+-747,
+-661,
+-791,
+-1278,
+-1465,
+-1063,
+-965,
+-1033,
+-768,
+-502,
+-304,
+-172,
+154,
+401,
+463,
+596,
+731,
+746,
+683,
+622,
+562,
+404,
+269,
+151,
+-16,
+-163,
+-270,
+-338,
+-409,
+-413,
+-369,
+-398,
+-358,
+-250,
+-188,
+-222,
+-97,
+60,
+158,
+174,
+248,
+307,
+329,
+325,
+354,
+295,
+217,
+162,
+154,
+78,
+0,
+-66,
+-86,
+-97,
+-93,
+-119,
+-104,
+-35,
+-4,
+-11,
+-6,
+-69,
+-43,
+38,
+41,
+-7,
+-37,
+0,
+-13,
+-85,
+-68,
+-68,
+-80,
+-107,
+-81,
+-82,
+-74,
+-86,
+-66,
+-92,
+-61,
+-61,
+-33,
+-59,
+-71,
+-122,
+-126,
+-181,
+-217,
+-254,
+-236,
+-270,
+-342,
+-315,
+-291,
+-285,
+-153,
+-35,
+78,
+89,
+1837,
+2562,
+831,
+424,
+1316,
+1760,
+754,
+-120,
+26,
+-317,
+-593,
+-716,
+-1095,
+-1379,
+-1373,
+-1018,
+-1002,
+-1129,
+-762,
+-415,
+-179,
+-2,
+243,
+478,
+604,
+784,
+838,
+751,
+682,
+608,
+504,
+280,
+35,
+-118,
+-205,
+-323,
+-476,
+-579,
+-561,
+-566,
+-544,
+-427,
+-292,
+-179,
+-49,
+98,
+231,
+332,
+430,
+482,
+485,
+478,
+442,
+392,
+283,
+178,
+82,
+18,
+-77,
+-143,
+-208,
+-211,
+-224,
+-225,
+-227,
+-167,
+-112,
+-45,
+-15,
+50,
+114,
+161,
+178,
+204,
+219,
+205,
+162,
+106,
+66,
+-23,
+-155,
+-194,
+-192,
+-254,
+-307,
+-314,
+-257,
+-247,
+-184,
+-157,
+-118,
+-48,
+35,
+34,
+9,
+0,
+53,
+-15,
+-101,
+-126,
+-139,
+-229,
+-321,
+-431,
+-343,
+-225,
+-136,
+-203,
+155,
+2249,
+2043,
+292,
+680,
+1780,
+1723,
+370,
+-146,
+104,
+-212,
+-411,
+-968,
+-1471,
+-1388,
+-1103,
+-1045,
+-1383,
+-1195,
+-536,
+-254,
+-126,
+-31,
+344,
+710,
+860,
+881,
+800,
+822,
+866,
+599,
+316,
+112,
+0,
+-205,
+-447,
+-592,
+-660,
+-669,
+-626,
+-625,
+-510,
+-331,
+-112,
+20,
+154,
+307,
+459,
+557,
+569,
+515,
+492,
+464,
+383,
+189,
+70,
+5,
+-88,
+-218,
+-281,
+-289,
+-290,
+-312,
+-254,
+-188,
+-103,
+-18,
+89,
+160,
+201,
+248,
+324,
+334,
+307,
+255,
+201,
+125,
+47,
+-41,
+-146,
+-175,
+-214,
+-290,
+-298,
+-398,
+-399,
+-262,
+-234,
+-263,
+-198,
+-20,
+69,
+41,
+17,
+59,
+80,
+37,
+-109,
+-163,
+-139,
+-217,
+-396,
+-489,
+-464,
+-241,
+-223,
+-132,
+-266,
+1765,
+2822,
+428,
+325,
+1911,
+2224,
+731,
+-466,
+58,
+90,
+-363,
+-1061,
+-1848,
+-1478,
+-1048,
+-1188,
+-1626,
+-1425,
+-500,
+-126,
+-120,
+29,
+427,
+983,
+1016,
+846,
+890,
+1003,
+968,
+621,
+321,
+168,
+11,
+-203,
+-507,
+-673,
+-695,
+-714,
+-741,
+-820,
+-670,
+-416,
+-267,
+-153,
+14,
+262,
+468,
+551,
+629,
+658,
+705,
+676,
+571,
+452,
+333,
+200,
+49,
+-106,
+-193,
+-336,
+-439,
+-444,
+-440,
+-429,
+-382,
+-296,
+-193,
+-87,
+17,
+78,
+148,
+237,
+288,
+278,
+282,
+280,
+243,
+162,
+95,
+67,
+6,
+-62,
+-121,
+-174,
+-228,
+-261,
+-278,
+-309,
+-330,
+-301,
+-278,
+-304,
+-342,
+-329,
+-283,
+-302,
+-329,
+-278,
+-238,
+-245,
+-244,
+-269,
+-78,
+41,
+242,
+97,
+1291,
+2890,
+1483,
+993,
+1982,
+2135,
+1016,
+98,
+475,
+68,
+-777,
+-1112,
+-1511,
+-1531,
+-1717,
+-1782,
+-1761,
+-1558,
+-1042,
+-930,
+-723,
+-176,
+262,
+536,
+698,
+1069,
+1263,
+1231,
+1250,
+1085,
+901,
+696,
+423,
+113,
+-206,
+-382,
+-622,
+-836,
+-909,
+-938,
+-898,
+-852,
+-708,
+-503,
+-323,
+-82,
+121,
+340,
+520,
+672,
+780,
+820,
+838,
+808,
+714,
+614,
+452,
+309,
+124,
+-30,
+-158,
+-280,
+-378,
+-437,
+-465,
+-459,
+-439,
+-386,
+-330,
+-247,
+-164,
+-94,
+-30,
+20,
+75,
+97,
+72,
+38,
+66,
+56,
+10,
+7,
+24,
+-3,
+-44,
+-31,
+2,
+-17,
+-43,
+-11,
+-33,
+-65,
+-125,
+-208,
+-261,
+-399,
+-523,
+-590,
+-648,
+-749,
+-865,
+-727,
+-583,
+-399,
+-359,
+937,
+2246,
+1545,
+1816,
+2823,
+2789,
+1815,
+1425,
+1819,
+907,
+22,
+-344,
+-736,
+-1228,
+-1916,
+-2187,
+-2283,
+-2317,
+-2281,
+-2329,
+-1779,
+-1327,
+-1049,
+-609,
+-9,
+603,
+799,
+1139,
+1566,
+1672,
+1679,
+1543,
+1538,
+1309,
+954,
+658,
+360,
+66,
+-293,
+-625,
+-752,
+-945,
+-1055,
+-1136,
+-1060,
+-938,
+-895,
+-698,
+-484,
+-262,
+-79,
+125,
+365,
+533,
+654,
+779,
+859,
+933,
+880,
+852,
+803,
+690,
+555,
+394,
+291,
+92,
+-95,
+-230,
+-373,
+-524,
+-625,
+-691,
+-729,
+-764,
+-719,
+-680,
+-583,
+-469,
+-351,
+-222,
+-73,
+79,
+170,
+274,
+392,
+423,
+419,
+417,
+393,
+254,
+117,
+-36,
+-207,
+-402,
+-607,
+-734,
+-940,
+-1034,
+-1216,
+-1324,
+-1241,
+-1034,
+-923,
+-557,
+1060,
+1737,
+1615,
+2842,
+3811,
+3578,
+2905,
+3300,
+3178,
+1690,
+955,
+455,
+-292,
+-1483,
+-2319,
+-2502,
+-3018,
+-3353,
+-3562,
+-3301,
+-2792,
+-2659,
+-2195,
+-1426,
+-640,
+-142,
+273,
+1167,
+1653,
+1841,
+2078,
+2310,
+2408,
+2044,
+1855,
+1622,
+1205,
+717,
+206,
+-131,
+-533,
+-952,
+-1217,
+-1401,
+-1429,
+-1527,
+-1467,
+-1251,
+-1021,
+-781,
+-507,
+-138,
+199,
+419,
+710,
+910,
+1082,
+1144,
+1180,
+1166,
+1090,
+978,
+809,
+614,
+444,
+219,
+4,
+-204,
+-352,
+-515,
+-653,
+-746,
+-776,
+-825,
+-810,
+-804,
+-699,
+-617,
+-494,
+-373,
+-190,
+-34,
+102,
+214,
+357,
+438,
+477,
+469,
+458,
+394,
+225,
+28,
+-148,
+-353,
+-602,
+-785,
+-934,
+-1033,
+-1142,
+-1203,
+-1058,
+-874,
+-612,
+-427,
+838,
+1786,
+1645,
+2459,
+3425,
+3408,
+2808,
+2738,
+2832,
+1691,
+673,
+137,
+-499,
+-1435,
+-2395,
+-2637,
+-2831,
+-3168,
+-3261,
+-2988,
+-2361,
+-2064,
+-1671,
+-864,
+-100,
+419,
+790,
+1411,
+1924,
+1941,
+1943,
+2017,
+1964,
+1554,
+1104,
+872,
+496,
+-29,
+-470,
+-717,
+-911,
+-1231,
+-1365,
+-1308,
+-1196,
+-1146,
+-992,
+-667,
+-350,
+-150,
+119,
+446,
+714,
+840,
+956,
+1107,
+1132,
+1064,
+940,
+850,
+690,
+445,
+212,
+24,
+-154,
+-367,
+-514,
+-588,
+-630,
+-683,
+-664,
+-595,
+-502,
+-438,
+-322,
+-194,
+-88,
+-28,
+67,
+160,
+192,
+218,
+246,
+253,
+204,
+150,
+101,
+1,
+-96,
+-193,
+-284,
+-376,
+-455,
+-555,
+-575,
+-631,
+-659,
+-679,
+-651,
+-615,
+-644,
+-561,
+-425,
+-228,
+-130,
+276,
+1386,
+1613,
+1695,
+2525,
+2972,
+2674,
+2279,
+2336,
+2011,
+997,
+342,
+-163,
+-758,
+-1590,
+-2268,
+-2448,
+-2639,
+-2927,
+-2968,
+-2601,
+-2099,
+-1895,
+-1414,
+-663,
+-21,
+374,
+827,
+1410,
+1787,
+1850,
+1929,
+2002,
+1916,
+1555,
+1215,
+942,
+563,
+49,
+-358,
+-646,
+-900,
+-1218,
+-1356,
+-1331,
+-1269,
+-1215,
+-1025,
+-714,
+-425,
+-201,
+114,
+419,
+671,
+789,
+948,
+1040,
+1053,
+955,
+865,
+756,
+580,
+352,
+185,
+22,
+-143,
+-317,
+-395,
+-475,
+-535,
+-564,
+-500,
+-483,
+-398,
+-319,
+-195,
+-106,
+-11,
+86,
+152,
+199,
+219,
+243,
+221,
+140,
+94,
+32,
+-51,
+-104,
+-140,
+-202,
+-240,
+-263,
+-294,
+-345,
+-390,
+-409,
+-483,
+-545,
+-577,
+-602,
+-626,
+-699,
+-643,
+-557,
+-392,
+-292,
+114,
+1059,
+1328,
+1501,
+2285,
+2720,
+2562,
+2319,
+2336,
+2078,
+1242,
+591,
+88,
+-507,
+-1320,
+-2026,
+-2257,
+-2474,
+-2759,
+-2782,
+-2435,
+-1979,
+-1679,
+-1182,
+-459,
+126,
+549,
+972,
+1433,
+1694,
+1699,
+1649,
+1588,
+1338,
+953,
+553,
+236,
+-157,
+-557,
+-827,
+-994,
+-1099,
+-1142,
+-1070,
+-878,
+-648,
+-389,
+-78,
+231,
+532,
+746,
+930,
+1044,
+1084,
+1028,
+909,
+732,
+516,
+277,
+1,
+-263,
+-479,
+-645,
+-807,
+-871,
+-828,
+-761,
+-639,
+-472,
+-236,
+-29,
+175,
+347,
+507,
+612,
+652,
+641,
+584,
+501,
+346,
+180,
+22,
+-131,
+-285,
+-416,
+-501,
+-560,
+-574,
+-595,
+-565,
+-495,
+-437,
+-411,
+-363,
+-258,
+-217,
+-226,
+-211,
+-226,
+-253,
+-363,
+-472,
+-483,
+-424,
+-340,
+-341,
+552,
+1617,
+1454,
+1874,
+2855,
+3002,
+2514,
+2085,
+2061,
+1390,
+268,
+-528,
+-1234,
+-1750,
+-2502,
+-3167,
+-3146,
+-2930,
+-2789,
+-2584,
+-1872,
+-901,
+-282,
+308,
+1085,
+1794,
+2213,
+2289,
+2307,
+2303,
+1969,
+1401,
+756,
+267,
+-269,
+-938,
+-1423,
+-1683,
+-1786,
+-1828,
+-1744,
+-1412,
+-955,
+-474,
+-38,
+439,
+953,
+1308,
+1472,
+1559,
+1581,
+1441,
+1132,
+752,
+391,
+-3,
+-410,
+-793,
+-1044,
+-1157,
+-1200,
+-1179,
+-984,
+-695,
+-328,
+-29,
+350,
+698,
+959,
+1087,
+1108,
+1083,
+927,
+662,
+339,
+41,
+-276,
+-572,
+-826,
+-957,
+-1012,
+-1024,
+-912,
+-762,
+-514,
+-289,
+-55,
+187,
+332,
+428,
+429,
+397,
+275,
+14,
+-231,
+-469,
+-727,
+-1018,
+-1174,
+-1020,
+-786,
+-613,
+-228,
+1364,
+2799,
+2457,
+2788,
+3873,
+3684,
+2460,
+1383,
+960,
+-70,
+-1527,
+-2538,
+-3408,
+-3453,
+-3426,
+-3769,
+-3360,
+-2146,
+-960,
+-415,
+314,
+1728,
+2548,
+2696,
+2764,
+2677,
+2528,
+1897,
+899,
+-2,
+-669,
+-1177,
+-1992,
+-2608,
+-2448,
+-2195,
+-1980,
+-1628,
+-901,
+1,
+661,
+1183,
+1643,
+2036,
+2295,
+2105,
+1691,
+1346,
+916,
+309,
+-359,
+-841,
+-1115,
+-1364,
+-1512,
+-1455,
+-1159,
+-790,
+-458,
+-64,
+400,
+781,
+977,
+1072,
+1176,
+1113,
+902,
+624,
+333,
+67,
+-243,
+-501,
+-741,
+-848,
+-834,
+-819,
+-831,
+-736,
+-485,
+-307,
+-216,
+-73,
+114,
+244,
+355,
+353,
+266,
+237,
+286,
+158,
+-288,
+-453,
+-492,
+-814,
+-1143,
+-1383,
+-1324,
+-1111,
+-815,
+-615,
+442,
+3114,
+3953,
+3029,
+3919,
+4941,
+3971,
+1878,
+374,
+-455,
+-1974,
+-3286,
+-4552,
+-5650,
+-4570,
+-3342,
+-3483,
+-2641,
+-269,
+1946,
+2478,
+2830,
+4030,
+4214,
+3803,
+2888,
+1228,
+136,
+-491,
+-1700,
+-3203,
+-3856,
+-3201,
+-2821,
+-2817,
+-1903,
+-637,
+581,
+1606,
+2167,
+2553,
+2896,
+3040,
+2593,
+1551,
+807,
+272,
+-605,
+-1460,
+-2042,
+-2202,
+-2015,
+-1775,
+-1386,
+-876,
+-132,
+665,
+1150,
+1393,
+1651,
+1797,
+1694,
+1299,
+803,
+318,
+-107,
+-513,
+-923,
+-1298,
+-1358,
+-1289,
+-1153,
+-1084,
+-838,
+-447,
+-41,
+243,
+441,
+656,
+958,
+981,
+839,
+682,
+511,
+236,
+-52,
+-445,
+-778,
+-1174,
+-1308,
+-1352,
+-1558,
+-1649,
+-1547,
+-1278,
+-879,
+-382,
+161,
+644,
+3348,
+6104,
+4816,
+3648,
+4808,
+4552,
+2078,
+-784,
+-2182,
+-3265,
+-4352,
+-4702,
+-5791,
+-6030,
+-3554,
+-1612,
+-1271,
+-443,
+1928,
+3939,
+4107,
+4000,
+4064,
+3257,
+2711,
+1724,
+-334,
+-2045,
+-2530,
+-2818,
+-3814,
+-4286,
+-3290,
+-2251,
+-1389,
+-186,
+846,
+1714,
+2703,
+3331,
+3093,
+2464,
+2180,
+1666,
+523,
+-508,
+-1187,
+-1812,
+-2159,
+-2176,
+-2015,
+-1810,
+-1193,
+-271,
+366,
+829,
+1396,
+1903,
+2099,
+1994,
+1626,
+1124,
+566,
+139,
+-409,
+-1054,
+-1436,
+-1468,
+-1292,
+-1136,
+-1026,
+-684,
+-200,
+225,
+501,
+562,
+625,
+732,
+705,
+523,
+230,
+-65,
+-282,
+-465,
+-752,
+-1154,
+-1418,
+-1247,
+-1238,
+-1499,
+-1622,
+-1520,
+-1164,
+-695,
+-34,
+403,
+1638,
+5931,
+7958,
+5384,
+4240,
+4911,
+3894,
+836,
+-2312,
+-4068,
+-5473,
+-5637,
+-5363,
+-6650,
+-6603,
+-3512,
+-852,
+-104,
+663,
+2831,
+4675,
+5137,
+5106,
+4149,
+2660,
+2205,
+1551,
+-531,
+-2750,
+-3254,
+-2848,
+-3218,
+-3660,
+-3123,
+-2255,
+-1075,
+296,
+1020,
+1242,
+1997,
+3202,
+3380,
+2502,
+1924,
+1596,
+954,
+119,
+-773,
+-1635,
+-2079,
+-1966,
+-1815,
+-1949,
+-1750,
+-932,
+-103,
+443,
+899,
+1332,
+1814,
+2147,
+2079,
+1638,
+1083,
+677,
+232,
+-448,
+-1163,
+-1623,
+-1755,
+-1731,
+-1606,
+-1448,
+-1105,
+-692,
+-98,
+367,
+706,
+901,
+1041,
+1012,
+803,
+544,
+56,
+-557,
+-990,
+-1031,
+-1320,
+-1806,
+-2086,
+-1988,
+-1453,
+-840,
+-107,
+286,
+2824,
+8161,
+9177,
+5513,
+3632,
+3567,
+2327,
+-794,
+-3932,
+-6200,
+-7500,
+-6227,
+-4761,
+-5838,
+-5877,
+-2578,
+1103,
+2615,
+3068,
+4186,
+5094,
+5568,
+5778,
+4142,
+1250,
+-132,
+-349,
+-1662,
+-3998,
+-5143,
+-4834,
+-4300,
+-3396,
+-2216,
+-1395,
+-256,
+1793,
+3508,
+3851,
+3570,
+3620,
+3451,
+2651,
+1641,
+418,
+-868,
+-1653,
+-1907,
+-2339,
+-2754,
+-2446,
+-1671,
+-1065,
+-478,
+139,
+677,
+1196,
+1665,
+1890,
+1696,
+1486,
+1340,
+988,
+343,
+-254,
+-685,
+-994,
+-1246,
+-1391,
+-1430,
+-1328,
+-1092,
+-793,
+-525,
+-158,
+205,
+559,
+744,
+829,
+829,
+758,
+439,
+9,
+-296,
+-447,
+-813,
+-1334,
+-1615,
+-1731,
+-1694,
+-1559,
+-1055,
+-694,
+360,
+3442,
+5109,
+3607,
+2189,
+2785,
+4015,
+3152,
+868,
+-642,
+-1512,
+-1742,
+-1879,
+-2998,
+-4294,
+-4178,
+-2538,
+-1395,
+-1552,
+-1371,
+-211,
+1144,
+1968,
+2197,
+2053,
+1917,
+2172,
+2349,
+1636,
+410,
+-250,
+-406,
+-763,
+-1506,
+-2096,
+-2271,
+-2112,
+-1695,
+-1288,
+-1062,
+-671,
+160,
+1038,
+1398,
+1487,
+1588,
+1643,
+1513,
+1173,
+665,
+72,
+-358,
+-595,
+-820,
+-1083,
+-1209,
+-1030,
+-748,
+-424,
+-140,
+137,
+405,
+691,
+869,
+882,
+764,
+636,
+514,
+322,
+62,
+-196,
+-408,
+-528,
+-545,
+-548,
+-555,
+-450,
+-265,
+-90,
+79,
+217,
+343,
+400,
+391,
+378,
+302,
+180,
+41,
+-105,
+-226,
+-375,
+-435,
+-459,
+-428,
+-381,
+-321,
+-222,
+-149,
+-79,
+24,
+158,
+248,
+183,
+112,
+63,
+27,
+-49,
+-119,
+-233,
+-176,
+64,
+185,
+-62,
+-229,
+-261,
+-200,
+-123,
+-85,
+126,
+1087,
+1992,
+1942,
+1470,
+1327,
+1169,
+695,
+-37,
+-706,
+-1358,
+-1547,
+-1428,
+-1460,
+-1608,
+-1364,
+-798,
+-192,
+143,
+449,
+713,
+959,
+1160,
+1184,
+857,
+537,
+313,
+121,
+-207,
+-539,
+-789,
+-843,
+-801,
+-670,
+-573,
+-439,
+-208,
+123,
+325,
+448,
+530,
+617,
+602,
+526,
+364,
+173,
+-17,
+-133,
+-269,
+-377,
+-447,
+-423,
+-353,
+-257,
+-159,
+-41,
+67,
+202,
+275,
+321,
+314,
+294,
+244,
+180,
+84,
+-28,
+-95,
+-131,
+-186,
+-185,
+-179,
+-147,
+-95,
+-25,
+31,
+51,
+111,
+150,
+135,
+146,
+122,
+78,
+61,
+43,
+-4,
+-43,
+-51,
+-74,
+-81,
+-66,
+-69,
+-64,
+-40,
+-19,
+-7,
+4,
+16,
+29,
+27,
+30,
+28,
+8,
+6,
+6,
+-7,
+0,
+12,
+6,
+-13,
+-22,
+-26,
+-42,
+-54,
+-51,
+-62,
+-59,
+-32,
+-21,
+-21,
+-11,
+4,
+12,
+7,
+3,
+-21,
+-56,
+-46,
+-42,
+-68,
+-89,
+-95,
+-84,
+-68,
+-46,
+-32,
+-22,
+67,
+214,
+276,
+221,
+144,
+119,
+94,
+30,
+-43,
+-81,
+-46,
+51,
+136,
+177,
+210,
+244,
+262,
+213,
+106,
+-21,
+-133,
+-221,
+-299,
+-373,
+-413,
+-380,
+-299,
+-201,
+-98,
+23,
+134,
+230,
+301,
+309,
+268,
+224,
+184,
+103,
+-21,
+-121,
+-166,
+-189,
+-204,
+-211,
+-207,
+-174,
+-96,
+-10,
+44,
+72,
+99,
+126,
+137,
+126,
+96,
+48,
+17,
+-6,
+-40,
+-68,
+-83,
+-75,
+-69,
+-73,
+-58,
+-29,
+-1,
+14,
+24,
+41,
+47,
+41,
+39,
+38,
+37,
+23,
+0,
+-10,
+-6,
+-1,
+-1,
+-4,
+-3,
+-1,
+5,
+7,
+7,
+15,
+11,
+-1,
+-3,
+6,
+-6,
+-8,
+0,
+-6,
+-5,
+6,
+17,
+-1,
+-7,
+5,
+4,
+-3,
+-6,
+-10,
+-26,
+-43,
+-37,
+-28,
+-21,
+-18,
+-28,
+-29,
+-15,
+-3,
+-2,
+-17,
+-22,
+-13,
+-31,
+-36,
+-27,
+-33,
+-57,
+-43,
+-15,
+5,
+20,
+60,
+107,
+165,
+197,
+199,
+172,
+144,
+102,
+51,
+-28,
+-94,
+-131,
+-139,
+-157,
+-158,
+-149,
+-117,
+-87,
+-39,
+-7,
+22,
+43,
+67,
+67,
+56,
+40,
+44,
+25,
+13,
+-12,
+-28,
+-31,
+-23,
+-25,
+-18,
+-12,
+-8,
+-6,
+14,
+12,
+6,
+19,
+35,
+25,
+16,
+5,
+0,
+9,
+7,
+2,
+16,
+18,
+3,
+-4,
+8,
+18,
+3,
+9,
+5,
+10,
+-3,
+-10,
+-12,
+-10,
+-13,
+-19,
+-29,
+-10,
+-17,
+-18,
+-24,
+-27,
+-27,
+-10,
+-24,
+-29,
+-43,
+-35,
+-39,
+-31,
+-33,
+-21,
+-30,
+-8,
+21,
+53,
+65,
+103,
+117,
+128,
+120,
+119,
+68,
+36,
+2,
+-23,
+-55,
+-71,
+-94,
+-88,
+-81,
+-67,
+-63,
+-48,
+-34,
+-8,
+6,
+11,
+10,
+30,
+25,
+15,
+27,
+26,
+15,
+-1,
+0,
+3,
+-6,
+-5,
+9,
+3,
+7,
+4,
+8,
+-2,
+9,
+12,
+27,
+13,
+6,
+-2,
+6,
+-17,
+5,
+-4,
+0,
+-9,
+4,
+-16,
+-16,
+-26,
+-10,
+-36,
+-18,
+-30,
+-26,
+-33,
+-19,
+-50,
+-38,
+-43,
+-25,
+-16,
+24,
+27,
+71,
+92,
+108,
+94,
+97,
+64,
+52,
+16,
+-6,
+-33,
+-36,
+-57,
+-57,
+-68,
+-43,
+-43,
+-37,
+-46,
+-20,
+-10,
+3,
+-7,
+10,
+10,
+11,
+13,
+12,
+-1,
+19,
+3,
+4,
+12,
+20,
+12,
+10,
+15,
+14,
+-2,
+15,
+19,
+5,
+2,
+2,
+1,
+-5,
+-16,
+-1,
+-8,
+-16,
+-8,
+-13,
+-29,
+-24,
+-27,
+-28,
+-28,
+-37,
+-30,
+-24,
+-8,
+26,
+58,
+75,
+81,
+73,
+59,
+51,
+30,
+6,
+3,
+-5,
+-24,
+-22,
+-15,
+-23,
+-34,
+-38,
+-30,
+-21,
+-10,
+-8,
+-4,
+0,
+4,
+-12,
+-15,
+-6,
+-9,
+13,
+22,
+18,
+28,
+30,
+15,
+10,
+5,
+6,
+-13,
+-36,
+-34,
+-42,
+-47,
+-25,
+-14,
+-21,
+-17,
+22,
+26,
+-5,
+4,
+2,
+-24,
+-32,
+-4,
+5,
+11,
+25,
+7,
+6,
+15,
+23,
+26,
+6,
+11,
+43,
+21,
+8,
+39,
+4,
+21,
+40,
+22,
+60,
+75,
+83,
+122,
+95,
+73,
+26,
+-23,
+-27,
+-92,
+-119,
+-104,
+-92,
+-41,
+-4,
+-4,
+-6,
+6,
+15,
+38,
+34,
+23,
+31,
+14,
+9,
+-15,
+-37,
+-33,
+-83,
+-120,
+-100,
+-81,
+-97,
+-64,
+-11,
+8,
+10,
+41,
+15,
+46,
+174,
+106,
+55,
+99,
+1,
+-18,
+-30,
+-61,
+-61,
+-67,
+-39,
+-33,
+-12,
+13,
+-1,
+5,
+19,
+3,
+9,
+-1,
+-5,
+-25,
+-26,
+-15,
+-37,
+-14,
+-3,
+-10,
+5,
+15,
+22,
+26,
+39,
+40,
+33,
+37,
+30,
+18,
+22,
+7,
+7,
+0,
+-5,
+-6,
+-15,
+-11,
+-19,
+-17,
+-21,
+-23,
+-27,
+-27,
+-30,
+-35,
+-27,
+-49,
+-45,
+-64,
+-56,
+-74,
+-28,
+-13,
+15,
+429,
+417,
+80,
+188,
+29,
+-101,
+-111,
+-167,
+-162,
+-171,
+-56,
+-91,
+-72,
+42,
+-18,
+15,
+45,
+11,
+31,
+1,
+23,
+-7,
+-5,
+21,
+-21,
+28,
+12,
+5,
+28,
+7,
+26,
+7,
+15,
+25,
+5,
+25,
+10,
+10,
+22,
+-9,
+10,
+-17,
+-5,
+-16,
+-17,
+-9,
+-8,
+-21,
+-11,
+-39,
+-23,
+-46,
+-30,
+-46,
+-26,
+-51,
+-67,
+-76,
+-90,
+-80,
+-63,
+39,
+-30,
+635,
+818,
+46,
+147,
+-11,
+-278,
+-216,
+-248,
+-194,
+-242,
+-6,
+-63,
+-100,
+131,
+-11,
+44,
+91,
+17,
+-18,
+-58,
+-5,
+-49,
+21,
+-33,
+34,
+160,
+61,
+42,
+32,
+-2,
+-113,
+-120,
+-192,
+-75,
+174,
+-143,
+-100,
+-10,
+1,
+79,
+135,
+266,
+-1,
+116,
+120,
+-89,
+154,
+-22,
+10,
+-58,
+-38,
+-202,
+-307,
+432,
+240,
+-80,
+320,
+-182,
+-285,
+-252,
+-618,
+-269,
+-89,
+401,
+459,
+347,
+472,
+26,
+-18,
+-47,
+-376,
+-223,
+-199,
+-46,
+-93,
+22,
+219,
+196,
+46,
+-326,
+-160,
+115,
+-210,
+144,
+129,
+-141,
+-8,
+140,
+433,
+-12,
+-87,
+20,
+-10,
+30,
+-307,
+-261,
+-690,
+-238,
+822,
+469,
+415,
+320,
+-6,
+185,
+-219,
+-145,
+-246,
+-420,
+-115,
+-157,
+-84,
+-87,
+221,
+0,
+-23,
+530,
+4,
+-15,
+89,
+9,
+-58,
+-197,
+-96,
+-421,
+-165,
+-13,
+-452,
+55,
+171,
+130,
+110,
+311,
+464,
+-39,
+43,
+10,
+-65,
+28,
+-164,
+62,
+-60,
+-209,
+-362,
+-272,
+244,
+-103,
+209,
+819,
+167,
+68,
+-34,
+-230,
+-100,
+-10,
+105,
+170,
+423,
+632,
+119,
+-199,
+42,
+-178,
+-85,
+-74,
+-344,
+-439,
+-339,
+-216,
+311,
+678,
+582,
+435,
+-158,
+-175,
+73,
+-80,
+-464,
+-815,
+-203,
+-323,
+-664,
+-21,
+26,
+433,
+441,
+246,
+333,
+142,
+171,
+-387,
+-263,
+148,
+23,
+149,
+-126,
+30,
+51,
+117,
+188,
+-539,
+29,
+205,
+-123,
+155,
+131,
+104,
+19,
+145,
+-289,
+-431,
+0,
+-420,
+-218,
+56,
+91,
+195,
+-103,
+87,
+-3,
+343,
+207,
+-281,
+35,
+-148,
+138,
+93,
+-334,
+63,
+36,
+78,
+-302,
+-526,
+-427,
+-660,
+-238,
+-298,
+21,
+790,
+448,
+472,
+757,
+856,
+389,
+-389,
+69,
+103,
+-63,
+-13,
+-557,
+-170,
+125,
+-4,
+-352,
+-410,
+315,
+-48,
+-97,
+-124,
+-527,
+246,
+647,
+71,
+-235,
+-228,
+-451,
+-306,
+363,
+382,
+-74,
+108,
+28,
+-341,
+37,
+162,
+-66,
+183,
+454,
+227,
+187,
+517,
+471,
+-139,
+-228,
+63,
+-170,
+-150,
+244,
+-64,
+-456,
+-54,
+461,
+195,
+-309,
+-326,
+-89,
+49,
+50,
+-323,
+-210,
+435,
+988,
+820,
+218,
+-165,
+-192,
+-175,
+-579,
+-567,
+-365,
+-146,
+141,
+-662,
+-1223,
+-704,
+227,
+269,
+-448,
+337,
+931,
+673,
+437,
+-205,
+-176,
+-156,
+-299,
+-386,
+-496,
+142,
+116,
+-154,
+-355,
+-491,
+17,
+-203,
+-499,
+-298,
+546,
+1489,
+516,
+-241,
+67,
+90,
+-223,
+-616,
+-622,
+-157,
+616,
+1075,
+610,
+288,
+676,
+659,
+150,
+-342,
+-244,
+-86,
+-320,
+-220,
+-278,
+-543,
+-80,
+488,
+247,
+-54,
+-153,
+-207,
+-283,
+-198,
+-170,
+-266,
+60,
+153,
+-215,
+-72,
+120,
+76,
+56,
+-87,
+22,
+64,
+141,
+73,
+-37,
+277,
+136,
+-169,
+-203,
+-127,
+-17,
+-145,
+-140,
+-241,
+-175,
+15,
+-195,
+-212,
+-100,
+-52,
+-12,
+-178,
+-183,
+-149,
+-57,
+-117,
+-392,
+-91,
+48,
+-216,
+-271,
+-469,
+-397,
+-181,
+516,
+777,
+1001,
+3479,
+4115,
+1347,
+-222,
+-177,
+-240,
+-1385,
+-1635,
+-1006,
+-1541,
+-520,
+485,
+-557,
+-748,
+-38,
+644,
+246,
+-252,
+468,
+74,
+-220,
+342,
+-5,
+-595,
+-393,
+152,
+8,
+-347,
+106,
+-23,
+-344,
+218,
+493,
+39,
+-291,
+56,
+296,
+-170,
+-123,
+-127,
+-256,
+22,
+115,
+-152,
+-373,
+40,
+424,
+4,
+-81,
+71,
+149,
+196,
+108,
+-52,
+-140,
+178,
+398,
+119,
+-134,
+-9,
+219,
+92,
+44,
+-49,
+5,
+156,
+240,
+44,
+-224,
+-7,
+198,
+46,
+-57,
+-75,
+82,
+53,
+94,
+-147,
+-214,
+10,
+142,
+-60,
+-192,
+-55,
+4,
+13,
+-20,
+-153,
+-107,
+-17,
+-1,
+-264,
+-153,
+125,
+109,
+-43,
+-215,
+-368,
+-192,
+-77,
+-270,
+-476,
+-241,
+3,
+-343,
+-672,
+-840,
+-735,
+-154,
+520,
+-118,
+638,
+5110,
+5318,
+313,
+-1333,
+-315,
+-312,
+-1728,
+-2948,
+-3283,
+-1999,
+2484,
+2536,
+-2013,
+-1675,
+2109,
+2863,
+441,
+-940,
+-163,
+507,
+1163,
+406,
+-2538,
+-2285,
+789,
+1005,
+-1405,
+-2044,
+21,
+1110,
+607,
+143,
+-524,
+-70,
+1636,
+1329,
+-636,
+-1084,
+522,
+978,
+-127,
+-706,
+-462,
+-31,
+667,
+392,
+-639,
+-636,
+527,
+949,
+183,
+-322,
+-7,
+503,
+716,
+348,
+-298,
+-269,
+355,
+505,
+-116,
+-541,
+-312,
+179,
+305,
+-33,
+-464,
+-280,
+277,
+425,
+-204,
+-549,
+-279,
+129,
+80,
+-348,
+-630,
+-332,
+214,
+54,
+-792,
+-987,
+-88,
+-51,
+-616,
+-1227,
+-1268,
+-659,
+-335,
+-81,
+-718,
+4376,
+11477,
+5778,
+-1970,
+-272,
+1642,
+-973,
+-5351,
+-7281,
+-6891,
+-2672,
+3193,
+-7,
+-4939,
+911,
+7202,
+4919,
+629,
+214,
+1744,
+2296,
+1588,
+-2183,
+-6087,
+-2879,
+1197,
+-1255,
+-4385,
+-1998,
+1583,
+2244,
+1509,
+876,
+599,
+2229,
+3512,
+715,
+-1625,
+-209,
+943,
+-848,
+-2156,
+-1329,
+-394,
+36,
+502,
+56,
+-46,
+1476,
+2086,
+549,
+-412,
+521,
+1004,
+-234,
+-1188,
+-1288,
+-1050,
+-434,
+-346,
+-644,
+-305,
+722,
+1109,
+337,
+-280,
+-52,
+5,
+78,
+-1079,
+-2736,
+-2774,
+-1980,
+-1476,
+-1451,
+-969,
+245,
+1501,
+10820,
+16134,
+3358,
+-4437,
+1229,
+2611,
+-3693,
+-10270,
+-10079,
+-5371,
+-873,
+1188,
+-4267,
+-5509,
+6273,
+12488,
+6174,
+732,
+1904,
+4303,
+3430,
+-849,
+-7991,
+-10784,
+-3524,
+1056,
+-4652,
+-7465
+};
diff --git a/codec2/branches/0.7/unittest/lsp1.txt b/codec2/branches/0.7/unittest/lsp1.txt
new file mode 100644 (file)
index 0000000..88995de
--- /dev/null
@@ -0,0 +1,16 @@
+225
+250
+275
+300
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
diff --git a/codec2/branches/0.7/unittest/lsp10.txt b/codec2/branches/0.7/unittest/lsp10.txt
new file mode 100644 (file)
index 0000000..1f1129b
--- /dev/null
@@ -0,0 +1,5 @@
+2900
+3100
+3300
+3500
+
diff --git a/codec2/branches/0.7/unittest/lsp2.txt b/codec2/branches/0.7/unittest/lsp2.txt
new file mode 100644 (file)
index 0000000..a5d9860
--- /dev/null
@@ -0,0 +1,16 @@
+325
+350
+375
+400
+425
+450
+475
+500
+525
+550
+575
+600
+625
+650
+675
+700
diff --git a/codec2/branches/0.7/unittest/lsp3.txt b/codec2/branches/0.7/unittest/lsp3.txt
new file mode 100644 (file)
index 0000000..6fde10c
--- /dev/null
@@ -0,0 +1,16 @@
+500
+550
+600
+650
+700
+750
+800
+850
+900
+950
+1000
+1050
+1100
+1150
+1200
+1250
diff --git a/codec2/branches/0.7/unittest/lsp4.txt b/codec2/branches/0.7/unittest/lsp4.txt
new file mode 100644 (file)
index 0000000..7eae7f8
--- /dev/null
@@ -0,0 +1,16 @@
+700
+800
+900
+1000
+1100
+1200
+1300
+1400
+1500
+1600
+1700
+1800
+1900
+2000
+2100
+2200
diff --git a/codec2/branches/0.7/unittest/lsp45678910.txt b/codec2/branches/0.7/unittest/lsp45678910.txt
new file mode 100644 (file)
index 0000000..291d3cd
--- /dev/null
@@ -0,0 +1,4097 @@
+6 4096
+1.081234  1.578844  1.855572  1.937313  2.532441  2.649806
+1.062804  1.450009  1.839560  1.956503  2.488847  2.653463
+1.101587  1.361019  1.833584  1.932414  2.505176  2.629812
+1.079058  1.376855  1.872688  1.955078  2.541337  2.633780
+1.095536  1.631036  1.866273  2.066987  2.506661  2.570431
+1.093059  1.561358  1.772473  2.123863  2.547475  2.618258
+1.093649  1.500206  1.786047  2.077115  2.483767  2.572542
+1.035022  1.485983  1.678652  2.079363  2.402344  2.513315
+1.231720  1.630566  1.849906  2.023447  2.467212  2.571610
+1.206362  1.478193  1.855647  2.009197  2.437429  2.552382
+1.204249  1.495756  1.846404  2.039977  2.500628  2.592437
+1.272025  1.438353  1.854503  2.038713  2.518717  2.620094
+1.298912  1.483356  1.838869  1.983659  2.488374  2.597006
+1.385591  1.500184  1.819431  1.981705  2.505537  2.612529
+1.413670  1.566546  1.767180  1.994490  2.569613  2.625244
+1.469053  1.626083  1.751768  2.041187  2.608951  2.658775
+1.489505  1.617638  1.689177  2.053852  2.662243  2.705533
+1.431122  1.535578  1.647319  1.810924  2.575767  2.692196
+1.411673  1.606174  1.730361  1.969368  2.628110  2.691849
+1.341020  1.639970  2.197392  2.281319  2.449714  2.625998
+1.319877  1.674826  2.101177  2.281732  2.499782  2.611482
+1.274620  1.610124  1.901436  2.235657  2.518178  2.628876
+1.172210  1.365637  1.784703  1.904448  2.538076  2.646190
+1.096161  1.350109  1.754990  1.869673  2.486568  2.605496
+1.036538  1.326195  1.729890  1.862116  2.461192  2.575454
+1.016529  1.277247  1.688801  1.808376  2.462981  2.576244
+0.968031  1.329007  1.716412  1.821357  2.481150  2.561950
+0.940641  1.283342  1.767876  1.860537  2.503139  2.594903
+0.926995  1.243331  1.738909  1.901001  2.449501  2.557636
+0.839883  1.237117  1.702150  1.812616  2.421388  2.492978
+0.924474  1.188075  1.757524  1.824899  2.455944  2.611065
+0.964230  1.207274  1.666224  1.876812  2.507149  2.580412
+0.989772  1.189729  1.693447  1.807142  2.445712  2.561953
+0.919183  1.203118  1.673832  1.772614  2.385797  2.511668
+0.978552  1.175420  1.613855  1.726871  2.328959  2.516699
+1.014543  1.254251  1.587284  1.756626  2.403061  2.510828
+1.096718  1.231168  1.557405  1.843944  2.463584  2.555458
+1.168771  1.351177  1.613931  1.831029  2.476269  2.581218
+1.176515  1.264150  1.564916  1.760486  2.483522  2.581045
+1.017969  1.249828  1.424493  1.593545  2.458340  2.525030
+1.053988  1.216029  1.517421  1.851941  2.342751  2.502327
+0.908986  1.250795  1.593917  1.887100  2.373089  2.530129
+0.993871  1.164018  1.616620  1.775732  2.569459  2.658570
+1.102483  1.386153  1.573681  1.785642  2.317931  2.508557
+1.207240  1.390831  1.551049  1.850614  2.335983  2.494330
+0.905032  1.416478  1.580046  1.841825  2.503807  2.601603
+0.795890  1.107933  1.597705  2.015496  2.402148  2.534611
+0.732401  1.158610  1.557468  1.938003  2.626415  2.705430
+0.859670  1.129062  1.671859  1.953992  2.514790  2.615870
+0.921647  1.245355  1.683753  1.894457  2.599645  2.716564
+0.845409  1.194759  1.767314  1.844514  2.589767  2.716944
+0.977678  1.141401  1.667109  1.923833  2.632008  2.689070
+0.951137  1.122551  1.714183  1.885895  2.535763  2.672112
+1.029949  1.159554  1.739443  1.928325  2.488185  2.623518
+0.925634  1.225929  1.751801  1.970749  2.532895  2.621066
+1.012300  1.211427  1.793946  1.885857  2.467267  2.572492
+0.993978  1.137467  1.743472  1.840886  2.390082  2.566385
+0.989822  1.173068  1.687559  1.948929  2.325527  2.473423
+0.955854  1.237231  1.807406  2.116766  2.391031  2.502779
+1.103361  1.357985  1.852236  2.097091  2.392749  2.553242
+1.128873  1.440897  1.927907  2.176697  2.407985  2.544276
+1.316127  1.575436  1.964565  2.158944  2.485840  2.576132
+1.469605  1.772101  1.954837  2.164070  2.399616  2.481917
+1.506520  1.754882  2.018413  2.249491  2.486272  2.607615
+1.524190  1.776451  2.054579  2.275694  2.584977  2.669083
+1.518000  1.850281  2.026435  2.301875  2.577528  2.669180
+1.422050  1.788979  1.967476  2.184773  2.596851  2.699678
+1.208408  1.434703  1.923623  2.003769  2.602930  2.685007
+1.221170  1.436565  1.879969  2.033402  2.498146  2.695421
+1.217714  1.375982  1.908609  1.973031  2.480559  2.645396
+1.200348  1.412239  1.863276  2.054536  2.409232  2.646327
+1.439453  1.675933  2.064707  2.273226  2.606450  2.696215
+1.547568  1.956021  2.083785  2.387077  2.634316  2.711216
+1.745365  1.995260  2.176270  2.409488  2.632251  2.707416
+1.819289  1.982164  2.210166  2.452194  2.603770  2.664517
+1.669555  1.940179  2.100875  2.386942  2.530819  2.630866
+1.597684  1.945913  2.072836  2.338891  2.544245  2.608247
+1.656152  1.888690  1.984550  2.301133  2.510775  2.586360
+1.618800  1.898863  2.024738  2.291312  2.440530  2.560289
+1.481284  1.826210  1.971921  2.192909  2.417020  2.530293
+1.318733  1.581540  1.845445  2.163997  2.389227  2.505418
+1.341326  1.565852  1.802875  2.218482  2.430769  2.545834
+1.318506  1.412657  1.677620  2.182351  2.372753  2.476532
+1.243720  1.456674  1.665712  2.126711  2.332874  2.438449
+1.152502  1.458855  1.582937  2.037521  2.342102  2.428296
+1.025383  1.407599  1.551528  1.846789  2.282863  2.385436
+0.876560  1.384326  1.582900  1.741935  2.239923  2.338453
+0.953781  1.441879  1.592404  1.764174  2.294091  2.474201
+0.899968  1.454031  1.634363  1.724312  2.353403  2.597502
+0.784159  1.423933  1.737258  1.855960  2.390032  2.614540
+0.802442  1.397066  1.658548  1.816788  2.429390  2.500099
+0.863071  1.318492  1.646022  1.812971  2.398098  2.503855
+0.896870  1.306239  1.671592  1.902175  2.466526  2.601523
+0.999503  1.304292  1.708420  1.899036  2.512342  2.655191
+1.045277  1.266302  1.669631  1.846323  2.517066  2.637484
+1.038456  1.158529  1.643778  1.865279  2.583201  2.658938
+1.026317  1.219306  1.768348  1.840920  2.538168  2.673329
+1.080965  1.215431  1.730192  1.836927  2.236858  2.608870
+1.101801  1.431508  1.752078  1.918964  2.091244  2.538958
+1.178729  1.297314  1.724099  1.850753  2.310291  2.621525
+1.151182  1.239683  1.754792  1.850524  2.539101  2.705992
+1.202697  1.300604  1.763340  1.867428  2.470717  2.664655
+1.261122  1.368681  1.753282  1.846646  2.461515  2.652599
+1.263075  1.364289  1.797670  1.876939  2.543725  2.660224
+1.320149  1.415925  1.809830  1.903217  2.515554  2.648236
+1.339872  1.459354  1.806677  1.924576  2.491477  2.587047
+1.355170  1.451772  1.763405  1.944161  2.472633  2.561167
+1.327925  1.428910  1.704448  1.914816  2.397366  2.503472
+1.307600  1.415352  1.616295  1.840793  2.322166  2.470994
+1.248247  1.349207  1.617615  1.772735  2.250680  2.486533
+1.096572  1.355681  1.626115  1.941988  2.313846  2.498213
+1.012526  1.342839  1.647854  1.907164  2.435934  2.533191
+0.944393  1.399280  1.642998  1.931993  2.331977  2.489908
+0.883306  1.402338  1.706359  2.025366  2.373713  2.543710
+0.829559  1.235771  1.712746  2.184853  2.386736  2.544183
+0.923799  1.513109  1.703086  2.105291  2.476476  2.555162
+0.772688  1.443301  1.656120  2.053011  2.450442  2.532517
+0.776285  1.403196  1.734016  1.935257  2.464085  2.566799
+0.782396  1.418811  1.758875  1.973225  2.548330  2.610298
+0.789572  1.411082  1.771533  2.060410  2.540262  2.631254
+0.774326  1.288019  1.837269  1.960951  2.512420  2.581626
+0.811751  1.274027  1.810006  1.885738  2.565463  2.639219
+0.844982  1.320831  1.873915  1.944600  2.561048  2.661720
+0.881256  1.695357  1.906981  2.078886  2.618546  2.678654
+1.099890  1.727818  1.971319  2.153135  2.509688  2.602947
+1.173850  1.685437  1.917457  2.147432  2.383055  2.567035
+1.101548  1.543219  1.820605  2.055324  2.338724  2.585028
+0.975012  1.379716  1.776625  2.033293  2.194151  2.518224
+0.967054  1.082459  1.618973  2.077928  2.206837  2.370886
+1.009607  1.120613  1.534181  2.088528  2.282936  2.420584
+0.899159  1.208523  1.423691  1.970324  2.287269  2.498904
+0.879682  1.314480  1.479489  1.689360  2.209743  2.285765
+1.033473  1.243843  1.473137  1.667992  2.159422  2.255044
+1.048412  1.255890  1.536997  1.820047  2.142252  2.313751
+1.048246  1.189264  1.705109  1.835993  2.105450  2.372062
+1.034320  1.138878  1.514616  1.829657  2.170447  2.425608
+1.103878  1.217645  1.622150  1.805848  2.027526  2.376811
+1.087235  1.195012  1.559018  1.895036  2.250122  2.379205
+1.130013  1.293868  1.692397  1.858880  2.197201  2.349063
+1.162892  1.304601  1.691021  1.969323  2.268614  2.430288
+1.151808  1.257932  1.673832  1.902017  2.189155  2.458708
+1.168445  1.271828  1.557328  2.084152  2.308031  2.420367
+1.235095  1.340187  1.656794  2.095155  2.283187  2.409638
+1.252394  1.355363  1.609848  2.085193  2.332714  2.488870
+1.226314  1.343994  1.673049  2.215533  2.459996  2.546921
+1.408182  1.566449  1.701931  2.155097  2.540243  2.588591
+1.303998  1.548995  1.653578  2.128738  2.589470  2.633320
+1.312529  1.488936  1.690548  1.982880  2.558390  2.622521
+1.303590  1.485664  1.772996  1.991417  2.555629  2.650059
+1.257202  1.528917  1.880489  2.045674  2.400087  2.567493
+1.294719  1.634324  1.911539  2.046657  2.438083  2.611133
+1.328444  1.716065  1.850301  2.021260  2.507052  2.612864
+1.138077  1.269039  1.792588  1.898148  2.530410  2.653563
+1.024794  1.145542  1.688222  1.812928  2.425037  2.650928
+1.056656  1.178042  1.590336  1.747349  2.368449  2.618711
+0.994299  1.110839  1.632651  1.730538  2.337688  2.550296
+0.960030  1.103482  1.632800  1.745079  2.197252  2.530535
+0.952099  1.078914  1.704160  1.837306  2.319065  2.544307
+0.901034  1.074801  1.653662  1.788590  2.393831  2.533117
+0.970595  1.130054  1.568353  1.820966  2.445105  2.563373
+0.883200  1.029140  1.480583  1.884365  2.321620  2.470715
+0.817959  0.941844  1.410138  1.540709  2.174043  2.482774
+0.772028  0.888033  1.490117  1.717092  2.324349  2.560462
+0.874200  1.020101  1.571479  1.746811  2.437393  2.561332
+0.827282  1.010026  1.605382  1.750680  2.261846  2.481604
+0.790605  1.149000  1.653820  1.781055  2.358642  2.491606
+0.746581  0.961080  1.604908  1.879005  2.319270  2.551585
+0.845418  0.969530  1.696169  1.890927  2.301880  2.621489
+0.826083  1.016050  1.658604  1.852554  2.435884  2.572744
+0.804260  0.948999  1.684490  2.103337  2.475054  2.575853
+0.837016  1.029999  1.676991  1.796645  2.498023  2.631032
+0.779629  0.917041  1.607073  1.868904  2.459568  2.628902
+0.802981  0.922379  1.556141  1.967845  2.595450  2.692512
+0.821239  0.952349  1.585249  2.095797  2.593711  2.655934
+0.819528  1.109552  1.526845  1.767514  2.637798  2.710511
+0.846222  1.055717  1.707281  1.838626  2.113999  2.501403
+0.956553  1.439848  1.724902  1.939820  2.145194  2.431913
+1.334292  1.551594  1.721399  2.019173  2.178003  2.329439
+1.247359  1.571459  1.834521  2.114156  2.268206  2.489811
+1.223145  1.573420  1.846247  2.016089  2.219280  2.457849
+1.239932  1.537791  1.822800  2.046476  2.444455  2.578055
+1.299681  1.557742  1.798304  2.080692  2.393370  2.575201
+1.273117  1.474131  1.814869  2.014907  2.405011  2.602918
+1.229029  1.448502  1.757153  2.050565  2.417160  2.594614
+1.206296  1.515099  1.788958  2.042150  2.368561  2.585804
+1.158903  1.544803  1.861448  2.066653  2.405246  2.590991
+1.203257  1.479859  1.833516  2.070616  2.431802  2.585701
+1.170767  1.555780  1.826674  2.077078  2.467476  2.619408
+1.116279  1.593527  1.824249  2.160817  2.427806  2.600491
+1.250314  1.617299  1.962648  2.152242  2.531239  2.631433
+1.352996  1.645245  2.070194  2.180379  2.612026  2.688774
+1.460334  1.917189  2.086815  2.314592  2.641184  2.723059
+1.557095  1.916613  2.056898  2.263201  2.640329  2.702797
+1.410674  1.903388  2.077833  2.222944  2.615402  2.694117
+1.340491  1.804040  2.040016  2.149565  2.607705  2.678152
+1.090681  1.321064  1.862736  1.983775  2.475855  2.592436
+1.002459  1.265507  1.813017  1.904336  2.499258  2.626541
+1.051386  1.161286  1.832534  1.955080  2.502338  2.624753
+0.942516  1.064243  1.669560  1.977253  2.464181  2.598328
+0.869608  0.984141  1.454614  1.956177  2.507893  2.617868
+0.972489  1.135467  1.529146  1.729979  2.411574  2.571077
+1.051275  1.149410  1.547524  1.827149  2.511333  2.617618
+1.079744  1.191206  1.539363  1.944728  2.545236  2.632156
+1.182063  1.260030  1.596098  2.084659  2.511859  2.579406
+1.172004  1.352761  1.462749  2.015059  2.625356  2.679374
+1.200545  1.322975  1.515601  1.769202  2.523140  2.666825
+1.228092  1.307135  1.734031  1.914746  2.244815  2.562025
+1.176188  1.321661  1.782310  1.882580  2.271364  2.521450
+1.150025  1.486223  1.774146  1.970935  2.385075  2.612636
+1.103163  1.455003  1.720622  1.899593  2.356715  2.591383
+1.070467  1.386313  1.746928  1.891984  2.367512  2.543572
+0.953610  1.176163  1.643545  1.919980  2.372057  2.572461
+1.052319  1.405171  1.688954  1.831668  2.542879  2.632479
+0.996802  1.441427  1.684462  1.821948  2.595992  2.658845
+1.026550  1.334938  1.740944  1.840382  2.571653  2.678967
+1.108319  1.200840  1.706127  1.999085  2.514665  2.648206
+1.133324  1.219468  1.747774  2.013077  2.406643  2.640363
+1.142143  1.218723  1.814638  1.951061  2.430067  2.666180
+1.081563  1.207089  1.846455  1.946284  2.339144  2.612659
+1.146374  1.238625  1.874251  1.968098  2.427377  2.595630
+1.069408  1.393128  1.859759  1.941816  2.374471  2.538181
+1.060221  1.402928  1.784643  1.909954  2.080852  2.375424
+0.893759  1.225333  1.741426  1.895488  2.062213  2.441777
+0.911307  1.301394  1.651487  1.798169  1.996879  2.208655
+1.102905  1.503307  1.707775  1.808533  1.958631  2.311679
+1.149446  1.328058  1.738279  1.904609  2.061868  2.257965
+1.121345  1.230563  1.748776  1.950661  2.086466  2.389286
+0.948970  1.101893  1.676635  1.875393  2.016817  2.296681
+1.035082  1.162231  1.641377  1.952709  2.100948  2.358717
+0.994183  1.114307  1.547601  1.773728  1.966081  2.336299
+1.025110  1.139705  1.585236  1.912371  2.102465  2.482426
+0.955352  1.062216  1.659060  1.848407  2.043281  2.487426
+1.049103  1.120549  1.446982  1.949018  2.026898  2.560590
+1.012432  1.138276  1.367936  2.008468  2.189441  2.422416
+1.082028  1.234911  1.351755  1.827170  2.173158  2.300241
+1.094359  1.235138  1.416416  1.922593  2.128232  2.419413
+1.034512  1.151307  1.492358  1.980846  2.149036  2.365312
+1.013088  1.154539  1.459958  1.943044  2.281758  2.397269
+0.987103  1.274347  1.561873  1.917460  2.334292  2.495651
+0.989791  1.289172  1.623138  1.982329  2.345033  2.548052
+1.042013  1.225970  1.610016  1.974800  2.406311  2.537036
+1.019690  1.323725  1.679076  1.983690  2.443023  2.561932
+1.030978  1.249914  1.753285  1.970302  2.442750  2.577102
+1.078647  1.281367  1.821676  2.046994  2.512487  2.614303
+1.042503  1.318276  1.817538  1.977740  2.538774  2.643473
+1.033751  1.323431  1.885960  1.993635  2.587127  2.648293
+1.084158  1.434121  1.899660  1.974483  2.661669  2.717102
+1.095790  1.481301  1.916550  1.970409  2.671232  2.730973
+1.147960  1.553068  1.884541  1.960664  2.501839  2.667876
+1.137776  1.498910  1.962620  2.047239  2.537310  2.642351
+1.108862  1.435492  1.955490  2.195866  2.514284  2.601530
+1.191071  1.557850  1.984542  2.270790  2.541878  2.642064
+1.110737  1.553081  1.978127  2.211052  2.613375  2.706641
+1.114093  1.728016  1.975042  2.124483  2.602927  2.681942
+1.148485  1.627087  1.968135  2.073898  2.607358  2.686667
+1.109004  1.450655  1.961102  2.058609  2.611646  2.694610
+1.095904  1.318763  1.866640  2.096294  2.574677  2.658840
+1.116558  1.367968  1.922533  2.016505  2.549444  2.646230
+1.129468  1.529113  1.942204  2.003339  2.527872  2.699919
+1.139050  1.679536  1.945866  2.032922  2.537427  2.642172
+1.219207  1.599421  1.929600  2.011091  2.539104  2.705280
+1.233969  1.556201  1.930999  2.084786  2.578580  2.675834
+1.234430  1.653741  2.033213  2.256759  2.637546  2.699663
+1.255288  1.475044  2.022543  2.289234  2.587690  2.703947
+1.253389  1.472198  1.956397  2.211186  2.574243  2.676099
+1.126854  1.587210  1.950824  2.031487  2.416846  2.614459
+1.007062  1.608304  1.896229  1.986335  2.223017  2.524028
+1.067280  1.729449  1.931889  2.045329  2.164850  2.400910
+0.946660  1.699777  1.870624  1.981832  2.135670  2.447688
+1.002686  1.728563  1.939905  2.072520  2.274792  2.467485
+1.148787  1.600550  2.003063  2.128026  2.409105  2.506525
+1.191365  1.359514  1.908437  2.116985  2.369079  2.529393
+1.229740  1.316359  1.901465  2.001169  2.368350  2.575701
+1.167453  1.284078  1.851548  2.056283  2.446292  2.573763
+1.177049  1.282978  1.796076  2.014566  2.409896  2.524428
+1.166550  1.281729  1.804132  1.938592  2.383050  2.543803
+1.144710  1.266197  1.755782  1.865513  2.354119  2.575142
+1.168465  1.283561  1.695054  1.817537  2.302788  2.529561
+1.093474  1.316111  1.625831  1.791050  2.303314  2.408563
+1.072994  1.218877  1.586912  1.725308  2.219203  2.343524
+0.946241  1.172838  1.426290  1.551682  2.192575  2.321727
+1.001802  1.174980  1.507444  1.697862  2.240802  2.478241
+0.992564  1.257780  1.429092  1.819825  2.234153  2.434915
+0.933586  1.255559  1.372464  1.686266  2.265977  2.349467
+0.987914  1.162881  1.404420  1.563483  2.227668  2.485371
+1.058576  1.185833  1.325383  1.445585  2.164512  2.455141
+1.042271  1.149610  1.389036  1.473828  1.906671  2.390132
+0.966952  1.075537  1.288155  1.405105  2.061861  2.451990
+0.901530  1.194476  1.354732  1.705750  2.325032  2.434812
+1.038418  1.292428  1.527305  1.909844  2.230333  2.465135
+1.336010  1.441693  1.849134  2.208029  2.414400  2.532513
+1.436224  1.645653  2.008636  2.198160  2.502278  2.601413
+1.424341  1.684427  1.929812  2.122504  2.512280  2.604860
+1.452203  1.722988  1.962207  2.156659  2.484102  2.584594
+1.481999  1.735238  1.971190  2.222801  2.512305  2.623621
+1.392556  1.721267  1.940304  2.174966  2.488944  2.601854
+1.243347  1.558461  1.809822  1.990890  2.381971  2.537485
+1.199294  1.421504  1.763108  1.990880  2.358918  2.489556
+1.217773  1.348784  1.714665  1.916837  2.379728  2.456961
+1.219523  1.326854  1.719656  1.838075  2.299329  2.435406
+1.263073  1.353656  1.787228  1.918973  2.320389  2.448246
+1.270962  1.373799  1.718185  1.857935  2.366922  2.481748
+1.284351  1.368069  1.793907  1.895081  2.356790  2.524604
+1.244789  1.353657  1.782947  1.928688  2.225716  2.379949
+1.269283  1.368726  1.719184  1.909677  2.267163  2.491540
+1.249305  1.338194  1.799918  1.917097  2.274691  2.533224
+1.179498  1.259046  1.802972  1.927327  2.228930  2.503637
+1.140961  1.245902  1.708660  1.923794  2.243465  2.557345
+1.063955  1.209030  1.737289  1.945349  2.338697  2.573092
+1.003475  1.109161  1.745131  1.902188  2.308443  2.601614
+0.937618  1.077537  1.747804  1.869648  2.205055  2.570449
+0.885099  1.192451  1.790545  1.876157  2.360305  2.598108
+0.803485  0.966415  1.768458  1.928742  2.196723  2.530460
+0.797205  1.120717  1.776585  1.878573  2.370357  2.614341
+0.831514  1.059080  1.808800  1.905483  2.448208  2.573050
+0.806597  0.967446  1.829385  1.963682  2.358632  2.653242
+0.699378  0.851831  1.739446  1.933943  2.516377  2.655249
+0.739203  1.033985  1.902113  2.010327  2.494149  2.629822
+0.945605  1.079706  1.796352  2.039543  2.581863  2.699784
+0.843512  1.304861  1.835452  2.036832  2.600217  2.677826
+0.970152  1.414374  1.854051  1.957787  2.596045  2.665425
+1.067282  1.438542  1.888429  2.067094  2.531016  2.643177
+1.117619  1.563112  1.886324  2.218866  2.530223  2.624080
+1.209656  1.626913  1.943700  2.187427  2.555090  2.658675
+1.338891  1.812879  2.030890  2.305204  2.569275  2.661165
+1.303367  1.840104  2.035985  2.286745  2.614227  2.713359
+1.193428  1.727354  1.926203  2.184400  2.574784  2.631812
+1.063515  1.717188  1.903657  2.119051  2.444811  2.497667
+1.062175  1.188948  1.810480  2.044978  2.322378  2.578780
+1.073201  1.177557  1.654731  2.023264  2.200369  2.442874
+1.027815  1.165415  1.669466  1.859614  2.202142  2.462466
+1.035584  1.148236  1.604900  1.872549  2.257851  2.551682
+1.007205  1.131087  1.579146  1.969788  2.331637  2.507912
+0.908594  1.005601  1.463269  2.072372  2.304356  2.407363
+0.981614  1.126428  1.280565  1.886853  2.101922  2.487836
+1.006764  1.132557  1.253088  1.718315  2.189249  2.436605
+0.899830  1.156538  1.260748  1.696712  2.116655  2.228297
+0.896996  1.246551  1.436874  1.645194  2.073642  2.149130
+0.965481  1.069671  1.446489  1.949492  2.091582  2.298331
+0.898113  1.058765  1.617556  1.941551  2.113568  2.374743
+0.769481  1.159379  1.597415  1.959851  2.283842  2.418197
+0.908091  1.305340  1.473570  1.862549  2.164147  2.331091
+0.924282  1.334689  1.563201  2.043541  2.406015  2.515756
+0.972939  1.381971  1.549985  2.021238  2.268488  2.419332
+1.032229  1.484031  1.620031  1.952234  2.267322  2.486440
+1.005234  1.354692  1.620203  1.777917  2.223067  2.497574
+1.072742  1.245035  1.661666  1.819389  2.260496  2.468700
+1.134470  1.250480  1.737034  1.868971  2.303204  2.466426
+1.145935  1.293264  1.728505  1.950979  2.350982  2.504021
+1.226356  1.329795  1.750777  1.982144  2.347843  2.553027
+1.234801  1.328107  1.696728  2.060564  2.437310  2.535600
+1.247128  1.360496  1.742955  1.961348  2.474080  2.668447
+1.234736  1.329837  1.688634  1.913331  2.442940  2.627695
+1.230430  1.326635  1.697588  1.806044  2.381473  2.618535
+1.188567  1.273079  1.708983  1.969001  2.340683  2.588959
+1.204284  1.331218  1.835523  2.141256  2.463226  2.583492
+1.202374  1.397220  1.863749  2.155165  2.599733  2.681191
+1.217581  1.333297  1.763898  1.994983  2.601835  2.684817
+1.272368  1.364451  1.776352  1.952098  2.563424  2.676170
+1.330173  1.434654  1.825090  1.938032  2.579405  2.666102
+1.383550  1.514770  1.774712  2.134998  2.528583  2.614711
+1.488234  1.631245  1.795942  2.180588  2.497787  2.585930
+1.497854  1.598429  1.760395  1.985719  2.538066  2.622220
+1.446514  1.555686  1.675484  1.899620  2.547070  2.637129
+1.420188  1.651758  1.888119  2.201558  2.498716  2.624372
+1.524851  1.748918  1.939479  2.132594  2.426619  2.604303
+1.588214  1.786968  1.965710  2.123251  2.417433  2.579888
+1.603052  1.805249  1.932723  2.088062  2.490882  2.628467
+1.521714  1.853040  1.968163  2.198421  2.530921  2.597229
+1.496309  1.785807  2.001979  2.206169  2.574155  2.645280
+1.405201  1.500557  1.908673  2.179223  2.543732  2.645774
+1.369555  1.501308  1.848796  2.089859  2.551118  2.643621
+1.395377  1.488644  1.872404  2.028116  2.530256  2.599192
+1.354582  1.508972  1.848875  1.976677  2.504926  2.579355
+1.325752  1.411326  1.837129  1.970792  2.502717  2.584831
+1.264497  1.390436  1.764758  2.087338  2.519279  2.625037
+1.280904  1.355652  1.790288  1.995707  2.502567  2.587359
+1.267443  1.360843  1.858033  2.035632  2.509375  2.584870
+1.238902  1.487541  1.786660  2.080354  2.480913  2.582137
+1.228708  1.441140  1.715963  1.893335  2.507070  2.565131
+1.167347  1.397307  1.672051  1.923535  2.438392  2.523520
+1.169232  1.356809  1.567433  1.950379  2.378945  2.468006
+1.240244  1.470896  1.629735  2.024684  2.376716  2.454875
+1.370859  1.665288  1.831505  2.176433  2.486403  2.586565
+1.513368  1.657039  1.965014  2.298013  2.532148  2.623007
+1.446940  1.612676  1.929087  2.232303  2.466210  2.565149
+1.430659  1.664527  1.882163  2.234579  2.421664  2.527294
+1.511551  1.658934  1.944043  2.198499  2.451946  2.588348
+1.539441  1.741360  2.111062  2.229922  2.438935  2.615056
+1.510948  1.846893  2.061790  2.202452  2.484110  2.572628
+1.366393  1.611652  2.079365  2.260070  2.467062  2.588032
+1.383579  1.641339  1.997349  2.226153  2.491435  2.611630
+1.381458  1.706898  1.963061  2.125553  2.596797  2.681115
+1.360033  1.558255  1.949661  2.054826  2.599573  2.714554
+1.379339  1.491775  1.925897  2.046337  2.539371  2.696047
+1.313275  1.469403  1.863111  2.141749  2.553959  2.668104
+1.201520  1.563000  1.925029  2.093014  2.476606  2.614413
+0.965563  1.662126  1.836100  2.071866  2.530046  2.578446
+0.976435  1.635119  1.844726  2.005117  2.553083  2.614153
+1.098159  1.549476  1.826426  1.907908  2.490671  2.625630
+0.971599  1.431927  1.818186  1.923193  2.493841  2.568117
+0.881008  1.272866  1.901429  1.959221  2.513674  2.596017
+0.915929  1.478770  1.955701  2.082549  2.494350  2.585776
+1.008177  1.579393  1.898198  2.139172  2.477629  2.551209
+0.937399  1.507567  1.803910  1.922590  2.546047  2.637297
+0.848413  1.358228  1.783925  1.906229  2.477012  2.588525
+0.863404  1.488629  1.835502  1.930032  2.465498  2.545317
+0.844376  1.622282  1.826798  2.048364  2.490552  2.545809
+0.869731  1.705034  1.854703  2.111605  2.517014  2.593453
+0.862235  1.623015  1.899372  2.028710  2.527844  2.574800
+0.931658  1.576339  1.853614  1.975118  2.542237  2.614786
+0.848799  1.588406  1.847097  1.955899  2.534073  2.584561
+0.737814  1.457219  1.829993  1.966203  2.501271  2.579455
+0.786199  1.100080  1.860369  1.964282  2.419364  2.566134
+0.728962  1.040841  1.773818  1.963733  2.356948  2.578866
+0.733093  1.147783  1.789774  1.909293  2.349819  2.481103
+0.785959  1.280236  1.730487  1.926696  2.346913  2.422480
+0.784924  1.446821  1.669690  1.935370  2.368317  2.459601
+0.758523  1.466915  1.805902  1.946588  2.352213  2.426335
+0.767907  1.544295  1.768171  2.003937  2.239037  2.386192
+0.896374  1.562074  1.716926  1.903301  2.308243  2.430582
+0.834530  1.504812  1.737424  1.917731  2.409279  2.493291
+0.896027  1.406949  1.730026  1.903326  2.431247  2.539722
+1.039666  1.364116  1.806278  1.948174  2.440690  2.557972
+1.093454  1.412357  1.833723  1.940104  2.489654  2.564450
+1.190180  1.386167  1.848700  1.956202  2.481553  2.580885
+1.243158  1.350416  1.811797  1.893593  2.467576  2.613520
+1.221986  1.308711  1.815913  1.911989  2.417533  2.600995
+1.228372  1.343619  1.763163  1.872602  2.394885  2.582719
+1.278387  1.389710  1.738500  1.870267  2.420854  2.532852
+1.211636  1.401793  1.710146  1.811019  2.363826  2.482240
+1.161497  1.400684  1.766674  1.891745  2.392605  2.495922
+1.114937  1.405487  1.718336  1.927418  2.356818  2.468335
+1.074680  1.452959  1.668715  1.898094  2.336526  2.443457
+1.006705  1.356254  1.629477  1.848470  2.313894  2.426320
+0.966452  1.457923  1.654693  1.906386  2.320056  2.418339
+0.939007  1.519988  1.667014  1.989416  2.390669  2.488951
+0.946840  1.483985  1.701087  2.105572  2.391444  2.490066
+0.909129  1.501060  1.665371  2.004939  2.256700  2.389841
+0.958919  1.390613  1.680082  2.107156  2.297251  2.440839
+1.462160  1.588562  1.808539  2.109890  2.264826  2.417467
+1.301642  1.673806  1.892518  2.168109  2.477558  2.561621
+1.152769  1.529326  1.783781  2.014354  2.446614  2.560929
+1.128698  1.493018  1.748156  1.930275  2.530674  2.621591
+1.164356  1.496855  1.767664  1.871136  2.607250  2.684794
+1.122714  1.380513  1.762236  1.875604  2.441522  2.732814
+1.173906  1.545927  1.843801  1.933791  2.123448  2.629011
+1.155439  1.465806  1.793876  1.928550  2.168553  2.609610
+1.147812  1.484543  1.816424  1.908762  2.262620  2.704081
+1.185870  1.393524  1.811853  1.881115  2.544291  2.735905
+1.153304  1.451135  1.855404  1.888619  2.603314  2.738077
+1.208854  1.582363  1.784858  1.880089  2.596481  2.727884
+1.194841  1.542896  1.919056  2.023145  2.551891  2.634186
+1.230327  1.492063  1.937225  2.133605  2.615726  2.690226
+1.258764  1.581307  1.980070  2.138762  2.599037  2.691033
+1.220691  1.572961  1.917212  2.177536  2.599585  2.702012
+1.258143  1.556630  1.871736  2.132633  2.585514  2.673307
+1.233770  1.598238  1.849957  2.013674  2.542859  2.634481
+1.269759  1.560794  1.865225  2.076328  2.521082  2.617443
+1.116561  1.680882  1.781694  1.920497  2.592211  2.675845
+1.048209  1.662996  1.817400  1.915170  2.484585  2.623077
+0.954241  1.619674  1.813457  1.881694  2.550667  2.631971
+0.964363  1.579747  1.728712  1.862126  2.567566  2.636332
+1.296922  1.646884  1.889259  2.069271  2.320227  2.481389
+1.232775  1.619596  1.955470  2.066559  2.335277  2.456514
+1.238971  1.351788  1.877566  2.166413  2.317967  2.474389
+1.180292  1.388353  1.607451  1.950835  2.210855  2.477718
+1.124001  1.423538  1.617323  1.826801  2.206068  2.444078
+1.147794  1.487048  1.627974  1.926015  2.278418  2.486526
+1.092654  1.499725  1.623041  1.880156  2.411660  2.648649
+1.115294  1.468690  1.607626  1.814459  2.356904  2.576088
+1.176045  1.424631  1.614229  1.966337  2.352676  2.570354
+1.211051  1.467429  1.617777  1.851487  2.389770  2.591860
+1.287681  1.464858  1.633790  1.856231  2.349748  2.565320
+1.298585  1.495223  1.639003  1.942642  2.415390  2.518116
+1.309890  1.431142  1.757192  1.977209  2.414871  2.520878
+1.392241  1.477414  1.811303  1.909687  2.440417  2.573891
+1.414942  1.515382  1.858997  2.127937  2.490674  2.635418
+1.490435  1.565967  1.952412  2.049065  2.499936  2.600180
+1.485068  1.734116  1.997368  2.089376  2.524766  2.608159
+1.507131  1.787198  2.048100  2.128356  2.533629  2.624653
+1.485217  1.772591  2.048100  2.144373  2.595743  2.679785
+1.560042  1.744521  2.076144  2.156837  2.615057  2.698771
+1.506276  1.855445  2.064190  2.144534  2.585665  2.687788
+1.592877  1.903451  2.084530  2.163395  2.496904  2.633589
+1.609454  1.870860  2.119821  2.186594  2.599505  2.697819
+1.594779  1.855348  2.025620  2.142545  2.572299  2.637841
+1.527194  1.714086  2.076267  2.185169  2.526549  2.631137
+1.518012  1.628010  2.039263  2.134528  2.453843  2.576361
+1.531312  1.678082  2.035179  2.146889  2.504859  2.584171
+1.508627  1.632606  1.965140  2.148678  2.496640  2.592746
+1.499896  1.599423  1.913687  2.036860  2.450192  2.538166
+1.481158  1.583812  1.884461  2.013870  2.359497  2.481100
+1.475736  1.569698  1.799993  1.916182  2.329218  2.535901
+1.498641  1.623604  1.792824  1.945217  2.358627  2.490727
+1.431128  1.574627  1.743263  2.006116  2.347765  2.508896
+1.427064  1.536583  1.790690  1.943028  2.344465  2.452652
+1.436838  1.542023  1.758917  1.925622  2.242913  2.416844
+1.419788  1.509038  1.863320  1.995399  2.275792  2.424732
+1.424396  1.510477  1.882887  2.179017  2.304708  2.455667
+1.366051  1.461194  1.935323  2.147551  2.263420  2.465785
+1.407395  1.564972  1.981125  2.103440  2.445291  2.565104
+1.597013  1.877015  2.068503  2.270312  2.499356  2.604888
+1.484981  1.818125  2.149815  2.337593  2.504753  2.589439
+1.487878  1.937181  2.118271  2.308368  2.511781  2.604626
+1.682297  1.977033  2.192290  2.373676  2.522931  2.611282
+1.749459  1.905682  2.218271  2.352013  2.574227  2.681484
+1.676221  1.936512  2.237179  2.343782  2.535908  2.661271
+1.723362  1.989915  2.271236  2.413144  2.550828  2.649366
+1.756006  1.996913  2.312656  2.461484  2.625420  2.708736
+1.499770  1.763295  2.158871  2.346879  2.592716  2.682851
+1.747521  1.927133  2.248936  2.410841  2.604121  2.690881
+1.670354  1.938258  2.247669  2.447135  2.657540  2.730040
+1.669237  1.959610  2.179318  2.440527  2.588429  2.640800
+1.780231  2.015138  2.164810  2.399021  2.581913  2.646942
+1.739561  1.967219  2.065694  2.364479  2.589977  2.649441
+1.605008  1.875105  2.018901  2.227404  2.541181  2.603541
+1.511246  1.892601  2.027827  2.148110  2.520001  2.608199
+1.363362  1.568768  1.910845  2.057695  2.463506  2.558819
+1.338497  1.483825  1.883695  2.067074  2.448950  2.577904
+1.369193  1.437863  1.845222  2.078464  2.428504  2.615891
+1.377698  1.498294  1.867666  2.164965  2.492547  2.570908
+1.408098  1.487760  1.872414  2.097948  2.447272  2.551716
+1.402363  1.531952  1.897693  2.126667  2.419162  2.551442
+1.456496  1.554631  1.841067  2.095807  2.421290  2.561761
+1.434931  1.529146  1.795336  2.163704  2.446465  2.530309
+1.391108  1.495499  1.869679  2.161228  2.381406  2.532017
+1.388934  1.534466  1.797003  2.102941  2.398508  2.521270
+1.358571  1.471303  1.760049  2.100883  2.350197  2.546548
+1.276599  1.519215  1.779419  2.095819  2.442938  2.665941
+1.206661  1.457865  1.760464  2.244280  2.495881  2.644848
+1.214611  1.460274  1.979019  2.239454  2.398324  2.634473
+1.275473  1.473470  1.878570  2.203117  2.475028  2.687851
+1.291712  1.399288  1.813807  2.194118  2.502758  2.614888
+1.260058  1.397998  1.924890  2.186721  2.511667  2.644548
+1.210634  1.326713  1.897594  2.107441  2.460079  2.711722
+1.202657  1.319235  1.892634  2.079859  2.379418  2.679891
+0.967019  1.105970  1.761322  2.107426  2.328428  2.593155
+0.947746  1.035797  1.393730  2.061233  2.300744  2.668280
+0.996167  1.215029  1.378995  1.861982  2.329665  2.605022
+1.008823  1.198481  1.313837  1.693525  2.360746  2.604824
+1.054057  1.218510  1.368106  1.738006  2.174906  2.546071
+1.021568  1.133991  1.369174  1.935639  2.267798  2.544415
+1.033742  1.227769  1.451289  2.005917  2.412620  2.595031
+1.065155  1.168636  1.530185  2.061499  2.410743  2.485478
+1.121227  1.281283  1.432233  1.909928  2.202734  2.509308
+1.170032  1.306041  1.494945  1.981910  2.202815  2.351735
+1.152630  1.266186  1.620999  2.057673  2.214453  2.381642
+1.228128  1.313272  1.751468  2.118469  2.263417  2.453888
+1.307832  1.398650  1.799753  2.125735  2.260615  2.451800
+1.360104  1.477444  1.835740  2.121870  2.291563  2.499791
+1.398477  1.492966  1.806519  2.107140  2.241410  2.434146
+1.351212  1.462506  1.726393  2.122387  2.285789  2.421844
+1.297203  1.498868  1.766246  2.157839  2.376714  2.497158
+1.377349  1.518971  1.803789  2.191150  2.356374  2.478897
+1.289165  1.553241  1.674591  2.112634  2.403345  2.473877
+1.188972  1.700336  1.834324  2.055585  2.599531  2.700414
+1.077038  1.667666  1.902189  2.045693  2.602910  2.700056
+1.072057  1.272462  1.843743  1.901183  2.586254  2.720558
+1.084385  1.392072  1.823558  1.901299  2.589426  2.680029
+1.106319  1.441363  1.766145  1.853724  2.549356  2.627414
+1.094566  1.550024  1.771922  1.870952  2.559682  2.628051
+1.041899  1.598552  1.813702  1.928485  2.545630  2.671501
+1.090204  1.610510  1.812559  2.019257  2.556321  2.608793
+1.016528  1.626657  1.742411  2.041925  2.541538  2.602247
+1.075570  1.647752  1.870667  2.073970  2.574597  2.628798
+1.126656  1.586213  1.792572  1.982408  2.629180  2.725561
+1.027776  1.542665  1.831396  1.956878  2.603010  2.668523
+1.111897  1.543416  1.861469  1.942917  2.621957  2.672864
+1.080512  1.583194  1.857304  1.958456  2.633597  2.695142
+1.132239  1.449156  1.884949  1.977000  2.607850  2.709420
+1.232769  1.612605  1.960435  2.071693  2.644678  2.727118
+1.325014  1.779901  1.967304  2.113871  2.547837  2.668723
+1.404585  1.644448  2.058088  2.257112  2.519116  2.634613
+1.413485  1.609401  2.002521  2.184102  2.587532  2.696153
+1.354020  1.593877  2.014439  2.122204  2.617254  2.721812
+1.373822  1.656758  1.992185  2.189875  2.548725  2.702514
+1.421181  1.611084  1.958071  2.123616  2.569835  2.648136
+1.379179  1.620195  1.922636  2.093948  2.550690  2.641857
+1.367726  1.656675  1.838447  1.992123  2.596226  2.654039
+1.394553  1.750623  1.872269  2.038430  2.553215  2.623595
+1.464021  1.741591  1.912988  2.150261  2.565594  2.648823
+1.461132  1.809059  1.954612  2.209898  2.570276  2.642519
+1.434520  1.770834  1.904022  2.217315  2.631183  2.686995
+1.375527  1.631662  1.885996  2.086587  2.600503  2.671257
+1.339213  1.568724  1.817375  2.085568  2.591336  2.666455
+1.504403  1.779590  2.057141  2.272445  2.534600  2.634655
+1.474504  1.746318  2.044711  2.137376  2.474545  2.630529
+1.557045  1.755017  2.039661  2.080935  2.661339  2.741743
+1.573452  1.715361  2.056726  2.098368  2.691640  2.743685
+1.511431  1.831887  1.991585  2.156042  2.624346  2.709519
+1.501907  1.714027  2.012931  2.079434  2.554662  2.690409
+1.547183  1.671908  1.977966  2.104057  2.507158  2.614807
+1.563264  1.635971  1.990128  2.123718  2.563823  2.633190
+1.587772  1.697791  2.007538  2.127360  2.588839  2.656541
+1.618303  1.722230  2.008488  2.131284  2.618167  2.687641
+1.580078  1.684932  2.000646  2.087829  2.613984  2.687671
+1.572775  1.736323  1.961536  2.144351  2.641248  2.687943
+1.538985  1.652845  1.952108  2.156038  2.639302  2.685734
+1.537130  1.622797  1.963527  2.075940  2.612204  2.679327
+1.537449  1.633250  1.986524  2.075675  2.542791  2.643796
+1.543228  1.772021  2.053914  2.142473  2.536411  2.690489
+1.621800  1.829997  2.052741  2.210858  2.583215  2.665837
+1.609565  1.935324  2.146682  2.393315  2.597212  2.670556
+1.560818  1.935543  2.191435  2.444376  2.609921  2.692602
+1.704277  1.874585  2.010256  2.380095  2.528658  2.604802
+1.624784  1.837785  1.925361  2.193011  2.497168  2.569432
+1.556125  1.832653  1.986935  2.189317  2.453204  2.531630
+1.347428  1.669666  1.943932  2.108052  2.506631  2.608423
+1.278409  1.497251  1.838413  2.073920  2.454553  2.592324
+1.271049  1.415120  1.758107  2.232460  2.422770  2.554672
+1.260337  1.356714  1.913167  2.225895  2.380602  2.557250
+1.223099  1.307974  1.784088  2.207517  2.362875  2.487786
+1.249454  1.538164  1.716600  1.998319  2.362110  2.465531
+1.208014  1.503064  1.761303  1.917077  2.448048  2.525133
+1.151848  1.461146  1.783945  1.946886  2.452561  2.556307
+1.165555  1.347773  1.799946  1.920752  2.437876  2.546954
+1.109788  1.310449  1.815889  1.923381  2.427304  2.602804
+1.091990  1.233639  1.789609  1.925036  2.467804  2.611170
+1.052323  1.194748  1.809895  1.914231  2.390180  2.556318
+1.032267  1.189488  1.775623  1.889690  2.393248  2.640830
+0.992854  1.169627  1.814159  1.912252  2.320268  2.634324
+1.054415  1.177746  1.762755  1.907196  2.266178  2.516301
+1.029545  1.167365  1.780060  1.973540  2.227843  2.613887
+1.067777  1.184807  1.741322  1.919129  2.121959  2.500789
+1.167843  1.263051  1.778629  1.900717  2.150811  2.568660
+1.247027  1.323672  1.811046  1.934590  2.184022  2.674617
+1.331781  1.426137  1.785144  1.966030  2.114558  2.541825
+1.360900  1.444142  1.862535  1.949748  2.426744  2.646105
+1.408538  1.451788  1.866918  2.014230  2.478842  2.705911
+1.405554  1.483551  1.874980  1.960293  2.502764  2.662540
+1.442367  1.544656  1.883354  1.987590  2.562980  2.647761
+1.480719  1.536202  1.881818  2.018874  2.582349  2.661791
+1.513078  1.583246  1.895764  1.987154  2.586166  2.676009
+1.497760  1.602088  1.831006  1.985404  2.564090  2.643635
+1.497065  1.564915  1.844643  1.957697  2.539930  2.677163
+1.468106  1.523747  1.865842  1.940079  2.607970  2.684862
+1.468104  1.564389  1.858916  1.982405  2.606481  2.709686
+1.422735  1.519196  1.806791  1.891590  2.614823  2.703893
+1.396871  1.476698  1.776404  2.013253  2.607847  2.665988
+1.391532  1.504565  1.830535  2.081544  2.611020  2.720808
+1.372885  1.645062  1.833360  2.015761  2.631341  2.701342
+1.331289  1.747404  1.897953  2.146510  2.586685  2.658273
+1.503178  1.734690  1.914996  2.282089  2.598389  2.679187
+1.465242  1.711762  2.025166  2.284078  2.653659  2.717393
+1.423402  1.768761  2.084406  2.277880  2.636443  2.711524
+1.423821  1.724472  2.032594  2.300309  2.603340  2.686111
+1.433184  1.818868  2.053883  2.409241  2.628605  2.699461
+1.509846  1.793493  2.052637  2.357768  2.644126  2.718058
+1.575730  1.851530  2.032958  2.374899  2.583530  2.662235
+1.501264  1.780829  1.998554  2.329265  2.505605  2.606743
+1.460060  1.763209  1.912334  2.214416  2.494328  2.577616
+1.444041  1.657674  1.895357  2.148549  2.478458  2.595455
+1.454287  1.619858  1.935887  2.189754  2.478831  2.594880
+1.377243  1.642180  1.919668  2.142842  2.421514  2.541038
+1.051059  1.421021  1.830399  2.021216  2.373690  2.548829
+0.964571  1.071641  1.394899  2.151202  2.371776  2.464951
+0.966306  1.181025  1.302213  2.014819  2.375093  2.435135
+0.895560  1.207845  1.335308  1.823923  2.239924  2.363100
+1.006776  1.203093  1.317821  1.873977  2.336638  2.408782
+1.054129  1.225595  1.379006  2.024687  2.333311  2.421550
+1.090202  1.224770  1.409674  2.013195  2.245364  2.353229
+1.076475  1.203972  1.563890  2.033954  2.203362  2.369101
+1.127967  1.249133  1.664693  2.080426  2.256625  2.469541
+1.202013  1.429684  1.793680  2.080715  2.339984  2.460053
+1.517223  1.673904  1.927925  2.203642  2.386760  2.520143
+1.586618  1.786240  2.041674  2.198999  2.416371  2.581194
+1.593300  1.808548  2.148779  2.250278  2.372090  2.532412
+1.657294  1.783458  2.150393  2.258130  2.453915  2.616209
+1.571489  1.792659  2.117652  2.350385  2.577192  2.666949
+1.301994  1.729750  1.974424  2.093250  2.593899  2.663024
+1.100218  1.563399  1.919910  2.059220  2.562974  2.637757
+1.025074  1.540738  1.811898  2.057911  2.491877  2.603248
+1.015309  1.473504  1.802588  2.013084  2.436758  2.605319
+1.022065  1.158479  1.689786  2.183529  2.383778  2.492374
+1.212476  1.453108  1.823947  2.061442  2.396186  2.536578
+1.126243  1.452934  1.809587  2.071074  2.408943  2.549557
+0.880332  1.324785  1.621337  1.967251  2.313156  2.426927
+0.749583  1.358409  1.575073  1.870590  2.279227  2.377431
+0.901917  1.290215  1.674425  1.954410  2.233361  2.391524
+0.850971  1.252102  1.657646  1.816460  2.183885  2.328806
+0.881480  1.284101  1.698159  1.844661  2.341820  2.440909
+0.874499  1.182682  1.709489  1.917452  2.365966  2.499649
+0.833751  1.231132  1.803319  1.918020  2.459092  2.546881
+0.850970  1.127086  1.772073  1.855222  2.487580  2.582865
+0.881650  1.114802  1.820703  1.959079  2.521753  2.598731
+0.803558  1.150285  1.798477  1.952675  2.538917  2.634898
+0.867833  0.990496  1.832275  1.929767  2.547660  2.681084
+0.865057  1.067437  1.773263  1.860188  2.558331  2.702216
+0.832529  0.985960  1.756367  1.862925  2.438281  2.623782
+0.850804  1.060553  1.892217  1.984007  2.483774  2.661123
+0.873803  1.041984  1.746198  1.932438  2.338221  2.554585
+0.958594  1.103471  1.836438  1.936783  2.393758  2.573200
+1.014831  1.140873  1.825933  2.013713  2.401490  2.609423
+1.075369  1.457644  1.900463  2.033493  2.314190  2.490949
+1.201715  1.736170  1.914076  2.066503  2.386907  2.476963
+1.215217  1.873613  2.065903  2.182990  2.374981  2.489555
+1.620207  1.851261  2.111542  2.342798  2.527494  2.633887
+1.683879  1.860372  2.126009  2.404344  2.562983  2.636158
+1.703817  1.934383  2.133673  2.393214  2.601932  2.682469
+1.526877  1.900128  2.151100  2.361638  2.575171  2.658979
+1.587253  1.881390  2.129945  2.267860  2.577863  2.657840
+1.539163  1.871344  2.190283  2.360385  2.624615  2.705636
+1.625747  1.862181  2.120094  2.339463  2.592159  2.682142
+1.679527  1.920689  2.161166  2.317106  2.648896  2.712106
+1.635199  1.922826  2.174839  2.407399  2.630046  2.709271
+1.454186  1.975699  2.151850  2.371342  2.609179  2.685790
+1.672439  2.011404  2.183017  2.463917  2.652956  2.711525
+1.612105  1.987481  2.102582  2.293346  2.616125  2.670264
+1.528075  1.895073  2.053582  2.232503  2.544912  2.624122
+1.420355  1.683500  1.963431  2.159418  2.536725  2.620131
+1.456320  1.693132  1.969234  2.164744  2.587162  2.677588
+1.481106  1.637541  1.992642  2.178479  2.548138  2.632755
+1.488517  1.591174  2.016501  2.123324  2.528663  2.614918
+1.477429  1.651519  1.962894  2.102183  2.543300  2.618840
+1.473856  1.622302  1.992230  2.080352  2.572688  2.644430
+1.478216  1.633404  1.931202  2.064133  2.552282  2.629338
+1.452477  1.676763  1.945911  2.084750  2.600973  2.668889
+1.411560  1.706182  1.890249  2.169616  2.567319  2.650155
+1.383398  1.664625  1.803260  2.108612  2.595771  2.646221
+1.434597  1.645007  1.871751  2.115488  2.528958  2.660256
+1.444542  1.581834  1.898636  2.094074  2.528453  2.631504
+1.465558  1.562000  1.841423  2.051601  2.559944  2.632318
+1.499287  1.581053  1.857454  2.098994  2.511597  2.604341
+1.528680  1.651347  1.871308  2.071232  2.562548  2.622460
+1.514467  1.633477  1.778604  2.123502  2.606102  2.662390
+1.301476  1.683914  1.796063  2.170750  2.644952  2.691777
+1.154424  1.626935  1.749221  1.996410  2.579238  2.652899
+1.117912  1.569269  1.795380  1.885300  2.376717  2.739725
+1.251786  1.625672  1.839263  1.991314  2.350120  2.655047
+1.412131  1.694235  1.839362  1.998399  2.445222  2.739684
+1.370157  1.687258  1.879731  2.006454  2.329014  2.632962
+1.174780  1.729049  1.887372  2.013905  2.259388  2.557737
+1.317917  1.737041  1.878083  1.979313  2.175363  2.634863
+1.140130  1.586450  1.932219  2.027711  2.236840  2.484950
+1.100136  1.600099  1.851286  1.972375  2.604826  2.649449
+1.111969  1.525982  1.842706  2.011491  2.601600  2.669393
+1.080825  1.492576  1.810233  1.965312  2.556725  2.645171
+1.129345  1.635898  1.785176  2.137400  2.498003  2.572522
+1.003594  1.603010  1.722697  2.139397  2.431587  2.510996
+1.120169  1.425151  1.675683  2.050774  2.343247  2.460676
+1.328607  1.599151  1.873581  2.170450  2.470538  2.613529
+1.382087  1.595341  1.923462  2.082111  2.349552  2.510754
+1.466192  1.572864  1.870467  2.179996  2.346338  2.471868
+1.379765  1.633014  1.808273  2.166294  2.398723  2.492469
+1.305921  1.610021  1.856406  2.001543  2.390671  2.533908
+1.383086  1.586806  1.757224  1.934804  2.433540  2.587951
+1.307509  1.450943  1.675332  2.033940  2.244229  2.418123
+1.191501  1.484072  1.750272  2.096644  2.249380  2.504983
+1.241378  1.491790  1.776884  2.071735  2.367933  2.508071
+1.265701  1.459923  1.781754  2.009900  2.348578  2.516037
+1.279508  1.414652  1.795096  2.055938  2.395700  2.530542
+1.337338  1.445932  1.853009  2.075183  2.385984  2.535489
+1.288973  1.424709  1.797989  2.026295  2.299802  2.423713
+1.365284  1.471788  1.801705  1.937695  2.345304  2.466696
+1.353791  1.447746  1.736211  1.868886  2.274358  2.475584
+1.360863  1.449607  1.680466  1.802646  2.395536  2.513256
+1.388330  1.526246  1.673331  1.909867  2.385020  2.535430
+1.424428  1.544219  1.720205  1.936245  2.307968  2.491418
+1.448943  1.552009  1.797935  1.937520  2.406873  2.546121
+1.432034  1.521621  1.799322  2.021435  2.477329  2.571754
+1.463087  1.546282  1.834418  2.063488  2.489800  2.595267
+1.425467  1.556435  1.904716  2.110821  2.466374  2.587563
+1.384837  1.569415  1.925581  2.072374  2.561291  2.640537
+1.418492  1.539421  1.937535  2.014318  2.609201  2.676764
+1.397006  1.483285  1.936731  1.977746  2.595606  2.735850
+1.335615  1.441868  1.884738  1.994960  2.589628  2.695748
+1.357490  1.518997  1.871603  1.980199  2.629016  2.700305
+1.353558  1.524318  1.891083  1.963707  2.595814  2.679332
+1.295102  1.639282  1.907387  2.103139  2.583356  2.679778
+1.455545  1.667590  1.953202  2.240488  2.570672  2.673617
+1.460281  1.786653  1.997747  2.285131  2.582928  2.677618
+1.543121  1.729391  2.155674  2.280274  2.655577  2.744248
+1.434440  1.748782  2.042199  2.201295  2.606501  2.695862
+1.436079  1.747337  2.067838  2.253257  2.575944  2.679075
+1.470866  1.698245  2.083133  2.257574  2.565342  2.666191
+1.417419  1.693439  2.053193  2.243538  2.544836  2.632800
+1.412107  1.681588  2.081799  2.326098  2.472446  2.570581
+1.397226  1.764739  2.031556  2.297123  2.471645  2.575881
+1.466497  1.694305  2.005924  2.206325  2.534515  2.635757
+1.437113  1.746568  1.923838  2.127846  2.356631  2.464479
+1.324023  1.597918  1.757776  2.124352  2.347986  2.440470
+1.375387  1.626387  1.778068  2.068399  2.258938  2.397532
+1.379576  1.621789  1.857961  1.994277  2.306086  2.477213
+1.416412  1.648893  1.869117  2.098359  2.345397  2.475125
+1.426241  1.639197  1.925396  2.072677  2.448945  2.532546
+1.459052  1.615870  1.911170  2.125459  2.483704  2.592087
+1.459433  1.690704  1.852418  2.136068  2.529395  2.597199
+1.485144  1.578047  1.810569  2.150621  2.559043  2.618237
+1.529055  1.594664  1.738903  2.261216  2.595771  2.651620
+1.532488  1.585333  1.820935  2.229621  2.623157  2.658477
+1.374401  1.528078  1.848019  2.042459  2.458230  2.591088
+1.399870  1.597467  1.853082  2.096076  2.431604  2.556847
+1.457434  1.609510  1.930756  2.186100  2.392287  2.525064
+1.440508  1.607587  1.869980  2.158283  2.424280  2.555526
+1.376758  1.474791  1.750562  2.190623  2.406180  2.547123
+1.327713  1.454236  1.644635  2.110356  2.352447  2.455926
+1.302805  1.418954  1.609785  2.093121  2.263489  2.393252
+1.207712  1.379869  1.536412  2.059932  2.317302  2.455399
+1.154213  1.302966  1.499207  2.070378  2.322203  2.630828
+1.111474  1.224424  1.625635  2.176079  2.342546  2.606190
+0.945723  1.083298  1.625408  2.214532  2.389898  2.510077
+0.992344  1.116986  1.451917  2.008420  2.313589  2.437855
+1.117309  1.392988  1.713458  2.132315  2.276818  2.497613
+1.332868  1.580932  1.895512  2.129003  2.425104  2.576946
+1.322037  1.497740  1.819219  2.128645  2.443614  2.567952
+1.361937  1.547377  1.790968  2.062941  2.465318  2.546093
+1.252677  1.483878  1.758631  2.033450  2.416283  2.539220
+1.099384  1.344747  1.686531  2.016752  2.355863  2.530839
+1.126109  1.263617  1.649938  1.991544  2.309088  2.514895
+1.190621  1.289655  1.692709  2.009481  2.160091  2.417069
+1.174976  1.414314  1.797856  1.987597  2.278818  2.492762
+1.205354  1.482053  1.850760  2.025549  2.342281  2.523425
+1.248034  1.561185  1.852759  2.096445  2.428364  2.551865
+1.260728  1.601832  1.901052  2.131984  2.409850  2.565546
+1.265037  1.693841  2.000531  2.200039  2.503508  2.617708
+1.278843  1.738264  2.062020  2.289983  2.604440  2.678111
+1.339428  1.735918  2.050123  2.352408  2.597394  2.688219
+1.301064  1.708745  1.965976  2.286214  2.546707  2.653175
+1.278604  1.746157  1.950065  2.214767  2.605793  2.687616
+1.183771  1.523062  1.879119  2.004908  2.600314  2.690485
+1.186222  1.342133  1.817831  1.940077  2.504905  2.659254
+1.179389  1.243680  1.894260  1.979753  2.558019  2.721819
+1.175622  1.357037  1.853192  1.940810  2.646805  2.705660
+1.211124  1.369645  1.825254  1.913289  2.634717  2.712259
+1.169472  1.345149  1.764944  1.883669  2.591077  2.714522
+1.222090  1.389480  1.800177  1.935903  2.573766  2.702922
+1.287266  1.375911  1.878738  1.986045  2.625999  2.708468
+1.299711  1.389598  1.873905  1.942723  2.533485  2.691472
+1.271356  1.424203  1.849847  1.953565  2.555561  2.652372
+1.253571  1.448512  1.829531  1.919100  2.487837  2.630761
+1.223923  1.323017  1.841258  1.932730  2.226845  2.570717
+1.226170  1.321389  1.771794  1.948065  2.137880  2.563052
+1.316238  1.399466  1.789328  1.965570  2.132039  2.424710
+1.264391  1.363953  1.735531  2.005600  2.155844  2.418921
+1.214027  1.319779  1.662017  1.902948  2.064631  2.424833
+1.242602  1.342314  1.624757  1.929420  2.083549  2.318443
+1.241605  1.439119  1.646334  1.817919  1.997763  2.196632
+1.239348  1.336917  1.777062  2.028009  2.155853  2.328702
+1.178416  1.266326  1.802039  1.959820  2.145703  2.469513
+1.247702  1.328626  1.812686  1.992792  2.200638  2.499445
+1.270078  1.370907  1.882273  1.997225  2.254284  2.526050
+1.295553  1.376421  1.860437  2.076734  2.248998  2.567118
+1.304838  1.386085  1.832762  2.061619  2.219399  2.486348
+1.314313  1.381482  1.912831  2.017535  2.287746  2.576424
+1.275078  1.353772  1.858468  2.037031  2.362055  2.615420
+1.287115  1.366797  1.835524  1.961094  2.291985  2.562975
+1.256666  1.341161  1.798806  1.921264  2.333647  2.596913
+1.229284  1.337507  1.753982  1.942388  2.403549  2.602171
+1.224871  1.322981  1.792609  1.918908  2.363314  2.520583
+1.218452  1.321589  1.651493  1.884157  2.366537  2.521284
+1.193218  1.359120  1.632401  1.857625  2.322851  2.452708
+1.205474  1.368035  1.608030  1.815042  2.341851  2.574505
+1.061251  1.318432  1.545024  1.888740  2.401884  2.617020
+1.072522  1.365786  1.514127  1.893675  2.369617  2.474232
+1.111644  1.436790  1.606098  1.842456  2.382418  2.474111
+1.012061  1.316202  1.471593  1.799057  2.349432  2.455130
+1.089471  1.248571  1.572785  1.953061  2.298439  2.461784
+1.068360  1.195813  1.624024  2.111295  2.311476  2.419253
+1.147513  1.525224  1.724810  1.957167  2.387532  2.471314
+1.334336  1.568150  1.749039  1.962569  2.390633  2.484647
+1.298140  1.467881  1.814397  1.941570  2.384226  2.522176
+1.295007  1.418486  1.859466  1.962329  2.376315  2.521757
+1.335831  1.436636  1.858260  1.966332  2.446579  2.563483
+1.346492  1.477982  1.905644  1.998091  2.490052  2.584468
+1.407183  1.540763  1.879296  1.992980  2.487939  2.564009
+1.447665  1.628575  1.828196  2.053651  2.534046  2.605859
+1.524705  1.620051  1.837880  2.017915  2.592167  2.653373
+1.564584  1.647141  1.761178  2.024150  2.615248  2.656575
+1.529370  1.593981  1.683157  1.979831  2.601640  2.654391
+1.585075  1.652835  1.786770  2.031845  2.518000  2.620980
+1.588906  1.644232  1.813812  2.041481  2.610723  2.666049
+1.601362  1.686074  1.862952  2.127114  2.608859  2.655021
+1.640245  1.750920  1.921102  2.164412  2.547516  2.617193
+1.548602  1.638196  1.917398  2.092646  2.563829  2.615836
+1.515875  1.616955  1.844164  2.007026  2.528173  2.601071
+1.465872  1.572195  1.740969  2.011290  2.493415  2.581928
+1.411908  1.534275  1.669392  2.025507  2.419065  2.534991
+1.339405  1.524896  1.674545  2.018990  2.344004  2.443795
+1.300672  1.527060  1.673067  2.036189  2.269516  2.383792
+1.193083  1.476495  1.664464  1.933230  2.291004  2.414954
+1.192791  1.485591  1.649261  1.844048  2.295088  2.502001
+1.197824  1.364864  1.703691  1.827209  2.262766  2.499801
+1.138273  1.379249  1.658127  1.912486  2.389082  2.583381
+1.166597  1.357942  1.688915  1.942734  2.491527  2.589252
+1.170615  1.391547  1.721925  1.889510  2.506116  2.616390
+1.210959  1.452702  1.755617  1.844973  2.490062  2.624729
+1.212139  1.519716  1.785919  1.889270  2.551264  2.629492
+1.276001  1.664615  1.957757  2.249343  2.602286  2.677701
+1.400862  1.816183  1.994456  2.325956  2.651785  2.717305
+1.466054  1.834563  2.118572  2.372427  2.625377  2.704685
+1.578859  1.790938  2.136097  2.392831  2.638547  2.714022
+1.480700  1.816555  2.206450  2.432389  2.575887  2.645111
+1.617288  1.807665  2.241721  2.440067  2.567226  2.631745
+1.570100  1.785068  2.178210  2.348135  2.467045  2.556638
+1.579682  1.701535  2.005186  2.288766  2.434155  2.548589
+1.578691  1.674213  1.965474  2.199446  2.334867  2.479803
+1.640546  1.726915  1.991606  2.240338  2.400971  2.523628
+1.588532  1.709671  1.874418  2.160822  2.381523  2.517230
+1.447497  1.665484  1.900942  2.103382  2.397872  2.535571
+1.203022  1.599213  1.884283  2.032257  2.369015  2.504738
+1.146521  1.513193  1.880497  1.985787  2.407380  2.522482
+1.131266  1.435001  1.834092  2.111348  2.306550  2.531154
+1.176712  1.640343  1.870115  2.064938  2.313000  2.439124
+1.254490  1.590614  1.958487  2.200173  2.344272  2.479816
+1.243959  1.684492  2.016502  2.192945  2.451075  2.547334
+1.537310  1.763854  2.188639  2.371726  2.539927  2.648079
+1.646538  1.887574  2.280949  2.443446  2.593067  2.680775
+1.567456  1.876170  2.108713  2.427826  2.611726  2.691363
+1.341056  1.874127  2.114216  2.396197  2.621228  2.702770
+1.449196  1.837843  2.058401  2.307470  2.616907  2.689695
+1.313491  1.794349  1.961057  2.237499  2.597739  2.685191
+1.202175  1.706913  1.905104  2.139148  2.612890  2.693658
+1.080344  1.590487  1.846519  2.059279  2.631365  2.697376
+1.043219  1.601906  1.900346  2.141041  2.588352  2.662523
+0.984957  1.556146  1.841481  2.148769  2.577337  2.662952
+0.979403  1.553838  1.844172  2.052598  2.577754  2.641114
+0.947313  1.453890  1.836463  1.998780  2.566547  2.637546
+0.959460  1.441678  1.832870  2.106499  2.553643  2.630882
+0.951016  1.397882  1.793743  2.053066  2.492635  2.622573
+0.870727  1.369217  1.817794  2.107476  2.524230  2.627945
+0.902872  1.385159  1.754800  2.013432  2.536990  2.654823
+0.891101  1.362395  1.753579  1.878041  2.559805  2.662468
+0.835616  1.259326  1.757169  1.832338  2.486345  2.635682
+0.787419  1.132035  1.693975  1.776933  2.533180  2.616312
+0.791106  1.068132  1.697743  1.851598  2.571958  2.669553
+0.759951  1.112356  1.562357  1.855199  2.490682  2.601972
+0.792061  1.139999  1.724823  1.954458  2.608864  2.689684
+0.823952  1.270934  1.741090  2.077662  2.613199  2.669386
+0.736534  1.124969  1.743684  2.093250  2.579787  2.661721
+0.797043  1.051944  1.780229  2.240357  2.583476  2.662315
+0.923582  1.503155  1.776882  2.018470  2.613910  2.703042
+1.421538  1.735030  2.006889  2.210344  2.574319  2.670736
+1.350174  1.606122  1.963013  2.084969  2.478192  2.589945
+1.361799  1.656583  1.974082  2.173881  2.479634  2.612008
+1.319939  1.764454  2.027445  2.249293  2.529644  2.635744
+1.394028  1.664199  2.006309  2.246188  2.558094  2.671320
+1.385394  1.755426  2.080024  2.329874  2.630895  2.722673
+1.333690  1.669430  2.021492  2.250607  2.600265  2.689100
+1.341532  1.698164  1.975002  2.237112  2.560850  2.684376
+1.388610  1.785046  1.956888  2.281386  2.563576  2.643708
+1.345894  1.706236  1.842983  2.264164  2.606222  2.694785
+1.320329  1.694191  1.923363  2.218151  2.645478  2.750259
+1.332386  1.748388  2.014721  2.221780  2.602628  2.697461
+1.397603  1.715354  1.949721  2.236000  2.577802  2.661479
+1.618810  1.795968  2.016419  2.205191  2.506636  2.636829
+1.659811  1.735333  2.021086  2.175840  2.443378  2.641454
+1.539528  1.652064  1.946773  2.095081  2.446637  2.636547
+1.532272  1.592873  1.977822  2.053408  2.551491  2.674907
+1.509350  1.581109  2.004243  2.059379  2.524603  2.702937
+1.432533  1.504626  1.930707  2.042330  2.440661  2.690850
+1.194640  1.677037  2.023104  2.078391  2.446911  2.745852
+1.210373  1.824825  2.021515  2.139089  2.539931  2.659640
+1.276624  1.715436  1.952490  2.083815  2.473462  2.664346
+1.235656  1.548445  2.067341  2.118624  2.427438  2.727540
+1.283474  1.374296  1.963417  2.098418  2.474393  2.702856
+1.305021  1.394700  2.068003  2.139040  2.520168  2.706208
+1.284823  1.494312  2.055208  2.140334  2.602120  2.698828
+1.296593  1.587724  2.087205  2.156563  2.618559  2.718633
+1.252465  1.583350  2.108883  2.173872  2.600502  2.685035
+1.177439  1.612038  2.093884  2.155173  2.581066  2.695123
+1.132957  1.572991  2.135458  2.220598  2.615734  2.710569
+1.060318  1.542980  2.165747  2.230410  2.609442  2.697786
+0.993306  1.542205  2.170751  2.247209  2.631170  2.706892
+0.783750  1.568542  2.323323  2.398878  2.594196  2.690603
+0.866024  1.454427  2.113290  2.187039  2.662007  2.719943
+0.793002  1.437700  2.125666  2.225555  2.588880  2.664786
+0.863183  1.439828  2.031948  2.203948  2.586483  2.646886
+0.817301  1.443077  2.078742  2.356665  2.572146  2.635324
+0.840200  1.268198  1.973956  2.380693  2.546743  2.624124
+0.905910  1.472855  2.000805  2.420178  2.606009  2.662539
+0.885218  1.599132  2.063964  2.335379  2.688751  2.736255
+0.812099  1.480973  2.103159  2.193629  2.621360  2.702113
+0.727009  1.481278  2.088167  2.170556  2.575583  2.660557
+0.783755  1.482083  2.210773  2.281994  2.564635  2.658081
+0.810890  1.318001  2.156661  2.250146  2.565371  2.666169
+0.775372  1.352710  2.277457  2.371730  2.587244  2.655489
+0.765239  1.280609  2.227449  2.304899  2.577531  2.696870
+0.860727  1.309962  2.239215  2.358255  2.523746  2.681832
+0.828001  1.157509  2.157199  2.279201  2.554510  2.655379
+0.776568  1.131001  2.110470  2.282369  2.502240  2.634533
+0.662804  1.210648  2.214487  2.275268  2.480153  2.598167
+0.752595  1.172127  2.270252  2.354795  2.534373  2.613431
+0.769014  1.037539  2.239849  2.320190  2.523883  2.637275
+0.747299  1.036519  2.059875  2.380316  2.507719  2.677768
+0.818428  1.110448  2.132574  2.306792  2.442669  2.597844
+0.838124  1.256032  2.152521  2.304078  2.501081  2.591854
+0.842740  1.147341  2.045086  2.317073  2.459293  2.588472
+0.950977  1.150930  2.097644  2.290004  2.497415  2.643449
+0.932262  1.159756  1.945175  2.233748  2.538888  2.635754
+0.872640  1.294667  1.881084  2.112185  2.488729  2.612697
+0.953242  1.398337  1.906758  2.024454  2.396667  2.616332
+1.019160  1.447236  1.917323  2.023333  2.213019  2.528896
+0.980910  1.420444  1.857618  1.943436  2.294481  2.596120
+1.007917  1.474723  1.827586  1.921475  2.567362  2.643752
+1.057674  1.583820  1.862216  1.988312  2.507590  2.602780
+1.089480  1.610937  1.894205  2.067983  2.401427  2.589250
+1.155642  1.601524  1.853784  2.109924  2.266420  2.654880
+1.190394  1.403206  1.850320  2.129434  2.355479  2.599651
+1.165667  1.266234  1.847925  2.191760  2.352164  2.576809
+1.112543  1.237226  1.755553  2.196412  2.378413  2.515897
+1.093202  1.229320  1.630970  2.198491  2.394327  2.490062
+1.030916  1.160090  1.536996  2.150269  2.345755  2.526171
+1.090134  1.227459  1.470303  2.121663  2.325691  2.414263
+1.084185  1.353427  1.495774  2.165409  2.396637  2.501534
+1.128688  1.380138  1.551457  2.110309  2.296856  2.418999
+1.087172  1.454259  1.658795  2.020385  2.196298  2.381465
+1.039395  1.582193  1.728098  2.070179  2.301852  2.489432
+1.019025  1.646872  1.828918  2.125767  2.542468  2.624929
+1.017909  1.675444  2.009386  2.200627  2.432273  2.532754
+0.975365  1.568456  2.099629  2.243759  2.469669  2.558656
+1.045139  1.750545  2.091194  2.277034  2.473998  2.559636
+1.003490  1.670000  2.149872  2.216814  2.544142  2.591015
+0.972271  1.669349  2.066914  2.253461  2.528115  2.626794
+1.001400  1.910537  2.208899  2.322095  2.475052  2.594146
+1.106236  1.762398  2.170214  2.368326  2.532382  2.636954
+0.937567  1.570796  2.208314  2.312080  2.547601  2.604149
+0.984015  1.531648  2.154446  2.260403  2.519554  2.621365
+1.058045  1.589683  2.130473  2.238788  2.559220  2.636001
+1.126293  1.674296  2.142380  2.304378  2.581987  2.659797
+1.092169  1.547245  2.138847  2.246962  2.570924  2.653740
+1.164152  1.513575  2.120596  2.203037  2.555931  2.629117
+1.154436  1.451664  2.109876  2.193787  2.569383  2.668688
+1.171007  1.297549  2.105789  2.224294  2.529719  2.663245
+1.139370  1.343339  2.024942  2.161273  2.570054  2.662064
+1.214975  1.759488  2.013624  2.126711  2.350657  2.508933
+1.410441  1.787361  1.940449  2.082004  2.255781  2.406359
+1.192527  1.698280  1.956892  2.084836  2.235743  2.490643
+1.173627  1.448751  2.011122  2.145246  2.280142  2.534706
+1.172797  1.327177  1.938868  2.095910  2.247560  2.526844
+1.129709  1.376142  1.891533  1.985327  2.196351  2.582653
+1.195218  1.292910  1.887213  2.025135  2.200698  2.525594
+1.246281  1.338967  1.851654  2.072793  2.209074  2.457441
+1.244715  1.395538  1.916844  2.097048  2.296495  2.526646
+1.346432  1.453272  2.128410  2.313839  2.566271  2.666215
+1.392181  1.506569  2.060420  2.183828  2.523643  2.656421
+1.397671  1.478362  2.037869  2.140024  2.522879  2.634883
+1.405078  1.437969  2.064698  2.121678  2.484341  2.664086
+1.527970  1.731644  2.001400  2.182281  2.477459  2.609679
+1.602215  1.694049  2.065008  2.176143  2.567575  2.650751
+1.549243  1.668152  2.061940  2.136053  2.575954  2.678540
+1.590489  1.693208  1.921586  2.193585  2.522338  2.657822
+1.593120  1.715596  2.057856  2.172814  2.502009  2.607762
+1.508461  1.713948  2.053457  2.146855  2.383043  2.628673
+1.500942  1.577870  1.978516  2.080955  2.517866  2.640817
+1.503819  1.559203  1.933282  2.030596  2.516193  2.657495
+1.430951  1.506436  1.856364  2.014512  2.406913  2.583800
+1.394417  1.471155  1.914772  2.015327  2.414514  2.568928
+1.376718  1.476739  1.841743  1.961573  2.459621  2.552505
+1.304829  1.509257  1.807862  1.899025  2.532604  2.616563
+1.486241  1.646868  1.928992  2.176641  2.503384  2.645535
+1.477068  1.576408  1.937301  2.094449  2.468734  2.643633
+1.431493  1.551268  1.935807  2.027994  2.468760  2.605588
+1.427171  1.670820  1.944981  2.109944  2.482745  2.652433
+1.393190  1.649564  1.991075  2.070334  2.586450  2.667337
+1.406966  1.518528  1.967049  2.067755  2.501722  2.624107
+1.399129  1.487381  1.880327  1.972568  2.359193  2.604810
+1.419452  1.541906  1.920889  2.015257  2.416437  2.547537
+1.447736  1.626647  1.911603  2.037838  2.508304  2.609091
+1.507943  1.649223  1.954490  2.063843  2.515779  2.591471
+1.512511  1.697882  1.919266  2.077175  2.545774  2.631085
+1.577487  1.652922  1.969378  2.057105  2.533497  2.610477
+1.604710  1.687839  1.943635  2.030700  2.552461  2.659467
+1.634825  1.710086  1.943508  2.035741  2.553037  2.650522
+1.629110  1.721048  1.907265  2.020140  2.570097  2.652611
+1.653862  1.731013  1.917069  2.016503  2.551305  2.678978
+1.675623  1.740253  1.923108  1.995468  2.543890  2.693466
+1.704324  1.761003  1.892088  1.958603  2.520344  2.709583
+1.631746  1.698022  1.879765  1.974816  2.475043  2.688708
+1.563394  1.662351  1.863499  1.961656  2.492069  2.692141
+1.535271  1.621802  1.864516  2.016880  2.457202  2.701452
+1.463627  1.689995  1.942593  2.019493  2.516076  2.684085
+1.427161  1.545730  1.922601  1.983390  2.549083  2.724037
+1.387863  1.469421  1.874287  2.047091  2.486568  2.643007
+1.364743  1.462745  1.908513  2.076519  2.468769  2.627416
+1.421611  1.616670  2.074387  2.243630  2.604811  2.697119
+1.443567  1.802480  2.145890  2.311026  2.615127  2.704969
+1.402806  1.864810  2.209376  2.377972  2.654288  2.731440
+1.472673  1.860803  2.162882  2.447267  2.648421  2.719024
+1.518497  1.794725  2.075011  2.339205  2.552102  2.655931
+1.503597  1.758472  2.111549  2.304480  2.551002  2.643546
+1.466759  1.587712  2.046144  2.276602  2.546510  2.649906
+1.414608  1.499164  2.000686  2.080851  2.549084  2.654414
+1.324617  1.597419  1.961703  2.075259  2.518788  2.638260
+1.262448  1.666067  1.961546  2.098269  2.549101  2.630367
+1.220869  1.632115  1.947651  2.054954  2.515971  2.607563
+1.136650  1.569138  1.923253  2.011403  2.513979  2.612924
+1.058570  1.570577  1.921267  2.037973  2.484487  2.569497
+1.039823  1.492368  1.862383  2.113321  2.462634  2.586287
+1.291651  1.546687  1.888427  2.160338  2.444567  2.573682
+1.154151  1.629832  1.978719  2.114524  2.505413  2.616168
+1.018988  1.844229  2.003497  2.145640  2.430051  2.549664
+1.003639  1.900247  2.103968  2.200810  2.555267  2.678873
+1.007182  1.652528  2.033376  2.117896  2.534356  2.593837
+1.014065  1.625311  2.073565  2.163998  2.546138  2.611829
+1.009846  1.729007  2.001610  2.190071  2.554550  2.635426
+1.019489  1.599817  2.062920  2.180981  2.585351  2.651906
+1.042282  1.559849  2.061719  2.184907  2.608829  2.711272
+1.093985  1.606698  2.067049  2.179456  2.578115  2.647082
+1.117524  1.554503  2.010457  2.171257  2.524192  2.604614
+1.189148  1.687116  2.026818  2.220744  2.584656  2.673603
+1.184285  1.592927  2.011407  2.140558  2.575633  2.652764
+1.243271  1.544342  1.991354  2.103724  2.547726  2.633837
+1.249802  1.530059  1.930460  2.044509  2.489498  2.611045
+1.317227  1.550858  1.927474  2.019107  2.563575  2.632413
+1.300146  1.571198  1.817213  1.967321  2.572012  2.659755
+1.304786  1.459074  1.804350  1.873800  2.572345  2.677847
+1.272113  1.387927  1.710588  1.798443  2.519124  2.630967
+1.168824  1.271438  1.680467  1.847635  2.472587  2.636108
+1.127715  1.380423  1.702693  1.948341  2.254799  2.516590
+1.037344  1.362071  1.698870  1.943363  2.319984  2.576108
+0.912701  1.215239  1.774758  2.057933  2.407301  2.609739
+0.884045  1.283341  1.740086  2.012038  2.332329  2.530152
+0.859928  1.361393  1.787767  2.032428  2.439162  2.572497
+0.933575  1.497313  1.860114  2.007764  2.460777  2.636583
+0.980843  1.376674  1.808267  1.899302  2.551384  2.660680
+0.888314  1.390836  1.819063  1.938604  2.611726  2.713704
+0.839112  1.455052  1.864246  1.932569  2.561260  2.649480
+0.851738  1.633441  1.854938  2.065105  2.591532  2.637966
+0.927993  1.739190  1.882023  2.133201  2.585017  2.640778
+0.938681  1.795656  1.962111  2.138930  2.565233  2.627897
+0.939389  1.842127  2.021817  2.196345  2.611519  2.658322
+0.876668  1.922758  2.066598  2.238607  2.657831  2.709139
+0.928890  1.831807  2.053719  2.203623  2.653635  2.695408
+0.843177  1.785949  2.180039  2.258075  2.596807  2.669868
+0.904710  1.738574  2.045482  2.171335  2.659082  2.701770
+0.870576  1.672854  2.046684  2.160295  2.663395  2.706284
+0.863208  1.611276  2.039577  2.131986  2.662744  2.710206
+0.911587  1.521477  1.972249  2.117701  2.671514  2.736290
+0.857624  1.506231  1.927459  2.092066  2.599004  2.671353
+0.876724  1.386211  1.930102  2.020125  2.640246  2.715714
+0.822485  1.363083  1.951099  2.012089  2.546285  2.704224
+0.896312  1.299233  1.946153  2.039999  2.427568  2.660429
+0.993275  1.379765  2.001120  2.083441  2.476481  2.621083
+1.111974  1.369262  1.980570  2.050077  2.518420  2.654724
+1.168214  1.421156  1.929649  2.013732  2.513895  2.659462
+1.185532  1.477308  1.941700  2.021792  2.545835  2.636829
+1.134677  1.498395  1.996860  2.077054  2.487095  2.605961
+1.411729  1.500808  1.930565  2.251695  2.391409  2.514752
+1.387101  1.551631  1.939267  2.134432  2.390647  2.538102
+1.436468  1.601632  1.856306  2.001721  2.498428  2.579682
+1.490762  1.673865  1.865367  2.015258  2.490944  2.589599
+1.532290  1.665821  1.854110  1.987787  2.544314  2.634547
+1.563136  1.683249  1.819205  1.981344  2.592402  2.655991
+1.532691  1.642869  1.795089  1.955952  2.595574  2.688667
+1.506939  1.596868  1.724719  1.902522  2.497152  2.646767
+1.385229  1.553302  1.733776  1.993489  2.385677  2.620193
+1.191373  1.508094  1.914117  2.177183  2.460347  2.600638
+0.990202  1.268417  1.760300  1.988487  2.516663  2.661016
+1.004888  1.273030  1.919583  1.976961  2.621532  2.711155
+1.013289  1.479166  1.983769  2.021110  2.561293  2.681392
+1.094384  1.424205  1.985002  2.164791  2.592137  2.670975
+1.057765  1.377512  1.866113  2.165416  2.490671  2.623341
+1.001768  1.321304  1.902289  2.133880  2.499889  2.659347
+0.896048  1.414778  1.927546  2.127605  2.570653  2.658502
+0.862503  1.586972  1.946548  2.153624  2.615123  2.677873
+0.837783  1.700010  1.932982  2.209447  2.588567  2.687532
+0.901209  1.639772  1.999974  2.070577  2.515297  2.763152
+0.955829  1.601245  2.008965  2.112233  2.503888  2.592844
+0.939285  1.704094  2.027412  2.125922  2.430007  2.538916
+0.948268  1.700873  2.002768  2.088348  2.563468  2.622110
+0.959154  1.624274  2.005824  2.077760  2.577716  2.658733
+0.932538  1.593435  1.952831  2.044660  2.567978  2.644497
+0.933107  1.590563  1.945695  2.111900  2.534278  2.608873
+0.943808  1.649088  1.897019  2.104647  2.578170  2.689758
+1.003034  1.619161  1.930228  2.216721  2.582337  2.637890
+0.936810  1.692346  1.965525  2.118648  2.628517  2.684797
+0.973578  1.737821  1.975673  2.106344  2.658295  2.722445
+0.955324  1.750194  1.961437  2.075373  2.655612  2.731757
+0.994013  1.727390  1.946779  2.062413  2.643379  2.738490
+1.005363  1.693919  1.929868  2.100177  2.618754  2.684861
+0.967862  1.640078  1.930261  2.021548  2.639890  2.726662
+0.928258  1.579359  1.864413  1.973012  2.638908  2.717888
+1.058334  1.410591  1.870850  2.066023  2.451575  2.633697
+1.123046  1.486876  1.862969  2.086078  2.412975  2.591738
+1.177472  1.431539  1.849290  2.099756  2.423335  2.566135
+1.187028  1.443506  1.882075  1.983318  2.550673  2.639389
+1.267969  1.628389  1.932608  2.043278  2.552232  2.641727
+1.355546  1.701559  1.924241  2.034556  2.590180  2.660965
+1.472056  1.739983  1.914264  2.052330  2.573889  2.644926
+1.461490  1.790656  1.911310  2.057871  2.525599  2.587235
+1.542347  1.742399  1.901654  2.063063  2.499169  2.580661
+1.550813  1.642896  1.877392  1.995154  2.474361  2.561166
+1.625354  1.724756  1.899115  2.052586  2.447095  2.556852
+1.636703  1.742201  1.904488  2.155317  2.470314  2.569291
+1.608688  1.701026  1.957110  2.085583  2.465316  2.552203
+1.517569  1.685169  1.923050  2.028968  2.382899  2.503932
+1.215848  1.648126  1.842885  2.049966  2.393827  2.484346
+1.158500  1.452995  1.752665  1.859020  2.467269  2.575520
+1.128274  1.384146  1.801504  1.899178  2.472451  2.609988
+1.080623  1.414338  1.812493  1.916642  2.422686  2.620118
+1.104866  1.492913  1.854038  1.971940  2.444002  2.583583
+1.235805  1.437823  1.919484  2.042792  2.483999  2.617147
+1.167412  1.407601  1.774394  2.073573  2.390599  2.543323
+1.096565  1.317231  1.782210  2.013544  2.394372  2.571806
+1.104307  1.206800  1.718582  2.001006  2.351339  2.505639
+1.047321  1.316889  1.824322  2.050773  2.417158  2.531028
+1.087184  1.408401  1.843144  2.031666  2.440481  2.544264
+1.108521  1.394200  1.760026  2.005728  2.435035  2.552154
+1.121767  1.340590  1.749504  1.963633  2.493819  2.609645
+1.122415  1.452714  1.793131  2.030414  2.502133  2.593239
+1.026877  1.468099  1.745342  1.860466  2.483684  2.579747
+0.971670  1.244091  1.752977  1.837331  2.384716  2.625316
+0.917302  1.104410  1.674928  1.792426  2.336189  2.629469
+0.961560  1.088356  1.555776  1.663706  2.282322  2.579748
+0.919563  1.063279  1.573205  1.711100  2.422693  2.675976
+0.875889  1.022614  1.380839  1.829163  2.584656  2.667378
+0.763749  1.018806  1.506319  1.707976  2.471526  2.595865
+0.886944  1.031388  1.425057  1.710023  2.427922  2.576385
+0.890351  1.037652  1.443986  1.587883  2.520205  2.695833
+0.906256  1.035046  1.405613  1.523743  2.536532  2.596081
+0.929418  1.061071  1.157090  1.566597  2.528260  2.694068
+0.917396  1.106117  1.253042  1.389506  2.551566  2.709098
+0.910230  1.042070  1.162527  1.362129  2.393076  2.605349
+0.804288  1.059586  1.418081  1.530362  2.410566  2.663442
+0.907675  1.046288  1.392541  1.508232  2.495351  2.692340
+0.835212  1.126874  1.350498  1.463210  2.567735  2.694674
+0.770295  1.150701  1.428259  1.601173  2.610228  2.683669
+0.924536  1.075405  1.468526  1.669865  2.543683  2.693196
+0.972382  1.191757  1.544758  1.638670  2.535321  2.642972
+0.903877  1.101926  1.510782  1.602659  2.487038  2.638272
+0.881279  1.096901  1.554249  1.644297  2.424659  2.557575
+0.866115  1.118877  1.603042  1.702467  2.543898  2.649301
+0.906645  1.160248  1.672021  1.747258  2.517909  2.650863
+0.861085  1.205864  1.660991  1.847091  2.462741  2.632034
+0.837175  1.187776  1.806042  1.889495  2.508608  2.684557
+0.797709  1.178516  1.903177  2.021653  2.546180  2.690072
+0.802875  1.262753  1.923936  2.000576  2.568440  2.670106
+0.766638  1.320827  1.961021  2.058945  2.582312  2.646725
+0.811579  1.455194  2.011480  2.084784  2.548418  2.639933
+0.829770  1.484961  2.052714  2.127227  2.530640  2.608181
+0.799011  1.567454  2.155632  2.265108  2.573173  2.668504
+0.730379  1.358614  2.125791  2.194588  2.518703  2.605426
+0.720667  1.277836  2.042808  2.111923  2.592800  2.675300
+0.777663  1.163703  2.066790  2.179199  2.570004  2.675513
+0.839969  1.373176  2.185884  2.304679  2.509358  2.602576
+0.815752  1.915221  2.233635  2.288481  2.569983  2.628428
+1.191882  1.945689  2.175132  2.299053  2.523524  2.632041
+1.036281  1.742208  2.072713  2.141555  2.573194  2.641551
+1.042507  1.303046  2.012892  2.154612  2.530678  2.649182
+1.109942  1.204237  1.928687  2.058228  2.384097  2.639570
+1.187387  1.287703  1.954253  2.071260  2.382559  2.641811
+1.239189  1.327757  1.930550  2.015277  2.361685  2.627501
+1.292084  1.351985  1.938008  2.017320  2.411502  2.663432
+1.306236  1.382401  1.918450  2.038312  2.339392  2.637738
+1.330235  1.401641  1.873760  1.990443  2.185496  2.510909
+1.356391  1.459759  1.883388  1.980460  2.264547  2.541810
+1.347396  1.438637  1.891675  2.018006  2.302572  2.643809
+1.300877  1.390171  1.889271  1.972933  2.337515  2.605637
+1.318667  1.410121  1.895352  1.990366  2.384682  2.654040
+1.309274  1.425501  1.966145  2.021896  2.501117  2.698509
+1.293853  1.370923  1.908443  1.999149  2.465481  2.673998
+1.277395  1.382844  2.002299  2.066843  2.496853  2.664070
+1.245384  1.422441  2.002908  2.070718  2.556839  2.666388
+1.272587  1.491087  2.012301  2.129241  2.562307  2.657432
+1.265182  1.533940  2.020942  2.093088  2.498380  2.630954
+1.265700  1.477033  2.103009  2.196534  2.455284  2.619887
+1.288505  1.642454  2.093854  2.247833  2.561691  2.658788
+1.410258  1.828971  2.171872  2.374134  2.564587  2.653381
+1.353887  1.710043  2.209331  2.426043  2.629318  2.702189
+1.413615  1.766928  2.137724  2.434853  2.632060  2.702909
+1.459054  1.706939  2.135084  2.377030  2.626415  2.708945
+1.498018  1.687923  2.094822  2.342946  2.558778  2.665699
+1.413908  1.588267  2.086727  2.293084  2.513587  2.642131
+1.399998  1.553342  1.938772  2.183871  2.458665  2.610409
+1.373521  1.449791  1.880601  2.079841  2.298236  2.559768
+1.367538  1.440752  1.973770  2.086070  2.339106  2.621913
+1.368842  1.460821  2.006053  2.129789  2.391520  2.650517
+1.375993  1.496235  2.050052  2.130850  2.453915  2.698625
+1.340575  1.484156  2.084130  2.140940  2.549924  2.685428
+1.389975  1.553009  2.063781  2.147982  2.592260  2.703825
+1.247451  1.503376  2.044299  2.136485  2.344491  2.599169
+1.315110  1.540850  2.028329  2.116330  2.272535  2.431545
+1.298833  1.587487  2.071926  2.185875  2.335690  2.500779
+1.293658  1.562430  2.031101  2.149606  2.408168  2.517292
+1.357545  1.513305  1.998085  2.153047  2.450464  2.583804
+1.314414  1.517423  2.079463  2.179438  2.522288  2.616203
+1.237750  1.513563  2.052227  2.181066  2.539042  2.628158
+1.208558  1.486041  2.046503  2.194666  2.489982  2.636673
+1.196570  1.462494  2.073139  2.230856  2.547633  2.700603
+1.080935  1.459427  2.110500  2.217708  2.538133  2.678354
+1.094483  1.378608  2.167880  2.246181  2.567935  2.691322
+0.942435  1.463343  2.253533  2.330775  2.538479  2.626769
+0.828468  1.390170  2.152319  2.218028  2.545274  2.621490
+0.883311  1.334196  2.094816  2.191259  2.475576  2.573464
+0.863185  1.418682  2.080489  2.166381  2.556104  2.714086
+0.848520  1.391080  2.049319  2.134194  2.702541  2.780818
+0.826225  1.373582  2.037386  2.120576  2.736093  2.782594
+0.823246  1.343853  2.033890  2.111803  2.740872  2.787067
+0.833848  1.336791  2.045450  2.118012  2.699609  2.796181
+0.811654  1.321345  2.094991  2.178116  2.494230  2.649899
+0.947528  1.361146  2.127848  2.219008  2.511382  2.668194
+0.875759  1.251606  2.133422  2.241748  2.473825  2.662930
+0.933534  1.448444  2.139134  2.244510  2.486761  2.606936
+0.945109  1.280801  2.208944  2.335059  2.511318  2.614528
+0.956935  1.371241  2.107196  2.194521  2.403252  2.573030
+0.981000  1.251932  2.147964  2.266597  2.440418  2.624374
+1.061610  1.231691  2.076021  2.233401  2.438599  2.636988
+1.018874  1.354035  1.998033  2.260078  2.443139  2.554775
+1.080301  1.301891  2.034629  2.145600  2.415056  2.591218
+1.133867  1.359760  2.063950  2.164629  2.439392  2.628661
+1.125038  1.414128  1.997540  2.103717  2.392421  2.599578
+1.167273  1.393564  1.998177  2.076478  2.441776  2.643288
+1.198696  1.421193  1.967983  2.057020  2.432820  2.645067
+1.256230  1.378074  1.941853  2.019326  2.444584  2.608853
+1.295565  1.412154  1.932411  2.008349  2.430053  2.649016
+1.281347  1.464522  1.888236  2.006518  2.425280  2.635204
+1.270582  1.406704  1.901187  1.969293  2.470983  2.647901
+1.266697  1.372887  1.871811  1.957591  2.414971  2.648622
+1.194388  1.351744  1.888250  1.978092  2.400857  2.662660
+1.198872  1.299839  1.864283  1.963651  2.362794  2.619509
+1.126580  1.240104  1.902544  1.997646  2.331426  2.608634
+1.104618  1.214183  1.879788  2.014306  2.251659  2.573373
+1.024288  1.193207  1.868916  2.127876  2.376009  2.623451
+1.000362  1.230212  1.960304  2.075244  2.329353  2.584128
+0.977548  1.321985  1.988755  2.104256  2.381026  2.607919
+0.927608  1.447916  2.027888  2.123013  2.478479  2.585880
+0.887733  1.516534  2.046895  2.153890  2.480515  2.582006
+0.898681  1.564754  2.091528  2.179653  2.573940  2.676783
+0.974718  1.500859  2.081966  2.177780  2.532281  2.634995
+1.023818  1.390635  2.060590  2.142028  2.469386  2.636908
+1.106581  1.431053  1.977134  2.097146  2.471693  2.659120
+1.201259  1.485663  1.944652  2.112542  2.500250  2.665927
+1.285694  1.520657  1.911058  2.044248  2.487710  2.665801
+1.362495  1.534785  1.910552  1.990936  2.505705  2.661527
+1.434594  1.514838  1.934187  2.017407  2.501527  2.693875
+1.420840  1.519491  1.909348  1.986650  2.460403  2.688194
+1.404412  1.469806  1.964287  2.054233  2.366794  2.655269
+1.388287  1.466909  1.964052  2.058950  2.286531  2.604935
+1.367998  1.434810  1.857703  2.007116  2.196577  2.604187
+1.300836  1.380544  1.740254  2.046889  2.235228  2.521906
+1.231299  1.321604  1.867230  2.147627  2.354630  2.579138
+1.154924  1.255903  1.932323  2.164374  2.392832  2.605994
+1.098663  1.202218  1.948275  2.150159  2.492596  2.625742
+1.057458  1.221852  1.869129  2.268825  2.456540  2.580362
+1.033078  1.150105  1.708873  2.264876  2.476044  2.563612
+0.988998  1.159268  1.962027  2.302711  2.448723  2.560725
+1.028425  1.228689  2.025910  2.260366  2.561850  2.661757
+0.934860  1.348208  2.053889  2.214742  2.525301  2.647713
+0.919150  1.264565  2.068138  2.183398  2.534979  2.644315
+0.975247  1.362233  2.052147  2.231420  2.582800  2.724482
+0.954336  1.311177  1.977372  2.238157  2.478111  2.617046
+0.941853  1.335982  1.976422  2.219013  2.579491  2.714299
+0.928694  1.366450  1.884879  2.183146  2.580560  2.657594
+0.986067  1.338370  1.954317  2.187863  2.566522  2.638835
+0.912646  1.284402  1.814142  2.175069  2.553933  2.638518
+0.968965  1.310497  1.839690  2.078084  2.590335  2.660573
+0.977192  1.304629  1.880951  2.127022  2.598044  2.712114
+1.023839  1.299619  1.944708  2.103778  2.625919  2.730897
+1.110208  1.286313  1.959383  2.053969  2.564587  2.676132
+1.028136  1.324243  1.976740  2.094942  2.586202  2.754727
+1.129799  1.269907  2.011874  2.109219  2.588902  2.696539
+1.056967  1.340484  2.016171  2.105554  2.557611  2.747157
+1.037500  1.255766  2.029385  2.136193  2.511776  2.709627
+1.006157  1.417167  2.071949  2.132612  2.543898  2.701957
+1.136962  1.416211  2.050339  2.112042  2.449673  2.695205
+1.135319  1.436267  2.083850  2.194924  2.386385  2.656934
+1.094073  1.385456  2.015160  2.113333  2.320097  2.641531
+1.025929  1.360649  1.878300  1.981456  2.128037  2.458938
+1.142747  1.416162  1.901013  2.054884  2.170210  2.459052
+1.093211  1.488385  1.801376  2.073578  2.203432  2.494834
+1.161243  1.263262  1.784814  2.071204  2.194577  2.436217
+1.010788  1.141181  1.728171  2.118721  2.251271  2.426326
+1.083805  1.275984  1.888426  2.068392  2.227464  2.511105
+1.093824  1.303401  1.924085  2.183963  2.348527  2.531702
+1.409867  1.540059  1.722330  2.049905  2.235685  2.389249
+1.466595  1.617030  1.819393  2.035808  2.439730  2.543324
+1.526883  1.811727  1.926153  2.129197  2.481471  2.556058
+1.420465  1.731610  1.925362  2.081119  2.474447  2.570275
+1.248374  1.462520  1.699273  1.907107  2.355354  2.484796
+1.183224  1.558159  1.646615  1.999807  2.374069  2.461600
+1.143841  1.513288  1.675690  1.906750  2.428362  2.518793
+1.066986  1.500051  1.667526  1.961464  2.445898  2.521565
+1.046648  1.520761  1.705160  1.878376  2.459759  2.532729
+1.013709  1.559530  1.737535  1.955854  2.437820  2.515857
+1.021952  1.586883  1.737034  1.929179  2.523644  2.577879
+0.942307  1.579146  1.776104  2.060265  2.437220  2.517653
+0.914226  1.642076  1.812801  2.001091  2.508510  2.570062
+0.952017  1.688066  1.935018  2.016153  2.446793  2.563584
+0.856280  1.697514  1.902727  2.012686  2.522414  2.584398
+0.891878  1.553150  1.935497  2.046974  2.532664  2.594967
+0.845424  1.602286  1.937720  2.027521  2.583016  2.649168
+0.876501  1.716624  1.939566  2.067536  2.588264  2.625363
+0.901014  1.864369  1.978925  2.075191  2.462666  2.609798
+0.911677  1.767853  1.947788  2.072575  2.595744  2.634946
+0.937394  1.708734  1.927739  2.054606  2.574109  2.647431
+1.003647  1.614615  1.942062  2.035984  2.592009  2.664724
+1.089415  1.563712  1.910690  1.974956  2.590910  2.681816
+1.180196  1.457231  1.840836  1.921595  2.573409  2.659354
+1.239380  1.444276  1.818908  1.893870  2.559595  2.657419
+1.377315  1.528992  1.744904  1.862220  2.591155  2.669066
+1.504904  1.589455  1.777756  1.887229  2.506207  2.617754
+1.628411  1.697438  1.830602  1.957574  2.495413  2.652982
+1.655345  1.726761  1.914454  2.042947  2.589709  2.658972
+1.698171  1.754006  1.967189  2.090429  2.602705  2.677128
+1.676303  1.767709  2.042847  2.156668  2.628324  2.690687
+1.724974  1.789927  2.022254  2.138454  2.576232  2.671774
+1.748186  1.802674  2.037781  2.180248  2.542513  2.638948
+1.727494  1.820586  1.984490  2.159068  2.525266  2.641113
+1.681162  1.820947  1.975700  2.157376  2.485796  2.590414
+1.695585  1.807190  1.993679  2.180888  2.380331  2.560860
+1.706934  1.810695  2.008115  2.133097  2.420753  2.641751
+1.654579  1.765733  2.024758  2.124029  2.493478  2.660848
+1.482280  1.849534  2.039337  2.240485  2.457215  2.547774
+1.603912  1.832539  2.051601  2.251630  2.461138  2.560412
+1.611914  1.787316  2.134457  2.250322  2.620939  2.678279
+1.702258  1.857664  2.093573  2.245781  2.633559  2.687798
+1.692364  1.776254  2.026193  2.275357  2.580552  2.683245
+1.587105  1.750297  1.997944  2.242069  2.586538  2.691453
+1.535548  1.765338  2.053611  2.233619  2.646730  2.717875
+1.189624  1.336795  1.763750  2.001818  2.436073  2.594289
+1.190961  1.322629  1.662495  2.028538  2.347408  2.530977
+1.170930  1.394685  1.727435  2.022812  2.382661  2.552602
+1.082797  1.383312  1.623231  1.825654  2.463128  2.574492
+1.058861  1.316419  1.617844  1.734402  2.496675  2.607354
+1.031745  1.332707  1.534727  1.707419  2.433275  2.544209
+1.096632  1.405927  1.540583  1.719915  2.509655  2.573209
+1.088142  1.381934  1.507222  1.618554  2.484112  2.618437
+1.128355  1.341806  1.494171  1.715551  2.495969  2.579865
+1.175042  1.360111  1.572899  1.757164  2.481162  2.588909
+1.251837  1.388286  1.580411  1.744290  2.530232  2.614281
+1.310739  1.444267  1.657251  1.823494  2.515110  2.614602
+1.329594  1.483659  1.703926  1.871461  2.532374  2.621921
+1.364647  1.503101  1.755842  1.919028  2.547482  2.624406
+1.400143  1.516781  1.808646  1.943813  2.572341  2.655551
+1.403936  1.536778  1.854571  1.961169  2.527770  2.650144
+1.441635  1.534902  1.873629  1.970753  2.528116  2.670832
+1.448614  1.528669  1.860977  1.951947  2.473243  2.657815
+1.451619  1.547843  1.824154  2.019980  2.462454  2.654097
+1.474914  1.548478  1.890892  1.995469  2.484609  2.659992
+1.432352  1.541523  1.888921  2.060202  2.407091  2.630443
+1.443739  1.529785  1.892698  1.996592  2.373799  2.620977
+1.379224  1.489730  1.897357  2.016742  2.416784  2.627496
+1.377069  1.463119  1.911655  2.022620  2.355389  2.608649
+1.331805  1.431037  1.929174  2.046904  2.374045  2.605001
+1.261392  1.448545  1.975458  2.082519  2.366860  2.620796
+1.222534  1.418974  1.979786  2.116310  2.439587  2.664630
+1.142938  1.304442  1.984504  2.071356  2.473077  2.672948
+1.163073  1.268521  1.930445  2.046302  2.305097  2.594448
+1.102508  1.246087  1.951734  2.103272  2.299777  2.571979
+1.010568  1.147332  1.902536  2.046240  2.288021  2.566997
+1.010466  1.307000  1.827652  2.076872  2.333263  2.555967
+1.246338  1.534633  1.859079  2.187994  2.388066  2.541619
+1.200493  1.578943  1.899233  2.165025  2.448881  2.583181
+0.969958  1.321171  1.879198  2.166270  2.417955  2.602455
+0.883738  1.359575  2.004523  2.100728  2.516977  2.633388
+0.844286  1.405546  2.057051  2.140524  2.516435  2.660060
+0.862435  1.502332  2.107411  2.205164  2.558187  2.660491
+0.940459  1.428240  2.139821  2.233319  2.564481  2.673761
+0.930987  1.583981  2.021904  2.152394  2.404035  2.506344
+1.046556  1.798258  1.988424  2.129290  2.357578  2.453538
+1.053483  1.593749  2.104331  2.232679  2.372807  2.498150
+1.137645  1.642783  2.089155  2.231807  2.383165  2.575567
+1.180782  1.899843  2.114705  2.223340  2.453147  2.554915
+1.144768  1.795798  2.058166  2.194105  2.452139  2.558749
+1.132549  1.688302  1.980246  2.107445  2.321949  2.446573
+1.155835  1.527004  1.951246  2.101869  2.265669  2.423260
+1.218988  1.551877  1.978933  2.129503  2.365239  2.547894
+1.269955  1.592834  1.957403  2.059254  2.477360  2.620075
+1.304775  1.597146  1.974266  2.084408  2.414413  2.613437
+1.304611  1.645522  1.976796  2.100584  2.364468  2.510600
+1.357449  1.721619  2.013975  2.141789  2.385178  2.512136
+1.335725  1.833907  2.001270  2.155846  2.401439  2.496098
+1.311398  1.558292  1.938760  2.063279  2.307274  2.526616
+1.360360  1.440763  1.893578  2.075310  2.237527  2.504599
+1.331599  1.468494  1.928903  2.060963  2.318029  2.567821
+1.318611  1.537603  1.924470  2.015195  2.358808  2.593307
+1.214364  1.546191  1.882099  1.995250  2.377928  2.652939
+1.296335  1.566534  1.875140  2.003277  2.476321  2.631527
+1.397784  1.586154  1.861480  2.030113  2.587065  2.654646
+1.475237  1.644203  1.915883  2.047027  2.653267  2.714423
+1.524741  1.716019  1.957822  2.067654  2.623703  2.690243
+1.578686  1.677809  1.940919  2.066782  2.613829  2.704583
+1.558659  1.702533  1.930114  2.028274  2.615049  2.686527
+1.500895  1.699904  1.908920  1.998738  2.620634  2.691280
+1.442946  1.702672  1.900985  1.975333  2.624730  2.699244
+1.372883  1.638290  1.917707  2.028286  2.626184  2.697452
+1.284224  1.656214  1.897845  1.992564  2.644425  2.707381
+1.204035  1.651822  1.889771  1.992564  2.638494  2.709577
+1.149198  1.622068  1.884510  1.979246  2.632691  2.699244
+1.133732  1.618626  1.895041  1.977544  2.625046  2.694884
+1.157568  1.662329  1.889784  1.978395  2.626035  2.684544
+1.218943  1.667105  1.879063  2.005165  2.602271  2.658132
+1.224226  1.626864  1.791981  1.894650  2.517637  2.647870
+1.354348  1.558760  1.843077  1.930892  2.571225  2.630861
+1.339527  1.595092  1.762248  1.979267  2.546017  2.613198
+1.389217  1.592419  1.859636  1.962120  2.550950  2.637714
+1.441267  1.590433  1.879393  1.987047  2.582006  2.666738
+1.431033  1.609808  1.890274  2.037874  2.525040  2.672056
+1.468384  1.575421  1.945848  2.029866  2.551470  2.705315
+1.450092  1.601430  1.954103  2.062799  2.534132  2.666966
+1.482171  1.565438  1.973588  2.124154  2.520208  2.656022
+1.429418  1.560169  1.984368  2.078415  2.510933  2.668346
+1.440913  1.587927  1.976090  2.097963  2.464144  2.621669
+1.432466  1.582610  1.973345  2.159930  2.500511  2.668329
+1.429101  1.593924  1.974811  2.070207  2.527049  2.683794
+1.377247  1.571046  1.937033  2.094336  2.488609  2.653189
+1.485270  1.572718  1.935520  2.015863  2.471891  2.687018
+1.473606  1.569260  1.872618  1.962880  2.412797  2.654369
+1.486059  1.580245  1.866252  1.975544  2.318749  2.586712
+1.465213  1.581118  1.784993  1.913021  2.172477  2.555915
+1.433656  1.566339  1.728508  1.853259  2.061966  2.413952
+1.367612  1.543842  1.700068  1.854972  2.034622  2.282022
+1.503264  1.657179  1.809362  1.937669  2.143191  2.435605
+1.340742  1.593266  1.833843  2.129408  2.468938  2.572839
+1.336721  1.481696  1.944774  2.230613  2.480290  2.580121
+1.321318  1.603141  1.968333  2.203371  2.515102  2.650047
+1.341931  1.668341  1.988838  2.185252  2.564141  2.653216
+1.315554  1.648897  1.959899  2.147638  2.516885  2.612616
+1.277314  1.620218  2.001858  2.229409  2.531549  2.621818
+1.305168  1.578599  2.038627  2.295512  2.565341  2.654838
+1.330511  1.609911  1.991543  2.262708  2.563339  2.665956
+1.374004  1.683930  1.980067  2.338575  2.595603  2.682727
+1.268703  1.389752  1.885378  2.110404  2.488114  2.638645
+1.216813  1.310045  1.854691  2.036714  2.277594  2.566534
+1.234945  1.337806  1.949427  2.059361  2.295326  2.566468
+1.188939  1.302387  1.996200  2.107442  2.349193  2.585236
+1.268977  1.440154  2.024771  2.136855  2.444005  2.664042
+1.274373  1.383125  2.066734  2.151173  2.407560  2.654201
+1.264553  1.356123  2.001656  2.118864  2.287784  2.569535
+1.234337  1.329784  2.063392  2.150768  2.367188  2.598596
+1.155210  1.257442  2.082496  2.211439  2.390593  2.620100
+1.199455  1.265557  1.934979  2.226691  2.540894  2.664195
+1.304701  1.526851  1.954550  2.174656  2.477694  2.621713
+1.638067  1.896263  2.077081  2.361007  2.646027  2.718839
+1.643821  1.943109  2.131987  2.329624  2.578717  2.645464
+1.640898  1.989224  2.161468  2.269205  2.586475  2.655395
+1.723007  1.910073  2.070189  2.259565  2.564392  2.640342
+1.652067  1.998733  2.135937  2.352824  2.652512  2.717475
+1.680722  2.074091  2.269666  2.453470  2.699939  2.763041
+1.695085  2.058973  2.193637  2.313571  2.639345  2.699445
+1.782955  2.014033  2.224899  2.332287  2.645355  2.724401
+1.705960  1.974745  2.180829  2.256084  2.575177  2.716938
+1.662556  1.988643  2.115183  2.205279  2.548376  2.657655
+1.562053  1.843896  2.173269  2.265891  2.477950  2.695966
+1.685920  1.795837  2.078330  2.180138  2.465369  2.667314
+1.680613  1.738555  1.994736  2.131193  2.473191  2.649544
+1.659289  1.833639  2.000087  2.140167  2.564913  2.692724
+1.714890  1.784823  1.974907  2.085230  2.566670  2.701036
+1.729112  1.826059  1.895041  2.053724  2.603924  2.699244
+1.696294  1.791079  1.916038  2.017742  2.583106  2.704200
+1.626844  1.720989  1.890443  2.014482  2.589192  2.689135
+1.574181  1.677998  1.880801  1.982799  2.574984  2.664083
+1.432597  1.676378  1.834673  1.964658  2.535300  2.638654
+1.318535  1.535375  1.836957  1.932882  2.478408  2.578350
+1.226292  1.492951  1.836423  1.946067  2.430171  2.582074
+1.098912  1.499048  1.896293  2.028872  2.540535  2.618603
+1.034465  1.533372  1.964842  2.070966  2.578583  2.651519
+0.979835  1.480912  1.975960  2.089319  2.534240  2.632634
+0.916592  1.481293  1.967506  2.053292  2.558345  2.642742
+0.937338  1.474374  2.023762  2.110460  2.585438  2.665463
+0.873055  1.560533  2.028802  2.086416  2.575020  2.684778
+0.901938  1.628414  2.031806  2.102850  2.610158  2.685650
+0.862562  1.556144  1.997573  2.081742  2.533196  2.615757
+0.906140  1.665744  2.019373  2.133337  2.581928  2.661153
+0.872836  1.638660  2.038436  2.097283  2.645014  2.697786
+0.829264  1.441895  2.039191  2.111142  2.611659  2.688610
+0.825197  1.304534  2.056354  2.143792  2.590309  2.657819
+0.793520  1.521024  1.979438  2.058424  2.596225  2.668581
+0.849751  1.485532  1.986103  2.055458  2.624269  2.701899
+0.849936  1.385589  2.007518  2.060577  2.567229  2.678449
+0.829655  1.230975  1.988404  2.101475  2.530728  2.677331
+0.940677  1.264510  1.946316  2.046724  2.499806  2.677984
+1.038884  1.297487  1.958215  2.035997  2.406970  2.650323
+1.157909  1.247311  1.892511  1.984329  2.396990  2.663399
+1.237064  1.318827  1.843309  1.954773  2.420851  2.693910
+1.328871  1.403948  1.808685  1.946118  2.400888  2.683397
+1.393193  1.460812  1.822128  1.939601  2.242548  2.723232
+1.370957  1.526137  1.785367  1.963164  2.136749  2.644805
+1.501135  1.606768  1.841831  2.009462  2.198461  2.614649
+1.467944  1.551473  1.849852  1.982829  2.208604  2.514793
+1.405944  1.480977  1.855980  1.997060  2.178717  2.490007
+1.448170  1.520957  1.868813  1.975365  2.241031  2.616351
+1.380808  1.612670  1.869962  2.026788  2.443477  2.639977
+1.483716  1.596112  1.969733  2.100913  2.577431  2.688144
+1.467685  1.578222  1.986564  2.194709  2.570945  2.671094
+1.496302  1.614196  2.032020  2.218322  2.553463  2.681813
+1.596958  1.722731  2.144525  2.319980  2.604392  2.703958
+1.563283  1.830072  2.213128  2.432926  2.641108  2.721000
+1.591103  1.948477  2.288414  2.486581  2.666837  2.743573
+1.475707  1.718658  2.050982  2.217962  2.487280  2.571804
+1.558930  1.772302  2.094474  2.234464  2.518928  2.597737
+1.567586  1.822091  2.100593  2.286654  2.533948  2.648113
+1.750029  1.936668  2.135601  2.347638  2.546896  2.638316
+1.756882  1.998584  2.116800  2.223412  2.556559  2.647062
+1.700043  1.922262  2.075348  2.184374  2.556081  2.639062
+1.598667  1.709712  1.994558  2.098788  2.521397  2.628442
+1.609782  1.719799  1.937528  2.091978  2.547584  2.621070
+1.580745  1.686692  1.927934  2.059508  2.580331  2.643528
+1.541164  1.684662  1.944797  2.038248  2.568516  2.637104
+1.474497  1.633889  1.881331  1.988847  2.554704  2.623589
+1.427685  1.616808  1.898469  1.994121  2.545908  2.635844
+1.366974  1.583736  1.860760  2.018090  2.526247  2.594032
+1.257899  1.562399  1.870764  1.961750  2.512050  2.589589
+1.183313  1.571246  1.867445  1.988791  2.543767  2.607786
+1.137720  1.607193  1.879149  2.008769  2.536804  2.607481
+1.053818  1.511423  1.904439  2.002387  2.584849  2.657089
+1.029306  1.560669  1.913466  1.984439  2.613420  2.670916
+0.990299  1.520302  1.919708  2.005988  2.615870  2.705960
+0.927002  1.486845  1.900099  1.977768  2.614622  2.695757
+0.924166  1.500302  1.837270  1.915819  2.601787  2.702827
+0.901854  1.422756  1.898010  1.950141  2.572992  2.759299
+0.910623  1.286484  1.801282  1.925793  2.438152  2.671294
+0.904293  1.226137  1.873337  1.946907  2.485265  2.645532
+0.872654  1.122664  1.912497  2.047619  2.468062  2.645490
+1.136081  1.248013  1.725399  2.180627  2.493778  2.579400
+1.161500  1.346974  1.804044  2.157021  2.550312  2.633164
+1.287295  1.663717  2.044188  2.321923  2.599284  2.687129
+1.456799  1.758274  2.055266  2.310654  2.549315  2.660074
+1.416948  1.741370  2.104189  2.357764  2.591761  2.679543
+1.379535  1.752525  2.173415  2.361073  2.617497  2.699322
+1.361005  1.762025  2.115710  2.330663  2.562002  2.650389
+1.340777  1.685357  2.024889  2.281946  2.547415  2.639463
+1.278174  1.686145  1.961407  2.165468  2.554171  2.647873
+1.294524  1.547620  1.981967  2.183432  2.547510  2.637235
+1.201621  1.343641  2.007859  2.089427  2.535679  2.660742
+1.201995  1.332111  1.949153  2.051811  2.553202  2.665468
+1.180355  1.354250  1.890523  2.069912  2.515229  2.620120
+1.128725  1.419757  1.854779  2.056632  2.480702  2.583539
+1.133191  1.402342  1.822656  2.013606  2.539914  2.639438
+1.149266  1.376927  1.821187  1.914934  2.562423  2.664037
+1.080871  1.408443  1.788020  1.879929  2.517515  2.656681
+1.152439  1.509600  1.822338  1.939812  2.528944  2.619151
+1.227262  1.543782  1.935413  2.017678  2.575512  2.665626
+1.253647  1.485940  1.945543  1.987370  2.539186  2.715089
+1.224504  1.521337  1.982156  2.044940  2.522684  2.687446
+1.258716  1.476124  1.981858  2.073104  2.536174  2.634089
+1.255580  1.471131  1.983938  2.052555  2.541040  2.708650
+1.221419  1.556731  2.013319  2.089772  2.538596  2.706495
+1.178484  1.474650  2.007635  2.122088  2.560256  2.629434
+1.136643  1.459288  2.033733  2.100427  2.544702  2.689126
+1.035202  1.462561  2.024973  2.194093  2.530601  2.662208
+1.090875  1.522421  2.038442  2.129424  2.587618  2.687392
+1.054541  1.538340  2.000589  2.084015  2.516505  2.644331
+1.069567  1.471150  1.977006  2.102657  2.548224  2.645658
+1.084637  1.235068  1.999027  2.091007  2.405191  2.622410
+1.073907  1.180490  1.961383  2.101877  2.255303  2.531797
+1.185536  1.320277  2.006751  2.098846  2.443082  2.582972
+1.256811  1.419989  1.983529  2.130962  2.470417  2.558689
+1.290736  1.391916  1.995379  2.106560  2.351663  2.485168
+1.428569  1.748298  2.044813  2.277573  2.513087  2.625248
+1.495766  1.686660  2.135657  2.292230  2.499007  2.616505
+1.482459  1.632012  2.083877  2.297241  2.488552  2.605327
+1.538843  1.630868  2.111745  2.223107  2.576837  2.693238
+1.551627  1.628553  2.040601  2.158000  2.590177  2.713514
+1.570014  1.637722  1.958103  2.124258  2.570176  2.692788
+1.534589  1.607992  1.801643  2.087274  2.392697  2.600933
+1.502776  1.607625  1.843802  2.082344  2.323284  2.522392
+1.515698  1.613442  1.837842  2.027239  2.402910  2.602242
+1.510034  1.607577  1.826422  1.955465  2.340570  2.679619
+1.445827  1.566639  1.756421  1.869709  2.296147  2.601653
+1.410709  1.488515  1.820022  1.910438  2.358230  2.614654
+1.301575  1.428283  1.812427  1.902581  2.293360  2.725276
+1.106808  1.351509  1.888725  1.956330  2.320442  2.646886
+1.056263  1.366917  1.866615  1.968949  2.421463  2.653524
+1.148746  1.368055  1.809637  2.064105  2.437788  2.604096
+0.990270  1.453159  1.887277  2.035172  2.296937  2.600298
+0.943695  1.204266  1.748001  1.886445  2.181614  2.509804
+1.057049  1.221402  1.835972  1.972438  2.154951  2.492969
+0.936404  1.225524  1.895053  1.998065  2.539531  2.644930
+0.941516  1.224493  1.966408  2.055267  2.515087  2.609082
+1.000240  1.314972  1.942001  2.051921  2.535877  2.634783
+1.031394  1.407401  1.953467  2.045443  2.550815  2.634369
+1.118870  1.441951  1.952517  2.061995  2.494339  2.608036
+1.197103  1.553158  1.887646  2.009186  2.472098  2.550658
+1.293802  1.588339  1.868376  2.045916  2.481096  2.566107
+1.353770  1.610646  1.897619  2.083477  2.408292  2.543397
+1.403681  1.521997  1.891672  2.054144  2.357288  2.512253
+1.370402  1.446254  1.871326  1.998144  2.336676  2.570693
+1.499387  1.755248  2.090328  2.282953  2.484033  2.574394
+1.567708  1.842611  2.136623  2.278726  2.477117  2.576067
+1.591554  1.767544  2.169415  2.302935  2.525126  2.637496
+1.458272  1.799744  2.227216  2.397500  2.616529  2.705570
+1.496705  1.846042  2.279896  2.437186  2.649673  2.726623
+1.502759  1.731322  2.268727  2.464213  2.623623  2.706745
+1.497299  1.617932  2.156580  2.386255  2.579030  2.664716
+1.379977  1.538687  1.850634  2.109517  2.410662  2.586146
+1.405875  1.497926  1.741705  1.932278  2.337183  2.563846
+1.346170  1.431041  1.657425  1.884420  2.373948  2.587354
+1.307909  1.406366  1.734141  1.875825  2.460720  2.602094
+1.273940  1.571154  1.771276  1.912248  2.536452  2.595610
+1.200061  1.575178  1.770854  1.877630  2.508016  2.579146
+1.125813  1.539421  1.722626  1.859971  2.511653  2.574626
+1.064900  1.484512  1.690862  1.832750  2.519579  2.589278
+1.042869  1.483231  1.627118  1.867084  2.495867  2.550264
+0.950910  1.474823  1.576110  1.830086  2.519438  2.569906
+1.004516  1.423026  1.550120  1.835220  2.473605  2.544366
+1.026409  1.365688  1.510656  1.879110  2.467179  2.543867
+0.978321  1.338491  1.528018  1.913878  2.465066  2.524725
+0.922555  1.409585  1.520258  1.932657  2.404714  2.472216
+1.009019  1.345028  1.518729  1.999531  2.463064  2.544939
+0.989351  1.433164  1.573872  2.015438  2.401202  2.490979
+1.035325  1.556325  1.677312  2.086779  2.481518  2.567949
+1.004119  1.575292  1.796393  2.075521  2.402912  2.574238
+1.037355  1.681818  1.943106  2.065425  2.478887  2.598899
+1.005855  1.684746  1.972392  2.109307  2.565052  2.623513
+0.954873  1.719791  2.006188  2.112346  2.598630  2.682782
+0.937994  1.728321  1.993763  2.105254  2.632050  2.700706
+0.889626  1.709530  2.001291  2.090092  2.620540  2.709802
+0.912128  1.657624  1.966778  2.058636  2.626429  2.702918
+0.972006  1.569116  1.985953  2.130241  2.569149  2.677258
+1.038791  1.651170  2.008290  2.118109  2.599188  2.701292
+1.102203  1.624993  1.998759  2.125031  2.569760  2.646643
+1.187738  1.639367  2.059243  2.147304  2.475862  2.634964
+1.274099  1.590670  2.016754  2.099633  2.548725  2.668989
+1.373403  1.630011  1.981494  2.070929  2.505950  2.689328
+1.511208  1.602606  1.911343  2.022899  2.475945  2.645751
+1.553078  1.639398  1.870403  1.975613  2.473431  2.626572
+1.633420  1.773325  1.875127  1.959482  2.413151  2.625912
+1.596719  1.747314  1.878046  2.049018  2.587489  2.669276
+1.664674  1.933354  2.156044  2.280025  2.462736  2.571555
+1.551190  1.695801  2.047099  2.236977  2.447592  2.570843
+1.648304  1.728067  2.060789  2.273739  2.475137  2.631203
+1.633548  1.757572  2.089279  2.240980  2.436119  2.556847
+1.608644  1.684711  2.123747  2.256566  2.486503  2.598234
+1.653176  1.714541  2.105354  2.203230  2.509317  2.641781
+1.541046  1.679960  2.104266  2.247262  2.540379  2.626724
+1.559664  1.659637  2.101376  2.213674  2.473238  2.562999
+1.608810  1.671776  2.071434  2.184829  2.493283  2.639463
+1.538876  1.610189  2.083083  2.171544  2.554389  2.650993
+1.511021  1.595459  2.031637  2.130089  2.587598  2.660399
+1.340693  1.587842  1.931002  2.117119  2.599860  2.676574
+1.484682  1.533251  2.024488  2.113154  2.548321  2.659954
+1.534337  1.608310  2.031541  2.136001  2.537102  2.617716
+1.571577  1.618314  2.056726  2.139748  2.525414  2.622206
+1.564471  1.631266  2.060592  2.166039  2.469995  2.635657
+1.533650  1.663515  2.093962  2.190787  2.406743  2.622754
+1.570124  1.631042  2.049374  2.165169  2.393566  2.588498
+1.552473  1.634522  2.008478  2.098878  2.509195  2.669322
+1.498536  1.602806  2.008880  2.099726  2.525137  2.659175
+1.450925  1.660536  1.991759  2.103304  2.544073  2.696474
+1.447598  1.569099  1.993051  2.079756  2.587712  2.676395
+1.394567  1.544697  2.006663  2.078973  2.579015  2.721882
+1.347921  1.507746  1.993785  2.077331  2.510234  2.682685
+1.265189  1.355385  1.877848  2.063826  2.425800  2.657797
+1.266300  1.376932  2.008877  2.275008  2.479039  2.636159
+1.414729  1.680622  2.057398  2.332754  2.549975  2.652454
+1.499883  1.708789  2.054742  2.313580  2.521026  2.613915
+1.445680  1.741768  2.126388  2.338809  2.495118  2.597970
+1.459203  1.792340  2.113493  2.346074  2.563702  2.664973
+1.416845  1.644394  2.131474  2.322905  2.578800  2.677164
+1.447967  1.708221  2.144894  2.272584  2.593212  2.700869
+1.474608  1.742978  2.066944  2.341635  2.601749  2.685249
+1.346721  1.653940  1.999147  2.218537  2.633365  2.723602
+1.375208  1.551414  2.052682  2.232013  2.586844  2.697029
+1.260950  1.501751  1.925196  2.033937  2.546694  2.652031
+1.259339  1.500189  1.909647  1.982913  2.545881  2.638673
+1.252838  1.563842  1.910593  1.973683  2.579307  2.664280
+1.263002  1.546326  1.878080  2.031152  2.583468  2.653793
+1.265196  1.521273  1.905708  1.967385  2.581430  2.658715
+1.307704  1.547718  1.881421  1.962040  2.573475  2.658828
+1.291340  1.575015  1.915239  1.985560  2.602082  2.697699
+1.295431  1.626460  1.923299  2.023724  2.591291  2.680142
+1.301210  1.624080  1.878934  1.998083  2.560098  2.634506
+1.305813  1.620922  1.888028  1.989036  2.606227  2.669425
+1.308088  1.642328  1.885958  2.013573  2.611911  2.696648
+1.312101  1.627858  1.861841  1.974096  2.602616  2.658487
+1.292897  1.605725  1.877131  1.973395  2.599643  2.682844
+1.273139  1.591736  1.870416  1.947454  2.602328  2.674146
+1.283582  1.620817  1.847273  1.928033  2.590051  2.636876
+1.246205  1.560066  1.851625  1.954533  2.587535  2.673542
+1.260393  1.539639  1.831617  1.928432  2.552288  2.629629
+1.261220  1.505229  1.857309  1.933908  2.569004  2.696314
+1.283108  1.719865  1.823903  1.976026  2.565436  2.628748
+1.314387  1.617735  1.804065  1.960535  2.596814  2.686738
+1.338699  1.637284  1.896932  2.009128  2.523466  2.637375
+1.336475  1.577029  1.850025  1.943237  2.521339  2.596832
+1.398912  1.549275  1.724463  1.861933  2.166791  2.466332
+1.406894  1.497435  1.805042  1.909122  2.284281  2.542582
+1.474849  1.579373  1.970765  2.079699  2.371434  2.542616
+1.452309  1.539401  2.076665  2.137999  2.442972  2.649515
+1.450617  1.506612  2.036385  2.131452  2.484829  2.674720
+1.434796  1.583083  2.027674  2.136807  2.429113  2.578344
+1.087572  1.367208  1.786303  2.025035  2.298079  2.515673
+0.992092  1.436432  1.725512  1.965111  2.425717  2.549021
+0.969474  1.497321  1.730092  2.016045  2.414373  2.633316
+0.936277  1.413012  1.683609  2.029768  2.443096  2.552830
+1.176352  1.559638  1.748772  2.061891  2.311483  2.434690
+1.067106  1.406642  1.643885  1.978806  2.374725  2.547845
+0.989262  1.333111  1.475085  1.728650  2.492018  2.553467
+0.957471  1.308545  1.424561  1.823472  2.490215  2.552316
+1.035765  1.254486  1.352081  1.786247  2.539488  2.585779
+1.023678  1.232418  1.398476  1.875768  2.451677  2.540251
+1.037249  1.247286  1.387422  2.008554  2.419268  2.496115
+1.045924  1.231687  1.361952  1.887611  2.384450  2.471500
+1.000981  1.250837  1.376662  1.767666  2.398053  2.484439
+1.061773  1.214611  1.410756  1.728252  2.423979  2.514269
+1.168228  1.291194  1.597509  1.900015  2.415419  2.555014
+1.150788  1.412860  1.825953  1.953264  2.400052  2.535324
+1.166923  1.517635  1.943529  2.034246  2.373359  2.521470
+1.183183  1.523161  1.995315  2.119892  2.433461  2.591155
+1.159482  1.521728  2.072369  2.176962  2.514904  2.660759
+1.260320  1.722656  2.116773  2.249048  2.534123  2.645628
+1.450433  1.717713  2.048790  2.212752  2.499485  2.636128
+1.449227  1.653123  2.023641  2.196888  2.453054  2.612516
+1.388122  1.597569  1.968649  2.163453  2.425431  2.578033
+1.347603  1.449808  1.894138  2.168973  2.446471  2.602268
+1.398006  1.471755  1.922063  2.120957  2.396434  2.600718
+1.428663  1.541308  2.046052  2.132513  2.397088  2.643104
+1.492673  1.585159  2.059339  2.158303  2.480824  2.648749
+1.558991  1.648786  2.037511  2.153321  2.512380  2.647660
+1.587505  1.659085  2.020500  2.139692  2.537458  2.616564
+1.634348  1.739360  2.044485  2.218194  2.530130  2.622735
+1.650152  1.736774  2.049269  2.148919  2.551868  2.651288
+1.640705  1.707347  1.991329  2.119563  2.587595  2.642835
+1.655822  1.709750  1.941946  2.090791  2.570081  2.630366
+1.606441  1.695623  1.852762  2.047845  2.554897  2.628090
+1.484591  1.657033  1.822979  2.008956  2.584027  2.653723
+1.348381  1.627797  1.779073  1.897327  2.521867  2.646403
+1.155644  1.464872  1.763798  1.943553  2.555854  2.642088
+1.339453  1.676328  1.971041  2.186803  2.438887  2.571072
+1.297378  1.615525  1.946759  2.151180  2.429841  2.558129
+1.136457  1.519887  1.867226  2.107387  2.452727  2.553710
+0.943433  1.350976  1.714327  1.830884  2.380038  2.573606
+0.933950  1.078579  1.553087  1.662344  2.027950  2.453145
+0.896937  1.246931  1.586629  1.684078  2.397137  2.611707
+0.892078  1.350059  1.560075  1.689846  2.506278  2.607560
+0.772181  1.313675  1.525659  1.650282  2.468977  2.636413
+0.863603  1.328577  1.481135  1.768890  2.496778  2.546566
+0.908312  1.258415  1.382771  1.699751  2.448589  2.547326
+0.863083  1.273798  1.422414  1.575877  2.509924  2.567103
+0.798143  1.233378  1.328045  1.718547  2.545479  2.654885
+0.937997  1.297209  1.447389  1.659450  2.539430  2.664368
+1.015311  1.282646  1.449652  1.656931  2.519587  2.597241
+1.012603  1.308086  1.428756  1.742642  2.581377  2.654752
+1.075222  1.359942  1.466363  1.790456  2.582927  2.654917
+1.174719  1.354592  1.470683  1.808114  2.611814  2.690601
+1.304671  1.380565  1.486415  1.863253  2.499088  2.646637
+1.329253  1.458935  1.599739  1.985102  2.412241  2.489601
+1.326849  1.466962  1.650712  1.972882  2.173652  2.363777
+1.440729  1.597862  1.756923  1.942121  2.134420  2.330899
+1.490912  1.615283  1.799725  1.989183  2.307191  2.535959
+1.523001  1.676436  1.841390  2.084493  2.490067  2.619504
+1.536446  1.672927  1.834339  2.067942  2.594848  2.655730
+1.585206  1.673419  1.879347  2.026137  2.609162  2.691334
+1.576452  1.662112  1.868110  1.987273  2.629831  2.702492
+1.561137  1.629084  1.910414  2.005430  2.633437  2.726135
+1.531209  1.615548  1.873644  1.966279  2.522587  2.706064
+1.473294  1.591222  1.908945  1.973407  2.535042  2.733124
+1.412536  1.473645  1.871722  1.957323  2.341205  2.740704
+1.379808  1.473241  1.923919  1.986068  2.447172  2.657583
+1.333691  1.500115  1.933534  2.138032  2.501795  2.615830
+1.405765  1.570091  2.028114  2.332669  2.573681  2.664117
+1.386052  1.546746  2.101843  2.380119  2.607300  2.712463
+1.420552  1.664080  2.096840  2.287671  2.545433  2.645671
+1.429919  1.632895  2.056448  2.245342  2.469727  2.594625
+1.450338  1.542326  1.936139  2.160089  2.389658  2.594948
+1.458650  1.545840  1.973946  2.132840  2.280546  2.519107
+1.499624  1.621854  1.924363  2.086584  2.253820  2.393464
+1.480124  1.596614  1.822901  2.030079  2.212455  2.440593
+1.385572  1.515794  1.763525  2.007562  2.207014  2.505163
+1.363477  1.483710  1.745394  2.020826  2.177380  2.428417
+1.422412  1.526361  1.802470  2.041367  2.267629  2.509983
+1.451781  1.539504  1.888618  2.079745  2.258528  2.500819
+1.462745  1.548876  1.925748  2.065292  2.320100  2.591877
+1.459612  1.526791  1.937299  2.029745  2.425999  2.618215
+1.426774  1.495962  1.934803  2.028683  2.474317  2.639936
+1.395478  1.494605  1.923542  2.006865  2.508795  2.651596
+1.315323  1.475877  1.925867  2.012444  2.562544  2.642674
+1.216208  1.542312  1.867609  1.962911  2.578507  2.638914
+1.188119  1.592111  1.826165  1.956758  2.592728  2.659305
+1.157283  1.519027  1.841285  1.936129  2.596722  2.669387
+1.042732  1.334857  1.852810  1.927812  2.509256  2.721390
+1.076921  1.512728  1.892211  1.976017  2.370736  2.635640
+1.328644  1.555209  1.826957  2.080018  2.447934  2.607755
+1.271225  1.383527  1.740551  2.048721  2.356257  2.567108
+1.288765  1.385478  1.793872  1.977849  2.390396  2.604554
+1.328655  1.422241  1.805644  2.002822  2.289156  2.544301
+1.377945  1.493655  1.793682  2.031868  2.353733  2.518906
+1.384430  1.453654  1.838071  2.001840  2.390785  2.635123
+1.289457  1.403427  1.871018  1.986122  2.479981  2.723796
+1.207888  1.388220  1.865052  2.031661  2.450066  2.591415
+1.218628  1.309314  1.909852  2.003782  2.499425  2.604984
+1.178831  1.273297  1.832814  2.025041  2.508629  2.650229
+1.147475  1.259195  1.930161  2.027735  2.522075  2.634075
+1.100906  1.268026  1.857908  1.951898  2.508895  2.660387
+1.069825  1.225671  1.888950  1.974341  2.492132  2.592105
+1.042255  1.182210  1.891740  2.039958  2.559652  2.679327
+0.956414  1.180966  1.881463  1.994332  2.316474  2.617691
+1.061791  1.571696  1.926569  2.107177  2.404155  2.525452
+1.374312  1.475896  1.678426  1.972424  2.364289  2.516531
+1.363442  1.455771  1.763156  1.970798  2.368334  2.586977
+1.423043  1.591891  1.798197  2.012780  2.388112  2.602184
+1.527265  1.605781  1.909513  2.033429  2.406683  2.593463
+1.585135  1.664508  1.918013  2.026537  2.425727  2.600924
+1.611888  1.728561  1.907667  2.034036  2.395680  2.641770
+1.463013  1.624657  1.872286  1.998243  2.487821  2.662465
+1.507075  1.597912  1.893748  1.997011  2.535979  2.672459
+1.502401  1.618027  1.888560  2.024162  2.581852  2.656536
+1.553117  1.639479  1.918920  2.034284  2.576859  2.655677
+1.577358  1.648261  1.958093  2.053413  2.567886  2.656516
+1.595375  1.654628  1.997767  2.099746  2.531642  2.675206
+1.621639  1.704007  1.957750  2.074637  2.584314  2.660506
+1.618433  1.711386  1.954786  2.067454  2.533767  2.695229
+1.617851  1.716314  1.949677  2.103360  2.635944  2.686892
+1.649322  1.746309  1.901606  2.064352  2.606774  2.690238
+1.635059  1.769603  1.904617  2.019099  2.607597  2.713325
+1.645565  1.779500  1.868948  1.965332  2.592154  2.714895
+1.686573  1.757504  1.858066  1.922036  2.505271  2.698890
+1.612716  1.703234  1.831053  1.925901  2.373806  2.613684
+1.244351  1.409563  1.713462  1.967702  2.351463  2.537356
+1.269988  1.387301  1.640967  1.991832  2.324911  2.501768
+1.305349  1.455772  1.788777  2.091229  2.487237  2.614726
+1.413862  1.518807  1.888520  2.252275  2.448086  2.594722
+1.409418  1.591460  1.944717  2.196924  2.518393  2.638233
+1.399142  1.703314  1.966146  2.224863  2.616908  2.734082
+1.375311  1.636377  2.061764  2.292420  2.586624  2.705744
+1.394667  1.733415  2.073598  2.297154  2.573824  2.672888
+1.366082  1.738611  2.016634  2.285662  2.605490  2.693517
+1.360620  1.601685  1.967966  2.194839  2.564848  2.657918
+1.354700  1.471541  1.990171  2.165439  2.569000  2.679116
+1.319372  1.403922  2.030220  2.115007  2.452702  2.635911
+1.303257  1.374731  1.975040  2.111171  2.369818  2.660606
+1.325790  1.431051  2.036171  2.113943  2.475995  2.685073
+1.307478  1.510363  2.117703  2.179166  2.554579  2.695776
+1.311427  1.548305  2.128351  2.279725  2.551702  2.645499
+1.293775  1.442228  2.115561  2.289555  2.415905  2.531210
+1.278672  1.697114  2.092498  2.199540  2.368518  2.561138
+1.292641  1.867932  2.128826  2.206329  2.450839  2.551778
+1.234857  1.631071  2.143705  2.304460  2.491014  2.565728
+1.219953  1.367565  2.149802  2.218488  2.495215  2.635299
+1.208902  1.484837  2.180300  2.276690  2.526332  2.626732
+1.165264  1.458241  2.155590  2.227283  2.490182  2.596799
+1.116188  1.492178  2.177271  2.241905  2.532331  2.620529
+1.096897  1.524925  2.093489  2.345253  2.480356  2.611159
+1.043785  1.369028  2.229277  2.306648  2.527431  2.613026
+1.080719  1.336126  2.135541  2.240613  2.463443  2.634282
+1.126263  1.502538  2.065329  2.274832  2.512833  2.588250
+1.199125  1.448000  2.040575  2.216856  2.449127  2.544297
+1.244303  1.540831  2.036533  2.174834  2.470267  2.580345
+1.277190  1.574057  2.066371  2.150365  2.508540  2.611728
+1.341754  1.576876  2.031475  2.120651  2.496164  2.575343
+1.335444  1.541598  1.994337  2.108804  2.518844  2.622948
+1.351719  1.543708  2.003315  2.075354  2.579158  2.656631
+1.359299  1.470533  1.968461  2.042323  2.565151  2.664841
+1.368199  1.433218  1.983774  2.044947  2.438603  2.670598
+1.351177  1.426131  1.991290  2.087726  2.430748  2.616370
+1.349866  1.483300  2.000270  2.242826  2.535909  2.629047
+1.322061  1.596777  2.113123  2.408146  2.548980  2.625263
+1.381288  1.648758  2.192458  2.378361  2.579516  2.654496
+1.372134  1.542663  2.062546  2.307310  2.475587  2.580621
+1.363570  1.463481  1.864764  2.288459  2.467800  2.571685
+1.335793  1.536300  1.886159  2.221871  2.543381  2.670529
+1.259757  1.393352  1.604761  1.934288  2.430512  2.509599
+1.224722  1.349648  1.481936  1.836832  2.384963  2.463134
+1.253661  1.369206  1.505507  1.994342  2.366061  2.454562
+1.250448  1.372217  1.563439  2.133283  2.391531  2.461107
+1.298984  1.412532  1.560005  2.162846  2.475577  2.551467
+1.308701  1.487231  1.616571  2.140891  2.422519  2.527844
+1.362265  1.509740  1.691137  2.151850  2.425060  2.504008
+1.415186  1.573817  1.726343  2.145690  2.423615  2.518947
+1.468304  1.624569  1.768003  2.107079  2.433687  2.501879
+1.474213  1.645172  1.829377  2.150471  2.330539  2.454132
+1.488731  1.662220  1.853177  2.160434  2.390722  2.507469
+1.515371  1.685102  1.820897  2.090815  2.477135  2.541320
+1.533941  1.681022  1.911151  2.101052  2.431211  2.507421
+1.547022  1.762747  1.905315  2.057302  2.369967  2.496458
+1.524747  1.707503  1.880853  2.145136  2.331290  2.443298
+1.532670  1.689464  1.838440  2.066707  2.352074  2.487585
+1.449082  1.639914  1.786524  2.047043  2.328788  2.426218
+1.393415  1.607003  1.752128  2.065963  2.381000  2.473775
+1.234921  1.620384  1.751709  2.079353  2.400969  2.471820
+1.128649  1.589193  1.725978  2.097814  2.421776  2.507176
+1.205122  1.491109  1.707033  2.143134  2.407676  2.489596
+1.105985  1.524092  1.740260  2.142524  2.422755  2.532710
+1.146867  1.428089  1.698792  2.100330  2.423332  2.545496
+1.116015  1.351902  1.754307  2.146023  2.411698  2.527537
+1.178509  1.306840  1.824109  2.272040  2.452886  2.546314
+1.386046  1.686532  2.010818  2.148686  2.439205  2.570934
+1.334381  1.674050  1.962490  2.108725  2.403922  2.587496
+1.309542  1.519433  2.030598  2.119732  2.436082  2.620801
+1.199624  1.425192  2.037889  2.161327  2.493314  2.639529
+0.913804  1.251727  2.055079  2.176873  2.416854  2.644928
+0.822137  1.067331  2.019119  2.216592  2.395557  2.658189
+0.859923  0.985874  1.904285  2.160589  2.433708  2.639822
+0.906761  1.140617  2.010505  2.146239  2.469640  2.644134
+0.950845  1.253958  2.039526  2.095898  2.600275  2.711094
+0.953879  1.245319  1.985465  2.133152  2.543655  2.613003
+1.031672  1.286594  1.974619  2.037126  2.541018  2.690276
+1.051598  1.373163  1.905246  2.009638  2.495552  2.674053
+1.088262  1.297396  1.898694  2.018578  2.508840  2.690510
+1.146698  1.282269  1.930714  2.010155  2.439408  2.647009
+1.157205  1.343846  1.930823  2.029125  2.368152  2.598000
+1.247348  1.432742  1.942594  2.067451  2.392833  2.554304
+1.297617  1.516021  1.993391  2.079273  2.439458  2.548273
+1.386254  1.483598  1.965854  2.071612  2.444793  2.594366
+1.429692  1.499865  1.880633  2.074107  2.346203  2.604251
+1.569133  1.644482  1.942763  2.045196  2.370694  2.589367
+1.696361  1.745617  1.980943  2.093662  2.433481  2.583667
+1.694840  1.801151  1.961027  2.068322  2.452636  2.638290
+1.619793  1.785586  1.919626  2.055816  2.238163  2.498763
+1.223689  1.621225  1.791717  1.898693  2.161669  2.499947
+1.144413  1.452915  1.780893  1.866745  2.214208  2.494268
+1.135538  1.495124  1.820776  1.894356  2.115005  2.441578
+1.131378  1.535817  1.737318  1.842419  2.021638  2.425946
+1.212645  1.312165  1.752907  1.889323  2.108905  2.469701
+1.253951  1.352407  1.652652  1.960954  2.394436  2.568676
+1.362676  1.580790  1.913319  2.212617  2.381597  2.528987
+1.417331  1.582049  1.977630  2.237995  2.413078  2.580292
+1.383161  1.603552  2.016139  2.210126  2.449048  2.587234
+1.442111  1.544212  1.938946  2.141876  2.494998  2.590164
+1.381730  1.579156  1.982000  2.138775  2.485780  2.620572
+1.361593  1.597812  1.964935  2.138121  2.542610  2.622470
+1.360664  1.614689  2.010781  2.161500  2.460448  2.583897
+1.390092  1.628646  1.963826  2.130557  2.477732  2.613382
+1.346169  1.648499  2.082367  2.321708  2.555952  2.649424
+1.440422  1.742439  2.007648  2.208244  2.450993  2.577906
+1.444825  1.695062  2.026868  2.210477  2.414028  2.532766
+1.345541  1.589166  1.955423  2.129306  2.409889  2.543165
+1.400043  1.481922  1.947067  2.110259  2.313164  2.531167
+1.384776  1.484787  1.983872  2.107142  2.360088  2.585480
+1.429185  1.514936  2.019660  2.137662  2.329551  2.585292
+1.450546  1.518321  2.010034  2.102797  2.401692  2.603278
+1.441363  1.525406  1.964971  2.076719  2.376014  2.594808
+1.464787  1.521553  1.968987  2.077867  2.444963  2.621082
+1.486696  1.573684  2.001845  2.108515  2.433771  2.626158
+1.471032  1.543603  1.991659  2.111714  2.473307  2.645459
+1.415271  1.524488  2.012703  2.095751  2.458820  2.642016
+1.407514  1.501486  2.050311  2.156204  2.480187  2.623271
+1.376118  1.459583  2.009938  2.169415  2.480196  2.642689
+1.345946  1.472883  2.073124  2.184863  2.486126  2.610362
+1.306365  1.438379  2.090496  2.213143  2.554203  2.683954
+1.219262  1.423037  2.090917  2.170494  2.559623  2.668211
+1.180469  1.408080  1.935170  2.088177  2.548134  2.639438
+1.209541  1.528929  1.887266  1.961882  2.483440  2.649342
+1.219923  1.521384  1.939175  1.988023  2.460034  2.673476
+1.198754  1.474098  1.859112  1.981042  2.395346  2.719202
+1.118408  1.504845  1.897944  2.002376  2.242870  2.598523
+1.018525  1.459894  1.746590  2.051954  2.324856  2.458848
+0.866990  1.387782  1.654105  1.799741  2.325792  2.407380
+0.862252  1.365828  1.705762  1.802245  2.416352  2.493849
+0.928394  1.546454  1.716680  1.877069  2.379724  2.524594
+1.083354  1.487338  1.801149  2.005692  2.321736  2.558733
+1.057425  1.339797  1.834422  1.934601  2.279625  2.530701
+0.954787  1.140996  1.792870  1.891796  2.342908  2.492038
+0.996853  1.130036  1.792153  1.895409  2.236238  2.403350
+0.920268  1.069492  1.874858  2.072086  2.335228  2.486570
+0.954214  1.081065  1.827324  2.079149  2.238820  2.508120
+0.894487  1.013841  1.716536  2.018446  2.175347  2.482241
+0.842005  0.979634  1.644526  1.945897  2.271025  2.438632
+0.955710  1.090003  1.754054  1.967070  2.127836  2.448885
+0.954385  1.094473  1.727553  2.005579  2.266567  2.514397
+1.025620  1.137605  1.787527  2.002076  2.336896  2.511839
+1.013813  1.175105  1.881936  2.016643  2.345862  2.445716
+1.082667  1.227297  1.923243  2.022783  2.402376  2.520967
+1.118115  1.224136  1.824448  1.961745  2.245832  2.515829
+1.146448  1.298991  1.872929  1.995465  2.371727  2.526896
+1.188552  1.310653  1.902213  1.996780  2.290374  2.520538
+1.309924  1.416529  1.878448  2.050089  2.224176  2.387793
+1.394764  1.506270  1.934888  2.056817  2.271193  2.453341
+1.377933  1.572642  1.990697  2.083570  2.381595  2.606523
+1.444019  1.689297  1.997464  2.153207  2.361127  2.507701
+1.515035  1.642770  1.929088  2.159339  2.335507  2.497838
+1.540079  1.708314  1.883825  2.094981  2.398624  2.570098
+1.600911  1.698511  1.881481  2.085171  2.451013  2.653738
+1.502633  1.756061  2.040722  2.163397  2.376168  2.548669
+1.532107  1.855341  1.993840  2.139554  2.302488  2.430987
+1.484859  1.822055  1.964302  2.135961  2.337023  2.472337
+1.536688  1.766917  1.951249  2.090524  2.324175  2.529206
+1.582282  1.723852  1.912068  2.069366  2.302944  2.473896
+1.499712  1.593288  1.912697  2.034098  2.366553  2.553790
+1.434200  1.540709  1.867569  1.989167  2.323715  2.539399
+1.189101  1.500824  1.763417  1.976198  2.137279  2.441179
+1.165922  1.470178  1.772997  1.927098  2.088007  2.304301
+1.250154  1.600421  1.818068  1.922113  2.080252  2.241814
+1.122694  1.628796  1.814409  1.932949  2.099304  2.418672
+1.019615  1.510656  1.850726  1.995621  2.130205  2.457063
+0.958176  1.639680  1.840433  1.956534  2.104283  2.279028
+1.010543  1.537512  1.772221  1.930517  2.101622  2.248506
+0.904371  1.505016  1.664330  1.827875  2.278031  2.348418
+1.067733  1.454537  1.686858  1.803459  2.384372  2.499789
+1.262873  1.516004  1.882748  1.975559  2.353571  2.519731
+1.560637  1.698959  1.921539  2.000060  2.540292  2.605234
+1.665625  1.744091  1.995924  2.104003  2.538942  2.620162
+1.615168  1.748503  2.024112  2.126056  2.408165  2.614133
+1.678025  1.752954  2.027903  2.146564  2.382374  2.568508
+1.580352  1.680273  1.997415  2.122458  2.459846  2.587827
+1.590082  1.692050  1.934784  2.095757  2.552980  2.625876
+1.539000  1.620243  1.920765  2.031604  2.481670  2.592695
+1.408796  1.511786  1.744250  1.896588  2.412019  2.515579
+1.320558  1.487993  1.754964  1.896907  2.437159  2.563184
+1.174869  1.524851  1.708181  1.962955  2.513779  2.581010
+1.287639  1.559567  1.903084  2.105175  2.450979  2.599458
+1.224033  1.507999  1.922793  2.076370  2.372907  2.581210
+1.163218  1.444961  1.734673  2.020179  2.322152  2.541566
+1.212255  1.448003  1.638494  2.031919  2.229345  2.399467
+1.108889  1.283327  1.481151  1.907068  2.100013  2.293484
+1.155218  1.290372  1.476717  1.688065  2.089220  2.181765
+1.171472  1.290390  1.556515  1.825992  2.018143  2.243494
+1.149886  1.282652  1.601900  1.745296  2.110780  2.409060
+1.223914  1.360718  1.650069  1.792936  2.265100  2.370934
+1.254374  1.404539  1.706674  1.854649  2.276473  2.394690
+1.225833  1.442107  1.766130  1.924123  2.292396  2.394677
+1.211141  1.461886  1.804549  1.927018  2.361986  2.453285
+1.218638  1.405782  1.809530  1.914204  2.318449  2.520048
+1.222942  1.394674  1.840107  1.932398  2.391674  2.503193
+1.206898  1.372866  1.842954  1.943799  2.424465  2.578763
+1.246306  1.423826  1.866209  1.962415  2.436055  2.595659
+1.270919  1.455901  1.888055  1.976335  2.469281  2.582811
+1.198265  1.323940  1.880236  1.949408  2.471659  2.644805
+1.174323  1.293200  1.765612  2.019282  2.282243  2.576238
+1.141730  1.383190  1.882826  2.126532  2.453044  2.611191
+1.483342  1.650728  2.043593  2.193798  2.517271  2.622915
+1.446069  1.621898  1.999609  2.103532  2.493478  2.581923
+1.414671  1.630237  1.945678  2.061773  2.500655  2.588950
+1.438432  1.615586  1.903350  2.013028  2.426105  2.613642
+1.556674  1.623119  1.875461  1.972308  2.366695  2.629218
+1.466504  1.638319  1.796576  1.959267  2.457617  2.603231
+1.308284  1.481394  1.730539  1.979266  2.332265  2.538090
+1.301646  1.413738  1.674441  1.933375  2.143487  2.508142
+1.318907  1.416559  1.751644  1.913438  2.294089  2.555125
+1.324509  1.425623  1.844923  1.947411  2.375384  2.597366
+1.266998  1.359728  1.849155  1.950839  2.370723  2.579301
+1.162697  1.344305  1.906935  1.986568  2.470580  2.583422
+1.115998  1.365829  1.948029  2.040077  2.461135  2.583597
+1.061798  1.350291  2.006280  2.080459  2.451632  2.526961
+1.024331  1.233571  1.989411  2.085049  2.387181  2.495816
+0.962287  1.219238  1.967000  2.089191  2.424659  2.599861
+0.881533  1.356828  2.047429  2.155394  2.409074  2.508754
+0.856010  1.217716  2.008528  2.111528  2.424806  2.537738
+0.774065  0.965055  1.874139  2.035878  2.251024  2.527966
+0.820344  0.990331  1.960958  2.242123  2.349553  2.535465
+0.846158  1.062894  1.972506  2.169152  2.353165  2.556086
+0.748812  1.063441  1.949952  2.066846  2.364509  2.602003
+0.855725  1.158383  2.008420  2.144140  2.328495  2.600481
+0.862076  1.188230  1.906456  2.191351  2.368506  2.542645
+0.814218  1.194007  2.086397  2.156864  2.482953  2.574777
+0.811087  1.320952  2.038259  2.112835  2.508878  2.598939
+0.967874  1.191718  2.049318  2.146525  2.422668  2.566778
+1.008026  1.234198  2.040908  2.121036  2.480150  2.609085
+1.118175  1.312265  1.961423  2.071245  2.409323  2.600531
+1.189338  1.302425  1.961961  2.063211  2.432115  2.545303
+1.253885  1.371226  1.931879  2.030140  2.387565  2.558949
+1.307301  1.398036  1.910989  2.006938  2.409438  2.577142
+1.330085  1.468465  1.908521  2.012222  2.418015  2.537683
+1.367992  1.492291  1.942021  2.036750  2.498866  2.581003
+1.368367  1.443433  1.947482  2.013180  2.486344  2.585241
+1.418284  1.496850  1.933442  2.024630  2.473682  2.594036
+1.443886  1.551220  1.904909  2.018103  2.456717  2.542868
+1.473689  1.587097  1.899829  2.079006  2.421501  2.584477
+1.424674  1.611334  1.974517  2.142720  2.402882  2.620760
+1.431487  1.622660  1.940232  2.125436  2.429652  2.581851
+1.484538  1.690581  1.921860  2.109101  2.474401  2.607828
+1.498136  1.751579  1.925730  2.039135  2.440519  2.616180
+1.505248  1.789182  1.994666  2.114126  2.408417  2.599889
+1.609869  1.793035  1.986226  2.160600  2.519572  2.593245
+1.562825  1.739913  1.974184  2.143221  2.539588  2.620088
+1.650259  1.723964  2.002949  2.150399  2.532100  2.600746
+1.584628  1.665482  1.833853  1.979658  2.511168  2.576182
+1.547562  1.665631  1.805111  1.930451  2.428670  2.548606
+1.499078  1.595123  1.700269  1.824190  2.376924  2.575480
+1.300837  1.552954  1.664576  1.791707  2.488304  2.561078
+1.168605  1.311953  1.668583  1.872905  2.413570  2.493285
+1.047458  1.249963  1.699886  1.914183  2.417032  2.496381
+0.948776  1.275594  1.738944  1.998684  2.312154  2.462020
+0.921081  1.311946  1.775244  1.895491  2.382160  2.528440
+0.811311  1.125217  1.745194  2.094737  2.326109  2.511883
+0.796518  1.060230  1.740129  2.060503  2.179506  2.385501
+0.868836  1.153353  1.792833  1.945638  2.125498  2.248001
+0.915536  1.218160  1.818910  2.068347  2.243402  2.348648
+0.966595  1.301606  1.895255  2.111957  2.248646  2.389247
+0.995849  1.442084  1.952071  2.066120  2.240125  2.338587
+1.056392  1.372214  1.984171  2.119327  2.271702  2.372743
+1.098400  1.324164  1.781533  2.082856  2.218804  2.344318
+1.039157  1.356474  1.820178  2.114625  2.346728  2.450389
+0.988689  1.293884  1.916348  2.088201  2.362497  2.481270
+1.104406  1.230679  1.939434  2.122401  2.254811  2.377705
+1.086105  1.174481  1.826346  2.111318  2.237689  2.471667
+1.069802  1.206486  1.845381  2.118634  2.471087  2.575405
+1.074963  1.342794  1.955309  2.147713  2.511467  2.589270
+1.149198  1.418813  1.887043  1.966968  2.472616  2.587246
+1.455749  1.669829  1.964104  2.175182  2.469990  2.605009
+1.418548  1.603566  1.964426  2.175678  2.466765  2.583333
+1.389392  1.601163  1.925746  2.131857  2.442025  2.574229
+1.415333  1.507338  1.911262  2.087139  2.535199  2.629580
+1.382483  1.453710  1.872292  1.955406  2.554343  2.658507
+1.392944  1.482296  1.838526  1.928577  2.473732  2.633718
+1.390456  1.463044  1.839906  1.922012  2.514942  2.698788
+1.339376  1.470118  1.858751  1.959522  2.539427  2.686382
+1.353776  1.541029  1.822546  2.022164  2.542215  2.677200
+1.350868  1.631877  1.918792  2.183528  2.501087  2.617310
+1.407644  1.669128  2.000740  2.224226  2.522804  2.634897
+1.433780  1.586913  1.999627  2.192922  2.535981  2.626121
+1.413876  1.639426  1.952196  2.170695  2.501106  2.610591
+1.505388  1.613685  1.991590  2.214459  2.487873  2.612841
+1.409245  1.563694  2.048043  2.154145  2.483727  2.642180
+1.411023  1.646699  1.983177  2.152550  2.568807  2.661248
+1.384745  1.603808  1.934487  2.141949  2.507642  2.630050
+1.366120  1.551337  1.999561  2.177467  2.489112  2.596761
+1.355542  1.635015  2.008420  2.162675  2.465273  2.661406
+1.453972  1.673697  2.037857  2.180201  2.615971  2.709278
+1.369538  1.696466  1.999789  2.084847  2.482775  2.666286
+1.349740  1.462313  1.966717  2.051722  2.472616  2.652615
+1.327312  1.437762  1.928517  2.006392  2.505810  2.658921
+1.341350  1.419153  1.921202  1.991463  2.530825  2.613585
+1.342697  1.505329  1.946926  2.029431  2.538224  2.635583
+1.392743  1.535099  1.936104  2.024567  2.527279  2.614258
+1.432564  1.543790  1.951854  2.049855  2.546244  2.623711
+1.452940  1.569432  1.932369  2.037247  2.558693  2.638096
+1.467999  1.597453  1.920306  2.018574  2.536219  2.622824
+1.486806  1.569654  1.875855  1.966065  2.536740  2.631905
+1.454618  1.578126  1.811620  1.974659  2.537513  2.606334
+1.418040  1.507665  1.783572  1.893001  2.551797  2.628991
+1.264140  1.474380  1.770586  1.898927  2.524762  2.594073
+1.118340  1.456671  1.734720  1.996589  2.412285  2.519146
+1.096432  1.603123  1.808391  2.012238  2.409620  2.544361
+0.976303  1.473740  1.759171  1.855828  2.412929  2.483947
+0.990184  1.390703  1.710711  1.831672  2.377092  2.454935
+1.056900  1.387366  1.783109  1.873514  2.401419  2.486425
+0.989786  1.452622  1.851566  1.945924  2.403454  2.482939
+1.112084  1.364820  1.770002  1.921998  2.290405  2.437297
+1.096250  1.336388  1.741855  1.968572  2.211613  2.362493
+1.000030  1.346185  1.704531  1.966852  2.277389  2.389374
+1.027901  1.174070  1.793005  2.026854  2.178200  2.387232
+1.056882  1.167504  1.861000  2.204421  2.351246  2.485631
+1.075972  1.226420  1.997644  2.196176  2.330099  2.494137
+1.147221  1.258128  1.958667  2.258550  2.387749  2.552119
+1.162811  1.290567  2.052795  2.201829  2.424621  2.560484
+1.147890  1.265733  2.025675  2.130794  2.496878  2.620259
+1.239563  1.315734  2.018377  2.123513  2.463946  2.569207
+1.181131  1.358942  1.942155  2.159833  2.458701  2.593961
+1.247455  1.386435  1.898250  1.999009  2.446020  2.542764
+1.227695  1.504889  1.817998  1.908019  2.213334  2.552228
+1.201972  1.577872  1.771276  1.873354  2.061263  2.535817
+1.306230  1.516310  1.819234  1.923423  2.382025  2.582568
+1.505719  1.585654  1.949330  2.046203  2.448307  2.615962
+1.623749  1.698728  2.009543  2.108007  2.461522  2.647903
+1.690861  1.764294  2.036097  2.175502  2.515253  2.616822
+1.715336  1.828294  2.078551  2.252209  2.483666  2.607649
+1.659970  1.807170  1.975009  2.255594  2.481341  2.589617
+1.734824  1.850216  2.012044  2.276744  2.519359  2.608181
+1.635768  1.862548  1.956456  2.328743  2.568869  2.632471
+1.616355  1.825398  1.949523  2.281216  2.560861  2.641804
+1.592472  1.804360  1.927158  2.167339  2.577510  2.646873
+1.606484  1.895095  1.983153  2.112452  2.477608  2.576959
+1.708493  1.835068  1.966711  2.127238  2.427571  2.543077
+1.691093  1.889580  1.986069  2.206774  2.522399  2.601798
+1.702442  1.902120  2.076380  2.216219  2.484843  2.603543
+1.329491  1.542588  1.875436  2.105532  2.385234  2.536630
+1.321384  1.474161  1.932268  2.152505  2.374420  2.506710
+1.277750  1.458580  1.963094  2.182377  2.417003  2.558654
+1.208016  1.418710  2.009739  2.138531  2.396782  2.554506
+1.198910  1.299925  1.983625  2.150128  2.296124  2.505944
+1.250344  1.361156  2.010558  2.195944  2.340984  2.500873
+1.308664  1.585162  2.106341  2.214164  2.402673  2.635894
+1.330165  1.494630  2.141901  2.235810  2.459582  2.649465
+1.296306  1.434105  2.098086  2.204131  2.355208  2.600113
+1.309619  1.402978  1.892542  2.184955  2.333605  2.513160
+1.269067  1.491839  1.958963  2.174572  2.324689  2.543667
+1.434975  1.628849  1.981273  2.247282  2.476397  2.593980
+1.459644  1.650080  2.024368  2.267723  2.546314  2.675203
+1.381486  1.703195  2.138905  2.295559  2.545762  2.642527
+1.441842  1.700585  2.197906  2.276293  2.468211  2.694954
+1.539669  1.999668  2.206532  2.351484  2.651231  2.734825
+1.589576  1.926407  2.173457  2.256196  2.633242  2.707677
+1.434262  1.859373  2.141950  2.211447  2.511783  2.628376
+1.326814  1.596573  2.024769  2.115813  2.426136  2.609340
+1.229072  1.325550  1.838698  2.013045  2.471300  2.639281
+1.230813  1.329059  1.872619  1.964510  2.444752  2.594694
+1.193705  1.426297  1.898594  2.039364  2.502714  2.581046
+1.175637  1.473287  1.912423  2.002740  2.476222  2.606851
+1.099269  1.443896  1.892457  1.997567  2.522081  2.611086
+1.113739  1.439098  1.912268  2.000476  2.462769  2.559343
+1.085510  1.469634  1.914465  2.064613  2.427917  2.512412
+1.052481  1.501205  1.918797  1.999794  2.493684  2.571708
+1.043597  1.331616  1.927947  1.989186  2.445730  2.578082
+1.051981  1.200390  1.938627  2.026811  2.446750  2.629884
+0.978672  1.083042  1.868777  2.133583  2.430141  2.580267
+0.904772  1.105214  1.960566  2.064948  2.362564  2.604875
+0.859439  1.084629  1.901705  2.033000  2.276166  2.574716
+0.948943  1.043554  1.855644  2.050857  2.444431  2.661478
+0.974338  1.126459  1.927321  2.020910  2.455487  2.559782
+0.995629  1.175887  1.937743  2.013680  2.378974  2.617290
+1.001312  1.224390  1.901702  1.976467  2.425878  2.574844
+0.985969  1.282601  1.886614  2.032451  2.455957  2.599528
+0.927590  1.320448  1.924006  2.012174  2.498308  2.599681
+1.007942  1.383963  1.921628  2.007624  2.507570  2.607500
+0.972512  1.446775  1.920365  2.013492  2.490207  2.576492
+0.951123  1.452036  1.889861  1.987269  2.421483  2.562217
+0.924342  1.369953  1.851744  1.942740  2.475661  2.544282
+0.882605  1.301666  1.850813  2.032498  2.364632  2.541824
+0.933888  1.368996  1.943109  2.023849  2.405442  2.530330
+0.927916  1.112379  1.847430  1.979093  2.255596  2.563992
+1.031936  1.249132  1.833165  1.925221  2.310315  2.520141
+0.934046  1.239886  1.909603  2.008149  2.372869  2.548965
+0.984297  1.220031  1.823788  1.947602  2.264359  2.478653
+0.933366  1.278980  1.860469  1.942999  2.289801  2.465670
+0.983115  1.227707  1.842104  2.047699  2.272651  2.531979
+0.953311  1.245822  1.849685  1.945142  2.289569  2.572282
+0.994609  1.303464  1.868144  1.971560  2.372435  2.585257
+0.986061  1.364094  1.852132  1.917821  2.435113  2.633873
+0.975486  1.248848  1.848797  1.934434  2.402023  2.574203
+1.008388  1.304679  1.804310  1.888508  2.369473  2.598230
+0.999393  1.329937  1.901438  1.994378  2.397503  2.504548
+0.922186  1.321538  1.851082  1.962056  2.382159  2.472985
+0.897224  1.382187  1.780842  1.921734  2.359590  2.448091
+0.859516  1.447371  1.732311  1.881193  2.295231  2.380849
+0.986347  1.601641  1.752386  1.966362  2.314384  2.459101
+1.265264  1.616535  1.811273  2.097139  2.371242  2.550361
+1.318958  1.600426  1.755641  2.029814  2.329188  2.493144
+1.209901  1.470135  1.670187  1.970732  2.416208  2.523420
+1.122232  1.308395  1.457114  1.720231  2.384259  2.470421
+1.077675  1.245511  1.366478  1.664281  2.327344  2.419196
+1.075445  1.228131  1.365376  1.558947  2.238585  2.324563
+1.044502  1.215785  1.325993  1.645187  2.148642  2.225749
+0.955863  1.150609  1.283133  1.492306  2.177576  2.266677
+0.909204  1.045108  1.166160  1.320593  2.215965  2.352846
+0.960368  1.103540  1.278352  1.467726  2.260152  2.460237
+1.010220  1.186777  1.290055  1.578425  2.388733  2.500317
+1.020144  1.135718  1.239343  1.388838  2.438182  2.563922
+1.082493  1.206954  1.347455  1.490039  2.404819  2.494617
+1.144114  1.278638  1.434725  1.567887  2.322768  2.424800
+1.274296  1.348789  1.515602  1.632221  2.360105  2.552789
+1.301328  1.390629  1.638492  1.764907  2.347961  2.576115
+1.358515  1.444452  1.724492  1.843715  2.478143  2.574552
+1.399712  1.513306  1.791713  1.902169  2.495815  2.581592
+1.448866  1.534750  1.821506  1.931492  2.517823  2.622859
+1.438398  1.530057  1.831437  1.999329  2.531929  2.623280
+1.511918  1.581087  1.927484  2.041399  2.573287  2.663469
+1.535380  1.608310  1.924231  2.048796  2.546746  2.681650
+1.544368  1.620413  1.980425  2.068130  2.477398  2.626652
+1.558461  1.643007  2.024613  2.121014  2.451868  2.639494
+1.524202  1.613947  2.005898  2.115477  2.429090  2.663085
+1.504519  1.590381  1.966356  2.072628  2.376901  2.621094
+1.439395  1.512336  1.950354  2.058564  2.276407  2.573036
+1.315215  1.400050  1.854752  1.957633  2.246197  2.576501
+1.288117  1.488904  1.945571  2.024839  2.439848  2.605685
+1.436278  1.667254  2.056847  2.146443  2.548238  2.661743
+1.417389  1.819841  2.083572  2.220278  2.606693  2.690863
+1.373599  1.963014  2.144565  2.274057  2.547389  2.638900
+1.320367  1.918635  2.063208  2.237723  2.415847  2.517654
+1.223778  1.619753  1.890594  2.107915  2.520999  2.629701
+1.018748  1.427668  1.917566  2.001782  2.435507  2.564351
+1.026252  1.377048  1.949170  2.039209  2.393769  2.530053
+1.009988  1.472847  1.998049  2.079876  2.484961  2.553950
+1.053267  1.468372  2.016120  2.129309  2.456623  2.564128
+1.101072  1.355268  2.010441  2.107467  2.395605  2.537748
+1.132796  1.391658  2.016574  2.114099  2.497623  2.585099
+1.173305  1.443009  1.970633  2.104863  2.447883  2.535937
+1.209478  1.384097  1.972240  2.069587  2.457494  2.573686
+1.242419  1.453561  1.983731  2.068419  2.471041  2.593609
+1.320388  1.463651  1.997825  2.082334  2.472034  2.605892
+1.389516  1.477732  1.978692  2.094038  2.480170  2.644445
+1.413743  1.526085  1.963751  2.113919  2.403846  2.654427
+1.519419  1.592852  1.919458  2.024494  2.301172  2.668892
+1.513663  1.600129  1.922007  2.105104  2.278322  2.523416
+1.481852  1.659944  1.913552  2.049439  2.272255  2.493787
+1.567545  1.659167  1.930647  2.071517  2.312595  2.564270
+1.550890  1.677657  1.863928  2.010128  2.223475  2.520007
+1.572772  1.683020  1.863047  2.002198  2.320378  2.560791
+1.621943  1.734050  1.920642  2.062932  2.335107  2.576252
+1.631487  1.697136  1.952883  2.056578  2.459627  2.652858
+1.594706  1.671490  1.936091  2.013301  2.430776  2.669632
+1.601444  1.668704  1.945495  2.037168  2.503369  2.682121
+1.587570  1.664898  1.944621  2.032989  2.569757  2.703408
+1.556417  1.631245  1.930707  2.040513  2.453873  2.665177
+1.487851  1.565634  1.892869  2.011729  2.393945  2.647118
+1.406012  1.520184  1.791646  1.987880  2.289334  2.602762
+1.358221  1.436040  1.818480  1.957084  2.309801  2.605784
+1.309339  1.405329  1.835697  2.076369  2.340807  2.613062
+1.303792  1.415614  1.985149  2.129488  2.469355  2.643119
+1.358952  1.437733  1.988826  2.127374  2.537981  2.656471
+1.333866  1.480460  1.950069  2.122437  2.431168  2.587133
+1.384528  1.539708  1.964093  2.130549  2.510449  2.652805
+1.412625  1.544436  1.947280  2.173185  2.593018  2.716637
+1.433269  1.539892  2.004125  2.201951  2.515051  2.635244
+1.447580  1.554019  2.128269  2.240167  2.470753  2.657077
+1.480647  1.609898  2.097964  2.167566  2.473701  2.700702
+1.607823  1.675959  2.023409  2.146384  2.426913  2.636247
+1.643303  1.717783  2.060655  2.197557  2.415413  2.614329
+1.737392  1.816967  2.039362  2.219707  2.422999  2.623531
+1.694258  1.799366  2.042600  2.280098  2.418626  2.583273
+1.556188  1.831866  1.985355  2.207899  2.471677  2.630819
+1.421150  1.803896  1.984581  2.123513  2.438200  2.522496
+1.327444  1.668870  1.888433  2.029945  2.224455  2.461746
+1.109824  1.562199  1.862663  1.977860  2.139552  2.328644
+1.233875  1.580797  1.854187  2.021788  2.193504  2.355917
+1.207537  1.568638  1.872908  1.986671  2.137938  2.487653
+1.179978  1.625946  1.900003  2.008135  2.231660  2.594349
+1.469842  1.717204  1.875670  2.024433  2.325463  2.488422
+1.641097  1.809779  1.926763  2.062053  2.414037  2.542900
+1.648803  1.734123  1.966905  2.086726  2.354475  2.498840
+1.605468  1.689394  2.010048  2.114211  2.407628  2.527066
+1.520887  1.628733  1.977005  2.086771  2.340162  2.489336
+1.503816  1.600587  2.039010  2.130377  2.396482  2.513742
+1.437817  1.545316  2.043931  2.188366  2.356821  2.521449
+1.445398  1.549208  1.982213  2.096659  2.328629  2.462126
+1.416417  1.504357  1.973772  2.080427  2.393479  2.543532
+1.425822  1.528083  1.995729  2.162530  2.440693  2.562510
+1.394274  1.473952  2.043537  2.149086  2.432979  2.549080
+1.373755  1.476048  2.043903  2.160251  2.345351  2.501882
+1.370183  1.443588  2.092872  2.178103  2.413056  2.590595
+1.320393  1.466374  2.036782  2.137812  2.435621  2.578912
+1.286926  1.393325  2.060733  2.200945  2.500015  2.582353
+1.323391  1.421794  2.058500  2.153930  2.495548  2.638088
+1.295313  1.393216  2.004420  2.138189  2.526374  2.641535
+1.230979  1.355132  2.047369  2.156418  2.522379  2.664129
+1.233755  1.308524  1.939495  2.097348  2.487349  2.649836
+1.227589  1.355101  1.875835  1.977538  2.319288  2.575191
+1.227369  1.507108  1.853515  2.022894  2.212431  2.576493
+1.152896  1.470513  1.830430  1.954309  2.331452  2.533253
+1.336656  1.650185  1.779214  2.043424  2.444821  2.539640
+1.455824  1.582937  2.022254  2.176680  2.481340  2.592664
+1.437625  1.556245  2.081454  2.174959  2.482445  2.614573
+1.416470  1.620886  2.033007  2.157073  2.462925  2.601588
+1.376304  1.551493  2.117213  2.198338  2.416190  2.605635
+1.442804  1.657855  2.127088  2.206301  2.344857  2.578113
+1.368110  1.538734  2.060199  2.198045  2.366884  2.622242
+1.346445  1.428338  1.980453  2.126605  2.283275  2.530611
+1.304592  1.373259  1.923523  2.096362  2.239964  2.508433
+1.298027  1.371594  1.954971  2.107512  2.349707  2.545570
+1.307177  1.416169  1.980337  2.064455  2.389102  2.588444
+1.279296  1.390782  1.959784  2.090687  2.436145  2.612606
+1.317020  1.415866  1.921874  2.071794  2.463821  2.616221
+1.294309  1.412297  1.916195  2.019201  2.484708  2.611341
+1.310051  1.407774  1.853169  2.009907  2.466493  2.645013
+1.341298  1.422330  1.885156  1.967813  2.483863  2.626324
+1.428263  1.526125  1.885115  1.978529  2.499386  2.603389
+1.501165  1.580511  1.847282  2.000494  2.465952  2.608868
+1.538510  1.625396  1.813916  1.950057  2.522899  2.620472
+1.566628  1.639602  1.771792  1.878749  2.541764  2.663693
+1.543435  1.647821  1.748616  1.822597  2.434677  2.631280
+1.623389  1.680917  1.759152  1.844539  2.521467  2.653611
+1.574857  1.663719  1.767780  1.869740  2.453335  2.658218
+1.558309  1.661251  1.793844  1.895130  2.261873  2.572330
+1.543680  1.627756  1.817671  1.921282  2.432997  2.653342
+1.493536  1.575657  1.805687  1.939448  2.470642  2.665081
+1.440050  1.513838  1.832212  1.937802  2.530248  2.702867
+1.319101  1.506232  1.823485  1.931612  2.539554  2.676703
+1.307271  1.563371  1.847930  1.951724  2.251818  2.453220
+1.336405  1.661596  1.828825  1.988331  2.189506  2.354248
+1.342922  1.598751  1.784739  1.915122  2.109991  2.450644
+1.336704  1.646363  1.800742  1.891215  2.235913  2.558506
+1.311763  1.500014  1.830220  1.945042  2.430387  2.644578
+1.266113  1.431962  1.858757  2.059148  2.590485  2.674762
+1.317779  1.419948  1.916462  2.124820  2.574729  2.668476
+1.341519  1.436167  1.968421  2.097444  2.572787  2.685098
+1.305930  1.438859  1.933746  2.036080  2.569070  2.656417
+1.279130  1.406473  1.943094  2.031719  2.530080  2.630882
+1.286005  1.410029  1.969688  2.040243  2.448573  2.651374
+1.257538  1.391063  1.966565  2.039208  2.402422  2.646794
+1.224386  1.352129  1.931370  2.006343  2.456203  2.696151
+1.296292  1.488099  1.996948  2.068189  2.594535  2.695842
+1.334566  1.607716  1.922141  2.163161  2.545921  2.679970
+1.381781  1.646772  2.037640  2.204087  2.545791  2.639326
+1.416818  1.628929  2.045931  2.209348  2.523853  2.675794
+1.431463  1.694802  1.998932  2.159531  2.522928  2.664749
+1.384236  1.622936  2.036943  2.115706  2.528893  2.633929
+1.403832  1.558362  2.027347  2.138015  2.562774  2.659379
+1.390591  1.671936  2.017942  2.164595  2.592820  2.683609
+1.357527  1.553759  2.023137  2.212306  2.420463  2.558257
+1.301715  1.465816  2.052932  2.215957  2.420685  2.548524
+1.339331  1.597053  2.035156  2.145819  2.509602  2.644137
+1.346088  1.633870  2.006920  2.114724  2.570026  2.688879
+1.358438  1.501669  1.949578  2.027633  2.479635  2.637460
+1.427991  1.533690  1.853629  1.960806  2.437544  2.588461
+1.507003  1.585812  1.864642  1.950265  2.478769  2.624546
+1.535154  1.619477  1.784602  1.926332  2.537152  2.665799
+1.499658  1.574823  1.685832  1.822553  2.533986  2.705306
+1.585485  1.642424  1.721846  1.846735  2.524494  2.710346
+1.167359  1.627213  1.768394  1.853039  2.265556  2.540517
+1.110320  1.506953  1.805632  1.881807  2.361271  2.589961
+1.066434  1.539420  1.746305  1.936119  2.127988  2.461181
+1.110995  1.565351  1.852078  1.960462  2.214924  2.497897
+1.116118  1.590687  1.879184  1.969081  2.323294  2.532966
+1.148401  1.557455  1.819964  1.963793  2.380344  2.484532
+1.092558  1.569815  1.784004  1.959241  2.324259  2.468490
+1.212996  1.578928  1.751637  1.901569  2.271773  2.386093
+1.123979  1.626268  1.758062  1.983762  2.291127  2.408000
+1.075785  1.534831  1.784777  2.041940  2.236695  2.368112
+1.118783  1.415693  1.971932  2.122755  2.330245  2.440458
+1.016087  1.334517  1.899204  2.121574  2.425143  2.543872
+1.066196  1.289419  1.948157  2.081946  2.471493  2.593822
+1.064989  1.255756  1.935973  2.036951  2.493176  2.612753
+1.049670  1.228450  1.829530  2.025060  2.431071  2.670840
+1.019627  1.313583  1.880313  1.953952  2.491693  2.642660
+1.153477  1.551900  1.909752  2.133530  2.540066  2.626465
+1.293030  1.600480  2.035687  2.166885  2.572967  2.658261
+1.409308  1.624144  1.993621  2.268493  2.527057  2.651858
+1.426397  1.681509  2.039405  2.215283  2.559060  2.681401
+1.422045  1.752644  2.027991  2.231432  2.546485  2.631238
+1.403067  1.735547  2.007077  2.202109  2.635543  2.718353
+1.364124  1.687363  2.011927  2.293629  2.640697  2.705256
+1.328058  1.608269  1.989851  2.364958  2.590564  2.689451
+1.333592  1.644867  2.130503  2.308577  2.644140  2.732807
+1.405236  1.665965  2.123365  2.315861  2.656941  2.732874
+1.435372  1.679544  2.019100  2.254404  2.596082  2.674056
+1.041025  1.476515  1.923322  2.290557  2.592337  2.673623
+0.818396  1.189747  2.051367  2.233382  2.417100  2.622567
+0.745703  1.240251  2.139256  2.224179  2.476418  2.558791
+0.786217  1.296744  2.004359  2.245816  2.548718  2.631400
+0.781573  1.122340  1.875748  2.277284  2.459421  2.557207
+0.697586  1.327149  2.097985  2.173556  2.574671  2.693605
+0.773107  1.393007  1.971171  2.270220  2.591495  2.651543
+0.799951  1.252666  1.928383  2.211233  2.577718  2.683817
+0.737528  1.237907  1.827160  2.110526  2.476303  2.627671
+0.896067  1.421355  1.841161  2.104821  2.432869  2.585719
+0.920446  1.418578  1.943416  2.252701  2.491235  2.623110
+0.905094  1.284731  1.843688  2.269109  2.479541  2.595905
+1.049549  1.447497  1.841173  2.160358  2.575747  2.655700
+1.282800  1.445416  1.901230  2.290173  2.581640  2.678726
+1.174710  1.517021  1.867926  2.176617  2.547483  2.640154
+1.241259  1.518496  1.936773  2.208770  2.521322  2.619833
+1.321929  1.540199  1.998528  2.205769  2.605663  2.707912
+1.303802  1.622926  1.880392  2.189485  2.588909  2.669966
+1.360827  1.658553  1.903323  2.178010  2.554280  2.634772
+1.385461  1.623312  1.959095  2.257739  2.605390  2.694616
+1.467954  1.628168  2.003097  2.348920  2.596096  2.674558
+1.411837  1.691393  1.947010  2.259218  2.526145  2.615112
+1.415256  1.697464  2.003104  2.284290  2.526236  2.643365
+1.365343  1.610187  2.022103  2.171703  2.557595  2.642236
+1.343948  1.630769  2.040836  2.261714  2.477921  2.647359
+1.333580  1.630378  2.031205  2.210871  2.504057  2.623327
+1.344121  1.704685  2.065813  2.192571  2.541365  2.658520
+1.439884  1.666588  2.082726  2.206006  2.636341  2.699174
+1.344355  1.655936  2.026852  2.227832  2.565868  2.661265
+1.299677  1.585295  1.961552  2.231139  2.599559  2.677599
+1.184434  1.441654  1.888542  2.255409  2.554664  2.625508
+1.446570  1.792548  2.022664  2.179214  2.497160  2.591115
+1.464682  1.809276  2.060194  2.205446  2.545963  2.641910
+1.481290  1.729523  2.025686  2.250012  2.537459  2.667746
+1.476458  1.657788  2.008062  2.249201  2.503220  2.613116
+1.386264  1.589548  2.031702  2.218301  2.509210  2.619100
+1.386263  1.662864  2.052585  2.208677  2.488387  2.623049
+1.438117  1.646070  1.967818  2.212439  2.508718  2.629395
+1.437599  1.590230  2.089082  2.184453  2.566546  2.677847
+1.367022  1.652527  2.084373  2.169492  2.483600  2.655744
+1.403779  1.701337  2.062797  2.148537  2.443186  2.657250
+1.399193  1.706047  2.062427  2.144585  2.531224  2.635014
+1.409664  1.750569  2.005073  2.087238  2.602834  2.694068
+1.430153  1.760399  2.048802  2.118059  2.569383  2.657275
+1.418847  1.858926  2.018666  2.141412  2.597867  2.671139
+1.515040  1.815611  1.942165  2.089059  2.554645  2.634597
+1.420031  1.740119  1.953746  2.196133  2.502692  2.639749
+1.384099  1.723309  1.901165  2.160196  2.426618  2.522583
+1.341050  1.737372  1.894752  2.110869  2.407505  2.502838
+1.375756  1.553983  1.784274  1.981423  2.504116  2.571526
+1.414589  1.520552  1.715365  2.013015  2.511199  2.608636
+1.384971  1.519108  1.696689  1.939377  2.575701  2.644752
+1.377861  1.611683  1.751236  2.044564  2.493605  2.567974
+1.360853  1.553679  1.693976  2.036113  2.535885  2.588469
+1.391629  1.489335  1.631480  1.853083  2.529546  2.631825
+1.364077  1.476053  1.629040  1.949019  2.525741  2.587922
+1.243896  1.398594  1.539687  2.066323  2.528653  2.592221
+1.255509  1.429357  1.548843  1.950985  2.519984  2.574845
+1.213331  1.388798  1.505976  1.886640  2.486118  2.545361
+1.125797  1.286903  1.534946  1.982051  2.490209  2.570684
+1.132522  1.296198  1.460831  1.925246  2.355670  2.444037
+1.146734  1.365341  1.496067  2.020613  2.448334  2.510650
+1.192778  1.378937  1.491161  1.959258  2.459140  2.519716
+1.271605  1.383883  1.525856  1.953206  2.473140  2.526275
+1.199948  1.366094  1.519729  1.926772  2.562989  2.623739
+1.236017  1.383510  1.510394  1.793300  2.585490  2.677079
+1.277218  1.416561  1.539447  1.923790  2.599080  2.667723
+1.195957  1.408063  1.568713  2.090793  2.622180  2.668897
+1.174436  1.300805  1.706567  2.070327  2.332828  2.490999
+1.120253  1.252790  1.562102  2.057117  2.357857  2.488099
+1.176325  1.291966  1.760265  2.093355  2.395545  2.591528
+1.197722  1.415532  1.801926  2.033180  2.459620  2.592560
+1.170462  1.491249  1.888044  2.082479  2.392285  2.528149
+1.083509  1.491779  1.949458  2.046197  2.422471  2.591609
+1.059936  1.417978  1.954816  2.073246  2.480964  2.599125
+0.939633  1.348507  2.005684  2.094229  2.474051  2.580294
+0.849679  1.293534  1.998123  2.105266  2.410101  2.615907
+0.886534  1.432349  1.990451  2.089797  2.379083  2.539500
+0.973462  1.473622  1.944390  2.051837  2.393100  2.468610
+1.041989  1.576432  1.952733  2.062536  2.326319  2.437768
+1.048696  1.543946  1.799024  2.015259  2.415911  2.487382
+1.060745  1.463281  1.792003  1.940494  2.417438  2.517618
+1.086879  1.350511  1.715443  1.804481  2.481994  2.577240
+1.237763  1.487227  1.724896  1.808323  2.528530  2.614554
+1.398461  1.499585  1.705939  1.817865  2.537422  2.611149
+1.461839  1.549278  1.719489  1.835184  2.480052  2.656622
+1.411934  1.594838  1.722617  1.840214  2.536598  2.618705
+1.527085  1.609472  1.704839  1.832817  2.512769  2.605081
+1.549304  1.649714  1.747183  1.838847  2.593282  2.681523
+1.408650  1.622130  1.797760  1.950766  2.238972  2.463941
+1.463558  1.647961  1.790731  1.921407  2.348044  2.572625
+1.531892  1.700373  1.834041  2.005597  2.413477  2.570542
+1.595204  1.681563  1.857023  2.020177  2.475381  2.620261
+1.578383  1.651863  1.912263  2.011994  2.512496  2.625607
+1.551105  1.644360  1.936207  2.041608  2.527321  2.617243
+1.531973  1.623150  1.927602  2.007454  2.528038  2.634563
+1.492463  1.579493  1.908682  1.998228  2.490609  2.583094
+1.445430  1.548758  1.913697  2.002797  2.519245  2.610948
+1.397285  1.482251  1.891220  1.983837  2.474487  2.607776
+1.358299  1.562942  1.902050  2.003614  2.425639  2.585407
+1.313352  1.518886  1.923066  2.011942  2.496939  2.583703
+1.321679  1.506830  1.903064  1.990064  2.510610  2.619736
+1.272893  1.513437  1.897901  2.039656  2.536517  2.604144
+1.255738  1.431150  1.896619  1.960886  2.526746  2.624236
+1.253559  1.392826  1.893788  1.975079  2.520685  2.596673
+1.212336  1.375220  1.860311  1.964962  2.531189  2.598668
+1.177442  1.324186  1.806632  1.885288  2.487316  2.595463
+1.184996  1.383080  1.783224  1.863469  2.466568  2.570648
+1.162268  1.444731  1.797884  1.960244  2.515838  2.594432
+1.293132  1.612625  1.912866  2.113069  2.467202  2.592647
+1.354402  1.698025  1.960114  2.149465  2.532985  2.652695
+1.412069  1.729124  2.034085  2.172945  2.538810  2.643693
+1.391792  1.801757  1.944790  2.194546  2.467300  2.547714
+1.476077  1.743192  1.982548  2.141155  2.559049  2.642891
+1.423680  1.857196  1.998407  2.146989  2.499501  2.583857
+1.420678  1.878169  2.012321  2.298282  2.578266  2.665489
+1.455663  1.910540  2.069836  2.393055  2.593493  2.679808
+1.525575  1.925713  2.186470  2.400715  2.660126  2.743114
+1.376147  1.633438  1.934297  2.250493  2.494057  2.618970
+1.354498  1.560950  1.931259  2.207320  2.500701  2.611053
+1.308071  1.569512  1.967243  2.245460  2.461123  2.595512
+1.347009  1.654983  1.980907  2.251887  2.510089  2.634977
+1.478008  1.588438  2.038202  2.224140  2.499366  2.646631
+1.451530  1.630286  2.114101  2.249734  2.416504  2.651801
+1.412137  1.655832  2.128349  2.224639  2.525056  2.681740
+1.374504  1.848893  2.140832  2.291897  2.602827  2.691005
+1.378568  1.744853  2.106673  2.201221  2.626831  2.711996
+1.082739  1.603117  2.070774  2.129571  2.504286  2.657551
+1.013288  1.467910  1.960032  2.091788  2.362049  2.561554
+0.994100  1.328068  1.791699  1.902549  2.410628  2.501324
+0.999159  1.325245  1.722310  1.871377  2.281177  2.502088
+1.035282  1.338082  1.653023  1.759760  2.441464  2.540672
+1.077126  1.293589  1.565666  1.711796  2.330341  2.436256
+1.058117  1.243026  1.488328  1.623677  2.330121  2.429536
+1.150659  1.296201  1.574724  1.701839  2.390475  2.507354
+1.167918  1.382035  1.573815  1.795297  2.440653  2.490361
+1.221368  1.405075  1.535783  1.728642  2.412290  2.519375
+1.248273  1.383975  1.572280  1.826858  2.425352  2.494218
+1.274149  1.386267  1.557821  1.734106  2.378306  2.477968
+1.343890  1.456032  1.668535  1.815600  2.248744  2.419705
+1.356022  1.559300  1.731279  1.853333  2.343968  2.514760
+1.433214  1.575906  1.673186  1.781463  2.292800  2.491264
+1.354708  1.637604  1.875368  2.162870  2.408490  2.566375
+1.464664  1.591442  2.071219  2.235462  2.398887  2.563489
+1.424812  1.622646  2.020332  2.161315  2.328264  2.468190
+1.364274  1.516152  2.011760  2.109608  2.395705  2.554722
+1.342677  1.460516  2.038898  2.122976  2.506655  2.643449
+1.338308  1.519884  2.030044  2.100145  2.533338  2.674767
+1.321127  1.545574  1.977232  2.122268  2.557592  2.680218
+1.315091  1.467109  1.972429  2.068538  2.526845  2.645634
+1.304457  1.400689  1.954545  2.053140  2.562504  2.685886
+1.267182  1.376660  1.888057  2.029893  2.545417  2.669311
+1.225012  1.339338  1.887320  1.965236  2.543506  2.672285
+1.226210  1.403527  1.797664  1.959693  2.540988  2.627346
+1.347025  1.607942  1.966769  2.184515  2.477879  2.608821
+1.332099  1.755961  1.948416  2.176713  2.513390  2.601370
+1.349288  1.781404  1.922794  2.109230  2.462878  2.559863
+1.362379  1.693594  1.884339  2.088053  2.522473  2.613966
+1.320290  1.510299  1.857749  2.065435  2.494726  2.605564
+1.282991  1.459743  1.744910  1.961419  2.439941  2.623746
+1.251365  1.381919  1.673542  1.772697  2.323540  2.661592
+1.204256  1.435153  1.654230  1.737800  2.305057  2.581558
+1.181960  1.465280  1.670027  1.861303  2.444123  2.546129
+1.347122  1.628258  1.931339  2.123429  2.466851  2.598918
+1.170479  1.284934  1.552741  1.832546  2.299787  2.519811
+1.190040  1.284015  1.646086  1.969170  2.496917  2.620449
+1.255411  1.381474  1.781732  2.094994  2.431362  2.593520
+1.231880  1.334167  1.796249  2.040002  2.387081  2.554655
+1.180520  1.308571  1.818239  1.976323  2.293501  2.451796
+1.102564  1.266319  1.844247  1.961761  2.324841  2.514083
+1.004636  1.144874  1.835019  1.997102  2.182380  2.522076
+0.956994  1.212915  1.940923  2.060449  2.312226  2.441670
+0.795434  1.444280  1.932418  2.047161  2.365680  2.450523
+0.942462  1.606038  2.025121  2.119735  2.299947  2.431814
+0.812186  1.469389  2.078323  2.173021  2.391967  2.474051
+0.831008  1.620609  2.092943  2.167732  2.334863  2.416721
+0.917049  1.800997  2.121233  2.199383  2.347284  2.440519
+0.857286  1.679152  2.112428  2.203072  2.444738  2.529211
+0.809582  1.542552  2.182369  2.239437  2.461979  2.543366
+0.912283  1.779198  2.166321  2.251092  2.461682  2.576876
+0.774827  1.770199  2.179196  2.239611  2.487323  2.560225
+1.222989  1.574575  2.081078  2.223587  2.501523  2.661302
+1.394216  1.696320  2.036647  2.273328  2.570400  2.684130
+1.370771  1.698913  2.082660  2.245671  2.598794  2.695446
+1.372406  1.647175  2.142373  2.272905  2.608093  2.686558
+1.342788  1.694536  2.123284  2.256762  2.575277  2.690952
+1.380553  1.750680  2.123405  2.199744  2.488043  2.610243
+1.395056  1.883317  2.088702  2.189488  2.458258  2.548140
+1.413151  1.872836  2.020835  2.161956  2.396167  2.487013
+1.403097  1.764242  1.911249  2.055851  2.391006  2.484601
+1.250592  1.606846  1.834805  1.914414  2.344090  2.549461
+1.171007  1.406438  1.699124  1.858102  2.354073  2.471053
+1.132691  1.251867  1.521350  1.638290  2.355284  2.470608
+1.011681  1.287897  1.450262  1.663822  2.285463  2.371452
+1.030244  1.208417  1.366673  1.550352  2.337520  2.421401
+0.964915  1.171185  1.288162  1.588419  2.327292  2.388297
+0.953674  1.102888  1.263755  1.835591  2.316855  2.424820
+0.886544  1.074635  1.242245  1.964445  2.296815  2.412946
+0.853009  1.077083  1.184534  1.752324  2.283038  2.389217
+0.840278  1.033222  1.152546  1.520954  2.333984  2.454533
+0.910770  1.083873  1.223537  1.668076  2.346235  2.511845
+0.967915  1.121818  1.220258  1.806588  2.421129  2.498176
+0.992265  1.169069  1.260049  1.679990  2.398939  2.459143
+1.065276  1.230957  1.322385  1.753477  2.314399  2.415925
+1.081305  1.271782  1.458008  1.729400  2.332304  2.405121
+1.017815  1.349087  1.515836  1.721892  2.292963  2.398991
+1.097652  1.332937  1.570030  1.776462  2.377274  2.465894
+1.147644  1.302495  1.640156  1.797044  2.363880  2.474795
+1.127168  1.322009  1.684884  1.796463  2.407050  2.578659
+1.159532  1.266652  1.709552  1.830584  2.438156  2.572425
+1.137105  1.331512  1.749399  1.846000  2.414391  2.511488
+1.121271  1.351105  1.728223  1.846664  2.449211  2.564158
+1.118680  1.261543  1.794458  1.885767  2.429009  2.552772
+1.076991  1.212163  1.727637  1.861263  2.432992  2.564041
+1.082093  1.261697  1.760917  1.858031  2.315851  2.573591
+1.086353  1.279061  1.763123  1.864186  2.380786  2.485297
+0.988401  1.262393  1.737901  1.836710  2.375780  2.492390
+1.074712  1.196202  1.677279  1.806309  2.341401  2.560642
+1.067864  1.265290  1.689350  1.802993  2.401947  2.524062
+1.010475  1.289540  1.652721  1.778727  2.362305  2.466551
+0.977570  1.261308  1.576271  1.741327  2.297622  2.404091
+1.097180  1.464421  1.606664  1.717614  2.330709  2.412068
+1.383838  1.652270  1.898203  2.096608  2.476719  2.574183
+1.279735  1.700611  1.894987  2.029873  2.468395  2.584491
+1.236668  1.683312  1.791059  1.953368  2.533100  2.587084
+1.185052  1.599131  1.853897  1.944925  2.499951  2.572896
+1.163573  1.307316  1.872443  1.953987  2.544667  2.623228
+1.190969  1.449255  1.863288  1.937666  2.525272  2.599969
+1.118547  1.513105  1.856666  1.968822  2.497385  2.575529
+1.156521  1.630926  1.845452  2.051106  2.443167  2.534052
+1.410042  1.541981  2.135508  2.235609  2.575406  2.680553
+1.392791  1.720666  2.034946  2.192456  2.487154  2.653398
+1.581248  1.837838  2.109761  2.187484  2.497898  2.660089
+1.663078  1.901302  2.151665  2.248289  2.534789  2.639793
+1.623160  1.843067  2.177770  2.255312  2.543601  2.681190
+1.539709  1.846069  2.119080  2.315024  2.605425  2.695012
+1.532691  1.805362  2.166180  2.276515  2.582080  2.695324
+1.517203  1.864729  2.111840  2.241033  2.602399  2.678593
+1.481004  1.879771  2.183398  2.258504  2.624580  2.714706
+1.480064  1.947829  2.126591  2.239313  2.602703  2.689760
+1.615747  2.025678  2.188405  2.291472  2.673701  2.723276
+1.546688  2.023668  2.137583  2.233880  2.563573  2.627361
+1.517274  1.902434  2.132410  2.189277  2.548379  2.643352
+1.498762  1.602359  2.159933  2.275665  2.540579  2.682962
+1.573572  1.655201  2.071740  2.214602  2.523447  2.642142
+1.601993  1.680362  2.130147  2.247308  2.567706  2.670568
+1.632928  1.733671  2.134699  2.255127  2.559994  2.682076
+1.707428  1.752059  2.139704  2.252060  2.567637  2.647910
+1.680790  1.812582  2.189235  2.287297  2.578245  2.644737
+1.746130  1.778548  2.119511  2.283392  2.596379  2.686826
+1.680242  1.774944  2.097848  2.213994  2.558507  2.656276
+1.698158  1.777690  2.096918  2.211009  2.512421  2.625627
+1.757218  1.828197  2.092183  2.218630  2.459897  2.653906
+1.768299  1.815758  2.044601  2.174404  2.469800  2.674385
+1.740913  1.830010  2.044499  2.168426  2.442501  2.587668
+1.728988  1.801586  2.036902  2.135694  2.483000  2.647346
+1.740200  1.780349  2.039841  2.116482  2.460078  2.666408
+1.679167  1.810585  1.976200  2.085150  2.330970  2.574697
+1.675383  1.741676  1.986605  2.086988  2.444839  2.648385
+1.605366  1.684640  1.977146  2.084309  2.401376  2.626669
+1.593589  1.667011  1.993079  2.095793  2.477055  2.660517
+1.495436  1.677492  1.915438  2.107516  2.504100  2.687519
+1.371193  1.581007  1.812088  2.159971  2.540808  2.654514
+1.308897  1.652762  1.877696  2.100223  2.498357  2.635266
+1.257546  1.701192  1.908659  2.063978  2.330876  2.588480
+1.260641  1.733829  1.901311  2.046022  2.230421  2.379709
+1.192017  1.695443  1.866332  1.969861  2.131279  2.367813
+1.331300  1.727619  1.875686  1.967226  2.115488  2.461652
+1.221851  1.644785  1.861070  1.957289  2.263788  2.509227
+1.297010  1.684814  1.825106  1.981266  2.388696  2.497940
+1.292992  1.621691  1.795497  1.891584  2.430941  2.597238
+1.293338  1.412441  1.678427  2.013436  2.406265  2.575295
+1.355250  1.470521  1.748288  2.044830  2.411070  2.590823
+1.352085  1.474384  1.811950  2.028535  2.445376  2.597977
+1.380432  1.472981  1.836191  1.957768  2.390372  2.571170
+1.417568  1.514975  1.839991  1.974610  2.382486  2.510706
+1.396329  1.511621  1.743909  2.009524  2.414088  2.533502
+1.355999  1.511197  1.775041  1.973539  2.445398  2.568851
+1.357482  1.533305  1.820633  1.998326  2.395457  2.573696
+1.244544  1.446552  1.726849  1.935995  2.428985  2.555947
+1.206555  1.365874  1.510017  1.809039  2.464853  2.520241
+1.204707  1.340270  1.477154  1.731800  2.461076  2.525822
+1.152135  1.294762  1.429873  1.669780  2.436091  2.504828
+1.122329  1.284669  1.445441  1.811897  2.444467  2.535691
+1.167102  1.311995  1.430682  1.931216  2.579180  2.626367
+1.140963  1.255562  1.416924  1.913114  2.462643  2.552650
+1.175380  1.325094  1.434137  1.826282  2.534111  2.599692
+1.152952  1.311344  1.428753  1.733281  2.499163  2.555417
+1.208942  1.318147  1.450855  1.631131  2.484793  2.560756
+1.214984  1.312305  1.496973  1.602685  2.441060  2.513740
+1.154899  1.274352  1.497828  1.611080  2.493972  2.628464
+1.221737  1.324479  1.529355  1.668502  2.496342  2.572455
+1.265483  1.360436  1.574447  1.698291  2.465872  2.529454
+1.299969  1.411470  1.634331  1.790167  2.464188  2.546209
+1.296816  1.461296  1.674047  1.867297  2.472828  2.546532
+1.319231  1.493029  1.702922  1.867177  2.417583  2.503853
+1.307703  1.511731  1.795464  1.988697  2.415827  2.502063
+1.341439  1.567295  1.849636  2.054411  2.368545  2.484938
+1.346092  1.709857  1.847822  2.089875  2.320388  2.426929
+1.351207  1.582397  1.853947  2.087781  2.269740  2.406134
+1.403409  1.681258  1.930634  2.064741  2.317595  2.445510
+1.303563  1.800429  1.946546  2.064780  2.347899  2.575654
+1.401968  1.795117  2.043851  2.149158  2.337423  2.475421
+1.486349  1.896915  2.033679  2.164583  2.427213  2.516709
+1.581223  1.920360  2.032925  2.186636  2.458825  2.534175
+1.623672  1.949219  2.056949  2.220873  2.544733  2.612737
+1.720081  1.916335  2.069658  2.310061  2.503085  2.592652
+1.652066  1.993905  2.122170  2.282322  2.533728  2.604129
+1.696384  1.990268  2.088659  2.317899  2.562346  2.630795
+1.688613  1.976549  2.085500  2.354425  2.483404  2.567677
+1.791891  1.956617  2.084765  2.344129  2.473213  2.578020
+1.770146  1.955967  2.075143  2.263105  2.508576  2.594808
+1.688172  1.958387  2.097165  2.237127  2.443133  2.558386
+1.614095  1.858106  1.996129  2.151245  2.327315  2.485345
+1.517662  1.729778  1.975388  2.118726  2.390828  2.523423
+1.576388  1.764916  1.937347  2.159436  2.354537  2.476553
+1.596523  1.796717  1.930679  2.173774  2.415264  2.515193
+1.598274  1.758907  1.941525  2.242941  2.461919  2.548378
+1.564588  1.667806  1.910211  2.207508  2.432969  2.562295
+1.502258  1.598757  1.701036  1.993517  2.431658  2.568611
+1.261165  1.379257  1.669436  1.864259  2.424394  2.560278
+1.183142  1.291685  1.496242  1.775091  2.415349  2.571850
+1.176858  1.280643  1.397295  1.556275  2.482609  2.556911
+1.151406  1.269090  1.402613  1.529417  2.547298  2.660723
+1.138350  1.270088  1.386698  1.656508  2.516680  2.570828
+1.167637  1.288387  1.379397  1.815954  2.488744  2.544025
+1.191129  1.318584  1.433056  1.898734  2.440995  2.505523
+1.231547  1.339710  1.505832  1.865461  2.401919  2.567552
+1.249001  1.342543  1.526521  1.644629  2.260060  2.528113
+1.292116  1.385043  1.567293  1.928018  2.343597  2.526727
+1.553055  1.731196  1.875584  2.037623  2.189580  2.433617
+1.556332  1.807351  2.009873  2.134758  2.395110  2.517757
+1.700800  1.862996  2.016062  2.212872  2.465828  2.576608
+1.744516  1.892300  2.042875  2.203697  2.393022  2.529386
+1.614682  1.867043  2.024132  2.172368  2.402152  2.567866
+1.662548  1.926469  2.016222  2.153675  2.544682  2.636605
+1.607737  1.840632  2.036507  2.148869  2.475726  2.623423
+1.542603  1.789412  1.988210  2.133702  2.500071  2.623838
+1.520491  1.854019  1.966284  2.100229  2.465497  2.590987
+1.429100  1.726203  1.958566  2.068736  2.397125  2.578275
+1.230963  1.483915  1.909424  2.037168  2.278162  2.442677
+1.165473  1.402475  1.877668  1.985029  2.337001  2.482301
+1.060649  1.341795  1.891591  1.997803  2.342252  2.473851
+1.045982  1.264410  1.892878  2.028108  2.265711  2.418342
+0.872467  1.318607  1.941288  2.054895  2.265976  2.523000
+0.878165  1.208778  1.863524  2.074171  2.319885  2.460496
+0.871380  1.050930  1.866310  2.044293  2.184267  2.469225
+0.814866  1.206234  1.936241  2.046364  2.243986  2.391005
+0.791495  1.154802  1.950862  2.062225  2.270188  2.497120
+0.734873  1.117496  2.013891  2.146348  2.252079  2.340218
+0.717596  1.113315  2.145116  2.214288  2.350660  2.437091
+0.747897  1.181886  1.982640  2.073387  2.391063  2.461216
+0.814210  1.593704  1.930814  2.051889  2.279916  2.450975
+1.007998  1.635254  1.848698  1.998294  2.264960  2.399367
+1.058125  1.548258  1.725115  1.885874  2.174154  2.386746
+1.065325  1.446828  1.763113  2.061160  2.393931  2.533355
+1.245436  1.513106  1.699869  1.885972  2.163732  2.412556
+1.402218  1.550167  1.679097  2.104476  2.314265  2.464617
+1.439688  1.565541  1.746159  2.175756  2.353179  2.445969
+1.282789  1.467574  1.689789  2.057017  2.299566  2.506538
+1.157513  1.360077  1.531522  1.931682  2.277828  2.387362
+1.127719  1.287186  1.421085  1.844362  2.281074  2.385221
+1.172511  1.317506  1.497831  1.768329  2.327099  2.453399
+1.215615  1.351452  1.554622  1.706859  2.280267  2.410315
+1.162714  1.318505  1.568816  1.757107  2.225559  2.321236
+1.221146  1.364069  1.728202  1.867240  2.149636  2.323430
+1.274525  1.455876  1.651807  1.929882  2.119518  2.245371
+1.324827  1.466657  1.837727  1.982753  2.167839  2.294890
+1.207408  1.463737  1.907228  2.010942  2.187613  2.315377
+1.197505  1.325369  1.903945  2.104257  2.264375  2.406017
+0.964658  1.421326  1.800591  2.075541  2.249667  2.391422
+0.900184  1.419486  1.860531  2.052169  2.204670  2.414730
+0.976462  1.444988  1.837158  1.997086  2.133567  2.303194
+0.943062  1.543803  1.914625  1.993134  2.184650  2.344182
+0.896780  1.426973  1.923545  2.039994  2.257922  2.504524
+0.957615  1.553177  1.862682  2.044650  2.192655  2.484166
+1.024381  1.626871  1.891283  2.041787  2.304775  2.613132
+1.260699  1.570977  1.796922  1.938909  2.457980  2.543689
+1.433872  1.676893  2.020354  2.249287  2.488434  2.619226
+1.427791  1.605308  1.999841  2.197618  2.472581  2.628257
+1.344936  1.547750  2.019906  2.153463  2.482519  2.664904
+1.394553  1.830863  2.075753  2.146704  2.529848  2.662938
+1.393531  1.579984  2.005267  2.068322  2.595828  2.677955
+1.371670  1.501665  2.012362  2.069292  2.605716  2.701205
+1.365970  1.443760  1.893696  2.063362  2.540864  2.635754
+1.392813  1.470933  1.920415  1.985276  2.612047  2.670626
+1.393576  1.502340  1.926492  2.019514  2.571540  2.645701
+1.331438  1.470056  1.844344  1.945539  2.527331  2.620827
+1.280394  1.379998  1.822792  1.927676  2.470720  2.614037
+1.230446  1.394851  1.772237  1.910697  2.494879  2.569172
+1.103766  1.420997  1.742156  1.901028  2.458527  2.544960
+1.070834  1.438456  1.754789  1.827791  2.323725  2.484121
+1.023924  1.522342  1.713716  1.834742  2.289596  2.496846
+1.123843  1.539945  1.766275  1.866623  2.349980  2.441218
+1.046667  1.496581  1.791535  1.859477  2.400747  2.468296
+1.031227  1.504904  1.714267  1.944348  2.365219  2.459437
+1.201184  1.370120  1.882630  2.011333  2.411295  2.510294
+1.249461  1.324457  1.907616  2.059001  2.448619  2.551408
+1.308584  1.403015  1.961155  2.048592  2.475709  2.562469
+1.354357  1.476040  2.008730  2.111323  2.513237  2.591557
+1.415309  1.559632  2.020191  2.107847  2.505348  2.596462
+1.452150  1.536961  2.033461  2.120472  2.473458  2.600239
+1.476159  1.570668  1.981439  2.089874  2.441733  2.574939
+1.532138  1.607322  1.996255  2.099111  2.448993  2.575083
+1.578251  1.670901  1.946452  2.067931  2.484573  2.596033
+1.645992  1.719829  1.908426  2.034805  2.521504  2.630135
+1.675204  1.739089  1.858009  1.951150  2.549621  2.668138
+1.698801  1.740674  1.816221  1.872214  2.552990  2.675039
+1.589313  1.665941  1.751972  1.834254  2.495821  2.663916
+1.443571  1.535057  1.685496  1.788025  2.391781  2.644852
+1.389394  1.597558  1.884291  2.161052  2.453631  2.577281
+1.344693  1.573396  1.949051  2.033207  2.436483  2.650227
+1.340679  1.442192  1.904082  1.992387  2.427510  2.604339
+1.301569  1.363519  1.870210  1.953388  2.445808  2.609366
+1.265637  1.365516  1.838660  1.922174  2.431739  2.552480
+1.291868  1.451067  1.770742  1.900677  2.380488  2.474590
+1.319797  1.502062  1.686208  1.922008  2.291200  2.392613
+1.253224  1.445797  1.591748  1.893558  2.295028  2.381503
+1.171375  1.370630  1.523209  1.825821  2.336350  2.399182
+1.238986  1.365086  1.486833  1.790131  2.302513  2.384222
+1.186490  1.327527  1.463687  1.680778  2.322037  2.402246
+1.160765  1.294904  1.467635  1.613241  2.219663  2.329651
+1.167970  1.312269  1.458793  1.725469  2.182513  2.270653
+1.160491  1.371381  1.546645  1.859914  2.151480  2.267109
+1.060643  1.447736  1.589363  1.762026  2.187949  2.312538
+1.096873  1.449372  1.669939  1.880786  2.205157  2.322919
+0.965471  1.394985  1.664859  1.869740  2.130135  2.272101
+0.992815  1.276232  1.736324  1.883127  2.198488  2.291947
+0.989087  1.348989  1.869284  1.945029  2.217100  2.329616
+0.905850  1.296468  1.839413  1.984491  2.131357  2.261643
+0.913468  1.347104  1.974941  2.056808  2.233065  2.312403
+0.891335  1.518146  1.956057  2.017051  2.234247  2.369537
+0.838007  1.490697  2.017641  2.097784  2.331456  2.417972
+0.918242  1.411219  2.047094  2.157938  2.312207  2.414304
+0.737470  1.475335  2.131705  2.195099  2.336065  2.410088
+0.804454  1.247009  2.183193  2.253103  2.376866  2.457474
+0.910989  1.120584  2.031279  2.134740  2.301672  2.401323
+0.823657  1.023714  1.899299  2.153486  2.278157  2.468898
+0.820197  0.968457  1.655670  2.137310  2.320413  2.442552
+0.901009  1.047635  1.785794  2.126322  2.248142  2.419219
+0.908944  1.151536  1.941268  2.153759  2.287775  2.477861
+1.022921  1.329810  1.973526  2.121196  2.269160  2.496929
+1.008035  1.176565  1.832554  2.130737  2.263094  2.484071
+1.148404  1.261617  1.868165  2.138339  2.287914  2.475774
+1.131641  1.245536  1.746902  2.127206  2.273644  2.439518
+1.105449  1.230686  1.759865  2.023222  2.225896  2.485020
+1.232277  1.363476  1.914876  2.021647  2.314039  2.455927
+1.287966  1.377464  1.853658  2.039634  2.348077  2.502708
+1.285144  1.520789  1.951021  2.053636  2.366537  2.486110
+1.276358  1.656613  1.882329  2.084625  2.430619  2.524004
+1.305701  1.532539  1.861534  2.029161  2.435632  2.519577
+1.295725  1.474840  1.838375  2.045012  2.413018  2.545296
+1.232802  1.307215  1.786758  1.911450  2.533633  2.625793
+1.106012  1.252432  1.737311  1.827401  2.395470  2.658026
+1.080321  1.249736  1.763810  1.842229  2.488083  2.637970
+1.084809  1.302696  1.791104  1.915712  2.532753  2.626979
+1.024077  1.398495  1.758154  1.947685  2.536753  2.647797
+1.052552  1.486524  1.835972  2.013128  2.526539  2.621519
+0.980943  1.528894  1.887706  1.990429  2.559226  2.631730
+0.954706  1.355188  1.890849  1.968743  2.538301  2.645803
+0.894853  1.316420  1.931923  2.000630  2.617822  2.706960
+0.859848  1.166660  1.851854  2.011085  2.629872  2.731061
+0.817565  1.169139  1.975684  2.117069  2.593136  2.683713
+0.776768  0.999874  1.951669  2.126997  2.578530  2.719218
+0.750075  1.105669  2.015241  2.099156  2.469178  2.637879
+0.878438  1.039620  2.078822  2.189100  2.453168  2.610618
+0.915136  1.114879  2.017689  2.236527  2.370275  2.538277
+0.826110  1.208983  2.069074  2.156825  2.331864  2.463067
+0.869876  1.289563  2.061703  2.143050  2.313737  2.395809
+0.790056  1.421058  1.945728  2.025231  2.254924  2.384106
+0.782642  1.678142  1.928308  1.980152  2.169702  2.290020
+0.795940  1.409661  1.767797  1.894756  2.191648  2.280190
+0.832117  1.169093  1.828013  1.911028  2.228646  2.366162
+0.862231  1.189399  1.754948  1.924129  2.312126  2.412551
+1.034774  1.290469  1.783502  1.996158  2.343760  2.462730
+1.135806  1.358791  1.789192  1.980630  2.376359  2.495841
+1.303901  1.414996  1.787505  1.918440  2.435463  2.547746
+1.489246  1.592963  1.850578  1.950051  2.428039  2.571337
+1.631472  1.742640  1.887885  1.994933  2.493769  2.619665
+1.683853  1.800379  1.926611  2.064050  2.509149  2.592626
+1.745313  1.854259  1.988545  2.117137  2.504306  2.611340
+1.764270  1.890575  2.037993  2.174299  2.507724  2.600610
+1.680174  1.817366  1.937110  2.228976  2.550139  2.623314
+1.552625  1.819462  1.957322  2.263495  2.517281  2.580506
+1.558425  1.784912  2.021491  2.239374  2.543712  2.637456
+1.240665  1.739293  1.889814  2.105082  2.532436  2.618228
+0.928972  1.440269  1.769258  1.853352  2.400406  2.636877
+1.055767  1.488842  1.756065  1.832574  2.209682  2.650309
+1.013301  1.381032  1.704087  1.772713  2.155486  2.585135
+1.009186  1.333235  1.741382  1.846496  2.158765  2.517761
+1.006381  1.519900  1.813751  1.916290  2.407674  2.581853
+1.357730  1.530547  1.883639  2.141513  2.463268  2.614627
+1.426823  1.560875  1.882518  2.175206  2.488354  2.628703
+1.315984  1.579838  1.859556  2.083481  2.419884  2.564645
+1.213050  1.538899  1.800250  1.882067  2.341570  2.574606
+1.275056  1.543507  1.917099  2.127451  2.388939  2.542721
+1.438943  1.698143  1.856610  2.075189  2.266712  2.437372
+1.454331  1.663763  1.869820  2.011414  2.366272  2.533385
+1.382166  1.672920  1.827442  1.942032  2.453906  2.559856
+1.400656  1.585453  1.841334  2.002744  2.426997  2.517756
+1.382144  1.688087  1.819756  2.063153  2.417793  2.492551
+1.255095  1.603378  1.753915  2.047569  2.455562  2.569585
+1.134783  1.409147  1.705283  1.802106  2.488030  2.647140
+1.111876  1.260129  1.676050  1.778495  2.501588  2.627003
+1.060347  1.208811  1.660354  1.776864  2.488758  2.604456
+0.947120  1.164647  1.642037  1.723789  2.475156  2.567411
+0.902077  1.251204  1.664026  1.769008  2.499003  2.576704
+0.920170  1.243894  1.709681  1.794989  2.534352  2.623833
+0.938770  1.267684  1.725861  1.870157  2.549512  2.628197
+0.914357  1.254315  1.712915  1.784742  2.590431  2.707485
+0.930246  1.281241  1.802793  1.878861  2.560218  2.687216
+0.955350  1.148671  1.814732  1.902586  2.557821  2.684594
+0.968330  1.098589  1.813440  1.911875  2.463136  2.646490
+0.990311  1.185444  1.864673  1.941589  2.488112  2.664465
+1.186903  1.590929  1.954158  2.033697  2.597861  2.662179
+1.302643  1.694423  1.997444  2.169046  2.617414  2.693079
+1.379258  1.718278  1.993219  2.212202  2.543730  2.640859
+1.405165  1.780534  1.997893  2.151147  2.555776  2.632215
+1.297766  1.878255  2.020268  2.190566  2.546467  2.617338
+1.442158  1.856645  2.101038  2.299709  2.561481  2.644123
+1.370167  1.781207  2.114991  2.251821  2.446751  2.549845
+1.403451  1.703568  2.079302  2.221399  2.448766  2.593978
+1.413349  1.649169  2.009976  2.159164  2.518675  2.615138
+1.326655  1.719941  1.950443  2.025468  2.521068  2.635953
+1.385954  1.552749  1.856784  1.937506  2.496646  2.580159
+1.345409  1.488014  1.885538  2.017189  2.546874  2.625597
+1.335716  1.420210  1.787067  1.976842  2.501334  2.643553
+1.303803  1.408266  1.801454  1.901471  2.375048  2.575946
+1.312907  1.408086  1.837981  1.950093  2.318536  2.475897
+1.193613  1.293642  1.819061  1.974492  2.468077  2.585285
+1.191527  1.311470  1.711629  1.854585  2.395044  2.554024
+1.103176  1.332165  1.717922  1.857994  2.340287  2.445217
+0.996011  1.234172  1.751022  1.868274  2.285877  2.406723
+1.055311  1.378240  1.712116  1.841673  2.206702  2.440537
+1.078611  1.465910  1.787009  1.948977  2.231741  2.478981
+0.984520  1.420593  1.815304  1.925218  2.263433  2.430940
+0.984574  1.495178  1.774189  1.964126  2.221656  2.346849
+1.154842  1.507200  1.812101  1.949371  2.281741  2.426097
+1.170058  1.429376  1.745091  1.937927  2.235016  2.374769
+1.206485  1.487526  1.767298  2.009836  2.207048  2.339471
+1.073656  1.377733  1.828679  1.993004  2.130615  2.256776
+1.088454  1.495385  1.907767  1.996871  2.213903  2.390489
+1.122976  1.422213  1.865827  2.037113  2.253747  2.418388
+1.134166  1.382636  1.804236  1.963200  2.161170  2.473602
+1.245397  1.552607  1.960811  2.134690  2.453597  2.577539
+1.118704  1.567208  1.952615  2.176519  2.446630  2.578556
+1.141708  1.643603  2.013339  2.277434  2.557381  2.634785
+1.392514  1.807925  2.039343  2.237922  2.578023  2.668286
+1.433212  1.833712  2.020620  2.252182  2.518635  2.600857
+1.379262  1.712226  2.024999  2.242965  2.515533  2.602479
+1.366984  1.675637  1.976590  2.199474  2.516967  2.598815
+1.352760  1.801872  2.033607  2.181935  2.491382  2.589883
+1.323663  1.743572  2.009640  2.122701  2.474517  2.566379
+1.190092  1.540538  1.933066  2.088076  2.506726  2.570608
+1.519832  1.766187  1.906004  2.076747  2.261416  2.407680
+1.534691  1.714074  2.016476  2.130902  2.323259  2.457608
+1.522050  1.794760  2.050945  2.218278  2.408013  2.537728
+1.665365  1.906867  2.025658  2.232383  2.430131  2.550641
+1.666299  1.834650  1.998042  2.220240  2.401507  2.502391
+1.523608  1.730092  1.862962  2.164599  2.466262  2.549229
+1.216124  1.503465  1.760462  1.967473  2.381720  2.564350
+1.171128  1.429428  1.616628  1.917782  2.387933  2.477271
+1.091303  1.351374  1.568657  1.796196  2.437587  2.514874
+1.001277  1.386906  1.539603  1.775045  2.413270  2.482152
+0.952227  1.397307  1.527926  1.722524  2.442747  2.492370
+0.824979  1.388886  1.568976  1.735264  2.408751  2.471180
+0.794444  1.433059  1.588848  1.749579  2.489366  2.576364
+0.899067  1.521851  1.681397  1.780293  2.441748  2.508286
+0.922249  1.464613  1.592525  1.828442  2.418162  2.477264
+0.871556  1.444421  1.538321  1.889009  2.353691  2.412544
+0.857823  1.270248  1.501265  1.760257  2.355761  2.407297
+0.846263  1.176606  1.481984  1.614166  2.369933  2.485687
+0.882414  1.176092  1.377969  1.497390  2.380010  2.516508
+0.938718  1.100648  1.489109  1.576205  2.325566  2.543468
+0.932462  1.105586  1.294346  1.470956  2.400120  2.554718
+0.945253  1.161000  1.303877  1.580262  2.466680  2.584612
+1.018317  1.214740  1.330580  1.683749  2.482961  2.557157
+1.048240  1.175481  1.258095  1.599087  2.521448  2.642499
+1.073739  1.203513  1.298705  1.688758  2.555683  2.614473
+1.096788  1.260856  1.368595  1.755340  2.493034  2.606453
+1.105643  1.227026  1.404391  1.849702  2.523314  2.601568
+1.143864  1.269393  1.387340  1.829083  2.395167  2.496463
+1.099246  1.228614  1.344408  1.664420  2.440626  2.518066
+1.116181  1.228322  1.332947  1.667312  2.331673  2.512262
+1.201517  1.299388  1.478475  1.577915  2.003307  2.451583
+1.167995  1.292729  1.470730  1.814621  2.140965  2.436146
+1.280521  1.424881  1.595211  1.803880  2.205832  2.315376
+1.230157  1.364939  1.610435  2.002513  2.172872  2.355721
+1.302555  1.400606  1.734329  2.074003  2.208548  2.389274
+1.512686  1.818227  2.144783  2.266917  2.447736  2.569392
+1.507528  1.760422  2.164228  2.276872  2.479494  2.624837
+1.446511  1.760436  2.114696  2.256700  2.572570  2.661468
+1.468868  1.812355  2.114567  2.193023  2.617745  2.713842
+1.449647  1.776448  2.080604  2.210155  2.540909  2.713991
+1.441252  1.719517  2.114612  2.218690  2.511304  2.660049
+1.477657  1.619839  2.112699  2.198704  2.520599  2.655696
+1.532866  1.718145  2.132629  2.222301  2.551440  2.665729
+1.341030  1.814584  2.125039  2.245863  2.547976  2.649591
+1.361910  1.698086  2.076920  2.255113  2.524884  2.647043
+1.315333  1.592772  2.109776  2.210194  2.517745  2.666968
+1.382801  1.571593  2.106842  2.204058  2.495197  2.661417
+1.453626  1.641746  2.100313  2.199368  2.462404  2.608881
+1.376104  1.646574  1.987188  2.218409  2.413618  2.526810
+1.372839  1.632461  2.056237  2.163721  2.376186  2.586874
+1.432614  1.624632  2.074174  2.119889  2.480656  2.669026
+1.410683  1.662804  2.069219  2.130369  2.581373  2.714005
+1.174126  1.524516  2.032046  2.105255  2.502385  2.653307
+1.150832  1.249780  2.004788  2.158226  2.317980  2.588167
+1.057643  1.199724  2.043666  2.165479  2.371022  2.608171
+1.070330  1.169192  2.051065  2.187195  2.476449  2.671328
+0.989962  1.100883  1.959715  2.107656  2.451860  2.659328
+0.995945  1.125081  1.967729  2.171051  2.352755  2.586378
+0.951054  1.073408  1.768679  2.213097  2.362509  2.504270
+0.912647  1.063629  1.874306  2.209354  2.347793  2.515052
+0.880146  1.057702  1.939506  2.298197  2.447874  2.559719
+0.808391  0.999903  1.789456  2.221085  2.383243  2.512098
+0.872797  1.051306  1.907981  2.345885  2.551438  2.620384
+0.736864  0.925226  2.101552  2.273865  2.392948  2.568863
+0.704727  1.026198  2.094726  2.212489  2.474164  2.656197
+0.793545  1.029482  1.901019  2.333682  2.650248  2.721424
+0.890709  1.270067  2.139854  2.238320  2.544384  2.711324
+0.971655  1.317691  2.245472  2.351092  2.631963  2.711259
+1.080789  1.555771  2.010618  2.245992  2.528408  2.644890
+1.409512  1.769321  2.106696  2.284262  2.512254  2.638336
+1.248437  1.661986  2.035140  2.283241  2.534287  2.647326
+0.952460  1.123797  2.103484  2.258075  2.394744  2.604571
+0.989645  1.181656  2.023429  2.237371  2.369517  2.522527
+0.926042  1.348117  1.949341  2.062080  2.346962  2.449077
+0.919696  1.405301  1.834047  2.099696  2.376206  2.493394
+1.000811  1.371649  1.836653  2.224095  2.410108  2.539296
+1.200088  1.436788  1.839151  2.179281  2.398849  2.498430
+1.223520  1.486412  1.943988  2.252258  2.407325  2.540679
+1.113671  1.477208  1.844163  2.218008  2.381333  2.486877
+1.138107  1.498752  1.980951  2.297474  2.457848  2.560767
+1.146154  1.614539  1.898903  2.232476  2.416572  2.510958
+1.119673  1.589916  1.824415  2.111914  2.354760  2.453276
+1.032037  1.589416  1.852847  2.142988  2.324001  2.472943
+0.989427  1.528982  1.914645  2.179193  2.376737  2.494371
+1.095755  1.494564  1.866122  2.136805  2.283713  2.464058
+0.834557  1.463722  1.882565  2.150927  2.378636  2.463091
+0.835589  1.296069  1.771371  2.098776  2.286243  2.426378
+0.806577  1.403328  1.685216  2.040945  2.235736  2.356401
+0.800011  1.383092  1.814158  1.959934  2.309583  2.386791
+0.804745  1.318210  1.821360  1.908703  2.235131  2.427141
+0.895849  1.367225  1.864812  1.979670  2.324237  2.420788
+0.827390  1.425085  1.767158  2.058185  2.376232  2.469430
+0.917915  1.497920  1.855338  1.987207  2.315382  2.451640
+0.940855  1.409563  1.789190  1.988531  2.336666  2.534686
+0.972711  1.291697  1.786937  1.914881  2.323264  2.405491
+0.993281  1.368817  1.807237  1.958622  2.357274  2.459276
+1.074694  1.349312  1.840844  1.954844  2.269081  2.384056
+1.100597  1.218573  1.756134  1.900188  2.277874  2.406215
+1.165622  1.313695  1.843695  1.962222  2.157100  2.342911
+1.157768  1.372357  1.879963  1.991928  2.258080  2.390865
+1.286092  1.780986  1.959702  2.118874  2.324541  2.437595
+1.455169  1.738149  2.098885  2.235010  2.428464  2.539714
+1.500252  1.684257  2.161002  2.272591  2.399078  2.510334
+1.485672  1.846402  2.195717  2.305655  2.546282  2.650594
+1.727818  2.013707  2.167283  2.304214  2.586608  2.652160
+1.676773  1.960528  2.217006  2.368813  2.598284  2.681624
+1.631959  1.915752  2.227040  2.335178  2.603101  2.710218
+1.663857  1.973017  2.124709  2.222354  2.660483  2.724322
+1.542011  1.929582  2.075601  2.170628  2.628551  2.707745
+1.509689  1.706046  2.056908  2.197674  2.578326  2.653903
+1.482072  1.673728  2.131047  2.194868  2.586319  2.690293
+1.423447  1.643267  2.092317  2.178941  2.527205  2.636748
+1.355154  1.565169  2.023932  2.236487  2.538323  2.655495
+1.328421  1.553976  2.081558  2.161922  2.472742  2.656928
+1.330758  1.419042  2.026707  2.129051  2.367999  2.571017
+1.270648  1.377593  2.025948  2.140131  2.389237  2.575945
+1.236825  1.345428  2.022395  2.109848  2.478126  2.633911
+1.222076  1.320425  1.939670  2.021742  2.436807  2.628532
+1.252172  1.358274  1.972621  2.079346  2.371453  2.598928
+1.266234  1.470203  1.930446  2.145813  2.471858  2.618153
+1.332281  1.546411  2.025723  2.219524  2.464616  2.645111
+1.418604  1.649476  2.008305  2.128114  2.489878  2.676868
+1.455677  1.684682  1.988976  2.152647  2.470396  2.651526
+1.447490  1.600650  1.935900  2.271764  2.512990  2.631833
+1.444770  1.556361  2.020377  2.282318  2.475768  2.612336
+1.387476  1.487406  2.024679  2.244659  2.445046  2.582829
+1.353922  1.443279  1.957555  2.171307  2.336106  2.560084
+1.369786  1.447714  2.006181  2.191416  2.404713  2.604727
+1.425956  1.504279  2.072312  2.178177  2.417663  2.603411
+1.440235  1.540501  2.082397  2.211979  2.377070  2.637315
+1.497010  1.582681  2.056522  2.172175  2.389278  2.593845
+1.504963  1.584564  1.984094  2.149333  2.367563  2.559723
+1.519045  1.603989  1.993800  2.109929  2.327255  2.599694
+1.569559  1.651048  1.988942  2.116726  2.345772  2.569917
+1.569894  1.683682  1.980575  2.182917  2.357234  2.587282
+1.607074  1.712704  1.951468  2.125681  2.307168  2.547246
+1.645231  1.736599  1.952360  2.131487  2.376223  2.606463
+1.669612  1.763984  1.979653  2.173233  2.332349  2.516667
+1.632436  1.758871  1.980800  2.124271  2.285899  2.443828
+1.557406  1.667695  1.902055  2.106931  2.260859  2.483917
+1.470421  1.688945  1.846379  2.032834  2.185130  2.375868
+1.421944  1.531479  1.825667  2.026592  2.180382  2.360115
+1.385644  1.606158  1.846365  2.071388  2.488500  2.607454
+1.359715  1.577664  1.897105  2.111958  2.471108  2.603005
+1.339447  1.542640  1.933966  2.133741  2.454906  2.583194
+1.325808  1.691761  2.080233  2.164213  2.474164  2.605215
+1.347146  1.624704  2.074108  2.214395  2.430593  2.562946
+1.314857  1.541837  1.967631  2.164145  2.372693  2.606516
+1.312898  1.534081  1.917285  2.089949  2.411610  2.570672
+1.283019  1.557401  1.937879  2.103338  2.520615  2.623700
+1.138825  1.337472  1.871092  1.972746  2.433484  2.647653
+1.155936  1.281125  1.831346  1.919243  2.266602  2.600943
+1.166841  1.273824  1.843198  1.946026  2.318377  2.578792
+1.172291  1.275007  1.832581  2.025917  2.353813  2.624686
+1.082157  1.265436  1.892357  1.989008  2.383161  2.601421
+1.091903  1.208823  1.835009  2.034461  2.394722  2.562904
+1.098835  1.199487  1.757650  2.065888  2.390403  2.578893
+1.132798  1.244386  1.876625  2.071549  2.339183  2.537916
+1.180603  1.259469  1.823163  2.095055  2.256898  2.542724
+1.186987  1.312908  1.800793  2.105036  2.366989  2.496082
+1.266390  1.377139  1.810434  2.113272  2.329619  2.533152
+1.323586  1.404515  1.904242  2.145928  2.386113  2.580936
+1.352171  1.451401  1.949824  2.077051  2.390820  2.538573
+1.343859  1.452231  1.889889  2.026744  2.317477  2.482486
+1.244808  1.378854  1.792557  1.986745  2.422571  2.536950
+1.124619  1.253596  1.703825  1.951315  2.439640  2.545147
+0.995104  1.411750  1.728505  1.861639  2.456605  2.544957
+1.001072  1.409106  1.797727  1.897572  2.409482  2.555324
+1.033981  1.428160  1.786944  1.880286  2.326359  2.503159
+0.970169  1.320721  1.716642  1.841569  2.220200  2.388916
+0.930477  1.373382  1.798398  1.904734  2.305786  2.525304
+0.939935  1.418455  1.772704  1.878087  2.367491  2.461526
+0.949116  1.527114  1.765903  1.840735  2.164926  2.474337
+0.993353  1.629343  1.813445  1.910215  2.100772  2.492902
+1.013830  1.549621  1.796834  1.891936  2.239760  2.556346
+0.970121  1.509802  1.834006  1.938978  2.338575  2.504346
+0.947238  1.361377  1.783553  1.984713  2.423900  2.547178
+0.980991  1.388783  1.783307  2.131708  2.454635  2.558692
+1.002668  1.402339  1.807195  2.024461  2.464418  2.554280
+1.010697  1.404186  1.872558  2.079362  2.479332  2.569625
+0.972976  1.375802  1.843367  1.980698  2.513609  2.578272
+0.932062  1.277676  1.851126  1.985878  2.466286  2.566260
+0.938577  1.181150  1.833964  1.965034  2.458011  2.550532
+0.940095  1.145447  1.796688  2.078273  2.482897  2.610630
+0.909789  1.074084  1.717403  2.139110  2.462525  2.572261
+0.882446  1.066652  1.729556  2.284662  2.478899  2.555022
+0.938178  1.121504  1.828485  2.234041  2.474778  2.557100
+0.917165  1.283072  1.779497  2.100290  2.475831  2.590182
+1.062938  1.349043  1.762759  2.118297  2.504806  2.606788
+1.186965  1.461900  1.889039  2.112738  2.481323  2.621310
+1.480720  1.619232  1.979483  2.177103  2.436476  2.578983
+1.448723  1.566337  1.880134  2.138534  2.339676  2.554594
+1.407995  1.613546  1.828927  2.052703  2.344501  2.538078
+1.616019  1.691006  1.856347  1.980078  2.548246  2.637759
+1.628171  1.684163  1.886153  2.012867  2.563772  2.621577
+1.595743  1.688011  1.935400  2.025813  2.483630  2.616820
+1.641560  1.708656  1.955460  2.046989  2.519834  2.645741
+1.673668  1.752213  1.951288  2.080918  2.487394  2.640725
+1.656417  1.736239  1.991365  2.098321  2.571908  2.676827
+1.659820  1.732449  1.951246  2.077020  2.581642  2.693515
+1.654803  1.716207  1.966639  2.044230  2.563251  2.680200
+1.602729  1.682614  1.917410  1.994825  2.531087  2.673289
+1.582550  1.639535  1.926100  1.992074  2.532073  2.697110
+1.462370  1.585004  1.818300  1.897553  2.557132  2.706256
+1.453199  1.550734  1.815192  1.916461  2.399968  2.667684
+1.419387  1.557717  1.784441  1.909176  2.511382  2.669980
+1.395165  1.539820  1.847477  1.930837  2.583961  2.703625
+1.348853  1.610875  1.958146  2.043068  2.586086  2.664353
+1.372390  1.658144  1.958657  2.189437  2.450481  2.650316
+1.352586  1.528092  1.923141  2.194837  2.427729  2.562143
+1.380925  1.612272  1.993385  2.176111  2.508934  2.635056
+1.429580  1.686586  2.017126  2.172565  2.486420  2.609268
+1.392123  1.641039  1.952077  2.065066  2.421215  2.574909
+1.399593  1.788262  1.952093  2.098580  2.489935  2.629393
+1.383756  1.662435  1.983097  2.112236  2.532805  2.631814
+1.372732  1.673625  1.912122  2.134246  2.432996  2.612276
+1.396034  1.642619  1.962634  2.197392  2.521323  2.660686
+1.379360  1.623989  2.069404  2.243124  2.562033  2.668437
+1.338665  1.618629  2.042041  2.195119  2.570159  2.699099
+1.294124  1.712084  2.050162  2.120133  2.607839  2.681695
+1.293254  1.596252  1.993414  2.060041  2.583077  2.664144
+1.209917  1.362665  1.955116  2.028347  2.512957  2.625803
+1.381701  1.706617  2.003167  2.146470  2.500026  2.613009
+1.204671  1.734562  1.928802  2.109687  2.476898  2.549090
+1.114491  1.696319  1.888819  2.043672  2.539268  2.637168
+1.119312  1.601460  1.846733  2.085664  2.577543  2.645353
+1.128747  1.531175  1.858280  2.146770  2.596351  2.688725
+1.130254  1.674654  1.830664  2.172114  2.562554  2.672831
+1.100767  1.644406  1.833225  2.040605  2.599334  2.652288
+1.066968  1.530596  1.768634  2.003323  2.617323  2.678055
+1.063119  1.469356  1.797817  1.881851  2.568187  2.679145
+1.177293  1.703277  1.865510  2.061041  2.481068  2.581444
+1.404135  1.657504  1.927058  2.181851  2.457409  2.580431
+1.428360  1.663538  1.984994  2.183449  2.458664  2.569489
+1.403204  1.667154  1.955094  2.146449  2.462636  2.562658
+1.234126  1.597848  1.917754  2.034440  2.407548  2.560257
+1.224528  1.368625  1.848065  1.924719  2.494949  2.670207
+1.214772  1.588344  1.765811  2.003861  2.526784  2.635964
+1.264884  1.636472  1.825225  2.077058  2.563495  2.679292
+1.269611  1.588977  1.782182  2.095015  2.620415  2.691789
+1.296409  1.504336  1.802915  2.013382  2.605687  2.681621
+1.334375  1.520771  1.796606  1.963884  2.600418  2.703744
+1.397570  1.600583  1.845972  1.940123  2.616223  2.696111
+1.430879  1.559075  1.799241  1.994052  2.598948  2.674700
+1.482115  1.583037  1.807507  1.981426  2.575382  2.684729
+1.464344  1.565621  1.776029  1.917627  2.575000  2.659270
+1.455399  1.538232  1.730658  1.882074  2.563750  2.660443
+1.499577  1.584423  1.688069  1.892068  2.587098  2.688675
+1.479760  1.573703  1.695194  2.024437  2.558177  2.639037
+1.452267  1.547118  1.750567  2.072025  2.537014  2.673786
+1.447379  1.563037  1.794376  2.141633  2.353387  2.502548
+1.351721  1.450714  1.730230  1.991889  2.298349  2.463553
+1.318760  1.414624  1.641985  1.948338  2.326246  2.474291
+1.212051  1.346227  1.685099  1.959885  2.322238  2.512951
+1.209021  1.302946  1.634616  1.930848  2.282912  2.507545
+1.188947  1.292823  1.665660  2.177853  2.373563  2.474293
+1.257542  1.451148  1.836011  2.161476  2.447295  2.596642
+1.253420  1.370197  1.833717  2.244743  2.479769  2.576022
+1.179954  1.302011  1.592154  2.151577  2.455959  2.518120
+1.114477  1.257653  1.411579  2.042361  2.548294  2.620409
+1.099986  1.307070  1.407174  2.159418  2.585914  2.649358
+1.131151  1.246857  1.401279  2.116604  2.483756  2.546663
+1.173775  1.340865  1.449901  2.093705  2.561030  2.626482
+1.189575  1.346203  1.465586  2.003540  2.517749  2.575697
+1.217965  1.302991  1.569488  2.028970  2.455729  2.550140
+1.231915  1.393228  1.520464  1.955734  2.476226  2.642241
+1.277177  1.451138  1.591018  1.925992  2.458091  2.566561
+1.216236  1.483117  1.688680  1.988972  2.454628  2.599617
+1.184293  1.553039  1.838890  2.100265  2.385006  2.550049
+1.239174  1.792822  1.959073  2.182600  2.445294  2.529569
+1.624571  1.860854  2.120332  2.219916  2.429410  2.594102
+1.753243  1.889331  2.136521  2.254574  2.436331  2.562459
+1.757269  1.956924  2.242335  2.360108  2.493739  2.587626
+1.806843  1.985195  2.197761  2.338682  2.496335  2.600682
+1.859905  2.030422  2.282537  2.396000  2.548595  2.632629
+1.771104  1.896134  2.306763  2.421261  2.538338  2.625956
+1.505646  1.893235  2.019328  2.325790  2.487965  2.585530
+1.189137  1.771099  1.915068  2.254873  2.534430  2.612783
+1.103999  1.649346  1.834993  1.935938  2.534134  2.651998
+1.079006  1.522445  1.767276  1.934965  2.523135  2.596389
+1.106210  1.608040  1.751444  2.008392  2.491731  2.577152
+1.225135  1.597265  1.857833  2.103611  2.465420  2.593047
+1.375366  1.618359  1.930516  2.214454  2.445564  2.576198
+1.429991  1.698975  1.982144  2.233337  2.490443  2.605353
+1.482797  1.679463  1.997759  2.222400  2.464577  2.586822
+1.407997  1.676636  1.970849  2.221085  2.440364  2.592428
+1.279905  1.618797  1.920986  2.161088  2.438805  2.627424
+0.936959  1.310295  1.663367  2.010101  2.515991  2.597781
+1.014662  1.401511  1.590078  2.080875  2.556905  2.622152
+1.043648  1.384572  1.571501  1.988231  2.568660  2.647893
+1.107266  1.413973  1.562057  1.877144  2.554722  2.637289
+1.179476  1.467385  1.605003  1.839003  2.523485  2.640499
+1.218315  1.412023  1.591634  1.796526  2.519799  2.660570
+1.305370  1.427385  1.614577  1.763694  2.497267  2.657791
+1.338542  1.456340  1.642200  1.862353  2.448789  2.631625
+1.328675  1.442223  1.575230  1.858910  2.470665  2.570433
+1.351215  1.466285  1.601432  1.863743  2.425253  2.500336
+1.360914  1.476484  1.624624  1.832107  2.486273  2.563333
+1.401730  1.499881  1.613403  1.749733  2.423219  2.591408
+1.261551  1.402991  1.523781  1.802043  2.499740  2.605532
+1.160005  1.467049  1.605598  1.787691  2.508050  2.557362
+1.279521  1.535093  1.620574  1.758619  2.409621  2.676419
+1.161358  1.505461  1.626199  1.733096  2.398831  2.617482
+1.184633  1.528528  1.614286  1.698210  2.350337  2.667102
+1.117350  1.538074  1.658450  1.759625  2.281261  2.580678
+1.109838  1.492830  1.701966  1.789832  2.151236  2.489725
+1.010233  1.467118  1.631090  1.886421  2.420021  2.522779
+0.950861  1.336887  1.617005  1.789550  2.449618  2.528894
+1.028468  1.348095  1.571888  1.880393  2.543912  2.608014
+1.110746  1.415658  1.690546  2.005512  2.558177  2.650097
+1.110147  1.432665  1.669404  1.901594  2.516926  2.602743
+1.067829  1.543381  1.719440  1.979004  2.543666  2.617575
+1.422545  1.701061  1.940427  2.327061  2.557612  2.642956
+1.386122  1.781934  2.040679  2.383895  2.573951  2.633463
+1.512775  1.696332  2.184500  2.295985  2.578995  2.677261
+1.571845  1.705242  2.225227  2.319189  2.542604  2.676163
+1.514913  1.844285  2.247341  2.361592  2.529071  2.653297
+1.603580  1.948417  2.271813  2.429600  2.528208  2.617731
+1.620409  2.024184  2.379020  2.477983  2.622963  2.670765
+1.578823  1.906347  2.238314  2.378843  2.556955  2.647118
+1.611136  1.900666  2.185777  2.317384  2.517010  2.610141
+1.554611  1.941431  2.133055  2.249862  2.491762  2.571608
+1.469621  1.918901  2.094184  2.225177  2.490350  2.564343
+1.335366  1.697214  2.017085  2.232317  2.474337  2.571016
+1.221936  1.519055  1.814063  2.129404  2.458290  2.560125
+1.193348  1.426044  1.731637  2.009086  2.485687  2.566097
+1.140861  1.304138  1.724072  1.962123  2.456816  2.673582
+1.171988  1.316998  1.756942  2.050812  2.520621  2.679355
+1.135139  1.410213  1.715289  2.092595  2.499448  2.617713
+1.114534  1.487214  1.595404  2.013785  2.531961  2.628395
+1.185163  1.399888  1.582655  2.195793  2.518380  2.582468
+1.104552  1.423680  1.656289  2.262530  2.593187  2.664012
+1.164305  1.596992  1.717746  2.207846  2.563155  2.621398
+1.022593  1.596460  1.831763  2.287975  2.519037  2.580420
+0.920067  1.656499  1.829222  2.207172  2.535598  2.582536
+0.940069  1.577439  1.960575  2.189248  2.482820  2.549330
+0.824619  1.708493  1.932229  2.188611  2.551880  2.605484
+0.819752  1.688971  1.950607  2.083451  2.463192  2.515870
+0.820934  1.718478  2.021631  2.158415  2.521119  2.576288
+0.860984  1.615689  2.046857  2.146219  2.469888  2.571061
+0.722400  1.647372  1.973155  2.066104  2.438838  2.609071
+0.853506  1.577947  1.949855  2.082839  2.448741  2.512425
+0.745605  1.464510  1.993321  2.077513  2.469178  2.532474
+0.710718  1.533693  1.890047  2.013877  2.425598  2.516390
+0.877569  1.511979  1.831605  2.031903  2.441617  2.517441
+1.259618  1.519519  1.879696  2.138828  2.450290  2.614072
+1.326658  1.670099  1.919340  2.148365  2.362928  2.464453
+1.437714  1.671637  1.955052  2.166713  2.405950  2.557523
+1.603868  1.740291  1.989945  2.198778  2.467525  2.585653
+1.638499  1.743252  2.051089  2.149707  2.462625  2.569332
+1.631833  1.721768  2.002918  2.131145  2.438931  2.569221
+1.603157  1.763192  2.082194  2.174769  2.376719  2.502259
+1.630977  1.703944  2.009215  2.149268  2.369179  2.580570
+1.576599  1.658687  1.922940  2.124950  2.448734  2.578273
+1.516265  1.630706  1.860803  2.127036  2.444402  2.582277
+1.458879  1.547626  1.796080  2.046972  2.378056  2.535592
+1.376657  1.512511  1.733562  2.098209  2.361768  2.452137
+1.134749  1.320184  1.582547  2.052886  2.449062  2.527062
+1.079447  1.164059  1.573367  2.220764  2.500300  2.560928
+1.060468  1.186417  1.456658  2.155790  2.437004  2.526903
+0.974645  1.132811  1.563530  2.089864  2.504612  2.571780
+0.925733  1.049035  1.555693  2.095444  2.541677  2.614171
+1.012861  1.154680  1.283807  2.126165  2.558786  2.595811
+0.970704  1.088894  1.398803  1.969666  2.517460  2.621486
+0.996670  1.155602  1.284230  1.967741  2.478048  2.536750
+1.061875  1.172759  1.296847  1.890131  2.465313  2.550488
+0.971133  1.146895  1.425088  1.823656  2.310199  2.513193
+1.122316  1.246948  1.573931  1.945863  2.350666  2.546107
+1.130444  1.281802  1.711748  2.052845  2.471168  2.568969
+1.285794  1.425185  1.874398  2.085225  2.426111  2.576993
+1.273537  1.490213  1.878772  2.106249  2.402449  2.544368
+1.224244  1.462476  1.904611  2.128189  2.416565  2.570019
+1.252061  1.449849  1.802510  2.119875  2.418885  2.518798
+1.327124  1.417585  1.789962  2.174930  2.340651  2.468715
+1.346777  1.435555  1.734308  2.036035  2.356552  2.531051
+1.235820  1.315959  1.597124  1.897870  2.284217  2.575948
+0.955415  1.303770  1.560187  1.730070  2.449775  2.648120
+0.909089  1.471674  1.624478  1.890973  2.389653  2.627950
+0.919631  1.366873  1.506021  1.842587  2.342002  2.554492
+0.855197  1.279671  1.539553  1.688524  2.386911  2.502065
+0.807057  1.135620  1.541600  1.681299  2.243913  2.510869
+0.849115  1.190235  1.449935  1.541388  2.302579  2.655596
+0.832569  1.273363  1.592481  1.792808  2.284175  2.498482
+0.835449  1.168916  1.544629  1.718930  2.423889  2.632619
+0.826578  1.276188  1.407857  1.660287  2.378044  2.474526
+0.873632  1.360315  1.502868  1.758332  2.570802  2.712262
+0.828320  1.284633  1.462407  1.624198  2.575860  2.705612
+0.866930  1.133312  1.254056  1.429890  2.499289  2.562307
+0.807119  1.218080  1.346012  1.540621  2.487606  2.633103
+0.983680  1.146576  1.336648  1.479310  2.327156  2.614361
+0.991742  1.170728  1.296168  1.485606  2.543050  2.663819
+0.857243  1.172195  1.298593  1.623901  2.581253  2.675646
+1.024459  1.245164  1.335833  1.923956  2.623488  2.689817
+1.035260  1.293064  1.419811  1.882694  2.474976  2.673673
+0.981160  1.239841  1.334553  1.628448  2.544049  2.681735
+0.948338  1.227389  1.360095  1.572061  2.447980  2.668611
+1.097120  1.256099  1.362188  1.632542  2.507787  2.656424
+1.060738  1.283998  1.527933  1.676274  2.540944  2.638141
+0.999111  1.230695  1.531258  1.643979  2.373065  2.634336
+0.900037  1.357157  1.519901  1.691155  2.333453  2.605899
+0.906535  1.200477  1.615255  1.715962  2.288870  2.609565
+0.841267  1.337701  1.721187  1.799125  2.176356  2.627236
+0.950819  1.507117  1.718816  1.826725  2.050526  2.489892
+0.922437  1.447590  1.832061  1.920513  2.148990  2.509573
+0.797637  1.120473  1.756266  1.946112  2.209112  2.535941
+0.821846  1.168739  1.837911  1.977726  2.361612  2.642410
+0.802821  1.394640  1.945588  2.031517  2.337491  2.589953
+0.808599  1.214285  1.878529  2.002325  2.280219  2.577779
+0.825133  1.329296  1.896620  1.979559  2.455746  2.573104
+0.847939  1.235948  1.897295  2.016610  2.422214  2.651151
+0.793266  1.311794  1.885265  1.974869  2.493916  2.699921
+0.835729  1.418115  1.839725  1.903232  2.507962  2.645131
+0.849380  1.476197  1.836815  1.977378  2.321338  2.561101
+0.774570  1.284607  1.758190  1.864424  2.367732  2.561205
+0.896154  1.466437  1.770222  1.871354  2.586553  2.688477
+1.097803  1.576496  1.742325  1.910224  2.160666  2.658455
+0.950720  1.452865  1.760158  1.934774  2.196277  2.624191
+0.947778  1.334777  1.745609  1.830510  2.256113  2.667856
+0.970291  1.214911  1.745935  1.840709  2.268780  2.555177
+1.027483  1.193053  1.655411  1.770558  2.115990  2.502962
+1.108625  1.224039  1.556423  1.705900  2.019067  2.463824
+1.137334  1.248642  1.659896  1.835999  2.087298  2.494018
+1.192784  1.290313  1.652861  1.878632  2.086082  2.615960
+1.231829  1.343294  1.528206  1.646125  1.912160  2.354407
+1.043149  1.380698  1.679143  1.830121  2.008367  2.414010
+1.102887  1.243057  1.747479  1.861385  2.203092  2.504381
+1.049734  1.354368  1.735882  1.819000  2.248805  2.557794
+1.105977  1.571421  1.764806  1.953547  2.428854  2.560105
+1.290846  1.550164  1.837562  2.126596  2.488831  2.600779
+1.194236  1.426699  1.837665  1.914014  2.443207  2.635517
+1.165504  1.260088  1.790938  1.893312  2.400453  2.646643
+1.224955  1.308139  1.825926  1.919493  2.321356  2.695079
+1.248486  1.345382  1.775451  1.876708  2.353719  2.654140
+1.271138  1.399667  1.811535  1.897580  2.403493  2.653922
+1.309100  1.407658  1.806843  1.897827  2.339222  2.632347
+1.291018  1.383330  1.802439  1.887187  2.247718  2.662452
+1.261355  1.370512  1.755969  1.871246  2.101895  2.593588
+1.282645  1.376536  1.775534  1.904499  2.192341  2.507429
+1.361360  1.450864  1.791066  1.906164  2.221501  2.543343
+1.334993  1.431384  1.716268  1.905493  2.089197  2.378260
+1.385673  1.470423  1.765397  1.909217  2.173842  2.456572
+1.364318  1.455064  1.754884  1.871473  2.365039  2.572279
+1.387777  1.486887  1.712089  1.847504  2.243563  2.570692
+1.312448  1.425290  1.622893  1.756780  1.978470  2.367512
+1.347202  1.454345  1.683431  1.825472  2.087917  2.462563
+1.326447  1.405443  1.727641  1.835551  2.328868  2.614333
+1.333108  1.429712  1.796075  1.900347  2.445062  2.652912
+1.322803  1.421588  1.736939  1.843495  2.532120  2.646639
+1.344685  1.431856  1.766206  1.924579  2.550076  2.689857
+1.388277  1.485813  1.711960  1.826211  2.496137  2.658495
+1.411133  1.495610  1.776872  1.876674  2.492586  2.651345
+1.417795  1.491577  1.801693  1.890405  2.442446  2.706992
+1.406122  1.515595  1.757336  1.896968  2.382045  2.633633
+1.425860  1.514813  1.773260  1.901744  2.447546  2.634715
+1.476029  1.555032  1.745731  1.861617  2.398766  2.614978
+1.459852  1.561528  1.786445  1.911235  2.476542  2.591787
+1.403056  1.514189  1.720761  1.900939  2.489890  2.577333
+1.428127  1.523512  1.689756  1.835214  2.458899  2.565972
+1.328956  1.434709  1.604068  1.734252  2.466296  2.566835
+1.241317  1.343249  1.457997  1.696624  2.527818  2.645659
+1.136623  1.311125  1.429957  1.695364  2.542525  2.660410
+1.153111  1.344144  1.690808  1.985929  2.420013  2.553782
+1.231755  1.373918  1.668818  2.117444  2.401907  2.488883
+0.978581  1.115592  1.517126  2.000531  2.449025  2.526020
+0.951081  1.107962  1.208612  1.737223  2.474298  2.611849
+0.981806  1.127841  1.220590  1.720985  2.586528  2.698889
+0.977554  1.224067  1.337758  1.713271  2.593374  2.675408
+0.986078  1.260397  1.407440  1.571486  2.569420  2.631754
+1.068774  1.209396  1.464430  1.557978  2.551351  2.669751
+1.034191  1.174307  1.467256  1.555295  2.460490  2.642259
+1.056632  1.178692  1.509897  1.621544  2.153033  2.540535
+1.108939  1.240242  1.651384  1.778538  2.227605  2.571951
+1.040854  1.397785  1.709633  1.830019  2.398698  2.618954
+1.063080  1.564032  1.695538  1.794688  2.419017  2.577353
+1.156653  1.579890  1.742991  1.888966  2.419007  2.626873
+1.282148  1.604674  1.769820  1.984806  2.290529  2.408545
+1.414961  1.752587  1.937904  2.076787  2.287689  2.502281
+1.561586  1.882695  2.087185  2.199871  2.398595  2.509058
+1.741771  1.963051  2.161078  2.262211  2.516056  2.626131
+1.579553  1.916299  2.201667  2.301679  2.458486  2.648337
+1.656200  1.849299  2.101697  2.302170  2.487760  2.573832
+1.761707  1.935887  2.167102  2.423095  2.531309  2.619774
+1.747342  1.946460  2.129719  2.452120  2.591709  2.681100
+1.664774  1.950714  2.064839  2.452925  2.653282  2.719977
+1.182120  1.806988  2.031810  2.240448  2.589338  2.666952
+0.911793  1.444427  1.938199  2.009542  2.518849  2.662424
+0.906235  1.353950  1.860144  1.948940  2.570343  2.653728
+0.915756  1.182444  1.779374  1.918355  2.495182  2.685238
+0.923262  1.168083  1.705447  2.007985  2.401242  2.584424
+0.915338  1.196101  1.641183  1.957797  2.235160  2.502509
+1.116935  1.269153  1.597465  1.950801  2.129101  2.392503
+1.227147  1.344231  1.809259  1.999158  2.320768  2.545770
+1.307876  1.517973  1.832338  2.042156  2.347761  2.543408
+1.142909  1.427477  1.831520  2.022295  2.356478  2.589639
+1.020209  1.202712  1.780168  2.070788  2.565827  2.661648
+1.087846  1.265956  1.653284  2.093962  2.625661  2.709244
+1.146593  1.234170  1.666291  2.022252  2.605716  2.676253
+1.089057  1.311412  1.647149  1.833847  2.666682  2.722762
+1.188386  1.319963  1.725677  1.806948  2.571193  2.664171
+1.209565  1.358036  1.697429  1.794200  2.470455  2.640229
+1.246047  1.338292  1.695538  1.782003  2.565757  2.666941
+1.261251  1.384481  1.619675  1.779584  2.591799  2.712426
+1.337507  1.450232  1.646992  1.774207  2.578969  2.703367
+1.387688  1.478096  1.618920  1.747276  2.531990  2.665704
+1.301779  1.392643  1.541867  1.665649  2.484537  2.655063
+1.257012  1.398833  1.527358  1.734139  2.619531  2.689676
+1.211161  1.324264  1.664338  1.911508  2.589343  2.685254
+1.113028  1.325407  1.697702  1.940185  2.591124  2.679629
+1.000343  1.352231  1.719494  2.024790  2.577661  2.639096
+0.952537  1.564659  1.914580  2.021105  2.481262  2.553572
+0.941380  1.573371  1.898482  1.990822  2.388399  2.527824
+0.835656  1.426857  1.914902  2.006303  2.455843  2.544426
+0.762518  1.617975  1.848163  1.952719  2.511683  2.576889
+0.760103  1.720246  1.884039  1.972497  2.526184  2.668968
+0.788105  1.515939  1.760885  1.953721  2.498661  2.553903
+0.842390  1.235086  1.687435  2.011114  2.391471  2.529546
+0.970555  1.304880  1.689915  2.060096  2.386014  2.524270
+1.078507  1.220815  1.630394  2.103928  2.411414  2.518300
+1.035130  1.374294  1.739516  2.015391  2.383541  2.542893
+1.232775  1.466122  1.942876  2.112602  2.359872  2.476841
+1.032139  1.460157  1.843607  2.111319  2.405612  2.545609
+0.863004  1.575367  1.754339  2.026425  2.484055  2.545871
+0.781880  1.621135  1.876114  2.131620  2.591150  2.665213
+0.689257  1.567671  1.951319  2.246727  2.507788  2.649956
+0.762920  1.454508  2.052137  2.239950  2.408909  2.570384
+0.735313  1.369541  2.141121  2.226737  2.404256  2.515847
+0.692794  1.213217  2.021728  2.170012  2.409789  2.632609
+0.749191  1.327407  1.876305  2.159813  2.396372  2.543556
+0.723514  1.311926  1.779121  2.000990  2.333064  2.521625
+0.800844  1.399334  1.702525  1.886771  2.183805  2.391837
+0.935365  1.532399  1.746103  1.843273  2.027876  2.366925
+0.879717  1.390978  1.696694  1.873227  2.273388  2.532951
+1.115628  1.395380  1.552486  2.062541  2.379745  2.485662
+1.253460  1.379822  1.726521  2.164899  2.386851  2.507812
+1.288652  1.548609  1.769224  2.106137  2.428838  2.517503
+1.369653  1.611147  1.793668  1.970474  2.367649  2.558036
+1.399028  1.694930  1.865624  2.036762  2.409162  2.586430
+1.433335  1.745725  1.930732  2.159385  2.426554  2.579037
+1.267585  1.665867  1.971379  2.103318  2.444523  2.567741
+1.226120  1.497218  1.888612  2.083592  2.547854  2.623475
+1.217864  1.502320  1.850155  1.973913  2.506017  2.625566
+1.213794  1.595369  1.875039  1.979415  2.427150  2.606463
+1.239752  1.513874  1.766680  1.947926  2.281624  2.492074
+1.247634  1.585626  1.729740  1.894696  2.381964  2.522121
+1.201153  1.474465  1.746568  1.834238  2.289729  2.525183
+1.181465  1.555321  1.703604  1.823083  2.315827  2.443888
+1.196327  1.573762  1.735225  1.808031  2.403501  2.557243
+1.149081  1.631606  1.769163  1.925569  2.368122  2.542814
+1.071093  1.633545  1.761338  1.872468  2.408464  2.573521
+1.065230  1.551738  1.713412  1.880487  2.387426  2.512159
+0.987564  1.635727  1.785940  1.956709  2.413400  2.548618
+0.931677  1.526457  1.773013  1.896960  2.437956  2.513898
+0.900322  1.645882  1.787979  2.041039  2.334273  2.434592
+0.867303  1.714715  1.901607  2.099190  2.387096  2.475894
+0.868278  1.693735  1.917301  2.013076  2.274597  2.382531
+0.848816  1.567192  1.829012  1.929834  2.339398  2.425619
+0.789452  1.369290  1.826862  1.917268  2.414283  2.502071
+0.737031  1.173300  1.873028  1.972833  2.455130  2.541243
+0.759015  1.250729  1.781114  1.994631  2.420436  2.554945
+0.749485  1.363939  1.896372  1.993571  2.442257  2.509848
+0.749379  1.214662  1.940660  2.034076  2.450716  2.568302
+0.801242  1.269156  1.870897  1.955986  2.405162  2.473861
+0.823290  1.258951  1.879861  2.069704  2.411773  2.510105
+0.836531  1.273927  1.957305  2.047469  2.490158  2.582295
+0.834116  1.183883  1.886457  1.969193  2.499483  2.604335
+0.876413  1.171153  1.946619  2.030903  2.431350  2.553010
+0.839364  1.056108  1.853641  2.100590  2.392613  2.554339
+0.864173  1.164684  1.835487  1.968845  2.376306  2.516103
+0.932804  1.294569  1.830951  1.901036  2.445265  2.552572
+0.963048  1.356861  1.768829  1.893219  2.479918  2.614673
+1.037066  1.359723  1.820807  1.891047  2.519312  2.605020
+1.060607  1.462340  1.797954  1.939293  2.521868  2.591879
+1.079923  1.504167  1.802208  1.930535  2.465137  2.543195
+1.140112  1.339064  1.813350  1.905307  2.370068  2.530420
+1.151868  1.356167  1.772359  1.883710  2.370014  2.610806
+1.288085  1.638629  1.751055  2.279923  2.555394  2.623279
+1.451442  1.739489  1.916401  2.388700  2.636146  2.702827
+1.591253  1.851544  2.218282  2.385490  2.593754  2.679427
+1.592264  2.016137  2.233799  2.333758  2.544823  2.665169
+1.654199  1.941575  2.250965  2.372366  2.458905  2.599827
+1.703247  2.025498  2.229596  2.337095  2.468575  2.617655
+1.638815  2.005565  2.201946  2.268461  2.499537  2.618409
+1.924675  2.135325  2.458180  2.504168  2.593838  2.625401
+1.803809  2.062572  2.199354  2.289456  2.550039  2.643916
+1.773011  1.976616  2.107571  2.220874  2.444977  2.543841
+1.764952  2.001727  2.214453  2.254705  2.475610  2.579746
+1.678332  1.863913  2.244638  2.343674  2.471126  2.636086
+1.755810  1.860246  2.223719  2.353060  2.498302  2.586676
+1.693433  1.869241  2.283303  2.395805  2.519741  2.583673
+1.704396  1.791207  2.147185  2.336447  2.479029  2.590894
+1.683258  1.862251  2.163335  2.351843  2.520908  2.616034
+1.623219  1.804206  2.222072  2.360296  2.619900  2.699507
+1.657240  1.825612  2.258489  2.347345  2.545732  2.694714
+1.660069  1.860341  2.253569  2.364116  2.564093  2.630731
+1.596899  1.839512  2.218930  2.385793  2.546468  2.625886
+1.622317  1.851201  1.996215  2.377397  2.522071  2.595493
+1.029466  1.254529  1.748991  2.053525  2.445882  2.576112
+0.856689  0.993818  1.569607  2.213756  2.461855  2.547082
+1.016581  1.191900  1.293465  1.778141  2.455802  2.551646
+1.010542  1.228148  1.311431  1.820284  2.531515  2.656752
+0.908278  1.189582  1.285536  1.858600  2.525918  2.619924
+0.871987  1.171922  1.317490  1.826516  2.400744  2.518087
+1.033124  1.188852  1.439697  2.039008  2.572425  2.656103
+0.970197  1.295635  1.402442  2.035038  2.488178  2.549888
+1.088196  1.220650  1.553062  2.133376  2.535702  2.595055
+1.009947  1.389803  1.517057  2.115221  2.474188  2.550693
+0.993372  1.427374  1.539173  1.972396  2.525839  2.583860
+1.048290  1.482084  1.637176  2.161075  2.523169  2.614712
+1.024326  1.562855  1.692237  2.295162  2.594836  2.648573
+0.907692  1.612559  1.746134  2.162536  2.575745  2.616258
+0.890482  1.611128  1.773927  1.970733  2.577746  2.659601
+0.808392  1.597802  1.785959  2.006399  2.565042  2.638957
+0.766474  1.584421  1.835838  1.929741  2.581539  2.641074
+0.769957  1.626769  1.869258  2.029447  2.602778  2.660482
+0.798945  1.531859  1.834894  1.946531  2.628257  2.692621
+0.720628  1.380228  1.817598  1.895348  2.547755  2.607196
+0.717991  1.301269  1.753273  1.880568  2.501113  2.570677
+0.757538  1.197506  1.719315  1.863401  2.467197  2.580754
+0.753702  1.292466  1.691851  1.775796  2.472592  2.583782
+0.814552  1.234200  1.583851  1.688282  2.546255  2.601382
+0.892573  1.259415  1.548665  1.628711  2.465185  2.557477
+0.949846  1.260567  1.429248  1.620283  2.396748  2.457397
+1.035299  1.244100  1.498240  1.643920  2.381366  2.524331
+1.108074  1.337571  1.538192  1.800588  2.513582  2.617693
+1.182535  1.370472  1.561886  1.844157  2.545726  2.614455
+1.215270  1.374402  1.595386  1.940797  2.512277  2.594163
+1.232828  1.356701  1.648355  2.040665  2.518326  2.606889
+1.295532  1.441002  1.626009  2.063594  2.535454  2.607196
+1.317455  1.484169  1.666626  2.107203  2.509460  2.569563
+1.288135  1.404836  1.708442  2.142397  2.478263  2.558149
+1.301178  1.490634  1.688663  2.209739  2.516570  2.582597
+1.388908  1.488602  1.753074  2.249110  2.468447  2.532735
+1.432358  1.501949  1.756043  2.227378  2.540315  2.633816
+1.270629  1.444250  1.697177  2.167736  2.574168  2.667078
+1.377953  1.511825  1.619242  2.070588  2.580573  2.655449
+1.319093  1.437635  1.575159  1.826257  2.568503  2.646941
+1.273340  1.439378  1.614682  1.977816  2.589179  2.642268
+1.364811  1.491437  1.654641  1.914895  2.277580  2.491707
+1.381399  1.482330  1.625703  1.767453  2.292816  2.535410
+1.316122  1.410804  1.574518  1.696495  2.241547  2.544142
+1.249213  1.448411  1.651606  1.812013  2.166941  2.528826
+1.329985  1.430104  1.637785  1.753696  2.144268  2.491734
+1.212008  1.460184  1.663715  1.723968  2.452735  2.654868
+1.154672  1.427992  1.639839  1.703824  2.524782  2.647191
+1.132193  1.276380  1.638189  1.750734  2.360136  2.630237
+1.106796  1.292196  1.563991  1.737151  2.276384  2.673484
+1.009469  1.409199  1.605253  1.755880  2.549809  2.666897
+0.849242  1.424760  1.607336  1.770467  2.593061  2.697570
+0.884126  1.418674  1.690537  1.910365  2.648893  2.753562
+0.835786  1.505326  1.650834  1.839830  2.667508  2.731820
+0.830887  1.418426  1.698221  1.812786  2.546614  2.605179
+0.770144  1.456185  1.735350  1.839787  2.485317  2.539411
+0.741204  1.461201  1.720258  2.039661  2.613149  2.656617
+0.746126  1.436058  1.674916  1.868865  2.616457  2.659599
+0.785082  1.343492  1.675451  1.756554  2.550054  2.611912
+0.745773  1.354824  1.630019  1.938987  2.453600  2.549079
+0.845780  1.469252  1.629079  1.974969  2.499282  2.549783
+0.949421  1.462768  1.572994  2.286043  2.549581  2.602929
+1.025145  1.385363  1.648388  2.192934  2.440628  2.531024
+1.033724  1.436166  1.744094  2.132259  2.544044  2.618903
+1.082839  1.455838  1.597987  2.003093  2.628262  2.736133
+1.021616  1.380799  1.537805  2.007919  2.656179  2.725478
+0.934605  1.338311  1.721281  2.021380  2.452658  2.635942
+0.974987  1.280603  1.740482  1.988643  2.383388  2.588543
+0.963572  1.358626  1.775093  2.077077  2.374408  2.552547
+1.339392  1.606067  1.941038  2.159799  2.446540  2.587306
+1.268637  1.604063  1.940062  2.178915  2.487660  2.597501
+1.129807  1.522621  1.872974  2.075068  2.479707  2.633172
+1.135346  1.422302  1.865991  1.945310  2.523357  2.686142
+1.135540  1.562266  1.768152  1.922013  2.506054  2.736130
+1.173335  1.637622  1.845405  1.974533  2.379511  2.627590
+1.223094  1.477161  1.799506  1.945290  2.603703  2.697773
+1.285652  1.781420  1.972532  2.335252  2.649620  2.719252
+1.516066  1.862470  2.084987  2.386138  2.563370  2.650523
+1.622511  1.800884  2.074682  2.371099  2.494100  2.608952
+1.644218  1.730914  2.235251  2.344625  2.460604  2.621775
+1.646495  1.743836  2.118671  2.334538  2.487649  2.597304
+1.574474  1.666941  2.165682  2.294626  2.463016  2.642929
+1.568529  1.662679  2.068377  2.240071  2.374784  2.534291
+1.501088  1.675567  2.019200  2.253935  2.403957  2.560212
+1.333222  1.481857  1.810385  2.032438  2.235271  2.464023
+1.184189  1.376469  1.743067  2.077177  2.247370  2.436639
+0.860298  1.017970  1.399466  2.031356  2.445832  2.512045
+0.987543  1.187216  1.324668  2.086564  2.440265  2.507859
+0.987539  1.057392  1.400508  2.291033  2.462013  2.534542
+1.072567  1.168456  1.335425  2.281555  2.595283  2.641991
+1.042424  1.219473  1.328751  2.104394  2.481407  2.544847
+1.075840  1.204873  1.370286  2.206558  2.509524  2.557197
+1.075906  1.188083  1.414337  2.320102  2.530914  2.589422
+1.076149  1.267397  1.411982  2.218421  2.452294  2.540946
+1.154549  1.314810  1.500389  2.300970  2.505189  2.569795
+1.170382  1.300375  1.477782  2.201078  2.418226  2.511009
+1.164826  1.290783  1.436432  2.042173  2.434597  2.517154
+1.193857  1.293191  1.527594  2.008805  2.370813  2.473257
+1.263542  1.385669  1.596130  2.048764  2.427787  2.504082
+1.305187  1.421012  1.658876  2.095853  2.429425  2.518576
+1.378304  1.494361  1.710276  2.078040  2.477964  2.559482
+1.333727  1.475263  1.674044  2.039635  2.446712  2.527050
+1.346152  1.468526  1.673673  1.961087  2.462599  2.567158
+1.324261  1.466904  1.747093  2.009440  2.480558  2.571278
+1.306921  1.411049  1.740784  2.032398  2.466338  2.575794
+1.277304  1.408311  1.715677  1.956928  2.505971  2.597300
+1.239174  1.409858  1.635688  1.843138  2.511337  2.592493
+1.262271  1.377900  1.665878  1.785276  2.414923  2.519101
+1.223772  1.378608  1.706935  1.812010  2.472106  2.553503
+1.248275  1.560969  1.688454  2.024421  2.464682  2.532083
+1.551147  1.674831  1.863917  2.242605  2.425666  2.512306
+1.613538  1.736360  1.915832  2.284340  2.505100  2.575495
+1.675654  1.764549  2.013262  2.308596  2.479308  2.570877
+1.676790  1.732192  2.216913  2.350744  2.516807  2.584938
+1.672091  1.768085  2.170300  2.277530  2.411164  2.492525
+1.645851  1.881233  2.216349  2.320633  2.460809  2.564931
+1.714095  1.933206  2.220117  2.327698  2.453033  2.557432
+1.864162  1.965600  2.211890  2.354075  2.451546  2.543697
+1.840509  1.980901  2.141357  2.275924  2.487833  2.607026
+1.281628  1.508538  1.878088  2.153311  2.510390  2.597723
+1.285937  1.558518  1.895925  2.154502  2.510047  2.628884
+1.179704  1.457966  1.805824  2.088695  2.536834  2.648347
+1.213178  1.474144  1.796481  1.886388  2.426441  2.597142
+1.175759  1.566628  1.786803  1.959634  2.443976  2.621808
+1.241280  1.495544  1.772941  1.959431  2.513639  2.611886
+1.252864  1.547349  1.741300  1.873671  2.447277  2.674639
+1.234254  1.437033  1.742154  1.835750  2.372173  2.581494
+1.262397  1.351279  1.710277  1.833486  2.308910  2.583598
+1.330861  1.424104  1.673893  1.802977  2.271847  2.556762
+1.374920  1.473192  1.703358  1.804519  2.374494  2.625833
+1.350424  1.477644  1.741927  1.869579  2.468162  2.637851
+1.299448  1.409270  1.707326  1.828822  2.412618  2.660075
+1.283675  1.413183  1.694008  1.913840  2.235005  2.663358
+1.131349  1.545449  1.738197  1.927132  2.242548  2.529539
+1.310395  1.445321  1.800815  1.941760  2.224181  2.430698
+1.207823  1.407710  1.792289  1.897833  2.278582  2.588793
+1.172078  1.380374  1.769606  1.870709  2.420713  2.665411
+1.050374  1.292916  1.708676  1.815571  2.398301  2.647835
+1.012196  1.352840  1.710467  1.798435  2.501052  2.622110
+0.949688  1.511315  1.802233  2.051775  2.386590  2.543931
+1.239527  1.523312  1.992644  2.175922  2.535838  2.663321
+1.170409  1.423959  1.918088  2.072957  2.371327  2.600694
+1.153282  1.631638  1.943662  2.041389  2.426287  2.527936
+1.130992  1.687340  1.913097  1.982416  2.366644  2.592156
+0.876015  1.539120  1.952815  2.040387  2.354192  2.592474
+0.741027  1.330783  2.010264  2.088976  2.406380  2.512408
+0.692068  1.220984  1.966843  2.053168  2.527609  2.625367
+0.697907  1.406778  2.016010  2.085819  2.573177  2.652342
+0.747161  1.542479  1.982188  2.091091  2.573313  2.614600
+0.759939  1.518111  1.938220  2.162963  2.534355  2.639085
+0.752015  1.445930  2.097743  2.150626  2.479886  2.587138
+0.804190  1.428522  2.012448  2.195806  2.470749  2.577263
+0.757784  1.356544  1.878177  2.232246  2.530996  2.630296
+0.782189  1.251703  1.766911  2.206553  2.564453  2.617695
+0.692136  1.308291  1.593024  1.842927  2.504334  2.652647
+0.779817  1.264995  1.689687  1.803686  2.530498  2.669456
+0.774734  1.199620  1.649586  1.726576  2.437097  2.591528
+0.885025  1.311938  1.646470  1.739192  2.578721  2.671994
+0.949387  1.387109  1.641927  1.762570  2.528769  2.585787
+1.012043  1.455355  1.666729  1.752575  2.434270  2.553516
+1.104075  1.529375  1.682092  1.973044  2.345511  2.511577
+1.423997  1.619409  1.995513  2.298913  2.430779  2.521288
+1.582461  1.832072  2.275101  2.383131  2.482800  2.539316
+1.706366  2.001667  2.300029  2.394812  2.486966  2.586945
+1.532256  1.933761  2.284009  2.422313  2.622936  2.706043
+1.678938  1.889060  2.338973  2.512967  2.632369  2.679498
+1.634405  1.783714  2.124182  2.462997  2.610348  2.691361
+1.618353  1.751021  2.026128  2.418017  2.609402  2.678953
+1.565199  1.794303  1.902067  2.405664  2.629332  2.696870
+1.282138  1.591250  1.852032  2.314230  2.617777  2.722940
+1.220365  1.421679  1.694336  1.881742  2.556796  2.653179
+1.139402  1.299007  1.622371  1.770432  2.543866  2.640704
+1.214491  1.467423  1.628034  1.794008  2.563409  2.691705
+1.059626  1.521805  1.631948  1.865161  2.601036  2.683659
+1.180200  1.536587  1.671861  2.137961  2.587647  2.638393
+1.213651  1.582110  1.709505  2.157513  2.476799  2.574007
+1.248459  1.553050  1.645298  1.897537  2.577761  2.681279
+1.340584  1.601427  1.679985  1.889143  2.647088  2.755132
+1.194554  1.575563  1.697528  1.801365  2.596516  2.752368
+1.152988  1.531378  1.716414  1.812718  2.417149  2.696455
+1.175284  1.565269  1.657415  1.734779  2.517977  2.671209
+1.315878  1.515976  1.775170  2.058078  2.307304  2.449295
+1.247131  1.381271  1.568357  1.857012  2.157278  2.435014
+1.240254  1.383648  1.580575  1.991473  2.303569  2.411055
+1.286797  1.385847  1.730704  2.067540  2.326906  2.473042
+1.204107  1.337886  1.665492  2.038754  2.231416  2.543395
+1.182343  1.312111  1.522260  1.971028  2.237772  2.483629
+1.095429  1.319910  1.465710  2.032595  2.279936  2.523638
+1.152497  1.294508  1.458307  2.032534  2.306031  2.406760
+0.991441  1.274662  1.428222  1.940576  2.399100  2.509374
+0.850157  1.274723  1.453729  1.893527  2.382294  2.477664
+0.936060  1.313211  1.426739  1.888973  2.551745  2.604392
+0.972592  1.328333  1.432833  2.011050  2.573671  2.613672
+0.909400  1.422756  1.494628  2.073945  2.620634  2.662685
+0.828475  1.431701  1.569493  2.054254  2.622115  2.669741
+0.779249  1.375673  1.476635  1.949187  2.558998  2.622137
+0.815710  1.472687  1.650494  2.000905  2.565206  2.611683
+0.822357  1.333508  1.551653  1.864184  2.595847  2.706122
+0.736497  1.259887  1.490815  1.882220  2.494405  2.619982
+0.902240  1.431002  1.520505  1.910794  2.605395  2.678585
+0.900488  1.363048  1.461814  2.009771  2.665876  2.717180
+1.015394  1.361530  1.474854  1.920438  2.637482  2.702570
+0.950918  1.335184  1.440876  1.874351  2.678915  2.746244
+0.965674  1.306906  1.412895  1.727184  2.656317  2.739472
+1.121335  1.291332  1.412980  1.731394  2.624577  2.735999
+1.135486  1.299970  1.448634  1.635793  2.616713  2.687744
+1.120410  1.248201  1.383680  1.579760  2.397167  2.585237
+1.113415  1.294499  1.482373  1.602789  2.394835  2.634809
+1.241746  1.318174  1.473167  1.577503  2.426003  2.649775
+1.184376  1.272893  1.497747  1.608053  2.144455  2.537267
+1.283135  1.377322  1.543041  1.645177  2.105790  2.490904
+1.138008  1.380756  1.560480  1.640979  2.271006  2.625523
+1.243884  1.351538  1.603070  1.739791  2.038080  2.447512
+1.267258  1.509957  1.641649  1.831984  2.331327  2.472826
+1.276365  1.476401  1.625021  1.930342  2.319377  2.524369
+1.222679  1.559407  1.669982  1.805473  2.326911  2.580278
+1.265218  1.503892  1.830979  2.091536  2.396722  2.569088
+1.256047  1.528877  1.853033  2.106171  2.365139  2.503280
+1.236501  1.479118  1.728297  2.041463  2.528558  2.612900
+1.220644  1.605193  1.713770  1.950925  2.597639  2.649495
+1.255546  1.591871  1.706750  2.062713  2.561381  2.626901
+1.307080  1.580016  1.653547  1.941293  2.552727  2.643706
+1.310968  1.512803  1.656527  1.839190  2.592097  2.677706
+1.188596  1.316082  1.579370  1.690772  2.438500  2.641881
+1.114671  1.235994  1.591973  1.749192  2.359438  2.545213
+1.080067  1.277132  1.727997  2.041411  2.337068  2.549786
+1.032222  1.250210  1.680999  1.998340  2.318533  2.502200
+1.064719  1.159182  1.666731  2.019294  2.256570  2.573467
+1.026313  1.146367  1.672929  2.054063  2.433228  2.615716
+0.942929  1.092789  1.613522  2.077784  2.365142  2.499737
+0.980250  1.254777  1.492003  1.801193  2.445325  2.575711
+0.957395  1.251868  1.378337  1.744574  2.502966  2.665866
+0.840336  1.267995  1.397728  1.827984  2.555867  2.651285
+1.009902  1.175808  1.277770  2.048361  2.637904  2.700904
+0.883840  1.026780  1.146692  1.893681  2.518692  2.610564
+0.997171  1.138289  1.246408  1.837527  2.549820  2.642693
+0.992125  1.178874  1.282272  1.974399  2.559112  2.612968
+1.067589  1.255803  1.359021  1.963939  2.541420  2.596308
+1.086327  1.329068  1.432326  1.928840  2.528332  2.598239
+1.100351  1.345579  1.469529  1.942358  2.469723  2.561680
+1.101019  1.374382  1.561144  1.942560  2.484288  2.552996
+1.177497  1.455165  1.571485  1.943496  2.500309  2.550902
+1.260768  1.477903  1.601611  2.024022  2.487425  2.554237
+1.216439  1.470082  1.639601  1.957212  2.523832  2.588189
+1.257980  1.407199  1.651434  1.910722  2.464200  2.620868
+1.162091  1.436543  1.682166  1.896924  2.447302  2.677069
+1.250215  1.484632  1.653870  1.930473  2.493894  2.633436
+1.237977  1.513389  1.648781  1.880344  2.504094  2.581491
+1.223199  1.412456  1.634083  1.797183  2.451210  2.620618
+1.258745  1.358397  1.627717  1.726099  2.428287  2.621329
+1.234919  1.345606  1.552151  1.708675  2.385742  2.606052
+1.186417  1.341808  1.636911  1.754679  2.429716  2.544394
+1.216260  1.305888  1.632777  1.755770  2.320806  2.583785
+1.165343  1.284152  1.560527  1.682036  2.243217  2.494673
+1.085859  1.215111  1.590602  1.715333  2.231633  2.527227
+1.091652  1.384156  1.655159  1.716563  2.302785  2.535552
+1.060328  1.239077  1.627213  1.737571  2.420162  2.599147
+1.090079  1.394777  1.682485  1.799904  2.331813  2.532862
+1.169038  1.568116  1.785725  2.031553  2.372207  2.497865
+1.241903  1.662080  1.822491  2.169543  2.424542  2.525186
+1.040287  1.690414  1.853098  2.038593  2.472015  2.535969
+0.974879  1.689063  1.850137  2.151312  2.507415  2.562538
+0.879683  1.743838  1.968060  2.161147  2.463916  2.545849
+0.790116  1.794412  2.037297  2.159739  2.508403  2.564883
+0.793374  1.796169  2.060524  2.331075  2.591299  2.648578
+0.859332  1.800464  2.025451  2.200641  2.534316  2.611320
+0.825206  1.895126  2.063579  2.264528  2.514030  2.610797
+0.974068  1.904781  2.002639  2.315848  2.539666  2.595157
+0.961311  1.821283  2.015215  2.274545  2.600786  2.653365
+0.971040  1.737011  1.914953  2.243896  2.572362  2.612602
+0.999552  1.817902  1.953097  2.178591  2.574331  2.626275
+0.977300  1.756036  1.929137  2.135346  2.424209  2.556085
+1.065543  1.747638  1.899169  2.309745  2.587388  2.630589
+1.077057  1.655717  1.868334  2.238603  2.508913  2.571841
+1.077829  1.716423  1.791462  2.266223  2.615485  2.654046
+1.276021  1.713383  1.788825  2.101442  2.625616  2.679590
+1.263173  1.699086  1.776931  2.035107  2.610346  2.653421
+1.297137  1.667668  1.744010  2.030119  2.608062  2.678066
+1.262373  1.626459  1.781159  2.026178  2.636261  2.699179
+1.318031  1.657767  1.763578  1.939043  2.575450  2.705613
+0.980669  1.555891  1.722977  1.978553  2.568958  2.638420
+0.840013  1.463397  1.772781  2.164864  2.566894  2.666228
+0.832158  1.505750  1.937891  2.233974  2.630131  2.694884
+0.745541  1.530097  2.060727  2.162996  2.619130  2.692130
+0.832050  1.597985  2.127678  2.196662  2.528870  2.619304
+0.820544  1.616482  2.044842  2.133557  2.587661  2.668155
+0.789348  1.638569  1.996032  2.212800  2.572934  2.615430
+0.806795  1.742530  2.043915  2.183841  2.603407  2.660269
+0.843597  1.761377  1.998823  2.132969  2.596500  2.673163
+0.927714  1.759399  1.987169  2.201990  2.591677  2.650810
+1.070504  1.767115  1.978295  2.227191  2.642696  2.686380
+1.022852  1.856828  1.989822  2.217218  2.480936  2.574687
+0.886409  1.742690  1.863071  2.054904  2.542328  2.627054
+0.996501  1.553639  1.808061  1.948514  2.516726  2.605745
+1.218221  1.525015  1.878023  2.107205  2.423952  2.578894
+1.274705  1.491779  1.906237  2.101242  2.455724  2.563566
+1.319477  1.587082  1.879825  2.240443  2.439462  2.547992
+1.474513  1.699004  1.929257  2.228217  2.451873  2.563132
+1.545274  1.722709  1.892103  2.169162  2.520241  2.602958
+1.546160  1.668894  1.961486  2.212079  2.505999  2.621266
+1.535625  1.699287  2.016356  2.250824  2.550093  2.645619
+1.583411  1.687746  2.051949  2.332633  2.491721  2.598036
+1.500933  1.594052  1.929231  2.259850  2.422622  2.547761
+1.464918  1.614783  1.881701  2.216729  2.528952  2.623217
+1.406726  1.605026  1.805977  2.222725  2.509009  2.587841
+1.106418  1.527781  1.730182  2.045916  2.549464  2.637497
+1.008151  1.439718  1.665472  1.941372  2.652442  2.751095
+0.971347  1.402084  1.708896  1.953274  2.613325  2.684989
+0.946352  1.501044  1.672151  1.975870  2.527905  2.585573
+0.909229  1.453576  1.713898  2.065638  2.529315  2.613161
+0.975079  1.523288  1.839559  2.138553  2.498690  2.583725
+0.899524  1.552407  1.831637  2.068567  2.544880  2.611180
+0.805175  1.462327  1.860536  2.101344  2.570440  2.654850
+0.859011  1.514531  1.892400  2.012520  2.579679  2.648521
+0.763528  1.522433  1.902539  2.018517  2.556446  2.609582
+0.814387  1.494849  1.941715  2.077981  2.540329  2.612839
+0.853805  1.401871  1.942985  2.088086  2.488394  2.578614
+0.782036  1.348553  1.935300  2.025076  2.516816  2.598046
+0.754386  1.384949  1.900243  1.999656  2.600374  2.663763
+0.746921  1.421143  1.934567  2.038908  2.553273  2.612298
+0.731911  1.450761  1.924508  2.032744  2.497904  2.556491
+0.706741  1.543731  1.876596  1.992525  2.510176  2.565960
+0.852548  1.549952  1.899169  2.226497  2.522787  2.583939
+0.885718  1.656999  1.865791  2.162889  2.467388  2.553769
+0.951271  1.641721  1.813995  2.153059  2.427099  2.499612
+0.928485  1.502784  1.809440  2.224767  2.472400  2.553921
+0.816616  1.391098  1.665580  2.176141  2.510722  2.582819
+0.915934  1.390936  1.767514  2.169548  2.471665  2.652526
+1.115341  1.362311  1.722592  2.033033  2.406363  2.601875
+1.138664  1.252976  1.684517  1.937366  2.384311  2.623900
+1.084318  1.211953  1.633639  1.889936  2.413095  2.626228
+1.126224  1.344921  1.648605  2.071123  2.484189  2.605656
+1.123905  1.461556  1.845099  2.172457  2.462662  2.605139
+1.132557  1.468636  1.740223  2.184934  2.467938  2.580103
+1.148248  1.506173  1.676602  2.049290  2.446774  2.565419
+0.999544  1.404698  1.641769  1.863324  2.523843  2.592114
+0.932167  1.395984  1.709428  1.845739  2.524792  2.599616
+0.870085  1.476327  1.721511  1.897091  2.490256  2.593759
+0.891107  1.429106  1.789728  1.958425  2.519104  2.604987
+0.855550  1.421268  1.900935  2.011013  2.546617  2.609760
+0.895038  1.482579  1.873572  1.974828  2.519429  2.584450
+0.809092  1.486499  1.902272  2.000876  2.518374  2.597261
+0.808211  1.460169  1.881579  1.961398  2.468386  2.616332
+0.774237  1.471857  1.901217  2.013761  2.564870  2.665691
+0.800018  1.576948  1.938176  2.043718  2.494383  2.630097
+0.804705  1.570759  1.889356  1.975489  2.447653  2.555191
+0.840709  1.603377  1.827077  2.026318  2.442892  2.492424
+0.887288  1.536144  1.781616  1.952198  2.500811  2.576512
+0.847527  1.504701  1.792948  1.891589  2.578888  2.637316
+0.959025  1.533821  1.821486  1.979739  2.463750  2.544302
+1.036319  1.640786  1.886024  1.962887  2.358662  2.577756
+0.981142  1.486738  1.733096  1.878277  2.537973  2.610473
+1.046486  1.438515  1.740840  1.850012  2.590883  2.684137
+1.103404  1.489782  1.738241  1.817496  2.588368  2.701052
+1.176925  1.473684  1.732853  1.823270  2.524527  2.733540
+1.173320  1.438383  1.696555  1.792536  2.580785  2.665770
+1.134955  1.421862  1.604070  1.756135  2.617948  2.706644
+1.136007  1.384178  1.699100  1.855319  2.591013  2.683215
+1.201710  1.421935  1.737864  2.011199  2.540959  2.681093
+1.227450  1.624461  2.125226  2.340556  2.593435  2.671453
+1.265133  1.765689  2.131338  2.391774  2.613959  2.699849
+1.342282  1.581411  1.979244  2.297759  2.520391  2.602258
+1.449013  1.725546  2.176279  2.354739  2.538758  2.627319
+1.418726  1.898681  2.206330  2.275600  2.488746  2.586794
+1.555706  1.837600  2.165743  2.346188  2.530178  2.628757
+1.444437  1.790050  1.911014  2.301915  2.468862  2.540557
+1.378052  1.668499  1.845265  2.324889  2.537708  2.601471
+1.394741  1.682710  1.817346  2.075533  2.512120  2.566889
+1.297199  1.655884  1.825405  2.062105  2.513307  2.577371
+1.280659  1.669901  1.824567  2.168209  2.528166  2.601986
+1.306896  1.600808  1.767971  2.095291  2.509869  2.606002
+1.257678  1.559755  1.787804  2.076895  2.540388  2.627179
+1.196849  1.597550  1.817421  2.152662  2.580796  2.651246
+1.235935  1.676643  1.942307  2.326482  2.561542  2.645593
+1.189058  1.818895  2.081496  2.366454  2.608018  2.672086
+1.427589  1.885421  2.264907  2.424220  2.571371  2.651155
+1.714473  1.937868  2.390009  2.457149  2.552016  2.601930
+1.874136  2.073506  2.370468  2.511263  2.709177  2.749495
+1.647818  1.987798  2.281909  2.412099  2.604693  2.674821
+1.596366  1.881529  2.193995  2.380524  2.511918  2.584564
+1.555508  1.775218  2.064094  2.325699  2.512934  2.599262
+1.330054  1.712961  1.917624  2.285900  2.466591  2.579279
+0.990071  1.410874  1.632331  1.965889  2.466882  2.580417
+0.925150  1.299025  1.551401  1.897486  2.498481  2.645212
+0.968080  1.367127  1.520360  1.988159  2.313473  2.546943
+0.974374  1.283811  1.474810  2.078302  2.331089  2.455153
+1.000624  1.299150  1.415675  1.955760  2.261550  2.354258
+0.964045  1.136490  1.305931  1.936406  2.197537  2.299418
+1.013087  1.201143  1.372664  1.820179  2.063576  2.210659
+1.086478  1.216705  1.476655  1.604039  1.855963  2.324503
+1.090160  1.201207  1.460778  1.562225  2.016093  2.458980
+1.133754  1.257469  1.407186  1.787681  2.289532  2.530854
+1.134831  1.341221  1.636293  1.813775  2.219453  2.584652
+0.952747  1.300930  1.616891  1.751014  2.352113  2.547879
+1.078704  1.490043  1.571579  1.800532  2.468175  2.650436
+1.239045  1.333032  1.551379  1.707824  2.242922  2.604251
+1.176517  1.299114  1.588881  1.714081  2.128856  2.533523
+1.135831  1.253056  1.538412  1.634480  2.258093  2.593874
+1.092382  1.253236  1.541772  1.679875  2.423197  2.617584
+1.142663  1.256402  1.528284  1.629676  2.391580  2.589689
+1.172793  1.281248  1.479204  1.608878  2.335938  2.593681
+1.146782  1.251953  1.432916  1.553285  2.238941  2.534180
+1.109946  1.231415  1.412105  1.516055  2.308569  2.599903
+1.120273  1.235535  1.425736  1.509519  2.435529  2.643814
+1.085869  1.189296  1.392718  1.494347  2.129342  2.508989
+1.020500  1.173144  1.440965  1.574421  2.335855  2.524051
+1.040551  1.174338  1.525717  1.693110  2.493748  2.632352
+1.034516  1.205262  1.365087  1.513000  2.471788  2.578008
+1.079383  1.204002  1.332428  1.456604  2.502131  2.665633
+1.088863  1.236949  1.357003  1.564945  2.602020  2.707576
+1.106792  1.262402  1.367273  1.823952  2.598579  2.676300
+1.085013  1.233527  1.311463  1.730333  2.560087  2.690320
+1.069205  1.180224  1.343020  1.474834  2.268046  2.544311
+1.039392  1.375617  1.721445  2.038018  2.463998  2.600812
+1.267853  1.384109  1.659902  1.934021  2.207761  2.424577
+1.225276  1.316621  1.678147  1.819230  2.165345  2.498548
+1.114141  1.283029  1.655518  1.879671  2.352472  2.553537
+1.094762  1.370017  1.799126  2.082377  2.469494  2.578819
+1.041250  1.472757  1.748735  2.047588  2.511699  2.589828
+1.071665  1.456546  1.700524  1.927317  2.441484  2.607003
+0.929006  1.487241  1.669550  1.885619  2.544274  2.628318
+0.844366  1.339712  1.812456  2.300208  2.566012  2.631255
+0.761441  1.279951  1.670446  2.006350  2.526824  2.607557
+0.716643  1.374843  1.843436  2.126958  2.552993  2.613146
+0.749967  1.598458  1.883266  2.050443  2.579184  2.614111
+0.759376  1.596383  1.929103  1.984550  2.566734  2.654207
+0.724977  1.682905  1.888292  2.034796  2.503861  2.565502
+0.812327  1.669865  1.961771  2.102146  2.538781  2.598559
+0.767334  1.594629  1.984319  2.133419  2.501689  2.557813
+0.760230  1.650647  1.928366  2.094047  2.565241  2.596082
+0.766762  1.648062  1.858552  2.078593  2.587079  2.608213
+0.860938  1.629253  1.824855  2.067350  2.563373  2.603209
+0.960953  1.583632  1.752206  2.078444  2.555531  2.628507
+1.007927  1.548004  1.734955  2.185660  2.489350  2.551445
+1.040401  1.471117  1.643519  2.051558  2.508524  2.579168
+1.096025  1.457427  1.604009  1.926200  2.482033  2.552204
+1.130428  1.431534  1.592806  2.014740  2.510652  2.567779
+1.197898  1.465481  1.622929  2.075950  2.507052  2.582750
+1.258831  1.504797  1.659109  1.970653  2.595750  2.685651
+1.315451  1.467446  1.705718  1.898634  2.602572  2.704978
+1.272475  1.431894  1.712848  1.940258  2.650379  2.717166
+1.278865  1.528652  1.796202  1.995202  2.501761  2.587606
+1.458616  1.693943  2.067903  2.264838  2.506857  2.623939
+1.718797  1.909611  2.147601  2.354174  2.485581  2.591269
+1.813873  1.875483  2.097637  2.329683  2.497798  2.596247
+1.744286  1.859449  2.043169  2.284589  2.430897  2.538572
+1.514180  1.808296  1.933791  2.234651  2.462232  2.546237
+1.489264  1.781194  1.908004  2.144484  2.418589  2.513858
+1.434785  1.679793  1.817348  2.105365  2.431372  2.528241
+1.469581  1.589507  1.813510  2.213129  2.440502  2.520511
+1.496287  1.640049  1.893865  2.298621  2.484705  2.576207
+1.333417  1.584728  1.893019  2.121814  2.525345  2.632617
+1.518722  1.735840  1.956529  2.176426  2.465338  2.572342
+1.520953  1.742556  2.010582  2.133578  2.447458  2.566704
+1.458119  1.692227  2.001920  2.120543  2.431042  2.565112
+1.526915  1.662389  2.025135  2.125056  2.537873  2.626810
+1.498303  1.644212  1.960732  2.103288  2.440309  2.572412
+1.415476  1.548286  1.770800  2.099931  2.450265  2.599463
+1.367188  1.460632  1.739482  2.074030  2.551953  2.639997
diff --git a/codec2/branches/0.7/unittest/lsp5.txt b/codec2/branches/0.7/unittest/lsp5.txt
new file mode 100644 (file)
index 0000000..05d7221
--- /dev/null
@@ -0,0 +1,18 @@
+ 950
+1050
+1150
+1250
+1350
+1450
+1550
+1650
+1750
+1850
+1950
+2050
+2150
+2250
+2350
+2450
+
+
diff --git a/codec2/branches/0.7/unittest/lsp6.txt b/codec2/branches/0.7/unittest/lsp6.txt
new file mode 100644 (file)
index 0000000..d1207ff
--- /dev/null
@@ -0,0 +1,18 @@
+1100
+1200
+1300
+1400
+1500
+1600
+1700
+1800
+1900
+2000
+2100
+2200
+2300
+2400
+2500
+2600
+
+
diff --git a/codec2/branches/0.7/unittest/lsp7.txt b/codec2/branches/0.7/unittest/lsp7.txt
new file mode 100644 (file)
index 0000000..1f6eaa6
--- /dev/null
@@ -0,0 +1,18 @@
+1500
+1600
+1700
+1800
+1900
+2000
+2100
+2200
+2300
+2400
+2500
+2600
+2700
+2800
+2900
+3000
+
+
diff --git a/codec2/branches/0.7/unittest/lsp8.txt b/codec2/branches/0.7/unittest/lsp8.txt
new file mode 100644 (file)
index 0000000..89607c8
--- /dev/null
@@ -0,0 +1,10 @@
+2300
+2400
+2500
+2600
+2700
+2800
+2900
+3000
+
+
diff --git a/codec2/branches/0.7/unittest/lsp9.txt b/codec2/branches/0.7/unittest/lsp9.txt
new file mode 100644 (file)
index 0000000..82be58c
--- /dev/null
@@ -0,0 +1,10 @@
+2500
+2600
+2700
+2800
+2900
+3000
+3100
+3200
+
+
diff --git a/codec2/branches/0.7/unittest/lspd456.txt b/codec2/branches/0.7/unittest/lspd456.txt
new file mode 100644 (file)
index 0000000..07462ba
--- /dev/null
@@ -0,0 +1,1024 @@
+0.347624  0.090959  0.454834
+0.446215  0.124000  0.370817
+0.409839  0.143155  0.295004
+0.440759  0.090281  0.296885
+0.465214  0.048451  0.542712
+0.471598  0.086037  0.483358
+0.372213  0.179217  0.438123
+0.592442  0.166741  0.433982
+0.399563  0.151320  0.400160
+0.479513  0.108517  0.258405
+0.485953  0.066923  0.193914
+0.548002  0.077271  0.152336
+0.565599  0.143205  0.140294
+0.558550  0.201462  0.109620
+0.607051  0.211633  0.152670
+0.670273  0.190261  0.139432
+0.430187  0.478301  0.135903
+0.148336  0.680821  0.114594
+0.185120  0.925628  0.147625
+0.249453  0.196637  0.241588
+0.179636  0.162617  0.313756
+0.586115  0.159387  0.307418
+0.472213  0.142351  0.245426
+0.384650  0.125831  0.240183
+0.332192  0.095235  0.255403
+0.300937  0.083633  0.239104
+0.282901  0.084036  0.324663
+0.264823  0.053630  0.355336
+0.262817  0.057144  0.308867
+0.235162  0.063366  0.290788
+0.225952  0.074491  0.259080
+0.250763  0.056393  0.263298
+0.261983  0.035121  0.221390
+0.232025  0.071049  0.211475
+0.251247  0.084420  0.177652
+0.317549  0.092361  0.194930
+0.376276  0.108869  0.213490
+0.407707  0.134249  0.200956
+0.324354  0.161579  0.180522
+0.155666  0.212650  0.191861
+0.276764  0.149348  0.164832
+0.232067  0.140034  0.296200
+0.202557  0.227413  0.232181
+0.213631  0.254317  0.286816
+0.230290  0.348972  0.223799
+0.073922  0.234044  0.444311
+0.165732  0.157286  0.377940
+0.143741  0.116266  0.367517
+0.170743  0.108278  0.335489
+0.204941  0.105478  0.323687
+0.232372  0.096166  0.294273
+0.249692  0.106680  0.233431
+0.247681  0.098716  0.205549
+0.285627  0.093674  0.181026
+0.273729  0.071657  0.199517
+0.324046  0.078751  0.174477
+0.320316  0.099534  0.141530
+0.305721  0.138944  0.194222
+0.307697  0.112445  0.306832
+0.263996  0.168409  0.279904
+0.209440  0.206560  0.352981
+0.207167  0.322235  0.237881
+0.248742  0.300747  0.244987
+0.244240  0.372015  0.250098
+0.311161  0.424673  0.225040
+0.297068  0.321411  0.313296
+0.379598  0.254957  0.371188
+0.432562  0.150907  0.250569
+0.490914  0.159011  0.203063
+0.459581  0.210629  0.184517
+0.365981  0.161992  0.242609
+0.273934  0.337911  0.234642
+0.303721  0.505646  0.388642
+0.245707  0.638533  0.280329
+0.225268  0.652879  0.192438
+0.258619  0.514447  0.279012
+0.316225  0.442602  0.335354
+0.376736  0.486777  0.308274
+0.327223  0.324066  0.242576
+0.485431  0.280997  0.355045
+0.572007  0.122510  0.240640
+0.616966  0.130938  0.227853
+0.513791  0.196874  0.180058
+0.466626  0.182542  0.223111
+0.402779  0.115602  0.343902
+0.375184  0.115227  0.402459
+0.273038  0.096940  0.441549
+0.286064  0.098337  0.549602
+0.246440  0.074548  0.556880
+0.236129  0.064941  0.588188
+0.209837  0.057975  0.532197
+0.259255  0.105430  0.407552
+0.302610  0.088086  0.382011
+0.330261  0.083490  0.318869
+0.339807  0.116430  0.207260
+0.296092  0.172928  0.144366
+0.253885  0.186664  0.166529
+0.277668  0.172442  0.196902
+0.314677  0.169787  0.285051
+0.278732  0.261731  0.151343
+0.192094  0.380939  0.072290
+0.164268  0.445241  0.088517
+0.213885  0.495691  0.078607
+0.244315  0.538432  0.099402
+0.213845  0.607105  0.091577
+0.286835  0.597563  0.087259
+0.318522  0.532846  0.080556
+0.284601  0.472920  0.105552
+0.326441  0.404994  0.109082
+0.361786  0.342944  0.134275
+0.405219  0.182087  0.266692
+0.339703  0.133107  0.349810
+0.318105  0.105264  0.418487
+0.268618  0.127749  0.519300
+0.210097  0.094867  0.551063
+0.184708  0.182810  0.698480
+0.158544  0.111449  0.634672
+0.170413  0.071464  0.657281
+0.171397  0.082903  0.699070
+0.201223  0.064064  0.627255
+0.180269  0.136502  0.501476
+0.221574  0.070933  0.434092
+0.211382  0.073149  0.481703
+0.114169  0.100113  0.915283
+0.146052  0.246456  0.633652
+0.275922  0.245082  0.498471
+0.266161  0.247382  0.434042
+0.302721  0.126115  0.373389
+0.300980  0.138225  0.249755
+0.290909  0.136927  0.286352
+0.350897  0.109421  0.304023
+0.386165  0.088656  0.245381
+0.382333  0.105625  0.151256
+0.421477  0.091637  0.128128
+0.404884  0.121558  0.102941
+0.322205  0.220312  0.077762
+0.283695  0.260465  0.065194
+0.383440  0.199544  0.094240
+0.480839  0.209932  0.141564
+0.441391  0.230279  0.141240
+0.362251  0.290803  0.099062
+0.301174  0.368993  0.092277
+0.377409  0.363282  0.091280
+0.337772  0.461506  0.076775
+0.373032  0.519469  0.124106
+0.314757  0.552002  0.139769
+0.250607  0.492442  0.145557
+0.335493  0.328724  0.166487
+0.534645  0.644574  0.182718
+0.488781  0.353657  0.328925
+0.554548  0.233808  0.376737
+0.492450  0.553839  0.367700
+0.394815  0.210972  0.142784
+0.238589  0.303384  0.080013
+0.224147  0.255123  0.068313
+0.256497  0.235171  0.099373
+0.297511  0.154648  0.113728
+0.305673  0.117198  0.107972
+0.290657  0.090218  0.126335
+0.258861  0.096775  0.145361
+0.259983  0.099517  0.110715
+0.118646  0.148765  0.076387
+0.145023  0.105727  0.109695
+0.181102  0.134847  0.077805
+0.211445  0.088585  0.101849
+0.198248  0.105956  0.172142
+0.180296  0.129252  0.141319
+0.221042  0.083049  0.144665
+0.212791  0.063744  0.179816
+0.167506  0.115897  0.208529
+0.205822  0.062715  0.241237
+0.172651  0.083940  0.183620
+0.124447  0.084470  0.196419
+0.186739  0.063095  0.269351
+0.160093  0.104677  0.295459
+0.143447  0.142741  0.276552
+0.123263  0.196627  0.476282
+0.108325  0.605694  0.334137
+0.285290  0.315781  0.362135
+0.353244  0.270895  0.333924
+0.263653  0.300345  0.291813
+0.208575  0.465618  0.269759
+0.220467  0.418879  0.223504
+0.146022  0.320151  0.302772
+0.183727  0.325046  0.366600
+0.171236  0.313334  0.429997
+0.247905  0.276696  0.319839
+0.127071  0.396634  0.387451
+0.073374  0.373431  0.434696
+0.210963  0.363358  0.326782
+0.268129  0.366304  0.302607
+0.276157  0.386117  0.406186
+0.340781  0.360413  0.321075
+0.431904  0.276036  0.404829
+0.495040  0.225348  0.450453
+0.262250  0.219954  0.192843
+0.261002  0.142204  0.241314
+0.278943  0.115884  0.204352
+0.260726  0.138775  0.101751
+0.183464  0.210049  0.109076
+0.162266  0.261270  0.088046
+0.236604  0.196725  0.126686
+0.316678  0.196107  0.179685
+0.243299  0.306025  0.151947
+0.400615  0.162590  0.232750
+0.372639  0.216589  0.209970
+0.140820  0.222509  0.129726
+0.097670  0.184209  0.193834
+0.193869  0.127067  0.282177
+0.208523  0.142275  0.352114
+0.126584  0.151378  0.342813
+0.235628  0.172984  0.215508
+0.249437  0.175207  0.390557
+0.255433  0.127918  0.372391
+0.359147  0.151917  0.290168
+0.351722  0.205430  0.115799
+0.267453  0.279897  0.108704
+0.350766  0.239207  0.087893
+0.318117  0.273230  0.085462
+0.381113  0.237724  0.065900
+0.219080  0.256349  0.369571
+0.196609  0.194954  0.411062
+0.213051  0.139071  0.398959
+0.244873  0.146332  0.435157
+0.235630  0.181860  0.511397
+0.292860  0.209424  0.147620
+0.331811  0.148006  0.093985
+0.293049  0.144326  0.069176
+0.281985  0.195922  0.077879
+0.228381  0.205538  0.080972
+0.235938  0.163446  0.071037
+0.168487  0.195102  0.072566
+0.199465  0.163509  0.108306
+0.255681  0.174779  0.108553
+0.302851  0.083047  0.155297
+0.321466  0.113845  0.176969
+0.338191  0.096339  0.224480
+0.360544  0.065938  0.241459
+0.378601  0.057338  0.276674
+0.368373  0.076055  0.310651
+0.344437  0.070848  0.286673
+0.376329  0.104163  0.278687
+0.355476  0.110470  0.243634
+0.362002  0.085143  0.260003
+0.411330  0.051881  0.247678
+0.414240  0.068326  0.276653
+0.410484  0.082208  0.354845
+0.418149  0.061438  0.388696
+0.433860  0.142628  0.438577
+0.495950  0.091923  0.413338
+0.434164  0.131070  0.325030
+0.347126  0.153569  0.402577
+0.458076  0.093458  0.443701
+0.495375  0.120909  0.562539
+0.589514  0.080183  0.512524
+0.531194  0.063220  0.328711
+0.499017  0.059249  0.243179
+0.530991  0.079568  0.259341
+0.585658  0.077791  0.416801
+0.536002  0.122366  0.473100
+0.511945  0.062231  0.459896
+0.486451  0.116847  0.370233
+0.481843  0.144265  0.420622
+0.407554  0.241229  0.282167
+0.320925  0.282038  0.252246
+0.225131  0.374849  0.479590
+0.228011  0.237458  0.622277
+0.261961  0.179596  0.806264
+0.076218  0.139692  1.043456
+0.151340  0.328626  0.887716
+0.337210  0.198192  0.379580
+0.460842  0.167548  0.160717
+0.477628  0.229247  0.072684
+0.451350  0.203095  0.091994
+0.420022  0.110903  0.058632
+0.449733  0.161924  0.093239
+0.411145  0.163560  0.078750
+0.435222  0.142044  0.126205
+0.420083  0.099757  0.203874
+0.370276  0.131184  0.131964
+0.354905  0.098162  0.185357
+0.354880  0.098109  0.151202
+0.355875  0.081150  0.202714
+0.329850  0.070604  0.206228
+0.326647  0.063899  0.235204
+0.330171  0.045901  0.207938
+0.329941  0.047031  0.176438
+0.337293  0.074879  0.140863
+0.368014  0.066698  0.168744
+0.300423  0.104975  0.266224
+0.156403  0.547850  0.093121
+0.288125  0.304080  0.176781
+0.210923  0.180445  0.267334
+0.236880  0.217374  0.275212
+0.213759  0.376162  0.184946
+0.372297  0.209676  0.309731
+0.445389  0.226789  0.291673
+0.519740  0.112223  0.265429
+0.472434  0.174961  0.115646
+0.417682  0.274453  0.070003
+0.458596  0.258372  0.047548
+0.455272  0.274496  0.086373
+0.444215  0.318398  0.074804
+0.427749  0.360899  0.081827
+0.369149  0.335197  0.063361
+0.408385  0.324949  0.072860
+0.384052  0.298347  0.060899
+0.373725  0.264760  0.080748
+0.352145  0.176148  0.080707
+0.310910  0.188712  0.108730
+0.250319  0.151051  0.140139
+0.238071  0.144852  0.173219
+0.228573  0.106294  0.172491
+0.217371  0.097639  0.248280
+0.253003  0.069144  0.233568
+0.256968  0.055968  0.160406
+0.235219  0.115044  0.075964
+0.336525  0.077151  0.097771
+0.295976  0.059336  0.123351
+0.324309  0.059429  0.397350
+0.348266  0.106120  0.501358
+0.340380  0.127511  0.440305
+0.275937  0.136374  0.468843
+0.266087  0.282816  0.379226
+0.228482  0.306643  0.416738
+0.246227  0.200955  0.450023
+0.318533  0.209335  0.569205
+0.413909  0.089360  0.618461
+0.382377  0.110800  0.185218
+0.298919  0.076922  0.206253
+0.295486  0.062198  0.170334
+0.220572  0.123944  0.132661
+0.199126  0.138104  0.199012
+0.150799  0.164435  0.128584
+0.141718  0.112651  0.157620
+0.218667  0.109546  0.215544
+0.255989  0.086240  0.259903
+0.300656  0.046011  0.269817
+0.291157  0.059173  0.236624
+0.310810  0.077525  0.293206
+0.314641  0.049528  0.310313
+0.279240  0.086840  0.353600
+0.165264  0.103047  0.417338
+0.208135  0.117070  0.429435
+0.232791  0.103415  0.462895
+0.271864  0.129281  0.319815
+0.366981  0.141852  0.212178
+0.373262  0.242359  0.117112
+0.422067  0.278600  0.123501
+0.338944  0.345572  0.098531
+0.308216  0.428668  0.066433
+0.271454  0.398601  0.070491
+0.278913  0.492798  0.060932
+0.247776  0.441372  0.071561
+0.343570  0.386117  0.081017
+0.461654  0.239819  0.108222
+0.430485  0.272031  0.176591
+0.408685  0.297320  0.097183
+0.485213  0.284632  0.069179
+0.461397  0.373449  0.100410
+0.671420  0.378029  0.088090
+0.808405  0.276010  0.102934
+0.704869  0.430068  0.070162
+0.554941  0.507594  0.125272
+0.359919  0.301913  0.230542
+0.251847  0.314817  0.199777
+0.293156  0.307596  0.224547
+0.356977  0.402190  0.240191
+0.290117  0.743767  0.395678
+0.392248  0.703453  0.280630
+0.476220  0.520924  0.129796
+0.527212  0.411812  0.063633
+0.542919  0.358453  0.095274
+0.556482  0.315834  0.117993
+0.482078  0.326051  0.096336
+0.420379  0.426709  0.088736
+0.369052  0.415845  0.093306
+0.437630  0.334794  0.118496
+0.466644  0.293770  0.233791
+0.508918  0.228596  0.222776
+0.484639  0.121415  0.212331
+0.443499  0.096268  0.231387
+0.511197  0.174015  0.270205
+0.352556  0.283611  0.272015
+0.293392  0.425947  0.162990
+0.332821  0.275494  0.174376
+0.298858  0.241340  0.192968
+0.305188  0.294785  0.139588
+0.375530  0.449251  0.144064
+0.292345  0.781183  0.254538
+0.358461  0.243978  0.182222
+0.415777  0.244409  0.238222
+0.467064  0.146980  0.298146
+0.416339  0.232371  0.189786
+0.191873  0.319957  0.083328
+0.203436  0.360141  0.135797
+0.374532  0.135837  0.364913
+0.268287  0.102231  0.714801
+0.254501  0.146265  0.649860
+0.218848  0.270739  0.467287
+0.188426  0.170744  0.462937
+0.245247  0.107864  0.332378
+0.122418  0.152546  0.533111
+0.079016  0.314882  0.596442
+0.126964  0.240808  0.550476
+0.075791  0.140645  0.502026
+0.093230  0.113111  0.626546
+0.172159  0.080636  0.831021
+0.068199  0.206815  0.906033
+0.062132  0.233971  0.778223
+0.074593  0.142563  0.751383
+0.109526  0.088462  0.775006
+0.124547  0.075148  0.714916
+0.219269  0.045432  0.388959
+0.127591  0.145316  0.230824
+0.075140  0.099358  0.462657
+0.064338  0.123266  0.563272
+0.078238  0.117014  0.688975
+0.084643  0.135331  0.834358
+0.139739  0.180181  0.788226
+0.146212  0.130036  0.742469
+0.142021  0.071166  0.618520
+0.264581  0.062830  0.446908
+0.320084  0.063118  0.350973
+0.396868  0.104191  0.308665
+0.464396  0.100744  0.190844
+0.474587  0.135638  0.122223
+0.505265  0.164031  0.083774
+0.508671  0.149050  0.116783
+0.494586  0.165303  0.148019
+0.472521  0.133399  0.178996
+0.472105  0.087004  0.224228
+0.446638  0.121806  0.273503
+0.367261  0.095789  0.337281
+0.359383  0.069161  0.376118
+0.283834  0.061745  0.401507
+0.233699  0.158991  0.567659
+0.131424  0.169028  0.614621
+0.073539  0.165230  0.608024
+0.084229  0.293229  0.506663
+0.148758  0.720830  0.237339
+0.256384  0.243042  0.348749
+0.395262  0.183863  0.343968
+0.381026  0.153580  0.322679
+0.344857  0.169307  0.357051
+0.180931  0.274934  0.267210
+0.133417  0.315317  0.364657
+0.184162  0.267604  0.330168
+0.220026  0.283042  0.231767
+0.259555  0.237606  0.232106
+0.276933  0.249820  0.287878
+0.349980  0.282625  0.421991
+0.481016  0.212218  0.325727
+0.458797  0.184528  0.274070
+0.484482  0.148105  0.341873
+0.526047  0.155385  0.400111
+0.526136  0.175193  0.328794
+0.556038  0.116326  0.373700
+0.437912  0.183108  0.320129
+0.154855  0.684819  0.527786
+0.142128  0.492151  0.711010
+0.062256  0.311531  0.691655
+0.180612  0.307234  0.730728
+0.152739  0.786052  0.357275
+0.421748  0.155971  0.355152
+0.513427  0.140653  0.180397
+0.503293  0.090152  0.226204
+0.470923  0.079454  0.290961
+0.458356  0.094363  0.377705
+0.447899  0.062986  0.355100
+0.490749  0.048144  0.340535
+0.490854  0.079767  0.368968
+0.568302  0.078153  0.271815
+0.574387  0.098205  0.200963
+0.644881  0.089413  0.208920
+0.636596  0.088651  0.058559
+0.553118  0.323894  0.063352
+0.583298  0.295978  0.091612
+0.606749  0.318066  0.058865
+0.487005  0.454915  0.177572
+0.329222  0.315592  0.285150
+0.299399  0.277718  0.282728
+0.302006  0.358174  0.148859
+0.334243  0.327319  0.350426
+0.291480  0.333984  0.274831
+0.383078  0.333489  0.255643
+0.406396  0.413215  0.258302
+0.479588  0.360631  0.169112
+0.594135  0.255844  0.137076
+0.847445  0.093619  0.248967
+0.810961  0.161433  0.181118
+0.732094  0.308294  0.140083
+0.623878  0.379968  0.070210
+0.567617  0.374818  0.060450
+0.664229  0.294886  0.104059
+0.645906  0.246204  0.135086
+0.673058  0.227775  0.100138
+0.659455  0.250925  0.067423
+0.627904  0.283712  0.067938
+0.581249  0.267066  0.063458
+0.617716  0.219403  0.068390
+0.599018  0.303403  0.166919
+0.450459  0.568624  0.270030
+0.497221  0.226918  0.270466
+0.411324  0.232483  0.331049
+0.320406  0.443850  0.269652
+0.187291  0.561422  0.165638
+0.294572  0.343681  0.200707
+0.326397  0.258546  0.286441
+0.279400  0.306226  0.260735
+0.193123  0.385992  0.258247
+0.342327  0.381838  0.147491
+0.433089  0.378484  0.207774
+0.362956  0.347448  0.222551
+0.361638  0.480201  0.226996
+0.384522  0.377667  0.186341
+0.427881  0.296866  0.282612
+0.563327  0.229524  0.304696
+0.567170  0.247155  0.202733
+0.585411  0.220038  0.115594
+0.519250  0.229429  0.071582
+0.466406  0.348495  0.062605
+0.474052  0.430997  0.059085
+0.456952  0.434321  0.092489
+0.443242  0.479322  0.066114
+0.424170  0.532398  0.074007
+0.394911  0.475416  0.086889
+0.452632  0.411710  0.140813
+0.403571  0.307690  0.141199
+0.330609  0.309675  0.202639
+0.162152  0.333000  0.246273
+0.104212  0.372786  0.256919
+0.136824  0.521324  0.228461
+0.104865  0.608493  0.187863
+0.112234  0.499159  0.140580
+0.103176  0.394350  0.106114
+0.097342  0.431118  0.194462
+0.199846  0.166342  0.150206
+0.257308  0.138618  0.204462
+0.377777  0.076428  0.214777
+0.396461  0.078672  0.186686
+0.412491  0.083042  0.157354
+0.409492  0.113963  0.166822
+0.402656  0.132414  0.136860
+0.384318  0.169269  0.141277
+0.379760  0.142363  0.169790
+0.434051  0.125795  0.180081
+0.291493  0.229394  0.111634
+0.413319  0.193400  0.112837
+0.413655  0.226896  0.114264
+0.433596  0.176677  0.130118
+0.324845  0.251559  0.120351
+0.359504  0.214180  0.154811
+0.415838  0.197748  0.221624
+0.330767  0.232694  0.237892
+0.283703  0.199163  0.276558
+0.402389  0.264705  0.562024
+0.405915  0.068161  0.722076
+0.408789  0.081683  0.224705
+0.412949  0.070850  0.318290
+0.383543  0.088037  0.376585
+0.413842  0.087764  0.457480
+0.394697  0.085379  0.526908
+0.326022  0.124012  0.545103
+0.360363  0.103599  0.573651
+0.374875  0.071392  0.577138
+0.426542  0.064067  0.485994
+0.414344  0.062295  0.436129
+0.357597  0.053368  0.442984
+0.352690  0.061527  0.481466
+0.435965  0.091560  0.330005
+0.452104  0.173696  0.389629
+0.240811  0.227686  0.399164
+0.387054  0.212876  0.250823
+0.348481  0.199112  0.239045
+0.406692  0.124037  0.262865
+0.364589  0.130457  0.265840
+0.418494  0.152965  0.158070
+0.525395  0.176045  0.224438
+0.649496  0.162294  0.265624
+0.577476  0.087708  0.311571
+0.635120  0.080693  0.336377
+0.695460  0.066421  0.421660
+0.621358  0.149936  0.353147
+0.567838  0.187842  0.239684
+0.610053  0.188465  0.189601
+0.290729  0.370305  0.245506
+0.474752  0.256582  0.192554
+0.523264  0.281951  0.174076
+0.487445  0.266791  0.140722
+0.418187  0.308871  0.224831
+0.542461  0.339261  0.179909
+0.660046  0.325237  0.064232
+0.699190  0.263381  0.081222
+0.771760  0.141829  0.114068
+0.849307  0.167518  0.110492
+0.768620  0.215479  0.101016
+0.943168  0.112917  0.126022
+0.700213  0.207371  0.114043
+0.520214  0.355040  0.056977
+0.501121  0.416740  0.097933
+0.413408  0.446710  0.207348
+0.316233  0.501402  0.172782
+0.422015  0.299620  0.334807
+0.467201  0.278473  0.294606
+0.449356  0.314132  0.169959
+0.383191  0.318048  0.185054
+0.263466  0.409830  0.258522
+0.344203  0.180472  0.319223
+0.362266  0.169616  0.180383
+0.341699  0.182702  0.146822
+0.335987  0.174976  0.210809
+0.395083  0.165288  0.194206
+0.465646  0.099187  0.323536
+0.462006  0.053739  0.310921
+0.455068  0.081078  0.262737
+0.418012  0.119395  0.233351
+0.345448  0.135789  0.188425
+0.351492  0.162596  0.117706
+0.344759  0.149410  0.147248
+0.314307  0.134967  0.151339
+0.286415  0.116093  0.164754
+0.277756  0.126139  0.130984
+0.361188  0.110945  0.070191
+0.361209  0.201107  0.056536
+0.284536  0.314088  0.069545
+0.432086  0.300442  0.045010
+0.395858  0.449191  0.053920
+0.358265  0.503243  0.063399
+0.373607  0.577103  0.071048
+0.277978  0.673759  0.088057
+0.361589  0.613722  0.123032
+0.384724  0.684712  0.091070
+0.459571  0.724691  0.081391
+0.440636  0.611416  0.071085
+0.491405  0.544525  0.066202
+0.495390  0.482599  0.069217
+0.585200  0.253363  0.096585
+0.538917  0.276943  0.073936
+0.500464  0.315306  0.054544
+0.664338  0.150817  0.196704
+0.500195  0.080074  0.282262
+0.530558  0.067443  0.375424
+0.440087  0.352641  0.277248
+0.390681  0.267263  0.209143
+0.359333  0.241690  0.261267
+0.370447  0.247920  0.308405
+0.336215  0.226039  0.305830
+0.195785  0.339497  0.283349
+0.151348  0.445352  0.258280
+0.266713  0.219848  0.307969
+0.218114  0.294964  0.285277
+0.174107  0.381064  0.212437
+0.155914  0.377087  0.116389
+0.134386  0.253742  0.304443
+0.151029  0.213087  0.353221
+0.217483  0.140058  0.241820
+0.242753  0.116518  0.270671
+0.285332  0.068762  0.270927
+0.317498  0.078582  0.264060
+0.277862  0.110739  0.250417
+0.308456  0.109889  0.221582
+0.276315  0.089684  0.226545
+0.333980  0.135929  0.231792
+0.334591  0.166897  0.259283
+0.397876  0.537888  0.188209
+0.290878  0.394567  0.198465
+0.163752  0.435990  0.173066
+0.191115  0.481622  0.133956
+0.260636  0.377095  0.197277
+0.338080  0.235880  0.426527
+0.378463  0.127767  0.454089
+0.385046  0.056905  0.498118
+0.374068  0.049953  0.405294
+0.271022  0.098818  0.289459
+0.182680  0.217988  0.292618
+0.225435  0.235809  0.318205
+0.177229  0.103515  0.463042
+0.175834  0.055640  0.486987
+0.183210  0.062875  0.440837
+0.226003  0.097193  0.366732
+0.251396  0.070201  0.393377
+0.234201  0.074576  0.326442
+0.223004  0.066314  0.353857
+0.186211  0.106789  0.245913
+0.151535  0.094840  0.253435
+0.195080  0.089425  0.287492
+0.162720  0.067083  0.227111
+0.196415  0.076298  0.212223
+0.180505  0.083889  0.141164
+0.246234  0.066099  0.131760
+0.282666  0.087223  0.081269
+0.340580  0.122366  0.117784
+0.376555  0.091363  0.111974
+0.393102  0.087543  0.417517
+0.297217  0.163487  0.549749
+0.362450  0.174227  0.634258
+0.323933  0.627863  0.231764
+0.327261  0.458545  0.128228
+0.345717  0.429564  0.187171
+0.260069  0.337062  0.335170
+0.306881  0.385334  0.293359
+0.271898  0.457259  0.215823
+0.259289  0.441347  0.303200
+0.363305  0.398019  0.291679
+0.291795  0.279053  0.324220
+0.294547  0.262771  0.399943
+0.371243  0.306137  0.366069
+0.382008  0.339743  0.307443
+0.438316  0.228950  0.367986
+0.537463  0.298231  0.257224
+0.645494  0.307091  0.289935
+0.669328  0.320508  0.177252
+0.616771  0.434999  0.131058
+0.565925  0.511230  0.217275
+0.568203  0.409220  0.089091
+0.577548  0.394258  0.217345
+0.648943  0.237348  0.200174
+0.599721  0.237036  0.256373
+0.754878  0.197561  0.266084
+0.714487  0.175657  0.200087
+0.710745  0.237411  0.165014
+0.720827  0.339743  0.072832
+0.545081  0.459358  0.071144
+0.346804  0.807739  0.104644
+0.216743  0.762837  0.120249
+0.197697  0.658146  0.387627
+0.165912  0.499878  0.549502
+0.241754  0.317091  0.529186
+0.169200  0.553212  0.416930
+0.320751  0.621112  0.366138
+0.337485  0.556049  0.269330
+0.250664  0.574848  0.514561
+0.140209  0.430307  0.459246
+0.162363  0.246323  0.477493
+0.381402  0.092797  0.469234
+0.459381  0.155970  0.481903
+0.442539  0.088546  0.414977
+0.408686  0.121373  0.498045
+0.329248  0.153610  0.482630
+0.331997  0.142511  0.315883
+0.221799  0.396419  0.292101
+0.176966  0.273274  0.211951
+0.203478  0.286430  0.129390
+0.216827  0.258314  0.184043
+0.234488  0.175930  0.313819
+0.311501  0.270429  0.211948
+0.294432  0.162487  0.229611
+0.329328  0.117112  0.277223
+0.416641  0.099298  0.274074
+0.554873  0.155235  0.201501
+0.569426  0.189358  0.155950
+0.539367  0.241198  0.105444
+0.501517  0.357700  0.084370
+0.545573  0.281564  0.125541
+0.514425  0.301811  0.096910
+0.460345  0.293995  0.114532
+0.487409  0.345311  0.229900
+0.412521  0.355808  0.145545
+0.509374  0.347915  0.128813
+0.629454  0.215821  0.104369
+0.658561  0.176420  0.084630
+0.700668  0.136656  0.112851
+0.667071  0.122890  0.157514
+0.612182  0.148628  0.155034
+0.539605  0.176739  0.090625
+0.590039  0.124542  0.106912
+0.629817  0.100757  0.139713
+0.604716  0.105384  0.173581
+0.720555  0.111138  0.330763
+0.245112  0.336634  0.265337
+0.226689  0.424271  0.348303
+0.329654  0.359100  0.261678
+0.379459  0.286999  0.299860
+0.342863  0.299943  0.318446
+0.330710  0.371149  0.198420
+0.285053  0.275836  0.238793
+0.361749  0.196487  0.281140
+0.406042  0.191956  0.297341
+0.445690  0.223770  0.237164
+0.393133  0.274606  0.262027
+0.544286  0.142320  0.276324
+0.619365  0.107015  0.281186
+0.607150  0.081004  0.243243
+0.678787  0.091345  0.263915
+0.734877  0.105834  0.242728
+0.694254  0.100473  0.181406
+0.758976  0.109087  0.167450
+0.565683  0.217978  0.071529
+0.445274  0.395501  0.058069
+0.484692  0.379794  0.062350
+0.214619  0.245836  0.117895
+0.246969  0.229441  0.150311
+0.385481  0.258270  0.151377
+0.353085  0.290950  0.141139
+0.535642  0.170306  0.146284
+0.446113  0.090546  0.161019
+0.348613  0.118759  0.163942
+0.256859  0.116937  0.175945
+0.095533  0.124223  0.128081
+0.104333  0.215306  0.075249
+0.100294  0.187881  0.135738
+0.148622  0.275139  0.167339
+0.078452  0.360587  0.329967
+0.127610  0.289917  0.238589
+0.148272  0.316966  0.121487
+0.085461  0.330668  0.163259
+0.142401  0.216090  0.250904
+0.175731  0.166076  0.233510
+0.152278  0.156198  0.181459
+0.193328  0.210638  0.148227
+0.207811  0.191064  0.188672
+0.296438  0.161485  0.325233
+0.306068  0.199688  0.322695
+0.342566  0.219355  0.346721
+0.291750  0.188465  0.494566
+0.352065  0.234211  0.491138
+0.383860  0.596099  0.458394
+0.386344  0.202868  0.380113
+0.399359  0.282461  0.474285
+0.322622  0.279134  0.358938
+0.347701  0.262331  0.223429
+0.424998  0.191838  0.164353
+0.451151  0.131623  0.217203
+0.456273  0.120859  0.149404
+0.490554  0.108928  0.157243
+0.517816  0.130242  0.142810
+0.500090  0.217505  0.103504
+0.514504  0.191274  0.118656
+0.554806  0.122508  0.163126
+0.442524  0.162708  0.199911
+0.388949  0.157852  0.109288
+0.504477  0.095186  0.125173
+0.477591  0.066576  0.138585
+0.452216  0.100773  0.107700
+0.485286  0.127587  0.074852
+0.488827  0.194629  0.066040
+0.426576  0.237428  0.067677
+0.340727  0.291206  0.061076
+0.243435  0.361855  0.071906
+0.382323  0.324483  0.098684
+0.414425  0.354228  0.048282
+0.401390  0.400107  0.040249
+0.403756  0.393196  0.073045
+0.357685  0.422727  0.054290
+0.376221  0.373641  0.056815
+0.334172  0.375680  0.054225
+0.296174  0.361326  0.050408
+0.326273  0.330339  0.064557
+0.420692  0.255904  0.094806
+0.421944  0.199537  0.068849
+0.326830  0.232006  0.153704
+0.301454  0.201485  0.233060
+0.258842  0.191789  0.343414
+0.294282  0.195861  0.362979
+0.286399  0.234317  0.360778
+0.319442  0.214047  0.274131
+0.333404  0.220264  0.204146
+0.386995  0.195077  0.182131
+0.404880  0.215968  0.423836
+0.477146  0.435211  0.260239
+0.532189  0.227684  0.146512
+0.568278  0.159946  0.110703
+0.605267  0.174809  0.088477
+0.624009  0.142924  0.112772
+0.652905  0.148818  0.139204
+0.714256  0.157313  0.148093
+0.720760  0.199261  0.080657
+0.741518  0.278514  0.083257
+0.566298  0.527298  0.062699
+0.445052  0.597589  0.130277
+0.526449  0.626948  0.074424
+0.801938  0.367141  0.075543
+0.916524  0.255963  0.112835
+0.645568  0.521635  0.064144
+0.608913  0.448818  0.064142
+0.629099  0.328544  0.099333
+0.620582  0.182449  0.132128
+0.590707  0.148356  0.186809
+0.543143  0.102875  0.300062
+0.527847  0.116107  0.336959
+0.499887  0.117763  0.297680
+0.508919  0.134512  0.236929
+0.531706  0.109558  0.239043
+0.541620  0.120673  0.208110
+0.517661  0.098274  0.183512
+0.449983  0.054085  0.247178
+0.575793  0.062186  0.355346
+0.489231  0.203337  0.380285
+0.340551  0.340643  0.414281
+0.210167  0.526078  0.337705
+0.284920  0.525512  0.222620
+0.208797  0.499630  0.207868
+0.267127  0.583546  0.176083
+0.228186  0.428672  0.171167
+0.258450  0.355455  0.160617
+0.273653  0.409657  0.120028
+0.264098  0.344696  0.111979
+0.222486  0.415597  0.112772
+0.199350  0.325482  0.185961
+0.294632  0.157878  0.367064
+0.346967  0.102272  0.381014
+0.324707  0.101328  0.346674
+0.300669  0.154767  0.427674
+0.297977  0.190730  0.402531
+0.322781  0.242743  0.378056
+0.419505  0.654624  0.200084
+0.318601  0.692538  0.162850
+0.178499  0.579044  0.270280
+0.195204  0.388057  0.398083
+0.241827  0.349617  0.379452
+0.315199  0.303795  0.489292
+0.380392  0.178450  0.504430
+0.414296  0.143625  0.555054
+0.339645  0.110851  0.633101
+0.315159  0.082478  0.583218
+0.337965  0.059219  0.531018
+0.321096  0.080831  0.498225
+0.307444  0.107476  0.461283
+0.278693  0.093535  0.490594
+0.252057  0.083619  0.514079
+0.224412  0.111350  0.505414
+0.169223  0.083911  0.512845
+0.208880  0.083504  0.402948
+0.187837  0.073111  0.335010
+0.206755  0.055269  0.311264
+0.156291  0.062835  0.298062
+0.156028  0.064082  0.415247
+0.129754  0.074279  0.474540
+0.183725  0.101044  0.375452
+0.181248  0.060180  0.378248
+0.178353  0.183494  0.547763
+0.303398  0.241676  0.322364
+0.263082  0.269825  0.205102
+0.295290  0.241493  0.251070
+0.310143  0.206645  0.446008
+0.249752  0.262630  0.261739
+0.225039  0.305225  0.344815
+0.153658  0.404495  0.314509
+0.142025  0.474338  0.358307
+0.228656  0.455858  0.431304
+0.360261  0.434834  0.461602
+0.432447  0.356868  0.399441
+0.405888  0.423867  0.341787
+0.307752  0.379122  0.354664
+0.495951  0.255588  0.098194
+0.590320  0.364141  0.130834
+0.523157  0.411325  0.142398
+0.622815  0.267082  0.098576
+0.586226  0.337718  0.086861
+0.396476  0.396958  0.127666
+0.278385  0.309875  0.439028
+0.210412  0.240403  0.530267
+0.142154  0.341782  0.515974
+0.236712  0.330636  0.302147
+0.313995  0.313085  0.102247
+0.536878  0.123790  0.095432
+0.546579  0.066696  0.222251
+0.528723  0.046496  0.288028
+0.490438  0.079978  0.328045
+0.416715  0.108530  0.389254
+0.350888  0.083964  0.417653
+0.307331  0.062124  0.473629
+0.274119  0.115537  0.597408
+0.226906  0.099518  0.609696
+0.147094  0.067376  0.550921
+0.178994  0.061997  0.585308
+0.132607  0.110425  0.587137
+0.110327  0.099682  0.549983
+0.068912  0.202205  0.534312
+0.065072  0.231313  0.620174
+0.080325  0.190639  0.689245
+0.127351  0.125355  0.674554
+0.110891  0.072596  0.663783
+0.097157  0.070549  0.589126
+0.106411  0.082418  0.509171
+0.125632  0.088198  0.439270
+0.126006  0.083980  0.396385
+0.144132  0.069483  0.352444
+0.105337  0.088013  0.358993
+0.119785  0.099438  0.312550
+0.070842  0.142954  0.331889
+0.071861  0.089577  0.402256
+0.108923  0.084005  0.258422
+0.092866  0.123378  0.193507
+0.088292  0.071041  0.315009
+0.063561  0.165270  0.420738
+0.074840  0.133173  0.262739
+0.089400  0.194231  0.262021
+0.079851  0.205849  0.344821
+0.157143  0.146865  0.421765
+0.125245  0.208011  0.414350
+0.174337  0.251983  0.396703
+0.084886  0.272191  0.354568
+0.110693  0.292372  0.436834
+0.211165  0.375835  0.619400
+0.062966  0.412899  0.552075
+0.081388  0.529721  0.443287
+0.081245  0.483334  0.304728
+0.138084  0.348639  0.182624
+0.103443  0.309738  0.080859
+0.104109  0.260851  0.123996
+0.091414  0.251910  0.196193
+0.076304  0.263206  0.278157
+0.134332  0.188036  0.301992
+0.107220  0.138757  0.409882
+0.128381  0.129478  0.471249
+0.160195  0.115412  0.544945
+0.191115  0.149126  0.609196
+0.184568  0.103795  0.587575
+0.248953  0.058854  0.636286
+0.192984  0.081624  0.751367
+0.220001  0.099182  0.668267
+0.223085  0.059316  0.689244
+0.276099  0.046871  0.774911
+0.314266  0.073942  0.676716
+0.296234  0.076044  0.626027
+0.279541  0.049108  0.565247
+0.285398  0.057887  0.519502
+0.243492  0.048975  0.483027
+0.309314  0.059143  0.435497
+0.387586  0.051625  0.354348
+0.397104  0.047268  0.326093
+0.434850  0.059475  0.193227
diff --git a/codec2/branches/0.7/unittest/lspd678910.txt b/codec2/branches/0.7/unittest/lspd678910.txt
new file mode 100644 (file)
index 0000000..6cd1695
--- /dev/null
@@ -0,0 +1,1025 @@
+5 1024
+0.490574  0.255810  0.097016  0.668209  0.076176
+0.319657  0.377243  0.111246  0.519778  0.213532
+0.364308  0.499601  0.080493  0.524374  0.178250
+0.309691  0.486066  0.086872  0.593653  0.081516
+0.511878  0.227659  0.205762  0.464504  0.072641
+0.415877  0.221666  0.335610  0.566378  0.068611
+0.432793  0.262579  0.300716  0.456684  0.072810
+0.449945  0.126438  0.410080  0.461448  0.063356
+0.395672  0.238704  0.113056  0.471384  0.175583
+0.271033  0.349694  0.122549  0.405050  0.094055
+0.256025  0.401662  0.153103  0.446633  0.101411
+0.196597  0.467529  0.166464  0.498735  0.097213
+0.180138  0.381420  0.152389  0.514638  0.089537
+0.132744  0.304911  0.152650  0.583153  0.097649
+0.111190  0.161269  0.163283  0.673181  0.079189
+0.123015  0.112572  0.323074  0.592470  0.066637
+0.161118  0.095718  0.455233  0.767700  0.071090
+0.152146  0.098727  0.256718  0.969609  0.130922
+0.237523  0.116394  0.260363  0.787369  0.066436
+0.281553  0.534802  0.112685  0.153703  0.108972
+0.312479  0.447863  0.170904  0.228491  0.097052
+0.296432  0.346142  0.293149  0.331820  0.110852
+0.262549  0.297210  0.087733  0.729481  0.079176
+0.212710  0.412005  0.145571  0.599877  0.097017
+0.235745  0.381859  0.105728  0.701574  0.097767
+0.254355  0.439673  0.075854  0.633815  0.087595
+0.329609  0.416567  0.112711  0.634041  0.079475
+0.403396  0.432572  0.162376  0.571168  0.158567
+0.287614  0.474969  0.161406  0.563635  0.139393
+0.283025  0.497138  0.077927  0.607423  0.163092
+0.273090  0.543705  0.098977  0.570197  0.241298
+0.256126  0.457031  0.162645  0.688488  0.083656
+0.244353  0.541124  0.107308  0.612757  0.091303
+0.133591  0.529436  0.155266  0.589826  0.109966
+0.169031  0.424115  0.159383  0.621843  0.161686
+0.197216  0.289787  0.167090  0.636383  0.182529
+0.220826  0.159524  0.216292  0.685372  0.175210
+0.163352  0.133163  0.258336  0.707076  0.069078
+0.139154  0.127062  0.188384  0.887034  0.076588
+0.149980  0.129949  0.139695  1.099261  0.119098
+0.116969  0.248652  0.346785  0.563640  0.149677
+0.288434  0.390172  0.230976  0.523980  0.142045
+0.204095  0.265235  0.247311  0.729439  0.074811
+0.223184  0.193652  0.102042  0.585987  0.270676
+0.208143  0.120077  0.185902  0.646853  0.088698
+0.355403  0.111468  0.373144  0.782590  0.084255
+0.467759  0.441272  0.454529  0.331431  0.068101
+0.287421  0.457040  0.408663  0.482212  0.061728
+0.357332  0.423457  0.207750  0.647728  0.065810
+0.278780  0.374907  0.213186  0.898049  0.086156
+0.254920  0.512858  0.068783  0.832756  0.092460
+0.155053  0.504579  0.227236  0.724872  0.074763
+0.224304  0.592281  0.154800  0.708373  0.084213
+0.134061  0.649051  0.265649  0.518767  0.136752
+0.159119  0.597636  0.132300  0.544301  0.080443
+0.165326  0.584118  0.065722  0.501958  0.113312
+0.168393  0.605334  0.170032  0.442580  0.111346
+0.222994  0.617265  0.187848  0.353529  0.108058
+0.341928  0.566020  0.267172  0.250143  0.094590
+0.259273  0.480338  0.214658  0.296496  0.096477
+0.376071  0.427466  0.264839  0.212427  0.086437
+0.255428  0.467896  0.110450  0.239556  0.176526
+0.246442  0.283461  0.119163  0.266608  0.102263
+0.244230  0.220479  0.202744  0.193491  0.182223
+0.237905  0.265321  0.225608  0.313174  0.087490
+0.319376  0.102135  0.327013  0.263502  0.075298
+0.390918  0.172754  0.184723  0.394890  0.146035
+0.273313  0.346658  0.092567  0.641158  0.151283
+0.284128  0.499354  0.081163  0.466535  0.297221
+0.178627  0.505374  0.097332  0.391523  0.244837
+0.242389  0.479312  0.181425  0.323507  0.276699
+0.227955  0.434010  0.184932  0.350457  0.167121
+0.326553  0.127161  0.261385  0.230075  0.165213
+0.247641  0.152672  0.221240  0.220448  0.083136
+0.138131  0.168731  0.293988  0.150390  0.154272
+0.236984  0.179876  0.290894  0.126578  0.101180
+0.322888  0.120611  0.456483  0.246062  0.067720
+0.255233  0.111619  0.355633  0.185287  0.091429
+0.265851  0.149737  0.318600  0.149243  0.216703
+0.451118  0.128440  0.361694  0.171150  0.106107
+0.211707  0.286172  0.315759  0.241198  0.150374
+0.193664  0.323335  0.464691  0.210845  0.137824
+0.099896  0.302611  0.444419  0.202631  0.098263
+0.206293  0.199056  0.454382  0.228845  0.085913
+0.343607  0.108340  0.521050  0.409023  0.064294
+0.493453  0.123961  0.247355  0.447710  0.124726
+0.434770  0.143238  0.183864  0.561544  0.086875
+0.529629  0.148537  0.149009  0.473557  0.136178
+0.379057  0.132645  0.109105  0.638162  0.277237
+0.633604  0.264938  0.162909  0.497149  0.179863
+0.500831  0.188804  0.188785  0.614856  0.179411
+0.409058  0.293672  0.183466  0.539013  0.180347
+0.340943  0.260960  0.231356  0.682368  0.162876
+0.243558  0.350532  0.230302  0.638438  0.126011
+0.168147  0.405395  0.147416  0.723426  0.111308
+0.144733  0.493639  0.084317  0.806213  0.114733
+0.209375  0.447862  0.072831  0.678780  0.187683
+0.116793  0.292883  0.094540  0.405312  0.470496
+0.339386  0.369706  0.107212  0.183574  0.399445
+0.142545  0.519655  0.092104  0.423208  0.366382
+0.093719  0.480688  0.072510  0.700939  0.168728
+0.096498  0.393584  0.070223  0.528217  0.428409
+0.106946  0.213115  0.090222  0.645586  0.382829
+0.131374  0.284012  0.100010  0.696767  0.283433
+0.084860  0.378946  0.098026  0.591087  0.224287
+0.076065  0.390799  0.089447  0.556643  0.130491
+0.085384  0.299699  0.167066  0.530650  0.136243
+0.101110  0.275481  0.324362  0.407650  0.214664
+0.094439  0.210386  0.210643  0.534842  0.192886
+0.094551  0.323082  0.149016  0.523689  0.226975
+0.220485  0.335486  0.256500  0.409588  0.150207
+0.366839  0.298863  0.309801  0.490853  0.152025
+0.411901  0.248761  0.230634  0.405806  0.220158
+0.562388  0.230272  0.289954  0.326961  0.180335
+0.433963  0.388442  0.510615  0.183758  0.128993
+0.741497  0.175849  0.278972  0.290774  0.093210
+0.636737  0.297657  0.365424  0.301362  0.087897
+0.642858  0.381201  0.076680  0.397305  0.211904
+0.666816  0.294012  0.134119  0.575608  0.066802
+0.673901  0.374634  0.175412  0.431165  0.076339
+0.511508  0.520820  0.139574  0.514646  0.069956
+0.520418  0.676457  0.064624  0.566333  0.064221
+0.598325  0.523644  0.074044  0.596331  0.066797
+0.933498  0.193401  0.143854  0.384238  0.081501
+0.632041  0.309843  0.244221  0.175740  0.134154
+0.568536  0.196273  0.123632  0.141162  0.214852
+0.500738  0.214997  0.179596  0.229019  0.227366
+0.333126  0.392124  0.318250  0.149137  0.265740
+0.251055  0.458955  0.593244  0.208910  0.121161
+0.298473  0.125524  0.614986  0.207582  0.101533
+0.352024  0.191840  0.514194  0.250891  0.147019
+0.263760  0.133327  0.326719  0.550786  0.063452
+0.149142  0.305892  0.218217  0.537478  0.088693
+0.201858  0.412388  0.241794  0.422920  0.114007
+0.142398  0.414950  0.222849  0.474207  0.085970
+0.094251  0.497997  0.240920  0.516622  0.097808
+0.111682  0.520946  0.148676  0.474755  0.091833
+0.117734  0.589300  0.215125  0.270818  0.107284
+0.201989  0.494555  0.179351  0.388040  0.114157
+0.174398  0.484392  0.260266  0.320839  0.096003
+0.085306  0.348476  0.249229  0.368376  0.199297
+0.124532  0.461494  0.527860  0.212430  0.093418
+0.113723  0.376335  0.368746  0.324531  0.177288
+0.101162  0.363061  0.490114  0.290204  0.085286
+0.108277  0.250270  0.530634  0.258356  0.079511
+0.145081  0.134926  0.501157  0.371551  0.069207
+0.231306  0.116734  0.501041  0.513138  0.077657
+0.176259  0.097578  0.459134  0.613445  0.063998
+0.164468  0.189593  0.257897  0.610588  0.064585
+0.233804  0.306454  0.185793  0.265924  0.304463
+0.343128  0.231821  0.135908  0.350415  0.244677
+0.344263  0.124095  0.110467  0.582485  0.146492
+0.148671  0.504915  0.094415  0.664071  0.066676
+0.095715  0.618261  0.179292  0.545763  0.242356
+0.103474  0.514563  0.090244  0.614314  0.211560
+0.113099  0.514409  0.084701  0.508874  0.291824
+0.088297  0.564236  0.080256  0.490382  0.213520
+0.122914  0.581662  0.068764  0.592567  0.118286
+0.070668  0.514562  0.081542  0.627909  0.102380
+0.188592  0.486562  0.077089  0.549411  0.233297
+0.140458  0.532554  0.174729  0.513439  0.183895
+0.118377  0.435228  0.123578  0.665560  0.298307
+0.087854  0.611600  0.097721  0.686778  0.177549
+0.154595  0.699793  0.082366  0.692338  0.115191
+0.130325  0.640376  0.080435  0.569886  0.205270
+0.203456  0.576083  0.073822  0.525491  0.194465
+0.111898  0.687564  0.102749  0.541060  0.099285
+0.254521  0.662003  0.071248  0.479177  0.251266
+0.207296  0.627004  0.082830  0.633571  0.157024
+0.103953  0.665250  0.420705  0.548528  0.067388
+0.353493  0.620117  0.092475  0.520480  0.209522
+0.297252  0.650446  0.069155  0.659795  0.109539
+0.224459  0.631257  0.066952  0.780605  0.106404
+0.120831  0.603720  0.539876  0.453029  0.060154
+0.139273  0.198121  0.102822  0.995897  0.098301
+0.237263  0.579293  0.092012  0.327905  0.315070
+0.486273  0.391733  0.242175  0.149691  0.214426
+0.300339  0.132790  0.151137  0.165343  0.263675
+0.470234  0.207154  0.257271  0.118630  0.377311
+0.231404  0.184568  0.123060  0.224821  0.395590
+0.294403  0.259511  0.187609  0.423169  0.134765
+0.213429  0.150682  0.223072  0.282966  0.256916
+0.188239  0.250539  0.140391  0.362037  0.288466
+0.297488  0.272163  0.285020  0.322549  0.263203
+0.339489  0.234995  0.229447  0.188811  0.306166
+0.471108  0.316005  0.226394  0.317645  0.222039
+0.357586  0.365287  0.315209  0.372770  0.185823
+0.388093  0.277880  0.357906  0.315369  0.171751
+0.441160  0.240648  0.283512  0.163176  0.214520
+0.299201  0.396604  0.182789  0.317222  0.153875
+0.285743  0.424218  0.144479  0.364270  0.098407
+0.505903  0.165614  0.127044  0.254585  0.089779
+0.331316  0.102213  0.146285  0.374807  0.075771
+0.447060  0.119162  0.132109  0.378569  0.075195
+0.480053  0.196352  0.101594  0.402987  0.078775
+0.221052  0.566668  0.091514  0.406351  0.113527
+0.267701  0.491109  0.088210  0.449996  0.079021
+0.173590  0.667613  0.073920  0.479611  0.145941
+0.161590  0.750841  0.279513  0.400302  0.100640
+0.123252  0.448395  0.474747  0.539272  0.089969
+0.103201  0.404376  0.184240  0.701070  0.205018
+0.120487  0.369051  0.450877  0.702917  0.091539
+0.120387  0.210856  0.422533  0.626951  0.069784
+0.133489  0.337866  0.586816  0.462600  0.061741
+0.155228  0.099643  0.613974  0.677822  0.065653
+0.238915  0.114730  0.285524  0.886174  0.107992
+0.097758  0.288300  0.175006  0.323226  0.380635
+0.193016  0.396803  0.125995  0.371597  0.302987
+0.328241  0.351932  0.169485  0.365731  0.247671
+0.359390  0.296631  0.073742  0.434952  0.226132
+0.345670  0.369745  0.178296  0.422139  0.159520
+0.271279  0.469466  0.244005  0.447820  0.207990
+0.361580  0.120094  0.215775  0.878268  0.160090
+0.277345  0.128469  0.186375  0.989875  0.070807
+0.298700  0.442492  0.085352  0.812309  0.072085
+0.141086  0.576619  0.235677  0.648656  0.116102
+0.092415  0.551379  0.171369  0.413082  0.246634
+0.112362  0.648358  0.192381  0.371821  0.209130
+0.085349  0.673175  0.083715  0.356861  0.212484
+0.109528  0.672834  0.079353  0.454863  0.227345
+0.314176  0.472511  0.109010  0.378621  0.221648
+0.473822  0.407882  0.096108  0.180136  0.258137
+0.339014  0.658837  0.128012  0.208939  0.304361
+0.404801  0.486071  0.173029  0.140185  0.331012
+0.522218  0.309443  0.134996  0.162711  0.355239
+0.239218  0.564177  0.134663  0.133921  0.234046
+0.132066  0.791260  0.218037  0.140401  0.260218
+0.121835  0.666346  0.256077  0.131259  0.288536
+0.101989  0.541072  0.298054  0.124917  0.349203
+0.088976  0.393531  0.316070  0.143252  0.341282
+0.101393  0.320009  0.436810  0.118405  0.346214
+0.115633  0.286281  0.212116  0.159512  0.497827
+0.286947  0.279577  0.227044  0.122089  0.428814
+0.086166  0.333882  0.763682  0.106719  0.492366
+0.112629  0.187606  0.582205  0.157566  0.435087
+0.129445  0.192272  0.407708  0.144958  0.241631
+0.384213  0.153504  0.435697  0.181808  0.317005
+0.211711  0.272203  0.553356  0.303220  0.107653
+0.278393  0.274678  0.378365  0.392714  0.164314
+0.249986  0.217448  0.464347  0.456336  0.080569
+0.344974  0.497950  0.330937  0.337593  0.148443
+0.222730  0.448762  0.331648  0.395038  0.111948
+0.278511  0.448111  0.197387  0.487487  0.068759
+0.284545  0.587071  0.190442  0.450325  0.120815
+0.242897  0.540770  0.089529  0.528286  0.099731
+0.311484  0.576470  0.068708  0.572142  0.102919
+0.356067  0.502825  0.078341  0.695153  0.078752
+0.394819  0.429408  0.088022  0.731616  0.077904
+0.401981  0.374078  0.083607  0.460834  0.178060
+0.342091  0.485245  0.075656  0.425769  0.148694
+0.301302  0.522671  0.160822  0.379160  0.087694
+0.394884  0.535562  0.385186  0.169599  0.171204
+0.467932  0.533984  0.233680  0.290672  0.197333
+0.567897  0.202538  0.121919  0.562827  0.077447
+0.498173  0.336008  0.085433  0.608275  0.067929
+0.402247  0.498935  0.083195  0.569731  0.083813
+0.228445  0.525870  0.229214  0.550628  0.084302
+0.269995  0.522327  0.080030  0.468787  0.181821
+0.494799  0.454542  0.075562  0.510643  0.220302
+0.536191  0.294448  0.089924  0.469042  0.180989
+0.433882  0.313513  0.088848  0.567754  0.161336
+0.400192  0.334434  0.148995  0.538420  0.081007
+0.419312  0.469218  0.252292  0.325453  0.093272
+0.309433  0.619520  0.206890  0.291754  0.215947
+0.312741  0.555786  0.245782  0.366817  0.173692
+0.500191  0.370349  0.087660  0.386210  0.176883
+0.696041  0.382472  0.085830  0.228362  0.231409
+0.704156  0.170202  0.121273  0.150301  0.291043
+0.602824  0.191671  0.096937  0.161816  0.434180
+0.903506  0.230343  0.082074  0.187722  0.125128
+0.384170  0.375233  0.115102  0.222496  0.118075
+0.128983  0.707425  0.176360  0.164154  0.159361
+0.084548  0.571038  0.097687  0.305940  0.187860
+0.128042  0.606879  0.092465  0.348941  0.137691
+0.095473  0.678141  0.122052  0.341624  0.111983
+0.090864  0.562484  0.088849  0.394831  0.185360
+0.123849  0.507637  0.079890  0.464565  0.178220
+0.122564  0.410094  0.102049  0.484462  0.294573
+0.229321  0.286865  0.188570  0.513885  0.106524
+0.147548  0.389244  0.179789  0.595543  0.054525
+0.181343  0.199067  0.143642  0.709901  0.067120
+0.133527  0.236448  0.220785  0.640310  0.205873
+0.146697  0.228089  0.427444  0.399805  0.142999
+0.135772  0.124591  0.354606  0.626347  0.194995
+0.174970  0.096177  0.360896  0.773055  0.151537
+0.129752  0.123873  0.231596  0.762722  0.226311
+0.094786  0.206587  0.093236  0.497512  0.446528
+0.110523  0.170676  0.101314  0.773611  0.319170
+0.112312  0.176026  0.473699  0.522928  0.170826
+0.257136  0.158335  0.510015  0.385679  0.194140
+0.103087  0.529797  0.416572  0.184552  0.117677
+0.169263  0.371936  0.191937  0.292095  0.125469
+0.297466  0.238101  0.136424  0.387694  0.074518
+0.237761  0.211913  0.172642  0.307723  0.149041
+0.201199  0.252732  0.258414  0.281538  0.155626
+0.347975  0.190591  0.195409  0.286847  0.181540
+0.274058  0.298589  0.091129  0.426866  0.191629
+0.246536  0.278837  0.188331  0.411223  0.079774
+0.113327  0.424052  0.099892  0.495951  0.078924
+0.083116  0.564109  0.181962  0.428562  0.120069
+0.083834  0.498604  0.109611  0.332854  0.102921
+0.080710  0.451451  0.161543  0.440414  0.171509
+0.074355  0.465288  0.122748  0.363411  0.173461
+0.092007  0.488316  0.112396  0.280348  0.179377
+0.084620  0.407361  0.122379  0.357813  0.245605
+0.089475  0.498801  0.099468  0.365981  0.248221
+0.078040  0.536380  0.132965  0.250027  0.261269
+0.108924  0.502718  0.178496  0.323830  0.329518
+0.088507  0.572954  0.225507  0.304754  0.224929
+0.124548  0.590063  0.104624  0.315887  0.265646
+0.104299  0.717161  0.203711  0.278911  0.212791
+0.181081  0.726864  0.076367  0.381984  0.224228
+0.232249  0.709155  0.127219  0.291505  0.249139
+0.319579  0.712186  0.082794  0.380234  0.227925
+0.266859  0.759329  0.077150  0.503108  0.110534
+0.250604  0.853961  0.094041  0.316646  0.218562
+0.158680  0.868187  0.085373  0.580488  0.108664
+0.203564  0.899781  0.104219  0.435037  0.158907
+0.180082  0.736011  0.170314  0.446979  0.114729
+0.442348  0.574640  0.061388  0.635575  0.080820
+0.485214  0.465943  0.072348  0.674169  0.104751
+0.452473  0.474026  0.090702  0.423456  0.124520
+0.536765  0.407861  0.214815  0.315424  0.114424
+0.387891  0.385258  0.234788  0.322837  0.159279
+0.424436  0.245501  0.234072  0.260119  0.112615
+0.433081  0.234628  0.164498  0.349419  0.092404
+0.589196  0.169146  0.182072  0.288234  0.094524
+0.642431  0.145496  0.163391  0.402251  0.167644
+0.241206  0.720484  0.268696  0.302572  0.105894
+0.227208  0.516362  0.297669  0.263151  0.217841
+0.157823  0.505412  0.209992  0.327272  0.208331
+0.188918  0.567152  0.287327  0.404316  0.221471
+0.117589  0.482686  0.417164  0.306122  0.096026
+0.096426  0.452399  0.451314  0.293387  0.256610
+0.224454  0.127500  0.532287  0.238199  0.324602
+0.135876  0.144824  0.324903  0.322635  0.438443
+0.260561  0.170798  0.211409  0.355245  0.375861
+0.241357  0.129124  0.400639  0.276088  0.218756
+0.199518  0.259911  0.381201  0.324165  0.197395
+0.251235  0.377989  0.344902  0.270364  0.211865
+0.291296  0.384935  0.422781  0.294449  0.090980
+0.395823  0.365064  0.344755  0.415986  0.084583
+0.386477  0.248849  0.455442  0.365781  0.088672
+0.458033  0.155479  0.426783  0.280998  0.145175
+0.531981  0.141346  0.329938  0.252887  0.250131
+0.374946  0.268161  0.075505  0.510520  0.332301
+0.184531  0.374438  0.194028  0.517563  0.214417
+0.147560  0.465804  0.195189  0.428052  0.176505
+0.148334  0.523244  0.128330  0.361610  0.151203
+0.077690  0.465213  0.245172  0.390288  0.240527
+0.086426  0.430840  0.330699  0.420341  0.124550
+0.112022  0.345300  0.269904  0.488879  0.216281
+0.124982  0.372020  0.199492  0.426906  0.295323
+0.090183  0.350995  0.106602  0.430935  0.379114
+0.082426  0.406537  0.203467  0.310012  0.281593
+0.097489  0.660568  0.359241  0.290708  0.157249
+0.225098  0.605767  0.361924  0.359285  0.082358
+0.132418  0.382778  0.252320  0.761284  0.075589
+0.094659  0.441486  0.188296  0.651609  0.091024
+0.105780  0.329945  0.175481  0.666592  0.136558
+0.089106  0.324847  0.402205  0.426529  0.076884
+0.104303  0.249418  0.358039  0.353634  0.090345
+0.097984  0.107847  0.191108  0.634878  0.146858
+0.108646  0.138888  0.147686  0.762312  0.116913
+0.212705  0.171260  0.283930  0.262645  0.181071
+0.163478  0.208128  0.156460  0.271129  0.174478
+0.139789  0.152510  0.124415  0.248322  0.322683
+0.135948  0.126114  0.118662  0.442261  0.258146
+0.269052  0.117807  0.240510  0.315434  0.077056
+0.272173  0.190742  0.228064  0.380147  0.091157
+0.093206  0.405534  0.219163  0.416979  0.109899
+0.079579  0.352146  0.301267  0.545994  0.090767
+0.084397  0.359349  0.118580  0.517250  0.074602
+0.142924  0.375509  0.104248  0.557536  0.080598
+0.078233  0.435400  0.149153  0.515426  0.089637
+0.110687  0.467759  0.349990  0.600145  0.085545
+0.100132  0.551704  0.325140  0.370687  0.141516
+0.181971  0.519689  0.286529  0.452168  0.096892
+0.159153  0.383139  0.297630  0.360105  0.077438
+0.183481  0.283365  0.129323  0.656147  0.069784
+0.220018  0.182682  0.385213  0.555811  0.084366
+0.231995  0.281431  0.313643  0.520252  0.082302
+0.240791  0.233989  0.320275  0.403334  0.084817
+0.171626  0.210184  0.395140  0.301540  0.074726
+0.123974  0.217388  0.372344  0.199194  0.098678
+0.094207  0.340277  0.342699  0.229163  0.094361
+0.185288  0.230262  0.262745  0.200532  0.102872
+0.095962  0.264991  0.227913  0.202329  0.177991
+0.080476  0.352796  0.139512  0.208977  0.227863
+0.275940  0.222441  0.111305  0.254747  0.156578
+0.165298  0.474978  0.192185  0.235092  0.135086
+0.233131  0.392950  0.157143  0.269425  0.156572
+0.298527  0.302925  0.133842  0.506002  0.132732
+0.241454  0.398460  0.084375  0.494325  0.234749
+0.159631  0.421398  0.092589  0.413926  0.179796
+0.158224  0.418616  0.283534  0.367067  0.205082
+0.412365  0.395342  0.111344  0.328391  0.244173
+0.731001  0.188693  0.218000  0.439587  0.059263
+0.745998  0.200881  0.187697  0.535200  0.060072
+0.469681  0.181024  0.087472  0.556582  0.163565
+0.441174  0.437510  0.095320  0.502861  0.077980
+0.322936  0.728585  0.177880  0.361976  0.127210
+0.548711  0.485972  0.114597  0.398005  0.088237
+0.610200  0.296764  0.238908  0.322896  0.084667
+0.592628  0.345184  0.098471  0.562811  0.087139
+0.560240  0.449189  0.083091  0.579717  0.093314
+0.663473  0.368021  0.076482  0.477615  0.079947
+0.840453  0.162820  0.244379  0.383785  0.063482
+0.912157  0.172957  0.256442  0.240074  0.091406
+0.834827  0.322582  0.132713  0.399434  0.066227
+0.874296  0.227941  0.130581  0.534307  0.055764
+0.781475  0.321342  0.090938  0.519094  0.079899
+0.710368  0.431864  0.099467  0.532623  0.068002
+0.383525  0.718920  0.099055  0.461407  0.121495
+0.321455  0.825089  0.079595  0.427568  0.108507
+0.462084  0.596965  0.071969  0.517949  0.100383
+0.621282  0.471919  0.098704  0.478693  0.075515
+0.776229  0.441476  0.101458  0.413008  0.071570
+1.055603  0.281500  0.098804  0.330063  0.056286
+0.771298  0.184425  0.130775  0.291681  0.117787
+0.665328  0.260827  0.103040  0.287881  0.123419
+0.664697  0.240922  0.136388  0.447161  0.065891
+0.414409  0.353609  0.145744  0.442868  0.087314
+0.340256  0.437220  0.091053  0.510486  0.092269
+0.288764  0.365145  0.080428  0.571963  0.079355
+0.256452  0.463354  0.070186  0.524028  0.128702
+0.171512  0.504065  0.086462  0.532869  0.092264
+0.090054  0.543273  0.088797  0.502580  0.106631
+0.114850  0.462977  0.076917  0.569930  0.177260
+0.151671  0.397556  0.095758  0.505144  0.181704
+0.192648  0.353679  0.095802  0.575344  0.156084
+0.235208  0.332379  0.146583  0.514241  0.063492
+0.297139  0.344976  0.192100  0.465214  0.077665
+0.344994  0.271830  0.170591  0.477851  0.069874
+0.378705  0.252593  0.253455  0.525208  0.074234
+0.422686  0.223283  0.163494  0.463124  0.074401
+0.536741  0.207841  0.375674  0.335239  0.080770
+0.576205  0.121946  0.482428  0.189663  0.122584
+0.676912  0.137942  0.410135  0.303729  0.052162
+0.500812  0.275746  0.395759  0.178866  0.106177
+0.185855  0.153489  0.402933  0.141660  0.119752
+0.347855  0.262387  0.216402  0.262314  0.088094
+0.394245  0.275682  0.213007  0.425591  0.126433
+0.280260  0.257848  0.091658  0.697149  0.196117
+0.285112  0.250968  0.090577  0.843502  0.109028
+0.319921  0.257047  0.092162  0.768396  0.316052
+0.355869  0.267076  0.091597  0.198027  0.510532
+0.307895  0.345189  0.078152  0.344043  0.358648
+0.221846  0.299984  0.112351  0.523762  0.364610
+0.291795  0.410895  0.105575  0.603179  0.258227
+0.283089  0.424032  0.071178  0.791398  0.180963
+0.404844  0.302286  0.101039  0.708910  0.163041
+0.358318  0.318550  0.090435  0.516159  0.065090
+0.298166  0.435765  0.229621  0.406055  0.118523
+0.368986  0.384758  0.217436  0.396128  0.086725
+0.411213  0.354891  0.234282  0.497014  0.084281
+0.307657  0.332725  0.287959  0.434842  0.080152
+0.337856  0.231898  0.120082  0.591233  0.069187
+0.346355  0.263461  0.225771  0.624157  0.064656
+0.418261  0.188590  0.138241  0.691730  0.068140
+0.618168  0.133250  0.084086  0.594058  0.182457
+0.715131  0.240256  0.105083  0.675577  0.056648
+0.591409  0.161581  0.158443  0.842515  0.108974
+0.350607  0.231988  0.112984  0.202511  0.203101
+0.300281  0.425813  0.103862  0.158493  0.225605
+0.104868  0.621079  0.312459  0.141264  0.161945
+0.192814  0.214042  0.244105  0.366775  0.176633
+0.270326  0.120168  0.205289  0.345302  0.166367
+0.339007  0.134562  0.326535  0.353717  0.199303
+0.427795  0.117156  0.172565  0.516587  0.227170
+0.303780  0.139461  0.275676  0.533802  0.207780
+0.394670  0.130774  0.425867  0.442357  0.201882
+0.216763  0.191531  0.366565  0.479326  0.214174
+0.097217  0.120156  0.107590  0.582121  0.222583
+0.167975  0.157098  0.292665  0.513619  0.084077
+0.163339  0.318464  0.335679  0.453557  0.139234
+0.081592  0.386785  0.081896  0.495806  0.213491
+0.088051  0.370484  0.160735  0.432777  0.204573
+0.074725  0.459123  0.090166  0.429763  0.124912
+0.188613  0.370441  0.104341  0.400017  0.082281
+0.347630  0.196574  0.073723  0.441321  0.077130
+0.329961  0.342811  0.083976  0.423968  0.090995
+0.217172  0.345686  0.084780  0.488087  0.101164
+0.406673  0.272249  0.098395  0.420694  0.091348
+0.385704  0.257156  0.070908  0.324285  0.105747
+0.274677  0.268878  0.080441  0.343145  0.135384
+0.250038  0.175672  0.106202  0.368802  0.097441
+0.163520  0.411919  0.100421  0.243085  0.147996
+0.074293  0.397642  0.107317  0.290996  0.193865
+0.161399  0.337870  0.098872  0.320589  0.165900
+0.086900  0.354661  0.109703  0.286976  0.095093
+0.090251  0.377230  0.113555  0.402994  0.083618
+0.076344  0.263634  0.109835  0.339987  0.222795
+0.084522  0.203422  0.107145  0.507916  0.209607
+0.112317  0.197961  0.147767  0.392846  0.191935
+0.160377  0.138381  0.146411  0.382843  0.119865
+0.096779  0.236364  0.158125  0.406405  0.074097
+0.071278  0.230916  0.124923  0.333671  0.128043
+0.076867  0.314226  0.120144  0.280011  0.169668
+0.084828  0.426814  0.229878  0.183948  0.187964
+0.091915  0.578979  0.157955  0.193695  0.165487
+0.147362  0.515345  0.097774  0.255679  0.120270
+0.216319  0.147567  0.200703  0.134818  0.226775
+0.345195  0.373533  0.190523  0.148016  0.092224
+0.403999  0.182963  0.122107  0.207890  0.107122
+0.249797  0.156173  0.137234  0.199544  0.131932
+0.097153  0.250759  0.139250  0.232362  0.211991
+0.190336  0.293021  0.114678  0.197947  0.120045
+0.289001  0.303379  0.111096  0.135843  0.150785
+0.299836  0.298154  0.133264  0.198659  0.093498
+0.267982  0.369040  0.186695  0.239136  0.091856
+0.225610  0.405658  0.103119  0.157298  0.093425
+0.210233  0.359038  0.183413  0.172165  0.094590
+0.232533  0.285959  0.226716  0.138425  0.102607
+0.251807  0.114231  0.225196  0.169145  0.130262
+0.196681  0.131629  0.290550  0.249612  0.088731
+0.243067  0.127312  0.146654  0.308179  0.085049
+0.338559  0.140278  0.100978  0.301595  0.106500
+0.219595  0.467497  0.081582  0.359391  0.125808
+0.147560  0.414328  0.163898  0.351622  0.173962
+0.097265  0.497791  0.227591  0.352834  0.128111
+0.103010  0.462785  0.310935  0.245591  0.122244
+0.082383  0.388077  0.185504  0.343316  0.137526
+0.088990  0.438568  0.203709  0.270278  0.109601
+0.099761  0.329199  0.149830  0.304031  0.249088
+0.091143  0.326604  0.291538  0.334291  0.120320
+0.091393  0.351780  0.234918  0.254151  0.169727
+0.088636  0.262717  0.274724  0.281853  0.219807
+0.110626  0.219733  0.372703  0.291122  0.240271
+0.147262  0.193514  0.282718  0.166328  0.348140
+0.215753  0.283606  0.338510  0.204902  0.290646
+0.249265  0.660090  0.308265  0.154668  0.214312
+0.184237  0.457150  0.358988  0.155031  0.226845
+0.085928  0.461941  0.313838  0.233675  0.235701
+0.152277  0.546282  0.244499  0.213061  0.206098
+0.127947  0.626109  0.242087  0.241094  0.281851
+0.185087  0.648682  0.147192  0.192190  0.316338
+0.126523  0.730039  0.358042  0.122395  0.193527
+0.099402  0.293812  0.455058  0.219881  0.194990
+0.140126  0.121216  0.447204  0.462855  0.285712
+0.130693  0.092146  0.402485  0.902334  0.103806
+0.186313  0.103913  0.515406  0.626164  0.194363
+0.130862  0.133525  0.578230  0.495540  0.065482
+0.133112  0.171137  0.648298  0.374117  0.238776
+0.117563  0.253110  0.632193  0.195934  0.100484
+0.123787  0.147417  0.506314  0.292581  0.258762
+0.191351  0.125634  0.488336  0.276781  0.084991
+0.095634  0.433137  0.500180  0.133656  0.153654
+0.113082  0.343094  0.432986  0.128759  0.218562
+0.082603  0.429341  0.351512  0.117175  0.223189
+0.088047  0.371923  0.239395  0.216084  0.264315
+0.093190  0.278617  0.297918  0.134469  0.258214
+0.104852  0.260763  0.390849  0.137838  0.152196
+0.220196  0.210581  0.386651  0.207171  0.180526
+0.185770  0.244580  0.310431  0.129160  0.205549
+0.352853  0.158613  0.396338  0.160413  0.161804
+0.623161  0.135729  0.281111  0.641385  0.060850
+0.601179  0.235528  0.147420  0.676282  0.075378
+0.237210  0.512938  0.081247  0.719764  0.100476
+0.313619  0.398199  0.084859  0.727021  0.072137
+0.415154  0.318599  0.086411  0.844552  0.074841
+0.414193  0.186697  0.133621  1.003991  0.090317
+0.525046  0.126708  0.158060  0.656220  0.071292
+0.506539  0.199293  0.222064  0.594940  0.056127
+0.588419  0.116726  0.374361  0.494496  0.062444
+0.587909  0.161096  0.247685  0.508021  0.074031
+0.427260  0.175283  0.161764  0.797938  0.081903
+0.365955  0.293527  0.113142  0.712024  0.075121
+0.516236  0.390842  0.077007  0.770221  0.074317
+0.629270  0.381192  0.082654  0.659143  0.069191
+0.364438  0.389905  0.093220  0.651788  0.157496
+0.367133  0.364451  0.097770  0.526551  0.125794
+0.459416  0.189986  0.121752  0.328420  0.198173
+0.234904  0.434831  0.196421  0.214213  0.123432
+0.245564  0.355295  0.178844  0.420738  0.184541
+0.263115  0.415513  0.093895  0.437966  0.145018
+0.264263  0.395578  0.086908  0.349500  0.200286
+0.200094  0.352862  0.173362  0.435563  0.108616
+0.258514  0.266984  0.097829  0.451154  0.078365
+0.289789  0.173100  0.193328  0.613342  0.066761
+0.384511  0.117381  0.144745  0.493977  0.060918
+0.321287  0.136297  0.206007  0.449189  0.084129
+0.371064  0.120061  0.244529  0.348665  0.075581
+0.383605  0.111685  0.372188  0.378829  0.087538
+0.174528  0.200500  0.203880  0.536189  0.097704
+0.226423  0.256017  0.201538  0.593869  0.082507
+0.275188  0.339960  0.203946  0.219877  0.162736
+0.239492  0.288304  0.090042  0.261673  0.213821
+0.152091  0.224078  0.126405  0.603417  0.175553
+0.176378  0.304695  0.087618  0.592353  0.084284
+0.261868  0.265799  0.100472  0.563239  0.093167
+0.181788  0.305669  0.102111  0.450140  0.211949
+0.076788  0.312046  0.114906  0.383016  0.181321
+0.072498  0.327165  0.105074  0.455708  0.110841
+0.083842  0.251487  0.120489  0.439817  0.158393
+0.086221  0.273512  0.110497  0.497088  0.076061
+0.076690  0.290120  0.088018  0.513515  0.185343
+0.091149  0.246724  0.119248  0.584019  0.114931
+0.085559  0.311584  0.084386  0.550846  0.106859
+0.080454  0.396575  0.093437  0.473853  0.136830
+0.089353  0.382071  0.099052  0.396226  0.157854
+0.210887  0.219290  0.116425  0.362522  0.187150
+0.176967  0.255448  0.117574  0.310020  0.105187
+0.392418  0.212007  0.286555  0.188339  0.092884
+0.344965  0.265505  0.225226  0.147488  0.106140
+0.148182  0.138167  0.388457  0.241265  0.112270
+0.197373  0.131937  0.283996  0.356406  0.073471
+0.246375  0.146284  0.127800  0.282946  0.226409
+0.358012  0.189491  0.156340  0.352246  0.069082
+0.214274  0.363392  0.245513  0.331406  0.119490
+0.093232  0.409989  0.395607  0.166468  0.122107
+0.122065  0.552656  0.460436  0.115372  0.181968
+0.119270  0.602676  0.580138  0.247072  0.071915
+0.334314  0.212124  0.245339  0.411184  0.082342
+0.344198  0.199682  0.197387  0.518104  0.126800
+0.298611  0.364076  0.155972  0.575893  0.099503
+0.249879  0.405878  0.103603  0.526826  0.095430
+0.182662  0.493723  0.079858  0.462683  0.135075
+0.088535  0.619266  0.100563  0.470730  0.132925
+0.179689  0.598357  0.088681  0.428125  0.225276
+0.212633  0.682527  0.086947  0.395939  0.110870
+0.205101  0.610063  0.096655  0.347915  0.205010
+0.141822  0.680363  0.091759  0.366814  0.325419
+0.183195  0.776576  0.114337  0.241439  0.329250
+0.103939  0.739682  0.143415  0.164819  0.345811
+0.137855  0.630401  0.110674  0.287816  0.446019
+0.098682  0.470697  0.132827  0.178435  0.516442
+0.074890  0.379911  0.133316  0.243811  0.351980
+0.091414  0.591116  0.077867  0.401649  0.277337
+0.063991  0.510720  0.066415  0.526174  0.171061
+0.091198  0.309140  0.103600  0.535669  0.316638
+0.093317  0.258841  0.100346  0.744677  0.085006
+0.080710  0.302136  0.098014  0.638831  0.098723
+0.099287  0.309662  0.104631  0.597698  0.172054
+0.100144  0.233660  0.127926  0.674948  0.122933
+0.083106  0.258737  0.105127  0.603675  0.247173
+0.124688  0.224305  0.100198  0.797080  0.214990
+0.109656  0.200220  0.109010  0.854398  0.092044
+0.131654  0.161230  0.126313  0.923489  0.222156
+0.108983  0.212933  0.237962  0.732235  0.084731
+0.124876  0.316481  0.280211  0.621265  0.084670
+0.291151  0.156039  0.169693  0.788326  0.062107
+0.363626  0.144241  0.273635  0.576773  0.063353
+0.246209  0.111402  0.411881  0.431162  0.073653
+0.187427  0.214392  0.248322  0.426410  0.096999
+0.259263  0.391515  0.214924  0.345257  0.090006
+0.265809  0.325254  0.241771  0.283388  0.095075
+0.360417  0.278085  0.304761  0.236391  0.060111
+0.244583  0.277639  0.307198  0.298215  0.100785
+0.190750  0.300193  0.350348  0.158056  0.096414
+0.314417  0.242688  0.380630  0.164618  0.096062
+0.243765  0.206741  0.354691  0.248322  0.088520
+0.177022  0.234262  0.293393  0.331888  0.093099
+0.161817  0.331698  0.255844  0.286339  0.110281
+0.278399  0.284033  0.185269  0.305259  0.184203
+0.385992  0.480594  0.173432  0.378859  0.153632
+0.184090  0.115317  0.748681  0.378734  0.060556
+0.151586  0.107061  0.742021  0.535618  0.051151
+0.332921  0.095413  0.513180  0.645978  0.059463
+0.258027  0.096049  0.611288  0.535843  0.059083
+0.247584  0.121388  0.614788  0.370232  0.077324
+0.169111  0.140849  0.604788  0.239980  0.095216
+0.111607  0.322529  0.542365  0.168161  0.109291
+0.241876  0.305289  0.439888  0.120248  0.200225
+0.284239  0.394417  0.251394  0.244455  0.193399
+0.147939  0.165823  0.154594  0.167245  0.301729
+0.181518  0.161729  0.146628  0.202260  0.206488
+0.212973  0.328934  0.129941  0.155031  0.247663
+0.102294  0.362696  0.130871  0.170694  0.124880
+0.213580  0.332469  0.270053  0.226216  0.097265
+0.452215  0.241818  0.093796  0.538977  0.071308
+0.489047  0.360411  0.090544  0.488290  0.081715
+0.552862  0.219107  0.213786  0.398709  0.155961
+0.437694  0.412404  0.209319  0.437276  0.195087
+0.199286  0.644714  0.440653  0.212028  0.096342
+0.287744  0.341997  0.207514  0.385949  0.117592
+0.263774  0.439511  0.269147  0.341149  0.172563
+0.454161  0.381508  0.331847  0.268151  0.152272
+0.498290  0.289594  0.304899  0.362633  0.106732
+0.481679  0.328798  0.222406  0.397769  0.104606
+0.346873  0.440248  0.129990  0.443019  0.087516
+0.380155  0.530965  0.097578  0.409382  0.082665
+0.321254  0.579714  0.089049  0.390589  0.201519
+0.362547  0.576427  0.085672  0.491626  0.104850
+0.276854  0.642201  0.083025  0.467384  0.121062
+0.273630  0.663476  0.158964  0.548773  0.087067
+0.373979  0.679628  0.060478  0.566170  0.089921
+0.231054  0.689868  0.075141  0.554939  0.121992
+0.131352  0.746985  0.224259  0.632082  0.114206
+0.122786  0.768200  0.082348  0.539275  0.195919
+0.109772  0.815210  0.139772  0.362727  0.266362
+0.104772  0.856439  0.113332  0.232571  0.246206
+0.120584  0.754666  0.080447  0.429169  0.118502
+0.129558  0.791075  0.105915  0.315074  0.120715
+0.471551  0.424768  0.106094  0.298460  0.095269
+0.554926  0.269653  0.080730  0.240918  0.109021
+0.715432  0.175592  0.151435  0.182408  0.123486
+0.137564  0.237719  0.187711  0.139854  0.135833
+0.094527  0.273567  0.286247  0.168053  0.115917
+0.167637  0.157429  0.212566  0.193778  0.120081
+0.336811  0.142407  0.179532  0.175920  0.143067
+0.359984  0.220774  0.139955  0.276172  0.088412
+0.229300  0.314626  0.202672  0.266918  0.121818
+0.254903  0.239660  0.205666  0.231586  0.089226
+0.167122  0.146638  0.180676  0.284930  0.110311
+0.343078  0.188097  0.234475  0.241020  0.085210
+0.453742  0.129229  0.238583  0.231887  0.093298
+0.339970  0.125720  0.278618  0.183409  0.087075
+0.340525  0.112000  0.203560  0.267435  0.074552
+0.421266  0.136001  0.163313  0.278632  0.077810
+0.231080  0.342813  0.163037  0.331660  0.151451
+0.219435  0.349874  0.194108  0.374829  0.093483
+0.192275  0.378257  0.132811  0.343050  0.103414
+0.110721  0.427391  0.100405  0.325509  0.111209
+0.146685  0.286203  0.121744  0.415444  0.104287
+0.140158  0.355739  0.095810  0.450215  0.085634
+0.169104  0.279898  0.130179  0.506051  0.078620
+0.182052  0.216413  0.119325  0.576246  0.074259
+0.225160  0.129927  0.259427  0.435333  0.063882
+0.269429  0.222859  0.221923  0.506932  0.072807
+0.178884  0.213869  0.166680  0.458615  0.073113
+0.173590  0.299930  0.242906  0.454873  0.075763
+0.100242  0.268104  0.176813  0.481588  0.072095
+0.090237  0.243244  0.251971  0.381230  0.134740
+0.115219  0.162206  0.219459  0.448797  0.139604
+0.153424  0.114968  0.426394  0.484294  0.069918
+0.340250  0.102354  0.415558  0.530027  0.067470
+0.463554  0.114390  0.258182  0.708843  0.077525
+0.490093  0.173433  0.090040  0.421955  0.279956
+0.382461  0.193817  0.087070  0.298236  0.364436
+0.318849  0.150566  0.097605  0.414953  0.299328
+0.113221  0.190688  0.097473  0.317986  0.524035
+0.487612  0.157990  0.137684  0.207485  0.328511
+0.415390  0.156206  0.110413  0.173488  0.449581
+0.392854  0.243412  0.095319  0.158735  0.352930
+0.554126  0.279294  0.084682  0.789521  0.053595
+0.426016  0.255484  0.163308  0.615069  0.071484
+0.431377  0.338700  0.141517  0.673050  0.060005
+0.566932  0.141427  0.223486  0.375608  0.070605
+0.493511  0.233734  0.315571  0.238950  0.087048
+0.297922  0.264510  0.411237  0.278766  0.092207
+0.282302  0.280217  0.244330  0.279897  0.142264
+0.177097  0.323486  0.184695  0.254221  0.183230
+0.184257  0.328819  0.268892  0.187933  0.187193
+0.122061  0.220291  0.321286  0.201051  0.198515
+0.326682  0.185267  0.112300  0.407868  0.149352
+0.193578  0.190639  0.125066  0.491527  0.159276
+0.122828  0.230083  0.225742  0.246379  0.289540
+0.208084  0.292604  0.243207  0.126616  0.272821
+0.288296  0.286988  0.273500  0.223556  0.187415
+0.202485  0.337359  0.222418  0.324829  0.208113
+0.149017  0.419979  0.241372  0.290285  0.175273
+0.085329  0.455188  0.179868  0.274085  0.218022
+0.149409  0.414893  0.200622  0.357569  0.102277
+0.087805  0.312668  0.140154  0.367296  0.098465
+0.089148  0.241602  0.116991  0.435363  0.284444
+0.102707  0.161375  0.122429  0.703344  0.226518
+0.194637  0.121701  0.250432  0.461063  0.167048
+0.127617  0.158234  0.229630  0.325473  0.201565
+0.095300  0.179652  0.103247  0.535340  0.340825
+0.087410  0.265488  0.197557  0.377987  0.253206
+0.086397  0.306960  0.231208  0.441333  0.106770
+0.121230  0.358556  0.167666  0.464476  0.115565
+0.141336  0.323618  0.111516  0.503399  0.110768
+0.105150  0.362605  0.111172  0.614013  0.078718
+0.141384  0.450586  0.064529  0.592426  0.068985
+0.098662  0.400708  0.085985  0.636453  0.149305
+0.152546  0.320095  0.087644  0.691881  0.122628
+0.205102  0.370324  0.096574  0.622388  0.082397
+0.311191  0.243388  0.111673  0.558532  0.190249
+0.260012  0.292469  0.255853  0.373923  0.095727
+0.324122  0.216718  0.325816  0.332369  0.076832
+0.213938  0.301380  0.215070  0.323471  0.134882
+0.310035  0.327218  0.144910  0.349521  0.137458
+0.328729  0.313940  0.162626  0.287671  0.091596
+0.188131  0.449382  0.149802  0.305148  0.110859
+0.226128  0.397555  0.219231  0.283246  0.128045
+0.268488  0.383741  0.267036  0.140066  0.113841
+0.300194  0.307947  0.234061  0.213999  0.085346
+0.249251  0.359982  0.175305  0.303210  0.089854
+0.305787  0.174719  0.170370  0.267549  0.093204
+0.277988  0.215844  0.288148  0.208727  0.119363
+0.251537  0.194177  0.264074  0.293404  0.095994
+0.198388  0.217117  0.190170  0.358153  0.091230
+0.259438  0.298203  0.180977  0.340391  0.098331
+0.213229  0.282142  0.168016  0.412408  0.145436
+0.155758  0.305559  0.214118  0.355955  0.096258
+0.160386  0.184590  0.361414  0.413724  0.083817
+0.112845  0.220949  0.421627  0.486660  0.061043
+0.112629  0.190622  0.638070  0.341215  0.082163
+0.116782  0.255025  0.491926  0.370337  0.065029
+0.154064  0.331035  0.181792  0.381628  0.163855
+0.109744  0.273913  0.213751  0.316332  0.168076
+0.174637  0.393942  0.248357  0.229476  0.127964
+0.132432  0.261070  0.323617  0.263662  0.118229
+0.107105  0.214560  0.444968  0.282514  0.117291
+0.119399  0.169338  0.506733  0.185210  0.138955
+0.221036  0.132225  0.518560  0.171333  0.187982
+0.199032  0.152181  0.654897  0.144632  0.237100
+0.120866  0.235536  0.584756  0.165567  0.242740
+0.109058  0.386849  0.680956  0.275759  0.068830
+0.105995  0.368329  0.606941  0.161897  0.237895
+0.143761  0.179830  0.780855  0.202850  0.097554
+0.268849  0.443371  0.378456  0.183844  0.111634
+0.228760  0.335152  0.265416  0.280008  0.156587
+0.179733  0.367035  0.353314  0.263542  0.108968
+0.167471  0.309785  0.282987  0.352425  0.164452
+0.296403  0.267574  0.263134  0.372176  0.161801
+0.226712  0.354418  0.317933  0.355062  0.151163
+0.103298  0.357472  0.310082  0.291660  0.309223
+0.101618  0.343584  0.340646  0.212203  0.202494
+0.195241  0.408380  0.177813  0.242224  0.242440
+0.313510  0.358992  0.112963  0.263010  0.210174
+0.309341  0.249017  0.208548  0.340886  0.113637
+0.372923  0.300790  0.189317  0.246020  0.170098
+0.511267  0.252399  0.215894  0.218157  0.085380
+0.460722  0.326954  0.181351  0.303566  0.087593
+0.427875  0.335350  0.285155  0.176962  0.082338
+0.362400  0.286238  0.329083  0.230290  0.137244
+0.480916  0.194219  0.211225  0.327812  0.074704
+0.352388  0.305558  0.103426  0.617043  0.070092
+0.211613  0.490287  0.136608  0.466294  0.185644
+0.179765  0.528888  0.066660  0.646064  0.127519
+0.184515  0.296351  0.122412  0.800505  0.095897
+0.139991  0.352790  0.102051  0.933430  0.160030
+0.130957  0.352874  0.086439  0.751460  0.187693
+0.097718  0.377684  0.084285  0.794735  0.086198
+0.113793  0.433105  0.077788  0.698458  0.088428
+0.110614  0.442982  0.121026  0.588836  0.093086
+0.194030  0.442051  0.073890  0.583050  0.121409
+0.168129  0.371113  0.099215  0.602795  0.239593
+0.131199  0.468405  0.097038  0.327861  0.436528
+0.105739  0.344430  0.114523  0.270244  0.474281
+0.172534  0.406580  0.145497  0.222626  0.382126
+0.087707  0.315868  0.208793  0.169532  0.349797
+0.111903  0.195832  0.150730  0.204733  0.423196
+0.085304  0.388147  0.240388  0.122330  0.256361
+0.082961  0.517760  0.233624  0.130478  0.240802
+0.082212  0.582552  0.147653  0.157918  0.277928
+0.103393  0.589256  0.170611  0.155752  0.395248
+0.085466  0.464226  0.135038  0.188922  0.198734
+0.072725  0.439998  0.165898  0.173695  0.298867
+0.104679  0.499326  0.228596  0.218945  0.325428
+0.080427  0.446632  0.200732  0.147028  0.409762
+0.075389  0.517600  0.114506  0.227527  0.363530
+0.084986  0.523083  0.086758  0.315701  0.315594
+0.088441  0.430377  0.106263  0.270315  0.279921
+0.081395  0.467028  0.133672  0.464790  0.242030
+0.090952  0.453212  0.149743  0.547528  0.175694
+0.099379  0.481611  0.071887  0.534029  0.100287
+0.083062  0.386335  0.220161  0.532010  0.173719
+0.144972  0.263844  0.201580  0.469277  0.177389
+0.142121  0.147515  0.211734  0.584132  0.310712
+0.353816  0.133526  0.405674  0.623611  0.160589
+0.324226  0.184162  0.342782  0.466907  0.096072
+0.310467  0.115672  0.285285  0.672622  0.074180
+0.263143  0.201205  0.336584  0.648774  0.075784
+0.180648  0.357954  0.426869  0.380501  0.111876
+0.119271  0.457551  0.527575  0.382157  0.062359
+0.430820  0.165178  0.255443  0.435750  0.074534
+0.237698  0.131779  0.153751  0.487195  0.075951
+0.180891  0.425850  0.088458  0.492405  0.095550
+0.127499  0.456765  0.097912  0.496377  0.139623
+0.113342  0.558562  0.083514  0.413433  0.105192
+0.154586  0.452843  0.117083  0.405856  0.095318
+0.110357  0.322982  0.108231  0.465112  0.168830
+0.106166  0.234890  0.174721  0.581859  0.064417
+0.121238  0.142086  0.198109  0.545828  0.068485
+0.126792  0.116153  0.295495  0.813626  0.074704
+0.181164  0.105619  0.372673  0.692702  0.063916
+0.112864  0.183776  0.258872  0.434172  0.231634
+0.084876  0.160535  0.242597  0.602670  0.081827
+0.099892  0.230109  0.283019  0.473404  0.089380
+0.117540  0.181325  0.242558  0.352096  0.084823
+0.096557  0.204351  0.129500  0.505436  0.090511
+0.093064  0.150856  0.121938  0.580397  0.124525
+0.097239  0.137281  0.323145  0.480001  0.089031
+0.102517  0.153194  0.359697  0.381040  0.170476
+0.156408  0.147906  0.342562  0.312323  0.095657
+0.260029  0.136204  0.390788  0.332696  0.084106
+0.299114  0.136351  0.309438  0.400320  0.068766
+0.267323  0.186838  0.183452  0.438919  0.217618
+0.107227  0.170604  0.112600  0.371471  0.390769
+0.255438  0.269699  0.266564  0.497348  0.174202
+0.190164  0.374471  0.261554  0.538124  0.113444
+0.271933  0.286121  0.157487  0.651620  0.081535
+0.196314  0.203974  0.165772  0.797090  0.105362
+0.309812  0.186345  0.098772  0.675252  0.086908
+0.383614  0.333117  0.281250  0.299235  0.085667
+0.421148  0.216396  0.359232  0.371396  0.072937
+0.318360  0.264567  0.262105  0.319453  0.073952
+0.262536  0.409518  0.292890  0.263326  0.086857
+0.231399  0.536373  0.240170  0.174999  0.098506
+0.114050  0.465195  0.301214  0.145552  0.138694
+0.099833  0.344497  0.224309  0.143338  0.129083
+0.085813  0.345800  0.327581  0.131012  0.164973
+0.127262  0.186996  0.218444  0.163716  0.232902
+0.088498  0.290046  0.185292  0.165045  0.250641
+0.110534  0.184782  0.269122  0.249893  0.115434
+0.148053  0.265736  0.193619  0.250175  0.091308
+0.379875  0.285987  0.161507  0.361349  0.144975
+0.390482  0.367610  0.105617  0.347003  0.103944
+0.334816  0.476018  0.210396  0.274579  0.200321
+0.421665  0.151238  0.177117  0.144761  0.197904
+0.454088  0.285435  0.115227  0.152621  0.139846
+0.358198  0.468506  0.200348  0.123930  0.174367
+0.185748  0.449898  0.199187  0.134662  0.194569
+0.103349  0.471913  0.152270  0.151000  0.085548
+0.282837  0.308619  0.317962  0.215435  0.105821
+0.402882  0.326504  0.197948  0.232861  0.086919
+0.390806  0.213090  0.234939  0.324037  0.084063
+0.492621  0.111084  0.319478  0.341779  0.086320
+0.482136  0.118733  0.296374  0.546299  0.071209
+0.605538  0.245134  0.181933  0.544933  0.059700
+0.618492  0.293192  0.233297  0.475559  0.067750
+0.601265  0.269593  0.342096  0.447819  0.079243
+0.514350  0.298209  0.161298  0.541413  0.079463
+0.447130  0.363282  0.181394  0.588958  0.068802
+0.438142  0.456465  0.207360  0.438283  0.087927
+0.538469  0.407440  0.181607  0.443458  0.109596
+0.521273  0.426539  0.292112  0.408676  0.079726
+0.541366  0.408530  0.221462  0.553654  0.063429
+0.541684  0.325679  0.121371  0.669718  0.149155
+0.392702  0.525994  0.076333  0.633049  0.173987
+0.333941  0.576747  0.075341  0.717406  0.129229
+0.300007  0.469533  0.314894  0.583532  0.079827
+0.359423  0.582027  0.197819  0.626980  0.071930
+0.375155  0.526411  0.181059  0.497522  0.076711
+0.440203  0.345132  0.347966  0.737184  0.090692
+0.415601  0.609245  0.350830  0.418593  0.061022
+0.200119  0.796816  0.429073  0.283859  0.065924
+0.534968  0.295700  0.290228  0.575688  0.098730
+0.332613  0.308798  0.174258  0.388578  0.074034
+0.186081  0.473443  0.092342  0.303737  0.205637
+0.286049  0.395487  0.102551  0.283964  0.109250
+0.447677  0.281928  0.093508  0.270614  0.101271
+0.275778  0.337680  0.223162  0.318782  0.151265
+0.328181  0.353926  0.241536  0.255548  0.115068
+0.344691  0.399851  0.187118  0.309705  0.081445
+0.328331  0.319898  0.212749  0.327657  0.107502
+0.403608  0.157937  0.333564  0.272334  0.085989
+0.447611  0.159044  0.250646  0.339178  0.168145
+0.367334  0.294287  0.252652  0.317527  0.166986
+0.405963  0.275243  0.245541  0.366684  0.093630
+0.305351  0.216470  0.287889  0.294907  0.143758
+0.114953  0.171443  0.123606  0.319322  0.255373
+0.090433  0.253035  0.122365  0.240238  0.333953
+0.081823  0.308896  0.093993  0.340615  0.329296
+0.082674  0.341047  0.098594  0.414837  0.255269
+0.087470  0.446794  0.079606  0.431651  0.220610
+0.089093  0.426871  0.106092  0.365100  0.328627
+0.459583  0.347569  0.081792  0.356045  0.394248
+0.593081  0.220081  0.080151  0.293147  0.332040
+0.426883  0.291573  0.100010  0.251732  0.287532
+0.167967  0.514537  0.108654  0.210527  0.270166
+0.090191  0.658566  0.116349  0.252329  0.294360
+0.101347  0.661212  0.091714  0.248497  0.188598
+0.193061  0.583990  0.132395  0.265251  0.184525
+0.236665  0.553438  0.101675  0.301357  0.108440
+0.336569  0.509293  0.104890  0.302262  0.131419
+0.321735  0.630549  0.087409  0.374096  0.112967
+0.467603  0.615493  0.085577  0.419123  0.122689
+0.453593  0.708086  0.085382  0.338539  0.118159
+0.562007  0.607979  0.086375  0.367191  0.089294
+0.670852  0.547460  0.085965  0.387358  0.091762
+0.569530  0.585864  0.070041  0.487567  0.090297
+0.517535  0.747142  0.082653  0.439445  0.085448
+0.550921  0.642960  0.210149  0.312601  0.077560
+0.434674  0.758326  0.259834  0.201585  0.120645
+0.397124  0.654162  0.458831  0.180345  0.085122
+0.593045  0.502594  0.302433  0.281234  0.088978
+0.719975  0.402121  0.203694  0.280016  0.073221
+0.715201  0.570861  0.067241  0.478463  0.065605
+0.683625  0.689241  0.060655  0.334940  0.098963
+0.556302  0.776554  0.069081  0.306893  0.086083
+0.426715  0.813035  0.104246  0.242797  0.204849
+0.378576  0.825199  0.098678  0.322154  0.096380
+0.373181  0.938991  0.074899  0.329906  0.115048
+0.531337  0.890418  0.086286  0.195433  0.102164
+0.331830  0.938828  0.132144  0.187716  0.129650
+0.263502  0.782498  0.313909  0.148704  0.136379
+0.169978  0.983636  0.087887  0.271870  0.160723
+0.421034  1.050926  0.080973  0.173235  0.091496
+0.226638  1.162236  0.131864  0.171522  0.148265
+0.153397  0.976301  0.178361  0.136460  0.233506
+0.256414  0.918775  0.249344  0.145875  0.168910
+0.296611  0.848865  0.155931  0.162775  0.271815
+0.124515  0.874587  0.289086  0.122107  0.167854
+0.126736  0.855896  0.245568  0.281517  0.123689
+0.161475  0.828095  0.407515  0.150156  0.104949
+0.405729  0.596624  0.213151  0.386929  0.116147
+0.420695  0.635707  0.107173  0.355082  0.250151
+0.391488  0.492272  0.088173  0.260076  0.229852
+0.292133  0.511892  0.094559  0.227255  0.374600
+0.446199  0.398980  0.100935  0.615509  0.072066
+0.559358  0.292218  0.134613  0.381863  0.081697
+0.531829  0.297407  0.114050  0.322506  0.239551
+0.365141  0.332372  0.155150  0.138239  0.261754
+0.246994  0.456676  0.214320  0.142386  0.333454
+0.101428  0.541105  0.347628  0.137940  0.237903
+0.111916  0.688920  0.518607  0.141385  0.130675
+0.097677  0.516438  0.680891  0.148460  0.119448
+0.074679  0.311782  0.864591  0.195630  0.074962
+0.128848  0.146236  0.877752  0.345093  0.040314
+0.250258  0.116181  0.750184  0.265212  0.071996
+0.436550  0.113508  0.609363  0.315415  0.088130
+0.563791  0.115646  0.469339  0.333534  0.061239
+0.588540  0.139056  0.251609  0.186147  0.125557
+0.654957  0.156575  0.300506  0.405071  0.075981
+0.526240  0.414692  0.183810  0.186420  0.097223
+0.597026  0.511405  0.108666  0.171816  0.130111
+0.762306  0.336982  0.108317  0.193431  0.116628
+0.631676  0.454942  0.114949  0.315528  0.083995
+0.813025  0.522594  0.067380  0.196985  0.090847
+0.931959  0.388760  0.069329  0.236506  0.086399
+0.703619  0.564281  0.098629  0.276405  0.098209
+0.669720  0.698228  0.087051  0.183111  0.087664
+0.527639  0.662217  0.125666  0.194637  0.220262
+0.435453  0.529825  0.119419  0.176498  0.096993
+0.569041  0.527193  0.094926  0.298364  0.241613
+0.454893  0.563825  0.102980  0.332162  0.090583
+0.376914  0.679534  0.106861  0.199343  0.123625
+0.256805  0.727460  0.087715  0.290642  0.122030
+0.225371  0.814127  0.136481  0.212414  0.191651
diff --git a/codec2/branches/0.7/unittest/lspd78.txt b/codec2/branches/0.7/unittest/lspd78.txt
new file mode 100644 (file)
index 0000000..f41403a
--- /dev/null
@@ -0,0 +1,64 @@
+0.281245  0.072824
+0.339645  0.060014
+0.409277  0.064576
+0.523095  0.061305
+0.230096  0.211887
+0.207683  0.332701
+0.284308  0.308783
+0.140378  0.711570
+0.174527  0.127827
+0.352952  0.235323
+0.370502  0.190103
+0.402932  0.159641
+0.347927  0.146360
+0.296583  0.131013
+0.223266  0.153607
+0.197020  0.420964
+0.116898  0.516163
+0.119488  0.109699
+0.111778  0.278792
+0.578302  0.202919
+0.414620  0.214613
+0.305886  0.397131
+0.332819  0.101995
+0.378387  0.086890
+0.382898  0.121331
+0.453255  0.063910
+0.426851  0.114357
+0.460512  0.099039
+0.479185  0.134529
+0.496434  0.084061
+0.573538  0.071989
+0.531672  0.120071
+0.591529  0.134458
+0.511033  0.180023
+0.448004  0.171478
+0.322286  0.187786
+0.297869  0.238597
+0.242424  0.263223
+0.175075  0.260064
+0.201034  0.074025
+0.268571  0.522305
+0.344104  0.296771
+0.409613  0.271732
+0.173676  0.190087
+0.115603  0.193700
+0.115269  0.373202
+0.407643  0.637929
+0.439428  0.478964
+0.567749  0.389060
+0.551502  0.271892
+0.639284  0.075639
+0.665511  0.286926
+0.720983  0.084070
+0.795786  0.214436
+0.832583  0.095102
+0.671796  0.164706
+0.983554  0.136778
+0.812831  0.368808
+0.644281  0.515306
+0.480389  0.316998
+0.403689  0.360441
+0.476736  0.232898
+0.248084  0.111421
+0.273953  0.180184
diff --git a/codec2/branches/0.7/unittest/lspd910.txt b/codec2/branches/0.7/unittest/lspd910.txt
new file mode 100644 (file)
index 0000000..9dcd14b
--- /dev/null
@@ -0,0 +1,64 @@
+0.678062  0.043120
+0.472775  0.257353
+0.522878  0.127961
+0.628034  0.038788
+0.480545  0.057725
+0.437201  0.064479
+0.327854  0.073645
+0.308168  0.135691
+0.390919  0.172150
+0.362940  0.121889
+0.384688  0.065511
+0.419078  0.117947
+0.468913  0.116759
+0.507838  0.089601
+0.555567  0.052196
+0.521040  0.052787
+0.589645  0.043616
+0.985285  0.088227
+0.724020  0.177911
+0.129928  0.130564
+0.120671  0.249971
+0.266520  0.077658
+0.685157  0.083387
+0.673088  0.130951
+0.726463  0.107217
+0.779587  0.130439
+0.652097  0.060232
+0.616365  0.062903
+0.614893  0.095188
+0.671203  0.264629
+0.657805  0.188243
+0.647995  0.095077
+0.581225  0.110398
+0.573894  0.254912
+0.531176  0.201073
+0.544230  0.353796
+0.621094  0.138556
+0.717028  0.053894
+0.890269  0.071236
+1.100420  0.115118
+0.492946  0.167302
+0.387836  0.249419
+0.929411  0.210459
+0.389735  0.351413
+0.273341  0.443161
+0.453321  0.457227
+0.303206  0.300360
+0.563261  0.148813
+0.789479  0.244432
+0.817080  0.062843
+0.852058  0.150352
+0.760492  0.059787
+0.711233  0.355546
+0.598869  0.189758
+0.583624  0.073653
+0.548949  0.089569
+0.445394  0.183962
+0.333115  0.197087
+0.246232  0.142290
+0.263973  0.216087
+0.185969  0.192135
+0.205425  0.302232
+0.195923  0.088343
+0.148277  0.406699
diff --git a/codec2/branches/0.7/unittest/lspjnd5-10.txt b/codec2/branches/0.7/unittest/lspjnd5-10.txt
new file mode 100644 (file)
index 0000000..e4e500c
--- /dev/null
@@ -0,0 +1,8317 @@
+6 3369
+1400.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1400.0  1900.0  2400.0  2500.0  3200.0  3400.0
+1400.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1400.0  1800.0  2400.0  2500.0  3300.0  3400.0
+1400.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1400.0  1900.0  2300.0  2600.0  3200.0  3300.0
+1400.0  1900.0  2100.0  2600.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1900.0  2300.0  2600.0  3100.0  3200.0
+1600.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1800.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1800.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1900.0  2000.0  2200.0  2600.0  3300.0  3400.0
+1700.0  2000.0  2700.0  2900.0  3200.0  3300.0
+1700.0  2100.0  2600.0  2900.0  3200.0  3300.0
+1600.0  2000.0  2500.0  2800.0  3200.0  3400.0
+1500.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1400.0  1700.0  2200.0  2400.0  3200.0  3300.0
+1300.0  1700.0  2200.0  2300.0  3200.0  3300.0
+1300.0  1600.0  2200.0  2300.0  3200.0  3300.0
+1200.0  1600.0  2200.0  2400.0  3200.0  3300.0
+1200.0  1600.0  2200.0  2300.0  3200.0  3300.0
+1200.0  1500.0  2200.0  2300.0  3100.0  3300.0
+1200.0  1500.0  2200.0  2300.0  3200.0  3300.0
+1300.0  1500.0  2100.0  2300.0  3000.0  3200.0
+1300.0  1600.0  2000.0  2200.0  3000.0  3200.0
+1400.0  1700.0  2000.0  2300.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2300.0  3200.0  3300.0
+1300.0  1600.0  1900.0  2100.0  3100.0  3200.0
+1200.0  1500.0  2100.0  2300.0  3200.0  3300.0
+1500.0  1800.0  2000.0  2300.0  3000.0  3200.0
+1200.0  1500.0  2200.0  2400.0  3300.0  3400.0
+1200.0  1500.0  2200.0  2400.0  3200.0  3400.0
+1200.0  1500.0  2200.0  2400.0  3200.0  3300.0
+1300.0  1500.0  2300.0  2400.0  3200.0  3300.0
+1300.0  1500.0  2200.0  2500.0  3000.0  3200.0
+1300.0  1600.0  2300.0  2600.0  3000.0  3200.0
+1400.0  1800.0  2400.0  2600.0  3100.0  3200.0
+1700.0  2000.0  2500.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2600.0  2700.0  3100.0  3200.0
+1900.0  2300.0  2600.0  2900.0  3200.0  3300.0
+2000.0  2300.0  2600.0  2900.0  3300.0  3400.0
+1900.0  2300.0  2500.0  2900.0  3300.0  3400.0
+1800.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1600.0  1800.0  2400.0  2500.0  3200.0  3400.0
+1500.0  1800.0  2400.0  2600.0  3100.0  3400.0
+1800.0  2100.0  2600.0  2900.0  3300.0  3500.0
+2000.0  2500.0  2700.0  3000.0  3400.0  3500.0
+2200.0  2500.0  2700.0  3100.0  3300.0  3400.0
+2300.0  2500.0  2700.0  3100.0  3300.0  3400.0
+2100.0  2500.0  2600.0  3000.0  3200.0  3300.0
+2100.0  2400.0  2500.0  3000.0  3200.0  3300.0
+1700.0  2000.0  2300.0  2700.0  3100.0  3200.0
+1700.0  2000.0  2300.0  2800.0  3100.0  3300.0
+1600.0  1900.0  2200.0  2800.0  3000.0  3200.0
+1500.0  1900.0  2100.0  2700.0  3000.0  3200.0
+1400.0  1900.0  2000.0  2600.0  3000.0  3100.0
+1200.0  1600.0  2100.0  2400.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2400.0  3200.0  3400.0
+1600.0  1700.0  2200.0  2400.0  3100.0  3400.0
+1600.0  1700.0  2200.0  2400.0  3200.0  3400.0
+1700.0  1800.0  2300.0  2400.0  3200.0  3400.0
+1700.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1700.0  1800.0  2300.0  2400.0  3100.0  3200.0
+1700.0  1800.0  2200.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2100.0  2400.0  3000.0  3100.0
+1500.0  1700.0  2100.0  2300.0  3000.0  3100.0
+1400.0  1700.0  2100.0  2500.0  3000.0  3200.0
+1000.0  1700.0  2300.0  2500.0  3200.0  3300.0
+1100.0  1700.0  2400.0  2500.0  3300.0  3400.0
+1500.0  2000.0  2300.0  2600.0  3000.0  3300.0
+1300.0  1600.0  1800.0  2600.0  2900.0  3100.0
+1300.0  1600.0  1900.0  2200.0  2900.0  3000.0
+1500.0  1700.0  2200.0  2500.0  2900.0  3000.0
+1500.0  1600.0  2100.0  2400.0  2900.0  3100.0
+1500.0  1600.0  2000.0  2600.0  3000.0  3100.0
+1600.0  1700.0  2100.0  2600.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2500.0  3300.0  3400.0
+1700.0  1900.0  2200.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2400.0  2600.0  3000.0  3300.0
+1700.0  2100.0  2400.0  2600.0  3100.0  3300.0
+1700.0  2100.0  2400.0  2600.0  3200.0  3400.0
+1400.0  1600.0  2300.0  2400.0  3300.0  3400.0
+1300.0  1400.0  2100.0  2200.0  2900.0  3200.0
+1000.0  1300.0  2200.0  2300.0  3200.0  3400.0
+1600.0  2000.0  2300.0  2600.0  2800.0  3100.0
+1600.0  2000.0  2300.0  2600.0  2900.0  3200.0
+1600.0  2000.0  2300.0  2600.0  3100.0  3300.0
+1700.0  2000.0  2300.0  2600.0  3100.0  3300.0
+1600.0  1900.0  2300.0  2500.0  3100.0  3400.0
+1500.0  1900.0  2300.0  2600.0  3000.0  3300.0
+1500.0  1900.0  2300.0  2600.0  3100.0  3300.0
+1500.0  2000.0  2300.0  2700.0  3100.0  3300.0
+2000.0  2500.0  2700.0  2900.0  3300.0  3400.0
+2000.0  2400.0  2600.0  2800.0  3300.0  3400.0
+1700.0  2300.0  2600.0  2800.0  3300.0  3400.0
+1400.0  1700.0  2400.0  2500.0  3200.0  3300.0
+1300.0  1600.0  2300.0  2500.0  3200.0  3300.0
+1300.0  1500.0  2000.0  2300.0  3200.0  3300.0
+1500.0  1800.0  2200.0  2400.0  2900.0  3300.0
+1500.0  1700.0  2200.0  2400.0  3000.0  3200.0
+1400.0  1800.0  2200.0  2400.0  3000.0  3300.0
+1400.0  1800.0  2200.0  2400.0  3000.0  3200.0
+1200.0  1500.0  2100.0  2400.0  3100.0  3300.0
+1300.0  1800.0  2200.0  2300.0  3300.0  3400.0
+1300.0  1700.0  2200.0  2400.0  3300.0  3400.0
+1400.0  1500.0  2300.0  2500.0  3100.0  3400.0
+1500.0  1600.0  2300.0  2500.0  3100.0  3300.0
+1500.0  1600.0  2400.0  2500.0  3100.0  3300.0
+1400.0  1800.0  2400.0  2500.0  3000.0  3300.0
+1300.0  1700.0  2100.0  2500.0  3000.0  3200.0
+1300.0  1600.0  2100.0  2500.0  3100.0  3200.0
+1300.0  1700.0  2200.0  2500.0  3100.0  3200.0
+1300.0  1600.0  2200.0  2500.0  3100.0  3300.0
+1300.0  1700.0  2300.0  2600.0  3200.0  3300.0
+1300.0  1700.0  2400.0  2500.0  3200.0  3400.0
+1500.0  1900.0  2500.0  2600.0  3200.0  3400.0
+1500.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1600.0  2100.0  2600.0  2900.0  3400.0  3500.0
+1600.0  1900.0  2500.0  2800.0  3300.0  3400.0
+1500.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1600.0  2000.0  2500.0  2700.0  3100.0  3200.0
+1500.0  1700.0  2400.0  2700.0  3100.0  3200.0
+1500.0  1600.0  2400.0  2600.0  3100.0  3300.0
+1500.0  1600.0  2200.0  2400.0  3000.0  3200.0
+1500.0  1600.0  2200.0  2300.0  3000.0  3200.0
+1400.0  1700.0  2100.0  2300.0  3000.0  3100.0
+1700.0  1800.0  2300.0  2800.0  3100.0  3300.0
+1800.0  2100.0  2500.0  2800.0  3200.0  3300.0
+1800.0  2200.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1800.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1600.0  2000.0  2300.0  2500.0  3000.0  3200.0
+1500.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1500.0  1700.0  2200.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2400.0  3000.0  3100.0
+1600.0  1700.0  2300.0  2400.0  3000.0  3100.0
+1600.0  1700.0  2300.0  2400.0  3000.0  3200.0
+1600.0  1700.0  2300.0  2400.0  2900.0  3100.0
+1600.0  1700.0  2300.0  2400.0  2900.0  3200.0
+1600.0  1700.0  2300.0  2500.0  2900.0  3200.0
+1500.0  1600.0  2300.0  2500.0  2900.0  3300.0
+1400.0  1500.0  2200.0  2500.0  3000.0  3300.0
+1200.0  1400.0  2300.0  2400.0  3000.0  3300.0
+1100.0  1400.0  2300.0  2400.0  3100.0  3300.0
+1200.0  1800.0  2400.0  2500.0  3300.0  3400.0
+1400.0  2000.0  2400.0  2700.0  3300.0  3400.0
+1600.0  2100.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2300.0  2600.0  2900.0  3300.0  3400.0
+1400.0  2100.0  2400.0  2600.0  3100.0  3200.0
+1300.0  1600.0  2300.0  2500.0  3000.0  3200.0
+1200.0  1500.0  2100.0  2500.0  3000.0  3200.0
+1300.0  1700.0  2100.0  2300.0  2900.0  3200.0
+1500.0  1600.0  2200.0  2400.0  3000.0  3100.0
+1500.0  1600.0  2200.0  2500.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2500.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2500.0  3100.0  3300.0
+1600.0  1700.0  2200.0  2400.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2500.0  3300.0  3400.0
+1700.0  1800.0  2300.0  2500.0  3300.0  3400.0
+1800.0  2000.0  2300.0  2700.0  3200.0  3300.0
+1900.0  2000.0  2300.0  2700.0  3300.0  3400.0
+1900.0  2000.0  2100.0  2400.0  3300.0  3400.0
+1800.0  2100.0  2400.0  2800.0  3200.0  3400.0
+2000.0  2200.0  2500.0  2700.0  3100.0  3300.0
+2000.0  2300.0  2500.0  2700.0  3100.0  3300.0
+2000.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1900.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1800.0  1900.0  2300.0  2600.0  3300.0  3400.0
+1800.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1700.0  1800.0  2300.0  2600.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2300.0  2600.0  3200.0  3300.0
+1500.0  1800.0  2200.0  2400.0  3200.0  3300.0
+1500.0  1800.0  2100.0  2500.0  3100.0  3200.0
+1700.0  2100.0  2400.0  2800.0  3200.0  3300.0
+1900.0  2100.0  2500.0  2900.0  3200.0  3300.0
+1900.0  2100.0  2400.0  2900.0  3200.0  3300.0
+1800.0  2100.0  2400.0  2800.0  3100.0  3200.0
+2000.0  2200.0  2500.0  2800.0  3100.0  3300.0
+2000.0  2200.0  2700.0  2800.0  3100.0  3300.0
+2000.0  2300.0  2600.0  2800.0  3200.0  3300.0
+1800.0  2000.0  2600.0  2800.0  3200.0  3300.0
+1800.0  2100.0  2600.0  2800.0  3200.0  3400.0
+1800.0  2200.0  2500.0  2700.0  3300.0  3400.0
+1700.0  1900.0  2500.0  2600.0  3200.0  3400.0
+1700.0  1900.0  2400.0  2700.0  3200.0  3400.0
+1500.0  1900.0  2500.0  2600.0  3100.0  3300.0
+1200.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1300.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1200.0  1600.0  2400.0  2600.0  3200.0  3300.0
+1200.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1300.0  2000.0  2400.0  2700.0  3200.0  3300.0
+1200.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1100.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1100.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1100.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1000.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1000.0  1500.0  2400.0  2500.0  3100.0  3200.0
+1000.0  1500.0  2300.0  2400.0  3100.0  3200.0
+1000.0  1900.0  2300.0  2500.0  3000.0  3100.0
+1100.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1200.0  1800.0  2300.0  2400.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2400.0  3100.0  3200.0
+1400.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2400.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2400.0  3100.0  3200.0
+1500.0  1800.0  2200.0  2400.0  3100.0  3200.0
+1400.0  1800.0  2200.0  2400.0  3100.0  3200.0
+1400.0  1800.0  2200.0  2400.0  3000.0  3100.0
+1800.0  2000.0  2300.0  2800.0  2900.0  3100.0
+1500.0  1900.0  2300.0  2500.0  3100.0  3200.0
+1500.0  1900.0  2300.0  2400.0  3300.0  3400.0
+1500.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1600.0  2000.0  2400.0  2700.0  3300.0  3400.0
+1600.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1700.0  2100.0  2400.0  2600.0  2900.0  3200.0
+1600.0  2000.0  2500.0  2700.0  2900.0  3200.0
+1500.0  1800.0  2400.0  2800.0  3000.0  3200.0
+1500.0  1800.0  2100.0  2400.0  2900.0  3100.0
+1600.0  1900.0  2100.0  2400.0  3100.0  3300.0
+1600.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1800.0  1900.0  2300.0  2400.0  3100.0  3300.0
+1900.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1900.0  2200.0  2600.0  2700.0  3300.0  3400.0
+1900.0  2300.0  2600.0  2700.0  3300.0  3400.0
+1900.0  2300.0  2700.0  2800.0  3300.0  3400.0
+2000.0  2200.0  2700.0  2800.0  3300.0  3400.0
+2000.0  2400.0  2700.0  2800.0  3300.0  3400.0
+2000.0  2300.0  2700.0  2800.0  3300.0  3400.0
+2000.0  2400.0  2600.0  2700.0  3300.0  3400.0
+2000.0  2200.0  2600.0  2700.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2700.0  3200.0  3300.0
+1900.0  2100.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2600.0  3100.0  3200.0
+1900.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1800.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1800.0  1900.0  2300.0  2500.0  3000.0  3100.0
+1800.0  1900.0  2400.0  2700.0  3000.0  3200.0
+1800.0  1900.0  2500.0  2700.0  3000.0  3200.0
+1800.0  2000.0  2500.0  2700.0  3100.0  3200.0
+2000.0  2300.0  2600.0  2900.0  3100.0  3300.0
+1900.0  2300.0  2700.0  3000.0  3200.0  3300.0
+2000.0  2400.0  2700.0  3000.0  3200.0  3300.0
+2100.0  2500.0  2800.0  3000.0  3200.0  3300.0
+2200.0  2400.0  2800.0  3000.0  3300.0  3400.0
+1900.0  2200.0  2700.0  2900.0  3300.0  3400.0
+2200.0  2400.0  2900.0  3100.0  3300.0  3400.0
+2100.0  2400.0  2800.0  3100.0  3300.0  3400.0
+2200.0  2500.0  2800.0  3100.0  3300.0  3400.0
+2100.0  2400.0  2600.0  2800.0  3300.0  3400.0
+2000.0  2400.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2400.0  2700.0  3200.0  3300.0
+1800.0  1900.0  2400.0  2700.0  3100.0  3200.0
+1800.0  1900.0  2400.0  2700.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2700.0  3100.0  3200.0
+1700.0  1900.0  2200.0  2700.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2700.0  2900.0  3200.0
+1700.0  1900.0  2300.0  2700.0  2900.0  3200.0
+1700.0  1900.0  2200.0  2700.0  3000.0  3200.0
+1700.0  2000.0  2300.0  2800.0  3000.0  3200.0
+1400.0  1700.0  2300.0  2400.0  3300.0  3400.0
+1400.0  1800.0  2300.0  2400.0  3300.0  3400.0
+1400.0  1900.0  2300.0  2400.0  3300.0  3400.0
+1400.0  2100.0  2300.0  2500.0  3300.0  3400.0
+1400.0  2100.0  2300.0  2600.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2700.0  3200.0  3400.0
+1800.0  2100.0  2600.0  2900.0  3200.0  3400.0
+1800.0  2100.0  2600.0  2800.0  3300.0  3400.0
+1800.0  2100.0  2600.0  2700.0  3300.0  3400.0
+1800.0  2000.0  2500.0  2700.0  3300.0  3400.0
+1800.0  2100.0  2400.0  2700.0  3300.0  3400.0
+1800.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1800.0  2200.0  2400.0  2600.0  3300.0  3400.0
+1800.0  2200.0  2400.0  2700.0  3300.0  3400.0
+1900.0  2300.0  2600.0  2900.0  3200.0  3400.0
+1900.0  2200.0  2600.0  2700.0  3200.0  3400.0
+1900.0  2100.0  2600.0  2700.0  3300.0  3400.0
+2000.0  2100.0  2500.0  2700.0  3200.0  3300.0
+2000.0  2100.0  2500.0  2700.0  3300.0  3400.0
+2000.0  2200.0  2500.0  2700.0  3300.0  3400.0
+2000.0  2100.0  2600.0  2700.0  3300.0  3400.0
+2000.0  2100.0  2500.0  2700.0  3400.0  3500.0
+1900.0  2100.0  2500.0  2600.0  3200.0  3400.0
+2000.0  2200.0  2600.0  2700.0  3200.0  3400.0
+2100.0  2300.0  2600.0  2800.0  3300.0  3400.0
+2100.0  2500.0  2700.0  3100.0  3300.0  3400.0
+2100.0  2500.0  2800.0  3100.0  3300.0  3400.0
+2100.0  2300.0  2400.0  2700.0  3200.0  3300.0
+2000.0  2300.0  2500.0  2800.0  3200.0  3300.0
+1700.0  2100.0  2500.0  2700.0  3200.0  3300.0
+1600.0  1900.0  2300.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2300.0  2800.0  3100.0  3300.0
+1500.0  1800.0  2300.0  2400.0  3100.0  3200.0
+1500.0  1700.0  2300.0  2400.0  3100.0  3300.0
+1400.0  1700.0  2300.0  2400.0  3100.0  3300.0
+1400.0  1500.0  2300.0  2400.0  3100.0  3300.0
+1300.0  1500.0  2300.0  2400.0  3100.0  3300.0
+1300.0  1500.0  2400.0  2500.0  3100.0  3300.0
+1300.0  1500.0  2400.0  2500.0  3000.0  3300.0
+1300.0  1500.0  2300.0  2400.0  2900.0  3300.0
+1400.0  1500.0  2400.0  2500.0  2900.0  3300.0
+1500.0  1600.0  2300.0  2500.0  2800.0  3300.0
+1600.0  1700.0  2300.0  2500.0  2800.0  3400.0
+1700.0  1800.0  2300.0  2500.0  2800.0  3300.0
+1800.0  1900.0  2400.0  2500.0  3100.0  3400.0
+1800.0  1900.0  2400.0  2500.0  3200.0  3400.0
+1900.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1900.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1900.0  2200.0  2600.0  2900.0  3400.0  3500.0
+1800.0  2200.0  2600.0  2900.0  3300.0  3400.0
+1900.0  2300.0  2600.0  3000.0  3400.0  3500.0
+2000.0  2300.0  2600.0  3000.0  3300.0  3400.0
+1800.0  2200.0  2500.0  2900.0  3200.0  3300.0
+1800.0  2100.0  2400.0  2700.0  3200.0  3300.0
+1900.0  2100.0  2500.0  2800.0  3200.0  3300.0
+1700.0  2100.0  2500.0  2700.0  3100.0  3300.0
+1400.0  1800.0  2300.0  2600.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2400.0  3000.0  3100.0
+1500.0  1800.0  2300.0  2600.0  3000.0  3200.0
+1900.0  2200.0  2500.0  2800.0  3000.0  3300.0
+2000.0  2300.0  2600.0  2800.0  3100.0  3300.0
+2000.0  2300.0  2700.0  2900.0  3100.0  3300.0
+2100.0  2300.0  2700.0  2900.0  3100.0  3300.0
+2000.0  2300.0  2700.0  3000.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2600.0  3300.0  3400.0
+1400.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1300.0  1900.0  2300.0  2600.0  3100.0  3300.0
+1200.0  1600.0  2200.0  2400.0  3000.0  3100.0
+1100.0  1500.0  2200.0  2400.0  3100.0  3200.0
+1100.0  1400.0  2300.0  2400.0  3200.0  3300.0
+1100.0  1500.0  2300.0  2400.0  3200.0  3300.0
+1100.0  1500.0  2300.0  2400.0  3300.0  3400.0
+1300.0  1400.0  2400.0  2500.0  3100.0  3300.0
+1500.0  2200.0  2500.0  2600.0  3100.0  3200.0
+2100.0  2400.0  2700.0  3000.0  3200.0  3300.0
+2200.0  2400.0  2700.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2700.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2700.0  2900.0  3300.0  3400.0
+2000.0  2300.0  2700.0  3000.0  3400.0  3500.0
+2100.0  2400.0  2700.0  3000.0  3400.0  3500.0
+2100.0  2500.0  2700.0  3100.0  3400.0  3500.0
+1900.0  2400.0  2600.0  2800.0  3300.0  3400.0
+1900.0  2100.0  2600.0  2800.0  3300.0  3400.0
+1900.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1900.0  2100.0  2500.0  2600.0  3300.0  3400.0
+1800.0  2200.0  2400.0  2800.0  3300.0  3400.0
+1800.0  2000.0  2400.0  2700.0  3300.0  3400.0
+1900.0  2000.0  2400.0  2700.0  3200.0  3300.0
+2000.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1500.0  2100.0  2200.0  2500.0  3300.0  3400.0
+1400.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1400.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1400.0  1800.0  2200.0  2600.0  3100.0  3200.0
+1700.0  2100.0  2400.0  2700.0  3100.0  3300.0
+1800.0  2000.0  2400.0  2700.0  3000.0  3200.0
+1600.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1700.0  2000.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2200.0  2600.0  2900.0  3200.0
+1600.0  1900.0  2300.0  2600.0  2900.0  3200.0
+1600.0  1900.0  2300.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2500.0  3000.0  3200.0
+1600.0  1800.0  2300.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2400.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2500.0  3000.0  3100.0
+1700.0  1800.0  2300.0  2500.0  3100.0  3200.0
+1700.0  1800.0  2200.0  2400.0  3000.0  3200.0
+1700.0  1800.0  2100.0  2300.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2400.0  3000.0  3200.0
+1800.0  2000.0  2200.0  2400.0  3000.0  3200.0
+1800.0  2000.0  2300.0  2500.0  3100.0  3300.0
+1800.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1800.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1700.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1700.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1800.0  2100.0  2500.0  2900.0  3300.0  3400.0
+1800.0  2200.0  2600.0  2800.0  3300.0  3500.0
+1800.0  2100.0  2600.0  2900.0  3300.0  3400.0
+1800.0  2100.0  2600.0  3000.0  3200.0  3300.0
+1800.0  2200.0  2600.0  2900.0  3200.0  3300.0
+1800.0  2100.0  2600.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2400.0  2700.0  3100.0  3200.0
+1700.0  2000.0  2300.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2300.0  2600.0  3000.0  3100.0
+1800.0  2100.0  2400.0  2600.0  3100.0  3200.0
+1800.0  2100.0  2400.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2400.0  2700.0  3200.0  3300.0
+1800.0  2000.0  2400.0  2700.0  3100.0  3300.0
+1700.0  2000.0  2400.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2300.0  2700.0  3100.0  3300.0
+1700.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1700.0  2200.0  2500.0  3000.0  3200.0
+1500.0  1700.0  2100.0  2500.0  2900.0  3100.0
+1500.0  1800.0  2300.0  2600.0  2900.0  3200.0
+1500.0  1900.0  2400.0  2600.0  3000.0  3200.0
+1600.0  2000.0  2300.0  2700.0  3100.0  3200.0
+1600.0  2000.0  2400.0  2700.0  3100.0  3300.0
+1600.0  2200.0  2600.0  2900.0  3300.0  3400.0
+1700.0  2200.0  2600.0  3000.0  3300.0  3400.0
+1700.0  2100.0  2500.0  2900.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2900.0  3300.0  3400.0
+1500.0  1800.0  2400.0  2500.0  3200.0  3400.0
+1500.0  1700.0  2400.0  2500.0  3300.0  3400.0
+1500.0  1700.0  2300.0  2400.0  3300.0  3400.0
+1600.0  1800.0  2300.0  2400.0  3300.0  3400.0
+1600.0  1800.0  2400.0  2500.0  3300.0  3400.0
+1600.0  1700.0  2400.0  2500.0  2800.0  3300.0
+1600.0  1800.0  2300.0  2500.0  2700.0  3200.0
+1600.0  1700.0  2300.0  2500.0  2700.0  3200.0
+1600.0  1700.0  2200.0  2500.0  2700.0  3100.0
+1600.0  1700.0  2200.0  2500.0  2600.0  3000.0
+1600.0  1700.0  2400.0  2500.0  2700.0  3200.0
+1600.0  1700.0  2400.0  2500.0  2800.0  3200.0
+1700.0  1800.0  2400.0  2600.0  2900.0  3300.0
+1700.0  1800.0  2300.0  2600.0  2800.0  3300.0
+1700.0  1800.0  2400.0  2600.0  3000.0  3400.0
+1700.0  1800.0  2300.0  2500.0  2900.0  3300.0
+1600.0  1700.0  2300.0  2500.0  3000.0  3300.0
+1400.0  1800.0  2000.0  2400.0  3000.0  3200.0
+1400.0  1700.0  2000.0  2300.0  3000.0  3200.0
+1700.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1700.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1800.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1900.0  2000.0  2300.0  2600.0  3300.0  3400.0
+2000.0  2100.0  2200.0  2600.0  3300.0  3400.0
+2000.0  2100.0  2300.0  2600.0  3300.0  3400.0
+2100.0  2200.0  2500.0  2800.0  3300.0  3400.0
+2000.0  2100.0  2300.0  2500.0  3200.0  3300.0
+1900.0  2000.0  2200.0  2600.0  3200.0  3300.0
+1800.0  1900.0  2100.0  2600.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2600.0  3000.0  3200.0
+1500.0  1800.0  2100.0  2300.0  3000.0  3200.0
+1500.0  1800.0  2100.0  2400.0  3100.0  3300.0
+1500.0  1700.0  2200.0  2500.0  3100.0  3300.0
+1500.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1500.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1800.0  2300.0  2600.0  3000.0  3400.0  3500.0
+1900.0  2300.0  2700.0  3000.0  3400.0  3500.0
+2000.0  2300.0  2800.0  3100.0  3300.0  3400.0
+2100.0  2300.0  2800.0  3100.0  3300.0  3400.0
+2000.0  2300.0  2700.0  3000.0  3200.0  3300.0
+2000.0  2200.0  2600.0  2900.0  3100.0  3300.0
+2000.0  2200.0  2500.0  2800.0  3000.0  3200.0
+2000.0  2200.0  2400.0  2800.0  3100.0  3200.0
+1600.0  2000.0  2400.0  2600.0  3100.0  3200.0
+1400.0  1900.0  2400.0  2500.0  3100.0  3200.0
+1400.0  1900.0  2300.0  2600.0  3000.0  3200.0
+1500.0  2000.0  2400.0  2700.0  2900.0  3200.0
+2000.0  2300.0  2800.0  3000.0  3200.0  3400.0
+2100.0  2300.0  2900.0  3100.0  3300.0  3400.0
+1800.0  2300.0  2600.0  2900.0  3400.0  3500.0
+1700.0  2300.0  2500.0  2900.0  3300.0  3400.0
+1300.0  2000.0  2400.0  2700.0  3300.0  3400.0
+1200.0  1900.0  2300.0  2600.0  3300.0  3400.0
+1200.0  1800.0  2300.0  2600.0  3300.0  3400.0
+1100.0  1800.0  2300.0  2500.0  3300.0  3400.0
+1800.0  2200.0  2600.0  2800.0  3300.0  3400.0
+1800.0  2000.0  2500.0  2700.0  3200.0  3400.0
+1700.0  2100.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2200.0  2600.0  2800.0  3300.0  3400.0
+1800.0  2200.0  2600.0  3000.0  3300.0  3500.0
+1700.0  2100.0  2600.0  2800.0  3300.0  3400.0
+1700.0  2100.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2800.0  3300.0  3500.0
+1800.0  2200.0  2500.0  2900.0  3300.0  3400.0
+2100.0  2200.0  2600.0  2700.0  3100.0  3400.0
+1900.0  2100.0  2500.0  2600.0  3100.0  3400.0
+1900.0  2000.0  2500.0  2600.0  3200.0  3400.0
+1900.0  2000.0  2600.0  2700.0  3200.0  3400.0
+1800.0  1900.0  2500.0  2600.0  3100.0  3400.0
+1600.0  2000.0  2700.0  2800.0  3300.0  3400.0
+1400.0  2000.0  2700.0  2800.0  3300.0  3400.0
+1000.0  1900.0  2700.0  2800.0  3300.0  3400.0
+1000.0  1400.0  2700.0  2900.0  3200.0  3400.0
+1100.0  1500.0  2700.0  2900.0  3200.0  3300.0
+1200.0  1700.0  2400.0  2500.0  3100.0  3300.0
+1300.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1300.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1400.0  2000.0  2400.0  2600.0  3100.0  3300.0
+1500.0  2000.0  2400.0  2700.0  3000.0  3300.0
+1300.0  2100.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1900.0  2700.0  2800.0  3300.0  3400.0
+1500.0  1900.0  2700.0  2800.0  3300.0  3400.0
+1400.0  1800.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2300.0  2600.0  2700.0  2900.0  3200.0
+1500.0  1700.0  2400.0  2600.0  2800.0  3300.0
+1600.0  1700.0  2500.0  2700.0  2900.0  3300.0
+1800.0  1900.0  2600.0  2700.0  3200.0  3400.0
+1800.0  1900.0  2600.0  2700.0  3200.0  3300.0
+2000.0  2200.0  2600.0  2800.0  3200.0  3300.0
+2000.0  2100.0  2600.0  2700.0  3200.0  3400.0
+2000.0  2100.0  2500.0  2800.0  3200.0  3400.0
+2000.0  2100.0  2600.0  2700.0  3100.0  3300.0
+1900.0  2000.0  2400.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2400.0  2600.0  3100.0  3200.0
+1700.0  2000.0  2300.0  2400.0  3200.0  3300.0
+1900.0  2100.0  2500.0  2700.0  3200.0  3400.0
+1900.0  2000.0  2500.0  2700.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1800.0  2100.0  2500.0  2700.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2600.0  3200.0  3400.0
+1800.0  1900.0  2400.0  2500.0  3000.0  3300.0
+1800.0  2000.0  2400.0  2600.0  3100.0  3300.0
+1900.0  2100.0  2500.0  2600.0  3200.0  3300.0
+2000.0  2100.0  2500.0  2600.0  3300.0  3400.0
+2000.0  2200.0  2500.0  2600.0  3300.0  3400.0
+2100.0  2200.0  2500.0  2600.0  3300.0  3400.0
+2100.0  2200.0  2500.0  2600.0  3200.0  3400.0
+2100.0  2200.0  2400.0  2500.0  3200.0  3400.0
+2000.0  2100.0  2400.0  2500.0  3200.0  3400.0
+1800.0  1900.0  2400.0  2600.0  3200.0  3400.0
+1800.0  1900.0  2500.0  2600.0  3200.0  3400.0
+1800.0  2300.0  2700.0  2900.0  3300.0  3400.0
+1900.0  2400.0  2800.0  3000.0  3300.0  3500.0
+1900.0  2300.0  2800.0  3100.0  3300.0  3400.0
+2000.0  2300.0  2700.0  2900.0  3200.0  3400.0
+1800.0  2000.0  2600.0  2900.0  3300.0  3400.0
+1700.0  2000.0  2500.0  2600.0  3200.0  3400.0
+1600.0  2100.0  2500.0  2600.0  3300.0  3400.0
+1500.0  2100.0  2500.0  2600.0  3300.0  3400.0
+1500.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1400.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2400.0  2600.0  3100.0  3300.0
+1300.0  2000.0  2600.0  2800.0  3300.0  3400.0
+1500.0  2000.0  2600.0  2700.0  3300.0  3400.0
+1600.0  2000.0  2500.0  2700.0  3200.0  3400.0
+1600.0  2000.0  2500.0  2600.0  3200.0  3400.0
+1600.0  2000.0  2400.0  2500.0  3200.0  3400.0
+1700.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1600.0  1900.0  2300.0  2400.0  3300.0  3400.0
+1500.0  1700.0  2200.0  2400.0  3200.0  3300.0
+1500.0  1800.0  2200.0  2500.0  2900.0  3200.0
+1300.0  1700.0  2200.0  2500.0  3000.0  3300.0
+1200.0  1700.0  2200.0  2600.0  3000.0  3200.0
+1100.0  1700.0  2300.0  2600.0  3100.0  3300.0
+1200.0  1800.0  2300.0  2500.0  3300.0  3400.0
+1100.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1200.0  2200.0  2400.0  2700.0  3300.0  3400.0
+1200.0  2300.0  2500.0  2700.0  3300.0  3400.0
+1200.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1200.0  2300.0  2600.0  2800.0  3300.0  3400.0
+1100.0  1800.0  2500.0  2600.0  3400.0  3500.0
+1300.0  1700.0  2500.0  2600.0  3200.0  3400.0
+1400.0  1800.0  2500.0  2600.0  3200.0  3400.0
+1500.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1500.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1800.0  1900.0  2500.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2400.0  2500.0  3200.0  3300.0
+2000.0  2100.0  2300.0  2500.0  3300.0  3400.0
+1500.0  1900.0  2400.0  2800.0  3100.0  3300.0
+1200.0  1700.0  2500.0  2600.0  3300.0  3400.0
+1300.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1400.0  1800.0  2500.0  2700.0  3300.0  3400.0
+1300.0  1700.0  2400.0  2700.0  3200.0  3400.0
+1100.0  2100.0  2600.0  2700.0  3300.0  3400.0
+1200.0  2100.0  2600.0  2700.0  3300.0  3400.0
+1200.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1200.0  2100.0  2500.0  2600.0  3300.0  3400.0
+1200.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1200.0  2200.0  2500.0  2700.0  3400.0  3500.0
+1400.0  1800.0  2400.0  2600.0  3100.0  3400.0
+1400.0  1900.0  2400.0  2600.0  3100.0  3300.0
+1500.0  1800.0  2400.0  2700.0  3100.0  3300.0
+1500.0  1900.0  2400.0  2600.0  3200.0  3400.0
+1600.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1900.0  2200.0  2400.0  2600.0  3300.0  3400.0
+2000.0  2200.0  2400.0  2600.0  3200.0  3300.0
+2000.0  2100.0  2400.0  2500.0  3200.0  3300.0
+2100.0  2200.0  2500.0  2600.0  3200.0  3300.0
+2100.0  2200.0  2500.0  2700.0  3200.0  3300.0
+2000.0  2100.0  2400.0  2600.0  3100.0  3200.0
+1500.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1500.0  1900.0  2300.0  2400.0  3100.0  3300.0
+1500.0  1800.0  2300.0  2400.0  3100.0  3300.0
+1400.0  1800.0  2300.0  2400.0  3100.0  3300.0
+1400.0  1900.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1500.0  1800.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1700.0  2200.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2200.0  2500.0  3000.0  3200.0
+1300.0  1700.0  2400.0  2600.0  3100.0  3200.0
+1400.0  1700.0  2200.0  2500.0  3200.0  3300.0
+1400.0  1800.0  2300.0  2500.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1100.0  1500.0  2300.0  2400.0  3200.0  3400.0
+1000.0  1600.0  2500.0  2600.0  3300.0  3400.0
+1000.0  1700.0  2500.0  2600.0  3300.0  3400.0
+1000.0  1800.0  2600.0  2700.0  3300.0  3400.0
+1000.0  1900.0  2600.0  2700.0  3300.0  3400.0
+1000.0  1800.0  2800.0  2900.0  3300.0  3400.0
+1400.0  1600.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1700.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1700.0  2500.0  2600.0  3000.0  3400.0
+1700.0  1800.0  2500.0  2600.0  3000.0  3400.0
+1700.0  1800.0  2400.0  2600.0  2800.0  3300.0
+1700.0  1800.0  2400.0  2600.0  2900.0  3400.0
+1700.0  1800.0  2500.0  2600.0  3200.0  3400.0
+1700.0  1800.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1800.0  2500.0  2600.0  3200.0  3400.0
+1600.0  1800.0  2600.0  2700.0  3200.0  3400.0
+1600.0  1900.0  2600.0  2700.0  3300.0  3400.0
+1600.0  2000.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2300.0  2800.0  3000.0  3300.0  3400.0
+1800.0  2100.0  2800.0  3100.0  3300.0  3400.0
+1900.0  2100.0  2700.0  2900.0  3300.0  3400.0
+1800.0  2000.0  2600.0  2800.0  3200.0  3400.0
+1700.0  1900.0  2500.0  2800.0  3100.0  3300.0
+1700.0  1800.0  2400.0  2600.0  3000.0  3300.0
+1700.0  1800.0  2500.0  2700.0  3000.0  3400.0
+1700.0  1900.0  2600.0  2700.0  3100.0  3400.0
+1600.0  1900.0  2600.0  2700.0  3000.0  3300.0
+1700.0  2000.0  2600.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1700.0  1900.0  2600.0  2800.0  3200.0  3300.0
+1600.0  1900.0  2600.0  2800.0  3200.0  3400.0
+1200.0  1800.0  2700.0  2800.0  3200.0  3400.0
+1100.0  1700.0  2700.0  2800.0  3200.0  3300.0
+1500.0  1800.0  2600.0  2700.0  3100.0  3400.0
+1500.0  1800.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1800.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1800.0  2400.0  2500.0  3100.0  3400.0
+1500.0  1700.0  2400.0  2500.0  3000.0  3400.0
+1400.0  1600.0  2400.0  2500.0  3000.0  3400.0
+1400.0  1600.0  2400.0  2600.0  2900.0  3300.0
+1200.0  1700.0  2600.0  2700.0  3100.0  3300.0
+1200.0  1800.0  2600.0  2700.0  3200.0  3400.0
+1100.0  1900.0  2600.0  2700.0  3200.0  3400.0
+1400.0  1800.0  2500.0  2700.0  3200.0  3400.0
+1700.0  1900.0  2500.0  2600.0  2900.0  3300.0
+1600.0  1700.0  2500.0  2700.0  3000.0  3400.0
+1400.0  1500.0  2500.0  2700.0  3200.0  3400.0
+1400.0  1700.0  2500.0  2700.0  3000.0  3300.0
+1800.0  2000.0  2200.0  2600.0  2900.0  3200.0
+1900.0  2100.0  2400.0  2600.0  3100.0  3300.0
+1900.0  2300.0  2400.0  2700.0  3200.0  3300.0
+1800.0  2200.0  2400.0  2700.0  3200.0  3300.0
+1600.0  1900.0  2200.0  2400.0  3000.0  3200.0
+1500.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1500.0  1900.0  2100.0  2400.0  3100.0  3200.0
+1400.0  1900.0  2100.0  2500.0  3200.0  3300.0
+1300.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1200.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1200.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1100.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1200.0  2200.0  2500.0  2600.0  3300.0  3400.0
+1500.0  1800.0  2400.0  2500.0  3300.0  3400.0
+1800.0  1900.0  2300.0  2400.0  3300.0  3400.0
+2100.0  2200.0  2400.0  2600.0  3300.0  3400.0
+2200.0  2300.0  2600.0  2700.0  3300.0  3400.0
+2200.0  2300.0  2600.0  2800.0  3300.0  3400.0
+2100.0  2300.0  2500.0  2800.0  3100.0  3300.0
+2200.0  2300.0  2600.0  2700.0  3100.0  3400.0
+2100.0  2200.0  2600.0  2700.0  3200.0  3400.0
+1900.0  2300.0  2600.0  2900.0  3100.0  3300.0
+2000.0  2300.0  2600.0  2900.0  3200.0  3300.0
+2200.0  2300.0  2700.0  2900.0  3300.0  3400.0
+2000.0  2300.0  2500.0  2900.0  3300.0  3400.0
+1500.0  1700.0  2200.0  2600.0  3100.0  3300.0
+1500.0  1700.0  2200.0  2600.0  3000.0  3300.0
+1500.0  1800.0  2200.0  2600.0  3100.0  3300.0
+1500.0  1800.0  2000.0  2300.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2300.0  3200.0  3300.0
+1600.0  1900.0  2100.0  2300.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2400.0  3300.0  3400.0
+1800.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1800.0  2000.0  2400.0  2500.0  3200.0  3400.0
+1800.0  2000.0  2400.0  2600.0  3100.0  3400.0
+1800.0  1900.0  2400.0  2600.0  3100.0  3400.0
+1400.0  1600.0  2500.0  2600.0  2900.0  3300.0
+1300.0  1500.0  2500.0  2600.0  2900.0  3300.0
+1300.0  1700.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1900.0  2400.0  2800.0  3100.0  3200.0
+1500.0  2000.0  2400.0  2800.0  3100.0  3300.0
+1100.0  1700.0  2600.0  2700.0  3200.0  3400.0
+1100.0  1800.0  2600.0  2700.0  3300.0  3400.0
+1100.0  1800.0  2700.0  2800.0  3300.0  3400.0
+1700.0  2000.0  2600.0  2700.0  3100.0  3400.0
+1700.0  2100.0  2500.0  2600.0  3000.0  3200.0
+1700.0  2200.0  2600.0  2700.0  3100.0  3200.0
+1700.0  2000.0  2500.0  2600.0  3000.0  3200.0
+1700.0  1900.0  2500.0  2600.0  3000.0  3300.0
+1700.0  1900.0  2400.0  2600.0  3000.0  3300.0
+2000.0  2200.0  2400.0  2600.0  3300.0  3400.0
+1800.0  2100.0  2400.0  2500.0  3300.0  3400.0
+1700.0  2100.0  2400.0  2500.0  3300.0  3400.0
+1500.0  2100.0  2400.0  2500.0  3300.0  3400.0
+1600.0  2100.0  2400.0  2500.0  3300.0  3400.0
+1700.0  2000.0  2300.0  2400.0  3300.0  3400.0
+1700.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1800.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1900.0  2000.0  2400.0  2500.0  3100.0  3400.0
+1900.0  2000.0  2400.0  2500.0  3000.0  3400.0
+1900.0  2000.0  2300.0  2400.0  2800.0  3300.0
+1800.0  2000.0  2200.0  2400.0  2600.0  3200.0
+1900.0  2000.0  2300.0  2500.0  2800.0  3200.0
+1700.0  2000.0  2300.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2800.0  3200.0  3300.0
+1700.0  2000.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2000.0  2600.0  2900.0  3300.0  3400.0
+1700.0  1800.0  2500.0  2700.0  3200.0  3400.0
+1600.0  1700.0  2400.0  2600.0  2900.0  3300.0
+1600.0  1700.0  2500.0  2600.0  2900.0  3300.0
+1600.0  1800.0  2600.0  2700.0  3100.0  3400.0
+1600.0  1700.0  2600.0  2700.0  3000.0  3300.0
+1600.0  1700.0  2600.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2800.0  3200.0  3400.0
+2100.0  2500.0  2700.0  3000.0  3300.0  3400.0
+2100.0  2400.0  2700.0  2900.0  3300.0  3400.0
+2200.0  2500.0  2700.0  3000.0  3300.0  3400.0
+2200.0  2500.0  2800.0  2900.0  3400.0  3500.0
+2200.0  2500.0  2800.0  2900.0  3300.0  3500.0
+2100.0  2500.0  2700.0  2800.0  3300.0  3400.0
+2100.0  2400.0  2700.0  2900.0  3200.0  3400.0
+2100.0  2300.0  2600.0  2800.0  3100.0  3400.0
+2100.0  2200.0  2500.0  2700.0  3100.0  3400.0
+2200.0  2300.0  2500.0  2700.0  3200.0  3400.0
+1900.0  2100.0  2400.0  2500.0  3200.0  3400.0
+1700.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1900.0  2400.0  2500.0  3100.0  3300.0
+1400.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1200.0  1900.0  2600.0  2700.0  3300.0  3400.0
+1100.0  2000.0  2600.0  2700.0  3300.0  3400.0
+1100.0  1700.0  2600.0  2700.0  3300.0  3400.0
+1300.0  1600.0  2500.0  2600.0  3100.0  3400.0
+1500.0  1600.0  2400.0  2500.0  3000.0  3400.0
+1600.0  1700.0  2400.0  2500.0  3100.0  3400.0
+1900.0  2000.0  2300.0  2500.0  2900.0  3400.0
+1900.0  2000.0  2400.0  2500.0  2800.0  3300.0
+1900.0  2000.0  2500.0  2700.0  3300.0  3400.0
+1900.0  2000.0  2500.0  2800.0  3300.0  3400.0
+2000.0  2200.0  2700.0  2900.0  3300.0  3400.0
+1900.0  2200.0  2700.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2700.0  2900.0  3200.0  3300.0
+2000.0  2300.0  2700.0  2900.0  3200.0  3300.0
+2200.0  2600.0  2700.0  2900.0  3300.0  3400.0
+2100.0  2400.0  2700.0  2800.0  3300.0  3400.0
+2100.0  2200.0  2500.0  2700.0  3300.0  3400.0
+1900.0  2100.0  2400.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1500.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1200.0  1900.0  2400.0  2500.0  3300.0  3500.0
+1200.0  1600.0  2400.0  2500.0  3200.0  3400.0
+1700.0  2100.0  2600.0  2900.0  3300.0  3400.0
+1800.0  2200.0  2700.0  3000.0  3300.0  3400.0
+1800.0  2200.0  2800.0  3000.0  3300.0  3400.0
+1700.0  2100.0  2600.0  2900.0  3200.0  3400.0
+1700.0  2000.0  2600.0  2800.0  3200.0  3400.0
+1600.0  1800.0  2500.0  2700.0  3200.0  3400.0
+1500.0  1700.0  2500.0  2600.0  3200.0  3400.0
+1500.0  1700.0  2400.0  2600.0  3200.0  3300.0
+1500.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1500.0  1800.0  2300.0  2500.0  3200.0  3400.0
+1400.0  1800.0  2300.0  2500.0  3300.0  3400.0
+1400.0  1800.0  2300.0  2400.0  3200.0  3400.0
+1600.0  1900.0  2500.0  2600.0  3200.0  3400.0
+1500.0  1900.0  2600.0  2700.0  3200.0  3400.0
+1500.0  1900.0  2600.0  2700.0  3300.0  3400.0
+1400.0  1900.0  2600.0  2700.0  3300.0  3400.0
+1400.0  1900.0  2600.0  2700.0  3200.0  3400.0
+1500.0  1700.0  2600.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2600.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2700.0  2900.0  3200.0  3300.0
+2000.0  2100.0  2500.0  2700.0  3200.0  3400.0
+2000.0  2100.0  2400.0  2600.0  3100.0  3400.0
+2000.0  2100.0  2300.0  2600.0  3000.0  3300.0
+1900.0  2000.0  2300.0  2500.0  3000.0  3400.0
+1800.0  1900.0  2300.0  2400.0  3000.0  3400.0
+1600.0  1800.0  2300.0  2400.0  3000.0  3400.0
+1400.0  1700.0  2400.0  2500.0  2900.0  3400.0
+1300.0  1700.0  2400.0  2500.0  3100.0  3400.0
+1400.0  1700.0  2300.0  2600.0  3100.0  3300.0
+1200.0  1600.0  2400.0  2500.0  3200.0  3300.0
+1200.0  1600.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1400.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2600.0  3100.0  3200.0
+1800.0  1900.0  2400.0  2600.0  3000.0  3300.0
+2000.0  2300.0  2700.0  2900.0  3300.0  3400.0
+1900.0  2300.0  2900.0  3100.0  3400.0  3500.0
+1900.0  2100.0  2700.0  3000.0  3300.0  3400.0
+1800.0  1900.0  2300.0  2700.0  3100.0  3300.0
+1800.0  1900.0  2200.0  2500.0  3100.0  3300.0
+1700.0  1800.0  2100.0  2400.0  3000.0  3300.0
+1700.0  1800.0  2200.0  2400.0  3100.0  3300.0
+1400.0  1900.0  2100.0  2300.0  3200.0  3300.0
+1300.0  1800.0  2000.0  2300.0  3200.0  3300.0
+1300.0  1800.0  1900.0  2500.0  3200.0  3300.0
+1300.0  1900.0  2100.0  2600.0  3200.0  3300.0
+2000.0  2100.0  2400.0  2500.0  3100.0  3400.0
+2100.0  2200.0  2400.0  2500.0  3100.0  3400.0
+2100.0  2400.0  2800.0  2900.0  3100.0  3300.0
+2000.0  2200.0  2600.0  2900.0  3200.0  3300.0
+2100.0  2200.0  2700.0  2800.0  3200.0  3300.0
+2000.0  2100.0  2700.0  2800.0  3200.0  3300.0
+2000.0  2100.0  2600.0  2800.0  3200.0  3400.0
+1900.0  2000.0  2600.0  2700.0  3300.0  3400.0
+1800.0  1900.0  2500.0  2700.0  3300.0  3400.0
+2000.0  2100.0  2600.0  2700.0  3200.0  3300.0
+2000.0  2100.0  2600.0  2700.0  3100.0  3400.0
+1900.0  2100.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2000.0  2600.0  2700.0  3300.0  3400.0
+1800.0  2000.0  2600.0  2700.0  3300.0  3500.0
+1700.0  1900.0  2500.0  2700.0  3200.0  3400.0
+1800.0  2100.0  2700.0  2900.0  3200.0  3400.0
+1900.0  2200.0  2600.0  2900.0  3200.0  3300.0
+1900.0  2200.0  2700.0  2900.0  3200.0  3400.0
+1800.0  2200.0  2700.0  3000.0  3200.0  3400.0
+1800.0  2100.0  2700.0  2900.0  3300.0  3400.0
+1900.0  2200.0  2600.0  2900.0  3300.0  3500.0
+1700.0  2100.0  2500.0  2800.0  3400.0  3500.0
+1600.0  1900.0  2400.0  2600.0  3200.0  3400.0
+1600.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1700.0  2000.0  2400.0  2500.0  3200.0  3400.0
+1700.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1700.0  2000.0  2300.0  2400.0  2900.0  3200.0
+1900.0  2000.0  2600.0  2700.0  3100.0  3200.0
+1900.0  2000.0  2600.0  2700.0  3100.0  3400.0
+1800.0  2000.0  2600.0  2700.0  3100.0  3300.0
+1400.0  1800.0  2300.0  2600.0  3000.0  3200.0
+1300.0  1800.0  2200.0  2500.0  3100.0  3300.0
+1300.0  1900.0  2200.0  2600.0  3100.0  3300.0
+1400.0  1800.0  2100.0  2500.0  3000.0  3200.0
+1300.0  1600.0  1700.0  2500.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2400.0  3100.0  3200.0
+1300.0  1600.0  1800.0  2300.0  3100.0  3200.0
+1500.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1500.0  1900.0  2500.0  2600.0  3000.0  3200.0
+1800.0  2200.0  2600.0  2800.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2400.0  2700.0  3100.0  3300.0
+1800.0  1900.0  2500.0  2700.0  3100.0  3300.0
+1800.0  1900.0  2600.0  2700.0  3000.0  3300.0
+2100.0  2200.0  2600.0  2700.0  3200.0  3300.0
+2100.0  2200.0  2600.0  2700.0  3300.0  3400.0
+1900.0  2100.0  2300.0  2500.0  3300.0  3400.0
+1700.0  2100.0  2500.0  2800.0  3100.0  3300.0
+1600.0  2100.0  2500.0  2700.0  3100.0  3300.0
+1500.0  1900.0  2400.0  2700.0  3100.0  3300.0
+1200.0  1700.0  1800.0  2100.0  3200.0  3400.0
+1400.0  1700.0  1800.0  2200.0  3300.0  3400.0
+1600.0  1800.0  1900.0  2400.0  3200.0  3300.0
+1700.0  1900.0  2000.0  2500.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2400.0  2900.0  3100.0
+1800.0  2000.0  2200.0  2400.0  2800.0  3200.0
+1900.0  2100.0  2300.0  2600.0  2900.0  3300.0
+1900.0  2100.0  2300.0  2600.0  3200.0  3400.0
+2000.0  2100.0  2400.0  2500.0  3300.0  3400.0
+1800.0  1900.0  2400.0  2500.0  3200.0  3500.0
+1700.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1800.0  2000.0  2600.0  3000.0  3300.0  3400.0
+1900.0  2000.0  2500.0  2700.0  2900.0  3200.0
+1900.0  2000.0  2500.0  2700.0  2900.0  3100.0
+1900.0  2000.0  2400.0  2600.0  2900.0  3200.0
+1700.0  2000.0  2300.0  2600.0  2900.0  3200.0
+1800.0  2000.0  2300.0  2600.0  2900.0  3200.0
+1900.0  2000.0  2400.0  2600.0  2900.0  3300.0
+1900.0  2000.0  2400.0  2600.0  3000.0  3300.0
+1900.0  2000.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1800.0  2200.0  2600.0  3000.0  3300.0
+1600.0  1800.0  2200.0  2500.0  3000.0  3300.0
+1700.0  1900.0  2300.0  2600.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2600.0  3000.0  3200.0
+1800.0  1900.0  2400.0  2500.0  3000.0  3400.0
+1700.0  1800.0  2400.0  2500.0  3200.0  3400.0
+1600.0  1700.0  2400.0  2600.0  3100.0  3300.0
+1600.0  1700.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1600.0  2400.0  2500.0  3200.0  3400.0
+1400.0  1600.0  2400.0  2500.0  3200.0  3400.0
+1300.0  1600.0  2400.0  2500.0  3200.0  3300.0
+1400.0  2000.0  2500.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2200.0  2500.0  3000.0  3300.0
+1700.0  1900.0  2300.0  2500.0  3100.0  3300.0
+2000.0  2100.0  2400.0  2600.0  3100.0  3300.0
+2000.0  2200.0  2500.0  2600.0  3100.0  3300.0
+1900.0  2000.0  2400.0  2500.0  3200.0  3400.0
+2100.0  2200.0  2300.0  2400.0  3200.0  3400.0
+2000.0  2100.0  2300.0  2500.0  3000.0  3400.0
+1600.0  1800.0  2100.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2200.0  2700.0  3200.0  3300.0
+1800.0  1900.0  2400.0  2800.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2800.0  3200.0  3400.0
+1700.0  2100.0  2600.0  2900.0  3300.0  3500.0
+1800.0  2200.0  2600.0  2900.0  3300.0  3500.0
+1700.0  2200.0  2600.0  2900.0  3300.0  3400.0
+1700.0  2100.0  2500.0  2800.0  3200.0  3400.0
+1700.0  1900.0  2600.0  2700.0  3300.0  3400.0
+1700.0  1800.0  2600.0  2700.0  3100.0  3400.0
+1700.0  1800.0  2600.0  2700.0  3200.0  3400.0
+1700.0  1900.0  2700.0  2800.0  3200.0  3400.0
+1600.0  1900.0  2700.0  2800.0  3200.0  3300.0
+1400.0  1900.0  2800.0  2900.0  3200.0  3300.0
+1600.0  2000.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2600.0  2700.0  3200.0  3400.0
+1700.0  2000.0  2600.0  2700.0  3300.0  3400.0
+1700.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1700.0  1800.0  2500.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2000.0  2400.0  2800.0  3300.0  3400.0
+1600.0  1800.0  2100.0  2400.0  3100.0  3200.0
+1700.0  1800.0  2000.0  2700.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2700.0  3100.0  3200.0
+1800.0  2000.0  2200.0  2700.0  3100.0  3200.0
+1900.0  2000.0  2300.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2300.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2400.0  2700.0  3100.0  3200.0
+2000.0  2100.0  2400.0  2700.0  3100.0  3200.0
+2000.0  2200.0  2400.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1800.0  2100.0  2200.0  2600.0  3100.0  3200.0
+1600.0  2000.0  2200.0  2600.0  3100.0  3200.0
+1500.0  2000.0  2200.0  2700.0  3100.0  3200.0
+1500.0  1900.0  2200.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2200.0  2600.0  3100.0  3200.0
+1800.0  2100.0  2600.0  2700.0  3100.0  3300.0
+1700.0  2100.0  2600.0  2700.0  3100.0  3300.0
+1500.0  1800.0  2600.0  2700.0  3200.0  3400.0
+1200.0  1400.0  2500.0  2700.0  3200.0  3400.0
+1400.0  1700.0  2400.0  2600.0  3200.0  3400.0
+1400.0  1600.0  2400.0  2600.0  3100.0  3400.0
+1500.0  1700.0  2500.0  2600.0  3000.0  3300.0
+1600.0  1800.0  2500.0  2600.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2400.0  2600.0  3000.0  3400.0
+2000.0  2100.0  2500.0  2600.0  3000.0  3300.0
+2100.0  2200.0  2500.0  2600.0  3100.0  3400.0
+2200.0  2300.0  2500.0  2600.0  3100.0  3400.0
+1400.0  1900.0  2300.0  2400.0  2800.0  3200.0
+1400.0  1900.0  2300.0  2400.0  2700.0  3100.0
+1500.0  1700.0  2300.0  2400.0  2800.0  3200.0
+1600.0  1700.0  2100.0  2500.0  3000.0  3300.0
+1700.0  2000.0  2400.0  2800.0  3000.0  3300.0
+1800.0  2000.0  2600.0  2800.0  3100.0  3300.0
+1800.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1800.0  2000.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2000.0  2600.0  2700.0  3200.0  3300.0
+1800.0  2200.0  2600.0  2800.0  3200.0  3300.0
+1800.0  2100.0  2600.0  2800.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2700.0  3000.0  3300.0
+1800.0  1900.0  2500.0  2700.0  3000.0  3300.0
+1900.0  2000.0  2500.0  2700.0  3100.0  3300.0
+1900.0  2000.0  2500.0  2700.0  3100.0  3400.0
+1700.0  1900.0  2600.0  2800.0  3200.0  3400.0
+1600.0  1900.0  2600.0  2800.0  3300.0  3400.0
+1500.0  1800.0  2500.0  2700.0  3300.0  3400.0
+1500.0  1900.0  2400.0  2500.0  3200.0  3400.0
+1200.0  1800.0  2200.0  2300.0  3100.0  3200.0
+1400.0  1900.0  2300.0  2600.0  3000.0  3300.0
+1300.0  1400.0  2300.0  2400.0  2800.0  3100.0
+1300.0  1400.0  2300.0  2500.0  3000.0  3200.0
+1300.0  1600.0  2400.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2400.0  2500.0  2900.0  3200.0
+1500.0  1600.0  2400.0  2600.0  3000.0  3200.0
+1500.0  1700.0  2400.0  2600.0  2900.0  3200.0
+1600.0  1800.0  2400.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2500.0  2700.0  3000.0  3300.0
+1900.0  2100.0  2600.0  2700.0  3000.0  3300.0
+1900.0  2100.0  2500.0  2700.0  3000.0  3200.0
+2000.0  2100.0  2400.0  2700.0  3100.0  3300.0
+2000.0  2200.0  2400.0  2700.0  3100.0  3300.0
+1900.0  2300.0  2600.0  2700.0  3000.0  3200.0
+2000.0  2200.0  2500.0  2600.0  3000.0  3200.0
+1900.0  2000.0  2500.0  2600.0  3000.0  3300.0
+1800.0  2000.0  2400.0  2600.0  3000.0  3300.0
+1500.0  1900.0  2300.0  2500.0  2700.0  3000.0
+1500.0  2000.0  2400.0  2500.0  2700.0  3100.0
+1200.0  1900.0  2300.0  2500.0  2800.0  3000.0
+1300.0  1800.0  2200.0  2300.0  3100.0  3200.0
+1600.0  1900.0  2400.0  2500.0  3100.0  3200.0
+2100.0  2200.0  2600.0  2700.0  3100.0  3300.0
+2100.0  2200.0  2600.0  2700.0  3000.0  3300.0
+2000.0  2200.0  2600.0  2700.0  3100.0  3300.0
+2000.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2300.0  2400.0  3100.0  3300.0
+1500.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1600.0  1900.0  2400.0  2600.0  3100.0  3300.0
+1500.0  1800.0  2200.0  2600.0  3000.0  3200.0
+1500.0  1800.0  2100.0  2600.0  2900.0  3100.0
+1400.0  1700.0  1900.0  2300.0  2800.0  3000.0
+1500.0  1700.0  1900.0  2200.0  2800.0  2900.0
+1500.0  1700.0  2000.0  2200.0  2900.0  3000.0
+1500.0  1700.0  2100.0  2300.0  2900.0  3000.0
+1500.0  1800.0  2200.0  2300.0  3000.0  3100.0
+1500.0  1800.0  2200.0  2400.0  3000.0  3100.0
+1600.0  1800.0  2300.0  2400.0  3100.0  3200.0
+1600.0  1800.0  2300.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2400.0  2500.0  3100.0  3300.0
+1600.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1700.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1700.0  2300.0  2500.0  2900.0  3300.0
+1800.0  2100.0  2500.0  2600.0  3200.0  3300.0
+1900.0  2100.0  2400.0  2500.0  3100.0  3400.0
+1900.0  2100.0  2200.0  2500.0  3100.0  3300.0
+1700.0  1800.0  2200.0  2500.0  2900.0  3300.0
+1700.0  1800.0  2400.0  2500.0  3000.0  3300.0
+1600.0  1700.0  2400.0  2500.0  3100.0  3300.0
+1500.0  1700.0  2400.0  2500.0  3100.0  3300.0
+1400.0  1700.0  2500.0  2600.0  3100.0  3200.0
+1300.0  1600.0  2500.0  2600.0  3100.0  3200.0
+1200.0  1600.0  2500.0  2600.0  3100.0  3200.0
+1100.0  1700.0  2600.0  2700.0  3100.0  3200.0
+1100.0  1500.0  2600.0  2700.0  3100.0  3200.0
+1100.0  1500.0  2600.0  2700.0  3100.0  3300.0
+1100.0  1500.0  2500.0  2700.0  3000.0  3300.0
+1000.0  1600.0  2600.0  2700.0  3100.0  3300.0
+1300.0  1600.0  2600.0  2700.0  3100.0  3300.0
+1300.0  1600.0  2600.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2500.0  2600.0  3100.0  3300.0
+1700.0  1800.0  2500.0  2600.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1800.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2500.0  2700.0  3100.0  3400.0
+1800.0  2100.0  2500.0  2700.0  3100.0  3300.0
+1900.0  2200.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2200.0  2400.0  2600.0  3100.0  3300.0
+1900.0  2300.0  2500.0  2600.0  3100.0  3300.0
+1900.0  2000.0  2200.0  2400.0  3200.0  3300.0
+1600.0  1900.0  2200.0  2300.0  3200.0  3300.0
+1400.0  1600.0  2200.0  2400.0  3100.0  3200.0
+1100.0  1500.0  2300.0  2500.0  3000.0  3100.0
+1400.0  1700.0  2500.0  2700.0  3200.0  3300.0
+1500.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1800.0  2100.0  2500.0  2800.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2500.0  3200.0  3400.0
+1700.0  1900.0  2300.0  2500.0  3200.0  3400.0
+1800.0  2100.0  2500.0  2800.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2800.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2800.0  3100.0  3400.0
+1700.0  2100.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2100.0  2600.0  2700.0  3300.0  3500.0
+1900.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1600.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1400.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2400.0  3000.0  3100.0
+1300.0  1700.0  2300.0  2500.0  3000.0  3100.0
+1600.0  1700.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2300.0  2400.0  3100.0  3300.0
+2200.0  2300.0  2600.0  2800.0  3200.0  3400.0
+2100.0  2300.0  2500.0  2900.0  3200.0  3300.0
+2200.0  2300.0  2500.0  2900.0  3200.0  3300.0
+2000.0  2300.0  2500.0  2700.0  3200.0  3300.0
+2200.0  2400.0  2500.0  2700.0  3200.0  3300.0
+2200.0  2400.0  2600.0  2800.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2700.0  3000.0  3200.0
+1700.0  1900.0  2500.0  2700.0  3000.0  3200.0
+1700.0  1900.0  2600.0  2700.0  3100.0  3300.0
+1500.0  1800.0  2600.0  2700.0  3100.0  3300.0
+1600.0  1700.0  2600.0  2700.0  2900.0  3300.0
+1600.0  1700.0  2600.0  2800.0  3000.0  3300.0
+1700.0  2000.0  2700.0  2800.0  3100.0  3400.0
+1600.0  1900.0  2500.0  2700.0  3000.0  3300.0
+1800.0  2200.0  2800.0  2900.0  3300.0  3400.0
+2000.0  2500.0  2800.0  2900.0  3400.0  3500.0
+2000.0  2400.0  2800.0  2900.0  3400.0  3500.0
+2000.0  2300.0  2700.0  2800.0  3200.0  3400.0
+1600.0  1700.0  2400.0  2600.0  3200.0  3300.0
+1500.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1400.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1400.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1700.0  2500.0  2600.0  3100.0  3300.0
+1300.0  1500.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1400.0  2400.0  2500.0  3100.0  3300.0
+1200.0  1500.0  2400.0  2500.0  3100.0  3300.0
+1200.0  1600.0  2400.0  2500.0  3100.0  3300.0
+1200.0  1700.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1700.0  2500.0  2600.0  3200.0  3300.0
+1200.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1200.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1200.0  1800.0  2400.0  2500.0  3100.0  3300.0
+1200.0  1700.0  2400.0  2500.0  3100.0  3200.0
+1200.0  1600.0  2400.0  2500.0  3000.0  3200.0
+1200.0  1600.0  2400.0  2500.0  2900.0  3100.0
+1200.0  1700.0  2400.0  2500.0  3000.0  3300.0
+1300.0  1700.0  2400.0  2500.0  3100.0  3300.0
+1200.0  1700.0  2400.0  2500.0  3000.0  3100.0
+1200.0  1700.0  2300.0  2400.0  3000.0  3100.0
+1600.0  2000.0  2300.0  2600.0  3000.0  3300.0
+1400.0  1600.0  1900.0  2200.0  3000.0  3100.0
+1400.0  1600.0  1800.0  2100.0  3000.0  3100.0
+1300.0  1500.0  1600.0  2000.0  3100.0  3200.0
+1300.0  1500.0  1700.0  1900.0  3100.0  3200.0
+1400.0  1600.0  1700.0  1900.0  3100.0  3200.0
+1600.0  1700.0  2000.0  2100.0  3100.0  3200.0
+1600.0  1800.0  2100.0  2200.0  3100.0  3200.0
+1800.0  1900.0  2300.0  2400.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2700.0  3100.0  3400.0
+1900.0  2000.0  2500.0  2600.0  3000.0  3400.0
+1800.0  2100.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2300.0  2600.0  2800.0  3300.0  3500.0
+1600.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2500.0  2600.0  3100.0  3300.0
+1300.0  1800.0  2500.0  2600.0  3100.0  3300.0
+1400.0  1800.0  2600.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2500.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1900.0  2000.0  2500.0  2700.0  2900.0  3300.0
+2000.0  2100.0  2400.0  2600.0  2900.0  3200.0
+2000.0  2100.0  2400.0  2600.0  3000.0  3300.0
+2100.0  2200.0  2400.0  2600.0  3000.0  3300.0
+2000.0  2100.0  2500.0  2600.0  3100.0  3400.0
+1900.0  2000.0  2400.0  2600.0  3000.0  3400.0
+1800.0  1900.0  2300.0  2500.0  2900.0  3400.0
+1700.0  1800.0  2500.0  2700.0  3100.0  3400.0
+1700.0  1900.0  2500.0  2700.0  3100.0  3400.0
+1800.0  1900.0  2700.0  2800.0  3200.0  3400.0
+2100.0  2200.0  2600.0  2800.0  3100.0  3400.0
+2200.0  2300.0  2600.0  2800.0  3100.0  3400.0
+1800.0  2300.0  2500.0  2700.0  3100.0  3300.0
+1500.0  2000.0  2400.0  2500.0  2800.0  3100.0
+1600.0  2000.0  2400.0  2500.0  2800.0  3100.0
+1600.0  2000.0  2400.0  2500.0  2800.0  3200.0
+1600.0  2000.0  2400.0  2500.0  2900.0  3300.0
+1800.0  2200.0  2500.0  2600.0  3000.0  3300.0
+2100.0  2300.0  2500.0  2600.0  3100.0  3300.0
+2100.0  2200.0  2600.0  2700.0  3100.0  3200.0
+1800.0  1900.0  2600.0  2700.0  3100.0  3200.0
+1800.0  1900.0  2600.0  2700.0  3100.0  3300.0
+1700.0  1800.0  2600.0  2700.0  3100.0  3300.0
+1700.0  1800.0  2600.0  2700.0  3200.0  3300.0
+1600.0  1700.0  2600.0  2700.0  3200.0  3400.0
+1600.0  1700.0  2500.0  2700.0  3200.0  3300.0
+1500.0  1800.0  2400.0  2500.0  3000.0  3300.0
+1500.0  1900.0  2300.0  2500.0  3000.0  3200.0
+1700.0  2100.0  2300.0  2600.0  3100.0  3300.0
+1800.0  2000.0  2700.0  2800.0  3100.0  3300.0
+1700.0  1800.0  2500.0  2700.0  2900.0  3300.0
+1600.0  1800.0  2500.0  2700.0  3000.0  3300.0
+1700.0  1800.0  2400.0  2600.0  3100.0  3300.0
+1700.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1800.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2500.0  3200.0  3300.0
+2000.0  2100.0  2300.0  2500.0  3200.0  3400.0
+2000.0  2100.0  2200.0  2400.0  3200.0  3400.0
+2000.0  2100.0  2300.0  2400.0  3100.0  3400.0
+1700.0  1900.0  2400.0  2500.0  3200.0  3400.0
+1700.0  1900.0  2400.0  2500.0  3100.0  3400.0
+1700.0  1800.0  2400.0  2600.0  3300.0  3400.0
+1700.0  1800.0  2500.0  2600.0  3300.0  3400.0
+1600.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1700.0  1900.0  2600.0  2800.0  3100.0  3300.0
+1700.0  2100.0  2600.0  2700.0  3300.0  3400.0
+1800.0  2000.0  2400.0  2500.0  3100.0  3300.0
+2000.0  2100.0  2300.0  2400.0  3200.0  3400.0
+1400.0  1900.0  2300.0  2400.0  3000.0  3300.0
+1400.0  2000.0  2300.0  2500.0  3000.0  3100.0
+1400.0  1700.0  2500.0  2600.0  3100.0  3300.0
+1300.0  1600.0  2400.0  2600.0  3100.0  3300.0
+1300.0  1600.0  2400.0  2500.0  3200.0  3400.0
+1500.0  2000.0  2500.0  2700.0  3200.0  3400.0
+1800.0  2100.0  2500.0  2900.0  3200.0  3400.0
+1800.0  2200.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2000.0  2500.0  2900.0  3300.0  3400.0
+1700.0  2100.0  2600.0  2900.0  3400.0  3500.0
+1500.0  1900.0  2400.0  2800.0  3300.0  3400.0
+1800.0  2100.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2000.0  2600.0  2800.0  3300.0  3400.0
+1700.0  2100.0  2600.0  2800.0  3200.0  3400.0
+1900.0  2200.0  2600.0  2800.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2800.0  3200.0  3300.0
+1800.0  2100.0  2700.0  2800.0  3300.0  3400.0
+1700.0  2100.0  2700.0  2800.0  3200.0  3400.0
+1800.0  2200.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2200.0  2600.0  2700.0  3300.0  3400.0
+1800.0  2300.0  2600.0  2700.0  3300.0  3400.0
+1900.0  2300.0  2500.0  2700.0  3300.0  3400.0
+1800.0  2200.0  2500.0  2800.0  3200.0  3400.0
+1800.0  2200.0  2500.0  2700.0  3100.0  3300.0
+1700.0  2200.0  2400.0  2600.0  3100.0  3200.0
+1800.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1800.0  2000.0  2200.0  2500.0  3300.0  3400.0
+1800.0  2000.0  2200.0  2600.0  3300.0  3400.0
+1500.0  1800.0  1900.0  2400.0  3200.0  3300.0
+1500.0  1700.0  1900.0  2500.0  3200.0  3300.0
+1500.0  1800.0  1900.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2400.0  3300.0  3400.0
+1500.0  1700.0  2200.0  2600.0  3000.0  3200.0
+1400.0  1700.0  2000.0  2600.0  3000.0  3200.0
+1500.0  1900.0  2400.0  2600.0  3100.0  3200.0
+1400.0  1900.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1600.0  2500.0  2700.0  3100.0  3300.0
+1200.0  1800.0  2500.0  2600.0  3100.0  3200.0
+1400.0  1800.0  2300.0  2400.0  3100.0  3200.0
+1400.0  1700.0  2200.0  2300.0  3200.0  3300.0
+1800.0  1900.0  2200.0  2300.0  3300.0  3400.0
+1800.0  2100.0  2300.0  2400.0  2900.0  3200.0
+1900.0  2100.0  2300.0  2500.0  3000.0  3300.0
+1900.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1600.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1700.0  2300.0  2400.0  3200.0  3300.0
+1500.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1600.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2200.0  2500.0  2700.0  3300.0  3400.0
+1800.0  2300.0  2500.0  2700.0  3300.0  3400.0
+1800.0  2400.0  2500.0  2900.0  3300.0  3400.0
+1900.0  2400.0  2600.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2700.0  3000.0  3400.0  3500.0
+1800.0  2100.0  2500.0  2900.0  3200.0  3300.0
+1700.0  2100.0  2500.0  2900.0  3200.0  3400.0
+1800.0  2100.0  2600.0  2800.0  3100.0  3400.0
+1800.0  2200.0  2700.0  2800.0  3200.0  3400.0
+1800.0  2300.0  2700.0  2900.0  3300.0  3500.0
+1400.0  2000.0  2600.0  2700.0  3200.0  3400.0
+1300.0  1800.0  2200.0  2300.0  3000.0  3100.0
+1300.0  1700.0  2100.0  2200.0  3100.0  3200.0
+1400.0  1700.0  2000.0  2200.0  3000.0  3100.0
+1400.0  1600.0  2000.0  2100.0  3000.0  3100.0
+1500.0  1800.0  2000.0  2300.0  3100.0  3200.0
+1600.0  1800.0  2000.0  2300.0  3100.0  3200.0
+1600.0  1800.0  2000.0  2200.0  3100.0  3200.0
+1700.0  2000.0  2200.0  2300.0  3000.0  3200.0
+1700.0  2100.0  2400.0  2800.0  3100.0  3300.0
+1800.0  2000.0  2600.0  2800.0  3000.0  3200.0
+1700.0  1900.0  2600.0  2700.0  3200.0  3400.0
+1600.0  1700.0  2400.0  2600.0  3200.0  3400.0
+1600.0  1700.0  2400.0  2500.0  3200.0  3400.0
+1700.0  2100.0  2500.0  2800.0  3200.0  3300.0
+1700.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1700.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2200.0  2500.0  3100.0  3300.0
+1500.0  1900.0  2100.0  2400.0  3100.0  3300.0
+1500.0  1600.0  2000.0  2300.0  3000.0  3200.0
+1500.0  1700.0  2100.0  2500.0  3100.0  3300.0
+1600.0  1800.0  2300.0  2700.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2600.0  3100.0  3200.0
+1500.0  1700.0  2300.0  2500.0  3000.0  3200.0
+1400.0  1700.0  2400.0  2500.0  3000.0  3200.0
+1200.0  1500.0  2500.0  2600.0  3000.0  3100.0
+1100.0  1900.0  2600.0  2700.0  3000.0  3100.0
+1500.0  2000.0  2700.0  2800.0  3200.0  3400.0
+1700.0  2100.0  2700.0  2800.0  3300.0  3400.0
+1800.0  2200.0  2700.0  2800.0  3300.0  3400.0
+1800.0  2400.0  2700.0  2800.0  3200.0  3300.0
+1800.0  2300.0  2500.0  2600.0  3100.0  3200.0
+1500.0  1800.0  2100.0  2400.0  3000.0  3200.0
+1400.0  1600.0  1800.0  2200.0  3000.0  3100.0
+1300.0  1600.0  1700.0  2100.0  3000.0  3100.0
+1200.0  1400.0  1600.0  2400.0  3000.0  3100.0
+1300.0  1500.0  1600.0  2100.0  3000.0  3100.0
+1400.0  1600.0  1700.0  2100.0  3000.0  3100.0
+1400.0  1700.0  2100.0  2300.0  3100.0  3200.0
+1400.0  1700.0  2200.0  2300.0  3100.0  3200.0
+1400.0  1600.0  2200.0  2300.0  3100.0  3200.0
+1400.0  1700.0  2200.0  2400.0  3100.0  3200.0
+1400.0  1700.0  2300.0  2400.0  3100.0  3200.0
+1400.0  1600.0  2300.0  2400.0  3100.0  3200.0
+1400.0  1600.0  2200.0  2300.0  3000.0  3200.0
+1500.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1700.0  2000.0  2700.0  2800.0  3200.0  3400.0
+2100.0  2400.0  2800.0  2900.0  3200.0  3400.0
+2000.0  2500.0  2700.0  2800.0  3400.0  3500.0
+2100.0  2600.0  2800.0  2900.0  3400.0  3500.0
+2000.0  2500.0  2700.0  2800.0  3300.0  3400.0
+1900.0  2100.0  2700.0  2800.0  3200.0  3400.0
+2100.0  2200.0  2700.0  2800.0  3200.0  3400.0
+2100.0  2200.0  2700.0  2900.0  3300.0  3400.0
+2200.0  2300.0  2700.0  2800.0  3200.0  3400.0
+1700.0  2100.0  2400.0  2700.0  3200.0  3400.0
+1600.0  2100.0  2400.0  2600.0  2900.0  3200.0
+1500.0  2100.0  2400.0  2500.0  2800.0  3100.0
+1600.0  2100.0  2400.0  2500.0  2800.0  3200.0
+1600.0  2100.0  2400.0  2500.0  2900.0  3200.0
+1600.0  2100.0  2400.0  2500.0  3000.0  3200.0
+1600.0  2100.0  2300.0  2500.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2600.0  3100.0  3300.0
+1700.0  1900.0  2300.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2500.0  3100.0  3300.0
+1800.0  1900.0  2400.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2200.0  2500.0  3100.0  3300.0
+1500.0  1700.0  1900.0  2200.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2100.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2300.0  3200.0  3300.0
+1500.0  1700.0  1900.0  2400.0  3200.0  3300.0
+1500.0  1700.0  1800.0  2400.0  3200.0  3300.0
+1500.0  1700.0  1900.0  2200.0  3200.0  3300.0
+1500.0  1700.0  1900.0  2100.0  3200.0  3300.0
+1500.0  1600.0  1900.0  2000.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2100.0  3200.0  3300.0
+1600.0  1700.0  2000.0  2100.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2300.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2500.0  3100.0  3200.0
+1700.0  2000.0  2400.0  2600.0  3000.0  3100.0
+1700.0  2100.0  2400.0  2600.0  3000.0  3100.0
+1600.0  2000.0  2400.0  2600.0  2900.0  3100.0
+1800.0  2200.0  2600.0  2800.0  3000.0  3200.0
+2000.0  2400.0  2500.0  2800.0  3100.0  3200.0
+2100.0  2500.0  2600.0  2800.0  3200.0  3300.0
+2200.0  2500.0  2700.0  3000.0  3200.0  3300.0
+2100.0  2500.0  2700.0  3000.0  3200.0  3300.0
+2200.0  2500.0  2600.0  3000.0  3200.0  3300.0
+2200.0  2500.0  2600.0  2900.0  3200.0  3300.0
+2200.0  2400.0  2600.0  2800.0  3100.0  3300.0
+2000.0  2300.0  2500.0  2700.0  3100.0  3200.0
+2000.0  2200.0  2500.0  2700.0  3100.0  3200.0
+2000.0  2300.0  2500.0  2800.0  3100.0  3200.0
+2000.0  2300.0  2400.0  2800.0  3100.0  3200.0
+2100.0  2200.0  2500.0  2800.0  3100.0  3200.0
+2000.0  2100.0  2500.0  2800.0  3200.0  3300.0
+1900.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2400.0  3100.0  3300.0
+1500.0  1600.0  1800.0  2100.0  3200.0  3300.0
+1500.0  1700.0  1800.0  2100.0  3200.0  3300.0
+1500.0  1700.0  1800.0  2300.0  3200.0  3300.0
+2000.0  2200.0  2400.0  2600.0  3000.0  3200.0
+2000.0  2400.0  2600.0  2800.0  3100.0  3300.0
+2000.0  2400.0  2500.0  2700.0  3100.0  3300.0
+1800.0  2200.0  2500.0  2600.0  3100.0  3300.0
+1600.0  1800.0  2400.0  2500.0  3000.0  3200.0
+1500.0  1800.0  2400.0  2500.0  3000.0  3100.0
+1800.0  2000.0  2200.0  2700.0  3000.0  3300.0
+1600.0  1900.0  2100.0  2600.0  3000.0  3200.0
+1500.0  1700.0  1900.0  2300.0  3000.0  3100.0
+1500.0  1700.0  1900.0  2200.0  3000.0  3100.0
+1600.0  1700.0  2200.0  2400.0  2900.0  3000.0
+1600.0  1800.0  2200.0  2400.0  2900.0  3000.0
+1800.0  2300.0  2600.0  2700.0  3200.0  3400.0
+1800.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1800.0  1900.0  2400.0  2600.0  3300.0  3400.0
+1700.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1600.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2400.0  2600.0  3100.0  3200.0
+2000.0  2100.0  2500.0  2600.0  3200.0  3300.0
+2100.0  2200.0  2400.0  2600.0  3200.0  3400.0
+1700.0  2000.0  2400.0  2600.0  3100.0  3400.0
+1700.0  1800.0  2400.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1600.0  1900.0  2200.0  2500.0  3000.0  3100.0
+1500.0  1800.0  2000.0  2300.0  3000.0  3100.0
+1500.0  1700.0  1900.0  2100.0  2900.0  3000.0
+1400.0  1600.0  2400.0  2700.0  2900.0  3100.0
+1400.0  1600.0  2300.0  2600.0  3000.0  3100.0
+1500.0  1600.0  2300.0  2500.0  2900.0  3100.0
+1600.0  1700.0  2400.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2400.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2400.0  2600.0  3100.0  3200.0
+1700.0  2100.0  2400.0  2600.0  3100.0  3200.0
+1600.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2200.0  2300.0  3100.0  3300.0
+1400.0  1600.0  2200.0  2300.0  3200.0  3300.0
+1300.0  1800.0  2300.0  2500.0  3300.0  3400.0
+1200.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1200.0  1700.0  2400.0  2500.0  3300.0  3400.0
+1500.0  1700.0  2300.0  2500.0  3100.0  3200.0
+1900.0  2000.0  2300.0  2400.0  3200.0  3300.0
+2200.0  2300.0  2500.0  2700.0  3200.0  3300.0
+2100.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1300.0  1900.0  2300.0  2400.0  3100.0  3300.0
+1800.0  2000.0  2400.0  2700.0  3200.0  3300.0
+1500.0  2000.0  2300.0  2400.0  3000.0  3300.0
+1600.0  2000.0  2400.0  2700.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2600.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2600.0  3000.0  3300.0
+1800.0  2100.0  2400.0  2500.0  3100.0  3300.0
+1700.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1600.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1500.0  1800.0  2200.0  2300.0  3200.0  3400.0
+1400.0  1600.0  2200.0  2300.0  3200.0  3400.0
+1300.0  1500.0  2200.0  2300.0  3200.0  3300.0
+1200.0  1600.0  2300.0  2400.0  3300.0  3400.0
+1200.0  1500.0  2300.0  2400.0  3200.0  3400.0
+1200.0  1400.0  2300.0  2400.0  3100.0  3400.0
+1300.0  1500.0  2400.0  2500.0  3200.0  3400.0
+1700.0  2300.0  2600.0  2700.0  3300.0  3400.0
+1800.0  2400.0  2700.0  3000.0  3300.0  3400.0
+1800.0  2300.0  2700.0  2800.0  3200.0  3300.0
+1800.0  2200.0  2500.0  2600.0  3300.0  3400.0
+1700.0  1900.0  2400.0  2600.0  3200.0  3400.0
+1700.0  1800.0  2200.0  2500.0  3200.0  3400.0
+1500.0  1700.0  2300.0  2500.0  3100.0  3300.0
+1400.0  1700.0  2200.0  2400.0  3000.0  3200.0
+1300.0  1600.0  2200.0  2300.0  3000.0  3100.0
+1300.0  1900.0  2200.0  2400.0  2900.0  3100.0
+1400.0  1900.0  2300.0  2400.0  3000.0  3100.0
+1400.0  1900.0  2300.0  2500.0  2900.0  3100.0
+1400.0  1800.0  2400.0  2600.0  2800.0  3100.0
+1600.0  2000.0  2500.0  2700.0  3100.0  3300.0
+1500.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1500.0  2100.0  2600.0  2900.0  3300.0  3400.0
+1800.0  2300.0  2600.0  2800.0  3300.0  3400.0
+1700.0  2200.0  2600.0  2700.0  3300.0  3400.0
+2000.0  2200.0  2500.0  2700.0  3000.0  3100.0
+2000.0  2300.0  2600.0  2800.0  3100.0  3200.0
+2100.0  2400.0  2500.0  2900.0  3200.0  3300.0
+2100.0  2300.0  2500.0  2800.0  3100.0  3200.0
+1900.0  2200.0  2300.0  2700.0  3100.0  3200.0
+1200.0  1900.0  2000.0  2300.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2100.0  3200.0  3300.0
+1400.0  1600.0  1700.0  2100.0  3200.0  3300.0
+1400.0  1600.0  1700.0  2200.0  3200.0  3300.0
+1600.0  1700.0  2200.0  2600.0  2900.0  3100.0
+1900.0  2300.0  2700.0  2900.0  3200.0  3300.0
+1700.0  2100.0  2700.0  2900.0  3200.0  3400.0
+1800.0  2100.0  2700.0  2800.0  3100.0  3400.0
+1800.0  2100.0  2600.0  2800.0  3000.0  3200.0
+1800.0  2100.0  2700.0  2800.0  3200.0  3400.0
+1400.0  1600.0  2600.0  2700.0  3000.0  3300.0
+1400.0  1500.0  2600.0  2700.0  3000.0  3400.0
+1300.0  1400.0  2400.0  2800.0  3000.0  3300.0
+1800.0  2200.0  2600.0  2900.0  3200.0  3400.0
+1600.0  2100.0  2600.0  2900.0  3200.0  3400.0
+1200.0  1700.0  2500.0  2600.0  3000.0  3100.0
+1200.0  1800.0  2300.0  2600.0  3000.0  3100.0
+1200.0  1800.0  2300.0  2500.0  3000.0  3100.0
+1300.0  1700.0  2400.0  2500.0  3000.0  3100.0
+1500.0  1800.0  2400.0  2500.0  2900.0  3000.0
+1600.0  2300.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2200.0  2700.0  2900.0  3100.0  3200.0
+1900.0  2200.0  2800.0  2900.0  3100.0  3200.0
+1900.0  2300.0  2800.0  2900.0  3200.0  3300.0
+2200.0  2500.0  2800.0  3000.0  3300.0  3400.0
+2100.0  2500.0  2800.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2700.0  2800.0  3300.0  3500.0
+1900.0  2200.0  2600.0  2800.0  3300.0  3400.0
+1900.0  2100.0  2700.0  2800.0  3300.0  3400.0
+1700.0  1900.0  2600.0  2700.0  3000.0  3300.0
+1600.0  1700.0  2500.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2600.0  2800.0  3100.0  3300.0
+1800.0  1900.0  2500.0  2800.0  3000.0  3300.0
+1900.0  2000.0  2600.0  2800.0  3100.0  3400.0
+2000.0  2100.0  2500.0  2700.0  3000.0  3300.0
+2100.0  2200.0  2500.0  2700.0  3000.0  3300.0
+2100.0  2200.0  2500.0  2800.0  3000.0  3300.0
+2000.0  2100.0  2400.0  2700.0  2900.0  3200.0
+1900.0  2000.0  2400.0  2600.0  2800.0  3100.0
+1700.0  2000.0  2500.0  2700.0  3100.0  3300.0
+1700.0  2100.0  2700.0  2800.0  3100.0  3300.0
+1500.0  1700.0  2400.0  2600.0  3100.0  3400.0
+1500.0  1600.0  2400.0  2500.0  3000.0  3300.0
+1400.0  1600.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1500.0  2300.0  2600.0  3100.0  3300.0
+1500.0  1600.0  2400.0  2600.0  2900.0  3200.0
+1600.0  1700.0  2300.0  2600.0  3000.0  3200.0
+1600.0  1700.0  2300.0  2700.0  3000.0  3200.0
+1700.0  1800.0  2400.0  2600.0  3000.0  3200.0
+1600.0  1700.0  2300.0  2500.0  3100.0  3200.0
+1500.0  1600.0  2200.0  2400.0  3100.0  3200.0
+1300.0  1800.0  2200.0  2400.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2400.0  3000.0  3200.0
+1200.0  1700.0  2300.0  2400.0  2900.0  3100.0
+1200.0  1800.0  2400.0  2500.0  2900.0  3200.0
+1200.0  1800.0  2300.0  2500.0  3100.0  3200.0
+1300.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1300.0  1700.0  2400.0  2500.0  3200.0  3300.0
+1200.0  1700.0  2400.0  2500.0  3200.0  3300.0
+1200.0  1500.0  2400.0  2500.0  3200.0  3300.0
+1900.0  2100.0  2500.0  2800.0  3100.0  3300.0
+1800.0  2000.0  2400.0  2700.0  3000.0  3300.0
+1800.0  2000.0  2300.0  2600.0  3000.0  3300.0
+1900.0  2000.0  2300.0  2400.0  3200.0  3500.0
+1900.0  2000.0  2300.0  2400.0  3100.0  3400.0
+1800.0  2000.0  2300.0  2500.0  3200.0  3400.0
+1700.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1800.0  2100.0  2500.0  2800.0  3100.0  3400.0
+1800.0  2000.0  2500.0  2800.0  3100.0  3300.0
+1800.0  2100.0  2500.0  2600.0  3100.0  3300.0
+1700.0  2100.0  2500.0  2700.0  3100.0  3400.0
+1600.0  1700.0  2500.0  2600.0  3200.0  3300.0
+1500.0  2200.0  2400.0  2700.0  3200.0  3300.0
+1400.0  2000.0  2300.0  2700.0  3300.0  3400.0
+1400.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2400.0  2600.0  3100.0  3300.0
+1600.0  2000.0  2300.0  2600.0  3300.0  3400.0
+1600.0  2100.0  2300.0  2600.0  3300.0  3400.0
+1700.0  1900.0  2300.0  2600.0  3300.0  3400.0
+1900.0  2000.0  2300.0  2400.0  3300.0  3400.0
+1900.0  2000.0  2200.0  2400.0  3300.0  3400.0
+1700.0  1800.0  2200.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2100.0  2500.0  3000.0  3200.0
+1500.0  1700.0  2100.0  2500.0  3000.0  3200.0
+1500.0  1600.0  2100.0  2500.0  3000.0  3200.0
+1500.0  1700.0  2200.0  2700.0  3100.0  3200.0
+1600.0  1900.0  2300.0  2700.0  3200.0  3300.0
+1500.0  1700.0  1800.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2100.0  2500.0  3100.0  3300.0
+2000.0  2300.0  2700.0  2800.0  3100.0  3300.0
+2200.0  2500.0  2900.0  3000.0  3200.0  3300.0
+2300.0  2500.0  2900.0  3000.0  3200.0  3300.0
+1400.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1600.0  2000.0  2300.0  2700.0  3200.0  3300.0
+1500.0  1900.0  2000.0  2400.0  3200.0  3300.0
+1300.0  1800.0  2000.0  2400.0  3300.0  3400.0
+1400.0  1900.0  2200.0  2500.0  3200.0  3300.0
+1800.0  2200.0  2600.0  3000.0  3300.0  3400.0
+1900.0  2200.0  2800.0  2900.0  3300.0  3400.0
+2000.0  2500.0  2900.0  3100.0  3200.0  3300.0
+2000.0  2400.0  2900.0  3000.0  3300.0  3400.0
+2100.0  2400.0  2800.0  3000.0  3200.0  3300.0
+2000.0  2400.0  2700.0  2900.0  3200.0  3300.0
+1700.0  2100.0  2600.0  2800.0  3200.0  3300.0
+1500.0  1900.0  2300.0  2700.0  3100.0  3300.0
+1500.0  1800.0  2200.0  2600.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2500.0  3200.0  3400.0
+1100.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1000.0  2100.0  2500.0  2700.0  3200.0  3300.0
+1000.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1000.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1100.0  1900.0  2400.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2400.0  2700.0  3100.0  3400.0
+1700.0  2100.0  2500.0  2700.0  3000.0  3200.0
+2000.0  2200.0  2600.0  2800.0  3100.0  3300.0
+2100.0  2200.0  2600.0  2800.0  3100.0  3300.0
+1900.0  2100.0  2400.0  2700.0  3100.0  3300.0
+1900.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1800.0  1900.0  2200.0  2600.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2600.0  3100.0  3200.0
+1400.0  1500.0  1800.0  2800.0  3200.0  3300.0
+1300.0  1500.0  1700.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2400.0  2700.0  3100.0  3200.0
+1600.0  1900.0  2400.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2300.0  2700.0  3000.0  3200.0
+1700.0  1900.0  2200.0  2600.0  3000.0  3200.0
+1200.0  1600.0  1800.0  2000.0  3100.0  3400.0
+1100.0  1600.0  2400.0  2500.0  3000.0  3300.0
+1400.0  1700.0  2300.0  2400.0  2900.0  3200.0
+1700.0  2000.0  2300.0  2700.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2400.0  3000.0  3400.0
+1700.0  1800.0  2300.0  2400.0  2900.0  3400.0
+1700.0  1800.0  2300.0  2400.0  2800.0  3300.0
+1800.0  1900.0  2300.0  2400.0  2800.0  3200.0
+1800.0  1900.0  2300.0  2400.0  3000.0  3300.0
+1800.0  1900.0  2300.0  2400.0  2900.0  3300.0
+1700.0  1800.0  2200.0  2300.0  2600.0  3200.0
+1700.0  1800.0  2200.0  2300.0  2700.0  3200.0
+1700.0  1800.0  2300.0  2400.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2400.0  3100.0  3400.0
+1700.0  1800.0  2200.0  2400.0  3200.0  3400.0
+1700.0  1900.0  2200.0  2400.0  3300.0  3400.0
+1800.0  1900.0  2200.0  2400.0  3200.0  3400.0
+1800.0  1900.0  2300.0  2400.0  3200.0  3400.0
+1800.0  1900.0  2300.0  2400.0  3100.0  3400.0
+1800.0  2000.0  2200.0  2400.0  3200.0  3300.0
+1800.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1700.0  1800.0  2000.0  2200.0  3200.0  3300.0
+1400.0  1700.0  1800.0  2200.0  3200.0  3300.0
+1400.0  1800.0  2100.0  2500.0  3100.0  3300.0
+1500.0  1800.0  2200.0  2700.0  3100.0  3200.0
+1600.0  2000.0  2300.0  2500.0  2900.0  3200.0
+1800.0  2200.0  2500.0  2700.0  3000.0  3300.0
+2000.0  2400.0  2700.0  2800.0  3100.0  3300.0
+2200.0  2500.0  2800.0  2900.0  3200.0  3300.0
+1500.0  2300.0  2500.0  2900.0  3300.0  3400.0
+1500.0  1700.0  2300.0  2600.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2600.0  3000.0  3300.0
+1600.0  1700.0  2200.0  2300.0  3200.0  3400.0
+1600.0  1700.0  2200.0  2300.0  3300.0  3400.0
+1200.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1000.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1000.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1300.0  1700.0  2200.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2500.0  2700.0  3000.0  3200.0
+1300.0  1900.0  2400.0  2700.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2700.0  3100.0  3200.0
+1700.0  2100.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2400.0  2500.0  3200.0  3400.0
+1600.0  2000.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2300.0  2400.0  3000.0  3200.0
+1500.0  1900.0  2200.0  2300.0  3000.0  3200.0
+1500.0  2000.0  2200.0  2400.0  3100.0  3200.0
+1400.0  2000.0  2200.0  2400.0  3100.0  3200.0
+1300.0  2000.0  2200.0  2500.0  3100.0  3200.0
+1100.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1000.0  2000.0  2400.0  2500.0  3100.0  3200.0
+1000.0  1700.0  2400.0  2500.0  3100.0  3200.0
+1000.0  1600.0  2400.0  2500.0  3100.0  3200.0
+1100.0  1600.0  2400.0  2500.0  3100.0  3200.0
+1100.0  1600.0  2400.0  2600.0  3100.0  3200.0
+1100.0  1600.0  2500.0  2600.0  3200.0  3300.0
+1100.0  1500.0  2500.0  2600.0  3200.0  3300.0
+1100.0  1500.0  2500.0  2600.0  3100.0  3200.0
+1200.0  1400.0  2400.0  2600.0  3100.0  3200.0
+1300.0  1700.0  2300.0  2400.0  3200.0  3300.0
+1300.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2400.0  3200.0  3300.0
+1400.0  1900.0  2300.0  2400.0  3100.0  3300.0
+1500.0  1700.0  2300.0  2400.0  3000.0  3200.0
+1500.0  1700.0  2300.0  2400.0  3000.0  3300.0
+2100.0  2300.0  2800.0  3000.0  3300.0  3400.0
+2200.0  2400.0  2900.0  3000.0  3200.0  3300.0
+2100.0  2300.0  2900.0  3000.0  3300.0  3400.0
+2000.0  2300.0  2600.0  3000.0  3200.0  3300.0
+1300.0  1600.0  2200.0  2600.0  3100.0  3300.0
+1000.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1000.0  2100.0  2400.0  2600.0  3300.0  3400.0
+1300.0  1700.0  1900.0  2100.0  3100.0  3200.0
+1500.0  1800.0  2000.0  2400.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2100.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2500.0  3300.0  3400.0
+1700.0  1900.0  2100.0  2500.0  2900.0  3200.0
+1600.0  1900.0  2100.0  2300.0  2800.0  3200.0
+1200.0  1700.0  2200.0  2600.0  3000.0  3300.0
+1200.0  1700.0  2300.0  2600.0  3100.0  3300.0
+1600.0  2100.0  2400.0  2700.0  3100.0  3300.0
+1500.0  2000.0  2400.0  2600.0  3100.0  3400.0
+2100.0  2200.0  2700.0  3000.0  3200.0  3300.0
+2100.0  2200.0  2700.0  2900.0  3100.0  3300.0
+1500.0  1800.0  2200.0  2600.0  2900.0  3200.0
+1400.0  1600.0  1800.0  2900.0  3200.0  3300.0
+1600.0  1700.0  1900.0  2500.0  3100.0  3200.0
+1700.0  1800.0  2000.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2600.0  3100.0  3200.0
+1700.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1700.0  1800.0  2200.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2300.0  3100.0  3200.0
+2300.0  2500.0  2800.0  2900.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2800.0  3200.0  3300.0
+1500.0  1900.0  2300.0  2700.0  3200.0  3300.0
+1500.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1600.0  1900.0  2200.0  2500.0  3200.0  3300.0
+1600.0  1900.0  2200.0  2400.0  3100.0  3300.0
+1600.0  1800.0  2200.0  2300.0  3000.0  3300.0
+1700.0  1800.0  2200.0  2300.0  3000.0  3300.0
+1700.0  1900.0  2200.0  2400.0  3100.0  3300.0
+1700.0  1900.0  2200.0  2400.0  3100.0  3400.0
+1700.0  1800.0  2200.0  2400.0  3100.0  3400.0
+1500.0  1800.0  2300.0  2400.0  2900.0  3300.0
+1500.0  1700.0  2200.0  2400.0  3100.0  3400.0
+1400.0  1700.0  2200.0  2300.0  3100.0  3400.0
+1600.0  1900.0  2500.0  2700.0  3200.0  3400.0
+1500.0  1800.0  2400.0  2600.0  3000.0  3300.0
+1400.0  2100.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1800.0  2100.0  2300.0  3200.0  3300.0
+1800.0  2100.0  2600.0  2900.0  3100.0  3200.0
+2000.0  2400.0  2900.0  3100.0  3300.0  3400.0
+1500.0  1800.0  2200.0  2400.0  3300.0  3400.0
+1500.0  2000.0  2100.0  2700.0  3300.0  3400.0
+1600.0  1800.0  2000.0  2400.0  2900.0  3100.0
+1600.0  1800.0  2200.0  2600.0  3000.0  3200.0
+1500.0  1800.0  2100.0  2600.0  3000.0  3200.0
+1600.0  1900.0  2100.0  2400.0  3000.0  3300.0
+1600.0  2000.0  2200.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2100.0  2400.0  3300.0  3400.0
+1400.0  1700.0  2200.0  2600.0  3000.0  3200.0
+1300.0  1600.0  2200.0  2500.0  3000.0  3200.0
+1300.0  1500.0  2100.0  2500.0  3000.0  3300.0
+1200.0  1600.0  1700.0  2400.0  3300.0  3400.0
+1300.0  1600.0  1700.0  2500.0  3300.0  3400.0
+1300.0  1600.0  1700.0  2500.0  3200.0  3300.0
+1400.0  1700.0  1800.0  2500.0  3200.0  3300.0
+1500.0  1800.0  2000.0  2500.0  3200.0  3300.0
+1500.0  1900.0  2000.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2400.0  3200.0  3300.0
+1600.0  1900.0  2100.0  2400.0  3200.0  3300.0
+1500.0  1700.0  2100.0  2200.0  3000.0  3300.0
+1400.0  1600.0  2100.0  2200.0  3000.0  3200.0
+1400.0  1800.0  2100.0  2300.0  3000.0  3200.0
+1600.0  2100.0  2300.0  2700.0  3100.0  3300.0
+1200.0  2100.0  2400.0  2700.0  3300.0  3400.0
+1600.0  2100.0  2200.0  2600.0  3300.0  3400.0
+1300.0  2000.0  2200.0  2500.0  3300.0  3400.0
+1300.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1300.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2800.0  3100.0  3300.0
+1900.0  2200.0  2500.0  2900.0  3100.0  3300.0
+2000.0  2100.0  2600.0  2800.0  3200.0  3300.0
+2000.0  2100.0  2700.0  2900.0  3200.0  3300.0
+1000.0  1900.0  2400.0  2600.0  3300.0  3400.0
+1000.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1000.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1000.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1000.0  1800.0  2400.0  2600.0  3300.0  3400.0
+1000.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1400.0  1700.0  2200.0  2600.0  3100.0  3300.0
+1400.0  1600.0  2100.0  2500.0  3000.0  3300.0
+1300.0  1800.0  2100.0  2400.0  3200.0  3300.0
+1100.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1100.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1100.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1100.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1100.0  1900.0  2300.0  2400.0  3300.0  3400.0
+1200.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2400.0  3300.0  3400.0
+1500.0  1800.0  2200.0  2300.0  3300.0  3400.0
+1700.0  2200.0  2700.0  3000.0  3300.0  3400.0
+1900.0  2200.0  2800.0  3000.0  3200.0  3300.0
+1900.0  2200.0  2500.0  3000.0  3200.0  3300.0
+1600.0  2100.0  2300.0  2700.0  3300.0  3400.0
+1600.0  2000.0  2300.0  2700.0  3300.0  3400.0
+1600.0  2100.0  2500.0  3000.0  3300.0  3400.0
+1600.0  2200.0  2600.0  3000.0  3300.0  3400.0
+1900.0  2400.0  2900.0  3100.0  3300.0  3400.0
+2100.0  2500.0  2900.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2900.0  3000.0  3200.0  3300.0
+1700.0  2200.0  2400.0  2900.0  3200.0  3300.0
+1300.0  1800.0  2100.0  2500.0  3200.0  3300.0
+1500.0  1600.0  1800.0  2300.0  3000.0  3200.0
+1500.0  1600.0  1900.0  2000.0  3000.0  3300.0
+1400.0  1800.0  2200.0  2600.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2400.0  2900.0  3100.0
+1500.0  1700.0  2100.0  2400.0  2900.0  3100.0
+1400.0  1700.0  2100.0  2400.0  3000.0  3200.0
+1400.0  1700.0  2300.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2600.0  3200.0  3300.0
+1000.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1400.0  1900.0  2000.0  2500.0  3200.0  3300.0
+1600.0  1900.0  2100.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2300.0  2500.0  3200.0  3300.0
+2200.0  2400.0  2800.0  3000.0  3200.0  3300.0
+1900.0  2300.0  2400.0  2700.0  3100.0  3200.0
+1900.0  2200.0  2300.0  2600.0  3100.0  3200.0
+1900.0  2100.0  2300.0  2800.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2700.0  3200.0  3300.0
+1900.0  2200.0  2500.0  2700.0  3100.0  3300.0
+1700.0  1800.0  2200.0  2500.0  3300.0  3400.0
+1700.0  1900.0  2200.0  2700.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2700.0  3300.0  3400.0
+1800.0  2000.0  2400.0  2800.0  3300.0  3400.0
+1800.0  2000.0  2300.0  2600.0  3300.0  3400.0
+1900.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1900.0  2100.0  2400.0  2600.0  3200.0  3300.0
+2000.0  2200.0  2400.0  2700.0  3200.0  3300.0
+2100.0  2200.0  2500.0  2900.0  3200.0  3300.0
+2200.0  2300.0  2600.0  2900.0  3200.0  3300.0
+2200.0  2300.0  2700.0  2900.0  3100.0  3300.0
+2100.0  2400.0  2600.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2600.0  2800.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2700.0  3000.0  3200.0
+1800.0  2000.0  2400.0  2700.0  3100.0  3200.0
+1600.0  2000.0  2200.0  2500.0  3100.0  3200.0
+1300.0  1900.0  2100.0  2300.0  3100.0  3300.0
+1200.0  1600.0  2100.0  2200.0  3200.0  3400.0
+1100.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1400.0  1700.0  2100.0  2300.0  3100.0  3300.0
+1400.0  1900.0  2200.0  2500.0  3300.0  3400.0
+1300.0  1800.0  2200.0  2700.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2600.0  3200.0  3300.0
+1400.0  2000.0  2200.0  2700.0  3200.0  3300.0
+1400.0  2000.0  2200.0  2600.0  3300.0  3400.0
+1400.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1400.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1400.0  1800.0  2200.0  2300.0  3000.0  3300.0
+1400.0  1800.0  2200.0  2300.0  3100.0  3300.0
+1400.0  1800.0  2100.0  2300.0  3200.0  3400.0
+1500.0  2000.0  2400.0  2700.0  3300.0  3400.0
+1700.0  2100.0  2500.0  3000.0  3300.0  3400.0
+1400.0  1900.0  2300.0  2800.0  3200.0  3300.0
+1400.0  2000.0  2200.0  2400.0  3200.0  3300.0
+1200.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1200.0  1900.0  2200.0  2500.0  3200.0  3300.0
+1200.0  2000.0  2200.0  2500.0  3300.0  3400.0
+1700.0  2100.0  2300.0  2400.0  3200.0  3400.0
+1400.0  1600.0  1800.0  2500.0  3100.0  3200.0
+1500.0  1800.0  2100.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2200.0  2500.0  3100.0  3300.0
+2000.0  2100.0  2500.0  2800.0  3100.0  3300.0
+1900.0  2100.0  2200.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2100.0  2300.0  3200.0  3400.0
+1600.0  1800.0  2000.0  2300.0  3200.0  3400.0
+1600.0  1800.0  2100.0  2300.0  3200.0  3400.0
+1500.0  1800.0  2000.0  2300.0  3300.0  3400.0
+1500.0  1700.0  1900.0  2400.0  3300.0  3400.0
+1600.0  1900.0  2000.0  2700.0  3100.0  3200.0
+1700.0  1900.0  2200.0  2600.0  3100.0  3300.0
+1700.0  1900.0  2200.0  2500.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2600.0  3100.0  3300.0
+1700.0  2000.0  2400.0  2700.0  3100.0  3200.0
+2300.0  2400.0  2700.0  3000.0  3200.0  3300.0
+2200.0  2400.0  2600.0  2900.0  3200.0  3300.0
+2200.0  2400.0  2500.0  2800.0  3200.0  3300.0
+2100.0  2400.0  2500.0  2800.0  3200.0  3300.0
+2000.0  2400.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2300.0  2400.0  2800.0  3200.0  3300.0
+1900.0  2300.0  2600.0  2700.0  3100.0  3300.0
+2000.0  2400.0  2800.0  2900.0  3200.0  3300.0
+1700.0  2200.0  2500.0  2800.0  3200.0  3400.0
+1500.0  2100.0  2400.0  2600.0  3100.0  3300.0
+1500.0  1900.0  2300.0  2500.0  3200.0  3400.0
+1400.0  1900.0  2300.0  2400.0  3200.0  3300.0
+1100.0  1700.0  2400.0  2600.0  3200.0  3300.0
+1100.0  1700.0  2400.0  2600.0  3300.0  3400.0
+1100.0  1800.0  2400.0  2500.0  3300.0  3400.0
+1100.0  1800.0  2400.0  2500.0  3200.0  3300.0
+1100.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1100.0  2100.0  2500.0  2600.0  3200.0  3300.0
+1100.0  2100.0  2500.0  2700.0  3200.0  3300.0
+1000.0  2200.0  2600.0  2700.0  3200.0  3300.0
+1100.0  2300.0  2600.0  2800.0  3200.0  3300.0
+1100.0  2100.0  2500.0  2700.0  3100.0  3200.0
+1500.0  1700.0  2300.0  2500.0  2900.0  3200.0
+1600.0  1700.0  2200.0  2600.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2600.0  2800.0  3000.0
+1500.0  1700.0  2100.0  2500.0  2800.0  3000.0
+1500.0  1600.0  2200.0  2500.0  2800.0  3100.0
+1500.0  1600.0  2300.0  2600.0  2800.0  3100.0
+1400.0  1500.0  2300.0  2700.0  2900.0  3100.0
+1400.0  1500.0  2200.0  2700.0  2800.0  3100.0
+1400.0  1600.0  2000.0  2700.0  2900.0  3100.0
+1500.0  1700.0  2200.0  2700.0  3100.0  3300.0
+1500.0  1800.0  2300.0  2700.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2700.0  3000.0  3300.0
+1700.0  1800.0  2200.0  2700.0  2900.0  3200.0
+1800.0  1900.0  2200.0  2700.0  2900.0  3100.0
+1700.0  1900.0  2200.0  2600.0  2900.0  3000.0
+1800.0  2000.0  2300.0  2700.0  2900.0  3100.0
+1800.0  2000.0  2300.0  2800.0  3000.0  3200.0
+1800.0  2000.0  2400.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2800.0  3000.0  3200.0
+1500.0  1700.0  2200.0  2500.0  3000.0  3100.0
+1700.0  2100.0  2400.0  2800.0  3100.0  3200.0
+1800.0  2200.0  2700.0  2900.0  3400.0  3500.0
+1900.0  2400.0  2700.0  2900.0  3400.0  3500.0
+2000.0  2400.0  2600.0  2900.0  3300.0  3400.0
+1900.0  2400.0  2500.0  2800.0  3200.0  3300.0
+1900.0  2300.0  2500.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2500.0  3100.0  3200.0
+1600.0  1700.0  2300.0  2600.0  2900.0  3100.0
+1600.0  1700.0  2400.0  2600.0  2900.0  3100.0
+1600.0  2100.0  2600.0  2800.0  3300.0  3400.0
+1700.0  2200.0  2700.0  3000.0  3200.0  3300.0
+1700.0  2300.0  2800.0  2900.0  3200.0  3300.0
+1700.0  2300.0  2700.0  3000.0  3200.0  3300.0
+1600.0  2100.0  2700.0  2900.0  3300.0  3400.0
+1200.0  1600.0  2400.0  2600.0  3000.0  3300.0
+1100.0  1400.0  2400.0  2700.0  2900.0  3100.0
+1200.0  1800.0  2200.0  2500.0  3100.0  3300.0
+1200.0  1700.0  2200.0  2500.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2500.0  2900.0  3200.0
+1900.0  2000.0  2400.0  2500.0  2800.0  3100.0
+2000.0  2200.0  2400.0  2500.0  2800.0  3100.0
+2000.0  2200.0  2400.0  2600.0  2800.0  3200.0
+2000.0  2100.0  2500.0  2700.0  3100.0  3400.0
+1900.0  2000.0  2600.0  2700.0  3100.0  3300.0
+1900.0  2000.0  2600.0  2700.0  3200.0  3300.0
+1900.0  2400.0  2700.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2800.0  2900.0  3200.0  3400.0
+1900.0  2000.0  2300.0  2600.0  3000.0  3200.0
+1900.0  2100.0  2400.0  2700.0  3000.0  3200.0
+1900.0  2100.0  2400.0  2800.0  3100.0  3200.0
+1900.0  2100.0  2400.0  2800.0  3300.0  3400.0
+1500.0  1800.0  2100.0  2600.0  3100.0  3300.0
+1600.0  1800.0  2100.0  2200.0  3000.0  3300.0
+1800.0  2100.0  2300.0  2500.0  3000.0  3200.0
+2000.0  2100.0  2300.0  2500.0  3000.0  3300.0
+2000.0  2100.0  2300.0  2500.0  2900.0  3300.0
+2000.0  2100.0  2300.0  2400.0  2900.0  3300.0
+1600.0  1800.0  2300.0  2500.0  2900.0  3200.0
+1700.0  1900.0  2400.0  2700.0  3000.0  3200.0
+1700.0  2000.0  2400.0  2600.0  3000.0  3300.0
+1600.0  2000.0  2300.0  2700.0  3000.0  3200.0
+1500.0  1800.0  2300.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2400.0  2800.0  3000.0
+1800.0  2000.0  2400.0  2500.0  2900.0  3200.0
+1800.0  2000.0  2400.0  2600.0  3000.0  3200.0
+1900.0  2000.0  2400.0  2500.0  3000.0  3200.0
+1900.0  2000.0  2300.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2400.0  2900.0  3200.0
+1800.0  1900.0  2200.0  2300.0  2900.0  3200.0
+1600.0  1800.0  2200.0  2400.0  3100.0  3300.0
+1600.0  2000.0  2400.0  2700.0  3100.0  3200.0
+1800.0  2100.0  2500.0  2700.0  3000.0  3200.0
+2000.0  2200.0  2500.0  2700.0  3000.0  3200.0
+2000.0  2300.0  2500.0  2700.0  3000.0  3200.0
+2000.0  2300.0  2400.0  2700.0  3000.0  3200.0
+2100.0  2200.0  2400.0  2500.0  3000.0  3300.0
+1900.0  2000.0  2300.0  2600.0  2800.0  3300.0
+1900.0  2000.0  2400.0  2700.0  3100.0  3300.0
+1500.0  2000.0  2400.0  2700.0  3100.0  3300.0
+1600.0  1900.0  2500.0  2800.0  3000.0  3300.0
+1900.0  2000.0  2400.0  2700.0  2900.0  3200.0
+2000.0  2200.0  2400.0  2700.0  2900.0  3200.0
+2100.0  2200.0  2400.0  2700.0  2900.0  3200.0
+2100.0  2300.0  2400.0  2600.0  2800.0  3200.0
+1300.0  2000.0  2300.0  2500.0  2700.0  3100.0
+1800.0  1900.0  2100.0  2400.0  2900.0  3100.0
+1700.0  1900.0  2100.0  2500.0  2900.0  3100.0
+1800.0  1900.0  2300.0  2600.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2600.0  2800.0  3200.0
+1700.0  1800.0  2300.0  2600.0  2800.0  3100.0
+1700.0  1800.0  2300.0  2700.0  2800.0  3200.0
+1500.0  1700.0  2300.0  2600.0  3000.0  3300.0
+1400.0  1700.0  2200.0  2500.0  3000.0  3300.0
+1400.0  1600.0  2200.0  2300.0  3000.0  3300.0
+1400.0  1600.0  2200.0  2400.0  2800.0  3300.0
+1500.0  1600.0  2200.0  2400.0  2900.0  3300.0
+1500.0  1600.0  2200.0  2400.0  2800.0  3300.0
+1500.0  1700.0  2200.0  2500.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2700.0  3000.0  3300.0
+1600.0  1800.0  2400.0  2700.0  3000.0  3200.0
+1600.0  2000.0  2500.0  2800.0  3000.0  3300.0
+2000.0  2200.0  2500.0  2600.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2500.0  3100.0  3200.0
+1500.0  1700.0  1800.0  2300.0  3300.0  3400.0
+1400.0  1600.0  1800.0  2000.0  3200.0  3400.0
+1400.0  1600.0  1800.0  1900.0  3100.0  3400.0
+1400.0  1600.0  1900.0  2000.0  2900.0  3300.0
+1400.0  1500.0  1900.0  2000.0  2900.0  3200.0
+1900.0  2200.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2200.0  2500.0  2700.0  3000.0  3200.0
+1800.0  2200.0  2600.0  2700.0  3100.0  3200.0
+2000.0  2300.0  2700.0  2800.0  3200.0  3300.0
+2100.0  2200.0  2600.0  2800.0  3000.0  3300.0
+2100.0  2200.0  2500.0  2700.0  3100.0  3300.0
+1700.0  1800.0  2000.0  2100.0  2800.0  3200.0
+1600.0  1700.0  1900.0  2000.0  2800.0  3200.0
+1400.0  1500.0  1800.0  1900.0  2800.0  3200.0
+1400.0  1800.0  2100.0  2400.0  3000.0  3200.0
+1600.0  1900.0  2300.0  2600.0  3000.0  3300.0
+1600.0  1900.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2400.0  2700.0  3000.0  3200.0
+1600.0  1900.0  2400.0  2700.0  3000.0  3300.0
+1500.0  1900.0  2400.0  2700.0  3000.0  3300.0
+1100.0  1400.0  2500.0  2800.0  3000.0  3300.0
+1100.0  1300.0  2300.0  2800.0  3000.0  3200.0
+1400.0  1500.0  2100.0  2700.0  2900.0  3100.0
+1500.0  1600.0  2100.0  2700.0  2900.0  3100.0
+1700.0  1800.0  2200.0  2600.0  2800.0  3100.0
+1800.0  2000.0  2300.0  2600.0  2800.0  3000.0
+1900.0  2100.0  2300.0  2600.0  2800.0  3100.0
+2000.0  2100.0  2300.0  2600.0  2800.0  3100.0
+2000.0  2100.0  2400.0  2500.0  2800.0  3200.0
+1900.0  2100.0  2300.0  2500.0  2800.0  3200.0
+1800.0  1900.0  2300.0  2500.0  2800.0  3300.0
+1700.0  1800.0  2300.0  2500.0  3000.0  3300.0
+1700.0  1900.0  2400.0  2600.0  3000.0  3200.0
+1500.0  1900.0  2200.0  2600.0  3100.0  3300.0
+1300.0  1500.0  1800.0  1900.0  2900.0  3200.0
+1300.0  1500.0  1800.0  1900.0  2900.0  3300.0
+1300.0  1500.0  1800.0  1900.0  2800.0  3200.0
+1400.0  1500.0  1700.0  1900.0  2800.0  3200.0
+1400.0  1500.0  1700.0  1800.0  2800.0  3200.0
+1700.0  2000.0  2400.0  2500.0  3100.0  3300.0
+2100.0  2400.0  2700.0  2800.0  3300.0  3500.0
+1800.0  2300.0  2700.0  2900.0  3200.0  3400.0
+1700.0  2300.0  2700.0  2900.0  3300.0  3400.0
+1700.0  2100.0  2700.0  2900.0  3300.0  3400.0
+1800.0  2400.0  2700.0  2900.0  3300.0  3400.0
+1900.0  2500.0  2800.0  3000.0  3300.0  3400.0
+2000.0  2500.0  2800.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2700.0  3000.0  3200.0  3400.0
+1900.0  2300.0  2700.0  3000.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2700.0  2900.0  3200.0
+1800.0  2000.0  2400.0  2700.0  2900.0  3100.0
+1900.0  2000.0  2300.0  2700.0  2900.0  3000.0
+1900.0  2000.0  2400.0  2700.0  2900.0  3100.0
+1800.0  1900.0  2400.0  2700.0  2900.0  3100.0
+1800.0  1900.0  2300.0  2700.0  2800.0  3100.0
+1800.0  1900.0  2300.0  2600.0  2800.0  3100.0
+1500.0  1800.0  2400.0  2700.0  3200.0  3400.0
+1600.0  1800.0  2500.0  2700.0  3100.0  3400.0
+1500.0  1700.0  2400.0  2700.0  3000.0  3300.0
+1400.0  1500.0  2400.0  2700.0  2900.0  3200.0
+1300.0  1500.0  2300.0  2700.0  2900.0  3100.0
+1400.0  1600.0  2100.0  2600.0  2800.0  3000.0
+1500.0  1600.0  2100.0  2600.0  2800.0  3000.0
+1400.0  1600.0  2200.0  2400.0  3000.0  3200.0
+1300.0  1600.0  2200.0  2500.0  2900.0  3200.0
+1300.0  1700.0  2200.0  2600.0  3000.0  3300.0
+1300.0  1700.0  2200.0  2700.0  3100.0  3200.0
+1200.0  1400.0  2200.0  2700.0  2900.0  3100.0
+1100.0  1400.0  2300.0  2700.0  2900.0  3100.0
+1100.0  1300.0  2400.0  2800.0  3000.0  3200.0
+1200.0  1600.0  2300.0  2600.0  3100.0  3200.0
+1500.0  2100.0  2400.0  2700.0  3200.0  3300.0
+1800.0  2100.0  2400.0  2800.0  3200.0  3300.0
+1600.0  2100.0  2400.0  2800.0  3200.0  3300.0
+1600.0  2000.0  2500.0  2900.0  3200.0  3300.0
+1800.0  2000.0  2500.0  2900.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2800.0  3100.0  3300.0
+1600.0  1800.0  2400.0  2700.0  3100.0  3300.0
+1500.0  1600.0  2200.0  2500.0  2900.0  3200.0
+1500.0  1600.0  2200.0  2500.0  2800.0  3200.0
+1400.0  1600.0  2100.0  2500.0  2800.0  3100.0
+1200.0  1400.0  2200.0  2500.0  2700.0  3100.0
+1100.0  1400.0  2400.0  2800.0  2900.0  3100.0
+1400.0  1700.0  2300.0  2600.0  2900.0  3200.0
+1500.0  1800.0  2300.0  2500.0  2900.0  3300.0
+1500.0  1700.0  2000.0  2100.0  3000.0  3300.0
+1500.0  1700.0  2000.0  2200.0  3100.0  3300.0
+1500.0  1700.0  2100.0  2300.0  3100.0  3200.0
+1600.0  1900.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2300.0  2800.0  3100.0  3300.0  3400.0
+1800.0  2200.0  2700.0  2900.0  3200.0  3400.0
+1700.0  2200.0  2700.0  2800.0  3200.0  3400.0
+1500.0  1800.0  2600.0  2700.0  3000.0  3200.0
+1500.0  1700.0  2300.0  2700.0  2800.0  3100.0
+1400.0  1500.0  2100.0  2200.0  2700.0  3200.0
+1400.0  1500.0  2000.0  2100.0  2600.0  3100.0
+1300.0  1500.0  1900.0  2000.0  2500.0  3100.0
+1400.0  1500.0  1800.0  1900.0  2700.0  3200.0
+1500.0  1600.0  2000.0  2100.0  2600.0  3100.0
+1700.0  1800.0  2000.0  2200.0  2600.0  3100.0
+1700.0  1800.0  2100.0  2200.0  2700.0  3100.0
+1600.0  2000.0  2400.0  2500.0  3000.0  3200.0
+2000.0  2200.0  2500.0  2900.0  3100.0  3300.0
+1900.0  2200.0  2400.0  2600.0  2900.0  3100.0
+1600.0  1700.0  2200.0  2400.0  2700.0  3300.0
+1700.0  1800.0  2300.0  2400.0  2800.0  3200.0
+1800.0  1900.0  2300.0  2500.0  2800.0  3200.0
+1900.0  2100.0  2400.0  2500.0  3000.0  3300.0
+2100.0  2200.0  2500.0  2600.0  3000.0  3300.0
+2000.0  2100.0  2500.0  2700.0  2900.0  3200.0
+1700.0  1900.0  2200.0  2700.0  2800.0  3100.0
+1800.0  1900.0  2400.0  2700.0  2800.0  3200.0
+1800.0  1900.0  2400.0  2700.0  2900.0  3200.0
+1700.0  1800.0  2200.0  2700.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2700.0  3000.0  3200.0
+1900.0  2100.0  2500.0  2900.0  3100.0  3300.0
+1700.0  2000.0  2500.0  2700.0  3200.0  3400.0
+1900.0  2200.0  2700.0  3000.0  3300.0  3400.0
+2000.0  2400.0  2800.0  3100.0  3400.0  3500.0
+2100.0  2400.0  2600.0  2900.0  3200.0  3300.0
+2100.0  2400.0  2500.0  2700.0  3100.0  3300.0
+1800.0  2100.0  2500.0  2700.0  3200.0  3300.0
+1700.0  2100.0  2400.0  2700.0  3200.0  3300.0
+1500.0  1600.0  1800.0  1900.0  2600.0  3100.0
+1500.0  1600.0  1900.0  2000.0  2500.0  3100.0
+1600.0  1700.0  2000.0  2100.0  2500.0  3100.0
+1800.0  2100.0  2300.0  2500.0  2800.0  3200.0
+1900.0  2100.0  2300.0  2500.0  2700.0  3200.0
+2000.0  2200.0  2400.0  2600.0  2900.0  3300.0
+2000.0  2200.0  2400.0  2600.0  2900.0  3200.0
+2000.0  2100.0  2400.0  2500.0  2900.0  3300.0
+1800.0  2200.0  2500.0  2900.0  3400.0  3500.0
+1800.0  2300.0  2500.0  2900.0  3300.0  3400.0
+2000.0  2300.0  2500.0  2800.0  3000.0  3300.0
+1800.0  2000.0  2400.0  2500.0  2800.0  3300.0
+1100.0  1400.0  2600.0  2800.0  3000.0  3200.0
+1300.0  1500.0  2200.0  2700.0  2900.0  3200.0
+1400.0  1600.0  2200.0  2700.0  3000.0  3200.0
+1400.0  1600.0  2200.0  2600.0  3100.0  3200.0
+1500.0  1800.0  2200.0  2400.0  3100.0  3300.0
+1700.0  1800.0  2200.0  2500.0  3000.0  3300.0
+1700.0  1800.0  2200.0  2600.0  3000.0  3200.0
+1700.0  1800.0  2300.0  2600.0  3000.0  3200.0
+1700.0  1800.0  2400.0  2700.0  3000.0  3100.0
+1600.0  1700.0  2500.0  2800.0  3000.0  3200.0
+1400.0  1500.0  2200.0  2700.0  2900.0  3100.0
+1300.0  1400.0  2100.0  2700.0  2900.0  3200.0
+1500.0  1900.0  2300.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2200.0  2500.0  2700.0  3100.0
+1600.0  1700.0  2200.0  2500.0  2800.0  3200.0
+1600.0  1800.0  2100.0  2500.0  2900.0  3200.0
+1600.0  1800.0  2100.0  2600.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2800.0  3100.0  3300.0
+1800.0  2100.0  2400.0  2700.0  3000.0  3300.0
+2000.0  2100.0  2500.0  2800.0  3000.0  3200.0
+1800.0  2000.0  2500.0  2700.0  3000.0  3200.0
+1600.0  1900.0  2300.0  2700.0  2900.0  3200.0
+1600.0  1900.0  2100.0  2500.0  2800.0  3100.0
+1700.0  1900.0  2100.0  2500.0  2800.0  3000.0
+1700.0  1800.0  2100.0  2600.0  2800.0  3000.0
+1600.0  1700.0  2000.0  2600.0  2800.0  3000.0
+1400.0  1700.0  2200.0  2700.0  3000.0  3200.0
+1500.0  1800.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1800.0  2300.0  2600.0  3000.0  3300.0
+1600.0  1800.0  2300.0  2600.0  3100.0  3300.0
+1600.0  1900.0  2300.0  2600.0  3100.0  3300.0
+1200.0  1300.0  2100.0  2700.0  3000.0  3100.0
+1300.0  1400.0  2100.0  2700.0  2900.0  3100.0
+1300.0  1400.0  2200.0  2700.0  2900.0  3100.0
+1300.0  1400.0  2100.0  2600.0  2800.0  3100.0
+1300.0  1500.0  2100.0  2600.0  2800.0  3100.0
+1500.0  1600.0  1900.0  2500.0  2900.0  3100.0
+1500.0  1700.0  2100.0  2700.0  2900.0  3200.0
+1600.0  1900.0  2400.0  2700.0  3200.0  3300.0
+1900.0  2100.0  2500.0  2800.0  3200.0  3400.0
+1700.0  2000.0  2400.0  2800.0  3200.0  3400.0
+1600.0  1700.0  2200.0  2400.0  2800.0  3300.0
+1500.0  1600.0  2200.0  2400.0  3000.0  3300.0
+1500.0  1700.0  2300.0  2700.0  3100.0  3300.0
+1400.0  1500.0  2000.0  2600.0  2900.0  3100.0
+1400.0  1500.0  2100.0  2500.0  2800.0  3100.0
+1400.0  1700.0  2200.0  2600.0  3000.0  3300.0
+1000.0  1500.0  2600.0  2800.0  3100.0  3400.0
+1300.0  1500.0  2500.0  2700.0  2900.0  3300.0
+1500.0  1600.0  2200.0  2600.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2400.0  2700.0  3200.0
+1700.0  1800.0  2100.0  2400.0  2600.0  3100.0
+1600.0  1700.0  2100.0  2400.0  2700.0  3200.0
+1600.0  1900.0  2300.0  2700.0  3000.0  3300.0
+1500.0  1600.0  2000.0  2400.0  3000.0  3300.0
+1600.0  1800.0  2300.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2400.0  2600.0  3200.0  3400.0
+1600.0  1800.0  2400.0  2600.0  3200.0  3400.0
+1700.0  1800.0  2300.0  2600.0  3000.0  3300.0
+1700.0  1800.0  2100.0  2500.0  2900.0  3200.0
+1800.0  1900.0  2100.0  2600.0  2800.0  3000.0
+1800.0  1900.0  2200.0  2600.0  2800.0  3000.0
+1800.0  1900.0  2200.0  2600.0  2900.0  3100.0
+1700.0  1800.0  2100.0  2600.0  2900.0  3100.0
+1600.0  1700.0  2100.0  2700.0  2900.0  3100.0
+1400.0  1600.0  2100.0  2700.0  2900.0  3200.0
+1200.0  1600.0  2200.0  2400.0  3000.0  3300.0
+1600.0  1900.0  2300.0  2700.0  3100.0  3400.0
+1200.0  1800.0  2300.0  2700.0  3100.0  3300.0
+1600.0  2000.0  2400.0  2800.0  3100.0  3300.0
+1700.0  1900.0  2100.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2600.0  3100.0  3400.0
+1900.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1900.0  2000.0  2300.0  2600.0  3100.0  3300.0
+1900.0  2100.0  2300.0  2700.0  3100.0  3300.0
+1200.0  1400.0  2200.0  2800.0  3000.0  3100.0
+1800.0  2100.0  2400.0  2700.0  3200.0  3400.0
+1600.0  2100.0  2500.0  2800.0  3100.0  3300.0
+1600.0  2000.0  2500.0  2800.0  3200.0  3300.0
+1700.0  2000.0  2500.0  2800.0  3200.0  3400.0
+1700.0  1900.0  2700.0  2800.0  3100.0  3400.0
+1600.0  1800.0  2400.0  2600.0  3100.0  3400.0
+1600.0  1800.0  2300.0  2500.0  3100.0  3400.0
+1600.0  1800.0  2200.0  2500.0  3100.0  3400.0
+1600.0  1800.0  2100.0  2300.0  3100.0  3400.0
+1500.0  1700.0  2000.0  2200.0  3000.0  3300.0
+1500.0  1600.0  1900.0  2000.0  3000.0  3200.0
+1300.0  1500.0  1700.0  1900.0  2800.0  3200.0
+1800.0  2000.0  2300.0  2600.0  3000.0  3200.0
+1700.0  2000.0  2200.0  2600.0  3000.0  3200.0
+1600.0  1900.0  2400.0  2600.0  3000.0  3300.0
+1300.0  1700.0  2100.0  2400.0  2900.0  3200.0
+1600.0  1800.0  2400.0  2600.0  3000.0  3300.0
+1300.0  1600.0  2200.0  2300.0  2900.0  3200.0
+1300.0  1400.0  2100.0  2200.0  3000.0  3200.0
+1300.0  1500.0  1800.0  2000.0  3000.0  3200.0
+1300.0  1400.0  1800.0  1900.0  2800.0  3200.0
+1300.0  1700.0  2200.0  2500.0  3000.0  3200.0
+1200.0  1800.0  2300.0  2600.0  3200.0  3300.0
+1400.0  1900.0  2300.0  2700.0  3100.0  3300.0
+1500.0  2000.0  2400.0  2600.0  3000.0  3300.0
+1600.0  2000.0  2500.0  2600.0  3100.0  3300.0
+1600.0  1900.0  2500.0  2700.0  3100.0  3300.0
+1600.0  2000.0  2500.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2300.0  2600.0  2800.0  3200.0
+1300.0  1500.0  2000.0  2600.0  2700.0  3000.0
+1300.0  1500.0  2200.0  2600.0  2800.0  3100.0
+1400.0  1500.0  2100.0  2600.0  2800.0  3100.0
+1400.0  1500.0  2100.0  2600.0  2800.0  3000.0
+1500.0  1600.0  2000.0  2500.0  2700.0  3000.0
+1500.0  1700.0  2000.0  2500.0  2700.0  3000.0
+1600.0  1700.0  2000.0  2500.0  2800.0  3000.0
+1700.0  1800.0  2100.0  2500.0  2900.0  3100.0
+1700.0  1900.0  2100.0  2500.0  2900.0  3000.0
+1800.0  2000.0  2200.0  2600.0  2800.0  3000.0
+1800.0  2100.0  2300.0  2600.0  2800.0  3100.0
+1800.0  2100.0  2300.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2200.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2300.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2300.0  2600.0  2800.0  3100.0
+1700.0  1900.0  2200.0  2600.0  2800.0  3000.0
+1700.0  1800.0  2100.0  2500.0  2700.0  3000.0
+1500.0  1700.0  2200.0  2400.0  2800.0  3300.0
+1500.0  1900.0  2300.0  2500.0  3100.0  3300.0
+1700.0  1800.0  2200.0  2800.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2700.0  3000.0  3200.0
+1900.0  2100.0  2400.0  2600.0  3000.0  3200.0
+2000.0  2200.0  2400.0  2700.0  3000.0  3200.0
+1900.0  2300.0  2400.0  2700.0  3100.0  3300.0
+1500.0  1600.0  1800.0  2000.0  3100.0  3300.0
+1200.0  1400.0  1900.0  2500.0  2900.0  3100.0
+1600.0  1700.0  2000.0  2100.0  2900.0  3300.0
+1700.0  1800.0  2100.0  2200.0  2900.0  3300.0
+1800.0  1900.0  2200.0  2300.0  3000.0  3300.0
+1900.0  2000.0  2200.0  2300.0  3100.0  3300.0
+2000.0  2100.0  2300.0  2500.0  3100.0  3400.0
+1900.0  2100.0  2300.0  2500.0  3000.0  3200.0
+1800.0  2000.0  2300.0  2400.0  2900.0  3200.0
+1900.0  2200.0  2600.0  2800.0  3100.0  3300.0
+2000.0  2400.0  2600.0  2700.0  3200.0  3400.0
+1800.0  2200.0  2600.0  2700.0  3100.0  3300.0
+1600.0  2100.0  2600.0  2700.0  3100.0  3300.0
+1600.0  2100.0  2500.0  2800.0  3200.0  3400.0
+1900.0  2200.0  2500.0  2800.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2800.0  3300.0  3400.0
+1700.0  1900.0  2600.0  2800.0  3100.0  3400.0
+1600.0  1700.0  2400.0  2700.0  3100.0  3300.0
+1400.0  1600.0  2200.0  2500.0  2800.0  3200.0
+1400.0  1600.0  2300.0  2500.0  2900.0  3200.0
+1400.0  1500.0  2300.0  2600.0  2900.0  3200.0
+1300.0  1500.0  2400.0  2600.0  3000.0  3300.0
+1200.0  1400.0  2400.0  2600.0  2900.0  3300.0
+1200.0  1300.0  2300.0  2600.0  2800.0  3200.0
+1200.0  1300.0  2300.0  2600.0  2800.0  3100.0
+1200.0  1400.0  2300.0  2600.0  2800.0  3200.0
+1200.0  1400.0  2300.0  2500.0  2800.0  3200.0
+1200.0  1400.0  2300.0  2500.0  2700.0  3200.0
+1300.0  1400.0  2300.0  2500.0  2700.0  3200.0
+1300.0  1400.0  2300.0  2400.0  2900.0  3200.0
+1300.0  1600.0  2300.0  2400.0  2900.0  3200.0
+1600.0  1700.0  2200.0  2500.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2500.0  2900.0  3200.0
+1600.0  1800.0  2300.0  2400.0  2900.0  3200.0
+1600.0  1800.0  2200.0  2400.0  2900.0  3200.0
+1700.0  1900.0  2400.0  2700.0  3000.0  3300.0
+1600.0  1800.0  2400.0  2700.0  3000.0  3300.0
+1600.0  1800.0  2300.0  2600.0  2900.0  3200.0
+1600.0  1800.0  2500.0  2700.0  2900.0  3200.0
+1600.0  1900.0  2500.0  2800.0  3100.0  3300.0
+1600.0  1900.0  2500.0  2800.0  3000.0  3200.0
+1400.0  1700.0  2400.0  2700.0  2900.0  3200.0
+1400.0  1500.0  2200.0  2600.0  2800.0  3100.0
+1300.0  1500.0  2300.0  2600.0  2800.0  3100.0
+1200.0  1400.0  2300.0  2500.0  2700.0  3100.0
+1300.0  1600.0  2200.0  2600.0  3000.0  3300.0
+1200.0  1600.0  2500.0  2700.0  3100.0  3400.0
+1300.0  1800.0  2400.0  2700.0  3200.0  3400.0
+1300.0  1700.0  2300.0  2700.0  3100.0  3300.0
+1300.0  1700.0  2200.0  2500.0  3100.0  3300.0
+1300.0  1600.0  2200.0  2600.0  2900.0  3200.0
+1400.0  1600.0  2200.0  2700.0  2800.0  3100.0
+1600.0  1700.0  2200.0  2700.0  3100.0  3200.0
+1800.0  2000.0  2400.0  2800.0  3100.0  3300.0
+1800.0  2000.0  2400.0  2800.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2700.0  2900.0  3100.0
+1700.0  1800.0  2300.0  2700.0  3000.0  3300.0
+1800.0  1900.0  2600.0  2800.0  3300.0  3400.0
+1900.0  2100.0  2300.0  2600.0  2900.0  3100.0
+1900.0  2200.0  2400.0  2700.0  3000.0  3100.0
+1800.0  2300.0  2400.0  2700.0  3000.0  3100.0
+1800.0  2300.0  2400.0  2600.0  3100.0  3200.0
+2000.0  2300.0  2400.0  2700.0  3100.0  3200.0
+2100.0  2300.0  2500.0  2700.0  3000.0  3200.0
+2000.0  2100.0  2500.0  2700.0  3000.0  3200.0
+1900.0  2000.0  2300.0  2700.0  2900.0  3100.0
+1600.0  1800.0  2200.0  2500.0  2700.0  3000.0
+1500.0  1800.0  2300.0  2500.0  2700.0  3000.0
+1500.0  1800.0  2200.0  2500.0  2700.0  3000.0
+1600.0  1800.0  2300.0  2500.0  2800.0  3000.0
+1700.0  1800.0  2400.0  2700.0  3000.0  3200.0
+1700.0  1800.0  2500.0  2700.0  3000.0  3200.0
+1700.0  1800.0  2400.0  2700.0  3000.0  3300.0
+1600.0  1700.0  2400.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2400.0  2600.0  2800.0  3200.0
+1500.0  1700.0  2400.0  2500.0  2800.0  3200.0
+1400.0  1600.0  2400.0  2500.0  3000.0  3300.0
+1500.0  1700.0  2300.0  2400.0  2900.0  3200.0
+1500.0  1800.0  2200.0  2400.0  2800.0  3000.0
+1600.0  1900.0  2200.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2300.0  2600.0  2900.0  3000.0
+1600.0  2000.0  2300.0  2500.0  2900.0  3100.0
+1600.0  1800.0  2100.0  2300.0  2900.0  3100.0
+1300.0  1500.0  2200.0  2400.0  3000.0  3200.0
+1300.0  1500.0  2200.0  2400.0  2900.0  3200.0
+1300.0  1500.0  2200.0  2500.0  2900.0  3200.0
+1400.0  1500.0  2300.0  2500.0  2900.0  3200.0
+1600.0  1700.0  2100.0  2500.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2600.0  2800.0  3100.0
+1700.0  1800.0  2100.0  2500.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2600.0  2900.0  3100.0
+1700.0  1900.0  2300.0  2600.0  2900.0  3200.0
+1800.0  2100.0  2300.0  2600.0  2900.0  3200.0
+1800.0  2100.0  2300.0  2700.0  2900.0  3200.0
+1900.0  2200.0  2400.0  2700.0  2900.0  3200.0
+1900.0  2100.0  2300.0  2700.0  2900.0  3100.0
+1900.0  2000.0  2300.0  2600.0  2800.0  3100.0
+1900.0  2200.0  2500.0  2800.0  3100.0  3300.0
+1900.0  2200.0  2400.0  2800.0  3000.0  3200.0
+1900.0  2200.0  2400.0  2700.0  2900.0  3100.0
+1900.0  2300.0  2400.0  2800.0  3100.0  3200.0
+2000.0  2300.0  2500.0  2800.0  3100.0  3300.0
+1900.0  2400.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2000.0  2200.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2100.0  2400.0  2900.0  3200.0
+1500.0  1600.0  2200.0  2400.0  2700.0  3200.0
+1300.0  1400.0  2200.0  2500.0  2700.0  3200.0
+1200.0  1500.0  2500.0  2700.0  3000.0  3300.0
+1300.0  1600.0  2400.0  2600.0  3000.0  3300.0
+2000.0  2200.0  2600.0  2700.0  3000.0  3300.0
+2100.0  2300.0  2500.0  2700.0  3000.0  3300.0
+2100.0  2300.0  2600.0  2700.0  3000.0  3300.0
+2000.0  2200.0  2600.0  2700.0  3000.0  3200.0
+1800.0  2300.0  2500.0  2600.0  2900.0  3200.0
+1800.0  2300.0  2500.0  2700.0  2900.0  3100.0
+1800.0  2200.0  2400.0  2600.0  2900.0  3200.0
+1800.0  2200.0  2400.0  2600.0  2800.0  3100.0
+1800.0  2200.0  2300.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2200.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2800.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2800.0  3000.0  3300.0
+1600.0  1800.0  2300.0  2800.0  3000.0  3300.0
+1400.0  1700.0  2200.0  2500.0  2800.0  2900.0
+1400.0  1700.0  2100.0  2500.0  2900.0  3200.0
+1700.0  2000.0  2200.0  2800.0  3200.0  3300.0
+1800.0  1900.0  2200.0  2700.0  2900.0  3200.0
+1800.0  2000.0  2200.0  2700.0  2900.0  3100.0
+1800.0  2000.0  2200.0  2700.0  2800.0  3000.0
+1800.0  2000.0  2200.0  2700.0  2800.0  3100.0
+1600.0  1900.0  2100.0  2600.0  2900.0  3200.0
+2000.0  2100.0  2600.0  2900.0  3000.0  3200.0
+2000.0  2200.0  2700.0  2900.0  3100.0  3300.0
+2000.0  2200.0  2400.0  2800.0  3000.0  3200.0
+2000.0  2200.0  2300.0  2700.0  3000.0  3200.0
+1700.0  2200.0  2400.0  2600.0  2900.0  3100.0
+1800.0  2200.0  2400.0  2700.0  3000.0  3200.0
+1900.0  2300.0  2500.0  2700.0  3000.0  3200.0
+1900.0  2300.0  2500.0  2700.0  2900.0  3100.0
+1900.0  2300.0  2500.0  2800.0  3000.0  3200.0
+1900.0  2300.0  2500.0  2700.0  2900.0  3200.0
+1800.0  2200.0  2400.0  2700.0  2900.0  3100.0
+1800.0  2000.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1700.0  2100.0  2800.0  3100.0  3200.0
+1400.0  1800.0  2200.0  2500.0  3000.0  3100.0
+1400.0  1800.0  2300.0  2500.0  3000.0  3100.0
+1400.0  1800.0  2300.0  2500.0  2900.0  3100.0
+1600.0  1800.0  2500.0  2800.0  3100.0  3200.0
+1700.0  2000.0  2400.0  2700.0  3200.0  3400.0
+1700.0  2000.0  2500.0  2800.0  3100.0  3400.0
+1500.0  1700.0  2300.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2200.0  2600.0  2800.0  3200.0
+1500.0  1700.0  2200.0  2600.0  2900.0  3300.0
+1400.0  1700.0  2200.0  2600.0  2900.0  3300.0
+1200.0  1500.0  2200.0  2300.0  3100.0  3400.0
+1200.0  1600.0  2300.0  2400.0  3200.0  3300.0
+1200.0  1700.0  2300.0  2400.0  3100.0  3300.0
+1100.0  1700.0  2400.0  2500.0  3100.0  3300.0
+1100.0  1800.0  2500.0  2600.0  3100.0  3300.0
+1100.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1000.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1000.0  1700.0  2400.0  2500.0  3200.0  3300.0
+1100.0  1600.0  2400.0  2500.0  3200.0  3300.0
+1100.0  1600.0  2300.0  2400.0  3200.0  3300.0
+1300.0  1600.0  2300.0  2500.0  3100.0  3300.0
+1400.0  1700.0  2300.0  2500.0  3100.0  3300.0
+2000.0  2100.0  2500.0  2600.0  3200.0  3400.0
+1700.0  2100.0  2600.0  2800.0  3100.0  3200.0
+1800.0  2200.0  2700.0  2900.0  3100.0  3300.0
+2100.0  2400.0  2700.0  2900.0  3200.0  3300.0
+2100.0  2500.0  2700.0  2900.0  3300.0  3400.0
+2100.0  2400.0  2600.0  2800.0  3200.0  3400.0
+1700.0  1900.0  2400.0  2600.0  2900.0  3000.0
+1600.0  1900.0  2400.0  2500.0  2800.0  2900.0
+1300.0  2000.0  2400.0  2500.0  2900.0  3200.0
+1500.0  2000.0  2400.0  2500.0  2900.0  3100.0
+1600.0  2000.0  2400.0  2600.0  3000.0  3100.0
+1700.0  1900.0  2500.0  2600.0  3100.0  3200.0
+1600.0  1800.0  2600.0  2700.0  3300.0  3400.0
+1500.0  1600.0  2600.0  2700.0  3200.0  3400.0
+1500.0  1700.0  2600.0  2700.0  3200.0  3400.0
+1500.0  2100.0  2600.0  2800.0  3300.0  3400.0
+1700.0  2200.0  2700.0  2900.0  3300.0  3400.0
+1700.0  2300.0  2700.0  2800.0  3300.0  3400.0
+1800.0  2300.0  2700.0  2800.0  3300.0  3400.0
+1400.0  1700.0  2500.0  2600.0  3000.0  3300.0
+1400.0  1800.0  2500.0  2600.0  3000.0  3300.0
+1800.0  2200.0  2700.0  2900.0  3300.0  3400.0
+1800.0  2300.0  2600.0  2900.0  3300.0  3400.0
+1400.0  1900.0  2500.0  2600.0  3200.0  3400.0
+1400.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1400.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1200.0  2000.0  2400.0  2700.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2600.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2500.0  3100.0  3200.0
+1200.0  1700.0  2300.0  2500.0  3000.0  3100.0
+1200.0  1800.0  2400.0  2500.0  3000.0  3100.0
+1100.0  2100.0  2300.0  2600.0  3000.0  3100.0
+1400.0  1800.0  2200.0  2700.0  3100.0  3200.0
+1600.0  2000.0  2400.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2400.0  2600.0  3300.0  3400.0
+1600.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1600.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1500.0  2400.0  2700.0  2800.0  3100.0  3300.0
+1300.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1400.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1600.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1600.0  2100.0  2300.0  2500.0  3000.0  3100.0
+1800.0  2100.0  2400.0  2700.0  2900.0  3200.0
+1500.0  1700.0  2000.0  2600.0  3200.0  3300.0
+1400.0  1700.0  2000.0  2400.0  3200.0  3300.0
+1400.0  1900.0  2200.0  2500.0  3100.0  3300.0
+1500.0  1900.0  2200.0  2500.0  3100.0  3300.0
+1200.0  1900.0  2500.0  2600.0  3100.0  3300.0
+1000.0  1700.0  2600.0  2800.0  3300.0  3400.0
+1200.0  1500.0  2400.0  2700.0  2900.0  3200.0
+1700.0  2100.0  2400.0  2800.0  3200.0  3400.0
+1700.0  2000.0  2600.0  2800.0  3100.0  3400.0
+1700.0  2000.0  2600.0  2700.0  3000.0  3300.0
+1500.0  1700.0  2500.0  2700.0  3000.0  3300.0
+1600.0  2000.0  2600.0  2800.0  3100.0  3300.0
+1500.0  2000.0  2500.0  2800.0  3200.0  3400.0
+1400.0  1800.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2200.0  2600.0  2900.0  3200.0  3400.0
+1700.0  2200.0  2600.0  2800.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1500.0  1800.0  2200.0  2500.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2700.0  3300.0  3400.0
+1400.0  1800.0  2500.0  2700.0  3000.0  3300.0
+1300.0  1600.0  2500.0  2600.0  3200.0  3400.0
+1400.0  1700.0  2500.0  2600.0  3300.0  3400.0
+1500.0  1700.0  2400.0  2500.0  3200.0  3400.0
+1900.0  2000.0  2300.0  2500.0  3200.0  3400.0
+1600.0  1900.0  2100.0  2500.0  3000.0  3200.0
+1600.0  2100.0  2500.0  2800.0  3200.0  3300.0
+1400.0  2000.0  2400.0  2700.0  3200.0  3300.0
+900.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1100.0  1600.0  2700.0  2800.0  3200.0  3400.0
+1200.0  1600.0  2600.0  2800.0  3200.0  3400.0
+1300.0  1700.0  2500.0  2700.0  3100.0  3300.0
+1400.0  1700.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1800.0  2300.0  2500.0  3100.0  3200.0
+1400.0  2100.0  2400.0  2600.0  2900.0  3100.0
+1300.0  2000.0  2400.0  2600.0  3100.0  3200.0
+1200.0  1800.0  2300.0  2500.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2500.0  3100.0  3300.0
+1600.0  2000.0  2400.0  2600.0  3200.0  3400.0
+1800.0  2000.0  2300.0  2500.0  3100.0  3400.0
+1700.0  1900.0  2300.0  2400.0  3100.0  3300.0
+1600.0  1800.0  2300.0  2400.0  2900.0  3300.0
+1600.0  1800.0  2300.0  2400.0  3000.0  3300.0
+1600.0  1700.0  2300.0  2400.0  3000.0  3300.0
+1600.0  1700.0  2300.0  2400.0  2800.0  3200.0
+1600.0  1700.0  2300.0  2400.0  2900.0  3300.0
+1500.0  1700.0  2300.0  2500.0  3000.0  3300.0
+1400.0  1700.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1600.0  2500.0  2700.0  3100.0  3300.0
+1300.0  1500.0  2500.0  2700.0  3100.0  3300.0
+1300.0  1600.0  2400.0  2700.0  3000.0  3400.0
+1800.0  2300.0  2600.0  2800.0  3100.0  3300.0
+1800.0  2200.0  2500.0  2800.0  3100.0  3300.0
+1700.0  2100.0  2500.0  2700.0  3000.0  3300.0
+1600.0  1900.0  2500.0  2700.0  2900.0  3200.0
+1700.0  2000.0  2500.0  2700.0  3000.0  3200.0
+1700.0  2300.0  2600.0  2700.0  3200.0  3400.0
+1400.0  1700.0  1900.0  2200.0  3200.0  3300.0
+1200.0  1900.0  2100.0  2600.0  3100.0  3200.0
+1200.0  1900.0  2200.0  2700.0  3100.0  3200.0
+1200.0  1900.0  2300.0  2700.0  3200.0  3300.0
+1100.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1200.0  1900.0  2400.0  2700.0  3200.0  3300.0
+1200.0  1800.0  2300.0  2600.0  3200.0  3400.0
+1200.0  1600.0  2400.0  2700.0  3200.0  3400.0
+1200.0  1500.0  2400.0  2600.0  3000.0  3200.0
+1300.0  1500.0  2100.0  2500.0  2700.0  3000.0
+1200.0  1800.0  2400.0  2600.0  3100.0  3200.0
+1200.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1700.0  2400.0  2700.0  3100.0  3300.0  3400.0
+2000.0  2500.0  2700.0  3100.0  3400.0  3500.0
+1900.0  2400.0  2700.0  3100.0  3400.0  3500.0
+1900.0  2200.0  2700.0  3100.0  3300.0  3400.0
+1800.0  2200.0  2700.0  3100.0  3300.0  3400.0
+1500.0  1700.0  2100.0  2500.0  3200.0  3300.0
+1400.0  1800.0  2100.0  2600.0  3200.0  3300.0
+1200.0  1700.0  2000.0  2300.0  3300.0  3400.0
+1300.0  1500.0  1600.0  2300.0  3100.0  3200.0
+1500.0  1900.0  2400.0  2600.0  3000.0  3300.0
+1500.0  2000.0  2400.0  2500.0  2800.0  3200.0
+1400.0  2000.0  2400.0  2500.0  2900.0  3200.0
+1300.0  1600.0  1700.0  2300.0  3300.0  3400.0
+1300.0  1600.0  1700.0  2100.0  3200.0  3400.0
+2000.0  2200.0  2500.0  2900.0  3300.0  3400.0
+2100.0  2300.0  2500.0  2700.0  3300.0  3400.0
+1900.0  2200.0  2400.0  2700.0  3300.0  3400.0
+1500.0  1900.0  2200.0  2400.0  3000.0  3300.0
+1500.0  1900.0  2400.0  2700.0  3300.0  3400.0
+1500.0  1700.0  2500.0  2700.0  3200.0  3400.0
+1500.0  1700.0  2500.0  2600.0  3100.0  3400.0
+1600.0  2000.0  2400.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2600.0  3000.0  3100.0
+1500.0  1800.0  2200.0  2600.0  3000.0  3100.0
+1500.0  1900.0  2400.0  2500.0  3000.0  3200.0
+1200.0  1500.0  2400.0  2600.0  3200.0  3300.0
+1500.0  2000.0  2500.0  2700.0  3100.0  3300.0
+1700.0  2100.0  2500.0  2900.0  3200.0  3300.0
+1400.0  1800.0  2400.0  2500.0  3100.0  3300.0
+1400.0  2000.0  2300.0  2500.0  3200.0  3400.0
+1200.0  1900.0  2200.0  2400.0  3300.0  3400.0
+1200.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1200.0  1900.0  2300.0  2400.0  3300.0  3400.0
+1200.0  1700.0  2300.0  2400.0  3300.0  3400.0
+1200.0  1600.0  2200.0  2300.0  3300.0  3400.0
+1200.0  1600.0  2200.0  2400.0  3300.0  3400.0
+1300.0  1600.0  2100.0  2400.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2600.0  2900.0  3200.0
+2100.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1600.0  1800.0  2300.0  2500.0  3100.0  3300.0
+1500.0  1800.0  2300.0  2500.0  3100.0  3300.0
+1400.0  1800.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1800.0  2400.0  2600.0  3100.0  3300.0
+1300.0  1800.0  2400.0  2700.0  3200.0  3300.0
+1100.0  1800.0  2400.0  2700.0  3200.0  3300.0
+1400.0  2000.0  2500.0  2600.0  2900.0  3200.0
+1500.0  2100.0  2500.0  2600.0  2900.0  3200.0
+1500.0  1900.0  2400.0  2600.0  3100.0  3300.0
+1300.0  1900.0  2400.0  2800.0  3100.0  3300.0
+1300.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1300.0  1800.0  2600.0  2700.0  3100.0  3400.0
+1300.0  1700.0  2600.0  2700.0  3100.0  3300.0
+1300.0  1700.0  2600.0  2700.0  3100.0  3400.0
+1400.0  1900.0  2400.0  2600.0  2900.0  3100.0
+1500.0  1800.0  2300.0  2600.0  2900.0  3100.0
+1600.0  1900.0  2400.0  2600.0  3000.0  3200.0
+1700.0  2000.0  2600.0  2900.0  3100.0  3300.0
+1800.0  2300.0  2500.0  2800.0  3200.0  3400.0
+1900.0  2300.0  2600.0  2900.0  3300.0  3400.0
+1600.0  1900.0  2500.0  2600.0  3000.0  3100.0
+1600.0  1900.0  2500.0  2600.0  3000.0  3200.0
+1500.0  1800.0  2200.0  2500.0  3200.0  3300.0
+1500.0  1900.0  2200.0  2500.0  3300.0  3400.0
+1500.0  1800.0  2200.0  2400.0  3200.0  3400.0
+1500.0  1800.0  2100.0  2400.0  3200.0  3400.0
+1600.0  1800.0  2100.0  2200.0  3200.0  3400.0
+1700.0  1800.0  2100.0  2400.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2400.0  2700.0  3100.0
+1600.0  1900.0  2400.0  2500.0  3000.0  3300.0
+1600.0  2100.0  2500.0  2600.0  3200.0  3400.0
+1200.0  2000.0  2400.0  2500.0  3400.0  3500.0
+1200.0  1600.0  2300.0  2400.0  3200.0  3400.0
+1400.0  1900.0  2400.0  2500.0  3000.0  3200.0
+1300.0  1800.0  2100.0  2500.0  3100.0  3300.0
+1300.0  1700.0  2300.0  2500.0  3100.0  3300.0
+1300.0  1700.0  2200.0  2400.0  3200.0  3300.0
+1300.0  1800.0  2200.0  2400.0  3200.0  3300.0
+1500.0  1800.0  2300.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2300.0  2500.0  3300.0  3400.0
+1700.0  1900.0  2400.0  2600.0  3300.0  3400.0
+1700.0  1900.0  2500.0  2700.0  3000.0  3100.0
+1700.0  1800.0  2500.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2500.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2400.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2400.0  2600.0  3100.0  3300.0
+1500.0  1700.0  2400.0  2600.0  3100.0  3300.0
+1300.0  1700.0  2400.0  2600.0  3100.0  3300.0
+1300.0  1700.0  2400.0  2600.0  3200.0  3300.0
+1400.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1400.0  1800.0  2300.0  2600.0  3200.0  3300.0
+1500.0  1800.0  2300.0  2600.0  3300.0  3400.0
+1500.0  1800.0  2300.0  2500.0  3300.0  3400.0
+1500.0  1700.0  2200.0  2400.0  3300.0  3400.0
+1800.0  2200.0  2400.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2600.0  3200.0  3300.0
+1900.0  2000.0  2200.0  2500.0  3300.0  3400.0
+1900.0  2100.0  2300.0  2600.0  3300.0  3400.0
+1800.0  1900.0  2200.0  2600.0  3100.0  3300.0
+1100.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1000.0  1700.0  2700.0  2800.0  3200.0  3300.0
+1000.0  1800.0  2600.0  2700.0  3000.0  3100.0
+1200.0  2000.0  2600.0  2800.0  3200.0  3300.0
+1200.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1200.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1200.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1300.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1300.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1400.0  1900.0  2300.0  2600.0  3300.0  3400.0
+2200.0  2400.0  2500.0  2900.0  3200.0  3300.0
+2100.0  2200.0  2400.0  2800.0  3200.0  3300.0
+2000.0  2200.0  2400.0  2800.0  3200.0  3300.0
+1900.0  2100.0  2400.0  2800.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2400.0  2800.0  3000.0
+1600.0  1900.0  2300.0  2400.0  2900.0  3300.0
+1800.0  2100.0  2400.0  2500.0  3100.0  3200.0
+1800.0  2300.0  2500.0  2700.0  3200.0  3300.0
+1800.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1500.0  1900.0  2100.0  2700.0  3000.0  3100.0
+1500.0  1700.0  1800.0  2600.0  3300.0  3400.0
+1500.0  1700.0  1800.0  2500.0  3300.0  3400.0
+1300.0  1500.0  1600.0  2500.0  3200.0  3300.0
+1300.0  1500.0  1700.0  2400.0  3000.0  3100.0
+1600.0  2000.0  2500.0  2700.0  3300.0  3400.0
+2000.0  2100.0  2400.0  2700.0  3300.0  3400.0
+1800.0  2000.0  2200.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2100.0  2600.0  3200.0  3300.0
+1700.0  2000.0  2100.0  2700.0  3200.0  3300.0
+1700.0  2100.0  2200.0  2700.0  3200.0  3300.0
+1700.0  2200.0  2400.0  2700.0  3200.0  3300.0
+1700.0  2200.0  2400.0  2600.0  3200.0  3300.0
+1700.0  2100.0  2500.0  2600.0  3200.0  3300.0
+1800.0  2400.0  2600.0  3000.0  3300.0  3400.0
+1800.0  2400.0  2800.0  3100.0  3300.0  3400.0
+1900.0  2400.0  2800.0  3100.0  3300.0  3500.0
+1900.0  2300.0  2800.0  3000.0  3300.0  3400.0
+1600.0  1800.0  2400.0  2600.0  3000.0  3100.0
+1500.0  1700.0  1900.0  2500.0  3300.0  3400.0
+1200.0  1700.0  2200.0  2300.0  3100.0  3300.0
+1100.0  1500.0  2300.0  2400.0  3000.0  3300.0
+1200.0  1600.0  2300.0  2400.0  3100.0  3300.0
+1200.0  1600.0  2300.0  2400.0  3100.0  3400.0
+1300.0  1600.0  2200.0  2400.0  3200.0  3300.0
+1500.0  1600.0  2100.0  2400.0  3000.0  3300.0
+1600.0  1700.0  2100.0  2400.0  3100.0  3300.0
+1500.0  1600.0  2100.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2200.0  2600.0  3100.0  3300.0
+1500.0  1800.0  2200.0  2500.0  3000.0  3200.0
+1400.0  1800.0  2200.0  2500.0  2900.0  3200.0
+1300.0  1600.0  2200.0  2600.0  3000.0  3200.0
+1700.0  2000.0  2400.0  2800.0  3000.0  3100.0
+1700.0  2100.0  2400.0  2700.0  3000.0  3100.0
+1800.0  2200.0  2500.0  2800.0  3000.0  3200.0
+1700.0  2100.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2200.0  2500.0  2700.0  3200.0  3400.0
+1600.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2400.0  3200.0  3300.0
+1500.0  1700.0  1900.0  2300.0  3300.0  3400.0
+1400.0  1600.0  1800.0  2200.0  3300.0  3400.0
+1500.0  1600.0  1900.0  2600.0  3000.0  3200.0
+1500.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1200.0  1900.0  2100.0  2500.0  3200.0  3300.0
+1900.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1800.0  2100.0  2300.0  2600.0  3300.0  3400.0
+1700.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1600.0  2100.0  2300.0  2700.0  3200.0  3300.0
+1500.0  1900.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1900.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1500.0  2100.0  2500.0  2600.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2500.0  2900.0  3100.0
+1800.0  2000.0  2500.0  2800.0  3000.0  3200.0
+1400.0  1600.0  2100.0  2600.0  3000.0  3300.0
+1700.0  2000.0  2400.0  2700.0  3300.0  3400.0
+1700.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1700.0  2100.0  2600.0  2700.0  3000.0  3300.0
+1800.0  2100.0  2500.0  2700.0  3100.0  3200.0
+2200.0  2300.0  2500.0  2800.0  3200.0  3300.0
+2100.0  2300.0  2500.0  2800.0  3200.0  3300.0
+2000.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2700.0  3100.0  3200.0
+1600.0  2000.0  2400.0  2700.0  3100.0  3400.0
+1300.0  1800.0  2100.0  2500.0  3100.0  3200.0
+1300.0  1800.0  2200.0  2800.0  3100.0  3200.0
+1300.0  2000.0  2200.0  2600.0  3200.0  3300.0
+1900.0  2100.0  2400.0  2500.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1500.0  1900.0  2400.0  2600.0  3300.0  3400.0
+1500.0  1800.0  2400.0  2600.0  3200.0  3400.0
+1500.0  1700.0  2400.0  2600.0  3200.0  3400.0
+1400.0  1700.0  2400.0  2600.0  3100.0  3300.0
+1400.0  1900.0  2500.0  2600.0  2900.0  3200.0
+1400.0  1900.0  2400.0  2700.0  3000.0  3200.0
+1400.0  1900.0  2400.0  2600.0  3000.0  3100.0
+1400.0  1900.0  2300.0  2500.0  2700.0  3000.0
+1300.0  1800.0  2200.0  2500.0  3300.0  3400.0
+1300.0  1800.0  2200.0  2400.0  3300.0  3400.0
+1300.0  1700.0  2100.0  2400.0  3200.0  3400.0
+1400.0  1900.0  2300.0  2600.0  3100.0  3300.0
+1900.0  2200.0  2400.0  2800.0  3100.0  3200.0
+1600.0  2200.0  2400.0  2700.0  3300.0  3400.0
+1600.0  2100.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1700.0  2000.0  2500.0  3000.0  3200.0
+1400.0  1800.0  2300.0  2500.0  3000.0  3200.0
+1700.0  1900.0  2100.0  2400.0  3200.0  3300.0
+1800.0  1900.0  2200.0  2500.0  3200.0  3300.0
+1900.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2000.0  2500.0  2600.0  3100.0  3300.0
+1400.0  1900.0  2300.0  2500.0  2800.0  3200.0
+1400.0  1900.0  2300.0  2500.0  2900.0  3300.0
+1400.0  1600.0  2300.0  2500.0  3000.0  3200.0
+1400.0  1600.0  2200.0  2500.0  3100.0  3200.0
+2000.0  2200.0  2500.0  2700.0  3000.0  3300.0
+1600.0  2100.0  2600.0  2900.0  3200.0  3300.0
+1500.0  1700.0  2100.0  2500.0  3100.0  3200.0
+1200.0  2100.0  2600.0  2700.0  3200.0  3300.0
+1100.0  2100.0  2600.0  2800.0  3200.0  3300.0
+1000.0  2000.0  2800.0  2900.0  3100.0  3200.0
+1600.0  1900.0  2100.0  2500.0  3000.0  3100.0
+1700.0  1900.0  2200.0  2500.0  3000.0  3100.0
+1700.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1400.0  2000.0  2300.0  2400.0  3200.0  3300.0
+1300.0  2000.0  2200.0  2400.0  3100.0  3200.0
+1200.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1200.0  1800.0  2300.0  2600.0  3100.0  3200.0
+1300.0  1600.0  2300.0  2700.0  3100.0  3200.0
+1300.0  1700.0  2300.0  2700.0  3100.0  3200.0
+1100.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1300.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1300.0  1900.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1800.0  2100.0  2600.0  3300.0  3400.0
+1500.0  1900.0  2100.0  2500.0  2800.0  3000.0
+1500.0  2000.0  2200.0  2500.0  3000.0  3100.0
+1500.0  2000.0  2200.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2300.0  2500.0  3100.0  3200.0
+1600.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1600.0  1900.0  2400.0  2600.0  2900.0  3100.0
+1900.0  2300.0  2600.0  2800.0  3100.0  3200.0
+2000.0  2400.0  2700.0  2800.0  3100.0  3200.0
+1300.0  1800.0  2000.0  2400.0  3100.0  3200.0
+1100.0  1700.0  2100.0  2400.0  3100.0  3200.0
+1300.0  1600.0  2100.0  2500.0  3000.0  3100.0
+1200.0  1700.0  2200.0  2500.0  3000.0  3200.0
+1400.0  1800.0  2100.0  2300.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2200.0  3200.0  3300.0
+1700.0  1900.0  2100.0  2300.0  3200.0  3300.0
+1800.0  1900.0  2400.0  2800.0  3100.0  3200.0
+2000.0  2300.0  2800.0  3000.0  3100.0  3300.0
+2100.0  2300.0  2700.0  3000.0  3200.0  3300.0
+2100.0  2300.0  2600.0  2900.0  3200.0  3300.0
+2200.0  2400.0  2700.0  2800.0  3200.0  3300.0
+1700.0  2000.0  2300.0  2500.0  3000.0  3100.0
+1600.0  2000.0  2300.0  2400.0  2800.0  3200.0
+1700.0  2100.0  2300.0  2400.0  2900.0  3200.0
+1400.0  1800.0  2300.0  2600.0  3000.0  3300.0
+1500.0  2200.0  2400.0  2700.0  3100.0  3200.0
+1500.0  2200.0  2500.0  2700.0  3200.0  3300.0
+1400.0  1600.0  2400.0  2500.0  3100.0  3400.0
+1600.0  2200.0  2500.0  2800.0  3300.0  3400.0
+1600.0  2000.0  2500.0  2800.0  3300.0  3400.0
+1400.0  1700.0  2400.0  2500.0  3200.0  3400.0
+1400.0  1600.0  2400.0  2600.0  3200.0  3300.0
+1400.0  1700.0  2300.0  2500.0  3200.0  3300.0
+1500.0  2000.0  2300.0  2400.0  2800.0  3200.0
+1500.0  2000.0  2300.0  2400.0  2700.0  3200.0
+1400.0  1900.0  2300.0  2500.0  3000.0  3300.0
+1200.0  1400.0  2300.0  2600.0  2900.0  3100.0
+1500.0  2000.0  2300.0  2500.0  3000.0  3200.0
+1800.0  2000.0  2500.0  2600.0  3100.0  3200.0
+1500.0  1800.0  2400.0  2600.0  3000.0  3200.0
+1200.0  1500.0  2200.0  2400.0  3000.0  3100.0
+1500.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1700.0  2000.0  2600.0  2800.0  3200.0  3300.0
+1500.0  1900.0  2100.0  2500.0  3200.0  3300.0
+1700.0  1800.0  2000.0  2300.0  3000.0  3100.0
+1600.0  1900.0  2300.0  2500.0  2800.0  3100.0
+1600.0  1800.0  2300.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2300.0  2500.0  3200.0  3300.0
+1700.0  1800.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1700.0  2200.0  2400.0  3000.0  3300.0
+1500.0  1700.0  2300.0  2500.0  3200.0  3400.0
+1500.0  1700.0  2300.0  2400.0  2800.0  3300.0
+1600.0  1700.0  2200.0  2400.0  2600.0  3200.0
+1700.0  1800.0  2200.0  2400.0  2900.0  3300.0
+1900.0  2100.0  2400.0  2500.0  3100.0  3300.0
+1900.0  2000.0  2400.0  2500.0  3100.0  3300.0
+1900.0  2300.0  2500.0  2900.0  3200.0  3300.0
+2200.0  2400.0  2700.0  3100.0  3300.0  3400.0
+2200.0  2400.0  2800.0  3100.0  3300.0  3400.0
+1500.0  1900.0  2300.0  2400.0  3200.0  3300.0
+1500.0  1800.0  2200.0  2300.0  3100.0  3300.0
+1700.0  2000.0  2600.0  2900.0  3200.0  3400.0
+1500.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1300.0  1600.0  2000.0  2500.0  3000.0  3200.0
+1800.0  2000.0  2200.0  2500.0  3000.0  3100.0
+1200.0  1800.0  2200.0  2400.0  3100.0  3200.0
+1300.0  1500.0  2100.0  2200.0  3100.0  3200.0
+1400.0  1900.0  2200.0  2300.0  3200.0  3300.0
+1900.0  2300.0  2600.0  3000.0  3200.0  3400.0
+1900.0  2300.0  2600.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2600.0  2900.0  3100.0  3300.0
+1200.0  1500.0  2500.0  2600.0  3100.0  3200.0
+1400.0  1900.0  2300.0  2400.0  2600.0  3100.0
+1500.0  1600.0  2100.0  2400.0  2900.0  3200.0
+1400.0  1600.0  2200.0  2600.0  2900.0  3200.0
+1700.0  1800.0  2100.0  2300.0  3000.0  3100.0
+1700.0  1900.0  2100.0  2300.0  3100.0  3200.0
+1800.0  1900.0  2200.0  2300.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2300.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1600.0  1700.0  2200.0  2300.0  3100.0  3300.0
+1700.0  2100.0  2400.0  2900.0  3300.0  3400.0
+1600.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1500.0  2000.0  2400.0  2600.0  3100.0  3200.0
+1600.0  2000.0  2300.0  2500.0  2800.0  3000.0
+1500.0  1700.0  1800.0  2200.0  2800.0  2900.0
+1500.0  1700.0  1900.0  2100.0  2700.0  2800.0
+1600.0  2000.0  2300.0  2500.0  3000.0  3300.0
+1900.0  2300.0  2500.0  2800.0  3100.0  3200.0
+2200.0  2400.0  2600.0  3000.0  3200.0  3300.0
+2300.0  2500.0  2800.0  3100.0  3300.0  3400.0
+1900.0  2400.0  2700.0  3000.0  3400.0  3500.0
+1900.0  2400.0  2600.0  3000.0  3400.0  3500.0
+1800.0  2300.0  2700.0  3100.0  3400.0  3500.0
+1800.0  2300.0  2700.0  3000.0  3300.0  3400.0
+1400.0  1700.0  2200.0  2500.0  3200.0  3400.0
+1600.0  1900.0  2500.0  2600.0  3100.0  3300.0
+2000.0  2300.0  2600.0  2800.0  3300.0  3400.0
+1900.0  2200.0  2500.0  2800.0  3300.0  3400.0
+1700.0  2100.0  2400.0  2700.0  3300.0  3400.0
+1600.0  1700.0  2300.0  2500.0  3200.0  3400.0
+1600.0  1700.0  2300.0  2400.0  3300.0  3400.0
+1600.0  1800.0  2400.0  2600.0  3300.0  3400.0
+1500.0  1700.0  2300.0  2700.0  3300.0  3400.0
+1400.0  1800.0  2300.0  2400.0  3100.0  3400.0
+1500.0  2000.0  2300.0  2400.0  2900.0  3200.0
+1500.0  1900.0  2300.0  2400.0  2800.0  3200.0
+1300.0  1800.0  2200.0  2500.0  3000.0  3100.0
+1200.0  1700.0  2200.0  2300.0  3200.0  3300.0
+1200.0  1700.0  2200.0  2400.0  3200.0  3300.0
+1100.0  1700.0  2200.0  2400.0  3200.0  3300.0
+1100.0  1700.0  2300.0  2500.0  3100.0  3200.0
+1100.0  1700.0  2300.0  2600.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2600.0  3000.0  3200.0
+1300.0  1900.0  2300.0  2600.0  3000.0  3300.0
+1300.0  1800.0  2300.0  2600.0  3100.0  3300.0
+1400.0  2000.0  2500.0  2800.0  3200.0  3300.0
+1200.0  1600.0  2400.0  2700.0  3200.0  3300.0
+1500.0  1800.0  2300.0  2500.0  3100.0  3200.0
+1500.0  1600.0  2200.0  2600.0  3000.0  3200.0
+1500.0  1600.0  2200.0  2500.0  3000.0  3300.0
+1200.0  1600.0  2400.0  2600.0  3200.0  3400.0
+1000.0  2300.0  2800.0  2900.0  3100.0  3200.0
+900.0  1700.0  2700.0  2800.0  3200.0  3300.0
+1500.0  1700.0  2400.0  2500.0  3100.0  3200.0
+1500.0  1900.0  2400.0  2500.0  3100.0  3200.0
+1400.0  1900.0  2400.0  2500.0  2900.0  3100.0
+1600.0  2100.0  2400.0  2600.0  3000.0  3100.0
+1700.0  1900.0  2300.0  2500.0  3000.0  3100.0
+2100.0  2400.0  2600.0  2900.0  3100.0  3300.0
+2200.0  2400.0  2700.0  2900.0  3200.0  3300.0
+2100.0  2200.0  2700.0  2800.0  3100.0  3300.0
+2000.0  2100.0  2300.0  2600.0  3100.0  3300.0
+1800.0  2000.0  2100.0  2600.0  3100.0  3200.0
+1800.0  1900.0  2200.0  2500.0  2900.0  3000.0
+1800.0  1900.0  2300.0  2400.0  3000.0  3100.0
+1800.0  1900.0  2200.0  2400.0  3000.0  3100.0
+1800.0  2000.0  2200.0  2500.0  3100.0  3200.0
+1800.0  2000.0  2300.0  2800.0  3100.0  3200.0
+1800.0  2000.0  2400.0  2800.0  3100.0  3200.0
+1800.0  2000.0  2400.0  2800.0  3000.0  3100.0
+1700.0  1900.0  2300.0  2700.0  2900.0  3100.0
+1700.0  1900.0  2200.0  2700.0  2900.0  3100.0
+1600.0  1800.0  2000.0  2600.0  2800.0  3000.0
+1500.0  1700.0  2000.0  2500.0  2900.0  3100.0
+1700.0  1900.0  2200.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2300.0  2400.0  3100.0  3300.0
+1800.0  2000.0  2300.0  2500.0  3000.0  3100.0
+1800.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1400.0  1600.0  2100.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2000.0  2500.0  3000.0  3200.0
+1400.0  1800.0  2000.0  2400.0  3200.0  3300.0
+1200.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1100.0  1700.0  2100.0  2300.0  3000.0  3100.0
+1300.0  1500.0  1700.0  2000.0  2900.0  3100.0
+1600.0  1900.0  2200.0  2400.0  2900.0  3100.0
+1700.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1700.0  1800.0  2100.0  2500.0  3100.0  3300.0
+2000.0  2300.0  2500.0  2700.0  3100.0  3400.0
+1900.0  2200.0  2500.0  2600.0  3000.0  3300.0
+1900.0  2000.0  2300.0  2400.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2400.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2500.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2400.0  3000.0  3100.0
+1500.0  1600.0  2500.0  2600.0  2900.0  3300.0
+1500.0  1700.0  2500.0  2600.0  3100.0  3200.0
+1900.0  2300.0  2500.0  2800.0  3200.0  3300.0
+1400.0  1600.0  2000.0  2600.0  3000.0  3200.0
+1700.0  1900.0  2100.0  2600.0  3000.0  3100.0
+1800.0  1900.0  2400.0  2900.0  3100.0  3300.0
+1800.0  1900.0  2500.0  2900.0  3100.0  3300.0
+1600.0  1800.0  2100.0  2700.0  3000.0  3200.0
+1700.0  2000.0  2300.0  2700.0  2900.0  3200.0
+1600.0  2000.0  2400.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2300.0  2500.0  3300.0  3400.0
+1400.0  1600.0  2200.0  2400.0  3100.0  3300.0
+1500.0  1600.0  2200.0  2500.0  3200.0  3400.0
+1600.0  1700.0  2300.0  2400.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2500.0  3200.0  3300.0
+1600.0  1700.0  2200.0  2500.0  3200.0  3300.0
+1700.0  2100.0  2300.0  2400.0  3100.0  3300.0
+1600.0  2000.0  2400.0  2500.0  3000.0  3300.0
+1500.0  1800.0  2300.0  2400.0  2900.0  3200.0
+1600.0  2000.0  2400.0  2800.0  3200.0  3400.0
+1900.0  2200.0  2600.0  2800.0  3200.0  3400.0
+1900.0  2200.0  2500.0  2800.0  3100.0  3400.0
+1300.0  1800.0  2400.0  2600.0  3100.0  3400.0
+1300.0  1500.0  2400.0  2500.0  2900.0  3300.0
+1300.0  1700.0  2500.0  2600.0  3100.0  3200.0
+1300.0  1700.0  2600.0  2700.0  3200.0  3300.0
+1400.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1400.0  2000.0  2600.0  2700.0  3200.0  3300.0
+1700.0  1900.0  2100.0  2600.0  3200.0  3300.0
+1700.0  2000.0  2100.0  2300.0  3200.0  3300.0
+2000.0  2100.0  2400.0  2600.0  3200.0  3400.0
+2100.0  2200.0  2500.0  2700.0  3200.0  3400.0
+1800.0  1900.0  2500.0  2700.0  3200.0  3400.0
+1700.0  2000.0  2500.0  2700.0  3300.0  3400.0
+1400.0  1900.0  2500.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2500.0  2600.0  3100.0  3300.0
+1600.0  2000.0  2300.0  2600.0  3000.0  3200.0
+1600.0  1900.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1800.0  2300.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2100.0  2500.0  3000.0  3200.0
+1400.0  1800.0  2200.0  2500.0  2700.0  3100.0
+1400.0  1900.0  2300.0  2500.0  3100.0  3200.0
+1300.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1300.0  1900.0  2300.0  2500.0  3100.0  3200.0
+1800.0  2100.0  2500.0  2700.0  3000.0  3300.0
+1800.0  2100.0  2400.0  2700.0  3100.0  3300.0
+1900.0  2100.0  2500.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2300.0  2400.0  3200.0  3400.0
+1700.0  1800.0  2400.0  2500.0  3300.0  3400.0
+1900.0  2000.0  2700.0  2800.0  3200.0  3400.0
+1900.0  2000.0  2600.0  2900.0  3100.0  3300.0
+2000.0  2200.0  2800.0  2900.0  3300.0  3400.0
+2000.0  2100.0  2700.0  2800.0  3300.0  3400.0
+1900.0  2100.0  2400.0  2700.0  3300.0  3400.0
+1600.0  1900.0  2100.0  2500.0  3200.0  3300.0
+1400.0  1900.0  2100.0  2400.0  3200.0  3300.0
+1200.0  1900.0  2100.0  2400.0  3100.0  3200.0
+1200.0  1800.0  2100.0  2500.0  2900.0  3200.0
+1300.0  1700.0  1900.0  2400.0  2800.0  2900.0
+1900.0  2300.0  2600.0  3000.0  3200.0  3300.0
+1800.0  2300.0  2600.0  3000.0  3300.0  3400.0
+1800.0  2200.0  2500.0  2800.0  3300.0  3500.0
+1700.0  1900.0  2300.0  2400.0  3200.0  3400.0
+1800.0  1900.0  2400.0  2500.0  3100.0  3300.0
+2100.0  2200.0  2400.0  2500.0  3100.0  3300.0
+1800.0  2100.0  2500.0  2800.0  3100.0  3200.0
+2000.0  2300.0  2600.0  2700.0  3100.0  3300.0
+2100.0  2200.0  2500.0  2600.0  3100.0  3300.0
+2000.0  2200.0  2300.0  2500.0  3100.0  3300.0
+1800.0  1900.0  2100.0  2300.0  3200.0  3300.0
+1800.0  1900.0  2100.0  2400.0  3300.0  3400.0
+1700.0  1800.0  2200.0  2300.0  3300.0  3400.0
+1700.0  1800.0  2200.0  2300.0  3200.0  3400.0
+1600.0  1700.0  2200.0  2300.0  2900.0  3400.0
+1400.0  1600.0  2500.0  2600.0  3100.0  3200.0
+1300.0  1400.0  2400.0  2600.0  3000.0  3100.0
+1300.0  1500.0  2400.0  2500.0  3000.0  3200.0
+1300.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1300.0  1900.0  2400.0  2500.0  3100.0  3200.0
+1800.0  1900.0  2200.0  2400.0  3300.0  3400.0
+1000.0  1500.0  2500.0  2600.0  3200.0  3400.0
+1000.0  1700.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1700.0  2200.0  2600.0  3000.0  3200.0
+900.0  1800.0  2400.0  2600.0  3300.0  3400.0
+900.0  1800.0  2300.0  2400.0  3300.0  3400.0
+1000.0  1600.0  2300.0  2400.0  3300.0  3400.0
+1400.0  1900.0  2200.0  2600.0  3300.0  3400.0
+1500.0  1900.0  2300.0  2600.0  3300.0  3400.0
+1300.0  2000.0  2200.0  2500.0  3000.0  3200.0
+1100.0  1800.0  2300.0  2500.0  3200.0  3300.0
+1100.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1100.0  1900.0  2400.0  2700.0  3200.0  3300.0
+1300.0  2000.0  2200.0  2400.0  3200.0  3300.0
+1800.0  2100.0  2400.0  2800.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2700.0  3300.0  3400.0
+1700.0  2000.0  2300.0  2700.0  3200.0  3400.0
+1200.0  1600.0  2500.0  2600.0  3200.0  3400.0
+1100.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1500.0  1600.0  2400.0  2700.0  2900.0  3200.0
+1500.0  1800.0  2500.0  2700.0  3100.0  3400.0
+1600.0  1900.0  2600.0  2800.0  3100.0  3300.0
+1700.0  1800.0  2600.0  2700.0  3000.0  3300.0
+1700.0  1800.0  2500.0  2600.0  2900.0  3200.0
+1700.0  1800.0  2500.0  2600.0  3000.0  3300.0
+1600.0  1700.0  2500.0  2600.0  3000.0  3300.0
+1700.0  2000.0  2400.0  2700.0  3100.0  3400.0
+1700.0  1800.0  2400.0  2600.0  2900.0  3200.0
+1800.0  1900.0  2500.0  2600.0  2900.0  3200.0
+1700.0  1800.0  2200.0  2500.0  2700.0  3200.0
+1700.0  1800.0  2300.0  2500.0  2800.0  3200.0
+1500.0  1600.0  2000.0  2400.0  2600.0  2900.0
+1200.0  1300.0  2100.0  2400.0  2600.0  3200.0
+1700.0  2200.0  2500.0  2900.0  3200.0  3400.0
+1700.0  2200.0  2600.0  2900.0  3400.0  3500.0
+1700.0  2100.0  2700.0  2900.0  3400.0  3500.0
+1500.0  1800.0  2400.0  2600.0  3100.0  3300.0
+1100.0  1700.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1700.0  2600.0  2700.0  3200.0  3400.0
+1400.0  1900.0  2600.0  2800.0  3200.0  3300.0
+1600.0  2000.0  2500.0  2900.0  3300.0  3400.0
+1500.0  1700.0  2500.0  2700.0  3100.0  3300.0
+1800.0  2000.0  2500.0  2700.0  2900.0  3300.0
+1900.0  2000.0  2600.0  2700.0  2900.0  3300.0
+1900.0  2100.0  2400.0  2700.0  2900.0  3200.0
+1900.0  2000.0  2500.0  2700.0  3000.0  3300.0
+1900.0  2000.0  2400.0  2700.0  3000.0  3300.0
+1700.0  1900.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1900.0  2500.0  2600.0  3200.0  3500.0
+1900.0  2100.0  2600.0  2900.0  3200.0  3400.0
+2100.0  2300.0  2700.0  2900.0  3200.0  3300.0
+1600.0  2000.0  2200.0  2400.0  3100.0  3200.0
+1700.0  1900.0  2200.0  2400.0  2900.0  3100.0
+1700.0  1800.0  2100.0  2400.0  2800.0  3200.0
+1900.0  2200.0  2500.0  2700.0  3000.0  3200.0
+1900.0  2300.0  2600.0  2700.0  3100.0  3200.0
+1800.0  2400.0  2600.0  2900.0  3200.0  3300.0
+1800.0  2300.0  2500.0  2900.0  3200.0  3300.0
+1600.0  1800.0  2500.0  2600.0  3300.0  3400.0
+1500.0  1700.0  2200.0  2400.0  2900.0  3200.0
+1500.0  1600.0  2200.0  2300.0  2800.0  3200.0
+1400.0  1500.0  2100.0  2200.0  2800.0  3200.0
+1400.0  1500.0  2100.0  2300.0  2800.0  3200.0
+1400.0  1500.0  2200.0  2400.0  2700.0  3100.0
+1700.0  1900.0  2400.0  2800.0  3100.0  3200.0
+1700.0  1800.0  2400.0  2700.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2700.0  2900.0  3300.0
+2000.0  2100.0  2400.0  2700.0  3000.0  3300.0
+1400.0  1600.0  2500.0  2700.0  3100.0  3400.0
+1000.0  1600.0  2300.0  2400.0  3100.0  3200.0
+1100.0  1700.0  2400.0  2500.0  3200.0  3300.0
+1200.0  1700.0  2300.0  2400.0  3100.0  3200.0
+2000.0  2100.0  2400.0  2500.0  3100.0  3300.0
+1900.0  2000.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1800.0  2300.0  2500.0  3200.0  3300.0
+1400.0  1600.0  2300.0  2400.0  3100.0  3300.0
+1300.0  1500.0  2300.0  2500.0  3000.0  3300.0
+1300.0  1500.0  2300.0  2500.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2600.0  3100.0  3200.0
+1800.0  1900.0  2400.0  2500.0  3000.0  3200.0
+1900.0  2400.0  2600.0  3000.0  3200.0  3300.0
+1400.0  1500.0  2400.0  2600.0  2900.0  3300.0
+1400.0  1500.0  2200.0  2600.0  2800.0  3300.0
+1400.0  1500.0  2200.0  2500.0  2800.0  3200.0
+1400.0  1500.0  2300.0  2500.0  3000.0  3300.0
+1600.0  2000.0  2400.0  2700.0  3200.0  3400.0
+1700.0  2200.0  2600.0  2800.0  3100.0  3300.0
+1800.0  2100.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2200.0  2500.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2300.0  3000.0  3300.0
+1600.0  1700.0  2200.0  2500.0  3200.0  3400.0
+1600.0  1800.0  2300.0  2400.0  3100.0  3300.0
+1700.0  1800.0  2200.0  2400.0  3000.0  3300.0
+1700.0  1800.0  2200.0  2300.0  3000.0  3200.0
+1700.0  1800.0  2200.0  2300.0  3100.0  3300.0
+1700.0  2000.0  2200.0  2600.0  3200.0  3300.0
+1800.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1600.0  1700.0  2100.0  2400.0  2900.0  3200.0
+1500.0  1800.0  2300.0  2700.0  3000.0  3300.0
+1500.0  1800.0  2200.0  2600.0  3000.0  3300.0
+1700.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2000.0  2600.0  2800.0  3200.0  3400.0
+1800.0  1900.0  2500.0  2800.0  3100.0  3300.0
+1600.0  1800.0  2500.0  2600.0  3000.0  3300.0
+1200.0  1500.0  2500.0  2700.0  3100.0  3200.0
+1100.0  1900.0  2500.0  2600.0  3100.0  3200.0
+1200.0  1900.0  2400.0  2500.0  3100.0  3200.0
+1500.0  1700.0  2100.0  2200.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2200.0  3300.0  3400.0
+1500.0  1600.0  1800.0  2000.0  3300.0  3400.0
+1400.0  1600.0  1800.0  1900.0  3300.0  3400.0
+1400.0  1600.0  2400.0  2600.0  3000.0  3400.0
+1400.0  1800.0  2500.0  2600.0  3100.0  3200.0
+1500.0  1700.0  2400.0  2700.0  3100.0  3300.0
+1500.0  1800.0  2500.0  2700.0  3000.0  3300.0
+1400.0  1500.0  2400.0  2600.0  3000.0  3300.0
+1200.0  1400.0  2300.0  2400.0  3000.0  3200.0
+1200.0  1600.0  2300.0  2400.0  3100.0  3200.0
+1400.0  2000.0  2400.0  2700.0  3100.0  3300.0
+1600.0  1900.0  2300.0  2700.0  3100.0  3200.0
+1500.0  1900.0  2300.0  2700.0  3100.0  3200.0
+1200.0  1400.0  2300.0  2500.0  3100.0  3300.0
+1800.0  1900.0  2400.0  2600.0  3000.0  3100.0
+1800.0  1900.0  2500.0  2600.0  2900.0  3100.0
+1600.0  2000.0  2400.0  2700.0  3000.0  3300.0
+1600.0  1900.0  2400.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2500.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2400.0  2500.0  2900.0  3300.0
+1700.0  1800.0  2300.0  2500.0  2900.0  3200.0
+1700.0  1800.0  2400.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2500.0  3000.0  3200.0
+1700.0  2000.0  2300.0  2500.0  3000.0  3200.0
+1800.0  2000.0  2300.0  2500.0  3000.0  3200.0
+1900.0  2100.0  2300.0  2600.0  3000.0  3200.0
+1900.0  2100.0  2400.0  2600.0  3000.0  3300.0
+2000.0  2100.0  2300.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2300.0  2600.0  3100.0  3300.0
+1700.0  2100.0  2500.0  2700.0  3200.0  3400.0
+1700.0  1900.0  2300.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2400.0  2900.0  3300.0
+1800.0  1900.0  2300.0  2500.0  3000.0  3300.0
+1800.0  2000.0  2200.0  2500.0  2900.0  3200.0
+1900.0  2200.0  2400.0  2600.0  2900.0  3200.0
+1700.0  2100.0  2600.0  2800.0  3100.0  3300.0
+1800.0  2300.0  2700.0  2900.0  3200.0  3300.0
+2000.0  2300.0  2800.0  2900.0  3100.0  3300.0
+2100.0  2200.0  2600.0  2800.0  3200.0  3300.0
+1800.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2600.0  3100.0  3200.0
+1800.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1600.0  1800.0  2000.0  3100.0  3300.0
+1300.0  1700.0  2300.0  2400.0  3100.0  3200.0
+1500.0  1700.0  2300.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2300.0  2500.0  2900.0  3100.0
+1500.0  1700.0  2300.0  2500.0  2900.0  3100.0
+1500.0  1700.0  2300.0  2500.0  2800.0  3000.0
+1500.0  1600.0  2300.0  2500.0  2800.0  3200.0
+1400.0  1500.0  2300.0  2600.0  3000.0  3200.0
+1200.0  1600.0  2400.0  2500.0  3000.0  3300.0
+1400.0  1600.0  2200.0  2500.0  2900.0  3200.0
+1500.0  1900.0  2300.0  2600.0  2900.0  3200.0
+1400.0  1800.0  2400.0  2700.0  3200.0  3400.0
+1500.0  1900.0  2400.0  2700.0  3200.0  3400.0
+1700.0  2100.0  2400.0  2800.0  3000.0  3300.0
+1700.0  2000.0  2500.0  2700.0  3100.0  3400.0
+1800.0  1900.0  2400.0  2800.0  3200.0  3300.0
+1800.0  1900.0  2300.0  2900.0  3200.0  3300.0
+1800.0  1900.0  2500.0  2800.0  3200.0  3300.0
+1700.0  1800.0  2400.0  2800.0  3200.0  3300.0
+1700.0  1800.0  2400.0  2700.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2600.0  3000.0  3300.0
+1600.0  1700.0  2200.0  2500.0  2900.0  3300.0
+1500.0  1600.0  2300.0  2500.0  3000.0  3300.0
+1500.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1500.0  2000.0  2400.0  2800.0  3200.0  3300.0
+1400.0  1800.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1900.0  2400.0  2700.0  3200.0  3400.0
+1300.0  1700.0  2300.0  2500.0  3200.0  3400.0
+1100.0  1700.0  2300.0  2400.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2200.0  3300.0  3400.0
+1900.0  2300.0  2600.0  2800.0  3200.0  3400.0
+1900.0  2400.0  2700.0  2800.0  3300.0  3400.0
+2000.0  2300.0  2700.0  2900.0  3400.0  3500.0
+1900.0  2300.0  2700.0  2900.0  3400.0  3500.0
+1900.0  2100.0  2800.0  2900.0  3300.0  3400.0
+1700.0  1800.0  2700.0  2800.0  3100.0  3300.0
+1500.0  1700.0  2700.0  2800.0  3200.0  3300.0
+1500.0  1600.0  2600.0  2700.0  3000.0  3300.0
+1400.0  1600.0  2600.0  2800.0  3000.0  3200.0
+1200.0  1400.0  2600.0  2700.0  3000.0  3200.0
+1000.0  1500.0  2600.0  2800.0  3200.0  3400.0
+1100.0  1300.0  2500.0  2800.0  3000.0  3200.0
+1500.0  1600.0  2500.0  2600.0  3000.0  3300.0
+1400.0  1500.0  2300.0  2600.0  2800.0  3200.0
+1400.0  1600.0  2200.0  2600.0  2800.0  3100.0
+1500.0  1600.0  2300.0  2700.0  2900.0  3200.0
+1400.0  1500.0  2500.0  2600.0  3100.0  3400.0
+1400.0  1500.0  2400.0  2600.0  2800.0  3300.0
+1400.0  1600.0  2400.0  2600.0  2800.0  3200.0
+1300.0  1600.0  2300.0  2600.0  2900.0  3300.0
+1700.0  2200.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2300.0  2600.0  2700.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2600.0  3100.0  3200.0
+1800.0  2300.0  2500.0  2600.0  3200.0  3300.0
+1900.0  2400.0  2500.0  2800.0  3300.0  3400.0
+1800.0  2000.0  2600.0  2800.0  3300.0  3400.0
+1600.0  1900.0  2400.0  2800.0  3200.0  3300.0
+1700.0  1800.0  2600.0  2800.0  3000.0  3300.0
+1900.0  2000.0  2600.0  2800.0  3200.0  3300.0
+2000.0  2100.0  2700.0  2800.0  3200.0  3400.0
+2000.0  2100.0  2600.0  2800.0  3300.0  3400.0
+1600.0  1700.0  2300.0  2600.0  2900.0  3300.0
+1400.0  1600.0  2400.0  2500.0  2800.0  3200.0
+1800.0  1900.0  2500.0  2700.0  3000.0  3400.0
+1900.0  2000.0  2600.0  2700.0  3000.0  3300.0
+1700.0  2000.0  2400.0  2600.0  2900.0  3200.0
+1500.0  1600.0  2300.0  2600.0  3000.0  3300.0
+1500.0  1600.0  2400.0  2600.0  2900.0  3300.0
+1400.0  1500.0  2300.0  2700.0  3000.0  3300.0
+1600.0  1800.0  2500.0  2600.0  2900.0  3200.0
+2000.0  2100.0  2400.0  2600.0  3000.0  3200.0
+1800.0  2000.0  2300.0  2400.0  3200.0  3300.0
+1600.0  1900.0  2300.0  2400.0  3200.0  3300.0
+1500.0  1800.0  2400.0  2700.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2400.0  3000.0  3200.0
+2000.0  2200.0  2400.0  2500.0  3200.0  3300.0
+2200.0  2300.0  2600.0  2700.0  3200.0  3300.0
+2100.0  2200.0  2400.0  2700.0  3000.0  3200.0
+2100.0  2200.0  2500.0  2700.0  3000.0  3200.0
+2200.0  2300.0  2600.0  2800.0  3000.0  3300.0
+1900.0  2200.0  2600.0  2700.0  3000.0  3300.0
+1700.0  1800.0  2500.0  2700.0  2800.0  3200.0
+1700.0  1800.0  2600.0  2700.0  3000.0  3200.0
+1700.0  1900.0  2500.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2700.0  3300.0  3400.0
+1800.0  2000.0  2400.0  2600.0  3100.0  3200.0
+1700.0  2200.0  2300.0  2500.0  3200.0  3300.0
+1700.0  2200.0  2300.0  2600.0  3100.0  3200.0
+1600.0  1700.0  2400.0  2600.0  3300.0  3400.0
+1600.0  1700.0  2400.0  2500.0  3300.0  3400.0
+1900.0  2100.0  2500.0  2800.0  3000.0  3100.0
+1800.0  2100.0  2500.0  2800.0  3000.0  3100.0
+1800.0  2100.0  2600.0  2800.0  3100.0  3200.0
+1800.0  2000.0  2500.0  2800.0  3100.0  3200.0
+1900.0  2100.0  2500.0  2600.0  3000.0  3200.0
+1800.0  1900.0  2600.0  2800.0  3200.0  3400.0
+1500.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1100.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1100.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1300.0  1500.0  2200.0  2400.0  2900.0  3300.0
+1600.0  1700.0  2300.0  2500.0  2900.0  3300.0
+1600.0  1700.0  2400.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2500.0  2600.0  3100.0  3300.0
+1900.0  2000.0  2500.0  2700.0  3100.0  3200.0
+2100.0  2200.0  2400.0  2600.0  3100.0  3400.0
+2100.0  2200.0  2500.0  2600.0  3000.0  3400.0
+1900.0  2100.0  2400.0  2700.0  3000.0  3100.0
+1600.0  1800.0  2200.0  2400.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2300.0  2900.0  3300.0
+1600.0  1700.0  2100.0  2300.0  2800.0  3100.0
+2200.0  2300.0  2600.0  2800.0  3100.0  3300.0
+2200.0  2300.0  2700.0  2800.0  3100.0  3400.0
+2000.0  2100.0  2600.0  2800.0  3100.0  3400.0
+1700.0  1800.0  2400.0  2700.0  2900.0  3200.0
+1600.0  1800.0  2400.0  2700.0  3100.0  3200.0
+1600.0  1800.0  2300.0  2400.0  3000.0  3200.0
+1800.0  1900.0  2400.0  2600.0  3100.0  3300.0
+1900.0  2000.0  2300.0  2600.0  2900.0  3200.0
+1900.0  2100.0  2300.0  2700.0  2800.0  3000.0
+1800.0  2000.0  2600.0  2700.0  3000.0  3300.0
+1800.0  1900.0  2400.0  2600.0  2900.0  3300.0
+1700.0  1800.0  2300.0  2400.0  2900.0  3300.0
+1600.0  1700.0  2100.0  2500.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2600.0  3100.0  3200.0
+1500.0  1700.0  2200.0  2500.0  2900.0  3300.0
+1500.0  1600.0  2300.0  2400.0  2800.0  3300.0
+1400.0  1600.0  2300.0  2400.0  3000.0  3300.0
+1500.0  2000.0  2500.0  2800.0  3200.0  3300.0
+1300.0  1500.0  2600.0  2700.0  3100.0  3300.0
+1200.0  1400.0  1700.0  1900.0  3100.0  3300.0
+1200.0  1700.0  1900.0  2300.0  3200.0  3300.0
+1200.0  1900.0  2000.0  2300.0  3200.0  3300.0
+1200.0  2000.0  2100.0  2500.0  3300.0  3400.0
+1200.0  2000.0  2200.0  2600.0  3300.0  3400.0
+1200.0  2000.0  2300.0  2400.0  3200.0  3300.0
+1000.0  1900.0  2300.0  2500.0  3200.0  3300.0
+1200.0  1800.0  2200.0  2500.0  3100.0  3200.0
+1400.0  1600.0  2300.0  2500.0  3200.0  3300.0
+1500.0  1600.0  2500.0  2700.0  2900.0  3200.0
+1600.0  1900.0  2400.0  2800.0  3100.0  3300.0
+1700.0  1800.0  2400.0  2800.0  3100.0  3200.0
+1700.0  1800.0  2500.0  2800.0  3100.0  3200.0
+1500.0  1800.0  2400.0  2500.0  2900.0  3100.0
+1500.0  1600.0  2400.0  2500.0  2900.0  3200.0
+1300.0  1500.0  2200.0  2500.0  2800.0  3100.0
+1300.0  1400.0  2000.0  2400.0  2600.0  2900.0
+1400.0  1500.0  2100.0  2500.0  2700.0  3100.0
+1500.0  2000.0  2300.0  2600.0  3000.0  3200.0
+1700.0  2100.0  2400.0  2600.0  2900.0  3100.0
+1400.0  1500.0  2300.0  2600.0  3000.0  3300.0
+1500.0  1700.0  2200.0  2300.0  3200.0  3300.0
+1400.0  1600.0  2000.0  2400.0  3100.0  3300.0
+1500.0  1700.0  2000.0  2100.0  3100.0  3300.0
+1600.0  1900.0  2200.0  2500.0  2900.0  3200.0
+1500.0  1600.0  2200.0  2400.0  2800.0  3200.0
+1500.0  1600.0  2100.0  2500.0  3000.0  3300.0
+1500.0  1600.0  2000.0  2500.0  2900.0  3300.0
+1500.0  1600.0  2100.0  2500.0  2900.0  3200.0
+1500.0  1600.0  2200.0  2700.0  2800.0  3100.0
+1300.0  1400.0  2200.0  2600.0  3000.0  3200.0
+1400.0  1900.0  2400.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2500.0  2600.0  3000.0  3200.0
+1500.0  1700.0  2300.0  2500.0  2800.0  3200.0
+1700.0  1800.0  2200.0  2400.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2300.0  3000.0  3300.0
+1600.0  1700.0  2000.0  2400.0  3000.0  3200.0
+1700.0  1800.0  2300.0  2600.0  2900.0  3200.0
+1500.0  2000.0  2300.0  2600.0  3100.0  3400.0
+1400.0  1900.0  2500.0  2700.0  3100.0  3300.0
+1400.0  1700.0  2600.0  2700.0  3100.0  3300.0
+1500.0  1600.0  2300.0  2600.0  2800.0  3200.0
+1700.0  1800.0  2300.0  2500.0  3100.0  3400.0
+1500.0  1600.0  2200.0  2300.0  3100.0  3300.0
+1400.0  1500.0  2200.0  2400.0  3100.0  3200.0
+1400.0  1600.0  2200.0  2400.0  3000.0  3100.0
+1700.0  2100.0  2300.0  2700.0  3100.0  3200.0
+1900.0  2300.0  2500.0  2700.0  3100.0  3200.0
+1900.0  2300.0  2600.0  2800.0  3100.0  3300.0
+1900.0  2400.0  2600.0  2900.0  3200.0  3300.0
+1900.0  2300.0  2600.0  2800.0  3300.0  3400.0
+1800.0  2400.0  2600.0  2800.0  3300.0  3400.0
+1600.0  1800.0  2600.0  2700.0  3000.0  3300.0
+1600.0  1700.0  2600.0  2700.0  2900.0  3200.0
+1500.0  1600.0  2500.0  2700.0  3000.0  3300.0
+1300.0  1400.0  2400.0  2700.0  2900.0  3300.0
+1300.0  1400.0  2300.0  2700.0  2800.0  3100.0
+1300.0  1400.0  2500.0  2800.0  3000.0  3300.0
+1500.0  1700.0  2400.0  2500.0  2800.0  3300.0
+1900.0  2000.0  2500.0  2600.0  3000.0  3200.0
+1800.0  2000.0  2400.0  2500.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2300.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2400.0  2800.0  3200.0
+1600.0  1700.0  2200.0  2400.0  2800.0  3200.0
+1500.0  1600.0  2200.0  2400.0  2700.0  3300.0
+1400.0  1500.0  2200.0  2400.0  2900.0  3200.0
+1600.0  1700.0  2300.0  2500.0  2700.0  3000.0
+1600.0  1700.0  2200.0  2500.0  2700.0  3000.0
+1700.0  1900.0  2200.0  2500.0  2800.0  3100.0
+1900.0  2000.0  2300.0  2500.0  2900.0  3100.0
+1900.0  2100.0  2300.0  2500.0  2900.0  3200.0
+1900.0  2100.0  2300.0  2500.0  3100.0  3300.0
+2000.0  2200.0  2600.0  2800.0  3000.0  3200.0
+1900.0  2200.0  2500.0  2700.0  2900.0  3200.0
+2100.0  2300.0  2600.0  2800.0  3100.0  3300.0
+2100.0  2300.0  2600.0  2700.0  3000.0  3200.0
+2100.0  2200.0  2500.0  2600.0  3000.0  3200.0
+1500.0  1600.0  2300.0  2400.0  2900.0  3200.0
+1400.0  1500.0  2100.0  2400.0  2800.0  3100.0
+1300.0  1600.0  2100.0  2400.0  3100.0  3200.0
+1300.0  1400.0  2300.0  2600.0  2800.0  3200.0
+1400.0  1500.0  2200.0  2500.0  2700.0  3200.0
+1400.0  1500.0  2300.0  2500.0  2700.0  3200.0
+1500.0  1600.0  2400.0  2500.0  2800.0  3200.0
+1600.0  1700.0  2400.0  2500.0  2900.0  3200.0
+1700.0  1800.0  2400.0  2500.0  2900.0  3100.0
+1800.0  1900.0  2400.0  2600.0  3000.0  3200.0
+2100.0  2200.0  2700.0  2900.0  3200.0  3300.0
+1800.0  2100.0  2500.0  2900.0  3100.0  3300.0
+1700.0  1800.0  2500.0  2800.0  2900.0  3300.0
+1200.0  1600.0  2100.0  2400.0  3000.0  3200.0
+1600.0  1700.0  2100.0  2600.0  2900.0  3000.0
+1600.0  1700.0  2200.0  2700.0  2900.0  3000.0
+1600.0  1800.0  2200.0  2500.0  2900.0  3000.0
+1700.0  1800.0  2300.0  2500.0  2900.0  3100.0
+1700.0  1900.0  2300.0  2600.0  2900.0  3100.0
+1500.0  1700.0  2000.0  2600.0  2900.0  3100.0
+1400.0  1600.0  1800.0  2600.0  3000.0  3100.0
+1300.0  1500.0  1700.0  2700.0  3100.0  3200.0
+1300.0  1700.0  2400.0  2700.0  3100.0  3300.0
+1200.0  1600.0  2400.0  2600.0  2900.0  3200.0
+1300.0  1400.0  2000.0  2700.0  2800.0  3000.0
+1400.0  1500.0  2000.0  2600.0  2800.0  3000.0
+1500.0  1700.0  2100.0  2600.0  2800.0  3000.0
+1600.0  1800.0  2200.0  2700.0  2800.0  3000.0
+1600.0  1800.0  2100.0  2700.0  2900.0  3100.0
+1500.0  1900.0  2300.0  2700.0  3000.0  3100.0
+1500.0  1900.0  2300.0  2700.0  3000.0  3200.0
+1500.0  2000.0  2300.0  2700.0  3000.0  3200.0
+1800.0  2100.0  2300.0  2700.0  3100.0  3300.0
+1500.0  2000.0  2300.0  2600.0  3000.0  3100.0
+1500.0  2100.0  2300.0  2700.0  3100.0  3200.0
+1600.0  2100.0  2200.0  2700.0  3100.0  3200.0
+1500.0  2100.0  2200.0  2600.0  3100.0  3200.0
+1400.0  2300.0  2500.0  2700.0  3100.0  3200.0
+1700.0  2100.0  2300.0  2700.0  2900.0  3100.0
+1500.0  1800.0  2300.0  2700.0  3000.0  3100.0
+1500.0  1700.0  2300.0  2700.0  3000.0  3100.0
+1500.0  1600.0  2100.0  2700.0  3000.0  3100.0
+1400.0  1500.0  1900.0  2600.0  3100.0  3200.0
+1200.0  1300.0  1900.0  2600.0  2900.0  3100.0
+1100.0  1200.0  1800.0  2700.0  3000.0  3100.0
+1200.0  1300.0  1800.0  2700.0  3000.0  3100.0
+1200.0  1400.0  1900.0  2700.0  3000.0  3100.0
+1300.0  1500.0  1800.0  2600.0  3000.0  3100.0
+1200.0  1400.0  2300.0  2700.0  2900.0  3100.0
+1300.0  1400.0  2200.0  2700.0  2800.0  3100.0
+1300.0  1500.0  2000.0  2600.0  2900.0  3100.0
+1300.0  1500.0  2100.0  2700.0  2900.0  3100.0
+1400.0  1800.0  2100.0  2600.0  2800.0  3000.0
+1400.0  1800.0  2100.0  2500.0  2900.0  3100.0
+1700.0  2000.0  2500.0  2800.0  3000.0  3200.0
+1900.0  2000.0  2700.0  2800.0  3100.0  3400.0
+1900.0  2100.0  2600.0  2800.0  3100.0  3300.0
+1600.0  2100.0  2400.0  2700.0  3200.0  3400.0
+1700.0  2000.0  2300.0  2500.0  2800.0  3200.0
+1500.0  1700.0  2100.0  2300.0  3000.0  3200.0
+1400.0  1900.0  2200.0  2500.0  2900.0  3200.0
+1400.0  1900.0  2300.0  2500.0  2700.0  3100.0
+1300.0  1500.0  2100.0  2700.0  2800.0  3100.0
+1300.0  1500.0  2000.0  2600.0  2800.0  3100.0
+1300.0  1400.0  2100.0  2600.0  2800.0  3000.0
+1300.0  1400.0  2000.0  2600.0  2800.0  3000.0
+1200.0  1300.0  2000.0  2700.0  2800.0  3000.0
+1200.0  1400.0  2300.0  2600.0  2900.0  3200.0
+1300.0  1600.0  2300.0  2700.0  2900.0  3200.0
+1600.0  1900.0  2300.0  2800.0  3100.0  3200.0
+1700.0  1900.0  2300.0  2800.0  3000.0  3200.0
+1700.0  1900.0  2100.0  2600.0  2900.0  3000.0
+1700.0  1900.0  2400.0  2600.0  2800.0  3100.0
+1700.0  2100.0  2400.0  2500.0  2800.0  3100.0
+1700.0  2000.0  2400.0  2500.0  2900.0  3100.0
+1900.0  2200.0  2400.0  2600.0  3000.0  3200.0
+1700.0  2000.0  2400.0  2700.0  3000.0  3100.0
+1500.0  1900.0  2300.0  2600.0  3000.0  3100.0
+1500.0  1600.0  2100.0  2600.0  2900.0  3200.0
+1400.0  1600.0  1800.0  2300.0  2800.0  2900.0
+1400.0  1600.0  1700.0  2500.0  3200.0  3300.0
+1400.0  1600.0  1800.0  2400.0  3200.0  3300.0
+1400.0  1700.0  1900.0  2200.0  3100.0  3200.0
+1300.0  1700.0  1900.0  2300.0  3100.0  3200.0
+1100.0  1600.0  2000.0  2300.0  3000.0  3100.0
+1500.0  1900.0  2500.0  2800.0  3200.0  3300.0
+1800.0  2000.0  2300.0  2800.0  3000.0  3100.0
+1800.0  1900.0  2300.0  2700.0  2900.0  3200.0
+1700.0  1900.0  2300.0  2600.0  2800.0  3100.0
+1700.0  1900.0  2100.0  2500.0  2700.0  3000.0
+1700.0  1900.0  2100.0  2600.0  2800.0  3000.0
+1700.0  1900.0  2100.0  2700.0  2900.0  3100.0
+1700.0  1900.0  2500.0  2800.0  3000.0  3300.0
+1400.0  1600.0  1900.0  2600.0  2900.0  3000.0
+1500.0  1600.0  2000.0  2200.0  3200.0  3300.0
+1300.0  1500.0  1700.0  2600.0  3100.0  3200.0
+1300.0  1500.0  1700.0  2700.0  3000.0  3100.0
+1500.0  1700.0  2300.0  2700.0  3000.0  3200.0
+1700.0  2000.0  2500.0  2800.0  3100.0  3200.0
+1200.0  1300.0  1800.0  2600.0  3000.0  3100.0
+1300.0  1600.0  2000.0  2400.0  3000.0  3200.0
+1500.0  1600.0  2000.0  2600.0  3200.0  3300.0
+1600.0  1700.0  2100.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2700.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2700.0  3200.0  3300.0
+1600.0  1900.0  2100.0  2700.0  3200.0  3300.0
+1100.0  1800.0  2200.0  2400.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2800.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2700.0  3000.0  3100.0
+1500.0  1800.0  2200.0  2800.0  3100.0  3200.0
+1600.0  1900.0  2200.0  2800.0  3100.0  3200.0
+1600.0  1900.0  2100.0  2700.0  3100.0  3200.0
+1500.0  1900.0  2100.0  2600.0  3100.0  3200.0
+1700.0  2100.0  2400.0  2700.0  3000.0  3300.0
+1900.0  2400.0  2700.0  2900.0  3200.0  3300.0
+1700.0  2200.0  2700.0  2900.0  3200.0  3300.0
+1700.0  2100.0  2700.0  2900.0  3200.0  3300.0
+1700.0  2200.0  2600.0  2900.0  3200.0  3300.0
+1800.0  2400.0  2600.0  2800.0  3100.0  3200.0
+1800.0  2400.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2300.0  2400.0  2700.0  3100.0  3200.0
+1600.0  2300.0  2500.0  2700.0  3100.0  3200.0
+1500.0  2200.0  2400.0  2600.0  3100.0  3200.0
+1600.0  2200.0  2400.0  2600.0  3100.0  3200.0
+1500.0  2200.0  2500.0  2700.0  3100.0  3200.0
+1500.0  2200.0  2400.0  2600.0  3000.0  3100.0
+1600.0  2200.0  2400.0  2700.0  3000.0  3100.0
+1500.0  2100.0  2400.0  2700.0  3000.0  3100.0
+1400.0  1800.0  2100.0  2400.0  3200.0  3300.0
+1200.0  1300.0  2100.0  2800.0  3000.0  3200.0
+1300.0  1400.0  2100.0  2700.0  3000.0  3200.0
+1500.0  1700.0  2200.0  2800.0  3000.0  3100.0
+1800.0  2200.0  2400.0  2600.0  3000.0  3200.0
+1700.0  1900.0  2400.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2500.0  2800.0  3000.0  3200.0
+1600.0  1800.0  2500.0  2700.0  3000.0  3200.0
+1600.0  1700.0  2300.0  2700.0  2900.0  3100.0
+1500.0  1700.0  2100.0  2700.0  3000.0  3100.0
+1500.0  1600.0  2000.0  2600.0  2900.0  3000.0
+1500.0  1600.0  1900.0  2600.0  3000.0  3100.0
+1500.0  1700.0  2000.0  2500.0  3000.0  3100.0
+1500.0  1700.0  2000.0  2500.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2600.0  3000.0  3100.0
+1500.0  1800.0  2000.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2500.0  2800.0  3100.0  3300.0
+1800.0  2000.0  2600.0  2900.0  3200.0  3300.0
+1800.0  2000.0  2500.0  2900.0  3100.0  3300.0
+1400.0  1600.0  1900.0  2600.0  3000.0  3100.0
+1400.0  1600.0  1900.0  2700.0  3000.0  3100.0
+1500.0  1700.0  2300.0  2800.0  3000.0  3200.0
+1700.0  2000.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2300.0  2600.0  2800.0  3200.0  3300.0
+1800.0  2100.0  2600.0  3000.0  3300.0  3400.0
+1800.0  2100.0  2600.0  3000.0  3200.0  3400.0
+1600.0  1800.0  2300.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2100.0  2600.0  3100.0  3200.0
+1100.0  1400.0  2100.0  2800.0  3100.0  3200.0
+1200.0  1700.0  2200.0  2400.0  3000.0  3200.0
+1500.0  2100.0  2500.0  2800.0  3200.0  3400.0
+1500.0  2000.0  2200.0  2400.0  3100.0  3300.0
+1400.0  1900.0  2200.0  2300.0  3000.0  3200.0
+1500.0  1800.0  2200.0  2400.0  3000.0  3200.0
+1200.0  1600.0  2300.0  2500.0  3100.0  3200.0
+1300.0  1900.0  2200.0  2700.0  3200.0  3300.0
+1100.0  1300.0  2000.0  2700.0  3100.0  3200.0
+1400.0  1500.0  2400.0  2700.0  2900.0  3300.0
+1500.0  1800.0  2500.0  2700.0  3000.0  3100.0
+1500.0  1700.0  2500.0  2800.0  3000.0  3200.0
+1400.0  1600.0  2200.0  2400.0  2700.0  3200.0
+1300.0  1400.0  2000.0  2400.0  2600.0  3000.0
+1200.0  1300.0  2100.0  2500.0  2700.0  3100.0
+1800.0  2100.0  2400.0  2600.0  2800.0  3100.0
+1800.0  2100.0  2400.0  2600.0  2800.0  3000.0
+1900.0  2200.0  2500.0  2700.0  2900.0  3100.0
+1900.0  2300.0  2500.0  2800.0  3000.0  3100.0
+1900.0  2400.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2400.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2400.0  2600.0  2700.0  3100.0  3200.0
+1800.0  2400.0  2600.0  2800.0  3200.0  3300.0
+1900.0  2400.0  2600.0  2800.0  3100.0  3300.0
+1900.0  2400.0  2600.0  2800.0  3200.0  3300.0
+1700.0  2400.0  2600.0  2800.0  3200.0  3300.0
+1700.0  2200.0  2600.0  2800.0  3200.0  3300.0
+2000.0  2200.0  2800.0  3000.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2700.0  3100.0  3300.0
+1900.0  2100.0  2400.0  2800.0  3000.0  3200.0
+1900.0  2100.0  2300.0  2800.0  3000.0  3200.0
+1800.0  2100.0  2300.0  2700.0  3000.0  3200.0
+1600.0  2000.0  2200.0  2700.0  3000.0  3100.0
+1600.0  2000.0  2200.0  2500.0  3000.0  3100.0
+1700.0  2000.0  2200.0  2700.0  3000.0  3200.0
+1700.0  2000.0  2200.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2200.0  2700.0  3100.0  3200.0
+1500.0  1900.0  2200.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2300.0  2800.0  3000.0  3100.0
+1600.0  1900.0  2200.0  2700.0  3000.0  3100.0
+1600.0  1900.0  2300.0  2700.0  3000.0  3100.0
+1600.0  2000.0  2400.0  2800.0  3100.0  3200.0
+1700.0  2000.0  2200.0  2700.0  3100.0  3200.0
+1800.0  2000.0  2200.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2100.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2700.0  3000.0  3100.0  3300.0
+1800.0  2100.0  2700.0  3000.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2900.0  3100.0  3200.0
+1900.0  2100.0  2500.0  3000.0  3100.0  3200.0
+1700.0  2000.0  2500.0  2900.0  3100.0  3200.0
+1800.0  2100.0  2600.0  2900.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2900.0  3200.0  3300.0
+1700.0  2100.0  2500.0  2900.0  3100.0  3300.0
+1800.0  2100.0  2500.0  2900.0  3100.0  3200.0
+1600.0  2000.0  2300.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2100.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2200.0  2700.0  3000.0  3200.0
+2000.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1800.0  2100.0  2300.0  2700.0  3200.0  3300.0
+1700.0  2100.0  2300.0  2700.0  3000.0  3200.0
+1600.0  2200.0  2400.0  2800.0  3200.0  3300.0
+1600.0  1700.0  2000.0  2300.0  2700.0  3100.0
+1800.0  2000.0  2200.0  2400.0  2700.0  3100.0
+1700.0  1800.0  2100.0  2400.0  2700.0  3000.0
+1500.0  1600.0  2200.0  2500.0  2800.0  3300.0
+1500.0  1600.0  2100.0  2500.0  2700.0  3000.0
+1500.0  2000.0  2300.0  2500.0  2700.0  2900.0
+1700.0  2100.0  2300.0  2600.0  2800.0  3000.0
+1700.0  2200.0  2400.0  2700.0  3000.0  3100.0
+1500.0  2200.0  2400.0  2600.0  3000.0  3200.0
+1500.0  2100.0  2400.0  2600.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2600.0  3000.0  3200.0
+1500.0  2100.0  2300.0  2600.0  3000.0  3100.0
+1600.0  2000.0  2300.0  2700.0  3000.0  3100.0
+1600.0  1900.0  2200.0  2600.0  3100.0  3200.0
+1500.0  1800.0  2000.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2000.0  2500.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2300.0  3000.0  3100.0
+1400.0  1800.0  2100.0  2400.0  2900.0  3100.0
+1600.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1600.0  1900.0  2200.0  2500.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2800.0  3100.0  3200.0
+1500.0  1800.0  2100.0  2600.0  3000.0  3100.0
+1600.0  1800.0  2100.0  2600.0  2900.0  3100.0
+1600.0  1900.0  2100.0  2500.0  2900.0  3100.0
+1600.0  1900.0  2100.0  2600.0  2900.0  3100.0
+1600.0  1900.0  2100.0  2600.0  2800.0  3100.0
+1600.0  1800.0  2200.0  2600.0  2800.0  3000.0
+1600.0  1900.0  2200.0  2700.0  2900.0  3100.0
+1600.0  1900.0  2200.0  2600.0  2900.0  3000.0
+1900.0  2000.0  2200.0  2800.0  3000.0  3100.0
+1400.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1400.0  1900.0  2100.0  2400.0  3100.0  3200.0
+1500.0  1800.0  2100.0  2400.0  3200.0  3300.0
+1500.0  1700.0  2100.0  2300.0  3100.0  3300.0
+1400.0  1700.0  2100.0  2300.0  3200.0  3300.0
+1400.0  1600.0  2100.0  2300.0  3200.0  3300.0
+1300.0  1600.0  2100.0  2300.0  3200.0  3300.0
+1300.0  1600.0  2100.0  2300.0  3100.0  3300.0
+1200.0  1400.0  2000.0  2200.0  3100.0  3300.0
+1200.0  1400.0  2000.0  2600.0  3100.0  3200.0
+1200.0  1400.0  2000.0  2800.0  3100.0  3200.0
+1200.0  1400.0  2100.0  2800.0  3100.0  3200.0
+1400.0  1500.0  2200.0  2700.0  3000.0  3100.0
+1700.0  1900.0  2200.0  2500.0  2900.0  3200.0
+1400.0  1600.0  2200.0  2700.0  2900.0  3100.0
+1500.0  1600.0  1900.0  2700.0  2900.0  3000.0
+1500.0  1600.0  1900.0  2700.0  3000.0  3100.0
+1500.0  1600.0  2000.0  2700.0  3000.0  3100.0
+1400.0  1600.0  2000.0  2600.0  2900.0  3100.0
+1300.0  1500.0  2400.0  2700.0  2900.0  3200.0
+1600.0  1800.0  2300.0  2700.0  3100.0  3400.0
+1600.0  2100.0  2400.0  2800.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2700.0  3000.0  3100.0
+1600.0  1900.0  2100.0  2700.0  3000.0  3100.0
+1600.0  1800.0  2100.0  2700.0  3000.0  3100.0
+1700.0  1800.0  2300.0  2800.0  3100.0  3200.0
+1800.0  1900.0  2400.0  2900.0  3100.0  3200.0
+1500.0  1700.0  1800.0  2600.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2800.0  3000.0  3200.0
+1800.0  2100.0  2600.0  2900.0  3100.0  3300.0
+1700.0  2300.0  2500.0  2700.0  3100.0  3200.0
+2000.0  2400.0  2500.0  2700.0  3100.0  3200.0
+1900.0  2500.0  2600.0  2800.0  3100.0  3200.0
+1800.0  2400.0  2700.0  2900.0  3200.0  3300.0
+1900.0  2400.0  2600.0  2800.0  3100.0  3200.0
+1700.0  2200.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2200.0  2300.0  2600.0  3100.0  3200.0
+1800.0  2200.0  2300.0  2700.0  3100.0  3200.0
+1800.0  2200.0  2400.0  2800.0  3100.0  3300.0
+1900.0  2100.0  2500.0  2900.0  3300.0  3400.0
+1900.0  2100.0  2400.0  2900.0  3100.0  3200.0
+1900.0  2200.0  2400.0  2800.0  3000.0  3100.0
+1800.0  2200.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2300.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2300.0  2400.0  2800.0  3100.0  3200.0
+1800.0  2100.0  2300.0  2700.0  2900.0  3100.0
+1700.0  2000.0  2500.0  2800.0  3000.0  3300.0
+1100.0  1300.0  2300.0  2600.0  2800.0  3200.0
+1400.0  1600.0  2200.0  2500.0  2800.0  3100.0
+1400.0  1600.0  2000.0  2500.0  2700.0  3000.0
+1400.0  1500.0  1900.0  2500.0  2800.0  2900.0
+1400.0  1500.0  1900.0  2600.0  2900.0  3000.0
+1400.0  1600.0  1900.0  2700.0  2900.0  3000.0
+1500.0  1600.0  2000.0  2700.0  2900.0  3100.0
+1500.0  1600.0  2000.0  2700.0  2900.0  3000.0
+1500.0  1600.0  2100.0  2800.0  3000.0  3100.0
+1600.0  1700.0  2100.0  2800.0  3000.0  3100.0
+1900.0  2200.0  2600.0  2900.0  3300.0  3400.0
+2000.0  2200.0  2600.0  3000.0  3300.0  3400.0
+2000.0  2200.0  2600.0  3000.0  3200.0  3300.0
+1800.0  2100.0  2700.0  3000.0  3400.0  3500.0
+1300.0  1600.0  2300.0  2500.0  3000.0  3300.0
+1400.0  1700.0  2400.0  2500.0  2800.0  2900.0
+1400.0  1700.0  2400.0  2500.0  2800.0  3000.0
+1500.0  2000.0  2400.0  2500.0  3100.0  3200.0
+1400.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1400.0  1500.0  2400.0  2500.0  3100.0  3300.0
+1900.0  2200.0  2600.0  2900.0  3200.0  3400.0
+1600.0  2000.0  2600.0  2700.0  3300.0  3400.0
+1800.0  2200.0  2800.0  3100.0  3400.0  3500.0
+1900.0  2200.0  2700.0  3000.0  3400.0  3500.0
+1900.0  2400.0  2800.0  3000.0  3200.0  3400.0
+1300.0  1900.0  2100.0  2400.0  2800.0  3000.0
+1800.0  2100.0  2300.0  2500.0  2800.0  3100.0
+1800.0  2100.0  2400.0  2600.0  2900.0  3100.0
+1600.0  1800.0  2500.0  2600.0  2900.0  3000.0
+1700.0  1900.0  2200.0  2400.0  2900.0  3200.0
+1600.0  1800.0  2000.0  2300.0  3000.0  3200.0
+1600.0  1700.0  1900.0  2300.0  3100.0  3300.0
+1400.0  1600.0  1800.0  2200.0  3200.0  3300.0
+1400.0  1600.0  1800.0  2300.0  3100.0  3200.0
+1400.0  1600.0  1800.0  2300.0  3000.0  3200.0
+1100.0  2200.0  2500.0  2600.0  2700.0  2900.0
+1200.0  1900.0  2500.0  2600.0  2800.0  3000.0
+1200.0  1800.0  2500.0  2600.0  2800.0  2900.0
+1300.0  1900.0  2500.0  2600.0  2800.0  3100.0
+1500.0  2100.0  2400.0  2500.0  2900.0  3200.0
+1400.0  2100.0  2400.0  2500.0  3000.0  3200.0
+1400.0  2000.0  2400.0  2500.0  3000.0  3300.0
+1300.0  1700.0  2300.0  2400.0  3200.0  3400.0
+1700.0  1900.0  2400.0  2500.0  3000.0  3300.0
+1900.0  2000.0  2500.0  2600.0  2900.0  3200.0
+1900.0  2100.0  2500.0  2700.0  2900.0  3200.0
+2000.0  2100.0  2600.0  2700.0  3000.0  3200.0
+2000.0  2100.0  2600.0  2700.0  3000.0  3300.0
+1900.0  2100.0  2500.0  2600.0  2900.0  3200.0
+1800.0  1900.0  2500.0  2700.0  3100.0  3400.0
+1600.0  2100.0  2400.0  2600.0  3100.0  3300.0
+1700.0  1800.0  2500.0  2600.0  2900.0  3300.0
+1500.0  1900.0  2400.0  2500.0  2800.0  3200.0
+1500.0  2000.0  2400.0  2500.0  2700.0  3000.0
+2100.0  2400.0  2700.0  3000.0  3300.0  3400.0
+1900.0  2200.0  2600.0  2800.0  3100.0  3400.0
+1800.0  2100.0  2600.0  2700.0  3100.0  3400.0
+1800.0  2000.0  2300.0  2500.0  2800.0  3200.0
+1700.0  2100.0  2200.0  2600.0  2900.0  3100.0
+1400.0  2100.0  2200.0  2600.0  2900.0  3100.0
+1500.0  1700.0  2100.0  2400.0  2800.0  3000.0
+1500.0  2000.0  2400.0  2600.0  3000.0  3200.0
+1500.0  1800.0  2400.0  2500.0  3000.0  3200.0
+1500.0  1700.0  2400.0  2500.0  3000.0  3300.0
+1700.0  2100.0  2500.0  2600.0  3200.0  3400.0
+1800.0  2300.0  2500.0  2800.0  3200.0  3300.0
+1800.0  2300.0  2600.0  2900.0  3200.0  3300.0
+1900.0  2300.0  2600.0  3000.0  3300.0  3400.0
+1800.0  1900.0  2300.0  2400.0  2700.0  3100.0
+1600.0  1800.0  2200.0  2500.0  2900.0  3200.0
+1700.0  1900.0  2400.0  2700.0  3100.0  3400.0
+1800.0  2200.0  2400.0  2800.0  3200.0  3400.0
+1900.0  2200.0  2800.0  3000.0  3300.0  3400.0
+2300.0  2600.0  2700.0  2900.0  3200.0  3300.0
+1700.0  2100.0  2500.0  2600.0  3100.0  3300.0
+1700.0  1900.0  2400.0  2500.0  2900.0  3100.0
+1900.0  2100.0  2400.0  2500.0  2900.0  3200.0
+2000.0  2100.0  2400.0  2500.0  2900.0  3200.0
+2000.0  2100.0  2500.0  2600.0  3000.0  3200.0
+2000.0  2200.0  2500.0  2600.0  3000.0  3300.0
+2000.0  2200.0  2600.0  2700.0  2900.0  3100.0
+1700.0  2000.0  2600.0  2700.0  3000.0  3100.0
+1900.0  2200.0  2700.0  2800.0  3100.0  3200.0
+1900.0  2400.0  2700.0  2800.0  3200.0  3300.0
+2100.0  2400.0  2600.0  2800.0  3100.0  3300.0
+2200.0  2500.0  2700.0  2900.0  3200.0  3300.0
+2000.0  2400.0  2800.0  3000.0  3300.0  3400.0
+1300.0  2000.0  2300.0  2400.0  3200.0  3300.0
+1400.0  1800.0  2200.0  2500.0  3000.0  3200.0
+1300.0  1600.0  2100.0  2500.0  2900.0  3200.0
+1300.0  1500.0  2100.0  2400.0  2900.0  3200.0
+1500.0  1700.0  1800.0  2200.0  2600.0  3200.0
+1500.0  1900.0  2200.0  2400.0  2800.0  3100.0
+1300.0  1600.0  2200.0  2300.0  3200.0  3400.0
+1300.0  1700.0  2200.0  2400.0  3100.0  3300.0
+1500.0  2100.0  2300.0  2700.0  3200.0  3400.0
+2000.0  2300.0  2800.0  3000.0  3300.0  3400.0
+1800.0  2300.0  2800.0  3000.0  3400.0  3500.0
+1800.0  2300.0  2700.0  3000.0  3300.0  3500.0
+2000.0  2500.0  2800.0  3100.0  3400.0  3500.0
+2000.0  2500.0  2800.0  3100.0  3300.0  3400.0
+2000.0  2400.0  2800.0  3100.0  3300.0  3400.0
+2100.0  2500.0  2800.0  2900.0  3300.0  3400.0
+2000.0  2300.0  2800.0  2900.0  3200.0  3300.0
+2000.0  2300.0  2700.0  2800.0  3100.0  3200.0
+1900.0  2200.0  2500.0  2700.0  3100.0  3200.0
+1600.0  2200.0  2400.0  2600.0  2900.0  3100.0
+1500.0  2200.0  2400.0  2600.0  2900.0  3200.0
+1400.0  1900.0  2200.0  2400.0  2700.0  3000.0
+1400.0  1900.0  2300.0  2500.0  2800.0  3100.0
+1600.0  1900.0  2400.0  2500.0  2800.0  3000.0
+1600.0  1800.0  2400.0  2600.0  2900.0  3000.0
+1600.0  1900.0  2500.0  2600.0  2900.0  3100.0
+1600.0  1900.0  2400.0  2500.0  3000.0  3100.0
+1600.0  2000.0  2400.0  2600.0  3000.0  3200.0
+1400.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1900.0  2200.0  2500.0  3000.0  3100.0
+1400.0  1800.0  2000.0  2400.0  3000.0  3100.0
+1400.0  1700.0  1900.0  2400.0  2800.0  2900.0
+1700.0  2100.0  2400.0  2600.0  3000.0  3300.0
+1900.0  2100.0  2500.0  2600.0  3000.0  3300.0
+1900.0  2100.0  2400.0  2500.0  2800.0  3200.0
+1800.0  2000.0  2300.0  2400.0  2900.0  3300.0
+1600.0  1800.0  2000.0  2300.0  2700.0  3200.0
+1300.0  1500.0  2100.0  2500.0  3000.0  3200.0
+1400.0  2000.0  2200.0  2400.0  2900.0  3200.0
+1800.0  1900.0  2300.0  2600.0  3000.0  3300.0
+1900.0  2000.0  2300.0  2500.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2400.0  2800.0  3100.0
+1700.0  2000.0  2400.0  2500.0  2800.0  3000.0
+1600.0  2100.0  2500.0  2700.0  3100.0  3200.0
+1900.0  2200.0  2400.0  2700.0  3000.0  3200.0
+1900.0  2100.0  2300.0  2500.0  2800.0  3000.0
+1700.0  2000.0  2300.0  2500.0  2900.0  3100.0
+1700.0  2100.0  2300.0  2500.0  2900.0  3100.0
+1500.0  1700.0  1900.0  2500.0  2800.0  3100.0
+1600.0  1800.0  2000.0  2500.0  2700.0  3000.0
+1700.0  1800.0  2100.0  2500.0  2700.0  2900.0
+2000.0  2300.0  2700.0  2900.0  3100.0  3200.0
+2000.0  2300.0  2600.0  2900.0  3100.0  3200.0
+1600.0  2000.0  2500.0  2600.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2500.0  2800.0  3000.0
+1400.0  2000.0  2400.0  2500.0  2900.0  3100.0
+1500.0  2000.0  2400.0  2500.0  3100.0  3300.0
+1700.0  2100.0  2500.0  2800.0  3300.0  3500.0
+1500.0  1600.0  2300.0  2500.0  2800.0  3100.0
+1500.0  1800.0  2300.0  2500.0  2700.0  2900.0
+1400.0  2000.0  2300.0  2400.0  2700.0  3100.0
+1400.0  2100.0  2400.0  2500.0  2800.0  3200.0
+1400.0  2100.0  2400.0  2500.0  2900.0  3200.0
+1800.0  2000.0  2300.0  2400.0  3000.0  3300.0
+1900.0  2200.0  2500.0  2600.0  2900.0  3100.0
+1800.0  2200.0  2600.0  2900.0  3100.0  3200.0
+2100.0  2500.0  2700.0  2800.0  3200.0  3300.0
+1900.0  2400.0  2600.0  2700.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2700.0  3100.0  3200.0
+1800.0  2000.0  2500.0  2600.0  2900.0  3100.0
+1800.0  2100.0  2500.0  2600.0  2900.0  3100.0
+1900.0  2100.0  2500.0  2600.0  2900.0  3100.0
+1900.0  2100.0  2400.0  2500.0  2900.0  3100.0
+1900.0  2200.0  2300.0  2500.0  2900.0  3200.0
+1800.0  2200.0  2400.0  2600.0  3000.0  3100.0
+1800.0  2200.0  2400.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2300.0  2800.0  3200.0  3400.0
+1600.0  2100.0  2300.0  2700.0  3200.0  3400.0
+1800.0  2200.0  2600.0  2700.0  3000.0  3200.0
+1900.0  2200.0  2600.0  3000.0  3200.0  3400.0
+2000.0  2400.0  2900.0  3000.0  3300.0  3500.0
+2100.0  2500.0  2800.0  2900.0  3400.0  3500.0
+2100.0  2600.0  2800.0  3000.0  3300.0  3400.0
+2300.0  2600.0  2800.0  3000.0  3200.0  3300.0
+2200.0  2500.0  2600.0  2800.0  3200.0  3300.0
+2200.0  2400.0  2600.0  2700.0  3200.0  3300.0
+2100.0  2300.0  2500.0  2700.0  3100.0  3300.0
+2100.0  2300.0  2500.0  2800.0  3000.0  3200.0
+1900.0  2100.0  2200.0  2500.0  3000.0  3200.0
+1700.0  2000.0  2400.0  2600.0  3000.0  3200.0
+1900.0  2200.0  2700.0  3000.0  3200.0  3300.0
+2000.0  2300.0  2900.0  3000.0  3300.0  3400.0
+2100.0  2400.0  2800.0  3000.0  3300.0  3400.0
+2000.0  2500.0  2800.0  2900.0  3300.0  3400.0
+2100.0  2600.0  2800.0  2900.0  3300.0  3400.0
+1800.0  2100.0  2700.0  2900.0  3200.0  3300.0
+1800.0  2200.0  2600.0  2800.0  3100.0  3300.0
+1700.0  2000.0  2400.0  2500.0  2700.0  2900.0
+1500.0  1800.0  2400.0  2600.0  2900.0  3200.0
+1500.0  2000.0  2400.0  2500.0  2800.0  3000.0
+1500.0  1900.0  2400.0  2500.0  2700.0  3000.0
+1500.0  2000.0  2400.0  2600.0  2800.0  3100.0
+1500.0  1800.0  2500.0  2600.0  3000.0  3300.0
+1500.0  2100.0  2400.0  2500.0  3000.0  3300.0
+1600.0  2100.0  2400.0  2600.0  3000.0  3300.0
+1600.0  2000.0  2400.0  2600.0  2800.0  3100.0
+1900.0  2300.0  2700.0  2900.0  3300.0  3400.0
+1800.0  2300.0  2700.0  3100.0  3300.0  3400.0
+2000.0  2100.0  2300.0  2700.0  3000.0  3300.0
+2100.0  2300.0  2600.0  2700.0  3100.0  3300.0
+2100.0  2300.0  2500.0  2700.0  3200.0  3300.0
+2100.0  2300.0  2600.0  2800.0  3200.0  3300.0
+1600.0  2100.0  2400.0  2600.0  3100.0  3200.0
+1500.0  2100.0  2500.0  2600.0  3000.0  3100.0
+1600.0  2100.0  2300.0  2600.0  3100.0  3300.0
+1800.0  2100.0  2500.0  2600.0  3000.0  3300.0
+1600.0  1800.0  2500.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2500.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2400.0  2600.0  2900.0  3100.0
+1700.0  2100.0  2500.0  2800.0  3000.0  3200.0
+1600.0  1800.0  2300.0  2700.0  3000.0  3300.0
+1600.0  1800.0  2200.0  2700.0  3100.0  3300.0
+1600.0  1700.0  2100.0  2700.0  3100.0  3200.0
+1600.0  1700.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1600.0  2200.0  2500.0  3100.0  3300.0
+1400.0  1600.0  2100.0  2300.0  3100.0  3300.0
+1400.0  1600.0  2100.0  2300.0  3200.0  3400.0
+1300.0  1600.0  2100.0  2200.0  3200.0  3300.0
+1300.0  1700.0  2200.0  2400.0  3200.0  3400.0
+1300.0  1600.0  2200.0  2300.0  3100.0  3400.0
+1400.0  1600.0  2200.0  2300.0  2900.0  3300.0
+1400.0  1600.0  2200.0  2400.0  2900.0  3300.0
+1300.0  1500.0  2200.0  2400.0  3000.0  3300.0
+1300.0  1500.0  2200.0  2400.0  3100.0  3300.0
+1200.0  1500.0  2200.0  2400.0  3100.0  3300.0
+1200.0  1700.0  2300.0  2500.0  3200.0  3300.0
+1800.0  2000.0  2300.0  2400.0  3200.0  3400.0
+2000.0  2100.0  2400.0  2500.0  3000.0  3400.0
+2000.0  2200.0  2500.0  2700.0  3200.0  3400.0
+2000.0  2500.0  2700.0  2900.0  3400.0  3500.0
+1700.0  2000.0  2500.0  2600.0  3000.0  3300.0
+1600.0  1700.0  2100.0  2400.0  2800.0  3200.0
+1400.0  1600.0  2200.0  2300.0  3000.0  3400.0
+1300.0  1500.0  2200.0  2300.0  2800.0  3200.0
+1500.0  1700.0  2400.0  2500.0  3000.0  3200.0
+1600.0  1700.0  2400.0  2500.0  3000.0  3300.0
+1700.0  1800.0  2400.0  2500.0  2900.0  3200.0
+1800.0  1900.0  2400.0  2500.0  2900.0  3100.0
+1700.0  1900.0  2400.0  2500.0  2900.0  3200.0
+1500.0  1700.0  2300.0  2400.0  3100.0  3400.0
+1400.0  1600.0  2200.0  2400.0  2800.0  3100.0
+1400.0  1600.0  2200.0  2400.0  2800.0  3200.0
+1400.0  1600.0  2100.0  2300.0  2800.0  3200.0
+1500.0  1600.0  2100.0  2400.0  2700.0  3100.0
+1600.0  1700.0  2200.0  2400.0  2800.0  3100.0
+1600.0  2200.0  2500.0  2700.0  3300.0  3400.0
+1500.0  2000.0  2500.0  2900.0  3300.0  3400.0
+1400.0  2000.0  2400.0  2800.0  3200.0  3400.0
+1400.0  1700.0  2300.0  2600.0  3000.0  3200.0
+1300.0  1600.0  2300.0  2400.0  3100.0  3200.0
+1300.0  1600.0  2300.0  2400.0  3000.0  3200.0
+1200.0  1500.0  2200.0  2300.0  3000.0  3300.0
+1300.0  1700.0  2300.0  2400.0  3100.0  3300.0
+1300.0  1600.0  2300.0  2400.0  3000.0  3300.0
+1300.0  1700.0  2300.0  2400.0  3000.0  3300.0
+1300.0  1600.0  2200.0  2300.0  3000.0  3300.0
+1300.0  1600.0  2200.0  2300.0  3100.0  3300.0
+1300.0  1400.0  2200.0  2300.0  3000.0  3300.0
+1300.0  1600.0  2200.0  2400.0  3100.0  3300.0
+1400.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1400.0  1600.0  2300.0  2400.0  3200.0  3400.0
+1400.0  1600.0  2300.0  2400.0  3100.0  3400.0
+1400.0  1600.0  2300.0  2400.0  3000.0  3400.0
+1400.0  1500.0  2400.0  2500.0  3000.0  3300.0
+1400.0  1900.0  2300.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2300.0  3200.0  3400.0
+1400.0  1600.0  2100.0  2400.0  3100.0  3400.0
+1600.0  1900.0  2200.0  2500.0  2800.0  3100.0
+1500.0  1800.0  2200.0  2300.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2400.0  3000.0  3200.0
+1700.0  1800.0  2300.0  2400.0  2900.0  3200.0
+1800.0  1900.0  2400.0  2500.0  2800.0  3100.0
+2000.0  2100.0  2500.0  2600.0  3100.0  3300.0
+2000.0  2100.0  2400.0  2500.0  3000.0  3300.0
+1800.0  2100.0  2400.0  2600.0  3200.0  3400.0
+1600.0  1900.0  2300.0  2500.0  3000.0  3300.0
+1400.0  1700.0  2200.0  2300.0  3000.0  3300.0
+1400.0  1700.0  2100.0  2200.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2300.0  3100.0  3200.0
+1900.0  2200.0  2400.0  2500.0  2900.0  3100.0
+1400.0  1600.0  2200.0  2600.0  3100.0  3300.0
+1400.0  1700.0  2300.0  2700.0  3100.0  3300.0
+1500.0  1900.0  2300.0  2600.0  3200.0  3400.0
+1200.0  1600.0  2400.0  2500.0  3100.0  3200.0
+1200.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1700.0  1800.0  2100.0  2300.0  2900.0  3000.0
+1800.0  1900.0  2200.0  2300.0  2900.0  3000.0
+1900.0  2000.0  2500.0  2600.0  3100.0  3200.0
+1700.0  1900.0  2300.0  2600.0  3200.0  3300.0
+1800.0  2100.0  2500.0  2600.0  3300.0  3400.0
+1700.0  2300.0  2500.0  2900.0  3200.0  3300.0
+1900.0  2400.0  2800.0  3000.0  3300.0  3400.0
+1600.0  1800.0  2400.0  2500.0  3000.0  3400.0
+1700.0  1800.0  2400.0  2500.0  3100.0  3400.0
+1600.0  2000.0  2200.0  2600.0  3200.0  3300.0
+1500.0  2100.0  2500.0  2800.0  3200.0  3300.0
+1500.0  2000.0  2500.0  2800.0  3300.0  3400.0
+1800.0  2000.0  2500.0  2900.0  3300.0  3400.0
+1500.0  2100.0  2400.0  2800.0  3300.0  3400.0
+1300.0  2000.0  2400.0  2500.0  3300.0  3400.0
+1600.0  1700.0  2200.0  2400.0  3200.0  3300.0
+1600.0  1700.0  2200.0  2300.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2400.0  3200.0  3300.0
+1600.0  1700.0  2200.0  2400.0  2900.0  3300.0
+1500.0  1700.0  2300.0  2400.0  2900.0  3100.0
+1400.0  1800.0  2500.0  2600.0  3000.0  3200.0
+1300.0  1600.0  2400.0  2500.0  3100.0  3300.0
+1300.0  1500.0  2400.0  2500.0  3000.0  3400.0
+1300.0  1500.0  2500.0  2600.0  3000.0  3300.0
+1300.0  1500.0  2400.0  2500.0  2800.0  3300.0
+1400.0  1500.0  2500.0  2600.0  2900.0  3300.0
+1800.0  2200.0  2700.0  2900.0  3200.0  3300.0
+1600.0  1700.0  2400.0  2500.0  2900.0  3300.0
+1600.0  1700.0  2300.0  2500.0  2800.0  3300.0
+1700.0  1800.0  2200.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2300.0  3100.0  3200.0
+1600.0  1800.0  2200.0  2400.0  3100.0  3200.0
+1500.0  1800.0  2100.0  2300.0  3100.0  3200.0
+1400.0  1800.0  2200.0  2400.0  2900.0  3200.0
+1500.0  2000.0  2200.0  2400.0  2700.0  3200.0
+1600.0  1900.0  2200.0  2400.0  2800.0  3200.0
+1700.0  1800.0  2400.0  2500.0  3300.0  3500.0
+1500.0  1800.0  2300.0  2600.0  3200.0  3400.0
+1300.0  1600.0  2200.0  2400.0  3200.0  3400.0
+1200.0  1600.0  2200.0  2400.0  3100.0  3300.0
+1100.0  1500.0  2100.0  2300.0  3100.0  3200.0
+1400.0  1700.0  2100.0  2400.0  3100.0  3200.0
+1500.0  1600.0  2100.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2100.0  2300.0  2900.0  3000.0
+1600.0  1700.0  2100.0  2400.0  2900.0  3100.0
+1600.0  1700.0  2100.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2100.0  2300.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2300.0  3200.0  3300.0
+1700.0  1900.0  2100.0  2300.0  3200.0  3400.0
+1800.0  1900.0  2100.0  2300.0  3200.0  3400.0
+1700.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2300.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2300.0  2700.0  3100.0
+1600.0  1700.0  2100.0  2300.0  2500.0  3000.0
+1500.0  1800.0  2300.0  2500.0  2900.0  3100.0
+1500.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1500.0  2000.0  2500.0  2900.0  3200.0  3300.0
+1700.0  2400.0  2900.0  3100.0  3300.0  3400.0
+1700.0  2100.0  2400.0  2800.0  3300.0  3400.0
+1800.0  2400.0  2600.0  2800.0  3100.0  3300.0
+1200.0  1600.0  2400.0  2500.0  3100.0  3400.0
+1300.0  1500.0  2400.0  2500.0  3100.0  3400.0
+1400.0  1500.0  2400.0  2500.0  3000.0  3200.0
+1400.0  1600.0  2400.0  2500.0  3000.0  3200.0
+1800.0  2100.0  2500.0  2600.0  3000.0  3200.0
+1700.0  2200.0  2500.0  2800.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2500.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2500.0  3000.0  3200.0
+1400.0  2000.0  2400.0  2500.0  3200.0  3400.0
+1800.0  2100.0  2400.0  2500.0  3200.0  3400.0
+1800.0  1900.0  2200.0  2400.0  3100.0  3300.0
+1700.0  2000.0  2400.0  2600.0  3200.0  3400.0
+1600.0  1700.0  2300.0  2400.0  3100.0  3400.0
+1600.0  1700.0  2300.0  2400.0  3200.0  3400.0
+1200.0  1700.0  2400.0  2500.0  3200.0  3400.0
+1700.0  2200.0  2800.0  3100.0  3400.0  3500.0
+1600.0  2000.0  2400.0  2800.0  3300.0  3400.0
+1300.0  1600.0  2100.0  2300.0  3100.0  3200.0
+1300.0  1600.0  2100.0  2200.0  3100.0  3200.0
+1300.0  1500.0  1800.0  2000.0  3000.0  3100.0
+1300.0  1500.0  1800.0  1900.0  3100.0  3200.0
+1400.0  1500.0  1700.0  1800.0  3100.0  3200.0
+1400.0  1600.0  1700.0  2000.0  2800.0  2900.0
+1500.0  1700.0  2200.0  2400.0  2800.0  3200.0
+1500.0  1700.0  2200.0  2300.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2200.0  3100.0  3200.0
+1300.0  1500.0  1800.0  2200.0  3100.0  3200.0
+1400.0  1800.0  2300.0  2500.0  2900.0  3200.0
+1400.0  1800.0  2300.0  2400.0  2700.0  3200.0
+1500.0  1600.0  2000.0  2500.0  2900.0  3200.0
+1500.0  1600.0  2000.0  2400.0  3100.0  3300.0
+1500.0  1700.0  2200.0  2500.0  2800.0  3200.0
+1700.0  1800.0  2200.0  2500.0  2800.0  3100.0
+1600.0  1700.0  2200.0  2500.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2500.0  2900.0  3100.0
+1900.0  2000.0  2400.0  2600.0  3000.0  3200.0
+1500.0  1700.0  2200.0  2500.0  3000.0  3300.0
+1300.0  1500.0  2200.0  2400.0  3000.0  3400.0
+1200.0  1400.0  2200.0  2500.0  3200.0  3400.0
+1300.0  1600.0  2000.0  2200.0  3100.0  3200.0
+1400.0  1600.0  1900.0  2000.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2400.0  2900.0  3100.0
+1500.0  1600.0  2200.0  2300.0  2800.0  3100.0
+1400.0  1600.0  2200.0  2300.0  2800.0  3100.0
+1300.0  1600.0  2300.0  2400.0  2900.0  3300.0
+1700.0  2200.0  2800.0  3100.0  3300.0  3400.0
+1700.0  2200.0  2600.0  3000.0  3300.0  3500.0
+1100.0  1500.0  2400.0  2500.0  3200.0  3300.0
+1500.0  2000.0  2300.0  2500.0  2700.0  3100.0
+1900.0  2100.0  2500.0  2600.0  3100.0  3300.0
+1900.0  2000.0  2300.0  2400.0  3000.0  3300.0
+1500.0  2100.0  2500.0  2800.0  3300.0  3400.0
+1600.0  2100.0  2500.0  2900.0  3300.0  3400.0
+1200.0  1600.0  2400.0  2500.0  2900.0  3400.0
+1300.0  1500.0  2300.0  2500.0  2700.0  3200.0
+1400.0  1600.0  2500.0  2600.0  3000.0  3300.0
+1300.0  1600.0  2400.0  2500.0  3100.0  3400.0
+1300.0  1800.0  2300.0  2500.0  3100.0  3300.0
+1300.0  1600.0  2300.0  2400.0  3100.0  3300.0
+1200.0  1600.0  2300.0  2400.0  3000.0  3300.0
+1100.0  1700.0  2200.0  2500.0  3100.0  3300.0
+1500.0  1600.0  2200.0  2600.0  3000.0  3300.0
+1500.0  1600.0  2200.0  2600.0  2900.0  3300.0
+1500.0  1700.0  2400.0  2600.0  2900.0  3300.0
+1500.0  1600.0  2300.0  2500.0  2900.0  3200.0
+1700.0  2100.0  2600.0  3000.0  3300.0  3400.0
+1600.0  1800.0  2400.0  2500.0  3100.0  3500.0
+1500.0  1600.0  2400.0  2500.0  3100.0  3400.0
+1500.0  1600.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1500.0  1600.0  2000.0  3200.0  3400.0
+1900.0  2000.0  2300.0  2500.0  2900.0  3200.0
+2000.0  2500.0  2700.0  2800.0  3200.0  3300.0
+2000.0  2200.0  2500.0  2800.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2700.0  2900.0  3100.0
+1700.0  1800.0  2400.0  2800.0  2900.0  3100.0
+1700.0  1800.0  2400.0  2800.0  3000.0  3100.0
+1700.0  1800.0  2300.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2800.0  3100.0  3200.0
+1400.0  1900.0  2200.0  2400.0  3000.0  3200.0
+2100.0  2300.0  2800.0  3000.0  3200.0  3300.0
+2100.0  2400.0  2900.0  3000.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2600.0  3000.0  3100.0
+1700.0  1800.0  2300.0  2600.0  2900.0  3100.0
+1600.0  1700.0  2100.0  2600.0  2900.0  3100.0
+1700.0  1800.0  2100.0  2700.0  2900.0  3100.0
+1800.0  1900.0  2200.0  2700.0  3000.0  3100.0
+1900.0  2100.0  2300.0  2800.0  3100.0  3200.0
+2000.0  2400.0  2600.0  2900.0  3200.0  3300.0
+1300.0  1700.0  2400.0  2700.0  3100.0  3200.0
+1200.0  1500.0  2300.0  2400.0  3000.0  3200.0
+1100.0  1500.0  2300.0  2500.0  3100.0  3200.0
+2000.0  2300.0  2800.0  3000.0  3200.0  3300.0
+2100.0  2400.0  2900.0  3000.0  3300.0  3400.0
+2200.0  2500.0  2900.0  3100.0  3300.0  3400.0
+2300.0  2500.0  2900.0  3100.0  3300.0  3400.0
+2200.0  2500.0  2900.0  3100.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2600.0  3200.0  3400.0
+1500.0  1800.0  2000.0  2300.0  3200.0  3400.0
+1700.0  1800.0  2000.0  2100.0  3200.0  3400.0
+1800.0  1900.0  2200.0  2300.0  3200.0  3400.0
+1900.0  2000.0  2500.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2400.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2500.0  2800.0  3200.0  3400.0
+1800.0  2300.0  2600.0  2800.0  3200.0  3400.0
+1500.0  1900.0  2600.0  2800.0  3100.0  3300.0
+1400.0  1500.0  2400.0  2700.0  2800.0  3100.0
+1400.0  1500.0  2300.0  2700.0  2800.0  3100.0
+1400.0  1500.0  2400.0  2800.0  2900.0  3100.0
+1300.0  1500.0  2300.0  2900.0  3100.0  3200.0
+1300.0  1500.0  2200.0  2900.0  3100.0  3300.0
+1500.0  1600.0  2000.0  2700.0  3200.0  3300.0
+1500.0  1600.0  2000.0  2400.0  3100.0  3200.0
+1700.0  1800.0  2200.0  2400.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2400.0  2900.0  3200.0
+1700.0  1900.0  2100.0  2400.0  2900.0  3200.0
+2000.0  2400.0  2700.0  2900.0  3100.0  3200.0
+1900.0  2000.0  2400.0  2800.0  3100.0  3200.0
+1700.0  1900.0  2500.0  2800.0  3000.0  3200.0
+1100.0  1400.0  2500.0  2900.0  3100.0  3200.0
+2200.0  2500.0  2900.0  3000.0  3200.0  3400.0
+2100.0  2500.0  2900.0  3000.0  3200.0  3400.0
+1900.0  2100.0  2500.0  2900.0  3000.0  3200.0
+1900.0  2000.0  2400.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2800.0  3000.0  3100.0
+1700.0  1900.0  2200.0  2800.0  3000.0  3100.0
+1600.0  1900.0  2000.0  2500.0  2800.0  3000.0
+1300.0  1900.0  2100.0  2500.0  2900.0  3100.0
+1500.0  1900.0  2100.0  2600.0  2900.0  3100.0
+1100.0  1400.0  2500.0  2700.0  3000.0  3300.0
+1300.0  1600.0  2500.0  2700.0  2900.0  3300.0
+1500.0  1700.0  2500.0  2700.0  2900.0  3200.0
+1700.0  1900.0  2600.0  2700.0  3000.0  3200.0
+1800.0  1900.0  2500.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2500.0  2800.0  2900.0  3200.0
+1900.0  2000.0  2400.0  2800.0  2900.0  3200.0
+1900.0  2000.0  2400.0  2800.0  3000.0  3100.0
+1900.0  2100.0  2500.0  2900.0  3100.0  3200.0
+1800.0  2100.0  2500.0  2800.0  3000.0  3200.0
+1500.0  1700.0  2100.0  2600.0  2900.0  3100.0
+1500.0  1700.0  2400.0  2800.0  3000.0  3200.0
+1500.0  1700.0  2400.0  2900.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2600.0  3000.0  3300.0
+1200.0  1700.0  2500.0  2700.0  3000.0  3300.0
+1200.0  1500.0  2600.0  2700.0  3000.0  3300.0
+1300.0  1600.0  2600.0  2700.0  3000.0  3300.0
+1600.0  1800.0  2400.0  2600.0  2900.0  3200.0
+1700.0  1800.0  2500.0  2600.0  2800.0  3200.0
+1900.0  2000.0  2400.0  2700.0  2800.0  3100.0
+2000.0  2100.0  2500.0  2700.0  2800.0  3100.0
+1800.0  1900.0  2400.0  2700.0  2800.0  3100.0
+1700.0  1800.0  2400.0  2700.0  2800.0  3100.0
+1600.0  1700.0  2400.0  2700.0  2800.0  3100.0
+1500.0  1600.0  2400.0  2700.0  2800.0  3200.0
+1400.0  1600.0  2300.0  2600.0  2900.0  3200.0
+1300.0  1500.0  2400.0  2600.0  2800.0  3200.0
+1200.0  1400.0  2500.0  2600.0  2900.0  3200.0
+1300.0  1400.0  2200.0  2600.0  2800.0  3100.0
+1900.0  2100.0  2600.0  2800.0  3200.0  3400.0
+1900.0  2000.0  2500.0  2800.0  3200.0  3300.0
+1800.0  2100.0  2500.0  2700.0  2900.0  3100.0
+1600.0  2000.0  2400.0  2800.0  3000.0  3200.0
+1600.0  1900.0  2400.0  2800.0  3000.0  3300.0
+1800.0  1900.0  2300.0  2700.0  3000.0  3100.0
+1800.0  1900.0  2300.0  2700.0  2900.0  3000.0
+1700.0  1900.0  2200.0  2500.0  2900.0  3000.0
+1400.0  1900.0  2200.0  2500.0  2900.0  3100.0
+1500.0  1800.0  2200.0  2400.0  2900.0  3100.0
+1600.0  1900.0  2300.0  2500.0  3000.0  3200.0
+1800.0  2100.0  2300.0  2700.0  3100.0  3200.0
+1900.0  2300.0  2600.0  2800.0  3000.0  3200.0
+1500.0  1700.0  2300.0  2700.0  2900.0  3100.0
+1700.0  1800.0  2300.0  2800.0  3000.0  3100.0
+2000.0  2100.0  2400.0  2800.0  3100.0  3200.0
+2100.0  2400.0  2500.0  2800.0  3100.0  3200.0
+1900.0  2100.0  2500.0  2800.0  3000.0  3200.0
+1700.0  1800.0  2400.0  2800.0  3000.0  3200.0
+1300.0  1500.0  2200.0  2800.0  3100.0  3200.0
+1400.0  1500.0  2400.0  2800.0  2900.0  3200.0
+1400.0  1600.0  2500.0  2700.0  3000.0  3200.0
+1500.0  1600.0  2400.0  2700.0  3000.0  3200.0
+1600.0  1800.0  2400.0  2700.0  2900.0  3200.0
+1400.0  1600.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1600.0  2600.0  2700.0  3100.0  3300.0
+1000.0  1800.0  2700.0  2800.0  3200.0  3400.0
+1100.0  1700.0  2400.0  2500.0  3200.0  3400.0
+1600.0  1800.0  2000.0  2200.0  3200.0  3400.0
+1800.0  1900.0  2200.0  2400.0  3000.0  3300.0
+1800.0  1900.0  2200.0  2600.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2700.0  3000.0  3200.0
+1300.0  1500.0  2500.0  2800.0  3000.0  3300.0
+1700.0  2000.0  2500.0  2700.0  2900.0  3200.0
+2000.0  2200.0  2500.0  2700.0  2900.0  3200.0
+2200.0  2600.0  2700.0  2800.0  3100.0  3300.0
+2100.0  2600.0  2700.0  2900.0  3300.0  3400.0
+2200.0  2300.0  2600.0  2800.0  3000.0  3200.0
+1600.0  2200.0  2500.0  2700.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2700.0  3100.0  3200.0
+1800.0  2000.0  2500.0  2900.0  3100.0  3200.0
+2200.0  2400.0  2600.0  2900.0  3100.0  3200.0
+2200.0  2500.0  2600.0  2800.0  3100.0  3200.0
+2300.0  2500.0  2600.0  2800.0  3200.0  3300.0
+2200.0  2500.0  2700.0  2800.0  3200.0  3300.0
+2200.0  2500.0  2700.0  2800.0  3100.0  3200.0
+2200.0  2400.0  2600.0  2800.0  3100.0  3200.0
+2000.0  2200.0  2400.0  2800.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2800.0  3000.0  3200.0
+1700.0  2100.0  2300.0  2600.0  3000.0  3200.0
+1900.0  2200.0  2300.0  2600.0  3000.0  3100.0
+1800.0  2000.0  2200.0  2600.0  3000.0  3100.0
+1600.0  1900.0  2300.0  2500.0  2800.0  3000.0
+1700.0  1800.0  2300.0  2500.0  2800.0  2900.0
+1700.0  2100.0  2400.0  2700.0  3100.0  3200.0
+1400.0  1600.0  1700.0  2100.0  3200.0  3400.0
+1500.0  1800.0  2200.0  2300.0  3200.0  3500.0
+1300.0  1700.0  2300.0  2500.0  2900.0  3200.0
+1300.0  1500.0  2100.0  2500.0  2900.0  3200.0
+1700.0  2000.0  2200.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2500.0  2700.0  2900.0  3200.0
+1700.0  1900.0  2400.0  2700.0  2900.0  3200.0
+1600.0  1700.0  2300.0  2600.0  2900.0  3200.0
+1400.0  1600.0  2300.0  2400.0  2800.0  3300.0
+1600.0  1700.0  2400.0  2700.0  3000.0  3300.0
+1600.0  1800.0  2400.0  2700.0  2900.0  3300.0
+1600.0  1800.0  2400.0  2800.0  3000.0  3200.0
+1600.0  1700.0  2100.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2200.0  2500.0  2700.0  3200.0
+1700.0  2000.0  2400.0  2700.0  3000.0  3300.0
+1600.0  1700.0  2400.0  2700.0  3000.0  3200.0
+1500.0  1600.0  2300.0  2700.0  3100.0  3300.0
+1400.0  1600.0  2300.0  2700.0  3100.0  3300.0
+1400.0  1600.0  2200.0  2800.0  3100.0  3200.0
+1500.0  1600.0  2200.0  2800.0  3100.0  3200.0
+1500.0  1600.0  2100.0  2800.0  3100.0  3200.0
+1500.0  1600.0  2000.0  2600.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2800.0  3100.0  3200.0
+1700.0  1900.0  2500.0  2900.0  3100.0  3300.0
+2300.0  2400.0  2600.0  2900.0  3200.0  3300.0
+2200.0  2300.0  2500.0  2800.0  3100.0  3300.0
+2000.0  2200.0  2400.0  2600.0  3000.0  3300.0
+1300.0  1800.0  2200.0  2400.0  3000.0  3300.0
+1500.0  1800.0  2300.0  2400.0  3100.0  3400.0
+1800.0  2100.0  2300.0  2600.0  3000.0  3200.0
+1900.0  2100.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1900.0  2500.0  2600.0  3000.0  3300.0
+1600.0  1800.0  2500.0  2600.0  3000.0  3400.0
+1600.0  1900.0  2400.0  2500.0  3100.0  3400.0
+1600.0  1800.0  2300.0  2400.0  3100.0  3400.0
+1600.0  1800.0  2200.0  2300.0  3100.0  3400.0
+1600.0  1800.0  2000.0  2200.0  3100.0  3400.0
+1700.0  1800.0  2300.0  2600.0  3100.0  3200.0
+2200.0  2300.0  2500.0  2800.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2500.0  3000.0  3200.0
+1300.0  1700.0  2300.0  2400.0  3000.0  3200.0
+1400.0  1800.0  2300.0  2400.0  3000.0  3100.0
+1200.0  1500.0  2600.0  2800.0  3000.0  3300.0
+2200.0  2400.0  2600.0  2800.0  3000.0  3200.0
+2000.0  2500.0  2600.0  2800.0  3100.0  3200.0
+1900.0  2400.0  2600.0  2700.0  3100.0  3200.0
+2000.0  2300.0  2400.0  2600.0  3000.0  3200.0
+1900.0  2200.0  2400.0  2800.0  3100.0  3300.0
+1800.0  2100.0  2300.0  2800.0  3100.0  3300.0
+1900.0  2100.0  2400.0  2600.0  3100.0  3200.0
+2000.0  2300.0  2500.0  2600.0  2900.0  3200.0
+1600.0  2100.0  2400.0  2600.0  2900.0  3300.0
+1400.0  1700.0  2400.0  2800.0  3000.0  3200.0
+1100.0  1700.0  2900.0  3000.0  3200.0  3400.0
+1100.0  1700.0  2300.0  2900.0  3300.0  3400.0
+1100.0  1500.0  2300.0  2400.0  3300.0  3500.0
+1400.0  1700.0  2200.0  2400.0  3000.0  3300.0
+1600.0  1800.0  2300.0  2600.0  2900.0  3300.0
+2000.0  2100.0  2400.0  2800.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2700.0  3000.0  3100.0
+1600.0  1900.0  2100.0  2600.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2600.0  3000.0  3300.0
+1500.0  1700.0  1900.0  2200.0  3200.0  3400.0
+1400.0  1600.0  1800.0  2100.0  3200.0  3400.0
+1300.0  1500.0  1600.0  2200.0  3300.0  3400.0
+1800.0  2000.0  2200.0  2400.0  3000.0  3300.0
+2100.0  2500.0  2700.0  2800.0  3100.0  3200.0
+2100.0  2400.0  2600.0  2800.0  3100.0  3200.0
+1300.0  1800.0  2200.0  2600.0  3000.0  3200.0
+1800.0  2200.0  2400.0  2800.0  3200.0  3300.0
+1700.0  2100.0  2300.0  2700.0  3100.0  3300.0
+1400.0  1600.0  2100.0  2200.0  3000.0  3300.0
+1500.0  1700.0  2100.0  2200.0  3100.0  3400.0
+1500.0  1700.0  2000.0  2200.0  3100.0  3400.0
+1700.0  1800.0  2100.0  2300.0  3100.0  3400.0
+1900.0  2000.0  2400.0  2600.0  3000.0  3100.0
+2100.0  2500.0  2800.0  2900.0  3200.0  3300.0
+1800.0  2200.0  2400.0  2700.0  3100.0  3200.0
+1700.0  2100.0  2300.0  2600.0  3000.0  3100.0
+1900.0  2100.0  2300.0  2700.0  3000.0  3100.0
+2000.0  2200.0  2500.0  2700.0  2900.0  3100.0
+1400.0  1700.0  2000.0  2600.0  3200.0  3300.0
+1400.0  1700.0  2200.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2900.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2600.0  3000.0  3100.0
+1600.0  1900.0  2200.0  2500.0  2900.0  3000.0
+1600.0  1800.0  2000.0  2600.0  3000.0  3100.0
+1600.0  1800.0  2300.0  2700.0  2900.0  3100.0
+1500.0  1900.0  2200.0  2500.0  2600.0  3200.0
+1800.0  1900.0  2400.0  2800.0  2900.0  3200.0
+2000.0  2100.0  2400.0  2800.0  3000.0  3200.0
+2000.0  2300.0  2400.0  2700.0  3200.0  3300.0
+1900.0  2200.0  2400.0  2800.0  3200.0  3300.0
+1300.0  1800.0  2200.0  2600.0  3100.0  3300.0
+2000.0  2400.0  2800.0  3000.0  3200.0  3400.0
+2200.0  2300.0  2800.0  3000.0  3200.0  3300.0
+2100.0  2300.0  2600.0  3000.0  3200.0  3300.0
+2100.0  2200.0  2600.0  2900.0  3100.0  3200.0
+2100.0  2200.0  2500.0  2900.0  3100.0  3200.0
+1800.0  2100.0  2300.0  2800.0  3100.0  3200.0
+1800.0  2000.0  2200.0  2600.0  3100.0  3200.0
+2000.0  2100.0  2400.0  2900.0  3100.0  3200.0
+2200.0  2500.0  2800.0  3000.0  3200.0  3300.0
+2100.0  2400.0  2800.0  3000.0  3200.0  3400.0
+2000.0  2100.0  2500.0  2800.0  3100.0  3200.0
+2000.0  2100.0  2500.0  2900.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2800.0  2900.0  3100.0
+1600.0  1900.0  2100.0  2500.0  2800.0  3000.0
+1700.0  1900.0  2200.0  2500.0  2800.0  3000.0
+2100.0  2400.0  2700.0  3000.0  3200.0  3400.0
+1700.0  1800.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1700.0  2300.0  2800.0  3000.0  3200.0
+1600.0  1900.0  2300.0  2800.0  3100.0  3300.0
+1400.0  1600.0  1700.0  2100.0  3300.0  3400.0
+1600.0  1700.0  2000.0  2300.0  3200.0  3400.0
+1600.0  1800.0  2300.0  2700.0  2900.0  3200.0
+1600.0  1700.0  2300.0  2800.0  2900.0  3200.0
+1600.0  1800.0  2300.0  2800.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2800.0  3000.0  3100.0
+1800.0  1900.0  2300.0  2600.0  2900.0  3300.0
+1700.0  1800.0  2300.0  2500.0  3000.0  3400.0
+1600.0  1700.0  2200.0  2400.0  3000.0  3400.0
+1600.0  1700.0  2200.0  2300.0  3000.0  3400.0
+2000.0  2100.0  2300.0  2400.0  3000.0  3300.0
+2200.0  2500.0  2700.0  2900.0  3200.0  3400.0
+2000.0  2500.0  2600.0  2800.0  3200.0  3300.0
+2100.0  2500.0  2600.0  2900.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2700.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2800.0  3000.0  3100.0
+1700.0  2000.0  2300.0  2700.0  3000.0  3200.0
+2000.0  2100.0  2500.0  2800.0  3000.0  3100.0
+1400.0  1600.0  1800.0  2100.0  3300.0  3400.0
+1500.0  1800.0  2100.0  2300.0  3200.0  3300.0
+1600.0  1700.0  2200.0  2500.0  3000.0  3300.0
+1600.0  1700.0  2200.0  2600.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2700.0  3000.0  3200.0
+1700.0  1800.0  2200.0  2700.0  3000.0  3100.0
+1800.0  2000.0  2200.0  2800.0  3000.0  3100.0
+1300.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1300.0  2000.0  2200.0  2600.0  3100.0  3200.0
+2100.0  2500.0  2800.0  2900.0  3200.0  3400.0
+2200.0  2600.0  2800.0  3000.0  3300.0  3400.0
+1600.0  1900.0  2500.0  2600.0  3100.0  3400.0
+1400.0  1800.0  2500.0  2600.0  3100.0  3400.0
+1100.0  1800.0  2600.0  2700.0  3200.0  3400.0
+1000.0  1800.0  2500.0  2600.0  3300.0  3400.0
+1200.0  1500.0  1700.0  1900.0  3000.0  3400.0
+1700.0  2100.0  2300.0  2700.0  3200.0  3300.0
+2000.0  2100.0  2600.0  2800.0  3100.0  3300.0
+2000.0  2100.0  2500.0  2900.0  3100.0  3200.0
+1700.0  2000.0  2300.0  2800.0  3100.0  3200.0
+1600.0  2000.0  2100.0  2700.0  3000.0  3100.0
+1600.0  2000.0  2100.0  2700.0  3100.0  3200.0
+1800.0  1900.0  2200.0  2500.0  2900.0  3100.0
+1700.0  2000.0  2200.0  2500.0  2900.0  3100.0
+1500.0  2000.0  2200.0  2400.0  2900.0  3100.0
+1600.0  1900.0  2200.0  2600.0  3000.0  3100.0
+1600.0  1900.0  2300.0  2700.0  2900.0  3100.0
+1700.0  2000.0  2200.0  2700.0  2900.0  3000.0
+1700.0  2000.0  2300.0  2700.0  2900.0  3100.0
+1700.0  2000.0  2300.0  2600.0  2900.0  3100.0
+1700.0  1900.0  2400.0  2600.0  2800.0  3000.0
+1700.0  1800.0  2300.0  2600.0  2800.0  3000.0
+1700.0  1900.0  2400.0  2600.0  2900.0  3100.0
+1700.0  1900.0  2300.0  2500.0  2800.0  3100.0
+1700.0  2100.0  2400.0  2600.0  2800.0  3100.0
+2000.0  2200.0  2500.0  2700.0  2800.0  3100.0
+1900.0  2200.0  2400.0  2700.0  2900.0  3000.0
+1800.0  2000.0  2300.0  2700.0  2900.0  3000.0
+1800.0  2300.0  2500.0  2700.0  3000.0  3100.0
+2000.0  2400.0  2600.0  2800.0  3100.0  3200.0
+1900.0  2300.0  2700.0  2800.0  3200.0  3300.0
+1800.0  2400.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2300.0  2600.0  2800.0  3200.0  3300.0
+1700.0  2000.0  2300.0  2500.0  2900.0  3000.0
+1700.0  1800.0  2100.0  2500.0  2900.0  3000.0
+1600.0  1700.0  2000.0  2400.0  2900.0  3100.0
+1600.0  1700.0  2100.0  2400.0  2700.0  2900.0
+1500.0  1600.0  2000.0  2600.0  2800.0  3100.0
+1400.0  1500.0  2000.0  2700.0  3200.0  3300.0
+1500.0  1600.0  2100.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2100.0  2600.0  3100.0  3200.0
+1800.0  1900.0  2200.0  2800.0  3100.0  3300.0
+2000.0  2200.0  2800.0  2900.0  3200.0  3400.0
+2000.0  2200.0  2800.0  2900.0  3100.0  3400.0
+2000.0  2100.0  2700.0  2900.0  3100.0  3400.0
+1800.0  2200.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2200.0  2600.0  2800.0  3100.0  3200.0
+1900.0  2200.0  2500.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2500.0  2900.0  3100.0
+1800.0  1900.0  2200.0  2500.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2500.0  2800.0  3000.0
+1500.0  1700.0  2100.0  2400.0  2700.0  3100.0
+1400.0  1500.0  1900.0  2400.0  3000.0  3100.0
+1400.0  1600.0  2000.0  2400.0  3100.0  3200.0
+1500.0  1700.0  2100.0  2400.0  3000.0  3200.0
+1600.0  1800.0  2100.0  2400.0  2900.0  3100.0
+1600.0  1800.0  2100.0  2300.0  3000.0  3200.0
+1600.0  1800.0  2100.0  2300.0  3100.0  3300.0
+1600.0  1700.0  2000.0  2200.0  3200.0  3300.0
+1600.0  1700.0  1900.0  2100.0  3000.0  3300.0
+1700.0  1800.0  2100.0  2400.0  3100.0  3200.0
+2000.0  2300.0  2500.0  2700.0  2900.0  3100.0
+2000.0  2300.0  2600.0  2700.0  3000.0  3200.0
+1900.0  2100.0  2400.0  2600.0  2900.0  3200.0
+1700.0  1900.0  2200.0  2600.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2600.0  2700.0  3100.0
+1600.0  1700.0  2200.0  2600.0  2800.0  3000.0
+1500.0  1600.0  2100.0  2700.0  2800.0  3000.0
+1300.0  1500.0  2000.0  2700.0  3000.0  3200.0
+1200.0  1500.0  2100.0  2800.0  3000.0  3200.0
+1300.0  1500.0  2100.0  2800.0  3000.0  3100.0
+1600.0  1900.0  2100.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2200.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2100.0  2500.0  3200.0  3300.0
+1500.0  1900.0  2400.0  2500.0  2900.0  3200.0
+1600.0  1700.0  2200.0  2500.0  2900.0  3100.0
+1600.0  1700.0  2200.0  2700.0  2800.0  3000.0
+1600.0  1700.0  2200.0  2700.0  2900.0  3100.0
+1500.0  1700.0  2400.0  2700.0  2900.0  3100.0
+1500.0  1800.0  2400.0  2700.0  2900.0  3200.0
+1700.0  2100.0  2500.0  2700.0  3100.0  3200.0
+1700.0  2100.0  2500.0  2600.0  2900.0  3100.0
+1900.0  2300.0  2600.0  2700.0  3000.0  3100.0
+1800.0  2200.0  2600.0  2700.0  3000.0  3100.0
+1900.0  2200.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2100.0  2400.0  2800.0  3000.0  3100.0
+1800.0  2000.0  2300.0  2500.0  3000.0  3300.0
+1600.0  2000.0  2200.0  2600.0  2800.0  3000.0
+1700.0  1800.0  2100.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2100.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2100.0  2400.0  2900.0  3200.0
+1400.0  1600.0  2100.0  2300.0  3000.0  3200.0
+1400.0  1800.0  2100.0  2500.0  3100.0  3200.0
+1700.0  1900.0  2300.0  2500.0  2700.0  3100.0
+1800.0  1900.0  2200.0  2500.0  2800.0  3200.0
+1700.0  1900.0  2100.0  2500.0  2800.0  3100.0
+1700.0  1900.0  2200.0  2500.0  2800.0  3200.0
+1600.0  1800.0  2100.0  2600.0  2800.0  3100.0
+1600.0  1800.0  2200.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2200.0  2600.0  2800.0  3100.0
+1400.0  1600.0  2200.0  2600.0  2900.0  3100.0
+1400.0  1600.0  2300.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2200.0  2700.0  2900.0  3200.0
+1500.0  1700.0  2100.0  2600.0  3000.0  3100.0
+1600.0  1700.0  2100.0  2600.0  3000.0  3100.0
+1600.0  1800.0  2300.0  2500.0  2900.0  3100.0
+1700.0  1900.0  2300.0  2500.0  2900.0  3100.0
+1600.0  1800.0  2300.0  2500.0  2900.0  3000.0
+1500.0  1700.0  2000.0  2700.0  3000.0  3100.0
+1500.0  1600.0  2000.0  2600.0  2900.0  3100.0
+1500.0  1600.0  1900.0  2500.0  2900.0  3000.0
+1500.0  1600.0  1900.0  2600.0  2900.0  3100.0
+1700.0  1900.0  2500.0  2700.0  3100.0  3200.0
+1600.0  1700.0  2300.0  2700.0  2900.0  3200.0
+1600.0  1700.0  2200.0  2700.0  2800.0  3100.0
+1600.0  1700.0  2300.0  2700.0  2800.0  3100.0
+1500.0  1600.0  2200.0  2700.0  2900.0  3200.0
+1500.0  1600.0  2100.0  2700.0  3000.0  3200.0
+1400.0  1500.0  2100.0  2700.0  3000.0  3100.0
+1600.0  1800.0  2200.0  2500.0  3200.0  3300.0
+1900.0  2200.0  2400.0  2700.0  3100.0  3300.0
+1900.0  2100.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2100.0  2400.0  2800.0  3000.0  3200.0
+1600.0  1800.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2400.0  3000.0  3300.0
+1700.0  1900.0  2100.0  2500.0  3100.0  3300.0
+1600.0  1800.0  2200.0  2500.0  3200.0  3400.0
+1700.0  1900.0  2200.0  2500.0  3200.0  3400.0
+1600.0  1800.0  2200.0  2600.0  3200.0  3300.0
+1900.0  2100.0  2500.0  2700.0  2900.0  3100.0
+1900.0  2200.0  2400.0  2600.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2500.0  2700.0  3000.0
+1600.0  1700.0  2100.0  2500.0  2600.0  3000.0
+1600.0  1700.0  2200.0  2400.0  2700.0  2900.0
+1700.0  1800.0  2300.0  2500.0  2800.0  3000.0
+1700.0  1800.0  2300.0  2500.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2400.0  2800.0  3100.0
+1700.0  1900.0  2200.0  2400.0  2800.0  3100.0
+1500.0  2000.0  2300.0  2700.0  2900.0  3100.0
+1500.0  1900.0  2300.0  2500.0  3000.0  3300.0
+1700.0  2000.0  2400.0  2900.0  3200.0  3300.0
+2000.0  2100.0  2400.0  2700.0  3000.0  3100.0
+1900.0  2200.0  2400.0  2600.0  2900.0  3000.0
+1700.0  2100.0  2300.0  2700.0  2900.0  3000.0
+1600.0  2000.0  2200.0  2600.0  3000.0  3100.0
+1600.0  2100.0  2200.0  2600.0  3000.0  3100.0
+1600.0  2100.0  2300.0  2600.0  3000.0  3100.0
+1700.0  2100.0  2300.0  2600.0  2900.0  3100.0
+1800.0  2300.0  2400.0  2700.0  3000.0  3200.0
+1900.0  2300.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2400.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2400.0  2600.0  2800.0  3000.0  3200.0
+1800.0  2400.0  2600.0  2800.0  3000.0  3200.0
+1800.0  2300.0  2600.0  2700.0  3000.0  3100.0
+1600.0  1800.0  2300.0  2500.0  2800.0  3100.0
+1500.0  1800.0  2200.0  2500.0  2800.0  3000.0
+1500.0  1800.0  2300.0  2500.0  2800.0  3100.0
+1400.0  1900.0  2300.0  2500.0  2800.0  3000.0
+2000.0  2100.0  2500.0  2700.0  3100.0  3200.0
+2000.0  2100.0  2600.0  2800.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2700.0  2900.0  3100.0
+1800.0  2100.0  2400.0  2600.0  2900.0  3200.0
+1800.0  2000.0  2400.0  2600.0  2900.0  3200.0
+1700.0  1900.0  2400.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2100.0  2500.0  2900.0  3200.0
+1200.0  1700.0  2200.0  2400.0  2900.0  3200.0
+1500.0  1600.0  1900.0  2500.0  2800.0  3000.0
+1500.0  1600.0  2000.0  2500.0  2800.0  3000.0
+1600.0  1700.0  2100.0  2500.0  2800.0  3200.0
+1700.0  1800.0  2100.0  2400.0  2800.0  3100.0
+1700.0  1800.0  2100.0  2400.0  2900.0  3100.0
+1700.0  1800.0  2300.0  2700.0  3100.0  3300.0
+1300.0  1700.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1800.0  2300.0  2700.0  3100.0  3300.0
+1500.0  1600.0  1900.0  2100.0  2800.0  3300.0
+1600.0  1700.0  2000.0  2100.0  2700.0  3300.0
+1800.0  2200.0  2400.0  2500.0  3000.0  3300.0
+1700.0  2300.0  2400.0  2600.0  3100.0  3200.0
+1700.0  2200.0  2400.0  2600.0  3000.0  3100.0
+1800.0  2000.0  2300.0  2500.0  2800.0  3100.0
+1800.0  2000.0  2200.0  2500.0  2900.0  3100.0
+1800.0  2100.0  2200.0  2700.0  3000.0  3100.0
+1800.0  2000.0  2200.0  2600.0  2900.0  3000.0
+1700.0  2000.0  2100.0  2600.0  3000.0  3100.0
+1700.0  2000.0  2100.0  2500.0  3000.0  3100.0
+1700.0  1900.0  2300.0  2500.0  2800.0  3200.0
+1600.0  1900.0  2300.0  2500.0  2900.0  3200.0
+1500.0  1800.0  2200.0  2500.0  3100.0  3300.0
+1600.0  1700.0  2300.0  2700.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2600.0  2900.0  3000.0
+1400.0  1600.0  2000.0  2600.0  2900.0  3200.0
+1500.0  1600.0  2000.0  2600.0  2900.0  3200.0
+1600.0  1700.0  2100.0  2500.0  2900.0  3200.0
+1500.0  1900.0  2300.0  2400.0  3000.0  3300.0
+1600.0  1800.0  2300.0  2500.0  3000.0  3300.0
+1800.0  2200.0  2500.0  2700.0  2900.0  3100.0
+1500.0  1900.0  2200.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2700.0  2900.0  3100.0
+1400.0  1600.0  2000.0  2700.0  2800.0  3000.0
+1400.0  1600.0  1900.0  2600.0  2800.0  3000.0
+1400.0  1600.0  2100.0  2600.0  2900.0  3200.0
+1500.0  1600.0  2100.0  2600.0  3000.0  3200.0
+1500.0  1600.0  2100.0  2600.0  2900.0  3100.0
+1600.0  1700.0  2000.0  2600.0  2900.0  3000.0
+1700.0  1900.0  2100.0  2600.0  2800.0  3100.0
+1800.0  2000.0  2400.0  2700.0  2900.0  3200.0
+1900.0  2000.0  2400.0  2700.0  3000.0  3200.0
+1800.0  2200.0  2600.0  2900.0  3100.0  3300.0
+1800.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1800.0  1900.0  2100.0  2400.0  3000.0  3200.0
+1700.0  1900.0  2100.0  2500.0  3000.0  3200.0
+1600.0  1700.0  2300.0  2500.0  2800.0  3200.0
+1600.0  1700.0  2200.0  2600.0  2800.0  3200.0
+1600.0  1700.0  2100.0  2600.0  2800.0  3200.0
+1600.0  1700.0  2000.0  2600.0  2800.0  3100.0
+1400.0  1700.0  2000.0  2600.0  2900.0  3100.0
+1800.0  2200.0  2500.0  2900.0  3100.0  3300.0
+1700.0  2100.0  2500.0  2900.0  3100.0  3200.0
+1500.0  1700.0  2400.0  2700.0  2900.0  3200.0
+1400.0  1500.0  2300.0  2500.0  2800.0  3100.0
+1300.0  1500.0  2300.0  2500.0  2800.0  3100.0
+1300.0  1500.0  2200.0  2600.0  2700.0  3100.0
+1200.0  1600.0  2400.0  2600.0  3000.0  3200.0
+1600.0  2000.0  2500.0  2700.0  3000.0  3300.0
+1500.0  1700.0  2500.0  2700.0  3000.0  3200.0
+1400.0  1500.0  2000.0  2700.0  3000.0  3100.0
+1400.0  1500.0  1900.0  2600.0  3000.0  3100.0
+2000.0  2300.0  2800.0  2900.0  3200.0  3400.0
+2100.0  2500.0  2700.0  2800.0  3200.0  3400.0
+1900.0  2300.0  2500.0  2700.0  3100.0  3400.0
+1800.0  1900.0  2200.0  2500.0  3000.0  3300.0
+1900.0  2200.0  2500.0  2600.0  2900.0  3200.0
+1900.0  2100.0  2300.0  2700.0  2800.0  3100.0
+1900.0  2000.0  2200.0  2600.0  3000.0  3200.0
+1900.0  2000.0  2500.0  2800.0  3100.0  3300.0
+1800.0  1900.0  2200.0  2700.0  2800.0  3100.0
+1700.0  1800.0  2400.0  2600.0  2800.0  3200.0
+1700.0  1900.0  2400.0  2500.0  2900.0  3300.0
+1400.0  1700.0  2300.0  2400.0  2600.0  3000.0
+1600.0  1700.0  2000.0  2200.0  2900.0  3200.0
+1600.0  1700.0  2000.0  2300.0  2900.0  3200.0
+1800.0  1900.0  2100.0  2600.0  2800.0  3100.0
+1800.0  1900.0  2300.0  2600.0  2900.0  3100.0
+1100.0  1800.0  2200.0  2400.0  2900.0  3200.0
+1200.0  1700.0  2300.0  2500.0  3000.0  3200.0
+1500.0  1600.0  2200.0  2600.0  2700.0  3100.0
+1700.0  1800.0  2100.0  2500.0  3000.0  3100.0
+1300.0  1700.0  2000.0  2400.0  3000.0  3200.0
+1300.0  1600.0  2000.0  2300.0  3100.0  3200.0
+1300.0  1600.0  1900.0  2300.0  3100.0  3200.0
+1400.0  1600.0  1900.0  2300.0  3100.0  3200.0
+1400.0  1600.0  1900.0  2400.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2400.0  3100.0  3200.0
+1800.0  2100.0  2200.0  2700.0  3100.0  3200.0
+1700.0  2100.0  2200.0  2700.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2700.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2600.0  3200.0  3400.0
+1900.0  2200.0  2600.0  3000.0  3300.0  3400.0
+1400.0  1800.0  2200.0  2600.0  3000.0  3300.0
+1000.0  1400.0  2400.0  2600.0  2900.0  3200.0
+1200.0  1500.0  2500.0  2600.0  3000.0  3300.0
+1200.0  1500.0  2400.0  2600.0  3000.0  3300.0
+1200.0  1500.0  2400.0  2600.0  2900.0  3300.0
+1200.0  1500.0  2400.0  2500.0  2900.0  3300.0
+1200.0  1500.0  2300.0  2500.0  3000.0  3300.0
+1200.0  1500.0  2300.0  2400.0  3000.0  3300.0
+1300.0  2000.0  2300.0  2700.0  3100.0  3200.0
+1700.0  1800.0  2200.0  2500.0  2800.0  3200.0
+1800.0  1900.0  2300.0  2500.0  2700.0  3200.0
+1800.0  1900.0  2300.0  2600.0  2700.0  3100.0
+1800.0  1900.0  2400.0  2600.0  2800.0  3200.0
+1900.0  2000.0  2700.0  2800.0  3100.0  3300.0
+1900.0  2000.0  2600.0  2800.0  3000.0  3300.0
+1900.0  2000.0  2500.0  2800.0  3000.0  3300.0
+1900.0  2100.0  2700.0  2800.0  3100.0  3300.0
+1900.0  2000.0  2700.0  2800.0  3000.0  3300.0
+1900.0  2000.0  2600.0  2800.0  3000.0  3200.0
+1200.0  1500.0  2200.0  2500.0  3100.0  3300.0
+1600.0  1900.0  2200.0  2600.0  3000.0  3200.0
+1300.0  1700.0  2300.0  2500.0  3100.0  3200.0
+1400.0  1500.0  2100.0  2400.0  2600.0  3100.0
+1500.0  1600.0  2000.0  2400.0  2700.0  3100.0
+1600.0  1700.0  2000.0  2500.0  2700.0  3100.0
+1900.0  2100.0  2300.0  2600.0  2900.0  3200.0
+1900.0  2100.0  2400.0  2600.0  2900.0  3100.0
+1700.0  2000.0  2200.0  2700.0  2900.0  3100.0
+1800.0  2000.0  2100.0  2700.0  3000.0  3100.0
+1800.0  1900.0  2100.0  2700.0  3000.0  3200.0
+1900.0  2100.0  2700.0  2800.0  3000.0  3300.0
+1900.0  2300.0  2700.0  2800.0  3100.0  3300.0
+2000.0  2400.0  2700.0  2800.0  3200.0  3400.0
+1600.0  2000.0  2300.0  2600.0  3000.0  3100.0
+1000.0  1400.0  2200.0  2400.0  3100.0  3300.0
+1400.0  1500.0  2000.0  2100.0  2900.0  3300.0
+1800.0  1900.0  2100.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2700.0  3000.0  3300.0
+1800.0  2000.0  2300.0  2700.0  3100.0  3300.0
+1800.0  2100.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2200.0  2800.0  2900.0  3200.0  3300.0
+2000.0  2200.0  2500.0  2900.0  3200.0  3300.0
+1800.0  2000.0  2300.0  2400.0  3100.0  3200.0
+1800.0  2000.0  2300.0  2400.0  3000.0  3200.0
+1800.0  1900.0  2200.0  2400.0  3000.0  3200.0
+1600.0  1800.0  2100.0  2600.0  2800.0  3000.0
+1500.0  1600.0  2200.0  2600.0  2900.0  3100.0
+1600.0  1700.0  2000.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2000.0  2500.0  3100.0  3200.0
+1600.0  1900.0  2000.0  2500.0  3000.0  3100.0
+1900.0  2300.0  2800.0  2900.0  3200.0  3400.0
+2000.0  2200.0  2700.0  3000.0  3200.0  3300.0
+1900.0  2400.0  2800.0  2900.0  3200.0  3300.0
+2000.0  2400.0  2700.0  2900.0  3100.0  3300.0
+1800.0  2200.0  2400.0  2800.0  3000.0  3200.0
+1900.0  2200.0  2700.0  3000.0  3200.0  3400.0
+1900.0  2200.0  2600.0  2800.0  3000.0  3300.0
+1600.0  1700.0  2400.0  2600.0  2800.0  3200.0
+1600.0  1700.0  2300.0  2700.0  2800.0  3200.0
+1600.0  1700.0  2200.0  2700.0  2800.0  3200.0
+1600.0  1700.0  2000.0  2400.0  2900.0  3200.0
+1600.0  1900.0  2200.0  2500.0  2800.0  3000.0
+1600.0  2000.0  2400.0  2800.0  3200.0  3300.0
+1900.0  2000.0  2300.0  2700.0  3000.0  3200.0
+1600.0  1800.0  2000.0  2700.0  3000.0  3100.0
+1400.0  1600.0  2100.0  2700.0  2900.0  3100.0
+1900.0  2200.0  2800.0  3000.0  3300.0  3500.0
+1700.0  2000.0  2700.0  2800.0  3100.0  3300.0
+1600.0  1800.0  2200.0  2500.0  2800.0  3100.0
+1600.0  1800.0  2100.0  2400.0  2800.0  3000.0
+1600.0  2000.0  2300.0  2600.0  2800.0  3000.0
+1600.0  1900.0  2300.0  2600.0  2800.0  3000.0
+1800.0  2200.0  2500.0  2900.0  3200.0  3400.0
+1700.0  1900.0  2200.0  2800.0  3100.0  3200.0
+1600.0  2000.0  2300.0  2700.0  3000.0  3300.0
+1600.0  2000.0  2200.0  2600.0  3000.0  3200.0
+1800.0  2100.0  2300.0  2600.0  3000.0  3100.0
+1800.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1900.0  2200.0  2400.0  2600.0  3100.0  3200.0
+1800.0  1900.0  2400.0  2600.0  2900.0  3200.0
+1300.0  2000.0  2300.0  2400.0  2800.0  3300.0
+1800.0  2000.0  2400.0  2600.0  2900.0  3300.0
+1900.0  2200.0  2300.0  2700.0  3000.0  3100.0
+1900.0  2200.0  2300.0  2700.0  3000.0  3200.0
+1800.0  2200.0  2400.0  2800.0  3100.0  3200.0
+1600.0  2100.0  2200.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2300.0  2500.0  2900.0  3200.0
+1800.0  2200.0  2400.0  2700.0  3100.0  3300.0
+1200.0  2000.0  2500.0  2600.0  3100.0  3200.0
+1000.0  1600.0  2700.0  2900.0  3200.0  3300.0
+1000.0  1500.0  2700.0  2900.0  3200.0  3300.0
+1500.0  1700.0  2600.0  2800.0  3100.0  3300.0
+1500.0  1700.0  2600.0  2800.0  3000.0  3300.0
+1600.0  1700.0  2500.0  2800.0  3000.0  3300.0
+1600.0  1700.0  2400.0  2800.0  3000.0  3300.0
+1700.0  1800.0  2000.0  2400.0  3000.0  3200.0
+1700.0  1900.0  2100.0  2500.0  3000.0  3100.0
+1700.0  1900.0  2200.0  2500.0  2900.0  3100.0
+1700.0  1800.0  2200.0  2500.0  2800.0  3000.0
+1700.0  1800.0  2400.0  2600.0  2800.0  3100.0
+1200.0  1600.0  2200.0  2400.0  2900.0  3100.0
+1300.0  1800.0  2400.0  2600.0  2900.0  3200.0
+1300.0  1500.0  2000.0  2600.0  3000.0  3200.0
+1500.0  1800.0  2400.0  2700.0  3100.0  3200.0
+1800.0  2100.0  2400.0  2700.0  3100.0  3400.0
+1500.0  1600.0  2000.0  2200.0  3000.0  3300.0
+1600.0  1700.0  2100.0  2200.0  3000.0  3300.0
+1700.0  1800.0  2100.0  2300.0  3100.0  3300.0
+1800.0  1900.0  2200.0  2400.0  2900.0  3100.0
+1800.0  2000.0  2300.0  2700.0  3100.0  3200.0
+1500.0  1900.0  2200.0  2500.0  3000.0  3200.0
+1500.0  2100.0  2300.0  2500.0  3100.0  3300.0
+1700.0  1900.0  2400.0  2700.0  2900.0  3100.0
+1400.0  1800.0  2200.0  2300.0  3100.0  3400.0
+1300.0  1800.0  2300.0  2400.0  3000.0  3300.0
+1800.0  2200.0  2400.0  2600.0  3100.0  3300.0
+1800.0  2100.0  2300.0  2500.0  3100.0  3200.0
+1100.0  1700.0  2200.0  2300.0  3000.0  3200.0
+1100.0  1600.0  2200.0  2400.0  3100.0  3200.0
+1200.0  2000.0  2300.0  2500.0  3000.0  3100.0
+1700.0  2300.0  2500.0  2800.0  3200.0  3300.0
+1500.0  1900.0  2200.0  2400.0  2900.0  3100.0
+1400.0  1900.0  2200.0  2500.0  3000.0  3200.0
+1400.0  2000.0  2200.0  2600.0  3100.0  3200.0
+1700.0  2000.0  2300.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2500.0  2800.0  2900.0  3200.0
+1700.0  1800.0  2500.0  2700.0  2900.0  3200.0
+1600.0  1800.0  2400.0  2600.0  2800.0  3200.0
+1400.0  1700.0  2100.0  2500.0  3000.0  3300.0
+1400.0  1600.0  1900.0  2000.0  3100.0  3300.0
+1400.0  1600.0  2000.0  2100.0  3100.0  3300.0
+1900.0  2000.0  2300.0  2400.0  2900.0  3300.0
+2100.0  2300.0  2600.0  2900.0  3100.0  3300.0
+1200.0  1800.0  2200.0  2400.0  3000.0  3200.0
+1700.0  2000.0  2300.0  2600.0  3000.0  3300.0
+1900.0  2400.0  2700.0  2900.0  3300.0  3400.0
+1400.0  1600.0  2100.0  2500.0  3100.0  3200.0
+1400.0  1700.0  2300.0  2500.0  3200.0  3400.0
+1400.0  1600.0  2300.0  2500.0  3200.0  3400.0
+1400.0  1600.0  2300.0  2500.0  3100.0  3400.0
+1500.0  1700.0  2200.0  2800.0  3100.0  3200.0
+1500.0  1600.0  2300.0  2800.0  3000.0  3200.0
+1400.0  1600.0  2300.0  2800.0  3000.0  3200.0
+1200.0  1400.0  2400.0  2900.0  3100.0  3200.0
+1200.0  1400.0  2400.0  2900.0  3200.0  3300.0
+1100.0  1400.0  2400.0  2900.0  3200.0  3300.0
+1600.0  1800.0  2400.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2400.0  2800.0  3000.0  3200.0
+1900.0  2300.0  2700.0  3000.0  3300.0  3400.0
+1800.0  2300.0  2800.0  3000.0  3200.0  3400.0
+1800.0  1900.0  2400.0  2800.0  3100.0  3300.0
+1700.0  1800.0  2100.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2700.0  3100.0  3200.0
+1600.0  1700.0  2000.0  2500.0  3100.0  3200.0
+1400.0  1700.0  2200.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2600.0  3100.0  3200.0
+1700.0  1900.0  2200.0  2700.0  3100.0  3200.0
+1900.0  2200.0  2500.0  2800.0  3000.0  3100.0
+2000.0  2200.0  2500.0  2700.0  3200.0  3300.0
+1700.0  1800.0  2300.0  2800.0  2900.0  3200.0
+1700.0  1800.0  2400.0  2800.0  2900.0  3200.0
+1600.0  1800.0  2600.0  2800.0  3000.0  3300.0
+2100.0  2300.0  2500.0  2800.0  3000.0  3300.0
+2100.0  2200.0  2500.0  2600.0  2900.0  3200.0
+1900.0  2100.0  2400.0  2600.0  2800.0  3200.0
+1800.0  2000.0  2700.0  2800.0  3000.0  3300.0
+1700.0  2100.0  2400.0  2600.0  3000.0  3200.0
+1800.0  2000.0  2400.0  2500.0  3100.0  3400.0
+1900.0  2200.0  2500.0  2600.0  3100.0  3200.0
+1900.0  2200.0  2500.0  2600.0  3000.0  3200.0
+1800.0  2200.0  2500.0  2600.0  3000.0  3100.0
+2000.0  2200.0  2600.0  2700.0  3100.0  3200.0
+2000.0  2300.0  2600.0  2700.0  3100.0  3200.0
+1800.0  2100.0  2300.0  2500.0  2900.0  3100.0
+1800.0  2100.0  2700.0  3000.0  3300.0  3400.0
+1800.0  2000.0  2700.0  2900.0  3200.0  3300.0
+1900.0  2100.0  2400.0  2700.0  3000.0  3300.0
+1900.0  2100.0  2400.0  2700.0  2900.0  3100.0
+2000.0  2200.0  2400.0  2700.0  2900.0  3100.0
+2000.0  2400.0  2600.0  2700.0  2900.0  3100.0
+1500.0  1700.0  2200.0  2300.0  3100.0  3300.0
+1400.0  1600.0  2300.0  2600.0  2900.0  3300.0
+1600.0  1700.0  2500.0  2700.0  2900.0  3200.0
+1600.0  1700.0  2500.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2300.0  2400.0  3000.0  3400.0
+1500.0  1700.0  2100.0  2300.0  2900.0  3300.0
+1600.0  1700.0  2100.0  2300.0  3000.0  3300.0
+1500.0  2000.0  2300.0  2600.0  3100.0  3300.0
+1500.0  2100.0  2500.0  2600.0  3000.0  3200.0
+1500.0  2000.0  2500.0  2600.0  3100.0  3200.0
+1600.0  1700.0  2000.0  2500.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2600.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2500.0  3000.0  3100.0
+1800.0  1900.0  2200.0  2600.0  3000.0  3100.0
+1700.0  2100.0  2600.0  2900.0  3100.0  3400.0
+1700.0  2000.0  2600.0  2900.0  3200.0  3300.0
+1800.0  1900.0  2300.0  2800.0  2900.0  3100.0
+1800.0  1900.0  2600.0  2800.0  3200.0  3300.0
+1800.0  2000.0  2500.0  2900.0  3200.0  3400.0
+1800.0  2400.0  2800.0  2900.0  3300.0  3400.0
+1500.0  1800.0  2300.0  2700.0  3200.0  3300.0
+1600.0  1700.0  2400.0  2800.0  3000.0  3200.0
+1200.0  1600.0  2200.0  2600.0  2900.0  3200.0
+1400.0  1800.0  2400.0  2800.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2800.0  3100.0  3300.0
+1300.0  1700.0  2300.0  2600.0  3000.0  3200.0
+1500.0  1600.0  2400.0  2600.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2600.0  3000.0  3100.0
+1800.0  2000.0  2600.0  2900.0  3200.0  3400.0
+1900.0  2000.0  2700.0  2900.0  3200.0  3400.0
+1200.0  1800.0  2400.0  2500.0  3000.0  3300.0
+1300.0  1900.0  2400.0  2500.0  3100.0  3300.0
+1700.0  2000.0  2500.0  2900.0  3200.0  3300.0
+1100.0  1400.0  2400.0  2900.0  3100.0  3200.0
+1700.0  1800.0  2200.0  2700.0  3100.0  3200.0
+2000.0  2200.0  2400.0  2600.0  3000.0  3100.0
+1900.0  2100.0  2300.0  2600.0  3000.0  3100.0
+1700.0  1900.0  2500.0  2800.0  3100.0  3200.0
+1400.0  1600.0  2400.0  2800.0  3000.0  3200.0
+1200.0  1500.0  2200.0  2600.0  3100.0  3300.0
+1400.0  1600.0  2100.0  2700.0  3100.0  3200.0
+1500.0  1700.0  2200.0  2400.0  2900.0  3100.0
+1500.0  1800.0  2200.0  2300.0  2800.0  2900.0
+1500.0  1800.0  2200.0  2500.0  2900.0  3100.0
+1600.0  1800.0  2200.0  2500.0  2900.0  3100.0
+1700.0  1800.0  2200.0  2700.0  2900.0  3000.0
+1600.0  1800.0  2100.0  2800.0  3000.0  3100.0
+1800.0  1900.0  2300.0  2800.0  3100.0  3300.0
+1800.0  2000.0  2400.0  2800.0  3200.0  3400.0
+1900.0  2000.0  2500.0  2800.0  3200.0  3400.0
+1900.0  2000.0  2300.0  2700.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2600.0  3000.0  3200.0
+1400.0  1700.0  2200.0  2500.0  3100.0  3300.0
+1900.0  2300.0  2500.0  2800.0  3100.0  3300.0
+1300.0  2000.0  2200.0  2400.0  2800.0  3100.0
+1400.0  1700.0  2300.0  2600.0  3000.0  3300.0
+1500.0  1600.0  2300.0  2700.0  2800.0  3100.0
+1600.0  1800.0  2300.0  2600.0  2800.0  3100.0
+1900.0  2000.0  2400.0  2600.0  2900.0  3100.0
+2000.0  2500.0  2600.0  2700.0  3200.0  3300.0
+2200.0  2500.0  2600.0  2900.0  3100.0  3300.0
+2100.0  2400.0  2600.0  2700.0  3200.0  3300.0
+2100.0  2400.0  2600.0  2700.0  3200.0  3400.0
+1700.0  1900.0  2500.0  2700.0  2900.0  3100.0
+1900.0  2300.0  2400.0  2700.0  3000.0  3200.0
+2000.0  2300.0  2500.0  2700.0  3000.0  3100.0
+2000.0  2400.0  2500.0  2800.0  3200.0  3300.0
+2000.0  2400.0  2600.0  2800.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1600.0  2200.0  2400.0  3000.0  3300.0
+1400.0  1600.0  2100.0  2400.0  2900.0  3200.0
+1600.0  1700.0  2200.0  2300.0  2700.0  3200.0
+1700.0  1800.0  2100.0  2300.0  2800.0  3300.0
+1700.0  1800.0  2200.0  2400.0  2800.0  3300.0
+1900.0  2000.0  2200.0  2500.0  3000.0  3200.0
+1300.0  2000.0  2300.0  2400.0  2900.0  3200.0
+1900.0  2200.0  2400.0  2500.0  2900.0  3200.0
+1600.0  1800.0  2200.0  2500.0  2700.0  3100.0
+1600.0  1700.0  2300.0  2500.0  3000.0  3400.0
+1900.0  2000.0  2400.0  2700.0  2900.0  3300.0
+1800.0  2200.0  2400.0  2600.0  2900.0  3100.0
+1700.0  2000.0  2300.0  2600.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2600.0  2800.0  3000.0
+1600.0  1700.0  2100.0  2700.0  2900.0  3000.0
+1400.0  1600.0  2000.0  2200.0  2800.0  3200.0
+1200.0  1600.0  2000.0  2400.0  3000.0  3200.0
+1200.0  1700.0  2200.0  2500.0  3000.0  3100.0
+1600.0  1900.0  2600.0  2800.0  3000.0  3200.0
+1500.0  1900.0  2300.0  2700.0  2900.0  3200.0
+1200.0  1900.0  2300.0  2400.0  3000.0  3300.0
+1400.0  1600.0  2300.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2500.0  3000.0  3200.0
+1500.0  1600.0  2100.0  2400.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2300.0  3000.0  3300.0
+1600.0  1700.0  2100.0  2200.0  2900.0  3300.0
+1500.0  1600.0  2000.0  2100.0  2800.0  3200.0
+1500.0  1600.0  2000.0  2200.0  2800.0  3200.0
+1500.0  1600.0  2000.0  2200.0  2900.0  3200.0
+1500.0  1800.0  2100.0  2200.0  2900.0  3300.0
+2100.0  2300.0  2500.0  2700.0  2900.0  3100.0
+2000.0  2200.0  2400.0  2600.0  2800.0  3100.0
+1800.0  2100.0  2300.0  2600.0  2800.0  3000.0
+1600.0  1800.0  2400.0  2600.0  2800.0  3000.0
+1200.0  1300.0  2100.0  2700.0  2800.0  3000.0
+1100.0  1300.0  2300.0  2700.0  2900.0  3100.0
+1100.0  1300.0  2300.0  2700.0  2800.0  3100.0
+1100.0  1300.0  2300.0  2800.0  2900.0  3100.0
+1500.0  1800.0  2300.0  2700.0  3100.0  3200.0
+1200.0  1800.0  2300.0  2600.0  3000.0  3200.0
+1700.0  1800.0  2300.0  2600.0  2800.0  3200.0
+1900.0  2000.0  2400.0  2600.0  2800.0  3200.0
+2100.0  2200.0  2400.0  2600.0  3100.0  3300.0
+2000.0  2200.0  2400.0  2600.0  3100.0  3300.0
+2300.0  2500.0  2800.0  3000.0  3200.0  3300.0
+1900.0  2200.0  2700.0  2800.0  3100.0  3300.0
+1600.0  1700.0  2200.0  2600.0  3000.0  3300.0
+1500.0  1700.0  2100.0  2400.0  3100.0  3300.0
+1300.0  1600.0  2100.0  2400.0  3200.0  3400.0
+1400.0  2000.0  2300.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2300.0  2500.0  3000.0  3300.0
+1400.0  1600.0  2300.0  2400.0  2800.0  3200.0
+1400.0  1600.0  2300.0  2500.0  2800.0  3200.0
+1400.0  1500.0  2300.0  2500.0  2800.0  3200.0
+1400.0  1500.0  2200.0  2600.0  3000.0  3300.0
+1500.0  1600.0  2000.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2200.0  2700.0  3000.0  3200.0
+1500.0  1600.0  2300.0  2700.0  3000.0  3200.0
+1800.0  2000.0  2500.0  2800.0  2900.0  3200.0
+1700.0  1900.0  2500.0  2700.0  2900.0  3200.0
+1900.0  2200.0  2600.0  2800.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2200.0  2700.0  3100.0  3200.0
+1300.0  1500.0  2100.0  2800.0  3100.0  3200.0
+1500.0  1600.0  2400.0  2800.0  3000.0  3300.0
+1400.0  1500.0  2500.0  2600.0  2900.0  3200.0
+1500.0  1600.0  2400.0  2600.0  2800.0  3300.0
+1600.0  1700.0  2400.0  2600.0  2800.0  3300.0
+1800.0  2000.0  2300.0  2600.0  3000.0  3100.0
+1800.0  2000.0  2300.0  2700.0  3000.0  3100.0
+1900.0  2100.0  2400.0  2800.0  3100.0  3300.0
+1900.0  2100.0  2400.0  2800.0  3000.0  3300.0
+1800.0  1900.0  2300.0  2700.0  2900.0  3100.0
+1800.0  2100.0  2300.0  2700.0  3000.0  3100.0
+1900.0  2100.0  2300.0  2800.0  3000.0  3100.0
+1400.0  2000.0  2200.0  2500.0  3000.0  3200.0
+1900.0  2200.0  2600.0  3000.0  3200.0  3300.0
+1800.0  2200.0  2600.0  3000.0  3200.0  3300.0
+1500.0  1600.0  2400.0  2600.0  2800.0  3200.0
+1400.0  1600.0  2500.0  2700.0  2900.0  3200.0
+1500.0  1600.0  2400.0  2700.0  2900.0  3100.0
+1500.0  2100.0  2400.0  2700.0  3100.0  3300.0
+1900.0  2000.0  2300.0  2600.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2600.0  2900.0  3100.0
+1700.0  2000.0  2200.0  2600.0  2900.0  3100.0
+1700.0  2200.0  2400.0  2700.0  3000.0  3200.0
+1700.0  1900.0  2500.0  2600.0  2900.0  3100.0
+1500.0  1700.0  2500.0  2600.0  2900.0  3100.0
+1400.0  1600.0  2300.0  2600.0  2900.0  3100.0
+1200.0  1400.0  2200.0  2600.0  2900.0  3200.0
+1600.0  1700.0  2200.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2500.0  3100.0  3200.0
+1600.0  1900.0  2200.0  2700.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2800.0  3100.0  3200.0
+1900.0  2100.0  2500.0  2700.0  3100.0  3400.0
+2100.0  2300.0  2600.0  2800.0  3000.0  3200.0
+2000.0  2300.0  2600.0  2800.0  3000.0  3200.0
+2100.0  2400.0  2700.0  2800.0  3000.0  3200.0
+1600.0  2300.0  2600.0  2800.0  3000.0  3100.0
+1700.0  2300.0  2600.0  2800.0  3000.0  3100.0
+1600.0  1700.0  2400.0  2600.0  3000.0  3300.0
+1500.0  1700.0  2400.0  2500.0  2900.0  3300.0
+1600.0  1900.0  2300.0  2600.0  2700.0  3300.0
+1600.0  1900.0  2300.0  2500.0  3300.0  3400.0
+1600.0  1800.0  2300.0  2500.0  3200.0  3400.0
+1800.0  2200.0  2700.0  2900.0  3300.0  3500.0
+1700.0  2000.0  2400.0  2600.0  3300.0  3400.0
+1800.0  2200.0  2800.0  3000.0  3200.0  3300.0
+2100.0  2400.0  2800.0  3100.0  3400.0  3500.0
+2100.0  2500.0  2800.0  3100.0  3400.0  3500.0
+1900.0  2300.0  2900.0  3000.0  3300.0  3400.0
+1900.0  2000.0  2300.0  2400.0  3200.0  3400.0
+1400.0  1700.0  2000.0  2300.0  3000.0  3100.0
+1400.0  1600.0  1900.0  2100.0  3000.0  3100.0
+1400.0  1600.0  1800.0  2100.0  3100.0  3200.0
+1400.0  1600.0  1800.0  2000.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2300.0  2900.0  3300.0
+1600.0  1800.0  2400.0  2500.0  2900.0  3300.0
+1900.0  2000.0  2200.0  2400.0  3100.0  3300.0
+1900.0  2000.0  2200.0  2400.0  3200.0  3400.0
+1300.0  1500.0  2000.0  2500.0  3000.0  3200.0
+1300.0  1600.0  2100.0  2500.0  3000.0  3200.0
+1300.0  1600.0  2300.0  2600.0  3200.0  3300.0
+1400.0  1800.0  2200.0  2600.0  3200.0  3400.0
+1600.0  1800.0  2100.0  2400.0  3300.0  3400.0
+1700.0  1900.0  2200.0  2400.0  3200.0  3400.0
+1800.0  2000.0  2400.0  2700.0  3200.0  3400.0
+1900.0  2200.0  2600.0  2700.0  3000.0  3200.0
+1800.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2400.0  3100.0  3200.0
+1400.0  1600.0  1800.0  2000.0  3000.0  3100.0
+1400.0  1600.0  1800.0  2000.0  2900.0  3000.0
+1400.0  1600.0  1800.0  2100.0  2800.0  3000.0
+1500.0  1700.0  2100.0  2400.0  3000.0  3300.0
+1400.0  1600.0  2200.0  2500.0  3200.0  3300.0
+1100.0  1700.0  2400.0  2600.0  3100.0  3300.0
+1200.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2800.0  3300.0  3400.0
+1600.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1800.0  2200.0  2700.0  3100.0  3400.0  3500.0
+1800.0  2200.0  2800.0  3000.0  3400.0  3500.0
+1900.0  2300.0  2800.0  3100.0  3400.0  3500.0
+1900.0  2400.0  2800.0  3100.0  3300.0  3400.0
+1800.0  2200.0  2600.0  2900.0  3400.0  3500.0
+1600.0  1800.0  2400.0  2800.0  3200.0  3300.0
+2000.0  2500.0  2600.0  2900.0  3200.0  3300.0
+2100.0  2400.0  2600.0  3000.0  3200.0  3300.0
+2200.0  2500.0  2700.0  3100.0  3200.0  3300.0
+2100.0  2500.0  2600.0  2800.0  3300.0  3400.0
+2000.0  2100.0  2700.0  2900.0  3300.0  3400.0
+1900.0  2000.0  2300.0  2500.0  3100.0  3400.0
+1700.0  1900.0  2300.0  2400.0  3100.0  3400.0
+1600.0  1900.0  2300.0  2500.0  3200.0  3400.0
+1600.0  2200.0  2700.0  3000.0  3300.0  3400.0
+1800.0  2300.0  2700.0  3000.0  3400.0  3500.0
+1700.0  2300.0  2500.0  2800.0  3300.0  3400.0
+1500.0  1900.0  2500.0  2700.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2800.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2500.0  3200.0  3300.0
+1100.0  2000.0  2400.0  2500.0  3200.0  3300.0
+1400.0  1800.0  2400.0  2700.0  3100.0  3300.0
+1500.0  1900.0  2500.0  2700.0  3100.0  3300.0
+1500.0  1900.0  2300.0  2500.0  2700.0  2900.0
+1400.0  1800.0  2200.0  2500.0  2700.0  2900.0
+1400.0  1800.0  2400.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2400.0  2600.0  3000.0  3300.0
+1500.0  1900.0  2100.0  2300.0  3200.0  3300.0
+1400.0  1800.0  2300.0  2400.0  3000.0  3300.0
+2000.0  2300.0  2800.0  3000.0  3400.0  3500.0
+1600.0  1900.0  2200.0  2300.0  3100.0  3400.0
+1600.0  1800.0  2000.0  2500.0  3000.0  3100.0
+1500.0  1700.0  1800.0  2400.0  3100.0  3200.0
+1500.0  1600.0  1800.0  2400.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2600.0  3100.0  3200.0
+1700.0  1900.0  2300.0  2500.0  2900.0  3300.0
+1900.0  2300.0  2700.0  2900.0  3100.0  3300.0
+1400.0  1700.0  2300.0  2500.0  3100.0  3200.0
+1200.0  1700.0  2300.0  2500.0  3100.0  3200.0
+1300.0  2200.0  2600.0  2800.0  3100.0  3300.0
+1100.0  1700.0  2500.0  2600.0  3200.0  3400.0
+1300.0  1600.0  2500.0  2600.0  3200.0  3300.0
+1400.0  1500.0  2500.0  2600.0  3100.0  3300.0
+1700.0  1800.0  2300.0  2500.0  2700.0  3300.0
+1800.0  2000.0  2500.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2400.0  2500.0  2900.0  3200.0
+1800.0  1900.0  2400.0  2500.0  2800.0  3200.0
+1900.0  2000.0  2300.0  2500.0  2800.0  3300.0
+1800.0  2000.0  2200.0  2500.0  2800.0  3300.0
+1900.0  2300.0  2700.0  3000.0  3300.0  3500.0
+2100.0  2300.0  2900.0  3000.0  3200.0  3300.0
+1900.0  2100.0  2800.0  2900.0  3100.0  3300.0
+1700.0  2000.0  2600.0  2700.0  2900.0  3100.0
+1700.0  2100.0  2600.0  2800.0  3000.0  3200.0
+1700.0  2100.0  2600.0  2900.0  3100.0  3300.0
+1400.0  1500.0  1700.0  2900.0  3300.0  3400.0
+1400.0  1700.0  1800.0  2600.0  3300.0  3400.0
+1400.0  1700.0  2000.0  2700.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2300.0  2900.0  3000.0
+1400.0  1700.0  1800.0  2200.0  3000.0  3100.0
+1500.0  1600.0  2000.0  2100.0  3000.0  3200.0
+1300.0  1600.0  1800.0  2000.0  3000.0  3100.0
+1300.0  1600.0  1800.0  2000.0  3100.0  3200.0
+1300.0  1500.0  1700.0  2200.0  3200.0  3300.0
+1300.0  1600.0  1700.0  2200.0  3200.0  3300.0
+1300.0  1500.0  1600.0  2100.0  3200.0  3300.0
+1600.0  1700.0  2100.0  2300.0  3100.0  3300.0
+1500.0  1600.0  2300.0  2400.0  3100.0  3400.0
+1900.0  2400.0  2800.0  3100.0  3400.0  3500.0
+2000.0  2400.0  2800.0  3000.0  3400.0  3500.0
+1600.0  1800.0  2200.0  2600.0  2900.0  3100.0
+1300.0  1600.0  1800.0  2400.0  3100.0  3200.0
+1200.0  1600.0  1800.0  2100.0  3000.0  3100.0
+1400.0  1900.0  2100.0  2400.0  3000.0  3100.0
+1300.0  1900.0  2100.0  2300.0  3000.0  3200.0
+1300.0  1800.0  2100.0  2300.0  3000.0  3200.0
+1400.0  1800.0  2500.0  2700.0  3100.0  3400.0
+1100.0  1800.0  2200.0  2300.0  3100.0  3200.0
+1100.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1200.0  1700.0  2300.0  2400.0  3200.0  3300.0
+1400.0  1700.0  2300.0  2400.0  3000.0  3300.0
+1400.0  1700.0  2400.0  2500.0  3000.0  3300.0
+1900.0  2200.0  2400.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2400.0  3200.0  3400.0
+1300.0  1700.0  2200.0  2400.0  2900.0  3100.0
+1100.0  1600.0  1800.0  2100.0  2900.0  3000.0
+1500.0  1700.0  1900.0  2100.0  3000.0  3100.0
+1600.0  1700.0  1900.0  2100.0  3000.0  3100.0
+1700.0  1900.0  2300.0  2500.0  2900.0  3200.0
+1400.0  1800.0  2200.0  2300.0  3300.0  3400.0
+2100.0  2400.0  2800.0  2900.0  3200.0  3300.0
+2200.0  2500.0  2700.0  2900.0  3100.0  3300.0
+2300.0  2500.0  2700.0  3000.0  3100.0  3300.0
+1700.0  2200.0  2400.0  2800.0  3300.0  3400.0
+1800.0  2300.0  2800.0  3100.0  3400.0  3500.0
+1800.0  2300.0  2600.0  3100.0  3400.0  3500.0
+1800.0  2300.0  2600.0  3100.0  3300.0  3400.0
+1500.0  1700.0  2400.0  2600.0  3000.0  3300.0
+1400.0  1600.0  2400.0  2500.0  2900.0  3300.0
+1200.0  1700.0  2200.0  2400.0  3100.0  3200.0
+1500.0  2000.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1900.0  2300.0  2700.0  3000.0  3200.0
+1300.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1600.0  1900.0  2400.0  2500.0  3000.0  3200.0
+2000.0  2300.0  2600.0  2700.0  3000.0  3100.0
+1800.0  2000.0  2500.0  2800.0  3000.0  3300.0
+2000.0  2400.0  2600.0  2700.0  3100.0  3200.0
+1700.0  2400.0  2600.0  2800.0  3100.0  3200.0
+1200.0  1800.0  2200.0  2300.0  3300.0  3400.0
+1100.0  1600.0  2200.0  2400.0  3200.0  3300.0
+1100.0  1800.0  1900.0  2500.0  3000.0  3100.0
+1200.0  1700.0  1900.0  2500.0  3100.0  3200.0
+1400.0  1800.0  2300.0  2500.0  3200.0  3400.0
+1500.0  1700.0  2400.0  2500.0  3100.0  3400.0
+1500.0  1700.0  2300.0  2400.0  2900.0  3300.0
+1500.0  1900.0  2200.0  2600.0  3000.0  3100.0
+1300.0  1600.0  2100.0  2300.0  3000.0  3100.0
+1400.0  1700.0  2200.0  2300.0  3000.0  3100.0
+1400.0  1700.0  2200.0  2400.0  3000.0  3100.0
+1400.0  1600.0  2200.0  2300.0  3000.0  3100.0
+1500.0  1700.0  2200.0  2400.0  3100.0  3300.0
+1500.0  1700.0  2100.0  2300.0  3200.0  3300.0
+1400.0  1700.0  2000.0  2300.0  3200.0  3300.0
+1300.0  1700.0  2100.0  2500.0  3100.0  3200.0
+1500.0  1800.0  2200.0  2700.0  3000.0  3200.0
+1500.0  1700.0  2300.0  2400.0  3200.0  3400.0
+1500.0  1600.0  2200.0  2400.0  3100.0  3400.0
+1400.0  1600.0  2200.0  2400.0  3100.0  3400.0
+1100.0  1700.0  2300.0  2400.0  3200.0  3300.0
+1100.0  1900.0  2300.0  2500.0  3100.0  3200.0
+1500.0  1700.0  2300.0  2600.0  3100.0  3400.0
+1500.0  1700.0  2300.0  2500.0  3000.0  3400.0
+1500.0  1900.0  2200.0  2600.0  2800.0  3000.0
+1500.0  1800.0  2200.0  2500.0  2900.0  3000.0
+1500.0  1700.0  2200.0  2500.0  3100.0  3400.0
+1300.0  1800.0  2100.0  2300.0  3300.0  3400.0
+1100.0  1600.0  2200.0  2500.0  3000.0  3300.0
+1400.0  1600.0  2100.0  2500.0  2900.0  3200.0
+1500.0  1800.0  2400.0  2600.0  3300.0  3400.0
+1500.0  1900.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2000.0  2100.0  2600.0  3000.0  3200.0
+1500.0  1700.0  2100.0  2600.0  3100.0  3300.0
+1500.0  1600.0  1800.0  2200.0  3200.0  3300.0
+1600.0  1800.0  1900.0  2300.0  3300.0  3400.0
+1500.0  1800.0  2100.0  2200.0  3200.0  3400.0
+1500.0  2000.0  2200.0  2600.0  3200.0  3300.0
+1300.0  1700.0  2100.0  2300.0  3100.0  3300.0
+1400.0  1500.0  2100.0  2300.0  3000.0  3300.0
+1500.0  1600.0  2100.0  2300.0  3000.0  3300.0
+1500.0  1600.0  2200.0  2300.0  3000.0  3300.0
+1400.0  1900.0  2100.0  2200.0  3000.0  3100.0
+1400.0  1800.0  2100.0  2400.0  3100.0  3200.0
+1500.0  1700.0  2300.0  2600.0  3100.0  3300.0
+1600.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2300.0  3200.0  3400.0
+1500.0  1900.0  2200.0  2400.0  2600.0  3300.0
+1500.0  1900.0  2300.0  2400.0  2800.0  3300.0
+1400.0  1600.0  2400.0  2600.0  3100.0  3300.0
+1400.0  1600.0  2400.0  2500.0  3100.0  3300.0
+1500.0  1600.0  2400.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2100.0  2300.0  2800.0  3300.0
+1800.0  2100.0  2600.0  3000.0  3400.0  3500.0
+2100.0  2500.0  2900.0  3100.0  3400.0  3500.0
+1700.0  2100.0  2600.0  2700.0  3100.0  3200.0
+1600.0  1900.0  2300.0  2400.0  3200.0  3400.0
+1500.0  1800.0  2400.0  2500.0  3100.0  3400.0
+1600.0  2300.0  2700.0  3000.0  3300.0  3400.0
+1400.0  1600.0  1700.0  2100.0  3100.0  3200.0
+1400.0  1600.0  1700.0  2000.0  3100.0  3200.0
+1600.0  1700.0  1900.0  2200.0  3100.0  3300.0
+1800.0  1900.0  2500.0  2600.0  3000.0  3300.0
+1800.0  2100.0  2600.0  2900.0  3400.0  3500.0
+1800.0  2000.0  2300.0  2900.0  3200.0  3300.0
+1700.0  1800.0  2300.0  2400.0  2900.0  3100.0
+1100.0  1600.0  2500.0  2700.0  3100.0  3400.0
+1200.0  1700.0  2600.0  2700.0  3200.0  3300.0
+1400.0  2000.0  2600.0  2900.0  3300.0  3400.0
+1800.0  2200.0  2700.0  3000.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2600.0  3100.0  3300.0
+1300.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1800.0  2100.0  2800.0  2900.0  3300.0  3400.0
+1700.0  1800.0  2000.0  2400.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2500.0  3100.0  3300.0
+1800.0  2100.0  2300.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2600.0  2700.0  3000.0  3200.0
+1800.0  2000.0  2600.0  2700.0  3000.0  3200.0
+1900.0  2000.0  2500.0  2700.0  3000.0  3200.0
+2000.0  2100.0  2500.0  2600.0  2900.0  3200.0
+1800.0  1900.0  2500.0  2700.0  2900.0  3300.0
+1700.0  1800.0  2500.0  2700.0  3000.0  3300.0
+1800.0  2200.0  2700.0  2800.0  3200.0  3300.0
+1400.0  1600.0  2400.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2300.0  2700.0  2900.0  3100.0
+1400.0  1600.0  2400.0  2700.0  2900.0  3200.0
+1700.0  2300.0  2700.0  3000.0  3300.0  3400.0
+1400.0  1700.0  2400.0  2700.0  3100.0  3300.0
+1400.0  1700.0  2400.0  2700.0  3000.0  3300.0
+1400.0  1700.0  1800.0  2500.0  3000.0  3100.0
+1300.0  1700.0  1900.0  2300.0  3000.0  3100.0
+1400.0  1800.0  1900.0  2400.0  3000.0  3100.0
+1900.0  2100.0  2500.0  2700.0  3100.0  3200.0
+1200.0  1700.0  2200.0  2300.0  2900.0  3100.0
+1300.0  1700.0  2200.0  2400.0  2800.0  3100.0
+1400.0  1700.0  2200.0  2300.0  2800.0  3100.0
+1500.0  1700.0  2200.0  2300.0  2900.0  3200.0
+1500.0  1700.0  2100.0  2300.0  2900.0  3200.0
+1500.0  1700.0  2000.0  2200.0  2900.0  3100.0
+1500.0  1700.0  1900.0  2200.0  3000.0  3200.0
+1500.0  1700.0  1900.0  2300.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2300.0  3100.0  3200.0
+1600.0  1800.0  2300.0  2600.0  3000.0  3100.0
+2000.0  2500.0  2700.0  2900.0  3200.0  3300.0
+2300.0  2500.0  2800.0  3100.0  3200.0  3300.0
+2300.0  2500.0  2600.0  2900.0  3200.0  3300.0
+1500.0  1700.0  2000.0  2400.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2200.0  3100.0  3300.0
+1600.0  1700.0  1800.0  2100.0  3200.0  3300.0
+1300.0  1600.0  2300.0  2500.0  3000.0  3100.0
+1200.0  1800.0  2300.0  2500.0  3000.0  3200.0
+1400.0  1800.0  2300.0  2400.0  2800.0  3200.0
+1400.0  1700.0  2300.0  2400.0  2900.0  3300.0
+1500.0  2000.0  2500.0  2600.0  2800.0  3100.0
+1800.0  2000.0  2200.0  2600.0  3000.0  3200.0
+1400.0  1700.0  1900.0  2100.0  3000.0  3100.0
+1300.0  1600.0  2300.0  2400.0  2900.0  3100.0
+1400.0  1700.0  2300.0  2500.0  3000.0  3200.0
+1500.0  1700.0  2300.0  2600.0  3100.0  3200.0
+1500.0  1800.0  2400.0  2600.0  3100.0  3200.0
+1600.0  1800.0  2000.0  2600.0  2900.0  3100.0
+1500.0  1700.0  1900.0  2600.0  2900.0  3100.0
+1400.0  1600.0  1700.0  2200.0  3100.0  3200.0
+1300.0  1500.0  1700.0  2100.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2700.0  3100.0  3300.0
+1400.0  1700.0  1900.0  2200.0  3000.0  3100.0
+1400.0  1800.0  2000.0  2200.0  3000.0  3100.0
+2100.0  2300.0  2500.0  2700.0  3100.0  3200.0
+1500.0  1900.0  2300.0  2500.0  3000.0  3100.0
+1500.0  1900.0  2200.0  2500.0  2900.0  3100.0
+1500.0  1800.0  2100.0  2500.0  2900.0  3100.0
+1500.0  1700.0  2300.0  2600.0  2800.0  3200.0
+1500.0  1700.0  2300.0  2500.0  3000.0  3100.0
+1400.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1200.0  1500.0  2600.0  2700.0  2900.0  3000.0
+1300.0  1600.0  2500.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2500.0  2600.0  3000.0  3200.0
+1400.0  1700.0  2500.0  2600.0  3000.0  3200.0
+1500.0  1800.0  2500.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2400.0  2600.0  2900.0  3200.0
+1400.0  1600.0  2400.0  2700.0  3000.0  3300.0
+1400.0  1500.0  2200.0  2600.0  2900.0  3200.0
+1300.0  1700.0  2400.0  2600.0  3000.0  3300.0
+1800.0  2000.0  2500.0  2600.0  3100.0  3400.0
+1100.0  1800.0  2500.0  2600.0  3100.0  3200.0
+1100.0  1800.0  2400.0  2500.0  3100.0  3300.0
+1100.0  1800.0  2400.0  2600.0  3100.0  3300.0
+1000.0  1800.0  2500.0  2700.0  3200.0  3300.0
+1100.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2500.0  2900.0  3300.0
+1700.0  1900.0  2300.0  2500.0  3000.0  3300.0
+1300.0  1700.0  2100.0  2300.0  3000.0  3200.0
+1300.0  1600.0  2000.0  2200.0  3000.0  3100.0
+1300.0  1600.0  1900.0  2100.0  3000.0  3100.0
+1500.0  1700.0  2400.0  2600.0  2900.0  3100.0
+1500.0  1900.0  2600.0  2700.0  3100.0  3200.0
+2100.0  2400.0  2900.0  3100.0  3300.0  3400.0
+2000.0  2500.0  2900.0  3100.0  3400.0  3500.0
+2000.0  2500.0  2700.0  3000.0  3300.0  3400.0
+1600.0  1900.0  2600.0  2700.0  3100.0  3300.0
+1600.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1100.0  1500.0  1600.0  2200.0  2900.0  3000.0
+1200.0  1500.0  1600.0  2100.0  3000.0  3100.0
+2300.0  2500.0  2900.0  3100.0  3400.0  3500.0
+1500.0  1900.0  2300.0  2400.0  2900.0  3200.0
+1500.0  2000.0  2500.0  2600.0  3100.0  3300.0
+1500.0  1900.0  2400.0  2800.0  3200.0  3300.0
+1100.0  1800.0  2200.0  2500.0  3100.0  3200.0
+1200.0  1800.0  2200.0  2400.0  3200.0  3300.0
+1300.0  1700.0  2400.0  2500.0  3100.0  3200.0
+1600.0  2100.0  2300.0  2600.0  3100.0  3200.0
+1300.0  1800.0  2100.0  2300.0  3200.0  3300.0
+1200.0  1800.0  2100.0  2300.0  3100.0  3200.0
+2100.0  2200.0  2700.0  2800.0  3300.0  3400.0
+2000.0  2300.0  2600.0  2900.0  3200.0  3400.0
+2100.0  2400.0  2700.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2600.0  2700.0  3100.0  3300.0
+2100.0  2400.0  2600.0  3000.0  3300.0  3400.0
+1400.0  1800.0  2300.0  2400.0  3000.0  3200.0
+1500.0  1700.0  1900.0  2400.0  2900.0  3000.0
+1500.0  1600.0  1800.0  2300.0  3100.0  3200.0
+1500.0  1700.0  1800.0  2300.0  3100.0  3200.0
+2100.0  2500.0  2700.0  3000.0  3400.0  3500.0
+2000.0  2400.0  2700.0  2900.0  3400.0  3500.0
+1400.0  1800.0  1900.0  2600.0  3100.0  3200.0
+1400.0  1800.0  2100.0  2300.0  3200.0  3300.0
+1600.0  1800.0  2300.0  2500.0  3000.0  3100.0
+1400.0  2000.0  2400.0  2700.0  3100.0  3200.0
+1400.0  1900.0  2300.0  2600.0  3100.0  3200.0
+1700.0  1800.0  2500.0  2800.0  3100.0  3300.0
+1400.0  1800.0  2400.0  2500.0  2900.0  3300.0
+1400.0  2000.0  2400.0  2500.0  3100.0  3300.0
+1300.0  1600.0  2400.0  2600.0  3200.0  3300.0
+1900.0  2400.0  2900.0  3100.0  3400.0  3500.0
+2000.0  2400.0  2900.0  3100.0  3400.0  3500.0
+900.0  1800.0  2500.0  2600.0  3200.0  3300.0
+900.0  1800.0  2600.0  2700.0  3200.0  3300.0
+1000.0  1700.0  2800.0  2900.0  3200.0  3300.0
+1500.0  1600.0  2200.0  2600.0  2900.0  3200.0
+1600.0  1800.0  2100.0  2500.0  2800.0  3000.0
+1800.0  1900.0  2400.0  2600.0  2900.0  3100.0
+1900.0  2100.0  2600.0  2900.0  3100.0  3300.0
+1800.0  1900.0  2600.0  2800.0  3000.0  3200.0
+1900.0  2100.0  2500.0  2900.0  3200.0  3400.0
+1300.0  1500.0  2400.0  2700.0  2900.0  3100.0
+1300.0  1600.0  2500.0  2600.0  2900.0  3100.0
+1400.0  1600.0  2400.0  2600.0  2900.0  3100.0
+1600.0  1700.0  2500.0  2800.0  2900.0  3200.0
+1700.0  2000.0  2600.0  3000.0  3300.0  3400.0
+1900.0  2200.0  2700.0  2800.0  3200.0  3400.0
+2000.0  2100.0  2700.0  2800.0  3100.0  3300.0
+2000.0  2100.0  2600.0  2800.0  3100.0  3200.0
+1700.0  2000.0  2500.0  2600.0  3100.0  3300.0
+1900.0  2100.0  2300.0  2500.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2500.0  3200.0  3400.0
+1300.0  1800.0  2300.0  2400.0  3200.0  3400.0
+1300.0  1900.0  2300.0  2500.0  3200.0  3300.0
+2000.0  2300.0  2600.0  2700.0  3000.0  3300.0
+1800.0  2000.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1800.0  2500.0  2700.0  3100.0  3300.0
+1200.0  1500.0  2500.0  2900.0  3100.0  3200.0
+1400.0  1600.0  2500.0  2700.0  2900.0  3100.0
+2100.0  2400.0  2700.0  2800.0  3100.0  3300.0
+1600.0  2100.0  2400.0  2800.0  3100.0  3300.0
+1400.0  1600.0  2100.0  2600.0  3100.0  3200.0
+1300.0  1500.0  2300.0  2600.0  3100.0  3300.0
+2000.0  2200.0  2700.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2700.0  2800.0  3300.0  3400.0
+1800.0  2400.0  2700.0  3000.0  3400.0  3500.0
+1900.0  2400.0  2800.0  3000.0  3400.0  3500.0
+2000.0  2100.0  2600.0  2800.0  3000.0  3300.0
+2100.0  2200.0  2700.0  2800.0  3000.0  3300.0
+1500.0  2000.0  2400.0  2600.0  3100.0  3300.0
+1300.0  2000.0  2200.0  2500.0  3000.0  3100.0
+1800.0  2100.0  2300.0  2500.0  3100.0  3300.0
+1500.0  1800.0  2500.0  2800.0  3200.0  3300.0
+1500.0  1700.0  2100.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2600.0  3200.0  3400.0
+1400.0  1700.0  2300.0  2400.0  3200.0  3400.0
+1100.0  1800.0  2300.0  2400.0  3300.0  3400.0
+1000.0  1900.0  2400.0  2500.0  3100.0  3400.0
+1600.0  1800.0  2200.0  2300.0  3100.0  3300.0
+1500.0  1600.0  2300.0  2400.0  3100.0  3300.0
+1500.0  1600.0  2200.0  2300.0  3200.0  3400.0
+1400.0  1800.0  2300.0  2700.0  3000.0  3300.0
+1400.0  1800.0  2100.0  2300.0  2800.0  3200.0
+1400.0  1800.0  2100.0  2500.0  2900.0  3200.0
+1200.0  1600.0  1700.0  2100.0  3000.0  3100.0
+1200.0  1600.0  1900.0  2400.0  3000.0  3200.0
+1100.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1100.0  2000.0  2400.0  2700.0  3100.0  3200.0
+1200.0  1400.0  2400.0  2600.0  2900.0  3200.0
+1300.0  1400.0  2300.0  2400.0  2800.0  3300.0
+1300.0  1500.0  2300.0  2400.0  2900.0  3200.0
+1300.0  1600.0  2400.0  2500.0  2800.0  3200.0
+1300.0  1600.0  2300.0  2500.0  2900.0  3200.0
+1300.0  1500.0  1600.0  2100.0  2800.0  2900.0
+1500.0  1800.0  2500.0  2700.0  3200.0  3400.0
+1400.0  1700.0  2300.0  2500.0  2900.0  3100.0
+1300.0  1700.0  2400.0  2500.0  3000.0  3200.0
+1200.0  1600.0  2500.0  2600.0  3100.0  3400.0
+1100.0  1700.0  2500.0  2600.0  3100.0  3400.0
+1400.0  1800.0  2200.0  2300.0  2600.0  3000.0
+1300.0  1800.0  2200.0  2300.0  2500.0  3000.0
+1400.0  1800.0  2300.0  2700.0  3000.0  3200.0
+1300.0  1500.0  2300.0  2400.0  2900.0  3100.0
+1300.0  1600.0  2400.0  2500.0  3000.0  3200.0
+1200.0  1600.0  2400.0  2600.0  3100.0  3300.0
+1200.0  1500.0  2600.0  2700.0  3100.0  3300.0
+1200.0  1500.0  2500.0  2700.0  2900.0  3200.0
+1400.0  1600.0  2300.0  2500.0  3100.0  3300.0
+1400.0  1600.0  2000.0  2200.0  2900.0  3000.0
+1300.0  1500.0  1800.0  1900.0  2800.0  2900.0
+1200.0  1600.0  1700.0  2200.0  2900.0  3000.0
+1300.0  1700.0  1800.0  2100.0  2900.0  3000.0
+1500.0  1700.0  2100.0  2400.0  2600.0  3100.0
+1500.0  2000.0  2500.0  2600.0  3000.0  3200.0
+1700.0  2000.0  2200.0  2600.0  2900.0  3200.0
+1700.0  2200.0  2600.0  2700.0  3100.0  3300.0
+1600.0  1700.0  2400.0  2500.0  3000.0  3400.0
+1900.0  2000.0  2100.0  2300.0  3300.0  3400.0
+1700.0  1900.0  2400.0  2500.0  3100.0  3300.0
+1500.0  1800.0  2200.0  2300.0  3100.0  3400.0
+1900.0  2300.0  2500.0  3000.0  3300.0  3400.0
+1500.0  1700.0  2100.0  2300.0  3000.0  3300.0
+1700.0  1900.0  2200.0  2400.0  2700.0  3200.0
+1800.0  1900.0  2200.0  2300.0  2700.0  3100.0
+1700.0  1900.0  2100.0  2300.0  2700.0  3100.0
+1700.0  2000.0  2600.0  2800.0  3100.0  3300.0
+1200.0  1800.0  2200.0  2400.0  3000.0  3100.0
+1300.0  1900.0  2200.0  2500.0  3000.0  3100.0
+1500.0  1600.0  2300.0  2500.0  3000.0  3200.0
+1400.0  1500.0  2300.0  2500.0  3000.0  3200.0
+1300.0  1700.0  2100.0  2400.0  3100.0  3200.0
+1500.0  1600.0  2200.0  2500.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2300.0  3100.0  3400.0
+1400.0  1600.0  2100.0  2300.0  2900.0  3000.0
+1400.0  1600.0  2000.0  2200.0  2800.0  2900.0
+1400.0  1800.0  2200.0  2500.0  3100.0  3300.0
+1400.0  1800.0  2100.0  2400.0  3100.0  3300.0
+1400.0  1700.0  2000.0  2400.0  3000.0  3200.0
+1900.0  2100.0  2300.0  2500.0  2800.0  3100.0
+1900.0  2100.0  2300.0  2500.0  2900.0  3100.0
+1400.0  1600.0  2100.0  2400.0  3000.0  3200.0
+1400.0  1600.0  2000.0  2300.0  3000.0  3200.0
+1600.0  2000.0  2200.0  2600.0  2900.0  3200.0
+1600.0  2000.0  2200.0  2600.0  3000.0  3300.0
+1300.0  1900.0  2200.0  2400.0  3000.0  3200.0
+1700.0  2000.0  2300.0  2700.0  3000.0  3300.0
+1000.0  1600.0  2600.0  2700.0  3200.0  3300.0
+1100.0  1700.0  2600.0  2700.0  3200.0  3300.0
+1500.0  1800.0  2300.0  2400.0  3300.0  3400.0
+1900.0  2100.0  2300.0  2500.0  3100.0  3200.0
+1400.0  1700.0  2200.0  2500.0  3300.0  3400.0
+1400.0  1900.0  2200.0  2700.0  3200.0  3300.0
+1400.0  2000.0  2300.0  2700.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2700.0  3000.0  3200.0
+1600.0  1800.0  2100.0  2400.0  3000.0  3200.0
+1700.0  1800.0  2100.0  2400.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2500.0  2900.0  3300.0
+1800.0  1900.0  2200.0  2500.0  2900.0  3300.0
+1800.0  1900.0  2200.0  2500.0  2900.0  3200.0
+1700.0  1900.0  2200.0  2400.0  3000.0  3300.0
+1700.0  1900.0  2200.0  2400.0  2600.0  3000.0
+1500.0  1800.0  2500.0  2600.0  3200.0  3300.0
+1600.0  1700.0  2500.0  2600.0  3000.0  3200.0
+1600.0  1700.0  2400.0  2500.0  3100.0  3200.0
+1600.0  1700.0  2500.0  2600.0  3100.0  3200.0
+1600.0  1800.0  2500.0  2600.0  3100.0  3200.0
+1800.0  1900.0  2500.0  2600.0  3000.0  3200.0
+1900.0  2400.0  2700.0  3000.0  3300.0  3500.0
+1900.0  2400.0  2700.0  3100.0  3300.0  3400.0
+2000.0  2400.0  2600.0  3000.0  3300.0  3400.0
+1800.0  2500.0  2700.0  2900.0  3300.0  3400.0
+1800.0  2400.0  2700.0  2900.0  3400.0  3500.0
+1900.0  2400.0  2700.0  3000.0  3200.0  3300.0
+1600.0  1800.0  2400.0  2500.0  3000.0  3300.0
+1700.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1300.0  1800.0  2000.0  2500.0  3100.0  3200.0
+1500.0  1800.0  2300.0  2400.0  3000.0  3100.0
+2100.0  2500.0  2700.0  2900.0  3100.0  3300.0
+1800.0  2000.0  2200.0  2500.0  2800.0  3100.0
+1400.0  1700.0  1900.0  2300.0  2800.0  2900.0
+1800.0  2000.0  2300.0  2700.0  3000.0  3300.0
+1800.0  1900.0  2300.0  2700.0  3200.0  3300.0
+1700.0  1800.0  2400.0  2800.0  3100.0  3300.0
+1500.0  1700.0  2500.0  2600.0  2900.0  3300.0
+1400.0  1500.0  2300.0  2500.0  2900.0  3300.0
+1500.0  1700.0  2200.0  2500.0  2900.0  3200.0
+1700.0  1900.0  2100.0  2300.0  3100.0  3300.0
+1400.0  1800.0  2200.0  2400.0  2700.0  3100.0
+1300.0  1500.0  1700.0  1900.0  2800.0  3000.0
+1300.0  1500.0  1700.0  1900.0  2900.0  3000.0
+1100.0  1600.0  2300.0  2500.0  3100.0  3200.0
+1000.0  1600.0  2300.0  2500.0  3200.0  3300.0
+1000.0  1700.0  2300.0  2400.0  3200.0  3300.0
+900.0  1700.0  2300.0  2400.0  3200.0  3300.0
+900.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1100.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1200.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1200.0  1700.0  2200.0  2300.0  3100.0  3200.0
+1300.0  1700.0  2200.0  2300.0  3100.0  3200.0
+1400.0  1800.0  2200.0  2300.0  3100.0  3200.0
+1500.0  1700.0  2200.0  2300.0  3000.0  3200.0
+1500.0  1600.0  2200.0  2300.0  2900.0  3200.0
+1600.0  2000.0  2300.0  2400.0  3100.0  3300.0
+1600.0  2100.0  2300.0  2400.0  2700.0  3300.0
+1600.0  1800.0  2100.0  2300.0  2900.0  3000.0
+1400.0  1600.0  1700.0  2300.0  2900.0  3000.0
+1600.0  1800.0  2100.0  2300.0  3000.0  3100.0
+1600.0  1700.0  2000.0  2200.0  3000.0  3100.0
+1500.0  1600.0  2300.0  2400.0  2900.0  3100.0
+1500.0  1600.0  2400.0  2500.0  3000.0  3200.0
+1800.0  2100.0  2600.0  2700.0  3100.0  3200.0
+1500.0  1600.0  1900.0  2300.0  2900.0  3100.0
+1500.0  1700.0  2300.0  2700.0  3100.0  3200.0
+1500.0  2100.0  2500.0  2700.0  3100.0  3300.0
+1000.0  1500.0  2400.0  2500.0  3100.0  3300.0
+1200.0  1400.0  2400.0  2500.0  2900.0  3300.0
+1300.0  1700.0  2200.0  2400.0  2900.0  3000.0
+1200.0  2000.0  2400.0  2500.0  3000.0  3200.0
+1200.0  1900.0  2400.0  2500.0  3100.0  3300.0
+1300.0  1800.0  2400.0  2500.0  3100.0  3400.0
+1500.0  1800.0  2300.0  2400.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2400.0  3000.0  3200.0
+1600.0  1900.0  2100.0  2400.0  2900.0  3200.0
+1400.0  1600.0  2200.0  2400.0  2900.0  3100.0
+1500.0  1700.0  2200.0  2400.0  3000.0  3100.0
+1400.0  1600.0  2300.0  2400.0  3000.0  3200.0
+1400.0  1600.0  2200.0  2300.0  2900.0  3200.0
+1600.0  1700.0  2000.0  2200.0  3000.0  3200.0
+1600.0  1800.0  2100.0  2400.0  2900.0  3200.0
+1600.0  1700.0  2100.0  2300.0  2900.0  3200.0
+1400.0  1600.0  2100.0  2400.0  3200.0  3300.0
+1200.0  1600.0  2100.0  2300.0  3100.0  3200.0
+1600.0  2100.0  2300.0  2500.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2600.0  3100.0  3300.0
+1400.0  1600.0  2300.0  2400.0  2900.0  3200.0
+1400.0  1500.0  2100.0  2400.0  2700.0  3100.0
+1200.0  1400.0  2100.0  2200.0  3000.0  3300.0
+1300.0  1800.0  2200.0  2300.0  2800.0  3200.0
+1300.0  1700.0  2200.0  2300.0  2800.0  3300.0
+1400.0  1800.0  2200.0  2300.0  2800.0  3200.0
+1800.0  2100.0  2500.0  3000.0  3200.0  3400.0
+1700.0  1900.0  2200.0  2500.0  3100.0  3300.0
+1800.0  1900.0  2100.0  2400.0  3200.0  3300.0
+1500.0  1600.0  2200.0  2300.0  3200.0  3300.0
+1400.0  1700.0  2200.0  2300.0  3100.0  3300.0
+1400.0  1900.0  2200.0  2600.0  3100.0  3300.0
+1600.0  1900.0  2500.0  2900.0  3200.0  3300.0
+1400.0  1900.0  2400.0  2700.0  3100.0  3200.0
+1400.0  1600.0  2200.0  2300.0  2900.0  3100.0
+1600.0  1800.0  2200.0  2400.0  3000.0  3100.0
+1800.0  2000.0  2400.0  2900.0  3100.0  3200.0
+1900.0  2000.0  2500.0  2900.0  3100.0  3300.0
+1500.0  1600.0  2100.0  2200.0  3000.0  3300.0
+1500.0  1600.0  2100.0  2300.0  2900.0  3200.0
+1300.0  1500.0  2200.0  2300.0  2800.0  3100.0
+1100.0  1900.0  2500.0  2700.0  3100.0  3200.0
+1300.0  1800.0  2300.0  2700.0  3100.0  3200.0
+1100.0  1700.0  2200.0  2600.0  3000.0  3200.0
+1300.0  1600.0  1900.0  2100.0  3000.0  3200.0
+1300.0  1500.0  1800.0  1900.0  3000.0  3100.0
+1100.0  1400.0  2500.0  2600.0  3000.0  3300.0
+1300.0  1500.0  2400.0  2600.0  2900.0  3300.0
+1700.0  1900.0  2300.0  2400.0  3000.0  3300.0
+1600.0  1800.0  2100.0  2400.0  2800.0  3100.0
+1500.0  1700.0  2000.0  2500.0  2800.0  3000.0
+1400.0  1700.0  2200.0  2500.0  2900.0  3100.0
+1300.0  1500.0  2300.0  2600.0  3000.0  3300.0
+1000.0  1600.0  2200.0  2500.0  3000.0  3100.0
+1000.0  1500.0  2500.0  2600.0  3100.0  3300.0
+1000.0  1600.0  2500.0  2600.0  3200.0  3300.0
+1000.0  1700.0  2600.0  2700.0  3200.0  3300.0
+2000.0  2400.0  2800.0  3000.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2700.0  3100.0  3200.0
+1800.0  1900.0  2400.0  2700.0  3000.0  3300.0
+1700.0  2100.0  2300.0  2500.0  3000.0  3200.0
+1200.0  1400.0  1500.0  2100.0  3100.0  3200.0
+1400.0  1600.0  1700.0  2200.0  3000.0  3200.0
+1600.0  1800.0  1900.0  2200.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2300.0  3000.0  3200.0
+1900.0  2000.0  2400.0  2500.0  3000.0  3300.0
+1800.0  1900.0  2400.0  2500.0  2900.0  3300.0
+1800.0  1900.0  2300.0  2500.0  3100.0  3400.0
+1800.0  2000.0  2400.0  2600.0  3200.0  3400.0
+1400.0  1600.0  2100.0  2200.0  3100.0  3400.0
+1500.0  1700.0  1900.0  2500.0  3000.0  3200.0
+1300.0  1400.0  2200.0  2500.0  2900.0  3200.0
+1300.0  1700.0  2100.0  2600.0  3100.0  3300.0
+1900.0  2100.0  2400.0  2700.0  3200.0  3400.0
+1700.0  2000.0  2300.0  2500.0  3000.0  3300.0
+1600.0  1700.0  2100.0  2600.0  3000.0  3200.0
+1400.0  1600.0  1700.0  2000.0  3000.0  3100.0
+1300.0  1500.0  1600.0  2000.0  3000.0  3100.0
+1400.0  1600.0  2100.0  2200.0  2700.0  3200.0
+1300.0  1600.0  1700.0  2300.0  3100.0  3300.0
+1500.0  1700.0  2200.0  2500.0  3100.0  3200.0
+2100.0  2200.0  2600.0  2900.0  3200.0  3400.0
+2100.0  2300.0  2700.0  3000.0  3300.0  3400.0
+1900.0  2300.0  2800.0  3100.0  3300.0  3500.0
+1900.0  2300.0  2700.0  3100.0  3400.0  3500.0
+1900.0  2300.0  2700.0  3100.0  3300.0  3400.0
+1400.0  1800.0  2200.0  2300.0  2900.0  3200.0
+1400.0  1600.0  2100.0  2300.0  2800.0  3300.0
+1300.0  1700.0  2200.0  2300.0  2800.0  3200.0
+1300.0  1600.0  2200.0  2300.0  2900.0  3300.0
+1400.0  1800.0  2200.0  2600.0  3100.0  3300.0
+1700.0  2100.0  2400.0  2700.0  3000.0  3200.0
+1300.0  1800.0  2200.0  2500.0  3000.0  3300.0
+1900.0  2000.0  2500.0  2600.0  2900.0  3300.0
+2100.0  2200.0  2400.0  2600.0  2900.0  3200.0
+2100.0  2200.0  2400.0  2600.0  3000.0  3200.0
+2000.0  2100.0  2400.0  2500.0  3000.0  3200.0
+1800.0  2000.0  2200.0  2400.0  3100.0  3200.0
+1400.0  2000.0  2300.0  2400.0  3000.0  3100.0
+1300.0  1600.0  2100.0  2300.0  2700.0  3200.0
+1200.0  1800.0  2200.0  2400.0  3200.0  3400.0
+1200.0  1800.0  2300.0  2400.0  3200.0  3400.0
+1200.0  1900.0  2300.0  2400.0  3100.0  3400.0
+1700.0  1800.0  2100.0  2300.0  2800.0  3200.0
+1500.0  1600.0  2200.0  2300.0  2900.0  3300.0
+1500.0  1600.0  2100.0  2300.0  2800.0  3200.0
+1500.0  1600.0  2000.0  2200.0  2700.0  3200.0
+1400.0  1900.0  2200.0  2600.0  3200.0  3300.0
+1400.0  1600.0  2100.0  2200.0  2800.0  3200.0
+1900.0  2100.0  2300.0  2600.0  3100.0  3300.0
+2000.0  2300.0  2600.0  2800.0  3200.0  3400.0
+1700.0  1800.0  2300.0  2500.0  2700.0  3200.0
+1700.0  1800.0  2300.0  2500.0  2700.0  3100.0
+1800.0  1900.0  2400.0  2500.0  2700.0  3100.0
+1700.0  1800.0  2400.0  2500.0  2800.0  3200.0
+1600.0  1800.0  2500.0  2600.0  2900.0  3100.0
+1500.0  1800.0  2500.0  2600.0  3200.0  3400.0
+1400.0  1500.0  2100.0  2300.0  2900.0  3300.0
+1400.0  1600.0  2100.0  2300.0  3000.0  3300.0
+1600.0  1700.0  2200.0  2500.0  3100.0  3400.0
+1600.0  2000.0  2200.0  2400.0  2900.0  3100.0
+2000.0  2200.0  2600.0  2900.0  3200.0  3400.0
+1200.0  1400.0  2200.0  2300.0  3100.0  3300.0
+1300.0  1500.0  2200.0  2300.0  3100.0  3300.0
+1700.0  1800.0  2200.0  2300.0  3100.0  3400.0
+1800.0  1900.0  2200.0  2300.0  2900.0  3300.0
+1800.0  2000.0  2400.0  2700.0  3100.0  3400.0
+1600.0  1700.0  2000.0  2100.0  2700.0  3100.0
+1700.0  1900.0  2200.0  2300.0  2900.0  3200.0
+2200.0  2500.0  2700.0  2800.0  3100.0  3300.0
+1600.0  1700.0  2200.0  2300.0  2900.0  3100.0
+1400.0  1500.0  1600.0  2000.0  3000.0  3200.0
+1500.0  1700.0  1900.0  2400.0  3000.0  3200.0
+1900.0  2200.0  2500.0  2900.0  3200.0  3300.0
+1900.0  2400.0  2600.0  2900.0  3300.0  3400.0
+1800.0  2100.0  2200.0  2400.0  3000.0  3300.0
+1400.0  1600.0  1700.0  2300.0  3200.0  3300.0
+1400.0  1600.0  1900.0  2500.0  3200.0  3300.0
+1700.0  2100.0  2700.0  3000.0  3300.0  3400.0
+1400.0  1800.0  2300.0  2700.0  3100.0  3200.0
+1400.0  1600.0  2300.0  2700.0  3000.0  3200.0
+1400.0  2000.0  2200.0  2500.0  3100.0  3300.0
+1600.0  2100.0  2400.0  2900.0  3200.0  3400.0
+1400.0  1600.0  1800.0  2600.0  3300.0  3400.0
+1400.0  1500.0  1700.0  2200.0  3200.0  3300.0
+1400.0  1500.0  1700.0  2100.0  3100.0  3200.0
+1300.0  1500.0  2200.0  2400.0  2800.0  3100.0
+1300.0  1600.0  1800.0  2400.0  3000.0  3100.0
+1400.0  1600.0  2000.0  2200.0  3000.0  3300.0
+1500.0  1600.0  2100.0  2400.0  3100.0  3300.0
+1500.0  1700.0  2100.0  2300.0  2700.0  3100.0
+1500.0  1600.0  2000.0  2200.0  2600.0  3100.0
+1400.0  1500.0  2000.0  2300.0  3100.0  3300.0
+1400.0  1500.0  2000.0  2200.0  3100.0  3300.0
+1600.0  1800.0  2200.0  2300.0  3000.0  3200.0
+1400.0  1700.0  2100.0  2500.0  2900.0  3100.0
+1400.0  1800.0  2200.0  2400.0  2900.0  3000.0
+1500.0  1800.0  2300.0  2500.0  3000.0  3200.0
+2000.0  2300.0  2800.0  3100.0  3400.0  3500.0
+2000.0  2500.0  2800.0  2900.0  3200.0  3300.0
+1400.0  2000.0  2300.0  2600.0  3000.0  3300.0
+1600.0  1900.0  2300.0  2700.0  3200.0  3400.0
+2000.0  2400.0  2800.0  2900.0  3300.0  3400.0
+1200.0  1400.0  2000.0  2200.0  3200.0  3400.0
+1200.0  1600.0  2400.0  2500.0  2900.0  3200.0
+1500.0  1600.0  2300.0  2400.0  2800.0  3200.0
+1100.0  1600.0  2200.0  2300.0  3300.0  3400.0
+1300.0  1600.0  2200.0  2400.0  3000.0  3300.0
+1300.0  1600.0  2200.0  2400.0  2700.0  3200.0
+1400.0  1700.0  2300.0  2500.0  2700.0  3100.0
+1500.0  1700.0  2400.0  2500.0  2800.0  3100.0
+1800.0  2000.0  2200.0  2300.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2400.0  2900.0  3200.0
+1700.0  1900.0  2200.0  2400.0  2900.0  3300.0
+1300.0  1700.0  2200.0  2300.0  3200.0  3400.0
+1500.0  1600.0  2300.0  2400.0  3000.0  3400.0
+1600.0  1900.0  2400.0  2800.0  3200.0  3400.0
+1500.0  1600.0  2300.0  2400.0  2900.0  3300.0
+1600.0  1700.0  2300.0  2400.0  2800.0  3300.0
+1800.0  2000.0  2200.0  2500.0  3000.0  3300.0
+1900.0  2000.0  2300.0  2500.0  2800.0  3100.0
+1600.0  1700.0  2400.0  2600.0  3100.0  3400.0
+1600.0  1800.0  2400.0  2700.0  3200.0  3300.0
+1600.0  1900.0  2400.0  2700.0  3200.0  3400.0
+1500.0  1800.0  2200.0  2500.0  3200.0  3400.0
+1200.0  1800.0  2300.0  2600.0  3100.0  3300.0
+1900.0  2000.0  2400.0  2600.0  3100.0  3400.0
+1700.0  1800.0  2400.0  2500.0  3000.0  3400.0
+1400.0  2000.0  2300.0  2400.0  2600.0  3100.0
+1800.0  1900.0  2100.0  2200.0  3300.0  3400.0
+1400.0  1600.0  1700.0  2300.0  3300.0  3400.0
+1400.0  1600.0  1700.0  2200.0  3300.0  3400.0
+1400.0  1600.0  1700.0  2300.0  3200.0  3400.0
+1600.0  1800.0  2000.0  2300.0  2900.0  3100.0
+1700.0  1800.0  2000.0  2300.0  2900.0  3100.0
+1600.0  1800.0  2100.0  2300.0  2800.0  3100.0
+1500.0  1700.0  2100.0  2300.0  2800.0  3100.0
+1500.0  1600.0  2100.0  2300.0  2700.0  3100.0
+1500.0  1600.0  2100.0  2200.0  2700.0  3100.0
+1400.0  1800.0  2300.0  2400.0  2800.0  3100.0
+1400.0  1600.0  2300.0  2400.0  2900.0  3300.0
+1200.0  1700.0  2200.0  2300.0  2900.0  3200.0
+1400.0  1500.0  2100.0  2400.0  3200.0  3400.0
+1700.0  2100.0  2400.0  2500.0  2900.0  3100.0
+1500.0  1700.0  2000.0  2400.0  3000.0  3200.0
+1400.0  1900.0  2200.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2700.0  3000.0  3100.0
+1600.0  1800.0  2100.0  2500.0  2800.0  3100.0
+2000.0  2300.0  2500.0  2800.0  3000.0  3100.0
+1900.0  2400.0  2700.0  2800.0  3100.0  3200.0
+1800.0  2300.0  2700.0  2800.0  3100.0  3200.0
+1700.0  2400.0  2700.0  2800.0  3200.0  3300.0
+1700.0  2400.0  2700.0  2800.0  3100.0  3200.0
+1600.0  2400.0  2700.0  2800.0  3100.0  3200.0
+1600.0  2000.0  2200.0  2700.0  3100.0  3200.0
+1800.0  2200.0  2600.0  2800.0  3100.0  3400.0
+1800.0  2200.0  2600.0  3000.0  3200.0  3400.0
+1800.0  2200.0  2300.0  2700.0  3200.0  3300.0
+1600.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2600.0  3000.0  3100.0
+1600.0  1800.0  2200.0  2500.0  2800.0  3000.0
+2000.0  2400.0  2800.0  3100.0  3200.0  3300.0
+1500.0  1700.0  1900.0  2000.0  2600.0  3100.0
+1400.0  1600.0  1900.0  2000.0  2500.0  3100.0
+1400.0  1600.0  1800.0  2000.0  2500.0  3100.0
+1400.0  1500.0  1800.0  1900.0  2500.0  3100.0
+1400.0  1500.0  1800.0  1900.0  2600.0  3200.0
+1400.0  1500.0  1700.0  2000.0  2900.0  3200.0
+1300.0  1700.0  2100.0  2600.0  3100.0  3200.0
+1200.0  1700.0  2200.0  2500.0  3100.0  3200.0
+1800.0  2000.0  2500.0  2600.0  3000.0  3200.0
+1700.0  1900.0  2200.0  2700.0  2900.0  3200.0
+1500.0  1700.0  2100.0  2600.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2400.0  2700.0  3100.0
+1600.0  1900.0  2200.0  2600.0  2800.0  3100.0
+1600.0  1800.0  2100.0  2500.0  3000.0  3100.0
+1600.0  1800.0  2000.0  2200.0  2600.0  3100.0
+1200.0  1400.0  2300.0  2700.0  2800.0  3100.0
+1300.0  1600.0  2100.0  2600.0  3100.0  3300.0
+1400.0  1600.0  2100.0  2500.0  2700.0  3000.0
+1300.0  1600.0  2300.0  2600.0  3000.0  3300.0
+1300.0  1700.0  2300.0  2700.0  3000.0  3300.0
+1400.0  1600.0  2000.0  2500.0  2800.0  3000.0
+1800.0  2000.0  2200.0  2600.0  2800.0  3100.0
+1800.0  1900.0  2400.0  2600.0  2800.0  3100.0
+1500.0  1700.0  2200.0  2700.0  2900.0  3100.0
+1400.0  1700.0  2300.0  2700.0  3000.0  3100.0
+1700.0  2200.0  2500.0  2900.0  3200.0  3300.0
+1500.0  1700.0  2100.0  2700.0  3000.0  3200.0
+1700.0  2000.0  2600.0  2700.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2500.0  3100.0  3200.0
+1500.0  2000.0  2200.0  2600.0  3000.0  3100.0
+1500.0  1800.0  2000.0  2800.0  3200.0  3300.0
+1700.0  1900.0  2500.0  2600.0  2900.0  3200.0
+1800.0  2000.0  2400.0  2600.0  3000.0  3100.0
+1400.0  1700.0  2100.0  2500.0  2700.0  3000.0
+1500.0  1900.0  2200.0  2400.0  2800.0  3200.0
+1300.0  1500.0  2100.0  2400.0  3100.0  3300.0
+1200.0  1600.0  2200.0  2500.0  3200.0  3300.0
+1300.0  1800.0  2300.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1300.0  1800.0  2200.0  2400.0  3000.0  3100.0
+1500.0  1700.0  2100.0  2700.0  3100.0  3200.0
+1500.0  1700.0  2100.0  2800.0  3100.0  3200.0
+1700.0  2000.0  2200.0  2500.0  3100.0  3200.0
+1800.0  1900.0  2100.0  2300.0  2600.0  3100.0
+1500.0  1600.0  1800.0  2000.0  2500.0  3100.0
+1700.0  2000.0  2200.0  2400.0  3100.0  3300.0
+1600.0  1800.0  2000.0  2400.0  2900.0  3200.0
+1400.0  1500.0  1700.0  1900.0  3000.0  3200.0
+1600.0  1700.0  2000.0  2600.0  3000.0  3200.0
+1700.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1700.0  2200.0  2600.0  2800.0  3100.0  3200.0
+1600.0  2200.0  2500.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2200.0  2500.0  3000.0  3100.0
+1600.0  2000.0  2500.0  2800.0  3100.0  3300.0
+1700.0  2100.0  2400.0  2900.0  3200.0  3300.0
+1800.0  2000.0  2400.0  2700.0  3000.0  3100.0
+1800.0  2000.0  2500.0  2700.0  3000.0  3100.0
+1600.0  1900.0  2300.0  2600.0  3000.0  3100.0
+1500.0  1900.0  2100.0  2500.0  3000.0  3200.0
+1900.0  2300.0  2500.0  2600.0  2900.0  3100.0
+2000.0  2200.0  2500.0  2800.0  3300.0  3400.0
+2100.0  2300.0  2600.0  2800.0  3200.0  3400.0
+2200.0  2400.0  2800.0  2900.0  3200.0  3300.0
+2100.0  2500.0  2700.0  2900.0  3200.0  3300.0
+1800.0  2300.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2300.0  2500.0  2700.0  3000.0  3200.0
+1400.0  1800.0  2500.0  2700.0  3200.0  3300.0
+1400.0  1600.0  2500.0  2700.0  3200.0  3300.0
+1400.0  1700.0  2200.0  2700.0  3100.0  3300.0
+1500.0  1700.0  2200.0  2700.0  3000.0  3200.0
+1500.0  1700.0  2100.0  2700.0  2900.0  3100.0
+1800.0  2300.0  2600.0  2700.0  3200.0  3300.0
+1800.0  2400.0  2700.0  2800.0  3300.0  3400.0
+1800.0  2500.0  2700.0  2900.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2400.0  2800.0  3000.0
+1600.0  1800.0  2200.0  2400.0  2800.0  3100.0
+1900.0  2000.0  2200.0  2700.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2700.0  3100.0  3300.0
+2000.0  2200.0  2500.0  2600.0  2900.0  3100.0
+1400.0  1900.0  2400.0  2700.0  3000.0  3300.0
+1500.0  1900.0  2300.0  2700.0  3000.0  3300.0
+1300.0  1800.0  2100.0  2400.0  3100.0  3200.0
+1500.0  1800.0  2200.0  2500.0  2700.0  3100.0
+1600.0  2000.0  2200.0  2600.0  2900.0  3100.0
+1700.0  2100.0  2700.0  3000.0  3200.0  3300.0
+1600.0  1800.0  2600.0  2800.0  3200.0  3300.0
+1200.0  1600.0  2200.0  2600.0  3000.0  3300.0
+1800.0  2300.0  2600.0  2800.0  3100.0  3200.0
+1800.0  2400.0  2700.0  2800.0  3100.0  3200.0
+1700.0  2300.0  2700.0  2800.0  3100.0  3200.0
+1900.0  2200.0  2700.0  2900.0  3100.0  3300.0
+1600.0  2200.0  2500.0  2700.0  3000.0  3200.0
+1600.0  2000.0  2500.0  2700.0  3000.0  3100.0
+1800.0  2200.0  2500.0  2600.0  3100.0  3200.0
+1800.0  2500.0  2700.0  2800.0  3200.0  3300.0
+1700.0  2300.0  2600.0  2700.0  3100.0  3200.0
+1400.0  1600.0  2000.0  2500.0  2900.0  3100.0
+1700.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1200.0  1400.0  1700.0  1800.0  2700.0  3200.0
+1500.0  1700.0  2000.0  2400.0  2700.0  3000.0
+1600.0  1800.0  2300.0  2400.0  2800.0  3100.0
+1800.0  2000.0  2400.0  2500.0  2900.0  3100.0
+1700.0  2000.0  2400.0  2600.0  2900.0  3000.0
+1500.0  1900.0  2300.0  2600.0  2900.0  3100.0
+1500.0  1900.0  2200.0  2600.0  2900.0  3100.0
+1500.0  1900.0  2100.0  2400.0  2900.0  3100.0
+1700.0  2300.0  2500.0  2800.0  3100.0  3200.0
+1600.0  2400.0  2700.0  2800.0  3200.0  3300.0
+1500.0  2400.0  2800.0  2900.0  3200.0  3300.0
+1200.0  1700.0  2300.0  2400.0  3000.0  3200.0
+1300.0  1900.0  2400.0  2600.0  3200.0  3300.0
+1500.0  2100.0  2300.0  2700.0  3100.0  3300.0
+1700.0  2200.0  2500.0  2700.0  3100.0  3300.0
+1400.0  1600.0  2000.0  2500.0  3000.0  3300.0
+1600.0  2000.0  2400.0  2500.0  3100.0  3300.0
+1400.0  1900.0  2300.0  2500.0  3200.0  3400.0
+1100.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1100.0  2200.0  2400.0  2700.0  3200.0  3300.0
+1200.0  2000.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2500.0  2900.0  3000.0
+1500.0  1900.0  2200.0  2400.0  2600.0  3100.0
+1800.0  2000.0  2500.0  2600.0  2900.0  3200.0
+2000.0  2100.0  2500.0  2700.0  3100.0  3300.0
+1800.0  2100.0  2400.0  2600.0  3000.0  3400.0
+1600.0  1800.0  2200.0  2400.0  3300.0  3400.0
+1400.0  1800.0  2200.0  2400.0  3200.0  3300.0
+1600.0  1900.0  2200.0  2700.0  3200.0  3300.0
+1500.0  1900.0  2300.0  2400.0  3000.0  3200.0
+1500.0  1900.0  2300.0  2500.0  2900.0  3200.0
+2200.0  2500.0  2900.0  3000.0  3300.0  3400.0
+1500.0  1800.0  2400.0  2700.0  3300.0  3400.0
+1400.0  1800.0  2100.0  2700.0  3100.0  3200.0
+1400.0  1600.0  2000.0  2700.0  3100.0  3200.0
+1900.0  2000.0  2300.0  2800.0  3100.0  3200.0
+2100.0  2200.0  2400.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2400.0  2500.0  2900.0  3100.0
+1800.0  1900.0  2200.0  2700.0  3200.0  3300.0
+1800.0  2200.0  2800.0  3000.0  3300.0  3500.0
+1800.0  2300.0  2600.0  2900.0  3300.0  3500.0
+2100.0  2400.0  2700.0  3000.0  3300.0  3500.0
+1600.0  1800.0  2200.0  2400.0  2900.0  3300.0
+1500.0  1900.0  2500.0  2600.0  2900.0  3100.0
+1600.0  2100.0  2400.0  2600.0  2800.0  3100.0
+1500.0  1600.0  2100.0  2400.0  2900.0  3300.0
+1500.0  1700.0  2200.0  2400.0  2900.0  3300.0
+1400.0  1500.0  2300.0  2500.0  3200.0  3300.0
+1400.0  1700.0  2400.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2400.0  2500.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2400.0  2900.0  3200.0
+1700.0  2400.0  2600.0  2900.0  3300.0  3400.0
+1600.0  1700.0  2100.0  2300.0  2700.0  3200.0
+1800.0  2300.0  2600.0  2900.0  3100.0  3300.0
+1800.0  2400.0  2600.0  2900.0  3300.0  3400.0
+1900.0  2300.0  2700.0  2900.0  3200.0  3400.0
+1400.0  1800.0  2200.0  2500.0  3300.0  3400.0
+1300.0  1900.0  2300.0  2700.0  3100.0  3300.0
+1500.0  1800.0  2300.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2400.0  2500.0  3000.0  3300.0
+1900.0  2300.0  2600.0  2700.0  3200.0  3300.0
+1900.0  2100.0  2700.0  2900.0  3100.0  3300.0
+1600.0  1800.0  2000.0  2500.0  2900.0  3000.0
+1800.0  2100.0  2400.0  2500.0  2900.0  3100.0
+1500.0  1700.0  2400.0  2500.0  2700.0  3000.0
+1400.0  1600.0  2200.0  2500.0  2600.0  3000.0
+1300.0  2100.0  2300.0  2800.0  3100.0  3200.0
+1300.0  2100.0  2200.0  2700.0  3100.0  3200.0
+1500.0  2000.0  2300.0  2500.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2400.0  2800.0  3200.0
+1900.0  2000.0  2300.0  2500.0  2900.0  3300.0
+1600.0  1900.0  2500.0  2800.0  3100.0  3200.0
+1400.0  2000.0  2400.0  2600.0  3000.0  3100.0
+1200.0  1900.0  2000.0  2400.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2000.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2600.0  2900.0  3000.0
+1700.0  1900.0  2300.0  2600.0  3000.0  3100.0
+1800.0  2200.0  2800.0  3000.0  3200.0  3400.0
+2000.0  2300.0  2900.0  3100.0  3300.0  3400.0
+1500.0  2000.0  2300.0  2700.0  3300.0  3400.0
+1200.0  1700.0  2300.0  2500.0  3100.0  3300.0
+1300.0  1800.0  2200.0  2600.0  3200.0  3300.0
+1200.0  2000.0  2200.0  2600.0  3100.0  3200.0
+2000.0  2300.0  2500.0  2900.0  3200.0  3300.0
+2200.0  2300.0  2700.0  3000.0  3200.0  3300.0
+1500.0  2000.0  2300.0  2500.0  2800.0  3000.0
+1200.0  1800.0  2300.0  2400.0  3200.0  3300.0
+1200.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1200.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1600.0  2100.0  2500.0  2700.0  3200.0  3300.0
+1500.0  1700.0  1900.0  2400.0  2800.0  3000.0
+1500.0  1700.0  1900.0  2500.0  2800.0  3000.0
+1500.0  1800.0  2100.0  2700.0  3000.0  3200.0
+2000.0  2200.0  2700.0  3000.0  3300.0  3400.0
+2100.0  2400.0  2800.0  3000.0  3400.0  3500.0
+2000.0  2200.0  2700.0  2900.0  3200.0  3300.0
+2100.0  2500.0  2800.0  3000.0  3400.0  3500.0
+2000.0  2300.0  2600.0  2700.0  3200.0  3300.0
+1900.0  2300.0  2600.0  2700.0  3200.0  3400.0
+1500.0  1800.0  2300.0  2600.0  3000.0  3300.0
+1400.0  1900.0  2400.0  2500.0  2700.0  3000.0
+2200.0  2300.0  2700.0  2900.0  3200.0  3300.0
+2100.0  2300.0  2700.0  2800.0  3200.0  3300.0
+2000.0  2300.0  2500.0  2700.0  3300.0  3400.0
+2300.0  2500.0  2800.0  3100.0  3400.0  3500.0
+2200.0  2600.0  2800.0  3100.0  3300.0  3400.0
+2200.0  2600.0  2700.0  3000.0  3300.0  3400.0
+1900.0  2200.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2400.0  2600.0  2900.0  3100.0
+1700.0  1800.0  2300.0  2500.0  2700.0  3000.0
+1500.0  1800.0  2200.0  2400.0  2800.0  3200.0
+1300.0  2100.0  2400.0  2700.0  3300.0  3400.0
+1200.0  1900.0  2400.0  2600.0  3100.0  3300.0
+1200.0  1500.0  2400.0  2500.0  3100.0  3400.0
+1400.0  1500.0  2400.0  2600.0  3000.0  3400.0
+1500.0  1600.0  2500.0  2600.0  3100.0  3400.0
+1600.0  2100.0  2400.0  2500.0  3100.0  3300.0
+1600.0  2200.0  2400.0  2600.0  3100.0  3300.0
+1800.0  2300.0  2600.0  2900.0  3200.0  3400.0
+2100.0  2200.0  2500.0  2700.0  2900.0  3200.0
+1700.0  2000.0  2300.0  2400.0  2700.0  3000.0
+2000.0  2200.0  2400.0  2700.0  3300.0  3400.0
+1500.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1200.0  1700.0  2200.0  2400.0  3300.0  3400.0
+1400.0  1900.0  2000.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2200.0  2600.0  3200.0  3300.0
+1200.0  2100.0  2300.0  2600.0  3300.0  3400.0
+1100.0  2100.0  2300.0  2600.0  3300.0  3400.0
+1900.0  2100.0  2600.0  2700.0  3100.0  3300.0
+1200.0  1600.0  2100.0  2400.0  3000.0  3300.0
+1200.0  1700.0  2100.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2100.0  2300.0  2600.0  3000.0
+1900.0  2200.0  2300.0  2700.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2500.0  2900.0  3200.0
+1500.0  1900.0  2100.0  2500.0  2900.0  3100.0
+1300.0  1900.0  2100.0  2400.0  3000.0  3100.0
+1800.0  2400.0  2800.0  3000.0  3400.0  3500.0
+1600.0  2000.0  2300.0  2800.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2400.0  3000.0  3300.0
+1400.0  2100.0  2300.0  2500.0  3200.0  3400.0
+1700.0  2000.0  2500.0  2700.0  3000.0  3300.0
+1800.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1400.0  1700.0  1900.0  2800.0  3100.0  3200.0
+1300.0  1600.0  1800.0  2600.0  3100.0  3200.0
+1300.0  1500.0  1600.0  2400.0  3100.0  3200.0
+1400.0  1600.0  1700.0  2200.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2500.0  2900.0  3200.0
+1500.0  1900.0  2100.0  2400.0  3200.0  3300.0
+1800.0  2000.0  2100.0  2500.0  3200.0  3300.0
+1400.0  2000.0  2400.0  2500.0  3100.0  3200.0
+1200.0  1800.0  2500.0  2600.0  3100.0  3300.0
+1100.0  1800.0  2300.0  2600.0  3100.0  3300.0
+1400.0  1700.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2300.0  2600.0  3100.0  3200.0
+1500.0  1800.0  2500.0  2700.0  3100.0  3300.0
+1500.0  1900.0  2500.0  2700.0  3000.0  3200.0
+1600.0  1900.0  2500.0  2800.0  3200.0  3400.0
+1600.0  1700.0  2400.0  2700.0  2900.0  3200.0
+1500.0  1600.0  2100.0  2600.0  2800.0  3100.0
+1300.0  1500.0  1700.0  1900.0  3000.0  3100.0
+1400.0  1500.0  2200.0  2400.0  3100.0  3300.0
+1100.0  1400.0  2200.0  2500.0  3200.0  3300.0
+1200.0  1500.0  1700.0  1900.0  3200.0  3300.0
+1500.0  1700.0  2300.0  2700.0  3000.0  3300.0
+1900.0  2200.0  2700.0  2800.0  3100.0  3400.0
+1900.0  2200.0  2700.0  2900.0  3300.0  3500.0
+1400.0  1900.0  2300.0  2400.0  3000.0  3200.0
+1500.0  1600.0  2300.0  2600.0  2900.0  3200.0
+1800.0  2100.0  2700.0  2800.0  3200.0  3300.0
+1500.0  1700.0  2400.0  2800.0  3100.0  3300.0
+1700.0  1900.0  2700.0  2800.0  3300.0  3400.0
+1700.0  2100.0  2600.0  2800.0  3100.0  3400.0
+1700.0  2200.0  2700.0  2900.0  3200.0  3400.0
+1900.0  2100.0  2400.0  2800.0  3200.0  3400.0
+1800.0  2100.0  2300.0  2600.0  3000.0  3300.0
+1800.0  2000.0  2200.0  2500.0  3100.0  3300.0
+1400.0  1600.0  2300.0  2400.0  3200.0  3300.0
+1600.0  1800.0  2300.0  2400.0  2900.0  3100.0
+1800.0  2200.0  2700.0  2800.0  3100.0  3300.0
+1800.0  2100.0  2700.0  2800.0  3000.0  3300.0
+1800.0  2100.0  2700.0  2800.0  3100.0  3300.0
+1500.0  1900.0  2200.0  2500.0  3200.0  3300.0
+1200.0  1800.0  2200.0  2400.0  3100.0  3300.0
+1000.0  1400.0  2300.0  2400.0  3200.0  3300.0
+1100.0  1500.0  2200.0  2400.0  3200.0  3300.0
+1200.0  1500.0  2100.0  2200.0  3200.0  3300.0
+1900.0  2000.0  2300.0  2600.0  3200.0  3400.0
+1100.0  1500.0  2100.0  2200.0  3200.0  3300.0
+1500.0  2000.0  2600.0  2800.0  3200.0  3400.0
+1400.0  1600.0  2500.0  2800.0  3000.0  3300.0
+1500.0  1600.0  2500.0  2700.0  3100.0  3300.0
+1400.0  1700.0  2600.0  2800.0  3000.0  3300.0
+1100.0  1900.0  2200.0  2400.0  3100.0  3300.0
+1000.0  1800.0  2200.0  2400.0  3200.0  3300.0
+1000.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1300.0  1600.0  1800.0  2000.0  3200.0  3300.0
+1300.0  1500.0  1800.0  1900.0  3200.0  3300.0
+1500.0  1700.0  2100.0  2500.0  3000.0  3300.0
+1700.0  1800.0  2400.0  2600.0  3100.0  3400.0
+1500.0  1600.0  2100.0  2600.0  2800.0  3200.0
+1500.0  1600.0  2200.0  2600.0  2800.0  3000.0
+1600.0  1700.0  2100.0  2500.0  2900.0  3100.0
+1500.0  1600.0  2100.0  2500.0  2800.0  3200.0
+1500.0  1600.0  2100.0  2500.0  2700.0  3100.0
+1500.0  1600.0  2100.0  2400.0  2800.0  3100.0
+1500.0  1700.0  2200.0  2400.0  2800.0  3100.0
+2000.0  2300.0  2600.0  2700.0  3200.0  3400.0
+1600.0  1800.0  2100.0  2600.0  3100.0  3300.0
+1600.0  1700.0  2200.0  2700.0  3100.0  3300.0
+1300.0  1800.0  2400.0  2600.0  3100.0  3300.0
+1300.0  1500.0  2400.0  2700.0  3000.0  3300.0
+1500.0  1600.0  1900.0  2600.0  2900.0  3000.0
+1800.0  1900.0  2200.0  2700.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2700.0  3000.0  3300.0
+1800.0  1900.0  2400.0  2700.0  2900.0  3300.0
+1900.0  2000.0  2600.0  2700.0  3000.0  3200.0
+1900.0  2200.0  2700.0  2800.0  3000.0  3200.0
+1500.0  1600.0  2100.0  2500.0  2800.0  3100.0
+1100.0  1300.0  2400.0  2600.0  2800.0  3200.0
+1200.0  1500.0  2300.0  2600.0  3100.0  3300.0
+1200.0  1600.0  1800.0  2000.0  3200.0  3300.0
+1400.0  1600.0  1900.0  2000.0  3200.0  3300.0
+1300.0  1500.0  1700.0  1900.0  3200.0  3300.0
+2000.0  2200.0  2700.0  2800.0  3200.0  3400.0
+1500.0  1600.0  2400.0  2500.0  2900.0  3300.0
+1100.0  1700.0  2100.0  2300.0  3100.0  3200.0
+1500.0  1600.0  2100.0  2700.0  2900.0  3000.0
+1500.0  1900.0  2300.0  2600.0  2900.0  3000.0
+1600.0  2000.0  2200.0  2600.0  3100.0  3300.0
+1400.0  1600.0  1800.0  2000.0  3100.0  3200.0
+1900.0  2000.0  2300.0  2500.0  3000.0  3300.0
+1900.0  2100.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2400.0  2700.0  2800.0  3200.0  3400.0
+1900.0  2500.0  2700.0  2800.0  3300.0  3400.0
+2000.0  2500.0  2800.0  2900.0  3300.0  3500.0
+2100.0  2600.0  2800.0  3000.0  3400.0  3500.0
+1500.0  1600.0  2300.0  2600.0  2900.0  3300.0
+1600.0  2100.0  2600.0  2800.0  3200.0  3300.0
+1300.0  1500.0  2300.0  2700.0  3000.0  3300.0
+1400.0  1800.0  2300.0  2500.0  2700.0  3100.0
+1400.0  1600.0  2400.0  2700.0  3200.0  3300.0
+1400.0  1500.0  2300.0  2600.0  3200.0  3300.0
+1400.0  1600.0  2200.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2100.0  2300.0  3200.0  3400.0
+2100.0  2400.0  2700.0  2800.0  3100.0  3400.0
+2100.0  2400.0  2700.0  2800.0  3200.0  3400.0
+1600.0  1800.0  2600.0  2700.0  3000.0  3400.0
+1500.0  1700.0  2600.0  2700.0  2900.0  3300.0
+1600.0  1800.0  2600.0  2700.0  3000.0  3200.0
+1900.0  2500.0  2700.0  3000.0  3400.0  3500.0
+2000.0  2500.0  2600.0  3100.0  3300.0  3400.0
+2100.0  2300.0  2700.0  3000.0  3200.0  3400.0
+1600.0  1700.0  2100.0  2500.0  3100.0  3300.0
+1600.0  1700.0  2000.0  2400.0  3200.0  3300.0
+1600.0  1700.0  2000.0  2500.0  3200.0  3300.0
+2200.0  2500.0  2700.0  2900.0  3300.0  3400.0
+1200.0  1400.0  2100.0  2500.0  3000.0  3100.0
+1400.0  1700.0  2200.0  2400.0  3100.0  3300.0
+1300.0  1700.0  2000.0  2200.0  3100.0  3200.0
+1200.0  1600.0  1700.0  2100.0  3100.0  3200.0
+1800.0  2100.0  2700.0  2900.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2800.0  2900.0  3100.0
+1900.0  2000.0  2300.0  2700.0  2900.0  3200.0
+2000.0  2100.0  2400.0  2700.0  3000.0  3200.0
+1800.0  1900.0  2400.0  2700.0  3100.0  3400.0
+1700.0  1800.0  2500.0  2800.0  3000.0  3300.0
+2200.0  2600.0  2800.0  2900.0  3300.0  3400.0
+1500.0  1700.0  2200.0  2500.0  3200.0  3300.0
+1300.0  1600.0  2200.0  2500.0  3100.0  3200.0
+1700.0  1900.0  2300.0  2700.0  3100.0  3200.0
+1700.0  1900.0  2400.0  2800.0  3000.0  3200.0
+1300.0  1800.0  2200.0  2600.0  3000.0  3300.0
+1200.0  1500.0  2300.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2400.0  3100.0  3400.0
+1300.0  1700.0  2200.0  2300.0  3100.0  3300.0
+1500.0  1700.0  2300.0  2500.0  3200.0  3300.0
+1500.0  1600.0  2400.0  2600.0  3200.0  3300.0
+1600.0  1700.0  2400.0  2700.0  3100.0  3400.0
+1600.0  1700.0  2300.0  2800.0  3000.0  3300.0
+1300.0  1700.0  2300.0  2600.0  2700.0  2900.0
+1500.0  1600.0  2200.0  2600.0  2800.0  3200.0
+1300.0  1700.0  2200.0  2400.0  3000.0  3200.0
+1400.0  1900.0  2300.0  2600.0  2900.0  3300.0
+1200.0  1400.0  2500.0  2600.0  3100.0  3400.0
+1500.0  1600.0  2200.0  2500.0  2700.0  3200.0
+1600.0  1700.0  2300.0  2500.0  2700.0  3300.0
+1100.0  1300.0  2200.0  2700.0  3000.0  3200.0
+1200.0  1300.0  2000.0  2700.0  2900.0  3100.0
+1800.0  2000.0  2700.0  2900.0  3100.0  3300.0
+1800.0  1900.0  2400.0  2800.0  3000.0  3300.0
+1900.0  2000.0  2400.0  2800.0  3000.0  3300.0
+2000.0  2100.0  2400.0  2700.0  2900.0  3100.0
+1700.0  1800.0  2300.0  2600.0  2700.0  3100.0
+1500.0  1700.0  2100.0  2500.0  2700.0  2900.0
+1400.0  1800.0  2400.0  2600.0  2800.0  3200.0
+2000.0  2100.0  2500.0  2900.0  3100.0  3300.0
+2000.0  2100.0  2600.0  2900.0  3100.0  3300.0
+2100.0  2200.0  2500.0  2800.0  3100.0  3300.0
+1900.0  2000.0  2500.0  2600.0  2900.0  3100.0
+1800.0  1900.0  2500.0  2700.0  2800.0  3100.0
+1900.0  2300.0  2800.0  2900.0  3300.0  3400.0
+1700.0  1800.0  2100.0  2200.0  3100.0  3200.0
+1800.0  1900.0  2200.0  2300.0  3100.0  3200.0
+1200.0  1700.0  2100.0  2300.0  3200.0  3300.0
+1400.0  1600.0  2000.0  2200.0  3000.0  3100.0
+1500.0  1600.0  2200.0  2500.0  2900.0  3100.0
+1900.0  2200.0  2400.0  2600.0  2800.0  3000.0
+1900.0  2100.0  2400.0  2700.0  2800.0  3000.0
+1900.0  2100.0  2300.0  2700.0  2900.0  3000.0
+1800.0  2000.0  2400.0  2900.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2800.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2500.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2200.0  2700.0  3100.0
+1600.0  1700.0  2100.0  2200.0  2600.0  3100.0
+1900.0  2200.0  2400.0  2900.0  3300.0  3400.0
+1600.0  1800.0  2400.0  2500.0  2900.0  3200.0
+2000.0  2200.0  2400.0  2500.0  2800.0  3200.0
+2000.0  2400.0  2500.0  2700.0  2900.0  3100.0
+1900.0  2000.0  2200.0  2300.0  3100.0  3400.0
+2000.0  2100.0  2300.0  2600.0  3000.0  3200.0
+2000.0  2100.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2600.0  2900.0  3000.0
+1300.0  1500.0  2300.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2100.0  2600.0  2900.0  3000.0
+1700.0  1800.0  2200.0  2500.0  2700.0  3100.0
+1900.0  2400.0  2600.0  2700.0  3000.0  3100.0
+2000.0  2400.0  2500.0  2900.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2600.0  2800.0  3100.0
+1900.0  2100.0  2600.0  3000.0  3200.0  3300.0
+1800.0  2300.0  2400.0  2600.0  3200.0  3300.0
+1900.0  2200.0  2300.0  2600.0  3200.0  3300.0
+1900.0  2400.0  2800.0  2900.0  3200.0  3400.0
+1800.0  2400.0  2700.0  2800.0  3200.0  3400.0
+1700.0  2100.0  2200.0  2600.0  3000.0  3100.0
+1900.0  2200.0  2500.0  2900.0  3200.0  3400.0
+1800.0  2400.0  2600.0  2700.0  3300.0  3400.0
+1900.0  2500.0  2700.0  2900.0  3300.0  3400.0
+1900.0  2400.0  2800.0  2900.0  3300.0  3400.0
+1800.0  2400.0  2800.0  2900.0  3200.0  3400.0
+1200.0  1300.0  2400.0  2800.0  2900.0  3100.0
+1600.0  1800.0  2000.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2300.0  2700.0  3200.0  3300.0
+1800.0  2100.0  2300.0  2800.0  3200.0  3300.0
+1500.0  1600.0  2100.0  2200.0  2800.0  3100.0
+1500.0  1600.0  2000.0  2200.0  2500.0  3100.0
+1400.0  1500.0  2200.0  2500.0  2700.0  3000.0
+1200.0  1400.0  2300.0  2600.0  2800.0  3100.0
+1700.0  1800.0  2100.0  2400.0  2800.0  3000.0
+1700.0  2100.0  2200.0  2600.0  2800.0  2900.0
+2000.0  2200.0  2400.0  2700.0  3000.0  3100.0
+1500.0  2100.0  2500.0  2600.0  3100.0  3200.0
+1800.0  2400.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2400.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2300.0  2400.0  2600.0  3200.0  3300.0
+1900.0  2000.0  2400.0  2700.0  3000.0  3100.0
+2000.0  2200.0  2700.0  2900.0  3100.0  3200.0
+1800.0  1900.0  2300.0  2800.0  3200.0  3300.0
+1900.0  2000.0  2200.0  2700.0  3200.0  3300.0
+1900.0  2100.0  2200.0  2700.0  3200.0  3300.0
+1600.0  2000.0  2200.0  2700.0  3200.0  3300.0
+1800.0  2000.0  2300.0  2800.0  3200.0  3300.0
+2000.0  2200.0  2500.0  2800.0  3200.0  3400.0
+1800.0  2100.0  2400.0  2900.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2700.0  3000.0  3100.0
+1500.0  1700.0  2100.0  2300.0  2600.0  3100.0
+1400.0  1500.0  1800.0  1900.0  2400.0  3000.0
+1400.0  1500.0  1800.0  1900.0  2300.0  3000.0
+1400.0  1600.0  1900.0  2000.0  2600.0  3200.0
+1700.0  1800.0  2200.0  2300.0  2700.0  3100.0
+1500.0  1600.0  2100.0  2700.0  3100.0  3200.0
+1400.0  1500.0  2100.0  2700.0  3100.0  3200.0
+1700.0  1800.0  2200.0  2600.0  2900.0  3000.0
+1800.0  1900.0  2200.0  2600.0  2900.0  3000.0
+1400.0  1600.0  2100.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2000.0  2500.0  2900.0  3100.0
+1600.0  1800.0  2400.0  2800.0  3100.0  3200.0
+1400.0  1900.0  2300.0  2700.0  3100.0  3200.0
+1900.0  2200.0  2500.0  2900.0  3300.0  3400.0
+1500.0  1600.0  2100.0  2800.0  3200.0  3300.0
+1400.0  1500.0  1700.0  1900.0  2800.0  3100.0
+1400.0  1600.0  2100.0  2600.0  2800.0  3100.0
+1500.0  1700.0  2300.0  2600.0  2800.0  3000.0
+1600.0  1700.0  2500.0  2700.0  3100.0  3200.0
+1600.0  1900.0  2400.0  2800.0  3000.0  3200.0
+1800.0  2300.0  2600.0  2700.0  3100.0  3300.0
+1900.0  2300.0  2500.0  2700.0  3100.0  3300.0
+1700.0  2000.0  2200.0  2600.0  3000.0  3100.0
+1600.0  1900.0  2100.0  2700.0  2900.0  3100.0
+1600.0  2200.0  2400.0  2700.0  3200.0  3300.0
+1700.0  2300.0  2500.0  2700.0  3200.0  3300.0
+1600.0  2100.0  2300.0  2500.0  3100.0  3200.0
+1700.0  2100.0  2300.0  2500.0  3100.0  3200.0
+1800.0  2200.0  2300.0  2600.0  3200.0  3300.0
+1700.0  2200.0  2400.0  2600.0  3300.0  3400.0
+1700.0  2200.0  2300.0  2600.0  3200.0  3300.0
+1800.0  1900.0  2300.0  2600.0  2900.0  3200.0
+1700.0  1800.0  2200.0  2400.0  2700.0  3000.0
+1800.0  1900.0  2200.0  2500.0  2700.0  3100.0
+1700.0  1900.0  2100.0  2600.0  3100.0  3200.0
+1900.0  2000.0  2300.0  2800.0  3200.0  3300.0
+1800.0  2000.0  2200.0  2700.0  3200.0  3300.0
+1700.0  1800.0  2100.0  2400.0  3200.0  3300.0
+1200.0  1500.0  2400.0  2700.0  2900.0  3000.0
+1700.0  1800.0  2100.0  2200.0  2500.0  3000.0
+1700.0  1800.0  2100.0  2200.0  2400.0  3000.0
+1600.0  1700.0  2000.0  2100.0  2400.0  3000.0
+1600.0  1700.0  1900.0  2000.0  2500.0  3000.0
+1700.0  1900.0  2100.0  2400.0  2600.0  2900.0
+1800.0  2000.0  2200.0  2400.0  2600.0  3000.0
+1600.0  1900.0  2400.0  2500.0  2900.0  3200.0
+1900.0  2100.0  2300.0  2700.0  3200.0  3300.0
+1900.0  2000.0  2300.0  2700.0  2800.0  3000.0
+1900.0  2000.0  2300.0  2700.0  2800.0  3100.0
+1500.0  1600.0  2300.0  2700.0  2900.0  3100.0
+1700.0  2200.0  2700.0  2800.0  3100.0  3300.0
+1600.0  2000.0  2600.0  2800.0  3200.0  3300.0
+1800.0  2200.0  2400.0  2600.0  3100.0  3200.0
+1600.0  2200.0  2600.0  2700.0  3000.0  3100.0
+2000.0  2200.0  2400.0  2600.0  2900.0  3100.0
+1400.0  1600.0  2000.0  2600.0  2800.0  3000.0
+1500.0  1600.0  2500.0  2700.0  3000.0  3100.0
+1300.0  1500.0  2200.0  2600.0  3100.0  3300.0
+1100.0  1600.0  2200.0  2500.0  3000.0  3200.0
+1200.0  1400.0  2200.0  2700.0  2800.0  3000.0
+1200.0  1400.0  2300.0  2600.0  2700.0  3000.0
+1600.0  1700.0  2000.0  2100.0  2600.0  3100.0
+1800.0  2300.0  2400.0  2600.0  2800.0  3100.0
+1700.0  2300.0  2700.0  2800.0  3200.0  3300.0
+1300.0  1600.0  2300.0  2700.0  2900.0  3000.0
+1500.0  1600.0  2200.0  2700.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2700.0  3000.0  3100.0
+1900.0  2000.0  2300.0  2600.0  2800.0  3000.0
+1900.0  2100.0  2300.0  2600.0  2800.0  3000.0
+1500.0  1900.0  2500.0  2700.0  3000.0  3100.0
+1900.0  2400.0  2700.0  2900.0  3100.0  3300.0
+1300.0  1600.0  1800.0  2100.0  2900.0  3200.0
+1700.0  1800.0  2000.0  2200.0  3100.0  3200.0
+2000.0  2300.0  2700.0  3100.0  3300.0  3400.0
+1900.0  2200.0  2300.0  2600.0  3000.0  3200.0
+1900.0  2300.0  2800.0  3000.0  3200.0  3300.0
+2100.0  2300.0  2800.0  2900.0  3200.0  3300.0
+2000.0  2200.0  2800.0  2900.0  3200.0  3300.0
+1700.0  1900.0  2400.0  2800.0  3200.0  3300.0
+1500.0  1600.0  2200.0  2800.0  3200.0  3300.0
+1400.0  1500.0  2200.0  2500.0  2900.0  3200.0
+1300.0  1800.0  2200.0  2500.0  3100.0  3200.0
+1200.0  1800.0  2300.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2500.0  2700.0  3200.0  3300.0
+1900.0  2300.0  2400.0  2700.0  2900.0  3100.0
+1900.0  2200.0  2400.0  2600.0  3000.0  3100.0
+1600.0  1800.0  2100.0  2800.0  3100.0  3200.0
+1800.0  2400.0  2600.0  2700.0  3000.0  3100.0
+1600.0  1700.0  1900.0  2000.0  2500.0  3100.0
+1800.0  1900.0  2100.0  2300.0  2900.0  3300.0
+1300.0  1700.0  2400.0  2700.0  3200.0  3300.0
+1500.0  2000.0  2500.0  2800.0  3100.0  3300.0
+1900.0  2300.0  2400.0  2600.0  3300.0  3400.0
+1900.0  2300.0  2500.0  2700.0  3200.0  3300.0
+1400.0  1600.0  2100.0  2800.0  3100.0  3200.0
+1500.0  1600.0  2100.0  2200.0  2700.0  3200.0
+1500.0  1600.0  1900.0  2000.0  2600.0  3100.0
+1400.0  1500.0  1900.0  2000.0  2600.0  3100.0
+1400.0  1600.0  1900.0  2000.0  2700.0  3200.0
+1700.0  1900.0  2100.0  2400.0  3000.0  3100.0
+1800.0  2000.0  2200.0  2400.0  2900.0  3200.0
+1700.0  2000.0  2200.0  2400.0  2800.0  3100.0
+1800.0  2000.0  2300.0  2700.0  2900.0  3200.0
+1700.0  2000.0  2200.0  2400.0  3000.0  3200.0
+1600.0  1900.0  2100.0  2300.0  3000.0  3200.0
+1700.0  1900.0  2100.0  2300.0  3000.0  3200.0
+1600.0  1900.0  2100.0  2400.0  3000.0  3200.0
+1700.0  1900.0  2200.0  2600.0  2900.0  3100.0
+1500.0  1800.0  1900.0  2400.0  2800.0  3000.0
+1700.0  2000.0  2400.0  2900.0  3100.0  3300.0
+1800.0  2000.0  2700.0  2900.0  3200.0  3400.0
+2000.0  2200.0  2600.0  2900.0  3100.0  3200.0
+1600.0  2200.0  2500.0  2700.0  3200.0  3300.0
+1800.0  2000.0  2200.0  2400.0  2600.0  3100.0
+1700.0  1800.0  2000.0  2100.0  2600.0  3100.0
+1600.0  1700.0  1900.0  2000.0  2700.0  3200.0
+1700.0  1900.0  2100.0  2300.0  2600.0  3100.0
+2000.0  2300.0  2500.0  2600.0  3200.0  3300.0
+1500.0  2100.0  2500.0  2700.0  3100.0  3200.0
+1500.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1600.0  2200.0  2500.0  2800.0  3100.0  3200.0
+1500.0  2100.0  2400.0  2700.0  3100.0  3200.0
+1600.0  2100.0  2400.0  2700.0  3000.0  3100.0
+1800.0  2100.0  2400.0  2700.0  3000.0  3100.0
+1500.0  1600.0  2000.0  2600.0  3000.0  3200.0
+1400.0  1900.0  2400.0  2600.0  3000.0  3300.0
+1400.0  1500.0  2100.0  2600.0  3000.0  3100.0
+1300.0  1500.0  2300.0  2600.0  2800.0  3200.0
+1400.0  1600.0  2200.0  2600.0  3000.0  3200.0
+1700.0  1800.0  2200.0  2600.0  2900.0  3200.0
+1700.0  1800.0  2000.0  2600.0  2900.0  3100.0
+1600.0  1800.0  2000.0  2500.0  3000.0  3200.0
+1300.0  1500.0  2300.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2300.0  2800.0  3200.0  3300.0
+1900.0  2000.0  2300.0  2400.0  3000.0  3200.0
+1700.0  1900.0  2200.0  2600.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2600.0  2800.0  2900.0
+1600.0  1700.0  2000.0  2300.0  3100.0  3200.0
+1600.0  1700.0  2100.0  2400.0  3000.0  3200.0
+2000.0  2100.0  2400.0  2800.0  3100.0  3300.0
+1700.0  2200.0  2300.0  2700.0  3000.0  3100.0
+1700.0  2200.0  2400.0  2600.0  3000.0  3200.0
+1900.0  2300.0  2400.0  2600.0  3000.0  3200.0
+2100.0  2200.0  2600.0  2800.0  3200.0  3400.0
+2100.0  2200.0  2700.0  2900.0  3200.0  3400.0
+2000.0  2200.0  2800.0  3000.0  3200.0  3400.0
+2000.0  2200.0  2700.0  3000.0  3200.0  3400.0
+2000.0  2200.0  2700.0  2900.0  3200.0  3400.0
+1700.0  2100.0  2400.0  2900.0  3100.0  3200.0
+1500.0  1800.0  1900.0  2500.0  3000.0  3100.0
+1700.0  1800.0  2100.0  2400.0  2900.0  3300.0
+1800.0  2000.0  2300.0  2400.0  2700.0  3100.0
+1800.0  2100.0  2300.0  2800.0  3000.0  3200.0
+1600.0  2300.0  2500.0  2800.0  3100.0  3200.0
+1600.0  2100.0  2500.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2100.0  2800.0  3000.0  3100.0
+1800.0  2300.0  2600.0  2700.0  3100.0  3200.0
+2000.0  2200.0  2800.0  3000.0  3300.0  3400.0
+2000.0  2200.0  2600.0  2800.0  3200.0  3400.0
+1700.0  1800.0  2200.0  2600.0  2800.0  3200.0
+1600.0  1800.0  2200.0  2500.0  2800.0  3200.0
+1600.0  1700.0  1900.0  2000.0  2600.0  3100.0
+1600.0  1700.0  2200.0  2800.0  3000.0  3200.0
+1700.0  1800.0  2400.0  2900.0  3100.0  3300.0
+1900.0  2200.0  2700.0  2900.0  3400.0  3500.0
+1700.0  1800.0  2000.0  2200.0  2900.0  3200.0
+1700.0  1900.0  2100.0  2300.0  2900.0  3200.0
+1200.0  1400.0  2200.0  2900.0  3100.0  3200.0
+1800.0  1900.0  2300.0  2600.0  2800.0  3200.0
+1600.0  1700.0  2000.0  2200.0  2700.0  3200.0
+1600.0  1700.0  2000.0  2200.0  2800.0  3200.0
+1600.0  1700.0  2000.0  2100.0  2800.0  3200.0
+1600.0  1800.0  2000.0  2100.0  2800.0  3200.0
+1700.0  1800.0  2000.0  2300.0  2900.0  3200.0
+1800.0  1900.0  2200.0  2600.0  3200.0  3300.0
+1800.0  2000.0  2200.0  2500.0  3200.0  3300.0
+1300.0  1500.0  1900.0  2600.0  3100.0  3200.0
+1300.0  1400.0  2000.0  2600.0  3200.0  3300.0
+1600.0  1700.0  2100.0  2700.0  3000.0  3200.0
+1400.0  1500.0  2000.0  2600.0  3100.0  3200.0
+1400.0  1500.0  2000.0  2700.0  3100.0  3200.0
+1500.0  1800.0  2400.0  2700.0  3000.0  3300.0
+1500.0  1600.0  2200.0  2300.0  2700.0  3300.0
+1400.0  1500.0  2200.0  2400.0  2700.0  3200.0
+1300.0  1500.0  2300.0  2600.0  2900.0  3200.0
+1400.0  1700.0  2400.0  2600.0  3000.0  3200.0
+1300.0  1600.0  2400.0  2500.0  2900.0  3200.0
+1400.0  1500.0  2200.0  2400.0  2900.0  3300.0
+1400.0  1600.0  2100.0  2200.0  3200.0  3300.0
+1400.0  1800.0  2200.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2500.0  2600.0  3100.0  3200.0
+1500.0  1700.0  1900.0  2600.0  3200.0  3300.0
+1500.0  1600.0  1800.0  2000.0  2800.0  3200.0
+1500.0  1600.0  1900.0  2000.0  2700.0  3200.0
+1500.0  1600.0  1900.0  2000.0  2800.0  3200.0
+1600.0  1700.0  2000.0  2500.0  3000.0  3200.0
+1600.0  1700.0  2200.0  2700.0  2900.0  3200.0
+1300.0  1500.0  2300.0  2700.0  2900.0  3200.0
+1600.0  1700.0  2600.0  2800.0  2900.0  3200.0
+1300.0  1500.0  2300.0  2500.0  2800.0  3200.0
+1300.0  1400.0  2300.0  2500.0  2800.0  3200.0
+1500.0  1700.0  2200.0  2600.0  2700.0  3100.0
+1500.0  1700.0  2200.0  2600.0  2800.0  3000.0
+1500.0  1700.0  2000.0  2600.0  2700.0  3000.0
+1100.0  1300.0  2300.0  2800.0  3100.0  3200.0
+1600.0  1700.0  2100.0  2500.0  3200.0  3300.0
+1700.0  1800.0  2300.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2300.0  2700.0  2900.0  3200.0
+1800.0  2000.0  2500.0  2800.0  3100.0  3400.0
+1900.0  2000.0  2800.0  2900.0  3300.0  3400.0
+1800.0  2000.0  2700.0  2800.0  3300.0  3400.0
+1700.0  1800.0  2100.0  2200.0  2600.0  3100.0
+1500.0  1600.0  1800.0  1900.0  2600.0  3200.0
+1600.0  1700.0  1900.0  2000.0  2600.0  3200.0
+1600.0  1700.0  2000.0  2100.0  2600.0  3200.0
+1700.0  1800.0  2000.0  2100.0  2800.0  3300.0
+1600.0  1900.0  2100.0  2400.0  3000.0  3100.0
+1600.0  1800.0  2300.0  2600.0  2900.0  3000.0
+1400.0  1500.0  2100.0  2600.0  2900.0  3100.0
+1400.0  1500.0  2200.0  2600.0  2900.0  3100.0
+1000.0  1200.0  2300.0  2900.0  3100.0  3200.0
+1300.0  1700.0  2400.0  2600.0  3000.0  3200.0
+1100.0  1600.0  2300.0  2600.0  3200.0  3300.0
+1200.0  1600.0  2300.0  2600.0  3100.0  3300.0
+1100.0  1600.0  2200.0  2600.0  3100.0  3300.0
+1600.0  2200.0  2400.0  2700.0  3100.0  3200.0
+1700.0  1800.0  2300.0  2700.0  2800.0  3000.0
+1400.0  1700.0  1900.0  2500.0  3200.0  3300.0
+1700.0  1900.0  2200.0  2400.0  2800.0  3000.0
+1400.0  1600.0  2100.0  2200.0  2700.0  3000.0
+1500.0  1700.0  2200.0  2400.0  2700.0  3100.0
+1500.0  1600.0  2200.0  2400.0  2800.0  3100.0
+1000.0  1900.0  2200.0  2500.0  3200.0  3300.0
+1200.0  1700.0  2100.0  2400.0  3200.0  3300.0
+1700.0  2000.0  2500.0  2600.0  3100.0  3400.0
+1600.0  2200.0  2400.0  2600.0  3200.0  3300.0
+2000.0  2500.0  2600.0  3000.0  3300.0  3400.0
+1400.0  1500.0  2100.0  2300.0  3200.0  3300.0
+1500.0  1700.0  2100.0  2400.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2300.0  3300.0  3400.0
+1800.0  2200.0  2500.0  2700.0  3100.0  3400.0
+1500.0  1900.0  2300.0  2600.0  3200.0  3300.0
+2100.0  2200.0  2600.0  2900.0  3100.0  3300.0
+1500.0  1600.0  1800.0  2600.0  3200.0  3300.0
+1300.0  1500.0  1600.0  2200.0  3100.0  3200.0
+1200.0  1800.0  2300.0  2400.0  3000.0  3200.0
+1100.0  1900.0  2100.0  2500.0  3200.0  3300.0
+1400.0  1700.0  2200.0  2500.0  3100.0  3200.0
+1900.0  2100.0  2300.0  2600.0  3000.0  3300.0
+1900.0  2100.0  2500.0  2800.0  3300.0  3400.0
+1700.0  1900.0  2300.0  2500.0  3100.0  3400.0
+1500.0  1900.0  2200.0  2500.0  2900.0  3200.0
+1200.0  2000.0  2300.0  2400.0  2500.0  3100.0
+1200.0  2000.0  2300.0  2400.0  2600.0  3100.0
+1900.0  2200.0  2500.0  2600.0  3100.0  3300.0
+1900.0  2200.0  2500.0  2700.0  3200.0  3400.0
+1800.0  2100.0  2400.0  2500.0  3200.0  3300.0
+1800.0  2100.0  2300.0  2500.0  3300.0  3400.0
+1500.0  1700.0  1800.0  2500.0  3200.0  3300.0
+1400.0  1600.0  1800.0  2300.0  3200.0  3300.0
+1300.0  1600.0  2300.0  2400.0  3200.0  3400.0
+1200.0  1500.0  1700.0  2100.0  3100.0  3200.0
+2100.0  2300.0  2400.0  2800.0  3200.0  3300.0
+1500.0  2000.0  2300.0  2400.0  3100.0  3300.0
+1400.0  1600.0  2000.0  2100.0  3000.0  3300.0
+1900.0  2000.0  2200.0  2400.0  3000.0  3300.0
+1500.0  1800.0  2200.0  2300.0  3000.0  3300.0
+1300.0  1500.0  2100.0  2200.0  2800.0  3300.0
+1500.0  1800.0  2200.0  2400.0  3000.0  3300.0
+1600.0  1900.0  2300.0  2600.0  3200.0  3400.0
+1300.0  1800.0  2200.0  2500.0  3000.0  3200.0
+1100.0  1600.0  2200.0  2300.0  3100.0  3200.0
+1300.0  1500.0  2000.0  2200.0  3100.0  3300.0
+2300.0  2500.0  2900.0  3100.0  3200.0  3300.0
+2300.0  2400.0  2700.0  2800.0  3100.0  3300.0
+2000.0  2100.0  2400.0  2700.0  3200.0  3300.0
+1600.0  1700.0  1900.0  2100.0  3200.0  3300.0
+1600.0  1800.0  1900.0  2300.0  3200.0  3300.0
+1500.0  1600.0  1900.0  2600.0  3100.0  3200.0
+1300.0  1500.0  1900.0  2300.0  3000.0  3100.0
+1200.0  1600.0  2000.0  2100.0  3200.0  3300.0
+1300.0  2000.0  2200.0  2400.0  2700.0  3100.0
+1100.0  1900.0  2300.0  2400.0  3000.0  3100.0
+1200.0  1500.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1600.0  1900.0  2500.0  3000.0  3100.0
+1300.0  1500.0  1600.0  2300.0  3200.0  3300.0
+1500.0  1800.0  2100.0  2400.0  3100.0  3200.0
+1900.0  2200.0  2500.0  2600.0  3200.0  3400.0
+1400.0  1500.0  2100.0  2300.0  2900.0  3200.0
+1100.0  1600.0  2100.0  2300.0  3100.0  3200.0
+1100.0  1600.0  2100.0  2300.0  3200.0  3300.0
+1000.0  1600.0  2200.0  2300.0  3100.0  3300.0
+1100.0  1600.0  2100.0  2300.0  3000.0  3100.0
+1100.0  1400.0  2300.0  2500.0  3200.0  3300.0
+1700.0  2100.0  2500.0  2800.0  3100.0  3400.0
+1300.0  1600.0  2300.0  2400.0  3200.0  3300.0
+1400.0  1700.0  2300.0  2400.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2400.0  3000.0  3300.0
+1700.0  1900.0  2500.0  2600.0  3000.0  3200.0
+1100.0  1500.0  2400.0  2500.0  3100.0  3200.0
+1700.0  1900.0  2100.0  2400.0  3100.0  3300.0
+1300.0  1700.0  2200.0  2600.0  3100.0  3300.0
+1600.0  1700.0  2000.0  2200.0  3100.0  3300.0
+1800.0  2000.0  2200.0  2400.0  3200.0  3400.0
+1900.0  2100.0  2600.0  2800.0  3000.0  3200.0
+1900.0  2100.0  2600.0  2800.0  3100.0  3200.0
+1400.0  1900.0  2400.0  2500.0  3100.0  3300.0
+1100.0  2100.0  2300.0  2700.0  3100.0  3200.0
+1100.0  1800.0  2200.0  2500.0  3000.0  3100.0
+1100.0  1800.0  2200.0  2400.0  3000.0  3100.0
+1500.0  1800.0  2400.0  2500.0  3100.0  3300.0
+1500.0  2000.0  2400.0  2500.0  3200.0  3400.0
+1800.0  2000.0  2500.0  2600.0  3000.0  3300.0
+1900.0  2400.0  2600.0  2900.0  3200.0  3400.0
+1500.0  2100.0  2500.0  2700.0  3200.0  3300.0
+1400.0  2100.0  2400.0  2700.0  3100.0  3200.0
+1500.0  2100.0  2500.0  2700.0  3000.0  3200.0
+1600.0  2100.0  2500.0  2600.0  3100.0  3300.0
+1500.0  1800.0  2100.0  2700.0  3100.0  3300.0
+1300.0  1600.0  1800.0  2500.0  3200.0  3300.0
+1300.0  1500.0  1600.0  2800.0  3300.0  3400.0
+1300.0  1400.0  2200.0  2300.0  3100.0  3300.0
+1300.0  1600.0  2400.0  2500.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2500.0  3200.0  3400.0
+1400.0  2000.0  2100.0  2400.0  3000.0  3100.0
+1300.0  1900.0  2100.0  2400.0  3100.0  3200.0
+1600.0  1700.0  2200.0  2600.0  3200.0  3300.0
+1400.0  1800.0  2300.0  2400.0  2900.0  3200.0
+1300.0  1600.0  2200.0  2400.0  3000.0  3200.0
+1200.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1500.0  1600.0  2200.0  2400.0  3100.0  3300.0
+1000.0  1600.0  2500.0  2600.0  3100.0  3200.0
+900.0  1600.0  2500.0  2600.0  3200.0  3300.0
+1400.0  1700.0  2500.0  2700.0  3100.0  3300.0
+1300.0  1900.0  2500.0  2700.0  3200.0  3300.0
+1600.0  2000.0  2400.0  2500.0  2900.0  3100.0
+1400.0  1600.0  2500.0  2600.0  3200.0  3400.0
+1400.0  1600.0  2600.0  2700.0  3100.0  3300.0
+1400.0  1600.0  2600.0  2700.0  3100.0  3400.0
+1600.0  2100.0  2600.0  2900.0  3300.0  3400.0
+1800.0  2100.0  2800.0  3000.0  3300.0  3400.0
+1800.0  2300.0  2700.0  2900.0  3400.0  3500.0
+1800.0  2400.0  2900.0  3100.0  3300.0  3400.0
+1200.0  1800.0  2300.0  2400.0  3000.0  3100.0
+1300.0  1600.0  2400.0  2500.0  3100.0  3200.0
+1400.0  1800.0  2400.0  2500.0  3200.0  3400.0
+2000.0  2500.0  2700.0  3100.0  3300.0  3400.0
+1900.0  2000.0  2400.0  2800.0  3100.0  3300.0
+1500.0  1800.0  1900.0  2500.0  3100.0  3200.0
+1600.0  1800.0  2000.0  2600.0  3100.0  3200.0
+1700.0  2000.0  2200.0  2700.0  3000.0  3100.0
+1700.0  2000.0  2300.0  2600.0  2900.0  3000.0
+2300.0  2400.0  2700.0  2900.0  3200.0  3300.0
+1200.0  1600.0  2200.0  2300.0  3000.0  3100.0
+1400.0  2000.0  2300.0  2500.0  3100.0  3200.0
+1500.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1300.0  1700.0  1800.0  2400.0  2900.0  3000.0
+1300.0  1500.0  1600.0  2200.0  2800.0  2900.0
+1900.0  2100.0  2500.0  2700.0  3000.0  3300.0
+1500.0  1900.0  2400.0  2600.0  2900.0  3300.0
+1400.0  1800.0  2300.0  2500.0  3100.0  3300.0
+1300.0  1800.0  2500.0  2700.0  3100.0  3300.0
+1300.0  1800.0  2400.0  2600.0  3100.0  3200.0
+1200.0  1700.0  2400.0  2500.0  2900.0  3100.0
+1100.0  1800.0  2000.0  2200.0  3000.0  3100.0
+1300.0  1600.0  1700.0  2600.0  3100.0  3200.0
+1700.0  1900.0  2200.0  2400.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2400.0  3000.0  3100.0
+1800.0  1900.0  2400.0  2500.0  3000.0  3100.0
+1500.0  2200.0  2500.0  2700.0  3300.0  3400.0
+1900.0  2500.0  2700.0  3000.0  3300.0  3400.0
+1400.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1400.0  1800.0  2100.0  2500.0  3000.0  3100.0
+1200.0  1500.0  1600.0  2600.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2300.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2200.0  3100.0  3200.0
+1200.0  1500.0  1600.0  2200.0  3100.0  3200.0
+1200.0  1500.0  1600.0  2300.0  3000.0  3100.0
+1300.0  1800.0  2400.0  2600.0  3000.0  3200.0
+1300.0  1800.0  2200.0  2400.0  3100.0  3300.0
+1400.0  1800.0  2200.0  2400.0  3100.0  3300.0
+1600.0  1700.0  2100.0  2300.0  2700.0  3100.0
+1700.0  1800.0  2100.0  2300.0  2700.0  3200.0
+1700.0  1800.0  2200.0  2300.0  2800.0  3200.0
+1700.0  2200.0  2400.0  2800.0  3100.0  3200.0
+1100.0  2000.0  2200.0  2400.0  3000.0  3100.0
+1100.0  1900.0  2000.0  2400.0  3000.0  3100.0
+1300.0  1500.0  1600.0  2700.0  3200.0  3300.0
+1300.0  1500.0  1600.0  2600.0  3300.0  3400.0
+1600.0  1700.0  2000.0  2600.0  3100.0  3200.0
+1700.0  2200.0  2500.0  2700.0  2900.0  3200.0
+1100.0  1700.0  2200.0  2300.0  3100.0  3200.0
+1100.0  1800.0  2100.0  2200.0  3100.0  3200.0
+1100.0  1600.0  2000.0  2100.0  3100.0  3200.0
+1100.0  1600.0  1900.0  2100.0  3100.0  3200.0
+1200.0  1600.0  1800.0  2000.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2000.0  3100.0  3200.0
+1300.0  1600.0  1700.0  2000.0  3000.0  3100.0
+1200.0  1500.0  1600.0  2000.0  3000.0  3100.0
+1500.0  1700.0  1900.0  2400.0  2800.0  2900.0
+1600.0  2000.0  2300.0  2600.0  2900.0  3100.0
+2200.0  2400.0  2700.0  2800.0  3100.0  3300.0
+1700.0  2100.0  2300.0  2400.0  2800.0  3200.0
+1600.0  1800.0  2300.0  2400.0  2800.0  3200.0
+1000.0  2000.0  2600.0  2700.0  3200.0  3300.0
+1000.0  1900.0  2800.0  2900.0  3300.0  3400.0
+1400.0  1600.0  1800.0  2400.0  2700.0  3000.0
+1800.0  2000.0  2300.0  2500.0  2900.0  3100.0
+1200.0  1800.0  2600.0  2700.0  3200.0  3300.0
+1300.0  1800.0  2400.0  2500.0  3000.0  3300.0
+1500.0  1900.0  2500.0  2700.0  3200.0  3400.0
+1400.0  1800.0  2500.0  2600.0  3100.0  3300.0
+1600.0  1800.0  2200.0  2300.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2400.0  2700.0  3100.0
+1700.0  1900.0  2200.0  2500.0  2700.0  3100.0
+1300.0  1400.0  2200.0  2800.0  3100.0  3200.0
+1700.0  2100.0  2300.0  2500.0  2800.0  3100.0
+1500.0  1600.0  2200.0  2700.0  2900.0  3100.0
+1200.0  1400.0  2200.0  2800.0  3000.0  3200.0
+1200.0  1400.0  2300.0  2800.0  3100.0  3200.0
+1900.0  2000.0  2600.0  2800.0  3100.0  3300.0
+1900.0  2100.0  2500.0  2800.0  3000.0  3300.0
+2100.0  2300.0  2500.0  2700.0  2900.0  3200.0
+1900.0  2000.0  2700.0  2900.0  3100.0  3400.0
+1900.0  2000.0  2600.0  2900.0  3200.0  3300.0
+1900.0  2000.0  2600.0  2900.0  3200.0  3400.0
+900.0  1500.0  2500.0  2600.0  3200.0  3400.0
+1800.0  1900.0  2400.0  2800.0  2900.0  3100.0
+1600.0  1900.0  2300.0  2600.0  2900.0  3100.0
+1400.0  1500.0  2000.0  2400.0  2900.0  3100.0
+1500.0  1800.0  2200.0  2400.0  2600.0  2800.0
+2000.0  2400.0  2800.0  2900.0  3100.0  3400.0
+1900.0  2300.0  2800.0  2900.0  3100.0  3300.0
+1200.0  1400.0  1900.0  2600.0  3100.0  3200.0
+2100.0  2300.0  2800.0  2900.0  3100.0  3200.0
+2000.0  2400.0  2600.0  2700.0  3100.0  3300.0
+2000.0  2400.0  2600.0  2700.0  3000.0  3200.0
+2000.0  2300.0  2600.0  2700.0  2900.0  3200.0
+1800.0  1900.0  2300.0  2600.0  2800.0  3000.0
+2000.0  2300.0  2500.0  2800.0  3000.0  3200.0
+1700.0  2000.0  2200.0  2600.0  2800.0  3000.0
+1900.0  2000.0  2400.0  2800.0  2900.0  3100.0
+2200.0  2600.0  2800.0  2900.0  3200.0  3400.0
+1600.0  1700.0  2200.0  2400.0  2700.0  3200.0
+1500.0  1600.0  2300.0  2400.0  2700.0  3200.0
+1300.0  1500.0  2200.0  2500.0  2700.0  3100.0
+1700.0  1800.0  2100.0  2200.0  2700.0  3200.0
+1900.0  2000.0  2600.0  2900.0  3000.0  3200.0
+1800.0  2100.0  2400.0  2500.0  2800.0  3100.0
+1400.0  1500.0  2200.0  2500.0  2700.0  3100.0
+1500.0  1600.0  2200.0  2400.0  2700.0  3100.0
+1700.0  1800.0  2300.0  2400.0  2700.0  3100.0
+1900.0  2000.0  2300.0  2500.0  2700.0  3100.0
+1900.0  2200.0  2400.0  2700.0  2800.0  3100.0
+1600.0  1700.0  2200.0  2600.0  2700.0  3100.0
+2100.0  2400.0  2600.0  2800.0  3000.0  3200.0
+2100.0  2300.0  2700.0  2800.0  3200.0  3400.0
+1800.0  2300.0  2600.0  2800.0  3000.0  3200.0
+2000.0  2200.0  2400.0  2700.0  3000.0  3300.0
+1900.0  2200.0  2400.0  2600.0  3000.0  3300.0
+1700.0  2000.0  2300.0  2600.0  2800.0  3000.0
+1600.0  1800.0  2100.0  2500.0  2700.0  3000.0
+1600.0  1700.0  2300.0  2600.0  2800.0  3000.0
+1600.0  1700.0  2400.0  2600.0  2800.0  3000.0
+2000.0  2300.0  2600.0  2700.0  3300.0  3400.0
+1700.0  1800.0  2100.0  2500.0  3000.0  3300.0
+1300.0  1500.0  2300.0  2400.0  3000.0  3300.0
+1500.0  1600.0  1900.0  2100.0  3000.0  3100.0
+1900.0  2000.0  2500.0  2800.0  3100.0  3200.0
+2000.0  2400.0  2900.0  3000.0  3200.0  3400.0
+1700.0  1800.0  2100.0  2500.0  2700.0  3100.0
+1500.0  2000.0  2400.0  2500.0  3000.0  3300.0
+1500.0  1600.0  2300.0  2400.0  2700.0  3100.0
+1600.0  1700.0  2300.0  2400.0  2700.0  3200.0
+1700.0  1800.0  2200.0  2500.0  2600.0  3000.0
+1800.0  1900.0  2200.0  2500.0  2700.0  3000.0
+1800.0  1900.0  2200.0  2600.0  2700.0  3000.0
+1800.0  2200.0  2500.0  2700.0  2900.0  3200.0
+1200.0  1600.0  2500.0  2600.0  3000.0  3300.0
+1000.0  1300.0  2400.0  2900.0  3100.0  3200.0
+1300.0  1600.0  2500.0  2800.0  3000.0  3200.0
+1800.0  2100.0  2600.0  2800.0  3000.0  3300.0
+1300.0  1600.0  2500.0  2800.0  2900.0  3200.0
+1200.0  1500.0  2300.0  2700.0  2900.0  3200.0
+1200.0  1400.0  2300.0  2700.0  2900.0  3200.0
+1400.0  1600.0  2100.0  2500.0  3100.0  3300.0
+1700.0  2300.0  2600.0  2800.0  3100.0  3200.0
+2000.0  2200.0  2400.0  2700.0  2800.0  3100.0
+1400.0  1500.0  2300.0  2800.0  3000.0  3100.0
+1500.0  1600.0  2300.0  2800.0  2900.0  3100.0
+1500.0  1600.0  2400.0  2800.0  2900.0  3100.0
+1700.0  1800.0  2200.0  2700.0  2800.0  3000.0
+1800.0  1900.0  2600.0  2700.0  2900.0  3200.0
+1800.0  2000.0  2700.0  2800.0  3200.0  3400.0
+1800.0  2000.0  2600.0  2800.0  3000.0  3300.0
+1700.0  1800.0  2400.0  2600.0  2900.0  3100.0
+2000.0  2200.0  2500.0  2600.0  3000.0  3100.0
+2000.0  2100.0  2500.0  2900.0  3200.0  3300.0
+1800.0  2000.0  2600.0  2900.0  3100.0  3300.0
+1700.0  1900.0  2200.0  2700.0  2800.0  3000.0
+1700.0  2000.0  2500.0  2600.0  3200.0  3300.0
+1400.0  1600.0  2300.0  2500.0  2700.0  3100.0
+1900.0  2300.0  2800.0  3000.0  3400.0  3500.0
+1600.0  1800.0  2300.0  2400.0  2800.0  3300.0
+1600.0  1700.0  2200.0  2400.0  2800.0  3000.0
+1600.0  1700.0  2300.0  2600.0  3000.0  3100.0
+1800.0  2100.0  2700.0  2900.0  3300.0  3500.0
+1600.0  1700.0  2300.0  2800.0  2900.0  3100.0
+1300.0  1500.0  2200.0  2700.0  2900.0  3100.0
+1200.0  1400.0  2500.0  2900.0  3000.0  3200.0
+1900.0  2200.0  2400.0  2700.0  3200.0  3400.0
+1800.0  2000.0  2600.0  2900.0  3100.0  3400.0
+1600.0  1700.0  2100.0  2600.0  2700.0  3100.0
+1500.0  1600.0  2300.0  2500.0  2700.0  3100.0
+1500.0  1600.0  2200.0  2800.0  3100.0  3300.0
+1300.0  1500.0  2000.0  2700.0  3100.0  3200.0
+1300.0  1500.0  1900.0  2600.0  3200.0  3300.0
+1300.0  1400.0  2000.0  2400.0  3200.0  3300.0
+1300.0  1400.0  2000.0  2300.0  3100.0  3300.0
+1300.0  1500.0  2000.0  2300.0  3100.0  3200.0
+1800.0  2000.0  2200.0  2400.0  3100.0  3300.0
+1700.0  1900.0  2300.0  2400.0  2800.0  3300.0
+1200.0  2200.0  2500.0  2700.0  3200.0  3300.0
+1300.0  2100.0  2300.0  2700.0  3200.0  3300.0
+1400.0  2200.0  2400.0  2900.0  3300.0  3400.0
+1500.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1200.0  1900.0  2400.0  2500.0  3000.0  3200.0
+1200.0  2000.0  2400.0  2600.0  3000.0  3200.0
+1200.0  1900.0  2400.0  2500.0  3200.0  3300.0
+2000.0  2300.0  2700.0  3000.0  3200.0  3400.0
+1900.0  2100.0  2600.0  3000.0  3300.0  3400.0
+1500.0  1900.0  2200.0  2600.0  3000.0  3300.0
+1400.0  1800.0  2200.0  2500.0  3000.0  3300.0
+1800.0  2000.0  2300.0  2400.0  3300.0  3400.0
+1600.0  2100.0  2300.0  2400.0  3100.0  3300.0
+1900.0  2300.0  2800.0  3000.0  3200.0  3400.0
+1700.0  2100.0  2400.0  2700.0  3100.0  3400.0
+1400.0  1800.0  2300.0  2600.0  3200.0  3400.0
+1700.0  2000.0  2200.0  2400.0  3100.0  3200.0
+1500.0  1800.0  2200.0  2500.0  3000.0  3300.0
+1700.0  1900.0  2200.0  2600.0  2900.0  3200.0
+1400.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1500.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1600.0  2100.0  2300.0  2700.0  3100.0  3200.0
+1600.0  1700.0  1900.0  2800.0  3000.0  3100.0
+1500.0  1700.0  1900.0  2600.0  3000.0  3100.0
+1500.0  1600.0  2100.0  2600.0  3200.0  3300.0
+2200.0  2300.0  2600.0  2900.0  3100.0  3300.0
+1900.0  2200.0  2400.0  2700.0  3000.0  3300.0
+1400.0  1700.0  2300.0  2400.0  3000.0  3100.0
+1900.0  2000.0  2400.0  2500.0  3100.0  3200.0
+2000.0  2500.0  2600.0  2800.0  3300.0  3400.0
+2000.0  2400.0  2600.0  3000.0  3200.0  3300.0
+1500.0  1800.0  2300.0  2500.0  2900.0  3200.0
+1300.0  1900.0  2200.0  2300.0  3000.0  3200.0
+1600.0  1700.0  2500.0  2800.0  3200.0  3400.0
+1500.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1900.0  2200.0  2500.0  2700.0  3000.0  3300.0
+1300.0  1600.0  1800.0  2100.0  3000.0  3100.0
+1000.0  1900.0  2200.0  2500.0  3100.0  3200.0
+1200.0  2000.0  2300.0  2600.0  3300.0  3400.0
+1400.0  1600.0  1800.0  2600.0  2900.0  3100.0
+1400.0  1700.0  2000.0  2600.0  3100.0  3200.0
+1300.0  1800.0  2000.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2300.0  2400.0  2700.0  3100.0
+1700.0  1800.0  2000.0  2400.0  3100.0  3200.0
+1800.0  1900.0  2100.0  2500.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2500.0  2800.0  3100.0
+1600.0  1800.0  2100.0  2400.0  2700.0  2800.0
+1300.0  1700.0  2100.0  2200.0  3100.0  3300.0
+1300.0  1700.0  2100.0  2200.0  3000.0  3200.0
+1500.0  1800.0  2200.0  2400.0  2700.0  3200.0
+1600.0  1800.0  2200.0  2300.0  2900.0  3200.0
+1500.0  1800.0  2100.0  2400.0  2900.0  3200.0
+1400.0  1700.0  1900.0  2200.0  2800.0  2900.0
+1500.0  1800.0  2100.0  2500.0  3000.0  3100.0
+1500.0  1900.0  2100.0  2500.0  3000.0  3100.0
+1500.0  2000.0  2200.0  2700.0  3200.0  3300.0
+1400.0  1800.0  2200.0  2500.0  3200.0  3300.0
+1500.0  2000.0  2200.0  2400.0  2900.0  3200.0
+1800.0  2000.0  2700.0  2900.0  3300.0  3400.0
+1500.0  1800.0  2100.0  2500.0  3200.0  3300.0
+1400.0  1700.0  1800.0  2200.0  3100.0  3200.0
+1400.0  1600.0  1700.0  2300.0  3000.0  3100.0
+1300.0  2000.0  2100.0  2700.0  3100.0  3200.0
+1400.0  1800.0  2200.0  2500.0  3100.0  3200.0
+1400.0  1700.0  1800.0  2300.0  3000.0  3100.0
+1600.0  1700.0  1900.0  2600.0  3000.0  3100.0
+1800.0  2100.0  2300.0  2700.0  3300.0  3400.0
+1700.0  2100.0  2300.0  2700.0  3300.0  3400.0
+1800.0  2100.0  2300.0  2400.0  2700.0  3100.0
+1500.0  1700.0  1900.0  2600.0  3100.0  3200.0
+1300.0  2000.0  2200.0  2800.0  3200.0  3300.0
+1700.0  1900.0  2600.0  2900.0  3200.0  3400.0
+1200.0  1800.0  2600.0  2700.0  3100.0  3200.0
+1900.0  2000.0  2200.0  2500.0  3200.0  3400.0
+1300.0  1700.0  2300.0  2400.0  2900.0  3200.0
+1200.0  1600.0  2200.0  2400.0  2800.0  3100.0
+1200.0  1800.0  2200.0  2600.0  3200.0  3300.0
+1300.0  1800.0  2300.0  2700.0  3300.0  3400.0
+1700.0  2000.0  2400.0  2500.0  3000.0  3200.0
+1600.0  1900.0  2200.0  2300.0  2900.0  3100.0
+1400.0  1700.0  1900.0  2400.0  3000.0  3100.0
+1600.0  1900.0  2400.0  2700.0  3300.0  3400.0
+1800.0  2300.0  2700.0  3000.0  3200.0  3400.0
+1300.0  1700.0  2300.0  2600.0  3000.0  3300.0
+1200.0  1800.0  2200.0  2600.0  3100.0  3300.0
+1700.0  2000.0  2400.0  2800.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2400.0  2600.0  3000.0
+1600.0  1700.0  2100.0  2400.0  2600.0  3000.0
+1700.0  1900.0  2200.0  2400.0  2800.0  3200.0
+1700.0  2100.0  2300.0  2700.0  2800.0  3000.0
+1600.0  1900.0  2100.0  2600.0  2900.0  3000.0
+1800.0  2000.0  2700.0  2800.0  3100.0  3400.0
+1500.0  1600.0  2200.0  2800.0  3000.0  3100.0
+1300.0  1500.0  2100.0  2700.0  3000.0  3100.0
+1500.0  1800.0  2300.0  2600.0  3000.0  3100.0
+1600.0  1700.0  2300.0  2700.0  2900.0  3000.0
+1600.0  1800.0  2200.0  2600.0  2800.0  3100.0
+1500.0  1600.0  2300.0  2600.0  2900.0  3100.0
+1600.0  1800.0  2200.0  2700.0  3000.0  3300.0
+2100.0  2200.0  2600.0  2700.0  2900.0  3100.0
+1800.0  1900.0  2300.0  2700.0  2800.0  3000.0
+1800.0  1900.0  2200.0  2700.0  2800.0  3000.0
+1500.0  1800.0  2000.0  2600.0  3000.0  3100.0
+1500.0  1700.0  2100.0  2500.0  2700.0  3000.0
+1500.0  1600.0  1900.0  2000.0  2400.0  3100.0
+1200.0  1500.0  2100.0  2200.0  2700.0  3200.0
+1300.0  1700.0  2400.0  2700.0  3000.0  3200.0
+1600.0  1700.0  2400.0  2800.0  2900.0  3200.0
+1500.0  1800.0  2000.0  2500.0  2900.0  3200.0
+1800.0  2000.0  2200.0  2500.0  2700.0  3000.0
+1800.0  1900.0  2300.0  2600.0  2700.0  3200.0
+1500.0  1700.0  2200.0  2700.0  2900.0  3200.0
+1300.0  1400.0  2100.0  2600.0  3000.0  3200.0
+1400.0  1500.0  2100.0  2700.0  3000.0  3200.0
+1500.0  1600.0  2300.0  2800.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2600.0  2900.0  3300.0
+1600.0  1700.0  2100.0  2400.0  2900.0  3300.0
+1500.0  1600.0  1900.0  2100.0  2500.0  3100.0
+1700.0  1900.0  2100.0  2400.0  2700.0  3100.0
+1400.0  1500.0  2100.0  2800.0  3100.0  3200.0
+1400.0  1600.0  2100.0  2800.0  3000.0  3200.0
+1700.0  1800.0  2100.0  2700.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2600.0  2700.0  3000.0
+1500.0  1600.0  2100.0  2600.0  2700.0  3100.0
+1600.0  1700.0  2000.0  2500.0  2900.0  3200.0
+1900.0  2000.0  2300.0  2400.0  2700.0  3100.0
+1900.0  2100.0  2300.0  2500.0  2700.0  3100.0
+1900.0  2100.0  2400.0  2600.0  2800.0  3100.0
+1700.0  2200.0  2400.0  2700.0  3100.0  3200.0
+1600.0  2000.0  2600.0  2900.0  3200.0  3300.0
+2000.0  2100.0  2300.0  2500.0  2800.0  3100.0
+1800.0  1900.0  2200.0  2400.0  2800.0  3200.0
+1900.0  2100.0  2700.0  2900.0  3200.0  3400.0
+1800.0  2100.0  2300.0  2800.0  2900.0  3100.0
+1800.0  2000.0  2200.0  2700.0  2900.0  3000.0
+1800.0  1900.0  2200.0  2700.0  2900.0  3000.0
+2100.0  2200.0  2600.0  2800.0  3000.0  3200.0
+1600.0  1700.0  2100.0  2400.0  2700.0  3100.0
+1800.0  2000.0  2200.0  2300.0  2600.0  3100.0
+1700.0  1900.0  2300.0  2600.0  2700.0  3000.0
+1800.0  2000.0  2300.0  2500.0  2900.0  3200.0
+1200.0  1400.0  2300.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2300.0  2800.0  3000.0  3200.0
+1600.0  1800.0  2300.0  2700.0  3000.0  3100.0
+1700.0  1800.0  2300.0  2700.0  2900.0  3000.0
+1400.0  1500.0  2000.0  2200.0  2900.0  3200.0
+2000.0  2300.0  2400.0  2700.0  2900.0  3100.0
+1400.0  2100.0  2400.0  2800.0  3100.0  3200.0
+1500.0  1600.0  1900.0  2100.0  2900.0  3200.0
+1500.0  1700.0  2400.0  2600.0  3000.0  3200.0
+1300.0  1500.0  2300.0  2700.0  3100.0  3300.0
+1600.0  2100.0  2300.0  2600.0  3000.0  3200.0
+1900.0  2300.0  2400.0  2700.0  3000.0  3100.0
+1700.0  2300.0  2600.0  2900.0  3200.0  3300.0
+1700.0  2000.0  2200.0  2600.0  2800.0  3100.0
+1800.0  1900.0  2200.0  2600.0  2800.0  3100.0
+2000.0  2100.0  2500.0  2800.0  3000.0  3300.0
+2000.0  2100.0  2700.0  2900.0  3100.0  3300.0
+2100.0  2300.0  2800.0  2900.0  3100.0  3300.0
+1800.0  1900.0  2100.0  2500.0  2800.0  3200.0
+1700.0  1800.0  2200.0  2500.0  2700.0  3000.0
+1500.0  1700.0  2100.0  2500.0  2800.0  3100.0
+1800.0  2100.0  2400.0  2900.0  3200.0  3300.0
+1800.0  2100.0  2700.0  2900.0  3100.0  3300.0
+1700.0  2000.0  2200.0  2500.0  2800.0  3100.0
+1300.0  1900.0  2200.0  2600.0  2800.0  3000.0
+1400.0  1900.0  2300.0  2700.0  2900.0  3200.0
+1800.0  2200.0  2500.0  2800.0  3000.0  3100.0
+1800.0  2300.0  2600.0  2700.0  3000.0  3200.0
+1500.0  1700.0  2200.0  2500.0  2800.0  3100.0
+1500.0  1700.0  2100.0  2600.0  2800.0  3100.0
+1400.0  1500.0  1900.0  2700.0  3100.0  3200.0
+2000.0  2500.0  2900.0  3100.0  3300.0  3400.0
+1200.0  1800.0  2400.0  2700.0  3100.0  3300.0
+1700.0  1900.0  2100.0  2500.0  2700.0  3100.0
+1500.0  2300.0  2500.0  2700.0  2900.0  3100.0
+1700.0  1800.0  2200.0  2600.0  2700.0  3000.0
+1800.0  1900.0  2300.0  2500.0  2700.0  3100.0
+1900.0  2000.0  2300.0  2600.0  3000.0  3300.0
+1400.0  1600.0  2200.0  2600.0  2800.0  3200.0
+1400.0  1700.0  2300.0  2600.0  3000.0  3100.0
+1500.0  1700.0  2100.0  2500.0  2800.0  3200.0
+2200.0  2600.0  2900.0  3100.0  3400.0  3500.0
+2200.0  2500.0  2900.0  3100.0  3300.0  3500.0
+1800.0  2100.0  2400.0  2900.0  3100.0  3300.0
+1600.0  1800.0  2300.0  2600.0  2900.0  3100.0
+1200.0  1400.0  2200.0  2400.0  3000.0  3200.0
+1300.0  1700.0  2100.0  2400.0  2900.0  3100.0
+1600.0  1700.0  2100.0  2200.0  3000.0  3200.0
+1500.0  1600.0  2500.0  2800.0  3100.0  3300.0
+1400.0  1600.0  2300.0  2700.0  3000.0  3300.0
+1400.0  1600.0  2200.0  2500.0  2900.0  3100.0
+1300.0  1600.0  2300.0  2600.0  3100.0  3300.0
+1600.0  1700.0  2200.0  2400.0  2900.0  3200.0
+1700.0  1800.0  2100.0  2300.0  3000.0  3300.0
+1300.0  1400.0  2300.0  2600.0  2900.0  3200.0
+1300.0  1500.0  2300.0  2500.0  2900.0  3200.0
+1800.0  1900.0  2200.0  2400.0  2700.0  3100.0
+1800.0  1900.0  2200.0  2400.0  2800.0  3100.0
+1600.0  1700.0  2200.0  2400.0  2700.0  3100.0
+1400.0  1600.0  2200.0  2500.0  3000.0  3300.0
+1500.0  1700.0  2200.0  2400.0  3000.0  3400.0
+1600.0  1700.0  2200.0  2500.0  2700.0  3200.0
+1700.0  1800.0  2100.0  2200.0  2800.0  3200.0
+1600.0  1700.0  2100.0  2200.0  3100.0  3300.0
+1500.0  1600.0  2100.0  2200.0  3100.0  3300.0
+1000.0  1800.0  2200.0  2500.0  3100.0  3300.0
+1100.0  1700.0  2200.0  2500.0  3000.0  3200.0
+1400.0  1800.0  2100.0  2400.0  2800.0  3000.0
+1500.0  1800.0  2500.0  2700.0  3000.0  3200.0
+1900.0  2500.0  2800.0  3000.0  3400.0  3500.0
+2000.0  2500.0  2900.0  3200.0  3400.0  3500.0
+1400.0  1700.0  2300.0  2500.0  3000.0  3300.0
+1400.0  1900.0  2300.0  2500.0  3000.0  3200.0
+1400.0  2000.0  2300.0  2600.0  2900.0  3100.0
+1400.0  1900.0  2200.0  2500.0  2700.0  3100.0
+1600.0  1800.0  2000.0  2400.0  3000.0  3200.0
+1300.0  1800.0  2400.0  2700.0  3100.0  3300.0
+1400.0  1600.0  2400.0  2600.0  3100.0  3200.0
+1400.0  1500.0  1600.0  2400.0  3200.0  3300.0
+1900.0  2300.0  2600.0  2900.0  3100.0  3200.0
+1100.0  1700.0  2500.0  2600.0  3100.0  3300.0
+1300.0  1700.0  2400.0  2500.0  3000.0  3300.0
+1400.0  1700.0  2400.0  2500.0  3000.0  3400.0
+1400.0  1600.0  2400.0  2500.0  2900.0  3400.0
+1400.0  1700.0  2400.0  2500.0  3100.0  3400.0
+1500.0  1600.0  2300.0  2600.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2400.0  3000.0  3200.0
+1600.0  1800.0  2200.0  2300.0  3000.0  3100.0
+1500.0  1900.0  2400.0  2700.0  3000.0  3200.0
+1300.0  1800.0  2400.0  2700.0  3300.0  3400.0
+1400.0  1700.0  2200.0  2500.0  2900.0  3200.0
+1800.0  2100.0  2500.0  2700.0  3100.0  3400.0
+1000.0  1500.0  1800.0  2200.0  3000.0  3100.0
+2100.0  2600.0  2900.0  3100.0  3300.0  3400.0
+1900.0  2000.0  2200.0  2500.0  3100.0  3300.0
+1700.0  1900.0  2300.0  2600.0  2900.0  3300.0
+1600.0  1800.0  2000.0  2200.0  3100.0  3300.0
+1300.0  1700.0  2300.0  2600.0  3100.0  3200.0
+1400.0  2100.0  2400.0  2700.0  3100.0  3300.0
+1200.0  1500.0  2200.0  2600.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2500.0  3000.0  3100.0
+1600.0  1900.0  2300.0  2500.0  3000.0  3100.0
+1500.0  1800.0  2600.0  2800.0  3200.0  3400.0
+1600.0  1700.0  2300.0  2500.0  3100.0  3400.0
+1500.0  1600.0  2300.0  2600.0  3100.0  3400.0
+1200.0  1500.0  2500.0  2600.0  3100.0  3400.0
+1200.0  1500.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1600.0  2500.0  2600.0  3100.0  3300.0
+1900.0  2300.0  2600.0  2900.0  3400.0  3500.0
+900.0  1500.0  2600.0  2700.0  3100.0  3200.0
+2100.0  2500.0  2900.0  3100.0  3300.0  3400.0
+1400.0  2100.0  2300.0  2500.0  3000.0  3300.0
+1200.0  1600.0  1700.0  2300.0  3100.0  3200.0
+1100.0  1800.0  2200.0  2600.0  3000.0  3200.0
+1500.0  2000.0  2400.0  2700.0  3100.0  3200.0
+2000.0  2100.0  2400.0  2600.0  2900.0  3300.0
+1400.0  2100.0  2500.0  2700.0  3100.0  3200.0
+1200.0  1600.0  2300.0  2500.0  3000.0  3200.0
+1500.0  1600.0  2300.0  2500.0  3100.0  3200.0
+2300.0  2500.0  2700.0  2800.0  3100.0  3300.0
+2200.0  2300.0  2500.0  2700.0  3100.0  3200.0
+1300.0  1900.0  2300.0  2500.0  2800.0  3000.0
+1200.0  1800.0  2300.0  2500.0  3000.0  3300.0
+1400.0  1600.0  2400.0  2600.0  3200.0  3400.0
+1500.0  1600.0  2300.0  2500.0  3100.0  3400.0
+1400.0  1900.0  2400.0  2500.0  2700.0  3100.0
+1200.0  1600.0  2200.0  2600.0  3100.0  3300.0
+1300.0  1600.0  2300.0  2600.0  3100.0  3400.0
+1500.0  1600.0  2200.0  2500.0  3100.0  3400.0
+1600.0  2000.0  2500.0  2700.0  3000.0  3200.0
+1600.0  1700.0  2000.0  2300.0  3000.0  3200.0
+1400.0  1700.0  1800.0  2300.0  3100.0  3200.0
+2100.0  2200.0  2400.0  2600.0  3200.0  3300.0
+1600.0  1900.0  2400.0  2500.0  2700.0  3200.0
+2200.0  2300.0  2500.0  2700.0  3100.0  3300.0
+2200.0  2300.0  2600.0  2700.0  3100.0  3300.0
+1400.0  1800.0  2300.0  2500.0  2800.0  3200.0
+1600.0  1800.0  2300.0  2500.0  2700.0  3100.0
+1400.0  1600.0  1800.0  2500.0  2900.0  3000.0
+1400.0  1600.0  1900.0  2600.0  3000.0  3200.0
+1500.0  1700.0  2000.0  2600.0  3000.0  3200.0
+1400.0  1700.0  2400.0  2500.0  3100.0  3300.0
+2300.0  2400.0  2700.0  3000.0  3200.0  3400.0
+1300.0  1700.0  2100.0  2300.0  3100.0  3200.0
+1300.0  1700.0  2100.0  2300.0  3000.0  3100.0
+1300.0  1700.0  2000.0  2200.0  3000.0  3100.0
+1400.0  1700.0  1900.0  2300.0  3000.0  3100.0
+1400.0  1600.0  1800.0  2300.0  2900.0  3000.0
+1300.0  1800.0  2400.0  2600.0  3000.0  3300.0
+2200.0  2300.0  2500.0  2800.0  3000.0  3200.0
+1900.0  2200.0  2400.0  2600.0  2900.0  3300.0
+1900.0  2100.0  2400.0  2600.0  3200.0  3400.0
+1900.0  2400.0  2600.0  2800.0  3200.0  3400.0
+1800.0  2100.0  2500.0  2600.0  3200.0  3400.0
+1500.0  1900.0  2400.0  2600.0  2900.0  3100.0
+1200.0  1600.0  2300.0  2500.0  3200.0  3300.0
+1100.0  1400.0  2300.0  2400.0  3000.0  3300.0
+1000.0  1800.0  2400.0  2500.0  3300.0  3400.0
+1000.0  1700.0  2400.0  2500.0  3300.0  3400.0
+2000.0  2400.0  2800.0  3000.0  3300.0  3500.0
+1400.0  2100.0  2500.0  2700.0  3300.0  3400.0
+1200.0  1900.0  2500.0  2600.0  3200.0  3300.0
+1400.0  2000.0  2500.0  2600.0  3100.0  3300.0
+1800.0  2200.0  2700.0  3000.0  3300.0  3500.0
+1700.0  2200.0  2400.0  2700.0  3100.0  3300.0
+1000.0  2000.0  2300.0  2400.0  3300.0  3400.0
+1400.0  1900.0  2400.0  2600.0  3300.0  3400.0
+1300.0  1800.0  2400.0  2500.0  3100.0  3300.0
+1600.0  2000.0  2500.0  2600.0  3200.0  3300.0
+2100.0  2500.0  2700.0  3000.0  3200.0  3400.0
+1600.0  2000.0  2300.0  2400.0  3200.0  3300.0
+1400.0  1700.0  1900.0  2100.0  3300.0  3400.0
+1500.0  1700.0  2000.0  2200.0  3200.0  3300.0
+1500.0  1800.0  2200.0  2300.0  2600.0  2900.0
+1600.0  1700.0  2300.0  2500.0  2800.0  3000.0
+1600.0  1700.0  2200.0  2300.0  2900.0  3200.0
+1300.0  1500.0  2300.0  2400.0  2800.0  3200.0
+1400.0  1700.0  2300.0  2400.0  3000.0  3200.0
+1600.0  1700.0  2100.0  2300.0  2900.0  3300.0
+1500.0  2100.0  2300.0  2600.0  3100.0  3300.0
+1100.0  1500.0  2200.0  2300.0  3100.0  3300.0
+1000.0  1800.0  2300.0  2400.0  3100.0  3200.0
+900.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1000.0  1800.0  2400.0  2500.0  3100.0  3200.0
+1700.0  2200.0  2500.0  2900.0  3400.0  3500.0
+1300.0  1900.0  2300.0  2400.0  3300.0  3400.0
+1100.0  1900.0  2300.0  2400.0  3200.0  3300.0
+1200.0  1700.0  2300.0  2400.0  3200.0  3400.0
+1300.0  1700.0  2300.0  2500.0  3200.0  3300.0
+1200.0  1500.0  2200.0  2300.0  3000.0  3200.0
+1200.0  1800.0  2200.0  2300.0  3000.0  3200.0
+1000.0  1800.0  2400.0  2500.0  3100.0  3300.0
+900.0  1800.0  2600.0  2700.0  3300.0  3400.0
+900.0  1900.0  2700.0  2800.0  3300.0  3400.0
+1800.0  2400.0  2700.0  3100.0  3400.0  3500.0
+1400.0  1600.0  2200.0  2400.0  2900.0  3200.0
+1700.0  2300.0  2500.0  2700.0  3300.0  3400.0
+1400.0  1900.0  2400.0  2600.0  3200.0  3400.0
+1300.0  1500.0  2200.0  2400.0  2700.0  3100.0
+1500.0  1600.0  2000.0  2200.0  2900.0  3100.0
+1500.0  1600.0  1800.0  1900.0  2800.0  3300.0
+1700.0  1800.0  2000.0  2300.0  3000.0  3300.0
+2200.0  2400.0  2600.0  2700.0  3300.0  3400.0
+1700.0  1900.0  2300.0  2400.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2400.0  2700.0  3100.0
+1700.0  2300.0  2600.0  3000.0  3300.0  3400.0
+2200.0  2300.0  2500.0  2700.0  3100.0  3400.0
+1600.0  1800.0  2000.0  2200.0  3200.0  3300.0
+2100.0  2500.0  2700.0  2900.0  3400.0  3500.0
+2100.0  2400.0  2600.0  2700.0  3100.0  3300.0
+2100.0  2400.0  2700.0  3100.0  3300.0  3400.0
+1400.0  1700.0  2200.0  2600.0  2900.0  3200.0
+1000.0  1900.0  2200.0  2400.0  3100.0  3200.0
+1100.0  1600.0  2500.0  2600.0  3100.0  3300.0
+1300.0  1600.0  2200.0  2300.0  2800.0  3300.0
+1000.0  2000.0  2500.0  2600.0  3300.0  3400.0
+1700.0  2200.0  2400.0  2700.0  3200.0  3400.0
+1200.0  2000.0  2400.0  2500.0  3100.0  3200.0
+1100.0  1700.0  2100.0  2200.0  3000.0  3200.0
+1100.0  1600.0  2100.0  2200.0  3100.0  3300.0
+1100.0  1600.0  2200.0  2300.0  3200.0  3300.0
+1300.0  1700.0  2300.0  2400.0  3300.0  3400.0
+1300.0  1800.0  2300.0  2400.0  3300.0  3400.0
+1000.0  1800.0  2300.0  2400.0  3100.0  3300.0
+1400.0  2000.0  2300.0  2500.0  2900.0  3200.0
+1100.0  1900.0  2400.0  2500.0  3100.0  3200.0
+1000.0  2000.0  2600.0  2700.0  3300.0  3400.0
+1200.0  1600.0  2200.0  2300.0  3100.0  3300.0
+1300.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1000.0  1700.0  2400.0  2600.0  3300.0  3400.0
+1000.0  1700.0  2400.0  2600.0  3200.0  3300.0
+2000.0  2400.0  2700.0  3100.0  3300.0  3400.0
+1500.0  1900.0  2200.0  2400.0  3200.0  3300.0
+1400.0  1700.0  2100.0  2200.0  3100.0  3300.0
+2200.0  2400.0  2600.0  2900.0  3300.0  3400.0
+1300.0  1900.0  2100.0  2500.0  3000.0  3200.0
+1900.0  2100.0  2300.0  2400.0  3000.0  3300.0
+1100.0  2200.0  2600.0  2700.0  3300.0  3400.0
+1700.0  1900.0  2400.0  2500.0  3000.0  3400.0
+1800.0  2100.0  2600.0  2900.0  3100.0  3400.0
+1900.0  2300.0  2900.0  3100.0  3300.0  3400.0
+1900.0  2400.0  2600.0  3000.0  3300.0  3500.0
+1400.0  2100.0  2400.0  2500.0  2700.0  3000.0
+1300.0  1600.0  1900.0  2100.0  2900.0  3000.0
+1900.0  2000.0  2200.0  2300.0  3000.0  3300.0
+1300.0  1600.0  2200.0  2500.0  3000.0  3300.0
+1100.0  1800.0  2300.0  2500.0  3100.0  3300.0
+1100.0  1700.0  2300.0  2500.0  3000.0  3200.0
+1200.0  1600.0  2300.0  2400.0  3000.0  3200.0
+1300.0  1600.0  2200.0  2400.0  2900.0  3200.0
+1800.0  2300.0  2600.0  3000.0  3300.0  3500.0
+1500.0  2000.0  2400.0  2700.0  3200.0  3400.0
+1800.0  2000.0  2200.0  2500.0  2800.0  3000.0
+1800.0  2100.0  2300.0  2400.0  2700.0  3000.0
+1800.0  2100.0  2300.0  2500.0  2900.0  3200.0
+1700.0  1900.0  2100.0  2700.0  2900.0  3200.0
+1800.0  2100.0  2300.0  2600.0  2900.0  3000.0
+1600.0  1800.0  2100.0  2400.0  2600.0  2900.0
+1800.0  1900.0  2400.0  2800.0  3000.0  3100.0
+2000.0  2400.0  2700.0  2900.0  3200.0  3400.0
+1900.0  2100.0  2800.0  2900.0  3200.0  3400.0
+2000.0  2100.0  2500.0  2800.0  2900.0  3100.0
+1800.0  1900.0  2500.0  2600.0  2900.0  3300.0
+1600.0  1700.0  2000.0  2100.0  3000.0  3200.0
+1600.0  1700.0  2000.0  2100.0  2900.0  3200.0
+2000.0  2200.0  2400.0  2800.0  3100.0  3300.0
+2100.0  2300.0  2800.0  2900.0  3300.0  3400.0
+1900.0  2000.0  2300.0  2400.0  2900.0  3100.0
+1500.0  1800.0  2300.0  2500.0  3000.0  3300.0
+1200.0  1800.0  2500.0  2600.0  2900.0  3000.0
+1400.0  1700.0  2200.0  2600.0  2900.0  3000.0
+1500.0  1700.0  2200.0  2600.0  3000.0  3100.0
+1700.0  1800.0  2100.0  2400.0  2900.0  3200.0
+1800.0  1900.0  2200.0  2600.0  2900.0  3200.0
+1800.0  2000.0  2200.0  2400.0  2800.0  3100.0
+1400.0  1600.0  1900.0  2100.0  2700.0  3200.0
+1500.0  2000.0  2200.0  2500.0  3000.0  3200.0
+1700.0  1800.0  2000.0  2200.0  3100.0  3300.0
+1800.0  1900.0  2100.0  2400.0  3000.0  3100.0
+1800.0  2100.0  2400.0  2600.0  3000.0  3100.0
+2000.0  2300.0  2600.0  2800.0  3000.0  3300.0
+2100.0  2300.0  2800.0  2900.0  3200.0  3400.0
+1800.0  1900.0  2500.0  2800.0  3100.0  3200.0
+1800.0  2000.0  2200.0  2500.0  2900.0  3000.0
+1700.0  1800.0  2100.0  2700.0  2900.0  3000.0
+1700.0  1800.0  2600.0  2800.0  3100.0  3300.0
+1600.0  2000.0  2300.0  2800.0  3100.0  3300.0
+1500.0  1600.0  1900.0  2000.0  2900.0  3200.0
+2100.0  2300.0  2700.0  2800.0  3000.0  3200.0
+2000.0  2200.0  2400.0  2600.0  3100.0  3200.0
+1800.0  2100.0  2400.0  2500.0  3000.0  3200.0
+1800.0  2100.0  2500.0  2600.0  2900.0  3200.0
+2100.0  2400.0  2800.0  2900.0  3300.0  3400.0
+1800.0  2000.0  2300.0  2600.0  3100.0  3400.0
+1700.0  2000.0  2300.0  2600.0  2900.0  3300.0
+1800.0  1900.0  2300.0  2500.0  2800.0  3000.0
+1400.0  1600.0  2200.0  2500.0  2900.0  3300.0
+1600.0  1700.0  2100.0  2300.0  2600.0  3100.0
+1700.0  1800.0  2100.0  2500.0  2800.0  3200.0
+1500.0  1600.0  2200.0  2700.0  2800.0  3200.0
+2100.0  2300.0  2700.0  2800.0  3100.0  3300.0
+1600.0  1700.0  2000.0  2400.0  3000.0  3300.0
+1500.0  1600.0  2600.0  2800.0  3100.0  3300.0
+1800.0  2000.0  2400.0  2600.0  2900.0  3100.0
+1700.0  1800.0  2300.0  2500.0  2600.0  3100.0
+1500.0  1800.0  2100.0  2500.0  2900.0  3300.0
+1600.0  1800.0  2100.0  2500.0  3000.0  3300.0
+1700.0  1800.0  2300.0  2400.0  2800.0  3100.0
+1600.0  1700.0  2000.0  2300.0  2800.0  3100.0
+1700.0  1800.0  2200.0  2400.0  2700.0  3100.0
+2000.0  2500.0  2800.0  3000.0  3400.0  3500.0
+1900.0  2400.0  2800.0  2900.0  3400.0  3500.0
+1600.0  1700.0  2400.0  2700.0  2900.0  3100.0
+1600.0  1700.0  2500.0  2600.0  2900.0  3100.0
+1500.0  1700.0  2200.0  2600.0  2900.0  3100.0
+1700.0  2000.0  2200.0  2500.0  2900.0  3200.0
+1500.0  1700.0  2200.0  2700.0  3200.0  3300.0
+1400.0  1500.0  2100.0  2500.0  3000.0  3200.0
+1200.0  1500.0  2200.0  2400.0  2800.0  3200.0
+1500.0  1600.0  2000.0  2100.0  2900.0  3200.0
+1800.0  1900.0  2100.0  2500.0  2900.0  3200.0
+1500.0  1800.0  2300.0  2500.0  2800.0  3200.0
+1500.0  1800.0  2500.0  2800.0  3100.0  3300.0
+1300.0  1800.0  2500.0  2600.0  3000.0  3100.0
+1600.0  1800.0  2300.0  2700.0  2900.0  3000.0
+1500.0  1600.0  2200.0  2400.0  2600.0  3100.0
+1600.0  2000.0  2500.0  2600.0  3000.0  3300.0
+1500.0  1600.0  2000.0  2600.0  2800.0  3000.0
+1500.0  1600.0  2200.0  2600.0  2700.0  3000.0
+1200.0  1600.0  2200.0  2400.0  3000.0  3200.0
+1800.0  2300.0  2500.0  2800.0  3000.0  3100.0
+1500.0  1600.0  2500.0  2800.0  2900.0  3200.0
+1300.0  1500.0  2300.0  2800.0  3100.0  3200.0
+1700.0  1800.0  2100.0  2500.0  2800.0  3000.0
+1400.0  1800.0  2200.0  2600.0  3000.0  3200.0
+1500.0  1700.0  2000.0  2700.0  3100.0  3200.0
+1400.0  1600.0  2300.0  2600.0  3000.0  3300.0
+1700.0  2100.0  2700.0  2900.0  3300.0  3500.0
+1700.0  1800.0  2300.0  2700.0  2800.0  3100.0
+1600.0  1800.0  2200.0  2600.0  2700.0  3000.0
+1900.0  2300.0  2400.0  2600.0  2800.0  3100.0
+1300.0  1600.0  2100.0  2200.0  3100.0  3300.0
+1500.0  1800.0  2400.0  2700.0  3000.0  3100.0
+1600.0  1800.0  2000.0  2600.0  2900.0  3000.0
+1600.0  1800.0  2100.0  2700.0  2900.0  3000.0
+1600.0  1700.0  2300.0  2700.0  3000.0  3100.0
+1700.0  1800.0  2400.0  2700.0  2900.0  3100.0
+1800.0  1900.0  2500.0  2600.0  3000.0  3100.0
+1700.0  1800.0  2100.0  2400.0  2700.0  3200.0
+1700.0  2000.0  2200.0  2500.0  2800.0  3000.0
+2000.0  2400.0  2500.0  2700.0  3000.0  3100.0
+1800.0  2000.0  2600.0  2700.0  3100.0  3200.0
+2200.0  2400.0  2700.0  2900.0  3100.0  3300.0
+2300.0  2500.0  2700.0  2900.0  3100.0  3300.0
+1800.0  2200.0  2300.0  2600.0  3000.0  3100.0
+1700.0  2100.0  2300.0  2800.0  3100.0  3200.0
+2000.0  2400.0  2600.0  2800.0  3000.0  3200.0
+1500.0  2000.0  2200.0  2600.0  3100.0  3300.0
+1100.0  1600.0  2200.0  2600.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2500.0  2700.0  3000.0
+1900.0  2300.0  2400.0  2600.0  2800.0  3000.0
+1700.0  2100.0  2300.0  2600.0  2900.0  3000.0
+1600.0  1700.0  2000.0  2200.0  2600.0  3100.0
+1600.0  1900.0  2200.0  2400.0  3000.0  3100.0
+1300.0  2000.0  2300.0  2600.0  3100.0  3300.0
+1600.0  2100.0  2300.0  2600.0  2900.0  3000.0
+1700.0  2100.0  2300.0  2500.0  2800.0  3000.0
+1600.0  2100.0  2300.0  2500.0  2800.0  3000.0
+1500.0  1800.0  2000.0  2300.0  2800.0  2900.0
+1300.0  1600.0  2300.0  2600.0  2900.0  3200.0
+1200.0  1700.0  2100.0  2600.0  3100.0  3300.0
+1800.0  2200.0  2600.0  2700.0  3200.0  3300.0
+1600.0  1700.0  1900.0  2100.0  3100.0  3200.0
+1500.0  2000.0  2300.0  2500.0  3000.0  3300.0
+1600.0  1700.0  2000.0  2500.0  2700.0  2900.0
+1600.0  1800.0  2100.0  2500.0  2900.0  3000.0
+1600.0  1700.0  2100.0  2500.0  2700.0  2900.0
+1600.0  1700.0  2200.0  2500.0  2700.0  2900.0
+1500.0  1700.0  2000.0  2600.0  2800.0  3000.0
+1200.0  1600.0  2200.0  2400.0  2800.0  3000.0
+1800.0  2200.0  2400.0  2600.0  2800.0  3000.0
+1700.0  2000.0  2200.0  2500.0  2700.0  3100.0
+1700.0  2000.0  2200.0  2500.0  2700.0  3000.0
+1600.0  1900.0  2300.0  2600.0  2800.0  3200.0
+1200.0  1400.0  2000.0  2600.0  2800.0  3000.0
+1400.0  1600.0  2200.0  2600.0  3000.0  3300.0
+1500.0  1700.0  2200.0  2400.0  2700.0  2900.0
+1600.0  1700.0  2200.0  2500.0  2800.0  3000.0
+1600.0  1700.0  2100.0  2400.0  2700.0  3000.0
+1900.0  2100.0  2400.0  2600.0  3000.0  3100.0
+1900.0  2500.0  2700.0  2800.0  3100.0  3200.0
+1800.0  2200.0  2500.0  2600.0  3000.0  3200.0
+1900.0  2200.0  2400.0  2500.0  2800.0  3100.0
+1800.0  2100.0  2300.0  2500.0  2700.0  3000.0
+2000.0  2300.0  2400.0  2600.0  2900.0  3100.0
+1400.0  1600.0  1800.0  1900.0  2700.0  3200.0
+1400.0  1600.0  1700.0  1900.0  2800.0  3100.0
+2100.0  2200.0  2600.0  3000.0  3200.0  3300.0
+1700.0  2000.0  2200.0  2400.0  2700.0  2900.0
+1500.0  1600.0  1900.0  2400.0  2600.0  2700.0
+1600.0  1700.0  2000.0  2400.0  2600.0  2800.0
+1900.0  2000.0  2500.0  2800.0  2900.0  3200.0
+1500.0  1600.0  1900.0  2100.0  2700.0  3200.0
+1500.0  1700.0  2000.0  2200.0  2900.0  3300.0
+1800.0  2000.0  2700.0  2800.0  3200.0  3300.0
+1700.0  1800.0  2400.0  2700.0  3300.0  3400.0
+1600.0  1900.0  2500.0  2700.0  3300.0  3400.0
+1200.0  1800.0  2100.0  2400.0  3100.0  3200.0
+1200.0  1800.0  2100.0  2500.0  3200.0  3300.0
+1600.0  1700.0  2200.0  2600.0  2900.0  3200.0
+1800.0  2200.0  2500.0  2600.0  3200.0  3400.0
+1000.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1100.0  2000.0  2600.0  2700.0  3200.0  3300.0
+1300.0  1800.0  2500.0  2700.0  3200.0  3300.0
+1400.0  1700.0  1800.0  2400.0  3000.0  3100.0
+1500.0  1800.0  2000.0  2400.0  3100.0  3200.0
+1200.0  1400.0  1500.0  2300.0  3100.0  3200.0
+2100.0  2200.0  2500.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2100.0  2400.0  2900.0  3100.0
+1400.0  1500.0  2100.0  2400.0  2800.0  3200.0
+1100.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1200.0  2000.0  2300.0  2700.0  3100.0  3200.0
+1300.0  1700.0  2200.0  2500.0  2900.0  3000.0
+1400.0  1700.0  1900.0  2600.0  2900.0  3100.0
+1200.0  2000.0  2300.0  2700.0  3200.0  3300.0
+1500.0  2200.0  2400.0  2600.0  3200.0  3300.0
+1400.0  1800.0  2000.0  2500.0  3000.0  3100.0
+1400.0  2000.0  2300.0  2500.0  3200.0  3300.0
+1900.0  2400.0  2600.0  2700.0  3100.0  3300.0
+1300.0  1600.0  1700.0  2200.0  3000.0  3100.0
+1300.0  1600.0  2500.0  2600.0  3100.0  3300.0
+1500.0  1700.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1600.0  2400.0  2600.0  3200.0  3400.0
+1400.0  2000.0  2300.0  2500.0  2700.0  3000.0
+1500.0  1900.0  2300.0  2500.0  2700.0  3100.0
+1500.0  1600.0  1800.0  2500.0  2800.0  3000.0
+1300.0  1800.0  2200.0  2600.0  3100.0  3200.0
+1300.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1300.0  1700.0  2100.0  2400.0  3100.0  3300.0
+1300.0  1900.0  2300.0  2600.0  3000.0  3200.0
+1200.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1700.0  2200.0  2500.0  2600.0  3200.0  3400.0
+1600.0  2000.0  2200.0  2300.0  3100.0  3200.0
+1800.0  1900.0  2300.0  2600.0  3200.0  3300.0
+1800.0  1900.0  2100.0  2500.0  3200.0  3300.0
+1900.0  2000.0  2100.0  2500.0  3300.0  3400.0
+1700.0  2100.0  2600.0  2800.0  3300.0  3500.0
+1600.0  1800.0  2200.0  2700.0  3200.0  3300.0
+1400.0  2000.0  2300.0  2400.0  2600.0  3000.0
+1400.0  1600.0  2100.0  2300.0  3100.0  3200.0
+1100.0  1900.0  2500.0  2600.0  3300.0  3400.0
+1200.0  1600.0  2300.0  2600.0  3100.0  3400.0
+1400.0  1600.0  2100.0  2400.0  3000.0  3300.0
+1400.0  1700.0  2100.0  2500.0  3100.0  3300.0
+1200.0  2000.0  2700.0  2800.0  3300.0  3400.0
+1700.0  1800.0  2000.0  2300.0  3300.0  3400.0
+1300.0  1600.0  1800.0  2100.0  3100.0  3200.0
+1800.0  1900.0  2100.0  2200.0  3200.0  3400.0
+1800.0  1900.0  2100.0  2300.0  3300.0  3400.0
+1800.0  1900.0  2200.0  2300.0  3100.0  3300.0
+1800.0  2300.0  2800.0  2900.0  3200.0  3300.0
+1900.0  2200.0  2500.0  2600.0  3200.0  3300.0
+1300.0  1600.0  2300.0  2500.0  2900.0  3300.0
+1400.0  1600.0  2300.0  2500.0  2900.0  3300.0
+1400.0  1700.0  2400.0  2500.0  2900.0  3200.0
+1500.0  1700.0  2100.0  2200.0  3100.0  3200.0
+1500.0  1700.0  2100.0  2200.0  3100.0  3300.0
+1500.0  1600.0  2100.0  2300.0  2900.0  3300.0
+1300.0  1900.0  2200.0  2500.0  3000.0  3200.0
+1200.0  1900.0  2200.0  2500.0  3000.0  3200.0
+1000.0  1300.0  2100.0  2200.0  2900.0  3200.0
+1400.0  1600.0  1700.0  2000.0  3300.0  3400.0
+1300.0  1500.0  1600.0  2000.0  3300.0  3400.0
+1300.0  1500.0  1700.0  1900.0  3300.0  3400.0
+1500.0  1600.0  2100.0  2300.0  3100.0  3400.0
+1500.0  1600.0  2300.0  2500.0  2700.0  3200.0
+1400.0  2000.0  2300.0  2400.0  2700.0  3200.0
+1200.0  1500.0  2400.0  2600.0  2900.0  3200.0
+1500.0  1600.0  2300.0  2400.0  2700.0  3300.0
+1500.0  1700.0  2200.0  2400.0  2600.0  3100.0
+1500.0  1700.0  2300.0  2500.0  3100.0  3400.0
+1600.0  1700.0  2400.0  2600.0  3000.0  3400.0
+1600.0  1700.0  2500.0  2700.0  3100.0  3400.0
+1400.0  1500.0  2300.0  2400.0  3000.0  3300.0
+1500.0  1600.0  2100.0  2300.0  3000.0  3200.0
+1500.0  1600.0  2200.0  2400.0  2900.0  3200.0
+1500.0  1700.0  2400.0  2500.0  2900.0  3200.0
+1400.0  1900.0  2200.0  2300.0  2800.0  3200.0
+1500.0  1800.0  2100.0  2200.0  3000.0  3300.0
+2000.0  2100.0  2500.0  2600.0  3000.0  3400.0
+1000.0  1600.0  2200.0  2300.0  3200.0  3400.0
+1300.0  1500.0  2300.0  2600.0  2900.0  3300.0
+1400.0  1600.0  2500.0  2600.0  2900.0  3200.0
+1400.0  1600.0  2100.0  2400.0  3100.0  3300.0
+1500.0  2000.0  2300.0  2500.0  3100.0  3300.0
+1000.0  1700.0  2100.0  2200.0  3200.0  3300.0
+1500.0  1700.0  2200.0  2400.0  3200.0  3400.0
+1600.0  1800.0  2300.0  2400.0  3000.0  3100.0
+1300.0  1500.0  2100.0  2200.0  3000.0  3300.0
+1200.0  1400.0  2200.0  2300.0  3000.0  3300.0
+1600.0  1700.0  1900.0  2200.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2300.0  3000.0  3400.0
+1400.0  1500.0  2200.0  2500.0  2800.0  3100.0
+1800.0  1900.0  2300.0  2500.0  3000.0  3400.0
+1500.0  1700.0  2100.0  2500.0  2700.0  3100.0
+1600.0  1900.0  2400.0  2700.0  2900.0  3100.0
+1700.0  1800.0  2200.0  2500.0  2700.0  3300.0
+1800.0  1900.0  2400.0  2500.0  2800.0  3300.0
+1300.0  1600.0  2100.0  2300.0  3000.0  3300.0
+1300.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1100.0  1500.0  2500.0  2600.0  3100.0  3400.0
+1600.0  1700.0  2200.0  2500.0  2600.0  3100.0
+1500.0  1600.0  2200.0  2500.0  2600.0  3100.0
+1600.0  2200.0  2600.0  2800.0  3100.0  3300.0
+2000.0  2200.0  2600.0  2700.0  3300.0  3400.0
+1500.0  2000.0  2200.0  2400.0  2600.0  2900.0
+1500.0  1800.0  2200.0  2400.0  3100.0  3400.0
+1800.0  2200.0  2600.0  2800.0  3400.0  3500.0
+1600.0  1700.0  2200.0  2600.0  3200.0  3400.0
+1800.0  2000.0  2300.0  2600.0  3200.0  3400.0
+1600.0  1800.0  2200.0  2600.0  3200.0  3400.0
+1500.0  1600.0  2100.0  2400.0  2800.0  3200.0
+1500.0  1800.0  2000.0  2600.0  3200.0  3300.0
+1200.0  1800.0  1900.0  2200.0  3100.0  3200.0
+1500.0  1600.0  2200.0  2400.0  3200.0  3300.0
+1800.0  1900.0  2600.0  2800.0  3000.0  3300.0
+1300.0  1600.0  2300.0  2400.0  3000.0  3100.0
+2000.0  2100.0  2400.0  2600.0  3000.0  3100.0
+2000.0  2100.0  2500.0  2600.0  2900.0  3100.0
+1800.0  2000.0  2500.0  2600.0  3000.0  3100.0
+1800.0  2300.0  2700.0  2800.0  3400.0  3500.0
+1200.0  1900.0  2200.0  2600.0  3100.0  3200.0
+1600.0  2000.0  2500.0  2700.0  3100.0  3400.0
+1900.0  2100.0  2600.0  2700.0  3000.0  3200.0
+1500.0  1900.0  2600.0  2800.0  3200.0  3300.0
+1600.0  1800.0  2200.0  2700.0  3200.0  3400.0
+1400.0  1800.0  2400.0  2600.0  2900.0  3200.0
+1500.0  1700.0  2500.0  2600.0  3000.0  3200.0
+1800.0  2100.0  2600.0  2800.0  3400.0  3500.0
+1700.0  2000.0  2600.0  2800.0  3000.0  3300.0
+1800.0  2100.0  2700.0  2900.0  3400.0  3500.0
+1600.0  1700.0  2600.0  2700.0  3100.0  3400.0
+1800.0  1900.0  2400.0  2600.0  2800.0  3000.0
+1600.0  2000.0  2500.0  2600.0  2900.0  3200.0
+1400.0  1800.0  2400.0  2500.0  2900.0  3100.0
+1500.0  1800.0  2400.0  2500.0  2900.0  3200.0
+1200.0  1400.0  2300.0  2500.0  2900.0  3200.0
+1400.0  1600.0  2500.0  2700.0  3000.0  3300.0
+1500.0  1900.0  2500.0  2700.0  3000.0  3300.0
+1000.0  1400.0  2600.0  2700.0  3100.0  3300.0
+1400.0  1700.0  2100.0  2300.0  2900.0  3000.0
+1700.0  1800.0  2400.0  2600.0  2800.0  3000.0
+1500.0  2000.0  2100.0  2500.0  3000.0  3100.0
+2000.0  2100.0  2300.0  2400.0  3100.0  3300.0
+2100.0  2200.0  2600.0  2800.0  3100.0  3200.0
+2100.0  2200.0  2600.0  2700.0  3000.0  3200.0
+1800.0  2000.0  2600.0  2800.0  3100.0  3400.0
+1700.0  2000.0  2500.0  2900.0  3100.0  3300.0
+1700.0  2000.0  2500.0  2900.0  3100.0  3400.0
+1600.0  1800.0  2500.0  2800.0  3000.0  3200.0
+1500.0  1800.0  2200.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2300.0  2600.0  3200.0  3300.0
+1500.0  1600.0  2400.0  2600.0  2800.0  3100.0
+1200.0  1600.0  2200.0  2600.0  3000.0  3200.0
+1500.0  1600.0  2000.0  2300.0  2900.0  3200.0
+1900.0  2000.0  2400.0  2700.0  3200.0  3400.0
+1900.0  2000.0  2400.0  2700.0  2800.0  3200.0
+1500.0  1700.0  2300.0  2600.0  3200.0  3400.0
+1700.0  1800.0  2400.0  2500.0  2800.0  3100.0
+1500.0  1600.0  2200.0  2400.0  2900.0  3100.0
+1500.0  1600.0  2200.0  2500.0  3100.0  3300.0
+1600.0  2000.0  2200.0  2400.0  2700.0  3100.0
+1500.0  1700.0  2300.0  2600.0  2900.0  3300.0
+1700.0  1800.0  2100.0  2300.0  2900.0  3100.0
+1400.0  1500.0  2000.0  2500.0  2700.0  3000.0
+1800.0  1900.0  2300.0  2400.0  2800.0  3100.0
+1300.0  1800.0  2200.0  2500.0  2900.0  3100.0
+1300.0  1900.0  2300.0  2700.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2500.0  2700.0  3100.0
+1600.0  1700.0  2200.0  2600.0  3100.0  3300.0
+1400.0  1500.0  2300.0  2500.0  2800.0  3000.0
+1300.0  1700.0  2100.0  2500.0  3000.0  3300.0
+1600.0  1800.0  2200.0  2400.0  2800.0  3200.0
+1400.0  1500.0  2200.0  2500.0  3200.0  3300.0
+1800.0  1900.0  2200.0  2500.0  3000.0  3100.0
+1300.0  1500.0  2200.0  2400.0  2900.0  3100.0
+1300.0  1500.0  2300.0  2500.0  3100.0  3300.0
+1100.0  1500.0  2400.0  2500.0  3000.0  3200.0
+1600.0  1700.0  2400.0  2600.0  2800.0  3100.0
+1500.0  1600.0  2400.0  2500.0  2800.0  3100.0
+1500.0  1600.0  2000.0  2500.0  2800.0  3100.0
+1200.0  1700.0  2400.0  2600.0  3200.0  3300.0
+1100.0  1600.0  2400.0  2500.0  3200.0  3400.0
+1100.0  1500.0  2400.0  2500.0  3000.0  3400.0
+1100.0  1600.0  2400.0  2500.0  3100.0  3300.0
+1900.0  2000.0  2400.0  2500.0  2900.0  3100.0
+1300.0  1500.0  2200.0  2300.0  2700.0  3100.0
+1600.0  1900.0  2500.0  2800.0  3200.0  3300.0
+1900.0  2100.0  2600.0  2900.0  3300.0  3400.0
+1700.0  2100.0  2500.0  2600.0  3000.0  3300.0
+1800.0  1900.0  2400.0  2500.0  2900.0  3000.0
+1300.0  1500.0  2300.0  2400.0  2900.0  3000.0
+1200.0  1700.0  1800.0  2300.0  2900.0  3000.0
+1200.0  1600.0  1800.0  2200.0  2900.0  3000.0
+1200.0  1700.0  2100.0  2300.0  3100.0  3200.0
+1400.0  1900.0  2100.0  2400.0  3000.0  3200.0
+1100.0  1500.0  2500.0  2600.0  3000.0  3300.0
+1300.0  1400.0  2400.0  2500.0  2800.0  3300.0
+1300.0  1500.0  2300.0  2500.0  3200.0  3400.0
+1300.0  1900.0  2300.0  2700.0  3100.0  3200.0
+1700.0  1900.0  2200.0  2400.0  2700.0  3100.0
+1400.0  1500.0  2000.0  2500.0  2600.0  3000.0
+1500.0  1600.0  2000.0  2400.0  2600.0  3000.0
+1400.0  1700.0  2400.0  2600.0  3000.0  3300.0
+2000.0  2100.0  2300.0  2500.0  2900.0  3100.0
+1900.0  2000.0  2400.0  2500.0  2800.0  3000.0
+1800.0  1900.0  2200.0  2400.0  2700.0  3000.0
+1400.0  1600.0  1900.0  2300.0  2600.0  3000.0
+1600.0  2000.0  2600.0  2800.0  3300.0  3400.0
+1200.0  1600.0  1800.0  2100.0  3200.0  3300.0
+1900.0  2300.0  2700.0  2800.0  3400.0  3500.0
+1500.0  1600.0  2200.0  2500.0  2700.0  3100.0
+1700.0  2100.0  2300.0  2500.0  2900.0  3200.0
+1300.0  1500.0  2200.0  2500.0  3000.0  3300.0
+1400.0  1500.0  2100.0  2500.0  2600.0  2900.0
+1500.0  1600.0  2200.0  2300.0  2800.0  3300.0
+1500.0  1600.0  1800.0  2100.0  2800.0  2900.0
+1700.0  1800.0  2200.0  2400.0  2600.0  3100.0
+1600.0  1900.0  2600.0  2700.0  3200.0  3400.0
+1500.0  1700.0  2400.0  2600.0  3000.0  3400.0
+1200.0  1500.0  2300.0  2400.0  2900.0  3300.0
+1600.0  2100.0  2500.0  2700.0  3200.0  3400.0
+1500.0  1700.0  2300.0  2500.0  2600.0  2900.0
+1500.0  1600.0  2400.0  2600.0  3000.0  3100.0
+1600.0  1800.0  2600.0  2800.0  3000.0  3200.0
+1400.0  1700.0  2200.0  2500.0  3100.0  3400.0
+1600.0  1700.0  2300.0  2600.0  2700.0  3100.0
+1600.0  1700.0  2100.0  2500.0  2700.0  3100.0
+2000.0  2200.0  2500.0  2700.0  3100.0  3400.0
+1900.0  2100.0  2400.0  2600.0  3000.0  3400.0
+1400.0  1800.0  2100.0  2600.0  2900.0  3100.0
+1000.0  1800.0  2100.0  2300.0  3100.0  3200.0
+1400.0  1500.0  2200.0  2400.0  3000.0  3300.0
+1300.0  1800.0  2200.0  2300.0  3000.0  3200.0
+1100.0  1500.0  2300.0  2400.0  3000.0  3200.0
+1400.0  1500.0  2300.0  2400.0  2900.0  3300.0
+1400.0  1500.0  2200.0  2400.0  2800.0  3300.0
+1200.0  1600.0  2100.0  2200.0  3200.0  3300.0
+1600.0  1800.0  2100.0  2300.0  2500.0  3100.0
+1500.0  1600.0  2400.0  2600.0  3000.0  3400.0
+1500.0  1800.0  2500.0  2600.0  3300.0  3400.0
+1900.0  2500.0  2600.0  2900.0  3200.0  3300.0
+1300.0  1500.0  2100.0  2500.0  2700.0  3100.0
+1200.0  1400.0  2400.0  2500.0  2800.0  3200.0
+1600.0  1700.0  2300.0  2400.0  2900.0  3400.0
+1100.0  1800.0  2200.0  2300.0  3300.0  3400.0
+1800.0  2200.0  2500.0  2800.0  3100.0  3400.0
+1200.0  1700.0  2100.0  2700.0  3100.0  3200.0
+1300.0  1600.0  2100.0  2600.0  3000.0  3200.0
+2000.0  2200.0  2300.0  2400.0  3100.0  3300.0
+1700.0  1900.0  2400.0  2600.0  3100.0  3400.0
+1300.0  1700.0  2000.0  2600.0  3200.0  3300.0
+1100.0  1700.0  2300.0  2400.0  3200.0  3400.0
+1100.0  1600.0  2300.0  2400.0  3200.0  3400.0
+1700.0  2300.0  2800.0  3000.0  3300.0  3400.0
+1700.0  2000.0  2300.0  2800.0  3200.0  3300.0
+1800.0  1900.0  2100.0  2600.0  3000.0  3200.0
+1300.0  2000.0  2200.0  2600.0  3000.0  3200.0
+1300.0  1500.0  2300.0  2400.0  3000.0  3400.0
+1600.0  1700.0  2100.0  2300.0  2800.0  3200.0
+1700.0  1800.0  2400.0  2700.0  2800.0  3200.0
+1800.0  1900.0  2500.0  2700.0  2800.0  3200.0
+1700.0  1800.0  2100.0  2300.0  2900.0  3300.0
+1500.0  1700.0  2300.0  2400.0  2700.0  3200.0
+1600.0  2100.0  2500.0  2800.0  3100.0  3200.0
+1400.0  1700.0  2300.0  2700.0  3000.0  3300.0
+900.0  1400.0  2300.0  2500.0  3100.0  3300.0
+1700.0  1800.0  2300.0  2400.0  3000.0  3400.0
+2000.0  2100.0  2400.0  2600.0  2900.0  3100.0
+1900.0  2500.0  2600.0  2800.0  3300.0  3400.0
+1400.0  1500.0  2200.0  2300.0  2900.0  3300.0
+1600.0  1700.0  2000.0  2500.0  2600.0  3100.0
+1700.0  1800.0  2200.0  2300.0  2900.0  3200.0
+2100.0  2500.0  2800.0  3100.0  3300.0  3500.0
+1900.0  2400.0  2600.0  2700.0  3300.0  3400.0
+1700.0  2100.0  2500.0  2600.0  3300.0  3400.0
+1100.0  1500.0  2300.0  2400.0  3100.0  3400.0
+1200.0  1500.0  2300.0  2400.0  3300.0  3400.0
+1200.0  1800.0  2200.0  2400.0  3300.0  3400.0
+1500.0  1900.0  2200.0  2300.0  3100.0  3300.0
+1300.0  1600.0  1800.0  2100.0  3200.0  3300.0
+1600.0  1800.0  2400.0  2600.0  2900.0  3300.0
+1700.0  1900.0  2400.0  2600.0  3000.0  3400.0
+1300.0  1800.0  2200.0  2300.0  2900.0  3200.0
+1400.0  1700.0  2200.0  2300.0  3200.0  3400.0
+1400.0  1600.0  2200.0  2400.0  3200.0  3400.0
+1700.0  1800.0  2400.0  2500.0  3200.0  3500.0
+1600.0  1700.0  2500.0  2600.0  3200.0  3400.0
+1500.0  1700.0  2400.0  2500.0  2900.0  3400.0
+1700.0  1800.0  2300.0  2400.0  2900.0  3500.0
+1700.0  1800.0  2300.0  2400.0  3000.0  3500.0
+1600.0  1700.0  2300.0  2500.0  2700.0  3400.0
+1800.0  1900.0  2400.0  2500.0  3000.0  3500.0
+1300.0  1600.0  1800.0  2500.0  3100.0  3300.0
+1200.0  1700.0  2000.0  2200.0  3200.0  3300.0
+1200.0  1600.0  2200.0  2300.0  3200.0  3400.0
+1200.0  1600.0  2200.0  2400.0  3200.0  3400.0
+1600.0  2300.0  2600.0  2900.0  3300.0  3400.0
+1300.0  1600.0  2200.0  2300.0  3000.0  3400.0
+1900.0  2100.0  2400.0  2500.0  2800.0  3100.0
+1400.0  2000.0  2500.0  2700.0  3100.0  3200.0
+1700.0  1800.0  2400.0  2500.0  2800.0  3300.0
+1900.0  2000.0  2400.0  2600.0  2800.0  3400.0
+1600.0  2200.0  2500.0  2800.0  3200.0  3300.0
+1200.0  1700.0  2300.0  2400.0  3000.0  3300.0
+1200.0  1400.0  2200.0  2300.0  2900.0  3200.0
+1600.0  1800.0  2400.0  2700.0  3200.0  3400.0
+1600.0  1900.0  2400.0  2600.0  3100.0  3400.0
+1500.0  1800.0  2400.0  2600.0  3000.0  3400.0
+1600.0  1700.0  2400.0  2500.0  3100.0  3500.0
+1500.0  1600.0  2100.0  2300.0  2700.0  3200.0
+1500.0  1600.0  2100.0  2200.0  2600.0  3100.0
+1700.0  1900.0  2400.0  2700.0  3300.0  3400.0
+1200.0  1500.0  2200.0  2300.0  3300.0  3400.0
+1300.0  1600.0  2100.0  2200.0  3300.0  3400.0
+1400.0  1500.0  2100.0  2200.0  3200.0  3400.0
+1800.0  1900.0  2300.0  2400.0  2800.0  3300.0
+1900.0  2000.0  2400.0  2500.0  2800.0  3200.0
+2000.0  2100.0  2400.0  2600.0  2800.0  3200.0
+1500.0  2100.0  2300.0  2500.0  2800.0  3200.0
+1500.0  1800.0  2300.0  2400.0  3000.0  3200.0
+1700.0  1800.0  2600.0  2800.0  3000.0  3200.0
+1900.0  2500.0  2800.0  2900.0  3200.0  3300.0
+1100.0  1400.0  2500.0  2800.0  3000.0  3200.0
+1200.0  1400.0  2700.0  2900.0  3100.0  3300.0
+1200.0  1400.0  2600.0  2900.0  3000.0  3300.0
+1200.0  1400.0  2700.0  2900.0  3000.0  3400.0
+1200.0  1600.0  2600.0  2800.0  3100.0  3400.0
+1300.0  1800.0  2400.0  2500.0  2900.0  3200.0
+1400.0  1700.0  2500.0  2600.0  3200.0  3400.0
+1400.0  1900.0  2300.0  2400.0  2900.0  3300.0
+1800.0  1900.0  2600.0  2700.0  3100.0  3400.0
+1800.0  2000.0  2600.0  2700.0  3100.0  3400.0
+1800.0  1900.0  2600.0  2700.0  3000.0  3400.0
+1400.0  1800.0  2300.0  2500.0  2700.0  3000.0
+1600.0  1700.0  2500.0  2700.0  3200.0  3400.0
+1500.0  1700.0  2400.0  2700.0  3000.0  3200.0
+1500.0  1900.0  2400.0  2700.0  3100.0  3200.0
+1900.0  2100.0  2700.0  2800.0  3200.0  3300.0
+1600.0  2000.0  2300.0  2400.0  3200.0  3400.0
+1500.0  1700.0  2500.0  2700.0  3200.0  3300.0
+1700.0  1800.0  2500.0  2700.0  3200.0  3300.0
+1800.0  1900.0  2600.0  2800.0  3100.0  3400.0
+1700.0  1800.0  2500.0  2800.0  2900.0  3200.0
+1600.0  1700.0  2500.0  2700.0  3000.0  3300.0
+1200.0  1700.0  2700.0  2800.0  3100.0  3300.0
+1200.0  1500.0  2700.0  2900.0  3100.0  3300.0
+1500.0  1800.0  2400.0  2700.0  3100.0  3400.0
+1400.0  1600.0  2600.0  2800.0  3000.0  3300.0
+1600.0  1800.0  2500.0  2700.0  3000.0  3400.0
+1500.0  1800.0  2300.0  2600.0  3100.0  3400.0
+1500.0  1700.0  2300.0  2500.0  2700.0  3300.0
+2000.0  2100.0  2500.0  2700.0  2900.0  3300.0
+2200.0  2300.0  2600.0  2700.0  3200.0  3400.0
+1400.0  1800.0  2300.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2600.0  2700.0  3100.0  3400.0
+1300.0  1700.0  2100.0  2500.0  3100.0  3300.0
+2100.0  2200.0  2600.0  2800.0  3300.0  3400.0
+2100.0  2300.0  2700.0  2800.0  3300.0  3400.0
+1600.0  1700.0  2500.0  2700.0  3100.0  3300.0
+1400.0  1700.0  2600.0  2700.0  3200.0  3400.0
+1200.0  1500.0  2600.0  2800.0  3100.0  3300.0
+1800.0  1900.0  2500.0  2600.0  3000.0  3400.0
+1700.0  1800.0  2400.0  2600.0  2900.0  3000.0
+1200.0  1600.0  2800.0  3000.0  3200.0  3300.0
+1600.0  1700.0  2300.0  2600.0  3200.0  3400.0
+1700.0  1800.0  2200.0  2500.0  2800.0  3300.0
+1700.0  1800.0  2600.0  2700.0  3000.0  3400.0
+1500.0  1600.0  2600.0  2800.0  3000.0  3300.0
+1100.0  1300.0  2400.0  2900.0  3000.0  3200.0
+1100.0  1500.0  2700.0  2800.0  3100.0  3300.0
+1600.0  1800.0  2000.0  2300.0  3300.0  3400.0
+1800.0  2000.0  2100.0  2400.0  3300.0  3400.0
+1800.0  2000.0  2500.0  2600.0  2900.0  3300.0
+1600.0  1700.0  2400.0  2700.0  2900.0  3300.0
+1600.0  1700.0  2600.0  2800.0  3100.0  3300.0
+1500.0  1700.0  1900.0  2100.0  3000.0  3300.0
+1900.0  2000.0  2100.0  2300.0  3200.0  3400.0
+2100.0  2200.0  2500.0  2600.0  2900.0  3300.0
+1800.0  2000.0  2200.0  2400.0  3300.0  3400.0
+1700.0  1800.0  2100.0  2300.0  3300.0  3400.0
+2000.0  2200.0  2500.0  2600.0  3200.0  3400.0
+1700.0  1900.0  2100.0  2800.0  3100.0  3200.0
+1800.0  1900.0  2500.0  2900.0  3100.0  3200.0
+1800.0  1900.0  2500.0  2900.0  3000.0  3200.0
+1300.0  1500.0  1800.0  1900.0  2700.0  3200.0
+1000.0  1300.0  2400.0  3000.0  3300.0  3400.0
+1400.0  1600.0  1800.0  1900.0  2900.0  3300.0
+1500.0  1700.0  1900.0  2000.0  2800.0  3200.0
+1800.0  2000.0  2300.0  2500.0  2700.0  3100.0
+1800.0  1900.0  2200.0  2300.0  2800.0  3200.0
+1200.0  1900.0  2500.0  2600.0  2900.0  3000.0
+1200.0  1900.0  2400.0  2600.0  2900.0  3000.0
+1800.0  2000.0  2100.0  2400.0  3000.0  3200.0
+1900.0  2200.0  2600.0  2900.0  3100.0  3200.0
+1600.0  1700.0  2000.0  2100.0  2700.0  3200.0
+1600.0  1800.0  2300.0  2800.0  3100.0  3200.0
+1700.0  1900.0  2400.0  2700.0  2900.0  3300.0
+1900.0  2000.0  2400.0  2800.0  3200.0  3300.0
+1400.0  1600.0  2300.0  2500.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2200.0  2700.0  3200.0
+2000.0  2100.0  2600.0  2900.0  3300.0  3400.0
+1200.0  1500.0  2300.0  2500.0  2900.0  3200.0
+1200.0  1400.0  2200.0  2400.0  2900.0  3200.0
+1600.0  2200.0  2400.0  2600.0  3200.0  3400.0
+1700.0  1800.0  2400.0  2500.0  3000.0  3100.0
+1700.0  1800.0  2200.0  2600.0  3100.0  3200.0
+1200.0  1900.0  2300.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2000.0  2800.0  3200.0  3300.0
+1500.0  1700.0  2400.0  2500.0  3000.0  3100.0
+1400.0  2000.0  2400.0  2600.0  3000.0  3300.0
+1200.0  1400.0  2400.0  2800.0  3000.0  3100.0
+1500.0  1600.0  2000.0  2100.0  2900.0  3300.0
+1500.0  1600.0  2000.0  2200.0  2800.0  3300.0
+1200.0  1500.0  2100.0  2200.0  3000.0  3300.0
+1400.0  2000.0  2300.0  2700.0  3100.0  3300.0
+1600.0  1700.0  2000.0  2700.0  3200.0  3300.0
+1700.0  1900.0  2300.0  2600.0  2800.0  3200.0
+2100.0  2300.0  2600.0  2800.0  3100.0  3200.0
+1400.0  1800.0  2400.0  2500.0  3000.0  3200.0
+1500.0  2100.0  2400.0  2700.0  3000.0  3300.0
+1600.0  1700.0  2100.0  2700.0  3000.0  3100.0
+1500.0  1800.0  2200.0  2700.0  3100.0  3300.0
+1300.0  1500.0  2400.0  2500.0  2900.0  3200.0
+1200.0  1500.0  2500.0  2600.0  3000.0  3200.0
+1100.0  1500.0  2400.0  2500.0  2900.0  3300.0
+1800.0  1900.0  2400.0  2500.0  2800.0  3000.0
+1700.0  1800.0  2100.0  2800.0  3100.0  3200.0
+1900.0  2200.0  2400.0  2900.0  3100.0  3200.0
+1500.0  1700.0  2300.0  2600.0  2800.0  3100.0
+1300.0  1500.0  1900.0  2500.0  3000.0  3100.0
+1700.0  1800.0  2400.0  2700.0  3100.0  3200.0
+1900.0  2500.0  2900.0  3100.0  3300.0  3400.0
+1500.0  1800.0  2000.0  2600.0  2900.0  3100.0
+1900.0  2300.0  2500.0  2800.0  3200.0  3400.0
+1500.0  2100.0  2500.0  2700.0  3200.0  3400.0
+1500.0  2100.0  2500.0  2700.0  2900.0  3200.0
+1800.0  2300.0  2800.0  2900.0  3300.0  3400.0
+1600.0  1900.0  2200.0  2600.0  3000.0  3300.0
+1400.0  1900.0  2400.0  2600.0  2800.0  3100.0
+1300.0  1700.0  2500.0  2600.0  3000.0  3200.0
+1400.0  1800.0  2100.0  2500.0  2800.0  3100.0
+1700.0  2400.0  2600.0  3000.0  3300.0  3400.0
+2200.0  2400.0  2700.0  3000.0  3200.0  3300.0
+1400.0  1800.0  2400.0  2700.0  3000.0  3200.0
+1300.0  1700.0  2300.0  2600.0  2900.0  3200.0
+1400.0  1900.0  2200.0  2500.0  2700.0  3000.0
+1500.0  1900.0  2200.0  2800.0  3100.0  3300.0
+1400.0  1600.0  1800.0  2200.0  3200.0  3400.0
+1700.0  2000.0  2200.0  2700.0  3200.0  3300.0
+1400.0  1900.0  2500.0  2700.0  3300.0  3400.0
+1500.0  2100.0  2300.0  2500.0  2800.0  3100.0
+1500.0  2000.0  2300.0  2500.0  2800.0  3100.0
+1500.0  1600.0  2400.0  2800.0  3000.0  3200.0
+1400.0  1600.0  2200.0  2700.0  3000.0  3100.0
+1200.0  1800.0  2000.0  2300.0  2900.0  3100.0
+1300.0  1900.0  2400.0  2700.0  3200.0  3300.0
+2200.0  2500.0  2800.0  3100.0  3400.0  3500.0
+2100.0  2400.0  2900.0  3000.0  3100.0  3300.0
+1200.0  1500.0  1700.0  2300.0  2900.0  3000.0
+1600.0  2200.0  2600.0  2800.0  3200.0  3300.0
+1700.0  2300.0  2500.0  2800.0  3100.0  3300.0
+1400.0  1900.0  2500.0  2600.0  3100.0  3200.0
+1400.0  1700.0  2500.0  2600.0  3100.0  3400.0
+1300.0  1700.0  2500.0  2600.0  3100.0  3400.0
+1400.0  2100.0  2300.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2600.0  3100.0  3200.0
+1100.0  1900.0  2100.0  2500.0  3100.0  3200.0
+1300.0  1400.0  2500.0  2600.0  3000.0  3300.0
+1300.0  2000.0  2400.0  2600.0  3100.0  3300.0
+1500.0  2000.0  2300.0  2600.0  3200.0  3400.0
+1400.0  1900.0  2200.0  2700.0  3000.0  3200.0
+1600.0  2100.0  2500.0  2600.0  3000.0  3200.0
+1600.0  2100.0  2500.0  2700.0  3000.0  3200.0
+1500.0  2000.0  2500.0  2700.0  3000.0  3200.0
+1900.0  2400.0  2600.0  2900.0  3400.0  3500.0
+1400.0  1700.0  2300.0  2700.0  3000.0  3200.0
+1800.0  2300.0  2900.0  3100.0  3400.0  3500.0
+1700.0  2100.0  2300.0  2500.0  3000.0  3100.0
+1900.0  2100.0  2500.0  3000.0  3300.0  3400.0
+1300.0  1500.0  1800.0  2500.0  2800.0  3000.0
+1300.0  1400.0  2000.0  2400.0  2800.0  3200.0
+1300.0  2100.0  2400.0  2600.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2600.0  3000.0  3200.0
+1400.0  1900.0  2400.0  2600.0  3100.0  3200.0
+1300.0  1800.0  2500.0  2600.0  3100.0  3200.0
+1500.0  2100.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1700.0  2000.0  2700.0  2900.0  3100.0
+1400.0  2000.0  2200.0  2400.0  2700.0  3100.0
+1200.0  1400.0  2600.0  2700.0  2900.0  3100.0
+1500.0  2100.0  2300.0  2500.0  2700.0  3100.0
+1800.0  2100.0  2500.0  2600.0  3100.0  3200.0
+1200.0  1700.0  2100.0  2500.0  3200.0  3300.0
+1400.0  2100.0  2300.0  2700.0  3200.0  3300.0
+1700.0  2000.0  2600.0  2800.0  3100.0  3200.0
+1400.0  1700.0  2300.0  2700.0  3200.0  3300.0
+1300.0  1600.0  2200.0  2400.0  3100.0  3200.0
+1400.0  1500.0  2200.0  2500.0  3000.0  3200.0
+1400.0  1700.0  2300.0  2500.0  2800.0  3100.0
+1500.0  1700.0  2200.0  2500.0  2700.0  3100.0
+1500.0  1700.0  2200.0  2500.0  2900.0  3100.0
+1800.0  2000.0  2700.0  2900.0  3100.0  3400.0
+1300.0  1700.0  2100.0  2200.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2700.0  2900.0  3300.0
+1500.0  1600.0  2700.0  2800.0  3000.0  3300.0
+1400.0  1500.0  2500.0  2700.0  2900.0  3200.0
+1100.0  1600.0  2400.0  2600.0  3000.0  3200.0
+1600.0  2000.0  2700.0  2900.0  3300.0  3400.0
+1400.0  1500.0  2600.0  2800.0  3000.0  3300.0
+1400.0  1500.0  2600.0  2700.0  3000.0  3300.0
+1400.0  1500.0  2500.0  2700.0  2900.0  3300.0
+1700.0  1900.0  2600.0  2900.0  3100.0  3300.0
+1500.0  1600.0  2300.0  2700.0  3100.0  3200.0
+1200.0  1700.0  2300.0  2700.0  3000.0  3200.0
+1500.0  1600.0  2500.0  2800.0  3000.0  3300.0
+1500.0  1600.0  1700.0  1800.0  3100.0  3400.0
+1500.0  1600.0  2300.0  2700.0  3000.0  3300.0
+1300.0  1500.0  2600.0  2700.0  3200.0  3300.0
+2100.0  2200.0  2500.0  2700.0  3100.0  3200.0
+2100.0  2200.0  2800.0  3000.0  3200.0  3300.0
+1500.0  1700.0  2400.0  2600.0  2800.0  3100.0
+1500.0  1800.0  2400.0  2700.0  3000.0  3200.0
+1400.0  1700.0  2400.0  2700.0  3100.0  3200.0
+900.0  1500.0  2800.0  2900.0  3100.0  3300.0
+1400.0  1700.0  2500.0  2700.0  3100.0  3400.0
+1800.0  2000.0  2300.0  2800.0  3100.0  3300.0
+1200.0  1600.0  2300.0  2400.0  2900.0  3200.0
+1800.0  1900.0  2300.0  2600.0  3000.0  3100.0
+1300.0  1600.0  1900.0  2400.0  2900.0  3200.0
+1400.0  1600.0  2500.0  2700.0  2900.0  3300.0
+900.0  1600.0  2200.0  2300.0  3200.0  3300.0
+1300.0  1900.0  2200.0  2300.0  3100.0  3300.0
+1700.0  1900.0  2500.0  2900.0  3200.0  3300.0
+1400.0  1900.0  2500.0  2700.0  3200.0  3400.0
+1700.0  2000.0  2200.0  2500.0  2900.0  3000.0
+1200.0  1500.0  2600.0  2800.0  3100.0  3400.0
+1400.0  1700.0  2100.0  2600.0  3000.0  3300.0
+1400.0  1700.0  2500.0  2800.0  3200.0  3300.0
+1800.0  2400.0  2600.0  2900.0  3400.0  3500.0
+1900.0  2100.0  2500.0  2600.0  3100.0  3200.0
+2200.0  2500.0  2800.0  3000.0  3400.0  3500.0
+1600.0  1800.0  1900.0  2500.0  3100.0  3200.0
+1100.0  1600.0  2500.0  2600.0  3200.0  3400.0
+1700.0  2200.0  2500.0  2700.0  3100.0  3400.0
+1000.0  1700.0  2200.0  2300.0  3200.0  3300.0
+1100.0  1700.0  2200.0  2600.0  3100.0  3300.0
+1100.0  1700.0  2300.0  2700.0  3200.0  3300.0
+1500.0  1800.0  2100.0  2600.0  3200.0  3300.0
+1300.0  2100.0  2400.0  2600.0  2800.0  3200.0
+1800.0  1900.0  2200.0  2600.0  2800.0  3200.0
+1800.0  1900.0  2500.0  2600.0  3100.0  3200.0
+1400.0  2100.0  2300.0  2500.0  2700.0  3100.0
+1300.0  2000.0  2400.0  2500.0  2800.0  3200.0
+1600.0  2100.0  2600.0  2800.0  3200.0  3400.0
+1400.0  1800.0  2200.0  2400.0  3300.0  3400.0
+1300.0  1700.0  2200.0  2300.0  3300.0  3400.0
+1300.0  1600.0  2200.0  2300.0  3300.0  3400.0
+1300.0  1600.0  2300.0  2400.0  3300.0  3400.0
+1100.0  1700.0  2200.0  2300.0  3300.0  3400.0
+1500.0  1900.0  2200.0  2500.0  2700.0  3100.0
+1300.0  1700.0  1900.0  2200.0  3000.0  3100.0
+1400.0  1600.0  2500.0  2600.0  3300.0  3400.0
+1500.0  1600.0  2500.0  2600.0  3200.0  3400.0
+1000.0  1700.0  2600.0  2700.0  3300.0  3400.0
+1000.0  1600.0  2600.0  2700.0  3300.0  3400.0
+1400.0  1700.0  2500.0  2600.0  3000.0  3400.0
+1400.0  1800.0  2500.0  2600.0  3300.0  3400.0
+1500.0  1600.0  2400.0  2600.0  3200.0  3400.0
+1600.0  2200.0  2500.0  2600.0  3200.0  3300.0
+1000.0  1900.0  2400.0  2500.0  3300.0  3400.0
+1200.0  1700.0  2200.0  2400.0  3200.0  3400.0
+2000.0  2200.0  2600.0  2900.0  3300.0  3400.0
+2200.0  2300.0  2700.0  2800.0  3300.0  3400.0
+2200.0  2300.0  2700.0  2800.0  3200.0  3300.0
+2000.0  2300.0  2400.0  2700.0  3100.0  3300.0
+2200.0  2300.0  2600.0  2800.0  3200.0  3300.0
+1500.0  2000.0  2300.0  2400.0  3200.0  3300.0
+1500.0  1600.0  1800.0  2500.0  3200.0  3300.0
+1100.0  1900.0  2200.0  2400.0  3000.0  3300.0
+1500.0  2100.0  2600.0  2700.0  3200.0  3400.0
+1400.0  1900.0  2400.0  2600.0  3000.0  3200.0
+1200.0  1800.0  2400.0  2600.0  3200.0  3300.0
+1200.0  1700.0  2700.0  2800.0  3200.0  3300.0
+1200.0  1600.0  2600.0  2700.0  3200.0  3300.0
+1300.0  1600.0  2500.0  2600.0  3000.0  3300.0
+1500.0  1600.0  2500.0  2700.0  2900.0  3300.0
+1500.0  1700.0  1800.0  2500.0  3100.0  3200.0
+1400.0  1700.0  1900.0  2600.0  3100.0  3200.0
+1300.0  1700.0  2500.0  2600.0  3200.0  3300.0
+1100.0  1400.0  2600.0  3000.0  3200.0  3300.0
+1100.0  1400.0  2600.0  2900.0  3100.0  3300.0
+1600.0  1800.0  1900.0  2600.0  3200.0  3300.0
+2000.0  2100.0  2600.0  2700.0  3100.0  3200.0
+1300.0  1700.0  2100.0  2300.0  3200.0  3300.0
+1100.0  1700.0  2800.0  2900.0  3200.0  3300.0
+1500.0  1700.0  2500.0  2600.0  2900.0  3200.0
+1400.0  1800.0  2600.0  2700.0  3200.0  3300.0
+1600.0  1700.0  2100.0  2400.0  3000.0  3300.0
+1300.0  1500.0  1600.0  2200.0  3000.0  3100.0
+1300.0  2000.0  2500.0  2700.0  3100.0  3200.0
+1800.0  2200.0  2500.0  2600.0  3200.0  3300.0
+1700.0  2200.0  2400.0  2600.0  2800.0  3100.0
+2000.0  2200.0  2600.0  2800.0  3000.0  3300.0
+1300.0  1400.0  2400.0  2700.0  3100.0  3300.0
+1500.0  1600.0  1900.0  2000.0  2900.0  3300.0
+1000.0  1200.0  2400.0  2500.0  3100.0  3400.0
+1800.0  1900.0  2200.0  2400.0  2600.0  3000.0
+1900.0  2000.0  2200.0  2600.0  2800.0  3000.0
+1300.0  1800.0  2200.0  2400.0  2900.0  3200.0
+1800.0  2100.0  2300.0  2500.0  2800.0  3000.0
+1500.0  2000.0  2300.0  2600.0  2800.0  3100.0
+1000.0  1400.0  2400.0  2500.0  3100.0  3300.0
+1300.0  1900.0  2700.0  2800.0  3200.0  3300.0
+1900.0  2200.0  2300.0  2500.0  2800.0  3100.0
+1900.0  2000.0  2200.0  2600.0  2800.0  3100.0
+1600.0  1700.0  2100.0  2200.0  2900.0  3200.0
+1500.0  1900.0  2200.0  2500.0  3000.0  3300.0
+1400.0  1900.0  2400.0  2800.0  3100.0  3300.0
+1900.0  2000.0  2300.0  2600.0  2800.0  3200.0
+1900.0  2100.0  2300.0  2600.0  2800.0  3200.0
+1600.0  1700.0  2300.0  2700.0  3100.0  3300.0
+1600.0  1800.0  2100.0  2300.0  2600.0  3000.0
+1600.0  1800.0  2100.0  2400.0  2600.0  3000.0
+1700.0  2000.0  2200.0  2500.0  3100.0  3300.0
+1600.0  1700.0  2000.0  2400.0  2600.0  3000.0
+1300.0  1500.0  2200.0  2400.0  2800.0  3200.0
+1300.0  1700.0  2200.0  2400.0  2900.0  3200.0
+1700.0  1900.0  2100.0  2300.0  2800.0  3100.0
+1200.0  1400.0  2300.0  2400.0  2900.0  3300.0
+1400.0  1500.0  2000.0  2200.0  2700.0  3000.0
+1200.0  1900.0  2400.0  2600.0  3000.0  3300.0
+1700.0  1800.0  2100.0  2300.0  2600.0  3100.0
+1900.0  2000.0  2200.0  2400.0  2700.0  3000.0
+1900.0  2100.0  2300.0  2400.0  2700.0  3000.0
+1400.0  1800.0  2200.0  2400.0  2700.0  3200.0
+1700.0  1800.0  2200.0  2300.0  2900.0  3300.0
+1700.0  2000.0  2500.0  2800.0  3400.0  3500.0
+1300.0  1500.0  2200.0  2300.0  3100.0  3200.0
+1400.0  1800.0  2100.0  2600.0  3000.0  3200.0
+1300.0  1900.0  2200.0  2500.0  3100.0  3300.0
+1500.0  2100.0  2600.0  2700.0  3200.0  3300.0
+1300.0  1800.0  2600.0  2700.0  3200.0  3300.0
+1000.0  1500.0  2700.0  2800.0  3100.0  3300.0
+2200.0  2300.0  2500.0  2900.0  3200.0  3400.0
+2100.0  2200.0  2500.0  2900.0  3100.0  3300.0
+1500.0  1600.0  2400.0  2700.0  3000.0  3300.0
+1300.0  1500.0  1600.0  2000.0  3200.0  3400.0
+1400.0  1600.0  1700.0  2000.0  3200.0  3400.0
+1700.0  1900.0  2700.0  2800.0  3200.0  3300.0
+1700.0  1900.0  2700.0  2800.0  3100.0  3300.0
+1500.0  1600.0  2300.0  2700.0  2800.0  3200.0
+1500.0  1600.0  2200.0  2500.0  2900.0  3300.0
+1200.0  1500.0  2100.0  2600.0  3000.0  3300.0
+1800.0  2300.0  2700.0  2800.0  3200.0  3400.0
+1000.0  1400.0  2400.0  2500.0  2900.0  3300.0
+1000.0  1500.0  2500.0  2600.0  2900.0  3200.0
+1900.0  2400.0  2700.0  3000.0  3200.0  3400.0
+1700.0  1900.0  2300.0  2400.0  3000.0  3400.0
+1300.0  1600.0  1700.0  2200.0  3100.0  3300.0
+1800.0  1900.0  2600.0  2900.0  3100.0  3300.0
+2300.0  2600.0  2800.0  2900.0  3300.0  3400.0
+1000.0  1500.0  2400.0  2500.0  3200.0  3300.0
+1400.0  1600.0  2100.0  2300.0  2900.0  3200.0
+1500.0  2000.0  2400.0  2600.0  2800.0  3000.0
+1400.0  1900.0  2300.0  2600.0  2800.0  3100.0
+1600.0  1700.0  2500.0  2600.0  2800.0  3200.0
+2000.0  2200.0  2800.0  3000.0  3300.0  3500.0
+2000.0  2400.0  2700.0  2800.0  3200.0  3300.0
+1400.0  1600.0  1700.0  1900.0  3200.0  3400.0
+2100.0  2200.0  2400.0  2700.0  3000.0  3300.0
+2100.0  2400.0  2800.0  3000.0  3100.0  3300.0
+1800.0  2000.0  2300.0  2400.0  3100.0  3400.0
+1400.0  1700.0  2600.0  2700.0  3000.0  3300.0
+1300.0  1700.0  2200.0  2500.0  3200.0  3400.0
+1500.0  1900.0  2300.0  2600.0  2800.0  3100.0
+2200.0  2500.0  2700.0  2800.0  3200.0  3400.0
+2100.0  2200.0  2500.0  2800.0  3000.0  3200.0
+1700.0  1900.0  2300.0  2600.0  2800.0  3000.0
+1800.0  2000.0  2400.0  2700.0  2900.0  3300.0
+1500.0  1800.0  2000.0  2400.0  3000.0  3100.0
+1500.0  1700.0  1800.0  2600.0  3100.0  3200.0
+1200.0  1700.0  2300.0  2600.0  3000.0  3200.0
+1400.0  1500.0  1900.0  2700.0  3000.0  3100.0
+1600.0  2100.0  2300.0  2700.0  3000.0  3100.0
+1700.0  2300.0  2400.0  2700.0  3100.0  3200.0
+1800.0  2300.0  2400.0  2700.0  2900.0  3100.0
+1400.0  1500.0  1900.0  2500.0  2800.0  3000.0
+1300.0  1500.0  1900.0  2600.0  3000.0  3100.0
+1500.0  1600.0  2000.0  2500.0  2900.0  3100.0
+1500.0  1900.0  2300.0  2800.0  3200.0  3300.0
+1900.0  2000.0  2500.0  2700.0  3000.0  3100.0
+1400.0  1500.0  2000.0  2500.0  2800.0  3000.0
+1400.0  1500.0  2000.0  2600.0  3000.0  3100.0
+1700.0  2000.0  2200.0  2600.0  2700.0  3000.0
+1400.0  1700.0  2000.0  2500.0  3100.0  3200.0
+1700.0  1900.0  2400.0  2700.0  2800.0  3100.0
+1700.0  2000.0  2300.0  2500.0  2800.0  3100.0
+1400.0  1600.0  1900.0  2400.0  2700.0  3000.0
+1500.0  1700.0  1900.0  2400.0  2700.0  3000.0
+1400.0  1500.0  1900.0  2800.0  3100.0  3200.0
+1400.0  1900.0  2200.0  2600.0  3100.0  3200.0
+1200.0  1600.0  2200.0  2500.0  3000.0  3100.0
+1500.0  1800.0  2500.0  2800.0  3000.0  3200.0
+1200.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1700.0  2100.0  2300.0  2500.0  2700.0  3200.0
+1300.0  1600.0  2100.0  2300.0  2800.0  3200.0
+1800.0  2000.0  2200.0  2800.0  3100.0  3200.0
+2100.0  2400.0  2900.0  3000.0  3300.0  3500.0
+1700.0  1900.0  2600.0  2900.0  3200.0  3300.0
+2100.0  2500.0  2900.0  3000.0  3200.0  3300.0
+2000.0  2300.0  2800.0  2900.0  3100.0  3400.0
+1300.0  1500.0  2100.0  2400.0  2800.0  3200.0
+1600.0  1700.0  2000.0  2700.0  3000.0  3100.0
+1500.0  1800.0  2000.0  2500.0  3000.0  3100.0
+1500.0  1800.0  2200.0  2700.0  2900.0  3100.0
+1600.0  1700.0  2100.0  2400.0  2600.0  3100.0
+1500.0  1900.0  2300.0  2400.0  2900.0  3300.0
+1300.0  2000.0  2400.0  2700.0  3100.0  3200.0
+1300.0  2000.0  2300.0  2700.0  3300.0  3400.0
+1700.0  2200.0  2400.0  2800.0  3200.0  3300.0
+1400.0  1900.0  2600.0  2900.0  3200.0  3300.0
+1400.0  1700.0  2000.0  2400.0  3100.0  3200.0
+1400.0  1600.0  2300.0  2500.0  2700.0  3000.0
+1500.0  1600.0  2300.0  2600.0  3100.0  3200.0
+1500.0  1900.0  2200.0  2400.0  3300.0  3400.0
+1200.0  1900.0  2100.0  2400.0  2900.0  3100.0
+1000.0  2300.0  2600.0  2800.0  3200.0  3300.0
+2200.0  2300.0  2600.0  2900.0  3300.0  3400.0
+1400.0  1600.0  2600.0  2700.0  3200.0  3300.0
+1300.0  2100.0  2500.0  2700.0  3100.0  3200.0
+1400.0  1600.0  2500.0  2600.0  3000.0  3400.0
+1200.0  1800.0  2700.0  2800.0  3000.0  3100.0
+1100.0  2000.0  2600.0  2700.0  3100.0  3200.0
+1000.0  1900.0  2700.0  2800.0  3100.0  3200.0
+1100.0  1900.0  2700.0  2800.0  3200.0  3300.0
+1200.0  1800.0  2500.0  2600.0  3000.0  3200.0
+2000.0  2100.0  2500.0  2600.0  3100.0  3200.0
+1400.0  2000.0  2500.0  2700.0  3200.0  3300.0
+2300.0  2400.0  2900.0  3100.0  3300.0  3400.0
+1600.0  1900.0  2300.0  2500.0  2900.0  3100.0
+1300.0  2200.0  2400.0  2900.0  3300.0  3400.0
+1300.0  2100.0  2200.0  2500.0  3200.0  3300.0
+1300.0  1900.0  2500.0  2600.0  3000.0  3100.0
+1300.0  1900.0  2500.0  2600.0  3100.0  3200.0
+1300.0  2000.0  2500.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2500.0  2600.0  3200.0  3300.0
+1700.0  1800.0  2300.0  2600.0  3000.0  3400.0
+1600.0  1800.0  2300.0  2700.0  3200.0  3400.0
+1300.0  1500.0  1600.0  2600.0  3200.0  3300.0
+1300.0  1500.0  1600.0  2500.0  3300.0  3400.0
+1300.0  1500.0  1600.0  2700.0  3300.0  3400.0
+2100.0  2500.0  3000.0  3100.0  3300.0  3400.0
+1400.0  1900.0  2300.0  2400.0  3100.0  3200.0
+1600.0  2200.0  2300.0  2600.0  3300.0  3400.0
+1300.0  1600.0  1700.0  2700.0  3100.0  3200.0
+1800.0  2300.0  2500.0  2800.0  3100.0  3300.0
+1500.0  1600.0  2400.0  2600.0  3100.0  3400.0
+1200.0  1900.0  2200.0  2400.0  3000.0  3100.0
+1400.0  1900.0  2200.0  2700.0  3100.0  3200.0
+1300.0  1700.0  2300.0  2600.0  2900.0  3100.0
+1300.0  2000.0  2300.0  2600.0  3200.0  3300.0
+1800.0  1900.0  2400.0  2600.0  3200.0  3500.0
+1700.0  1800.0  2400.0  2700.0  2900.0  3300.0
+1400.0  2000.0  2400.0  2500.0  2700.0  2900.0
+1400.0  2100.0  2400.0  2500.0  2700.0  3100.0
+1500.0  1700.0  2300.0  2700.0  2900.0  3200.0
+1200.0  1300.0  2300.0  2800.0  3000.0  3200.0
+1200.0  1400.0  2100.0  2600.0  3000.0  3300.0
+1600.0  1700.0  2500.0  2700.0  2800.0  3200.0
+1700.0  2100.0  2200.0  2700.0  3000.0  3100.0
+1400.0  1500.0  2100.0  2400.0  2900.0  3200.0
+1700.0  2100.0  2200.0  2600.0  3100.0  3200.0
+1600.0  1900.0  2300.0  2500.0  2900.0  3000.0
+1300.0  1500.0  2000.0  2600.0  2900.0  3000.0
+1800.0  1900.0  2100.0  2300.0  3000.0  3200.0
+1100.0  1500.0  2500.0  2800.0  3000.0  3200.0
+1900.0  2000.0  2200.0  2400.0  2800.0  3200.0
+1800.0  1900.0  2700.0  2800.0  3100.0  3300.0
+1200.0  1400.0  2000.0  2700.0  3000.0  3100.0
+1300.0  1400.0  1900.0  2000.0  2600.0  3200.0
+1000.0  1300.0  2400.0  2600.0  2800.0  3200.0
+1700.0  1800.0  2200.0  2400.0  2600.0  3000.0
+2000.0  2300.0  2400.0  2700.0  2900.0  3000.0
+1600.0  1700.0  2000.0  2200.0  2500.0  3100.0
+1700.0  2300.0  2700.0  2800.0  3200.0  3400.0
+1600.0  1700.0  2300.0  2600.0  2700.0  3000.0
+1400.0  1500.0  2000.0  2700.0  2900.0  3100.0
+1100.0  1400.0  2200.0  2600.0  2800.0  3000.0
+1700.0  2100.0  2300.0  2600.0  3000.0  3300.0
+1400.0  1500.0  1700.0  1800.0  2700.0  3200.0
+1500.0  1600.0  1900.0  2000.0  2600.0  3200.0
+1000.0  1300.0  2400.0  2600.0  2900.0  3300.0
+1300.0  1500.0  1900.0  2500.0  2700.0  3000.0
+1800.0  1900.0  2200.0  2600.0  2900.0  3300.0
+1300.0  1400.0  1700.0  1800.0  2700.0  3200.0
+1700.0  1800.0  2000.0  2500.0  2700.0  2900.0
+1800.0  2000.0  2300.0  2700.0  2800.0  3100.0
+1600.0  1700.0  2200.0  2800.0  2900.0  3100.0
+1800.0  2100.0  2800.0  2900.0  3200.0  3400.0
+1700.0  2100.0  2800.0  2900.0  3100.0  3400.0
+1900.0  2400.0  2700.0  2800.0  3400.0  3500.0
+1600.0  1700.0  2400.0  2700.0  2800.0  3200.0
+1600.0  1900.0  2200.0  2500.0  3000.0  3300.0
+1400.0  1500.0  2000.0  2500.0  2800.0  3100.0
+1200.0  1300.0  2100.0  2500.0  2700.0  3000.0
+1900.0  2200.0  2600.0  2800.0  3400.0  3500.0
+1500.0  1900.0  2600.0  2700.0  2900.0  3300.0
+1400.0  1500.0  2000.0  2100.0  2700.0  3100.0
+1600.0  1700.0  2100.0  2200.0  2600.0  3200.0
+1700.0  2200.0  2500.0  2700.0  3000.0  3100.0
+1800.0  2300.0  2500.0  2600.0  2900.0  3100.0
+1100.0  1300.0  2500.0  2700.0  2900.0  3200.0
+1400.0  1500.0  1900.0  2000.0  2600.0  3200.0
+1600.0  1700.0  2000.0  2100.0  2800.0  3300.0
+1300.0  1900.0  2300.0  2600.0  2700.0  3000.0
+1800.0  1900.0  2500.0  2700.0  2900.0  3100.0
+2100.0  2200.0  2700.0  3000.0  3100.0  3300.0
+2000.0  2100.0  2700.0  2900.0  3200.0  3400.0
+1500.0  1700.0  1800.0  2200.0  3200.0  3300.0
+1500.0  1800.0  2000.0  2700.0  3200.0  3300.0
+1800.0  1900.0  2100.0  2400.0  3100.0  3200.0
+1500.0  1600.0  2400.0  2500.0  3200.0  3300.0
+1400.0  1800.0  2400.0  2600.0  3300.0  3400.0
+1400.0  1800.0  2400.0  2600.0  3200.0  3400.0
+2300.0  2600.0  2800.0  3100.0  3300.0  3400.0
+2000.0  2100.0  2800.0  2900.0  3300.0  3400.0
+1400.0  1700.0  2600.0  2700.0  3200.0  3300.0
+1300.0  1700.0  2500.0  2700.0  3200.0  3300.0
+1500.0  1800.0  2200.0  2700.0  3000.0  3300.0
+1800.0  2000.0  2300.0  2500.0  2900.0  3300.0
+1300.0  1800.0  2400.0  2500.0  3200.0  3400.0
+1500.0  1900.0  2500.0  2600.0  3000.0  3300.0
+1700.0  1800.0  2700.0  2800.0  3200.0  3400.0
+1500.0  1800.0  2700.0  2800.0  3200.0  3400.0
+1500.0  1800.0  2700.0  2800.0  3300.0  3400.0
+1400.0  1600.0  2400.0  2500.0  3200.0  3300.0
+1600.0  1800.0  2400.0  2800.0  3100.0  3300.0
+1500.0  2100.0  2500.0  2600.0  3100.0  3300.0
+1500.0  1600.0  2500.0  2600.0  3000.0  3400.0
+1200.0  1900.0  2300.0  2500.0  3100.0  3300.0
+1500.0  1600.0  2300.0  2500.0  3200.0  3300.0
+1600.0  2300.0  2600.0  2800.0  3300.0  3400.0
+2100.0  2400.0  2500.0  2700.0  3200.0  3300.0
+1100.0  1800.0  2500.0  2600.0  2900.0  3200.0
+1400.0  1700.0  2100.0  2600.0  3000.0  3200.0
+1700.0  2000.0  2500.0  2600.0  3000.0  3100.0
+1100.0  1500.0  2500.0  2600.0  3100.0  3300.0
+1500.0  1600.0  2200.0  2400.0  2600.0  3200.0
+1600.0  1800.0  2300.0  2500.0  2900.0  3300.0
+1600.0  1700.0  2100.0  2300.0  3000.0  3200.0
+2000.0  2200.0  2600.0  2800.0  3300.0  3400.0
+1600.0  1700.0  1900.0  2400.0  3100.0  3300.0
+1200.0  1700.0  2300.0  2500.0  3100.0  3400.0
+1100.0  1600.0  1900.0  2200.0  3000.0  3100.0
+1400.0  1900.0  2300.0  2600.0  2900.0  3000.0
+1900.0  2200.0  2800.0  3000.0  3200.0  3400.0
+1400.0  1500.0  2200.0  2300.0  2700.0  3100.0
+1800.0  1900.0  2200.0  2600.0  3000.0  3300.0
+1700.0  1900.0  2200.0  2500.0  2700.0  3000.0
+1600.0  1800.0  2000.0  2400.0  2700.0  2800.0
+1900.0  2300.0  2700.0  2900.0  3100.0  3200.0
+1400.0  1500.0  2000.0  2400.0  2900.0  3000.0
+1800.0  2100.0  2200.0  2500.0  2700.0  3000.0
+1200.0  1300.0  1900.0  2500.0  3000.0  3100.0
+1100.0  1200.0  2500.0  2900.0  3000.0  3200.0
+1400.0  1500.0  1900.0  2000.0  2500.0  3100.0
+1400.0  1600.0  2000.0  2200.0  2500.0  3100.0
+1200.0  1700.0  2300.0  2700.0  3100.0  3300.0
+1900.0  2200.0  2300.0  2500.0  2700.0  3100.0
+1500.0  1600.0  2000.0  2100.0  2800.0  3300.0
+1500.0  1800.0  2000.0  2300.0  2600.0  2900.0
+2100.0  2200.0  2600.0  2700.0  3000.0  3100.0
+2100.0  2300.0  2700.0  2900.0  3200.0  3400.0
+1600.0  1700.0  1900.0  2000.0  2700.0  3100.0
+1300.0  1500.0  1800.0  1900.0  2500.0  3100.0
+1900.0  2500.0  2700.0  2900.0  3200.0  3300.0
+1200.0  1400.0  2000.0  2700.0  3200.0  3300.0
+1900.0  2500.0  2700.0  2800.0  3200.0  3300.0
+1200.0  1600.0  2200.0  2400.0  2900.0  3200.0
+2000.0  2200.0  2600.0  2700.0  3100.0  3400.0
+1500.0  1700.0  2000.0  2300.0  2600.0  3000.0
+1700.0  2100.0  2500.0  2700.0  3000.0  3100.0
+1800.0  2200.0  2500.0  2700.0  3000.0  3100.0
+2000.0  2400.0  2600.0  2900.0  3100.0  3200.0
+1700.0  2400.0  2500.0  2700.0  3100.0  3200.0
+1600.0  2000.0  2100.0  2600.0  3000.0  3100.0
+1500.0  2100.0  2400.0  2600.0  3000.0  3200.0
+1400.0  1600.0  2000.0  2600.0  3100.0  3200.0
+1500.0  1700.0  2000.0  2800.0  3100.0  3200.0
+1600.0  1700.0  2000.0  2700.0  3100.0  3200.0
+1400.0  2000.0  2300.0  2500.0  3000.0  3200.0
+1600.0  1800.0  2000.0  2300.0  3100.0  3300.0
+1500.0  1800.0  2300.0  2700.0  2900.0  3200.0
+1100.0  1400.0  2200.0  2300.0  3200.0  3300.0
+1800.0  2400.0  2800.0  2900.0  3200.0  3300.0
+1700.0  2400.0  2800.0  2900.0  3200.0  3300.0
+2000.0  2200.0  2800.0  3000.0  3400.0  3500.0
+1300.0  1400.0  2200.0  2900.0  3100.0  3200.0
+1200.0  1400.0  2300.0  2900.0  3100.0  3200.0
+1600.0  1900.0  2300.0  2600.0  2900.0  3300.0
+1700.0  2200.0  2300.0  2700.0  3100.0  3200.0
+1200.0  1700.0  2400.0  2700.0  3000.0  3300.0
+1500.0  1700.0  1900.0  2500.0  2900.0  3100.0
+1700.0  1800.0  2200.0  2600.0  2900.0  3300.0
+1300.0  1400.0  1900.0  2600.0  3000.0  3100.0
+1200.0  1400.0  2200.0  2500.0  2900.0  3300.0
+1500.0  1800.0  2000.0  2500.0  2900.0  3000.0
+1300.0  1400.0  2300.0  2500.0  2900.0  3300.0
+1700.0  2100.0  2300.0  2700.0  3000.0  3100.0
+1700.0  2100.0  2300.0  2800.0  3000.0  3100.0
+1200.0  1300.0  2100.0  2800.0  3200.0  3300.0
+1300.0  1600.0  2100.0  2600.0  2900.0  3100.0
+1300.0  1400.0  1800.0  2500.0  2800.0  3000.0
+1500.0  1700.0  2400.0  2600.0  2900.0  3000.0
+2100.0  2200.0  2500.0  2600.0  3000.0  3100.0
+2200.0  2300.0  2500.0  2700.0  3000.0  3200.0
+1400.0  1800.0  2000.0  2300.0  3200.0  3300.0
+1600.0  1700.0  2400.0  2700.0  3100.0  3200.0
+1600.0  1700.0  2500.0  2700.0  3000.0  3200.0
+1900.0  2500.0  2600.0  2800.0  3200.0  3300.0
+1200.0  1400.0  2600.0  2800.0  3000.0  3300.0
+1800.0  2300.0  2500.0  3000.0  3300.0  3400.0
+1200.0  1400.0  2200.0  2700.0  3200.0  3300.0
+1100.0  1400.0  2400.0  2500.0  3100.0  3400.0
+1100.0  1300.0  2400.0  2500.0  3200.0  3400.0
+1000.0  1400.0  2400.0  2500.0  3000.0  3300.0
+1800.0  1900.0  2400.0  2700.0  3200.0  3400.0
+1600.0  1700.0  2200.0  2500.0  2800.0  3300.0
+2000.0  2200.0  2400.0  2800.0  2900.0  3100.0
+1300.0  1800.0  2700.0  2800.0  3200.0  3400.0
+1800.0  2200.0  2700.0  3000.0  3400.0  3500.0
+1800.0  1900.0  2300.0  2600.0  2700.0  3000.0
+1900.0  2000.0  2400.0  2600.0  2900.0  3400.0
+1600.0  1700.0  2300.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2500.0  2700.0  3200.0  3300.0
+2100.0  2500.0  2800.0  3000.0  3200.0  3400.0
+1800.0  2000.0  2300.0  2400.0  3000.0  3100.0
+2300.0  2400.0  2600.0  2900.0  3100.0  3300.0
+1600.0  1800.0  2400.0  2500.0  3000.0  3100.0
+2100.0  2500.0  2900.0  3100.0  3200.0  3300.0
+1600.0  1900.0  2500.0  2900.0  3100.0  3300.0
+1500.0  1800.0  2300.0  2400.0  3200.0  3400.0
+1300.0  1500.0  2700.0  2800.0  3100.0  3300.0
+1200.0  1500.0  2600.0  2700.0  3200.0  3300.0
+1000.0  1500.0  2700.0  2800.0  3200.0  3300.0
+1100.0  1600.0  2600.0  2700.0  3200.0  3300.0
+1500.0  1700.0  2600.0  2700.0  3000.0  3300.0
+1100.0  1700.0  2800.0  2900.0  3200.0  3400.0
+1300.0  1700.0  2300.0  2500.0  3300.0  3400.0
+1700.0  2100.0  2400.0  2500.0  3200.0  3300.0
+1500.0  1800.0  2100.0  2400.0  3300.0  3400.0
+2000.0  2100.0  2400.0  2600.0  2800.0  3100.0
+1600.0  1700.0  2300.0  2800.0  3100.0  3300.0
+1900.0  2100.0  2800.0  3000.0  3300.0  3400.0
+2000.0  2100.0  2300.0  2600.0  2900.0  3200.0
+1100.0  1500.0  2500.0  2700.0  2900.0  3300.0
+1600.0  1800.0  2200.0  2500.0  2700.0  2800.0
+2000.0  2200.0  2500.0  2600.0  3100.0  3200.0
+1400.0  1600.0  2100.0  2900.0  3100.0  3200.0
+1900.0  2400.0  2800.0  3000.0  3200.0  3300.0
+2000.0  2300.0  2500.0  2700.0  2900.0  3200.0
+1700.0  2100.0  2300.0  2800.0  3200.0  3300.0
+1400.0  2000.0  2300.0  2500.0  3100.0  3300.0
+2000.0  2500.0  2600.0  3000.0  3200.0  3300.0
+1500.0  1700.0  2500.0  2600.0  3000.0  3400.0
+1100.0  2000.0  2500.0  2700.0  3200.0  3300.0
+1400.0  1600.0  2600.0  2900.0  3100.0  3400.0
+1800.0  2300.0  2800.0  3000.0  3200.0  3300.0
+1700.0  2000.0  2100.0  2300.0  3300.0  3400.0
+1400.0  1700.0  1800.0  2300.0  3300.0  3400.0
+1400.0  1500.0  2300.0  2500.0  3000.0  3400.0
+1400.0  1700.0  2600.0  2700.0  3100.0  3200.0
+1500.0  1700.0  2600.0  2700.0  3200.0  3300.0
+1600.0  1800.0  2600.0  2700.0  3100.0  3300.0
+1200.0  1400.0  1500.0  2200.0  3100.0  3200.0
+1500.0  1600.0  2100.0  2400.0  2700.0  3200.0
+1000.0  1500.0  2600.0  2700.0  3000.0  3300.0
+1200.0  1500.0  1600.0  2100.0  3100.0  3200.0
+1800.0  2200.0  2600.0  3000.0  3400.0  3500.0
+1000.0  2300.0  2600.0  2700.0  3200.0  3300.0
+1400.0  1600.0  2100.0  2500.0  2800.0  3200.0
+1300.0  1900.0  2300.0  2500.0  2900.0  3300.0
+1500.0  1600.0  2400.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2500.0  2800.0  3100.0  3200.0
+1000.0  2100.0  2500.0  2600.0  3100.0  3400.0
+1700.0  1800.0  2100.0  2400.0  3000.0  3100.0
+2200.0  2300.0  2600.0  2700.0  3000.0  3300.0
+1900.0  2000.0  2700.0  2800.0  3300.0  3400.0
+1500.0  1700.0  2400.0  2500.0  2900.0  3100.0
+1100.0  1600.0  2800.0  2900.0  3200.0  3300.0
+2000.0  2600.0  2800.0  3000.0  3400.0  3500.0
+1900.0  2500.0  2800.0  3100.0  3400.0  3500.0
+1200.0  1700.0  2700.0  2800.0  3200.0  3400.0
+1300.0  1600.0  2700.0  2800.0  3100.0  3400.0
+1500.0  1700.0  2700.0  2800.0  3100.0  3400.0
+1300.0  1400.0  2500.0  2800.0  3200.0  3400.0
+1700.0  2000.0  2700.0  2800.0  3300.0  3400.0
+1800.0  1900.0  2600.0  2700.0  3300.0  3400.0
+1100.0  1800.0  2700.0  2800.0  3200.0  3300.0
+2100.0  2600.0  2700.0  3000.0  3300.0  3400.0
+1300.0  1600.0  1800.0  2100.0  2900.0  3000.0
+1300.0  1500.0  2200.0  2400.0  3100.0  3400.0
+1200.0  1500.0  1700.0  2000.0  3000.0  3100.0
+1200.0  1500.0  1700.0  2100.0  3000.0  3100.0
+1300.0  2000.0  2200.0  2400.0  2700.0  3000.0
+1500.0  1800.0  2100.0  2300.0  3300.0  3400.0
+1100.0  1600.0  1800.0  2200.0  3000.0  3100.0
+1000.0  1800.0  2100.0  2400.0  3000.0  3100.0
+1500.0  1600.0  2300.0  2400.0  2900.0  3400.0
+1400.0  1600.0  1800.0  2100.0  2900.0  3000.0
+1100.0  1500.0  2100.0  2200.0  3100.0  3200.0
+1300.0  1700.0  1800.0  2200.0  3000.0  3100.0
+1500.0  1700.0  2100.0  2300.0  2700.0  2900.0
+1100.0  1700.0  1900.0  2100.0  2900.0  3000.0
+1400.0  1700.0  2100.0  2400.0  2900.0  3200.0
+1300.0  1600.0  1800.0  2300.0  3000.0  3100.0
+1200.0  1500.0  1700.0  2300.0  3000.0  3100.0
+1600.0  1800.0  1900.0  2300.0  3000.0  3100.0
+1700.0  2200.0  2600.0  2900.0  3100.0  3300.0
+1900.0  2400.0  2500.0  2700.0  2900.0  3100.0
+1800.0  2000.0  2100.0  2400.0  3100.0  3200.0
+1700.0  2400.0  2700.0  2800.0  3000.0  3200.0
+1800.0  1900.0  2300.0  2600.0  2800.0  3300.0
+1300.0  1900.0  2500.0  2600.0  3200.0  3400.0
+1400.0  1600.0  2300.0  2400.0  2800.0  3100.0
+1900.0  2000.0  2300.0  2700.0  3000.0  3300.0
+1700.0  1800.0  2400.0  2700.0  3200.0  3400.0
+1800.0  2000.0  2300.0  2600.0  2900.0  3300.0
+2100.0  2300.0  2600.0  2700.0  3300.0  3400.0
+1400.0  1600.0  2200.0  2400.0  3200.0  3300.0
+1300.0  1600.0  1800.0  2200.0  2800.0  2900.0
+1500.0  1700.0  1900.0  2600.0  2800.0  3000.0
+1700.0  2200.0  2500.0  2600.0  3100.0  3300.0
+1200.0  1700.0  1800.0  2100.0  3000.0  3100.0
+1100.0  1800.0  2500.0  2600.0  3300.0  3400.0
+1100.0  1900.0  2100.0  2300.0  2900.0  3000.0
+1200.0  1700.0  2400.0  2600.0  3100.0  3400.0
+1100.0  1700.0  2600.0  2700.0  3000.0  3300.0
+1000.0  1700.0  2700.0  2800.0  3200.0  3400.0
+1100.0  1900.0  2200.0  2300.0  3200.0  3300.0
+1300.0  1900.0  2300.0  2500.0  3000.0  3300.0
+1200.0  1600.0  2600.0  2700.0  3100.0  3400.0
+1300.0  1600.0  1800.0  2400.0  3000.0  3200.0
+1400.0  1700.0  1800.0  2100.0  3200.0  3400.0
+1000.0  1500.0  2300.0  2400.0  3200.0  3400.0
+900.0  1700.0  2600.0  2700.0  3300.0  3400.0
+1100.0  1400.0  2500.0  2700.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2500.0  2800.0  2900.0
+2100.0  2300.0  2700.0  2900.0  3400.0  3500.0
+2100.0  2200.0  2300.0  2400.0  3000.0  3300.0
+1800.0  2000.0  2400.0  2500.0  2800.0  3000.0
+1700.0  1900.0  2300.0  2500.0  2700.0  3000.0
+1300.0  1400.0  2300.0  2900.0  3100.0  3200.0
+2100.0  2300.0  2600.0  2900.0  3100.0  3200.0
+1400.0  1800.0  2200.0  2300.0  3200.0  3400.0
+2100.0  2500.0  2900.0  3200.0  3400.0  3500.0
+1700.0  1900.0  2100.0  2400.0  3200.0  3400.0
+1600.0  1700.0  2300.0  2600.0  2800.0  2900.0
+1800.0  2000.0  2300.0  2700.0  2800.0  3000.0
+1900.0  2300.0  2600.0  2800.0  3000.0  3100.0
+1300.0  1600.0  2200.0  2600.0  3100.0  3200.0
+1500.0  1600.0  2400.0  2500.0  2900.0  3400.0
+1600.0  1800.0  2000.0  2700.0  3100.0  3200.0
+1000.0  1800.0  2600.0  2700.0  3200.0  3400.0
+900.0  1800.0  2500.0  2600.0  3300.0  3400.0
+1300.0  2200.0  2300.0  2700.0  3200.0  3300.0
+1200.0  2000.0  2300.0  2500.0  3300.0  3400.0
+1100.0  1500.0  2400.0  2500.0  3100.0  3400.0
+1300.0  1700.0  1900.0  2100.0  3000.0  3100.0
+2000.0  2100.0  2500.0  2600.0  3300.0  3500.0
+1500.0  1800.0  2000.0  2500.0  3300.0  3400.0
+2000.0  2100.0  2800.0  2900.0  3100.0  3300.0
+2300.0  2400.0  2600.0  2800.0  3200.0  3300.0
+1400.0  1900.0  2200.0  2300.0  3100.0  3200.0
+1500.0  1900.0  2600.0  2700.0  3200.0  3300.0
+1500.0  1600.0  2200.0  2600.0  3100.0  3400.0
+1700.0  1800.0  2500.0  2700.0  3300.0  3400.0
+1100.0  1600.0  2400.0  2500.0  3300.0  3400.0
+900.0  1600.0  2600.0  2700.0  3300.0  3400.0
+1400.0  1500.0  2200.0  2600.0  3200.0  3400.0
+1200.0  2000.0  2400.0  2500.0  2700.0  3200.0
+1300.0  1500.0  2500.0  2600.0  3200.0  3300.0
+1500.0  1600.0  2300.0  2600.0  3200.0  3400.0
+1300.0  2000.0  2300.0  2800.0  3000.0  3200.0
+2000.0  2100.0  2600.0  2700.0  3000.0  3100.0
+2000.0  2200.0  2600.0  2700.0  3000.0  3100.0
+2100.0  2200.0  2800.0  2900.0  3100.0  3200.0
+1900.0  2100.0  2500.0  2600.0  3000.0  3100.0
+1900.0  2100.0  2300.0  2500.0  2800.0  2900.0
+1800.0  2000.0  2600.0  2700.0  3000.0  3400.0
+1400.0  1700.0  1800.0  2500.0  2800.0  3200.0
+1300.0  1800.0  2200.0  2300.0  3200.0  3400.0
+1400.0  1600.0  1700.0  2200.0  3200.0  3400.0
+1400.0  1500.0  1600.0  2100.0  3200.0  3400.0
+1700.0  2100.0  2300.0  2500.0  3300.0  3400.0
+1600.0  2000.0  2600.0  2800.0  3200.0  3400.0
+1400.0  1600.0  2700.0  2800.0  3000.0  3300.0
+1400.0  1500.0  1600.0  2200.0  3300.0  3400.0
+1600.0  1700.0  2500.0  2600.0  3300.0  3400.0
+1000.0  1500.0  2300.0  2400.0  3000.0  3100.0
+1400.0  1500.0  1700.0  1800.0  3200.0  3300.0
+1600.0  2000.0  2300.0  2500.0  2800.0  3100.0
+1900.0  2500.0  2600.0  2900.0  3400.0  3500.0
+1800.0  1900.0  2500.0  2600.0  3300.0  3500.0
+1500.0  1900.0  2200.0  2300.0  3200.0  3300.0
+1900.0  2200.0  2500.0  2600.0  3300.0  3400.0
+1400.0  2000.0  2300.0  2600.0  3100.0  3300.0
+1800.0  1900.0  2300.0  2400.0  3200.0  3500.0
+1100.0  1900.0  2500.0  2600.0  2900.0  3000.0
+1600.0  1700.0  2300.0  2400.0  2900.0  3000.0
+1700.0  2300.0  2500.0  2700.0  3000.0  3100.0
+2100.0  2200.0  2700.0  2900.0  3100.0  3400.0
+1400.0  1900.0  2300.0  2600.0  2800.0  2900.0
+1800.0  2000.0  2200.0  2400.0  2600.0  2900.0
+1400.0  2100.0  2500.0  2600.0  2900.0  3100.0
+1700.0  1900.0  2400.0  2800.0  3200.0  3400.0
+1000.0  1500.0  2300.0  2400.0  3000.0  3300.0
+1500.0  2000.0  2300.0  2800.0  3200.0  3300.0
+1900.0  2000.0  2300.0  2600.0  3100.0  3400.0
+1300.0  1500.0  2400.0  2600.0  3300.0  3400.0
+2100.0  2500.0  2900.0  3100.0  3200.0  3400.0
+1400.0  1700.0  1800.0  2400.0  3200.0  3300.0
+1400.0  1500.0  2300.0  2600.0  3100.0  3400.0
+1000.0  1900.0  2600.0  2700.0  3000.0  3100.0
+1100.0  1800.0  2500.0  2700.0  3200.0  3300.0
+1700.0  1800.0  2200.0  2700.0  2800.0  3200.0
+2000.0  2200.0  2700.0  2800.0  3100.0  3200.0
+1300.0  2100.0  2400.0  2500.0  2900.0  3100.0
+1300.0  2000.0  2400.0  2500.0  2800.0  3000.0
+1500.0  2100.0  2500.0  2600.0  2900.0  3100.0
+1700.0  2200.0  2500.0  2700.0  3000.0  3200.0
+1600.0  2100.0  2500.0  2600.0  3000.0  3100.0
+1700.0  2200.0  2500.0  2600.0  3000.0  3200.0
+1800.0  2200.0  2300.0  2600.0  3000.0  3200.0
+1300.0  1500.0  1700.0  2100.0  3300.0  3400.0
+1300.0  1500.0  1700.0  2000.0  3300.0  3400.0
+1300.0  1900.0  2700.0  2800.0  3200.0  3400.0
+1700.0  2500.0  2700.0  2900.0  3300.0  3400.0
+1100.0  1700.0  2100.0  2200.0  3300.0  3400.0
+1000.0  1800.0  2700.0  2900.0  3300.0  3400.0
+1500.0  1600.0  2500.0  2600.0  3200.0  3300.0
+1100.0  1900.0  2600.0  2800.0  3000.0  3100.0
+1300.0  1500.0  2400.0  2500.0  3200.0  3300.0
+1700.0  2100.0  2300.0  2400.0  2800.0  3300.0
+1300.0  1500.0  1700.0  1800.0  3200.0  3400.0
+2000.0  2100.0  2400.0  2700.0  2900.0  3300.0
+1400.0  1500.0  2500.0  2600.0  3000.0  3200.0
+1400.0  1500.0  2000.0  2900.0  3300.0  3400.0
+1300.0  1500.0  2600.0  2700.0  3100.0  3200.0
+1100.0  1300.0  2700.0  2800.0  3200.0  3300.0
+1100.0  1300.0  2500.0  2600.0  2900.0  3100.0
+1900.0  2300.0  2400.0  2600.0  2700.0  3100.0
+1300.0  2100.0  2200.0  2600.0  3200.0  3300.0
+1100.0  1800.0  2400.0  2500.0  2900.0  3100.0
+1000.0  1800.0  2200.0  2300.0  3200.0  3300.0
+1500.0  1700.0  1800.0  2600.0  3200.0  3400.0
+1500.0  2000.0  2400.0  2600.0  2700.0  3100.0
+2000.0  2100.0  2300.0  2500.0  2700.0  3300.0
+1000.0  1500.0  2700.0  2800.0  3300.0  3400.0
diff --git a/codec2/branches/0.7/unittest/mksine.c b/codec2/branches/0.7/unittest/mksine.c
new file mode 100644 (file)
index 0000000..8c4cea2
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+  mksine.c
+  David Rowe
+  10 Nov 2010
+
+  Creates a file of sine wave samples.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#define TWO_PI     6.283185307
+#define FS         8000.0
+#define AMP        10000.0
+
+int main(int argc, char *argv[]) {
+    FILE *f;
+    int   i,n;
+    float freq, length;
+    short *buf;
+
+    if (argc != 4) {
+       printf("usage: %s outputFile frequencyHz lengthSecs\n", argv[0]);
+       exit(1);
+    }
+
+    f = fopen(argv[1] ,"wb");
+    freq = atof(argv[2]);
+    length = atof(argv[3]);
+    n = length*FS;
+    buf = (short*)malloc(sizeof(short)*n);
+    assert(buf != NULL);
+
+    for(i=0; i<n; i++)
+       buf[i] = AMP*cos(freq*i*(TWO_PI/FS));
+
+    fwrite(buf, sizeof(short), n, f);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/polar2rect.c b/codec2/branches/0.7/unittest/polar2rect.c
new file mode 100644 (file)
index 0000000..ecbe6b2
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+  polar2rect.c
+  David Rowe 28 July 2013
+
+  Convert a file of sparse phases in polar (angle) format to a file in rect
+  format.
+*/
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef struct {
+    float real;
+    float imag;
+} COMP;
+
+int main(int argc, char *argv[]) {
+    FILE *fpolar;
+    FILE *frect;
+    float polar;
+    COMP  rect;
+
+    if (argc != 3) {
+       printf("usage: %s polarFile rectFile\n", argv[0]);
+       exit(0);
+    }
+
+    fpolar = fopen(argv[1], "rb");
+    assert(fpolar != NULL);
+    frect = fopen(argv[2], "wb");
+    assert(frect != NULL);
+
+    while (fread(&polar, sizeof(float), 1, fpolar) != 0) {
+       if (polar == 0.0) {
+           /* this values indicates the VQ training should ignore
+              this vector element.  It's not a valid phase as it
+              doesn't have mangitude of 1.0 */
+           rect.real = 0.0;
+           rect.imag = 0.0;
+       }
+       else {
+           rect.real = cos(polar);
+           rect.imag = sin(polar);
+       }
+       fwrite(&rect, sizeof(COMP), 1, frect);
+    }
+
+    fclose(fpolar);
+    fclose(frect);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/pre.c b/codec2/branches/0.7/unittest/pre.c
new file mode 100644 (file)
index 0000000..0a5a2a1
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+   pre.c
+   David Rowe
+   Sep 26 2012
+
+   Takes audio from a file, pre-emphasises, and sends to output file.
+*/
+
+#include <assert.h>
+#include <math.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "lpc.h"
+
+#define N 80
+
+int main(int argc, char*argv[]) {
+    FILE  *fin, *fout;
+    short  buf[N];
+    float  Sn[N], Sn_pre[N];
+    float  pre_mem = 0.0;
+    int    i;
+
+    if (argc != 3) {
+       printf("usage: pre InputRawSpeechFile OutputRawSpeechFile\n");
+       printf("e.g    pre input.raw output.raw");
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+       fprintf(stderr, "Error opening input speech 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 speech file: %s: %s.\n",
+         argv[2], strerror(errno));
+       exit(1);
+    }
+
+    while(fread(buf, sizeof(short), N, fin) == N) {
+       for(i=0; i<N; i++)
+           Sn[i] = buf[i];
+       pre_emp(Sn_pre, Sn, &pre_mem, N);
+       for(i=0; i<N; i++)
+           buf[i] = Sn_pre[i];
+       fwrite(buf, sizeof(short), N, fout);
+    }
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/raw2h.c b/codec2/branches/0.7/unittest/raw2h.c
new file mode 100644 (file)
index 0000000..cb17f7c
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+  raw2h.c
+  David Rowe
+  10 April 2013
+
+  Converts a raw sound file to a C header file.  Used for generating arrays to
+  test Codec2 on embedded systems without disk I/O.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char *argv[]) {
+    FILE *fraw, *fheader;
+    int   i, samples, ret;
+    short sam;
+
+    if (argc != 5) {
+       printf("usage: %s inputRawFile outputHeaderFile arrayName samples\n", argv[0]);
+       exit(1);
+    }
+
+    fraw = fopen(argv[1] ,"rb");
+    assert(fraw != NULL);
+    fheader = fopen(argv[2],"wt");
+    assert(fheader != NULL);
+    samples = atoi(argv[4]);
+
+    fprintf(fheader, "short %s[] = {\n", argv[3]);
+    for(i=0; i<samples-1; i++) {
+       ret = fread(&sam, sizeof(short), 1, fraw);
+        assert(ret == 1);
+        fprintf(fheader, "%d,\n", sam);
+    }
+    ret = fread(&sam, sizeof(short), 1, fraw);
+    assert(ret == 1);
+    fprintf(fheader, "%d\n};\n", sam);
+
+    fclose(fraw);
+    fclose(fheader);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/run_tests.sh b/codec2/branches/0.7/unittest/run_tests.sh
new file mode 100644 (file)
index 0000000..06e7b6b
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# verbose, skittish
+set -ex
+
+# run valgrind?
+VG="valgrind --error-exitcode=149 --leak-check=full --show-reachable=yes"
+
+# make sure we're up-to-date
+make
+
+
+# runs, not certaion wht it does yet
+${VG} ./tcodec2
+${VG} ./tinterp
+${VG} ./tquant
+
+# these fail, missing arguments
+${VG} ./extract
+${VG} ./genlsp
+${VG} ./genres
+${VG} ./scalarlsptest
+${VG} ./tnlp
+${VG} ./vq_train_jvm
+${VG} ./vqtrain
+${VG} ./vqtrainjnd
+
diff --git a/codec2/branches/0.7/unittest/scalarlsptest.c b/codec2/branches/0.7/unittest/scalarlsptest.c
new file mode 100644 (file)
index 0000000..d2d46c5
--- /dev/null
@@ -0,0 +1,110 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: scalarlsptest.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 8/2/12
+
+  Test Scalar LSP quantiser, output variance of quantisation error.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "defines.h"
+#include "quantise.h"
+
+/*---------------------------------------------------------------------------*\
+
+                                MAIN
+
+\*---------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+    FILE *ftrain;       /* LSP training data text file */
+    float lsp[LPC_ORD];    /* LSP input vector in rads */
+    float lsp_hz[LPC_ORD]; /* LSP input vector in Hz */
+    int vectors;           /* number LSP vectors processed */
+    int k,m;             /* LSP vector order and codebook size */
+    float  wt[1];        /* weighting (not used here for scalars) */
+    const float *cb;           /* LSP quantiser codebook */
+    int i, ret;
+    float  total_se;
+
+    if (argc < 2) {
+       printf("usage: %s InputFile\n", argv[0]);
+       exit(1);
+    }
+
+    if ((ftrain = fopen(argv[1],"rt")) == NULL) {
+       printf("Error opening input file: %s\n",argv[1]);
+       exit(0);
+    }
+
+    total_se = 0.0;
+    vectors = 0;
+    wt[0] = 1.0;
+
+    /* Main loop */
+
+    while(!feof(ftrain)) {
+
+       /* Read LSP input vector speech */
+
+       for (i=0; i<LPC_ORD; i++) {
+           ret = fscanf(ftrain, "%f ", &lsp[i]);
+            assert(ret == 1);
+       }
+       vectors++;
+       if ((vectors % 1000) == 0)
+           printf("\r%d vectors", vectors);
+
+       /* convert from radians to Hz so we can use human readable
+          frequencies */
+
+       for(i=0; i<LPC_ORD; i++)
+           lsp_hz[i] = (4000.0/PI)*lsp[i];
+
+       /* simple uniform scalar quantisers */
+
+       for(i=0; i<LPC_ORD; i++) {
+           k = lsp_cb[i].k;
+           m = lsp_cb[i].m;
+           cb = lsp_cb[i].cb;
+           #if 1
+              quantise(cb, &lsp_hz[i], wt, k, m, &total_se);
+           #else
+               int index = quantise(cb, &lsp_hz[i], wt, k, m, &total_se);
+              printf("k %d m %d lsp[%d] %f %f se %f\n", k,m,i,lsp_hz[i], cb[index],se);
+            #endif
+       }
+       //printf("total se %f\n", total_se);
+       //exit(0);
+    }
+
+    fclose(ftrain);
+
+    printf("\n variance = %f\n", ((PI*PI)/(4000.0*4000.0))*total_se/vectors);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/sd.c b/codec2/branches/0.7/unittest/sd.c
new file mode 100644 (file)
index 0000000..74bec67
--- /dev/null
@@ -0,0 +1,83 @@
+/*--------------------------------------------------------------------------*\
+
+       FILE........: sd.c
+       AUTHOR......: David Rowe
+       DATE CREATED: 20/7/93
+
+       Function to determine spectral distortion between two sets of LPCs.
+
+\*--------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define        MAX_N   2048    /* maximum DFT size     */
+
+#include <math.h>
+#include "four1.h"
+#include "comp.h"
+#include "sd.h"
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: spectral_dist()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 20/7/93
+
+       This function returns the soectral distoertion between two
+       sets of LPCs.
+
+\*---------------------------------------------------------------------------*/
+
+float spectral_dist(float ak1[], float ak2[], int p, int n)
+/*  float ak1[];       unquantised set of p+1 LPCs                      */
+/*  float ak2[];       quantised set of p+1 LPCs                        */
+/*  int p;             LP order                                         */
+/*  int n;             DFT size to use for SD calculations (power of 2) */
+{
+    COMP  A1[MAX_N];   /* DFT of ak1[]                 */
+    COMP  A2[MAX_N];   /* DFT of ak2[]                 */
+    float P1,P2;       /* power of current bin         */
+    float sd;
+    int i;
+
+    for(i=0; i<n; i++) {
+       A1[i].real = 0.0;
+       A1[i].imag = 0.0;
+       A2[i].real = 0.0;
+       A2[i].imag = 0.0;
+    }
+
+    for(i=0; i<p+1; i++) {
+       A1[i].real = ak1[i];
+       A2[i].real = ak2[i];
+    }
+
+    four1(&A1[-1].imag,n,-1);
+    four1(&A2[-1].imag,n,-1);
+
+    sd = 0.0;
+    for(i=0; i<n; i++) {
+       P1 = A1[i].real*A1[i].real + A1[i].imag*A1[i].imag;
+       P2 = A2[i].real*A2[i].real + A2[i].imag*A2[i].imag;
+       sd += pow(log10(P2/P1),2.0);
+    }
+    sd = 10.0*sqrt(sd/n);      /* sd in dB */
+
+    return(sd);
+}
diff --git a/codec2/branches/0.7/unittest/sd.h b/codec2/branches/0.7/unittest/sd.h
new file mode 100644 (file)
index 0000000..c92e0f7
--- /dev/null
@@ -0,0 +1,33 @@
+/*--------------------------------------------------------------------------*\
+
+       FILE........: sd.h
+       AUTHOR......: David Rowe
+       DATE CREATED: 22/7/93
+
+       Function to determine spectral distortion between two sets of LPCs.
+
+\*--------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SD__
+#define __SD__
+
+float spectral_dist(float ak1[], float ak2[], int p, int n);
+
+#endif /* __SD__  */
diff --git a/codec2/branches/0.7/unittest/speexlsptest.c b/codec2/branches/0.7/unittest/speexlsptest.c
new file mode 100644 (file)
index 0000000..5cfc805
--- /dev/null
@@ -0,0 +1,176 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: speexlsptest.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/8/09
+
+  Test LPC to LSP conversion and quantisation using Speex LSP quantiser.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <lpc.h>
+#include <lsp.h>
+#include <sd.h>
+
+#define N 160
+#define P 10
+
+#define LPC_FLOOR 0.0002        /* autocorrelation floor */
+#define LSP_DELTA1 0.2          /* grid spacing for LSP root searches */
+#define NDFT    256             /* DFT size for SD calculation          */
+
+/* Speex lag window */
+
+const float lag_window[11] = {
+   1.00000, 0.99716, 0.98869, 0.97474, 0.95554, 0.93140, 0.90273, 0.86998,
+   0.83367, 0.79434, 0.75258
+};
+
+/*---------------------------------------------------------------------------*\
+
+  find_aks_for_lsp()
+
+  This function takes a frame of samples, and determines the linear
+  prediction coefficients for that frame of samples.  Modified version of
+  find_aks from lpc.c to include autocorrelation noise floor and lag window
+  to match Speex processing steps prior to LSP conversion.
+
+\*---------------------------------------------------------------------------*/
+
+void find_aks_for_lsp(
+  float Sn[],  /* Nsam samples with order sample memory */
+  float a[],   /* order+1 LPCs with first coeff 1.0 */
+  int Nsam,    /* number of input speech samples */
+  int order,   /* order of the LPC analysis */
+  float *E     /* residual energy */
+)
+{
+  float Wn[N]; /* windowed frame of Nsam speech samples */
+  float R[P+1];        /* order+1 autocorrelation values of Sn[] */
+  int i;
+
+  hanning_window(Sn,Wn,Nsam);
+
+  autocorrelate(Wn,R,Nsam,order);
+  R[0] += LPC_FLOOR;
+  assert(order == 10); /* lag window only defined for order == 10 */
+  for(i=0; i<=order; i++)
+      R[i] *= lag_window[i];
+  levinson_durbin(R,a,order);
+
+  *E = 0.0;
+  for(i=0; i<=order; i++)
+    *E += a[i]*R[i];
+  if (*E < 0.0)
+    *E = 1E-12;
+}
+
+/*---------------------------------------------------------------------------*\
+
+                                MAIN
+
+\*---------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+  FILE *fin;            /* input speech files */
+  short buf[N];         /* buffer of 16 bit speech samples */
+  float Sn[P+N];        /* input speech samples */
+  float E;
+  float ak[P+1];        /* LP coeffs */
+  float ak_[P+1];       /* quantised LP coeffs */
+  float lsp[P];
+  float lsp_[P];        /* quantised LSPs */
+  int   roots;          /* number of LSP roots found */
+  int frames;           /* frames processed so far */
+  int i;                /* loop variables */
+
+  SpeexBits bits;
+
+  float  sd;            /* SD for this frame                */
+  float  totsd;         /* accumulated SD so far            */
+  int    gt2,gt4;       /* number of frames > 2 and 4 dB SD */
+  int    unstables;     /* number of unstable LSP frames    */
+
+  if (argc < 2) {
+    printf("usage: %s InputFile\n", argv[0]);
+    exit(0);
+  }
+
+  /* Open files */
+
+  if ((fin = fopen(argv[1],"rb")) == NULL) {
+    printf("Error opening input file: %s\n",argv[1]);
+    exit(0);
+  }
+
+  /* Initialise */
+
+  frames = 0;
+  for(i=0; i<P; i++) {
+    Sn[i] = 0.0;
+  }
+  ak_[0] = 1.0;
+
+  speex_bits_init(&bits);
+
+  totsd = 0.0;
+  unstables = 0;
+  gt2 = 0; gt4 = 0;
+
+  /* Main loop */
+
+  while( (fread(buf,sizeof(short),N,fin)) == N) {
+    frames++;
+    for(i=0; i<N; i++)
+      Sn[P+i] = (float)buf[i];
+
+    /* convert to LSP domain and back */
+
+    find_aks(&Sn[P], ak, N, P, &E);
+    roots = lpc_to_lsp(&ak[1], P , lsp, 10, LSP_DELTA1, NULL);
+    if (roots == P) {
+
+        speex_bits_reset(&bits);
+       lsp_quant_lbr(lsp, lsp_, P, &bits);
+       lsp_to_lpc(lsp_, &ak_[1], P, NULL);
+
+       /* measure spectral distortion */
+       sd = spectral_dist(ak, ak_, P, NDFT);
+       if (sd > 2.0) gt2++;
+       if (sd > 4.0) gt4++;
+       totsd += sd;
+    }
+    else
+       unstables++;
+  }
+
+  fclose(fin);
+
+  printf("frames = %d Av sd = %3.2f dB", frames, totsd/frames);
+  printf("  >2 dB %3.2f%%  >4 dB %3.2f%%  unstables: %d\n",gt2*100.0/frames,
+         gt4*100.0/frames, unstables);
+
+  return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/speexnoisesup.c b/codec2/branches/0.7/unittest/speexnoisesup.c
new file mode 100644 (file)
index 0000000..f76d5e2
--- /dev/null
@@ -0,0 +1,59 @@
+/*----------------------------------------------------------------------------*\
+
+  FILE....: speexnoisesup.c
+  AUTHOR..: David Rowe
+  CREATED.: Sun 22 June 2014
+
+  File I/O based test program for Speex pre-processor, used for
+  initial testing of Speech noise supression.
+
+\*----------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdint.h>
+#include <speex/speex_preprocess.h>
+
+#define    N          80
+#define    FS       8000
+
+int main(int argc, char *argv[]) {
+    FILE *fin, *fout;
+    short buf[N];
+    SpeexPreprocessState *st;
+
+    if (argc < 2) {
+       printf("usage: %s InFile OutFile\n", argv[0]);
+       exit(0);
+    }
+
+    if (strcmp(argv[1], "-")  == 0) fin = stdin;
+    else if ( (fin = fopen(argv[1],"rb")) == NULL ) {
+        fprintf(stderr, "Error opening %s\n", argv[1]);
+        exit(1);
+    }
+
+    if (strcmp(argv[2], "-") == 0) fout = stdout;
+    else if ((fout = fopen(argv[2],"wb")) == NULL) {
+       fprintf(stderr, "Error opening %s\n", argv[2]);
+       exit(1);
+    }
+
+    st = speex_preprocess_state_init(N, FS);
+
+    while(fread(buf, sizeof(short), N, fin) == N) {
+       speex_preprocess_run(st, buf);
+       fwrite(buf, sizeof(short), N, fout);
+        if (fin == stdin) fflush(stdin);
+        if (fout == stdout) fflush(stdout);
+    }
+
+    speex_preprocess_state_destroy(st);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/t16_8.c b/codec2/branches/0.7/unittest/t16_8.c
new file mode 100644 (file)
index 0000000..f6d83ba
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+   t16_8.c
+   David Rowe
+   May 10 2012
+
+   Unit test for 16 to 8 kHz sample rate conversion functions.  I
+   evaluated output by plotting using Octave and looking for jaggies:
+
+     pl("../unittest/out16.raw",1,3000)
+     pl("../unittest/out8.raw",1,3000)
+
+   Listening to it also shows up anything nasty:
+
+     $ play -s -2 -r 16000 out16.raw
+     $ play -s -2 -r 8000 out8.raw
+
+  */
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "codec2_fdmdv.h"
+
+#define N8                        160 /* procssing buffer size at 8 kHz */
+#define N16             (N8*FDMDV_OS)
+#define FRAMES                     50
+#define TWO_PI            6.283185307
+#define FS                      16000
+
+#define SINE
+
+int main() {
+    float in8k[FDMDV_OS_TAPS_8K + N8];
+    float out16k[N16];
+    short out16k_short[N16];
+    FILE *f16;
+
+    float in16k[FDMDV_OS_TAPS_16K + N16];
+    float out8k[N16];
+    short out8k_short[N8];
+    FILE *f8;
+
+    int i,f,t,t1;
+    float freq = 800.0;
+
+    f16 = fopen("out16.raw", "wb");
+    assert(f16 != NULL);
+    f8 = fopen("out8.raw", "wb");
+    assert(f8 != NULL);
+
+    /* clear filter memories */
+
+    for(i=0; i<FDMDV_OS_TAPS_8K; i++)
+       in8k[i] = 0.0;
+    for(i=0; i<FDMDV_OS_TAPS_16K; i++)
+       in16k[i] = 0.0;
+
+    t = t1 = 0;
+    for(f=0; f<FRAMES; f++) {
+
+#ifdef DC
+       for(i=0; i<N8; i++)
+           in8k[FDMDV_OS_TAPS_8K+i] = 16000.0;
+#endif
+#ifdef SINE
+       for(i=0; i<N8; i++,t++)
+           in8k[FDMDV_OS_TAPS_8K+i] = 16000.0*cos(TWO_PI*t*freq/FS);
+#endif
+
+       /* upsample  */
+
+       fdmdv_8_to_16(out16k, &in8k[FDMDV_OS_TAPS_8K], N8);
+       /*
+       for(i=0; i<MEM8; i++)
+           in8k[i] = in8k[i+N8];
+       */
+
+       /* save 16k to disk for plotting and check out */
+
+       for(i=0; i<N16; i++)
+           out16k_short[i] = (short)out16k[i];
+       fwrite(out16k_short, sizeof(short), N16, f16);
+
+       /* add a 6 kHz spurious signal, down sampler should
+          knock this out */
+
+       for(i=0; i<N16; i++,t1++)
+           in16k[i+FDMDV_OS_TAPS_16K] = out16k[i] + 16000.0*cos(TWO_PI*t1*6000.0/FS);
+
+       /* downsample */
+
+       fdmdv_16_to_8(out8k, &in16k[FDMDV_OS_TAPS_16K], N8);
+       /*
+       for(i=0; i<FDMDV_OS_TAPS_16K; i++)
+           in16k[i] = in16k[i+N16];
+       */
+
+       /* save 8k to disk for plotting and check out */
+
+       for(i=0; i<N8; i++)
+           out8k_short[i] = (short)out8k[i];
+       fwrite(out8k_short, sizeof(short), N8, f8);
+
+    }
+
+    fclose(f16);
+    fclose(f8);
+    return 0;
+
+}
diff --git a/codec2/branches/0.7/unittest/t16_8_short.c b/codec2/branches/0.7/unittest/t16_8_short.c
new file mode 100644 (file)
index 0000000..4caf2a8
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+   t16_8_short.c
+   David Rowe
+   19 August 2014
+
+   Unit test for 16 to 8 kHz sample rate conversion functions.  I
+   evaluated output by plotting using Octave and looking for jaggies:
+
+     pl("../unittest/out16_short.raw",1,3000)
+     pl("../unittest/out8.raw",1,3000)
+
+   Listening to it also shows up anything nasty:
+
+     $ play -s -2 -r 16000 out16_short.raw
+     $ play -s -2 -r 8000 out8.raw
+
+  */
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "codec2_fdmdv.h"
+
+#define N8                        160 /* procssing buffer size at 8 kHz */
+#define N16             (N8*FDMDV_OS)
+#define FRAMES                     100
+#define TWO_PI            6.283185307
+#define FS                      16000
+
+#define SINE
+
+int main() {
+    short in8k_short[FDMDV_OS_TAPS_8K + N8];
+    short out16k_short[N16];
+    FILE *f16;
+
+    short in16k_short[FDMDV_OS_TAPS_16K + N16];
+    short out8k_short[N16];
+    FILE *f8;
+
+    int i,f,t,t1;
+    float freq = 800.0;
+
+    f16 = fopen("out16_short.raw", "wb");
+    assert(f16 != NULL);
+    f8 = fopen("out8.raw", "wb");
+    assert(f8 != NULL);
+
+    /* clear filter memories */
+
+    for(i=0; i<FDMDV_OS_TAPS_8K; i++)
+       in8k_short[i] = 0;
+    for(i=0; i<FDMDV_OS_TAPS_16K; i++)
+       in16k_short[i] = 0;
+
+    t = t1 = 0;
+    for(f=0; f<FRAMES; f++) {
+
+#ifdef DC
+       for(i=0; i<N8; i++)
+           in8k_short[FDMDV_OS_TAPS_8K+i] = 16000.0;
+#endif
+#ifdef SINE
+       for(i=0; i<N8; i++,t++)
+           in8k_short[FDMDV_OS_TAPS_8K+i] = 8000.0*cos(TWO_PI*t*freq/FS);
+#endif
+
+       /* upsample  */
+
+       fdmdv_8_to_16_short(out16k_short, &in8k_short[FDMDV_OS_TAPS_8K], N8);
+
+       fwrite(out16k_short, sizeof(short), N16, f16);
+
+       /* add a 6 kHz spurious signal for fun, we want down sampler to
+          knock this out */
+
+       for(i=0; i<N16; i++,t1++)
+           in16k_short[i+FDMDV_OS_TAPS_16K] = out16k_short[i] + 8000.0*cos(TWO_PI*t1*6000.0/FS);
+
+       /* downsample */
+
+       fdmdv_16_to_8_short(out8k_short, &in16k_short[FDMDV_OS_TAPS_16K], N8);
+
+       /* save 8k to disk for plotting and check out */
+
+       fwrite(out8k_short, sizeof(short), N8, f8);
+
+    }
+
+    fclose(f16);
+    fclose(f8);
+    return 0;
+
+}
diff --git a/codec2/branches/0.7/unittest/t48_8.c b/codec2/branches/0.7/unittest/t48_8.c
new file mode 100644 (file)
index 0000000..ca49bc3
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+   t48_8.c
+   David Rowe
+   May 10 2012
+
+   Unit test for 48 to 8 kHz sample rate conversion functions.  I
+   evaluated output by plotting using Octave and looking for jaggies:
+
+     pl("../unittest/out48.raw",1,3000)
+     pl("../unittest/out8.raw",1,3000)
+
+   Listening to it also shows up anything nasty:
+
+     $ play -s -2 -r 48000 out48.raw
+     $ play -s -2 -r 8000 out8.raw
+
+  */
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "codec2_fdmdv.h"
+
+#define N8                        160 /* procssing buffer size at 8 kHz */
+#define N48             (N8*FDMDV_OS)
+#define MEM8 (FDMDV_OS_TAPS/FDMDV_OS)
+#define FRAMES                     50
+#define TWO_PI            6.283185307
+#define FS                       8000
+
+#define SINE
+
+int main() {
+    float in8k[MEM8 + N8];
+    float out48k[N48];
+    short out48k_short[N48];
+    FILE *f48;
+
+    float in48k[FDMDV_OS_TAPS + N48];
+    float out8k[N48];
+    short out8k_short[N8];
+    FILE *f8;
+
+    int i,f,t,t1;
+    float freq = 800.0;
+
+    f48 = fopen("out48.raw", "wb");
+    assert(f48 != NULL);
+    f8 = fopen("out8.raw", "wb");
+    assert(f8 != NULL);
+
+    /* clear filter memories */
+
+    for(i=0; i<MEM8; i++)
+       in8k[i] = 0.0;
+    for(i=0; i<FDMDV_OS_TAPS; i++)
+       in48k[i] = 0.0;
+
+    t = t1 = 0;
+    for(f=0; f<FRAMES; f++) {
+
+#ifdef DC
+       for(i=0; i<N8; i++)
+           in8k[MEM8+i] = 16000.0;
+#endif
+#ifdef SINE
+       for(i=0; i<N8; i++,t++)
+           in8k[MEM8+i] = 16000.0*cos(TWO_PI*t*freq/FS);
+#endif
+
+       /* upsample  */
+
+       fdmdv_8_to_48(out48k, &in8k[MEM8], N8);
+       /*
+       for(i=0; i<MEM8; i++)
+           in8k[i] = in8k[i+N8];
+       */
+
+       /* save 48k to disk for plotting and check out */
+
+       for(i=0; i<N48; i++)
+           out48k_short[i] = (short)out48k[i];
+       fwrite(out48k_short, sizeof(short), N48, f48);
+
+       /* add a 10 kHz spurious signal for fun, we want down sampler to
+          knock this out */
+
+       for(i=0; i<N48; i++,t1++)
+           in48k[i+FDMDV_OS_TAPS] = out48k[i] + 16000.0*cos(TWO_PI*t1*1E4/FS);
+
+       /* downsample */
+
+       fdmdv_48_to_8(out8k, &in48k[FDMDV_OS_TAPS], N8);
+       /*
+       for(i=0; i<FDMDV_OS_TAPS; i++)
+           in48k[i] = in48k[i+N48];
+       */
+
+       /* save 8k to disk for plotting and check out */
+
+       for(i=0; i<N8; i++)
+           out8k_short[i] = (short)out8k[i];
+       fwrite(out8k_short, sizeof(short), N8, f8);
+
+    }
+
+    fclose(f48);
+    fclose(f8);
+    return 0;
+
+}
diff --git a/codec2/branches/0.7/unittest/tcodec2.c b/codec2/branches/0.7/unittest/tcodec2.c
new file mode 100644 (file)
index 0000000..84bc2a6
--- /dev/null
@@ -0,0 +1,220 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tcodec2.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/8/10
+
+  Test program for codec2.c functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "defines.h"
+#include "comp.h"
+#include "codec2.h"
+#include "quantise.h"
+#include "interp.h"
+
+/* CODEC2 struct copies from codec2.c to help with testing */
+
+struct CODEC2 {
+    int    mode;
+    float  w[M];               /* time domain hamming window                */
+    COMP   W[FFT_ENC];         /* DFT of w[]                                */
+    float  Pn[2*N];            /* trapezoidal synthesis window              */
+    float  Sn[M];               /* input speech                              */
+    float  hpf_states[2];       /* high pass filter states                   */
+    void  *nlp;                 /* pitch predictor states                    */
+    float  Sn_[2*N];           /* synthesised output speech                 */
+    float  ex_phase;            /* excitation model phase track              */
+    float  bg_est;              /* background noise estimate for post filter */
+    float  prev_Wo;             /* previous frame's pitch estimate           */
+    MODEL  prev_model;          /* previous frame's model parameters         */
+    float  prev_lsps_[LPC_ORD]; /* previous frame's LSPs                     */
+    float  prev_energy;         /* previous frame's LPC energy               */
+};
+
+void analyse_one_frame(struct CODEC2 *c2, MODEL *model, short speech[]);
+void synthesise_one_frame(struct CODEC2 *c2, short speech[], MODEL *model, float ak[]);
+
+int test1()
+{
+    FILE   *fin, *fout;
+    short   buf[N];
+    struct CODEC2 *c2;
+    MODEL   model;
+    float   ak[LPC_ORD+1];
+    float   lsps[LPC_ORD];
+
+    c2 = codec2_create(CODEC2_MODE_2400);
+
+    fin = fopen("../raw/hts1a.raw", "rb");
+    assert(fin != NULL);
+    fout = fopen("hts1a_test.raw", "wb");
+    assert(fout != NULL);
+
+    while(fread(buf, sizeof(short), N, fin) == N) {
+       analyse_one_frame(c2, &model, buf);
+       speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+       synthesise_one_frame(c2, buf, &model, ak);
+       fwrite(buf, sizeof(short), N, fout);
+    }
+
+    codec2_destroy(c2);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
+
+int test2()
+{
+    FILE   *fin, *fout;
+    short   buf[2*N];
+    struct  CODEC2 *c2;
+    MODEL   model, model_interp;
+    float   ak[LPC_ORD+1];
+    int     voiced1, voiced2;
+    int     lsp_indexes[LPC_ORD];
+    int     energy_index;
+    int     Wo_index;
+    char    *bits;
+    int     nbit;
+    int     i;
+    float   lsps[LPC_ORD];
+    float   e;
+
+    c2 = codec2_create(CODEC2_MODE_2400);
+    bits = (char*)malloc(codec2_bits_per_frame(c2));
+    assert(bits != NULL);
+    fin = fopen("../raw/hts1a.raw", "rb");
+    assert(fin != NULL);
+    fout = fopen("hts1a_test.raw", "wb");
+    assert(fout != NULL);
+
+    while(fread(buf, sizeof(short), 2*N, fin) == 2*N) {
+       /* first 10ms analysis frame - we just want voicing */
+
+       analyse_one_frame(c2, &model, buf);
+       voiced1 = model.voiced;
+
+       /* second 10ms analysis frame */
+
+       analyse_one_frame(c2, &model, &buf[N]);
+       voiced2 = model.voiced;
+
+       Wo_index = encode_Wo(model.Wo);
+       e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+       encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+       energy_index = encode_energy(e);
+       nbit = 0;
+       pack((unsigned char*)bits, (unsigned *)&nbit, Wo_index, WO_BITS);
+       for(i=0; i<LPC_ORD; i++) {
+           pack((unsigned char*)bits, (unsigned *)&nbit, lsp_indexes[i], lsp_bits(i));
+       }
+       pack((unsigned char*)bits, (unsigned *)&nbit, energy_index, E_BITS);
+       pack((unsigned char*)bits, (unsigned *)&nbit, voiced1, 1);
+       pack((unsigned char*)bits, (unsigned *)&nbit, voiced2, 1);
+
+       nbit = 0;
+       Wo_index = unpack((unsigned char*)bits, (unsigned *)&nbit, WO_BITS);
+       for(i=0; i<LPC_ORD; i++) {
+           lsp_indexes[i] = unpack((unsigned char*)bits, (unsigned *)&nbit, lsp_bits(i));
+       }
+       energy_index = unpack((unsigned char*)bits, (unsigned *)&nbit, E_BITS);
+       voiced1 = unpack((unsigned char*)bits, (unsigned *)&nbit, 1);
+       voiced2 = unpack((unsigned char*)bits, (unsigned *)&nbit, 1);
+
+       model.Wo = decode_Wo(Wo_index);
+       model.L = PI/model.Wo;
+       decode_amplitudes(&model,
+                         ak,
+                         lsp_indexes,
+                         energy_index,
+                         lsps,
+                         &e);
+
+       model.voiced = voiced2;
+       model_interp.voiced = voiced1;
+       interpolate(&model_interp, &c2->prev_model, &model);
+
+       synthesise_one_frame(c2,  buf,     &model_interp, ak);
+       synthesise_one_frame(c2, &buf[N],  &model, ak);
+
+       memcpy(&c2->prev_model, &model, sizeof(MODEL));
+       fwrite(buf, sizeof(short), 2*N, fout);
+    }
+
+    free(bits);
+    codec2_destroy(c2);
+
+    fclose(fin);
+    fclose(fout);
+
+    return 0;
+}
+
+int test3()
+{
+    FILE   *fin, *fout, *fbits;
+    short   buf1[2*N];
+    short   buf2[2*N];
+    char   *bits;
+    struct CODEC2 *c2;
+
+    c2 = codec2_create(CODEC2_MODE_2400);
+    int numBits  = codec2_bits_per_frame(c2);
+    int numBytes = (numBits+7)>>3;
+
+    bits = (char*)malloc(numBytes);
+
+    fin = fopen("../raw/hts1a.raw", "rb");
+    assert(fin != NULL);
+    fout = fopen("hts1a_test.raw", "wb");
+    assert(fout != NULL);
+    fbits = fopen("hts1a_test3.bit", "wb");
+    assert(fout != NULL);
+
+    while(fread(buf1, sizeof(short), 2*N, fin) == 2*N) {
+       codec2_encode(c2, (void*)bits, buf1);
+       fwrite(bits, sizeof(char), numBytes, fbits);
+       codec2_decode(c2, buf2, (void*)bits);
+       fwrite(buf2, sizeof(short), numBytes, fout);
+    }
+
+    free(bits);
+    codec2_destroy(c2);
+
+    fclose(fin);
+    fclose(fout);
+    fclose(fbits);
+
+    return 0;
+}
+
+int main() {
+    test3();
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/tcohpsk.c b/codec2/branches/0.7/unittest/tcohpsk.c
new file mode 100644 (file)
index 0000000..2302c02
--- /dev/null
@@ -0,0 +1,286 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tcohpsk.c
+  AUTHOR......: David Rowe
+  DATE CREATED: March 2015
+
+  Tests for the C version of the coherent PSK FDM modem.  This program
+  outputs a file of Octave vectors that are loaded and automatically
+  tested against the Octave version of the modem by the Octave script
+  tcohpsk.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "fdmdv_internal.h"
+#include "codec2_fdmdv.h"
+#include "codec2_cohpsk.h"
+#include "cohpsk_defs.h"
+#include "cohpsk_internal.h"
+#include "octave.h"
+#include "comp_prim.h"
+#include "noise_samples.h"
+
+#define FRAMES      100                   /* LOG_FRAMES is #defined in cohpsk_internal.h                        */
+#define SYNC_FRAMES 12                    /* sync state uses up extra log storage as we reprocess several times */
+#define FRAMESL     (SYNC_FRAMES*FRAMES)  /* worst case is every frame is out of sync                           */
+
+#define FOFF        58.7
+#define DFOFF       (-0.5/(float)COHPSK_FS)
+#define ESNODB      8
+#define PPM         -1500
+
+extern float pilots_coh[][PILOTS_NC];
+
+int main(int argc, char *argv[])
+{
+    struct COHPSK *coh;
+    int            tx_bits[COHPSK_BITS_PER_FRAME];
+    COMP           tx_symb[NSYMROWPILOT][COHPSK_NC*ND];
+    COMP           tx_fdm_frame[COHPSK_M*NSYMROWPILOT];
+    COMP           ch_fdm_frame[COHPSK_M*NSYMROWPILOT];
+    //COMP           rx_fdm_frame_bb[M*NSYMROWPILOT];
+    //COMP           ch_symb[NSYMROWPILOT][COHPSK_NC*ND];
+    float          rx_bits_sd[COHPSK_BITS_PER_FRAME];
+    int            rx_bits[COHPSK_BITS_PER_FRAME];
+
+    int            tx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
+    COMP           tx_symb_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND];
+    COMP           tx_fdm_frame_log[COHPSK_M*NSYMROWPILOT*FRAMES];
+    COMP           ch_fdm_frame_log[COHPSK_M*NSYMROWPILOT*FRAMES];
+    COMP           ch_fdm_frame_log_out[(COHPSK_M*NSYMROWPILOT+1)*FRAMES];
+    //COMP           rx_fdm_frame_bb_log[M*NSYMROWPILOT*FRAMES];
+    //COMP           ch_symb_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND];
+    COMP           ct_symb_ff_log[NSYMROWPILOT*FRAMES][COHPSK_NC*ND];
+    float          rx_amp_log[NSYMROW*FRAMES][COHPSK_NC*ND];
+    float          rx_phi_log[NSYMROW*FRAMES][COHPSK_NC*ND];
+    COMP           rx_symb_log[NSYMROW*FRAMES][COHPSK_NC*ND];
+    int            rx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
+
+    FILE          *fout;
+    int            f, r, c, log_r, log_data_r, noise_r, ff_log_r, i;
+    double         foff;
+    COMP           foff_rect, phase_ch;
+
+    struct FDMDV  *fdmdv;
+    //COMP           rx_filt[COHPSK_NC*ND][P+1];
+    //int            rx_filt_log_col_index = 0;
+    //float          env[NT*P];
+    //float           __attribute__((unused)) rx_timing;
+    COMP           tx_onesym[COHPSK_NC*ND];
+    //COMP           rx_onesym[COHPSK_NC*ND];
+    //int            rx_baseband_log_col_index = 0;
+    //COMP           rx_baseband_log[COHPSK_NC*ND][(M+M/P)*NSYMROWPILOT*FRAMES];
+    float            f_est_log[FRAMES], sig_rms_log[FRAMES], noise_rms_log[FRAMES];
+    int              f_est_samples;
+
+    int            log_bits;
+    float          EsNo, variance;
+    COMP           scaled_noise;
+    int            reliable_sync_bit;
+    int            ch_fdm_frame_log_index, nin_frame, tmp, nout;
+
+    coh = cohpsk_create();
+    fdmdv = coh->fdmdv;
+    assert(coh != NULL);
+    cohpsk_set_verbose(coh, 1);
+
+    /* these puppies are used for logging data in the bowels on the modem */
+
+    coh->rx_baseband_log_col_sz = (COHPSK_M+COHPSK_M/P)*NSYMROWPILOT*FRAMESL;
+    coh->rx_baseband_log = (COMP *)malloc(sizeof(COMP)*COHPSK_NC*ND*coh->rx_baseband_log_col_sz);
+
+    coh->rx_filt_log_col_sz = (P+1)*NSYMROWPILOT*FRAMESL;
+    coh->rx_filt_log = (COMP *)malloc(sizeof(COMP)*COHPSK_NC*ND*coh->rx_filt_log_col_sz);
+
+    coh->ch_symb_log_col_sz = COHPSK_NC*ND;
+    coh->ch_symb_log = (COMP *)malloc(sizeof(COMP)*NSYMROWPILOT*FRAMESL*coh->ch_symb_log_col_sz);
+
+    coh->rx_timing_log = (float*)malloc(sizeof(float)*NSYMROWPILOT*FRAMESL);
+
+    /* init stuff */
+
+    log_r = log_data_r = noise_r = log_bits = ff_log_r = f_est_samples = 0;
+    phase_ch.real = 1.0; phase_ch.imag = 0.0;
+    foff = FOFF;
+
+    /*  each carrier has power = 2, total power 2Nc, total symbol rate
+        NcRs, noise BW B=Fs Es/No = (C/Rs)/(N/B), N = var =
+        2NcFs/NcRs(Es/No) = 2Fs/Rs(Es/No) */
+
+    EsNo = pow(10.0, ESNODB/10.0);
+    variance = 2.0*COHPSK_FS/(COHPSK_RS*EsNo);
+    //fprintf(stderr, "doff: %e\n", DFOFF);
+
+    /* Main Loop ---------------------------------------------------------------------*/
+
+    for(f=0; f<FRAMES; f++) {
+
+       /* --------------------------------------------------------*\
+                                 Mod
+       \*---------------------------------------------------------*/
+
+        cohpsk_get_test_bits(coh, tx_bits);
+       bits_to_qpsk_symbols(tx_symb, (int*)tx_bits, COHPSK_BITS_PER_FRAME);
+
+        for(r=0; r<NSYMROWPILOT; r++) {
+           for(c=0; c<COHPSK_NC*ND; c++)
+               tx_onesym[c] = tx_symb[r][c];
+           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
+       \*---------------------------------------------------------*/
+
+        for(r=0; r<NSYMROWPILOT*COHPSK_M; r++) {
+            foff_rect.real = cos(2.0*M_PI*foff/COHPSK_FS); foff_rect.imag = sin(2.0*M_PI*foff/COHPSK_FS);
+            foff += DFOFF;
+            phase_ch = cmult(phase_ch, foff_rect);
+            ch_fdm_frame[r] = cmult(tx_fdm_frame[r], phase_ch);
+        }
+        phase_ch.real /= cabsolute(phase_ch);
+        phase_ch.imag /= cabsolute(phase_ch);
+        //fprintf(stderr, "%f\n", foff);
+        for(r=0; r<NSYMROWPILOT*COHPSK_M; r++,noise_r++) {
+            scaled_noise = fcmult(sqrt(variance), noise[noise_r]);
+            ch_fdm_frame[r] = cadd(ch_fdm_frame[r], scaled_noise);
+        }
+
+        /* optional gain to test level sensitivity */
+
+        for(r=0; r<NSYMROWPILOT*COHPSK_M; r++) {
+            ch_fdm_frame[r] = fcmult(1.0, ch_fdm_frame[r]);
+        }
+
+        /* tx vector logging */
+
+       memcpy(&tx_bits_log[COHPSK_BITS_PER_FRAME*f], tx_bits, sizeof(int)*COHPSK_BITS_PER_FRAME);
+       memcpy(&tx_fdm_frame_log[COHPSK_M*NSYMROWPILOT*f], tx_fdm_frame, sizeof(COMP)*COHPSK_M*NSYMROWPILOT);
+       memcpy(&ch_fdm_frame_log[COHPSK_M*NSYMROWPILOT*f], ch_fdm_frame, sizeof(COMP)*COHPSK_M*NSYMROWPILOT);
+
+       for(r=0; r<NSYMROWPILOT; r++, log_r++) {
+            for(c=0; c<COHPSK_NC*ND; c++) {
+               tx_symb_log[log_r][c] = tx_symb[r][c];
+            }
+        }
+    }
+
+    /* Fs offset simulation */
+
+    nout = cohpsk_fs_offset(ch_fdm_frame_log_out, ch_fdm_frame_log, COHPSK_M*NSYMROWPILOT*FRAMES, PPM);
+    assert(nout < (COHPSK_M*NSYMROWPILOT+1)*FRAMES);
+
+    nin_frame = COHPSK_NOM_SAMPLES_PER_FRAME;
+    ch_fdm_frame_log_index = 0;
+
+    /* --------------------------------------------------------*\
+                               Demod
+    \*---------------------------------------------------------*/
+
+    for(f=0; f<FRAMES; f++) {
+        coh->frame = f;
+
+        //printf("nin_frame: %d\n", nin_frame);
+
+        assert(ch_fdm_frame_log_index < COHPSK_M*NSYMROWPILOT*FRAMES);
+        tmp = nin_frame;
+        cohpsk_demod(coh, rx_bits_sd, &reliable_sync_bit, &ch_fdm_frame_log_out[ch_fdm_frame_log_index], &nin_frame);
+        for(i=0; i<COHPSK_BITS_PER_FRAME; i++)
+            rx_bits[i] = rx_bits_sd[i] < 0.0;
+
+        ch_fdm_frame_log_index += tmp;
+
+       /* --------------------------------------------------------*\
+                              Log each vector
+       \*---------------------------------------------------------*/
+
+        if (coh->sync == 1) {
+
+            for(r=0; r<NSYMROWPILOT; r++, ff_log_r++) {
+                for(c=0; c<COHPSK_NC*ND; c++) {
+                    ct_symb_ff_log[ff_log_r][c] = coh->ct_symb_ff_buf[r][c];
+                }
+            }
+
+            for(r=0; r<NSYMROW; r++, log_data_r++) {
+                for(c=0; c<COHPSK_NC*ND; c++) {
+                    rx_amp_log[log_data_r][c] = coh->amp_[r][c];
+                    rx_phi_log[log_data_r][c] = coh->phi_[r][c];
+                    rx_symb_log[log_data_r][c] = coh->rx_symb[r][c];
+                }
+            }
+            memcpy(&rx_bits_log[COHPSK_BITS_PER_FRAME*log_bits], rx_bits, sizeof(int)*COHPSK_BITS_PER_FRAME);
+            log_bits++;
+            f_est_log[f_est_samples] = coh->f_est;
+            sig_rms_log[f_est_samples] = coh->sig_rms;
+            noise_rms_log[f_est_samples] = coh->noise_rms;
+            f_est_samples++;;
+        }
+
+       assert(log_r <= NSYMROWPILOT*FRAMES);
+       assert(noise_r <= NSYMROWPILOT*COHPSK_M*FRAMES);
+       assert(log_data_r <= NSYMROW*FRAMES);
+
+        printf("\r  [%d]", f+1);
+    }
+    printf("\n");
+
+    /*---------------------------------------------------------*\
+               Dump logs to Octave file for evaluation
+                      by tcohpsk.m Octave script
+    \*---------------------------------------------------------*/
+
+    fout = fopen("tcohpsk_out.txt","wt");
+    assert(fout != NULL);
+    fprintf(fout, "# Created by tcohpsk.c\n");
+    octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, COHPSK_BITS_PER_FRAME*FRAMES);
+    octave_save_complex(fout, "tx_symb_log_c", (COMP*)tx_symb_log, NSYMROWPILOT*FRAMES, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_complex(fout, "tx_fdm_frame_log_c", (COMP*)tx_fdm_frame_log, 1, COHPSK_M*NSYMROWPILOT*FRAMES, COHPSK_M*NSYMROWPILOT*FRAMES);
+    octave_save_complex(fout, "ch_fdm_frame_log_c", (COMP*)ch_fdm_frame_log_out, 1, nout-1, nout-1);
+    //octave_save_complex(fout, "rx_fdm_frame_bb_log_c", (COMP*)rx_fdm_frame_bb_log, 1, M*NSYMROWPILOT*FRAMES, M*NSYMROWPILOT*FRAMES);
+    octave_save_complex(fout, "rx_baseband_log_c", (COMP*)coh->rx_baseband_log, COHPSK_NC*ND, coh->rx_baseband_log_col_index, coh->rx_baseband_log_col_sz);
+    octave_save_complex(fout, "rx_filt_log_c", (COMP*)coh->rx_filt_log, COHPSK_NC*ND, coh->rx_filt_log_col_index, coh->rx_filt_log_col_sz);
+    octave_save_complex(fout, "ch_symb_log_c", (COMP*)coh->ch_symb_log, coh->ch_symb_log_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_float(fout, "rx_timing_log_c", (float*)coh->rx_timing_log, 1, coh->rx_timing_log_index, coh->rx_timing_log_index);
+    octave_save_complex(fout, "ct_symb_ff_log_c", (COMP*)ct_symb_ff_log, NSYMROWPILOT*FRAMES, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_float(fout, "rx_phi_log_c", (float*)rx_phi_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_complex(fout, "rx_symb_log_c", (COMP*)rx_symb_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, COHPSK_BITS_PER_FRAME*log_bits);
+    octave_save_float(fout, "f_est_log_c", &f_est_log[1], 1, f_est_samples-1, f_est_samples-1);
+    octave_save_float(fout, "sig_rms_log_c", sig_rms_log, 1, f_est_samples, f_est_samples-1);
+    octave_save_float(fout, "noise_rms_log_c", noise_rms_log, 1, f_est_samples, f_est_samples);
+#ifdef XX
+#endif
+    fclose(fout);
+
+    cohpsk_destroy(coh);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/tcontphase.c b/codec2/branches/0.7/unittest/tcontphase.c
new file mode 100644 (file)
index 0000000..1ae507e
--- /dev/null
@@ -0,0 +1,186 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tcontphase.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 11/9/09
+
+  Test program for developing continuous phase track synthesis algorithm.
+  However while developing this it was discovered that synthesis_mixed()
+  worked just as well.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#define N  80          /* frame size          */
+#define F 160           /* frames to synthesis */
+#define P  10           /* LPC order           */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "sine.h"
+#include "dump.h"
+#include "synth.h"
+#include "phase.h"
+
+int   frames;
+
+float ak[] = {
+ 1.000000,
+-1.455836,
+ 1.361841,
+-0.879267,
+ 0.915985,
+-1.002202,
+ 0.944103,
+-0.743094,
+ 1.053356,
+-0.817491,
+ 0.431222
+};
+
+
+/*---------------------------------------------------------------------------*\
+
+  switch_present()
+
+  Searches the command line arguments for a "switch".  If the switch is
+  found, returns the command line argument where it ws found, else returns
+  NULL.
+
+\*---------------------------------------------------------------------------*/
+
+int switch_present(sw,argc,argv)
+  char sw[];     /* switch in string form */
+  int argc;      /* number of command line arguments */
+  char *argv[];  /* array of command line arguments in string form */
+{
+  int i;       /* loop variable */
+
+  for(i=1; i<argc; i++)
+    if (!strcmp(sw,argv[i]))
+      return(i);
+
+  return 0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+                                    MAIN
+
+\*---------------------------------------------------------------------------*/
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+    FILE *fout;
+    short buf[N];
+    int   i,j;
+    int   dump;
+    float phi_prev[MAX_AMP];
+    float Wo_prev, ex_phase, G;
+    //float ak[P+1];
+    COMP  H[MAX_AMP];
+    float f0;
+
+    if (argc < 3) {
+       printf("\nusage: %s OutputRawSpeechFile F0\n", argv[0]);
+        exit(1);
+    }
+
+    /* Output file */
+
+    if ((fout = fopen(argv[1],"wb")) == NULL) {
+      printf("Error opening output speech file: %s\n",argv[1]);
+      exit(1);
+    }
+
+    f0 = atof(argv[2]);
+
+    dump = switch_present("--dump",argc,argv);
+    if (dump)
+      dump_on(argv[dump+1]);
+
+    init_decoder();
+
+    for(i=0; i<MAX_AMP; i++)
+       phi_prev[i] = 0.0;
+    Wo_prev = 0.0;
+
+    model.Wo = PI*(f0/4000.0);
+    G = 1000.0;
+    model.L = floor(PI/model.Wo);
+
+    //aks_to_H(&model, ak, G , H, P);
+    //for(i=1; i<=model.L; i++)
+       model.A[i] = sqrt(H[i].real*H[i].real + H[i].imag*H[i].imag);
+    //printf("L = %d\n", model.L);
+    //model.L = 10;
+    for(i=1; i<=model.L; i++) {
+      model.A[i]   = 1000/model.L;
+      model.phi[i] = 0;
+      H[i].real = 1.0; H[i].imag = 0.0;
+    }
+
+    //ak[0] = 1.0;
+    //for(i=1; i<=P; i++)
+    //  ak[i] = 0.0;
+
+    frames = 0;
+    for(j=0; j<F; j++) {
+       frames++;
+
+       #ifdef SWAP
+       /* lets make phases bounce around from frame to frame.  This
+          could happen if H[m] is varying, for example due to frame
+          to frame Wo variations, or non-stationary speech.
+          Continous model generally results in smooth phase track
+          under these circumstances. */
+       if (j%2){
+           H[1].real = 1.0; H[1].imag = 0.0;
+           model.phi[1] = 0.0;
+       }
+       else {
+           H[1].real = 0.0; H[1].imag = 1.0;
+           model.phi[1] = PI/2;
+       }
+       #endif
+
+       //#define CONT
+       #ifdef CONT
+       synthesise_continuous_phase(Pn, &model, Sn_, 1, &Wo_prev, phi_prev);
+       #else
+       phase_synth_zero_order(5.0, H, &Wo_prev, &ex_phase);
+       synthesise_mixed(Pn,&model,Sn_,1);
+       #endif
+
+       for(i=0; i<N; i++)
+           buf[i] = Sn_[i];
+       fwrite(buf,sizeof(short),N,fout);
+    }
+
+    fclose(fout);
+    if (dump) dump_off();
+
+    return 0;
+}
+
+
diff --git a/codec2/branches/0.7/unittest/tdec.c b/codec2/branches/0.7/unittest/tdec.c
new file mode 100644 (file)
index 0000000..bd1a7bf
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+   tdec.c
+   David Rowe
+   Jan 2017
+
+   Trivial non filtered decimator for high ration sample rate conversion.
+
+   build: gcc tdec.c -o tdec -Wall -O2
+
+*/
+
+#include <assert.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#define SIGNED_16BIT   0
+#define SIGNED_8BIT    1
+
+void freq_shift_complex_buf(short buf[], int n, int lo_i[], int lo_q[]);
+
+void display_help(void) {
+    fprintf(stderr, "\nusage: tdec inputRawFile OutputRawFile DecimationRatio [-c]\n");
+    fprintf(stderr, "\nUse - for stdin/stdout\n\n");
+    fprintf(stderr, "-c complex signed 16 bit input and output\n");
+    fprintf(stderr, "-d complex signed 8 bit input, complex signed 16 bit output\n");
+    fprintf(stderr, "-f -Fs/4 freq shift\n\n");
+}
+
+int main(int argc, char *argv[]) {
+    FILE       *fin, *fout;
+    short       dec;
+    int         lo_i[3], lo_q[3];
+
+    if (argc < 3) {
+       display_help();
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-") == 0) 
+        fin = stdin;
+    else
+        fin = fopen(argv[1], "rb");
+    assert(fin != NULL);
+
+    if (strcmp(argv[2], "-") == 0) 
+        fout = stdout;
+    else
+        fout = fopen(argv[2], "wb");
+    assert(fout != NULL);
+
+    dec = atoi(argv[3]);
+
+    int channels = 1;
+    int freq_shift = 0;
+    lo_i[0] = -1; lo_i[1] =  0;
+    lo_q[0] =  0; lo_q[1] = -1;
+    int opt;
+    int format = SIGNED_16BIT;
+    while ((opt = getopt(argc, argv, "cdf")) != -1) {
+        switch (opt) {
+        case 'c': channels = 2; break;
+        case 'd': channels = 2; format = SIGNED_8BIT; break;
+        case 'f': freq_shift = 1; break;
+        default:
+            display_help();
+            exit(1);
+        }
+    }
+
+    if (format == SIGNED_16BIT) {
+        short buf[dec*channels];
+        while(fread(buf, sizeof(short)*channels, dec, fin) == dec) {
+            if (freq_shift)            
+                freq_shift_complex_buf(buf, dec*channels, lo_i, lo_q);
+            exit(0);
+            fwrite(buf, sizeof(short), channels, fout);
+        }
+    }
+    else {
+        uint8_t inbuf[dec*channels];
+        short   outbuf[dec*channels];
+        short   sam, i;
+        
+        while(fread(inbuf, sizeof(uint8_t)*channels, dec, fin) == dec) {
+            for (i=0; i<dec*channels; i++) {
+                sam = (short)inbuf[i];
+                sam <<= 8;
+                outbuf[i] = sam;
+            }
+            if (freq_shift)
+                freq_shift_complex_buf(outbuf, dec*channels, lo_i, lo_q);
+            fwrite(outbuf, sizeof(short), channels, fout);
+        }
+
+    }
+
+    fclose(fout);
+    fclose(fin);
+
+    return 0;
+}
+                
+
+void freq_shift_complex_buf(short buf[], int n, int lo_i[], int lo_q[]) {
+    int i;
+
+    for (i=0; i<n; i+=2) {
+        /* update local osc recursion */
+
+        lo_i[2] = -lo_i[0]; lo_q[2] = -lo_q[0];
+
+        /* freq shift down input samples */
+
+        int a = buf[i];
+        int b = buf[i+1];
+        int c = lo_i[2];
+        int d = -lo_q[2];  /* conj LO as down shift */
+
+        buf[i]   = a*c - b*d;
+        buf[i+1] = b*c + a*d;
+
+        //fprintf(stderr, "% d % d % 5d % 5d\n", lo_i[2], lo_q[2], buf[i], buf[i+1]);
+
+        /* update LO memory */
+
+        lo_i[0] = lo_i[1]; lo_i[1] = lo_i[2]; 
+        lo_q[0] = lo_q[1]; lo_q[1] = lo_q[2]; 
+    }
+}
+
diff --git a/codec2/branches/0.7/unittest/tdeframer.c b/codec2/branches/0.7/unittest/tdeframer.c
new file mode 100644 (file)
index 0000000..03e8bb1
--- /dev/null
@@ -0,0 +1,148 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tdeframer.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 8 April 2016
+
+  C unit test for the VHF framer/deframer used by modes 2400A and 2400B.
+  The deframer should sync up within one frame at a BER of 10e-3
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* BER of test */
+#define TESTBER 0.01
+
+/* Frame count */
+#define FRCNT 1500
+
+/* Random bits leading frame */
+#define LRCNT 44
+
+#include <stdio.h>
+#include <math.h>
+#include <stdint.h>
+#include <freedv_vhf_framing.h>
+#include <golay23.h>
+#include <string.h>
+
+/* The main loop of the test driver */
+int main(int argc,char *argv[]){
+    uint8_t * bit_buffer;
+    uint8_t c2_buffer[10];
+    struct freedv_vhf_deframer * fvd;
+    int i,p,k;
+    int bitbufferlen;
+    int fsize;
+    int ftype;
+    int first_tol;
+    
+    if(argc<2){
+        fprintf(stderr,"Usage: %s [A|B]\n",argv[0]);
+        exit(1);
+    }
+    
+    if(strcmp(argv[1],"A")==0){
+        ftype = FREEDV_VHF_FRAME_A;
+        first_tol = 2;
+    }else if(strcmp(argv[1],"B")==0){
+        ftype = FREEDV_HF_FRAME_B;
+        first_tol = 5;
+    }else{
+        fprintf(stderr,"Usage: %s [A|B]\n",argv[0]);
+        exit(1);
+    }
+    
+    srand(1);
+    golay23_init();
+    
+    /* Set up the deframer */
+    fvd = fvhff_create_deframer(ftype,1);
+
+    fsize = fvhff_get_frame_size(fvd);
+    bitbufferlen = (LRCNT+fsize*FRCNT);
+    
+    /* Allocate bit buffer */
+    bit_buffer = (uint8_t *) malloc(sizeof(uint8_t)*bitbufferlen);
+    p = 0;
+    
+    /* Fill out front of buffer */
+    for(i=0; i<LRCNT; i++){
+        bit_buffer[p++] = rand()&0x1;
+    }
+    
+    /* Place frames */
+    for(i=0; i<FRCNT; i++){
+        /* Encode frame index into golay codeword to protect from test BER*/
+        k = golay23_encode((i+1)&0x0FFF);
+        c2_buffer[5] = (k    )&0xFF;
+        c2_buffer[1] = (k>>8 )&0xFF;
+        c2_buffer[0] = (k>>16)&0x7F;
+        /* Frame the bits */
+        fvhff_frame_bits(ftype, &bit_buffer[p+(i*fsize)], c2_buffer,NULL,NULL);
+    }
+    
+    /* Flip bits */
+    for(i=0; i<bitbufferlen; i++){
+        if( (rand()&0xFFFFFF) < (int)(TESTBER*0xFFFFFF)){
+            bit_buffer[i] = bit_buffer[i]?0:1;
+        }
+    }
+    
+    p=0;
+    int first_extract = 0;
+    int total_extract = 0;
+    int err_count = 0;
+    printf("\n");
+    /* Deframe some bits */
+    for(i=0; i<bitbufferlen; i+=fsize){
+        if( fvhff_deframe_bits(fvd, c2_buffer, NULL, NULL, &bit_buffer[i])){
+            /* Extract golay23 codeword */
+            k  = ((int)c2_buffer[5])    ;
+            k |= ((int)c2_buffer[1])<<8 ;
+            k |= ((int)c2_buffer[0])<<16;
+            k = k & 0x7FFFFF;
+            /* Decode frame index */
+            p = golay23_decode(k);
+            err_count += golay23_count_errors(k,p);
+            p = p>>11;
+
+            printf("%d,\t",p);
+            total_extract++;
+            if(first_extract==0)
+                first_extract=p;
+        }
+    }
+    printf("\n");
+    float measured_ber = (float)err_count/(float)(23*total_extract);
+    
+    printf("First extracted frame %d\n",first_extract);
+    printf("Extracted %d frames of %d, %f hit rate\n",total_extract,FRCNT,((float)total_extract/(float)FRCNT));
+    printf("Bit error rate %f measured from golay code\n",measured_ber);
+    printf("Bit error rate %f measured by deframer\n",fvd->ber_est);
+    printf("Bit error rate %f measured by deframer\n",(float)fvd->total_uw_err/(float)fvd->total_uw_bits);
+    /* Check test condition */
+    if(first_extract<first_tol){
+        printf("Test passed at test BER of %f!\n",TESTBER);
+        exit(0);
+    }else{
+        printf("** Test failed at test BER of %f!\n",TESTBER);
+        exit(1);
+    }
+    fvhff_destroy_deframer(fvd);
+}
diff --git a/codec2/branches/0.7/unittest/test_cohpsk_ch.c b/codec2/branches/0.7/unittest/test_cohpsk_ch.c
new file mode 100644 (file)
index 0000000..d5fec72
--- /dev/null
@@ -0,0 +1,296 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: test_cohpsk_ch.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 2015
+
+  Tests for the C version of the coherent PSK FDM modem with channel
+  impairments generated by Octave.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2015 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "codec2_cohpsk.h"
+#include "octave.h"
+#include "comp_prim.h"
+#include "noise_samples.h"
+#include "cohpsk_defs.h"
+#include "cohpsk_internal.h"
+
+#define FRAMES      100
+#define SYNC_FRAMES 12     /* sync state uses up extra log storage as we reprocess several times */
+
+/* defaults with no arguments */
+
+#define FOFF_HZ      0.0
+#define ES_NO_DB     8.0
+#define HF_DELAY_MS  2.0
+
+#define CH_BUF_SZ (4*COHPSK_NOM_SAMPLES_PER_FRAME)
+
+/* This file gets generated using the function write_noise_file in tcohpsk.m.  You have to run
+   tcohpsk first (any variant) to load the function into Octave, e.g.:
+
+  octave:17> tcohpsk
+  octave:18> write_noise_file("../raw/fast_fading_samples.float", 7500, 7500*60)
+  octave:19> write_noise_file("../raw/slow_fading_samples.float", 75000, 7500*60)
+*/
+
+#define FADING_FILE_NAME "../../raw/fading_samples.float"
+
+int main(int argc, char *argv[])
+{
+    struct COHPSK *coh;
+    int            tx_bits[COHPSK_BITS_PER_FRAME];
+    COMP           tx_fdm[COHPSK_NOM_SAMPLES_PER_FRAME];
+    COMP           ch_fdm[COHPSK_NOM_SAMPLES_PER_FRAME];
+    COMP           ch_buf[CH_BUF_SZ];
+    float          rx_bits_sd[COHPSK_BITS_PER_FRAME];
+    char           rx_bits_char[COHPSK_BITS_PER_FRAME];
+    float         *rx_amp_log;
+    float         *rx_phi_log;
+    COMP          *rx_symb_log;
+
+    int            f, r, i;
+    COMP           phase_ch;
+    int            noise_r, noise_end;
+    int            bit_errors;
+    int            state, nerrors, nbits, reliable_sync_bit;
+    float          EsNo, variance;
+    COMP           scaled_noise;
+    float          EsNodB, foff_hz;
+    int            fading_en, nhfdelay, ret, nin_frame, frames, framesl;
+    float          hf_gain;
+    COMP          *ch_fdm_delay, aspread, aspread_2ms, delayed, direct;
+    FILE          *ffading, *fout;
+    int            ch_buf_n;
+    float          tx_pwr, rx_pwr, noise_pwr;
+    short          error_pattern[COHPSK_BITS_PER_FRAME];
+    int            log_data_r, c, j, tmp;
+
+    EsNodB = ES_NO_DB;
+    foff_hz =  FOFF_HZ;
+    fading_en = 0;
+    frames = FRAMES;
+    if (argc == 5) {
+        EsNodB = atof(argv[1]);
+        foff_hz = atof(argv[2]);
+        fading_en = atoi(argv[3]);
+        frames = atoi(argv[4]);
+    }
+    fprintf(stderr, "EsNodB: %4.2f foff: %4.2f Hz fading: %d\n", EsNodB, foff_hz, fading_en);
+
+    coh = cohpsk_create();
+    assert(coh != NULL);
+
+    framesl = SYNC_FRAMES*frames;
+    coh->ch_symb_log_col_sz = COHPSK_NC*ND;
+    coh->ch_symb_log = (COMP *)malloc(sizeof(COMP)*NSYMROWPILOT*framesl*coh->ch_symb_log_col_sz);
+    assert(coh->ch_symb_log != NULL);
+
+    rx_amp_log = (float *)malloc(sizeof(float)*frames*NSYMROW*COHPSK_NC*ND);
+    assert(rx_amp_log != NULL);
+    rx_phi_log = (float *)malloc(sizeof(float)*frames*NSYMROW*COHPSK_NC*ND);
+    assert(rx_phi_log != NULL);
+    rx_symb_log = (COMP *)malloc(sizeof(COMP)*frames*NSYMROW*COHPSK_NC*ND);
+    assert(rx_symb_log != NULL);
+
+    phase_ch.real = 1.0; phase_ch.imag = 0.0;
+    noise_r = 0;
+    noise_end = sizeof(noise)/sizeof(COMP);
+    ch_buf_n = 0;
+
+    log_data_r = 0;
+
+    /*  each carrier has power = 2, total power 2Nc, total symbol rate
+        NcRs, noise BW B=Fs Es/No = (C/Rs)/(N/B), N = var =
+        2NcFs/NcRs(Es/No) = 2Fs/Rs(Es/No) */
+
+    EsNo = pow(10.0, EsNodB/10.0);
+    variance = 2.0*COHPSK_FS/(COHPSK_RS*EsNo);
+
+    tx_pwr = rx_pwr = noise_pwr = 0.0;
+
+    nerrors = 0;
+    nbits = 0;
+
+    /* init HF fading model */
+    ffading = NULL;
+    ch_fdm_delay = NULL;
+
+    if (fading_en) {
+        ffading = fopen(FADING_FILE_NAME, "rb");
+        if (ffading == NULL) {
+            printf("Can't find fading file: %s\n", FADING_FILE_NAME);
+            exit(1);
+        }
+        nhfdelay = floor(HF_DELAY_MS*COHPSK_FS/1000);
+        ch_fdm_delay = (COMP*)malloc((nhfdelay+COHPSK_NOM_SAMPLES_PER_FRAME)*sizeof(COMP));
+        assert(ch_fdm_delay != NULL);
+        for(i=0; i<nhfdelay+COHPSK_NOM_SAMPLES_PER_FRAME; i++) {
+            ch_fdm_delay[i].real = 0.0;
+            ch_fdm_delay[i].imag = 0.0;
+        }
+
+        /* first values in file are HF gains */
+
+        for (i=0; i<4; i++)
+            ret = fread(&hf_gain, sizeof(float), 1, ffading);
+        printf("hf_gain: %f\n", hf_gain);
+    }
+
+    /* Main Loop ---------------------------------------------------------------------*/
+
+    nin_frame = COHPSK_NOM_SAMPLES_PER_FRAME;
+    for(f=0; f<frames; f++) {
+
+       /* --------------------------------------------------------*\
+                                 Mod
+       \*---------------------------------------------------------*/
+
+        cohpsk_get_test_bits(coh, tx_bits);
+       cohpsk_mod(coh, tx_fdm, tx_bits, COHPSK_BITS_PER_FRAME);
+        cohpsk_clip(tx_fdm);
+
+        for(r=0; r<COHPSK_NOM_SAMPLES_PER_FRAME; r++) {
+            tx_pwr += pow(tx_fdm[r].real, 2.0) + pow(tx_fdm[r].imag, 2.0);
+        }
+
+       /* --------------------------------------------------------*\
+                                 Channel
+       \*---------------------------------------------------------*/
+
+        fdmdv_freq_shift(ch_fdm, tx_fdm, foff_hz, &phase_ch, COHPSK_NOM_SAMPLES_PER_FRAME);
+
+        /* optional HF fading -------------------------------------*/
+
+        if (fading_en) {
+
+            /* update delayed signal buffer */
+
+            for(i=0; i<nhfdelay; i++)
+                ch_fdm_delay[i] = ch_fdm_delay[i+COHPSK_NOM_SAMPLES_PER_FRAME];
+            for(j=0; j<COHPSK_NOM_SAMPLES_PER_FRAME; i++, j++)
+                ch_fdm_delay[i] = ch_fdm[j];
+
+            /* combine direct and delayed paths, both multiplied by
+               "spreading" (doppler) functions */
+
+            for(i=0; i<COHPSK_NOM_SAMPLES_PER_FRAME; i++) {
+                ret = fread(&aspread, sizeof(COMP), 1, ffading);
+                assert(ret == 1);
+                ret = fread(&aspread_2ms, sizeof(COMP), 1, ffading);
+                assert(ret == 1);
+                //printf("%f %f %f %f\n", aspread.real, aspread.imag, aspread_2ms.real, aspread_2ms.imag);
+
+                direct    = cmult(aspread, ch_fdm[i]);
+                delayed   = cmult(aspread_2ms, ch_fdm_delay[i]);
+                ch_fdm[i] = fcmult(hf_gain, cadd(direct, delayed));
+            }
+        }
+
+        for(i=0; i<COHPSK_NOM_SAMPLES_PER_FRAME; i++) {
+            rx_pwr += pow(ch_fdm[i].real, 2.0) + pow(ch_fdm[i].imag, 2.0);
+        }
+
+        /* AWGN noise ------------------------------------------*/
+
+        for(r=0; r<COHPSK_NOM_SAMPLES_PER_FRAME; r++) {
+            scaled_noise = fcmult(sqrt(variance), noise[noise_r]);
+            ch_fdm[r] = cadd(ch_fdm[r], scaled_noise);
+            noise_pwr += pow(noise[noise_r].real, 2.0) + pow(noise[noise_r].imag, 2.0);
+            noise_r++;
+            if (noise_r > noise_end) {
+                noise_r = 0;
+                //fprintf(stderr, "  [%d] noise wrap\n", f);
+            }
+
+        }
+
+        /* buffer so we can let demod Fs offset code do it's thing */
+
+        memcpy(&ch_buf[ch_buf_n], ch_fdm, sizeof(COMP)*COHPSK_NOM_SAMPLES_PER_FRAME);
+        ch_buf_n += COHPSK_NOM_SAMPLES_PER_FRAME;
+        assert(ch_buf_n < CH_BUF_SZ);
+
+       /* --------------------------------------------------------*\
+                                 Demod
+       \*---------------------------------------------------------*/
+
+        coh->frame = f;
+        tmp = nin_frame;
+       cohpsk_demod(coh, rx_bits_sd, &reliable_sync_bit, ch_buf, &tmp);
+
+        ch_buf_n -= nin_frame;
+        //printf("nin_frame: %d tmp: %d ch_buf_n: %d\n", nin_frame, tmp, ch_buf_n);
+        assert(ch_buf_n >= 0);
+        if (ch_buf_n)
+            memcpy(ch_buf, &ch_buf[nin_frame], sizeof(COMP)*ch_buf_n);
+        nin_frame = tmp;
+
+       int i;
+       for (i = 0; i < COHPSK_BITS_PER_FRAME; i++)
+       {
+           rx_bits_char[i] = rx_bits_sd[i];
+       }
+
+        cohpsk_put_test_bits(coh, &state, error_pattern, &bit_errors, rx_bits_char, 0);
+        nerrors += bit_errors;
+        nbits   += COHPSK_BITS_PER_FRAME;
+
+        if (state) {
+            for(r=0; r<NSYMROW; r++, log_data_r++) {
+                for(c=0; c<COHPSK_NC*ND; c++) {
+                    rx_amp_log[log_data_r*COHPSK_NC*ND+c] = coh->amp_[r][c];
+                    rx_phi_log[log_data_r*COHPSK_NC*ND+c] = coh->phi_[r][c];
+                    rx_symb_log[log_data_r*COHPSK_NC*ND+c] = coh->rx_symb[r][c];
+                }
+            }
+        }
+
+    }
+
+    printf("%4.3f %d %d\n", (float)nerrors/nbits, nbits, nerrors);
+    printf("tx var: %f noise var: %f rx var: %f\n",
+           tx_pwr/(frames*COHPSK_NOM_SAMPLES_PER_FRAME),
+           noise_pwr/(frames*COHPSK_NOM_SAMPLES_PER_FRAME),
+           rx_pwr/(frames*COHPSK_NOM_SAMPLES_PER_FRAME)
+           );
+    if (fading_en) {
+        free(ch_fdm_delay);
+        fclose(ffading);
+    }
+    cohpsk_destroy(coh);
+
+    fout = fopen("test_cohpsk_ch_out.txt","wt");
+    octave_save_complex(fout, "ch_symb_log_c", (COMP*)coh->ch_symb_log, coh->ch_symb_log_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_float(fout, "rx_phi_log_c", (float*)rx_phi_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    octave_save_complex(fout, "rx_symb_log_c", (COMP*)rx_symb_log, log_data_r, COHPSK_NC*ND, COHPSK_NC*ND);
+    fclose(fout);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/tfdmdv.c b/codec2/branches/0.7/unittest/tfdmdv.c
new file mode 100644 (file)
index 0000000..0cfe886
--- /dev/null
@@ -0,0 +1,287 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tfdmdv.c
+  AUTHOR......: David Rowe
+  DATE CREATED: April 16 2012
+
+  Tests for the C version of the FDMDV modem.  This program outputs a
+  file of Octave vectors that are loaded and automatically tested
+  against the Octave version of the modem by the Octave script
+  tfmddv.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "fdmdv_internal.h"
+#include "codec2_fdmdv.h"
+#include "octave.h"
+
+#define FRAMES 35
+#define CHANNEL_BUF_SIZE (10*M_FAC)
+
+extern float pilot_coeff[];
+
+int main(int argc, char *argv[])
+{
+    struct FDMDV *fdmdv;
+    int           tx_bits[FDMDV_BITS_PER_FRAME];
+    COMP          tx_symbols[FDMDV_NC+1];
+    COMP          tx_fdm[M_FAC];
+    float         channel[CHANNEL_BUF_SIZE];
+    int           channel_count;
+    COMP          rx_fdm[M_FAC+M_FAC/P];
+    float         foff_coarse;
+    int           nin, next_nin;
+    COMP          rx_fdm_fcorr[M_FAC+M_FAC/P];
+    COMP          rx_fdm_filter[M_FAC+M_FAC/P];
+    COMP          rx_filt[NC+1][P+1];
+    float         rx_timing;
+    float         env[NT*P];
+    COMP          rx_symbols[FDMDV_NC+1];
+    int           rx_bits[FDMDV_BITS_PER_FRAME];
+    float         foff_fine;
+    int           sync_bit, reliable_sync_bit;
+
+    int           tx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
+    COMP          tx_symbols_log[(FDMDV_NC+1)*FRAMES];
+    COMP          tx_fdm_log[M_FAC*FRAMES];
+    COMP          pilot_baseband1_log[NPILOTBASEBAND*FRAMES];
+    COMP          pilot_baseband2_log[NPILOTBASEBAND*FRAMES];
+    COMP          pilot_lpf1_log[NPILOTLPF*FRAMES];
+    COMP          pilot_lpf2_log[NPILOTLPF*FRAMES];
+    COMP          S1_log[MPILOTFFT*FRAMES];
+    COMP          S2_log[MPILOTFFT*FRAMES];
+    float         foff_coarse_log[FRAMES];
+    float         foff_log[FRAMES];
+    COMP          rx_fdm_filter_log[(M_FAC+M_FAC/P)*FRAMES];
+    int           rx_fdm_filter_log_index;
+    COMP          rx_filt_log[NC+1][(P+1)*FRAMES];
+    int           rx_filt_log_col_index;
+    float         env_log[NT*P*FRAMES];
+    float         rx_timing_log[FRAMES];
+    COMP          rx_symbols_log[FDMDV_NC+1][FRAMES];
+    COMP          phase_difference_log[FDMDV_NC+1][FRAMES];
+    float         sig_est_log[FDMDV_NC+1][FRAMES];
+    float         noise_est_log[FDMDV_NC+1][FRAMES];
+    int           rx_bits_log[FDMDV_BITS_PER_FRAME*FRAMES];
+    float         foff_fine_log[FRAMES];
+    int           sync_bit_log[FRAMES];
+    int           sync_log[FRAMES];
+    int           nin_log[FRAMES];
+
+    FILE         *fout;
+    int           f,c,i,j;
+
+    fdmdv = fdmdv_create(FDMDV_NC);
+    next_nin = M_FAC;
+    channel_count = 0;
+
+    rx_fdm_filter_log_index = 0;
+    rx_filt_log_col_index = 0;
+
+    printf("sizeof FDMDV states: %zd bytes\n", sizeof(struct FDMDV));
+
+    for(f=0; f<FRAMES; f++) {
+
+       /* --------------------------------------------------------*\
+                                 Modulator
+       \*---------------------------------------------------------*/
+
+       fdmdv_get_test_bits(fdmdv, tx_bits);
+       bits_to_dqpsk_symbols(tx_symbols, FDMDV_NC, fdmdv->prev_tx_symbols, tx_bits, &fdmdv->tx_pilot_bit, 0);
+       memcpy(fdmdv->prev_tx_symbols, tx_symbols, sizeof(COMP)*(FDMDV_NC+1));
+        tx_filter_and_upconvert(tx_fdm, FDMDV_NC , tx_symbols, fdmdv->tx_filter_memory,
+                                fdmdv->phase_tx, fdmdv->freq, &fdmdv->fbb_phase_tx, fdmdv->fbb_rect);
+
+       /* --------------------------------------------------------*\
+                                 Channel
+       \*---------------------------------------------------------*/
+
+       nin = next_nin;
+
+        // nin = M_FAC;  // when debugging good idea to uncomment this to "open loop"
+
+       /* add M_FAC tx samples to end of buffer */
+
+       assert((channel_count + M_FAC) < CHANNEL_BUF_SIZE);
+       for(i=0; i<M_FAC; i++)
+           channel[channel_count+i] = tx_fdm[i].real;
+       channel_count += M_FAC;
+
+       /* take nin samples from start of buffer */
+
+       for(i=0; i<nin; i++) {
+           rx_fdm[i].real = channel[i];
+            rx_fdm[i].imag = 0;
+        }
+
+       /* shift buffer back */
+
+       for(i=0,j=nin; j<channel_count; i++,j++)
+           channel[i] = channel[j];
+       channel_count -= nin;
+
+       /* --------------------------------------------------------*\
+                               Demodulator
+       \*---------------------------------------------------------*/
+
+        /* shift down to complex baseband */
+
+        fdmdv_freq_shift(rx_fdm, rx_fdm, -FDMDV_FCENTRE, &fdmdv->fbb_phase_rx, nin);
+
+       /* freq offset estimation and correction */
+
+        // fdmdv->sync = 0; // when debugging good idea to uncomment this to "open loop"
+
+       foff_coarse = rx_est_freq_offset(fdmdv, rx_fdm, nin, !fdmdv->sync);
+
+       if (fdmdv->sync == 0)
+           fdmdv->foff = foff_coarse;
+       fdmdv_freq_shift(rx_fdm_fcorr, rx_fdm, -fdmdv->foff, &fdmdv->foff_phase_rect, nin);
+
+       /* baseband processing */
+
+        rxdec_filter(rx_fdm_filter, rx_fdm_fcorr, fdmdv->rxdec_lpf_mem, nin);
+        
+        down_convert_and_rx_filter(rx_filt, fdmdv->Nc, rx_fdm_filter, fdmdv->rx_fdm_mem, fdmdv->phase_rx, fdmdv->freq,
+                                   fdmdv->freq_pol, nin, M_FAC/Q);
+       rx_timing = rx_est_timing(rx_symbols, FDMDV_NC, rx_filt, fdmdv->rx_filter_mem_timing, env, nin, M_FAC);
+       foff_fine = qpsk_to_bits(rx_bits, &sync_bit, FDMDV_NC, fdmdv->phase_difference, fdmdv->prev_rx_symbols, rx_symbols, 0);
+
+        //for(i=0; i<FDMDV_NC;i++)
+        //    printf("rx_symbols: %f %f prev_rx_symbols: %f %f phase_difference: %f %f\n", rx_symbols[i].real, rx_symbols[i].imag,
+        //          fdmdv->prev_rx_symbols[i].real, fdmdv->prev_rx_symbols[i].imag, fdmdv->phase_difference[i].real, fdmdv->phase_difference[i].imag);
+        //if (f==1)
+        //   exit(0);
+
+       snr_update(fdmdv->sig_est, fdmdv->noise_est, FDMDV_NC, fdmdv->phase_difference);
+       memcpy(fdmdv->prev_rx_symbols, rx_symbols, sizeof(COMP)*(FDMDV_NC+1));
+
+       next_nin = M_FAC;
+
+       if (rx_timing > 2*M_FAC/P)
+           next_nin += M_FAC/P;
+
+       if (rx_timing < 0)
+           next_nin -= M_FAC/P;
+
+       fdmdv->sync = freq_state(&reliable_sync_bit, sync_bit, &fdmdv->fest_state, &fdmdv->timer, fdmdv->sync_mem);
+       fdmdv->foff  -= TRACK_COEFF*foff_fine;
+
+       /* --------------------------------------------------------*\
+                           Log each vector
+       \*---------------------------------------------------------*/
+
+       memcpy(&tx_bits_log[FDMDV_BITS_PER_FRAME*f], tx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME);
+       memcpy(&tx_symbols_log[(FDMDV_NC+1)*f], tx_symbols, sizeof(COMP)*(FDMDV_NC+1));
+       memcpy(&tx_fdm_log[M_FAC*f], tx_fdm, sizeof(COMP)*M_FAC);
+
+       memcpy(&pilot_baseband1_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband1, sizeof(COMP)*NPILOTBASEBAND);
+       memcpy(&pilot_baseband2_log[f*NPILOTBASEBAND], fdmdv->pilot_baseband2, sizeof(COMP)*NPILOTBASEBAND);
+       memcpy(&pilot_lpf1_log[f*NPILOTLPF], fdmdv->pilot_lpf1, sizeof(COMP)*NPILOTLPF);
+       memcpy(&pilot_lpf2_log[f*NPILOTLPF], fdmdv->pilot_lpf2, sizeof(COMP)*NPILOTLPF);
+       memcpy(&S1_log[f*MPILOTFFT], fdmdv->S1, sizeof(COMP)*MPILOTFFT);
+       memcpy(&S2_log[f*MPILOTFFT], fdmdv->S2, sizeof(COMP)*MPILOTFFT);
+       foff_coarse_log[f] = foff_coarse;
+       foff_log[f] = fdmdv->foff;
+       
+       /* rx filtering */
+
+        for(i=0; i<nin; i++)
+            rx_fdm_filter_log[rx_fdm_filter_log_index + i] = rx_fdm_filter[i];
+        rx_fdm_filter_log_index += nin;
+
+       for(c=0; c<NC+1; c++) {
+           for(i=0; i<(P*nin)/M_FAC; i++)
+               rx_filt_log[c][rx_filt_log_col_index + i] = rx_filt[c][i];
+       }
+       rx_filt_log_col_index += (P*nin)/M_FAC;
+
+       /* timing estimation */
+
+       memcpy(&env_log[NT*P*f], env, sizeof(float)*NT*P);
+       rx_timing_log[f] = rx_timing;
+       nin_log[f] = nin;
+
+       for(c=0; c<FDMDV_NC+1; c++) {
+           rx_symbols_log[c][f] = rx_symbols[c];
+           phase_difference_log[c][f] = fdmdv->phase_difference[c];
+        }
+
+       /* qpsk_to_bits() */
+
+       memcpy(&rx_bits_log[FDMDV_BITS_PER_FRAME*f], rx_bits, sizeof(int)*FDMDV_BITS_PER_FRAME);
+       for(c=0; c<FDMDV_NC+1; c++) {
+           sig_est_log[c][f] = fdmdv->sig_est[c];
+           noise_est_log[c][f] = fdmdv->noise_est[c];
+       }
+       foff_fine_log[f] = foff_fine;
+       sync_bit_log[f] = sync_bit;
+
+       sync_log[f] = fdmdv->sync;
+    }
+
+
+    /*---------------------------------------------------------*\
+               Dump logs to Octave file for evaluation
+                      by tfdmdv.m Octave script
+    \*---------------------------------------------------------*/
+
+    fout = fopen("tfdmdv_out.txt","wt");
+    assert(fout != NULL);
+    fprintf(fout, "# Created by tfdmdv.c\n");
+    octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, FDMDV_BITS_PER_FRAME*FRAMES);
+    octave_save_complex(fout, "tx_symbols_log_c", tx_symbols_log, 1, (FDMDV_NC+1)*FRAMES, (FDMDV_NC+1)*FRAMES);
+    octave_save_complex(fout, "tx_fdm_log_c", (COMP*)tx_fdm_log, 1, M_FAC*FRAMES, M_FAC*FRAMES);
+    octave_save_complex(fout, "pilot_lut_c", (COMP*)fdmdv->pilot_lut, 1, NPILOT_LUT, NPILOT_LUT);
+    octave_save_complex(fout, "pilot_baseband1_log_c", pilot_baseband1_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);
+    octave_save_complex(fout, "pilot_baseband2_log_c", pilot_baseband2_log, 1, NPILOTBASEBAND*FRAMES, NPILOTBASEBAND*FRAMES);
+    octave_save_float(fout, "pilot_coeff_c", pilot_coeff, 1, NPILOTCOEFF, NPILOTCOEFF);
+    octave_save_complex(fout, "pilot_lpf1_log_c", pilot_lpf1_log, 1, NPILOTLPF*FRAMES, NPILOTLPF*FRAMES);
+    octave_save_complex(fout, "pilot_lpf2_log_c", pilot_lpf2_log, 1, NPILOTLPF*FRAMES, NPILOTLPF*FRAMES);
+    octave_save_complex(fout, "S1_log_c", S1_log, 1, MPILOTFFT*FRAMES, MPILOTFFT*FRAMES);
+    octave_save_complex(fout, "S2_log_c", S2_log, 1, MPILOTFFT*FRAMES, MPILOTFFT*FRAMES);
+    octave_save_float(fout, "foff_log_c", foff_log, 1, FRAMES, FRAMES);
+    octave_save_float(fout, "foff_coarse_log_c", foff_coarse_log, 1, FRAMES, FRAMES);
+    octave_save_complex(fout, "rx_fdm_filter_log_c", (COMP*)rx_fdm_filter_log, 1, rx_fdm_filter_log_index, rx_fdm_filter_log_index);
+    octave_save_complex(fout, "rx_filt_log_c", (COMP*)rx_filt_log, (FDMDV_NC+1), rx_filt_log_col_index, (P+1)*FRAMES);
+    octave_save_float(fout, "env_log_c", env_log, 1, NT*P*FRAMES, NT*P*FRAMES);
+    octave_save_float(fout, "rx_timing_log_c", rx_timing_log, 1, FRAMES, FRAMES);
+    octave_save_complex(fout, "rx_symbols_log_c", (COMP*)rx_symbols_log, (FDMDV_NC+1), FRAMES, FRAMES);
+    octave_save_complex(fout, "phase_difference_log_c", (COMP*)phase_difference_log, (FDMDV_NC+1), FRAMES, FRAMES);
+    octave_save_float(fout, "sig_est_log_c", (float*)sig_est_log, (FDMDV_NC+1), FRAMES, FRAMES);
+    octave_save_float(fout, "noise_est_log_c", (float*)noise_est_log, (FDMDV_NC+1), FRAMES, FRAMES);
+    octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, FDMDV_BITS_PER_FRAME*FRAMES);
+    octave_save_float(fout, "foff_fine_log_c", foff_fine_log, 1, FRAMES, FRAMES);
+    octave_save_int(fout, "sync_bit_log_c", sync_bit_log, 1, FRAMES);
+    octave_save_int(fout, "sync_log_c", sync_log, 1, FRAMES);
+    octave_save_int(fout, "nin_log_c", nin_log, 1, FRAMES);
+    fclose(fout);
+
+    fdmdv_destroy(fdmdv);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/tfifo.c b/codec2/branches/0.7/unittest/tfifo.c
new file mode 100644 (file)
index 0000000..5c96fcd
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+   tfifo.c
+   David Rowe
+   Nov 19 2012
+
+   Takes FIFOs, in particular thread safety.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <pthread.h>
+#include "codec2_fifo.h"
+
+#define FIFO_SZ  1024
+#define WRITE_SZ 10
+#define READ_SZ  8
+#define N_MAX    100
+#define LOOPS    1000000
+
+int run_thread = 1;
+struct FIFO *f;
+
+void writer(void);
+void *writer_thread(void *data);
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+#define USE_THREADS
+//#define USE_MUTEX
+
+int main() {
+    pthread_t awriter_thread;
+    int    i,j;
+    short  read_buf[READ_SZ];
+    int    n_out = 0;
+    int    sucess;
+
+    f = fifo_create(FIFO_SZ);
+    #ifdef USE_THREADS
+    pthread_create(&awriter_thread, NULL, writer_thread, NULL);
+    #endif
+
+    for(i=0; i<LOOPS; ) {
+        #ifndef USE_THREADS
+        writer();
+        #endif
+
+        #ifdef USE_MUTEX
+        pthread_mutex_lock(&mutex);
+        #endif
+        sucess = (fifo_read(f, read_buf, READ_SZ) == 0);
+        #ifdef USE_MUTEX
+        pthread_mutex_unlock(&mutex);
+        #endif
+
+       if (sucess) {
+           for(j=0; j<READ_SZ; j++) {
+                if (read_buf[j] != n_out)
+                    printf("error: %d %d\n", read_buf[j], n_out);
+                n_out++;
+                if (n_out == N_MAX)
+                    n_out = 0;
+            }
+            i++;
+        }
+
+    }
+
+    #ifdef USE_THREADS
+    run_thread = 0;
+    pthread_join(awriter_thread,NULL);
+    #endif
+
+    return 0;
+}
+
+int    n_in = 0;
+
+void writer(void) {
+    short  write_buf[WRITE_SZ];
+    int    i;
+
+    if ((FIFO_SZ - fifo_used(f)) > WRITE_SZ) {
+        for(i=0; i<WRITE_SZ; i++) {
+            write_buf[i] = n_in++;
+            if (n_in == N_MAX)
+                n_in = 0;
+        }
+        #ifdef USE_MUTEX
+        pthread_mutex_lock(&mutex);
+        #endif
+        fifo_write(f, write_buf, WRITE_SZ);
+        pthread_mutex_unlock(&mutex);
+    }
+}
+
+void *writer_thread(void *data) {
+
+    while(run_thread) {
+        writer();
+    }
+
+    return NULL;
+}
diff --git a/codec2/branches/0.7/unittest/tfmfsk.c b/codec2/branches/0.7/unittest/tfmfsk.c
new file mode 100644 (file)
index 0000000..23e6bea
--- /dev/null
@@ -0,0 +1,198 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tfmfsk.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 8 February 2016
+
+  C test driver for fmfsk_mod and fmfsk_demod in fmfsk.c. Reads a file with input
+  bits/rf and spits out modulated/demoduladed samples and a dump of internal
+  state. To run unit test, see octave/tfmfsk.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#define MODEMPROBE_ENABLE
+
+#include "modem_probe.h"
+#include <stdio.h>
+
+/* Note: This is a dirty hack to force fsk.c to compile with modem probing enabled */
+#include "fmfsk.c"
+
+#define ST_BITS 10000
+#define ST_FS 48000
+#define ST_RS 2400
+#define ST_EBNO 8
+
+#define TEST_SELF_FULL 1    /* No-arg self test */
+#define TEST_MOD 2          /* Test modulator using in and out file */
+#define TEST_DEMOD 3        /* Test demodulator using in and out file */
+
+
+int main(int argc,char *argv[]){
+    struct FMFSK *fmfsk;
+    int Fs,Rs;
+    FILE *fin,*fout;
+
+    uint8_t *bitbuf = NULL;
+    float *modbuf = NULL;
+    uint8_t *bitbufp;
+    float *modbufp;
+
+    size_t bitbufsize = 0;
+    size_t modbufsize = 0;
+
+    int test_type;
+    
+    int i;
+    
+    fin = NULL;
+    fout = NULL;
+    
+    /* Set up full self-test */
+    if(argc == 1){
+        test_type = TEST_SELF_FULL;
+        modem_probe_init("fmfsk","fmfsk_tfmfsk_log.txt");
+        Fs = ST_FS;
+        Rs = ST_RS;
+    } else if (argc<7){
+    /* Not running any test */
+        printf("Usage: %s [(M|D) SampleRate BitRate InputFile OutputFile OctaveLogFile]\n",argv[0]);
+        exit(1);
+    } else {
+    /* Running stim-drivin test */
+        /* Mod test */
+        if(strcmp(argv[1],"M")==0 || strcmp(argv[1],"m")==0) {
+            test_type = TEST_MOD;
+        /* Demod test */
+        } else if(strcmp(argv[1],"D")==0 || strcmp(argv[1],"d")==0) {
+            test_type = TEST_DEMOD;
+        } else {
+            printf("Must specify mod or demod test with M or D\n");
+            exit(1);
+        }
+        /* Extract parameters */
+        Fs = atoi(argv[2]);
+        Rs = atoi(argv[3]);
+        
+        /* Open files */
+        fin = fopen(argv[4],"r");
+        fout = fopen(argv[5],"w");
+        
+        if(fin == NULL || fout == NULL){
+            printf("Couldn't open test vector files\n");
+            exit(1);
+        }
+        /* Init modem probing */
+        modem_probe_init("fmfsk",argv[6]);
+        
+    }
+    
+       srand(1);
+    
+    /* set up FSK */
+    fmfsk = fmfsk_create(Fs,Rs);
+    /* Modulate! */
+    if(test_type == TEST_MOD || test_type == TEST_SELF_FULL){
+        /* Generate random bits for self test */
+        if(test_type == TEST_SELF_FULL){
+            bitbufsize = ST_BITS;
+            bitbuf = (uint8_t*) malloc(sizeof(uint8_t)*ST_BITS);
+            for(i=0; i<ST_BITS; i++){
+                /* Generate a randomish bit */
+                bitbuf[i] = (uint8_t)(rand()&0x01);
+            }
+        } else { /* Load bits from a file */
+            /* Figure out how many bits are in the input file */
+            fseek(fin, 0L, SEEK_END);
+            bitbufsize = ftell(fin);
+            fseek(fin, 0L, SEEK_SET);
+            bitbuf = malloc(sizeof(uint8_t)*bitbufsize);
+            i = 0;
+            /* Read in some bits */
+            bitbufp = bitbuf;
+            while( fread(bitbufp,sizeof(uint8_t),fmfsk->nbit,fin) == fmfsk->nbit){
+                i++;
+                bitbufp+=fmfsk->nbit;
+                /* Make sure we don't break the buffer */
+                if(i*fmfsk->nbit > bitbufsize){
+                    bitbuf = realloc(bitbuf,sizeof(uint8_t)*(bitbufsize+fmfsk->nbit));
+                    bitbufsize += fmfsk->nbit;
+                }
+            }
+        }
+        /* Allocate modulation buffer */
+        modbuf = (float*)malloc(sizeof(float)*(bitbufsize/fmfsk->nbit)*fmfsk->N*4);
+        modbufsize = (bitbufsize/fmfsk->nbit)*fmfsk->N;
+        /* Do the modulation */
+        modbufp = modbuf;
+        bitbufp = bitbuf;
+        while( bitbufp < bitbuf+bitbufsize){
+            fmfsk_mod(fmfsk, modbufp, bitbufp);
+            modbufp += fmfsk->N;
+            bitbufp += fmfsk->nbit;
+        }
+        /* For a mod-only test, write out the result */
+        if(test_type == TEST_MOD){
+            fwrite(modbuf,sizeof(float),modbufsize,fout);
+            free(modbuf);
+        }
+        /* Free bit buffer */
+        free(bitbuf);
+    }
+    
+    /* Add channel imp here */
+    
+    
+    /* Now test the demod */
+    if(test_type == TEST_DEMOD || test_type == TEST_SELF_FULL){
+        free(modbuf);
+        modbuf = malloc(sizeof(float)*(fmfsk->N+fmfsk->Ts*2));
+        bitbuf = malloc(sizeof(uint8_t)*fmfsk->nbit);
+        /* Demod-only test */
+        if(test_type == TEST_DEMOD){
+            
+            //fprintf(stderr,"%d\n",(fmfsk->N+fmfsk->Ts*2));
+            while( fread(modbuf,sizeof(float),fmfsk_nin(fmfsk),fin) == fmfsk_nin(fmfsk) ){
+                fmfsk_demod(fmfsk,bitbuf,modbuf);
+                fwrite(bitbuf,sizeof(uint8_t),fmfsk->nbit,fout);
+            }
+        }
+        /* Demod after channel imp. and mod */
+        else{
+            bitbufp = bitbuf;
+            modbufp = modbuf;
+            while( modbufp < modbuf + modbufsize){
+                fmfsk_demod(fmfsk,bitbuf,modbuf);
+                modbufp += fmfsk_nin(fmfsk);
+            }
+        }
+        free(bitbuf);
+    }
+    
+    modem_probe_close();
+    if(test_type == TEST_DEMOD || test_type == TEST_MOD){
+        fclose(fin);
+        fclose(fout);
+    }
+    fmfsk_destroy(fmfsk);
+    exit(0);
+}
+
diff --git a/codec2/branches/0.7/unittest/tfreedv_data_channel.c b/codec2/branches/0.7/unittest/tfreedv_data_channel.c
new file mode 100644 (file)
index 0000000..631feb8
--- /dev/null
@@ -0,0 +1,292 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tfreedv_data_channel
+  AUTHOR......: Jeroen Vreeken
+  DATE CREATED: May 3 2016
+
+  Tests for the data channel code.
+  Data channel frame behaviour is tested with test vectors.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 Jeroen Vreeken
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "freedv_data_channel.h"
+
+#include <stdio.h>
+#include <string.h>
+
+unsigned char test_header[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 };
+
+
+struct testvec {
+    char *testname;
+    
+    unsigned char *data;
+    size_t data_size;
+    
+    size_t frame_size;
+    
+    unsigned char *frame_data;
+    size_t frame_data_size;
+
+    unsigned char *flags;
+} testvec[] = {
+    {
+        "Regular packet, does not match header and no broadcast",
+        (unsigned char[]){ 
+            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 
+            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11, 0x12
+        },
+        0x12,
+        8,
+        (unsigned char[]){ 
+            0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x01, 0x02,
+            0x03, 0x04, 0x05, 0x06, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11, 0x12, 0x47, 0x6e
+        },
+        0x14,
+        (unsigned char[]){ 0x00, 0x00, 0x04 },
+    },
+    {
+        "Header",
+        NULL,
+        0,
+        8,
+        (unsigned char[]){ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x5a, 0x60 },
+        0x08,
+        (unsigned char[]){ 0x08 },
+    },
+    {
+        "Broadcast packet",
+        (unsigned char[]){ 
+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11, 0x22,
+            0x33, 0x44, 0x55, 0x66, 0x05, 0x06, 0x07, 0x08, 
+            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11
+        },
+        0x19,
+        8,
+        (unsigned char[]){ 
+            0x05, 0x06, 0x07, 0x08, 
+            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11, 0x3c, 0xbe
+        },
+        0x0f,
+        (unsigned char[]){ 0xc0, 0x07 },
+    },
+    {
+        "Broadcast packet, header does not match",
+        (unsigned char[]){ 
+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x22,
+            0xbb, 0xcc, 0xdd, 0xee, 0x05, 0x06, 0x07, 0x08, 
+            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11
+        },
+        0x19,
+        8,
+        (unsigned char[]){ 
+            0xaa, 0x22,
+            0xbb, 0xcc, 0xdd, 0xee, 0x05, 0x06, 0x07, 0x08, 
+            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11, 0x1a, 0x68
+        },
+        0x15,
+        (unsigned char[]){ 0x40, 0x00, 0x05 },
+    },
+    {
+        "Header 6 bytes",
+        NULL,
+        0,
+        6,
+        (unsigned char[]){ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 },
+        0x06,
+        (unsigned char[]){ 0x2f },
+    },
+    {
+        "Broadcast packet, header does not match (6 byte frames)",
+        (unsigned char[]){ 
+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xaa, 0x22,
+            0xbb, 0xcc, 0xdd, 0xee, 0x05, 0x06, 0x07, 0x08, 
+            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11
+        },
+        0x19,
+        6,
+        (unsigned char[]){ 
+            0xaa, 0x22,
+            0xbb, 0xcc, 0xdd, 0xee, 0x05, 0x06, 0x07, 0x08, 
+            0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+            0x11, 0x1a, 0x68
+        },
+        0x15,
+        (unsigned char[]){ 0x40, 0x00, 0x00, 0x03 },
+    },
+};
+
+
+static int ret = 0;
+static int vector = 0;
+static size_t frame_data_pos = 0;
+static int rx_done = 0;
+
+void *tx_cb_arg = (void*)0xaa55;
+void *rx_cb_arg = (void*)0xbb44;
+
+void tfreedv_data_callback_tx(void *arg, unsigned char *packet, size_t *size)
+{
+    if (tx_cb_arg != arg) {
+        ret++;
+        printf("FAIL: %s called with wrong argument value\n", __func__);
+    }
+    printf("--------------------------------------\n");
+    printf("TX callback called for test %zd bytes data for test %d:\n'%s'\n",
+        testvec[vector].data_size, vector,
+        testvec[vector].testname);
+
+    memcpy(packet, testvec[vector].data, testvec[vector].data_size);
+    *size = testvec[vector].data_size;
+    
+    return;
+}
+
+void tfreedv_data_callback_rx(void *arg, unsigned char *packet, size_t size)
+{
+    if (rx_cb_arg != arg) {
+        ret++;
+        printf("FAIL: %s called with wrong argument value\n", __func__);
+    }
+    printf("RX callback called with %zd bytes\n", size);
+    
+    if (testvec[vector].data_size) {
+        size_t data_size = testvec[vector].data_size;
+        if (data_size != size) {
+            printf("FAIL: Received size does not match test vector: %zd != %zd\n",
+                size, data_size);
+            ret++;
+        } else {
+            size_t i;
+            for (i = 0; i < data_size; i++) {
+                if (packet[i] != testvec[vector].data[i]) {
+                    printf("FAIL: byte %zd does not match 0x%02x != 0x%02x\n",
+                        i, packet[i], testvec[vector].data[i]);
+                    ret++;
+                }
+            }
+        }
+    } else {
+        if (size != 12) {
+            printf("FAIL: Received header is not 12 bytes: %zd\n", size);
+            ret++;
+        } else {
+            if (memcmp(packet+6, test_header, 6)) {
+                printf("FAIL: Header does not match!\n");
+                ret++;
+            }
+        }
+    }
+    
+    rx_done = 1;
+}
+
+int main(int argc, char **argv)
+{
+    struct freedv_data_channel *fdc;
+    
+    fdc = freedv_data_channel_create();
+
+    freedv_data_set_header(fdc, test_header);
+    freedv_data_set_cb_tx(fdc, tfreedv_data_callback_tx, tx_cb_arg);
+    freedv_data_set_cb_rx(fdc, tfreedv_data_callback_rx, rx_cb_arg);
+
+    while (vector < sizeof(testvec)/sizeof(struct testvec)) {
+        size_t frame_size = testvec[vector].frame_size;
+        unsigned char frame[frame_size];
+        int from, bcast, crc, end;
+        int i;
+        size_t check_size;
+        unsigned char flags;
+        int nr_frames;
+       
+        freedv_data_channel_tx_frame(fdc, frame, frame_size, &from, &bcast, &crc, &end);
+
+        check_size = frame_size;
+        if (frame_data_pos + check_size > testvec[vector].frame_data_size)
+            check_size = testvec[vector].frame_data_size - frame_data_pos;
+        
+        flags = from * 0x80 + bcast * 0x40 + crc * 0x20 + end;
+        printf("0x%02x:", flags);
+        for (i = 0; i < check_size; i++) {
+            if (frame[i] != testvec[vector].frame_data[frame_data_pos + i]) {
+                printf(" [0x%02x!=0x%02x]", 
+                    frame[i], testvec[vector].frame_data[frame_data_pos + i]);
+                ret++;
+            } else {
+                printf(" 0x%02x", frame[i]);
+            }
+        }
+        printf("\n");
+        
+        if (flags != testvec[vector].flags[frame_data_pos / frame_size]) {
+            printf("FAIL: Flags byte does not match 0x%02x != 0x%02x\n",
+                flags, testvec[vector].flags[frame_data_pos / frame_size]);
+            ret++;
+        }
+
+        freedv_data_channel_rx_frame(fdc, frame, frame_size, from, bcast, crc, end);
+
+        frame_data_pos += frame_size;
+
+        nr_frames = freedv_data_get_n_tx_frames(fdc, frame_size);
+
+        if (frame_data_pos >= testvec[vector].frame_data_size) {
+           if (nr_frames) {
+               printf("FAIL: nr_frames is not zero: %d\n", nr_frames);
+               ret++;
+           }
+            vector++;
+            frame_data_pos = 0;
+            if (!rx_done) {
+                printf("FAIL: RX callback not executed\n");
+                ret++;
+            }
+            rx_done = 0;
+        } else {
+            int vec_frames = (testvec[vector].frame_data_size - frame_data_pos);
+            vec_frames /= frame_size;
+            vec_frames++;
+            if (nr_frames != vec_frames) {
+                printf("FAIL: nr_frames != vec_frames: %d != %d\n", nr_frames, vec_frames);
+                ret++;
+            }
+        }
+    }
+
+    freedv_data_channel_destroy(fdc);
+
+    printf("--------------------------------------\n");
+    printf("tfreedv_data_channel test result: ");
+    if (ret) {
+        printf("Failed %d\n", ret);
+    } else {
+        printf("Passed\n");
+    }
+
+    return ret;
+}
diff --git a/codec2/branches/0.7/unittest/tfsk.c b/codec2/branches/0.7/unittest/tfsk.c
new file mode 100644 (file)
index 0000000..dbc80fa
--- /dev/null
@@ -0,0 +1,232 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tfsk.c
+  AUTHOR......: Brady O'Brien
+  DATE CREATED: 20 January 2016
+
+  C test driver for fsk_mod and fsk_demod in fsk.c. Reads a file with input
+  bits/rf and spits out modulated/demoduladed samples and a dump of internal
+  state. To run unit test, see octave/tfsk.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2016 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#define MODEMPROBE_ENABLE
+
+#include "modem_probe.h"
+#include <stdio.h>
+
+/* Note: This is a dirty hack to force fsk.c to compile with modem probing enabled */
+#include "fsk.c"
+
+#define ST_BITS 10000
+#define ST_FS 8000
+#define ST_RS 100
+#define ST_F1 1200
+#define ST_Fs 400
+#define ST_EBNO 8
+#define ST_M 2
+
+#define TEST_SELF_FULL 1    /* No-arg self test */
+#define TEST_MOD 2          /* Test modulator using in and out file */
+#define TEST_MOD_H 3          /* Test modulator using in and out file */
+#define TEST_DEMOD 4        /* Test demodulator using in and out file */
+#define TEST_DEMOD_H 5      /* Test demodulator using in and out file */
+
+
+int main(int argc,char *argv[]){
+    struct FSK *fsk;
+    int Fs,Rs,f1,fs,M;
+    FILE *fin,*fout;
+
+    uint8_t *bitbuf = NULL;
+    float *modbuf = NULL;
+    uint8_t *bitbufp;
+    float *modbufp;
+
+    size_t bitbufsize = 0;
+    size_t modbufsize = 0;
+
+    int test_type;
+    
+    int i;
+    
+    fin = NULL;
+    fout = NULL;
+    
+    /* Set up full self-test */
+    if(argc == 1){
+        test_type = TEST_SELF_FULL;
+        modem_probe_init("fsk2","fsk2_tfsk_log.txt");
+        Fs = ST_FS;
+        Rs = ST_RS;
+        f1 = ST_F1;
+        fs = ST_Fs;
+        M = ST_M;
+    } else if (argc<9){
+    /* Not running any test */
+        printf("Usage: %s [(M|D|DX) Mode TXFreq1 TXFreqSpace SampleRate BitRate InputFile OutputFile OctaveLogFile]\n",argv[0]);
+        exit(1);
+    } else {
+    /* Running stim-drivin test */
+        /* Mod test */
+        if(strcmp(argv[1],"MX")==0){
+            test_type = TEST_MOD_H;
+        } else if(strcmp(argv[1],"M")==0 || strcmp(argv[1],"m")==0) {
+            test_type = TEST_MOD;
+        /* Demod test */
+        } else if(strcmp(argv[1],"DX")==0)  {
+            test_type = TEST_DEMOD_H;
+        } else if(strcmp(argv[1],"D")==0 || strcmp(argv[1],"d")==0) {
+            test_type = TEST_DEMOD;
+        } else {
+            printf("Must specify mod or demod test with M or D\n");
+            exit(1);
+        }
+        /* Extract parameters */
+        M = atoi(argv[2]);
+        f1 = atoi(argv[3]);
+        fs = atoi(argv[4]);
+        Fs = atoi(argv[5]);
+        Rs = atoi(argv[6]);
+        
+        /* Open files */
+        fin = fopen(argv[7],"r");
+        fout = fopen(argv[8],"w");
+        
+        if(fin == NULL || fout == NULL){
+            printf("Couldn't open test vector files\n");
+            exit(1);
+        }
+        /* Init modem probing */
+        modem_probe_init("fsk",argv[9]);
+        
+    }
+    
+       srand(1);
+    /* set up FSK */
+    if(test_type == TEST_DEMOD_H || test_type == TEST_MOD_H){
+        fsk = fsk_create_hbr(Fs,Rs,10,M,f1,fs);
+        if(test_type == TEST_DEMOD_H)
+            test_type = TEST_DEMOD;
+        else
+            test_type = TEST_MOD;
+    }else{
+        fsk = fsk_create(Fs,Rs,M,f1,fs);
+    }
+    /* Modulate! */
+    if(test_type == TEST_MOD || test_type == TEST_SELF_FULL){
+        /* Generate random bits for self test */
+        if(test_type == TEST_SELF_FULL){
+            bitbufsize = ST_BITS;
+            bitbuf = (uint8_t*) malloc(sizeof(uint8_t)*ST_BITS);
+            for(i=0; i<ST_BITS; i++){
+                /* Generate a randomish bit */
+                bitbuf[i] = (uint8_t)(rand()&0x01);
+            }
+        } else { /* Load bits from a file */
+            /* Figure out how many bits are in the input file */
+            fseek(fin, 0L, SEEK_END);
+            bitbufsize = ftell(fin);
+            fseek(fin, 0L, SEEK_SET);
+            bitbuf = malloc(sizeof(uint8_t)*bitbufsize);
+            i = 0;
+            /* Read in some bits */
+            bitbufp = bitbuf;
+            while( fread(bitbufp,sizeof(uint8_t),fsk->Nbits,fin) == fsk->Nbits){
+                i++;
+                bitbufp+=fsk->Nbits;
+                /* Make sure we don't break the buffer */
+                if(i*fsk->Nbits > bitbufsize){
+                    bitbuf = realloc(bitbuf,sizeof(uint8_t)*(bitbufsize+fsk->Nbits));
+                    bitbufsize += fsk->Nbits;
+                }
+            }
+        }
+        /* Allocate modulation buffer */
+        modbuf = (float*)malloc(sizeof(float)*(bitbufsize/fsk->Nbits)*fsk->N*4);
+        modbufsize = (bitbufsize/fsk->Nbits)*fsk->N;
+        /* Do the modulation */
+        modbufp = modbuf;
+        bitbufp = bitbuf;
+        while( bitbufp < bitbuf+bitbufsize){
+            fsk_mod(fsk, modbufp, bitbufp);
+            modbufp += fsk->N;
+            bitbufp += fsk->Nbits;
+        }
+        /* For a mod-only test, write out the result */
+        if(test_type == TEST_MOD){
+            fwrite(modbuf,sizeof(float),modbufsize,fout);
+            free(modbuf);
+        }
+        /* Free bit buffer */
+        free(bitbuf);
+    }
+    
+    /* Add channel imp here */
+    
+    
+    /* Now test the demod */
+    if(test_type == TEST_DEMOD || test_type == TEST_SELF_FULL){
+        free(modbuf);
+        modbuf = malloc(sizeof(float)*(fsk->N+fsk->Ts*2));
+        bitbuf = malloc(sizeof(uint8_t)*fsk->Nbits);
+        /* Demod-only test */
+        if(test_type == TEST_DEMOD){
+            while( fread(modbuf,sizeof(float),fsk_nin(fsk),fin) == fsk_nin(fsk) ){
+                /* DR 21/11/16 temp code during port to complex */
+                int n = fsk_nin(fsk);
+                COMP modbuf_comp[n];
+                for(i=0; i<n; i++) {
+                    modbuf_comp[i].real = modbuf[i];
+                    modbuf_comp[i].imag = 0.0;
+                }
+                fsk_demod(fsk,bitbuf,modbuf_comp);
+                fwrite(bitbuf,sizeof(uint8_t),fsk->Nbits,fout);
+            }
+        }
+        /* Demod after channel imp. and mod */
+        else{
+            bitbufp = bitbuf;
+            modbufp = modbuf;
+            while( modbufp < modbuf + modbufsize){
+                /* DR 21/11/16 temp code during port to complex */
+                int n = fsk_nin(fsk);
+                COMP modbuf_comp[n];
+                for(i=0; i<n; i++) {
+                    modbuf_comp[i].real = modbuf[i];
+                    modbuf_comp[i].imag = 0.0;
+                }
+                fsk_demod(fsk,bitbuf,modbuf_comp);
+                modbufp += fsk_nin(fsk);
+            }
+        }
+        free(bitbuf);
+    }
+    
+    modem_probe_close();
+    if(test_type == TEST_DEMOD || test_type == TEST_MOD){
+        fclose(fin);
+        fclose(fout);
+    }
+    fsk_destroy(fsk);
+    exit(0);
+}
+
diff --git a/codec2/branches/0.7/unittest/tinterp.c b/codec2/branches/0.7/unittest/tinterp.c
new file mode 100644 (file)
index 0000000..c4ee362
--- /dev/null
@@ -0,0 +1,151 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tinterp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/10
+
+  Tests interpolation functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "defines.h"
+#include "sine.h"
+#include "interp.h"
+
+void make_amp(MODEL *model, float f0, float cdB, float mdBHz)
+{
+    int   i;
+    float mdBrad = mdBHz*FS/TWO_PI;
+
+    model->Wo = f0*TWO_PI/FS;
+    model->L  = PI/model->Wo;
+    for(i=0; i<=model->L; i++)
+       model->A[i] = pow(10.0,(cdB + (float)i*model->Wo*mdBrad)/20.0);
+    model->voiced = 1;
+}
+
+void write_amp(char file[], MODEL *model)
+{
+    FILE  *f;
+    int    i;
+
+    f = fopen(file,"wt");
+    for(i=1; i<=model->L; i++)
+       fprintf(f, "%f\t%f\n", model->Wo*i, model->A[i]);
+    fclose(f);
+}
+
+const char *get_next_float(const char *s, float *num)
+{
+    const char *p = s;
+    char  tmp[MAX_STR];
+
+    while(*p && !isspace(*p))
+       p++;
+    assert((p-s) < (int)(sizeof(tmp)-1));
+    memcpy(tmp, s, p-s);
+    tmp[p-s] = 0;
+    *num = atof(tmp);
+
+    return p+1;
+}
+
+const char *get_next_int(const char *s, int *num)
+{
+    const char *p = s;
+    char  tmp[MAX_STR];
+
+    while(*p && !isspace(*p))
+       p++;
+    assert((p-s) < (int)(sizeof(tmp)-1));
+    memcpy(tmp, s, p-s);
+    tmp[p-s] = 0;
+    *num = atoi(tmp);
+
+    return p+1;
+}
+
+void load_amp(MODEL *model, const char * file, int frame)
+{
+    FILE *f;
+    int   i;
+    char  s[1024];
+    const char *ps;
+
+    f = fopen(file,"rt");
+    assert(f);
+
+    for(i=0; i<frame; i++)
+       ps = fgets(s, 1023, f);
+
+    /// can frame ever be 0? what if fgets fails?
+    ps = s;
+    ps = get_next_float(ps, &model->Wo);
+    ps = get_next_int(ps, &model->L);
+    for(i=1; i<=model->L; i++)
+       ps = get_next_float(ps, &model->A[i]);
+
+    fclose(f);
+}
+
+void load_or_make_amp(MODEL *model,
+                      const char * filename, int frame,
+                      float f0, float cdB, float mdBHz)
+{
+    struct stat buf;
+    int rc = stat(filename, &buf);
+    if (rc || !S_ISREG(buf.st_mode) || ((buf.st_mode & S_IRUSR) != S_IRUSR))
+    {
+        make_amp(model, f0, cdB, mdBHz);
+    }
+    else
+    {
+        load_amp(model, filename, frame);
+    }
+}
+int main() {
+    MODEL  prev, next, interp;
+
+    load_or_make_amp(&prev,
+                     "../src/hts1a_model.txt", 32,
+                     50.0, 60.0, 6E-3);
+    load_or_make_amp(&next,
+                     "../src/hts1a_model.txt", 34,
+                     50.0, 40.0, 6E-3);
+
+    interp.voiced = 1;
+    interpolate(&interp, &prev, &next);
+
+    write_amp("tinterp_prev.txt", &prev);
+    write_amp("tinterp_interp.txt", &interp);
+    write_amp("tinterp_next.txt", &next);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/tlininterp.c b/codec2/branches/0.7/unittest/tlininterp.c
new file mode 100644 (file)
index 0000000..be9ebd7
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+   tlininterp.c
+   David Rowe
+   Jan 2017
+
+   Fast linear interpolator for high oversam[pling rates.  Upsample
+   with a decent filter first such that the signal is "low pass" wrt
+   to the input sample rate.
+
+   build: gcc tlininterp.c -o tlininterp -Wall -O2
+
+*/
+
+#include <assert.h>
+#include <getopt.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#define NBUF         1000
+#define SIGNED_16BIT    0
+#define SIGNED_8BIT     1
+
+void display_help(void) {
+    fprintf(stderr, "\nusage: tlininterp inputRawFile OutputRawFile OverSampleRatio [-c]\n");
+    fprintf(stderr, "\nUse - for stdin/stdout\n\n");
+    fprintf(stderr, "-c complex signed 16 bit input and output\n");
+    fprintf(stderr, "-d complex signed 16 bit input, complex signed 8 bit output\n");
+    fprintf(stderr, "-f +Fs/4 freq shift\n\n");
+}
+
+int main(int argc, char *argv[]) {
+    FILE       *fin, *fout;
+    short       left[2], right[2], out[2*NBUF], i;
+    float       oversample, t;
+    int8_t      out_s8[2*NBUF];
+    int         lo_i[3], lo_q[3];
+
+    if (argc < 3) {
+       display_help();
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-") == 0) 
+        fin = stdin;
+    else
+        fin = fopen(argv[1], "rb");
+    assert(fin != NULL);
+
+    if (strcmp(argv[2], "-") == 0) 
+        fout = stdout;
+    else
+        fout = fopen(argv[2], "wb");
+    assert(fout != NULL);
+
+    oversample = atof(argv[3]);
+    if (oversample <= 1) {
+       display_help();
+       exit(1);
+    }
+       
+    int channels = 1;
+    int freq_shift = 0;
+    lo_i[0] = -1; lo_i[1] =  0;
+    lo_q[0] =  0; lo_q[1] = -1;
+    int format = SIGNED_16BIT;
+    int opt;
+    while ((opt = getopt(argc, argv, "cdf")) != -1) {
+        switch (opt) {
+        case 'c': channels = 2; break;
+        case 'd': channels = 2; format = SIGNED_8BIT; break;
+        case 'f': freq_shift = 1; break;
+        default:
+            display_help();
+            exit(1);
+        }
+    }
+
+    for (i=0; i<channels; i++)
+        left[i] = 0;
+    t = 0.0;
+    int j = 0;
+    while(fread(&right, sizeof(short)*channels, 1, fin) == 1) {
+        while (t < 1.0) {
+
+            for (i=0; i<channels; i++) {
+                out[2*j+i] = (1.0 - t)*left[i] + t*right[i];
+            }
+
+            if (freq_shift) {
+
+                /* update local osc recursion */
+
+                lo_i[2] = -lo_i[0]; lo_q[2] = -lo_q[0];
+                
+                /* complex mixer to up-shift complex samples */
+
+                int a = out[2*j];
+                int b = out[2*j+1];
+                int c = lo_i[2];
+                int d = lo_q[2];
+
+                out[2*j]   = a*c - b*d;
+                out[2*j+1] = b*c + a*d;
+
+                //fprintf(stderr, "% d % d % 5d % 5d\n", lo_i[2], lo_q[2], out[0], out[1]);
+
+                /* update LO memory */
+
+                lo_i[0] = lo_i[1]; lo_i[1] = lo_i[2]; 
+                lo_q[0] = lo_q[1]; lo_q[1] = lo_q[2]; 
+            }
+
+            /* once we have enough samples write to disk */
+
+            j++;
+            if (j == NBUF) {
+                if (format == SIGNED_16BIT) {
+                    fwrite(&out, sizeof(short)*channels, NBUF, fout);
+                } else {
+                    for (i=0; i<channels*NBUF; i++) {
+                        out_s8[i] = out[i] >> 8;
+                    }
+                    fwrite(&out_s8, sizeof(int8_t)*channels, NBUF, fout);
+                }
+                j = 0;
+            }
+
+            t += 1.0/oversample;
+        }
+        
+        t -= 1.0;
+        for (i=0; i<channels; i++)
+            left[i] = right[i];
+    }
+
+    /* write remaining samples to disk */
+
+    if (format == SIGNED_16BIT) {
+        fwrite(&out, sizeof(short), j, fout);
+    } else {
+        for (i=0; i<j; i++) {
+            out_s8[i] = out[i] >> 8;
+        }
+        fwrite(&out_s8, sizeof(int8_t), j, fout);
+    }
+
+    fclose(fout);
+    fclose(fin);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/tlspsens.c b/codec2/branches/0.7/unittest/tlspsens.c
new file mode 100644 (file)
index 0000000..8a680f6
--- /dev/null
@@ -0,0 +1,131 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tlspsens.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 31 May 2012
+
+  Testing bit error sensitivity of LSP bits, first step in devising an unequal
+  error protection scheme.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "defines.h"
+#include "comp.h"
+#include "codec2.h"
+#include "lsp.h"
+#include "quantise.h"
+#include "interp.h"
+#include "codec2_internal.h"
+
+float run_a_test(char raw_file_name[], int bit_to_corrupt)
+{
+    FILE   *fin;
+    short   buf[N_SAMP];
+    struct  CODEC2 *c2;
+    codec2_fftr_cfg  fftr_fwd_cfg;
+    MODEL   model;
+    float   ak[LPC_ORD+1];
+    float   lsps[LPC_ORD], e;
+    int     lsp_indexes[LPC_ORD], found_bit;
+    float   snr, snr_sum;
+    int     frames, i, mask, index;
+    COMP    Aw[FFT_ENC];
+
+    c2 = codec2_create(CODEC2_MODE_2400);
+    fftr_fwd_cfg = codec2_fftr_alloc(FFT_ENC, 0, NULL, NULL);
+
+    fin = fopen(raw_file_name, "rb");
+    assert(fin != NULL);
+
+    /* find bit we are corrupting */
+
+    found_bit = 0;
+    mask = 0;
+    index = -1;
+    for(i=0; i<LSP_SCALAR_INDEXES; i++) {
+       if (!found_bit) {
+           if (bit_to_corrupt > lsp_bits(i))
+               bit_to_corrupt -= lsp_bits(i);
+           else {
+               index = i;
+               mask = (1 << bit_to_corrupt);
+               printf(" index: %d bit: %d mask: 0x%x ", index, bit_to_corrupt, mask);
+               found_bit = 1;
+           }
+       }
+    }
+    assert(found_bit == 1);
+
+    /* OK test a sample file, flipping bit */
+
+    snr_sum = 0.0;
+    frames = 0;
+    while(fread(buf, sizeof(short), N_SAMP, fin) == N_SAMP) {
+       analyse_one_frame(c2, &model, buf);
+       e = speech_to_uq_lsps(lsps, ak, c2->Sn, c2->w, LPC_ORD);
+       encode_lsps_scalar(lsp_indexes, lsps, LPC_ORD);
+
+       /* find and flip bit we are testing */
+
+       lsp_indexes[index] ^= mask;
+
+       /* decode LSPs and measure SNR */
+
+       decode_lsps_scalar(lsps, lsp_indexes, LPC_ORD);
+       check_lsp_order(lsps, LPC_ORD);
+       bw_expand_lsps(lsps, LPC_ORD, 50.0, 100.0);
+       lsp_to_lpc(lsps, ak, LPC_ORD);
+       aks_to_M2(fftr_fwd_cfg, ak, LPC_ORD, &model, e, &snr, 0, 0, 1, 1, LPCPF_BETA, LPCPF_GAMMA, Aw);
+       snr_sum += snr;
+       frames++;
+    }
+
+    codec2_destroy(c2);
+
+    fclose(fin);
+
+    return snr_sum/frames;
+}
+
+int main(int argc, char *argv[]) {
+    int   i;
+    int   total_lsp_bits = 0;
+    float snr;
+
+    if (argc != 2) {
+       printf("usage: %s RawFile\n", argv[0]);
+       exit(1);
+    }
+
+    for(i=0; i<LPC_ORD; i++)
+       total_lsp_bits += lsp_bits(i);
+
+    for(i=0; i<total_lsp_bits; i++) {
+       snr = run_a_test(argv[1], i);
+       printf("%d %5.2f\n", i, snr);
+    }
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/tnewamp1.c b/codec2/branches/0.7/unittest/tnewamp1.c
new file mode 100644 (file)
index 0000000..35be03e
--- /dev/null
@@ -0,0 +1,288 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tnewamp1.c
+  AUTHOR......: David Rowe
+  DATE CREATED: Jan 2017
+
+  Tests for the C version of the newamp1 amplitude modelling used for
+  700c.  This program outputs a file of Octave vectors that are loaded
+  and automatically tested against the Octave version of the modem by
+  the Octave script tnewamp1.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2017 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "defines.h"
+#include "codec2_fft.h"
+#include "sine.h"
+#include "nlp.h"
+#include "dump.h"
+#include "octave.h"
+#include "newamp1.h"
+#include "quantise.h"
+
+#define FRAMES 300
+
+int main(int argc, char *argv[]) {
+    int Fs = 8000;
+    C2CONST c2const = c2const_create(Fs);
+    int   n_samp = c2const.n_samp;
+    int   m_pitch = c2const.m_pitch;
+    short buf[n_samp];         /* input/output buffer                   */
+    float Sn[m_pitch];         /* float input speech samples            */
+    COMP  Sw[FFT_ENC];         /* DFT of Sn[]                           */
+    codec2_fft_cfg fft_fwd_cfg; /* fwd FFT states                        */
+    float w[m_pitch];          /* time domain hamming window            */
+    COMP  W[FFT_ENC];          /* DFT of w[]                            */
+    MODEL model;
+    void *nlp_states;
+    codec2_fft_cfg phase_fft_fwd_cfg, phase_fft_inv_cfg;
+    float pitch, prev_f0;
+    int   i,m,f,k;
+    
+    if (argc != 2) {
+        printf("usage: ./tnewamp1 RawFile\n");
+        exit(1);
+    }
+    nlp_states = nlp_create(&c2const);
+    prev_f0 = 1.0/P_MAX_S;
+    fft_fwd_cfg = codec2_fft_alloc(FFT_ENC, 0, NULL, NULL); 
+    make_analysis_window(&c2const,fft_fwd_cfg, w, W);
+
+    phase_fft_fwd_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 0, NULL, NULL);
+    phase_fft_inv_cfg = codec2_fft_alloc(NEWAMP1_PHASE_NFFT, 1, NULL, NULL);
+
+    for(i=0; i<m_pitch; i++) {
+       Sn[i] = 1.0;
+    }
+
+    int K = 20;
+    float rate_K_sample_freqs_kHz[K];
+    float model_octave[FRAMES][MAX_AMP+2];    // model params in matrix format, useful for C <-> Octave  
+    float rate_K_surface[FRAMES][K];          // rate K vecs for each frame, form a surface that makes pretty graphs
+    float rate_K_surface_no_mean[FRAMES][K];  // mean removed surface  
+    float rate_K_surface_no_mean_[FRAMES][K]; // quantised mean removed surface  
+    float mean[FRAMES];
+    float mean_[FRAMES];
+    float rate_K_surface_[FRAMES][K];         // quantised rate K vecs for each frame
+    float interpolated_surface_[FRAMES][K];   // dec/interpolated surface
+    //int   voicing[FRAMES];
+    int   voicing_[FRAMES];
+    float model_octave_[FRAMES][MAX_AMP+2];
+    COMP  H[FRAMES][MAX_AMP];
+    int indexes[FRAMES][NEWAMP1_N_INDEXES];
+
+    for(f=0; f<FRAMES; f++) {
+        for(m=0; m<MAX_AMP+2; m++) {
+            model_octave[f][m] = 0.0;
+            model_octave_[f][m] = 0.0;
+        }
+        for(m=0; m<MAX_AMP; m++) {
+            H[f][m].real = 0.0;
+            H[f][m].imag = 0.0;
+        }
+        for(k=0; m<K; k++)
+            interpolated_surface_[f][k] = 0.0;
+        voicing_[f] = 0;
+    }
+
+    mel_sample_freqs_kHz(rate_K_sample_freqs_kHz, K, ftomel(200.0), ftomel(3700.0));
+
+    //for(int k=0; k<K; k++)
+    //    printf("k: %d sf: %f\n", k, rate_K_sample_freqs_kHz[k]);
+
+    FILE *fin = fopen(argv[1], "rb");
+    if (fin == NULL) {
+        fprintf(stderr, "Problem opening hts1.raw\n");
+        exit(1);
+    }
+
+    int M = 4; 
+
+    for(f=0; f<FRAMES; f++) {
+        assert(fread(buf,sizeof(short),n_samp,fin) == n_samp);
+
+        /* shift buffer of input samples, and insert new samples */
+
+       for(i=0; i<m_pitch-n_samp; i++) {
+           Sn[i] = Sn[i+n_samp];
+       }
+       for(i=0; i<n_samp; i++) {
+           Sn[i+m_pitch-n_samp] = buf[i];
+        }
+
+       /* Estimate Sinusoidal Model Parameters ----------------------*/
+
+       nlp(nlp_states, Sn, n_samp, &pitch, Sw, W, &prev_f0);
+       model.Wo = TWO_PI/pitch;
+
+       dft_speech(&c2const, fft_fwd_cfg, Sw, Sn, w);
+       two_stage_pitch_refinement(&c2const, &model, Sw);
+       estimate_amplitudes(&model, Sw, W, 1);
+        est_voicing_mbe(&c2const, &model, Sw, W);
+        //voicing[f] = model.voiced;
+
+        /* newamp1  processing ----------------------------------------*/
+
+        newamp1_model_to_indexes(&c2const, 
+                                 &indexes[f][0], 
+                                 &model, 
+                                 &rate_K_surface[f][0], 
+                                 rate_K_sample_freqs_kHz,
+                                 K,
+                                 &mean[f],
+                                 &rate_K_surface_no_mean[f][0],
+                                 &rate_K_surface_no_mean_[f][0]);
+
+        newamp1_indexes_to_rate_K_vec(&rate_K_surface_[f][0],
+                                      &rate_K_surface_no_mean_[f][0],
+                                      rate_K_sample_freqs_kHz,
+                                      K,
+                                      &mean_[f],
+                                      &indexes[f][0]);
+
+        fprintf(stderr,"f: %d Wo: %4.3f L: %d v: %d\n", f, model.Wo, model.L, model.voiced);
+        if ((f % M) == 0) {
+            for(i=0; i<5; i++) {
+                fprintf(stderr,"  %5.3f", rate_K_surface_[f][i]);
+            }
+            fprintf(stderr,"\n");
+            fprintf(stderr,"  %d %d %d %d\n", indexes[f][0], indexes[f][1], indexes[f][2], indexes[f][3]);
+        }
+        /* log vectors */
+        model_octave[f][0] = model.Wo;
+        model_octave[f][1] = model.L;
+        for(m=1; m<=model.L; m++) {
+            model_octave[f][m+1] = model.A[m];
+        }        
+    }
+
+     /* Decoder */
+
+    MODEL model__[M];
+    float prev_rate_K_vec_[K];
+    COMP  HH[M][MAX_AMP+1];
+    float Wo_left;
+    int   voicing_left;
+
+    /* initial conditions */
+
+    for(k=0; k<K; k++)
+        prev_rate_K_vec_[k] = 0.0;
+    voicing_left = 0;
+    Wo_left = 2.0*M_PI/100.0;
+
+    /* decoder runs on every M-th frame, 25Hz frame rate, offset at
+       start is to minimise processing delay (thanks Jeroen!) */
+
+    fprintf(stderr,"\n");
+    for(f=M-1; f<FRAMES; f+=M) {
+
+        float a_interpolated_surface_[M][K];
+        newamp1_indexes_to_model(&c2const,
+                                 model__,
+                                 (COMP*)HH,
+                                 (float*)a_interpolated_surface_,
+                                 prev_rate_K_vec_,
+                                 &Wo_left,
+                                 &voicing_left,
+                                 rate_K_sample_freqs_kHz, 
+                                 K,
+                                 phase_fft_fwd_cfg, 
+                                 phase_fft_inv_cfg,
+                                 &indexes[f][0]);
+
+        fprintf(stderr,"f: %d\n", f);
+        fprintf(stderr,"  %d %d %d %d\n", indexes[f][0], indexes[f][1], indexes[f][2], indexes[f][3]);
+        for(i=0; i<M; i++) {
+            fprintf(stderr,"  Wo: %4.3f L: %d v: %d\n", model__[i].Wo, model__[i].L, model__[i].voiced);
+        }
+        fprintf(stderr,"  rate_K_vec: ");
+        for(i=0; i<5; i++) {
+            fprintf(stderr,"%5.3f  ", prev_rate_K_vec_[i]);
+        }
+        fprintf(stderr,"\n");
+        fprintf(stderr,"  H:\n");
+
+        for(m=0; m<M; m++) {
+            fprintf(stderr,"    ");  
+            for(i=1; i<=5; i++) {
+                fprintf(stderr,"(%5.3f %5.3f)  ", HH[m][i].real, HH[m][i].imag);
+            }
+            fprintf(stderr,"\n");
+        }
+
+        fprintf(stderr,"\n\n");
+
+        //if (f == 80)
+        //    exit(0);
+
+        /* with f == 0, we don't store ouput, but memories are updated, helps to match
+           what happens in Codec 2 mode */
+
+        if (f >= M) {
+           for(i=0; i<M; i++) {
+               for(k=0; k<K; k++) {
+                   interpolated_surface_[f-M+i][k] = a_interpolated_surface_[i][k];
+               }
+           }
+          
+             /* store test vectors */
+
+            for(i=f-M, m=0; i<f; i++,m++) {
+                model_octave_[i][0] = model__[m].Wo;
+                model_octave_[i][1] = model__[m].L; 
+                voicing_[i] = model__[m].voiced;
+            }
+
+            int j;
+            for(i=f-M, j=0; i<f; i++,j++) {
+                for(m=1; m<=model__[j].L; m++) {
+                    model_octave_[i][m+1] = model__[j].A[m]; 
+                    H[i][m-1] = HH[j][m];// aH[m];
+                }
+            }
+        }
+    }
+
+    fclose(fin);
+
+    /* save vectors in Octave format */
+
+    FILE *fout = fopen("tnewamp1_out.txt","wt");
+    assert(fout != NULL);
+    fprintf(fout, "# Created by tnewamp1.c\n");
+    octave_save_float(fout, "rate_K_surface_c", (float*)rate_K_surface, FRAMES, K, K);
+    octave_save_float(fout, "mean_c", (float*)mean, 1, FRAMES, 1);
+    octave_save_float(fout, "rate_K_surface_no_mean_c", (float*)rate_K_surface_no_mean, FRAMES, K, K);
+    octave_save_float(fout, "rate_K_surface_no_mean__c", (float*)rate_K_surface_no_mean_, FRAMES, K, K);
+    octave_save_float(fout, "mean__c", (float*)mean_, FRAMES, 1, 1);
+    octave_save_float(fout, "rate_K_surface__c", (float*)rate_K_surface_, FRAMES, K, K);
+    octave_save_float(fout, "interpolated_surface__c", (float*)interpolated_surface_, FRAMES, K, K);
+    octave_save_float(fout, "model_c", (float*)model_octave, FRAMES, MAX_AMP+2, MAX_AMP+2);
+    octave_save_float(fout, "model__c", (float*)model_octave_, FRAMES, MAX_AMP+2, MAX_AMP+2);
+    octave_save_int(fout, "voicing__c", (int*)voicing_, 1, FRAMES);
+    octave_save_complex(fout, "H_c", (COMP*)H, FRAMES, MAX_AMP, MAX_AMP);
+    fclose(fout);
+
+    printf("Done! Now run\n  octave:1> tnewamp1(\"../build_linux/src/hts1a\")\n");
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/tnlp.c b/codec2/branches/0.7/unittest/tnlp.c
new file mode 100644 (file)
index 0000000..f5ea4b6
--- /dev/null
@@ -0,0 +1,164 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tnlp.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 23/3/93
+
+  Test program for non linear pitch estimation functions.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "defines.h"
+#include "dump.h"
+#include "sine.h"
+#include "nlp.h"
+#include "kiss_fft.h"
+
+int   frames;
+
+/*---------------------------------------------------------------------------*\
+
+   switch_present()
+
+   Searches the command line arguments for a "switch".  If the switch is
+   found, returns the command line argument where it ws found, else returns
+   NULL.
+
+\*---------------------------------------------------------------------------*/
+
+int switch_present(sw,argc,argv)
+  char sw[];     /* switch in string form */
+  int argc;      /* number of command line arguments */
+  char *argv[];  /* array of command line arguments in string form */
+{
+  int i;       /* loop variable */
+
+  for(i=1; i<argc; i++)
+    if (!strcmp(sw,argv[i]))
+      return(i);
+
+  return 0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+                                    MAIN
+
+\*---------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+    if (argc < 3) {
+       printf("\nusage: tnlp InputRawSpeechFile Outputf0PitchTextFile "
+              "[--dump DumpFile] [--Fs SampleRateHz]\n");
+        exit(1);
+    }
+    
+    int Fs = 8000;
+    if (switch_present("--Fs",argc,argv)) {
+        Fs = atoi(argv[argc+1]);
+    }
+
+    C2CONST c2const = c2const_create(Fs);
+    int   n = c2const.n_samp;
+    int   m = c2const.m_pitch;
+    FILE *fin,*fout;
+    short buf[n];
+    float Sn[m];               /* float input speech samples */
+    kiss_fft_cfg  fft_fwd_cfg;
+    COMP  Sw[FFT_ENC];         /* DFT of Sn[] */
+    float w[m];                        /* time domain hamming window */
+    COMP  W[FFT_ENC];          /* DFT of w[] */
+    float pitch_samples;
+    int   i;
+    float f0, prev_f0;
+    void  *nlp_states;
+    #ifdef DUMP
+    int   dump;
+    #endif
+
+    /* Input file */
+
+    if ((fin = fopen(argv[1],"rb")) == NULL) {
+      printf("Error opening input speech file: %s\n",argv[1]);
+      exit(1);
+    }
+
+    /* Output file */
+
+    if ((fout = fopen(argv[2],"wt")) == NULL) {
+      printf("Error opening output text file: %s\n",argv[2]);
+      exit(1);
+    }
+
+    #ifdef DUMP
+    dump = switch_present("--dump",argc,argv);
+    if (dump)
+      dump_on(argv[dump+1]);
+    #else
+    /// TODO
+    /// #warning "Compile with -DDUMP if you expect to dump anything."
+    #endif
+
+    for(i=0; i<m; i++) {
+      Sn[i] = 0.0;
+    }
+
+    nlp_states = nlp_create(&c2const);
+    fft_fwd_cfg = kiss_fft_alloc(FFT_ENC, 0, NULL, NULL);
+    make_analysis_window(&c2const, fft_fwd_cfg, w, W);
+
+    frames = 0;
+    prev_f0 = 1/P_MAX_S;
+    while(fread(buf, sizeof(short), n, fin)) {
+      /* Update input speech buffers */
+
+      for(i=0; i<m-n; i++)
+        Sn[i] = Sn[i+n];
+      for(i=0; i<n; i++)
+        Sn[i+m-n] = buf[i];
+      dft_speech(&c2const, fft_fwd_cfg, Sw, Sn, w);
+      #ifdef DUMP
+      dump_Sn(m, Sn); dump_Sw(Sw);
+      #endif
+
+      f0 = nlp(nlp_states, Sn, n, &pitch_samples, Sw, W, &prev_f0);
+
+      fprintf(stderr,"%d %f %f\n", frames++, f0, pitch_samples);
+      fprintf(fout,"%f %f\n", f0, pitch_samples);
+    }
+
+    fclose(fin);
+    fclose(fout);
+    #ifdef DUMP
+    if (dump) dump_off();
+    #endif
+    nlp_destroy(nlp_states);
+
+    return 0;
+}
+
+
diff --git a/codec2/branches/0.7/unittest/tofdm.c b/codec2/branches/0.7/unittest/tofdm.c
new file mode 100644 (file)
index 0000000..115a86e
--- /dev/null
@@ -0,0 +1,306 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tofdm.c
+  AUTHORS.....: David Rowe & Steve Sampson
+  DATE CREATED: June 2017
+
+  Tests for the C version of the OFDM modem.  This program
+  outputs a file of Octave vectors that are loaded and automatically
+  tested against the Octave version of the modem by the Octave script
+  tofdm.m
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2017 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <complex.h>
+
+#include "ofdm_internal.h"
+#include "codec2_ofdm.h"
+#include "octave.h"
+#include "test_bits_ofdm.h"
+#include "comp_prim.h"
+
+#define NFRAMES 30
+#define SAMPLE_CLOCK_OFFSET_PPM 100
+#define FOFF_HZ 0.5f
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: fs_offset()
+  AUTHOR......: David Rowe
+  DATE CREATED: May 2015
+
+  Simulates small Fs offset between mod and demod.
+  (Note: Won't work with float, works OK with double)
+
+\*---------------------------------------------------------------------------*/
+
+static int fs_offset(COMP out[], COMP in[], int n, float sample_rate_ppm) {
+    double f;
+    int t1, t2;
+
+    double tin = 0.0;
+    int tout = 0;
+
+    while (tin < (double) n) {
+      t1 = (int) floor(tin);
+      t2 = (int) ceil(tin);
+
+      f = (tin - (double) t1);
+
+      out[tout].real = (1.0 - f) * in[t1].real + f * in[t2].real;
+      out[tout].imag = (1.0 - f) * in[t1].imag + f * in[t2].imag;
+
+      tout += 1;
+      tin  += 1.0 + sample_rate_ppm / 1E6;
+    }
+
+    return tout;
+}
+
+#ifndef ARM_MATH_CM4
+  #define SINF(a) sinf(a)
+  #define COSF(a) cosf(a)
+#else
+  #define SINF(a) arm_sin_f32(a)
+  #define COSF(a) arm_cos_f32(a)
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+  FUNCTION....: freq_shift()
+  AUTHOR......: David Rowe
+  DATE CREATED: 26/4/2012
+
+  Frequency shift modem signal.  The use of complex input and output allows
+  single sided frequency shifting (no images).
+
+\*---------------------------------------------------------------------------*/
+
+static void freq_shift(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, COMP *foff_phase_rect, int nin) {
+    float temp = (TAU * foff / OFDM_FS);
+    COMP  foff_rect = { COSF(temp), SINF(temp) };
+    int   i;
+
+    for (i = 0; i < nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
+    }
+
+    /* normalise digital oscillator as the magnitude can drift over time */
+
+    float mag = cabsolute(*foff_phase_rect);
+    foff_phase_rect->real /= mag;
+    foff_phase_rect->imag /= mag;
+}
+
+int main(int argc, char *argv[])
+{
+    int            samples_per_frame = ofdm_get_samples_per_frame();
+    int            max_samples_per_frame = ofdm_get_max_samples_per_frame();
+
+    struct OFDM   *ofdm;
+    COMP           tx[samples_per_frame];         /* one frame of tx samples */
+
+    int            rx_bits[OFDM_BITSPERFRAME];    /* one frame of rx bits    */
+
+    /* log arrays */
+
+    int            tx_bits_log[OFDM_BITSPERFRAME*NFRAMES];
+    COMP           tx_log[samples_per_frame*NFRAMES];
+    COMP           rx_log[samples_per_frame*NFRAMES];
+    COMP           rxbuf_in_log[max_samples_per_frame*NFRAMES];
+    COMP           rxbuf_log[OFDM_RXBUF*NFRAMES];
+    COMP           rx_sym_log[(OFDM_NS + 3)*NFRAMES][OFDM_NC + 2];
+    float          phase_est_pilot_log[OFDM_ROWSPERFRAME*NFRAMES][OFDM_NC];
+    COMP           rx_np_log[OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES];
+    float          rx_amp_log[OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES];
+    float          foff_hz_log[NFRAMES];
+    int            rx_bits_log[OFDM_BITSPERFRAME*NFRAMES];
+    int            timing_est_log[OFDM_BITSPERFRAME*NFRAMES];
+    int            sample_point_log[OFDM_BITSPERFRAME*NFRAMES];
+
+    FILE          *fout;
+    int            f,i,j;
+
+    ofdm = ofdm_create();
+    assert(ofdm != NULL);
+
+    /* Main Loop ---------------------------------------------------------------------*/
+
+    for(f=0; f<NFRAMES; f++) {
+
+       /* --------------------------------------------------------*\
+                                 Mod
+       \*---------------------------------------------------------*/
+
+        /* todo: add a longer sequence of test bits through
+           ofdm_get/put test bits functin similat to cohpsk/fdmdv */
+
+        ofdm_mod(ofdm, (COMP*)tx, test_bits_ofdm);
+
+        /* tx vector logging */
+
+       memcpy(&tx_bits_log[OFDM_BITSPERFRAME*f], test_bits_ofdm, sizeof(int)*OFDM_BITSPERFRAME);
+       memcpy(&tx_log[samples_per_frame*f], tx, sizeof(COMP)*samples_per_frame);
+    }
+
+    /* --------------------------------------------------------*\
+                               Channel
+    \*---------------------------------------------------------*/
+
+    fs_offset(rx_log, tx_log, samples_per_frame*NFRAMES, SAMPLE_CLOCK_OFFSET_PPM);
+
+    COMP foff_phase_rect = {1.0f, 0.0f};
+
+    freq_shift(rx_log, rx_log, FOFF_HZ, &foff_phase_rect, samples_per_frame * NFRAMES);
+
+    /* --------------------------------------------------------*\
+                               Demod
+    \*---------------------------------------------------------*/
+
+    /* Init rx with ideal timing so we can test with timing estimation disabled */
+
+    int  Nsam = samples_per_frame*NFRAMES;
+    int  prx = 0;
+    int  nin = samples_per_frame + 2*(OFDM_M+OFDM_NCP);
+
+    int  lnew;
+    COMP rxbuf_in[max_samples_per_frame];
+
+    for (i=0; i<nin; i++,prx++) {
+         ofdm->rxbuf[OFDM_RXBUF-nin+i] = rx_log[prx].real + I*rx_log[prx].imag;
+    }
+
+    int nin_tot = 0;
+
+    /* disable estimators for initial testing */
+
+    ofdm_set_verbose(ofdm, true);
+    ofdm_set_timing_enable(ofdm, true);
+    ofdm_set_foff_est_enable(ofdm, true);
+    ofdm_set_phase_est_enable(ofdm, true);
+
+    for(f=0; f<NFRAMES; f++) {
+        /* For initial testng, timing est is off, so nin is always
+           fixed.  TODO: we need a constant for rxbuf_in[] size that
+           is the maximum possible nin */
+
+        nin = ofdm_get_nin(ofdm);
+        assert(nin <= max_samples_per_frame);
+
+        /* Insert samples at end of buffer, set to zero if no samples
+           available to disable phase estimation on future pilots on
+           last frame of simulation. */
+
+        if ((Nsam-prx) < nin) {
+            lnew = Nsam-prx;
+        } else {
+            lnew = nin;
+        }
+        //printf("nin: %d prx: %d lnew: %d\n", nin, prx, lnew);
+        for(i=0; i<nin; i++) {
+            rxbuf_in[i].real = 0.0;
+            rxbuf_in[i].imag = 0.0;
+        }
+
+        if (lnew) {
+            for(i=0; i<lnew; i++, prx++) {
+                rxbuf_in[i] = rx_log[prx];
+            }
+        }
+        assert(prx <= max_samples_per_frame*NFRAMES);
+
+        ofdm_demod(ofdm, rx_bits, rxbuf_in);
+
+        /* rx vector logging -----------------------------------*/
+
+        assert(nin_tot < samples_per_frame*NFRAMES);
+       memcpy(&rxbuf_in_log[nin_tot], rxbuf_in, sizeof(COMP)*nin);
+        nin_tot += nin;
+
+        for(i=0; i<OFDM_RXBUF; i++) {
+            rxbuf_log[OFDM_RXBUF*f+i].real = crealf(ofdm->rxbuf[i]);
+            rxbuf_log[OFDM_RXBUF*f+i].imag = cimagf(ofdm->rxbuf[i]);
+       }
+
+        for (i = 0; i < (OFDM_NS + 3); i++) {
+            for (j = 0; j < (OFDM_NC + 2); j++) {
+                rx_sym_log[(OFDM_NS + 3)*f+i][j].real = crealf(ofdm->rx_sym[i][j]);
+                rx_sym_log[(OFDM_NS + 3)*f+i][j].imag = cimagf(ofdm->rx_sym[i][j]);
+            }
+        }
+
+        /* note corrected phase (rx no phase) is one big linear array for frame */
+
+        for (i = 0; i < OFDM_ROWSPERFRAME*OFDM_NC; i++) {
+            rx_np_log[OFDM_ROWSPERFRAME*OFDM_NC*f + i].real = crealf(ofdm->rx_np[i]);
+            rx_np_log[OFDM_ROWSPERFRAME*OFDM_NC*f + i].imag = cimagf(ofdm->rx_np[i]);
+        }
+
+        /* note phase/amp ests the same for each col, but check them all anyway */
+
+        for (i = 0; i < OFDM_ROWSPERFRAME; i++) {
+            for (j = 0; j < OFDM_NC; j++) {
+                phase_est_pilot_log[OFDM_ROWSPERFRAME*f+i][j] = ofdm->aphase_est_pilot_log[OFDM_NC*i+j];
+                rx_amp_log[OFDM_ROWSPERFRAME*OFDM_NC*f+OFDM_NC*i+j] = ofdm->rx_amp[OFDM_NC*i+j];
+            }
+        }
+
+        foff_hz_log[f] = ofdm->foff_est_hz;
+        timing_est_log[f] = ofdm->timing_est + 1;      /* offset by 1 to match Octave */
+        sample_point_log[f] = ofdm->sample_point + 1; /* offset by 1 to match Octave */
+
+        memcpy(&rx_bits_log[OFDM_BITSPERFRAME*f], rx_bits, sizeof(rx_bits));
+    }
+
+    /*---------------------------------------------------------*\
+               Dump logs to Octave file for evaluation
+                      by tofdm.m Octave script
+    \*---------------------------------------------------------*/
+
+    fout = fopen("tofdm_out.txt","wt");
+    assert(fout != NULL);
+    fprintf(fout, "# Created by tofdm.c\n");
+    octave_save_complex(fout, "W_c", (COMP*)ofdm->W, OFDM_NC + 2, OFDM_M, OFDM_M);
+    octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, OFDM_BITSPERFRAME*NFRAMES);
+    octave_save_complex(fout, "tx_log_c", (COMP*)tx_log, 1, samples_per_frame*NFRAMES,  samples_per_frame*NFRAMES);
+    octave_save_complex(fout, "rx_log_c", (COMP*)rx_log, 1, samples_per_frame*NFRAMES,  samples_per_frame*NFRAMES);
+    octave_save_complex(fout, "rxbuf_in_log_c", (COMP*)rxbuf_in_log, 1, nin_tot, nin_tot);
+    octave_save_complex(fout, "rxbuf_log_c", (COMP*)rxbuf_log, 1, OFDM_RXBUF*NFRAMES,  OFDM_RXBUF*NFRAMES);
+    octave_save_complex(fout, "rx_sym_log_c", (COMP*)rx_sym_log, (OFDM_NS + 3)*NFRAMES, OFDM_NC + 2, OFDM_NC + 2);
+    octave_save_float(fout, "phase_est_pilot_log_c", (float*)phase_est_pilot_log, OFDM_ROWSPERFRAME*NFRAMES, OFDM_NC, OFDM_NC);
+    octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, 1, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES);
+    octave_save_float(fout, "foff_hz_log_c", foff_hz_log, NFRAMES, 1, 1);
+    octave_save_int(fout, "timing_est_log_c", timing_est_log, NFRAMES, 1);
+    octave_save_int(fout, "sample_point_log_c", sample_point_log, NFRAMES, 1);
+    octave_save_complex(fout, "rx_np_log_c", (COMP*)rx_np_log, 1, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES, OFDM_ROWSPERFRAME*OFDM_NC*NFRAMES);
+    octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, OFDM_BITSPERFRAME*NFRAMES);
+    fclose(fout);
+
+    ofdm_destroy(ofdm);
+
+    return 0;
+}
+
diff --git a/codec2/branches/0.7/unittest/tprede.c b/codec2/branches/0.7/unittest/tprede.c
new file mode 100644 (file)
index 0000000..4d3d09c
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+   tpre_de.c
+   David Rowe
+   Sep 24 2012
+
+   Unit test to generate the combined impulse response of pre & de-emphasis filters.
+
+     pl("../unittest/out48.raw",1,3000)
+     pl("../unittest/out8.raw",1,3000)
+
+   Listening to it also shows up anything nasty:
+
+     $ play -s -2 -r 48000 out48.raw
+     $ play -s -2 -r 8000 out8.raw
+
+  */
+
+#include <assert.h>
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "lpc.h"
+
+#define N                        10
+#define F                        10
+
+int main() {
+    FILE  *fprede;
+    float  Sn[N], Sn_pre[N], Sn_de[N];
+    float  pre_mem = 0.0, de_mem = 0.0;
+    int    i, f;
+
+    fprede = fopen("prede.txt", "wt");
+    assert(fprede != NULL);
+
+    for(i=0; i<N; i++)
+       Sn[i] = 0.0;
+
+    Sn[0]= 1.0;
+
+    for(f=0; f<F; f++) {
+       pre_emp(Sn_pre, Sn, &pre_mem, N);
+       de_emp(Sn_de, Sn_pre, &de_mem, N);
+       for(i=0; i<N; i++) {
+           fprintf(fprede, "%f\n", Sn_de[i]);
+       }
+       Sn[0] = 0.0;
+    }
+
+    fclose(fprede);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/tquant.c b/codec2/branches/0.7/unittest/tquant.c
new file mode 100644 (file)
index 0000000..9b9ee2b
--- /dev/null
@@ -0,0 +1,214 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: tquant.c
+  AUTHOR......: David Rowe
+  DATE CREATED: 22/8/10
+
+  Generates quantisation curves for plotting on Octave.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2010 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include "defines.h"
+#include "dump.h"
+#include "quantise.h"
+
+int test_Wo_quant();
+int test_lsp_quant();
+int test_lsp(int lsp_number, int levels, float max_error_hz);
+int test_energy_quant(int levels, float max_error_dB);
+
+int main() {
+    quantise_init();
+    test_Wo_quant();
+    test_lsp_quant();
+    test_energy_quant(E_LEVELS, 0.5*(E_MAX_DB - E_MIN_DB)/E_LEVELS);
+
+    return 0;
+}
+
+int test_lsp_quant() {
+    test_lsp( 1, 16,  12.5);
+    test_lsp( 2, 16,  12.5);
+    test_lsp( 3, 16,  25);
+    test_lsp( 4, 16,  50);
+    test_lsp( 5, 16,  50);
+    test_lsp( 6, 16,  50);
+    test_lsp( 7, 16,  50);
+    test_lsp( 8,  8,  50);
+    test_lsp( 9,  8,  50);
+    test_lsp(10,  4, 100);
+
+    return 0;
+}
+
+int test_energy_quant(int levels, float max_error_dB) {
+    FILE  *fe;
+    float  e,e_dec, error, low_e, high_e;
+    int    index, index_in, index_out, i;
+
+    /* check 1:1 match between input and output levels */
+
+    for(i=0; i<levels; i++) {
+       index_in = i;
+       e = decode_energy(index_in, E_BITS);
+       index_out = encode_energy(e, E_BITS);
+       if (index_in != index_out) {
+           printf("edB: %f index_in: %d index_out: %d\n",
+                  10.0*log10(e), index_in, index_out);
+           exit(0);
+       }
+    }
+
+    /* check error over range of quantiser */
+
+    low_e = decode_energy(0, E_BITS);
+    high_e = decode_energy(levels-1, E_BITS);
+    fe = fopen("energy_err.txt", "wt");
+
+    for(e=low_e; e<high_e; e +=(high_e-low_e)/1000.0) {
+       index = encode_energy(e, E_BITS);
+       e_dec = decode_energy(index, E_BITS);
+       error = 10.0*log10(e) - 10.0*log10(e_dec);
+       fprintf(fe, "%f\n", error);
+       if (fabs(error) > max_error_dB) {
+           printf("error: %f %f\n", error, max_error_dB);
+           exit(0);
+       }
+    }
+
+    fclose(fe);
+    return 0;
+}
+
+int test_lsp(int lsp_number, int levels, float max_error_hz) {
+    float lsp[LPC_ORD];
+    int   indexes_in[LPC_ORD];
+    int   indexes_out[LPC_ORD];
+    int   indexes[LPC_ORD];
+    int   i;
+    float lowf, highf, f, error;
+    char  s[MAX_STR];
+    FILE *flsp;
+    float max_error_rads;
+
+    lsp_number--;
+    max_error_rads = max_error_hz*TWO_PI/FS;
+
+    for(i=0; i<LPC_ORD; i++)
+       indexes_in[i] = 0;
+
+    for(i=0; i<levels; i++) {
+       indexes_in[lsp_number] = i;
+       decode_lsps_scalar(lsp, indexes_in, LPC_ORD);
+       encode_lsps_scalar(indexes_out, lsp,LPC_ORD);
+       if (indexes_in[lsp_number] != indexes_out[lsp_number]) {
+           printf("freq: %f index_in: %d index_out: %d\n",
+                  lsp[lsp_number]+1, indexes_in[lsp_number],
+                  indexes_out[lsp_number]);
+           exit(0);
+       }
+    }
+
+    for(i=0; i<LPC_ORD; i++)
+       indexes[i] = 0;
+    indexes[lsp_number] = 0;
+    decode_lsps_scalar(lsp, indexes, LPC_ORD);
+    lowf = lsp[lsp_number];
+    indexes[lsp_number] = levels - 1;
+    decode_lsps_scalar(lsp, indexes, LPC_ORD);
+    highf = lsp[lsp_number];
+    sprintf(s,"lsp%d_err.txt", lsp_number+1);
+    flsp = fopen(s, "wt");
+
+    for(f=lowf; f<highf; f +=(highf-lowf)/1000.0) {
+       lsp[lsp_number] = f;
+       encode_lsps_scalar(indexes, lsp, LPC_ORD);
+       decode_lsps_scalar(lsp, indexes, LPC_ORD);
+       error = f - lsp[lsp_number];
+       fprintf(flsp, "%f\n", error);
+       if (fabs(error) > max_error_rads) {
+           printf("%d error: %f %f\n", lsp_number+1, error, max_error_rads);
+           exit(0);
+       }
+    }
+
+    fclose(flsp);
+
+    printf("OK\n");
+
+    return 0;
+}
+
+int test_Wo_quant() {
+    int    c;
+    FILE  *f;
+    float  Wo,Wo_dec, error, step_size;
+    int    index, index_in, index_out;
+
+    /* output Wo quant curve for plotting */
+
+    f = fopen("quant_pitch.txt","wt");
+
+    for(Wo=0.9*(TWO_PI/P_MAX); Wo<=1.1*(TWO_PI/P_MIN); Wo += 0.001) {
+       index = encode_Wo(Wo, WO_BITS);
+       fprintf(f, "%f %d\n", Wo, index);
+    }
+
+    fclose(f);
+
+    /* check for all Wo codes we get 1:1 match between encoder
+       and decoder Wo levels */
+
+    for(c=0; c<WO_LEVELS; c++) {
+       index_in = c;
+       Wo = decode_Wo(index_in, WO_BITS);
+        index_out = encode_Wo(Wo, WO_BITS);
+       if (index_in != index_out)
+           printf("  Wo %f index_in %d index_out %d\n", Wo,
+                  index_in, index_out);
+    }
+
+    /* measure quantisation error stats and compare to expected.  Also
+       plot histogram of error file to check. */
+
+    f = fopen("quant_pitch_err.txt","wt");
+    step_size = ((TWO_PI/P_MIN) - (TWO_PI/P_MAX))/WO_LEVELS;
+
+    for(Wo=TWO_PI/P_MAX; Wo<0.99*TWO_PI/P_MIN; Wo += 0.0001) {
+       index = encode_Wo(Wo, WO_BITS);
+       Wo_dec = decode_Wo(index, WO_BITS);
+       error = Wo - Wo_dec;
+       if (fabs(error) > (step_size/2.0)) {
+           printf("error: %f  step_size/2: %f\n", error, step_size/2.0);
+           exit(0);
+       }
+       fprintf(f,"%f\n",error);
+    }
+    printf("OK\n");
+
+    fclose(f);
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/tsrc.c b/codec2/branches/0.7/unittest/tsrc.c
new file mode 100644 (file)
index 0000000..6791b51
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+   tsrc.c
+   David Rowe
+   Sat Nov 3 2012
+
+   Unit test for libresample code.
+
+   build: gcc tsrc.c -o tsrc -lm -lsamplerate
+
+  */
+
+#include <assert.h>
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <samplerate.h>
+#include <unistd.h>
+
+#define N    10000                   /* processing buffer size */
+
+void display_help(void) {
+    fprintf(stderr, "\nusage: tsrc inputRawFile OutputRawFile OutSampleRatio [-l] [-c]\n");
+    fprintf(stderr, "\nUse - for stdin/stdout\n\n");
+    fprintf(stderr, "-l fast linear resampler\n");
+    fprintf(stderr, "-c complex (two channel) resampling\n\n");
+}
+
+int main(int argc, char *argv[]) {
+    FILE       *fin, *fout;
+    short       in_short[N], out_short[N];
+    float       in[N], out[N];
+    SRC_STATE  *src;
+    SRC_DATA    data;
+    int         error, nin, nremaining, i;
+
+    if (argc < 3) {
+       display_help();
+       exit(1);
+    }
+
+    if (strcmp(argv[1], "-") == 0) 
+        fin = stdin;
+    else
+        fin = fopen(argv[1], "rb");
+    assert(fin != NULL);
+
+    if (strcmp(argv[2], "-") == 0) 
+        fout = stdout;
+    else
+        fout = fopen(argv[2], "wb");
+    assert(fout != NULL);
+
+    data.data_in = in;
+    data.data_out = out;
+    data.end_of_input = 0;
+    data.src_ratio = atof(argv[3]);
+
+    int channels = 1;
+    int resampler = SRC_SINC_FASTEST;
+    int opt;
+    while ((opt = getopt(argc, argv, "lc")) != -1) {
+        switch (opt) {
+        case 'l': resampler = SRC_LINEAR; break;
+        case 'c': channels = 2; break;
+        default:
+            display_help();
+            exit(1);
+        }
+    }
+
+    data.input_frames = N/channels;
+    data.output_frames = N/channels;
+
+    src = src_new(resampler, channels, &error);
+    assert(src != NULL);
+
+    int total_in = 0;
+    int total_out = 0;
+
+    nin = data.input_frames;
+    nremaining = 0;
+    while(fread(&in_short[nremaining*channels], sizeof(short)*channels, nin, fin) == nin) {
+       src_short_to_float_array(in_short, in, N);
+       error = src_process(src, &data);
+        assert(error == 0);
+       src_float_to_short_array(out, out_short, data.output_frames_gen*channels);
+
+       fwrite(out_short, sizeof(short), data.output_frames_gen*channels, fout);
+        if (fout == stdout) fflush(stdout);
+
+        nremaining = data.input_frames - data.input_frames_used;
+        nin = data.input_frames_used;
+       //fprintf(stderr, "input frames: %d output_frames %d nremaining: %d\n", 
+        //        (int)data.input_frames_used, (int)data.output_frames_gen, nremaining);
+        for(i=0; i<nremaining*channels; i++)
+            in_short[i] = in_short[i+nin*channels];
+
+        total_in  += data.input_frames_used;
+        total_out += data.output_frames_gen;
+    }
+
+    //fprintf(stderr, "total_in: %d total_out: %d\n", total_in, total_out);
+
+    fclose(fout);
+    fclose(fin);
+
+    return 0;
+}
diff --git a/codec2/branches/0.7/unittest/vq_train_jvm.c b/codec2/branches/0.7/unittest/vq_train_jvm.c
new file mode 100755 (executable)
index 0000000..a63e54d
--- /dev/null
@@ -0,0 +1,487 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: vq_train_jvm.c
+  AUTHOR......: Jean-Marc Valin
+  DATE CREATED: 21 Jan 2012
+
+  Multi-stage Vector Quantiser training program developed by Jean-Marc at
+  linux.conf.au 2012.  Minor mods by David Rowe
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2012 Jean-Marc Valin
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#ifdef VALGRIND
+#include <valgrind/memcheck.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#define COEF 0.0f
+#define MAX_ENTRIES 16384
+
+void compute_weights(const float *x, float *w, int ndim)
+{
+  int i;
+  w[0] = MIN(x[0], x[1]-x[0]);
+  for (i=1;i<ndim-1;i++)
+    w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]);
+  w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], M_PI-x[ndim-1]);
+
+  for (i=0;i<ndim;i++)
+    w[i] = 1./(.01+w[i]);
+  w[0]*=3;
+  w[1]*=2;
+}
+
+int find_nearest(const float *codebook, int nb_entries, float *x, int ndim, float *min_dist)
+{
+  int i, j;
+  int nearest = 0;
+
+  *min_dist = 1E15;
+
+  for (i=0;i<nb_entries;i++)
+  {
+    float dist=0;
+    for (j=0;j<ndim;j++)
+      dist += (x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]);
+    if (dist<*min_dist)
+    {
+      *min_dist = dist;
+      nearest = i;
+    }
+  }
+  return nearest;
+}
+
+int find_nearest_weighted(const float *codebook, int nb_entries, float *x, const float *w, int ndim)
+{
+  int i, j;
+  float min_dist = 1e15;
+  int nearest = 0;
+
+  for (i=0;i<nb_entries;i++)
+  {
+    float dist=0;
+    for (j=0;j<ndim;j++)
+      dist += w[j]*(x[j]-codebook[i*ndim+j])*(x[j]-codebook[i*ndim+j]);
+    if (dist<min_dist)
+    {
+      min_dist = dist;
+      nearest = i;
+    }
+  }
+  return nearest;
+}
+
+int quantize_lsp(const float *x, const float *codebook1, const float *codebook2,
+                const float *codebook3, int nb_entries, float *xq, int ndim)
+{
+  int i, n1, n2, n3;
+  float err[ndim], err2[ndim], err3[ndim];
+  float w[ndim], w2[ndim], w3[ndim], min_dist;
+
+  w[0] = MIN(x[0], x[1]-x[0]);
+  for (i=1;i<ndim-1;i++)
+    w[i] = MIN(x[i]-x[i-1], x[i+1]-x[i]);
+  w[ndim-1] = MIN(x[ndim-1]-x[ndim-2], M_PI-x[ndim-1]);
+
+  /*
+  for (i=0;i<ndim;i++)
+    w[i] = 1./(.003+w[i]);
+  w[0]*=3;
+  w[1]*=2;*/
+  compute_weights(x, w, ndim);
+
+  for (i=0;i<ndim;i++)
+    err[i] = x[i]-COEF*xq[i];
+  n1 = find_nearest(codebook1, nb_entries, err, ndim, &min_dist);
+
+  for (i=0;i<ndim;i++)
+  {
+    xq[i] = COEF*xq[i] + codebook1[ndim*n1+i];
+    err[i] -= codebook1[ndim*n1+i];
+  }
+  for (i=0;i<ndim/2;i++)
+  {
+    err2[i] = err[2*i];
+    err3[i] = err[2*i+1];
+    w2[i] = w[2*i];
+    w3[i] = w[2*i+1];
+  }
+  n2 = find_nearest_weighted(codebook2, nb_entries, err2, w2, ndim/2);
+  n3 = find_nearest_weighted(codebook3, nb_entries, err3, w3, ndim/2);
+
+  for (i=0;i<ndim/2;i++)
+  {
+    xq[2*i] += codebook2[ndim*n2/2+i];
+    xq[2*i+1] += codebook3[ndim*n3/2+i];
+  }
+  return 0;
+}
+
+void split(float *codebook, int nb_entries, int ndim)
+{
+  int i,j;
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim;j++)
+    {
+      float delta = .01*(rand()/(float)RAND_MAX-.5);
+      codebook[i*ndim+j] += delta;
+      codebook[(i+nb_entries)*ndim+j] = codebook[i*ndim+j] - delta;
+    }
+  }
+}
+
+void update(float *data, int nb_vectors, float *codebook, int nb_entries, int ndim)
+{
+  int i,j;
+  int count[nb_entries];
+  int nearest[nb_vectors];
+  float min_dist;
+  float total_min_dist = 0;
+
+  for (i=0;i<nb_entries;i++)
+    count[i] = 0;
+
+  for (i=0;i<nb_vectors;i++)
+  {
+      nearest[i] = find_nearest(codebook, nb_entries, data+i*ndim, ndim, &min_dist);
+      total_min_dist += min_dist;
+  }
+  for (i=0;i<nb_entries*ndim;i++)
+    codebook[i] = 0;
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    int n = nearest[i];
+    count[n]++;
+    for (j=0;j<ndim;j++)
+      codebook[n*ndim+j] += data[i*ndim+j];
+  }
+
+  float w2=0;
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim;j++)
+      codebook[i*ndim+j] *= (1./count[i]);
+    w2 += (count[i]/(float)nb_vectors)*(count[i]/(float)nb_vectors);
+  }
+  fprintf(stderr, "%f / %d var = %f\n", 1./w2, nb_entries, total_min_dist/nb_vectors );
+}
+
+void update_weighted(float *data, float *weight, int nb_vectors, float *codebook, int nb_entries, int ndim)
+{
+  int i,j;
+  float count[MAX_ENTRIES][ndim];
+  int nearest[nb_vectors];
+
+  for (i=0;i<nb_entries;i++)
+    for (j=0;j<ndim;j++)
+      count[i][j] = 0;
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    nearest[i] = find_nearest_weighted(codebook, nb_entries, data+i*ndim, weight+i*ndim, ndim);
+  }
+  for (i=0;i<nb_entries*ndim;i++)
+    codebook[i] = 0;
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    int n = nearest[i];
+    for (j=0;j<ndim;j++)
+    {
+      float w = sqrt(weight[i*ndim+j]);
+      count[n][j]+=w;
+      codebook[n*ndim+j] += w*data[i*ndim+j];
+    }
+  }
+
+  //float w2=0;
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim;j++)
+      codebook[i*ndim+j] *= (1./count[i][j]);
+    //w2 += (count[i]/(float)nb_vectors)*(count[i]/(float)nb_vectors);
+  }
+  //fprintf(stderr, "%f / %d\n", 1./w2, nb_entries);
+}
+
+void vq_train(float *data, int nb_vectors, float *codebook, int nb_entries, int ndim)
+{
+  int i, j, e;
+  e = 1;
+
+  for (j=0;j<ndim;j++)
+    codebook[j] = 0;
+  for (i=0;i<nb_vectors;i++)
+    for (j=0;j<ndim;j++)
+      codebook[j] += data[i*ndim+j];
+  for (j=0;j<ndim;j++)
+    codebook[j] *= (1./nb_vectors);
+
+  while (e< nb_entries)
+  {
+    split(codebook, e, ndim);
+    fprintf(stderr, "%d\n", e);
+    e<<=1;
+    for (j=0;j<ndim;j++)
+      update(data, nb_vectors, codebook, e, ndim);
+  }
+}
+
+void vq_train_weighted(float *data, float *weight, int nb_vectors, float *codebook, int nb_entries, int ndim)
+{
+  int i, j, e;
+  e = 1;
+  for (j=0;j<ndim;j++)
+    codebook[j] = 0;
+  for (i=0;i<nb_vectors;i++)
+    for (j=0;j<ndim;j++)
+      codebook[j] += data[i*ndim+j];
+  for (j=0;j<ndim;j++)
+    codebook[j] *= (1./nb_vectors);
+
+  while (e<nb_entries)
+  {
+    split(codebook, e, ndim);
+    fprintf(stderr, "%d\n", e);
+    e<<=1;
+    for (j=0;j<ndim;j++)
+      update_weighted(data, weight, nb_vectors, codebook, e, ndim);
+  }
+}
+
+
+int main(int argc, char **argv)
+{
+  int i,j;
+  FILE *ftrain;
+  int nb_vectors, nb_entries, ndim;
+  float *data, *pred, *codebook, *codebook2, *codebook3;
+  float *weight, *weight2, *weight3;
+  float *delta, *delta2;
+  float tmp, err, min_dist, total_min_dist, ret;
+  char filename[256];
+  FILE *fcb;
+
+  printf("Jean-Marc Valin's Split VQ training program....\n");
+
+  if (argc != 5) {
+      printf("usage: %s TrainTextFile K(dimension) M(codebook size) VQFilesPrefix\n", argv[0]);
+      exit(1);
+  }
+
+  ndim = atoi(argv[2]);
+  nb_vectors = atoi(argv[3]);
+  nb_entries = atoi(argv[3]);
+
+  /* determine size of training file */
+
+  ftrain = fopen(argv[1],"rt");  assert(ftrain != NULL);
+  nb_vectors = 0;
+  while (1) {
+    if (feof(ftrain))
+      break;
+    for (j=0;j<ndim;j++)
+    {
+       ret = fscanf(ftrain, "%f ", &tmp);
+        assert(ret == 1);
+    }
+    nb_vectors++;
+    if ((nb_vectors % 1000) == 0)
+       printf("\r%d lines",nb_vectors);
+  }
+
+  rewind(ftrain);
+
+  printf("\nndim %d nb_vectors %d nb_entries %d\n", ndim, nb_vectors, nb_entries);
+
+  data = malloc(nb_vectors*ndim*sizeof(*data));
+  weight = malloc(nb_vectors*ndim*sizeof(*weight));
+  weight2 = malloc(nb_vectors*ndim*sizeof(*weight2));
+  weight3 = malloc(nb_vectors*ndim*sizeof(*weight3));
+  pred = malloc(nb_vectors*ndim*sizeof(*pred));
+  codebook = malloc(nb_entries*ndim*sizeof(*codebook));
+  codebook2 = malloc(nb_entries*ndim*sizeof(*codebook2));
+  codebook3 = malloc(nb_entries*ndim*sizeof(*codebook3));
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    if (feof(ftrain))
+      break;
+    for (j=0;j<ndim;j++)
+    {
+       ret = fscanf(ftrain, "%f ", &data[i*ndim+j]);
+        assert(ret == 1);
+    }
+  }
+  nb_vectors = i;
+
+#ifdef VALGRIND
+  VALGRIND_CHECK_MEM_IS_DEFINED(data, nb_entries*ndim);
+#endif
+
+  /* determine weights for each training vector */
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    compute_weights(data+i*ndim, weight+i*ndim, ndim);
+    for (j=0;j<ndim/2;j++)
+    {
+      weight2[i*ndim/2+j] = weight[i*ndim+2*j];
+      weight3[i*ndim/2+j] = weight[i*ndim+2*j+1];
+    }
+  }
+
+  /* 20ms (two frame gaps) initial predictor state */
+
+  for (i=0;i<ndim;i++) {
+    pred[i+ndim] = pred[i] = data[i] - M_PI*(i+1)/(ndim+1);
+  }
+
+  /* generate predicted data for training */
+
+  for (i=2;i<nb_vectors;i++)
+  {
+    for (j=0;j<ndim;j++)
+      pred[i*ndim+j] = data[i*ndim+j] - COEF*data[(i-2)*ndim+j];
+  }
+
+#ifdef VALGRIND
+  VALGRIND_CHECK_MEM_IS_DEFINED(pred, nb_entries*ndim);
+#endif
+
+  /* train first stage */
+
+  vq_train(pred, nb_vectors, codebook, nb_entries, ndim);
+
+  delta = malloc(nb_vectors*ndim*sizeof(*data));
+  err = 0;
+  total_min_dist = 0;
+  for (i=0;i<nb_vectors;i++)
+  {
+      int nearest = find_nearest(codebook, nb_entries, &pred[i*ndim], ndim, &min_dist);
+      total_min_dist += min_dist;
+    for (j=0;j<ndim;j++)
+    {
+      //delta[i*ndim+j] = data[i*ndim+j] - codebook[nearest*ndim+j];
+      //printf("%f ", delta[i*ndim+j]);
+      //err += (delta[i*ndim+j])*(delta[i*ndim+j]);
+      delta[i*ndim/2+j/2+(j&1)*nb_vectors*ndim/2] = pred[i*ndim+j] - codebook[nearest*ndim+j];
+      //printf("%f ", delta[i*ndim/2+j/2+(j&1)*nb_vectors*ndim/2]);
+      err += (delta[i*ndim/2+j/2+(j&1)*nb_vectors*ndim/2])*(delta[i*ndim/2+j/2+(j&1)*nb_vectors*ndim/2]);
+    }
+    //printf("\n");
+  }
+  fprintf(stderr, "Stage 1 LSP RMS error: %f\n", sqrt(err/nb_vectors/ndim));
+  fprintf(stderr, "Stage 1 LSP variance.: %f\n", total_min_dist/nb_vectors);
+
+#if 1
+  vq_train(delta, nb_vectors, codebook2, nb_entries, ndim/2);
+  vq_train(delta+ndim*nb_vectors/2, nb_vectors, codebook3, nb_entries, ndim/2);
+#else
+  vq_train_weighted(delta, weight2, nb_vectors, codebook2, nb_entries, ndim/2);
+  vq_train_weighted(delta+ndim*nb_vectors/2, weight3, nb_vectors, codebook3, nb_entries, ndim/2);
+#endif
+
+  err = 0;
+  total_min_dist = 0;
+
+  delta2 = delta + nb_vectors*ndim/2;
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    int n1, n2;
+    n1 = find_nearest(codebook2, nb_entries, &delta[i*ndim/2], ndim/2, &min_dist);
+    for (j=0;j<ndim/2;j++)
+    {
+      delta[i*ndim/2+j] = delta[i*ndim/2+j] - codebook2[n1*ndim/2+j];
+      err += (delta[i*ndim/2+j])*(delta[i*ndim/2+j]);
+    }
+    total_min_dist += min_dist;
+
+    n2 = find_nearest(codebook3, nb_entries, &delta2[i*ndim/2], ndim/2, &min_dist);
+    for (j=0;j<ndim/2;j++)
+    {
+      delta[i*ndim/2+j] = delta[i*ndim/2+j] - codebook2[n2*ndim/2+j];
+      err += (delta2[i*ndim/2+j])*(delta2[i*ndim/2+j]);
+    }
+    total_min_dist += min_dist;
+  }
+  fprintf(stderr, "Stage 2 LSP RMS error: %f\n", sqrt(err/nb_vectors/ndim));
+  fprintf(stderr, "Stage 2 LSP Variance.: %f\n", total_min_dist/nb_vectors);
+
+  float xq[ndim];
+  for (i=0;i<ndim;i++)
+    xq[i] = M_PI*(i+1)/(ndim+1);
+
+  for (i=0;i<nb_vectors;i++)
+  {
+    quantize_lsp(data+i*ndim, codebook, codebook2,
+                codebook3, nb_entries, xq, ndim);
+    /*for (j=0;j<ndim;j++)
+      printf("%f ", xq[j]);
+    printf("\n");*/
+  }
+
+  /* save output tables to text files */
+
+  sprintf(filename, "%s1.txt", argv[4]);
+  fcb = fopen(filename, "wt"); assert(fcb != NULL);
+  fprintf(fcb, "%d %d\n", ndim, nb_entries);
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim;j++)
+       fprintf(fcb, "%f ", codebook[i*ndim+j]);
+    fprintf(fcb, "\n");
+  }
+  fclose(fcb);
+
+  sprintf(filename, "%s2.txt", argv[4]);
+  fcb = fopen(filename, "wt"); assert(fcb != NULL);
+  fprintf(fcb, "%d %d\n", ndim/2, nb_entries);
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim/2;j++)
+       fprintf(fcb, "%f ", codebook2[i*ndim/2+j]);
+    fprintf(fcb, "\n");
+  }
+  fclose(fcb);
+
+  sprintf(filename, "%s3.txt", argv[4]);
+  fcb = fopen(filename, "wt"); assert(fcb != NULL);
+  fprintf(fcb, "%d %d\n", ndim/2, nb_entries);
+  for (i=0;i<nb_entries;i++)
+  {
+    for (j=0;j<ndim/2;j++)
+      fprintf(fcb, "%f ", codebook3[i*ndim/2+j]);
+    fprintf(fcb, "\n");
+  }
+  fclose(fcb);
+
+  return 0;
+}
diff --git a/codec2/branches/0.7/unittest/vqtrain.c b/codec2/branches/0.7/unittest/vqtrain.c
new file mode 100644 (file)
index 0000000..e5d81a1
--- /dev/null
@@ -0,0 +1,304 @@
+/*--------------------------------------------------------------------------*\
+
+       FILE........: VQTRAIN.C
+       AUTHOR......: David Rowe
+       DATE CREATED: 23/2/95
+
+       This program trains vector quantisers using K dimensional Lloyd-Max
+       method.
+
+\*--------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*-----------------------------------------------------------------------*\
+
+                               INCLUDES
+
+\*-----------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include <assert.h>
+
+/*-----------------------------------------------------------------------*\
+
+                               DEFINES
+
+\*-----------------------------------------------------------------------*/
+
+#define        DELTAQ  0.01            /* quiting distortion                   */
+#define        MAX_STR 80              /* maximum string length                */
+
+/*-----------------------------------------------------------------------*\
+
+                       FUNCTION PROTOTYPES
+
+\*-----------------------------------------------------------------------*/
+
+void zero(float v[], int k);
+void acc(float v1[], float v2[], int k);
+void norm(float v[], int k, long n);
+long quantise(float cb[], float vec[], int k, int m, float *se);
+
+/*-----------------------------------------------------------------------* \
+
+                               MAIN
+
+\*-----------------------------------------------------------------------*/
+
+int main(int argc, char *argv[]) {
+    long   k,m;                /* dimension and codebook size                  */
+    float  *vec;       /* current vector                               */
+    float  *cb;                /* vector codebook                              */
+    float  *cent;      /* centroids for each codebook entry            */
+    long   *n;         /* number of vectors in this interval           */
+    long   J;          /* number of vectors in training set            */
+    long   i,j;
+    long   ind;                /* index of current vector                      */
+    float  se;         /* squared error for this iteration             */
+    float  Dn,Dn_1;    /* current and previous iterations distortion   */
+    float  delta;      /* improvement in distortion                    */
+    FILE   *ftrain;    /* file containing training set                 */
+    FILE   *fvq;       /* file containing vector quantiser             */
+    int     ret;
+
+    /* Interpret command line arguments */
+
+    if (argc != 5)     {
+       printf("usage: %s TrainFile K(dimension) M(codebook size) VQFile\n", argv[0]);
+       exit(1);
+    }
+
+    /* Open training file */
+
+    ftrain = fopen(argv[1],"rb");
+    if (ftrain == NULL) {
+       printf("Error opening training database file: %s\n",argv[1]);
+       exit(1);
+    }
+
+    /* determine k and m, and allocate arrays */
+
+    k = atol(argv[2]);
+    m = atol(argv[3]);
+    printf("dimension K=%ld  number of entries M=%ld\n", k, m);
+    vec = (float*)malloc(sizeof(float)*k);
+    cb = (float*)malloc(sizeof(float)*k*m);
+    cent = (float*)malloc(sizeof(float)*k*m);
+    n = (long*)malloc(sizeof(long)*m);
+    if (cb == NULL || cb == NULL || cent == NULL || vec == NULL) {
+       printf("Error in malloc.\n");
+       exit(1);
+    }
+
+    /* determine size of training set */
+
+    J = 0;
+    while(fread(vec, sizeof(float), k, ftrain) == (size_t)k)
+    J++;
+    printf("J=%ld entries in training set\n", J);
+
+    /* set up initial codebook state from samples of training set */
+
+    rewind(ftrain);
+    ret = fread(cb, sizeof(float), k*m, ftrain);
+    assert(ret == k*m);
+
+    /* main loop */
+
+    Dn = 1E32;
+    j = 1;
+    do {
+       Dn_1 = Dn;
+
+       /* zero centroids */
+
+       for(i=0; i<m; i++) {
+           zero(&cent[i*k], k);
+           n[i] = 0;
+       }
+
+       /* quantise training set */
+
+       se = 0.0;
+       rewind(ftrain);
+       for(i=0; i<J; i++) {
+           ret = fread(vec, sizeof(float), k, ftrain);
+            assert(ret == k);
+           ind = quantise(cb, vec, k, m, &se);
+           n[ind]++;
+           acc(&cent[ind*k], vec, k);
+       }
+       Dn = se/J;
+       delta = (Dn_1-Dn)/Dn;
+
+       printf("\r  Iteration %ld, Dn = %f, Delta = %e\n", j, Dn, delta);
+       j++;
+
+       /* determine new codebook from centroids */
+
+       if (delta > DELTAQ)
+           for(i=0; i<m; i++) {
+               if (n[i] != 0) {
+                   norm(&cent[i*k], k, n[i]);
+                   memcpy(&cb[i*k], &cent[i*k], k*sizeof(float));
+               }
+           }
+
+    } while (delta > DELTAQ);
+
+    /* save codebook to disk */
+
+    fvq = fopen(argv[4],"wt");
+    if (fvq == NULL) {
+       printf("Error opening VQ file: %s\n",argv[4]);
+       exit(1);
+    }
+
+    fprintf(fvq,"%ld %ld\n",k,m);
+    for(j=0; j<m; j++) {
+       for(i=0; i<k; i++)
+           fprintf(fvq,"%f  ",cb[j*k+i]);
+       fprintf(fvq,"\n");
+    }
+    fclose(fvq);
+
+    return 0;
+}
+
+/*-----------------------------------------------------------------------*\
+
+                               FUNCTIONS
+
+\*-----------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: zero()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 23/2/95
+
+       Zeros a vector of length k.
+
+\*---------------------------------------------------------------------------*/
+
+void zero(float v[], int k)
+/*  float  v[];                ptr to start of vector          */
+/*  int    k;          lngth of vector                 */
+{
+    int        i;
+
+    for(i=0; i<k; i++)
+       v[i] = 0.0;
+}
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: acc()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 23/2/95
+
+       Adds k dimensional vectors v1 to v2 and stores the result back in v1.
+
+\*---------------------------------------------------------------------------*/
+
+void acc(float v1[], float v2[], int k)
+/*  float  v1[];       ptr to start of vector to accumulate    */
+/*  float  v2[];       ptr to start of vector to add           */
+/*  int           k;           dimension of vectors                    */
+{
+    int           i;
+
+    for(i=0; i<k; i++)
+       v1[i] += v2[i];
+}
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: norm()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 23/2/95
+
+       Divides each element in k dimensional vector v by n.
+
+\*---------------------------------------------------------------------------*/
+
+void norm(float v[], int k, long n)
+/*  float  v[];                ptr to start of vector          */
+/*  int           k;           dimension of vectors            */
+/*  int           n;           normalising factor              */
+{
+    int           i;
+
+    for(i=0; i<k; i++)
+       v[i] /= n;
+}
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: quantise()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 23/2/95
+
+       Quantises vec by choosing the nearest vector in codebook cb, and
+       returns the vector index.  The squared error of the quantised vector
+       is added to se.
+
+\*---------------------------------------------------------------------------*/
+
+long quantise(float cb[], float vec[], int k, int m, float *se)
+/* float   cb[][K];    current VQ codebook             */
+/* float   vec[];      vector to quantise              */
+/* int    k;           dimension of vectors            */
+/* int     m;          size of codebook                */
+/* float   *se;                accumulated squared error       */
+{
+   float   e;          /* current error                */
+   long           besti;       /* best index so far            */
+   float   beste;      /* best error so far            */
+   long           j;
+   int     i;
+   float   diff;
+
+   besti = 0;
+   beste = 1E32;
+   for(j=0; j<m; j++) {
+       e = 0.0;
+       for(i=0; i<k; i++) {
+           diff = cb[j*k+i]-vec[i];
+           e += pow(diff,2.0);
+       }
+       if (e < beste) {
+           beste = e;
+           besti = j;
+       }
+   }
+
+   *se += beste;
+
+   return(besti);
+}
+
diff --git a/codec2/branches/0.7/wav/all.wav b/codec2/branches/0.7/wav/all.wav
new file mode 100644 (file)
index 0000000..ba37838
Binary files /dev/null and b/codec2/branches/0.7/wav/all.wav differ
diff --git a/codec2/branches/0.7/wav/cross.wav b/codec2/branches/0.7/wav/cross.wav
new file mode 100644 (file)
index 0000000..f9f2d04
Binary files /dev/null and b/codec2/branches/0.7/wav/cross.wav differ
diff --git a/codec2/branches/0.7/wav/cross_melp2400.wav b/codec2/branches/0.7/wav/cross_melp2400.wav
new file mode 100644 (file)
index 0000000..0b314b8
Binary files /dev/null and b/codec2/branches/0.7/wav/cross_melp2400.wav differ
diff --git a/codec2/branches/0.7/wav/f2400.wav b/codec2/branches/0.7/wav/f2400.wav
new file mode 100644 (file)
index 0000000..35c41d9
Binary files /dev/null and b/codec2/branches/0.7/wav/f2400.wav differ
diff --git a/codec2/branches/0.7/wav/forig.wav b/codec2/branches/0.7/wav/forig.wav
new file mode 100644 (file)
index 0000000..81f3f9f
Binary files /dev/null and b/codec2/branches/0.7/wav/forig.wav differ
diff --git a/codec2/branches/0.7/wav/forig_ambe2000.wav b/codec2/branches/0.7/wav/forig_ambe2000.wav
new file mode 100644 (file)
index 0000000..35b27cf
Binary files /dev/null and b/codec2/branches/0.7/wav/forig_ambe2000.wav differ
diff --git a/codec2/branches/0.7/wav/forig_speex_8k.wav b/codec2/branches/0.7/wav/forig_speex_8k.wav
new file mode 100644 (file)
index 0000000..ac816f9
Binary files /dev/null and b/codec2/branches/0.7/wav/forig_speex_8k.wav differ
diff --git a/codec2/branches/0.7/wav/hts1a.wav b/codec2/branches/0.7/wav/hts1a.wav
new file mode 100644 (file)
index 0000000..f605089
Binary files /dev/null and b/codec2/branches/0.7/wav/hts1a.wav differ
diff --git a/codec2/branches/0.7/wav/hts1a_ambe2000.wav b/codec2/branches/0.7/wav/hts1a_ambe2000.wav
new file mode 100644 (file)
index 0000000..f1f107b
Binary files /dev/null and b/codec2/branches/0.7/wav/hts1a_ambe2000.wav differ
diff --git a/codec2/branches/0.7/wav/hts1a_c2_v0.1.wav b/codec2/branches/0.7/wav/hts1a_c2_v0.1.wav
new file mode 100644 (file)
index 0000000..f41c70c
Binary files /dev/null and b/codec2/branches/0.7/wav/hts1a_c2_v0.1.wav differ
diff --git a/codec2/branches/0.7/wav/hts1a_c2_v0.1a.wav b/codec2/branches/0.7/wav/hts1a_c2_v0.1a.wav
new file mode 100644 (file)
index 0000000..60bc3f0
Binary files /dev/null and b/codec2/branches/0.7/wav/hts1a_c2_v0.1a.wav differ
diff --git a/codec2/branches/0.7/wav/hts1a_g729a.wav b/codec2/branches/0.7/wav/hts1a_g729a.wav
new file mode 100644 (file)
index 0000000..f475775
Binary files /dev/null and b/codec2/branches/0.7/wav/hts1a_g729a.wav differ
diff --git a/codec2/branches/0.7/wav/hts1a_lpc10.wav b/codec2/branches/0.7/wav/hts1a_lpc10.wav
new file mode 100644 (file)
index 0000000..0a73f92
Binary files /dev/null and b/codec2/branches/0.7/wav/hts1a_lpc10.wav differ
diff --git a/codec2/branches/0.7/wav/hts1a_speex_8k.wav b/codec2/branches/0.7/wav/hts1a_speex_8k.wav
new file mode 100644 (file)
index 0000000..c192ee0
Binary files /dev/null and b/codec2/branches/0.7/wav/hts1a_speex_8k.wav differ
diff --git a/codec2/branches/0.7/wav/hts2a.wav b/codec2/branches/0.7/wav/hts2a.wav
new file mode 100644 (file)
index 0000000..644b536
Binary files /dev/null and b/codec2/branches/0.7/wav/hts2a.wav differ
diff --git a/codec2/branches/0.7/wav/hts2a_ambe2000.wav b/codec2/branches/0.7/wav/hts2a_ambe2000.wav
new file mode 100644 (file)
index 0000000..432959b
Binary files /dev/null and b/codec2/branches/0.7/wav/hts2a_ambe2000.wav differ
diff --git a/codec2/branches/0.7/wav/hts2a_c2_v0.1.wav b/codec2/branches/0.7/wav/hts2a_c2_v0.1.wav
new file mode 100644 (file)
index 0000000..7f0e0f1
Binary files /dev/null and b/codec2/branches/0.7/wav/hts2a_c2_v0.1.wav differ
diff --git a/codec2/branches/0.7/wav/hts2a_c2_v0.1a.wav b/codec2/branches/0.7/wav/hts2a_c2_v0.1a.wav
new file mode 100644 (file)
index 0000000..3e60bca
Binary files /dev/null and b/codec2/branches/0.7/wav/hts2a_c2_v0.1a.wav differ
diff --git a/codec2/branches/0.7/wav/hts2a_g729a.wav b/codec2/branches/0.7/wav/hts2a_g729a.wav
new file mode 100644 (file)
index 0000000..7709a1c
Binary files /dev/null and b/codec2/branches/0.7/wav/hts2a_g729a.wav differ
diff --git a/codec2/branches/0.7/wav/hts2a_lpc10.wav b/codec2/branches/0.7/wav/hts2a_lpc10.wav
new file mode 100644 (file)
index 0000000..a1cfde5
Binary files /dev/null and b/codec2/branches/0.7/wav/hts2a_lpc10.wav differ
diff --git a/codec2/branches/0.7/wav/hts2a_speex_8k.wav b/codec2/branches/0.7/wav/hts2a_speex_8k.wav
new file mode 100644 (file)
index 0000000..98293b6
Binary files /dev/null and b/codec2/branches/0.7/wav/hts2a_speex_8k.wav differ
diff --git a/codec2/branches/0.7/wav/m2400.wav b/codec2/branches/0.7/wav/m2400.wav
new file mode 100644 (file)
index 0000000..a1fe1a5
Binary files /dev/null and b/codec2/branches/0.7/wav/m2400.wav differ
diff --git a/codec2/branches/0.7/wav/mmt1.wav b/codec2/branches/0.7/wav/mmt1.wav
new file mode 100644 (file)
index 0000000..b0526cb
Binary files /dev/null and b/codec2/branches/0.7/wav/mmt1.wav differ
diff --git a/codec2/branches/0.7/wav/mmt1_ambe2000.wav b/codec2/branches/0.7/wav/mmt1_ambe2000.wav
new file mode 100644 (file)
index 0000000..db11834
Binary files /dev/null and b/codec2/branches/0.7/wav/mmt1_ambe2000.wav differ
diff --git a/codec2/branches/0.7/wav/mmt1_c2_v01a.wav b/codec2/branches/0.7/wav/mmt1_c2_v01a.wav
new file mode 100644 (file)
index 0000000..6f80052
Binary files /dev/null and b/codec2/branches/0.7/wav/mmt1_c2_v01a.wav differ
diff --git a/codec2/branches/0.7/wav/mmt1_lpc10.wav b/codec2/branches/0.7/wav/mmt1_lpc10.wav
new file mode 100644 (file)
index 0000000..848ef23
Binary files /dev/null and b/codec2/branches/0.7/wav/mmt1_lpc10.wav differ
diff --git a/codec2/branches/0.7/wav/mmt1_speex_8k.wav b/codec2/branches/0.7/wav/mmt1_speex_8k.wav
new file mode 100644 (file)
index 0000000..f0191a2
Binary files /dev/null and b/codec2/branches/0.7/wav/mmt1_speex_8k.wav differ
diff --git a/codec2/branches/0.7/wav/morig.wav b/codec2/branches/0.7/wav/morig.wav
new file mode 100644 (file)
index 0000000..eaf52d1
Binary files /dev/null and b/codec2/branches/0.7/wav/morig.wav differ
diff --git a/codec2/branches/0.7/wav/morig_ambe2000.wav b/codec2/branches/0.7/wav/morig_ambe2000.wav
new file mode 100644 (file)
index 0000000..977611b
Binary files /dev/null and b/codec2/branches/0.7/wav/morig_ambe2000.wav differ
diff --git a/codec2/branches/0.7/wav/morig_speex_8k.wav b/codec2/branches/0.7/wav/morig_speex_8k.wav
new file mode 100644 (file)
index 0000000..d62d19b
Binary files /dev/null and b/codec2/branches/0.7/wav/morig_speex_8k.wav differ
diff --git a/codec2/branches/0.7/wav/ve9qrp.wav b/codec2/branches/0.7/wav/ve9qrp.wav
new file mode 100644 (file)
index 0000000..38454a5
Binary files /dev/null and b/codec2/branches/0.7/wav/ve9qrp.wav differ
diff --git a/codec2/branches/0.7/wav/vk5qi.wav b/codec2/branches/0.7/wav/vk5qi.wav
new file mode 100644 (file)
index 0000000..b1aaed9
Binary files /dev/null and b/codec2/branches/0.7/wav/vk5qi.wav differ
diff --git a/codec2/branches/0.7/wav/x200_ext.wav b/codec2/branches/0.7/wav/x200_ext.wav
new file mode 100644 (file)
index 0000000..38c5c4b
Binary files /dev/null and b/codec2/branches/0.7/wav/x200_ext.wav differ
diff --git a/codec2/branches/0.7/wav/x200_int.wav b/codec2/branches/0.7/wav/x200_int.wav
new file mode 100644 (file)
index 0000000..4828c2f
Binary files /dev/null and b/codec2/branches/0.7/wav/x200_int.wav differ
index 666c5fa93ee92f6d37876a80ea168d9b2dacd7c5..a9f7049645a753b1dcf507189c9178cb9643058d 100644 (file)
@@ -6,6 +6,8 @@
 # mailing list: https://lists.sourceforge.net/lists/listinfo/freetel-codec2
 #
 
+set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7" CACHE STRING "Minimum OS X deployment version")
+
 cmake_minimum_required(VERSION 2.8)
 
 # Prevent in-source builds to protect automake/autoconf config.
@@ -29,12 +31,12 @@ project(FreeDV)
 #
 set(FREEDV_VERSION_MAJOR 1)
 set(FREEDV_VERSION_MINOR 2)
-set(FREEDV_VERSION_PATCH FALSE)
+set(FREEDV_VERSION_PATCH 2)
 set(FREEDV_VERSION ${FREEDV_VERSION_MAJOR}.${FREEDV_VERSION_MINOR})
 if(FREEDV_VERSION_PATCH)
     set(FREEDV_VERSION ${FREEDV_VERSION}.${FREEDV_VERSION_PATCH})
 endif()
-set(FREEDV_VERSION_SUFFIX "devel")
+set(FREEDV_VERSION_SUFFIX FALSE)
 if(FREEDV_VERSION_SUFFIX)
     set(FREEDV_VERSION_STRING "${FREEDV_VERSION} ${FREEDV_VERSION_SUFFIX}")
 else()
@@ -45,16 +47,15 @@ configure_file(cmake/version.h.in src/version.h @ONLY)
 
 # Set default build type
 if(NOT CMAKE_BUILD_TYPE)
-    set(CMAKE_BUILD_TYPE "Release")
+    set(CMAKE_BUILD_TYPE "Debug")
     message(STATUS "Build type not specified, defaulting to ${CMAKE_BUILD_TYPE}")
 endif(NOT CMAKE_BUILD_TYPE)
 
-
 # Work around for not using a svn working copy.
 add_definitions(-D_NO_AUTOTOOLS_)
-find_program(SVNVERSION_PATH svnversion)
-if(SVNVERSION_PATH)
-    execute_process(COMMAND ${SVNVERSION_PATH} .
+find_program(SVN_PATH svn)
+if(SVN_PATH)
+    execute_process(COMMAND ${SVN_PATH} info --show-item revision
         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
         RESULT_VARIABLE SVN_REVISION_RESULT
         OUTPUT_VARIABLE SVN_CURRENT_REVISION
@@ -63,16 +64,21 @@ if(SVNVERSION_PATH)
 else()
     set(SVN_REVISION_RESULT 1)
 endif()
+
 if(SVN_REVISION_RESULT EQUAL 0)
-string(STRIP ${SVN_CURRENT_REVISION} SVN_REVISION)
-add_definitions(-DSVN_REVISION="${SVN_REVISION}")
+    string(STRIP ${SVN_CURRENT_REVISION} SVN_REVISION)
+    add_definitions(-DSVN_REVISION="${SVN_REVISION}")
 else()
-add_definitions(-DSVN_REVISION="Unversioned directory")
+    add_definitions(-DSVN_REVISION="None")
 endif()
 
 
 # Set default build flags.
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+if(APPLE)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++11")
+endif(APPLE)
 
 #
 # Setup cmake options
index 311af47081d057cc2cefbb449bc3bea04eb455d5..26e731d113fe5a00ab567986a229c539d4ab0d0b 100644 (file)
@@ -1,25 +1,70 @@
+==================================
+ FreeDV GUI README.txt
+==================================
+
+This document describes how to build the FreeDV GUI program for
+various operating systems.  See also:
+
+  http://freedv.org - introduction, documentation, downloads
+  RELEASE_NOTES.txt - changes made to each version
+  USER_MANUAL.txt   - FreeDV GUI Manual
+
 ==================================
  Building and installing on Linux
 ==================================
 
-To build codec2, the build-essential and cmake packages will be required.
-If they are not already installed, you can install them by typing
+First the basics:
+
+  $ sudo apt-get install build-essential cmake subversion
+
+To install the required development libraries instead of building them
+statically:
+
+Debian/Ubuntu:
+
+  $ sudo apt-get install libwxgtk3.0-dev portaudio19-dev \
+    libhamlib-dev libsamplerate-dev libasound2-dev libao-dev libgsm1-dev \
+    libsndfile-dev
+
+Fedora:
+
+  $ sudo dnf install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
+
+
+RHEL/CentOS and derivitves (requires Fedora EPEL repository)
+
+  $ sudo yum install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
 
-  $ sudo apt-get install build-essential cmake
 
 Quickstart 1
------------
+------------
+
+1/ Using a modern Linux, and the development library packages
+   installed above:
+
+  $ cd /path/to/freedv
+  $ mkdir build_linux
+  $ cd build_linux
+  $ cmake ../ 
+  $ make
+  $ ./src/freedv
+
+Quickstart 2
+------------
 
 Builds static versions of wxWidgets, portaudio, codec2-dev, which are commonly
-missing on many Linux systems, or of the wrong (older) version.
+missing on older Linux systems.
 
-1/ Assuming the freedv-dev source is checked out into ~/freedv-dev:
+1/ Assumes static build of wxWidgets and the freedv-dev source is checked out into ~/freedv-dev:
 
-  $ sudo apt-get install libgtk2.0-dev libhamlib-dev libsamplerate-dev libasound2-dev libao-dev libgsm1-dev libsndfile-dev
-  $ cd freedv-dev
+  $ cd ~/freedv-dev
   $ mkdir build_linux
   $ cd build_linux
-  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE ~/freedv-dev ../
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE ../
   $ make
 
 2/ Then you can configure FreeDV using your local codec-dev, something like:
@@ -35,21 +80,6 @@ missing on many Linux systems, or of the wrong (older) version.
    $ make
    $ ./src/freedv
 
-Quickstart 2
-------------
-
-1/ Assuming you have all the dependant libraries:
-
-  $ cd /path/to/freedv
-  $ mkdir build_linux
-  $ cd build_linux
-  $ cmake ../ (defaults to /usr/local, use CMAKE_INSTALL_PREFIX to override)
-  (if no errors)
-  $ make
-  (as root)
-  $ make install
-
-
 =======================================================
  Building for Windows on Ubuntu Linux (Cross compiling)
 =======================================================
@@ -172,172 +202,32 @@ configure emacs:
                       (setq c-basic-offset 4)
                       )))
 
-====
-TODO
-====
-
-[ ] Open R&D questions
-    + Goal is to develop an open source DV mode that performs comparably to SSB
-    [ ] Does 700 perform OK next to SSB?
-        + approx same tx pk level (hard to measure exactly)
-        + try some low SNR channels
-        + try some fast fading/nasty channels
-    [ ] Is 700 speech quality acceptable?
-
-[X] test frames 
-    [X] freedv API support
-    [X] BER displayed on GUI for 700 and 1600
-    [X] plot error patterns for 700 and 1600
-        + callback for error patterns, or poll via stats interface
-    [X] plot error histograms for 700 and 1600
-        + map bit error to carrier, have done this in tcohpsk?
-        + how to reset histogram?  On error reset?
-        + histogram screen ... new code?
-        + test with filter
-
-[X] Bugs
-    [X] resync issue
-    [X] equalise power on 700 and 1600
-    [X] research real and complex PAPR
-    [X] waterfall and spectrum in analog mode
-    [X] The waterfall in analog mode appears to quit working sometimes?
-
-    [X] On TX, intermittently PTT will cause signal to be heard in speakers.  Toggle PTT or 
-        Stop/Start toggle and then starts working.
-    [X] Squelch control on 1600 mode will not open up squelch to 0 (appears to be around 2 dB)
-    [X] space bar keys PTT when entering text info box
-    [X] checksum based txt reception
-        + only print if valid
-    [X] IC7200 audio breakup
-    [ ] short varicode doesn't work
-        + #ifdef-ed out for now
-        + cld be broken in freedv_api
-    [X] On 700 audio sounds tinny and clicky when out of sync compared to 1600 why?
-        + clue: only when analog not pressed
-        + this was 7.5 to 8kHz interpolator bug
-    [X] spectrum and waterfall scale changes when analog pressed
-    [X] ocassional test frames error counter goes crazy
-    [ ] old Waterfall AGC
-    [ ] 700 syncs up to 1000Hz sine waves
-        + shouldn't trigger sync logic, will be a problem with carriers
-    [ ] "clip" led, encourage people to adjust gain to hit that occ when speaking
-    [ ] Win32 record from radio time
-    [ ] Stuttering with squelch off
-        + Rpeorted by Mark VK5QI, can we repeat?
-
-[ ] FreeDV 700 improvements
-    [ ] bpf filter after clipping to remove clicks
-        [ ] tcohpsk first, measure PAPR, impl loss
-    [ ] error masking
-        [ ] C version
-        [ ] training off air?  Switchable?
-        [ ] excitation params
-        [ ] training
-    [ ] plotting other demod stats like ch ampl and phase ests
-    [ ] profile with perf, different libresample routine
-    [ ] check for occassional freedv 700 loss of sync
-        + scatter seems to jump
-    [ ] switchable diversity (narrowband) option
-        + measure difference on a few channels
-        + blog
-    [ ] slow mode at half speed rather than repeating, or tx twice and sum
-    [ ] Can freedv remove ambient rf with a simple second Rx?
-    [ ] presence, posting to web site
-    [ ] explore relaxing sync 700 thresh
-    [ ] longer record files
-    [ ] two vertical lines in the waterfall representing the band limits of the 700B mode
-
-[X] win32
-    [X] X-compile works
-    [X] basic installer
-    [X] Win32 installer
-        + Richard has taken care of this
-
-[ ] Small fixes
-    [X] Playfile bug
-    [X] running again
-    [X] bump ver number
-    [X] long varicode default
-    [X] option to _not_ require checksum, on by default
-    [X] default squelch 2dB
-    [X] scatter diagram tweaks
-        + e.g. meaningful plots on fading channels in real time 
-        [X] agc with hysteresis
-            + changed to log steps
-        [X] longer persistance
-            + changed to 6 seconds
-        [X] diversity addtions on 700
-            + still not real obvious on plot
-            + might be useful to make this switchable
-    [X] scatter diagram different colours/carrier
-    [X] remember what mode you were in
-    [ ] cmd line file decode
-    [ ] Waterfall direction
-    [ ] documentation or use, walk through, you tube, blog posts
-
-[ ] Web support for Presence/spotting hooks
-
-=================
-USER GUIDE NOTES
-=================
-
-TODO: Put this in a more usable form (maybe parse into HTML), video
-tutorials etc...
-
-1/ Error Histogram
-------------------
-
-Displays BER of each carrier when in "test frame"
-mode.  As each QPSK carrier has 2 bits there are 2*Nc histogram
-points.
-
-Ideally all carriers will have about the same BER (+/- 20% after 5000
-total bit errors).  However problems can occur with filtering in the
-tx path.  If one carrier has less power, then it will have a higher
-BER.  The errors in this carrier will tend to dominate overall
-BER. For example if one carrier is attenuated due to SSB filter ripple
-in the tx path then the BER on that carrier will be higher.  This is
-bad news for DV.
-
-Suggested usage: 
-
-i) Transmit FreeDV in test frame mode.  Use a 2nd rx (or
-get a friend) to monitor your rx signal with FreeDV in test frame
-mode.  
-
-ii) Adjust your rx SNR to get a BER of a few % (e.g. reduce tx
-power, use a short antenna for the rx, point your beam away, adjust rx
-RF gain).  
-
-iii) Monitor the error histogram for a few minutes, until you
-have say 5000 total bit errors.  You have a problem if the BER of any
-carrier is more than 20% different from the rest.
-
-A typical issue will be one carrier at 1.0, the others at 0.5,
-indicating the poorer carrier BER is twice the larger.
-
-2/ Voice Keyer
---------------
-
-Puts FreeDV and your radio into transmit, reads a wave
-file of your voice to call CQ, then switches to receive to see if
-anyone is replying.  If you press space bar the voice keyer stops.  If
-a signal with a valid sync is received for a few seconds the voice
-keyer stops.  The Tools-PTT dialog can be used to select the wave
-file, set the Rx delay, and number of times the tx/rx cycle repeats.
-
-3/ UDP Control port
--------------------
-
-FreeDV can be controlled via UDP from other programs on the same host
-(127.0.0.1) using text strings.  The default port is 3000, and can be
-set Via Tools-Options.
-
-Currents commands:
-
-  "set txtmsg XXX" - sets the text/callsign ID string to XXX
-  "restore"        - Restores the FreeDV windowto full size if minimised
-  "ptton"          - PTT on (transmit)
-  "pttoff"         - PTT off (receive)
-
-Hint: "netcat" can be used to test this feature.
+FreeDV GUI TODO List
+--------------------
+
+[ ] Ubuntu packaging
+[ ] default sound card in/out setting for rx out of the box
+[ ] When application close on windows while "Start" down sometimes crashes
+    + Also on Linux it reports an unterminated thread when exiting
+[ ] Tool-Audio Config Dialog sound device names truncated on Windows
+[ ] Serialport::closeport() on Linux takes about 1 second 
+    + delays 'Stop' on main window test on Tools-PTT Test
+[ ] Voice keyer file name at bottom on main screen truncated
+    + need a bigger field
+[ ] Start/Stop file rec/playback, work out a better UI, 
+    maybe buttons on front page
+[ ] feature for evaluating yr own sound quality
+    + trap bad mic response/levels
+    + zero in on different sound quality from different users
+[ ] feeding audio over UDP say from from gqrx
+    + could also be used to netcat stored files
+[ ] refactoring
+    [ ] fdmdv2_main.cpp is way too long
+    [ ] rename fdmdv2*.cpp -> freedv*.cpp
+    [ ] dlg_ptt uses ComPortsDlg name internally, rename PttDlg or similar
+[ ] Add RSID
+    + use case, when would it be used?
+[ ] clean up dialogs
+    + were based on auto generation code
+    + must be an easier/clearer way to write them
+
diff --git a/freedv/branches/1.2/RELEASE_NOTES.txt b/freedv/branches/1.2/RELEASE_NOTES.txt
new file mode 100644 (file)
index 0000000..79eaeca
--- /dev/null
@@ -0,0 +1,7 @@
+V1.2.2 July 2017
+----------------
+
+1/ Improvements to Hamlib support, error message reporting, serial rate box.
+
+2/ Disabled unused UDP comms/egexp processing to clean up Options dialog.
+
diff --git a/freedv/branches/1.2/USER_MANUAL.txt b/freedv/branches/1.2/USER_MANUAL.txt
new file mode 100644 (file)
index 0000000..2cc4494
--- /dev/null
@@ -0,0 +1,100 @@
+======================
+FREEDV GUI USER MANUAL
+======================
+
+Introduction
+------------
+
+This document describes additional features in the latest FreeDV
+releases that haven't been documented in other sources.  See also
+freedv.org
+
+PTT Configuration
+-----------------
+
+Tools-PTT Dialog
+
+Hamlib comes with a default serial rate for each radio.  If your radio
+has a different serial rate change the Serial Rate drop down box to
+match your radio.
+
+When "Test" is pressed, the "Serial Params" field is populated and
+displayed.  This will help track down any mis-matches between Hamlib
+and your radio.
+
+Voice Keyer
+-----------
+
+Voice Keyer Button on Front Page
+Options-PTT Dialog
+
+Puts FreeDV and your radio into transmit, reads a wave file of your
+voice to call CQ, then switches to receive to see if anyone is
+replying.  If you press space bar the voice keyer stops.  If a signal
+with a valid sync is received for a few seconds the voice keyer stops.
+
+Options-PTT dialog can be used to select the wave file, set the Rx
+delay, and number of times the tx/rx cycle repeats.
+
+The wave file for the voice keyer should be in 8kHz mono 16 bit sample
+form.  Use a free application such as Audacity to convert a file you
+have recorded to this format.
+
+Test Frame Histogram
+--------------------
+
+Test Frame Histogram tab on Front Page
+
+Displays BER of each carrier when in "test frame" mode.  As each QPSK
+carrier has 2 bits there are 2*Nc histogram points.
+
+Ideally all carriers will have about the same BER (+/- 20% after 5000
+total bit errors).  However problems can occur with filtering in the
+tx path.  If one carrier has less power, then it will have a higher
+BER.  The errors in this carrier will tend to dominate overall
+BER. For example if one carrier is attenuated due to SSB filter ripple
+in the tx path then the BER on that carrier will be higher.  This is
+bad news for DV.
+
+Suggested usage: 
+
+i) Transmit FreeDV in test frame mode.  Use a 2nd rx (or
+get a friend) to monitor your rx signal with FreeDV in test frame
+mode.  
+
+ii) Adjust your rx SNR to get a BER of a few % (e.g. reduce tx
+power, use a short antenna for the rx, point your beam away, adjust rx
+RF gain).  
+
+iii) Monitor the error histogram for a few minutes, until you
+have say 5000 total bit errors.  You have a problem if the BER of any
+carrier is more than 20% different from the rest.
+
+A typical issue will be one carrier at 1.0, the others at 0.5,
+indicating the poorer carrier BER is twice the larger.
+
+Full Duplex Testing with loopback
+---------------------------------
+
+Options - Half Duplex check box
+
+FreeDV GUI can operate in full duplex mode which is useful for
+development of listening to your own FreeDV signal as only one PC is
+required.  Normal operation is half duplex.
+
+Tx and Rx signals can be looped back via an analog connection between
+the sound cards.
+
+On Linux, using the Alsa loopback module:
+
+  $ sudo modprobe snd-aloop
+  $ ./freedv
+
+  In Tools - Audio Config - Receive Tab  - From Radio select -> Loopback: Loopback PCM (hw:1,0)
+                          - Transmit Tab - To Radio select   -> Loopback: Loopback PCM (hw:1,1)
+
+TODO
+----
+
+[ ] Merge this information into existing start up guides
+
diff --git a/freedv/branches/1.2/freedv-dev/.clang/.gitignore b/freedv/branches/1.2/freedv-dev/.clang/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/branches/1.2/freedv-dev/CMakeLists.txt b/freedv/branches/1.2/freedv-dev/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fdc1c01
--- /dev/null
@@ -0,0 +1,463 @@
+#
+# FreeDV - HF Digital Voice for Radio Amateurs
+#
+# CMake configuration contributed by Richard Shaw (KF5OIM)
+# Please report questions, comments, problems, or patches to the freetel
+# mailing list: https://lists.sourceforge.net/lists/listinfo/freetel-codec2
+#
+
+set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7" CACHE STRING "Minimum OS X deployment version")
+
+cmake_minimum_required(VERSION 2.8)
+
+# Prevent in-source builds to protect automake/autoconf config.
+# If an in-source build is attempted, you will still need to clean up a few
+# files manually.
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
+if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+  message(FATAL_ERROR "In-source builds in ${CMAKE_BINARY_DIR} are not "   
+   "allowed, please remove ./CMakeCache.txt and ./CMakeFiles/, create a "
+   "separate build directory and run cmake from there.")
+endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+
+# Set local module path.
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+
+project(FreeDV)
+
+#
+# Set FreeDV version and generate src/version.h
+#
+set(FREEDV_VERSION_MAJOR 1)
+set(FREEDV_VERSION_MINOR 2)
+set(FREEDV_VERSION_PATCH 2)
+set(FREEDV_VERSION ${FREEDV_VERSION_MAJOR}.${FREEDV_VERSION_MINOR})
+if(FREEDV_VERSION_PATCH)
+    set(FREEDV_VERSION ${FREEDV_VERSION}.${FREEDV_VERSION_PATCH})
+endif()
+set(FREEDV_VERSION_SUFFIX "devel")
+if(FREEDV_VERSION_SUFFIX)
+    set(FREEDV_VERSION_STRING "${FREEDV_VERSION} ${FREEDV_VERSION_SUFFIX}")
+else()
+    set(FREEDV_VERSION_STRING "${FREEDV_VERSION}")
+endif()
+message(STATUS "FreeDV version: ${FREEDV_VERSION_STRING}")
+configure_file(cmake/version.h.in src/version.h @ONLY)
+
+# Set default build type
+if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Debug")
+    message(STATUS "Build type not specified, defaulting to ${CMAKE_BUILD_TYPE}")
+endif(NOT CMAKE_BUILD_TYPE)
+
+# Work around for not using a svn working copy.
+add_definitions(-D_NO_AUTOTOOLS_)
+find_program(SVN_PATH svn)
+if(SVN_PATH)
+    execute_process(COMMAND ${SVN_PATH} info --show-item revision
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        RESULT_VARIABLE SVN_REVISION_RESULT
+        OUTPUT_VARIABLE SVN_CURRENT_REVISION
+        ERROR_QUIET
+    )
+else()
+    set(SVN_REVISION_RESULT 1)
+endif()
+
+if(SVN_REVISION_RESULT EQUAL 0)
+    string(STRIP ${SVN_CURRENT_REVISION} SVN_REVISION)
+    add_definitions(-DSVN_REVISION="${SVN_REVISION}")
+else()
+    add_definitions(-DSVN_REVISION="None")
+endif()
+
+
+# Set default build flags.
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+if(APPLE)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++11")
+endif(APPLE)
+
+#
+# Setup cmake options
+#
+set(CMAKE_VERBOSE_MAKEFILE TRUE CACHE BOOL "Verbose makefile.")
+set(USE_STATIC_DEPS FALSE CACHE BOOL 
+    "Download and build static libraries instead of system libraries.")
+set(USE_STATIC_PORTAUDIO FALSE CACHE BOOL 
+    "Download and build static portaudio instead of the system library.")
+set(USE_STATIC_SNDFILE FALSE CACHE BOOL
+    "Download and build static sndfile instead of the system library.")
+set(USE_STATIC_SAMPLERATE FALSE CACHE BOOL
+    "Download and build static samplerate instead of the system library.")
+set(USE_STATIC_CODEC2 TRUE CACHE BOOL
+    "Download and build static codec2 instead of the system library.")
+set(USE_STATIC_SPEEXDSP TRUE CACHE BOOL
+    "Download and build static speex instead of the system library.")
+set(BOOTSTRAP_WXWIDGETS FALSE CACHE BOOL
+    "Download and build static wxWidgets instead of the system library.")
+
+if(USE_STATIC_DEPS)
+    set(USE_STATIC_PORTAUDIO TRUE FORCE)
+    set(USE_STATIC_SNDFILE TRUE FORCE)
+    set(USE_STATIC_SAMPLERATE TRUE FORCE)
+    set(USE_STATIC_CODEC2 TRUE FORCE)
+endif(USE_STATIC_DEPS)
+
+#
+# Pull in external wxWidgets target if performing static build.
+#
+if(BOOTSTRAP_WXWIDGETS)
+    message(STATUS "Adding wxWidgets build target...")
+    include(cmake/BuildWxWidgets.cmake)
+endif(BOOTSTRAP_WXWIDGETS)
+
+#
+# Perform bootstrap build of wxWidgets
+#
+if(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
+    message(STATUS "Will perform bootstrap build of wxWidgets.
+   After make step completes, re-run cmake and make again to perform FreeDV build.")
+#
+# Continue normal build if not bootstrapping wxWidgets or is already built.
+#
+else(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
+
+
+#
+# Various hacks and work arounds for building under MinGW.
+#
+if(MINGW)
+    message(STATUS "System is MinGW.")
+    # Setup HOST variable.
+    include(cmake/MinGW.cmake)
+    # This sets up the exe icon for windows under mingw.
+    set(RES_FILES "")
+    set(RES_FILES "${CMAKE_SOURCE_DIR}/contrib/freedv.rc")
+    set(CMAKE_RC_COMPILER_INIT windres)
+    enable_language(RC)
+    set(CMAKE_RC_COMPILE_OBJECT
+        "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
+    include(InstallRequiredSystemLibraries)
+endif(MINGW)
+
+# Math library is automatic on MinGW
+if(UNIX)
+    set(CMAKE_REQUIRED_INCLUDES math.h)
+    set(CMAKE_REQUIRED_LIBRARIES m)
+endif(UNIX)
+
+# Find some standard headers and functions.
+include(CheckIncludeFiles)
+check_include_files("byteswap.h"   HAVE_BYTESWAP_H)
+check_include_files("limits.h"     HAVE_LIMITS_H)
+check_include_files("stddef.h"     HAVE_STDDEF_H)
+check_include_files("stdlib.h"     HAVE_STDLIB_H)
+check_include_files("string.h"     HAVE_STRING_H)
+check_include_files("strings.h"    HAVE_STRINGS_H)
+check_include_files("ltdl.h"       HAVE_LTDL_H)
+check_include_files("inttypes.h"   HAVE_INTTYPES_H)
+check_include_files("sys/stat.h"   HAVE_SYS_STAT_H)
+check_include_files("sys/types.h"  HAVE_SYS_TYPES_H)
+
+include(CheckTypeSize)
+check_type_size("int" SIZEOF_INT)
+
+include(CheckFunctionExists)
+check_function_exists(floor HAVE_FLOOR)
+check_function_exists(memset HAVE_MEMSET)
+check_function_exists(pow HAVE_POW)
+check_function_exists(sqrt HAVE_SQRT)
+check_function_exists(fseeko HAVE_FSEEKO)
+check_function_exists(fmemopen HAVE_FMEMOPEN)
+check_function_exists(strcasecmp HAVE_STRCASECMP)
+check_function_exists(vsnprintf HAVE_VSNPRINTF)
+
+include(CheckSymbolExists)
+check_symbol_exists("_fseeki64" "stdio.h" HAVE__FSEEKI64)
+
+# fdmdv2_main.h requires patching to find config.h as it current looks in the
+# source directory and the generated file goes in the binary directory.
+configure_file ("${PROJECT_SOURCE_DIR}/cmake/config.h.in"
+                "${PROJECT_BINARY_DIR}/config.h" )
+include_directories(${PROJECT_BINARY_DIR})
+add_definitions(-DHAVE_CONFIG_H)
+
+# Config file for bundled sox sources
+configure_file("${PROJECT_SOURCE_DIR}/cmake/soxconfig.h.in"
+               "${PROJECT_BINARY_DIR}/soxconfig.h")
+
+# Pthread Library
+find_package(Threads REQUIRED)
+message(STATUS "Threads library flags: ${CMAKE_THREAD_LIBS_INIT}")
+
+#
+# Find codec2
+#
+if(NOT USE_STATIC_CODEC2)
+    message(STATUS "Looking for codec2...")
+    # 'CONFIG' removed due to incompatibility with cmake version
+    # in Ubuntu 12.04 (Precise) -- Stuart Longland
+    find_package(codec2 QUIET)
+    if(codec2_FOUND)
+        get_target_property(CODEC2_LIBRARY codec2 LOCATION)
+        message(STATUS "  codec2 library: ${CODEC2_LIBRARY}")
+        message(STATUS "  codec2 headers: ${codec2_INCLUDE_DIRS}")
+    else()
+        # Try to find manually
+        find_path(CODEC2_INCLUDE_DIRS codec2.h
+                  PATH_SUFFIXES codec2)
+        find_library(CODEC2_LIBRARY NAMES codec2)
+        if(CODEC2_LIBRARY AND CODEC2_INCLUDE_DIRS)
+            message(STATUS "  codec2 library: ${CODEC2_LIBRARY}")
+            message(STATUS "  codec2 headers: ${CODEC2_INCLUDE_DIRS}")
+            list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARY})
+            include_directories(${CODEC2_INCLUDE_DIRS})
+        else()
+            message(FATAL_ERROR "codec2 library not found.
+Linux: 
+Codec2 may not be in your distribution so build yourself or use the cmake option to build statically into FreeDV.
+Windws:
+It's easiest to use the cmake option: USE_STATIC_CODEC2"
+        )
+        endif()
+    endif()
+else(NOT USE_STATIC_CODEC2)
+    message(STATUS "Will attempt static build of codec2.")
+    include(cmake/BuildCodec2.cmake)
+endif(NOT USE_STATIC_CODEC2)
+
+#
+# Find or build portaudio Library
+#
+if(NOT USE_STATIC_PORTAUDIO)
+    message(STATUS "Looking for portaudio...")
+    find_package(Portaudio REQUIRED)
+    if(PORTAUDIO_FOUND)
+        message(STATUS "  portaudio library: ${PORTAUDIO_LIBRARIES}")
+        message(STATUS "  portaudio headers: ${PORTAUDIO_INCLUDE_DIRS}")
+        list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
+        include_directories(${PORTAUDIO_INCLUDE_DIRS})
+    else()
+        message(FATAL_ERROR "portaudio library not found.
+On Linux systems try installing:
+    portaudio-devel  (RPM based systems)
+    libportaudio-dev (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_PORTAUDIO"
+        )
+    endif()
+    if(NOT ${PORTAUDIO_VERSION} EQUAL 19)
+        message(WARNING "Portaudio versions other than 19 are known to have issues. You have been warned!")
+    endif()
+else(NOT USE_STATIC_PORTAUDIO)
+    message(STATUS "Will attempt static build of portaudio.")
+    include(cmake/BuildPortaudio.cmake)
+endif(NOT USE_STATIC_PORTAUDIO)
+
+#
+# Hamlib library
+#
+message(STATUS "Looking for hamlib...")
+find_path(HAMLIB_INCLUDE_DIR hamlib/rig.h)
+find_library(HAMLIB_LIBRARY hamlib PATH_SUFFIXES hamlib)
+message(STATUS "Hamlib library: ${HAMLIB_LIBRARY}")
+message(STATUS "Hamlib headers: ${HAMLIB_INCLUDE_DIR}")
+if(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+    message(STATUS "Hamlib library found.")
+    include_directories(${HAMLIB_INCLUDE_DIR})
+    list(APPEND FREEDV_LINK_LIBS ${HAMLIB_LIBRARY})
+else(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+    message(FATAL_ERROR "hamlib not found.
+On Linux systems try installing:
+    hamlib-devel  (RPM based systems)
+    libhamlib-dev (DEB based systems)"
+    )
+endif(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+
+
+#
+# Samplerate Library
+#
+if(NOT USE_STATIC_SAMPLERATE)
+    message(STATUS "Looking for samplerate...")
+    find_library(LIBSAMPLERATE samplerate)
+    find_path(LIBSAMPLERATE_INCLUDE_DIR samplerate.h)
+    message(STATUS "  samplerate library: ${LIBSAMPLERATE}")
+    message(STATUS "  samplerate headers: ${LIBSAMPLERATE_INCLUDE_DIR}")
+    if(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        list(APPEND FREEDV_LINK_LIBS ${LIBSAMPLERATE})
+        include_directories(${LIBSAMPLERATE_INCLUDE_DIR})
+    else(LIBSTAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        message(FATAL_ERROR "samplerate library not found.
+On Linux systems try installing:
+    samplerate-devel  (RPM based systems)
+    libsamplerate-dev (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_SAMPLERATE"
+        )
+    endif(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+else(NOT USE_STATIC_SAMPLERATE)
+    message(STATUS "Will attempt static build of samplerate.")
+    include(cmake/BuildSamplerate.cmake)
+endif(NOT USE_STATIC_SAMPLERATE)
+
+#    
+# sndfile Library
+#
+if(NOT USE_STATIC_SNDFILE)
+    message(STATUS "Looking for sndfile...")
+    find_library(LIBSNDFILE sndfile)
+    find_path(LIBSNDFILE_INCLUDE_DIR sndfile.h)
+    message(STATUS "  sndfile library: ${LIBSNDFILE}")
+    message(STATUS "  sndfile headers: ${LIBSNDFILE_INCLUDE_DIR}")
+    if(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+        list(APPEND FREEDV_LINK_LIBS ${LIBSNDFILE})
+    else(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+        message(FATAL_ERROR "sndfile library not found.
+On Linux systems try installing:
+    libsndfile-devel (RPM based systems)
+    libsndfile-dev   (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_SNDFILE"
+        )
+    endif(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+else(NOT USE_STATIC_SNDFILE)
+    message(STATUS "Will attempt static build of sndfile.")
+    include(cmake/BuildSndfile.cmake)
+endif(NOT USE_STATIC_SNDFILE)
+
+#
+# Find wxWidgets
+#
+if(NOT BOOTSTRAP_WXWIDGETS)
+    set(WXCONFIG "" CACHE FILEPATH "Location of wx-config binary.")
+    set(WXRC "" CACHE FILEPATH "Location of wxrc binary.")
+endif(NOT BOOTSTRAP_WXWIDGETS)
+#if(BOOTSTRAP_WXWIDGETS)
+#    set(WXCONFIG "${CMAKE_BINARY_DIR}/external/dist/bin/wx-config")
+#    set(WXRC "${CMAKE_BINARY_DIR}/external/dist/bin/wxrc")
+#    list(APPEND FREEDV_STATIC_DEPS wxWidgets)
+#endif(BOOTSTRAP_WXWIDGETS)
+message(STATUS "Looking for wxWidgets...")
+if(WXCONFIG)
+    message(STATUS "wx-config: ${WXCONFIG}")
+    set(wxWidgets_CONFIG_EXECUTABLE ${WXCONFIG})
+endif(WXCONFIG)
+if(WXRC)
+    message(STATUS "wxrc: ${WXRC}")
+    set(wxWidgets_wxrc_EXECUTABLE ${WXRC})
+endif(WXRC)
+set(WX_VERSION_MIN 3.0.0)
+find_package(wxWidgets REQUIRED core base aui html net adv)
+execute_process(COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" --version
+    OUTPUT_VARIABLE WX_VERSION)
+string(STRIP ${WX_VERSION} WX_VERSION)
+if(WX_VERSION VERSION_EQUAL ${WX_VERSION_MIN}
+    OR WX_VERSION VERSION_GREATER ${WX_VERSION_MIN})
+   message(STATUS "wxWidgets version: ${WX_VERSION}")
+else()
+    message(FATAL_ERROR "wxWidgets must be installed on your system.
+Please check that wx-config is in path, the directory
+where wxWidgets libraries are installed (returned by
+'wx-config --libs' or 'wx-config --static --libs' command)
+is in LD_LIBRARY_PATH or equivalent variable and
+wxWidgets version is ${WX_VERSION_MIN} or above.")
+endif()
+if(wxWidgets_FOUND)
+    include("${wxWidgets_USE_FILE}")
+    list(APPEND FREEDV_LINK_LIBS ${wxWidgets_LIBRARIES})
+endif(wxWidgets_FOUND)
+
+#
+# Find speex library
+#
+if(NOT USE_STATIC_SPEEXDSP)
+    message(STATUS "Looking for Speex DSP library.")
+    find_path(SPEEXDSP_INCLUDE_DIR NAMES speex/speex.h speex/speexdsp_types.h)
+    find_library(SPEEXDSP_LIBRARY speexdsp)
+    message(STATUS "  Speex DSP headers: ${SPEEXDSP_INCLUDE_DIR}")
+    message(STATUS "  Speex DSP library: ${SPEEXDSP_LIBRARY}")
+    if(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+        include_directories(${SPEEXDSP_INCLUDE_DIR})
+        list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARY})
+    else(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+        message(FATAL_ERROR "Speex DSP library not found!")
+    endif(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+else()
+    message(STATUS "Will attempt static build of speex.")
+    include(cmake/BuildSpeex.cmake)
+endif()
+
+#
+# Find libdl for dlopen/dlclose
+#
+if(UNIX)
+    message(STATUS "Looking for dl library.")
+    find_library(DL_LIBRARY dl)
+    if(DL_LIBRARY)
+        message(STATUS "  dl library: ${DL_LIBRARY}")
+        list(APPEND FREEDV_LINK_LIBS ${DL_LIBRARY})
+    else()
+        message(FATAL_ERROR "dl library not found.
+On Linux systems try installing:
+    glibc-devel  (RPM based systems)
+    glibc-dev (DEB based systems)"
+        )
+    endif()
+endif(UNIX)
+
+    
+#Freedv 
+add_subdirectory(src)
+
+# Icons and desktop file
+add_subdirectory(contrib)
+
+message(STATUS "Build type will be: ${CMAKE_BUILD_TYPE}")
+
+#
+# Cpack NSIS configuration for Windows.
+#
+if(WIN32)
+    # Detect if we're doing a 32-bit or 64-bit windows build.
+    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+        set(CMAKE_CL_64 TRUE)
+        set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
+    endif()
+    if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+        set(CPACK_STRIP_FILES TRUE)
+    endif()
+    configure_file(cmake/GetDependencies.cmake.in cmake/GetDependencies.cmake
+        @ONLY
+    )
+    install(SCRIPT ${CMAKE_BINARY_DIR}/cmake/GetDependencies.cmake)
+    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "HF Digital Voice for Radio Amateurs")
+    set(CPACK_PACKAGE_VENDOR "CMake")
+    #set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
+    set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
+    set(CPACK_PACKAGE_VERSION_MAJOR ${FREEDV_VERSION_MAJOR})
+    set(CPACK_PACKAGE_VERSION_MINOR ${FREEDV_VERSION_MINOR})
+    # CPack expects a patch level version so set it here and override if we
+    # are actually setting one.
+    set(CPACK_PACKAGE_VERSION_PATCH 0)
+    if(FREEDV_VERSION_PATCH)
+        set(CPACK_PACKAGE_VERSION_PATCH ${FREEDV_VERSION_PATCH})
+    endif()
+    if(FREEDV_VERSION_SUFFIX)
+        set(CPACK_PACKAGE_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH}-${FREEDV_VERSION_SUFFIX}")
+    endif()
+    # There is a bug in NSI that does not handle full unix paths properly. Make
+    # sure there is at least one set of four (4) backlasshes.
+    #set(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp")
+    set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\freedv.exe")
+    set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+    set(CPACK_NSIS_PACKAGE_NAME "FreeDV")
+    set(CPACK_PACKAGE_EXECUTABLES freedv;FreeDV)
+    set(CPACK_NSIS_URL_INFO_ABOUT "http://freedv.org")
+    set(CPACK_NSIS_MODIFY_PATH OFF)
+    set(CPACK_NSIS_MENU_LINKS
+        "http://freedv.org" "FreeDV Homepage")
+    include(CPack)
+endif(WIN32)
+
+endif(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
diff --git a/freedv/branches/1.2/freedv-dev/COPYING b/freedv/branches/1.2/freedv-dev/COPYING
new file mode 100644 (file)
index 0000000..cfd4e99
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, see
+    <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/freedv/branches/1.2/freedv-dev/README.osx b/freedv/branches/1.2/freedv-dev/README.osx
new file mode 100644 (file)
index 0000000..c71544f
--- /dev/null
@@ -0,0 +1,107 @@
+Building under OSX is similar to building under linux, but there are some additional steps that need to be performed to produce a working app-bundle.
+
+For the following instructions, I'm assuming you will be placing everything in:
+/Users/<yourusername>/Dev/
+
+1/ DEPENDENCIES
+Using Macports, most of the appropriate dependencies can be installed by:
+
+$ sudo port install subversion git libtool libsamplerate sox portaudio dylibbundler cmake
+
+It should be fairly similar using HomeBrew, but you will need to replace all the /opt/ paths in the following instructions.
+
+1.1/ HAMLIB 
+First, we will need to build hamlib from source, as we need hamlib to be statically compiled (Macports won't do this..)
+
+$ git clone git://git.code.sf.net/p/hamlib/code hamlib-code
+$ cd hamlib-code
+
+You will now need to edit line 12 of autogen.sh, to change "libtoolize" to "glibtoolize"
+
+$ ./autogen.sh
+$ ./configure --disable-shared --prefix /Users/<your-username-here>/Dev/hamlib
+$ make
+$ make install
+
+You should now have an installation of hamlib in ~/Dev/hamlib
+
+Just in case you have hamlib installed via Macports, it may be a good idea to run
+$ sudo port deactivate hamlib
+
+1.2/ WXWIDGETS
+To be able to produce an appbundle, we need wxWidgets to be build statically. Again, Macports won't do this out of the box.
+
+Edit the wxWidgets-3.0 port file using:
+$ sudo port edit wxWidgets-3.0
+
+and add the following to the bottom of the file:
+
+variant static description { build a static version of the libraries with some other options... } {
+    configure.args-append       --enable-std_iostreams
+    configure.args-append       --disable-shared
+    configure.args-delete       --with-sdl
+    configure.args-delete       --with-opengl
+    set installtype release-static
+}
+
+Now you can build and install a static variant of wxWidgets with:
+$ sudo port install wxWidgets-3.0 +static
+
+Note: This will probably break anything else which is using wxWidgets. Once you have finished building FreeDV, you may
+want to go back to the dynamically compiled version using:
+$ sudo port install wxWidgets-3.0
+
+HomeBrew Users: Anyone know how to do the above?
+
+1.3/ CODEC2 LIBRARIES
+The FreeDV CMake procedure will automatically checkout and compile Codec2.
+If you want to build and install your own copy (i.e. for access to the command-line tools), you can do so:
+
+$ wget http://files.freedv.org/codec2/codec2-0.4.tar.gz
+or
+$ svn checkout https://svn.code.sf.net/p/freetel/code/codec2-dev/
+
+$ cd codec2-0.4
+or 
+cd codec2-dev
+$ mkdir build_osx && cd build_osx
+$ cmake ../ && make
+$ sudo make install
+
+3/ BUILDING FREEDV 
+Get the FreeDV source by either:
+
+Getting the current 'stable' release (1.0):
+$ wget http://files.freedv.org/freedv/freedv-1.0.tar.gz
+$ tar -xzf freedv-1.0.tar.gz
+
+or
+
+Checking the latest revision out from SVN:
+$ svn checkout https://svn.code.sf.net/p/freetel/code/freedv-dev/
+
+$ cd freedv-1.0
+or 
+$ cd freedv-dev
+
+$ mkdir build_osx && cd build_osx
+
+Assuming you are intending on building Codec2 as part of the build process, run:
+
+$ cmake -DWXCONFIG=/opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/lib/wx/config/osx_cocoa-unicode-static-3.0 -DCMAKE_EXE_LINKER_FLAGS="-L/opt/local/lib" -DHAMLIB_INCLUDE_DIR=../../hamlib/include -DHAMLIB_LIBRARY=../../hamlib/lib/libhamlib.a ../
+
+Then, build FreeDV:
+$ make
+
+The build process will create an appbundle (FreeDV.app) and a compressed disk image (FreeDV.dmg) in ./build_osx/src
+Move these to wherever you want, and run!
+
+Happy DVing!
+
+Acknowledgements:
+A big thank you to Mooneer Salem, K6AQ, for walking me through this process, and figuring out how to solve the wxWidgets and Hamlib issues.
+
+Please e-mail any corrections to either the digitalvoice google group list, or myself, at:
+vk5qi(at)rfhead.net
+Mark Jessop VK5QI
+
diff --git a/freedv/branches/1.2/freedv-dev/README.txt b/freedv/branches/1.2/freedv-dev/README.txt
new file mode 100644 (file)
index 0000000..26e731d
--- /dev/null
@@ -0,0 +1,233 @@
+==================================
+ FreeDV GUI README.txt
+==================================
+
+This document describes how to build the FreeDV GUI program for
+various operating systems.  See also:
+
+  http://freedv.org - introduction, documentation, downloads
+  RELEASE_NOTES.txt - changes made to each version
+  USER_MANUAL.txt   - FreeDV GUI Manual
+
+==================================
+ Building and installing on Linux
+==================================
+
+First the basics:
+
+  $ sudo apt-get install build-essential cmake subversion
+
+To install the required development libraries instead of building them
+statically:
+
+Debian/Ubuntu:
+
+  $ sudo apt-get install libwxgtk3.0-dev portaudio19-dev \
+    libhamlib-dev libsamplerate-dev libasound2-dev libao-dev libgsm1-dev \
+    libsndfile-dev
+
+Fedora:
+
+  $ sudo dnf install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
+
+
+RHEL/CentOS and derivitves (requires Fedora EPEL repository)
+
+  $ sudo yum install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
+
+
+Quickstart 1
+------------
+
+1/ Using a modern Linux, and the development library packages
+   installed above:
+
+  $ cd /path/to/freedv
+  $ mkdir build_linux
+  $ cd build_linux
+  $ cmake ../ 
+  $ make
+  $ ./src/freedv
+
+Quickstart 2
+------------
+
+Builds static versions of wxWidgets, portaudio, codec2-dev, which are commonly
+missing on older Linux systems.
+
+1/ Assumes static build of wxWidgets and the freedv-dev source is checked out into ~/freedv-dev:
+
+  $ cd ~/freedv-dev
+  $ mkdir build_linux
+  $ cd build_linux
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE ../
+  $ make
+
+2/ Then you can configure FreeDV using your local codec-dev, something like:
+
+  $ cmake -DCMAKE_BUILD_TYPE=Debug -DBOOTSTRAP_WXWIDGETS=TRUE -DCODEC2_INCLUDE_DIRS=/path/to/codec2-dev/src -DCODEC2_LIBRARY=/path/to/codec2-dev/build_linux/src/libcodec2.so -DUSE_STATIC_CODEC2=FALSE -DUSE_STATIC_PORTAUDIO=TRUE ../
+
+3/ OR build a local copy of codec2-dev:
+
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DUSE_STATIC_CODEC2=TRUE -DUSE_STATIC_PORTAUDIO=TRUE  ../
+  
+4/ Build and run FreeDV:
+
+   $ make
+   $ ./src/freedv
+
+=======================================================
+ Building for Windows on Ubuntu Linux (Cross compiling)
+=======================================================
+
+1/ Install the cross compiling toolchain:
+
+  $ sudo apt-get install mingw-w64
+
+2/ Patch cmake using: http://www.cmake.org/gitweb?p=stage/cmake.git;a=patch;h=33286235048495ceafb636d549d9a4e8891967ae
+
+3/ Checkout a fresh copy of codec2-dev and build for Windows, pointing to the generate_codebook built by a linux build of generate_codebook, using this cmake line
+
+  $ cmake .. -DCMAKE_TOOLCHAIN_FILE=/home/david/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake -DUNITTEST=FALSE -DGENERATE_CODEBOOK=/home/david/codec2-dev/build_linux/src/generate_codebook 
+
+4/ Build WxWidgets
+
+  $ cd /path/to/freedv-dev
+  $ mkdir build_windows
+  $ cd build_windows
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE .. -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DCMAKE_BUILD_TYPE=Debug
+  $ make
+
+5/ Download and install the Windows version of Hamlib:
+
+  $ wget http://internode.dl.sourceforge.net/project/hamlib/hamlib/1.2.15.3/hamlib-win32-1.2.15.3.zip
+  $ unzip hamlib-win32-1.2.15.3.zip
+
+6/ Build All the libraries and FreeDV:
+
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DUSE_STATIC_PORTAUDIO=TRUE -DUSE_STATIC_SNDFILE=TRUE -DUSE_STATIC_SAMPLERATE=TRUE -DUSE_STATIC_CODEC2=FALSE -DCODEC2_INCLUDE_DIRS=/home/david/tmp/codec2-dev/src -DCODEC2_LIBRARY=/home/david/tmp/codec2-dev/build_windows/src/libcodec2.dll.a -DHAMLIB_INCLUDE_DIR=hamlib-win32-1.2.15.3/include -DHAMLIB_LIBRARY=hamlib-win32-1.2.15.3/lib/gcc/libhamlib.dll.a -DCMAKE_BUILD_TYPE=Debug ..
+  $ make
+
+7/ Test on Linux with "wine", this will tell you if any DLLs are missing:
+
+  $ wine src/freedv.exe
+
+8/ When moving to an actual Windows machine, I needed:
+
+  /usr/lib/gcc/i686-w64-mingw32/4.8/libstdc++-6.dll
+  /usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
+  /usr/i686-w64-mingw32/lib/libwinpthread-1.dll
+
+  Wine seems to find these automagically, so I found them on my system by
+  looking at ~/.wine/system.reg for PATH:
+
+  [System\\CurrentControlSet\\Control\\Session Manager\\Environment] 1423800803
+  "PATH"=str(2):"C:\\windows\\system32;C:\\windows;C:\\windows\\system32\\wbem;Z:\\usr\\i686-w64-mingw32\\lib;Z:\\usr\\lib\\gcc\\i686-w64-mingw32\\4.8"
+
+
+====================================
+ Building and installing on Windows
+====================================
+
+The windows build is similar to linux and follows the same basic workflow,
+however, while codec2 and FreeDV (freedv) build well on windows, some of the
+dependencies do not. For that reson current windows releases are cross-compiled
+from linux.
+
+Only MinGW is supported. While it is likely possible to perform a pure MinGW
+build, installing MSYS2 will make your life easier.
+
+CMake may not automatically detect that you're in the MSYS environment. If this
+occurs you need to pass cmake the proper generator:
+
+cmake -G"MSYS Makefiles" [other options] </path/to/source>
+
+===============================
+ Bootstrapping wxWidgets build
+===============================
+
+If wxWidgets (>= 3.0) is not available then one option is to have CMake boot-
+strap the build for FreeDV.
+
+This is required because the tool wx-config is used to get the correct compiler
+and linker flags of the wxWidgets components needed by FreeDV. Since this is
+normally done at configure time, not during "make", it is not possible for CMake
+or have this information prior to building wxWidgets.
+
+In order to work around this issue you can "bootstrap" the wxWidgets build using
+the CMake option, "BOOTSTRAP_WXWIDGETS". wxWidgets will be built using static
+libraries.
+
+NOTE: This forces "USE_STATIC_WXWIDGETS" to be true internally regarless of the
+value set manually.
+
+(from any directory, but empty directory outside of the source is prefered.)
+$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE /path/to/freedv
+$ make
+(wxWidgets is downloaded and built)
+$ cmake .
+(wxWidgets build should be detected)
+$ make
+(if all goes well, as root)
+$ make install
+
+====================================
+ Building and installing on OSX
+====================================
+
+Pls see README.osx
+
+====================================
+ Building and installing on FreeBSD
+====================================
+
+As per "Quickstart 2" above but change build_linux to build_freebsd
+
+=======
+Editing
+=======
+
+Please make sure your text editor does not insert tabs, and
+used indents of 4 spaces.  The following .emacs code was used to
+configure emacs:
+
+(setq-default indent-tabs-mode nil)
+
+(add-hook 'c-mode-common-hook
+          (function (lambda ()
+                      (setq c-basic-offset 4)
+                      )))
+
+FreeDV GUI TODO List
+--------------------
+
+[ ] Ubuntu packaging
+[ ] default sound card in/out setting for rx out of the box
+[ ] When application close on windows while "Start" down sometimes crashes
+    + Also on Linux it reports an unterminated thread when exiting
+[ ] Tool-Audio Config Dialog sound device names truncated on Windows
+[ ] Serialport::closeport() on Linux takes about 1 second 
+    + delays 'Stop' on main window test on Tools-PTT Test
+[ ] Voice keyer file name at bottom on main screen truncated
+    + need a bigger field
+[ ] Start/Stop file rec/playback, work out a better UI, 
+    maybe buttons on front page
+[ ] feature for evaluating yr own sound quality
+    + trap bad mic response/levels
+    + zero in on different sound quality from different users
+[ ] feeding audio over UDP say from from gqrx
+    + could also be used to netcat stored files
+[ ] refactoring
+    [ ] fdmdv2_main.cpp is way too long
+    [ ] rename fdmdv2*.cpp -> freedv*.cpp
+    [ ] dlg_ptt uses ComPortsDlg name internally, rename PttDlg or similar
+[ ] Add RSID
+    + use case, when would it be used?
+[ ] clean up dialogs
+    + were based on auto generation code
+    + must be an easier/clearer way to write them
+
diff --git a/freedv/branches/1.2/freedv-dev/RELEASE_NOTES.txt b/freedv/branches/1.2/freedv-dev/RELEASE_NOTES.txt
new file mode 100644 (file)
index 0000000..79eaeca
--- /dev/null
@@ -0,0 +1,7 @@
+V1.2.2 July 2017
+----------------
+
+1/ Improvements to Hamlib support, error message reporting, serial rate box.
+
+2/ Disabled unused UDP comms/egexp processing to clean up Options dialog.
+
diff --git a/freedv/branches/1.2/freedv-dev/USER_MANUAL.txt b/freedv/branches/1.2/freedv-dev/USER_MANUAL.txt
new file mode 100644 (file)
index 0000000..2cc4494
--- /dev/null
@@ -0,0 +1,100 @@
+======================
+FREEDV GUI USER MANUAL
+======================
+
+Introduction
+------------
+
+This document describes additional features in the latest FreeDV
+releases that haven't been documented in other sources.  See also
+freedv.org
+
+PTT Configuration
+-----------------
+
+Tools-PTT Dialog
+
+Hamlib comes with a default serial rate for each radio.  If your radio
+has a different serial rate change the Serial Rate drop down box to
+match your radio.
+
+When "Test" is pressed, the "Serial Params" field is populated and
+displayed.  This will help track down any mis-matches between Hamlib
+and your radio.
+
+Voice Keyer
+-----------
+
+Voice Keyer Button on Front Page
+Options-PTT Dialog
+
+Puts FreeDV and your radio into transmit, reads a wave file of your
+voice to call CQ, then switches to receive to see if anyone is
+replying.  If you press space bar the voice keyer stops.  If a signal
+with a valid sync is received for a few seconds the voice keyer stops.
+
+Options-PTT dialog can be used to select the wave file, set the Rx
+delay, and number of times the tx/rx cycle repeats.
+
+The wave file for the voice keyer should be in 8kHz mono 16 bit sample
+form.  Use a free application such as Audacity to convert a file you
+have recorded to this format.
+
+Test Frame Histogram
+--------------------
+
+Test Frame Histogram tab on Front Page
+
+Displays BER of each carrier when in "test frame" mode.  As each QPSK
+carrier has 2 bits there are 2*Nc histogram points.
+
+Ideally all carriers will have about the same BER (+/- 20% after 5000
+total bit errors).  However problems can occur with filtering in the
+tx path.  If one carrier has less power, then it will have a higher
+BER.  The errors in this carrier will tend to dominate overall
+BER. For example if one carrier is attenuated due to SSB filter ripple
+in the tx path then the BER on that carrier will be higher.  This is
+bad news for DV.
+
+Suggested usage: 
+
+i) Transmit FreeDV in test frame mode.  Use a 2nd rx (or
+get a friend) to monitor your rx signal with FreeDV in test frame
+mode.  
+
+ii) Adjust your rx SNR to get a BER of a few % (e.g. reduce tx
+power, use a short antenna for the rx, point your beam away, adjust rx
+RF gain).  
+
+iii) Monitor the error histogram for a few minutes, until you
+have say 5000 total bit errors.  You have a problem if the BER of any
+carrier is more than 20% different from the rest.
+
+A typical issue will be one carrier at 1.0, the others at 0.5,
+indicating the poorer carrier BER is twice the larger.
+
+Full Duplex Testing with loopback
+---------------------------------
+
+Options - Half Duplex check box
+
+FreeDV GUI can operate in full duplex mode which is useful for
+development of listening to your own FreeDV signal as only one PC is
+required.  Normal operation is half duplex.
+
+Tx and Rx signals can be looped back via an analog connection between
+the sound cards.
+
+On Linux, using the Alsa loopback module:
+
+  $ sudo modprobe snd-aloop
+  $ ./freedv
+
+  In Tools - Audio Config - Receive Tab  - From Radio select -> Loopback: Loopback PCM (hw:1,0)
+                          - Transmit Tab - To Radio select   -> Loopback: Loopback PCM (hw:1,1)
+
+TODO
+----
+
+[ ] Merge this information into existing start up guides
+
diff --git a/freedv/branches/1.2/freedv-dev/cmake/BuildCodec2.cmake b/freedv/branches/1.2/freedv-dev/cmake/BuildCodec2.cmake
new file mode 100644 (file)
index 0000000..038826d
--- /dev/null
@@ -0,0 +1,26 @@
+set(SPEEXDSP_CMAKE_ARGS -DBUILD_SHARED_LIBS=FALSE -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external/dist)
+
+if(USE_STATIC_SPEEXDSP)
+    list(APPEND SPEEXDSP_CMAKE_ARGS 
+        -DSPEEXDSP_LIBRARIES=${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a
+        -DSPEEXDSP_INCLUDE_DIR=${CMAKE_BINARY_DIR}/external/dist/include)
+endif()
+
+set(CODEC2_CMAKE_ARGS -DUNITTEST=FALSE)
+
+if(CMAKE_CROSSCOMPILING)
+    set(CODEC2_CMAKE_ARGS ${CODEC2_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(codec2
+   SVN_REPOSITORY https://svn.code.sf.net/p/freetel/code/codec2-dev
+   CMAKE_ARGS ${CODEC2_CMAKE_ARGS} ${SPEEXDSP_CMAKE_ARGS} 
+   CMAKE_CACHE_ARGS -DCMAKE_OSX_DEPLOYMENT_TARGET:string=10.7
+   INSTALL_COMMAND ""
+)
+set(CODEC2_LIBRARIES
+    ${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2-build/src/libcodec2.a)
+include_directories(${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2/src)
+list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS codec2)
diff --git a/freedv/branches/1.2/freedv-dev/cmake/BuildHamlib.cmake b/freedv/branches/1.2/freedv-dev/cmake/BuildHamlib.cmake
new file mode 100644 (file)
index 0000000..4166f5a
--- /dev/null
@@ -0,0 +1,20 @@
+set(HAMLIB_TARBALL "hamlib-1.2.15.3")
+
+include(ExternalProject)
+ExternalProject_Add(hamlib
+    URL http://downloads.sourceforge.net/hamlib/${HAMLIB_TARBALL}.tar.gz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(HAMLIB_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/portaudio.lib)
+else(WIN32)
+    set(HAMLIB_LIBRARIES
+    )
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${HAMLIB_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS hamlib)
diff --git a/freedv/branches/1.2/freedv-dev/cmake/BuildPortaudio.cmake b/freedv/branches/1.2/freedv-dev/cmake/BuildPortaudio.cmake
new file mode 100644 (file)
index 0000000..cc33d06
--- /dev/null
@@ -0,0 +1,52 @@
+set(PORTAUDIO_TARBALL "pa_stable_v19_20111121")
+
+# required linking libraries on linux. Not sure about windows.
+find_library(ALSA_LIBRARIES asound)
+
+if(UNIX AND NOT ALSA_LIBRARIES)
+    message(ERROR "Could not find alsa library which is required for portaudio.
+On Linux systems try installing:
+    alsa-lib-devel  (RPM based systems)
+    libasound2-dev  (DEB based systems)"
+    )
+endif()
+
+# Make sure that configure knows what system we're using when cross-compiling.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+else()
+    set(CONFIGURE_COMMAND ./configure --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(portaudio
+    URL http://www.portaudio.com/archives/${PORTAUDIO_TARBALL}.tgz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(PORTAUDIO_LIBRARIES 
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
+)
+else(WIN32)
+    find_library(RT rt)
+    find_library(ASOUND asound)
+    set(PORTAUDIO_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
+        ${RT}
+        ${ASOUND}
+    )
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+
+# Add the portaudio library to the list of libraries that must be linked.
+list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
+
+# Setup a dependency so that this gets built before linking to freedv.
+list(APPEND FREEDV_STATIC_DEPS portaudio)
diff --git a/freedv/branches/1.2/freedv-dev/cmake/BuildSamplerate.cmake b/freedv/branches/1.2/freedv-dev/cmake/BuildSamplerate.cmake
new file mode 100644 (file)
index 0000000..8b6b7a3
--- /dev/null
@@ -0,0 +1,27 @@
+set(SAMPLERATE_TARBALL "libsamplerate-0.1.8")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-sndfile --disable-fftw)
+else()
+    set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(samplerate
+    URL http://www.mega-nerd.com/SRC/${SAMPLERATE_TARBALL}.tar.gz 
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(SAMPLERATE_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
+else(WIN32)
+    set(SAMPLERATE_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SAMPLERATE_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS samplerate)
diff --git a/freedv/branches/1.2/freedv-dev/cmake/BuildSndfile.cmake b/freedv/branches/1.2/freedv-dev/cmake/BuildSndfile.cmake
new file mode 100644 (file)
index 0000000..c49b638
--- /dev/null
@@ -0,0 +1,26 @@
+set(SNDFILE_TARBALL "libsndfile-1.0.25")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST}  --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared --disable-sqlite)
+else()
+    set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared --disable-external-libs)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(sndfile
+    URL http://www.mega-nerd.com/libsndfile/files/${SNDFILE_TARBALL}.tar.gz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE) V=1
+    INSTALL_COMMAND $(MAKE) install
+)
+if(MINGW)
+    set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
+else()
+    set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
+endif()
+
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SNDFILE_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS sndfile)
diff --git a/freedv/branches/1.2/freedv-dev/cmake/BuildSpeex.cmake b/freedv/branches/1.2/freedv-dev/cmake/BuildSpeex.cmake
new file mode 100644 (file)
index 0000000..8d287ea
--- /dev/null
@@ -0,0 +1,30 @@
+set(SPEEXDSP_TARBALL "speexdsp-1.2rc3.tar.gz")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
+else()
+    if(APPLE)
+        set(CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/../configure_speexdsp_osx.sh ${CMAKE_BINARY_DIR}/external/dist)
+    else()
+        set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
+    endif()
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(speex
+   URL http://downloads.xiph.org/releases/speex/${SPEEXDSP_TARBALL}
+   BUILD_IN_SOURCE 1
+   INSTALL_DIR external/dist
+   CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+   BUILD_COMMAND $(MAKE)
+   INSTALL_COMMAND $(MAKE) install
+)
+
+set(SPEEXDSP_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS speex)
+if(USE_STATIC_CODEC2)
+    add_dependencies(codec2 speex)
+endif()
diff --git a/freedv/branches/1.2/freedv-dev/cmake/BuildWxWidgets.cmake b/freedv/branches/1.2/freedv-dev/cmake/BuildWxWidgets.cmake
new file mode 100644 (file)
index 0000000..901d806
--- /dev/null
@@ -0,0 +1,43 @@
+set(WXWIDGETS_TARBALL "wxWidgets-3.0.2")
+
+# If we're cross-compiling then we need to set the target host manually.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+endif()
+
+# If not cross-compiling then use the built-in makefile, otherwise use standard configure.
+if(MINGW AND NOT CMAKE_CROSSCOMPILING)
+#    set(CONFIGURE_COMMAND "true")
+#    set(MAKE_COMMAND $(MAKE) -C build/msw -f makefile.gcc SHARED=0 UNICODE=1 BUILD=release PREFIX=${CMAKE_BINARY_DIR}/external/dist)
+    set(CONFIGURE_COMMAND ./configure --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+if(NOT MINGW)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(wxWidgets
+    URL http://downloads.sourceforge.net/wxwindows/${WXWIDGETS_TARBALL}.tar.bz2
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND ${MAKE_COMMAND}
+    INSTALL_COMMAND $(MAKE) install
+)
+
+ExternalProject_Get_Property(wxWidgets install_dir)
+message(STATUS "wxWidgets install dir: ${install_dir}")
+if(NOT WXCONFIG)
+    set(WXCONFIG "${install_dir}/bin/wx-config")
+endif()
+if(EXISTS ${WXCONFIG})
+    set(BS_WX_DONE TRUE)
+endif()
diff --git a/freedv/branches/1.2/freedv-dev/cmake/FindPortaudio.cmake b/freedv/branches/1.2/freedv-dev/cmake/FindPortaudio.cmake
new file mode 100644 (file)
index 0000000..158e20e
--- /dev/null
@@ -0,0 +1,107 @@
+# - Try to find Portaudio
+# Once done this will define
+#
+#  PORTAUDIO_FOUND - system has Portaudio
+#  PORTAUDIO_INCLUDE_DIRS - the Portaudio include directory
+#  PORTAUDIO_LIBRARIES - Link these to use Portaudio
+#  PORTAUDIO_DEFINITIONS - Compiler switches required for using Portaudio
+#  PORTAUDIO_VERSION - Portaudio version
+#
+#  Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
+#
+# Redistribution and use is allowed according to the terms of the New BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+  # in cache already
+  set(PORTAUDIO_FOUND TRUE)
+else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+  if (NOT WIN32)
+   include(FindPkgConfig)
+   pkg_check_modules(PORTAUDIO2 portaudio-2.0)
+  endif (NOT WIN32)
+
+  if (PORTAUDIO2_FOUND)
+    set(PORTAUDIO_INCLUDE_DIRS
+      ${PORTAUDIO2_INCLUDE_DIRS}
+    )
+    if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+      set(PORTAUDIO_LIBRARIES "${PORTAUDIO2_LIBRARY_DIRS}/lib${PORTAUDIO2_LIBRARIES}.dylib")
+    else (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+      set(PORTAUDIO_LIBRARIES
+        ${PORTAUDIO2_LIBRARIES}
+      )
+    endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    set(PORTAUDIO_VERSION
+      19
+    )
+    set(PORTAUDIO_FOUND TRUE)
+  else (PORTAUDIO2_FOUND)
+    find_path(PORTAUDIO_INCLUDE_DIR
+      NAMES
+        portaudio.h
+      PATHS
+        /usr/include
+        /usr/local/include
+        /opt/local/include
+        /sw/include
+    )
+   
+    find_library(PORTAUDIO_LIBRARY
+      NAMES
+        portaudio
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /opt/local/lib
+        /sw/lib
+    )
+   
+    find_path(PORTAUDIO_LIBRARY_DIR
+      NAMES
+        portaudio
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /opt/local/lib
+        /sw/lib
+    )
+   
+    set(PORTAUDIO_INCLUDE_DIRS
+      ${PORTAUDIO_INCLUDE_DIR}
+    )
+    set(PORTAUDIO_LIBRARIES
+      ${PORTAUDIO_LIBRARY}
+    )
+   
+    set(PORTAUDIO_LIBRARY_DIRS
+      ${PORTAUDIO_LIBRARY_DIR}
+    )
+   
+    set(PORTAUDIO_VERSION
+      18
+    )
+   
+    if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
+       set(PORTAUDIO_FOUND TRUE)
+    endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
+   
+    if (PORTAUDIO_FOUND)
+      if (NOT Portaudio_FIND_QUIETLY)
+        message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}")
+      endif (NOT Portaudio_FIND_QUIETLY)
+    else (PORTAUDIO_FOUND)
+      if (Portaudio_FIND_REQUIRED)
+        message(FATAL_ERROR "Could not find Portaudio")
+      endif (Portaudio_FIND_REQUIRED)
+    endif (PORTAUDIO_FOUND)
+  endif (PORTAUDIO2_FOUND)
+
+
+  # show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
+  mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES)
+
+endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+
diff --git a/freedv/branches/1.2/freedv-dev/cmake/GetDependencies.cmake.in b/freedv/branches/1.2/freedv-dev/cmake/GetDependencies.cmake.in
new file mode 100644 (file)
index 0000000..7470aa6
--- /dev/null
@@ -0,0 +1,37 @@
+# As this script is run in a new cmake instance, it does not have access to
+# the existing cache variables. Pass them in via the configure_file command.
+set(CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@)
+set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@)
+set(UNIX @UNIX@)
+set(WIN32 @WIN32@)
+set(CMAKE_CROSSCOMPILING @CMAKE_CROSSCOMPILING@)
+set(CMAKE_FIND_LIBRARY_SUFFIXES @CMAKE_FIND_LIBRARY_SUFFIXES@)
+set(CMAKE_FIND_LIBRARY_PREFIXES @CMAKE_FIND_LIBRARY_PREFIXES@)
+set(CMAKE_SYSTEM_LIBRARY_PATH @CMAKE_SYSTEM_LIBRARY_PATH@)
+set(CMAKE_FIND_ROOT_PATH @CMAKE_FIND_ROOT_PATH@)
+
+set(FREEDV_EXE ${CMAKE_BINARY_DIR}/src/freedv.exe)
+
+include(GetPrerequisites)
+get_prerequisites("${FREEDV_EXE}" _deps 1 0 "" "")
+foreach(_runtime ${_deps})
+    message("Looking for ${_runtime}")
+    find_library(RUNTIME_${_runtime} ${_runtime})
+    message("${RUNTIME_${_runtime}}")
+    if(RUNTIME_${_runtime})
+        message("Looking for dependencies of ${_runtime}")
+        get_prerequisites("${RUNTIME_${_runtime}}" _deps2 1 0 "" "")
+        foreach(_runtime2 ${_deps2})
+            find_library(RUNTIME_${_runtime2} ${_runtime2})
+            message("${RUNTIME_${_runtime2}}")
+            if(RUNTIME_${_runtime2})
+                file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
+                TYPE EXECUTABLE FILES "${RUNTIME_${_runtime2}}")
+            endif()
+        endforeach()
+    endif()
+    if(RUNTIME_${_runtime})
+        file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
+        TYPE EXECUTABLE FILES "${RUNTIME_${_runtime}}")
+    endif()
+endforeach()
diff --git a/freedv/branches/1.2/freedv-dev/cmake/MinGW.cmake b/freedv/branches/1.2/freedv-dev/cmake/MinGW.cmake
new file mode 100644 (file)
index 0000000..333c1dc
--- /dev/null
@@ -0,0 +1,8 @@
+# If we're cross-compiling then we need to set the target host manually.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+        set(HOST x86_64-w64-mingw32)
+    else()
+        set(HOST i686-w64-mingw32)
+    endif()
+endif()
diff --git a/freedv/branches/1.2/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake b/freedv/branches/1.2/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake
new file mode 100644 (file)
index 0000000..3507d72
--- /dev/null
@@ -0,0 +1,25 @@
+# Sample toolchain file for building for Windows from an Ubuntu Linux system.
+#
+# Typical usage:
+#    *) install cross compiler: `sudo apt-get install mingw-w64 g++-mingw-w64`
+#    *) cd build
+#    *) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-mingw32.cmake ..
+
+set(CMAKE_SYSTEM_NAME Windows)
+set(TOOLCHAIN_PREFIX i686-w64-mingw32)
+
+# cross compilers to use for C and C++
+set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
+set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
+
+# target environment on the build host system
+#   set 1st to dir with the cross compiler's C/C++ headers/libs
+set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
+
+# modify default behavior of FIND_XXX() commands to
+# search for headers/libs in the target environment and
+# search for programs in the build host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/freedv/branches/1.2/freedv-dev/cmake/config.h.in b/freedv/branches/1.2/freedv-dev/cmake/config.h.in
new file mode 100644 (file)
index 0000000..8e3ab76
--- /dev/null
@@ -0,0 +1,19 @@
+/*--------------------------------------------------------------------------
+ ** This file is autogenerated from config.h.in 
+ ** during the cmake configuration of your project. If you need to make changes
+ ** edit the original file NOT THIS FILE.
+ ** --------------------------------------------------------------------------*/
+#ifndef _CONFIGURATION_HEADER_GUARD_H_
+#define _CONFIGURATION_HEADER_GUARD_H_
+
+#define SIZEOF_INT @SIZEOF_INT@
+#cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@
+#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
+#cmakedefine HAVE_STDDEF_H @HAVE_STDDEF_H@
+#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@
+#cmakedefine HAVE_STRING_H @HAVE_STRING_H@
+#cmakedefine HAVE_FLOOR @HAVE_FLOOR@
+#cmakedefine HAVE_MEMSET @HAVE_MEMSET@
+#cmakedefine HAVE_POW @HAVE_POW@
+#cmakedefine HAVE_SQRT @HAVE_SQRT@
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/cmake/soxconfig.h.in b/freedv/branches/1.2/freedv-dev/cmake/soxconfig.h.in
new file mode 100644 (file)
index 0000000..fb38608
--- /dev/null
@@ -0,0 +1,16 @@
+#define PACKAGE_VERSION "14.4.2"
+
+#cmakedefine HAVE_BYTESWAP_H          1
+#cmakedefine HAVE_FMEMOPEN            1
+#cmakedefine HAVE_FSEEKO              1
+#cmakedefine HAVE__FSEEKOI64          1
+#cmakedefine HAVE_LTDL_H              1
+#cmakedefine HAVE_MAGIC               1
+#cmakedefine HAVE_POPEN               1
+#cmakedefine HAVE_STDINT_H            1
+#cmakedefine HAVE_INTTYPES_H          1
+#cmakedefine HAVE_STRCASECMP          1
+#cmakedefine HAVE_STRINGS_H           1
+#cmakedefine HAVE_SYS_STAT_H          1
+#cmakedefine HAVE_SYS_TYPES_H         1
+#cmakedefine HAVE_VSNPRINTF           1
diff --git a/freedv/branches/1.2/freedv-dev/cmake/version.h.in b/freedv/branches/1.2/freedv-dev/cmake/version.h.in
new file mode 100644 (file)
index 0000000..43b3b7a
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef FREEDV_VER_DOT_H
+#define FREEDV_VER_DOT_H 1
+
+#define FREEDV_VERSION_MAJOR @FREEDV_VERSION_MAJOR@
+#define FREEDV_VERSION_MINOR @FREEDV_VERSION_MINOR@
+#define FREEDV_VERSION_PATCH @FREEDV_VERSION_PATCH@
+#define FREEDV_VERSION_SUFFIX "@FREEDV_VERSION_SUFFIX@"
+
+#define FREEDV_VERSION "@FREEDV_VERSION_STRING@"
+
+#endif //FREEDV_VER_DOT_H
diff --git a/freedv/branches/1.2/freedv-dev/contrib/CMakeLists.txt b/freedv/branches/1.2/freedv-dev/contrib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3f4b7e0
--- /dev/null
@@ -0,0 +1,22 @@
+# Install icons if we're on most *nix systems.
+if(UNIX AND NOT APPLE)
+    set(ICON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor
+        CACHE PATH "Prefix to use for installing icons.")
+    install(FILES freedv48x48.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/48x48/apps
+        RENAME freedv.png)
+    install(FILES freedv64x64.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/64x64/apps
+        RENAME freedv.png)
+    install(FILES freedv128x128.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/128x128/apps
+        RENAME freedv.png)
+    install(FILES freedv256x256.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/256x256/apps
+        RENAME freedv.png)
+
+    set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications
+        CACHE PATH "Location to install desktop files.")
+    install(FILES freedv.desktop
+        DESTINATION ${DESKTOP_INSTALL_DIR})
+endif(UNIX AND NOT APPLE)
diff --git a/freedv/branches/1.2/freedv-dev/contrib/LICENSE b/freedv/branches/1.2/freedv-dev/contrib/LICENSE
new file mode 100644 (file)
index 0000000..dc8853a
--- /dev/null
@@ -0,0 +1,393 @@
+Attribution 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+     Considerations for licensors: Our public licenses are
+     intended for use by those authorized to give the public
+     permission to use material in ways otherwise restricted by
+     copyright and certain other rights. Our licenses are
+     irrevocable. Licensors should read and understand the terms
+     and conditions of the license they choose before applying it.
+     Licensors should also secure all rights necessary before
+     applying our licenses so that the public can reuse the
+     material as expected. Licensors should clearly mark any
+     material not subject to the license. This includes other CC-
+     licensed material, or material used under an exception or
+     limitation to copyright. More considerations for licensors:
+       wiki.creativecommons.org/Considerations_for_licensors
+
+     Considerations for the public: By using one of our public
+     licenses, a licensor grants the public permission to use the
+     licensed material under specified terms and conditions. If
+     the licensor's permission is not necessary for any reason--for
+     example, because of any applicable exception or limitation to
+     copyright--then that use is not regulated by the license. Our
+     licenses grant only permissions under copyright and certain
+     other rights that a licensor has authority to grant. Use of
+     the licensed material may still be restricted for other
+     reasons, including because others have copyright or other
+     rights in the material. A licensor may make special requests,
+     such as asking that all changes be marked or described.
+     Although not required by our licenses, you are encouraged to
+     respect those requests where reasonable. More_considerations
+     for the public: 
+       wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution 4.0 International Public License ("Public License"). To the
+extent this Public License may be interpreted as a contract, You are
+granted the Licensed Rights in consideration of Your acceptance of
+these terms and conditions, and the Licensor grants You such rights in
+consideration of benefits the Licensor receives from making the
+Licensed Material available under these terms and conditions.
+
+
+Section 1 -- Definitions.
+
+  a. Adapted Material means material subject to Copyright and Similar
+     Rights that is derived from or based upon the Licensed Material
+     and in which the Licensed Material is translated, altered,
+     arranged, transformed, or otherwise modified in a manner requiring
+     permission under the Copyright and Similar Rights held by the
+     Licensor. For purposes of this Public License, where the Licensed
+     Material is a musical work, performance, or sound recording,
+     Adapted Material is always produced where the Licensed Material is
+     synched in timed relation with a moving image.
+
+  b. Adapter's License means the license You apply to Your Copyright
+     and Similar Rights in Your contributions to Adapted Material in
+     accordance with the terms and conditions of this Public License.
+
+  c. Copyright and Similar Rights means copyright and/or similar rights
+     closely related to copyright including, without limitation,
+     performance, broadcast, sound recording, and Sui Generis Database
+     Rights, without regard to how the rights are labeled or
+     categorized. For purposes of this Public License, the rights
+     specified in Section 2(b)(1)-(2) are not Copyright and Similar
+     Rights.
+
+  d. Effective Technological Measures means those measures that, in the
+     absence of proper authority, may not be circumvented under laws
+     fulfilling obligations under Article 11 of the WIPO Copyright
+     Treaty adopted on December 20, 1996, and/or similar international
+     agreements.
+
+  e. Exceptions and Limitations means fair use, fair dealing, and/or
+     any other exception or limitation to Copyright and Similar Rights
+     that applies to Your use of the Licensed Material.
+
+  f. Licensed Material means the artistic or literary work, database,
+     or other material to which the Licensor applied this Public
+     License.
+
+  g. Licensed Rights means the rights granted to You subject to the
+     terms and conditions of this Public License, which are limited to
+     all Copyright and Similar Rights that apply to Your use of the
+     Licensed Material and that the Licensor has authority to license.
+
+  h. Licensor means the individual(s) or entity(ies) granting rights
+     under this Public License.
+
+  i. Share means to provide material to the public by any means or
+     process that requires permission under the Licensed Rights, such
+     as reproduction, public display, public performance, distribution,
+     dissemination, communication, or importation, and to make material
+     available to the public including in ways that members of the
+     public may access the material from a place and at a time
+     individually chosen by them.
+
+  j. Sui Generis Database Rights means rights other than copyright
+     resulting from Directive 96/9/EC of the European Parliament and of
+     the Council of 11 March 1996 on the legal protection of databases,
+     as amended and/or succeeded, as well as other essentially
+     equivalent rights anywhere in the world.
+
+  k. You means the individual or entity exercising the Licensed Rights
+     under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+  a. License grant.
+
+       1. Subject to the terms and conditions of this Public License,
+          the Licensor hereby grants You a worldwide, royalty-free,
+          non-sublicensable, non-exclusive, irrevocable license to
+          exercise the Licensed Rights in the Licensed Material to:
+
+            a. reproduce and Share the Licensed Material, in whole or
+               in part; and
+
+            b. produce, reproduce, and Share Adapted Material.
+
+       2. Exceptions and Limitations. For the avoidance of doubt, where
+          Exceptions and Limitations apply to Your use, this Public
+          License does not apply, and You do not need to comply with
+          its terms and conditions.
+
+       3. Term. The term of this Public License is specified in Section
+          6(a).
+
+       4. Media and formats; technical modifications allowed. The
+          Licensor authorizes You to exercise the Licensed Rights in
+          all media and formats whether now known or hereafter created,
+          and to make technical modifications necessary to do so. The
+          Licensor waives and/or agrees not to assert any right or
+          authority to forbid You from making technical modifications
+          necessary to exercise the Licensed Rights, including
+          technical modifications necessary to circumvent Effective
+          Technological Measures. For purposes of this Public License,
+          simply making modifications authorized by this Section 2(a)
+          (4) never produces Adapted Material.
+
+       5. Downstream recipients.
+
+            a. Offer from the Licensor -- Licensed Material. Every
+               recipient of the Licensed Material automatically
+               receives an offer from the Licensor to exercise the
+               Licensed Rights under the terms and conditions of this
+               Public License.
+
+            b. No downstream restrictions. You may not offer or impose
+               any additional or different terms or conditions on, or
+               apply any Effective Technological Measures to, the
+               Licensed Material if doing so restricts exercise of the
+               Licensed Rights by any recipient of the Licensed
+               Material.
+
+       6. No endorsement. Nothing in this Public License constitutes or
+          may be construed as permission to assert or imply that You
+          are, or that Your use of the Licensed Material is, connected
+          with, or sponsored, endorsed, or granted official status by,
+          the Licensor or others designated to receive attribution as
+          provided in Section 3(a)(1)(A)(i).
+
+  b. Other rights.
+
+       1. Moral rights, such as the right of integrity, are not
+          licensed under this Public License, nor are publicity,
+          privacy, and/or other similar personality rights; however, to
+          the extent possible, the Licensor waives and/or agrees not to
+          assert any such rights held by the Licensor to the limited
+          extent necessary to allow You to exercise the Licensed
+          Rights, but not otherwise.
+
+       2. Patent and trademark rights are not licensed under this
+          Public License.
+
+       3. To the extent possible, the Licensor waives any right to
+          collect royalties from You for the exercise of the Licensed
+          Rights, whether directly or through a collecting society
+          under any voluntary or waivable statutory or compulsory
+          licensing scheme. In all other cases the Licensor expressly
+          reserves any right to collect such royalties.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+  a. Attribution.
+
+       1. If You Share the Licensed Material (including in modified
+          form), You must:
+
+            a. retain the following if it is supplied by the Licensor
+               with the Licensed Material:
+
+                 i. identification of the creator(s) of the Licensed
+                    Material and any others designated to receive
+                    attribution, in any reasonable manner requested by
+                    the Licensor (including by pseudonym if
+                    designated);
+
+                ii. a copyright notice;
+
+               iii. a notice that refers to this Public License;
+
+                iv. a notice that refers to the disclaimer of
+                    warranties;
+
+                 v. a URI or hyperlink to the Licensed Material to the
+                    extent reasonably practicable;
+
+            b. indicate if You modified the Licensed Material and
+               retain an indication of any previous modifications; and
+
+            c. indicate the Licensed Material is licensed under this
+               Public License, and include the text of, or the URI or
+               hyperlink to, this Public License.
+
+       2. You may satisfy the conditions in Section 3(a)(1) in any
+          reasonable manner based on the medium, means, and context in
+          which You Share the Licensed Material. For example, it may be
+          reasonable to satisfy the conditions by providing a URI or
+          hyperlink to a resource that includes the required
+          information.
+
+       3. If requested by the Licensor, You must remove any of the
+          information required by Section 3(a)(1)(A) to the extent
+          reasonably practicable.
+
+       4. If You Share Adapted Material You produce, the Adapter's
+          License You apply must not prevent recipients of the Adapted
+          Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+     to extract, reuse, reproduce, and Share all or a substantial
+     portion of the contents of the database;
+
+  b. if You include all or a substantial portion of the database
+     contents in a database in which You have Sui Generis Database
+     Rights, then the database in which You have Sui Generis Database
+     Rights (but not its individual contents) is Adapted Material; and
+
+  c. You must comply with the conditions in Section 3(a) if You Share
+     all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+  c. The disclaimer of warranties and limitation of liability provided
+     above shall be interpreted in a manner that, to the extent
+     possible, most closely approximates an absolute disclaimer and
+     waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+  a. This Public License applies for the term of the Copyright and
+     Similar Rights licensed here. However, if You fail to comply with
+     this Public License, then Your rights under this Public License
+     terminate automatically.
+
+  b. Where Your right to use the Licensed Material has terminated under
+     Section 6(a), it reinstates:
+
+       1. automatically as of the date the violation is cured, provided
+          it is cured within 30 days of Your discovery of the
+          violation; or
+
+       2. upon express reinstatement by the Licensor.
+
+     For the avoidance of doubt, this Section 6(b) does not affect any
+     right the Licensor may have to seek remedies for Your violations
+     of this Public License.
+
+  c. For the avoidance of doubt, the Licensor may also offer the
+     Licensed Material under separate terms or conditions or stop
+     distributing the Licensed Material at any time; however, doing so
+     will not terminate this Public License.
+
+  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+     License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+  a. The Licensor shall not be bound by any additional or different
+     terms or conditions communicated by You unless expressly agreed.
+
+  b. Any arrangements, understandings, or agreements regarding the
+     Licensed Material not stated herein are separate from and
+     independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+  a. For the avoidance of doubt, this Public License does not, and
+     shall not be interpreted to, reduce, limit, restrict, or impose
+     conditions on any use of the Licensed Material that could lawfully
+     be made without permission under this Public License.
+
+  b. To the extent possible, if any provision of this Public License is
+     deemed unenforceable, it shall be automatically reformed to the
+     minimum extent necessary to make it enforceable. If the provision
+     cannot be reformed, it shall be severed from this Public License
+     without affecting the enforceability of the remaining terms and
+     conditions.
+
+  c. No term or condition of this Public License will be waived and no
+     failure to comply consented to unless expressly agreed to by the
+     Licensor.
+
+  d. Nothing in this Public License constitutes or may be interpreted
+     as a limitation upon, or waiver of, any privileges and immunities
+     that apply to the Licensor or You, including from the legal
+     processes of any jurisdiction or authority.
+
+
+=======================================================================
+
+Creative Commons is not a party to its public licenses.
+Notwithstanding, Creative Commons may elect to apply one of its public
+licenses to material it publishes and in those instances will be
+considered the "Licensor." Except for the limited purpose of indicating
+that material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the public
+licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv.desktop b/freedv/branches/1.2/freedv-dev/contrib/freedv.desktop
new file mode 100644 (file)
index 0000000..96e8293
--- /dev/null
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Version=1.0
+Name=FreeDV
+Exec=freedv
+Icon=freedv
+Type=Application
+Terminal=false
+Categories=GTK;GNOME;AudioVideo;Audio;HamRadio;
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv.ico b/freedv/branches/1.2/freedv-dev/contrib/freedv.ico
new file mode 100644 (file)
index 0000000..e6b9a20
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/contrib/freedv.ico differ
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv.rc b/freedv/branches/1.2/freedv-dev/contrib/freedv.rc
new file mode 100644 (file)
index 0000000..2e6655d
--- /dev/null
@@ -0,0 +1 @@
+id ICON "./freedv.ico"
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv128x128.png b/freedv/branches/1.2/freedv-dev/contrib/freedv128x128.png
new file mode 100644 (file)
index 0000000..5190a77
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/contrib/freedv128x128.png differ
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv256x256.png b/freedv/branches/1.2/freedv-dev/contrib/freedv256x256.png
new file mode 100644 (file)
index 0000000..b3eb5d7
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/contrib/freedv256x256.png differ
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv48x48.png b/freedv/branches/1.2/freedv-dev/contrib/freedv48x48.png
new file mode 100644 (file)
index 0000000..bd5efc6
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/contrib/freedv48x48.png differ
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv64x64.png b/freedv/branches/1.2/freedv-dev/contrib/freedv64x64.png
new file mode 100644 (file)
index 0000000..eb89773
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/contrib/freedv64x64.png differ
diff --git a/freedv/branches/1.2/freedv-dev/contrib/freedv_screenshot.png b/freedv/branches/1.2/freedv-dev/contrib/freedv_screenshot.png
new file mode 100644 (file)
index 0000000..f93e3c5
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/contrib/freedv_screenshot.png differ
diff --git a/freedv/branches/1.2/freedv-dev/credits.txt b/freedv/branches/1.2/freedv-dev/credits.txt
new file mode 100644 (file)
index 0000000..431e399
--- /dev/null
@@ -0,0 +1,13 @@
+Credits (code or ideas borrowed from):
+==============================================
+Dave Witten and David Rowe (obviously)
+Mel Whitten K0PFX (material and moral support)
+Bruce Perens (cheerleader, promotion and publicity)
+Mooneer Salem KG6AOV(Mac OSX Patch)
+Soeren Straarup OZ2DAK (FreeBSD Port)
+Don Mak
+Steve Nance (K5FR)
+Joel Stanley (Hamlib prototyping) and Mark Jessop (Mac OSX) 
+James Ahlstrom (Quisk)
+FLDIGI
+All the folks on the digital voice google group...
diff --git a/freedv/branches/1.2/freedv-dev/db/current b/freedv/branches/1.2/freedv-dev/db/current
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/freedv/branches/1.2/freedv-dev/db/format b/freedv/branches/1.2/freedv-dev/db/format
new file mode 100644 (file)
index 0000000..db06890
--- /dev/null
@@ -0,0 +1,2 @@
+4
+layout sharded 1000
diff --git a/freedv/branches/1.2/freedv-dev/db/fs-type b/freedv/branches/1.2/freedv-dev/db/fs-type
new file mode 100644 (file)
index 0000000..4fdd953
--- /dev/null
@@ -0,0 +1 @@
+fsfs
diff --git a/freedv/branches/1.2/freedv-dev/db/fsfs.conf b/freedv/branches/1.2/freedv-dev/db/fsfs.conf
new file mode 100644 (file)
index 0000000..cc08ceb
--- /dev/null
@@ -0,0 +1,38 @@
+### This file controls the configuration of the FSFS filesystem.\r
+\r
+[memcached-servers]\r
+### These options name memcached servers used to cache internal FSFS\r
+### data.  See http://www.danga.com/memcached/ for more information on\r
+### memcached.  To use memcached with FSFS, run one or more memcached\r
+### servers, and specify each of them as an option like so:\r
+# first-server = 127.0.0.1:11211\r
+# remote-memcached = mymemcached.corp.example.com:11212\r
+### The option name is ignored; the value is of the form HOST:PORT.\r
+### memcached servers can be shared between multiple repositories;\r
+### however, if you do this, you *must* ensure that repositories have\r
+### distinct UUIDs and paths, or else cached data from one repository\r
+### might be used by another accidentally.  Note also that memcached has\r
+### no authentication for reads or writes, so you must ensure that your\r
+### memcached servers are only accessible by trusted users.\r
+\r
+[caches]\r
+### When a cache-related error occurs, normally Subversion ignores it\r
+### and continues, logging an error if the server is appropriately\r
+### configured (and ignoring it with file:// access).  To make\r
+### Subversion never ignore cache errors, uncomment this line.\r
+# fail-stop = true\r
+\r
+[rep-sharing]\r
+### To conserve space, the filesystem can optionally avoid storing\r
+### duplicate representations.  This comes at a slight cost in\r
+### performance, as maintaining a database of shared representations can\r
+### increase commit times.  The space savings are dependent upon the size\r
+### of the repository, the number of objects it contains and the amount of\r
+### duplication between them, usually a function of the branching and\r
+### merging process.\r
+###\r
+### The following parameter enables rep-sharing in the repository.  It can\r
+### be switched on and off at will, but for best space-saving results\r
+### should be enabled consistently over the life of the repository.\r
+### rep-sharing is enabled by default.\r
+# enable-rep-sharing = true\r
diff --git a/freedv/branches/1.2/freedv-dev/db/min-unpacked-rev b/freedv/branches/1.2/freedv-dev/db/min-unpacked-rev
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/freedv/branches/1.2/freedv-dev/db/rep-cache.db b/freedv/branches/1.2/freedv-dev/db/rep-cache.db
new file mode 100644 (file)
index 0000000..63c6f0b
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/db/rep-cache.db differ
diff --git a/freedv/branches/1.2/freedv-dev/db/revprops/0/0 b/freedv/branches/1.2/freedv-dev/db/revprops/0/0
new file mode 100644 (file)
index 0000000..d0b90de
--- /dev/null
@@ -0,0 +1,5 @@
+K 8
+svn:date
+V 27
+2012-08-21T18:27:59.389906Z
+END
diff --git a/freedv/branches/1.2/freedv-dev/db/revprops/0/1 b/freedv/branches/1.2/freedv-dev/db/revprops/0/1
new file mode 100644 (file)
index 0000000..0af71a2
--- /dev/null
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 9
+OFA-Staff
+K 8
+svn:date
+V 27
+2012-08-21T18:28:08.741468Z
+K 7
+svn:log
+V 25
+Imported folder structure
+END
diff --git a/freedv/branches/1.2/freedv-dev/db/revs/0/0 b/freedv/branches/1.2/freedv-dev/db/revs/0/0
new file mode 100644 (file)
index 0000000..10f5c45
--- /dev/null
@@ -0,0 +1,11 @@
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
diff --git a/freedv/branches/1.2/freedv-dev/db/revs/0/1 b/freedv/branches/1.2/freedv-dev/db/revs/0/1
new file mode 100644 (file)
index 0000000..fd802a9
--- /dev/null
@@ -0,0 +1,49 @@
+id: 3-1.0.r1/0
+type: dir
+count: 0
+cpath: /tags
+copyroot: 0 /
+
+id: 0-1.0.r1/62
+type: dir
+count: 0
+cpath: /trunk
+copyroot: 0 /
+
+id: 2-1.0.r1/126
+type: dir
+count: 0
+cpath: /branches
+copyroot: 0 /
+
+PLAIN
+K 8
+branches
+V 16
+dir 2-1.0.r1/126
+K 4
+tags
+V 14
+dir 3-1.0.r1/0
+K 5
+trunk
+V 15
+dir 0-1.0.r1/62
+END
+ENDREP
+id: 0.0.r1/306
+type: dir
+pred: 0.0.r0/17
+count: 1
+text: 1 194 99 99 7b6cc14dddba4e09be5255b475d1a0a8
+cpath: /
+copyroot: 0 /
+
+_0.0.t0-0 add-dir false false /trunk
+
+_2.0.t0-0 add-dir false false /branches
+
+_3.0.t0-0 add-dir false false /tags
+
+
+306 431
diff --git a/freedv/branches/1.2/freedv-dev/db/transactions/.gitignore b/freedv/branches/1.2/freedv-dev/db/transactions/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/branches/1.2/freedv-dev/db/txn-current b/freedv/branches/1.2/freedv-dev/db/txn-current
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/freedv/branches/1.2/freedv-dev/db/txn-current-lock b/freedv/branches/1.2/freedv-dev/db/txn-current-lock
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/branches/1.2/freedv-dev/db/txn-protorevs/.gitignore b/freedv/branches/1.2/freedv-dev/db/txn-protorevs/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/branches/1.2/freedv-dev/db/uuid b/freedv/branches/1.2/freedv-dev/db/uuid
new file mode 100644 (file)
index 0000000..0f36297
--- /dev/null
@@ -0,0 +1 @@
+a56d66ce-6468-4744-9be7-52ce95ca47a4
diff --git a/freedv/branches/1.2/freedv-dev/db/write-lock b/freedv/branches/1.2/freedv-dev/db/write-lock
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/branches/1.2/freedv-dev/debian/changelog b/freedv/branches/1.2/freedv-dev/debian/changelog
new file mode 100644 (file)
index 0000000..ddfe80b
--- /dev/null
@@ -0,0 +1,5 @@
+freedv (1.0-150830) unstable; urgency=low
+
+  * Subversion snapshot of tag 1.0.
+
+ -- Stuart Longland <stuartl@longlandclan.yi.org>  Sun, 30 Aug 2015 09:01:13 +1000
diff --git a/freedv/branches/1.2/freedv-dev/debian/compat b/freedv/branches/1.2/freedv-dev/debian/compat
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/freedv/branches/1.2/freedv-dev/debian/control b/freedv/branches/1.2/freedv-dev/debian/control
new file mode 100644 (file)
index 0000000..d1472b2
--- /dev/null
@@ -0,0 +1,19 @@
+Source: fdmdv2
+Section: main
+Priority: optional
+Maintainer: Stuart Longland <stuartl@longlandclan.yi.org>
+Build-Depends: debhelper (>= 9), cmake, libcodec2-dev, libgtk2.0-dev,
+ libhamlib-dev, libsamplerate-dev, libasound2-dev, libao-dev, libgsm1-dev,
+ portaudio19-dev, libsox-dev, libsndfile1-dev, libwxgtk3.0-dev
+Standards-Version: 3.9.5
+Homepage: http://www.freedv.org
+#Vcs-Git: git://anonscm.debian.org/collab-maint/freedv.git
+#Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/freedv.git;a=summary
+
+Package: freedv
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libcodec2
+Description: FreeDV: Open-Source Digital Voice modem
+ FreeDV is a digital voice modem that can transmit voice-quality
+ audio digitally over HF radio links in as little as 1.25kHz
+ bandwidth in varying conditions.
diff --git a/freedv/branches/1.2/freedv-dev/debian/copyright b/freedv/branches/1.2/freedv-dev/debian/copyright
new file mode 100644 (file)
index 0000000..b55a293
--- /dev/null
@@ -0,0 +1,38 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: freedv
+Source: <url://example.com>
+
+Files: *
+Copyright: <years> <put author's name and email here>
+           <years> <likewise for another author>
+License: <special license>
+ <Put the license of the package here indented by 1 space>
+ <This follows the format of Description: lines in control file>
+ .
+ <Including paragraphs>
+
+# If you want to use GPL v2 or later for the /debian/* files use 
+# the following clauses, or change it to suit. Delete these two lines
+Files: debian/*
+Copyright: 2015 unknown <stuartl@unknown>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid to pick license terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/freedv/branches/1.2/freedv-dev/debian/docs b/freedv/branches/1.2/freedv-dev/debian/docs
new file mode 100644 (file)
index 0000000..acfbcb3
--- /dev/null
@@ -0,0 +1,3 @@
+credits.txt
+README.txt
+README.txt
diff --git a/freedv/branches/1.2/freedv-dev/debian/format b/freedv/branches/1.2/freedv-dev/debian/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/freedv/branches/1.2/freedv-dev/debian/rules b/freedv/branches/1.2/freedv-dev/debian/rules
new file mode 100755 (executable)
index 0000000..ad89215
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/make -f
+# See debhelper(7) (uncomment to enable)
+# output every command that modifies files on the build system.
+#DH_VERBOSE = 1
+
+# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/default.mk
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
+# package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+
+# main packaging script based on dh7 syntax
+%:
+       dh $@ 
+
+# debmake generated override targets
+# This is example for Cmake (See http://bugs.debian.org/641051 )
+override_dh_auto_configure:
+       dh_auto_configure -- \
+              -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \
+              -DUSE_STATIC_CODEC2=FALSE \
+              -DUSE_STATIC_SPEEXDSP=FALSE
diff --git a/freedv/branches/1.2/freedv-dev/script/spot.sh b/freedv/branches/1.2/freedv-dev/script/spot.sh
new file mode 100644 (file)
index 0000000..cb1309a
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# spot.sh
+# David Rowe Sep 2015
+#
+
+# Demo script for "spotting" based on FreeDV txt string. Posts a
+# date-stamped text file to a web server.  Called from FreeDV GUI
+# program when a callsign is received in the txt msg.
+
+
+# Q: how to remove repeated spots, or those close in time?
+#
+# Set up automated lftp login:
+#
+#   $ lftp ftp://username@server
+#   Password:
+#   lftp username@server:~>  set bmk:save-passwords true
+#   lftp username@server:~> bookmark add yourserver
+#   lftp username@server:~> bookmark list
+#   lftp username@server:~> quit
+
+SPOTFILE=/home/david/tmp/freedvspot.html
+FTPSERVER=ftp.rowetel.com
+
+echo `date -u` "  " $1 "<br>" >> $SPOTFILE
+tail -n 25 $SPOTFILE > /tmp/spot.tmp1
+mv /tmp/spot.tmp1 $SPOTFILE
+lftp -e "cd www;put $SPOTFILE;quit" $FTPSERVER
diff --git a/freedv/branches/1.2/freedv-dev/src/CMakeLists.txt b/freedv/branches/1.2/freedv-dev/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ef0798b
--- /dev/null
@@ -0,0 +1,79 @@
+set(FREEDV_SOURCES
+    dlg_audiooptions.cpp
+    dlg_filter.cpp
+    dlg_options.cpp
+    dlg_ptt.cpp
+    dlg_plugin.cpp
+    fdmdv2_main.cpp
+    fdmdv2_pa_wrapper.cpp
+    fdmdv2_plot.cpp
+    fdmdv2_plot_scalar.cpp
+    fdmdv2_plot_scatter.cpp
+    fdmdv2_plot_spectrum.cpp
+    fdmdv2_plot_waterfall.cpp
+    hamlib.cpp
+    serialport.cpp
+    topFrame.cpp
+    sox_biquad.c
+    comp.h
+    dlg_audiooptions.h
+    dlg_filter.h
+    dlg_options.h
+    dlg_ptt.h
+    fdmdv2_defines.h
+    fdmdv2_main.h
+    fdmdv2_pa_wrapper.h
+    fdmdv2_plot.h
+    fdmdv2_plot_scalar.h
+    fdmdv2_plot_scatter.h
+    fdmdv2_plot_spectrum.h
+    fdmdv2_plot_waterfall.h
+    hamlib.h
+    sox_biquad.h
+    sox/band.h
+    sox/biquad.c
+    sox/biquads.c
+    sox/biquad.h
+    sox/effects.c
+    sox/effects.h
+    sox/effects_i.c
+    sox/formats_i.c
+    sox/libsox.c
+    sox/sox.h
+    sox/sox_i.h
+    sox/soxomp.h
+    sox/util.h
+    sox/xmalloc.h
+    sox/xmalloc.c
+    topFrame.h
+    version.h
+)
+
+# WIN32 is needed for Windows GUI apps and is ignored for UNIX like systems.
+add_executable(freedv WIN32 ${FREEDV_SOURCES} ${RES_FILES})
+target_link_libraries(freedv ${FREEDV_LINK_LIBS})
+include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+if(FREEDV_STATIC_DEPS)
+    add_dependencies(freedv ${FREEDV_STATIC_DEPS})
+endif(FREEDV_STATIC_DEPS)
+install(TARGETS freedv
+    RUNTIME DESTINATION bin)
+
+# Custom commands to build OSX images.
+if(APPLE)
+    add_custom_command(
+        TARGET freedv
+        POST_BUILD
+        COMMAND mkdir ARGS -p FreeDV.app/Contents/MacOS
+        COMMAND mkdir ARGS -p FreeDV.app/Contents/Resources/English.lproj
+        COMMAND cp ARGS ${CMAKE_CURRENT_SOURCE_DIR}/info.plist FreeDV.app/Contents
+        COMMAND cp ARGS ${CMAKE_CURRENT_SOURCE_DIR}/freedv.icns FreeDV.app/Contents/Resources
+        COMMAND echo ARGS -n "APPL????" > FreeDV.app/Contents/PkgInfo
+        COMMAND cp ARGS freedv FreeDV.app/Contents/MacOS/FreeDV
+        COMMAND dylibbundler ARGS -od -b -x FreeDV.app/Contents/MacOS/FreeDV -d FreeDV.app/Contents/libs -p @executable_path/../libs/
+        COMMAND mkdir dist_tmp
+        COMMAND cp -r FreeDV.app dist_tmp
+        COMMAND hdiutil create -srcfolder dist_tmp/ -volname FreeDV -format UDZO ./FreeDV.dmg
+        COMMAND rm -rf dist_tmp
+    )
+endif(APPLE)
diff --git a/freedv/branches/1.2/freedv-dev/src/Makefile.win32 b/freedv/branches/1.2/freedv-dev/src/Makefile.win32
new file mode 100644 (file)
index 0000000..932e851
--- /dev/null
@@ -0,0 +1,52 @@
+# src/Makefile.win32
+# David Rowe 26 Oct 2012
+#
+# Makefile for Win32 on msys/Mingw to help David R get up to speed
+#
+# $ make -f Makefile.Win32
+
+CODEC2_PATH=$(HOME)/codec2-dev
+INCLUDE_PATH=/usr/local/include
+
+WX_CONFIG=wx-config
+WX_CPPFLAGS = $(shell $(WX_CONFIG) --cxxflags) -D__WXDEBUG__
+WX_LIBS = $(shell $(WX_CONFIG) --libs core, base, aui, adv, net)
+SVN_REVISION=$(shell svnversion)
+CODEC2_INC=$(CODEC2_PATH)/src 
+CODEC2_LIB=$(CODEC2_PATH)/build_win32/src/
+
+CPP_FLAGS = -D_NO_AUTOTOOLS_ -I$(INCLUDE_PATH) $(WX_CPPFLAGS) -I$(CODEC2_INC) -I../extern/include -I. -g -Wall -DSVN_REVISION=\"$(SVN_REVISION)\"
+LIBS = $(WX_LIBS) -L$(CODEC2_LIB) -lcodec2 -lm -lportaudiocpp -lportaudio -lpthread -lsndfile -lsamplerate -lhamlib -lsox -lspeexdsp
+
+OBJS = topFrame.o \
+fdmdv2_main.o \
+fdmdv2_plot.o \
+fdmdv2_plot_scalar.o \
+fdmdv2_plot_scatter.o \
+fdmdv2_plot_spectrum.o \
+fdmdv2_plot_waterfall.o \
+fdmdv2_pa_wrapper.o \
+dlg_audiooptions.o \
+dlg_ptt.o \
+dlg_options.o \
+dlg_filter.o \
+sox_biquad.o \
+hamlib.o \
+../../codec2-dev/src/golay23.o
+
+HDRS = version.h dlg_audiooptions.h dlg_ptt.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h topFrame.h varicode.h ../../codec2-dev/src/golay23.h hamlib.h
+
+all: freedv
+
+freedv: $(OBJS) 
+       g++ -o freedv $(OBJS) $(CPP_FLAGS) $(LIBS)
+
+%.o: %.cpp $(HDRS) Makefile.win32
+       g++ $(CPP_FLAGS) -c $< -o $@
+
+%.o: %.c $(HDRS) Makefile.win32
+       gcc $(CPP_FLAGS) -c $< -o $@
+
+clean:
+       rm -f *.o fdmdv2
+
diff --git a/freedv/branches/1.2/freedv-dev/src/afreedvplugin.c b/freedv/branches/1.2/freedv-dev/src/afreedvplugin.c
new file mode 100644 (file)
index 0000000..5fdc424
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+  afreedvplugin.c
+  David Rowe Feb 2016
+
+  Sample FreeDV plugin
+
+  TODO:
+     [ ] plugin to call back to functions
+     [ ] ability to list .so's/DLLs and scan
+     [ ] where do we put plugins?
+     [ ] Windows build and test environment
+
+  linux .so:
+    $ gcc -Wall -fPIC -c afreedvplugin.c
+    $ gcc -shared -Wl,-soname,afreedvplugin.so -o afreedvplugin.so afreedvplugin.o
+  win32 .dll:
+    $ i686-w64-mingw32-gcc -c afreedvplugin.c
+    $ i686-w64-mingw32-gcc -shared -o afreedvplugin.dll afreedvplugin.o -Wl,--out-implib,afreedvplugin_dll.a
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32_
+#define DLL __declspec(dllexport)
+#else
+#define DLL
+#endif
+
+
+#ifdef LATER
+/* functions plugin can call - not sure how to link to these */
+
+int plugin_alert(char string[]);
+int plugin_get_persistant(char name[], char value[]);
+int plugin_set_persistant(char name[], char value[]);
+#endif
+static int (*plugin_get_persistant)(char name[], char value[]);
+
+struct APLUGIN_STATES {
+    int symbol_rate;
+    int num_tones;
+    int counter;
+};
+
+/* plugin functions called by host, we need to write these */
+
+void DLL plugin_name(char name[]) {
+
+    sprintf(name, "aFreeDVplugIn");
+}
+
+/* 
+   Text fields will be created for nparams, using the names
+   in *param_names[].  These fields we be saved to persistent
+   storage as name/param_names[0], name/param_names[1] ....
+*/
+
+void DLL *plugin_open(char *param_names[], 
+                      int *nparams, 
+                      int (*aplugin_get_persistant)(char *, char *))
+{
+    struct APLUGIN_STATES *states;
+
+    /* set up function ptrs */
+
+    plugin_get_persistant = aplugin_get_persistant;
+    /* tell host how many persistent parameters we have and their names */
+
+    strcpy(param_names[0], "SymbolRate");
+    strcpy(param_names[1], "NumTones");
+    *nparams = 2;
+
+    /* init local states */
+
+    states = (struct APLUGIN_STATES *)malloc(sizeof(struct APLUGIN_STATES));
+    if (states == NULL) {
+        // TODO: plugin_alert("Problem starting plugin!");
+        return NULL;
+    }
+    states->counter = 0;
+    
+    return (void*)states;
+}
+
+void DLL plugin_close(void *states) {
+    free(states);
+}
+
+void DLL plugin_start(void *s) {
+    struct APLUGIN_STATES *states = (struct APLUGIN_STATES*)s;
+    char txt[80];
+
+    fprintf(stderr, "\nplugin_start\n");
+
+    (plugin_get_persistant)("SymbolRate",txt);
+    states->symbol_rate = atoi(txt);
+
+    (plugin_get_persistant)("NumTones",txt);
+    states->num_tones = atoi(txt);
+    
+    fprintf(stderr, "symbol_rate: %d num_tones: %d\n", states->symbol_rate, states->num_tones);
+}
+
+void DLL plugin_stop(void *states) {
+    fprintf(stderr, "\nplugin_stop\n");
+}
+
+void DLL plugin_rx_samples(void *s, short samples[], int n) {
+    struct APLUGIN_STATES *states = (struct APLUGIN_STATES*)s;
+    //fprintf(stderr, "Got n=%d samples!\n", n);
+    //fprintf(stderr, "samples[0] = %d  samples[%d-1] = %d  counter = %d\n", samples[0], n, samples[n-1], states->counter++);
+}
+
diff --git a/freedv/branches/1.2/freedv-dev/src/comp.h b/freedv/branches/1.2/freedv-dev/src/comp.h
new file mode 100644 (file)
index 0000000..a3a1bd9
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: comp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/08/09
+
+  Complex number definition.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __COMP__
+#define __COMP__
+
+/* Complex number */
+
+typedef struct
+{
+    float real;
+    float imag;
+} COMP;
+
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_audiooptions.cpp b/freedv/branches/1.2/freedv-dev/src/dlg_audiooptions.cpp
new file mode 100644 (file)
index 0000000..4e8cd98
--- /dev/null
@@ -0,0 +1,1264 @@
+//=========================================================================
+// Name:            AudioOptsDialog.cpp
+// Purpose:         Implements an Audio options selection dialog.
+//
+// Authors:         David Rowe, David Witten
+// License:
+//
+//  All rights reserved.
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//=========================================================================
+#include "fdmdv2_main.h"
+#include "dlg_audiooptions.h"
+
+// constants for test waveform plots
+
+#define TEST_WAVEFORM_X          180
+#define TEST_WAVEFORM_Y          180
+#define TEST_WAVEFORM_PLOT_TIME  2.0
+#define TEST_WAVEFORM_PLOT_FS    400
+#define TEST_BUF_SIZE           1024
+#define TEST_FS                 48000.0
+#define TEST_DT                 0.1      // time between plot updates in seconds
+#define TEST_WAVEFORM_PLOT_BUF  ((int)(DT*400))
+
+void AudioOptsDialog::Pa_Init(void)
+{
+    m_isPaInitialized = false;
+
+    if((pa_err = Pa_Initialize()) == paNoError)
+    {
+        m_isPaInitialized = true;
+    }
+    else
+    {
+        wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
+        return;
+    }
+}
+
+
+void AudioOptsDialog::buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, 
+                                        wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel)
+{
+    wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
+
+    wxPanel *panel = new wxPanel(parentPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
+    *plotScalar = new PlotScalar((wxFrame*) panel, 1, TEST_WAVEFORM_PLOT_TIME, 1.0/TEST_WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "", 1);
+    (*plotScalar)->SetClientSize(wxSize(TEST_WAVEFORM_X,TEST_WAVEFORM_Y));
+    bSizer1->Add(panel, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 8);
+
+    *btnTest = new wxButton(parentPanel, wxID_ANY, buttonLabel, wxDefaultPosition, wxDefaultSize);
+    bSizer1->Add(*btnTest, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0);
+
+    bSizer->Add(bSizer1, 0, wxALIGN_CENTER_HORIZONTAL |wxALIGN_CENTER_VERTICAL );
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// AudioOptsDialog()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+AudioOptsDialog::AudioOptsDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    //this->SetSizeHints(wxSize(850, 600), wxDefaultSize);
+    fprintf(stderr, "pos %d %d\n", pos.x, pos.y);
+    Pa_Init();
+
+    wxBoxSizer* mainSizer;
+    mainSizer = new wxBoxSizer(wxVERTICAL);
+    m_panel1 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer4;
+    bSizer4 = new wxBoxSizer(wxVERTICAL);
+    m_notebook1 = new wxNotebook(m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM);
+    m_panelRx = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer20;
+    bSizer20 = new wxBoxSizer(wxVERTICAL);
+    wxGridSizer* gSizer4;
+    gSizer4 = new wxGridSizer(2, 1, 0, 0);
+
+    // Rx In -----------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer2;
+    sbSizer2 = new wxStaticBoxSizer(new wxStaticBox(m_panelRx, wxID_ANY, _("From Radio")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer811a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlRxInDevices = new wxListCtrl(m_panelRx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer811a->Add(m_listCtrlRxInDevices, 1, wxALL|wxEXPAND, 1);
+
+    wxBoxSizer* bSizer811;
+    bSizer811 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText51 = new wxStaticText(m_panelRx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText51->Wrap(-1);
+    bSizer811->Add(m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_textCtrlRxIn = new wxTextCtrl(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer811->Add(m_textCtrlRxIn, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText6 = new wxStaticText(m_panelRx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText6->Wrap(-1);
+    bSizer811->Add(m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateRxIn = new wxComboBox(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer811->Add(m_cbSampleRateRxIn, 0, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    bSizer811a->Add(bSizer811, 0, wxEXPAND, 5);
+
+    sbSizer2->Add(bSizer811a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarRxIn, &m_btnRxInTest, m_panelRx, sbSizer2, _("Rec 2s"));
+
+    gSizer4->Add(sbSizer2, 1, wxEXPAND, 5);
+
+    // Rx Out -----------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer3;
+    sbSizer3 = new wxStaticBoxSizer(new wxStaticBox(m_panelRx, wxID_ANY, _("To Speaker/Headphones")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer81a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlRxOutDevices = new wxListCtrl(m_panelRx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer81a->Add(m_listCtrlRxOutDevices, 1, wxALL|wxEXPAND, 1);
+
+    wxBoxSizer* bSizer81;
+    bSizer81 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText9 = new wxStaticText(m_panelRx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText9->Wrap(-1);
+    bSizer81->Add(m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_textCtrlRxOut = new wxTextCtrl(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer81->Add(m_textCtrlRxOut, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText10 = new wxStaticText(m_panelRx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText10->Wrap(-1);
+    bSizer81->Add(m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateRxOut = new wxComboBox(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer81->Add(m_cbSampleRateRxOut, 0, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    bSizer81a->Add(bSizer81, 0, wxEXPAND, 5);
+
+    sbSizer3->Add(bSizer81a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarRxOut, &m_btnRxOutTest, m_panelRx, sbSizer3, _("Play 2s"));
+    gSizer4->Add(sbSizer3, 1, wxEXPAND, 2);
+    bSizer20->Add(gSizer4, 1, wxEXPAND, 1);
+    m_panelRx->SetSizer(bSizer20);
+    m_panelRx->Layout();
+    bSizer20->Fit(m_panelRx);
+    m_notebook1->AddPage(m_panelRx, _("Receive"), true);
+
+    // Tx Tab -------------------------------------------------------------------------------
+
+    m_panelTx = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer18;
+    bSizer18 = new wxBoxSizer(wxVERTICAL);
+    wxGridSizer* gSizer2;
+    gSizer2 = new wxGridSizer(2, 1, 0, 0);
+
+    // Tx In ----------------------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer22;
+    sbSizer22 = new wxStaticBoxSizer(new wxStaticBox(m_panelTx, wxID_ANY, _("From Microphone")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer83a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlTxInDevices = new wxListCtrl(m_panelTx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer83a->Add(m_listCtrlTxInDevices, 1, wxALL|wxEXPAND, 1);
+    wxBoxSizer* bSizer83;
+    bSizer83 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText12 = new wxStaticText(m_panelTx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText12->Wrap(-1);
+    bSizer83->Add(m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_textCtrlTxIn = new wxTextCtrl(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer83->Add(m_textCtrlTxIn, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText11 = new wxStaticText(m_panelTx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText11->Wrap(-1);
+    bSizer83->Add(m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateTxIn = new wxComboBox(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer83->Add(m_cbSampleRateTxIn, 0, wxALL, 1);
+
+    bSizer83a->Add(bSizer83, 0, wxEXPAND, 5);
+
+    sbSizer22->Add(bSizer83a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarTxIn, &m_btnTxInTest, m_panelTx, sbSizer22, _("Rec 2s"));
+
+    gSizer2->Add(sbSizer22, 1, wxEXPAND, 5);
+
+    // Tx Out ----------------------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer21;
+    sbSizer21 = new wxStaticBoxSizer(new wxStaticBox(m_panelTx, wxID_ANY, _("To Radio")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer82a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlTxOutDevices = new wxListCtrl(m_panelTx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer82a->Add(m_listCtrlTxOutDevices, 1, wxALL|wxEXPAND, 2);
+    wxBoxSizer* bSizer82;
+    bSizer82 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText81 = new wxStaticText(m_panelTx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText81->Wrap(-1);
+    bSizer82->Add(m_staticText81, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_textCtrlTxOut = new wxTextCtrl(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer82->Add(m_textCtrlTxOut, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText71 = new wxStaticText(m_panelTx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText71->Wrap(-1);
+    bSizer82->Add(m_staticText71, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateTxOut = new wxComboBox(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer82->Add(m_cbSampleRateTxOut, 0, wxALL, 1);
+
+    bSizer82a->Add(bSizer82, 0, wxEXPAND, 5);
+
+    sbSizer21->Add(bSizer82a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarTxOut, &m_btnTxOutTest, m_panelTx, sbSizer21, _("Play 2s"));
+
+    gSizer2->Add(sbSizer21, 1, wxEXPAND, 5);
+    bSizer18->Add(gSizer2, 1, wxEXPAND, 1);
+    m_panelTx->SetSizer(bSizer18);
+    m_panelTx->Layout();
+    bSizer18->Fit(m_panelTx);
+    m_notebook1->AddPage(m_panelTx, _("Transmit"), false);
+
+    // API Tab -------------------------------------------------------------------
+
+    m_panelAPI = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer12;
+    bSizer12 = new wxBoxSizer(wxHORIZONTAL);
+    wxGridSizer* gSizer31;
+    gSizer31 = new wxGridSizer(2, 1, 0, 0);
+    wxStaticBoxSizer* sbSizer1;
+    sbSizer1 = new wxStaticBoxSizer(new wxStaticBox(m_panelAPI, wxID_ANY, _("PortAudio")), wxVERTICAL);
+
+    wxGridSizer* gSizer3;
+    gSizer3 = new wxGridSizer(4, 2, 0, 0);
+
+    m_staticText7 = new wxStaticText(m_panelAPI, wxID_ANY, _("PortAudio Version String:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText7->Wrap(-1);
+    gSizer3->Add(m_staticText7, 1, wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+    m_textStringVer = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    gSizer3->Add(m_textStringVer, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText8 = new wxStaticText(m_panelAPI, wxID_ANY, _("PortAudio Int Version:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText8->Wrap(-1);
+    gSizer3->Add(m_staticText8, 1, wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+    m_textIntVer = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    gSizer3->Add(m_textIntVer, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText5 = new wxStaticText(m_panelAPI, wxID_ANY, _("Device Count:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText5->Wrap(-1);
+    gSizer3->Add(m_staticText5, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 10);
+    m_textCDevCount = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    gSizer3->Add(m_textCDevCount, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText4 = new wxStaticText(m_panelAPI, wxID_ANY, _("API Count:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText4->Wrap(-1);
+    gSizer3->Add(m_staticText4, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 10);
+    m_textAPICount = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    m_textAPICount->SetMaxSize(wxSize(45,-1));
+    gSizer3->Add(m_textAPICount, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    sbSizer1->Add(gSizer3, 1, wxEXPAND, 2);
+    gSizer31->Add(sbSizer1, 1, wxEXPAND, 2);
+    wxStaticBoxSizer* sbSizer6;
+    sbSizer6 = new wxStaticBoxSizer(new wxStaticBox(m_panelAPI, wxID_ANY, _("Other")), wxVERTICAL);
+    gSizer31->Add(sbSizer6, 1, wxEXPAND, 5);
+    bSizer12->Add(gSizer31, 1, wxEXPAND, 5);
+    m_panelAPI->SetSizer(bSizer12);
+    m_panelAPI->Layout();
+    bSizer12->Fit(m_panelAPI);
+    m_notebook1->AddPage(m_panelAPI, _("API Info"), false);
+    bSizer4->Add(m_notebook1, 1, wxEXPAND | wxALL, 0);
+    m_panel1->SetSizer(bSizer4);
+    m_panel1->Layout();
+    bSizer4->Fit(m_panel1);
+    mainSizer->Add(m_panel1, 1, wxEXPAND | wxALL, 1);
+
+    wxBoxSizer* bSizer6;
+    bSizer6 = new wxBoxSizer(wxHORIZONTAL);
+    m_btnRefresh = new wxButton(this, wxID_ANY, _("Refresh"), wxDefaultPosition, wxDefaultSize, 0);
+    bSizer6->Add(m_btnRefresh, 0, wxALIGN_CENTER|wxALL, 2);
+
+    m_sdbSizer1 = new wxStdDialogButtonSizer();
+
+    m_sdbSizer1OK = new wxButton(this, wxID_OK);
+    m_sdbSizer1->AddButton(m_sdbSizer1OK);
+
+    m_sdbSizer1Cancel = new wxButton(this, wxID_CANCEL);
+    m_sdbSizer1->AddButton(m_sdbSizer1Cancel);
+
+    m_sdbSizer1Apply = new wxButton(this, wxID_APPLY);
+    m_sdbSizer1->AddButton(m_sdbSizer1Apply);
+
+    m_sdbSizer1->Realize();
+
+    bSizer6->Add(m_sdbSizer1, 1, wxALIGN_CENTER_VERTICAL, 2);
+    mainSizer->Add(bSizer6, 0, wxEXPAND, 2);
+    this->SetSizer(mainSizer);
+    this->Layout();
+    this->Centre(wxBOTH);
+//    this->Centre(wxBOTH);
+
+    m_notebook1->SetSelection(0);
+
+    showAPIInfo();
+    m_RxInDevices.m_listDevices   = m_listCtrlRxInDevices;
+    m_RxInDevices.direction       = AUDIO_IN;
+    m_RxInDevices.m_textDevice    = m_textCtrlRxIn;
+    m_RxInDevices.m_cbSampleRate  = m_cbSampleRateRxIn;
+
+    m_RxOutDevices.m_listDevices  = m_listCtrlRxOutDevices;
+    m_RxOutDevices.direction      = AUDIO_OUT;
+    m_RxOutDevices.m_textDevice   = m_textCtrlRxOut;
+    m_RxOutDevices.m_cbSampleRate = m_cbSampleRateRxOut;
+
+    m_TxInDevices.m_listDevices   = m_listCtrlTxInDevices;
+    m_TxInDevices.direction       = AUDIO_IN;
+    m_TxInDevices.m_textDevice    = m_textCtrlTxIn;
+    m_TxInDevices.m_cbSampleRate  = m_cbSampleRateTxIn;
+
+    m_TxOutDevices.m_listDevices  = m_listCtrlTxOutDevices;
+    m_TxOutDevices.direction      = AUDIO_OUT;
+    m_TxOutDevices.m_textDevice   = m_textCtrlTxOut;
+    m_TxOutDevices.m_cbSampleRate = m_cbSampleRateTxOut;
+
+    populateParams(m_RxInDevices);
+    populateParams(m_RxOutDevices);
+    populateParams(m_TxInDevices);
+    populateParams(m_TxOutDevices);
+
+    m_listCtrlRxInDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnRxInDeviceSelect ), NULL, this );
+    m_listCtrlRxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnRxOutDeviceSelect ), NULL, this );
+    m_listCtrlTxInDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxInDeviceSelect ), NULL, this );
+    m_listCtrlTxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxOutDeviceSelect ), NULL, this );
+
+    // wire up test buttons
+    m_btnRxInTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+    m_btnRxOutTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxOutTest ), NULL, this );
+    m_btnTxInTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxInTest ), NULL, this );
+    m_btnTxOutTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxOutTest ), NULL, this );
+
+    m_btnRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRefreshClick ), NULL, this );
+    m_sdbSizer1Apply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnApplyAudioParameters ), NULL, this );
+    m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnCancelAudioParameters ), NULL, this );
+    m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnOkAudioParameters ), NULL, this );
+/*
+        void OnClose( wxCloseEvent& event ) { event.Skip(); }
+        void OnHibernate( wxActivateEvent& event ) { event.Skip(); }
+        void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
+        void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
+*/
+//    this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(AudioOptsDialog::OnClose));
+    this->Connect(wxEVT_HIBERNATE, wxActivateEventHandler(AudioOptsDialog::OnHibernate));
+    this->Connect(wxEVT_ICONIZE, wxIconizeEventHandler(AudioOptsDialog::OnIconize));
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(AudioOptsDialog::OnInitDialog));
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// ~AudioOptsDialog()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+AudioOptsDialog::~AudioOptsDialog()
+{
+    Pa_Terminate();
+
+    // Disconnect Events
+    this->Disconnect(wxEVT_HIBERNATE, wxActivateEventHandler(AudioOptsDialog::OnHibernate));
+    this->Disconnect(wxEVT_ICONIZE, wxIconizeEventHandler(AudioOptsDialog::OnIconize));
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(AudioOptsDialog::OnInitDialog));
+
+    m_listCtrlRxInDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnRxInDeviceSelect), NULL, this);
+    m_listCtrlRxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnRxOutDeviceSelect), NULL, this);
+    m_listCtrlTxInDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxInDeviceSelect), NULL, this);
+    m_listCtrlTxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxOutDeviceSelect), NULL, this);
+
+    m_btnRxInTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+    m_btnRxOutTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxOutTest ), NULL, this );
+    m_btnTxInTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxInTest ), NULL, this );
+    m_btnTxOutTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxOutTest ), NULL, this );
+
+    m_btnRefresh->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnRefreshClick), NULL, this);
+    m_sdbSizer1Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnApplyAudioParameters), NULL, this);
+    m_sdbSizer1Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnCancelAudioParameters), NULL, this);
+    m_sdbSizer1OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnOkAudioParameters), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnInitDialog( wxInitDialogEvent& event )
+{
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//
+// helper function to look up name of devNum, and if it exists write
+// name to textCtrl.  Used to trap dissapearing devices.
+//-------------------------------------------------------------------------
+int AudioOptsDialog::setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum)
+{
+    int i, aDevNum, found_devNum;
+
+    // ignore last list entry as it is the "none" entry
+
+    found_devNum = 0;
+    for(i=0; i<listCtrl->GetItemCount()-1; i++) {
+        aDevNum = wxAtoi(listCtrl->GetItemText(i, 1));
+        //printf("aDevNum: %d devNum: %d\n", aDevNum, devNum);
+        if (aDevNum == devNum) {
+            found_devNum = 1;
+            textCtrl->SetValue(listCtrl->GetItemText(i, 0) + " (" + wxString::Format(wxT("%i"),devNum) + ")");
+            printf("setting focus of %d\n", i);
+            listCtrl->SetItemState(i, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
+        }
+    }
+
+    if (found_devNum) 
+        return devNum;
+    else {
+        textCtrl->SetValue("none");
+        return -1;
+    }
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+int AudioOptsDialog::ExchangeData(int inout)
+{
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        // Map sound card device numbers to tx/rx device numbers depending
+        // on number of sound cards in use
+
+        printf("EXCHANGE_DATA_IN:\n");
+        printf("  g_nSoundCards: %d\n", g_nSoundCards);
+        printf("  g_soundCard1InDeviceNum: %d\n", g_soundCard1InDeviceNum);
+        printf("  g_soundCard1OutDeviceNum: %d\n", g_soundCard1OutDeviceNum);
+        printf("  g_soundCard1SampleRate: %d\n", g_soundCard1SampleRate);
+        printf("  g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+        printf("  g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+        printf("  g_soundCard2SampleRate: %d\n", g_soundCard2SampleRate);
+
+        if (g_nSoundCards == 0) {
+            m_textCtrlRxIn ->SetValue("none"); rxInAudioDeviceNum  = -1;
+            m_textCtrlRxOut->SetValue("none"); rxOutAudioDeviceNum = -1;
+            m_textCtrlTxIn ->SetValue("none"); txInAudioDeviceNum  = -1;
+            m_textCtrlTxOut->SetValue("none"); txOutAudioDeviceNum = -1;           
+        }
+
+        if (g_nSoundCards == 1) {
+            rxInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlRxIn, 
+                                                           m_listCtrlRxInDevices, 
+                                                           g_soundCard1InDeviceNum);
+
+            rxOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlRxOut, 
+                                                           m_listCtrlRxOutDevices, 
+                                                           g_soundCard1OutDeviceNum);
+
+            if ((rxInAudioDeviceNum != -1) && (rxInAudioDeviceNum != -1)) {
+                m_cbSampleRateRxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+                m_cbSampleRateRxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+            }
+
+            m_textCtrlTxIn ->SetValue("none"); txInAudioDeviceNum  = -1;
+            m_textCtrlTxOut->SetValue("none"); txOutAudioDeviceNum = -1;           
+        }
+
+        if (g_nSoundCards == 2) {
+            rxInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlRxIn, 
+                                                           m_listCtrlRxInDevices, 
+                                                           g_soundCard1InDeviceNum);
+
+            rxOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlRxOut, 
+                                                           m_listCtrlRxOutDevices, 
+                                                           g_soundCard2OutDeviceNum);
+
+            txInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlTxIn, 
+                                                           m_listCtrlTxInDevices, 
+                                                           g_soundCard2InDeviceNum);
+
+            txOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlTxOut, 
+                                                           m_listCtrlTxOutDevices, 
+                                                           g_soundCard1OutDeviceNum);
+
+            if ((rxInAudioDeviceNum != -1) && (txOutAudioDeviceNum != -1)) {
+                m_cbSampleRateRxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+                m_cbSampleRateTxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+            }
+
+            if ((txInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1)) {
+                m_cbSampleRateTxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard2SampleRate));
+                m_cbSampleRateRxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard2SampleRate));
+            }
+        }
+        printf("  rxInAudioDeviceNum: %d\n  rxOutAudioDeviceNum: %d\n  txInAudioDeviceNum: %d\n  txOutAudioDeviceNum: %d\n",
+               rxInAudioDeviceNum, rxOutAudioDeviceNum, txInAudioDeviceNum, txOutAudioDeviceNum);
+    }
+
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        int valid_one_card_config = 0;
+        int valid_two_card_config = 0;
+        wxString sampleRate1, sampleRate2;
+
+        printf("EXCHANGE_DATA_OUT:\n");
+        printf("  rxInAudioDeviceNum: %d\n  rxOutAudioDeviceNum: %d\n  txInAudioDeviceNum: %d\n  txOutAudioDeviceNum: %d\n",
+               rxInAudioDeviceNum, rxOutAudioDeviceNum, txInAudioDeviceNum, txOutAudioDeviceNum);
+
+        // ---------------------------------------------------------------
+        // check we have a valid 1 or 2 sound card configuration
+        // ---------------------------------------------------------------
+
+        // one sound card config, tx device numbers should be set to -1 
+
+        if ((rxInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1) &&
+            (txInAudioDeviceNum == -1) && (txOutAudioDeviceNum == -1)) {
+            valid_one_card_config = 1; 
+
+            // in and out sample rate must be the same, as there is one callback
+            
+            sampleRate1 = m_cbSampleRateRxIn->GetValue();
+            if (!sampleRate1.IsSameAs(m_cbSampleRateRxOut->GetValue())) {
+                wxMessageBox(wxT("With a single sound card the Sample Rate of "
+                                 "From Radio and To Speaker/Headphones must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+        }
+
+        // two card configuration
+
+        if ((rxInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1) &&
+            (txInAudioDeviceNum != -1) && (txOutAudioDeviceNum != -1)) {
+
+            valid_two_card_config = 1; 
+
+            // Check we haven't doubled up on sound devices
+
+            if (rxInAudioDeviceNum == txInAudioDeviceNum) {
+                wxMessageBox(wxT("You must use different devices for From Radio and From Microphone"), wxT(""), wxOK);
+                return -1;
+            }
+
+            if (rxOutAudioDeviceNum == txOutAudioDeviceNum) {
+                wxMessageBox(wxT("You must use different devices for To Radio and To Speaker/Headphones"), wxT(""), wxOK);
+                return -1;
+            }
+
+            // Check sample rates for callback 1 devices are the same,
+            // as input and output are handled synchronously by one
+            // portaudio callback
+            
+            sampleRate1 = m_cbSampleRateRxIn->GetValue();
+            if (!sampleRate1.IsSameAs(m_cbSampleRateTxOut->GetValue())) {
+                wxMessageBox(wxT("With two sound cards the Sample Rate "
+                                 "of From Radio and To Radio must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+            // check sample rate for callback 2 devices is the same
+
+            sampleRate2 = m_cbSampleRateTxIn->GetValue();
+            if (!sampleRate2.IsSameAs(m_cbSampleRateRxOut->GetValue())) {
+                wxMessageBox(wxT("With two sound cards the Sample Rate of "
+                                 "From Microphone and To Speaker/Headphones must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+        }
+
+        printf("  valid_one_card_config: %d  valid_two_card_config: %d\n", valid_one_card_config, valid_two_card_config);
+
+        if (!valid_one_card_config && !valid_two_card_config) {
+            wxMessageBox(wxT("Invalid one or two sound card configuration"), wxT(""), wxOK);
+            return -1;
+        }
+
+        // ---------------------------------------------------------------
+        // Map Rx/TX device numbers to sound card device numbers used
+        // in callbacks. Portaudio uses one callback per sound card so
+        // we have to be soundcard oriented at run time rather than
+        // Tx/Rx oriented as in this dialog.
+        // ---------------------------------------------------------------
+        g_nSoundCards = 0;
+        g_soundCard1InDeviceNum = g_soundCard1OutDeviceNum = g_soundCard2InDeviceNum = g_soundCard2OutDeviceNum = -1;
+
+        if (valid_one_card_config) {
+
+            // Only callback 1 used
+
+            g_nSoundCards = 1;
+            g_soundCard1InDeviceNum  = rxInAudioDeviceNum;
+            g_soundCard1OutDeviceNum = rxOutAudioDeviceNum;
+            g_soundCard1SampleRate = wxAtoi(sampleRate1);
+        }
+
+        if (valid_two_card_config) {
+            g_nSoundCards = 2;
+            g_soundCard1InDeviceNum  = rxInAudioDeviceNum;
+            g_soundCard1OutDeviceNum = txOutAudioDeviceNum;
+            g_soundCard1SampleRate   = wxAtoi(sampleRate1);
+            g_soundCard2InDeviceNum  = txInAudioDeviceNum;
+            g_soundCard2OutDeviceNum = rxOutAudioDeviceNum;
+            g_soundCard2SampleRate   = wxAtoi(sampleRate2);
+        }
+
+        printf("  g_nSoundCards: %d\n", g_nSoundCards);
+        printf("  g_soundCard1InDeviceNum: %d\n", g_soundCard1InDeviceNum);
+        printf("  g_soundCard1OutDeviceNum: %d\n", g_soundCard1OutDeviceNum);
+        printf("  g_soundCard1SampleRate: %d\n", g_soundCard1SampleRate);
+        printf("  g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+        printf("  g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+        printf("  g_soundCard2SampleRate: %d\n", g_soundCard2SampleRate);
+
+        wxConfigBase *pConfig = wxConfigBase::Get();
+        pConfig->Write(wxT("/Audio/soundCard1InDeviceNum"),       g_soundCard1InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1OutDeviceNum"),      g_soundCard1OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1SampleRate"),        g_soundCard1SampleRate );
+
+        pConfig->Write(wxT("/Audio/soundCard2InDeviceNum"),       g_soundCard2InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2OutDeviceNum"),      g_soundCard2OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2SampleRate"),        g_soundCard2SampleRate );
+
+        pConfig->Flush();
+        delete wxConfigBase::Set((wxConfigBase *) NULL);
+    }
+
+    return 0;
+}
+
+//-------------------------------------------------------------------------
+// buildListOfSupportedSampleRates()
+//-------------------------------------------------------------------------
+int AudioOptsDialog:: buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out)
+{
+    // every sound device has a different list of supported sample rates, so
+    // we work out which ones are supported and populate the list ctrl
+
+    static double standardSampleRates[] =
+    {
+        8000.0,     9600.0,
+        11025.0,    12000.0,
+        16000.0,    22050.0,
+        24000.0,    32000.0,
+        44100.0,    48000.0,
+        88200.0,    96000.0,
+        192000.0,   -1          // negative terminated  list
+    };
+
+    const PaDeviceInfo  *deviceInfo;
+    PaStreamParameters   inputParameters, outputParameters;
+    PaError              err;
+    wxString             str;
+    int                  i, numSampleRates;
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        printf("Pa_GetDeviceInfo(%d) failed!\n", devNum);
+        cbSampleRate->Clear();
+        return 0;
+    }
+
+    inputParameters.device = devNum;
+    inputParameters.channelCount = deviceInfo->maxInputChannels;
+    inputParameters.sampleFormat = paInt16;
+    inputParameters.suggestedLatency = 0;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+        
+    outputParameters.device = devNum;
+    outputParameters.channelCount = deviceInfo->maxOutputChannels;
+    outputParameters.sampleFormat = paInt16;
+    outputParameters.suggestedLatency = 0;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    
+    cbSampleRate->Clear();
+    //printf("devNum %d supports: ", devNum);
+    numSampleRates = 0;
+    for(i = 0; standardSampleRates[i] > 0; i++)
+    {      
+        if (in_out == AUDIO_IN)
+            err = Pa_IsFormatSupported(&inputParameters, NULL, standardSampleRates[i]);
+        else
+            err = Pa_IsFormatSupported(NULL, &outputParameters, standardSampleRates[i]);
+
+        if( err == paFormatIsSupported ) {
+            str.Printf("%i", (int)standardSampleRates[i]);
+            cbSampleRate->AppendString(str);
+            printf("%i ", (int)standardSampleRates[i]);
+            numSampleRates++;
+        }
+    }
+    printf("\n");
+
+    return numSampleRates;
+}
+
+//-------------------------------------------------------------------------
+// showAPIInfo()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::showAPIInfo()
+{
+    wxString    strval;
+    int         apiVersion;
+    int         apiCount        = 0;
+    int         numDevices      = 0;
+
+    strval = Pa_GetVersionText();
+    m_textStringVer->SetLabel(strval);
+
+    apiVersion = Pa_GetVersion();
+    strval.Printf(wxT("%d"), apiVersion);
+    m_textIntVer->SetLabel(strval);
+
+    apiCount = Pa_GetHostApiCount();
+    strval.Printf(wxT("%d"), apiCount);
+    m_textAPICount->SetLabel(strval);
+
+    numDevices = Pa_GetDeviceCount();
+    strval.Printf(wxT("%d"), numDevices);
+    m_textCDevCount->SetLabel(strval);
+}
+
+//-------------------------------------------------------------------------
+// populateParams()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::populateParams(AudioInfoDisplay ai)
+{
+    const       PaDeviceInfo *deviceInfo = NULL;
+    wxListCtrl* ctrl    = ai.m_listDevices;
+    int         in_out  = ai.direction;
+    long        idx;
+    int         numDevices;
+    wxListItem  listItem;
+    wxString    buf;
+    int         devn;
+    int         col = 0;
+
+    numDevices = Pa_GetDeviceCount();
+
+    if(ctrl->GetColumnCount() > 0)
+    {
+        ctrl->ClearAll();
+    }
+
+    listItem.SetAlign(wxLIST_FORMAT_LEFT);
+    listItem.SetText(wxT("Device"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 300);
+
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("ID"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 45);
+
+    listItem.SetAlign(wxLIST_FORMAT_LEFT);
+    listItem.SetText(wxT("API"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+
+    if(in_out == AUDIO_IN)
+    {
+        listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+        listItem.SetText(wxT("Default Sample Rate"));
+        idx = ctrl->InsertColumn(col, listItem);
+        ctrl->SetColumnWidth(col++, 160);
+    }
+    else if(in_out == AUDIO_OUT)
+    {
+        listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+        listItem.SetText(wxT("Default Sample Rate"));
+        idx = ctrl->InsertColumn(col, listItem);
+        ctrl->SetColumnWidth(col++, 160);
+    }
+
+    #ifdef LATENCY
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("Min Latency"));
+    ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("Max Latency"));
+    ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+    #endif
+
+    for(devn = 0; devn < numDevices; devn++)
+    {
+        buf.Printf(wxT(""));
+        deviceInfo = Pa_GetDeviceInfo(devn);
+        if( ((in_out == AUDIO_IN) && (deviceInfo->maxInputChannels > 0)) ||
+            ((in_out == AUDIO_OUT) && (deviceInfo->maxOutputChannels > 0)))
+        {
+            col = 0;
+            buf.Printf(wxT("%s"), deviceInfo->name);
+            idx = ctrl->InsertItem(ctrl->GetItemCount(), buf);
+            col++;
+                
+            buf.Printf(wxT("%d"), devn);
+            ctrl->SetItem(idx, col++, buf);
+
+            buf.Printf(wxT("%s"), Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+            ctrl->SetItem(idx, col++, buf);
+
+            buf.Printf(wxT("%i"), (int)deviceInfo->defaultSampleRate);
+            ctrl->SetItem(idx, col++, buf);
+
+            #ifdef LATENCY
+            if (in_out == AUDIO_IN)
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultLowInputLatency);
+            else
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultLowOutputLatency);               
+            ctrl->SetItem(idx, col++, buf);
+
+            if (in_out == AUDIO_IN)
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultHighInputLatency);
+            else
+                 buf.Printf(wxT("%8.4f"), deviceInfo->defaultHighOutputLatency);             
+            ctrl->SetItem(idx, col++, buf);
+            #endif
+        }        
+    }
+
+    // add "none" option at end
+
+    buf.Printf(wxT("%s"), "none");
+    idx = ctrl->InsertItem(ctrl->GetItemCount(), buf);
+}
+
+//-------------------------------------------------------------------------
+// OnDeviceSelect()
+//
+// helper function to set up "Device:" and "Sample Rate:" fields when
+// we click on a line in the list of devices box
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnDeviceSelect(wxComboBox *cbSampleRate, 
+                                     wxTextCtrl *textCtrl, 
+                                     int        *devNum, 
+                                     wxListCtrl *listCtrlDevices, 
+                                     int         index,
+                                     int         in_out)
+{
+
+    wxString devName = listCtrlDevices->GetItemText(index, 0);
+     if (devName.IsSameAs("none")) {
+        *devNum = -1;
+        textCtrl->SetValue("none");
+    }
+    else {
+        *devNum = wxAtoi(listCtrlDevices->GetItemText(index, 1));
+        textCtrl->SetValue(devName + " (" + wxString::Format(wxT("%i"),*devNum) + ")");
+
+        int numSampleRates = buildListOfSupportedSampleRates(cbSampleRate, *devNum, in_out);
+        if (numSampleRates) {
+            wxString defSampleRate = listCtrlDevices->GetItemText(index, 3);        
+            cbSampleRate->SetValue(defSampleRate);
+        }
+        else {
+             cbSampleRate->SetValue("None");           
+        }
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnRxInDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxInDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateRxIn, 
+                   m_textCtrlRxIn, 
+                   &rxInAudioDeviceNum, 
+                   m_listCtrlRxInDevices, 
+                   evt.GetIndex(),
+                   AUDIO_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnRxOutDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxOutDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateRxOut, 
+                   m_textCtrlRxOut, 
+                   &rxOutAudioDeviceNum, 
+                   m_listCtrlRxOutDevices, 
+                   evt.GetIndex(),
+                   AUDIO_OUT);
+}
+
+//-------------------------------------------------------------------------
+// OnTxInDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxInDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateTxIn, 
+                   m_textCtrlTxIn, 
+                   &txInAudioDeviceNum, 
+                   m_listCtrlTxInDevices, 
+                   evt.GetIndex(),
+                   AUDIO_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnTxOutDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxOutDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateTxOut, 
+                   m_textCtrlTxOut, 
+                   &txOutAudioDeviceNum, 
+                   m_listCtrlTxOutDevices, 
+                   evt.GetIndex(),
+                   AUDIO_OUT);
+}
+
+//-------------------------------------------------------------------------
+// plotDeviceInputForAFewSecs()
+//
+// opens a record device and plots the input speech for a few seconds.  This is "modal" using
+// synchronous portaudio functions, so the GUI will not respond until after test sample has been
+// taken
+//-------------------------------------------------------------------------
+void AudioOptsDialog::plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar) {
+    PaStreamParameters  inputParameters;
+    const PaDeviceInfo *deviceInfo = NULL;
+    PaStream           *stream = NULL;
+    PaError             err;
+    short               in48k_stereo_short[2*TEST_BUF_SIZE];
+    short               in48k_short[TEST_BUF_SIZE];
+    short               in8k_short[TEST_BUF_SIZE];
+    int                 numDevices, nBufs, i, j, src_error,inputChannels;
+    float               t;
+    SRC_STATE          *src;
+    FIFO               *fifo;
+
+    // a basic sanity check
+    numDevices = Pa_GetDeviceCount();
+    if (devNum >= numDevices)
+        return;
+    if (devNum < 0)
+        return;
+    printf("devNum %d\n", devNum);
+
+    fifo = fifo_create((int)(DT*TEST_WAVEFORM_PLOT_FS*2)); assert(fifo != NULL);
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(src != NULL);
+
+    // work out how many input channels this device supports.
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card "), wxT("Error"), wxOK);
+        return;
+    }
+    if (deviceInfo->maxInputChannels == 1)
+        inputChannels = 1;
+    else
+        inputChannels = 2;
+
+    // open device
+
+    inputParameters.device = devNum;
+    inputParameters.channelCount = inputChannels;
+    inputParameters.sampleFormat = paInt16;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    nBufs = TEST_WAVEFORM_PLOT_TIME*TEST_FS/TEST_BUF_SIZE;
+    printf("inputChannels: %d nBufs %d\n", inputChannels, nBufs);
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,
+              TEST_FS,
+              TEST_BUF_SIZE,
+              paClipOff,    
+              NULL,       // no callback, use blocking API
+              NULL ); 
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't initialise sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    err = Pa_StartStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't start sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    for(i=0, t=0.0; i<nBufs; i++, t+=(float)TEST_BUF_SIZE/TEST_FS) {
+        Pa_ReadStream(stream, in48k_stereo_short, TEST_BUF_SIZE);
+        if (inputChannels == 2) {
+            for(j=0; j<TEST_BUF_SIZE; j++)
+                in48k_short[j] = in48k_stereo_short[2*j]; // left channel only
+        }
+        else {
+            for(j=0; j<TEST_BUF_SIZE; j++)
+                in48k_short[j] = in48k_stereo_short[j]; 
+        }
+        int n8k = resample(src, in8k_short, in48k_short, 8000, TEST_FS, TEST_BUF_SIZE, TEST_BUF_SIZE);
+        resample_for_plot(fifo, in8k_short, n8k, FS);
+
+        // every TEST_DT seconds update plot, unfortunately plot
+        // doesnt get updated to end as we are blocking events in this
+        // function
+
+        if (t > TEST_DT) {
+            t -= TEST_DT;
+            short plotSamples[TEST_WAVEFORM_PLOT_BUF];
+            if (fifo_read(fifo, plotSamples, TEST_WAVEFORM_PLOT_BUF))
+                memset(plotSamples, 0, TEST_WAVEFORM_PLOT_BUF*sizeof(short));
+            plotScalar->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
+            plotScalar->Refresh();
+       }
+    }
+   
+    err = Pa_StopStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't stop sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+    Pa_CloseStream(stream);
+
+    fifo_destroy(fifo);
+    src_delete(src);
+}
+
+//-------------------------------------------------------------------------
+// plotDeviceOutputForAFewSecs()
+//
+// opens a play device and plays a tone for a few seconds.  This is "modal" using
+// synchronous portaudio functions, so the GUI will not respond until after test sample has been
+// taken.  Also plots a pretty picture like the record versions
+//-------------------------------------------------------------------------
+void AudioOptsDialog::plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar) {
+    PaStreamParameters  outputParameters;
+    const PaDeviceInfo *deviceInfo = NULL;
+    PaStream           *stream = NULL;
+    PaError             err;
+    short               out48k_stereo_short[2*TEST_BUF_SIZE];
+    short               out48k_short[TEST_BUF_SIZE];
+    short               out8k_short[TEST_BUF_SIZE];
+    int                 numDevices, nBufs, i, j, src_error, n, outputChannels;
+    float               t;
+    SRC_STATE          *src;
+    FIFO               *fifo;
+
+    // a basic sanity check
+    numDevices = Pa_GetDeviceCount();
+    if (devNum >= numDevices)
+        return;
+    if (devNum < 0)
+        return;
+
+    fifo = fifo_create((int)(DT*TEST_WAVEFORM_PLOT_FS*2)); assert(fifo != NULL);
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(src != NULL);
+
+    // work out how many output channels this device supports.
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card "), wxT("Error"), wxOK);
+        return;
+    }
+    if (deviceInfo->maxOutputChannels == 1)
+        outputChannels = 1;
+    else
+        outputChannels = 2;
+
+    printf("outputChannels: %d\n", outputChannels);
+
+    outputParameters.device = devNum;
+    outputParameters.channelCount = outputChannels;
+    outputParameters.sampleFormat = paInt16;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    nBufs = TEST_WAVEFORM_PLOT_TIME*TEST_FS/TEST_BUF_SIZE;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL,
+              &outputParameters,
+              TEST_FS,
+              TEST_BUF_SIZE,
+              paClipOff,    
+              NULL,       // no callback, use blocking API
+              NULL ); 
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't initialise sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    err = Pa_StartStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't start sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    for(i=0, t=0.0, n=0; i<nBufs; i++, t+=(float)TEST_BUF_SIZE/TEST_FS) {
+        for(j=0; j<TEST_BUF_SIZE; j++,n++) {
+            out48k_short[j] = 2000.0*cos(6.2832*(n++)*400.0/TEST_FS);
+            if (outputChannels == 2) {
+                out48k_stereo_short[2*j] = out48k_short[j];   // left channel
+                out48k_stereo_short[2*j+1] = out48k_short[j]; // right channel
+            }
+            else {
+                out48k_stereo_short[j] = out48k_short[j];     // mono
+            }
+        }
+        Pa_WriteStream(stream, out48k_stereo_short, TEST_BUF_SIZE);
+
+        // convert back to 8kHz just for plotting
+        int n8k = resample(src, out8k_short, out48k_short, 8000, TEST_FS, TEST_BUF_SIZE, TEST_BUF_SIZE);
+        resample_for_plot(fifo, out8k_short, n8k, FS);
+
+        // every TEST_DT seconds update plot
+
+        if (t > TEST_DT) {
+            t -= TEST_DT;
+            short plotSamples[TEST_WAVEFORM_PLOT_BUF];
+            if (fifo_read(fifo, plotSamples, TEST_WAVEFORM_PLOT_BUF))
+                memset(plotSamples, 0, TEST_WAVEFORM_PLOT_BUF*sizeof(short));
+            plotScalar->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
+            plotScalar->Refresh();
+       }
+    }
+   
+    err = Pa_StopStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't stop sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+    Pa_CloseStream(stream);
+
+    fifo_destroy(fifo);
+    src_delete(src);
+}
+
+//-------------------------------------------------------------------------
+// OnRxInTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxInTest(wxCommandEvent& event)
+{
+    plotDeviceInputForAFewSecs(rxInAudioDeviceNum, m_plotScalarRxIn);
+}
+
+//-------------------------------------------------------------------------
+// OnRxOutTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxOutTest(wxCommandEvent& event)
+{
+    plotDeviceOutputForAFewSecs(rxOutAudioDeviceNum, m_plotScalarRxOut);
+}
+
+//-------------------------------------------------------------------------
+// OnTxInTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxInTest(wxCommandEvent& event)
+{
+    plotDeviceInputForAFewSecs(txInAudioDeviceNum, m_plotScalarTxIn);
+}
+
+//-------------------------------------------------------------------------
+// OnTxOutTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxOutTest(wxCommandEvent& event)
+{
+    plotDeviceOutputForAFewSecs(txOutAudioDeviceNum, m_plotScalarTxOut);
+}
+
+//-------------------------------------------------------------------------
+// OnRefreshClick()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRefreshClick(wxCommandEvent& event)
+{
+    // restart portaudio, to re-sample available devices
+
+    Pa_Terminate();
+    Pa_Init();
+
+    m_notebook1->SetSelection(0);
+    showAPIInfo();
+    populateParams(m_RxInDevices);
+    populateParams(m_RxOutDevices);
+    populateParams(m_TxInDevices);
+    populateParams(m_TxOutDevices);
+
+    // some devices may have dissapeared, so possibily change sound
+    // card config
+
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnApplyAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnApplyAudioParameters(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    if(m_isPaInitialized)
+    {
+        if((pa_err = Pa_Terminate()) == paNoError)
+        {
+            m_isPaInitialized = false;
+        }
+        else
+        {
+            wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+        }
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnCancelAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnCancelAudioParameters(wxCommandEvent& event)
+{
+    if(m_isPaInitialized)
+    {
+        if((pa_err = Pa_Terminate()) == paNoError)
+        {
+            m_isPaInitialized = false;
+        }
+        else
+        {
+            wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+        }
+    }
+    EndModal(wxCANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnOkAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnOkAudioParameters(wxCommandEvent& event)
+{
+    int status = ExchangeData(EXCHANGE_DATA_OUT);
+
+    // We only accept OK if config sucessful
+
+    printf("status: %d m_isPaInitialized: %d\n", status, m_isPaInitialized);
+    if (status == 0) {
+        if(m_isPaInitialized)
+        {
+            if((pa_err = Pa_Terminate()) == paNoError)
+            {
+                printf("terminated OK\n");
+                m_isPaInitialized = false;
+            }
+            else
+            {
+                wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+            }
+        }
+        EndModal(wxOK);
+    }
+
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_audiooptions.h b/freedv/branches/1.2/freedv-dev/src/dlg_audiooptions.h
new file mode 100644 (file)
index 0000000..5aa6741
--- /dev/null
@@ -0,0 +1,176 @@
+//=========================================================================
+// Name:          AudioInfoDisplay.h
+// Purpose:       Declares simple wxWidgets application with GUI
+//                created using wxFormBuilder.
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//=========================================================================
+#ifndef __AudioOptsDialog__
+#define __AudioOptsDialog__
+
+#include "fdmdv2_main.h"
+
+#define ID_AUDIO_OPTIONS    1000
+#define AUDIO_IN            0
+#define AUDIO_OUT           1
+
+#include "portaudio.h"
+#ifdef WIN32
+#if PA_USE_ASIO
+#include "pa_asio.h"
+#endif
+#endif
+#include "codec2_fifo.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// AudioInfoDisplay
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class AudioInfoDisplay
+{
+    public:
+        wxListCtrl*     m_listDevices;
+        int             direction;
+        wxTextCtrl*     m_textDevice;
+        wxComboBox*     m_cbSampleRate;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class AudioOptsDialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class AudioOptsDialog : public wxDialog
+{
+    private:
+
+    protected:
+        PaError         pa_err;
+        bool            m_isPaInitialized;
+
+        int             rxInAudioDeviceNum;
+        int             rxOutAudioDeviceNum;
+        int             txInAudioDeviceNum;
+        int             txOutAudioDeviceNum;
+
+        void buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, 
+                               wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel);
+        void plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar);
+        void plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar);
+
+        int buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out);
+        void populateParams(AudioInfoDisplay);
+        void showAPIInfo();
+        int setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum);
+        void Pa_Init(void);
+        void OnDeviceSelect(wxComboBox *cbSampleRate, 
+                            wxTextCtrl *textCtrl, 
+                            int        *devNum, 
+                            wxListCtrl *listCtrlDevices, 
+                            int         index,
+                            int         in_out);
+
+        AudioInfoDisplay m_RxInDevices;
+        AudioInfoDisplay m_RxOutDevices;
+        AudioInfoDisplay m_TxInDevices;
+        AudioInfoDisplay m_TxOutDevices;
+        wxPanel* m_panel1;
+        wxNotebook* m_notebook1;
+
+        wxPanel* m_panelRx;
+
+        wxListCtrl* m_listCtrlRxInDevices;
+        wxStaticText* m_staticText51;
+        wxTextCtrl* m_textCtrlRxIn;
+        wxStaticText* m_staticText6;
+        wxComboBox* m_cbSampleRateRxIn;
+
+        wxButton* m_btnRxInTest;
+        PlotScalar* m_plotScalarRxIn;
+
+        wxListCtrl* m_listCtrlRxOutDevices;
+        wxStaticText* m_staticText9;
+        wxTextCtrl* m_textCtrlRxOut;
+        wxStaticText* m_staticText10;
+        wxComboBox* m_cbSampleRateRxOut;
+
+        wxButton* m_btnRxOutTest;
+        PlotScalar* m_plotScalarRxOut;
+
+        wxPanel* m_panelTx;
+
+        wxListCtrl* m_listCtrlTxInDevices;
+        wxStaticText* m_staticText12;
+        wxTextCtrl* m_textCtrlTxIn;
+        wxStaticText* m_staticText11;
+        wxComboBox* m_cbSampleRateTxIn;
+
+        wxButton* m_btnTxInTest;
+        PlotScalar* m_plotScalarTxIn;
+
+        wxListCtrl* m_listCtrlTxOutDevices;
+        wxStaticText* m_staticText81;
+        wxTextCtrl* m_textCtrlTxOut;
+        wxStaticText* m_staticText71;
+        wxComboBox* m_cbSampleRateTxOut;
+
+        wxButton* m_btnTxOutTest;
+        PlotScalar* m_plotScalarTxOut;
+
+        wxPanel* m_panelAPI;
+
+        wxStaticText* m_staticText7;
+        wxStaticText* m_textStringVer;
+        wxStaticText* m_staticText8;
+        wxStaticText* m_textIntVer;
+        wxStaticText* m_staticText5;
+        wxStaticText* m_textCDevCount;
+        wxStaticText* m_staticText4;
+        wxStaticText* m_textAPICount;
+        wxButton* m_btnRefresh;
+        wxStdDialogButtonSizer* m_sdbSizer1;
+        wxButton* m_sdbSizer1OK;
+        wxButton* m_sdbSizer1Apply;
+        wxButton* m_sdbSizer1Cancel;
+
+        // Virtual event handlers, overide them in your derived class
+        //virtual void OnActivateApp( wxActivateEvent& event ) { event.Skip(); }
+//        virtual void OnCloseFrame( wxCloseEvent& event ) { event.Skip(); }
+
+        void OnRxInDeviceSelect( wxListEvent& event );
+
+        void OnRxInTest( wxCommandEvent& event );
+        void OnRxOutTest( wxCommandEvent& event );
+        void OnTxInTest( wxCommandEvent& event );
+        void OnTxOutTest( wxCommandEvent& event );
+
+        void OnRxOutDeviceSelect( wxListEvent& event );
+        void OnTxInDeviceSelect( wxListEvent& event );
+        void OnTxOutDeviceSelect( wxListEvent& event );
+        void OnRefreshClick( wxCommandEvent& event );
+        void OnApplyAudioParameters( wxCommandEvent& event );
+        void OnCancelAudioParameters( wxCommandEvent& event );
+        void OnOkAudioParameters( wxCommandEvent& event );
+        // Virtual event handlers, overide them in your derived class
+        void OnClose( wxCloseEvent& event ) { event.Skip(); }
+        void OnHibernate( wxActivateEvent& event ) { event.Skip(); }
+        void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
+        void OnInitDialog( wxInitDialogEvent& event );
+
+    public:
+
+        AudioOptsDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Audio Config"), const wxPoint& pos = wxPoint(1,1), const wxSize& size = wxSize( 800, 650 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~AudioOptsDialog();
+        int ExchangeData(int inout);
+};
+#endif //__AudioOptsDialog__
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_filter.cpp b/freedv/branches/1.2/freedv-dev/src/dlg_filter.cpp
new file mode 100644 (file)
index 0000000..5a5294a
--- /dev/null
@@ -0,0 +1,785 @@
+//==========================================================================
+// Name:            dlg_filter.cpp
+// Purpose:         Dialog for controlling Codec audio filtering
+// Date:            Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "dlg_filter.h"
+
+#define SLIDER_MAX 100
+#define SLIDER_LENGTH 100
+
+#define FILTER_MIN_MAG_DB -20.0
+#define FILTER_MAX_MAG_DB  20.0
+
+#define MAX_FREQ_BASS      600.00
+#define MAX_FREQ_TREBLE   3900.00
+#define MAX_FREQ_DEF      3000.00
+
+#define MIN_GAIN          -20
+#define MAX_GAIN           20
+
+#define MAX_LOG10_Q         1.0
+#define MIN_LOG10_Q        -1.0 
+
+// DFT parameters
+
+#define IMP_AMP           2000.0                     // amplitude of impulse
+#define NIMP              50                         // number of samples in impulse response
+#define F_STEP_DFT        10.0                       // frequency steps to sample spectrum
+#define F_MAG_N           (int)(MAX_F_HZ/F_STEP_DFT) // number of frequency steps
+
+extern struct freedv      *g_pfreedv;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class FilterDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
+                     wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    m_running = running;
+    m_newMicInFilter = newMicInFilter;
+    m_newSpkOutFilter = newSpkOutFilter;
+
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+
+    wxBoxSizer* bSizer30;
+    bSizer30 = new wxBoxSizer(wxVERTICAL);
+
+    // LPC Post Filter --------------------------------------------------------
+
+    wxStaticBoxSizer* lpcpfs = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("LPC Post Filter")), wxHORIZONTAL);
+
+    wxBoxSizer* left = new wxBoxSizer(wxVERTICAL);
+
+    m_codec2LPCPostFilterEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    left->Add(m_codec2LPCPostFilterEnable);
+
+    m_codec2LPCPostFilterBassBoost = new wxCheckBox(this, wxID_ANY, _("0-1 kHz 3dB Boost"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    left->Add(m_codec2LPCPostFilterBassBoost);
+    lpcpfs->Add(left, 0, wxALL, 5);
+
+    newLPCPFControl(&m_codec2LPCPostFilterBeta, &m_staticTextBeta, lpcpfs, "Beta");
+    newLPCPFControl(&m_codec2LPCPostFilterGamma, &m_staticTextGamma, lpcpfs, "Gamma");
+
+    m_LPCPostFilterDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    lpcpfs->Add(m_LPCPostFilterDefault, 0, wxALL|wxALIGN_CENTRE_HORIZONTAL|wxALIGN_CENTRE_VERTICAL, 5);
+
+    bSizer30->Add(lpcpfs, 0, wxALL, 0);
+
+    // Speex pre-processor --------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer_speexpp;
+    wxStaticBox *sb_speexpp = new wxStaticBox(this, wxID_ANY, _("Speex Mic Audio Pre-Processor"));
+    sbSizer_speexpp = new wxStaticBoxSizer(sb_speexpp, wxVERTICAL);
+
+    m_ckboxSpeexpp = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_speexpp->SetToolTip(_("Enable noise supression, dereverberation, AGC of mic signal"));
+    sbSizer_speexpp->Add(m_ckboxSpeexpp, wxALIGN_LEFT, 2);
+
+    bSizer30->Add(sbSizer_speexpp, 0, wxALL, 0);   
+
+    // EQ Filters -----------------------------------------------------------
+
+    wxStaticBoxSizer* eqMicInSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mic In Equaliser")), wxVERTICAL);
+    wxBoxSizer* eqMicInSizer1 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* eqMicInSizer2 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_MicInBass   = newEQ(eqMicInSizer1, "Bass"  , MAX_FREQ_BASS, disableQ);
+    m_MicInTreble = newEQ(eqMicInSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
+    eqMicInSizer->Add(eqMicInSizer1);
+
+    m_MicInEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    eqMicInSizer2->Add(m_MicInEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
+    m_MicInMid    = newEQ(eqMicInSizer2, "Mid"   , MAX_FREQ_DEF, enableQ);
+    m_MicInDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    eqMicInSizer2->Add(m_MicInDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
+    eqMicInSizer->Add(eqMicInSizer2);
+
+    wxStaticBoxSizer* eqSpkOutSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Speaker Out Equaliser")), wxVERTICAL);
+    wxBoxSizer* eqSpkOutSizer1 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* eqSpkOutSizer2 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_SpkOutBass   = newEQ(eqSpkOutSizer1, "Bass"  , MAX_FREQ_BASS, disableQ);
+    m_SpkOutTreble = newEQ(eqSpkOutSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
+    eqSpkOutSizer->Add(eqSpkOutSizer1);
+
+    m_SpkOutEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    eqSpkOutSizer2->Add(m_SpkOutEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
+    m_SpkOutMid    = newEQ(eqSpkOutSizer2, "Mid"   , MAX_FREQ_DEF, enableQ);
+    m_SpkOutDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    eqSpkOutSizer2->Add(m_SpkOutDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
+    eqSpkOutSizer->Add(eqSpkOutSizer2);
+    
+    bSizer30->Add(eqMicInSizer, 0, wxALL, 0);
+    bSizer30->Add(eqSpkOutSizer, 0, wxALL, 0);
+
+    // Storgage for spectrum magnitude plots ------------------------------------
+
+    m_MicInMagdB = new float[F_MAG_N];
+    for(int i=0; i<F_MAG_N; i++)
+        m_MicInMagdB[i] = 0.0;
+
+    m_SpkOutMagdB = new float[F_MAG_N];
+    for(int i=0; i<F_MAG_N; i++)
+        m_SpkOutMagdB[i] = 0.0;
+
+    // Spectrum Plots -----------------------------------------------------------
+
+    long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
+    m_auiNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(-1,200), nb_style);
+    m_auiNotebook->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
+
+    bSizer30->Add(m_auiNotebook, 0, wxEXPAND|wxALL, 3);
+    
+    m_MicInFreqRespPlot = new PlotSpectrum((wxFrame*) m_auiNotebook, m_MicInMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
+    m_auiNotebook->AddPage(m_MicInFreqRespPlot, _("Microphone In Equaliser"));
+
+    m_SpkOutFreqRespPlot = new PlotSpectrum((wxFrame*)m_auiNotebook, m_SpkOutMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
+    m_auiNotebook->AddPage(m_SpkOutFreqRespPlot, _("Speaker Out Equaliser"));
+
+    //  OK - Cancel buttons at the bottom --------------------------
+
+    wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_sdbSizer5OK = new wxButton(this, wxID_OK);
+    bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
+
+    m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
+    bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
+
+    bSizer30->Add(bSizer31, 0, wxALIGN_RIGHT|wxALL, 0);
+
+    this->SetSizer(bSizer30);
+    this->Layout();
+
+    this->Centre(wxBOTH);
+    // Connect Events -------------------------------------------------------
+
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
+
+    m_codec2LPCPostFilterEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
+    m_codec2LPCPostFilterBassBoost->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
+    m_codec2LPCPostFilterBeta->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
+    m_codec2LPCPostFilterGamma->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
+    m_LPCPostFilterDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
+
+    m_ckboxSpeexpp->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpeexppEnable), NULL, this);
+
+    m_MicInBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
+    m_MicInBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
+    m_MicInTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
+    m_MicInTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
+    m_MicInMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
+    m_MicInMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
+    m_MicInMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
+    m_MicInEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
+    m_MicInDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
+
+    m_SpkOutBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
+    m_SpkOutBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
+    m_SpkOutTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
+    m_SpkOutTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
+    m_SpkOutMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
+    m_SpkOutMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
+    m_SpkOutMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
+    m_SpkOutEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
+    m_SpkOutDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
+
+    m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
+    m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// ~FilterDlg()
+//-------------------------------------------------------------------------
+FilterDlg::~FilterDlg()
+{
+    delete m_MicInMagdB;
+    delete m_SpkOutMagdB;
+
+    // Disconnect Events
+
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
+
+    m_codec2LPCPostFilterEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
+    m_codec2LPCPostFilterBassBoost->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
+    m_codec2LPCPostFilterBeta->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
+    m_codec2LPCPostFilterGamma->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
+    m_LPCPostFilterDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
+
+    m_MicInBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
+    m_MicInBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
+    m_MicInTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
+    m_MicInTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
+    m_MicInMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
+    m_MicInMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
+    m_MicInMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
+    m_MicInEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
+    m_MicInDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
+
+    m_SpkOutBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
+    m_SpkOutBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
+    m_SpkOutTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
+    m_SpkOutTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
+    m_SpkOutMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
+    m_SpkOutMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
+    m_SpkOutMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
+    m_SpkOutEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
+    m_SpkOutDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
+
+    m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
+    m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
+}
+
+void FilterDlg::newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *s, wxString controlName)
+{
+    wxBoxSizer *bs = new wxBoxSizer(wxHORIZONTAL);
+
+    wxStaticText* st = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxSize(70,-1), wxALIGN_RIGHT);
+    bs->Add(st, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 2);
+
+    *slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
+    bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 2);
+
+    *stValue = new wxStaticText(this, wxID_ANY, wxT("0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    bs->Add(*stValue, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 2);
+
+    s->Add(bs, 0);
+}
+
+void FilterDlg::newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName)
+{
+    wxStaticText* label = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+    bs->Add(label, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 0);
+
+    *slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
+    bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    *value = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(40,-1), wxALIGN_LEFT);
+    bs->Add(*value, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxRIGHT, 5);
+}
+
+EQ FilterDlg::newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ)
+{
+    EQ eq;
+
+    wxStaticBoxSizer *bsEQ = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, eqName), wxHORIZONTAL);
+
+    newEQControl(&eq.sliderFreq, &eq.valueFreq, bsEQ, "Freq"); 
+    eq.maxFreqHz = maxFreqHz; 
+    eq.sliderFreqId = eq.sliderFreq->GetId();
+
+    newEQControl(&eq.sliderGain, &eq.valueGain, bsEQ, "Gain");
+    if (enableQ)
+        newEQControl(&eq.sliderQ, &eq.valueQ, bsEQ, "Q");
+    else
+        eq.sliderQ = NULL;
+
+    bs->Add(bsEQ);
+
+    return eq;
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void FilterDlg::ExchangeData(int inout, bool storePersistent)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        // LPC Post filter
+
+        m_codec2LPCPostFilterEnable->SetValue(wxGetApp().m_codec2LPCPostFilterEnable);
+        m_codec2LPCPostFilterBassBoost->SetValue(wxGetApp().m_codec2LPCPostFilterBassBoost);
+        m_beta = wxGetApp().m_codec2LPCPostFilterBeta; setBeta();
+        m_gamma = wxGetApp().m_codec2LPCPostFilterGamma; setGamma();
+
+        // Speex Pre-Processor
+
+        m_ckboxSpeexpp->SetValue(wxGetApp().m_speexpp_enable);
+
+        // Mic In Equaliser
+
+        m_MicInBass.freqHz = wxGetApp().m_MicInBassFreqHz; 
+        m_MicInBass.freqHz = limit(m_MicInBass.freqHz, 1.0, MAX_FREQ_BASS);
+        setFreq(&m_MicInBass);
+        m_MicInBass.gaindB = wxGetApp().m_MicInBassGaindB;
+        m_MicInBass.gaindB = limit(m_MicInBass.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInBass);
+
+        m_MicInTreble.freqHz = wxGetApp().m_MicInTrebleFreqHz;
+        m_MicInTreble.freqHz = limit(m_MicInTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_MicInTreble);
+        m_MicInTreble.gaindB = wxGetApp().m_MicInTrebleGaindB; 
+        m_MicInTreble.gaindB = limit(m_MicInTreble.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInTreble);
+
+        m_MicInMid.freqHz = wxGetApp().m_MicInMidFreqHz; 
+        m_MicInMid.freqHz = limit(m_MicInMid.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_MicInMid);
+        m_MicInMid.gaindB = wxGetApp().m_MicInMidGaindB; 
+        m_MicInMid.gaindB = limit(m_MicInMid.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInMid);
+        m_MicInMid.Q = wxGetApp().m_MicInMidQ;
+        m_MicInMid.Q = limit(m_MicInMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
+        setQ(&m_MicInMid);
+
+        m_MicInEnable->SetValue(wxGetApp().m_MicInEQEnable);
+
+        plotMicInFilterSpectrum();
+        // Spk Out Equaliser
+
+        m_SpkOutBass.freqHz = wxGetApp().m_SpkOutBassFreqHz;
+        m_SpkOutBass.freqHz = limit(m_SpkOutBass.freqHz, 1.0, MAX_FREQ_BASS);
+        setFreq(&m_SpkOutBass);
+        m_SpkOutBass.gaindB = wxGetApp().m_SpkOutBassGaindB; 
+        m_SpkOutBass.gaindB = limit(m_SpkOutBass.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutBass);
+
+        m_SpkOutTreble.freqHz = wxGetApp().m_SpkOutTrebleFreqHz; 
+        m_SpkOutTreble.freqHz = limit(m_SpkOutTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_SpkOutTreble);
+        m_SpkOutTreble.gaindB = wxGetApp().m_SpkOutTrebleGaindB; 
+        m_SpkOutTreble.gaindB = limit(m_SpkOutTreble.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutTreble);
+
+        m_SpkOutMid.freqHz = wxGetApp().m_SpkOutMidFreqHz;
+        m_SpkOutMid.freqHz = limit(m_SpkOutMid.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_SpkOutMid);
+        m_SpkOutMid.gaindB = wxGetApp().m_SpkOutMidGaindB;
+        m_SpkOutMid.gaindB = limit(m_SpkOutMid.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutMid);
+        m_SpkOutMid.Q = wxGetApp().m_SpkOutMidQ;
+        m_SpkOutMid.Q = limit(m_SpkOutMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
+        setQ(&m_SpkOutMid);
+
+        m_SpkOutEnable->SetValue(wxGetApp().m_SpkOutEQEnable);
+
+        plotSpkOutFilterSpectrum();
+    }
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        // LPC Post filter
+
+        wxGetApp().m_codec2LPCPostFilterEnable     = m_codec2LPCPostFilterEnable->GetValue();
+        wxGetApp().m_codec2LPCPostFilterBassBoost  = m_codec2LPCPostFilterBassBoost->GetValue();
+        wxGetApp().m_codec2LPCPostFilterBeta       = m_beta;
+        wxGetApp().m_codec2LPCPostFilterGamma      = m_gamma;
+
+        // Speex Pre-Processor
+
+        wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
+
+        // Mic In Equaliser
+
+        wxGetApp().m_MicInBassFreqHz = m_MicInBass.freqHz;
+        wxGetApp().m_MicInBassGaindB = m_MicInBass.gaindB;
+
+        wxGetApp().m_MicInTrebleFreqHz = m_MicInTreble.freqHz;
+        wxGetApp().m_MicInTrebleGaindB = m_MicInTreble.gaindB;
+
+        wxGetApp().m_MicInMidFreqHz = m_MicInMid.freqHz;
+        wxGetApp().m_MicInMidGaindB = m_MicInMid.gaindB;
+        wxGetApp().m_MicInMidQ = m_MicInMid.Q;
+
+        // Spk Out Equaliser
+
+        wxGetApp().m_SpkOutBassFreqHz = m_SpkOutBass.freqHz;
+        wxGetApp().m_SpkOutBassGaindB = m_SpkOutBass.gaindB;
+
+        wxGetApp().m_SpkOutTrebleFreqHz = m_SpkOutTreble.freqHz;
+        wxGetApp().m_SpkOutTrebleGaindB = m_SpkOutTreble.gaindB;
+
+        wxGetApp().m_SpkOutMidFreqHz = m_SpkOutMid.freqHz;
+        wxGetApp().m_SpkOutMidGaindB = m_SpkOutMid.gaindB;
+        wxGetApp().m_SpkOutMidQ = m_SpkOutMid.Q;
+
+        if (storePersistent) {
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterEnable"),     wxGetApp().m_codec2LPCPostFilterEnable);
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterBassBoost"),  wxGetApp().m_codec2LPCPostFilterBassBoost);
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterBeta"),       (int)(m_beta*100.0));
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterGamma"),      (int)(m_gamma*100.0));
+
+            pConfig->Write(wxT("/Filter/speexpp_enable"),                wxGetApp().m_speexpp_enable);
+
+            pConfig->Write(wxT("/Filter/MicInBassFreqHz"), (int)m_MicInBass.freqHz);
+            pConfig->Write(wxT("/Filter/MicInBassGaindB"), (int)(10.0*m_MicInBass.gaindB));
+            pConfig->Write(wxT("/Filter/MicInTrebleFreqHz"), (int)m_MicInTreble.freqHz);
+            pConfig->Write(wxT("/Filter/MicInTrebleGaindB"), (int)(10.0*m_MicInTreble.gaindB));
+            pConfig->Write(wxT("/Filter/MicInMidFreqHz"), (int)m_MicInMid.freqHz);
+            pConfig->Write(wxT("/Filter/MicInMidGaindB"), (int)(10.0*m_MicInMid.gaindB));
+            pConfig->Write(wxT("/Filter/MicInMidQ"), (int)(100.0*m_MicInMid.Q));
+
+            pConfig->Write(wxT("/Filter/SpkOutBassFreqHz"), (int)m_SpkOutBass.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutBassGaindB"), (int)(10.0*m_SpkOutBass.gaindB));
+            pConfig->Write(wxT("/Filter/SpkOutTrebleFreqHz"), (int)m_SpkOutTreble.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutTrebleGaindB"), (int)(10.0*m_SpkOutTreble.gaindB));
+            pConfig->Write(wxT("/Filter/SpkOutMidQ"), (int)(100.0*m_SpkOutMid.Q));
+            pConfig->Write(wxT("/Filter/SpkOutMidFreqHz"), (int)m_SpkOutMid.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutMidGaindB"), (int)(10.0*m_SpkOutMid.gaindB));
+
+            pConfig->Flush();
+        }
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+float FilterDlg::limit(float value, float min, float max) {
+    if (value < min) return min;
+    if (value > max) return max;
+    return value;
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void FilterDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnDefault()
+//-------------------------------------------------------------------------
+
+void FilterDlg::OnLPCPostFilterDefault(wxCommandEvent& event)
+{
+    m_beta = CODEC2_LPC_PF_BETA; setBeta();
+    m_gamma = CODEC2_LPC_PF_GAMMA; setGamma();
+    m_codec2LPCPostFilterEnable->SetValue(true);
+    m_codec2LPCPostFilterBassBoost->SetValue(true);
+}
+
+void FilterDlg::OnMicInDefault(wxCommandEvent& event)
+{
+    m_MicInBass.freqHz = 100.0;
+    m_MicInBass.gaindB = 0.0;
+    setFreq(&m_MicInBass); setGain(&m_MicInBass); 
+
+    m_MicInTreble.freqHz = 3000.0;
+    m_MicInTreble.gaindB = 0.0;
+    setFreq(&m_MicInTreble); setGain(&m_MicInTreble); 
+
+    m_MicInMid.freqHz = 1500.0;
+    m_MicInMid.gaindB = 0.0;
+    m_MicInMid.Q = 1.0;
+    setFreq(&m_MicInMid); setGain(&m_MicInMid); setQ(&m_MicInMid); 
+
+    plotMicInFilterSpectrum();    
+}
+
+void FilterDlg::OnSpkOutDefault(wxCommandEvent& event)
+{
+    m_SpkOutBass.freqHz = 100.0;
+    m_SpkOutBass.gaindB = 0.0;
+    setFreq(&m_SpkOutBass); setGain(&m_SpkOutBass); 
+
+    m_SpkOutTreble.freqHz = 3000.0;
+    m_SpkOutTreble.gaindB = 0.0;
+    setFreq(&m_SpkOutTreble); setGain(&m_SpkOutTreble); 
+
+    m_SpkOutMid.freqHz = 1500.0;
+    m_SpkOutMid.gaindB = 0.0;
+    m_SpkOutMid.Q = 1.0;
+    setFreq(&m_SpkOutMid); setGain(&m_SpkOutMid); setQ(&m_SpkOutMid); 
+
+    plotSpkOutFilterSpectrum();    
+}
+
+//-------------------------------------------------------------------------
+// OnOK()
+//-------------------------------------------------------------------------
+void FilterDlg::OnOK(wxCommandEvent& event)
+{
+    //printf("FilterDlg::OnOK\n");
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+    this->EndModal(wxID_OK);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void FilterDlg::OnClose(wxCloseEvent& event)
+{
+    this->EndModal(wxID_OK);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void FilterDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    //printf("FilterDlg::OnInitDialog\n");
+    ExchangeData(EXCHANGE_DATA_IN, false);
+    //printf("m_beta: %f\n", m_beta);
+}
+
+void FilterDlg::setBeta(void) {
+    wxString buf;
+    buf.Printf(wxT("%3.2f"), m_beta);
+    m_staticTextBeta->SetLabel(buf);
+    int slider = (int)(m_beta*SLIDER_MAX + 0.5);
+    m_codec2LPCPostFilterBeta->SetValue(slider);
+}
+
+void FilterDlg::setCodec2(void) {
+    if (m_running) {
+        codec2_set_lpc_post_filter(freedv_get_codec2(g_pfreedv), 
+                               m_codec2LPCPostFilterEnable->GetValue(), 
+                               m_codec2LPCPostFilterBassBoost->GetValue(), 
+                               m_beta, m_gamma);
+    }
+}
+
+void FilterDlg::setGamma(void) {
+    wxString buf;
+    buf.Printf(wxT("%3.2f"), m_gamma);
+    m_staticTextGamma->SetLabel(buf);
+    int slider = (int)(m_gamma*SLIDER_MAX + 0.5);
+    m_codec2LPCPostFilterGamma->SetValue(slider);
+}
+
+void FilterDlg::OnEnable(wxScrollEvent& event) {
+    setCodec2();    
+}
+
+void FilterDlg::OnBassBoost(wxScrollEvent& event) {
+    setCodec2();    
+}
+
+void FilterDlg::OnBetaScroll(wxScrollEvent& event) {
+    m_beta = (float)m_codec2LPCPostFilterBeta->GetValue()/SLIDER_MAX;
+    setBeta();
+    setCodec2();
+}
+
+void FilterDlg::OnGammaScroll(wxScrollEvent& event) {
+    m_gamma = (float)m_codec2LPCPostFilterGamma->GetValue()/SLIDER_MAX;
+    setGamma();
+    setCodec2();
+}
+
+// immediately change enable flags rather using ExchangeData() so we can switch on and off at run time
+
+void FilterDlg::OnSpeexppEnable(wxScrollEvent& event) {
+    wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
+}
+
+void FilterDlg::OnMicInEnable(wxScrollEvent& event) {
+    wxGetApp().m_MicInEQEnable = m_MicInEnable->GetValue();
+}
+
+void FilterDlg::OnSpkOutEnable(wxScrollEvent& event) {
+    wxGetApp().m_SpkOutEQEnable = m_SpkOutEnable->GetValue();
+    //printf("wxGetApp().m_SpkOutEQEnable: %d\n", wxGetApp().m_SpkOutEQEnable);
+}
+
+void FilterDlg::setFreq(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%3.0f"), eq->freqHz);
+    eq->valueFreq->SetLabel(buf);
+    int slider = (int)((eq->freqHz/eq->maxFreqHz)*SLIDER_MAX + 0.5);
+    eq->sliderFreq->SetValue(slider);
+}
+
+void FilterDlg::sliderToFreq(EQ *eq, bool micIn)
+{
+    eq->freqHz = ((float)eq->sliderFreq->GetValue()/SLIDER_MAX)*eq->maxFreqHz;
+    if (eq->freqHz < 1.0) eq->freqHz = 1.0; // sox doesn't like 0 Hz;
+    setFreq(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+}
+
+void FilterDlg::setGain(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%3.1f"), eq->gaindB);
+    eq->valueGain->SetLabel(buf);
+    int slider = (int)(((eq->gaindB-MIN_GAIN)/(MAX_GAIN-MIN_GAIN))*SLIDER_MAX + 0.5);
+    eq->sliderGain->SetValue(slider);
+}
+
+void FilterDlg::sliderToGain(EQ *eq, bool micIn)
+{
+    float range = MAX_GAIN-MIN_GAIN;
+    
+    eq->gaindB = MIN_GAIN + range*((float)eq->sliderGain->GetValue()/SLIDER_MAX);
+    //printf("gaindB: %f\n", eq->gaindB);
+    setGain(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+        
+}
+
+void FilterDlg::setQ(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%2.1f"), eq->Q);
+    eq->valueQ->SetLabel(buf);
+
+    float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
+
+    int slider = (int)(((log10(eq->Q+1E-6)-MIN_LOG10_Q)/log10_range)*SLIDER_MAX + 0.5);
+    eq->sliderQ->SetValue(slider);
+}
+
+void FilterDlg::sliderToQ(EQ *eq, bool micIn)
+{
+    float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
+    
+    float sliderNorm = (float)eq->sliderQ->GetValue()/SLIDER_MAX;
+    float log10Q =  MIN_LOG10_Q + sliderNorm*(log10_range);
+    eq->Q = pow(10.0, log10Q);
+    //printf("log10Q: %f eq->Q: %f\n", log10Q, eq->Q);
+    setQ(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+}
+
+void FilterDlg::plotMicInFilterSpectrum(void) {
+    plotFilterSpectrum(&m_MicInBass, &m_MicInMid, &m_MicInTreble, m_MicInFreqRespPlot, m_MicInMagdB);
+}
+
+void FilterDlg::plotSpkOutFilterSpectrum(void) {
+    plotFilterSpectrum(&m_SpkOutBass, &m_SpkOutMid, &m_SpkOutTreble, m_SpkOutFreqRespPlot, m_SpkOutMagdB);
+}
+
+void FilterDlg::adjRunTimeMicInFilter(void) {
+    // signal an adjustment in running filter coeffs
+
+    if (m_running) {
+        ExchangeData(EXCHANGE_DATA_OUT, false);
+        *m_newMicInFilter = true;
+    }
+}
+        
+void FilterDlg::adjRunTimeSpkOutFilter(void) {
+    // signal an adjustment in running filter coeffs
+
+    if (m_running) {
+        ExchangeData(EXCHANGE_DATA_OUT, false);
+        *m_newSpkOutFilter = true;
+    }
+}
+        
+
+void FilterDlg::plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ *eqTreble, PlotSpectrum* freqRespPlot, float *magdB) {
+    char  *argBass[10];
+    char  *argTreble[10];
+    char  *argMid[10];
+    char   argstorage[10][80];
+    float magBass[F_MAG_N];
+    float magTreble[F_MAG_N];
+    float magMid[F_MAG_N];
+    int   i;
+
+    for(i=0; i<10; i++) {
+        argBass[i] = &argstorage[i][0];
+        argTreble[i] = &argstorage[i][0];
+        argMid[i] = &argstorage[i][0];
+    }
+    sprintf(argBass[0], "bass");                
+    sprintf(argBass[1], "%f", eqBass->gaindB+1E-6);
+    sprintf(argBass[2], "%f", eqBass->freqHz);      
+
+    calcFilterSpectrum(magBass, 2, argBass);
+
+    sprintf(argTreble[0], "treble");                
+    sprintf(argTreble[1], "%f", eqTreble->gaindB+1E-6);
+    sprintf(argTreble[2], "%f", eqTreble->freqHz);      
+
+    calcFilterSpectrum(magTreble, 2, argTreble);
+
+    sprintf(argTreble[0], "equalizer");                
+    sprintf(argTreble[1], "%f", eqMid->freqHz);      
+    sprintf(argTreble[2], "%f", eqMid->Q);      
+    sprintf(argTreble[3], "%f", eqMid->gaindB+1E-6);
+
+    calcFilterSpectrum(magMid, 3, argMid);
+
+    for(i=0; i<F_MAG_N; i++)
+        magdB[i] = magBass[i] + magMid[i] + magTreble[i];
+    freqRespPlot->m_newdata = true;
+    freqRespPlot->Refresh();
+}
+
+void FilterDlg::calcFilterSpectrum(float magdB[], int argc, char *argv[]) {
+    void       *sbq;
+    short       in[NIMP];
+    short       out[NIMP];
+    COMP        X[F_MAG_N];
+    float       f, w;
+    int         i, k;
+
+    // find impulse response -----------------------------------
+
+    for(i=0; i<NIMP; i++)
+        in[i] = 0;
+    in[0] = IMP_AMP;
+
+    //printf("argv[0]: %s argv[1]: %s\n", argv[0], argv[1]);
+    sbq = sox_biquad_create(argc, (const char **)argv);
+
+    sox_biquad_filter(sbq, out, in, NIMP);
+    //for(i=0; i<NIMP; i++)
+    //    printf("%d\n", out[i]);
+   
+    sox_biquad_destroy(sbq);
+
+    //for(i=0; i<NIMP; i++)
+    //    out[i] = 0.0;
+    //out[0] = IMP_AMP;
+
+    // calculate discrete time continous frequency Fourer transform
+    // doing this from first principles rather than FFT for no good reason
+
+    for(f=0,i=0; f<MAX_F_HZ; f+=F_STEP_DFT,i++) {
+        w = M_PI*f/(FS/2);
+        X[i].real = 0.0; X[i].imag = 0.0;
+        for(k=0; k<NIMP; k++) {
+            X[i].real += ((float)out[k]/IMP_AMP) * cos(w*k);
+            X[i].imag -= ((float)out[k]/IMP_AMP) * sin(w*k);
+        }
+        magdB[i] = 10.0*log10(X[i].real* X[i].real + X[i].imag*X[i].imag + 1E-12);
+        //printf("f: %f X[%d] = %f %f magdB = %f\n", f, i, X[i].real, X[i].imag,  magdB[i]);
+    }
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_filter.h b/freedv/branches/1.2/freedv-dev/src/dlg_filter.h
new file mode 100644 (file)
index 0000000..82c43df
--- /dev/null
@@ -0,0 +1,166 @@
+//==========================================================================
+// Name:            dlg_filter.h
+// Purpose:         Dialog for controlling Codec audio filtering
+// Created:         Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __FILTER_DIALOG__
+#define __FILTER_DIALOG__
+
+#include "fdmdv2_main.h"
+
+enum {disableQ = false, enableQ = true};
+
+typedef struct { 
+    wxSlider     *sliderFreq;
+    wxStaticText *valueFreq;
+    wxSlider     *sliderGain;
+    wxStaticText *valueGain;
+    wxSlider     *sliderQ;
+    wxStaticText *valueQ;
+
+    int       sliderFreqId;
+    int       sliderGainId;
+    int       sliderQId;
+    
+    float     freqHz;
+    float     gaindB;
+    float     Q;
+
+    float     maxFreqHz;
+} EQ;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class FilterDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class FilterDlg : public wxDialog
+{
+    public:
+    FilterDlg( wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
+               wxWindowID id = wxID_ANY, const wxString& title = _("Filter"), 
+               const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 800, 630 ), 
+               long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~FilterDlg();
+
+        void    ExchangeData(int inout, bool storePersistent);
+
+    protected:
+        // Handlers for events.
+        void    OnCancel(wxCommandEvent& event);
+        void    OnOK(wxCommandEvent& event);
+        void    OnClose(wxCloseEvent& event);
+        void    OnInitDialog(wxInitDialogEvent& event);
+        void    OnLPCPostFilterDefault(wxCommandEvent& event);
+
+        void    OnBetaScroll(wxScrollEvent& event);
+        void    OnGammaScroll(wxScrollEvent& event);
+        void    OnEnable(wxScrollEvent& event);
+        void    OnBassBoost(wxScrollEvent& event);
+
+        void    OnSpeexppEnable(wxScrollEvent& event);
+
+        void    OnMicInBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInBass, true); }
+        void    OnMicInBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInBass, true); }
+        void    OnMicInTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInTreble, true); }
+        void    OnMicInTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInTreble, true); }
+        void    OnMicInMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInMid, true); }
+        void    OnMicInMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInMid, true); }
+        void    OnMicInMidQScroll(wxScrollEvent& event) { sliderToQ(&m_MicInMid, true); }
+        void    OnMicInEnable(wxScrollEvent& event);
+        void    OnMicInDefault(wxCommandEvent& event);
+
+        void    OnSpkOutBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutBass, false); }
+        void    OnSpkOutBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutBass, false); }
+        void    OnSpkOutTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutTreble, false); }
+        void    OnSpkOutTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutTreble, false); }
+        void    OnSpkOutMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutMid, false); }
+        void    OnSpkOutMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutMid, false); }
+        void    OnSpkOutMidQScroll(wxScrollEvent& event) { sliderToQ(&m_SpkOutMid, false); }
+        void    OnSpkOutEnable(wxScrollEvent& event);
+        void    OnSpkOutDefault(wxCommandEvent& event);
+
+        wxStaticText* m_staticText8;
+        wxCheckBox*   m_codec2LPCPostFilterEnable;
+        wxStaticText* m_staticText9;
+        wxCheckBox*   m_codec2LPCPostFilterBassBoost;
+        wxStaticText* m_staticText91;
+        wxSlider*     m_codec2LPCPostFilterBeta;
+        wxStaticText* m_staticTextBeta;
+        wxStaticText* m_staticText911;
+        wxSlider*     m_codec2LPCPostFilterGamma;
+        wxStaticText* m_staticTextGamma;
+        wxButton*     m_LPCPostFilterDefault;
+
+        wxCheckBox*   m_ckboxSpeexpp;
+
+        wxStdDialogButtonSizer* m_sdbSizer5;
+        wxButton*     m_sdbSizer5OK;
+        wxButton*     m_sdbSizer5Cancel;
+        PlotSpectrum* m_MicInFreqRespPlot;
+        PlotSpectrum* m_SpkOutFreqRespPlot;
+        
+        wxCheckBox*   m_MicInEnable;
+        wxButton*     m_MicInDefault;
+        wxCheckBox*   m_SpkOutEnable;
+        wxButton*     m_SpkOutDefault;
+
+        float        *m_MicInMagdB;
+        float        *m_SpkOutMagdB;
+
+     private:
+        bool          m_running;
+        float         m_beta;
+        float         m_gamma;
+
+        void          setBeta(void);  // sets slider and static text from m_beta
+        void          setGamma(void); // sets slider and static text from m_gamma
+        void          setCodec2(void);
+        void          newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName);
+        EQ            newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ);
+        void          newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *sbs, wxString controlName);
+        wxAuiNotebook *m_auiNotebook;
+        void          setFreq(EQ *eq);
+        void          setGain(EQ *eq);
+        void          setQ(EQ *eq);
+        void          sliderToFreq(EQ *eq, bool micIn);
+        void          sliderToGain(EQ *eq, bool micIn);
+        void          sliderToQ(EQ *eq, bool micIn);
+        void          plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ* eqTreble, PlotSpectrum* freqRespPlot, float *magdB);
+        void          calcFilterSpectrum(float magdB[], int arc, char *argv[]);
+        void          plotMicInFilterSpectrum(void);
+        void          plotSpkOutFilterSpectrum(void);
+        void          adjRunTimeMicInFilter(void);
+        void          adjRunTimeSpkOutFilter(void);
+
+        EQ            m_MicInBass;
+        EQ            m_MicInMid;
+        EQ            m_MicInTreble;
+
+        EQ            m_SpkOutBass;
+        EQ            m_SpkOutMid;
+        EQ            m_SpkOutTreble;
+
+        float         limit(float value, float min, float max);
+        bool          *m_newMicInFilter;
+        bool          *m_newSpkOutFilter;
+
+};
+
+#endif // __FILTER_DIALOG__
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_options.cpp b/freedv/branches/1.2/freedv-dev/src/dlg_options.cpp
new file mode 100644 (file)
index 0000000..79b6c87
--- /dev/null
@@ -0,0 +1,616 @@
+//==========================================================================
+// Name:            dlg_options.cpp
+// Purpose:         Dialog for controlling misc FreeDV options
+// Date:            May 24 2013
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "dlg_options.h"
+
+extern bool                g_modal;
+extern struct freedv      *g_pfreedv;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class OptionsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+
+    wxBoxSizer* bSizer30;
+    bSizer30 = new wxBoxSizer(wxVERTICAL);
+
+    //------------------------------
+    // Txt Msg Text Box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_callSign;
+    wxStaticBox *sb_textMsg = new wxStaticBox(this, wxID_ANY, _("Txt Msg"));
+    sbSizer_callSign = new wxStaticBoxSizer(sb_textMsg, wxVERTICAL);
+
+    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    m_txtCtrlCallSign->SetToolTip(_("Txt Msg you can send along with Voice"));
+    sbSizer_callSign->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 3);
+
+    bSizer30->Add(sbSizer_callSign,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    //----------------------------------------------------------------------
+    // Voice Keyer 
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Voice Keyer")), wxHORIZONTAL);
+
+    wxStaticText *m_staticText28b = new wxStaticText(this, wxID_ANY, _("Wave File: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28b, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtCtrlVoiceKeyerWaveFile = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
+    m_txtCtrlVoiceKeyerWaveFile->SetToolTip(_("Wave file to play for Voice Keyer"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerWaveFile, 0, 0, 5);
+
+    m_buttonChooseVoiceKeyerWaveFile = new wxButton(this, wxID_APPLY, _("Choose"), wxDefaultPosition, wxSize(-1,-1), 0);
+    staticBoxSizer28a->Add(m_buttonChooseVoiceKeyerWaveFile, 0, wxALIGN_CENTER_VERTICAL, 5);
+
+    wxStaticText *m_staticText28c = new wxStaticText(this, wxID_ANY, _("   Rx Pause: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28c, 0, wxALIGN_CENTER_VERTICAL , 5);
+    m_txtCtrlVoiceKeyerRxPause = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRxPause->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRxPause, 0, 0, 5);
+
+    wxStaticText *m_staticText28d = new wxStaticText(this, wxID_ANY, _("   Repeats: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28d, 0, wxALIGN_CENTER_VERTICAL, 5);
+    m_txtCtrlVoiceKeyerRepeats = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRepeats->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRepeats, 0, 0, 5);
+
+    bSizer30->Add(staticBoxSizer28a,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __WXMSW__
+    //------------------------------
+    // debug console, for WIndows build make console pop up for debug messages
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_console;
+    wxStaticBox *sb_console = new wxStaticBox(this, wxID_ANY, _("Debug"));
+    sbSizer_console = new wxStaticBoxSizer(sb_console, wxHORIZONTAL);
+
+    m_ckboxDebugConsole = new wxCheckBox(this, wxID_ANY, _("Show Console"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_console->Add(m_ckboxDebugConsole, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_console,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
+
+    //------------------------------
+    // FreeDV 700 Options
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_freedv700;
+    wxStaticBox *sb_freedv700 = new wxStaticBox(this, wxID_ANY, _("FreeDV 700 Options"));
+    sbSizer_freedv700 = new wxStaticBoxSizer(sb_freedv700, wxHORIZONTAL);
+
+    m_ckboxFreeDV700txClip = new wxCheckBox(this, wxID_ANY, _("Clipping"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_freedv700->Add(m_ckboxFreeDV700txClip, 0, wxALIGN_LEFT, 0);
+    m_ckboxFreeDV700Combine = new wxCheckBox(this, wxID_ANY, _("Diversity Combine for plots"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_freedv700->Add(m_ckboxFreeDV700Combine, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_freedv700, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Half/Full duplex selection
+    //------------------------------
+
+    wxStaticBox *sb_duplex = new wxStaticBox(this, wxID_ANY, _("Half/Full Duplex Operation"));
+    wxStaticBoxSizer* sbSizer_duplex = new wxStaticBoxSizer(sb_duplex, wxHORIZONTAL);
+    m_ckHalfDuplex = new wxCheckBox(this, wxID_ANY, _("Half Duplex"), wxDefaultPosition, wxSize(-1,-1), 0);
+    sbSizer_duplex->Add(m_ckHalfDuplex, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
+    bSizer30->Add(sbSizer_duplex,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Test Frames/Channel simulation check box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_testFrames;
+    wxStaticBox *sb_testFrames = new wxStaticBox(this, wxID_ANY, _("Testing and Channel Simulation"));
+    sbSizer_testFrames = new wxStaticBoxSizer(sb_testFrames, wxHORIZONTAL);
+
+    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Test Frames"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxChannelNoise = new wxCheckBox(this, wxID_ANY, _("Channel Noise   SNR (dB):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxChannelNoise, 0, wxALIGN_LEFT, 0);
+    m_txtNoiseSNR = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtNoiseSNR, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxAttnCarrierEn = new wxCheckBox(this, wxID_ANY, _("Attn Carrier  Carrier:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxAttnCarrierEn, 0, wxALIGN_LEFT, 0);
+    m_txtAttnCarrier = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtAttnCarrier, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Interfering tone
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_tone;
+    wxStaticBox *sb_tone = new wxStaticBox(this, wxID_ANY, _("Simulated Interference Tone"));
+    sbSizer_tone = new wxStaticBoxSizer(sb_tone, wxHORIZONTAL);
+
+    m_ckboxTone = new wxCheckBox(this, wxID_ANY, _("Tone   Freq (Hz):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_tone->Add(m_ckboxTone, 0, wxALIGN_LEFT, 0);
+    m_txtToneFreqHz = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneFreqHz, 0, wxALIGN_LEFT, 0);
+    wxStaticText *m_staticTextta = new wxStaticText(this, wxID_ANY, _(" Amplitude (pk): "), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_tone->Add(m_staticTextta, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtToneAmplitude = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneAmplitude, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_tone,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __EXPERIMENTAL_UDP__
+    //------------------------------
+    // Txt Encoding 
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_encoding = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Text Encoding")), wxHORIZONTAL);
+
+#ifdef SHORT_VARICODE
+    m_rb_textEncoding1 = new wxRadioButton( this, wxID_ANY, wxT("Long varicode"), wxDefaultPosition, wxDefaultSize, 0);
+    m_rb_textEncoding1->SetValue(true);
+    sbSizer_encoding->Add(m_rb_textEncoding1, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb_textEncoding2 = new wxRadioButton( this, wxID_ANY, wxT("Short Varicode"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_encoding->Add(m_rb_textEncoding2, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+
+    m_ckboxEnableChecksum = new wxCheckBox(this, wxID_ANY, _("Use Checksum on Rx"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_encoding->Add(m_ckboxEnableChecksum, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_encoding,0, wxALL|wxEXPAND, 3);
+    //------------------------------
+    // Event processing
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_events;
+    wxStaticBox *sb_events = new wxStaticBox(this, wxID_ANY, _("Event Processing"));
+    sbSizer_events = new wxStaticBoxSizer(sb_events, wxVERTICAL);
+
+    // event processing enable and spam timer
+
+    wxStaticBoxSizer* sbSizer_events_top;
+    wxStaticBox* sb_events1 = new wxStaticBox(this, wxID_ANY, _(""));    
+    sbSizer_events_top = new wxStaticBoxSizer(sb_events1, wxHORIZONTAL);
+
+    m_ckbox_events = new wxCheckBox(this, wxID_ANY, _("Enable System Calls    Syscall Spam Timer"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_events->SetToolTip(_("Enable processing of events and generation of system calls"));
+    sbSizer_events_top->Add(m_ckbox_events, 0, 0, 5);
+    m_txt_spam_timer = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    m_txt_spam_timer->SetToolTip(_("Many matching events can cause a flood of syscalls. Set minimum time (seconds) between syscalls for each event here"));
+    sbSizer_events_top->Add(m_txt_spam_timer, 0, 0, 5);
+    m_rb_spam_timer = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    m_rb_spam_timer->SetForegroundColour( wxColour(0, 255, 0 ) );
+    sbSizer_events_top->Add(m_rb_spam_timer, 0, 0, 10);
+    sbSizer_events->Add(sbSizer_events_top, 0, 0, 5);
+
+    // list of regexps
+
+    wxStaticBoxSizer* sbSizer_regexp = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Regular Expressions to Process Events")), wxHORIZONTAL);
+    m_txt_events_regexp_match = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
+    m_txt_events_regexp_match->SetToolTip(_("Enter regular expressions to match events"));
+    sbSizer_regexp->Add(m_txt_events_regexp_match, 1, wxEXPAND, 5);
+    m_txt_events_regexp_replace = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
+    m_txt_events_regexp_replace->SetToolTip(_("Enter regular expressions to replace events"));
+    sbSizer_regexp->Add(m_txt_events_regexp_replace, 1, wxEXPAND, 5);
+    sbSizer_events->Add(sbSizer_regexp, 1, wxEXPAND, 5);
+
+    // log of events and responses
+
+    wxStaticBoxSizer* sbSizer_event_log = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Log of Events and Responses")), wxVERTICAL);
+    wxBoxSizer* bSizer33 = new wxBoxSizer(wxHORIZONTAL);
+    m_txt_events_in = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
+    bSizer33->Add(m_txt_events_in, 1, wxEXPAND, 5);
+    m_txt_events_out = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
+    bSizer33->Add(m_txt_events_out, 1, wxEXPAND, 5);
+    sbSizer_event_log->Add(bSizer33, 1, wxEXPAND, 5);
+    sbSizer_events->Add(sbSizer_event_log, 1, wxEXPAND, 5);
+
+    bSizer30->Add(sbSizer_events,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // UDP control port
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_udp;
+    wxStaticBox* sb_udp = new wxStaticBox(this, wxID_ANY, _("UDP Control Port"));
+    sbSizer_udp = new wxStaticBoxSizer(sb_udp, wxHORIZONTAL);
+    m_ckbox_udp_enable = new wxCheckBox(this, wxID_ANY, _("Enable UDP Control Port    UDP Port Number:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_udp->SetToolTip(_("Enable control of FreeDV via UDP port"));
+    sbSizer_udp->Add(m_ckbox_udp_enable, 0,  wxALIGN_CENTER_HORIZONTAL, 5);
+    m_txt_udp_port = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(50,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_udp->Add(m_txt_udp_port, 0, wxALIGN_CENTER_HORIZONTAL, 5);
+
+    bSizer30->Add(sbSizer_udp,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
+
+    //------------------------------
+    // OK - Cancel - Apply Buttons 
+    //------------------------------
+
+    wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_sdbSizer5OK = new wxButton(this, wxID_OK);
+    bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
+
+    m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
+    bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
+
+    m_sdbSizer5Apply = new wxButton(this, wxID_APPLY);
+    bSizer31->Add(m_sdbSizer5Apply, 0, wxALL, 2);
+
+    bSizer30->Add(bSizer31, 0, wxALIGN_CENTER, 0);
+
+    this->SetSizer(bSizer30);
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+     this->Layout();
+
+    this->Centre(wxBOTH);
+    // Connect Events -------------------------------------------------------
+
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
+
+    m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
+    m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
+    m_sdbSizer5Apply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
+
+    m_ckboxTestFrame->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
+    m_ckboxFreeDV700txClip->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
+
+    m_buttonChooseVoiceKeyerWaveFile->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+
+    event_in_serial = 0;
+    event_out_serial = 0;
+}
+
+//-------------------------------------------------------------------------
+// ~OptionsDlg()
+//-------------------------------------------------------------------------
+OptionsDlg::~OptionsDlg()
+{
+
+    // Disconnect Events
+
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
+
+    m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
+    m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
+    m_sdbSizer5Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
+
+    m_ckboxTestFrame->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
+    m_ckboxFreeDV700txClip->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+    m_buttonChooseVoiceKeyerWaveFile->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
+}
+
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void OptionsDlg::ExchangeData(int inout, bool storePersistent)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        m_txtCtrlCallSign->SetValue(wxGetApp().m_callSign);
+
+        /* Voice Keyer */
+
+        m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+        m_txtCtrlVoiceKeyerRxPause->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRxPause));
+        m_txtCtrlVoiceKeyerRepeats->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRepeats));
+
+        m_ckHalfDuplex->SetValue(wxGetApp().m_boolHalfDuplex);
+
+        m_ckboxTestFrame->SetValue(wxGetApp().m_testFrames);
+
+        m_ckboxChannelNoise->SetValue(wxGetApp().m_channel_noise);
+        m_txtNoiseSNR->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_noise_snr));
+
+        m_ckboxTone->SetValue(wxGetApp().m_tone);
+        m_txtToneFreqHz->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_freq_hz));
+        m_txtToneAmplitude->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_amplitude));
+
+        m_ckboxAttnCarrierEn->SetValue(wxGetApp().m_attn_carrier_en);
+        m_txtAttnCarrier->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_attn_carrier));
+
+#ifdef __EXPERIMENTAL_UDP__
+        m_ckbox_events->SetValue(wxGetApp().m_events);
+        m_txt_spam_timer->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_events_spam_timer));
+
+        m_txt_events_regexp_match->SetValue(wxGetApp().m_events_regexp_match);
+        m_txt_events_regexp_replace->SetValue(wxGetApp().m_events_regexp_replace);
+        
+        m_ckbox_udp_enable->SetValue(wxGetApp().m_udp_enable);
+        m_txt_udp_port->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_udp_port));
+
+#ifdef SHORT_VARICODE
+        if (wxGetApp().m_textEncoding == 1)
+            m_rb_textEncoding1->SetValue(true);
+        if (wxGetApp().m_textEncoding == 2)
+            m_rb_textEncoding2->SetValue(true);
+#endif
+        m_ckboxEnableChecksum->SetValue(wxGetApp().m_enable_checksum);
+#endif
+
+        m_ckboxFreeDV700txClip->SetValue(wxGetApp().m_FreeDV700txClip);
+        m_ckboxFreeDV700Combine->SetValue(wxGetApp().m_FreeDV700Combine);
+
+#ifdef __WXMSW__
+        m_ckboxDebugConsole->SetValue(wxGetApp().m_debug_console);
+#endif
+    }
+
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        wxGetApp().m_callSign = m_txtCtrlCallSign->GetValue();
+
+        wxGetApp().m_boolHalfDuplex = m_ckHalfDuplex->GetValue();
+        pConfig->Write(wxT("/Rig/HalfDuplex"), wxGetApp().m_boolHalfDuplex);
+
+        /* Voice Keyer */
+
+        wxGetApp().m_txtVoiceKeyerWaveFile = m_txtCtrlVoiceKeyerWaveFile->GetValue();
+        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
+        long tmp;
+        m_txtCtrlVoiceKeyerRxPause->GetValue().ToLong(&tmp); if (tmp < 0) tmp = 0; wxGetApp().m_intVoiceKeyerRxPause = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
+        m_txtCtrlVoiceKeyerRepeats->GetValue().ToLong(&tmp);
+        if (tmp < 0) tmp = 0; if (tmp > 100) tmp = 100;
+        wxGetApp().m_intVoiceKeyerRepeats = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
+
+        wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
+
+        wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+        long noise_snr;
+        m_txtNoiseSNR->GetValue().ToLong(&noise_snr);
+        wxGetApp().m_noise_snr = (int)noise_snr;
+
+        wxGetApp().m_tone    = m_ckboxTone->GetValue();
+        long tone_freq_hz, tone_amplitude;
+        m_txtToneFreqHz->GetValue().ToLong(&tone_freq_hz);
+        wxGetApp().m_tone_freq_hz = (int)tone_freq_hz;
+        m_txtToneAmplitude->GetValue().ToLong(&tone_amplitude);
+        wxGetApp().m_tone_amplitude = (int)tone_amplitude;
+
+        wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();
+        long attn_carrier;
+        m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+        wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+#ifdef __EXPERIMENTAL_UDP__
+        wxGetApp().m_events        = m_ckbox_events->GetValue();
+        long spam_timer;
+        m_txt_spam_timer->GetValue().ToLong(&spam_timer);
+        wxGetApp().m_events_spam_timer = (int)spam_timer;
+
+        // make sure regexp lists are terminated by a \n
+
+        if (m_txt_events_regexp_match->GetValue().Last() != '\n') {
+            m_txt_events_regexp_match->SetValue(m_txt_events_regexp_match->GetValue()+'\n');
+        }
+        if (m_txt_events_regexp_replace->GetValue().Last() != '\n') {
+            m_txt_events_regexp_replace->SetValue(m_txt_events_regexp_replace->GetValue()+'\n');
+        }
+        wxGetApp().m_events_regexp_match = m_txt_events_regexp_match->GetValue();
+        wxGetApp().m_events_regexp_replace = m_txt_events_regexp_replace->GetValue();
+        wxGetApp().m_udp_enable     = m_ckbox_udp_enable->GetValue();
+        long port;
+        m_txt_udp_port->GetValue().ToLong(&port);
+        wxGetApp().m_udp_port       = (int)port;
+
+#ifdef SHORT_VARICODE
+        if (m_rb_textEncoding1->GetValue())
+            wxGetApp().m_textEncoding = 1;
+        if (m_rb_textEncoding2->GetValue())
+            wxGetApp().m_textEncoding = 2;
+#endif
+        wxGetApp().m_enable_checksum = m_ckboxEnableChecksum->GetValue();
+#endif
+
+        wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
+        wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+
+#ifdef __WXMSW__
+        wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#endif
+
+        if (storePersistent) {
+            pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
+#ifdef SHORT_VARICODE
+            pConfig->Write(wxT("/Data/TextEncoding"), wxGetApp().m_textEncoding);
+#endif
+            pConfig->Write(wxT("/Data/EnableChecksumOnMsgRx"), wxGetApp().m_enable_checksum);
+
+            pConfig->Write(wxT("/Events/enable"), wxGetApp().m_events);
+            pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+            pConfig->Write(wxT("/Events/regexp_match"), wxGetApp().m_events_regexp_match);
+            pConfig->Write(wxT("/Events/regexp_replace"), wxGetApp().m_events_regexp_replace);
+            
+            pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
+            pConfig->Write(wxT("/UDP/port"),  wxGetApp().m_udp_port);
+
+            pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+
+            pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
+
+            pConfig->Write(wxT("/Noise/noise_snr"),  wxGetApp().m_noise_snr);
+
+#ifdef __WXMSW__
+            pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+#endif
+
+            pConfig->Flush();
+        }
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+//-------------------------------------------------------------------------
+// OnOK()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+    //this->EndModal(wxID_OK);
+    g_modal = false;
+    this->Show(false);
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnCancel(wxCommandEvent& event)
+{
+    //this->EndModal(wxID_CANCEL);
+    g_modal = false;
+    this->Show(false);
+}
+
+//-------------------------------------------------------------------------
+// OnApply()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnApply(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_IN, false);
+}
+
+// immediately change flags rather using ExchangeData() so we can switch on and off at run time
+
+void OptionsDlg::OnTestFrame(wxScrollEvent& event) {
+    wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
+}
+
+void OptionsDlg::OnChannelNoise(wxScrollEvent& event) {
+    wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+}
+
+
+void OptionsDlg::OnChooseVoiceKeyerWaveFile(wxCommandEvent& event) {
+     wxFileDialog openFileDialog(
+                                 this,
+                                 wxT("Voice Keyer wave file"),
+                                 wxGetApp().m_txtVoiceKeyerWaveFilePath,
+                                 wxEmptyString,
+                                 wxT("WAV files (*.wav)|*.wav"),
+                                 wxFD_OPEN
+                                 );
+     if(openFileDialog.ShowModal() == wxID_CANCEL) {
+         return;     // the user changed their mind...
+     }
+
+     wxString fileName, extension;
+     wxGetApp().m_txtVoiceKeyerWaveFile = openFileDialog.GetPath();
+     wxFileName::SplitPath(wxGetApp().m_txtVoiceKeyerWaveFile, &wxGetApp().m_txtVoiceKeyerWaveFilePath, &fileName, &extension);
+     m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+}
+
+//  Run time update of carrier amplitude attenuation
+
+void OptionsDlg::OnAttnCarrierEn(wxScrollEvent& event) {
+    long attn_carrier;
+    m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+    wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+    /* uncheck -> checked, attenuate selected carrier */
+
+    if (m_ckboxAttnCarrierEn->GetValue() && !wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 0.25);
+        } else {
+            wxMessageBox("Carrier attenuation feature only works on 700C", wxT("Warning"), wxOK | wxICON_WARNING, this);
+        }
+    }
+
+    /* checked -> unchecked, reset selected carrier */
+
+    if (!m_ckboxAttnCarrierEn->GetValue() && wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 1.0);
+        }
+    }
+        
+    wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();    
+}
+
+void OptionsDlg::OnFreeDV700txClip(wxScrollEvent& event) {
+    wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
+}
+
+void OptionsDlg::OnFreeDV700Combine(wxScrollEvent& event) {
+    wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+}
+
+void OptionsDlg::updateEventLog(wxString event_in, wxString event_out) {
+    wxString event_in_with_serial, event_out_with_serial; 
+    event_in_with_serial.Printf(_T("[%d] %s"), event_in_serial++, event_in);
+    event_out_with_serial.Printf(_T("[%d] %s"), event_out_serial++, event_out);
+
+    m_txt_events_in->AppendText(event_in_with_serial+"\n");
+    m_txt_events_out->AppendText(event_out_with_serial+"\n");
+}
+
+
+void OptionsDlg::OnDebugConsole(wxScrollEvent& event) {
+    wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#ifdef __WXMSW__
+    // somewhere to send printfs while developing, causes conmsole to pop up on Windows
+    if (wxGetApp().m_debug_console) {
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    } 
+#endif
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_options.h b/freedv/branches/1.2/freedv-dev/src/dlg_options.h
new file mode 100644 (file)
index 0000000..081448c
--- /dev/null
@@ -0,0 +1,137 @@
+//==========================================================================
+// Name:            dlg_options.h
+// Purpose:         Dialog for controlling misc FreeDV options
+// Created:         Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __OPTIONS_DIALOG__
+#define __OPTIONS_DIALOG__
+
+#include "fdmdv2_main.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class OptionsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class OptionsDlg : public wxDialog
+{
+    public:
+    OptionsDlg( wxWindow* parent,
+               wxWindowID id = wxID_ANY, const wxString& title = _("Options"), 
+                const wxPoint& pos = wxDefaultPosition, 
+#ifdef __WXMSW__
+                /* we add debug console check box for windows */
+                const wxSize& size = wxSize(600,410), 
+#else
+                const wxSize& size = wxSize(600,380), 
+#endif
+               long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~OptionsDlg();
+
+        void    ExchangeData(int inout, bool storePersistent);
+        void    updateEventLog(wxString event_in, wxString event_out);
+
+        bool    enableEventsChecked() {return m_ckbox_events->GetValue();}
+
+        void SetSpamTimerLight(bool state) {
+
+            // Colours don't work on Windows
+
+            if (state) {
+                m_rb_spam_timer->SetForegroundColour( wxColour( 255,0 , 0 ) ); // red
+                m_rb_spam_timer->SetValue(true);
+            }
+            else {
+                m_rb_spam_timer->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
+                m_rb_spam_timer->SetValue(false);
+            }
+        }
+
+
+    protected:
+
+        // Handlers for events.
+
+        void    OnOK(wxCommandEvent& event);
+        void    OnCancel(wxCommandEvent& event);
+        void    OnApply(wxCommandEvent& event);
+        void    OnClose(wxCloseEvent& event);
+        void    OnInitDialog(wxInitDialogEvent& event);
+        void    OnTestFrame(wxScrollEvent& event);
+        void    OnChannelNoise(wxScrollEvent& event);
+        void    OnAttnCarrierEn(wxScrollEvent& event);
+        void    OnFreeDV700txClip(wxScrollEvent& event);
+        void    OnFreeDV700Combine(wxScrollEvent& event);
+        void    OnDebugConsole(wxScrollEvent& event);
+
+        wxTextCtrl   *m_txtCtrlCallSign; // TODO: this should be renamed to tx_txtmsg, and rename all related incl persis strge
+
+        wxCheckBox* m_ckHalfDuplex;
+
+        /* Voice Keyer */
+
+        wxButton     *m_buttonChooseVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRxPause;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRepeats;
+
+        /* test frames, other simulated channel impairments */
+
+        wxCheckBox   *m_ckboxTestFrame;
+        wxCheckBox   *m_ckboxChannelNoise;
+        wxTextCtrl   *m_txtNoiseSNR;
+        wxCheckBox   *m_ckboxAttnCarrierEn;
+        wxTextCtrl   *m_txtAttnCarrier;
+
+        wxCheckBox   *m_ckboxTone;
+        wxTextCtrl   *m_txtToneFreqHz;
+        wxTextCtrl   *m_txtToneAmplitude;
+
+        wxCheckBox   *m_ckboxFreeDV700txClip;
+        wxCheckBox   *m_ckboxFreeDV700Combine;
+
+        wxRadioButton *m_rb_textEncoding1;
+        wxRadioButton *m_rb_textEncoding2;
+        wxCheckBox    *m_ckboxEnableChecksum;
+
+        wxCheckBox   *m_ckbox_events;
+        wxTextCtrl   *m_txt_events_regexp_match;
+        wxTextCtrl   *m_txt_events_regexp_replace;
+        wxTextCtrl   *m_txt_events_in;
+        wxTextCtrl   *m_txt_events_out;
+        wxTextCtrl   *m_txt_spam_timer;
+        wxRadioButton *m_rb_spam_timer;
+
+        wxCheckBox   *m_ckbox_udp_enable;
+        wxTextCtrl   *m_txt_udp_port;
+
+        wxButton*     m_sdbSizer5OK;
+        wxButton*     m_sdbSizer5Cancel;
+        wxButton*     m_sdbSizer5Apply;
+
+        wxCheckBox   *m_ckboxDebugConsole;
+
+        unsigned int  event_in_serial, event_out_serial;
+
+        void OnChooseVoiceKeyerWaveFile(wxCommandEvent& event);
+
+     private:
+};
+
+#endif // __OPTIONS_DIALOG__
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_plugin.cpp b/freedv/branches/1.2/freedv-dev/src/dlg_plugin.cpp
new file mode 100644 (file)
index 0000000..68610f4
--- /dev/null
@@ -0,0 +1,148 @@
+//==========================================================================
+// Name:            dlg_plugin.cpp
+// Purpose:         Subclasses dialog GUI for PlugIn Config. Creates simple 
+//                  wxWidgets dialog GUI to set a few text strings.
+// Date:            Jan 2016
+// Authors:         David Rowe
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "dlg_plugin.h"
+#include "fdmdv2_main.h"
+
+#ifdef __WIN32__
+#include <wx/msw/registry.h>
+#endif
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+#include <glob.h>
+#include <string.h>
+#endif
+
+#include <sstream>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlugInDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlugInDlg::PlugInDlg(const wxString& title, int numParam, wxString paramName[], wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    m_name = title;
+    m_numParam = numParam;
+    assert(m_numParam <= PLUGIN_MAX_PARAMS);
+
+    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
+    this->SetSizer(mainSizer);
+
+    int i;
+    for (i=0; i<m_numParam; i++) {
+        m_paramName[i] = paramName[i];
+        wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, m_paramName[i]), wxVERTICAL);
+        m_txtCtrlParam[i]= new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
+        staticBoxSizer28a->Add(m_txtCtrlParam[i], 0, 0, 5);
+        mainSizer->Add(staticBoxSizer28a, 0, wxEXPAND, 5);
+    }
+
+    //----------------------------------------------------------------------
+    // OK - Cancel - Apply
+    //----------------------------------------------------------------------
+
+    wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_buttonOK->SetDefault();
+    boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonCancel, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    mainSizer->Add(boxSizer12, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 5);
+
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+    Centre(wxBOTH);
+
+    // Connect events
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(PlugInDlg::OnInitDialog), NULL, this);
+    m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnOK), NULL, this);
+    m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnCancel), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// ~PlugInDlg()
+//-------------------------------------------------------------------------
+PlugInDlg::~PlugInDlg()
+{
+    // Disconnect Events
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(PlugInDlg::OnInitDialog), NULL, this);
+    m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnOK), NULL, this);
+    m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnCancel), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void PlugInDlg::ExchangeData(int inout)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    wxString str;
+    int i;
+    
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        for (i=0; i<m_numParam; i++) {
+            m_txtCtrlParam[i]->SetValue(wxGetApp().m_txtPlugInParam[i]);
+        }
+    }
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        for (i=0; i<m_numParam; i++) {
+          wxGetApp().m_txtPlugInParam[i] = m_txtCtrlParam[i]->GetValue();
+          wxString configStr = "/" + m_name + "/" + m_paramName[i];
+          pConfig->Write(configStr, wxGetApp().m_txtPlugInParam[i]);
+        }
+        pConfig->Flush();
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    this->EndModal(wxID_OK);
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_plugin.h b/freedv/branches/1.2/freedv-dev/src/dlg_plugin.h
new file mode 100644 (file)
index 0000000..72efc7b
--- /dev/null
@@ -0,0 +1,65 @@
+//==========================================================================
+// Name:            dlg_ptt.h
+// Purpose:         Subclasses dialog GUI for PTT Config.
+//                  
+// Created:         May. 11, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __PLUGIN_DIALOG__
+#define __PLUGIN_DIALOG__
+
+#include "fdmdv2_main.h"
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/xrc/xh_bmp.h>
+#include <wx/dialog.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/listbox.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/spinctrl.h>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlugInDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlugInDlg : public wxDialog
+{
+    public:
+    PlugInDlg(const wxString& title = _("PTT Config"), int numParam = 0, wxString paramNames[]=NULL, wxWindow* parent=NULL, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(450,300), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
+        virtual ~PlugInDlg();
+        void    ExchangeData(int inout);
+
+    protected:
+        wxString    m_name;
+        int         m_numParam;
+        wxString    m_paramName[PLUGIN_MAX_PARAMS];
+
+        wxTextCtrl* m_txtCtrlParam[PLUGIN_MAX_PARAMS];
+        wxButton*   m_buttonOK;
+        wxButton*   m_buttonCancel;
+
+
+protected:
+
+        void OnOK(wxCommandEvent& event);
+        void OnCancel(wxCommandEvent& event);
+        virtual void OnInitDialog(wxInitDialogEvent& event);
+};
+
+#endif // __PLUGIN_DIALOG__
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_ptt.cpp b/freedv/branches/1.2/freedv-dev/src/dlg_ptt.cpp
new file mode 100644 (file)
index 0000000..1a04c9c
--- /dev/null
@@ -0,0 +1,570 @@
+//==========================================================================
+// Name:            dlg_ptt.cpp
+// Purpose:         Subclasses dialog GUI for PTT Config. Creates simple 
+//                  wxWidgets dialog GUI to select real/virtual Comm ports.
+// Date:            May 11 2012
+// Authors:         David Rowe, David Witten, Joel Stanley
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "dlg_ptt.h"
+#include "fdmdv2_main.h"
+
+#ifdef __WIN32__
+#include <wx/msw/registry.h>
+#endif
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+#include <glob.h>
+#include <string.h>
+#endif
+
+#include <sstream>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class ComPortsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
+    this->SetSizer(mainSizer);
+    
+    //----------------------------------------------------------------------
+    // Vox tone option
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer28 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("VOX PTT Settings")), wxHORIZONTAL);
+    m_ckLeftChannelVoxTone = new wxCheckBox(this, wxID_ANY, _("Left Channel Vox Tone"), wxDefaultPosition, wxSize(-1,-1), 0);
+    staticBoxSizer28->Add(m_ckLeftChannelVoxTone, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
+
+    mainSizer->Add(staticBoxSizer28, 0, wxEXPAND, 5);
+
+    //----------------------------------------------------------------------
+    // Hamlib for CAT PTT
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxHORIZONTAL);
+    wxGridSizer* gridSizerhl = new wxGridSizer(5, 2, 0, 0);
+    staticBoxSizer18->Add(gridSizerhl, 1, wxEXPAND|wxALIGN_LEFT, 5);
+
+    /* Use Hamlib for PTT checkbox. */
+
+    m_ckUseHamlibPTT = new wxCheckBox(this, wxID_ANY, _("Use Hamlib PTT"), wxDefaultPosition, wxSize(-1, -1), 0);
+    m_ckUseHamlibPTT->SetValue(false);
+    gridSizerhl->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0);
+    gridSizerhl->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND);
+
+    /* Hamlib Rig Type combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbRigName = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, -1), 0, NULL, wxCB_DROPDOWN);
+    wxGetApp().m_hamlib->populateComboBox(m_cbRigName);
+    m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
+    gridSizerhl->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    /* Hamlib Serial Port combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL |  wxALIGN_RIGHT, 20);
+    m_cbSerialPort = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizerhl->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    /* Hamlib Serial Rate combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Rate:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialRate = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizerhl->Add(m_cbSerialRate, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Params:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialParams = new wxStaticText(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, 0);
+    gridSizerhl->Add(m_cbSerialParams, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    mainSizer->Add(staticBoxSizer18, 0, wxEXPAND, 5);
+
+    //----------------------------------------------------------------------
+    // Serial port PTT
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer17 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Serial Port Settings")), wxVERTICAL);
+    mainSizer->Add(staticBoxSizer17, 1, wxEXPAND, 5);
+    wxStaticBoxSizer* staticBoxSizer31 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("PTT Port")), wxVERTICAL);
+    staticBoxSizer17->Add(staticBoxSizer31, 1, wxEXPAND, 5);
+
+#ifdef __WXMSW__
+    m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckUseSerialPTT->SetValue(false);
+    staticBoxSizer31->Add(m_ckUseSerialPTT, 0, wxALIGN_LEFT, 20);
+
+    wxArrayString m_listCtrlPortsArr;
+    m_listCtrlPorts = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(-1,45), m_listCtrlPortsArr, wxLB_SINGLE | wxLB_SORT);
+    staticBoxSizer31->Add(m_listCtrlPorts, 1, wxALIGN_CENTER, 0);
+#endif
+
+#if defined(__WXOSX__) || defined(__WXGTK__)
+    wxBoxSizer* bSizer83;
+    bSizer83 = new wxBoxSizer(wxHORIZONTAL);
+
+    wxGridSizer* gridSizer200 = new wxGridSizer(1, 3, 0, 0);
+    
+    m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckUseSerialPTT->SetValue(false);
+    gridSizer200->Add(m_ckUseSerialPTT, 1, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
+
+    m_staticText12 = new wxStaticText(this, wxID_ANY, _("Serial Device:  "), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText12->Wrap(-1);
+    gridSizer200->Add(m_staticText12, 1,wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
+
+    m_cbCtlDevicePath = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizer200->Add(m_cbCtlDevicePath, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 2);
+    
+    bSizer83->Add(gridSizer200, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 2);
+    staticBoxSizer31->Add(bSizer83, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    wxBoxSizer* boxSizer19 = new wxBoxSizer(wxVERTICAL);
+    staticBoxSizer17->Add(boxSizer19, 1, wxEXPAND, 5);
+    wxStaticBoxSizer* staticBoxSizer16 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Signal polarity")), wxHORIZONTAL);
+    boxSizer19->Add(staticBoxSizer16, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    wxGridSizer* gridSizer17 = new wxGridSizer(2, 2, 0, 0);
+    staticBoxSizer16->Add(gridSizer17, 1, wxEXPAND|wxALIGN_RIGHT, 5);
+
+    m_rbUseDTR = new wxRadioButton(this, wxID_ANY, _("Use DTR"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_rbUseDTR->SetToolTip(_("Toggle DTR line for PTT"));
+    m_rbUseDTR->SetValue(1);
+    gridSizer17->Add(m_rbUseDTR, 0, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
+
+    m_ckDTRPos = new wxCheckBox(this, wxID_ANY, _("DTR = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckDTRPos->SetToolTip(_("Set Polarity of the DTR line"));
+    m_ckDTRPos->SetValue(false);
+    gridSizer17->Add(m_ckDTRPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    m_rbUseRTS = new wxRadioButton(this, wxID_ANY, _("Use RTS"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_rbUseRTS->SetToolTip(_("Toggle the RTS pin for PTT"));
+    m_rbUseRTS->SetValue(1);
+    gridSizer17->Add(m_rbUseRTS, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    m_ckRTSPos = new wxCheckBox(this, wxID_ANY, _("RTS = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckRTSPos->SetValue(false);
+    m_ckRTSPos->SetToolTip(_("Set Polarity of the RTS line"));
+    gridSizer17->Add(m_ckRTSPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    //----------------------------------------------------------------------
+    // OK - Cancel - Apply
+    //----------------------------------------------------------------------
+
+    wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_buttonTest = new wxButton(this, wxID_APPLY, _("Test PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonTest, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_buttonOK->SetDefault();
+    boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonCancel, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonApply = new wxButton(this, wxID_APPLY, _("Apply"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonApply, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    mainSizer->Add(boxSizer12, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 5);
+
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+    Centre(wxBOTH);
+
+    // Connect events
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
+    m_ckUseHamlibPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
+    m_ckUseSerialPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
+    m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
+    m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
+    m_buttonApply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// ~ComPortsDlg()
+//-------------------------------------------------------------------------
+ComPortsDlg::~ComPortsDlg()
+{
+    // Disconnect Events
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
+    m_ckUseHamlibPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
+    m_ckUseSerialPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
+    m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
+    m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
+    m_buttonApply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    populatePortList();
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// populatePortList()
+//-------------------------------------------------------------------------
+void ComPortsDlg::populatePortList()
+{
+
+    /* populate Hamlib serial rate combo box */
+
+    wxString serialRates[] = {"default", "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"}; 
+    for(int i=0; i<WXSIZEOF(serialRates); i++) {
+        m_cbSerialRate->Append(serialRates[i]);
+    }
+
+#ifdef __WXMSW__
+    m_listCtrlPorts->Clear();
+    m_cbSerialPort->Clear();
+    wxArrayString aStr;
+    wxRegKey key(wxRegKey::HKLM, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"));
+    if(!key.Exists())
+    {
+        return;
+    }
+    else
+    {
+        // Get the number of subkeys and enumerate them.
+        if(!key.Open(wxRegKey::Read))
+        {
+            return;
+        }    
+        size_t subkeys;
+        size_t values;
+        if(!key.GetKeyInfo(&subkeys, NULL, &values, NULL))
+        {
+            return;
+        }
+        if(!key.HasValues())
+        {
+            return;
+        }
+        wxString key_name;
+        long el = 1;
+        key.GetFirstValue(key_name, el);
+        wxString valType;
+        wxString key_data;
+        for(unsigned int i = 0; i < values; i++)
+        {
+            key.QueryValue(key_name, key_data);
+            //wxPrintf("Value:  %s Data: %s\n", key_name, key_data);
+            aStr.Add(key_data, 1);
+            key.GetNextValue(key_name, el);
+        }
+    }
+    m_listCtrlPorts->Append(aStr);
+    m_cbSerialPort->Append(aStr);
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+    m_cbSerialPort->Clear();
+    m_cbCtlDevicePath->Clear();
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+       glob_t  gl;
+#ifdef __FreeBSD__
+       if(glob("/dev/tty*", GLOB_MARK, NULL, &gl)==0) {
+#else
+       if(glob("/dev/tty.*", GLOB_MARK, NULL, &gl)==0) {
+#endif
+               for(unsigned int i=0; i<gl.gl_pathc; i++) {
+                       if(gl.gl_pathv[i][strlen(gl.gl_pathv[i])-1]=='/')
+                               continue;
+                               
+                       /* Exclude pseudo TTYs */
+                       if(gl.gl_pathv[i][8] >= 'l' && gl.gl_pathv[i][8] <= 's')
+                               continue;
+                       if(gl.gl_pathv[i][8] >= 'L' && gl.gl_pathv[i][8] <= 'S')
+                               continue;
+
+                       /* Exclude virtual TTYs */
+                       if(gl.gl_pathv[i][8] == 'v')
+                               continue;
+
+                       /* Exclude initial-state and lock-state devices */
+#ifndef __WXOSX__
+                       if(strchr(gl.gl_pathv[i], '.') != NULL)
+                               continue;
+#endif
+
+                       m_cbSerialPort->Append(gl.gl_pathv[i]);
+                       m_cbCtlDevicePath->Append(gl.gl_pathv[i]);
+               }
+               globfree(&gl);
+       }
+#else
+    /* TODO(Joel): http://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them */
+    m_cbSerialPort->Append("/dev/ttyUSB0");
+    m_cbSerialPort->Append("/dev/ttyUSB1");
+    m_cbSerialPort->Append("/dev/ttyS0");
+    m_cbSerialPort->Append("/dev/ttyS1");
+
+    m_cbCtlDevicePath->Clear();
+    m_cbCtlDevicePath->Append("/dev/ttyUSB0");
+    m_cbCtlDevicePath->Append("/dev/ttyUSB1");
+    m_cbCtlDevicePath->Append("/dev/ttyS0");
+    m_cbCtlDevicePath->Append("/dev/ttyS1");
+#endif
+#endif
+
+
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void ComPortsDlg::ExchangeData(int inout)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    wxString str;
+    
+    if(inout == EXCHANGE_DATA_IN) {
+        m_ckLeftChannelVoxTone->SetValue(wxGetApp().m_leftChannelVoxTone);
+
+        /* Hamlib */
+
+        m_ckUseHamlibPTT->SetValue(wxGetApp().m_boolHamlibUseForPTT);
+        m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
+        m_cbSerialPort->SetValue(wxGetApp().m_strHamlibSerialPort);
+
+        if (wxGetApp().m_intHamlibSerialRate == 0) {
+            m_cbSerialRate->SetSelection(0);
+        } else {
+            m_cbSerialRate->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intHamlibSerialRate));
+        }
+
+        /* Serial PTT */
+
+        m_ckUseSerialPTT->SetValue(wxGetApp().m_boolUseSerialPTT);
+        str = wxGetApp().m_strRigCtrlPort;
+#ifdef __WXMSW__
+        m_listCtrlPorts->SetStringSelection(str);
+#endif
+#if defined(__WXOSX__) || defined(__WXGTK__)
+        m_cbCtlDevicePath->SetValue(str);
+#endif
+        m_rbUseRTS->SetValue(wxGetApp().m_boolUseRTS);
+        m_ckRTSPos->SetValue(wxGetApp().m_boolRTSPos);
+        m_rbUseDTR->SetValue(wxGetApp().m_boolUseDTR);
+        m_ckDTRPos->SetValue(wxGetApp().m_boolDTRPos);
+    }
+
+    if (inout == EXCHANGE_DATA_OUT) {
+        wxGetApp().m_leftChannelVoxTone = m_ckLeftChannelVoxTone->GetValue();
+        pConfig->Write(wxT("/Rig/leftChannelVoxTone"), wxGetApp().m_leftChannelVoxTone);
+
+        /* Hamlib settings. */
+
+        wxGetApp().m_boolHamlibUseForPTT = m_ckUseHamlibPTT->GetValue();
+        wxGetApp().m_intHamlibRig = m_cbRigName->GetSelection();
+        wxGetApp().m_strHamlibSerialPort = m_cbSerialPort->GetValue();
+
+        wxString s = m_cbSerialRate->GetValue();
+        if (s == "default") {
+            wxGetApp().m_intHamlibSerialRate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            wxGetApp().m_intHamlibSerialRate = tmp;
+        }
+        fprintf(stderr, "serial rate: %d\n", wxGetApp().m_intHamlibSerialRate);
+
+        pConfig->Write(wxT("/Hamlib/UseForPTT"), wxGetApp().m_boolHamlibUseForPTT);
+        pConfig->Write(wxT("/Hamlib/RigName"), wxGetApp().m_intHamlibRig);
+        pConfig->Write(wxT("/Hamlib/SerialPort"), wxGetApp().m_strHamlibSerialPort);
+        pConfig->Write(wxT("/Hamlib/SerialRate"), wxGetApp().m_intHamlibSerialRate);
+
+        /* Serial settings */
+
+        wxGetApp().m_boolUseSerialPTT           = m_ckUseSerialPTT->IsChecked();
+#ifdef __WXMSW__
+        wxGetApp().m_strRigCtrlPort             = m_listCtrlPorts->GetStringSelection();
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+        wxGetApp().m_strRigCtrlPort             = m_cbCtlDevicePath->GetValue();
+#endif
+        wxGetApp().m_boolUseRTS                 = m_rbUseRTS->GetValue();
+        wxGetApp().m_boolRTSPos                 = m_ckRTSPos->IsChecked();
+        wxGetApp().m_boolUseDTR                 = m_rbUseDTR->GetValue();
+        wxGetApp().m_boolDTRPos                 = m_ckDTRPos->IsChecked();
+        
+        pConfig->Write(wxT("/Rig/UseSerialPTT"),    wxGetApp().m_boolUseSerialPTT);
+        pConfig->Write(wxT("/Rig/Port"),            wxGetApp().m_strRigCtrlPort); 
+        pConfig->Write(wxT("/Rig/UseRTS"),          wxGetApp().m_boolUseRTS);
+        pConfig->Write(wxT("/Rig/RTSPolarity"),     wxGetApp().m_boolRTSPos);
+        pConfig->Write(wxT("/Rig/UseDTR"),          wxGetApp().m_boolUseDTR);
+        pConfig->Write(wxT("/Rig/DTRPolarity"),     wxGetApp().m_boolDTRPos);
+
+        pConfig->Flush();
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+//-------------------------------------------------------------------------
+// PTTUseHamLibClicked()
+//-------------------------------------------------------------------------
+void ComPortsDlg::PTTUseHamLibClicked(wxCommandEvent& event)
+{
+    m_ckUseSerialPTT->SetValue(false);
+}
+
+
+/* Attempt to toggle PTT for 1 second */
+
+void ComPortsDlg::OnTest(wxCommandEvent& event) {
+
+    /* Tone PTT */
+
+    if (m_ckLeftChannelVoxTone->GetValue()) {
+        wxMessageBox("Testing of tone based PTT not supported; try PTT after pressing Start on main window", 
+                     wxT("Error"), wxOK | wxICON_ERROR, this);
+    }
+
+    /* Hamlib PTT */
+
+    if (m_ckUseHamlibPTT->GetValue()) {
+
+        // set up current hamlib config from GUI
+
+        int rig = m_cbRigName->GetSelection();
+        wxString port = m_cbSerialPort->GetValue();
+        wxString s = m_cbSerialRate->GetValue();
+        int serial_rate;
+        if (s == "default") {
+            serial_rate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            serial_rate = tmp;
+        }
+
+        // display serial params
+
+        fprintf(stderr, "serial rate: %d\n", serial_rate);
+
+        // try to open rig
+
+        Hamlib *hamlib = wxGetApp().m_hamlib; 
+        bool status = hamlib->connect(rig, port.mb_str(wxConvUTF8), serial_rate);
+        if (status == false) {
+            wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+        else {
+            wxString hamlib_serial_config;
+            hamlib_serial_config.sprintf(" %d, %d, %d", 
+                                         hamlib->get_serial_rate(),
+                                         hamlib->get_data_bits(),
+                                         hamlib->get_stop_bits());
+            m_cbSerialParams->SetLabel(hamlib_serial_config);
+       }
+
+        // toggle PTT
+
+        wxString hamlibError;
+        if (hamlib->ptt(true, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+
+        wxSleep(1);
+
+        if (hamlib->ptt(false, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+    }
+
+    /* Serial PTT */
+
+    if (m_ckUseSerialPTT->IsChecked()) {
+        Serialport *serialport = wxGetApp().m_serialport; 
+        
+        wxString ctrlport;
+#ifdef __WXMSW__
+        ctrlport = m_listCtrlPorts->GetStringSelection();
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+        ctrlport = m_cbCtlDevicePath->GetValue();
+#endif
+        fprintf(stderr, "opening serial port\n");
+
+        bool success = serialport->openport(ctrlport.c_str(),
+                                            m_rbUseRTS->GetValue(),
+                                            m_ckRTSPos->IsChecked(),
+                                            m_rbUseDTR->GetValue(),
+                                            m_ckDTRPos->IsChecked());
+
+        fprintf(stderr, "serial port open\n");
+
+        if (!success) {
+            wxMessageBox("Couldn't open serial port", wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+
+        // assert PTT port for 1 sec
+
+        serialport->ptt(true);
+        wxSleep(1);
+        serialport->ptt(false);
+
+        fprintf(stderr, "closing serial port\n");
+        serialport->closeport();
+        fprintf(stderr, "serial port closed\n");
+    }
+    
+}
+
+
+//-------------------------------------------------------------------------
+// PTTUseSerialClicked()
+//-------------------------------------------------------------------------
+void ComPortsDlg::PTTUseSerialClicked(wxCommandEvent& event)
+{
+    m_ckUseHamlibPTT->SetValue(false);
+}
+
+//-------------------------------------------------------------------------
+// OnApply()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnApply(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    this->EndModal(wxID_OK);
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/dlg_ptt.h b/freedv/branches/1.2/freedv-dev/src/dlg_ptt.h
new file mode 100644 (file)
index 0000000..5a35c3b
--- /dev/null
@@ -0,0 +1,95 @@
+//==========================================================================
+// Name:            dlg_ptt.h
+// Purpose:         Subclasses dialog GUI for PTT Config.
+//                  
+// Created:         May. 11, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __COMPORTS_DIALOG__
+#define __COMPORTS_DIALOG__
+
+#include "fdmdv2_main.h"
+#include "hamlib.h"
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/xrc/xh_bmp.h>
+#include <wx/dialog.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/listbox.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/spinctrl.h>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class ComPortsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class ComPortsDlg : public wxDialog
+{
+     public:
+        ComPortsDlg(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PTT Config"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(450,300), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
+        virtual ~ComPortsDlg();
+        void    ExchangeData(int inout);
+
+    protected:
+        wxCheckBox* m_ckLeftChannelVoxTone;
+
+        /* Hamlib settings.*/
+
+        wxCheckBox *m_ckUseHamlibPTT;
+        wxComboBox *m_cbRigName;
+        wxComboBox *m_cbSerialPort;
+        wxComboBox *m_cbSerialRate;
+        wxStaticText  *m_cbSerialParams;
+        Hamlib *m_hamlib;
+
+        /* Serial Settings */
+
+        wxListBox     *m_listCtrlPorts;
+        wxCheckBox    *m_ckUseSerialPTT;
+        wxStaticText  *m_staticText12;
+        wxComboBox    *m_cbCtlDevicePath;
+        wxRadioButton *m_rbUseDTR;
+        wxCheckBox    *m_ckRTSPos;
+        wxRadioButton *m_rbUseRTS;
+        wxCheckBox    *m_ckDTRPos;
+
+        /* Test - Ok - Cancel - Apply */
+
+        wxButton* m_buttonTest;
+        wxButton* m_buttonOK;
+        wxButton* m_buttonCancel;
+        wxButton* m_buttonApply;
+
+
+protected:
+        void populatePortList();
+
+        void PTTUseHamLibClicked(wxCommandEvent& event);
+        void PTTUseSerialClicked(wxCommandEvent& event);
+
+        void OnTest(wxCommandEvent& event);
+
+        void OnOK(wxCommandEvent& event);
+        void OnCancel(wxCommandEvent& event);
+        void OnApply(wxCommandEvent& event);
+        virtual void OnInitDialog(wxInitDialogEvent& event);
+    
+};
+
+#endif // __COMPORTS_DIALOG__
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_defines.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_defines.h
new file mode 100644 (file)
index 0000000..a687889
--- /dev/null
@@ -0,0 +1,106 @@
+//==========================================================================
+// Name:            fdmdv2_defines.h
+// Purpose:         Definitions used by plots derived from fdmdv2_plot class.
+// Created:         August 27, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_DEFINES__
+#define __FDMDV2_DEFINES__
+
+#include "wx/wx.h"
+#include "freedv_api.h"
+#include "modem_stats.h"
+
+// Spectrogram and Waterfall
+
+#define MIN_MAG_DB        -40.0     // min of spectrogram/waterfall magnitude axis
+#define MAX_MAG_DB          0.0     // max of spectrogram/waterfall magnitude axis
+#define STEP_MAG_DB         5.0     // magnitude axis step
+#define BETA                0.95    // constant for time averaging spectrum data
+#define MIN_F_HZ            0       // min freq on Waterfall and Spectrum
+#define MAX_F_HZ            3000    // max freq on Waterfall and Spectrum
+#define STEP_F_HZ           500     // major (e.g. text legend) freq step on Waterfall and Spectrum graticule
+#define STEP_MINOR_F_HZ     100     // minor (ticks) freq step on Waterfall and Spectrum graticule
+#define WATERFALL_SECS_Y    30      // number of seconds respresented by y axis of waterfall
+#define WATERFALL_SECS_STEP 5       // graticule y axis steps of waterfall
+#define DT                  0.1     // time between real time graphing updates
+#define FS                  8000    // FDMDV modem sample rate
+
+// Scatter diagram 
+
+#define SCATTER_MEM_SECS    10
+// (symbols/frame)/(graphics update period) = symbols/s sent to scatter memory
+// memory (symbols) = secs of memory * symbols/sec
+#define SCATTER_MEM_SYMS_MAX    ((int)(SCATTER_MEM_SECS*((MODEM_STATS_NC_MAX+1)/DT)))
+#define SCATTER_EYE_MEM_ROWS    ((int)(SCATTER_MEM_SECS/DT))
+
+// Waveform plotting constants
+
+#define WAVEFORM_PLOT_FS    400                            // sample rate (points/s) of waveform plotted to screen
+#define WAVEFORM_PLOT_TIME  5                              // length or entire waveform on screen
+#define WAVEFORM_PLOT_BUF   ((int)(DT*WAVEFORM_PLOT_FS))   // number of new samples we plot per DT
+
+// sample rate I/O & conversion constants
+
+#define MAX_FPB             8096                           // maximum value of portAudio framesPerBuffer
+#define PA_FPB              1024                           // nominal value of portAudio framesPerBuffer
+#define SAMPLE_RATE         48000                          // 48 kHz sampling rate rec. as we can trust accuracy of sound card
+#define N8                  160                            // processing buffer size at 8 kHz
+#define MEM8                (FDMDV_OS_TAPS/FDMDV_OS)
+#define N48                 (N8*SAMPLE_RATE/FS)            // processing buffer size at 48 kHz
+#define NUM_CHANNELS        2                              // I think most sound cards prefer stereo we will convert to mono
+#define VOX_TONE_FREQ       1000.0                         // optional left channel vox tone freq
+#define VOX_TONE_AMP        30000                          // optional left channel vox tone amp
+
+#define MAX_BITS_PER_CODEC_FRAME 64                            // 1600 bit/s mode
+#define MAX_BYTES_PER_CODEC_FRAME (MAX_BITS_PER_CODEC_FRAME/8)
+#define MAX_BITS_PER_FDMDV_FRAME 40                            // 2000 bit/s mode
+
+// Squelch
+#define SQ_DEFAULT_SNR       2.0
+
+// Level Gauge
+#define FROM_RADIO_MAX       0.8
+#define FROM_MIC_MAX         0.8
+#define LEVEL_BETA           0.99
+
+// SNR
+#define SNRSLOW_BETA        0.5                           // time constant for slow SNR for display
+
+// Text messaging Data
+#define MAX_CALLSIGN         80
+#define MAX_EVENT_LOG        10
+#define MAX_EVENT_RULES      100
+   
+enum
+{
+    ID_ROTATE_LEFT = wxID_HIGHEST + 1,
+    ID_ROTATE_RIGHT,
+    ID_RESIZE,
+    ID_PAINT_BG
+};
+
+// Codec 2 LPC Post Filter defaults, from codec-dev/src/quantise.c
+
+#define CODEC2_LPC_PF_GAMMA 0.5
+#define CODEC2_LPC_PF_BETA  0.2
+
+// PlugIns ...
+
+#define PLUGIN_MAX_PARAMS 4
+
+#endif  //__FDMDV2_DEFINES__
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_main.cpp b/freedv/branches/1.2/freedv-dev/src/fdmdv2_main.cpp
new file mode 100644 (file)
index 0000000..506406c
--- /dev/null
@@ -0,0 +1,4042 @@
+//==========================================================================
+// Name:            fdmdv2_main.cpp
+//
+// Purpose:         FreeDV main()
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "fdmdv2_main.h"
+
+#define wxUSE_FILEDLG   1
+#define wxUSE_LIBPNG    1
+#define wxUSE_LIBJPEG   1
+#define wxUSE_GIF       1
+#define wxUSE_PCX       1
+#define wxUSE_LIBTIFF   1
+
+//-------------------------------------------------------------------
+// Bunch of globals used for communication with sound card call
+// back functions
+// ------------------------------------------------------------------
+
+int g_in, g_out;
+
+// Global Codec2 & modem states - just one reqd for tx & rx
+int                 g_Nc;
+int                 g_mode;
+struct freedv      *g_pfreedv;
+struct MODEM_STATS  g_stats;
+float               g_pwr_scale;
+int                 g_clip;
+
+// test Frames
+int                 g_testFrames;
+int                 g_test_frame_sync_state;
+int                 g_test_frame_count;
+int                 g_channel_noise;
+int                 g_resyncs;
+float               g_sig_pwr_av = 0.0;
+struct FIFO        *g_error_pattern_fifo;
+short              *g_error_hist, *g_error_histn;
+float               g_tone_phase;
+
+// time averaged magnitude spectrum used for waterfall and spectrum display
+float               g_avmag[MODEM_STATS_NSPEC];
+
+// GUI controls that affect rx and tx processes
+int   g_SquelchActive;
+float g_SquelchLevel;
+int   g_analog;
+int   g_split;
+int   g_tx;
+float g_snr;
+bool  g_half_duplex;
+bool  g_modal;
+
+// sending and receiving Call Sign data
+struct FIFO         *g_txDataInFifo;
+struct FIFO         *g_rxDataOutFifo;
+
+// tx/rx processing states
+int                 g_State, g_prev_State;
+paCallBackData     *g_rxUserdata;
+
+// FIFOs used for plotting waveforms
+struct FIFO        *g_plotDemodInFifo;
+struct FIFO        *g_plotSpeechOutFifo;
+struct FIFO        *g_plotSpeechInFifo;
+
+// Soundcard config
+int                 g_nSoundCards;
+int                 g_soundCard1InDeviceNum;
+int                 g_soundCard1OutDeviceNum;
+int                 g_soundCard1SampleRate;
+int                 g_soundCard2InDeviceNum;
+int                 g_soundCard2OutDeviceNum;
+int                 g_soundCard2SampleRate;
+
+// playing and recording from sound files
+
+SNDFILE            *g_sfPlayFile;
+bool                g_playFileToMicIn;
+bool                g_loopPlayFileToMicIn;
+int                 g_playFileToMicInEventId;
+
+SNDFILE            *g_sfRecFile;
+bool                g_recFileFromRadio;
+unsigned int        g_recFromRadioSamples;
+int                 g_recFileFromRadioEventId;
+
+SNDFILE            *g_sfPlayFileFromRadio;
+bool                g_playFileFromRadio;
+int                 g_sfFs;
+bool                g_loopPlayFileFromRadio;
+int                 g_playFileFromRadioEventId;
+float               g_blink;
+
+wxWindow           *g_parent;
+
+// Click to tune rx and tx frequency offset states
+float               g_RxFreqOffsetHz;
+COMP                g_RxFreqOffsetPhaseRect;
+float               g_TxFreqOffsetHz;
+COMP                g_TxFreqOffsetPhaseRect;
+
+// experimental mutex to make sound card callbacks mutually exclusive
+// TODO: review code and see if we need this any more, as fifos should
+// now be thread safe
+
+wxMutex g_mutexProtectingCallbackData;
+
+// Speex pre-processor states
+
+SpeexPreprocessState *g_speex_st;
+
+// WxWidgets - initialize the application
+IMPLEMENT_APP(MainApp);
+
+//FILE *ftest;
+FILE *g_logfile;
+
+//-------------------------------------------------------------------------
+// OnInit()
+//-------------------------------------------------------------------------
+bool MainApp::OnInit()
+{
+    if(!wxApp::OnInit())
+    {
+        return false;
+    }
+    SetVendorName(wxT("CODEC2-Project"));
+    SetAppName(wxT("FreeDV"));      // not needed, it's the default value
+
+#ifdef FILE_RATHER_THAN_REGISTRY
+    // Force use of file-based configuration persistance on Windows platforma
+    wxConfig *pConfig = new wxConfig();
+    wxFileConfig *pFConfig = new wxFileConfig(wxT("FreeDV"), wxT("CODEC2-Project"), wxT("FreeDV.conf"), wxT("FreeDV.conf"),  wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
+    pConfig->Set(pFConfig);
+    pConfig->SetRecordDefaults();
+#else
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    pConfig->SetRecordDefaults();
+#endif
+
+    m_rTopWindow = wxRect(0, 0, 0, 0);
+    m_strRxInAudio.Empty();
+    m_strRxOutAudio.Empty();
+    m_textVoiceInput.Empty();
+    m_textVoiceOutput.Empty();
+    m_strSampleRate.Empty();
+    m_strBitrate.Empty();
+
+    // Look for Plug In
+
+    m_plugIn = false;
+    #ifdef __WXMSW__
+    wchar_t dll_path[] = L"afreedvplugin.dll";
+    m_plugInHandle = LoadLibrary(dll_path);
+    #else
+    m_plugInHandle = dlopen("afreedvplugin.so", RTLD_LAZY);
+    #endif
+    
+    if (m_plugInHandle) {
+        printf("plugin: .so found\n");
+        
+        // lets get some information abt the plugIn
+
+        void (*plugin_namefp)(char s[]);
+        void *(*plugin_openfp)(char *param_names[], int *nparams, int (*aplugin_get_persistant)(char *, char *));
+
+        #ifdef __WXMSW__
+        plugin_namefp = (void (*)(char*))GetProcAddress((HMODULE)m_plugInHandle, "plugin_name");
+        plugin_openfp = (void* (*)(char**,int *, int (*)(char *, char *)))GetProcAddress((HMODULE)m_plugInHandle, "plugin_open");
+        m_plugin_startfp = (void (*)(void *))GetProcAddress((HMODULE)m_plugInHandle, "plugin_start");
+        m_plugin_stopfp = (void (*)(void *))GetProcAddress((HMODULE)m_plugInHandle, "plugin_stop");
+        m_plugin_rx_samplesfp = (void (*)(void *, short *, int))GetProcAddress((HMODULE)m_plugInHandle, "plugin_rx_samples");
+        #else
+        plugin_namefp = (void (*)(char*))dlsym(m_plugInHandle, "plugin_name");
+        plugin_openfp = (void* (*)(char**,int *, int (*)(char *, char *)))dlsym(m_plugInHandle, "plugin_open");
+        m_plugin_startfp = (void (*)(void *))dlsym(m_plugInHandle, "plugin_start");
+        m_plugin_stopfp = (void (*)(void *))dlsym(m_plugInHandle, "plugin_stop");
+        m_plugin_rx_samplesfp = (void (*)(void *, short *, int))dlsym(m_plugInHandle, "plugin_rx_samples");
+        #endif
+        
+        if ((plugin_namefp != NULL) && (plugin_openfp != NULL)) {
+
+            char s[256];
+            m_plugIn = true;
+            (plugin_namefp)(s);
+            fprintf(stderr, "plugin name: %s\n", s);
+            m_plugInName = s;
+
+            char param_name1[80], param_name2[80];
+            char *param_names[2] = {param_name1, param_name2};
+            int  nparams, i;
+            m_plugInStates = (plugin_openfp)(param_names, &nparams, plugin_get_persistant);
+            m_numPlugInParam = nparams;
+            for(i=0; i<nparams; i++) {
+                m_plugInParamName[i] = param_names[i];
+                wxString configStr = "/" + m_plugInName + "/" + m_plugInParamName[i];
+                m_txtPlugInParam[i] = pConfig->Read(configStr, wxT(""));
+                //fprintf(stderr, "  plugin param name[%d]: %s\n", i, param_names[i]);
+                fprintf(stderr, "  plugin param name[%d]: %s values: %s\n", i, m_plugInParamName[i].mb_str().data(), m_txtPlugInParam[i].mb_str().data());
+            }
+        }
+        
+        else {
+            fprintf(stderr, "plugin: fps not found...\n");           
+        }
+    }
+    else {
+        fprintf(stderr, "plugin not found...\n");           
+    }
+
+    // Create the main application window
+
+    frame = new MainFrame(m_plugInName, NULL);
+    SetTopWindow(frame);
+
+    // Should guarantee that the first plot tab defined is the one
+    // displayed. But it doesn't when built from command line.  Why?
+
+    frame->m_auiNbookCtrl->ChangeSelection(0);
+    frame->Layout();
+    frame->Show();
+    g_parent =frame;
+
+
+    return true;
+}
+
+//-------------------------------------------------------------------------
+// OnExit()
+//-------------------------------------------------------------------------
+int MainApp::OnExit()
+{
+    fprintf(stderr, "MainApp::OnExit\n");
+    if (m_plugIn) {
+        #ifdef __WXMSW__
+        FreeLibrary((HMODULE)m_plugInHandle);
+        #else
+        dlclose(m_plugInHandle);
+        #endif
+    }
+
+    return 0;
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainFrame(wxFrame* pa->ent) : TopFrame(parent)
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInName, parent)
+{
+    m_zoom              = 1.;
+
+    #ifdef __WXMSW__
+    g_logfile = stderr;
+    #else
+    g_logfile = stderr;
+    #endif
+
+
+    SetMinSize(wxSize(400,400));
+
+    // Init Hamlib library, but we dont start talking to any rigs yet
+
+    wxGetApp().m_hamlib = new Hamlib();
+
+    // Init Serialport library, but as for Hamlib we dont start talking to any rigs yet
+
+    wxGetApp().m_serialport = new Serialport();
+
+    tools->AppendSeparator();
+    wxMenuItem* m_menuItemToolsConfigDelete;
+    m_menuItemToolsConfigDelete = new wxMenuItem(tools, wxID_ANY, wxString(_("&Restore defaults")) , wxT("Delete config file/keys and restore defaults"), wxITEM_NORMAL);
+    this->Connect(m_menuItemToolsConfigDelete->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnDeleteConfig));
+
+    tools->Append(m_menuItemToolsConfigDelete);
+
+    wxConfigBase *pConfig = wxConfigBase::Get();
+
+    // restore frame position and size
+    int x = pConfig->Read(wxT("/MainFrame/left"),       20);
+    int y = pConfig->Read(wxT("/MainFrame/top"),        20);
+    int w = pConfig->Read(wxT("/MainFrame/width"),     800);
+    int h = pConfig->Read(wxT("/MainFrame/height"),    550);
+
+    // sanitise frame position as a first pass at Win32 registry bug
+
+    fprintf(g_logfile, "x = %d y = %d w = %d h = %d\n", x,y,w,h);
+    if (x < 0 || x > 2048) x = 20;
+    if (y < 0 || y > 2048) y = 20;
+    if (w < 0 || w > 2048) w = 800;
+    if (h < 0 || h > 2048) h = 550;
+
+    wxGetApp().m_show_wf            = pConfig->Read(wxT("/MainFrame/show_wf"),           1);
+    wxGetApp().m_show_spect         = pConfig->Read(wxT("/MainFrame/show_spect"),        1);
+    wxGetApp().m_show_scatter       = pConfig->Read(wxT("/MainFrame/show_scatter"),      1);
+    wxGetApp().m_show_timing        = pConfig->Read(wxT("/MainFrame/show_timing"),       1);
+    wxGetApp().m_show_freq          = pConfig->Read(wxT("/MainFrame/show_freq"),         1);
+    wxGetApp().m_show_speech_in     = pConfig->Read(wxT("/MainFrame/show_speech_in"),    1);
+    wxGetApp().m_show_speech_out    = pConfig->Read(wxT("/MainFrame/show_speech_out"),   1);
+    wxGetApp().m_show_demod_in      = pConfig->Read(wxT("/MainFrame/show_demod_in"),     1);
+    wxGetApp().m_show_test_frame_errors = pConfig->Read(wxT("/MainFrame/show_test_frame_errors"),     1);
+    wxGetApp().m_show_test_frame_errors_hist = pConfig->Read(wxT("/MainFrame/show_test_frame_errors_hist"),     1);
+
+    wxGetApp().m_rxNbookCtrl        = pConfig->Read(wxT("/MainFrame/rxNbookCtrl"),    (long)0);
+
+    g_SquelchActive = pConfig->Read(wxT("/Audio/SquelchActive"), (long)0);
+    g_SquelchLevel = pConfig->Read(wxT("/Audio/SquelchLevel"), (int)(SQ_DEFAULT_SNR*2));
+    g_SquelchLevel /= 2.0;
+
+    Move(x, y);
+    SetClientSize(w, h);
+    
+    if(wxGetApp().m_show_wf)
+    {
+        // Add Waterfall Plot window
+        m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl, false, 0);
+        m_panelWaterfall->SetToolTip(_("Left click to tune, Right click to toggle mono/colour"));
+        m_auiNbookCtrl->AddPage(m_panelWaterfall, _("Waterfall"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_spect)
+    {
+        // Add Spectrum Plot window
+        m_panelSpectrum = new PlotSpectrum((wxFrame*) m_auiNbookCtrl, g_avmag,
+                                           MODEM_STATS_NSPEC*((float)MAX_F_HZ/MODEM_STATS_MAX_F_HZ));
+        m_panelSpectrum->SetToolTip(_("Left click to tune"));
+        m_auiNbookCtrl->AddPage(m_panelSpectrum, _("Spectrum"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_scatter)
+    {
+        // Add Scatter Plot window
+        m_panelScatter = new PlotScatter((wxFrame*) m_auiNbookCtrl);
+        m_auiNbookCtrl->AddPage(m_panelScatter, _("Scatter"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_demod_in)
+    {
+        // Add Demod Input window
+        m_panelDemodIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelDemodIn, _("Frm Radio"), true, wxNullBitmap);
+        g_plotDemodInFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_speech_in)
+    {
+        // Add Speech Input window
+        m_panelSpeechIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelSpeechIn, _("Frm Mic"), true, wxNullBitmap);
+        g_plotSpeechInFifo = fifo_create(4*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_speech_out)
+    {
+        // Add Speech Output window
+        m_panelSpeechOut = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelSpeechOut, _("To Spkr/Hdphns"), true, wxNullBitmap);
+        g_plotSpeechOutFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_timing)
+    {
+        // Add Timing Offset window
+        m_panelTimeOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 5.0, DT, -0.5, 0.5, 1, 0.1, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelTimeOffset, L"Timing \u0394", true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_freq)
+    {
+        // Add Frequency Offset window
+        m_panelFreqOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 5.0, DT, -200, 200, 1, 50, "%3.0fHz", 0);
+        m_auiNbookCtrl->AddPage(m_panelFreqOffset, L"Frequency \u0394", true, wxNullBitmap);
+    }
+
+    if(wxGetApp().m_show_test_frame_errors)
+    {
+        // Add Test Frame Errors window
+        m_panelTestFrameErrors = new PlotScalar((wxFrame*) m_auiNbookCtrl, 2*MODEM_STATS_NC_MAX, 30.0, DT, 0, 2*MODEM_STATS_NC_MAX+2, 1, 1, "", 1);
+        m_auiNbookCtrl->AddPage(m_panelTestFrameErrors, L"Test Frame Errors", true, wxNullBitmap);
+    }
+
+    if(wxGetApp().m_show_test_frame_errors_hist)
+    {
+        // Add Test Frame Historgram window.  1 column for every bit, 2 bits per carrier
+        m_panelTestFrameErrorsHist = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 1.0, 1.0/(2*FDMDV_NC_MAX), 0.001, 0.1, 1.0/FDMDV_NC_MAX, 0.1, "%0.0E", 0);
+        m_auiNbookCtrl->AddPage(m_panelTestFrameErrorsHist, L"Test Frame Histogram", true, wxNullBitmap);
+        m_panelTestFrameErrorsHist->setBarGraph(1);
+        m_panelTestFrameErrorsHist->setLogY(1);
+    }
+
+    wxGetApp().m_framesPerBuffer = pConfig->Read(wxT("/Audio/framesPerBuffer"), PA_FPB);
+
+    g_soundCard1InDeviceNum  = pConfig->Read(wxT("/Audio/soundCard1InDeviceNum"),         -1);
+    g_soundCard1OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard1OutDeviceNum"),        -1);
+    g_soundCard1SampleRate   = pConfig->Read(wxT("/Audio/soundCard1SampleRate"),          -1);
+
+    g_soundCard2InDeviceNum  = pConfig->Read(wxT("/Audio/soundCard2InDeviceNum"),         -1);
+    g_soundCard2OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard2OutDeviceNum"),        -1);
+    g_soundCard2SampleRate   = pConfig->Read(wxT("/Audio/soundCard2SampleRate"),          -1);
+
+    g_nSoundCards = 0;
+    if ((g_soundCard1InDeviceNum > -1) && (g_soundCard1OutDeviceNum > -1)) {
+        g_nSoundCards = 1;
+        if ((g_soundCard2InDeviceNum > -1) && (g_soundCard2OutDeviceNum > -1))
+            g_nSoundCards = 2;
+    }
+
+    wxGetApp().m_playFileToMicInPath = pConfig->Read("/File/playFileToMicInPath",   wxT(""));
+    wxGetApp().m_recFileFromRadioPath = pConfig->Read("/File/recFileFromRadioPath", wxT(""));
+    wxGetApp().m_recFileFromRadioSecs = pConfig->Read("/File/recFileFromRadioSecs", 30);
+    wxGetApp().m_playFileFromRadioPath = pConfig->Read("/File/playFileFromRadioPath", wxT(""));
+
+    // PTT -------------------------------------------------------------------
+
+    wxGetApp().m_boolHalfDuplex     = pConfig->ReadBool(wxT("/Rig/HalfDuplex"),     true);
+    wxGetApp().m_leftChannelVoxTone = pConfig->ReadBool("/Rig/leftChannelVoxTone",  false);
+    wxGetApp().m_txtVoiceKeyerWaveFilePath = pConfig->Read(wxT("/VoiceKeyer/WaveFilePath"), wxT(""));
+    wxGetApp().m_txtVoiceKeyerWaveFile = pConfig->Read(wxT("/VoiceKeyer/WaveFile"), wxT("voicekeyer.wav"));
+    wxGetApp().m_intVoiceKeyerRxPause = pConfig->Read(wxT("/VoiceKeyer/RxPause"), 10);
+    wxGetApp().m_intVoiceKeyerRepeats = pConfig->Read(wxT("/VoiceKeyer/Repeats"), 5);
+    wxGetApp().m_boolHamlibUseForPTT = pConfig->ReadBool("/Hamlib/UseForPTT", false);
+    wxGetApp().m_intHamlibRig = pConfig->ReadLong("/Hamlib/RigName", 0);
+    wxGetApp().m_strHamlibSerialPort = pConfig->Read("/Hamlib/SerialPort", "");
+    wxGetApp().m_intHamlibSerialRate = pConfig->ReadLong("/Hamlib/SerialRate", 0);
+    
+    wxGetApp().m_boolUseSerialPTT   = pConfig->ReadBool(wxT("/Rig/UseSerialPTT"),   false);
+    wxGetApp().m_strRigCtrlPort     = pConfig->Read(wxT("/Rig/Port"),               wxT(""));
+    wxGetApp().m_boolUseRTS         = pConfig->ReadBool(wxT("/Rig/UseRTS"),         true);
+    wxGetApp().m_boolRTSPos         = pConfig->ReadBool(wxT("/Rig/RTSPolarity"),    true);
+    wxGetApp().m_boolUseDTR         = pConfig->ReadBool(wxT("/Rig/UseDTR"),         false);
+    wxGetApp().m_boolDTRPos         = pConfig->ReadBool(wxT("/Rig/DTRPolarity"),    false);
+
+    assert(wxGetApp().m_serialport != NULL);
+
+    // -----------------------------------------------------------------------
+
+    bool slow = false; // prevents compile error when using default bool
+    wxGetApp().m_snrSlow = pConfig->Read("/Audio/snrSlow", slow);
+
+    bool t = true;     // prevents compile error when using default bool
+    wxGetApp().m_codec2LPCPostFilterEnable     = pConfig->Read(wxT("/Filter/codec2LPCPostFilterEnable"),    t);
+    wxGetApp().m_codec2LPCPostFilterBassBoost  = pConfig->Read(wxT("/Filter/codec2LPCPostFilterBassBoost"), t);
+    wxGetApp().m_codec2LPCPostFilterGamma      = (float)pConfig->Read(wxT("/Filter/codec2LPCPostFilterGamma"),     CODEC2_LPC_PF_GAMMA*100)/100.0;
+    wxGetApp().m_codec2LPCPostFilterBeta       = (float)pConfig->Read(wxT("/Filter/codec2LPCPostFilterBeta"),      CODEC2_LPC_PF_BETA*100)/100.0;
+    //printf("main(): m_codec2LPCPostFilterBeta: %f\n", wxGetApp().m_codec2LPCPostFilterBeta);
+
+    wxGetApp().m_speexpp_enable     = pConfig->Read(wxT("/Filter/speexpp_enable"),    t);
+
+    wxGetApp().m_MicInBassFreqHz = (float)pConfig->Read(wxT("/Filter/MicInBassFreqHz"),    1);
+    wxGetApp().m_MicInBassGaindB = (float)pConfig->Read(wxT("/Filter/MicInBassGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInTrebleFreqHz = (float)pConfig->Read(wxT("/Filter/MicInTrebleFreqHz"),    1);
+    wxGetApp().m_MicInTrebleGaindB = (float)pConfig->Read(wxT("/Filter/MicInTrebleGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInMidFreqHz = (float)pConfig->Read(wxT("/Filter/MicInMidFreqHz"),    1);
+    wxGetApp().m_MicInMidGaindB = (float)pConfig->Read(wxT("/Filter/MicInMidGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInMidQ = (float)pConfig->Read(wxT("/Filter/MicInMidQ"),              (long)100)/100.0;
+
+    bool f = false;
+    wxGetApp().m_MicInEQEnable = (float)pConfig->Read(wxT("/Filter/MicInEQEnable"), f);
+
+    wxGetApp().m_SpkOutBassFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutBassFreqHz"),    1);
+    wxGetApp().m_SpkOutBassGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutBassGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutTrebleFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutTrebleFreqHz"),    1);
+    wxGetApp().m_SpkOutTrebleGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutTrebleGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutMidFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutMidFreqHz"),    1);
+    wxGetApp().m_SpkOutMidGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutMidGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutMidQ = (float)pConfig->Read(wxT("/Filter/SpkOutMidQ"),                (long)100)/100.0;
+
+    wxGetApp().m_SpkOutEQEnable = (float)pConfig->Read(wxT("/Filter/SpkOutEQEnable"), f);
+
+    wxGetApp().m_callSign = pConfig->Read("/Data/CallSign", wxT(""));
+    wxGetApp().m_textEncoding = pConfig->Read("/Data/TextEncoding", 1);
+    wxGetApp().m_enable_checksum = pConfig->Read("/Data/EnableChecksumOnMsgRx", f);
+
+    wxGetApp().m_events = pConfig->Read("/Events/enable", f);
+    wxGetApp().m_events_spam_timer = (int)pConfig->Read(wxT("/Events/spam_timer"), 10);
+    wxGetApp().m_events_regexp_match = pConfig->Read("/Events/regexp_match", wxT("s=(.*)"));
+    wxGetApp().m_events_regexp_replace = pConfig->Read("/Events/regexp_replace", 
+                                                       wxT("curl http://qso.freedv.org/cgi-bin/onspot.cgi?s=\\1"));
+    // make sure regexp lists are terminated by a \n
+
+    if (wxGetApp().m_events_regexp_match.Last() != '\n') {
+        wxGetApp().m_events_regexp_match = wxGetApp().m_events_regexp_match+'\n';
+    }
+    if (wxGetApp().m_events_regexp_replace.Last() != '\n') {
+        wxGetApp().m_events_regexp_replace = wxGetApp().m_events_regexp_replace+'\n';
+    }
+
+    wxGetApp().m_udp_enable = (float)pConfig->Read(wxT("/UDP/enable"), f);
+    wxGetApp().m_udp_port = (int)pConfig->Read(wxT("/UDP/port"), 3000);
+
+    wxGetApp().m_FreeDV700txClip = (float)pConfig->Read(wxT("/FreeDV700/txClip"), t);
+    wxGetApp().m_FreeDV700Combine = 1;
+    wxGetApp().m_noise_snr = (float)pConfig->Read(wxT("/Noise/noise_snr"), 2);
+    wxGetApp().m_debug_console = (float)pConfig->Read(wxT("/Debug/console"), f);
+
+    wxGetApp().m_attn_carrier_en = 0;
+    wxGetApp().m_attn_carrier    = 0;
+
+    wxGetApp().m_tone = 0;
+    wxGetApp().m_tone_freq_hz = 1000;
+    wxGetApp().m_tone_amplitude = 500;
+
+    int mode  = pConfig->Read(wxT("/Audio/mode"), (long)0);
+    if (mode == 0)
+        m_rb1600->SetValue(1);
+    //if (mode == 2)
+    //    m_rb700b->SetValue(1);
+    if (mode == 3)
+        m_rb700c->SetValue(1);
+    if (mode == 4)
+        m_rb800xa->SetValue(1);
+        
+    pConfig->SetPath(wxT("/"));
+
+//    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    //m_togRxID->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnRxIDUI), NULL, this);
+    //m_togTxID->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnTxIDUI), NULL, this);
+    m_togBtnOnOff->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnOnOffUI), NULL, this);
+    m_togBtnSplit->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnSplitClickUI), NULL, this);
+    m_togBtnAnalog->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnAnalogClickUI), NULL, this);
+    //m_togBtnALC->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnALCClickUI), NULL, this);
+   // m_btnTogPTT->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnPTT_UI), NULL, this);
+
+    m_togBtnSplit->Disable();
+    //m_togRxID->Disable();
+    //m_togTxID->Disable();
+    m_togBtnAnalog->Disable();
+    m_btnTogPTT->Disable();
+    m_togBtnVoiceKeyer->Disable();
+    //m_togBtnALC->Disable();
+
+    // squelch settings
+    char sqsnr[15];
+    m_sliderSQ->SetValue((int)((g_SquelchLevel+5.0)*2.0));
+    sprintf(sqsnr, "%4.1f", g_SquelchLevel);
+    wxString sqsnr_string(sqsnr);
+    m_textSQ->SetLabel(sqsnr_string);
+    m_ckboxSQ->SetValue(g_SquelchActive);
+
+    // SNR settings
+
+    m_ckboxSNR->SetValue(wxGetApp().m_snrSlow);
+    setsnrBeta(wxGetApp().m_snrSlow);
+
+#ifdef _USE_TIMER
+    Bind(wxEVT_TIMER, &MainFrame::OnTimer, this);       // ID_MY_WINDOW);
+    m_plotTimer.SetOwner(this, ID_TIMER_WATERFALL);
+    //m_panelWaterfall->Refresh();
+#endif
+
+    m_RxRunning = false;
+
+#ifdef _USE_ONIDLE
+    Connect(wxEVT_IDLE, wxIdleEventHandler(MainFrame::OnIdle), NULL, this);
+#endif //_USE_ONIDLE
+
+    g_sfPlayFile = NULL;
+    g_playFileToMicIn = false;
+    g_loopPlayFileToMicIn = false;
+
+    g_sfRecFile = NULL;
+    g_recFileFromRadio = false;
+
+    g_sfPlayFileFromRadio = NULL;
+    g_playFileFromRadio = false;
+    g_loopPlayFileFromRadio = false;
+
+    // init click-tune states
+
+    g_RxFreqOffsetHz = 0.0;
+    g_RxFreqOffsetPhaseRect.real = cos(0.0);
+    g_RxFreqOffsetPhaseRect.imag = sin(0.0);
+    m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+    m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+
+    g_TxFreqOffsetHz = 0.0;
+    g_TxFreqOffsetPhaseRect.real = cos(0.0);
+    g_TxFreqOffsetPhaseRect.imag = sin(0.0);
+
+    g_tx = 0;
+    g_split = 0;
+
+    // data states
+    g_txDataInFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
+    g_rxDataOutFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
+
+    sox_biquad_start();
+
+    g_testFrames = 0;
+    g_test_frame_sync_state = 0;
+    g_resyncs = 0;
+    wxGetApp().m_testFrames = false;
+    g_tone_phase = 0.0;
+
+    g_modal = false;
+
+#ifdef __EXPERIMENTAL_UDP__
+    // Start UDP listener thread
+
+    m_UDPThread = NULL;
+    startUDPThread();
+#endif
+
+    optionsDlg = new OptionsDlg(NULL);
+    m_schedule_restore = false;
+
+    vk_state = VK_IDLE;
+
+    // Init optional Windows debug console so we can see all those printfs
+
+#ifdef __WXMSW__
+    if (wxGetApp().m_debug_console) {
+        // somewhere to send printfs while developing
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    }
+#endif
+
+    //ftest = fopen("ftest.raw", "wb");
+    //assert(ftest != NULL);
+}
+
+//-------------------------------------------------------------------------
+// ~MainFrame()
+//-------------------------------------------------------------------------
+MainFrame::~MainFrame()
+{
+    int x;
+    int y;
+    int w;
+    int h;
+
+    fprintf(stderr, "MainFrame::~MainFrame()\n");
+    //fclose(ftest);
+    #ifdef __WXMSW__
+    fclose(g_logfile);
+    #endif
+
+    if (optionsDlg != NULL) {
+        delete optionsDlg;
+        optionsDlg = NULL;
+    }
+
+#ifdef __EXPERIMENTAL_UDP__
+    stopUDPThread();
+#endif
+
+    if (wxGetApp().m_hamlib) delete wxGetApp().m_hamlib;
+    if (wxGetApp().m_serialport) delete wxGetApp().m_serialport;
+
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(pConfig)
+    {
+        if (!IsIconized()) {
+            GetClientSize(&w, &h);
+            GetPosition(&x, &y);
+            printf("x = %d y = %d w = %d h = %d\n", x,y,w,h);
+            pConfig->Write(wxT("/MainFrame/left"),               (long) x);
+            pConfig->Write(wxT("/MainFrame/top"),                (long) y);
+            pConfig->Write(wxT("/MainFrame/width"),              (long) w);
+            pConfig->Write(wxT("/MainFrame/height"),             (long) h);
+        }
+        pConfig->Write(wxT("/MainFrame/show_wf"),           wxGetApp().m_show_wf);
+        pConfig->Write(wxT("/MainFrame/show_spect"),        wxGetApp().m_show_spect);
+        pConfig->Write(wxT("/MainFrame/show_scatter"),      wxGetApp().m_show_scatter);
+        pConfig->Write(wxT("/MainFrame/show_timing"),       wxGetApp().m_show_timing);
+        pConfig->Write(wxT("/MainFrame/show_freq"),         wxGetApp().m_show_freq);
+        pConfig->Write(wxT("/MainFrame/show_speech_in"),    wxGetApp().m_show_speech_in);
+        pConfig->Write(wxT("/MainFrame/show_speech_out"),   wxGetApp().m_show_speech_out);
+        pConfig->Write(wxT("/MainFrame/show_demod_in"),     wxGetApp().m_show_demod_in);
+        pConfig->Write(wxT("/MainFrame/show_test_frame_errors"), wxGetApp().m_show_test_frame_errors);
+        pConfig->Write(wxT("/MainFrame/show_test_frame_errors_hist"), wxGetApp().m_show_test_frame_errors_hist);
+
+        pConfig->Write(wxT("/MainFrame/rxNbookCtrl"), wxGetApp().m_rxNbookCtrl);
+
+        pConfig->Write(wxT("/Audio/SquelchActive"),         g_SquelchActive);
+        pConfig->Write(wxT("/Audio/SquelchLevel"),          (int)(g_SquelchLevel*2.0));
+
+        pConfig->Write(wxT("/Audio/framesPerBuffer"),       wxGetApp().m_framesPerBuffer);
+
+        pConfig->Write(wxT("/Audio/soundCard1InDeviceNum"),   g_soundCard1InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1OutDeviceNum"),  g_soundCard1OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1SampleRate"),    g_soundCard1SampleRate );
+
+        pConfig->Write(wxT("/Audio/soundCard2InDeviceNum"),   g_soundCard2InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2OutDeviceNum"),  g_soundCard2OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2SampleRate"),    g_soundCard2SampleRate );
+
+        pConfig->Write(wxT("/VoiceKeyer/WaveFilePath"), wxGetApp().m_txtVoiceKeyerWaveFilePath);
+        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
+        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
+        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
+
+        pConfig->Write(wxT("/Rig/HalfDuplex"),              wxGetApp().m_boolHalfDuplex);
+        pConfig->Write(wxT("/Rig/leftChannelVoxTone"),      wxGetApp().m_leftChannelVoxTone);
+        pConfig->Write("/Hamlib/UseForPTT", wxGetApp().m_boolHamlibUseForPTT);
+        pConfig->Write("/Hamlib/RigName", wxGetApp().m_intHamlibRig);
+        pConfig->Write("/Hamlib/SerialPort", wxGetApp().m_strHamlibSerialPort);
+        pConfig->Write("/Hamlib/SerialRate", wxGetApp().m_intHamlibSerialRate);
+
+
+        pConfig->Write(wxT("/File/playFileToMicInPath"),    wxGetApp().m_playFileToMicInPath);
+        pConfig->Write(wxT("/File/recFileFromRadioPath"),   wxGetApp().m_recFileFromRadioPath);
+        pConfig->Write(wxT("/File/recFileFromRadioSecs"),   wxGetApp().m_recFileFromRadioSecs);
+        pConfig->Write(wxT("/File/playFileFromRadioPath"),  wxGetApp().m_playFileFromRadioPath);
+
+        pConfig->Write(wxT("/Audio/snrSlow"), wxGetApp().m_snrSlow);
+
+        pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
+        pConfig->Write(wxT("/Data/TextEncoding"), wxGetApp().m_textEncoding);
+        pConfig->Write(wxT("/Data/EnableChecksumOnMsgRx"), wxGetApp().m_enable_checksum);
+        pConfig->Write(wxT("/Events/enable"), wxGetApp().m_events);
+        pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+        pConfig->Write(wxT("/Events/regexp_match"), wxGetApp().m_events_regexp_match);
+        pConfig->Write(wxT("/Events/regexp_replace"), wxGetApp().m_events_regexp_replace);
+        pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
+        pConfig->Write(wxT("/UDP/port"),  wxGetApp().m_udp_port);
+
+        pConfig->Write(wxT("/Filter/MicInEQEnable"), wxGetApp().m_MicInEQEnable);
+        pConfig->Write(wxT("/Filter/SpkOutEQEnable"), wxGetApp().m_SpkOutEQEnable);
+
+        pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
+        pConfig->Write(wxT("/Noise/noise_snr"), wxGetApp().m_noise_snr);
+
+        pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+
+        int mode;
+        if (m_rb1600->GetValue())
+            mode = 0;
+        //if (m_rb700b->GetValue())
+        //    mode = 2;
+        if (m_rb700c->GetValue())
+            mode = 3;
+        if (m_rb800xa->GetValue())
+            mode = 4;
+       pConfig->Write(wxT("/Audio/mode"), mode);
+    }
+
+    //m_togRxID->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnRxIDUI), NULL, this);
+    //m_togTxID->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnTxIDUI), NULL, this);
+    m_togBtnOnOff->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnOnOffUI), NULL, this);
+    m_togBtnSplit->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnSplitClickUI), NULL, this);
+    m_togBtnAnalog->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnAnalogClickUI), NULL, this);
+    //m_togBtnALC->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnALCClickUI), NULL, this);
+    //m_btnTogPTT->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnPTT_UI), NULL, this);
+
+    sox_biquad_finish();
+
+    if (m_RxRunning)
+    {
+        stopRxStream();
+    }
+    if (g_sfPlayFile != NULL)
+    {
+        sf_close(g_sfPlayFile);
+        g_sfPlayFile = NULL;
+    }
+    if (g_sfRecFile != NULL)
+    {
+        sf_close(g_sfRecFile);
+        g_sfRecFile = NULL;
+    }
+#ifdef _USE_TIMER
+    if(m_plotTimer.IsRunning())
+    {
+        m_plotTimer.Stop();
+        Unbind(wxEVT_TIMER, &MainFrame::OnTimer, this);
+    }
+#endif //_USE_TIMER
+
+#ifdef _USE_ONIDLE
+    Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainFrame::OnIdle), NULL, this);
+#endif // _USE_ONIDLE
+
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+
+#ifdef _USE_ONIDLE
+void MainFrame::OnIdle(wxIdleEvent &evt) {
+}
+#endif
+
+
+#ifdef _USE_TIMER
+//----------------------------------------------------------------
+// OnTimer()
+//
+// when the timer fires every DT seconds we update the GUI displays.
+// the tabs only the plot that is visible actually gets updated, this
+// keeps CPU load reasonable
+//----------------------------------------------------------------
+void MainFrame::OnTimer(wxTimerEvent &evt)
+{
+
+    int r,c;
+
+    if (m_panelWaterfall->checkDT()) {
+        m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+        m_panelWaterfall->m_newdata = true;
+        m_panelWaterfall->Refresh();
+    }
+
+    m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+    m_panelSpectrum->m_newdata = true;
+    m_panelSpectrum->Refresh();
+
+    /* update scatter/eye plot ------------------------------------------------------------*/
+
+    if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_800XA) {
+        /* FSK Mode - eye diagram ---------------------------------------------------------*/
+        
+        /* add samples row by row */
+
+        int i;
+       for (i=0; i<g_stats.neyetr; i++) {
+            m_panelScatter->add_new_samples_eye(&g_stats.rx_eye[i][0], g_stats.neyesamp);
+        }
+    }
+    else {
+        /* PSK Modes - scatter plot -------------------------------------------------------*/
+        for (r=0; r<g_stats.nr; r++) {
+        
+            if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600) {
+                m_panelScatter->add_new_samples_scatter(&g_stats.rx_symbols[r][0]);
+            }
+        
+            if (/*(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) ||*/(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
+            
+                if (wxGetApp().m_FreeDV700Combine) {
+                    m_panelScatter->setNc(g_Nc/2); /* m_FreeDV700Combine may have changed at run time */
+
+                    /* 
+                       FreeDV 700 uses diversity, so optionaly combine
+                       symbols for scatter plot, as combined symbols are
+                       used for demodulation.  Note we need to use a copy
+                       of the symbols, as we are not sure when the stats
+                       will be updated.
+                    */
+
+                    COMP rx_symbols_copy[g_Nc/2];
+
+                    for(c=0; c<g_Nc/2; c++)
+                        rx_symbols_copy[c] = fcmult(0.5, cadd(g_stats.rx_symbols[r][c], g_stats.rx_symbols[r][c+g_Nc/2]));
+                    m_panelScatter->add_new_samples_scatter(rx_symbols_copy);
+                }
+                else {
+                    m_panelScatter->setNc(g_Nc); /* m_FreeDV700Combine may have changed at run time */
+                    /*
+                      Sometimes useful to plot carriers separately, e.g. to determine if tx carrier power is constant
+                      across carriers.
+                    */
+                    m_panelScatter->add_new_samples_scatter(&g_stats.rx_symbols[r][0]);
+                }
+            }
+       
+        }
+    }
+
+    m_panelScatter->Refresh();
+
+    // Oscilliscope type speech plots -------------------------------------------------------
+
+    short speechInPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotSpeechInFifo, speechInPlotSamples, WAVEFORM_PLOT_BUF)) {
+        memset(speechInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+        //fprintf(stderr, "empty!\n");
+    }
+    m_panelSpeechIn->add_new_short_samples(0, speechInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelSpeechIn->Refresh();
+
+    short speechOutPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotSpeechOutFifo, speechOutPlotSamples, WAVEFORM_PLOT_BUF))
+        memset(speechOutPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+    m_panelSpeechOut->add_new_short_samples(0, speechOutPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelSpeechOut->Refresh();
+
+    short demodInPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotDemodInFifo, demodInPlotSamples, WAVEFORM_PLOT_BUF)) {
+        memset(demodInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+    }
+    m_panelDemodIn->add_new_short_samples(0,demodInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelDemodIn->Refresh();
+
+    // Demod states -----------------------------------------------------------------------
+
+    m_panelTimeOffset->add_new_sample(0, (float)g_stats.rx_timing/FDMDV_NOM_SAMPLES_PER_FRAME);
+    m_panelTimeOffset->Refresh();
+
+    m_panelFreqOffset->add_new_sample(0, g_stats.foff);
+    m_panelFreqOffset->Refresh();
+
+    // SNR text box and gauge ------------------------------------------------------------
+
+    // LP filter g_stats.snr_est some more to stabilise the
+    // display. g_stats.snr_est already has some low pass filtering
+    // but we need it fairly fast to activate squelch.  So we
+    // optionally perform some further filtering for the display
+    // version of SNR.  The "Slow" checkbox controls the amount of
+    // filtering.  The filtered snr also controls the squelch
+
+    g_snr = m_snrBeta*g_snr + (1.0 - m_snrBeta)*g_stats.snr_est;
+    float snr_limited = g_snr;
+    if (snr_limited < -5.0) snr_limited = -5.0;
+    if (snr_limited > 20.0) snr_limited = 20.0;
+
+    char snr[15];
+    sprintf(snr, "%d", (int)(g_snr+0.5)); // round to nearest dB
+
+    //printf("snr_est: %f m_snrBeta: %f g_snr: %f snr_limited: %f\n", g_stats.snr_est,  m_snrBeta, g_snr, snr_limited);
+
+    wxString snr_string(snr);
+    m_textSNR->SetLabel(snr_string);
+    m_gaugeSNR->SetValue((int)(snr_limited+5));
+
+    // Level Gauge -----------------------------------------------------------------------
+
+    float tooHighThresh;
+    if (!g_tx && m_RxRunning)
+    {
+        // receive mode - display From Radio peaks
+        // peak from this DT sampling period
+        int maxDemodIn = 0;
+        for(int i=0; i<WAVEFORM_PLOT_BUF; i++)
+            if (maxDemodIn < abs(demodInPlotSamples[i]))
+                maxDemodIn = abs(demodInPlotSamples[i]);
+
+        // peak from last second
+        if (maxDemodIn > m_maxLevel)
+            m_maxLevel = maxDemodIn;
+
+        tooHighThresh = FROM_RADIO_MAX;
+    }
+    else
+    {
+        // transmit mode - display From Mic peaks
+
+        // peak from this DT sampling period
+        int maxSpeechIn = 0;
+        for(int i=0; i<WAVEFORM_PLOT_BUF; i++)
+            if (maxSpeechIn < abs(speechInPlotSamples[i]))
+                maxSpeechIn = abs(speechInPlotSamples[i]);
+
+        // peak from last second
+        if (maxSpeechIn > m_maxLevel)
+            m_maxLevel = maxSpeechIn;
+
+       tooHighThresh = FROM_MIC_MAX;
+    }
+
+    // Peak Reading meter: updates peaks immediately, then slowly decays
+    int maxScaled = (int)(100.0 * ((float)m_maxLevel/32767.0));
+    m_gaugeLevel->SetValue(maxScaled);
+    //printf("maxScaled: %d\n", maxScaled);
+    if (((float)maxScaled/100) > tooHighThresh)
+        m_textLevel->SetLabel("Too High");
+    else
+        m_textLevel->SetLabel("");
+
+    m_maxLevel *= LEVEL_BETA;
+
+    // sync LED (Colours don't work on Windows) ------------------------
+
+    //fprintf(stderr, "g_State: %d  m_rbSync->GetValue(): %d\n", g_State, m_rbSync->GetValue());
+    if (g_State) {
+        if (g_prev_State == 0) {
+            g_resyncs++;
+        }
+        m_rbSync->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
+        m_rbSync->SetValue(true);        
+    }
+    else {
+        m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) ); // red
+        m_rbSync->SetValue(false);
+    }
+    g_prev_State = g_State;
+
+    // send Callsign ----------------------------------------------------
+
+    char callsign[MAX_CALLSIGN];
+    strncpy(callsign, (const char*) wxGetApp().m_callSign.mb_str(wxConvUTF8), MAX_CALLSIGN-1);
+
+    // buffer 1 txt message to ensure tx data fifo doesn't "run dry"
+
+    if ((unsigned)fifo_used(g_txDataInFifo) < strlen(callsign)) {
+        unsigned int  i;
+
+        //fprintf(g_logfile, "tx callsign: %s.\n", callsign);
+
+        /* optionally append checksum */
+
+        if (wxGetApp().m_enable_checksum) {
+
+            unsigned char checksum = 0;
+            char callsign_checksum_cr[MAX_CALLSIGN+1];
+
+            for(i=0; i<strlen(callsign); i++)
+                checksum += callsign[i];
+            sprintf(callsign_checksum_cr, "%s%2x", callsign, checksum);
+            callsign_checksum_cr[strlen(callsign)+2] = 13;
+            callsign_checksum_cr[strlen(callsign)+3] = 0;
+            strcpy(callsign, callsign_checksum_cr);
+        }
+        else {
+            callsign[strlen(callsign)] = 13;
+            callsign[strlen(callsign)+1] = 0;
+        }
+
+        //fprintf(g_logfile, "tx callsign: %s.\n", callsign);
+
+        // write chars to tx data fifo
+
+        for(i=0; i<strlen(callsign); i++) {
+            short ashort = (short)callsign[i];
+            fifo_write(g_txDataInFifo, &ashort, 1);
+        }
+    }
+
+    // See if any Callsign info received --------------------------------
+
+    short ashort;
+    while (fifo_read(g_rxDataOutFifo, &ashort, 1) == 0) {
+
+        if ((ashort == 13) || ((m_pcallsign - m_callsign) > MAX_CALLSIGN-1)) {
+            // CR completes line
+            *m_pcallsign = 0;
+            
+            /* Checksums can be disabled, e.g. for compatability with
+               older vesions.  In that case we print msg but don't do
+               any event processing.  If checksums enabled, only print
+               out when checksum is good. */
+
+            if (wxGetApp().m_enable_checksum) {
+                // lets see if checksum is OK
+            
+                unsigned char checksum_rx = 0;
+                if (strlen(m_callsign) > 2) {
+                    for(unsigned int i=0; i<strlen(m_callsign)-2; i++)
+                        checksum_rx += m_callsign[i];
+                }
+                unsigned int checksum_tx;
+                int ret = sscanf(&m_callsign[strlen(m_callsign)-2], "%2x", &checksum_tx);
+                //fprintf(g_logfile, "rx callsign: %s.\n  checksum tx: %02x checksum rx: %02x\n", m_callsign, checksum_tx, checksum_rx);
+
+                wxString s;
+                if (ret && (checksum_tx == checksum_rx)) {
+                    m_callsign[strlen(m_callsign)-2] = 0;
+                    s.Printf("%s", m_callsign);
+                    m_txtCtrlCallSign->SetValue(s);
+
+#ifdef __UDP_EXPERIMENTAL__
+                    char s1[MAX_CALLSIGN];
+                    sprintf(s1,"rx_txtmsg %s", m_callsign);
+                    processTxtEvent(s1);
+
+                    m_checksumGood++;
+                    s.Printf("%d", m_checksumGood);
+                    m_txtChecksumGood->SetLabel(s);              
+#endif
+                }
+                else {
+#ifdef __UDP_EXPERIMENTAL__
+                    m_checksumBad++;
+                    s.Printf("%d", m_checksumBad);
+                    m_txtChecksumBad->SetLabel(s);        
+#endif
+                }
+            }
+
+            //fprintf(g_logfile,"resetting callsign %s %ld\n", m_callsign, m_pcallsign-m_callsign);
+            // reset ptr to start of string
+            m_pcallsign = m_callsign;
+        }
+        else {
+            //fprintf(g_logfile, "new char %d %c\n", ashort, (char)ashort);
+            *m_pcallsign++ = (char)ashort;
+        }
+
+        /* If checksums disabled, display txt chars as they arrive */
+
+        if (!wxGetApp().m_enable_checksum) {
+            m_txtCtrlCallSign->SetValue(m_callsign);
+        }
+    }
+
+
+    // Run time update of EQ filters -----------------------------------
+
+    if (m_newMicInFilter || m_newSpkOutFilter) {
+        g_mutexProtectingCallbackData.Lock();
+        deleteEQFilters(g_rxUserdata);
+        designEQFilters(g_rxUserdata);
+        g_mutexProtectingCallbackData.Unlock();
+        m_newMicInFilter = m_newSpkOutFilter = false;
+    }
+    g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+    g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+
+
+    if (g_mode != -1)  {
+
+        // Run time update of FreeDV 700 tx clipper
+
+        freedv_set_clip(g_pfreedv, (int)wxGetApp().m_FreeDV700txClip);
+        
+        // Test Frame Bit Error Updates ------------------------------------
+
+        // Toggle test frame mode at run time
+
+        if (!freedv_get_test_frames(g_pfreedv) && wxGetApp().m_testFrames) {
+
+            // reset stats on check box off to on transition
+
+            freedv_set_test_frames(g_pfreedv, 1);
+            freedv_set_total_bits(g_pfreedv, 0);
+            freedv_set_total_bit_errors(g_pfreedv, 0);
+        }
+        freedv_set_test_frames(g_pfreedv, wxGetApp().m_testFrames);
+        freedv_set_test_frames_diversity(g_pfreedv, wxGetApp().m_FreeDV700Combine);
+        g_channel_noise =  wxGetApp().m_channel_noise;
+
+        if (g_State) {
+            char bits[80], errors[80], ber[80], resyncs[80];
+
+            // update stats on main page
+
+            sprintf(bits, "Bits: %d", freedv_get_total_bits(g_pfreedv)); wxString bits_string(bits); m_textBits->SetLabel(bits_string);
+            sprintf(errors, "Errs: %d", freedv_get_total_bit_errors(g_pfreedv)); wxString errors_string(errors); m_textErrors->SetLabel(errors_string);
+            float b = (float)freedv_get_total_bit_errors(g_pfreedv)/(1E-6+freedv_get_total_bits(g_pfreedv));
+            sprintf(ber, "BER: %4.3f", b); wxString ber_string(ber); m_textBER->SetLabel(ber_string);
+            sprintf(resyncs, "Resyncs: %d", g_resyncs); wxString resyncs_string(resyncs); m_textResyncs->SetLabel(resyncs_string);
+
+            // update error pattern plots if supported
+
+            int sz_error_pattern = freedv_get_sz_error_pattern(g_pfreedv);
+            //fprintf(stderr, "sz_error_pattern: %d\n", sz_error_pattern);
+            if (sz_error_pattern) {
+                short error_pattern[sz_error_pattern];
+
+                if (fifo_read(g_error_pattern_fifo, error_pattern, sz_error_pattern) == 0) {
+                    int i,b;
+
+                    /* both modes map IQ to alternate bits, but on same carrier */
+
+                    if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600) {
+                        /* FreeDV 1600 mapping from error pattern to two bits on each carrier */
+
+                        for(b=0; b<g_Nc*2; b++) {
+                            for(i=b; i<sz_error_pattern; i+= 2*g_Nc) {
+                                m_panelTestFrameErrors->add_new_sample(b, b + 0.8*error_pattern[i]);
+                                g_error_hist[b] += error_pattern[i];
+                                g_error_histn[b]++;
+                            }
+                            //if (b%2)
+                            //    printf("g_error_hist[%d]: %d\n", b/2, g_error_hist[b/2]);
+                        }
+
+                         /* calculate BERs and send to plot */
+
+                        float ber[2*FDMDV_NC_MAX];
+                        for(b=0; b<2*FDMDV_NC_MAX; b++) {
+                            ber[b] = 0.0;
+                        }
+                        for(b=0; b<g_Nc*2; b++) {
+                            ber[b+1] = (float)g_error_hist[b]/g_error_histn[b];
+                        }
+                        assert(g_Nc*2 <= 2*FDMDV_NC_MAX);
+                        m_panelTestFrameErrorsHist->add_new_samples(0, ber, 2*FDMDV_NC_MAX);
+                    }
+       
+                    if (/*(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) || */(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
+                        int c;
+                        //fprintf(stderr, "after g_error_pattern_fifo read 2\n");
+                        
+                        /* 
+                           FreeDV 700 mapping from error pattern to bit on each carrier, see 
+                           data bit to carrier mapping in:
+
+                              codec2-dev/octave/cohpsk_frame_design.ods
+                           We can plot a histogram of the errors/carrier before or after diversity
+                           recombination.  Actually one bar for each IQ bit in carrier order.
+                        */
+
+                        int hist_Nc = sz_error_pattern/4;
+                        //fprintf(stderr, "hist_Nc: %d\n", hist_Nc);
+
+                        for(i=0; i<sz_error_pattern; i++) {
+                            /* maps to IQ bits from each symbol to a "carrier" (actually one line for each IQ bit in carrier order) */
+                            c = floor(i/4);
+                            /* this will clock in 4 bits/carrier to plot */
+                            m_panelTestFrameErrors->add_new_sample(c, c + 0.8*error_pattern[i]);
+                            g_error_hist[c] += error_pattern[i];
+                            g_error_histn[c]++;
+                            //printf("i: %d c: %d\n", i, c);
+                        }
+                        for(; i<2*MODEM_STATS_NC_MAX*4; i++) {
+                            c = floor(i/4);
+                            m_panelTestFrameErrors->add_new_sample(c, c);
+                            //printf("i: %d c: %d\n", i, c);
+                        }
+
+                        /* calculate BERs and send to plot */
+
+                        float ber[2*FDMDV_NC_MAX];
+                        for(b=0; b<2*FDMDV_NC_MAX; b++) {
+                            ber[b] = 0.0;
+                        }
+                        for(b=0; b<hist_Nc; b++) {
+                            ber[b+1] = (float)g_error_hist[b]/g_error_histn[b];
+                        }
+                        assert(hist_Nc <= 2*FDMDV_NC_MAX);
+                        m_panelTestFrameErrorsHist->add_new_samples(0, ber, 2*FDMDV_NC_MAX);
+                    }
+                    m_panelTestFrameErrors->Refresh();       
+                    m_panelTestFrameErrorsHist->Refresh();
+                }
+            }
+        }
+    }
+
+    // command from UDP thread that is best processed in main thread to avoid seg faults
+
+    if (m_schedule_restore) {
+        if (IsIconized())
+            Restore();
+        m_schedule_restore = false;
+    }
+
+#ifdef __UDP_EXPERIMENTAL__
+    // Light Spam Timer LED if at least one timer is running
+
+    int i;
+    optionsDlg->SetSpamTimerLight(false);
+    for(i=0; i<MAX_EVENT_RULES; i++)
+        if (spamTimer[i].IsRunning())
+            optionsDlg->SetSpamTimerLight(true);        
+#endif
+
+    // Blink file playback status line
+
+    if (g_playFileFromRadio) {
+        g_blink += DT;
+        //fprintf(g_logfile, "g_blink: %f\n", g_blink);
+        if ((g_blink >= 1.0) && (g_blink < 2.0))
+            SetStatusText(wxT("Playing into from radio"), 0);
+        if (g_blink >= 2.0) {
+            SetStatusText(wxT(""), 0);
+            g_blink = 0.0;
+        }
+    }
+
+    // Voice Keyer state machine
+
+    VoiceKeyerProcessEvent(VK_DT);
+}
+#endif
+
+
+//-------------------------------------------------------------------------
+// OnCloseFrame()
+//-------------------------------------------------------------------------
+void MainFrame::OnCloseFrame(wxCloseEvent& event)
+{
+    fprintf(stderr, "MainFrame::OnCloseFrame()\n");
+    Pa_Terminate();
+    Destroy();
+}
+
+//-------------------------------------------------------------------------
+// OnTop()
+//-------------------------------------------------------------------------
+void MainFrame::OnTop(wxCommandEvent& event)
+{
+    int style = GetWindowStyle();
+
+    if (style & wxSTAY_ON_TOP)
+    {
+        style &= ~wxSTAY_ON_TOP;
+    }
+    else
+    {
+        style |= wxSTAY_ON_TOP;
+    }
+    SetWindowStyle(style);
+}
+
+//-------------------------------------------------------------------------
+// OnDeleteConfig()
+//-------------------------------------------------------------------------
+void MainFrame::OnDeleteConfig(wxCommandEvent&)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(pConfig->DeleteAll())
+    {
+        wxLogMessage(wxT("Config file/registry key successfully deleted."));
+
+        delete wxConfigBase::Set(NULL);
+        wxConfigBase::DontCreateOnDemand();
+    }
+    else
+    {
+        wxLogError(wxT("Deleting config file/registry key failed."));
+    }
+}
+
+//-------------------------------------------------------------------------
+// Paint()
+//-------------------------------------------------------------------------
+void MainFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+    wxPaintDC dc(this);
+
+    if(GetMenuBar()->IsChecked(ID_PAINT_BG))
+    {
+        dc.Clear();
+    }
+    dc.SetUserScale(m_zoom, m_zoom);
+}
+
+//-------------------------------------------------------------------------
+// OnCmdSliderScroll()
+//-------------------------------------------------------------------------
+void MainFrame::OnCmdSliderScroll(wxScrollEvent& event)
+{
+    char sqsnr[15];
+    g_SquelchLevel = (float)m_sliderSQ->GetValue()/2.0 - 5.0;   
+    sprintf(sqsnr, "%4.1f", g_SquelchLevel); // 0.5 dB steps
+    wxString sqsnr_string(sqsnr);
+    m_textSQ->SetLabel(sqsnr_string);
+
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnCheckSQClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnCheckSQClick(wxCommandEvent& event)
+{
+    if(!g_SquelchActive)
+    {
+        g_SquelchActive = true;
+    }
+    else
+    {
+        g_SquelchActive = false;
+    }
+}
+
+void MainFrame::setsnrBeta(bool snrSlow)
+{
+    if(snrSlow)
+    {
+        m_snrBeta = 0.95; // make this closer to 1.0 to smooth SNR est further
+    }
+    else
+    {
+        m_snrBeta = 0.0; // no smoothing of SNR estimate from demodulator
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnCheckSQClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnCheckSNRClick(wxCommandEvent& event)
+{
+    wxGetApp().m_snrSlow = m_ckboxSNR->GetValue();
+    setsnrBeta(wxGetApp().m_snrSlow);
+    //printf("m_snrSlow: %d\n", (int)wxGetApp().m_snrSlow);
+}
+
+// check for space bar press (only when running)
+
+int MainApp::FilterEvent(wxEvent& event)
+{
+    if ((event.GetEventType() == wxEVT_KEY_DOWN) && 
+        (((wxKeyEvent&)event).GetKeyCode() == WXK_SPACE))
+        {
+            // only use space to toggle PTT if we are running and no modal dialogs (like options) up
+            //fprintf(stderr,"frame->m_RxRunning: %d g_modal: %d\n",
+            //        frame->m_RxRunning, g_modal);
+            if (frame->m_RxRunning && !g_modal) {
+
+                // space bar controls rx/rx if keyer not running
+                if (frame->vk_state == VK_IDLE) {
+                    if (frame->m_btnTogPTT->GetValue())
+                        frame->m_btnTogPTT->SetValue(false);
+                    else
+                        frame->m_btnTogPTT->SetValue(true);
+
+                    frame->togglePTT();
+                }
+                else // spavce bar stops keyer
+                    frame->VoiceKeyerProcessEvent(VK_SPACE_BAR);
+                    
+                return true; // absorb space so we don't toggle control with focus (e.g. Start)
+
+            }
+        }
+
+    return -1;
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnPTT ()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnPTT (wxCommandEvent& event)
+{
+    togglePTT();
+    event.Skip();
+}
+
+void MainFrame::togglePTT(void) {
+
+    // Change tabbed page in centre panel depending on PTT state
+
+    if (g_tx)
+    {
+        // tx-> rx transition, swap to the page we were on for last rx
+        m_auiNbookCtrl->ChangeSelection(wxGetApp().m_rxNbookCtrl);
+    }
+    else
+    {
+        // rx-> tx transition, swap to Mic In page to monitor speech
+        wxGetApp().m_rxNbookCtrl = m_auiNbookCtrl->GetSelection();
+        m_auiNbookCtrl->ChangeSelection(m_auiNbookCtrl->GetPageIndex((wxWindow *)m_panelSpeechIn));
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"ptt"); processTxtEvent(e);
+#endif
+    }
+
+    g_tx = m_btnTogPTT->GetValue();
+
+    // Hamlib PTT
+
+    if (wxGetApp().m_boolHamlibUseForPTT) {        
+        Hamlib *hamlib = wxGetApp().m_hamlib; 
+        wxString hamlibError;
+        if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
+            if (hamlib->ptt(g_tx, hamlibError) == false) {
+                wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            }
+        }
+    }
+
+    // Serial PTT
+
+    if (wxGetApp().m_boolUseSerialPTT && (wxGetApp().m_serialport->isopen())) {
+        wxGetApp().m_serialport->ptt(g_tx);
+    }
+
+    // reset level gauge
+
+    m_maxLevel = 0;
+    m_textLevel->SetLabel(wxT(""));
+    m_gaugeLevel->SetValue(0);
+}
+
+/*
+   Voice Keyer:
+
+   + space bar turns keyer off
+   + 5 secs of valid sync turns it off
+
+   [X] complete state machine and builds OK
+   [ ] file select dialog
+   [ ] test all states
+   [ ] restore size
+*/
+
+void MainFrame::OnTogBtnVoiceKeyerClick (wxCommandEvent& event)
+{
+    if (vk_state == VK_IDLE)
+        VoiceKeyerProcessEvent(VK_START);
+    else
+        VoiceKeyerProcessEvent(VK_SPACE_BAR);
+        
+    event.Skip();
+}
+
+
+int MainFrame::VoiceKeyerStartTx(void)
+{
+    int next_state;
+
+    // start playing wave file or die trying
+
+    SF_INFO sfInfo;
+    sfInfo.format = 0;
+
+    g_sfPlayFile = sf_open(wxGetApp().m_txtVoiceKeyerWaveFile, SFM_READ, &sfInfo);
+    if(g_sfPlayFile == NULL) {
+        wxString strErr = sf_strerror(NULL);
+        wxMessageBox(strErr, wxT("Couldn't open:") + wxGetApp().m_txtVoiceKeyerWaveFile, wxOK);
+        m_togBtnVoiceKeyer->SetValue(false);
+        next_state = VK_IDLE;
+    }
+    else {
+        SetStatusText(wxT("Voice Keyer: Playing File") + wxGetApp().m_txtVoiceKeyerWaveFile + wxT(" to Mic Input") , 0);
+        g_loopPlayFileToMicIn = false;
+        g_playFileToMicIn = true;
+
+        m_btnTogPTT->SetValue(true); togglePTT();
+        next_state = VK_TX;
+    }
+
+    return next_state;
+}
+
+
+void MainFrame::VoiceKeyerProcessEvent(int vk_event) {
+    int next_state = vk_state;
+
+    switch(vk_state) {
+
+    case VK_IDLE:
+        if (vk_event == VK_START) {
+            // sample these puppies at start just in case they are changed while VK running
+            vk_rx_pause = wxGetApp().m_intVoiceKeyerRxPause;
+            vk_repeats = wxGetApp().m_intVoiceKeyerRepeats;
+            fprintf(stderr, "vk_rx_pause: %d vk_repeats: %d\n", vk_rx_pause, vk_repeats);
+
+            vk_repeat_counter = 0;
+            next_state = VoiceKeyerStartTx();
+        }
+        break;
+        
+     case VK_TX:
+
+        // In this state we are transmitting and playing a wave file
+        // to Mic In
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_btnTogPTT->SetValue(false); togglePTT();
+            StopPlayFileToMicIn();
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        if (vk_event == VK_PLAY_FINISHED) {
+            m_btnTogPTT->SetValue(false); togglePTT();
+            vk_repeat_counter++;
+            if (vk_repeat_counter > vk_repeats) {
+                m_togBtnVoiceKeyer->SetValue(false);
+                next_state = VK_IDLE;
+            }
+            else {
+                vk_rx_time = 0.0;
+                next_state = VK_RX;
+            }
+        }
+
+        break;
+
+     case VK_RX:
+
+        // in this state we are receiving and waiting for
+        // delay timer or valid sync
+
+        if (vk_event == VK_DT) {
+            if (freedv_get_sync(g_pfreedv) == 1) {
+                // if we detect sync simulate a smooth transition to SYNC_WAIT State - TODO: review
+                if (vk_rx_time >= DT) {
+                    vk_rx_time -= DT;
+                } else {
+                    next_state = VK_SYNC_WAIT;
+                }
+            } else {
+                vk_rx_time += DT;
+                if (vk_rx_time >= vk_rx_pause) {
+                    next_state = VoiceKeyerStartTx();
+                }
+            }
+        }
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        break;
+
+     case VK_SYNC_WAIT:
+
+        // In this state we wait for valid sync to last
+        // VK_SYNC_WAIT_TIME seconds
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        if (vk_event == VK_DT) {
+            if (freedv_get_sync(g_pfreedv) == 0) {
+                // if we lose sync simulate a smooth transition to return in RX State - TODO: review
+                if (vk_rx_time >= DT) {
+                    vk_rx_time -= DT;
+                } else {
+                    next_state = VK_RX;
+                }
+            } else {
+                vk_rx_time += DT;
+            }
+
+            // drop out of voice keyer if we get a few seconds of valid sync
+
+            if (vk_rx_time >= VK_SYNC_WAIT_TIME) {
+                m_togBtnVoiceKeyer->SetValue(false);
+                next_state = VK_IDLE;
+            }
+        }
+        break;
+
+    default:
+        // catch anything we missed
+
+        m_btnTogPTT->SetValue(false); togglePTT();
+        m_togBtnVoiceKeyer->SetValue(false);
+        next_state = VK_IDLE;
+    }
+
+    //if ((vk_event != VK_DT) || (vk_state != next_state))
+    //    fprintf(stderr, "VoiceKeyerProcessEvent: vk_state: %d vk_event: %d next_state: %d  vk_repeat_counter: %d\n", vk_state, vk_event, next_state, vk_repeat_counter);
+    vk_state = next_state;
+}
+
+
+//-------------------------------------------------------------------------
+// OnTogBtnRxID()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnRxID(wxCommandEvent& event)
+{
+    // empty any junk in rx data FIFO
+    short junk;
+    while(fifo_read(g_rxDataOutFifo,&junk,1) == 0);
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnTxID()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnTxID(wxCommandEvent& event)
+{
+    event.Skip();
+}
+
+void MainFrame::OnTogBtnSplitClick(wxCommandEvent& event) {
+    if (g_split)
+        g_split = 0;
+    else
+        g_split = 1;
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnAnalogClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnAnalogClick (wxCommandEvent& event)
+{
+    if (g_analog == 0) {
+        g_analog = 1;
+        m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(FS/2)));
+        m_panelWaterfall->setFs(FS);
+    }
+    else {
+        g_analog = 0;
+        m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(freedv_get_modem_sample_rate(g_pfreedv)/2)));
+        m_panelWaterfall->setFs(freedv_get_modem_sample_rate(g_pfreedv));
+    }
+
+    g_State = g_prev_State = 0;
+    g_stats.snr_est = 0;
+
+    event.Skip();
+}
+
+void MainFrame::OnCallSignReset(wxCommandEvent& event)
+{
+    m_pcallsign = m_callsign;
+    memset(m_callsign, 0, MAX_CALLSIGN);
+    wxString s;
+    s.Printf("%s", m_callsign);
+    m_txtCtrlCallSign->SetValue(s);
+#ifdef __UDP__EXPERIMENTAL__
+    m_checksumGood = m_checksumBad = 0;
+    m_txtChecksumGood->SetLabel(_("0"));
+    m_txtChecksumBad->SetLabel(_("0"));
+#endif
+}
+
+void MainFrame::OnBerReset(wxCommandEvent& event)
+{
+    freedv_set_total_bits(g_pfreedv, 0);
+    freedv_set_total_bit_errors(g_pfreedv, 0);
+    g_resyncs = 0;
+    int i;
+    for(i=0; i<2*g_Nc; i++) {
+        g_error_hist[i] = 0;
+        g_error_histn[i] = 0;
+    }
+    
+}
+
+#ifdef ALC
+//-------------------------------------------------------------------------
+// OnTogBtnALCClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnALCClick(wxCommandEvent& event)
+{
+    wxMessageBox(wxT("Got Click!"), wxT("OnTogBtnALCClick"), wxOK);
+
+    event.Skip();
+}
+#endif
+
+// extra panel added to file open dialog to add loop checkbox
+MyExtraPlayFilePanel::MyExtraPlayFilePanel(wxWindow *parent): wxPanel(parent)
+{
+    m_cb = new wxCheckBox(this, -1, wxT("Loop"));
+    m_cb->SetToolTip(_("When checked file will repeat forever"));
+    m_cb->SetValue(g_loopPlayFileToMicIn);
+
+    // bug: I can't this to align right.....
+    wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
+    sizerTop->Add(m_cb, 0, wxALIGN_RIGHT, 0);
+    SetSizerAndFit(sizerTop);
+}
+
+static wxWindow* createMyExtraPlayFilePanel(wxWindow *parent)
+{
+    return new MyExtraPlayFilePanel(parent);
+}
+
+void MainFrame::StopPlayFileToMicIn(void)
+{
+    g_mutexProtectingCallbackData.Lock();
+    g_playFileToMicIn = false;
+    sf_close(g_sfPlayFile);
+    SetStatusText(wxT(""));
+    g_mutexProtectingCallbackData.Unlock();
+}
+
+//-------------------------------------------------------------------------
+// OnPlayFileToMicIn()
+//-------------------------------------------------------------------------
+void MainFrame::OnPlayFileToMicIn(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    if(g_playFileToMicIn) {
+        StopPlayFileToMicIn();
+        VoiceKeyerProcessEvent(VK_PLAY_FINISHED);
+    }
+    else
+    {
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+        wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Play File to Mic In"),
+                                    wxGetApp().m_playFileToMicInPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_OPEN | wxFD_FILE_MUST_EXIST
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraPlayFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_playFileToMicInPath, &fileName, &extension);
+        //wxLogDebug("m_playFileToMicInPath: %s", wxGetApp().m_playFileToMicInPath);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = FS;
+            }
+        }
+        g_sfPlayFile = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
+        if(g_sfPlayFile == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+
+        // Huh?! I just copied wxWidgets-2.9.4/samples/dialogs ....
+        g_loopPlayFileToMicIn = static_cast<MyExtraPlayFilePanel*>(ctrl)->getLoopPlayFileToMicIn();
+
+        SetStatusText(wxT("Playing File: ") + fileName + wxT(" to Mic Input") , 0);
+        g_playFileToMicIn = true;
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnPlayFileFromRadio()
+// This puppy "plays" a recorded file into the demodulator input, allowing us
+// to replay off air signals.
+//-------------------------------------------------------------------------
+void MainFrame::OnPlayFileFromRadio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    printf("OnPlayFileFromRadio:: %d\n", (int)g_playFileFromRadio);
+    if (g_playFileFromRadio)
+    {
+        printf("OnPlayFileFromRadio:: Stop\n");
+        g_mutexProtectingCallbackData.Lock();
+        g_playFileFromRadio = false;
+        sf_close(g_sfPlayFileFromRadio);
+        SetStatusText(wxT(""),0);
+        SetStatusText(wxT(""),1);
+        g_mutexProtectingCallbackData.Unlock();
+    }
+    else
+    {
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+        wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Play File - From Radio"),
+                                    wxGetApp().m_playFileFromRadioPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_OPEN | wxFD_FILE_MUST_EXIST
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraPlayFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_playFileFromRadioPath, &fileName, &extension);
+        //wxLogDebug("m_playFileToFromRadioPath: %s", wxGetApp().m_playFileFromRadioPath);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            }
+        }
+        g_sfPlayFileFromRadio = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
+        g_sfFs = sfInfo.samplerate;
+        if(g_sfPlayFileFromRadio == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+
+        // Huh?! I just copied wxWidgets-2.9.4/samples/dialogs ....
+        g_loopPlayFileFromRadio = static_cast<MyExtraPlayFilePanel*>(ctrl)->getLoopPlayFileToMicIn();
+
+        SetStatusText(wxT("Playing into from radio"), 0);
+        if(extension == wxT("raw")) {
+            wxString stringnumber = wxString::Format(wxT("%d"), (int)sfInfo.samplerate);
+            SetStatusText(wxT("raw file assuming Fs=") + stringnumber, 1);          
+        }
+        fprintf(g_logfile, "OnPlayFileFromRadio:: Playing File\n");
+        g_playFileFromRadio = true;
+        g_blink = 0.0;
+    }
+}
+
+// extra panel added to file save dialog to set number of seconds to record for
+
+MyExtraRecFilePanel::MyExtraRecFilePanel(wxWindow *parent): wxPanel(parent)
+{
+    wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
+
+    wxStaticText* staticText = new wxStaticText(this, wxID_ANY, _("Seconds:"), wxDefaultPosition, wxDefaultSize, 0);
+    sizerTop->Add(staticText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_secondsToRecord = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    m_secondsToRecord->SetToolTip(_("Number of seconds to record for"));
+    m_secondsToRecord->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_recFileFromRadioSecs));
+    sizerTop->Add(m_secondsToRecord, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    SetSizerAndFit(sizerTop);
+}
+
+static wxWindow* createMyExtraRecFilePanel(wxWindow *parent)
+{
+    return new MyExtraRecFilePanel(parent);
+}
+
+//-------------------------------------------------------------------------
+// OnRecFileFromRadio()
+//-------------------------------------------------------------------------
+void MainFrame::OnRecFileFromRadio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    if (g_recFileFromRadio) {
+        printf("Stopping Record....\n");
+        g_mutexProtectingCallbackData.Lock();
+        g_recFileFromRadio = false;
+        sf_close(g_sfRecFile);
+        SetStatusText(wxT(""));
+        g_mutexProtectingCallbackData.Unlock();
+    }
+    else {
+
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+         wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Record File From Radio"),
+                                    wxGetApp().m_recFileFromRadioPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_SAVE
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraRecFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_recFileFromRadioPath, &fileName, &extension);
+        wxLogDebug("m_recFileFromRadioPath: %s", wxGetApp().m_recFileFromRadioPath);
+        wxLogDebug("soundFile: %s", soundFile);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            }
+            else if(extension == wxT("wav"))
+            {
+                sfInfo.format     = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            } else {
+                wxMessageBox(wxT("Invalid file format"), wxT("Record File From Radio"), wxOK);
+                return;
+            }
+        }
+        else {
+            wxMessageBox(wxT("Invalid file format"), wxT("Record File From Radio"), wxOK);
+            return;
+        }
+
+        // Bug: on Win32 I cant read m_recFileFromRadioSecs, so have hard coded it
+#ifdef __WIN32__
+        long secs = wxGetApp().m_recFileFromRadioSecs;
+        g_recFromRadioSamples = FS*(unsigned int)secs;
+#else
+        // work out number of samples to record
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+        wxString secsString = static_cast<MyExtraRecFilePanel*>(ctrl)->getSecondsToRecord();
+        wxLogDebug("test: %s secsString: %s\n", wxT("testing 123"), secsString);
+
+        long secs;
+        if (secsString.ToLong(&secs)) {
+            wxGetApp().m_recFileFromRadioSecs = (unsigned int)secs;
+            //printf(" secondsToRecord: %d\n",  (unsigned int)secs);
+            g_recFromRadioSamples = FS*(unsigned int)secs;
+            //printf("g_recFromRadioSamples: %d\n", g_recFromRadioSamples);
+        }
+        else {
+            wxMessageBox(wxT("Invalid number of Seconds"), wxT("Record File From Radio"), wxOK);
+            return;
+        }
+#endif
+
+        g_sfRecFile = sf_open(soundFile.c_str(), SFM_WRITE, &sfInfo);
+        if(g_sfRecFile == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        SetStatusText(wxT("Recording File: ") + fileName + wxT(" From Radio") , 0);
+        g_recFileFromRadio = true;
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnExit()
+//-------------------------------------------------------------------------
+void MainFrame::OnExit(wxCommandEvent& event)
+{
+    fprintf(stderr, "MainFrame::OnExit\n");
+    wxUnusedVar(event);
+#ifdef _USE_TIMER
+    m_plotTimer.Stop();
+#endif // _USE_TIMER
+    if(g_sfPlayFile != NULL)
+    {
+        sf_close(g_sfPlayFile);
+        g_sfPlayFile = NULL;
+    }
+    if(g_sfRecFile != NULL)
+    {
+        sf_close(g_sfRecFile);
+        g_sfRecFile = NULL;
+    }
+    if(m_RxRunning)
+    {
+        stopRxStream();
+    }
+    m_togBtnSplit->Disable();
+    //m_togRxID->Disable();
+    //m_togTxID->Disable();
+    m_togBtnAnalog->Disable();
+    //m_togBtnALC->Disable();
+    //m_btnTogPTT->Disable();
+    Pa_Terminate();
+    Destroy();
+}
+
+//-------------------------------------------------------------------------
+// OnExitClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnExitClick(wxCommandEvent& event)
+{
+    OnExit(event);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsAudio()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsAudio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    int rv = 0;
+    AudioOptsDialog *dlg = new AudioOptsDialog(NULL);
+    rv = dlg->ShowModal();
+    if(rv == wxID_OK)
+    {
+        dlg->ExchangeData(EXCHANGE_DATA_OUT);
+    }
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsAudioUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsAudioUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsFilter()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsFilter(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    FilterDlg *dlg = new FilterDlg(NULL, m_RxRunning, &m_newMicInFilter, &m_newSpkOutFilter);
+    dlg->ShowModal();
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsOptions()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsOptions(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    g_modal = true;
+    //fprintf(stderr,"g_modal: %d\n", g_modal);
+    optionsDlg->Show();
+}
+
+//-------------------------------------------------------------------------
+// OnToolsOptionsUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsOptionsUI(wxUpdateUIEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnToolsComCfg()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsComCfg(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    ComPortsDlg *dlg = new ComPortsDlg(NULL);
+
+    dlg->ShowModal();
+
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsComCfgUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsComCfgUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsPlugInCfg()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsPlugInCfg(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    PlugInDlg *dlg = new PlugInDlg(wxGetApp().m_plugInName, wxGetApp().m_numPlugInParam, wxGetApp().m_plugInParamName);
+    dlg->ShowModal();
+    delete dlg;
+}
+               
+void MainFrame::OnToolsPlugInCfgUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning && wxGetApp().m_plugIn);
+}
+
+
+//-------------------------------------------------------------------------
+// OnHelpCheckUpdates()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpCheckUpdates(wxCommandEvent& event)
+{
+    wxMessageBox("Got Click!", "OnHelpCheckUpdates", wxOK);
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnHelpCheckUpdatesUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpCheckUpdatesUI(wxUpdateUIEvent& event)
+{
+    event.Enable(false);
+}
+
+//-------------------------------------------------------------------------
+//OnHelpAbout()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpAbout(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    wxString msg;
+    msg.Printf( wxT("FreeDV %s\n\n")
+                wxT("Open Source Digital Voice\n\n")
+                wxT("For Help and Support visit: http://freedv.org\n\n")
+
+                wxT("GNU Public License V2.1\n\n")
+                wxT("Copyright (c) David Witten KD0EAG and David Rowe VK5DGR\n\n")
+                wxT("svn revision: %s\n"), FREEDV_VERSION, SVN_REVISION);
+
+    wxMessageBox(msg, wxT("About"), wxOK | wxICON_INFORMATION, this);
+}
+
+
+// Attempt to talk to rig using Hamlib
+
+bool MainFrame::OpenHamlibRig() {
+    if (wxGetApp().m_boolHamlibUseForPTT != true)
+       return false;
+    if (wxGetApp().m_intHamlibRig == 0)
+        return false;
+    if (wxGetApp().m_hamlib == NULL)
+        return false;
+
+    int rig = wxGetApp().m_intHamlibRig;
+    wxString port = wxGetApp().m_strHamlibSerialPort;
+    int serial_rate = wxGetApp().m_intHamlibSerialRate;
+    bool status = wxGetApp().m_hamlib->connect(rig, port.mb_str(wxConvUTF8), serial_rate);
+    if (status == false)
+        wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
+    return status;
+} 
+
+//-------------------------------------------------------------------------
+// OnTogBtnOnOff()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
+{
+    wxString startStop = m_togBtnOnOff->GetLabel();
+
+    // we are attempting to start
+
+    if (startStop.IsSameAs("Start"))
+    {
+        //
+        // Start Running -------------------------------------------------
+        //
+
+        // modify some button states when running
+
+        m_togBtnSplit->Enable();
+        m_togBtnAnalog->Enable();
+        m_togBtnOnOff->SetLabel(wxT("Stop"));
+        m_btnTogPTT->Enable();
+        m_togBtnVoiceKeyer->Enable();
+        vk_state = VK_IDLE;
+
+        m_rb1600->Disable();
+        //m_rb700b->Disable();
+        m_rb700c->Disable();
+        m_rb800xa->Disable();
+        if (m_rbPlugIn != NULL)
+            m_rbPlugIn->Disable();
+
+        // determine what mode we are using
+
+        if (m_rb1600->GetValue()) {
+            g_mode = FREEDV_MODE_1600;
+            g_Nc = 16;
+            m_panelScatter->setNc(g_Nc+1);  /* +1 for BPSK pilot */
+        }
+        #ifdef DISABLED
+        if (m_rb700b->GetValue()) {
+            g_mode = FREEDV_MODE_700B;
+            g_Nc = 14;
+            if (wxGetApp().m_FreeDV700Combine) {
+                m_panelScatter->setNc(g_Nc/2);  /* diversity combnation */
+            }
+            else {
+                m_panelScatter->setNc(g_Nc); 
+            }
+        }
+        #endif
+        if (m_rb700c->GetValue()) {
+            g_mode = FREEDV_MODE_700C;
+            g_Nc = 14;
+            if (wxGetApp().m_FreeDV700Combine) {
+                m_panelScatter->setNc(g_Nc/2);  /* diversity combnation */
+            }
+            else {
+                m_panelScatter->setNc(g_Nc); 
+            }
+        }
+        if (m_rb800xa->GetValue()) {
+            g_mode = FREEDV_MODE_800XA;
+        }
+        if (m_rbPlugIn != NULL) {
+            if (m_rbPlugIn->GetValue()) {
+                g_mode = -1;  /* TODO; a better way of handling (enumarating?) non-freedv modes */
+
+                /* scale plots assuming Fs = 8000 Hz for now */
+
+                m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ)/8000.0);
+                m_panelWaterfall->setFs(8000.0);
+
+                (wxGetApp().m_plugin_startfp)(wxGetApp().m_plugInStates);
+            }
+        }
+
+        if (g_mode != -1) { 
+            // init freedv states
+
+            g_pfreedv = freedv_open(g_mode);
+            freedv_set_callback_txt(g_pfreedv, &my_put_next_rx_char, &my_get_next_tx_char, NULL);
+
+            freedv_set_callback_error_pattern(g_pfreedv, my_freedv_put_error_pattern, (void*)m_panelTestFrameErrors);
+            g_error_pattern_fifo = fifo_create(2*freedv_get_sz_error_pattern(g_pfreedv)+1);
+            g_error_hist = new short[FDMDV_NC_MAX*2];
+            g_error_histn = new short[FDMDV_NC_MAX*2];
+            int i;
+            for(i=0; i<2*FDMDV_NC_MAX; i++) {
+                g_error_hist[i] = 0;
+                g_error_histn[i] = 0;
+            }
+
+            assert(g_pfreedv != NULL);
+
+            // init Codec 2 LPC Post Filter
+
+            codec2_set_lpc_post_filter(freedv_get_codec2(g_pfreedv),
+                                       wxGetApp().m_codec2LPCPostFilterEnable,
+                                       wxGetApp().m_codec2LPCPostFilterBassBoost,
+                                       wxGetApp().m_codec2LPCPostFilterBeta,
+                                       wxGetApp().m_codec2LPCPostFilterGamma);
+
+            // Init Speex pre-processor states
+            // by inspecting Speex source it seems that only denoiser is on be default
+
+            g_speex_st = speex_preprocess_state_init(freedv_get_n_speech_samples(g_pfreedv), FS); 
+
+            // adjust spectrum and waterfall freq scaling base on mode
+
+            m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(freedv_get_modem_sample_rate(g_pfreedv)/2)));
+            m_panelWaterfall->setFs(freedv_get_modem_sample_rate(g_pfreedv));
+
+            // Init text msg decoding
+
+            freedv_set_varicode_code_num(g_pfreedv, wxGetApp().m_textEncoding);
+        }
+
+        modem_stats_open(&g_stats);
+        g_State = g_prev_State = 0;
+        g_snr = 0.0;
+        g_half_duplex = wxGetApp().m_boolHalfDuplex;
+
+        if (g_mode == FREEDV_MODE_800XA) {
+            m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_EYE);
+        }
+        else {
+            m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_SCATTER);
+        }
+
+        m_pcallsign = m_callsign;
+        memset(m_callsign, 0, sizeof(m_callsign));
+#ifdef __UDP_EXPERIMENTAL__
+        m_checksumGood = m_checksumBad = 0;
+        wxString s;
+        s.Printf("%d", m_checksumGood);
+        m_txtChecksumGood->SetLabel(s);              
+        s.Printf("%d", m_checksumBad);
+        m_txtChecksumBad->SetLabel(s);        
+#endif
+
+        m_maxLevel = 0;
+        m_textLevel->SetLabel(wxT(""));
+        m_gaugeLevel->SetValue(0);
+
+        //printf("m_textEncoding = %d\n", wxGetApp().m_textEncoding);
+        //printf("g_stats.snr: %f\n", g_stats.snr_est);
+
+        // attempt to start PTT ......
+        
+        if (wxGetApp().m_boolHamlibUseForPTT)
+            OpenHamlibRig();
+        if (wxGetApp().m_boolUseSerialPTT) {
+            OpenSerialPort();
+        }
+
+        // attempt to start sound cards and tx/rx processing
+
+        startRxStream();
+
+        if (m_RxRunning)
+        {
+#ifdef _USE_TIMER
+            m_plotTimer.Start(_REFRESH_TIMER_PERIOD, wxTIMER_CONTINUOUS);
+#endif // _USE_TIMER
+        }
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"start"); processTxtEvent(e);
+#endif
+    }
+
+    // Stop was pressed or start up failed
+
+    if (startStop.IsSameAs("Stop") || !m_RxRunning ) {
+
+        //
+        // Stop Running -------------------------------------------------
+        //
+
+#ifdef __UDP_EXPERIMENTAL__
+        optionsDlg->SetSpamTimerLight(false);
+#endif
+
+#ifdef _USE_TIMER
+        m_plotTimer.Stop();
+#endif // _USE_TIMER
+
+        // ensure we are not transmitting and shut down audio processing
+
+        if (wxGetApp().m_boolHamlibUseForPTT) {
+            Hamlib *hamlib = wxGetApp().m_hamlib; 
+            wxString hamlibError;
+            if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
+                if (hamlib->ptt(false, hamlibError) == false) {
+                    wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+                }
+                hamlib->close();
+            }
+        }
+
+        if (wxGetApp().m_boolUseSerialPTT) {
+            CloseSerialPort();
+        }
+
+        m_btnTogPTT->SetValue(false);
+        VoiceKeyerProcessEvent(VK_SPACE_BAR);
+
+        stopRxStream();
+        modem_stats_close(&g_stats);
+
+        // free up states, clean up
+
+        if (g_mode == -1) {
+            // PlugIn clean up
+            (wxGetApp().m_plugin_stopfp)(wxGetApp().m_plugInStates);
+        }
+        else {
+            // FreeDV clean up
+            delete g_error_hist;
+            delete g_error_histn;
+            fifo_destroy(g_error_pattern_fifo);
+            freedv_close(g_pfreedv);
+            speex_preprocess_state_destroy(g_speex_st);
+        }
+
+        m_newMicInFilter = m_newSpkOutFilter = true;
+
+        m_togBtnSplit->Disable();
+        //m_togRxID->Disable();
+        //m_togTxID->Disable();
+        m_togBtnAnalog->Disable();
+        m_btnTogPTT->Disable();
+        m_togBtnVoiceKeyer->Disable();
+        m_togBtnOnOff->SetLabel(wxT("Start"));
+        m_rb1600->Enable();
+        //m_rb700b->Enable();
+        m_rb700c->Enable();
+        m_rb800xa->Enable();
+        if (m_rbPlugIn != NULL)
+            m_rbPlugIn->Enable();
+           
+#ifdef DISABLED_FEATURE
+        m_rb700->Enable();
+        m_rb1400old->Enable();
+        m_rb1600Wide->Enable();
+        m_rb1400->Enable();
+        m_rb2000->Enable();
+#endif
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"stop"); processTxtEvent(e);
+#endif
+    }
+}
+
+//-------------------------------------------------------------------------
+// stopRxStream()
+//-------------------------------------------------------------------------
+void MainFrame::stopRxStream()
+{
+    if(m_RxRunning)
+    {
+        m_RxRunning = false;
+
+        fprintf(stderr, "waiting for thread to stop\n");
+        m_txRxThread->m_run = 0;
+        m_txRxThread->Wait();
+        fprintf(stderr, "thread stopped\n");
+
+        m_rxInPa->stop();
+        m_rxInPa->streamClose();
+        delete m_rxInPa;
+        if(m_rxOutPa != m_rxInPa) {
+                       m_rxOutPa->stop();
+                       m_rxOutPa->streamClose();
+                       delete m_rxOutPa;
+               }
+
+        if (g_nSoundCards == 2) {
+            m_txInPa->stop();
+            m_txInPa->streamClose();
+            delete m_txInPa;
+            if(m_txInPa != m_txOutPa) {
+                               m_txOutPa->stop();
+                               m_txOutPa->streamClose();
+                               delete m_txOutPa;
+                       }
+        }
+
+        destroy_fifos();
+        destroy_src();
+        deleteEQFilters(g_rxUserdata);
+        delete g_rxUserdata;
+    }
+}
+
+void MainFrame::destroy_fifos(void)
+{
+    fifo_destroy(g_rxUserdata->infifo1);
+    fifo_destroy(g_rxUserdata->outfifo1);
+    fifo_destroy(g_rxUserdata->infifo2);
+    fifo_destroy(g_rxUserdata->outfifo2);
+    fifo_destroy(g_rxUserdata->rxinfifo);
+    fifo_destroy(g_rxUserdata->rxoutfifo);
+}
+
+void MainFrame::destroy_src(void)
+{
+    src_delete(g_rxUserdata->insrc1);
+    src_delete(g_rxUserdata->outsrc1);
+    src_delete(g_rxUserdata->insrc2);
+    src_delete(g_rxUserdata->outsrc2);
+    src_delete(g_rxUserdata->insrcsf);
+}
+
+void  MainFrame::initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice,
+                                     int soundCard, int sampleRate, int inputChannels)
+{
+    // Note all of the wrapper functions below just set values in a
+    // portaudio struct so can't return any errors. So no need to trap
+    // any errors in this function.
+
+    // init input params
+
+    pa->setInputDevice(inDevice);
+    if(inDevice != paNoDevice) {
+        pa->setInputChannelCount(inputChannels);           // stereo input
+        pa->setInputSampleFormat(PA_SAMPLE_TYPE);
+        pa->setInputLatency(pa->getInputDefaultLowLatency());
+        pa->setInputHostApiStreamInfo(NULL);
+    }
+
+    pa->setOutputDevice(paNoDevice);
+    
+    // init output params
+    
+    pa->setOutputDevice(outDevice);
+    if(outDevice != paNoDevice) {
+        pa->setOutputChannelCount(2);                      // stereo output
+        pa->setOutputSampleFormat(PA_SAMPLE_TYPE);
+        pa->setOutputLatency(pa->getOutputDefaultLowLatency());
+        pa->setOutputHostApiStreamInfo(NULL);
+    }
+
+    // init params that affect input and output
+
+    /*
+      On Linux, setting this to wxGetApp().m_framesPerBuffer caused
+      intermittant break up on the audio from my IC7200 on Ubuntu 14.
+      After a day of bug hunting I found that 0, as recommended by the
+      PortAudio docunmentation, fixed the problem.
+    */
+
+    //pa->setFramesPerBuffer(wxGetApp().m_framesPerBuffer);
+    pa->setFramesPerBuffer(0);
+
+    pa->setSampleRate(sampleRate);
+    pa->setStreamFlags(paClipOff);
+}
+
+//-------------------------------------------------------------------------
+// startRxStream()
+//-------------------------------------------------------------------------
+void MainFrame::startRxStream()
+{
+    int   src_error;
+    const PaDeviceInfo *deviceInfo1 = NULL, *deviceInfo2 = NULL;
+    int   inputChannels1, inputChannels2;
+    bool  two_rx=false;
+    bool  two_tx=false;
+
+    if(!m_RxRunning) {
+        m_RxRunning = true;
+
+        if(Pa_Initialize())
+        {
+            wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
+        }
+
+        m_rxInPa = new PortAudioWrap();
+        if(g_soundCard1InDeviceNum != g_soundCard1OutDeviceNum)
+            two_rx=true;
+        if(g_soundCard2InDeviceNum != g_soundCard2OutDeviceNum)
+            two_tx=true;
+        
+        fprintf(g_logfile, "two_rx: %d two_tx: %d\n", two_rx, two_tx);
+        if(two_rx)
+            m_rxOutPa = new PortAudioWrap();
+        else
+            m_rxOutPa = m_rxInPa;
+
+        if (g_nSoundCards == 0) {
+            wxMessageBox(wxT("No Sound Cards configured, use Tools - Audio Config to configure"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+
+        // Init Sound card 1 ----------------------------------------------
+        // sanity check on sound card device numbers
+
+        if ((m_rxInPa->getDeviceCount() <= g_soundCard1InDeviceNum) ||
+            (m_rxOutPa->getDeviceCount() <= g_soundCard1OutDeviceNum)) {
+            wxMessageBox(wxT("Sound Card 1 not present"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                               delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+
+        // work out how many input channels this device supports.
+
+        deviceInfo1 = Pa_GetDeviceInfo(g_soundCard1InDeviceNum);
+        if (deviceInfo1 == NULL) {
+            wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                               delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+        if (deviceInfo1->maxInputChannels == 1)
+            inputChannels1 = 1;
+        else
+            inputChannels1 = 2;
+
+        if(two_rx) {
+            initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, paNoDevice, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+            initPortAudioDevice(m_rxOutPa, paNoDevice, g_soundCard1OutDeviceNum, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+               }
+        else
+            initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, g_soundCard1OutDeviceNum, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+
+        // Init Sound Card 2 ------------------------------------------------
+
+        if (g_nSoundCards == 2) {
+
+            m_txInPa = new PortAudioWrap();
+            if(two_tx)
+                m_txOutPa = new PortAudioWrap();
+            else
+                m_txOutPa = m_txInPa;
+
+            // sanity check on sound card device numbers
+
+            //printf("m_txInPa->getDeviceCount(): %d\n", m_txInPa->getDeviceCount());
+            //printf("g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+            //printf("g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+
+            if ((m_txInPa->getDeviceCount() <= g_soundCard2InDeviceNum) ||
+                (m_txOutPa->getDeviceCount() <= g_soundCard2OutDeviceNum)) {
+                wxMessageBox(wxT("Sound Card 2 not present"), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                if(two_rx)
+                    delete m_rxOutPa;
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                m_RxRunning = false;
+                return;
+            }
+
+            deviceInfo2 = Pa_GetDeviceInfo(g_soundCard2InDeviceNum);
+            if (deviceInfo2 == NULL) {
+                wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                if(two_rx)
+                                       delete m_rxOutPa;
+                delete m_txInPa;
+                if(two_tx)
+                                       delete m_txOutPa;
+                m_RxRunning = false;
+                return;
+            }
+            if (deviceInfo2->maxInputChannels == 1)
+                inputChannels2 = 1;
+            else
+                inputChannels2 = 2;
+
+            if(two_tx) {
+                               initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, paNoDevice, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+                               initPortAudioDevice(m_txOutPa, paNoDevice, g_soundCard2OutDeviceNum, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+                       }
+                       else
+                               initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, g_soundCard2OutDeviceNum, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+        }
+
+        // Init call back data structure ----------------------------------------------
+
+        g_rxUserdata = new paCallBackData;
+        g_rxUserdata->inputChannels1 = inputChannels1;
+        if (deviceInfo2 != NULL)
+            g_rxUserdata->inputChannels2 = inputChannels2;
+
+        // init sample rate conversion states
+
+        g_rxUserdata->insrc1 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrc1 != NULL);
+        g_rxUserdata->outsrc1 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->outsrc1 != NULL);
+        g_rxUserdata->insrc2 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrc2 != NULL);
+        g_rxUserdata->outsrc2 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->outsrc2 != NULL);
+
+        g_rxUserdata->insrcsf = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrcsf != NULL);
+
+        // create FIFOs used to interface between different buffer sizes
+
+        g_rxUserdata->infifo1 = fifo_create(8*N48);
+        g_rxUserdata->outfifo1 = fifo_create(10*N48);
+        g_rxUserdata->outfifo2 = fifo_create(8*N48);
+        g_rxUserdata->infifo2 = fifo_create(8*N48);
+        printf("N48: %d\n", N48);
+
+        g_rxUserdata->rxinfifo = fifo_create(10 * N8);
+        g_rxUserdata->rxoutfifo = fifo_create(10 * N8);
+
+        // Init Equaliser Filters ------------------------------------------------------
+
+        m_newMicInFilter = m_newSpkOutFilter = true;
+        designEQFilters(g_rxUserdata);
+        g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+        g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+
+        // optional tone in left channel to reliably trigger vox
+        
+        g_rxUserdata->leftChannelVoxTone = wxGetApp().m_leftChannelVoxTone;
+        g_rxUserdata->voxTonePhase = 0;
+
+        // Start sound card 1 ----------------------------------------------------------
+
+        m_rxInPa->setUserData(g_rxUserdata);
+        m_rxErr = m_rxInPa->setCallback(rxCallback);
+
+        m_rxErr = m_rxInPa->streamOpen();
+
+        if(m_rxErr != paNoError) {
+            wxMessageBox(wxT("Sound Card 1 Open/Setup error."), wxT("Error"), wxOK);
+                       delete m_rxInPa;
+                       if(two_rx)
+                               delete m_rxOutPa;
+                       delete m_txInPa;
+                       if(two_tx)
+                               delete m_txOutPa;
+            destroy_fifos();
+            destroy_src();
+            deleteEQFilters(g_rxUserdata);
+            delete g_rxUserdata;
+            m_RxRunning = false;
+            return;
+        }
+
+        m_rxErr = m_rxInPa->streamStart();
+        if(m_rxErr != paNoError) {
+            wxMessageBox(wxT("Sound Card 1 Stream Start Error."), wxT("Error"), wxOK);
+                       delete m_rxInPa;
+                       if(two_rx)
+                               delete m_rxOutPa;
+                       delete m_txInPa;
+                       if(two_tx)
+                               delete m_txOutPa;
+            destroy_fifos();
+            destroy_src();
+            deleteEQFilters(g_rxUserdata);
+            delete g_rxUserdata;
+            m_RxRunning = false;
+            return;
+        }
+
+        // Start separate output stream if needed
+
+        if(two_rx) {
+            m_rxOutPa->setUserData(g_rxUserdata);
+            m_rxErr = m_rxOutPa->setCallback(rxCallback);
+
+            m_rxErr = m_rxOutPa->streamOpen();
+
+            if(m_rxErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 1 Second Stream Open/Setup error."), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                delete m_rxOutPa;
+                delete m_txOutPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+
+            m_rxErr = m_rxOutPa->streamStart();
+            if(m_rxErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 1 Second Stream Start Error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                delete m_rxOutPa;
+                delete m_txOutPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+        }
+
+        // Start sound card 2 ----------------------------------------------------------
+
+        if (g_nSoundCards == 2) {
+
+            // question: can we use same callback data
+            // (g_rxUserdata)or both sound card callbacks?  Is there a
+            // chance of them both being called at the same time?  We
+            // could need a mutex ...
+
+            m_txInPa->setUserData(g_rxUserdata);
+            m_txErr = m_txInPa->setCallback(txCallback);
+            m_txErr = m_txInPa->streamOpen();
+
+            if(m_txErr != paNoError) {
+                fprintf(stderr, "Err: %d\n", m_txErr);
+                wxMessageBox(wxT("Sound Card 2 Open/Setup error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                if(two_rx) {
+                    m_rxOutPa->stop();
+                    m_rxOutPa->streamClose();
+                    delete m_rxOutPa;
+                }
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+            m_txErr = m_txInPa->streamStart();
+            if(m_txErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 2 Start Error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                if(two_rx) {
+                    m_rxOutPa->stop();
+                    m_rxOutPa->streamClose();
+                    delete m_rxOutPa;
+                }
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+
+            // Start separate output stream if needed
+
+            if (two_tx) {
+
+                // question: can we use same callback data
+                // (g_rxUserdata)or both sound card callbacks?  Is there a
+                // chance of them both being called at the same time?  We
+                // could need a mutex ...
+
+                m_txOutPa->setUserData(g_rxUserdata);
+                m_txErr = m_txOutPa->setCallback(txCallback);
+                m_txErr = m_txOutPa->streamOpen();
+
+                if(m_txErr != paNoError) {
+                    wxMessageBox(wxT("Sound Card 2 Second Stream Open/Setup error."), wxT("Error"), wxOK);
+                    m_rxInPa->stop();
+                    m_rxInPa->streamClose();
+                    delete m_rxInPa;
+                    if(two_rx) {
+                        m_rxOutPa->stop();
+                        m_rxOutPa->streamClose();
+                        delete m_rxOutPa;
+                    }
+                    m_txInPa->stop();
+                    m_txInPa->streamClose();
+                    delete m_txInPa;
+                    delete m_txOutPa;
+                    destroy_fifos();
+                    destroy_src();
+                    deleteEQFilters(g_rxUserdata);
+                    delete g_rxUserdata;
+                    m_RxRunning = false;
+                    return;
+                }
+                m_txErr = m_txOutPa->streamStart();
+                if(m_txErr != paNoError) {
+                    wxMessageBox(wxT("Sound Card 2 Second Stream Start Error."), wxT("Error"), wxOK);
+                    m_rxInPa->stop();
+                    m_rxInPa->streamClose();
+                    m_txInPa->stop();
+                    m_txInPa->streamClose();
+                    delete m_txInPa;
+                    if(two_rx) {
+                        m_rxOutPa->stop();
+                        m_rxOutPa->streamClose();
+                        delete m_rxOutPa;
+                    }
+                    delete m_txInPa;
+                    delete m_txOutPa;
+                    destroy_fifos();
+                    destroy_src();
+                    deleteEQFilters(g_rxUserdata);
+                    delete g_rxUserdata;
+                    m_RxRunning = false;
+                    return;
+                }
+            }
+        }
+
+        // start tx/rx processing thread
+
+        m_txRxThread = new txRxThread;
+
+        if ( m_txRxThread->Create() != wxTHREAD_NO_ERROR )
+        {
+            wxLogError(wxT("Can't create thread!"));
+        }
+
+        m_txRxThread->SetPriority(WXTHREAD_MAX_PRIORITY);
+
+        if ( m_txRxThread->Run() != wxTHREAD_NO_ERROR )
+        {
+            wxLogError(wxT("Can't start thread!"));
+        }
+
+    }
+}
+
+
+void MainFrame::processTxtEvent(char event[]) {
+    int rule = 0;
+
+    //printf("processTxtEvent:\n");
+    //printf("  event: %s\n", event);
+
+    // process with regexp and issue system command
+
+    // Each regexp in our list is separated by a newline.  We want to try all of them.
+
+    wxString event_str(event);
+    int match_end, replace_end;
+    match_end = replace_end = 0;
+    wxString regexp_match_list = wxGetApp().m_events_regexp_match;
+    wxString regexp_replace_list = wxGetApp().m_events_regexp_replace;
+
+    bool found_match = false;
+
+    while (((match_end = regexp_match_list.Find('\n')) != wxNOT_FOUND) && (rule < MAX_EVENT_RULES)) {
+        //printf("match_end: %d\n", match_end);
+        if ((replace_end = regexp_replace_list.Find('\n')) != wxNOT_FOUND) {
+            //printf("replace_end = %d\n", replace_end);
+
+            // candidate match and replace regexps strings exist, so lets try them
+
+            wxString regexp_match = regexp_match_list.SubString(0, match_end-1);
+            wxString regexp_replace = regexp_replace_list.SubString(0, replace_end-1);
+            //printf("match: %s replace: %s\n", (const char *)regexp_match.c_str(), (const char *)regexp_replace.c_str());
+            wxRegEx re(regexp_match);
+            //printf("  checking for match against: %s\n", (const char *)regexp_match.c_str());
+
+            // if we found a match, lets run the replace regexp and issue the system command
+
+            wxString event_str_rep = event_str;
+           
+            if (re.Replace(&event_str_rep, regexp_replace) != 0) {
+                fprintf(stderr, "  found match! event_str: %s\n", (const char *)event_str.c_str());
+                found_match = true;
+
+                bool enableSystem = false;
+                if (wxGetApp().m_events)
+                    enableSystem = true;
+
+                // no syscall if spam timer still running
+
+                if (spamTimer[rule].IsRunning()) {
+                    enableSystem = false;
+                    fprintf(stderr, "  spam timer running\n");
+                }
+
+                const char *event_out = event_str_rep.ToUTF8();
+                wxString event_out_with_return_code;
+
+                if (enableSystem) {
+                    int ret = wxExecute(event_str_rep);
+                    event_out_with_return_code.Printf(_T("%s -> returned %d"), event_out, ret);
+                    spamTimer[rule].Start((wxGetApp().m_events_spam_timer)*1000, wxTIMER_ONE_SHOT);
+                }
+                else
+                    event_out_with_return_code.Printf(_T("%s T: %d"), event_out, spamTimer[rule].IsRunning());
+
+                // update event log GUI if currently displayed
+                
+                if (optionsDlg != NULL) {                  
+                    optionsDlg->updateEventLog(wxString(event), event_out_with_return_code);                     
+                }
+            }
+        }
+        regexp_match_list = regexp_match_list.SubString(match_end+1, regexp_match_list.length());
+        regexp_replace_list = regexp_replace_list.SubString(replace_end+1, regexp_replace_list.length());
+
+        rule++;
+    }
+    if ((optionsDlg != NULL) && !found_match) {                  
+        optionsDlg->updateEventLog(wxString(event), _("<no match>"));                     
+    }
+}
+
+
+#define SBQ_MAX_ARGS 4
+
+void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q)
+{
+    char  *arg[SBQ_MAX_ARGS];
+    char   argstorage[SBQ_MAX_ARGS][80];
+    void  *sbq;
+    int    i, argc;
+
+    assert((strcmp(filterType, "bass") == 0)   ||
+           (strcmp(filterType, "treble") == 0) ||
+           (strcmp(filterType, "equalizer") == 0));
+
+    for(i=0; i<SBQ_MAX_ARGS; i++) {
+        arg[i] = &argstorage[i][0];
+        arg[i] = &argstorage[i][0];
+        arg[i] = &argstorage[i][0];
+    }
+
+    argc = 0;
+
+    if ((strcmp(filterType, "bass") == 0) || (strcmp(filterType, "treble") == 0)) {
+        sprintf(arg[argc++], "%s", filterType);
+        sprintf(arg[argc++], "%f", gaindB+1E-6);
+        sprintf(arg[argc++], "%f", freqHz);
+    }
+
+    if (strcmp(filterType, "equalizer") == 0) {
+        sprintf(arg[argc++], "%s", filterType);
+        sprintf(arg[argc++], "%f", freqHz);
+        sprintf(arg[argc++], "%f", Q);
+        sprintf(arg[argc++], "%f", gaindB+1E-6);
+    }
+
+    assert(argc <= SBQ_MAX_ARGS);
+
+    sbq = sox_biquad_create(argc-1, (const char **)arg);
+    assert(sbq != NULL);
+
+    return sbq;
+}
+
+void  MainFrame::designEQFilters(paCallBackData *cb)
+{
+    // init Mic In Equaliser Filters
+
+    if (m_newMicInFilter) {
+        //printf("designing new Min In filters\n");
+        cb->sbqMicInBass   = designAnEQFilter("bass", wxGetApp().m_MicInBassFreqHz, wxGetApp().m_MicInBassGaindB);
+        cb->sbqMicInTreble = designAnEQFilter("treble", wxGetApp().m_MicInTrebleFreqHz, wxGetApp().m_MicInTrebleGaindB);
+        cb->sbqMicInMid    = designAnEQFilter("equalizer", wxGetApp().m_MicInMidFreqHz, wxGetApp().m_MicInMidGaindB, wxGetApp().m_MicInMidQ);
+    }
+
+    // init Spk Out Equaliser Filters
+
+    if (m_newSpkOutFilter) {
+        //printf("designing new Spk Out filters\n");
+        //printf("designEQFilters: wxGetApp().m_SpkOutBassFreqHz: %f\n",wxGetApp().m_SpkOutBassFreqHz);
+        cb->sbqSpkOutBass   = designAnEQFilter("bass", wxGetApp().m_SpkOutBassFreqHz, wxGetApp().m_SpkOutBassGaindB);
+        cb->sbqSpkOutTreble = designAnEQFilter("treble", wxGetApp().m_SpkOutTrebleFreqHz, wxGetApp().m_SpkOutTrebleGaindB);
+        cb->sbqSpkOutMid    = designAnEQFilter("equalizer", wxGetApp().m_SpkOutMidFreqHz, wxGetApp().m_SpkOutMidGaindB, wxGetApp().m_SpkOutMidQ);
+    }
+}
+
+void  MainFrame::deleteEQFilters(paCallBackData *cb)
+{
+    if (m_newMicInFilter) {
+        sox_biquad_destroy(cb->sbqMicInBass);
+        sox_biquad_destroy(cb->sbqMicInTreble);
+        sox_biquad_destroy(cb->sbqMicInMid);
+    }
+    if (m_newSpkOutFilter) {
+        sox_biquad_destroy(cb->sbqSpkOutBass);
+        sox_biquad_destroy(cb->sbqSpkOutTreble);
+        sox_biquad_destroy(cb->sbqSpkOutMid);
+    }
+}
+
+// returns number of output samples generated by resampling
+int resample(SRC_STATE *src,
+            short      output_short[],
+            short      input_short[],
+            int        output_sample_rate,
+            int        input_sample_rate,
+            int        length_output_short, // maximum output array length in samples
+            int        length_input_short
+            )
+{
+    SRC_DATA src_data;
+    float    input[N48*4];
+    float    output[N48*4];
+    int      ret;
+
+    assert(src != NULL);
+    assert(length_input_short <= N48*4);
+    assert(length_output_short <= N48*4);
+
+    src_short_to_float_array(input_short, input, length_input_short);
+
+    src_data.data_in = input;
+    src_data.data_out = output;
+    src_data.input_frames = length_input_short;
+    src_data.output_frames = length_output_short;
+    src_data.end_of_input = 0;
+    src_data.src_ratio = (float)output_sample_rate/input_sample_rate;
+
+    ret = src_process(src, &src_data);
+    assert(ret == 0);
+
+    assert(src_data.output_frames_gen <= length_output_short);
+    src_float_to_short_array(output, output_short, src_data.output_frames_gen);
+
+    return src_data.output_frames_gen;
+}
+
+
+// Decimates samples using an algorithm that produces nice plots of
+// speech signals at a low sample rate.  We want a low sample rate so
+// we don't hammer the graphics system too hard.  Saves decimated data
+// to a fifo for plotting on screen.
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length, int fs)
+{
+    int decimation = fs/WAVEFORM_PLOT_FS;
+    int nSamples, sample;
+    int i, st, en, max, min;
+    short dec_samples[length];
+
+    nSamples = length/decimation;
+
+    for(sample = 0; sample < nSamples; sample += 2)
+    {
+        st = decimation*sample;
+        en = decimation*(sample+2);
+        max = min = 0;
+        for(i=st; i<en; i++ )
+        {
+            if (max < buf[i]) max = buf[i];
+            if (min > buf[i]) min = buf[i];
+        }
+        dec_samples[sample] = max;
+        dec_samples[sample+1] = min;
+    }
+    fifo_write(plotFifo, dec_samples, nSamples);
+}
+
+void txRxProcessing()
+{
+
+    paCallBackData  *cbData = g_rxUserdata;
+
+    // Buffers re-used by tx and rx processing
+    // signals in in48k/out48k are at a maximum sample rate of 48k, could be 44.1kHz
+    // depending on sound hardware.
+
+    short           in8k_short[4*N8];
+    short           in48k_short[4*N48];
+    short           out8k_short[4*N8];
+    short           out48k_short[4*N48];
+    int             nout, samplerate, n_samples;
+
+    //fprintf(g_logfile, "start infifo1: %5d outfifo2: %5d\n", fifo_used(cbData->infifo1), fifo_used(cbData->outfifo2));
+
+    // FreeDV 700 uses a modem sample rate of 7500 Hz which requires some special treatment
+
+    if (g_analog || g_mode == -1) 
+        samplerate = FS;
+    else
+        samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+
+    //
+    //  RX side processing --------------------------------------------
+    //
+
+    // while we have enough input samples available ...
+
+    int nsam = g_soundCard1SampleRate * (float)N8/FS;
+    assert(nsam <= N48);
+    g_mutexProtectingCallbackData.Lock();
+    while ((fifo_read(cbData->infifo1, in48k_short, nsam) == 0) && ((g_half_duplex && !g_tx) || !g_half_duplex)) 
+    {
+        g_mutexProtectingCallbackData.Unlock();
+        unsigned int n8k;
+
+        n8k = resample(cbData->insrc1, in8k_short, in48k_short, samplerate, g_soundCard1SampleRate, N8, nsam);
+        assert(n8k <= N8);
+
+        // optionally save "from radio" signal (write demod input to file)
+        // Really useful for testing and development as it allows us
+        // to repeat tests using off air signals
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_recFileFromRadio && (g_sfRecFile != NULL)) {
+            //printf("g_recFromRadioSamples: %d  n8k: %d \n", g_recFromRadioSamples);
+            if (g_recFromRadioSamples < n8k) {
+                sf_write_short(g_sfRecFile, in8k_short, g_recFromRadioSamples);
+                wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_recFileFromRadioEventId );
+                // call stop/start record menu item, should be thread safe
+                g_parent->GetEventHandler()->AddPendingEvent( event );
+                g_recFromRadioSamples = 0;
+                //printf("finished recording g_recFromRadioSamples: %d n8k: %d!\n", g_recFileFromRadio, n8k);
+            }
+            else {
+                sf_write_short(g_sfRecFile, in8k_short, n8k);
+                g_recFromRadioSamples -= n8k;
+            }
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        // optionally read "from radio" signal from file (read demod input from file)
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_playFileFromRadio && (g_sfPlayFileFromRadio != NULL)) {
+            unsigned int nsf = n8k*g_sfFs/samplerate;
+            short        insf_short[nsf];
+            unsigned int n = sf_read_short(g_sfPlayFileFromRadio, insf_short, nsf);
+            n8k = resample(cbData->insrcsf, in8k_short, insf_short, samplerate, g_sfFs, N8, nsf);
+            //fprintf(g_logfile, "n: %d nsf: %d n8k: %d samplerate: %d\n", n, nsf, n8k, samplerate);
+            assert(n8k <= N8);
+
+            if (n == 0) {
+                if (g_loopPlayFileFromRadio)
+                    sf_seek(g_sfPlayFileFromRadio, 0, SEEK_SET);
+                else {
+                    printf("playFileFromRadio finished, issuing event!\n");
+                    wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_playFileFromRadioEventId );
+                    // call stop/start play menu item, should be thread safe
+                    g_parent->GetEventHandler()->AddPendingEvent( event );
+                }
+            }
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        resample_for_plot(g_plotDemodInFifo, in8k_short, n8k, samplerate);
+
+        if (g_mode != -1) {
+            // send latest squelch level to FreeDV API, as it handles squelch internally
+
+            freedv_set_squelch_en(g_pfreedv, g_SquelchActive);
+            freedv_set_snr_squelch_thresh(g_pfreedv, g_SquelchLevel);
+        }
+
+        // Optional tone interferer
+
+        if (wxGetApp().m_tone) {
+            float w = 2.0*M_PI*wxGetApp().m_tone_freq_hz/freedv_get_modem_sample_rate(g_pfreedv);
+            float s;
+            unsigned int i;
+            for(i=0; i<n8k; i++) {
+                s = (float)wxGetApp().m_tone_amplitude*cos(g_tone_phase);   
+                in8k_short[i] += (int)s;             
+                g_tone_phase += w;
+                //fprintf(stderr, "%f\n", s);
+            }
+            g_tone_phase -= 2.0*M_PI*floor(g_tone_phase/(2.0*M_PI));                                         
+        }
+
+        //fprintf(g_logfile, "snr_squelch_thresh: %f\n",  g_pfreedv->snr_squelch_thresh);
+
+        // compute rx spectrum - do here so update rate in constant
+
+        COMP  rx_fdm[n8k];
+        float rx_spec[MODEM_STATS_NSPEC];
+        unsigned int   i;
+
+        for(i=0; i<n8k; i++) {
+            rx_fdm[i].real = in8k_short[i];
+            rx_fdm[i].imag = 0.0;
+        }            
+        modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, n8k);
+
+        // Average rx spectrum data using a simple IIR low pass filter
+
+        for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+            g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+        }
+
+        // Get some audio to send to headphones/speaker.  If in analog
+        // mode we pass thru the "from radio" audio to the
+        // headphones/speaker.
+
+        if (g_analog) {
+            memcpy(out8k_short, in8k_short, sizeof(short)*n8k);
+            
+            #ifdef OLDSPEC
+            // compute rx spectrum 
+
+            COMP  rx_fdm[n8k];
+            float rx_spec[MODEM_STATS_NSPEC];
+            unsigned int   i;
+
+            for(i=0; i<n8k; i++) {
+                rx_fdm[i].real = in8k_short[i];
+                rx_fdm[i].imag = 0.0;
+            }            
+            modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, n8k);
+
+            // Average rx spectrum data using a simple IIR low pass filter
+
+            for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+                g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+            }
+            #endif
+        }
+        else {
+            fifo_write(cbData->rxinfifo, in8k_short, n8k);
+            per_frame_rx_processing(cbData->rxoutfifo, cbData->rxinfifo);
+            memset(out8k_short, 0, sizeof(short)*N8);
+            fifo_read(cbData->rxoutfifo, out8k_short, N8);
+            //printf("out8k_short: %d\n", out8k_short[0]);
+        }
+
+
+        // Optional Spk Out EQ Filtering, need mutex as filter can change at run time
+        g_mutexProtectingCallbackData.Lock();
+        if (cbData->spkOutEQEnable) {
+            sox_biquad_filter(cbData->sbqSpkOutBass,   out8k_short, out8k_short, N8);
+            sox_biquad_filter(cbData->sbqSpkOutTreble, out8k_short, out8k_short, N8);
+            sox_biquad_filter(cbData->sbqSpkOutMid,    out8k_short, out8k_short, N8);
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        resample_for_plot(g_plotSpeechOutFifo, out8k_short, N8, FS);
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_nSoundCards == 1) {
+            nout = resample(cbData->outsrc2, out48k_short, out8k_short, g_soundCard1SampleRate, FS, N48, N8);
+            fifo_write(cbData->outfifo1, out48k_short, nout);
+        }
+        else {
+            nout = resample(cbData->outsrc2, out48k_short, out8k_short, g_soundCard2SampleRate, FS, N48, N8);
+            fifo_write(cbData->outfifo2, out48k_short, nout);
+        }
+    }
+    g_mutexProtectingCallbackData.Unlock();
+
+    //
+    //  TX side processing --------------------------------------------
+    //
+
+    if ((g_mode != -1) && ((g_nSoundCards == 2) && ((g_half_duplex && g_tx) || !g_half_duplex))) {
+        int ret;
+
+        // Make sure we have q few frames of modulator output
+        // samples.  This also locks the modulator to the sample rate
+        // of sound card 1.  We want to make sure that modulator
+        // samples are uninterrupted by differences in sample rate
+        // between this sound card and sound card 2.
+
+        g_mutexProtectingCallbackData.Lock();
+        while((unsigned)fifo_used(cbData->outfifo1) < 6*N48)
+        {
+            g_mutexProtectingCallbackData.Unlock();
+
+            int   nsam = g_soundCard2SampleRate * freedv_get_n_speech_samples(g_pfreedv)/FS;
+            assert(nsam <= 4*N48);
+
+            // infifo2 is written to by another sound card so it may
+            // over or underflow, but we don't realy care.  It will
+            // just result in a short interruption in audio being fed
+            // to codec2_enc, possibly making a click every now and
+            // again in the decoded audio at the other end.
+
+            // zero speech input just in case infifo2 underflows
+            memset(in48k_short, 0, nsam*sizeof(short));
+            fifo_read(cbData->infifo2, in48k_short, nsam);
+
+            nout = resample(cbData->insrc2, in8k_short, in48k_short, FS, g_soundCard2SampleRate, 4*N8, nsam);
+
+            // optionally use file for mic input signal
+
+            g_mutexProtectingCallbackData.Lock();
+            if (g_playFileToMicIn && (g_sfPlayFile != NULL)) {
+                int n = sf_read_short(g_sfPlayFile, in8k_short, nout);
+                //fprintf(stderr, "n: %d nout: %d\n", n, nout);
+                if (n != nout) {
+                    if (g_loopPlayFileToMicIn)
+                        sf_seek(g_sfPlayFile, 0, SEEK_SET);
+                    else {
+                        wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_playFileToMicInEventId );
+                        // call stop/start play menu item, should be thread safe
+                        g_parent->GetEventHandler()->AddPendingEvent( event );
+                    }
+                }
+            }
+            g_mutexProtectingCallbackData.Unlock();
+
+            // Optional Speex pre-processor for acoustic noise reduction
+
+            if (wxGetApp().m_speexpp_enable) {
+                speex_preprocess_run(g_speex_st, in8k_short);
+            }
+
+            // Optional Mic In EQ Filtering, need mutex as filter can change at run time
+
+            g_mutexProtectingCallbackData.Lock();
+            if (cbData->micInEQEnable) {
+                sox_biquad_filter(cbData->sbqMicInBass, in8k_short, in8k_short, nout);
+                sox_biquad_filter(cbData->sbqMicInTreble, in8k_short, in8k_short, nout);
+                sox_biquad_filter(cbData->sbqMicInMid, in8k_short, in8k_short, nout);
+            }
+            g_mutexProtectingCallbackData.Unlock();
+
+            resample_for_plot(g_plotSpeechInFifo, in8k_short, nout, FS);
+
+            n_samples = freedv_get_n_nom_modem_samples(g_pfreedv);
+
+            if (g_analog) {
+                n_samples = freedv_get_n_speech_samples(g_pfreedv);
+
+                // Boost the "from mic" -> "to radio" audio in analog
+                // mode.  The need for the gain was found by
+                // experiment - analog SSB sounded too quiet compared
+                // to digital. With digital voice we generally drive
+                // the "to radio" (SSB radio mic input) at about 25%
+                // of the peak level for normal SSB voice. So we
+                // introduce 6dB gain to make analog SSB sound the
+                // same level as the digital.  Watch out for clipping.
+                for(int i=0; i<n_samples; i++) {
+                    float out = (float)in8k_short[i]*2.0;
+                    if (out > 32767) out = 32767.0;
+                    if (out < -32767) out = -32767.0;
+                    out8k_short[i] = out;
+                }
+            }
+            else {
+                COMP tx_fdm[freedv_get_n_nom_modem_samples(g_pfreedv)];
+                COMP tx_fdm_offset[freedv_get_n_nom_modem_samples(g_pfreedv)];
+                int  i;
+
+                if (g_mode == FREEDV_MODE_800XA) {
+                    /* 800XA doesn't support complex output just yet */
+                    freedv_tx(g_pfreedv, out8k_short, in8k_short);
+                }
+                else {
+                    freedv_comptx(g_pfreedv, tx_fdm, in8k_short);
+  
+                    freq_shift_coh(tx_fdm_offset, tx_fdm, g_TxFreqOffsetHz, freedv_get_modem_sample_rate(g_pfreedv), &g_TxFreqOffsetPhaseRect, freedv_get_n_nom_modem_samples(g_pfreedv));
+                    for(i=0; i<freedv_get_n_nom_modem_samples(g_pfreedv); i++)
+                        out8k_short[i] = tx_fdm_offset[i].real;
+                }
+            }
+
+            // output one frame of modem signal
+            nout = resample(cbData->outsrc1, out48k_short, out8k_short, g_soundCard1SampleRate, samplerate, N48*4, n_samples);
+            g_mutexProtectingCallbackData.Lock();
+            ret = fifo_write(cbData->outfifo1, out48k_short, nout);
+            //fprintf(stderr,"nout: %d ret: %d N48*4: %d\n", nout, ret, N48*4);
+
+            assert(ret != -1);
+        }
+        g_mutexProtectingCallbackData.Unlock();
+    }
+   
+    //fprintf(g_logfile, "  end infifo1: %5d outfifo2: %5d\n", fifo_used(cbData->infifo1), fifo_used(cbData->outfifo2));
+
+}
+
+//----------------------------------------------------------------
+// per_frame_rx_processing()
+//----------------------------------------------------------------
+
+void per_frame_rx_processing(
+                             FIFO    *output_fifo,   // decoded speech samples
+                             FIFO    *input_fifo
+                             )
+{
+    #ifdef OLDSPEC
+    float               rx_spec[MODEM_STATS_NSPEC];
+    #endif
+    int                 i;
+
+    if (g_mode == -1) {
+        // PlugIn processing ---------------------------------------------------
+
+        int   nin = 160; // TODO: hard code for now - some sort of plugin supplied param in future
+        short input_buf[nin];
+
+        while (fifo_read(input_fifo, input_buf, nin) == 0) {
+            (wxGetApp().m_plugin_rx_samplesfp)(wxGetApp().m_plugInStates, input_buf, nin);
+        }
+
+        #ifdef OLD_SPEC
+        COMP  rx_fdm[nin];
+
+        for(i=0; i<nin; i++) {
+            rx_fdm[i].real = (float)input_buf[i];
+            rx_fdm[i].imag = 0.0;
+        }
+
+        modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, nin);
+
+        // Average rx spectrum data using a simple IIR low pass filter
+
+        for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+            g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+        }
+        #endif
+
+    }
+    else {
+        // FreeDV processing ----------------------------------------------------
+
+        short               input_buf[freedv_get_n_max_modem_samples(g_pfreedv)];
+        short               output_buf[freedv_get_n_speech_samples(g_pfreedv)];
+        COMP                rx_fdm[freedv_get_n_max_modem_samples(g_pfreedv)];
+        COMP                rx_fdm_offset[freedv_get_n_max_modem_samples(g_pfreedv)];
+        int                 nin, nout;
+
+        nin = freedv_nin(g_pfreedv);
+        while (fifo_read(input_fifo, input_buf, nin) == 0) {
+            assert(nin <= freedv_get_n_max_modem_samples(g_pfreedv));
+
+            #ifdef OLD_SPEC
+            int nin_prev = nin;
+            #endif
+
+            //fwrite(input_buf, sizeof(short), nin, ftest);
+
+            // demod per frame processing
+
+            for(i=0; i<nin; i++) {
+                rx_fdm[i].real = (float)input_buf[i];
+                rx_fdm[i].imag = 0.0;
+            }
+       
+            // Optional channel noise
+
+            if (g_channel_noise) {
+                fdmdv_simulate_channel(&g_sig_pwr_av, rx_fdm, nin, wxGetApp().m_noise_snr);
+            }
+
+            freq_shift_coh(rx_fdm_offset, rx_fdm, g_RxFreqOffsetHz, freedv_get_modem_sample_rate(g_pfreedv), &g_RxFreqOffsetPhaseRect, nin);
+            nout = freedv_comprx(g_pfreedv, output_buf, rx_fdm_offset);
+            //kprintf("nout %d outbuf_buf[0]: %d\n", nout, output_buf[0]);
+            fifo_write(output_fifo, output_buf, nout);
+        
+            nin = freedv_nin(g_pfreedv);
+            g_State = freedv_get_sync(g_pfreedv);
+
+            //fprintf(g_logfile, "g_State: %d g_stats.sync: %d snr: %f \n", g_State, g_stats.sync, f->snr);
+
+            // grab extended stats so we can plot spectrum, scatter diagram etc
+
+            freedv_get_modem_extended_stats(g_pfreedv, &g_stats);
+
+            #ifdef OLD_SPEC
+            // compute rx spectrum 
+
+            modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, nin_prev); 
+            
+            // Average rx spectrum data using a simple IIR low pass filter
+
+            for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+                g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+            }
+            #endif
+        }
+    }
+
+
+}
+
+
+//-------------------------------------------------------------------------
+// rxCallback()
+//
+// Sound card 1 callback from PortAudio, that is used for processing rx
+// side:
+//
+// + infifo1 is the "from radio" off air modem signal from the SSB rx that we send to the demod.
+// + In single sound card mode outfifo1 is the "to speaker/headphones" decoded speech output.
+// + In dual sound card mode outfifo1 is the "to radio" modulator signal to the SSB tx.
+//
+//-------------------------------------------------------------------------
+int MainFrame::rxCallback(
+                            const void      *inputBuffer,
+                            void            *outputBuffer,
+                            unsigned long   framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void            *userData
+                         )
+{
+    paCallBackData  *cbData = (paCallBackData*)userData;
+    short           *rptr    = (short*)inputBuffer;
+    short           *wptr    = (short*)outputBuffer;
+
+    short           indata[MAX_FPB];
+    short           outdata[MAX_FPB];
+
+    unsigned int    i;
+
+    (void) timeInfo;
+    (void) statusFlags;
+
+    wxMutexLocker lock(g_mutexProtectingCallbackData);
+
+    //fprintf(g_logfile, "cb1 statusFlags: 0x%x framesPerBuffer: %d rptr: 0x%x wptr: 0x%x \n", (int)statusFlags,
+    //        framesPerBuffer, rptr, wptr);
+
+    //
+    //  RX side processing --------------------------------------------
+    //
+
+    // assemble a mono buffer and write to FIFO
+
+    assert(framesPerBuffer < MAX_FPB);
+
+    if(rptr) {
+        //fprintf(g_logfile,"in %ld %d\n",  framesPerBuffer, g_in++);
+        //g_indata += framesPerBuffer;
+        for(i = 0; i < framesPerBuffer; i++, rptr += cbData->inputChannels1)
+            indata[i] = rptr[0];                       
+        if (fifo_write(cbData->infifo1, indata, framesPerBuffer)) {
+            //fprintf(g_logfile, "infifo1 full\n");
+        }
+        //fifo_write(cbData->outfifo1, indata, framesPerBuffer);
+    }
+
+    // OK now set up output samples for this callback
+
+    if(wptr) {
+        //fprintf(g_logfile,"out %ld %d\n",  framesPerBuffer, g_out++);
+        if (fifo_read(cbData->outfifo1, outdata, framesPerBuffer) == 0) {
+
+            // write signal to both channels
+
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                if (cbData->leftChannelVoxTone) {
+                    cbData->voxTonePhase += 2.0*M_PI*VOX_TONE_FREQ/g_soundCard1SampleRate;
+                    cbData->voxTonePhase -= 2.0*M_PI*floor(cbData->voxTonePhase/(2.0*M_PI));
+                    wptr[0] = VOX_TONE_AMP*cos(cbData->voxTonePhase);                              
+                    //printf("%f %d\n", cbData->voxTonePhase, wptr[0]);
+                }
+                else
+                    wptr[0] = outdata[i];
+                               
+                wptr[1] = outdata[i];
+            }
+        }
+        else {
+            //fprintf(g_logfile, "outfifo1 empty\n");
+            // zero output if no data available
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = 0;
+                wptr[1] = 0;
+            }
+        }
+    }
+
+    return paContinue;
+}
+
+
+//-------------------------------------------------------------------------
+// txCallback()
+//-------------------------------------------------------------------------
+int MainFrame::txCallback(
+                            const void *inputBuffer,
+                            void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo *outTime,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData
+                        )
+{
+    paCallBackData  *cbData = (paCallBackData*)userData;
+    unsigned int    i;
+    short           *rptr    = (short*)inputBuffer;
+    short           *wptr    = (short*)outputBuffer;
+    short           indata[MAX_FPB];
+    short           outdata[MAX_FPB];
+
+    wxMutexLocker lock(g_mutexProtectingCallbackData);
+
+    //    if (statusFlags)
+    //    printf("cb2 statusFlags: 0x%x\n", (int)statusFlags);
+
+    // assemble a mono buffer and write to FIFO
+
+    assert(framesPerBuffer < MAX_FPB);
+
+    if(rptr) {
+        for(i = 0; i < framesPerBuffer; i++, rptr += cbData->inputChannels2)
+            indata[i] = rptr[0];                        
+    }
+
+    //#define SC2_LOOPBACK
+#ifdef SC2_LOOPBACK
+    //TODO: This doesn't work unless using the same soundcard!
+
+    if(wptr) {
+        for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+            wptr[0] = indata[i];
+            wptr[1] = indata[i];
+        }
+    }
+
+#else
+    if(rptr) {
+        if (fifo_write(cbData->infifo2, indata, framesPerBuffer)) {
+            //fprintf(g_logfile, "infifo2 full\n");
+        }
+    }
+
+    // OK now set up output samples for this callback
+
+    if(wptr) {
+        if (fifo_read(cbData->outfifo2, outdata, framesPerBuffer) == 0) {
+               
+            // write signal to both channels */
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = outdata[i];
+                wptr[1] = outdata[i];
+            }
+        }
+        else {
+            //fprintf(g_logfile, "outfifo2 empty\n");
+            // zero output if no data available
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = 0;
+                wptr[1] = 0;
+            }
+        }
+    }
+#endif
+    return paContinue;
+}
+
+// Callback from plot_spectrum & plot_waterfall.  would be nice to
+// work out a way to do this without globals.
+
+void fdmdv2_clickTune(float freq) {
+
+    // The demod is hard-wired to expect a centre frequency of
+    // FDMDV_FCENTRE.  So we want to take the signal centered on the
+    // click tune freq and re-centre it on FDMDV_FCENTRE.  For example
+    // if the click tune freq is 1500Hz, and FDMDV_CENTRE is 1200 Hz,
+    // we need to shift the input signal centred on 1500Hz down to
+    // 1200Hz, an offset of -300Hz.
+
+    // Bit of an "indent" as we are often trying to get it back
+    // exactly in the centre
+
+    if (fabs(FDMDV_FCENTRE - freq) < 10.0) {
+        freq = FDMDV_FCENTRE;
+        fprintf(stderr, "indent!\n");
+    }
+
+    if (g_split) {
+        g_RxFreqOffsetHz = FDMDV_FCENTRE - freq;
+    }
+    else {
+        g_TxFreqOffsetHz = freq - FDMDV_FCENTRE;
+        g_RxFreqOffsetHz = FDMDV_FCENTRE - freq;
+    }
+}
+
+//----------------------------------------------------------------
+// OpenSerialPort()
+//----------------------------------------------------------------
+
+void MainFrame::OpenSerialPort(void)
+{
+    Serialport *serialport = wxGetApp().m_serialport;
+
+    if(!wxGetApp().m_strRigCtrlPort.IsEmpty()) {
+       serialport->openport(wxGetApp().m_strRigCtrlPort.c_str(), 
+                            wxGetApp().m_boolUseRTS, 
+                            wxGetApp().m_boolRTSPos, 
+                            wxGetApp().m_boolUseDTR,
+                            wxGetApp().m_boolDTRPos);
+       if (serialport->isopen()) {
+            // always start PTT in Rx state
+           serialport->ptt(false);
+       }
+       else {
+           wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this);
+       }
+    }
+}
+
+
+//----------------------------------------------------------------
+// CloseSerialPort()
+//----------------------------------------------------------------
+
+void MainFrame::CloseSerialPort(void)
+{
+    Serialport *serialport = wxGetApp().m_serialport;
+    if (serialport->isopen()) {
+        // always end with PTT in rx state
+
+        serialport->ptt(false);
+        serialport->closeport();
+    }
+}
+
+
+#ifdef __UDP_SUPPORT__
+
+//----------------------------------------------------------------
+// PollUDP() - see if any commands on UDP port
+//----------------------------------------------------------------
+
+// test this puppy with netcat: 
+//   $ echo "hello" | nc -u -q1 localhost 3000
+
+int MainFrame::PollUDP(void)
+{
+    // this will block until message received, so we put it in it's own thread
+
+    char buf[1024];
+    char reply[80];
+    size_t n = m_udp_sock->RecvFrom(m_udp_addr, buf, sizeof(buf)).LastCount();
+
+    if (n) {
+        wxString bufstr = wxString::From8BitData(buf, n);
+        bufstr.Trim();
+        wxString ipaddr = m_udp_addr.IPAddress();
+        printf("Received: \"%s\" from %s:%u\n",
+               (const char *)bufstr.c_str(),
+               (const char *)ipaddr.c_str(), m_udp_addr.Service());
+
+        // for security only accept commands from local host
+
+        sprintf(reply,"nope\n");
+        if (ipaddr.Cmp(_("127.0.0.1")) == 0) {
+
+            // process commands
+
+            if (bufstr.Cmp(_("restore")) == 0) {
+                m_schedule_restore = true;  // Make Restore happen in main thread to avoid crashing
+                sprintf(reply,"ok\n");
+            }
+                
+            wxString itemToSet, val;
+            if (bufstr.StartsWith(_("set "), &itemToSet)) {
+                if (itemToSet.StartsWith("txtmsg ", &val)) {
+                    // note: if options dialog is open this will get overwritten
+                    wxGetApp().m_callSign = val;
+                }  
+                sprintf(reply,"ok\n");
+            }
+            if (bufstr.StartsWith(_("ptton"), &itemToSet)) {
+                // note: if options dialog is open this will get overwritten
+                m_btnTogPTT->SetValue(true);
+                togglePTT();
+                sprintf(reply,"ok\n");
+            }
+            if (bufstr.StartsWith(_("pttoff"), &itemToSet)) {
+                // note: if options dialog is open this will get overwritten
+                m_btnTogPTT->SetValue(false);
+                togglePTT();
+                sprintf(reply,"ok\n");
+            }
+                
+        }
+        else {
+            printf("We only accept messages from locahost!\n");
+        }
+
+       if ( m_udp_sock->SendTo(m_udp_addr, reply, strlen(reply)).LastCount() != strlen(reply)) {
+           printf("ERROR: failed to send data\n");
+        }
+    }
+
+    return n;
+}
+
+void MainFrame::startUDPThread(void) {
+    fprintf(stderr, "starting UDP thread!\n");
+    m_UDPThread = new UDPThread;
+    m_UDPThread->mf = this;
+    if (m_UDPThread->Create() != wxTHREAD_NO_ERROR ) {
+        wxLogError(wxT("Can't create thread!"));
+    }
+    if (m_UDPThread->Run() != wxTHREAD_NO_ERROR ) {
+        wxLogError(wxT("Can't start thread!"));
+        delete m_UDPThread;
+    }
+}
+
+void MainFrame::stopUDPThread(void) {
+    printf("stopping UDP thread!\n");
+    if ((m_UDPThread != NULL) && m_UDPThread->m_run) {
+        m_UDPThread->m_run = 0;
+        m_UDPThread->Wait();
+        m_UDPThread = NULL;
+    }
+}
+
+void *UDPThread::Entry() {
+    printf("UDP thread started!\n");
+    while (m_run) {
+        if (wxGetApp().m_udp_enable) {
+            printf("m_udp_enable\n");
+            mf->m_udp_addr.Service(wxGetApp().m_udp_port);
+            mf->m_udp_sock = new wxDatagramSocket(mf->m_udp_addr, wxSOCKET_NOWAIT);
+
+            while (m_run && wxGetApp().m_udp_enable) {
+                if (mf->PollUDP() == 0) {
+                    wxThread::Sleep(20);
+                }
+            }
+
+            delete mf->m_udp_sock;
+        }
+        wxThread::Sleep(20);
+    }
+    return NULL;
+}
+
+#endif
+
+char my_get_next_tx_char(void *callback_state) {
+    short ch = 0;
+    
+    fifo_read(g_txDataInFifo, &ch, 1);
+    //fprintf(stderr, "get_next_tx_char: %c\n", (char)ch);
+    return (char)ch;
+}
+
+void my_put_next_rx_char(void *callback_state, char c) {
+    short ch = (short)c;
+    //fprintf(stderr, "put_next_rx_char: %c\n", (char)c);
+    fifo_write(g_rxDataOutFifo, &ch, 1);
+}
+
+// Callback from FreeDv API to update error plots
+
+void my_freedv_put_error_pattern(void *state, short error_pattern[], int sz_error_pattern) {
+    fifo_write(g_error_pattern_fifo, error_pattern, sz_error_pattern);
+    //fprintf(stderr, "my_freedv_put_error_pattern: sz_error_pattern: %d ret: %d used: %d\n", 
+    //        sz_error_pattern, ret, fifo_used(g_error_pattern_fifo) );
+}
+
+void freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, COMP *foff_phase_rect, int nin)
+{
+    COMP  foff_rect;
+    float mag;
+    int   i;
+
+    foff_rect.real = cosf(2.0*M_PI*foff/Fs);
+    foff_rect.imag = sinf(2.0*M_PI*foff/Fs);
+    for(i=0; i<nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
+    }
+
+    /* normalise digital oscilator as the magnitude can drift over time */
+
+    mag = cabsolute(*foff_phase_rect);
+    foff_phase_rect->real /= mag;       
+    foff_phase_rect->imag /= mag;       
+}
+
+int plugin_get_persistant(char name[], char value[]) {
+    wxString n,v;
+    int i;
+
+    for(i=0; i<wxGetApp().m_numPlugInParam; i++) {
+
+        n = wxGetApp().m_plugInParamName[i];
+
+        if (strcmp(n.mb_str().data(), name) == 0) {
+            v = wxGetApp().m_txtPlugInParam[i];
+            strcpy(value, v.mb_str().data());
+            fprintf(stderr, "plugin_get_persistant called name: %s value: %s\n", name, v.mb_str().data());
+        }
+    }
+
+    return 0;
+}
+
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_main.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_main.h
new file mode 100644 (file)
index 0000000..e074069
--- /dev/null
@@ -0,0 +1,681 @@
+//==========================================================================
+// Name:            fdmdv2_main.h
+//
+// Purpose:         Declares simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_MAIN__
+#define __FDMDV2_MAIN__
+
+#include "version.h"
+#ifndef _NO_AUTOTOOLS_
+#include "../config.h"
+#endif
+#include <wx/wx.h>
+
+#include <wx/tglbtn.h>
+#include <wx/app.h>
+#include "wx/rawbmp.h"
+#include "wx/file.h"
+#include "wx/filename.h"
+#include "wx/config.h"
+#include <wx/fileconf.h>
+#include "wx/graphics.h"
+#include "wx/mstream.h"
+#include "wx/wfstream.h"
+#include "wx/quantize.h"
+#include "wx/scopedptr.h"
+#include "wx/stopwatch.h"
+#include "wx/versioninfo.h"
+#include <wx/sound.h>
+#include <wx/url.h>
+#include <wx/sstream.h>
+#include <wx/listbox.h>
+#include <wx/textdlg.h>
+#include <wx/regex.h>
+#include <wx/socket.h>
+
+#include <samplerate.h>
+
+#include <stdint.h>
+#include <speex/speex_preprocess.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#endif
+
+#include "codec2.h"
+#include "codec2_fifo.h"
+#include "modem_stats.h"
+
+#include "topFrame.h"
+#include "dlg_ptt.h"
+#include "dlg_options.h"
+#include "fdmdv2_plot.h"
+#include "fdmdv2_plot_scalar.h"
+#include "fdmdv2_plot_scatter.h"
+#include "fdmdv2_plot_waterfall.h"
+#include "fdmdv2_plot_spectrum.h"
+#include "fdmdv2_pa_wrapper.h"
+#include "sndfile.h"
+#include "portaudio.h"
+#include "dlg_audiooptions.h"
+#include "dlg_filter.h"
+#include "dlg_options.h"
+#include "varicode.h"
+#include "sox_biquad.h"
+#include "comp_prim.h"
+#include "dlg_plugin.h"
+#include "hamlib.h"
+#include "serialport.h" 
+
+#define _USE_TIMER              1
+#define _USE_ONIDLE             1
+#define _DUMMY_DATA             1
+//#define _AUDIO_PASSTHROUGH    1
+#define _REFRESH_TIMER_PERIOD   (DT*1000)
+//#define _USE_ABOUT_DIALOG       1
+
+enum {
+        ID_START = wxID_HIGHEST,
+        ID_TIMER_WATERFALL,
+        ID_TIMER_SPECTRUM,
+        ID_TIMER_SCATTER,
+        ID_TIMER_SCALAR
+     };
+
+#define EXCHANGE_DATA_IN    0
+#define EXCHANGE_DATA_OUT   1
+
+
+extern int                 g_nSoundCards;
+extern int                 g_soundCard1InDeviceNum;
+extern int                 g_soundCard1OutDeviceNum;
+extern int                 g_soundCard1SampleRate;
+extern int                 g_soundCard2InDeviceNum;
+extern int                 g_soundCard2OutDeviceNum;
+extern int                 g_soundCard2SampleRate;
+
+// Voice Keyer Constants
+
+#define VK_SYNC_WAIT_TIME 5.0
+
+// Voice Keyer States
+
+#define VK_IDLE      0
+#define VK_TX        1
+#define VK_RX        2
+#define VK_SYNC_WAIT 3
+
+// Voice Keyer Events
+
+#define VK_START         0
+#define VK_SPACE_BAR     1
+#define VK_PLAY_FINISHED 2
+#define VK_DT            3
+#define VK_SYNC          4
+
+class MainFrame;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainApp
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MainApp : public wxApp
+{
+    public:
+        virtual bool        OnInit();
+        virtual int         OnExit();
+
+        wxString            m_strVendName;
+        wxString            m_StrAppName;
+
+        wxString            m_textNumChOut;
+        wxString            m_textNumChIn;
+
+        wxString            m_strRxInAudio;
+        wxString            m_strRxOutAudio;
+        wxString            m_textVoiceInput;
+        wxString            m_textVoiceOutput;
+        wxString            m_strSampleRate;
+        wxString            m_strBitrate;
+
+        // PTT -----------------------------------
+
+        bool                m_boolHalfDuplex;
+
+        wxString            m_txtVoiceKeyerWaveFilePath;
+        wxString            m_txtVoiceKeyerWaveFile;
+        int                 m_intVoiceKeyerRxPause;
+        int                 m_intVoiceKeyerRepeats;
+
+        bool                m_boolHamlibUseForPTT;
+        unsigned int        m_intHamlibRig;
+        wxString            m_strHamlibSerialPort;
+        unsigned int        m_intHamlibSerialRate;
+        Hamlib              *m_hamlib;
+
+        bool                m_boolUseSerialPTT;
+        wxString            m_strRigCtrlPort;
+        bool                m_boolUseRTS;
+        bool                m_boolRTSPos;
+        bool                m_boolUseDTR;
+        bool                m_boolDTRPos;
+        Serialport         *m_serialport;
+
+        // Play/Rec files
+
+        wxString            m_playFileToMicInPath;
+        wxString            m_recFileFromRadioPath;
+        unsigned int        m_recFileFromRadioSecs;
+        wxString            m_playFileFromRadioPath;
+
+        // Options dialog
+
+        wxString            m_callSign;
+        bool                m_events;
+        int                 m_events_spam_timer;
+        unsigned int        m_textEncoding;
+        bool                m_enable_checksum;
+        wxString            m_events_regexp_match;
+        wxString            m_events_regexp_replace;
+
+        bool                m_snrSlow;
+
+        // LPC Post Filter
+        bool                m_codec2LPCPostFilterEnable;
+        bool                m_codec2LPCPostFilterBassBoost;
+        float               m_codec2LPCPostFilterGamma;
+        float               m_codec2LPCPostFilterBeta;
+        
+        // Speex Pre-Processor
+        bool                m_speexpp_enable;
+
+        // Mic In Equaliser
+        float               m_MicInBassFreqHz;
+        float               m_MicInBassGaindB;
+        float               m_MicInTrebleFreqHz;
+        float               m_MicInTrebleGaindB;
+        float               m_MicInMidFreqHz;
+        float               m_MicInMidGaindB;
+        float               m_MicInMidQ;
+        bool                m_MicInEQEnable;
+
+        // Spk Out Equaliser
+        float               m_SpkOutBassFreqHz;
+        float               m_SpkOutBassGaindB;
+        float               m_SpkOutTrebleFreqHz;
+        float               m_SpkOutTrebleGaindB;
+        float               m_SpkOutMidFreqHz;
+        float               m_SpkOutMidGaindB;
+        float               m_SpkOutMidQ;
+        bool                m_SpkOutEQEnable;
+
+        // Flags for displaying windows
+        int                 m_show_wf;
+        int                 m_show_spect;
+        int                 m_show_scatter;
+        int                 m_show_timing;
+        int                 m_show_freq;
+        int                 m_show_speech_in;
+        int                 m_show_speech_out;
+        int                 m_show_demod_in;
+        int                 m_show_test_frame_errors;
+        int                 m_show_test_frame_errors_hist;
+
+        // optional vox trigger tone
+        bool                m_leftChannelVoxTone;
+
+        // UDP control port
+        bool                m_udp_enable;
+        int                 m_udp_port;
+
+        // notebook display after tx->rxtransition
+        int                 m_rxNbookCtrl;
+
+        wxRect              m_rTopWindow;
+
+        int                 m_framesPerBuffer;
+
+        bool                loadConfig();
+        bool                saveConfig();
+
+        // Plugins -----------------------------------
+
+        wxString            m_txtPlugInParam[PLUGIN_MAX_PARAMS];
+
+        // plugin details
+
+        void      *m_plugInHandle;
+        bool       m_plugIn;
+        wxString   m_plugInName;
+        int        m_numPlugInParam;
+        wxString   m_plugInParamName[PLUGIN_MAX_PARAMS];
+        void      *m_plugInStates;
+        void     (*m_plugin_startfp)(void *);
+        void     (*m_plugin_stopfp)(void *);
+        void     (*m_plugin_rx_samplesfp)(void *, short *, int);
+
+        // misc
+
+        bool       m_testFrames;
+        bool       m_channel_noise;
+        float      m_channel_snr_dB;
+
+        int        FilterEvent(wxEvent& event);
+        MainFrame *frame;
+
+        // 700 options
+
+        bool       m_FreeDV700txClip;
+        bool       m_FreeDV700Combine;
+
+        // Noise simulation
+
+        int        m_noise_snr;
+
+        // carrier attenuation
+
+        bool       m_attn_carrier_en;
+        int        m_attn_carrier;
+
+        // tone interferer simulation
+
+        bool       m_tone;
+        int        m_tone_freq_hz;
+        int        m_tone_amplitude;
+
+        // Windows debug console
+
+        bool       m_debug_console;
+    protected:
+};
+
+// declare global static function wxGetApp()
+DECLARE_APP(MainApp)
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// paCallBackData
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+typedef struct
+{
+    // libresample states for 48 to 8 kHz conversions
+
+    SRC_STATE      *insrc1;
+    SRC_STATE      *outsrc1;
+    SRC_STATE      *insrc2;
+    SRC_STATE      *outsrc2;
+    SRC_STATE      *insrcsf;
+
+    // FIFOs attached to first sound card
+
+    struct FIFO    *infifo1;
+    struct FIFO    *outfifo1;
+
+    // FIFOs attached to second sound card
+    struct FIFO    *infifo2;
+    struct FIFO    *outfifo2;
+
+    // FIFOs for rx process
+    struct FIFO    *rxinfifo;
+    struct FIFO    *rxoutfifo;
+
+    int             inputChannels1, inputChannels2;
+
+    // EQ filter states
+    void           *sbqMicInBass;
+    void           *sbqMicInTreble;
+    void           *sbqMicInMid;
+    void           *sbqSpkOutBass;
+    void           *sbqSpkOutTreble;
+    void           *sbqSpkOutMid;
+
+    bool            micInEQEnable;
+    bool            spkOutEQEnable;
+
+    // optional loud tone on left channel to reliably trigger vox
+    bool            leftChannelVoxTone;
+    float           voxTonePhase;
+
+} paCallBackData;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// panel with custom loop checkbox for play file dialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MyExtraPlayFilePanel : public wxPanel
+{
+public:
+    MyExtraPlayFilePanel(wxWindow *parent);
+    void setLoopPlayFileToMicIn(bool checked) { m_cb->SetValue(checked); }
+    bool getLoopPlayFileToMicIn(void) { return m_cb->GetValue(); }
+private:
+    wxCheckBox *m_cb;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// panel with custom Seconds-to-record control for record file dialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MyExtraRecFilePanel : public wxPanel
+{
+public:
+    MyExtraRecFilePanel(wxWindow *parent);
+    ~MyExtraRecFilePanel() 
+    {
+        wxLogDebug("Destructor\n");
+    }
+    void setSecondsToRecord(wxString value) { m_secondsToRecord->SetValue(value); }
+    wxString getSecondsToRecord(void) 
+    { 
+        wxLogDebug("getSecondsToRecord: %s\n",m_secondsToRecord->GetValue());
+        return m_secondsToRecord->GetValue(); 
+    }
+private:
+    wxTextCtrl *m_secondsToRecord;
+};
+
+class txRxThread;
+class UDPThread;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainFrame
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MainFrame : public TopFrame
+{
+    public:
+        MainFrame(wxString plugInName, wxWindow *parent);
+        virtual ~MainFrame();
+
+        PlotSpectrum*           m_panelSpectrum;
+        PlotWaterfall*          m_panelWaterfall;
+        PlotScatter*            m_panelScatter;
+        PlotScalar*             m_panelTimeOffset;
+        PlotScalar*             m_panelFreqOffset;
+        PlotScalar*             m_panelSpeechIn;
+        PlotScalar*             m_panelSpeechOut;
+        PlotScalar*             m_panelDemodIn;
+        PlotScalar*             m_panelTestFrameErrors;
+        PlotScalar*             m_panelTestFrameErrorsHist;
+
+        bool                    m_RxRunning;
+
+        PortAudioWrap           *m_rxInPa;
+        PortAudioWrap           *m_rxOutPa;
+        PortAudioWrap           *m_txInPa;
+        PortAudioWrap           *m_txOutPa;
+
+        PaError                 m_rxErr;
+        PaError                 m_txErr;
+        
+        txRxThread*             m_txRxThread;
+
+        bool                    OpenHamlibRig();
+        void                    OpenSerialPort(void);
+        void                    CloseSerialPort(void);
+        void                    SerialPTTRx(void);
+
+        bool                    m_modal;
+
+#ifdef _USE_TIMER
+        wxTimer                 m_plotTimer;
+#endif
+
+    void destroy_fifos(void);
+    void destroy_src(void);
+    void autoDetectSoundCards(PortAudioWrap *pa);
+
+        static int rxCallback(
+                                const void *inBuffer,
+                                void *outBuffer,
+                                unsigned long framesPerBuffer,
+                                const PaStreamCallbackTimeInfo *outTime,
+                                PaStreamCallbackFlags statusFlags,
+                                void *userData
+                             );
+        static int txCallback(
+                                const void *inBuffer,
+                                void *outBuffer,
+                                unsigned long framesPerBuffer,
+                                const PaStreamCallbackTimeInfo *outTime,
+                                PaStreamCallbackFlags statusFlags,
+                                void *userData
+                             );
+
+
+    void initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice, 
+                             int soundCard, int sampleRate, int inputChannels);
+
+    void togglePTT(void);
+
+    wxIPV4address           m_udp_addr;
+    wxDatagramSocket       *m_udp_sock;
+    UDPThread              *m_UDPThread;
+    void                    startUDPThread(void);
+    void                    stopUDPThread(void);
+    int                     PollUDP();
+    bool                    m_schedule_restore;
+
+    int                     vk_state;
+    void VoiceKeyerProcessEvent(int vk_event);
+
+    protected:
+
+        void setsnrBeta(bool snrSlow);
+
+        // protected event handlers
+        virtual void OnCloseFrame(wxCloseEvent& event);
+        void OnExitClick(wxCommandEvent& event);
+
+        void startTxStream();
+        void startRxStream();
+        void stopTxStream();
+        void stopRxStream();
+        void abortTxStream();
+        void abortRxStream();
+        
+        void OnTop(wxCommandEvent& event);
+        void OnExit( wxCommandEvent& event );
+
+        void OnToolsAudio( wxCommandEvent& event );
+        void OnToolsAudioUI( wxUpdateUIEvent& event );
+        void OnToolsComCfg( wxCommandEvent& event );
+        void OnToolsComCfgUI( wxUpdateUIEvent& event );
+        void OnToolsFilter( wxCommandEvent& event );
+        void OnToolsOptions(wxCommandEvent& event);
+        void OnToolsOptionsUI(wxUpdateUIEvent& event);
+
+        void OnToolsPlugInCfg( wxCommandEvent& event );
+        void OnToolsPlugInCfgUI( wxUpdateUIEvent& event );
+
+        void OnPlayFileToMicIn( wxCommandEvent& event );
+        void StopPlayFileToMicIn(void);
+        void OnRecFileFromRadio( wxCommandEvent& event );
+        void OnPlayFileFromRadio( wxCommandEvent& event );
+
+        void OnHelpCheckUpdates( wxCommandEvent& event );
+        void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event );
+        void OnHelpAbout( wxCommandEvent& event );
+        void OnCmdSliderScroll( wxScrollEvent& event );
+//        void OnSliderScrollBottom( wxScrollEvent& event );
+//        void OnCmdSliderScrollChanged( wxScrollEvent& event );
+//        void OnSliderScrollTop( wxScrollEvent& event );
+        void OnCheckSQClick( wxCommandEvent& event );
+        void OnCheckSNRClick( wxCommandEvent& event );
+
+        // Toggle Buttons
+        void OnTogBtnSplitClick(wxCommandEvent& event);
+        void OnTogBtnAnalogClick(wxCommandEvent& event);
+        void OnTogBtnRxID( wxCommandEvent& event );
+        void OnTogBtnTxID( wxCommandEvent& event );
+        void OnTogBtnPTT( wxCommandEvent& event );
+        void OnTogBtnVoiceKeyerClick (wxCommandEvent& event);
+        void OnTogBtnOnOff( wxCommandEvent& event );
+
+        void OnCallSignReset( wxCommandEvent& event );
+        void OnBerReset( wxCommandEvent& event );
+
+        //System Events
+        void OnPaint(wxPaintEvent& event);
+        void OnSize( wxSizeEvent& event );
+        void OnUpdateUI( wxUpdateUIEvent& event );
+        void OnDeleteConfig(wxCommandEvent&);
+#ifdef _USE_TIMER
+        void OnTimer(wxTimerEvent &evt);
+#endif
+#ifdef _USE_ONIDLE
+        void OnIdle(wxIdleEvent &evt);
+#endif
+
+        int VoiceKeyerStartTx(void);
+
+    private:
+        bool        m_useMemory;
+        wxTextCtrl* m_tc;
+        int         m_zoom;
+        float       m_snrBeta;
+        
+        // Callsign/text messaging
+        char        m_callsign[MAX_CALLSIGN];
+        char       *m_pcallsign;
+        unsigned int m_checksumGood;
+        unsigned int m_checksumBad;
+        
+        // Events
+        void        processTxtEvent(char event[]);
+        class OptionsDlg *optionsDlg;
+        wxTimer     spamTimer[MAX_EVENT_RULES];
+
+        // level Gauge
+        float       m_maxLevel;
+        // flags to indicate when new EQ filters need to be designed
+
+        bool        m_newMicInFilter;
+        bool        m_newSpkOutFilter;
+
+        void*       designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q = 0.0);
+        void        designEQFilters(paCallBackData *cb);
+        void        deleteEQFilters(paCallBackData *cb);
+
+        // Voice Keyer States
+
+        int        vk_rx_pause;
+        int        vk_repeats, vk_repeat_counter;
+        float      vk_rx_time;
+};
+
+void txRxProcessing();
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class txRxThread - experimental tx/rx processing thread
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class txRxThread : public wxThread
+{
+public:
+    txRxThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
+
+    // thread execution starts here
+    void *Entry() 
+    {
+        while (m_run) 
+        {
+            txRxProcessing();        
+            wxThread::Sleep(20);
+        }
+        return NULL;
+    }
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    void OnExit() { }
+
+public:
+    bool  m_run;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class UDPThread - waits for UDP messages
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class UDPThread : public wxThread
+{
+public:
+    UDPThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
+
+    // thread execution starts here
+    void *Entry();
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    void OnExit() { }
+
+public:
+    MainFrame              *mf;
+    bool                    m_run;
+};
+
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length, int fs);
+
+int resample(SRC_STATE *src,
+             short      output_short[],
+             short      input_short[],
+             int        output_sample_rate,
+             int        input_sample_rate,
+             int        length_output_short, // maximum output array length in samples
+             int        length_input_short
+             );
+void txRxProcessing();
+void per_frame_rx_processing(
+                                        FIFO    *output_fifo,   // decoded speech samples
+                                        FIFO    *input_fifo     // modem samples input to demod
+                                    );
+
+// FreeDv API calls this when there is a test frame that needs a-plottin'
+
+void my_freedv_put_error_pattern(void *state, short error_pattern[], int sz_error_pattern);
+
+// FreeDv API calls these puppies when it needs/receives a text char 
+
+char my_get_next_tx_char(void *callback_state);
+void my_put_next_rx_char(void *callback_state, char c);
+
+// helper complex freq shift function
+
+void freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, COMP *foff_phase_rect, int nin);
+
+// Helper function called by plugin
+
+int plugin_get_persistant(char name[], char value[]);
+
+#endif //__FDMDV2_MAIN__
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_pa_wrapper.cpp b/freedv/branches/1.2/freedv-dev/src/fdmdv2_pa_wrapper.cpp
new file mode 100644 (file)
index 0000000..2f67ca2
--- /dev/null
@@ -0,0 +1,324 @@
+//==========================================================================
+// Name:            fdmdv2_pa_wrapper.cpp
+// Purpose:         Implements a wrapper class around the PortAudio library.
+// Created:         August 12, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "fdmdv2_pa_wrapper.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// PortAudioWrap()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PortAudioWrap::PortAudioWrap()
+{
+    m_pStream                   = NULL;
+    m_pUserData                 = NULL;
+    m_samplerate                = 0;
+    m_framesPerBuffer           = 0;
+    m_statusFlags               = 0;
+    m_pStreamCallback           = NULL;
+    m_pStreamFinishedCallback   = NULL;
+    m_pTimeInfo                 = 0;
+    m_newdata                   = false;
+
+//    loadData();
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// ~PortAudioWrap()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PortAudioWrap::~PortAudioWrap()
+{
+}
+
+//----------------------------------------------------------------
+// streamOpen()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamOpen()
+{
+    return Pa_OpenStream(
+                            &m_pStream,
+                            m_inputBuffer.device == paNoDevice ? NULL : &m_inputBuffer,
+                            m_outputBuffer.device == paNoDevice ? NULL : &m_outputBuffer,
+                            m_samplerate,
+                            m_framesPerBuffer,
+                            m_statusFlags,
+                            *m_pStreamCallback,
+                            m_pUserData
+                        );
+}
+
+//----------------------------------------------------------------
+// streamStart()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamStart()
+{
+    return Pa_StartStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// streamClose()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamClose()
+{
+    if(isOpen())
+    {
+        PaError rv = Pa_CloseStream(m_pStream);
+        return rv;
+    }
+    else
+    {
+        return paNoError;
+    }
+}
+
+//----------------------------------------------------------------
+// terminate()
+//----------------------------------------------------------------
+void PortAudioWrap::terminate()
+{
+    if(Pa_IsStreamStopped(m_pStream) != paNoError)
+    {
+        Pa_StopStream(m_pStream);
+    }
+    Pa_Terminate();
+}
+
+//----------------------------------------------------------------
+// stop()
+//----------------------------------------------------------------
+void PortAudioWrap::stop()
+{
+    Pa_StopStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// abort()
+//----------------------------------------------------------------
+void PortAudioWrap::abort()
+{
+    Pa_AbortStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// isStopped()
+//----------------------------------------------------------------
+bool PortAudioWrap::isStopped() const
+{
+    PaError ret = Pa_IsStreamStopped(m_pStream);
+    return ret;
+}
+
+//----------------------------------------------------------------
+// isActive()
+//----------------------------------------------------------------
+bool PortAudioWrap::isActive() const
+{
+    PaError ret = Pa_IsStreamActive(m_pStream);
+    return ret;
+}
+
+//----------------------------------------------------------------
+// isOpen()
+//----------------------------------------------------------------
+bool PortAudioWrap::isOpen() const
+{
+    return (m_pStream != NULL);
+}
+
+//----------------------------------------------------------------
+// getDefaultInputDevice()
+//----------------------------------------------------------------
+PaDeviceIndex PortAudioWrap::getDefaultInputDevice()
+{
+    return Pa_GetDefaultInputDevice();
+}
+
+//----------------------------------------------------------------
+// getDefaultOutputDevice()
+//----------------------------------------------------------------
+PaDeviceIndex PortAudioWrap::getDefaultOutputDevice()
+{
+    return Pa_GetDefaultOutputDevice();
+}
+
+//----------------------------------------------------------------
+// setInputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputChannelCount(int count)
+{
+    m_inputBuffer.channelCount = count;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// getInputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::getInputChannelCount()
+{
+    return m_inputBuffer.channelCount;
+}
+
+//----------------------------------------------------------------
+// setInputSampleFormat()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputSampleFormat(PaSampleFormat format)
+{
+    m_inputBuffer.sampleFormat = format;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputLatency()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputLatency(PaTime latency)
+{
+    m_inputBuffer.suggestedLatency = latency;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputHostApiStreamInfo()
+//----------------------------------------------------------------
+void PortAudioWrap::setInputHostApiStreamInfo(void *info)
+{
+    m_inputBuffer.hostApiSpecificStreamInfo = info;
+}
+
+//----------------------------------------------------------------
+// getInputDefaultLowLatency()
+//----------------------------------------------------------------
+PaTime  PortAudioWrap::getInputDefaultLowLatency()
+{
+    return Pa_GetDeviceInfo(m_inputBuffer.device)->defaultLowInputLatency;
+}
+
+//----------------------------------------------------------------
+// setOutputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputChannelCount(int count)
+{
+    m_outputBuffer.channelCount = count;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// getOutputChannelCount()
+//----------------------------------------------------------------
+const int PortAudioWrap::getOutputChannelCount()
+{
+    return m_outputBuffer.channelCount;
+}
+
+//----------------------------------------------------------------
+// getDeviceName()
+//----------------------------------------------------------------
+const char *PortAudioWrap::getDeviceName(PaDeviceIndex dev)
+{
+    const PaDeviceInfo *info;
+    info = Pa_GetDeviceInfo(dev);
+    return info->name;
+}
+
+//----------------------------------------------------------------
+// setOutputSampleFormat()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputSampleFormat(PaSampleFormat format)
+{
+    m_outputBuffer.sampleFormat = format;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputLatency()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputLatency(PaTime latency)
+{
+    m_outputBuffer.suggestedLatency = latency;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputHostApiStreamInfo()
+//----------------------------------------------------------------
+void PortAudioWrap::setOutputHostApiStreamInfo(void *info)
+{
+    m_outputBuffer.hostApiSpecificStreamInfo = info;
+}
+
+//----------------------------------------------------------------
+// getOutputDefaultLowLatency()
+//----------------------------------------------------------------
+PaTime  PortAudioWrap::getOutputDefaultLowLatency()
+{
+    return Pa_GetDeviceInfo(m_outputBuffer.device)->defaultLowOutputLatency;
+}
+
+//----------------------------------------------------------------
+// setFramesPerBuffer()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setFramesPerBuffer(unsigned long size)
+{
+    m_framesPerBuffer = size;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setSampleRate()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setSampleRate(unsigned long rate)
+{
+    m_samplerate = rate;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setStreamFlags()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setStreamFlags(PaStreamFlags flags)
+{
+    m_statusFlags = flags;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputDevice()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputDevice(PaDeviceIndex index)
+{
+    m_inputBuffer.device = index;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputDevice()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputDevice(PaDeviceIndex index)
+{
+    m_outputBuffer.device = index;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setCallback()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setCallback(PaStreamCallback *callback)
+{
+    m_pStreamCallback = callback;
+    return paNoError;
+}
+
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_pa_wrapper.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_pa_wrapper.h
new file mode 100644 (file)
index 0000000..3d216c0
--- /dev/null
@@ -0,0 +1,115 @@
+//==========================================================================
+// Name:            fdmdv2_pa_wrapper.h
+// Purpose:         Defines a wrapper class around PortAudio
+// Created:         August 12, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <stdio.h>
+#include <math.h>
+#include "fdmdv2_defines.h"
+#include "codec2_fdmdv.h"
+#include "codec2.h"
+#include "portaudio.h"
+
+#define PA_SAMPLE_TYPE      paInt16         //paFloat32
+#define FRAMES_PER_BUFFER   (64)
+
+typedef float SAMPLE;
+
+class PortAudioWrap
+{
+    public:
+        PortAudioWrap();
+        ~PortAudioWrap();
+
+//        float                           m_av_mag[FDMDV_NSPEC];
+
+    private:
+        PaStream                        *m_pStream;
+        void                            *m_pUserData;
+        PaStreamCallback                *m_pStreamCallback;
+        PaStreamFinishedCallback        *m_pStreamFinishedCallback;
+        const PaStreamCallbackTimeInfo  *m_pTimeInfo;
+        struct FDMDV                    *m_pFDMDV_state;
+        PaStreamParameters              m_inputBuffer;
+        PaStreamParameters              m_outputBuffer;
+        int                             m_samplerate;
+        unsigned long                   m_framesPerBuffer;
+        PaStreamCallbackFlags           m_statusFlags;
+        bool                            m_newdata;
+
+    public:
+
+        void                averageData(float mag_dB[]);
+
+        int                 getDeviceCount() { return Pa_GetDeviceCount(); }
+        PaDeviceIndex       getDefaultInputDevice();
+        PaDeviceIndex       getDefaultOutputDevice();
+        PaStreamParameters  *getDeviceInfo(PaDeviceIndex idx);
+
+        PaError             setFramesPerBuffer(unsigned long size);
+        PaError             setSampleRate(unsigned long size);
+
+        PaError             setStreamFlags(PaStreamFlags flags);
+        PaError             setCallback(PaStreamCallback *m_pStreamCallback);
+        PaError             setStreamCallback(PaStream *stream, PaStreamCallback* callback) { m_pStreamCallback = callback; return 0;}
+        PaError             setStreamFinishedCallback(PaStream *stream, PaStreamFinishedCallback* m_pStreamFinishedCallback);
+
+        void                setInputBuffer(const PaStreamParameters& inputBuffer)   {this->m_inputBuffer = inputBuffer;}
+        PaError             setInputDevice(PaDeviceIndex dev);
+        PaError             setInputChannelCount(int count);
+        int                 getInputChannelCount();
+        PaError             setInputSampleFormat(PaSampleFormat format);
+        PaError             setInputSampleRate(PaSampleFormat format);
+        PaError             setInputLatency(PaTime latency);
+        void                setInputHostApiStreamInfo(void *info = NULL);
+        PaTime              getInputDefaultLowLatency();
+        const char          *getDeviceName(PaDeviceIndex dev);
+
+        PaError             setOutputDevice(PaDeviceIndex dev);
+        PaError             setOutputChannelCount(int count);
+        const int           getOutputChannelCount();
+        PaError             setOutputSampleFormat(PaSampleFormat format);
+        PaError             setOutputLatency(PaTime latency);
+        void                setOutputHostApiStreamInfo(void *info = NULL);
+        PaTime              getOutputDefaultLowLatency();
+
+        void                setFdmdvState(FDMDV* fdmdv_state)                       {this->m_pFDMDV_state = fdmdv_state;}
+        void                setOutputBuffer(const PaStreamParameters& outputBuffer) {this->m_outputBuffer = outputBuffer;}
+        void                setTimeInfo(PaStreamCallbackTimeInfo* timeInfo)         {this->m_pTimeInfo = timeInfo;}
+        void                setUserData(void* userData)                             {this->m_pUserData = userData;}
+        unsigned long       getFramesPerBuffer() const                              {return m_framesPerBuffer;}
+        const               PaStreamParameters& getInputBuffer() const              {return m_inputBuffer;}
+        const               PaStreamParameters& getOutputBuffer() const             {return m_outputBuffer;}
+        const               PaStreamCallbackFlags& getStatusFlags() const           {return m_statusFlags;}
+
+        FDMDV*              getFdmdvState()                                         {return m_pFDMDV_state;}
+        int                 getSamplerate() const                                   {return m_samplerate;}
+        PaStream*           getStream()                                             {return m_pStream;}
+        void                *getUserData()                                          {return m_pUserData;}
+        bool                getDataAvail()                                          {return m_newdata;}
+        PaError             streamStart();
+        PaError             streamClose();
+        PaError             streamOpen();
+        void                terminate();
+        void                stop();
+        void                abort();
+        bool                isOpen() const;
+        bool                isStopped() const;
+        bool                isActive() const;
+//        void                loadData();
+};
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot.cpp b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot.cpp
new file mode 100644 (file)
index 0000000..1b85cd9
--- /dev/null
@@ -0,0 +1,283 @@
+//==========================================================================
+// Name:            fdmdv2_plot.cpp
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "fdmdv2_plot.h"
+
+BEGIN_EVENT_TABLE(PlotPanel, wxPanel)
+    EVT_PAINT           (PlotPanel::OnPaint)
+    EVT_MOTION          (PlotPanel::OnMouseMove)
+    EVT_LEFT_DOWN       (PlotPanel::OnMouseLeftDown)
+    EVT_LEFT_UP         (PlotPanel::OnMouseLeftUp)
+    EVT_RIGHT_DOWN      (PlotPanel::OnMouseRightDown)
+    EVT_MOUSEWHEEL      (PlotPanel::OnMouseWheelMoved)
+    EVT_SIZE            (PlotPanel::OnSize)
+    EVT_SHOW            (PlotPanel::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotPanel(wxFrame* parent) : wxPanel(parent)
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotPanel::PlotPanel(wxFrame* parent) : wxPanel(parent)
+{
+    m_pNoteBook         = (wxAuiNotebook *) parent;
+    m_pTopFrame         = (MainFrame *)m_pNoteBook->GetParent();
+    m_zoomFactor        = 1.0;
+    m_pBmp              = NULL;
+    m_pPix              = NULL;
+    m_firstPass         = true;
+    m_line_color        = 0;
+    m_newdata           = false;
+    m_clip              = false;
+    m_use_bitmap        = true;
+    m_rubberBand        = false;
+    m_mouseDown         = false;
+    m_penShortDash      = wxPen(wxColor(0xA0, 0xA0, 0xA0), 1, wxPENSTYLE_SHORT_DASH);
+    m_penDotDash        = wxPen(wxColor(0xD0, 0xD0, 0xD0), 1, wxPENSTYLE_DOT_DASH);
+    m_penSolid          = wxPen(wxColor(0x00, 0x00, 0x00), 1, wxPENSTYLE_SOLID);
+    SetBackgroundStyle(wxBG_STYLE_PAINT);
+    SetLabelSize(10.0);
+}
+
+//-------------------------------------------------------------------------
+// ~PlotPanel()
+//-------------------------------------------------------------------------
+PlotPanel::~PlotPanel()
+{
+    if(m_pBmp != NULL)
+    {
+        delete m_pBmp;
+    }
+}
+
+//-------------------------------------------------------------------------
+// GetLabelSize()
+//-------------------------------------------------------------------------
+double PlotPanel::GetLabelSize()
+{
+    return m_label_size;
+}
+
+//-------------------------------------------------------------------------
+// SetLabelSize()
+//-------------------------------------------------------------------------
+void PlotPanel::SetLabelSize(double size)
+{
+    m_label_size = size;
+}
+
+//-------------------------------------------------------------------------
+// OnShow()
+//-------------------------------------------------------------------------
+void PlotPanel::OnShow(wxShowEvent& event)
+{
+    this->Refresh();
+}
+
+//-------------------------------------------------------------------------
+// OnErase()
+//-------------------------------------------------------------------------
+void PlotPanel::OnErase(wxEraseEvent& event)
+{
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnSize()
+//-------------------------------------------------------------------------
+void PlotPanel::OnSize(wxSizeEvent& event)
+{
+    m_rCtrlPrev = m_rCtrl;
+    m_rCtrl     = GetClientRect();
+    if(m_use_bitmap)
+    {
+        if(!m_oImage.IsOk())
+        {
+            m_oImage.Create(m_rCtrl.GetWidth(), m_rCtrl.GetHeight(), true);
+        }
+        else
+        {
+            m_oImage.Rescale(m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
+        }
+        m_pBmp = new wxBitmap(m_oImage, wxBITMAP_SCREEN_DEPTH);
+        m_firstPass = true;
+    }
+    this->Refresh();
+}
+
+//-------------------------------------------------------------------------
+// OnMouseMove()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseMove(wxMouseEvent& event)
+{
+//    if(m_mouseDown)
+//    {
+//        paintNow();
+//    }
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftDown()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseLeftDown(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseRightDown(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseWheelMoved()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseWheelMoved(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftUp()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseLeftUp(wxMouseEvent& event)
+{
+    m_mouseDown = false;
+}
+
+//-------------------------------------------------------------------------
+// SetZoomFactor()
+//-------------------------------------------------------------------------
+double PlotPanel::SetZoomFactor(double zf)
+{
+    if((zf > 0) && (zf < 5.0))
+    {
+        m_zoomFactor = zf;
+    }
+    return zf;
+}
+
+//-------------------------------------------------------------------------
+// GetZoomFactor()
+//-------------------------------------------------------------------------
+double PlotPanel::GetZoomFactor(double zf)
+{
+    return m_zoomFactor;
+}
+
+//-------------------------------------------------------------------------
+// draw()
+//-------------------------------------------------------------------------
+void PlotPanel::draw(wxAutoBufferedPaintDC& pDC)
+{
+    printf("PlotPanel::draw()");
+    wxMemoryDC m_mDC;
+    m_mDC.SelectObject(*m_pBmp);
+    m_rCtrl  = GetClientRect();
+    m_rGrid  = m_rCtrl;
+
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+    m_rGrid.Offset(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
+
+    pDC.Clear();
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    if(m_firstPass)
+    {
+        m_firstPass = false;
+        m_mDC.FloodFill(0, 0, VERY_LTGREY_COLOR);
+
+        // Draw a filled rectangle with aborder
+        wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR);
+        m_mDC.SetBrush(ltGraphBkgBrush);
+        m_mDC.SetPen(wxPen(BLACK_COLOR, 0));
+        m_mDC.DrawRectangle(m_rPlot);
+    }
+    if(m_newdata)
+    {
+        m_newdata = false;
+        int t = m_rPlot.GetTop();
+        int l = m_rPlot.GetLeft();
+//        int r = m_rPlot.GetRight();
+        int h = m_rPlot.GetHeight();
+        int w = m_rPlot.GetWidth();
+        pDC.Blit(l, t, w, h, &m_mDC, l, t);
+    }
+    drawGraticule(pDC);
+    m_mDC.SetBrush(wxNullBrush);
+    m_mDC.SelectObject(wxNullBitmap);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotPanel::drawGraticule(wxAutoBufferedPaintDC& pDC)
+{
+    int p;
+    char buf[15];
+    wxString s;
+
+    // Vertical gridlines
+    pDC.SetPen(m_penShortDash);
+    for(p = (PLOT_BORDER + XLEFT_OFFSET + GRID_INCREMENT); p < ((m_rGrid.GetWidth() - XLEFT_OFFSET) + GRID_INCREMENT); p += GRID_INCREMENT)
+    {
+        pDC.DrawLine(p, (m_rGrid.GetHeight() + PLOT_BORDER), p, PLOT_BORDER);
+    }
+    // Horizontal gridlines
+    pDC.SetPen(m_penDotDash);
+    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
+    {
+        pDC.DrawLine(PLOT_BORDER + XLEFT_OFFSET, (p + PLOT_BORDER), (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), (p + PLOT_BORDER));
+    }
+    // Label the X-Axis
+    pDC.SetPen(wxPen(GREY_COLOR, 1));
+    for(p = GRID_INCREMENT; p < (m_rGrid.GetWidth() - YBOTTOM_OFFSET); p += GRID_INCREMENT)
+    {
+        sprintf(buf, "%1.1f Hz",(double)(p / 10));
+        pDC.DrawText(buf, p - PLOT_BORDER + XLEFT_OFFSET, m_rGrid.GetHeight() + YBOTTOM_OFFSET/2);
+    }
+    // Label the Y-Axis
+    //for(p = GRID_INCREMENT; p < (h - YBOTTOM_OFFSET); p += GRID_INCREMENT)
+    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
+    {
+        sprintf(buf, "%1.0f", (double)((m_rGrid.GetHeight() - p) * -10));
+        pDC.DrawText(buf, XLEFT_TEXT_OFFSET, p);
+    }
+}
+
+//-------------------------------------------------------------------------
+// paintEvent()
+//
+// Called by the system of by wxWidgets when the panel needs
+// to be redrawn. You can also trigger this call by calling
+// Refresh()/Update().
+//-------------------------------------------------------------------------
+void PlotPanel::OnPaint(wxPaintEvent & evt)
+{
+    wxAutoBufferedPaintDC pdc(this);
+    draw(pdc);
+}
+
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot.h
new file mode 100644 (file)
index 0000000..25309d3
--- /dev/null
@@ -0,0 +1,150 @@
+//==========================================================================
+// Name:            fdmdv2_plot.h
+// Purpose:         Declares simple wxWidgets application with GUI
+// Created:         Apr. 10, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+//#include "fdmdv2_main.h"
+#ifndef __FDMDV2_PLOT__
+#define __FDMDV2_PLOT__
+#include <wx/wx.h>
+#include <wx/aui/auibook.h>
+#include <wx/rawbmp.h>
+#include <wx/image.h>
+#include <wx/dcbuffer.h>
+
+#define MAX_ZOOM            7
+#define MAX_BMP_X           (400 * MAX_ZOOM)
+#define MAX_BMP_Y           (400 * MAX_ZOOM)
+#define DATA_LINE_HEIGHT    10
+#define TEXT_BASELINE_OFFSET_Y  -5
+
+
+#define wxUSE_FILEDLG       1
+#define wxUSE_LIBPNG        1
+#define wxUSE_LIBJPEG       1
+#define wxUSE_GIF           1
+#define wxUSE_PCX           1
+#define wxUSE_LIBTIFF       1
+
+#define PLOT_BORDER         12
+#define XLEFT_OFFSET        40
+#define XLEFT_TEXT_OFFSET   6
+#define YBOTTOM_OFFSET      20
+#define YBOTTOM_TEXT_OFFSET 15
+#define GRID_INCREMENT      50
+
+#define BLACK_COLOR         wxColor(0x00, 0x00, 0x00)
+#define GREY_COLOR          wxColor(0x80, 0x80, 0x80)
+#define DARK_GREY_COLOR     wxColor(0x40, 0x40, 0x40)
+#define MEDIUM_GREY_COLOR   wxColor(0xC0, 0xC0, 0xC0)
+#define LIGHT_GREY_COLOR    wxColor(0xE0, 0xE0, 0xE0)
+#define VERY_LTGREY_COLOR   wxColor(0xF8, 0xF8, 0xF8)
+#define WHITE_COLOR         wxColor(0xFF, 0xFF, 0xFF)
+
+#define DARK_BLUE_COLOR     wxColor(0x00, 0x00, 0x60)
+#define BLUE_COLOR          wxColor(0x00, 0x00, 0xFF)
+#define LIGHT_BLUE_COLOR    wxColor(0x80, 0x80, 0xFF)
+
+#define RED_COLOR           wxColor(0xFF, 0x5E, 0x5E)
+#define LIGHT_RED_COLOR     wxColor(0xFF, 0xE0, 0xE0)
+#define DARK_RED_COLOR      wxColor(0xFF, 0x00, 0x00)
+#define PINK_COLOR          wxColor(0xFF, 0x80, 0xFF)
+
+#define LIGHT_GREEN_COLOR   wxColor(0xE3, 0xFF, 0xE0)
+#define GREEN_COLOR         wxColor(0x95, 0xFF, 0x8A)
+#define DARK_GREEN_COLOR    wxColor(0x20, 0xFF, 0x08)
+#define VERY_GREEN_COLOR    wxColor(0x00, 0xFF, 0x00)
+
+#define YELLOW_COLOR        wxColor(0xFF, 0xFF, 0x5E)
+#define LIGHT_YELLOW_COLOR  wxColor(0xFF, 0xFF, 0xB5)
+#define DARK_YELLOW_COLOR   wxColor(0xFF, 0xFF, 0x08)
+
+class MainFrame;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotPanel
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotPanel : public wxPanel
+{
+    public:
+        PlotPanel(wxFrame* parent);
+        ~PlotPanel();
+        wxPen               m_penShortDash;
+        wxPen               m_penDotDash;
+        wxPen               m_penSolid;
+        wxRect              m_rCtrlPrev;
+        wxRect              m_rCtrl;
+        wxRect              m_rGrid;
+        wxRect              m_rPlot;
+        MainFrame           *m_pTopFrame;
+        wxAuiNotebook       *m_pNoteBook;
+        double              m_label_size;
+        wxSize              m_Bufsz;
+        bool                m_newdata;
+        wxImage             m_oImage;
+        wxBitmap            *m_pBmp;
+        wxNativePixelData   *m_pPix;
+
+        // some useful events
+        void            OnMouseMove(wxMouseEvent& event);
+        virtual void    OnMouseLeftDown(wxMouseEvent& event);
+        void            OnMouseLeftUp(wxMouseEvent& event);
+        virtual void    OnMouseRightDown(wxMouseEvent& event);
+        void            OnMouseWheelMoved(wxMouseEvent& event);
+        void            OnClose(wxCloseEvent& event ){ event.Skip(); }
+        void            OnSize( wxSizeEvent& event );
+        void            OnErase(wxEraseEvent& event);
+        void            OnPaint(wxPaintEvent& event);
+        //void OnUpdateUI( wxUpdateUIEvent& event ){ event.Skip(); }
+
+        void            paintEvent(wxPaintEvent & evt);
+        virtual void    draw(wxAutoBufferedPaintDC&  pdc);
+        virtual void    drawGraticule(wxAutoBufferedPaintDC&  pdc);
+        virtual double  SetZoomFactor(double zf);
+        virtual double  GetZoomFactor(double zf);
+        virtual void    OnShow(wxShowEvent& event);
+        virtual double  GetLabelSize();
+        virtual void    SetLabelSize(double size);
+
+    protected:
+        int             m_x;
+        int             m_y;
+        int             m_left;
+        int             m_top;
+        int             m_prev_w;
+        int             m_prev_h;
+        int             m_prev_x;
+        int             m_prev_y;
+        bool            m_use_bitmap;
+        bool            m_clip;
+        bool            m_rubberBand;
+        bool            m_mouseDown;
+        bool            m_firstPass;
+        double          m_zoomFactor;
+        int             m_greyscale;
+        int             m_line_color;
+    DECLARE_EVENT_TABLE()
+};
+#endif //__FDMDV2_PLOT__
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scalar.cpp b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scalar.cpp
new file mode 100644 (file)
index 0000000..9a794f5
--- /dev/null
@@ -0,0 +1,344 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scalar.cpp
+// Purpose:         Plots scalar amplitude against time
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_main.h"
+#include "fdmdv2_plot_scalar.h"
+
+BEGIN_EVENT_TABLE(PlotScalar, PlotPanel)
+    EVT_PAINT           (PlotScalar::OnPaint)
+    EVT_MOTION          (PlotScalar::OnMouseMove)
+    EVT_MOUSEWHEEL      (PlotScalar::OnMouseWheelMoved)
+    EVT_SIZE            (PlotScalar::OnSize)
+    EVT_SHOW            (PlotScalar::OnShow)
+//    EVT_ERASE_BACKGROUND(PlotScalar::OnErase)
+END_EVENT_TABLE()
+
+//----------------------------------------------------------------
+// PlotScalar()
+//----------------------------------------------------------------
+PlotScalar::PlotScalar(wxFrame* parent, 
+                       int    channels,           // number on channels to plot
+                      float  t_secs,             // time covered by entire x axis in seconds
+                      float  sample_period_secs, // time between each sample in seconds
+                      float  a_min,              // min ampltude of samples being plotted
+                      float  a_max,              // max ampltude of samples being plotted
+                      float  graticule_t_step,   // time step of x (time) axis graticule in seconds
+                      float  graticule_a_step,   // step of amplitude axis graticule
+                      const char a_fmt[],        // printf format string for amplitude axis labels
+                       int    mini                // true for mini-plot - don't draw graticule
+                      ): PlotPanel(parent)
+{
+    int i;
+
+    m_rCtrl = GetClientRect();
+
+    m_channels = channels;
+    m_t_secs = t_secs;
+    m_sample_period_secs = sample_period_secs;
+    m_a_min = a_min;
+    m_a_max = a_max;
+    m_graticule_t_step = graticule_t_step;
+    m_graticule_a_step = graticule_a_step;
+    assert(strlen(a_fmt) < 15);
+    strcpy(m_a_fmt, a_fmt);
+    m_mini = mini;
+    m_bar_graph = 0;
+    m_logy = 0;
+
+    // work out number of samples we will store and allocate storage
+
+    m_samples = m_t_secs/m_sample_period_secs;
+    m_mem = new float[m_samples*m_channels];
+
+    for(i = 0; i < m_samples*m_channels; i++)
+    {
+        m_mem[i] = 0.0;
+    }
+}
+
+//----------------------------------------------------------------
+// ~PlotScalar()
+//----------------------------------------------------------------
+PlotScalar::~PlotScalar()
+{
+    delete m_mem;
+}
+
+//----------------------------------------------------------------
+// add_new_sample()
+//----------------------------------------------------------------
+void PlotScalar::add_new_sample(int channel, float sample)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+    for(i = 0; i < m_samples-1; i++)
+    {
+        m_mem[offset+i] = m_mem[offset+i+1];
+    }
+    m_mem[offset+m_samples-1] = sample;
+}
+
+//----------------------------------------------------------------
+// add_new_samples()
+//----------------------------------------------------------------
+void  PlotScalar::add_new_samples(int channel, float samples[], int length)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+   for(i = 0; i < m_samples-length; i++)
+        m_mem[offset+i] = m_mem[offset+i+length];
+    for(; i < m_samples; i++)
+       m_mem[offset+i] = *samples++;
+}
+
+//----------------------------------------------------------------
+// add_new_short_samples()
+//----------------------------------------------------------------
+void  PlotScalar::add_new_short_samples(int channel, short samples[], int length, float scale_factor)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+    for(i = 0; i < m_samples-length; i++)
+        m_mem[offset+i] = m_mem[offset+i+length];
+    for(; i < m_samples; i++)
+       m_mem[offset+i] = (float)*samples++/scale_factor;
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotScalar::draw(wxAutoBufferedPaintDC&  dc)
+{
+    float index_to_px;
+    float a_to_py;
+    int   i;
+    int   prev_x, prev_y;
+    float a;
+
+    m_rCtrl = GetClientRect();
+    m_rGrid = m_rCtrl;
+    if (!m_mini)
+        m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    //printf("h %d w %d\n", m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
+    //printf("h %d w %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
+
+    // black background
+
+    dc.Clear();
+    if (m_mini)
+        m_rPlot = wxRect(0, 0, m_rGrid.GetWidth(), m_rGrid.GetHeight());        
+    else
+        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+   
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+
+    index_to_px = (float)m_rGrid.GetWidth()/m_samples;
+    a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
+
+    wxPen pen;
+    pen.SetColour(DARK_GREEN_COLOR);
+    pen.SetWidth(1);
+    dc.SetPen(pen);
+
+    // draw all samples
+
+    prev_x = prev_y = 0; // stop warning
+
+    // plot each channel 
+
+    int offset, x, y;
+    for(offset=0; offset<m_channels*m_samples; offset+=m_samples) {
+
+        for(i = 0; i < m_samples; i++) {
+            a = m_mem[offset+i];
+            if (a < m_a_min) a = m_a_min;
+            if (a > m_a_max) a = m_a_max;
+
+            // invert y axis and offset by minimum
+
+            y = m_rGrid.GetHeight() - a_to_py * a + m_a_min*a_to_py;
+
+            // regular point-point line graph
+
+            x = index_to_px * i;
+
+            // put inside plot window
+
+            if (!m_mini) {
+                x += PLOT_BORDER + XLEFT_OFFSET;
+                y += PLOT_BORDER;
+            }
+
+            if (m_bar_graph) {
+
+                if (m_logy) {
+
+                    // can't take log(0)
+
+                    assert(m_a_min > 0.0); 
+                    assert(m_a_max > 0.0);
+
+                    float norm = (log10(a) - log10(m_a_min))/(log10(m_a_max) - log10(m_a_min));
+                    y = m_rGrid.GetHeight()*(1.0 - norm);
+                } else {
+                    y = m_rGrid.GetHeight() - a_to_py * a + m_a_min*a_to_py;
+                }
+
+                // use points to make a bar graph
+
+                int x1, x2, y1;
+
+                x1 = index_to_px * ((float)i - 0.5);
+                x2 = index_to_px * ((float)i + 0.5);
+                y1 = m_rGrid.GetHeight();
+                x1 += PLOT_BORDER + XLEFT_OFFSET; x2 += PLOT_BORDER + XLEFT_OFFSET;
+                y1 += PLOT_BORDER;
+                dc.DrawLine(x1, y1, x1, y); dc.DrawLine(x1, y, x2, y); dc.DrawLine(x2, y, x2, y1);
+            }
+            else {
+                if (i)
+                    dc.DrawLine(x, y, prev_x, prev_y);
+                prev_x = x; prev_y = y;
+            }
+        }
+    }
+
+    drawGraticule(dc);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotScalar::drawGraticule(wxAutoBufferedPaintDC&  dc)
+{
+    float    t, a;
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    sec_to_px;
+    float    a_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    sec_to_px = (float)m_rGrid.GetWidth()/m_t_secs;
+    a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Vertical gridlines
+
+    dc.SetPen(m_penShortDash);
+    for(t=0; t<=m_t_secs; t+=m_graticule_t_step) {
+       x = t*sec_to_px;
+       if (m_mini) {
+            dc.DrawLine(x, m_rGrid.GetHeight(), x, 0);
+        }
+        else {
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        }
+        if (!m_mini) {
+            sprintf(buf, "%2.1fs", t);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+        }
+    }
+
+    // Horizontal gridlines
+
+    dc.SetPen(m_penDotDash);
+    for(a=m_a_min; a<m_a_max; ) {
+        if (m_logy) {
+            float norm = (log10(a) - log10(m_a_min))/(log10(m_a_max) - log10(m_a_min));
+            y = m_rGrid.GetHeight()*(1.0 - norm);
+        }
+       else {
+            y = m_rGrid.GetHeight() - a*a_to_py + m_a_min*a_to_py;
+        }
+       if (m_mini) {
+            dc.DrawLine(0, y, m_rGrid.GetWidth(), y);
+        }
+        else {
+            y += PLOT_BORDER;
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        }
+        if (!m_mini) {
+            sprintf(buf, m_a_fmt, a);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+        }
+
+        if (m_logy) {
+            // m_graticule_a_step ==  0.1 means 10 steps/decade
+            float log10_step_size = floor(log10(a));
+            a += pow(10,log10_step_size);
+        }
+        else {
+            a += m_graticule_a_step;
+        }
+   }
+
+
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotScalar::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotScalar::OnSize(wxSizeEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotScalar::OnShow(wxShowEvent& event)
+{
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scalar.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scalar.h
new file mode 100644 (file)
index 0000000..4b668ff
--- /dev/null
@@ -0,0 +1,78 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scalar.h
+// Purpose:         Defines a scalar plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SCALAR__
+#define __FDMDV2_PLOT_SCALAR__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotScalar
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotScalar: public PlotPanel
+{
+    public:
+
+    PlotScalar(wxFrame* parent,
+               int   channels,
+              float t_secs, 
+              float sample_period_secs,
+              float a_min,
+              float a_max,
+              float graticule_t_step,   
+              float graticule_a_step,
+              const char  a_fmt[],
+               int   mini
+              );
+        ~PlotScalar();
+         void add_new_sample(int channel, float sample);
+         void add_new_samples(int channel, float samples[], int length);
+         void add_new_short_samples(int channel, short samples[], int length, float scale_factor);
+         void setBarGraph(int bar_graph) { m_bar_graph = bar_graph; }
+         void setLogY(int logy) { m_logy = logy; }
+
+    protected:
+
+         int      m_channels;
+        float    m_t_secs;
+        float    m_sample_period_secs;
+        float    m_a_min;
+        float    m_a_max;
+        float    m_graticule_t_step;   
+        float    m_graticule_a_step;
+        char     m_a_fmt[15];
+         int      m_mini;
+        int      m_samples;
+        float   *m_mem;              
+         int      m_bar_graph;                 // non zero to plot bar graphs 
+         int      m_logy;                      // plot graph on log scale
+
+         void draw(wxAutoBufferedPaintDC&  dc);
+         void drawGraticule(wxAutoBufferedPaintDC&  dc);
+         void OnPaint(wxPaintEvent& event);
+         void OnSize(wxSizeEvent& event);
+         void OnShow(wxShowEvent& event);
+
+         DECLARE_EVENT_TABLE()
+};
+
+#endif // __FDMDV2_PLOT_SCALAR__
+
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scatter.cpp b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scatter.cpp
new file mode 100644 (file)
index 0000000..d7e88c7
--- /dev/null
@@ -0,0 +1,289 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scatter.cpp
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
+// Created:         June 24, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_plot_scatter.h"
+
+BEGIN_EVENT_TABLE(PlotScatter, PlotPanel)
+    EVT_PAINT           (PlotScatter::OnPaint)
+    EVT_MOTION          (PlotScatter::OnMouseMove)
+    EVT_MOUSEWHEEL      (PlotScatter::OnMouseWheelMoved)
+    EVT_SIZE            (PlotScatter::OnSize)
+    EVT_SHOW            (PlotScatter::OnShow)
+//    EVT_ERASE_BACKGROUND(PlotScatter::OnErase)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// PlotScatter
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotScatter::PlotScatter(wxFrame* parent) : PlotPanel(parent)
+{
+    int i;
+
+    for(i=0; i < SCATTER_MEM_SYMS_MAX; i++)
+    {
+        m_mem[i].real = 0.0;
+        m_mem[i].imag = 0.0;
+    }
+
+    m_filter_max_xy = m_filter_max_y = 0.1;
+
+    // defaults so we start off with something sensible
+
+    Nsym = 14+1;
+    scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
+    assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
+
+    Ncol = 0;
+    memset(eye_mem, 0, sizeof(eye_mem));
+
+    mode = PLOT_SCATTER_MODE_SCATTER;
+}
+
+// changing number of carriers changes number of symbols to plot
+void PlotScatter::setNc(int Nc) {
+    Nsym = Nc;
+    assert(Nsym <= (MODEM_STATS_NC_MAX+1));
+    scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
+    assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotScatter::draw(wxAutoBufferedPaintDC& dc)
+{
+    float x_scale;
+    float y_scale;
+    int   i,j;
+    int   x;
+    int   y;
+    wxColour sym_to_colour[] = {wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255), 
+                                wxColor(255,255,0),
+                                wxColor(255,255,255),
+                                wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255), 
+                                wxColor(255,255,0),
+                                wxColor(255,255,255),
+                                wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255)
+    };
+
+    m_rCtrl = GetClientRect();
+    m_rGrid = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    // black background
+
+    dc.Clear();
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+    wxPen pen;
+    pen.SetWidth(1); // note this is ignored by DrawPoint
+
+    if (mode == PLOT_SCATTER_MODE_SCATTER) {
+
+        // automatically scale, first measure the maximum value
+
+        float max_xy = 1E-12;
+        float real,imag;
+        for(i=0; i< scatterMemSyms; i++) {
+            real = fabs(m_mem[i].real);
+            imag = fabs(m_mem[i].imag);
+            if (real > max_xy)
+                max_xy = real;
+            if (imag > max_xy)
+                max_xy = imag;
+        }
+
+        // smooth it out and set a lower limit to prevent divide by 0 issues
+
+        m_filter_max_xy = BETA*m_filter_max_xy + (1 - BETA)*2.5*max_xy;
+        if (m_filter_max_xy < 0.001)
+            m_filter_max_xy = 0.001;
+
+        // quantise to log steps to prevent scatter scaling bobbing about too
+        // much as scaling varies
+
+        float quant_m_filter_max_xy = exp(floor(0.5+log(m_filter_max_xy)));
+        //printf("max_xy: %f m_filter_max_xy: %f quant_m_filter_max_xy: %f\n", max_xy, m_filter_max_xy, quant_m_filter_max_xy);
+
+        x_scale = (float)m_rGrid.GetWidth()/quant_m_filter_max_xy;
+        y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_xy;
+
+        // draw all samples
+
+        for(i = 0; i < scatterMemSyms; i++) {
+            x = x_scale * m_mem[i].real + m_rGrid.GetWidth()/2;
+            y = y_scale * m_mem[i].imag + m_rGrid.GetHeight()/2;
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            y += PLOT_BORDER;
+            pen.SetColour(sym_to_colour[i%Nsym]);
+            dc.SetPen(pen);
+            dc.DrawPoint(x, y);
+        }
+    }
+
+    if (mode == PLOT_SCATTER_MODE_EYE) {
+
+        pen.SetColour(DARK_GREEN_COLOR);
+        pen.SetWidth(1);
+        dc.SetPen(pen);
+
+        // automatically scale, first measure the maximum Y value
+
+        float max_y = 1E-12;
+        float min_y = 1E+12;
+        for(i=0; i<SCATTER_EYE_MEM_ROWS; i++) {
+            for(j=0; j<Ncol; j++) {
+                if (eye_mem[i][j] > max_y) {
+                    max_y = eye_mem[i][j];
+                }
+                if (eye_mem[i][j] < min_y) {
+                    min_y = eye_mem[i][j];
+                }
+            }
+        }
+        // smooth it out and set a lower limit to prevent divide by 0 issues
+
+        m_filter_max_y = BETA*m_filter_max_y + (1 - BETA)*2.5*max_y;
+        if (m_filter_max_y < 0.001)
+            m_filter_max_y = 0.001;
+
+        // quantise to log steps to prevent scatter scaling bobbing about too
+        // much as scaling varies
+
+        float quant_m_filter_max_y = exp(floor(0.5+log(m_filter_max_y)));
+        //printf("min_y: %4.3f max_y: %4.3f quant_m_filter_max_y: %4.3f\n", min_y, max_y, quant_m_filter_max_y);
+
+        x_scale = (float)m_rGrid.GetWidth()/Ncol;
+        y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_y;
+        //printf("GetWidth(): %d GetHeight(): %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
+
+        // plot eye traces row by row
+
+        int prev_x, prev_y;
+        prev_x = prev_y = 0;
+        for(i=0; i<SCATTER_EYE_MEM_ROWS; i++) {
+            //printf("row: ");
+            for(j=0; j<Ncol; j++) {
+                x = x_scale * j;
+                y = m_rGrid.GetHeight()*0.75 - y_scale * eye_mem[i][j];
+               //printf("%4d,%4d  ", x, y);
+                x += PLOT_BORDER + XLEFT_OFFSET;
+                y += PLOT_BORDER;
+                pen.SetColour(sym_to_colour[i%4]);
+                dc.SetPen(pen);
+                if (j)
+                    dc.DrawLine(x, y, prev_x, prev_y);
+                prev_x = x; prev_y = y;
+            }
+            //printf("\n");
+        }
+        
+    }
+}
+
+//----------------------------------------------------------------
+// add_new_samples()
+//----------------------------------------------------------------
+void PlotScatter::add_new_samples_scatter(COMP samples[])
+{
+    int i,j;
+
+    // shift memory
+
+    for(i = 0; i < scatterMemSyms - Nsym; i++)
+    {
+        m_mem[i] = m_mem[i+Nsym];
+    }
+
+    // new samples
+
+    for(j=0; i < scatterMemSyms; i++,j++)
+    {
+        m_mem[i] = samples[j];
+    }
+}
+
+/* add a row of eye samples, updating buffer */
+
+void PlotScatter::add_new_samples_eye(float samples[], int n)
+{
+    int i,j;
+
+    Ncol = n; /* this should be constant for a given modem config */
+
+    assert(n <= PLOT_SCATTER_EYE_MAX_SAMPLES_ROW);
+
+    // eye traces are arrnaged in rows, shift memory of traces
+
+    for(i=0; i<SCATTER_EYE_MEM_ROWS-1; i++) {
+        for(j=0; j<Ncol; j++) {
+            eye_mem[i][j] = eye_mem[i+1][j];
+        }
+    }
+
+    // new samples in last row
+
+    for(j=0; j<Ncol; j++) {
+        eye_mem[SCATTER_EYE_MEM_ROWS-1][j] = samples[j];
+    }
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotScatter::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotScatter::OnSize(wxSizeEvent& event)
+{
+    // todo: clear screen
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotScatter::OnShow(wxShowEvent& event)
+{
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scatter.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_scatter.h
new file mode 100644 (file)
index 0000000..b5e3352
--- /dev/null
@@ -0,0 +1,65 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scatter.h
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
+// Created:         June 24, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SCATTER__
+#define __FDMDV2_PLOT_SCATTER__
+
+#include "comp.h"
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+#define PLOT_SCATTER_MODE_SCATTER            0
+#define PLOT_SCATTER_MODE_EYE                1
+#define PLOT_SCATTER_EYE_MAX_SAMPLES_ROW    80
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotScatter
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotScatter : public PlotPanel
+{
+    public:
+        PlotScatter(wxFrame* parent);
+        ~PlotScatter(){};
+       void add_new_samples_scatter(COMP samples[]);
+       void add_new_samples_eye(float samples[], int n);
+       void setNc(int Nc);
+        void setEyeScatter(int eye_mode) {mode = eye_mode;}
+
+    protected:
+        int  mode;
+        COMP m_mem[SCATTER_MEM_SYMS_MAX];
+        COMP m_new_samples[MODEM_STATS_NC_MAX+1];
+        float eye_mem[SCATTER_EYE_MEM_ROWS][PLOT_SCATTER_EYE_MAX_SAMPLES_ROW];
+
+        void draw(wxAutoBufferedPaintDC&  dc);
+        void OnPaint(wxPaintEvent& event);
+        void OnSize(wxSizeEvent& event);
+        void OnShow(wxShowEvent& event);
+
+        DECLARE_EVENT_TABLE()
+
+    private:
+        int   Nsym;
+        int   Ncol;
+        int   scatterMemSyms;
+        float m_filter_max_xy, m_filter_max_y;
+};
+
+#endif //__FDMDV2_PLOT_SCATTER__
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_spectrum.cpp b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_spectrum.cpp
new file mode 100644 (file)
index 0000000..1f5be59
--- /dev/null
@@ -0,0 +1,267 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.cpp
+// Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 23, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+
+#include "fdmdv2_main.h"
+
+extern float g_avmag[];                 // average mag data passed to draw() 
+void fdmdv2_clickTune(float frequency); // callback to pass new click freq
+
+BEGIN_EVENT_TABLE(PlotSpectrum, PlotPanel)
+    EVT_MOTION          (PlotSpectrum::OnMouseMove)
+    EVT_LEFT_DOWN       (PlotSpectrum::OnMouseLeftDown)
+    EVT_LEFT_DCLICK     (PlotSpectrum::OnMouseLeftDoubleClick)
+    EVT_LEFT_UP         (PlotSpectrum::OnMouseLeftUp)
+    EVT_MOUSEWHEEL      (PlotSpectrum::OnMouseWheelMoved)
+    EVT_PAINT           (PlotSpectrum::OnPaint)
+    EVT_SHOW            (PlotSpectrum::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotSpectrum
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotSpectrum::PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, 
+                           float min_mag_db, float max_mag_db, bool clickTune): PlotPanel(parent)
+{
+    m_greyscale     = 0;
+    m_Bufsz         = GetMaxClientSize();
+    m_newdata       = false;
+    m_firstPass     = true;
+    m_line_color    = 0;
+    SetLabelSize(10.0);
+
+    m_magdB         = magdB;
+    m_n_magdB       = n_magdB;     // number of points in magdB that covers 0 ... MAX_F_HZ of spectrum
+    m_max_mag_db    = max_mag_db;
+    m_min_mag_db    = min_mag_db;
+    m_rxFreq        = 0.0;
+    m_clickTune     = clickTune;
+}
+
+//----------------------------------------------------------------
+// ~PlotSpectrum()
+//----------------------------------------------------------------
+PlotSpectrum::~PlotSpectrum()
+{
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotSpectrum::OnSize(wxSizeEvent& event) {
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotSpectrum::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotSpectrum::OnShow(wxShowEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotSpectrum::draw(wxAutoBufferedPaintDC& dc)
+{
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.  We need to work this out every time we draw
+    // as OnSize() may not be called before OnPaint(), for example when a new tab
+    // is selected
+
+    m_rGrid  = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    dc.Clear();
+
+    // black background
+
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+
+    // draw spectrum
+
+    int   x, y, prev_x, prev_y, index;
+    float index_to_px, mag_dB_to_py, mag;
+
+    m_newdata = false;
+
+    wxPen pen;
+    pen.SetColour(DARK_GREEN_COLOR);
+    pen.SetWidth(1);
+    dc.SetPen(pen);
+
+    index_to_px = (float)m_rGrid.GetWidth()/m_n_magdB;
+    mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
+
+    prev_x = PLOT_BORDER + XLEFT_OFFSET;
+    prev_y = PLOT_BORDER;
+    for(index = 0; index < m_n_magdB; index++)
+    {
+        x = index*index_to_px;
+        mag = m_magdB[index];
+        if (mag > m_max_mag_db) mag = m_max_mag_db;
+        if (mag < m_min_mag_db) mag = m_min_mag_db;
+        y = -(mag - m_max_mag_db) * mag_dB_to_py;
+
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        y += PLOT_BORDER;
+
+        if (index)
+            dc.DrawLine(x, y, prev_x, prev_y);
+        prev_x = x; prev_y = y;
+    }
+
+    // and finally draw Graticule
+
+    drawGraticule(dc);
+
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC&  dc)
+{
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    f, mag, freq_hz_to_px, mag_dB_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+    mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Check if small screen size means text will overlap
+
+    int textXStep = STEP_F_HZ*freq_hz_to_px;
+    int textYStep = STEP_MAG_DB*mag_dB_to_py;
+    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
+    GetTextExtent(buf, &text_w, &text_h);
+    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
+    //printf("text_w: %d textXStep: %d text_h: %d textYStep: %d  overlappedText: %d\n", text_w, textXStep, 
+    //      text_h, textYStep, overlappedText);
+
+    // Vertical gridlines
+
+    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) {
+       x = f*freq_hz_to_px;
+       x += PLOT_BORDER + XLEFT_OFFSET;
+
+        dc.SetPen(m_penShortDash);
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        dc.SetPen(wxPen(BLACK_COLOR, 1));
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+
+        sprintf(buf, "%4.0fHz", f);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+    }
+
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
+    // Horizontal gridlines
+
+    dc.SetPen(m_penDotDash);
+    for(mag=m_min_mag_db; mag<=m_max_mag_db; mag+=STEP_MAG_DB) {
+       y = -(mag - m_max_mag_db) * mag_dB_to_py;
+       y += PLOT_BORDER;
+       dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                   (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        sprintf(buf, "%3.0fdB", mag);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+    }
+
+    // red rx tuning line
+    
+    if (m_rxFreq != 0.0) {
+        dc.SetPen(wxPen(RED_COLOR, 2));
+        x = m_rxFreq*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
+        dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnMouseDown()
+//-------------------------------------------------------------------------
+void PlotSpectrum::OnMouseLeftDoubleClick(wxMouseEvent& event)
+{
+    m_mouseDown = true;
+    wxClientDC dc(this);
+
+    wxPoint pt(event.GetLogicalPosition(dc));
+
+    // map x coord to edges of actual plot
+    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
+    pt.y -= PLOT_BORDER;
+
+    // valid click if inside of plot
+    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0) && m_clickTune) {
+        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+        float clickFreq = (float)pt.x/freq_hz_to_px;
+
+        // see PlotWaterfall::OnMouseDown()
+
+        fdmdv2_clickTune(clickFreq);
+    }
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_spectrum.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_spectrum.h
new file mode 100644 (file)
index 0000000..271eeb9
--- /dev/null
@@ -0,0 +1,58 @@
+//==========================================================================
+// Name:            fdmdv2_plot_spectrum.h
+// Purpose:         Defines a spectrum plot derived from fdmdv2_plot class.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SPECTRUM__
+#define __FDMDV2_PLOT_SPECTRUM__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class Waterfall
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotSpectrum : public PlotPanel
+{
+    public:
+    PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, 
+                 float min_mag_db=MIN_MAG_DB, float max_mag_db=MAX_MAG_DB, bool clickTune=true);
+        ~PlotSpectrum();
+        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
+        void setFreqScale(int n_magdB) { m_n_magdB = n_magdB; }
+
+    protected:
+        void        OnPaint(wxPaintEvent& event);
+        void        OnSize(wxSizeEvent& event);
+        void        OnShow(wxShowEvent& event);
+        void        drawGraticule(wxAutoBufferedPaintDC& dc);
+        void        draw(wxAutoBufferedPaintDC& dc);
+        void        OnMouseLeftDoubleClick(wxMouseEvent& event);
+
+   private:
+        float       m_rxFreq;
+        float       m_max_mag_db;
+        float       m_min_mag_db;
+        float      *m_magdB;
+        int         m_n_magdB;  
+        bool        m_clickTune;
+
+        DECLARE_EVENT_TABLE()
+};
+
+#endif //__FDMDV2_PLOT_SPECTRUM__
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_waterfall.cpp b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_waterfall.cpp
new file mode 100644 (file)
index 0000000..cdbe01e
--- /dev/null
@@ -0,0 +1,483 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.cpp
+// Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_main.h"
+
+extern float g_avmag[];                 // av mag spec passed in to draw() 
+void fdmdv2_clickTune(float frequency); // callback to pass new click freq
+
+BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel)
+    EVT_PAINT           (PlotWaterfall::OnPaint)
+    EVT_MOTION          (PlotWaterfall::OnMouseMove)
+    EVT_LEFT_DCLICK     (PlotWaterfall::OnMouseLeftDoubleClick)
+    EVT_RIGHT_DOWN      (PlotWaterfall::OnMouseRightDown)
+    EVT_LEFT_UP         (PlotWaterfall::OnMouseLeftUp)
+    EVT_MOUSEWHEEL      (PlotWaterfall::OnMouseWheelMoved)
+    EVT_SIZE            (PlotWaterfall::OnSize)
+    EVT_SHOW            (PlotWaterfall::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class WaterfallPlot
+//
+// @class   WaterfallPlot
+// @author  David Witten
+// @date    $(Date)
+// @file    $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotWaterfall::PlotWaterfall(wxFrame* parent, bool graticule, int colour): PlotPanel(parent)
+{
+
+    for(int i = 0; i < 255; i++)
+    {
+        m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0);
+    }
+    m_graticule     = graticule;
+    m_colour        = colour;
+    m_Bufsz         = GetMaxClientSize();
+    m_newdata       = false;
+    m_firstPass     = true;
+    m_line_color    = 0;
+    m_modem_stats_max_f_hz = MODEM_STATS_MAX_F_HZ;
+
+    SetLabelSize(10.0);
+
+    m_pBmp = NULL;
+    m_max_mag = MAX_MAG_DB;
+    m_min_mag = MIN_MAG_DB;
+}
+
+// When the window size gets set we can work outthe size of the window
+// we plot in and allocate a bit map of the correct size
+void PlotWaterfall::OnSize(wxSizeEvent& event) 
+{
+    // resize bit map
+
+    delete m_pBmp;
+    
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid  = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    // we want a bit map the size of m_rGrid
+
+    m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
+
+    m_dT = DT;
+}
+
+//----------------------------------------------------------------
+// paintEvent()
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+// Called by the system of by wxWidgets when the panel needs
+// to be redrawn. You can also trigger this call by calling
+// Refresh()/Update().
+//----------------------------------------------------------------
+void PlotWaterfall::OnPaint(wxPaintEvent & evt)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotWaterfall::OnShow(wxShowEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// ~PlotWaterfall()
+//----------------------------------------------------------------
+PlotWaterfall::~PlotWaterfall()
+{
+}
+
+//----------------------------------------------------------------
+// heatmap()
+// map val to a rgb colour
+// from http://eddiema.ca/2011/01/21/c-sharp-heatmaps/
+//----------------------------------------------------------------
+unsigned PlotWaterfall::heatmap(float val, float min, float max)
+{
+    unsigned r = 0;
+    unsigned g = 0;
+    unsigned b = 0;
+
+    val = (val - min) / (max - min);
+    if(val <= 0.2)
+    {
+        b = (unsigned)((val / 0.2) * 255);
+    }
+    else if(val >  0.2 &&  val <= 0.7)
+    {
+        b = (unsigned)((1.0 - ((val - 0.2) / 0.5)) * 255);
+    }
+    if(val >= 0.2 &&  val <= 0.6)
+    {
+        g = (unsigned)(((val - 0.2) / 0.4) * 255);
+    }
+    else if(val >  0.6 &&  val <= 0.9)
+    {
+        g = (unsigned)((1.0 - ((val - 0.6) / 0.3)) * 255);
+    }
+    if(val >= 0.5)
+    {
+        r = (unsigned)(((val - 0.5) / 0.5) * 255);
+    }
+    //printf("%f %x %x %x\n", val, r, g, b);
+    return  (b << 16) + (g << 8) + r;
+}
+
+bool PlotWaterfall::checkDT(void)
+{
+    // Check dY is > 1 pixel before proceeding. For small screens
+    // and large WATERFALL_SECS_Y we might have less than one
+    // block per pixel.  In this case increase m_dT and perform draw
+    // less often
+
+    float px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    float dy = m_dT * px_per_sec;
+    
+    if (dy < 1.0) {
+        m_dT += DT;
+        return false;
+    }
+    else
+        return true;
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotWaterfall::draw(wxAutoBufferedPaintDC& dc)
+{
+
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    if (m_pBmp == NULL) 
+    {
+        // we want a bit map the size of m_rGrid
+        m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
+    }
+
+    dc.Clear();
+
+    if(m_newdata)
+    {
+        m_newdata = false;
+        plotPixelData();
+        dc.DrawBitmap(*m_pBmp, PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
+        m_dT = DT;
+    }
+    else 
+    {
+
+        // no data to plot so just erase to black.  Blue looks nicer
+        // but is same colour as low amplitude signal
+
+        // Bug on Linux: When Stop is pressed this code doesn't erase
+        // the lower 25% of the Waterfall Window
+
+        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+        wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+        dc.SetBrush(ltGraphBkgBrush);
+        dc.SetPen(wxPen(BLACK_COLOR, 0));
+        dc.DrawRectangle(m_rPlot);
+    }
+    drawGraticule(dc);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
+{
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    f, time, freq_hz_to_px, time_s_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+    time_s_to_py = (float)m_rGrid.GetHeight()/WATERFALL_SECS_Y;
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Check if small screen size means text will overlap
+
+    int textXStep = STEP_F_HZ*freq_hz_to_px;
+    int textYStep = WATERFALL_SECS_STEP*time_s_to_py;
+    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
+    GetTextExtent(buf, &text_w, &text_h);
+    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
+
+    // Major Vertical gridlines and legend
+    //dc.SetPen(m_penShortDash);
+    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+
+        if (m_graticule)
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        else
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+            
+        sprintf(buf, "%4.0fHz", f);
+        GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+    }
+
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
+    // Horizontal gridlines
+    dc.SetPen(m_penDotDash);
+    for(time=0; time<=WATERFALL_SECS_Y; time+=WATERFALL_SECS_STEP) {
+       y = m_rGrid.GetHeight() - time*time_s_to_py;
+       y += PLOT_BORDER;
+
+        if (m_graticule)
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        sprintf(buf, "%3.0fs", time);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+   }
+
+    // red rx tuning line
+    dc.SetPen(wxPen(RED_COLOR, 2));
+    x = m_rxFreq*freq_hz_to_px;
+    x += PLOT_BORDER + XLEFT_OFFSET;
+    //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
+    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
+    
+}
+
+//-------------------------------------------------------------------------
+// plotPixelData()
+//-------------------------------------------------------------------------
+void PlotWaterfall::plotPixelData()
+{
+    float       spec_index_per_px;
+    float       intensity_per_dB;
+    float       px_per_sec;
+    int         index;
+    float       dy;
+    int         dy_blocks;
+    int         b;
+    int         px;
+    int         py;
+    int         intensity;
+
+    /*
+      Design Notes:
+
+      The height in pixels represents WATERFALL_SECS_Y of data.  Every DT
+      seconds we get a vector of MODEM_STATS_NSPEC spectrum samples which we use
+      to update the last row.  The height of each row is dy pixels, which
+      maps to DT seconds.  We call each dy high rectangle of pixels a
+      block.
+
+    */
+
+    // determine dy, the height of one "block"
+    px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    dy = m_dT * px_per_sec;
+
+    // number of dy high blocks in spectrogram
+    dy_blocks = m_rGrid.GetHeight()/ dy;
+
+    // update min and max amplitude estimates
+    float max_mag = MIN_MAG_DB;
+
+    int min_fft_bin=((float)200/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
+    int max_fft_bin=((float)2800/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
+
+    for(int i=min_fft_bin; i<max_fft_bin; i++) 
+    {
+        if (g_avmag[i] > max_mag)
+        {
+            max_mag = g_avmag[i];
+        }
+    }
+
+    m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
+    m_min_mag = max_mag - 20.0;
+    //printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
+    //intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
+    intensity_per_dB  = (float)256 /(m_max_mag - m_min_mag);
+    spec_index_per_px = ((float)(MAX_F_HZ)/(float)m_modem_stats_max_f_hz)*(float)MODEM_STATS_NSPEC / (float) m_rGrid.GetWidth();
+
+    /*
+    printf("h %d w %d px_per_sec %d dy %d dy_blocks %d spec_index_per_px: %f\n", 
+       m_rGrid.GetHeight(), m_rGrid.GetWidth(), px_per_sec, 
+       dy, dy_blocks, spec_index_per_px);
+    */
+
+    // Shift previous bit map up one row of blocks ----------------------------
+    wxNativePixelData data(*m_pBmp);
+    wxNativePixelData::Iterator bitMapStart(data);
+    wxNativePixelData::Iterator p = bitMapStart;
+
+    for(b = 0; b < dy_blocks - 1; b++) 
+    {
+        wxNativePixelData::Iterator psrc = bitMapStart;
+        wxNativePixelData::Iterator pdest = bitMapStart;
+        pdest.OffsetY(data, dy * b);
+        psrc.OffsetY(data, dy * (b+1));
+
+        // copy one line of blocks
+
+        for(py = 0; py < dy; py++) 
+        {
+            wxNativePixelData::Iterator pdestRowStart = pdest;
+            wxNativePixelData::Iterator psrcRowStart = psrc;
+
+            for(px = 0; px < m_rGrid.GetWidth(); px++) 
+            {
+                pdest.Red() = psrc.Red();
+                pdest.Green() = psrc.Green();
+                pdest.Blue() = psrc.Blue();
+                pdest++;
+                psrc++;
+            }
+            pdest = pdestRowStart;
+            pdest.OffsetY(data, 1);
+            psrc = psrcRowStart;
+            psrc.OffsetY(data, 1);         
+        }
+    }
+
+    // Draw last line of blocks using latest amplitude data ------------------
+    p = bitMapStart;
+    p.OffsetY(data, dy *(dy_blocks - 1));
+    for(py = 0; py < dy; py++)
+    {
+        wxNativePixelData::Iterator rowStart = p;
+
+        for(px = 0; px < m_rGrid.GetWidth(); px++)
+        {
+            index = px * spec_index_per_px;
+            assert(index < MODEM_STATS_NSPEC);
+
+            intensity = intensity_per_dB * (g_avmag[index] - m_min_mag);
+            if(intensity > 255) intensity = 255;
+            if (intensity < 0) intensity = 0;
+            //printf("%d %f %d \n", index, g_avmag[index], intensity);
+
+            switch (m_colour) {
+            case 0:
+                p.Red() = m_heatmap_lut[intensity] & 0xff;
+                p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
+                p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
+                break;
+            case 1:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                p.Blue() = intensity;       
+                break;
+            case 2:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                if (intensity < 127)
+                    p.Blue() = intensity*2;
+                else
+                    p.Blue() = 255;
+                        
+                break;
+            }
+            ++p;
+        }
+        p = rowStart;
+        p.OffsetY(data, 1);
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseLeftDoubleClick(wxMouseEvent& event)
+{
+    m_mouseDown = true;
+    wxClientDC dc(this);
+
+    wxPoint pt(event.GetLogicalPosition(dc));
+
+    // map x coord to edges of actual plot
+    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
+    pt.y -= PLOT_BORDER;
+
+    // valid click if inside of plot
+    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0)) 
+    {
+        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+        float clickFreq = (float)pt.x/freq_hz_to_px;
+
+        // communicate back to other threads
+        fdmdv2_clickTune(clickFreq);
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseRightDown(wxMouseEvent& event)
+{
+    m_colour++;
+    if (m_colour == 3)
+        m_colour = 0;
+}
+
diff --git a/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_waterfall.h b/freedv/branches/1.2/freedv-dev/src/fdmdv2_plot_waterfall.h
new file mode 100644 (file)
index 0000000..f4896c6
--- /dev/null
@@ -0,0 +1,73 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.h
+// Purpose:         Defines a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_WATERFALL__
+#define __FDMDV2_PLOT_WATERFALL__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotWaterfall
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotWaterfall : public PlotPanel
+{
+    public:
+    PlotWaterfall(wxFrame* parent, bool graticule, int colour);
+        ~PlotWaterfall();
+        bool checkDT(void);
+        void setGreyscale(bool greyscale) { m_greyscale = greyscale; }
+        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
+        void setFs(int fs) { m_modem_stats_max_f_hz = fs/2; }
+
+    protected:
+        unsigned    m_heatmap_lut[256];
+
+        unsigned    heatmap(float val, float min, float max);
+
+        void        OnPaint(wxPaintEvent & evt);
+        void        OnSize(wxSizeEvent& event);
+        void        OnShow(wxShowEvent& event);
+        void        drawGraticule(wxAutoBufferedPaintDC&  dc);
+        void        draw(wxAutoBufferedPaintDC& dc);
+        void        plotPixelData();
+        void        OnMouseLeftDoubleClick(wxMouseEvent& event);
+        void        OnMouseRightDown(wxMouseEvent& event);
+
+    private:
+        float       m_dT;
+        float       m_rxFreq;
+        bool        m_graticule;
+        float       m_min_mag;
+        float       m_max_mag;
+        int         m_colour;
+        int         m_modem_stats_max_f_hz;
+
+        DECLARE_EVENT_TABLE()
+};
+
+#endif //__FDMDV2_PLOT_WATERFALL__
diff --git a/freedv/branches/1.2/freedv-dev/src/freedv.icns b/freedv/branches/1.2/freedv-dev/src/freedv.icns
new file mode 100644 (file)
index 0000000..5190e79
Binary files /dev/null and b/freedv/branches/1.2/freedv-dev/src/freedv.icns differ
diff --git a/freedv/branches/1.2/freedv-dev/src/hamlib.cpp b/freedv/branches/1.2/freedv-dev/src/hamlib.cpp
new file mode 100644 (file)
index 0000000..ff80b24
--- /dev/null
@@ -0,0 +1,160 @@
+//==========================================================================
+// Name:            hamlib.cpp
+//
+// Purpose:         Hamlib integration for FreeDV
+// Created:         May 2013
+// Authors:         Joel Stanley
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <hamlib.h>
+
+#include <vector>
+#include <algorithm>
+
+using namespace std;
+
+typedef std::vector<const struct rig_caps *> riglist_t;
+
+static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2);
+static int build_list(const struct rig_caps *rig, rig_ptr_t);
+
+Hamlib::Hamlib() : m_rig(NULL) {
+    /* Stop hamlib from spewing info to stderr. */
+    rig_set_debug(RIG_DEBUG_NONE);
+
+    /* Create sorted list of rigs. */
+    rig_load_all_backends();
+    rig_list_foreach(build_list, &m_rigList);
+    sort(m_rigList.begin(), m_rigList.end(), rig_cmp);
+
+    /* Reset debug output. */
+    rig_set_debug(RIG_DEBUG_VERBOSE);
+
+    m_rig = NULL;
+}
+
+Hamlib::~Hamlib() {
+       if(m_rig)
+               close();
+}
+
+static int build_list(const struct rig_caps *rig, rig_ptr_t rigList) {
+    ((riglist_t *)rigList)->push_back(rig); 
+    return 1;
+}
+
+static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2) {
+    /* Compare manufacturer. */
+    int r = strcasecmp(rig1->mfg_name, rig2->mfg_name);
+    if (r != 0)
+        return r < 0;
+
+    /* Compare model. */
+    r = strcasecmp(rig1->model_name, rig2->model_name);
+    if (r != 0)
+        return r < 0;
+
+    /* Compare rig ID. */
+    return rig1->rig_model < rig2->rig_model;
+}
+
+void Hamlib::populateComboBox(wxComboBox *cb) {
+
+    riglist_t::const_iterator rig = m_rigList.begin();
+    for (; rig !=m_rigList.end(); rig++) {
+        char name[128];
+        snprintf(name, 128, "%s %s", (*rig)->mfg_name, (*rig)->model_name); 
+        cb->Append(name);
+    }
+}
+
+bool Hamlib::connect(unsigned int rig_index, const char *serial_port, const int serial_rate) {
+    /* Look up model from index. */
+    if (rig_index >= m_rigList.size()) {
+        return false;
+    }
+    fprintf(stderr, "rig: %s %s (%d)\n", m_rigList[rig_index]->mfg_name,
+            m_rigList[rig_index]->model_name, m_rigList[rig_index]->rig_model);
+
+       if(m_rig) {
+               printf("Closing old hamlib instance!\n");
+               close();
+       }
+
+    /* Initialise, configure and open. */
+
+    m_rig = rig_init(m_rigList[rig_index]->rig_model);
+
+    if (!m_rig)
+        return false;
+
+    /* TODO we may also need civaddr for Icom */
+
+    strncpy(m_rig->state.rigport.pathname, serial_port, FILPATHLEN - 1);
+    if (serial_rate) {
+        m_rig->state.rigport.parm.serial.rate = serial_rate;
+    }
+    fprintf(stderr, "hamlib: setting serial rate: %d\n", m_rig->state.rigport.parm.serial.rate);
+
+    if (rig_open(m_rig) == RIG_OK) {
+        return true;
+    }
+
+    return false;
+}
+
+int Hamlib::get_serial_rate(void) {
+    return m_rig->state.rigport.parm.serial.rate;
+}
+
+int Hamlib::get_data_bits(void) {
+    return m_rig->state.rigport.parm.serial.data_bits;
+}
+
+int Hamlib::get_stop_bits(void) {
+    return m_rig->state.rigport.parm.serial.stop_bits;
+}
+
+bool Hamlib::ptt(bool press, wxString &hamlibError) {
+    fprintf(stderr,"Hamlib::ptt: %d\n", press);
+    hamlibError = "";
+
+    if(!m_rig)
+        return false;
+
+    /* TODO(Joel): make ON_DATA and ON configurable. */
+
+    ptt_t on = press ? RIG_PTT_ON : RIG_PTT_OFF;
+
+    /* TODO(Joel): what should the VFO option be? */
+
+    int retcode = rig_set_ptt(m_rig, RIG_VFO_CURR, on);
+    fprintf(stderr,"Hamlib::ptt: rig_set_ptt returned: %d\n", retcode);
+    if (retcode != RIG_OK ) {
+        fprintf(stderr, "rig_set_ptt: error = %s \n", rigerror(retcode));
+        hamlibError = rigerror(retcode);
+    }
+
+    return retcode == RIG_OK;
+}
+
+void Hamlib::close(void) {
+    if(m_rig) {
+        rig_close(m_rig);
+        rig_cleanup(m_rig);
+        m_rig = NULL;
+    }
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/hamlib.h b/freedv/branches/1.2/freedv-dev/src/hamlib.h
new file mode 100644 (file)
index 0000000..65af2d4
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef HAMLIB_H
+#define HAMLIB_H
+
+extern "C" {
+#include <hamlib/rig.h>
+}
+#include <wx/combobox.h>
+#include <vector>
+
+class Hamlib {
+
+    public:
+        Hamlib();
+        ~Hamlib();
+        void populateComboBox(wxComboBox *cb);
+        bool connect(unsigned int rig_index, const char *serial_port, const int serial_rate);
+        bool ptt(bool press, wxString &hamlibError);
+        void close(void);
+        int get_serial_rate(void);
+        int get_data_bits(void);
+        int get_stop_bits(void);
+
+        typedef std::vector<const struct rig_caps *> riglist_t;
+
+    private:
+        RIG *m_rig;
+        /* Sorted list of rigs. */
+        riglist_t m_rigList;
+};
+
+#endif /*HAMLIB_H*/
diff --git a/freedv/branches/1.2/freedv-dev/src/info.plist b/freedv/branches/1.2/freedv-dev/src/info.plist
new file mode 100644 (file)
index 0000000..8f0d4c3
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>CFBundleIconFile</key>
+       <string>freedv</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
\ No newline at end of file
diff --git a/freedv/branches/1.2/freedv-dev/src/serialport.cpp b/freedv/branches/1.2/freedv-dev/src/serialport.cpp
new file mode 100644 (file)
index 0000000..59dd0c9
--- /dev/null
@@ -0,0 +1,234 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "serialport.h"
+
+Serialport::Serialport() {
+    com_handle = COM_HANDLE_INVALID;
+}
+
+Serialport::~Serialport() {
+    if (isopen()) {
+        closeport();
+    }
+}
+
+// returns true if comm port opened OK, false if there was a problem
+
+bool Serialport::openport(const char name[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos)
+{
+    if (com_handle != COM_HANDLE_INVALID) {
+        closeport();
+    }
+
+    m_useRTS = useRTS;
+    m_RTSPos = RTSPos;
+    m_useDTR = useDTR;
+    m_DTRPos = DTRPos;
+
+#ifdef _WIN32
+       {
+               COMMCONFIG CC;
+               DWORD CCsize=sizeof(CC);
+               COMMTIMEOUTS timeouts;
+               DCB     dcb;
+
+               if(GetDefaultCommConfigA(name, &CC, &CCsize)) {
+                       CC.dcb.fOutxCtsFlow             = FALSE;
+                       CC.dcb.fOutxDsrFlow             = FALSE;
+                       CC.dcb.fDtrControl              = DTR_CONTROL_DISABLE;
+                       CC.dcb.fDsrSensitivity  = FALSE;
+                       CC.dcb.fRtsControl              = RTS_CONTROL_DISABLE;
+                       SetDefaultCommConfigA(name, &CC, CCsize);
+               }
+
+               if((com_handle=CreateFileA(name
+                       ,GENERIC_READ|GENERIC_WRITE     /* Access */
+                       ,0                                                              /* Share mode */
+                       ,NULL                                                   /* Security attributes */
+                       ,OPEN_EXISTING                                  /* Create access */
+                       ,FILE_ATTRIBUTE_NORMAL                  /* File attributes */
+                       ,NULL                                                   /* Template */
+                       ))==INVALID_HANDLE_VALUE)
+                       return false;
+
+               if(GetCommTimeouts(com_handle, &timeouts)) {
+                       timeouts.ReadIntervalTimeout=MAXDWORD;
+                       timeouts.ReadTotalTimeoutMultiplier=0;
+                       timeouts.ReadTotalTimeoutConstant=0;            // No-wait read timeout
+                       timeouts.WriteTotalTimeoutMultiplier=0;
+                       timeouts.WriteTotalTimeoutConstant=5000;        // 5 seconds
+                       SetCommTimeouts(com_handle,&timeouts);
+               }
+
+               /* Force N-8-1 mode: */
+               if(GetCommState(com_handle, &dcb)==TRUE) {
+                       dcb.ByteSize            = 8;
+                       dcb.Parity                      = NOPARITY;
+                       dcb.StopBits            = ONESTOPBIT;
+                       dcb.DCBlength           = sizeof(DCB);
+                       dcb.fBinary                     = TRUE;
+                       dcb.fOutxCtsFlow        = FALSE;
+                       dcb.fOutxDsrFlow        = FALSE;
+                       dcb.fDtrControl         = DTR_CONTROL_DISABLE;
+                       dcb.fDsrSensitivity     = FALSE;
+                       dcb.fTXContinueOnXoff= TRUE;
+                       dcb.fOutX                       = FALSE;
+                       dcb.fInX                        = FALSE;
+                       dcb.fRtsControl         = RTS_CONTROL_DISABLE;
+                       dcb.fAbortOnError       = FALSE;
+                       SetCommState(com_handle, &dcb);
+               }
+       }
+#else
+       {
+               struct termios t;
+
+               if((com_handle=open(name, O_NONBLOCK|O_RDWR))== COM_HANDLE_INVALID)
+                       return false;
+
+               if(tcgetattr(com_handle, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+
+               t.c_iflag = (
+                                         IGNBRK   /* ignore BREAK condition */
+                                       | IGNPAR   /* ignore (discard) parity errors */
+                                       );
+               t.c_oflag = 0;  /* No output processing */
+               t.c_cflag = (
+                                         CS8         /* 8 bits */
+                                       | CREAD       /* enable receiver */
+
+               /*
+               Fun snippet from the FreeBSD manpage:
+
+                        If CREAD is set, the receiver is enabled.  Otherwise, no character is
+                        received.  Not all hardware supports this bit.  In fact, this flag is
+                        pretty silly and if it were not part of the termios specification it
+                        would be omitted.
+               */
+                                       | CLOCAL      /* ignore modem status lines */
+                                       );
+
+               t.c_lflag = 0;  /* No local modes */
+               if(tcsetattr(com_handle, TCSANOW, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+               
+       }
+#endif
+       return true;
+}
+
+
+// fixme: this takes about one second to close under Linux
+
+void Serialport::closeport()
+{
+#ifdef _WIN32
+       CloseHandle(com_handle);
+#else
+       close(com_handle);
+#endif
+        com_handle = COM_HANDLE_INVALID;
+}
+
+//----------------------------------------------------------------
+// (raise|lower)(RTS|DTR)()
+//
+// Raises/lowers the specified signal
+//----------------------------------------------------------------
+
+void Serialport::raiseDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::raiseRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::ptt(bool tx) {
+
+   /*  Truth table:
+
+          g_tx   RTSPos   RTS
+          -------------------
+          0      1        0
+          1      1        1
+          0      0        1
+          1      0        0
+
+          exclusive NOR
+    */
+
+    if (com_handle != COM_HANDLE_INVALID) {
+        if (m_useRTS) {
+            //fprintf(stderr, "g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos);
+            if (tx == m_RTSPos)
+                raiseRTS();
+            else
+                lowerRTS();
+        }
+        if (m_useDTR) {
+            //fprintf(stderr, "g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos);
+            if (tx == m_DTRPos)
+                raiseDTR();
+            else
+                lowerDTR();
+        }
+    }
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/serialport.h b/freedv/branches/1.2/freedv-dev/src/serialport.h
new file mode 100644 (file)
index 0000000..e5db10b
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef SERIALPORT_H
+#define SERIALPORT_H
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#endif
+
+// Serial ports called com port for historic reasons, especially on Windows machines 
+
+#ifdef _WIN32
+#define COM_HANDLE_INVALID                     INVALID_HANDLE_VALUE
+typedef HANDLE      com_handle_t;
+#else
+#define COM_HANDLE_INVALID                     -1
+typedef int         com_handle_t;
+#endif
+
+class Serialport {
+
+    public:
+        Serialport();
+        ~Serialport();
+        bool openport(const char port[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos);
+        bool isopen() {return (com_handle != COM_HANDLE_INVALID);}
+        void closeport();
+        void ptt(bool tx);
+
+    private:
+        com_handle_t  com_handle;
+        bool          m_useRTS, m_RTSPos, m_useDTR, m_DTRPos;
+
+        void raiseDTR(void);
+        void lowerDTR(void);
+        void raiseRTS(void);
+        void lowerRTS(void);
+};
+
+#endif /* SERIALPORT_H */
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/band.h b/freedv/branches/1.2/freedv-dev/src/sox/band.h
new file mode 100644 (file)
index 0000000..5398ff4
--- /dev/null
@@ -0,0 +1,47 @@
+/* libSoX Bandpass effect file.     July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * Algorithm:  2nd order recursive filter.
+ * Formula stolen from MUSIC56K, a toolkit of 56000 assembler stuff.
+ * Quote:
+ *   This is a 2nd order recursive band pass filter of the form.
+ *   y(n)= a * x(n) - b * y(n-1) - c * y(n-2)
+ *   where :
+ *        x(n) = "IN"
+ *        "OUT" = y(n)
+ *        c = EXP(-2*pi*cBW/S_RATE)
+ *        b = -4*c/(1+c)*COS(2*pi*cCF/S_RATE)
+ *   if cSCL=2 (i.e. noise input)
+ *        a = SQT(((1+c)*(1+c)-b*b)*(1-c)/(1+c))
+ *   else
+ *        a = SQT(1-b*b/(4*c))*(1-c)
+ *   endif
+ *   note :     cCF is the center frequency in Hertz
+ *        cBW is the band width in Hertz
+ *        cSCL is a scale factor, use 1 for pitched sounds
+ *   use 2 for noise.
+ *
+ *
+ * July 1, 1999 - Jan Paul Schmidt <jps@fundament.org>
+ *
+ *   This looks like the resonator band pass in SPKit. It's a
+ *   second order all-pole (IIR) band-pass filter described
+ *   at the pages 186 - 189 in
+ *     Dodge, Charles & Jerse, Thomas A. 1985:
+ *       Computer Music -- Synthesis, Composition and Performance.
+ *       New York: Schirmer Books.
+ *   Reference from the SPKit manual.
+ */
+
+  p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate);
+  p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->in_signal.rate);
+  p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2);
+  if (p->filter_type == filter_BPF_SPK_N) {
+    mult = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2)) / p->b0;
+    p->b0 *= mult;
+  }
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/biquad.c b/freedv/branches/1.2/freedv-dev/src/sox/biquad.c
new file mode 100644 (file)
index 0000000..c57f190
--- /dev/null
@@ -0,0 +1,178 @@
+/* libSoX Biquad filter common functions   (c) 2006-7 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "biquad.h"
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+static char const * const width_str[] = {
+  "band-width(Hz)",
+  "band-width(kHz)",
+  "band-width(Hz, no warp)", /* deprecated */
+  "band-width(octaves)",
+  "Q",
+  "slope",
+};
+static char const all_width_types[] = "hkboqs";
+
+
+int lsx_biquad_getopts(sox_effect_t * effp, int argc, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  char width_type = *allowed_width_types;
+  char dummy, * dummy_p;     /* To check for extraneous chars. */
+  --argc, ++argv;
+
+  p->filter_type = filter_type;
+  if (argc < min_args || argc > max_args ||
+      (argc > fc_pos    && ((p->fc = lsx_parse_frequency(argv[fc_pos], &dummy_p)) <= 0 || *dummy_p)) ||
+      (argc > width_pos && ((unsigned)(sscanf(argv[width_pos], "%lf%c %c", &p->width, &width_type, &dummy)-1) > 1 || p->width <= 0)) ||
+      (argc > gain_pos  && sscanf(argv[gain_pos], "%lf %c", &p->gain, &dummy) != 1) ||
+      !strchr(allowed_width_types, width_type) || (width_type == 's' && p->width > 1))
+    return lsx_usage(effp);
+  p->width_type = strchr(all_width_types, width_type) - all_width_types;
+  if ((size_t)p->width_type >= strlen(all_width_types))
+    p->width_type = 0;
+  if (p->width_type == width_bw_kHz) {
+    p->width *= 1000;
+    p->width_type = width_bw_Hz;
+  }
+  return SOX_SUCCESS;
+}
+
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  /* Simplify: */
+  p->b2 /= p->a0;
+  p->b1 /= p->a0;
+  p->b0 /= p->a0;
+  p->a2 /= p->a0;
+  p->a1 /= p->a0;
+
+  p->o2 = p->o1 = p->i2 = p->i1 = 0;
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+
+  start(effp);
+
+  if (effp->global_info->plot == sox_plot_octave) {
+    printf(
+      "%% GNU Octave file (may also work with MATLAB(R) )\n"
+      "Fs=%g;minF=10;maxF=Fs/2;\n"
+      "sweepF=logspace(log10(minF),log10(maxF),200);\n"
+      "[h,w]=freqz([%.15e %.15e %.15e],[1 %.15e %.15e],sweepF,Fs);\n"
+      "semilogx(w,20*log10(h))\n"
+      "title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)')\n"
+      "xlabel('Frequency (Hz)')\n"
+      "ylabel('Amplitude Response (dB)')\n"
+      "axis([minF maxF -35 25])\n"
+      "grid on\n"
+      "disp('Hit return to continue')\n"
+      "pause\n"
+      , effp->in_signal.rate, p->b0, p->b1, p->b2, p->a1, p->a2
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_gnuplot) {
+    printf(
+      "# gnuplot file\n"
+      "set title 'SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)'\n"
+      "set xlabel 'Frequency (Hz)'\n"
+      "set ylabel 'Amplitude Response (dB)'\n"
+      "Fs=%g\n"
+      "b0=%.15e; b1=%.15e; b2=%.15e; a1=%.15e; a2=%.15e\n"
+      "o=2*pi/Fs\n"
+      "H(f)=sqrt((b0*b0+b1*b1+b2*b2+2.*(b0*b1+b1*b2)*cos(f*o)+2.*(b0*b2)*cos(2.*f*o))/(1.+a1*a1+a2*a2+2.*(a1+a1*a2)*cos(f*o)+2.*a2*cos(2.*f*o)))\n"
+      "set logscale x\n"
+      "set samples 250\n"
+      "set grid xtics ytics\n"
+      "set key off\n"
+      "plot [f=10:Fs/2] [-35:25] 20*log10(H(f))\n"
+      "pause -1 'Hit return to continue'\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_data) {
+    printf("# SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)\n"
+      "# IIR filter\n"
+      "# rate: %g\n"
+      "# name: b\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      "# name: a\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, 1. /* a0 */, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
+    sox_sample_t *obuf, size_t *isamp, size_t *osamp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  size_t len = *isamp = *osamp = min(*isamp, *osamp);
+  while (len--) {
+    double o0 = *ibuf*p->b0 + p->i1*p->b1 + p->i2*p->b2 - p->o1*p->a1 - p->o2*p->a2;
+    p->i2 = p->i1, p->i1 = *ibuf++;
+    p->o2 = p->o1, p->o1 = o0;
+    *obuf++ = SOX_ROUND_CLIP_COUNT(o0, effp->clips);
+  }
+  return SOX_SUCCESS;
+}
+
+static int create(sox_effect_t * effp, int argc, char * * argv)
+{
+  priv_t             * p = (priv_t *)effp->priv;
+  double             * d = &p->b0;
+  char               c;
+
+  --argc, ++argv;
+  if (argc == 6)
+    for (; argc && sscanf(*argv, "%lf%c", d, &c) == 1; --argc, ++argv, ++d);
+  return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * lsx_biquad_effect_fn(void)
+{
+  static sox_effect_handler_t handler = {
+    "biquad", "b0 b1 b2 a0 a1 a2", 0,
+    create, lsx_biquad_start, lsx_biquad_flow, NULL, NULL, NULL, sizeof(priv_t)
+  };
+  return &handler;
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/biquad.h b/freedv/branches/1.2/freedv-dev/src/sox/biquad.h
new file mode 100644 (file)
index 0000000..8786ac8
--- /dev/null
@@ -0,0 +1,78 @@
+/* libSoX Biquad filter common definitions (c) 2006-7 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef biquad_included
+#define biquad_included
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+
+typedef enum {
+  filter_LPF,
+  filter_HPF,
+  filter_BPF_CSG,
+  filter_BPF,
+  filter_notch,
+  filter_APF,
+  filter_peakingEQ,
+  filter_lowShelf,
+  filter_highShelf,
+  filter_LPF_1,
+  filter_HPF_1,
+  filter_BPF_SPK,
+  filter_BPF_SPK_N,
+  filter_AP1,
+  filter_AP2,
+  filter_deemph,
+  filter_riaa
+} filter_t;
+
+typedef enum {
+  width_bw_Hz,
+  width_bw_kHz,
+  /* The old, non-RBJ, non-freq-warped band-pass/reject response;
+   * leaving here for now just in case anybody misses it: */
+  width_bw_old,
+  width_bw_oct,
+  width_Q,
+  width_slope
+} width_t;
+
+/* Private data for the biquad filter effects */
+typedef struct {
+  double gain;             /* For EQ filters */
+  double fc;               /* Centre/corner/cutoff frequency */
+  double width;            /* Filter width; interpreted as per width_type */
+  width_t width_type;
+
+  filter_t filter_type;
+
+  double b0, b1, b2;       /* Filter coefficients */
+  double a0, a1, a2;       /* Filter coefficients */
+
+  sox_sample_t i1, i2;     /* Filter memory */
+  double      o1, o2;      /* Filter memory */
+} biquad_t;
+
+int lsx_biquad_getopts(sox_effect_t * effp, int n, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type);
+int lsx_biquad_start(sox_effect_t * effp);
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
+                        size_t *isamp, size_t *osamp);
+
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/biquads.c b/freedv/branches/1.2/freedv-dev/src/sox/biquads.c
new file mode 100644 (file)
index 0000000..19793a6
--- /dev/null
@@ -0,0 +1,400 @@
+/* libSoX Biquad filter effects   (c) 2006-8 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
+ *   see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+ *
+ * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
+ *   Algorithms: Recursive single pole low/high pass filter
+ *   Reference: The Scientist and Engineer's Guide to Digital Signal Processing
+ *
+ *   low-pass: output[N] = input[N] * A + output[N-1] * B
+ *     X = exp(-2.0 * pi * Fc)
+ *     A = 1 - X
+ *     B = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC low-pass filter:
+ *
+ *     ---/\/\/\/\----------->
+ *                   |
+ *                  --- C
+ *                  ---
+ *                   |
+ *                   |
+ *                   V
+ *
+ *   high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
+ *     X  = exp(-2.0 * pi * Fc)
+ *     A0 = (1 + X) / 2
+ *     A1 = -(1 + X) / 2
+ *     B1 = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC high-pass filter:
+ *
+ *         || C
+ *     ----||--------->
+ *         ||    |
+ *               <
+ *               > R
+ *               <
+ *               |
+ *               V
+ */
+
+
+#include "biquad.h"
+#include <assert.h>
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+
+static int hilo1_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 1, 1, 0, 1, 2, "",
+      *effp->handler.name == 'l'? filter_LPF_1 : filter_HPF_1);
+}
+
+
+static int hilo2_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    return hilo1_getopts(effp, argc - 1, argv + 1);
+  if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc;
+  p->width = sqrt(0.5); /* Default to Butterworth */
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "qohk",
+      *effp->handler.name == 'l'? filter_LPF : filter_HPF);
+}
+
+
+static int bandpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF;
+  if (argc > 1 && strcmp(argv[1], "-c") == 0)
+    ++argv, --argc, type = filter_BPF_CSG;
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", type);
+}
+
+
+static int bandrej_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", filter_notch);
+}
+
+
+static int allpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_APF;
+  int m;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    ++argv, --argc, type = filter_AP1;
+  else if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc, type = filter_AP2;
+  m = 1 + (type == filter_APF);
+  return lsx_biquad_getopts(effp, argc, argv, m, m, 0, 1, 2, "hkqo", type);
+}
+
+
+static int tone_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->width = 0.5;
+  p->fc = *effp->handler.name == 'b'? 100 : 3000;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 3, 1, 2, 0, "shkqo",
+      *effp->handler.name == 'b'?  filter_lowShelf: filter_highShelf);
+}
+
+
+static int equalizer_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 3, 3, 0, 1, 2, "qohk", filter_peakingEQ);
+}
+
+
+static int band_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF_SPK;
+  if (argc > 1 && strcmp(argv[1], "-n") == 0)
+    ++argv, --argc, type = filter_BPF_SPK_N;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "hkqo", type);
+}
+
+
+static int deemph_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->fc    = 5283;
+  p->width = 0.4845;
+  p->gain  = -9.477;
+  return lsx_biquad_getopts(effp, argc, argv, 0, 0, 0, 1, 2, "s", filter_deemph);
+}
+
+
+static int riaa_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->filter_type = filter_riaa;
+  (void)argv;
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+
+static void make_poly_from_roots(
+    double const * roots, size_t num_roots, double * poly)
+{
+  size_t i, j;
+  poly[0] = 1;
+  poly[1] = -roots[0];
+  memset(poly + 2, 0, (num_roots + 1 - 2) * sizeof(*poly));
+  for (i = 1; i < num_roots; ++i)
+    for (j = num_roots; j > 0; --j)
+      poly[j] -= poly[j - 1] * roots[i];
+}
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  double w0 = 2 * M_PI * p->fc / effp->in_signal.rate;
+  double A  = exp(p->gain / 40 * log(10.));
+  double alpha = 0, mult = dB_to_linear(max(p->gain, 0));
+
+  if (w0 > M_PI) {
+    lsx_fail("frequency must be less than half the sample-rate (Nyquist rate)");
+    return SOX_EOF;
+  }
+
+  /* Set defaults: */
+  p->b0 = p->b1 = p->b2 = p->a1 = p->a2 = 0;
+  p->a0 = 1;
+
+  if (p->width) switch (p->width_type) {
+    case width_slope:
+      alpha = sin(w0)/2 * sqrt((A + 1/A)*(1/p->width - 1) + 2);
+      break;
+
+    case width_Q:
+      alpha = sin(w0)/(2*p->width);
+      break;
+
+    case width_bw_oct:
+      alpha = sin(w0)*sinh(log(2.)/2 * p->width * w0/sin(w0));
+      break;
+
+    case width_bw_Hz:
+      alpha = sin(w0)/(2*p->fc/p->width);
+      break;
+
+    case width_bw_kHz: assert(0); /* Shouldn't get here */
+
+    case width_bw_old:
+      alpha = tan(M_PI * p->width / effp->in_signal.rate);
+      break;
+  }
+  switch (p->filter_type) {
+    case filter_LPF: /* H(s) = 1 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 - cos(w0))/2;
+      p->b1 =   1 - cos(w0);
+      p->b2 =  (1 - cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_HPF: /* H(s) = s^2 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 + cos(w0))/2;
+      p->b1 = -(1 + cos(w0));
+      p->b2 =  (1 + cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF_CSG: /* H(s) = s / (s^2 + s/Q + 1)  (constant skirt gain, peak gain = Q) */
+      p->b0 =   sin(w0)/2;
+      p->b1 =   0;
+      p->b2 =  -sin(w0)/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF: /* H(s) = (s/Q) / (s^2 + s/Q + 1)      (constant 0 dB peak gain) */
+      p->b0 =   alpha;
+      p->b1 =   0;
+      p->b2 =  -alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_notch: /* H(s) = (s^2 + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_APF: /* H(s) = (s^2 - s/Q + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1 - alpha;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 + alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_peakingEQ: /* H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =   1 + alpha*A;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 - alpha*A;
+      p->a0 =   1 + alpha/A;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha/A;
+      break;
+
+    case filter_lowShelf: /* H(s) = A * (s^2 + (sqrt(A)/Q)*s + A)/(A*s^2 + (sqrt(A)/Q)*s + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 =  2*A*( (A-1) - (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =   -2*( (A-1) + (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_deemph:  /* See deemph.plt for documentation */
+      if (effp->in_signal.rate != 44100) {
+        lsx_fail("Sample rate must be 44100 (audio-CD)");
+        return SOX_EOF;
+      }
+      /* Falls through... */
+
+    case filter_highShelf: /* H(s) = A * (A*s^2 + (sqrt(A)/Q)*s + 1)/(s^2 + (sqrt(A)/Q)*s + A) */
+      if (!A)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 = -2*A*( (A-1) + (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =    2*( (A-1) - (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_LPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = 1 + p->a1;
+      break;
+
+    case filter_HPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = (1 - p->a1)/2;
+      p->b1 = -p->b0;
+      break;
+
+    case filter_BPF_SPK: case filter_BPF_SPK_N: {
+      double bw_Hz;
+      if (!p->width)
+        p->width = p->fc / 2;
+      bw_Hz = p->width_type == width_Q?  p->fc / p->width :
+        p->width_type == width_bw_Hz? p->width :
+        p->fc * (pow(2., p->width) - 1) * pow(2., -0.5 * p->width); /* bw_oct */
+      #include "band.h" /* Has different licence */
+      break;
+    }
+
+    case filter_AP1:     /* Experimental 1-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = exp(-w0);
+      p->b1 = -1;
+      p->a1 = -exp(-w0);
+      break;
+
+    case filter_AP2:     /* Experimental 2-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = 1 - sin(w0);
+      p->b1 = -2 * cos(w0);
+      p->b2 = 1 + sin(w0);
+      p->a0 = 1 + sin(w0);
+      p->a1 = -2 * cos(w0);
+      p->a2 = 1 - sin(w0);
+      break;
+
+    case filter_riaa: /* http://www.dsprelated.com/showmessage/73300/3.php */
+      if (effp->in_signal.rate == 44100) {
+        static const double zeros[] = {-0.2014898, 0.9233820};
+        static const double poles[] = {0.7083149, 0.9924091};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 48000) {
+        static const double zeros[] = {-0.1766069, 0.9321590};
+        static const double poles[] = {0.7396325, 0.9931330};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 88200) {
+        static const double zeros[] = {-0.1168735, 0.9648312};
+        static const double poles[] = {0.8590646, 0.9964002};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 96000) {
+        static const double zeros[] = {-0.1141486, 0.9676817};
+        static const double poles[] = {0.8699137, 0.9966946};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else {
+        lsx_fail("Sample rate must be 44.1k, 48k, 88.2k, or 96k");
+        return SOX_EOF;
+      }
+      { /* Normalise to 0dB at 1kHz (Thanks to Glenn Davis) */
+        double y = 2 * M_PI * 1000 / effp->in_signal.rate;
+        double b_re = p->b0 + p->b1 * cos(-y) + p->b2 * cos(-2 * y);
+        double a_re = p->a0 + p->a1 * cos(-y) + p->a2 * cos(-2 * y);
+        double b_im = p->b1 * sin(-y) + p->b2 * sin(-2 * y);
+        double a_im = p->a1 * sin(-y) + p->a2 * sin(-2 * y);
+        double g = 1 / sqrt((sqr(b_re) + sqr(b_im)) / (sqr(a_re) + sqr(a_im)));
+        p->b0 *= g; p->b1 *= g; p->b2 *= g;
+      }
+      mult = (p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2);
+      lsx_debug("gain=%f", linear_to_dB(mult));
+      break;
+  }
+  if (effp->in_signal.mult)
+    *effp->in_signal.mult /= mult;
+  return lsx_biquad_start(effp);
+}
+
+
+#define BIQUAD_EFFECT(name,group,usage,flags) \
+sox_effect_handler_t const * lsx_##name##_effect_fn(void) { \
+  static sox_effect_handler_t handler = { \
+    #name, usage, flags, \
+    group##_getopts, start, lsx_biquad_flow, 0, 0, 0, sizeof(biquad_t)\
+  }; \
+  return &handler; \
+}
+
+BIQUAD_EFFECT(highpass,  hilo2,    "[-1|-2] frequency [width[q|o|h|k](0.707q)]", 0)
+BIQUAD_EFFECT(lowpass,   hilo2,    "[-1|-2] frequency [width[q|o|h|k]](0.707q)", 0)
+BIQUAD_EFFECT(bandpass,  bandpass, "[-c] frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bandreject,bandrej,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(allpass,   allpass,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bass,      tone,     "gain [frequency(100) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(treble,    tone,     "gain [frequency(3000) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(equalizer, equalizer,"frequency width[q|o|h|k] gain", 0)
+BIQUAD_EFFECT(band,      band,     "[-n] center [width[h|k|q|o]]", 0)
+BIQUAD_EFFECT(deemph,    deemph,   NULL, 0)
+BIQUAD_EFFECT(riaa,      riaa,     NULL, 0)
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/effects.c b/freedv/branches/1.2/freedv-dev/src/sox/effects.c
new file mode 100644 (file)
index 0000000..435412f
--- /dev/null
@@ -0,0 +1,544 @@
+/* SoX Effects chain     (c) 2007 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <assert.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+  #include <strings.h>
+#endif
+
+#define DEBUG_EFFECTS_CHAIN 0
+
+/* Default effect handler functions for do-nothing situations: */
+
+static int default_function(sox_effect_t * effp UNUSED)
+{
+  return SOX_SUCCESS;
+}
+
+/* Pass through samples verbatim */
+int lsx_flow_copy(sox_effect_t * effp UNUSED, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp)
+{
+  *isamp = *osamp = min(*isamp, *osamp);
+  memcpy(obuf, ibuf, *isamp * sizeof(*obuf));
+  return SOX_SUCCESS;
+}
+
+/* Inform no more samples to drain */
+static int default_drain(sox_effect_t * effp UNUSED, sox_sample_t *obuf UNUSED, size_t *osamp)
+{
+  *osamp = 0;
+  return SOX_EOF;
+}
+
+/* Check that no parameters have been given */
+static int default_getopts(sox_effect_t * effp, int argc, char **argv UNUSED)
+{
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+/* Partially initialise the effect structure; signal info will come later */
+sox_effect_t * sox_create_effect(sox_effect_handler_t const * eh)
+{
+  sox_effect_t * effp = lsx_calloc(1, sizeof(*effp));
+  effp->obuf = NULL;
+
+  effp->global_info = sox_get_effects_globals();
+  effp->handler = *eh;
+  if (!effp->handler.getopts) effp->handler.getopts = default_getopts;
+  if (!effp->handler.start  ) effp->handler.start   = default_function;
+  if (!effp->handler.flow   ) effp->handler.flow    = lsx_flow_copy;
+  if (!effp->handler.drain  ) effp->handler.drain   = default_drain;
+  if (!effp->handler.stop   ) effp->handler.stop    = default_function;
+  if (!effp->handler.kill   ) effp->handler.kill    = default_function;
+
+  effp->priv = lsx_calloc(1, effp->handler.priv_size);
+
+  return effp;
+} /* sox_create_effect */
+
+int sox_effect_options(sox_effect_t *effp, int argc, char * const argv[])
+{
+  int result;
+
+  char * * argv2 = lsx_malloc((argc + 1) * sizeof(*argv2));
+  argv2[0] = (char *)effp->handler.name;
+  memcpy(argv2 + 1, argv, argc * sizeof(*argv2));
+  result = effp->handler.getopts(effp, argc + 1, argv2);
+  free(argv2);
+  return result;
+} /* sox_effect_options */
+
+/* Effects chain: */
+
+sox_effects_chain_t * sox_create_effects_chain(
+    sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc)
+{
+  sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t));
+  result->global_info = *sox_get_effects_globals();
+  result->in_enc = in_enc;
+  result->out_enc = out_enc;
+  return result;
+} /* sox_create_effects_chain */
+
+void sox_delete_effects_chain(sox_effects_chain_t *ecp)
+{
+    if (ecp && ecp->length)
+        sox_delete_effects(ecp);
+    free(ecp->effects);
+    free(ecp);
+} /* sox_delete_effects_chain */
+
+/* Effect can call in start() or flow() to set minimum input size to flow() */
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin)
+{
+  if (imin > sox_globals.bufsiz / effp->flows) {
+    lsx_fail("sox_bufsiz not big enough");
+    return SOX_EOF;
+  }
+
+  effp->imin = imin;
+  return SOX_SUCCESS;
+}
+
+/* Effects table to be extended in steps of EFF_TABLE_STEP */
+#define EFF_TABLE_STEP 8
+
+/* Add an effect to the chain. *in is the input signal for this effect. *out is
+ * a suggestion as to what the output signal should be, but depending on its
+ * given options and *in, the effect can choose to do differently.  Whatever
+ * output rate and channels the effect does produce are written back to *in,
+ * ready for the next effect in the chain.
+ */
+int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out)
+{
+  int ret, (*start)(sox_effect_t * effp) = effp->handler.start;
+  unsigned f;
+  sox_effect_t eff0;  /* Copy of effect for flow 0 before calling start */
+
+  effp->global_info = &chain->global_info;
+  effp->in_signal = *in;
+  effp->out_signal = *out;
+  effp->in_encoding = chain->in_enc;
+  effp->out_encoding = chain->out_enc;
+  if (!(effp->handler.flags & SOX_EFF_CHAN))
+    effp->out_signal.channels = in->channels;
+  if (!(effp->handler.flags & SOX_EFF_RATE))
+    effp->out_signal.rate = in->rate;
+  if (!(effp->handler.flags & SOX_EFF_PREC))
+    effp->out_signal.precision = (effp->handler.flags & SOX_EFF_MODIFY)?
+        in->precision : SOX_SAMPLE_PRECISION;
+  if (!(effp->handler.flags & SOX_EFF_GAIN))
+    effp->out_signal.mult = in->mult;
+
+  effp->flows =
+    (effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels;
+  effp->clips = 0;
+  effp->imin = 0;
+  eff0 = *effp, eff0.priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+  eff0.in_signal.mult = NULL; /* Only used in channel 0 */
+  ret = start(effp);
+  if (ret == SOX_EFF_NULL) {
+    lsx_report("has no effect in this configuration");
+    free(eff0.priv);
+    free(effp->priv);
+    effp->priv = NULL;
+    return SOX_SUCCESS;
+  }
+  if (ret != SOX_SUCCESS) {
+    free(eff0.priv);
+    return SOX_EOF;
+  }
+  if (in->mult)
+    lsx_debug("mult=%g", *in->mult);
+
+  if (!(effp->handler.flags & SOX_EFF_LENGTH)) {
+    effp->out_signal.length = in->length;
+    if (effp->out_signal.length != SOX_UNKNOWN_LEN) {
+      if (effp->handler.flags & SOX_EFF_CHAN)
+        effp->out_signal.length =
+          effp->out_signal.length / in->channels * effp->out_signal.channels;
+      if (effp->handler.flags & SOX_EFF_RATE)
+        effp->out_signal.length =
+          effp->out_signal.length / in->rate * effp->out_signal.rate + .5;
+    }
+  }
+
+  *in = effp->out_signal;
+
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_add_effect: extending effects table, "
+      "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length] =
+    lsx_calloc(effp->flows, sizeof(chain->effects[chain->length][0]));
+  chain->effects[chain->length][0] = *effp;
+
+  for (f = 1; f < effp->flows; ++f) {
+    chain->effects[chain->length][f] = eff0;
+    chain->effects[chain->length][f].flow = f;
+    chain->effects[chain->length][f].priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+    if (start(&chain->effects[chain->length][f]) != SOX_SUCCESS) {
+      free(eff0.priv);
+      return SOX_EOF;
+    }
+  }
+
+  ++chain->length;
+  free(eff0.priv);
+  return SOX_SUCCESS;
+}
+
+static int flow_effect(sox_effects_chain_t * chain, size_t n)
+{
+  sox_effect_t * effp1 = &chain->effects[n - 1][0];
+  sox_effect_t * effp = &chain->effects[n][0];
+  int effstatus = SOX_SUCCESS, f = 0;
+  size_t i;
+  const sox_sample_t *ibuf;
+  size_t idone = effp1->oend - effp1->obeg;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#if DEBUG_EFFECTS_CHAIN
+  size_t pre_idone = idone;
+  size_t pre_odone = obeg;
+#endif
+
+  if (effp->flows == 1) {     /* Run effect on all channels at once */
+    idone -= idone % effp->in_signal.channels;
+    effstatus = effp->handler.flow(effp, &effp1->obuf[effp1->obeg],
+                                   &effp->obuf[effp->oend], &idone, &obeg);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect flowed asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {               /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    size_t idone_last = 0, odone_last = 0; /* Initialised to prevent warning */
+
+    ibuf = &effp1->obuf[effp1->obeg];
+    for (i = 0; i < idone; i += effp->flows)
+      for (f = 0; f < (int)effp->flows; ++f)
+        chain->ibufc[f][i / effp->flows] = *ibuf++;
+
+#ifdef HAVE_OPENMP
+    if (sox_globals.use_threads && effp->flows > 1)
+    {
+      #pragma omp parallel for
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (!f) {
+          idone_last = idonec;
+          odone_last = odonec;
+        }
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+    else /* sox_globals.use_threads */
+#endif
+    {
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (f && (idonec != idone_last || odonec != odone_last)) {
+          lsx_fail("flowed asymmetrically!");
+          effstatus = SOX_EOF;
+        }
+        idone_last = idonec;
+        odone_last = odonec;
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+
+    for (i = 0; i < odone_last; ++i)
+      for (f = 0; f < (int)effp->flows; ++f)
+        *obuf++ = chain->obufc[f][i];
+
+    idone = effp->flows * idone_last;
+    obeg = effp->flows * odone_last;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("flow:  %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      pre_idone, pre_odone, idone, obeg);
+#endif
+  effp1->obeg += idone;
+  if (effp1->obeg == effp1->oend)
+    effp1->obeg = effp1->oend = 0;
+  else if (effp1->oend - effp1->obeg < effp->imin ) { /* Need to refill? */
+    memmove(effp1->obuf, &effp1->obuf[effp1->obeg], (effp1->oend - effp1->obeg) * sizeof(*effp1->obuf));
+    effp1->oend -= effp1->obeg;
+    effp1->obeg = 0;
+  }
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* The same as flow_effect but with no input */
+static int drain_effect(sox_effects_chain_t * chain, size_t n)
+{
+  sox_effect_t * effp = &chain->effects[n][0];
+  int effstatus = SOX_SUCCESS;
+  size_t i, f;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#if DEBUG_EFFECTS_CHAIN
+  size_t pre_odone = obeg;
+#endif
+
+  if (effp->flows == 1) { /* Run effect on all channels at once */
+    effstatus = effp->handler.drain(effp, &effp->obuf[effp->oend], &obeg);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect drained asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {                       /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    size_t odone_last = 0; /* Initialised to prevent warning */
+
+    for (f = 0; f < effp->flows; ++f) {
+      size_t odonec = obeg / effp->flows;
+      int eff_status_c = effp->handler.drain(&chain->effects[n][f], chain->obufc[f], &odonec);
+      if (f && (odonec != odone_last)) {
+        lsx_fail("drained asymmetrically!");
+        effstatus = SOX_EOF;
+      }
+      odone_last = odonec;
+
+      if (eff_status_c != SOX_SUCCESS)
+        effstatus = SOX_EOF;
+    }
+
+    for (i = 0; i < odone_last; ++i)
+      for (f = 0; f < effp->flows; ++f)
+        *obuf++ = chain->obufc[f][i];
+    obeg = f * odone_last;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("drain: %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      (size_t)0, pre_odone, (size_t)0, obeg);
+#endif
+  if (!obeg)   /* This is the only thing that drain has and flow hasn't */
+    effstatus = SOX_EOF;
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* Flow data through the effects chain until an effect or callback gives EOF */
+int sox_flow_effects(sox_effects_chain_t * chain, int (* callback)(sox_bool all_done, void * client_data), void * client_data)
+{
+  int flow_status = SOX_SUCCESS;
+  size_t e, source_e = 0;               /* effect indices */
+  size_t f, max_flows = 0;
+  sox_bool draining = sox_true;
+
+  for (e = 0; e < chain->length; ++e) {
+    chain->effects[e][0].obuf = lsx_realloc(chain->effects[e][0].obuf,
+        sox_globals.bufsiz * sizeof(chain->effects[e][0].obuf[0]));
+      /* Possibly there is already a buffer, if this is a used effect;
+         it may still contain samples in that case. */
+      /* Memory will be freed by sox_delete_effect() later. */
+    max_flows = max(max_flows, chain->effects[e][0].flows);
+  }
+  if (max_flows == 1) /* don't need interleave buffers */
+    max_flows = 0;
+  chain->ibufc = lsx_calloc(max_flows, sizeof(*chain->ibufc));
+  chain->obufc = lsx_calloc(max_flows, sizeof(*chain->obufc));
+  for (f = 0; f < max_flows; ++f) {
+    chain->ibufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->ibufc[f][0]));
+    chain->obufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->obufc[f][0]));
+  }
+
+  e = chain->length - 1;
+  while (source_e < chain->length) {
+#define have_imin (e > 0 && e < chain->length && chain->effects[e - 1][0].oend - chain->effects[e - 1][0].obeg >= chain->effects[e][0].imin)
+    size_t osize = chain->effects[e][0].oend - chain->effects[e][0].obeg;
+    if (e == source_e && (draining || !have_imin)) {
+      if (drain_effect(chain, e) == SOX_EOF) {
+        ++source_e;
+        draining = sox_false;
+      }
+    } else if (have_imin && flow_effect(chain, e) == SOX_EOF) {
+      flow_status = SOX_EOF;
+      if (e == chain->length - 1)
+        break;
+      source_e = e;
+      draining = sox_true;
+    }
+    if (e < chain->length && chain->effects[e][0].oend - chain->effects[e][0].obeg > osize) /* False for output */
+      ++e;
+    else if (e == source_e)
+      draining = sox_true;
+    else if ((int)--e < (int)source_e)
+      e = source_e;
+
+    if (callback && callback(source_e == chain->length, client_data) != SOX_SUCCESS) {
+      flow_status = SOX_EOF; /* Client has requested to stop the flow. */
+      break;
+    }
+  }
+
+  for (f = 0; f < max_flows; ++f) {
+    free(chain->ibufc[f]);
+    free(chain->obufc[f]);
+  }
+  free(chain->obufc);
+  free(chain->ibufc);
+
+  return flow_status;
+}
+
+sox_uint64_t sox_effects_clips(sox_effects_chain_t * chain)
+{
+  unsigned i, f;
+  uint64_t clips = 0;
+  for (i = 1; i < chain->length - 1; ++i)
+    for (f = 0; f < chain->effects[i][0].flows; ++f)
+      clips += chain->effects[i][f].clips;
+  return clips;
+}
+
+sox_uint64_t sox_stop_effect(sox_effect_t *effp)
+{
+  unsigned f;
+  uint64_t clips = 0;
+
+  for (f = 0; f < effp->flows; ++f) {
+    effp[f].handler.stop(&effp[f]);
+    clips += effp[f].clips;
+  }
+  return clips;
+}
+
+void sox_push_effect_last(sox_effects_chain_t *chain, sox_effect_t *effp)
+{
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_push_effect_last: extending effects table, "
+        "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length++] = effp;
+} /* sox_push_effect_last */
+
+sox_effect_t *sox_pop_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    sox_effect_t *effp;
+    chain->length--;
+    effp = chain->effects[chain->length];
+    chain->effects[chain->length] = NULL;
+    return effp;
+  }
+  else
+    return NULL;
+} /* sox_pop_effect_last */
+
+/* Free resources related to effect.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effect(sox_effect_t *effp)
+{
+  uint64_t clips;
+  unsigned f;
+
+  if ((clips = sox_stop_effect(effp)) != 0)
+    lsx_warn("%s clipped %" PRIu64 " samples; decrease volume?",
+        effp->handler.name, clips);
+  if (effp->obeg != effp->oend)
+    lsx_debug("output buffer still held %" PRIuPTR " samples; dropped.",
+        (effp->oend - effp->obeg)/effp->out_signal.channels);
+      /* May or may not indicate a problem; it is normal if the user aborted
+         processing, or if an effect like "trim" stopped early. */
+  effp->handler.kill(effp); /* N.B. only one kill; not one per flow */
+  for (f = 0; f < effp->flows; ++f)
+    free(effp[f].priv);
+  free(effp->obuf);
+  free(effp);
+}
+
+void sox_delete_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    chain->length--;
+    sox_delete_effect(chain->effects[chain->length]);
+    chain->effects[chain->length] = NULL;
+  }
+} /* sox_delete_effect_last */
+
+/* Remove all effects from the chain.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effects(sox_effects_chain_t * chain)
+{
+  size_t e;
+
+  for (e = 0; e < chain->length; ++e) {
+    sox_delete_effect(chain->effects[e]);
+    chain->effects[e] = NULL;
+  }
+  chain->length = 0;
+}
+
+/*----------------------------- Effects library ------------------------------*/
+
+static sox_effect_fn_t s_sox_effect_fns[] = {
+#define EFFECT(f) lsx_##f##_effect_fn,
+#include "effects.h"
+#undef EFFECT
+  NULL
+};
+
+const sox_effect_fn_t*
+sox_get_effect_fns(void)
+{
+    return s_sox_effect_fns;
+}
+
+/* Find a named effect in the effects library */
+sox_effect_handler_t const * sox_find_effect(char const * name)
+{
+  int e;
+  sox_effect_fn_t const * fns = sox_get_effect_fns();
+  for (e = 0; fns[e]; ++e) {
+    const sox_effect_handler_t *eh = fns[e] ();
+    if (eh && eh->name && strcasecmp(eh->name, name) == 0)
+      return eh;                 /* Found it. */
+  }
+  return NULL;
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/effects.h b/freedv/branches/1.2/freedv-dev/src/sox/effects.h
new file mode 100644 (file)
index 0000000..8d7025c
--- /dev/null
@@ -0,0 +1,22 @@
+/* This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/* Manually edited for FreeDV to contain just the effects we need */
+
+  EFFECT(bass)
+  EFFECT(highpass)
+  EFFECT(treble)
+  EFFECT(equalizer)
+
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/effects_i.c b/freedv/branches/1.2/freedv-dev/src/sox/effects_i.c
new file mode 100644 (file)
index 0000000..e5770a9
--- /dev/null
@@ -0,0 +1,379 @@
+/* Implements a libSoX internal interface for implementing effects.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * Copyright (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <string.h>
+#include <ctype.h>
+
+int lsx_usage(sox_effect_t * effp)
+{
+  if (effp->handler.usage)
+    lsx_fail("usage: %s", effp->handler.usage);
+  else
+    lsx_fail("this effect takes no parameters");
+  return SOX_EOF;
+}
+
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n)
+{
+  if (!*usage) {
+    size_t i, len;
+    for (len = i = 0; i < n; len += strlen(lines[i++]) + 1);
+    *usage = lsx_malloc(len); /* FIXME: this memory will never be freed */
+    strcpy(*usage, lines[0]);
+    for (i = 1; i < n; ++i) {
+      strcat(*usage, "\n");
+      strcat(*usage, lines[i]);
+    }
+  }
+  return *usage;
+}
+
+static lsx_enum_item const s_lsx_wave_enum[] = {
+  LSX_ENUM_ITEM(SOX_WAVE_,SINE)
+  LSX_ENUM_ITEM(SOX_WAVE_,TRIANGLE)
+  {0, 0}};
+
+lsx_enum_item const * lsx_get_wave_enum(void)
+{
+  return s_lsx_wave_enum;
+}
+
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void *table,
+    size_t table_size,
+    double min,
+    double max,
+    double phase)
+{
+  uint32_t t;
+  uint32_t phase_offset = phase / M_PI / 2 * table_size + 0.5;
+
+  for (t = 0; t < table_size; t++)
+  {
+    uint32_t point = (t + phase_offset) % table_size;
+    double d;
+    switch (wave_type)
+    {
+      case SOX_WAVE_SINE:
+      d = (sin((double)point / table_size * 2 * M_PI) + 1) / 2;
+      break;
+
+      case SOX_WAVE_TRIANGLE:
+      d = (double)point * 2 / table_size;
+      switch (4 * point / table_size)
+      {
+        case 0:         d = d + 0.5; break;
+        case 1: case 2: d = 1.5 - d; break;
+        case 3:         d = d - 1.5; break;
+      }
+      break;
+
+      default: /* Oops! FIXME */
+        d = 0.0; /* Make sure we have a value */
+      break;
+    }
+    d  = d * (max - min) + min;
+    switch (data_type)
+    {
+      case SOX_FLOAT:
+        {
+          float *fp = (float *)table;
+          *fp++ = (float)d;
+          table = fp;
+          continue;
+        }
+      case SOX_DOUBLE:
+        {
+          double *dp = (double *)table;
+          *dp++ = d;
+          table = dp;
+          continue;
+        }
+      default: break;
+    }
+    d += d < 0? -0.5 : +0.5;
+    switch (data_type)
+    {
+      case SOX_SHORT:
+        {
+          short *sp = table;
+          *sp++ = (short)d;
+          table = sp;
+          continue;
+        }
+      case SOX_INT:
+        {
+          int *ip = table;
+          *ip++ = (int)d;
+          table = ip;
+          continue;
+        }
+      default: break;
+    }
+  }
+}
+
+/*
+ * lsx_parsesamples
+ *
+ * Parse a string for # of samples.  If string ends with a 's'
+ * then the string is interpreted as a user calculated # of samples.
+ * If string contains ':' or '.' or if it ends with a 't' then its
+ * treated as an amount of time.  This is converted into seconds and
+ * fraction of seconds and then use the sample rate to calculate
+ * # of samples.
+ * Returns NULL on error, pointer to next char to parse otherwise.
+ */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str0, uint64_t *samples, int def)
+{
+  int i, found_samples = 0, found_time = 0;
+  char const * end;
+  char const * pos;
+  sox_bool found_colon, found_dot;
+  char * str = (char *)str0;
+
+  for (;*str == ' '; ++str);
+  for (end = str; *end && strchr("0123456789:.ets", *end); ++end);
+  if (end == str)
+    return NULL;
+
+  pos = strchr(str, ':');
+  found_colon = pos && pos < end;
+
+  pos = strchr(str, '.');
+  found_dot = pos && pos < end;
+
+  if (found_colon || found_dot || *(end-1) == 't')
+    found_time = 1;
+  else if (*(end-1) == 's')
+    found_samples = 1;
+
+  if (found_time || (def == 't' && !found_samples)) {
+    for (*samples = 0, i = 0; *str != '.' && i < 3; ++i) {
+      char * last_str = str;
+      long part = strtol(str, &str, 10);
+      if (!i && str == last_str)
+        return NULL;
+      *samples += rate * part;
+      if (i < 2) {
+        if (*str != ':')
+          break;
+        ++str;
+        *samples *= 60;
+      }
+    }
+    if (*str == '.') {
+      char * last_str = str;
+      double part = strtod(str, &str);
+      if (str == last_str)
+        return NULL;
+      *samples += rate * part + .5;
+    }
+    return *str == 't'? str + 1 : str;
+  }
+  {
+    char * last_str = str;
+    double part = strtod(str, &str);
+    if (str == last_str)
+      return NULL;
+    *samples = part + .5;
+    return *str == 's'? str + 1 : str;
+  }
+}
+
+#if 0
+
+#include <assert.h>
+
+#define TEST(st, samp, len) \
+  str = st; \
+  next = lsx_parsesamples(10000, str, &samples, 't'); \
+  assert(samples == samp && next == str + len);
+
+int main(int argc, char * * argv)
+{
+  char const * str, * next;
+  uint64_t samples;
+
+  TEST("0"  , 0, 1)
+  TEST("1" , 10000, 1)
+
+  TEST("0s" , 0, 2)
+  TEST("0s,", 0, 2)
+  TEST("0s/", 0, 2)
+  TEST("0s@", 0, 2)
+
+  TEST("0t" , 0, 2)
+  TEST("0t,", 0, 2)
+  TEST("0t/", 0, 2)
+  TEST("0t@", 0, 2)
+
+  TEST("1s" , 1, 2)
+  TEST("1s,", 1, 2)
+  TEST("1s/", 1, 2)
+  TEST("1s@", 1, 2)
+  TEST(" 01s" , 1, 4)
+  TEST("1e6s" , 1000000, 4)
+
+  TEST("1t" , 10000, 2)
+  TEST("1t,", 10000, 2)
+  TEST("1t/", 10000, 2)
+  TEST("1t@", 10000, 2)
+  TEST("1.1t" , 11000, 4)
+  TEST("1.1t,", 11000, 4)
+  TEST("1.1t/", 11000, 4)
+  TEST("1.1t@", 11000, 4)
+  TEST("1e6t" , 10000, 1)
+
+  TEST(".0", 0, 2)
+  TEST("0.0", 0, 3)
+  TEST("0:0.0", 0, 5)
+  TEST("0:0:0.0", 0, 7)
+
+  TEST(".1", 1000, 2)
+  TEST(".10", 1000, 3)
+  TEST("0.1", 1000, 3)
+  TEST("1.1", 11000, 3)
+  TEST("1:1.1", 611000, 5)
+  TEST("1:1:1.1", 36611000, 7)
+  TEST("1:1", 610000, 3)
+  TEST("1:01", 610000, 4)
+  TEST("1:1:1", 36610000, 5)
+  TEST("1:", 600000, 2)
+  TEST("1::", 36000000, 3)
+
+  TEST("0.444444", 4444, 8)
+  TEST("0.555555", 5556, 8)
+
+  assert(!lsx_parsesamples(10000, "x", &samples, 't'));
+  return 0;
+}
+#endif 
+
+/* a note is given as an int,
+ * 0   => 440 Hz = A
+ * >0  => number of half notes 'up',
+ * <0  => number of half notes down,
+ * example 12 => A of next octave, 880Hz
+ *
+ * calculated by freq = 440Hz * 2**(note/12)
+ */
+static double calc_note_freq(double note, int key)
+{
+  if (key != INT_MAX) {                         /* Just intonation. */
+    static const int n[] = {16, 9, 6, 5, 4, 7}; /* Numerator. */
+    static const int d[] = {15, 8, 5, 4, 3, 5}; /* Denominator. */
+    static double j[13];                        /* Just semitones */
+    int i, m = floor(note);
+
+    if (!j[1]) for (i = 1; i <= 12; ++i)
+      j[i] = i <= 6? log((double)n[i - 1] / d[i - 1]) / log(2.) : 1 - j[12 - i];
+    note -= m;
+    m -= key = m - ((INT_MAX / 2 - ((INT_MAX / 2) % 12) + m - key) % 12);
+    return 440 * pow(2., key / 12. + j[m] + (j[m + 1] - j[m]) * note);
+  }
+  return 440 * pow(2., note / 12);
+}
+
+int lsx_parse_note(char const * text, char * * end_ptr)
+{
+  int result = INT_MAX;
+
+  if (*text >= 'A' && *text <= 'G') {
+    result = (int)(5/3. * (*text++ - 'A') + 9.5) % 12 - 9;
+    if (*text == 'b') {--result; ++text;}
+    else if (*text == '#') {++result; ++text;}
+    if (isdigit((unsigned char)*text))
+      result += 12 * (*text++ - '4'); 
+  }
+  *end_ptr = (char *)text;
+  return result;
+}
+
+/* Read string 'text' and convert to frequency.
+ * 'text' can be a positive number which is the frequency in Hz.
+ * If 'text' starts with a '%' and a following number the corresponding
+ * note is calculated.
+ * Return -1 on error.
+ */
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key)
+{
+  double result;
+
+  if (*text == '%') {
+    result = strtod(text + 1, end_ptr);
+    if (*end_ptr == text + 1)
+      return -1;
+    return calc_note_freq(result, key);
+  }
+  if (*text >= 'A' && *text <= 'G') {
+    int result2 = lsx_parse_note(text, end_ptr);
+    return result2 == INT_MAX? - 1 : calc_note_freq((double)result2, key);
+  }
+  result = strtod(text, end_ptr);
+  if (end_ptr) {
+    if (*end_ptr == text)
+      return -1;
+    if (**end_ptr == 'k') {
+      result *= 1000;
+      ++*end_ptr;
+    }
+  }
+  return result < 0 ? -1 : result;
+}
+
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename)
+{
+  FILE * file;
+
+  if (!filename || !strcmp(filename, "-")) {
+    if (effp->global_info->global_info->stdin_in_use_by) {
+      lsx_fail("stdin already in use by `%s'", effp->global_info->global_info->stdin_in_use_by);
+      return NULL;
+    }
+    effp->global_info->global_info->stdin_in_use_by = effp->handler.name;
+    file = stdin;
+  }
+  else if (!(file = fopen(filename, "r"))) {
+    lsx_fail("couldn't open file %s: %s", filename, strerror(errno));
+    return NULL;
+  }
+  return file;
+}
+
+int lsx_effects_init(void)
+{
+  #ifndef __FREEDV__
+  init_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
+
+int lsx_effects_quit(void)
+{
+  #ifndef __FREEDV__
+  clear_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/formats_i.c b/freedv/branches/1.2/freedv-dev/src/sox/formats_i.c
new file mode 100644 (file)
index 0000000..17c4061
--- /dev/null
@@ -0,0 +1,487 @@
+/* Implements a libSoX internal interface for use in implementing file formats.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <string.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+
+void lsx_fail_errno(sox_format_t * ft, int sox_errno, const char *fmt, ...)
+{
+  va_list args;
+
+  ft->sox_errno = sox_errno;
+
+  va_start(args, fmt);
+#ifdef HAVE_VSNPRINTF
+  vsnprintf(ft->sox_errstr, sizeof(ft->sox_errstr), fmt, args);
+#else
+  vsprintf(ft->sox_errstr, fmt, args);
+#endif
+  va_end(args);
+  ft->sox_errstr[255] = '\0';
+}
+
+void lsx_set_signal_defaults(sox_format_t * ft)
+{
+  if (!ft->signal.rate     ) ft->signal.rate      = SOX_DEFAULT_RATE;
+  if (!ft->signal.precision) ft->signal.precision = SOX_DEFAULT_PRECISION;
+  if (!ft->signal.channels ) ft->signal.channels  = SOX_DEFAULT_CHANNELS;
+
+  if (!ft->encoding.bits_per_sample)
+    ft->encoding.bits_per_sample = ft->signal.precision;
+  if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+    ft->encoding.encoding = SOX_ENCODING_SIGN2;
+}
+
+#ifndef __FREEDV__
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length)
+{
+  ft->signal.length = ft->signal.length == SOX_IGNORE_LENGTH? SOX_UNSPEC : num_samples;
+
+  if (ft->seekable)
+    ft->data_start = lsx_tell(ft);
+
+  if (channels && ft->signal.channels && ft->signal.channels != channels)
+    lsx_warn("`%s': overriding number of channels", ft->filename);
+  else ft->signal.channels = channels;
+
+  if (rate && ft->signal.rate && ft->signal.rate != rate)
+    lsx_warn("`%s': overriding sample rate", ft->filename);
+  else ft->signal.rate = rate;
+
+  if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding)
+    lsx_warn("`%s': overriding encoding type", ft->filename);
+  else ft->encoding.encoding = encoding;
+
+  if (bits_per_sample && ft->encoding.bits_per_sample && ft->encoding.bits_per_sample != bits_per_sample)
+    lsx_warn("`%s': overriding encoding size", ft->filename);
+  ft->encoding.bits_per_sample = bits_per_sample;
+
+  if (check_length && ft->encoding.bits_per_sample && lsx_filelength(ft)) {
+    uint64_t calculated_length = div_bits(lsx_filelength(ft) - ft->data_start, ft->encoding.bits_per_sample);
+    if (!ft->signal.length)
+      ft->signal.length = calculated_length;
+    else if (num_samples != calculated_length)
+      lsx_warn("`%s': file header gives the total number of samples as %" PRIu64 " but file length indicates the number is in fact %" PRIu64, ft->filename, num_samples, calculated_length);
+  }
+
+  if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
+    return SOX_SUCCESS;
+  lsx_fail_errno(ft, EINVAL, "invalid format for this file type");
+  return SOX_EOF;
+}
+#endif
+
+/* Read in a buffer of data of length len bytes.
+ * Returns number of bytes read.
+ */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len)
+{
+  size_t ret = fread(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len && ferror((FILE*)ft->fp))
+    lsx_fail_errno(ft, errno, "lsx_readbuf");
+  ft->tell_off += ret;
+  return ret;
+}
+
+/* Skip input without seeking. */
+int lsx_skipbytes(sox_format_t * ft, size_t n)
+{
+  unsigned char trash;
+
+  while (n--)
+    if (lsx_readb(ft, &trash) == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Pad output. */
+int lsx_padbytes(sox_format_t * ft, size_t n)
+{
+  while (n--)
+    if (lsx_writeb(ft, '\0') == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Write a buffer of data of length bytes.
+ * Returns number of bytes written.
+ */
+size_t lsx_writebuf(sox_format_t * ft, void const * buf, size_t len)
+{
+  size_t ret = fwrite(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len) {
+    lsx_fail_errno(ft, errno, "error writing output file");
+    clearerr((FILE*)ft->fp); /* Allows us to seek back to write header */
+  }
+  ft->tell_off += ret;
+  return ret;
+}
+
+uint64_t lsx_filelength(sox_format_t * ft)
+{
+  struct stat st;
+  int ret = fstat(fileno((FILE*)ft->fp), &st);
+
+  return (!ret && (st.st_mode & S_IFREG))? (uint64_t)st.st_size : 0;
+}
+
+int lsx_flush(sox_format_t * ft)
+{
+  return fflush((FILE*)ft->fp);
+}
+
+off_t lsx_tell(sox_format_t * ft)
+{
+  return ft->seekable? (off_t)ftello((FILE*)ft->fp) : (off_t)ft->tell_off;
+}
+
+int lsx_eof(sox_format_t * ft)
+{
+  return feof((FILE*)ft->fp);
+}
+
+int lsx_error(sox_format_t * ft)
+{
+  return ferror((FILE*)ft->fp);
+}
+
+void lsx_rewind(sox_format_t * ft)
+{
+  rewind((FILE*)ft->fp);
+  ft->tell_off = 0;
+}
+
+void lsx_clearerr(sox_format_t * ft)
+{
+  clearerr((FILE*)ft->fp);
+  ft->sox_errno = 0;
+}
+
+int lsx_unreadb(sox_format_t * ft, unsigned b)
+{
+  return ungetc((int)b, ft->fp);
+}
+
+/* Implements traditional fseek() behavior.  Meant to abstract out
+ * file operations so that they could one day also work on memory
+ * buffers.
+ *
+ * N.B. Can only seek forwards on non-seekable streams!
+ */
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence)
+{
+    if (ft->seekable == 0) {
+        /* If a stream peel off chars else EPERM */
+        if (whence == SEEK_CUR) {
+            while (offset > 0 && !feof((FILE*)ft->fp)) {
+                getc((FILE*)ft->fp);
+                offset--;
+                ++ft->tell_off;
+            }
+            if (offset)
+                lsx_fail_errno(ft,SOX_EOF, "offset past EOF");
+            else
+                ft->sox_errno = SOX_SUCCESS;
+        } else
+            lsx_fail_errno(ft,SOX_EPERM, "file not seekable");
+    } else {
+        if (fseeko((FILE*)ft->fp, offset, whence) == -1)
+            lsx_fail_errno(ft,errno, "%s", strerror(errno));
+        else
+            ft->sox_errno = SOX_SUCCESS;
+    }
+    return ft->sox_errno;
+}
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample)
+{
+  double wide_sample = to_sample - (to_sample % ft->signal.channels);
+  double to_d = wide_sample * ft->encoding.bits_per_sample / 8;
+  off_t to = to_d;
+  return (to != to_d)? SOX_EOF : lsx_seeki(ft, (byte_offset + to), SEEK_SET);
+}
+
+/* Read and write known datatypes in "machine format".  Swap if indicated.
+ * They all return SOX_EOF on error and SOX_SUCCESS on success.
+ */
+/* Read n-char string (and possibly null-terminating).
+ * Stop reading and null-terminate string if either a 0 or \n is reached.
+ */
+int lsx_reads(sox_format_t * ft, char *c, size_t len)
+{
+    char *sc;
+    char in;
+
+    sc = c;
+    do
+    {
+        if (lsx_readbuf(ft, &in, (size_t)1) != 1)
+        {
+            *sc = 0;
+            return (SOX_EOF);
+        }
+        if (in == 0 || in == '\n')
+            break;
+
+        *sc = in;
+        sc++;
+    } while (sc - c < (ptrdiff_t)len);
+    *sc = 0;
+    return(SOX_SUCCESS);
+}
+
+/* Write null-terminated string (without \0). */
+int lsx_writes(sox_format_t * ft, char const * c)
+{
+        if (lsx_writebuf(ft, c, strlen(c)) != strlen(c))
+                return(SOX_EOF);
+        return(SOX_SUCCESS);
+}
+
+/* return swapped 32-bit float */
+static void lsx_swapf(float * f)
+{
+    union {
+        uint32_t dw;
+        float f;
+    } u;
+
+    u.f= *f;
+    u.dw= (u.dw>>24) | ((u.dw>>8)&0xff00) | ((u.dw<<8)&0xff0000) | (u.dw<<24);
+    *f = u.f;
+}
+
+static void swap(void * data, size_t len)
+{
+  uint8_t * bytes = (uint8_t *)data;
+  size_t i;
+
+  for (i = 0; i < len / 2; ++i) {
+    char tmp = bytes[i];
+    bytes[i] = bytes[len - 1 - i];
+    bytes[len - 1 - i] = tmp;
+  }
+}
+
+static double lsx_swapdf(double data)
+{
+  swap(&data, sizeof(data));
+  return data;
+}
+
+static uint64_t lsx_swapqw(uint64_t data)
+{
+  swap(&data, sizeof(data));
+  return data;
+}
+
+/* Lookup table to reverse the bit order of a byte. ie MSB become LSB */
+static uint8_t const cswap[256] = {
+  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
+  0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+  0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
+  0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
+  0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+  0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
+  0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
+  0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+  0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
+  0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
+  0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+  0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
+  0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
+  0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+  0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
+  0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
+  0x3F, 0xBF, 0x7F, 0xFF
+};
+
+/* Utilities to byte-swap values, use libc optimized macros if possible  */
+#define TWIDDLE_BYTE(ub, type) \
+  do { \
+    if (ft->encoding.reverse_bits) \
+      ub = cswap[ub]; \
+    if (ft->encoding.reverse_nibbles) \
+      ub = ((ub & 15) << 4) | (ub >> 4); \
+  } while (0);
+
+#define TWIDDLE_WORD(uw, type) \
+  if (ft->encoding.reverse_bytes) \
+    uw = lsx_swap ## type(uw);
+
+#define TWIDDLE_FLOAT(f, type) \
+  if (ft->encoding.reverse_bytes) \
+    lsx_swapf(&f);
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define READ_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    nread = lsx_readbuf(ft, buf, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      twiddle(buf[n], type); \
+    return nread; \
+  }
+
+/* Unpack a 3-byte value from a uint8_t * */
+#define sox_unpack3(p) (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN? \
+  ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16)) : \
+  ((p)[2] | ((p)[1] << 8) | ((p)[0] << 16)))
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be unpacked. */
+#define READ_FUNC_UNPACK(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    uint8_t *data = lsx_malloc(size * len); \
+    nread = lsx_readbuf(ft, data, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      buf[n] = sox_unpack ## size(data + n * size); \
+    free(data); \
+    return n; \
+  }
+
+READ_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+READ_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+READ_FUNC_UNPACK(3, 3, sox_uint24_t, TWIDDLE_WORD)
+READ_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+READ_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
+READ_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
+READ_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
+
+#define READ1_FUNC(type, ctype) \
+int lsx_read ## type(sox_format_t * ft, ctype * datum) { \
+  if (lsx_read_ ## type ## _buf(ft, datum, (size_t)1) == 1) \
+    return SOX_SUCCESS; \
+  if (!lsx_error(ft)) \
+    lsx_fail_errno(ft, errno, premature_eof); \
+  return SOX_EOF; \
+}
+
+static char const premature_eof[] = "premature EOF";
+
+READ1_FUNC(b,  uint8_t)
+READ1_FUNC(w,  uint16_t)
+READ1_FUNC(3,  sox_uint24_t)
+READ1_FUNC(dw, uint32_t)
+READ1_FUNC(qw, uint64_t)
+READ1_FUNC(f,  float)
+READ1_FUNC(df, double)
+
+int lsx_readchars(sox_format_t * ft, char * chars, size_t len)
+{
+  size_t ret = lsx_readbuf(ft, chars, len);
+  if (ret == len)
+    return SOX_SUCCESS;
+  if (!lsx_error(ft))
+    lsx_fail_errno(ft, errno, premature_eof);
+  return SOX_EOF;
+}
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define WRITE_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    for (n = 0; n < len; n++) \
+      twiddle(buf[n], type); \
+    nwritten = lsx_writebuf(ft, buf, len * size); \
+    return nwritten / size; \
+  }
+
+/* Pack a 3-byte value to a uint8_t * */
+#define sox_pack3(p, v) do {if (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN)\
+{(p)[0] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[2] = (v >> 16) & 0xff;} else \
+{(p)[2] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[0] = (v >> 16) & 0xff;} \
+} while (0)
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be packed. */
+#define WRITE_FUNC_PACK(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    uint8_t *data = lsx_malloc(size * len); \
+    for (n = 0; n < len; n++) \
+      sox_pack ## size(data + n * size, buf[n]); \
+    nwritten = lsx_writebuf(ft, data, len * size); \
+    free(data); \
+    return nwritten / size; \
+  }
+
+WRITE_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+WRITE_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+WRITE_FUNC_PACK(3, 3, sox_uint24_t, TWIDDLE_WORD)
+WRITE_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+WRITE_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
+WRITE_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
+WRITE_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
+
+#define WRITE1U_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, unsigned d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1S_FUNC(type, ctype) \
+  int lsx_writes ## type(sox_format_t * ft, signed d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, ctype datum) \
+  { \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+WRITE1U_FUNC(b, uint8_t)
+WRITE1U_FUNC(w, uint16_t)
+WRITE1U_FUNC(3, sox_uint24_t)
+WRITE1U_FUNC(dw, uint32_t)
+WRITE1_FUNC(qw, uint64_t)
+WRITE1S_FUNC(b, uint8_t)
+WRITE1S_FUNC(w, uint16_t)
+WRITE1_FUNC(df, double)
+
+int lsx_writef(sox_format_t * ft, double datum)
+{
+  float f = datum;
+  return lsx_write_f_buf(ft, &f, (size_t) 1) == 1 ? SOX_SUCCESS : SOX_EOF;
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/libsox.c b/freedv/branches/1.2/freedv-dev/src/sox/libsox.c
new file mode 100644 (file)
index 0000000..4362025
--- /dev/null
@@ -0,0 +1,225 @@
+/* Implements the public API for libSoX general functions
+ * All public functions & data are prefixed with sox_ .
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <string.h>
+
+const char *sox_version(void)
+{
+  static char versionstr[20];
+
+  sprintf(versionstr, "%d.%d.%d",
+          (SOX_LIB_VERSION_CODE & 0xff0000) >> 16,
+          (SOX_LIB_VERSION_CODE & 0x00ff00) >> 8,
+          (SOX_LIB_VERSION_CODE & 0x0000ff));
+  return(versionstr);
+}
+
+sox_version_info_t const * sox_version_info(void)
+{
+#define STRINGIZE1(x) #x
+#define STRINGIZE(x) STRINGIZE1(x)
+    static char arch[30];
+    static sox_version_info_t info = {
+        /* size */
+        sizeof(sox_version_info_t),
+        /* flags */
+        (sox_version_flags_t)(
+#if HAVE_POPEN
+        sox_version_have_popen +
+#endif
+#if  HAVE_MAGIC
+        sox_version_have_magic +
+#endif
+#if HAVE_OPENMP
+        sox_version_have_threads +
+#endif
+#ifdef HAVE_FMEMOPEN
+        sox_version_have_memopen +
+#endif
+        sox_version_none),
+        /* version_code */
+        SOX_LIB_VERSION_CODE,
+        /* version */
+        NULL,
+        /* sox_version_extra */
+#ifdef PACKAGE_EXTRA
+        PACKAGE_EXTRA,
+#else
+        NULL,
+#endif
+        /* sox_time */
+        __DATE__ " " __TIME__,
+        /* sox_distro */
+#ifdef DISTRO
+        DISTRO,
+#else
+        NULL,
+#endif
+        /* sox_compiler */
+#if defined __GNUC__
+        "gcc " __VERSION__,
+#elif defined _MSC_VER
+        "msvc " STRINGIZE(_MSC_FULL_VER),
+#elif defined __SUNPRO_C
+    fprintf(file, "sun c " STRINGIZE(__SUNPRO_C),
+#else
+        NULL,
+#endif
+        /* sox_arch */
+        NULL
+    };
+
+    if (!info.version)
+    {
+        info.version = sox_version();
+    }
+
+    if (!info.arch)
+    {
+        snprintf(arch, sizeof(arch),
+            "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR
+            " %" PRIuPTR "%" PRIuPTR " %" PRIuPTR "%" PRIuPTR " %c %s",
+            sizeof(char), sizeof(short), sizeof(long), sizeof(off_t),
+            sizeof(float), sizeof(double), sizeof(int *), sizeof(int (*)(void)),
+            MACHINE_IS_BIGENDIAN ? 'B' : 'L',
+            (info.flags & sox_version_have_threads) ? "OMP" : "");
+        arch[sizeof(arch) - 1] = 0;
+        info.arch = arch;
+    }
+
+    return &info;
+}
+
+/* Default routine to output messages; can be overridden */
+static void output_message(
+    unsigned level, const char *filename, const char *fmt, va_list ap)
+{
+  if (sox_globals.verbosity >= level) {
+    char base_name[128];
+    sox_basename(base_name, sizeof(base_name), filename);
+    fprintf(stderr, "%s: ", base_name);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+  }
+}
+
+static sox_globals_t s_sox_globals = {
+  2,               /* unsigned     verbosity */
+  output_message,  /* sox_output_message_handler */
+  sox_false,       /* sox_bool     repeatable */
+  8192,            /* size_t       bufsiz */
+  0,               /* size_t       input_bufsiz */
+  0,               /* int32_t      ranqd1 */
+  NULL,            /* char const * stdin_in_use_by */
+  NULL,            /* char const * stdout_in_use_by */
+  NULL,            /* char const * subsystem */
+  NULL,            /* char       * tmp_path */
+  sox_false,       /* sox_bool     use_magic */
+  sox_false        /* sox_bool     use_threads */
+};
+
+sox_globals_t * sox_get_globals(void)
+{
+    return &s_sox_globals;
+}
+
+/* FIXME: Not thread safe using globals */
+static sox_effects_globals_t s_sox_effects_globals =
+    {sox_plot_off, &s_sox_globals};
+
+sox_effects_globals_t *
+sox_get_effects_globals(void)
+{
+    return &s_sox_effects_globals;
+}
+
+char const * sox_strerror(int sox_errno)
+{
+  static char const * const errors[] = {
+    "Invalid Audio Header",
+    "Unsupported data format",
+    "Can't allocate memory",
+    "Operation not permitted",
+    "Operation not supported",
+    "Invalid argument",
+  };
+  if (sox_errno < SOX_EHDR)
+    return strerror(sox_errno);
+  sox_errno -= SOX_EHDR;
+  if (sox_errno < 0 || (size_t)sox_errno >= array_length(errors))
+    return "Unknown error";
+  return errors[sox_errno];
+}
+
+size_t sox_basename(char * base_buffer, size_t base_buffer_len, const char * filename)
+{
+  if (!base_buffer || !base_buffer_len)
+  {
+    return 0;
+  }
+  else
+  {
+    char const * slash_pos = LAST_SLASH(filename);
+    char const * base_name = slash_pos ? slash_pos + 1 : filename;
+    char const * dot_pos   = strrchr(base_name, '.');
+    size_t i, len;
+    dot_pos = dot_pos ? dot_pos : base_name + strlen(base_name);
+    len = dot_pos - base_name;
+    len = min(len, base_buffer_len - 1);
+    for (i = 0; i < len; i++)
+    {
+      base_buffer[i] = base_name[i];
+    }
+    base_buffer[i] = 0;
+    return i;
+  }
+}
+
+#define SOX_MESSAGE_FUNCTION(name,level) \
+void name(char const * fmt, ...) { \
+  va_list ap; \
+  va_start(ap, fmt); \
+  if (sox_globals.output_message_handler) \
+    (*sox_globals.output_message_handler)(level,sox_globals.subsystem,fmt,ap); \
+  va_end(ap); \
+}
+
+SOX_MESSAGE_FUNCTION(lsx_fail_impl  , 1)
+SOX_MESSAGE_FUNCTION(lsx_warn_impl  , 2)
+SOX_MESSAGE_FUNCTION(lsx_report_impl, 3)
+SOX_MESSAGE_FUNCTION(lsx_debug_impl , 4)
+SOX_MESSAGE_FUNCTION(lsx_debug_more_impl , 5)
+SOX_MESSAGE_FUNCTION(lsx_debug_most_impl , 6)
+
+#undef SOX_MESSAGE_FUNCTION
+
+int sox_init(void)
+{
+  return lsx_effects_init();
+}
+
+int sox_quit(void)
+{
+  #ifndef __FREEDV__
+  sox_format_quit();
+  #endif
+  return lsx_effects_quit();
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/sox.h b/freedv/branches/1.2/freedv-dev/src/sox/sox.h
new file mode 100644 (file)
index 0000000..0537255
--- /dev/null
@@ -0,0 +1,2608 @@
+/* libSoX Library Public Interface
+ *
+ * Copyright 1999-2011 Chris Bagwell and SoX Contributors.
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/** @file
+Contains the interface exposed to clients of the libSoX library.
+Symbols starting with "sox_" or "SOX_" are part of the public interface for
+libSoX clients (applications that consume libSoX). Symbols starting with
+"lsx_" or "LSX_" are internal use by libSoX and plugins.
+LSX_ and lsx_ symbols should not be used by libSoX-based applications.
+*/
+
+#ifndef SOX_H
+#define SOX_H /**< Client API: This macro is defined if sox.h has been included. */
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Suppress warnings from use of type long long. */
+#if defined __GNUC__
+#pragma GCC system_header
+#endif
+
+/*****************************************************************************
+API decoration macros:
+Mostly for documentation purposes. For some compilers, decorations also affect
+code generation, influence compiler warnings or activate compiler
+optimizations.
+*****************************************************************************/
+
+/**
+Plugins API:
+Attribute required on all functions exported by libSoX and on all function
+pointer types used by the libSoX API.
+*/
+#ifdef __GNUC__
+#define LSX_API  __attribute__ ((cdecl)) /* libSoX function */
+#elif _MSC_VER
+#define LSX_API  __cdecl /* libSoX function */
+#else
+#define LSX_API /* libSoX function */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter or local variable to suppress warnings about
+the variable being unused (especially in macro-generated code).
+*/
+#ifdef __GNUC__
+#define LSX_UNUSED  __attribute__ ((unused)) /* Parameter or local variable is intentionally unused. */
+#else
+#define LSX_UNUSED /* Parameter or local variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+LSX_PRINTF12: Attribute applied to a function to indicate that it requires
+a printf-style format string for arg1 and that printf parameters start at
+arg2.
+*/
+#ifdef __GNUC__
+#define LSX_PRINTF12  __attribute__ ((format (printf, 1, 2))) /* Function has printf-style arguments. */
+#else
+#define LSX_PRINTF12 /* Function has printf-style arguments. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that it has no side effects and
+depends only its input parameters and global memory. If called repeatedly, it
+returns the same result each time.
+*/
+#ifdef __GNUC__
+#define LSX_RETURN_PURE __attribute__ ((pure)) /* Function is pure. */
+#else
+#define LSX_RETURN_PURE /* Function is pure. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the
+return value is always a pointer to a valid object (never NULL).
+*/
+#ifdef _Ret_
+#define LSX_RETURN_VALID _Ret_ /* Function always returns a valid object (never NULL). */
+#else
+#define LSX_RETURN_VALID /* Function always returns a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid array (never NULL).
+*/
+#ifdef _Ret_valid_
+#define LSX_RETURN_ARRAY _Ret_valid_ /* Function always returns a valid array (never NULL). */
+#else
+#define LSX_RETURN_ARRAY /* Function always returns a valid array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid 0-terminated array (never NULL).
+*/
+#ifdef _Ret_z_
+#define LSX_RETURN_VALID_Z _Ret_z_ /* Function always returns a 0-terminated array (never NULL). */
+#else
+#define LSX_RETURN_VALID_Z /* Function always returns a 0-terminated array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the returned pointer may be
+null.
+*/
+#ifdef _Ret_opt_
+#define LSX_RETURN_OPT _Ret_opt_ /* Function may return NULL. */
+#else
+#define LSX_RETURN_OPT /* Function may return NULL. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one const element of the pointed-to type (never NULL).
+*/
+#ifdef _In_
+#define LSX_PARAM_IN _In_ /* Required const pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_IN /* Required const pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to a const 0-terminated string (never NULL).
+*/
+#ifdef _In_z_
+#define LSX_PARAM_IN_Z _In_z_ /* Required const pointer to 0-terminated string (never NULL). */
+#else
+#define LSX_PARAM_IN_Z /* Required const pointer to 0-terminated string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a const
+pointer to a 0-terminated printf format string.
+*/
+#ifdef _Printf_format_string_
+#define LSX_PARAM_IN_PRINTF _Printf_format_string_ /* Required const pointer to 0-terminated printf format string (never NULL). */
+#else
+#define LSX_PARAM_IN_PRINTF /* Required const pointer to 0-terminated printf format string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const initialized elements of the pointed-to type, where
+(len) is the name of another parameter.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _In_count_
+#define LSX_PARAM_IN_COUNT(len) _In_count_(len) /* Required const pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_IN_COUNT(len) /* Required const pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const bytes of initialized data, where (len) is the name of
+another parameter.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _In_bytecount_
+#define LSX_PARAM_IN_BYTECOUNT(len) _In_bytecount_(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#else
+#define LSX_PARAM_IN_BYTECOUNT(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to one const element of the pointed-to type.
+*/
+#ifdef _In_opt_
+#define LSX_PARAM_IN_OPT _In_opt_ /* Optional const pointer to a valid object (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT /* Optional const pointer to a valid object (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to a const 0-terminated string.
+*/
+#ifdef _In_opt_z_
+#define LSX_PARAM_IN_OPT_Z _In_opt_z_ /* Optional const pointer to 0-terminated string (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT_Z /* Optional const pointer to 0-terminated string (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one initialized element of the pointed-to type (never NULL). The
+function may modify the element.
+*/
+#ifdef _Inout_
+#define LSX_PARAM_INOUT _Inout_ /* Required pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_INOUT /* Required pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) initialized elements of the pointed-to type (never NULL). The
+function may modify the elements.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _Inout_count_x_
+#define LSX_PARAM_INOUT_COUNT(len) _Inout_count_x_(len) /* Required pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_INOUT_COUNT(len) /* Required pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for one element of the pointed-to type (never
+NULL). The function will initialize the element.
+*/
+#ifdef _Out_
+#define LSX_PARAM_OUT _Out_ /* Required pointer to an object to be initialized (never NULL). */
+#else
+#define LSX_PARAM_OUT /* Required pointer to an object to be initialized (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) bytes of data (never NULL), where (len)
+is the name of another parameter. The function may write up to len bytes of
+data to this memory.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _Out_bytecap_
+#define LSX_PARAM_OUT_BYTECAP(len) _Out_bytecap_(len) /* Required pointer to writable buffer with room for len bytes. */
+#else
+#define LSX_PARAM_OUT_BYTECAP(len) /* Required pointer to writable buffer with room for len bytes. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled)
+elements will have been initialized, where (filled) is either the dereference
+of another pointer parameter (for example "*written") or the "return"
+parameter (indicating that the function returns the number of elements
+written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array, or "return" if the value is returned.
+*/
+#ifdef _Out_cap_post_count_
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) _Out_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#else
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled+1)
+elements will have been initialized, with the last element having been
+initialized to 0, where (filled) is either the dereference of another pointer
+parameter (for example, "*written") or the "return" parameter (indicating that
+the function returns the number of elements written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array (not counting the terminating null), or "return" if the value is returned.
+*/
+#ifdef _Out_z_cap_post_count_
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) _Out_z_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#else
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to memory sufficient for one element of the pointed-to
+type. The function will initialize the element.
+*/
+#ifdef _Out_opt_
+#define LSX_PARAM_OUT_OPT _Out_opt_ /* Optional pointer to an object to be initialized (may be NULL). */
+#else
+#define LSX_PARAM_OUT_OPT /* Optional pointer to an object to be initialized (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which may be NULL when the function is
+invoked.
+*/
+#ifdef _Deref_pre_maybenull_
+#define LSX_PARAM_DEREF_PRE_MAYBENULL _Deref_pre_maybenull_ /* Required pointer (never NULL) to another pointer (may be NULL). */
+#else
+#define LSX_PARAM_DEREF_PRE_MAYBENULL /* Required pointer (never NULL) to another pointer (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be NULL when the function
+returns.
+*/
+#ifdef _Deref_post_null_
+#define LSX_PARAM_DEREF_POST_NULL _Deref_post_null_ /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NULL /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be non-NULL when the
+function returns.
+*/
+#ifdef _Deref_post_notnull_
+#define LSX_PARAM_DEREF_POST_NOTNULL _Deref_post_notnull_ /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NOTNULL /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#endif
+
+/**
+Plugins API:
+Expression that "uses" a potentially-unused variable to avoid compiler
+warnings (especially in macro-generated code).
+*/
+#ifdef _PREFAST_
+#define LSX_USE_VAR(x)  ((void)(x=0)) /* During static analysis, initialize unused variables to 0. */
+#else
+#define LSX_USE_VAR(x)  ((void)(x)) /* Parameter or variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+Compile-time assertion. Causes a compile error if the expression is false.
+@param e  The expression to test. If expression is false, compilation will fail.
+@param f  A unique identifier for the test, for example foo_must_not_be_zero.
+*/
+#define lsx_static_assert(e,f) enum {lsx_static_assert_##f = 1/((e) ? 1 : 0)}
+
+/*****************************************************************************
+Basic typedefs:
+*****************************************************************************/
+
+/**
+Client API:
+Signed twos-complement 8-bit type. Typically defined as signed char.
+*/
+#if SCHAR_MAX==127 && SCHAR_MIN==(-128)
+typedef signed char sox_int8_t;
+#elif CHAR_MAX==127 && CHAR_MIN==(-128)
+typedef char sox_int8_t;
+#else
+#error Unable to determine an appropriate definition for sox_int8_t.
+#endif
+
+/**
+Client API:
+Unsigned 8-bit type. Typically defined as unsigned char.
+*/
+#if UCHAR_MAX==0xff
+typedef unsigned char sox_uint8_t;
+#elif CHAR_MAX==0xff && CHAR_MIN==0
+typedef char sox_uint8_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint8_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 16-bit type. Typically defined as short.
+*/
+#if SHRT_MAX==32767 && SHRT_MIN==(-32768)
+typedef short sox_int16_t;
+#elif INT_MAX==32767 && INT_MIN==(-32768)
+typedef int sox_int16_t;
+#else
+#error Unable to determine an appropriate definition for sox_int16_t.
+#endif
+
+/**
+Client API:
+Unsigned 16-bit type. Typically defined as unsigned short.
+*/
+#if USHRT_MAX==0xffff
+typedef unsigned short sox_uint16_t;
+#elif UINT_MAX==0xffff
+typedef unsigned int sox_uint16_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint16_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 32-bit type. Typically defined as int.
+*/
+#if INT_MAX==2147483647 && INT_MIN==(-2147483647-1)
+typedef int sox_int32_t;
+#elif LONG_MAX==2147483647 && LONG_MIN==(-2147483647-1)
+typedef long sox_int32_t;
+#else
+#error Unable to determine an appropriate definition for sox_int32_t.
+#endif
+
+/**
+Client API:
+Unsigned 32-bit type. Typically defined as unsigned int.
+*/
+#if UINT_MAX==0xffffffff
+typedef unsigned int sox_uint32_t;
+#elif ULONG_MAX==0xffffffff
+typedef unsigned long sox_uint32_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint32_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 64-bit type. Typically defined as long or long long.
+*/
+#if LONG_MAX==9223372036854775807 && LONG_MIN==(-9223372036854775807-1)
+typedef long sox_int64_t;
+#elif defined(_MSC_VER)
+typedef __int64 sox_int64_t;
+#else
+typedef long long sox_int64_t;
+#endif
+
+/**
+Client API:
+Unsigned 64-bit type. Typically defined as unsigned long or unsigned long long.
+*/
+#if ULONG_MAX==0xffffffffffffffff
+typedef unsigned long sox_uint64_t;
+#elif defined(_MSC_VER)
+typedef unsigned __int64 sox_uint64_t;
+#else
+typedef unsigned long long sox_uint64_t;
+#endif
+
+#ifndef _DOXYGEN_
+lsx_static_assert(sizeof(sox_int8_t)==1,   sox_int8_size);
+lsx_static_assert(sizeof(sox_uint8_t)==1,  sox_uint8_size);
+lsx_static_assert(sizeof(sox_int16_t)==2,  sox_int16_size);
+lsx_static_assert(sizeof(sox_uint16_t)==2, sox_uint16_size);
+lsx_static_assert(sizeof(sox_int32_t)==4,  sox_int32_size);
+lsx_static_assert(sizeof(sox_uint32_t)==4, sox_uint32_size);
+lsx_static_assert(sizeof(sox_int64_t)==8,  sox_int64_size);
+lsx_static_assert(sizeof(sox_uint64_t)==8, sox_uint64_size);
+#endif
+
+/**
+Client API:
+Alias for sox_int32_t (beware of the extra byte).
+*/
+typedef sox_int32_t sox_int24_t;
+
+/**
+Client API:
+Alias for sox_uint32_t (beware of the extra byte).
+*/
+typedef sox_uint32_t sox_uint24_t;
+
+/**
+Client API:
+Native SoX audio sample type (alias for sox_int32_t).
+*/
+typedef sox_int32_t sox_sample_t;
+
+/**
+Client API:
+Samples per second is stored as a double.
+*/
+typedef double sox_rate_t;
+
+/**
+Client API:
+File's metadata, access via sox_*_comments functions.
+*/
+typedef char * * sox_comments_t;
+
+/*****************************************************************************
+Enumerations:
+*****************************************************************************/
+
+/**
+Client API:
+Boolean type, assignment (but not necessarily binary) compatible with C++ bool.
+*/
+typedef enum sox_bool {
+    sox_false, /**< False = 0. */
+    sox_true   /**< True = 1. */
+} sox_bool;
+
+/**
+Client API:
+no, yes, or default (default usually implies some kind of auto-detect logic).
+*/
+typedef enum sox_option_t {
+    sox_option_no,      /**< Option specified as no = 0. */
+    sox_option_yes,     /**< Option specified as yes = 1. */
+    sox_option_default  /**< Option unspecified = 2. */
+} sox_option_t;
+
+/**
+Client API:
+The libSoX-specific error codes.
+libSoX functions may return these codes or others that map from errno codes.
+*/
+enum sox_error_t {
+  SOX_SUCCESS = 0,     /**< Function succeeded = 0 */
+  SOX_EOF = -1,        /**< End Of File or other error = -1 */
+  SOX_EHDR = 2000,     /**< Invalid Audio Header = 2000 */
+  SOX_EFMT,            /**< Unsupported data format = 2001 */
+  SOX_ENOMEM,          /**< Can't alloc memory = 2002 */
+  SOX_EPERM,           /**< Operation not permitted = 2003 */
+  SOX_ENOTSUP,         /**< Operation not supported = 2004 */
+  SOX_EINVAL           /**< Invalid argument = 2005 */
+};
+
+/**
+Client API:
+Flags indicating whether optional features are present in this build of libSoX.
+*/
+typedef enum sox_version_flags_t {
+    sox_version_none = 0,         /**< No special features = 0. */
+    sox_version_have_popen = 1,   /**< popen = 1. */
+    sox_version_have_magic = 2,   /**< magic = 2. */
+    sox_version_have_threads = 4, /**< threads = 4. */
+    sox_version_have_memopen = 8  /**< memopen = 8. */
+} sox_version_flags_t;
+
+/**
+Client API:
+Format of sample data.
+*/
+typedef enum sox_encoding_t {
+  SOX_ENCODING_UNKNOWN   , /**< encoding has not yet been determined */
+
+  SOX_ENCODING_SIGN2     , /**< signed linear 2's comp: Mac */
+  SOX_ENCODING_UNSIGNED  , /**< unsigned linear: Sound Blaster */
+  SOX_ENCODING_FLOAT     , /**< floating point (binary format) */
+  SOX_ENCODING_FLOAT_TEXT, /**< floating point (text format) */
+  SOX_ENCODING_FLAC      , /**< FLAC compression */
+  SOX_ENCODING_HCOM      , /**< Mac FSSD files with Huffman compression */
+  SOX_ENCODING_WAVPACK   , /**< WavPack with integer samples */
+  SOX_ENCODING_WAVPACKF  , /**< WavPack with float samples */
+  SOX_ENCODING_ULAW      , /**< u-law signed logs: US telephony, SPARC */
+  SOX_ENCODING_ALAW      , /**< A-law signed logs: non-US telephony, Psion */
+  SOX_ENCODING_G721      , /**< G.721 4-bit ADPCM */
+  SOX_ENCODING_G723      , /**< G.723 3 or 5 bit ADPCM */
+  SOX_ENCODING_CL_ADPCM  , /**< Creative Labs 8 --> 2,3,4 bit Compressed PCM */
+  SOX_ENCODING_CL_ADPCM16, /**< Creative Labs 16 --> 4 bit Compressed PCM */
+  SOX_ENCODING_MS_ADPCM  , /**< Microsoft Compressed PCM */
+  SOX_ENCODING_IMA_ADPCM , /**< IMA Compressed PCM */
+  SOX_ENCODING_OKI_ADPCM , /**< Dialogic/OKI Compressed PCM */
+  SOX_ENCODING_DPCM      , /**< Differential PCM: Fasttracker 2 (xi) */
+  SOX_ENCODING_DWVW      , /**< Delta Width Variable Word */
+  SOX_ENCODING_DWVWN     , /**< Delta Width Variable Word N-bit */
+  SOX_ENCODING_GSM       , /**< GSM 6.10 33byte frame lossy compression */
+  SOX_ENCODING_MP3       , /**< MP3 compression */
+  SOX_ENCODING_VORBIS    , /**< Vorbis compression */
+  SOX_ENCODING_AMR_WB    , /**< AMR-WB compression */
+  SOX_ENCODING_AMR_NB    , /**< AMR-NB compression */
+  SOX_ENCODING_CVSD      , /**< Continuously Variable Slope Delta modulation */
+  SOX_ENCODING_LPC10     , /**< Linear Predictive Coding */
+
+  SOX_ENCODINGS            /**< End of list marker */
+} sox_encoding_t;
+
+/**
+Client API:
+Flags for sox_encodings_info_t: lossless/lossy1/lossy2.
+*/
+typedef enum sox_encodings_flags_t {
+  sox_encodings_none   = 0, /**< no flags specified (implies lossless encoding) = 0. */
+  sox_encodings_lossy1 = 1, /**< encode, decode: lossy once = 1. */
+  sox_encodings_lossy2 = 2  /**< encode, decode, encode, decode: lossy twice = 2. */
+} sox_encodings_flags_t;
+
+/**
+Client API:
+Type of plot.
+*/
+typedef enum sox_plot_t {
+    sox_plot_off,     /**< No plot = 0. */
+    sox_plot_octave,  /**< Octave plot = 1. */
+    sox_plot_gnuplot, /**< Gnuplot plot = 2. */
+    sox_plot_data     /**< Plot data = 3. */
+} sox_plot_t;
+
+/**
+Client API:
+Loop modes: upper 4 bits mask the loop blass, lower 4 bits describe
+the loop behaviour, for example single shot, bidirectional etc.
+*/
+enum sox_loop_flags_t {
+  sox_loop_none = 0,          /**< single-shot = 0 */
+  sox_loop_forward = 1,       /**< forward loop = 1 */
+  sox_loop_forward_back = 2,  /**< forward/back loop = 2 */
+  sox_loop_8 = 32,            /**< 8 loops (??) = 32 */
+  sox_loop_sustain_decay = 64 /**< AIFF style, one sustain & one decay loop = 64 */
+};
+
+/**
+Plugins API:
+Is file a real file, a pipe, or a url?
+*/
+typedef enum lsx_io_type
+{
+    lsx_io_file, /**< File is a real file = 0. */
+    lsx_io_pipe, /**< File is a pipe (no seeking) = 1. */
+    lsx_io_url   /**< File is a URL (no seeking) = 2. */
+} lsx_io_type;
+
+/*****************************************************************************
+Macros:
+*****************************************************************************/
+
+/**
+Client API:
+Compute a 32-bit integer API version from three 8-bit parts.
+@param a Major version.
+@param b Minor version.
+@param c Revision or build number.
+@returns 32-bit integer API version 0x000a0b0c.
+*/
+#define SOX_LIB_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+
+/**
+Client API:
+The API version of the sox.h file. It is not meant to follow the version
+number of SoX but it has historically. Please do not count on
+SOX_LIB_VERSION_CODE staying in sync with the libSoX version.
+*/
+#define SOX_LIB_VERSION_CODE   SOX_LIB_VERSION(14, 4, 1)
+
+/**
+Client API:
+Returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MIN(8) = 0x80, SOX_INT_MIN(16) = 0x8000, etc.
+@param bits Size of value for which to calculate minimum.
+@returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MIN(bits) (1 <<((bits)-1))
+
+/**
+Client API:
+Returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MAX(8) = 0x7F, SOX_INT_MAX(16) = 0x7FFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MAX(bits) (((unsigned)-1)>>(33-(bits)))
+
+/**
+Client API:
+Returns the largest value storable in an unsigned integer with the specified
+number of bits; for example, SOX_UINT_MAX(8) = 0xFF,
+SOX_UINT_MAX(16) = 0xFFFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest value storable in an unsigned integer with the specified
+number of bits.
+*/
+#define SOX_UINT_MAX(bits) (SOX_INT_MIN(bits)|SOX_INT_MAX(bits))
+
+/**
+Client API:
+Returns 0x7F.
+*/
+#define SOX_INT8_MAX  SOX_INT_MAX(8)
+
+/**
+Client API:
+Returns 0x7FFF.
+*/
+#define SOX_INT16_MAX SOX_INT_MAX(16)
+
+/**
+Client API:
+Returns 0x7FFFFF.
+*/
+#define SOX_INT24_MAX SOX_INT_MAX(24)
+
+/**
+Client API:
+Returns 0x7FFFFFFF.
+*/
+#define SOX_INT32_MAX SOX_INT_MAX(32)
+
+/**
+Client API:
+Bits in a sox_sample_t = 32.
+*/
+#define SOX_SAMPLE_PRECISION 32
+
+/**
+Client API:
+Max value for sox_sample_t = 0x7FFFFFFF.
+*/
+#define SOX_SAMPLE_MAX (sox_sample_t)SOX_INT_MAX(32)
+
+/**
+Client API:
+Min value for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_MIN (sox_sample_t)SOX_INT_MIN(32)
+
+
+/*                Conversions: Linear PCM <--> sox_sample_t
+ *
+ *   I/O      Input    sox_sample_t Clips?   Input    sox_sample_t Clips?
+ *  Format   Minimum     Minimum     I O    Maximum     Maximum     I O
+ *  ------  ---------  ------------ -- --   --------  ------------ -- --
+ *  Float     -inf         -1        y n      inf      1 - 5e-10    y n
+ *  Int8      -128        -128       n n      127     127.9999999   n y
+ *  Int16    -32768      -32768      n n     32767    32767.99998   n y
+ *  Int24   -8388608    -8388608     n n    8388607   8388607.996   n y
+ *  Int32  -2147483648 -2147483648   n n   2147483647 2147483647    n n
+ *
+ * Conversions are as accurate as possible (with rounding).
+ *
+ * Rounding: halves toward +inf, all others to nearest integer.
+ *
+ * Clips? shows whether on not there is the possibility of a conversion
+ * clipping to the minimum or maximum value when inputing from or outputing
+ * to a given type.
+ *
+ * Unsigned integers are converted to and from signed integers by flipping
+ * the upper-most bit then treating them as signed integers.
+ */
+
+/**
+Client API:
+Declares the temporary local variables that are required when using SOX
+conversion macros.
+*/
+#define SOX_SAMPLE_LOCALS sox_sample_t sox_macro_temp_sample LSX_UNUSED; \
+  double sox_macro_temp_double LSX_UNUSED
+
+/**
+Client API:
+Sign bit for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_NEG SOX_INT_MIN(32)
+
+/**
+Client API:
+Converts sox_sample_t to an unsigned integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Unsigned integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_UNSIGNED(bits,d,clips) \
+  (sox_uint##bits##_t)(SOX_SAMPLE_TO_SIGNED(bits,d,clips)^SOX_INT_MIN(bits))
+
+/**
+Client API:
+Converts sox_sample_t to a signed integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Signed integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \
+  (sox_int##bits##_t)(LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-(1<<(31-bits))?++(clips),SOX_INT_MAX(bits):((sox_uint32_t)(sox_macro_temp_sample+(1<<(31-bits))))>>(32-bits))
+
+/**
+Client API:
+Converts signed integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-bits))
+
+/**
+Client API:
+Converts unsigned integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts unsigned 8-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_8BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts signed 8-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_8BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts unsigned 16-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_16BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts signed 16-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_16BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts unsigned 24-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_24BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts signed 24-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_24BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts unsigned 32-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts signed 32-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d)
+
+/**
+Client API:
+Converts 32-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<SOX_SAMPLE_MIN?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double>=SOX_SAMPLE_MAX+1.?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double)
+
+/**
+Client API:
+Converts 64-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<0?sox_macro_temp_double<=SOX_SAMPLE_MIN-.5?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double-.5:sox_macro_temp_double>=SOX_SAMPLE_MAX+.5?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double+.5)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an signed 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_8BIT(d,clips) SOX_SAMPLE_TO_SIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) SOX_SAMPLE_TO_SIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_24BIT(d,clips) SOX_SAMPLE_TO_SIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d,clips) (sox_uint32_t)((d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts SoX native sample to a signed 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_SIGNED_32BIT(d,clips) (sox_int32_t)(d)
+
+/**
+Client API:
+Converts SoX native sample to a 32-bit float.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_FLOAT_32BIT(d,clips) (LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-128?++(clips),1:(((sox_macro_temp_sample+128)&~255)*(1./(SOX_SAMPLE_MAX+1.))))
+
+/**
+Client API:
+Converts SoX native sample to a 64-bit float.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_FLOAT_64BIT(d,clips) ((d)*(1./(SOX_SAMPLE_MAX+1.)))
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param samp Value (lvalue) to be clipped, updated as necessary.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+*/
+#define SOX_SAMPLE_CLIP_COUNT(samp, clips) \
+  do { \
+    if (samp > SOX_SAMPLE_MAX) \
+      { samp = SOX_SAMPLE_MAX; clips++; } \
+    else if (samp < SOX_SAMPLE_MIN) \
+      { samp = SOX_SAMPLE_MIN; clips++; } \
+  } while (0)
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param d Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_ROUND_CLIP_COUNT(d, clips) \
+  ((d) < 0? (d) <= SOX_SAMPLE_MIN - 0.5? ++(clips), SOX_SAMPLE_MIN: (d) - 0.5 \
+        : (d) >= SOX_SAMPLE_MAX + 0.5? ++(clips), SOX_SAMPLE_MAX: (d) + 0.5)
+
+/**
+Client API:
+Clips a value to the limits of a signed integer of the specified width
+and increment a counter if clipping occurs.
+@param bits Width (in bits) of target integer type.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_INTEGER_CLIP_COUNT(bits,i,clips) ( \
+  (i) >(1 << ((bits)-1))- 1? ++(clips),(1 << ((bits)-1))- 1 : \
+  (i) <-1 << ((bits)-1)    ? ++(clips),-1 << ((bits)-1) : (i))
+
+/**
+Client API:
+Clips a value to the limits of a 16-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_16BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(16,i,clips)
+
+/**
+Client API:
+Clips a value to the limits of a 24-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_24BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(24,i,clips)
+
+#define SOX_SIZE_MAX ((size_t)(-1)) /**< Client API: Maximum value of size_t. */
+
+#define SOX_UNSPEC 0                         /**< Client API: Members of sox_signalinfo_t are set to SOX_UNSPEC (= 0) if the actual value is not yet known. */
+#define SOX_UNKNOWN_LEN (sox_uint64_t)(-1) /**< Client API: sox_signalinfo_t.length is set to SOX_UNKNOWN_LEN (= -1) within the effects chain if the actual length is not known. Format handlers currently use SOX_UNSPEC instead. */
+#define SOX_IGNORE_LENGTH (sox_uint64_t)(-2) /**< Client API: sox_signalinfo_t.length is set to SOX_IGNORE_LENGTH (= -2) to indicate that a format handler should ignore length information in file headers. */
+
+#define SOX_DEFAULT_CHANNELS  2     /**< Client API: Default channel count is 2 (stereo). */
+#define SOX_DEFAULT_RATE      48000 /**< Client API: Default rate is 48000Hz. */
+#define SOX_DEFAULT_PRECISION 16    /**< Client API: Default precision is 16 bits per sample. */
+#define SOX_DEFAULT_ENCODING  SOX_ENCODING_SIGN2 /**< Client API: Default encoding is SIGN2 (linear 2's complement PCM). */
+
+#define SOX_LOOP_NONE          ((unsigned char)sox_loop_none)          /**< Client API: single-shot = 0 */
+#define SOX_LOOP_8             ((unsigned char)sox_loop_8)             /**< Client API: 8 loops = 32 */
+#define SOX_LOOP_SUSTAIN_DECAY ((unsigned char)sox_loop_sustain_decay) /**< Client API: AIFF style, one sustain & one decay loop = 64 */
+
+#define SOX_MAX_NLOOPS         8 /**< Client API: Maximum number of loops supported by sox_oob_t = 8. */
+
+#define SOX_FILE_NOSTDIO 0x0001 /**< Client API: Does not use stdio routines */
+#define SOX_FILE_DEVICE  0x0002 /**< Client API: File is an audio device */
+#define SOX_FILE_PHONY   0x0004 /**< Client API: Phony file/device (for example /dev/null) */
+#define SOX_FILE_REWIND  0x0008 /**< Client API: File should be rewound to write header */
+#define SOX_FILE_BIT_REV 0x0010 /**< Client API: Is file bit-reversed? */
+#define SOX_FILE_NIB_REV 0x0020 /**< Client API: Is file nibble-reversed? */
+#define SOX_FILE_ENDIAN  0x0040 /**< Client API: Is file format endian? */
+#define SOX_FILE_ENDBIG  0x0080 /**< Client API: For endian file format, is it big endian? */
+#define SOX_FILE_MONO    0x0100 /**< Client API: Do channel restrictions allow mono? */
+#define SOX_FILE_STEREO  0x0200 /**< Client API: Do channel restrictions allow stereo? */
+#define SOX_FILE_QUAD    0x0400 /**< Client API: Do channel restrictions allow quad? */
+
+#define SOX_FILE_CHANS   (SOX_FILE_MONO | SOX_FILE_STEREO | SOX_FILE_QUAD) /**< Client API: No channel restrictions */
+#define SOX_FILE_LIT_END (SOX_FILE_ENDIAN | 0)                             /**< Client API: File is little-endian */
+#define SOX_FILE_BIG_END (SOX_FILE_ENDIAN | SOX_FILE_ENDBIG)               /**< Client API: File is big-endian */
+
+#define SOX_EFF_CHAN     1           /**< Client API: Effect might alter the number of channels */
+#define SOX_EFF_RATE     2           /**< Client API: Effect might alter sample rate */
+#define SOX_EFF_PREC     4           /**< Client API: Effect does its own calculation of output sample precision (otherwise a default value is taken, depending on the presence of SOX_EFF_MODIFY) */
+#define SOX_EFF_LENGTH   8           /**< Client API: Effect might alter audio length (as measured in time units, not necessarily in samples) */
+#define SOX_EFF_MCHAN    16          /**< Client API: Effect handles multiple channels internally */
+#define SOX_EFF_NULL     32          /**< Client API: Effect does nothing (can be optimized out of chain) */
+#define SOX_EFF_DEPRECATED 64        /**< Client API: Effect will soon be removed from SoX */
+#define SOX_EFF_GAIN     128         /**< Client API: Effect does not support gain -r */
+#define SOX_EFF_MODIFY   256         /**< Client API: Effect does not modify sample values (but might remove or duplicate samples or insert zeros) */
+#define SOX_EFF_ALPHA    512         /**< Client API: Effect is experimental/incomplete */
+#define SOX_EFF_INTERNAL 1024        /**< Client API: Effect present in libSoX but not valid for use by SoX command-line tools */
+
+/**
+Client API:
+When used as the "whence" parameter of sox_seek, indicates that the specified
+offset is relative to the beginning of the file.
+*/
+#define SOX_SEEK_SET 0
+
+/*****************************************************************************
+Forward declarations:
+*****************************************************************************/
+
+typedef struct sox_format_t sox_format_t;
+typedef struct sox_effect_t sox_effect_t;
+typedef struct sox_effect_handler_t sox_effect_handler_t;
+typedef struct sox_format_handler_t sox_format_handler_t;
+
+/*****************************************************************************
+Function pointers:
+*****************************************************************************/
+
+/**
+Client API:
+Callback to write a message to an output device (console or log file),
+used by sox_globals_t.output_message_handler.
+*/
+typedef void (LSX_API * sox_output_message_handler_t)(
+    unsigned level,                       /* 1 = FAIL, 2 = WARN, 3 = INFO, 4 = DEBUG, 5 = DEBUG_MORE, 6 = DEBUG_MOST. */
+    LSX_PARAM_IN_Z char const * filename, /* Source code __FILENAME__ from which message originates. */
+    LSX_PARAM_IN_PRINTF char const * fmt, /* Message format string. */
+    LSX_PARAM_IN va_list ap               /* Message format parameters. */
+    );
+
+/**
+Client API:
+Callback to retrieve information about a format handler,
+used by sox_format_tab_t.fn.
+@returns format handler information.
+*/
+typedef sox_format_handler_t const * (LSX_API * sox_format_fn_t)(void);
+
+/**
+Client API:
+Callback to get information about an effect handler,
+used by the table returned from sox_get_effect_fns(void).
+@returns Pointer to information about an effect handler.
+*/
+typedef sox_effect_handler_t const * (LSX_API *sox_effect_fn_t)(void);
+
+/**
+Client API:
+Callback to initialize reader (decoder), used by
+sox_format_handler.startread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to read (decode) a block of samples,
+used by sox_format_handler.read.
+@returns number of samples read, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_read)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Callback to close reader (decoder),
+used by sox_format_handler.stopread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to initialize writer (encoder),
+used by sox_format_handler.startwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to write (encode) a block of samples,
+used by sox_format_handler.write.
+@returns number of samples written, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_write)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer to which samples are written. */
+    size_t len /**< Capacity of buf, measured in samples. */
+    );
+
+/**
+Client API:
+Callback to close writer (decoder),
+used by sox_format_handler.stopwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to reposition reader,
+used by sox_format_handler.seek.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_seek)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset /**< Sample offset to which reader should be positioned. */
+    );
+
+/**
+Client API:
+Callback to parse command-line arguments (called once per effect),
+used by sox_effect_handler.getopts.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_getopts)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char *argv[] /**< Array of command-line arguments. */
+    );
+
+/**
+Client API:
+Callback to initialize effect (called once per flow),
+used by sox_effect_handler.start.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_start)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to process samples,
+used by sox_effect_handler.flow.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_flow)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_IN_COUNT(*isamp) sox_sample_t const * ibuf, /**< Buffer from which to read samples. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t * obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *isamp, /**< On entry, contains capacity of ibuf; on exit, contains number of samples consumed. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to finish getting output after input is complete,
+used by sox_effect_handler.drain.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_drain)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t *obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per flow),
+used by sox_effect_handler.stop.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_stop)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per effect),
+used by sox_effect_handler.kill.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_kill)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback called while flow is running (called once per buffer),
+used by sox_flow_effects.callback.
+@returns SOX_SUCCESS to continue, other value to abort flow.
+*/
+typedef int (LSX_API * sox_flow_effects_callback)(
+    sox_bool all_done,
+    void * client_data
+    );
+
+/**
+Client API:
+Callback for enumerating the contents of a playlist,
+used by the sox_parse_playlist function.
+@returns SOX_SUCCESS if successful, any other value to abort playlist enumeration.
+*/
+typedef int (LSX_API * sox_playlist_callback_t)(
+    void * callback_data,
+    LSX_PARAM_IN_Z char const * filename
+    );
+
+/*****************************************************************************
+Structures:
+*****************************************************************************/
+
+/**
+Client API:
+Information about a build of libSoX, returned from the sox_version_info
+function.
+*/
+typedef struct sox_version_info_t {
+    size_t       size;         /**< structure size = sizeof(sox_version_info_t) */
+    sox_version_flags_t flags; /**< feature flags = popen | magic | threads | memopen */
+    sox_uint32_t version_code; /**< version number = 0x140400 */
+    char const * version;      /**< version string = sox_version(), for example, "14.4.0" */
+    char const * version_extra;/**< version extra info or null = "PACKAGE_EXTRA", for example, "beta" */
+    char const * time;         /**< build time = "__DATE__ __TIME__", for example, "Jan  7 2010 03:31:50" */
+    char const * distro;       /**< distro or null = "DISTRO", for example, "Debian" */
+    char const * compiler;     /**< compiler info or null, for example, "msvc 160040219" */
+    char const * arch;         /**< arch, for example, "1248 48 44 L OMP" */
+    /* new info should be added at the end for version backwards-compatibility. */
+} sox_version_info_t;
+
+/**
+Client API:
+Global parameters (for effects & formats), returned from the sox_get_globals
+function.
+*/
+typedef struct sox_globals_t {
+/* public: */
+  unsigned     verbosity; /**< messages are only written if globals.verbosity >= message.level */
+  sox_output_message_handler_t output_message_handler; /**< client-specified message output callback */
+  sox_bool     repeatable; /**< true to use pre-determined timestamps and PRNG seed */
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       bufsiz;
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of input sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       input_bufsiz;
+
+  sox_int32_t  ranqd1; /**< Can be used to re-seed libSoX's PRNG */
+
+  char const * stdin_in_use_by;  /**< Private: tracks the name of the handler currently using stdin */
+  char const * stdout_in_use_by; /**< Private: tracks the name of the handler currently using stdout */
+  char const * subsystem;        /**< Private: tracks the name of the handler currently writing an output message */
+  char       * tmp_path;         /**< Private: client-configured path to use for temporary files */
+  sox_bool     use_magic;        /**< Private: true if client has requested use of 'magic' file-type detection */
+  sox_bool     use_threads;      /**< Private: true if client has requested parallel effects processing */
+} sox_globals_t;
+
+/**
+Client API:
+Signal parameters; members should be set to SOX_UNSPEC (= 0) if unknown.
+*/
+typedef struct sox_signalinfo_t {
+  sox_rate_t       rate;         /**< samples per second, 0 if unknown */
+  unsigned         channels;     /**< number of sound channels, 0 if unknown */
+  unsigned         precision;    /**< bits per sample, 0 if unknown */
+  sox_uint64_t     length;       /**< samples * chans in file, 0 if unknown, -1 if unspecified */
+  double           * mult;       /**< Effects headroom multiplier; may be null */
+} sox_signalinfo_t;
+
+/**
+Client API:
+Basic information about an encoding.
+*/
+typedef struct sox_encodings_info_t {
+  sox_encodings_flags_t flags; /**< lossy once (lossy1), lossy twice (lossy2), or lossless (none). */
+  char const * name;           /**< encoding name. */
+  char const * desc;           /**< encoding description. */
+} sox_encodings_info_t;
+
+/**
+Client API:
+Encoding parameters.
+*/
+typedef struct sox_encodinginfo_t {
+  sox_encoding_t encoding; /**< format of sample numbers */
+  unsigned bits_per_sample;/**< 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */
+  double compression;      /**< compression factor (where applicable) */
+
+  /**
+  Should bytes be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bytes;
+
+  /**
+  Should nibbles be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_nibbles;
+
+  /**
+  Should bits be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bits;
+
+  /**
+  If set to true, the format should reverse its default endianness.
+  */
+  sox_bool opposite_endian;
+} sox_encodinginfo_t;
+
+/**
+Client API:
+Looping parameters (out-of-band data).
+*/
+typedef struct sox_loopinfo_t {
+  sox_uint64_t  start;  /**< first sample */
+  sox_uint64_t  length; /**< length */
+  unsigned      count;  /**< number of repeats, 0=forever */
+  unsigned char type;   /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* for valid values). */
+} sox_loopinfo_t;
+
+/**
+Client API:
+Instrument information.
+*/
+typedef struct sox_instrinfo_t{
+  signed char MIDInote;   /**< for unity pitch playback */
+  signed char MIDIlow;    /**< MIDI pitch-bend low range */
+  signed char MIDIhi;     /**< MIDI pitch-bend high range */
+  unsigned char loopmode; /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* values) */
+  unsigned nloops;  /**< number of active loops (max SOX_MAX_NLOOPS). */
+} sox_instrinfo_t;
+
+/**
+Client API:
+File buffer info.  Holds info so that data can be read in blocks.
+*/
+typedef struct sox_fileinfo_t {
+  char          *buf;                 /**< Pointer to data buffer */
+  size_t        size;                 /**< Size of buffer in bytes */
+  size_t        count;                /**< Count read into buffer */
+  size_t        pos;                  /**< Position in buffer */
+} sox_fileinfo_t;
+
+/**
+Client API:
+Handler structure defined by each format.
+*/
+struct sox_format_handler_t {
+  unsigned     sox_lib_version_code;  /**< Checked on load; must be 1st in struct*/
+  char         const * description;   /**< short description of format */
+  char         const * const * names; /**< null-terminated array of filename extensions that are handled by this format */
+  unsigned int flags;                 /**< File flags (SOX_FILE_* values). */
+  sox_format_handler_startread startread; /**< called to initialize reader (decoder) */
+  sox_format_handler_read read;       /**< called to read (decode) a block of samples */
+  sox_format_handler_stopread stopread; /**< called to close reader (decoder); may be null if no closing necessary */
+  sox_format_handler_startwrite startwrite; /**< called to initialize writer (encoder) */
+  sox_format_handler_write write;     /**< called to write (encode) a block of samples */
+  sox_format_handler_stopwrite stopwrite; /**< called to close writer (decoder); may be null if no closing necessary */
+  sox_format_handler_seek seek;       /**< called to reposition reader; may be null if not supported */
+
+  /**
+  Array of values indicating the encodings and precisions supported for
+  writing (encoding). Precisions specified with default precision first.
+  Encoding, precision, precision, ..., 0, repeat. End with one more 0.
+  Example:
+  unsigned const * formats = {
+    SOX_ENCODING_SIGN2, 16, 24, 0, // Support SIGN2 at 16 and 24 bits, default to 16 bits.
+    SOX_ENCODING_UNSIGNED, 8, 0,   // Support UNSIGNED at 8 bits, default to 8 bits.
+    0 // No more supported encodings.
+  };
+  */
+  unsigned     const * write_formats;
+
+  /**
+  Array of sample rates (samples per second) supported for writing (encoding).
+  NULL if all (or almost all) rates are supported. End with 0.
+  */
+  sox_rate_t   const * write_rates;
+
+  /**
+  SoX will automatically allocate a buffer in which the handler can store data.
+  Specify the size of the buffer needed here. Usually this will be sizeof(your_struct).
+  The buffer will be allocated and zeroed before the call to startread/startwrite.
+  The buffer will be freed after the call to stopread/stopwrite.
+  The buffer will be provided via format.priv in each call to the handler.
+  */
+  size_t       priv_size;
+};
+
+/**
+Client API:
+Comments, instrument info, loop info (out-of-band data).
+*/
+typedef struct sox_oob_t{
+  /* Decoded: */
+  sox_comments_t   comments;              /**< Comment strings in id=value format. */
+  sox_instrinfo_t  instr;                 /**< Instrument specification */
+  sox_loopinfo_t   loops[SOX_MAX_NLOOPS]; /**< Looping specification */
+
+  /* TBD: Non-decoded chunks, etc: */
+} sox_oob_t;
+
+/**
+Client API:
+Data passed to/from the format handler
+*/
+struct sox_format_t {
+  char             * filename;      /**< File name */
+
+  /**
+  Signal specifications for reader (decoder) or writer (encoder):
+  sample rate, number of channels, precision, length, headroom multiplier.
+  Any info specified by the user is here on entry to startread or
+  startwrite. Info will be SOX_UNSPEC if the user provided no info.
+  At exit from startread, should be completely filled in, using
+  either data from the file's headers (if available) or whatever
+  the format is guessing/assuming (if header data is not available).
+  At exit from startwrite, should be completely filled in, using
+  either the data that was specified, or values chosen by the format
+  based on the format's defaults or capabilities.
+  */
+  sox_signalinfo_t signal;
+
+  /**
+  Encoding specifications for reader (decoder) or writer (encoder):
+  encoding (sample format), bits per sample, compression rate, endianness.
+  Should be filled in by startread. Values specified should be used
+  by startwrite when it is configuring the encoding parameters.
+  */
+  sox_encodinginfo_t encoding;
+
+  char             * filetype;      /**< Type of file, as determined by header inspection or libmagic. */
+  sox_oob_t        oob;             /**< comments, instrument info, loop info (out-of-band data) */
+  sox_bool         seekable;        /**< Can seek on this file */
+  char             mode;            /**< Read or write mode ('r' or 'w') */
+  sox_uint64_t     olength;         /**< Samples * chans written to file */
+  sox_uint64_t     clips;           /**< Incremented if clipping occurs */
+  int              sox_errno;       /**< Failure error code */
+  char             sox_errstr[256]; /**< Failure error text */
+  void             * fp;            /**< File stream pointer */
+  lsx_io_type      io_type;         /**< Stores whether this is a file, pipe or URL */
+  sox_uint64_t     tell_off;        /**< Current offset within file */
+  sox_uint64_t     data_start;      /**< Offset at which headers end and sound data begins (set by lsx_check_read_params) */
+  sox_format_handler_t handler;     /**< Format handler for this file */
+  void             * priv;          /**< Format handler's private data area */
+};
+
+/**
+Client API:
+Information about a loaded format handler, including the format name and a
+function pointer that can be invoked to get additional information about the
+format.
+*/
+typedef struct sox_format_tab_t {
+  char *name;         /**< Name of format handler */
+  sox_format_fn_t fn; /**< Function to call to get format handler's information */
+} sox_format_tab_t;
+
+/**
+Client API:
+Global parameters for effects.
+*/
+typedef struct sox_effects_globals_t {
+  sox_plot_t plot;         /**< To help the user choose effect & options */
+  sox_globals_t * global_info; /**< Pointer to associated SoX globals */
+} sox_effects_globals_t;
+
+/**
+Client API:
+Effect handler information.
+*/
+struct sox_effect_handler_t {
+  char const * name;  /**< Effect name */
+  char const * usage; /**< Short explanation of parameters accepted by effect */
+  unsigned int flags; /**< Combination of SOX_EFF_* flags */
+  sox_effect_handler_getopts getopts; /**< Called to parse command-line arguments (called once per effect). */
+  sox_effect_handler_start start;     /**< Called to initialize effect (called once per flow). */
+  sox_effect_handler_flow flow;       /**< Called to process samples. */
+  sox_effect_handler_drain drain;     /**< Called to finish getting output after input is complete. */
+  sox_effect_handler_stop stop;       /**< Called to shut down effect (called once per flow). */
+  sox_effect_handler_kill kill;       /**< Called to shut down effect (called once per effect). */
+  size_t       priv_size;             /**< Size of private data SoX should pre-allocate for effect */
+};
+
+/**
+Client API:
+Effect information.
+*/
+struct sox_effect_t {
+  sox_effects_globals_t    * global_info; /**< global effect parameters */
+  sox_signalinfo_t         in_signal;     /**< Information about the incoming data stream */
+  sox_signalinfo_t         out_signal;    /**< Information about the outgoing data stream */
+  sox_encodinginfo_t       const * in_encoding;  /**< Information about the incoming data encoding */
+  sox_encodinginfo_t       const * out_encoding; /**< Information about the outgoing data encoding */
+  sox_effect_handler_t     handler;   /**< The handler for this effect */
+  sox_sample_t             * obuf;    /**< output buffer */
+  size_t                   obeg;      /**< output buffer: start of valid data section */
+  size_t                   oend;      /**< output buffer: one past valid data section (oend-obeg is length of current content) */
+  size_t               imin;          /**< minimum input buffer content required for calling this effect's flow function; set via lsx_effect_set_imin() */
+  sox_uint64_t         clips;         /**< increment if clipping occurs */
+  size_t               flows;         /**< 1 if MCHAN, number of chans otherwise */
+  size_t               flow;          /**< flow number */
+  void                 * priv;        /**< Effect's private data area (each flow has a separate copy) */
+};
+
+/**
+Client API:
+Chain of effects to be applied to a stream.
+*/
+typedef struct sox_effects_chain_t {
+  sox_effect_t **effects;                  /**< Table of effects to be applied to a stream */
+  unsigned table_size;                     /**< Number of entries in effects table */
+  unsigned length;                         /**< Number of effects to be applied */
+  sox_sample_t **ibufc;                    /**< Channel interleave buffer */
+  sox_sample_t **obufc;                    /**< Channel interleave buffer */
+  sox_effects_globals_t global_info;       /**< Copy of global effects settings */
+  sox_encodinginfo_t const * in_enc;       /**< Input encoding */
+  sox_encodinginfo_t const * out_enc;      /**< Output encoding */
+} sox_effects_chain_t;
+
+/*****************************************************************************
+Functions:
+*****************************************************************************/
+
+/**
+Client API:
+Returns version number string of libSoX, for example, "14.4.0".
+@returns The version number string of libSoX, for example, "14.4.0".
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_version(void);
+
+/**
+Client API:
+Returns information about this build of libsox.
+@returns Pointer to a version information structure.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_version_info_t const *
+LSX_API
+sox_version_info(void);
+
+/**
+Client API:
+Returns a pointer to the structure with libSoX's global settings.
+@returns a pointer to the structure with libSoX's global settings.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_globals_t *
+LSX_API
+sox_get_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns the structure with libSoX's global settings
+as an lvalue.
+*/
+#define sox_globals (*sox_get_globals())
+
+/**
+Client API:
+Returns a pointer to the list of available encodings.
+End of list indicated by name == NULL.
+@returns pointer to the list of available encodings.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_encodings_info_t const *
+LSX_API
+sox_get_encodings_info(void);
+
+/**
+Client API:
+Deprecated macro that returns the list of available encodings.
+End of list indicated by name == NULL.
+*/
+#define sox_encodings_info (sox_get_encodings_info())
+
+/**
+Client API:
+Fills in an encodinginfo with default values.
+*/
+void
+LSX_API
+sox_init_encodinginfo(
+    LSX_PARAM_OUT sox_encodinginfo_t * e /**< Pointer to uninitialized encoding info structure to be initialized. */
+    );
+
+/**
+Client API:
+Given an encoding (for example, SIGN2) and the encoded bits_per_sample (for
+example, 16), returns the number of useful bits per sample in the decoded data
+(for example, 16), or returns 0 to indicate that the value returned by the
+format handler should be used instead of a pre-determined precision.
+@returns the number of useful bits per sample in the decoded data (for example
+16), or returns 0 to indicate that the value returned by the format handler
+should be used instead of a pre-determined precision.
+*/
+LSX_RETURN_PURE
+unsigned
+LSX_API
+sox_precision(
+    sox_encoding_t encoding,   /**< Encoding for which to lookup precision information. */
+    unsigned bits_per_sample   /**< The number of encoded bits per sample. */
+    );
+
+/**
+Client API:
+Returns the number of items in the metadata block.
+@returns the number of items in the metadata block.
+*/
+size_t
+LSX_API
+sox_num_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+Adds an "id=value" item to the metadata block.
+*/
+void
+LSX_API
+sox_append_comment(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * item /**< Item to be added in "id=value" format. */
+    );
+
+/**
+Client API:
+Adds a newline-delimited list of "id=value" items to the metadata block.
+*/
+void
+LSX_API
+sox_append_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * items /**< Newline-separated list of items to be added, for example "id1=value1\\nid2=value2". */
+    );
+
+/**
+Client API:
+Duplicates the metadata block.
+@returns the copied metadata block.
+*/
+LSX_RETURN_OPT
+sox_comments_t
+LSX_API
+sox_copy_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block to copy. */
+    );
+
+/**
+Client API:
+Frees the metadata block.
+*/
+void
+LSX_API
+sox_delete_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NULL sox_comments_t * comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+If "id=value" is found, return value, else return null.
+@returns value, or null if value not found.
+*/
+LSX_RETURN_OPT
+char const *
+LSX_API
+sox_find_comment(
+    LSX_PARAM_IN_OPT sox_comments_t comments, /**< Metadata block in which to search. */
+    LSX_PARAM_IN_Z char const * id /**< Id for which to search */
+    );
+
+/**
+Client API:
+Find and load format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_format_init(void);
+
+/**
+Client API:
+Unload format handler plugins.
+*/
+void
+LSX_API
+sox_format_quit(void);
+
+/**
+Client API:
+Initialize effects library.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_init(void);
+
+/**
+Client API:
+Close effects library and unload format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_quit(void);
+
+/**
+Client API:
+Returns the table of format handler names and functions.
+@returns the table of format handler names and functions.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_format_tab_t const *
+LSX_API
+sox_get_format_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns the table of format handler names and functions.
+*/
+#define sox_format_fns (sox_get_format_fns())
+
+/**
+Client API:
+Opens a decoding session for a file. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_read(
+    LSX_PARAM_IN_Z   char               const * path,      /**< Path to file to be opened (required). */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,    /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,  /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype   /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Opens a decoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_read(
+    LSX_PARAM_IN_BYTECOUNT(buffer_size) void  * buffer,     /**< Pointer to audio data buffer (required). */
+    size_t                                      buffer_size,/**< Number of bytes to read from audio data buffer. */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,     /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,   /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype    /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Returns true if the format handler for the specified file type supports the specified encoding.
+@returns true if the format handler for the specified file type supports the specified encoding.
+*/
+sox_bool
+LSX_API
+sox_format_supports_encoding(
+    LSX_PARAM_IN_OPT_Z char               const * path,       /**< Path to file to be examined (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,   /**< Previously-determined file type, or NULL to use extension from path. */
+    LSX_PARAM_IN       sox_encodinginfo_t const * encoding    /**< Encoding for which format handler should be queried. */
+    );
+
+/**
+Client API:
+Gets the format handler for a specified file type.
+@returns The found format handler, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_write_handler(
+    LSX_PARAM_IN_OPT_Z char               const * path,         /**< Path to file (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,     /**< Filetype for which handler is needed, or NULL to use extension from path. */
+    LSX_PARAM_OUT_OPT  char               const * * filetype1   /**< Receives the filetype that was detected. Pass NULL if not needed. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a file. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_write(
+    LSX_PARAM_IN_Z     char               const * path,     /**< Path to file to be written (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,   /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding, /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype, /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob,      /**< Out-of-band data to add to file, or NULL if none. */
+    LSX_PARAM_IN_OPT   sox_bool           (LSX_API * overwrite_permitted)(LSX_PARAM_IN_Z char const * filename) /**< Called if file exists to determine whether overwrite is ok. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_write(
+    LSX_PARAM_OUT_BYTECAP(buffer_size) void                     * buffer,      /**< Pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_IN                       size_t                     buffer_size, /**< Maximum number of bytes to write to audio data buffer. */
+    LSX_PARAM_IN                       sox_signalinfo_t   const * signal,      /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT                   sox_encodinginfo_t const * encoding,    /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z                 char               const * filetype,    /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT                   sox_oob_t          const * oob          /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memstream buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_memstream_write(
+    LSX_PARAM_OUT      char                     * * buffer_ptr,    /**< Receives pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_OUT      size_t                   * buffer_size_ptr, /**< Receives size of data written to audio data buffer (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,          /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding,        /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,        /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob              /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Reads samples from a decoding session into a sample buffer.
+@returns Number of samples decoded, or 0 for EOF.
+*/
+size_t
+LSX_API
+sox_read(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Writes samples to an encoding session from a sample buffer.
+@returns Number of samples encoded.
+*/
+size_t
+LSX_API
+sox_write(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Closes an encoding or decoding session.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_close(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Sets the location at which next samples will be decoded. Returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_seek(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset, /**< Sample offset at which to position reader. */
+    int whence /**< Set to SOX_SEEK_SET. */
+    );
+
+/**
+Client API:
+Finds a format handler by name.
+@returns Format handler data, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_find_format(
+    LSX_PARAM_IN_Z char const * name, /**< Name of format handler to find. */
+    sox_bool ignore_devices /**< Set to true to ignore device names. */
+    );
+
+/**
+Client API:
+Returns global parameters for effects
+@returns global parameters for effects.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_effects_globals_t *
+LSX_API
+sox_get_effects_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns global parameters for effects.
+*/
+#define sox_effects_globals (*sox_get_effects_globals())
+
+/**
+Client API:
+Finds the effect handler with the given name.
+@returns Effect pointer, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+sox_effect_handler_t const *
+LSX_API
+sox_find_effect(
+    LSX_PARAM_IN_Z char const * name /**< Name of effect to find. */
+    );
+
+/**
+Client API:
+Creates an effect using the given handler.
+@returns The new effect, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_create_effect(
+    LSX_PARAM_IN sox_effect_handler_t const * eh /**< Handler to use for effect. */
+    );
+
+/**
+Client API:
+Applies the command-line options to the effect.
+@returns the number of arguments consumed.
+*/
+int
+LSX_API
+sox_effect_options(
+    LSX_PARAM_IN sox_effect_t *effp, /**< Effect pointer on which to set options. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char * const argv[] /**< Array of command-line options. */
+    );
+
+/**
+Client API:
+Returns an array containing the known effect handlers.
+@returns An array containing the known effect handlers.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+sox_effect_fn_t const *
+LSX_API
+sox_get_effect_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns an array containing the known effect handlers.
+*/
+#define sox_effect_fns (sox_get_effect_fns())
+
+/**
+Client API:
+Initializes an effects chain. Returned handle must be closed with sox_delete_effects_chain().
+@returns Handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_effects_chain_t *
+LSX_API
+sox_create_effects_chain(
+    LSX_PARAM_IN sox_encodinginfo_t const * in_enc, /**< Input encoding. */
+    LSX_PARAM_IN sox_encodinginfo_t const * out_enc /**< Output encoding. */
+    );
+
+/**
+Client API:
+Closes an effects chain.
+*/
+void
+LSX_API
+sox_delete_effects_chain(
+    LSX_PARAM_INOUT sox_effects_chain_t *ecp /**< Effects chain pointer. */
+    );
+
+/**
+Client API:
+Adds an effect to the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_add_effect(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added . */
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect to be added. */
+    LSX_PARAM_INOUT sox_signalinfo_t * in, /**< Input format. */
+    LSX_PARAM_IN    sox_signalinfo_t const * out /**< Output format. */
+    );
+
+/**
+Client API:
+Runs the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_flow_effects(
+    LSX_PARAM_INOUT  sox_effects_chain_t * chain, /**< Effects chain to run. */
+    LSX_PARAM_IN_OPT sox_flow_effects_callback callback, /**< Callback for monitoring flow progress. */
+    LSX_PARAM_IN_OPT void * client_data /**< Data to pass into callback. */
+    );
+
+/**
+Client API:
+Gets the number of clips that occurred while running an effects chain.
+@returns the number of clips that occurred while running an effects chain.
+*/
+sox_uint64_t
+LSX_API
+sox_effects_clips(
+    LSX_PARAM_IN sox_effects_chain_t * chain /**< Effects chain from which to read clip information. */
+    );
+
+/**
+Client API:
+Shuts down an effect (calls stop on each of its flows).
+@returns the number of clips from all flows.
+*/
+sox_uint64_t
+LSX_API
+sox_stop_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t * effp /**< Effect to stop. */
+    );
+
+/**
+Client API:
+Adds an already-initialized effect to the end of the chain.
+*/
+void
+LSX_API
+sox_push_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added. */
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect to be added. */
+    );
+
+/**
+Client API:
+Removes and returns an effect from the end of the chain.
+@returns the removed effect, or null if no effects.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_pop_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove an effect. */
+    );
+
+/**
+Client API:
+Shut down and delete an effect.
+*/
+void
+LSX_API
+sox_delete_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t *effp /**< Effect to be deleted. */
+    );
+
+/**
+Client API:
+Shut down and delete the last effect in the chain.
+*/
+void
+LSX_API
+sox_delete_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove the last effect. */
+    );
+
+/**
+Client API:
+Shut down and delete all effects in the chain.
+*/
+void
+LSX_API
+sox_delete_effects(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to delete effects. */
+    );
+
+/**
+Client API:
+Gets the sample offset of the start of the trim, useful for efficiently
+skipping the part that will be trimmed anyway (get trim start, seek, then
+clear trim start).
+@returns the sample offset of the start of the trim.
+*/
+sox_uint64_t
+LSX_API
+sox_trim_get_start(
+    LSX_PARAM_IN sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Clears the start of the trim to 0.
+*/
+void
+LSX_API
+sox_trim_clear_start(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Returns true if the specified file is a known playlist file type.
+@returns true if the specified file is a known playlist file type.
+*/
+sox_bool
+LSX_API
+sox_is_playlist(
+    LSX_PARAM_IN_Z char const * filename /**< Name of file to examine. */
+    );
+
+/**
+Client API:
+Parses the specified playlist file.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_parse_playlist(
+    LSX_PARAM_IN sox_playlist_callback_t callback, /**< Callback to call for each item in the playlist. */
+    void * p, /**< Data to pass to callback. */
+    LSX_PARAM_IN char const * const listname /**< Filename of playlist file. */
+    );
+
+/**
+Client API:
+Converts a SoX error code into an error string.
+@returns error string corresponding to the specified error code,
+or a generic message if the error code is not recognized.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_strerror(
+    int sox_errno /**< Error code to look up. */
+    );
+
+/**
+Client API:
+Gets the basename of the specified file; for example, the basename of
+"/a/b/c.d" would be "c".
+@returns the number of characters written to base_buffer, excluding the null,
+or 0 on failure.
+*/
+size_t
+LSX_API
+sox_basename(
+    LSX_PARAM_OUT_Z_CAP_POST_COUNT(base_buffer_len,return) char * base_buffer, /**< Buffer into which basename should be written. */
+    size_t base_buffer_len, /**< Size of base_buffer, in bytes. */
+    LSX_PARAM_IN_Z char const * filename /**< Filename from which to extract basename. */
+    );
+
+/*****************************************************************************
+Internal API:
+WARNING - The items in this section are subject to instability. They only
+exist in the public header because sox (the application) currently uses them.
+These may be changed or removed in future versions of libSoX.
+*****************************************************************************/
+
+/**
+Plugins API:
+Print a fatal error in libSoX.
+*/
+void
+LSX_API
+lsx_fail_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a warning in libSoX.
+*/
+void
+LSX_API
+lsx_warn_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print an informational message in libSoX.
+*/
+void
+LSX_API
+lsx_report_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a debug message in libSoX.
+*/
+void
+LSX_API
+lsx_debug_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Report a fatal error in libSoX; printf-style arguments must follow.
+*/
+#define lsx_fail       sox_get_globals()->subsystem=__FILE__,lsx_fail_impl
+
+/**
+Plugins API:
+Report a warning in libSoX; printf-style arguments must follow.
+*/
+#define lsx_warn       sox_get_globals()->subsystem=__FILE__,lsx_warn_impl
+
+/**
+Plugins API:
+Report an informational message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_report     sox_get_globals()->subsystem=__FILE__,lsx_report_impl
+
+/**
+Plugins API:
+Report a debug message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_debug      sox_get_globals()->subsystem=__FILE__,lsx_debug_impl
+
+/**
+Plugins API:
+String name and integer values for enumerated types (type metadata), for use
+with LSX_ENUM_ITEM, lsx_find_enum_text, and lsx_find_enum_value.
+*/
+typedef struct lsx_enum_item {
+    char const *text; /**< String name of enumeration. */
+    unsigned value;   /**< Integer value of enumeration. */
+} lsx_enum_item;
+
+/**
+Plugins API:
+Declares a static instance of an lsx_enum_item structure in format
+{ "item", prefixitem }, for use in declaring lsx_enum_item[] arrays.
+@param prefix The prefix to prepend to the item in the enumeration symbolic name.
+@param item   The user-visible text name of the item (must also be a valid C symbol name).
+*/
+#define LSX_ENUM_ITEM(prefix, item) {#item, prefix##item},
+
+/**
+Plugins API:
+Flags for use with lsx_find_enum_item.
+*/
+enum
+{
+    lsx_find_enum_item_none = 0, /**< Default parameters (case-insensitive). */
+    lsx_find_enum_item_case_sensitive = 1 /**< Enable case-sensitive search. */
+};
+
+/**
+Plugins API:
+Looks up an enumeration by name in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_text(
+    LSX_PARAM_IN_Z char const * text, /**< Name of enumeration to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items, /**< Array of items to search, with text == NULL for last item. */
+    int flags /**< Search flags: 0 (case-insensitive) or lsx_find_enum_item_case_sensitive (case-sensitive). */
+    );
+
+/**
+Plugins API:
+Looks up an enumeration by value in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_value(
+    unsigned value, /**< Enumeration value to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Looks up a command-line argument in a set of enumeration names, showing an
+error message if the argument is not found in the set of names.
+@returns The enumeration value corresponding to the matching enumeration, or
+INT_MAX if the argument does not match any enumeration name.
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_enum_option(
+    int c, /**< Option character to which arg is associated, for example with -a, c would be 'a'. */
+    LSX_PARAM_IN_Z char const * arg, /**< Argument to find in enumeration list. */
+    LSX_PARAM_IN lsx_enum_item const * items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Determines whether the specified string ends with the specified suffix (case-sensitive).
+@returns true if the specified string ends with the specified suffix.
+*/
+LSX_RETURN_PURE
+sox_bool
+LSX_API
+lsx_strends(
+    LSX_PARAM_IN_Z char const * str, /**< String to search. */
+    LSX_PARAM_IN_Z char const * end  /**< Suffix to search for. */
+    );
+
+/**
+Plugins API:
+Finds the file extension for a filename.
+@returns the file extension, not including the '.', or null if filename does
+not have an extension.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+lsx_find_file_extension(
+    LSX_PARAM_IN_Z char const * pathname /**< Filename to search for extension. */
+    );
+
+/**
+Plugins API:
+Formats the specified number with up to three significant figures and adds a
+metric suffix in place of the exponent, such as 1.23G.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3(
+    double number /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Formats the specified number as a percentage, showing up to three significant
+figures.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3p(
+    double percentage /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Allocates, deallocates, or resizes; like C's realloc, except that this version
+terminates the running application if unable to allocate the requested memory.
+@returns New buffer, or null if buffer was freed.
+*/
+LSX_RETURN_OPT
+void *
+LSX_API
+lsx_realloc(
+    LSX_PARAM_IN_OPT void *ptr, /**< Pointer to be freed or resized, or null if allocating a new buffer. */
+    size_t newsize /**< New size for buffer, or 0 to free the buffer. */
+    );
+
+/**
+Plugins API:
+Like strcmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strcasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2  /**< Second string. */
+    );
+
+
+/**
+Plugins API:
+Like strncmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strncasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2, /**< Second string. */
+    size_t n /**< Maximum number of characters to examine. */
+    );
+
+/**
+Plugins API:
+Is option argument unsupported, required, or optional.
+*/
+typedef enum lsx_option_arg_t {
+    lsx_option_arg_none, /**< Option does not have an argument. */
+    lsx_option_arg_required, /**< Option requires an argument. */
+    lsx_option_arg_optional /**< Option can optionally be followed by an argument. */
+} lsx_option_arg_t;
+
+/**
+Plugins API:
+lsx_getopt_init options.
+*/
+typedef enum lsx_getopt_flags_t {
+    lsx_getopt_flag_none = 0,      /**< no flags (no output, not long-only) */
+    lsx_getopt_flag_opterr = 1,    /**< if set, invalid options trigger lsx_warn output */
+    lsx_getopt_flag_longonly = 2   /**< if set, recognize -option as a long option */
+} lsx_getopt_flags_t;
+
+/**
+Plugins API:
+lsx_getopt long option descriptor.
+*/
+typedef struct lsx_option_t {
+    char const *     name;    /**< Name of the long option. */
+    lsx_option_arg_t has_arg; /**< Whether the long option supports an argument and, if so, whether the argument is required or optional. */
+    int *            flag;    /**< Flag to set if argument is present. */
+    int              val;     /**< Value to put in flag if argument is present. */
+} lsx_option_t;
+
+/**
+Plugins API:
+lsx_getopt session information (initialization data and state).
+*/
+typedef struct lsx_getopt_t {
+    int                  argc;     /**< IN    argc:      Number of arguments in argv */
+    char * const *       argv;     /**< IN    argv:      Array of arguments */
+    char const *         shortopts;/**< IN    shortopts: Short option characters */
+    lsx_option_t const * longopts; /**< IN    longopts:  Array of long option descriptors */
+    lsx_getopt_flags_t   flags;    /**< IN    flags:     Flags for longonly and opterr */
+    char const *         curpos;   /**< INOUT curpos:    Maintains state between calls to lsx_getopt */
+    int                  ind;      /**< INOUT optind:    Maintains the index of next element to be processed */
+    int                  opt;      /**< OUT   optopt:    Receives the option character that caused error */
+    char const *         arg;      /**< OUT   optarg:    Receives the value of the option's argument */
+    int                  lngind;   /**< OUT   lngind:    Receives the index of the matched long option or -1 if not a long option */
+} lsx_getopt_t;
+
+/**
+Plugins API:
+Initializes an lsx_getopt_t structure for use with lsx_getopt.
+*/
+void
+LSX_API
+lsx_getopt_init(
+    LSX_PARAM_IN             int argc,                      /**< Number of arguments in argv */
+    LSX_PARAM_IN_COUNT(argc) char * const * argv,           /**< Array of arguments */
+    LSX_PARAM_IN_Z           char const * shortopts,        /**< Short options, for example ":abc:def::ghi" (+/- not supported) */
+    LSX_PARAM_IN_OPT         lsx_option_t const * longopts, /**< Array of long option descriptors */
+    LSX_PARAM_IN             lsx_getopt_flags_t flags,      /**< Flags for longonly and opterr */
+    LSX_PARAM_IN             int first,                     /**< First argv to check (usually 1) */
+    LSX_PARAM_OUT            lsx_getopt_t * state           /**< State object to be initialized */
+    );
+
+/**
+Plugins API:
+Gets the next option. Options are parameters that start with "-" or "--".
+If no more options, returns -1. If unrecognized short option, returns '?'.
+If a recognized short option is missing a required argument,
+return (shortopts[0]==':' ? ':' : '?'). If successfully recognized short
+option, return the recognized character. If successfully recognized long
+option, returns (option.flag ? 0 : option.val).
+Note: lsx_getopt does not permute the non-option arguments.
+@returns option character (short), val or 0 (long), or -1 (no more).
+*/
+int
+LSX_API
+lsx_getopt(
+    LSX_PARAM_INOUT lsx_getopt_t * state /**< The getopt state pointer. */
+    );
+
+/* WARNING END */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* SOX_H */
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/sox_i.h b/freedv/branches/1.2/freedv-dev/src/sox/sox_i.h
new file mode 100644 (file)
index 0000000..9d53326
--- /dev/null
@@ -0,0 +1,417 @@
+/* libSoX Internal header
+ *
+ *   This file is meant for libSoX internal use only
+ *
+ * Copyright 2001-2008 Chris Bagwell and SoX Contributors
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#ifndef SOX_I_H
+#define SOX_I_H
+
+#include "soxomp.h"  /* Note: soxomp.h includes soxconfig.h */
+#include "sox.h"
+
+#define __FREEDV__
+
+#if defined HAVE_FMEMOPEN
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#if defined(LSX_EFF_ALIAS)
+#undef lsx_debug
+#undef lsx_fail
+#undef lsx_report
+#undef lsx_warn
+#define lsx_debug sox_globals.subsystem=effp->handler.name,lsx_debug_impl
+#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail_impl
+#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report_impl
+#define lsx_warn sox_globals.subsystem=effp->handler.name,lsx_warn_impl
+#endif
+
+#define RANQD1 ranqd1(sox_globals.ranqd1)
+#define DRANQD1 dranqd1(sox_globals.ranqd1)
+
+typedef enum {SOX_SHORT, SOX_INT, SOX_FLOAT, SOX_DOUBLE} sox_data_t;
+typedef enum {SOX_WAVE_SINE, SOX_WAVE_TRIANGLE} lsx_wave_t;
+lsx_enum_item const * lsx_get_wave_enum(void);
+
+/* Define fseeko and ftello for platforms lacking them */
+#ifndef HAVE_FSEEKO
+#define fseeko fseek
+#define ftello ftell
+#endif
+
+#ifdef _FILE_OFFSET_BITS
+assert_static(sizeof(off_t) == _FILE_OFFSET_BITS >> 3, OFF_T_BUILD_PROBLEM);
+#endif
+
+FILE * lsx_tmpfile(void);
+
+void lsx_debug_more_impl(char const * fmt, ...) LSX_PRINTF12;
+void lsx_debug_most_impl(char const * fmt, ...) LSX_PRINTF12;
+
+#define lsx_debug_more sox_get_globals()->subsystem=__FILE__,lsx_debug_more_impl
+#define lsx_debug_most sox_get_globals()->subsystem=__FILE__,lsx_debug_most_impl
+
+/* Digitise one cycle of a wave and store it as
+ * a table of samples of a specified data-type.
+ */
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void * table,       /* Really of type indicated by data_type. */
+    size_t table_size,  /* Number of points on the x-axis. */
+    double min,         /* Minimum value on the y-axis. (e.g. -1) */
+    double max,         /* Maximum value on the y-axis. (e.g. +1) */
+    double phase);      /* Phase at 1st point; 0..2pi. (e.g. pi/2 for cosine) */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str, uint64_t *samples, int def);
+int lsx_parse_note(char const * text, char * * end_ptr);
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key);
+#define lsx_parse_frequency(a, b) lsx_parse_frequency_k(a, b, INT_MAX)
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename);
+
+void lsx_prepare_spline3(double const * x, double const * y, int n,
+    double start_1d, double end_1d, double * y_2d);
+double lsx_spline3(double const * x, double const * y, double const * y_2d,
+    int n, double x1);
+
+double lsx_bessel_I_0(double x);
+int lsx_set_dft_length(int num_taps);
+void init_fft_cache(void);
+void clear_fft_cache(void);
+void lsx_safe_rdft(int len, int type, double * d);
+void lsx_safe_cdft(int len, int type, double * d);
+void lsx_power_spectrum(int n, double const * in, double * out);
+void lsx_power_spectrum_f(int n, float const * in, float * out);
+void lsx_apply_hann_f(float h[], const int num_points);
+void lsx_apply_hann(double h[], const int num_points);
+void lsx_apply_hamming(double h[], const int num_points);
+void lsx_apply_bartlett(double h[], const int num_points);
+void lsx_apply_blackman(double h[], const int num_points, double alpha);
+void lsx_apply_blackman_nutall(double h[], const int num_points);
+double lsx_kaiser_beta(double att);
+void lsx_apply_kaiser(double h[], const int num_points, double beta);
+double * lsx_make_lpf(int num_taps, double Fc, double beta, double scale, sox_bool dc_norm);
+int lsx_lpf_num_taps(double att, double tr_bw, int k);
+double * lsx_design_lpf(
+    double Fp,      /* End of pass-band; ~= 0.01dB point */
+    double Fc,      /* Start of stop-band */
+    double Fn,      /* Nyquist freq; e.g. 0.5, 1, PI */
+    sox_bool allow_aliasing,
+    double att,     /* Stop-band attenuation in dB */
+    int * num_taps, /* (Single phase.)  0: value will be estimated */
+    int k);         /* Number of phases; 0 for single-phase */
+void lsx_fir_to_phase(double * * h, int * len,
+    int * post_len, double phase0);
+#define LSX_TO_6dB .5869
+#define LSX_TO_3dB ((2/3.) * (.5 + LSX_TO_6dB))
+#define LSX_MAX_TBW0 36.
+#define LSX_MAX_TBW0A (LSX_MAX_TBW0 / (1 + LSX_TO_3dB))
+#define LSX_MAX_TBW3 floor(LSX_MAX_TBW0 * LSX_TO_3dB)
+#define LSX_MAX_TBW3A floor(LSX_MAX_TBW0A * LSX_TO_3dB)
+void lsx_plot_fir(double * h, int num_points, sox_rate_t rate, sox_plot_t type, char const * title, double y1, double y2);
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#define lsx_swapw(x) bswap_16(x)
+#define lsx_swapdw(x) bswap_32(x)
+#elif defined(_MSC_VER)
+#define lsx_swapw(x) _byteswap_ushort(x)
+#define lsx_swapdw(x) _byteswap_ulong(x)
+#else
+#define lsx_swapw(uw) (((uw >> 8) | (uw << 8)) & 0xffff)
+#define lsx_swapdw(udw) ((udw >> 24) | ((udw >> 8) & 0xff00) | ((udw << 8) & 0xff0000) | (udw << 24))
+#endif
+
+
+
+/*------------------------ Implemented in libsoxio.c -------------------------*/
+
+/* Read and write basic data types from "ft" stream. */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len);
+int lsx_skipbytes(sox_format_t * ft, size_t n);
+int lsx_padbytes(sox_format_t * ft, size_t n);
+size_t lsx_writebuf(sox_format_t * ft, void const *buf, size_t len);
+int lsx_reads(sox_format_t * ft, char *c, size_t len);
+int lsx_writes(sox_format_t * ft, char const * c);
+void lsx_set_signal_defaults(sox_format_t * ft);
+#define lsx_writechars(ft, chars, len) (lsx_writebuf(ft, chars, len) == len? SOX_SUCCESS : SOX_EOF)
+
+size_t lsx_read_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+size_t lsx_read_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
+size_t lsx_read_df_buf(sox_format_t * ft, double *buf, size_t len);
+size_t lsx_read_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_read_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
+size_t lsx_read_f_buf(sox_format_t * ft, float *buf, size_t len);
+size_t lsx_read_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
+
+size_t lsx_write_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+size_t lsx_write_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
+size_t lsx_write_df_buf(sox_format_t * ft, double *buf, size_t len);
+size_t lsx_write_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_write_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
+size_t lsx_write_f_buf(sox_format_t * ft, float *buf, size_t len);
+size_t lsx_write_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
+
+int lsx_read3(sox_format_t * ft, sox_uint24_t * u3);
+int lsx_readb(sox_format_t * ft, uint8_t * ub);
+int lsx_readchars(sox_format_t * ft, char * chars, size_t len);
+int lsx_readdf(sox_format_t * ft, double * d);
+int lsx_readdw(sox_format_t * ft, uint32_t * udw);
+int lsx_readqw(sox_format_t * ft, uint64_t * udw);
+int lsx_readf(sox_format_t * ft, float * f);
+int lsx_readw(sox_format_t * ft, uint16_t * uw);
+
+#if 1 /* FIXME: use defines */
+UNUSED static int lsx_readsb(sox_format_t * ft, int8_t * sb)
+{return lsx_readb(ft, (uint8_t *)sb);}
+UNUSED static int lsx_readsw(sox_format_t * ft, int16_t * sw)
+{return lsx_readw(ft, (uint16_t *)sw);}
+#else
+#define lsx_readsb(ft, sb) lsx_readb(ft, (uint8_t *)sb)
+#define lsx_readsw(ft, sw) lsx_readb(ft, (uint16_t *)sw)
+#endif
+
+int lsx_write3(sox_format_t * ft, unsigned u3);
+int lsx_writeb(sox_format_t * ft, unsigned ub);
+int lsx_writedf(sox_format_t * ft, double d);
+int lsx_writedw(sox_format_t * ft, unsigned udw);
+int lsx_writeqw(sox_format_t * ft, uint64_t uqw);
+int lsx_writef(sox_format_t * ft, double f);
+int lsx_writew(sox_format_t * ft, unsigned uw);
+
+int lsx_writesb(sox_format_t * ft, signed);
+int lsx_writesw(sox_format_t * ft, signed);
+
+int lsx_eof(sox_format_t * ft);
+int lsx_error(sox_format_t * ft);
+int lsx_flush(sox_format_t * ft);
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence);
+int lsx_unreadb(sox_format_t * ft, unsigned ub);
+uint64_t lsx_filelength(sox_format_t * ft);
+off_t lsx_tell(sox_format_t * ft);
+void lsx_clearerr(sox_format_t * ft);
+void lsx_rewind(sox_format_t * ft);
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample);
+
+void lsx_fail_errno(sox_format_t *, int, const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 3, 4)));
+#else
+;
+#endif
+
+typedef struct sox_formats_globals { /* Global parameters (for formats) */
+  sox_globals_t * global_info;
+} sox_formats_globals;
+
+
+
+/*------------------------------ File Handlers -------------------------------*/
+
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length);
+#define LSX_FORMAT_HANDLER(name) \
+sox_format_handler_t const * lsx_##name##_format_fn(void); \
+sox_format_handler_t const * lsx_##name##_format_fn(void)
+#define div_bits(size, bits) ((uint64_t)(size) * 8 / bits)
+
+/* Raw I/O */
+int lsx_rawstartread(sox_format_t * ft);
+size_t lsx_rawread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp);
+int lsx_rawstopread(sox_format_t * ft);
+int lsx_rawstartwrite(sox_format_t * ft);
+size_t lsx_rawwrite(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp);
+int lsx_rawseek(sox_format_t * ft, uint64_t offset);
+int lsx_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_bool default_length, sox_encoding_t encoding, unsigned bits_per_sample);
+#define lsx_rawstartread(ft) lsx_rawstart(ft, sox_false, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
+#define lsx_rawstartwrite lsx_rawstartread
+#define lsx_rawstopread NULL
+#define lsx_rawstopwrite NULL
+
+extern sox_format_handler_t const * lsx_sndfile_format_fn(void);
+
+char * lsx_cat_comments(sox_comments_t comments);
+
+/*--------------------------------- Effects ----------------------------------*/
+
+int lsx_flow_copy(sox_effect_t * effp, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp);
+int lsx_usage(sox_effect_t * effp);
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n);
+#define EFFECT(f) extern sox_effect_handler_t const * lsx_##f##_effect_fn(void);
+#include "effects.h"
+#undef EFFECT
+
+#define NUMERIC_PARAMETER(name, min, max) { \
+  char * end_ptr; \
+  double d; \
+  if (argc == 0) break; \
+  d = strtod(*argv, &end_ptr); \
+  if (end_ptr != *argv) { \
+    if (d < min || d > max || *end_ptr != '\0') {\
+      lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+      return lsx_usage(effp); \
+    } \
+    p->name = d; \
+    --argc, ++argv; \
+  } \
+}
+
+#define TEXTUAL_PARAMETER(name, enum_table) { \
+  lsx_enum_item const * e; \
+  if (argc == 0) break; \
+  e = lsx_find_enum_text(*argv, enum_table, 0); \
+  if (e != NULL) { \
+    p->name = e->value; \
+    --argc, ++argv; \
+  } \
+}
+
+#define GETOPT_NUMERIC(state, ch, name, min, max) case ch:{ \
+  char * end_ptr; \
+  double d = strtod(state.arg, &end_ptr); \
+  if (end_ptr == state.arg || d < min || d > max || *end_ptr != '\0') {\
+    lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+    return lsx_usage(effp); \
+  } \
+  p->name = d; \
+  break; \
+}
+
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin);
+
+int lsx_effects_init(void);
+int lsx_effects_quit(void);
+
+/*--------------------------------- Dynamic Library ----------------------------------*/
+
+#if defined(HAVE_WIN32_LTDL_H)
+    #include "win32-ltdl.h"
+    #define HAVE_LIBLTDL 1
+    typedef lt_dlhandle lsx_dlhandle;
+#elif defined(HAVE_LIBLTDL)
+    #include <ltdl.h>
+    typedef lt_dlhandle lsx_dlhandle;
+#else
+    struct lsx_dlhandle_tag;
+    typedef struct lsx_dlhandle_tag *lsx_dlhandle;
+#endif
+
+typedef void (*lsx_dlptr)(void);
+
+typedef struct lsx_dlfunction_info
+{
+    const char* name;
+    lsx_dlptr static_func;
+    lsx_dlptr stub_func;
+} lsx_dlfunction_info;
+
+int lsx_open_dllibrary(
+    int show_error_on_failure,
+    const char* library_description,
+    const char * const library_names[],
+    const lsx_dlfunction_info func_infos[],
+    lsx_dlptr selected_funcs[],
+    lsx_dlhandle* pdl);
+
+void lsx_close_dllibrary(
+    lsx_dlhandle dl);
+
+#define LSX_DLENTRIES_APPLY__(entries, f, x) entries(f, x)
+
+#define LSX_DLENTRY_TO_PTR__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return (*func_ptr) func_args;
+
+#define LSX_DLENTRIES_TO_FUNCTIONS__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return func_name func_args;
+
+/* LSX_DLENTRIES_TO_PTRS: Given an ENTRIES macro and the name of the dlhandle
+   variable, declares the corresponding function pointer variables and the
+   dlhandle variable. */
+#define LSX_DLENTRIES_TO_PTRS(entries, dlhandle) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRY_TO_PTR__, 0) \
+    lsx_dlhandle dlhandle
+
+/* LSX_DLENTRIES_TO_FUNCTIONS: Given an ENTRIES macro, declares the corresponding
+   functions. */
+#define LSX_DLENTRIES_TO_FUNCTIONS(entries) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRIES_TO_FUNCTIONS__, 0)
+
+#define LSX_DLLIBRARY_OPEN1__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    { #func_name, (lsx_dlptr)(static_func), (lsx_dlptr)(stub_func) },
+
+#define LSX_DLLIBRARY_OPEN2__(ptr_container, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    (ptr_container)->func_ptr = (func_return (*)func_args)lsx_dlfunction_open_library_funcs[lsx_dlfunction_open_library_index++];
+
+/* LSX_DLLIBRARY_OPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a failure message. */
+#define LSX_DLLIBRARY_OPEN(ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    LSX_DLLIBRARY_TRYOPEN(1, ptr_container, dlhandle, entries, library_description, library_names, return_var)
+
+/* LSX_DLLIBRARY_TRYOPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a report or a failure
+   message, depending on whether error_on_failure is non-zero. */
+#define LSX_DLLIBRARY_TRYOPEN(error_on_failure, ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    do { \
+      lsx_dlfunction_info lsx_dlfunction_open_library_infos[] = { \
+        LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN1__, 0) \
+        {NULL,NULL,NULL} }; \
+      int lsx_dlfunction_open_library_index = 0; \
+      lsx_dlptr lsx_dlfunction_open_library_funcs[sizeof(lsx_dlfunction_open_library_infos)/sizeof(lsx_dlfunction_open_library_infos[0])]; \
+      (return_var) = lsx_open_dllibrary((error_on_failure), (library_description), (library_names), lsx_dlfunction_open_library_infos, lsx_dlfunction_open_library_funcs, &(ptr_container)->dlhandle); \
+      LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN2__, ptr_container) \
+    } while(0)
+
+#define LSX_DLLIBRARY_CLOSE(ptr_container, dlhandle) \
+    lsx_close_dllibrary((ptr_container)->dlhandle)
+
+  /* LSX_DLENTRY_STATIC: For use in creating an ENTRIES macro. func is
+     expected to be available at link time. If not present, link will fail. */
+#define LSX_DLENTRY_STATIC(f,x, ret, func, args)  f(x, ret, func, args, func, NULL, func)
+
+  /* LSX_DLENTRY_DYNAMIC: For use in creating an ENTRIES macro. func need
+     not be available at link time (and if present, the link time version will
+     not be used). func will be loaded via dlsym. If this function is not
+     found in the shared library, the shared library will not be used. */
+#define LSX_DLENTRY_DYNAMIC(f,x, ret, func, args) f(x, ret, func, args, NULL, NULL, func)
+
+  /* LSX_DLENTRY_STUB: For use in creating an ENTRIES macro. func need not
+     be available at link time (and if present, the link time version will not
+     be used). If using DL_LAME, the func may be loaded via dlopen/dlsym, but
+     if not found, the shared library will still be used if all of the
+     non-stub functions are found. If the function is not found via dlsym (or
+     if we are not loading any shared libraries), the stub will be used. This
+     assumes that the name of the stub function is the name of the function +
+     "_stub". */
+#define LSX_DLENTRY_STUB(f,x, ret, func, args)    f(x, ret, func, args, NULL, func##_stub, func)
+
+  /* LSX_DLFUNC_IS_STUB: returns true if the named function is a do-nothing
+     stub. Assumes that the name of the stub function is the name of the
+     function + "_stub". */
+#define LSX_DLFUNC_IS_STUB(ptr_container, func) ((ptr_container)->func == func##_stub)
+
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/soxomp.h b/freedv/branches/1.2/freedv-dev/src/sox/soxomp.h
new file mode 100644 (file)
index 0000000..6fce07d
--- /dev/null
@@ -0,0 +1,38 @@
+#include "soxconfig.h"
+
+#ifdef HAVE_OPENMP
+  #include <omp.h>
+#else
+
+typedef int omp_lock_t;
+typedef int omp_nest_lock_t;
+
+#define omp_set_num_threads(int) (void)0
+#define omp_get_num_threads() 1
+#define omp_get_max_threads() 1
+#define omp_get_thread_num() 0
+#define omp_get_num_procs() 1
+#define omp_in_parallel() 1
+
+#define omp_set_dynamic(int) (void)0
+#define omp_get_dynamic() 0
+
+#define omp_set_nested(int) (void)0
+#define omp_get_nested() 0
+
+#define omp_init_lock(omp_lock_t) (void)0
+#define omp_destroy_lock(omp_lock_t) (void)0
+#define omp_set_lock(omp_lock_t) (void)0
+#define omp_unset_lock(omp_lock_t) (void)0
+#define omp_test_lock(omp_lock_t) 0
+
+#define omp_init_nest_lock(omp_nest_lock_t) (void)0
+#define omp_destroy_nest_lock(omp_nest_lock_t) (void)0
+#define omp_set_nest_lock(omp_nest_lock_t) (void)0
+#define omp_unset_nest_lock(omp_nest_lock_t) (void)0
+#define omp_test_nest_lock(omp_nest_lock_t) 0
+
+#define omp_get_wtime() 0
+#define omp_get_wtick() 0
+
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/util.h b/freedv/branches/1.2/freedv-dev/src/sox/util.h
new file mode 100644 (file)
index 0000000..89bbe75
--- /dev/null
@@ -0,0 +1,231 @@
+/* General purpose, i.e. non SoX specific, utility functions and macros.
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "soxconfig.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h> /* For off_t not found in stdio.h */
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h> /* Needs to be included before we redefine off_t. */
+#endif
+
+#include "xmalloc.h"
+
+/*---------------------------- Portability stuff -----------------------------*/
+
+#if defined(HAVE_INTTYPES_H)
+  #include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+  #include <stdint.h>
+#else
+  typedef sox_int8_t   int8_t;
+  typedef sox_uint8_t  uint8_t;
+  typedef sox_int16_t  int16_t;
+  typedef sox_uint16_t uint16_t;
+  typedef sox_int32_t  int32_t;
+  typedef sox_uint32_t uint32_t;
+  typedef sox_int64_t  int64_t;
+  typedef sox_uint64_t uint64_t;
+#endif
+
+/* Define the format specifier to use for int64_t values.
+ * Example: printf("You may have already won $ %" PRId64 " !!!", n64); */
+#ifndef PRId64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %lld. */
+#define PRId64 "I64d"
+#elif LONG_MAX==9223372036854775807
+#define PRId64 "ld"
+#else
+#define PRId64 "lld"
+#endif
+#endif /* PRId64 */
+
+/* Define the format specifier to use for uint64_t values. */
+#ifndef PRIu64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %llu. */
+#define PRIu64 "I64u"
+#elif ULONG_MAX==0xffffffffffffffff
+#define PRIu64 "lu"
+#else
+#define PRIu64 "llu"
+#endif
+#endif /* PRIu64 */
+
+/* Define the format specifier to use for size_t values.
+ * Example: printf("Sizeof(x) = %" PRIuPTR " bytes", sizeof(x)); */
+#ifndef PRIuPTR /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %zu. */
+#define PRIuPTR "Iu"
+#else
+#define PRIuPTR "zu"
+#endif
+#endif /* PRIuPTR */
+
+#ifdef __GNUC__
+#define NORET __attribute__((noreturn))
+#define UNUSED __attribute__ ((unused))
+#else
+#define NORET
+#define UNUSED
+#endif
+
+#ifdef _MSC_VER
+
+#define __STDC__ 1
+#define O_BINARY _O_BINARY
+#define O_CREAT _O_CREAT
+#define O_RDWR _O_RDWR
+#define O_TRUNC _O_TRUNC
+#define S_IFMT _S_IFMT
+#define S_IFREG _S_IFREG
+#define S_IREAD _S_IREAD
+#define S_IWRITE _S_IWRITE
+#define close _close
+#define dup _dup
+#define fdopen _fdopen
+#define fileno _fileno
+
+#ifdef _fstati64
+#define fstat _fstati64
+#else
+#define fstat _fstat
+#endif
+
+#define ftime _ftime
+#define inline __inline
+#define isatty _isatty
+#define kbhit _kbhit
+#define mktemp _mktemp
+#define off_t _off_t
+#define open _open
+#define pclose _pclose
+#define popen _popen
+#define setmode _setmode
+#define snprintf _snprintf
+
+#ifdef _stati64
+#define stat _stati64
+#else
+#define stat _stat
+#endif
+
+#define strdup _strdup
+#define timeb _timeb
+#define unlink _unlink
+
+#if defined(HAVE__FSEEKI64) && !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko _fseeki64
+#define ftello _ftelli64
+#define off_t __int64
+#define HAVE_FSEEKO 1
+#endif
+
+#elif defined(__MINGW32__)
+
+#if !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko fseeko64
+#define fstat _fstati64
+#define ftello ftello64
+#define off_t off64_t
+#define stat _stati64
+#define HAVE_FSEEKO 1
+#endif
+
+#endif
+
+#if defined(DOS) || defined(WIN32) || defined(__NT__) || defined(__DJGPP__) || defined(__OS2__)
+  #define LAST_SLASH(path) max(strrchr(path, '/'), strrchr(path, '\\'))
+  #define IS_ABSOLUTE(path) ((path)[0] == '/' || (path)[0] == '\\' || (path)[1] == ':')
+  #define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+  #define POPEN_MODE "rb"
+#else
+  #define LAST_SLASH(path) strrchr(path, '/')
+  #define IS_ABSOLUTE(path) ((path)[0] == '/')
+  #define SET_BINARY_MODE(file)
+#endif
+
+#ifdef WORDS_BIGENDIAN
+  #define MACHINE_IS_BIGENDIAN 1
+  #define MACHINE_IS_LITTLEENDIAN 0
+#else
+  #define MACHINE_IS_BIGENDIAN 0
+  #define MACHINE_IS_LITTLEENDIAN 1
+#endif
+
+/*--------------------------- Language extensions ----------------------------*/
+
+/* Compile-time ("static") assertion */
+/*   e.g. assert_static(sizeof(int) >= 4, int_type_too_small)    */
+#define assert_static(e,f) enum {assert_static__##f = 1/(e)}
+#define array_length(a) (sizeof(a)/sizeof(a[0]))
+#define field_offset(type, field) ((size_t)&(((type *)0)->field))
+#define unless(x) if (!(x))
+
+/*------------------------------- Maths stuff --------------------------------*/
+
+#include <math.h>
+
+#ifdef min
+#undef min
+#endif
+#define min(a, b) ((a) <= (b) ? (a) : (b))
+
+#ifdef max
+#undef max
+#endif
+#define max(a, b) ((a) >= (b) ? (a) : (b))
+
+#define range_limit(x, lower, upper) (min(max(x, lower), upper))
+
+#ifndef M_PI
+#define M_PI    3.14159265358979323846
+#endif
+#ifndef M_PI_2
+#define M_PI_2  1.57079632679489661923  /* pi/2 */
+#endif
+#ifndef M_LN10
+#define M_LN10  2.30258509299404568402  /* natural log of 10 */
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2  sqrt(2.)
+#endif
+
+#define sqr(a) ((a) * (a))
+#define sign(x) ((x) < 0? -1 : 1)
+
+/* Numerical Recipes in C, p. 284 */
+#define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */
+#define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
+
+#define dB_to_linear(x) exp((x) * M_LN10 * 0.05)
+#define linear_to_dB(x) (log10(x) * 20)
+
+extern int lsx_strcasecmp(const char *s1, const char *st);
+extern int lsx_strncasecmp(char const *s1, char const *s2, size_t n);
+
+#ifndef HAVE_STRCASECMP
+#define strcasecmp(s1, s2) lsx_strcasecmp((s1), (s2))
+#define strncasecmp(s1, s2, n) lsx_strncasecmp((s1), (s2), (n))
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/xmalloc.c b/freedv/branches/1.2/freedv-dev/src/sox/xmalloc.c
new file mode 100644 (file)
index 0000000..9bf1596
--- /dev/null
@@ -0,0 +1,43 @@
+/* SoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <stdlib.h>
+
+/* Resize an allocated memory area; abort if not possible.
+ *
+ * For malloc, `If the size of the space requested is zero, the behavior is
+ * implementation defined: either a null pointer is returned, or the
+ * behavior is as if the size were some nonzero value, except that the
+ * returned pointer shall not be used to access an object'
+ */
+void *lsx_realloc(void *ptr, size_t newsize)
+{
+  if (ptr && newsize == 0) {
+    free(ptr);
+    return NULL;
+  }
+
+  if ((ptr = realloc(ptr, newsize)) == NULL) {
+    lsx_fail("out of memory");
+    exit(2);
+  }
+
+  return ptr;
+}
diff --git a/freedv/branches/1.2/freedv-dev/src/sox/xmalloc.h b/freedv/branches/1.2/freedv-dev/src/sox/xmalloc.h
new file mode 100644 (file)
index 0000000..9ee77f6
--- /dev/null
@@ -0,0 +1,34 @@
+/* libSoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef LSX_MALLOC_H
+#define LSX_MALLOC_H
+
+#include <stddef.h>
+#include <string.h>
+
+#define lsx_malloc(size) lsx_realloc(NULL, (size))
+#define lsx_calloc(n,s) (((n)*(s))? memset(lsx_malloc((n)*(s)),0,(n)*(s)) : NULL)
+#define lsx_Calloc(v,n)  v = lsx_calloc(n,sizeof(*(v)))
+#define lsx_strdup(p) ((p)? strcpy((char *)lsx_malloc(strlen(p) + 1), p) : NULL)
+#define lsx_memdup(p,s) ((p)? memcpy(lsx_malloc(s), p, s) : NULL)
+#define lsx_valloc(v,n)  v = lsx_malloc((n)*sizeof(*(v)))
+#define lsx_revalloc(v,n)  v = lsx_realloc(v, (n)*sizeof(*(v)))
+
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/sox_biquad.c b/freedv/branches/1.2/freedv-dev/src/sox_biquad.c
new file mode 100644 (file)
index 0000000..548f424
--- /dev/null
@@ -0,0 +1,134 @@
+//==========================================================================
+// Name:            sox_biquad.h
+// Purpose:         Interface into Sox Biquad filters 
+// Created:         Dec 1, 2012
+// Authors:         David Rowe
+// 
+// To test:
+/*
+          $ gcc sox_biquad.c sox/effects_i.c sox/effects.c sox/formats_i.c \
+            sox/biquad.c sox/biquads.c sox/xmalloc.c sox/libsox.c \
+            -o sox_biquad -DSOX_BIQUAD_UNITTEST -D__FREEDV__ \
+            -Wall -lm -lsndfile -g
+          $ ./sox_biquad
+*/
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "sox/sox.h"
+
+#include "sox_biquad.h"
+
+
+#define N_MAX 1024
+
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
+                    sox_sample_t *obuf, size_t *isamp, size_t *osamp);
+
+void sox_biquad_start(void)
+{
+    int r = sox_init();
+    assert(r == SOX_SUCCESS);
+}
+
+void sox_biquad_finish(void)
+{
+    sox_quit();
+}
+
+/*
+  Effect must be implemented by biquads.c in sox, arguments are just
+  like sox command line, for example:
+
+  char *argv[10];
+  argv[0] = "highpass"; argv[1]="1000"; argc=1;
+*/
+
+void *sox_biquad_create(int argc, const char *argv[])
+{
+    int ret;
+    sox_effect_t *e;
+    int (*start)(sox_effect_t *); /* function pointer to effect start func */
+    
+    e = sox_create_effect(sox_find_effect(argv[0])); assert(e != NULL);
+    ret = sox_effect_options(e, argc, (char * const*)&argv[1]);
+    assert(ret == SOX_SUCCESS);
+
+    start = e->handler.start;
+    e->in_signal.rate = 8000;     /* locked at FS=8000 Hz */
+    ret = start(e); assert(ret == SOX_SUCCESS);
+    
+    return (void *)e;
+}
+
+void sox_biquad_destroy(void *sbq) {
+    sox_effect_t *e = (sox_effect_t *)sbq;
+    free(e);
+}
+
+void sox_biquad_filter(void *sbq, short out[], short in[], int n)
+{
+    sox_effect_t *e = (sox_effect_t *)sbq;
+    sox_sample_t ibuf[N_MAX];
+    sox_sample_t obuf[N_MAX];
+    size_t isamp, osamp;
+    unsigned int clips;
+    SOX_SAMPLE_LOCALS; 
+    int i;
+
+    assert(n <= N_MAX);
+
+    clips = 0;
+    for(i=0; i<n; i++)
+        ibuf[i] = SOX_SIGNED_16BIT_TO_SAMPLE(in[i], clips);
+    isamp = osamp = (unsigned int)n;
+    lsx_biquad_flow(e, ibuf, obuf, &isamp, &osamp);
+    for(i=0; i<n; i++)
+        out[i] = SOX_SAMPLE_TO_SIGNED_16BIT(obuf[i], clips); 
+}
+
+
+#ifdef SOX_BIQUAD_UNITTEST
+#define N 20
+int main(void) {
+    void *sbq;
+    const char *argv[] = {"highpass", "1000"};
+    short in[N];
+    short out[N];
+    int   i, argc;;
+
+    for(i=0; i<N; i++)
+        in[i] = 0;
+    in[0] = 8000;
+
+    sox_biquad_start();
+    //argv[0] = "highpass"; argv[1]="1000"; 
+    argc=1;
+    sbq = sox_biquad_create(argc, argv);
+
+    sox_biquad_filter(sbq, out, in, N);
+    for(i=0; i<N; i++)
+        printf("%d\n", out[i]);
+   
+    sox_biquad_destroy(sbq);
+    sox_biquad_finish();
+
+    return 0;
+}
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/sox_biquad.h b/freedv/branches/1.2/freedv-dev/src/sox_biquad.h
new file mode 100644 (file)
index 0000000..f38de64
--- /dev/null
@@ -0,0 +1,40 @@
+//==========================================================================
+// Name:            sox_biquad.h
+// Purpose:         Interface into Sox Biquad filters 
+// Created:         Dec 1, 2012
+// Authors:         David Rowe
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __SOX_BIQUAD__
+#define __SOX_BIQUAD__
+
+#ifdef __cplusplus
+extern "C" {
+
+#endif
+
+void sox_biquad_start(void);
+void sox_biquad_finish(void);
+void *sox_biquad_create(int argc, const char *argv[]);
+void sox_biquad_destroy(void *sbq);
+void sox_biquad_filter(void *sbq, short out[], short in[], int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freedv/branches/1.2/freedv-dev/src/topFrame.cpp b/freedv/branches/1.2/freedv-dev/src/topFrame.cpp
new file mode 100644 (file)
index 0000000..a5b574a
--- /dev/null
@@ -0,0 +1,595 @@
+//==========================================================================
+// Name:            topFrame.cpp
+//
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "topFrame.h"
+
+extern int g_playFileToMicInEventId;
+extern int g_recFileFromRadioEventId;
+extern int g_playFileFromRadioEventId;
+
+//=========================================================================
+// Code that lays out the main application window
+//=========================================================================
+TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style)
+{
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+    this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+    this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+    this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+    this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
+    //=====================================================
+    // Menubar Setup
+    m_menubarMain = new wxMenuBar(wxMB_DOCKABLE);
+    file = new wxMenu();
+
+    wxMenuItem* m_menuItemOnTop;
+    m_menuItemOnTop = new wxMenuItem(file, wxID_ANY, wxString(_("On Top")) , _("Always Top Window"), wxITEM_NORMAL);
+    file->Append(m_menuItemOnTop);
+
+    wxMenuItem* m_menuItemExit;
+    m_menuItemExit = new wxMenuItem(file, ID_EXIT, wxString(_("E&xit")) , _("Exit Program"), wxITEM_NORMAL);
+    file->Append(m_menuItemExit);
+
+    m_menubarMain->Append(file, _("&File"));
+
+    tools = new wxMenu();
+    wxMenuItem* m_menuItemAudio;
+    m_menuItemAudio = new wxMenuItem(tools, wxID_ANY, wxString(_("&Audio Config")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemAudio);
+
+    wxMenuItem* m_menuItemRigCtrlCfg;
+    m_menuItemRigCtrlCfg = new wxMenuItem(tools, wxID_ANY, wxString(_("&PTT Config")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemRigCtrlCfg);
+
+    wxMenuItem* m_menuItemOptions;
+    m_menuItemOptions = new wxMenuItem(tools, wxID_ANY, wxString(_("Options")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemOptions);
+
+    wxMenuItem* m_menuItemFilter;
+    m_menuItemFilter = new wxMenuItem(tools, wxID_ANY, wxString(_("&Filter")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemFilter);
+
+    wxMenuItem* m_menuItemPlugIn;
+    if (!wxIsEmpty(plugInName)) {
+        m_menuItemPlugIn = new wxMenuItem(tools, wxID_ANY, plugInName + wxString(_(" Config")) , wxEmptyString, wxITEM_NORMAL);
+        tools->Append(m_menuItemPlugIn);
+    }
+
+    wxMenuItem* m_menuItemPlayFileToMicIn;
+    m_menuItemPlayFileToMicIn = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - Mic In")) , wxEmptyString, wxITEM_NORMAL);
+    g_playFileToMicInEventId = m_menuItemPlayFileToMicIn->GetId();
+    tools->Append(m_menuItemPlayFileToMicIn);
+
+    wxMenuItem* m_menuItemRecFileFromRadio;
+    m_menuItemRecFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Record File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
+    g_recFileFromRadioEventId = m_menuItemRecFileFromRadio->GetId();
+    tools->Append(m_menuItemRecFileFromRadio);
+
+    wxMenuItem* m_menuItemPlayFileFromRadio;
+    m_menuItemPlayFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
+    g_playFileFromRadioEventId = m_menuItemPlayFileFromRadio->GetId();
+    tools->Append(m_menuItemPlayFileFromRadio);
+    m_menubarMain->Append(tools, _("&Tools"));
+
+    help = new wxMenu();
+    wxMenuItem* m_menuItemHelpUpdates;
+    m_menuItemHelpUpdates = new wxMenuItem(help, wxID_ANY, wxString(_("Check for Updates")) , wxEmptyString, wxITEM_NORMAL);
+    help->Append(m_menuItemHelpUpdates);
+    m_menuItemHelpUpdates->Enable(false);
+
+    wxMenuItem* m_menuItemAbout;
+    m_menuItemAbout = new wxMenuItem(help, ID_ABOUT, wxString(_("&About")) , _("About this program"), wxITEM_NORMAL);
+    help->Append(m_menuItemAbout);
+
+    m_menubarMain->Append(help, _("&Help"));
+
+    this->SetMenuBar(m_menubarMain);
+
+    wxBoxSizer* bSizer1;
+    bSizer1 = new wxBoxSizer(wxHORIZONTAL);
+
+    //=====================================================
+    // Left side
+    //=====================================================
+    wxBoxSizer* leftSizer;
+    leftSizer = new wxBoxSizer(wxVERTICAL);
+
+    wxStaticBoxSizer* snrSizer;
+    snrSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("SNR")), wxVERTICAL);
+
+    //------------------------------
+    // S/N ratio Guage (vert. bargraph)
+    //------------------------------
+    m_gaugeSNR = new wxGauge(this, wxID_ANY, 25, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
+    m_gaugeSNR->SetToolTip(_("Displays signal to noise ratio in dB."));
+    snrSizer->Add(m_gaugeSNR, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
+
+    //------------------------------
+    // Box for S/N ratio (Numeric)
+    //------------------------------
+    m_textSNR = new wxStaticText(this, wxID_ANY, wxT(" 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    snrSizer->Add(m_textSNR, 0, wxALIGN_CENTER_HORIZONTAL, 1);
+
+    //------------------------------
+    // S/N ratio slow Checkbox
+    //------------------------------
+    m_ckboxSNR = new wxCheckBox(this, wxID_ANY, _("Slow"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    m_ckboxSNR->SetToolTip(_("Smooth but slow SNR estimation"));
+    snrSizer->Add(m_ckboxSNR, 0, wxALIGN_CENTER_HORIZONTAL, 5);
+
+    leftSizer->Add(snrSizer, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxALL, 1);
+
+    //------------------------------
+    // Sync  Indicator box
+    //------------------------------
+    wxStaticBoxSizer* sbSizer3_33;
+    sbSizer3_33 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Sync")), wxVERTICAL);
+
+    m_rbSync = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) );
+    sbSizer3_33->Add(m_rbSync, 0, wxALIGN_CENTER|wxALL, 1);
+    leftSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // BER Frames box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_ber;
+    sbSizer_ber = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Bit Error Rate")), wxVERTICAL);
+
+    m_BtnBerReset = new wxButton(this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_ber->Add(m_BtnBerReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    m_textBits = new wxStaticText(this, wxID_ANY, wxT("Bits: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textBits, 0, wxALIGN_LEFT, 1);
+    m_textErrors = new wxStaticText(this, wxID_ANY, wxT("Errs: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textErrors, 0, wxALIGN_LEFT, 1);
+    m_textBER = new wxStaticText(this, wxID_ANY, wxT("BER: 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textBER, 0, wxALIGN_LEFT, 1);
+
+    m_textResyncs = new wxStaticText(this, wxID_ANY, wxT("Resyncs: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textResyncs, 0, wxALIGN_LEFT, 1);
+
+    leftSizer->Add(sbSizer_ber,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Signal Level(vert. bargraph)
+    //------------------------------
+    wxStaticBoxSizer* levelSizer;
+    levelSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Level")), wxVERTICAL);
+
+    m_textLevel = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(60,-1), wxALIGN_CENTRE);
+    m_textLevel->SetForegroundColour(wxColour(255,0,0));
+    levelSizer->Add(m_textLevel, 0, wxALIGN_LEFT, 1);
+
+    m_gaugeLevel = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
+    m_gaugeLevel->SetToolTip(_("Peak of From Radio in Rx, or peak of From Mic in Tx mode.  If Red you should reduce your levels"));
+    levelSizer->Add(m_gaugeLevel, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
+
+    leftSizer->Add(levelSizer, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 1);
+
+    bSizer1->Add(leftSizer, 0, wxALL|wxEXPAND, 5);
+
+    //=====================================================
+    // Center Section
+    //=====================================================
+    wxBoxSizer* centerSizer;
+    centerSizer = new wxBoxSizer(wxVERTICAL);
+    wxBoxSizer* upperSizer;
+    upperSizer = new wxBoxSizer(wxVERTICAL);
+
+    //=====================================================
+    // Tabbed Notebook control containing display graphs
+    //=====================================================
+    //m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM|wxAUI_NB_DEFAULT_STYLE);
+    //long style = wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_MIDDLE_CLICK_CLOSE;
+    long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
+    m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, nb_style);
+    // This line sets the fontsize for the tabs on the notebook control
+    m_auiNbookCtrl->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
+
+    upperSizer->Add(m_auiNbookCtrl, 1, wxALIGN_TOP|wxEXPAND, 1);
+    centerSizer->Add(upperSizer, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALIGN_TOP|wxEXPAND, 0);
+
+    // lower middle used for user ID
+
+    wxBoxSizer* lowerSizer;
+    lowerSizer = new wxBoxSizer(wxHORIZONTAL);
+
+    m_BtnCallSignReset = new wxButton(this, wxID_ANY, _("Clear"), wxDefaultPosition, wxDefaultSize, 0);
+    lowerSizer->Add(m_BtnCallSignReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    wxBoxSizer* bSizer15;
+    bSizer15 = new wxBoxSizer(wxVERTICAL);
+    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
+    m_txtCtrlCallSign->SetToolTip(_("Call Sign of transmitting station will appear here"));
+    bSizer15->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
+    lowerSizer->Add(bSizer15, 1, wxEXPAND, 5);
+
+#ifdef __EXPERIMENTAL_UDP__
+    wxStaticBoxSizer* sbSizer_Checksum = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Checksums")), wxHORIZONTAL);
+
+    wxStaticText *goodLabel = new wxStaticText(this, wxID_ANY, wxT("Good: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(goodLabel, 0, 0, 2);
+    m_txtChecksumGood = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(m_txtChecksumGood, 0, 0, 2);
+
+    wxStaticText *badLabel = new wxStaticText(this, wxID_ANY, wxT("Bad: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(badLabel, 0, 0, 1);
+    m_txtChecksumBad = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(m_txtChecksumBad, 0, 0, 1);
+
+    lowerSizer->Add(sbSizer_Checksum, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    //=====================================================
+    // These are the buttons that autosend the userid (?)
+    //=====================================================
+
+    // DR 4 Dec - taken off for screen for Beta release to avoid questions on their use until
+    // we implement this feature
+ #ifdef UNIMPLEMENTED
+    wxBoxSizer* bSizer141;
+    bSizer141 = new wxBoxSizer(wxHORIZONTAL);
+
+    // TxID
+    //---------
+    m_togTxID = new wxToggleButton(this, wxID_ANY, _("TxID"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togTxID->SetToolTip(_("Send Tx ID information"));
+    bSizer141->Add(m_togTxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
+
+    // RxID
+    //---------
+    m_togRxID = new wxToggleButton(this, wxID_ANY, _("RxID"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togRxID->SetToolTip(_("Enable reception of ID information"));
+    bSizer141->Add(m_togRxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_LEFT|wxALL|wxFIXED_MINSIZE, 5);
+
+    lowerSizer->Add(bSizer141, 0, wxALIGN_RIGHT, 5);
+#endif
+
+    centerSizer->Add(lowerSizer, 0, wxALIGN_BOTTOM|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 2);
+    bSizer1->Add(centerSizer, 4, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 1);
+
+    //=====================================================
+    // Right side
+    //=====================================================
+    wxBoxSizer* rightSizer;
+    rightSizer = new wxBoxSizer(wxVERTICAL);
+
+    //=====================================================
+    // Squelch Slider Control
+    //=====================================================
+    wxStaticBoxSizer* sbSizer3;
+    sbSizer3 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Squelch")), wxVERTICAL);
+
+    m_sliderSQ = new wxSlider(this, wxID_ANY, 0, 0, 40, wxDefaultPosition, wxSize(-1,80), wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_VERTICAL);
+    m_sliderSQ->SetToolTip(_("Set Squelch level in dB."));
+
+    sbSizer3->Add(m_sliderSQ, 1, wxALIGN_CENTER_HORIZONTAL, 0);
+
+    //------------------------------
+    // Squelch Level static text box
+    //------------------------------
+    m_textSQ = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+
+    sbSizer3->Add(m_textSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
+
+    //------------------------------
+    // Squelch Toggle Checkbox
+    //------------------------------
+    m_ckboxSQ = new wxCheckBox(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+
+    sbSizer3->Add(m_ckboxSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
+    rightSizer->Add(sbSizer3, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 0);
+
+    //rightSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    /* new --- */
+
+    //------------------------------
+    // Mode box
+    //------------------------------
+    wxStaticBoxSizer* sbSizer_mode;
+    sbSizer_mode = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mode")), wxVERTICAL);
+
+#ifdef DISABLED_FEATURE
+    m_rb1400old = new wxRadioButton( this, wxID_ANY, wxT("1400 V0.91"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb1400old, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1400 = new wxRadioButton( this, wxID_ANY, wxT("1400"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1400, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb700 = new wxRadioButton( this, wxID_ANY, wxT("700"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb700b = new wxRadioButton( this, wxID_ANY, wxT("700B"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700b, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+    m_rb700c = new wxRadioButton( this, wxID_ANY, wxT("700C"), wxDefaultPosition, wxDefaultSize,  wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700c, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb800xa = new wxRadioButton( this, wxID_ANY, wxT("800XA"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb800xa, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1600 = new wxRadioButton( this, wxID_ANY, wxT("1600"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1600, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1600->SetValue(true);
+
+    m_rbPlugIn = NULL;
+    if (!wxIsEmpty(plugInName)) {
+        // Optional plug in
+
+        m_rbPlugIn = new wxRadioButton( this, wxID_ANY, plugInName, wxDefaultPosition, wxDefaultSize, 0);
+        sbSizer_mode->Add(m_rbPlugIn, 0, wxALIGN_LEFT|wxALL, 1);
+    }
+
+#ifdef DISABLED_FEATURE
+    m_rb1600Wide = new wxRadioButton( this, wxID_ANY, wxT("1600 Wide"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1600Wide, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb2000 = new wxRadioButton( this, wxID_ANY, wxT("2000"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb2000, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+
+    rightSizer->Add(sbSizer_mode,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    #ifdef MOVED_TO_OPTIONS_DIALOG
+    /* new --- */
+
+    //------------------------------
+    // Test Frames box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_testFrames;
+    sbSizer_testFrames = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Test Frames")), wxVERTICAL);
+
+    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+
+    rightSizer->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    #endif
+
+    //=====================================================
+    // Control Toggles box
+    //=====================================================
+    wxStaticBoxSizer* sbSizer5;
+    sbSizer5 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Control")), wxVERTICAL);
+    wxBoxSizer* bSizer1511;
+    bSizer1511 = new wxBoxSizer(wxVERTICAL);
+
+    //-------------------------------
+    // Stop/Stop signal processing (rx and tx)
+    //-------------------------------
+    m_togBtnOnOff = new wxToggleButton(this, wxID_ANY, _("Start"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnOnOff->SetToolTip(_("Begin/End receiving data."));
+    bSizer1511->Add(m_togBtnOnOff, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer1511, 0, wxEXPAND, 1);
+
+#ifdef UNIMPLEMENTED
+    //------------------------------
+    // Toggle Loopback button for RX
+    //------------------------------
+    wxBoxSizer* bSizer15113;
+    bSizer15113 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* bSizer15111;
+    bSizer15111 = new wxBoxSizer(wxVERTICAL);
+    wxSize wxSz = wxSize(44, 30);
+    m_togBtnLoopRx = new wxToggleButton(this, wxID_ANY, _("Loop\nRX"), wxDefaultPosition, wxSz, 0);
+    m_togBtnLoopRx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
+    m_togBtnLoopRx->SetToolTip(_("Loopback Receive audio data."));
+
+    bSizer15111->Add(m_togBtnLoopRx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    //sbSizer5->Add(bSizer15111, 0, wxEXPAND, 1);
+    bSizer15113->Add(bSizer15111, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    //------------------------------
+    // Toggle Loopback button for Tx
+    //------------------------------
+    wxBoxSizer* bSizer15112;
+    bSizer15112 = new wxBoxSizer(wxVERTICAL);
+    m_togBtnLoopTx = new wxToggleButton(this, wxID_ANY, _("Loop\nTX"), wxDefaultPosition, wxSz, 0);
+    m_togBtnLoopTx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
+    m_togBtnLoopTx->SetToolTip(_("Loopback Transmit audio data."));
+
+    bSizer15112->Add(m_togBtnLoopTx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+    bSizer15113->Add(bSizer15112, 0,  wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    sbSizer5->Add(bSizer15113, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    //------------------------------
+    // Split Frequency Mode Toggle
+    //------------------------------
+    wxBoxSizer* bSizer151;
+    bSizer151 = new wxBoxSizer(wxVERTICAL);
+
+    m_togBtnSplit = new wxToggleButton(this, wxID_ANY, _("Split"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnSplit->SetToolTip(_("Toggle split frequency mode."));
+
+    bSizer151->Add(m_togBtnSplit, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer151, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 1);
+    wxBoxSizer* bSizer13;
+    bSizer13 = new wxBoxSizer(wxVERTICAL);
+
+    //------------------------------
+    // Analog Passthrough Toggle
+    //------------------------------
+    m_togBtnAnalog = new wxToggleButton(this, wxID_ANY, _("Analog"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnAnalog->SetToolTip(_("Toggle analog/digital operation."));
+    bSizer13->Add(m_togBtnAnalog, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer13, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    //------------------------------
+    // Voice Keyer Toggle
+    //------------------------------
+    m_togBtnVoiceKeyer = new wxToggleButton(this, wxID_ANY, _("Voice Keyer"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnVoiceKeyer->SetToolTip(_("Toggle Voice Keyer"));
+    wxBoxSizer* bSizer13a = new wxBoxSizer(wxVERTICAL);    
+    bSizer13a->Add(m_togBtnVoiceKeyer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer13a, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    // not implemented on fdmdv2
+#ifdef ALC
+    //------------------------------
+    // Toggle for ALC
+    //------------------------------
+    wxBoxSizer* bSizer14;
+    bSizer14 = new wxBoxSizer(wxVERTICAL);
+    m_togBtnALC = new wxToggleButton(this, wxID_ANY, _("ALC"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnALC->SetToolTip(_("Toggle automatic level control mode."));
+
+    bSizer14->Add(m_togBtnALC, 0, wxALL, 1);
+    sbSizer5->Add(bSizer14, 0, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALL, 1);
+#endif
+
+    //------------------------------
+    // PTT button: Toggle Transmit/Receive mode
+    //------------------------------
+    wxBoxSizer* bSizer11;
+    bSizer11 = new wxBoxSizer(wxVERTICAL);
+    m_btnTogPTT = new wxToggleButton(this, wxID_ANY, _("PTT"), wxDefaultPosition, wxDefaultSize, 0);
+    m_btnTogPTT->SetToolTip(_("Push to Talk - Switch between Receive and Transmit - you can also use the space bar "));
+    bSizer11->Add(m_btnTogPTT, 1, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer11, 2, wxEXPAND, 1);
+    rightSizer->Add(sbSizer5, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 3);
+    bSizer1->Add(rightSizer, 0, wxALL|wxEXPAND, 3);
+    this->SetSizer(bSizer1);
+    this->Layout();
+    m_statusBar1 = this->CreateStatusBar(3, wxST_SIZEGRIP, wxID_ANY);
+
+    //=====================================================
+    // End of layout
+    //=====================================================
+
+    //-------------------
+    // Connect Events
+    //-------------------
+    this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
+    this->Connect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
+    this->Connect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
+    this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
+
+    this->Connect(m_menuItemExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
+    this->Connect(m_menuItemOnTop->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnTop));
+
+    this->Connect(m_menuItemAudio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
+    this->Connect(m_menuItemAudio->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
+    this->Connect(m_menuItemFilter->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
+    this->Connect(m_menuItemFilter->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
+    this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
+    this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
+    this->Connect(m_menuItemOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
+    this->Connect(m_menuItemOptions->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
+
+    if (!wxIsEmpty(plugInName)) {
+        this->Connect(m_menuItemPlugIn->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsPlugInCfg));
+        this->Connect(m_menuItemPlugIn->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsPlugInCfgUI));
+    }
+
+    this->Connect(m_menuItemPlayFileToMicIn->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
+    this->Connect(m_menuItemRecFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
+    this->Connect(m_menuItemPlayFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
+
+    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
+    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    this->Connect(m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
+    //m_togRxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
+    //m_togTxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
+    m_ckboxSQ->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
+
+    m_ckboxSNR->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSNRClick), NULL, this);
+
+    m_togBtnOnOff->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
+    m_togBtnSplit->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
+    m_togBtnAnalog->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
+    m_togBtnVoiceKeyer->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnVoiceKeyerClick), NULL, this);
+#ifdef ALC
+    m_togBtnALC->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
+#endif
+    m_btnTogPTT->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
+
+    m_BtnCallSignReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnCallSignReset), NULL, this);
+    m_BtnBerReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnBerReset), NULL, this);
+}
+
+TopFrame::~TopFrame()
+{
+    //-------------------
+    // Disconnect Events
+    //-------------------
+    this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
+    this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
+    this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
+    this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
+    this->Disconnect(ID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsPlugInCfg));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    this->Disconnect(ID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
+    //m_togRxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
+    //m_togTxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
+    m_ckboxSQ->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
+
+    m_togBtnOnOff->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
+    m_togBtnSplit->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
+    m_togBtnAnalog->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
+    m_togBtnVoiceKeyer->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnVoiceKeyerClick), NULL, this);
+#ifdef ALC
+    m_togBtnALC->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
+#endif
+    m_btnTogPTT->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
+
+}
+
diff --git a/freedv/branches/1.2/freedv-dev/src/topFrame.h b/freedv/branches/1.2/freedv-dev/src/topFrame.h
new file mode 100644 (file)
index 0000000..37950a9
--- /dev/null
@@ -0,0 +1,194 @@
+//==========================================================================
+// Name:            topFrame.h
+//
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Lesser General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __TOPFRAME_H__
+#define __TOPFRAME_H__
+
+#include "version.h"
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include <wx/string.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/menu.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/gauge.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/aui/auibook.h>
+#include <wx/tglbtn.h>
+#include <wx/slider.h>
+#include <wx/checkbox.h>
+#include <wx/statusbr.h>
+#include <wx/frame.h>
+#include <wx/statbmp.h>
+#include <wx/stattext.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+#include <wx/radiobut.h>
+#include <wx/combobox.h>
+#include <wx/panel.h>
+#include <wx/listbox.h>
+#include <wx/notebook.h>
+#include <wx/listctrl.h>
+
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_OPEN 1000
+#define ID_SAVE 1001
+#define ID_CLOSE 1002
+#define ID_EXIT 1003
+#define ID_COPY 1004
+#define ID_CUT 1005
+#define ID_PASTE 1006
+#define ID_OPTIONS 1007
+#define ID_ABOUT 1008
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class TopFrame
+///////////////////////////////////////////////////////////////////////////////
+class TopFrame : public wxFrame
+{
+    private:
+
+    protected:
+        wxMenuBar* m_menubarMain;
+        wxMenu* file;
+        wxMenu* edit;
+        wxMenu* tools;
+        wxMenu* help;
+        wxGauge* m_gaugeSNR;
+        wxStaticText* m_textSNR;
+        wxCheckBox* m_ckboxSNR;
+        wxGauge* m_gaugeLevel;
+        wxStaticText* m_textLevel;
+
+        wxButton*     m_BtnCallSignReset;
+        wxTextCtrl*   m_txtCtrlCallSign;
+        wxStaticText* m_txtChecksumGood;
+        wxStaticText* m_txtChecksumBad;
+
+        wxSlider* m_sliderSQ;
+        wxCheckBox* m_ckboxSQ;
+        wxStaticText* m_textSQ;
+        wxStatusBar* m_statusBar1;
+
+        wxButton*     m_BtnBerReset;
+        wxStaticText  *m_textBits;
+        wxStaticText  *m_textErrors;
+        wxStaticText  *m_textBER;
+        wxStaticText  *m_textResyncs;
+
+        wxRadioButton *m_rbSync;
+        wxRadioButton *m_rb1400old;
+        wxRadioButton *m_rb1400;
+        wxRadioButton *m_rb700;
+        wxRadioButton *m_rb700b;
+        wxRadioButton *m_rb700c;
+        wxRadioButton *m_rb800xa;
+        wxRadioButton *m_rb1600;
+        wxRadioButton *m_rb2000;
+        wxRadioButton *m_rb1600Wide;
+        wxRadioButton *m_rbPlugIn;
+
+        // Virtual event handlers, overide them in your derived class
+        virtual void topFrame_OnClose( wxCloseEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnPaint( wxPaintEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnSize( wxSizeEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTop( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsAudio( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsAudioUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsFilter( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsFilterUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsOptions( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnToolsPlugInCfg( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsPlugInCfgUI( wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnToolsUDP( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsOptionsUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsComCfg( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsComCfgUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnPlayFileToMicIn( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnRecFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnPlayFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnHelpCheckUpdates( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnHelpAbout( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnRxID( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnTxID( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnCmdSliderScroll( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnSliderScrollBottom( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnCmdSliderScrollChanged( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnSliderScrollTop( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnCheckSQClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnCheckSNRClick( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnTogBtnLoopRx( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnLoopTx( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnOnOff( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnSplitClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnAnalogClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnVoiceKeyerClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnALCClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnPTT( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnTogBtnSplitClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnAnalogClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnALCClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnRxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnTxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnPTT_UI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnOnOffUI(wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnCallSignReset( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnBerReset( wxCommandEvent& event ) { event.Skip(); }
+
+    public:
+        wxToggleButton* m_togRxID;
+        wxToggleButton* m_togTxID;
+        wxToggleButton* m_togBtnOnOff;
+        wxToggleButton* m_togBtnSplit;
+        wxToggleButton* m_togBtnAnalog;
+        wxToggleButton* m_togBtnVoiceKeyer;
+        wxToggleButton* m_togBtnALC;
+        wxToggleButton* m_btnTogPTT;
+        wxToggleButton* m_togBtnLoopRx;
+        wxToggleButton* m_togBtnLoopTx;
+        wxAuiNotebook* m_auiNbookCtrl;
+
+        TopFrame( wxString plugInName, wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FreeDV ") + _(FREEDV_VERSION), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(561,300 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
+
+        ~TopFrame();
+};
+
+#endif //__TOPFRAME_H__
index 2fa45232f1ea89365eb7a1bd27f3f9ff3aa45e25..ef0798b36007dea1d013f4e1c81042c86c64b62c 100644 (file)
@@ -12,6 +12,7 @@ set(FREEDV_SOURCES
     fdmdv2_plot_spectrum.cpp
     fdmdv2_plot_waterfall.cpp
     hamlib.cpp
+    serialport.cpp
     topFrame.cpp
     sox_biquad.c
     comp.h
index 9189febaad45c40f78e0772f16cd52b7c75b1981..79b6c87f2ca93cd05c03acbfd00b9ce48bd11aed 100644 (file)
@@ -20,7 +20,9 @@
 //==========================================================================
 
 #include "dlg_options.h"
-extern bool g_modal;
+
+extern bool                g_modal;
+extern struct freedv      *g_pfreedv;
 
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
 // Class OptionsDlg
@@ -34,51 +36,131 @@ OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, c
     bSizer30 = new wxBoxSizer(wxVERTICAL);
 
     //------------------------------
-    // Test Frames check box
+    // Txt Msg Text Box
     //------------------------------
 
-    wxStaticBoxSizer* sbSizer_testFrames;
-    wxStaticBox *sb_testFrames = new wxStaticBox(this, wxID_ANY, _("Test Frames"));
-    sbSizer_testFrames = new wxStaticBoxSizer(sb_testFrames, wxHORIZONTAL);
+    wxStaticBoxSizer* sbSizer_callSign;
+    wxStaticBox *sb_textMsg = new wxStaticBox(this, wxID_ANY, _("Txt Msg"));
+    sbSizer_callSign = new wxStaticBoxSizer(sb_textMsg, wxVERTICAL);
 
-    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
-    m_ckboxTestFrame->SetToolTip(_("Send frames of known bits instead of compressed voice"));
-    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    m_txtCtrlCallSign->SetToolTip(_("Txt Msg you can send along with Voice"));
+    sbSizer_callSign->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 3);
 
-    m_ckboxChannelNoise = new wxCheckBox(this, wxID_ANY, _("Channel Noise"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
-    m_ckboxChannelNoise->SetToolTip(_("Add simulated AWGN channel noise to received signal"));
-    sbSizer_testFrames->Add(m_ckboxChannelNoise, 0, wxALIGN_LEFT, 0);
+    bSizer30->Add(sbSizer_callSign,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    //----------------------------------------------------------------------
+    // Voice Keyer 
+    //----------------------------------------------------------------------
 
-    bSizer30->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Voice Keyer")), wxHORIZONTAL);
+
+    wxStaticText *m_staticText28b = new wxStaticText(this, wxID_ANY, _("Wave File: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28b, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtCtrlVoiceKeyerWaveFile = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
+    m_txtCtrlVoiceKeyerWaveFile->SetToolTip(_("Wave file to play for Voice Keyer"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerWaveFile, 0, 0, 5);
+
+    m_buttonChooseVoiceKeyerWaveFile = new wxButton(this, wxID_APPLY, _("Choose"), wxDefaultPosition, wxSize(-1,-1), 0);
+    staticBoxSizer28a->Add(m_buttonChooseVoiceKeyerWaveFile, 0, wxALIGN_CENTER_VERTICAL, 5);
+
+    wxStaticText *m_staticText28c = new wxStaticText(this, wxID_ANY, _("   Rx Pause: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28c, 0, wxALIGN_CENTER_VERTICAL , 5);
+    m_txtCtrlVoiceKeyerRxPause = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRxPause->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRxPause, 0, 0, 5);
+
+    wxStaticText *m_staticText28d = new wxStaticText(this, wxID_ANY, _("   Repeats: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28d, 0, wxALIGN_CENTER_VERTICAL, 5);
+    m_txtCtrlVoiceKeyerRepeats = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRepeats->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRepeats, 0, 0, 5);
+
+    bSizer30->Add(staticBoxSizer28a,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __WXMSW__
+    //------------------------------
+    // debug console, for WIndows build make console pop up for debug messages
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_console;
+    wxStaticBox *sb_console = new wxStaticBox(this, wxID_ANY, _("Debug"));
+    sbSizer_console = new wxStaticBoxSizer(sb_console, wxHORIZONTAL);
+
+    m_ckboxDebugConsole = new wxCheckBox(this, wxID_ANY, _("Show Console"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_console->Add(m_ckboxDebugConsole, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_console,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
 
     //------------------------------
     // FreeDV 700 Options
     //------------------------------
 
     wxStaticBoxSizer* sbSizer_freedv700;
-    wxStaticBox *sb_freedv700 = new wxStaticBox(this, wxID_ANY, _("FreeDV 700 Clipping"));
+    wxStaticBox *sb_freedv700 = new wxStaticBox(this, wxID_ANY, _("FreeDV 700 Options"));
     sbSizer_freedv700 = new wxStaticBoxSizer(sb_freedv700, wxHORIZONTAL);
 
-    m_ckboxFreeDV700txClip = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
-    m_ckboxFreeDV700txClip->SetToolTip(_("Clip FreeDv 700 tx waveform to reduce Peak to Average Power Ratio (PAPR)"));
+    m_ckboxFreeDV700txClip = new wxCheckBox(this, wxID_ANY, _("Clipping"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
     sbSizer_freedv700->Add(m_ckboxFreeDV700txClip, 0, wxALIGN_LEFT, 0);
+    m_ckboxFreeDV700Combine = new wxCheckBox(this, wxID_ANY, _("Diversity Combine for plots"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_freedv700->Add(m_ckboxFreeDV700Combine, 0, wxALIGN_LEFT, 0);
 
-    bSizer30->Add(sbSizer_freedv700,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    bSizer30->Add(sbSizer_freedv700, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
 
     //------------------------------
-    // Txt Msg Text Box
+    // Half/Full duplex selection
     //------------------------------
 
-    wxStaticBoxSizer* sbSizer_callSign;
-    wxStaticBox *sb_textMsg = new wxStaticBox(this, wxID_ANY, _("Txt Msg"));
-    sbSizer_callSign = new wxStaticBoxSizer(sb_textMsg, wxVERTICAL);
+    wxStaticBox *sb_duplex = new wxStaticBox(this, wxID_ANY, _("Half/Full Duplex Operation"));
+    wxStaticBoxSizer* sbSizer_duplex = new wxStaticBoxSizer(sb_duplex, wxHORIZONTAL);
+    m_ckHalfDuplex = new wxCheckBox(this, wxID_ANY, _("Half Duplex"), wxDefaultPosition, wxSize(-1,-1), 0);
+    sbSizer_duplex->Add(m_ckHalfDuplex, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
+    bSizer30->Add(sbSizer_duplex,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
 
-    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
-    m_txtCtrlCallSign->SetToolTip(_("Txt Msg you can send along with Voice"));
-    sbSizer_callSign->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 3);
+    //------------------------------
+    // Test Frames/Channel simulation check box
+    //------------------------------
 
-    bSizer30->Add(sbSizer_callSign,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    wxStaticBoxSizer* sbSizer_testFrames;
+    wxStaticBox *sb_testFrames = new wxStaticBox(this, wxID_ANY, _("Testing and Channel Simulation"));
+    sbSizer_testFrames = new wxStaticBoxSizer(sb_testFrames, wxHORIZONTAL);
+
+    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Test Frames"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxChannelNoise = new wxCheckBox(this, wxID_ANY, _("Channel Noise   SNR (dB):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxChannelNoise, 0, wxALIGN_LEFT, 0);
+    m_txtNoiseSNR = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtNoiseSNR, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxAttnCarrierEn = new wxCheckBox(this, wxID_ANY, _("Attn Carrier  Carrier:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxAttnCarrierEn, 0, wxALIGN_LEFT, 0);
+    m_txtAttnCarrier = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtAttnCarrier, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Interfering tone
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_tone;
+    wxStaticBox *sb_tone = new wxStaticBox(this, wxID_ANY, _("Simulated Interference Tone"));
+    sbSizer_tone = new wxStaticBoxSizer(sb_tone, wxHORIZONTAL);
+
+    m_ckboxTone = new wxCheckBox(this, wxID_ANY, _("Tone   Freq (Hz):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_tone->Add(m_ckboxTone, 0, wxALIGN_LEFT, 0);
+    m_txtToneFreqHz = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneFreqHz, 0, wxALIGN_LEFT, 0);
+    wxStaticText *m_staticTextta = new wxStaticText(this, wxID_ANY, _(" Amplitude (pk): "), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_tone->Add(m_staticTextta, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtToneAmplitude = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneAmplitude, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_tone,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __EXPERIMENTAL_UDP__
     //------------------------------
     // Txt Encoding 
     //------------------------------
@@ -161,6 +243,7 @@ OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, c
     sbSizer_udp->Add(m_txt_udp_port, 0, wxALIGN_CENTER_HORIZONTAL, 5);
 
     bSizer30->Add(sbSizer_udp,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
 
     //------------------------------
     // OK - Cancel - Apply Buttons 
@@ -177,10 +260,14 @@ OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, c
     m_sdbSizer5Apply = new wxButton(this, wxID_APPLY);
     bSizer31->Add(m_sdbSizer5Apply, 0, wxALL, 2);
 
-    bSizer30->Add(bSizer31, 0, wxALIGN_RIGHT|wxALL, 0);
+    bSizer30->Add(bSizer31, 0, wxALIGN_CENTER, 0);
 
     this->SetSizer(bSizer30);
-    this->Layout();
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+     this->Layout();
 
     this->Centre(wxBOTH);
  
@@ -192,7 +279,18 @@ OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, c
     m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
     m_sdbSizer5Apply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
 
+    m_ckboxTestFrame->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
     m_ckboxFreeDV700txClip->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
+
+    m_buttonChooseVoiceKeyerWaveFile->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
 
     event_in_serial = 0;
     event_out_serial = 0;
@@ -211,7 +309,18 @@ OptionsDlg::~OptionsDlg()
     m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
     m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
     m_sdbSizer5Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
+
+    m_ckboxTestFrame->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
     m_ckboxFreeDV700txClip->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+    m_buttonChooseVoiceKeyerWaveFile->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
 }
 
 
@@ -225,9 +334,28 @@ void OptionsDlg::ExchangeData(int inout, bool storePersistent)
     if(inout == EXCHANGE_DATA_IN)
     {
         m_txtCtrlCallSign->SetValue(wxGetApp().m_callSign);
+
+        /* Voice Keyer */
+
+        m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+        m_txtCtrlVoiceKeyerRxPause->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRxPause));
+        m_txtCtrlVoiceKeyerRepeats->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRepeats));
+
+        m_ckHalfDuplex->SetValue(wxGetApp().m_boolHalfDuplex);
+
         m_ckboxTestFrame->SetValue(wxGetApp().m_testFrames);
+
         m_ckboxChannelNoise->SetValue(wxGetApp().m_channel_noise);
+        m_txtNoiseSNR->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_noise_snr));
 
+        m_ckboxTone->SetValue(wxGetApp().m_tone);
+        m_txtToneFreqHz->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_freq_hz));
+        m_txtToneAmplitude->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_amplitude));
+
+        m_ckboxAttnCarrierEn->SetValue(wxGetApp().m_attn_carrier_en);
+        m_txtAttnCarrier->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_attn_carrier));
+
+#ifdef __EXPERIMENTAL_UDP__
         m_ckbox_events->SetValue(wxGetApp().m_events);
         m_txt_spam_timer->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_events_spam_timer));
 
@@ -244,16 +372,55 @@ void OptionsDlg::ExchangeData(int inout, bool storePersistent)
             m_rb_textEncoding2->SetValue(true);
 #endif
         m_ckboxEnableChecksum->SetValue(wxGetApp().m_enable_checksum);
+#endif
 
         m_ckboxFreeDV700txClip->SetValue(wxGetApp().m_FreeDV700txClip);
+        m_ckboxFreeDV700Combine->SetValue(wxGetApp().m_FreeDV700Combine);
+
+#ifdef __WXMSW__
+        m_ckboxDebugConsole->SetValue(wxGetApp().m_debug_console);
+#endif
     }
 
     if(inout == EXCHANGE_DATA_OUT)
     {
-        wxGetApp().m_callSign      = m_txtCtrlCallSign->GetValue();
+        wxGetApp().m_callSign = m_txtCtrlCallSign->GetValue();
+
+        wxGetApp().m_boolHalfDuplex = m_ckHalfDuplex->GetValue();
+        pConfig->Write(wxT("/Rig/HalfDuplex"), wxGetApp().m_boolHalfDuplex);
+
+        /* Voice Keyer */
+
+        wxGetApp().m_txtVoiceKeyerWaveFile = m_txtCtrlVoiceKeyerWaveFile->GetValue();
+        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
+        long tmp;
+        m_txtCtrlVoiceKeyerRxPause->GetValue().ToLong(&tmp); if (tmp < 0) tmp = 0; wxGetApp().m_intVoiceKeyerRxPause = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
+        m_txtCtrlVoiceKeyerRepeats->GetValue().ToLong(&tmp);
+        if (tmp < 0) tmp = 0; if (tmp > 100) tmp = 100;
+        wxGetApp().m_intVoiceKeyerRepeats = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
+
         wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
-        wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
 
+        wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+        long noise_snr;
+        m_txtNoiseSNR->GetValue().ToLong(&noise_snr);
+        wxGetApp().m_noise_snr = (int)noise_snr;
+
+        wxGetApp().m_tone    = m_ckboxTone->GetValue();
+        long tone_freq_hz, tone_amplitude;
+        m_txtToneFreqHz->GetValue().ToLong(&tone_freq_hz);
+        wxGetApp().m_tone_freq_hz = (int)tone_freq_hz;
+        m_txtToneAmplitude->GetValue().ToLong(&tone_amplitude);
+        wxGetApp().m_tone_amplitude = (int)tone_amplitude;
+
+        wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();
+        long attn_carrier;
+        m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+        wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+#ifdef __EXPERIMENTAL_UDP__
         wxGetApp().m_events        = m_ckbox_events->GetValue();
         long spam_timer;
         m_txt_spam_timer->GetValue().ToLong(&spam_timer);
@@ -282,8 +449,14 @@ void OptionsDlg::ExchangeData(int inout, bool storePersistent)
             wxGetApp().m_textEncoding = 2;
 #endif
         wxGetApp().m_enable_checksum = m_ckboxEnableChecksum->GetValue();
+#endif
 
         wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
+        wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+
+#ifdef __WXMSW__
+        wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#endif
 
         if (storePersistent) {
             pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
@@ -300,8 +473,16 @@ void OptionsDlg::ExchangeData(int inout, bool storePersistent)
             pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
             pConfig->Write(wxT("/UDP/port"),  wxGetApp().m_udp_port);
 
+            pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+
             pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
 
+            pConfig->Write(wxT("/Noise/noise_snr"),  wxGetApp().m_noise_snr);
+
+#ifdef __WXMSW__
+            pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+#endif
+
             pConfig->Flush();
         }
     }
@@ -347,10 +528,69 @@ void OptionsDlg::OnInitDialog(wxInitDialogEvent& event)
 
 // immediately change flags rather using ExchangeData() so we can switch on and off at run time
 
+void OptionsDlg::OnTestFrame(wxScrollEvent& event) {
+    wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
+}
+
+void OptionsDlg::OnChannelNoise(wxScrollEvent& event) {
+    wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+}
+
+
+void OptionsDlg::OnChooseVoiceKeyerWaveFile(wxCommandEvent& event) {
+     wxFileDialog openFileDialog(
+                                 this,
+                                 wxT("Voice Keyer wave file"),
+                                 wxGetApp().m_txtVoiceKeyerWaveFilePath,
+                                 wxEmptyString,
+                                 wxT("WAV files (*.wav)|*.wav"),
+                                 wxFD_OPEN
+                                 );
+     if(openFileDialog.ShowModal() == wxID_CANCEL) {
+         return;     // the user changed their mind...
+     }
+
+     wxString fileName, extension;
+     wxGetApp().m_txtVoiceKeyerWaveFile = openFileDialog.GetPath();
+     wxFileName::SplitPath(wxGetApp().m_txtVoiceKeyerWaveFile, &wxGetApp().m_txtVoiceKeyerWaveFilePath, &fileName, &extension);
+     m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+}
+
+//  Run time update of carrier amplitude attenuation
+
+void OptionsDlg::OnAttnCarrierEn(wxScrollEvent& event) {
+    long attn_carrier;
+    m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+    wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+    /* uncheck -> checked, attenuate selected carrier */
+
+    if (m_ckboxAttnCarrierEn->GetValue() && !wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 0.25);
+        } else {
+            wxMessageBox("Carrier attenuation feature only works on 700C", wxT("Warning"), wxOK | wxICON_WARNING, this);
+        }
+    }
+
+    /* checked -> unchecked, reset selected carrier */
+
+    if (!m_ckboxAttnCarrierEn->GetValue() && wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 1.0);
+        }
+    }
+        
+    wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();    
+}
+
 void OptionsDlg::OnFreeDV700txClip(wxScrollEvent& event) {
     wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
 }
 
+void OptionsDlg::OnFreeDV700Combine(wxScrollEvent& event) {
+    wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+}
 
 void OptionsDlg::updateEventLog(wxString event_in, wxString event_out) {
     wxString event_in_with_serial, event_out_with_serial; 
@@ -361,3 +601,16 @@ void OptionsDlg::updateEventLog(wxString event_in, wxString event_out) {
     m_txt_events_out->AppendText(event_out_with_serial+"\n");
 }
 
+
+void OptionsDlg::OnDebugConsole(wxScrollEvent& event) {
+    wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#ifdef __WXMSW__
+    // somewhere to send printfs while developing, causes conmsole to pop up on Windows
+    if (wxGetApp().m_debug_console) {
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    } 
+#endif
+}
index fe355ac253c5a0387b40100a9ff57c1507dbd37f..081448cbba39ff079d5cfbf8284ff15ad7164347 100644 (file)
@@ -33,7 +33,13 @@ class OptionsDlg : public wxDialog
     public:
     OptionsDlg( wxWindow* parent,
                wxWindowID id = wxID_ANY, const wxString& title = _("Options"), 
-                const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(600,630), 
+                const wxPoint& pos = wxDefaultPosition, 
+#ifdef __WXMSW__
+                /* we add debug console check box for windows */
+                const wxSize& size = wxSize(600,410), 
+#else
+                const wxSize& size = wxSize(600,380), 
+#endif
                long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
         ~OptionsDlg();
 
@@ -58,19 +64,47 @@ class OptionsDlg : public wxDialog
 
 
     protected:
+
         // Handlers for events.
+
         void    OnOK(wxCommandEvent& event);
         void    OnCancel(wxCommandEvent& event);
         void    OnApply(wxCommandEvent& event);
         void    OnClose(wxCloseEvent& event);
         void    OnInitDialog(wxInitDialogEvent& event);
  
+        void    OnTestFrame(wxScrollEvent& event);
+        void    OnChannelNoise(wxScrollEvent& event);
+        void    OnAttnCarrierEn(wxScrollEvent& event);
         void    OnFreeDV700txClip(wxScrollEvent& event);
+        void    OnFreeDV700Combine(wxScrollEvent& event);
+        void    OnDebugConsole(wxScrollEvent& event);
 
         wxTextCtrl   *m_txtCtrlCallSign; // TODO: this should be renamed to tx_txtmsg, and rename all related incl persis strge
+
+        wxCheckBox* m_ckHalfDuplex;
+
+        /* Voice Keyer */
+
+        wxButton     *m_buttonChooseVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRxPause;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRepeats;
+
+        /* test frames, other simulated channel impairments */
+
         wxCheckBox   *m_ckboxTestFrame;
         wxCheckBox   *m_ckboxChannelNoise;
+        wxTextCtrl   *m_txtNoiseSNR;
+        wxCheckBox   *m_ckboxAttnCarrierEn;
+        wxTextCtrl   *m_txtAttnCarrier;
+
+        wxCheckBox   *m_ckboxTone;
+        wxTextCtrl   *m_txtToneFreqHz;
+        wxTextCtrl   *m_txtToneAmplitude;
+
         wxCheckBox   *m_ckboxFreeDV700txClip;
+        wxCheckBox   *m_ckboxFreeDV700Combine;
 
         wxRadioButton *m_rb_textEncoding1;
         wxRadioButton *m_rb_textEncoding2;
@@ -91,8 +125,12 @@ class OptionsDlg : public wxDialog
         wxButton*     m_sdbSizer5Cancel;
         wxButton*     m_sdbSizer5Apply;
 
+        wxCheckBox   *m_ckboxDebugConsole;
+
         unsigned int  event_in_serial, event_out_serial;
 
+        void OnChooseVoiceKeyerWaveFile(wxCommandEvent& event);
+
      private:
 };
 
index 138f63f25f8b2f203e46d40b109661093775cca9..1a04c9c4e5034aaafc545ddd3b5be4451395e60e 100644 (file)
@@ -41,79 +41,59 @@ ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title,
     this->SetSizer(mainSizer);
     
     //----------------------------------------------------------------------
-    // Half Duplex Flag for VOX PTT
+    // Vox tone option
     //----------------------------------------------------------------------
 
-    // DR: should this be on options dialog?
-
     wxStaticBoxSizer* staticBoxSizer28 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("VOX PTT Settings")), wxHORIZONTAL);
-    m_ckHalfDuplex = new wxCheckBox(this, wxID_ANY, _("Half Duplex"), wxDefaultPosition, wxSize(-1,-1), 0);
-    staticBoxSizer28->Add(m_ckHalfDuplex, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
     m_ckLeftChannelVoxTone = new wxCheckBox(this, wxID_ANY, _("Left Channel Vox Tone"), wxDefaultPosition, wxSize(-1,-1), 0);
     staticBoxSizer28->Add(m_ckLeftChannelVoxTone, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
 
     mainSizer->Add(staticBoxSizer28, 0, wxEXPAND, 5);
 
-    //----------------------------------------------------------------------
-    // Voice Keyer 
-    //----------------------------------------------------------------------
-
-    wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Voice Keyer")), wxHORIZONTAL);
-
-    wxStaticText *m_staticText28b = new wxStaticText(this, wxID_ANY, _("Wave File: "), wxDefaultPosition, wxDefaultSize, 0);
-    staticBoxSizer28a->Add(m_staticText28b, 0, wxALIGN_CENTER_VERTICAL, 5);    
-    m_txtCtrlVoiceKeyerWaveFile = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
-    m_txtCtrlVoiceKeyerWaveFile->SetToolTip(_("Wave file to play for Voice Keyer"));
-    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerWaveFile, 0, 0, 5);
-
-    m_buttonChooseVoiceKeyerWaveFile = new wxButton(this, wxID_APPLY, _("Choose"), wxDefaultPosition, wxSize(-1,-1), 0);
-    staticBoxSizer28a->Add(m_buttonChooseVoiceKeyerWaveFile, 0, wxALIGN_CENTER_VERTICAL, 5);
-
-    wxStaticText *m_staticText28c = new wxStaticText(this, wxID_ANY, _("   Rx Pause: "), wxDefaultPosition, wxDefaultSize, 0);
-    staticBoxSizer28a->Add(m_staticText28c, 0, wxALIGN_CENTER_VERTICAL , 5);
-    m_txtCtrlVoiceKeyerRxPause = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
-    m_txtCtrlVoiceKeyerRxPause->SetToolTip(_("How long to wait in Rx mode before repeat"));
-    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRxPause, 0, 0, 5);
-
-    wxStaticText *m_staticText28d = new wxStaticText(this, wxID_ANY, _("   Repeats: "), wxDefaultPosition, wxDefaultSize, 0);
-    staticBoxSizer28a->Add(m_staticText28d, 0, wxALIGN_CENTER_VERTICAL, 5);
-    m_txtCtrlVoiceKeyerRepeats = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
-    m_txtCtrlVoiceKeyerRepeats->SetToolTip(_("How long to wait in Rx mode before repeat"));
-    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRepeats, 0, 0, 5);
-
-    mainSizer->Add(staticBoxSizer28a, 0, wxEXPAND, 5);
-
     //----------------------------------------------------------------------
     // Hamlib for CAT PTT
     //----------------------------------------------------------------------
 
-    wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxVERTICAL);
-
-    wxBoxSizer* gridSizer100 = new wxBoxSizer(wxHORIZONTAL);
+    wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxHORIZONTAL);
+    wxGridSizer* gridSizerhl = new wxGridSizer(5, 2, 0, 0);
+    staticBoxSizer18->Add(gridSizerhl, 1, wxEXPAND|wxALIGN_LEFT, 5);
 
     /* Use Hamlib for PTT checkbox. */
+
     m_ckUseHamlibPTT = new wxCheckBox(this, wxID_ANY, _("Use Hamlib PTT"), wxDefaultPosition, wxSize(-1, -1), 0);
     m_ckUseHamlibPTT->SetValue(false);
-    gridSizer100->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0);
+    gridSizerhl->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0);
+    gridSizerhl->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND);
 
     /* Hamlib Rig Type combobox. */
-    gridSizer100->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), 
-                      0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20);
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
     m_cbRigName = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, -1), 0, NULL, wxCB_DROPDOWN);
-    /* TODO(Joel): this is a hack. At the least, need to gurantee that m_hamLib
-     * exists. */
     wxGetApp().m_hamlib->populateComboBox(m_cbRigName);
     m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
-    gridSizer100->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0);
+    gridSizerhl->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0);
 
     /* Hamlib Serial Port combobox. */
-    gridSizer100->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), 
-                      0, wxALIGN_CENTER_VERTICAL | wxLEFT, 20);
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL |  wxALIGN_RIGHT, 20);
     m_cbSerialPort = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
-    gridSizer100->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0);
+    gridSizerhl->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    /* Hamlib Serial Rate combobox. */
 
-    staticBoxSizer18->Add(gridSizer100, 1);
-    mainSizer->Add(staticBoxSizer18, 1);
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Rate:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialRate = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizerhl->Add(m_cbSerialRate, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Params:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialParams = new wxStaticText(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, 0);
+    gridSizerhl->Add(m_cbSerialParams, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    mainSizer->Add(staticBoxSizer18, 0, wxEXPAND, 5);
 
     //----------------------------------------------------------------------
     // Serial port PTT
@@ -189,6 +169,9 @@ ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title,
 
     wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
 
+    m_buttonTest = new wxButton(this, wxID_APPLY, _("Test PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonTest, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
     m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
     m_buttonOK->SetDefault();
     boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
@@ -214,7 +197,7 @@ ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title,
     m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
     m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
     m_buttonApply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
-    m_buttonChooseVoiceKeyerWaveFile->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
 }
 
 //-------------------------------------------------------------------------
@@ -229,7 +212,7 @@ ComPortsDlg::~ComPortsDlg()
     m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
     m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
     m_buttonApply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
-    m_buttonChooseVoiceKeyerWaveFile->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
 }
 
 //-------------------------------------------------------------------------
@@ -246,6 +229,14 @@ void ComPortsDlg::OnInitDialog(wxInitDialogEvent& event)
 //-------------------------------------------------------------------------
 void ComPortsDlg::populatePortList()
 {
+
+    /* populate Hamlib serial rate combo box */
+
+    wxString serialRates[] = {"default", "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"}; 
+    for(int i=0; i<WXSIZEOF(serialRates); i++) {
+        m_cbSerialRate->Append(serialRates[i]);
+    }
+
 #ifdef __WXMSW__
     m_listCtrlPorts->Clear();
     m_cbSerialPort->Clear();
@@ -329,6 +320,7 @@ void ComPortsDlg::populatePortList()
     m_cbSerialPort->Append("/dev/ttyUSB1");
     m_cbSerialPort->Append("/dev/ttyS0");
     m_cbSerialPort->Append("/dev/ttyS1");
+
     m_cbCtlDevicePath->Clear();
     m_cbCtlDevicePath->Append("/dev/ttyUSB0");
     m_cbCtlDevicePath->Append("/dev/ttyUSB1");
@@ -336,6 +328,8 @@ void ComPortsDlg::populatePortList()
     m_cbCtlDevicePath->Append("/dev/ttyS1");
 #endif
 #endif
+
+
 }
 
 //-------------------------------------------------------------------------
@@ -346,21 +340,23 @@ void ComPortsDlg::ExchangeData(int inout)
     wxConfigBase *pConfig = wxConfigBase::Get();
     wxString str;
     
-    if(inout == EXCHANGE_DATA_IN)
-    {
-        m_ckHalfDuplex->SetValue(wxGetApp().m_boolHalfDuplex);
+    if(inout == EXCHANGE_DATA_IN) {
         m_ckLeftChannelVoxTone->SetValue(wxGetApp().m_leftChannelVoxTone);
 
-        /* Voice Keyer */
-
-        m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
-        m_txtCtrlVoiceKeyerRxPause->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRxPause));
-        m_txtCtrlVoiceKeyerRepeats->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRepeats));
+        /* Hamlib */
 
         m_ckUseHamlibPTT->SetValue(wxGetApp().m_boolHamlibUseForPTT);
         m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
         m_cbSerialPort->SetValue(wxGetApp().m_strHamlibSerialPort);
 
+        if (wxGetApp().m_intHamlibSerialRate == 0) {
+            m_cbSerialRate->SetSelection(0);
+        } else {
+            m_cbSerialRate->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intHamlibSerialRate));
+        }
+
+        /* Serial PTT */
+
         m_ckUseSerialPTT->SetValue(wxGetApp().m_boolUseSerialPTT);
         str = wxGetApp().m_strRigCtrlPort;
 #ifdef __WXMSW__
@@ -374,34 +370,31 @@ void ComPortsDlg::ExchangeData(int inout)
         m_rbUseDTR->SetValue(wxGetApp().m_boolUseDTR);
         m_ckDTRPos->SetValue(wxGetApp().m_boolDTRPos);
     }
-    if(inout == EXCHANGE_DATA_OUT)
-    {
-        wxGetApp().m_boolHalfDuplex = m_ckHalfDuplex->GetValue();
-        pConfig->Write(wxT("/Rig/HalfDuplex"), wxGetApp().m_boolHalfDuplex);
+
+    if (inout == EXCHANGE_DATA_OUT) {
         wxGetApp().m_leftChannelVoxTone = m_ckLeftChannelVoxTone->GetValue();
         pConfig->Write(wxT("/Rig/leftChannelVoxTone"), wxGetApp().m_leftChannelVoxTone);
 
-        /* Voice Keyer */
-
-        wxGetApp().m_txtVoiceKeyerWaveFile = m_txtCtrlVoiceKeyerWaveFile->GetValue();
-        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
-        long tmp;
-        m_txtCtrlVoiceKeyerRxPause->GetValue().ToLong(&tmp); if (tmp < 0) tmp = 0; wxGetApp().m_intVoiceKeyerRxPause = (int)tmp;
-        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
-        m_txtCtrlVoiceKeyerRepeats->GetValue().ToLong(&tmp);
-        if (tmp < 0) tmp = 0; if (tmp > 100) tmp = 100;
-        wxGetApp().m_intVoiceKeyerRepeats = (int)tmp;
-        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
-
         /* Hamlib settings. */
 
         wxGetApp().m_boolHamlibUseForPTT = m_ckUseHamlibPTT->GetValue();
         wxGetApp().m_intHamlibRig = m_cbRigName->GetSelection();
         wxGetApp().m_strHamlibSerialPort = m_cbSerialPort->GetValue();
 
+        wxString s = m_cbSerialRate->GetValue();
+        if (s == "default") {
+            wxGetApp().m_intHamlibSerialRate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            wxGetApp().m_intHamlibSerialRate = tmp;
+        }
+        fprintf(stderr, "serial rate: %d\n", wxGetApp().m_intHamlibSerialRate);
+
         pConfig->Write(wxT("/Hamlib/UseForPTT"), wxGetApp().m_boolHamlibUseForPTT);
         pConfig->Write(wxT("/Hamlib/RigName"), wxGetApp().m_intHamlibRig);
         pConfig->Write(wxT("/Hamlib/SerialPort"), wxGetApp().m_strHamlibSerialPort);
+        pConfig->Write(wxT("/Hamlib/SerialRate"), wxGetApp().m_intHamlibSerialRate);
 
         /* Serial settings */
 
@@ -434,9 +427,115 @@ void ComPortsDlg::ExchangeData(int inout)
 //-------------------------------------------------------------------------
 void ComPortsDlg::PTTUseHamLibClicked(wxCommandEvent& event)
 {
-    m_ckUseSerialPTT->SetValue(false);    
+    m_ckUseSerialPTT->SetValue(false);
+}
+
+
+/* Attempt to toggle PTT for 1 second */
+
+void ComPortsDlg::OnTest(wxCommandEvent& event) {
+
+    /* Tone PTT */
+
+    if (m_ckLeftChannelVoxTone->GetValue()) {
+        wxMessageBox("Testing of tone based PTT not supported; try PTT after pressing Start on main window", 
+                     wxT("Error"), wxOK | wxICON_ERROR, this);
+    }
+
+    /* Hamlib PTT */
+
+    if (m_ckUseHamlibPTT->GetValue()) {
+
+        // set up current hamlib config from GUI
+
+        int rig = m_cbRigName->GetSelection();
+        wxString port = m_cbSerialPort->GetValue();
+        wxString s = m_cbSerialRate->GetValue();
+        int serial_rate;
+        if (s == "default") {
+            serial_rate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            serial_rate = tmp;
+        }
+
+        // display serial params
+
+        fprintf(stderr, "serial rate: %d\n", serial_rate);
+
+        // try to open rig
+
+        Hamlib *hamlib = wxGetApp().m_hamlib; 
+        bool status = hamlib->connect(rig, port.mb_str(wxConvUTF8), serial_rate);
+        if (status == false) {
+            wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+        else {
+            wxString hamlib_serial_config;
+            hamlib_serial_config.sprintf(" %d, %d, %d", 
+                                         hamlib->get_serial_rate(),
+                                         hamlib->get_data_bits(),
+                                         hamlib->get_stop_bits());
+            m_cbSerialParams->SetLabel(hamlib_serial_config);
+       }
+
+        // toggle PTT
+
+        wxString hamlibError;
+        if (hamlib->ptt(true, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+
+        wxSleep(1);
+
+        if (hamlib->ptt(false, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+    }
+
+    /* Serial PTT */
+
+    if (m_ckUseSerialPTT->IsChecked()) {
+        Serialport *serialport = wxGetApp().m_serialport; 
+        
+        wxString ctrlport;
+#ifdef __WXMSW__
+        ctrlport = m_listCtrlPorts->GetStringSelection();
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+        ctrlport = m_cbCtlDevicePath->GetValue();
+#endif
+        fprintf(stderr, "opening serial port\n");
+
+        bool success = serialport->openport(ctrlport.c_str(),
+                                            m_rbUseRTS->GetValue(),
+                                            m_ckRTSPos->IsChecked(),
+                                            m_rbUseDTR->GetValue(),
+                                            m_ckDTRPos->IsChecked());
+
+        fprintf(stderr, "serial port open\n");
+
+        if (!success) {
+            wxMessageBox("Couldn't open serial port", wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+
+        // assert PTT port for 1 sec
+
+        serialport->ptt(true);
+        wxSleep(1);
+        serialport->ptt(false);
+
+        fprintf(stderr, "closing serial port\n");
+        serialport->closeport();
+        fprintf(stderr, "serial port closed\n");
+    }
+    
 }
 
+
 //-------------------------------------------------------------------------
 // PTTUseSerialClicked()
 //-------------------------------------------------------------------------
@@ -453,25 +552,6 @@ void ComPortsDlg::OnApply(wxCommandEvent& event)
     ExchangeData(EXCHANGE_DATA_OUT);
 }
 
- void ComPortsDlg::OnChooseVoiceKeyerWaveFile(wxCommandEvent& event) {
-     wxFileDialog openFileDialog(
-                                 this,
-                                 wxT("Voice Keyer wave file"),
-                                 wxGetApp().m_txtVoiceKeyerWaveFilePath,
-                                 wxEmptyString,
-                                 wxT("WAV files (*.wav)|*.wav"),
-                                 wxFD_SAVE
-                                 );
-     if(openFileDialog.ShowModal() == wxID_CANCEL) {
-         return;     // the user changed their mind...
-     }
-
-     wxString fileName, extension;
-     wxGetApp().m_txtVoiceKeyerWaveFile = openFileDialog.GetPath();
-     wxFileName::SplitPath(wxGetApp().m_txtVoiceKeyerWaveFile, &wxGetApp().m_txtVoiceKeyerWaveFilePath, &fileName, &extension);
-     m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
-}
-
 //-------------------------------------------------------------------------
 // OnCancel()
 //-------------------------------------------------------------------------
index 70b8ff351bee6267fe5e26f2dcfe7b7742d9bce0..26ab17e8a8f90fdc90881728d2bb952fc0947309 100644 (file)
@@ -47,22 +47,14 @@ class ComPortsDlg : public wxDialog
         void    ExchangeData(int inout);
 
     protected:
-        wxCheckBox* m_ckHalfDuplex;
         wxCheckBox* m_ckLeftChannelVoxTone;
 
-        /* Voice Keyer */
-
-        wxButton     *m_buttonChooseVoiceKeyerWaveFile;
-        wxTextCtrl   *m_txtCtrlVoiceKeyerWaveFile;
-        wxTextCtrl   *m_txtCtrlVoiceKeyerRxPause;
-        wxTextCtrl   *m_txtCtrlVoiceKeyerRepeats;
-
         /* Hamlib settings.*/
 
         wxCheckBox *m_ckUseHamlibPTT;
         wxComboBox *m_cbRigName;
         wxComboBox *m_cbSerialPort;
-
+        wxStaticText  *m_cbSerialParams;
         Hamlib *m_hamlib;
 
         /* Serial Settings */
@@ -76,8 +68,9 @@ class ComPortsDlg : public wxDialog
         wxRadioButton *m_rbUseRTS;
         wxCheckBox    *m_ckDTRPos;
 
-        /* Ok - Cancel - Apply */
+        /* Test - Ok - Cancel - Apply */
 
+        wxButton* m_buttonTest;
         wxButton* m_buttonOK;
         wxButton* m_buttonCancel;
         wxButton* m_buttonApply;
@@ -89,7 +82,7 @@ protected:
         void PTTUseHamLibClicked(wxCommandEvent& event);
         void PTTUseSerialClicked(wxCommandEvent& event);
 
-        void OnChooseVoiceKeyerWaveFile(wxCommandEvent& event);
+        void OnTest(wxCommandEvent& event);
 
         void OnOK(wxCommandEvent& event);
         void OnCancel(wxCommandEvent& event);
index 836f26f2cf270a6ac39cce5fa1e12b713481a258..47a6e77c6bc1b2bb1229a238d1431c54eb67b240 100644 (file)
@@ -145,9 +145,7 @@ bool MainApp::OnInit()
     SetVendorName(wxT("CODEC2-Project"));
     SetAppName(wxT("FreeDV"));      // not needed, it's the default value
 
-    // DR - this is wrong define so won't be used on windows build, should be __WXMSW__
-    // So registry will be used for Win32
-#ifdef _WXMSW_
+#ifdef FILE_RATHER_THAN_REGISTRY
     // Force use of file-based configuration persistance on Windows platforma
     wxConfig *pConfig = new wxConfig();
     wxFileConfig *pFConfig = new wxFileConfig(wxT("FreeDV"), wxT("CODEC2-Project"), wxT("FreeDV.conf"), wxT("FreeDV.conf"),  wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
@@ -250,6 +248,7 @@ bool MainApp::OnInit()
 //-------------------------------------------------------------------------
 int MainApp::OnExit()
 {
+    fprintf(stderr, "MainApp::OnExit\n");
     if (m_plugIn) {
         #ifdef __WXMSW__
         FreeLibrary((HMODULE)m_plugInHandle);
@@ -281,6 +280,10 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
 
     wxGetApp().m_hamlib = new Hamlib();
 
+    // Init Serialport library, but as for Hamlib we dont start talking to any rigs yet
+
+    wxGetApp().m_serialport = new Serialport();
+
     tools->AppendSeparator();
     wxMenuItem* m_menuItemToolsConfigDelete;
     m_menuItemToolsConfigDelete = new wxMenuItem(tools, wxID_ANY, wxString(_("&Restore defaults")) , wxT("Delete config file/keys and restore defaults"), wxITEM_NORMAL);
@@ -438,7 +441,8 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
     wxGetApp().m_boolRTSPos         = pConfig->ReadBool(wxT("/Rig/RTSPolarity"),    true);
     wxGetApp().m_boolUseDTR         = pConfig->ReadBool(wxT("/Rig/UseDTR"),         false);
     wxGetApp().m_boolDTRPos         = pConfig->ReadBool(wxT("/Rig/DTRPolarity"),    false);
-    com_handle = COM_HANDLE_INVALID;
+
+    assert(wxGetApp().m_serialport != NULL);
 
     // -----------------------------------------------------------------------
 
@@ -497,6 +501,8 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
     wxGetApp().m_udp_port = (int)pConfig->Read(wxT("/UDP/port"), 3000);
 
     wxGetApp().m_FreeDV700txClip = (float)pConfig->Read(wxT("/FreeDV700/txClip"), t);
+    wxGetApp().m_debug_console = (float)pConfig->Read(wxT("/Debug/console"), f);
 
     int mode  = pConfig->Read(wxT("/Audio/mode"), (long)0);
     if (mode == 0)
@@ -592,16 +598,30 @@ MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInNam
 
     g_modal = false;
 
+#ifdef __EXPERIMENTAL_UDP__
     // Start UDP listener thread
 
     m_UDPThread = NULL;
     startUDPThread();
+#endif
 
     optionsDlg = new OptionsDlg(NULL);
     m_schedule_restore = false;
 
     vk_state = VK_IDLE;
 
+    // Init optional Windows debug console so we can see all those printfs
+
+#ifdef __WXMSW__
+    if (wxGetApp().m_debug_console) {
+        // somewhere to send printfs while developing
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    }
+#endif
+
     //ftest = fopen("ftest.raw", "wb");
     //assert(ftest != NULL);
 }
@@ -616,6 +636,7 @@ MainFrame::~MainFrame()
     int w;
     int h;
 
+    fprintf(stderr, "MainFrame::~MainFrame()\n");
     //fclose(ftest);
     #ifdef __WXMSW__
     fclose(g_logfile);
@@ -626,23 +647,18 @@ MainFrame::~MainFrame()
         optionsDlg = NULL;
     }
 
+#ifdef __EXPERIMENTAL_UDP__
     stopUDPThread();
+#endif
 
-    /* TOOD(Joel): the ownership of m_hamlib is probably wrong. */
     if (wxGetApp().m_hamlib) delete wxGetApp().m_hamlib;
+    if (wxGetApp().m_serialport) delete wxGetApp().m_serialport;
 
-    //MainApp *pApp = wxGetApp();
     wxConfigBase *pConfig = wxConfigBase::Get();
     if(pConfig)
     {
         if (!IsIconized()) {
             GetClientSize(&w, &h);
-
-            // big hack - for some reason height shrinks by this much
-            // every time FreeDV runs!  I have no idea why
-
-            h += 23;
-
             GetPosition(&x, &y);
             printf("x = %d y = %d w = %d h = %d\n", x,y,w,h);
             pConfig->Write(wxT("/MainFrame/left"),               (long) x);
@@ -711,6 +727,8 @@ MainFrame::~MainFrame()
 
         pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
 
+        pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+
         int mode;
         if (m_rb1600->GetValue())
             mode = 0;
@@ -762,187 +780,12 @@ MainFrame::~MainFrame()
     delete wxConfigBase::Set((wxConfigBase *) NULL);
 }
 
-//----------------------------------------------------------------
-// closeComPort() closes the currently open com port
-//----------------------------------------------------------------
-void MainFrame::closeComPort(void)
-{
-#ifdef _WIN32
-       CloseHandle(com_handle);
-#else
-       close(com_handle);
-#endif
-       com_handle = COM_HANDLE_INVALID;
-}
-
-//----------------------------------------------------------------
-// openComPort() opens the com port specified by the string
-// ie: "COM1" on Windows or "/dev/ttyu0" on FreeBSD
-//----------------------------------------------------------------
-bool MainFrame::openComPort(const char *name)
-{
-       if(com_handle != COM_HANDLE_INVALID)
-               closeComPort();
-#ifdef _WIN32
-       {
-               COMMCONFIG CC;
-               DWORD CCsize=sizeof(CC);
-               COMMTIMEOUTS timeouts;
-               DCB     dcb;
-
-               if(GetDefaultCommConfigA(name, &CC, &CCsize)) {
-                       CC.dcb.fOutxCtsFlow             = FALSE;
-                       CC.dcb.fOutxDsrFlow             = FALSE;
-                       CC.dcb.fDtrControl              = DTR_CONTROL_DISABLE;
-                       CC.dcb.fDsrSensitivity  = FALSE;
-                       CC.dcb.fRtsControl              = RTS_CONTROL_DISABLE;
-                       SetDefaultCommConfigA(name, &CC, CCsize);
-               }
-
-               if((com_handle=CreateFileA(name
-                       ,GENERIC_READ|GENERIC_WRITE     /* Access */
-                       ,0                                                              /* Share mode */
-                       ,NULL                                                   /* Security attributes */
-                       ,OPEN_EXISTING                                  /* Create access */
-                       ,FILE_ATTRIBUTE_NORMAL                  /* File attributes */
-                       ,NULL                                                   /* Template */
-                       ))==INVALID_HANDLE_VALUE)
-                       return false;
-
-               if(GetCommTimeouts(com_handle, &timeouts)) {
-                       timeouts.ReadIntervalTimeout=MAXDWORD;
-                       timeouts.ReadTotalTimeoutMultiplier=0;
-                       timeouts.ReadTotalTimeoutConstant=0;            // No-wait read timeout
-                       timeouts.WriteTotalTimeoutMultiplier=0;
-                       timeouts.WriteTotalTimeoutConstant=5000;        // 5 seconds
-                       SetCommTimeouts(com_handle,&timeouts);
-               }
-
-               /* Force N-8-1 mode: */
-               if(GetCommState(com_handle, &dcb)==TRUE) {
-                       dcb.ByteSize            = 8;
-                       dcb.Parity                      = NOPARITY;
-                       dcb.StopBits            = ONESTOPBIT;
-                       dcb.DCBlength           = sizeof(DCB);
-                       dcb.fBinary                     = TRUE;
-                       dcb.fOutxCtsFlow        = FALSE;
-                       dcb.fOutxDsrFlow        = FALSE;
-                       dcb.fDtrControl         = DTR_CONTROL_DISABLE;
-                       dcb.fDsrSensitivity     = FALSE;
-                       dcb.fTXContinueOnXoff= TRUE;
-                       dcb.fOutX                       = FALSE;
-                       dcb.fInX                        = FALSE;
-                       dcb.fRtsControl         = RTS_CONTROL_DISABLE;
-                       dcb.fAbortOnError       = FALSE;
-                       SetCommState(com_handle, &dcb);
-               }
-       }
-#else
-       {
-               struct termios t;
-
-               if((com_handle=open(name, O_NONBLOCK|O_RDWR))==COM_HANDLE_INVALID)
-                       return false;
-
-               if(tcgetattr(com_handle, &t)==-1) {
-                       close(com_handle);
-                       com_handle = COM_HANDLE_INVALID;
-                       return false;
-               }
-
-               t.c_iflag = (
-                                         IGNBRK   /* ignore BREAK condition */
-                                       | IGNPAR   /* ignore (discard) parity errors */
-                                       );
-               t.c_oflag = 0;  /* No output processing */
-               t.c_cflag = (
-                                         CS8         /* 8 bits */
-                                       | CREAD       /* enable receiver */
-               /*
-               Fun snippet from the FreeBSD manpage:
-
-                        If CREAD is set, the receiver is enabled.  Otherwise, no character is
-                        received.  Not all hardware supports this bit.  In fact, this flag is
-                        pretty silly and if it were not part of the termios specification it
-                        would be omitted.
-               */
-                                       | CLOCAL      /* ignore modem status lines */
-                                       );
-               t.c_lflag = 0;  /* No local modes */
-               if(tcsetattr(com_handle, TCSANOW, &t)==-1) {
-                       close(com_handle);
-                       com_handle = COM_HANDLE_INVALID;
-                       return false;
-               }
-               
-       }
-#endif
-       return true;
-}
 
 #ifdef _USE_ONIDLE
 void MainFrame::OnIdle(wxIdleEvent &evt) {
 }
 #endif
 
-//----------------------------------------------------------------
-// (raise|lower)(RTS|DTR)()
-//
-// Raises/lowers the specified signal
-//----------------------------------------------------------------
-void MainFrame::raiseDTR(void)
-{
-       if(com_handle == COM_HANDLE_INVALID)
-               return;
-#ifdef _WIN32
-       EscapeCommFunction(com_handle, SETDTR);
-#else
-       {       // For C89 happiness
-               int flags = TIOCM_DTR;
-               ioctl(com_handle, TIOCMBIS, &flags);
-       }
-#endif
-}
-void MainFrame::raiseRTS(void)
-{
-       if(com_handle == COM_HANDLE_INVALID)
-               return;
-#ifdef _WIN32
-       EscapeCommFunction(com_handle, SETRTS);
-#else
-       {       // For C89 happiness
-               int flags = TIOCM_RTS;
-               ioctl(com_handle, TIOCMBIS, &flags);
-       }
-#endif
-}
-void MainFrame::lowerDTR(void)
-{
-       if(com_handle == COM_HANDLE_INVALID)
-               return;
-#ifdef _WIN32
-       EscapeCommFunction(com_handle, CLRDTR);
-#else
-       {       // For C89 happiness
-               int flags = TIOCM_DTR;
-               ioctl(com_handle, TIOCMBIC, &flags);
-       }
-#endif
-}
-void MainFrame::lowerRTS(void)
-{
-       if(com_handle == COM_HANDLE_INVALID)
-               return;
-#ifdef _WIN32
-       EscapeCommFunction(com_handle, CLRRTS);
-#else
-       {       // For C89 happiness
-               int flags = TIOCM_RTS;
-               ioctl(com_handle, TIOCMBIC, &flags);
-       }
-#endif
-}
-
 
 #ifdef _USE_TIMER
 //----------------------------------------------------------------
@@ -1194,6 +1037,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
                     s.Printf("%s", m_callsign);
                     m_txtCtrlCallSign->SetValue(s);
 
+#ifdef __UDP_EXPERIMENTAL__
                     char s1[MAX_CALLSIGN];
                     sprintf(s1,"rx_txtmsg %s", m_callsign);
                     processTxtEvent(s1);
@@ -1201,11 +1045,14 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
                     m_checksumGood++;
                     s.Printf("%d", m_checksumGood);
                     m_txtChecksumGood->SetLabel(s);              
+#endif
                 }
                 else {
+#ifdef __UDP_EXPERIMENTAL__
                     m_checksumBad++;
                     s.Printf("%d", m_checksumBad);
                     m_txtChecksumBad->SetLabel(s);        
+#endif
                 }
             }
 
@@ -1336,6 +1183,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
         m_schedule_restore = false;
     }
 
+#ifdef __UDP_EXPERIMENTAL__
     // Light Spam Timer LED if at least one timer is running
 
     int i;
@@ -1343,6 +1191,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
     for(i=0; i<MAX_EVENT_RULES; i++)
         if (spamTimer[i].IsRunning())
             optionsDlg->SetSpamTimerLight(true);        
+#endif
 
     // Blink file playback status line
 
@@ -1369,6 +1218,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
 //-------------------------------------------------------------------------
 void MainFrame::OnCloseFrame(wxCloseEvent& event)
 {
+    fprintf(stderr, "MainFrame::OnCloseFrame()\n");
     Pa_Terminate();
     Destroy();
 }
@@ -1530,7 +1380,9 @@ void MainFrame::togglePTT(void) {
         // rx-> tx transition, swap to Mic In page to monitor speech
         wxGetApp().m_rxNbookCtrl = m_auiNbookCtrl->GetSelection();
         m_auiNbookCtrl->ChangeSelection(m_auiNbookCtrl->GetPageIndex((wxWindow *)m_panelSpeechIn));
+#ifdef __UDP_EXPERIMENTAL__
         char e[80]; sprintf(e,"ptt"); processTxtEvent(e);
+#endif
     }
 
     g_tx = m_btnTogPTT->GetValue();
@@ -1539,41 +1391,18 @@ void MainFrame::togglePTT(void) {
 
     if (wxGetApp().m_boolHamlibUseForPTT) {        
         Hamlib *hamlib = wxGetApp().m_hamlib; 
+        wxString hamlibError;
         if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
-            hamlib->ptt(g_tx);
+            if (hamlib->ptt(g_tx, hamlibError) == false) {
+                wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            }
         }
     }
 
     // Serial PTT
 
-    /*  Truth table:
-
-          g_tx   RTSPos   RTS
-          -------------------
-          0      1        0
-          1      1        1
-          0      0        1
-          1      0        0
-
-          exclusive NOR
-    */
-
-    if(wxGetApp().m_boolUseSerialPTT && (com_handle != COM_HANDLE_INVALID)) {
-        if (wxGetApp().m_boolUseRTS) {
-            //fprintf(stderr, "g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos);
-            if (g_tx == wxGetApp().m_boolRTSPos)
-                raiseRTS();
-            else
-                lowerRTS();
-        }
-        if (wxGetApp().m_boolUseDTR) {
-            //fprintf(stderr, "g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos);
-            if (g_tx == wxGetApp().m_boolDTRPos)
-                raiseDTR();
-            else
-                lowerDTR();
-        }
+    if (wxGetApp().m_boolUseSerialPTT && (wxGetApp().m_serialport->isopen())) {
+        wxGetApp().m_serialport->ptt(g_tx);
     }
 
     // reset level gauge
@@ -1808,9 +1637,11 @@ void MainFrame::OnCallSignReset(wxCommandEvent& event)
     wxString s;
     s.Printf("%s", m_callsign);
     m_txtCtrlCallSign->SetValue(s);
+#ifdef __UDP__EXPERIMENTAL__
     m_checksumGood = m_checksumBad = 0;
     m_txtChecksumGood->SetLabel(_("0"));
     m_txtChecksumBad->SetLabel(_("0"));
+#endif
 }
 
 void MainFrame::OnBerReset(wxCommandEvent& event)
@@ -2146,6 +1977,7 @@ void MainFrame::OnRecFileFromRadio(wxCommandEvent& event)
 //-------------------------------------------------------------------------
 void MainFrame::OnExit(wxCommandEvent& event)
 {
+    fprintf(stderr, "MainFrame::OnExit\n");
     wxUnusedVar(event);
 #ifdef _USE_TIMER
     m_plotTimer.Stop();
@@ -2244,21 +2076,7 @@ void MainFrame::OnToolsComCfg(wxCommandEvent& event)
 
     ComPortsDlg *dlg = new ComPortsDlg(NULL);
 
-    int rv = dlg->ShowModal();
-
-    // test Hamlib/Serial set up
-
-    if(rv == wxID_OK)
-    {
-        if (wxGetApp().m_boolHamlibUseForPTT) {
-            OpenHamlibRig();
-            wxGetApp().m_hamlib->close();
-        }
-        if (wxGetApp().m_boolUseSerialPTT) {
-            SetupSerialPort();
-            CloseSerialPort();
-        }
-    }
+    dlg->ShowModal();
 
     delete dlg;
 }
@@ -2338,7 +2156,7 @@ bool MainFrame::OpenHamlibRig() {
     wxString port = wxGetApp().m_strHamlibSerialPort;
     bool status = wxGetApp().m_hamlib->connect(rig, port.mb_str(wxConvUTF8));
     if (status == false)
-        wxMessageBox("Couldn't connect to Radio with hamlib", wxT("About"), wxOK | wxICON_ERROR, this);
+        wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
  
     return status;
 } 
@@ -2459,12 +2277,14 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
 
         m_pcallsign = m_callsign;
         memset(m_callsign, 0, sizeof(m_callsign));
+#ifdef __UDP_EXPERIMENTAL__
         m_checksumGood = m_checksumBad = 0;
         wxString s;
         s.Printf("%d", m_checksumGood);
         m_txtChecksumGood->SetLabel(s);              
         s.Printf("%d", m_checksumBad);
         m_txtChecksumBad->SetLabel(s);        
+#endif
 
         m_maxLevel = 0;
         m_textLevel->SetLabel(wxT(""));
@@ -2478,7 +2298,7 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
         if (wxGetApp().m_boolHamlibUseForPTT)
             OpenHamlibRig();
         if (wxGetApp().m_boolUseSerialPTT) {
-            SetupSerialPort();
+            OpenSerialPort();
         }
 
         // attempt to start sound cards and tx/rx processing
@@ -2491,7 +2311,9 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
             m_plotTimer.Start(_REFRESH_TIMER_PERIOD, wxTIMER_CONTINUOUS);
 #endif // _USE_TIMER
         }
+#ifdef __UDP_EXPERIMENTAL__
         char e[80]; sprintf(e,"start"); processTxtEvent(e);
+#endif
     }
 
     // Stop was pressed or start up failed
@@ -2502,7 +2324,9 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
         // Stop Running -------------------------------------------------
         //
 
+#ifdef __UDP_EXPERIMENTAL__
         optionsDlg->SetSpamTimerLight(false);
+#endif
 
 #ifdef _USE_TIMER
         m_plotTimer.Stop();
@@ -2512,14 +2336,18 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
 
         if (wxGetApp().m_boolHamlibUseForPTT) {
             Hamlib *hamlib = wxGetApp().m_hamlib; 
+            wxString hamlibError;
             if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
-                hamlib->ptt(false);
+                if (hamlib->ptt(false, hamlibError) == false) {
+                    wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+                }
                 hamlib->close();
             }
         }
 
-        if (wxGetApp().m_boolUseSerialPTT)
+        if (wxGetApp().m_boolUseSerialPTT) {
             CloseSerialPort();
+        }
 
         m_btnTogPTT->SetValue(false);
         VoiceKeyerProcessEvent(VK_SPACE_BAR);
@@ -2564,7 +2392,9 @@ void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
         m_rb1400->Enable();
         m_rb2000->Enable();
 #endif
+#ifdef __UDP_EXPERIMENTAL__
         char e[80]; sprintf(e,"stop"); processTxtEvent(e);
+#endif
     }
 }
 
@@ -2577,10 +2407,10 @@ void MainFrame::stopRxStream()
     {
         m_RxRunning = false;
 
-        fprintf(g_logfile, "waiting for thread to stop");
+        fprintf(stderr, "waiting for thread to stop\n");
         m_txRxThread->m_run = 0;
         m_txRxThread->Wait();
-        fprintf(g_logfile, "thread stopped");
+        fprintf(stderr, "thread stopped\n");
 
         m_rxInPa->stop();
         m_rxInPa->streamClose();
@@ -3897,55 +3727,48 @@ void fdmdv2_clickTune(float freq) {
 }
 
 //----------------------------------------------------------------
-// SetupSerialPort()
+// OpenSerialPort()
 //----------------------------------------------------------------
-void MainFrame::SetupSerialPort(void)
+
+void MainFrame::OpenSerialPort(void)
 {
-    if(!wxGetApp().m_strRigCtrlPort.IsEmpty())
-    {
-        if(openComPort(wxGetApp().m_strRigCtrlPort.c_str()))
-        {
+    Serialport *serialport = wxGetApp().m_serialport;
+
+    if(!wxGetApp().m_strRigCtrlPort.IsEmpty()) {
+       serialport->openport(wxGetApp().m_strRigCtrlPort.c_str(), 
+                            wxGetApp().m_boolUseRTS, 
+                            wxGetApp().m_boolRTSPos, 
+                            wxGetApp().m_boolUseDTR,
+                            wxGetApp().m_boolDTRPos);
+       if (serialport->isopen()) {
             // always start PTT in Rx state
-            SerialPTTRx();
-        }
-        else
-        {
-            wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this);
-        }
+           serialport->ptt(false);
+       }
+       else {
+           wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this);
+       }
     }
 }
 
-void MainFrame::SerialPTTRx(void)
-{
-    printf("m_boolUseRTS: %d m_boolRTSPos: %d m_boolUseDTR: %d m_boolDTRPos: %d\n",
-           wxGetApp().m_boolUseRTS, wxGetApp().m_boolRTSPos, wxGetApp().m_boolUseDTR, wxGetApp().m_boolDTRPos);
-
-        if(wxGetApp().m_boolRTSPos) // RTS cleared LOW
-            lowerRTS();
-        else                        // RTS cleared HIGH
-            raiseRTS();
-
-        if(wxGetApp().m_boolDTRPos) // DTR cleared LOW
-            lowerDTR();
-        else                        // DTR cleared HIGH
-            raiseDTR();
-}
 
 //----------------------------------------------------------------
 // CloseSerialPort()
 //----------------------------------------------------------------
+
 void MainFrame::CloseSerialPort(void)
 {
-    if (com_handle != COM_HANDLE_INVALID) {
+    Serialport *serialport = wxGetApp().m_serialport;
+    if (serialport->isopen()) {
         // always end with PTT in rx state
 
-        SerialPTTRx();
-
-               closeComPort();
+        serialport->ptt(false);
+        serialport->closeport();
     }
 }
 
 
+#ifdef __UDP_SUPPORT__
+
 //----------------------------------------------------------------
 // PollUDP() - see if any commands on UDP port
 //----------------------------------------------------------------
@@ -4016,7 +3839,7 @@ int MainFrame::PollUDP(void)
 }
 
 void MainFrame::startUDPThread(void) {
-    printf("starting UDP thread!\n");
+    fprintf(stderr, "starting UDP thread!\n");
     m_UDPThread = new UDPThread;
     m_UDPThread->mf = this;
     if (m_UDPThread->Create() != wxTHREAD_NO_ERROR ) {
@@ -4058,6 +3881,7 @@ void *UDPThread::Entry() {
     return NULL;
 }
 
+#endif
 
 char my_get_next_tx_char(void *callback_state) {
     short ch = 0;
index 43f4d0ffff9a328e369a2916ed636deae88c75ba..e07406925e12ac17d609303fd2cf891e4db60cd2 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <wx/tglbtn.h>
 #include <wx/app.h>
-//#include <wx/aboutdlg.h>
 #include "wx/rawbmp.h"
 #include "wx/file.h"
 #include "wx/filename.h"
@@ -53,7 +52,6 @@
 
 #include <samplerate.h>
 
-#include <hamlib.h> 
 #include <stdint.h>
 #include <speex/speex_preprocess.h>
 
@@ -87,6 +85,8 @@
 #include "sox_biquad.h"
 #include "comp_prim.h"
 #include "dlg_plugin.h"
+#include "hamlib.h"
+#include "serialport.h" 
 
 #define _USE_TIMER              1
 #define _USE_ONIDLE             1
@@ -106,13 +106,6 @@ enum {
 #define EXCHANGE_DATA_IN    0
 #define EXCHANGE_DATA_OUT   1
 
-#ifdef _WIN32
-#define COM_HANDLE_INVALID                     INVALID_HANDLE_VALUE
-typedef HANDLE      com_handle_t;
-#else
-#define COM_HANDLE_INVALID                     -1
-typedef int         com_handle_t;
-#endif
 
 extern int                 g_nSoundCards;
 extern int                 g_soundCard1InDeviceNum;
@@ -184,6 +177,7 @@ class MainApp : public wxApp
         bool                m_boolHamlibUseForPTT;
         unsigned int        m_intHamlibRig;
         wxString            m_strHamlibSerialPort;
+        unsigned int        m_intHamlibSerialRate;
         Hamlib              *m_hamlib;
 
         bool                m_boolUseSerialPTT;
@@ -192,6 +186,7 @@ class MainApp : public wxApp
         bool                m_boolRTSPos;
         bool                m_boolUseDTR;
         bool                m_boolDTRPos;
+        Serialport         *m_serialport;
 
         // Play/Rec files
 
@@ -295,7 +290,29 @@ class MainApp : public wxApp
         int        FilterEvent(wxEvent& event);
         MainFrame *frame;
 
+        // 700 options
+
         bool       m_FreeDV700txClip;
+        bool       m_FreeDV700Combine;
+
+        // Noise simulation
+
+        int        m_noise_snr;
+
+        // carrier attenuation
+
+        bool       m_attn_carrier_en;
+        int        m_attn_carrier;
+
+        // tone interferer simulation
+
+        bool       m_tone;
+        int        m_tone_freq_hz;
+        int        m_tone_amplitude;
+
+        // Windows debug console
+
+        bool       m_debug_console;
     protected:
 };
 
@@ -424,7 +441,7 @@ class MainFrame : public TopFrame
         txRxThread*             m_txRxThread;
 
         bool                    OpenHamlibRig();
-        void                    SetupSerialPort(void);
+        void                    OpenSerialPort(void);
         void                    CloseSerialPort(void);
         void                    SerialPTTRx(void);
 
@@ -475,20 +492,6 @@ class MainFrame : public TopFrame
 
     protected:
 
-#ifdef _WIN32
-#define COM_HANDLE_INVALID                     INVALID_HANDLE_VALUE
-        com_handle_t  com_handle;
-#else
-#define COM_HANDLE_INVALID                     -1
-        com_handle_t  com_handle;
-#endif
-        void raiseDTR(void);
-        void lowerDTR(void);
-        void raiseRTS(void);
-        void lowerRTS(void);
-        bool openComPort(const char *port);
-        void closeComPort(void);
-
         void setsnrBeta(bool snrSlow);
 
         // protected event handlers
index 575f36a81e2bf32aaa15c951cf4e2d5288b9c746..ff80b24a253b0cdee7e112b2b94635eb87ab5913 100644 (file)
@@ -43,7 +43,7 @@ Hamlib::Hamlib() : m_rig(NULL) {
     /* Reset debug output. */
     rig_set_debug(RIG_DEBUG_VERBOSE);
 
-       m_rig = NULL;
+    m_rig = NULL;
 }
 
 Hamlib::~Hamlib() {
@@ -81,12 +81,12 @@ void Hamlib::populateComboBox(wxComboBox *cb) {
     }
 }
 
-bool Hamlib::connect(unsigned int rig_index, const char *serial_port) {
+bool Hamlib::connect(unsigned int rig_index, const char *serial_port, const int serial_rate) {
     /* Look up model from index. */
     if (rig_index >= m_rigList.size()) {
         return false;
     }
-    printf("rig: %s %s (%d)\n", m_rigList[rig_index]->mfg_name,
+    fprintf(stderr, "rig: %s %s (%d)\n", m_rigList[rig_index]->mfg_name,
             m_rigList[rig_index]->model_name, m_rigList[rig_index]->rig_model);
 
        if(m_rig) {
@@ -95,33 +95,66 @@ bool Hamlib::connect(unsigned int rig_index, const char *serial_port) {
        }
 
     /* Initialise, configure and open. */
+
     m_rig = rig_init(m_rigList[rig_index]->rig_model);
-    /* TODO: Also use baud rate from the screen. */
+
     if (!m_rig)
         return false;
-    token_t token = rig_token_lookup(m_rig, "rig_pathname");
-    if (rig_set_conf(m_rig, token, serial_port) != RIG_OK) {
-        return false;
+
+    /* TODO we may also need civaddr for Icom */
+
+    strncpy(m_rig->state.rigport.pathname, serial_port, FILPATHLEN - 1);
+    if (serial_rate) {
+        m_rig->state.rigport.parm.serial.rate = serial_rate;
     }
+    fprintf(stderr, "hamlib: setting serial rate: %d\n", m_rig->state.rigport.parm.serial.rate);
+
     if (rig_open(m_rig) == RIG_OK) {
         return true;
     }
+
     return false;
 }
 
-bool Hamlib::ptt(bool press) {
-       if(!m_rig)
-               return false;
+int Hamlib::get_serial_rate(void) {
+    return m_rig->state.rigport.parm.serial.rate;
+}
+
+int Hamlib::get_data_bits(void) {
+    return m_rig->state.rigport.parm.serial.data_bits;
+}
+
+int Hamlib::get_stop_bits(void) {
+    return m_rig->state.rigport.parm.serial.stop_bits;
+}
+
+bool Hamlib::ptt(bool press, wxString &hamlibError) {
+    fprintf(stderr,"Hamlib::ptt: %d\n", press);
+    hamlibError = "";
+
+    if(!m_rig)
+        return false;
+
     /* TODO(Joel): make ON_DATA and ON configurable. */
+
     ptt_t on = press ? RIG_PTT_ON : RIG_PTT_OFF;
+
     /* TODO(Joel): what should the VFO option be? */
-    return rig_set_ptt(m_rig, RIG_VFO_CURR, on) == RIG_OK;
+
+    int retcode = rig_set_ptt(m_rig, RIG_VFO_CURR, on);
+    fprintf(stderr,"Hamlib::ptt: rig_set_ptt returned: %d\n", retcode);
+    if (retcode != RIG_OK ) {
+        fprintf(stderr, "rig_set_ptt: error = %s \n", rigerror(retcode));
+        hamlibError = rigerror(retcode);
+    }
+
+    return retcode == RIG_OK;
 }
 
 void Hamlib::close(void) {
-       if(m_rig) {
-               rig_close(m_rig);
-               rig_cleanup(m_rig);
-               m_rig = NULL;
-       }
+    if(m_rig) {
+        rig_close(m_rig);
+        rig_cleanup(m_rig);
+        m_rig = NULL;
+    }
 }
index fe3496ff26ece41b36d31e9b479cced9a7c033f6..150ed86a52f45d8cf0cee5aa2158bd4710d305cb 100644 (file)
@@ -14,8 +14,11 @@ class Hamlib {
         ~Hamlib();
         void populateComboBox(wxComboBox *cb);
         bool connect(unsigned int rig_index, const char *serial_port);
-        bool ptt(bool press);
+        bool ptt(bool press, wxString &hamlibError);
         void close(void);
+        int get_serial_rate(void);
+        int get_data_bits(void);
+        int get_stop_bits(void);
 
         typedef std::vector<const struct rig_caps *> riglist_t;
 
diff --git a/freedv/branches/1.2/src/serialport.cpp b/freedv/branches/1.2/src/serialport.cpp
new file mode 100644 (file)
index 0000000..59dd0c9
--- /dev/null
@@ -0,0 +1,234 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "serialport.h"
+
+Serialport::Serialport() {
+    com_handle = COM_HANDLE_INVALID;
+}
+
+Serialport::~Serialport() {
+    if (isopen()) {
+        closeport();
+    }
+}
+
+// returns true if comm port opened OK, false if there was a problem
+
+bool Serialport::openport(const char name[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos)
+{
+    if (com_handle != COM_HANDLE_INVALID) {
+        closeport();
+    }
+
+    m_useRTS = useRTS;
+    m_RTSPos = RTSPos;
+    m_useDTR = useDTR;
+    m_DTRPos = DTRPos;
+
+#ifdef _WIN32
+       {
+               COMMCONFIG CC;
+               DWORD CCsize=sizeof(CC);
+               COMMTIMEOUTS timeouts;
+               DCB     dcb;
+
+               if(GetDefaultCommConfigA(name, &CC, &CCsize)) {
+                       CC.dcb.fOutxCtsFlow             = FALSE;
+                       CC.dcb.fOutxDsrFlow             = FALSE;
+                       CC.dcb.fDtrControl              = DTR_CONTROL_DISABLE;
+                       CC.dcb.fDsrSensitivity  = FALSE;
+                       CC.dcb.fRtsControl              = RTS_CONTROL_DISABLE;
+                       SetDefaultCommConfigA(name, &CC, CCsize);
+               }
+
+               if((com_handle=CreateFileA(name
+                       ,GENERIC_READ|GENERIC_WRITE     /* Access */
+                       ,0                                                              /* Share mode */
+                       ,NULL                                                   /* Security attributes */
+                       ,OPEN_EXISTING                                  /* Create access */
+                       ,FILE_ATTRIBUTE_NORMAL                  /* File attributes */
+                       ,NULL                                                   /* Template */
+                       ))==INVALID_HANDLE_VALUE)
+                       return false;
+
+               if(GetCommTimeouts(com_handle, &timeouts)) {
+                       timeouts.ReadIntervalTimeout=MAXDWORD;
+                       timeouts.ReadTotalTimeoutMultiplier=0;
+                       timeouts.ReadTotalTimeoutConstant=0;            // No-wait read timeout
+                       timeouts.WriteTotalTimeoutMultiplier=0;
+                       timeouts.WriteTotalTimeoutConstant=5000;        // 5 seconds
+                       SetCommTimeouts(com_handle,&timeouts);
+               }
+
+               /* Force N-8-1 mode: */
+               if(GetCommState(com_handle, &dcb)==TRUE) {
+                       dcb.ByteSize            = 8;
+                       dcb.Parity                      = NOPARITY;
+                       dcb.StopBits            = ONESTOPBIT;
+                       dcb.DCBlength           = sizeof(DCB);
+                       dcb.fBinary                     = TRUE;
+                       dcb.fOutxCtsFlow        = FALSE;
+                       dcb.fOutxDsrFlow        = FALSE;
+                       dcb.fDtrControl         = DTR_CONTROL_DISABLE;
+                       dcb.fDsrSensitivity     = FALSE;
+                       dcb.fTXContinueOnXoff= TRUE;
+                       dcb.fOutX                       = FALSE;
+                       dcb.fInX                        = FALSE;
+                       dcb.fRtsControl         = RTS_CONTROL_DISABLE;
+                       dcb.fAbortOnError       = FALSE;
+                       SetCommState(com_handle, &dcb);
+               }
+       }
+#else
+       {
+               struct termios t;
+
+               if((com_handle=open(name, O_NONBLOCK|O_RDWR))== COM_HANDLE_INVALID)
+                       return false;
+
+               if(tcgetattr(com_handle, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+
+               t.c_iflag = (
+                                         IGNBRK   /* ignore BREAK condition */
+                                       | IGNPAR   /* ignore (discard) parity errors */
+                                       );
+               t.c_oflag = 0;  /* No output processing */
+               t.c_cflag = (
+                                         CS8         /* 8 bits */
+                                       | CREAD       /* enable receiver */
+
+               /*
+               Fun snippet from the FreeBSD manpage:
+
+                        If CREAD is set, the receiver is enabled.  Otherwise, no character is
+                        received.  Not all hardware supports this bit.  In fact, this flag is
+                        pretty silly and if it were not part of the termios specification it
+                        would be omitted.
+               */
+                                       | CLOCAL      /* ignore modem status lines */
+                                       );
+
+               t.c_lflag = 0;  /* No local modes */
+               if(tcsetattr(com_handle, TCSANOW, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+               
+       }
+#endif
+       return true;
+}
+
+
+// fixme: this takes about one second to close under Linux
+
+void Serialport::closeport()
+{
+#ifdef _WIN32
+       CloseHandle(com_handle);
+#else
+       close(com_handle);
+#endif
+        com_handle = COM_HANDLE_INVALID;
+}
+
+//----------------------------------------------------------------
+// (raise|lower)(RTS|DTR)()
+//
+// Raises/lowers the specified signal
+//----------------------------------------------------------------
+
+void Serialport::raiseDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::raiseRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::ptt(bool tx) {
+
+   /*  Truth table:
+
+          g_tx   RTSPos   RTS
+          -------------------
+          0      1        0
+          1      1        1
+          0      0        1
+          1      0        0
+
+          exclusive NOR
+    */
+
+    if (com_handle != COM_HANDLE_INVALID) {
+        if (m_useRTS) {
+            //fprintf(stderr, "g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos);
+            if (tx == m_RTSPos)
+                raiseRTS();
+            else
+                lowerRTS();
+        }
+        if (m_useDTR) {
+            //fprintf(stderr, "g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos);
+            if (tx == m_DTRPos)
+                raiseDTR();
+            else
+                lowerDTR();
+        }
+    }
+}
diff --git a/freedv/branches/1.2/src/serialport.h b/freedv/branches/1.2/src/serialport.h
new file mode 100644 (file)
index 0000000..e5db10b
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef SERIALPORT_H
+#define SERIALPORT_H
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#endif
+
+// Serial ports called com port for historic reasons, especially on Windows machines 
+
+#ifdef _WIN32
+#define COM_HANDLE_INVALID                     INVALID_HANDLE_VALUE
+typedef HANDLE      com_handle_t;
+#else
+#define COM_HANDLE_INVALID                     -1
+typedef int         com_handle_t;
+#endif
+
+class Serialport {
+
+    public:
+        Serialport();
+        ~Serialport();
+        bool openport(const char port[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos);
+        bool isopen() {return (com_handle != COM_HANDLE_INVALID);}
+        void closeport();
+        void ptt(bool tx);
+
+    private:
+        com_handle_t  com_handle;
+        bool          m_useRTS, m_RTSPos, m_useDTR, m_DTRPos;
+
+        void raiseDTR(void);
+        void lowerDTR(void);
+        void raiseRTS(void);
+        void lowerRTS(void);
+};
+
+#endif /* SERIALPORT_H */
index 01aaac6d31aab9b9a2bdad3e7adcbc3ba7ca4093..c1044b33b75265883c57a9ad8f26a633a46a3902 100644 (file)
@@ -222,6 +222,7 @@ TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const w
     bSizer15->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
     lowerSizer->Add(bSizer15, 1, wxEXPAND, 5);
 
+#ifdef __EXPERIMENTAL_UDP__
     wxStaticBoxSizer* sbSizer_Checksum = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Checksums")), wxHORIZONTAL);
 
     wxStaticText *goodLabel = new wxStaticText(this, wxID_ANY, wxT("Good: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
@@ -235,6 +236,7 @@ TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const w
     sbSizer_Checksum->Add(m_txtChecksumBad, 0, 0, 1);
 
     lowerSizer->Add(sbSizer_Checksum, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
 
     //=====================================================
     // These are the buttons that autosend the userid (?)
@@ -316,7 +318,7 @@ TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const w
 #endif
     m_rb700b = new wxRadioButton( this, wxID_ANY, wxT("700B"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
     sbSizer_mode->Add(m_rb700b, 0, wxALIGN_LEFT|wxALL, 1);
-    m_rb700c = new wxRadioButton( this, wxID_ANY, wxT("700C"), wxDefaultPosition, wxDefaultSize, 0);
+    m_rb700c = new wxRadioButton( this, wxID_ANY, wxT("700C"), wxDefaultPosition, wxDefaultSize,  wxRB_GROUP);
     sbSizer_mode->Add(m_rb700c, 0, wxALIGN_LEFT|wxALL, 1);
     m_rb800xa = new wxRadioButton( this, wxID_ANY, wxT("800XA"), wxDefaultPosition, wxDefaultSize, 0);
     sbSizer_mode->Add(m_rb800xa, 0, wxALIGN_LEFT|wxALL, 1);
diff --git a/freedv/tags/1.2.2/.clang/.gitignore b/freedv/tags/1.2.2/.clang/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/CMakeLists.txt b/freedv/tags/1.2.2/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a9f7049
--- /dev/null
@@ -0,0 +1,463 @@
+#
+# FreeDV - HF Digital Voice for Radio Amateurs
+#
+# CMake configuration contributed by Richard Shaw (KF5OIM)
+# Please report questions, comments, problems, or patches to the freetel
+# mailing list: https://lists.sourceforge.net/lists/listinfo/freetel-codec2
+#
+
+set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7" CACHE STRING "Minimum OS X deployment version")
+
+cmake_minimum_required(VERSION 2.8)
+
+# Prevent in-source builds to protect automake/autoconf config.
+# If an in-source build is attempted, you will still need to clean up a few
+# files manually.
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
+if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+  message(FATAL_ERROR "In-source builds in ${CMAKE_BINARY_DIR} are not "   
+   "allowed, please remove ./CMakeCache.txt and ./CMakeFiles/, create a "
+   "separate build directory and run cmake from there.")
+endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+
+# Set local module path.
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+
+project(FreeDV)
+
+#
+# Set FreeDV version and generate src/version.h
+#
+set(FREEDV_VERSION_MAJOR 1)
+set(FREEDV_VERSION_MINOR 2)
+set(FREEDV_VERSION_PATCH 2)
+set(FREEDV_VERSION ${FREEDV_VERSION_MAJOR}.${FREEDV_VERSION_MINOR})
+if(FREEDV_VERSION_PATCH)
+    set(FREEDV_VERSION ${FREEDV_VERSION}.${FREEDV_VERSION_PATCH})
+endif()
+set(FREEDV_VERSION_SUFFIX FALSE)
+if(FREEDV_VERSION_SUFFIX)
+    set(FREEDV_VERSION_STRING "${FREEDV_VERSION} ${FREEDV_VERSION_SUFFIX}")
+else()
+    set(FREEDV_VERSION_STRING "${FREEDV_VERSION}")
+endif()
+message(STATUS "FreeDV version: ${FREEDV_VERSION_STRING}")
+configure_file(cmake/version.h.in src/version.h @ONLY)
+
+# Set default build type
+if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Debug")
+    message(STATUS "Build type not specified, defaulting to ${CMAKE_BUILD_TYPE}")
+endif(NOT CMAKE_BUILD_TYPE)
+
+# Work around for not using a svn working copy.
+add_definitions(-D_NO_AUTOTOOLS_)
+find_program(SVN_PATH svn)
+if(SVN_PATH)
+    execute_process(COMMAND ${SVN_PATH} info --show-item revision
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        RESULT_VARIABLE SVN_REVISION_RESULT
+        OUTPUT_VARIABLE SVN_CURRENT_REVISION
+        ERROR_QUIET
+    )
+else()
+    set(SVN_REVISION_RESULT 1)
+endif()
+
+if(SVN_REVISION_RESULT EQUAL 0)
+    string(STRIP ${SVN_CURRENT_REVISION} SVN_REVISION)
+    add_definitions(-DSVN_REVISION="${SVN_REVISION}")
+else()
+    add_definitions(-DSVN_REVISION="None")
+endif()
+
+
+# Set default build flags.
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+if(APPLE)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++11")
+endif(APPLE)
+
+#
+# Setup cmake options
+#
+set(CMAKE_VERBOSE_MAKEFILE TRUE CACHE BOOL "Verbose makefile.")
+set(USE_STATIC_DEPS FALSE CACHE BOOL 
+    "Download and build static libraries instead of system libraries.")
+set(USE_STATIC_PORTAUDIO FALSE CACHE BOOL 
+    "Download and build static portaudio instead of the system library.")
+set(USE_STATIC_SNDFILE FALSE CACHE BOOL
+    "Download and build static sndfile instead of the system library.")
+set(USE_STATIC_SAMPLERATE FALSE CACHE BOOL
+    "Download and build static samplerate instead of the system library.")
+set(USE_STATIC_CODEC2 TRUE CACHE BOOL
+    "Download and build static codec2 instead of the system library.")
+set(USE_STATIC_SPEEXDSP TRUE CACHE BOOL
+    "Download and build static speex instead of the system library.")
+set(BOOTSTRAP_WXWIDGETS FALSE CACHE BOOL
+    "Download and build static wxWidgets instead of the system library.")
+
+if(USE_STATIC_DEPS)
+    set(USE_STATIC_PORTAUDIO TRUE FORCE)
+    set(USE_STATIC_SNDFILE TRUE FORCE)
+    set(USE_STATIC_SAMPLERATE TRUE FORCE)
+    set(USE_STATIC_CODEC2 TRUE FORCE)
+endif(USE_STATIC_DEPS)
+
+#
+# Pull in external wxWidgets target if performing static build.
+#
+if(BOOTSTRAP_WXWIDGETS)
+    message(STATUS "Adding wxWidgets build target...")
+    include(cmake/BuildWxWidgets.cmake)
+endif(BOOTSTRAP_WXWIDGETS)
+
+#
+# Perform bootstrap build of wxWidgets
+#
+if(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
+    message(STATUS "Will perform bootstrap build of wxWidgets.
+   After make step completes, re-run cmake and make again to perform FreeDV build.")
+#
+# Continue normal build if not bootstrapping wxWidgets or is already built.
+#
+else(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
+
+
+#
+# Various hacks and work arounds for building under MinGW.
+#
+if(MINGW)
+    message(STATUS "System is MinGW.")
+    # Setup HOST variable.
+    include(cmake/MinGW.cmake)
+    # This sets up the exe icon for windows under mingw.
+    set(RES_FILES "")
+    set(RES_FILES "${CMAKE_SOURCE_DIR}/contrib/freedv.rc")
+    set(CMAKE_RC_COMPILER_INIT windres)
+    enable_language(RC)
+    set(CMAKE_RC_COMPILE_OBJECT
+        "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
+    include(InstallRequiredSystemLibraries)
+endif(MINGW)
+
+# Math library is automatic on MinGW
+if(UNIX)
+    set(CMAKE_REQUIRED_INCLUDES math.h)
+    set(CMAKE_REQUIRED_LIBRARIES m)
+endif(UNIX)
+
+# Find some standard headers and functions.
+include(CheckIncludeFiles)
+check_include_files("byteswap.h"   HAVE_BYTESWAP_H)
+check_include_files("limits.h"     HAVE_LIMITS_H)
+check_include_files("stddef.h"     HAVE_STDDEF_H)
+check_include_files("stdlib.h"     HAVE_STDLIB_H)
+check_include_files("string.h"     HAVE_STRING_H)
+check_include_files("strings.h"    HAVE_STRINGS_H)
+check_include_files("ltdl.h"       HAVE_LTDL_H)
+check_include_files("inttypes.h"   HAVE_INTTYPES_H)
+check_include_files("sys/stat.h"   HAVE_SYS_STAT_H)
+check_include_files("sys/types.h"  HAVE_SYS_TYPES_H)
+
+include(CheckTypeSize)
+check_type_size("int" SIZEOF_INT)
+
+include(CheckFunctionExists)
+check_function_exists(floor HAVE_FLOOR)
+check_function_exists(memset HAVE_MEMSET)
+check_function_exists(pow HAVE_POW)
+check_function_exists(sqrt HAVE_SQRT)
+check_function_exists(fseeko HAVE_FSEEKO)
+check_function_exists(fmemopen HAVE_FMEMOPEN)
+check_function_exists(strcasecmp HAVE_STRCASECMP)
+check_function_exists(vsnprintf HAVE_VSNPRINTF)
+
+include(CheckSymbolExists)
+check_symbol_exists("_fseeki64" "stdio.h" HAVE__FSEEKI64)
+
+# fdmdv2_main.h requires patching to find config.h as it current looks in the
+# source directory and the generated file goes in the binary directory.
+configure_file ("${PROJECT_SOURCE_DIR}/cmake/config.h.in"
+                "${PROJECT_BINARY_DIR}/config.h" )
+include_directories(${PROJECT_BINARY_DIR})
+add_definitions(-DHAVE_CONFIG_H)
+
+# Config file for bundled sox sources
+configure_file("${PROJECT_SOURCE_DIR}/cmake/soxconfig.h.in"
+               "${PROJECT_BINARY_DIR}/soxconfig.h")
+
+# Pthread Library
+find_package(Threads REQUIRED)
+message(STATUS "Threads library flags: ${CMAKE_THREAD_LIBS_INIT}")
+
+#
+# Find codec2
+#
+if(NOT USE_STATIC_CODEC2)
+    message(STATUS "Looking for codec2...")
+    # 'CONFIG' removed due to incompatibility with cmake version
+    # in Ubuntu 12.04 (Precise) -- Stuart Longland
+    find_package(codec2 QUIET)
+    if(codec2_FOUND)
+        get_target_property(CODEC2_LIBRARY codec2 LOCATION)
+        message(STATUS "  codec2 library: ${CODEC2_LIBRARY}")
+        message(STATUS "  codec2 headers: ${codec2_INCLUDE_DIRS}")
+    else()
+        # Try to find manually
+        find_path(CODEC2_INCLUDE_DIRS codec2.h
+                  PATH_SUFFIXES codec2)
+        find_library(CODEC2_LIBRARY NAMES codec2)
+        if(CODEC2_LIBRARY AND CODEC2_INCLUDE_DIRS)
+            message(STATUS "  codec2 library: ${CODEC2_LIBRARY}")
+            message(STATUS "  codec2 headers: ${CODEC2_INCLUDE_DIRS}")
+            list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARY})
+            include_directories(${CODEC2_INCLUDE_DIRS})
+        else()
+            message(FATAL_ERROR "codec2 library not found.
+Linux: 
+Codec2 may not be in your distribution so build yourself or use the cmake option to build statically into FreeDV.
+Windws:
+It's easiest to use the cmake option: USE_STATIC_CODEC2"
+        )
+        endif()
+    endif()
+else(NOT USE_STATIC_CODEC2)
+    message(STATUS "Will attempt static build of codec2.")
+    include(cmake/BuildCodec2.cmake)
+endif(NOT USE_STATIC_CODEC2)
+
+#
+# Find or build portaudio Library
+#
+if(NOT USE_STATIC_PORTAUDIO)
+    message(STATUS "Looking for portaudio...")
+    find_package(Portaudio REQUIRED)
+    if(PORTAUDIO_FOUND)
+        message(STATUS "  portaudio library: ${PORTAUDIO_LIBRARIES}")
+        message(STATUS "  portaudio headers: ${PORTAUDIO_INCLUDE_DIRS}")
+        list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
+        include_directories(${PORTAUDIO_INCLUDE_DIRS})
+    else()
+        message(FATAL_ERROR "portaudio library not found.
+On Linux systems try installing:
+    portaudio-devel  (RPM based systems)
+    libportaudio-dev (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_PORTAUDIO"
+        )
+    endif()
+    if(NOT ${PORTAUDIO_VERSION} EQUAL 19)
+        message(WARNING "Portaudio versions other than 19 are known to have issues. You have been warned!")
+    endif()
+else(NOT USE_STATIC_PORTAUDIO)
+    message(STATUS "Will attempt static build of portaudio.")
+    include(cmake/BuildPortaudio.cmake)
+endif(NOT USE_STATIC_PORTAUDIO)
+
+#
+# Hamlib library
+#
+message(STATUS "Looking for hamlib...")
+find_path(HAMLIB_INCLUDE_DIR hamlib/rig.h)
+find_library(HAMLIB_LIBRARY hamlib PATH_SUFFIXES hamlib)
+message(STATUS "Hamlib library: ${HAMLIB_LIBRARY}")
+message(STATUS "Hamlib headers: ${HAMLIB_INCLUDE_DIR}")
+if(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+    message(STATUS "Hamlib library found.")
+    include_directories(${HAMLIB_INCLUDE_DIR})
+    list(APPEND FREEDV_LINK_LIBS ${HAMLIB_LIBRARY})
+else(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+    message(FATAL_ERROR "hamlib not found.
+On Linux systems try installing:
+    hamlib-devel  (RPM based systems)
+    libhamlib-dev (DEB based systems)"
+    )
+endif(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+
+
+#
+# Samplerate Library
+#
+if(NOT USE_STATIC_SAMPLERATE)
+    message(STATUS "Looking for samplerate...")
+    find_library(LIBSAMPLERATE samplerate)
+    find_path(LIBSAMPLERATE_INCLUDE_DIR samplerate.h)
+    message(STATUS "  samplerate library: ${LIBSAMPLERATE}")
+    message(STATUS "  samplerate headers: ${LIBSAMPLERATE_INCLUDE_DIR}")
+    if(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        list(APPEND FREEDV_LINK_LIBS ${LIBSAMPLERATE})
+        include_directories(${LIBSAMPLERATE_INCLUDE_DIR})
+    else(LIBSTAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        message(FATAL_ERROR "samplerate library not found.
+On Linux systems try installing:
+    samplerate-devel  (RPM based systems)
+    libsamplerate-dev (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_SAMPLERATE"
+        )
+    endif(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+else(NOT USE_STATIC_SAMPLERATE)
+    message(STATUS "Will attempt static build of samplerate.")
+    include(cmake/BuildSamplerate.cmake)
+endif(NOT USE_STATIC_SAMPLERATE)
+
+#    
+# sndfile Library
+#
+if(NOT USE_STATIC_SNDFILE)
+    message(STATUS "Looking for sndfile...")
+    find_library(LIBSNDFILE sndfile)
+    find_path(LIBSNDFILE_INCLUDE_DIR sndfile.h)
+    message(STATUS "  sndfile library: ${LIBSNDFILE}")
+    message(STATUS "  sndfile headers: ${LIBSNDFILE_INCLUDE_DIR}")
+    if(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+        list(APPEND FREEDV_LINK_LIBS ${LIBSNDFILE})
+    else(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+        message(FATAL_ERROR "sndfile library not found.
+On Linux systems try installing:
+    libsndfile-devel (RPM based systems)
+    libsndfile-dev   (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_SNDFILE"
+        )
+    endif(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+else(NOT USE_STATIC_SNDFILE)
+    message(STATUS "Will attempt static build of sndfile.")
+    include(cmake/BuildSndfile.cmake)
+endif(NOT USE_STATIC_SNDFILE)
+
+#
+# Find wxWidgets
+#
+if(NOT BOOTSTRAP_WXWIDGETS)
+    set(WXCONFIG "" CACHE FILEPATH "Location of wx-config binary.")
+    set(WXRC "" CACHE FILEPATH "Location of wxrc binary.")
+endif(NOT BOOTSTRAP_WXWIDGETS)
+#if(BOOTSTRAP_WXWIDGETS)
+#    set(WXCONFIG "${CMAKE_BINARY_DIR}/external/dist/bin/wx-config")
+#    set(WXRC "${CMAKE_BINARY_DIR}/external/dist/bin/wxrc")
+#    list(APPEND FREEDV_STATIC_DEPS wxWidgets)
+#endif(BOOTSTRAP_WXWIDGETS)
+message(STATUS "Looking for wxWidgets...")
+if(WXCONFIG)
+    message(STATUS "wx-config: ${WXCONFIG}")
+    set(wxWidgets_CONFIG_EXECUTABLE ${WXCONFIG})
+endif(WXCONFIG)
+if(WXRC)
+    message(STATUS "wxrc: ${WXRC}")
+    set(wxWidgets_wxrc_EXECUTABLE ${WXRC})
+endif(WXRC)
+set(WX_VERSION_MIN 3.0.0)
+find_package(wxWidgets REQUIRED core base aui html net adv)
+execute_process(COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" --version
+    OUTPUT_VARIABLE WX_VERSION)
+string(STRIP ${WX_VERSION} WX_VERSION)
+if(WX_VERSION VERSION_EQUAL ${WX_VERSION_MIN}
+    OR WX_VERSION VERSION_GREATER ${WX_VERSION_MIN})
+   message(STATUS "wxWidgets version: ${WX_VERSION}")
+else()
+    message(FATAL_ERROR "wxWidgets must be installed on your system.
+Please check that wx-config is in path, the directory
+where wxWidgets libraries are installed (returned by
+'wx-config --libs' or 'wx-config --static --libs' command)
+is in LD_LIBRARY_PATH or equivalent variable and
+wxWidgets version is ${WX_VERSION_MIN} or above.")
+endif()
+if(wxWidgets_FOUND)
+    include("${wxWidgets_USE_FILE}")
+    list(APPEND FREEDV_LINK_LIBS ${wxWidgets_LIBRARIES})
+endif(wxWidgets_FOUND)
+
+#
+# Find speex library
+#
+if(NOT USE_STATIC_SPEEXDSP)
+    message(STATUS "Looking for Speex DSP library.")
+    find_path(SPEEXDSP_INCLUDE_DIR NAMES speex/speex.h speex/speexdsp_types.h)
+    find_library(SPEEXDSP_LIBRARY speexdsp)
+    message(STATUS "  Speex DSP headers: ${SPEEXDSP_INCLUDE_DIR}")
+    message(STATUS "  Speex DSP library: ${SPEEXDSP_LIBRARY}")
+    if(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+        include_directories(${SPEEXDSP_INCLUDE_DIR})
+        list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARY})
+    else(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+        message(FATAL_ERROR "Speex DSP library not found!")
+    endif(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+else()
+    message(STATUS "Will attempt static build of speex.")
+    include(cmake/BuildSpeex.cmake)
+endif()
+
+#
+# Find libdl for dlopen/dlclose
+#
+if(UNIX)
+    message(STATUS "Looking for dl library.")
+    find_library(DL_LIBRARY dl)
+    if(DL_LIBRARY)
+        message(STATUS "  dl library: ${DL_LIBRARY}")
+        list(APPEND FREEDV_LINK_LIBS ${DL_LIBRARY})
+    else()
+        message(FATAL_ERROR "dl library not found.
+On Linux systems try installing:
+    glibc-devel  (RPM based systems)
+    glibc-dev (DEB based systems)"
+        )
+    endif()
+endif(UNIX)
+
+    
+#Freedv 
+add_subdirectory(src)
+
+# Icons and desktop file
+add_subdirectory(contrib)
+
+message(STATUS "Build type will be: ${CMAKE_BUILD_TYPE}")
+
+#
+# Cpack NSIS configuration for Windows.
+#
+if(WIN32)
+    # Detect if we're doing a 32-bit or 64-bit windows build.
+    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+        set(CMAKE_CL_64 TRUE)
+        set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
+    endif()
+    if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+        set(CPACK_STRIP_FILES TRUE)
+    endif()
+    configure_file(cmake/GetDependencies.cmake.in cmake/GetDependencies.cmake
+        @ONLY
+    )
+    install(SCRIPT ${CMAKE_BINARY_DIR}/cmake/GetDependencies.cmake)
+    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "HF Digital Voice for Radio Amateurs")
+    set(CPACK_PACKAGE_VENDOR "CMake")
+    #set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
+    set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
+    set(CPACK_PACKAGE_VERSION_MAJOR ${FREEDV_VERSION_MAJOR})
+    set(CPACK_PACKAGE_VERSION_MINOR ${FREEDV_VERSION_MINOR})
+    # CPack expects a patch level version so set it here and override if we
+    # are actually setting one.
+    set(CPACK_PACKAGE_VERSION_PATCH 0)
+    if(FREEDV_VERSION_PATCH)
+        set(CPACK_PACKAGE_VERSION_PATCH ${FREEDV_VERSION_PATCH})
+    endif()
+    if(FREEDV_VERSION_SUFFIX)
+        set(CPACK_PACKAGE_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH}-${FREEDV_VERSION_SUFFIX}")
+    endif()
+    # There is a bug in NSI that does not handle full unix paths properly. Make
+    # sure there is at least one set of four (4) backlasshes.
+    #set(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp")
+    set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\freedv.exe")
+    set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+    set(CPACK_NSIS_PACKAGE_NAME "FreeDV")
+    set(CPACK_PACKAGE_EXECUTABLES freedv;FreeDV)
+    set(CPACK_NSIS_URL_INFO_ABOUT "http://freedv.org")
+    set(CPACK_NSIS_MODIFY_PATH OFF)
+    set(CPACK_NSIS_MENU_LINKS
+        "http://freedv.org" "FreeDV Homepage")
+    include(CPack)
+endif(WIN32)
+
+endif(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
diff --git a/freedv/tags/1.2.2/COPYING b/freedv/tags/1.2.2/COPYING
new file mode 100644 (file)
index 0000000..cfd4e99
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, see
+    <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/freedv/tags/1.2.2/README.osx b/freedv/tags/1.2.2/README.osx
new file mode 100644 (file)
index 0000000..c71544f
--- /dev/null
@@ -0,0 +1,107 @@
+Building under OSX is similar to building under linux, but there are some additional steps that need to be performed to produce a working app-bundle.
+
+For the following instructions, I'm assuming you will be placing everything in:
+/Users/<yourusername>/Dev/
+
+1/ DEPENDENCIES
+Using Macports, most of the appropriate dependencies can be installed by:
+
+$ sudo port install subversion git libtool libsamplerate sox portaudio dylibbundler cmake
+
+It should be fairly similar using HomeBrew, but you will need to replace all the /opt/ paths in the following instructions.
+
+1.1/ HAMLIB 
+First, we will need to build hamlib from source, as we need hamlib to be statically compiled (Macports won't do this..)
+
+$ git clone git://git.code.sf.net/p/hamlib/code hamlib-code
+$ cd hamlib-code
+
+You will now need to edit line 12 of autogen.sh, to change "libtoolize" to "glibtoolize"
+
+$ ./autogen.sh
+$ ./configure --disable-shared --prefix /Users/<your-username-here>/Dev/hamlib
+$ make
+$ make install
+
+You should now have an installation of hamlib in ~/Dev/hamlib
+
+Just in case you have hamlib installed via Macports, it may be a good idea to run
+$ sudo port deactivate hamlib
+
+1.2/ WXWIDGETS
+To be able to produce an appbundle, we need wxWidgets to be build statically. Again, Macports won't do this out of the box.
+
+Edit the wxWidgets-3.0 port file using:
+$ sudo port edit wxWidgets-3.0
+
+and add the following to the bottom of the file:
+
+variant static description { build a static version of the libraries with some other options... } {
+    configure.args-append       --enable-std_iostreams
+    configure.args-append       --disable-shared
+    configure.args-delete       --with-sdl
+    configure.args-delete       --with-opengl
+    set installtype release-static
+}
+
+Now you can build and install a static variant of wxWidgets with:
+$ sudo port install wxWidgets-3.0 +static
+
+Note: This will probably break anything else which is using wxWidgets. Once you have finished building FreeDV, you may
+want to go back to the dynamically compiled version using:
+$ sudo port install wxWidgets-3.0
+
+HomeBrew Users: Anyone know how to do the above?
+
+1.3/ CODEC2 LIBRARIES
+The FreeDV CMake procedure will automatically checkout and compile Codec2.
+If you want to build and install your own copy (i.e. for access to the command-line tools), you can do so:
+
+$ wget http://files.freedv.org/codec2/codec2-0.4.tar.gz
+or
+$ svn checkout https://svn.code.sf.net/p/freetel/code/codec2-dev/
+
+$ cd codec2-0.4
+or 
+cd codec2-dev
+$ mkdir build_osx && cd build_osx
+$ cmake ../ && make
+$ sudo make install
+
+3/ BUILDING FREEDV 
+Get the FreeDV source by either:
+
+Getting the current 'stable' release (1.0):
+$ wget http://files.freedv.org/freedv/freedv-1.0.tar.gz
+$ tar -xzf freedv-1.0.tar.gz
+
+or
+
+Checking the latest revision out from SVN:
+$ svn checkout https://svn.code.sf.net/p/freetel/code/freedv-dev/
+
+$ cd freedv-1.0
+or 
+$ cd freedv-dev
+
+$ mkdir build_osx && cd build_osx
+
+Assuming you are intending on building Codec2 as part of the build process, run:
+
+$ cmake -DWXCONFIG=/opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/lib/wx/config/osx_cocoa-unicode-static-3.0 -DCMAKE_EXE_LINKER_FLAGS="-L/opt/local/lib" -DHAMLIB_INCLUDE_DIR=../../hamlib/include -DHAMLIB_LIBRARY=../../hamlib/lib/libhamlib.a ../
+
+Then, build FreeDV:
+$ make
+
+The build process will create an appbundle (FreeDV.app) and a compressed disk image (FreeDV.dmg) in ./build_osx/src
+Move these to wherever you want, and run!
+
+Happy DVing!
+
+Acknowledgements:
+A big thank you to Mooneer Salem, K6AQ, for walking me through this process, and figuring out how to solve the wxWidgets and Hamlib issues.
+
+Please e-mail any corrections to either the digitalvoice google group list, or myself, at:
+vk5qi(at)rfhead.net
+Mark Jessop VK5QI
+
diff --git a/freedv/tags/1.2.2/README.txt b/freedv/tags/1.2.2/README.txt
new file mode 100644 (file)
index 0000000..26e731d
--- /dev/null
@@ -0,0 +1,233 @@
+==================================
+ FreeDV GUI README.txt
+==================================
+
+This document describes how to build the FreeDV GUI program for
+various operating systems.  See also:
+
+  http://freedv.org - introduction, documentation, downloads
+  RELEASE_NOTES.txt - changes made to each version
+  USER_MANUAL.txt   - FreeDV GUI Manual
+
+==================================
+ Building and installing on Linux
+==================================
+
+First the basics:
+
+  $ sudo apt-get install build-essential cmake subversion
+
+To install the required development libraries instead of building them
+statically:
+
+Debian/Ubuntu:
+
+  $ sudo apt-get install libwxgtk3.0-dev portaudio19-dev \
+    libhamlib-dev libsamplerate-dev libasound2-dev libao-dev libgsm1-dev \
+    libsndfile-dev
+
+Fedora:
+
+  $ sudo dnf install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
+
+
+RHEL/CentOS and derivitves (requires Fedora EPEL repository)
+
+  $ sudo yum install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
+
+
+Quickstart 1
+------------
+
+1/ Using a modern Linux, and the development library packages
+   installed above:
+
+  $ cd /path/to/freedv
+  $ mkdir build_linux
+  $ cd build_linux
+  $ cmake ../ 
+  $ make
+  $ ./src/freedv
+
+Quickstart 2
+------------
+
+Builds static versions of wxWidgets, portaudio, codec2-dev, which are commonly
+missing on older Linux systems.
+
+1/ Assumes static build of wxWidgets and the freedv-dev source is checked out into ~/freedv-dev:
+
+  $ cd ~/freedv-dev
+  $ mkdir build_linux
+  $ cd build_linux
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE ../
+  $ make
+
+2/ Then you can configure FreeDV using your local codec-dev, something like:
+
+  $ cmake -DCMAKE_BUILD_TYPE=Debug -DBOOTSTRAP_WXWIDGETS=TRUE -DCODEC2_INCLUDE_DIRS=/path/to/codec2-dev/src -DCODEC2_LIBRARY=/path/to/codec2-dev/build_linux/src/libcodec2.so -DUSE_STATIC_CODEC2=FALSE -DUSE_STATIC_PORTAUDIO=TRUE ../
+
+3/ OR build a local copy of codec2-dev:
+
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DUSE_STATIC_CODEC2=TRUE -DUSE_STATIC_PORTAUDIO=TRUE  ../
+  
+4/ Build and run FreeDV:
+
+   $ make
+   $ ./src/freedv
+
+=======================================================
+ Building for Windows on Ubuntu Linux (Cross compiling)
+=======================================================
+
+1/ Install the cross compiling toolchain:
+
+  $ sudo apt-get install mingw-w64
+
+2/ Patch cmake using: http://www.cmake.org/gitweb?p=stage/cmake.git;a=patch;h=33286235048495ceafb636d549d9a4e8891967ae
+
+3/ Checkout a fresh copy of codec2-dev and build for Windows, pointing to the generate_codebook built by a linux build of generate_codebook, using this cmake line
+
+  $ cmake .. -DCMAKE_TOOLCHAIN_FILE=/home/david/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake -DUNITTEST=FALSE -DGENERATE_CODEBOOK=/home/david/codec2-dev/build_linux/src/generate_codebook 
+
+4/ Build WxWidgets
+
+  $ cd /path/to/freedv-dev
+  $ mkdir build_windows
+  $ cd build_windows
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE .. -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DCMAKE_BUILD_TYPE=Debug
+  $ make
+
+5/ Download and install the Windows version of Hamlib:
+
+  $ wget http://internode.dl.sourceforge.net/project/hamlib/hamlib/1.2.15.3/hamlib-win32-1.2.15.3.zip
+  $ unzip hamlib-win32-1.2.15.3.zip
+
+6/ Build All the libraries and FreeDV:
+
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DUSE_STATIC_PORTAUDIO=TRUE -DUSE_STATIC_SNDFILE=TRUE -DUSE_STATIC_SAMPLERATE=TRUE -DUSE_STATIC_CODEC2=FALSE -DCODEC2_INCLUDE_DIRS=/home/david/tmp/codec2-dev/src -DCODEC2_LIBRARY=/home/david/tmp/codec2-dev/build_windows/src/libcodec2.dll.a -DHAMLIB_INCLUDE_DIR=hamlib-win32-1.2.15.3/include -DHAMLIB_LIBRARY=hamlib-win32-1.2.15.3/lib/gcc/libhamlib.dll.a -DCMAKE_BUILD_TYPE=Debug ..
+  $ make
+
+7/ Test on Linux with "wine", this will tell you if any DLLs are missing:
+
+  $ wine src/freedv.exe
+
+8/ When moving to an actual Windows machine, I needed:
+
+  /usr/lib/gcc/i686-w64-mingw32/4.8/libstdc++-6.dll
+  /usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
+  /usr/i686-w64-mingw32/lib/libwinpthread-1.dll
+
+  Wine seems to find these automagically, so I found them on my system by
+  looking at ~/.wine/system.reg for PATH:
+
+  [System\\CurrentControlSet\\Control\\Session Manager\\Environment] 1423800803
+  "PATH"=str(2):"C:\\windows\\system32;C:\\windows;C:\\windows\\system32\\wbem;Z:\\usr\\i686-w64-mingw32\\lib;Z:\\usr\\lib\\gcc\\i686-w64-mingw32\\4.8"
+
+
+====================================
+ Building and installing on Windows
+====================================
+
+The windows build is similar to linux and follows the same basic workflow,
+however, while codec2 and FreeDV (freedv) build well on windows, some of the
+dependencies do not. For that reson current windows releases are cross-compiled
+from linux.
+
+Only MinGW is supported. While it is likely possible to perform a pure MinGW
+build, installing MSYS2 will make your life easier.
+
+CMake may not automatically detect that you're in the MSYS environment. If this
+occurs you need to pass cmake the proper generator:
+
+cmake -G"MSYS Makefiles" [other options] </path/to/source>
+
+===============================
+ Bootstrapping wxWidgets build
+===============================
+
+If wxWidgets (>= 3.0) is not available then one option is to have CMake boot-
+strap the build for FreeDV.
+
+This is required because the tool wx-config is used to get the correct compiler
+and linker flags of the wxWidgets components needed by FreeDV. Since this is
+normally done at configure time, not during "make", it is not possible for CMake
+or have this information prior to building wxWidgets.
+
+In order to work around this issue you can "bootstrap" the wxWidgets build using
+the CMake option, "BOOTSTRAP_WXWIDGETS". wxWidgets will be built using static
+libraries.
+
+NOTE: This forces "USE_STATIC_WXWIDGETS" to be true internally regarless of the
+value set manually.
+
+(from any directory, but empty directory outside of the source is prefered.)
+$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE /path/to/freedv
+$ make
+(wxWidgets is downloaded and built)
+$ cmake .
+(wxWidgets build should be detected)
+$ make
+(if all goes well, as root)
+$ make install
+
+====================================
+ Building and installing on OSX
+====================================
+
+Pls see README.osx
+
+====================================
+ Building and installing on FreeBSD
+====================================
+
+As per "Quickstart 2" above but change build_linux to build_freebsd
+
+=======
+Editing
+=======
+
+Please make sure your text editor does not insert tabs, and
+used indents of 4 spaces.  The following .emacs code was used to
+configure emacs:
+
+(setq-default indent-tabs-mode nil)
+
+(add-hook 'c-mode-common-hook
+          (function (lambda ()
+                      (setq c-basic-offset 4)
+                      )))
+
+FreeDV GUI TODO List
+--------------------
+
+[ ] Ubuntu packaging
+[ ] default sound card in/out setting for rx out of the box
+[ ] When application close on windows while "Start" down sometimes crashes
+    + Also on Linux it reports an unterminated thread when exiting
+[ ] Tool-Audio Config Dialog sound device names truncated on Windows
+[ ] Serialport::closeport() on Linux takes about 1 second 
+    + delays 'Stop' on main window test on Tools-PTT Test
+[ ] Voice keyer file name at bottom on main screen truncated
+    + need a bigger field
+[ ] Start/Stop file rec/playback, work out a better UI, 
+    maybe buttons on front page
+[ ] feature for evaluating yr own sound quality
+    + trap bad mic response/levels
+    + zero in on different sound quality from different users
+[ ] feeding audio over UDP say from from gqrx
+    + could also be used to netcat stored files
+[ ] refactoring
+    [ ] fdmdv2_main.cpp is way too long
+    [ ] rename fdmdv2*.cpp -> freedv*.cpp
+    [ ] dlg_ptt uses ComPortsDlg name internally, rename PttDlg or similar
+[ ] Add RSID
+    + use case, when would it be used?
+[ ] clean up dialogs
+    + were based on auto generation code
+    + must be an easier/clearer way to write them
+
diff --git a/freedv/tags/1.2.2/RELEASE_NOTES.txt b/freedv/tags/1.2.2/RELEASE_NOTES.txt
new file mode 100644 (file)
index 0000000..79eaeca
--- /dev/null
@@ -0,0 +1,7 @@
+V1.2.2 July 2017
+----------------
+
+1/ Improvements to Hamlib support, error message reporting, serial rate box.
+
+2/ Disabled unused UDP comms/egexp processing to clean up Options dialog.
+
diff --git a/freedv/tags/1.2.2/USER_MANUAL.txt b/freedv/tags/1.2.2/USER_MANUAL.txt
new file mode 100644 (file)
index 0000000..2cc4494
--- /dev/null
@@ -0,0 +1,100 @@
+======================
+FREEDV GUI USER MANUAL
+======================
+
+Introduction
+------------
+
+This document describes additional features in the latest FreeDV
+releases that haven't been documented in other sources.  See also
+freedv.org
+
+PTT Configuration
+-----------------
+
+Tools-PTT Dialog
+
+Hamlib comes with a default serial rate for each radio.  If your radio
+has a different serial rate change the Serial Rate drop down box to
+match your radio.
+
+When "Test" is pressed, the "Serial Params" field is populated and
+displayed.  This will help track down any mis-matches between Hamlib
+and your radio.
+
+Voice Keyer
+-----------
+
+Voice Keyer Button on Front Page
+Options-PTT Dialog
+
+Puts FreeDV and your radio into transmit, reads a wave file of your
+voice to call CQ, then switches to receive to see if anyone is
+replying.  If you press space bar the voice keyer stops.  If a signal
+with a valid sync is received for a few seconds the voice keyer stops.
+
+Options-PTT dialog can be used to select the wave file, set the Rx
+delay, and number of times the tx/rx cycle repeats.
+
+The wave file for the voice keyer should be in 8kHz mono 16 bit sample
+form.  Use a free application such as Audacity to convert a file you
+have recorded to this format.
+
+Test Frame Histogram
+--------------------
+
+Test Frame Histogram tab on Front Page
+
+Displays BER of each carrier when in "test frame" mode.  As each QPSK
+carrier has 2 bits there are 2*Nc histogram points.
+
+Ideally all carriers will have about the same BER (+/- 20% after 5000
+total bit errors).  However problems can occur with filtering in the
+tx path.  If one carrier has less power, then it will have a higher
+BER.  The errors in this carrier will tend to dominate overall
+BER. For example if one carrier is attenuated due to SSB filter ripple
+in the tx path then the BER on that carrier will be higher.  This is
+bad news for DV.
+
+Suggested usage: 
+
+i) Transmit FreeDV in test frame mode.  Use a 2nd rx (or
+get a friend) to monitor your rx signal with FreeDV in test frame
+mode.  
+
+ii) Adjust your rx SNR to get a BER of a few % (e.g. reduce tx
+power, use a short antenna for the rx, point your beam away, adjust rx
+RF gain).  
+
+iii) Monitor the error histogram for a few minutes, until you
+have say 5000 total bit errors.  You have a problem if the BER of any
+carrier is more than 20% different from the rest.
+
+A typical issue will be one carrier at 1.0, the others at 0.5,
+indicating the poorer carrier BER is twice the larger.
+
+Full Duplex Testing with loopback
+---------------------------------
+
+Options - Half Duplex check box
+
+FreeDV GUI can operate in full duplex mode which is useful for
+development of listening to your own FreeDV signal as only one PC is
+required.  Normal operation is half duplex.
+
+Tx and Rx signals can be looped back via an analog connection between
+the sound cards.
+
+On Linux, using the Alsa loopback module:
+
+  $ sudo modprobe snd-aloop
+  $ ./freedv
+
+  In Tools - Audio Config - Receive Tab  - From Radio select -> Loopback: Loopback PCM (hw:1,0)
+                          - Transmit Tab - To Radio select   -> Loopback: Loopback PCM (hw:1,1)
+
+TODO
+----
+
+[ ] Merge this information into existing start up guides
+
diff --git a/freedv/tags/1.2.2/cmake/BuildCodec2.cmake b/freedv/tags/1.2.2/cmake/BuildCodec2.cmake
new file mode 100644 (file)
index 0000000..588b316
--- /dev/null
@@ -0,0 +1,25 @@
+set(SPEEXDSP_CMAKE_ARGS -DBUILD_SHARED_LIBS=FALSE -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external/dist)
+
+if(USE_STATIC_SPEEXDSP)
+    list(APPEND SPEEXDSP_CMAKE_ARGS 
+        -DSPEEXDSP_LIBRARIES=${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a
+        -DSPEEXDSP_INCLUDE_DIR=${CMAKE_BINARY_DIR}/external/dist/include)
+endif()
+
+set(CODEC2_CMAKE_ARGS -DUNITTEST=FALSE)
+
+if(CMAKE_CROSSCOMPILING)
+    set(CODEC2_CMAKE_ARGS ${CODEC2_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(codec2
+   SVN_REPOSITORY https://svn.code.sf.net/p/freetel/code/codec2-dev
+   CMAKE_ARGS ${CODEC2_CMAKE_ARGS} ${SPEEXDSP_CMAKE_ARGS}
+   INSTALL_COMMAND ""
+)
+set(CODEC2_LIBRARIES
+    ${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2-build/src/libcodec2.a)
+include_directories(${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2/src)
+list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS codec2)
diff --git a/freedv/tags/1.2.2/cmake/BuildHamlib.cmake b/freedv/tags/1.2.2/cmake/BuildHamlib.cmake
new file mode 100644 (file)
index 0000000..4166f5a
--- /dev/null
@@ -0,0 +1,20 @@
+set(HAMLIB_TARBALL "hamlib-1.2.15.3")
+
+include(ExternalProject)
+ExternalProject_Add(hamlib
+    URL http://downloads.sourceforge.net/hamlib/${HAMLIB_TARBALL}.tar.gz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(HAMLIB_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/portaudio.lib)
+else(WIN32)
+    set(HAMLIB_LIBRARIES
+    )
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${HAMLIB_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS hamlib)
diff --git a/freedv/tags/1.2.2/cmake/BuildPortaudio.cmake b/freedv/tags/1.2.2/cmake/BuildPortaudio.cmake
new file mode 100644 (file)
index 0000000..cc33d06
--- /dev/null
@@ -0,0 +1,52 @@
+set(PORTAUDIO_TARBALL "pa_stable_v19_20111121")
+
+# required linking libraries on linux. Not sure about windows.
+find_library(ALSA_LIBRARIES asound)
+
+if(UNIX AND NOT ALSA_LIBRARIES)
+    message(ERROR "Could not find alsa library which is required for portaudio.
+On Linux systems try installing:
+    alsa-lib-devel  (RPM based systems)
+    libasound2-dev  (DEB based systems)"
+    )
+endif()
+
+# Make sure that configure knows what system we're using when cross-compiling.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+else()
+    set(CONFIGURE_COMMAND ./configure --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(portaudio
+    URL http://www.portaudio.com/archives/${PORTAUDIO_TARBALL}.tgz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(PORTAUDIO_LIBRARIES 
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
+)
+else(WIN32)
+    find_library(RT rt)
+    find_library(ASOUND asound)
+    set(PORTAUDIO_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
+        ${RT}
+        ${ASOUND}
+    )
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+
+# Add the portaudio library to the list of libraries that must be linked.
+list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
+
+# Setup a dependency so that this gets built before linking to freedv.
+list(APPEND FREEDV_STATIC_DEPS portaudio)
diff --git a/freedv/tags/1.2.2/cmake/BuildSamplerate.cmake b/freedv/tags/1.2.2/cmake/BuildSamplerate.cmake
new file mode 100644 (file)
index 0000000..8b6b7a3
--- /dev/null
@@ -0,0 +1,27 @@
+set(SAMPLERATE_TARBALL "libsamplerate-0.1.8")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-sndfile --disable-fftw)
+else()
+    set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(samplerate
+    URL http://www.mega-nerd.com/SRC/${SAMPLERATE_TARBALL}.tar.gz 
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(SAMPLERATE_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
+else(WIN32)
+    set(SAMPLERATE_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SAMPLERATE_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS samplerate)
diff --git a/freedv/tags/1.2.2/cmake/BuildSndfile.cmake b/freedv/tags/1.2.2/cmake/BuildSndfile.cmake
new file mode 100644 (file)
index 0000000..c49b638
--- /dev/null
@@ -0,0 +1,26 @@
+set(SNDFILE_TARBALL "libsndfile-1.0.25")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST}  --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared --disable-sqlite)
+else()
+    set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared --disable-external-libs)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(sndfile
+    URL http://www.mega-nerd.com/libsndfile/files/${SNDFILE_TARBALL}.tar.gz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE) V=1
+    INSTALL_COMMAND $(MAKE) install
+)
+if(MINGW)
+    set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
+else()
+    set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
+endif()
+
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SNDFILE_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS sndfile)
diff --git a/freedv/tags/1.2.2/cmake/BuildSpeex.cmake b/freedv/tags/1.2.2/cmake/BuildSpeex.cmake
new file mode 100644 (file)
index 0000000..262d558
--- /dev/null
@@ -0,0 +1,26 @@
+set(SPEEXDSP_TARBALL "speexdsp-1.2rc3.tar.gz")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
+else()
+    set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(speex
+   URL http://downloads.xiph.org/releases/speex/${SPEEXDSP_TARBALL}
+   BUILD_IN_SOURCE 1
+   INSTALL_DIR external/dist
+   CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+   BUILD_COMMAND $(MAKE)
+   INSTALL_COMMAND $(MAKE) install
+)
+
+set(SPEEXDSP_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS speex)
+if(USE_STATIC_CODEC2)
+    add_dependencies(codec2 speex)
+endif()
diff --git a/freedv/tags/1.2.2/cmake/BuildWxWidgets.cmake b/freedv/tags/1.2.2/cmake/BuildWxWidgets.cmake
new file mode 100644 (file)
index 0000000..901d806
--- /dev/null
@@ -0,0 +1,43 @@
+set(WXWIDGETS_TARBALL "wxWidgets-3.0.2")
+
+# If we're cross-compiling then we need to set the target host manually.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+endif()
+
+# If not cross-compiling then use the built-in makefile, otherwise use standard configure.
+if(MINGW AND NOT CMAKE_CROSSCOMPILING)
+#    set(CONFIGURE_COMMAND "true")
+#    set(MAKE_COMMAND $(MAKE) -C build/msw -f makefile.gcc SHARED=0 UNICODE=1 BUILD=release PREFIX=${CMAKE_BINARY_DIR}/external/dist)
+    set(CONFIGURE_COMMAND ./configure --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+if(NOT MINGW)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(wxWidgets
+    URL http://downloads.sourceforge.net/wxwindows/${WXWIDGETS_TARBALL}.tar.bz2
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND ${MAKE_COMMAND}
+    INSTALL_COMMAND $(MAKE) install
+)
+
+ExternalProject_Get_Property(wxWidgets install_dir)
+message(STATUS "wxWidgets install dir: ${install_dir}")
+if(NOT WXCONFIG)
+    set(WXCONFIG "${install_dir}/bin/wx-config")
+endif()
+if(EXISTS ${WXCONFIG})
+    set(BS_WX_DONE TRUE)
+endif()
diff --git a/freedv/tags/1.2.2/cmake/FindPortaudio.cmake b/freedv/tags/1.2.2/cmake/FindPortaudio.cmake
new file mode 100644 (file)
index 0000000..158e20e
--- /dev/null
@@ -0,0 +1,107 @@
+# - Try to find Portaudio
+# Once done this will define
+#
+#  PORTAUDIO_FOUND - system has Portaudio
+#  PORTAUDIO_INCLUDE_DIRS - the Portaudio include directory
+#  PORTAUDIO_LIBRARIES - Link these to use Portaudio
+#  PORTAUDIO_DEFINITIONS - Compiler switches required for using Portaudio
+#  PORTAUDIO_VERSION - Portaudio version
+#
+#  Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
+#
+# Redistribution and use is allowed according to the terms of the New BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+  # in cache already
+  set(PORTAUDIO_FOUND TRUE)
+else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+  if (NOT WIN32)
+   include(FindPkgConfig)
+   pkg_check_modules(PORTAUDIO2 portaudio-2.0)
+  endif (NOT WIN32)
+
+  if (PORTAUDIO2_FOUND)
+    set(PORTAUDIO_INCLUDE_DIRS
+      ${PORTAUDIO2_INCLUDE_DIRS}
+    )
+    if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+      set(PORTAUDIO_LIBRARIES "${PORTAUDIO2_LIBRARY_DIRS}/lib${PORTAUDIO2_LIBRARIES}.dylib")
+    else (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+      set(PORTAUDIO_LIBRARIES
+        ${PORTAUDIO2_LIBRARIES}
+      )
+    endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    set(PORTAUDIO_VERSION
+      19
+    )
+    set(PORTAUDIO_FOUND TRUE)
+  else (PORTAUDIO2_FOUND)
+    find_path(PORTAUDIO_INCLUDE_DIR
+      NAMES
+        portaudio.h
+      PATHS
+        /usr/include
+        /usr/local/include
+        /opt/local/include
+        /sw/include
+    )
+   
+    find_library(PORTAUDIO_LIBRARY
+      NAMES
+        portaudio
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /opt/local/lib
+        /sw/lib
+    )
+   
+    find_path(PORTAUDIO_LIBRARY_DIR
+      NAMES
+        portaudio
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /opt/local/lib
+        /sw/lib
+    )
+   
+    set(PORTAUDIO_INCLUDE_DIRS
+      ${PORTAUDIO_INCLUDE_DIR}
+    )
+    set(PORTAUDIO_LIBRARIES
+      ${PORTAUDIO_LIBRARY}
+    )
+   
+    set(PORTAUDIO_LIBRARY_DIRS
+      ${PORTAUDIO_LIBRARY_DIR}
+    )
+   
+    set(PORTAUDIO_VERSION
+      18
+    )
+   
+    if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
+       set(PORTAUDIO_FOUND TRUE)
+    endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
+   
+    if (PORTAUDIO_FOUND)
+      if (NOT Portaudio_FIND_QUIETLY)
+        message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}")
+      endif (NOT Portaudio_FIND_QUIETLY)
+    else (PORTAUDIO_FOUND)
+      if (Portaudio_FIND_REQUIRED)
+        message(FATAL_ERROR "Could not find Portaudio")
+      endif (Portaudio_FIND_REQUIRED)
+    endif (PORTAUDIO_FOUND)
+  endif (PORTAUDIO2_FOUND)
+
+
+  # show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
+  mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES)
+
+endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+
diff --git a/freedv/tags/1.2.2/cmake/GetDependencies.cmake.in b/freedv/tags/1.2.2/cmake/GetDependencies.cmake.in
new file mode 100644 (file)
index 0000000..7470aa6
--- /dev/null
@@ -0,0 +1,37 @@
+# As this script is run in a new cmake instance, it does not have access to
+# the existing cache variables. Pass them in via the configure_file command.
+set(CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@)
+set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@)
+set(UNIX @UNIX@)
+set(WIN32 @WIN32@)
+set(CMAKE_CROSSCOMPILING @CMAKE_CROSSCOMPILING@)
+set(CMAKE_FIND_LIBRARY_SUFFIXES @CMAKE_FIND_LIBRARY_SUFFIXES@)
+set(CMAKE_FIND_LIBRARY_PREFIXES @CMAKE_FIND_LIBRARY_PREFIXES@)
+set(CMAKE_SYSTEM_LIBRARY_PATH @CMAKE_SYSTEM_LIBRARY_PATH@)
+set(CMAKE_FIND_ROOT_PATH @CMAKE_FIND_ROOT_PATH@)
+
+set(FREEDV_EXE ${CMAKE_BINARY_DIR}/src/freedv.exe)
+
+include(GetPrerequisites)
+get_prerequisites("${FREEDV_EXE}" _deps 1 0 "" "")
+foreach(_runtime ${_deps})
+    message("Looking for ${_runtime}")
+    find_library(RUNTIME_${_runtime} ${_runtime})
+    message("${RUNTIME_${_runtime}}")
+    if(RUNTIME_${_runtime})
+        message("Looking for dependencies of ${_runtime}")
+        get_prerequisites("${RUNTIME_${_runtime}}" _deps2 1 0 "" "")
+        foreach(_runtime2 ${_deps2})
+            find_library(RUNTIME_${_runtime2} ${_runtime2})
+            message("${RUNTIME_${_runtime2}}")
+            if(RUNTIME_${_runtime2})
+                file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
+                TYPE EXECUTABLE FILES "${RUNTIME_${_runtime2}}")
+            endif()
+        endforeach()
+    endif()
+    if(RUNTIME_${_runtime})
+        file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
+        TYPE EXECUTABLE FILES "${RUNTIME_${_runtime}}")
+    endif()
+endforeach()
diff --git a/freedv/tags/1.2.2/cmake/MinGW.cmake b/freedv/tags/1.2.2/cmake/MinGW.cmake
new file mode 100644 (file)
index 0000000..333c1dc
--- /dev/null
@@ -0,0 +1,8 @@
+# If we're cross-compiling then we need to set the target host manually.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+        set(HOST x86_64-w64-mingw32)
+    else()
+        set(HOST i686-w64-mingw32)
+    endif()
+endif()
diff --git a/freedv/tags/1.2.2/cmake/Toolchain-Ubuntu-mingw32.cmake b/freedv/tags/1.2.2/cmake/Toolchain-Ubuntu-mingw32.cmake
new file mode 100644 (file)
index 0000000..3507d72
--- /dev/null
@@ -0,0 +1,25 @@
+# Sample toolchain file for building for Windows from an Ubuntu Linux system.
+#
+# Typical usage:
+#    *) install cross compiler: `sudo apt-get install mingw-w64 g++-mingw-w64`
+#    *) cd build
+#    *) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-mingw32.cmake ..
+
+set(CMAKE_SYSTEM_NAME Windows)
+set(TOOLCHAIN_PREFIX i686-w64-mingw32)
+
+# cross compilers to use for C and C++
+set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
+set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
+
+# target environment on the build host system
+#   set 1st to dir with the cross compiler's C/C++ headers/libs
+set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
+
+# modify default behavior of FIND_XXX() commands to
+# search for headers/libs in the target environment and
+# search for programs in the build host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/freedv/tags/1.2.2/cmake/config.h.in b/freedv/tags/1.2.2/cmake/config.h.in
new file mode 100644 (file)
index 0000000..8e3ab76
--- /dev/null
@@ -0,0 +1,19 @@
+/*--------------------------------------------------------------------------
+ ** This file is autogenerated from config.h.in 
+ ** during the cmake configuration of your project. If you need to make changes
+ ** edit the original file NOT THIS FILE.
+ ** --------------------------------------------------------------------------*/
+#ifndef _CONFIGURATION_HEADER_GUARD_H_
+#define _CONFIGURATION_HEADER_GUARD_H_
+
+#define SIZEOF_INT @SIZEOF_INT@
+#cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@
+#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
+#cmakedefine HAVE_STDDEF_H @HAVE_STDDEF_H@
+#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@
+#cmakedefine HAVE_STRING_H @HAVE_STRING_H@
+#cmakedefine HAVE_FLOOR @HAVE_FLOOR@
+#cmakedefine HAVE_MEMSET @HAVE_MEMSET@
+#cmakedefine HAVE_POW @HAVE_POW@
+#cmakedefine HAVE_SQRT @HAVE_SQRT@
+#endif
diff --git a/freedv/tags/1.2.2/cmake/soxconfig.h.in b/freedv/tags/1.2.2/cmake/soxconfig.h.in
new file mode 100644 (file)
index 0000000..fb38608
--- /dev/null
@@ -0,0 +1,16 @@
+#define PACKAGE_VERSION "14.4.2"
+
+#cmakedefine HAVE_BYTESWAP_H          1
+#cmakedefine HAVE_FMEMOPEN            1
+#cmakedefine HAVE_FSEEKO              1
+#cmakedefine HAVE__FSEEKOI64          1
+#cmakedefine HAVE_LTDL_H              1
+#cmakedefine HAVE_MAGIC               1
+#cmakedefine HAVE_POPEN               1
+#cmakedefine HAVE_STDINT_H            1
+#cmakedefine HAVE_INTTYPES_H          1
+#cmakedefine HAVE_STRCASECMP          1
+#cmakedefine HAVE_STRINGS_H           1
+#cmakedefine HAVE_SYS_STAT_H          1
+#cmakedefine HAVE_SYS_TYPES_H         1
+#cmakedefine HAVE_VSNPRINTF           1
diff --git a/freedv/tags/1.2.2/cmake/version.h.in b/freedv/tags/1.2.2/cmake/version.h.in
new file mode 100644 (file)
index 0000000..43b3b7a
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef FREEDV_VER_DOT_H
+#define FREEDV_VER_DOT_H 1
+
+#define FREEDV_VERSION_MAJOR @FREEDV_VERSION_MAJOR@
+#define FREEDV_VERSION_MINOR @FREEDV_VERSION_MINOR@
+#define FREEDV_VERSION_PATCH @FREEDV_VERSION_PATCH@
+#define FREEDV_VERSION_SUFFIX "@FREEDV_VERSION_SUFFIX@"
+
+#define FREEDV_VERSION "@FREEDV_VERSION_STRING@"
+
+#endif //FREEDV_VER_DOT_H
diff --git a/freedv/tags/1.2.2/contrib/CMakeLists.txt b/freedv/tags/1.2.2/contrib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3f4b7e0
--- /dev/null
@@ -0,0 +1,22 @@
+# Install icons if we're on most *nix systems.
+if(UNIX AND NOT APPLE)
+    set(ICON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor
+        CACHE PATH "Prefix to use for installing icons.")
+    install(FILES freedv48x48.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/48x48/apps
+        RENAME freedv.png)
+    install(FILES freedv64x64.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/64x64/apps
+        RENAME freedv.png)
+    install(FILES freedv128x128.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/128x128/apps
+        RENAME freedv.png)
+    install(FILES freedv256x256.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/256x256/apps
+        RENAME freedv.png)
+
+    set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications
+        CACHE PATH "Location to install desktop files.")
+    install(FILES freedv.desktop
+        DESTINATION ${DESKTOP_INSTALL_DIR})
+endif(UNIX AND NOT APPLE)
diff --git a/freedv/tags/1.2.2/contrib/LICENSE b/freedv/tags/1.2.2/contrib/LICENSE
new file mode 100644 (file)
index 0000000..dc8853a
--- /dev/null
@@ -0,0 +1,393 @@
+Attribution 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+     Considerations for licensors: Our public licenses are
+     intended for use by those authorized to give the public
+     permission to use material in ways otherwise restricted by
+     copyright and certain other rights. Our licenses are
+     irrevocable. Licensors should read and understand the terms
+     and conditions of the license they choose before applying it.
+     Licensors should also secure all rights necessary before
+     applying our licenses so that the public can reuse the
+     material as expected. Licensors should clearly mark any
+     material not subject to the license. This includes other CC-
+     licensed material, or material used under an exception or
+     limitation to copyright. More considerations for licensors:
+       wiki.creativecommons.org/Considerations_for_licensors
+
+     Considerations for the public: By using one of our public
+     licenses, a licensor grants the public permission to use the
+     licensed material under specified terms and conditions. If
+     the licensor's permission is not necessary for any reason--for
+     example, because of any applicable exception or limitation to
+     copyright--then that use is not regulated by the license. Our
+     licenses grant only permissions under copyright and certain
+     other rights that a licensor has authority to grant. Use of
+     the licensed material may still be restricted for other
+     reasons, including because others have copyright or other
+     rights in the material. A licensor may make special requests,
+     such as asking that all changes be marked or described.
+     Although not required by our licenses, you are encouraged to
+     respect those requests where reasonable. More_considerations
+     for the public: 
+       wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution 4.0 International Public License ("Public License"). To the
+extent this Public License may be interpreted as a contract, You are
+granted the Licensed Rights in consideration of Your acceptance of
+these terms and conditions, and the Licensor grants You such rights in
+consideration of benefits the Licensor receives from making the
+Licensed Material available under these terms and conditions.
+
+
+Section 1 -- Definitions.
+
+  a. Adapted Material means material subject to Copyright and Similar
+     Rights that is derived from or based upon the Licensed Material
+     and in which the Licensed Material is translated, altered,
+     arranged, transformed, or otherwise modified in a manner requiring
+     permission under the Copyright and Similar Rights held by the
+     Licensor. For purposes of this Public License, where the Licensed
+     Material is a musical work, performance, or sound recording,
+     Adapted Material is always produced where the Licensed Material is
+     synched in timed relation with a moving image.
+
+  b. Adapter's License means the license You apply to Your Copyright
+     and Similar Rights in Your contributions to Adapted Material in
+     accordance with the terms and conditions of this Public License.
+
+  c. Copyright and Similar Rights means copyright and/or similar rights
+     closely related to copyright including, without limitation,
+     performance, broadcast, sound recording, and Sui Generis Database
+     Rights, without regard to how the rights are labeled or
+     categorized. For purposes of this Public License, the rights
+     specified in Section 2(b)(1)-(2) are not Copyright and Similar
+     Rights.
+
+  d. Effective Technological Measures means those measures that, in the
+     absence of proper authority, may not be circumvented under laws
+     fulfilling obligations under Article 11 of the WIPO Copyright
+     Treaty adopted on December 20, 1996, and/or similar international
+     agreements.
+
+  e. Exceptions and Limitations means fair use, fair dealing, and/or
+     any other exception or limitation to Copyright and Similar Rights
+     that applies to Your use of the Licensed Material.
+
+  f. Licensed Material means the artistic or literary work, database,
+     or other material to which the Licensor applied this Public
+     License.
+
+  g. Licensed Rights means the rights granted to You subject to the
+     terms and conditions of this Public License, which are limited to
+     all Copyright and Similar Rights that apply to Your use of the
+     Licensed Material and that the Licensor has authority to license.
+
+  h. Licensor means the individual(s) or entity(ies) granting rights
+     under this Public License.
+
+  i. Share means to provide material to the public by any means or
+     process that requires permission under the Licensed Rights, such
+     as reproduction, public display, public performance, distribution,
+     dissemination, communication, or importation, and to make material
+     available to the public including in ways that members of the
+     public may access the material from a place and at a time
+     individually chosen by them.
+
+  j. Sui Generis Database Rights means rights other than copyright
+     resulting from Directive 96/9/EC of the European Parliament and of
+     the Council of 11 March 1996 on the legal protection of databases,
+     as amended and/or succeeded, as well as other essentially
+     equivalent rights anywhere in the world.
+
+  k. You means the individual or entity exercising the Licensed Rights
+     under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+  a. License grant.
+
+       1. Subject to the terms and conditions of this Public License,
+          the Licensor hereby grants You a worldwide, royalty-free,
+          non-sublicensable, non-exclusive, irrevocable license to
+          exercise the Licensed Rights in the Licensed Material to:
+
+            a. reproduce and Share the Licensed Material, in whole or
+               in part; and
+
+            b. produce, reproduce, and Share Adapted Material.
+
+       2. Exceptions and Limitations. For the avoidance of doubt, where
+          Exceptions and Limitations apply to Your use, this Public
+          License does not apply, and You do not need to comply with
+          its terms and conditions.
+
+       3. Term. The term of this Public License is specified in Section
+          6(a).
+
+       4. Media and formats; technical modifications allowed. The
+          Licensor authorizes You to exercise the Licensed Rights in
+          all media and formats whether now known or hereafter created,
+          and to make technical modifications necessary to do so. The
+          Licensor waives and/or agrees not to assert any right or
+          authority to forbid You from making technical modifications
+          necessary to exercise the Licensed Rights, including
+          technical modifications necessary to circumvent Effective
+          Technological Measures. For purposes of this Public License,
+          simply making modifications authorized by this Section 2(a)
+          (4) never produces Adapted Material.
+
+       5. Downstream recipients.
+
+            a. Offer from the Licensor -- Licensed Material. Every
+               recipient of the Licensed Material automatically
+               receives an offer from the Licensor to exercise the
+               Licensed Rights under the terms and conditions of this
+               Public License.
+
+            b. No downstream restrictions. You may not offer or impose
+               any additional or different terms or conditions on, or
+               apply any Effective Technological Measures to, the
+               Licensed Material if doing so restricts exercise of the
+               Licensed Rights by any recipient of the Licensed
+               Material.
+
+       6. No endorsement. Nothing in this Public License constitutes or
+          may be construed as permission to assert or imply that You
+          are, or that Your use of the Licensed Material is, connected
+          with, or sponsored, endorsed, or granted official status by,
+          the Licensor or others designated to receive attribution as
+          provided in Section 3(a)(1)(A)(i).
+
+  b. Other rights.
+
+       1. Moral rights, such as the right of integrity, are not
+          licensed under this Public License, nor are publicity,
+          privacy, and/or other similar personality rights; however, to
+          the extent possible, the Licensor waives and/or agrees not to
+          assert any such rights held by the Licensor to the limited
+          extent necessary to allow You to exercise the Licensed
+          Rights, but not otherwise.
+
+       2. Patent and trademark rights are not licensed under this
+          Public License.
+
+       3. To the extent possible, the Licensor waives any right to
+          collect royalties from You for the exercise of the Licensed
+          Rights, whether directly or through a collecting society
+          under any voluntary or waivable statutory or compulsory
+          licensing scheme. In all other cases the Licensor expressly
+          reserves any right to collect such royalties.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+  a. Attribution.
+
+       1. If You Share the Licensed Material (including in modified
+          form), You must:
+
+            a. retain the following if it is supplied by the Licensor
+               with the Licensed Material:
+
+                 i. identification of the creator(s) of the Licensed
+                    Material and any others designated to receive
+                    attribution, in any reasonable manner requested by
+                    the Licensor (including by pseudonym if
+                    designated);
+
+                ii. a copyright notice;
+
+               iii. a notice that refers to this Public License;
+
+                iv. a notice that refers to the disclaimer of
+                    warranties;
+
+                 v. a URI or hyperlink to the Licensed Material to the
+                    extent reasonably practicable;
+
+            b. indicate if You modified the Licensed Material and
+               retain an indication of any previous modifications; and
+
+            c. indicate the Licensed Material is licensed under this
+               Public License, and include the text of, or the URI or
+               hyperlink to, this Public License.
+
+       2. You may satisfy the conditions in Section 3(a)(1) in any
+          reasonable manner based on the medium, means, and context in
+          which You Share the Licensed Material. For example, it may be
+          reasonable to satisfy the conditions by providing a URI or
+          hyperlink to a resource that includes the required
+          information.
+
+       3. If requested by the Licensor, You must remove any of the
+          information required by Section 3(a)(1)(A) to the extent
+          reasonably practicable.
+
+       4. If You Share Adapted Material You produce, the Adapter's
+          License You apply must not prevent recipients of the Adapted
+          Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+     to extract, reuse, reproduce, and Share all or a substantial
+     portion of the contents of the database;
+
+  b. if You include all or a substantial portion of the database
+     contents in a database in which You have Sui Generis Database
+     Rights, then the database in which You have Sui Generis Database
+     Rights (but not its individual contents) is Adapted Material; and
+
+  c. You must comply with the conditions in Section 3(a) if You Share
+     all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+  c. The disclaimer of warranties and limitation of liability provided
+     above shall be interpreted in a manner that, to the extent
+     possible, most closely approximates an absolute disclaimer and
+     waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+  a. This Public License applies for the term of the Copyright and
+     Similar Rights licensed here. However, if You fail to comply with
+     this Public License, then Your rights under this Public License
+     terminate automatically.
+
+  b. Where Your right to use the Licensed Material has terminated under
+     Section 6(a), it reinstates:
+
+       1. automatically as of the date the violation is cured, provided
+          it is cured within 30 days of Your discovery of the
+          violation; or
+
+       2. upon express reinstatement by the Licensor.
+
+     For the avoidance of doubt, this Section 6(b) does not affect any
+     right the Licensor may have to seek remedies for Your violations
+     of this Public License.
+
+  c. For the avoidance of doubt, the Licensor may also offer the
+     Licensed Material under separate terms or conditions or stop
+     distributing the Licensed Material at any time; however, doing so
+     will not terminate this Public License.
+
+  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+     License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+  a. The Licensor shall not be bound by any additional or different
+     terms or conditions communicated by You unless expressly agreed.
+
+  b. Any arrangements, understandings, or agreements regarding the
+     Licensed Material not stated herein are separate from and
+     independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+  a. For the avoidance of doubt, this Public License does not, and
+     shall not be interpreted to, reduce, limit, restrict, or impose
+     conditions on any use of the Licensed Material that could lawfully
+     be made without permission under this Public License.
+
+  b. To the extent possible, if any provision of this Public License is
+     deemed unenforceable, it shall be automatically reformed to the
+     minimum extent necessary to make it enforceable. If the provision
+     cannot be reformed, it shall be severed from this Public License
+     without affecting the enforceability of the remaining terms and
+     conditions.
+
+  c. No term or condition of this Public License will be waived and no
+     failure to comply consented to unless expressly agreed to by the
+     Licensor.
+
+  d. Nothing in this Public License constitutes or may be interpreted
+     as a limitation upon, or waiver of, any privileges and immunities
+     that apply to the Licensor or You, including from the legal
+     processes of any jurisdiction or authority.
+
+
+=======================================================================
+
+Creative Commons is not a party to its public licenses.
+Notwithstanding, Creative Commons may elect to apply one of its public
+licenses to material it publishes and in those instances will be
+considered the "Licensor." Except for the limited purpose of indicating
+that material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the public
+licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/freedv/tags/1.2.2/contrib/freedv.desktop b/freedv/tags/1.2.2/contrib/freedv.desktop
new file mode 100644 (file)
index 0000000..96e8293
--- /dev/null
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Version=1.0
+Name=FreeDV
+Exec=freedv
+Icon=freedv
+Type=Application
+Terminal=false
+Categories=GTK;GNOME;AudioVideo;Audio;HamRadio;
diff --git a/freedv/tags/1.2.2/contrib/freedv.ico b/freedv/tags/1.2.2/contrib/freedv.ico
new file mode 100644 (file)
index 0000000..e6b9a20
Binary files /dev/null and b/freedv/tags/1.2.2/contrib/freedv.ico differ
diff --git a/freedv/tags/1.2.2/contrib/freedv.rc b/freedv/tags/1.2.2/contrib/freedv.rc
new file mode 100644 (file)
index 0000000..2e6655d
--- /dev/null
@@ -0,0 +1 @@
+id ICON "./freedv.ico"
diff --git a/freedv/tags/1.2.2/contrib/freedv128x128.png b/freedv/tags/1.2.2/contrib/freedv128x128.png
new file mode 100644 (file)
index 0000000..5190a77
Binary files /dev/null and b/freedv/tags/1.2.2/contrib/freedv128x128.png differ
diff --git a/freedv/tags/1.2.2/contrib/freedv256x256.png b/freedv/tags/1.2.2/contrib/freedv256x256.png
new file mode 100644 (file)
index 0000000..b3eb5d7
Binary files /dev/null and b/freedv/tags/1.2.2/contrib/freedv256x256.png differ
diff --git a/freedv/tags/1.2.2/contrib/freedv48x48.png b/freedv/tags/1.2.2/contrib/freedv48x48.png
new file mode 100644 (file)
index 0000000..bd5efc6
Binary files /dev/null and b/freedv/tags/1.2.2/contrib/freedv48x48.png differ
diff --git a/freedv/tags/1.2.2/contrib/freedv64x64.png b/freedv/tags/1.2.2/contrib/freedv64x64.png
new file mode 100644 (file)
index 0000000..eb89773
Binary files /dev/null and b/freedv/tags/1.2.2/contrib/freedv64x64.png differ
diff --git a/freedv/tags/1.2.2/contrib/freedv_screenshot.png b/freedv/tags/1.2.2/contrib/freedv_screenshot.png
new file mode 100644 (file)
index 0000000..f93e3c5
Binary files /dev/null and b/freedv/tags/1.2.2/contrib/freedv_screenshot.png differ
diff --git a/freedv/tags/1.2.2/credits.txt b/freedv/tags/1.2.2/credits.txt
new file mode 100644 (file)
index 0000000..431e399
--- /dev/null
@@ -0,0 +1,13 @@
+Credits (code or ideas borrowed from):
+==============================================
+Dave Witten and David Rowe (obviously)
+Mel Whitten K0PFX (material and moral support)
+Bruce Perens (cheerleader, promotion and publicity)
+Mooneer Salem KG6AOV(Mac OSX Patch)
+Soeren Straarup OZ2DAK (FreeBSD Port)
+Don Mak
+Steve Nance (K5FR)
+Joel Stanley (Hamlib prototyping) and Mark Jessop (Mac OSX) 
+James Ahlstrom (Quisk)
+FLDIGI
+All the folks on the digital voice google group...
diff --git a/freedv/tags/1.2.2/db/current b/freedv/tags/1.2.2/db/current
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/freedv/tags/1.2.2/db/format b/freedv/tags/1.2.2/db/format
new file mode 100644 (file)
index 0000000..db06890
--- /dev/null
@@ -0,0 +1,2 @@
+4
+layout sharded 1000
diff --git a/freedv/tags/1.2.2/db/fs-type b/freedv/tags/1.2.2/db/fs-type
new file mode 100644 (file)
index 0000000..4fdd953
--- /dev/null
@@ -0,0 +1 @@
+fsfs
diff --git a/freedv/tags/1.2.2/db/fsfs.conf b/freedv/tags/1.2.2/db/fsfs.conf
new file mode 100644 (file)
index 0000000..cc08ceb
--- /dev/null
@@ -0,0 +1,38 @@
+### This file controls the configuration of the FSFS filesystem.\r
+\r
+[memcached-servers]\r
+### These options name memcached servers used to cache internal FSFS\r
+### data.  See http://www.danga.com/memcached/ for more information on\r
+### memcached.  To use memcached with FSFS, run one or more memcached\r
+### servers, and specify each of them as an option like so:\r
+# first-server = 127.0.0.1:11211\r
+# remote-memcached = mymemcached.corp.example.com:11212\r
+### The option name is ignored; the value is of the form HOST:PORT.\r
+### memcached servers can be shared between multiple repositories;\r
+### however, if you do this, you *must* ensure that repositories have\r
+### distinct UUIDs and paths, or else cached data from one repository\r
+### might be used by another accidentally.  Note also that memcached has\r
+### no authentication for reads or writes, so you must ensure that your\r
+### memcached servers are only accessible by trusted users.\r
+\r
+[caches]\r
+### When a cache-related error occurs, normally Subversion ignores it\r
+### and continues, logging an error if the server is appropriately\r
+### configured (and ignoring it with file:// access).  To make\r
+### Subversion never ignore cache errors, uncomment this line.\r
+# fail-stop = true\r
+\r
+[rep-sharing]\r
+### To conserve space, the filesystem can optionally avoid storing\r
+### duplicate representations.  This comes at a slight cost in\r
+### performance, as maintaining a database of shared representations can\r
+### increase commit times.  The space savings are dependent upon the size\r
+### of the repository, the number of objects it contains and the amount of\r
+### duplication between them, usually a function of the branching and\r
+### merging process.\r
+###\r
+### The following parameter enables rep-sharing in the repository.  It can\r
+### be switched on and off at will, but for best space-saving results\r
+### should be enabled consistently over the life of the repository.\r
+### rep-sharing is enabled by default.\r
+# enable-rep-sharing = true\r
diff --git a/freedv/tags/1.2.2/db/min-unpacked-rev b/freedv/tags/1.2.2/db/min-unpacked-rev
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/freedv/tags/1.2.2/db/rep-cache.db b/freedv/tags/1.2.2/db/rep-cache.db
new file mode 100644 (file)
index 0000000..63c6f0b
Binary files /dev/null and b/freedv/tags/1.2.2/db/rep-cache.db differ
diff --git a/freedv/tags/1.2.2/db/revprops/0/0 b/freedv/tags/1.2.2/db/revprops/0/0
new file mode 100644 (file)
index 0000000..d0b90de
--- /dev/null
@@ -0,0 +1,5 @@
+K 8
+svn:date
+V 27
+2012-08-21T18:27:59.389906Z
+END
diff --git a/freedv/tags/1.2.2/db/revprops/0/1 b/freedv/tags/1.2.2/db/revprops/0/1
new file mode 100644 (file)
index 0000000..0af71a2
--- /dev/null
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 9
+OFA-Staff
+K 8
+svn:date
+V 27
+2012-08-21T18:28:08.741468Z
+K 7
+svn:log
+V 25
+Imported folder structure
+END
diff --git a/freedv/tags/1.2.2/db/revs/0/0 b/freedv/tags/1.2.2/db/revs/0/0
new file mode 100644 (file)
index 0000000..10f5c45
--- /dev/null
@@ -0,0 +1,11 @@
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
diff --git a/freedv/tags/1.2.2/db/revs/0/1 b/freedv/tags/1.2.2/db/revs/0/1
new file mode 100644 (file)
index 0000000..fd802a9
--- /dev/null
@@ -0,0 +1,49 @@
+id: 3-1.0.r1/0
+type: dir
+count: 0
+cpath: /tags
+copyroot: 0 /
+
+id: 0-1.0.r1/62
+type: dir
+count: 0
+cpath: /trunk
+copyroot: 0 /
+
+id: 2-1.0.r1/126
+type: dir
+count: 0
+cpath: /branches
+copyroot: 0 /
+
+PLAIN
+K 8
+branches
+V 16
+dir 2-1.0.r1/126
+K 4
+tags
+V 14
+dir 3-1.0.r1/0
+K 5
+trunk
+V 15
+dir 0-1.0.r1/62
+END
+ENDREP
+id: 0.0.r1/306
+type: dir
+pred: 0.0.r0/17
+count: 1
+text: 1 194 99 99 7b6cc14dddba4e09be5255b475d1a0a8
+cpath: /
+copyroot: 0 /
+
+_0.0.t0-0 add-dir false false /trunk
+
+_2.0.t0-0 add-dir false false /branches
+
+_3.0.t0-0 add-dir false false /tags
+
+
+306 431
diff --git a/freedv/tags/1.2.2/db/transactions/.gitignore b/freedv/tags/1.2.2/db/transactions/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/db/txn-current b/freedv/tags/1.2.2/db/txn-current
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/freedv/tags/1.2.2/db/txn-current-lock b/freedv/tags/1.2.2/db/txn-current-lock
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/db/txn-protorevs/.gitignore b/freedv/tags/1.2.2/db/txn-protorevs/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/db/uuid b/freedv/tags/1.2.2/db/uuid
new file mode 100644 (file)
index 0000000..0f36297
--- /dev/null
@@ -0,0 +1 @@
+a56d66ce-6468-4744-9be7-52ce95ca47a4
diff --git a/freedv/tags/1.2.2/db/write-lock b/freedv/tags/1.2.2/db/write-lock
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/debian/changelog b/freedv/tags/1.2.2/debian/changelog
new file mode 100644 (file)
index 0000000..ddfe80b
--- /dev/null
@@ -0,0 +1,5 @@
+freedv (1.0-150830) unstable; urgency=low
+
+  * Subversion snapshot of tag 1.0.
+
+ -- Stuart Longland <stuartl@longlandclan.yi.org>  Sun, 30 Aug 2015 09:01:13 +1000
diff --git a/freedv/tags/1.2.2/debian/compat b/freedv/tags/1.2.2/debian/compat
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/freedv/tags/1.2.2/debian/control b/freedv/tags/1.2.2/debian/control
new file mode 100644 (file)
index 0000000..d1472b2
--- /dev/null
@@ -0,0 +1,19 @@
+Source: fdmdv2
+Section: main
+Priority: optional
+Maintainer: Stuart Longland <stuartl@longlandclan.yi.org>
+Build-Depends: debhelper (>= 9), cmake, libcodec2-dev, libgtk2.0-dev,
+ libhamlib-dev, libsamplerate-dev, libasound2-dev, libao-dev, libgsm1-dev,
+ portaudio19-dev, libsox-dev, libsndfile1-dev, libwxgtk3.0-dev
+Standards-Version: 3.9.5
+Homepage: http://www.freedv.org
+#Vcs-Git: git://anonscm.debian.org/collab-maint/freedv.git
+#Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/freedv.git;a=summary
+
+Package: freedv
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libcodec2
+Description: FreeDV: Open-Source Digital Voice modem
+ FreeDV is a digital voice modem that can transmit voice-quality
+ audio digitally over HF radio links in as little as 1.25kHz
+ bandwidth in varying conditions.
diff --git a/freedv/tags/1.2.2/debian/copyright b/freedv/tags/1.2.2/debian/copyright
new file mode 100644 (file)
index 0000000..b55a293
--- /dev/null
@@ -0,0 +1,38 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: freedv
+Source: <url://example.com>
+
+Files: *
+Copyright: <years> <put author's name and email here>
+           <years> <likewise for another author>
+License: <special license>
+ <Put the license of the package here indented by 1 space>
+ <This follows the format of Description: lines in control file>
+ .
+ <Including paragraphs>
+
+# If you want to use GPL v2 or later for the /debian/* files use 
+# the following clauses, or change it to suit. Delete these two lines
+Files: debian/*
+Copyright: 2015 unknown <stuartl@unknown>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid to pick license terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/freedv/tags/1.2.2/debian/docs b/freedv/tags/1.2.2/debian/docs
new file mode 100644 (file)
index 0000000..acfbcb3
--- /dev/null
@@ -0,0 +1,3 @@
+credits.txt
+README.txt
+README.txt
diff --git a/freedv/tags/1.2.2/debian/format b/freedv/tags/1.2.2/debian/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/freedv/tags/1.2.2/debian/rules b/freedv/tags/1.2.2/debian/rules
new file mode 100755 (executable)
index 0000000..ad89215
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/make -f
+# See debhelper(7) (uncomment to enable)
+# output every command that modifies files on the build system.
+#DH_VERBOSE = 1
+
+# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/default.mk
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
+# package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+
+# main packaging script based on dh7 syntax
+%:
+       dh $@ 
+
+# debmake generated override targets
+# This is example for Cmake (See http://bugs.debian.org/641051 )
+override_dh_auto_configure:
+       dh_auto_configure -- \
+              -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \
+              -DUSE_STATIC_CODEC2=FALSE \
+              -DUSE_STATIC_SPEEXDSP=FALSE
diff --git a/freedv/tags/1.2.2/freedv-dev/.clang/.gitignore b/freedv/tags/1.2.2/freedv-dev/.clang/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/freedv-dev/CMakeLists.txt b/freedv/tags/1.2.2/freedv-dev/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fdc1c01
--- /dev/null
@@ -0,0 +1,463 @@
+#
+# FreeDV - HF Digital Voice for Radio Amateurs
+#
+# CMake configuration contributed by Richard Shaw (KF5OIM)
+# Please report questions, comments, problems, or patches to the freetel
+# mailing list: https://lists.sourceforge.net/lists/listinfo/freetel-codec2
+#
+
+set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7" CACHE STRING "Minimum OS X deployment version")
+
+cmake_minimum_required(VERSION 2.8)
+
+# Prevent in-source builds to protect automake/autoconf config.
+# If an in-source build is attempted, you will still need to clean up a few
+# files manually.
+set(CMAKE_DISABLE_SOURCE_CHANGES ON)
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
+if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+  message(FATAL_ERROR "In-source builds in ${CMAKE_BINARY_DIR} are not "   
+   "allowed, please remove ./CMakeCache.txt and ./CMakeFiles/, create a "
+   "separate build directory and run cmake from there.")
+endif("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
+
+# Set local module path.
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+
+project(FreeDV)
+
+#
+# Set FreeDV version and generate src/version.h
+#
+set(FREEDV_VERSION_MAJOR 1)
+set(FREEDV_VERSION_MINOR 2)
+set(FREEDV_VERSION_PATCH 2)
+set(FREEDV_VERSION ${FREEDV_VERSION_MAJOR}.${FREEDV_VERSION_MINOR})
+if(FREEDV_VERSION_PATCH)
+    set(FREEDV_VERSION ${FREEDV_VERSION}.${FREEDV_VERSION_PATCH})
+endif()
+set(FREEDV_VERSION_SUFFIX "devel")
+if(FREEDV_VERSION_SUFFIX)
+    set(FREEDV_VERSION_STRING "${FREEDV_VERSION} ${FREEDV_VERSION_SUFFIX}")
+else()
+    set(FREEDV_VERSION_STRING "${FREEDV_VERSION}")
+endif()
+message(STATUS "FreeDV version: ${FREEDV_VERSION_STRING}")
+configure_file(cmake/version.h.in src/version.h @ONLY)
+
+# Set default build type
+if(NOT CMAKE_BUILD_TYPE)
+    set(CMAKE_BUILD_TYPE "Debug")
+    message(STATUS "Build type not specified, defaulting to ${CMAKE_BUILD_TYPE}")
+endif(NOT CMAKE_BUILD_TYPE)
+
+# Work around for not using a svn working copy.
+add_definitions(-D_NO_AUTOTOOLS_)
+find_program(SVN_PATH svn)
+if(SVN_PATH)
+    execute_process(COMMAND ${SVN_PATH} info --show-item revision
+        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+        RESULT_VARIABLE SVN_REVISION_RESULT
+        OUTPUT_VARIABLE SVN_CURRENT_REVISION
+        ERROR_QUIET
+    )
+else()
+    set(SVN_REVISION_RESULT 1)
+endif()
+
+if(SVN_REVISION_RESULT EQUAL 0)
+    string(STRIP ${SVN_CURRENT_REVISION} SVN_REVISION)
+    add_definitions(-DSVN_REVISION="${SVN_REVISION}")
+else()
+    add_definitions(-DSVN_REVISION="None")
+endif()
+
+
+# Set default build flags.
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+if(APPLE)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++11")
+endif(APPLE)
+
+#
+# Setup cmake options
+#
+set(CMAKE_VERBOSE_MAKEFILE TRUE CACHE BOOL "Verbose makefile.")
+set(USE_STATIC_DEPS FALSE CACHE BOOL 
+    "Download and build static libraries instead of system libraries.")
+set(USE_STATIC_PORTAUDIO FALSE CACHE BOOL 
+    "Download and build static portaudio instead of the system library.")
+set(USE_STATIC_SNDFILE FALSE CACHE BOOL
+    "Download and build static sndfile instead of the system library.")
+set(USE_STATIC_SAMPLERATE FALSE CACHE BOOL
+    "Download and build static samplerate instead of the system library.")
+set(USE_STATIC_CODEC2 TRUE CACHE BOOL
+    "Download and build static codec2 instead of the system library.")
+set(USE_STATIC_SPEEXDSP TRUE CACHE BOOL
+    "Download and build static speex instead of the system library.")
+set(BOOTSTRAP_WXWIDGETS FALSE CACHE BOOL
+    "Download and build static wxWidgets instead of the system library.")
+
+if(USE_STATIC_DEPS)
+    set(USE_STATIC_PORTAUDIO TRUE FORCE)
+    set(USE_STATIC_SNDFILE TRUE FORCE)
+    set(USE_STATIC_SAMPLERATE TRUE FORCE)
+    set(USE_STATIC_CODEC2 TRUE FORCE)
+endif(USE_STATIC_DEPS)
+
+#
+# Pull in external wxWidgets target if performing static build.
+#
+if(BOOTSTRAP_WXWIDGETS)
+    message(STATUS "Adding wxWidgets build target...")
+    include(cmake/BuildWxWidgets.cmake)
+endif(BOOTSTRAP_WXWIDGETS)
+
+#
+# Perform bootstrap build of wxWidgets
+#
+if(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
+    message(STATUS "Will perform bootstrap build of wxWidgets.
+   After make step completes, re-run cmake and make again to perform FreeDV build.")
+#
+# Continue normal build if not bootstrapping wxWidgets or is already built.
+#
+else(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
+
+
+#
+# Various hacks and work arounds for building under MinGW.
+#
+if(MINGW)
+    message(STATUS "System is MinGW.")
+    # Setup HOST variable.
+    include(cmake/MinGW.cmake)
+    # This sets up the exe icon for windows under mingw.
+    set(RES_FILES "")
+    set(RES_FILES "${CMAKE_SOURCE_DIR}/contrib/freedv.rc")
+    set(CMAKE_RC_COMPILER_INIT windres)
+    enable_language(RC)
+    set(CMAKE_RC_COMPILE_OBJECT
+        "<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
+    include(InstallRequiredSystemLibraries)
+endif(MINGW)
+
+# Math library is automatic on MinGW
+if(UNIX)
+    set(CMAKE_REQUIRED_INCLUDES math.h)
+    set(CMAKE_REQUIRED_LIBRARIES m)
+endif(UNIX)
+
+# Find some standard headers and functions.
+include(CheckIncludeFiles)
+check_include_files("byteswap.h"   HAVE_BYTESWAP_H)
+check_include_files("limits.h"     HAVE_LIMITS_H)
+check_include_files("stddef.h"     HAVE_STDDEF_H)
+check_include_files("stdlib.h"     HAVE_STDLIB_H)
+check_include_files("string.h"     HAVE_STRING_H)
+check_include_files("strings.h"    HAVE_STRINGS_H)
+check_include_files("ltdl.h"       HAVE_LTDL_H)
+check_include_files("inttypes.h"   HAVE_INTTYPES_H)
+check_include_files("sys/stat.h"   HAVE_SYS_STAT_H)
+check_include_files("sys/types.h"  HAVE_SYS_TYPES_H)
+
+include(CheckTypeSize)
+check_type_size("int" SIZEOF_INT)
+
+include(CheckFunctionExists)
+check_function_exists(floor HAVE_FLOOR)
+check_function_exists(memset HAVE_MEMSET)
+check_function_exists(pow HAVE_POW)
+check_function_exists(sqrt HAVE_SQRT)
+check_function_exists(fseeko HAVE_FSEEKO)
+check_function_exists(fmemopen HAVE_FMEMOPEN)
+check_function_exists(strcasecmp HAVE_STRCASECMP)
+check_function_exists(vsnprintf HAVE_VSNPRINTF)
+
+include(CheckSymbolExists)
+check_symbol_exists("_fseeki64" "stdio.h" HAVE__FSEEKI64)
+
+# fdmdv2_main.h requires patching to find config.h as it current looks in the
+# source directory and the generated file goes in the binary directory.
+configure_file ("${PROJECT_SOURCE_DIR}/cmake/config.h.in"
+                "${PROJECT_BINARY_DIR}/config.h" )
+include_directories(${PROJECT_BINARY_DIR})
+add_definitions(-DHAVE_CONFIG_H)
+
+# Config file for bundled sox sources
+configure_file("${PROJECT_SOURCE_DIR}/cmake/soxconfig.h.in"
+               "${PROJECT_BINARY_DIR}/soxconfig.h")
+
+# Pthread Library
+find_package(Threads REQUIRED)
+message(STATUS "Threads library flags: ${CMAKE_THREAD_LIBS_INIT}")
+
+#
+# Find codec2
+#
+if(NOT USE_STATIC_CODEC2)
+    message(STATUS "Looking for codec2...")
+    # 'CONFIG' removed due to incompatibility with cmake version
+    # in Ubuntu 12.04 (Precise) -- Stuart Longland
+    find_package(codec2 QUIET)
+    if(codec2_FOUND)
+        get_target_property(CODEC2_LIBRARY codec2 LOCATION)
+        message(STATUS "  codec2 library: ${CODEC2_LIBRARY}")
+        message(STATUS "  codec2 headers: ${codec2_INCLUDE_DIRS}")
+    else()
+        # Try to find manually
+        find_path(CODEC2_INCLUDE_DIRS codec2.h
+                  PATH_SUFFIXES codec2)
+        find_library(CODEC2_LIBRARY NAMES codec2)
+        if(CODEC2_LIBRARY AND CODEC2_INCLUDE_DIRS)
+            message(STATUS "  codec2 library: ${CODEC2_LIBRARY}")
+            message(STATUS "  codec2 headers: ${CODEC2_INCLUDE_DIRS}")
+            list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARY})
+            include_directories(${CODEC2_INCLUDE_DIRS})
+        else()
+            message(FATAL_ERROR "codec2 library not found.
+Linux: 
+Codec2 may not be in your distribution so build yourself or use the cmake option to build statically into FreeDV.
+Windws:
+It's easiest to use the cmake option: USE_STATIC_CODEC2"
+        )
+        endif()
+    endif()
+else(NOT USE_STATIC_CODEC2)
+    message(STATUS "Will attempt static build of codec2.")
+    include(cmake/BuildCodec2.cmake)
+endif(NOT USE_STATIC_CODEC2)
+
+#
+# Find or build portaudio Library
+#
+if(NOT USE_STATIC_PORTAUDIO)
+    message(STATUS "Looking for portaudio...")
+    find_package(Portaudio REQUIRED)
+    if(PORTAUDIO_FOUND)
+        message(STATUS "  portaudio library: ${PORTAUDIO_LIBRARIES}")
+        message(STATUS "  portaudio headers: ${PORTAUDIO_INCLUDE_DIRS}")
+        list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
+        include_directories(${PORTAUDIO_INCLUDE_DIRS})
+    else()
+        message(FATAL_ERROR "portaudio library not found.
+On Linux systems try installing:
+    portaudio-devel  (RPM based systems)
+    libportaudio-dev (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_PORTAUDIO"
+        )
+    endif()
+    if(NOT ${PORTAUDIO_VERSION} EQUAL 19)
+        message(WARNING "Portaudio versions other than 19 are known to have issues. You have been warned!")
+    endif()
+else(NOT USE_STATIC_PORTAUDIO)
+    message(STATUS "Will attempt static build of portaudio.")
+    include(cmake/BuildPortaudio.cmake)
+endif(NOT USE_STATIC_PORTAUDIO)
+
+#
+# Hamlib library
+#
+message(STATUS "Looking for hamlib...")
+find_path(HAMLIB_INCLUDE_DIR hamlib/rig.h)
+find_library(HAMLIB_LIBRARY hamlib PATH_SUFFIXES hamlib)
+message(STATUS "Hamlib library: ${HAMLIB_LIBRARY}")
+message(STATUS "Hamlib headers: ${HAMLIB_INCLUDE_DIR}")
+if(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+    message(STATUS "Hamlib library found.")
+    include_directories(${HAMLIB_INCLUDE_DIR})
+    list(APPEND FREEDV_LINK_LIBS ${HAMLIB_LIBRARY})
+else(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+    message(FATAL_ERROR "hamlib not found.
+On Linux systems try installing:
+    hamlib-devel  (RPM based systems)
+    libhamlib-dev (DEB based systems)"
+    )
+endif(HAMLIB_LIBRARY AND HAMLIB_INCLUDE_DIR)
+
+
+#
+# Samplerate Library
+#
+if(NOT USE_STATIC_SAMPLERATE)
+    message(STATUS "Looking for samplerate...")
+    find_library(LIBSAMPLERATE samplerate)
+    find_path(LIBSAMPLERATE_INCLUDE_DIR samplerate.h)
+    message(STATUS "  samplerate library: ${LIBSAMPLERATE}")
+    message(STATUS "  samplerate headers: ${LIBSAMPLERATE_INCLUDE_DIR}")
+    if(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        list(APPEND FREEDV_LINK_LIBS ${LIBSAMPLERATE})
+        include_directories(${LIBSAMPLERATE_INCLUDE_DIR})
+    else(LIBSTAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+        message(FATAL_ERROR "samplerate library not found.
+On Linux systems try installing:
+    samplerate-devel  (RPM based systems)
+    libsamplerate-dev (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_SAMPLERATE"
+        )
+    endif(LIBSAMPLERATE AND LIBSAMPLERATE_INCLUDE_DIR)
+else(NOT USE_STATIC_SAMPLERATE)
+    message(STATUS "Will attempt static build of samplerate.")
+    include(cmake/BuildSamplerate.cmake)
+endif(NOT USE_STATIC_SAMPLERATE)
+
+#    
+# sndfile Library
+#
+if(NOT USE_STATIC_SNDFILE)
+    message(STATUS "Looking for sndfile...")
+    find_library(LIBSNDFILE sndfile)
+    find_path(LIBSNDFILE_INCLUDE_DIR sndfile.h)
+    message(STATUS "  sndfile library: ${LIBSNDFILE}")
+    message(STATUS "  sndfile headers: ${LIBSNDFILE_INCLUDE_DIR}")
+    if(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+        list(APPEND FREEDV_LINK_LIBS ${LIBSNDFILE})
+    else(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+        message(FATAL_ERROR "sndfile library not found.
+On Linux systems try installing:
+    libsndfile-devel (RPM based systems)
+    libsndfile-dev   (DEB based systems)
+On Windows it's easiest to use the cmake option: USE_STATIC_SNDFILE"
+        )
+    endif(LIBSNDFILE AND LIBSNDFILE_INCLUDE_DIR)
+else(NOT USE_STATIC_SNDFILE)
+    message(STATUS "Will attempt static build of sndfile.")
+    include(cmake/BuildSndfile.cmake)
+endif(NOT USE_STATIC_SNDFILE)
+
+#
+# Find wxWidgets
+#
+if(NOT BOOTSTRAP_WXWIDGETS)
+    set(WXCONFIG "" CACHE FILEPATH "Location of wx-config binary.")
+    set(WXRC "" CACHE FILEPATH "Location of wxrc binary.")
+endif(NOT BOOTSTRAP_WXWIDGETS)
+#if(BOOTSTRAP_WXWIDGETS)
+#    set(WXCONFIG "${CMAKE_BINARY_DIR}/external/dist/bin/wx-config")
+#    set(WXRC "${CMAKE_BINARY_DIR}/external/dist/bin/wxrc")
+#    list(APPEND FREEDV_STATIC_DEPS wxWidgets)
+#endif(BOOTSTRAP_WXWIDGETS)
+message(STATUS "Looking for wxWidgets...")
+if(WXCONFIG)
+    message(STATUS "wx-config: ${WXCONFIG}")
+    set(wxWidgets_CONFIG_EXECUTABLE ${WXCONFIG})
+endif(WXCONFIG)
+if(WXRC)
+    message(STATUS "wxrc: ${WXRC}")
+    set(wxWidgets_wxrc_EXECUTABLE ${WXRC})
+endif(WXRC)
+set(WX_VERSION_MIN 3.0.0)
+find_package(wxWidgets REQUIRED core base aui html net adv)
+execute_process(COMMAND sh "${wxWidgets_CONFIG_EXECUTABLE}" --version
+    OUTPUT_VARIABLE WX_VERSION)
+string(STRIP ${WX_VERSION} WX_VERSION)
+if(WX_VERSION VERSION_EQUAL ${WX_VERSION_MIN}
+    OR WX_VERSION VERSION_GREATER ${WX_VERSION_MIN})
+   message(STATUS "wxWidgets version: ${WX_VERSION}")
+else()
+    message(FATAL_ERROR "wxWidgets must be installed on your system.
+Please check that wx-config is in path, the directory
+where wxWidgets libraries are installed (returned by
+'wx-config --libs' or 'wx-config --static --libs' command)
+is in LD_LIBRARY_PATH or equivalent variable and
+wxWidgets version is ${WX_VERSION_MIN} or above.")
+endif()
+if(wxWidgets_FOUND)
+    include("${wxWidgets_USE_FILE}")
+    list(APPEND FREEDV_LINK_LIBS ${wxWidgets_LIBRARIES})
+endif(wxWidgets_FOUND)
+
+#
+# Find speex library
+#
+if(NOT USE_STATIC_SPEEXDSP)
+    message(STATUS "Looking for Speex DSP library.")
+    find_path(SPEEXDSP_INCLUDE_DIR NAMES speex/speex.h speex/speexdsp_types.h)
+    find_library(SPEEXDSP_LIBRARY speexdsp)
+    message(STATUS "  Speex DSP headers: ${SPEEXDSP_INCLUDE_DIR}")
+    message(STATUS "  Speex DSP library: ${SPEEXDSP_LIBRARY}")
+    if(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+        include_directories(${SPEEXDSP_INCLUDE_DIR})
+        list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARY})
+    else(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+        message(FATAL_ERROR "Speex DSP library not found!")
+    endif(SPEEXDSP_INCLUDE_DIR AND SPEEXDSP_LIBRARY)
+else()
+    message(STATUS "Will attempt static build of speex.")
+    include(cmake/BuildSpeex.cmake)
+endif()
+
+#
+# Find libdl for dlopen/dlclose
+#
+if(UNIX)
+    message(STATUS "Looking for dl library.")
+    find_library(DL_LIBRARY dl)
+    if(DL_LIBRARY)
+        message(STATUS "  dl library: ${DL_LIBRARY}")
+        list(APPEND FREEDV_LINK_LIBS ${DL_LIBRARY})
+    else()
+        message(FATAL_ERROR "dl library not found.
+On Linux systems try installing:
+    glibc-devel  (RPM based systems)
+    glibc-dev (DEB based systems)"
+        )
+    endif()
+endif(UNIX)
+
+    
+#Freedv 
+add_subdirectory(src)
+
+# Icons and desktop file
+add_subdirectory(contrib)
+
+message(STATUS "Build type will be: ${CMAKE_BUILD_TYPE}")
+
+#
+# Cpack NSIS configuration for Windows.
+#
+if(WIN32)
+    # Detect if we're doing a 32-bit or 64-bit windows build.
+    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+        set(CMAKE_CL_64 TRUE)
+        set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
+    endif()
+    if(NOT ${CMAKE_BUILD_TYPE} STREQUAL "Debug")
+        set(CPACK_STRIP_FILES TRUE)
+    endif()
+    configure_file(cmake/GetDependencies.cmake.in cmake/GetDependencies.cmake
+        @ONLY
+    )
+    install(SCRIPT ${CMAKE_BINARY_DIR}/cmake/GetDependencies.cmake)
+    set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "HF Digital Voice for Radio Amateurs")
+    set(CPACK_PACKAGE_VENDOR "CMake")
+    #set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README")
+    set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING")
+    set(CPACK_PACKAGE_VERSION_MAJOR ${FREEDV_VERSION_MAJOR})
+    set(CPACK_PACKAGE_VERSION_MINOR ${FREEDV_VERSION_MINOR})
+    # CPack expects a patch level version so set it here and override if we
+    # are actually setting one.
+    set(CPACK_PACKAGE_VERSION_PATCH 0)
+    if(FREEDV_VERSION_PATCH)
+        set(CPACK_PACKAGE_VERSION_PATCH ${FREEDV_VERSION_PATCH})
+    endif()
+    if(FREEDV_VERSION_SUFFIX)
+        set(CPACK_PACKAGE_VERSION_PATCH "${CPACK_PACKAGE_VERSION_PATCH}-${FREEDV_VERSION_SUFFIX}")
+    endif()
+    # There is a bug in NSI that does not handle full unix paths properly. Make
+    # sure there is at least one set of four (4) backlasshes.
+    #set(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp")
+    set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\freedv.exe")
+    set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY}")
+    set(CPACK_NSIS_PACKAGE_NAME "FreeDV")
+    set(CPACK_PACKAGE_EXECUTABLES freedv;FreeDV)
+    set(CPACK_NSIS_URL_INFO_ABOUT "http://freedv.org")
+    set(CPACK_NSIS_MODIFY_PATH OFF)
+    set(CPACK_NSIS_MENU_LINKS
+        "http://freedv.org" "FreeDV Homepage")
+    include(CPack)
+endif(WIN32)
+
+endif(BOOTSTRAP_WXWIDGETS AND NOT EXISTS ${WXCONFIG})
diff --git a/freedv/tags/1.2.2/freedv-dev/COPYING b/freedv/tags/1.2.2/freedv-dev/COPYING
new file mode 100644 (file)
index 0000000..cfd4e99
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, see
+    <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/freedv/tags/1.2.2/freedv-dev/README.osx b/freedv/tags/1.2.2/freedv-dev/README.osx
new file mode 100644 (file)
index 0000000..c71544f
--- /dev/null
@@ -0,0 +1,107 @@
+Building under OSX is similar to building under linux, but there are some additional steps that need to be performed to produce a working app-bundle.
+
+For the following instructions, I'm assuming you will be placing everything in:
+/Users/<yourusername>/Dev/
+
+1/ DEPENDENCIES
+Using Macports, most of the appropriate dependencies can be installed by:
+
+$ sudo port install subversion git libtool libsamplerate sox portaudio dylibbundler cmake
+
+It should be fairly similar using HomeBrew, but you will need to replace all the /opt/ paths in the following instructions.
+
+1.1/ HAMLIB 
+First, we will need to build hamlib from source, as we need hamlib to be statically compiled (Macports won't do this..)
+
+$ git clone git://git.code.sf.net/p/hamlib/code hamlib-code
+$ cd hamlib-code
+
+You will now need to edit line 12 of autogen.sh, to change "libtoolize" to "glibtoolize"
+
+$ ./autogen.sh
+$ ./configure --disable-shared --prefix /Users/<your-username-here>/Dev/hamlib
+$ make
+$ make install
+
+You should now have an installation of hamlib in ~/Dev/hamlib
+
+Just in case you have hamlib installed via Macports, it may be a good idea to run
+$ sudo port deactivate hamlib
+
+1.2/ WXWIDGETS
+To be able to produce an appbundle, we need wxWidgets to be build statically. Again, Macports won't do this out of the box.
+
+Edit the wxWidgets-3.0 port file using:
+$ sudo port edit wxWidgets-3.0
+
+and add the following to the bottom of the file:
+
+variant static description { build a static version of the libraries with some other options... } {
+    configure.args-append       --enable-std_iostreams
+    configure.args-append       --disable-shared
+    configure.args-delete       --with-sdl
+    configure.args-delete       --with-opengl
+    set installtype release-static
+}
+
+Now you can build and install a static variant of wxWidgets with:
+$ sudo port install wxWidgets-3.0 +static
+
+Note: This will probably break anything else which is using wxWidgets. Once you have finished building FreeDV, you may
+want to go back to the dynamically compiled version using:
+$ sudo port install wxWidgets-3.0
+
+HomeBrew Users: Anyone know how to do the above?
+
+1.3/ CODEC2 LIBRARIES
+The FreeDV CMake procedure will automatically checkout and compile Codec2.
+If you want to build and install your own copy (i.e. for access to the command-line tools), you can do so:
+
+$ wget http://files.freedv.org/codec2/codec2-0.4.tar.gz
+or
+$ svn checkout https://svn.code.sf.net/p/freetel/code/codec2-dev/
+
+$ cd codec2-0.4
+or 
+cd codec2-dev
+$ mkdir build_osx && cd build_osx
+$ cmake ../ && make
+$ sudo make install
+
+3/ BUILDING FREEDV 
+Get the FreeDV source by either:
+
+Getting the current 'stable' release (1.0):
+$ wget http://files.freedv.org/freedv/freedv-1.0.tar.gz
+$ tar -xzf freedv-1.0.tar.gz
+
+or
+
+Checking the latest revision out from SVN:
+$ svn checkout https://svn.code.sf.net/p/freetel/code/freedv-dev/
+
+$ cd freedv-1.0
+or 
+$ cd freedv-dev
+
+$ mkdir build_osx && cd build_osx
+
+Assuming you are intending on building Codec2 as part of the build process, run:
+
+$ cmake -DWXCONFIG=/opt/local/Library/Frameworks/wxWidgets.framework/Versions/wxWidgets/3.0/lib/wx/config/osx_cocoa-unicode-static-3.0 -DCMAKE_EXE_LINKER_FLAGS="-L/opt/local/lib" -DHAMLIB_INCLUDE_DIR=../../hamlib/include -DHAMLIB_LIBRARY=../../hamlib/lib/libhamlib.a ../
+
+Then, build FreeDV:
+$ make
+
+The build process will create an appbundle (FreeDV.app) and a compressed disk image (FreeDV.dmg) in ./build_osx/src
+Move these to wherever you want, and run!
+
+Happy DVing!
+
+Acknowledgements:
+A big thank you to Mooneer Salem, K6AQ, for walking me through this process, and figuring out how to solve the wxWidgets and Hamlib issues.
+
+Please e-mail any corrections to either the digitalvoice google group list, or myself, at:
+vk5qi(at)rfhead.net
+Mark Jessop VK5QI
+
diff --git a/freedv/tags/1.2.2/freedv-dev/README.txt b/freedv/tags/1.2.2/freedv-dev/README.txt
new file mode 100644 (file)
index 0000000..26e731d
--- /dev/null
@@ -0,0 +1,233 @@
+==================================
+ FreeDV GUI README.txt
+==================================
+
+This document describes how to build the FreeDV GUI program for
+various operating systems.  See also:
+
+  http://freedv.org - introduction, documentation, downloads
+  RELEASE_NOTES.txt - changes made to each version
+  USER_MANUAL.txt   - FreeDV GUI Manual
+
+==================================
+ Building and installing on Linux
+==================================
+
+First the basics:
+
+  $ sudo apt-get install build-essential cmake subversion
+
+To install the required development libraries instead of building them
+statically:
+
+Debian/Ubuntu:
+
+  $ sudo apt-get install libwxgtk3.0-dev portaudio19-dev \
+    libhamlib-dev libsamplerate-dev libasound2-dev libao-dev libgsm1-dev \
+    libsndfile-dev
+
+Fedora:
+
+  $ sudo dnf install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
+
+
+RHEL/CentOS and derivitves (requires Fedora EPEL repository)
+
+  $ sudo yum install wxGTK3-devel portaudio-devel libsamplerate-devel \ 
+    libsndfile-devel speexdsp-devel hamlib-devel alsa-lib-devel libao-devel \
+    gsm-devel
+
+
+Quickstart 1
+------------
+
+1/ Using a modern Linux, and the development library packages
+   installed above:
+
+  $ cd /path/to/freedv
+  $ mkdir build_linux
+  $ cd build_linux
+  $ cmake ../ 
+  $ make
+  $ ./src/freedv
+
+Quickstart 2
+------------
+
+Builds static versions of wxWidgets, portaudio, codec2-dev, which are commonly
+missing on older Linux systems.
+
+1/ Assumes static build of wxWidgets and the freedv-dev source is checked out into ~/freedv-dev:
+
+  $ cd ~/freedv-dev
+  $ mkdir build_linux
+  $ cd build_linux
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE ../
+  $ make
+
+2/ Then you can configure FreeDV using your local codec-dev, something like:
+
+  $ cmake -DCMAKE_BUILD_TYPE=Debug -DBOOTSTRAP_WXWIDGETS=TRUE -DCODEC2_INCLUDE_DIRS=/path/to/codec2-dev/src -DCODEC2_LIBRARY=/path/to/codec2-dev/build_linux/src/libcodec2.so -DUSE_STATIC_CODEC2=FALSE -DUSE_STATIC_PORTAUDIO=TRUE ../
+
+3/ OR build a local copy of codec2-dev:
+
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DUSE_STATIC_CODEC2=TRUE -DUSE_STATIC_PORTAUDIO=TRUE  ../
+  
+4/ Build and run FreeDV:
+
+   $ make
+   $ ./src/freedv
+
+=======================================================
+ Building for Windows on Ubuntu Linux (Cross compiling)
+=======================================================
+
+1/ Install the cross compiling toolchain:
+
+  $ sudo apt-get install mingw-w64
+
+2/ Patch cmake using: http://www.cmake.org/gitweb?p=stage/cmake.git;a=patch;h=33286235048495ceafb636d549d9a4e8891967ae
+
+3/ Checkout a fresh copy of codec2-dev and build for Windows, pointing to the generate_codebook built by a linux build of generate_codebook, using this cmake line
+
+  $ cmake .. -DCMAKE_TOOLCHAIN_FILE=/home/david/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake -DUNITTEST=FALSE -DGENERATE_CODEBOOK=/home/david/codec2-dev/build_linux/src/generate_codebook 
+
+4/ Build WxWidgets
+
+  $ cd /path/to/freedv-dev
+  $ mkdir build_windows
+  $ cd build_windows
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE .. -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DCMAKE_BUILD_TYPE=Debug
+  $ make
+
+5/ Download and install the Windows version of Hamlib:
+
+  $ wget http://internode.dl.sourceforge.net/project/hamlib/hamlib/1.2.15.3/hamlib-win32-1.2.15.3.zip
+  $ unzip hamlib-win32-1.2.15.3.zip
+
+6/ Build All the libraries and FreeDV:
+
+  $ cmake -DBOOTSTRAP_WXWIDGETS=TRUE -DCMAKE_TOOLCHAIN_FILE=cmake/Toolchain-Ubuntu-mingw32.cmake -DUSE_STATIC_PORTAUDIO=TRUE -DUSE_STATIC_SNDFILE=TRUE -DUSE_STATIC_SAMPLERATE=TRUE -DUSE_STATIC_CODEC2=FALSE -DCODEC2_INCLUDE_DIRS=/home/david/tmp/codec2-dev/src -DCODEC2_LIBRARY=/home/david/tmp/codec2-dev/build_windows/src/libcodec2.dll.a -DHAMLIB_INCLUDE_DIR=hamlib-win32-1.2.15.3/include -DHAMLIB_LIBRARY=hamlib-win32-1.2.15.3/lib/gcc/libhamlib.dll.a -DCMAKE_BUILD_TYPE=Debug ..
+  $ make
+
+7/ Test on Linux with "wine", this will tell you if any DLLs are missing:
+
+  $ wine src/freedv.exe
+
+8/ When moving to an actual Windows machine, I needed:
+
+  /usr/lib/gcc/i686-w64-mingw32/4.8/libstdc++-6.dll
+  /usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll
+  /usr/i686-w64-mingw32/lib/libwinpthread-1.dll
+
+  Wine seems to find these automagically, so I found them on my system by
+  looking at ~/.wine/system.reg for PATH:
+
+  [System\\CurrentControlSet\\Control\\Session Manager\\Environment] 1423800803
+  "PATH"=str(2):"C:\\windows\\system32;C:\\windows;C:\\windows\\system32\\wbem;Z:\\usr\\i686-w64-mingw32\\lib;Z:\\usr\\lib\\gcc\\i686-w64-mingw32\\4.8"
+
+
+====================================
+ Building and installing on Windows
+====================================
+
+The windows build is similar to linux and follows the same basic workflow,
+however, while codec2 and FreeDV (freedv) build well on windows, some of the
+dependencies do not. For that reson current windows releases are cross-compiled
+from linux.
+
+Only MinGW is supported. While it is likely possible to perform a pure MinGW
+build, installing MSYS2 will make your life easier.
+
+CMake may not automatically detect that you're in the MSYS environment. If this
+occurs you need to pass cmake the proper generator:
+
+cmake -G"MSYS Makefiles" [other options] </path/to/source>
+
+===============================
+ Bootstrapping wxWidgets build
+===============================
+
+If wxWidgets (>= 3.0) is not available then one option is to have CMake boot-
+strap the build for FreeDV.
+
+This is required because the tool wx-config is used to get the correct compiler
+and linker flags of the wxWidgets components needed by FreeDV. Since this is
+normally done at configure time, not during "make", it is not possible for CMake
+or have this information prior to building wxWidgets.
+
+In order to work around this issue you can "bootstrap" the wxWidgets build using
+the CMake option, "BOOTSTRAP_WXWIDGETS". wxWidgets will be built using static
+libraries.
+
+NOTE: This forces "USE_STATIC_WXWIDGETS" to be true internally regarless of the
+value set manually.
+
+(from any directory, but empty directory outside of the source is prefered.)
+$ cmake -DBOOTSTRAP_WXWIDGETS=TRUE /path/to/freedv
+$ make
+(wxWidgets is downloaded and built)
+$ cmake .
+(wxWidgets build should be detected)
+$ make
+(if all goes well, as root)
+$ make install
+
+====================================
+ Building and installing on OSX
+====================================
+
+Pls see README.osx
+
+====================================
+ Building and installing on FreeBSD
+====================================
+
+As per "Quickstart 2" above but change build_linux to build_freebsd
+
+=======
+Editing
+=======
+
+Please make sure your text editor does not insert tabs, and
+used indents of 4 spaces.  The following .emacs code was used to
+configure emacs:
+
+(setq-default indent-tabs-mode nil)
+
+(add-hook 'c-mode-common-hook
+          (function (lambda ()
+                      (setq c-basic-offset 4)
+                      )))
+
+FreeDV GUI TODO List
+--------------------
+
+[ ] Ubuntu packaging
+[ ] default sound card in/out setting for rx out of the box
+[ ] When application close on windows while "Start" down sometimes crashes
+    + Also on Linux it reports an unterminated thread when exiting
+[ ] Tool-Audio Config Dialog sound device names truncated on Windows
+[ ] Serialport::closeport() on Linux takes about 1 second 
+    + delays 'Stop' on main window test on Tools-PTT Test
+[ ] Voice keyer file name at bottom on main screen truncated
+    + need a bigger field
+[ ] Start/Stop file rec/playback, work out a better UI, 
+    maybe buttons on front page
+[ ] feature for evaluating yr own sound quality
+    + trap bad mic response/levels
+    + zero in on different sound quality from different users
+[ ] feeding audio over UDP say from from gqrx
+    + could also be used to netcat stored files
+[ ] refactoring
+    [ ] fdmdv2_main.cpp is way too long
+    [ ] rename fdmdv2*.cpp -> freedv*.cpp
+    [ ] dlg_ptt uses ComPortsDlg name internally, rename PttDlg or similar
+[ ] Add RSID
+    + use case, when would it be used?
+[ ] clean up dialogs
+    + were based on auto generation code
+    + must be an easier/clearer way to write them
+
diff --git a/freedv/tags/1.2.2/freedv-dev/RELEASE_NOTES.txt b/freedv/tags/1.2.2/freedv-dev/RELEASE_NOTES.txt
new file mode 100644 (file)
index 0000000..79eaeca
--- /dev/null
@@ -0,0 +1,7 @@
+V1.2.2 July 2017
+----------------
+
+1/ Improvements to Hamlib support, error message reporting, serial rate box.
+
+2/ Disabled unused UDP comms/egexp processing to clean up Options dialog.
+
diff --git a/freedv/tags/1.2.2/freedv-dev/USER_MANUAL.txt b/freedv/tags/1.2.2/freedv-dev/USER_MANUAL.txt
new file mode 100644 (file)
index 0000000..2cc4494
--- /dev/null
@@ -0,0 +1,100 @@
+======================
+FREEDV GUI USER MANUAL
+======================
+
+Introduction
+------------
+
+This document describes additional features in the latest FreeDV
+releases that haven't been documented in other sources.  See also
+freedv.org
+
+PTT Configuration
+-----------------
+
+Tools-PTT Dialog
+
+Hamlib comes with a default serial rate for each radio.  If your radio
+has a different serial rate change the Serial Rate drop down box to
+match your radio.
+
+When "Test" is pressed, the "Serial Params" field is populated and
+displayed.  This will help track down any mis-matches between Hamlib
+and your radio.
+
+Voice Keyer
+-----------
+
+Voice Keyer Button on Front Page
+Options-PTT Dialog
+
+Puts FreeDV and your radio into transmit, reads a wave file of your
+voice to call CQ, then switches to receive to see if anyone is
+replying.  If you press space bar the voice keyer stops.  If a signal
+with a valid sync is received for a few seconds the voice keyer stops.
+
+Options-PTT dialog can be used to select the wave file, set the Rx
+delay, and number of times the tx/rx cycle repeats.
+
+The wave file for the voice keyer should be in 8kHz mono 16 bit sample
+form.  Use a free application such as Audacity to convert a file you
+have recorded to this format.
+
+Test Frame Histogram
+--------------------
+
+Test Frame Histogram tab on Front Page
+
+Displays BER of each carrier when in "test frame" mode.  As each QPSK
+carrier has 2 bits there are 2*Nc histogram points.
+
+Ideally all carriers will have about the same BER (+/- 20% after 5000
+total bit errors).  However problems can occur with filtering in the
+tx path.  If one carrier has less power, then it will have a higher
+BER.  The errors in this carrier will tend to dominate overall
+BER. For example if one carrier is attenuated due to SSB filter ripple
+in the tx path then the BER on that carrier will be higher.  This is
+bad news for DV.
+
+Suggested usage: 
+
+i) Transmit FreeDV in test frame mode.  Use a 2nd rx (or
+get a friend) to monitor your rx signal with FreeDV in test frame
+mode.  
+
+ii) Adjust your rx SNR to get a BER of a few % (e.g. reduce tx
+power, use a short antenna for the rx, point your beam away, adjust rx
+RF gain).  
+
+iii) Monitor the error histogram for a few minutes, until you
+have say 5000 total bit errors.  You have a problem if the BER of any
+carrier is more than 20% different from the rest.
+
+A typical issue will be one carrier at 1.0, the others at 0.5,
+indicating the poorer carrier BER is twice the larger.
+
+Full Duplex Testing with loopback
+---------------------------------
+
+Options - Half Duplex check box
+
+FreeDV GUI can operate in full duplex mode which is useful for
+development of listening to your own FreeDV signal as only one PC is
+required.  Normal operation is half duplex.
+
+Tx and Rx signals can be looped back via an analog connection between
+the sound cards.
+
+On Linux, using the Alsa loopback module:
+
+  $ sudo modprobe snd-aloop
+  $ ./freedv
+
+  In Tools - Audio Config - Receive Tab  - From Radio select -> Loopback: Loopback PCM (hw:1,0)
+                          - Transmit Tab - To Radio select   -> Loopback: Loopback PCM (hw:1,1)
+
+TODO
+----
+
+[ ] Merge this information into existing start up guides
+
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/BuildCodec2.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/BuildCodec2.cmake
new file mode 100644 (file)
index 0000000..038826d
--- /dev/null
@@ -0,0 +1,26 @@
+set(SPEEXDSP_CMAKE_ARGS -DBUILD_SHARED_LIBS=FALSE -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/external/dist)
+
+if(USE_STATIC_SPEEXDSP)
+    list(APPEND SPEEXDSP_CMAKE_ARGS 
+        -DSPEEXDSP_LIBRARIES=${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a
+        -DSPEEXDSP_INCLUDE_DIR=${CMAKE_BINARY_DIR}/external/dist/include)
+endif()
+
+set(CODEC2_CMAKE_ARGS -DUNITTEST=FALSE)
+
+if(CMAKE_CROSSCOMPILING)
+    set(CODEC2_CMAKE_ARGS ${CODEC2_CMAKE_ARGS} -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(codec2
+   SVN_REPOSITORY https://svn.code.sf.net/p/freetel/code/codec2-dev
+   CMAKE_ARGS ${CODEC2_CMAKE_ARGS} ${SPEEXDSP_CMAKE_ARGS} 
+   CMAKE_CACHE_ARGS -DCMAKE_OSX_DEPLOYMENT_TARGET:string=10.7
+   INSTALL_COMMAND ""
+)
+set(CODEC2_LIBRARIES
+    ${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2-build/src/libcodec2.a)
+include_directories(${CMAKE_BINARY_DIR}/codec2-prefix/src/codec2/src)
+list(APPEND FREEDV_LINK_LIBS ${CODEC2_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS codec2)
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/BuildHamlib.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/BuildHamlib.cmake
new file mode 100644 (file)
index 0000000..4166f5a
--- /dev/null
@@ -0,0 +1,20 @@
+set(HAMLIB_TARBALL "hamlib-1.2.15.3")
+
+include(ExternalProject)
+ExternalProject_Add(hamlib
+    URL http://downloads.sourceforge.net/hamlib/${HAMLIB_TARBALL}.tar.gz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(HAMLIB_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/portaudio.lib)
+else(WIN32)
+    set(HAMLIB_LIBRARIES
+    )
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${HAMLIB_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS hamlib)
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/BuildPortaudio.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/BuildPortaudio.cmake
new file mode 100644 (file)
index 0000000..cc33d06
--- /dev/null
@@ -0,0 +1,52 @@
+set(PORTAUDIO_TARBALL "pa_stable_v19_20111121")
+
+# required linking libraries on linux. Not sure about windows.
+find_library(ALSA_LIBRARIES asound)
+
+if(UNIX AND NOT ALSA_LIBRARIES)
+    message(ERROR "Could not find alsa library which is required for portaudio.
+On Linux systems try installing:
+    alsa-lib-devel  (RPM based systems)
+    libasound2-dev  (DEB based systems)"
+    )
+endif()
+
+# Make sure that configure knows what system we're using when cross-compiling.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+else()
+    set(CONFIGURE_COMMAND ./configure --enable-cxx --without-jack --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(portaudio
+    URL http://www.portaudio.com/archives/${PORTAUDIO_TARBALL}.tgz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(PORTAUDIO_LIBRARIES 
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
+)
+else(WIN32)
+    find_library(RT rt)
+    find_library(ASOUND asound)
+    set(PORTAUDIO_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudio.a
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libportaudiocpp.a
+        ${RT}
+        ${ASOUND}
+    )
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+
+# Add the portaudio library to the list of libraries that must be linked.
+list(APPEND FREEDV_LINK_LIBS ${PORTAUDIO_LIBRARIES})
+
+# Setup a dependency so that this gets built before linking to freedv.
+list(APPEND FREEDV_STATIC_DEPS portaudio)
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/BuildSamplerate.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/BuildSamplerate.cmake
new file mode 100644 (file)
index 0000000..8b6b7a3
--- /dev/null
@@ -0,0 +1,27 @@
+set(SAMPLERATE_TARBALL "libsamplerate-0.1.8")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-sndfile --disable-fftw)
+else()
+    set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(samplerate
+    URL http://www.mega-nerd.com/SRC/${SAMPLERATE_TARBALL}.tar.gz 
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE)
+    INSTALL_COMMAND $(MAKE) install
+)
+if(WIN32)
+    set(SAMPLERATE_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
+else(WIN32)
+    set(SAMPLERATE_LIBRARIES
+        ${CMAKE_BINARY_DIR}/external/dist/lib/libsamplerate.a)
+endif(WIN32)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SAMPLERATE_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS samplerate)
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/BuildSndfile.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/BuildSndfile.cmake
new file mode 100644 (file)
index 0000000..c49b638
--- /dev/null
@@ -0,0 +1,26 @@
+set(SNDFILE_TARBALL "libsndfile-1.0.25")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST}  --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared --disable-sqlite)
+else()
+    set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-external-libs --disable-shared --disable-external-libs)
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(sndfile
+    URL http://www.mega-nerd.com/libsndfile/files/${SNDFILE_TARBALL}.tar.gz
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND $(MAKE) V=1
+    INSTALL_COMMAND $(MAKE) install
+)
+if(MINGW)
+    set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
+else()
+    set(SNDFILE_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libsndfile.a)
+endif()
+
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SNDFILE_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS sndfile)
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/BuildSpeex.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/BuildSpeex.cmake
new file mode 100644 (file)
index 0000000..8d287ea
--- /dev/null
@@ -0,0 +1,30 @@
+set(SPEEXDSP_TARBALL "speexdsp-1.2rc3.tar.gz")
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST} --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
+else()
+    if(APPLE)
+        set(CONFIGURE_COMMAND ${CMAKE_BINARY_DIR}/../configure_speexdsp_osx.sh ${CMAKE_BINARY_DIR}/external/dist)
+    else()
+        set(CONFIGURE_COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/external/dist --disable-examples)
+    endif()
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(speex
+   URL http://downloads.xiph.org/releases/speex/${SPEEXDSP_TARBALL}
+   BUILD_IN_SOURCE 1
+   INSTALL_DIR external/dist
+   CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+   BUILD_COMMAND $(MAKE)
+   INSTALL_COMMAND $(MAKE) install
+)
+
+set(SPEEXDSP_LIBRARIES ${CMAKE_BINARY_DIR}/external/dist/lib/libspeexdsp.a)
+include_directories(${CMAKE_BINARY_DIR}/external/dist/include)
+list(APPEND FREEDV_LINK_LIBS ${SPEEXDSP_LIBRARIES})
+list(APPEND FREEDV_STATIC_DEPS speex)
+if(USE_STATIC_CODEC2)
+    add_dependencies(codec2 speex)
+endif()
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/BuildWxWidgets.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/BuildWxWidgets.cmake
new file mode 100644 (file)
index 0000000..901d806
--- /dev/null
@@ -0,0 +1,43 @@
+set(WXWIDGETS_TARBALL "wxWidgets-3.0.2")
+
+# If we're cross-compiling then we need to set the target host manually.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    include(cmake/MinGW.cmake)
+endif()
+
+# If not cross-compiling then use the built-in makefile, otherwise use standard configure.
+if(MINGW AND NOT CMAKE_CROSSCOMPILING)
+#    set(CONFIGURE_COMMAND "true")
+#    set(MAKE_COMMAND $(MAKE) -C build/msw -f makefile.gcc SHARED=0 UNICODE=1 BUILD=release PREFIX=${CMAKE_BINARY_DIR}/external/dist)
+    set(CONFIGURE_COMMAND ./configure --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    set(CONFIGURE_COMMAND ./configure --build=${HOST} --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+if(NOT MINGW)
+    set(CONFIGURE_COMMAND ./configure --host=${HOST} --target=${HOST} --disable-shared --prefix=${CMAKE_BINARY_DIR}/external/dist)
+       set(MAKE_COMMAND $(MAKE))
+endif()
+
+include(ExternalProject)
+ExternalProject_Add(wxWidgets
+    URL http://downloads.sourceforge.net/wxwindows/${WXWIDGETS_TARBALL}.tar.bz2
+    BUILD_IN_SOURCE 1
+    INSTALL_DIR external/dist
+    CONFIGURE_COMMAND ${CONFIGURE_COMMAND}
+    BUILD_COMMAND ${MAKE_COMMAND}
+    INSTALL_COMMAND $(MAKE) install
+)
+
+ExternalProject_Get_Property(wxWidgets install_dir)
+message(STATUS "wxWidgets install dir: ${install_dir}")
+if(NOT WXCONFIG)
+    set(WXCONFIG "${install_dir}/bin/wx-config")
+endif()
+if(EXISTS ${WXCONFIG})
+    set(BS_WX_DONE TRUE)
+endif()
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/FindPortaudio.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/FindPortaudio.cmake
new file mode 100644 (file)
index 0000000..158e20e
--- /dev/null
@@ -0,0 +1,107 @@
+# - Try to find Portaudio
+# Once done this will define
+#
+#  PORTAUDIO_FOUND - system has Portaudio
+#  PORTAUDIO_INCLUDE_DIRS - the Portaudio include directory
+#  PORTAUDIO_LIBRARIES - Link these to use Portaudio
+#  PORTAUDIO_DEFINITIONS - Compiler switches required for using Portaudio
+#  PORTAUDIO_VERSION - Portaudio version
+#
+#  Copyright (c) 2006 Andreas Schneider <mail@cynapses.org>
+#
+# Redistribution and use is allowed according to the terms of the New BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+
+if (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+  # in cache already
+  set(PORTAUDIO_FOUND TRUE)
+else (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+  if (NOT WIN32)
+   include(FindPkgConfig)
+   pkg_check_modules(PORTAUDIO2 portaudio-2.0)
+  endif (NOT WIN32)
+
+  if (PORTAUDIO2_FOUND)
+    set(PORTAUDIO_INCLUDE_DIRS
+      ${PORTAUDIO2_INCLUDE_DIRS}
+    )
+    if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+      set(PORTAUDIO_LIBRARIES "${PORTAUDIO2_LIBRARY_DIRS}/lib${PORTAUDIO2_LIBRARIES}.dylib")
+    else (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+      set(PORTAUDIO_LIBRARIES
+        ${PORTAUDIO2_LIBRARIES}
+      )
+    endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
+    set(PORTAUDIO_VERSION
+      19
+    )
+    set(PORTAUDIO_FOUND TRUE)
+  else (PORTAUDIO2_FOUND)
+    find_path(PORTAUDIO_INCLUDE_DIR
+      NAMES
+        portaudio.h
+      PATHS
+        /usr/include
+        /usr/local/include
+        /opt/local/include
+        /sw/include
+    )
+   
+    find_library(PORTAUDIO_LIBRARY
+      NAMES
+        portaudio
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /opt/local/lib
+        /sw/lib
+    )
+   
+    find_path(PORTAUDIO_LIBRARY_DIR
+      NAMES
+        portaudio
+      PATHS
+        /usr/lib
+        /usr/local/lib
+        /opt/local/lib
+        /sw/lib
+    )
+   
+    set(PORTAUDIO_INCLUDE_DIRS
+      ${PORTAUDIO_INCLUDE_DIR}
+    )
+    set(PORTAUDIO_LIBRARIES
+      ${PORTAUDIO_LIBRARY}
+    )
+   
+    set(PORTAUDIO_LIBRARY_DIRS
+      ${PORTAUDIO_LIBRARY_DIR}
+    )
+   
+    set(PORTAUDIO_VERSION
+      18
+    )
+   
+    if (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
+       set(PORTAUDIO_FOUND TRUE)
+    endif (PORTAUDIO_INCLUDE_DIRS AND PORTAUDIO_LIBRARIES)
+   
+    if (PORTAUDIO_FOUND)
+      if (NOT Portaudio_FIND_QUIETLY)
+        message(STATUS "Found Portaudio: ${PORTAUDIO_LIBRARIES}")
+      endif (NOT Portaudio_FIND_QUIETLY)
+    else (PORTAUDIO_FOUND)
+      if (Portaudio_FIND_REQUIRED)
+        message(FATAL_ERROR "Could not find Portaudio")
+      endif (Portaudio_FIND_REQUIRED)
+    endif (PORTAUDIO_FOUND)
+  endif (PORTAUDIO2_FOUND)
+
+
+  # show the PORTAUDIO_INCLUDE_DIRS and PORTAUDIO_LIBRARIES variables only in the advanced view
+  mark_as_advanced(PORTAUDIO_INCLUDE_DIRS PORTAUDIO_LIBRARIES)
+
+endif (PORTAUDIO_LIBRARIES AND PORTAUDIO_INCLUDE_DIRS)
+
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/GetDependencies.cmake.in b/freedv/tags/1.2.2/freedv-dev/cmake/GetDependencies.cmake.in
new file mode 100644 (file)
index 0000000..7470aa6
--- /dev/null
@@ -0,0 +1,37 @@
+# As this script is run in a new cmake instance, it does not have access to
+# the existing cache variables. Pass them in via the configure_file command.
+set(CMAKE_BINARY_DIR @CMAKE_BINARY_DIR@)
+set(CMAKE_SOURCE_DIR @CMAKE_SOURCE_DIR@)
+set(UNIX @UNIX@)
+set(WIN32 @WIN32@)
+set(CMAKE_CROSSCOMPILING @CMAKE_CROSSCOMPILING@)
+set(CMAKE_FIND_LIBRARY_SUFFIXES @CMAKE_FIND_LIBRARY_SUFFIXES@)
+set(CMAKE_FIND_LIBRARY_PREFIXES @CMAKE_FIND_LIBRARY_PREFIXES@)
+set(CMAKE_SYSTEM_LIBRARY_PATH @CMAKE_SYSTEM_LIBRARY_PATH@)
+set(CMAKE_FIND_ROOT_PATH @CMAKE_FIND_ROOT_PATH@)
+
+set(FREEDV_EXE ${CMAKE_BINARY_DIR}/src/freedv.exe)
+
+include(GetPrerequisites)
+get_prerequisites("${FREEDV_EXE}" _deps 1 0 "" "")
+foreach(_runtime ${_deps})
+    message("Looking for ${_runtime}")
+    find_library(RUNTIME_${_runtime} ${_runtime})
+    message("${RUNTIME_${_runtime}}")
+    if(RUNTIME_${_runtime})
+        message("Looking for dependencies of ${_runtime}")
+        get_prerequisites("${RUNTIME_${_runtime}}" _deps2 1 0 "" "")
+        foreach(_runtime2 ${_deps2})
+            find_library(RUNTIME_${_runtime2} ${_runtime2})
+            message("${RUNTIME_${_runtime2}}")
+            if(RUNTIME_${_runtime2})
+                file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
+                TYPE EXECUTABLE FILES "${RUNTIME_${_runtime2}}")
+            endif()
+        endforeach()
+    endif()
+    if(RUNTIME_${_runtime})
+        file(INSTALL DESTINATION "${CMAKE_INSTALL_PREFIX}/bin"
+        TYPE EXECUTABLE FILES "${RUNTIME_${_runtime}}")
+    endif()
+endforeach()
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/MinGW.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/MinGW.cmake
new file mode 100644 (file)
index 0000000..333c1dc
--- /dev/null
@@ -0,0 +1,8 @@
+# If we're cross-compiling then we need to set the target host manually.
+if(MINGW AND CMAKE_CROSSCOMPILING)
+    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+        set(HOST x86_64-w64-mingw32)
+    else()
+        set(HOST i686-w64-mingw32)
+    endif()
+endif()
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake b/freedv/tags/1.2.2/freedv-dev/cmake/Toolchain-Ubuntu-mingw32.cmake
new file mode 100644 (file)
index 0000000..3507d72
--- /dev/null
@@ -0,0 +1,25 @@
+# Sample toolchain file for building for Windows from an Ubuntu Linux system.
+#
+# Typical usage:
+#    *) install cross compiler: `sudo apt-get install mingw-w64 g++-mingw-w64`
+#    *) cd build
+#    *) cmake -DCMAKE_TOOLCHAIN_FILE=~/Toolchain-Ubuntu-mingw32.cmake ..
+
+set(CMAKE_SYSTEM_NAME Windows)
+set(TOOLCHAIN_PREFIX i686-w64-mingw32)
+
+# cross compilers to use for C and C++
+set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
+set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
+set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)
+
+# target environment on the build host system
+#   set 1st to dir with the cross compiler's C/C++ headers/libs
+set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX})
+
+# modify default behavior of FIND_XXX() commands to
+# search for headers/libs in the target environment and
+# search for programs in the build host environment
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/config.h.in b/freedv/tags/1.2.2/freedv-dev/cmake/config.h.in
new file mode 100644 (file)
index 0000000..8e3ab76
--- /dev/null
@@ -0,0 +1,19 @@
+/*--------------------------------------------------------------------------
+ ** This file is autogenerated from config.h.in 
+ ** during the cmake configuration of your project. If you need to make changes
+ ** edit the original file NOT THIS FILE.
+ ** --------------------------------------------------------------------------*/
+#ifndef _CONFIGURATION_HEADER_GUARD_H_
+#define _CONFIGURATION_HEADER_GUARD_H_
+
+#define SIZEOF_INT @SIZEOF_INT@
+#cmakedefine HAVE_LIMITS_H @HAVE_LIMITS_H@
+#cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@
+#cmakedefine HAVE_STDDEF_H @HAVE_STDDEF_H@
+#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@
+#cmakedefine HAVE_STRING_H @HAVE_STRING_H@
+#cmakedefine HAVE_FLOOR @HAVE_FLOOR@
+#cmakedefine HAVE_MEMSET @HAVE_MEMSET@
+#cmakedefine HAVE_POW @HAVE_POW@
+#cmakedefine HAVE_SQRT @HAVE_SQRT@
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/soxconfig.h.in b/freedv/tags/1.2.2/freedv-dev/cmake/soxconfig.h.in
new file mode 100644 (file)
index 0000000..fb38608
--- /dev/null
@@ -0,0 +1,16 @@
+#define PACKAGE_VERSION "14.4.2"
+
+#cmakedefine HAVE_BYTESWAP_H          1
+#cmakedefine HAVE_FMEMOPEN            1
+#cmakedefine HAVE_FSEEKO              1
+#cmakedefine HAVE__FSEEKOI64          1
+#cmakedefine HAVE_LTDL_H              1
+#cmakedefine HAVE_MAGIC               1
+#cmakedefine HAVE_POPEN               1
+#cmakedefine HAVE_STDINT_H            1
+#cmakedefine HAVE_INTTYPES_H          1
+#cmakedefine HAVE_STRCASECMP          1
+#cmakedefine HAVE_STRINGS_H           1
+#cmakedefine HAVE_SYS_STAT_H          1
+#cmakedefine HAVE_SYS_TYPES_H         1
+#cmakedefine HAVE_VSNPRINTF           1
diff --git a/freedv/tags/1.2.2/freedv-dev/cmake/version.h.in b/freedv/tags/1.2.2/freedv-dev/cmake/version.h.in
new file mode 100644 (file)
index 0000000..43b3b7a
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef FREEDV_VER_DOT_H
+#define FREEDV_VER_DOT_H 1
+
+#define FREEDV_VERSION_MAJOR @FREEDV_VERSION_MAJOR@
+#define FREEDV_VERSION_MINOR @FREEDV_VERSION_MINOR@
+#define FREEDV_VERSION_PATCH @FREEDV_VERSION_PATCH@
+#define FREEDV_VERSION_SUFFIX "@FREEDV_VERSION_SUFFIX@"
+
+#define FREEDV_VERSION "@FREEDV_VERSION_STRING@"
+
+#endif //FREEDV_VER_DOT_H
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/CMakeLists.txt b/freedv/tags/1.2.2/freedv-dev/contrib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3f4b7e0
--- /dev/null
@@ -0,0 +1,22 @@
+# Install icons if we're on most *nix systems.
+if(UNIX AND NOT APPLE)
+    set(ICON_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor
+        CACHE PATH "Prefix to use for installing icons.")
+    install(FILES freedv48x48.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/48x48/apps
+        RENAME freedv.png)
+    install(FILES freedv64x64.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/64x64/apps
+        RENAME freedv.png)
+    install(FILES freedv128x128.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/128x128/apps
+        RENAME freedv.png)
+    install(FILES freedv256x256.png
+        DESTINATION ${ICON_INSTALL_PREFIX}/256x256/apps
+        RENAME freedv.png)
+
+    set(DESKTOP_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications
+        CACHE PATH "Location to install desktop files.")
+    install(FILES freedv.desktop
+        DESTINATION ${DESKTOP_INSTALL_DIR})
+endif(UNIX AND NOT APPLE)
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/LICENSE b/freedv/tags/1.2.2/freedv-dev/contrib/LICENSE
new file mode 100644 (file)
index 0000000..dc8853a
--- /dev/null
@@ -0,0 +1,393 @@
+Attribution 4.0 International
+
+=======================================================================
+
+Creative Commons Corporation ("Creative Commons") is not a law firm and
+does not provide legal services or legal advice. Distribution of
+Creative Commons public licenses does not create a lawyer-client or
+other relationship. Creative Commons makes its licenses and related
+information available on an "as-is" basis. Creative Commons gives no
+warranties regarding its licenses, any material licensed under their
+terms and conditions, or any related information. Creative Commons
+disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and
+conditions that creators and other rights holders may use to share
+original works of authorship and other material subject to copyright
+and certain other rights specified in the public license below. The
+following considerations are for informational purposes only, are not
+exhaustive, and do not form part of our licenses.
+
+     Considerations for licensors: Our public licenses are
+     intended for use by those authorized to give the public
+     permission to use material in ways otherwise restricted by
+     copyright and certain other rights. Our licenses are
+     irrevocable. Licensors should read and understand the terms
+     and conditions of the license they choose before applying it.
+     Licensors should also secure all rights necessary before
+     applying our licenses so that the public can reuse the
+     material as expected. Licensors should clearly mark any
+     material not subject to the license. This includes other CC-
+     licensed material, or material used under an exception or
+     limitation to copyright. More considerations for licensors:
+       wiki.creativecommons.org/Considerations_for_licensors
+
+     Considerations for the public: By using one of our public
+     licenses, a licensor grants the public permission to use the
+     licensed material under specified terms and conditions. If
+     the licensor's permission is not necessary for any reason--for
+     example, because of any applicable exception or limitation to
+     copyright--then that use is not regulated by the license. Our
+     licenses grant only permissions under copyright and certain
+     other rights that a licensor has authority to grant. Use of
+     the licensed material may still be restricted for other
+     reasons, including because others have copyright or other
+     rights in the material. A licensor may make special requests,
+     such as asking that all changes be marked or described.
+     Although not required by our licenses, you are encouraged to
+     respect those requests where reasonable. More_considerations
+     for the public: 
+       wiki.creativecommons.org/Considerations_for_licensees
+
+=======================================================================
+
+Creative Commons Attribution 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree
+to be bound by the terms and conditions of this Creative Commons
+Attribution 4.0 International Public License ("Public License"). To the
+extent this Public License may be interpreted as a contract, You are
+granted the Licensed Rights in consideration of Your acceptance of
+these terms and conditions, and the Licensor grants You such rights in
+consideration of benefits the Licensor receives from making the
+Licensed Material available under these terms and conditions.
+
+
+Section 1 -- Definitions.
+
+  a. Adapted Material means material subject to Copyright and Similar
+     Rights that is derived from or based upon the Licensed Material
+     and in which the Licensed Material is translated, altered,
+     arranged, transformed, or otherwise modified in a manner requiring
+     permission under the Copyright and Similar Rights held by the
+     Licensor. For purposes of this Public License, where the Licensed
+     Material is a musical work, performance, or sound recording,
+     Adapted Material is always produced where the Licensed Material is
+     synched in timed relation with a moving image.
+
+  b. Adapter's License means the license You apply to Your Copyright
+     and Similar Rights in Your contributions to Adapted Material in
+     accordance with the terms and conditions of this Public License.
+
+  c. Copyright and Similar Rights means copyright and/or similar rights
+     closely related to copyright including, without limitation,
+     performance, broadcast, sound recording, and Sui Generis Database
+     Rights, without regard to how the rights are labeled or
+     categorized. For purposes of this Public License, the rights
+     specified in Section 2(b)(1)-(2) are not Copyright and Similar
+     Rights.
+
+  d. Effective Technological Measures means those measures that, in the
+     absence of proper authority, may not be circumvented under laws
+     fulfilling obligations under Article 11 of the WIPO Copyright
+     Treaty adopted on December 20, 1996, and/or similar international
+     agreements.
+
+  e. Exceptions and Limitations means fair use, fair dealing, and/or
+     any other exception or limitation to Copyright and Similar Rights
+     that applies to Your use of the Licensed Material.
+
+  f. Licensed Material means the artistic or literary work, database,
+     or other material to which the Licensor applied this Public
+     License.
+
+  g. Licensed Rights means the rights granted to You subject to the
+     terms and conditions of this Public License, which are limited to
+     all Copyright and Similar Rights that apply to Your use of the
+     Licensed Material and that the Licensor has authority to license.
+
+  h. Licensor means the individual(s) or entity(ies) granting rights
+     under this Public License.
+
+  i. Share means to provide material to the public by any means or
+     process that requires permission under the Licensed Rights, such
+     as reproduction, public display, public performance, distribution,
+     dissemination, communication, or importation, and to make material
+     available to the public including in ways that members of the
+     public may access the material from a place and at a time
+     individually chosen by them.
+
+  j. Sui Generis Database Rights means rights other than copyright
+     resulting from Directive 96/9/EC of the European Parliament and of
+     the Council of 11 March 1996 on the legal protection of databases,
+     as amended and/or succeeded, as well as other essentially
+     equivalent rights anywhere in the world.
+
+  k. You means the individual or entity exercising the Licensed Rights
+     under this Public License. Your has a corresponding meaning.
+
+
+Section 2 -- Scope.
+
+  a. License grant.
+
+       1. Subject to the terms and conditions of this Public License,
+          the Licensor hereby grants You a worldwide, royalty-free,
+          non-sublicensable, non-exclusive, irrevocable license to
+          exercise the Licensed Rights in the Licensed Material to:
+
+            a. reproduce and Share the Licensed Material, in whole or
+               in part; and
+
+            b. produce, reproduce, and Share Adapted Material.
+
+       2. Exceptions and Limitations. For the avoidance of doubt, where
+          Exceptions and Limitations apply to Your use, this Public
+          License does not apply, and You do not need to comply with
+          its terms and conditions.
+
+       3. Term. The term of this Public License is specified in Section
+          6(a).
+
+       4. Media and formats; technical modifications allowed. The
+          Licensor authorizes You to exercise the Licensed Rights in
+          all media and formats whether now known or hereafter created,
+          and to make technical modifications necessary to do so. The
+          Licensor waives and/or agrees not to assert any right or
+          authority to forbid You from making technical modifications
+          necessary to exercise the Licensed Rights, including
+          technical modifications necessary to circumvent Effective
+          Technological Measures. For purposes of this Public License,
+          simply making modifications authorized by this Section 2(a)
+          (4) never produces Adapted Material.
+
+       5. Downstream recipients.
+
+            a. Offer from the Licensor -- Licensed Material. Every
+               recipient of the Licensed Material automatically
+               receives an offer from the Licensor to exercise the
+               Licensed Rights under the terms and conditions of this
+               Public License.
+
+            b. No downstream restrictions. You may not offer or impose
+               any additional or different terms or conditions on, or
+               apply any Effective Technological Measures to, the
+               Licensed Material if doing so restricts exercise of the
+               Licensed Rights by any recipient of the Licensed
+               Material.
+
+       6. No endorsement. Nothing in this Public License constitutes or
+          may be construed as permission to assert or imply that You
+          are, or that Your use of the Licensed Material is, connected
+          with, or sponsored, endorsed, or granted official status by,
+          the Licensor or others designated to receive attribution as
+          provided in Section 3(a)(1)(A)(i).
+
+  b. Other rights.
+
+       1. Moral rights, such as the right of integrity, are not
+          licensed under this Public License, nor are publicity,
+          privacy, and/or other similar personality rights; however, to
+          the extent possible, the Licensor waives and/or agrees not to
+          assert any such rights held by the Licensor to the limited
+          extent necessary to allow You to exercise the Licensed
+          Rights, but not otherwise.
+
+       2. Patent and trademark rights are not licensed under this
+          Public License.
+
+       3. To the extent possible, the Licensor waives any right to
+          collect royalties from You for the exercise of the Licensed
+          Rights, whether directly or through a collecting society
+          under any voluntary or waivable statutory or compulsory
+          licensing scheme. In all other cases the Licensor expressly
+          reserves any right to collect such royalties.
+
+
+Section 3 -- License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the
+following conditions.
+
+  a. Attribution.
+
+       1. If You Share the Licensed Material (including in modified
+          form), You must:
+
+            a. retain the following if it is supplied by the Licensor
+               with the Licensed Material:
+
+                 i. identification of the creator(s) of the Licensed
+                    Material and any others designated to receive
+                    attribution, in any reasonable manner requested by
+                    the Licensor (including by pseudonym if
+                    designated);
+
+                ii. a copyright notice;
+
+               iii. a notice that refers to this Public License;
+
+                iv. a notice that refers to the disclaimer of
+                    warranties;
+
+                 v. a URI or hyperlink to the Licensed Material to the
+                    extent reasonably practicable;
+
+            b. indicate if You modified the Licensed Material and
+               retain an indication of any previous modifications; and
+
+            c. indicate the Licensed Material is licensed under this
+               Public License, and include the text of, or the URI or
+               hyperlink to, this Public License.
+
+       2. You may satisfy the conditions in Section 3(a)(1) in any
+          reasonable manner based on the medium, means, and context in
+          which You Share the Licensed Material. For example, it may be
+          reasonable to satisfy the conditions by providing a URI or
+          hyperlink to a resource that includes the required
+          information.
+
+       3. If requested by the Licensor, You must remove any of the
+          information required by Section 3(a)(1)(A) to the extent
+          reasonably practicable.
+
+       4. If You Share Adapted Material You produce, the Adapter's
+          License You apply must not prevent recipients of the Adapted
+          Material from complying with this Public License.
+
+
+Section 4 -- Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that
+apply to Your use of the Licensed Material:
+
+  a. for the avoidance of doubt, Section 2(a)(1) grants You the right
+     to extract, reuse, reproduce, and Share all or a substantial
+     portion of the contents of the database;
+
+  b. if You include all or a substantial portion of the database
+     contents in a database in which You have Sui Generis Database
+     Rights, then the database in which You have Sui Generis Database
+     Rights (but not its individual contents) is Adapted Material; and
+
+  c. You must comply with the conditions in Section 3(a) if You Share
+     all or a substantial portion of the contents of the database.
+
+For the avoidance of doubt, this Section 4 supplements and does not
+replace Your obligations under this Public License where the Licensed
+Rights include other Copyright and Similar Rights.
+
+
+Section 5 -- Disclaimer of Warranties and Limitation of Liability.
+
+  a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
+     EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
+     AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
+     ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
+     IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
+     WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
+     PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
+     ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
+     KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
+     ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
+
+  b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
+     TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+     NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
+     INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
+     COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
+     USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
+     ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
+     DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
+     IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
+
+  c. The disclaimer of warranties and limitation of liability provided
+     above shall be interpreted in a manner that, to the extent
+     possible, most closely approximates an absolute disclaimer and
+     waiver of all liability.
+
+
+Section 6 -- Term and Termination.
+
+  a. This Public License applies for the term of the Copyright and
+     Similar Rights licensed here. However, if You fail to comply with
+     this Public License, then Your rights under this Public License
+     terminate automatically.
+
+  b. Where Your right to use the Licensed Material has terminated under
+     Section 6(a), it reinstates:
+
+       1. automatically as of the date the violation is cured, provided
+          it is cured within 30 days of Your discovery of the
+          violation; or
+
+       2. upon express reinstatement by the Licensor.
+
+     For the avoidance of doubt, this Section 6(b) does not affect any
+     right the Licensor may have to seek remedies for Your violations
+     of this Public License.
+
+  c. For the avoidance of doubt, the Licensor may also offer the
+     Licensed Material under separate terms or conditions or stop
+     distributing the Licensed Material at any time; however, doing so
+     will not terminate this Public License.
+
+  d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
+     License.
+
+
+Section 7 -- Other Terms and Conditions.
+
+  a. The Licensor shall not be bound by any additional or different
+     terms or conditions communicated by You unless expressly agreed.
+
+  b. Any arrangements, understandings, or agreements regarding the
+     Licensed Material not stated herein are separate from and
+     independent of the terms and conditions of this Public License.
+
+
+Section 8 -- Interpretation.
+
+  a. For the avoidance of doubt, this Public License does not, and
+     shall not be interpreted to, reduce, limit, restrict, or impose
+     conditions on any use of the Licensed Material that could lawfully
+     be made without permission under this Public License.
+
+  b. To the extent possible, if any provision of this Public License is
+     deemed unenforceable, it shall be automatically reformed to the
+     minimum extent necessary to make it enforceable. If the provision
+     cannot be reformed, it shall be severed from this Public License
+     without affecting the enforceability of the remaining terms and
+     conditions.
+
+  c. No term or condition of this Public License will be waived and no
+     failure to comply consented to unless expressly agreed to by the
+     Licensor.
+
+  d. Nothing in this Public License constitutes or may be interpreted
+     as a limitation upon, or waiver of, any privileges and immunities
+     that apply to the Licensor or You, including from the legal
+     processes of any jurisdiction or authority.
+
+
+=======================================================================
+
+Creative Commons is not a party to its public licenses.
+Notwithstanding, Creative Commons may elect to apply one of its public
+licenses to material it publishes and in those instances will be
+considered the "Licensor." Except for the limited purpose of indicating
+that material is shared under a Creative Commons public license or as
+otherwise permitted by the Creative Commons policies published at
+creativecommons.org/policies, Creative Commons does not authorize the
+use of the trademark "Creative Commons" or any other trademark or logo
+of Creative Commons without its prior written consent including,
+without limitation, in connection with any unauthorized modifications
+to any of its public licenses or any other arrangements,
+understandings, or agreements concerning use of licensed material. For
+the avoidance of doubt, this paragraph does not form part of the public
+licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv.desktop b/freedv/tags/1.2.2/freedv-dev/contrib/freedv.desktop
new file mode 100644 (file)
index 0000000..96e8293
--- /dev/null
@@ -0,0 +1,8 @@
+[Desktop Entry]
+Version=1.0
+Name=FreeDV
+Exec=freedv
+Icon=freedv
+Type=Application
+Terminal=false
+Categories=GTK;GNOME;AudioVideo;Audio;HamRadio;
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv.ico b/freedv/tags/1.2.2/freedv-dev/contrib/freedv.ico
new file mode 100644 (file)
index 0000000..e6b9a20
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/contrib/freedv.ico differ
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv.rc b/freedv/tags/1.2.2/freedv-dev/contrib/freedv.rc
new file mode 100644 (file)
index 0000000..2e6655d
--- /dev/null
@@ -0,0 +1 @@
+id ICON "./freedv.ico"
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv128x128.png b/freedv/tags/1.2.2/freedv-dev/contrib/freedv128x128.png
new file mode 100644 (file)
index 0000000..5190a77
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/contrib/freedv128x128.png differ
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv256x256.png b/freedv/tags/1.2.2/freedv-dev/contrib/freedv256x256.png
new file mode 100644 (file)
index 0000000..b3eb5d7
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/contrib/freedv256x256.png differ
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv48x48.png b/freedv/tags/1.2.2/freedv-dev/contrib/freedv48x48.png
new file mode 100644 (file)
index 0000000..bd5efc6
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/contrib/freedv48x48.png differ
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv64x64.png b/freedv/tags/1.2.2/freedv-dev/contrib/freedv64x64.png
new file mode 100644 (file)
index 0000000..eb89773
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/contrib/freedv64x64.png differ
diff --git a/freedv/tags/1.2.2/freedv-dev/contrib/freedv_screenshot.png b/freedv/tags/1.2.2/freedv-dev/contrib/freedv_screenshot.png
new file mode 100644 (file)
index 0000000..f93e3c5
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/contrib/freedv_screenshot.png differ
diff --git a/freedv/tags/1.2.2/freedv-dev/credits.txt b/freedv/tags/1.2.2/freedv-dev/credits.txt
new file mode 100644 (file)
index 0000000..431e399
--- /dev/null
@@ -0,0 +1,13 @@
+Credits (code or ideas borrowed from):
+==============================================
+Dave Witten and David Rowe (obviously)
+Mel Whitten K0PFX (material and moral support)
+Bruce Perens (cheerleader, promotion and publicity)
+Mooneer Salem KG6AOV(Mac OSX Patch)
+Soeren Straarup OZ2DAK (FreeBSD Port)
+Don Mak
+Steve Nance (K5FR)
+Joel Stanley (Hamlib prototyping) and Mark Jessop (Mac OSX) 
+James Ahlstrom (Quisk)
+FLDIGI
+All the folks on the digital voice google group...
diff --git a/freedv/tags/1.2.2/freedv-dev/db/current b/freedv/tags/1.2.2/freedv-dev/db/current
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/freedv/tags/1.2.2/freedv-dev/db/format b/freedv/tags/1.2.2/freedv-dev/db/format
new file mode 100644 (file)
index 0000000..db06890
--- /dev/null
@@ -0,0 +1,2 @@
+4
+layout sharded 1000
diff --git a/freedv/tags/1.2.2/freedv-dev/db/fs-type b/freedv/tags/1.2.2/freedv-dev/db/fs-type
new file mode 100644 (file)
index 0000000..4fdd953
--- /dev/null
@@ -0,0 +1 @@
+fsfs
diff --git a/freedv/tags/1.2.2/freedv-dev/db/fsfs.conf b/freedv/tags/1.2.2/freedv-dev/db/fsfs.conf
new file mode 100644 (file)
index 0000000..cc08ceb
--- /dev/null
@@ -0,0 +1,38 @@
+### This file controls the configuration of the FSFS filesystem.\r
+\r
+[memcached-servers]\r
+### These options name memcached servers used to cache internal FSFS\r
+### data.  See http://www.danga.com/memcached/ for more information on\r
+### memcached.  To use memcached with FSFS, run one or more memcached\r
+### servers, and specify each of them as an option like so:\r
+# first-server = 127.0.0.1:11211\r
+# remote-memcached = mymemcached.corp.example.com:11212\r
+### The option name is ignored; the value is of the form HOST:PORT.\r
+### memcached servers can be shared between multiple repositories;\r
+### however, if you do this, you *must* ensure that repositories have\r
+### distinct UUIDs and paths, or else cached data from one repository\r
+### might be used by another accidentally.  Note also that memcached has\r
+### no authentication for reads or writes, so you must ensure that your\r
+### memcached servers are only accessible by trusted users.\r
+\r
+[caches]\r
+### When a cache-related error occurs, normally Subversion ignores it\r
+### and continues, logging an error if the server is appropriately\r
+### configured (and ignoring it with file:// access).  To make\r
+### Subversion never ignore cache errors, uncomment this line.\r
+# fail-stop = true\r
+\r
+[rep-sharing]\r
+### To conserve space, the filesystem can optionally avoid storing\r
+### duplicate representations.  This comes at a slight cost in\r
+### performance, as maintaining a database of shared representations can\r
+### increase commit times.  The space savings are dependent upon the size\r
+### of the repository, the number of objects it contains and the amount of\r
+### duplication between them, usually a function of the branching and\r
+### merging process.\r
+###\r
+### The following parameter enables rep-sharing in the repository.  It can\r
+### be switched on and off at will, but for best space-saving results\r
+### should be enabled consistently over the life of the repository.\r
+### rep-sharing is enabled by default.\r
+# enable-rep-sharing = true\r
diff --git a/freedv/tags/1.2.2/freedv-dev/db/min-unpacked-rev b/freedv/tags/1.2.2/freedv-dev/db/min-unpacked-rev
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/freedv/tags/1.2.2/freedv-dev/db/rep-cache.db b/freedv/tags/1.2.2/freedv-dev/db/rep-cache.db
new file mode 100644 (file)
index 0000000..63c6f0b
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/db/rep-cache.db differ
diff --git a/freedv/tags/1.2.2/freedv-dev/db/revprops/0/0 b/freedv/tags/1.2.2/freedv-dev/db/revprops/0/0
new file mode 100644 (file)
index 0000000..d0b90de
--- /dev/null
@@ -0,0 +1,5 @@
+K 8
+svn:date
+V 27
+2012-08-21T18:27:59.389906Z
+END
diff --git a/freedv/tags/1.2.2/freedv-dev/db/revprops/0/1 b/freedv/tags/1.2.2/freedv-dev/db/revprops/0/1
new file mode 100644 (file)
index 0000000..0af71a2
--- /dev/null
@@ -0,0 +1,13 @@
+K 10
+svn:author
+V 9
+OFA-Staff
+K 8
+svn:date
+V 27
+2012-08-21T18:28:08.741468Z
+K 7
+svn:log
+V 25
+Imported folder structure
+END
diff --git a/freedv/tags/1.2.2/freedv-dev/db/revs/0/0 b/freedv/tags/1.2.2/freedv-dev/db/revs/0/0
new file mode 100644 (file)
index 0000000..10f5c45
--- /dev/null
@@ -0,0 +1,11 @@
+PLAIN
+END
+ENDREP
+id: 0.0.r0/17
+type: dir
+count: 0
+text: 0 0 4 4 2d2977d1c96f487abe4a1e202dd03b4e
+cpath: /
+
+
+17 107
diff --git a/freedv/tags/1.2.2/freedv-dev/db/revs/0/1 b/freedv/tags/1.2.2/freedv-dev/db/revs/0/1
new file mode 100644 (file)
index 0000000..fd802a9
--- /dev/null
@@ -0,0 +1,49 @@
+id: 3-1.0.r1/0
+type: dir
+count: 0
+cpath: /tags
+copyroot: 0 /
+
+id: 0-1.0.r1/62
+type: dir
+count: 0
+cpath: /trunk
+copyroot: 0 /
+
+id: 2-1.0.r1/126
+type: dir
+count: 0
+cpath: /branches
+copyroot: 0 /
+
+PLAIN
+K 8
+branches
+V 16
+dir 2-1.0.r1/126
+K 4
+tags
+V 14
+dir 3-1.0.r1/0
+K 5
+trunk
+V 15
+dir 0-1.0.r1/62
+END
+ENDREP
+id: 0.0.r1/306
+type: dir
+pred: 0.0.r0/17
+count: 1
+text: 1 194 99 99 7b6cc14dddba4e09be5255b475d1a0a8
+cpath: /
+copyroot: 0 /
+
+_0.0.t0-0 add-dir false false /trunk
+
+_2.0.t0-0 add-dir false false /branches
+
+_3.0.t0-0 add-dir false false /tags
+
+
+306 431
diff --git a/freedv/tags/1.2.2/freedv-dev/db/transactions/.gitignore b/freedv/tags/1.2.2/freedv-dev/db/transactions/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/freedv-dev/db/txn-current b/freedv/tags/1.2.2/freedv-dev/db/txn-current
new file mode 100644 (file)
index 0000000..d00491f
--- /dev/null
@@ -0,0 +1 @@
+1
diff --git a/freedv/tags/1.2.2/freedv-dev/db/txn-current-lock b/freedv/tags/1.2.2/freedv-dev/db/txn-current-lock
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/freedv-dev/db/txn-protorevs/.gitignore b/freedv/tags/1.2.2/freedv-dev/db/txn-protorevs/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/freedv-dev/db/uuid b/freedv/tags/1.2.2/freedv-dev/db/uuid
new file mode 100644 (file)
index 0000000..0f36297
--- /dev/null
@@ -0,0 +1 @@
+a56d66ce-6468-4744-9be7-52ce95ca47a4
diff --git a/freedv/tags/1.2.2/freedv-dev/db/write-lock b/freedv/tags/1.2.2/freedv-dev/db/write-lock
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/freedv/tags/1.2.2/freedv-dev/debian/changelog b/freedv/tags/1.2.2/freedv-dev/debian/changelog
new file mode 100644 (file)
index 0000000..ddfe80b
--- /dev/null
@@ -0,0 +1,5 @@
+freedv (1.0-150830) unstable; urgency=low
+
+  * Subversion snapshot of tag 1.0.
+
+ -- Stuart Longland <stuartl@longlandclan.yi.org>  Sun, 30 Aug 2015 09:01:13 +1000
diff --git a/freedv/tags/1.2.2/freedv-dev/debian/compat b/freedv/tags/1.2.2/freedv-dev/debian/compat
new file mode 100644 (file)
index 0000000..ec63514
--- /dev/null
@@ -0,0 +1 @@
+9
diff --git a/freedv/tags/1.2.2/freedv-dev/debian/control b/freedv/tags/1.2.2/freedv-dev/debian/control
new file mode 100644 (file)
index 0000000..d1472b2
--- /dev/null
@@ -0,0 +1,19 @@
+Source: fdmdv2
+Section: main
+Priority: optional
+Maintainer: Stuart Longland <stuartl@longlandclan.yi.org>
+Build-Depends: debhelper (>= 9), cmake, libcodec2-dev, libgtk2.0-dev,
+ libhamlib-dev, libsamplerate-dev, libasound2-dev, libao-dev, libgsm1-dev,
+ portaudio19-dev, libsox-dev, libsndfile1-dev, libwxgtk3.0-dev
+Standards-Version: 3.9.5
+Homepage: http://www.freedv.org
+#Vcs-Git: git://anonscm.debian.org/collab-maint/freedv.git
+#Vcs-Browser: http://anonscm.debian.org/?p=collab-maint/freedv.git;a=summary
+
+Package: freedv
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libcodec2
+Description: FreeDV: Open-Source Digital Voice modem
+ FreeDV is a digital voice modem that can transmit voice-quality
+ audio digitally over HF radio links in as little as 1.25kHz
+ bandwidth in varying conditions.
diff --git a/freedv/tags/1.2.2/freedv-dev/debian/copyright b/freedv/tags/1.2.2/freedv-dev/debian/copyright
new file mode 100644 (file)
index 0000000..b55a293
--- /dev/null
@@ -0,0 +1,38 @@
+Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: freedv
+Source: <url://example.com>
+
+Files: *
+Copyright: <years> <put author's name and email here>
+           <years> <likewise for another author>
+License: <special license>
+ <Put the license of the package here indented by 1 space>
+ <This follows the format of Description: lines in control file>
+ .
+ <Including paragraphs>
+
+# If you want to use GPL v2 or later for the /debian/* files use 
+# the following clauses, or change it to suit. Delete these two lines
+Files: debian/*
+Copyright: 2015 unknown <stuartl@unknown>
+License: GPL-2+
+ This package is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+ .
+ This package is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+ .
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>
+ .
+ On Debian systems, the complete text of the GNU General
+ Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
+
+# Please also look if there are files or directories which have a
+# different copyright/license attached and list them here.
+# Please avoid to pick license terms that are more restrictive than the
+# packaged work, as it may make Debian's contributions unacceptable upstream.
diff --git a/freedv/tags/1.2.2/freedv-dev/debian/docs b/freedv/tags/1.2.2/freedv-dev/debian/docs
new file mode 100644 (file)
index 0000000..acfbcb3
--- /dev/null
@@ -0,0 +1,3 @@
+credits.txt
+README.txt
+README.txt
diff --git a/freedv/tags/1.2.2/freedv-dev/debian/format b/freedv/tags/1.2.2/freedv-dev/debian/format
new file mode 100644 (file)
index 0000000..163aaf8
--- /dev/null
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/freedv/tags/1.2.2/freedv-dev/debian/rules b/freedv/tags/1.2.2/freedv-dev/debian/rules
new file mode 100755 (executable)
index 0000000..ad89215
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/bin/make -f
+# See debhelper(7) (uncomment to enable)
+# output every command that modifies files on the build system.
+#DH_VERBOSE = 1
+
+# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
+DPKG_EXPORT_BUILDFLAGS = 1
+include /usr/share/dpkg/default.mk
+
+# see FEATURE AREAS in dpkg-buildflags(1)
+#export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+
+# see ENVIRONMENT in dpkg-buildflags(1)
+# package maintainers to append CFLAGS
+#export DEB_CFLAGS_MAINT_APPEND  = -Wall -pedantic
+# package maintainers to append LDFLAGS
+#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
+
+
+# main packaging script based on dh7 syntax
+%:
+       dh $@ 
+
+# debmake generated override targets
+# This is example for Cmake (See http://bugs.debian.org/641051 )
+override_dh_auto_configure:
+       dh_auto_configure -- \
+              -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) \
+              -DUSE_STATIC_CODEC2=FALSE \
+              -DUSE_STATIC_SPEEXDSP=FALSE
diff --git a/freedv/tags/1.2.2/freedv-dev/script/spot.sh b/freedv/tags/1.2.2/freedv-dev/script/spot.sh
new file mode 100644 (file)
index 0000000..cb1309a
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# spot.sh
+# David Rowe Sep 2015
+#
+
+# Demo script for "spotting" based on FreeDV txt string. Posts a
+# date-stamped text file to a web server.  Called from FreeDV GUI
+# program when a callsign is received in the txt msg.
+
+
+# Q: how to remove repeated spots, or those close in time?
+#
+# Set up automated lftp login:
+#
+#   $ lftp ftp://username@server
+#   Password:
+#   lftp username@server:~>  set bmk:save-passwords true
+#   lftp username@server:~> bookmark add yourserver
+#   lftp username@server:~> bookmark list
+#   lftp username@server:~> quit
+
+SPOTFILE=/home/david/tmp/freedvspot.html
+FTPSERVER=ftp.rowetel.com
+
+echo `date -u` "  " $1 "<br>" >> $SPOTFILE
+tail -n 25 $SPOTFILE > /tmp/spot.tmp1
+mv /tmp/spot.tmp1 $SPOTFILE
+lftp -e "cd www;put $SPOTFILE;quit" $FTPSERVER
diff --git a/freedv/tags/1.2.2/freedv-dev/src/CMakeLists.txt b/freedv/tags/1.2.2/freedv-dev/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ef0798b
--- /dev/null
@@ -0,0 +1,79 @@
+set(FREEDV_SOURCES
+    dlg_audiooptions.cpp
+    dlg_filter.cpp
+    dlg_options.cpp
+    dlg_ptt.cpp
+    dlg_plugin.cpp
+    fdmdv2_main.cpp
+    fdmdv2_pa_wrapper.cpp
+    fdmdv2_plot.cpp
+    fdmdv2_plot_scalar.cpp
+    fdmdv2_plot_scatter.cpp
+    fdmdv2_plot_spectrum.cpp
+    fdmdv2_plot_waterfall.cpp
+    hamlib.cpp
+    serialport.cpp
+    topFrame.cpp
+    sox_biquad.c
+    comp.h
+    dlg_audiooptions.h
+    dlg_filter.h
+    dlg_options.h
+    dlg_ptt.h
+    fdmdv2_defines.h
+    fdmdv2_main.h
+    fdmdv2_pa_wrapper.h
+    fdmdv2_plot.h
+    fdmdv2_plot_scalar.h
+    fdmdv2_plot_scatter.h
+    fdmdv2_plot_spectrum.h
+    fdmdv2_plot_waterfall.h
+    hamlib.h
+    sox_biquad.h
+    sox/band.h
+    sox/biquad.c
+    sox/biquads.c
+    sox/biquad.h
+    sox/effects.c
+    sox/effects.h
+    sox/effects_i.c
+    sox/formats_i.c
+    sox/libsox.c
+    sox/sox.h
+    sox/sox_i.h
+    sox/soxomp.h
+    sox/util.h
+    sox/xmalloc.h
+    sox/xmalloc.c
+    topFrame.h
+    version.h
+)
+
+# WIN32 is needed for Windows GUI apps and is ignored for UNIX like systems.
+add_executable(freedv WIN32 ${FREEDV_SOURCES} ${RES_FILES})
+target_link_libraries(freedv ${FREEDV_LINK_LIBS})
+include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+if(FREEDV_STATIC_DEPS)
+    add_dependencies(freedv ${FREEDV_STATIC_DEPS})
+endif(FREEDV_STATIC_DEPS)
+install(TARGETS freedv
+    RUNTIME DESTINATION bin)
+
+# Custom commands to build OSX images.
+if(APPLE)
+    add_custom_command(
+        TARGET freedv
+        POST_BUILD
+        COMMAND mkdir ARGS -p FreeDV.app/Contents/MacOS
+        COMMAND mkdir ARGS -p FreeDV.app/Contents/Resources/English.lproj
+        COMMAND cp ARGS ${CMAKE_CURRENT_SOURCE_DIR}/info.plist FreeDV.app/Contents
+        COMMAND cp ARGS ${CMAKE_CURRENT_SOURCE_DIR}/freedv.icns FreeDV.app/Contents/Resources
+        COMMAND echo ARGS -n "APPL????" > FreeDV.app/Contents/PkgInfo
+        COMMAND cp ARGS freedv FreeDV.app/Contents/MacOS/FreeDV
+        COMMAND dylibbundler ARGS -od -b -x FreeDV.app/Contents/MacOS/FreeDV -d FreeDV.app/Contents/libs -p @executable_path/../libs/
+        COMMAND mkdir dist_tmp
+        COMMAND cp -r FreeDV.app dist_tmp
+        COMMAND hdiutil create -srcfolder dist_tmp/ -volname FreeDV -format UDZO ./FreeDV.dmg
+        COMMAND rm -rf dist_tmp
+    )
+endif(APPLE)
diff --git a/freedv/tags/1.2.2/freedv-dev/src/Makefile.win32 b/freedv/tags/1.2.2/freedv-dev/src/Makefile.win32
new file mode 100644 (file)
index 0000000..932e851
--- /dev/null
@@ -0,0 +1,52 @@
+# src/Makefile.win32
+# David Rowe 26 Oct 2012
+#
+# Makefile for Win32 on msys/Mingw to help David R get up to speed
+#
+# $ make -f Makefile.Win32
+
+CODEC2_PATH=$(HOME)/codec2-dev
+INCLUDE_PATH=/usr/local/include
+
+WX_CONFIG=wx-config
+WX_CPPFLAGS = $(shell $(WX_CONFIG) --cxxflags) -D__WXDEBUG__
+WX_LIBS = $(shell $(WX_CONFIG) --libs core, base, aui, adv, net)
+SVN_REVISION=$(shell svnversion)
+CODEC2_INC=$(CODEC2_PATH)/src 
+CODEC2_LIB=$(CODEC2_PATH)/build_win32/src/
+
+CPP_FLAGS = -D_NO_AUTOTOOLS_ -I$(INCLUDE_PATH) $(WX_CPPFLAGS) -I$(CODEC2_INC) -I../extern/include -I. -g -Wall -DSVN_REVISION=\"$(SVN_REVISION)\"
+LIBS = $(WX_LIBS) -L$(CODEC2_LIB) -lcodec2 -lm -lportaudiocpp -lportaudio -lpthread -lsndfile -lsamplerate -lhamlib -lsox -lspeexdsp
+
+OBJS = topFrame.o \
+fdmdv2_main.o \
+fdmdv2_plot.o \
+fdmdv2_plot_scalar.o \
+fdmdv2_plot_scatter.o \
+fdmdv2_plot_spectrum.o \
+fdmdv2_plot_waterfall.o \
+fdmdv2_pa_wrapper.o \
+dlg_audiooptions.o \
+dlg_ptt.o \
+dlg_options.o \
+dlg_filter.o \
+sox_biquad.o \
+hamlib.o \
+../../codec2-dev/src/golay23.o
+
+HDRS = version.h dlg_audiooptions.h dlg_ptt.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h topFrame.h varicode.h ../../codec2-dev/src/golay23.h hamlib.h
+
+all: freedv
+
+freedv: $(OBJS) 
+       g++ -o freedv $(OBJS) $(CPP_FLAGS) $(LIBS)
+
+%.o: %.cpp $(HDRS) Makefile.win32
+       g++ $(CPP_FLAGS) -c $< -o $@
+
+%.o: %.c $(HDRS) Makefile.win32
+       gcc $(CPP_FLAGS) -c $< -o $@
+
+clean:
+       rm -f *.o fdmdv2
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/afreedvplugin.c b/freedv/tags/1.2.2/freedv-dev/src/afreedvplugin.c
new file mode 100644 (file)
index 0000000..5fdc424
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+  afreedvplugin.c
+  David Rowe Feb 2016
+
+  Sample FreeDV plugin
+
+  TODO:
+     [ ] plugin to call back to functions
+     [ ] ability to list .so's/DLLs and scan
+     [ ] where do we put plugins?
+     [ ] Windows build and test environment
+
+  linux .so:
+    $ gcc -Wall -fPIC -c afreedvplugin.c
+    $ gcc -shared -Wl,-soname,afreedvplugin.so -o afreedvplugin.so afreedvplugin.o
+  win32 .dll:
+    $ i686-w64-mingw32-gcc -c afreedvplugin.c
+    $ i686-w64-mingw32-gcc -shared -o afreedvplugin.dll afreedvplugin.o -Wl,--out-implib,afreedvplugin_dll.a
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32_
+#define DLL __declspec(dllexport)
+#else
+#define DLL
+#endif
+
+
+#ifdef LATER
+/* functions plugin can call - not sure how to link to these */
+
+int plugin_alert(char string[]);
+int plugin_get_persistant(char name[], char value[]);
+int plugin_set_persistant(char name[], char value[]);
+#endif
+static int (*plugin_get_persistant)(char name[], char value[]);
+
+struct APLUGIN_STATES {
+    int symbol_rate;
+    int num_tones;
+    int counter;
+};
+
+/* plugin functions called by host, we need to write these */
+
+void DLL plugin_name(char name[]) {
+
+    sprintf(name, "aFreeDVplugIn");
+}
+
+/* 
+   Text fields will be created for nparams, using the names
+   in *param_names[].  These fields we be saved to persistent
+   storage as name/param_names[0], name/param_names[1] ....
+*/
+
+void DLL *plugin_open(char *param_names[], 
+                      int *nparams, 
+                      int (*aplugin_get_persistant)(char *, char *))
+{
+    struct APLUGIN_STATES *states;
+
+    /* set up function ptrs */
+
+    plugin_get_persistant = aplugin_get_persistant;
+    /* tell host how many persistent parameters we have and their names */
+
+    strcpy(param_names[0], "SymbolRate");
+    strcpy(param_names[1], "NumTones");
+    *nparams = 2;
+
+    /* init local states */
+
+    states = (struct APLUGIN_STATES *)malloc(sizeof(struct APLUGIN_STATES));
+    if (states == NULL) {
+        // TODO: plugin_alert("Problem starting plugin!");
+        return NULL;
+    }
+    states->counter = 0;
+    
+    return (void*)states;
+}
+
+void DLL plugin_close(void *states) {
+    free(states);
+}
+
+void DLL plugin_start(void *s) {
+    struct APLUGIN_STATES *states = (struct APLUGIN_STATES*)s;
+    char txt[80];
+
+    fprintf(stderr, "\nplugin_start\n");
+
+    (plugin_get_persistant)("SymbolRate",txt);
+    states->symbol_rate = atoi(txt);
+
+    (plugin_get_persistant)("NumTones",txt);
+    states->num_tones = atoi(txt);
+    
+    fprintf(stderr, "symbol_rate: %d num_tones: %d\n", states->symbol_rate, states->num_tones);
+}
+
+void DLL plugin_stop(void *states) {
+    fprintf(stderr, "\nplugin_stop\n");
+}
+
+void DLL plugin_rx_samples(void *s, short samples[], int n) {
+    struct APLUGIN_STATES *states = (struct APLUGIN_STATES*)s;
+    //fprintf(stderr, "Got n=%d samples!\n", n);
+    //fprintf(stderr, "samples[0] = %d  samples[%d-1] = %d  counter = %d\n", samples[0], n, samples[n-1], states->counter++);
+}
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/comp.h b/freedv/tags/1.2.2/freedv-dev/src/comp.h
new file mode 100644 (file)
index 0000000..a3a1bd9
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: comp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/08/09
+
+  Complex number definition.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __COMP__
+#define __COMP__
+
+/* Complex number */
+
+typedef struct
+{
+    float real;
+    float imag;
+} COMP;
+
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_audiooptions.cpp b/freedv/tags/1.2.2/freedv-dev/src/dlg_audiooptions.cpp
new file mode 100644 (file)
index 0000000..4e8cd98
--- /dev/null
@@ -0,0 +1,1264 @@
+//=========================================================================
+// Name:            AudioOptsDialog.cpp
+// Purpose:         Implements an Audio options selection dialog.
+//
+// Authors:         David Rowe, David Witten
+// License:
+//
+//  All rights reserved.
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//=========================================================================
+#include "fdmdv2_main.h"
+#include "dlg_audiooptions.h"
+
+// constants for test waveform plots
+
+#define TEST_WAVEFORM_X          180
+#define TEST_WAVEFORM_Y          180
+#define TEST_WAVEFORM_PLOT_TIME  2.0
+#define TEST_WAVEFORM_PLOT_FS    400
+#define TEST_BUF_SIZE           1024
+#define TEST_FS                 48000.0
+#define TEST_DT                 0.1      // time between plot updates in seconds
+#define TEST_WAVEFORM_PLOT_BUF  ((int)(DT*400))
+
+void AudioOptsDialog::Pa_Init(void)
+{
+    m_isPaInitialized = false;
+
+    if((pa_err = Pa_Initialize()) == paNoError)
+    {
+        m_isPaInitialized = true;
+    }
+    else
+    {
+        wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
+        return;
+    }
+}
+
+
+void AudioOptsDialog::buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, 
+                                        wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel)
+{
+    wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
+
+    wxPanel *panel = new wxPanel(parentPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
+    *plotScalar = new PlotScalar((wxFrame*) panel, 1, TEST_WAVEFORM_PLOT_TIME, 1.0/TEST_WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "", 1);
+    (*plotScalar)->SetClientSize(wxSize(TEST_WAVEFORM_X,TEST_WAVEFORM_Y));
+    bSizer1->Add(panel, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 8);
+
+    *btnTest = new wxButton(parentPanel, wxID_ANY, buttonLabel, wxDefaultPosition, wxDefaultSize);
+    bSizer1->Add(*btnTest, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0);
+
+    bSizer->Add(bSizer1, 0, wxALIGN_CENTER_HORIZONTAL |wxALIGN_CENTER_VERTICAL );
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// AudioOptsDialog()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+AudioOptsDialog::AudioOptsDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    //this->SetSizeHints(wxSize(850, 600), wxDefaultSize);
+    fprintf(stderr, "pos %d %d\n", pos.x, pos.y);
+    Pa_Init();
+
+    wxBoxSizer* mainSizer;
+    mainSizer = new wxBoxSizer(wxVERTICAL);
+    m_panel1 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer4;
+    bSizer4 = new wxBoxSizer(wxVERTICAL);
+    m_notebook1 = new wxNotebook(m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM);
+    m_panelRx = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer20;
+    bSizer20 = new wxBoxSizer(wxVERTICAL);
+    wxGridSizer* gSizer4;
+    gSizer4 = new wxGridSizer(2, 1, 0, 0);
+
+    // Rx In -----------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer2;
+    sbSizer2 = new wxStaticBoxSizer(new wxStaticBox(m_panelRx, wxID_ANY, _("From Radio")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer811a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlRxInDevices = new wxListCtrl(m_panelRx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer811a->Add(m_listCtrlRxInDevices, 1, wxALL|wxEXPAND, 1);
+
+    wxBoxSizer* bSizer811;
+    bSizer811 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText51 = new wxStaticText(m_panelRx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText51->Wrap(-1);
+    bSizer811->Add(m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_textCtrlRxIn = new wxTextCtrl(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer811->Add(m_textCtrlRxIn, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText6 = new wxStaticText(m_panelRx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText6->Wrap(-1);
+    bSizer811->Add(m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateRxIn = new wxComboBox(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer811->Add(m_cbSampleRateRxIn, 0, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    bSizer811a->Add(bSizer811, 0, wxEXPAND, 5);
+
+    sbSizer2->Add(bSizer811a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarRxIn, &m_btnRxInTest, m_panelRx, sbSizer2, _("Rec 2s"));
+
+    gSizer4->Add(sbSizer2, 1, wxEXPAND, 5);
+
+    // Rx Out -----------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer3;
+    sbSizer3 = new wxStaticBoxSizer(new wxStaticBox(m_panelRx, wxID_ANY, _("To Speaker/Headphones")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer81a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlRxOutDevices = new wxListCtrl(m_panelRx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer81a->Add(m_listCtrlRxOutDevices, 1, wxALL|wxEXPAND, 1);
+
+    wxBoxSizer* bSizer81;
+    bSizer81 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText9 = new wxStaticText(m_panelRx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText9->Wrap(-1);
+    bSizer81->Add(m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_textCtrlRxOut = new wxTextCtrl(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer81->Add(m_textCtrlRxOut, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText10 = new wxStaticText(m_panelRx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText10->Wrap(-1);
+    bSizer81->Add(m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateRxOut = new wxComboBox(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer81->Add(m_cbSampleRateRxOut, 0, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    bSizer81a->Add(bSizer81, 0, wxEXPAND, 5);
+
+    sbSizer3->Add(bSizer81a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarRxOut, &m_btnRxOutTest, m_panelRx, sbSizer3, _("Play 2s"));
+    gSizer4->Add(sbSizer3, 1, wxEXPAND, 2);
+    bSizer20->Add(gSizer4, 1, wxEXPAND, 1);
+    m_panelRx->SetSizer(bSizer20);
+    m_panelRx->Layout();
+    bSizer20->Fit(m_panelRx);
+    m_notebook1->AddPage(m_panelRx, _("Receive"), true);
+
+    // Tx Tab -------------------------------------------------------------------------------
+
+    m_panelTx = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer18;
+    bSizer18 = new wxBoxSizer(wxVERTICAL);
+    wxGridSizer* gSizer2;
+    gSizer2 = new wxGridSizer(2, 1, 0, 0);
+
+    // Tx In ----------------------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer22;
+    sbSizer22 = new wxStaticBoxSizer(new wxStaticBox(m_panelTx, wxID_ANY, _("From Microphone")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer83a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlTxInDevices = new wxListCtrl(m_panelTx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer83a->Add(m_listCtrlTxInDevices, 1, wxALL|wxEXPAND, 1);
+    wxBoxSizer* bSizer83;
+    bSizer83 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText12 = new wxStaticText(m_panelTx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText12->Wrap(-1);
+    bSizer83->Add(m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_textCtrlTxIn = new wxTextCtrl(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer83->Add(m_textCtrlTxIn, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText11 = new wxStaticText(m_panelTx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText11->Wrap(-1);
+    bSizer83->Add(m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateTxIn = new wxComboBox(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer83->Add(m_cbSampleRateTxIn, 0, wxALL, 1);
+
+    bSizer83a->Add(bSizer83, 0, wxEXPAND, 5);
+
+    sbSizer22->Add(bSizer83a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarTxIn, &m_btnTxInTest, m_panelTx, sbSizer22, _("Rec 2s"));
+
+    gSizer2->Add(sbSizer22, 1, wxEXPAND, 5);
+
+    // Tx Out ----------------------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer21;
+    sbSizer21 = new wxStaticBoxSizer(new wxStaticBox(m_panelTx, wxID_ANY, _("To Radio")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer82a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlTxOutDevices = new wxListCtrl(m_panelTx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer82a->Add(m_listCtrlTxOutDevices, 1, wxALL|wxEXPAND, 2);
+    wxBoxSizer* bSizer82;
+    bSizer82 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText81 = new wxStaticText(m_panelTx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText81->Wrap(-1);
+    bSizer82->Add(m_staticText81, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_textCtrlTxOut = new wxTextCtrl(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer82->Add(m_textCtrlTxOut, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText71 = new wxStaticText(m_panelTx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText71->Wrap(-1);
+    bSizer82->Add(m_staticText71, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateTxOut = new wxComboBox(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer82->Add(m_cbSampleRateTxOut, 0, wxALL, 1);
+
+    bSizer82a->Add(bSizer82, 0, wxEXPAND, 5);
+
+    sbSizer21->Add(bSizer82a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarTxOut, &m_btnTxOutTest, m_panelTx, sbSizer21, _("Play 2s"));
+
+    gSizer2->Add(sbSizer21, 1, wxEXPAND, 5);
+    bSizer18->Add(gSizer2, 1, wxEXPAND, 1);
+    m_panelTx->SetSizer(bSizer18);
+    m_panelTx->Layout();
+    bSizer18->Fit(m_panelTx);
+    m_notebook1->AddPage(m_panelTx, _("Transmit"), false);
+
+    // API Tab -------------------------------------------------------------------
+
+    m_panelAPI = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer12;
+    bSizer12 = new wxBoxSizer(wxHORIZONTAL);
+    wxGridSizer* gSizer31;
+    gSizer31 = new wxGridSizer(2, 1, 0, 0);
+    wxStaticBoxSizer* sbSizer1;
+    sbSizer1 = new wxStaticBoxSizer(new wxStaticBox(m_panelAPI, wxID_ANY, _("PortAudio")), wxVERTICAL);
+
+    wxGridSizer* gSizer3;
+    gSizer3 = new wxGridSizer(4, 2, 0, 0);
+
+    m_staticText7 = new wxStaticText(m_panelAPI, wxID_ANY, _("PortAudio Version String:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText7->Wrap(-1);
+    gSizer3->Add(m_staticText7, 1, wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+    m_textStringVer = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    gSizer3->Add(m_textStringVer, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText8 = new wxStaticText(m_panelAPI, wxID_ANY, _("PortAudio Int Version:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText8->Wrap(-1);
+    gSizer3->Add(m_staticText8, 1, wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+    m_textIntVer = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    gSizer3->Add(m_textIntVer, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText5 = new wxStaticText(m_panelAPI, wxID_ANY, _("Device Count:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText5->Wrap(-1);
+    gSizer3->Add(m_staticText5, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 10);
+    m_textCDevCount = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    gSizer3->Add(m_textCDevCount, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText4 = new wxStaticText(m_panelAPI, wxID_ANY, _("API Count:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText4->Wrap(-1);
+    gSizer3->Add(m_staticText4, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 10);
+    m_textAPICount = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    m_textAPICount->SetMaxSize(wxSize(45,-1));
+    gSizer3->Add(m_textAPICount, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    sbSizer1->Add(gSizer3, 1, wxEXPAND, 2);
+    gSizer31->Add(sbSizer1, 1, wxEXPAND, 2);
+    wxStaticBoxSizer* sbSizer6;
+    sbSizer6 = new wxStaticBoxSizer(new wxStaticBox(m_panelAPI, wxID_ANY, _("Other")), wxVERTICAL);
+    gSizer31->Add(sbSizer6, 1, wxEXPAND, 5);
+    bSizer12->Add(gSizer31, 1, wxEXPAND, 5);
+    m_panelAPI->SetSizer(bSizer12);
+    m_panelAPI->Layout();
+    bSizer12->Fit(m_panelAPI);
+    m_notebook1->AddPage(m_panelAPI, _("API Info"), false);
+    bSizer4->Add(m_notebook1, 1, wxEXPAND | wxALL, 0);
+    m_panel1->SetSizer(bSizer4);
+    m_panel1->Layout();
+    bSizer4->Fit(m_panel1);
+    mainSizer->Add(m_panel1, 1, wxEXPAND | wxALL, 1);
+
+    wxBoxSizer* bSizer6;
+    bSizer6 = new wxBoxSizer(wxHORIZONTAL);
+    m_btnRefresh = new wxButton(this, wxID_ANY, _("Refresh"), wxDefaultPosition, wxDefaultSize, 0);
+    bSizer6->Add(m_btnRefresh, 0, wxALIGN_CENTER|wxALL, 2);
+
+    m_sdbSizer1 = new wxStdDialogButtonSizer();
+
+    m_sdbSizer1OK = new wxButton(this, wxID_OK);
+    m_sdbSizer1->AddButton(m_sdbSizer1OK);
+
+    m_sdbSizer1Cancel = new wxButton(this, wxID_CANCEL);
+    m_sdbSizer1->AddButton(m_sdbSizer1Cancel);
+
+    m_sdbSizer1Apply = new wxButton(this, wxID_APPLY);
+    m_sdbSizer1->AddButton(m_sdbSizer1Apply);
+
+    m_sdbSizer1->Realize();
+
+    bSizer6->Add(m_sdbSizer1, 1, wxALIGN_CENTER_VERTICAL, 2);
+    mainSizer->Add(bSizer6, 0, wxEXPAND, 2);
+    this->SetSizer(mainSizer);
+    this->Layout();
+    this->Centre(wxBOTH);
+//    this->Centre(wxBOTH);
+
+    m_notebook1->SetSelection(0);
+
+    showAPIInfo();
+    m_RxInDevices.m_listDevices   = m_listCtrlRxInDevices;
+    m_RxInDevices.direction       = AUDIO_IN;
+    m_RxInDevices.m_textDevice    = m_textCtrlRxIn;
+    m_RxInDevices.m_cbSampleRate  = m_cbSampleRateRxIn;
+
+    m_RxOutDevices.m_listDevices  = m_listCtrlRxOutDevices;
+    m_RxOutDevices.direction      = AUDIO_OUT;
+    m_RxOutDevices.m_textDevice   = m_textCtrlRxOut;
+    m_RxOutDevices.m_cbSampleRate = m_cbSampleRateRxOut;
+
+    m_TxInDevices.m_listDevices   = m_listCtrlTxInDevices;
+    m_TxInDevices.direction       = AUDIO_IN;
+    m_TxInDevices.m_textDevice    = m_textCtrlTxIn;
+    m_TxInDevices.m_cbSampleRate  = m_cbSampleRateTxIn;
+
+    m_TxOutDevices.m_listDevices  = m_listCtrlTxOutDevices;
+    m_TxOutDevices.direction      = AUDIO_OUT;
+    m_TxOutDevices.m_textDevice   = m_textCtrlTxOut;
+    m_TxOutDevices.m_cbSampleRate = m_cbSampleRateTxOut;
+
+    populateParams(m_RxInDevices);
+    populateParams(m_RxOutDevices);
+    populateParams(m_TxInDevices);
+    populateParams(m_TxOutDevices);
+
+    m_listCtrlRxInDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnRxInDeviceSelect ), NULL, this );
+    m_listCtrlRxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnRxOutDeviceSelect ), NULL, this );
+    m_listCtrlTxInDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxInDeviceSelect ), NULL, this );
+    m_listCtrlTxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxOutDeviceSelect ), NULL, this );
+
+    // wire up test buttons
+    m_btnRxInTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+    m_btnRxOutTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxOutTest ), NULL, this );
+    m_btnTxInTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxInTest ), NULL, this );
+    m_btnTxOutTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxOutTest ), NULL, this );
+
+    m_btnRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRefreshClick ), NULL, this );
+    m_sdbSizer1Apply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnApplyAudioParameters ), NULL, this );
+    m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnCancelAudioParameters ), NULL, this );
+    m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnOkAudioParameters ), NULL, this );
+/*
+        void OnClose( wxCloseEvent& event ) { event.Skip(); }
+        void OnHibernate( wxActivateEvent& event ) { event.Skip(); }
+        void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
+        void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
+*/
+//    this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(AudioOptsDialog::OnClose));
+    this->Connect(wxEVT_HIBERNATE, wxActivateEventHandler(AudioOptsDialog::OnHibernate));
+    this->Connect(wxEVT_ICONIZE, wxIconizeEventHandler(AudioOptsDialog::OnIconize));
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(AudioOptsDialog::OnInitDialog));
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// ~AudioOptsDialog()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+AudioOptsDialog::~AudioOptsDialog()
+{
+    Pa_Terminate();
+
+    // Disconnect Events
+    this->Disconnect(wxEVT_HIBERNATE, wxActivateEventHandler(AudioOptsDialog::OnHibernate));
+    this->Disconnect(wxEVT_ICONIZE, wxIconizeEventHandler(AudioOptsDialog::OnIconize));
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(AudioOptsDialog::OnInitDialog));
+
+    m_listCtrlRxInDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnRxInDeviceSelect), NULL, this);
+    m_listCtrlRxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnRxOutDeviceSelect), NULL, this);
+    m_listCtrlTxInDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxInDeviceSelect), NULL, this);
+    m_listCtrlTxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxOutDeviceSelect), NULL, this);
+
+    m_btnRxInTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+    m_btnRxOutTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxOutTest ), NULL, this );
+    m_btnTxInTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxInTest ), NULL, this );
+    m_btnTxOutTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxOutTest ), NULL, this );
+
+    m_btnRefresh->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnRefreshClick), NULL, this);
+    m_sdbSizer1Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnApplyAudioParameters), NULL, this);
+    m_sdbSizer1Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnCancelAudioParameters), NULL, this);
+    m_sdbSizer1OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnOkAudioParameters), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnInitDialog( wxInitDialogEvent& event )
+{
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//
+// helper function to look up name of devNum, and if it exists write
+// name to textCtrl.  Used to trap dissapearing devices.
+//-------------------------------------------------------------------------
+int AudioOptsDialog::setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum)
+{
+    int i, aDevNum, found_devNum;
+
+    // ignore last list entry as it is the "none" entry
+
+    found_devNum = 0;
+    for(i=0; i<listCtrl->GetItemCount()-1; i++) {
+        aDevNum = wxAtoi(listCtrl->GetItemText(i, 1));
+        //printf("aDevNum: %d devNum: %d\n", aDevNum, devNum);
+        if (aDevNum == devNum) {
+            found_devNum = 1;
+            textCtrl->SetValue(listCtrl->GetItemText(i, 0) + " (" + wxString::Format(wxT("%i"),devNum) + ")");
+            printf("setting focus of %d\n", i);
+            listCtrl->SetItemState(i, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
+        }
+    }
+
+    if (found_devNum) 
+        return devNum;
+    else {
+        textCtrl->SetValue("none");
+        return -1;
+    }
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+int AudioOptsDialog::ExchangeData(int inout)
+{
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        // Map sound card device numbers to tx/rx device numbers depending
+        // on number of sound cards in use
+
+        printf("EXCHANGE_DATA_IN:\n");
+        printf("  g_nSoundCards: %d\n", g_nSoundCards);
+        printf("  g_soundCard1InDeviceNum: %d\n", g_soundCard1InDeviceNum);
+        printf("  g_soundCard1OutDeviceNum: %d\n", g_soundCard1OutDeviceNum);
+        printf("  g_soundCard1SampleRate: %d\n", g_soundCard1SampleRate);
+        printf("  g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+        printf("  g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+        printf("  g_soundCard2SampleRate: %d\n", g_soundCard2SampleRate);
+
+        if (g_nSoundCards == 0) {
+            m_textCtrlRxIn ->SetValue("none"); rxInAudioDeviceNum  = -1;
+            m_textCtrlRxOut->SetValue("none"); rxOutAudioDeviceNum = -1;
+            m_textCtrlTxIn ->SetValue("none"); txInAudioDeviceNum  = -1;
+            m_textCtrlTxOut->SetValue("none"); txOutAudioDeviceNum = -1;           
+        }
+
+        if (g_nSoundCards == 1) {
+            rxInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlRxIn, 
+                                                           m_listCtrlRxInDevices, 
+                                                           g_soundCard1InDeviceNum);
+
+            rxOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlRxOut, 
+                                                           m_listCtrlRxOutDevices, 
+                                                           g_soundCard1OutDeviceNum);
+
+            if ((rxInAudioDeviceNum != -1) && (rxInAudioDeviceNum != -1)) {
+                m_cbSampleRateRxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+                m_cbSampleRateRxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+            }
+
+            m_textCtrlTxIn ->SetValue("none"); txInAudioDeviceNum  = -1;
+            m_textCtrlTxOut->SetValue("none"); txOutAudioDeviceNum = -1;           
+        }
+
+        if (g_nSoundCards == 2) {
+            rxInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlRxIn, 
+                                                           m_listCtrlRxInDevices, 
+                                                           g_soundCard1InDeviceNum);
+
+            rxOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlRxOut, 
+                                                           m_listCtrlRxOutDevices, 
+                                                           g_soundCard2OutDeviceNum);
+
+            txInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlTxIn, 
+                                                           m_listCtrlTxInDevices, 
+                                                           g_soundCard2InDeviceNum);
+
+            txOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlTxOut, 
+                                                           m_listCtrlTxOutDevices, 
+                                                           g_soundCard1OutDeviceNum);
+
+            if ((rxInAudioDeviceNum != -1) && (txOutAudioDeviceNum != -1)) {
+                m_cbSampleRateRxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+                m_cbSampleRateTxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+            }
+
+            if ((txInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1)) {
+                m_cbSampleRateTxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard2SampleRate));
+                m_cbSampleRateRxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard2SampleRate));
+            }
+        }
+        printf("  rxInAudioDeviceNum: %d\n  rxOutAudioDeviceNum: %d\n  txInAudioDeviceNum: %d\n  txOutAudioDeviceNum: %d\n",
+               rxInAudioDeviceNum, rxOutAudioDeviceNum, txInAudioDeviceNum, txOutAudioDeviceNum);
+    }
+
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        int valid_one_card_config = 0;
+        int valid_two_card_config = 0;
+        wxString sampleRate1, sampleRate2;
+
+        printf("EXCHANGE_DATA_OUT:\n");
+        printf("  rxInAudioDeviceNum: %d\n  rxOutAudioDeviceNum: %d\n  txInAudioDeviceNum: %d\n  txOutAudioDeviceNum: %d\n",
+               rxInAudioDeviceNum, rxOutAudioDeviceNum, txInAudioDeviceNum, txOutAudioDeviceNum);
+
+        // ---------------------------------------------------------------
+        // check we have a valid 1 or 2 sound card configuration
+        // ---------------------------------------------------------------
+
+        // one sound card config, tx device numbers should be set to -1 
+
+        if ((rxInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1) &&
+            (txInAudioDeviceNum == -1) && (txOutAudioDeviceNum == -1)) {
+            valid_one_card_config = 1; 
+
+            // in and out sample rate must be the same, as there is one callback
+            
+            sampleRate1 = m_cbSampleRateRxIn->GetValue();
+            if (!sampleRate1.IsSameAs(m_cbSampleRateRxOut->GetValue())) {
+                wxMessageBox(wxT("With a single sound card the Sample Rate of "
+                                 "From Radio and To Speaker/Headphones must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+        }
+
+        // two card configuration
+
+        if ((rxInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1) &&
+            (txInAudioDeviceNum != -1) && (txOutAudioDeviceNum != -1)) {
+
+            valid_two_card_config = 1; 
+
+            // Check we haven't doubled up on sound devices
+
+            if (rxInAudioDeviceNum == txInAudioDeviceNum) {
+                wxMessageBox(wxT("You must use different devices for From Radio and From Microphone"), wxT(""), wxOK);
+                return -1;
+            }
+
+            if (rxOutAudioDeviceNum == txOutAudioDeviceNum) {
+                wxMessageBox(wxT("You must use different devices for To Radio and To Speaker/Headphones"), wxT(""), wxOK);
+                return -1;
+            }
+
+            // Check sample rates for callback 1 devices are the same,
+            // as input and output are handled synchronously by one
+            // portaudio callback
+            
+            sampleRate1 = m_cbSampleRateRxIn->GetValue();
+            if (!sampleRate1.IsSameAs(m_cbSampleRateTxOut->GetValue())) {
+                wxMessageBox(wxT("With two sound cards the Sample Rate "
+                                 "of From Radio and To Radio must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+            // check sample rate for callback 2 devices is the same
+
+            sampleRate2 = m_cbSampleRateTxIn->GetValue();
+            if (!sampleRate2.IsSameAs(m_cbSampleRateRxOut->GetValue())) {
+                wxMessageBox(wxT("With two sound cards the Sample Rate of "
+                                 "From Microphone and To Speaker/Headphones must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+        }
+
+        printf("  valid_one_card_config: %d  valid_two_card_config: %d\n", valid_one_card_config, valid_two_card_config);
+
+        if (!valid_one_card_config && !valid_two_card_config) {
+            wxMessageBox(wxT("Invalid one or two sound card configuration"), wxT(""), wxOK);
+            return -1;
+        }
+
+        // ---------------------------------------------------------------
+        // Map Rx/TX device numbers to sound card device numbers used
+        // in callbacks. Portaudio uses one callback per sound card so
+        // we have to be soundcard oriented at run time rather than
+        // Tx/Rx oriented as in this dialog.
+        // ---------------------------------------------------------------
+        g_nSoundCards = 0;
+        g_soundCard1InDeviceNum = g_soundCard1OutDeviceNum = g_soundCard2InDeviceNum = g_soundCard2OutDeviceNum = -1;
+
+        if (valid_one_card_config) {
+
+            // Only callback 1 used
+
+            g_nSoundCards = 1;
+            g_soundCard1InDeviceNum  = rxInAudioDeviceNum;
+            g_soundCard1OutDeviceNum = rxOutAudioDeviceNum;
+            g_soundCard1SampleRate = wxAtoi(sampleRate1);
+        }
+
+        if (valid_two_card_config) {
+            g_nSoundCards = 2;
+            g_soundCard1InDeviceNum  = rxInAudioDeviceNum;
+            g_soundCard1OutDeviceNum = txOutAudioDeviceNum;
+            g_soundCard1SampleRate   = wxAtoi(sampleRate1);
+            g_soundCard2InDeviceNum  = txInAudioDeviceNum;
+            g_soundCard2OutDeviceNum = rxOutAudioDeviceNum;
+            g_soundCard2SampleRate   = wxAtoi(sampleRate2);
+        }
+
+        printf("  g_nSoundCards: %d\n", g_nSoundCards);
+        printf("  g_soundCard1InDeviceNum: %d\n", g_soundCard1InDeviceNum);
+        printf("  g_soundCard1OutDeviceNum: %d\n", g_soundCard1OutDeviceNum);
+        printf("  g_soundCard1SampleRate: %d\n", g_soundCard1SampleRate);
+        printf("  g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+        printf("  g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+        printf("  g_soundCard2SampleRate: %d\n", g_soundCard2SampleRate);
+
+        wxConfigBase *pConfig = wxConfigBase::Get();
+        pConfig->Write(wxT("/Audio/soundCard1InDeviceNum"),       g_soundCard1InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1OutDeviceNum"),      g_soundCard1OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1SampleRate"),        g_soundCard1SampleRate );
+
+        pConfig->Write(wxT("/Audio/soundCard2InDeviceNum"),       g_soundCard2InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2OutDeviceNum"),      g_soundCard2OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2SampleRate"),        g_soundCard2SampleRate );
+
+        pConfig->Flush();
+        delete wxConfigBase::Set((wxConfigBase *) NULL);
+    }
+
+    return 0;
+}
+
+//-------------------------------------------------------------------------
+// buildListOfSupportedSampleRates()
+//-------------------------------------------------------------------------
+int AudioOptsDialog:: buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out)
+{
+    // every sound device has a different list of supported sample rates, so
+    // we work out which ones are supported and populate the list ctrl
+
+    static double standardSampleRates[] =
+    {
+        8000.0,     9600.0,
+        11025.0,    12000.0,
+        16000.0,    22050.0,
+        24000.0,    32000.0,
+        44100.0,    48000.0,
+        88200.0,    96000.0,
+        192000.0,   -1          // negative terminated  list
+    };
+
+    const PaDeviceInfo  *deviceInfo;
+    PaStreamParameters   inputParameters, outputParameters;
+    PaError              err;
+    wxString             str;
+    int                  i, numSampleRates;
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        printf("Pa_GetDeviceInfo(%d) failed!\n", devNum);
+        cbSampleRate->Clear();
+        return 0;
+    }
+
+    inputParameters.device = devNum;
+    inputParameters.channelCount = deviceInfo->maxInputChannels;
+    inputParameters.sampleFormat = paInt16;
+    inputParameters.suggestedLatency = 0;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+        
+    outputParameters.device = devNum;
+    outputParameters.channelCount = deviceInfo->maxOutputChannels;
+    outputParameters.sampleFormat = paInt16;
+    outputParameters.suggestedLatency = 0;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    
+    cbSampleRate->Clear();
+    //printf("devNum %d supports: ", devNum);
+    numSampleRates = 0;
+    for(i = 0; standardSampleRates[i] > 0; i++)
+    {      
+        if (in_out == AUDIO_IN)
+            err = Pa_IsFormatSupported(&inputParameters, NULL, standardSampleRates[i]);
+        else
+            err = Pa_IsFormatSupported(NULL, &outputParameters, standardSampleRates[i]);
+
+        if( err == paFormatIsSupported ) {
+            str.Printf("%i", (int)standardSampleRates[i]);
+            cbSampleRate->AppendString(str);
+            printf("%i ", (int)standardSampleRates[i]);
+            numSampleRates++;
+        }
+    }
+    printf("\n");
+
+    return numSampleRates;
+}
+
+//-------------------------------------------------------------------------
+// showAPIInfo()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::showAPIInfo()
+{
+    wxString    strval;
+    int         apiVersion;
+    int         apiCount        = 0;
+    int         numDevices      = 0;
+
+    strval = Pa_GetVersionText();
+    m_textStringVer->SetLabel(strval);
+
+    apiVersion = Pa_GetVersion();
+    strval.Printf(wxT("%d"), apiVersion);
+    m_textIntVer->SetLabel(strval);
+
+    apiCount = Pa_GetHostApiCount();
+    strval.Printf(wxT("%d"), apiCount);
+    m_textAPICount->SetLabel(strval);
+
+    numDevices = Pa_GetDeviceCount();
+    strval.Printf(wxT("%d"), numDevices);
+    m_textCDevCount->SetLabel(strval);
+}
+
+//-------------------------------------------------------------------------
+// populateParams()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::populateParams(AudioInfoDisplay ai)
+{
+    const       PaDeviceInfo *deviceInfo = NULL;
+    wxListCtrl* ctrl    = ai.m_listDevices;
+    int         in_out  = ai.direction;
+    long        idx;
+    int         numDevices;
+    wxListItem  listItem;
+    wxString    buf;
+    int         devn;
+    int         col = 0;
+
+    numDevices = Pa_GetDeviceCount();
+
+    if(ctrl->GetColumnCount() > 0)
+    {
+        ctrl->ClearAll();
+    }
+
+    listItem.SetAlign(wxLIST_FORMAT_LEFT);
+    listItem.SetText(wxT("Device"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 300);
+
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("ID"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 45);
+
+    listItem.SetAlign(wxLIST_FORMAT_LEFT);
+    listItem.SetText(wxT("API"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+
+    if(in_out == AUDIO_IN)
+    {
+        listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+        listItem.SetText(wxT("Default Sample Rate"));
+        idx = ctrl->InsertColumn(col, listItem);
+        ctrl->SetColumnWidth(col++, 160);
+    }
+    else if(in_out == AUDIO_OUT)
+    {
+        listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+        listItem.SetText(wxT("Default Sample Rate"));
+        idx = ctrl->InsertColumn(col, listItem);
+        ctrl->SetColumnWidth(col++, 160);
+    }
+
+    #ifdef LATENCY
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("Min Latency"));
+    ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("Max Latency"));
+    ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+    #endif
+
+    for(devn = 0; devn < numDevices; devn++)
+    {
+        buf.Printf(wxT(""));
+        deviceInfo = Pa_GetDeviceInfo(devn);
+        if( ((in_out == AUDIO_IN) && (deviceInfo->maxInputChannels > 0)) ||
+            ((in_out == AUDIO_OUT) && (deviceInfo->maxOutputChannels > 0)))
+        {
+            col = 0;
+            buf.Printf(wxT("%s"), deviceInfo->name);
+            idx = ctrl->InsertItem(ctrl->GetItemCount(), buf);
+            col++;
+                
+            buf.Printf(wxT("%d"), devn);
+            ctrl->SetItem(idx, col++, buf);
+
+            buf.Printf(wxT("%s"), Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+            ctrl->SetItem(idx, col++, buf);
+
+            buf.Printf(wxT("%i"), (int)deviceInfo->defaultSampleRate);
+            ctrl->SetItem(idx, col++, buf);
+
+            #ifdef LATENCY
+            if (in_out == AUDIO_IN)
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultLowInputLatency);
+            else
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultLowOutputLatency);               
+            ctrl->SetItem(idx, col++, buf);
+
+            if (in_out == AUDIO_IN)
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultHighInputLatency);
+            else
+                 buf.Printf(wxT("%8.4f"), deviceInfo->defaultHighOutputLatency);             
+            ctrl->SetItem(idx, col++, buf);
+            #endif
+        }        
+    }
+
+    // add "none" option at end
+
+    buf.Printf(wxT("%s"), "none");
+    idx = ctrl->InsertItem(ctrl->GetItemCount(), buf);
+}
+
+//-------------------------------------------------------------------------
+// OnDeviceSelect()
+//
+// helper function to set up "Device:" and "Sample Rate:" fields when
+// we click on a line in the list of devices box
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnDeviceSelect(wxComboBox *cbSampleRate, 
+                                     wxTextCtrl *textCtrl, 
+                                     int        *devNum, 
+                                     wxListCtrl *listCtrlDevices, 
+                                     int         index,
+                                     int         in_out)
+{
+
+    wxString devName = listCtrlDevices->GetItemText(index, 0);
+     if (devName.IsSameAs("none")) {
+        *devNum = -1;
+        textCtrl->SetValue("none");
+    }
+    else {
+        *devNum = wxAtoi(listCtrlDevices->GetItemText(index, 1));
+        textCtrl->SetValue(devName + " (" + wxString::Format(wxT("%i"),*devNum) + ")");
+
+        int numSampleRates = buildListOfSupportedSampleRates(cbSampleRate, *devNum, in_out);
+        if (numSampleRates) {
+            wxString defSampleRate = listCtrlDevices->GetItemText(index, 3);        
+            cbSampleRate->SetValue(defSampleRate);
+        }
+        else {
+             cbSampleRate->SetValue("None");           
+        }
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnRxInDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxInDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateRxIn, 
+                   m_textCtrlRxIn, 
+                   &rxInAudioDeviceNum, 
+                   m_listCtrlRxInDevices, 
+                   evt.GetIndex(),
+                   AUDIO_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnRxOutDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxOutDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateRxOut, 
+                   m_textCtrlRxOut, 
+                   &rxOutAudioDeviceNum, 
+                   m_listCtrlRxOutDevices, 
+                   evt.GetIndex(),
+                   AUDIO_OUT);
+}
+
+//-------------------------------------------------------------------------
+// OnTxInDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxInDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateTxIn, 
+                   m_textCtrlTxIn, 
+                   &txInAudioDeviceNum, 
+                   m_listCtrlTxInDevices, 
+                   evt.GetIndex(),
+                   AUDIO_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnTxOutDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxOutDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateTxOut, 
+                   m_textCtrlTxOut, 
+                   &txOutAudioDeviceNum, 
+                   m_listCtrlTxOutDevices, 
+                   evt.GetIndex(),
+                   AUDIO_OUT);
+}
+
+//-------------------------------------------------------------------------
+// plotDeviceInputForAFewSecs()
+//
+// opens a record device and plots the input speech for a few seconds.  This is "modal" using
+// synchronous portaudio functions, so the GUI will not respond until after test sample has been
+// taken
+//-------------------------------------------------------------------------
+void AudioOptsDialog::plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar) {
+    PaStreamParameters  inputParameters;
+    const PaDeviceInfo *deviceInfo = NULL;
+    PaStream           *stream = NULL;
+    PaError             err;
+    short               in48k_stereo_short[2*TEST_BUF_SIZE];
+    short               in48k_short[TEST_BUF_SIZE];
+    short               in8k_short[TEST_BUF_SIZE];
+    int                 numDevices, nBufs, i, j, src_error,inputChannels;
+    float               t;
+    SRC_STATE          *src;
+    FIFO               *fifo;
+
+    // a basic sanity check
+    numDevices = Pa_GetDeviceCount();
+    if (devNum >= numDevices)
+        return;
+    if (devNum < 0)
+        return;
+    printf("devNum %d\n", devNum);
+
+    fifo = fifo_create((int)(DT*TEST_WAVEFORM_PLOT_FS*2)); assert(fifo != NULL);
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(src != NULL);
+
+    // work out how many input channels this device supports.
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card "), wxT("Error"), wxOK);
+        return;
+    }
+    if (deviceInfo->maxInputChannels == 1)
+        inputChannels = 1;
+    else
+        inputChannels = 2;
+
+    // open device
+
+    inputParameters.device = devNum;
+    inputParameters.channelCount = inputChannels;
+    inputParameters.sampleFormat = paInt16;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    nBufs = TEST_WAVEFORM_PLOT_TIME*TEST_FS/TEST_BUF_SIZE;
+    printf("inputChannels: %d nBufs %d\n", inputChannels, nBufs);
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,
+              TEST_FS,
+              TEST_BUF_SIZE,
+              paClipOff,    
+              NULL,       // no callback, use blocking API
+              NULL ); 
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't initialise sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    err = Pa_StartStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't start sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    for(i=0, t=0.0; i<nBufs; i++, t+=(float)TEST_BUF_SIZE/TEST_FS) {
+        Pa_ReadStream(stream, in48k_stereo_short, TEST_BUF_SIZE);
+        if (inputChannels == 2) {
+            for(j=0; j<TEST_BUF_SIZE; j++)
+                in48k_short[j] = in48k_stereo_short[2*j]; // left channel only
+        }
+        else {
+            for(j=0; j<TEST_BUF_SIZE; j++)
+                in48k_short[j] = in48k_stereo_short[j]; 
+        }
+        int n8k = resample(src, in8k_short, in48k_short, 8000, TEST_FS, TEST_BUF_SIZE, TEST_BUF_SIZE);
+        resample_for_plot(fifo, in8k_short, n8k, FS);
+
+        // every TEST_DT seconds update plot, unfortunately plot
+        // doesnt get updated to end as we are blocking events in this
+        // function
+
+        if (t > TEST_DT) {
+            t -= TEST_DT;
+            short plotSamples[TEST_WAVEFORM_PLOT_BUF];
+            if (fifo_read(fifo, plotSamples, TEST_WAVEFORM_PLOT_BUF))
+                memset(plotSamples, 0, TEST_WAVEFORM_PLOT_BUF*sizeof(short));
+            plotScalar->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
+            plotScalar->Refresh();
+       }
+    }
+   
+    err = Pa_StopStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't stop sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+    Pa_CloseStream(stream);
+
+    fifo_destroy(fifo);
+    src_delete(src);
+}
+
+//-------------------------------------------------------------------------
+// plotDeviceOutputForAFewSecs()
+//
+// opens a play device and plays a tone for a few seconds.  This is "modal" using
+// synchronous portaudio functions, so the GUI will not respond until after test sample has been
+// taken.  Also plots a pretty picture like the record versions
+//-------------------------------------------------------------------------
+void AudioOptsDialog::plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar) {
+    PaStreamParameters  outputParameters;
+    const PaDeviceInfo *deviceInfo = NULL;
+    PaStream           *stream = NULL;
+    PaError             err;
+    short               out48k_stereo_short[2*TEST_BUF_SIZE];
+    short               out48k_short[TEST_BUF_SIZE];
+    short               out8k_short[TEST_BUF_SIZE];
+    int                 numDevices, nBufs, i, j, src_error, n, outputChannels;
+    float               t;
+    SRC_STATE          *src;
+    FIFO               *fifo;
+
+    // a basic sanity check
+    numDevices = Pa_GetDeviceCount();
+    if (devNum >= numDevices)
+        return;
+    if (devNum < 0)
+        return;
+
+    fifo = fifo_create((int)(DT*TEST_WAVEFORM_PLOT_FS*2)); assert(fifo != NULL);
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(src != NULL);
+
+    // work out how many output channels this device supports.
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card "), wxT("Error"), wxOK);
+        return;
+    }
+    if (deviceInfo->maxOutputChannels == 1)
+        outputChannels = 1;
+    else
+        outputChannels = 2;
+
+    printf("outputChannels: %d\n", outputChannels);
+
+    outputParameters.device = devNum;
+    outputParameters.channelCount = outputChannels;
+    outputParameters.sampleFormat = paInt16;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    nBufs = TEST_WAVEFORM_PLOT_TIME*TEST_FS/TEST_BUF_SIZE;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL,
+              &outputParameters,
+              TEST_FS,
+              TEST_BUF_SIZE,
+              paClipOff,    
+              NULL,       // no callback, use blocking API
+              NULL ); 
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't initialise sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    err = Pa_StartStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't start sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    for(i=0, t=0.0, n=0; i<nBufs; i++, t+=(float)TEST_BUF_SIZE/TEST_FS) {
+        for(j=0; j<TEST_BUF_SIZE; j++,n++) {
+            out48k_short[j] = 2000.0*cos(6.2832*(n++)*400.0/TEST_FS);
+            if (outputChannels == 2) {
+                out48k_stereo_short[2*j] = out48k_short[j];   // left channel
+                out48k_stereo_short[2*j+1] = out48k_short[j]; // right channel
+            }
+            else {
+                out48k_stereo_short[j] = out48k_short[j];     // mono
+            }
+        }
+        Pa_WriteStream(stream, out48k_stereo_short, TEST_BUF_SIZE);
+
+        // convert back to 8kHz just for plotting
+        int n8k = resample(src, out8k_short, out48k_short, 8000, TEST_FS, TEST_BUF_SIZE, TEST_BUF_SIZE);
+        resample_for_plot(fifo, out8k_short, n8k, FS);
+
+        // every TEST_DT seconds update plot
+
+        if (t > TEST_DT) {
+            t -= TEST_DT;
+            short plotSamples[TEST_WAVEFORM_PLOT_BUF];
+            if (fifo_read(fifo, plotSamples, TEST_WAVEFORM_PLOT_BUF))
+                memset(plotSamples, 0, TEST_WAVEFORM_PLOT_BUF*sizeof(short));
+            plotScalar->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
+            plotScalar->Refresh();
+       }
+    }
+   
+    err = Pa_StopStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't stop sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+    Pa_CloseStream(stream);
+
+    fifo_destroy(fifo);
+    src_delete(src);
+}
+
+//-------------------------------------------------------------------------
+// OnRxInTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxInTest(wxCommandEvent& event)
+{
+    plotDeviceInputForAFewSecs(rxInAudioDeviceNum, m_plotScalarRxIn);
+}
+
+//-------------------------------------------------------------------------
+// OnRxOutTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxOutTest(wxCommandEvent& event)
+{
+    plotDeviceOutputForAFewSecs(rxOutAudioDeviceNum, m_plotScalarRxOut);
+}
+
+//-------------------------------------------------------------------------
+// OnTxInTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxInTest(wxCommandEvent& event)
+{
+    plotDeviceInputForAFewSecs(txInAudioDeviceNum, m_plotScalarTxIn);
+}
+
+//-------------------------------------------------------------------------
+// OnTxOutTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxOutTest(wxCommandEvent& event)
+{
+    plotDeviceOutputForAFewSecs(txOutAudioDeviceNum, m_plotScalarTxOut);
+}
+
+//-------------------------------------------------------------------------
+// OnRefreshClick()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRefreshClick(wxCommandEvent& event)
+{
+    // restart portaudio, to re-sample available devices
+
+    Pa_Terminate();
+    Pa_Init();
+
+    m_notebook1->SetSelection(0);
+    showAPIInfo();
+    populateParams(m_RxInDevices);
+    populateParams(m_RxOutDevices);
+    populateParams(m_TxInDevices);
+    populateParams(m_TxOutDevices);
+
+    // some devices may have dissapeared, so possibily change sound
+    // card config
+
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnApplyAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnApplyAudioParameters(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    if(m_isPaInitialized)
+    {
+        if((pa_err = Pa_Terminate()) == paNoError)
+        {
+            m_isPaInitialized = false;
+        }
+        else
+        {
+            wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+        }
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnCancelAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnCancelAudioParameters(wxCommandEvent& event)
+{
+    if(m_isPaInitialized)
+    {
+        if((pa_err = Pa_Terminate()) == paNoError)
+        {
+            m_isPaInitialized = false;
+        }
+        else
+        {
+            wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+        }
+    }
+    EndModal(wxCANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnOkAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnOkAudioParameters(wxCommandEvent& event)
+{
+    int status = ExchangeData(EXCHANGE_DATA_OUT);
+
+    // We only accept OK if config sucessful
+
+    printf("status: %d m_isPaInitialized: %d\n", status, m_isPaInitialized);
+    if (status == 0) {
+        if(m_isPaInitialized)
+        {
+            if((pa_err = Pa_Terminate()) == paNoError)
+            {
+                printf("terminated OK\n");
+                m_isPaInitialized = false;
+            }
+            else
+            {
+                wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+            }
+        }
+        EndModal(wxOK);
+    }
+
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_audiooptions.h b/freedv/tags/1.2.2/freedv-dev/src/dlg_audiooptions.h
new file mode 100644 (file)
index 0000000..5aa6741
--- /dev/null
@@ -0,0 +1,176 @@
+//=========================================================================
+// Name:          AudioInfoDisplay.h
+// Purpose:       Declares simple wxWidgets application with GUI
+//                created using wxFormBuilder.
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//=========================================================================
+#ifndef __AudioOptsDialog__
+#define __AudioOptsDialog__
+
+#include "fdmdv2_main.h"
+
+#define ID_AUDIO_OPTIONS    1000
+#define AUDIO_IN            0
+#define AUDIO_OUT           1
+
+#include "portaudio.h"
+#ifdef WIN32
+#if PA_USE_ASIO
+#include "pa_asio.h"
+#endif
+#endif
+#include "codec2_fifo.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// AudioInfoDisplay
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class AudioInfoDisplay
+{
+    public:
+        wxListCtrl*     m_listDevices;
+        int             direction;
+        wxTextCtrl*     m_textDevice;
+        wxComboBox*     m_cbSampleRate;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class AudioOptsDialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class AudioOptsDialog : public wxDialog
+{
+    private:
+
+    protected:
+        PaError         pa_err;
+        bool            m_isPaInitialized;
+
+        int             rxInAudioDeviceNum;
+        int             rxOutAudioDeviceNum;
+        int             txInAudioDeviceNum;
+        int             txOutAudioDeviceNum;
+
+        void buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, 
+                               wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel);
+        void plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar);
+        void plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar);
+
+        int buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out);
+        void populateParams(AudioInfoDisplay);
+        void showAPIInfo();
+        int setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum);
+        void Pa_Init(void);
+        void OnDeviceSelect(wxComboBox *cbSampleRate, 
+                            wxTextCtrl *textCtrl, 
+                            int        *devNum, 
+                            wxListCtrl *listCtrlDevices, 
+                            int         index,
+                            int         in_out);
+
+        AudioInfoDisplay m_RxInDevices;
+        AudioInfoDisplay m_RxOutDevices;
+        AudioInfoDisplay m_TxInDevices;
+        AudioInfoDisplay m_TxOutDevices;
+        wxPanel* m_panel1;
+        wxNotebook* m_notebook1;
+
+        wxPanel* m_panelRx;
+
+        wxListCtrl* m_listCtrlRxInDevices;
+        wxStaticText* m_staticText51;
+        wxTextCtrl* m_textCtrlRxIn;
+        wxStaticText* m_staticText6;
+        wxComboBox* m_cbSampleRateRxIn;
+
+        wxButton* m_btnRxInTest;
+        PlotScalar* m_plotScalarRxIn;
+
+        wxListCtrl* m_listCtrlRxOutDevices;
+        wxStaticText* m_staticText9;
+        wxTextCtrl* m_textCtrlRxOut;
+        wxStaticText* m_staticText10;
+        wxComboBox* m_cbSampleRateRxOut;
+
+        wxButton* m_btnRxOutTest;
+        PlotScalar* m_plotScalarRxOut;
+
+        wxPanel* m_panelTx;
+
+        wxListCtrl* m_listCtrlTxInDevices;
+        wxStaticText* m_staticText12;
+        wxTextCtrl* m_textCtrlTxIn;
+        wxStaticText* m_staticText11;
+        wxComboBox* m_cbSampleRateTxIn;
+
+        wxButton* m_btnTxInTest;
+        PlotScalar* m_plotScalarTxIn;
+
+        wxListCtrl* m_listCtrlTxOutDevices;
+        wxStaticText* m_staticText81;
+        wxTextCtrl* m_textCtrlTxOut;
+        wxStaticText* m_staticText71;
+        wxComboBox* m_cbSampleRateTxOut;
+
+        wxButton* m_btnTxOutTest;
+        PlotScalar* m_plotScalarTxOut;
+
+        wxPanel* m_panelAPI;
+
+        wxStaticText* m_staticText7;
+        wxStaticText* m_textStringVer;
+        wxStaticText* m_staticText8;
+        wxStaticText* m_textIntVer;
+        wxStaticText* m_staticText5;
+        wxStaticText* m_textCDevCount;
+        wxStaticText* m_staticText4;
+        wxStaticText* m_textAPICount;
+        wxButton* m_btnRefresh;
+        wxStdDialogButtonSizer* m_sdbSizer1;
+        wxButton* m_sdbSizer1OK;
+        wxButton* m_sdbSizer1Apply;
+        wxButton* m_sdbSizer1Cancel;
+
+        // Virtual event handlers, overide them in your derived class
+        //virtual void OnActivateApp( wxActivateEvent& event ) { event.Skip(); }
+//        virtual void OnCloseFrame( wxCloseEvent& event ) { event.Skip(); }
+
+        void OnRxInDeviceSelect( wxListEvent& event );
+
+        void OnRxInTest( wxCommandEvent& event );
+        void OnRxOutTest( wxCommandEvent& event );
+        void OnTxInTest( wxCommandEvent& event );
+        void OnTxOutTest( wxCommandEvent& event );
+
+        void OnRxOutDeviceSelect( wxListEvent& event );
+        void OnTxInDeviceSelect( wxListEvent& event );
+        void OnTxOutDeviceSelect( wxListEvent& event );
+        void OnRefreshClick( wxCommandEvent& event );
+        void OnApplyAudioParameters( wxCommandEvent& event );
+        void OnCancelAudioParameters( wxCommandEvent& event );
+        void OnOkAudioParameters( wxCommandEvent& event );
+        // Virtual event handlers, overide them in your derived class
+        void OnClose( wxCloseEvent& event ) { event.Skip(); }
+        void OnHibernate( wxActivateEvent& event ) { event.Skip(); }
+        void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
+        void OnInitDialog( wxInitDialogEvent& event );
+
+    public:
+
+        AudioOptsDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Audio Config"), const wxPoint& pos = wxPoint(1,1), const wxSize& size = wxSize( 800, 650 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~AudioOptsDialog();
+        int ExchangeData(int inout);
+};
+#endif //__AudioOptsDialog__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_filter.cpp b/freedv/tags/1.2.2/freedv-dev/src/dlg_filter.cpp
new file mode 100644 (file)
index 0000000..5a5294a
--- /dev/null
@@ -0,0 +1,785 @@
+//==========================================================================
+// Name:            dlg_filter.cpp
+// Purpose:         Dialog for controlling Codec audio filtering
+// Date:            Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "dlg_filter.h"
+
+#define SLIDER_MAX 100
+#define SLIDER_LENGTH 100
+
+#define FILTER_MIN_MAG_DB -20.0
+#define FILTER_MAX_MAG_DB  20.0
+
+#define MAX_FREQ_BASS      600.00
+#define MAX_FREQ_TREBLE   3900.00
+#define MAX_FREQ_DEF      3000.00
+
+#define MIN_GAIN          -20
+#define MAX_GAIN           20
+
+#define MAX_LOG10_Q         1.0
+#define MIN_LOG10_Q        -1.0 
+
+// DFT parameters
+
+#define IMP_AMP           2000.0                     // amplitude of impulse
+#define NIMP              50                         // number of samples in impulse response
+#define F_STEP_DFT        10.0                       // frequency steps to sample spectrum
+#define F_MAG_N           (int)(MAX_F_HZ/F_STEP_DFT) // number of frequency steps
+
+extern struct freedv      *g_pfreedv;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class FilterDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
+                     wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    m_running = running;
+    m_newMicInFilter = newMicInFilter;
+    m_newSpkOutFilter = newSpkOutFilter;
+
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+
+    wxBoxSizer* bSizer30;
+    bSizer30 = new wxBoxSizer(wxVERTICAL);
+
+    // LPC Post Filter --------------------------------------------------------
+
+    wxStaticBoxSizer* lpcpfs = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("LPC Post Filter")), wxHORIZONTAL);
+
+    wxBoxSizer* left = new wxBoxSizer(wxVERTICAL);
+
+    m_codec2LPCPostFilterEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    left->Add(m_codec2LPCPostFilterEnable);
+
+    m_codec2LPCPostFilterBassBoost = new wxCheckBox(this, wxID_ANY, _("0-1 kHz 3dB Boost"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    left->Add(m_codec2LPCPostFilterBassBoost);
+    lpcpfs->Add(left, 0, wxALL, 5);
+
+    newLPCPFControl(&m_codec2LPCPostFilterBeta, &m_staticTextBeta, lpcpfs, "Beta");
+    newLPCPFControl(&m_codec2LPCPostFilterGamma, &m_staticTextGamma, lpcpfs, "Gamma");
+
+    m_LPCPostFilterDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    lpcpfs->Add(m_LPCPostFilterDefault, 0, wxALL|wxALIGN_CENTRE_HORIZONTAL|wxALIGN_CENTRE_VERTICAL, 5);
+
+    bSizer30->Add(lpcpfs, 0, wxALL, 0);
+
+    // Speex pre-processor --------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer_speexpp;
+    wxStaticBox *sb_speexpp = new wxStaticBox(this, wxID_ANY, _("Speex Mic Audio Pre-Processor"));
+    sbSizer_speexpp = new wxStaticBoxSizer(sb_speexpp, wxVERTICAL);
+
+    m_ckboxSpeexpp = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_speexpp->SetToolTip(_("Enable noise supression, dereverberation, AGC of mic signal"));
+    sbSizer_speexpp->Add(m_ckboxSpeexpp, wxALIGN_LEFT, 2);
+
+    bSizer30->Add(sbSizer_speexpp, 0, wxALL, 0);   
+
+    // EQ Filters -----------------------------------------------------------
+
+    wxStaticBoxSizer* eqMicInSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mic In Equaliser")), wxVERTICAL);
+    wxBoxSizer* eqMicInSizer1 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* eqMicInSizer2 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_MicInBass   = newEQ(eqMicInSizer1, "Bass"  , MAX_FREQ_BASS, disableQ);
+    m_MicInTreble = newEQ(eqMicInSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
+    eqMicInSizer->Add(eqMicInSizer1);
+
+    m_MicInEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    eqMicInSizer2->Add(m_MicInEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
+    m_MicInMid    = newEQ(eqMicInSizer2, "Mid"   , MAX_FREQ_DEF, enableQ);
+    m_MicInDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    eqMicInSizer2->Add(m_MicInDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
+    eqMicInSizer->Add(eqMicInSizer2);
+
+    wxStaticBoxSizer* eqSpkOutSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Speaker Out Equaliser")), wxVERTICAL);
+    wxBoxSizer* eqSpkOutSizer1 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* eqSpkOutSizer2 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_SpkOutBass   = newEQ(eqSpkOutSizer1, "Bass"  , MAX_FREQ_BASS, disableQ);
+    m_SpkOutTreble = newEQ(eqSpkOutSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
+    eqSpkOutSizer->Add(eqSpkOutSizer1);
+
+    m_SpkOutEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    eqSpkOutSizer2->Add(m_SpkOutEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
+    m_SpkOutMid    = newEQ(eqSpkOutSizer2, "Mid"   , MAX_FREQ_DEF, enableQ);
+    m_SpkOutDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    eqSpkOutSizer2->Add(m_SpkOutDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
+    eqSpkOutSizer->Add(eqSpkOutSizer2);
+    
+    bSizer30->Add(eqMicInSizer, 0, wxALL, 0);
+    bSizer30->Add(eqSpkOutSizer, 0, wxALL, 0);
+
+    // Storgage for spectrum magnitude plots ------------------------------------
+
+    m_MicInMagdB = new float[F_MAG_N];
+    for(int i=0; i<F_MAG_N; i++)
+        m_MicInMagdB[i] = 0.0;
+
+    m_SpkOutMagdB = new float[F_MAG_N];
+    for(int i=0; i<F_MAG_N; i++)
+        m_SpkOutMagdB[i] = 0.0;
+
+    // Spectrum Plots -----------------------------------------------------------
+
+    long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
+    m_auiNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(-1,200), nb_style);
+    m_auiNotebook->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
+
+    bSizer30->Add(m_auiNotebook, 0, wxEXPAND|wxALL, 3);
+    
+    m_MicInFreqRespPlot = new PlotSpectrum((wxFrame*) m_auiNotebook, m_MicInMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
+    m_auiNotebook->AddPage(m_MicInFreqRespPlot, _("Microphone In Equaliser"));
+
+    m_SpkOutFreqRespPlot = new PlotSpectrum((wxFrame*)m_auiNotebook, m_SpkOutMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
+    m_auiNotebook->AddPage(m_SpkOutFreqRespPlot, _("Speaker Out Equaliser"));
+
+    //  OK - Cancel buttons at the bottom --------------------------
+
+    wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_sdbSizer5OK = new wxButton(this, wxID_OK);
+    bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
+
+    m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
+    bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
+
+    bSizer30->Add(bSizer31, 0, wxALIGN_RIGHT|wxALL, 0);
+
+    this->SetSizer(bSizer30);
+    this->Layout();
+
+    this->Centre(wxBOTH);
+    // Connect Events -------------------------------------------------------
+
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
+
+    m_codec2LPCPostFilterEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
+    m_codec2LPCPostFilterBassBoost->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
+    m_codec2LPCPostFilterBeta->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
+    m_codec2LPCPostFilterGamma->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
+    m_LPCPostFilterDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
+
+    m_ckboxSpeexpp->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpeexppEnable), NULL, this);
+
+    m_MicInBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
+    m_MicInBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
+    m_MicInTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
+    m_MicInTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
+    m_MicInMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
+    m_MicInMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
+    m_MicInMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
+    m_MicInEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
+    m_MicInDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
+
+    m_SpkOutBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
+    m_SpkOutBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
+    m_SpkOutTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
+    m_SpkOutTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
+    m_SpkOutMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
+    m_SpkOutMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
+    m_SpkOutMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
+    m_SpkOutEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
+    m_SpkOutDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
+
+    m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
+    m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// ~FilterDlg()
+//-------------------------------------------------------------------------
+FilterDlg::~FilterDlg()
+{
+    delete m_MicInMagdB;
+    delete m_SpkOutMagdB;
+
+    // Disconnect Events
+
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
+
+    m_codec2LPCPostFilterEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
+    m_codec2LPCPostFilterBassBoost->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
+    m_codec2LPCPostFilterBeta->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
+    m_codec2LPCPostFilterGamma->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
+    m_LPCPostFilterDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
+
+    m_MicInBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
+    m_MicInBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
+    m_MicInTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
+    m_MicInTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
+    m_MicInMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
+    m_MicInMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
+    m_MicInMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
+    m_MicInEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
+    m_MicInDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
+
+    m_SpkOutBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
+    m_SpkOutBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
+    m_SpkOutTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
+    m_SpkOutTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
+    m_SpkOutMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
+    m_SpkOutMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
+    m_SpkOutMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
+    m_SpkOutEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
+    m_SpkOutDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
+
+    m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
+    m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
+}
+
+void FilterDlg::newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *s, wxString controlName)
+{
+    wxBoxSizer *bs = new wxBoxSizer(wxHORIZONTAL);
+
+    wxStaticText* st = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxSize(70,-1), wxALIGN_RIGHT);
+    bs->Add(st, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 2);
+
+    *slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
+    bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 2);
+
+    *stValue = new wxStaticText(this, wxID_ANY, wxT("0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    bs->Add(*stValue, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 2);
+
+    s->Add(bs, 0);
+}
+
+void FilterDlg::newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName)
+{
+    wxStaticText* label = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+    bs->Add(label, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 0);
+
+    *slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
+    bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    *value = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(40,-1), wxALIGN_LEFT);
+    bs->Add(*value, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxRIGHT, 5);
+}
+
+EQ FilterDlg::newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ)
+{
+    EQ eq;
+
+    wxStaticBoxSizer *bsEQ = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, eqName), wxHORIZONTAL);
+
+    newEQControl(&eq.sliderFreq, &eq.valueFreq, bsEQ, "Freq"); 
+    eq.maxFreqHz = maxFreqHz; 
+    eq.sliderFreqId = eq.sliderFreq->GetId();
+
+    newEQControl(&eq.sliderGain, &eq.valueGain, bsEQ, "Gain");
+    if (enableQ)
+        newEQControl(&eq.sliderQ, &eq.valueQ, bsEQ, "Q");
+    else
+        eq.sliderQ = NULL;
+
+    bs->Add(bsEQ);
+
+    return eq;
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void FilterDlg::ExchangeData(int inout, bool storePersistent)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        // LPC Post filter
+
+        m_codec2LPCPostFilterEnable->SetValue(wxGetApp().m_codec2LPCPostFilterEnable);
+        m_codec2LPCPostFilterBassBoost->SetValue(wxGetApp().m_codec2LPCPostFilterBassBoost);
+        m_beta = wxGetApp().m_codec2LPCPostFilterBeta; setBeta();
+        m_gamma = wxGetApp().m_codec2LPCPostFilterGamma; setGamma();
+
+        // Speex Pre-Processor
+
+        m_ckboxSpeexpp->SetValue(wxGetApp().m_speexpp_enable);
+
+        // Mic In Equaliser
+
+        m_MicInBass.freqHz = wxGetApp().m_MicInBassFreqHz; 
+        m_MicInBass.freqHz = limit(m_MicInBass.freqHz, 1.0, MAX_FREQ_BASS);
+        setFreq(&m_MicInBass);
+        m_MicInBass.gaindB = wxGetApp().m_MicInBassGaindB;
+        m_MicInBass.gaindB = limit(m_MicInBass.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInBass);
+
+        m_MicInTreble.freqHz = wxGetApp().m_MicInTrebleFreqHz;
+        m_MicInTreble.freqHz = limit(m_MicInTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_MicInTreble);
+        m_MicInTreble.gaindB = wxGetApp().m_MicInTrebleGaindB; 
+        m_MicInTreble.gaindB = limit(m_MicInTreble.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInTreble);
+
+        m_MicInMid.freqHz = wxGetApp().m_MicInMidFreqHz; 
+        m_MicInMid.freqHz = limit(m_MicInMid.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_MicInMid);
+        m_MicInMid.gaindB = wxGetApp().m_MicInMidGaindB; 
+        m_MicInMid.gaindB = limit(m_MicInMid.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInMid);
+        m_MicInMid.Q = wxGetApp().m_MicInMidQ;
+        m_MicInMid.Q = limit(m_MicInMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
+        setQ(&m_MicInMid);
+
+        m_MicInEnable->SetValue(wxGetApp().m_MicInEQEnable);
+
+        plotMicInFilterSpectrum();
+        // Spk Out Equaliser
+
+        m_SpkOutBass.freqHz = wxGetApp().m_SpkOutBassFreqHz;
+        m_SpkOutBass.freqHz = limit(m_SpkOutBass.freqHz, 1.0, MAX_FREQ_BASS);
+        setFreq(&m_SpkOutBass);
+        m_SpkOutBass.gaindB = wxGetApp().m_SpkOutBassGaindB; 
+        m_SpkOutBass.gaindB = limit(m_SpkOutBass.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutBass);
+
+        m_SpkOutTreble.freqHz = wxGetApp().m_SpkOutTrebleFreqHz; 
+        m_SpkOutTreble.freqHz = limit(m_SpkOutTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_SpkOutTreble);
+        m_SpkOutTreble.gaindB = wxGetApp().m_SpkOutTrebleGaindB; 
+        m_SpkOutTreble.gaindB = limit(m_SpkOutTreble.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutTreble);
+
+        m_SpkOutMid.freqHz = wxGetApp().m_SpkOutMidFreqHz;
+        m_SpkOutMid.freqHz = limit(m_SpkOutMid.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_SpkOutMid);
+        m_SpkOutMid.gaindB = wxGetApp().m_SpkOutMidGaindB;
+        m_SpkOutMid.gaindB = limit(m_SpkOutMid.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutMid);
+        m_SpkOutMid.Q = wxGetApp().m_SpkOutMidQ;
+        m_SpkOutMid.Q = limit(m_SpkOutMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
+        setQ(&m_SpkOutMid);
+
+        m_SpkOutEnable->SetValue(wxGetApp().m_SpkOutEQEnable);
+
+        plotSpkOutFilterSpectrum();
+    }
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        // LPC Post filter
+
+        wxGetApp().m_codec2LPCPostFilterEnable     = m_codec2LPCPostFilterEnable->GetValue();
+        wxGetApp().m_codec2LPCPostFilterBassBoost  = m_codec2LPCPostFilterBassBoost->GetValue();
+        wxGetApp().m_codec2LPCPostFilterBeta       = m_beta;
+        wxGetApp().m_codec2LPCPostFilterGamma      = m_gamma;
+
+        // Speex Pre-Processor
+
+        wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
+
+        // Mic In Equaliser
+
+        wxGetApp().m_MicInBassFreqHz = m_MicInBass.freqHz;
+        wxGetApp().m_MicInBassGaindB = m_MicInBass.gaindB;
+
+        wxGetApp().m_MicInTrebleFreqHz = m_MicInTreble.freqHz;
+        wxGetApp().m_MicInTrebleGaindB = m_MicInTreble.gaindB;
+
+        wxGetApp().m_MicInMidFreqHz = m_MicInMid.freqHz;
+        wxGetApp().m_MicInMidGaindB = m_MicInMid.gaindB;
+        wxGetApp().m_MicInMidQ = m_MicInMid.Q;
+
+        // Spk Out Equaliser
+
+        wxGetApp().m_SpkOutBassFreqHz = m_SpkOutBass.freqHz;
+        wxGetApp().m_SpkOutBassGaindB = m_SpkOutBass.gaindB;
+
+        wxGetApp().m_SpkOutTrebleFreqHz = m_SpkOutTreble.freqHz;
+        wxGetApp().m_SpkOutTrebleGaindB = m_SpkOutTreble.gaindB;
+
+        wxGetApp().m_SpkOutMidFreqHz = m_SpkOutMid.freqHz;
+        wxGetApp().m_SpkOutMidGaindB = m_SpkOutMid.gaindB;
+        wxGetApp().m_SpkOutMidQ = m_SpkOutMid.Q;
+
+        if (storePersistent) {
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterEnable"),     wxGetApp().m_codec2LPCPostFilterEnable);
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterBassBoost"),  wxGetApp().m_codec2LPCPostFilterBassBoost);
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterBeta"),       (int)(m_beta*100.0));
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterGamma"),      (int)(m_gamma*100.0));
+
+            pConfig->Write(wxT("/Filter/speexpp_enable"),                wxGetApp().m_speexpp_enable);
+
+            pConfig->Write(wxT("/Filter/MicInBassFreqHz"), (int)m_MicInBass.freqHz);
+            pConfig->Write(wxT("/Filter/MicInBassGaindB"), (int)(10.0*m_MicInBass.gaindB));
+            pConfig->Write(wxT("/Filter/MicInTrebleFreqHz"), (int)m_MicInTreble.freqHz);
+            pConfig->Write(wxT("/Filter/MicInTrebleGaindB"), (int)(10.0*m_MicInTreble.gaindB));
+            pConfig->Write(wxT("/Filter/MicInMidFreqHz"), (int)m_MicInMid.freqHz);
+            pConfig->Write(wxT("/Filter/MicInMidGaindB"), (int)(10.0*m_MicInMid.gaindB));
+            pConfig->Write(wxT("/Filter/MicInMidQ"), (int)(100.0*m_MicInMid.Q));
+
+            pConfig->Write(wxT("/Filter/SpkOutBassFreqHz"), (int)m_SpkOutBass.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutBassGaindB"), (int)(10.0*m_SpkOutBass.gaindB));
+            pConfig->Write(wxT("/Filter/SpkOutTrebleFreqHz"), (int)m_SpkOutTreble.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutTrebleGaindB"), (int)(10.0*m_SpkOutTreble.gaindB));
+            pConfig->Write(wxT("/Filter/SpkOutMidQ"), (int)(100.0*m_SpkOutMid.Q));
+            pConfig->Write(wxT("/Filter/SpkOutMidFreqHz"), (int)m_SpkOutMid.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutMidGaindB"), (int)(10.0*m_SpkOutMid.gaindB));
+
+            pConfig->Flush();
+        }
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+float FilterDlg::limit(float value, float min, float max) {
+    if (value < min) return min;
+    if (value > max) return max;
+    return value;
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void FilterDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnDefault()
+//-------------------------------------------------------------------------
+
+void FilterDlg::OnLPCPostFilterDefault(wxCommandEvent& event)
+{
+    m_beta = CODEC2_LPC_PF_BETA; setBeta();
+    m_gamma = CODEC2_LPC_PF_GAMMA; setGamma();
+    m_codec2LPCPostFilterEnable->SetValue(true);
+    m_codec2LPCPostFilterBassBoost->SetValue(true);
+}
+
+void FilterDlg::OnMicInDefault(wxCommandEvent& event)
+{
+    m_MicInBass.freqHz = 100.0;
+    m_MicInBass.gaindB = 0.0;
+    setFreq(&m_MicInBass); setGain(&m_MicInBass); 
+
+    m_MicInTreble.freqHz = 3000.0;
+    m_MicInTreble.gaindB = 0.0;
+    setFreq(&m_MicInTreble); setGain(&m_MicInTreble); 
+
+    m_MicInMid.freqHz = 1500.0;
+    m_MicInMid.gaindB = 0.0;
+    m_MicInMid.Q = 1.0;
+    setFreq(&m_MicInMid); setGain(&m_MicInMid); setQ(&m_MicInMid); 
+
+    plotMicInFilterSpectrum();    
+}
+
+void FilterDlg::OnSpkOutDefault(wxCommandEvent& event)
+{
+    m_SpkOutBass.freqHz = 100.0;
+    m_SpkOutBass.gaindB = 0.0;
+    setFreq(&m_SpkOutBass); setGain(&m_SpkOutBass); 
+
+    m_SpkOutTreble.freqHz = 3000.0;
+    m_SpkOutTreble.gaindB = 0.0;
+    setFreq(&m_SpkOutTreble); setGain(&m_SpkOutTreble); 
+
+    m_SpkOutMid.freqHz = 1500.0;
+    m_SpkOutMid.gaindB = 0.0;
+    m_SpkOutMid.Q = 1.0;
+    setFreq(&m_SpkOutMid); setGain(&m_SpkOutMid); setQ(&m_SpkOutMid); 
+
+    plotSpkOutFilterSpectrum();    
+}
+
+//-------------------------------------------------------------------------
+// OnOK()
+//-------------------------------------------------------------------------
+void FilterDlg::OnOK(wxCommandEvent& event)
+{
+    //printf("FilterDlg::OnOK\n");
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+    this->EndModal(wxID_OK);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void FilterDlg::OnClose(wxCloseEvent& event)
+{
+    this->EndModal(wxID_OK);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void FilterDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    //printf("FilterDlg::OnInitDialog\n");
+    ExchangeData(EXCHANGE_DATA_IN, false);
+    //printf("m_beta: %f\n", m_beta);
+}
+
+void FilterDlg::setBeta(void) {
+    wxString buf;
+    buf.Printf(wxT("%3.2f"), m_beta);
+    m_staticTextBeta->SetLabel(buf);
+    int slider = (int)(m_beta*SLIDER_MAX + 0.5);
+    m_codec2LPCPostFilterBeta->SetValue(slider);
+}
+
+void FilterDlg::setCodec2(void) {
+    if (m_running) {
+        codec2_set_lpc_post_filter(freedv_get_codec2(g_pfreedv), 
+                               m_codec2LPCPostFilterEnable->GetValue(), 
+                               m_codec2LPCPostFilterBassBoost->GetValue(), 
+                               m_beta, m_gamma);
+    }
+}
+
+void FilterDlg::setGamma(void) {
+    wxString buf;
+    buf.Printf(wxT("%3.2f"), m_gamma);
+    m_staticTextGamma->SetLabel(buf);
+    int slider = (int)(m_gamma*SLIDER_MAX + 0.5);
+    m_codec2LPCPostFilterGamma->SetValue(slider);
+}
+
+void FilterDlg::OnEnable(wxScrollEvent& event) {
+    setCodec2();    
+}
+
+void FilterDlg::OnBassBoost(wxScrollEvent& event) {
+    setCodec2();    
+}
+
+void FilterDlg::OnBetaScroll(wxScrollEvent& event) {
+    m_beta = (float)m_codec2LPCPostFilterBeta->GetValue()/SLIDER_MAX;
+    setBeta();
+    setCodec2();
+}
+
+void FilterDlg::OnGammaScroll(wxScrollEvent& event) {
+    m_gamma = (float)m_codec2LPCPostFilterGamma->GetValue()/SLIDER_MAX;
+    setGamma();
+    setCodec2();
+}
+
+// immediately change enable flags rather using ExchangeData() so we can switch on and off at run time
+
+void FilterDlg::OnSpeexppEnable(wxScrollEvent& event) {
+    wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
+}
+
+void FilterDlg::OnMicInEnable(wxScrollEvent& event) {
+    wxGetApp().m_MicInEQEnable = m_MicInEnable->GetValue();
+}
+
+void FilterDlg::OnSpkOutEnable(wxScrollEvent& event) {
+    wxGetApp().m_SpkOutEQEnable = m_SpkOutEnable->GetValue();
+    //printf("wxGetApp().m_SpkOutEQEnable: %d\n", wxGetApp().m_SpkOutEQEnable);
+}
+
+void FilterDlg::setFreq(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%3.0f"), eq->freqHz);
+    eq->valueFreq->SetLabel(buf);
+    int slider = (int)((eq->freqHz/eq->maxFreqHz)*SLIDER_MAX + 0.5);
+    eq->sliderFreq->SetValue(slider);
+}
+
+void FilterDlg::sliderToFreq(EQ *eq, bool micIn)
+{
+    eq->freqHz = ((float)eq->sliderFreq->GetValue()/SLIDER_MAX)*eq->maxFreqHz;
+    if (eq->freqHz < 1.0) eq->freqHz = 1.0; // sox doesn't like 0 Hz;
+    setFreq(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+}
+
+void FilterDlg::setGain(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%3.1f"), eq->gaindB);
+    eq->valueGain->SetLabel(buf);
+    int slider = (int)(((eq->gaindB-MIN_GAIN)/(MAX_GAIN-MIN_GAIN))*SLIDER_MAX + 0.5);
+    eq->sliderGain->SetValue(slider);
+}
+
+void FilterDlg::sliderToGain(EQ *eq, bool micIn)
+{
+    float range = MAX_GAIN-MIN_GAIN;
+    
+    eq->gaindB = MIN_GAIN + range*((float)eq->sliderGain->GetValue()/SLIDER_MAX);
+    //printf("gaindB: %f\n", eq->gaindB);
+    setGain(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+        
+}
+
+void FilterDlg::setQ(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%2.1f"), eq->Q);
+    eq->valueQ->SetLabel(buf);
+
+    float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
+
+    int slider = (int)(((log10(eq->Q+1E-6)-MIN_LOG10_Q)/log10_range)*SLIDER_MAX + 0.5);
+    eq->sliderQ->SetValue(slider);
+}
+
+void FilterDlg::sliderToQ(EQ *eq, bool micIn)
+{
+    float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
+    
+    float sliderNorm = (float)eq->sliderQ->GetValue()/SLIDER_MAX;
+    float log10Q =  MIN_LOG10_Q + sliderNorm*(log10_range);
+    eq->Q = pow(10.0, log10Q);
+    //printf("log10Q: %f eq->Q: %f\n", log10Q, eq->Q);
+    setQ(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+}
+
+void FilterDlg::plotMicInFilterSpectrum(void) {
+    plotFilterSpectrum(&m_MicInBass, &m_MicInMid, &m_MicInTreble, m_MicInFreqRespPlot, m_MicInMagdB);
+}
+
+void FilterDlg::plotSpkOutFilterSpectrum(void) {
+    plotFilterSpectrum(&m_SpkOutBass, &m_SpkOutMid, &m_SpkOutTreble, m_SpkOutFreqRespPlot, m_SpkOutMagdB);
+}
+
+void FilterDlg::adjRunTimeMicInFilter(void) {
+    // signal an adjustment in running filter coeffs
+
+    if (m_running) {
+        ExchangeData(EXCHANGE_DATA_OUT, false);
+        *m_newMicInFilter = true;
+    }
+}
+        
+void FilterDlg::adjRunTimeSpkOutFilter(void) {
+    // signal an adjustment in running filter coeffs
+
+    if (m_running) {
+        ExchangeData(EXCHANGE_DATA_OUT, false);
+        *m_newSpkOutFilter = true;
+    }
+}
+        
+
+void FilterDlg::plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ *eqTreble, PlotSpectrum* freqRespPlot, float *magdB) {
+    char  *argBass[10];
+    char  *argTreble[10];
+    char  *argMid[10];
+    char   argstorage[10][80];
+    float magBass[F_MAG_N];
+    float magTreble[F_MAG_N];
+    float magMid[F_MAG_N];
+    int   i;
+
+    for(i=0; i<10; i++) {
+        argBass[i] = &argstorage[i][0];
+        argTreble[i] = &argstorage[i][0];
+        argMid[i] = &argstorage[i][0];
+    }
+    sprintf(argBass[0], "bass");                
+    sprintf(argBass[1], "%f", eqBass->gaindB+1E-6);
+    sprintf(argBass[2], "%f", eqBass->freqHz);      
+
+    calcFilterSpectrum(magBass, 2, argBass);
+
+    sprintf(argTreble[0], "treble");                
+    sprintf(argTreble[1], "%f", eqTreble->gaindB+1E-6);
+    sprintf(argTreble[2], "%f", eqTreble->freqHz);      
+
+    calcFilterSpectrum(magTreble, 2, argTreble);
+
+    sprintf(argTreble[0], "equalizer");                
+    sprintf(argTreble[1], "%f", eqMid->freqHz);      
+    sprintf(argTreble[2], "%f", eqMid->Q);      
+    sprintf(argTreble[3], "%f", eqMid->gaindB+1E-6);
+
+    calcFilterSpectrum(magMid, 3, argMid);
+
+    for(i=0; i<F_MAG_N; i++)
+        magdB[i] = magBass[i] + magMid[i] + magTreble[i];
+    freqRespPlot->m_newdata = true;
+    freqRespPlot->Refresh();
+}
+
+void FilterDlg::calcFilterSpectrum(float magdB[], int argc, char *argv[]) {
+    void       *sbq;
+    short       in[NIMP];
+    short       out[NIMP];
+    COMP        X[F_MAG_N];
+    float       f, w;
+    int         i, k;
+
+    // find impulse response -----------------------------------
+
+    for(i=0; i<NIMP; i++)
+        in[i] = 0;
+    in[0] = IMP_AMP;
+
+    //printf("argv[0]: %s argv[1]: %s\n", argv[0], argv[1]);
+    sbq = sox_biquad_create(argc, (const char **)argv);
+
+    sox_biquad_filter(sbq, out, in, NIMP);
+    //for(i=0; i<NIMP; i++)
+    //    printf("%d\n", out[i]);
+   
+    sox_biquad_destroy(sbq);
+
+    //for(i=0; i<NIMP; i++)
+    //    out[i] = 0.0;
+    //out[0] = IMP_AMP;
+
+    // calculate discrete time continous frequency Fourer transform
+    // doing this from first principles rather than FFT for no good reason
+
+    for(f=0,i=0; f<MAX_F_HZ; f+=F_STEP_DFT,i++) {
+        w = M_PI*f/(FS/2);
+        X[i].real = 0.0; X[i].imag = 0.0;
+        for(k=0; k<NIMP; k++) {
+            X[i].real += ((float)out[k]/IMP_AMP) * cos(w*k);
+            X[i].imag -= ((float)out[k]/IMP_AMP) * sin(w*k);
+        }
+        magdB[i] = 10.0*log10(X[i].real* X[i].real + X[i].imag*X[i].imag + 1E-12);
+        //printf("f: %f X[%d] = %f %f magdB = %f\n", f, i, X[i].real, X[i].imag,  magdB[i]);
+    }
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_filter.h b/freedv/tags/1.2.2/freedv-dev/src/dlg_filter.h
new file mode 100644 (file)
index 0000000..82c43df
--- /dev/null
@@ -0,0 +1,166 @@
+//==========================================================================
+// Name:            dlg_filter.h
+// Purpose:         Dialog for controlling Codec audio filtering
+// Created:         Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __FILTER_DIALOG__
+#define __FILTER_DIALOG__
+
+#include "fdmdv2_main.h"
+
+enum {disableQ = false, enableQ = true};
+
+typedef struct { 
+    wxSlider     *sliderFreq;
+    wxStaticText *valueFreq;
+    wxSlider     *sliderGain;
+    wxStaticText *valueGain;
+    wxSlider     *sliderQ;
+    wxStaticText *valueQ;
+
+    int       sliderFreqId;
+    int       sliderGainId;
+    int       sliderQId;
+    
+    float     freqHz;
+    float     gaindB;
+    float     Q;
+
+    float     maxFreqHz;
+} EQ;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class FilterDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class FilterDlg : public wxDialog
+{
+    public:
+    FilterDlg( wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
+               wxWindowID id = wxID_ANY, const wxString& title = _("Filter"), 
+               const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 800, 630 ), 
+               long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~FilterDlg();
+
+        void    ExchangeData(int inout, bool storePersistent);
+
+    protected:
+        // Handlers for events.
+        void    OnCancel(wxCommandEvent& event);
+        void    OnOK(wxCommandEvent& event);
+        void    OnClose(wxCloseEvent& event);
+        void    OnInitDialog(wxInitDialogEvent& event);
+        void    OnLPCPostFilterDefault(wxCommandEvent& event);
+
+        void    OnBetaScroll(wxScrollEvent& event);
+        void    OnGammaScroll(wxScrollEvent& event);
+        void    OnEnable(wxScrollEvent& event);
+        void    OnBassBoost(wxScrollEvent& event);
+
+        void    OnSpeexppEnable(wxScrollEvent& event);
+
+        void    OnMicInBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInBass, true); }
+        void    OnMicInBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInBass, true); }
+        void    OnMicInTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInTreble, true); }
+        void    OnMicInTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInTreble, true); }
+        void    OnMicInMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInMid, true); }
+        void    OnMicInMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInMid, true); }
+        void    OnMicInMidQScroll(wxScrollEvent& event) { sliderToQ(&m_MicInMid, true); }
+        void    OnMicInEnable(wxScrollEvent& event);
+        void    OnMicInDefault(wxCommandEvent& event);
+
+        void    OnSpkOutBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutBass, false); }
+        void    OnSpkOutBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutBass, false); }
+        void    OnSpkOutTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutTreble, false); }
+        void    OnSpkOutTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutTreble, false); }
+        void    OnSpkOutMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutMid, false); }
+        void    OnSpkOutMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutMid, false); }
+        void    OnSpkOutMidQScroll(wxScrollEvent& event) { sliderToQ(&m_SpkOutMid, false); }
+        void    OnSpkOutEnable(wxScrollEvent& event);
+        void    OnSpkOutDefault(wxCommandEvent& event);
+
+        wxStaticText* m_staticText8;
+        wxCheckBox*   m_codec2LPCPostFilterEnable;
+        wxStaticText* m_staticText9;
+        wxCheckBox*   m_codec2LPCPostFilterBassBoost;
+        wxStaticText* m_staticText91;
+        wxSlider*     m_codec2LPCPostFilterBeta;
+        wxStaticText* m_staticTextBeta;
+        wxStaticText* m_staticText911;
+        wxSlider*     m_codec2LPCPostFilterGamma;
+        wxStaticText* m_staticTextGamma;
+        wxButton*     m_LPCPostFilterDefault;
+
+        wxCheckBox*   m_ckboxSpeexpp;
+
+        wxStdDialogButtonSizer* m_sdbSizer5;
+        wxButton*     m_sdbSizer5OK;
+        wxButton*     m_sdbSizer5Cancel;
+        PlotSpectrum* m_MicInFreqRespPlot;
+        PlotSpectrum* m_SpkOutFreqRespPlot;
+        
+        wxCheckBox*   m_MicInEnable;
+        wxButton*     m_MicInDefault;
+        wxCheckBox*   m_SpkOutEnable;
+        wxButton*     m_SpkOutDefault;
+
+        float        *m_MicInMagdB;
+        float        *m_SpkOutMagdB;
+
+     private:
+        bool          m_running;
+        float         m_beta;
+        float         m_gamma;
+
+        void          setBeta(void);  // sets slider and static text from m_beta
+        void          setGamma(void); // sets slider and static text from m_gamma
+        void          setCodec2(void);
+        void          newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName);
+        EQ            newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ);
+        void          newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *sbs, wxString controlName);
+        wxAuiNotebook *m_auiNotebook;
+        void          setFreq(EQ *eq);
+        void          setGain(EQ *eq);
+        void          setQ(EQ *eq);
+        void          sliderToFreq(EQ *eq, bool micIn);
+        void          sliderToGain(EQ *eq, bool micIn);
+        void          sliderToQ(EQ *eq, bool micIn);
+        void          plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ* eqTreble, PlotSpectrum* freqRespPlot, float *magdB);
+        void          calcFilterSpectrum(float magdB[], int arc, char *argv[]);
+        void          plotMicInFilterSpectrum(void);
+        void          plotSpkOutFilterSpectrum(void);
+        void          adjRunTimeMicInFilter(void);
+        void          adjRunTimeSpkOutFilter(void);
+
+        EQ            m_MicInBass;
+        EQ            m_MicInMid;
+        EQ            m_MicInTreble;
+
+        EQ            m_SpkOutBass;
+        EQ            m_SpkOutMid;
+        EQ            m_SpkOutTreble;
+
+        float         limit(float value, float min, float max);
+        bool          *m_newMicInFilter;
+        bool          *m_newSpkOutFilter;
+
+};
+
+#endif // __FILTER_DIALOG__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_options.cpp b/freedv/tags/1.2.2/freedv-dev/src/dlg_options.cpp
new file mode 100644 (file)
index 0000000..79b6c87
--- /dev/null
@@ -0,0 +1,616 @@
+//==========================================================================
+// Name:            dlg_options.cpp
+// Purpose:         Dialog for controlling misc FreeDV options
+// Date:            May 24 2013
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "dlg_options.h"
+
+extern bool                g_modal;
+extern struct freedv      *g_pfreedv;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class OptionsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+
+    wxBoxSizer* bSizer30;
+    bSizer30 = new wxBoxSizer(wxVERTICAL);
+
+    //------------------------------
+    // Txt Msg Text Box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_callSign;
+    wxStaticBox *sb_textMsg = new wxStaticBox(this, wxID_ANY, _("Txt Msg"));
+    sbSizer_callSign = new wxStaticBoxSizer(sb_textMsg, wxVERTICAL);
+
+    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    m_txtCtrlCallSign->SetToolTip(_("Txt Msg you can send along with Voice"));
+    sbSizer_callSign->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 3);
+
+    bSizer30->Add(sbSizer_callSign,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    //----------------------------------------------------------------------
+    // Voice Keyer 
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Voice Keyer")), wxHORIZONTAL);
+
+    wxStaticText *m_staticText28b = new wxStaticText(this, wxID_ANY, _("Wave File: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28b, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtCtrlVoiceKeyerWaveFile = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
+    m_txtCtrlVoiceKeyerWaveFile->SetToolTip(_("Wave file to play for Voice Keyer"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerWaveFile, 0, 0, 5);
+
+    m_buttonChooseVoiceKeyerWaveFile = new wxButton(this, wxID_APPLY, _("Choose"), wxDefaultPosition, wxSize(-1,-1), 0);
+    staticBoxSizer28a->Add(m_buttonChooseVoiceKeyerWaveFile, 0, wxALIGN_CENTER_VERTICAL, 5);
+
+    wxStaticText *m_staticText28c = new wxStaticText(this, wxID_ANY, _("   Rx Pause: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28c, 0, wxALIGN_CENTER_VERTICAL , 5);
+    m_txtCtrlVoiceKeyerRxPause = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRxPause->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRxPause, 0, 0, 5);
+
+    wxStaticText *m_staticText28d = new wxStaticText(this, wxID_ANY, _("   Repeats: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28d, 0, wxALIGN_CENTER_VERTICAL, 5);
+    m_txtCtrlVoiceKeyerRepeats = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRepeats->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRepeats, 0, 0, 5);
+
+    bSizer30->Add(staticBoxSizer28a,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __WXMSW__
+    //------------------------------
+    // debug console, for WIndows build make console pop up for debug messages
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_console;
+    wxStaticBox *sb_console = new wxStaticBox(this, wxID_ANY, _("Debug"));
+    sbSizer_console = new wxStaticBoxSizer(sb_console, wxHORIZONTAL);
+
+    m_ckboxDebugConsole = new wxCheckBox(this, wxID_ANY, _("Show Console"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_console->Add(m_ckboxDebugConsole, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_console,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
+
+    //------------------------------
+    // FreeDV 700 Options
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_freedv700;
+    wxStaticBox *sb_freedv700 = new wxStaticBox(this, wxID_ANY, _("FreeDV 700 Options"));
+    sbSizer_freedv700 = new wxStaticBoxSizer(sb_freedv700, wxHORIZONTAL);
+
+    m_ckboxFreeDV700txClip = new wxCheckBox(this, wxID_ANY, _("Clipping"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_freedv700->Add(m_ckboxFreeDV700txClip, 0, wxALIGN_LEFT, 0);
+    m_ckboxFreeDV700Combine = new wxCheckBox(this, wxID_ANY, _("Diversity Combine for plots"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_freedv700->Add(m_ckboxFreeDV700Combine, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_freedv700, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Half/Full duplex selection
+    //------------------------------
+
+    wxStaticBox *sb_duplex = new wxStaticBox(this, wxID_ANY, _("Half/Full Duplex Operation"));
+    wxStaticBoxSizer* sbSizer_duplex = new wxStaticBoxSizer(sb_duplex, wxHORIZONTAL);
+    m_ckHalfDuplex = new wxCheckBox(this, wxID_ANY, _("Half Duplex"), wxDefaultPosition, wxSize(-1,-1), 0);
+    sbSizer_duplex->Add(m_ckHalfDuplex, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
+    bSizer30->Add(sbSizer_duplex,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Test Frames/Channel simulation check box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_testFrames;
+    wxStaticBox *sb_testFrames = new wxStaticBox(this, wxID_ANY, _("Testing and Channel Simulation"));
+    sbSizer_testFrames = new wxStaticBoxSizer(sb_testFrames, wxHORIZONTAL);
+
+    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Test Frames"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxChannelNoise = new wxCheckBox(this, wxID_ANY, _("Channel Noise   SNR (dB):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxChannelNoise, 0, wxALIGN_LEFT, 0);
+    m_txtNoiseSNR = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtNoiseSNR, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxAttnCarrierEn = new wxCheckBox(this, wxID_ANY, _("Attn Carrier  Carrier:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxAttnCarrierEn, 0, wxALIGN_LEFT, 0);
+    m_txtAttnCarrier = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtAttnCarrier, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Interfering tone
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_tone;
+    wxStaticBox *sb_tone = new wxStaticBox(this, wxID_ANY, _("Simulated Interference Tone"));
+    sbSizer_tone = new wxStaticBoxSizer(sb_tone, wxHORIZONTAL);
+
+    m_ckboxTone = new wxCheckBox(this, wxID_ANY, _("Tone   Freq (Hz):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_tone->Add(m_ckboxTone, 0, wxALIGN_LEFT, 0);
+    m_txtToneFreqHz = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneFreqHz, 0, wxALIGN_LEFT, 0);
+    wxStaticText *m_staticTextta = new wxStaticText(this, wxID_ANY, _(" Amplitude (pk): "), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_tone->Add(m_staticTextta, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtToneAmplitude = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneAmplitude, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_tone,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __EXPERIMENTAL_UDP__
+    //------------------------------
+    // Txt Encoding 
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_encoding = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Text Encoding")), wxHORIZONTAL);
+
+#ifdef SHORT_VARICODE
+    m_rb_textEncoding1 = new wxRadioButton( this, wxID_ANY, wxT("Long varicode"), wxDefaultPosition, wxDefaultSize, 0);
+    m_rb_textEncoding1->SetValue(true);
+    sbSizer_encoding->Add(m_rb_textEncoding1, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb_textEncoding2 = new wxRadioButton( this, wxID_ANY, wxT("Short Varicode"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_encoding->Add(m_rb_textEncoding2, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+
+    m_ckboxEnableChecksum = new wxCheckBox(this, wxID_ANY, _("Use Checksum on Rx"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_encoding->Add(m_ckboxEnableChecksum, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_encoding,0, wxALL|wxEXPAND, 3);
+    //------------------------------
+    // Event processing
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_events;
+    wxStaticBox *sb_events = new wxStaticBox(this, wxID_ANY, _("Event Processing"));
+    sbSizer_events = new wxStaticBoxSizer(sb_events, wxVERTICAL);
+
+    // event processing enable and spam timer
+
+    wxStaticBoxSizer* sbSizer_events_top;
+    wxStaticBox* sb_events1 = new wxStaticBox(this, wxID_ANY, _(""));    
+    sbSizer_events_top = new wxStaticBoxSizer(sb_events1, wxHORIZONTAL);
+
+    m_ckbox_events = new wxCheckBox(this, wxID_ANY, _("Enable System Calls    Syscall Spam Timer"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_events->SetToolTip(_("Enable processing of events and generation of system calls"));
+    sbSizer_events_top->Add(m_ckbox_events, 0, 0, 5);
+    m_txt_spam_timer = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    m_txt_spam_timer->SetToolTip(_("Many matching events can cause a flood of syscalls. Set minimum time (seconds) between syscalls for each event here"));
+    sbSizer_events_top->Add(m_txt_spam_timer, 0, 0, 5);
+    m_rb_spam_timer = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    m_rb_spam_timer->SetForegroundColour( wxColour(0, 255, 0 ) );
+    sbSizer_events_top->Add(m_rb_spam_timer, 0, 0, 10);
+    sbSizer_events->Add(sbSizer_events_top, 0, 0, 5);
+
+    // list of regexps
+
+    wxStaticBoxSizer* sbSizer_regexp = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Regular Expressions to Process Events")), wxHORIZONTAL);
+    m_txt_events_regexp_match = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
+    m_txt_events_regexp_match->SetToolTip(_("Enter regular expressions to match events"));
+    sbSizer_regexp->Add(m_txt_events_regexp_match, 1, wxEXPAND, 5);
+    m_txt_events_regexp_replace = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
+    m_txt_events_regexp_replace->SetToolTip(_("Enter regular expressions to replace events"));
+    sbSizer_regexp->Add(m_txt_events_regexp_replace, 1, wxEXPAND, 5);
+    sbSizer_events->Add(sbSizer_regexp, 1, wxEXPAND, 5);
+
+    // log of events and responses
+
+    wxStaticBoxSizer* sbSizer_event_log = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Log of Events and Responses")), wxVERTICAL);
+    wxBoxSizer* bSizer33 = new wxBoxSizer(wxHORIZONTAL);
+    m_txt_events_in = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
+    bSizer33->Add(m_txt_events_in, 1, wxEXPAND, 5);
+    m_txt_events_out = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
+    bSizer33->Add(m_txt_events_out, 1, wxEXPAND, 5);
+    sbSizer_event_log->Add(bSizer33, 1, wxEXPAND, 5);
+    sbSizer_events->Add(sbSizer_event_log, 1, wxEXPAND, 5);
+
+    bSizer30->Add(sbSizer_events,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // UDP control port
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_udp;
+    wxStaticBox* sb_udp = new wxStaticBox(this, wxID_ANY, _("UDP Control Port"));
+    sbSizer_udp = new wxStaticBoxSizer(sb_udp, wxHORIZONTAL);
+    m_ckbox_udp_enable = new wxCheckBox(this, wxID_ANY, _("Enable UDP Control Port    UDP Port Number:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_udp->SetToolTip(_("Enable control of FreeDV via UDP port"));
+    sbSizer_udp->Add(m_ckbox_udp_enable, 0,  wxALIGN_CENTER_HORIZONTAL, 5);
+    m_txt_udp_port = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(50,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_udp->Add(m_txt_udp_port, 0, wxALIGN_CENTER_HORIZONTAL, 5);
+
+    bSizer30->Add(sbSizer_udp,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
+
+    //------------------------------
+    // OK - Cancel - Apply Buttons 
+    //------------------------------
+
+    wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_sdbSizer5OK = new wxButton(this, wxID_OK);
+    bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
+
+    m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
+    bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
+
+    m_sdbSizer5Apply = new wxButton(this, wxID_APPLY);
+    bSizer31->Add(m_sdbSizer5Apply, 0, wxALL, 2);
+
+    bSizer30->Add(bSizer31, 0, wxALIGN_CENTER, 0);
+
+    this->SetSizer(bSizer30);
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+     this->Layout();
+
+    this->Centre(wxBOTH);
+    // Connect Events -------------------------------------------------------
+
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
+
+    m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
+    m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
+    m_sdbSizer5Apply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
+
+    m_ckboxTestFrame->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
+    m_ckboxFreeDV700txClip->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
+
+    m_buttonChooseVoiceKeyerWaveFile->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+
+    event_in_serial = 0;
+    event_out_serial = 0;
+}
+
+//-------------------------------------------------------------------------
+// ~OptionsDlg()
+//-------------------------------------------------------------------------
+OptionsDlg::~OptionsDlg()
+{
+
+    // Disconnect Events
+
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
+
+    m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
+    m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
+    m_sdbSizer5Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
+
+    m_ckboxTestFrame->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
+    m_ckboxFreeDV700txClip->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+    m_buttonChooseVoiceKeyerWaveFile->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
+}
+
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void OptionsDlg::ExchangeData(int inout, bool storePersistent)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        m_txtCtrlCallSign->SetValue(wxGetApp().m_callSign);
+
+        /* Voice Keyer */
+
+        m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+        m_txtCtrlVoiceKeyerRxPause->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRxPause));
+        m_txtCtrlVoiceKeyerRepeats->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRepeats));
+
+        m_ckHalfDuplex->SetValue(wxGetApp().m_boolHalfDuplex);
+
+        m_ckboxTestFrame->SetValue(wxGetApp().m_testFrames);
+
+        m_ckboxChannelNoise->SetValue(wxGetApp().m_channel_noise);
+        m_txtNoiseSNR->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_noise_snr));
+
+        m_ckboxTone->SetValue(wxGetApp().m_tone);
+        m_txtToneFreqHz->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_freq_hz));
+        m_txtToneAmplitude->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_amplitude));
+
+        m_ckboxAttnCarrierEn->SetValue(wxGetApp().m_attn_carrier_en);
+        m_txtAttnCarrier->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_attn_carrier));
+
+#ifdef __EXPERIMENTAL_UDP__
+        m_ckbox_events->SetValue(wxGetApp().m_events);
+        m_txt_spam_timer->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_events_spam_timer));
+
+        m_txt_events_regexp_match->SetValue(wxGetApp().m_events_regexp_match);
+        m_txt_events_regexp_replace->SetValue(wxGetApp().m_events_regexp_replace);
+        
+        m_ckbox_udp_enable->SetValue(wxGetApp().m_udp_enable);
+        m_txt_udp_port->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_udp_port));
+
+#ifdef SHORT_VARICODE
+        if (wxGetApp().m_textEncoding == 1)
+            m_rb_textEncoding1->SetValue(true);
+        if (wxGetApp().m_textEncoding == 2)
+            m_rb_textEncoding2->SetValue(true);
+#endif
+        m_ckboxEnableChecksum->SetValue(wxGetApp().m_enable_checksum);
+#endif
+
+        m_ckboxFreeDV700txClip->SetValue(wxGetApp().m_FreeDV700txClip);
+        m_ckboxFreeDV700Combine->SetValue(wxGetApp().m_FreeDV700Combine);
+
+#ifdef __WXMSW__
+        m_ckboxDebugConsole->SetValue(wxGetApp().m_debug_console);
+#endif
+    }
+
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        wxGetApp().m_callSign = m_txtCtrlCallSign->GetValue();
+
+        wxGetApp().m_boolHalfDuplex = m_ckHalfDuplex->GetValue();
+        pConfig->Write(wxT("/Rig/HalfDuplex"), wxGetApp().m_boolHalfDuplex);
+
+        /* Voice Keyer */
+
+        wxGetApp().m_txtVoiceKeyerWaveFile = m_txtCtrlVoiceKeyerWaveFile->GetValue();
+        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
+        long tmp;
+        m_txtCtrlVoiceKeyerRxPause->GetValue().ToLong(&tmp); if (tmp < 0) tmp = 0; wxGetApp().m_intVoiceKeyerRxPause = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
+        m_txtCtrlVoiceKeyerRepeats->GetValue().ToLong(&tmp);
+        if (tmp < 0) tmp = 0; if (tmp > 100) tmp = 100;
+        wxGetApp().m_intVoiceKeyerRepeats = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
+
+        wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
+
+        wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+        long noise_snr;
+        m_txtNoiseSNR->GetValue().ToLong(&noise_snr);
+        wxGetApp().m_noise_snr = (int)noise_snr;
+
+        wxGetApp().m_tone    = m_ckboxTone->GetValue();
+        long tone_freq_hz, tone_amplitude;
+        m_txtToneFreqHz->GetValue().ToLong(&tone_freq_hz);
+        wxGetApp().m_tone_freq_hz = (int)tone_freq_hz;
+        m_txtToneAmplitude->GetValue().ToLong(&tone_amplitude);
+        wxGetApp().m_tone_amplitude = (int)tone_amplitude;
+
+        wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();
+        long attn_carrier;
+        m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+        wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+#ifdef __EXPERIMENTAL_UDP__
+        wxGetApp().m_events        = m_ckbox_events->GetValue();
+        long spam_timer;
+        m_txt_spam_timer->GetValue().ToLong(&spam_timer);
+        wxGetApp().m_events_spam_timer = (int)spam_timer;
+
+        // make sure regexp lists are terminated by a \n
+
+        if (m_txt_events_regexp_match->GetValue().Last() != '\n') {
+            m_txt_events_regexp_match->SetValue(m_txt_events_regexp_match->GetValue()+'\n');
+        }
+        if (m_txt_events_regexp_replace->GetValue().Last() != '\n') {
+            m_txt_events_regexp_replace->SetValue(m_txt_events_regexp_replace->GetValue()+'\n');
+        }
+        wxGetApp().m_events_regexp_match = m_txt_events_regexp_match->GetValue();
+        wxGetApp().m_events_regexp_replace = m_txt_events_regexp_replace->GetValue();
+        wxGetApp().m_udp_enable     = m_ckbox_udp_enable->GetValue();
+        long port;
+        m_txt_udp_port->GetValue().ToLong(&port);
+        wxGetApp().m_udp_port       = (int)port;
+
+#ifdef SHORT_VARICODE
+        if (m_rb_textEncoding1->GetValue())
+            wxGetApp().m_textEncoding = 1;
+        if (m_rb_textEncoding2->GetValue())
+            wxGetApp().m_textEncoding = 2;
+#endif
+        wxGetApp().m_enable_checksum = m_ckboxEnableChecksum->GetValue();
+#endif
+
+        wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
+        wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+
+#ifdef __WXMSW__
+        wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#endif
+
+        if (storePersistent) {
+            pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
+#ifdef SHORT_VARICODE
+            pConfig->Write(wxT("/Data/TextEncoding"), wxGetApp().m_textEncoding);
+#endif
+            pConfig->Write(wxT("/Data/EnableChecksumOnMsgRx"), wxGetApp().m_enable_checksum);
+
+            pConfig->Write(wxT("/Events/enable"), wxGetApp().m_events);
+            pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+            pConfig->Write(wxT("/Events/regexp_match"), wxGetApp().m_events_regexp_match);
+            pConfig->Write(wxT("/Events/regexp_replace"), wxGetApp().m_events_regexp_replace);
+            
+            pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
+            pConfig->Write(wxT("/UDP/port"),  wxGetApp().m_udp_port);
+
+            pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+
+            pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
+
+            pConfig->Write(wxT("/Noise/noise_snr"),  wxGetApp().m_noise_snr);
+
+#ifdef __WXMSW__
+            pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+#endif
+
+            pConfig->Flush();
+        }
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+//-------------------------------------------------------------------------
+// OnOK()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+    //this->EndModal(wxID_OK);
+    g_modal = false;
+    this->Show(false);
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnCancel(wxCommandEvent& event)
+{
+    //this->EndModal(wxID_CANCEL);
+    g_modal = false;
+    this->Show(false);
+}
+
+//-------------------------------------------------------------------------
+// OnApply()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnApply(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_IN, false);
+}
+
+// immediately change flags rather using ExchangeData() so we can switch on and off at run time
+
+void OptionsDlg::OnTestFrame(wxScrollEvent& event) {
+    wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
+}
+
+void OptionsDlg::OnChannelNoise(wxScrollEvent& event) {
+    wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+}
+
+
+void OptionsDlg::OnChooseVoiceKeyerWaveFile(wxCommandEvent& event) {
+     wxFileDialog openFileDialog(
+                                 this,
+                                 wxT("Voice Keyer wave file"),
+                                 wxGetApp().m_txtVoiceKeyerWaveFilePath,
+                                 wxEmptyString,
+                                 wxT("WAV files (*.wav)|*.wav"),
+                                 wxFD_OPEN
+                                 );
+     if(openFileDialog.ShowModal() == wxID_CANCEL) {
+         return;     // the user changed their mind...
+     }
+
+     wxString fileName, extension;
+     wxGetApp().m_txtVoiceKeyerWaveFile = openFileDialog.GetPath();
+     wxFileName::SplitPath(wxGetApp().m_txtVoiceKeyerWaveFile, &wxGetApp().m_txtVoiceKeyerWaveFilePath, &fileName, &extension);
+     m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+}
+
+//  Run time update of carrier amplitude attenuation
+
+void OptionsDlg::OnAttnCarrierEn(wxScrollEvent& event) {
+    long attn_carrier;
+    m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+    wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+    /* uncheck -> checked, attenuate selected carrier */
+
+    if (m_ckboxAttnCarrierEn->GetValue() && !wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 0.25);
+        } else {
+            wxMessageBox("Carrier attenuation feature only works on 700C", wxT("Warning"), wxOK | wxICON_WARNING, this);
+        }
+    }
+
+    /* checked -> unchecked, reset selected carrier */
+
+    if (!m_ckboxAttnCarrierEn->GetValue() && wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 1.0);
+        }
+    }
+        
+    wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();    
+}
+
+void OptionsDlg::OnFreeDV700txClip(wxScrollEvent& event) {
+    wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
+}
+
+void OptionsDlg::OnFreeDV700Combine(wxScrollEvent& event) {
+    wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+}
+
+void OptionsDlg::updateEventLog(wxString event_in, wxString event_out) {
+    wxString event_in_with_serial, event_out_with_serial; 
+    event_in_with_serial.Printf(_T("[%d] %s"), event_in_serial++, event_in);
+    event_out_with_serial.Printf(_T("[%d] %s"), event_out_serial++, event_out);
+
+    m_txt_events_in->AppendText(event_in_with_serial+"\n");
+    m_txt_events_out->AppendText(event_out_with_serial+"\n");
+}
+
+
+void OptionsDlg::OnDebugConsole(wxScrollEvent& event) {
+    wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#ifdef __WXMSW__
+    // somewhere to send printfs while developing, causes conmsole to pop up on Windows
+    if (wxGetApp().m_debug_console) {
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    } 
+#endif
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_options.h b/freedv/tags/1.2.2/freedv-dev/src/dlg_options.h
new file mode 100644 (file)
index 0000000..081448c
--- /dev/null
@@ -0,0 +1,137 @@
+//==========================================================================
+// Name:            dlg_options.h
+// Purpose:         Dialog for controlling misc FreeDV options
+// Created:         Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __OPTIONS_DIALOG__
+#define __OPTIONS_DIALOG__
+
+#include "fdmdv2_main.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class OptionsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class OptionsDlg : public wxDialog
+{
+    public:
+    OptionsDlg( wxWindow* parent,
+               wxWindowID id = wxID_ANY, const wxString& title = _("Options"), 
+                const wxPoint& pos = wxDefaultPosition, 
+#ifdef __WXMSW__
+                /* we add debug console check box for windows */
+                const wxSize& size = wxSize(600,410), 
+#else
+                const wxSize& size = wxSize(600,380), 
+#endif
+               long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~OptionsDlg();
+
+        void    ExchangeData(int inout, bool storePersistent);
+        void    updateEventLog(wxString event_in, wxString event_out);
+
+        bool    enableEventsChecked() {return m_ckbox_events->GetValue();}
+
+        void SetSpamTimerLight(bool state) {
+
+            // Colours don't work on Windows
+
+            if (state) {
+                m_rb_spam_timer->SetForegroundColour( wxColour( 255,0 , 0 ) ); // red
+                m_rb_spam_timer->SetValue(true);
+            }
+            else {
+                m_rb_spam_timer->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
+                m_rb_spam_timer->SetValue(false);
+            }
+        }
+
+
+    protected:
+
+        // Handlers for events.
+
+        void    OnOK(wxCommandEvent& event);
+        void    OnCancel(wxCommandEvent& event);
+        void    OnApply(wxCommandEvent& event);
+        void    OnClose(wxCloseEvent& event);
+        void    OnInitDialog(wxInitDialogEvent& event);
+        void    OnTestFrame(wxScrollEvent& event);
+        void    OnChannelNoise(wxScrollEvent& event);
+        void    OnAttnCarrierEn(wxScrollEvent& event);
+        void    OnFreeDV700txClip(wxScrollEvent& event);
+        void    OnFreeDV700Combine(wxScrollEvent& event);
+        void    OnDebugConsole(wxScrollEvent& event);
+
+        wxTextCtrl   *m_txtCtrlCallSign; // TODO: this should be renamed to tx_txtmsg, and rename all related incl persis strge
+
+        wxCheckBox* m_ckHalfDuplex;
+
+        /* Voice Keyer */
+
+        wxButton     *m_buttonChooseVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRxPause;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRepeats;
+
+        /* test frames, other simulated channel impairments */
+
+        wxCheckBox   *m_ckboxTestFrame;
+        wxCheckBox   *m_ckboxChannelNoise;
+        wxTextCtrl   *m_txtNoiseSNR;
+        wxCheckBox   *m_ckboxAttnCarrierEn;
+        wxTextCtrl   *m_txtAttnCarrier;
+
+        wxCheckBox   *m_ckboxTone;
+        wxTextCtrl   *m_txtToneFreqHz;
+        wxTextCtrl   *m_txtToneAmplitude;
+
+        wxCheckBox   *m_ckboxFreeDV700txClip;
+        wxCheckBox   *m_ckboxFreeDV700Combine;
+
+        wxRadioButton *m_rb_textEncoding1;
+        wxRadioButton *m_rb_textEncoding2;
+        wxCheckBox    *m_ckboxEnableChecksum;
+
+        wxCheckBox   *m_ckbox_events;
+        wxTextCtrl   *m_txt_events_regexp_match;
+        wxTextCtrl   *m_txt_events_regexp_replace;
+        wxTextCtrl   *m_txt_events_in;
+        wxTextCtrl   *m_txt_events_out;
+        wxTextCtrl   *m_txt_spam_timer;
+        wxRadioButton *m_rb_spam_timer;
+
+        wxCheckBox   *m_ckbox_udp_enable;
+        wxTextCtrl   *m_txt_udp_port;
+
+        wxButton*     m_sdbSizer5OK;
+        wxButton*     m_sdbSizer5Cancel;
+        wxButton*     m_sdbSizer5Apply;
+
+        wxCheckBox   *m_ckboxDebugConsole;
+
+        unsigned int  event_in_serial, event_out_serial;
+
+        void OnChooseVoiceKeyerWaveFile(wxCommandEvent& event);
+
+     private:
+};
+
+#endif // __OPTIONS_DIALOG__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_plugin.cpp b/freedv/tags/1.2.2/freedv-dev/src/dlg_plugin.cpp
new file mode 100644 (file)
index 0000000..68610f4
--- /dev/null
@@ -0,0 +1,148 @@
+//==========================================================================
+// Name:            dlg_plugin.cpp
+// Purpose:         Subclasses dialog GUI for PlugIn Config. Creates simple 
+//                  wxWidgets dialog GUI to set a few text strings.
+// Date:            Jan 2016
+// Authors:         David Rowe
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "dlg_plugin.h"
+#include "fdmdv2_main.h"
+
+#ifdef __WIN32__
+#include <wx/msw/registry.h>
+#endif
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+#include <glob.h>
+#include <string.h>
+#endif
+
+#include <sstream>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlugInDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlugInDlg::PlugInDlg(const wxString& title, int numParam, wxString paramName[], wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    m_name = title;
+    m_numParam = numParam;
+    assert(m_numParam <= PLUGIN_MAX_PARAMS);
+
+    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
+    this->SetSizer(mainSizer);
+
+    int i;
+    for (i=0; i<m_numParam; i++) {
+        m_paramName[i] = paramName[i];
+        wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, m_paramName[i]), wxVERTICAL);
+        m_txtCtrlParam[i]= new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
+        staticBoxSizer28a->Add(m_txtCtrlParam[i], 0, 0, 5);
+        mainSizer->Add(staticBoxSizer28a, 0, wxEXPAND, 5);
+    }
+
+    //----------------------------------------------------------------------
+    // OK - Cancel - Apply
+    //----------------------------------------------------------------------
+
+    wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_buttonOK->SetDefault();
+    boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonCancel, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    mainSizer->Add(boxSizer12, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 5);
+
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+    Centre(wxBOTH);
+
+    // Connect events
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(PlugInDlg::OnInitDialog), NULL, this);
+    m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnOK), NULL, this);
+    m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnCancel), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// ~PlugInDlg()
+//-------------------------------------------------------------------------
+PlugInDlg::~PlugInDlg()
+{
+    // Disconnect Events
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(PlugInDlg::OnInitDialog), NULL, this);
+    m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnOK), NULL, this);
+    m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnCancel), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void PlugInDlg::ExchangeData(int inout)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    wxString str;
+    int i;
+    
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        for (i=0; i<m_numParam; i++) {
+            m_txtCtrlParam[i]->SetValue(wxGetApp().m_txtPlugInParam[i]);
+        }
+    }
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        for (i=0; i<m_numParam; i++) {
+          wxGetApp().m_txtPlugInParam[i] = m_txtCtrlParam[i]->GetValue();
+          wxString configStr = "/" + m_name + "/" + m_paramName[i];
+          pConfig->Write(configStr, wxGetApp().m_txtPlugInParam[i]);
+        }
+        pConfig->Flush();
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    this->EndModal(wxID_OK);
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_plugin.h b/freedv/tags/1.2.2/freedv-dev/src/dlg_plugin.h
new file mode 100644 (file)
index 0000000..72efc7b
--- /dev/null
@@ -0,0 +1,65 @@
+//==========================================================================
+// Name:            dlg_ptt.h
+// Purpose:         Subclasses dialog GUI for PTT Config.
+//                  
+// Created:         May. 11, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __PLUGIN_DIALOG__
+#define __PLUGIN_DIALOG__
+
+#include "fdmdv2_main.h"
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/xrc/xh_bmp.h>
+#include <wx/dialog.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/listbox.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/spinctrl.h>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlugInDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlugInDlg : public wxDialog
+{
+    public:
+    PlugInDlg(const wxString& title = _("PTT Config"), int numParam = 0, wxString paramNames[]=NULL, wxWindow* parent=NULL, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(450,300), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
+        virtual ~PlugInDlg();
+        void    ExchangeData(int inout);
+
+    protected:
+        wxString    m_name;
+        int         m_numParam;
+        wxString    m_paramName[PLUGIN_MAX_PARAMS];
+
+        wxTextCtrl* m_txtCtrlParam[PLUGIN_MAX_PARAMS];
+        wxButton*   m_buttonOK;
+        wxButton*   m_buttonCancel;
+
+
+protected:
+
+        void OnOK(wxCommandEvent& event);
+        void OnCancel(wxCommandEvent& event);
+        virtual void OnInitDialog(wxInitDialogEvent& event);
+};
+
+#endif // __PLUGIN_DIALOG__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_ptt.cpp b/freedv/tags/1.2.2/freedv-dev/src/dlg_ptt.cpp
new file mode 100644 (file)
index 0000000..1a04c9c
--- /dev/null
@@ -0,0 +1,570 @@
+//==========================================================================
+// Name:            dlg_ptt.cpp
+// Purpose:         Subclasses dialog GUI for PTT Config. Creates simple 
+//                  wxWidgets dialog GUI to select real/virtual Comm ports.
+// Date:            May 11 2012
+// Authors:         David Rowe, David Witten, Joel Stanley
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "dlg_ptt.h"
+#include "fdmdv2_main.h"
+
+#ifdef __WIN32__
+#include <wx/msw/registry.h>
+#endif
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+#include <glob.h>
+#include <string.h>
+#endif
+
+#include <sstream>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class ComPortsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
+    this->SetSizer(mainSizer);
+    
+    //----------------------------------------------------------------------
+    // Vox tone option
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer28 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("VOX PTT Settings")), wxHORIZONTAL);
+    m_ckLeftChannelVoxTone = new wxCheckBox(this, wxID_ANY, _("Left Channel Vox Tone"), wxDefaultPosition, wxSize(-1,-1), 0);
+    staticBoxSizer28->Add(m_ckLeftChannelVoxTone, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
+
+    mainSizer->Add(staticBoxSizer28, 0, wxEXPAND, 5);
+
+    //----------------------------------------------------------------------
+    // Hamlib for CAT PTT
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxHORIZONTAL);
+    wxGridSizer* gridSizerhl = new wxGridSizer(5, 2, 0, 0);
+    staticBoxSizer18->Add(gridSizerhl, 1, wxEXPAND|wxALIGN_LEFT, 5);
+
+    /* Use Hamlib for PTT checkbox. */
+
+    m_ckUseHamlibPTT = new wxCheckBox(this, wxID_ANY, _("Use Hamlib PTT"), wxDefaultPosition, wxSize(-1, -1), 0);
+    m_ckUseHamlibPTT->SetValue(false);
+    gridSizerhl->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0);
+    gridSizerhl->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND);
+
+    /* Hamlib Rig Type combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbRigName = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, -1), 0, NULL, wxCB_DROPDOWN);
+    wxGetApp().m_hamlib->populateComboBox(m_cbRigName);
+    m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
+    gridSizerhl->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    /* Hamlib Serial Port combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL |  wxALIGN_RIGHT, 20);
+    m_cbSerialPort = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizerhl->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    /* Hamlib Serial Rate combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Rate:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialRate = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizerhl->Add(m_cbSerialRate, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Params:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialParams = new wxStaticText(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, 0);
+    gridSizerhl->Add(m_cbSerialParams, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    mainSizer->Add(staticBoxSizer18, 0, wxEXPAND, 5);
+
+    //----------------------------------------------------------------------
+    // Serial port PTT
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer17 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Serial Port Settings")), wxVERTICAL);
+    mainSizer->Add(staticBoxSizer17, 1, wxEXPAND, 5);
+    wxStaticBoxSizer* staticBoxSizer31 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("PTT Port")), wxVERTICAL);
+    staticBoxSizer17->Add(staticBoxSizer31, 1, wxEXPAND, 5);
+
+#ifdef __WXMSW__
+    m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckUseSerialPTT->SetValue(false);
+    staticBoxSizer31->Add(m_ckUseSerialPTT, 0, wxALIGN_LEFT, 20);
+
+    wxArrayString m_listCtrlPortsArr;
+    m_listCtrlPorts = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(-1,45), m_listCtrlPortsArr, wxLB_SINGLE | wxLB_SORT);
+    staticBoxSizer31->Add(m_listCtrlPorts, 1, wxALIGN_CENTER, 0);
+#endif
+
+#if defined(__WXOSX__) || defined(__WXGTK__)
+    wxBoxSizer* bSizer83;
+    bSizer83 = new wxBoxSizer(wxHORIZONTAL);
+
+    wxGridSizer* gridSizer200 = new wxGridSizer(1, 3, 0, 0);
+    
+    m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckUseSerialPTT->SetValue(false);
+    gridSizer200->Add(m_ckUseSerialPTT, 1, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
+
+    m_staticText12 = new wxStaticText(this, wxID_ANY, _("Serial Device:  "), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText12->Wrap(-1);
+    gridSizer200->Add(m_staticText12, 1,wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
+
+    m_cbCtlDevicePath = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizer200->Add(m_cbCtlDevicePath, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 2);
+    
+    bSizer83->Add(gridSizer200, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 2);
+    staticBoxSizer31->Add(bSizer83, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    wxBoxSizer* boxSizer19 = new wxBoxSizer(wxVERTICAL);
+    staticBoxSizer17->Add(boxSizer19, 1, wxEXPAND, 5);
+    wxStaticBoxSizer* staticBoxSizer16 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Signal polarity")), wxHORIZONTAL);
+    boxSizer19->Add(staticBoxSizer16, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    wxGridSizer* gridSizer17 = new wxGridSizer(2, 2, 0, 0);
+    staticBoxSizer16->Add(gridSizer17, 1, wxEXPAND|wxALIGN_RIGHT, 5);
+
+    m_rbUseDTR = new wxRadioButton(this, wxID_ANY, _("Use DTR"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_rbUseDTR->SetToolTip(_("Toggle DTR line for PTT"));
+    m_rbUseDTR->SetValue(1);
+    gridSizer17->Add(m_rbUseDTR, 0, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
+
+    m_ckDTRPos = new wxCheckBox(this, wxID_ANY, _("DTR = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckDTRPos->SetToolTip(_("Set Polarity of the DTR line"));
+    m_ckDTRPos->SetValue(false);
+    gridSizer17->Add(m_ckDTRPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    m_rbUseRTS = new wxRadioButton(this, wxID_ANY, _("Use RTS"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_rbUseRTS->SetToolTip(_("Toggle the RTS pin for PTT"));
+    m_rbUseRTS->SetValue(1);
+    gridSizer17->Add(m_rbUseRTS, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    m_ckRTSPos = new wxCheckBox(this, wxID_ANY, _("RTS = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckRTSPos->SetValue(false);
+    m_ckRTSPos->SetToolTip(_("Set Polarity of the RTS line"));
+    gridSizer17->Add(m_ckRTSPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    //----------------------------------------------------------------------
+    // OK - Cancel - Apply
+    //----------------------------------------------------------------------
+
+    wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_buttonTest = new wxButton(this, wxID_APPLY, _("Test PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonTest, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_buttonOK->SetDefault();
+    boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonCancel, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonApply = new wxButton(this, wxID_APPLY, _("Apply"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonApply, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    mainSizer->Add(boxSizer12, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 5);
+
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+    Centre(wxBOTH);
+
+    // Connect events
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
+    m_ckUseHamlibPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
+    m_ckUseSerialPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
+    m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
+    m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
+    m_buttonApply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// ~ComPortsDlg()
+//-------------------------------------------------------------------------
+ComPortsDlg::~ComPortsDlg()
+{
+    // Disconnect Events
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
+    m_ckUseHamlibPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
+    m_ckUseSerialPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
+    m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
+    m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
+    m_buttonApply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    populatePortList();
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// populatePortList()
+//-------------------------------------------------------------------------
+void ComPortsDlg::populatePortList()
+{
+
+    /* populate Hamlib serial rate combo box */
+
+    wxString serialRates[] = {"default", "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"}; 
+    for(int i=0; i<WXSIZEOF(serialRates); i++) {
+        m_cbSerialRate->Append(serialRates[i]);
+    }
+
+#ifdef __WXMSW__
+    m_listCtrlPorts->Clear();
+    m_cbSerialPort->Clear();
+    wxArrayString aStr;
+    wxRegKey key(wxRegKey::HKLM, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"));
+    if(!key.Exists())
+    {
+        return;
+    }
+    else
+    {
+        // Get the number of subkeys and enumerate them.
+        if(!key.Open(wxRegKey::Read))
+        {
+            return;
+        }    
+        size_t subkeys;
+        size_t values;
+        if(!key.GetKeyInfo(&subkeys, NULL, &values, NULL))
+        {
+            return;
+        }
+        if(!key.HasValues())
+        {
+            return;
+        }
+        wxString key_name;
+        long el = 1;
+        key.GetFirstValue(key_name, el);
+        wxString valType;
+        wxString key_data;
+        for(unsigned int i = 0; i < values; i++)
+        {
+            key.QueryValue(key_name, key_data);
+            //wxPrintf("Value:  %s Data: %s\n", key_name, key_data);
+            aStr.Add(key_data, 1);
+            key.GetNextValue(key_name, el);
+        }
+    }
+    m_listCtrlPorts->Append(aStr);
+    m_cbSerialPort->Append(aStr);
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+    m_cbSerialPort->Clear();
+    m_cbCtlDevicePath->Clear();
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+       glob_t  gl;
+#ifdef __FreeBSD__
+       if(glob("/dev/tty*", GLOB_MARK, NULL, &gl)==0) {
+#else
+       if(glob("/dev/tty.*", GLOB_MARK, NULL, &gl)==0) {
+#endif
+               for(unsigned int i=0; i<gl.gl_pathc; i++) {
+                       if(gl.gl_pathv[i][strlen(gl.gl_pathv[i])-1]=='/')
+                               continue;
+                               
+                       /* Exclude pseudo TTYs */
+                       if(gl.gl_pathv[i][8] >= 'l' && gl.gl_pathv[i][8] <= 's')
+                               continue;
+                       if(gl.gl_pathv[i][8] >= 'L' && gl.gl_pathv[i][8] <= 'S')
+                               continue;
+
+                       /* Exclude virtual TTYs */
+                       if(gl.gl_pathv[i][8] == 'v')
+                               continue;
+
+                       /* Exclude initial-state and lock-state devices */
+#ifndef __WXOSX__
+                       if(strchr(gl.gl_pathv[i], '.') != NULL)
+                               continue;
+#endif
+
+                       m_cbSerialPort->Append(gl.gl_pathv[i]);
+                       m_cbCtlDevicePath->Append(gl.gl_pathv[i]);
+               }
+               globfree(&gl);
+       }
+#else
+    /* TODO(Joel): http://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them */
+    m_cbSerialPort->Append("/dev/ttyUSB0");
+    m_cbSerialPort->Append("/dev/ttyUSB1");
+    m_cbSerialPort->Append("/dev/ttyS0");
+    m_cbSerialPort->Append("/dev/ttyS1");
+
+    m_cbCtlDevicePath->Clear();
+    m_cbCtlDevicePath->Append("/dev/ttyUSB0");
+    m_cbCtlDevicePath->Append("/dev/ttyUSB1");
+    m_cbCtlDevicePath->Append("/dev/ttyS0");
+    m_cbCtlDevicePath->Append("/dev/ttyS1");
+#endif
+#endif
+
+
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void ComPortsDlg::ExchangeData(int inout)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    wxString str;
+    
+    if(inout == EXCHANGE_DATA_IN) {
+        m_ckLeftChannelVoxTone->SetValue(wxGetApp().m_leftChannelVoxTone);
+
+        /* Hamlib */
+
+        m_ckUseHamlibPTT->SetValue(wxGetApp().m_boolHamlibUseForPTT);
+        m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
+        m_cbSerialPort->SetValue(wxGetApp().m_strHamlibSerialPort);
+
+        if (wxGetApp().m_intHamlibSerialRate == 0) {
+            m_cbSerialRate->SetSelection(0);
+        } else {
+            m_cbSerialRate->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intHamlibSerialRate));
+        }
+
+        /* Serial PTT */
+
+        m_ckUseSerialPTT->SetValue(wxGetApp().m_boolUseSerialPTT);
+        str = wxGetApp().m_strRigCtrlPort;
+#ifdef __WXMSW__
+        m_listCtrlPorts->SetStringSelection(str);
+#endif
+#if defined(__WXOSX__) || defined(__WXGTK__)
+        m_cbCtlDevicePath->SetValue(str);
+#endif
+        m_rbUseRTS->SetValue(wxGetApp().m_boolUseRTS);
+        m_ckRTSPos->SetValue(wxGetApp().m_boolRTSPos);
+        m_rbUseDTR->SetValue(wxGetApp().m_boolUseDTR);
+        m_ckDTRPos->SetValue(wxGetApp().m_boolDTRPos);
+    }
+
+    if (inout == EXCHANGE_DATA_OUT) {
+        wxGetApp().m_leftChannelVoxTone = m_ckLeftChannelVoxTone->GetValue();
+        pConfig->Write(wxT("/Rig/leftChannelVoxTone"), wxGetApp().m_leftChannelVoxTone);
+
+        /* Hamlib settings. */
+
+        wxGetApp().m_boolHamlibUseForPTT = m_ckUseHamlibPTT->GetValue();
+        wxGetApp().m_intHamlibRig = m_cbRigName->GetSelection();
+        wxGetApp().m_strHamlibSerialPort = m_cbSerialPort->GetValue();
+
+        wxString s = m_cbSerialRate->GetValue();
+        if (s == "default") {
+            wxGetApp().m_intHamlibSerialRate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            wxGetApp().m_intHamlibSerialRate = tmp;
+        }
+        fprintf(stderr, "serial rate: %d\n", wxGetApp().m_intHamlibSerialRate);
+
+        pConfig->Write(wxT("/Hamlib/UseForPTT"), wxGetApp().m_boolHamlibUseForPTT);
+        pConfig->Write(wxT("/Hamlib/RigName"), wxGetApp().m_intHamlibRig);
+        pConfig->Write(wxT("/Hamlib/SerialPort"), wxGetApp().m_strHamlibSerialPort);
+        pConfig->Write(wxT("/Hamlib/SerialRate"), wxGetApp().m_intHamlibSerialRate);
+
+        /* Serial settings */
+
+        wxGetApp().m_boolUseSerialPTT           = m_ckUseSerialPTT->IsChecked();
+#ifdef __WXMSW__
+        wxGetApp().m_strRigCtrlPort             = m_listCtrlPorts->GetStringSelection();
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+        wxGetApp().m_strRigCtrlPort             = m_cbCtlDevicePath->GetValue();
+#endif
+        wxGetApp().m_boolUseRTS                 = m_rbUseRTS->GetValue();
+        wxGetApp().m_boolRTSPos                 = m_ckRTSPos->IsChecked();
+        wxGetApp().m_boolUseDTR                 = m_rbUseDTR->GetValue();
+        wxGetApp().m_boolDTRPos                 = m_ckDTRPos->IsChecked();
+        
+        pConfig->Write(wxT("/Rig/UseSerialPTT"),    wxGetApp().m_boolUseSerialPTT);
+        pConfig->Write(wxT("/Rig/Port"),            wxGetApp().m_strRigCtrlPort); 
+        pConfig->Write(wxT("/Rig/UseRTS"),          wxGetApp().m_boolUseRTS);
+        pConfig->Write(wxT("/Rig/RTSPolarity"),     wxGetApp().m_boolRTSPos);
+        pConfig->Write(wxT("/Rig/UseDTR"),          wxGetApp().m_boolUseDTR);
+        pConfig->Write(wxT("/Rig/DTRPolarity"),     wxGetApp().m_boolDTRPos);
+
+        pConfig->Flush();
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+//-------------------------------------------------------------------------
+// PTTUseHamLibClicked()
+//-------------------------------------------------------------------------
+void ComPortsDlg::PTTUseHamLibClicked(wxCommandEvent& event)
+{
+    m_ckUseSerialPTT->SetValue(false);
+}
+
+
+/* Attempt to toggle PTT for 1 second */
+
+void ComPortsDlg::OnTest(wxCommandEvent& event) {
+
+    /* Tone PTT */
+
+    if (m_ckLeftChannelVoxTone->GetValue()) {
+        wxMessageBox("Testing of tone based PTT not supported; try PTT after pressing Start on main window", 
+                     wxT("Error"), wxOK | wxICON_ERROR, this);
+    }
+
+    /* Hamlib PTT */
+
+    if (m_ckUseHamlibPTT->GetValue()) {
+
+        // set up current hamlib config from GUI
+
+        int rig = m_cbRigName->GetSelection();
+        wxString port = m_cbSerialPort->GetValue();
+        wxString s = m_cbSerialRate->GetValue();
+        int serial_rate;
+        if (s == "default") {
+            serial_rate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            serial_rate = tmp;
+        }
+
+        // display serial params
+
+        fprintf(stderr, "serial rate: %d\n", serial_rate);
+
+        // try to open rig
+
+        Hamlib *hamlib = wxGetApp().m_hamlib; 
+        bool status = hamlib->connect(rig, port.mb_str(wxConvUTF8), serial_rate);
+        if (status == false) {
+            wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+        else {
+            wxString hamlib_serial_config;
+            hamlib_serial_config.sprintf(" %d, %d, %d", 
+                                         hamlib->get_serial_rate(),
+                                         hamlib->get_data_bits(),
+                                         hamlib->get_stop_bits());
+            m_cbSerialParams->SetLabel(hamlib_serial_config);
+       }
+
+        // toggle PTT
+
+        wxString hamlibError;
+        if (hamlib->ptt(true, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+
+        wxSleep(1);
+
+        if (hamlib->ptt(false, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+    }
+
+    /* Serial PTT */
+
+    if (m_ckUseSerialPTT->IsChecked()) {
+        Serialport *serialport = wxGetApp().m_serialport; 
+        
+        wxString ctrlport;
+#ifdef __WXMSW__
+        ctrlport = m_listCtrlPorts->GetStringSelection();
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+        ctrlport = m_cbCtlDevicePath->GetValue();
+#endif
+        fprintf(stderr, "opening serial port\n");
+
+        bool success = serialport->openport(ctrlport.c_str(),
+                                            m_rbUseRTS->GetValue(),
+                                            m_ckRTSPos->IsChecked(),
+                                            m_rbUseDTR->GetValue(),
+                                            m_ckDTRPos->IsChecked());
+
+        fprintf(stderr, "serial port open\n");
+
+        if (!success) {
+            wxMessageBox("Couldn't open serial port", wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+
+        // assert PTT port for 1 sec
+
+        serialport->ptt(true);
+        wxSleep(1);
+        serialport->ptt(false);
+
+        fprintf(stderr, "closing serial port\n");
+        serialport->closeport();
+        fprintf(stderr, "serial port closed\n");
+    }
+    
+}
+
+
+//-------------------------------------------------------------------------
+// PTTUseSerialClicked()
+//-------------------------------------------------------------------------
+void ComPortsDlg::PTTUseSerialClicked(wxCommandEvent& event)
+{
+    m_ckUseHamlibPTT->SetValue(false);
+}
+
+//-------------------------------------------------------------------------
+// OnApply()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnApply(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    this->EndModal(wxID_OK);
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/dlg_ptt.h b/freedv/tags/1.2.2/freedv-dev/src/dlg_ptt.h
new file mode 100644 (file)
index 0000000..5a35c3b
--- /dev/null
@@ -0,0 +1,95 @@
+//==========================================================================
+// Name:            dlg_ptt.h
+// Purpose:         Subclasses dialog GUI for PTT Config.
+//                  
+// Created:         May. 11, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __COMPORTS_DIALOG__
+#define __COMPORTS_DIALOG__
+
+#include "fdmdv2_main.h"
+#include "hamlib.h"
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/xrc/xh_bmp.h>
+#include <wx/dialog.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/listbox.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/spinctrl.h>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class ComPortsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class ComPortsDlg : public wxDialog
+{
+     public:
+        ComPortsDlg(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PTT Config"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(450,300), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
+        virtual ~ComPortsDlg();
+        void    ExchangeData(int inout);
+
+    protected:
+        wxCheckBox* m_ckLeftChannelVoxTone;
+
+        /* Hamlib settings.*/
+
+        wxCheckBox *m_ckUseHamlibPTT;
+        wxComboBox *m_cbRigName;
+        wxComboBox *m_cbSerialPort;
+        wxComboBox *m_cbSerialRate;
+        wxStaticText  *m_cbSerialParams;
+        Hamlib *m_hamlib;
+
+        /* Serial Settings */
+
+        wxListBox     *m_listCtrlPorts;
+        wxCheckBox    *m_ckUseSerialPTT;
+        wxStaticText  *m_staticText12;
+        wxComboBox    *m_cbCtlDevicePath;
+        wxRadioButton *m_rbUseDTR;
+        wxCheckBox    *m_ckRTSPos;
+        wxRadioButton *m_rbUseRTS;
+        wxCheckBox    *m_ckDTRPos;
+
+        /* Test - Ok - Cancel - Apply */
+
+        wxButton* m_buttonTest;
+        wxButton* m_buttonOK;
+        wxButton* m_buttonCancel;
+        wxButton* m_buttonApply;
+
+
+protected:
+        void populatePortList();
+
+        void PTTUseHamLibClicked(wxCommandEvent& event);
+        void PTTUseSerialClicked(wxCommandEvent& event);
+
+        void OnTest(wxCommandEvent& event);
+
+        void OnOK(wxCommandEvent& event);
+        void OnCancel(wxCommandEvent& event);
+        void OnApply(wxCommandEvent& event);
+        virtual void OnInitDialog(wxInitDialogEvent& event);
+    
+};
+
+#endif // __COMPORTS_DIALOG__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_defines.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_defines.h
new file mode 100644 (file)
index 0000000..a687889
--- /dev/null
@@ -0,0 +1,106 @@
+//==========================================================================
+// Name:            fdmdv2_defines.h
+// Purpose:         Definitions used by plots derived from fdmdv2_plot class.
+// Created:         August 27, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_DEFINES__
+#define __FDMDV2_DEFINES__
+
+#include "wx/wx.h"
+#include "freedv_api.h"
+#include "modem_stats.h"
+
+// Spectrogram and Waterfall
+
+#define MIN_MAG_DB        -40.0     // min of spectrogram/waterfall magnitude axis
+#define MAX_MAG_DB          0.0     // max of spectrogram/waterfall magnitude axis
+#define STEP_MAG_DB         5.0     // magnitude axis step
+#define BETA                0.95    // constant for time averaging spectrum data
+#define MIN_F_HZ            0       // min freq on Waterfall and Spectrum
+#define MAX_F_HZ            3000    // max freq on Waterfall and Spectrum
+#define STEP_F_HZ           500     // major (e.g. text legend) freq step on Waterfall and Spectrum graticule
+#define STEP_MINOR_F_HZ     100     // minor (ticks) freq step on Waterfall and Spectrum graticule
+#define WATERFALL_SECS_Y    30      // number of seconds respresented by y axis of waterfall
+#define WATERFALL_SECS_STEP 5       // graticule y axis steps of waterfall
+#define DT                  0.1     // time between real time graphing updates
+#define FS                  8000    // FDMDV modem sample rate
+
+// Scatter diagram 
+
+#define SCATTER_MEM_SECS    10
+// (symbols/frame)/(graphics update period) = symbols/s sent to scatter memory
+// memory (symbols) = secs of memory * symbols/sec
+#define SCATTER_MEM_SYMS_MAX    ((int)(SCATTER_MEM_SECS*((MODEM_STATS_NC_MAX+1)/DT)))
+#define SCATTER_EYE_MEM_ROWS    ((int)(SCATTER_MEM_SECS/DT))
+
+// Waveform plotting constants
+
+#define WAVEFORM_PLOT_FS    400                            // sample rate (points/s) of waveform plotted to screen
+#define WAVEFORM_PLOT_TIME  5                              // length or entire waveform on screen
+#define WAVEFORM_PLOT_BUF   ((int)(DT*WAVEFORM_PLOT_FS))   // number of new samples we plot per DT
+
+// sample rate I/O & conversion constants
+
+#define MAX_FPB             8096                           // maximum value of portAudio framesPerBuffer
+#define PA_FPB              1024                           // nominal value of portAudio framesPerBuffer
+#define SAMPLE_RATE         48000                          // 48 kHz sampling rate rec. as we can trust accuracy of sound card
+#define N8                  160                            // processing buffer size at 8 kHz
+#define MEM8                (FDMDV_OS_TAPS/FDMDV_OS)
+#define N48                 (N8*SAMPLE_RATE/FS)            // processing buffer size at 48 kHz
+#define NUM_CHANNELS        2                              // I think most sound cards prefer stereo we will convert to mono
+#define VOX_TONE_FREQ       1000.0                         // optional left channel vox tone freq
+#define VOX_TONE_AMP        30000                          // optional left channel vox tone amp
+
+#define MAX_BITS_PER_CODEC_FRAME 64                            // 1600 bit/s mode
+#define MAX_BYTES_PER_CODEC_FRAME (MAX_BITS_PER_CODEC_FRAME/8)
+#define MAX_BITS_PER_FDMDV_FRAME 40                            // 2000 bit/s mode
+
+// Squelch
+#define SQ_DEFAULT_SNR       2.0
+
+// Level Gauge
+#define FROM_RADIO_MAX       0.8
+#define FROM_MIC_MAX         0.8
+#define LEVEL_BETA           0.99
+
+// SNR
+#define SNRSLOW_BETA        0.5                           // time constant for slow SNR for display
+
+// Text messaging Data
+#define MAX_CALLSIGN         80
+#define MAX_EVENT_LOG        10
+#define MAX_EVENT_RULES      100
+   
+enum
+{
+    ID_ROTATE_LEFT = wxID_HIGHEST + 1,
+    ID_ROTATE_RIGHT,
+    ID_RESIZE,
+    ID_PAINT_BG
+};
+
+// Codec 2 LPC Post Filter defaults, from codec-dev/src/quantise.c
+
+#define CODEC2_LPC_PF_GAMMA 0.5
+#define CODEC2_LPC_PF_BETA  0.2
+
+// PlugIns ...
+
+#define PLUGIN_MAX_PARAMS 4
+
+#endif  //__FDMDV2_DEFINES__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_main.cpp b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_main.cpp
new file mode 100644 (file)
index 0000000..506406c
--- /dev/null
@@ -0,0 +1,4042 @@
+//==========================================================================
+// Name:            fdmdv2_main.cpp
+//
+// Purpose:         FreeDV main()
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "fdmdv2_main.h"
+
+#define wxUSE_FILEDLG   1
+#define wxUSE_LIBPNG    1
+#define wxUSE_LIBJPEG   1
+#define wxUSE_GIF       1
+#define wxUSE_PCX       1
+#define wxUSE_LIBTIFF   1
+
+//-------------------------------------------------------------------
+// Bunch of globals used for communication with sound card call
+// back functions
+// ------------------------------------------------------------------
+
+int g_in, g_out;
+
+// Global Codec2 & modem states - just one reqd for tx & rx
+int                 g_Nc;
+int                 g_mode;
+struct freedv      *g_pfreedv;
+struct MODEM_STATS  g_stats;
+float               g_pwr_scale;
+int                 g_clip;
+
+// test Frames
+int                 g_testFrames;
+int                 g_test_frame_sync_state;
+int                 g_test_frame_count;
+int                 g_channel_noise;
+int                 g_resyncs;
+float               g_sig_pwr_av = 0.0;
+struct FIFO        *g_error_pattern_fifo;
+short              *g_error_hist, *g_error_histn;
+float               g_tone_phase;
+
+// time averaged magnitude spectrum used for waterfall and spectrum display
+float               g_avmag[MODEM_STATS_NSPEC];
+
+// GUI controls that affect rx and tx processes
+int   g_SquelchActive;
+float g_SquelchLevel;
+int   g_analog;
+int   g_split;
+int   g_tx;
+float g_snr;
+bool  g_half_duplex;
+bool  g_modal;
+
+// sending and receiving Call Sign data
+struct FIFO         *g_txDataInFifo;
+struct FIFO         *g_rxDataOutFifo;
+
+// tx/rx processing states
+int                 g_State, g_prev_State;
+paCallBackData     *g_rxUserdata;
+
+// FIFOs used for plotting waveforms
+struct FIFO        *g_plotDemodInFifo;
+struct FIFO        *g_plotSpeechOutFifo;
+struct FIFO        *g_plotSpeechInFifo;
+
+// Soundcard config
+int                 g_nSoundCards;
+int                 g_soundCard1InDeviceNum;
+int                 g_soundCard1OutDeviceNum;
+int                 g_soundCard1SampleRate;
+int                 g_soundCard2InDeviceNum;
+int                 g_soundCard2OutDeviceNum;
+int                 g_soundCard2SampleRate;
+
+// playing and recording from sound files
+
+SNDFILE            *g_sfPlayFile;
+bool                g_playFileToMicIn;
+bool                g_loopPlayFileToMicIn;
+int                 g_playFileToMicInEventId;
+
+SNDFILE            *g_sfRecFile;
+bool                g_recFileFromRadio;
+unsigned int        g_recFromRadioSamples;
+int                 g_recFileFromRadioEventId;
+
+SNDFILE            *g_sfPlayFileFromRadio;
+bool                g_playFileFromRadio;
+int                 g_sfFs;
+bool                g_loopPlayFileFromRadio;
+int                 g_playFileFromRadioEventId;
+float               g_blink;
+
+wxWindow           *g_parent;
+
+// Click to tune rx and tx frequency offset states
+float               g_RxFreqOffsetHz;
+COMP                g_RxFreqOffsetPhaseRect;
+float               g_TxFreqOffsetHz;
+COMP                g_TxFreqOffsetPhaseRect;
+
+// experimental mutex to make sound card callbacks mutually exclusive
+// TODO: review code and see if we need this any more, as fifos should
+// now be thread safe
+
+wxMutex g_mutexProtectingCallbackData;
+
+// Speex pre-processor states
+
+SpeexPreprocessState *g_speex_st;
+
+// WxWidgets - initialize the application
+IMPLEMENT_APP(MainApp);
+
+//FILE *ftest;
+FILE *g_logfile;
+
+//-------------------------------------------------------------------------
+// OnInit()
+//-------------------------------------------------------------------------
+bool MainApp::OnInit()
+{
+    if(!wxApp::OnInit())
+    {
+        return false;
+    }
+    SetVendorName(wxT("CODEC2-Project"));
+    SetAppName(wxT("FreeDV"));      // not needed, it's the default value
+
+#ifdef FILE_RATHER_THAN_REGISTRY
+    // Force use of file-based configuration persistance on Windows platforma
+    wxConfig *pConfig = new wxConfig();
+    wxFileConfig *pFConfig = new wxFileConfig(wxT("FreeDV"), wxT("CODEC2-Project"), wxT("FreeDV.conf"), wxT("FreeDV.conf"),  wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
+    pConfig->Set(pFConfig);
+    pConfig->SetRecordDefaults();
+#else
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    pConfig->SetRecordDefaults();
+#endif
+
+    m_rTopWindow = wxRect(0, 0, 0, 0);
+    m_strRxInAudio.Empty();
+    m_strRxOutAudio.Empty();
+    m_textVoiceInput.Empty();
+    m_textVoiceOutput.Empty();
+    m_strSampleRate.Empty();
+    m_strBitrate.Empty();
+
+    // Look for Plug In
+
+    m_plugIn = false;
+    #ifdef __WXMSW__
+    wchar_t dll_path[] = L"afreedvplugin.dll";
+    m_plugInHandle = LoadLibrary(dll_path);
+    #else
+    m_plugInHandle = dlopen("afreedvplugin.so", RTLD_LAZY);
+    #endif
+    
+    if (m_plugInHandle) {
+        printf("plugin: .so found\n");
+        
+        // lets get some information abt the plugIn
+
+        void (*plugin_namefp)(char s[]);
+        void *(*plugin_openfp)(char *param_names[], int *nparams, int (*aplugin_get_persistant)(char *, char *));
+
+        #ifdef __WXMSW__
+        plugin_namefp = (void (*)(char*))GetProcAddress((HMODULE)m_plugInHandle, "plugin_name");
+        plugin_openfp = (void* (*)(char**,int *, int (*)(char *, char *)))GetProcAddress((HMODULE)m_plugInHandle, "plugin_open");
+        m_plugin_startfp = (void (*)(void *))GetProcAddress((HMODULE)m_plugInHandle, "plugin_start");
+        m_plugin_stopfp = (void (*)(void *))GetProcAddress((HMODULE)m_plugInHandle, "plugin_stop");
+        m_plugin_rx_samplesfp = (void (*)(void *, short *, int))GetProcAddress((HMODULE)m_plugInHandle, "plugin_rx_samples");
+        #else
+        plugin_namefp = (void (*)(char*))dlsym(m_plugInHandle, "plugin_name");
+        plugin_openfp = (void* (*)(char**,int *, int (*)(char *, char *)))dlsym(m_plugInHandle, "plugin_open");
+        m_plugin_startfp = (void (*)(void *))dlsym(m_plugInHandle, "plugin_start");
+        m_plugin_stopfp = (void (*)(void *))dlsym(m_plugInHandle, "plugin_stop");
+        m_plugin_rx_samplesfp = (void (*)(void *, short *, int))dlsym(m_plugInHandle, "plugin_rx_samples");
+        #endif
+        
+        if ((plugin_namefp != NULL) && (plugin_openfp != NULL)) {
+
+            char s[256];
+            m_plugIn = true;
+            (plugin_namefp)(s);
+            fprintf(stderr, "plugin name: %s\n", s);
+            m_plugInName = s;
+
+            char param_name1[80], param_name2[80];
+            char *param_names[2] = {param_name1, param_name2};
+            int  nparams, i;
+            m_plugInStates = (plugin_openfp)(param_names, &nparams, plugin_get_persistant);
+            m_numPlugInParam = nparams;
+            for(i=0; i<nparams; i++) {
+                m_plugInParamName[i] = param_names[i];
+                wxString configStr = "/" + m_plugInName + "/" + m_plugInParamName[i];
+                m_txtPlugInParam[i] = pConfig->Read(configStr, wxT(""));
+                //fprintf(stderr, "  plugin param name[%d]: %s\n", i, param_names[i]);
+                fprintf(stderr, "  plugin param name[%d]: %s values: %s\n", i, m_plugInParamName[i].mb_str().data(), m_txtPlugInParam[i].mb_str().data());
+            }
+        }
+        
+        else {
+            fprintf(stderr, "plugin: fps not found...\n");           
+        }
+    }
+    else {
+        fprintf(stderr, "plugin not found...\n");           
+    }
+
+    // Create the main application window
+
+    frame = new MainFrame(m_plugInName, NULL);
+    SetTopWindow(frame);
+
+    // Should guarantee that the first plot tab defined is the one
+    // displayed. But it doesn't when built from command line.  Why?
+
+    frame->m_auiNbookCtrl->ChangeSelection(0);
+    frame->Layout();
+    frame->Show();
+    g_parent =frame;
+
+
+    return true;
+}
+
+//-------------------------------------------------------------------------
+// OnExit()
+//-------------------------------------------------------------------------
+int MainApp::OnExit()
+{
+    fprintf(stderr, "MainApp::OnExit\n");
+    if (m_plugIn) {
+        #ifdef __WXMSW__
+        FreeLibrary((HMODULE)m_plugInHandle);
+        #else
+        dlclose(m_plugInHandle);
+        #endif
+    }
+
+    return 0;
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainFrame(wxFrame* pa->ent) : TopFrame(parent)
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInName, parent)
+{
+    m_zoom              = 1.;
+
+    #ifdef __WXMSW__
+    g_logfile = stderr;
+    #else
+    g_logfile = stderr;
+    #endif
+
+
+    SetMinSize(wxSize(400,400));
+
+    // Init Hamlib library, but we dont start talking to any rigs yet
+
+    wxGetApp().m_hamlib = new Hamlib();
+
+    // Init Serialport library, but as for Hamlib we dont start talking to any rigs yet
+
+    wxGetApp().m_serialport = new Serialport();
+
+    tools->AppendSeparator();
+    wxMenuItem* m_menuItemToolsConfigDelete;
+    m_menuItemToolsConfigDelete = new wxMenuItem(tools, wxID_ANY, wxString(_("&Restore defaults")) , wxT("Delete config file/keys and restore defaults"), wxITEM_NORMAL);
+    this->Connect(m_menuItemToolsConfigDelete->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnDeleteConfig));
+
+    tools->Append(m_menuItemToolsConfigDelete);
+
+    wxConfigBase *pConfig = wxConfigBase::Get();
+
+    // restore frame position and size
+    int x = pConfig->Read(wxT("/MainFrame/left"),       20);
+    int y = pConfig->Read(wxT("/MainFrame/top"),        20);
+    int w = pConfig->Read(wxT("/MainFrame/width"),     800);
+    int h = pConfig->Read(wxT("/MainFrame/height"),    550);
+
+    // sanitise frame position as a first pass at Win32 registry bug
+
+    fprintf(g_logfile, "x = %d y = %d w = %d h = %d\n", x,y,w,h);
+    if (x < 0 || x > 2048) x = 20;
+    if (y < 0 || y > 2048) y = 20;
+    if (w < 0 || w > 2048) w = 800;
+    if (h < 0 || h > 2048) h = 550;
+
+    wxGetApp().m_show_wf            = pConfig->Read(wxT("/MainFrame/show_wf"),           1);
+    wxGetApp().m_show_spect         = pConfig->Read(wxT("/MainFrame/show_spect"),        1);
+    wxGetApp().m_show_scatter       = pConfig->Read(wxT("/MainFrame/show_scatter"),      1);
+    wxGetApp().m_show_timing        = pConfig->Read(wxT("/MainFrame/show_timing"),       1);
+    wxGetApp().m_show_freq          = pConfig->Read(wxT("/MainFrame/show_freq"),         1);
+    wxGetApp().m_show_speech_in     = pConfig->Read(wxT("/MainFrame/show_speech_in"),    1);
+    wxGetApp().m_show_speech_out    = pConfig->Read(wxT("/MainFrame/show_speech_out"),   1);
+    wxGetApp().m_show_demod_in      = pConfig->Read(wxT("/MainFrame/show_demod_in"),     1);
+    wxGetApp().m_show_test_frame_errors = pConfig->Read(wxT("/MainFrame/show_test_frame_errors"),     1);
+    wxGetApp().m_show_test_frame_errors_hist = pConfig->Read(wxT("/MainFrame/show_test_frame_errors_hist"),     1);
+
+    wxGetApp().m_rxNbookCtrl        = pConfig->Read(wxT("/MainFrame/rxNbookCtrl"),    (long)0);
+
+    g_SquelchActive = pConfig->Read(wxT("/Audio/SquelchActive"), (long)0);
+    g_SquelchLevel = pConfig->Read(wxT("/Audio/SquelchLevel"), (int)(SQ_DEFAULT_SNR*2));
+    g_SquelchLevel /= 2.0;
+
+    Move(x, y);
+    SetClientSize(w, h);
+    
+    if(wxGetApp().m_show_wf)
+    {
+        // Add Waterfall Plot window
+        m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl, false, 0);
+        m_panelWaterfall->SetToolTip(_("Left click to tune, Right click to toggle mono/colour"));
+        m_auiNbookCtrl->AddPage(m_panelWaterfall, _("Waterfall"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_spect)
+    {
+        // Add Spectrum Plot window
+        m_panelSpectrum = new PlotSpectrum((wxFrame*) m_auiNbookCtrl, g_avmag,
+                                           MODEM_STATS_NSPEC*((float)MAX_F_HZ/MODEM_STATS_MAX_F_HZ));
+        m_panelSpectrum->SetToolTip(_("Left click to tune"));
+        m_auiNbookCtrl->AddPage(m_panelSpectrum, _("Spectrum"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_scatter)
+    {
+        // Add Scatter Plot window
+        m_panelScatter = new PlotScatter((wxFrame*) m_auiNbookCtrl);
+        m_auiNbookCtrl->AddPage(m_panelScatter, _("Scatter"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_demod_in)
+    {
+        // Add Demod Input window
+        m_panelDemodIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelDemodIn, _("Frm Radio"), true, wxNullBitmap);
+        g_plotDemodInFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_speech_in)
+    {
+        // Add Speech Input window
+        m_panelSpeechIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelSpeechIn, _("Frm Mic"), true, wxNullBitmap);
+        g_plotSpeechInFifo = fifo_create(4*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_speech_out)
+    {
+        // Add Speech Output window
+        m_panelSpeechOut = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelSpeechOut, _("To Spkr/Hdphns"), true, wxNullBitmap);
+        g_plotSpeechOutFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_timing)
+    {
+        // Add Timing Offset window
+        m_panelTimeOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 5.0, DT, -0.5, 0.5, 1, 0.1, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelTimeOffset, L"Timing \u0394", true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_freq)
+    {
+        // Add Frequency Offset window
+        m_panelFreqOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 5.0, DT, -200, 200, 1, 50, "%3.0fHz", 0);
+        m_auiNbookCtrl->AddPage(m_panelFreqOffset, L"Frequency \u0394", true, wxNullBitmap);
+    }
+
+    if(wxGetApp().m_show_test_frame_errors)
+    {
+        // Add Test Frame Errors window
+        m_panelTestFrameErrors = new PlotScalar((wxFrame*) m_auiNbookCtrl, 2*MODEM_STATS_NC_MAX, 30.0, DT, 0, 2*MODEM_STATS_NC_MAX+2, 1, 1, "", 1);
+        m_auiNbookCtrl->AddPage(m_panelTestFrameErrors, L"Test Frame Errors", true, wxNullBitmap);
+    }
+
+    if(wxGetApp().m_show_test_frame_errors_hist)
+    {
+        // Add Test Frame Historgram window.  1 column for every bit, 2 bits per carrier
+        m_panelTestFrameErrorsHist = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 1.0, 1.0/(2*FDMDV_NC_MAX), 0.001, 0.1, 1.0/FDMDV_NC_MAX, 0.1, "%0.0E", 0);
+        m_auiNbookCtrl->AddPage(m_panelTestFrameErrorsHist, L"Test Frame Histogram", true, wxNullBitmap);
+        m_panelTestFrameErrorsHist->setBarGraph(1);
+        m_panelTestFrameErrorsHist->setLogY(1);
+    }
+
+    wxGetApp().m_framesPerBuffer = pConfig->Read(wxT("/Audio/framesPerBuffer"), PA_FPB);
+
+    g_soundCard1InDeviceNum  = pConfig->Read(wxT("/Audio/soundCard1InDeviceNum"),         -1);
+    g_soundCard1OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard1OutDeviceNum"),        -1);
+    g_soundCard1SampleRate   = pConfig->Read(wxT("/Audio/soundCard1SampleRate"),          -1);
+
+    g_soundCard2InDeviceNum  = pConfig->Read(wxT("/Audio/soundCard2InDeviceNum"),         -1);
+    g_soundCard2OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard2OutDeviceNum"),        -1);
+    g_soundCard2SampleRate   = pConfig->Read(wxT("/Audio/soundCard2SampleRate"),          -1);
+
+    g_nSoundCards = 0;
+    if ((g_soundCard1InDeviceNum > -1) && (g_soundCard1OutDeviceNum > -1)) {
+        g_nSoundCards = 1;
+        if ((g_soundCard2InDeviceNum > -1) && (g_soundCard2OutDeviceNum > -1))
+            g_nSoundCards = 2;
+    }
+
+    wxGetApp().m_playFileToMicInPath = pConfig->Read("/File/playFileToMicInPath",   wxT(""));
+    wxGetApp().m_recFileFromRadioPath = pConfig->Read("/File/recFileFromRadioPath", wxT(""));
+    wxGetApp().m_recFileFromRadioSecs = pConfig->Read("/File/recFileFromRadioSecs", 30);
+    wxGetApp().m_playFileFromRadioPath = pConfig->Read("/File/playFileFromRadioPath", wxT(""));
+
+    // PTT -------------------------------------------------------------------
+
+    wxGetApp().m_boolHalfDuplex     = pConfig->ReadBool(wxT("/Rig/HalfDuplex"),     true);
+    wxGetApp().m_leftChannelVoxTone = pConfig->ReadBool("/Rig/leftChannelVoxTone",  false);
+    wxGetApp().m_txtVoiceKeyerWaveFilePath = pConfig->Read(wxT("/VoiceKeyer/WaveFilePath"), wxT(""));
+    wxGetApp().m_txtVoiceKeyerWaveFile = pConfig->Read(wxT("/VoiceKeyer/WaveFile"), wxT("voicekeyer.wav"));
+    wxGetApp().m_intVoiceKeyerRxPause = pConfig->Read(wxT("/VoiceKeyer/RxPause"), 10);
+    wxGetApp().m_intVoiceKeyerRepeats = pConfig->Read(wxT("/VoiceKeyer/Repeats"), 5);
+    wxGetApp().m_boolHamlibUseForPTT = pConfig->ReadBool("/Hamlib/UseForPTT", false);
+    wxGetApp().m_intHamlibRig = pConfig->ReadLong("/Hamlib/RigName", 0);
+    wxGetApp().m_strHamlibSerialPort = pConfig->Read("/Hamlib/SerialPort", "");
+    wxGetApp().m_intHamlibSerialRate = pConfig->ReadLong("/Hamlib/SerialRate", 0);
+    
+    wxGetApp().m_boolUseSerialPTT   = pConfig->ReadBool(wxT("/Rig/UseSerialPTT"),   false);
+    wxGetApp().m_strRigCtrlPort     = pConfig->Read(wxT("/Rig/Port"),               wxT(""));
+    wxGetApp().m_boolUseRTS         = pConfig->ReadBool(wxT("/Rig/UseRTS"),         true);
+    wxGetApp().m_boolRTSPos         = pConfig->ReadBool(wxT("/Rig/RTSPolarity"),    true);
+    wxGetApp().m_boolUseDTR         = pConfig->ReadBool(wxT("/Rig/UseDTR"),         false);
+    wxGetApp().m_boolDTRPos         = pConfig->ReadBool(wxT("/Rig/DTRPolarity"),    false);
+
+    assert(wxGetApp().m_serialport != NULL);
+
+    // -----------------------------------------------------------------------
+
+    bool slow = false; // prevents compile error when using default bool
+    wxGetApp().m_snrSlow = pConfig->Read("/Audio/snrSlow", slow);
+
+    bool t = true;     // prevents compile error when using default bool
+    wxGetApp().m_codec2LPCPostFilterEnable     = pConfig->Read(wxT("/Filter/codec2LPCPostFilterEnable"),    t);
+    wxGetApp().m_codec2LPCPostFilterBassBoost  = pConfig->Read(wxT("/Filter/codec2LPCPostFilterBassBoost"), t);
+    wxGetApp().m_codec2LPCPostFilterGamma      = (float)pConfig->Read(wxT("/Filter/codec2LPCPostFilterGamma"),     CODEC2_LPC_PF_GAMMA*100)/100.0;
+    wxGetApp().m_codec2LPCPostFilterBeta       = (float)pConfig->Read(wxT("/Filter/codec2LPCPostFilterBeta"),      CODEC2_LPC_PF_BETA*100)/100.0;
+    //printf("main(): m_codec2LPCPostFilterBeta: %f\n", wxGetApp().m_codec2LPCPostFilterBeta);
+
+    wxGetApp().m_speexpp_enable     = pConfig->Read(wxT("/Filter/speexpp_enable"),    t);
+
+    wxGetApp().m_MicInBassFreqHz = (float)pConfig->Read(wxT("/Filter/MicInBassFreqHz"),    1);
+    wxGetApp().m_MicInBassGaindB = (float)pConfig->Read(wxT("/Filter/MicInBassGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInTrebleFreqHz = (float)pConfig->Read(wxT("/Filter/MicInTrebleFreqHz"),    1);
+    wxGetApp().m_MicInTrebleGaindB = (float)pConfig->Read(wxT("/Filter/MicInTrebleGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInMidFreqHz = (float)pConfig->Read(wxT("/Filter/MicInMidFreqHz"),    1);
+    wxGetApp().m_MicInMidGaindB = (float)pConfig->Read(wxT("/Filter/MicInMidGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInMidQ = (float)pConfig->Read(wxT("/Filter/MicInMidQ"),              (long)100)/100.0;
+
+    bool f = false;
+    wxGetApp().m_MicInEQEnable = (float)pConfig->Read(wxT("/Filter/MicInEQEnable"), f);
+
+    wxGetApp().m_SpkOutBassFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutBassFreqHz"),    1);
+    wxGetApp().m_SpkOutBassGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutBassGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutTrebleFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutTrebleFreqHz"),    1);
+    wxGetApp().m_SpkOutTrebleGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutTrebleGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutMidFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutMidFreqHz"),    1);
+    wxGetApp().m_SpkOutMidGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutMidGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutMidQ = (float)pConfig->Read(wxT("/Filter/SpkOutMidQ"),                (long)100)/100.0;
+
+    wxGetApp().m_SpkOutEQEnable = (float)pConfig->Read(wxT("/Filter/SpkOutEQEnable"), f);
+
+    wxGetApp().m_callSign = pConfig->Read("/Data/CallSign", wxT(""));
+    wxGetApp().m_textEncoding = pConfig->Read("/Data/TextEncoding", 1);
+    wxGetApp().m_enable_checksum = pConfig->Read("/Data/EnableChecksumOnMsgRx", f);
+
+    wxGetApp().m_events = pConfig->Read("/Events/enable", f);
+    wxGetApp().m_events_spam_timer = (int)pConfig->Read(wxT("/Events/spam_timer"), 10);
+    wxGetApp().m_events_regexp_match = pConfig->Read("/Events/regexp_match", wxT("s=(.*)"));
+    wxGetApp().m_events_regexp_replace = pConfig->Read("/Events/regexp_replace", 
+                                                       wxT("curl http://qso.freedv.org/cgi-bin/onspot.cgi?s=\\1"));
+    // make sure regexp lists are terminated by a \n
+
+    if (wxGetApp().m_events_regexp_match.Last() != '\n') {
+        wxGetApp().m_events_regexp_match = wxGetApp().m_events_regexp_match+'\n';
+    }
+    if (wxGetApp().m_events_regexp_replace.Last() != '\n') {
+        wxGetApp().m_events_regexp_replace = wxGetApp().m_events_regexp_replace+'\n';
+    }
+
+    wxGetApp().m_udp_enable = (float)pConfig->Read(wxT("/UDP/enable"), f);
+    wxGetApp().m_udp_port = (int)pConfig->Read(wxT("/UDP/port"), 3000);
+
+    wxGetApp().m_FreeDV700txClip = (float)pConfig->Read(wxT("/FreeDV700/txClip"), t);
+    wxGetApp().m_FreeDV700Combine = 1;
+    wxGetApp().m_noise_snr = (float)pConfig->Read(wxT("/Noise/noise_snr"), 2);
+    wxGetApp().m_debug_console = (float)pConfig->Read(wxT("/Debug/console"), f);
+
+    wxGetApp().m_attn_carrier_en = 0;
+    wxGetApp().m_attn_carrier    = 0;
+
+    wxGetApp().m_tone = 0;
+    wxGetApp().m_tone_freq_hz = 1000;
+    wxGetApp().m_tone_amplitude = 500;
+
+    int mode  = pConfig->Read(wxT("/Audio/mode"), (long)0);
+    if (mode == 0)
+        m_rb1600->SetValue(1);
+    //if (mode == 2)
+    //    m_rb700b->SetValue(1);
+    if (mode == 3)
+        m_rb700c->SetValue(1);
+    if (mode == 4)
+        m_rb800xa->SetValue(1);
+        
+    pConfig->SetPath(wxT("/"));
+
+//    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    //m_togRxID->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnRxIDUI), NULL, this);
+    //m_togTxID->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnTxIDUI), NULL, this);
+    m_togBtnOnOff->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnOnOffUI), NULL, this);
+    m_togBtnSplit->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnSplitClickUI), NULL, this);
+    m_togBtnAnalog->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnAnalogClickUI), NULL, this);
+    //m_togBtnALC->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnALCClickUI), NULL, this);
+   // m_btnTogPTT->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnPTT_UI), NULL, this);
+
+    m_togBtnSplit->Disable();
+    //m_togRxID->Disable();
+    //m_togTxID->Disable();
+    m_togBtnAnalog->Disable();
+    m_btnTogPTT->Disable();
+    m_togBtnVoiceKeyer->Disable();
+    //m_togBtnALC->Disable();
+
+    // squelch settings
+    char sqsnr[15];
+    m_sliderSQ->SetValue((int)((g_SquelchLevel+5.0)*2.0));
+    sprintf(sqsnr, "%4.1f", g_SquelchLevel);
+    wxString sqsnr_string(sqsnr);
+    m_textSQ->SetLabel(sqsnr_string);
+    m_ckboxSQ->SetValue(g_SquelchActive);
+
+    // SNR settings
+
+    m_ckboxSNR->SetValue(wxGetApp().m_snrSlow);
+    setsnrBeta(wxGetApp().m_snrSlow);
+
+#ifdef _USE_TIMER
+    Bind(wxEVT_TIMER, &MainFrame::OnTimer, this);       // ID_MY_WINDOW);
+    m_plotTimer.SetOwner(this, ID_TIMER_WATERFALL);
+    //m_panelWaterfall->Refresh();
+#endif
+
+    m_RxRunning = false;
+
+#ifdef _USE_ONIDLE
+    Connect(wxEVT_IDLE, wxIdleEventHandler(MainFrame::OnIdle), NULL, this);
+#endif //_USE_ONIDLE
+
+    g_sfPlayFile = NULL;
+    g_playFileToMicIn = false;
+    g_loopPlayFileToMicIn = false;
+
+    g_sfRecFile = NULL;
+    g_recFileFromRadio = false;
+
+    g_sfPlayFileFromRadio = NULL;
+    g_playFileFromRadio = false;
+    g_loopPlayFileFromRadio = false;
+
+    // init click-tune states
+
+    g_RxFreqOffsetHz = 0.0;
+    g_RxFreqOffsetPhaseRect.real = cos(0.0);
+    g_RxFreqOffsetPhaseRect.imag = sin(0.0);
+    m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+    m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+
+    g_TxFreqOffsetHz = 0.0;
+    g_TxFreqOffsetPhaseRect.real = cos(0.0);
+    g_TxFreqOffsetPhaseRect.imag = sin(0.0);
+
+    g_tx = 0;
+    g_split = 0;
+
+    // data states
+    g_txDataInFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
+    g_rxDataOutFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
+
+    sox_biquad_start();
+
+    g_testFrames = 0;
+    g_test_frame_sync_state = 0;
+    g_resyncs = 0;
+    wxGetApp().m_testFrames = false;
+    g_tone_phase = 0.0;
+
+    g_modal = false;
+
+#ifdef __EXPERIMENTAL_UDP__
+    // Start UDP listener thread
+
+    m_UDPThread = NULL;
+    startUDPThread();
+#endif
+
+    optionsDlg = new OptionsDlg(NULL);
+    m_schedule_restore = false;
+
+    vk_state = VK_IDLE;
+
+    // Init optional Windows debug console so we can see all those printfs
+
+#ifdef __WXMSW__
+    if (wxGetApp().m_debug_console) {
+        // somewhere to send printfs while developing
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    }
+#endif
+
+    //ftest = fopen("ftest.raw", "wb");
+    //assert(ftest != NULL);
+}
+
+//-------------------------------------------------------------------------
+// ~MainFrame()
+//-------------------------------------------------------------------------
+MainFrame::~MainFrame()
+{
+    int x;
+    int y;
+    int w;
+    int h;
+
+    fprintf(stderr, "MainFrame::~MainFrame()\n");
+    //fclose(ftest);
+    #ifdef __WXMSW__
+    fclose(g_logfile);
+    #endif
+
+    if (optionsDlg != NULL) {
+        delete optionsDlg;
+        optionsDlg = NULL;
+    }
+
+#ifdef __EXPERIMENTAL_UDP__
+    stopUDPThread();
+#endif
+
+    if (wxGetApp().m_hamlib) delete wxGetApp().m_hamlib;
+    if (wxGetApp().m_serialport) delete wxGetApp().m_serialport;
+
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(pConfig)
+    {
+        if (!IsIconized()) {
+            GetClientSize(&w, &h);
+            GetPosition(&x, &y);
+            printf("x = %d y = %d w = %d h = %d\n", x,y,w,h);
+            pConfig->Write(wxT("/MainFrame/left"),               (long) x);
+            pConfig->Write(wxT("/MainFrame/top"),                (long) y);
+            pConfig->Write(wxT("/MainFrame/width"),              (long) w);
+            pConfig->Write(wxT("/MainFrame/height"),             (long) h);
+        }
+        pConfig->Write(wxT("/MainFrame/show_wf"),           wxGetApp().m_show_wf);
+        pConfig->Write(wxT("/MainFrame/show_spect"),        wxGetApp().m_show_spect);
+        pConfig->Write(wxT("/MainFrame/show_scatter"),      wxGetApp().m_show_scatter);
+        pConfig->Write(wxT("/MainFrame/show_timing"),       wxGetApp().m_show_timing);
+        pConfig->Write(wxT("/MainFrame/show_freq"),         wxGetApp().m_show_freq);
+        pConfig->Write(wxT("/MainFrame/show_speech_in"),    wxGetApp().m_show_speech_in);
+        pConfig->Write(wxT("/MainFrame/show_speech_out"),   wxGetApp().m_show_speech_out);
+        pConfig->Write(wxT("/MainFrame/show_demod_in"),     wxGetApp().m_show_demod_in);
+        pConfig->Write(wxT("/MainFrame/show_test_frame_errors"), wxGetApp().m_show_test_frame_errors);
+        pConfig->Write(wxT("/MainFrame/show_test_frame_errors_hist"), wxGetApp().m_show_test_frame_errors_hist);
+
+        pConfig->Write(wxT("/MainFrame/rxNbookCtrl"), wxGetApp().m_rxNbookCtrl);
+
+        pConfig->Write(wxT("/Audio/SquelchActive"),         g_SquelchActive);
+        pConfig->Write(wxT("/Audio/SquelchLevel"),          (int)(g_SquelchLevel*2.0));
+
+        pConfig->Write(wxT("/Audio/framesPerBuffer"),       wxGetApp().m_framesPerBuffer);
+
+        pConfig->Write(wxT("/Audio/soundCard1InDeviceNum"),   g_soundCard1InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1OutDeviceNum"),  g_soundCard1OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1SampleRate"),    g_soundCard1SampleRate );
+
+        pConfig->Write(wxT("/Audio/soundCard2InDeviceNum"),   g_soundCard2InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2OutDeviceNum"),  g_soundCard2OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2SampleRate"),    g_soundCard2SampleRate );
+
+        pConfig->Write(wxT("/VoiceKeyer/WaveFilePath"), wxGetApp().m_txtVoiceKeyerWaveFilePath);
+        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
+        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
+        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
+
+        pConfig->Write(wxT("/Rig/HalfDuplex"),              wxGetApp().m_boolHalfDuplex);
+        pConfig->Write(wxT("/Rig/leftChannelVoxTone"),      wxGetApp().m_leftChannelVoxTone);
+        pConfig->Write("/Hamlib/UseForPTT", wxGetApp().m_boolHamlibUseForPTT);
+        pConfig->Write("/Hamlib/RigName", wxGetApp().m_intHamlibRig);
+        pConfig->Write("/Hamlib/SerialPort", wxGetApp().m_strHamlibSerialPort);
+        pConfig->Write("/Hamlib/SerialRate", wxGetApp().m_intHamlibSerialRate);
+
+
+        pConfig->Write(wxT("/File/playFileToMicInPath"),    wxGetApp().m_playFileToMicInPath);
+        pConfig->Write(wxT("/File/recFileFromRadioPath"),   wxGetApp().m_recFileFromRadioPath);
+        pConfig->Write(wxT("/File/recFileFromRadioSecs"),   wxGetApp().m_recFileFromRadioSecs);
+        pConfig->Write(wxT("/File/playFileFromRadioPath"),  wxGetApp().m_playFileFromRadioPath);
+
+        pConfig->Write(wxT("/Audio/snrSlow"), wxGetApp().m_snrSlow);
+
+        pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
+        pConfig->Write(wxT("/Data/TextEncoding"), wxGetApp().m_textEncoding);
+        pConfig->Write(wxT("/Data/EnableChecksumOnMsgRx"), wxGetApp().m_enable_checksum);
+        pConfig->Write(wxT("/Events/enable"), wxGetApp().m_events);
+        pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+        pConfig->Write(wxT("/Events/regexp_match"), wxGetApp().m_events_regexp_match);
+        pConfig->Write(wxT("/Events/regexp_replace"), wxGetApp().m_events_regexp_replace);
+        pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
+        pConfig->Write(wxT("/UDP/port"),  wxGetApp().m_udp_port);
+
+        pConfig->Write(wxT("/Filter/MicInEQEnable"), wxGetApp().m_MicInEQEnable);
+        pConfig->Write(wxT("/Filter/SpkOutEQEnable"), wxGetApp().m_SpkOutEQEnable);
+
+        pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
+        pConfig->Write(wxT("/Noise/noise_snr"), wxGetApp().m_noise_snr);
+
+        pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+
+        int mode;
+        if (m_rb1600->GetValue())
+            mode = 0;
+        //if (m_rb700b->GetValue())
+        //    mode = 2;
+        if (m_rb700c->GetValue())
+            mode = 3;
+        if (m_rb800xa->GetValue())
+            mode = 4;
+       pConfig->Write(wxT("/Audio/mode"), mode);
+    }
+
+    //m_togRxID->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnRxIDUI), NULL, this);
+    //m_togTxID->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnTxIDUI), NULL, this);
+    m_togBtnOnOff->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnOnOffUI), NULL, this);
+    m_togBtnSplit->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnSplitClickUI), NULL, this);
+    m_togBtnAnalog->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnAnalogClickUI), NULL, this);
+    //m_togBtnALC->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnALCClickUI), NULL, this);
+    //m_btnTogPTT->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnPTT_UI), NULL, this);
+
+    sox_biquad_finish();
+
+    if (m_RxRunning)
+    {
+        stopRxStream();
+    }
+    if (g_sfPlayFile != NULL)
+    {
+        sf_close(g_sfPlayFile);
+        g_sfPlayFile = NULL;
+    }
+    if (g_sfRecFile != NULL)
+    {
+        sf_close(g_sfRecFile);
+        g_sfRecFile = NULL;
+    }
+#ifdef _USE_TIMER
+    if(m_plotTimer.IsRunning())
+    {
+        m_plotTimer.Stop();
+        Unbind(wxEVT_TIMER, &MainFrame::OnTimer, this);
+    }
+#endif //_USE_TIMER
+
+#ifdef _USE_ONIDLE
+    Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainFrame::OnIdle), NULL, this);
+#endif // _USE_ONIDLE
+
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+
+#ifdef _USE_ONIDLE
+void MainFrame::OnIdle(wxIdleEvent &evt) {
+}
+#endif
+
+
+#ifdef _USE_TIMER
+//----------------------------------------------------------------
+// OnTimer()
+//
+// when the timer fires every DT seconds we update the GUI displays.
+// the tabs only the plot that is visible actually gets updated, this
+// keeps CPU load reasonable
+//----------------------------------------------------------------
+void MainFrame::OnTimer(wxTimerEvent &evt)
+{
+
+    int r,c;
+
+    if (m_panelWaterfall->checkDT()) {
+        m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+        m_panelWaterfall->m_newdata = true;
+        m_panelWaterfall->Refresh();
+    }
+
+    m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+    m_panelSpectrum->m_newdata = true;
+    m_panelSpectrum->Refresh();
+
+    /* update scatter/eye plot ------------------------------------------------------------*/
+
+    if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_800XA) {
+        /* FSK Mode - eye diagram ---------------------------------------------------------*/
+        
+        /* add samples row by row */
+
+        int i;
+       for (i=0; i<g_stats.neyetr; i++) {
+            m_panelScatter->add_new_samples_eye(&g_stats.rx_eye[i][0], g_stats.neyesamp);
+        }
+    }
+    else {
+        /* PSK Modes - scatter plot -------------------------------------------------------*/
+        for (r=0; r<g_stats.nr; r++) {
+        
+            if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600) {
+                m_panelScatter->add_new_samples_scatter(&g_stats.rx_symbols[r][0]);
+            }
+        
+            if (/*(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) ||*/(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
+            
+                if (wxGetApp().m_FreeDV700Combine) {
+                    m_panelScatter->setNc(g_Nc/2); /* m_FreeDV700Combine may have changed at run time */
+
+                    /* 
+                       FreeDV 700 uses diversity, so optionaly combine
+                       symbols for scatter plot, as combined symbols are
+                       used for demodulation.  Note we need to use a copy
+                       of the symbols, as we are not sure when the stats
+                       will be updated.
+                    */
+
+                    COMP rx_symbols_copy[g_Nc/2];
+
+                    for(c=0; c<g_Nc/2; c++)
+                        rx_symbols_copy[c] = fcmult(0.5, cadd(g_stats.rx_symbols[r][c], g_stats.rx_symbols[r][c+g_Nc/2]));
+                    m_panelScatter->add_new_samples_scatter(rx_symbols_copy);
+                }
+                else {
+                    m_panelScatter->setNc(g_Nc); /* m_FreeDV700Combine may have changed at run time */
+                    /*
+                      Sometimes useful to plot carriers separately, e.g. to determine if tx carrier power is constant
+                      across carriers.
+                    */
+                    m_panelScatter->add_new_samples_scatter(&g_stats.rx_symbols[r][0]);
+                }
+            }
+       
+        }
+    }
+
+    m_panelScatter->Refresh();
+
+    // Oscilliscope type speech plots -------------------------------------------------------
+
+    short speechInPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotSpeechInFifo, speechInPlotSamples, WAVEFORM_PLOT_BUF)) {
+        memset(speechInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+        //fprintf(stderr, "empty!\n");
+    }
+    m_panelSpeechIn->add_new_short_samples(0, speechInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelSpeechIn->Refresh();
+
+    short speechOutPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotSpeechOutFifo, speechOutPlotSamples, WAVEFORM_PLOT_BUF))
+        memset(speechOutPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+    m_panelSpeechOut->add_new_short_samples(0, speechOutPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelSpeechOut->Refresh();
+
+    short demodInPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotDemodInFifo, demodInPlotSamples, WAVEFORM_PLOT_BUF)) {
+        memset(demodInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+    }
+    m_panelDemodIn->add_new_short_samples(0,demodInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelDemodIn->Refresh();
+
+    // Demod states -----------------------------------------------------------------------
+
+    m_panelTimeOffset->add_new_sample(0, (float)g_stats.rx_timing/FDMDV_NOM_SAMPLES_PER_FRAME);
+    m_panelTimeOffset->Refresh();
+
+    m_panelFreqOffset->add_new_sample(0, g_stats.foff);
+    m_panelFreqOffset->Refresh();
+
+    // SNR text box and gauge ------------------------------------------------------------
+
+    // LP filter g_stats.snr_est some more to stabilise the
+    // display. g_stats.snr_est already has some low pass filtering
+    // but we need it fairly fast to activate squelch.  So we
+    // optionally perform some further filtering for the display
+    // version of SNR.  The "Slow" checkbox controls the amount of
+    // filtering.  The filtered snr also controls the squelch
+
+    g_snr = m_snrBeta*g_snr + (1.0 - m_snrBeta)*g_stats.snr_est;
+    float snr_limited = g_snr;
+    if (snr_limited < -5.0) snr_limited = -5.0;
+    if (snr_limited > 20.0) snr_limited = 20.0;
+
+    char snr[15];
+    sprintf(snr, "%d", (int)(g_snr+0.5)); // round to nearest dB
+
+    //printf("snr_est: %f m_snrBeta: %f g_snr: %f snr_limited: %f\n", g_stats.snr_est,  m_snrBeta, g_snr, snr_limited);
+
+    wxString snr_string(snr);
+    m_textSNR->SetLabel(snr_string);
+    m_gaugeSNR->SetValue((int)(snr_limited+5));
+
+    // Level Gauge -----------------------------------------------------------------------
+
+    float tooHighThresh;
+    if (!g_tx && m_RxRunning)
+    {
+        // receive mode - display From Radio peaks
+        // peak from this DT sampling period
+        int maxDemodIn = 0;
+        for(int i=0; i<WAVEFORM_PLOT_BUF; i++)
+            if (maxDemodIn < abs(demodInPlotSamples[i]))
+                maxDemodIn = abs(demodInPlotSamples[i]);
+
+        // peak from last second
+        if (maxDemodIn > m_maxLevel)
+            m_maxLevel = maxDemodIn;
+
+        tooHighThresh = FROM_RADIO_MAX;
+    }
+    else
+    {
+        // transmit mode - display From Mic peaks
+
+        // peak from this DT sampling period
+        int maxSpeechIn = 0;
+        for(int i=0; i<WAVEFORM_PLOT_BUF; i++)
+            if (maxSpeechIn < abs(speechInPlotSamples[i]))
+                maxSpeechIn = abs(speechInPlotSamples[i]);
+
+        // peak from last second
+        if (maxSpeechIn > m_maxLevel)
+            m_maxLevel = maxSpeechIn;
+
+       tooHighThresh = FROM_MIC_MAX;
+    }
+
+    // Peak Reading meter: updates peaks immediately, then slowly decays
+    int maxScaled = (int)(100.0 * ((float)m_maxLevel/32767.0));
+    m_gaugeLevel->SetValue(maxScaled);
+    //printf("maxScaled: %d\n", maxScaled);
+    if (((float)maxScaled/100) > tooHighThresh)
+        m_textLevel->SetLabel("Too High");
+    else
+        m_textLevel->SetLabel("");
+
+    m_maxLevel *= LEVEL_BETA;
+
+    // sync LED (Colours don't work on Windows) ------------------------
+
+    //fprintf(stderr, "g_State: %d  m_rbSync->GetValue(): %d\n", g_State, m_rbSync->GetValue());
+    if (g_State) {
+        if (g_prev_State == 0) {
+            g_resyncs++;
+        }
+        m_rbSync->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
+        m_rbSync->SetValue(true);        
+    }
+    else {
+        m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) ); // red
+        m_rbSync->SetValue(false);
+    }
+    g_prev_State = g_State;
+
+    // send Callsign ----------------------------------------------------
+
+    char callsign[MAX_CALLSIGN];
+    strncpy(callsign, (const char*) wxGetApp().m_callSign.mb_str(wxConvUTF8), MAX_CALLSIGN-1);
+
+    // buffer 1 txt message to ensure tx data fifo doesn't "run dry"
+
+    if ((unsigned)fifo_used(g_txDataInFifo) < strlen(callsign)) {
+        unsigned int  i;
+
+        //fprintf(g_logfile, "tx callsign: %s.\n", callsign);
+
+        /* optionally append checksum */
+
+        if (wxGetApp().m_enable_checksum) {
+
+            unsigned char checksum = 0;
+            char callsign_checksum_cr[MAX_CALLSIGN+1];
+
+            for(i=0; i<strlen(callsign); i++)
+                checksum += callsign[i];
+            sprintf(callsign_checksum_cr, "%s%2x", callsign, checksum);
+            callsign_checksum_cr[strlen(callsign)+2] = 13;
+            callsign_checksum_cr[strlen(callsign)+3] = 0;
+            strcpy(callsign, callsign_checksum_cr);
+        }
+        else {
+            callsign[strlen(callsign)] = 13;
+            callsign[strlen(callsign)+1] = 0;
+        }
+
+        //fprintf(g_logfile, "tx callsign: %s.\n", callsign);
+
+        // write chars to tx data fifo
+
+        for(i=0; i<strlen(callsign); i++) {
+            short ashort = (short)callsign[i];
+            fifo_write(g_txDataInFifo, &ashort, 1);
+        }
+    }
+
+    // See if any Callsign info received --------------------------------
+
+    short ashort;
+    while (fifo_read(g_rxDataOutFifo, &ashort, 1) == 0) {
+
+        if ((ashort == 13) || ((m_pcallsign - m_callsign) > MAX_CALLSIGN-1)) {
+            // CR completes line
+            *m_pcallsign = 0;
+            
+            /* Checksums can be disabled, e.g. for compatability with
+               older vesions.  In that case we print msg but don't do
+               any event processing.  If checksums enabled, only print
+               out when checksum is good. */
+
+            if (wxGetApp().m_enable_checksum) {
+                // lets see if checksum is OK
+            
+                unsigned char checksum_rx = 0;
+                if (strlen(m_callsign) > 2) {
+                    for(unsigned int i=0; i<strlen(m_callsign)-2; i++)
+                        checksum_rx += m_callsign[i];
+                }
+                unsigned int checksum_tx;
+                int ret = sscanf(&m_callsign[strlen(m_callsign)-2], "%2x", &checksum_tx);
+                //fprintf(g_logfile, "rx callsign: %s.\n  checksum tx: %02x checksum rx: %02x\n", m_callsign, checksum_tx, checksum_rx);
+
+                wxString s;
+                if (ret && (checksum_tx == checksum_rx)) {
+                    m_callsign[strlen(m_callsign)-2] = 0;
+                    s.Printf("%s", m_callsign);
+                    m_txtCtrlCallSign->SetValue(s);
+
+#ifdef __UDP_EXPERIMENTAL__
+                    char s1[MAX_CALLSIGN];
+                    sprintf(s1,"rx_txtmsg %s", m_callsign);
+                    processTxtEvent(s1);
+
+                    m_checksumGood++;
+                    s.Printf("%d", m_checksumGood);
+                    m_txtChecksumGood->SetLabel(s);              
+#endif
+                }
+                else {
+#ifdef __UDP_EXPERIMENTAL__
+                    m_checksumBad++;
+                    s.Printf("%d", m_checksumBad);
+                    m_txtChecksumBad->SetLabel(s);        
+#endif
+                }
+            }
+
+            //fprintf(g_logfile,"resetting callsign %s %ld\n", m_callsign, m_pcallsign-m_callsign);
+            // reset ptr to start of string
+            m_pcallsign = m_callsign;
+        }
+        else {
+            //fprintf(g_logfile, "new char %d %c\n", ashort, (char)ashort);
+            *m_pcallsign++ = (char)ashort;
+        }
+
+        /* If checksums disabled, display txt chars as they arrive */
+
+        if (!wxGetApp().m_enable_checksum) {
+            m_txtCtrlCallSign->SetValue(m_callsign);
+        }
+    }
+
+
+    // Run time update of EQ filters -----------------------------------
+
+    if (m_newMicInFilter || m_newSpkOutFilter) {
+        g_mutexProtectingCallbackData.Lock();
+        deleteEQFilters(g_rxUserdata);
+        designEQFilters(g_rxUserdata);
+        g_mutexProtectingCallbackData.Unlock();
+        m_newMicInFilter = m_newSpkOutFilter = false;
+    }
+    g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+    g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+
+
+    if (g_mode != -1)  {
+
+        // Run time update of FreeDV 700 tx clipper
+
+        freedv_set_clip(g_pfreedv, (int)wxGetApp().m_FreeDV700txClip);
+        
+        // Test Frame Bit Error Updates ------------------------------------
+
+        // Toggle test frame mode at run time
+
+        if (!freedv_get_test_frames(g_pfreedv) && wxGetApp().m_testFrames) {
+
+            // reset stats on check box off to on transition
+
+            freedv_set_test_frames(g_pfreedv, 1);
+            freedv_set_total_bits(g_pfreedv, 0);
+            freedv_set_total_bit_errors(g_pfreedv, 0);
+        }
+        freedv_set_test_frames(g_pfreedv, wxGetApp().m_testFrames);
+        freedv_set_test_frames_diversity(g_pfreedv, wxGetApp().m_FreeDV700Combine);
+        g_channel_noise =  wxGetApp().m_channel_noise;
+
+        if (g_State) {
+            char bits[80], errors[80], ber[80], resyncs[80];
+
+            // update stats on main page
+
+            sprintf(bits, "Bits: %d", freedv_get_total_bits(g_pfreedv)); wxString bits_string(bits); m_textBits->SetLabel(bits_string);
+            sprintf(errors, "Errs: %d", freedv_get_total_bit_errors(g_pfreedv)); wxString errors_string(errors); m_textErrors->SetLabel(errors_string);
+            float b = (float)freedv_get_total_bit_errors(g_pfreedv)/(1E-6+freedv_get_total_bits(g_pfreedv));
+            sprintf(ber, "BER: %4.3f", b); wxString ber_string(ber); m_textBER->SetLabel(ber_string);
+            sprintf(resyncs, "Resyncs: %d", g_resyncs); wxString resyncs_string(resyncs); m_textResyncs->SetLabel(resyncs_string);
+
+            // update error pattern plots if supported
+
+            int sz_error_pattern = freedv_get_sz_error_pattern(g_pfreedv);
+            //fprintf(stderr, "sz_error_pattern: %d\n", sz_error_pattern);
+            if (sz_error_pattern) {
+                short error_pattern[sz_error_pattern];
+
+                if (fifo_read(g_error_pattern_fifo, error_pattern, sz_error_pattern) == 0) {
+                    int i,b;
+
+                    /* both modes map IQ to alternate bits, but on same carrier */
+
+                    if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600) {
+                        /* FreeDV 1600 mapping from error pattern to two bits on each carrier */
+
+                        for(b=0; b<g_Nc*2; b++) {
+                            for(i=b; i<sz_error_pattern; i+= 2*g_Nc) {
+                                m_panelTestFrameErrors->add_new_sample(b, b + 0.8*error_pattern[i]);
+                                g_error_hist[b] += error_pattern[i];
+                                g_error_histn[b]++;
+                            }
+                            //if (b%2)
+                            //    printf("g_error_hist[%d]: %d\n", b/2, g_error_hist[b/2]);
+                        }
+
+                         /* calculate BERs and send to plot */
+
+                        float ber[2*FDMDV_NC_MAX];
+                        for(b=0; b<2*FDMDV_NC_MAX; b++) {
+                            ber[b] = 0.0;
+                        }
+                        for(b=0; b<g_Nc*2; b++) {
+                            ber[b+1] = (float)g_error_hist[b]/g_error_histn[b];
+                        }
+                        assert(g_Nc*2 <= 2*FDMDV_NC_MAX);
+                        m_panelTestFrameErrorsHist->add_new_samples(0, ber, 2*FDMDV_NC_MAX);
+                    }
+       
+                    if (/*(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) || */(freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
+                        int c;
+                        //fprintf(stderr, "after g_error_pattern_fifo read 2\n");
+                        
+                        /* 
+                           FreeDV 700 mapping from error pattern to bit on each carrier, see 
+                           data bit to carrier mapping in:
+
+                              codec2-dev/octave/cohpsk_frame_design.ods
+                           We can plot a histogram of the errors/carrier before or after diversity
+                           recombination.  Actually one bar for each IQ bit in carrier order.
+                        */
+
+                        int hist_Nc = sz_error_pattern/4;
+                        //fprintf(stderr, "hist_Nc: %d\n", hist_Nc);
+
+                        for(i=0; i<sz_error_pattern; i++) {
+                            /* maps to IQ bits from each symbol to a "carrier" (actually one line for each IQ bit in carrier order) */
+                            c = floor(i/4);
+                            /* this will clock in 4 bits/carrier to plot */
+                            m_panelTestFrameErrors->add_new_sample(c, c + 0.8*error_pattern[i]);
+                            g_error_hist[c] += error_pattern[i];
+                            g_error_histn[c]++;
+                            //printf("i: %d c: %d\n", i, c);
+                        }
+                        for(; i<2*MODEM_STATS_NC_MAX*4; i++) {
+                            c = floor(i/4);
+                            m_panelTestFrameErrors->add_new_sample(c, c);
+                            //printf("i: %d c: %d\n", i, c);
+                        }
+
+                        /* calculate BERs and send to plot */
+
+                        float ber[2*FDMDV_NC_MAX];
+                        for(b=0; b<2*FDMDV_NC_MAX; b++) {
+                            ber[b] = 0.0;
+                        }
+                        for(b=0; b<hist_Nc; b++) {
+                            ber[b+1] = (float)g_error_hist[b]/g_error_histn[b];
+                        }
+                        assert(hist_Nc <= 2*FDMDV_NC_MAX);
+                        m_panelTestFrameErrorsHist->add_new_samples(0, ber, 2*FDMDV_NC_MAX);
+                    }
+                    m_panelTestFrameErrors->Refresh();       
+                    m_panelTestFrameErrorsHist->Refresh();
+                }
+            }
+        }
+    }
+
+    // command from UDP thread that is best processed in main thread to avoid seg faults
+
+    if (m_schedule_restore) {
+        if (IsIconized())
+            Restore();
+        m_schedule_restore = false;
+    }
+
+#ifdef __UDP_EXPERIMENTAL__
+    // Light Spam Timer LED if at least one timer is running
+
+    int i;
+    optionsDlg->SetSpamTimerLight(false);
+    for(i=0; i<MAX_EVENT_RULES; i++)
+        if (spamTimer[i].IsRunning())
+            optionsDlg->SetSpamTimerLight(true);        
+#endif
+
+    // Blink file playback status line
+
+    if (g_playFileFromRadio) {
+        g_blink += DT;
+        //fprintf(g_logfile, "g_blink: %f\n", g_blink);
+        if ((g_blink >= 1.0) && (g_blink < 2.0))
+            SetStatusText(wxT("Playing into from radio"), 0);
+        if (g_blink >= 2.0) {
+            SetStatusText(wxT(""), 0);
+            g_blink = 0.0;
+        }
+    }
+
+    // Voice Keyer state machine
+
+    VoiceKeyerProcessEvent(VK_DT);
+}
+#endif
+
+
+//-------------------------------------------------------------------------
+// OnCloseFrame()
+//-------------------------------------------------------------------------
+void MainFrame::OnCloseFrame(wxCloseEvent& event)
+{
+    fprintf(stderr, "MainFrame::OnCloseFrame()\n");
+    Pa_Terminate();
+    Destroy();
+}
+
+//-------------------------------------------------------------------------
+// OnTop()
+//-------------------------------------------------------------------------
+void MainFrame::OnTop(wxCommandEvent& event)
+{
+    int style = GetWindowStyle();
+
+    if (style & wxSTAY_ON_TOP)
+    {
+        style &= ~wxSTAY_ON_TOP;
+    }
+    else
+    {
+        style |= wxSTAY_ON_TOP;
+    }
+    SetWindowStyle(style);
+}
+
+//-------------------------------------------------------------------------
+// OnDeleteConfig()
+//-------------------------------------------------------------------------
+void MainFrame::OnDeleteConfig(wxCommandEvent&)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(pConfig->DeleteAll())
+    {
+        wxLogMessage(wxT("Config file/registry key successfully deleted."));
+
+        delete wxConfigBase::Set(NULL);
+        wxConfigBase::DontCreateOnDemand();
+    }
+    else
+    {
+        wxLogError(wxT("Deleting config file/registry key failed."));
+    }
+}
+
+//-------------------------------------------------------------------------
+// Paint()
+//-------------------------------------------------------------------------
+void MainFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+    wxPaintDC dc(this);
+
+    if(GetMenuBar()->IsChecked(ID_PAINT_BG))
+    {
+        dc.Clear();
+    }
+    dc.SetUserScale(m_zoom, m_zoom);
+}
+
+//-------------------------------------------------------------------------
+// OnCmdSliderScroll()
+//-------------------------------------------------------------------------
+void MainFrame::OnCmdSliderScroll(wxScrollEvent& event)
+{
+    char sqsnr[15];
+    g_SquelchLevel = (float)m_sliderSQ->GetValue()/2.0 - 5.0;   
+    sprintf(sqsnr, "%4.1f", g_SquelchLevel); // 0.5 dB steps
+    wxString sqsnr_string(sqsnr);
+    m_textSQ->SetLabel(sqsnr_string);
+
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnCheckSQClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnCheckSQClick(wxCommandEvent& event)
+{
+    if(!g_SquelchActive)
+    {
+        g_SquelchActive = true;
+    }
+    else
+    {
+        g_SquelchActive = false;
+    }
+}
+
+void MainFrame::setsnrBeta(bool snrSlow)
+{
+    if(snrSlow)
+    {
+        m_snrBeta = 0.95; // make this closer to 1.0 to smooth SNR est further
+    }
+    else
+    {
+        m_snrBeta = 0.0; // no smoothing of SNR estimate from demodulator
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnCheckSQClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnCheckSNRClick(wxCommandEvent& event)
+{
+    wxGetApp().m_snrSlow = m_ckboxSNR->GetValue();
+    setsnrBeta(wxGetApp().m_snrSlow);
+    //printf("m_snrSlow: %d\n", (int)wxGetApp().m_snrSlow);
+}
+
+// check for space bar press (only when running)
+
+int MainApp::FilterEvent(wxEvent& event)
+{
+    if ((event.GetEventType() == wxEVT_KEY_DOWN) && 
+        (((wxKeyEvent&)event).GetKeyCode() == WXK_SPACE))
+        {
+            // only use space to toggle PTT if we are running and no modal dialogs (like options) up
+            //fprintf(stderr,"frame->m_RxRunning: %d g_modal: %d\n",
+            //        frame->m_RxRunning, g_modal);
+            if (frame->m_RxRunning && !g_modal) {
+
+                // space bar controls rx/rx if keyer not running
+                if (frame->vk_state == VK_IDLE) {
+                    if (frame->m_btnTogPTT->GetValue())
+                        frame->m_btnTogPTT->SetValue(false);
+                    else
+                        frame->m_btnTogPTT->SetValue(true);
+
+                    frame->togglePTT();
+                }
+                else // spavce bar stops keyer
+                    frame->VoiceKeyerProcessEvent(VK_SPACE_BAR);
+                    
+                return true; // absorb space so we don't toggle control with focus (e.g. Start)
+
+            }
+        }
+
+    return -1;
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnPTT ()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnPTT (wxCommandEvent& event)
+{
+    togglePTT();
+    event.Skip();
+}
+
+void MainFrame::togglePTT(void) {
+
+    // Change tabbed page in centre panel depending on PTT state
+
+    if (g_tx)
+    {
+        // tx-> rx transition, swap to the page we were on for last rx
+        m_auiNbookCtrl->ChangeSelection(wxGetApp().m_rxNbookCtrl);
+    }
+    else
+    {
+        // rx-> tx transition, swap to Mic In page to monitor speech
+        wxGetApp().m_rxNbookCtrl = m_auiNbookCtrl->GetSelection();
+        m_auiNbookCtrl->ChangeSelection(m_auiNbookCtrl->GetPageIndex((wxWindow *)m_panelSpeechIn));
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"ptt"); processTxtEvent(e);
+#endif
+    }
+
+    g_tx = m_btnTogPTT->GetValue();
+
+    // Hamlib PTT
+
+    if (wxGetApp().m_boolHamlibUseForPTT) {        
+        Hamlib *hamlib = wxGetApp().m_hamlib; 
+        wxString hamlibError;
+        if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
+            if (hamlib->ptt(g_tx, hamlibError) == false) {
+                wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            }
+        }
+    }
+
+    // Serial PTT
+
+    if (wxGetApp().m_boolUseSerialPTT && (wxGetApp().m_serialport->isopen())) {
+        wxGetApp().m_serialport->ptt(g_tx);
+    }
+
+    // reset level gauge
+
+    m_maxLevel = 0;
+    m_textLevel->SetLabel(wxT(""));
+    m_gaugeLevel->SetValue(0);
+}
+
+/*
+   Voice Keyer:
+
+   + space bar turns keyer off
+   + 5 secs of valid sync turns it off
+
+   [X] complete state machine and builds OK
+   [ ] file select dialog
+   [ ] test all states
+   [ ] restore size
+*/
+
+void MainFrame::OnTogBtnVoiceKeyerClick (wxCommandEvent& event)
+{
+    if (vk_state == VK_IDLE)
+        VoiceKeyerProcessEvent(VK_START);
+    else
+        VoiceKeyerProcessEvent(VK_SPACE_BAR);
+        
+    event.Skip();
+}
+
+
+int MainFrame::VoiceKeyerStartTx(void)
+{
+    int next_state;
+
+    // start playing wave file or die trying
+
+    SF_INFO sfInfo;
+    sfInfo.format = 0;
+
+    g_sfPlayFile = sf_open(wxGetApp().m_txtVoiceKeyerWaveFile, SFM_READ, &sfInfo);
+    if(g_sfPlayFile == NULL) {
+        wxString strErr = sf_strerror(NULL);
+        wxMessageBox(strErr, wxT("Couldn't open:") + wxGetApp().m_txtVoiceKeyerWaveFile, wxOK);
+        m_togBtnVoiceKeyer->SetValue(false);
+        next_state = VK_IDLE;
+    }
+    else {
+        SetStatusText(wxT("Voice Keyer: Playing File") + wxGetApp().m_txtVoiceKeyerWaveFile + wxT(" to Mic Input") , 0);
+        g_loopPlayFileToMicIn = false;
+        g_playFileToMicIn = true;
+
+        m_btnTogPTT->SetValue(true); togglePTT();
+        next_state = VK_TX;
+    }
+
+    return next_state;
+}
+
+
+void MainFrame::VoiceKeyerProcessEvent(int vk_event) {
+    int next_state = vk_state;
+
+    switch(vk_state) {
+
+    case VK_IDLE:
+        if (vk_event == VK_START) {
+            // sample these puppies at start just in case they are changed while VK running
+            vk_rx_pause = wxGetApp().m_intVoiceKeyerRxPause;
+            vk_repeats = wxGetApp().m_intVoiceKeyerRepeats;
+            fprintf(stderr, "vk_rx_pause: %d vk_repeats: %d\n", vk_rx_pause, vk_repeats);
+
+            vk_repeat_counter = 0;
+            next_state = VoiceKeyerStartTx();
+        }
+        break;
+        
+     case VK_TX:
+
+        // In this state we are transmitting and playing a wave file
+        // to Mic In
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_btnTogPTT->SetValue(false); togglePTT();
+            StopPlayFileToMicIn();
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        if (vk_event == VK_PLAY_FINISHED) {
+            m_btnTogPTT->SetValue(false); togglePTT();
+            vk_repeat_counter++;
+            if (vk_repeat_counter > vk_repeats) {
+                m_togBtnVoiceKeyer->SetValue(false);
+                next_state = VK_IDLE;
+            }
+            else {
+                vk_rx_time = 0.0;
+                next_state = VK_RX;
+            }
+        }
+
+        break;
+
+     case VK_RX:
+
+        // in this state we are receiving and waiting for
+        // delay timer or valid sync
+
+        if (vk_event == VK_DT) {
+            if (freedv_get_sync(g_pfreedv) == 1) {
+                // if we detect sync simulate a smooth transition to SYNC_WAIT State - TODO: review
+                if (vk_rx_time >= DT) {
+                    vk_rx_time -= DT;
+                } else {
+                    next_state = VK_SYNC_WAIT;
+                }
+            } else {
+                vk_rx_time += DT;
+                if (vk_rx_time >= vk_rx_pause) {
+                    next_state = VoiceKeyerStartTx();
+                }
+            }
+        }
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        break;
+
+     case VK_SYNC_WAIT:
+
+        // In this state we wait for valid sync to last
+        // VK_SYNC_WAIT_TIME seconds
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        if (vk_event == VK_DT) {
+            if (freedv_get_sync(g_pfreedv) == 0) {
+                // if we lose sync simulate a smooth transition to return in RX State - TODO: review
+                if (vk_rx_time >= DT) {
+                    vk_rx_time -= DT;
+                } else {
+                    next_state = VK_RX;
+                }
+            } else {
+                vk_rx_time += DT;
+            }
+
+            // drop out of voice keyer if we get a few seconds of valid sync
+
+            if (vk_rx_time >= VK_SYNC_WAIT_TIME) {
+                m_togBtnVoiceKeyer->SetValue(false);
+                next_state = VK_IDLE;
+            }
+        }
+        break;
+
+    default:
+        // catch anything we missed
+
+        m_btnTogPTT->SetValue(false); togglePTT();
+        m_togBtnVoiceKeyer->SetValue(false);
+        next_state = VK_IDLE;
+    }
+
+    //if ((vk_event != VK_DT) || (vk_state != next_state))
+    //    fprintf(stderr, "VoiceKeyerProcessEvent: vk_state: %d vk_event: %d next_state: %d  vk_repeat_counter: %d\n", vk_state, vk_event, next_state, vk_repeat_counter);
+    vk_state = next_state;
+}
+
+
+//-------------------------------------------------------------------------
+// OnTogBtnRxID()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnRxID(wxCommandEvent& event)
+{
+    // empty any junk in rx data FIFO
+    short junk;
+    while(fifo_read(g_rxDataOutFifo,&junk,1) == 0);
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnTxID()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnTxID(wxCommandEvent& event)
+{
+    event.Skip();
+}
+
+void MainFrame::OnTogBtnSplitClick(wxCommandEvent& event) {
+    if (g_split)
+        g_split = 0;
+    else
+        g_split = 1;
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnAnalogClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnAnalogClick (wxCommandEvent& event)
+{
+    if (g_analog == 0) {
+        g_analog = 1;
+        m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(FS/2)));
+        m_panelWaterfall->setFs(FS);
+    }
+    else {
+        g_analog = 0;
+        m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(freedv_get_modem_sample_rate(g_pfreedv)/2)));
+        m_panelWaterfall->setFs(freedv_get_modem_sample_rate(g_pfreedv));
+    }
+
+    g_State = g_prev_State = 0;
+    g_stats.snr_est = 0;
+
+    event.Skip();
+}
+
+void MainFrame::OnCallSignReset(wxCommandEvent& event)
+{
+    m_pcallsign = m_callsign;
+    memset(m_callsign, 0, MAX_CALLSIGN);
+    wxString s;
+    s.Printf("%s", m_callsign);
+    m_txtCtrlCallSign->SetValue(s);
+#ifdef __UDP__EXPERIMENTAL__
+    m_checksumGood = m_checksumBad = 0;
+    m_txtChecksumGood->SetLabel(_("0"));
+    m_txtChecksumBad->SetLabel(_("0"));
+#endif
+}
+
+void MainFrame::OnBerReset(wxCommandEvent& event)
+{
+    freedv_set_total_bits(g_pfreedv, 0);
+    freedv_set_total_bit_errors(g_pfreedv, 0);
+    g_resyncs = 0;
+    int i;
+    for(i=0; i<2*g_Nc; i++) {
+        g_error_hist[i] = 0;
+        g_error_histn[i] = 0;
+    }
+    
+}
+
+#ifdef ALC
+//-------------------------------------------------------------------------
+// OnTogBtnALCClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnALCClick(wxCommandEvent& event)
+{
+    wxMessageBox(wxT("Got Click!"), wxT("OnTogBtnALCClick"), wxOK);
+
+    event.Skip();
+}
+#endif
+
+// extra panel added to file open dialog to add loop checkbox
+MyExtraPlayFilePanel::MyExtraPlayFilePanel(wxWindow *parent): wxPanel(parent)
+{
+    m_cb = new wxCheckBox(this, -1, wxT("Loop"));
+    m_cb->SetToolTip(_("When checked file will repeat forever"));
+    m_cb->SetValue(g_loopPlayFileToMicIn);
+
+    // bug: I can't this to align right.....
+    wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
+    sizerTop->Add(m_cb, 0, wxALIGN_RIGHT, 0);
+    SetSizerAndFit(sizerTop);
+}
+
+static wxWindow* createMyExtraPlayFilePanel(wxWindow *parent)
+{
+    return new MyExtraPlayFilePanel(parent);
+}
+
+void MainFrame::StopPlayFileToMicIn(void)
+{
+    g_mutexProtectingCallbackData.Lock();
+    g_playFileToMicIn = false;
+    sf_close(g_sfPlayFile);
+    SetStatusText(wxT(""));
+    g_mutexProtectingCallbackData.Unlock();
+}
+
+//-------------------------------------------------------------------------
+// OnPlayFileToMicIn()
+//-------------------------------------------------------------------------
+void MainFrame::OnPlayFileToMicIn(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    if(g_playFileToMicIn) {
+        StopPlayFileToMicIn();
+        VoiceKeyerProcessEvent(VK_PLAY_FINISHED);
+    }
+    else
+    {
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+        wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Play File to Mic In"),
+                                    wxGetApp().m_playFileToMicInPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_OPEN | wxFD_FILE_MUST_EXIST
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraPlayFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_playFileToMicInPath, &fileName, &extension);
+        //wxLogDebug("m_playFileToMicInPath: %s", wxGetApp().m_playFileToMicInPath);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = FS;
+            }
+        }
+        g_sfPlayFile = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
+        if(g_sfPlayFile == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+
+        // Huh?! I just copied wxWidgets-2.9.4/samples/dialogs ....
+        g_loopPlayFileToMicIn = static_cast<MyExtraPlayFilePanel*>(ctrl)->getLoopPlayFileToMicIn();
+
+        SetStatusText(wxT("Playing File: ") + fileName + wxT(" to Mic Input") , 0);
+        g_playFileToMicIn = true;
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnPlayFileFromRadio()
+// This puppy "plays" a recorded file into the demodulator input, allowing us
+// to replay off air signals.
+//-------------------------------------------------------------------------
+void MainFrame::OnPlayFileFromRadio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    printf("OnPlayFileFromRadio:: %d\n", (int)g_playFileFromRadio);
+    if (g_playFileFromRadio)
+    {
+        printf("OnPlayFileFromRadio:: Stop\n");
+        g_mutexProtectingCallbackData.Lock();
+        g_playFileFromRadio = false;
+        sf_close(g_sfPlayFileFromRadio);
+        SetStatusText(wxT(""),0);
+        SetStatusText(wxT(""),1);
+        g_mutexProtectingCallbackData.Unlock();
+    }
+    else
+    {
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+        wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Play File - From Radio"),
+                                    wxGetApp().m_playFileFromRadioPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_OPEN | wxFD_FILE_MUST_EXIST
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraPlayFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_playFileFromRadioPath, &fileName, &extension);
+        //wxLogDebug("m_playFileToFromRadioPath: %s", wxGetApp().m_playFileFromRadioPath);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            }
+        }
+        g_sfPlayFileFromRadio = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
+        g_sfFs = sfInfo.samplerate;
+        if(g_sfPlayFileFromRadio == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+
+        // Huh?! I just copied wxWidgets-2.9.4/samples/dialogs ....
+        g_loopPlayFileFromRadio = static_cast<MyExtraPlayFilePanel*>(ctrl)->getLoopPlayFileToMicIn();
+
+        SetStatusText(wxT("Playing into from radio"), 0);
+        if(extension == wxT("raw")) {
+            wxString stringnumber = wxString::Format(wxT("%d"), (int)sfInfo.samplerate);
+            SetStatusText(wxT("raw file assuming Fs=") + stringnumber, 1);          
+        }
+        fprintf(g_logfile, "OnPlayFileFromRadio:: Playing File\n");
+        g_playFileFromRadio = true;
+        g_blink = 0.0;
+    }
+}
+
+// extra panel added to file save dialog to set number of seconds to record for
+
+MyExtraRecFilePanel::MyExtraRecFilePanel(wxWindow *parent): wxPanel(parent)
+{
+    wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
+
+    wxStaticText* staticText = new wxStaticText(this, wxID_ANY, _("Seconds:"), wxDefaultPosition, wxDefaultSize, 0);
+    sizerTop->Add(staticText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_secondsToRecord = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    m_secondsToRecord->SetToolTip(_("Number of seconds to record for"));
+    m_secondsToRecord->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_recFileFromRadioSecs));
+    sizerTop->Add(m_secondsToRecord, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    SetSizerAndFit(sizerTop);
+}
+
+static wxWindow* createMyExtraRecFilePanel(wxWindow *parent)
+{
+    return new MyExtraRecFilePanel(parent);
+}
+
+//-------------------------------------------------------------------------
+// OnRecFileFromRadio()
+//-------------------------------------------------------------------------
+void MainFrame::OnRecFileFromRadio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    if (g_recFileFromRadio) {
+        printf("Stopping Record....\n");
+        g_mutexProtectingCallbackData.Lock();
+        g_recFileFromRadio = false;
+        sf_close(g_sfRecFile);
+        SetStatusText(wxT(""));
+        g_mutexProtectingCallbackData.Unlock();
+    }
+    else {
+
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+         wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Record File From Radio"),
+                                    wxGetApp().m_recFileFromRadioPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_SAVE
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraRecFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_recFileFromRadioPath, &fileName, &extension);
+        wxLogDebug("m_recFileFromRadioPath: %s", wxGetApp().m_recFileFromRadioPath);
+        wxLogDebug("soundFile: %s", soundFile);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            }
+            else if(extension == wxT("wav"))
+            {
+                sfInfo.format     = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            } else {
+                wxMessageBox(wxT("Invalid file format"), wxT("Record File From Radio"), wxOK);
+                return;
+            }
+        }
+        else {
+            wxMessageBox(wxT("Invalid file format"), wxT("Record File From Radio"), wxOK);
+            return;
+        }
+
+        // Bug: on Win32 I cant read m_recFileFromRadioSecs, so have hard coded it
+#ifdef __WIN32__
+        long secs = wxGetApp().m_recFileFromRadioSecs;
+        g_recFromRadioSamples = FS*(unsigned int)secs;
+#else
+        // work out number of samples to record
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+        wxString secsString = static_cast<MyExtraRecFilePanel*>(ctrl)->getSecondsToRecord();
+        wxLogDebug("test: %s secsString: %s\n", wxT("testing 123"), secsString);
+
+        long secs;
+        if (secsString.ToLong(&secs)) {
+            wxGetApp().m_recFileFromRadioSecs = (unsigned int)secs;
+            //printf(" secondsToRecord: %d\n",  (unsigned int)secs);
+            g_recFromRadioSamples = FS*(unsigned int)secs;
+            //printf("g_recFromRadioSamples: %d\n", g_recFromRadioSamples);
+        }
+        else {
+            wxMessageBox(wxT("Invalid number of Seconds"), wxT("Record File From Radio"), wxOK);
+            return;
+        }
+#endif
+
+        g_sfRecFile = sf_open(soundFile.c_str(), SFM_WRITE, &sfInfo);
+        if(g_sfRecFile == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        SetStatusText(wxT("Recording File: ") + fileName + wxT(" From Radio") , 0);
+        g_recFileFromRadio = true;
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnExit()
+//-------------------------------------------------------------------------
+void MainFrame::OnExit(wxCommandEvent& event)
+{
+    fprintf(stderr, "MainFrame::OnExit\n");
+    wxUnusedVar(event);
+#ifdef _USE_TIMER
+    m_plotTimer.Stop();
+#endif // _USE_TIMER
+    if(g_sfPlayFile != NULL)
+    {
+        sf_close(g_sfPlayFile);
+        g_sfPlayFile = NULL;
+    }
+    if(g_sfRecFile != NULL)
+    {
+        sf_close(g_sfRecFile);
+        g_sfRecFile = NULL;
+    }
+    if(m_RxRunning)
+    {
+        stopRxStream();
+    }
+    m_togBtnSplit->Disable();
+    //m_togRxID->Disable();
+    //m_togTxID->Disable();
+    m_togBtnAnalog->Disable();
+    //m_togBtnALC->Disable();
+    //m_btnTogPTT->Disable();
+    Pa_Terminate();
+    Destroy();
+}
+
+//-------------------------------------------------------------------------
+// OnExitClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnExitClick(wxCommandEvent& event)
+{
+    OnExit(event);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsAudio()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsAudio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    int rv = 0;
+    AudioOptsDialog *dlg = new AudioOptsDialog(NULL);
+    rv = dlg->ShowModal();
+    if(rv == wxID_OK)
+    {
+        dlg->ExchangeData(EXCHANGE_DATA_OUT);
+    }
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsAudioUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsAudioUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsFilter()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsFilter(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    FilterDlg *dlg = new FilterDlg(NULL, m_RxRunning, &m_newMicInFilter, &m_newSpkOutFilter);
+    dlg->ShowModal();
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsOptions()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsOptions(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    g_modal = true;
+    //fprintf(stderr,"g_modal: %d\n", g_modal);
+    optionsDlg->Show();
+}
+
+//-------------------------------------------------------------------------
+// OnToolsOptionsUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsOptionsUI(wxUpdateUIEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnToolsComCfg()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsComCfg(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    ComPortsDlg *dlg = new ComPortsDlg(NULL);
+
+    dlg->ShowModal();
+
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsComCfgUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsComCfgUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsPlugInCfg()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsPlugInCfg(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    PlugInDlg *dlg = new PlugInDlg(wxGetApp().m_plugInName, wxGetApp().m_numPlugInParam, wxGetApp().m_plugInParamName);
+    dlg->ShowModal();
+    delete dlg;
+}
+               
+void MainFrame::OnToolsPlugInCfgUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning && wxGetApp().m_plugIn);
+}
+
+
+//-------------------------------------------------------------------------
+// OnHelpCheckUpdates()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpCheckUpdates(wxCommandEvent& event)
+{
+    wxMessageBox("Got Click!", "OnHelpCheckUpdates", wxOK);
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnHelpCheckUpdatesUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpCheckUpdatesUI(wxUpdateUIEvent& event)
+{
+    event.Enable(false);
+}
+
+//-------------------------------------------------------------------------
+//OnHelpAbout()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpAbout(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    wxString msg;
+    msg.Printf( wxT("FreeDV %s\n\n")
+                wxT("Open Source Digital Voice\n\n")
+                wxT("For Help and Support visit: http://freedv.org\n\n")
+
+                wxT("GNU Public License V2.1\n\n")
+                wxT("Copyright (c) David Witten KD0EAG and David Rowe VK5DGR\n\n")
+                wxT("svn revision: %s\n"), FREEDV_VERSION, SVN_REVISION);
+
+    wxMessageBox(msg, wxT("About"), wxOK | wxICON_INFORMATION, this);
+}
+
+
+// Attempt to talk to rig using Hamlib
+
+bool MainFrame::OpenHamlibRig() {
+    if (wxGetApp().m_boolHamlibUseForPTT != true)
+       return false;
+    if (wxGetApp().m_intHamlibRig == 0)
+        return false;
+    if (wxGetApp().m_hamlib == NULL)
+        return false;
+
+    int rig = wxGetApp().m_intHamlibRig;
+    wxString port = wxGetApp().m_strHamlibSerialPort;
+    int serial_rate = wxGetApp().m_intHamlibSerialRate;
+    bool status = wxGetApp().m_hamlib->connect(rig, port.mb_str(wxConvUTF8), serial_rate);
+    if (status == false)
+        wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
+    return status;
+} 
+
+//-------------------------------------------------------------------------
+// OnTogBtnOnOff()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
+{
+    wxString startStop = m_togBtnOnOff->GetLabel();
+
+    // we are attempting to start
+
+    if (startStop.IsSameAs("Start"))
+    {
+        //
+        // Start Running -------------------------------------------------
+        //
+
+        // modify some button states when running
+
+        m_togBtnSplit->Enable();
+        m_togBtnAnalog->Enable();
+        m_togBtnOnOff->SetLabel(wxT("Stop"));
+        m_btnTogPTT->Enable();
+        m_togBtnVoiceKeyer->Enable();
+        vk_state = VK_IDLE;
+
+        m_rb1600->Disable();
+        //m_rb700b->Disable();
+        m_rb700c->Disable();
+        m_rb800xa->Disable();
+        if (m_rbPlugIn != NULL)
+            m_rbPlugIn->Disable();
+
+        // determine what mode we are using
+
+        if (m_rb1600->GetValue()) {
+            g_mode = FREEDV_MODE_1600;
+            g_Nc = 16;
+            m_panelScatter->setNc(g_Nc+1);  /* +1 for BPSK pilot */
+        }
+        #ifdef DISABLED
+        if (m_rb700b->GetValue()) {
+            g_mode = FREEDV_MODE_700B;
+            g_Nc = 14;
+            if (wxGetApp().m_FreeDV700Combine) {
+                m_panelScatter->setNc(g_Nc/2);  /* diversity combnation */
+            }
+            else {
+                m_panelScatter->setNc(g_Nc); 
+            }
+        }
+        #endif
+        if (m_rb700c->GetValue()) {
+            g_mode = FREEDV_MODE_700C;
+            g_Nc = 14;
+            if (wxGetApp().m_FreeDV700Combine) {
+                m_panelScatter->setNc(g_Nc/2);  /* diversity combnation */
+            }
+            else {
+                m_panelScatter->setNc(g_Nc); 
+            }
+        }
+        if (m_rb800xa->GetValue()) {
+            g_mode = FREEDV_MODE_800XA;
+        }
+        if (m_rbPlugIn != NULL) {
+            if (m_rbPlugIn->GetValue()) {
+                g_mode = -1;  /* TODO; a better way of handling (enumarating?) non-freedv modes */
+
+                /* scale plots assuming Fs = 8000 Hz for now */
+
+                m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ)/8000.0);
+                m_panelWaterfall->setFs(8000.0);
+
+                (wxGetApp().m_plugin_startfp)(wxGetApp().m_plugInStates);
+            }
+        }
+
+        if (g_mode != -1) { 
+            // init freedv states
+
+            g_pfreedv = freedv_open(g_mode);
+            freedv_set_callback_txt(g_pfreedv, &my_put_next_rx_char, &my_get_next_tx_char, NULL);
+
+            freedv_set_callback_error_pattern(g_pfreedv, my_freedv_put_error_pattern, (void*)m_panelTestFrameErrors);
+            g_error_pattern_fifo = fifo_create(2*freedv_get_sz_error_pattern(g_pfreedv)+1);
+            g_error_hist = new short[FDMDV_NC_MAX*2];
+            g_error_histn = new short[FDMDV_NC_MAX*2];
+            int i;
+            for(i=0; i<2*FDMDV_NC_MAX; i++) {
+                g_error_hist[i] = 0;
+                g_error_histn[i] = 0;
+            }
+
+            assert(g_pfreedv != NULL);
+
+            // init Codec 2 LPC Post Filter
+
+            codec2_set_lpc_post_filter(freedv_get_codec2(g_pfreedv),
+                                       wxGetApp().m_codec2LPCPostFilterEnable,
+                                       wxGetApp().m_codec2LPCPostFilterBassBoost,
+                                       wxGetApp().m_codec2LPCPostFilterBeta,
+                                       wxGetApp().m_codec2LPCPostFilterGamma);
+
+            // Init Speex pre-processor states
+            // by inspecting Speex source it seems that only denoiser is on be default
+
+            g_speex_st = speex_preprocess_state_init(freedv_get_n_speech_samples(g_pfreedv), FS); 
+
+            // adjust spectrum and waterfall freq scaling base on mode
+
+            m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(freedv_get_modem_sample_rate(g_pfreedv)/2)));
+            m_panelWaterfall->setFs(freedv_get_modem_sample_rate(g_pfreedv));
+
+            // Init text msg decoding
+
+            freedv_set_varicode_code_num(g_pfreedv, wxGetApp().m_textEncoding);
+        }
+
+        modem_stats_open(&g_stats);
+        g_State = g_prev_State = 0;
+        g_snr = 0.0;
+        g_half_duplex = wxGetApp().m_boolHalfDuplex;
+
+        if (g_mode == FREEDV_MODE_800XA) {
+            m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_EYE);
+        }
+        else {
+            m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_SCATTER);
+        }
+
+        m_pcallsign = m_callsign;
+        memset(m_callsign, 0, sizeof(m_callsign));
+#ifdef __UDP_EXPERIMENTAL__
+        m_checksumGood = m_checksumBad = 0;
+        wxString s;
+        s.Printf("%d", m_checksumGood);
+        m_txtChecksumGood->SetLabel(s);              
+        s.Printf("%d", m_checksumBad);
+        m_txtChecksumBad->SetLabel(s);        
+#endif
+
+        m_maxLevel = 0;
+        m_textLevel->SetLabel(wxT(""));
+        m_gaugeLevel->SetValue(0);
+
+        //printf("m_textEncoding = %d\n", wxGetApp().m_textEncoding);
+        //printf("g_stats.snr: %f\n", g_stats.snr_est);
+
+        // attempt to start PTT ......
+        
+        if (wxGetApp().m_boolHamlibUseForPTT)
+            OpenHamlibRig();
+        if (wxGetApp().m_boolUseSerialPTT) {
+            OpenSerialPort();
+        }
+
+        // attempt to start sound cards and tx/rx processing
+
+        startRxStream();
+
+        if (m_RxRunning)
+        {
+#ifdef _USE_TIMER
+            m_plotTimer.Start(_REFRESH_TIMER_PERIOD, wxTIMER_CONTINUOUS);
+#endif // _USE_TIMER
+        }
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"start"); processTxtEvent(e);
+#endif
+    }
+
+    // Stop was pressed or start up failed
+
+    if (startStop.IsSameAs("Stop") || !m_RxRunning ) {
+
+        //
+        // Stop Running -------------------------------------------------
+        //
+
+#ifdef __UDP_EXPERIMENTAL__
+        optionsDlg->SetSpamTimerLight(false);
+#endif
+
+#ifdef _USE_TIMER
+        m_plotTimer.Stop();
+#endif // _USE_TIMER
+
+        // ensure we are not transmitting and shut down audio processing
+
+        if (wxGetApp().m_boolHamlibUseForPTT) {
+            Hamlib *hamlib = wxGetApp().m_hamlib; 
+            wxString hamlibError;
+            if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
+                if (hamlib->ptt(false, hamlibError) == false) {
+                    wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+                }
+                hamlib->close();
+            }
+        }
+
+        if (wxGetApp().m_boolUseSerialPTT) {
+            CloseSerialPort();
+        }
+
+        m_btnTogPTT->SetValue(false);
+        VoiceKeyerProcessEvent(VK_SPACE_BAR);
+
+        stopRxStream();
+        modem_stats_close(&g_stats);
+
+        // free up states, clean up
+
+        if (g_mode == -1) {
+            // PlugIn clean up
+            (wxGetApp().m_plugin_stopfp)(wxGetApp().m_plugInStates);
+        }
+        else {
+            // FreeDV clean up
+            delete g_error_hist;
+            delete g_error_histn;
+            fifo_destroy(g_error_pattern_fifo);
+            freedv_close(g_pfreedv);
+            speex_preprocess_state_destroy(g_speex_st);
+        }
+
+        m_newMicInFilter = m_newSpkOutFilter = true;
+
+        m_togBtnSplit->Disable();
+        //m_togRxID->Disable();
+        //m_togTxID->Disable();
+        m_togBtnAnalog->Disable();
+        m_btnTogPTT->Disable();
+        m_togBtnVoiceKeyer->Disable();
+        m_togBtnOnOff->SetLabel(wxT("Start"));
+        m_rb1600->Enable();
+        //m_rb700b->Enable();
+        m_rb700c->Enable();
+        m_rb800xa->Enable();
+        if (m_rbPlugIn != NULL)
+            m_rbPlugIn->Enable();
+           
+#ifdef DISABLED_FEATURE
+        m_rb700->Enable();
+        m_rb1400old->Enable();
+        m_rb1600Wide->Enable();
+        m_rb1400->Enable();
+        m_rb2000->Enable();
+#endif
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"stop"); processTxtEvent(e);
+#endif
+    }
+}
+
+//-------------------------------------------------------------------------
+// stopRxStream()
+//-------------------------------------------------------------------------
+void MainFrame::stopRxStream()
+{
+    if(m_RxRunning)
+    {
+        m_RxRunning = false;
+
+        fprintf(stderr, "waiting for thread to stop\n");
+        m_txRxThread->m_run = 0;
+        m_txRxThread->Wait();
+        fprintf(stderr, "thread stopped\n");
+
+        m_rxInPa->stop();
+        m_rxInPa->streamClose();
+        delete m_rxInPa;
+        if(m_rxOutPa != m_rxInPa) {
+                       m_rxOutPa->stop();
+                       m_rxOutPa->streamClose();
+                       delete m_rxOutPa;
+               }
+
+        if (g_nSoundCards == 2) {
+            m_txInPa->stop();
+            m_txInPa->streamClose();
+            delete m_txInPa;
+            if(m_txInPa != m_txOutPa) {
+                               m_txOutPa->stop();
+                               m_txOutPa->streamClose();
+                               delete m_txOutPa;
+                       }
+        }
+
+        destroy_fifos();
+        destroy_src();
+        deleteEQFilters(g_rxUserdata);
+        delete g_rxUserdata;
+    }
+}
+
+void MainFrame::destroy_fifos(void)
+{
+    fifo_destroy(g_rxUserdata->infifo1);
+    fifo_destroy(g_rxUserdata->outfifo1);
+    fifo_destroy(g_rxUserdata->infifo2);
+    fifo_destroy(g_rxUserdata->outfifo2);
+    fifo_destroy(g_rxUserdata->rxinfifo);
+    fifo_destroy(g_rxUserdata->rxoutfifo);
+}
+
+void MainFrame::destroy_src(void)
+{
+    src_delete(g_rxUserdata->insrc1);
+    src_delete(g_rxUserdata->outsrc1);
+    src_delete(g_rxUserdata->insrc2);
+    src_delete(g_rxUserdata->outsrc2);
+    src_delete(g_rxUserdata->insrcsf);
+}
+
+void  MainFrame::initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice,
+                                     int soundCard, int sampleRate, int inputChannels)
+{
+    // Note all of the wrapper functions below just set values in a
+    // portaudio struct so can't return any errors. So no need to trap
+    // any errors in this function.
+
+    // init input params
+
+    pa->setInputDevice(inDevice);
+    if(inDevice != paNoDevice) {
+        pa->setInputChannelCount(inputChannels);           // stereo input
+        pa->setInputSampleFormat(PA_SAMPLE_TYPE);
+        pa->setInputLatency(pa->getInputDefaultLowLatency());
+        pa->setInputHostApiStreamInfo(NULL);
+    }
+
+    pa->setOutputDevice(paNoDevice);
+    
+    // init output params
+    
+    pa->setOutputDevice(outDevice);
+    if(outDevice != paNoDevice) {
+        pa->setOutputChannelCount(2);                      // stereo output
+        pa->setOutputSampleFormat(PA_SAMPLE_TYPE);
+        pa->setOutputLatency(pa->getOutputDefaultLowLatency());
+        pa->setOutputHostApiStreamInfo(NULL);
+    }
+
+    // init params that affect input and output
+
+    /*
+      On Linux, setting this to wxGetApp().m_framesPerBuffer caused
+      intermittant break up on the audio from my IC7200 on Ubuntu 14.
+      After a day of bug hunting I found that 0, as recommended by the
+      PortAudio docunmentation, fixed the problem.
+    */
+
+    //pa->setFramesPerBuffer(wxGetApp().m_framesPerBuffer);
+    pa->setFramesPerBuffer(0);
+
+    pa->setSampleRate(sampleRate);
+    pa->setStreamFlags(paClipOff);
+}
+
+//-------------------------------------------------------------------------
+// startRxStream()
+//-------------------------------------------------------------------------
+void MainFrame::startRxStream()
+{
+    int   src_error;
+    const PaDeviceInfo *deviceInfo1 = NULL, *deviceInfo2 = NULL;
+    int   inputChannels1, inputChannels2;
+    bool  two_rx=false;
+    bool  two_tx=false;
+
+    if(!m_RxRunning) {
+        m_RxRunning = true;
+
+        if(Pa_Initialize())
+        {
+            wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
+        }
+
+        m_rxInPa = new PortAudioWrap();
+        if(g_soundCard1InDeviceNum != g_soundCard1OutDeviceNum)
+            two_rx=true;
+        if(g_soundCard2InDeviceNum != g_soundCard2OutDeviceNum)
+            two_tx=true;
+        
+        fprintf(g_logfile, "two_rx: %d two_tx: %d\n", two_rx, two_tx);
+        if(two_rx)
+            m_rxOutPa = new PortAudioWrap();
+        else
+            m_rxOutPa = m_rxInPa;
+
+        if (g_nSoundCards == 0) {
+            wxMessageBox(wxT("No Sound Cards configured, use Tools - Audio Config to configure"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+
+        // Init Sound card 1 ----------------------------------------------
+        // sanity check on sound card device numbers
+
+        if ((m_rxInPa->getDeviceCount() <= g_soundCard1InDeviceNum) ||
+            (m_rxOutPa->getDeviceCount() <= g_soundCard1OutDeviceNum)) {
+            wxMessageBox(wxT("Sound Card 1 not present"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                               delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+
+        // work out how many input channels this device supports.
+
+        deviceInfo1 = Pa_GetDeviceInfo(g_soundCard1InDeviceNum);
+        if (deviceInfo1 == NULL) {
+            wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                               delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+        if (deviceInfo1->maxInputChannels == 1)
+            inputChannels1 = 1;
+        else
+            inputChannels1 = 2;
+
+        if(two_rx) {
+            initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, paNoDevice, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+            initPortAudioDevice(m_rxOutPa, paNoDevice, g_soundCard1OutDeviceNum, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+               }
+        else
+            initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, g_soundCard1OutDeviceNum, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+
+        // Init Sound Card 2 ------------------------------------------------
+
+        if (g_nSoundCards == 2) {
+
+            m_txInPa = new PortAudioWrap();
+            if(two_tx)
+                m_txOutPa = new PortAudioWrap();
+            else
+                m_txOutPa = m_txInPa;
+
+            // sanity check on sound card device numbers
+
+            //printf("m_txInPa->getDeviceCount(): %d\n", m_txInPa->getDeviceCount());
+            //printf("g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+            //printf("g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+
+            if ((m_txInPa->getDeviceCount() <= g_soundCard2InDeviceNum) ||
+                (m_txOutPa->getDeviceCount() <= g_soundCard2OutDeviceNum)) {
+                wxMessageBox(wxT("Sound Card 2 not present"), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                if(two_rx)
+                    delete m_rxOutPa;
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                m_RxRunning = false;
+                return;
+            }
+
+            deviceInfo2 = Pa_GetDeviceInfo(g_soundCard2InDeviceNum);
+            if (deviceInfo2 == NULL) {
+                wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                if(two_rx)
+                                       delete m_rxOutPa;
+                delete m_txInPa;
+                if(two_tx)
+                                       delete m_txOutPa;
+                m_RxRunning = false;
+                return;
+            }
+            if (deviceInfo2->maxInputChannels == 1)
+                inputChannels2 = 1;
+            else
+                inputChannels2 = 2;
+
+            if(two_tx) {
+                               initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, paNoDevice, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+                               initPortAudioDevice(m_txOutPa, paNoDevice, g_soundCard2OutDeviceNum, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+                       }
+                       else
+                               initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, g_soundCard2OutDeviceNum, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+        }
+
+        // Init call back data structure ----------------------------------------------
+
+        g_rxUserdata = new paCallBackData;
+        g_rxUserdata->inputChannels1 = inputChannels1;
+        if (deviceInfo2 != NULL)
+            g_rxUserdata->inputChannels2 = inputChannels2;
+
+        // init sample rate conversion states
+
+        g_rxUserdata->insrc1 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrc1 != NULL);
+        g_rxUserdata->outsrc1 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->outsrc1 != NULL);
+        g_rxUserdata->insrc2 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrc2 != NULL);
+        g_rxUserdata->outsrc2 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->outsrc2 != NULL);
+
+        g_rxUserdata->insrcsf = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrcsf != NULL);
+
+        // create FIFOs used to interface between different buffer sizes
+
+        g_rxUserdata->infifo1 = fifo_create(8*N48);
+        g_rxUserdata->outfifo1 = fifo_create(10*N48);
+        g_rxUserdata->outfifo2 = fifo_create(8*N48);
+        g_rxUserdata->infifo2 = fifo_create(8*N48);
+        printf("N48: %d\n", N48);
+
+        g_rxUserdata->rxinfifo = fifo_create(10 * N8);
+        g_rxUserdata->rxoutfifo = fifo_create(10 * N8);
+
+        // Init Equaliser Filters ------------------------------------------------------
+
+        m_newMicInFilter = m_newSpkOutFilter = true;
+        designEQFilters(g_rxUserdata);
+        g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+        g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+
+        // optional tone in left channel to reliably trigger vox
+        
+        g_rxUserdata->leftChannelVoxTone = wxGetApp().m_leftChannelVoxTone;
+        g_rxUserdata->voxTonePhase = 0;
+
+        // Start sound card 1 ----------------------------------------------------------
+
+        m_rxInPa->setUserData(g_rxUserdata);
+        m_rxErr = m_rxInPa->setCallback(rxCallback);
+
+        m_rxErr = m_rxInPa->streamOpen();
+
+        if(m_rxErr != paNoError) {
+            wxMessageBox(wxT("Sound Card 1 Open/Setup error."), wxT("Error"), wxOK);
+                       delete m_rxInPa;
+                       if(two_rx)
+                               delete m_rxOutPa;
+                       delete m_txInPa;
+                       if(two_tx)
+                               delete m_txOutPa;
+            destroy_fifos();
+            destroy_src();
+            deleteEQFilters(g_rxUserdata);
+            delete g_rxUserdata;
+            m_RxRunning = false;
+            return;
+        }
+
+        m_rxErr = m_rxInPa->streamStart();
+        if(m_rxErr != paNoError) {
+            wxMessageBox(wxT("Sound Card 1 Stream Start Error."), wxT("Error"), wxOK);
+                       delete m_rxInPa;
+                       if(two_rx)
+                               delete m_rxOutPa;
+                       delete m_txInPa;
+                       if(two_tx)
+                               delete m_txOutPa;
+            destroy_fifos();
+            destroy_src();
+            deleteEQFilters(g_rxUserdata);
+            delete g_rxUserdata;
+            m_RxRunning = false;
+            return;
+        }
+
+        // Start separate output stream if needed
+
+        if(two_rx) {
+            m_rxOutPa->setUserData(g_rxUserdata);
+            m_rxErr = m_rxOutPa->setCallback(rxCallback);
+
+            m_rxErr = m_rxOutPa->streamOpen();
+
+            if(m_rxErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 1 Second Stream Open/Setup error."), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                delete m_rxOutPa;
+                delete m_txOutPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+
+            m_rxErr = m_rxOutPa->streamStart();
+            if(m_rxErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 1 Second Stream Start Error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                delete m_rxOutPa;
+                delete m_txOutPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+        }
+
+        // Start sound card 2 ----------------------------------------------------------
+
+        if (g_nSoundCards == 2) {
+
+            // question: can we use same callback data
+            // (g_rxUserdata)or both sound card callbacks?  Is there a
+            // chance of them both being called at the same time?  We
+            // could need a mutex ...
+
+            m_txInPa->setUserData(g_rxUserdata);
+            m_txErr = m_txInPa->setCallback(txCallback);
+            m_txErr = m_txInPa->streamOpen();
+
+            if(m_txErr != paNoError) {
+                fprintf(stderr, "Err: %d\n", m_txErr);
+                wxMessageBox(wxT("Sound Card 2 Open/Setup error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                if(two_rx) {
+                    m_rxOutPa->stop();
+                    m_rxOutPa->streamClose();
+                    delete m_rxOutPa;
+                }
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+            m_txErr = m_txInPa->streamStart();
+            if(m_txErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 2 Start Error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                if(two_rx) {
+                    m_rxOutPa->stop();
+                    m_rxOutPa->streamClose();
+                    delete m_rxOutPa;
+                }
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+
+            // Start separate output stream if needed
+
+            if (two_tx) {
+
+                // question: can we use same callback data
+                // (g_rxUserdata)or both sound card callbacks?  Is there a
+                // chance of them both being called at the same time?  We
+                // could need a mutex ...
+
+                m_txOutPa->setUserData(g_rxUserdata);
+                m_txErr = m_txOutPa->setCallback(txCallback);
+                m_txErr = m_txOutPa->streamOpen();
+
+                if(m_txErr != paNoError) {
+                    wxMessageBox(wxT("Sound Card 2 Second Stream Open/Setup error."), wxT("Error"), wxOK);
+                    m_rxInPa->stop();
+                    m_rxInPa->streamClose();
+                    delete m_rxInPa;
+                    if(two_rx) {
+                        m_rxOutPa->stop();
+                        m_rxOutPa->streamClose();
+                        delete m_rxOutPa;
+                    }
+                    m_txInPa->stop();
+                    m_txInPa->streamClose();
+                    delete m_txInPa;
+                    delete m_txOutPa;
+                    destroy_fifos();
+                    destroy_src();
+                    deleteEQFilters(g_rxUserdata);
+                    delete g_rxUserdata;
+                    m_RxRunning = false;
+                    return;
+                }
+                m_txErr = m_txOutPa->streamStart();
+                if(m_txErr != paNoError) {
+                    wxMessageBox(wxT("Sound Card 2 Second Stream Start Error."), wxT("Error"), wxOK);
+                    m_rxInPa->stop();
+                    m_rxInPa->streamClose();
+                    m_txInPa->stop();
+                    m_txInPa->streamClose();
+                    delete m_txInPa;
+                    if(two_rx) {
+                        m_rxOutPa->stop();
+                        m_rxOutPa->streamClose();
+                        delete m_rxOutPa;
+                    }
+                    delete m_txInPa;
+                    delete m_txOutPa;
+                    destroy_fifos();
+                    destroy_src();
+                    deleteEQFilters(g_rxUserdata);
+                    delete g_rxUserdata;
+                    m_RxRunning = false;
+                    return;
+                }
+            }
+        }
+
+        // start tx/rx processing thread
+
+        m_txRxThread = new txRxThread;
+
+        if ( m_txRxThread->Create() != wxTHREAD_NO_ERROR )
+        {
+            wxLogError(wxT("Can't create thread!"));
+        }
+
+        m_txRxThread->SetPriority(WXTHREAD_MAX_PRIORITY);
+
+        if ( m_txRxThread->Run() != wxTHREAD_NO_ERROR )
+        {
+            wxLogError(wxT("Can't start thread!"));
+        }
+
+    }
+}
+
+
+void MainFrame::processTxtEvent(char event[]) {
+    int rule = 0;
+
+    //printf("processTxtEvent:\n");
+    //printf("  event: %s\n", event);
+
+    // process with regexp and issue system command
+
+    // Each regexp in our list is separated by a newline.  We want to try all of them.
+
+    wxString event_str(event);
+    int match_end, replace_end;
+    match_end = replace_end = 0;
+    wxString regexp_match_list = wxGetApp().m_events_regexp_match;
+    wxString regexp_replace_list = wxGetApp().m_events_regexp_replace;
+
+    bool found_match = false;
+
+    while (((match_end = regexp_match_list.Find('\n')) != wxNOT_FOUND) && (rule < MAX_EVENT_RULES)) {
+        //printf("match_end: %d\n", match_end);
+        if ((replace_end = regexp_replace_list.Find('\n')) != wxNOT_FOUND) {
+            //printf("replace_end = %d\n", replace_end);
+
+            // candidate match and replace regexps strings exist, so lets try them
+
+            wxString regexp_match = regexp_match_list.SubString(0, match_end-1);
+            wxString regexp_replace = regexp_replace_list.SubString(0, replace_end-1);
+            //printf("match: %s replace: %s\n", (const char *)regexp_match.c_str(), (const char *)regexp_replace.c_str());
+            wxRegEx re(regexp_match);
+            //printf("  checking for match against: %s\n", (const char *)regexp_match.c_str());
+
+            // if we found a match, lets run the replace regexp and issue the system command
+
+            wxString event_str_rep = event_str;
+           
+            if (re.Replace(&event_str_rep, regexp_replace) != 0) {
+                fprintf(stderr, "  found match! event_str: %s\n", (const char *)event_str.c_str());
+                found_match = true;
+
+                bool enableSystem = false;
+                if (wxGetApp().m_events)
+                    enableSystem = true;
+
+                // no syscall if spam timer still running
+
+                if (spamTimer[rule].IsRunning()) {
+                    enableSystem = false;
+                    fprintf(stderr, "  spam timer running\n");
+                }
+
+                const char *event_out = event_str_rep.ToUTF8();
+                wxString event_out_with_return_code;
+
+                if (enableSystem) {
+                    int ret = wxExecute(event_str_rep);
+                    event_out_with_return_code.Printf(_T("%s -> returned %d"), event_out, ret);
+                    spamTimer[rule].Start((wxGetApp().m_events_spam_timer)*1000, wxTIMER_ONE_SHOT);
+                }
+                else
+                    event_out_with_return_code.Printf(_T("%s T: %d"), event_out, spamTimer[rule].IsRunning());
+
+                // update event log GUI if currently displayed
+                
+                if (optionsDlg != NULL) {                  
+                    optionsDlg->updateEventLog(wxString(event), event_out_with_return_code);                     
+                }
+            }
+        }
+        regexp_match_list = regexp_match_list.SubString(match_end+1, regexp_match_list.length());
+        regexp_replace_list = regexp_replace_list.SubString(replace_end+1, regexp_replace_list.length());
+
+        rule++;
+    }
+    if ((optionsDlg != NULL) && !found_match) {                  
+        optionsDlg->updateEventLog(wxString(event), _("<no match>"));                     
+    }
+}
+
+
+#define SBQ_MAX_ARGS 4
+
+void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q)
+{
+    char  *arg[SBQ_MAX_ARGS];
+    char   argstorage[SBQ_MAX_ARGS][80];
+    void  *sbq;
+    int    i, argc;
+
+    assert((strcmp(filterType, "bass") == 0)   ||
+           (strcmp(filterType, "treble") == 0) ||
+           (strcmp(filterType, "equalizer") == 0));
+
+    for(i=0; i<SBQ_MAX_ARGS; i++) {
+        arg[i] = &argstorage[i][0];
+        arg[i] = &argstorage[i][0];
+        arg[i] = &argstorage[i][0];
+    }
+
+    argc = 0;
+
+    if ((strcmp(filterType, "bass") == 0) || (strcmp(filterType, "treble") == 0)) {
+        sprintf(arg[argc++], "%s", filterType);
+        sprintf(arg[argc++], "%f", gaindB+1E-6);
+        sprintf(arg[argc++], "%f", freqHz);
+    }
+
+    if (strcmp(filterType, "equalizer") == 0) {
+        sprintf(arg[argc++], "%s", filterType);
+        sprintf(arg[argc++], "%f", freqHz);
+        sprintf(arg[argc++], "%f", Q);
+        sprintf(arg[argc++], "%f", gaindB+1E-6);
+    }
+
+    assert(argc <= SBQ_MAX_ARGS);
+
+    sbq = sox_biquad_create(argc-1, (const char **)arg);
+    assert(sbq != NULL);
+
+    return sbq;
+}
+
+void  MainFrame::designEQFilters(paCallBackData *cb)
+{
+    // init Mic In Equaliser Filters
+
+    if (m_newMicInFilter) {
+        //printf("designing new Min In filters\n");
+        cb->sbqMicInBass   = designAnEQFilter("bass", wxGetApp().m_MicInBassFreqHz, wxGetApp().m_MicInBassGaindB);
+        cb->sbqMicInTreble = designAnEQFilter("treble", wxGetApp().m_MicInTrebleFreqHz, wxGetApp().m_MicInTrebleGaindB);
+        cb->sbqMicInMid    = designAnEQFilter("equalizer", wxGetApp().m_MicInMidFreqHz, wxGetApp().m_MicInMidGaindB, wxGetApp().m_MicInMidQ);
+    }
+
+    // init Spk Out Equaliser Filters
+
+    if (m_newSpkOutFilter) {
+        //printf("designing new Spk Out filters\n");
+        //printf("designEQFilters: wxGetApp().m_SpkOutBassFreqHz: %f\n",wxGetApp().m_SpkOutBassFreqHz);
+        cb->sbqSpkOutBass   = designAnEQFilter("bass", wxGetApp().m_SpkOutBassFreqHz, wxGetApp().m_SpkOutBassGaindB);
+        cb->sbqSpkOutTreble = designAnEQFilter("treble", wxGetApp().m_SpkOutTrebleFreqHz, wxGetApp().m_SpkOutTrebleGaindB);
+        cb->sbqSpkOutMid    = designAnEQFilter("equalizer", wxGetApp().m_SpkOutMidFreqHz, wxGetApp().m_SpkOutMidGaindB, wxGetApp().m_SpkOutMidQ);
+    }
+}
+
+void  MainFrame::deleteEQFilters(paCallBackData *cb)
+{
+    if (m_newMicInFilter) {
+        sox_biquad_destroy(cb->sbqMicInBass);
+        sox_biquad_destroy(cb->sbqMicInTreble);
+        sox_biquad_destroy(cb->sbqMicInMid);
+    }
+    if (m_newSpkOutFilter) {
+        sox_biquad_destroy(cb->sbqSpkOutBass);
+        sox_biquad_destroy(cb->sbqSpkOutTreble);
+        sox_biquad_destroy(cb->sbqSpkOutMid);
+    }
+}
+
+// returns number of output samples generated by resampling
+int resample(SRC_STATE *src,
+            short      output_short[],
+            short      input_short[],
+            int        output_sample_rate,
+            int        input_sample_rate,
+            int        length_output_short, // maximum output array length in samples
+            int        length_input_short
+            )
+{
+    SRC_DATA src_data;
+    float    input[N48*4];
+    float    output[N48*4];
+    int      ret;
+
+    assert(src != NULL);
+    assert(length_input_short <= N48*4);
+    assert(length_output_short <= N48*4);
+
+    src_short_to_float_array(input_short, input, length_input_short);
+
+    src_data.data_in = input;
+    src_data.data_out = output;
+    src_data.input_frames = length_input_short;
+    src_data.output_frames = length_output_short;
+    src_data.end_of_input = 0;
+    src_data.src_ratio = (float)output_sample_rate/input_sample_rate;
+
+    ret = src_process(src, &src_data);
+    assert(ret == 0);
+
+    assert(src_data.output_frames_gen <= length_output_short);
+    src_float_to_short_array(output, output_short, src_data.output_frames_gen);
+
+    return src_data.output_frames_gen;
+}
+
+
+// Decimates samples using an algorithm that produces nice plots of
+// speech signals at a low sample rate.  We want a low sample rate so
+// we don't hammer the graphics system too hard.  Saves decimated data
+// to a fifo for plotting on screen.
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length, int fs)
+{
+    int decimation = fs/WAVEFORM_PLOT_FS;
+    int nSamples, sample;
+    int i, st, en, max, min;
+    short dec_samples[length];
+
+    nSamples = length/decimation;
+
+    for(sample = 0; sample < nSamples; sample += 2)
+    {
+        st = decimation*sample;
+        en = decimation*(sample+2);
+        max = min = 0;
+        for(i=st; i<en; i++ )
+        {
+            if (max < buf[i]) max = buf[i];
+            if (min > buf[i]) min = buf[i];
+        }
+        dec_samples[sample] = max;
+        dec_samples[sample+1] = min;
+    }
+    fifo_write(plotFifo, dec_samples, nSamples);
+}
+
+void txRxProcessing()
+{
+
+    paCallBackData  *cbData = g_rxUserdata;
+
+    // Buffers re-used by tx and rx processing
+    // signals in in48k/out48k are at a maximum sample rate of 48k, could be 44.1kHz
+    // depending on sound hardware.
+
+    short           in8k_short[4*N8];
+    short           in48k_short[4*N48];
+    short           out8k_short[4*N8];
+    short           out48k_short[4*N48];
+    int             nout, samplerate, n_samples;
+
+    //fprintf(g_logfile, "start infifo1: %5d outfifo2: %5d\n", fifo_used(cbData->infifo1), fifo_used(cbData->outfifo2));
+
+    // FreeDV 700 uses a modem sample rate of 7500 Hz which requires some special treatment
+
+    if (g_analog || g_mode == -1) 
+        samplerate = FS;
+    else
+        samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+
+    //
+    //  RX side processing --------------------------------------------
+    //
+
+    // while we have enough input samples available ...
+
+    int nsam = g_soundCard1SampleRate * (float)N8/FS;
+    assert(nsam <= N48);
+    g_mutexProtectingCallbackData.Lock();
+    while ((fifo_read(cbData->infifo1, in48k_short, nsam) == 0) && ((g_half_duplex && !g_tx) || !g_half_duplex)) 
+    {
+        g_mutexProtectingCallbackData.Unlock();
+        unsigned int n8k;
+
+        n8k = resample(cbData->insrc1, in8k_short, in48k_short, samplerate, g_soundCard1SampleRate, N8, nsam);
+        assert(n8k <= N8);
+
+        // optionally save "from radio" signal (write demod input to file)
+        // Really useful for testing and development as it allows us
+        // to repeat tests using off air signals
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_recFileFromRadio && (g_sfRecFile != NULL)) {
+            //printf("g_recFromRadioSamples: %d  n8k: %d \n", g_recFromRadioSamples);
+            if (g_recFromRadioSamples < n8k) {
+                sf_write_short(g_sfRecFile, in8k_short, g_recFromRadioSamples);
+                wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_recFileFromRadioEventId );
+                // call stop/start record menu item, should be thread safe
+                g_parent->GetEventHandler()->AddPendingEvent( event );
+                g_recFromRadioSamples = 0;
+                //printf("finished recording g_recFromRadioSamples: %d n8k: %d!\n", g_recFileFromRadio, n8k);
+            }
+            else {
+                sf_write_short(g_sfRecFile, in8k_short, n8k);
+                g_recFromRadioSamples -= n8k;
+            }
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        // optionally read "from radio" signal from file (read demod input from file)
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_playFileFromRadio && (g_sfPlayFileFromRadio != NULL)) {
+            unsigned int nsf = n8k*g_sfFs/samplerate;
+            short        insf_short[nsf];
+            unsigned int n = sf_read_short(g_sfPlayFileFromRadio, insf_short, nsf);
+            n8k = resample(cbData->insrcsf, in8k_short, insf_short, samplerate, g_sfFs, N8, nsf);
+            //fprintf(g_logfile, "n: %d nsf: %d n8k: %d samplerate: %d\n", n, nsf, n8k, samplerate);
+            assert(n8k <= N8);
+
+            if (n == 0) {
+                if (g_loopPlayFileFromRadio)
+                    sf_seek(g_sfPlayFileFromRadio, 0, SEEK_SET);
+                else {
+                    printf("playFileFromRadio finished, issuing event!\n");
+                    wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_playFileFromRadioEventId );
+                    // call stop/start play menu item, should be thread safe
+                    g_parent->GetEventHandler()->AddPendingEvent( event );
+                }
+            }
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        resample_for_plot(g_plotDemodInFifo, in8k_short, n8k, samplerate);
+
+        if (g_mode != -1) {
+            // send latest squelch level to FreeDV API, as it handles squelch internally
+
+            freedv_set_squelch_en(g_pfreedv, g_SquelchActive);
+            freedv_set_snr_squelch_thresh(g_pfreedv, g_SquelchLevel);
+        }
+
+        // Optional tone interferer
+
+        if (wxGetApp().m_tone) {
+            float w = 2.0*M_PI*wxGetApp().m_tone_freq_hz/freedv_get_modem_sample_rate(g_pfreedv);
+            float s;
+            unsigned int i;
+            for(i=0; i<n8k; i++) {
+                s = (float)wxGetApp().m_tone_amplitude*cos(g_tone_phase);   
+                in8k_short[i] += (int)s;             
+                g_tone_phase += w;
+                //fprintf(stderr, "%f\n", s);
+            }
+            g_tone_phase -= 2.0*M_PI*floor(g_tone_phase/(2.0*M_PI));                                         
+        }
+
+        //fprintf(g_logfile, "snr_squelch_thresh: %f\n",  g_pfreedv->snr_squelch_thresh);
+
+        // compute rx spectrum - do here so update rate in constant
+
+        COMP  rx_fdm[n8k];
+        float rx_spec[MODEM_STATS_NSPEC];
+        unsigned int   i;
+
+        for(i=0; i<n8k; i++) {
+            rx_fdm[i].real = in8k_short[i];
+            rx_fdm[i].imag = 0.0;
+        }            
+        modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, n8k);
+
+        // Average rx spectrum data using a simple IIR low pass filter
+
+        for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+            g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+        }
+
+        // Get some audio to send to headphones/speaker.  If in analog
+        // mode we pass thru the "from radio" audio to the
+        // headphones/speaker.
+
+        if (g_analog) {
+            memcpy(out8k_short, in8k_short, sizeof(short)*n8k);
+            
+            #ifdef OLDSPEC
+            // compute rx spectrum 
+
+            COMP  rx_fdm[n8k];
+            float rx_spec[MODEM_STATS_NSPEC];
+            unsigned int   i;
+
+            for(i=0; i<n8k; i++) {
+                rx_fdm[i].real = in8k_short[i];
+                rx_fdm[i].imag = 0.0;
+            }            
+            modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, n8k);
+
+            // Average rx spectrum data using a simple IIR low pass filter
+
+            for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+                g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+            }
+            #endif
+        }
+        else {
+            fifo_write(cbData->rxinfifo, in8k_short, n8k);
+            per_frame_rx_processing(cbData->rxoutfifo, cbData->rxinfifo);
+            memset(out8k_short, 0, sizeof(short)*N8);
+            fifo_read(cbData->rxoutfifo, out8k_short, N8);
+            //printf("out8k_short: %d\n", out8k_short[0]);
+        }
+
+
+        // Optional Spk Out EQ Filtering, need mutex as filter can change at run time
+        g_mutexProtectingCallbackData.Lock();
+        if (cbData->spkOutEQEnable) {
+            sox_biquad_filter(cbData->sbqSpkOutBass,   out8k_short, out8k_short, N8);
+            sox_biquad_filter(cbData->sbqSpkOutTreble, out8k_short, out8k_short, N8);
+            sox_biquad_filter(cbData->sbqSpkOutMid,    out8k_short, out8k_short, N8);
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        resample_for_plot(g_plotSpeechOutFifo, out8k_short, N8, FS);
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_nSoundCards == 1) {
+            nout = resample(cbData->outsrc2, out48k_short, out8k_short, g_soundCard1SampleRate, FS, N48, N8);
+            fifo_write(cbData->outfifo1, out48k_short, nout);
+        }
+        else {
+            nout = resample(cbData->outsrc2, out48k_short, out8k_short, g_soundCard2SampleRate, FS, N48, N8);
+            fifo_write(cbData->outfifo2, out48k_short, nout);
+        }
+    }
+    g_mutexProtectingCallbackData.Unlock();
+
+    //
+    //  TX side processing --------------------------------------------
+    //
+
+    if ((g_mode != -1) && ((g_nSoundCards == 2) && ((g_half_duplex && g_tx) || !g_half_duplex))) {
+        int ret;
+
+        // Make sure we have q few frames of modulator output
+        // samples.  This also locks the modulator to the sample rate
+        // of sound card 1.  We want to make sure that modulator
+        // samples are uninterrupted by differences in sample rate
+        // between this sound card and sound card 2.
+
+        g_mutexProtectingCallbackData.Lock();
+        while((unsigned)fifo_used(cbData->outfifo1) < 6*N48)
+        {
+            g_mutexProtectingCallbackData.Unlock();
+
+            int   nsam = g_soundCard2SampleRate * freedv_get_n_speech_samples(g_pfreedv)/FS;
+            assert(nsam <= 4*N48);
+
+            // infifo2 is written to by another sound card so it may
+            // over or underflow, but we don't realy care.  It will
+            // just result in a short interruption in audio being fed
+            // to codec2_enc, possibly making a click every now and
+            // again in the decoded audio at the other end.
+
+            // zero speech input just in case infifo2 underflows
+            memset(in48k_short, 0, nsam*sizeof(short));
+            fifo_read(cbData->infifo2, in48k_short, nsam);
+
+            nout = resample(cbData->insrc2, in8k_short, in48k_short, FS, g_soundCard2SampleRate, 4*N8, nsam);
+
+            // optionally use file for mic input signal
+
+            g_mutexProtectingCallbackData.Lock();
+            if (g_playFileToMicIn && (g_sfPlayFile != NULL)) {
+                int n = sf_read_short(g_sfPlayFile, in8k_short, nout);
+                //fprintf(stderr, "n: %d nout: %d\n", n, nout);
+                if (n != nout) {
+                    if (g_loopPlayFileToMicIn)
+                        sf_seek(g_sfPlayFile, 0, SEEK_SET);
+                    else {
+                        wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_playFileToMicInEventId );
+                        // call stop/start play menu item, should be thread safe
+                        g_parent->GetEventHandler()->AddPendingEvent( event );
+                    }
+                }
+            }
+            g_mutexProtectingCallbackData.Unlock();
+
+            // Optional Speex pre-processor for acoustic noise reduction
+
+            if (wxGetApp().m_speexpp_enable) {
+                speex_preprocess_run(g_speex_st, in8k_short);
+            }
+
+            // Optional Mic In EQ Filtering, need mutex as filter can change at run time
+
+            g_mutexProtectingCallbackData.Lock();
+            if (cbData->micInEQEnable) {
+                sox_biquad_filter(cbData->sbqMicInBass, in8k_short, in8k_short, nout);
+                sox_biquad_filter(cbData->sbqMicInTreble, in8k_short, in8k_short, nout);
+                sox_biquad_filter(cbData->sbqMicInMid, in8k_short, in8k_short, nout);
+            }
+            g_mutexProtectingCallbackData.Unlock();
+
+            resample_for_plot(g_plotSpeechInFifo, in8k_short, nout, FS);
+
+            n_samples = freedv_get_n_nom_modem_samples(g_pfreedv);
+
+            if (g_analog) {
+                n_samples = freedv_get_n_speech_samples(g_pfreedv);
+
+                // Boost the "from mic" -> "to radio" audio in analog
+                // mode.  The need for the gain was found by
+                // experiment - analog SSB sounded too quiet compared
+                // to digital. With digital voice we generally drive
+                // the "to radio" (SSB radio mic input) at about 25%
+                // of the peak level for normal SSB voice. So we
+                // introduce 6dB gain to make analog SSB sound the
+                // same level as the digital.  Watch out for clipping.
+                for(int i=0; i<n_samples; i++) {
+                    float out = (float)in8k_short[i]*2.0;
+                    if (out > 32767) out = 32767.0;
+                    if (out < -32767) out = -32767.0;
+                    out8k_short[i] = out;
+                }
+            }
+            else {
+                COMP tx_fdm[freedv_get_n_nom_modem_samples(g_pfreedv)];
+                COMP tx_fdm_offset[freedv_get_n_nom_modem_samples(g_pfreedv)];
+                int  i;
+
+                if (g_mode == FREEDV_MODE_800XA) {
+                    /* 800XA doesn't support complex output just yet */
+                    freedv_tx(g_pfreedv, out8k_short, in8k_short);
+                }
+                else {
+                    freedv_comptx(g_pfreedv, tx_fdm, in8k_short);
+  
+                    freq_shift_coh(tx_fdm_offset, tx_fdm, g_TxFreqOffsetHz, freedv_get_modem_sample_rate(g_pfreedv), &g_TxFreqOffsetPhaseRect, freedv_get_n_nom_modem_samples(g_pfreedv));
+                    for(i=0; i<freedv_get_n_nom_modem_samples(g_pfreedv); i++)
+                        out8k_short[i] = tx_fdm_offset[i].real;
+                }
+            }
+
+            // output one frame of modem signal
+            nout = resample(cbData->outsrc1, out48k_short, out8k_short, g_soundCard1SampleRate, samplerate, N48*4, n_samples);
+            g_mutexProtectingCallbackData.Lock();
+            ret = fifo_write(cbData->outfifo1, out48k_short, nout);
+            //fprintf(stderr,"nout: %d ret: %d N48*4: %d\n", nout, ret, N48*4);
+
+            assert(ret != -1);
+        }
+        g_mutexProtectingCallbackData.Unlock();
+    }
+   
+    //fprintf(g_logfile, "  end infifo1: %5d outfifo2: %5d\n", fifo_used(cbData->infifo1), fifo_used(cbData->outfifo2));
+
+}
+
+//----------------------------------------------------------------
+// per_frame_rx_processing()
+//----------------------------------------------------------------
+
+void per_frame_rx_processing(
+                             FIFO    *output_fifo,   // decoded speech samples
+                             FIFO    *input_fifo
+                             )
+{
+    #ifdef OLDSPEC
+    float               rx_spec[MODEM_STATS_NSPEC];
+    #endif
+    int                 i;
+
+    if (g_mode == -1) {
+        // PlugIn processing ---------------------------------------------------
+
+        int   nin = 160; // TODO: hard code for now - some sort of plugin supplied param in future
+        short input_buf[nin];
+
+        while (fifo_read(input_fifo, input_buf, nin) == 0) {
+            (wxGetApp().m_plugin_rx_samplesfp)(wxGetApp().m_plugInStates, input_buf, nin);
+        }
+
+        #ifdef OLD_SPEC
+        COMP  rx_fdm[nin];
+
+        for(i=0; i<nin; i++) {
+            rx_fdm[i].real = (float)input_buf[i];
+            rx_fdm[i].imag = 0.0;
+        }
+
+        modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, nin);
+
+        // Average rx spectrum data using a simple IIR low pass filter
+
+        for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+            g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+        }
+        #endif
+
+    }
+    else {
+        // FreeDV processing ----------------------------------------------------
+
+        short               input_buf[freedv_get_n_max_modem_samples(g_pfreedv)];
+        short               output_buf[freedv_get_n_speech_samples(g_pfreedv)];
+        COMP                rx_fdm[freedv_get_n_max_modem_samples(g_pfreedv)];
+        COMP                rx_fdm_offset[freedv_get_n_max_modem_samples(g_pfreedv)];
+        int                 nin, nout;
+
+        nin = freedv_nin(g_pfreedv);
+        while (fifo_read(input_fifo, input_buf, nin) == 0) {
+            assert(nin <= freedv_get_n_max_modem_samples(g_pfreedv));
+
+            #ifdef OLD_SPEC
+            int nin_prev = nin;
+            #endif
+
+            //fwrite(input_buf, sizeof(short), nin, ftest);
+
+            // demod per frame processing
+
+            for(i=0; i<nin; i++) {
+                rx_fdm[i].real = (float)input_buf[i];
+                rx_fdm[i].imag = 0.0;
+            }
+       
+            // Optional channel noise
+
+            if (g_channel_noise) {
+                fdmdv_simulate_channel(&g_sig_pwr_av, rx_fdm, nin, wxGetApp().m_noise_snr);
+            }
+
+            freq_shift_coh(rx_fdm_offset, rx_fdm, g_RxFreqOffsetHz, freedv_get_modem_sample_rate(g_pfreedv), &g_RxFreqOffsetPhaseRect, nin);
+            nout = freedv_comprx(g_pfreedv, output_buf, rx_fdm_offset);
+            //kprintf("nout %d outbuf_buf[0]: %d\n", nout, output_buf[0]);
+            fifo_write(output_fifo, output_buf, nout);
+        
+            nin = freedv_nin(g_pfreedv);
+            g_State = freedv_get_sync(g_pfreedv);
+
+            //fprintf(g_logfile, "g_State: %d g_stats.sync: %d snr: %f \n", g_State, g_stats.sync, f->snr);
+
+            // grab extended stats so we can plot spectrum, scatter diagram etc
+
+            freedv_get_modem_extended_stats(g_pfreedv, &g_stats);
+
+            #ifdef OLD_SPEC
+            // compute rx spectrum 
+
+            modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, nin_prev); 
+            
+            // Average rx spectrum data using a simple IIR low pass filter
+
+            for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+                g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+            }
+            #endif
+        }
+    }
+
+
+}
+
+
+//-------------------------------------------------------------------------
+// rxCallback()
+//
+// Sound card 1 callback from PortAudio, that is used for processing rx
+// side:
+//
+// + infifo1 is the "from radio" off air modem signal from the SSB rx that we send to the demod.
+// + In single sound card mode outfifo1 is the "to speaker/headphones" decoded speech output.
+// + In dual sound card mode outfifo1 is the "to radio" modulator signal to the SSB tx.
+//
+//-------------------------------------------------------------------------
+int MainFrame::rxCallback(
+                            const void      *inputBuffer,
+                            void            *outputBuffer,
+                            unsigned long   framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void            *userData
+                         )
+{
+    paCallBackData  *cbData = (paCallBackData*)userData;
+    short           *rptr    = (short*)inputBuffer;
+    short           *wptr    = (short*)outputBuffer;
+
+    short           indata[MAX_FPB];
+    short           outdata[MAX_FPB];
+
+    unsigned int    i;
+
+    (void) timeInfo;
+    (void) statusFlags;
+
+    wxMutexLocker lock(g_mutexProtectingCallbackData);
+
+    //fprintf(g_logfile, "cb1 statusFlags: 0x%x framesPerBuffer: %d rptr: 0x%x wptr: 0x%x \n", (int)statusFlags,
+    //        framesPerBuffer, rptr, wptr);
+
+    //
+    //  RX side processing --------------------------------------------
+    //
+
+    // assemble a mono buffer and write to FIFO
+
+    assert(framesPerBuffer < MAX_FPB);
+
+    if(rptr) {
+        //fprintf(g_logfile,"in %ld %d\n",  framesPerBuffer, g_in++);
+        //g_indata += framesPerBuffer;
+        for(i = 0; i < framesPerBuffer; i++, rptr += cbData->inputChannels1)
+            indata[i] = rptr[0];                       
+        if (fifo_write(cbData->infifo1, indata, framesPerBuffer)) {
+            //fprintf(g_logfile, "infifo1 full\n");
+        }
+        //fifo_write(cbData->outfifo1, indata, framesPerBuffer);
+    }
+
+    // OK now set up output samples for this callback
+
+    if(wptr) {
+        //fprintf(g_logfile,"out %ld %d\n",  framesPerBuffer, g_out++);
+        if (fifo_read(cbData->outfifo1, outdata, framesPerBuffer) == 0) {
+
+            // write signal to both channels
+
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                if (cbData->leftChannelVoxTone) {
+                    cbData->voxTonePhase += 2.0*M_PI*VOX_TONE_FREQ/g_soundCard1SampleRate;
+                    cbData->voxTonePhase -= 2.0*M_PI*floor(cbData->voxTonePhase/(2.0*M_PI));
+                    wptr[0] = VOX_TONE_AMP*cos(cbData->voxTonePhase);                              
+                    //printf("%f %d\n", cbData->voxTonePhase, wptr[0]);
+                }
+                else
+                    wptr[0] = outdata[i];
+                               
+                wptr[1] = outdata[i];
+            }
+        }
+        else {
+            //fprintf(g_logfile, "outfifo1 empty\n");
+            // zero output if no data available
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = 0;
+                wptr[1] = 0;
+            }
+        }
+    }
+
+    return paContinue;
+}
+
+
+//-------------------------------------------------------------------------
+// txCallback()
+//-------------------------------------------------------------------------
+int MainFrame::txCallback(
+                            const void *inputBuffer,
+                            void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo *outTime,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData
+                        )
+{
+    paCallBackData  *cbData = (paCallBackData*)userData;
+    unsigned int    i;
+    short           *rptr    = (short*)inputBuffer;
+    short           *wptr    = (short*)outputBuffer;
+    short           indata[MAX_FPB];
+    short           outdata[MAX_FPB];
+
+    wxMutexLocker lock(g_mutexProtectingCallbackData);
+
+    //    if (statusFlags)
+    //    printf("cb2 statusFlags: 0x%x\n", (int)statusFlags);
+
+    // assemble a mono buffer and write to FIFO
+
+    assert(framesPerBuffer < MAX_FPB);
+
+    if(rptr) {
+        for(i = 0; i < framesPerBuffer; i++, rptr += cbData->inputChannels2)
+            indata[i] = rptr[0];                        
+    }
+
+    //#define SC2_LOOPBACK
+#ifdef SC2_LOOPBACK
+    //TODO: This doesn't work unless using the same soundcard!
+
+    if(wptr) {
+        for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+            wptr[0] = indata[i];
+            wptr[1] = indata[i];
+        }
+    }
+
+#else
+    if(rptr) {
+        if (fifo_write(cbData->infifo2, indata, framesPerBuffer)) {
+            //fprintf(g_logfile, "infifo2 full\n");
+        }
+    }
+
+    // OK now set up output samples for this callback
+
+    if(wptr) {
+        if (fifo_read(cbData->outfifo2, outdata, framesPerBuffer) == 0) {
+               
+            // write signal to both channels */
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = outdata[i];
+                wptr[1] = outdata[i];
+            }
+        }
+        else {
+            //fprintf(g_logfile, "outfifo2 empty\n");
+            // zero output if no data available
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = 0;
+                wptr[1] = 0;
+            }
+        }
+    }
+#endif
+    return paContinue;
+}
+
+// Callback from plot_spectrum & plot_waterfall.  would be nice to
+// work out a way to do this without globals.
+
+void fdmdv2_clickTune(float freq) {
+
+    // The demod is hard-wired to expect a centre frequency of
+    // FDMDV_FCENTRE.  So we want to take the signal centered on the
+    // click tune freq and re-centre it on FDMDV_FCENTRE.  For example
+    // if the click tune freq is 1500Hz, and FDMDV_CENTRE is 1200 Hz,
+    // we need to shift the input signal centred on 1500Hz down to
+    // 1200Hz, an offset of -300Hz.
+
+    // Bit of an "indent" as we are often trying to get it back
+    // exactly in the centre
+
+    if (fabs(FDMDV_FCENTRE - freq) < 10.0) {
+        freq = FDMDV_FCENTRE;
+        fprintf(stderr, "indent!\n");
+    }
+
+    if (g_split) {
+        g_RxFreqOffsetHz = FDMDV_FCENTRE - freq;
+    }
+    else {
+        g_TxFreqOffsetHz = freq - FDMDV_FCENTRE;
+        g_RxFreqOffsetHz = FDMDV_FCENTRE - freq;
+    }
+}
+
+//----------------------------------------------------------------
+// OpenSerialPort()
+//----------------------------------------------------------------
+
+void MainFrame::OpenSerialPort(void)
+{
+    Serialport *serialport = wxGetApp().m_serialport;
+
+    if(!wxGetApp().m_strRigCtrlPort.IsEmpty()) {
+       serialport->openport(wxGetApp().m_strRigCtrlPort.c_str(), 
+                            wxGetApp().m_boolUseRTS, 
+                            wxGetApp().m_boolRTSPos, 
+                            wxGetApp().m_boolUseDTR,
+                            wxGetApp().m_boolDTRPos);
+       if (serialport->isopen()) {
+            // always start PTT in Rx state
+           serialport->ptt(false);
+       }
+       else {
+           wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this);
+       }
+    }
+}
+
+
+//----------------------------------------------------------------
+// CloseSerialPort()
+//----------------------------------------------------------------
+
+void MainFrame::CloseSerialPort(void)
+{
+    Serialport *serialport = wxGetApp().m_serialport;
+    if (serialport->isopen()) {
+        // always end with PTT in rx state
+
+        serialport->ptt(false);
+        serialport->closeport();
+    }
+}
+
+
+#ifdef __UDP_SUPPORT__
+
+//----------------------------------------------------------------
+// PollUDP() - see if any commands on UDP port
+//----------------------------------------------------------------
+
+// test this puppy with netcat: 
+//   $ echo "hello" | nc -u -q1 localhost 3000
+
+int MainFrame::PollUDP(void)
+{
+    // this will block until message received, so we put it in it's own thread
+
+    char buf[1024];
+    char reply[80];
+    size_t n = m_udp_sock->RecvFrom(m_udp_addr, buf, sizeof(buf)).LastCount();
+
+    if (n) {
+        wxString bufstr = wxString::From8BitData(buf, n);
+        bufstr.Trim();
+        wxString ipaddr = m_udp_addr.IPAddress();
+        printf("Received: \"%s\" from %s:%u\n",
+               (const char *)bufstr.c_str(),
+               (const char *)ipaddr.c_str(), m_udp_addr.Service());
+
+        // for security only accept commands from local host
+
+        sprintf(reply,"nope\n");
+        if (ipaddr.Cmp(_("127.0.0.1")) == 0) {
+
+            // process commands
+
+            if (bufstr.Cmp(_("restore")) == 0) {
+                m_schedule_restore = true;  // Make Restore happen in main thread to avoid crashing
+                sprintf(reply,"ok\n");
+            }
+                
+            wxString itemToSet, val;
+            if (bufstr.StartsWith(_("set "), &itemToSet)) {
+                if (itemToSet.StartsWith("txtmsg ", &val)) {
+                    // note: if options dialog is open this will get overwritten
+                    wxGetApp().m_callSign = val;
+                }  
+                sprintf(reply,"ok\n");
+            }
+            if (bufstr.StartsWith(_("ptton"), &itemToSet)) {
+                // note: if options dialog is open this will get overwritten
+                m_btnTogPTT->SetValue(true);
+                togglePTT();
+                sprintf(reply,"ok\n");
+            }
+            if (bufstr.StartsWith(_("pttoff"), &itemToSet)) {
+                // note: if options dialog is open this will get overwritten
+                m_btnTogPTT->SetValue(false);
+                togglePTT();
+                sprintf(reply,"ok\n");
+            }
+                
+        }
+        else {
+            printf("We only accept messages from locahost!\n");
+        }
+
+       if ( m_udp_sock->SendTo(m_udp_addr, reply, strlen(reply)).LastCount() != strlen(reply)) {
+           printf("ERROR: failed to send data\n");
+        }
+    }
+
+    return n;
+}
+
+void MainFrame::startUDPThread(void) {
+    fprintf(stderr, "starting UDP thread!\n");
+    m_UDPThread = new UDPThread;
+    m_UDPThread->mf = this;
+    if (m_UDPThread->Create() != wxTHREAD_NO_ERROR ) {
+        wxLogError(wxT("Can't create thread!"));
+    }
+    if (m_UDPThread->Run() != wxTHREAD_NO_ERROR ) {
+        wxLogError(wxT("Can't start thread!"));
+        delete m_UDPThread;
+    }
+}
+
+void MainFrame::stopUDPThread(void) {
+    printf("stopping UDP thread!\n");
+    if ((m_UDPThread != NULL) && m_UDPThread->m_run) {
+        m_UDPThread->m_run = 0;
+        m_UDPThread->Wait();
+        m_UDPThread = NULL;
+    }
+}
+
+void *UDPThread::Entry() {
+    printf("UDP thread started!\n");
+    while (m_run) {
+        if (wxGetApp().m_udp_enable) {
+            printf("m_udp_enable\n");
+            mf->m_udp_addr.Service(wxGetApp().m_udp_port);
+            mf->m_udp_sock = new wxDatagramSocket(mf->m_udp_addr, wxSOCKET_NOWAIT);
+
+            while (m_run && wxGetApp().m_udp_enable) {
+                if (mf->PollUDP() == 0) {
+                    wxThread::Sleep(20);
+                }
+            }
+
+            delete mf->m_udp_sock;
+        }
+        wxThread::Sleep(20);
+    }
+    return NULL;
+}
+
+#endif
+
+char my_get_next_tx_char(void *callback_state) {
+    short ch = 0;
+    
+    fifo_read(g_txDataInFifo, &ch, 1);
+    //fprintf(stderr, "get_next_tx_char: %c\n", (char)ch);
+    return (char)ch;
+}
+
+void my_put_next_rx_char(void *callback_state, char c) {
+    short ch = (short)c;
+    //fprintf(stderr, "put_next_rx_char: %c\n", (char)c);
+    fifo_write(g_rxDataOutFifo, &ch, 1);
+}
+
+// Callback from FreeDv API to update error plots
+
+void my_freedv_put_error_pattern(void *state, short error_pattern[], int sz_error_pattern) {
+    fifo_write(g_error_pattern_fifo, error_pattern, sz_error_pattern);
+    //fprintf(stderr, "my_freedv_put_error_pattern: sz_error_pattern: %d ret: %d used: %d\n", 
+    //        sz_error_pattern, ret, fifo_used(g_error_pattern_fifo) );
+}
+
+void freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, COMP *foff_phase_rect, int nin)
+{
+    COMP  foff_rect;
+    float mag;
+    int   i;
+
+    foff_rect.real = cosf(2.0*M_PI*foff/Fs);
+    foff_rect.imag = sinf(2.0*M_PI*foff/Fs);
+    for(i=0; i<nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
+    }
+
+    /* normalise digital oscilator as the magnitude can drift over time */
+
+    mag = cabsolute(*foff_phase_rect);
+    foff_phase_rect->real /= mag;       
+    foff_phase_rect->imag /= mag;       
+}
+
+int plugin_get_persistant(char name[], char value[]) {
+    wxString n,v;
+    int i;
+
+    for(i=0; i<wxGetApp().m_numPlugInParam; i++) {
+
+        n = wxGetApp().m_plugInParamName[i];
+
+        if (strcmp(n.mb_str().data(), name) == 0) {
+            v = wxGetApp().m_txtPlugInParam[i];
+            strcpy(value, v.mb_str().data());
+            fprintf(stderr, "plugin_get_persistant called name: %s value: %s\n", name, v.mb_str().data());
+        }
+    }
+
+    return 0;
+}
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_main.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_main.h
new file mode 100644 (file)
index 0000000..e074069
--- /dev/null
@@ -0,0 +1,681 @@
+//==========================================================================
+// Name:            fdmdv2_main.h
+//
+// Purpose:         Declares simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_MAIN__
+#define __FDMDV2_MAIN__
+
+#include "version.h"
+#ifndef _NO_AUTOTOOLS_
+#include "../config.h"
+#endif
+#include <wx/wx.h>
+
+#include <wx/tglbtn.h>
+#include <wx/app.h>
+#include "wx/rawbmp.h"
+#include "wx/file.h"
+#include "wx/filename.h"
+#include "wx/config.h"
+#include <wx/fileconf.h>
+#include "wx/graphics.h"
+#include "wx/mstream.h"
+#include "wx/wfstream.h"
+#include "wx/quantize.h"
+#include "wx/scopedptr.h"
+#include "wx/stopwatch.h"
+#include "wx/versioninfo.h"
+#include <wx/sound.h>
+#include <wx/url.h>
+#include <wx/sstream.h>
+#include <wx/listbox.h>
+#include <wx/textdlg.h>
+#include <wx/regex.h>
+#include <wx/socket.h>
+
+#include <samplerate.h>
+
+#include <stdint.h>
+#include <speex/speex_preprocess.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#endif
+
+#include "codec2.h"
+#include "codec2_fifo.h"
+#include "modem_stats.h"
+
+#include "topFrame.h"
+#include "dlg_ptt.h"
+#include "dlg_options.h"
+#include "fdmdv2_plot.h"
+#include "fdmdv2_plot_scalar.h"
+#include "fdmdv2_plot_scatter.h"
+#include "fdmdv2_plot_waterfall.h"
+#include "fdmdv2_plot_spectrum.h"
+#include "fdmdv2_pa_wrapper.h"
+#include "sndfile.h"
+#include "portaudio.h"
+#include "dlg_audiooptions.h"
+#include "dlg_filter.h"
+#include "dlg_options.h"
+#include "varicode.h"
+#include "sox_biquad.h"
+#include "comp_prim.h"
+#include "dlg_plugin.h"
+#include "hamlib.h"
+#include "serialport.h" 
+
+#define _USE_TIMER              1
+#define _USE_ONIDLE             1
+#define _DUMMY_DATA             1
+//#define _AUDIO_PASSTHROUGH    1
+#define _REFRESH_TIMER_PERIOD   (DT*1000)
+//#define _USE_ABOUT_DIALOG       1
+
+enum {
+        ID_START = wxID_HIGHEST,
+        ID_TIMER_WATERFALL,
+        ID_TIMER_SPECTRUM,
+        ID_TIMER_SCATTER,
+        ID_TIMER_SCALAR
+     };
+
+#define EXCHANGE_DATA_IN    0
+#define EXCHANGE_DATA_OUT   1
+
+
+extern int                 g_nSoundCards;
+extern int                 g_soundCard1InDeviceNum;
+extern int                 g_soundCard1OutDeviceNum;
+extern int                 g_soundCard1SampleRate;
+extern int                 g_soundCard2InDeviceNum;
+extern int                 g_soundCard2OutDeviceNum;
+extern int                 g_soundCard2SampleRate;
+
+// Voice Keyer Constants
+
+#define VK_SYNC_WAIT_TIME 5.0
+
+// Voice Keyer States
+
+#define VK_IDLE      0
+#define VK_TX        1
+#define VK_RX        2
+#define VK_SYNC_WAIT 3
+
+// Voice Keyer Events
+
+#define VK_START         0
+#define VK_SPACE_BAR     1
+#define VK_PLAY_FINISHED 2
+#define VK_DT            3
+#define VK_SYNC          4
+
+class MainFrame;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainApp
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MainApp : public wxApp
+{
+    public:
+        virtual bool        OnInit();
+        virtual int         OnExit();
+
+        wxString            m_strVendName;
+        wxString            m_StrAppName;
+
+        wxString            m_textNumChOut;
+        wxString            m_textNumChIn;
+
+        wxString            m_strRxInAudio;
+        wxString            m_strRxOutAudio;
+        wxString            m_textVoiceInput;
+        wxString            m_textVoiceOutput;
+        wxString            m_strSampleRate;
+        wxString            m_strBitrate;
+
+        // PTT -----------------------------------
+
+        bool                m_boolHalfDuplex;
+
+        wxString            m_txtVoiceKeyerWaveFilePath;
+        wxString            m_txtVoiceKeyerWaveFile;
+        int                 m_intVoiceKeyerRxPause;
+        int                 m_intVoiceKeyerRepeats;
+
+        bool                m_boolHamlibUseForPTT;
+        unsigned int        m_intHamlibRig;
+        wxString            m_strHamlibSerialPort;
+        unsigned int        m_intHamlibSerialRate;
+        Hamlib              *m_hamlib;
+
+        bool                m_boolUseSerialPTT;
+        wxString            m_strRigCtrlPort;
+        bool                m_boolUseRTS;
+        bool                m_boolRTSPos;
+        bool                m_boolUseDTR;
+        bool                m_boolDTRPos;
+        Serialport         *m_serialport;
+
+        // Play/Rec files
+
+        wxString            m_playFileToMicInPath;
+        wxString            m_recFileFromRadioPath;
+        unsigned int        m_recFileFromRadioSecs;
+        wxString            m_playFileFromRadioPath;
+
+        // Options dialog
+
+        wxString            m_callSign;
+        bool                m_events;
+        int                 m_events_spam_timer;
+        unsigned int        m_textEncoding;
+        bool                m_enable_checksum;
+        wxString            m_events_regexp_match;
+        wxString            m_events_regexp_replace;
+
+        bool                m_snrSlow;
+
+        // LPC Post Filter
+        bool                m_codec2LPCPostFilterEnable;
+        bool                m_codec2LPCPostFilterBassBoost;
+        float               m_codec2LPCPostFilterGamma;
+        float               m_codec2LPCPostFilterBeta;
+        
+        // Speex Pre-Processor
+        bool                m_speexpp_enable;
+
+        // Mic In Equaliser
+        float               m_MicInBassFreqHz;
+        float               m_MicInBassGaindB;
+        float               m_MicInTrebleFreqHz;
+        float               m_MicInTrebleGaindB;
+        float               m_MicInMidFreqHz;
+        float               m_MicInMidGaindB;
+        float               m_MicInMidQ;
+        bool                m_MicInEQEnable;
+
+        // Spk Out Equaliser
+        float               m_SpkOutBassFreqHz;
+        float               m_SpkOutBassGaindB;
+        float               m_SpkOutTrebleFreqHz;
+        float               m_SpkOutTrebleGaindB;
+        float               m_SpkOutMidFreqHz;
+        float               m_SpkOutMidGaindB;
+        float               m_SpkOutMidQ;
+        bool                m_SpkOutEQEnable;
+
+        // Flags for displaying windows
+        int                 m_show_wf;
+        int                 m_show_spect;
+        int                 m_show_scatter;
+        int                 m_show_timing;
+        int                 m_show_freq;
+        int                 m_show_speech_in;
+        int                 m_show_speech_out;
+        int                 m_show_demod_in;
+        int                 m_show_test_frame_errors;
+        int                 m_show_test_frame_errors_hist;
+
+        // optional vox trigger tone
+        bool                m_leftChannelVoxTone;
+
+        // UDP control port
+        bool                m_udp_enable;
+        int                 m_udp_port;
+
+        // notebook display after tx->rxtransition
+        int                 m_rxNbookCtrl;
+
+        wxRect              m_rTopWindow;
+
+        int                 m_framesPerBuffer;
+
+        bool                loadConfig();
+        bool                saveConfig();
+
+        // Plugins -----------------------------------
+
+        wxString            m_txtPlugInParam[PLUGIN_MAX_PARAMS];
+
+        // plugin details
+
+        void      *m_plugInHandle;
+        bool       m_plugIn;
+        wxString   m_plugInName;
+        int        m_numPlugInParam;
+        wxString   m_plugInParamName[PLUGIN_MAX_PARAMS];
+        void      *m_plugInStates;
+        void     (*m_plugin_startfp)(void *);
+        void     (*m_plugin_stopfp)(void *);
+        void     (*m_plugin_rx_samplesfp)(void *, short *, int);
+
+        // misc
+
+        bool       m_testFrames;
+        bool       m_channel_noise;
+        float      m_channel_snr_dB;
+
+        int        FilterEvent(wxEvent& event);
+        MainFrame *frame;
+
+        // 700 options
+
+        bool       m_FreeDV700txClip;
+        bool       m_FreeDV700Combine;
+
+        // Noise simulation
+
+        int        m_noise_snr;
+
+        // carrier attenuation
+
+        bool       m_attn_carrier_en;
+        int        m_attn_carrier;
+
+        // tone interferer simulation
+
+        bool       m_tone;
+        int        m_tone_freq_hz;
+        int        m_tone_amplitude;
+
+        // Windows debug console
+
+        bool       m_debug_console;
+    protected:
+};
+
+// declare global static function wxGetApp()
+DECLARE_APP(MainApp)
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// paCallBackData
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+typedef struct
+{
+    // libresample states for 48 to 8 kHz conversions
+
+    SRC_STATE      *insrc1;
+    SRC_STATE      *outsrc1;
+    SRC_STATE      *insrc2;
+    SRC_STATE      *outsrc2;
+    SRC_STATE      *insrcsf;
+
+    // FIFOs attached to first sound card
+
+    struct FIFO    *infifo1;
+    struct FIFO    *outfifo1;
+
+    // FIFOs attached to second sound card
+    struct FIFO    *infifo2;
+    struct FIFO    *outfifo2;
+
+    // FIFOs for rx process
+    struct FIFO    *rxinfifo;
+    struct FIFO    *rxoutfifo;
+
+    int             inputChannels1, inputChannels2;
+
+    // EQ filter states
+    void           *sbqMicInBass;
+    void           *sbqMicInTreble;
+    void           *sbqMicInMid;
+    void           *sbqSpkOutBass;
+    void           *sbqSpkOutTreble;
+    void           *sbqSpkOutMid;
+
+    bool            micInEQEnable;
+    bool            spkOutEQEnable;
+
+    // optional loud tone on left channel to reliably trigger vox
+    bool            leftChannelVoxTone;
+    float           voxTonePhase;
+
+} paCallBackData;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// panel with custom loop checkbox for play file dialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MyExtraPlayFilePanel : public wxPanel
+{
+public:
+    MyExtraPlayFilePanel(wxWindow *parent);
+    void setLoopPlayFileToMicIn(bool checked) { m_cb->SetValue(checked); }
+    bool getLoopPlayFileToMicIn(void) { return m_cb->GetValue(); }
+private:
+    wxCheckBox *m_cb;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// panel with custom Seconds-to-record control for record file dialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MyExtraRecFilePanel : public wxPanel
+{
+public:
+    MyExtraRecFilePanel(wxWindow *parent);
+    ~MyExtraRecFilePanel() 
+    {
+        wxLogDebug("Destructor\n");
+    }
+    void setSecondsToRecord(wxString value) { m_secondsToRecord->SetValue(value); }
+    wxString getSecondsToRecord(void) 
+    { 
+        wxLogDebug("getSecondsToRecord: %s\n",m_secondsToRecord->GetValue());
+        return m_secondsToRecord->GetValue(); 
+    }
+private:
+    wxTextCtrl *m_secondsToRecord;
+};
+
+class txRxThread;
+class UDPThread;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainFrame
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MainFrame : public TopFrame
+{
+    public:
+        MainFrame(wxString plugInName, wxWindow *parent);
+        virtual ~MainFrame();
+
+        PlotSpectrum*           m_panelSpectrum;
+        PlotWaterfall*          m_panelWaterfall;
+        PlotScatter*            m_panelScatter;
+        PlotScalar*             m_panelTimeOffset;
+        PlotScalar*             m_panelFreqOffset;
+        PlotScalar*             m_panelSpeechIn;
+        PlotScalar*             m_panelSpeechOut;
+        PlotScalar*             m_panelDemodIn;
+        PlotScalar*             m_panelTestFrameErrors;
+        PlotScalar*             m_panelTestFrameErrorsHist;
+
+        bool                    m_RxRunning;
+
+        PortAudioWrap           *m_rxInPa;
+        PortAudioWrap           *m_rxOutPa;
+        PortAudioWrap           *m_txInPa;
+        PortAudioWrap           *m_txOutPa;
+
+        PaError                 m_rxErr;
+        PaError                 m_txErr;
+        
+        txRxThread*             m_txRxThread;
+
+        bool                    OpenHamlibRig();
+        void                    OpenSerialPort(void);
+        void                    CloseSerialPort(void);
+        void                    SerialPTTRx(void);
+
+        bool                    m_modal;
+
+#ifdef _USE_TIMER
+        wxTimer                 m_plotTimer;
+#endif
+
+    void destroy_fifos(void);
+    void destroy_src(void);
+    void autoDetectSoundCards(PortAudioWrap *pa);
+
+        static int rxCallback(
+                                const void *inBuffer,
+                                void *outBuffer,
+                                unsigned long framesPerBuffer,
+                                const PaStreamCallbackTimeInfo *outTime,
+                                PaStreamCallbackFlags statusFlags,
+                                void *userData
+                             );
+        static int txCallback(
+                                const void *inBuffer,
+                                void *outBuffer,
+                                unsigned long framesPerBuffer,
+                                const PaStreamCallbackTimeInfo *outTime,
+                                PaStreamCallbackFlags statusFlags,
+                                void *userData
+                             );
+
+
+    void initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice, 
+                             int soundCard, int sampleRate, int inputChannels);
+
+    void togglePTT(void);
+
+    wxIPV4address           m_udp_addr;
+    wxDatagramSocket       *m_udp_sock;
+    UDPThread              *m_UDPThread;
+    void                    startUDPThread(void);
+    void                    stopUDPThread(void);
+    int                     PollUDP();
+    bool                    m_schedule_restore;
+
+    int                     vk_state;
+    void VoiceKeyerProcessEvent(int vk_event);
+
+    protected:
+
+        void setsnrBeta(bool snrSlow);
+
+        // protected event handlers
+        virtual void OnCloseFrame(wxCloseEvent& event);
+        void OnExitClick(wxCommandEvent& event);
+
+        void startTxStream();
+        void startRxStream();
+        void stopTxStream();
+        void stopRxStream();
+        void abortTxStream();
+        void abortRxStream();
+        
+        void OnTop(wxCommandEvent& event);
+        void OnExit( wxCommandEvent& event );
+
+        void OnToolsAudio( wxCommandEvent& event );
+        void OnToolsAudioUI( wxUpdateUIEvent& event );
+        void OnToolsComCfg( wxCommandEvent& event );
+        void OnToolsComCfgUI( wxUpdateUIEvent& event );
+        void OnToolsFilter( wxCommandEvent& event );
+        void OnToolsOptions(wxCommandEvent& event);
+        void OnToolsOptionsUI(wxUpdateUIEvent& event);
+
+        void OnToolsPlugInCfg( wxCommandEvent& event );
+        void OnToolsPlugInCfgUI( wxUpdateUIEvent& event );
+
+        void OnPlayFileToMicIn( wxCommandEvent& event );
+        void StopPlayFileToMicIn(void);
+        void OnRecFileFromRadio( wxCommandEvent& event );
+        void OnPlayFileFromRadio( wxCommandEvent& event );
+
+        void OnHelpCheckUpdates( wxCommandEvent& event );
+        void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event );
+        void OnHelpAbout( wxCommandEvent& event );
+        void OnCmdSliderScroll( wxScrollEvent& event );
+//        void OnSliderScrollBottom( wxScrollEvent& event );
+//        void OnCmdSliderScrollChanged( wxScrollEvent& event );
+//        void OnSliderScrollTop( wxScrollEvent& event );
+        void OnCheckSQClick( wxCommandEvent& event );
+        void OnCheckSNRClick( wxCommandEvent& event );
+
+        // Toggle Buttons
+        void OnTogBtnSplitClick(wxCommandEvent& event);
+        void OnTogBtnAnalogClick(wxCommandEvent& event);
+        void OnTogBtnRxID( wxCommandEvent& event );
+        void OnTogBtnTxID( wxCommandEvent& event );
+        void OnTogBtnPTT( wxCommandEvent& event );
+        void OnTogBtnVoiceKeyerClick (wxCommandEvent& event);
+        void OnTogBtnOnOff( wxCommandEvent& event );
+
+        void OnCallSignReset( wxCommandEvent& event );
+        void OnBerReset( wxCommandEvent& event );
+
+        //System Events
+        void OnPaint(wxPaintEvent& event);
+        void OnSize( wxSizeEvent& event );
+        void OnUpdateUI( wxUpdateUIEvent& event );
+        void OnDeleteConfig(wxCommandEvent&);
+#ifdef _USE_TIMER
+        void OnTimer(wxTimerEvent &evt);
+#endif
+#ifdef _USE_ONIDLE
+        void OnIdle(wxIdleEvent &evt);
+#endif
+
+        int VoiceKeyerStartTx(void);
+
+    private:
+        bool        m_useMemory;
+        wxTextCtrl* m_tc;
+        int         m_zoom;
+        float       m_snrBeta;
+        
+        // Callsign/text messaging
+        char        m_callsign[MAX_CALLSIGN];
+        char       *m_pcallsign;
+        unsigned int m_checksumGood;
+        unsigned int m_checksumBad;
+        
+        // Events
+        void        processTxtEvent(char event[]);
+        class OptionsDlg *optionsDlg;
+        wxTimer     spamTimer[MAX_EVENT_RULES];
+
+        // level Gauge
+        float       m_maxLevel;
+        // flags to indicate when new EQ filters need to be designed
+
+        bool        m_newMicInFilter;
+        bool        m_newSpkOutFilter;
+
+        void*       designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q = 0.0);
+        void        designEQFilters(paCallBackData *cb);
+        void        deleteEQFilters(paCallBackData *cb);
+
+        // Voice Keyer States
+
+        int        vk_rx_pause;
+        int        vk_repeats, vk_repeat_counter;
+        float      vk_rx_time;
+};
+
+void txRxProcessing();
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class txRxThread - experimental tx/rx processing thread
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class txRxThread : public wxThread
+{
+public:
+    txRxThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
+
+    // thread execution starts here
+    void *Entry() 
+    {
+        while (m_run) 
+        {
+            txRxProcessing();        
+            wxThread::Sleep(20);
+        }
+        return NULL;
+    }
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    void OnExit() { }
+
+public:
+    bool  m_run;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class UDPThread - waits for UDP messages
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class UDPThread : public wxThread
+{
+public:
+    UDPThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
+
+    // thread execution starts here
+    void *Entry();
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    void OnExit() { }
+
+public:
+    MainFrame              *mf;
+    bool                    m_run;
+};
+
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length, int fs);
+
+int resample(SRC_STATE *src,
+             short      output_short[],
+             short      input_short[],
+             int        output_sample_rate,
+             int        input_sample_rate,
+             int        length_output_short, // maximum output array length in samples
+             int        length_input_short
+             );
+void txRxProcessing();
+void per_frame_rx_processing(
+                                        FIFO    *output_fifo,   // decoded speech samples
+                                        FIFO    *input_fifo     // modem samples input to demod
+                                    );
+
+// FreeDv API calls this when there is a test frame that needs a-plottin'
+
+void my_freedv_put_error_pattern(void *state, short error_pattern[], int sz_error_pattern);
+
+// FreeDv API calls these puppies when it needs/receives a text char 
+
+char my_get_next_tx_char(void *callback_state);
+void my_put_next_rx_char(void *callback_state, char c);
+
+// helper complex freq shift function
+
+void freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, COMP *foff_phase_rect, int nin);
+
+// Helper function called by plugin
+
+int plugin_get_persistant(char name[], char value[]);
+
+#endif //__FDMDV2_MAIN__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_pa_wrapper.cpp b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_pa_wrapper.cpp
new file mode 100644 (file)
index 0000000..2f67ca2
--- /dev/null
@@ -0,0 +1,324 @@
+//==========================================================================
+// Name:            fdmdv2_pa_wrapper.cpp
+// Purpose:         Implements a wrapper class around the PortAudio library.
+// Created:         August 12, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "fdmdv2_pa_wrapper.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// PortAudioWrap()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PortAudioWrap::PortAudioWrap()
+{
+    m_pStream                   = NULL;
+    m_pUserData                 = NULL;
+    m_samplerate                = 0;
+    m_framesPerBuffer           = 0;
+    m_statusFlags               = 0;
+    m_pStreamCallback           = NULL;
+    m_pStreamFinishedCallback   = NULL;
+    m_pTimeInfo                 = 0;
+    m_newdata                   = false;
+
+//    loadData();
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// ~PortAudioWrap()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PortAudioWrap::~PortAudioWrap()
+{
+}
+
+//----------------------------------------------------------------
+// streamOpen()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamOpen()
+{
+    return Pa_OpenStream(
+                            &m_pStream,
+                            m_inputBuffer.device == paNoDevice ? NULL : &m_inputBuffer,
+                            m_outputBuffer.device == paNoDevice ? NULL : &m_outputBuffer,
+                            m_samplerate,
+                            m_framesPerBuffer,
+                            m_statusFlags,
+                            *m_pStreamCallback,
+                            m_pUserData
+                        );
+}
+
+//----------------------------------------------------------------
+// streamStart()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamStart()
+{
+    return Pa_StartStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// streamClose()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamClose()
+{
+    if(isOpen())
+    {
+        PaError rv = Pa_CloseStream(m_pStream);
+        return rv;
+    }
+    else
+    {
+        return paNoError;
+    }
+}
+
+//----------------------------------------------------------------
+// terminate()
+//----------------------------------------------------------------
+void PortAudioWrap::terminate()
+{
+    if(Pa_IsStreamStopped(m_pStream) != paNoError)
+    {
+        Pa_StopStream(m_pStream);
+    }
+    Pa_Terminate();
+}
+
+//----------------------------------------------------------------
+// stop()
+//----------------------------------------------------------------
+void PortAudioWrap::stop()
+{
+    Pa_StopStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// abort()
+//----------------------------------------------------------------
+void PortAudioWrap::abort()
+{
+    Pa_AbortStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// isStopped()
+//----------------------------------------------------------------
+bool PortAudioWrap::isStopped() const
+{
+    PaError ret = Pa_IsStreamStopped(m_pStream);
+    return ret;
+}
+
+//----------------------------------------------------------------
+// isActive()
+//----------------------------------------------------------------
+bool PortAudioWrap::isActive() const
+{
+    PaError ret = Pa_IsStreamActive(m_pStream);
+    return ret;
+}
+
+//----------------------------------------------------------------
+// isOpen()
+//----------------------------------------------------------------
+bool PortAudioWrap::isOpen() const
+{
+    return (m_pStream != NULL);
+}
+
+//----------------------------------------------------------------
+// getDefaultInputDevice()
+//----------------------------------------------------------------
+PaDeviceIndex PortAudioWrap::getDefaultInputDevice()
+{
+    return Pa_GetDefaultInputDevice();
+}
+
+//----------------------------------------------------------------
+// getDefaultOutputDevice()
+//----------------------------------------------------------------
+PaDeviceIndex PortAudioWrap::getDefaultOutputDevice()
+{
+    return Pa_GetDefaultOutputDevice();
+}
+
+//----------------------------------------------------------------
+// setInputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputChannelCount(int count)
+{
+    m_inputBuffer.channelCount = count;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// getInputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::getInputChannelCount()
+{
+    return m_inputBuffer.channelCount;
+}
+
+//----------------------------------------------------------------
+// setInputSampleFormat()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputSampleFormat(PaSampleFormat format)
+{
+    m_inputBuffer.sampleFormat = format;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputLatency()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputLatency(PaTime latency)
+{
+    m_inputBuffer.suggestedLatency = latency;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputHostApiStreamInfo()
+//----------------------------------------------------------------
+void PortAudioWrap::setInputHostApiStreamInfo(void *info)
+{
+    m_inputBuffer.hostApiSpecificStreamInfo = info;
+}
+
+//----------------------------------------------------------------
+// getInputDefaultLowLatency()
+//----------------------------------------------------------------
+PaTime  PortAudioWrap::getInputDefaultLowLatency()
+{
+    return Pa_GetDeviceInfo(m_inputBuffer.device)->defaultLowInputLatency;
+}
+
+//----------------------------------------------------------------
+// setOutputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputChannelCount(int count)
+{
+    m_outputBuffer.channelCount = count;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// getOutputChannelCount()
+//----------------------------------------------------------------
+const int PortAudioWrap::getOutputChannelCount()
+{
+    return m_outputBuffer.channelCount;
+}
+
+//----------------------------------------------------------------
+// getDeviceName()
+//----------------------------------------------------------------
+const char *PortAudioWrap::getDeviceName(PaDeviceIndex dev)
+{
+    const PaDeviceInfo *info;
+    info = Pa_GetDeviceInfo(dev);
+    return info->name;
+}
+
+//----------------------------------------------------------------
+// setOutputSampleFormat()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputSampleFormat(PaSampleFormat format)
+{
+    m_outputBuffer.sampleFormat = format;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputLatency()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputLatency(PaTime latency)
+{
+    m_outputBuffer.suggestedLatency = latency;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputHostApiStreamInfo()
+//----------------------------------------------------------------
+void PortAudioWrap::setOutputHostApiStreamInfo(void *info)
+{
+    m_outputBuffer.hostApiSpecificStreamInfo = info;
+}
+
+//----------------------------------------------------------------
+// getOutputDefaultLowLatency()
+//----------------------------------------------------------------
+PaTime  PortAudioWrap::getOutputDefaultLowLatency()
+{
+    return Pa_GetDeviceInfo(m_outputBuffer.device)->defaultLowOutputLatency;
+}
+
+//----------------------------------------------------------------
+// setFramesPerBuffer()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setFramesPerBuffer(unsigned long size)
+{
+    m_framesPerBuffer = size;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setSampleRate()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setSampleRate(unsigned long rate)
+{
+    m_samplerate = rate;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setStreamFlags()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setStreamFlags(PaStreamFlags flags)
+{
+    m_statusFlags = flags;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputDevice()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputDevice(PaDeviceIndex index)
+{
+    m_inputBuffer.device = index;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputDevice()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputDevice(PaDeviceIndex index)
+{
+    m_outputBuffer.device = index;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setCallback()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setCallback(PaStreamCallback *callback)
+{
+    m_pStreamCallback = callback;
+    return paNoError;
+}
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_pa_wrapper.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_pa_wrapper.h
new file mode 100644 (file)
index 0000000..3d216c0
--- /dev/null
@@ -0,0 +1,115 @@
+//==========================================================================
+// Name:            fdmdv2_pa_wrapper.h
+// Purpose:         Defines a wrapper class around PortAudio
+// Created:         August 12, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <stdio.h>
+#include <math.h>
+#include "fdmdv2_defines.h"
+#include "codec2_fdmdv.h"
+#include "codec2.h"
+#include "portaudio.h"
+
+#define PA_SAMPLE_TYPE      paInt16         //paFloat32
+#define FRAMES_PER_BUFFER   (64)
+
+typedef float SAMPLE;
+
+class PortAudioWrap
+{
+    public:
+        PortAudioWrap();
+        ~PortAudioWrap();
+
+//        float                           m_av_mag[FDMDV_NSPEC];
+
+    private:
+        PaStream                        *m_pStream;
+        void                            *m_pUserData;
+        PaStreamCallback                *m_pStreamCallback;
+        PaStreamFinishedCallback        *m_pStreamFinishedCallback;
+        const PaStreamCallbackTimeInfo  *m_pTimeInfo;
+        struct FDMDV                    *m_pFDMDV_state;
+        PaStreamParameters              m_inputBuffer;
+        PaStreamParameters              m_outputBuffer;
+        int                             m_samplerate;
+        unsigned long                   m_framesPerBuffer;
+        PaStreamCallbackFlags           m_statusFlags;
+        bool                            m_newdata;
+
+    public:
+
+        void                averageData(float mag_dB[]);
+
+        int                 getDeviceCount() { return Pa_GetDeviceCount(); }
+        PaDeviceIndex       getDefaultInputDevice();
+        PaDeviceIndex       getDefaultOutputDevice();
+        PaStreamParameters  *getDeviceInfo(PaDeviceIndex idx);
+
+        PaError             setFramesPerBuffer(unsigned long size);
+        PaError             setSampleRate(unsigned long size);
+
+        PaError             setStreamFlags(PaStreamFlags flags);
+        PaError             setCallback(PaStreamCallback *m_pStreamCallback);
+        PaError             setStreamCallback(PaStream *stream, PaStreamCallback* callback) { m_pStreamCallback = callback; return 0;}
+        PaError             setStreamFinishedCallback(PaStream *stream, PaStreamFinishedCallback* m_pStreamFinishedCallback);
+
+        void                setInputBuffer(const PaStreamParameters& inputBuffer)   {this->m_inputBuffer = inputBuffer;}
+        PaError             setInputDevice(PaDeviceIndex dev);
+        PaError             setInputChannelCount(int count);
+        int                 getInputChannelCount();
+        PaError             setInputSampleFormat(PaSampleFormat format);
+        PaError             setInputSampleRate(PaSampleFormat format);
+        PaError             setInputLatency(PaTime latency);
+        void                setInputHostApiStreamInfo(void *info = NULL);
+        PaTime              getInputDefaultLowLatency();
+        const char          *getDeviceName(PaDeviceIndex dev);
+
+        PaError             setOutputDevice(PaDeviceIndex dev);
+        PaError             setOutputChannelCount(int count);
+        const int           getOutputChannelCount();
+        PaError             setOutputSampleFormat(PaSampleFormat format);
+        PaError             setOutputLatency(PaTime latency);
+        void                setOutputHostApiStreamInfo(void *info = NULL);
+        PaTime              getOutputDefaultLowLatency();
+
+        void                setFdmdvState(FDMDV* fdmdv_state)                       {this->m_pFDMDV_state = fdmdv_state;}
+        void                setOutputBuffer(const PaStreamParameters& outputBuffer) {this->m_outputBuffer = outputBuffer;}
+        void                setTimeInfo(PaStreamCallbackTimeInfo* timeInfo)         {this->m_pTimeInfo = timeInfo;}
+        void                setUserData(void* userData)                             {this->m_pUserData = userData;}
+        unsigned long       getFramesPerBuffer() const                              {return m_framesPerBuffer;}
+        const               PaStreamParameters& getInputBuffer() const              {return m_inputBuffer;}
+        const               PaStreamParameters& getOutputBuffer() const             {return m_outputBuffer;}
+        const               PaStreamCallbackFlags& getStatusFlags() const           {return m_statusFlags;}
+
+        FDMDV*              getFdmdvState()                                         {return m_pFDMDV_state;}
+        int                 getSamplerate() const                                   {return m_samplerate;}
+        PaStream*           getStream()                                             {return m_pStream;}
+        void                *getUserData()                                          {return m_pUserData;}
+        bool                getDataAvail()                                          {return m_newdata;}
+        PaError             streamStart();
+        PaError             streamClose();
+        PaError             streamOpen();
+        void                terminate();
+        void                stop();
+        void                abort();
+        bool                isOpen() const;
+        bool                isStopped() const;
+        bool                isActive() const;
+//        void                loadData();
+};
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot.cpp b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot.cpp
new file mode 100644 (file)
index 0000000..1b85cd9
--- /dev/null
@@ -0,0 +1,283 @@
+//==========================================================================
+// Name:            fdmdv2_plot.cpp
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "fdmdv2_plot.h"
+
+BEGIN_EVENT_TABLE(PlotPanel, wxPanel)
+    EVT_PAINT           (PlotPanel::OnPaint)
+    EVT_MOTION          (PlotPanel::OnMouseMove)
+    EVT_LEFT_DOWN       (PlotPanel::OnMouseLeftDown)
+    EVT_LEFT_UP         (PlotPanel::OnMouseLeftUp)
+    EVT_RIGHT_DOWN      (PlotPanel::OnMouseRightDown)
+    EVT_MOUSEWHEEL      (PlotPanel::OnMouseWheelMoved)
+    EVT_SIZE            (PlotPanel::OnSize)
+    EVT_SHOW            (PlotPanel::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotPanel(wxFrame* parent) : wxPanel(parent)
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotPanel::PlotPanel(wxFrame* parent) : wxPanel(parent)
+{
+    m_pNoteBook         = (wxAuiNotebook *) parent;
+    m_pTopFrame         = (MainFrame *)m_pNoteBook->GetParent();
+    m_zoomFactor        = 1.0;
+    m_pBmp              = NULL;
+    m_pPix              = NULL;
+    m_firstPass         = true;
+    m_line_color        = 0;
+    m_newdata           = false;
+    m_clip              = false;
+    m_use_bitmap        = true;
+    m_rubberBand        = false;
+    m_mouseDown         = false;
+    m_penShortDash      = wxPen(wxColor(0xA0, 0xA0, 0xA0), 1, wxPENSTYLE_SHORT_DASH);
+    m_penDotDash        = wxPen(wxColor(0xD0, 0xD0, 0xD0), 1, wxPENSTYLE_DOT_DASH);
+    m_penSolid          = wxPen(wxColor(0x00, 0x00, 0x00), 1, wxPENSTYLE_SOLID);
+    SetBackgroundStyle(wxBG_STYLE_PAINT);
+    SetLabelSize(10.0);
+}
+
+//-------------------------------------------------------------------------
+// ~PlotPanel()
+//-------------------------------------------------------------------------
+PlotPanel::~PlotPanel()
+{
+    if(m_pBmp != NULL)
+    {
+        delete m_pBmp;
+    }
+}
+
+//-------------------------------------------------------------------------
+// GetLabelSize()
+//-------------------------------------------------------------------------
+double PlotPanel::GetLabelSize()
+{
+    return m_label_size;
+}
+
+//-------------------------------------------------------------------------
+// SetLabelSize()
+//-------------------------------------------------------------------------
+void PlotPanel::SetLabelSize(double size)
+{
+    m_label_size = size;
+}
+
+//-------------------------------------------------------------------------
+// OnShow()
+//-------------------------------------------------------------------------
+void PlotPanel::OnShow(wxShowEvent& event)
+{
+    this->Refresh();
+}
+
+//-------------------------------------------------------------------------
+// OnErase()
+//-------------------------------------------------------------------------
+void PlotPanel::OnErase(wxEraseEvent& event)
+{
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnSize()
+//-------------------------------------------------------------------------
+void PlotPanel::OnSize(wxSizeEvent& event)
+{
+    m_rCtrlPrev = m_rCtrl;
+    m_rCtrl     = GetClientRect();
+    if(m_use_bitmap)
+    {
+        if(!m_oImage.IsOk())
+        {
+            m_oImage.Create(m_rCtrl.GetWidth(), m_rCtrl.GetHeight(), true);
+        }
+        else
+        {
+            m_oImage.Rescale(m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
+        }
+        m_pBmp = new wxBitmap(m_oImage, wxBITMAP_SCREEN_DEPTH);
+        m_firstPass = true;
+    }
+    this->Refresh();
+}
+
+//-------------------------------------------------------------------------
+// OnMouseMove()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseMove(wxMouseEvent& event)
+{
+//    if(m_mouseDown)
+//    {
+//        paintNow();
+//    }
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftDown()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseLeftDown(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseRightDown(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseWheelMoved()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseWheelMoved(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftUp()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseLeftUp(wxMouseEvent& event)
+{
+    m_mouseDown = false;
+}
+
+//-------------------------------------------------------------------------
+// SetZoomFactor()
+//-------------------------------------------------------------------------
+double PlotPanel::SetZoomFactor(double zf)
+{
+    if((zf > 0) && (zf < 5.0))
+    {
+        m_zoomFactor = zf;
+    }
+    return zf;
+}
+
+//-------------------------------------------------------------------------
+// GetZoomFactor()
+//-------------------------------------------------------------------------
+double PlotPanel::GetZoomFactor(double zf)
+{
+    return m_zoomFactor;
+}
+
+//-------------------------------------------------------------------------
+// draw()
+//-------------------------------------------------------------------------
+void PlotPanel::draw(wxAutoBufferedPaintDC& pDC)
+{
+    printf("PlotPanel::draw()");
+    wxMemoryDC m_mDC;
+    m_mDC.SelectObject(*m_pBmp);
+    m_rCtrl  = GetClientRect();
+    m_rGrid  = m_rCtrl;
+
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+    m_rGrid.Offset(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
+
+    pDC.Clear();
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    if(m_firstPass)
+    {
+        m_firstPass = false;
+        m_mDC.FloodFill(0, 0, VERY_LTGREY_COLOR);
+
+        // Draw a filled rectangle with aborder
+        wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR);
+        m_mDC.SetBrush(ltGraphBkgBrush);
+        m_mDC.SetPen(wxPen(BLACK_COLOR, 0));
+        m_mDC.DrawRectangle(m_rPlot);
+    }
+    if(m_newdata)
+    {
+        m_newdata = false;
+        int t = m_rPlot.GetTop();
+        int l = m_rPlot.GetLeft();
+//        int r = m_rPlot.GetRight();
+        int h = m_rPlot.GetHeight();
+        int w = m_rPlot.GetWidth();
+        pDC.Blit(l, t, w, h, &m_mDC, l, t);
+    }
+    drawGraticule(pDC);
+    m_mDC.SetBrush(wxNullBrush);
+    m_mDC.SelectObject(wxNullBitmap);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotPanel::drawGraticule(wxAutoBufferedPaintDC& pDC)
+{
+    int p;
+    char buf[15];
+    wxString s;
+
+    // Vertical gridlines
+    pDC.SetPen(m_penShortDash);
+    for(p = (PLOT_BORDER + XLEFT_OFFSET + GRID_INCREMENT); p < ((m_rGrid.GetWidth() - XLEFT_OFFSET) + GRID_INCREMENT); p += GRID_INCREMENT)
+    {
+        pDC.DrawLine(p, (m_rGrid.GetHeight() + PLOT_BORDER), p, PLOT_BORDER);
+    }
+    // Horizontal gridlines
+    pDC.SetPen(m_penDotDash);
+    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
+    {
+        pDC.DrawLine(PLOT_BORDER + XLEFT_OFFSET, (p + PLOT_BORDER), (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), (p + PLOT_BORDER));
+    }
+    // Label the X-Axis
+    pDC.SetPen(wxPen(GREY_COLOR, 1));
+    for(p = GRID_INCREMENT; p < (m_rGrid.GetWidth() - YBOTTOM_OFFSET); p += GRID_INCREMENT)
+    {
+        sprintf(buf, "%1.1f Hz",(double)(p / 10));
+        pDC.DrawText(buf, p - PLOT_BORDER + XLEFT_OFFSET, m_rGrid.GetHeight() + YBOTTOM_OFFSET/2);
+    }
+    // Label the Y-Axis
+    //for(p = GRID_INCREMENT; p < (h - YBOTTOM_OFFSET); p += GRID_INCREMENT)
+    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
+    {
+        sprintf(buf, "%1.0f", (double)((m_rGrid.GetHeight() - p) * -10));
+        pDC.DrawText(buf, XLEFT_TEXT_OFFSET, p);
+    }
+}
+
+//-------------------------------------------------------------------------
+// paintEvent()
+//
+// Called by the system of by wxWidgets when the panel needs
+// to be redrawn. You can also trigger this call by calling
+// Refresh()/Update().
+//-------------------------------------------------------------------------
+void PlotPanel::OnPaint(wxPaintEvent & evt)
+{
+    wxAutoBufferedPaintDC pdc(this);
+    draw(pdc);
+}
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot.h
new file mode 100644 (file)
index 0000000..25309d3
--- /dev/null
@@ -0,0 +1,150 @@
+//==========================================================================
+// Name:            fdmdv2_plot.h
+// Purpose:         Declares simple wxWidgets application with GUI
+// Created:         Apr. 10, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+//#include "fdmdv2_main.h"
+#ifndef __FDMDV2_PLOT__
+#define __FDMDV2_PLOT__
+#include <wx/wx.h>
+#include <wx/aui/auibook.h>
+#include <wx/rawbmp.h>
+#include <wx/image.h>
+#include <wx/dcbuffer.h>
+
+#define MAX_ZOOM            7
+#define MAX_BMP_X           (400 * MAX_ZOOM)
+#define MAX_BMP_Y           (400 * MAX_ZOOM)
+#define DATA_LINE_HEIGHT    10
+#define TEXT_BASELINE_OFFSET_Y  -5
+
+
+#define wxUSE_FILEDLG       1
+#define wxUSE_LIBPNG        1
+#define wxUSE_LIBJPEG       1
+#define wxUSE_GIF           1
+#define wxUSE_PCX           1
+#define wxUSE_LIBTIFF       1
+
+#define PLOT_BORDER         12
+#define XLEFT_OFFSET        40
+#define XLEFT_TEXT_OFFSET   6
+#define YBOTTOM_OFFSET      20
+#define YBOTTOM_TEXT_OFFSET 15
+#define GRID_INCREMENT      50
+
+#define BLACK_COLOR         wxColor(0x00, 0x00, 0x00)
+#define GREY_COLOR          wxColor(0x80, 0x80, 0x80)
+#define DARK_GREY_COLOR     wxColor(0x40, 0x40, 0x40)
+#define MEDIUM_GREY_COLOR   wxColor(0xC0, 0xC0, 0xC0)
+#define LIGHT_GREY_COLOR    wxColor(0xE0, 0xE0, 0xE0)
+#define VERY_LTGREY_COLOR   wxColor(0xF8, 0xF8, 0xF8)
+#define WHITE_COLOR         wxColor(0xFF, 0xFF, 0xFF)
+
+#define DARK_BLUE_COLOR     wxColor(0x00, 0x00, 0x60)
+#define BLUE_COLOR          wxColor(0x00, 0x00, 0xFF)
+#define LIGHT_BLUE_COLOR    wxColor(0x80, 0x80, 0xFF)
+
+#define RED_COLOR           wxColor(0xFF, 0x5E, 0x5E)
+#define LIGHT_RED_COLOR     wxColor(0xFF, 0xE0, 0xE0)
+#define DARK_RED_COLOR      wxColor(0xFF, 0x00, 0x00)
+#define PINK_COLOR          wxColor(0xFF, 0x80, 0xFF)
+
+#define LIGHT_GREEN_COLOR   wxColor(0xE3, 0xFF, 0xE0)
+#define GREEN_COLOR         wxColor(0x95, 0xFF, 0x8A)
+#define DARK_GREEN_COLOR    wxColor(0x20, 0xFF, 0x08)
+#define VERY_GREEN_COLOR    wxColor(0x00, 0xFF, 0x00)
+
+#define YELLOW_COLOR        wxColor(0xFF, 0xFF, 0x5E)
+#define LIGHT_YELLOW_COLOR  wxColor(0xFF, 0xFF, 0xB5)
+#define DARK_YELLOW_COLOR   wxColor(0xFF, 0xFF, 0x08)
+
+class MainFrame;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotPanel
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotPanel : public wxPanel
+{
+    public:
+        PlotPanel(wxFrame* parent);
+        ~PlotPanel();
+        wxPen               m_penShortDash;
+        wxPen               m_penDotDash;
+        wxPen               m_penSolid;
+        wxRect              m_rCtrlPrev;
+        wxRect              m_rCtrl;
+        wxRect              m_rGrid;
+        wxRect              m_rPlot;
+        MainFrame           *m_pTopFrame;
+        wxAuiNotebook       *m_pNoteBook;
+        double              m_label_size;
+        wxSize              m_Bufsz;
+        bool                m_newdata;
+        wxImage             m_oImage;
+        wxBitmap            *m_pBmp;
+        wxNativePixelData   *m_pPix;
+
+        // some useful events
+        void            OnMouseMove(wxMouseEvent& event);
+        virtual void    OnMouseLeftDown(wxMouseEvent& event);
+        void            OnMouseLeftUp(wxMouseEvent& event);
+        virtual void    OnMouseRightDown(wxMouseEvent& event);
+        void            OnMouseWheelMoved(wxMouseEvent& event);
+        void            OnClose(wxCloseEvent& event ){ event.Skip(); }
+        void            OnSize( wxSizeEvent& event );
+        void            OnErase(wxEraseEvent& event);
+        void            OnPaint(wxPaintEvent& event);
+        //void OnUpdateUI( wxUpdateUIEvent& event ){ event.Skip(); }
+
+        void            paintEvent(wxPaintEvent & evt);
+        virtual void    draw(wxAutoBufferedPaintDC&  pdc);
+        virtual void    drawGraticule(wxAutoBufferedPaintDC&  pdc);
+        virtual double  SetZoomFactor(double zf);
+        virtual double  GetZoomFactor(double zf);
+        virtual void    OnShow(wxShowEvent& event);
+        virtual double  GetLabelSize();
+        virtual void    SetLabelSize(double size);
+
+    protected:
+        int             m_x;
+        int             m_y;
+        int             m_left;
+        int             m_top;
+        int             m_prev_w;
+        int             m_prev_h;
+        int             m_prev_x;
+        int             m_prev_y;
+        bool            m_use_bitmap;
+        bool            m_clip;
+        bool            m_rubberBand;
+        bool            m_mouseDown;
+        bool            m_firstPass;
+        double          m_zoomFactor;
+        int             m_greyscale;
+        int             m_line_color;
+    DECLARE_EVENT_TABLE()
+};
+#endif //__FDMDV2_PLOT__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scalar.cpp b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scalar.cpp
new file mode 100644 (file)
index 0000000..9a794f5
--- /dev/null
@@ -0,0 +1,344 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scalar.cpp
+// Purpose:         Plots scalar amplitude against time
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_main.h"
+#include "fdmdv2_plot_scalar.h"
+
+BEGIN_EVENT_TABLE(PlotScalar, PlotPanel)
+    EVT_PAINT           (PlotScalar::OnPaint)
+    EVT_MOTION          (PlotScalar::OnMouseMove)
+    EVT_MOUSEWHEEL      (PlotScalar::OnMouseWheelMoved)
+    EVT_SIZE            (PlotScalar::OnSize)
+    EVT_SHOW            (PlotScalar::OnShow)
+//    EVT_ERASE_BACKGROUND(PlotScalar::OnErase)
+END_EVENT_TABLE()
+
+//----------------------------------------------------------------
+// PlotScalar()
+//----------------------------------------------------------------
+PlotScalar::PlotScalar(wxFrame* parent, 
+                       int    channels,           // number on channels to plot
+                      float  t_secs,             // time covered by entire x axis in seconds
+                      float  sample_period_secs, // time between each sample in seconds
+                      float  a_min,              // min ampltude of samples being plotted
+                      float  a_max,              // max ampltude of samples being plotted
+                      float  graticule_t_step,   // time step of x (time) axis graticule in seconds
+                      float  graticule_a_step,   // step of amplitude axis graticule
+                      const char a_fmt[],        // printf format string for amplitude axis labels
+                       int    mini                // true for mini-plot - don't draw graticule
+                      ): PlotPanel(parent)
+{
+    int i;
+
+    m_rCtrl = GetClientRect();
+
+    m_channels = channels;
+    m_t_secs = t_secs;
+    m_sample_period_secs = sample_period_secs;
+    m_a_min = a_min;
+    m_a_max = a_max;
+    m_graticule_t_step = graticule_t_step;
+    m_graticule_a_step = graticule_a_step;
+    assert(strlen(a_fmt) < 15);
+    strcpy(m_a_fmt, a_fmt);
+    m_mini = mini;
+    m_bar_graph = 0;
+    m_logy = 0;
+
+    // work out number of samples we will store and allocate storage
+
+    m_samples = m_t_secs/m_sample_period_secs;
+    m_mem = new float[m_samples*m_channels];
+
+    for(i = 0; i < m_samples*m_channels; i++)
+    {
+        m_mem[i] = 0.0;
+    }
+}
+
+//----------------------------------------------------------------
+// ~PlotScalar()
+//----------------------------------------------------------------
+PlotScalar::~PlotScalar()
+{
+    delete m_mem;
+}
+
+//----------------------------------------------------------------
+// add_new_sample()
+//----------------------------------------------------------------
+void PlotScalar::add_new_sample(int channel, float sample)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+    for(i = 0; i < m_samples-1; i++)
+    {
+        m_mem[offset+i] = m_mem[offset+i+1];
+    }
+    m_mem[offset+m_samples-1] = sample;
+}
+
+//----------------------------------------------------------------
+// add_new_samples()
+//----------------------------------------------------------------
+void  PlotScalar::add_new_samples(int channel, float samples[], int length)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+   for(i = 0; i < m_samples-length; i++)
+        m_mem[offset+i] = m_mem[offset+i+length];
+    for(; i < m_samples; i++)
+       m_mem[offset+i] = *samples++;
+}
+
+//----------------------------------------------------------------
+// add_new_short_samples()
+//----------------------------------------------------------------
+void  PlotScalar::add_new_short_samples(int channel, short samples[], int length, float scale_factor)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+    for(i = 0; i < m_samples-length; i++)
+        m_mem[offset+i] = m_mem[offset+i+length];
+    for(; i < m_samples; i++)
+       m_mem[offset+i] = (float)*samples++/scale_factor;
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotScalar::draw(wxAutoBufferedPaintDC&  dc)
+{
+    float index_to_px;
+    float a_to_py;
+    int   i;
+    int   prev_x, prev_y;
+    float a;
+
+    m_rCtrl = GetClientRect();
+    m_rGrid = m_rCtrl;
+    if (!m_mini)
+        m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    //printf("h %d w %d\n", m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
+    //printf("h %d w %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
+
+    // black background
+
+    dc.Clear();
+    if (m_mini)
+        m_rPlot = wxRect(0, 0, m_rGrid.GetWidth(), m_rGrid.GetHeight());        
+    else
+        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+   
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+
+    index_to_px = (float)m_rGrid.GetWidth()/m_samples;
+    a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
+
+    wxPen pen;
+    pen.SetColour(DARK_GREEN_COLOR);
+    pen.SetWidth(1);
+    dc.SetPen(pen);
+
+    // draw all samples
+
+    prev_x = prev_y = 0; // stop warning
+
+    // plot each channel 
+
+    int offset, x, y;
+    for(offset=0; offset<m_channels*m_samples; offset+=m_samples) {
+
+        for(i = 0; i < m_samples; i++) {
+            a = m_mem[offset+i];
+            if (a < m_a_min) a = m_a_min;
+            if (a > m_a_max) a = m_a_max;
+
+            // invert y axis and offset by minimum
+
+            y = m_rGrid.GetHeight() - a_to_py * a + m_a_min*a_to_py;
+
+            // regular point-point line graph
+
+            x = index_to_px * i;
+
+            // put inside plot window
+
+            if (!m_mini) {
+                x += PLOT_BORDER + XLEFT_OFFSET;
+                y += PLOT_BORDER;
+            }
+
+            if (m_bar_graph) {
+
+                if (m_logy) {
+
+                    // can't take log(0)
+
+                    assert(m_a_min > 0.0); 
+                    assert(m_a_max > 0.0);
+
+                    float norm = (log10(a) - log10(m_a_min))/(log10(m_a_max) - log10(m_a_min));
+                    y = m_rGrid.GetHeight()*(1.0 - norm);
+                } else {
+                    y = m_rGrid.GetHeight() - a_to_py * a + m_a_min*a_to_py;
+                }
+
+                // use points to make a bar graph
+
+                int x1, x2, y1;
+
+                x1 = index_to_px * ((float)i - 0.5);
+                x2 = index_to_px * ((float)i + 0.5);
+                y1 = m_rGrid.GetHeight();
+                x1 += PLOT_BORDER + XLEFT_OFFSET; x2 += PLOT_BORDER + XLEFT_OFFSET;
+                y1 += PLOT_BORDER;
+                dc.DrawLine(x1, y1, x1, y); dc.DrawLine(x1, y, x2, y); dc.DrawLine(x2, y, x2, y1);
+            }
+            else {
+                if (i)
+                    dc.DrawLine(x, y, prev_x, prev_y);
+                prev_x = x; prev_y = y;
+            }
+        }
+    }
+
+    drawGraticule(dc);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotScalar::drawGraticule(wxAutoBufferedPaintDC&  dc)
+{
+    float    t, a;
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    sec_to_px;
+    float    a_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    sec_to_px = (float)m_rGrid.GetWidth()/m_t_secs;
+    a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Vertical gridlines
+
+    dc.SetPen(m_penShortDash);
+    for(t=0; t<=m_t_secs; t+=m_graticule_t_step) {
+       x = t*sec_to_px;
+       if (m_mini) {
+            dc.DrawLine(x, m_rGrid.GetHeight(), x, 0);
+        }
+        else {
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        }
+        if (!m_mini) {
+            sprintf(buf, "%2.1fs", t);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+        }
+    }
+
+    // Horizontal gridlines
+
+    dc.SetPen(m_penDotDash);
+    for(a=m_a_min; a<m_a_max; ) {
+        if (m_logy) {
+            float norm = (log10(a) - log10(m_a_min))/(log10(m_a_max) - log10(m_a_min));
+            y = m_rGrid.GetHeight()*(1.0 - norm);
+        }
+       else {
+            y = m_rGrid.GetHeight() - a*a_to_py + m_a_min*a_to_py;
+        }
+       if (m_mini) {
+            dc.DrawLine(0, y, m_rGrid.GetWidth(), y);
+        }
+        else {
+            y += PLOT_BORDER;
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        }
+        if (!m_mini) {
+            sprintf(buf, m_a_fmt, a);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+        }
+
+        if (m_logy) {
+            // m_graticule_a_step ==  0.1 means 10 steps/decade
+            float log10_step_size = floor(log10(a));
+            a += pow(10,log10_step_size);
+        }
+        else {
+            a += m_graticule_a_step;
+        }
+   }
+
+
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotScalar::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotScalar::OnSize(wxSizeEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotScalar::OnShow(wxShowEvent& event)
+{
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scalar.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scalar.h
new file mode 100644 (file)
index 0000000..4b668ff
--- /dev/null
@@ -0,0 +1,78 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scalar.h
+// Purpose:         Defines a scalar plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SCALAR__
+#define __FDMDV2_PLOT_SCALAR__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotScalar
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotScalar: public PlotPanel
+{
+    public:
+
+    PlotScalar(wxFrame* parent,
+               int   channels,
+              float t_secs, 
+              float sample_period_secs,
+              float a_min,
+              float a_max,
+              float graticule_t_step,   
+              float graticule_a_step,
+              const char  a_fmt[],
+               int   mini
+              );
+        ~PlotScalar();
+         void add_new_sample(int channel, float sample);
+         void add_new_samples(int channel, float samples[], int length);
+         void add_new_short_samples(int channel, short samples[], int length, float scale_factor);
+         void setBarGraph(int bar_graph) { m_bar_graph = bar_graph; }
+         void setLogY(int logy) { m_logy = logy; }
+
+    protected:
+
+         int      m_channels;
+        float    m_t_secs;
+        float    m_sample_period_secs;
+        float    m_a_min;
+        float    m_a_max;
+        float    m_graticule_t_step;   
+        float    m_graticule_a_step;
+        char     m_a_fmt[15];
+         int      m_mini;
+        int      m_samples;
+        float   *m_mem;              
+         int      m_bar_graph;                 // non zero to plot bar graphs 
+         int      m_logy;                      // plot graph on log scale
+
+         void draw(wxAutoBufferedPaintDC&  dc);
+         void drawGraticule(wxAutoBufferedPaintDC&  dc);
+         void OnPaint(wxPaintEvent& event);
+         void OnSize(wxSizeEvent& event);
+         void OnShow(wxShowEvent& event);
+
+         DECLARE_EVENT_TABLE()
+};
+
+#endif // __FDMDV2_PLOT_SCALAR__
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scatter.cpp b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scatter.cpp
new file mode 100644 (file)
index 0000000..d7e88c7
--- /dev/null
@@ -0,0 +1,289 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scatter.cpp
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
+// Created:         June 24, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_plot_scatter.h"
+
+BEGIN_EVENT_TABLE(PlotScatter, PlotPanel)
+    EVT_PAINT           (PlotScatter::OnPaint)
+    EVT_MOTION          (PlotScatter::OnMouseMove)
+    EVT_MOUSEWHEEL      (PlotScatter::OnMouseWheelMoved)
+    EVT_SIZE            (PlotScatter::OnSize)
+    EVT_SHOW            (PlotScatter::OnShow)
+//    EVT_ERASE_BACKGROUND(PlotScatter::OnErase)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// PlotScatter
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotScatter::PlotScatter(wxFrame* parent) : PlotPanel(parent)
+{
+    int i;
+
+    for(i=0; i < SCATTER_MEM_SYMS_MAX; i++)
+    {
+        m_mem[i].real = 0.0;
+        m_mem[i].imag = 0.0;
+    }
+
+    m_filter_max_xy = m_filter_max_y = 0.1;
+
+    // defaults so we start off with something sensible
+
+    Nsym = 14+1;
+    scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
+    assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
+
+    Ncol = 0;
+    memset(eye_mem, 0, sizeof(eye_mem));
+
+    mode = PLOT_SCATTER_MODE_SCATTER;
+}
+
+// changing number of carriers changes number of symbols to plot
+void PlotScatter::setNc(int Nc) {
+    Nsym = Nc;
+    assert(Nsym <= (MODEM_STATS_NC_MAX+1));
+    scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
+    assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotScatter::draw(wxAutoBufferedPaintDC& dc)
+{
+    float x_scale;
+    float y_scale;
+    int   i,j;
+    int   x;
+    int   y;
+    wxColour sym_to_colour[] = {wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255), 
+                                wxColor(255,255,0),
+                                wxColor(255,255,255),
+                                wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255), 
+                                wxColor(255,255,0),
+                                wxColor(255,255,255),
+                                wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255)
+    };
+
+    m_rCtrl = GetClientRect();
+    m_rGrid = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    // black background
+
+    dc.Clear();
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+    wxPen pen;
+    pen.SetWidth(1); // note this is ignored by DrawPoint
+
+    if (mode == PLOT_SCATTER_MODE_SCATTER) {
+
+        // automatically scale, first measure the maximum value
+
+        float max_xy = 1E-12;
+        float real,imag;
+        for(i=0; i< scatterMemSyms; i++) {
+            real = fabs(m_mem[i].real);
+            imag = fabs(m_mem[i].imag);
+            if (real > max_xy)
+                max_xy = real;
+            if (imag > max_xy)
+                max_xy = imag;
+        }
+
+        // smooth it out and set a lower limit to prevent divide by 0 issues
+
+        m_filter_max_xy = BETA*m_filter_max_xy + (1 - BETA)*2.5*max_xy;
+        if (m_filter_max_xy < 0.001)
+            m_filter_max_xy = 0.001;
+
+        // quantise to log steps to prevent scatter scaling bobbing about too
+        // much as scaling varies
+
+        float quant_m_filter_max_xy = exp(floor(0.5+log(m_filter_max_xy)));
+        //printf("max_xy: %f m_filter_max_xy: %f quant_m_filter_max_xy: %f\n", max_xy, m_filter_max_xy, quant_m_filter_max_xy);
+
+        x_scale = (float)m_rGrid.GetWidth()/quant_m_filter_max_xy;
+        y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_xy;
+
+        // draw all samples
+
+        for(i = 0; i < scatterMemSyms; i++) {
+            x = x_scale * m_mem[i].real + m_rGrid.GetWidth()/2;
+            y = y_scale * m_mem[i].imag + m_rGrid.GetHeight()/2;
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            y += PLOT_BORDER;
+            pen.SetColour(sym_to_colour[i%Nsym]);
+            dc.SetPen(pen);
+            dc.DrawPoint(x, y);
+        }
+    }
+
+    if (mode == PLOT_SCATTER_MODE_EYE) {
+
+        pen.SetColour(DARK_GREEN_COLOR);
+        pen.SetWidth(1);
+        dc.SetPen(pen);
+
+        // automatically scale, first measure the maximum Y value
+
+        float max_y = 1E-12;
+        float min_y = 1E+12;
+        for(i=0; i<SCATTER_EYE_MEM_ROWS; i++) {
+            for(j=0; j<Ncol; j++) {
+                if (eye_mem[i][j] > max_y) {
+                    max_y = eye_mem[i][j];
+                }
+                if (eye_mem[i][j] < min_y) {
+                    min_y = eye_mem[i][j];
+                }
+            }
+        }
+        // smooth it out and set a lower limit to prevent divide by 0 issues
+
+        m_filter_max_y = BETA*m_filter_max_y + (1 - BETA)*2.5*max_y;
+        if (m_filter_max_y < 0.001)
+            m_filter_max_y = 0.001;
+
+        // quantise to log steps to prevent scatter scaling bobbing about too
+        // much as scaling varies
+
+        float quant_m_filter_max_y = exp(floor(0.5+log(m_filter_max_y)));
+        //printf("min_y: %4.3f max_y: %4.3f quant_m_filter_max_y: %4.3f\n", min_y, max_y, quant_m_filter_max_y);
+
+        x_scale = (float)m_rGrid.GetWidth()/Ncol;
+        y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_y;
+        //printf("GetWidth(): %d GetHeight(): %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
+
+        // plot eye traces row by row
+
+        int prev_x, prev_y;
+        prev_x = prev_y = 0;
+        for(i=0; i<SCATTER_EYE_MEM_ROWS; i++) {
+            //printf("row: ");
+            for(j=0; j<Ncol; j++) {
+                x = x_scale * j;
+                y = m_rGrid.GetHeight()*0.75 - y_scale * eye_mem[i][j];
+               //printf("%4d,%4d  ", x, y);
+                x += PLOT_BORDER + XLEFT_OFFSET;
+                y += PLOT_BORDER;
+                pen.SetColour(sym_to_colour[i%4]);
+                dc.SetPen(pen);
+                if (j)
+                    dc.DrawLine(x, y, prev_x, prev_y);
+                prev_x = x; prev_y = y;
+            }
+            //printf("\n");
+        }
+        
+    }
+}
+
+//----------------------------------------------------------------
+// add_new_samples()
+//----------------------------------------------------------------
+void PlotScatter::add_new_samples_scatter(COMP samples[])
+{
+    int i,j;
+
+    // shift memory
+
+    for(i = 0; i < scatterMemSyms - Nsym; i++)
+    {
+        m_mem[i] = m_mem[i+Nsym];
+    }
+
+    // new samples
+
+    for(j=0; i < scatterMemSyms; i++,j++)
+    {
+        m_mem[i] = samples[j];
+    }
+}
+
+/* add a row of eye samples, updating buffer */
+
+void PlotScatter::add_new_samples_eye(float samples[], int n)
+{
+    int i,j;
+
+    Ncol = n; /* this should be constant for a given modem config */
+
+    assert(n <= PLOT_SCATTER_EYE_MAX_SAMPLES_ROW);
+
+    // eye traces are arrnaged in rows, shift memory of traces
+
+    for(i=0; i<SCATTER_EYE_MEM_ROWS-1; i++) {
+        for(j=0; j<Ncol; j++) {
+            eye_mem[i][j] = eye_mem[i+1][j];
+        }
+    }
+
+    // new samples in last row
+
+    for(j=0; j<Ncol; j++) {
+        eye_mem[SCATTER_EYE_MEM_ROWS-1][j] = samples[j];
+    }
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotScatter::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotScatter::OnSize(wxSizeEvent& event)
+{
+    // todo: clear screen
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotScatter::OnShow(wxShowEvent& event)
+{
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scatter.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_scatter.h
new file mode 100644 (file)
index 0000000..b5e3352
--- /dev/null
@@ -0,0 +1,65 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scatter.h
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
+// Created:         June 24, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SCATTER__
+#define __FDMDV2_PLOT_SCATTER__
+
+#include "comp.h"
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+#define PLOT_SCATTER_MODE_SCATTER            0
+#define PLOT_SCATTER_MODE_EYE                1
+#define PLOT_SCATTER_EYE_MAX_SAMPLES_ROW    80
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotScatter
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotScatter : public PlotPanel
+{
+    public:
+        PlotScatter(wxFrame* parent);
+        ~PlotScatter(){};
+       void add_new_samples_scatter(COMP samples[]);
+       void add_new_samples_eye(float samples[], int n);
+       void setNc(int Nc);
+        void setEyeScatter(int eye_mode) {mode = eye_mode;}
+
+    protected:
+        int  mode;
+        COMP m_mem[SCATTER_MEM_SYMS_MAX];
+        COMP m_new_samples[MODEM_STATS_NC_MAX+1];
+        float eye_mem[SCATTER_EYE_MEM_ROWS][PLOT_SCATTER_EYE_MAX_SAMPLES_ROW];
+
+        void draw(wxAutoBufferedPaintDC&  dc);
+        void OnPaint(wxPaintEvent& event);
+        void OnSize(wxSizeEvent& event);
+        void OnShow(wxShowEvent& event);
+
+        DECLARE_EVENT_TABLE()
+
+    private:
+        int   Nsym;
+        int   Ncol;
+        int   scatterMemSyms;
+        float m_filter_max_xy, m_filter_max_y;
+};
+
+#endif //__FDMDV2_PLOT_SCATTER__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_spectrum.cpp b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_spectrum.cpp
new file mode 100644 (file)
index 0000000..1f5be59
--- /dev/null
@@ -0,0 +1,267 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.cpp
+// Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 23, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+
+#include "fdmdv2_main.h"
+
+extern float g_avmag[];                 // average mag data passed to draw() 
+void fdmdv2_clickTune(float frequency); // callback to pass new click freq
+
+BEGIN_EVENT_TABLE(PlotSpectrum, PlotPanel)
+    EVT_MOTION          (PlotSpectrum::OnMouseMove)
+    EVT_LEFT_DOWN       (PlotSpectrum::OnMouseLeftDown)
+    EVT_LEFT_DCLICK     (PlotSpectrum::OnMouseLeftDoubleClick)
+    EVT_LEFT_UP         (PlotSpectrum::OnMouseLeftUp)
+    EVT_MOUSEWHEEL      (PlotSpectrum::OnMouseWheelMoved)
+    EVT_PAINT           (PlotSpectrum::OnPaint)
+    EVT_SHOW            (PlotSpectrum::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotSpectrum
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotSpectrum::PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, 
+                           float min_mag_db, float max_mag_db, bool clickTune): PlotPanel(parent)
+{
+    m_greyscale     = 0;
+    m_Bufsz         = GetMaxClientSize();
+    m_newdata       = false;
+    m_firstPass     = true;
+    m_line_color    = 0;
+    SetLabelSize(10.0);
+
+    m_magdB         = magdB;
+    m_n_magdB       = n_magdB;     // number of points in magdB that covers 0 ... MAX_F_HZ of spectrum
+    m_max_mag_db    = max_mag_db;
+    m_min_mag_db    = min_mag_db;
+    m_rxFreq        = 0.0;
+    m_clickTune     = clickTune;
+}
+
+//----------------------------------------------------------------
+// ~PlotSpectrum()
+//----------------------------------------------------------------
+PlotSpectrum::~PlotSpectrum()
+{
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotSpectrum::OnSize(wxSizeEvent& event) {
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotSpectrum::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotSpectrum::OnShow(wxShowEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotSpectrum::draw(wxAutoBufferedPaintDC& dc)
+{
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.  We need to work this out every time we draw
+    // as OnSize() may not be called before OnPaint(), for example when a new tab
+    // is selected
+
+    m_rGrid  = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    dc.Clear();
+
+    // black background
+
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+
+    // draw spectrum
+
+    int   x, y, prev_x, prev_y, index;
+    float index_to_px, mag_dB_to_py, mag;
+
+    m_newdata = false;
+
+    wxPen pen;
+    pen.SetColour(DARK_GREEN_COLOR);
+    pen.SetWidth(1);
+    dc.SetPen(pen);
+
+    index_to_px = (float)m_rGrid.GetWidth()/m_n_magdB;
+    mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
+
+    prev_x = PLOT_BORDER + XLEFT_OFFSET;
+    prev_y = PLOT_BORDER;
+    for(index = 0; index < m_n_magdB; index++)
+    {
+        x = index*index_to_px;
+        mag = m_magdB[index];
+        if (mag > m_max_mag_db) mag = m_max_mag_db;
+        if (mag < m_min_mag_db) mag = m_min_mag_db;
+        y = -(mag - m_max_mag_db) * mag_dB_to_py;
+
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        y += PLOT_BORDER;
+
+        if (index)
+            dc.DrawLine(x, y, prev_x, prev_y);
+        prev_x = x; prev_y = y;
+    }
+
+    // and finally draw Graticule
+
+    drawGraticule(dc);
+
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC&  dc)
+{
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    f, mag, freq_hz_to_px, mag_dB_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+    mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Check if small screen size means text will overlap
+
+    int textXStep = STEP_F_HZ*freq_hz_to_px;
+    int textYStep = STEP_MAG_DB*mag_dB_to_py;
+    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
+    GetTextExtent(buf, &text_w, &text_h);
+    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
+    //printf("text_w: %d textXStep: %d text_h: %d textYStep: %d  overlappedText: %d\n", text_w, textXStep, 
+    //      text_h, textYStep, overlappedText);
+
+    // Vertical gridlines
+
+    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) {
+       x = f*freq_hz_to_px;
+       x += PLOT_BORDER + XLEFT_OFFSET;
+
+        dc.SetPen(m_penShortDash);
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        dc.SetPen(wxPen(BLACK_COLOR, 1));
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+
+        sprintf(buf, "%4.0fHz", f);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+    }
+
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
+    // Horizontal gridlines
+
+    dc.SetPen(m_penDotDash);
+    for(mag=m_min_mag_db; mag<=m_max_mag_db; mag+=STEP_MAG_DB) {
+       y = -(mag - m_max_mag_db) * mag_dB_to_py;
+       y += PLOT_BORDER;
+       dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                   (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        sprintf(buf, "%3.0fdB", mag);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+    }
+
+    // red rx tuning line
+    
+    if (m_rxFreq != 0.0) {
+        dc.SetPen(wxPen(RED_COLOR, 2));
+        x = m_rxFreq*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
+        dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnMouseDown()
+//-------------------------------------------------------------------------
+void PlotSpectrum::OnMouseLeftDoubleClick(wxMouseEvent& event)
+{
+    m_mouseDown = true;
+    wxClientDC dc(this);
+
+    wxPoint pt(event.GetLogicalPosition(dc));
+
+    // map x coord to edges of actual plot
+    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
+    pt.y -= PLOT_BORDER;
+
+    // valid click if inside of plot
+    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0) && m_clickTune) {
+        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+        float clickFreq = (float)pt.x/freq_hz_to_px;
+
+        // see PlotWaterfall::OnMouseDown()
+
+        fdmdv2_clickTune(clickFreq);
+    }
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_spectrum.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_spectrum.h
new file mode 100644 (file)
index 0000000..271eeb9
--- /dev/null
@@ -0,0 +1,58 @@
+//==========================================================================
+// Name:            fdmdv2_plot_spectrum.h
+// Purpose:         Defines a spectrum plot derived from fdmdv2_plot class.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SPECTRUM__
+#define __FDMDV2_PLOT_SPECTRUM__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class Waterfall
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotSpectrum : public PlotPanel
+{
+    public:
+    PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, 
+                 float min_mag_db=MIN_MAG_DB, float max_mag_db=MAX_MAG_DB, bool clickTune=true);
+        ~PlotSpectrum();
+        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
+        void setFreqScale(int n_magdB) { m_n_magdB = n_magdB; }
+
+    protected:
+        void        OnPaint(wxPaintEvent& event);
+        void        OnSize(wxSizeEvent& event);
+        void        OnShow(wxShowEvent& event);
+        void        drawGraticule(wxAutoBufferedPaintDC& dc);
+        void        draw(wxAutoBufferedPaintDC& dc);
+        void        OnMouseLeftDoubleClick(wxMouseEvent& event);
+
+   private:
+        float       m_rxFreq;
+        float       m_max_mag_db;
+        float       m_min_mag_db;
+        float      *m_magdB;
+        int         m_n_magdB;  
+        bool        m_clickTune;
+
+        DECLARE_EVENT_TABLE()
+};
+
+#endif //__FDMDV2_PLOT_SPECTRUM__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_waterfall.cpp b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_waterfall.cpp
new file mode 100644 (file)
index 0000000..cdbe01e
--- /dev/null
@@ -0,0 +1,483 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.cpp
+// Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_main.h"
+
+extern float g_avmag[];                 // av mag spec passed in to draw() 
+void fdmdv2_clickTune(float frequency); // callback to pass new click freq
+
+BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel)
+    EVT_PAINT           (PlotWaterfall::OnPaint)
+    EVT_MOTION          (PlotWaterfall::OnMouseMove)
+    EVT_LEFT_DCLICK     (PlotWaterfall::OnMouseLeftDoubleClick)
+    EVT_RIGHT_DOWN      (PlotWaterfall::OnMouseRightDown)
+    EVT_LEFT_UP         (PlotWaterfall::OnMouseLeftUp)
+    EVT_MOUSEWHEEL      (PlotWaterfall::OnMouseWheelMoved)
+    EVT_SIZE            (PlotWaterfall::OnSize)
+    EVT_SHOW            (PlotWaterfall::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class WaterfallPlot
+//
+// @class   WaterfallPlot
+// @author  David Witten
+// @date    $(Date)
+// @file    $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotWaterfall::PlotWaterfall(wxFrame* parent, bool graticule, int colour): PlotPanel(parent)
+{
+
+    for(int i = 0; i < 255; i++)
+    {
+        m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0);
+    }
+    m_graticule     = graticule;
+    m_colour        = colour;
+    m_Bufsz         = GetMaxClientSize();
+    m_newdata       = false;
+    m_firstPass     = true;
+    m_line_color    = 0;
+    m_modem_stats_max_f_hz = MODEM_STATS_MAX_F_HZ;
+
+    SetLabelSize(10.0);
+
+    m_pBmp = NULL;
+    m_max_mag = MAX_MAG_DB;
+    m_min_mag = MIN_MAG_DB;
+}
+
+// When the window size gets set we can work outthe size of the window
+// we plot in and allocate a bit map of the correct size
+void PlotWaterfall::OnSize(wxSizeEvent& event) 
+{
+    // resize bit map
+
+    delete m_pBmp;
+    
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid  = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    // we want a bit map the size of m_rGrid
+
+    m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
+
+    m_dT = DT;
+}
+
+//----------------------------------------------------------------
+// paintEvent()
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+// Called by the system of by wxWidgets when the panel needs
+// to be redrawn. You can also trigger this call by calling
+// Refresh()/Update().
+//----------------------------------------------------------------
+void PlotWaterfall::OnPaint(wxPaintEvent & evt)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotWaterfall::OnShow(wxShowEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// ~PlotWaterfall()
+//----------------------------------------------------------------
+PlotWaterfall::~PlotWaterfall()
+{
+}
+
+//----------------------------------------------------------------
+// heatmap()
+// map val to a rgb colour
+// from http://eddiema.ca/2011/01/21/c-sharp-heatmaps/
+//----------------------------------------------------------------
+unsigned PlotWaterfall::heatmap(float val, float min, float max)
+{
+    unsigned r = 0;
+    unsigned g = 0;
+    unsigned b = 0;
+
+    val = (val - min) / (max - min);
+    if(val <= 0.2)
+    {
+        b = (unsigned)((val / 0.2) * 255);
+    }
+    else if(val >  0.2 &&  val <= 0.7)
+    {
+        b = (unsigned)((1.0 - ((val - 0.2) / 0.5)) * 255);
+    }
+    if(val >= 0.2 &&  val <= 0.6)
+    {
+        g = (unsigned)(((val - 0.2) / 0.4) * 255);
+    }
+    else if(val >  0.6 &&  val <= 0.9)
+    {
+        g = (unsigned)((1.0 - ((val - 0.6) / 0.3)) * 255);
+    }
+    if(val >= 0.5)
+    {
+        r = (unsigned)(((val - 0.5) / 0.5) * 255);
+    }
+    //printf("%f %x %x %x\n", val, r, g, b);
+    return  (b << 16) + (g << 8) + r;
+}
+
+bool PlotWaterfall::checkDT(void)
+{
+    // Check dY is > 1 pixel before proceeding. For small screens
+    // and large WATERFALL_SECS_Y we might have less than one
+    // block per pixel.  In this case increase m_dT and perform draw
+    // less often
+
+    float px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    float dy = m_dT * px_per_sec;
+    
+    if (dy < 1.0) {
+        m_dT += DT;
+        return false;
+    }
+    else
+        return true;
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotWaterfall::draw(wxAutoBufferedPaintDC& dc)
+{
+
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    if (m_pBmp == NULL) 
+    {
+        // we want a bit map the size of m_rGrid
+        m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
+    }
+
+    dc.Clear();
+
+    if(m_newdata)
+    {
+        m_newdata = false;
+        plotPixelData();
+        dc.DrawBitmap(*m_pBmp, PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
+        m_dT = DT;
+    }
+    else 
+    {
+
+        // no data to plot so just erase to black.  Blue looks nicer
+        // but is same colour as low amplitude signal
+
+        // Bug on Linux: When Stop is pressed this code doesn't erase
+        // the lower 25% of the Waterfall Window
+
+        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+        wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+        dc.SetBrush(ltGraphBkgBrush);
+        dc.SetPen(wxPen(BLACK_COLOR, 0));
+        dc.DrawRectangle(m_rPlot);
+    }
+    drawGraticule(dc);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
+{
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    f, time, freq_hz_to_px, time_s_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+    time_s_to_py = (float)m_rGrid.GetHeight()/WATERFALL_SECS_Y;
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Check if small screen size means text will overlap
+
+    int textXStep = STEP_F_HZ*freq_hz_to_px;
+    int textYStep = WATERFALL_SECS_STEP*time_s_to_py;
+    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
+    GetTextExtent(buf, &text_w, &text_h);
+    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
+
+    // Major Vertical gridlines and legend
+    //dc.SetPen(m_penShortDash);
+    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+
+        if (m_graticule)
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        else
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+            
+        sprintf(buf, "%4.0fHz", f);
+        GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+    }
+
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
+    // Horizontal gridlines
+    dc.SetPen(m_penDotDash);
+    for(time=0; time<=WATERFALL_SECS_Y; time+=WATERFALL_SECS_STEP) {
+       y = m_rGrid.GetHeight() - time*time_s_to_py;
+       y += PLOT_BORDER;
+
+        if (m_graticule)
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        sprintf(buf, "%3.0fs", time);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+   }
+
+    // red rx tuning line
+    dc.SetPen(wxPen(RED_COLOR, 2));
+    x = m_rxFreq*freq_hz_to_px;
+    x += PLOT_BORDER + XLEFT_OFFSET;
+    //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
+    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
+    
+}
+
+//-------------------------------------------------------------------------
+// plotPixelData()
+//-------------------------------------------------------------------------
+void PlotWaterfall::plotPixelData()
+{
+    float       spec_index_per_px;
+    float       intensity_per_dB;
+    float       px_per_sec;
+    int         index;
+    float       dy;
+    int         dy_blocks;
+    int         b;
+    int         px;
+    int         py;
+    int         intensity;
+
+    /*
+      Design Notes:
+
+      The height in pixels represents WATERFALL_SECS_Y of data.  Every DT
+      seconds we get a vector of MODEM_STATS_NSPEC spectrum samples which we use
+      to update the last row.  The height of each row is dy pixels, which
+      maps to DT seconds.  We call each dy high rectangle of pixels a
+      block.
+
+    */
+
+    // determine dy, the height of one "block"
+    px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    dy = m_dT * px_per_sec;
+
+    // number of dy high blocks in spectrogram
+    dy_blocks = m_rGrid.GetHeight()/ dy;
+
+    // update min and max amplitude estimates
+    float max_mag = MIN_MAG_DB;
+
+    int min_fft_bin=((float)200/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
+    int max_fft_bin=((float)2800/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
+
+    for(int i=min_fft_bin; i<max_fft_bin; i++) 
+    {
+        if (g_avmag[i] > max_mag)
+        {
+            max_mag = g_avmag[i];
+        }
+    }
+
+    m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
+    m_min_mag = max_mag - 20.0;
+    //printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
+    //intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
+    intensity_per_dB  = (float)256 /(m_max_mag - m_min_mag);
+    spec_index_per_px = ((float)(MAX_F_HZ)/(float)m_modem_stats_max_f_hz)*(float)MODEM_STATS_NSPEC / (float) m_rGrid.GetWidth();
+
+    /*
+    printf("h %d w %d px_per_sec %d dy %d dy_blocks %d spec_index_per_px: %f\n", 
+       m_rGrid.GetHeight(), m_rGrid.GetWidth(), px_per_sec, 
+       dy, dy_blocks, spec_index_per_px);
+    */
+
+    // Shift previous bit map up one row of blocks ----------------------------
+    wxNativePixelData data(*m_pBmp);
+    wxNativePixelData::Iterator bitMapStart(data);
+    wxNativePixelData::Iterator p = bitMapStart;
+
+    for(b = 0; b < dy_blocks - 1; b++) 
+    {
+        wxNativePixelData::Iterator psrc = bitMapStart;
+        wxNativePixelData::Iterator pdest = bitMapStart;
+        pdest.OffsetY(data, dy * b);
+        psrc.OffsetY(data, dy * (b+1));
+
+        // copy one line of blocks
+
+        for(py = 0; py < dy; py++) 
+        {
+            wxNativePixelData::Iterator pdestRowStart = pdest;
+            wxNativePixelData::Iterator psrcRowStart = psrc;
+
+            for(px = 0; px < m_rGrid.GetWidth(); px++) 
+            {
+                pdest.Red() = psrc.Red();
+                pdest.Green() = psrc.Green();
+                pdest.Blue() = psrc.Blue();
+                pdest++;
+                psrc++;
+            }
+            pdest = pdestRowStart;
+            pdest.OffsetY(data, 1);
+            psrc = psrcRowStart;
+            psrc.OffsetY(data, 1);         
+        }
+    }
+
+    // Draw last line of blocks using latest amplitude data ------------------
+    p = bitMapStart;
+    p.OffsetY(data, dy *(dy_blocks - 1));
+    for(py = 0; py < dy; py++)
+    {
+        wxNativePixelData::Iterator rowStart = p;
+
+        for(px = 0; px < m_rGrid.GetWidth(); px++)
+        {
+            index = px * spec_index_per_px;
+            assert(index < MODEM_STATS_NSPEC);
+
+            intensity = intensity_per_dB * (g_avmag[index] - m_min_mag);
+            if(intensity > 255) intensity = 255;
+            if (intensity < 0) intensity = 0;
+            //printf("%d %f %d \n", index, g_avmag[index], intensity);
+
+            switch (m_colour) {
+            case 0:
+                p.Red() = m_heatmap_lut[intensity] & 0xff;
+                p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
+                p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
+                break;
+            case 1:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                p.Blue() = intensity;       
+                break;
+            case 2:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                if (intensity < 127)
+                    p.Blue() = intensity*2;
+                else
+                    p.Blue() = 255;
+                        
+                break;
+            }
+            ++p;
+        }
+        p = rowStart;
+        p.OffsetY(data, 1);
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseLeftDoubleClick(wxMouseEvent& event)
+{
+    m_mouseDown = true;
+    wxClientDC dc(this);
+
+    wxPoint pt(event.GetLogicalPosition(dc));
+
+    // map x coord to edges of actual plot
+    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
+    pt.y -= PLOT_BORDER;
+
+    // valid click if inside of plot
+    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0)) 
+    {
+        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+        float clickFreq = (float)pt.x/freq_hz_to_px;
+
+        // communicate back to other threads
+        fdmdv2_clickTune(clickFreq);
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseRightDown(wxMouseEvent& event)
+{
+    m_colour++;
+    if (m_colour == 3)
+        m_colour = 0;
+}
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_waterfall.h b/freedv/tags/1.2.2/freedv-dev/src/fdmdv2_plot_waterfall.h
new file mode 100644 (file)
index 0000000..f4896c6
--- /dev/null
@@ -0,0 +1,73 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.h
+// Purpose:         Defines a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_WATERFALL__
+#define __FDMDV2_PLOT_WATERFALL__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotWaterfall
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotWaterfall : public PlotPanel
+{
+    public:
+    PlotWaterfall(wxFrame* parent, bool graticule, int colour);
+        ~PlotWaterfall();
+        bool checkDT(void);
+        void setGreyscale(bool greyscale) { m_greyscale = greyscale; }
+        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
+        void setFs(int fs) { m_modem_stats_max_f_hz = fs/2; }
+
+    protected:
+        unsigned    m_heatmap_lut[256];
+
+        unsigned    heatmap(float val, float min, float max);
+
+        void        OnPaint(wxPaintEvent & evt);
+        void        OnSize(wxSizeEvent& event);
+        void        OnShow(wxShowEvent& event);
+        void        drawGraticule(wxAutoBufferedPaintDC&  dc);
+        void        draw(wxAutoBufferedPaintDC& dc);
+        void        plotPixelData();
+        void        OnMouseLeftDoubleClick(wxMouseEvent& event);
+        void        OnMouseRightDown(wxMouseEvent& event);
+
+    private:
+        float       m_dT;
+        float       m_rxFreq;
+        bool        m_graticule;
+        float       m_min_mag;
+        float       m_max_mag;
+        int         m_colour;
+        int         m_modem_stats_max_f_hz;
+
+        DECLARE_EVENT_TABLE()
+};
+
+#endif //__FDMDV2_PLOT_WATERFALL__
diff --git a/freedv/tags/1.2.2/freedv-dev/src/freedv.icns b/freedv/tags/1.2.2/freedv-dev/src/freedv.icns
new file mode 100644 (file)
index 0000000..5190e79
Binary files /dev/null and b/freedv/tags/1.2.2/freedv-dev/src/freedv.icns differ
diff --git a/freedv/tags/1.2.2/freedv-dev/src/hamlib.cpp b/freedv/tags/1.2.2/freedv-dev/src/hamlib.cpp
new file mode 100644 (file)
index 0000000..ff80b24
--- /dev/null
@@ -0,0 +1,160 @@
+//==========================================================================
+// Name:            hamlib.cpp
+//
+// Purpose:         Hamlib integration for FreeDV
+// Created:         May 2013
+// Authors:         Joel Stanley
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <hamlib.h>
+
+#include <vector>
+#include <algorithm>
+
+using namespace std;
+
+typedef std::vector<const struct rig_caps *> riglist_t;
+
+static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2);
+static int build_list(const struct rig_caps *rig, rig_ptr_t);
+
+Hamlib::Hamlib() : m_rig(NULL) {
+    /* Stop hamlib from spewing info to stderr. */
+    rig_set_debug(RIG_DEBUG_NONE);
+
+    /* Create sorted list of rigs. */
+    rig_load_all_backends();
+    rig_list_foreach(build_list, &m_rigList);
+    sort(m_rigList.begin(), m_rigList.end(), rig_cmp);
+
+    /* Reset debug output. */
+    rig_set_debug(RIG_DEBUG_VERBOSE);
+
+    m_rig = NULL;
+}
+
+Hamlib::~Hamlib() {
+       if(m_rig)
+               close();
+}
+
+static int build_list(const struct rig_caps *rig, rig_ptr_t rigList) {
+    ((riglist_t *)rigList)->push_back(rig); 
+    return 1;
+}
+
+static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2) {
+    /* Compare manufacturer. */
+    int r = strcasecmp(rig1->mfg_name, rig2->mfg_name);
+    if (r != 0)
+        return r < 0;
+
+    /* Compare model. */
+    r = strcasecmp(rig1->model_name, rig2->model_name);
+    if (r != 0)
+        return r < 0;
+
+    /* Compare rig ID. */
+    return rig1->rig_model < rig2->rig_model;
+}
+
+void Hamlib::populateComboBox(wxComboBox *cb) {
+
+    riglist_t::const_iterator rig = m_rigList.begin();
+    for (; rig !=m_rigList.end(); rig++) {
+        char name[128];
+        snprintf(name, 128, "%s %s", (*rig)->mfg_name, (*rig)->model_name); 
+        cb->Append(name);
+    }
+}
+
+bool Hamlib::connect(unsigned int rig_index, const char *serial_port, const int serial_rate) {
+    /* Look up model from index. */
+    if (rig_index >= m_rigList.size()) {
+        return false;
+    }
+    fprintf(stderr, "rig: %s %s (%d)\n", m_rigList[rig_index]->mfg_name,
+            m_rigList[rig_index]->model_name, m_rigList[rig_index]->rig_model);
+
+       if(m_rig) {
+               printf("Closing old hamlib instance!\n");
+               close();
+       }
+
+    /* Initialise, configure and open. */
+
+    m_rig = rig_init(m_rigList[rig_index]->rig_model);
+
+    if (!m_rig)
+        return false;
+
+    /* TODO we may also need civaddr for Icom */
+
+    strncpy(m_rig->state.rigport.pathname, serial_port, FILPATHLEN - 1);
+    if (serial_rate) {
+        m_rig->state.rigport.parm.serial.rate = serial_rate;
+    }
+    fprintf(stderr, "hamlib: setting serial rate: %d\n", m_rig->state.rigport.parm.serial.rate);
+
+    if (rig_open(m_rig) == RIG_OK) {
+        return true;
+    }
+
+    return false;
+}
+
+int Hamlib::get_serial_rate(void) {
+    return m_rig->state.rigport.parm.serial.rate;
+}
+
+int Hamlib::get_data_bits(void) {
+    return m_rig->state.rigport.parm.serial.data_bits;
+}
+
+int Hamlib::get_stop_bits(void) {
+    return m_rig->state.rigport.parm.serial.stop_bits;
+}
+
+bool Hamlib::ptt(bool press, wxString &hamlibError) {
+    fprintf(stderr,"Hamlib::ptt: %d\n", press);
+    hamlibError = "";
+
+    if(!m_rig)
+        return false;
+
+    /* TODO(Joel): make ON_DATA and ON configurable. */
+
+    ptt_t on = press ? RIG_PTT_ON : RIG_PTT_OFF;
+
+    /* TODO(Joel): what should the VFO option be? */
+
+    int retcode = rig_set_ptt(m_rig, RIG_VFO_CURR, on);
+    fprintf(stderr,"Hamlib::ptt: rig_set_ptt returned: %d\n", retcode);
+    if (retcode != RIG_OK ) {
+        fprintf(stderr, "rig_set_ptt: error = %s \n", rigerror(retcode));
+        hamlibError = rigerror(retcode);
+    }
+
+    return retcode == RIG_OK;
+}
+
+void Hamlib::close(void) {
+    if(m_rig) {
+        rig_close(m_rig);
+        rig_cleanup(m_rig);
+        m_rig = NULL;
+    }
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/hamlib.h b/freedv/tags/1.2.2/freedv-dev/src/hamlib.h
new file mode 100644 (file)
index 0000000..65af2d4
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef HAMLIB_H
+#define HAMLIB_H
+
+extern "C" {
+#include <hamlib/rig.h>
+}
+#include <wx/combobox.h>
+#include <vector>
+
+class Hamlib {
+
+    public:
+        Hamlib();
+        ~Hamlib();
+        void populateComboBox(wxComboBox *cb);
+        bool connect(unsigned int rig_index, const char *serial_port, const int serial_rate);
+        bool ptt(bool press, wxString &hamlibError);
+        void close(void);
+        int get_serial_rate(void);
+        int get_data_bits(void);
+        int get_stop_bits(void);
+
+        typedef std::vector<const struct rig_caps *> riglist_t;
+
+    private:
+        RIG *m_rig;
+        /* Sorted list of rigs. */
+        riglist_t m_rigList;
+};
+
+#endif /*HAMLIB_H*/
diff --git a/freedv/tags/1.2.2/freedv-dev/src/info.plist b/freedv/tags/1.2.2/freedv-dev/src/info.plist
new file mode 100644 (file)
index 0000000..8f0d4c3
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>CFBundleIconFile</key>
+       <string>freedv</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
\ No newline at end of file
diff --git a/freedv/tags/1.2.2/freedv-dev/src/serialport.cpp b/freedv/tags/1.2.2/freedv-dev/src/serialport.cpp
new file mode 100644 (file)
index 0000000..59dd0c9
--- /dev/null
@@ -0,0 +1,234 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "serialport.h"
+
+Serialport::Serialport() {
+    com_handle = COM_HANDLE_INVALID;
+}
+
+Serialport::~Serialport() {
+    if (isopen()) {
+        closeport();
+    }
+}
+
+// returns true if comm port opened OK, false if there was a problem
+
+bool Serialport::openport(const char name[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos)
+{
+    if (com_handle != COM_HANDLE_INVALID) {
+        closeport();
+    }
+
+    m_useRTS = useRTS;
+    m_RTSPos = RTSPos;
+    m_useDTR = useDTR;
+    m_DTRPos = DTRPos;
+
+#ifdef _WIN32
+       {
+               COMMCONFIG CC;
+               DWORD CCsize=sizeof(CC);
+               COMMTIMEOUTS timeouts;
+               DCB     dcb;
+
+               if(GetDefaultCommConfigA(name, &CC, &CCsize)) {
+                       CC.dcb.fOutxCtsFlow             = FALSE;
+                       CC.dcb.fOutxDsrFlow             = FALSE;
+                       CC.dcb.fDtrControl              = DTR_CONTROL_DISABLE;
+                       CC.dcb.fDsrSensitivity  = FALSE;
+                       CC.dcb.fRtsControl              = RTS_CONTROL_DISABLE;
+                       SetDefaultCommConfigA(name, &CC, CCsize);
+               }
+
+               if((com_handle=CreateFileA(name
+                       ,GENERIC_READ|GENERIC_WRITE     /* Access */
+                       ,0                                                              /* Share mode */
+                       ,NULL                                                   /* Security attributes */
+                       ,OPEN_EXISTING                                  /* Create access */
+                       ,FILE_ATTRIBUTE_NORMAL                  /* File attributes */
+                       ,NULL                                                   /* Template */
+                       ))==INVALID_HANDLE_VALUE)
+                       return false;
+
+               if(GetCommTimeouts(com_handle, &timeouts)) {
+                       timeouts.ReadIntervalTimeout=MAXDWORD;
+                       timeouts.ReadTotalTimeoutMultiplier=0;
+                       timeouts.ReadTotalTimeoutConstant=0;            // No-wait read timeout
+                       timeouts.WriteTotalTimeoutMultiplier=0;
+                       timeouts.WriteTotalTimeoutConstant=5000;        // 5 seconds
+                       SetCommTimeouts(com_handle,&timeouts);
+               }
+
+               /* Force N-8-1 mode: */
+               if(GetCommState(com_handle, &dcb)==TRUE) {
+                       dcb.ByteSize            = 8;
+                       dcb.Parity                      = NOPARITY;
+                       dcb.StopBits            = ONESTOPBIT;
+                       dcb.DCBlength           = sizeof(DCB);
+                       dcb.fBinary                     = TRUE;
+                       dcb.fOutxCtsFlow        = FALSE;
+                       dcb.fOutxDsrFlow        = FALSE;
+                       dcb.fDtrControl         = DTR_CONTROL_DISABLE;
+                       dcb.fDsrSensitivity     = FALSE;
+                       dcb.fTXContinueOnXoff= TRUE;
+                       dcb.fOutX                       = FALSE;
+                       dcb.fInX                        = FALSE;
+                       dcb.fRtsControl         = RTS_CONTROL_DISABLE;
+                       dcb.fAbortOnError       = FALSE;
+                       SetCommState(com_handle, &dcb);
+               }
+       }
+#else
+       {
+               struct termios t;
+
+               if((com_handle=open(name, O_NONBLOCK|O_RDWR))== COM_HANDLE_INVALID)
+                       return false;
+
+               if(tcgetattr(com_handle, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+
+               t.c_iflag = (
+                                         IGNBRK   /* ignore BREAK condition */
+                                       | IGNPAR   /* ignore (discard) parity errors */
+                                       );
+               t.c_oflag = 0;  /* No output processing */
+               t.c_cflag = (
+                                         CS8         /* 8 bits */
+                                       | CREAD       /* enable receiver */
+
+               /*
+               Fun snippet from the FreeBSD manpage:
+
+                        If CREAD is set, the receiver is enabled.  Otherwise, no character is
+                        received.  Not all hardware supports this bit.  In fact, this flag is
+                        pretty silly and if it were not part of the termios specification it
+                        would be omitted.
+               */
+                                       | CLOCAL      /* ignore modem status lines */
+                                       );
+
+               t.c_lflag = 0;  /* No local modes */
+               if(tcsetattr(com_handle, TCSANOW, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+               
+       }
+#endif
+       return true;
+}
+
+
+// fixme: this takes about one second to close under Linux
+
+void Serialport::closeport()
+{
+#ifdef _WIN32
+       CloseHandle(com_handle);
+#else
+       close(com_handle);
+#endif
+        com_handle = COM_HANDLE_INVALID;
+}
+
+//----------------------------------------------------------------
+// (raise|lower)(RTS|DTR)()
+//
+// Raises/lowers the specified signal
+//----------------------------------------------------------------
+
+void Serialport::raiseDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::raiseRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::ptt(bool tx) {
+
+   /*  Truth table:
+
+          g_tx   RTSPos   RTS
+          -------------------
+          0      1        0
+          1      1        1
+          0      0        1
+          1      0        0
+
+          exclusive NOR
+    */
+
+    if (com_handle != COM_HANDLE_INVALID) {
+        if (m_useRTS) {
+            //fprintf(stderr, "g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos);
+            if (tx == m_RTSPos)
+                raiseRTS();
+            else
+                lowerRTS();
+        }
+        if (m_useDTR) {
+            //fprintf(stderr, "g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos);
+            if (tx == m_DTRPos)
+                raiseDTR();
+            else
+                lowerDTR();
+        }
+    }
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/serialport.h b/freedv/tags/1.2.2/freedv-dev/src/serialport.h
new file mode 100644 (file)
index 0000000..e5db10b
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef SERIALPORT_H
+#define SERIALPORT_H
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#endif
+
+// Serial ports called com port for historic reasons, especially on Windows machines 
+
+#ifdef _WIN32
+#define COM_HANDLE_INVALID                     INVALID_HANDLE_VALUE
+typedef HANDLE      com_handle_t;
+#else
+#define COM_HANDLE_INVALID                     -1
+typedef int         com_handle_t;
+#endif
+
+class Serialport {
+
+    public:
+        Serialport();
+        ~Serialport();
+        bool openport(const char port[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos);
+        bool isopen() {return (com_handle != COM_HANDLE_INVALID);}
+        void closeport();
+        void ptt(bool tx);
+
+    private:
+        com_handle_t  com_handle;
+        bool          m_useRTS, m_RTSPos, m_useDTR, m_DTRPos;
+
+        void raiseDTR(void);
+        void lowerDTR(void);
+        void raiseRTS(void);
+        void lowerRTS(void);
+};
+
+#endif /* SERIALPORT_H */
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/band.h b/freedv/tags/1.2.2/freedv-dev/src/sox/band.h
new file mode 100644 (file)
index 0000000..5398ff4
--- /dev/null
@@ -0,0 +1,47 @@
+/* libSoX Bandpass effect file.     July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * Algorithm:  2nd order recursive filter.
+ * Formula stolen from MUSIC56K, a toolkit of 56000 assembler stuff.
+ * Quote:
+ *   This is a 2nd order recursive band pass filter of the form.
+ *   y(n)= a * x(n) - b * y(n-1) - c * y(n-2)
+ *   where :
+ *        x(n) = "IN"
+ *        "OUT" = y(n)
+ *        c = EXP(-2*pi*cBW/S_RATE)
+ *        b = -4*c/(1+c)*COS(2*pi*cCF/S_RATE)
+ *   if cSCL=2 (i.e. noise input)
+ *        a = SQT(((1+c)*(1+c)-b*b)*(1-c)/(1+c))
+ *   else
+ *        a = SQT(1-b*b/(4*c))*(1-c)
+ *   endif
+ *   note :     cCF is the center frequency in Hertz
+ *        cBW is the band width in Hertz
+ *        cSCL is a scale factor, use 1 for pitched sounds
+ *   use 2 for noise.
+ *
+ *
+ * July 1, 1999 - Jan Paul Schmidt <jps@fundament.org>
+ *
+ *   This looks like the resonator band pass in SPKit. It's a
+ *   second order all-pole (IIR) band-pass filter described
+ *   at the pages 186 - 189 in
+ *     Dodge, Charles & Jerse, Thomas A. 1985:
+ *       Computer Music -- Synthesis, Composition and Performance.
+ *       New York: Schirmer Books.
+ *   Reference from the SPKit manual.
+ */
+
+  p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate);
+  p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->in_signal.rate);
+  p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2);
+  if (p->filter_type == filter_BPF_SPK_N) {
+    mult = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2)) / p->b0;
+    p->b0 *= mult;
+  }
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/biquad.c b/freedv/tags/1.2.2/freedv-dev/src/sox/biquad.c
new file mode 100644 (file)
index 0000000..c57f190
--- /dev/null
@@ -0,0 +1,178 @@
+/* libSoX Biquad filter common functions   (c) 2006-7 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "biquad.h"
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+static char const * const width_str[] = {
+  "band-width(Hz)",
+  "band-width(kHz)",
+  "band-width(Hz, no warp)", /* deprecated */
+  "band-width(octaves)",
+  "Q",
+  "slope",
+};
+static char const all_width_types[] = "hkboqs";
+
+
+int lsx_biquad_getopts(sox_effect_t * effp, int argc, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  char width_type = *allowed_width_types;
+  char dummy, * dummy_p;     /* To check for extraneous chars. */
+  --argc, ++argv;
+
+  p->filter_type = filter_type;
+  if (argc < min_args || argc > max_args ||
+      (argc > fc_pos    && ((p->fc = lsx_parse_frequency(argv[fc_pos], &dummy_p)) <= 0 || *dummy_p)) ||
+      (argc > width_pos && ((unsigned)(sscanf(argv[width_pos], "%lf%c %c", &p->width, &width_type, &dummy)-1) > 1 || p->width <= 0)) ||
+      (argc > gain_pos  && sscanf(argv[gain_pos], "%lf %c", &p->gain, &dummy) != 1) ||
+      !strchr(allowed_width_types, width_type) || (width_type == 's' && p->width > 1))
+    return lsx_usage(effp);
+  p->width_type = strchr(all_width_types, width_type) - all_width_types;
+  if ((size_t)p->width_type >= strlen(all_width_types))
+    p->width_type = 0;
+  if (p->width_type == width_bw_kHz) {
+    p->width *= 1000;
+    p->width_type = width_bw_Hz;
+  }
+  return SOX_SUCCESS;
+}
+
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  /* Simplify: */
+  p->b2 /= p->a0;
+  p->b1 /= p->a0;
+  p->b0 /= p->a0;
+  p->a2 /= p->a0;
+  p->a1 /= p->a0;
+
+  p->o2 = p->o1 = p->i2 = p->i1 = 0;
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+
+  start(effp);
+
+  if (effp->global_info->plot == sox_plot_octave) {
+    printf(
+      "%% GNU Octave file (may also work with MATLAB(R) )\n"
+      "Fs=%g;minF=10;maxF=Fs/2;\n"
+      "sweepF=logspace(log10(minF),log10(maxF),200);\n"
+      "[h,w]=freqz([%.15e %.15e %.15e],[1 %.15e %.15e],sweepF,Fs);\n"
+      "semilogx(w,20*log10(h))\n"
+      "title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)')\n"
+      "xlabel('Frequency (Hz)')\n"
+      "ylabel('Amplitude Response (dB)')\n"
+      "axis([minF maxF -35 25])\n"
+      "grid on\n"
+      "disp('Hit return to continue')\n"
+      "pause\n"
+      , effp->in_signal.rate, p->b0, p->b1, p->b2, p->a1, p->a2
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_gnuplot) {
+    printf(
+      "# gnuplot file\n"
+      "set title 'SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)'\n"
+      "set xlabel 'Frequency (Hz)'\n"
+      "set ylabel 'Amplitude Response (dB)'\n"
+      "Fs=%g\n"
+      "b0=%.15e; b1=%.15e; b2=%.15e; a1=%.15e; a2=%.15e\n"
+      "o=2*pi/Fs\n"
+      "H(f)=sqrt((b0*b0+b1*b1+b2*b2+2.*(b0*b1+b1*b2)*cos(f*o)+2.*(b0*b2)*cos(2.*f*o))/(1.+a1*a1+a2*a2+2.*(a1+a1*a2)*cos(f*o)+2.*a2*cos(2.*f*o)))\n"
+      "set logscale x\n"
+      "set samples 250\n"
+      "set grid xtics ytics\n"
+      "set key off\n"
+      "plot [f=10:Fs/2] [-35:25] 20*log10(H(f))\n"
+      "pause -1 'Hit return to continue'\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_data) {
+    printf("# SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)\n"
+      "# IIR filter\n"
+      "# rate: %g\n"
+      "# name: b\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      "# name: a\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, 1. /* a0 */, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
+    sox_sample_t *obuf, size_t *isamp, size_t *osamp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  size_t len = *isamp = *osamp = min(*isamp, *osamp);
+  while (len--) {
+    double o0 = *ibuf*p->b0 + p->i1*p->b1 + p->i2*p->b2 - p->o1*p->a1 - p->o2*p->a2;
+    p->i2 = p->i1, p->i1 = *ibuf++;
+    p->o2 = p->o1, p->o1 = o0;
+    *obuf++ = SOX_ROUND_CLIP_COUNT(o0, effp->clips);
+  }
+  return SOX_SUCCESS;
+}
+
+static int create(sox_effect_t * effp, int argc, char * * argv)
+{
+  priv_t             * p = (priv_t *)effp->priv;
+  double             * d = &p->b0;
+  char               c;
+
+  --argc, ++argv;
+  if (argc == 6)
+    for (; argc && sscanf(*argv, "%lf%c", d, &c) == 1; --argc, ++argv, ++d);
+  return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * lsx_biquad_effect_fn(void)
+{
+  static sox_effect_handler_t handler = {
+    "biquad", "b0 b1 b2 a0 a1 a2", 0,
+    create, lsx_biquad_start, lsx_biquad_flow, NULL, NULL, NULL, sizeof(priv_t)
+  };
+  return &handler;
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/biquad.h b/freedv/tags/1.2.2/freedv-dev/src/sox/biquad.h
new file mode 100644 (file)
index 0000000..8786ac8
--- /dev/null
@@ -0,0 +1,78 @@
+/* libSoX Biquad filter common definitions (c) 2006-7 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef biquad_included
+#define biquad_included
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+
+typedef enum {
+  filter_LPF,
+  filter_HPF,
+  filter_BPF_CSG,
+  filter_BPF,
+  filter_notch,
+  filter_APF,
+  filter_peakingEQ,
+  filter_lowShelf,
+  filter_highShelf,
+  filter_LPF_1,
+  filter_HPF_1,
+  filter_BPF_SPK,
+  filter_BPF_SPK_N,
+  filter_AP1,
+  filter_AP2,
+  filter_deemph,
+  filter_riaa
+} filter_t;
+
+typedef enum {
+  width_bw_Hz,
+  width_bw_kHz,
+  /* The old, non-RBJ, non-freq-warped band-pass/reject response;
+   * leaving here for now just in case anybody misses it: */
+  width_bw_old,
+  width_bw_oct,
+  width_Q,
+  width_slope
+} width_t;
+
+/* Private data for the biquad filter effects */
+typedef struct {
+  double gain;             /* For EQ filters */
+  double fc;               /* Centre/corner/cutoff frequency */
+  double width;            /* Filter width; interpreted as per width_type */
+  width_t width_type;
+
+  filter_t filter_type;
+
+  double b0, b1, b2;       /* Filter coefficients */
+  double a0, a1, a2;       /* Filter coefficients */
+
+  sox_sample_t i1, i2;     /* Filter memory */
+  double      o1, o2;      /* Filter memory */
+} biquad_t;
+
+int lsx_biquad_getopts(sox_effect_t * effp, int n, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type);
+int lsx_biquad_start(sox_effect_t * effp);
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
+                        size_t *isamp, size_t *osamp);
+
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/biquads.c b/freedv/tags/1.2.2/freedv-dev/src/sox/biquads.c
new file mode 100644 (file)
index 0000000..19793a6
--- /dev/null
@@ -0,0 +1,400 @@
+/* libSoX Biquad filter effects   (c) 2006-8 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
+ *   see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+ *
+ * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
+ *   Algorithms: Recursive single pole low/high pass filter
+ *   Reference: The Scientist and Engineer's Guide to Digital Signal Processing
+ *
+ *   low-pass: output[N] = input[N] * A + output[N-1] * B
+ *     X = exp(-2.0 * pi * Fc)
+ *     A = 1 - X
+ *     B = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC low-pass filter:
+ *
+ *     ---/\/\/\/\----------->
+ *                   |
+ *                  --- C
+ *                  ---
+ *                   |
+ *                   |
+ *                   V
+ *
+ *   high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
+ *     X  = exp(-2.0 * pi * Fc)
+ *     A0 = (1 + X) / 2
+ *     A1 = -(1 + X) / 2
+ *     B1 = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC high-pass filter:
+ *
+ *         || C
+ *     ----||--------->
+ *         ||    |
+ *               <
+ *               > R
+ *               <
+ *               |
+ *               V
+ */
+
+
+#include "biquad.h"
+#include <assert.h>
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+
+static int hilo1_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 1, 1, 0, 1, 2, "",
+      *effp->handler.name == 'l'? filter_LPF_1 : filter_HPF_1);
+}
+
+
+static int hilo2_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    return hilo1_getopts(effp, argc - 1, argv + 1);
+  if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc;
+  p->width = sqrt(0.5); /* Default to Butterworth */
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "qohk",
+      *effp->handler.name == 'l'? filter_LPF : filter_HPF);
+}
+
+
+static int bandpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF;
+  if (argc > 1 && strcmp(argv[1], "-c") == 0)
+    ++argv, --argc, type = filter_BPF_CSG;
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", type);
+}
+
+
+static int bandrej_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", filter_notch);
+}
+
+
+static int allpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_APF;
+  int m;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    ++argv, --argc, type = filter_AP1;
+  else if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc, type = filter_AP2;
+  m = 1 + (type == filter_APF);
+  return lsx_biquad_getopts(effp, argc, argv, m, m, 0, 1, 2, "hkqo", type);
+}
+
+
+static int tone_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->width = 0.5;
+  p->fc = *effp->handler.name == 'b'? 100 : 3000;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 3, 1, 2, 0, "shkqo",
+      *effp->handler.name == 'b'?  filter_lowShelf: filter_highShelf);
+}
+
+
+static int equalizer_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 3, 3, 0, 1, 2, "qohk", filter_peakingEQ);
+}
+
+
+static int band_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF_SPK;
+  if (argc > 1 && strcmp(argv[1], "-n") == 0)
+    ++argv, --argc, type = filter_BPF_SPK_N;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "hkqo", type);
+}
+
+
+static int deemph_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->fc    = 5283;
+  p->width = 0.4845;
+  p->gain  = -9.477;
+  return lsx_biquad_getopts(effp, argc, argv, 0, 0, 0, 1, 2, "s", filter_deemph);
+}
+
+
+static int riaa_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->filter_type = filter_riaa;
+  (void)argv;
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+
+static void make_poly_from_roots(
+    double const * roots, size_t num_roots, double * poly)
+{
+  size_t i, j;
+  poly[0] = 1;
+  poly[1] = -roots[0];
+  memset(poly + 2, 0, (num_roots + 1 - 2) * sizeof(*poly));
+  for (i = 1; i < num_roots; ++i)
+    for (j = num_roots; j > 0; --j)
+      poly[j] -= poly[j - 1] * roots[i];
+}
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  double w0 = 2 * M_PI * p->fc / effp->in_signal.rate;
+  double A  = exp(p->gain / 40 * log(10.));
+  double alpha = 0, mult = dB_to_linear(max(p->gain, 0));
+
+  if (w0 > M_PI) {
+    lsx_fail("frequency must be less than half the sample-rate (Nyquist rate)");
+    return SOX_EOF;
+  }
+
+  /* Set defaults: */
+  p->b0 = p->b1 = p->b2 = p->a1 = p->a2 = 0;
+  p->a0 = 1;
+
+  if (p->width) switch (p->width_type) {
+    case width_slope:
+      alpha = sin(w0)/2 * sqrt((A + 1/A)*(1/p->width - 1) + 2);
+      break;
+
+    case width_Q:
+      alpha = sin(w0)/(2*p->width);
+      break;
+
+    case width_bw_oct:
+      alpha = sin(w0)*sinh(log(2.)/2 * p->width * w0/sin(w0));
+      break;
+
+    case width_bw_Hz:
+      alpha = sin(w0)/(2*p->fc/p->width);
+      break;
+
+    case width_bw_kHz: assert(0); /* Shouldn't get here */
+
+    case width_bw_old:
+      alpha = tan(M_PI * p->width / effp->in_signal.rate);
+      break;
+  }
+  switch (p->filter_type) {
+    case filter_LPF: /* H(s) = 1 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 - cos(w0))/2;
+      p->b1 =   1 - cos(w0);
+      p->b2 =  (1 - cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_HPF: /* H(s) = s^2 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 + cos(w0))/2;
+      p->b1 = -(1 + cos(w0));
+      p->b2 =  (1 + cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF_CSG: /* H(s) = s / (s^2 + s/Q + 1)  (constant skirt gain, peak gain = Q) */
+      p->b0 =   sin(w0)/2;
+      p->b1 =   0;
+      p->b2 =  -sin(w0)/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF: /* H(s) = (s/Q) / (s^2 + s/Q + 1)      (constant 0 dB peak gain) */
+      p->b0 =   alpha;
+      p->b1 =   0;
+      p->b2 =  -alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_notch: /* H(s) = (s^2 + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_APF: /* H(s) = (s^2 - s/Q + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1 - alpha;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 + alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_peakingEQ: /* H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =   1 + alpha*A;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 - alpha*A;
+      p->a0 =   1 + alpha/A;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha/A;
+      break;
+
+    case filter_lowShelf: /* H(s) = A * (s^2 + (sqrt(A)/Q)*s + A)/(A*s^2 + (sqrt(A)/Q)*s + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 =  2*A*( (A-1) - (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =   -2*( (A-1) + (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_deemph:  /* See deemph.plt for documentation */
+      if (effp->in_signal.rate != 44100) {
+        lsx_fail("Sample rate must be 44100 (audio-CD)");
+        return SOX_EOF;
+      }
+      /* Falls through... */
+
+    case filter_highShelf: /* H(s) = A * (A*s^2 + (sqrt(A)/Q)*s + 1)/(s^2 + (sqrt(A)/Q)*s + A) */
+      if (!A)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 = -2*A*( (A-1) + (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =    2*( (A-1) - (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_LPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = 1 + p->a1;
+      break;
+
+    case filter_HPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = (1 - p->a1)/2;
+      p->b1 = -p->b0;
+      break;
+
+    case filter_BPF_SPK: case filter_BPF_SPK_N: {
+      double bw_Hz;
+      if (!p->width)
+        p->width = p->fc / 2;
+      bw_Hz = p->width_type == width_Q?  p->fc / p->width :
+        p->width_type == width_bw_Hz? p->width :
+        p->fc * (pow(2., p->width) - 1) * pow(2., -0.5 * p->width); /* bw_oct */
+      #include "band.h" /* Has different licence */
+      break;
+    }
+
+    case filter_AP1:     /* Experimental 1-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = exp(-w0);
+      p->b1 = -1;
+      p->a1 = -exp(-w0);
+      break;
+
+    case filter_AP2:     /* Experimental 2-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = 1 - sin(w0);
+      p->b1 = -2 * cos(w0);
+      p->b2 = 1 + sin(w0);
+      p->a0 = 1 + sin(w0);
+      p->a1 = -2 * cos(w0);
+      p->a2 = 1 - sin(w0);
+      break;
+
+    case filter_riaa: /* http://www.dsprelated.com/showmessage/73300/3.php */
+      if (effp->in_signal.rate == 44100) {
+        static const double zeros[] = {-0.2014898, 0.9233820};
+        static const double poles[] = {0.7083149, 0.9924091};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 48000) {
+        static const double zeros[] = {-0.1766069, 0.9321590};
+        static const double poles[] = {0.7396325, 0.9931330};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 88200) {
+        static const double zeros[] = {-0.1168735, 0.9648312};
+        static const double poles[] = {0.8590646, 0.9964002};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 96000) {
+        static const double zeros[] = {-0.1141486, 0.9676817};
+        static const double poles[] = {0.8699137, 0.9966946};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else {
+        lsx_fail("Sample rate must be 44.1k, 48k, 88.2k, or 96k");
+        return SOX_EOF;
+      }
+      { /* Normalise to 0dB at 1kHz (Thanks to Glenn Davis) */
+        double y = 2 * M_PI * 1000 / effp->in_signal.rate;
+        double b_re = p->b0 + p->b1 * cos(-y) + p->b2 * cos(-2 * y);
+        double a_re = p->a0 + p->a1 * cos(-y) + p->a2 * cos(-2 * y);
+        double b_im = p->b1 * sin(-y) + p->b2 * sin(-2 * y);
+        double a_im = p->a1 * sin(-y) + p->a2 * sin(-2 * y);
+        double g = 1 / sqrt((sqr(b_re) + sqr(b_im)) / (sqr(a_re) + sqr(a_im)));
+        p->b0 *= g; p->b1 *= g; p->b2 *= g;
+      }
+      mult = (p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2);
+      lsx_debug("gain=%f", linear_to_dB(mult));
+      break;
+  }
+  if (effp->in_signal.mult)
+    *effp->in_signal.mult /= mult;
+  return lsx_biquad_start(effp);
+}
+
+
+#define BIQUAD_EFFECT(name,group,usage,flags) \
+sox_effect_handler_t const * lsx_##name##_effect_fn(void) { \
+  static sox_effect_handler_t handler = { \
+    #name, usage, flags, \
+    group##_getopts, start, lsx_biquad_flow, 0, 0, 0, sizeof(biquad_t)\
+  }; \
+  return &handler; \
+}
+
+BIQUAD_EFFECT(highpass,  hilo2,    "[-1|-2] frequency [width[q|o|h|k](0.707q)]", 0)
+BIQUAD_EFFECT(lowpass,   hilo2,    "[-1|-2] frequency [width[q|o|h|k]](0.707q)", 0)
+BIQUAD_EFFECT(bandpass,  bandpass, "[-c] frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bandreject,bandrej,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(allpass,   allpass,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bass,      tone,     "gain [frequency(100) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(treble,    tone,     "gain [frequency(3000) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(equalizer, equalizer,"frequency width[q|o|h|k] gain", 0)
+BIQUAD_EFFECT(band,      band,     "[-n] center [width[h|k|q|o]]", 0)
+BIQUAD_EFFECT(deemph,    deemph,   NULL, 0)
+BIQUAD_EFFECT(riaa,      riaa,     NULL, 0)
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/effects.c b/freedv/tags/1.2.2/freedv-dev/src/sox/effects.c
new file mode 100644 (file)
index 0000000..435412f
--- /dev/null
@@ -0,0 +1,544 @@
+/* SoX Effects chain     (c) 2007 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <assert.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+  #include <strings.h>
+#endif
+
+#define DEBUG_EFFECTS_CHAIN 0
+
+/* Default effect handler functions for do-nothing situations: */
+
+static int default_function(sox_effect_t * effp UNUSED)
+{
+  return SOX_SUCCESS;
+}
+
+/* Pass through samples verbatim */
+int lsx_flow_copy(sox_effect_t * effp UNUSED, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp)
+{
+  *isamp = *osamp = min(*isamp, *osamp);
+  memcpy(obuf, ibuf, *isamp * sizeof(*obuf));
+  return SOX_SUCCESS;
+}
+
+/* Inform no more samples to drain */
+static int default_drain(sox_effect_t * effp UNUSED, sox_sample_t *obuf UNUSED, size_t *osamp)
+{
+  *osamp = 0;
+  return SOX_EOF;
+}
+
+/* Check that no parameters have been given */
+static int default_getopts(sox_effect_t * effp, int argc, char **argv UNUSED)
+{
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+/* Partially initialise the effect structure; signal info will come later */
+sox_effect_t * sox_create_effect(sox_effect_handler_t const * eh)
+{
+  sox_effect_t * effp = lsx_calloc(1, sizeof(*effp));
+  effp->obuf = NULL;
+
+  effp->global_info = sox_get_effects_globals();
+  effp->handler = *eh;
+  if (!effp->handler.getopts) effp->handler.getopts = default_getopts;
+  if (!effp->handler.start  ) effp->handler.start   = default_function;
+  if (!effp->handler.flow   ) effp->handler.flow    = lsx_flow_copy;
+  if (!effp->handler.drain  ) effp->handler.drain   = default_drain;
+  if (!effp->handler.stop   ) effp->handler.stop    = default_function;
+  if (!effp->handler.kill   ) effp->handler.kill    = default_function;
+
+  effp->priv = lsx_calloc(1, effp->handler.priv_size);
+
+  return effp;
+} /* sox_create_effect */
+
+int sox_effect_options(sox_effect_t *effp, int argc, char * const argv[])
+{
+  int result;
+
+  char * * argv2 = lsx_malloc((argc + 1) * sizeof(*argv2));
+  argv2[0] = (char *)effp->handler.name;
+  memcpy(argv2 + 1, argv, argc * sizeof(*argv2));
+  result = effp->handler.getopts(effp, argc + 1, argv2);
+  free(argv2);
+  return result;
+} /* sox_effect_options */
+
+/* Effects chain: */
+
+sox_effects_chain_t * sox_create_effects_chain(
+    sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc)
+{
+  sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t));
+  result->global_info = *sox_get_effects_globals();
+  result->in_enc = in_enc;
+  result->out_enc = out_enc;
+  return result;
+} /* sox_create_effects_chain */
+
+void sox_delete_effects_chain(sox_effects_chain_t *ecp)
+{
+    if (ecp && ecp->length)
+        sox_delete_effects(ecp);
+    free(ecp->effects);
+    free(ecp);
+} /* sox_delete_effects_chain */
+
+/* Effect can call in start() or flow() to set minimum input size to flow() */
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin)
+{
+  if (imin > sox_globals.bufsiz / effp->flows) {
+    lsx_fail("sox_bufsiz not big enough");
+    return SOX_EOF;
+  }
+
+  effp->imin = imin;
+  return SOX_SUCCESS;
+}
+
+/* Effects table to be extended in steps of EFF_TABLE_STEP */
+#define EFF_TABLE_STEP 8
+
+/* Add an effect to the chain. *in is the input signal for this effect. *out is
+ * a suggestion as to what the output signal should be, but depending on its
+ * given options and *in, the effect can choose to do differently.  Whatever
+ * output rate and channels the effect does produce are written back to *in,
+ * ready for the next effect in the chain.
+ */
+int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out)
+{
+  int ret, (*start)(sox_effect_t * effp) = effp->handler.start;
+  unsigned f;
+  sox_effect_t eff0;  /* Copy of effect for flow 0 before calling start */
+
+  effp->global_info = &chain->global_info;
+  effp->in_signal = *in;
+  effp->out_signal = *out;
+  effp->in_encoding = chain->in_enc;
+  effp->out_encoding = chain->out_enc;
+  if (!(effp->handler.flags & SOX_EFF_CHAN))
+    effp->out_signal.channels = in->channels;
+  if (!(effp->handler.flags & SOX_EFF_RATE))
+    effp->out_signal.rate = in->rate;
+  if (!(effp->handler.flags & SOX_EFF_PREC))
+    effp->out_signal.precision = (effp->handler.flags & SOX_EFF_MODIFY)?
+        in->precision : SOX_SAMPLE_PRECISION;
+  if (!(effp->handler.flags & SOX_EFF_GAIN))
+    effp->out_signal.mult = in->mult;
+
+  effp->flows =
+    (effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels;
+  effp->clips = 0;
+  effp->imin = 0;
+  eff0 = *effp, eff0.priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+  eff0.in_signal.mult = NULL; /* Only used in channel 0 */
+  ret = start(effp);
+  if (ret == SOX_EFF_NULL) {
+    lsx_report("has no effect in this configuration");
+    free(eff0.priv);
+    free(effp->priv);
+    effp->priv = NULL;
+    return SOX_SUCCESS;
+  }
+  if (ret != SOX_SUCCESS) {
+    free(eff0.priv);
+    return SOX_EOF;
+  }
+  if (in->mult)
+    lsx_debug("mult=%g", *in->mult);
+
+  if (!(effp->handler.flags & SOX_EFF_LENGTH)) {
+    effp->out_signal.length = in->length;
+    if (effp->out_signal.length != SOX_UNKNOWN_LEN) {
+      if (effp->handler.flags & SOX_EFF_CHAN)
+        effp->out_signal.length =
+          effp->out_signal.length / in->channels * effp->out_signal.channels;
+      if (effp->handler.flags & SOX_EFF_RATE)
+        effp->out_signal.length =
+          effp->out_signal.length / in->rate * effp->out_signal.rate + .5;
+    }
+  }
+
+  *in = effp->out_signal;
+
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_add_effect: extending effects table, "
+      "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length] =
+    lsx_calloc(effp->flows, sizeof(chain->effects[chain->length][0]));
+  chain->effects[chain->length][0] = *effp;
+
+  for (f = 1; f < effp->flows; ++f) {
+    chain->effects[chain->length][f] = eff0;
+    chain->effects[chain->length][f].flow = f;
+    chain->effects[chain->length][f].priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+    if (start(&chain->effects[chain->length][f]) != SOX_SUCCESS) {
+      free(eff0.priv);
+      return SOX_EOF;
+    }
+  }
+
+  ++chain->length;
+  free(eff0.priv);
+  return SOX_SUCCESS;
+}
+
+static int flow_effect(sox_effects_chain_t * chain, size_t n)
+{
+  sox_effect_t * effp1 = &chain->effects[n - 1][0];
+  sox_effect_t * effp = &chain->effects[n][0];
+  int effstatus = SOX_SUCCESS, f = 0;
+  size_t i;
+  const sox_sample_t *ibuf;
+  size_t idone = effp1->oend - effp1->obeg;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#if DEBUG_EFFECTS_CHAIN
+  size_t pre_idone = idone;
+  size_t pre_odone = obeg;
+#endif
+
+  if (effp->flows == 1) {     /* Run effect on all channels at once */
+    idone -= idone % effp->in_signal.channels;
+    effstatus = effp->handler.flow(effp, &effp1->obuf[effp1->obeg],
+                                   &effp->obuf[effp->oend], &idone, &obeg);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect flowed asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {               /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    size_t idone_last = 0, odone_last = 0; /* Initialised to prevent warning */
+
+    ibuf = &effp1->obuf[effp1->obeg];
+    for (i = 0; i < idone; i += effp->flows)
+      for (f = 0; f < (int)effp->flows; ++f)
+        chain->ibufc[f][i / effp->flows] = *ibuf++;
+
+#ifdef HAVE_OPENMP
+    if (sox_globals.use_threads && effp->flows > 1)
+    {
+      #pragma omp parallel for
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (!f) {
+          idone_last = idonec;
+          odone_last = odonec;
+        }
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+    else /* sox_globals.use_threads */
+#endif
+    {
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (f && (idonec != idone_last || odonec != odone_last)) {
+          lsx_fail("flowed asymmetrically!");
+          effstatus = SOX_EOF;
+        }
+        idone_last = idonec;
+        odone_last = odonec;
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+
+    for (i = 0; i < odone_last; ++i)
+      for (f = 0; f < (int)effp->flows; ++f)
+        *obuf++ = chain->obufc[f][i];
+
+    idone = effp->flows * idone_last;
+    obeg = effp->flows * odone_last;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("flow:  %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      pre_idone, pre_odone, idone, obeg);
+#endif
+  effp1->obeg += idone;
+  if (effp1->obeg == effp1->oend)
+    effp1->obeg = effp1->oend = 0;
+  else if (effp1->oend - effp1->obeg < effp->imin ) { /* Need to refill? */
+    memmove(effp1->obuf, &effp1->obuf[effp1->obeg], (effp1->oend - effp1->obeg) * sizeof(*effp1->obuf));
+    effp1->oend -= effp1->obeg;
+    effp1->obeg = 0;
+  }
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* The same as flow_effect but with no input */
+static int drain_effect(sox_effects_chain_t * chain, size_t n)
+{
+  sox_effect_t * effp = &chain->effects[n][0];
+  int effstatus = SOX_SUCCESS;
+  size_t i, f;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#if DEBUG_EFFECTS_CHAIN
+  size_t pre_odone = obeg;
+#endif
+
+  if (effp->flows == 1) { /* Run effect on all channels at once */
+    effstatus = effp->handler.drain(effp, &effp->obuf[effp->oend], &obeg);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect drained asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {                       /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    size_t odone_last = 0; /* Initialised to prevent warning */
+
+    for (f = 0; f < effp->flows; ++f) {
+      size_t odonec = obeg / effp->flows;
+      int eff_status_c = effp->handler.drain(&chain->effects[n][f], chain->obufc[f], &odonec);
+      if (f && (odonec != odone_last)) {
+        lsx_fail("drained asymmetrically!");
+        effstatus = SOX_EOF;
+      }
+      odone_last = odonec;
+
+      if (eff_status_c != SOX_SUCCESS)
+        effstatus = SOX_EOF;
+    }
+
+    for (i = 0; i < odone_last; ++i)
+      for (f = 0; f < effp->flows; ++f)
+        *obuf++ = chain->obufc[f][i];
+    obeg = f * odone_last;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("drain: %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      (size_t)0, pre_odone, (size_t)0, obeg);
+#endif
+  if (!obeg)   /* This is the only thing that drain has and flow hasn't */
+    effstatus = SOX_EOF;
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* Flow data through the effects chain until an effect or callback gives EOF */
+int sox_flow_effects(sox_effects_chain_t * chain, int (* callback)(sox_bool all_done, void * client_data), void * client_data)
+{
+  int flow_status = SOX_SUCCESS;
+  size_t e, source_e = 0;               /* effect indices */
+  size_t f, max_flows = 0;
+  sox_bool draining = sox_true;
+
+  for (e = 0; e < chain->length; ++e) {
+    chain->effects[e][0].obuf = lsx_realloc(chain->effects[e][0].obuf,
+        sox_globals.bufsiz * sizeof(chain->effects[e][0].obuf[0]));
+      /* Possibly there is already a buffer, if this is a used effect;
+         it may still contain samples in that case. */
+      /* Memory will be freed by sox_delete_effect() later. */
+    max_flows = max(max_flows, chain->effects[e][0].flows);
+  }
+  if (max_flows == 1) /* don't need interleave buffers */
+    max_flows = 0;
+  chain->ibufc = lsx_calloc(max_flows, sizeof(*chain->ibufc));
+  chain->obufc = lsx_calloc(max_flows, sizeof(*chain->obufc));
+  for (f = 0; f < max_flows; ++f) {
+    chain->ibufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->ibufc[f][0]));
+    chain->obufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->obufc[f][0]));
+  }
+
+  e = chain->length - 1;
+  while (source_e < chain->length) {
+#define have_imin (e > 0 && e < chain->length && chain->effects[e - 1][0].oend - chain->effects[e - 1][0].obeg >= chain->effects[e][0].imin)
+    size_t osize = chain->effects[e][0].oend - chain->effects[e][0].obeg;
+    if (e == source_e && (draining || !have_imin)) {
+      if (drain_effect(chain, e) == SOX_EOF) {
+        ++source_e;
+        draining = sox_false;
+      }
+    } else if (have_imin && flow_effect(chain, e) == SOX_EOF) {
+      flow_status = SOX_EOF;
+      if (e == chain->length - 1)
+        break;
+      source_e = e;
+      draining = sox_true;
+    }
+    if (e < chain->length && chain->effects[e][0].oend - chain->effects[e][0].obeg > osize) /* False for output */
+      ++e;
+    else if (e == source_e)
+      draining = sox_true;
+    else if ((int)--e < (int)source_e)
+      e = source_e;
+
+    if (callback && callback(source_e == chain->length, client_data) != SOX_SUCCESS) {
+      flow_status = SOX_EOF; /* Client has requested to stop the flow. */
+      break;
+    }
+  }
+
+  for (f = 0; f < max_flows; ++f) {
+    free(chain->ibufc[f]);
+    free(chain->obufc[f]);
+  }
+  free(chain->obufc);
+  free(chain->ibufc);
+
+  return flow_status;
+}
+
+sox_uint64_t sox_effects_clips(sox_effects_chain_t * chain)
+{
+  unsigned i, f;
+  uint64_t clips = 0;
+  for (i = 1; i < chain->length - 1; ++i)
+    for (f = 0; f < chain->effects[i][0].flows; ++f)
+      clips += chain->effects[i][f].clips;
+  return clips;
+}
+
+sox_uint64_t sox_stop_effect(sox_effect_t *effp)
+{
+  unsigned f;
+  uint64_t clips = 0;
+
+  for (f = 0; f < effp->flows; ++f) {
+    effp[f].handler.stop(&effp[f]);
+    clips += effp[f].clips;
+  }
+  return clips;
+}
+
+void sox_push_effect_last(sox_effects_chain_t *chain, sox_effect_t *effp)
+{
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_push_effect_last: extending effects table, "
+        "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length++] = effp;
+} /* sox_push_effect_last */
+
+sox_effect_t *sox_pop_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    sox_effect_t *effp;
+    chain->length--;
+    effp = chain->effects[chain->length];
+    chain->effects[chain->length] = NULL;
+    return effp;
+  }
+  else
+    return NULL;
+} /* sox_pop_effect_last */
+
+/* Free resources related to effect.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effect(sox_effect_t *effp)
+{
+  uint64_t clips;
+  unsigned f;
+
+  if ((clips = sox_stop_effect(effp)) != 0)
+    lsx_warn("%s clipped %" PRIu64 " samples; decrease volume?",
+        effp->handler.name, clips);
+  if (effp->obeg != effp->oend)
+    lsx_debug("output buffer still held %" PRIuPTR " samples; dropped.",
+        (effp->oend - effp->obeg)/effp->out_signal.channels);
+      /* May or may not indicate a problem; it is normal if the user aborted
+         processing, or if an effect like "trim" stopped early. */
+  effp->handler.kill(effp); /* N.B. only one kill; not one per flow */
+  for (f = 0; f < effp->flows; ++f)
+    free(effp[f].priv);
+  free(effp->obuf);
+  free(effp);
+}
+
+void sox_delete_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    chain->length--;
+    sox_delete_effect(chain->effects[chain->length]);
+    chain->effects[chain->length] = NULL;
+  }
+} /* sox_delete_effect_last */
+
+/* Remove all effects from the chain.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effects(sox_effects_chain_t * chain)
+{
+  size_t e;
+
+  for (e = 0; e < chain->length; ++e) {
+    sox_delete_effect(chain->effects[e]);
+    chain->effects[e] = NULL;
+  }
+  chain->length = 0;
+}
+
+/*----------------------------- Effects library ------------------------------*/
+
+static sox_effect_fn_t s_sox_effect_fns[] = {
+#define EFFECT(f) lsx_##f##_effect_fn,
+#include "effects.h"
+#undef EFFECT
+  NULL
+};
+
+const sox_effect_fn_t*
+sox_get_effect_fns(void)
+{
+    return s_sox_effect_fns;
+}
+
+/* Find a named effect in the effects library */
+sox_effect_handler_t const * sox_find_effect(char const * name)
+{
+  int e;
+  sox_effect_fn_t const * fns = sox_get_effect_fns();
+  for (e = 0; fns[e]; ++e) {
+    const sox_effect_handler_t *eh = fns[e] ();
+    if (eh && eh->name && strcasecmp(eh->name, name) == 0)
+      return eh;                 /* Found it. */
+  }
+  return NULL;
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/effects.h b/freedv/tags/1.2.2/freedv-dev/src/sox/effects.h
new file mode 100644 (file)
index 0000000..8d7025c
--- /dev/null
@@ -0,0 +1,22 @@
+/* This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/* Manually edited for FreeDV to contain just the effects we need */
+
+  EFFECT(bass)
+  EFFECT(highpass)
+  EFFECT(treble)
+  EFFECT(equalizer)
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/effects_i.c b/freedv/tags/1.2.2/freedv-dev/src/sox/effects_i.c
new file mode 100644 (file)
index 0000000..e5770a9
--- /dev/null
@@ -0,0 +1,379 @@
+/* Implements a libSoX internal interface for implementing effects.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * Copyright (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <string.h>
+#include <ctype.h>
+
+int lsx_usage(sox_effect_t * effp)
+{
+  if (effp->handler.usage)
+    lsx_fail("usage: %s", effp->handler.usage);
+  else
+    lsx_fail("this effect takes no parameters");
+  return SOX_EOF;
+}
+
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n)
+{
+  if (!*usage) {
+    size_t i, len;
+    for (len = i = 0; i < n; len += strlen(lines[i++]) + 1);
+    *usage = lsx_malloc(len); /* FIXME: this memory will never be freed */
+    strcpy(*usage, lines[0]);
+    for (i = 1; i < n; ++i) {
+      strcat(*usage, "\n");
+      strcat(*usage, lines[i]);
+    }
+  }
+  return *usage;
+}
+
+static lsx_enum_item const s_lsx_wave_enum[] = {
+  LSX_ENUM_ITEM(SOX_WAVE_,SINE)
+  LSX_ENUM_ITEM(SOX_WAVE_,TRIANGLE)
+  {0, 0}};
+
+lsx_enum_item const * lsx_get_wave_enum(void)
+{
+  return s_lsx_wave_enum;
+}
+
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void *table,
+    size_t table_size,
+    double min,
+    double max,
+    double phase)
+{
+  uint32_t t;
+  uint32_t phase_offset = phase / M_PI / 2 * table_size + 0.5;
+
+  for (t = 0; t < table_size; t++)
+  {
+    uint32_t point = (t + phase_offset) % table_size;
+    double d;
+    switch (wave_type)
+    {
+      case SOX_WAVE_SINE:
+      d = (sin((double)point / table_size * 2 * M_PI) + 1) / 2;
+      break;
+
+      case SOX_WAVE_TRIANGLE:
+      d = (double)point * 2 / table_size;
+      switch (4 * point / table_size)
+      {
+        case 0:         d = d + 0.5; break;
+        case 1: case 2: d = 1.5 - d; break;
+        case 3:         d = d - 1.5; break;
+      }
+      break;
+
+      default: /* Oops! FIXME */
+        d = 0.0; /* Make sure we have a value */
+      break;
+    }
+    d  = d * (max - min) + min;
+    switch (data_type)
+    {
+      case SOX_FLOAT:
+        {
+          float *fp = (float *)table;
+          *fp++ = (float)d;
+          table = fp;
+          continue;
+        }
+      case SOX_DOUBLE:
+        {
+          double *dp = (double *)table;
+          *dp++ = d;
+          table = dp;
+          continue;
+        }
+      default: break;
+    }
+    d += d < 0? -0.5 : +0.5;
+    switch (data_type)
+    {
+      case SOX_SHORT:
+        {
+          short *sp = table;
+          *sp++ = (short)d;
+          table = sp;
+          continue;
+        }
+      case SOX_INT:
+        {
+          int *ip = table;
+          *ip++ = (int)d;
+          table = ip;
+          continue;
+        }
+      default: break;
+    }
+  }
+}
+
+/*
+ * lsx_parsesamples
+ *
+ * Parse a string for # of samples.  If string ends with a 's'
+ * then the string is interpreted as a user calculated # of samples.
+ * If string contains ':' or '.' or if it ends with a 't' then its
+ * treated as an amount of time.  This is converted into seconds and
+ * fraction of seconds and then use the sample rate to calculate
+ * # of samples.
+ * Returns NULL on error, pointer to next char to parse otherwise.
+ */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str0, uint64_t *samples, int def)
+{
+  int i, found_samples = 0, found_time = 0;
+  char const * end;
+  char const * pos;
+  sox_bool found_colon, found_dot;
+  char * str = (char *)str0;
+
+  for (;*str == ' '; ++str);
+  for (end = str; *end && strchr("0123456789:.ets", *end); ++end);
+  if (end == str)
+    return NULL;
+
+  pos = strchr(str, ':');
+  found_colon = pos && pos < end;
+
+  pos = strchr(str, '.');
+  found_dot = pos && pos < end;
+
+  if (found_colon || found_dot || *(end-1) == 't')
+    found_time = 1;
+  else if (*(end-1) == 's')
+    found_samples = 1;
+
+  if (found_time || (def == 't' && !found_samples)) {
+    for (*samples = 0, i = 0; *str != '.' && i < 3; ++i) {
+      char * last_str = str;
+      long part = strtol(str, &str, 10);
+      if (!i && str == last_str)
+        return NULL;
+      *samples += rate * part;
+      if (i < 2) {
+        if (*str != ':')
+          break;
+        ++str;
+        *samples *= 60;
+      }
+    }
+    if (*str == '.') {
+      char * last_str = str;
+      double part = strtod(str, &str);
+      if (str == last_str)
+        return NULL;
+      *samples += rate * part + .5;
+    }
+    return *str == 't'? str + 1 : str;
+  }
+  {
+    char * last_str = str;
+    double part = strtod(str, &str);
+    if (str == last_str)
+      return NULL;
+    *samples = part + .5;
+    return *str == 's'? str + 1 : str;
+  }
+}
+
+#if 0
+
+#include <assert.h>
+
+#define TEST(st, samp, len) \
+  str = st; \
+  next = lsx_parsesamples(10000, str, &samples, 't'); \
+  assert(samples == samp && next == str + len);
+
+int main(int argc, char * * argv)
+{
+  char const * str, * next;
+  uint64_t samples;
+
+  TEST("0"  , 0, 1)
+  TEST("1" , 10000, 1)
+
+  TEST("0s" , 0, 2)
+  TEST("0s,", 0, 2)
+  TEST("0s/", 0, 2)
+  TEST("0s@", 0, 2)
+
+  TEST("0t" , 0, 2)
+  TEST("0t,", 0, 2)
+  TEST("0t/", 0, 2)
+  TEST("0t@", 0, 2)
+
+  TEST("1s" , 1, 2)
+  TEST("1s,", 1, 2)
+  TEST("1s/", 1, 2)
+  TEST("1s@", 1, 2)
+  TEST(" 01s" , 1, 4)
+  TEST("1e6s" , 1000000, 4)
+
+  TEST("1t" , 10000, 2)
+  TEST("1t,", 10000, 2)
+  TEST("1t/", 10000, 2)
+  TEST("1t@", 10000, 2)
+  TEST("1.1t" , 11000, 4)
+  TEST("1.1t,", 11000, 4)
+  TEST("1.1t/", 11000, 4)
+  TEST("1.1t@", 11000, 4)
+  TEST("1e6t" , 10000, 1)
+
+  TEST(".0", 0, 2)
+  TEST("0.0", 0, 3)
+  TEST("0:0.0", 0, 5)
+  TEST("0:0:0.0", 0, 7)
+
+  TEST(".1", 1000, 2)
+  TEST(".10", 1000, 3)
+  TEST("0.1", 1000, 3)
+  TEST("1.1", 11000, 3)
+  TEST("1:1.1", 611000, 5)
+  TEST("1:1:1.1", 36611000, 7)
+  TEST("1:1", 610000, 3)
+  TEST("1:01", 610000, 4)
+  TEST("1:1:1", 36610000, 5)
+  TEST("1:", 600000, 2)
+  TEST("1::", 36000000, 3)
+
+  TEST("0.444444", 4444, 8)
+  TEST("0.555555", 5556, 8)
+
+  assert(!lsx_parsesamples(10000, "x", &samples, 't'));
+  return 0;
+}
+#endif 
+
+/* a note is given as an int,
+ * 0   => 440 Hz = A
+ * >0  => number of half notes 'up',
+ * <0  => number of half notes down,
+ * example 12 => A of next octave, 880Hz
+ *
+ * calculated by freq = 440Hz * 2**(note/12)
+ */
+static double calc_note_freq(double note, int key)
+{
+  if (key != INT_MAX) {                         /* Just intonation. */
+    static const int n[] = {16, 9, 6, 5, 4, 7}; /* Numerator. */
+    static const int d[] = {15, 8, 5, 4, 3, 5}; /* Denominator. */
+    static double j[13];                        /* Just semitones */
+    int i, m = floor(note);
+
+    if (!j[1]) for (i = 1; i <= 12; ++i)
+      j[i] = i <= 6? log((double)n[i - 1] / d[i - 1]) / log(2.) : 1 - j[12 - i];
+    note -= m;
+    m -= key = m - ((INT_MAX / 2 - ((INT_MAX / 2) % 12) + m - key) % 12);
+    return 440 * pow(2., key / 12. + j[m] + (j[m + 1] - j[m]) * note);
+  }
+  return 440 * pow(2., note / 12);
+}
+
+int lsx_parse_note(char const * text, char * * end_ptr)
+{
+  int result = INT_MAX;
+
+  if (*text >= 'A' && *text <= 'G') {
+    result = (int)(5/3. * (*text++ - 'A') + 9.5) % 12 - 9;
+    if (*text == 'b') {--result; ++text;}
+    else if (*text == '#') {++result; ++text;}
+    if (isdigit((unsigned char)*text))
+      result += 12 * (*text++ - '4'); 
+  }
+  *end_ptr = (char *)text;
+  return result;
+}
+
+/* Read string 'text' and convert to frequency.
+ * 'text' can be a positive number which is the frequency in Hz.
+ * If 'text' starts with a '%' and a following number the corresponding
+ * note is calculated.
+ * Return -1 on error.
+ */
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key)
+{
+  double result;
+
+  if (*text == '%') {
+    result = strtod(text + 1, end_ptr);
+    if (*end_ptr == text + 1)
+      return -1;
+    return calc_note_freq(result, key);
+  }
+  if (*text >= 'A' && *text <= 'G') {
+    int result2 = lsx_parse_note(text, end_ptr);
+    return result2 == INT_MAX? - 1 : calc_note_freq((double)result2, key);
+  }
+  result = strtod(text, end_ptr);
+  if (end_ptr) {
+    if (*end_ptr == text)
+      return -1;
+    if (**end_ptr == 'k') {
+      result *= 1000;
+      ++*end_ptr;
+    }
+  }
+  return result < 0 ? -1 : result;
+}
+
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename)
+{
+  FILE * file;
+
+  if (!filename || !strcmp(filename, "-")) {
+    if (effp->global_info->global_info->stdin_in_use_by) {
+      lsx_fail("stdin already in use by `%s'", effp->global_info->global_info->stdin_in_use_by);
+      return NULL;
+    }
+    effp->global_info->global_info->stdin_in_use_by = effp->handler.name;
+    file = stdin;
+  }
+  else if (!(file = fopen(filename, "r"))) {
+    lsx_fail("couldn't open file %s: %s", filename, strerror(errno));
+    return NULL;
+  }
+  return file;
+}
+
+int lsx_effects_init(void)
+{
+  #ifndef __FREEDV__
+  init_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
+
+int lsx_effects_quit(void)
+{
+  #ifndef __FREEDV__
+  clear_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/formats_i.c b/freedv/tags/1.2.2/freedv-dev/src/sox/formats_i.c
new file mode 100644 (file)
index 0000000..17c4061
--- /dev/null
@@ -0,0 +1,487 @@
+/* Implements a libSoX internal interface for use in implementing file formats.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <string.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+
+void lsx_fail_errno(sox_format_t * ft, int sox_errno, const char *fmt, ...)
+{
+  va_list args;
+
+  ft->sox_errno = sox_errno;
+
+  va_start(args, fmt);
+#ifdef HAVE_VSNPRINTF
+  vsnprintf(ft->sox_errstr, sizeof(ft->sox_errstr), fmt, args);
+#else
+  vsprintf(ft->sox_errstr, fmt, args);
+#endif
+  va_end(args);
+  ft->sox_errstr[255] = '\0';
+}
+
+void lsx_set_signal_defaults(sox_format_t * ft)
+{
+  if (!ft->signal.rate     ) ft->signal.rate      = SOX_DEFAULT_RATE;
+  if (!ft->signal.precision) ft->signal.precision = SOX_DEFAULT_PRECISION;
+  if (!ft->signal.channels ) ft->signal.channels  = SOX_DEFAULT_CHANNELS;
+
+  if (!ft->encoding.bits_per_sample)
+    ft->encoding.bits_per_sample = ft->signal.precision;
+  if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+    ft->encoding.encoding = SOX_ENCODING_SIGN2;
+}
+
+#ifndef __FREEDV__
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length)
+{
+  ft->signal.length = ft->signal.length == SOX_IGNORE_LENGTH? SOX_UNSPEC : num_samples;
+
+  if (ft->seekable)
+    ft->data_start = lsx_tell(ft);
+
+  if (channels && ft->signal.channels && ft->signal.channels != channels)
+    lsx_warn("`%s': overriding number of channels", ft->filename);
+  else ft->signal.channels = channels;
+
+  if (rate && ft->signal.rate && ft->signal.rate != rate)
+    lsx_warn("`%s': overriding sample rate", ft->filename);
+  else ft->signal.rate = rate;
+
+  if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding)
+    lsx_warn("`%s': overriding encoding type", ft->filename);
+  else ft->encoding.encoding = encoding;
+
+  if (bits_per_sample && ft->encoding.bits_per_sample && ft->encoding.bits_per_sample != bits_per_sample)
+    lsx_warn("`%s': overriding encoding size", ft->filename);
+  ft->encoding.bits_per_sample = bits_per_sample;
+
+  if (check_length && ft->encoding.bits_per_sample && lsx_filelength(ft)) {
+    uint64_t calculated_length = div_bits(lsx_filelength(ft) - ft->data_start, ft->encoding.bits_per_sample);
+    if (!ft->signal.length)
+      ft->signal.length = calculated_length;
+    else if (num_samples != calculated_length)
+      lsx_warn("`%s': file header gives the total number of samples as %" PRIu64 " but file length indicates the number is in fact %" PRIu64, ft->filename, num_samples, calculated_length);
+  }
+
+  if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
+    return SOX_SUCCESS;
+  lsx_fail_errno(ft, EINVAL, "invalid format for this file type");
+  return SOX_EOF;
+}
+#endif
+
+/* Read in a buffer of data of length len bytes.
+ * Returns number of bytes read.
+ */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len)
+{
+  size_t ret = fread(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len && ferror((FILE*)ft->fp))
+    lsx_fail_errno(ft, errno, "lsx_readbuf");
+  ft->tell_off += ret;
+  return ret;
+}
+
+/* Skip input without seeking. */
+int lsx_skipbytes(sox_format_t * ft, size_t n)
+{
+  unsigned char trash;
+
+  while (n--)
+    if (lsx_readb(ft, &trash) == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Pad output. */
+int lsx_padbytes(sox_format_t * ft, size_t n)
+{
+  while (n--)
+    if (lsx_writeb(ft, '\0') == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Write a buffer of data of length bytes.
+ * Returns number of bytes written.
+ */
+size_t lsx_writebuf(sox_format_t * ft, void const * buf, size_t len)
+{
+  size_t ret = fwrite(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len) {
+    lsx_fail_errno(ft, errno, "error writing output file");
+    clearerr((FILE*)ft->fp); /* Allows us to seek back to write header */
+  }
+  ft->tell_off += ret;
+  return ret;
+}
+
+uint64_t lsx_filelength(sox_format_t * ft)
+{
+  struct stat st;
+  int ret = fstat(fileno((FILE*)ft->fp), &st);
+
+  return (!ret && (st.st_mode & S_IFREG))? (uint64_t)st.st_size : 0;
+}
+
+int lsx_flush(sox_format_t * ft)
+{
+  return fflush((FILE*)ft->fp);
+}
+
+off_t lsx_tell(sox_format_t * ft)
+{
+  return ft->seekable? (off_t)ftello((FILE*)ft->fp) : (off_t)ft->tell_off;
+}
+
+int lsx_eof(sox_format_t * ft)
+{
+  return feof((FILE*)ft->fp);
+}
+
+int lsx_error(sox_format_t * ft)
+{
+  return ferror((FILE*)ft->fp);
+}
+
+void lsx_rewind(sox_format_t * ft)
+{
+  rewind((FILE*)ft->fp);
+  ft->tell_off = 0;
+}
+
+void lsx_clearerr(sox_format_t * ft)
+{
+  clearerr((FILE*)ft->fp);
+  ft->sox_errno = 0;
+}
+
+int lsx_unreadb(sox_format_t * ft, unsigned b)
+{
+  return ungetc((int)b, ft->fp);
+}
+
+/* Implements traditional fseek() behavior.  Meant to abstract out
+ * file operations so that they could one day also work on memory
+ * buffers.
+ *
+ * N.B. Can only seek forwards on non-seekable streams!
+ */
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence)
+{
+    if (ft->seekable == 0) {
+        /* If a stream peel off chars else EPERM */
+        if (whence == SEEK_CUR) {
+            while (offset > 0 && !feof((FILE*)ft->fp)) {
+                getc((FILE*)ft->fp);
+                offset--;
+                ++ft->tell_off;
+            }
+            if (offset)
+                lsx_fail_errno(ft,SOX_EOF, "offset past EOF");
+            else
+                ft->sox_errno = SOX_SUCCESS;
+        } else
+            lsx_fail_errno(ft,SOX_EPERM, "file not seekable");
+    } else {
+        if (fseeko((FILE*)ft->fp, offset, whence) == -1)
+            lsx_fail_errno(ft,errno, "%s", strerror(errno));
+        else
+            ft->sox_errno = SOX_SUCCESS;
+    }
+    return ft->sox_errno;
+}
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample)
+{
+  double wide_sample = to_sample - (to_sample % ft->signal.channels);
+  double to_d = wide_sample * ft->encoding.bits_per_sample / 8;
+  off_t to = to_d;
+  return (to != to_d)? SOX_EOF : lsx_seeki(ft, (byte_offset + to), SEEK_SET);
+}
+
+/* Read and write known datatypes in "machine format".  Swap if indicated.
+ * They all return SOX_EOF on error and SOX_SUCCESS on success.
+ */
+/* Read n-char string (and possibly null-terminating).
+ * Stop reading and null-terminate string if either a 0 or \n is reached.
+ */
+int lsx_reads(sox_format_t * ft, char *c, size_t len)
+{
+    char *sc;
+    char in;
+
+    sc = c;
+    do
+    {
+        if (lsx_readbuf(ft, &in, (size_t)1) != 1)
+        {
+            *sc = 0;
+            return (SOX_EOF);
+        }
+        if (in == 0 || in == '\n')
+            break;
+
+        *sc = in;
+        sc++;
+    } while (sc - c < (ptrdiff_t)len);
+    *sc = 0;
+    return(SOX_SUCCESS);
+}
+
+/* Write null-terminated string (without \0). */
+int lsx_writes(sox_format_t * ft, char const * c)
+{
+        if (lsx_writebuf(ft, c, strlen(c)) != strlen(c))
+                return(SOX_EOF);
+        return(SOX_SUCCESS);
+}
+
+/* return swapped 32-bit float */
+static void lsx_swapf(float * f)
+{
+    union {
+        uint32_t dw;
+        float f;
+    } u;
+
+    u.f= *f;
+    u.dw= (u.dw>>24) | ((u.dw>>8)&0xff00) | ((u.dw<<8)&0xff0000) | (u.dw<<24);
+    *f = u.f;
+}
+
+static void swap(void * data, size_t len)
+{
+  uint8_t * bytes = (uint8_t *)data;
+  size_t i;
+
+  for (i = 0; i < len / 2; ++i) {
+    char tmp = bytes[i];
+    bytes[i] = bytes[len - 1 - i];
+    bytes[len - 1 - i] = tmp;
+  }
+}
+
+static double lsx_swapdf(double data)
+{
+  swap(&data, sizeof(data));
+  return data;
+}
+
+static uint64_t lsx_swapqw(uint64_t data)
+{
+  swap(&data, sizeof(data));
+  return data;
+}
+
+/* Lookup table to reverse the bit order of a byte. ie MSB become LSB */
+static uint8_t const cswap[256] = {
+  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
+  0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+  0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
+  0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
+  0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+  0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
+  0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
+  0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+  0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
+  0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
+  0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+  0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
+  0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
+  0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+  0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
+  0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
+  0x3F, 0xBF, 0x7F, 0xFF
+};
+
+/* Utilities to byte-swap values, use libc optimized macros if possible  */
+#define TWIDDLE_BYTE(ub, type) \
+  do { \
+    if (ft->encoding.reverse_bits) \
+      ub = cswap[ub]; \
+    if (ft->encoding.reverse_nibbles) \
+      ub = ((ub & 15) << 4) | (ub >> 4); \
+  } while (0);
+
+#define TWIDDLE_WORD(uw, type) \
+  if (ft->encoding.reverse_bytes) \
+    uw = lsx_swap ## type(uw);
+
+#define TWIDDLE_FLOAT(f, type) \
+  if (ft->encoding.reverse_bytes) \
+    lsx_swapf(&f);
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define READ_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    nread = lsx_readbuf(ft, buf, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      twiddle(buf[n], type); \
+    return nread; \
+  }
+
+/* Unpack a 3-byte value from a uint8_t * */
+#define sox_unpack3(p) (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN? \
+  ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16)) : \
+  ((p)[2] | ((p)[1] << 8) | ((p)[0] << 16)))
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be unpacked. */
+#define READ_FUNC_UNPACK(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    uint8_t *data = lsx_malloc(size * len); \
+    nread = lsx_readbuf(ft, data, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      buf[n] = sox_unpack ## size(data + n * size); \
+    free(data); \
+    return n; \
+  }
+
+READ_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+READ_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+READ_FUNC_UNPACK(3, 3, sox_uint24_t, TWIDDLE_WORD)
+READ_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+READ_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
+READ_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
+READ_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
+
+#define READ1_FUNC(type, ctype) \
+int lsx_read ## type(sox_format_t * ft, ctype * datum) { \
+  if (lsx_read_ ## type ## _buf(ft, datum, (size_t)1) == 1) \
+    return SOX_SUCCESS; \
+  if (!lsx_error(ft)) \
+    lsx_fail_errno(ft, errno, premature_eof); \
+  return SOX_EOF; \
+}
+
+static char const premature_eof[] = "premature EOF";
+
+READ1_FUNC(b,  uint8_t)
+READ1_FUNC(w,  uint16_t)
+READ1_FUNC(3,  sox_uint24_t)
+READ1_FUNC(dw, uint32_t)
+READ1_FUNC(qw, uint64_t)
+READ1_FUNC(f,  float)
+READ1_FUNC(df, double)
+
+int lsx_readchars(sox_format_t * ft, char * chars, size_t len)
+{
+  size_t ret = lsx_readbuf(ft, chars, len);
+  if (ret == len)
+    return SOX_SUCCESS;
+  if (!lsx_error(ft))
+    lsx_fail_errno(ft, errno, premature_eof);
+  return SOX_EOF;
+}
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define WRITE_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    for (n = 0; n < len; n++) \
+      twiddle(buf[n], type); \
+    nwritten = lsx_writebuf(ft, buf, len * size); \
+    return nwritten / size; \
+  }
+
+/* Pack a 3-byte value to a uint8_t * */
+#define sox_pack3(p, v) do {if (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN)\
+{(p)[0] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[2] = (v >> 16) & 0xff;} else \
+{(p)[2] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[0] = (v >> 16) & 0xff;} \
+} while (0)
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be packed. */
+#define WRITE_FUNC_PACK(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    uint8_t *data = lsx_malloc(size * len); \
+    for (n = 0; n < len; n++) \
+      sox_pack ## size(data + n * size, buf[n]); \
+    nwritten = lsx_writebuf(ft, data, len * size); \
+    free(data); \
+    return nwritten / size; \
+  }
+
+WRITE_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+WRITE_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+WRITE_FUNC_PACK(3, 3, sox_uint24_t, TWIDDLE_WORD)
+WRITE_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+WRITE_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
+WRITE_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
+WRITE_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
+
+#define WRITE1U_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, unsigned d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1S_FUNC(type, ctype) \
+  int lsx_writes ## type(sox_format_t * ft, signed d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, ctype datum) \
+  { \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+WRITE1U_FUNC(b, uint8_t)
+WRITE1U_FUNC(w, uint16_t)
+WRITE1U_FUNC(3, sox_uint24_t)
+WRITE1U_FUNC(dw, uint32_t)
+WRITE1_FUNC(qw, uint64_t)
+WRITE1S_FUNC(b, uint8_t)
+WRITE1S_FUNC(w, uint16_t)
+WRITE1_FUNC(df, double)
+
+int lsx_writef(sox_format_t * ft, double datum)
+{
+  float f = datum;
+  return lsx_write_f_buf(ft, &f, (size_t) 1) == 1 ? SOX_SUCCESS : SOX_EOF;
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/libsox.c b/freedv/tags/1.2.2/freedv-dev/src/sox/libsox.c
new file mode 100644 (file)
index 0000000..4362025
--- /dev/null
@@ -0,0 +1,225 @@
+/* Implements the public API for libSoX general functions
+ * All public functions & data are prefixed with sox_ .
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <string.h>
+
+const char *sox_version(void)
+{
+  static char versionstr[20];
+
+  sprintf(versionstr, "%d.%d.%d",
+          (SOX_LIB_VERSION_CODE & 0xff0000) >> 16,
+          (SOX_LIB_VERSION_CODE & 0x00ff00) >> 8,
+          (SOX_LIB_VERSION_CODE & 0x0000ff));
+  return(versionstr);
+}
+
+sox_version_info_t const * sox_version_info(void)
+{
+#define STRINGIZE1(x) #x
+#define STRINGIZE(x) STRINGIZE1(x)
+    static char arch[30];
+    static sox_version_info_t info = {
+        /* size */
+        sizeof(sox_version_info_t),
+        /* flags */
+        (sox_version_flags_t)(
+#if HAVE_POPEN
+        sox_version_have_popen +
+#endif
+#if  HAVE_MAGIC
+        sox_version_have_magic +
+#endif
+#if HAVE_OPENMP
+        sox_version_have_threads +
+#endif
+#ifdef HAVE_FMEMOPEN
+        sox_version_have_memopen +
+#endif
+        sox_version_none),
+        /* version_code */
+        SOX_LIB_VERSION_CODE,
+        /* version */
+        NULL,
+        /* sox_version_extra */
+#ifdef PACKAGE_EXTRA
+        PACKAGE_EXTRA,
+#else
+        NULL,
+#endif
+        /* sox_time */
+        __DATE__ " " __TIME__,
+        /* sox_distro */
+#ifdef DISTRO
+        DISTRO,
+#else
+        NULL,
+#endif
+        /* sox_compiler */
+#if defined __GNUC__
+        "gcc " __VERSION__,
+#elif defined _MSC_VER
+        "msvc " STRINGIZE(_MSC_FULL_VER),
+#elif defined __SUNPRO_C
+    fprintf(file, "sun c " STRINGIZE(__SUNPRO_C),
+#else
+        NULL,
+#endif
+        /* sox_arch */
+        NULL
+    };
+
+    if (!info.version)
+    {
+        info.version = sox_version();
+    }
+
+    if (!info.arch)
+    {
+        snprintf(arch, sizeof(arch),
+            "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR
+            " %" PRIuPTR "%" PRIuPTR " %" PRIuPTR "%" PRIuPTR " %c %s",
+            sizeof(char), sizeof(short), sizeof(long), sizeof(off_t),
+            sizeof(float), sizeof(double), sizeof(int *), sizeof(int (*)(void)),
+            MACHINE_IS_BIGENDIAN ? 'B' : 'L',
+            (info.flags & sox_version_have_threads) ? "OMP" : "");
+        arch[sizeof(arch) - 1] = 0;
+        info.arch = arch;
+    }
+
+    return &info;
+}
+
+/* Default routine to output messages; can be overridden */
+static void output_message(
+    unsigned level, const char *filename, const char *fmt, va_list ap)
+{
+  if (sox_globals.verbosity >= level) {
+    char base_name[128];
+    sox_basename(base_name, sizeof(base_name), filename);
+    fprintf(stderr, "%s: ", base_name);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+  }
+}
+
+static sox_globals_t s_sox_globals = {
+  2,               /* unsigned     verbosity */
+  output_message,  /* sox_output_message_handler */
+  sox_false,       /* sox_bool     repeatable */
+  8192,            /* size_t       bufsiz */
+  0,               /* size_t       input_bufsiz */
+  0,               /* int32_t      ranqd1 */
+  NULL,            /* char const * stdin_in_use_by */
+  NULL,            /* char const * stdout_in_use_by */
+  NULL,            /* char const * subsystem */
+  NULL,            /* char       * tmp_path */
+  sox_false,       /* sox_bool     use_magic */
+  sox_false        /* sox_bool     use_threads */
+};
+
+sox_globals_t * sox_get_globals(void)
+{
+    return &s_sox_globals;
+}
+
+/* FIXME: Not thread safe using globals */
+static sox_effects_globals_t s_sox_effects_globals =
+    {sox_plot_off, &s_sox_globals};
+
+sox_effects_globals_t *
+sox_get_effects_globals(void)
+{
+    return &s_sox_effects_globals;
+}
+
+char const * sox_strerror(int sox_errno)
+{
+  static char const * const errors[] = {
+    "Invalid Audio Header",
+    "Unsupported data format",
+    "Can't allocate memory",
+    "Operation not permitted",
+    "Operation not supported",
+    "Invalid argument",
+  };
+  if (sox_errno < SOX_EHDR)
+    return strerror(sox_errno);
+  sox_errno -= SOX_EHDR;
+  if (sox_errno < 0 || (size_t)sox_errno >= array_length(errors))
+    return "Unknown error";
+  return errors[sox_errno];
+}
+
+size_t sox_basename(char * base_buffer, size_t base_buffer_len, const char * filename)
+{
+  if (!base_buffer || !base_buffer_len)
+  {
+    return 0;
+  }
+  else
+  {
+    char const * slash_pos = LAST_SLASH(filename);
+    char const * base_name = slash_pos ? slash_pos + 1 : filename;
+    char const * dot_pos   = strrchr(base_name, '.');
+    size_t i, len;
+    dot_pos = dot_pos ? dot_pos : base_name + strlen(base_name);
+    len = dot_pos - base_name;
+    len = min(len, base_buffer_len - 1);
+    for (i = 0; i < len; i++)
+    {
+      base_buffer[i] = base_name[i];
+    }
+    base_buffer[i] = 0;
+    return i;
+  }
+}
+
+#define SOX_MESSAGE_FUNCTION(name,level) \
+void name(char const * fmt, ...) { \
+  va_list ap; \
+  va_start(ap, fmt); \
+  if (sox_globals.output_message_handler) \
+    (*sox_globals.output_message_handler)(level,sox_globals.subsystem,fmt,ap); \
+  va_end(ap); \
+}
+
+SOX_MESSAGE_FUNCTION(lsx_fail_impl  , 1)
+SOX_MESSAGE_FUNCTION(lsx_warn_impl  , 2)
+SOX_MESSAGE_FUNCTION(lsx_report_impl, 3)
+SOX_MESSAGE_FUNCTION(lsx_debug_impl , 4)
+SOX_MESSAGE_FUNCTION(lsx_debug_more_impl , 5)
+SOX_MESSAGE_FUNCTION(lsx_debug_most_impl , 6)
+
+#undef SOX_MESSAGE_FUNCTION
+
+int sox_init(void)
+{
+  return lsx_effects_init();
+}
+
+int sox_quit(void)
+{
+  #ifndef __FREEDV__
+  sox_format_quit();
+  #endif
+  return lsx_effects_quit();
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/sox.h b/freedv/tags/1.2.2/freedv-dev/src/sox/sox.h
new file mode 100644 (file)
index 0000000..0537255
--- /dev/null
@@ -0,0 +1,2608 @@
+/* libSoX Library Public Interface
+ *
+ * Copyright 1999-2011 Chris Bagwell and SoX Contributors.
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/** @file
+Contains the interface exposed to clients of the libSoX library.
+Symbols starting with "sox_" or "SOX_" are part of the public interface for
+libSoX clients (applications that consume libSoX). Symbols starting with
+"lsx_" or "LSX_" are internal use by libSoX and plugins.
+LSX_ and lsx_ symbols should not be used by libSoX-based applications.
+*/
+
+#ifndef SOX_H
+#define SOX_H /**< Client API: This macro is defined if sox.h has been included. */
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Suppress warnings from use of type long long. */
+#if defined __GNUC__
+#pragma GCC system_header
+#endif
+
+/*****************************************************************************
+API decoration macros:
+Mostly for documentation purposes. For some compilers, decorations also affect
+code generation, influence compiler warnings or activate compiler
+optimizations.
+*****************************************************************************/
+
+/**
+Plugins API:
+Attribute required on all functions exported by libSoX and on all function
+pointer types used by the libSoX API.
+*/
+#ifdef __GNUC__
+#define LSX_API  __attribute__ ((cdecl)) /* libSoX function */
+#elif _MSC_VER
+#define LSX_API  __cdecl /* libSoX function */
+#else
+#define LSX_API /* libSoX function */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter or local variable to suppress warnings about
+the variable being unused (especially in macro-generated code).
+*/
+#ifdef __GNUC__
+#define LSX_UNUSED  __attribute__ ((unused)) /* Parameter or local variable is intentionally unused. */
+#else
+#define LSX_UNUSED /* Parameter or local variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+LSX_PRINTF12: Attribute applied to a function to indicate that it requires
+a printf-style format string for arg1 and that printf parameters start at
+arg2.
+*/
+#ifdef __GNUC__
+#define LSX_PRINTF12  __attribute__ ((format (printf, 1, 2))) /* Function has printf-style arguments. */
+#else
+#define LSX_PRINTF12 /* Function has printf-style arguments. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that it has no side effects and
+depends only its input parameters and global memory. If called repeatedly, it
+returns the same result each time.
+*/
+#ifdef __GNUC__
+#define LSX_RETURN_PURE __attribute__ ((pure)) /* Function is pure. */
+#else
+#define LSX_RETURN_PURE /* Function is pure. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the
+return value is always a pointer to a valid object (never NULL).
+*/
+#ifdef _Ret_
+#define LSX_RETURN_VALID _Ret_ /* Function always returns a valid object (never NULL). */
+#else
+#define LSX_RETURN_VALID /* Function always returns a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid array (never NULL).
+*/
+#ifdef _Ret_valid_
+#define LSX_RETURN_ARRAY _Ret_valid_ /* Function always returns a valid array (never NULL). */
+#else
+#define LSX_RETURN_ARRAY /* Function always returns a valid array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid 0-terminated array (never NULL).
+*/
+#ifdef _Ret_z_
+#define LSX_RETURN_VALID_Z _Ret_z_ /* Function always returns a 0-terminated array (never NULL). */
+#else
+#define LSX_RETURN_VALID_Z /* Function always returns a 0-terminated array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the returned pointer may be
+null.
+*/
+#ifdef _Ret_opt_
+#define LSX_RETURN_OPT _Ret_opt_ /* Function may return NULL. */
+#else
+#define LSX_RETURN_OPT /* Function may return NULL. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one const element of the pointed-to type (never NULL).
+*/
+#ifdef _In_
+#define LSX_PARAM_IN _In_ /* Required const pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_IN /* Required const pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to a const 0-terminated string (never NULL).
+*/
+#ifdef _In_z_
+#define LSX_PARAM_IN_Z _In_z_ /* Required const pointer to 0-terminated string (never NULL). */
+#else
+#define LSX_PARAM_IN_Z /* Required const pointer to 0-terminated string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a const
+pointer to a 0-terminated printf format string.
+*/
+#ifdef _Printf_format_string_
+#define LSX_PARAM_IN_PRINTF _Printf_format_string_ /* Required const pointer to 0-terminated printf format string (never NULL). */
+#else
+#define LSX_PARAM_IN_PRINTF /* Required const pointer to 0-terminated printf format string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const initialized elements of the pointed-to type, where
+(len) is the name of another parameter.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _In_count_
+#define LSX_PARAM_IN_COUNT(len) _In_count_(len) /* Required const pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_IN_COUNT(len) /* Required const pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const bytes of initialized data, where (len) is the name of
+another parameter.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _In_bytecount_
+#define LSX_PARAM_IN_BYTECOUNT(len) _In_bytecount_(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#else
+#define LSX_PARAM_IN_BYTECOUNT(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to one const element of the pointed-to type.
+*/
+#ifdef _In_opt_
+#define LSX_PARAM_IN_OPT _In_opt_ /* Optional const pointer to a valid object (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT /* Optional const pointer to a valid object (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to a const 0-terminated string.
+*/
+#ifdef _In_opt_z_
+#define LSX_PARAM_IN_OPT_Z _In_opt_z_ /* Optional const pointer to 0-terminated string (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT_Z /* Optional const pointer to 0-terminated string (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one initialized element of the pointed-to type (never NULL). The
+function may modify the element.
+*/
+#ifdef _Inout_
+#define LSX_PARAM_INOUT _Inout_ /* Required pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_INOUT /* Required pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) initialized elements of the pointed-to type (never NULL). The
+function may modify the elements.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _Inout_count_x_
+#define LSX_PARAM_INOUT_COUNT(len) _Inout_count_x_(len) /* Required pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_INOUT_COUNT(len) /* Required pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for one element of the pointed-to type (never
+NULL). The function will initialize the element.
+*/
+#ifdef _Out_
+#define LSX_PARAM_OUT _Out_ /* Required pointer to an object to be initialized (never NULL). */
+#else
+#define LSX_PARAM_OUT /* Required pointer to an object to be initialized (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) bytes of data (never NULL), where (len)
+is the name of another parameter. The function may write up to len bytes of
+data to this memory.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _Out_bytecap_
+#define LSX_PARAM_OUT_BYTECAP(len) _Out_bytecap_(len) /* Required pointer to writable buffer with room for len bytes. */
+#else
+#define LSX_PARAM_OUT_BYTECAP(len) /* Required pointer to writable buffer with room for len bytes. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled)
+elements will have been initialized, where (filled) is either the dereference
+of another pointer parameter (for example "*written") or the "return"
+parameter (indicating that the function returns the number of elements
+written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array, or "return" if the value is returned.
+*/
+#ifdef _Out_cap_post_count_
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) _Out_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#else
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled+1)
+elements will have been initialized, with the last element having been
+initialized to 0, where (filled) is either the dereference of another pointer
+parameter (for example, "*written") or the "return" parameter (indicating that
+the function returns the number of elements written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array (not counting the terminating null), or "return" if the value is returned.
+*/
+#ifdef _Out_z_cap_post_count_
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) _Out_z_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#else
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to memory sufficient for one element of the pointed-to
+type. The function will initialize the element.
+*/
+#ifdef _Out_opt_
+#define LSX_PARAM_OUT_OPT _Out_opt_ /* Optional pointer to an object to be initialized (may be NULL). */
+#else
+#define LSX_PARAM_OUT_OPT /* Optional pointer to an object to be initialized (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which may be NULL when the function is
+invoked.
+*/
+#ifdef _Deref_pre_maybenull_
+#define LSX_PARAM_DEREF_PRE_MAYBENULL _Deref_pre_maybenull_ /* Required pointer (never NULL) to another pointer (may be NULL). */
+#else
+#define LSX_PARAM_DEREF_PRE_MAYBENULL /* Required pointer (never NULL) to another pointer (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be NULL when the function
+returns.
+*/
+#ifdef _Deref_post_null_
+#define LSX_PARAM_DEREF_POST_NULL _Deref_post_null_ /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NULL /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be non-NULL when the
+function returns.
+*/
+#ifdef _Deref_post_notnull_
+#define LSX_PARAM_DEREF_POST_NOTNULL _Deref_post_notnull_ /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NOTNULL /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#endif
+
+/**
+Plugins API:
+Expression that "uses" a potentially-unused variable to avoid compiler
+warnings (especially in macro-generated code).
+*/
+#ifdef _PREFAST_
+#define LSX_USE_VAR(x)  ((void)(x=0)) /* During static analysis, initialize unused variables to 0. */
+#else
+#define LSX_USE_VAR(x)  ((void)(x)) /* Parameter or variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+Compile-time assertion. Causes a compile error if the expression is false.
+@param e  The expression to test. If expression is false, compilation will fail.
+@param f  A unique identifier for the test, for example foo_must_not_be_zero.
+*/
+#define lsx_static_assert(e,f) enum {lsx_static_assert_##f = 1/((e) ? 1 : 0)}
+
+/*****************************************************************************
+Basic typedefs:
+*****************************************************************************/
+
+/**
+Client API:
+Signed twos-complement 8-bit type. Typically defined as signed char.
+*/
+#if SCHAR_MAX==127 && SCHAR_MIN==(-128)
+typedef signed char sox_int8_t;
+#elif CHAR_MAX==127 && CHAR_MIN==(-128)
+typedef char sox_int8_t;
+#else
+#error Unable to determine an appropriate definition for sox_int8_t.
+#endif
+
+/**
+Client API:
+Unsigned 8-bit type. Typically defined as unsigned char.
+*/
+#if UCHAR_MAX==0xff
+typedef unsigned char sox_uint8_t;
+#elif CHAR_MAX==0xff && CHAR_MIN==0
+typedef char sox_uint8_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint8_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 16-bit type. Typically defined as short.
+*/
+#if SHRT_MAX==32767 && SHRT_MIN==(-32768)
+typedef short sox_int16_t;
+#elif INT_MAX==32767 && INT_MIN==(-32768)
+typedef int sox_int16_t;
+#else
+#error Unable to determine an appropriate definition for sox_int16_t.
+#endif
+
+/**
+Client API:
+Unsigned 16-bit type. Typically defined as unsigned short.
+*/
+#if USHRT_MAX==0xffff
+typedef unsigned short sox_uint16_t;
+#elif UINT_MAX==0xffff
+typedef unsigned int sox_uint16_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint16_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 32-bit type. Typically defined as int.
+*/
+#if INT_MAX==2147483647 && INT_MIN==(-2147483647-1)
+typedef int sox_int32_t;
+#elif LONG_MAX==2147483647 && LONG_MIN==(-2147483647-1)
+typedef long sox_int32_t;
+#else
+#error Unable to determine an appropriate definition for sox_int32_t.
+#endif
+
+/**
+Client API:
+Unsigned 32-bit type. Typically defined as unsigned int.
+*/
+#if UINT_MAX==0xffffffff
+typedef unsigned int sox_uint32_t;
+#elif ULONG_MAX==0xffffffff
+typedef unsigned long sox_uint32_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint32_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 64-bit type. Typically defined as long or long long.
+*/
+#if LONG_MAX==9223372036854775807 && LONG_MIN==(-9223372036854775807-1)
+typedef long sox_int64_t;
+#elif defined(_MSC_VER)
+typedef __int64 sox_int64_t;
+#else
+typedef long long sox_int64_t;
+#endif
+
+/**
+Client API:
+Unsigned 64-bit type. Typically defined as unsigned long or unsigned long long.
+*/
+#if ULONG_MAX==0xffffffffffffffff
+typedef unsigned long sox_uint64_t;
+#elif defined(_MSC_VER)
+typedef unsigned __int64 sox_uint64_t;
+#else
+typedef unsigned long long sox_uint64_t;
+#endif
+
+#ifndef _DOXYGEN_
+lsx_static_assert(sizeof(sox_int8_t)==1,   sox_int8_size);
+lsx_static_assert(sizeof(sox_uint8_t)==1,  sox_uint8_size);
+lsx_static_assert(sizeof(sox_int16_t)==2,  sox_int16_size);
+lsx_static_assert(sizeof(sox_uint16_t)==2, sox_uint16_size);
+lsx_static_assert(sizeof(sox_int32_t)==4,  sox_int32_size);
+lsx_static_assert(sizeof(sox_uint32_t)==4, sox_uint32_size);
+lsx_static_assert(sizeof(sox_int64_t)==8,  sox_int64_size);
+lsx_static_assert(sizeof(sox_uint64_t)==8, sox_uint64_size);
+#endif
+
+/**
+Client API:
+Alias for sox_int32_t (beware of the extra byte).
+*/
+typedef sox_int32_t sox_int24_t;
+
+/**
+Client API:
+Alias for sox_uint32_t (beware of the extra byte).
+*/
+typedef sox_uint32_t sox_uint24_t;
+
+/**
+Client API:
+Native SoX audio sample type (alias for sox_int32_t).
+*/
+typedef sox_int32_t sox_sample_t;
+
+/**
+Client API:
+Samples per second is stored as a double.
+*/
+typedef double sox_rate_t;
+
+/**
+Client API:
+File's metadata, access via sox_*_comments functions.
+*/
+typedef char * * sox_comments_t;
+
+/*****************************************************************************
+Enumerations:
+*****************************************************************************/
+
+/**
+Client API:
+Boolean type, assignment (but not necessarily binary) compatible with C++ bool.
+*/
+typedef enum sox_bool {
+    sox_false, /**< False = 0. */
+    sox_true   /**< True = 1. */
+} sox_bool;
+
+/**
+Client API:
+no, yes, or default (default usually implies some kind of auto-detect logic).
+*/
+typedef enum sox_option_t {
+    sox_option_no,      /**< Option specified as no = 0. */
+    sox_option_yes,     /**< Option specified as yes = 1. */
+    sox_option_default  /**< Option unspecified = 2. */
+} sox_option_t;
+
+/**
+Client API:
+The libSoX-specific error codes.
+libSoX functions may return these codes or others that map from errno codes.
+*/
+enum sox_error_t {
+  SOX_SUCCESS = 0,     /**< Function succeeded = 0 */
+  SOX_EOF = -1,        /**< End Of File or other error = -1 */
+  SOX_EHDR = 2000,     /**< Invalid Audio Header = 2000 */
+  SOX_EFMT,            /**< Unsupported data format = 2001 */
+  SOX_ENOMEM,          /**< Can't alloc memory = 2002 */
+  SOX_EPERM,           /**< Operation not permitted = 2003 */
+  SOX_ENOTSUP,         /**< Operation not supported = 2004 */
+  SOX_EINVAL           /**< Invalid argument = 2005 */
+};
+
+/**
+Client API:
+Flags indicating whether optional features are present in this build of libSoX.
+*/
+typedef enum sox_version_flags_t {
+    sox_version_none = 0,         /**< No special features = 0. */
+    sox_version_have_popen = 1,   /**< popen = 1. */
+    sox_version_have_magic = 2,   /**< magic = 2. */
+    sox_version_have_threads = 4, /**< threads = 4. */
+    sox_version_have_memopen = 8  /**< memopen = 8. */
+} sox_version_flags_t;
+
+/**
+Client API:
+Format of sample data.
+*/
+typedef enum sox_encoding_t {
+  SOX_ENCODING_UNKNOWN   , /**< encoding has not yet been determined */
+
+  SOX_ENCODING_SIGN2     , /**< signed linear 2's comp: Mac */
+  SOX_ENCODING_UNSIGNED  , /**< unsigned linear: Sound Blaster */
+  SOX_ENCODING_FLOAT     , /**< floating point (binary format) */
+  SOX_ENCODING_FLOAT_TEXT, /**< floating point (text format) */
+  SOX_ENCODING_FLAC      , /**< FLAC compression */
+  SOX_ENCODING_HCOM      , /**< Mac FSSD files with Huffman compression */
+  SOX_ENCODING_WAVPACK   , /**< WavPack with integer samples */
+  SOX_ENCODING_WAVPACKF  , /**< WavPack with float samples */
+  SOX_ENCODING_ULAW      , /**< u-law signed logs: US telephony, SPARC */
+  SOX_ENCODING_ALAW      , /**< A-law signed logs: non-US telephony, Psion */
+  SOX_ENCODING_G721      , /**< G.721 4-bit ADPCM */
+  SOX_ENCODING_G723      , /**< G.723 3 or 5 bit ADPCM */
+  SOX_ENCODING_CL_ADPCM  , /**< Creative Labs 8 --> 2,3,4 bit Compressed PCM */
+  SOX_ENCODING_CL_ADPCM16, /**< Creative Labs 16 --> 4 bit Compressed PCM */
+  SOX_ENCODING_MS_ADPCM  , /**< Microsoft Compressed PCM */
+  SOX_ENCODING_IMA_ADPCM , /**< IMA Compressed PCM */
+  SOX_ENCODING_OKI_ADPCM , /**< Dialogic/OKI Compressed PCM */
+  SOX_ENCODING_DPCM      , /**< Differential PCM: Fasttracker 2 (xi) */
+  SOX_ENCODING_DWVW      , /**< Delta Width Variable Word */
+  SOX_ENCODING_DWVWN     , /**< Delta Width Variable Word N-bit */
+  SOX_ENCODING_GSM       , /**< GSM 6.10 33byte frame lossy compression */
+  SOX_ENCODING_MP3       , /**< MP3 compression */
+  SOX_ENCODING_VORBIS    , /**< Vorbis compression */
+  SOX_ENCODING_AMR_WB    , /**< AMR-WB compression */
+  SOX_ENCODING_AMR_NB    , /**< AMR-NB compression */
+  SOX_ENCODING_CVSD      , /**< Continuously Variable Slope Delta modulation */
+  SOX_ENCODING_LPC10     , /**< Linear Predictive Coding */
+
+  SOX_ENCODINGS            /**< End of list marker */
+} sox_encoding_t;
+
+/**
+Client API:
+Flags for sox_encodings_info_t: lossless/lossy1/lossy2.
+*/
+typedef enum sox_encodings_flags_t {
+  sox_encodings_none   = 0, /**< no flags specified (implies lossless encoding) = 0. */
+  sox_encodings_lossy1 = 1, /**< encode, decode: lossy once = 1. */
+  sox_encodings_lossy2 = 2  /**< encode, decode, encode, decode: lossy twice = 2. */
+} sox_encodings_flags_t;
+
+/**
+Client API:
+Type of plot.
+*/
+typedef enum sox_plot_t {
+    sox_plot_off,     /**< No plot = 0. */
+    sox_plot_octave,  /**< Octave plot = 1. */
+    sox_plot_gnuplot, /**< Gnuplot plot = 2. */
+    sox_plot_data     /**< Plot data = 3. */
+} sox_plot_t;
+
+/**
+Client API:
+Loop modes: upper 4 bits mask the loop blass, lower 4 bits describe
+the loop behaviour, for example single shot, bidirectional etc.
+*/
+enum sox_loop_flags_t {
+  sox_loop_none = 0,          /**< single-shot = 0 */
+  sox_loop_forward = 1,       /**< forward loop = 1 */
+  sox_loop_forward_back = 2,  /**< forward/back loop = 2 */
+  sox_loop_8 = 32,            /**< 8 loops (??) = 32 */
+  sox_loop_sustain_decay = 64 /**< AIFF style, one sustain & one decay loop = 64 */
+};
+
+/**
+Plugins API:
+Is file a real file, a pipe, or a url?
+*/
+typedef enum lsx_io_type
+{
+    lsx_io_file, /**< File is a real file = 0. */
+    lsx_io_pipe, /**< File is a pipe (no seeking) = 1. */
+    lsx_io_url   /**< File is a URL (no seeking) = 2. */
+} lsx_io_type;
+
+/*****************************************************************************
+Macros:
+*****************************************************************************/
+
+/**
+Client API:
+Compute a 32-bit integer API version from three 8-bit parts.
+@param a Major version.
+@param b Minor version.
+@param c Revision or build number.
+@returns 32-bit integer API version 0x000a0b0c.
+*/
+#define SOX_LIB_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+
+/**
+Client API:
+The API version of the sox.h file. It is not meant to follow the version
+number of SoX but it has historically. Please do not count on
+SOX_LIB_VERSION_CODE staying in sync with the libSoX version.
+*/
+#define SOX_LIB_VERSION_CODE   SOX_LIB_VERSION(14, 4, 1)
+
+/**
+Client API:
+Returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MIN(8) = 0x80, SOX_INT_MIN(16) = 0x8000, etc.
+@param bits Size of value for which to calculate minimum.
+@returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MIN(bits) (1 <<((bits)-1))
+
+/**
+Client API:
+Returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MAX(8) = 0x7F, SOX_INT_MAX(16) = 0x7FFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MAX(bits) (((unsigned)-1)>>(33-(bits)))
+
+/**
+Client API:
+Returns the largest value storable in an unsigned integer with the specified
+number of bits; for example, SOX_UINT_MAX(8) = 0xFF,
+SOX_UINT_MAX(16) = 0xFFFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest value storable in an unsigned integer with the specified
+number of bits.
+*/
+#define SOX_UINT_MAX(bits) (SOX_INT_MIN(bits)|SOX_INT_MAX(bits))
+
+/**
+Client API:
+Returns 0x7F.
+*/
+#define SOX_INT8_MAX  SOX_INT_MAX(8)
+
+/**
+Client API:
+Returns 0x7FFF.
+*/
+#define SOX_INT16_MAX SOX_INT_MAX(16)
+
+/**
+Client API:
+Returns 0x7FFFFF.
+*/
+#define SOX_INT24_MAX SOX_INT_MAX(24)
+
+/**
+Client API:
+Returns 0x7FFFFFFF.
+*/
+#define SOX_INT32_MAX SOX_INT_MAX(32)
+
+/**
+Client API:
+Bits in a sox_sample_t = 32.
+*/
+#define SOX_SAMPLE_PRECISION 32
+
+/**
+Client API:
+Max value for sox_sample_t = 0x7FFFFFFF.
+*/
+#define SOX_SAMPLE_MAX (sox_sample_t)SOX_INT_MAX(32)
+
+/**
+Client API:
+Min value for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_MIN (sox_sample_t)SOX_INT_MIN(32)
+
+
+/*                Conversions: Linear PCM <--> sox_sample_t
+ *
+ *   I/O      Input    sox_sample_t Clips?   Input    sox_sample_t Clips?
+ *  Format   Minimum     Minimum     I O    Maximum     Maximum     I O
+ *  ------  ---------  ------------ -- --   --------  ------------ -- --
+ *  Float     -inf         -1        y n      inf      1 - 5e-10    y n
+ *  Int8      -128        -128       n n      127     127.9999999   n y
+ *  Int16    -32768      -32768      n n     32767    32767.99998   n y
+ *  Int24   -8388608    -8388608     n n    8388607   8388607.996   n y
+ *  Int32  -2147483648 -2147483648   n n   2147483647 2147483647    n n
+ *
+ * Conversions are as accurate as possible (with rounding).
+ *
+ * Rounding: halves toward +inf, all others to nearest integer.
+ *
+ * Clips? shows whether on not there is the possibility of a conversion
+ * clipping to the minimum or maximum value when inputing from or outputing
+ * to a given type.
+ *
+ * Unsigned integers are converted to and from signed integers by flipping
+ * the upper-most bit then treating them as signed integers.
+ */
+
+/**
+Client API:
+Declares the temporary local variables that are required when using SOX
+conversion macros.
+*/
+#define SOX_SAMPLE_LOCALS sox_sample_t sox_macro_temp_sample LSX_UNUSED; \
+  double sox_macro_temp_double LSX_UNUSED
+
+/**
+Client API:
+Sign bit for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_NEG SOX_INT_MIN(32)
+
+/**
+Client API:
+Converts sox_sample_t to an unsigned integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Unsigned integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_UNSIGNED(bits,d,clips) \
+  (sox_uint##bits##_t)(SOX_SAMPLE_TO_SIGNED(bits,d,clips)^SOX_INT_MIN(bits))
+
+/**
+Client API:
+Converts sox_sample_t to a signed integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Signed integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \
+  (sox_int##bits##_t)(LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-(1<<(31-bits))?++(clips),SOX_INT_MAX(bits):((sox_uint32_t)(sox_macro_temp_sample+(1<<(31-bits))))>>(32-bits))
+
+/**
+Client API:
+Converts signed integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-bits))
+
+/**
+Client API:
+Converts unsigned integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts unsigned 8-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_8BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts signed 8-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_8BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts unsigned 16-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_16BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts signed 16-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_16BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts unsigned 24-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_24BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts signed 24-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_24BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts unsigned 32-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts signed 32-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d)
+
+/**
+Client API:
+Converts 32-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<SOX_SAMPLE_MIN?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double>=SOX_SAMPLE_MAX+1.?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double)
+
+/**
+Client API:
+Converts 64-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<0?sox_macro_temp_double<=SOX_SAMPLE_MIN-.5?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double-.5:sox_macro_temp_double>=SOX_SAMPLE_MAX+.5?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double+.5)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an signed 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_8BIT(d,clips) SOX_SAMPLE_TO_SIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) SOX_SAMPLE_TO_SIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_24BIT(d,clips) SOX_SAMPLE_TO_SIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d,clips) (sox_uint32_t)((d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts SoX native sample to a signed 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_SIGNED_32BIT(d,clips) (sox_int32_t)(d)
+
+/**
+Client API:
+Converts SoX native sample to a 32-bit float.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_FLOAT_32BIT(d,clips) (LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-128?++(clips),1:(((sox_macro_temp_sample+128)&~255)*(1./(SOX_SAMPLE_MAX+1.))))
+
+/**
+Client API:
+Converts SoX native sample to a 64-bit float.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_FLOAT_64BIT(d,clips) ((d)*(1./(SOX_SAMPLE_MAX+1.)))
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param samp Value (lvalue) to be clipped, updated as necessary.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+*/
+#define SOX_SAMPLE_CLIP_COUNT(samp, clips) \
+  do { \
+    if (samp > SOX_SAMPLE_MAX) \
+      { samp = SOX_SAMPLE_MAX; clips++; } \
+    else if (samp < SOX_SAMPLE_MIN) \
+      { samp = SOX_SAMPLE_MIN; clips++; } \
+  } while (0)
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param d Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_ROUND_CLIP_COUNT(d, clips) \
+  ((d) < 0? (d) <= SOX_SAMPLE_MIN - 0.5? ++(clips), SOX_SAMPLE_MIN: (d) - 0.5 \
+        : (d) >= SOX_SAMPLE_MAX + 0.5? ++(clips), SOX_SAMPLE_MAX: (d) + 0.5)
+
+/**
+Client API:
+Clips a value to the limits of a signed integer of the specified width
+and increment a counter if clipping occurs.
+@param bits Width (in bits) of target integer type.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_INTEGER_CLIP_COUNT(bits,i,clips) ( \
+  (i) >(1 << ((bits)-1))- 1? ++(clips),(1 << ((bits)-1))- 1 : \
+  (i) <-1 << ((bits)-1)    ? ++(clips),-1 << ((bits)-1) : (i))
+
+/**
+Client API:
+Clips a value to the limits of a 16-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_16BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(16,i,clips)
+
+/**
+Client API:
+Clips a value to the limits of a 24-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_24BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(24,i,clips)
+
+#define SOX_SIZE_MAX ((size_t)(-1)) /**< Client API: Maximum value of size_t. */
+
+#define SOX_UNSPEC 0                         /**< Client API: Members of sox_signalinfo_t are set to SOX_UNSPEC (= 0) if the actual value is not yet known. */
+#define SOX_UNKNOWN_LEN (sox_uint64_t)(-1) /**< Client API: sox_signalinfo_t.length is set to SOX_UNKNOWN_LEN (= -1) within the effects chain if the actual length is not known. Format handlers currently use SOX_UNSPEC instead. */
+#define SOX_IGNORE_LENGTH (sox_uint64_t)(-2) /**< Client API: sox_signalinfo_t.length is set to SOX_IGNORE_LENGTH (= -2) to indicate that a format handler should ignore length information in file headers. */
+
+#define SOX_DEFAULT_CHANNELS  2     /**< Client API: Default channel count is 2 (stereo). */
+#define SOX_DEFAULT_RATE      48000 /**< Client API: Default rate is 48000Hz. */
+#define SOX_DEFAULT_PRECISION 16    /**< Client API: Default precision is 16 bits per sample. */
+#define SOX_DEFAULT_ENCODING  SOX_ENCODING_SIGN2 /**< Client API: Default encoding is SIGN2 (linear 2's complement PCM). */
+
+#define SOX_LOOP_NONE          ((unsigned char)sox_loop_none)          /**< Client API: single-shot = 0 */
+#define SOX_LOOP_8             ((unsigned char)sox_loop_8)             /**< Client API: 8 loops = 32 */
+#define SOX_LOOP_SUSTAIN_DECAY ((unsigned char)sox_loop_sustain_decay) /**< Client API: AIFF style, one sustain & one decay loop = 64 */
+
+#define SOX_MAX_NLOOPS         8 /**< Client API: Maximum number of loops supported by sox_oob_t = 8. */
+
+#define SOX_FILE_NOSTDIO 0x0001 /**< Client API: Does not use stdio routines */
+#define SOX_FILE_DEVICE  0x0002 /**< Client API: File is an audio device */
+#define SOX_FILE_PHONY   0x0004 /**< Client API: Phony file/device (for example /dev/null) */
+#define SOX_FILE_REWIND  0x0008 /**< Client API: File should be rewound to write header */
+#define SOX_FILE_BIT_REV 0x0010 /**< Client API: Is file bit-reversed? */
+#define SOX_FILE_NIB_REV 0x0020 /**< Client API: Is file nibble-reversed? */
+#define SOX_FILE_ENDIAN  0x0040 /**< Client API: Is file format endian? */
+#define SOX_FILE_ENDBIG  0x0080 /**< Client API: For endian file format, is it big endian? */
+#define SOX_FILE_MONO    0x0100 /**< Client API: Do channel restrictions allow mono? */
+#define SOX_FILE_STEREO  0x0200 /**< Client API: Do channel restrictions allow stereo? */
+#define SOX_FILE_QUAD    0x0400 /**< Client API: Do channel restrictions allow quad? */
+
+#define SOX_FILE_CHANS   (SOX_FILE_MONO | SOX_FILE_STEREO | SOX_FILE_QUAD) /**< Client API: No channel restrictions */
+#define SOX_FILE_LIT_END (SOX_FILE_ENDIAN | 0)                             /**< Client API: File is little-endian */
+#define SOX_FILE_BIG_END (SOX_FILE_ENDIAN | SOX_FILE_ENDBIG)               /**< Client API: File is big-endian */
+
+#define SOX_EFF_CHAN     1           /**< Client API: Effect might alter the number of channels */
+#define SOX_EFF_RATE     2           /**< Client API: Effect might alter sample rate */
+#define SOX_EFF_PREC     4           /**< Client API: Effect does its own calculation of output sample precision (otherwise a default value is taken, depending on the presence of SOX_EFF_MODIFY) */
+#define SOX_EFF_LENGTH   8           /**< Client API: Effect might alter audio length (as measured in time units, not necessarily in samples) */
+#define SOX_EFF_MCHAN    16          /**< Client API: Effect handles multiple channels internally */
+#define SOX_EFF_NULL     32          /**< Client API: Effect does nothing (can be optimized out of chain) */
+#define SOX_EFF_DEPRECATED 64        /**< Client API: Effect will soon be removed from SoX */
+#define SOX_EFF_GAIN     128         /**< Client API: Effect does not support gain -r */
+#define SOX_EFF_MODIFY   256         /**< Client API: Effect does not modify sample values (but might remove or duplicate samples or insert zeros) */
+#define SOX_EFF_ALPHA    512         /**< Client API: Effect is experimental/incomplete */
+#define SOX_EFF_INTERNAL 1024        /**< Client API: Effect present in libSoX but not valid for use by SoX command-line tools */
+
+/**
+Client API:
+When used as the "whence" parameter of sox_seek, indicates that the specified
+offset is relative to the beginning of the file.
+*/
+#define SOX_SEEK_SET 0
+
+/*****************************************************************************
+Forward declarations:
+*****************************************************************************/
+
+typedef struct sox_format_t sox_format_t;
+typedef struct sox_effect_t sox_effect_t;
+typedef struct sox_effect_handler_t sox_effect_handler_t;
+typedef struct sox_format_handler_t sox_format_handler_t;
+
+/*****************************************************************************
+Function pointers:
+*****************************************************************************/
+
+/**
+Client API:
+Callback to write a message to an output device (console or log file),
+used by sox_globals_t.output_message_handler.
+*/
+typedef void (LSX_API * sox_output_message_handler_t)(
+    unsigned level,                       /* 1 = FAIL, 2 = WARN, 3 = INFO, 4 = DEBUG, 5 = DEBUG_MORE, 6 = DEBUG_MOST. */
+    LSX_PARAM_IN_Z char const * filename, /* Source code __FILENAME__ from which message originates. */
+    LSX_PARAM_IN_PRINTF char const * fmt, /* Message format string. */
+    LSX_PARAM_IN va_list ap               /* Message format parameters. */
+    );
+
+/**
+Client API:
+Callback to retrieve information about a format handler,
+used by sox_format_tab_t.fn.
+@returns format handler information.
+*/
+typedef sox_format_handler_t const * (LSX_API * sox_format_fn_t)(void);
+
+/**
+Client API:
+Callback to get information about an effect handler,
+used by the table returned from sox_get_effect_fns(void).
+@returns Pointer to information about an effect handler.
+*/
+typedef sox_effect_handler_t const * (LSX_API *sox_effect_fn_t)(void);
+
+/**
+Client API:
+Callback to initialize reader (decoder), used by
+sox_format_handler.startread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to read (decode) a block of samples,
+used by sox_format_handler.read.
+@returns number of samples read, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_read)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Callback to close reader (decoder),
+used by sox_format_handler.stopread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to initialize writer (encoder),
+used by sox_format_handler.startwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to write (encode) a block of samples,
+used by sox_format_handler.write.
+@returns number of samples written, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_write)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer to which samples are written. */
+    size_t len /**< Capacity of buf, measured in samples. */
+    );
+
+/**
+Client API:
+Callback to close writer (decoder),
+used by sox_format_handler.stopwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to reposition reader,
+used by sox_format_handler.seek.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_seek)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset /**< Sample offset to which reader should be positioned. */
+    );
+
+/**
+Client API:
+Callback to parse command-line arguments (called once per effect),
+used by sox_effect_handler.getopts.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_getopts)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char *argv[] /**< Array of command-line arguments. */
+    );
+
+/**
+Client API:
+Callback to initialize effect (called once per flow),
+used by sox_effect_handler.start.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_start)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to process samples,
+used by sox_effect_handler.flow.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_flow)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_IN_COUNT(*isamp) sox_sample_t const * ibuf, /**< Buffer from which to read samples. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t * obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *isamp, /**< On entry, contains capacity of ibuf; on exit, contains number of samples consumed. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to finish getting output after input is complete,
+used by sox_effect_handler.drain.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_drain)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t *obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per flow),
+used by sox_effect_handler.stop.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_stop)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per effect),
+used by sox_effect_handler.kill.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_kill)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback called while flow is running (called once per buffer),
+used by sox_flow_effects.callback.
+@returns SOX_SUCCESS to continue, other value to abort flow.
+*/
+typedef int (LSX_API * sox_flow_effects_callback)(
+    sox_bool all_done,
+    void * client_data
+    );
+
+/**
+Client API:
+Callback for enumerating the contents of a playlist,
+used by the sox_parse_playlist function.
+@returns SOX_SUCCESS if successful, any other value to abort playlist enumeration.
+*/
+typedef int (LSX_API * sox_playlist_callback_t)(
+    void * callback_data,
+    LSX_PARAM_IN_Z char const * filename
+    );
+
+/*****************************************************************************
+Structures:
+*****************************************************************************/
+
+/**
+Client API:
+Information about a build of libSoX, returned from the sox_version_info
+function.
+*/
+typedef struct sox_version_info_t {
+    size_t       size;         /**< structure size = sizeof(sox_version_info_t) */
+    sox_version_flags_t flags; /**< feature flags = popen | magic | threads | memopen */
+    sox_uint32_t version_code; /**< version number = 0x140400 */
+    char const * version;      /**< version string = sox_version(), for example, "14.4.0" */
+    char const * version_extra;/**< version extra info or null = "PACKAGE_EXTRA", for example, "beta" */
+    char const * time;         /**< build time = "__DATE__ __TIME__", for example, "Jan  7 2010 03:31:50" */
+    char const * distro;       /**< distro or null = "DISTRO", for example, "Debian" */
+    char const * compiler;     /**< compiler info or null, for example, "msvc 160040219" */
+    char const * arch;         /**< arch, for example, "1248 48 44 L OMP" */
+    /* new info should be added at the end for version backwards-compatibility. */
+} sox_version_info_t;
+
+/**
+Client API:
+Global parameters (for effects & formats), returned from the sox_get_globals
+function.
+*/
+typedef struct sox_globals_t {
+/* public: */
+  unsigned     verbosity; /**< messages are only written if globals.verbosity >= message.level */
+  sox_output_message_handler_t output_message_handler; /**< client-specified message output callback */
+  sox_bool     repeatable; /**< true to use pre-determined timestamps and PRNG seed */
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       bufsiz;
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of input sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       input_bufsiz;
+
+  sox_int32_t  ranqd1; /**< Can be used to re-seed libSoX's PRNG */
+
+  char const * stdin_in_use_by;  /**< Private: tracks the name of the handler currently using stdin */
+  char const * stdout_in_use_by; /**< Private: tracks the name of the handler currently using stdout */
+  char const * subsystem;        /**< Private: tracks the name of the handler currently writing an output message */
+  char       * tmp_path;         /**< Private: client-configured path to use for temporary files */
+  sox_bool     use_magic;        /**< Private: true if client has requested use of 'magic' file-type detection */
+  sox_bool     use_threads;      /**< Private: true if client has requested parallel effects processing */
+} sox_globals_t;
+
+/**
+Client API:
+Signal parameters; members should be set to SOX_UNSPEC (= 0) if unknown.
+*/
+typedef struct sox_signalinfo_t {
+  sox_rate_t       rate;         /**< samples per second, 0 if unknown */
+  unsigned         channels;     /**< number of sound channels, 0 if unknown */
+  unsigned         precision;    /**< bits per sample, 0 if unknown */
+  sox_uint64_t     length;       /**< samples * chans in file, 0 if unknown, -1 if unspecified */
+  double           * mult;       /**< Effects headroom multiplier; may be null */
+} sox_signalinfo_t;
+
+/**
+Client API:
+Basic information about an encoding.
+*/
+typedef struct sox_encodings_info_t {
+  sox_encodings_flags_t flags; /**< lossy once (lossy1), lossy twice (lossy2), or lossless (none). */
+  char const * name;           /**< encoding name. */
+  char const * desc;           /**< encoding description. */
+} sox_encodings_info_t;
+
+/**
+Client API:
+Encoding parameters.
+*/
+typedef struct sox_encodinginfo_t {
+  sox_encoding_t encoding; /**< format of sample numbers */
+  unsigned bits_per_sample;/**< 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */
+  double compression;      /**< compression factor (where applicable) */
+
+  /**
+  Should bytes be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bytes;
+
+  /**
+  Should nibbles be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_nibbles;
+
+  /**
+  Should bits be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bits;
+
+  /**
+  If set to true, the format should reverse its default endianness.
+  */
+  sox_bool opposite_endian;
+} sox_encodinginfo_t;
+
+/**
+Client API:
+Looping parameters (out-of-band data).
+*/
+typedef struct sox_loopinfo_t {
+  sox_uint64_t  start;  /**< first sample */
+  sox_uint64_t  length; /**< length */
+  unsigned      count;  /**< number of repeats, 0=forever */
+  unsigned char type;   /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* for valid values). */
+} sox_loopinfo_t;
+
+/**
+Client API:
+Instrument information.
+*/
+typedef struct sox_instrinfo_t{
+  signed char MIDInote;   /**< for unity pitch playback */
+  signed char MIDIlow;    /**< MIDI pitch-bend low range */
+  signed char MIDIhi;     /**< MIDI pitch-bend high range */
+  unsigned char loopmode; /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* values) */
+  unsigned nloops;  /**< number of active loops (max SOX_MAX_NLOOPS). */
+} sox_instrinfo_t;
+
+/**
+Client API:
+File buffer info.  Holds info so that data can be read in blocks.
+*/
+typedef struct sox_fileinfo_t {
+  char          *buf;                 /**< Pointer to data buffer */
+  size_t        size;                 /**< Size of buffer in bytes */
+  size_t        count;                /**< Count read into buffer */
+  size_t        pos;                  /**< Position in buffer */
+} sox_fileinfo_t;
+
+/**
+Client API:
+Handler structure defined by each format.
+*/
+struct sox_format_handler_t {
+  unsigned     sox_lib_version_code;  /**< Checked on load; must be 1st in struct*/
+  char         const * description;   /**< short description of format */
+  char         const * const * names; /**< null-terminated array of filename extensions that are handled by this format */
+  unsigned int flags;                 /**< File flags (SOX_FILE_* values). */
+  sox_format_handler_startread startread; /**< called to initialize reader (decoder) */
+  sox_format_handler_read read;       /**< called to read (decode) a block of samples */
+  sox_format_handler_stopread stopread; /**< called to close reader (decoder); may be null if no closing necessary */
+  sox_format_handler_startwrite startwrite; /**< called to initialize writer (encoder) */
+  sox_format_handler_write write;     /**< called to write (encode) a block of samples */
+  sox_format_handler_stopwrite stopwrite; /**< called to close writer (decoder); may be null if no closing necessary */
+  sox_format_handler_seek seek;       /**< called to reposition reader; may be null if not supported */
+
+  /**
+  Array of values indicating the encodings and precisions supported for
+  writing (encoding). Precisions specified with default precision first.
+  Encoding, precision, precision, ..., 0, repeat. End with one more 0.
+  Example:
+  unsigned const * formats = {
+    SOX_ENCODING_SIGN2, 16, 24, 0, // Support SIGN2 at 16 and 24 bits, default to 16 bits.
+    SOX_ENCODING_UNSIGNED, 8, 0,   // Support UNSIGNED at 8 bits, default to 8 bits.
+    0 // No more supported encodings.
+  };
+  */
+  unsigned     const * write_formats;
+
+  /**
+  Array of sample rates (samples per second) supported for writing (encoding).
+  NULL if all (or almost all) rates are supported. End with 0.
+  */
+  sox_rate_t   const * write_rates;
+
+  /**
+  SoX will automatically allocate a buffer in which the handler can store data.
+  Specify the size of the buffer needed here. Usually this will be sizeof(your_struct).
+  The buffer will be allocated and zeroed before the call to startread/startwrite.
+  The buffer will be freed after the call to stopread/stopwrite.
+  The buffer will be provided via format.priv in each call to the handler.
+  */
+  size_t       priv_size;
+};
+
+/**
+Client API:
+Comments, instrument info, loop info (out-of-band data).
+*/
+typedef struct sox_oob_t{
+  /* Decoded: */
+  sox_comments_t   comments;              /**< Comment strings in id=value format. */
+  sox_instrinfo_t  instr;                 /**< Instrument specification */
+  sox_loopinfo_t   loops[SOX_MAX_NLOOPS]; /**< Looping specification */
+
+  /* TBD: Non-decoded chunks, etc: */
+} sox_oob_t;
+
+/**
+Client API:
+Data passed to/from the format handler
+*/
+struct sox_format_t {
+  char             * filename;      /**< File name */
+
+  /**
+  Signal specifications for reader (decoder) or writer (encoder):
+  sample rate, number of channels, precision, length, headroom multiplier.
+  Any info specified by the user is here on entry to startread or
+  startwrite. Info will be SOX_UNSPEC if the user provided no info.
+  At exit from startread, should be completely filled in, using
+  either data from the file's headers (if available) or whatever
+  the format is guessing/assuming (if header data is not available).
+  At exit from startwrite, should be completely filled in, using
+  either the data that was specified, or values chosen by the format
+  based on the format's defaults or capabilities.
+  */
+  sox_signalinfo_t signal;
+
+  /**
+  Encoding specifications for reader (decoder) or writer (encoder):
+  encoding (sample format), bits per sample, compression rate, endianness.
+  Should be filled in by startread. Values specified should be used
+  by startwrite when it is configuring the encoding parameters.
+  */
+  sox_encodinginfo_t encoding;
+
+  char             * filetype;      /**< Type of file, as determined by header inspection or libmagic. */
+  sox_oob_t        oob;             /**< comments, instrument info, loop info (out-of-band data) */
+  sox_bool         seekable;        /**< Can seek on this file */
+  char             mode;            /**< Read or write mode ('r' or 'w') */
+  sox_uint64_t     olength;         /**< Samples * chans written to file */
+  sox_uint64_t     clips;           /**< Incremented if clipping occurs */
+  int              sox_errno;       /**< Failure error code */
+  char             sox_errstr[256]; /**< Failure error text */
+  void             * fp;            /**< File stream pointer */
+  lsx_io_type      io_type;         /**< Stores whether this is a file, pipe or URL */
+  sox_uint64_t     tell_off;        /**< Current offset within file */
+  sox_uint64_t     data_start;      /**< Offset at which headers end and sound data begins (set by lsx_check_read_params) */
+  sox_format_handler_t handler;     /**< Format handler for this file */
+  void             * priv;          /**< Format handler's private data area */
+};
+
+/**
+Client API:
+Information about a loaded format handler, including the format name and a
+function pointer that can be invoked to get additional information about the
+format.
+*/
+typedef struct sox_format_tab_t {
+  char *name;         /**< Name of format handler */
+  sox_format_fn_t fn; /**< Function to call to get format handler's information */
+} sox_format_tab_t;
+
+/**
+Client API:
+Global parameters for effects.
+*/
+typedef struct sox_effects_globals_t {
+  sox_plot_t plot;         /**< To help the user choose effect & options */
+  sox_globals_t * global_info; /**< Pointer to associated SoX globals */
+} sox_effects_globals_t;
+
+/**
+Client API:
+Effect handler information.
+*/
+struct sox_effect_handler_t {
+  char const * name;  /**< Effect name */
+  char const * usage; /**< Short explanation of parameters accepted by effect */
+  unsigned int flags; /**< Combination of SOX_EFF_* flags */
+  sox_effect_handler_getopts getopts; /**< Called to parse command-line arguments (called once per effect). */
+  sox_effect_handler_start start;     /**< Called to initialize effect (called once per flow). */
+  sox_effect_handler_flow flow;       /**< Called to process samples. */
+  sox_effect_handler_drain drain;     /**< Called to finish getting output after input is complete. */
+  sox_effect_handler_stop stop;       /**< Called to shut down effect (called once per flow). */
+  sox_effect_handler_kill kill;       /**< Called to shut down effect (called once per effect). */
+  size_t       priv_size;             /**< Size of private data SoX should pre-allocate for effect */
+};
+
+/**
+Client API:
+Effect information.
+*/
+struct sox_effect_t {
+  sox_effects_globals_t    * global_info; /**< global effect parameters */
+  sox_signalinfo_t         in_signal;     /**< Information about the incoming data stream */
+  sox_signalinfo_t         out_signal;    /**< Information about the outgoing data stream */
+  sox_encodinginfo_t       const * in_encoding;  /**< Information about the incoming data encoding */
+  sox_encodinginfo_t       const * out_encoding; /**< Information about the outgoing data encoding */
+  sox_effect_handler_t     handler;   /**< The handler for this effect */
+  sox_sample_t             * obuf;    /**< output buffer */
+  size_t                   obeg;      /**< output buffer: start of valid data section */
+  size_t                   oend;      /**< output buffer: one past valid data section (oend-obeg is length of current content) */
+  size_t               imin;          /**< minimum input buffer content required for calling this effect's flow function; set via lsx_effect_set_imin() */
+  sox_uint64_t         clips;         /**< increment if clipping occurs */
+  size_t               flows;         /**< 1 if MCHAN, number of chans otherwise */
+  size_t               flow;          /**< flow number */
+  void                 * priv;        /**< Effect's private data area (each flow has a separate copy) */
+};
+
+/**
+Client API:
+Chain of effects to be applied to a stream.
+*/
+typedef struct sox_effects_chain_t {
+  sox_effect_t **effects;                  /**< Table of effects to be applied to a stream */
+  unsigned table_size;                     /**< Number of entries in effects table */
+  unsigned length;                         /**< Number of effects to be applied */
+  sox_sample_t **ibufc;                    /**< Channel interleave buffer */
+  sox_sample_t **obufc;                    /**< Channel interleave buffer */
+  sox_effects_globals_t global_info;       /**< Copy of global effects settings */
+  sox_encodinginfo_t const * in_enc;       /**< Input encoding */
+  sox_encodinginfo_t const * out_enc;      /**< Output encoding */
+} sox_effects_chain_t;
+
+/*****************************************************************************
+Functions:
+*****************************************************************************/
+
+/**
+Client API:
+Returns version number string of libSoX, for example, "14.4.0".
+@returns The version number string of libSoX, for example, "14.4.0".
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_version(void);
+
+/**
+Client API:
+Returns information about this build of libsox.
+@returns Pointer to a version information structure.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_version_info_t const *
+LSX_API
+sox_version_info(void);
+
+/**
+Client API:
+Returns a pointer to the structure with libSoX's global settings.
+@returns a pointer to the structure with libSoX's global settings.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_globals_t *
+LSX_API
+sox_get_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns the structure with libSoX's global settings
+as an lvalue.
+*/
+#define sox_globals (*sox_get_globals())
+
+/**
+Client API:
+Returns a pointer to the list of available encodings.
+End of list indicated by name == NULL.
+@returns pointer to the list of available encodings.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_encodings_info_t const *
+LSX_API
+sox_get_encodings_info(void);
+
+/**
+Client API:
+Deprecated macro that returns the list of available encodings.
+End of list indicated by name == NULL.
+*/
+#define sox_encodings_info (sox_get_encodings_info())
+
+/**
+Client API:
+Fills in an encodinginfo with default values.
+*/
+void
+LSX_API
+sox_init_encodinginfo(
+    LSX_PARAM_OUT sox_encodinginfo_t * e /**< Pointer to uninitialized encoding info structure to be initialized. */
+    );
+
+/**
+Client API:
+Given an encoding (for example, SIGN2) and the encoded bits_per_sample (for
+example, 16), returns the number of useful bits per sample in the decoded data
+(for example, 16), or returns 0 to indicate that the value returned by the
+format handler should be used instead of a pre-determined precision.
+@returns the number of useful bits per sample in the decoded data (for example
+16), or returns 0 to indicate that the value returned by the format handler
+should be used instead of a pre-determined precision.
+*/
+LSX_RETURN_PURE
+unsigned
+LSX_API
+sox_precision(
+    sox_encoding_t encoding,   /**< Encoding for which to lookup precision information. */
+    unsigned bits_per_sample   /**< The number of encoded bits per sample. */
+    );
+
+/**
+Client API:
+Returns the number of items in the metadata block.
+@returns the number of items in the metadata block.
+*/
+size_t
+LSX_API
+sox_num_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+Adds an "id=value" item to the metadata block.
+*/
+void
+LSX_API
+sox_append_comment(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * item /**< Item to be added in "id=value" format. */
+    );
+
+/**
+Client API:
+Adds a newline-delimited list of "id=value" items to the metadata block.
+*/
+void
+LSX_API
+sox_append_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * items /**< Newline-separated list of items to be added, for example "id1=value1\\nid2=value2". */
+    );
+
+/**
+Client API:
+Duplicates the metadata block.
+@returns the copied metadata block.
+*/
+LSX_RETURN_OPT
+sox_comments_t
+LSX_API
+sox_copy_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block to copy. */
+    );
+
+/**
+Client API:
+Frees the metadata block.
+*/
+void
+LSX_API
+sox_delete_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NULL sox_comments_t * comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+If "id=value" is found, return value, else return null.
+@returns value, or null if value not found.
+*/
+LSX_RETURN_OPT
+char const *
+LSX_API
+sox_find_comment(
+    LSX_PARAM_IN_OPT sox_comments_t comments, /**< Metadata block in which to search. */
+    LSX_PARAM_IN_Z char const * id /**< Id for which to search */
+    );
+
+/**
+Client API:
+Find and load format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_format_init(void);
+
+/**
+Client API:
+Unload format handler plugins.
+*/
+void
+LSX_API
+sox_format_quit(void);
+
+/**
+Client API:
+Initialize effects library.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_init(void);
+
+/**
+Client API:
+Close effects library and unload format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_quit(void);
+
+/**
+Client API:
+Returns the table of format handler names and functions.
+@returns the table of format handler names and functions.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_format_tab_t const *
+LSX_API
+sox_get_format_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns the table of format handler names and functions.
+*/
+#define sox_format_fns (sox_get_format_fns())
+
+/**
+Client API:
+Opens a decoding session for a file. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_read(
+    LSX_PARAM_IN_Z   char               const * path,      /**< Path to file to be opened (required). */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,    /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,  /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype   /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Opens a decoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_read(
+    LSX_PARAM_IN_BYTECOUNT(buffer_size) void  * buffer,     /**< Pointer to audio data buffer (required). */
+    size_t                                      buffer_size,/**< Number of bytes to read from audio data buffer. */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,     /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,   /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype    /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Returns true if the format handler for the specified file type supports the specified encoding.
+@returns true if the format handler for the specified file type supports the specified encoding.
+*/
+sox_bool
+LSX_API
+sox_format_supports_encoding(
+    LSX_PARAM_IN_OPT_Z char               const * path,       /**< Path to file to be examined (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,   /**< Previously-determined file type, or NULL to use extension from path. */
+    LSX_PARAM_IN       sox_encodinginfo_t const * encoding    /**< Encoding for which format handler should be queried. */
+    );
+
+/**
+Client API:
+Gets the format handler for a specified file type.
+@returns The found format handler, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_write_handler(
+    LSX_PARAM_IN_OPT_Z char               const * path,         /**< Path to file (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,     /**< Filetype for which handler is needed, or NULL to use extension from path. */
+    LSX_PARAM_OUT_OPT  char               const * * filetype1   /**< Receives the filetype that was detected. Pass NULL if not needed. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a file. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_write(
+    LSX_PARAM_IN_Z     char               const * path,     /**< Path to file to be written (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,   /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding, /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype, /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob,      /**< Out-of-band data to add to file, or NULL if none. */
+    LSX_PARAM_IN_OPT   sox_bool           (LSX_API * overwrite_permitted)(LSX_PARAM_IN_Z char const * filename) /**< Called if file exists to determine whether overwrite is ok. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_write(
+    LSX_PARAM_OUT_BYTECAP(buffer_size) void                     * buffer,      /**< Pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_IN                       size_t                     buffer_size, /**< Maximum number of bytes to write to audio data buffer. */
+    LSX_PARAM_IN                       sox_signalinfo_t   const * signal,      /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT                   sox_encodinginfo_t const * encoding,    /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z                 char               const * filetype,    /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT                   sox_oob_t          const * oob          /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memstream buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_memstream_write(
+    LSX_PARAM_OUT      char                     * * buffer_ptr,    /**< Receives pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_OUT      size_t                   * buffer_size_ptr, /**< Receives size of data written to audio data buffer (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,          /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding,        /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,        /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob              /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Reads samples from a decoding session into a sample buffer.
+@returns Number of samples decoded, or 0 for EOF.
+*/
+size_t
+LSX_API
+sox_read(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Writes samples to an encoding session from a sample buffer.
+@returns Number of samples encoded.
+*/
+size_t
+LSX_API
+sox_write(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Closes an encoding or decoding session.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_close(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Sets the location at which next samples will be decoded. Returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_seek(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset, /**< Sample offset at which to position reader. */
+    int whence /**< Set to SOX_SEEK_SET. */
+    );
+
+/**
+Client API:
+Finds a format handler by name.
+@returns Format handler data, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_find_format(
+    LSX_PARAM_IN_Z char const * name, /**< Name of format handler to find. */
+    sox_bool ignore_devices /**< Set to true to ignore device names. */
+    );
+
+/**
+Client API:
+Returns global parameters for effects
+@returns global parameters for effects.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_effects_globals_t *
+LSX_API
+sox_get_effects_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns global parameters for effects.
+*/
+#define sox_effects_globals (*sox_get_effects_globals())
+
+/**
+Client API:
+Finds the effect handler with the given name.
+@returns Effect pointer, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+sox_effect_handler_t const *
+LSX_API
+sox_find_effect(
+    LSX_PARAM_IN_Z char const * name /**< Name of effect to find. */
+    );
+
+/**
+Client API:
+Creates an effect using the given handler.
+@returns The new effect, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_create_effect(
+    LSX_PARAM_IN sox_effect_handler_t const * eh /**< Handler to use for effect. */
+    );
+
+/**
+Client API:
+Applies the command-line options to the effect.
+@returns the number of arguments consumed.
+*/
+int
+LSX_API
+sox_effect_options(
+    LSX_PARAM_IN sox_effect_t *effp, /**< Effect pointer on which to set options. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char * const argv[] /**< Array of command-line options. */
+    );
+
+/**
+Client API:
+Returns an array containing the known effect handlers.
+@returns An array containing the known effect handlers.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+sox_effect_fn_t const *
+LSX_API
+sox_get_effect_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns an array containing the known effect handlers.
+*/
+#define sox_effect_fns (sox_get_effect_fns())
+
+/**
+Client API:
+Initializes an effects chain. Returned handle must be closed with sox_delete_effects_chain().
+@returns Handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_effects_chain_t *
+LSX_API
+sox_create_effects_chain(
+    LSX_PARAM_IN sox_encodinginfo_t const * in_enc, /**< Input encoding. */
+    LSX_PARAM_IN sox_encodinginfo_t const * out_enc /**< Output encoding. */
+    );
+
+/**
+Client API:
+Closes an effects chain.
+*/
+void
+LSX_API
+sox_delete_effects_chain(
+    LSX_PARAM_INOUT sox_effects_chain_t *ecp /**< Effects chain pointer. */
+    );
+
+/**
+Client API:
+Adds an effect to the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_add_effect(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added . */
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect to be added. */
+    LSX_PARAM_INOUT sox_signalinfo_t * in, /**< Input format. */
+    LSX_PARAM_IN    sox_signalinfo_t const * out /**< Output format. */
+    );
+
+/**
+Client API:
+Runs the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_flow_effects(
+    LSX_PARAM_INOUT  sox_effects_chain_t * chain, /**< Effects chain to run. */
+    LSX_PARAM_IN_OPT sox_flow_effects_callback callback, /**< Callback for monitoring flow progress. */
+    LSX_PARAM_IN_OPT void * client_data /**< Data to pass into callback. */
+    );
+
+/**
+Client API:
+Gets the number of clips that occurred while running an effects chain.
+@returns the number of clips that occurred while running an effects chain.
+*/
+sox_uint64_t
+LSX_API
+sox_effects_clips(
+    LSX_PARAM_IN sox_effects_chain_t * chain /**< Effects chain from which to read clip information. */
+    );
+
+/**
+Client API:
+Shuts down an effect (calls stop on each of its flows).
+@returns the number of clips from all flows.
+*/
+sox_uint64_t
+LSX_API
+sox_stop_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t * effp /**< Effect to stop. */
+    );
+
+/**
+Client API:
+Adds an already-initialized effect to the end of the chain.
+*/
+void
+LSX_API
+sox_push_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added. */
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect to be added. */
+    );
+
+/**
+Client API:
+Removes and returns an effect from the end of the chain.
+@returns the removed effect, or null if no effects.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_pop_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove an effect. */
+    );
+
+/**
+Client API:
+Shut down and delete an effect.
+*/
+void
+LSX_API
+sox_delete_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t *effp /**< Effect to be deleted. */
+    );
+
+/**
+Client API:
+Shut down and delete the last effect in the chain.
+*/
+void
+LSX_API
+sox_delete_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove the last effect. */
+    );
+
+/**
+Client API:
+Shut down and delete all effects in the chain.
+*/
+void
+LSX_API
+sox_delete_effects(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to delete effects. */
+    );
+
+/**
+Client API:
+Gets the sample offset of the start of the trim, useful for efficiently
+skipping the part that will be trimmed anyway (get trim start, seek, then
+clear trim start).
+@returns the sample offset of the start of the trim.
+*/
+sox_uint64_t
+LSX_API
+sox_trim_get_start(
+    LSX_PARAM_IN sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Clears the start of the trim to 0.
+*/
+void
+LSX_API
+sox_trim_clear_start(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Returns true if the specified file is a known playlist file type.
+@returns true if the specified file is a known playlist file type.
+*/
+sox_bool
+LSX_API
+sox_is_playlist(
+    LSX_PARAM_IN_Z char const * filename /**< Name of file to examine. */
+    );
+
+/**
+Client API:
+Parses the specified playlist file.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_parse_playlist(
+    LSX_PARAM_IN sox_playlist_callback_t callback, /**< Callback to call for each item in the playlist. */
+    void * p, /**< Data to pass to callback. */
+    LSX_PARAM_IN char const * const listname /**< Filename of playlist file. */
+    );
+
+/**
+Client API:
+Converts a SoX error code into an error string.
+@returns error string corresponding to the specified error code,
+or a generic message if the error code is not recognized.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_strerror(
+    int sox_errno /**< Error code to look up. */
+    );
+
+/**
+Client API:
+Gets the basename of the specified file; for example, the basename of
+"/a/b/c.d" would be "c".
+@returns the number of characters written to base_buffer, excluding the null,
+or 0 on failure.
+*/
+size_t
+LSX_API
+sox_basename(
+    LSX_PARAM_OUT_Z_CAP_POST_COUNT(base_buffer_len,return) char * base_buffer, /**< Buffer into which basename should be written. */
+    size_t base_buffer_len, /**< Size of base_buffer, in bytes. */
+    LSX_PARAM_IN_Z char const * filename /**< Filename from which to extract basename. */
+    );
+
+/*****************************************************************************
+Internal API:
+WARNING - The items in this section are subject to instability. They only
+exist in the public header because sox (the application) currently uses them.
+These may be changed or removed in future versions of libSoX.
+*****************************************************************************/
+
+/**
+Plugins API:
+Print a fatal error in libSoX.
+*/
+void
+LSX_API
+lsx_fail_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a warning in libSoX.
+*/
+void
+LSX_API
+lsx_warn_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print an informational message in libSoX.
+*/
+void
+LSX_API
+lsx_report_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a debug message in libSoX.
+*/
+void
+LSX_API
+lsx_debug_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Report a fatal error in libSoX; printf-style arguments must follow.
+*/
+#define lsx_fail       sox_get_globals()->subsystem=__FILE__,lsx_fail_impl
+
+/**
+Plugins API:
+Report a warning in libSoX; printf-style arguments must follow.
+*/
+#define lsx_warn       sox_get_globals()->subsystem=__FILE__,lsx_warn_impl
+
+/**
+Plugins API:
+Report an informational message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_report     sox_get_globals()->subsystem=__FILE__,lsx_report_impl
+
+/**
+Plugins API:
+Report a debug message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_debug      sox_get_globals()->subsystem=__FILE__,lsx_debug_impl
+
+/**
+Plugins API:
+String name and integer values for enumerated types (type metadata), for use
+with LSX_ENUM_ITEM, lsx_find_enum_text, and lsx_find_enum_value.
+*/
+typedef struct lsx_enum_item {
+    char const *text; /**< String name of enumeration. */
+    unsigned value;   /**< Integer value of enumeration. */
+} lsx_enum_item;
+
+/**
+Plugins API:
+Declares a static instance of an lsx_enum_item structure in format
+{ "item", prefixitem }, for use in declaring lsx_enum_item[] arrays.
+@param prefix The prefix to prepend to the item in the enumeration symbolic name.
+@param item   The user-visible text name of the item (must also be a valid C symbol name).
+*/
+#define LSX_ENUM_ITEM(prefix, item) {#item, prefix##item},
+
+/**
+Plugins API:
+Flags for use with lsx_find_enum_item.
+*/
+enum
+{
+    lsx_find_enum_item_none = 0, /**< Default parameters (case-insensitive). */
+    lsx_find_enum_item_case_sensitive = 1 /**< Enable case-sensitive search. */
+};
+
+/**
+Plugins API:
+Looks up an enumeration by name in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_text(
+    LSX_PARAM_IN_Z char const * text, /**< Name of enumeration to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items, /**< Array of items to search, with text == NULL for last item. */
+    int flags /**< Search flags: 0 (case-insensitive) or lsx_find_enum_item_case_sensitive (case-sensitive). */
+    );
+
+/**
+Plugins API:
+Looks up an enumeration by value in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_value(
+    unsigned value, /**< Enumeration value to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Looks up a command-line argument in a set of enumeration names, showing an
+error message if the argument is not found in the set of names.
+@returns The enumeration value corresponding to the matching enumeration, or
+INT_MAX if the argument does not match any enumeration name.
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_enum_option(
+    int c, /**< Option character to which arg is associated, for example with -a, c would be 'a'. */
+    LSX_PARAM_IN_Z char const * arg, /**< Argument to find in enumeration list. */
+    LSX_PARAM_IN lsx_enum_item const * items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Determines whether the specified string ends with the specified suffix (case-sensitive).
+@returns true if the specified string ends with the specified suffix.
+*/
+LSX_RETURN_PURE
+sox_bool
+LSX_API
+lsx_strends(
+    LSX_PARAM_IN_Z char const * str, /**< String to search. */
+    LSX_PARAM_IN_Z char const * end  /**< Suffix to search for. */
+    );
+
+/**
+Plugins API:
+Finds the file extension for a filename.
+@returns the file extension, not including the '.', or null if filename does
+not have an extension.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+lsx_find_file_extension(
+    LSX_PARAM_IN_Z char const * pathname /**< Filename to search for extension. */
+    );
+
+/**
+Plugins API:
+Formats the specified number with up to three significant figures and adds a
+metric suffix in place of the exponent, such as 1.23G.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3(
+    double number /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Formats the specified number as a percentage, showing up to three significant
+figures.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3p(
+    double percentage /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Allocates, deallocates, or resizes; like C's realloc, except that this version
+terminates the running application if unable to allocate the requested memory.
+@returns New buffer, or null if buffer was freed.
+*/
+LSX_RETURN_OPT
+void *
+LSX_API
+lsx_realloc(
+    LSX_PARAM_IN_OPT void *ptr, /**< Pointer to be freed or resized, or null if allocating a new buffer. */
+    size_t newsize /**< New size for buffer, or 0 to free the buffer. */
+    );
+
+/**
+Plugins API:
+Like strcmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strcasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2  /**< Second string. */
+    );
+
+
+/**
+Plugins API:
+Like strncmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strncasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2, /**< Second string. */
+    size_t n /**< Maximum number of characters to examine. */
+    );
+
+/**
+Plugins API:
+Is option argument unsupported, required, or optional.
+*/
+typedef enum lsx_option_arg_t {
+    lsx_option_arg_none, /**< Option does not have an argument. */
+    lsx_option_arg_required, /**< Option requires an argument. */
+    lsx_option_arg_optional /**< Option can optionally be followed by an argument. */
+} lsx_option_arg_t;
+
+/**
+Plugins API:
+lsx_getopt_init options.
+*/
+typedef enum lsx_getopt_flags_t {
+    lsx_getopt_flag_none = 0,      /**< no flags (no output, not long-only) */
+    lsx_getopt_flag_opterr = 1,    /**< if set, invalid options trigger lsx_warn output */
+    lsx_getopt_flag_longonly = 2   /**< if set, recognize -option as a long option */
+} lsx_getopt_flags_t;
+
+/**
+Plugins API:
+lsx_getopt long option descriptor.
+*/
+typedef struct lsx_option_t {
+    char const *     name;    /**< Name of the long option. */
+    lsx_option_arg_t has_arg; /**< Whether the long option supports an argument and, if so, whether the argument is required or optional. */
+    int *            flag;    /**< Flag to set if argument is present. */
+    int              val;     /**< Value to put in flag if argument is present. */
+} lsx_option_t;
+
+/**
+Plugins API:
+lsx_getopt session information (initialization data and state).
+*/
+typedef struct lsx_getopt_t {
+    int                  argc;     /**< IN    argc:      Number of arguments in argv */
+    char * const *       argv;     /**< IN    argv:      Array of arguments */
+    char const *         shortopts;/**< IN    shortopts: Short option characters */
+    lsx_option_t const * longopts; /**< IN    longopts:  Array of long option descriptors */
+    lsx_getopt_flags_t   flags;    /**< IN    flags:     Flags for longonly and opterr */
+    char const *         curpos;   /**< INOUT curpos:    Maintains state between calls to lsx_getopt */
+    int                  ind;      /**< INOUT optind:    Maintains the index of next element to be processed */
+    int                  opt;      /**< OUT   optopt:    Receives the option character that caused error */
+    char const *         arg;      /**< OUT   optarg:    Receives the value of the option's argument */
+    int                  lngind;   /**< OUT   lngind:    Receives the index of the matched long option or -1 if not a long option */
+} lsx_getopt_t;
+
+/**
+Plugins API:
+Initializes an lsx_getopt_t structure for use with lsx_getopt.
+*/
+void
+LSX_API
+lsx_getopt_init(
+    LSX_PARAM_IN             int argc,                      /**< Number of arguments in argv */
+    LSX_PARAM_IN_COUNT(argc) char * const * argv,           /**< Array of arguments */
+    LSX_PARAM_IN_Z           char const * shortopts,        /**< Short options, for example ":abc:def::ghi" (+/- not supported) */
+    LSX_PARAM_IN_OPT         lsx_option_t const * longopts, /**< Array of long option descriptors */
+    LSX_PARAM_IN             lsx_getopt_flags_t flags,      /**< Flags for longonly and opterr */
+    LSX_PARAM_IN             int first,                     /**< First argv to check (usually 1) */
+    LSX_PARAM_OUT            lsx_getopt_t * state           /**< State object to be initialized */
+    );
+
+/**
+Plugins API:
+Gets the next option. Options are parameters that start with "-" or "--".
+If no more options, returns -1. If unrecognized short option, returns '?'.
+If a recognized short option is missing a required argument,
+return (shortopts[0]==':' ? ':' : '?'). If successfully recognized short
+option, return the recognized character. If successfully recognized long
+option, returns (option.flag ? 0 : option.val).
+Note: lsx_getopt does not permute the non-option arguments.
+@returns option character (short), val or 0 (long), or -1 (no more).
+*/
+int
+LSX_API
+lsx_getopt(
+    LSX_PARAM_INOUT lsx_getopt_t * state /**< The getopt state pointer. */
+    );
+
+/* WARNING END */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* SOX_H */
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/sox_i.h b/freedv/tags/1.2.2/freedv-dev/src/sox/sox_i.h
new file mode 100644 (file)
index 0000000..9d53326
--- /dev/null
@@ -0,0 +1,417 @@
+/* libSoX Internal header
+ *
+ *   This file is meant for libSoX internal use only
+ *
+ * Copyright 2001-2008 Chris Bagwell and SoX Contributors
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#ifndef SOX_I_H
+#define SOX_I_H
+
+#include "soxomp.h"  /* Note: soxomp.h includes soxconfig.h */
+#include "sox.h"
+
+#define __FREEDV__
+
+#if defined HAVE_FMEMOPEN
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#if defined(LSX_EFF_ALIAS)
+#undef lsx_debug
+#undef lsx_fail
+#undef lsx_report
+#undef lsx_warn
+#define lsx_debug sox_globals.subsystem=effp->handler.name,lsx_debug_impl
+#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail_impl
+#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report_impl
+#define lsx_warn sox_globals.subsystem=effp->handler.name,lsx_warn_impl
+#endif
+
+#define RANQD1 ranqd1(sox_globals.ranqd1)
+#define DRANQD1 dranqd1(sox_globals.ranqd1)
+
+typedef enum {SOX_SHORT, SOX_INT, SOX_FLOAT, SOX_DOUBLE} sox_data_t;
+typedef enum {SOX_WAVE_SINE, SOX_WAVE_TRIANGLE} lsx_wave_t;
+lsx_enum_item const * lsx_get_wave_enum(void);
+
+/* Define fseeko and ftello for platforms lacking them */
+#ifndef HAVE_FSEEKO
+#define fseeko fseek
+#define ftello ftell
+#endif
+
+#ifdef _FILE_OFFSET_BITS
+assert_static(sizeof(off_t) == _FILE_OFFSET_BITS >> 3, OFF_T_BUILD_PROBLEM);
+#endif
+
+FILE * lsx_tmpfile(void);
+
+void lsx_debug_more_impl(char const * fmt, ...) LSX_PRINTF12;
+void lsx_debug_most_impl(char const * fmt, ...) LSX_PRINTF12;
+
+#define lsx_debug_more sox_get_globals()->subsystem=__FILE__,lsx_debug_more_impl
+#define lsx_debug_most sox_get_globals()->subsystem=__FILE__,lsx_debug_most_impl
+
+/* Digitise one cycle of a wave and store it as
+ * a table of samples of a specified data-type.
+ */
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void * table,       /* Really of type indicated by data_type. */
+    size_t table_size,  /* Number of points on the x-axis. */
+    double min,         /* Minimum value on the y-axis. (e.g. -1) */
+    double max,         /* Maximum value on the y-axis. (e.g. +1) */
+    double phase);      /* Phase at 1st point; 0..2pi. (e.g. pi/2 for cosine) */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str, uint64_t *samples, int def);
+int lsx_parse_note(char const * text, char * * end_ptr);
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key);
+#define lsx_parse_frequency(a, b) lsx_parse_frequency_k(a, b, INT_MAX)
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename);
+
+void lsx_prepare_spline3(double const * x, double const * y, int n,
+    double start_1d, double end_1d, double * y_2d);
+double lsx_spline3(double const * x, double const * y, double const * y_2d,
+    int n, double x1);
+
+double lsx_bessel_I_0(double x);
+int lsx_set_dft_length(int num_taps);
+void init_fft_cache(void);
+void clear_fft_cache(void);
+void lsx_safe_rdft(int len, int type, double * d);
+void lsx_safe_cdft(int len, int type, double * d);
+void lsx_power_spectrum(int n, double const * in, double * out);
+void lsx_power_spectrum_f(int n, float const * in, float * out);
+void lsx_apply_hann_f(float h[], const int num_points);
+void lsx_apply_hann(double h[], const int num_points);
+void lsx_apply_hamming(double h[], const int num_points);
+void lsx_apply_bartlett(double h[], const int num_points);
+void lsx_apply_blackman(double h[], const int num_points, double alpha);
+void lsx_apply_blackman_nutall(double h[], const int num_points);
+double lsx_kaiser_beta(double att);
+void lsx_apply_kaiser(double h[], const int num_points, double beta);
+double * lsx_make_lpf(int num_taps, double Fc, double beta, double scale, sox_bool dc_norm);
+int lsx_lpf_num_taps(double att, double tr_bw, int k);
+double * lsx_design_lpf(
+    double Fp,      /* End of pass-band; ~= 0.01dB point */
+    double Fc,      /* Start of stop-band */
+    double Fn,      /* Nyquist freq; e.g. 0.5, 1, PI */
+    sox_bool allow_aliasing,
+    double att,     /* Stop-band attenuation in dB */
+    int * num_taps, /* (Single phase.)  0: value will be estimated */
+    int k);         /* Number of phases; 0 for single-phase */
+void lsx_fir_to_phase(double * * h, int * len,
+    int * post_len, double phase0);
+#define LSX_TO_6dB .5869
+#define LSX_TO_3dB ((2/3.) * (.5 + LSX_TO_6dB))
+#define LSX_MAX_TBW0 36.
+#define LSX_MAX_TBW0A (LSX_MAX_TBW0 / (1 + LSX_TO_3dB))
+#define LSX_MAX_TBW3 floor(LSX_MAX_TBW0 * LSX_TO_3dB)
+#define LSX_MAX_TBW3A floor(LSX_MAX_TBW0A * LSX_TO_3dB)
+void lsx_plot_fir(double * h, int num_points, sox_rate_t rate, sox_plot_t type, char const * title, double y1, double y2);
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#define lsx_swapw(x) bswap_16(x)
+#define lsx_swapdw(x) bswap_32(x)
+#elif defined(_MSC_VER)
+#define lsx_swapw(x) _byteswap_ushort(x)
+#define lsx_swapdw(x) _byteswap_ulong(x)
+#else
+#define lsx_swapw(uw) (((uw >> 8) | (uw << 8)) & 0xffff)
+#define lsx_swapdw(udw) ((udw >> 24) | ((udw >> 8) & 0xff00) | ((udw << 8) & 0xff0000) | (udw << 24))
+#endif
+
+
+
+/*------------------------ Implemented in libsoxio.c -------------------------*/
+
+/* Read and write basic data types from "ft" stream. */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len);
+int lsx_skipbytes(sox_format_t * ft, size_t n);
+int lsx_padbytes(sox_format_t * ft, size_t n);
+size_t lsx_writebuf(sox_format_t * ft, void const *buf, size_t len);
+int lsx_reads(sox_format_t * ft, char *c, size_t len);
+int lsx_writes(sox_format_t * ft, char const * c);
+void lsx_set_signal_defaults(sox_format_t * ft);
+#define lsx_writechars(ft, chars, len) (lsx_writebuf(ft, chars, len) == len? SOX_SUCCESS : SOX_EOF)
+
+size_t lsx_read_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+size_t lsx_read_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
+size_t lsx_read_df_buf(sox_format_t * ft, double *buf, size_t len);
+size_t lsx_read_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_read_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
+size_t lsx_read_f_buf(sox_format_t * ft, float *buf, size_t len);
+size_t lsx_read_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
+
+size_t lsx_write_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+size_t lsx_write_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
+size_t lsx_write_df_buf(sox_format_t * ft, double *buf, size_t len);
+size_t lsx_write_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_write_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
+size_t lsx_write_f_buf(sox_format_t * ft, float *buf, size_t len);
+size_t lsx_write_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
+
+int lsx_read3(sox_format_t * ft, sox_uint24_t * u3);
+int lsx_readb(sox_format_t * ft, uint8_t * ub);
+int lsx_readchars(sox_format_t * ft, char * chars, size_t len);
+int lsx_readdf(sox_format_t * ft, double * d);
+int lsx_readdw(sox_format_t * ft, uint32_t * udw);
+int lsx_readqw(sox_format_t * ft, uint64_t * udw);
+int lsx_readf(sox_format_t * ft, float * f);
+int lsx_readw(sox_format_t * ft, uint16_t * uw);
+
+#if 1 /* FIXME: use defines */
+UNUSED static int lsx_readsb(sox_format_t * ft, int8_t * sb)
+{return lsx_readb(ft, (uint8_t *)sb);}
+UNUSED static int lsx_readsw(sox_format_t * ft, int16_t * sw)
+{return lsx_readw(ft, (uint16_t *)sw);}
+#else
+#define lsx_readsb(ft, sb) lsx_readb(ft, (uint8_t *)sb)
+#define lsx_readsw(ft, sw) lsx_readb(ft, (uint16_t *)sw)
+#endif
+
+int lsx_write3(sox_format_t * ft, unsigned u3);
+int lsx_writeb(sox_format_t * ft, unsigned ub);
+int lsx_writedf(sox_format_t * ft, double d);
+int lsx_writedw(sox_format_t * ft, unsigned udw);
+int lsx_writeqw(sox_format_t * ft, uint64_t uqw);
+int lsx_writef(sox_format_t * ft, double f);
+int lsx_writew(sox_format_t * ft, unsigned uw);
+
+int lsx_writesb(sox_format_t * ft, signed);
+int lsx_writesw(sox_format_t * ft, signed);
+
+int lsx_eof(sox_format_t * ft);
+int lsx_error(sox_format_t * ft);
+int lsx_flush(sox_format_t * ft);
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence);
+int lsx_unreadb(sox_format_t * ft, unsigned ub);
+uint64_t lsx_filelength(sox_format_t * ft);
+off_t lsx_tell(sox_format_t * ft);
+void lsx_clearerr(sox_format_t * ft);
+void lsx_rewind(sox_format_t * ft);
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample);
+
+void lsx_fail_errno(sox_format_t *, int, const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 3, 4)));
+#else
+;
+#endif
+
+typedef struct sox_formats_globals { /* Global parameters (for formats) */
+  sox_globals_t * global_info;
+} sox_formats_globals;
+
+
+
+/*------------------------------ File Handlers -------------------------------*/
+
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length);
+#define LSX_FORMAT_HANDLER(name) \
+sox_format_handler_t const * lsx_##name##_format_fn(void); \
+sox_format_handler_t const * lsx_##name##_format_fn(void)
+#define div_bits(size, bits) ((uint64_t)(size) * 8 / bits)
+
+/* Raw I/O */
+int lsx_rawstartread(sox_format_t * ft);
+size_t lsx_rawread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp);
+int lsx_rawstopread(sox_format_t * ft);
+int lsx_rawstartwrite(sox_format_t * ft);
+size_t lsx_rawwrite(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp);
+int lsx_rawseek(sox_format_t * ft, uint64_t offset);
+int lsx_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_bool default_length, sox_encoding_t encoding, unsigned bits_per_sample);
+#define lsx_rawstartread(ft) lsx_rawstart(ft, sox_false, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
+#define lsx_rawstartwrite lsx_rawstartread
+#define lsx_rawstopread NULL
+#define lsx_rawstopwrite NULL
+
+extern sox_format_handler_t const * lsx_sndfile_format_fn(void);
+
+char * lsx_cat_comments(sox_comments_t comments);
+
+/*--------------------------------- Effects ----------------------------------*/
+
+int lsx_flow_copy(sox_effect_t * effp, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp);
+int lsx_usage(sox_effect_t * effp);
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n);
+#define EFFECT(f) extern sox_effect_handler_t const * lsx_##f##_effect_fn(void);
+#include "effects.h"
+#undef EFFECT
+
+#define NUMERIC_PARAMETER(name, min, max) { \
+  char * end_ptr; \
+  double d; \
+  if (argc == 0) break; \
+  d = strtod(*argv, &end_ptr); \
+  if (end_ptr != *argv) { \
+    if (d < min || d > max || *end_ptr != '\0') {\
+      lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+      return lsx_usage(effp); \
+    } \
+    p->name = d; \
+    --argc, ++argv; \
+  } \
+}
+
+#define TEXTUAL_PARAMETER(name, enum_table) { \
+  lsx_enum_item const * e; \
+  if (argc == 0) break; \
+  e = lsx_find_enum_text(*argv, enum_table, 0); \
+  if (e != NULL) { \
+    p->name = e->value; \
+    --argc, ++argv; \
+  } \
+}
+
+#define GETOPT_NUMERIC(state, ch, name, min, max) case ch:{ \
+  char * end_ptr; \
+  double d = strtod(state.arg, &end_ptr); \
+  if (end_ptr == state.arg || d < min || d > max || *end_ptr != '\0') {\
+    lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+    return lsx_usage(effp); \
+  } \
+  p->name = d; \
+  break; \
+}
+
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin);
+
+int lsx_effects_init(void);
+int lsx_effects_quit(void);
+
+/*--------------------------------- Dynamic Library ----------------------------------*/
+
+#if defined(HAVE_WIN32_LTDL_H)
+    #include "win32-ltdl.h"
+    #define HAVE_LIBLTDL 1
+    typedef lt_dlhandle lsx_dlhandle;
+#elif defined(HAVE_LIBLTDL)
+    #include <ltdl.h>
+    typedef lt_dlhandle lsx_dlhandle;
+#else
+    struct lsx_dlhandle_tag;
+    typedef struct lsx_dlhandle_tag *lsx_dlhandle;
+#endif
+
+typedef void (*lsx_dlptr)(void);
+
+typedef struct lsx_dlfunction_info
+{
+    const char* name;
+    lsx_dlptr static_func;
+    lsx_dlptr stub_func;
+} lsx_dlfunction_info;
+
+int lsx_open_dllibrary(
+    int show_error_on_failure,
+    const char* library_description,
+    const char * const library_names[],
+    const lsx_dlfunction_info func_infos[],
+    lsx_dlptr selected_funcs[],
+    lsx_dlhandle* pdl);
+
+void lsx_close_dllibrary(
+    lsx_dlhandle dl);
+
+#define LSX_DLENTRIES_APPLY__(entries, f, x) entries(f, x)
+
+#define LSX_DLENTRY_TO_PTR__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return (*func_ptr) func_args;
+
+#define LSX_DLENTRIES_TO_FUNCTIONS__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return func_name func_args;
+
+/* LSX_DLENTRIES_TO_PTRS: Given an ENTRIES macro and the name of the dlhandle
+   variable, declares the corresponding function pointer variables and the
+   dlhandle variable. */
+#define LSX_DLENTRIES_TO_PTRS(entries, dlhandle) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRY_TO_PTR__, 0) \
+    lsx_dlhandle dlhandle
+
+/* LSX_DLENTRIES_TO_FUNCTIONS: Given an ENTRIES macro, declares the corresponding
+   functions. */
+#define LSX_DLENTRIES_TO_FUNCTIONS(entries) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRIES_TO_FUNCTIONS__, 0)
+
+#define LSX_DLLIBRARY_OPEN1__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    { #func_name, (lsx_dlptr)(static_func), (lsx_dlptr)(stub_func) },
+
+#define LSX_DLLIBRARY_OPEN2__(ptr_container, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    (ptr_container)->func_ptr = (func_return (*)func_args)lsx_dlfunction_open_library_funcs[lsx_dlfunction_open_library_index++];
+
+/* LSX_DLLIBRARY_OPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a failure message. */
+#define LSX_DLLIBRARY_OPEN(ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    LSX_DLLIBRARY_TRYOPEN(1, ptr_container, dlhandle, entries, library_description, library_names, return_var)
+
+/* LSX_DLLIBRARY_TRYOPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a report or a failure
+   message, depending on whether error_on_failure is non-zero. */
+#define LSX_DLLIBRARY_TRYOPEN(error_on_failure, ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    do { \
+      lsx_dlfunction_info lsx_dlfunction_open_library_infos[] = { \
+        LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN1__, 0) \
+        {NULL,NULL,NULL} }; \
+      int lsx_dlfunction_open_library_index = 0; \
+      lsx_dlptr lsx_dlfunction_open_library_funcs[sizeof(lsx_dlfunction_open_library_infos)/sizeof(lsx_dlfunction_open_library_infos[0])]; \
+      (return_var) = lsx_open_dllibrary((error_on_failure), (library_description), (library_names), lsx_dlfunction_open_library_infos, lsx_dlfunction_open_library_funcs, &(ptr_container)->dlhandle); \
+      LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN2__, ptr_container) \
+    } while(0)
+
+#define LSX_DLLIBRARY_CLOSE(ptr_container, dlhandle) \
+    lsx_close_dllibrary((ptr_container)->dlhandle)
+
+  /* LSX_DLENTRY_STATIC: For use in creating an ENTRIES macro. func is
+     expected to be available at link time. If not present, link will fail. */
+#define LSX_DLENTRY_STATIC(f,x, ret, func, args)  f(x, ret, func, args, func, NULL, func)
+
+  /* LSX_DLENTRY_DYNAMIC: For use in creating an ENTRIES macro. func need
+     not be available at link time (and if present, the link time version will
+     not be used). func will be loaded via dlsym. If this function is not
+     found in the shared library, the shared library will not be used. */
+#define LSX_DLENTRY_DYNAMIC(f,x, ret, func, args) f(x, ret, func, args, NULL, NULL, func)
+
+  /* LSX_DLENTRY_STUB: For use in creating an ENTRIES macro. func need not
+     be available at link time (and if present, the link time version will not
+     be used). If using DL_LAME, the func may be loaded via dlopen/dlsym, but
+     if not found, the shared library will still be used if all of the
+     non-stub functions are found. If the function is not found via dlsym (or
+     if we are not loading any shared libraries), the stub will be used. This
+     assumes that the name of the stub function is the name of the function +
+     "_stub". */
+#define LSX_DLENTRY_STUB(f,x, ret, func, args)    f(x, ret, func, args, NULL, func##_stub, func)
+
+  /* LSX_DLFUNC_IS_STUB: returns true if the named function is a do-nothing
+     stub. Assumes that the name of the stub function is the name of the
+     function + "_stub". */
+#define LSX_DLFUNC_IS_STUB(ptr_container, func) ((ptr_container)->func == func##_stub)
+
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/soxomp.h b/freedv/tags/1.2.2/freedv-dev/src/sox/soxomp.h
new file mode 100644 (file)
index 0000000..6fce07d
--- /dev/null
@@ -0,0 +1,38 @@
+#include "soxconfig.h"
+
+#ifdef HAVE_OPENMP
+  #include <omp.h>
+#else
+
+typedef int omp_lock_t;
+typedef int omp_nest_lock_t;
+
+#define omp_set_num_threads(int) (void)0
+#define omp_get_num_threads() 1
+#define omp_get_max_threads() 1
+#define omp_get_thread_num() 0
+#define omp_get_num_procs() 1
+#define omp_in_parallel() 1
+
+#define omp_set_dynamic(int) (void)0
+#define omp_get_dynamic() 0
+
+#define omp_set_nested(int) (void)0
+#define omp_get_nested() 0
+
+#define omp_init_lock(omp_lock_t) (void)0
+#define omp_destroy_lock(omp_lock_t) (void)0
+#define omp_set_lock(omp_lock_t) (void)0
+#define omp_unset_lock(omp_lock_t) (void)0
+#define omp_test_lock(omp_lock_t) 0
+
+#define omp_init_nest_lock(omp_nest_lock_t) (void)0
+#define omp_destroy_nest_lock(omp_nest_lock_t) (void)0
+#define omp_set_nest_lock(omp_nest_lock_t) (void)0
+#define omp_unset_nest_lock(omp_nest_lock_t) (void)0
+#define omp_test_nest_lock(omp_nest_lock_t) 0
+
+#define omp_get_wtime() 0
+#define omp_get_wtick() 0
+
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/util.h b/freedv/tags/1.2.2/freedv-dev/src/sox/util.h
new file mode 100644 (file)
index 0000000..89bbe75
--- /dev/null
@@ -0,0 +1,231 @@
+/* General purpose, i.e. non SoX specific, utility functions and macros.
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "soxconfig.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h> /* For off_t not found in stdio.h */
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h> /* Needs to be included before we redefine off_t. */
+#endif
+
+#include "xmalloc.h"
+
+/*---------------------------- Portability stuff -----------------------------*/
+
+#if defined(HAVE_INTTYPES_H)
+  #include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+  #include <stdint.h>
+#else
+  typedef sox_int8_t   int8_t;
+  typedef sox_uint8_t  uint8_t;
+  typedef sox_int16_t  int16_t;
+  typedef sox_uint16_t uint16_t;
+  typedef sox_int32_t  int32_t;
+  typedef sox_uint32_t uint32_t;
+  typedef sox_int64_t  int64_t;
+  typedef sox_uint64_t uint64_t;
+#endif
+
+/* Define the format specifier to use for int64_t values.
+ * Example: printf("You may have already won $ %" PRId64 " !!!", n64); */
+#ifndef PRId64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %lld. */
+#define PRId64 "I64d"
+#elif LONG_MAX==9223372036854775807
+#define PRId64 "ld"
+#else
+#define PRId64 "lld"
+#endif
+#endif /* PRId64 */
+
+/* Define the format specifier to use for uint64_t values. */
+#ifndef PRIu64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %llu. */
+#define PRIu64 "I64u"
+#elif ULONG_MAX==0xffffffffffffffff
+#define PRIu64 "lu"
+#else
+#define PRIu64 "llu"
+#endif
+#endif /* PRIu64 */
+
+/* Define the format specifier to use for size_t values.
+ * Example: printf("Sizeof(x) = %" PRIuPTR " bytes", sizeof(x)); */
+#ifndef PRIuPTR /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %zu. */
+#define PRIuPTR "Iu"
+#else
+#define PRIuPTR "zu"
+#endif
+#endif /* PRIuPTR */
+
+#ifdef __GNUC__
+#define NORET __attribute__((noreturn))
+#define UNUSED __attribute__ ((unused))
+#else
+#define NORET
+#define UNUSED
+#endif
+
+#ifdef _MSC_VER
+
+#define __STDC__ 1
+#define O_BINARY _O_BINARY
+#define O_CREAT _O_CREAT
+#define O_RDWR _O_RDWR
+#define O_TRUNC _O_TRUNC
+#define S_IFMT _S_IFMT
+#define S_IFREG _S_IFREG
+#define S_IREAD _S_IREAD
+#define S_IWRITE _S_IWRITE
+#define close _close
+#define dup _dup
+#define fdopen _fdopen
+#define fileno _fileno
+
+#ifdef _fstati64
+#define fstat _fstati64
+#else
+#define fstat _fstat
+#endif
+
+#define ftime _ftime
+#define inline __inline
+#define isatty _isatty
+#define kbhit _kbhit
+#define mktemp _mktemp
+#define off_t _off_t
+#define open _open
+#define pclose _pclose
+#define popen _popen
+#define setmode _setmode
+#define snprintf _snprintf
+
+#ifdef _stati64
+#define stat _stati64
+#else
+#define stat _stat
+#endif
+
+#define strdup _strdup
+#define timeb _timeb
+#define unlink _unlink
+
+#if defined(HAVE__FSEEKI64) && !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko _fseeki64
+#define ftello _ftelli64
+#define off_t __int64
+#define HAVE_FSEEKO 1
+#endif
+
+#elif defined(__MINGW32__)
+
+#if !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko fseeko64
+#define fstat _fstati64
+#define ftello ftello64
+#define off_t off64_t
+#define stat _stati64
+#define HAVE_FSEEKO 1
+#endif
+
+#endif
+
+#if defined(DOS) || defined(WIN32) || defined(__NT__) || defined(__DJGPP__) || defined(__OS2__)
+  #define LAST_SLASH(path) max(strrchr(path, '/'), strrchr(path, '\\'))
+  #define IS_ABSOLUTE(path) ((path)[0] == '/' || (path)[0] == '\\' || (path)[1] == ':')
+  #define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+  #define POPEN_MODE "rb"
+#else
+  #define LAST_SLASH(path) strrchr(path, '/')
+  #define IS_ABSOLUTE(path) ((path)[0] == '/')
+  #define SET_BINARY_MODE(file)
+#endif
+
+#ifdef WORDS_BIGENDIAN
+  #define MACHINE_IS_BIGENDIAN 1
+  #define MACHINE_IS_LITTLEENDIAN 0
+#else
+  #define MACHINE_IS_BIGENDIAN 0
+  #define MACHINE_IS_LITTLEENDIAN 1
+#endif
+
+/*--------------------------- Language extensions ----------------------------*/
+
+/* Compile-time ("static") assertion */
+/*   e.g. assert_static(sizeof(int) >= 4, int_type_too_small)    */
+#define assert_static(e,f) enum {assert_static__##f = 1/(e)}
+#define array_length(a) (sizeof(a)/sizeof(a[0]))
+#define field_offset(type, field) ((size_t)&(((type *)0)->field))
+#define unless(x) if (!(x))
+
+/*------------------------------- Maths stuff --------------------------------*/
+
+#include <math.h>
+
+#ifdef min
+#undef min
+#endif
+#define min(a, b) ((a) <= (b) ? (a) : (b))
+
+#ifdef max
+#undef max
+#endif
+#define max(a, b) ((a) >= (b) ? (a) : (b))
+
+#define range_limit(x, lower, upper) (min(max(x, lower), upper))
+
+#ifndef M_PI
+#define M_PI    3.14159265358979323846
+#endif
+#ifndef M_PI_2
+#define M_PI_2  1.57079632679489661923  /* pi/2 */
+#endif
+#ifndef M_LN10
+#define M_LN10  2.30258509299404568402  /* natural log of 10 */
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2  sqrt(2.)
+#endif
+
+#define sqr(a) ((a) * (a))
+#define sign(x) ((x) < 0? -1 : 1)
+
+/* Numerical Recipes in C, p. 284 */
+#define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */
+#define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
+
+#define dB_to_linear(x) exp((x) * M_LN10 * 0.05)
+#define linear_to_dB(x) (log10(x) * 20)
+
+extern int lsx_strcasecmp(const char *s1, const char *st);
+extern int lsx_strncasecmp(char const *s1, char const *s2, size_t n);
+
+#ifndef HAVE_STRCASECMP
+#define strcasecmp(s1, s2) lsx_strcasecmp((s1), (s2))
+#define strncasecmp(s1, s2, n) lsx_strncasecmp((s1), (s2), (n))
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/xmalloc.c b/freedv/tags/1.2.2/freedv-dev/src/sox/xmalloc.c
new file mode 100644 (file)
index 0000000..9bf1596
--- /dev/null
@@ -0,0 +1,43 @@
+/* SoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <stdlib.h>
+
+/* Resize an allocated memory area; abort if not possible.
+ *
+ * For malloc, `If the size of the space requested is zero, the behavior is
+ * implementation defined: either a null pointer is returned, or the
+ * behavior is as if the size were some nonzero value, except that the
+ * returned pointer shall not be used to access an object'
+ */
+void *lsx_realloc(void *ptr, size_t newsize)
+{
+  if (ptr && newsize == 0) {
+    free(ptr);
+    return NULL;
+  }
+
+  if ((ptr = realloc(ptr, newsize)) == NULL) {
+    lsx_fail("out of memory");
+    exit(2);
+  }
+
+  return ptr;
+}
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox/xmalloc.h b/freedv/tags/1.2.2/freedv-dev/src/sox/xmalloc.h
new file mode 100644 (file)
index 0000000..9ee77f6
--- /dev/null
@@ -0,0 +1,34 @@
+/* libSoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef LSX_MALLOC_H
+#define LSX_MALLOC_H
+
+#include <stddef.h>
+#include <string.h>
+
+#define lsx_malloc(size) lsx_realloc(NULL, (size))
+#define lsx_calloc(n,s) (((n)*(s))? memset(lsx_malloc((n)*(s)),0,(n)*(s)) : NULL)
+#define lsx_Calloc(v,n)  v = lsx_calloc(n,sizeof(*(v)))
+#define lsx_strdup(p) ((p)? strcpy((char *)lsx_malloc(strlen(p) + 1), p) : NULL)
+#define lsx_memdup(p,s) ((p)? memcpy(lsx_malloc(s), p, s) : NULL)
+#define lsx_valloc(v,n)  v = lsx_malloc((n)*sizeof(*(v)))
+#define lsx_revalloc(v,n)  v = lsx_realloc(v, (n)*sizeof(*(v)))
+
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox_biquad.c b/freedv/tags/1.2.2/freedv-dev/src/sox_biquad.c
new file mode 100644 (file)
index 0000000..548f424
--- /dev/null
@@ -0,0 +1,134 @@
+//==========================================================================
+// Name:            sox_biquad.h
+// Purpose:         Interface into Sox Biquad filters 
+// Created:         Dec 1, 2012
+// Authors:         David Rowe
+// 
+// To test:
+/*
+          $ gcc sox_biquad.c sox/effects_i.c sox/effects.c sox/formats_i.c \
+            sox/biquad.c sox/biquads.c sox/xmalloc.c sox/libsox.c \
+            -o sox_biquad -DSOX_BIQUAD_UNITTEST -D__FREEDV__ \
+            -Wall -lm -lsndfile -g
+          $ ./sox_biquad
+*/
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "sox/sox.h"
+
+#include "sox_biquad.h"
+
+
+#define N_MAX 1024
+
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
+                    sox_sample_t *obuf, size_t *isamp, size_t *osamp);
+
+void sox_biquad_start(void)
+{
+    int r = sox_init();
+    assert(r == SOX_SUCCESS);
+}
+
+void sox_biquad_finish(void)
+{
+    sox_quit();
+}
+
+/*
+  Effect must be implemented by biquads.c in sox, arguments are just
+  like sox command line, for example:
+
+  char *argv[10];
+  argv[0] = "highpass"; argv[1]="1000"; argc=1;
+*/
+
+void *sox_biquad_create(int argc, const char *argv[])
+{
+    int ret;
+    sox_effect_t *e;
+    int (*start)(sox_effect_t *); /* function pointer to effect start func */
+    
+    e = sox_create_effect(sox_find_effect(argv[0])); assert(e != NULL);
+    ret = sox_effect_options(e, argc, (char * const*)&argv[1]);
+    assert(ret == SOX_SUCCESS);
+
+    start = e->handler.start;
+    e->in_signal.rate = 8000;     /* locked at FS=8000 Hz */
+    ret = start(e); assert(ret == SOX_SUCCESS);
+    
+    return (void *)e;
+}
+
+void sox_biquad_destroy(void *sbq) {
+    sox_effect_t *e = (sox_effect_t *)sbq;
+    free(e);
+}
+
+void sox_biquad_filter(void *sbq, short out[], short in[], int n)
+{
+    sox_effect_t *e = (sox_effect_t *)sbq;
+    sox_sample_t ibuf[N_MAX];
+    sox_sample_t obuf[N_MAX];
+    size_t isamp, osamp;
+    unsigned int clips;
+    SOX_SAMPLE_LOCALS; 
+    int i;
+
+    assert(n <= N_MAX);
+
+    clips = 0;
+    for(i=0; i<n; i++)
+        ibuf[i] = SOX_SIGNED_16BIT_TO_SAMPLE(in[i], clips);
+    isamp = osamp = (unsigned int)n;
+    lsx_biquad_flow(e, ibuf, obuf, &isamp, &osamp);
+    for(i=0; i<n; i++)
+        out[i] = SOX_SAMPLE_TO_SIGNED_16BIT(obuf[i], clips); 
+}
+
+
+#ifdef SOX_BIQUAD_UNITTEST
+#define N 20
+int main(void) {
+    void *sbq;
+    const char *argv[] = {"highpass", "1000"};
+    short in[N];
+    short out[N];
+    int   i, argc;;
+
+    for(i=0; i<N; i++)
+        in[i] = 0;
+    in[0] = 8000;
+
+    sox_biquad_start();
+    //argv[0] = "highpass"; argv[1]="1000"; 
+    argc=1;
+    sbq = sox_biquad_create(argc, argv);
+
+    sox_biquad_filter(sbq, out, in, N);
+    for(i=0; i<N; i++)
+        printf("%d\n", out[i]);
+   
+    sox_biquad_destroy(sbq);
+    sox_biquad_finish();
+
+    return 0;
+}
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/sox_biquad.h b/freedv/tags/1.2.2/freedv-dev/src/sox_biquad.h
new file mode 100644 (file)
index 0000000..f38de64
--- /dev/null
@@ -0,0 +1,40 @@
+//==========================================================================
+// Name:            sox_biquad.h
+// Purpose:         Interface into Sox Biquad filters 
+// Created:         Dec 1, 2012
+// Authors:         David Rowe
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __SOX_BIQUAD__
+#define __SOX_BIQUAD__
+
+#ifdef __cplusplus
+extern "C" {
+
+#endif
+
+void sox_biquad_start(void);
+void sox_biquad_finish(void);
+void *sox_biquad_create(int argc, const char *argv[]);
+void sox_biquad_destroy(void *sbq);
+void sox_biquad_filter(void *sbq, short out[], short in[], int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freedv/tags/1.2.2/freedv-dev/src/topFrame.cpp b/freedv/tags/1.2.2/freedv-dev/src/topFrame.cpp
new file mode 100644 (file)
index 0000000..a5b574a
--- /dev/null
@@ -0,0 +1,595 @@
+//==========================================================================
+// Name:            topFrame.cpp
+//
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "topFrame.h"
+
+extern int g_playFileToMicInEventId;
+extern int g_recFileFromRadioEventId;
+extern int g_playFileFromRadioEventId;
+
+//=========================================================================
+// Code that lays out the main application window
+//=========================================================================
+TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style)
+{
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+    this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+    this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+    this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+    this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
+    //=====================================================
+    // Menubar Setup
+    m_menubarMain = new wxMenuBar(wxMB_DOCKABLE);
+    file = new wxMenu();
+
+    wxMenuItem* m_menuItemOnTop;
+    m_menuItemOnTop = new wxMenuItem(file, wxID_ANY, wxString(_("On Top")) , _("Always Top Window"), wxITEM_NORMAL);
+    file->Append(m_menuItemOnTop);
+
+    wxMenuItem* m_menuItemExit;
+    m_menuItemExit = new wxMenuItem(file, ID_EXIT, wxString(_("E&xit")) , _("Exit Program"), wxITEM_NORMAL);
+    file->Append(m_menuItemExit);
+
+    m_menubarMain->Append(file, _("&File"));
+
+    tools = new wxMenu();
+    wxMenuItem* m_menuItemAudio;
+    m_menuItemAudio = new wxMenuItem(tools, wxID_ANY, wxString(_("&Audio Config")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemAudio);
+
+    wxMenuItem* m_menuItemRigCtrlCfg;
+    m_menuItemRigCtrlCfg = new wxMenuItem(tools, wxID_ANY, wxString(_("&PTT Config")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemRigCtrlCfg);
+
+    wxMenuItem* m_menuItemOptions;
+    m_menuItemOptions = new wxMenuItem(tools, wxID_ANY, wxString(_("Options")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemOptions);
+
+    wxMenuItem* m_menuItemFilter;
+    m_menuItemFilter = new wxMenuItem(tools, wxID_ANY, wxString(_("&Filter")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemFilter);
+
+    wxMenuItem* m_menuItemPlugIn;
+    if (!wxIsEmpty(plugInName)) {
+        m_menuItemPlugIn = new wxMenuItem(tools, wxID_ANY, plugInName + wxString(_(" Config")) , wxEmptyString, wxITEM_NORMAL);
+        tools->Append(m_menuItemPlugIn);
+    }
+
+    wxMenuItem* m_menuItemPlayFileToMicIn;
+    m_menuItemPlayFileToMicIn = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - Mic In")) , wxEmptyString, wxITEM_NORMAL);
+    g_playFileToMicInEventId = m_menuItemPlayFileToMicIn->GetId();
+    tools->Append(m_menuItemPlayFileToMicIn);
+
+    wxMenuItem* m_menuItemRecFileFromRadio;
+    m_menuItemRecFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Record File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
+    g_recFileFromRadioEventId = m_menuItemRecFileFromRadio->GetId();
+    tools->Append(m_menuItemRecFileFromRadio);
+
+    wxMenuItem* m_menuItemPlayFileFromRadio;
+    m_menuItemPlayFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
+    g_playFileFromRadioEventId = m_menuItemPlayFileFromRadio->GetId();
+    tools->Append(m_menuItemPlayFileFromRadio);
+    m_menubarMain->Append(tools, _("&Tools"));
+
+    help = new wxMenu();
+    wxMenuItem* m_menuItemHelpUpdates;
+    m_menuItemHelpUpdates = new wxMenuItem(help, wxID_ANY, wxString(_("Check for Updates")) , wxEmptyString, wxITEM_NORMAL);
+    help->Append(m_menuItemHelpUpdates);
+    m_menuItemHelpUpdates->Enable(false);
+
+    wxMenuItem* m_menuItemAbout;
+    m_menuItemAbout = new wxMenuItem(help, ID_ABOUT, wxString(_("&About")) , _("About this program"), wxITEM_NORMAL);
+    help->Append(m_menuItemAbout);
+
+    m_menubarMain->Append(help, _("&Help"));
+
+    this->SetMenuBar(m_menubarMain);
+
+    wxBoxSizer* bSizer1;
+    bSizer1 = new wxBoxSizer(wxHORIZONTAL);
+
+    //=====================================================
+    // Left side
+    //=====================================================
+    wxBoxSizer* leftSizer;
+    leftSizer = new wxBoxSizer(wxVERTICAL);
+
+    wxStaticBoxSizer* snrSizer;
+    snrSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("SNR")), wxVERTICAL);
+
+    //------------------------------
+    // S/N ratio Guage (vert. bargraph)
+    //------------------------------
+    m_gaugeSNR = new wxGauge(this, wxID_ANY, 25, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
+    m_gaugeSNR->SetToolTip(_("Displays signal to noise ratio in dB."));
+    snrSizer->Add(m_gaugeSNR, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
+
+    //------------------------------
+    // Box for S/N ratio (Numeric)
+    //------------------------------
+    m_textSNR = new wxStaticText(this, wxID_ANY, wxT(" 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    snrSizer->Add(m_textSNR, 0, wxALIGN_CENTER_HORIZONTAL, 1);
+
+    //------------------------------
+    // S/N ratio slow Checkbox
+    //------------------------------
+    m_ckboxSNR = new wxCheckBox(this, wxID_ANY, _("Slow"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    m_ckboxSNR->SetToolTip(_("Smooth but slow SNR estimation"));
+    snrSizer->Add(m_ckboxSNR, 0, wxALIGN_CENTER_HORIZONTAL, 5);
+
+    leftSizer->Add(snrSizer, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxALL, 1);
+
+    //------------------------------
+    // Sync  Indicator box
+    //------------------------------
+    wxStaticBoxSizer* sbSizer3_33;
+    sbSizer3_33 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Sync")), wxVERTICAL);
+
+    m_rbSync = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) );
+    sbSizer3_33->Add(m_rbSync, 0, wxALIGN_CENTER|wxALL, 1);
+    leftSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // BER Frames box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_ber;
+    sbSizer_ber = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Bit Error Rate")), wxVERTICAL);
+
+    m_BtnBerReset = new wxButton(this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_ber->Add(m_BtnBerReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    m_textBits = new wxStaticText(this, wxID_ANY, wxT("Bits: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textBits, 0, wxALIGN_LEFT, 1);
+    m_textErrors = new wxStaticText(this, wxID_ANY, wxT("Errs: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textErrors, 0, wxALIGN_LEFT, 1);
+    m_textBER = new wxStaticText(this, wxID_ANY, wxT("BER: 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textBER, 0, wxALIGN_LEFT, 1);
+
+    m_textResyncs = new wxStaticText(this, wxID_ANY, wxT("Resyncs: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textResyncs, 0, wxALIGN_LEFT, 1);
+
+    leftSizer->Add(sbSizer_ber,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Signal Level(vert. bargraph)
+    //------------------------------
+    wxStaticBoxSizer* levelSizer;
+    levelSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Level")), wxVERTICAL);
+
+    m_textLevel = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(60,-1), wxALIGN_CENTRE);
+    m_textLevel->SetForegroundColour(wxColour(255,0,0));
+    levelSizer->Add(m_textLevel, 0, wxALIGN_LEFT, 1);
+
+    m_gaugeLevel = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
+    m_gaugeLevel->SetToolTip(_("Peak of From Radio in Rx, or peak of From Mic in Tx mode.  If Red you should reduce your levels"));
+    levelSizer->Add(m_gaugeLevel, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
+
+    leftSizer->Add(levelSizer, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 1);
+
+    bSizer1->Add(leftSizer, 0, wxALL|wxEXPAND, 5);
+
+    //=====================================================
+    // Center Section
+    //=====================================================
+    wxBoxSizer* centerSizer;
+    centerSizer = new wxBoxSizer(wxVERTICAL);
+    wxBoxSizer* upperSizer;
+    upperSizer = new wxBoxSizer(wxVERTICAL);
+
+    //=====================================================
+    // Tabbed Notebook control containing display graphs
+    //=====================================================
+    //m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM|wxAUI_NB_DEFAULT_STYLE);
+    //long style = wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_MIDDLE_CLICK_CLOSE;
+    long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
+    m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, nb_style);
+    // This line sets the fontsize for the tabs on the notebook control
+    m_auiNbookCtrl->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
+
+    upperSizer->Add(m_auiNbookCtrl, 1, wxALIGN_TOP|wxEXPAND, 1);
+    centerSizer->Add(upperSizer, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALIGN_TOP|wxEXPAND, 0);
+
+    // lower middle used for user ID
+
+    wxBoxSizer* lowerSizer;
+    lowerSizer = new wxBoxSizer(wxHORIZONTAL);
+
+    m_BtnCallSignReset = new wxButton(this, wxID_ANY, _("Clear"), wxDefaultPosition, wxDefaultSize, 0);
+    lowerSizer->Add(m_BtnCallSignReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    wxBoxSizer* bSizer15;
+    bSizer15 = new wxBoxSizer(wxVERTICAL);
+    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
+    m_txtCtrlCallSign->SetToolTip(_("Call Sign of transmitting station will appear here"));
+    bSizer15->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
+    lowerSizer->Add(bSizer15, 1, wxEXPAND, 5);
+
+#ifdef __EXPERIMENTAL_UDP__
+    wxStaticBoxSizer* sbSizer_Checksum = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Checksums")), wxHORIZONTAL);
+
+    wxStaticText *goodLabel = new wxStaticText(this, wxID_ANY, wxT("Good: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(goodLabel, 0, 0, 2);
+    m_txtChecksumGood = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(m_txtChecksumGood, 0, 0, 2);
+
+    wxStaticText *badLabel = new wxStaticText(this, wxID_ANY, wxT("Bad: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(badLabel, 0, 0, 1);
+    m_txtChecksumBad = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(m_txtChecksumBad, 0, 0, 1);
+
+    lowerSizer->Add(sbSizer_Checksum, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    //=====================================================
+    // These are the buttons that autosend the userid (?)
+    //=====================================================
+
+    // DR 4 Dec - taken off for screen for Beta release to avoid questions on their use until
+    // we implement this feature
+ #ifdef UNIMPLEMENTED
+    wxBoxSizer* bSizer141;
+    bSizer141 = new wxBoxSizer(wxHORIZONTAL);
+
+    // TxID
+    //---------
+    m_togTxID = new wxToggleButton(this, wxID_ANY, _("TxID"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togTxID->SetToolTip(_("Send Tx ID information"));
+    bSizer141->Add(m_togTxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
+
+    // RxID
+    //---------
+    m_togRxID = new wxToggleButton(this, wxID_ANY, _("RxID"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togRxID->SetToolTip(_("Enable reception of ID information"));
+    bSizer141->Add(m_togRxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_LEFT|wxALL|wxFIXED_MINSIZE, 5);
+
+    lowerSizer->Add(bSizer141, 0, wxALIGN_RIGHT, 5);
+#endif
+
+    centerSizer->Add(lowerSizer, 0, wxALIGN_BOTTOM|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 2);
+    bSizer1->Add(centerSizer, 4, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 1);
+
+    //=====================================================
+    // Right side
+    //=====================================================
+    wxBoxSizer* rightSizer;
+    rightSizer = new wxBoxSizer(wxVERTICAL);
+
+    //=====================================================
+    // Squelch Slider Control
+    //=====================================================
+    wxStaticBoxSizer* sbSizer3;
+    sbSizer3 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Squelch")), wxVERTICAL);
+
+    m_sliderSQ = new wxSlider(this, wxID_ANY, 0, 0, 40, wxDefaultPosition, wxSize(-1,80), wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_VERTICAL);
+    m_sliderSQ->SetToolTip(_("Set Squelch level in dB."));
+
+    sbSizer3->Add(m_sliderSQ, 1, wxALIGN_CENTER_HORIZONTAL, 0);
+
+    //------------------------------
+    // Squelch Level static text box
+    //------------------------------
+    m_textSQ = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+
+    sbSizer3->Add(m_textSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
+
+    //------------------------------
+    // Squelch Toggle Checkbox
+    //------------------------------
+    m_ckboxSQ = new wxCheckBox(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+
+    sbSizer3->Add(m_ckboxSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
+    rightSizer->Add(sbSizer3, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 0);
+
+    //rightSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    /* new --- */
+
+    //------------------------------
+    // Mode box
+    //------------------------------
+    wxStaticBoxSizer* sbSizer_mode;
+    sbSizer_mode = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mode")), wxVERTICAL);
+
+#ifdef DISABLED_FEATURE
+    m_rb1400old = new wxRadioButton( this, wxID_ANY, wxT("1400 V0.91"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb1400old, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1400 = new wxRadioButton( this, wxID_ANY, wxT("1400"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1400, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb700 = new wxRadioButton( this, wxID_ANY, wxT("700"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb700b = new wxRadioButton( this, wxID_ANY, wxT("700B"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700b, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+    m_rb700c = new wxRadioButton( this, wxID_ANY, wxT("700C"), wxDefaultPosition, wxDefaultSize,  wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700c, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb800xa = new wxRadioButton( this, wxID_ANY, wxT("800XA"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb800xa, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1600 = new wxRadioButton( this, wxID_ANY, wxT("1600"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1600, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1600->SetValue(true);
+
+    m_rbPlugIn = NULL;
+    if (!wxIsEmpty(plugInName)) {
+        // Optional plug in
+
+        m_rbPlugIn = new wxRadioButton( this, wxID_ANY, plugInName, wxDefaultPosition, wxDefaultSize, 0);
+        sbSizer_mode->Add(m_rbPlugIn, 0, wxALIGN_LEFT|wxALL, 1);
+    }
+
+#ifdef DISABLED_FEATURE
+    m_rb1600Wide = new wxRadioButton( this, wxID_ANY, wxT("1600 Wide"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1600Wide, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb2000 = new wxRadioButton( this, wxID_ANY, wxT("2000"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb2000, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+
+    rightSizer->Add(sbSizer_mode,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    #ifdef MOVED_TO_OPTIONS_DIALOG
+    /* new --- */
+
+    //------------------------------
+    // Test Frames box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_testFrames;
+    sbSizer_testFrames = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Test Frames")), wxVERTICAL);
+
+    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+
+    rightSizer->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    #endif
+
+    //=====================================================
+    // Control Toggles box
+    //=====================================================
+    wxStaticBoxSizer* sbSizer5;
+    sbSizer5 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Control")), wxVERTICAL);
+    wxBoxSizer* bSizer1511;
+    bSizer1511 = new wxBoxSizer(wxVERTICAL);
+
+    //-------------------------------
+    // Stop/Stop signal processing (rx and tx)
+    //-------------------------------
+    m_togBtnOnOff = new wxToggleButton(this, wxID_ANY, _("Start"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnOnOff->SetToolTip(_("Begin/End receiving data."));
+    bSizer1511->Add(m_togBtnOnOff, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer1511, 0, wxEXPAND, 1);
+
+#ifdef UNIMPLEMENTED
+    //------------------------------
+    // Toggle Loopback button for RX
+    //------------------------------
+    wxBoxSizer* bSizer15113;
+    bSizer15113 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* bSizer15111;
+    bSizer15111 = new wxBoxSizer(wxVERTICAL);
+    wxSize wxSz = wxSize(44, 30);
+    m_togBtnLoopRx = new wxToggleButton(this, wxID_ANY, _("Loop\nRX"), wxDefaultPosition, wxSz, 0);
+    m_togBtnLoopRx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
+    m_togBtnLoopRx->SetToolTip(_("Loopback Receive audio data."));
+
+    bSizer15111->Add(m_togBtnLoopRx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    //sbSizer5->Add(bSizer15111, 0, wxEXPAND, 1);
+    bSizer15113->Add(bSizer15111, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    //------------------------------
+    // Toggle Loopback button for Tx
+    //------------------------------
+    wxBoxSizer* bSizer15112;
+    bSizer15112 = new wxBoxSizer(wxVERTICAL);
+    m_togBtnLoopTx = new wxToggleButton(this, wxID_ANY, _("Loop\nTX"), wxDefaultPosition, wxSz, 0);
+    m_togBtnLoopTx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
+    m_togBtnLoopTx->SetToolTip(_("Loopback Transmit audio data."));
+
+    bSizer15112->Add(m_togBtnLoopTx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+    bSizer15113->Add(bSizer15112, 0,  wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    sbSizer5->Add(bSizer15113, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    //------------------------------
+    // Split Frequency Mode Toggle
+    //------------------------------
+    wxBoxSizer* bSizer151;
+    bSizer151 = new wxBoxSizer(wxVERTICAL);
+
+    m_togBtnSplit = new wxToggleButton(this, wxID_ANY, _("Split"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnSplit->SetToolTip(_("Toggle split frequency mode."));
+
+    bSizer151->Add(m_togBtnSplit, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer151, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 1);
+    wxBoxSizer* bSizer13;
+    bSizer13 = new wxBoxSizer(wxVERTICAL);
+
+    //------------------------------
+    // Analog Passthrough Toggle
+    //------------------------------
+    m_togBtnAnalog = new wxToggleButton(this, wxID_ANY, _("Analog"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnAnalog->SetToolTip(_("Toggle analog/digital operation."));
+    bSizer13->Add(m_togBtnAnalog, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer13, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    //------------------------------
+    // Voice Keyer Toggle
+    //------------------------------
+    m_togBtnVoiceKeyer = new wxToggleButton(this, wxID_ANY, _("Voice Keyer"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnVoiceKeyer->SetToolTip(_("Toggle Voice Keyer"));
+    wxBoxSizer* bSizer13a = new wxBoxSizer(wxVERTICAL);    
+    bSizer13a->Add(m_togBtnVoiceKeyer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer13a, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    // not implemented on fdmdv2
+#ifdef ALC
+    //------------------------------
+    // Toggle for ALC
+    //------------------------------
+    wxBoxSizer* bSizer14;
+    bSizer14 = new wxBoxSizer(wxVERTICAL);
+    m_togBtnALC = new wxToggleButton(this, wxID_ANY, _("ALC"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnALC->SetToolTip(_("Toggle automatic level control mode."));
+
+    bSizer14->Add(m_togBtnALC, 0, wxALL, 1);
+    sbSizer5->Add(bSizer14, 0, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALL, 1);
+#endif
+
+    //------------------------------
+    // PTT button: Toggle Transmit/Receive mode
+    //------------------------------
+    wxBoxSizer* bSizer11;
+    bSizer11 = new wxBoxSizer(wxVERTICAL);
+    m_btnTogPTT = new wxToggleButton(this, wxID_ANY, _("PTT"), wxDefaultPosition, wxDefaultSize, 0);
+    m_btnTogPTT->SetToolTip(_("Push to Talk - Switch between Receive and Transmit - you can also use the space bar "));
+    bSizer11->Add(m_btnTogPTT, 1, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer11, 2, wxEXPAND, 1);
+    rightSizer->Add(sbSizer5, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 3);
+    bSizer1->Add(rightSizer, 0, wxALL|wxEXPAND, 3);
+    this->SetSizer(bSizer1);
+    this->Layout();
+    m_statusBar1 = this->CreateStatusBar(3, wxST_SIZEGRIP, wxID_ANY);
+
+    //=====================================================
+    // End of layout
+    //=====================================================
+
+    //-------------------
+    // Connect Events
+    //-------------------
+    this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
+    this->Connect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
+    this->Connect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
+    this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
+
+    this->Connect(m_menuItemExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
+    this->Connect(m_menuItemOnTop->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnTop));
+
+    this->Connect(m_menuItemAudio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
+    this->Connect(m_menuItemAudio->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
+    this->Connect(m_menuItemFilter->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
+    this->Connect(m_menuItemFilter->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
+    this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
+    this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
+    this->Connect(m_menuItemOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
+    this->Connect(m_menuItemOptions->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
+
+    if (!wxIsEmpty(plugInName)) {
+        this->Connect(m_menuItemPlugIn->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsPlugInCfg));
+        this->Connect(m_menuItemPlugIn->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsPlugInCfgUI));
+    }
+
+    this->Connect(m_menuItemPlayFileToMicIn->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
+    this->Connect(m_menuItemRecFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
+    this->Connect(m_menuItemPlayFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
+
+    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
+    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    this->Connect(m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
+    //m_togRxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
+    //m_togTxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
+    m_ckboxSQ->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
+
+    m_ckboxSNR->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSNRClick), NULL, this);
+
+    m_togBtnOnOff->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
+    m_togBtnSplit->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
+    m_togBtnAnalog->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
+    m_togBtnVoiceKeyer->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnVoiceKeyerClick), NULL, this);
+#ifdef ALC
+    m_togBtnALC->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
+#endif
+    m_btnTogPTT->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
+
+    m_BtnCallSignReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnCallSignReset), NULL, this);
+    m_BtnBerReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnBerReset), NULL, this);
+}
+
+TopFrame::~TopFrame()
+{
+    //-------------------
+    // Disconnect Events
+    //-------------------
+    this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
+    this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
+    this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
+    this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
+    this->Disconnect(ID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsPlugInCfg));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    this->Disconnect(ID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
+    //m_togRxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
+    //m_togTxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
+    m_ckboxSQ->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
+
+    m_togBtnOnOff->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
+    m_togBtnSplit->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
+    m_togBtnAnalog->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
+    m_togBtnVoiceKeyer->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnVoiceKeyerClick), NULL, this);
+#ifdef ALC
+    m_togBtnALC->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
+#endif
+    m_btnTogPTT->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
+
+}
+
diff --git a/freedv/tags/1.2.2/freedv-dev/src/topFrame.h b/freedv/tags/1.2.2/freedv-dev/src/topFrame.h
new file mode 100644 (file)
index 0000000..37950a9
--- /dev/null
@@ -0,0 +1,194 @@
+//==========================================================================
+// Name:            topFrame.h
+//
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Lesser General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __TOPFRAME_H__
+#define __TOPFRAME_H__
+
+#include "version.h"
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include <wx/string.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/menu.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/gauge.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/aui/auibook.h>
+#include <wx/tglbtn.h>
+#include <wx/slider.h>
+#include <wx/checkbox.h>
+#include <wx/statusbr.h>
+#include <wx/frame.h>
+#include <wx/statbmp.h>
+#include <wx/stattext.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+#include <wx/radiobut.h>
+#include <wx/combobox.h>
+#include <wx/panel.h>
+#include <wx/listbox.h>
+#include <wx/notebook.h>
+#include <wx/listctrl.h>
+
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_OPEN 1000
+#define ID_SAVE 1001
+#define ID_CLOSE 1002
+#define ID_EXIT 1003
+#define ID_COPY 1004
+#define ID_CUT 1005
+#define ID_PASTE 1006
+#define ID_OPTIONS 1007
+#define ID_ABOUT 1008
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class TopFrame
+///////////////////////////////////////////////////////////////////////////////
+class TopFrame : public wxFrame
+{
+    private:
+
+    protected:
+        wxMenuBar* m_menubarMain;
+        wxMenu* file;
+        wxMenu* edit;
+        wxMenu* tools;
+        wxMenu* help;
+        wxGauge* m_gaugeSNR;
+        wxStaticText* m_textSNR;
+        wxCheckBox* m_ckboxSNR;
+        wxGauge* m_gaugeLevel;
+        wxStaticText* m_textLevel;
+
+        wxButton*     m_BtnCallSignReset;
+        wxTextCtrl*   m_txtCtrlCallSign;
+        wxStaticText* m_txtChecksumGood;
+        wxStaticText* m_txtChecksumBad;
+
+        wxSlider* m_sliderSQ;
+        wxCheckBox* m_ckboxSQ;
+        wxStaticText* m_textSQ;
+        wxStatusBar* m_statusBar1;
+
+        wxButton*     m_BtnBerReset;
+        wxStaticText  *m_textBits;
+        wxStaticText  *m_textErrors;
+        wxStaticText  *m_textBER;
+        wxStaticText  *m_textResyncs;
+
+        wxRadioButton *m_rbSync;
+        wxRadioButton *m_rb1400old;
+        wxRadioButton *m_rb1400;
+        wxRadioButton *m_rb700;
+        wxRadioButton *m_rb700b;
+        wxRadioButton *m_rb700c;
+        wxRadioButton *m_rb800xa;
+        wxRadioButton *m_rb1600;
+        wxRadioButton *m_rb2000;
+        wxRadioButton *m_rb1600Wide;
+        wxRadioButton *m_rbPlugIn;
+
+        // Virtual event handlers, overide them in your derived class
+        virtual void topFrame_OnClose( wxCloseEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnPaint( wxPaintEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnSize( wxSizeEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTop( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsAudio( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsAudioUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsFilter( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsFilterUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsOptions( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnToolsPlugInCfg( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsPlugInCfgUI( wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnToolsUDP( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsOptionsUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsComCfg( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsComCfgUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnPlayFileToMicIn( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnRecFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnPlayFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnHelpCheckUpdates( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnHelpAbout( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnRxID( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnTxID( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnCmdSliderScroll( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnSliderScrollBottom( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnCmdSliderScrollChanged( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnSliderScrollTop( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnCheckSQClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnCheckSNRClick( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnTogBtnLoopRx( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnLoopTx( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnOnOff( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnSplitClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnAnalogClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnVoiceKeyerClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnALCClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnPTT( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnTogBtnSplitClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnAnalogClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnALCClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnRxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnTxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnPTT_UI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnOnOffUI(wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnCallSignReset( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnBerReset( wxCommandEvent& event ) { event.Skip(); }
+
+    public:
+        wxToggleButton* m_togRxID;
+        wxToggleButton* m_togTxID;
+        wxToggleButton* m_togBtnOnOff;
+        wxToggleButton* m_togBtnSplit;
+        wxToggleButton* m_togBtnAnalog;
+        wxToggleButton* m_togBtnVoiceKeyer;
+        wxToggleButton* m_togBtnALC;
+        wxToggleButton* m_btnTogPTT;
+        wxToggleButton* m_togBtnLoopRx;
+        wxToggleButton* m_togBtnLoopTx;
+        wxAuiNotebook* m_auiNbookCtrl;
+
+        TopFrame( wxString plugInName, wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FreeDV ") + _(FREEDV_VERSION), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(561,300 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
+
+        ~TopFrame();
+};
+
+#endif //__TOPFRAME_H__
diff --git a/freedv/tags/1.2.2/script/spot.sh b/freedv/tags/1.2.2/script/spot.sh
new file mode 100644 (file)
index 0000000..cb1309a
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/bash
+#
+# spot.sh
+# David Rowe Sep 2015
+#
+
+# Demo script for "spotting" based on FreeDV txt string. Posts a
+# date-stamped text file to a web server.  Called from FreeDV GUI
+# program when a callsign is received in the txt msg.
+
+
+# Q: how to remove repeated spots, or those close in time?
+#
+# Set up automated lftp login:
+#
+#   $ lftp ftp://username@server
+#   Password:
+#   lftp username@server:~>  set bmk:save-passwords true
+#   lftp username@server:~> bookmark add yourserver
+#   lftp username@server:~> bookmark list
+#   lftp username@server:~> quit
+
+SPOTFILE=/home/david/tmp/freedvspot.html
+FTPSERVER=ftp.rowetel.com
+
+echo `date -u` "  " $1 "<br>" >> $SPOTFILE
+tail -n 25 $SPOTFILE > /tmp/spot.tmp1
+mv /tmp/spot.tmp1 $SPOTFILE
+lftp -e "cd www;put $SPOTFILE;quit" $FTPSERVER
diff --git a/freedv/tags/1.2.2/src/CMakeLists.txt b/freedv/tags/1.2.2/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..ef0798b
--- /dev/null
@@ -0,0 +1,79 @@
+set(FREEDV_SOURCES
+    dlg_audiooptions.cpp
+    dlg_filter.cpp
+    dlg_options.cpp
+    dlg_ptt.cpp
+    dlg_plugin.cpp
+    fdmdv2_main.cpp
+    fdmdv2_pa_wrapper.cpp
+    fdmdv2_plot.cpp
+    fdmdv2_plot_scalar.cpp
+    fdmdv2_plot_scatter.cpp
+    fdmdv2_plot_spectrum.cpp
+    fdmdv2_plot_waterfall.cpp
+    hamlib.cpp
+    serialport.cpp
+    topFrame.cpp
+    sox_biquad.c
+    comp.h
+    dlg_audiooptions.h
+    dlg_filter.h
+    dlg_options.h
+    dlg_ptt.h
+    fdmdv2_defines.h
+    fdmdv2_main.h
+    fdmdv2_pa_wrapper.h
+    fdmdv2_plot.h
+    fdmdv2_plot_scalar.h
+    fdmdv2_plot_scatter.h
+    fdmdv2_plot_spectrum.h
+    fdmdv2_plot_waterfall.h
+    hamlib.h
+    sox_biquad.h
+    sox/band.h
+    sox/biquad.c
+    sox/biquads.c
+    sox/biquad.h
+    sox/effects.c
+    sox/effects.h
+    sox/effects_i.c
+    sox/formats_i.c
+    sox/libsox.c
+    sox/sox.h
+    sox/sox_i.h
+    sox/soxomp.h
+    sox/util.h
+    sox/xmalloc.h
+    sox/xmalloc.c
+    topFrame.h
+    version.h
+)
+
+# WIN32 is needed for Windows GUI apps and is ignored for UNIX like systems.
+add_executable(freedv WIN32 ${FREEDV_SOURCES} ${RES_FILES})
+target_link_libraries(freedv ${FREEDV_LINK_LIBS})
+include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+if(FREEDV_STATIC_DEPS)
+    add_dependencies(freedv ${FREEDV_STATIC_DEPS})
+endif(FREEDV_STATIC_DEPS)
+install(TARGETS freedv
+    RUNTIME DESTINATION bin)
+
+# Custom commands to build OSX images.
+if(APPLE)
+    add_custom_command(
+        TARGET freedv
+        POST_BUILD
+        COMMAND mkdir ARGS -p FreeDV.app/Contents/MacOS
+        COMMAND mkdir ARGS -p FreeDV.app/Contents/Resources/English.lproj
+        COMMAND cp ARGS ${CMAKE_CURRENT_SOURCE_DIR}/info.plist FreeDV.app/Contents
+        COMMAND cp ARGS ${CMAKE_CURRENT_SOURCE_DIR}/freedv.icns FreeDV.app/Contents/Resources
+        COMMAND echo ARGS -n "APPL????" > FreeDV.app/Contents/PkgInfo
+        COMMAND cp ARGS freedv FreeDV.app/Contents/MacOS/FreeDV
+        COMMAND dylibbundler ARGS -od -b -x FreeDV.app/Contents/MacOS/FreeDV -d FreeDV.app/Contents/libs -p @executable_path/../libs/
+        COMMAND mkdir dist_tmp
+        COMMAND cp -r FreeDV.app dist_tmp
+        COMMAND hdiutil create -srcfolder dist_tmp/ -volname FreeDV -format UDZO ./FreeDV.dmg
+        COMMAND rm -rf dist_tmp
+    )
+endif(APPLE)
diff --git a/freedv/tags/1.2.2/src/Makefile.win32 b/freedv/tags/1.2.2/src/Makefile.win32
new file mode 100644 (file)
index 0000000..932e851
--- /dev/null
@@ -0,0 +1,52 @@
+# src/Makefile.win32
+# David Rowe 26 Oct 2012
+#
+# Makefile for Win32 on msys/Mingw to help David R get up to speed
+#
+# $ make -f Makefile.Win32
+
+CODEC2_PATH=$(HOME)/codec2-dev
+INCLUDE_PATH=/usr/local/include
+
+WX_CONFIG=wx-config
+WX_CPPFLAGS = $(shell $(WX_CONFIG) --cxxflags) -D__WXDEBUG__
+WX_LIBS = $(shell $(WX_CONFIG) --libs core, base, aui, adv, net)
+SVN_REVISION=$(shell svnversion)
+CODEC2_INC=$(CODEC2_PATH)/src 
+CODEC2_LIB=$(CODEC2_PATH)/build_win32/src/
+
+CPP_FLAGS = -D_NO_AUTOTOOLS_ -I$(INCLUDE_PATH) $(WX_CPPFLAGS) -I$(CODEC2_INC) -I../extern/include -I. -g -Wall -DSVN_REVISION=\"$(SVN_REVISION)\"
+LIBS = $(WX_LIBS) -L$(CODEC2_LIB) -lcodec2 -lm -lportaudiocpp -lportaudio -lpthread -lsndfile -lsamplerate -lhamlib -lsox -lspeexdsp
+
+OBJS = topFrame.o \
+fdmdv2_main.o \
+fdmdv2_plot.o \
+fdmdv2_plot_scalar.o \
+fdmdv2_plot_scatter.o \
+fdmdv2_plot_spectrum.o \
+fdmdv2_plot_waterfall.o \
+fdmdv2_pa_wrapper.o \
+dlg_audiooptions.o \
+dlg_ptt.o \
+dlg_options.o \
+dlg_filter.o \
+sox_biquad.o \
+hamlib.o \
+../../codec2-dev/src/golay23.o
+
+HDRS = version.h dlg_audiooptions.h dlg_ptt.h dlg_filter.h fdmdv2_main.h fdmdv2_defines.h fdmdv2_plot.h fdmdv2_plot_scalar.h fdmdv2_plot_waterfall.h fdmdv2_plot_scatter.h fdmdv2_plot_spectrum.h fdmdv2_pa_wrapper.h topFrame.h dlg_audiooptions.h topFrame.h varicode.h ../../codec2-dev/src/golay23.h hamlib.h
+
+all: freedv
+
+freedv: $(OBJS) 
+       g++ -o freedv $(OBJS) $(CPP_FLAGS) $(LIBS)
+
+%.o: %.cpp $(HDRS) Makefile.win32
+       g++ $(CPP_FLAGS) -c $< -o $@
+
+%.o: %.c $(HDRS) Makefile.win32
+       gcc $(CPP_FLAGS) -c $< -o $@
+
+clean:
+       rm -f *.o fdmdv2
+
diff --git a/freedv/tags/1.2.2/src/afreedvplugin.c b/freedv/tags/1.2.2/src/afreedvplugin.c
new file mode 100644 (file)
index 0000000..5fdc424
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+  afreedvplugin.c
+  David Rowe Feb 2016
+
+  Sample FreeDV plugin
+
+  TODO:
+     [ ] plugin to call back to functions
+     [ ] ability to list .so's/DLLs and scan
+     [ ] where do we put plugins?
+     [ ] Windows build and test environment
+
+  linux .so:
+    $ gcc -Wall -fPIC -c afreedvplugin.c
+    $ gcc -shared -Wl,-soname,afreedvplugin.so -o afreedvplugin.so afreedvplugin.o
+  win32 .dll:
+    $ i686-w64-mingw32-gcc -c afreedvplugin.c
+    $ i686-w64-mingw32-gcc -shared -o afreedvplugin.dll afreedvplugin.o -Wl,--out-implib,afreedvplugin_dll.a
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32_
+#define DLL __declspec(dllexport)
+#else
+#define DLL
+#endif
+
+
+#ifdef LATER
+/* functions plugin can call - not sure how to link to these */
+
+int plugin_alert(char string[]);
+int plugin_get_persistant(char name[], char value[]);
+int plugin_set_persistant(char name[], char value[]);
+#endif
+static int (*plugin_get_persistant)(char name[], char value[]);
+
+struct APLUGIN_STATES {
+    int symbol_rate;
+    int num_tones;
+    int counter;
+};
+
+/* plugin functions called by host, we need to write these */
+
+void DLL plugin_name(char name[]) {
+
+    sprintf(name, "aFreeDVplugIn");
+}
+
+/* 
+   Text fields will be created for nparams, using the names
+   in *param_names[].  These fields we be saved to persistent
+   storage as name/param_names[0], name/param_names[1] ....
+*/
+
+void DLL *plugin_open(char *param_names[], 
+                      int *nparams, 
+                      int (*aplugin_get_persistant)(char *, char *))
+{
+    struct APLUGIN_STATES *states;
+
+    /* set up function ptrs */
+
+    plugin_get_persistant = aplugin_get_persistant;
+    /* tell host how many persistent parameters we have and their names */
+
+    strcpy(param_names[0], "SymbolRate");
+    strcpy(param_names[1], "NumTones");
+    *nparams = 2;
+
+    /* init local states */
+
+    states = (struct APLUGIN_STATES *)malloc(sizeof(struct APLUGIN_STATES));
+    if (states == NULL) {
+        // TODO: plugin_alert("Problem starting plugin!");
+        return NULL;
+    }
+    states->counter = 0;
+    
+    return (void*)states;
+}
+
+void DLL plugin_close(void *states) {
+    free(states);
+}
+
+void DLL plugin_start(void *s) {
+    struct APLUGIN_STATES *states = (struct APLUGIN_STATES*)s;
+    char txt[80];
+
+    fprintf(stderr, "\nplugin_start\n");
+
+    (plugin_get_persistant)("SymbolRate",txt);
+    states->symbol_rate = atoi(txt);
+
+    (plugin_get_persistant)("NumTones",txt);
+    states->num_tones = atoi(txt);
+    
+    fprintf(stderr, "symbol_rate: %d num_tones: %d\n", states->symbol_rate, states->num_tones);
+}
+
+void DLL plugin_stop(void *states) {
+    fprintf(stderr, "\nplugin_stop\n");
+}
+
+void DLL plugin_rx_samples(void *s, short samples[], int n) {
+    struct APLUGIN_STATES *states = (struct APLUGIN_STATES*)s;
+    //fprintf(stderr, "Got n=%d samples!\n", n);
+    //fprintf(stderr, "samples[0] = %d  samples[%d-1] = %d  counter = %d\n", samples[0], n, samples[n-1], states->counter++);
+}
+
diff --git a/freedv/tags/1.2.2/src/comp.h b/freedv/tags/1.2.2/src/comp.h
new file mode 100644 (file)
index 0000000..a3a1bd9
--- /dev/null
@@ -0,0 +1,39 @@
+/*---------------------------------------------------------------------------*\
+
+  FILE........: comp.h
+  AUTHOR......: David Rowe
+  DATE CREATED: 24/08/09
+
+  Complex number definition.
+
+\*---------------------------------------------------------------------------*/
+
+/*
+  Copyright (C) 2009 David Rowe
+
+  All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License version 2.1, as
+  published by the Free Software Foundation.  This program is
+  distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+  License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __COMP__
+#define __COMP__
+
+/* Complex number */
+
+typedef struct
+{
+    float real;
+    float imag;
+} COMP;
+
+#endif
diff --git a/freedv/tags/1.2.2/src/dlg_audiooptions.cpp b/freedv/tags/1.2.2/src/dlg_audiooptions.cpp
new file mode 100644 (file)
index 0000000..4e8cd98
--- /dev/null
@@ -0,0 +1,1264 @@
+//=========================================================================
+// Name:            AudioOptsDialog.cpp
+// Purpose:         Implements an Audio options selection dialog.
+//
+// Authors:         David Rowe, David Witten
+// License:
+//
+//  All rights reserved.
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//=========================================================================
+#include "fdmdv2_main.h"
+#include "dlg_audiooptions.h"
+
+// constants for test waveform plots
+
+#define TEST_WAVEFORM_X          180
+#define TEST_WAVEFORM_Y          180
+#define TEST_WAVEFORM_PLOT_TIME  2.0
+#define TEST_WAVEFORM_PLOT_FS    400
+#define TEST_BUF_SIZE           1024
+#define TEST_FS                 48000.0
+#define TEST_DT                 0.1      // time between plot updates in seconds
+#define TEST_WAVEFORM_PLOT_BUF  ((int)(DT*400))
+
+void AudioOptsDialog::Pa_Init(void)
+{
+    m_isPaInitialized = false;
+
+    if((pa_err = Pa_Initialize()) == paNoError)
+    {
+        m_isPaInitialized = true;
+    }
+    else
+    {
+        wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
+        return;
+    }
+}
+
+
+void AudioOptsDialog::buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, 
+                                        wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel)
+{
+    wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
+
+    wxPanel *panel = new wxPanel(parentPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
+    *plotScalar = new PlotScalar((wxFrame*) panel, 1, TEST_WAVEFORM_PLOT_TIME, 1.0/TEST_WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "", 1);
+    (*plotScalar)->SetClientSize(wxSize(TEST_WAVEFORM_X,TEST_WAVEFORM_Y));
+    bSizer1->Add(panel, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 8);
+
+    *btnTest = new wxButton(parentPanel, wxID_ANY, buttonLabel, wxDefaultPosition, wxDefaultSize);
+    bSizer1->Add(*btnTest, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 0);
+
+    bSizer->Add(bSizer1, 0, wxALIGN_CENTER_HORIZONTAL |wxALIGN_CENTER_VERTICAL );
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// AudioOptsDialog()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+AudioOptsDialog::AudioOptsDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    //this->SetSizeHints(wxSize(850, 600), wxDefaultSize);
+    fprintf(stderr, "pos %d %d\n", pos.x, pos.y);
+    Pa_Init();
+
+    wxBoxSizer* mainSizer;
+    mainSizer = new wxBoxSizer(wxVERTICAL);
+    m_panel1 = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer4;
+    bSizer4 = new wxBoxSizer(wxVERTICAL);
+    m_notebook1 = new wxNotebook(m_panel1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM);
+    m_panelRx = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer20;
+    bSizer20 = new wxBoxSizer(wxVERTICAL);
+    wxGridSizer* gSizer4;
+    gSizer4 = new wxGridSizer(2, 1, 0, 0);
+
+    // Rx In -----------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer2;
+    sbSizer2 = new wxStaticBoxSizer(new wxStaticBox(m_panelRx, wxID_ANY, _("From Radio")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer811a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlRxInDevices = new wxListCtrl(m_panelRx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer811a->Add(m_listCtrlRxInDevices, 1, wxALL|wxEXPAND, 1);
+
+    wxBoxSizer* bSizer811;
+    bSizer811 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText51 = new wxStaticText(m_panelRx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText51->Wrap(-1);
+    bSizer811->Add(m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_textCtrlRxIn = new wxTextCtrl(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer811->Add(m_textCtrlRxIn, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText6 = new wxStaticText(m_panelRx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText6->Wrap(-1);
+    bSizer811->Add(m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateRxIn = new wxComboBox(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer811->Add(m_cbSampleRateRxIn, 0, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    bSizer811a->Add(bSizer811, 0, wxEXPAND, 5);
+
+    sbSizer2->Add(bSizer811a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarRxIn, &m_btnRxInTest, m_panelRx, sbSizer2, _("Rec 2s"));
+
+    gSizer4->Add(sbSizer2, 1, wxEXPAND, 5);
+
+    // Rx Out -----------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer3;
+    sbSizer3 = new wxStaticBoxSizer(new wxStaticBox(m_panelRx, wxID_ANY, _("To Speaker/Headphones")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer81a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlRxOutDevices = new wxListCtrl(m_panelRx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer81a->Add(m_listCtrlRxOutDevices, 1, wxALL|wxEXPAND, 1);
+
+    wxBoxSizer* bSizer81;
+    bSizer81 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText9 = new wxStaticText(m_panelRx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText9->Wrap(-1);
+    bSizer81->Add(m_staticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_textCtrlRxOut = new wxTextCtrl(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer81->Add(m_textCtrlRxOut, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText10 = new wxStaticText(m_panelRx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText10->Wrap(-1);
+    bSizer81->Add(m_staticText10, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateRxOut = new wxComboBox(m_panelRx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer81->Add(m_cbSampleRateRxOut, 0, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    bSizer81a->Add(bSizer81, 0, wxEXPAND, 5);
+
+    sbSizer3->Add(bSizer81a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarRxOut, &m_btnRxOutTest, m_panelRx, sbSizer3, _("Play 2s"));
+    gSizer4->Add(sbSizer3, 1, wxEXPAND, 2);
+    bSizer20->Add(gSizer4, 1, wxEXPAND, 1);
+    m_panelRx->SetSizer(bSizer20);
+    m_panelRx->Layout();
+    bSizer20->Fit(m_panelRx);
+    m_notebook1->AddPage(m_panelRx, _("Receive"), true);
+
+    // Tx Tab -------------------------------------------------------------------------------
+
+    m_panelTx = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer18;
+    bSizer18 = new wxBoxSizer(wxVERTICAL);
+    wxGridSizer* gSizer2;
+    gSizer2 = new wxGridSizer(2, 1, 0, 0);
+
+    // Tx In ----------------------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer22;
+    sbSizer22 = new wxStaticBoxSizer(new wxStaticBox(m_panelTx, wxID_ANY, _("From Microphone")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer83a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlTxInDevices = new wxListCtrl(m_panelTx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer83a->Add(m_listCtrlTxInDevices, 1, wxALL|wxEXPAND, 1);
+    wxBoxSizer* bSizer83;
+    bSizer83 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText12 = new wxStaticText(m_panelTx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText12->Wrap(-1);
+    bSizer83->Add(m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_textCtrlTxIn = new wxTextCtrl(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer83->Add(m_textCtrlTxIn, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText11 = new wxStaticText(m_panelTx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText11->Wrap(-1);
+    bSizer83->Add(m_staticText11, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateTxIn = new wxComboBox(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer83->Add(m_cbSampleRateTxIn, 0, wxALL, 1);
+
+    bSizer83a->Add(bSizer83, 0, wxEXPAND, 5);
+
+    sbSizer22->Add(bSizer83a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarTxIn, &m_btnTxInTest, m_panelTx, sbSizer22, _("Rec 2s"));
+
+    gSizer2->Add(sbSizer22, 1, wxEXPAND, 5);
+
+    // Tx Out ----------------------------------------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer21;
+    sbSizer21 = new wxStaticBoxSizer(new wxStaticBox(m_panelTx, wxID_ANY, _("To Radio")), wxHORIZONTAL);
+
+    wxBoxSizer* bSizer82a = new wxBoxSizer(wxVERTICAL);
+
+    m_listCtrlTxOutDevices = new wxListCtrl(m_panelTx, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_VRULES);
+    bSizer82a->Add(m_listCtrlTxOutDevices, 1, wxALL|wxEXPAND, 2);
+    wxBoxSizer* bSizer82;
+    bSizer82 = new wxBoxSizer(wxHORIZONTAL);
+    m_staticText81 = new wxStaticText(m_panelTx, wxID_ANY, _("Device:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText81->Wrap(-1);
+    bSizer82->Add(m_staticText81, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_textCtrlTxOut = new wxTextCtrl(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    bSizer82->Add(m_textCtrlTxOut, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    m_staticText71 = new wxStaticText(m_panelTx, wxID_ANY, _("Sample Rate:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText71->Wrap(-1);
+    bSizer82->Add(m_staticText71, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5);
+    m_cbSampleRateTxOut = new wxComboBox(m_panelTx, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(90,-1), 0, NULL, wxCB_DROPDOWN);
+    bSizer82->Add(m_cbSampleRateTxOut, 0, wxALL, 1);
+
+    bSizer82a->Add(bSizer82, 0, wxEXPAND, 5);
+
+    sbSizer21->Add(bSizer82a, 1, wxEXPAND, 2);
+    buildTestControls(&m_plotScalarTxOut, &m_btnTxOutTest, m_panelTx, sbSizer21, _("Play 2s"));
+
+    gSizer2->Add(sbSizer21, 1, wxEXPAND, 5);
+    bSizer18->Add(gSizer2, 1, wxEXPAND, 1);
+    m_panelTx->SetSizer(bSizer18);
+    m_panelTx->Layout();
+    bSizer18->Fit(m_panelTx);
+    m_notebook1->AddPage(m_panelTx, _("Transmit"), false);
+
+    // API Tab -------------------------------------------------------------------
+
+    m_panelAPI = new wxPanel(m_notebook1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
+    wxBoxSizer* bSizer12;
+    bSizer12 = new wxBoxSizer(wxHORIZONTAL);
+    wxGridSizer* gSizer31;
+    gSizer31 = new wxGridSizer(2, 1, 0, 0);
+    wxStaticBoxSizer* sbSizer1;
+    sbSizer1 = new wxStaticBoxSizer(new wxStaticBox(m_panelAPI, wxID_ANY, _("PortAudio")), wxVERTICAL);
+
+    wxGridSizer* gSizer3;
+    gSizer3 = new wxGridSizer(4, 2, 0, 0);
+
+    m_staticText7 = new wxStaticText(m_panelAPI, wxID_ANY, _("PortAudio Version String:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText7->Wrap(-1);
+    gSizer3->Add(m_staticText7, 1, wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+    m_textStringVer = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    gSizer3->Add(m_textStringVer, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText8 = new wxStaticText(m_panelAPI, wxID_ANY, _("PortAudio Int Version:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText8->Wrap(-1);
+    gSizer3->Add(m_staticText8, 1, wxALIGN_RIGHT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+    m_textIntVer = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    gSizer3->Add(m_textIntVer, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText5 = new wxStaticText(m_panelAPI, wxID_ANY, _("Device Count:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText5->Wrap(-1);
+    gSizer3->Add(m_staticText5, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 10);
+    m_textCDevCount = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    gSizer3->Add(m_textCDevCount, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    m_staticText4 = new wxStaticText(m_panelAPI, wxID_ANY, _("API Count:"), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText4->Wrap(-1);
+    gSizer3->Add(m_staticText4, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 10);
+    m_textAPICount = new wxStaticText(m_panelAPI, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(45,-1), 0);
+    m_textAPICount->SetMaxSize(wxSize(45,-1));
+    gSizer3->Add(m_textAPICount, 1, wxALIGN_LEFT|wxALL|wxALIGN_CENTER_VERTICAL, 10);
+
+    sbSizer1->Add(gSizer3, 1, wxEXPAND, 2);
+    gSizer31->Add(sbSizer1, 1, wxEXPAND, 2);
+    wxStaticBoxSizer* sbSizer6;
+    sbSizer6 = new wxStaticBoxSizer(new wxStaticBox(m_panelAPI, wxID_ANY, _("Other")), wxVERTICAL);
+    gSizer31->Add(sbSizer6, 1, wxEXPAND, 5);
+    bSizer12->Add(gSizer31, 1, wxEXPAND, 5);
+    m_panelAPI->SetSizer(bSizer12);
+    m_panelAPI->Layout();
+    bSizer12->Fit(m_panelAPI);
+    m_notebook1->AddPage(m_panelAPI, _("API Info"), false);
+    bSizer4->Add(m_notebook1, 1, wxEXPAND | wxALL, 0);
+    m_panel1->SetSizer(bSizer4);
+    m_panel1->Layout();
+    bSizer4->Fit(m_panel1);
+    mainSizer->Add(m_panel1, 1, wxEXPAND | wxALL, 1);
+
+    wxBoxSizer* bSizer6;
+    bSizer6 = new wxBoxSizer(wxHORIZONTAL);
+    m_btnRefresh = new wxButton(this, wxID_ANY, _("Refresh"), wxDefaultPosition, wxDefaultSize, 0);
+    bSizer6->Add(m_btnRefresh, 0, wxALIGN_CENTER|wxALL, 2);
+
+    m_sdbSizer1 = new wxStdDialogButtonSizer();
+
+    m_sdbSizer1OK = new wxButton(this, wxID_OK);
+    m_sdbSizer1->AddButton(m_sdbSizer1OK);
+
+    m_sdbSizer1Cancel = new wxButton(this, wxID_CANCEL);
+    m_sdbSizer1->AddButton(m_sdbSizer1Cancel);
+
+    m_sdbSizer1Apply = new wxButton(this, wxID_APPLY);
+    m_sdbSizer1->AddButton(m_sdbSizer1Apply);
+
+    m_sdbSizer1->Realize();
+
+    bSizer6->Add(m_sdbSizer1, 1, wxALIGN_CENTER_VERTICAL, 2);
+    mainSizer->Add(bSizer6, 0, wxEXPAND, 2);
+    this->SetSizer(mainSizer);
+    this->Layout();
+    this->Centre(wxBOTH);
+//    this->Centre(wxBOTH);
+
+    m_notebook1->SetSelection(0);
+
+    showAPIInfo();
+    m_RxInDevices.m_listDevices   = m_listCtrlRxInDevices;
+    m_RxInDevices.direction       = AUDIO_IN;
+    m_RxInDevices.m_textDevice    = m_textCtrlRxIn;
+    m_RxInDevices.m_cbSampleRate  = m_cbSampleRateRxIn;
+
+    m_RxOutDevices.m_listDevices  = m_listCtrlRxOutDevices;
+    m_RxOutDevices.direction      = AUDIO_OUT;
+    m_RxOutDevices.m_textDevice   = m_textCtrlRxOut;
+    m_RxOutDevices.m_cbSampleRate = m_cbSampleRateRxOut;
+
+    m_TxInDevices.m_listDevices   = m_listCtrlTxInDevices;
+    m_TxInDevices.direction       = AUDIO_IN;
+    m_TxInDevices.m_textDevice    = m_textCtrlTxIn;
+    m_TxInDevices.m_cbSampleRate  = m_cbSampleRateTxIn;
+
+    m_TxOutDevices.m_listDevices  = m_listCtrlTxOutDevices;
+    m_TxOutDevices.direction      = AUDIO_OUT;
+    m_TxOutDevices.m_textDevice   = m_textCtrlTxOut;
+    m_TxOutDevices.m_cbSampleRate = m_cbSampleRateTxOut;
+
+    populateParams(m_RxInDevices);
+    populateParams(m_RxOutDevices);
+    populateParams(m_TxInDevices);
+    populateParams(m_TxOutDevices);
+
+    m_listCtrlRxInDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnRxInDeviceSelect ), NULL, this );
+    m_listCtrlRxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnRxOutDeviceSelect ), NULL, this );
+    m_listCtrlTxInDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxInDeviceSelect ), NULL, this );
+    m_listCtrlTxOutDevices->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler( AudioOptsDialog::OnTxOutDeviceSelect ), NULL, this );
+
+    // wire up test buttons
+    m_btnRxInTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+    m_btnRxOutTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxOutTest ), NULL, this );
+    m_btnTxInTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxInTest ), NULL, this );
+    m_btnTxOutTest->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxOutTest ), NULL, this );
+
+    m_btnRefresh->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRefreshClick ), NULL, this );
+    m_sdbSizer1Apply->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnApplyAudioParameters ), NULL, this );
+    m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnCancelAudioParameters ), NULL, this );
+    m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnOkAudioParameters ), NULL, this );
+/*
+        void OnClose( wxCloseEvent& event ) { event.Skip(); }
+        void OnHibernate( wxActivateEvent& event ) { event.Skip(); }
+        void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
+        void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
+*/
+//    this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(AudioOptsDialog::OnClose));
+    this->Connect(wxEVT_HIBERNATE, wxActivateEventHandler(AudioOptsDialog::OnHibernate));
+    this->Connect(wxEVT_ICONIZE, wxIconizeEventHandler(AudioOptsDialog::OnIconize));
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(AudioOptsDialog::OnInitDialog));
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// ~AudioOptsDialog()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+AudioOptsDialog::~AudioOptsDialog()
+{
+    Pa_Terminate();
+
+    // Disconnect Events
+    this->Disconnect(wxEVT_HIBERNATE, wxActivateEventHandler(AudioOptsDialog::OnHibernate));
+    this->Disconnect(wxEVT_ICONIZE, wxIconizeEventHandler(AudioOptsDialog::OnIconize));
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(AudioOptsDialog::OnInitDialog));
+
+    m_listCtrlRxInDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnRxInDeviceSelect), NULL, this);
+    m_listCtrlRxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnRxOutDeviceSelect), NULL, this);
+    m_listCtrlTxInDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxInDeviceSelect), NULL, this);
+    m_listCtrlTxOutDevices->Disconnect(wxEVT_COMMAND_LIST_ITEM_SELECTED, wxListEventHandler(AudioOptsDialog::OnTxOutDeviceSelect), NULL, this);
+
+    m_btnRxInTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxInTest ), NULL, this );
+    m_btnRxOutTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnRxOutTest ), NULL, this );
+    m_btnTxInTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxInTest ), NULL, this );
+    m_btnTxOutTest->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( AudioOptsDialog::OnTxOutTest ), NULL, this );
+
+    m_btnRefresh->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnRefreshClick), NULL, this);
+    m_sdbSizer1Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnApplyAudioParameters), NULL, this);
+    m_sdbSizer1Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnCancelAudioParameters), NULL, this);
+    m_sdbSizer1OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(AudioOptsDialog::OnOkAudioParameters), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnInitDialog( wxInitDialogEvent& event )
+{
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//
+// helper function to look up name of devNum, and if it exists write
+// name to textCtrl.  Used to trap dissapearing devices.
+//-------------------------------------------------------------------------
+int AudioOptsDialog::setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum)
+{
+    int i, aDevNum, found_devNum;
+
+    // ignore last list entry as it is the "none" entry
+
+    found_devNum = 0;
+    for(i=0; i<listCtrl->GetItemCount()-1; i++) {
+        aDevNum = wxAtoi(listCtrl->GetItemText(i, 1));
+        //printf("aDevNum: %d devNum: %d\n", aDevNum, devNum);
+        if (aDevNum == devNum) {
+            found_devNum = 1;
+            textCtrl->SetValue(listCtrl->GetItemText(i, 0) + " (" + wxString::Format(wxT("%i"),devNum) + ")");
+            printf("setting focus of %d\n", i);
+            listCtrl->SetItemState(i, wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED);
+        }
+    }
+
+    if (found_devNum) 
+        return devNum;
+    else {
+        textCtrl->SetValue("none");
+        return -1;
+    }
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+int AudioOptsDialog::ExchangeData(int inout)
+{
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        // Map sound card device numbers to tx/rx device numbers depending
+        // on number of sound cards in use
+
+        printf("EXCHANGE_DATA_IN:\n");
+        printf("  g_nSoundCards: %d\n", g_nSoundCards);
+        printf("  g_soundCard1InDeviceNum: %d\n", g_soundCard1InDeviceNum);
+        printf("  g_soundCard1OutDeviceNum: %d\n", g_soundCard1OutDeviceNum);
+        printf("  g_soundCard1SampleRate: %d\n", g_soundCard1SampleRate);
+        printf("  g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+        printf("  g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+        printf("  g_soundCard2SampleRate: %d\n", g_soundCard2SampleRate);
+
+        if (g_nSoundCards == 0) {
+            m_textCtrlRxIn ->SetValue("none"); rxInAudioDeviceNum  = -1;
+            m_textCtrlRxOut->SetValue("none"); rxOutAudioDeviceNum = -1;
+            m_textCtrlTxIn ->SetValue("none"); txInAudioDeviceNum  = -1;
+            m_textCtrlTxOut->SetValue("none"); txOutAudioDeviceNum = -1;           
+        }
+
+        if (g_nSoundCards == 1) {
+            rxInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlRxIn, 
+                                                           m_listCtrlRxInDevices, 
+                                                           g_soundCard1InDeviceNum);
+
+            rxOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlRxOut, 
+                                                           m_listCtrlRxOutDevices, 
+                                                           g_soundCard1OutDeviceNum);
+
+            if ((rxInAudioDeviceNum != -1) && (rxInAudioDeviceNum != -1)) {
+                m_cbSampleRateRxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+                m_cbSampleRateRxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+            }
+
+            m_textCtrlTxIn ->SetValue("none"); txInAudioDeviceNum  = -1;
+            m_textCtrlTxOut->SetValue("none"); txOutAudioDeviceNum = -1;           
+        }
+
+        if (g_nSoundCards == 2) {
+            rxInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlRxIn, 
+                                                           m_listCtrlRxInDevices, 
+                                                           g_soundCard1InDeviceNum);
+
+            rxOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlRxOut, 
+                                                           m_listCtrlRxOutDevices, 
+                                                           g_soundCard2OutDeviceNum);
+
+            txInAudioDeviceNum  = setTextCtrlIfDevNumValid(m_textCtrlTxIn, 
+                                                           m_listCtrlTxInDevices, 
+                                                           g_soundCard2InDeviceNum);
+
+            txOutAudioDeviceNum = setTextCtrlIfDevNumValid(m_textCtrlTxOut, 
+                                                           m_listCtrlTxOutDevices, 
+                                                           g_soundCard1OutDeviceNum);
+
+            if ((rxInAudioDeviceNum != -1) && (txOutAudioDeviceNum != -1)) {
+                m_cbSampleRateRxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+                m_cbSampleRateTxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard1SampleRate));
+            }
+
+            if ((txInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1)) {
+                m_cbSampleRateTxIn->SetValue(wxString::Format(wxT("%i"),g_soundCard2SampleRate));
+                m_cbSampleRateRxOut->SetValue(wxString::Format(wxT("%i"),g_soundCard2SampleRate));
+            }
+        }
+        printf("  rxInAudioDeviceNum: %d\n  rxOutAudioDeviceNum: %d\n  txInAudioDeviceNum: %d\n  txOutAudioDeviceNum: %d\n",
+               rxInAudioDeviceNum, rxOutAudioDeviceNum, txInAudioDeviceNum, txOutAudioDeviceNum);
+    }
+
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        int valid_one_card_config = 0;
+        int valid_two_card_config = 0;
+        wxString sampleRate1, sampleRate2;
+
+        printf("EXCHANGE_DATA_OUT:\n");
+        printf("  rxInAudioDeviceNum: %d\n  rxOutAudioDeviceNum: %d\n  txInAudioDeviceNum: %d\n  txOutAudioDeviceNum: %d\n",
+               rxInAudioDeviceNum, rxOutAudioDeviceNum, txInAudioDeviceNum, txOutAudioDeviceNum);
+
+        // ---------------------------------------------------------------
+        // check we have a valid 1 or 2 sound card configuration
+        // ---------------------------------------------------------------
+
+        // one sound card config, tx device numbers should be set to -1 
+
+        if ((rxInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1) &&
+            (txInAudioDeviceNum == -1) && (txOutAudioDeviceNum == -1)) {
+            valid_one_card_config = 1; 
+
+            // in and out sample rate must be the same, as there is one callback
+            
+            sampleRate1 = m_cbSampleRateRxIn->GetValue();
+            if (!sampleRate1.IsSameAs(m_cbSampleRateRxOut->GetValue())) {
+                wxMessageBox(wxT("With a single sound card the Sample Rate of "
+                                 "From Radio and To Speaker/Headphones must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+        }
+
+        // two card configuration
+
+        if ((rxInAudioDeviceNum != -1) && (rxOutAudioDeviceNum != -1) &&
+            (txInAudioDeviceNum != -1) && (txOutAudioDeviceNum != -1)) {
+
+            valid_two_card_config = 1; 
+
+            // Check we haven't doubled up on sound devices
+
+            if (rxInAudioDeviceNum == txInAudioDeviceNum) {
+                wxMessageBox(wxT("You must use different devices for From Radio and From Microphone"), wxT(""), wxOK);
+                return -1;
+            }
+
+            if (rxOutAudioDeviceNum == txOutAudioDeviceNum) {
+                wxMessageBox(wxT("You must use different devices for To Radio and To Speaker/Headphones"), wxT(""), wxOK);
+                return -1;
+            }
+
+            // Check sample rates for callback 1 devices are the same,
+            // as input and output are handled synchronously by one
+            // portaudio callback
+            
+            sampleRate1 = m_cbSampleRateRxIn->GetValue();
+            if (!sampleRate1.IsSameAs(m_cbSampleRateTxOut->GetValue())) {
+                wxMessageBox(wxT("With two sound cards the Sample Rate "
+                                 "of From Radio and To Radio must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+            // check sample rate for callback 2 devices is the same
+
+            sampleRate2 = m_cbSampleRateTxIn->GetValue();
+            if (!sampleRate2.IsSameAs(m_cbSampleRateRxOut->GetValue())) {
+                wxMessageBox(wxT("With two sound cards the Sample Rate of "
+                                 "From Microphone and To Speaker/Headphones must be the same."), wxT(""), wxOK);
+                return -1;
+            }
+        }
+
+        printf("  valid_one_card_config: %d  valid_two_card_config: %d\n", valid_one_card_config, valid_two_card_config);
+
+        if (!valid_one_card_config && !valid_two_card_config) {
+            wxMessageBox(wxT("Invalid one or two sound card configuration"), wxT(""), wxOK);
+            return -1;
+        }
+
+        // ---------------------------------------------------------------
+        // Map Rx/TX device numbers to sound card device numbers used
+        // in callbacks. Portaudio uses one callback per sound card so
+        // we have to be soundcard oriented at run time rather than
+        // Tx/Rx oriented as in this dialog.
+        // ---------------------------------------------------------------
+        g_nSoundCards = 0;
+        g_soundCard1InDeviceNum = g_soundCard1OutDeviceNum = g_soundCard2InDeviceNum = g_soundCard2OutDeviceNum = -1;
+
+        if (valid_one_card_config) {
+
+            // Only callback 1 used
+
+            g_nSoundCards = 1;
+            g_soundCard1InDeviceNum  = rxInAudioDeviceNum;
+            g_soundCard1OutDeviceNum = rxOutAudioDeviceNum;
+            g_soundCard1SampleRate = wxAtoi(sampleRate1);
+        }
+
+        if (valid_two_card_config) {
+            g_nSoundCards = 2;
+            g_soundCard1InDeviceNum  = rxInAudioDeviceNum;
+            g_soundCard1OutDeviceNum = txOutAudioDeviceNum;
+            g_soundCard1SampleRate   = wxAtoi(sampleRate1);
+            g_soundCard2InDeviceNum  = txInAudioDeviceNum;
+            g_soundCard2OutDeviceNum = rxOutAudioDeviceNum;
+            g_soundCard2SampleRate   = wxAtoi(sampleRate2);
+        }
+
+        printf("  g_nSoundCards: %d\n", g_nSoundCards);
+        printf("  g_soundCard1InDeviceNum: %d\n", g_soundCard1InDeviceNum);
+        printf("  g_soundCard1OutDeviceNum: %d\n", g_soundCard1OutDeviceNum);
+        printf("  g_soundCard1SampleRate: %d\n", g_soundCard1SampleRate);
+        printf("  g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+        printf("  g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+        printf("  g_soundCard2SampleRate: %d\n", g_soundCard2SampleRate);
+
+        wxConfigBase *pConfig = wxConfigBase::Get();
+        pConfig->Write(wxT("/Audio/soundCard1InDeviceNum"),       g_soundCard1InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1OutDeviceNum"),      g_soundCard1OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1SampleRate"),        g_soundCard1SampleRate );
+
+        pConfig->Write(wxT("/Audio/soundCard2InDeviceNum"),       g_soundCard2InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2OutDeviceNum"),      g_soundCard2OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2SampleRate"),        g_soundCard2SampleRate );
+
+        pConfig->Flush();
+        delete wxConfigBase::Set((wxConfigBase *) NULL);
+    }
+
+    return 0;
+}
+
+//-------------------------------------------------------------------------
+// buildListOfSupportedSampleRates()
+//-------------------------------------------------------------------------
+int AudioOptsDialog:: buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out)
+{
+    // every sound device has a different list of supported sample rates, so
+    // we work out which ones are supported and populate the list ctrl
+
+    static double standardSampleRates[] =
+    {
+        8000.0,     9600.0,
+        11025.0,    12000.0,
+        16000.0,    22050.0,
+        24000.0,    32000.0,
+        44100.0,    48000.0,
+        88200.0,    96000.0,
+        192000.0,   -1          // negative terminated  list
+    };
+
+    const PaDeviceInfo  *deviceInfo;
+    PaStreamParameters   inputParameters, outputParameters;
+    PaError              err;
+    wxString             str;
+    int                  i, numSampleRates;
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        printf("Pa_GetDeviceInfo(%d) failed!\n", devNum);
+        cbSampleRate->Clear();
+        return 0;
+    }
+
+    inputParameters.device = devNum;
+    inputParameters.channelCount = deviceInfo->maxInputChannels;
+    inputParameters.sampleFormat = paInt16;
+    inputParameters.suggestedLatency = 0;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+        
+    outputParameters.device = devNum;
+    outputParameters.channelCount = deviceInfo->maxOutputChannels;
+    outputParameters.sampleFormat = paInt16;
+    outputParameters.suggestedLatency = 0;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    
+    cbSampleRate->Clear();
+    //printf("devNum %d supports: ", devNum);
+    numSampleRates = 0;
+    for(i = 0; standardSampleRates[i] > 0; i++)
+    {      
+        if (in_out == AUDIO_IN)
+            err = Pa_IsFormatSupported(&inputParameters, NULL, standardSampleRates[i]);
+        else
+            err = Pa_IsFormatSupported(NULL, &outputParameters, standardSampleRates[i]);
+
+        if( err == paFormatIsSupported ) {
+            str.Printf("%i", (int)standardSampleRates[i]);
+            cbSampleRate->AppendString(str);
+            printf("%i ", (int)standardSampleRates[i]);
+            numSampleRates++;
+        }
+    }
+    printf("\n");
+
+    return numSampleRates;
+}
+
+//-------------------------------------------------------------------------
+// showAPIInfo()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::showAPIInfo()
+{
+    wxString    strval;
+    int         apiVersion;
+    int         apiCount        = 0;
+    int         numDevices      = 0;
+
+    strval = Pa_GetVersionText();
+    m_textStringVer->SetLabel(strval);
+
+    apiVersion = Pa_GetVersion();
+    strval.Printf(wxT("%d"), apiVersion);
+    m_textIntVer->SetLabel(strval);
+
+    apiCount = Pa_GetHostApiCount();
+    strval.Printf(wxT("%d"), apiCount);
+    m_textAPICount->SetLabel(strval);
+
+    numDevices = Pa_GetDeviceCount();
+    strval.Printf(wxT("%d"), numDevices);
+    m_textCDevCount->SetLabel(strval);
+}
+
+//-------------------------------------------------------------------------
+// populateParams()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::populateParams(AudioInfoDisplay ai)
+{
+    const       PaDeviceInfo *deviceInfo = NULL;
+    wxListCtrl* ctrl    = ai.m_listDevices;
+    int         in_out  = ai.direction;
+    long        idx;
+    int         numDevices;
+    wxListItem  listItem;
+    wxString    buf;
+    int         devn;
+    int         col = 0;
+
+    numDevices = Pa_GetDeviceCount();
+
+    if(ctrl->GetColumnCount() > 0)
+    {
+        ctrl->ClearAll();
+    }
+
+    listItem.SetAlign(wxLIST_FORMAT_LEFT);
+    listItem.SetText(wxT("Device"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 300);
+
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("ID"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 45);
+
+    listItem.SetAlign(wxLIST_FORMAT_LEFT);
+    listItem.SetText(wxT("API"));
+    idx = ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+
+    if(in_out == AUDIO_IN)
+    {
+        listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+        listItem.SetText(wxT("Default Sample Rate"));
+        idx = ctrl->InsertColumn(col, listItem);
+        ctrl->SetColumnWidth(col++, 160);
+    }
+    else if(in_out == AUDIO_OUT)
+    {
+        listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+        listItem.SetText(wxT("Default Sample Rate"));
+        idx = ctrl->InsertColumn(col, listItem);
+        ctrl->SetColumnWidth(col++, 160);
+    }
+
+    #ifdef LATENCY
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("Min Latency"));
+    ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+
+    listItem.SetAlign(wxLIST_FORMAT_CENTRE);
+    listItem.SetText(wxT("Max Latency"));
+    ctrl->InsertColumn(col, listItem);
+    ctrl->SetColumnWidth(col++, 100);
+    #endif
+
+    for(devn = 0; devn < numDevices; devn++)
+    {
+        buf.Printf(wxT(""));
+        deviceInfo = Pa_GetDeviceInfo(devn);
+        if( ((in_out == AUDIO_IN) && (deviceInfo->maxInputChannels > 0)) ||
+            ((in_out == AUDIO_OUT) && (deviceInfo->maxOutputChannels > 0)))
+        {
+            col = 0;
+            buf.Printf(wxT("%s"), deviceInfo->name);
+            idx = ctrl->InsertItem(ctrl->GetItemCount(), buf);
+            col++;
+                
+            buf.Printf(wxT("%d"), devn);
+            ctrl->SetItem(idx, col++, buf);
+
+            buf.Printf(wxT("%s"), Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+            ctrl->SetItem(idx, col++, buf);
+
+            buf.Printf(wxT("%i"), (int)deviceInfo->defaultSampleRate);
+            ctrl->SetItem(idx, col++, buf);
+
+            #ifdef LATENCY
+            if (in_out == AUDIO_IN)
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultLowInputLatency);
+            else
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultLowOutputLatency);               
+            ctrl->SetItem(idx, col++, buf);
+
+            if (in_out == AUDIO_IN)
+                buf.Printf(wxT("%8.4f"), deviceInfo->defaultHighInputLatency);
+            else
+                 buf.Printf(wxT("%8.4f"), deviceInfo->defaultHighOutputLatency);             
+            ctrl->SetItem(idx, col++, buf);
+            #endif
+        }        
+    }
+
+    // add "none" option at end
+
+    buf.Printf(wxT("%s"), "none");
+    idx = ctrl->InsertItem(ctrl->GetItemCount(), buf);
+}
+
+//-------------------------------------------------------------------------
+// OnDeviceSelect()
+//
+// helper function to set up "Device:" and "Sample Rate:" fields when
+// we click on a line in the list of devices box
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnDeviceSelect(wxComboBox *cbSampleRate, 
+                                     wxTextCtrl *textCtrl, 
+                                     int        *devNum, 
+                                     wxListCtrl *listCtrlDevices, 
+                                     int         index,
+                                     int         in_out)
+{
+
+    wxString devName = listCtrlDevices->GetItemText(index, 0);
+     if (devName.IsSameAs("none")) {
+        *devNum = -1;
+        textCtrl->SetValue("none");
+    }
+    else {
+        *devNum = wxAtoi(listCtrlDevices->GetItemText(index, 1));
+        textCtrl->SetValue(devName + " (" + wxString::Format(wxT("%i"),*devNum) + ")");
+
+        int numSampleRates = buildListOfSupportedSampleRates(cbSampleRate, *devNum, in_out);
+        if (numSampleRates) {
+            wxString defSampleRate = listCtrlDevices->GetItemText(index, 3);        
+            cbSampleRate->SetValue(defSampleRate);
+        }
+        else {
+             cbSampleRate->SetValue("None");           
+        }
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnRxInDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxInDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateRxIn, 
+                   m_textCtrlRxIn, 
+                   &rxInAudioDeviceNum, 
+                   m_listCtrlRxInDevices, 
+                   evt.GetIndex(),
+                   AUDIO_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnRxOutDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxOutDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateRxOut, 
+                   m_textCtrlRxOut, 
+                   &rxOutAudioDeviceNum, 
+                   m_listCtrlRxOutDevices, 
+                   evt.GetIndex(),
+                   AUDIO_OUT);
+}
+
+//-------------------------------------------------------------------------
+// OnTxInDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxInDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateTxIn, 
+                   m_textCtrlTxIn, 
+                   &txInAudioDeviceNum, 
+                   m_listCtrlTxInDevices, 
+                   evt.GetIndex(),
+                   AUDIO_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnTxOutDeviceSelect()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxOutDeviceSelect(wxListEvent& evt)
+{
+    OnDeviceSelect(m_cbSampleRateTxOut, 
+                   m_textCtrlTxOut, 
+                   &txOutAudioDeviceNum, 
+                   m_listCtrlTxOutDevices, 
+                   evt.GetIndex(),
+                   AUDIO_OUT);
+}
+
+//-------------------------------------------------------------------------
+// plotDeviceInputForAFewSecs()
+//
+// opens a record device and plots the input speech for a few seconds.  This is "modal" using
+// synchronous portaudio functions, so the GUI will not respond until after test sample has been
+// taken
+//-------------------------------------------------------------------------
+void AudioOptsDialog::plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar) {
+    PaStreamParameters  inputParameters;
+    const PaDeviceInfo *deviceInfo = NULL;
+    PaStream           *stream = NULL;
+    PaError             err;
+    short               in48k_stereo_short[2*TEST_BUF_SIZE];
+    short               in48k_short[TEST_BUF_SIZE];
+    short               in8k_short[TEST_BUF_SIZE];
+    int                 numDevices, nBufs, i, j, src_error,inputChannels;
+    float               t;
+    SRC_STATE          *src;
+    FIFO               *fifo;
+
+    // a basic sanity check
+    numDevices = Pa_GetDeviceCount();
+    if (devNum >= numDevices)
+        return;
+    if (devNum < 0)
+        return;
+    printf("devNum %d\n", devNum);
+
+    fifo = fifo_create((int)(DT*TEST_WAVEFORM_PLOT_FS*2)); assert(fifo != NULL);
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(src != NULL);
+
+    // work out how many input channels this device supports.
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card "), wxT("Error"), wxOK);
+        return;
+    }
+    if (deviceInfo->maxInputChannels == 1)
+        inputChannels = 1;
+    else
+        inputChannels = 2;
+
+    // open device
+
+    inputParameters.device = devNum;
+    inputParameters.channelCount = inputChannels;
+    inputParameters.sampleFormat = paInt16;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    nBufs = TEST_WAVEFORM_PLOT_TIME*TEST_FS/TEST_BUF_SIZE;
+    printf("inputChannels: %d nBufs %d\n", inputChannels, nBufs);
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,
+              TEST_FS,
+              TEST_BUF_SIZE,
+              paClipOff,    
+              NULL,       // no callback, use blocking API
+              NULL ); 
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't initialise sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    err = Pa_StartStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't start sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    for(i=0, t=0.0; i<nBufs; i++, t+=(float)TEST_BUF_SIZE/TEST_FS) {
+        Pa_ReadStream(stream, in48k_stereo_short, TEST_BUF_SIZE);
+        if (inputChannels == 2) {
+            for(j=0; j<TEST_BUF_SIZE; j++)
+                in48k_short[j] = in48k_stereo_short[2*j]; // left channel only
+        }
+        else {
+            for(j=0; j<TEST_BUF_SIZE; j++)
+                in48k_short[j] = in48k_stereo_short[j]; 
+        }
+        int n8k = resample(src, in8k_short, in48k_short, 8000, TEST_FS, TEST_BUF_SIZE, TEST_BUF_SIZE);
+        resample_for_plot(fifo, in8k_short, n8k, FS);
+
+        // every TEST_DT seconds update plot, unfortunately plot
+        // doesnt get updated to end as we are blocking events in this
+        // function
+
+        if (t > TEST_DT) {
+            t -= TEST_DT;
+            short plotSamples[TEST_WAVEFORM_PLOT_BUF];
+            if (fifo_read(fifo, plotSamples, TEST_WAVEFORM_PLOT_BUF))
+                memset(plotSamples, 0, TEST_WAVEFORM_PLOT_BUF*sizeof(short));
+            plotScalar->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
+            plotScalar->Refresh();
+       }
+    }
+   
+    err = Pa_StopStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't stop sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+    Pa_CloseStream(stream);
+
+    fifo_destroy(fifo);
+    src_delete(src);
+}
+
+//-------------------------------------------------------------------------
+// plotDeviceOutputForAFewSecs()
+//
+// opens a play device and plays a tone for a few seconds.  This is "modal" using
+// synchronous portaudio functions, so the GUI will not respond until after test sample has been
+// taken.  Also plots a pretty picture like the record versions
+//-------------------------------------------------------------------------
+void AudioOptsDialog::plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar) {
+    PaStreamParameters  outputParameters;
+    const PaDeviceInfo *deviceInfo = NULL;
+    PaStream           *stream = NULL;
+    PaError             err;
+    short               out48k_stereo_short[2*TEST_BUF_SIZE];
+    short               out48k_short[TEST_BUF_SIZE];
+    short               out8k_short[TEST_BUF_SIZE];
+    int                 numDevices, nBufs, i, j, src_error, n, outputChannels;
+    float               t;
+    SRC_STATE          *src;
+    FIFO               *fifo;
+
+    // a basic sanity check
+    numDevices = Pa_GetDeviceCount();
+    if (devNum >= numDevices)
+        return;
+    if (devNum < 0)
+        return;
+
+    fifo = fifo_create((int)(DT*TEST_WAVEFORM_PLOT_FS*2)); assert(fifo != NULL);
+    src = src_new(SRC_SINC_FASTEST, 1, &src_error); assert(src != NULL);
+
+    // work out how many output channels this device supports.
+
+    deviceInfo = Pa_GetDeviceInfo(devNum);
+    if (deviceInfo == NULL) {
+        wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card "), wxT("Error"), wxOK);
+        return;
+    }
+    if (deviceInfo->maxOutputChannels == 1)
+        outputChannels = 1;
+    else
+        outputChannels = 2;
+
+    printf("outputChannels: %d\n", outputChannels);
+
+    outputParameters.device = devNum;
+    outputParameters.channelCount = outputChannels;
+    outputParameters.sampleFormat = paInt16;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    nBufs = TEST_WAVEFORM_PLOT_TIME*TEST_FS/TEST_BUF_SIZE;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL,
+              &outputParameters,
+              TEST_FS,
+              TEST_BUF_SIZE,
+              paClipOff,    
+              NULL,       // no callback, use blocking API
+              NULL ); 
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't initialise sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    err = Pa_StartStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't start sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+
+    for(i=0, t=0.0, n=0; i<nBufs; i++, t+=(float)TEST_BUF_SIZE/TEST_FS) {
+        for(j=0; j<TEST_BUF_SIZE; j++,n++) {
+            out48k_short[j] = 2000.0*cos(6.2832*(n++)*400.0/TEST_FS);
+            if (outputChannels == 2) {
+                out48k_stereo_short[2*j] = out48k_short[j];   // left channel
+                out48k_stereo_short[2*j+1] = out48k_short[j]; // right channel
+            }
+            else {
+                out48k_stereo_short[j] = out48k_short[j];     // mono
+            }
+        }
+        Pa_WriteStream(stream, out48k_stereo_short, TEST_BUF_SIZE);
+
+        // convert back to 8kHz just for plotting
+        int n8k = resample(src, out8k_short, out48k_short, 8000, TEST_FS, TEST_BUF_SIZE, TEST_BUF_SIZE);
+        resample_for_plot(fifo, out8k_short, n8k, FS);
+
+        // every TEST_DT seconds update plot
+
+        if (t > TEST_DT) {
+            t -= TEST_DT;
+            short plotSamples[TEST_WAVEFORM_PLOT_BUF];
+            if (fifo_read(fifo, plotSamples, TEST_WAVEFORM_PLOT_BUF))
+                memset(plotSamples, 0, TEST_WAVEFORM_PLOT_BUF*sizeof(short));
+            plotScalar->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
+            plotScalar->Refresh();
+       }
+    }
+   
+    err = Pa_StopStream(stream);
+    if (err != paNoError) {
+        wxMessageBox(wxT("Couldn't stop sound device."), wxT("Error"), wxOK);       
+        return;
+    }
+    Pa_CloseStream(stream);
+
+    fifo_destroy(fifo);
+    src_delete(src);
+}
+
+//-------------------------------------------------------------------------
+// OnRxInTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxInTest(wxCommandEvent& event)
+{
+    plotDeviceInputForAFewSecs(rxInAudioDeviceNum, m_plotScalarRxIn);
+}
+
+//-------------------------------------------------------------------------
+// OnRxOutTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRxOutTest(wxCommandEvent& event)
+{
+    plotDeviceOutputForAFewSecs(rxOutAudioDeviceNum, m_plotScalarRxOut);
+}
+
+//-------------------------------------------------------------------------
+// OnTxInTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxInTest(wxCommandEvent& event)
+{
+    plotDeviceInputForAFewSecs(txInAudioDeviceNum, m_plotScalarTxIn);
+}
+
+//-------------------------------------------------------------------------
+// OnTxOutTest()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnTxOutTest(wxCommandEvent& event)
+{
+    plotDeviceOutputForAFewSecs(txOutAudioDeviceNum, m_plotScalarTxOut);
+}
+
+//-------------------------------------------------------------------------
+// OnRefreshClick()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnRefreshClick(wxCommandEvent& event)
+{
+    // restart portaudio, to re-sample available devices
+
+    Pa_Terminate();
+    Pa_Init();
+
+    m_notebook1->SetSelection(0);
+    showAPIInfo();
+    populateParams(m_RxInDevices);
+    populateParams(m_RxOutDevices);
+    populateParams(m_TxInDevices);
+    populateParams(m_TxOutDevices);
+
+    // some devices may have dissapeared, so possibily change sound
+    // card config
+
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// OnApplyAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnApplyAudioParameters(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    if(m_isPaInitialized)
+    {
+        if((pa_err = Pa_Terminate()) == paNoError)
+        {
+            m_isPaInitialized = false;
+        }
+        else
+        {
+            wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+        }
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnCancelAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnCancelAudioParameters(wxCommandEvent& event)
+{
+    if(m_isPaInitialized)
+    {
+        if((pa_err = Pa_Terminate()) == paNoError)
+        {
+            m_isPaInitialized = false;
+        }
+        else
+        {
+            wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+        }
+    }
+    EndModal(wxCANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnOkAudioParameters()
+//-------------------------------------------------------------------------
+void AudioOptsDialog::OnOkAudioParameters(wxCommandEvent& event)
+{
+    int status = ExchangeData(EXCHANGE_DATA_OUT);
+
+    // We only accept OK if config sucessful
+
+    printf("status: %d m_isPaInitialized: %d\n", status, m_isPaInitialized);
+    if (status == 0) {
+        if(m_isPaInitialized)
+        {
+            if((pa_err = Pa_Terminate()) == paNoError)
+            {
+                printf("terminated OK\n");
+                m_isPaInitialized = false;
+            }
+            else
+            {
+                wxMessageBox(wxT("Port Audio failed to Terminate"), wxT("Pa_Terminate"), wxOK);
+            }
+        }
+        EndModal(wxOK);
+    }
+
+}
diff --git a/freedv/tags/1.2.2/src/dlg_audiooptions.h b/freedv/tags/1.2.2/src/dlg_audiooptions.h
new file mode 100644 (file)
index 0000000..5aa6741
--- /dev/null
@@ -0,0 +1,176 @@
+//=========================================================================
+// Name:          AudioInfoDisplay.h
+// Purpose:       Declares simple wxWidgets application with GUI
+//                created using wxFormBuilder.
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//=========================================================================
+#ifndef __AudioOptsDialog__
+#define __AudioOptsDialog__
+
+#include "fdmdv2_main.h"
+
+#define ID_AUDIO_OPTIONS    1000
+#define AUDIO_IN            0
+#define AUDIO_OUT           1
+
+#include "portaudio.h"
+#ifdef WIN32
+#if PA_USE_ASIO
+#include "pa_asio.h"
+#endif
+#endif
+#include "codec2_fifo.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// AudioInfoDisplay
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class AudioInfoDisplay
+{
+    public:
+        wxListCtrl*     m_listDevices;
+        int             direction;
+        wxTextCtrl*     m_textDevice;
+        wxComboBox*     m_cbSampleRate;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class AudioOptsDialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class AudioOptsDialog : public wxDialog
+{
+    private:
+
+    protected:
+        PaError         pa_err;
+        bool            m_isPaInitialized;
+
+        int             rxInAudioDeviceNum;
+        int             rxOutAudioDeviceNum;
+        int             txInAudioDeviceNum;
+        int             txOutAudioDeviceNum;
+
+        void buildTestControls(PlotScalar **plotScalar, wxButton **btnTest, 
+                               wxPanel *parentPanel, wxBoxSizer *bSizer, wxString buttonLabel);
+        void plotDeviceInputForAFewSecs(int devNum, PlotScalar *plotScalar);
+        void plotDeviceOutputForAFewSecs(int devNum, PlotScalar *plotScalar);
+
+        int buildListOfSupportedSampleRates(wxComboBox *cbSampleRate, int devNum, int in_out);
+        void populateParams(AudioInfoDisplay);
+        void showAPIInfo();
+        int setTextCtrlIfDevNumValid(wxTextCtrl *textCtrl, wxListCtrl *listCtrl, int devNum);
+        void Pa_Init(void);
+        void OnDeviceSelect(wxComboBox *cbSampleRate, 
+                            wxTextCtrl *textCtrl, 
+                            int        *devNum, 
+                            wxListCtrl *listCtrlDevices, 
+                            int         index,
+                            int         in_out);
+
+        AudioInfoDisplay m_RxInDevices;
+        AudioInfoDisplay m_RxOutDevices;
+        AudioInfoDisplay m_TxInDevices;
+        AudioInfoDisplay m_TxOutDevices;
+        wxPanel* m_panel1;
+        wxNotebook* m_notebook1;
+
+        wxPanel* m_panelRx;
+
+        wxListCtrl* m_listCtrlRxInDevices;
+        wxStaticText* m_staticText51;
+        wxTextCtrl* m_textCtrlRxIn;
+        wxStaticText* m_staticText6;
+        wxComboBox* m_cbSampleRateRxIn;
+
+        wxButton* m_btnRxInTest;
+        PlotScalar* m_plotScalarRxIn;
+
+        wxListCtrl* m_listCtrlRxOutDevices;
+        wxStaticText* m_staticText9;
+        wxTextCtrl* m_textCtrlRxOut;
+        wxStaticText* m_staticText10;
+        wxComboBox* m_cbSampleRateRxOut;
+
+        wxButton* m_btnRxOutTest;
+        PlotScalar* m_plotScalarRxOut;
+
+        wxPanel* m_panelTx;
+
+        wxListCtrl* m_listCtrlTxInDevices;
+        wxStaticText* m_staticText12;
+        wxTextCtrl* m_textCtrlTxIn;
+        wxStaticText* m_staticText11;
+        wxComboBox* m_cbSampleRateTxIn;
+
+        wxButton* m_btnTxInTest;
+        PlotScalar* m_plotScalarTxIn;
+
+        wxListCtrl* m_listCtrlTxOutDevices;
+        wxStaticText* m_staticText81;
+        wxTextCtrl* m_textCtrlTxOut;
+        wxStaticText* m_staticText71;
+        wxComboBox* m_cbSampleRateTxOut;
+
+        wxButton* m_btnTxOutTest;
+        PlotScalar* m_plotScalarTxOut;
+
+        wxPanel* m_panelAPI;
+
+        wxStaticText* m_staticText7;
+        wxStaticText* m_textStringVer;
+        wxStaticText* m_staticText8;
+        wxStaticText* m_textIntVer;
+        wxStaticText* m_staticText5;
+        wxStaticText* m_textCDevCount;
+        wxStaticText* m_staticText4;
+        wxStaticText* m_textAPICount;
+        wxButton* m_btnRefresh;
+        wxStdDialogButtonSizer* m_sdbSizer1;
+        wxButton* m_sdbSizer1OK;
+        wxButton* m_sdbSizer1Apply;
+        wxButton* m_sdbSizer1Cancel;
+
+        // Virtual event handlers, overide them in your derived class
+        //virtual void OnActivateApp( wxActivateEvent& event ) { event.Skip(); }
+//        virtual void OnCloseFrame( wxCloseEvent& event ) { event.Skip(); }
+
+        void OnRxInDeviceSelect( wxListEvent& event );
+
+        void OnRxInTest( wxCommandEvent& event );
+        void OnRxOutTest( wxCommandEvent& event );
+        void OnTxInTest( wxCommandEvent& event );
+        void OnTxOutTest( wxCommandEvent& event );
+
+        void OnRxOutDeviceSelect( wxListEvent& event );
+        void OnTxInDeviceSelect( wxListEvent& event );
+        void OnTxOutDeviceSelect( wxListEvent& event );
+        void OnRefreshClick( wxCommandEvent& event );
+        void OnApplyAudioParameters( wxCommandEvent& event );
+        void OnCancelAudioParameters( wxCommandEvent& event );
+        void OnOkAudioParameters( wxCommandEvent& event );
+        // Virtual event handlers, overide them in your derived class
+        void OnClose( wxCloseEvent& event ) { event.Skip(); }
+        void OnHibernate( wxActivateEvent& event ) { event.Skip(); }
+        void OnIconize( wxIconizeEvent& event ) { event.Skip(); }
+        void OnInitDialog( wxInitDialogEvent& event );
+
+    public:
+
+        AudioOptsDialog( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Audio Config"), const wxPoint& pos = wxPoint(1,1), const wxSize& size = wxSize( 800, 650 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~AudioOptsDialog();
+        int ExchangeData(int inout);
+};
+#endif //__AudioOptsDialog__
diff --git a/freedv/tags/1.2.2/src/dlg_filter.cpp b/freedv/tags/1.2.2/src/dlg_filter.cpp
new file mode 100644 (file)
index 0000000..5a5294a
--- /dev/null
@@ -0,0 +1,785 @@
+//==========================================================================
+// Name:            dlg_filter.cpp
+// Purpose:         Dialog for controlling Codec audio filtering
+// Date:            Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "dlg_filter.h"
+
+#define SLIDER_MAX 100
+#define SLIDER_LENGTH 100
+
+#define FILTER_MIN_MAG_DB -20.0
+#define FILTER_MAX_MAG_DB  20.0
+
+#define MAX_FREQ_BASS      600.00
+#define MAX_FREQ_TREBLE   3900.00
+#define MAX_FREQ_DEF      3000.00
+
+#define MIN_GAIN          -20
+#define MAX_GAIN           20
+
+#define MAX_LOG10_Q         1.0
+#define MIN_LOG10_Q        -1.0 
+
+// DFT parameters
+
+#define IMP_AMP           2000.0                     // amplitude of impulse
+#define NIMP              50                         // number of samples in impulse response
+#define F_STEP_DFT        10.0                       // frequency steps to sample spectrum
+#define F_MAG_N           (int)(MAX_F_HZ/F_STEP_DFT) // number of frequency steps
+
+extern struct freedv      *g_pfreedv;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class FilterDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
+                     wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    m_running = running;
+    m_newMicInFilter = newMicInFilter;
+    m_newSpkOutFilter = newSpkOutFilter;
+
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+
+    wxBoxSizer* bSizer30;
+    bSizer30 = new wxBoxSizer(wxVERTICAL);
+
+    // LPC Post Filter --------------------------------------------------------
+
+    wxStaticBoxSizer* lpcpfs = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("LPC Post Filter")), wxHORIZONTAL);
+
+    wxBoxSizer* left = new wxBoxSizer(wxVERTICAL);
+
+    m_codec2LPCPostFilterEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    left->Add(m_codec2LPCPostFilterEnable);
+
+    m_codec2LPCPostFilterBassBoost = new wxCheckBox(this, wxID_ANY, _("0-1 kHz 3dB Boost"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    left->Add(m_codec2LPCPostFilterBassBoost);
+    lpcpfs->Add(left, 0, wxALL, 5);
+
+    newLPCPFControl(&m_codec2LPCPostFilterBeta, &m_staticTextBeta, lpcpfs, "Beta");
+    newLPCPFControl(&m_codec2LPCPostFilterGamma, &m_staticTextGamma, lpcpfs, "Gamma");
+
+    m_LPCPostFilterDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    lpcpfs->Add(m_LPCPostFilterDefault, 0, wxALL|wxALIGN_CENTRE_HORIZONTAL|wxALIGN_CENTRE_VERTICAL, 5);
+
+    bSizer30->Add(lpcpfs, 0, wxALL, 0);
+
+    // Speex pre-processor --------------------------------------------------
+
+    wxStaticBoxSizer* sbSizer_speexpp;
+    wxStaticBox *sb_speexpp = new wxStaticBox(this, wxID_ANY, _("Speex Mic Audio Pre-Processor"));
+    sbSizer_speexpp = new wxStaticBoxSizer(sb_speexpp, wxVERTICAL);
+
+    m_ckboxSpeexpp = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_speexpp->SetToolTip(_("Enable noise supression, dereverberation, AGC of mic signal"));
+    sbSizer_speexpp->Add(m_ckboxSpeexpp, wxALIGN_LEFT, 2);
+
+    bSizer30->Add(sbSizer_speexpp, 0, wxALL, 0);   
+
+    // EQ Filters -----------------------------------------------------------
+
+    wxStaticBoxSizer* eqMicInSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mic In Equaliser")), wxVERTICAL);
+    wxBoxSizer* eqMicInSizer1 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* eqMicInSizer2 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_MicInBass   = newEQ(eqMicInSizer1, "Bass"  , MAX_FREQ_BASS, disableQ);
+    m_MicInTreble = newEQ(eqMicInSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
+    eqMicInSizer->Add(eqMicInSizer1);
+
+    m_MicInEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    eqMicInSizer2->Add(m_MicInEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
+    m_MicInMid    = newEQ(eqMicInSizer2, "Mid"   , MAX_FREQ_DEF, enableQ);
+    m_MicInDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    eqMicInSizer2->Add(m_MicInDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
+    eqMicInSizer->Add(eqMicInSizer2);
+
+    wxStaticBoxSizer* eqSpkOutSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Speaker Out Equaliser")), wxVERTICAL);
+    wxBoxSizer* eqSpkOutSizer1 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* eqSpkOutSizer2 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_SpkOutBass   = newEQ(eqSpkOutSizer1, "Bass"  , MAX_FREQ_BASS, disableQ);
+    m_SpkOutTreble = newEQ(eqSpkOutSizer1, "Treble", MAX_FREQ_TREBLE, disableQ);
+    eqSpkOutSizer->Add(eqSpkOutSizer1);
+
+    m_SpkOutEnable = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition,wxDefaultSize, wxCHK_2STATE);
+    eqSpkOutSizer2->Add(m_SpkOutEnable,0,wxALIGN_CENTRE_VERTICAL|wxRIGHT,10);
+    m_SpkOutMid    = newEQ(eqSpkOutSizer2, "Mid"   , MAX_FREQ_DEF, enableQ);
+    m_SpkOutDefault = new wxButton(this, wxID_ANY, wxT("Default"));
+    eqSpkOutSizer2->Add(m_SpkOutDefault,0,wxALIGN_CENTRE_VERTICAL|wxLEFT,20);
+    eqSpkOutSizer->Add(eqSpkOutSizer2);
+    
+    bSizer30->Add(eqMicInSizer, 0, wxALL, 0);
+    bSizer30->Add(eqSpkOutSizer, 0, wxALL, 0);
+
+    // Storgage for spectrum magnitude plots ------------------------------------
+
+    m_MicInMagdB = new float[F_MAG_N];
+    for(int i=0; i<F_MAG_N; i++)
+        m_MicInMagdB[i] = 0.0;
+
+    m_SpkOutMagdB = new float[F_MAG_N];
+    for(int i=0; i<F_MAG_N; i++)
+        m_SpkOutMagdB[i] = 0.0;
+
+    // Spectrum Plots -----------------------------------------------------------
+
+    long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
+    m_auiNotebook = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxSize(-1,200), nb_style);
+    m_auiNotebook->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
+
+    bSizer30->Add(m_auiNotebook, 0, wxEXPAND|wxALL, 3);
+    
+    m_MicInFreqRespPlot = new PlotSpectrum((wxFrame*) m_auiNotebook, m_MicInMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
+    m_auiNotebook->AddPage(m_MicInFreqRespPlot, _("Microphone In Equaliser"));
+
+    m_SpkOutFreqRespPlot = new PlotSpectrum((wxFrame*)m_auiNotebook, m_SpkOutMagdB, F_MAG_N, FILTER_MIN_MAG_DB, FILTER_MAX_MAG_DB);
+    m_auiNotebook->AddPage(m_SpkOutFreqRespPlot, _("Speaker Out Equaliser"));
+
+    //  OK - Cancel buttons at the bottom --------------------------
+
+    wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_sdbSizer5OK = new wxButton(this, wxID_OK);
+    bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
+
+    m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
+    bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
+
+    bSizer30->Add(bSizer31, 0, wxALIGN_RIGHT|wxALL, 0);
+
+    this->SetSizer(bSizer30);
+    this->Layout();
+
+    this->Centre(wxBOTH);
+    // Connect Events -------------------------------------------------------
+
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
+
+    m_codec2LPCPostFilterEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
+    m_codec2LPCPostFilterBassBoost->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
+    m_codec2LPCPostFilterBeta->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
+    m_codec2LPCPostFilterGamma->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
+    m_LPCPostFilterDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
+
+    m_ckboxSpeexpp->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpeexppEnable), NULL, this);
+
+    m_MicInBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
+    m_MicInBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
+    m_MicInTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
+    m_MicInTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
+    m_MicInMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
+    m_MicInMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
+    m_MicInMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
+    m_MicInEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
+    m_MicInDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
+
+    m_SpkOutBass.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
+    m_SpkOutBass.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
+    m_SpkOutTreble.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
+    m_SpkOutTreble.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
+    m_SpkOutMid.sliderFreq->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
+    m_SpkOutMid.sliderGain->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
+    m_SpkOutMid.sliderQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
+    m_SpkOutEnable->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
+    m_SpkOutDefault->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
+
+    m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
+    m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// ~FilterDlg()
+//-------------------------------------------------------------------------
+FilterDlg::~FilterDlg()
+{
+    delete m_MicInMagdB;
+    delete m_SpkOutMagdB;
+
+    // Disconnect Events
+
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(FilterDlg::OnInitDialog));
+
+    m_codec2LPCPostFilterEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnEnable), NULL, this);
+    m_codec2LPCPostFilterBassBoost->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnBassBoost), NULL, this);
+    m_codec2LPCPostFilterBeta->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnBetaScroll), NULL, this);
+    m_codec2LPCPostFilterGamma->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnGammaScroll), NULL, this);
+    m_LPCPostFilterDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnLPCPostFilterDefault), NULL, this);
+
+    m_MicInBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassFreqScroll), NULL, this);
+    m_MicInBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInBassGainScroll), NULL, this);
+    m_MicInTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleFreqScroll), NULL, this);
+    m_MicInTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInTrebleGainScroll), NULL, this);
+    m_MicInMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidFreqScroll), NULL, this);
+    m_MicInMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidGainScroll), NULL, this);
+    m_MicInMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnMicInMidQScroll), NULL, this);
+    m_MicInEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnMicInEnable), NULL, this);
+    m_MicInDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnMicInDefault), NULL, this);
+
+    m_SpkOutBass.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassFreqScroll), NULL, this);
+    m_SpkOutBass.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutBassGainScroll), NULL, this);
+    m_SpkOutTreble.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleFreqScroll), NULL, this);
+    m_SpkOutTreble.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutTrebleGainScroll), NULL, this);
+    m_SpkOutMid.sliderFreq->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidFreqScroll), NULL, this);
+    m_SpkOutMid.sliderGain->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidGainScroll), NULL, this);
+    m_SpkOutMid.sliderQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(FilterDlg::OnSpkOutMidQScroll), NULL, this);
+    m_SpkOutEnable->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(FilterDlg::OnSpkOutEnable), NULL, this);
+    m_SpkOutDefault->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnSpkOutDefault), NULL, this);
+
+    m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
+    m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
+}
+
+void FilterDlg::newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *s, wxString controlName)
+{
+    wxBoxSizer *bs = new wxBoxSizer(wxHORIZONTAL);
+
+    wxStaticText* st = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxSize(70,-1), wxALIGN_RIGHT);
+    bs->Add(st, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 2);
+
+    *slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
+    bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 2);
+
+    *stValue = new wxStaticText(this, wxID_ANY, wxT("0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    bs->Add(*stValue, 1, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 2);
+
+    s->Add(bs, 0);
+}
+
+void FilterDlg::newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName)
+{
+    wxStaticText* label = new wxStaticText(this, wxID_ANY, controlName, wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
+    bs->Add(label, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 0);
+
+    *slider = new wxSlider(this, wxID_ANY, 0, 0, SLIDER_MAX, wxDefaultPosition, wxSize(SLIDER_LENGTH,wxDefaultCoord));
+    bs->Add(*slider, 1, wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    *value = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(40,-1), wxALIGN_LEFT);
+    bs->Add(*value, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxRIGHT, 5);
+}
+
+EQ FilterDlg::newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ)
+{
+    EQ eq;
+
+    wxStaticBoxSizer *bsEQ = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, eqName), wxHORIZONTAL);
+
+    newEQControl(&eq.sliderFreq, &eq.valueFreq, bsEQ, "Freq"); 
+    eq.maxFreqHz = maxFreqHz; 
+    eq.sliderFreqId = eq.sliderFreq->GetId();
+
+    newEQControl(&eq.sliderGain, &eq.valueGain, bsEQ, "Gain");
+    if (enableQ)
+        newEQControl(&eq.sliderQ, &eq.valueQ, bsEQ, "Q");
+    else
+        eq.sliderQ = NULL;
+
+    bs->Add(bsEQ);
+
+    return eq;
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void FilterDlg::ExchangeData(int inout, bool storePersistent)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        // LPC Post filter
+
+        m_codec2LPCPostFilterEnable->SetValue(wxGetApp().m_codec2LPCPostFilterEnable);
+        m_codec2LPCPostFilterBassBoost->SetValue(wxGetApp().m_codec2LPCPostFilterBassBoost);
+        m_beta = wxGetApp().m_codec2LPCPostFilterBeta; setBeta();
+        m_gamma = wxGetApp().m_codec2LPCPostFilterGamma; setGamma();
+
+        // Speex Pre-Processor
+
+        m_ckboxSpeexpp->SetValue(wxGetApp().m_speexpp_enable);
+
+        // Mic In Equaliser
+
+        m_MicInBass.freqHz = wxGetApp().m_MicInBassFreqHz; 
+        m_MicInBass.freqHz = limit(m_MicInBass.freqHz, 1.0, MAX_FREQ_BASS);
+        setFreq(&m_MicInBass);
+        m_MicInBass.gaindB = wxGetApp().m_MicInBassGaindB;
+        m_MicInBass.gaindB = limit(m_MicInBass.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInBass);
+
+        m_MicInTreble.freqHz = wxGetApp().m_MicInTrebleFreqHz;
+        m_MicInTreble.freqHz = limit(m_MicInTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_MicInTreble);
+        m_MicInTreble.gaindB = wxGetApp().m_MicInTrebleGaindB; 
+        m_MicInTreble.gaindB = limit(m_MicInTreble.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInTreble);
+
+        m_MicInMid.freqHz = wxGetApp().m_MicInMidFreqHz; 
+        m_MicInMid.freqHz = limit(m_MicInMid.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_MicInMid);
+        m_MicInMid.gaindB = wxGetApp().m_MicInMidGaindB; 
+        m_MicInMid.gaindB = limit(m_MicInMid.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_MicInMid);
+        m_MicInMid.Q = wxGetApp().m_MicInMidQ;
+        m_MicInMid.Q = limit(m_MicInMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
+        setQ(&m_MicInMid);
+
+        m_MicInEnable->SetValue(wxGetApp().m_MicInEQEnable);
+
+        plotMicInFilterSpectrum();
+        // Spk Out Equaliser
+
+        m_SpkOutBass.freqHz = wxGetApp().m_SpkOutBassFreqHz;
+        m_SpkOutBass.freqHz = limit(m_SpkOutBass.freqHz, 1.0, MAX_FREQ_BASS);
+        setFreq(&m_SpkOutBass);
+        m_SpkOutBass.gaindB = wxGetApp().m_SpkOutBassGaindB; 
+        m_SpkOutBass.gaindB = limit(m_SpkOutBass.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutBass);
+
+        m_SpkOutTreble.freqHz = wxGetApp().m_SpkOutTrebleFreqHz; 
+        m_SpkOutTreble.freqHz = limit(m_SpkOutTreble.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_SpkOutTreble);
+        m_SpkOutTreble.gaindB = wxGetApp().m_SpkOutTrebleGaindB; 
+        m_SpkOutTreble.gaindB = limit(m_SpkOutTreble.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutTreble);
+
+        m_SpkOutMid.freqHz = wxGetApp().m_SpkOutMidFreqHz;
+        m_SpkOutMid.freqHz = limit(m_SpkOutMid.freqHz, 1.0, MAX_FREQ_TREBLE);
+        setFreq(&m_SpkOutMid);
+        m_SpkOutMid.gaindB = wxGetApp().m_SpkOutMidGaindB;
+        m_SpkOutMid.gaindB = limit(m_SpkOutMid.gaindB, MIN_GAIN, MAX_GAIN);
+        setGain(&m_SpkOutMid);
+        m_SpkOutMid.Q = wxGetApp().m_SpkOutMidQ;
+        m_SpkOutMid.Q = limit(m_SpkOutMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
+        setQ(&m_SpkOutMid);
+
+        m_SpkOutEnable->SetValue(wxGetApp().m_SpkOutEQEnable);
+
+        plotSpkOutFilterSpectrum();
+    }
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        // LPC Post filter
+
+        wxGetApp().m_codec2LPCPostFilterEnable     = m_codec2LPCPostFilterEnable->GetValue();
+        wxGetApp().m_codec2LPCPostFilterBassBoost  = m_codec2LPCPostFilterBassBoost->GetValue();
+        wxGetApp().m_codec2LPCPostFilterBeta       = m_beta;
+        wxGetApp().m_codec2LPCPostFilterGamma      = m_gamma;
+
+        // Speex Pre-Processor
+
+        wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
+
+        // Mic In Equaliser
+
+        wxGetApp().m_MicInBassFreqHz = m_MicInBass.freqHz;
+        wxGetApp().m_MicInBassGaindB = m_MicInBass.gaindB;
+
+        wxGetApp().m_MicInTrebleFreqHz = m_MicInTreble.freqHz;
+        wxGetApp().m_MicInTrebleGaindB = m_MicInTreble.gaindB;
+
+        wxGetApp().m_MicInMidFreqHz = m_MicInMid.freqHz;
+        wxGetApp().m_MicInMidGaindB = m_MicInMid.gaindB;
+        wxGetApp().m_MicInMidQ = m_MicInMid.Q;
+
+        // Spk Out Equaliser
+
+        wxGetApp().m_SpkOutBassFreqHz = m_SpkOutBass.freqHz;
+        wxGetApp().m_SpkOutBassGaindB = m_SpkOutBass.gaindB;
+
+        wxGetApp().m_SpkOutTrebleFreqHz = m_SpkOutTreble.freqHz;
+        wxGetApp().m_SpkOutTrebleGaindB = m_SpkOutTreble.gaindB;
+
+        wxGetApp().m_SpkOutMidFreqHz = m_SpkOutMid.freqHz;
+        wxGetApp().m_SpkOutMidGaindB = m_SpkOutMid.gaindB;
+        wxGetApp().m_SpkOutMidQ = m_SpkOutMid.Q;
+
+        if (storePersistent) {
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterEnable"),     wxGetApp().m_codec2LPCPostFilterEnable);
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterBassBoost"),  wxGetApp().m_codec2LPCPostFilterBassBoost);
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterBeta"),       (int)(m_beta*100.0));
+            pConfig->Write(wxT("/Filter/codec2LPCPostFilterGamma"),      (int)(m_gamma*100.0));
+
+            pConfig->Write(wxT("/Filter/speexpp_enable"),                wxGetApp().m_speexpp_enable);
+
+            pConfig->Write(wxT("/Filter/MicInBassFreqHz"), (int)m_MicInBass.freqHz);
+            pConfig->Write(wxT("/Filter/MicInBassGaindB"), (int)(10.0*m_MicInBass.gaindB));
+            pConfig->Write(wxT("/Filter/MicInTrebleFreqHz"), (int)m_MicInTreble.freqHz);
+            pConfig->Write(wxT("/Filter/MicInTrebleGaindB"), (int)(10.0*m_MicInTreble.gaindB));
+            pConfig->Write(wxT("/Filter/MicInMidFreqHz"), (int)m_MicInMid.freqHz);
+            pConfig->Write(wxT("/Filter/MicInMidGaindB"), (int)(10.0*m_MicInMid.gaindB));
+            pConfig->Write(wxT("/Filter/MicInMidQ"), (int)(100.0*m_MicInMid.Q));
+
+            pConfig->Write(wxT("/Filter/SpkOutBassFreqHz"), (int)m_SpkOutBass.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutBassGaindB"), (int)(10.0*m_SpkOutBass.gaindB));
+            pConfig->Write(wxT("/Filter/SpkOutTrebleFreqHz"), (int)m_SpkOutTreble.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutTrebleGaindB"), (int)(10.0*m_SpkOutTreble.gaindB));
+            pConfig->Write(wxT("/Filter/SpkOutMidQ"), (int)(100.0*m_SpkOutMid.Q));
+            pConfig->Write(wxT("/Filter/SpkOutMidFreqHz"), (int)m_SpkOutMid.freqHz);
+            pConfig->Write(wxT("/Filter/SpkOutMidGaindB"), (int)(10.0*m_SpkOutMid.gaindB));
+
+            pConfig->Flush();
+        }
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+float FilterDlg::limit(float value, float min, float max) {
+    if (value < min) return min;
+    if (value > max) return max;
+    return value;
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void FilterDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnDefault()
+//-------------------------------------------------------------------------
+
+void FilterDlg::OnLPCPostFilterDefault(wxCommandEvent& event)
+{
+    m_beta = CODEC2_LPC_PF_BETA; setBeta();
+    m_gamma = CODEC2_LPC_PF_GAMMA; setGamma();
+    m_codec2LPCPostFilterEnable->SetValue(true);
+    m_codec2LPCPostFilterBassBoost->SetValue(true);
+}
+
+void FilterDlg::OnMicInDefault(wxCommandEvent& event)
+{
+    m_MicInBass.freqHz = 100.0;
+    m_MicInBass.gaindB = 0.0;
+    setFreq(&m_MicInBass); setGain(&m_MicInBass); 
+
+    m_MicInTreble.freqHz = 3000.0;
+    m_MicInTreble.gaindB = 0.0;
+    setFreq(&m_MicInTreble); setGain(&m_MicInTreble); 
+
+    m_MicInMid.freqHz = 1500.0;
+    m_MicInMid.gaindB = 0.0;
+    m_MicInMid.Q = 1.0;
+    setFreq(&m_MicInMid); setGain(&m_MicInMid); setQ(&m_MicInMid); 
+
+    plotMicInFilterSpectrum();    
+}
+
+void FilterDlg::OnSpkOutDefault(wxCommandEvent& event)
+{
+    m_SpkOutBass.freqHz = 100.0;
+    m_SpkOutBass.gaindB = 0.0;
+    setFreq(&m_SpkOutBass); setGain(&m_SpkOutBass); 
+
+    m_SpkOutTreble.freqHz = 3000.0;
+    m_SpkOutTreble.gaindB = 0.0;
+    setFreq(&m_SpkOutTreble); setGain(&m_SpkOutTreble); 
+
+    m_SpkOutMid.freqHz = 1500.0;
+    m_SpkOutMid.gaindB = 0.0;
+    m_SpkOutMid.Q = 1.0;
+    setFreq(&m_SpkOutMid); setGain(&m_SpkOutMid); setQ(&m_SpkOutMid); 
+
+    plotSpkOutFilterSpectrum();    
+}
+
+//-------------------------------------------------------------------------
+// OnOK()
+//-------------------------------------------------------------------------
+void FilterDlg::OnOK(wxCommandEvent& event)
+{
+    //printf("FilterDlg::OnOK\n");
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+    this->EndModal(wxID_OK);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void FilterDlg::OnClose(wxCloseEvent& event)
+{
+    this->EndModal(wxID_OK);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void FilterDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    //printf("FilterDlg::OnInitDialog\n");
+    ExchangeData(EXCHANGE_DATA_IN, false);
+    //printf("m_beta: %f\n", m_beta);
+}
+
+void FilterDlg::setBeta(void) {
+    wxString buf;
+    buf.Printf(wxT("%3.2f"), m_beta);
+    m_staticTextBeta->SetLabel(buf);
+    int slider = (int)(m_beta*SLIDER_MAX + 0.5);
+    m_codec2LPCPostFilterBeta->SetValue(slider);
+}
+
+void FilterDlg::setCodec2(void) {
+    if (m_running) {
+        codec2_set_lpc_post_filter(freedv_get_codec2(g_pfreedv), 
+                               m_codec2LPCPostFilterEnable->GetValue(), 
+                               m_codec2LPCPostFilterBassBoost->GetValue(), 
+                               m_beta, m_gamma);
+    }
+}
+
+void FilterDlg::setGamma(void) {
+    wxString buf;
+    buf.Printf(wxT("%3.2f"), m_gamma);
+    m_staticTextGamma->SetLabel(buf);
+    int slider = (int)(m_gamma*SLIDER_MAX + 0.5);
+    m_codec2LPCPostFilterGamma->SetValue(slider);
+}
+
+void FilterDlg::OnEnable(wxScrollEvent& event) {
+    setCodec2();    
+}
+
+void FilterDlg::OnBassBoost(wxScrollEvent& event) {
+    setCodec2();    
+}
+
+void FilterDlg::OnBetaScroll(wxScrollEvent& event) {
+    m_beta = (float)m_codec2LPCPostFilterBeta->GetValue()/SLIDER_MAX;
+    setBeta();
+    setCodec2();
+}
+
+void FilterDlg::OnGammaScroll(wxScrollEvent& event) {
+    m_gamma = (float)m_codec2LPCPostFilterGamma->GetValue()/SLIDER_MAX;
+    setGamma();
+    setCodec2();
+}
+
+// immediately change enable flags rather using ExchangeData() so we can switch on and off at run time
+
+void FilterDlg::OnSpeexppEnable(wxScrollEvent& event) {
+    wxGetApp().m_speexpp_enable = m_ckboxSpeexpp->GetValue();
+}
+
+void FilterDlg::OnMicInEnable(wxScrollEvent& event) {
+    wxGetApp().m_MicInEQEnable = m_MicInEnable->GetValue();
+}
+
+void FilterDlg::OnSpkOutEnable(wxScrollEvent& event) {
+    wxGetApp().m_SpkOutEQEnable = m_SpkOutEnable->GetValue();
+    //printf("wxGetApp().m_SpkOutEQEnable: %d\n", wxGetApp().m_SpkOutEQEnable);
+}
+
+void FilterDlg::setFreq(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%3.0f"), eq->freqHz);
+    eq->valueFreq->SetLabel(buf);
+    int slider = (int)((eq->freqHz/eq->maxFreqHz)*SLIDER_MAX + 0.5);
+    eq->sliderFreq->SetValue(slider);
+}
+
+void FilterDlg::sliderToFreq(EQ *eq, bool micIn)
+{
+    eq->freqHz = ((float)eq->sliderFreq->GetValue()/SLIDER_MAX)*eq->maxFreqHz;
+    if (eq->freqHz < 1.0) eq->freqHz = 1.0; // sox doesn't like 0 Hz;
+    setFreq(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+}
+
+void FilterDlg::setGain(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%3.1f"), eq->gaindB);
+    eq->valueGain->SetLabel(buf);
+    int slider = (int)(((eq->gaindB-MIN_GAIN)/(MAX_GAIN-MIN_GAIN))*SLIDER_MAX + 0.5);
+    eq->sliderGain->SetValue(slider);
+}
+
+void FilterDlg::sliderToGain(EQ *eq, bool micIn)
+{
+    float range = MAX_GAIN-MIN_GAIN;
+    
+    eq->gaindB = MIN_GAIN + range*((float)eq->sliderGain->GetValue()/SLIDER_MAX);
+    //printf("gaindB: %f\n", eq->gaindB);
+    setGain(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+        
+}
+
+void FilterDlg::setQ(EQ *eq)
+{
+    wxString buf;
+    buf.Printf(wxT("%2.1f"), eq->Q);
+    eq->valueQ->SetLabel(buf);
+
+    float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
+
+    int slider = (int)(((log10(eq->Q+1E-6)-MIN_LOG10_Q)/log10_range)*SLIDER_MAX + 0.5);
+    eq->sliderQ->SetValue(slider);
+}
+
+void FilterDlg::sliderToQ(EQ *eq, bool micIn)
+{
+    float log10_range = MAX_LOG10_Q - MIN_LOG10_Q;
+    
+    float sliderNorm = (float)eq->sliderQ->GetValue()/SLIDER_MAX;
+    float log10Q =  MIN_LOG10_Q + sliderNorm*(log10_range);
+    eq->Q = pow(10.0, log10Q);
+    //printf("log10Q: %f eq->Q: %f\n", log10Q, eq->Q);
+    setQ(eq);
+    if (micIn) {
+        plotMicInFilterSpectrum();
+        adjRunTimeMicInFilter();
+    }
+    else {
+        plotSpkOutFilterSpectrum();
+        adjRunTimeSpkOutFilter();
+    }
+}
+
+void FilterDlg::plotMicInFilterSpectrum(void) {
+    plotFilterSpectrum(&m_MicInBass, &m_MicInMid, &m_MicInTreble, m_MicInFreqRespPlot, m_MicInMagdB);
+}
+
+void FilterDlg::plotSpkOutFilterSpectrum(void) {
+    plotFilterSpectrum(&m_SpkOutBass, &m_SpkOutMid, &m_SpkOutTreble, m_SpkOutFreqRespPlot, m_SpkOutMagdB);
+}
+
+void FilterDlg::adjRunTimeMicInFilter(void) {
+    // signal an adjustment in running filter coeffs
+
+    if (m_running) {
+        ExchangeData(EXCHANGE_DATA_OUT, false);
+        *m_newMicInFilter = true;
+    }
+}
+        
+void FilterDlg::adjRunTimeSpkOutFilter(void) {
+    // signal an adjustment in running filter coeffs
+
+    if (m_running) {
+        ExchangeData(EXCHANGE_DATA_OUT, false);
+        *m_newSpkOutFilter = true;
+    }
+}
+        
+
+void FilterDlg::plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ *eqTreble, PlotSpectrum* freqRespPlot, float *magdB) {
+    char  *argBass[10];
+    char  *argTreble[10];
+    char  *argMid[10];
+    char   argstorage[10][80];
+    float magBass[F_MAG_N];
+    float magTreble[F_MAG_N];
+    float magMid[F_MAG_N];
+    int   i;
+
+    for(i=0; i<10; i++) {
+        argBass[i] = &argstorage[i][0];
+        argTreble[i] = &argstorage[i][0];
+        argMid[i] = &argstorage[i][0];
+    }
+    sprintf(argBass[0], "bass");                
+    sprintf(argBass[1], "%f", eqBass->gaindB+1E-6);
+    sprintf(argBass[2], "%f", eqBass->freqHz);      
+
+    calcFilterSpectrum(magBass, 2, argBass);
+
+    sprintf(argTreble[0], "treble");                
+    sprintf(argTreble[1], "%f", eqTreble->gaindB+1E-6);
+    sprintf(argTreble[2], "%f", eqTreble->freqHz);      
+
+    calcFilterSpectrum(magTreble, 2, argTreble);
+
+    sprintf(argTreble[0], "equalizer");                
+    sprintf(argTreble[1], "%f", eqMid->freqHz);      
+    sprintf(argTreble[2], "%f", eqMid->Q);      
+    sprintf(argTreble[3], "%f", eqMid->gaindB+1E-6);
+
+    calcFilterSpectrum(magMid, 3, argMid);
+
+    for(i=0; i<F_MAG_N; i++)
+        magdB[i] = magBass[i] + magMid[i] + magTreble[i];
+    freqRespPlot->m_newdata = true;
+    freqRespPlot->Refresh();
+}
+
+void FilterDlg::calcFilterSpectrum(float magdB[], int argc, char *argv[]) {
+    void       *sbq;
+    short       in[NIMP];
+    short       out[NIMP];
+    COMP        X[F_MAG_N];
+    float       f, w;
+    int         i, k;
+
+    // find impulse response -----------------------------------
+
+    for(i=0; i<NIMP; i++)
+        in[i] = 0;
+    in[0] = IMP_AMP;
+
+    //printf("argv[0]: %s argv[1]: %s\n", argv[0], argv[1]);
+    sbq = sox_biquad_create(argc, (const char **)argv);
+
+    sox_biquad_filter(sbq, out, in, NIMP);
+    //for(i=0; i<NIMP; i++)
+    //    printf("%d\n", out[i]);
+   
+    sox_biquad_destroy(sbq);
+
+    //for(i=0; i<NIMP; i++)
+    //    out[i] = 0.0;
+    //out[0] = IMP_AMP;
+
+    // calculate discrete time continous frequency Fourer transform
+    // doing this from first principles rather than FFT for no good reason
+
+    for(f=0,i=0; f<MAX_F_HZ; f+=F_STEP_DFT,i++) {
+        w = M_PI*f/(FS/2);
+        X[i].real = 0.0; X[i].imag = 0.0;
+        for(k=0; k<NIMP; k++) {
+            X[i].real += ((float)out[k]/IMP_AMP) * cos(w*k);
+            X[i].imag -= ((float)out[k]/IMP_AMP) * sin(w*k);
+        }
+        magdB[i] = 10.0*log10(X[i].real* X[i].real + X[i].imag*X[i].imag + 1E-12);
+        //printf("f: %f X[%d] = %f %f magdB = %f\n", f, i, X[i].real, X[i].imag,  magdB[i]);
+    }
+}
diff --git a/freedv/tags/1.2.2/src/dlg_filter.h b/freedv/tags/1.2.2/src/dlg_filter.h
new file mode 100644 (file)
index 0000000..82c43df
--- /dev/null
@@ -0,0 +1,166 @@
+//==========================================================================
+// Name:            dlg_filter.h
+// Purpose:         Dialog for controlling Codec audio filtering
+// Created:         Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __FILTER_DIALOG__
+#define __FILTER_DIALOG__
+
+#include "fdmdv2_main.h"
+
+enum {disableQ = false, enableQ = true};
+
+typedef struct { 
+    wxSlider     *sliderFreq;
+    wxStaticText *valueFreq;
+    wxSlider     *sliderGain;
+    wxStaticText *valueGain;
+    wxSlider     *sliderQ;
+    wxStaticText *valueQ;
+
+    int       sliderFreqId;
+    int       sliderGainId;
+    int       sliderQId;
+    
+    float     freqHz;
+    float     gaindB;
+    float     Q;
+
+    float     maxFreqHz;
+} EQ;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class FilterDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class FilterDlg : public wxDialog
+{
+    public:
+    FilterDlg( wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
+               wxWindowID id = wxID_ANY, const wxString& title = _("Filter"), 
+               const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 800, 630 ), 
+               long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~FilterDlg();
+
+        void    ExchangeData(int inout, bool storePersistent);
+
+    protected:
+        // Handlers for events.
+        void    OnCancel(wxCommandEvent& event);
+        void    OnOK(wxCommandEvent& event);
+        void    OnClose(wxCloseEvent& event);
+        void    OnInitDialog(wxInitDialogEvent& event);
+        void    OnLPCPostFilterDefault(wxCommandEvent& event);
+
+        void    OnBetaScroll(wxScrollEvent& event);
+        void    OnGammaScroll(wxScrollEvent& event);
+        void    OnEnable(wxScrollEvent& event);
+        void    OnBassBoost(wxScrollEvent& event);
+
+        void    OnSpeexppEnable(wxScrollEvent& event);
+
+        void    OnMicInBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInBass, true); }
+        void    OnMicInBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInBass, true); }
+        void    OnMicInTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInTreble, true); }
+        void    OnMicInTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInTreble, true); }
+        void    OnMicInMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInMid, true); }
+        void    OnMicInMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInMid, true); }
+        void    OnMicInMidQScroll(wxScrollEvent& event) { sliderToQ(&m_MicInMid, true); }
+        void    OnMicInEnable(wxScrollEvent& event);
+        void    OnMicInDefault(wxCommandEvent& event);
+
+        void    OnSpkOutBassFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutBass, false); }
+        void    OnSpkOutBassGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutBass, false); }
+        void    OnSpkOutTrebleFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutTreble, false); }
+        void    OnSpkOutTrebleGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutTreble, false); }
+        void    OnSpkOutMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutMid, false); }
+        void    OnSpkOutMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutMid, false); }
+        void    OnSpkOutMidQScroll(wxScrollEvent& event) { sliderToQ(&m_SpkOutMid, false); }
+        void    OnSpkOutEnable(wxScrollEvent& event);
+        void    OnSpkOutDefault(wxCommandEvent& event);
+
+        wxStaticText* m_staticText8;
+        wxCheckBox*   m_codec2LPCPostFilterEnable;
+        wxStaticText* m_staticText9;
+        wxCheckBox*   m_codec2LPCPostFilterBassBoost;
+        wxStaticText* m_staticText91;
+        wxSlider*     m_codec2LPCPostFilterBeta;
+        wxStaticText* m_staticTextBeta;
+        wxStaticText* m_staticText911;
+        wxSlider*     m_codec2LPCPostFilterGamma;
+        wxStaticText* m_staticTextGamma;
+        wxButton*     m_LPCPostFilterDefault;
+
+        wxCheckBox*   m_ckboxSpeexpp;
+
+        wxStdDialogButtonSizer* m_sdbSizer5;
+        wxButton*     m_sdbSizer5OK;
+        wxButton*     m_sdbSizer5Cancel;
+        PlotSpectrum* m_MicInFreqRespPlot;
+        PlotSpectrum* m_SpkOutFreqRespPlot;
+        
+        wxCheckBox*   m_MicInEnable;
+        wxButton*     m_MicInDefault;
+        wxCheckBox*   m_SpkOutEnable;
+        wxButton*     m_SpkOutDefault;
+
+        float        *m_MicInMagdB;
+        float        *m_SpkOutMagdB;
+
+     private:
+        bool          m_running;
+        float         m_beta;
+        float         m_gamma;
+
+        void          setBeta(void);  // sets slider and static text from m_beta
+        void          setGamma(void); // sets slider and static text from m_gamma
+        void          setCodec2(void);
+        void          newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName);
+        EQ            newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ);
+        void          newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *sbs, wxString controlName);
+        wxAuiNotebook *m_auiNotebook;
+        void          setFreq(EQ *eq);
+        void          setGain(EQ *eq);
+        void          setQ(EQ *eq);
+        void          sliderToFreq(EQ *eq, bool micIn);
+        void          sliderToGain(EQ *eq, bool micIn);
+        void          sliderToQ(EQ *eq, bool micIn);
+        void          plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ* eqTreble, PlotSpectrum* freqRespPlot, float *magdB);
+        void          calcFilterSpectrum(float magdB[], int arc, char *argv[]);
+        void          plotMicInFilterSpectrum(void);
+        void          plotSpkOutFilterSpectrum(void);
+        void          adjRunTimeMicInFilter(void);
+        void          adjRunTimeSpkOutFilter(void);
+
+        EQ            m_MicInBass;
+        EQ            m_MicInMid;
+        EQ            m_MicInTreble;
+
+        EQ            m_SpkOutBass;
+        EQ            m_SpkOutMid;
+        EQ            m_SpkOutTreble;
+
+        float         limit(float value, float min, float max);
+        bool          *m_newMicInFilter;
+        bool          *m_newSpkOutFilter;
+
+};
+
+#endif // __FILTER_DIALOG__
diff --git a/freedv/tags/1.2.2/src/dlg_options.cpp b/freedv/tags/1.2.2/src/dlg_options.cpp
new file mode 100644 (file)
index 0000000..79b6c87
--- /dev/null
@@ -0,0 +1,616 @@
+//==========================================================================
+// Name:            dlg_options.cpp
+// Purpose:         Dialog for controlling misc FreeDV options
+// Date:            May 24 2013
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "dlg_options.h"
+
+extern bool                g_modal;
+extern struct freedv      *g_pfreedv;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class OptionsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+OptionsDlg::OptionsDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+
+    wxBoxSizer* bSizer30;
+    bSizer30 = new wxBoxSizer(wxVERTICAL);
+
+    //------------------------------
+    // Txt Msg Text Box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_callSign;
+    wxStaticBox *sb_textMsg = new wxStaticBox(this, wxID_ANY, _("Txt Msg"));
+    sbSizer_callSign = new wxStaticBoxSizer(sb_textMsg, wxVERTICAL);
+
+    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    m_txtCtrlCallSign->SetToolTip(_("Txt Msg you can send along with Voice"));
+    sbSizer_callSign->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 3);
+
+    bSizer30->Add(sbSizer_callSign,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    //----------------------------------------------------------------------
+    // Voice Keyer 
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Voice Keyer")), wxHORIZONTAL);
+
+    wxStaticText *m_staticText28b = new wxStaticText(this, wxID_ANY, _("Wave File: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28b, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtCtrlVoiceKeyerWaveFile = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
+    m_txtCtrlVoiceKeyerWaveFile->SetToolTip(_("Wave file to play for Voice Keyer"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerWaveFile, 0, 0, 5);
+
+    m_buttonChooseVoiceKeyerWaveFile = new wxButton(this, wxID_APPLY, _("Choose"), wxDefaultPosition, wxSize(-1,-1), 0);
+    staticBoxSizer28a->Add(m_buttonChooseVoiceKeyerWaveFile, 0, wxALIGN_CENTER_VERTICAL, 5);
+
+    wxStaticText *m_staticText28c = new wxStaticText(this, wxID_ANY, _("   Rx Pause: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28c, 0, wxALIGN_CENTER_VERTICAL , 5);
+    m_txtCtrlVoiceKeyerRxPause = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRxPause->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRxPause, 0, 0, 5);
+
+    wxStaticText *m_staticText28d = new wxStaticText(this, wxID_ANY, _("   Repeats: "), wxDefaultPosition, wxDefaultSize, 0);
+    staticBoxSizer28a->Add(m_staticText28d, 0, wxALIGN_CENTER_VERTICAL, 5);
+    m_txtCtrlVoiceKeyerRepeats = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0);
+    m_txtCtrlVoiceKeyerRepeats->SetToolTip(_("How long to wait in Rx mode before repeat"));
+    staticBoxSizer28a->Add(m_txtCtrlVoiceKeyerRepeats, 0, 0, 5);
+
+    bSizer30->Add(staticBoxSizer28a,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __WXMSW__
+    //------------------------------
+    // debug console, for WIndows build make console pop up for debug messages
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_console;
+    wxStaticBox *sb_console = new wxStaticBox(this, wxID_ANY, _("Debug"));
+    sbSizer_console = new wxStaticBoxSizer(sb_console, wxHORIZONTAL);
+
+    m_ckboxDebugConsole = new wxCheckBox(this, wxID_ANY, _("Show Console"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_console->Add(m_ckboxDebugConsole, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_console,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
+
+    //------------------------------
+    // FreeDV 700 Options
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_freedv700;
+    wxStaticBox *sb_freedv700 = new wxStaticBox(this, wxID_ANY, _("FreeDV 700 Options"));
+    sbSizer_freedv700 = new wxStaticBoxSizer(sb_freedv700, wxHORIZONTAL);
+
+    m_ckboxFreeDV700txClip = new wxCheckBox(this, wxID_ANY, _("Clipping"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_freedv700->Add(m_ckboxFreeDV700txClip, 0, wxALIGN_LEFT, 0);
+    m_ckboxFreeDV700Combine = new wxCheckBox(this, wxID_ANY, _("Diversity Combine for plots"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_freedv700->Add(m_ckboxFreeDV700Combine, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_freedv700, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Half/Full duplex selection
+    //------------------------------
+
+    wxStaticBox *sb_duplex = new wxStaticBox(this, wxID_ANY, _("Half/Full Duplex Operation"));
+    wxStaticBoxSizer* sbSizer_duplex = new wxStaticBoxSizer(sb_duplex, wxHORIZONTAL);
+    m_ckHalfDuplex = new wxCheckBox(this, wxID_ANY, _("Half Duplex"), wxDefaultPosition, wxSize(-1,-1), 0);
+    sbSizer_duplex->Add(m_ckHalfDuplex, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
+    bSizer30->Add(sbSizer_duplex,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Test Frames/Channel simulation check box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_testFrames;
+    wxStaticBox *sb_testFrames = new wxStaticBox(this, wxID_ANY, _("Testing and Channel Simulation"));
+    sbSizer_testFrames = new wxStaticBoxSizer(sb_testFrames, wxHORIZONTAL);
+
+    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Test Frames"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxChannelNoise = new wxCheckBox(this, wxID_ANY, _("Channel Noise   SNR (dB):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxChannelNoise, 0, wxALIGN_LEFT, 0);
+    m_txtNoiseSNR = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtNoiseSNR, 0, wxALIGN_LEFT, 0);
+
+    m_ckboxAttnCarrierEn = new wxCheckBox(this, wxID_ANY, _("Attn Carrier  Carrier:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxAttnCarrierEn, 0, wxALIGN_LEFT, 0);
+    m_txtAttnCarrier = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(30,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_testFrames->Add(m_txtAttnCarrier, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Interfering tone
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_tone;
+    wxStaticBox *sb_tone = new wxStaticBox(this, wxID_ANY, _("Simulated Interference Tone"));
+    sbSizer_tone = new wxStaticBoxSizer(sb_tone, wxHORIZONTAL);
+
+    m_ckboxTone = new wxCheckBox(this, wxID_ANY, _("Tone   Freq (Hz):"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_tone->Add(m_ckboxTone, 0, wxALIGN_LEFT, 0);
+    m_txtToneFreqHz = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneFreqHz, 0, wxALIGN_LEFT, 0);
+    wxStaticText *m_staticTextta = new wxStaticText(this, wxID_ANY, _(" Amplitude (pk): "), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_tone->Add(m_staticTextta, 0, wxALIGN_CENTER_VERTICAL, 5);    
+    m_txtToneAmplitude = new wxTextCtrl(this, wxID_ANY,  "1000", wxDefaultPosition, wxSize(60,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_tone->Add(m_txtToneAmplitude, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_tone,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+#ifdef __EXPERIMENTAL_UDP__
+    //------------------------------
+    // Txt Encoding 
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_encoding = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Text Encoding")), wxHORIZONTAL);
+
+#ifdef SHORT_VARICODE
+    m_rb_textEncoding1 = new wxRadioButton( this, wxID_ANY, wxT("Long varicode"), wxDefaultPosition, wxDefaultSize, 0);
+    m_rb_textEncoding1->SetValue(true);
+    sbSizer_encoding->Add(m_rb_textEncoding1, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb_textEncoding2 = new wxRadioButton( this, wxID_ANY, wxT("Short Varicode"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_encoding->Add(m_rb_textEncoding2, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+
+    m_ckboxEnableChecksum = new wxCheckBox(this, wxID_ANY, _("Use Checksum on Rx"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_encoding->Add(m_ckboxEnableChecksum, 0, wxALIGN_LEFT, 0);
+
+    bSizer30->Add(sbSizer_encoding,0, wxALL|wxEXPAND, 3);
+    //------------------------------
+    // Event processing
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_events;
+    wxStaticBox *sb_events = new wxStaticBox(this, wxID_ANY, _("Event Processing"));
+    sbSizer_events = new wxStaticBoxSizer(sb_events, wxVERTICAL);
+
+    // event processing enable and spam timer
+
+    wxStaticBoxSizer* sbSizer_events_top;
+    wxStaticBox* sb_events1 = new wxStaticBox(this, wxID_ANY, _(""));    
+    sbSizer_events_top = new wxStaticBoxSizer(sb_events1, wxHORIZONTAL);
+
+    m_ckbox_events = new wxCheckBox(this, wxID_ANY, _("Enable System Calls    Syscall Spam Timer"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_events->SetToolTip(_("Enable processing of events and generation of system calls"));
+    sbSizer_events_top->Add(m_ckbox_events, 0, 0, 5);
+    m_txt_spam_timer = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(40,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    m_txt_spam_timer->SetToolTip(_("Many matching events can cause a flood of syscalls. Set minimum time (seconds) between syscalls for each event here"));
+    sbSizer_events_top->Add(m_txt_spam_timer, 0, 0, 5);
+    m_rb_spam_timer = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    m_rb_spam_timer->SetForegroundColour( wxColour(0, 255, 0 ) );
+    sbSizer_events_top->Add(m_rb_spam_timer, 0, 0, 10);
+    sbSizer_events->Add(sbSizer_events_top, 0, 0, 5);
+
+    // list of regexps
+
+    wxStaticBoxSizer* sbSizer_regexp = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Regular Expressions to Process Events")), wxHORIZONTAL);
+    m_txt_events_regexp_match = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
+    m_txt_events_regexp_match->SetToolTip(_("Enter regular expressions to match events"));
+    sbSizer_regexp->Add(m_txt_events_regexp_match, 1, wxEXPAND, 5);
+    m_txt_events_regexp_replace = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,100), wxTE_MULTILINE);
+    m_txt_events_regexp_replace->SetToolTip(_("Enter regular expressions to replace events"));
+    sbSizer_regexp->Add(m_txt_events_regexp_replace, 1, wxEXPAND, 5);
+    sbSizer_events->Add(sbSizer_regexp, 1, wxEXPAND, 5);
+
+    // log of events and responses
+
+    wxStaticBoxSizer* sbSizer_event_log = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Log of Events and Responses")), wxVERTICAL);
+    wxBoxSizer* bSizer33 = new wxBoxSizer(wxHORIZONTAL);
+    m_txt_events_in = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
+    bSizer33->Add(m_txt_events_in, 1, wxEXPAND, 5);
+    m_txt_events_out = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,50), wxTE_MULTILINE | wxTE_READONLY);
+    bSizer33->Add(m_txt_events_out, 1, wxEXPAND, 5);
+    sbSizer_event_log->Add(bSizer33, 1, wxEXPAND, 5);
+    sbSizer_events->Add(sbSizer_event_log, 1, wxEXPAND, 5);
+
+    bSizer30->Add(sbSizer_events,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // UDP control port
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_udp;
+    wxStaticBox* sb_udp = new wxStaticBox(this, wxID_ANY, _("UDP Control Port"));
+    sbSizer_udp = new wxStaticBoxSizer(sb_udp, wxHORIZONTAL);
+    m_ckbox_udp_enable = new wxCheckBox(this, wxID_ANY, _("Enable UDP Control Port    UDP Port Number:"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sb_udp->SetToolTip(_("Enable control of FreeDV via UDP port"));
+    sbSizer_udp->Add(m_ckbox_udp_enable, 0,  wxALIGN_CENTER_HORIZONTAL, 5);
+    m_txt_udp_port = new wxTextCtrl(this, wxID_ANY,  wxEmptyString, wxDefaultPosition, wxSize(50,-1), 0, wxTextValidator(wxFILTER_DIGITS));
+    sbSizer_udp->Add(m_txt_udp_port, 0, wxALIGN_CENTER_HORIZONTAL, 5);
+
+    bSizer30->Add(sbSizer_udp,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+#endif
+
+    //------------------------------
+    // OK - Cancel - Apply Buttons 
+    //------------------------------
+
+    wxBoxSizer* bSizer31 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_sdbSizer5OK = new wxButton(this, wxID_OK);
+    bSizer31->Add(m_sdbSizer5OK, 0, wxALL, 2);
+
+    m_sdbSizer5Cancel = new wxButton(this, wxID_CANCEL);
+    bSizer31->Add(m_sdbSizer5Cancel, 0, wxALL, 2);
+
+    m_sdbSizer5Apply = new wxButton(this, wxID_APPLY);
+    bSizer31->Add(m_sdbSizer5Apply, 0, wxALL, 2);
+
+    bSizer30->Add(bSizer31, 0, wxALIGN_CENTER, 0);
+
+    this->SetSizer(bSizer30);
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+     this->Layout();
+
+    this->Centre(wxBOTH);
+    // Connect Events -------------------------------------------------------
+
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
+
+    m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
+    m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
+    m_sdbSizer5Apply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
+
+    m_ckboxTestFrame->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
+    m_ckboxFreeDV700txClip->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
+
+    m_buttonChooseVoiceKeyerWaveFile->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+
+    event_in_serial = 0;
+    event_out_serial = 0;
+}
+
+//-------------------------------------------------------------------------
+// ~OptionsDlg()
+//-------------------------------------------------------------------------
+OptionsDlg::~OptionsDlg()
+{
+
+    // Disconnect Events
+
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(OptionsDlg::OnInitDialog));
+
+    m_sdbSizer5OK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnOK), NULL, this);
+    m_sdbSizer5Cancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnCancel), NULL, this);
+    m_sdbSizer5Apply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnApply), NULL, this);
+
+    m_ckboxTestFrame->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnTestFrame), NULL, this);
+    m_ckboxChannelNoise->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnChannelNoise), NULL, this);
+    m_ckboxAttnCarrierEn->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnAttnCarrierEn), NULL, this);
+
+    m_ckboxFreeDV700txClip->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700txClip), NULL, this);
+    m_ckboxFreeDV700Combine->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnFreeDV700Combine), NULL, this);
+    m_buttonChooseVoiceKeyerWaveFile->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(OptionsDlg::OnChooseVoiceKeyerWaveFile), NULL, this);
+
+#ifdef __WXMSW__
+    m_ckboxDebugConsole->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxScrollEventHandler(OptionsDlg::OnDebugConsole), NULL, this);
+#endif
+}
+
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void OptionsDlg::ExchangeData(int inout, bool storePersistent)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        m_txtCtrlCallSign->SetValue(wxGetApp().m_callSign);
+
+        /* Voice Keyer */
+
+        m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+        m_txtCtrlVoiceKeyerRxPause->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRxPause));
+        m_txtCtrlVoiceKeyerRepeats->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intVoiceKeyerRepeats));
+
+        m_ckHalfDuplex->SetValue(wxGetApp().m_boolHalfDuplex);
+
+        m_ckboxTestFrame->SetValue(wxGetApp().m_testFrames);
+
+        m_ckboxChannelNoise->SetValue(wxGetApp().m_channel_noise);
+        m_txtNoiseSNR->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_noise_snr));
+
+        m_ckboxTone->SetValue(wxGetApp().m_tone);
+        m_txtToneFreqHz->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_freq_hz));
+        m_txtToneAmplitude->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_tone_amplitude));
+
+        m_ckboxAttnCarrierEn->SetValue(wxGetApp().m_attn_carrier_en);
+        m_txtAttnCarrier->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_attn_carrier));
+
+#ifdef __EXPERIMENTAL_UDP__
+        m_ckbox_events->SetValue(wxGetApp().m_events);
+        m_txt_spam_timer->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_events_spam_timer));
+
+        m_txt_events_regexp_match->SetValue(wxGetApp().m_events_regexp_match);
+        m_txt_events_regexp_replace->SetValue(wxGetApp().m_events_regexp_replace);
+        
+        m_ckbox_udp_enable->SetValue(wxGetApp().m_udp_enable);
+        m_txt_udp_port->SetValue(wxString::Format(wxT("%i"),wxGetApp().m_udp_port));
+
+#ifdef SHORT_VARICODE
+        if (wxGetApp().m_textEncoding == 1)
+            m_rb_textEncoding1->SetValue(true);
+        if (wxGetApp().m_textEncoding == 2)
+            m_rb_textEncoding2->SetValue(true);
+#endif
+        m_ckboxEnableChecksum->SetValue(wxGetApp().m_enable_checksum);
+#endif
+
+        m_ckboxFreeDV700txClip->SetValue(wxGetApp().m_FreeDV700txClip);
+        m_ckboxFreeDV700Combine->SetValue(wxGetApp().m_FreeDV700Combine);
+
+#ifdef __WXMSW__
+        m_ckboxDebugConsole->SetValue(wxGetApp().m_debug_console);
+#endif
+    }
+
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        wxGetApp().m_callSign = m_txtCtrlCallSign->GetValue();
+
+        wxGetApp().m_boolHalfDuplex = m_ckHalfDuplex->GetValue();
+        pConfig->Write(wxT("/Rig/HalfDuplex"), wxGetApp().m_boolHalfDuplex);
+
+        /* Voice Keyer */
+
+        wxGetApp().m_txtVoiceKeyerWaveFile = m_txtCtrlVoiceKeyerWaveFile->GetValue();
+        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
+        long tmp;
+        m_txtCtrlVoiceKeyerRxPause->GetValue().ToLong(&tmp); if (tmp < 0) tmp = 0; wxGetApp().m_intVoiceKeyerRxPause = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
+        m_txtCtrlVoiceKeyerRepeats->GetValue().ToLong(&tmp);
+        if (tmp < 0) tmp = 0; if (tmp > 100) tmp = 100;
+        wxGetApp().m_intVoiceKeyerRepeats = (int)tmp;
+        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
+
+        wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
+
+        wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+        long noise_snr;
+        m_txtNoiseSNR->GetValue().ToLong(&noise_snr);
+        wxGetApp().m_noise_snr = (int)noise_snr;
+
+        wxGetApp().m_tone    = m_ckboxTone->GetValue();
+        long tone_freq_hz, tone_amplitude;
+        m_txtToneFreqHz->GetValue().ToLong(&tone_freq_hz);
+        wxGetApp().m_tone_freq_hz = (int)tone_freq_hz;
+        m_txtToneAmplitude->GetValue().ToLong(&tone_amplitude);
+        wxGetApp().m_tone_amplitude = (int)tone_amplitude;
+
+        wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();
+        long attn_carrier;
+        m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+        wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+#ifdef __EXPERIMENTAL_UDP__
+        wxGetApp().m_events        = m_ckbox_events->GetValue();
+        long spam_timer;
+        m_txt_spam_timer->GetValue().ToLong(&spam_timer);
+        wxGetApp().m_events_spam_timer = (int)spam_timer;
+
+        // make sure regexp lists are terminated by a \n
+
+        if (m_txt_events_regexp_match->GetValue().Last() != '\n') {
+            m_txt_events_regexp_match->SetValue(m_txt_events_regexp_match->GetValue()+'\n');
+        }
+        if (m_txt_events_regexp_replace->GetValue().Last() != '\n') {
+            m_txt_events_regexp_replace->SetValue(m_txt_events_regexp_replace->GetValue()+'\n');
+        }
+        wxGetApp().m_events_regexp_match = m_txt_events_regexp_match->GetValue();
+        wxGetApp().m_events_regexp_replace = m_txt_events_regexp_replace->GetValue();
+        wxGetApp().m_udp_enable     = m_ckbox_udp_enable->GetValue();
+        long port;
+        m_txt_udp_port->GetValue().ToLong(&port);
+        wxGetApp().m_udp_port       = (int)port;
+
+#ifdef SHORT_VARICODE
+        if (m_rb_textEncoding1->GetValue())
+            wxGetApp().m_textEncoding = 1;
+        if (m_rb_textEncoding2->GetValue())
+            wxGetApp().m_textEncoding = 2;
+#endif
+        wxGetApp().m_enable_checksum = m_ckboxEnableChecksum->GetValue();
+#endif
+
+        wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
+        wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+
+#ifdef __WXMSW__
+        wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#endif
+
+        if (storePersistent) {
+            pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
+#ifdef SHORT_VARICODE
+            pConfig->Write(wxT("/Data/TextEncoding"), wxGetApp().m_textEncoding);
+#endif
+            pConfig->Write(wxT("/Data/EnableChecksumOnMsgRx"), wxGetApp().m_enable_checksum);
+
+            pConfig->Write(wxT("/Events/enable"), wxGetApp().m_events);
+            pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+            pConfig->Write(wxT("/Events/regexp_match"), wxGetApp().m_events_regexp_match);
+            pConfig->Write(wxT("/Events/regexp_replace"), wxGetApp().m_events_regexp_replace);
+            
+            pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
+            pConfig->Write(wxT("/UDP/port"),  wxGetApp().m_udp_port);
+
+            pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+
+            pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
+
+            pConfig->Write(wxT("/Noise/noise_snr"),  wxGetApp().m_noise_snr);
+
+#ifdef __WXMSW__
+            pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+#endif
+
+            pConfig->Flush();
+        }
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+//-------------------------------------------------------------------------
+// OnOK()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+    //this->EndModal(wxID_OK);
+    g_modal = false;
+    this->Show(false);
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnCancel(wxCommandEvent& event)
+{
+    //this->EndModal(wxID_CANCEL);
+    g_modal = false;
+    this->Show(false);
+}
+
+//-------------------------------------------------------------------------
+// OnApply()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnApply(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT, true);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void OptionsDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_IN, false);
+}
+
+// immediately change flags rather using ExchangeData() so we can switch on and off at run time
+
+void OptionsDlg::OnTestFrame(wxScrollEvent& event) {
+    wxGetApp().m_testFrames    = m_ckboxTestFrame->GetValue();
+}
+
+void OptionsDlg::OnChannelNoise(wxScrollEvent& event) {
+    wxGetApp().m_channel_noise = m_ckboxChannelNoise->GetValue();
+}
+
+
+void OptionsDlg::OnChooseVoiceKeyerWaveFile(wxCommandEvent& event) {
+     wxFileDialog openFileDialog(
+                                 this,
+                                 wxT("Voice Keyer wave file"),
+                                 wxGetApp().m_txtVoiceKeyerWaveFilePath,
+                                 wxEmptyString,
+                                 wxT("WAV files (*.wav)|*.wav"),
+                                 wxFD_OPEN
+                                 );
+     if(openFileDialog.ShowModal() == wxID_CANCEL) {
+         return;     // the user changed their mind...
+     }
+
+     wxString fileName, extension;
+     wxGetApp().m_txtVoiceKeyerWaveFile = openFileDialog.GetPath();
+     wxFileName::SplitPath(wxGetApp().m_txtVoiceKeyerWaveFile, &wxGetApp().m_txtVoiceKeyerWaveFilePath, &fileName, &extension);
+     m_txtCtrlVoiceKeyerWaveFile->SetValue(wxGetApp().m_txtVoiceKeyerWaveFile);
+}
+
+//  Run time update of carrier amplitude attenuation
+
+void OptionsDlg::OnAttnCarrierEn(wxScrollEvent& event) {
+    long attn_carrier;
+    m_txtAttnCarrier->GetValue().ToLong(&attn_carrier);
+    wxGetApp().m_attn_carrier = (int)attn_carrier;
+
+    /* uncheck -> checked, attenuate selected carrier */
+
+    if (m_ckboxAttnCarrierEn->GetValue() && !wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 0.25);
+        } else {
+            wxMessageBox("Carrier attenuation feature only works on 700C", wxT("Warning"), wxOK | wxICON_WARNING, this);
+        }
+    }
+
+    /* checked -> unchecked, reset selected carrier */
+
+    if (!m_ckboxAttnCarrierEn->GetValue() && wxGetApp().m_attn_carrier_en) {
+        if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C) {
+            freedv_set_carrier_ampl(g_pfreedv, wxGetApp().m_attn_carrier, 1.0);
+        }
+    }
+        
+    wxGetApp().m_attn_carrier_en = m_ckboxAttnCarrierEn->GetValue();    
+}
+
+void OptionsDlg::OnFreeDV700txClip(wxScrollEvent& event) {
+    wxGetApp().m_FreeDV700txClip = m_ckboxFreeDV700txClip->GetValue();
+}
+
+void OptionsDlg::OnFreeDV700Combine(wxScrollEvent& event) {
+    wxGetApp().m_FreeDV700Combine = m_ckboxFreeDV700Combine->GetValue();
+}
+
+void OptionsDlg::updateEventLog(wxString event_in, wxString event_out) {
+    wxString event_in_with_serial, event_out_with_serial; 
+    event_in_with_serial.Printf(_T("[%d] %s"), event_in_serial++, event_in);
+    event_out_with_serial.Printf(_T("[%d] %s"), event_out_serial++, event_out);
+
+    m_txt_events_in->AppendText(event_in_with_serial+"\n");
+    m_txt_events_out->AppendText(event_out_with_serial+"\n");
+}
+
+
+void OptionsDlg::OnDebugConsole(wxScrollEvent& event) {
+    wxGetApp().m_debug_console = m_ckboxDebugConsole->GetValue();
+#ifdef __WXMSW__
+    // somewhere to send printfs while developing, causes conmsole to pop up on Windows
+    if (wxGetApp().m_debug_console) {
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    } 
+#endif
+}
diff --git a/freedv/tags/1.2.2/src/dlg_options.h b/freedv/tags/1.2.2/src/dlg_options.h
new file mode 100644 (file)
index 0000000..081448c
--- /dev/null
@@ -0,0 +1,137 @@
+//==========================================================================
+// Name:            dlg_options.h
+// Purpose:         Dialog for controlling misc FreeDV options
+// Created:         Nov 25 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __OPTIONS_DIALOG__
+#define __OPTIONS_DIALOG__
+
+#include "fdmdv2_main.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class OptionsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class OptionsDlg : public wxDialog
+{
+    public:
+    OptionsDlg( wxWindow* parent,
+               wxWindowID id = wxID_ANY, const wxString& title = _("Options"), 
+                const wxPoint& pos = wxDefaultPosition, 
+#ifdef __WXMSW__
+                /* we add debug console check box for windows */
+                const wxSize& size = wxSize(600,410), 
+#else
+                const wxSize& size = wxSize(600,380), 
+#endif
+               long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+        ~OptionsDlg();
+
+        void    ExchangeData(int inout, bool storePersistent);
+        void    updateEventLog(wxString event_in, wxString event_out);
+
+        bool    enableEventsChecked() {return m_ckbox_events->GetValue();}
+
+        void SetSpamTimerLight(bool state) {
+
+            // Colours don't work on Windows
+
+            if (state) {
+                m_rb_spam_timer->SetForegroundColour( wxColour( 255,0 , 0 ) ); // red
+                m_rb_spam_timer->SetValue(true);
+            }
+            else {
+                m_rb_spam_timer->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
+                m_rb_spam_timer->SetValue(false);
+            }
+        }
+
+
+    protected:
+
+        // Handlers for events.
+
+        void    OnOK(wxCommandEvent& event);
+        void    OnCancel(wxCommandEvent& event);
+        void    OnApply(wxCommandEvent& event);
+        void    OnClose(wxCloseEvent& event);
+        void    OnInitDialog(wxInitDialogEvent& event);
+        void    OnTestFrame(wxScrollEvent& event);
+        void    OnChannelNoise(wxScrollEvent& event);
+        void    OnAttnCarrierEn(wxScrollEvent& event);
+        void    OnFreeDV700txClip(wxScrollEvent& event);
+        void    OnFreeDV700Combine(wxScrollEvent& event);
+        void    OnDebugConsole(wxScrollEvent& event);
+
+        wxTextCtrl   *m_txtCtrlCallSign; // TODO: this should be renamed to tx_txtmsg, and rename all related incl persis strge
+
+        wxCheckBox* m_ckHalfDuplex;
+
+        /* Voice Keyer */
+
+        wxButton     *m_buttonChooseVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerWaveFile;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRxPause;
+        wxTextCtrl   *m_txtCtrlVoiceKeyerRepeats;
+
+        /* test frames, other simulated channel impairments */
+
+        wxCheckBox   *m_ckboxTestFrame;
+        wxCheckBox   *m_ckboxChannelNoise;
+        wxTextCtrl   *m_txtNoiseSNR;
+        wxCheckBox   *m_ckboxAttnCarrierEn;
+        wxTextCtrl   *m_txtAttnCarrier;
+
+        wxCheckBox   *m_ckboxTone;
+        wxTextCtrl   *m_txtToneFreqHz;
+        wxTextCtrl   *m_txtToneAmplitude;
+
+        wxCheckBox   *m_ckboxFreeDV700txClip;
+        wxCheckBox   *m_ckboxFreeDV700Combine;
+
+        wxRadioButton *m_rb_textEncoding1;
+        wxRadioButton *m_rb_textEncoding2;
+        wxCheckBox    *m_ckboxEnableChecksum;
+
+        wxCheckBox   *m_ckbox_events;
+        wxTextCtrl   *m_txt_events_regexp_match;
+        wxTextCtrl   *m_txt_events_regexp_replace;
+        wxTextCtrl   *m_txt_events_in;
+        wxTextCtrl   *m_txt_events_out;
+        wxTextCtrl   *m_txt_spam_timer;
+        wxRadioButton *m_rb_spam_timer;
+
+        wxCheckBox   *m_ckbox_udp_enable;
+        wxTextCtrl   *m_txt_udp_port;
+
+        wxButton*     m_sdbSizer5OK;
+        wxButton*     m_sdbSizer5Cancel;
+        wxButton*     m_sdbSizer5Apply;
+
+        wxCheckBox   *m_ckboxDebugConsole;
+
+        unsigned int  event_in_serial, event_out_serial;
+
+        void OnChooseVoiceKeyerWaveFile(wxCommandEvent& event);
+
+     private:
+};
+
+#endif // __OPTIONS_DIALOG__
diff --git a/freedv/tags/1.2.2/src/dlg_plugin.cpp b/freedv/tags/1.2.2/src/dlg_plugin.cpp
new file mode 100644 (file)
index 0000000..68610f4
--- /dev/null
@@ -0,0 +1,148 @@
+//==========================================================================
+// Name:            dlg_plugin.cpp
+// Purpose:         Subclasses dialog GUI for PlugIn Config. Creates simple 
+//                  wxWidgets dialog GUI to set a few text strings.
+// Date:            Jan 2016
+// Authors:         David Rowe
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "dlg_plugin.h"
+#include "fdmdv2_main.h"
+
+#ifdef __WIN32__
+#include <wx/msw/registry.h>
+#endif
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+#include <glob.h>
+#include <string.h>
+#endif
+
+#include <sstream>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlugInDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlugInDlg::PlugInDlg(const wxString& title, int numParam, wxString paramName[], wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    m_name = title;
+    m_numParam = numParam;
+    assert(m_numParam <= PLUGIN_MAX_PARAMS);
+
+    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
+    this->SetSizer(mainSizer);
+
+    int i;
+    for (i=0; i<m_numParam; i++) {
+        m_paramName[i] = paramName[i];
+        wxStaticBoxSizer* staticBoxSizer28a = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, m_paramName[i]), wxVERTICAL);
+        m_txtCtrlParam[i]= new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(300,-1), 0);
+        staticBoxSizer28a->Add(m_txtCtrlParam[i], 0, 0, 5);
+        mainSizer->Add(staticBoxSizer28a, 0, wxEXPAND, 5);
+    }
+
+    //----------------------------------------------------------------------
+    // OK - Cancel - Apply
+    //----------------------------------------------------------------------
+
+    wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_buttonOK->SetDefault();
+    boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonCancel, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    mainSizer->Add(boxSizer12, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 5);
+
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+    Centre(wxBOTH);
+
+    // Connect events
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(PlugInDlg::OnInitDialog), NULL, this);
+    m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnOK), NULL, this);
+    m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnCancel), NULL, this);
+
+}
+
+//-------------------------------------------------------------------------
+// ~PlugInDlg()
+//-------------------------------------------------------------------------
+PlugInDlg::~PlugInDlg()
+{
+    // Disconnect Events
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(PlugInDlg::OnInitDialog), NULL, this);
+    m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnOK), NULL, this);
+    m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PlugInDlg::OnCancel), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void PlugInDlg::ExchangeData(int inout)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    wxString str;
+    int i;
+    
+    if(inout == EXCHANGE_DATA_IN)
+    {
+        for (i=0; i<m_numParam; i++) {
+            m_txtCtrlParam[i]->SetValue(wxGetApp().m_txtPlugInParam[i]);
+        }
+    }
+    if(inout == EXCHANGE_DATA_OUT)
+    {
+        for (i=0; i<m_numParam; i++) {
+          wxGetApp().m_txtPlugInParam[i] = m_txtCtrlParam[i]->GetValue();
+          wxString configStr = "/" + m_name + "/" + m_paramName[i];
+          pConfig->Write(configStr, wxGetApp().m_txtPlugInParam[i]);
+        }
+        pConfig->Flush();
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void PlugInDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    this->EndModal(wxID_OK);
+}
diff --git a/freedv/tags/1.2.2/src/dlg_plugin.h b/freedv/tags/1.2.2/src/dlg_plugin.h
new file mode 100644 (file)
index 0000000..72efc7b
--- /dev/null
@@ -0,0 +1,65 @@
+//==========================================================================
+// Name:            dlg_ptt.h
+// Purpose:         Subclasses dialog GUI for PTT Config.
+//                  
+// Created:         May. 11, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __PLUGIN_DIALOG__
+#define __PLUGIN_DIALOG__
+
+#include "fdmdv2_main.h"
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/xrc/xh_bmp.h>
+#include <wx/dialog.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/listbox.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/spinctrl.h>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlugInDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlugInDlg : public wxDialog
+{
+    public:
+    PlugInDlg(const wxString& title = _("PTT Config"), int numParam = 0, wxString paramNames[]=NULL, wxWindow* parent=NULL, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(450,300), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
+        virtual ~PlugInDlg();
+        void    ExchangeData(int inout);
+
+    protected:
+        wxString    m_name;
+        int         m_numParam;
+        wxString    m_paramName[PLUGIN_MAX_PARAMS];
+
+        wxTextCtrl* m_txtCtrlParam[PLUGIN_MAX_PARAMS];
+        wxButton*   m_buttonOK;
+        wxButton*   m_buttonCancel;
+
+
+protected:
+
+        void OnOK(wxCommandEvent& event);
+        void OnCancel(wxCommandEvent& event);
+        virtual void OnInitDialog(wxInitDialogEvent& event);
+};
+
+#endif // __PLUGIN_DIALOG__
diff --git a/freedv/tags/1.2.2/src/dlg_ptt.cpp b/freedv/tags/1.2.2/src/dlg_ptt.cpp
new file mode 100644 (file)
index 0000000..1a04c9c
--- /dev/null
@@ -0,0 +1,570 @@
+//==========================================================================
+// Name:            dlg_ptt.cpp
+// Purpose:         Subclasses dialog GUI for PTT Config. Creates simple 
+//                  wxWidgets dialog GUI to select real/virtual Comm ports.
+// Date:            May 11 2012
+// Authors:         David Rowe, David Witten, Joel Stanley
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "dlg_ptt.h"
+#include "fdmdv2_main.h"
+
+#ifdef __WIN32__
+#include <wx/msw/registry.h>
+#endif
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+#include <glob.h>
+#include <string.h>
+#endif
+
+#include <sstream>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class ComPortsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+ComPortsDlg::ComPortsDlg(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+{
+    wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);
+    this->SetSizer(mainSizer);
+    
+    //----------------------------------------------------------------------
+    // Vox tone option
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer28 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("VOX PTT Settings")), wxHORIZONTAL);
+    m_ckLeftChannelVoxTone = new wxCheckBox(this, wxID_ANY, _("Left Channel Vox Tone"), wxDefaultPosition, wxSize(-1,-1), 0);
+    staticBoxSizer28->Add(m_ckLeftChannelVoxTone, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL, 5);
+
+    mainSizer->Add(staticBoxSizer28, 0, wxEXPAND, 5);
+
+    //----------------------------------------------------------------------
+    // Hamlib for CAT PTT
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer18 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Hamlib Settings")), wxHORIZONTAL);
+    wxGridSizer* gridSizerhl = new wxGridSizer(5, 2, 0, 0);
+    staticBoxSizer18->Add(gridSizerhl, 1, wxEXPAND|wxALIGN_LEFT, 5);
+
+    /* Use Hamlib for PTT checkbox. */
+
+    m_ckUseHamlibPTT = new wxCheckBox(this, wxID_ANY, _("Use Hamlib PTT"), wxDefaultPosition, wxSize(-1, -1), 0);
+    m_ckUseHamlibPTT->SetValue(false);
+    gridSizerhl->Add(m_ckUseHamlibPTT, 0, wxALIGN_CENTER_VERTICAL, 0);
+    gridSizerhl->Add(new wxStaticText(this, -1, wxT("")), 0, wxEXPAND);
+
+    /* Hamlib Rig Type combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Rig Model:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbRigName = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(250, -1), 0, NULL, wxCB_DROPDOWN);
+    wxGetApp().m_hamlib->populateComboBox(m_cbRigName);
+    m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
+    gridSizerhl->Add(m_cbRigName, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    /* Hamlib Serial Port combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Device:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL |  wxALIGN_RIGHT, 20);
+    m_cbSerialPort = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizerhl->Add(m_cbSerialPort, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    /* Hamlib Serial Rate combobox. */
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Rate:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialRate = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizerhl->Add(m_cbSerialRate, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    gridSizerhl->Add(new wxStaticText(this, wxID_ANY, _("Serial Params:"), wxDefaultPosition, wxDefaultSize, 0), 
+                      0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT, 20);
+    m_cbSerialParams = new wxStaticText(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, 0);
+    gridSizerhl->Add(m_cbSerialParams, 0, wxALIGN_CENTER_VERTICAL, 0);
+
+    mainSizer->Add(staticBoxSizer18, 0, wxEXPAND, 5);
+
+    //----------------------------------------------------------------------
+    // Serial port PTT
+    //----------------------------------------------------------------------
+
+    wxStaticBoxSizer* staticBoxSizer17 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Serial Port Settings")), wxVERTICAL);
+    mainSizer->Add(staticBoxSizer17, 1, wxEXPAND, 5);
+    wxStaticBoxSizer* staticBoxSizer31 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("PTT Port")), wxVERTICAL);
+    staticBoxSizer17->Add(staticBoxSizer31, 1, wxEXPAND, 5);
+
+#ifdef __WXMSW__
+    m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckUseSerialPTT->SetValue(false);
+    staticBoxSizer31->Add(m_ckUseSerialPTT, 0, wxALIGN_LEFT, 20);
+
+    wxArrayString m_listCtrlPortsArr;
+    m_listCtrlPorts = new wxListBox(this, wxID_ANY, wxDefaultPosition, wxSize(-1,45), m_listCtrlPortsArr, wxLB_SINGLE | wxLB_SORT);
+    staticBoxSizer31->Add(m_listCtrlPorts, 1, wxALIGN_CENTER, 0);
+#endif
+
+#if defined(__WXOSX__) || defined(__WXGTK__)
+    wxBoxSizer* bSizer83;
+    bSizer83 = new wxBoxSizer(wxHORIZONTAL);
+
+    wxGridSizer* gridSizer200 = new wxGridSizer(1, 3, 0, 0);
+    
+    m_ckUseSerialPTT = new wxCheckBox(this, wxID_ANY, _("Use Serial Port PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckUseSerialPTT->SetValue(false);
+    gridSizer200->Add(m_ckUseSerialPTT, 1, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
+
+    m_staticText12 = new wxStaticText(this, wxID_ANY, _("Serial Device:  "), wxDefaultPosition, wxDefaultSize, 0);
+    m_staticText12->Wrap(-1);
+    gridSizer200->Add(m_staticText12, 1,wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 2);
+
+    m_cbCtlDevicePath = new wxComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(140, -1), 0, NULL, wxCB_DROPDOWN);
+    gridSizer200->Add(m_cbCtlDevicePath, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 2);
+    
+    bSizer83->Add(gridSizer200, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT | wxALL, 2);
+    staticBoxSizer31->Add(bSizer83, 1, wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    wxBoxSizer* boxSizer19 = new wxBoxSizer(wxVERTICAL);
+    staticBoxSizer17->Add(boxSizer19, 1, wxEXPAND, 5);
+    wxStaticBoxSizer* staticBoxSizer16 = new wxStaticBoxSizer( new wxStaticBox(this, wxID_ANY, _("Signal polarity")), wxHORIZONTAL);
+    boxSizer19->Add(staticBoxSizer16, 1, wxEXPAND|wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    wxGridSizer* gridSizer17 = new wxGridSizer(2, 2, 0, 0);
+    staticBoxSizer16->Add(gridSizer17, 1, wxEXPAND|wxALIGN_RIGHT, 5);
+
+    m_rbUseDTR = new wxRadioButton(this, wxID_ANY, _("Use DTR"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_rbUseDTR->SetToolTip(_("Toggle DTR line for PTT"));
+    m_rbUseDTR->SetValue(1);
+    gridSizer17->Add(m_rbUseDTR, 0, wxALIGN_CENTER|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 5);
+
+    m_ckDTRPos = new wxCheckBox(this, wxID_ANY, _("DTR = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckDTRPos->SetToolTip(_("Set Polarity of the DTR line"));
+    m_ckDTRPos->SetValue(false);
+    gridSizer17->Add(m_ckDTRPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    m_rbUseRTS = new wxRadioButton(this, wxID_ANY, _("Use RTS"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_rbUseRTS->SetToolTip(_("Toggle the RTS pin for PTT"));
+    m_rbUseRTS->SetValue(1);
+    gridSizer17->Add(m_rbUseRTS, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    m_ckRTSPos = new wxCheckBox(this, wxID_ANY, _("RTS = +V"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_ckRTSPos->SetValue(false);
+    m_ckRTSPos->SetToolTip(_("Set Polarity of the RTS line"));
+    gridSizer17->Add(m_ckRTSPos, 0, wxALIGN_CENTER|wxALIGN_RIGHT, 5);
+
+    //----------------------------------------------------------------------
+    // OK - Cancel - Apply
+    //----------------------------------------------------------------------
+
+    wxBoxSizer* boxSizer12 = new wxBoxSizer(wxHORIZONTAL);
+
+    m_buttonTest = new wxButton(this, wxID_APPLY, _("Test PTT"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonTest, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonOK = new wxButton(this, wxID_OK, _("OK"), wxDefaultPosition, wxSize(-1,-1), 0);
+    m_buttonOK->SetDefault();
+    boxSizer12->Add(m_buttonOK, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonCancel = new wxButton(this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonCancel, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    m_buttonApply = new wxButton(this, wxID_APPLY, _("Apply"), wxDefaultPosition, wxSize(-1,-1), 0);
+    boxSizer12->Add(m_buttonApply, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM, 5);
+
+    mainSizer->Add(boxSizer12, 0, wxLEFT|wxRIGHT|wxTOP|wxBOTTOM|wxALIGN_CENTER_HORIZONTAL, 5);
+
+    if ( GetSizer() ) 
+    {
+         GetSizer()->Fit(this);
+    }
+    Centre(wxBOTH);
+
+    // Connect events
+    this->Connect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
+    m_ckUseHamlibPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
+    m_ckUseSerialPTT->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
+    m_buttonOK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
+    m_buttonCancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
+    m_buttonApply->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// ~ComPortsDlg()
+//-------------------------------------------------------------------------
+ComPortsDlg::~ComPortsDlg()
+{
+    // Disconnect Events
+    this->Disconnect(wxEVT_INIT_DIALOG, wxInitDialogEventHandler(ComPortsDlg::OnInitDialog), NULL, this);
+    m_ckUseHamlibPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseHamLibClicked), NULL, this);
+    m_ckUseSerialPTT->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(ComPortsDlg::PTTUseSerialClicked), NULL, this);
+    m_buttonOK->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnOK), NULL, this);
+    m_buttonCancel->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnCancel), NULL, this);
+    m_buttonApply->Disconnect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnApply), NULL, this);
+    m_buttonTest->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(ComPortsDlg::OnTest), NULL, this);
+}
+
+//-------------------------------------------------------------------------
+// OnInitDialog()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnInitDialog(wxInitDialogEvent& event)
+{
+    populatePortList();
+    ExchangeData(EXCHANGE_DATA_IN);
+}
+
+//-------------------------------------------------------------------------
+// populatePortList()
+//-------------------------------------------------------------------------
+void ComPortsDlg::populatePortList()
+{
+
+    /* populate Hamlib serial rate combo box */
+
+    wxString serialRates[] = {"default", "300", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200"}; 
+    for(int i=0; i<WXSIZEOF(serialRates); i++) {
+        m_cbSerialRate->Append(serialRates[i]);
+    }
+
+#ifdef __WXMSW__
+    m_listCtrlPorts->Clear();
+    m_cbSerialPort->Clear();
+    wxArrayString aStr;
+    wxRegKey key(wxRegKey::HKLM, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"));
+    if(!key.Exists())
+    {
+        return;
+    }
+    else
+    {
+        // Get the number of subkeys and enumerate them.
+        if(!key.Open(wxRegKey::Read))
+        {
+            return;
+        }    
+        size_t subkeys;
+        size_t values;
+        if(!key.GetKeyInfo(&subkeys, NULL, &values, NULL))
+        {
+            return;
+        }
+        if(!key.HasValues())
+        {
+            return;
+        }
+        wxString key_name;
+        long el = 1;
+        key.GetFirstValue(key_name, el);
+        wxString valType;
+        wxString key_data;
+        for(unsigned int i = 0; i < values; i++)
+        {
+            key.QueryValue(key_name, key_data);
+            //wxPrintf("Value:  %s Data: %s\n", key_name, key_data);
+            aStr.Add(key_data, 1);
+            key.GetNextValue(key_name, el);
+        }
+    }
+    m_listCtrlPorts->Append(aStr);
+    m_cbSerialPort->Append(aStr);
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+    m_cbSerialPort->Clear();
+    m_cbCtlDevicePath->Clear();
+#if defined(__FreeBSD__) || defined(__WXOSX__)
+       glob_t  gl;
+#ifdef __FreeBSD__
+       if(glob("/dev/tty*", GLOB_MARK, NULL, &gl)==0) {
+#else
+       if(glob("/dev/tty.*", GLOB_MARK, NULL, &gl)==0) {
+#endif
+               for(unsigned int i=0; i<gl.gl_pathc; i++) {
+                       if(gl.gl_pathv[i][strlen(gl.gl_pathv[i])-1]=='/')
+                               continue;
+                               
+                       /* Exclude pseudo TTYs */
+                       if(gl.gl_pathv[i][8] >= 'l' && gl.gl_pathv[i][8] <= 's')
+                               continue;
+                       if(gl.gl_pathv[i][8] >= 'L' && gl.gl_pathv[i][8] <= 'S')
+                               continue;
+
+                       /* Exclude virtual TTYs */
+                       if(gl.gl_pathv[i][8] == 'v')
+                               continue;
+
+                       /* Exclude initial-state and lock-state devices */
+#ifndef __WXOSX__
+                       if(strchr(gl.gl_pathv[i], '.') != NULL)
+                               continue;
+#endif
+
+                       m_cbSerialPort->Append(gl.gl_pathv[i]);
+                       m_cbCtlDevicePath->Append(gl.gl_pathv[i]);
+               }
+               globfree(&gl);
+       }
+#else
+    /* TODO(Joel): http://stackoverflow.com/questions/2530096/how-to-find-all-serial-devices-ttys-ttyusb-on-linux-without-opening-them */
+    m_cbSerialPort->Append("/dev/ttyUSB0");
+    m_cbSerialPort->Append("/dev/ttyUSB1");
+    m_cbSerialPort->Append("/dev/ttyS0");
+    m_cbSerialPort->Append("/dev/ttyS1");
+
+    m_cbCtlDevicePath->Clear();
+    m_cbCtlDevicePath->Append("/dev/ttyUSB0");
+    m_cbCtlDevicePath->Append("/dev/ttyUSB1");
+    m_cbCtlDevicePath->Append("/dev/ttyS0");
+    m_cbCtlDevicePath->Append("/dev/ttyS1");
+#endif
+#endif
+
+
+}
+
+//-------------------------------------------------------------------------
+// ExchangeData()
+//-------------------------------------------------------------------------
+void ComPortsDlg::ExchangeData(int inout)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    wxString str;
+    
+    if(inout == EXCHANGE_DATA_IN) {
+        m_ckLeftChannelVoxTone->SetValue(wxGetApp().m_leftChannelVoxTone);
+
+        /* Hamlib */
+
+        m_ckUseHamlibPTT->SetValue(wxGetApp().m_boolHamlibUseForPTT);
+        m_cbRigName->SetSelection(wxGetApp().m_intHamlibRig);
+        m_cbSerialPort->SetValue(wxGetApp().m_strHamlibSerialPort);
+
+        if (wxGetApp().m_intHamlibSerialRate == 0) {
+            m_cbSerialRate->SetSelection(0);
+        } else {
+            m_cbSerialRate->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_intHamlibSerialRate));
+        }
+
+        /* Serial PTT */
+
+        m_ckUseSerialPTT->SetValue(wxGetApp().m_boolUseSerialPTT);
+        str = wxGetApp().m_strRigCtrlPort;
+#ifdef __WXMSW__
+        m_listCtrlPorts->SetStringSelection(str);
+#endif
+#if defined(__WXOSX__) || defined(__WXGTK__)
+        m_cbCtlDevicePath->SetValue(str);
+#endif
+        m_rbUseRTS->SetValue(wxGetApp().m_boolUseRTS);
+        m_ckRTSPos->SetValue(wxGetApp().m_boolRTSPos);
+        m_rbUseDTR->SetValue(wxGetApp().m_boolUseDTR);
+        m_ckDTRPos->SetValue(wxGetApp().m_boolDTRPos);
+    }
+
+    if (inout == EXCHANGE_DATA_OUT) {
+        wxGetApp().m_leftChannelVoxTone = m_ckLeftChannelVoxTone->GetValue();
+        pConfig->Write(wxT("/Rig/leftChannelVoxTone"), wxGetApp().m_leftChannelVoxTone);
+
+        /* Hamlib settings. */
+
+        wxGetApp().m_boolHamlibUseForPTT = m_ckUseHamlibPTT->GetValue();
+        wxGetApp().m_intHamlibRig = m_cbRigName->GetSelection();
+        wxGetApp().m_strHamlibSerialPort = m_cbSerialPort->GetValue();
+
+        wxString s = m_cbSerialRate->GetValue();
+        if (s == "default") {
+            wxGetApp().m_intHamlibSerialRate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            wxGetApp().m_intHamlibSerialRate = tmp;
+        }
+        fprintf(stderr, "serial rate: %d\n", wxGetApp().m_intHamlibSerialRate);
+
+        pConfig->Write(wxT("/Hamlib/UseForPTT"), wxGetApp().m_boolHamlibUseForPTT);
+        pConfig->Write(wxT("/Hamlib/RigName"), wxGetApp().m_intHamlibRig);
+        pConfig->Write(wxT("/Hamlib/SerialPort"), wxGetApp().m_strHamlibSerialPort);
+        pConfig->Write(wxT("/Hamlib/SerialRate"), wxGetApp().m_intHamlibSerialRate);
+
+        /* Serial settings */
+
+        wxGetApp().m_boolUseSerialPTT           = m_ckUseSerialPTT->IsChecked();
+#ifdef __WXMSW__
+        wxGetApp().m_strRigCtrlPort             = m_listCtrlPorts->GetStringSelection();
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+        wxGetApp().m_strRigCtrlPort             = m_cbCtlDevicePath->GetValue();
+#endif
+        wxGetApp().m_boolUseRTS                 = m_rbUseRTS->GetValue();
+        wxGetApp().m_boolRTSPos                 = m_ckRTSPos->IsChecked();
+        wxGetApp().m_boolUseDTR                 = m_rbUseDTR->GetValue();
+        wxGetApp().m_boolDTRPos                 = m_ckDTRPos->IsChecked();
+        
+        pConfig->Write(wxT("/Rig/UseSerialPTT"),    wxGetApp().m_boolUseSerialPTT);
+        pConfig->Write(wxT("/Rig/Port"),            wxGetApp().m_strRigCtrlPort); 
+        pConfig->Write(wxT("/Rig/UseRTS"),          wxGetApp().m_boolUseRTS);
+        pConfig->Write(wxT("/Rig/RTSPolarity"),     wxGetApp().m_boolRTSPos);
+        pConfig->Write(wxT("/Rig/UseDTR"),          wxGetApp().m_boolUseDTR);
+        pConfig->Write(wxT("/Rig/DTRPolarity"),     wxGetApp().m_boolDTRPos);
+
+        pConfig->Flush();
+    }
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+//-------------------------------------------------------------------------
+// PTTUseHamLibClicked()
+//-------------------------------------------------------------------------
+void ComPortsDlg::PTTUseHamLibClicked(wxCommandEvent& event)
+{
+    m_ckUseSerialPTT->SetValue(false);
+}
+
+
+/* Attempt to toggle PTT for 1 second */
+
+void ComPortsDlg::OnTest(wxCommandEvent& event) {
+
+    /* Tone PTT */
+
+    if (m_ckLeftChannelVoxTone->GetValue()) {
+        wxMessageBox("Testing of tone based PTT not supported; try PTT after pressing Start on main window", 
+                     wxT("Error"), wxOK | wxICON_ERROR, this);
+    }
+
+    /* Hamlib PTT */
+
+    if (m_ckUseHamlibPTT->GetValue()) {
+
+        // set up current hamlib config from GUI
+
+        int rig = m_cbRigName->GetSelection();
+        wxString port = m_cbSerialPort->GetValue();
+        wxString s = m_cbSerialRate->GetValue();
+        int serial_rate;
+        if (s == "default") {
+            serial_rate = 0;
+        } else {
+            long tmp;
+            m_cbSerialRate->GetValue().ToLong(&tmp); 
+            serial_rate = tmp;
+        }
+
+        // display serial params
+
+        fprintf(stderr, "serial rate: %d\n", serial_rate);
+
+        // try to open rig
+
+        Hamlib *hamlib = wxGetApp().m_hamlib; 
+        bool status = hamlib->connect(rig, port.mb_str(wxConvUTF8), serial_rate);
+        if (status == false) {
+            wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+        else {
+            wxString hamlib_serial_config;
+            hamlib_serial_config.sprintf(" %d, %d, %d", 
+                                         hamlib->get_serial_rate(),
+                                         hamlib->get_data_bits(),
+                                         hamlib->get_stop_bits());
+            m_cbSerialParams->SetLabel(hamlib_serial_config);
+       }
+
+        // toggle PTT
+
+        wxString hamlibError;
+        if (hamlib->ptt(true, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            return;
+        }
+
+        wxSleep(1);
+
+        if (hamlib->ptt(false, hamlibError) == false) {
+            wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+    }
+
+    /* Serial PTT */
+
+    if (m_ckUseSerialPTT->IsChecked()) {
+        Serialport *serialport = wxGetApp().m_serialport; 
+        
+        wxString ctrlport;
+#ifdef __WXMSW__
+        ctrlport = m_listCtrlPorts->GetStringSelection();
+#endif
+#if defined(__WXGTK__) || defined(__WXOSX__)
+        ctrlport = m_cbCtlDevicePath->GetValue();
+#endif
+        fprintf(stderr, "opening serial port\n");
+
+        bool success = serialport->openport(ctrlport.c_str(),
+                                            m_rbUseRTS->GetValue(),
+                                            m_ckRTSPos->IsChecked(),
+                                            m_rbUseDTR->GetValue(),
+                                            m_ckDTRPos->IsChecked());
+
+        fprintf(stderr, "serial port open\n");
+
+        if (!success) {
+            wxMessageBox("Couldn't open serial port", wxT("Error"), wxOK | wxICON_ERROR, this);
+        }
+
+        // assert PTT port for 1 sec
+
+        serialport->ptt(true);
+        wxSleep(1);
+        serialport->ptt(false);
+
+        fprintf(stderr, "closing serial port\n");
+        serialport->closeport();
+        fprintf(stderr, "serial port closed\n");
+    }
+    
+}
+
+
+//-------------------------------------------------------------------------
+// PTTUseSerialClicked()
+//-------------------------------------------------------------------------
+void ComPortsDlg::PTTUseSerialClicked(wxCommandEvent& event)
+{
+    m_ckUseHamlibPTT->SetValue(false);
+}
+
+//-------------------------------------------------------------------------
+// OnApply()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnApply(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+}
+
+//-------------------------------------------------------------------------
+// OnCancel()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnCancel(wxCommandEvent& event)
+{
+    this->EndModal(wxID_CANCEL);
+}
+
+//-------------------------------------------------------------------------
+// OnClose()
+//-------------------------------------------------------------------------
+void ComPortsDlg::OnOK(wxCommandEvent& event)
+{
+    ExchangeData(EXCHANGE_DATA_OUT);
+    this->EndModal(wxID_OK);
+}
diff --git a/freedv/tags/1.2.2/src/dlg_ptt.h b/freedv/tags/1.2.2/src/dlg_ptt.h
new file mode 100644 (file)
index 0000000..26ab17e
--- /dev/null
@@ -0,0 +1,93 @@
+//==========================================================================
+// Name:            dlg_ptt.h
+// Purpose:         Subclasses dialog GUI for PTT Config.
+//                  
+// Created:         May. 11, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __COMPORTS_DIALOG__
+#define __COMPORTS_DIALOG__
+
+#include "fdmdv2_main.h"
+#include "hamlib.h"
+#include <wx/settings.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/xrc/xh_bmp.h>
+#include <wx/dialog.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/checkbox.h>
+#include <wx/listbox.h>
+#include <wx/radiobut.h>
+#include <wx/button.h>
+#include <wx/spinctrl.h>
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class ComPortsDlg
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class ComPortsDlg : public wxDialog
+{
+     public:
+        ComPortsDlg(wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("PTT Config"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(450,300), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
+        virtual ~ComPortsDlg();
+        void    ExchangeData(int inout);
+
+    protected:
+        wxCheckBox* m_ckLeftChannelVoxTone;
+
+        /* Hamlib settings.*/
+
+        wxCheckBox *m_ckUseHamlibPTT;
+        wxComboBox *m_cbRigName;
+        wxComboBox *m_cbSerialPort;
+        wxStaticText  *m_cbSerialParams;
+        Hamlib *m_hamlib;
+
+        /* Serial Settings */
+
+        wxListBox     *m_listCtrlPorts;
+        wxCheckBox    *m_ckUseSerialPTT;
+        wxStaticText  *m_staticText12;
+        wxComboBox    *m_cbCtlDevicePath;
+        wxRadioButton *m_rbUseDTR;
+        wxCheckBox    *m_ckRTSPos;
+        wxRadioButton *m_rbUseRTS;
+        wxCheckBox    *m_ckDTRPos;
+
+        /* Test - Ok - Cancel - Apply */
+
+        wxButton* m_buttonTest;
+        wxButton* m_buttonOK;
+        wxButton* m_buttonCancel;
+        wxButton* m_buttonApply;
+
+
+protected:
+        void populatePortList();
+
+        void PTTUseHamLibClicked(wxCommandEvent& event);
+        void PTTUseSerialClicked(wxCommandEvent& event);
+
+        void OnTest(wxCommandEvent& event);
+
+        void OnOK(wxCommandEvent& event);
+        void OnCancel(wxCommandEvent& event);
+        void OnApply(wxCommandEvent& event);
+        virtual void OnInitDialog(wxInitDialogEvent& event);
+};
+
+#endif // __COMPORTS_DIALOG__
diff --git a/freedv/tags/1.2.2/src/fdmdv2_defines.h b/freedv/tags/1.2.2/src/fdmdv2_defines.h
new file mode 100644 (file)
index 0000000..a687889
--- /dev/null
@@ -0,0 +1,106 @@
+//==========================================================================
+// Name:            fdmdv2_defines.h
+// Purpose:         Definitions used by plots derived from fdmdv2_plot class.
+// Created:         August 27, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_DEFINES__
+#define __FDMDV2_DEFINES__
+
+#include "wx/wx.h"
+#include "freedv_api.h"
+#include "modem_stats.h"
+
+// Spectrogram and Waterfall
+
+#define MIN_MAG_DB        -40.0     // min of spectrogram/waterfall magnitude axis
+#define MAX_MAG_DB          0.0     // max of spectrogram/waterfall magnitude axis
+#define STEP_MAG_DB         5.0     // magnitude axis step
+#define BETA                0.95    // constant for time averaging spectrum data
+#define MIN_F_HZ            0       // min freq on Waterfall and Spectrum
+#define MAX_F_HZ            3000    // max freq on Waterfall and Spectrum
+#define STEP_F_HZ           500     // major (e.g. text legend) freq step on Waterfall and Spectrum graticule
+#define STEP_MINOR_F_HZ     100     // minor (ticks) freq step on Waterfall and Spectrum graticule
+#define WATERFALL_SECS_Y    30      // number of seconds respresented by y axis of waterfall
+#define WATERFALL_SECS_STEP 5       // graticule y axis steps of waterfall
+#define DT                  0.1     // time between real time graphing updates
+#define FS                  8000    // FDMDV modem sample rate
+
+// Scatter diagram 
+
+#define SCATTER_MEM_SECS    10
+// (symbols/frame)/(graphics update period) = symbols/s sent to scatter memory
+// memory (symbols) = secs of memory * symbols/sec
+#define SCATTER_MEM_SYMS_MAX    ((int)(SCATTER_MEM_SECS*((MODEM_STATS_NC_MAX+1)/DT)))
+#define SCATTER_EYE_MEM_ROWS    ((int)(SCATTER_MEM_SECS/DT))
+
+// Waveform plotting constants
+
+#define WAVEFORM_PLOT_FS    400                            // sample rate (points/s) of waveform plotted to screen
+#define WAVEFORM_PLOT_TIME  5                              // length or entire waveform on screen
+#define WAVEFORM_PLOT_BUF   ((int)(DT*WAVEFORM_PLOT_FS))   // number of new samples we plot per DT
+
+// sample rate I/O & conversion constants
+
+#define MAX_FPB             8096                           // maximum value of portAudio framesPerBuffer
+#define PA_FPB              1024                           // nominal value of portAudio framesPerBuffer
+#define SAMPLE_RATE         48000                          // 48 kHz sampling rate rec. as we can trust accuracy of sound card
+#define N8                  160                            // processing buffer size at 8 kHz
+#define MEM8                (FDMDV_OS_TAPS/FDMDV_OS)
+#define N48                 (N8*SAMPLE_RATE/FS)            // processing buffer size at 48 kHz
+#define NUM_CHANNELS        2                              // I think most sound cards prefer stereo we will convert to mono
+#define VOX_TONE_FREQ       1000.0                         // optional left channel vox tone freq
+#define VOX_TONE_AMP        30000                          // optional left channel vox tone amp
+
+#define MAX_BITS_PER_CODEC_FRAME 64                            // 1600 bit/s mode
+#define MAX_BYTES_PER_CODEC_FRAME (MAX_BITS_PER_CODEC_FRAME/8)
+#define MAX_BITS_PER_FDMDV_FRAME 40                            // 2000 bit/s mode
+
+// Squelch
+#define SQ_DEFAULT_SNR       2.0
+
+// Level Gauge
+#define FROM_RADIO_MAX       0.8
+#define FROM_MIC_MAX         0.8
+#define LEVEL_BETA           0.99
+
+// SNR
+#define SNRSLOW_BETA        0.5                           // time constant for slow SNR for display
+
+// Text messaging Data
+#define MAX_CALLSIGN         80
+#define MAX_EVENT_LOG        10
+#define MAX_EVENT_RULES      100
+   
+enum
+{
+    ID_ROTATE_LEFT = wxID_HIGHEST + 1,
+    ID_ROTATE_RIGHT,
+    ID_RESIZE,
+    ID_PAINT_BG
+};
+
+// Codec 2 LPC Post Filter defaults, from codec-dev/src/quantise.c
+
+#define CODEC2_LPC_PF_GAMMA 0.5
+#define CODEC2_LPC_PF_BETA  0.2
+
+// PlugIns ...
+
+#define PLUGIN_MAX_PARAMS 4
+
+#endif  //__FDMDV2_DEFINES__
diff --git a/freedv/tags/1.2.2/src/fdmdv2_main.cpp b/freedv/tags/1.2.2/src/fdmdv2_main.cpp
new file mode 100644 (file)
index 0000000..47a6e77
--- /dev/null
@@ -0,0 +1,3943 @@
+//==========================================================================
+// Name:            fdmdv2_main.cpp
+//
+// Purpose:         FreeDV main()
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include "fdmdv2_main.h"
+
+#define wxUSE_FILEDLG   1
+#define wxUSE_LIBPNG    1
+#define wxUSE_LIBJPEG   1
+#define wxUSE_GIF       1
+#define wxUSE_PCX       1
+#define wxUSE_LIBTIFF   1
+
+//-------------------------------------------------------------------
+// Bunch of globals used for communication with sound card call
+// back functions
+// ------------------------------------------------------------------
+
+int g_in, g_out;
+
+// Global Codec2 & modem states - just one reqd for tx & rx
+int                 g_Nc;
+int                 g_mode;
+struct freedv      *g_pfreedv;
+struct MODEM_STATS  g_stats;
+float               g_pwr_scale;
+int                 g_clip;
+
+// test Frames
+int                 g_testFrames;
+int                 g_test_frame_sync_state;
+int                 g_test_frame_count;
+int                 g_total_bits;
+int                 g_total_bit_errors;
+int                 g_channel_noise;
+float               g_sig_pwr_av = 0.0;
+struct FIFO        *g_error_pattern_fifo;
+short              *g_error_hist;
+// time averaged magnitude spectrum used for waterfall and spectrum display
+float               g_avmag[MODEM_STATS_NSPEC];
+
+// GUI controls that affect rx and tx processes
+int   g_SquelchActive;
+float g_SquelchLevel;
+int   g_analog;
+int   g_split;
+int   g_tx;
+float g_snr;
+bool  g_half_duplex;
+bool  g_modal;
+
+// sending and receiving Call Sign data
+struct FIFO         *g_txDataInFifo;
+struct FIFO         *g_rxDataOutFifo;
+
+// tx/rx processing states
+int                 g_State;
+paCallBackData     *g_rxUserdata;
+
+// FIFOs used for plotting waveforms
+struct FIFO        *g_plotDemodInFifo;
+struct FIFO        *g_plotSpeechOutFifo;
+struct FIFO        *g_plotSpeechInFifo;
+
+// Soundcard config
+int                 g_nSoundCards;
+int                 g_soundCard1InDeviceNum;
+int                 g_soundCard1OutDeviceNum;
+int                 g_soundCard1SampleRate;
+int                 g_soundCard2InDeviceNum;
+int                 g_soundCard2OutDeviceNum;
+int                 g_soundCard2SampleRate;
+
+// playing and recording from sound files
+
+SNDFILE            *g_sfPlayFile;
+bool                g_playFileToMicIn;
+bool                g_loopPlayFileToMicIn;
+int                 g_playFileToMicInEventId;
+
+SNDFILE            *g_sfRecFile;
+bool                g_recFileFromRadio;
+unsigned int        g_recFromRadioSamples;
+int                 g_recFileFromRadioEventId;
+
+SNDFILE            *g_sfPlayFileFromRadio;
+bool                g_playFileFromRadio;
+int                 g_sfFs;
+bool                g_loopPlayFileFromRadio;
+int                 g_playFileFromRadioEventId;
+float               g_blink;
+
+wxWindow           *g_parent;
+
+// Click to tune rx and tx frequency offset states
+float               g_RxFreqOffsetHz;
+COMP                g_RxFreqOffsetPhaseRect;
+float               g_TxFreqOffsetHz;
+COMP                g_TxFreqOffsetPhaseRect;
+
+// experimental mutex to make sound card callbacks mutually exclusive
+// TODO: review code and see if we need this any more, as fifos should
+// now be thread safe
+
+wxMutex g_mutexProtectingCallbackData;
+
+// Speex pre-processor states
+
+SpeexPreprocessState *g_speex_st;
+
+// WxWidgets - initialize the application
+IMPLEMENT_APP(MainApp);
+
+//FILE *ftest;
+FILE *g_logfile;
+
+//-------------------------------------------------------------------------
+// OnInit()
+//-------------------------------------------------------------------------
+bool MainApp::OnInit()
+{
+    if(!wxApp::OnInit())
+    {
+        return false;
+    }
+    SetVendorName(wxT("CODEC2-Project"));
+    SetAppName(wxT("FreeDV"));      // not needed, it's the default value
+
+#ifdef FILE_RATHER_THAN_REGISTRY
+    // Force use of file-based configuration persistance on Windows platforma
+    wxConfig *pConfig = new wxConfig();
+    wxFileConfig *pFConfig = new wxFileConfig(wxT("FreeDV"), wxT("CODEC2-Project"), wxT("FreeDV.conf"), wxT("FreeDV.conf"),  wxCONFIG_USE_LOCAL_FILE | wxCONFIG_USE_RELATIVE_PATH);
+    pConfig->Set(pFConfig);
+    pConfig->SetRecordDefaults();
+#else
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    pConfig->SetRecordDefaults();
+#endif
+
+    m_rTopWindow = wxRect(0, 0, 0, 0);
+    m_strRxInAudio.Empty();
+    m_strRxOutAudio.Empty();
+    m_textVoiceInput.Empty();
+    m_textVoiceOutput.Empty();
+    m_strSampleRate.Empty();
+    m_strBitrate.Empty();
+
+    // Look for Plug In
+
+    m_plugIn = false;
+    #ifdef __WXMSW__
+    wchar_t dll_path[] = L"afreedvplugin.dll";
+    m_plugInHandle = LoadLibrary(dll_path);
+    #else
+    m_plugInHandle = dlopen("afreedvplugin.so", RTLD_LAZY);
+    #endif
+    
+    if (m_plugInHandle) {
+        printf("plugin: .so found\n");
+        
+        // lets get some information abt the plugIn
+
+        void (*plugin_namefp)(char s[]);
+        void *(*plugin_openfp)(char *param_names[], int *nparams, int (*aplugin_get_persistant)(char *, char *));
+
+        #ifdef __WXMSW__
+        plugin_namefp = (void (*)(char*))GetProcAddress((HMODULE)m_plugInHandle, "plugin_name");
+        plugin_openfp = (void* (*)(char**,int *, int (*)(char *, char *)))GetProcAddress((HMODULE)m_plugInHandle, "plugin_open");
+        m_plugin_startfp = (void (*)(void *))GetProcAddress((HMODULE)m_plugInHandle, "plugin_start");
+        m_plugin_stopfp = (void (*)(void *))GetProcAddress((HMODULE)m_plugInHandle, "plugin_stop");
+        m_plugin_rx_samplesfp = (void (*)(void *, short *, int))GetProcAddress((HMODULE)m_plugInHandle, "plugin_rx_samples");
+        #else
+        plugin_namefp = (void (*)(char*))dlsym(m_plugInHandle, "plugin_name");
+        plugin_openfp = (void* (*)(char**,int *, int (*)(char *, char *)))dlsym(m_plugInHandle, "plugin_open");
+        m_plugin_startfp = (void (*)(void *))dlsym(m_plugInHandle, "plugin_start");
+        m_plugin_stopfp = (void (*)(void *))dlsym(m_plugInHandle, "plugin_stop");
+        m_plugin_rx_samplesfp = (void (*)(void *, short *, int))dlsym(m_plugInHandle, "plugin_rx_samples");
+        #endif
+        
+        if ((plugin_namefp != NULL) && (plugin_openfp != NULL)) {
+
+            char s[256];
+            m_plugIn = true;
+            (plugin_namefp)(s);
+            fprintf(stderr, "plugin name: %s\n", s);
+            m_plugInName = s;
+
+            char param_name1[80], param_name2[80];
+            char *param_names[2] = {param_name1, param_name2};
+            int  nparams, i;
+            m_plugInStates = (plugin_openfp)(param_names, &nparams, plugin_get_persistant);
+            m_numPlugInParam = nparams;
+            for(i=0; i<nparams; i++) {
+                m_plugInParamName[i] = param_names[i];
+                wxString configStr = "/" + m_plugInName + "/" + m_plugInParamName[i];
+                m_txtPlugInParam[i] = pConfig->Read(configStr, wxT(""));
+                //fprintf(stderr, "  plugin param name[%d]: %s\n", i, param_names[i]);
+                fprintf(stderr, "  plugin param name[%d]: %s values: %s\n", i, m_plugInParamName[i].mb_str().data(), m_txtPlugInParam[i].mb_str().data());
+            }
+        }
+        
+        else {
+            fprintf(stderr, "plugin: fps not found...\n");           
+        }
+    }
+    else {
+        fprintf(stderr, "plugin not found...\n");           
+    }
+
+    // Create the main application window
+
+    frame = new MainFrame(m_plugInName, NULL);
+    SetTopWindow(frame);
+
+    // Should guarantee that the first plot tab defined is the one
+    // displayed. But it doesn't when built from command line.  Why?
+
+    frame->m_auiNbookCtrl->ChangeSelection(0);
+    frame->Layout();
+    frame->Show();
+    g_parent =frame;
+
+
+    return true;
+}
+
+//-------------------------------------------------------------------------
+// OnExit()
+//-------------------------------------------------------------------------
+int MainApp::OnExit()
+{
+    fprintf(stderr, "MainApp::OnExit\n");
+    if (m_plugIn) {
+        #ifdef __WXMSW__
+        FreeLibrary((HMODULE)m_plugInHandle);
+        #else
+        dlclose(m_plugInHandle);
+        #endif
+    }
+
+    return 0;
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainFrame(wxFrame* pa->ent) : TopFrame(parent)
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+MainFrame::MainFrame(wxString plugInName, wxWindow *parent) : TopFrame(plugInName, parent)
+{
+    m_zoom              = 1.;
+
+    #ifdef __WXMSW__
+    g_logfile = stderr;
+    #else
+    g_logfile = stderr;
+    #endif
+
+
+    SetMinSize(wxSize(400,400));
+
+    // Init Hamlib library, but we dont start talking to any rigs yet
+
+    wxGetApp().m_hamlib = new Hamlib();
+
+    // Init Serialport library, but as for Hamlib we dont start talking to any rigs yet
+
+    wxGetApp().m_serialport = new Serialport();
+
+    tools->AppendSeparator();
+    wxMenuItem* m_menuItemToolsConfigDelete;
+    m_menuItemToolsConfigDelete = new wxMenuItem(tools, wxID_ANY, wxString(_("&Restore defaults")) , wxT("Delete config file/keys and restore defaults"), wxITEM_NORMAL);
+    this->Connect(m_menuItemToolsConfigDelete->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(MainFrame::OnDeleteConfig));
+
+    tools->Append(m_menuItemToolsConfigDelete);
+
+    wxConfigBase *pConfig = wxConfigBase::Get();
+
+    // restore frame position and size
+    int x = pConfig->Read(wxT("/MainFrame/left"),       20);
+    int y = pConfig->Read(wxT("/MainFrame/top"),        20);
+    int w = pConfig->Read(wxT("/MainFrame/width"),     800);
+    int h = pConfig->Read(wxT("/MainFrame/height"),    550);
+
+    // sanitise frame position as a first pass at Win32 registry bug
+
+    fprintf(g_logfile, "x = %d y = %d w = %d h = %d\n", x,y,w,h);
+    if (x < 0 || x > 2048) x = 20;
+    if (y < 0 || y > 2048) y = 20;
+    if (w < 0 || w > 2048) w = 800;
+    if (h < 0 || h > 2048) h = 550;
+
+    wxGetApp().m_show_wf            = pConfig->Read(wxT("/MainFrame/show_wf"),           1);
+    wxGetApp().m_show_spect         = pConfig->Read(wxT("/MainFrame/show_spect"),        1);
+    wxGetApp().m_show_scatter       = pConfig->Read(wxT("/MainFrame/show_scatter"),      1);
+    wxGetApp().m_show_timing        = pConfig->Read(wxT("/MainFrame/show_timing"),       1);
+    wxGetApp().m_show_freq          = pConfig->Read(wxT("/MainFrame/show_freq"),         1);
+    wxGetApp().m_show_speech_in     = pConfig->Read(wxT("/MainFrame/show_speech_in"),    1);
+    wxGetApp().m_show_speech_out    = pConfig->Read(wxT("/MainFrame/show_speech_out"),   1);
+    wxGetApp().m_show_demod_in      = pConfig->Read(wxT("/MainFrame/show_demod_in"),     1);
+    wxGetApp().m_show_test_frame_errors = pConfig->Read(wxT("/MainFrame/show_test_frame_errors"),     1);
+    wxGetApp().m_show_test_frame_errors_hist = pConfig->Read(wxT("/MainFrame/show_test_frame_errors_hist"),     1);
+
+    wxGetApp().m_rxNbookCtrl        = pConfig->Read(wxT("/MainFrame/rxNbookCtrl"),    (long)0);
+
+    g_SquelchActive = pConfig->Read(wxT("/Audio/SquelchActive"), (long)0);
+    g_SquelchLevel = pConfig->Read(wxT("/Audio/SquelchLevel"), (int)(SQ_DEFAULT_SNR*2));
+    g_SquelchLevel /= 2.0;
+
+    Move(x, y);
+    SetClientSize(w, h);
+    
+    if(wxGetApp().m_show_wf)
+    {
+        // Add Waterfall Plot window
+        m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl, false, 0);
+        m_panelWaterfall->SetToolTip(_("Left click to tune, Right click to toggle mono/colour"));
+        m_auiNbookCtrl->AddPage(m_panelWaterfall, _("Waterfall"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_spect)
+    {
+        // Add Spectrum Plot window
+        m_panelSpectrum = new PlotSpectrum((wxFrame*) m_auiNbookCtrl, g_avmag,
+                                           MODEM_STATS_NSPEC*((float)MAX_F_HZ/MODEM_STATS_MAX_F_HZ));
+        m_panelSpectrum->SetToolTip(_("Left click to tune"));
+        m_auiNbookCtrl->AddPage(m_panelSpectrum, _("Spectrum"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_scatter)
+    {
+        // Add Scatter Plot window
+        m_panelScatter = new PlotScatter((wxFrame*) m_auiNbookCtrl);
+        m_auiNbookCtrl->AddPage(m_panelScatter, _("Scatter"), true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_demod_in)
+    {
+        // Add Demod Input window
+        m_panelDemodIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelDemodIn, _("Frm Radio"), true, wxNullBitmap);
+        g_plotDemodInFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_speech_in)
+    {
+        // Add Speech Input window
+        m_panelSpeechIn = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelSpeechIn, _("Frm Mic"), true, wxNullBitmap);
+        g_plotSpeechInFifo = fifo_create(4*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_speech_out)
+    {
+        // Add Speech Output window
+        m_panelSpeechOut = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelSpeechOut, _("To Spkr/Hdphns"), true, wxNullBitmap);
+        g_plotSpeechOutFifo = fifo_create(2*WAVEFORM_PLOT_BUF);
+    }
+
+    if(wxGetApp().m_show_timing)
+    {
+        // Add Timing Offset window
+        m_panelTimeOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 5.0, DT, -0.5, 0.5, 1, 0.1, "%2.1f", 0);
+        m_auiNbookCtrl->AddPage(m_panelTimeOffset, L"Timing \u0394", true, wxNullBitmap);
+    }
+    if(wxGetApp().m_show_freq)
+    {
+        // Add Frequency Offset window
+        m_panelFreqOffset = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 5.0, DT, -200, 200, 1, 50, "%3.0fHz", 0);
+        m_auiNbookCtrl->AddPage(m_panelFreqOffset, L"Frequency \u0394", true, wxNullBitmap);
+    }
+
+    if(wxGetApp().m_show_test_frame_errors)
+    {
+        // Add Test Frame Errors window
+        m_panelTestFrameErrors = new PlotScalar((wxFrame*) m_auiNbookCtrl, 2*MODEM_STATS_NC_MAX, 30.0, DT, 0, 2*MODEM_STATS_NC_MAX+2, 1, 1, "", 1);
+        m_auiNbookCtrl->AddPage(m_panelTestFrameErrors, L"Test Frame Errors", true, wxNullBitmap);
+    }
+
+    if(wxGetApp().m_show_test_frame_errors_hist)
+    {
+        // Add Test Frame Errors window
+        m_panelTestFrameErrorsHist = new PlotScalar((wxFrame*) m_auiNbookCtrl, 1, 1.0, 1.0/(2*FDMDV_NC_MAX), 0.0, 1.0, 1.0/FDMDV_NC_MAX, 0.1, "%3.2f", 0);
+        m_auiNbookCtrl->AddPage(m_panelTestFrameErrorsHist, L"Test Frame Histogram", true, wxNullBitmap);
+    }
+
+    wxGetApp().m_framesPerBuffer = pConfig->Read(wxT("/Audio/framesPerBuffer"), PA_FPB);
+
+    g_soundCard1InDeviceNum  = pConfig->Read(wxT("/Audio/soundCard1InDeviceNum"),         -1);
+    g_soundCard1OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard1OutDeviceNum"),        -1);
+    g_soundCard1SampleRate   = pConfig->Read(wxT("/Audio/soundCard1SampleRate"),          -1);
+
+    g_soundCard2InDeviceNum  = pConfig->Read(wxT("/Audio/soundCard2InDeviceNum"),         -1);
+    g_soundCard2OutDeviceNum = pConfig->Read(wxT("/Audio/soundCard2OutDeviceNum"),        -1);
+    g_soundCard2SampleRate   = pConfig->Read(wxT("/Audio/soundCard2SampleRate"),          -1);
+
+    g_nSoundCards = 0;
+    if ((g_soundCard1InDeviceNum > -1) && (g_soundCard1OutDeviceNum > -1)) {
+        g_nSoundCards = 1;
+        if ((g_soundCard2InDeviceNum > -1) && (g_soundCard2OutDeviceNum > -1))
+            g_nSoundCards = 2;
+    }
+
+    wxGetApp().m_playFileToMicInPath = pConfig->Read("/File/playFileToMicInPath",   wxT(""));
+    wxGetApp().m_recFileFromRadioPath = pConfig->Read("/File/recFileFromRadioPath", wxT(""));
+    wxGetApp().m_recFileFromRadioSecs = pConfig->Read("/File/recFileFromRadioSecs", 30);
+    wxGetApp().m_playFileFromRadioPath = pConfig->Read("/File/playFileFromRadioPath", wxT(""));
+
+    // PTT -------------------------------------------------------------------
+
+    wxGetApp().m_boolHalfDuplex     = pConfig->ReadBool(wxT("/Rig/HalfDuplex"),     true);
+    wxGetApp().m_leftChannelVoxTone = pConfig->ReadBool("/Rig/leftChannelVoxTone",  false);
+    wxGetApp().m_txtVoiceKeyerWaveFilePath = pConfig->Read(wxT("/VoiceKeyer/WaveFilePath"), wxT(""));
+    wxGetApp().m_txtVoiceKeyerWaveFile = pConfig->Read(wxT("/VoiceKeyer/WaveFile"), wxT("voicekeyer.wav"));
+    wxGetApp().m_intVoiceKeyerRxPause = pConfig->Read(wxT("/VoiceKeyer/RxPause"), 10);
+    wxGetApp().m_intVoiceKeyerRepeats = pConfig->Read(wxT("/VoiceKeyer/Repeats"), 5);
+    wxGetApp().m_boolHamlibUseForPTT = pConfig->ReadBool("/Hamlib/UseForPTT", false);
+    wxGetApp().m_intHamlibRig = pConfig->ReadLong("/Hamlib/RigName", 0);
+    wxGetApp().m_strHamlibSerialPort = pConfig->Read("/Hamlib/SerialPort", "");
+    
+    wxGetApp().m_boolUseSerialPTT   = pConfig->ReadBool(wxT("/Rig/UseSerialPTT"),   false);
+    wxGetApp().m_strRigCtrlPort     = pConfig->Read(wxT("/Rig/Port"),               wxT(""));
+    wxGetApp().m_boolUseRTS         = pConfig->ReadBool(wxT("/Rig/UseRTS"),         true);
+    wxGetApp().m_boolRTSPos         = pConfig->ReadBool(wxT("/Rig/RTSPolarity"),    true);
+    wxGetApp().m_boolUseDTR         = pConfig->ReadBool(wxT("/Rig/UseDTR"),         false);
+    wxGetApp().m_boolDTRPos         = pConfig->ReadBool(wxT("/Rig/DTRPolarity"),    false);
+
+    assert(wxGetApp().m_serialport != NULL);
+
+    // -----------------------------------------------------------------------
+
+    bool slow = false; // prevents compile error when using default bool
+    wxGetApp().m_snrSlow = pConfig->Read("/Audio/snrSlow", slow);
+
+    bool t = true;     // prevents compile error when using default bool
+    wxGetApp().m_codec2LPCPostFilterEnable     = pConfig->Read(wxT("/Filter/codec2LPCPostFilterEnable"),    t);
+    wxGetApp().m_codec2LPCPostFilterBassBoost  = pConfig->Read(wxT("/Filter/codec2LPCPostFilterBassBoost"), t);
+    wxGetApp().m_codec2LPCPostFilterGamma      = (float)pConfig->Read(wxT("/Filter/codec2LPCPostFilterGamma"),     CODEC2_LPC_PF_GAMMA*100)/100.0;
+    wxGetApp().m_codec2LPCPostFilterBeta       = (float)pConfig->Read(wxT("/Filter/codec2LPCPostFilterBeta"),      CODEC2_LPC_PF_BETA*100)/100.0;
+    //printf("main(): m_codec2LPCPostFilterBeta: %f\n", wxGetApp().m_codec2LPCPostFilterBeta);
+
+    wxGetApp().m_speexpp_enable     = pConfig->Read(wxT("/Filter/speexpp_enable"),    t);
+
+    wxGetApp().m_MicInBassFreqHz = (float)pConfig->Read(wxT("/Filter/MicInBassFreqHz"),    1);
+    wxGetApp().m_MicInBassGaindB = (float)pConfig->Read(wxT("/Filter/MicInBassGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInTrebleFreqHz = (float)pConfig->Read(wxT("/Filter/MicInTrebleFreqHz"),    1);
+    wxGetApp().m_MicInTrebleGaindB = (float)pConfig->Read(wxT("/Filter/MicInTrebleGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInMidFreqHz = (float)pConfig->Read(wxT("/Filter/MicInMidFreqHz"),    1);
+    wxGetApp().m_MicInMidGaindB = (float)pConfig->Read(wxT("/Filter/MicInMidGaindB"),    (long)0)/10.0;
+    wxGetApp().m_MicInMidQ = (float)pConfig->Read(wxT("/Filter/MicInMidQ"),              (long)100)/100.0;
+
+    bool f = false;
+    wxGetApp().m_MicInEQEnable = (float)pConfig->Read(wxT("/Filter/MicInEQEnable"), f);
+
+    wxGetApp().m_SpkOutBassFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutBassFreqHz"),    1);
+    wxGetApp().m_SpkOutBassGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutBassGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutTrebleFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutTrebleFreqHz"),    1);
+    wxGetApp().m_SpkOutTrebleGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutTrebleGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutMidFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutMidFreqHz"),    1);
+    wxGetApp().m_SpkOutMidGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutMidGaindB"),    (long)0)/10.0;
+    wxGetApp().m_SpkOutMidQ = (float)pConfig->Read(wxT("/Filter/SpkOutMidQ"),                (long)100)/100.0;
+
+    wxGetApp().m_SpkOutEQEnable = (float)pConfig->Read(wxT("/Filter/SpkOutEQEnable"), f);
+
+    wxGetApp().m_callSign = pConfig->Read("/Data/CallSign", wxT(""));
+    wxGetApp().m_textEncoding = pConfig->Read("/Data/TextEncoding", 1);
+    wxGetApp().m_enable_checksum = pConfig->Read("/Data/EnableChecksumOnMsgRx", f);
+
+    wxGetApp().m_events = pConfig->Read("/Events/enable", f);
+    wxGetApp().m_events_spam_timer = (int)pConfig->Read(wxT("/Events/spam_timer"), 10);
+    wxGetApp().m_events_regexp_match = pConfig->Read("/Events/regexp_match", wxT("s=(.*)"));
+    wxGetApp().m_events_regexp_replace = pConfig->Read("/Events/regexp_replace", 
+                                                       wxT("curl http://qso.freedv.org/cgi-bin/onspot.cgi?s=\\1"));
+    // make sure regexp lists are terminated by a \n
+
+    if (wxGetApp().m_events_regexp_match.Last() != '\n') {
+        wxGetApp().m_events_regexp_match = wxGetApp().m_events_regexp_match+'\n';
+    }
+    if (wxGetApp().m_events_regexp_replace.Last() != '\n') {
+        wxGetApp().m_events_regexp_replace = wxGetApp().m_events_regexp_replace+'\n';
+    }
+
+    wxGetApp().m_udp_enable = (float)pConfig->Read(wxT("/UDP/enable"), f);
+    wxGetApp().m_udp_port = (int)pConfig->Read(wxT("/UDP/port"), 3000);
+
+    wxGetApp().m_FreeDV700txClip = (float)pConfig->Read(wxT("/FreeDV700/txClip"), t);
+    wxGetApp().m_debug_console = (float)pConfig->Read(wxT("/Debug/console"), f);
+
+    int mode  = pConfig->Read(wxT("/Audio/mode"), (long)0);
+    if (mode == 0)
+        m_rb1600->SetValue(1);
+    if (mode == 2)
+        m_rb700b->SetValue(1);
+    if (mode == 3)
+        m_rb700c->SetValue(1);
+    if (mode == 4)
+        m_rb800xa->SetValue(1);
+        
+    pConfig->SetPath(wxT("/"));
+
+//    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    //m_togRxID->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnRxIDUI), NULL, this);
+    //m_togTxID->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnTxIDUI), NULL, this);
+    m_togBtnOnOff->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnOnOffUI), NULL, this);
+    m_togBtnSplit->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnSplitClickUI), NULL, this);
+    m_togBtnAnalog->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnAnalogClickUI), NULL, this);
+    //m_togBtnALC->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnALCClickUI), NULL, this);
+   // m_btnTogPTT->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnPTT_UI), NULL, this);
+
+    m_togBtnSplit->Disable();
+    //m_togRxID->Disable();
+    //m_togTxID->Disable();
+    m_togBtnAnalog->Disable();
+    m_btnTogPTT->Disable();
+    m_togBtnVoiceKeyer->Disable();
+    //m_togBtnALC->Disable();
+
+    // squelch settings
+    char sqsnr[15];
+    m_sliderSQ->SetValue((int)((g_SquelchLevel+5.0)*2.0));
+    sprintf(sqsnr, "%4.1f", g_SquelchLevel);
+    wxString sqsnr_string(sqsnr);
+    m_textSQ->SetLabel(sqsnr_string);
+    m_ckboxSQ->SetValue(g_SquelchActive);
+
+    // SNR settings
+
+    m_ckboxSNR->SetValue(wxGetApp().m_snrSlow);
+    setsnrBeta(wxGetApp().m_snrSlow);
+
+#ifdef _USE_TIMER
+    Bind(wxEVT_TIMER, &MainFrame::OnTimer, this);       // ID_MY_WINDOW);
+    m_plotTimer.SetOwner(this, ID_TIMER_WATERFALL);
+    //m_panelWaterfall->Refresh();
+#endif
+
+    m_RxRunning = false;
+
+#ifdef _USE_ONIDLE
+    Connect(wxEVT_IDLE, wxIdleEventHandler(MainFrame::OnIdle), NULL, this);
+#endif //_USE_ONIDLE
+
+    g_sfPlayFile = NULL;
+    g_playFileToMicIn = false;
+    g_loopPlayFileToMicIn = false;
+
+    g_sfRecFile = NULL;
+    g_recFileFromRadio = false;
+
+    g_sfPlayFileFromRadio = NULL;
+    g_playFileFromRadio = false;
+    g_loopPlayFileFromRadio = false;
+
+    // init click-tune states
+
+    g_RxFreqOffsetHz = 0.0;
+    g_RxFreqOffsetPhaseRect.real = cos(0.0);
+    g_RxFreqOffsetPhaseRect.imag = sin(0.0);
+    m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+    m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+
+    g_TxFreqOffsetHz = 0.0;
+    g_TxFreqOffsetPhaseRect.real = cos(0.0);
+    g_TxFreqOffsetPhaseRect.imag = sin(0.0);
+
+    g_tx = 0;
+    g_split = 0;
+
+    // data states
+    g_txDataInFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
+    g_rxDataOutFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
+
+    sox_biquad_start();
+
+    g_testFrames = 0;
+    g_test_frame_sync_state = 0;
+    g_total_bit_errors = 0;
+    g_total_bits = 0;
+    wxGetApp().m_testFrames = false;
+
+    g_modal = false;
+
+#ifdef __EXPERIMENTAL_UDP__
+    // Start UDP listener thread
+
+    m_UDPThread = NULL;
+    startUDPThread();
+#endif
+
+    optionsDlg = new OptionsDlg(NULL);
+    m_schedule_restore = false;
+
+    vk_state = VK_IDLE;
+
+    // Init optional Windows debug console so we can see all those printfs
+
+#ifdef __WXMSW__
+    if (wxGetApp().m_debug_console) {
+        // somewhere to send printfs while developing
+        int ret = AllocConsole();
+        freopen("CONOUT$", "w", stdout); 
+        freopen("CONOUT$", "w", stderr); 
+        fprintf(stderr, "AllocConsole: %d m_debug_console: %d\n", ret, wxGetApp().m_debug_console);
+    }
+#endif
+
+    //ftest = fopen("ftest.raw", "wb");
+    //assert(ftest != NULL);
+}
+
+//-------------------------------------------------------------------------
+// ~MainFrame()
+//-------------------------------------------------------------------------
+MainFrame::~MainFrame()
+{
+    int x;
+    int y;
+    int w;
+    int h;
+
+    fprintf(stderr, "MainFrame::~MainFrame()\n");
+    //fclose(ftest);
+    #ifdef __WXMSW__
+    fclose(g_logfile);
+    #endif
+
+    if (optionsDlg != NULL) {
+        delete optionsDlg;
+        optionsDlg = NULL;
+    }
+
+#ifdef __EXPERIMENTAL_UDP__
+    stopUDPThread();
+#endif
+
+    if (wxGetApp().m_hamlib) delete wxGetApp().m_hamlib;
+    if (wxGetApp().m_serialport) delete wxGetApp().m_serialport;
+
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(pConfig)
+    {
+        if (!IsIconized()) {
+            GetClientSize(&w, &h);
+            GetPosition(&x, &y);
+            printf("x = %d y = %d w = %d h = %d\n", x,y,w,h);
+            pConfig->Write(wxT("/MainFrame/left"),               (long) x);
+            pConfig->Write(wxT("/MainFrame/top"),                (long) y);
+            pConfig->Write(wxT("/MainFrame/width"),              (long) w);
+            pConfig->Write(wxT("/MainFrame/height"),             (long) h);
+        }
+        pConfig->Write(wxT("/MainFrame/show_wf"),           wxGetApp().m_show_wf);
+        pConfig->Write(wxT("/MainFrame/show_spect"),        wxGetApp().m_show_spect);
+        pConfig->Write(wxT("/MainFrame/show_scatter"),      wxGetApp().m_show_scatter);
+        pConfig->Write(wxT("/MainFrame/show_timing"),       wxGetApp().m_show_timing);
+        pConfig->Write(wxT("/MainFrame/show_freq"),         wxGetApp().m_show_freq);
+        pConfig->Write(wxT("/MainFrame/show_speech_in"),    wxGetApp().m_show_speech_in);
+        pConfig->Write(wxT("/MainFrame/show_speech_out"),   wxGetApp().m_show_speech_out);
+        pConfig->Write(wxT("/MainFrame/show_demod_in"),     wxGetApp().m_show_demod_in);
+        pConfig->Write(wxT("/MainFrame/show_test_frame_errors"), wxGetApp().m_show_test_frame_errors);
+        pConfig->Write(wxT("/MainFrame/show_test_frame_errors_hist"), wxGetApp().m_show_test_frame_errors_hist);
+
+        pConfig->Write(wxT("/MainFrame/rxNbookCtrl"), wxGetApp().m_rxNbookCtrl);
+
+        pConfig->Write(wxT("/Audio/SquelchActive"),         g_SquelchActive);
+        pConfig->Write(wxT("/Audio/SquelchLevel"),          (int)(g_SquelchLevel*2.0));
+
+        pConfig->Write(wxT("/Audio/framesPerBuffer"),       wxGetApp().m_framesPerBuffer);
+
+        pConfig->Write(wxT("/Audio/soundCard1InDeviceNum"),   g_soundCard1InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1OutDeviceNum"),  g_soundCard1OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard1SampleRate"),    g_soundCard1SampleRate );
+
+        pConfig->Write(wxT("/Audio/soundCard2InDeviceNum"),   g_soundCard2InDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2OutDeviceNum"),  g_soundCard2OutDeviceNum);
+        pConfig->Write(wxT("/Audio/soundCard2SampleRate"),    g_soundCard2SampleRate );
+
+        pConfig->Write(wxT("/VoiceKeyer/WaveFilePath"), wxGetApp().m_txtVoiceKeyerWaveFilePath);
+        pConfig->Write(wxT("/VoiceKeyer/WaveFile"), wxGetApp().m_txtVoiceKeyerWaveFile);
+        pConfig->Write(wxT("/VoiceKeyer/RxPause"), wxGetApp().m_intVoiceKeyerRxPause);
+        pConfig->Write(wxT("/VoiceKeyer/Repeats"), wxGetApp().m_intVoiceKeyerRepeats);
+
+        pConfig->Write(wxT("/Rig/HalfDuplex"),              wxGetApp().m_boolHalfDuplex);
+        pConfig->Write(wxT("/Rig/leftChannelVoxTone"),      wxGetApp().m_leftChannelVoxTone);
+        pConfig->Write("/Hamlib/UseForPTT", wxGetApp().m_boolHamlibUseForPTT);
+        pConfig->Write("/Hamlib/RigName", wxGetApp().m_intHamlibRig);
+        pConfig->Write("/Hamlib/SerialPort", wxGetApp().m_strHamlibSerialPort);
+
+
+        pConfig->Write(wxT("/File/playFileToMicInPath"),    wxGetApp().m_playFileToMicInPath);
+        pConfig->Write(wxT("/File/recFileFromRadioPath"),   wxGetApp().m_recFileFromRadioPath);
+        pConfig->Write(wxT("/File/recFileFromRadioSecs"),   wxGetApp().m_recFileFromRadioSecs);
+        pConfig->Write(wxT("/File/playFileFromRadioPath"),  wxGetApp().m_playFileFromRadioPath);
+
+        pConfig->Write(wxT("/Audio/snrSlow"), wxGetApp().m_snrSlow);
+
+        pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
+        pConfig->Write(wxT("/Data/TextEncoding"), wxGetApp().m_textEncoding);
+        pConfig->Write(wxT("/Data/EnableChecksumOnMsgRx"), wxGetApp().m_enable_checksum);
+        pConfig->Write(wxT("/Events/enable"), wxGetApp().m_events);
+        pConfig->Write(wxT("/Events/spam_timer"), wxGetApp().m_events_spam_timer);
+        pConfig->Write(wxT("/Events/regexp_match"), wxGetApp().m_events_regexp_match);
+        pConfig->Write(wxT("/Events/regexp_replace"), wxGetApp().m_events_regexp_replace);
+        pConfig->Write(wxT("/UDP/enable"), wxGetApp().m_udp_enable);
+        pConfig->Write(wxT("/UDP/port"),  wxGetApp().m_udp_port);
+
+        pConfig->Write(wxT("/Filter/MicInEQEnable"), wxGetApp().m_MicInEQEnable);
+        pConfig->Write(wxT("/Filter/SpkOutEQEnable"), wxGetApp().m_SpkOutEQEnable);
+
+        pConfig->Write(wxT("/FreeDV700/txClip"), wxGetApp().m_FreeDV700txClip);
+
+        pConfig->Write(wxT("/Debug/console"), wxGetApp().m_debug_console);
+
+        int mode;
+        if (m_rb1600->GetValue())
+            mode = 0;
+        if (m_rb700b->GetValue())
+            mode = 2;
+        if (m_rb700c->GetValue())
+            mode = 3;
+        if (m_rb800xa->GetValue())
+            mode = 4;
+       pConfig->Write(wxT("/Audio/mode"), mode);
+    }
+
+    //m_togRxID->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnRxIDUI), NULL, this);
+    //m_togTxID->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnTxIDUI), NULL, this);
+    m_togBtnOnOff->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnOnOffUI), NULL, this);
+    m_togBtnSplit->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnSplitClickUI), NULL, this);
+    m_togBtnAnalog->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnAnalogClickUI), NULL, this);
+    //m_togBtnALC->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnALCClickUI), NULL, this);
+    //m_btnTogPTT->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnPTT_UI), NULL, this);
+
+    sox_biquad_finish();
+
+    if (m_RxRunning)
+    {
+        stopRxStream();
+    }
+    if (g_sfPlayFile != NULL)
+    {
+        sf_close(g_sfPlayFile);
+        g_sfPlayFile = NULL;
+    }
+    if (g_sfRecFile != NULL)
+    {
+        sf_close(g_sfRecFile);
+        g_sfRecFile = NULL;
+    }
+#ifdef _USE_TIMER
+    if(m_plotTimer.IsRunning())
+    {
+        m_plotTimer.Stop();
+        Unbind(wxEVT_TIMER, &MainFrame::OnTimer, this);
+    }
+#endif //_USE_TIMER
+
+#ifdef _USE_ONIDLE
+    Disconnect(wxEVT_IDLE, wxIdleEventHandler(MainFrame::OnIdle), NULL, this);
+#endif // _USE_ONIDLE
+
+    delete wxConfigBase::Set((wxConfigBase *) NULL);
+}
+
+
+#ifdef _USE_ONIDLE
+void MainFrame::OnIdle(wxIdleEvent &evt) {
+}
+#endif
+
+
+#ifdef _USE_TIMER
+//----------------------------------------------------------------
+// OnTimer()
+//
+// when the timer fires every DT seconds we update the GUI displays.
+// the tabs only the plot that is visible actually gets updated, this
+// keeps CPU load reasonable
+//----------------------------------------------------------------
+void MainFrame::OnTimer(wxTimerEvent &evt)
+{
+
+    int r,c;
+
+    if (m_panelWaterfall->checkDT()) {
+        m_panelWaterfall->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+        m_panelWaterfall->m_newdata = true;
+        m_panelWaterfall->Refresh();
+    }
+
+    m_panelSpectrum->setRxFreq(FDMDV_FCENTRE - g_RxFreqOffsetHz);
+    m_panelSpectrum->m_newdata = true;
+    m_panelSpectrum->Refresh();
+
+    /* update scatter/eye plot ------------------------------------------------------------*/
+
+    if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_800XA) {
+        /* FSK Mode - eye diagram ---------------------------------------------------------*/
+        
+        /* add samples row by row */
+
+        int i;
+       for (i=0; i<g_stats.neyetr; i++) {
+            m_panelScatter->add_new_samples_eye(&g_stats.rx_eye[i][0], g_stats.neyesamp);
+        }
+    }
+    else {
+        /* PSK Modes - scatter plot -------------------------------------------------------*/
+        for (r=0; r<g_stats.nr; r++) {
+        
+            if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600) {
+                m_panelScatter->add_new_samples_scatter(&g_stats.rx_symbols[r][0]);
+            }
+        
+            if ((freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) || (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
+            
+                /* 
+                   FreeDV 700 uses diversity, so combine symbols for
+                   scatter plot, as combined symbols are used for
+                   demodulation.  Note we need to use a copy of the
+                   symbols, as we are not sure when the stats will be
+                   updated.
+                */
+
+                COMP rx_symbols_copy[g_Nc/2];
+
+                for(c=0; c<g_Nc/2; c++)
+                    rx_symbols_copy[c] = cadd(g_stats.rx_symbols[r][c], g_stats.rx_symbols[r][c+g_Nc/2]);
+                m_panelScatter->add_new_samples_scatter(rx_symbols_copy);
+            }
+       
+        }
+    }
+
+    m_panelScatter->Refresh();
+
+    // Oscilliscope type speech plots -------------------------------------------------------
+
+    short speechInPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotSpeechInFifo, speechInPlotSamples, WAVEFORM_PLOT_BUF)) {
+        memset(speechInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+        //fprintf(stderr, "empty!\n");
+    }
+    m_panelSpeechIn->add_new_short_samples(0, speechInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelSpeechIn->Refresh();
+
+    short speechOutPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotSpeechOutFifo, speechOutPlotSamples, WAVEFORM_PLOT_BUF))
+        memset(speechOutPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+    m_panelSpeechOut->add_new_short_samples(0, speechOutPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelSpeechOut->Refresh();
+
+    short demodInPlotSamples[WAVEFORM_PLOT_BUF];
+    if (fifo_read(g_plotDemodInFifo, demodInPlotSamples, WAVEFORM_PLOT_BUF)) {
+        memset(demodInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
+    }
+    m_panelDemodIn->add_new_short_samples(0,demodInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
+    m_panelDemodIn->Refresh();
+
+    // Demod states -----------------------------------------------------------------------
+
+    m_panelTimeOffset->add_new_sample(0, (float)g_stats.rx_timing/FDMDV_NOM_SAMPLES_PER_FRAME);
+    m_panelTimeOffset->Refresh();
+
+    m_panelFreqOffset->add_new_sample(0, g_stats.foff);
+    m_panelFreqOffset->Refresh();
+
+    // SNR text box and gauge ------------------------------------------------------------
+
+    // LP filter g_stats.snr_est some more to stabilise the
+    // display. g_stats.snr_est already has some low pass filtering
+    // but we need it fairly fast to activate squelch.  So we
+    // optionally perform some further filtering for the display
+    // version of SNR.  The "Slow" checkbox controls the amount of
+    // filtering.  The filtered snr also controls the squelch
+
+    g_snr = m_snrBeta*g_snr + (1.0 - m_snrBeta)*g_stats.snr_est;
+    float snr_limited = g_snr;
+    if (snr_limited < -5.0) snr_limited = -5.0;
+    if (snr_limited > 20.0) snr_limited = 20.0;
+
+    char snr[15];
+    sprintf(snr, "%d", (int)(g_snr+0.5)); // round to nearest dB
+
+    //printf("snr_est: %f m_snrBeta: %f g_snr: %f snr_limited: %f\n", g_stats.snr_est,  m_snrBeta, g_snr, snr_limited);
+
+    wxString snr_string(snr);
+    m_textSNR->SetLabel(snr_string);
+    m_gaugeSNR->SetValue((int)(snr_limited+5));
+
+    // Level Gauge -----------------------------------------------------------------------
+
+    float tooHighThresh;
+    if (!g_tx && m_RxRunning)
+    {
+        // receive mode - display From Radio peaks
+        // peak from this DT sampling period
+        int maxDemodIn = 0;
+        for(int i=0; i<WAVEFORM_PLOT_BUF; i++)
+            if (maxDemodIn < abs(demodInPlotSamples[i]))
+                maxDemodIn = abs(demodInPlotSamples[i]);
+
+        // peak from last second
+        if (maxDemodIn > m_maxLevel)
+            m_maxLevel = maxDemodIn;
+
+        tooHighThresh = FROM_RADIO_MAX;
+    }
+    else
+    {
+        // transmit mode - display From Mic peaks
+
+        // peak from this DT sampling period
+        int maxSpeechIn = 0;
+        for(int i=0; i<WAVEFORM_PLOT_BUF; i++)
+            if (maxSpeechIn < abs(speechInPlotSamples[i]))
+                maxSpeechIn = abs(speechInPlotSamples[i]);
+
+        // peak from last second
+        if (maxSpeechIn > m_maxLevel)
+            m_maxLevel = maxSpeechIn;
+
+       tooHighThresh = FROM_MIC_MAX;
+    }
+
+    // Peak Reading meter: updates peaks immediately, then slowly decays
+    int maxScaled = (int)(100.0 * ((float)m_maxLevel/32767.0));
+    m_gaugeLevel->SetValue(maxScaled);
+    //printf("maxScaled: %d\n", maxScaled);
+    if (((float)maxScaled/100) > tooHighThresh)
+        m_textLevel->SetLabel("Too High");
+    else
+        m_textLevel->SetLabel("");
+
+    m_maxLevel *= LEVEL_BETA;
+
+    // sync LED (Colours don't work on Windows) ------------------------
+
+    if (g_State) {
+        m_rbSync->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
+        m_rbSync->SetValue(true);
+    }
+    else {
+        m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) ); // red
+        m_rbSync->SetValue(false);
+    }
+
+    // send Callsign ----------------------------------------------------
+
+    char callsign[MAX_CALLSIGN];
+    strncpy(callsign, (const char*) wxGetApp().m_callSign.mb_str(wxConvUTF8), MAX_CALLSIGN-1);
+
+    // buffer 1 txt message to ensure tx data fifo doesn't "run dry"
+
+    if ((unsigned)fifo_used(g_txDataInFifo) < strlen(callsign)) {
+        unsigned int  i;
+
+        //fprintf(g_logfile, "tx callsign: %s.\n", callsign);
+
+        /* optionally append checksum */
+
+        if (wxGetApp().m_enable_checksum) {
+
+            unsigned char checksum = 0;
+            char callsign_checksum_cr[MAX_CALLSIGN+1];
+
+            for(i=0; i<strlen(callsign); i++)
+                checksum += callsign[i];
+            sprintf(callsign_checksum_cr, "%s%2x", callsign, checksum);
+            callsign_checksum_cr[strlen(callsign)+2] = 13;
+            callsign_checksum_cr[strlen(callsign)+3] = 0;
+            strcpy(callsign, callsign_checksum_cr);
+        }
+        else {
+            callsign[strlen(callsign)] = 13;
+            callsign[strlen(callsign)+1] = 0;
+        }
+
+        //fprintf(g_logfile, "tx callsign: %s.\n", callsign);
+
+        // write chars to tx data fifo
+
+        for(i=0; i<strlen(callsign); i++) {
+            short ashort = (short)callsign[i];
+            fifo_write(g_txDataInFifo, &ashort, 1);
+        }
+    }
+
+    // See if any Callsign info received --------------------------------
+
+    short ashort;
+    while (fifo_read(g_rxDataOutFifo, &ashort, 1) == 0) {
+
+        if ((ashort == 13) || ((m_pcallsign - m_callsign) > MAX_CALLSIGN-1)) {
+            // CR completes line
+            *m_pcallsign = 0;
+            
+            /* Checksums can be disabled, e.g. for compatability with
+               older vesions.  In that case we print msg but don't do
+               any event processing.  If checksums enabled, only print
+               out when checksum is good. */
+
+            if (wxGetApp().m_enable_checksum) {
+                // lets see if checksum is OK
+            
+                unsigned char checksum_rx = 0;
+                if (strlen(m_callsign) > 2) {
+                    for(unsigned int i=0; i<strlen(m_callsign)-2; i++)
+                        checksum_rx += m_callsign[i];
+                }
+                unsigned int checksum_tx;
+                int ret = sscanf(&m_callsign[strlen(m_callsign)-2], "%2x", &checksum_tx);
+                //fprintf(g_logfile, "rx callsign: %s.\n  checksum tx: %02x checksum rx: %02x\n", m_callsign, checksum_tx, checksum_rx);
+
+                wxString s;
+                if (ret && (checksum_tx == checksum_rx)) {
+                    m_callsign[strlen(m_callsign)-2] = 0;
+                    s.Printf("%s", m_callsign);
+                    m_txtCtrlCallSign->SetValue(s);
+
+#ifdef __UDP_EXPERIMENTAL__
+                    char s1[MAX_CALLSIGN];
+                    sprintf(s1,"rx_txtmsg %s", m_callsign);
+                    processTxtEvent(s1);
+
+                    m_checksumGood++;
+                    s.Printf("%d", m_checksumGood);
+                    m_txtChecksumGood->SetLabel(s);              
+#endif
+                }
+                else {
+#ifdef __UDP_EXPERIMENTAL__
+                    m_checksumBad++;
+                    s.Printf("%d", m_checksumBad);
+                    m_txtChecksumBad->SetLabel(s);        
+#endif
+                }
+            }
+
+            //fprintf(g_logfile,"resetting callsign %s %ld\n", m_callsign, m_pcallsign-m_callsign);
+            // reset ptr to start of string
+            m_pcallsign = m_callsign;
+        }
+        else {
+            //fprintf(g_logfile, "new char %d %c\n", ashort, (char)ashort);
+            *m_pcallsign++ = (char)ashort;
+        }
+
+        /* If checksums disabled, display txt chars as they arrive */
+
+        if (!wxGetApp().m_enable_checksum) {
+            m_txtCtrlCallSign->SetValue(m_callsign);
+        }
+    }
+
+    // Run time update of EQ filters -----------------------------------
+    if (m_newMicInFilter || m_newSpkOutFilter) {
+        g_mutexProtectingCallbackData.Lock();
+        deleteEQFilters(g_rxUserdata);
+        designEQFilters(g_rxUserdata);
+        g_mutexProtectingCallbackData.Unlock();
+        m_newMicInFilter = m_newSpkOutFilter = false;
+    }
+    g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+    g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+
+
+    if (g_mode != -1)  {
+
+        // Run time update of FreeDV 700 tx clipper
+
+        freedv_set_clip(g_pfreedv, (int)wxGetApp().m_FreeDV700txClip);
+
+        // Test Frame Bit Error Updates ------------------------------------
+
+        // Toggle test frame mode at run time
+
+        if (!freedv_get_test_frames(g_pfreedv) && wxGetApp().m_testFrames) {
+
+            // reset stats on check box off to on transition
+
+            freedv_set_test_frames(g_pfreedv, 1);
+            freedv_set_total_bits(g_pfreedv, 0);
+            freedv_set_total_bit_errors(g_pfreedv, 0);
+        }
+        freedv_set_test_frames(g_pfreedv, wxGetApp().m_testFrames);
+        g_channel_noise =  wxGetApp().m_channel_noise;
+
+        if (g_State) {
+            char bits[80], errors[80], ber[80];
+
+            // update stats on main page
+
+            sprintf(bits, "Bits: %d", freedv_get_total_bits(g_pfreedv)); wxString bits_string(bits); m_textBits->SetLabel(bits_string);
+            sprintf(errors, "Errs: %d", freedv_get_total_bit_errors(g_pfreedv)); wxString errors_string(errors); m_textErrors->SetLabel(errors_string);
+            float b = (float)freedv_get_total_bit_errors(g_pfreedv)/(1E-6+freedv_get_total_bits(g_pfreedv));
+            sprintf(ber, "BER: %4.3f", b); wxString ber_string(ber); m_textBER->SetLabel(ber_string);
+
+            // update error pattern plots if supported
+
+            int sz_error_pattern = freedv_get_sz_error_pattern(g_pfreedv);
+            if (sz_error_pattern) {
+                short error_pattern[sz_error_pattern];
+
+                if (fifo_read(g_error_pattern_fifo, error_pattern, sz_error_pattern) == 0) {
+                    int i,b;
+
+                    /* both modes map IQ to alternate bits, but one same carrier */
+
+                    if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600) {
+                        /* FreeDV 1600 mapping from error pattern to bit on each carrier */
+
+                        for(b=0; b<g_Nc*2; b++) {
+                            for(i=b; i<sz_error_pattern; i+= 2*g_Nc) {
+                                m_panelTestFrameErrors->add_new_sample(b, b + 0.8*error_pattern[i]);
+                                g_error_hist[b] += error_pattern[i];
+                            }
+                            //if (b%2)
+                            //    printf("g_error_hist[%d]: %d\n", b/2, g_error_hist[b/2]);
+                        }
+
+                        int max_hist = 0;
+                        for(b=0; b<g_Nc; b++)
+                            if (g_error_hist[b] > max_hist)
+                                max_hist = g_error_hist[b];
+
+                        m_panelTestFrameErrorsHist->add_new_short_samples(0, g_error_hist, 2*FDMDV_NC_MAX, max_hist);
+                    }
+       
+                    if ((freedv_get_mode(g_pfreedv) == FREEDV_MODE_700B) || (freedv_get_mode(g_pfreedv) == FREEDV_MODE_700C)) {
+                        int c;
+
+                        /* FreeDV 700 mapping from error pattern to bit on each
+                           carrier.  Note we don't have access to carriers before
+                           diversity re-combination, so this won't give us the full
+                           picture, we have to assume Nc/2 carriers. */
+
+                        for(i=0; i<sz_error_pattern; i++) {
+                            c = i/4;
+                            m_panelTestFrameErrors->add_new_sample(c, c + 0.8*error_pattern[i]);
+                            g_error_hist[c] += error_pattern[i];
+                            //printf("i: %d c: %d\n", i, c);
+                        }
+
+                        int max_hist = 0;
+                        for(b=0; b<g_Nc; b++)
+                            if (g_error_hist[b] > max_hist)
+                                max_hist = g_error_hist[b];
+                        m_panelTestFrameErrorsHist->add_new_short_samples(0, g_error_hist, 2*FDMDV_NC_MAX, max_hist);                
+                    }
+                    m_panelTestFrameErrors->Refresh();       
+                    m_panelTestFrameErrorsHist->Refresh();
+                }
+            }
+        }
+    }
+
+    // command from UDP thread that is best processed in main thread to avoid seg faults
+
+    if (m_schedule_restore) {
+        if (IsIconized())
+            Restore();
+        m_schedule_restore = false;
+    }
+
+#ifdef __UDP_EXPERIMENTAL__
+    // Light Spam Timer LED if at least one timer is running
+
+    int i;
+    optionsDlg->SetSpamTimerLight(false);
+    for(i=0; i<MAX_EVENT_RULES; i++)
+        if (spamTimer[i].IsRunning())
+            optionsDlg->SetSpamTimerLight(true);        
+#endif
+
+    // Blink file playback status line
+
+    if (g_playFileFromRadio) {
+        g_blink += DT;
+        //fprintf(g_logfile, "g_blink: %f\n", g_blink);
+        if ((g_blink >= 1.0) && (g_blink < 2.0))
+            SetStatusText(wxT("Playing into from radio"), 0);
+        if (g_blink >= 2.0) {
+            SetStatusText(wxT(""), 0);
+            g_blink = 0.0;
+        }
+    }
+
+    // Voice Keyer state machine
+
+    VoiceKeyerProcessEvent(VK_DT);
+}
+#endif
+
+
+//-------------------------------------------------------------------------
+// OnCloseFrame()
+//-------------------------------------------------------------------------
+void MainFrame::OnCloseFrame(wxCloseEvent& event)
+{
+    fprintf(stderr, "MainFrame::OnCloseFrame()\n");
+    Pa_Terminate();
+    Destroy();
+}
+
+//-------------------------------------------------------------------------
+// OnTop()
+//-------------------------------------------------------------------------
+void MainFrame::OnTop(wxCommandEvent& event)
+{
+    int style = GetWindowStyle();
+
+    if (style & wxSTAY_ON_TOP)
+    {
+        style &= ~wxSTAY_ON_TOP;
+    }
+    else
+    {
+        style |= wxSTAY_ON_TOP;
+    }
+    SetWindowStyle(style);
+}
+
+//-------------------------------------------------------------------------
+// OnDeleteConfig()
+//-------------------------------------------------------------------------
+void MainFrame::OnDeleteConfig(wxCommandEvent&)
+{
+    wxConfigBase *pConfig = wxConfigBase::Get();
+    if(pConfig->DeleteAll())
+    {
+        wxLogMessage(wxT("Config file/registry key successfully deleted."));
+
+        delete wxConfigBase::Set(NULL);
+        wxConfigBase::DontCreateOnDemand();
+    }
+    else
+    {
+        wxLogError(wxT("Deleting config file/registry key failed."));
+    }
+}
+
+//-------------------------------------------------------------------------
+// Paint()
+//-------------------------------------------------------------------------
+void MainFrame::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+    wxPaintDC dc(this);
+
+    if(GetMenuBar()->IsChecked(ID_PAINT_BG))
+    {
+        dc.Clear();
+    }
+    dc.SetUserScale(m_zoom, m_zoom);
+}
+
+//-------------------------------------------------------------------------
+// OnCmdSliderScroll()
+//-------------------------------------------------------------------------
+void MainFrame::OnCmdSliderScroll(wxScrollEvent& event)
+{
+    char sqsnr[15];
+    g_SquelchLevel = (float)m_sliderSQ->GetValue()/2.0 - 5.0;   
+    sprintf(sqsnr, "%4.1f", g_SquelchLevel); // 0.5 dB steps
+    wxString sqsnr_string(sqsnr);
+    m_textSQ->SetLabel(sqsnr_string);
+
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnCheckSQClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnCheckSQClick(wxCommandEvent& event)
+{
+    if(!g_SquelchActive)
+    {
+        g_SquelchActive = true;
+    }
+    else
+    {
+        g_SquelchActive = false;
+    }
+}
+
+void MainFrame::setsnrBeta(bool snrSlow)
+{
+    if(snrSlow)
+    {
+        m_snrBeta = 0.95; // make this closer to 1.0 to smooth SNR est further
+    }
+    else
+    {
+        m_snrBeta = 0.0; // no smoothing of SNR estimate from demodulator
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnCheckSQClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnCheckSNRClick(wxCommandEvent& event)
+{
+    wxGetApp().m_snrSlow = m_ckboxSNR->GetValue();
+    setsnrBeta(wxGetApp().m_snrSlow);
+    //printf("m_snrSlow: %d\n", (int)wxGetApp().m_snrSlow);
+}
+
+// check for space bar press (only when running)
+
+int MainApp::FilterEvent(wxEvent& event)
+{
+    if ((event.GetEventType() == wxEVT_KEY_DOWN) && 
+        (((wxKeyEvent&)event).GetKeyCode() == WXK_SPACE))
+        {
+            // only use space to toggle PTT if we are running and no modal dialogs (like options) up
+            //fprintf(stderr,"frame->m_RxRunning: %d g_modal: %d\n",
+            //        frame->m_RxRunning, g_modal);
+            if (frame->m_RxRunning && !g_modal) {
+
+                // space bar controls rx/rx if keyer not running
+                if (frame->vk_state == VK_IDLE) {
+                    if (frame->m_btnTogPTT->GetValue())
+                        frame->m_btnTogPTT->SetValue(false);
+                    else
+                        frame->m_btnTogPTT->SetValue(true);
+
+                    frame->togglePTT();
+                }
+                else // spavce bar stops keyer
+                    frame->VoiceKeyerProcessEvent(VK_SPACE_BAR);
+                    
+                return true; // absorb space so we don't toggle control with focus (e.g. Start)
+
+            }
+        }
+
+    return -1;
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnPTT ()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnPTT (wxCommandEvent& event)
+{
+    togglePTT();
+    event.Skip();
+}
+
+void MainFrame::togglePTT(void) {
+
+    // Change tabbed page in centre panel depending on PTT state
+
+    if (g_tx)
+    {
+        // tx-> rx transition, swap to the page we were on for last rx
+        m_auiNbookCtrl->ChangeSelection(wxGetApp().m_rxNbookCtrl);
+    }
+    else
+    {
+        // rx-> tx transition, swap to Mic In page to monitor speech
+        wxGetApp().m_rxNbookCtrl = m_auiNbookCtrl->GetSelection();
+        m_auiNbookCtrl->ChangeSelection(m_auiNbookCtrl->GetPageIndex((wxWindow *)m_panelSpeechIn));
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"ptt"); processTxtEvent(e);
+#endif
+    }
+
+    g_tx = m_btnTogPTT->GetValue();
+
+    // Hamlib PTT
+
+    if (wxGetApp().m_boolHamlibUseForPTT) {        
+        Hamlib *hamlib = wxGetApp().m_hamlib; 
+        wxString hamlibError;
+        if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
+            if (hamlib->ptt(g_tx, hamlibError) == false) {
+                wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+            }
+        }
+    }
+
+    // Serial PTT
+
+    if (wxGetApp().m_boolUseSerialPTT && (wxGetApp().m_serialport->isopen())) {
+        wxGetApp().m_serialport->ptt(g_tx);
+    }
+
+    // reset level gauge
+
+    m_maxLevel = 0;
+    m_textLevel->SetLabel(wxT(""));
+    m_gaugeLevel->SetValue(0);
+}
+
+/*
+   Voice Keyer:
+
+   + space bar turns keyer off
+   + 5 secs of valid sync turns it off
+
+   [X] complete state machine and builds OK
+   [ ] file select dialog
+   [ ] test all states
+   [ ] restore size
+*/
+
+void MainFrame::OnTogBtnVoiceKeyerClick (wxCommandEvent& event)
+{
+    if (vk_state == VK_IDLE)
+        VoiceKeyerProcessEvent(VK_START);
+    else
+        VoiceKeyerProcessEvent(VK_SPACE_BAR);
+        
+    event.Skip();
+}
+
+
+int MainFrame::VoiceKeyerStartTx(void)
+{
+    int next_state;
+
+    // start playing wave file or die trying
+
+    SF_INFO sfInfo;
+    sfInfo.format = 0;
+
+    g_sfPlayFile = sf_open(wxGetApp().m_txtVoiceKeyerWaveFile, SFM_READ, &sfInfo);
+    if(g_sfPlayFile == NULL) {
+        wxString strErr = sf_strerror(NULL);
+        wxMessageBox(strErr, wxT("Couldn't open:") + wxGetApp().m_txtVoiceKeyerWaveFile, wxOK);
+        m_togBtnVoiceKeyer->SetValue(false);
+        next_state = VK_IDLE;
+    }
+    else {
+        SetStatusText(wxT("Voice Keyer: Playing File") + wxGetApp().m_txtVoiceKeyerWaveFile + wxT(" to Mic Input") , 0);
+        g_loopPlayFileToMicIn = false;
+        g_playFileToMicIn = true;
+
+        m_btnTogPTT->SetValue(true); togglePTT();
+        next_state = VK_TX;
+    }
+
+    return next_state;
+}
+
+
+void MainFrame::VoiceKeyerProcessEvent(int vk_event) {
+    int next_state = vk_state;
+
+    switch(vk_state) {
+
+    case VK_IDLE:
+        if (vk_event == VK_START) {
+            // sample these puppies at start just in case they are changed while VK running
+            vk_rx_pause = wxGetApp().m_intVoiceKeyerRxPause;
+            vk_repeats = wxGetApp().m_intVoiceKeyerRepeats;
+            fprintf(stderr, "vk_rx_pause: %d vk_repeats: %d\n", vk_rx_pause, vk_repeats);
+
+            vk_repeat_counter = 0;
+            next_state = VoiceKeyerStartTx();
+        }
+        break;
+        
+     case VK_TX:
+
+        // In this state we are transmitting and playing a wave file
+        // to Mic In
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_btnTogPTT->SetValue(false); togglePTT();
+            StopPlayFileToMicIn();
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        if (vk_event == VK_PLAY_FINISHED) {
+            m_btnTogPTT->SetValue(false); togglePTT();
+            vk_repeat_counter++;
+            if (vk_repeat_counter > vk_repeats) {
+                m_togBtnVoiceKeyer->SetValue(false);
+                next_state = VK_IDLE;
+            }
+            else {
+                vk_rx_time = 0.0;
+                next_state = VK_RX;
+            }
+        }
+
+        break;
+
+     case VK_RX:
+
+        // in this state we are receiving and waiting for
+        // delay timer or valid sync
+
+        if (vk_event == VK_DT) {
+            if (freedv_get_sync(g_pfreedv) == 1) {
+                // if we detect sync simulate a smooth transition to SYNC_WAIT State - TODO: review
+                if (vk_rx_time >= DT) {
+                    vk_rx_time -= DT;
+                } else {
+                    next_state = VK_SYNC_WAIT;
+                }
+            } else {
+                vk_rx_time += DT;
+                if (vk_rx_time >= vk_rx_pause) {
+                    next_state = VoiceKeyerStartTx();
+                }
+            }
+        }
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        break;
+
+     case VK_SYNC_WAIT:
+
+        // In this state we wait for valid sync to last
+        // VK_SYNC_WAIT_TIME seconds
+
+        if (vk_event == VK_SPACE_BAR) {
+            m_togBtnVoiceKeyer->SetValue(false);
+            next_state = VK_IDLE;
+        }
+
+        if (vk_event == VK_DT) {
+            if (freedv_get_sync(g_pfreedv) == 0) {
+                // if we lose sync simulate a smooth transition to return in RX State - TODO: review
+                if (vk_rx_time >= DT) {
+                    vk_rx_time -= DT;
+                } else {
+                    next_state = VK_RX;
+                }
+            } else {
+                vk_rx_time += DT;
+            }
+
+            // drop out of voice keyer if we get a few seconds of valid sync
+
+            if (vk_rx_time >= VK_SYNC_WAIT_TIME) {
+                m_togBtnVoiceKeyer->SetValue(false);
+                next_state = VK_IDLE;
+            }
+        }
+        break;
+
+    default:
+        // catch anything we missed
+
+        m_btnTogPTT->SetValue(false); togglePTT();
+        m_togBtnVoiceKeyer->SetValue(false);
+        next_state = VK_IDLE;
+   }
+
+    if ((vk_event != VK_DT) || (vk_state != next_state))
+        fprintf(stderr, "VoiceKeyerProcessEvent: vk_state: %d vk_event: %d next_state: %d  vk_repeat_counter: %d\n", vk_state, vk_event, next_state, vk_repeat_counter);
+    vk_state = next_state;
+}
+
+
+//-------------------------------------------------------------------------
+// OnTogBtnRxID()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnRxID(wxCommandEvent& event)
+{
+    // empty any junk in rx data FIFO
+    short junk;
+    while(fifo_read(g_rxDataOutFifo,&junk,1) == 0);
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnTxID()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnTxID(wxCommandEvent& event)
+{
+    event.Skip();
+}
+
+void MainFrame::OnTogBtnSplitClick(wxCommandEvent& event) {
+    if (g_split)
+        g_split = 0;
+    else
+        g_split = 1;
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnTogBtnAnalogClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnAnalogClick (wxCommandEvent& event)
+{
+    if (g_analog == 0) {
+        g_analog = 1;
+        m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(FS/2)));
+        m_panelWaterfall->setFs(FS);
+    }
+    else {
+        g_analog = 0;
+        m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(freedv_get_modem_sample_rate(g_pfreedv)/2)));
+        m_panelWaterfall->setFs(freedv_get_modem_sample_rate(g_pfreedv));
+    }
+
+    g_State = 0;
+    g_stats.snr_est = 0;
+
+    event.Skip();
+}
+
+void MainFrame::OnCallSignReset(wxCommandEvent& event)
+{
+    m_pcallsign = m_callsign;
+    memset(m_callsign, 0, MAX_CALLSIGN);
+    wxString s;
+    s.Printf("%s", m_callsign);
+    m_txtCtrlCallSign->SetValue(s);
+#ifdef __UDP__EXPERIMENTAL__
+    m_checksumGood = m_checksumBad = 0;
+    m_txtChecksumGood->SetLabel(_("0"));
+    m_txtChecksumBad->SetLabel(_("0"));
+#endif
+}
+
+void MainFrame::OnBerReset(wxCommandEvent& event)
+{
+    freedv_set_total_bits(g_pfreedv, 0);
+    freedv_set_total_bit_errors(g_pfreedv, 0);
+    int i;
+    for(i=0; i<2*g_Nc; i++)
+        g_error_hist[i] = 0;
+    
+}
+
+#ifdef ALC
+//-------------------------------------------------------------------------
+// OnTogBtnALCClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnALCClick(wxCommandEvent& event)
+{
+    wxMessageBox(wxT("Got Click!"), wxT("OnTogBtnALCClick"), wxOK);
+
+    event.Skip();
+}
+#endif
+
+// extra panel added to file open dialog to add loop checkbox
+MyExtraPlayFilePanel::MyExtraPlayFilePanel(wxWindow *parent): wxPanel(parent)
+{
+    m_cb = new wxCheckBox(this, -1, wxT("Loop"));
+    m_cb->SetToolTip(_("When checked file will repeat forever"));
+    m_cb->SetValue(g_loopPlayFileToMicIn);
+
+    // bug: I can't this to align right.....
+    wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
+    sizerTop->Add(m_cb, 0, wxALIGN_RIGHT, 0);
+    SetSizerAndFit(sizerTop);
+}
+
+static wxWindow* createMyExtraPlayFilePanel(wxWindow *parent)
+{
+    return new MyExtraPlayFilePanel(parent);
+}
+
+void MainFrame::StopPlayFileToMicIn(void)
+{
+    g_mutexProtectingCallbackData.Lock();
+    g_playFileToMicIn = false;
+    sf_close(g_sfPlayFile);
+    SetStatusText(wxT(""));
+    g_mutexProtectingCallbackData.Unlock();
+}
+
+//-------------------------------------------------------------------------
+// OnPlayFileToMicIn()
+//-------------------------------------------------------------------------
+void MainFrame::OnPlayFileToMicIn(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    if(g_playFileToMicIn) {
+        StopPlayFileToMicIn();
+        VoiceKeyerProcessEvent(VK_PLAY_FINISHED);
+    }
+    else
+    {
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+        wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Play File to Mic In"),
+                                    wxGetApp().m_playFileToMicInPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_OPEN | wxFD_FILE_MUST_EXIST
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraPlayFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_playFileToMicInPath, &fileName, &extension);
+        //wxLogDebug("m_playFileToMicInPath: %s", wxGetApp().m_playFileToMicInPath);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = FS;
+            }
+        }
+        g_sfPlayFile = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
+        if(g_sfPlayFile == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+
+        // Huh?! I just copied wxWidgets-2.9.4/samples/dialogs ....
+        g_loopPlayFileToMicIn = static_cast<MyExtraPlayFilePanel*>(ctrl)->getLoopPlayFileToMicIn();
+
+        SetStatusText(wxT("Playing File: ") + fileName + wxT(" to Mic Input") , 0);
+        g_playFileToMicIn = true;
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnPlayFileFromRadio()
+// This puppy "plays" a recorded file into the demodulator input, allowing us
+// to replay off air signals.
+//-------------------------------------------------------------------------
+void MainFrame::OnPlayFileFromRadio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    printf("OnPlayFileFromRadio:: %d\n", (int)g_playFileFromRadio);
+    if (g_playFileFromRadio)
+    {
+        printf("OnPlayFileFromRadio:: Stop\n");
+        g_mutexProtectingCallbackData.Lock();
+        g_playFileFromRadio = false;
+        sf_close(g_sfPlayFileFromRadio);
+        SetStatusText(wxT(""),0);
+        SetStatusText(wxT(""),1);
+        g_mutexProtectingCallbackData.Unlock();
+    }
+    else
+    {
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+        wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Play File - From Radio"),
+                                    wxGetApp().m_playFileFromRadioPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_OPEN | wxFD_FILE_MUST_EXIST
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraPlayFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_playFileFromRadioPath, &fileName, &extension);
+        //wxLogDebug("m_playFileToFromRadioPath: %s", wxGetApp().m_playFileFromRadioPath);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            }
+        }
+        g_sfPlayFileFromRadio = sf_open(soundFile.c_str(), SFM_READ, &sfInfo);
+        g_sfFs = sfInfo.samplerate;
+        if(g_sfPlayFileFromRadio == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+
+        // Huh?! I just copied wxWidgets-2.9.4/samples/dialogs ....
+        g_loopPlayFileFromRadio = static_cast<MyExtraPlayFilePanel*>(ctrl)->getLoopPlayFileToMicIn();
+
+        SetStatusText(wxT("Playing into from radio"), 0);
+        if(extension == wxT("raw")) {
+            wxString stringnumber = wxString::Format(wxT("%d"), (int)sfInfo.samplerate);
+            SetStatusText(wxT("raw file assuming Fs=") + stringnumber, 1);          
+        }
+        fprintf(g_logfile, "OnPlayFileFromRadio:: Playing File\n");
+        g_playFileFromRadio = true;
+        g_blink = 0.0;
+    }
+}
+
+// extra panel added to file save dialog to set number of seconds to record for
+
+MyExtraRecFilePanel::MyExtraRecFilePanel(wxWindow *parent): wxPanel(parent)
+{
+    wxBoxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
+
+    wxStaticText* staticText = new wxStaticText(this, wxID_ANY, _("Seconds:"), wxDefaultPosition, wxDefaultSize, 0);
+    sizerTop->Add(staticText, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    m_secondsToRecord = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0);
+    m_secondsToRecord->SetToolTip(_("Number of seconds to record for"));
+    m_secondsToRecord->SetValue(wxString::Format(wxT("%i"), wxGetApp().m_recFileFromRadioSecs));
+    sizerTop->Add(m_secondsToRecord, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
+    SetSizerAndFit(sizerTop);
+}
+
+static wxWindow* createMyExtraRecFilePanel(wxWindow *parent)
+{
+    return new MyExtraRecFilePanel(parent);
+}
+
+//-------------------------------------------------------------------------
+// OnRecFileFromRadio()
+//-------------------------------------------------------------------------
+void MainFrame::OnRecFileFromRadio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    if (g_recFileFromRadio) {
+        printf("Stopping Record....\n");
+        g_mutexProtectingCallbackData.Lock();
+        g_recFileFromRadio = false;
+        sf_close(g_sfRecFile);
+        SetStatusText(wxT(""));
+        g_mutexProtectingCallbackData.Unlock();
+    }
+    else {
+
+        wxString    soundFile;
+        SF_INFO     sfInfo;
+
+         wxFileDialog openFileDialog(
+                                    this,
+                                    wxT("Record File From Radio"),
+                                    wxGetApp().m_recFileFromRadioPath,
+                                    wxEmptyString,
+                                    wxT("WAV and RAW files (*.wav;*.raw)|*.wav;*.raw|")
+                                    wxT("All files (*.*)|*.*"),
+                                    wxFD_SAVE
+                                    );
+
+        // add the loop check box
+        openFileDialog.SetExtraControlCreator(&createMyExtraRecFilePanel);
+
+        if(openFileDialog.ShowModal() == wxID_CANCEL)
+        {
+            return;     // the user changed their mind...
+        }
+
+        wxString fileName, extension;
+        soundFile = openFileDialog.GetPath();
+        wxFileName::SplitPath(soundFile, &wxGetApp().m_recFileFromRadioPath, &fileName, &extension);
+        wxLogDebug("m_recFileFromRadioPath: %s", wxGetApp().m_recFileFromRadioPath);
+        wxLogDebug("soundFile: %s", soundFile);
+        sfInfo.format = 0;
+
+        if(!extension.IsEmpty())
+        {
+            extension.LowerCase();
+            if(extension == wxT("raw"))
+            {
+                sfInfo.format     = SF_FORMAT_RAW | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            }
+            else if(extension == wxT("wav"))
+            {
+                sfInfo.format     = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+                sfInfo.channels   = 1;
+                sfInfo.samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+            } else {
+                wxMessageBox(wxT("Invalid file format"), wxT("Record File From Radio"), wxOK);
+                return;
+            }
+        }
+        else {
+            wxMessageBox(wxT("Invalid file format"), wxT("Record File From Radio"), wxOK);
+            return;
+        }
+
+        // Bug: on Win32 I cant read m_recFileFromRadioSecs, so have hard coded it
+#ifdef __WIN32__
+        long secs = wxGetApp().m_recFileFromRadioSecs;
+        g_recFromRadioSamples = FS*(unsigned int)secs;
+#else
+        // work out number of samples to record
+
+        wxWindow * const ctrl = openFileDialog.GetExtraControl();
+        wxString secsString = static_cast<MyExtraRecFilePanel*>(ctrl)->getSecondsToRecord();
+        wxLogDebug("test: %s secsString: %s\n", wxT("testing 123"), secsString);
+
+        long secs;
+        if (secsString.ToLong(&secs)) {
+            wxGetApp().m_recFileFromRadioSecs = (unsigned int)secs;
+            //printf(" secondsToRecord: %d\n",  (unsigned int)secs);
+            g_recFromRadioSamples = FS*(unsigned int)secs;
+            //printf("g_recFromRadioSamples: %d\n", g_recFromRadioSamples);
+        }
+        else {
+            wxMessageBox(wxT("Invalid number of Seconds"), wxT("Record File From Radio"), wxOK);
+            return;
+        }
+#endif
+
+        g_sfRecFile = sf_open(soundFile.c_str(), SFM_WRITE, &sfInfo);
+        if(g_sfRecFile == NULL)
+        {
+            wxString strErr = sf_strerror(NULL);
+            wxMessageBox(strErr, wxT("Couldn't open sound file"), wxOK);
+            return;
+        }
+
+        SetStatusText(wxT("Recording File: ") + fileName + wxT(" From Radio") , 0);
+        g_recFileFromRadio = true;
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnExit()
+//-------------------------------------------------------------------------
+void MainFrame::OnExit(wxCommandEvent& event)
+{
+    fprintf(stderr, "MainFrame::OnExit\n");
+    wxUnusedVar(event);
+#ifdef _USE_TIMER
+    m_plotTimer.Stop();
+#endif // _USE_TIMER
+    if(g_sfPlayFile != NULL)
+    {
+        sf_close(g_sfPlayFile);
+        g_sfPlayFile = NULL;
+    }
+    if(g_sfRecFile != NULL)
+    {
+        sf_close(g_sfRecFile);
+        g_sfRecFile = NULL;
+    }
+    if(m_RxRunning)
+    {
+        stopRxStream();
+    }
+    m_togBtnSplit->Disable();
+    //m_togRxID->Disable();
+    //m_togTxID->Disable();
+    m_togBtnAnalog->Disable();
+    //m_togBtnALC->Disable();
+    //m_btnTogPTT->Disable();
+    Pa_Terminate();
+    Destroy();
+}
+
+//-------------------------------------------------------------------------
+// OnExitClick()
+//-------------------------------------------------------------------------
+void MainFrame::OnExitClick(wxCommandEvent& event)
+{
+    OnExit(event);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsAudio()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsAudio(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    int rv = 0;
+    AudioOptsDialog *dlg = new AudioOptsDialog(NULL);
+    rv = dlg->ShowModal();
+    if(rv == wxID_OK)
+    {
+        dlg->ExchangeData(EXCHANGE_DATA_OUT);
+    }
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsAudioUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsAudioUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsFilter()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsFilter(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    FilterDlg *dlg = new FilterDlg(NULL, m_RxRunning, &m_newMicInFilter, &m_newSpkOutFilter);
+    dlg->ShowModal();
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsOptions()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsOptions(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    g_modal = true;
+    //fprintf(stderr,"g_modal: %d\n", g_modal);
+    optionsDlg->Show();
+}
+
+//-------------------------------------------------------------------------
+// OnToolsOptionsUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsOptionsUI(wxUpdateUIEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnToolsComCfg()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsComCfg(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+
+    ComPortsDlg *dlg = new ComPortsDlg(NULL);
+
+    dlg->ShowModal();
+
+    delete dlg;
+}
+
+//-------------------------------------------------------------------------
+// OnToolsComCfgUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsComCfgUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning);
+}
+
+//-------------------------------------------------------------------------
+// OnToolsPlugInCfg()
+//-------------------------------------------------------------------------
+void MainFrame::OnToolsPlugInCfg(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    PlugInDlg *dlg = new PlugInDlg(wxGetApp().m_plugInName, wxGetApp().m_numPlugInParam, wxGetApp().m_plugInParamName);
+    dlg->ShowModal();
+    delete dlg;
+}
+               
+void MainFrame::OnToolsPlugInCfgUI(wxUpdateUIEvent& event)
+{
+    event.Enable(!m_RxRunning && wxGetApp().m_plugIn);
+}
+
+
+//-------------------------------------------------------------------------
+// OnHelpCheckUpdates()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpCheckUpdates(wxCommandEvent& event)
+{
+    wxMessageBox("Got Click!", "OnHelpCheckUpdates", wxOK);
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnHelpCheckUpdatesUI()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpCheckUpdatesUI(wxUpdateUIEvent& event)
+{
+    event.Enable(false);
+}
+
+//-------------------------------------------------------------------------
+//OnHelpAbout()
+//-------------------------------------------------------------------------
+void MainFrame::OnHelpAbout(wxCommandEvent& event)
+{
+    wxUnusedVar(event);
+    wxString msg;
+    msg.Printf( wxT("FreeDV %s\n\n")
+                wxT("Open Source Digital Voice\n\n")
+                wxT("For Help and Support visit: http://freedv.org\n\n")
+
+                wxT("GNU Public License V2.1\n\n")
+                wxT("Copyright (c) David Witten KD0EAG and David Rowe VK5DGR\n\n")
+                wxT("svn revision: %s\n"), FREEDV_VERSION, SVN_REVISION);
+
+    wxMessageBox(msg, wxT("About"), wxOK | wxICON_INFORMATION, this);
+}
+
+
+// Attempt to talk to rig using Hamlib
+
+bool MainFrame::OpenHamlibRig() {
+    if (wxGetApp().m_boolHamlibUseForPTT != true)
+       return false;
+    if (wxGetApp().m_intHamlibRig == 0)
+        return false;
+    if (wxGetApp().m_hamlib == NULL)
+        return false;
+
+    int rig = wxGetApp().m_intHamlibRig;
+    wxString port = wxGetApp().m_strHamlibSerialPort;
+    bool status = wxGetApp().m_hamlib->connect(rig, port.mb_str(wxConvUTF8));
+    if (status == false)
+        wxMessageBox("Couldn't connect to Radio with hamlib", wxT("Error"), wxOK | wxICON_ERROR, this);
+    return status;
+} 
+
+//-------------------------------------------------------------------------
+// OnTogBtnOnOff()
+//-------------------------------------------------------------------------
+void MainFrame::OnTogBtnOnOff(wxCommandEvent& event)
+{
+    wxString startStop = m_togBtnOnOff->GetLabel();
+
+    // we are attempting to start
+
+    if (startStop.IsSameAs("Start"))
+    {
+        //
+        // Start Running -------------------------------------------------
+        //
+
+        // modify some button states when running
+
+        m_togBtnSplit->Enable();
+        m_togBtnAnalog->Enable();
+        m_togBtnOnOff->SetLabel(wxT("Stop"));
+        m_btnTogPTT->Enable();
+        m_togBtnVoiceKeyer->Enable();
+        vk_state = VK_IDLE;
+
+        m_rb1600->Disable();
+        m_rb700b->Disable();
+        m_rb700c->Disable();
+        m_rb800xa->Disable();
+        if (m_rbPlugIn != NULL)
+            m_rbPlugIn->Disable();
+
+        // determine what mode we are using
+
+        if (m_rb1600->GetValue()) {
+            g_mode = FREEDV_MODE_1600;
+            g_Nc = 16;
+            m_panelScatter->setNc(g_Nc);
+        }
+        if (m_rb700b->GetValue()) {
+            g_mode = FREEDV_MODE_700B;
+            g_Nc = 14;
+            m_panelScatter->setNc(g_Nc/2-1);  /* due to diversity, -1 due to no pilot like FreeDV 1600 */
+        }
+        if (m_rb700c->GetValue()) {
+            g_mode = FREEDV_MODE_700C;
+            g_Nc = 14;
+            m_panelScatter->setNc(g_Nc/2-1);  /* due to diversity, -1 due to no pilot like FreeDV 1600 */
+        }
+        if (m_rb800xa->GetValue()) {
+            g_mode = FREEDV_MODE_800XA;
+        }
+        if (m_rbPlugIn != NULL) {
+            if (m_rbPlugIn->GetValue()) {
+                g_mode = -1;  /* TODO; a better way of handling (enumarating?) non-freedv modes */
+
+                /* scale plots assuming Fs = 8000 Hz for now */
+
+                m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ)/8000.0);
+                m_panelWaterfall->setFs(8000.0);
+
+                (wxGetApp().m_plugin_startfp)(wxGetApp().m_plugInStates);
+            }
+        }
+
+        if (g_mode != -1) { 
+            // init freedv states
+
+            g_pfreedv = freedv_open(g_mode);
+            freedv_set_callback_txt(g_pfreedv, &my_put_next_rx_char, &my_get_next_tx_char, NULL);
+
+            freedv_set_callback_error_pattern(g_pfreedv, my_freedv_put_error_pattern, (void*)m_panelTestFrameErrors);
+            g_error_pattern_fifo = fifo_create(2*freedv_get_sz_error_pattern(g_pfreedv));
+            g_error_hist = new short[FDMDV_NC_MAX*2];
+            int i;
+            for(i=0; i<2*FDMDV_NC_MAX; i++)
+                g_error_hist[i] = 0;
+
+            assert(g_pfreedv != NULL);
+
+            // init Codec 2 LPC Post Filter
+
+            codec2_set_lpc_post_filter(freedv_get_codec2(g_pfreedv),
+                                       wxGetApp().m_codec2LPCPostFilterEnable,
+                                       wxGetApp().m_codec2LPCPostFilterBassBoost,
+                                       wxGetApp().m_codec2LPCPostFilterBeta,
+                                       wxGetApp().m_codec2LPCPostFilterGamma);
+
+            // Init Speex pre-processor states
+            // by inspecting Speex source it seems that only denoiser is on be default
+
+            g_speex_st = speex_preprocess_state_init(freedv_get_n_speech_samples(g_pfreedv), FS); 
+
+            // adjust spectrum and waterfall freq scaling base on mode
+
+            m_panelSpectrum->setFreqScale(MODEM_STATS_NSPEC*((float)MAX_F_HZ/(freedv_get_modem_sample_rate(g_pfreedv)/2)));
+            m_panelWaterfall->setFs(freedv_get_modem_sample_rate(g_pfreedv));
+
+            // Init text msg decoding
+
+            freedv_set_varicode_code_num(g_pfreedv, wxGetApp().m_textEncoding);
+        }
+
+        modem_stats_open(&g_stats);
+        g_State = 0;
+        g_snr = 0.0;
+        g_half_duplex = wxGetApp().m_boolHalfDuplex;
+
+        if (g_mode == FREEDV_MODE_800XA) {
+            m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_EYE);
+        }
+        else {
+            m_panelScatter->setEyeScatter(PLOT_SCATTER_MODE_SCATTER);
+        }
+
+        m_pcallsign = m_callsign;
+        memset(m_callsign, 0, sizeof(m_callsign));
+#ifdef __UDP_EXPERIMENTAL__
+        m_checksumGood = m_checksumBad = 0;
+        wxString s;
+        s.Printf("%d", m_checksumGood);
+        m_txtChecksumGood->SetLabel(s);              
+        s.Printf("%d", m_checksumBad);
+        m_txtChecksumBad->SetLabel(s);        
+#endif
+
+        m_maxLevel = 0;
+        m_textLevel->SetLabel(wxT(""));
+        m_gaugeLevel->SetValue(0);
+
+        //printf("m_textEncoding = %d\n", wxGetApp().m_textEncoding);
+        //printf("g_stats.snr: %f\n", g_stats.snr_est);
+
+        // attempt to start PTT ......
+        
+        if (wxGetApp().m_boolHamlibUseForPTT)
+            OpenHamlibRig();
+        if (wxGetApp().m_boolUseSerialPTT) {
+            OpenSerialPort();
+        }
+
+        // attempt to start sound cards and tx/rx processing
+
+        startRxStream();
+
+        if (m_RxRunning)
+        {
+#ifdef _USE_TIMER
+            m_plotTimer.Start(_REFRESH_TIMER_PERIOD, wxTIMER_CONTINUOUS);
+#endif // _USE_TIMER
+        }
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"start"); processTxtEvent(e);
+#endif
+    }
+
+    // Stop was pressed or start up failed
+
+    if (startStop.IsSameAs("Stop") || !m_RxRunning ) {
+
+        //
+        // Stop Running -------------------------------------------------
+        //
+
+#ifdef __UDP_EXPERIMENTAL__
+        optionsDlg->SetSpamTimerLight(false);
+#endif
+
+#ifdef _USE_TIMER
+        m_plotTimer.Stop();
+#endif // _USE_TIMER
+
+        // ensure we are not transmitting and shut down audio processing
+
+        if (wxGetApp().m_boolHamlibUseForPTT) {
+            Hamlib *hamlib = wxGetApp().m_hamlib; 
+            wxString hamlibError;
+            if (wxGetApp().m_boolHamlibUseForPTT && hamlib != NULL) {
+                if (hamlib->ptt(false, hamlibError) == false) {
+                    wxMessageBox(wxString("Hamlib PTT Error: ") + hamlibError, wxT("Error"), wxOK | wxICON_ERROR, this);
+                }
+                hamlib->close();
+            }
+        }
+
+        if (wxGetApp().m_boolUseSerialPTT) {
+            CloseSerialPort();
+        }
+
+        m_btnTogPTT->SetValue(false);
+        VoiceKeyerProcessEvent(VK_SPACE_BAR);
+
+        stopRxStream();
+        modem_stats_close(&g_stats);
+
+        // free up states, clean up
+
+        if (g_mode == -1) {
+            // PlugIn clean up
+            (wxGetApp().m_plugin_stopfp)(wxGetApp().m_plugInStates);
+        }
+        else {
+            // FreeDV clean up
+            delete g_error_hist;
+            fifo_destroy(g_error_pattern_fifo);
+            freedv_close(g_pfreedv);
+            speex_preprocess_state_destroy(g_speex_st);
+        }
+
+        m_newMicInFilter = m_newSpkOutFilter = true;
+
+        m_togBtnSplit->Disable();
+        //m_togRxID->Disable();
+        //m_togTxID->Disable();
+        m_togBtnAnalog->Disable();
+        m_btnTogPTT->Disable();
+        m_togBtnVoiceKeyer->Disable();
+        m_togBtnOnOff->SetLabel(wxT("Start"));
+        m_rb1600->Enable();
+        m_rb700b->Enable();
+        m_rb700c->Enable();
+        m_rb800xa->Enable();
+        if (m_rbPlugIn != NULL)
+            m_rbPlugIn->Enable();
+           
+#ifdef DISABLED_FEATURE
+        m_rb700->Enable();
+        m_rb1400old->Enable();
+        m_rb1600Wide->Enable();
+        m_rb1400->Enable();
+        m_rb2000->Enable();
+#endif
+#ifdef __UDP_EXPERIMENTAL__
+        char e[80]; sprintf(e,"stop"); processTxtEvent(e);
+#endif
+    }
+}
+
+//-------------------------------------------------------------------------
+// stopRxStream()
+//-------------------------------------------------------------------------
+void MainFrame::stopRxStream()
+{
+    if(m_RxRunning)
+    {
+        m_RxRunning = false;
+
+        fprintf(stderr, "waiting for thread to stop\n");
+        m_txRxThread->m_run = 0;
+        m_txRxThread->Wait();
+        fprintf(stderr, "thread stopped\n");
+
+        m_rxInPa->stop();
+        m_rxInPa->streamClose();
+        delete m_rxInPa;
+        if(m_rxOutPa != m_rxInPa) {
+                       m_rxOutPa->stop();
+                       m_rxOutPa->streamClose();
+                       delete m_rxOutPa;
+               }
+
+        if (g_nSoundCards == 2) {
+            m_txInPa->stop();
+            m_txInPa->streamClose();
+            delete m_txInPa;
+            if(m_txInPa != m_txOutPa) {
+                               m_txOutPa->stop();
+                               m_txOutPa->streamClose();
+                               delete m_txOutPa;
+                       }
+        }
+
+        destroy_fifos();
+        destroy_src();
+        deleteEQFilters(g_rxUserdata);
+        delete g_rxUserdata;
+    }
+}
+
+void MainFrame::destroy_fifos(void)
+{
+    fifo_destroy(g_rxUserdata->infifo1);
+    fifo_destroy(g_rxUserdata->outfifo1);
+    fifo_destroy(g_rxUserdata->infifo2);
+    fifo_destroy(g_rxUserdata->outfifo2);
+    fifo_destroy(g_rxUserdata->rxinfifo);
+    fifo_destroy(g_rxUserdata->rxoutfifo);
+}
+
+void MainFrame::destroy_src(void)
+{
+    src_delete(g_rxUserdata->insrc1);
+    src_delete(g_rxUserdata->outsrc1);
+    src_delete(g_rxUserdata->insrc2);
+    src_delete(g_rxUserdata->outsrc2);
+    src_delete(g_rxUserdata->insrcsf);
+}
+
+void  MainFrame::initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice,
+                                     int soundCard, int sampleRate, int inputChannels)
+{
+    // Note all of the wrapper functions below just set values in a
+    // portaudio struct so can't return any errors. So no need to trap
+    // any errors in this function.
+
+    // init input params
+
+    pa->setInputDevice(inDevice);
+    if(inDevice != paNoDevice) {
+        pa->setInputChannelCount(inputChannels);           // stereo input
+        pa->setInputSampleFormat(PA_SAMPLE_TYPE);
+        pa->setInputLatency(pa->getInputDefaultLowLatency());
+        pa->setInputHostApiStreamInfo(NULL);
+    }
+
+    pa->setOutputDevice(paNoDevice);
+    
+    // init output params
+    
+    pa->setOutputDevice(outDevice);
+    if(outDevice != paNoDevice) {
+        pa->setOutputChannelCount(2);                      // stereo output
+        pa->setOutputSampleFormat(PA_SAMPLE_TYPE);
+        pa->setOutputLatency(pa->getOutputDefaultLowLatency());
+        pa->setOutputHostApiStreamInfo(NULL);
+    }
+
+    // init params that affect input and output
+
+    /*
+      On Linux, setting this to wxGetApp().m_framesPerBuffer caused
+      intermittant break up on the audio from my IC7200 on Ubuntu 14.
+      After a day of bug hunting I found that 0, as recommended by the
+      PortAudio docunmentation, fixed the problem.
+    */
+
+    //pa->setFramesPerBuffer(wxGetApp().m_framesPerBuffer);
+    pa->setFramesPerBuffer(0);
+
+    pa->setSampleRate(sampleRate);
+    pa->setStreamFlags(paClipOff);
+}
+
+//-------------------------------------------------------------------------
+// startRxStream()
+//-------------------------------------------------------------------------
+void MainFrame::startRxStream()
+{
+    int   src_error;
+    const PaDeviceInfo *deviceInfo1 = NULL, *deviceInfo2 = NULL;
+    int   inputChannels1, inputChannels2;
+    bool  two_rx=false;
+    bool  two_tx=false;
+
+    if(!m_RxRunning) {
+        m_RxRunning = true;
+
+        if(Pa_Initialize())
+        {
+            wxMessageBox(wxT("Port Audio failed to initialize"), wxT("Pa_Initialize"), wxOK);
+        }
+
+        m_rxInPa = new PortAudioWrap();
+        if(g_soundCard1InDeviceNum != g_soundCard1OutDeviceNum)
+            two_rx=true;
+        if(g_soundCard2InDeviceNum != g_soundCard2OutDeviceNum)
+            two_tx=true;
+        
+        fprintf(g_logfile, "two_rx: %d two_tx: %d\n", two_rx, two_tx);
+        if(two_rx)
+            m_rxOutPa = new PortAudioWrap();
+        else
+            m_rxOutPa = m_rxInPa;
+
+        if (g_nSoundCards == 0) {
+            wxMessageBox(wxT("No Sound Cards configured, use Tools - Audio Config to configure"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+
+        // Init Sound card 1 ----------------------------------------------
+        // sanity check on sound card device numbers
+
+        if ((m_rxInPa->getDeviceCount() <= g_soundCard1InDeviceNum) ||
+            (m_rxOutPa->getDeviceCount() <= g_soundCard1OutDeviceNum)) {
+            wxMessageBox(wxT("Sound Card 1 not present"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                               delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+
+        // work out how many input channels this device supports.
+
+        deviceInfo1 = Pa_GetDeviceInfo(g_soundCard1InDeviceNum);
+        if (deviceInfo1 == NULL) {
+            wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
+            delete m_rxInPa;
+            if(two_rx)
+                               delete m_rxOutPa;
+            m_RxRunning = false;
+            return;
+        }
+        if (deviceInfo1->maxInputChannels == 1)
+            inputChannels1 = 1;
+        else
+            inputChannels1 = 2;
+
+        if(two_rx) {
+            initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, paNoDevice, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+            initPortAudioDevice(m_rxOutPa, paNoDevice, g_soundCard1OutDeviceNum, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+               }
+        else
+            initPortAudioDevice(m_rxInPa, g_soundCard1InDeviceNum, g_soundCard1OutDeviceNum, 1,
+                            g_soundCard1SampleRate, inputChannels1);
+
+        // Init Sound Card 2 ------------------------------------------------
+
+        if (g_nSoundCards == 2) {
+
+            m_txInPa = new PortAudioWrap();
+            if(two_tx)
+                m_txOutPa = new PortAudioWrap();
+            else
+                m_txOutPa = m_txInPa;
+
+            // sanity check on sound card device numbers
+
+            //printf("m_txInPa->getDeviceCount(): %d\n", m_txInPa->getDeviceCount());
+            //printf("g_soundCard2InDeviceNum: %d\n", g_soundCard2InDeviceNum);
+            //printf("g_soundCard2OutDeviceNum: %d\n", g_soundCard2OutDeviceNum);
+
+            if ((m_txInPa->getDeviceCount() <= g_soundCard2InDeviceNum) ||
+                (m_txOutPa->getDeviceCount() <= g_soundCard2OutDeviceNum)) {
+                wxMessageBox(wxT("Sound Card 2 not present"), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                if(two_rx)
+                    delete m_rxOutPa;
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                m_RxRunning = false;
+                return;
+            }
+
+            deviceInfo2 = Pa_GetDeviceInfo(g_soundCard2InDeviceNum);
+            if (deviceInfo2 == NULL) {
+                wxMessageBox(wxT("Couldn't get device info from Port Audio for Sound Card 1"), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                if(two_rx)
+                                       delete m_rxOutPa;
+                delete m_txInPa;
+                if(two_tx)
+                                       delete m_txOutPa;
+                m_RxRunning = false;
+                return;
+            }
+            if (deviceInfo2->maxInputChannels == 1)
+                inputChannels2 = 1;
+            else
+                inputChannels2 = 2;
+
+            if(two_tx) {
+                               initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, paNoDevice, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+                               initPortAudioDevice(m_txOutPa, paNoDevice, g_soundCard2OutDeviceNum, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+                       }
+                       else
+                               initPortAudioDevice(m_txInPa, g_soundCard2InDeviceNum, g_soundCard2OutDeviceNum, 2,
+                                g_soundCard2SampleRate, inputChannels2);
+        }
+
+        // Init call back data structure ----------------------------------------------
+
+        g_rxUserdata = new paCallBackData;
+        g_rxUserdata->inputChannels1 = inputChannels1;
+        if (deviceInfo2 != NULL)
+            g_rxUserdata->inputChannels2 = inputChannels2;
+
+        // init sample rate conversion states
+
+        g_rxUserdata->insrc1 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrc1 != NULL);
+        g_rxUserdata->outsrc1 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->outsrc1 != NULL);
+        g_rxUserdata->insrc2 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrc2 != NULL);
+        g_rxUserdata->outsrc2 = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->outsrc2 != NULL);
+
+        g_rxUserdata->insrcsf = src_new(SRC_SINC_FASTEST, 1, &src_error);
+        assert(g_rxUserdata->insrcsf != NULL);
+
+        // create FIFOs used to interface between different buffer sizes
+
+        g_rxUserdata->infifo1 = fifo_create(8*N48);
+        g_rxUserdata->outfifo1 = fifo_create(10*N48);
+        g_rxUserdata->outfifo2 = fifo_create(8*N48);
+        g_rxUserdata->infifo2 = fifo_create(8*N48);
+        printf("N48: %d\n", N48);
+
+        g_rxUserdata->rxinfifo = fifo_create(10 * N8);
+        g_rxUserdata->rxoutfifo = fifo_create(10 * N8);
+
+        // Init Equaliser Filters ------------------------------------------------------
+
+        m_newMicInFilter = m_newSpkOutFilter = true;
+        designEQFilters(g_rxUserdata);
+        g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+        g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+
+        // optional tone in left channel to reliably trigger vox
+        
+        g_rxUserdata->leftChannelVoxTone = wxGetApp().m_leftChannelVoxTone;
+        g_rxUserdata->voxTonePhase = 0;
+
+        // Start sound card 1 ----------------------------------------------------------
+
+        m_rxInPa->setUserData(g_rxUserdata);
+        m_rxErr = m_rxInPa->setCallback(rxCallback);
+
+        m_rxErr = m_rxInPa->streamOpen();
+
+        if(m_rxErr != paNoError) {
+            wxMessageBox(wxT("Sound Card 1 Open/Setup error."), wxT("Error"), wxOK);
+                       delete m_rxInPa;
+                       if(two_rx)
+                               delete m_rxOutPa;
+                       delete m_txInPa;
+                       if(two_tx)
+                               delete m_txOutPa;
+            destroy_fifos();
+            destroy_src();
+            deleteEQFilters(g_rxUserdata);
+            delete g_rxUserdata;
+            m_RxRunning = false;
+            return;
+        }
+
+        m_rxErr = m_rxInPa->streamStart();
+        if(m_rxErr != paNoError) {
+            wxMessageBox(wxT("Sound Card 1 Stream Start Error."), wxT("Error"), wxOK);
+                       delete m_rxInPa;
+                       if(two_rx)
+                               delete m_rxOutPa;
+                       delete m_txInPa;
+                       if(two_tx)
+                               delete m_txOutPa;
+            destroy_fifos();
+            destroy_src();
+            deleteEQFilters(g_rxUserdata);
+            delete g_rxUserdata;
+            m_RxRunning = false;
+            return;
+        }
+
+        // Start separate output stream if needed
+
+        if(two_rx) {
+            m_rxOutPa->setUserData(g_rxUserdata);
+            m_rxErr = m_rxOutPa->setCallback(rxCallback);
+
+            m_rxErr = m_rxOutPa->streamOpen();
+
+            if(m_rxErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 1 Second Stream Open/Setup error."), wxT("Error"), wxOK);
+                delete m_rxInPa;
+                delete m_rxOutPa;
+                delete m_txOutPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+
+            m_rxErr = m_rxOutPa->streamStart();
+            if(m_rxErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 1 Second Stream Start Error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                delete m_rxOutPa;
+                delete m_txOutPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+        }
+
+        // Start sound card 2 ----------------------------------------------------------
+
+        if (g_nSoundCards == 2) {
+
+            // question: can we use same callback data
+            // (g_rxUserdata)or both sound card callbacks?  Is there a
+            // chance of them both being called at the same time?  We
+            // could need a mutex ...
+
+            m_txInPa->setUserData(g_rxUserdata);
+            m_txErr = m_txInPa->setCallback(txCallback);
+            m_txErr = m_txInPa->streamOpen();
+
+            if(m_txErr != paNoError) {
+                fprintf(stderr, "Err: %d\n", m_txErr);
+                wxMessageBox(wxT("Sound Card 2 Open/Setup error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                if(two_rx) {
+                    m_rxOutPa->stop();
+                    m_rxOutPa->streamClose();
+                    delete m_rxOutPa;
+                }
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+            m_txErr = m_txInPa->streamStart();
+            if(m_txErr != paNoError) {
+                wxMessageBox(wxT("Sound Card 2 Start Error."), wxT("Error"), wxOK);
+                m_rxInPa->stop();
+                m_rxInPa->streamClose();
+                delete m_rxInPa;
+                if(two_rx) {
+                    m_rxOutPa->stop();
+                    m_rxOutPa->streamClose();
+                    delete m_rxOutPa;
+                }
+                delete m_txInPa;
+                if(two_tx)
+                    delete m_txOutPa;
+                destroy_fifos();
+                destroy_src();
+                deleteEQFilters(g_rxUserdata);
+                delete g_rxUserdata;
+                m_RxRunning = false;
+                return;
+            }
+
+            // Start separate output stream if needed
+
+            if (two_tx) {
+
+                // question: can we use same callback data
+                // (g_rxUserdata)or both sound card callbacks?  Is there a
+                // chance of them both being called at the same time?  We
+                // could need a mutex ...
+
+                m_txOutPa->setUserData(g_rxUserdata);
+                m_txErr = m_txOutPa->setCallback(txCallback);
+                m_txErr = m_txOutPa->streamOpen();
+
+                if(m_txErr != paNoError) {
+                    wxMessageBox(wxT("Sound Card 2 Second Stream Open/Setup error."), wxT("Error"), wxOK);
+                    m_rxInPa->stop();
+                    m_rxInPa->streamClose();
+                    delete m_rxInPa;
+                    if(two_rx) {
+                        m_rxOutPa->stop();
+                        m_rxOutPa->streamClose();
+                        delete m_rxOutPa;
+                    }
+                    m_txInPa->stop();
+                    m_txInPa->streamClose();
+                    delete m_txInPa;
+                    delete m_txOutPa;
+                    destroy_fifos();
+                    destroy_src();
+                    deleteEQFilters(g_rxUserdata);
+                    delete g_rxUserdata;
+                    m_RxRunning = false;
+                    return;
+                }
+                m_txErr = m_txOutPa->streamStart();
+                if(m_txErr != paNoError) {
+                    wxMessageBox(wxT("Sound Card 2 Second Stream Start Error."), wxT("Error"), wxOK);
+                    m_rxInPa->stop();
+                    m_rxInPa->streamClose();
+                    m_txInPa->stop();
+                    m_txInPa->streamClose();
+                    delete m_txInPa;
+                    if(two_rx) {
+                        m_rxOutPa->stop();
+                        m_rxOutPa->streamClose();
+                        delete m_rxOutPa;
+                    }
+                    delete m_txInPa;
+                    delete m_txOutPa;
+                    destroy_fifos();
+                    destroy_src();
+                    deleteEQFilters(g_rxUserdata);
+                    delete g_rxUserdata;
+                    m_RxRunning = false;
+                    return;
+                }
+            }
+        }
+
+        // start tx/rx processing thread
+
+        m_txRxThread = new txRxThread;
+
+        if ( m_txRxThread->Create() != wxTHREAD_NO_ERROR )
+        {
+            wxLogError(wxT("Can't create thread!"));
+        }
+
+        m_txRxThread->SetPriority(WXTHREAD_MAX_PRIORITY);
+
+        if ( m_txRxThread->Run() != wxTHREAD_NO_ERROR )
+        {
+            wxLogError(wxT("Can't start thread!"));
+        }
+
+    }
+}
+
+
+void MainFrame::processTxtEvent(char event[]) {
+    int rule = 0;
+
+    //printf("processTxtEvent:\n");
+    //printf("  event: %s\n", event);
+
+    // process with regexp and issue system command
+
+    // Each regexp in our list is separated by a newline.  We want to try all of them.
+
+    wxString event_str(event);
+    int match_end, replace_end;
+    match_end = replace_end = 0;
+    wxString regexp_match_list = wxGetApp().m_events_regexp_match;
+    wxString regexp_replace_list = wxGetApp().m_events_regexp_replace;
+
+    bool found_match = false;
+
+    while (((match_end = regexp_match_list.Find('\n')) != wxNOT_FOUND) && (rule < MAX_EVENT_RULES)) {
+        //printf("match_end: %d\n", match_end);
+        if ((replace_end = regexp_replace_list.Find('\n')) != wxNOT_FOUND) {
+            //printf("replace_end = %d\n", replace_end);
+
+            // candidate match and replace regexps strings exist, so lets try them
+
+            wxString regexp_match = regexp_match_list.SubString(0, match_end-1);
+            wxString regexp_replace = regexp_replace_list.SubString(0, replace_end-1);
+            //printf("match: %s replace: %s\n", (const char *)regexp_match.c_str(), (const char *)regexp_replace.c_str());
+            wxRegEx re(regexp_match);
+            //printf("  checking for match against: %s\n", (const char *)regexp_match.c_str());
+
+            // if we found a match, lets run the replace regexp and issue the system command
+
+            wxString event_str_rep = event_str;
+           
+            if (re.Replace(&event_str_rep, regexp_replace) != 0) {
+                fprintf(stderr, "  found match! event_str: %s\n", (const char *)event_str.c_str());
+                found_match = true;
+
+                bool enableSystem = false;
+                if (wxGetApp().m_events)
+                    enableSystem = true;
+
+                // no syscall if spam timer still running
+
+                if (spamTimer[rule].IsRunning()) {
+                    enableSystem = false;
+                    fprintf(stderr, "  spam timer running\n");
+                }
+
+                const char *event_out = event_str_rep.ToUTF8();
+                wxString event_out_with_return_code;
+
+                if (enableSystem) {
+                    int ret = wxExecute(event_str_rep);
+                    event_out_with_return_code.Printf(_T("%s -> returned %d"), event_out, ret);
+                    spamTimer[rule].Start((wxGetApp().m_events_spam_timer)*1000, wxTIMER_ONE_SHOT);
+                }
+                else
+                    event_out_with_return_code.Printf(_T("%s T: %d"), event_out, spamTimer[rule].IsRunning());
+
+                // update event log GUI if currently displayed
+                
+                if (optionsDlg != NULL) {                  
+                    optionsDlg->updateEventLog(wxString(event), event_out_with_return_code);                     
+                }
+            }
+        }
+        regexp_match_list = regexp_match_list.SubString(match_end+1, regexp_match_list.length());
+        regexp_replace_list = regexp_replace_list.SubString(replace_end+1, regexp_replace_list.length());
+
+        rule++;
+    }
+    if ((optionsDlg != NULL) && !found_match) {                  
+        optionsDlg->updateEventLog(wxString(event), _("<no match>"));                     
+    }
+}
+
+
+#define SBQ_MAX_ARGS 4
+
+void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q)
+{
+    char  *arg[SBQ_MAX_ARGS];
+    char   argstorage[SBQ_MAX_ARGS][80];
+    void  *sbq;
+    int    i, argc;
+
+    assert((strcmp(filterType, "bass") == 0)   ||
+           (strcmp(filterType, "treble") == 0) ||
+           (strcmp(filterType, "equalizer") == 0));
+
+    for(i=0; i<SBQ_MAX_ARGS; i++) {
+        arg[i] = &argstorage[i][0];
+        arg[i] = &argstorage[i][0];
+        arg[i] = &argstorage[i][0];
+    }
+
+    argc = 0;
+
+    if ((strcmp(filterType, "bass") == 0) || (strcmp(filterType, "treble") == 0)) {
+        sprintf(arg[argc++], "%s", filterType);
+        sprintf(arg[argc++], "%f", gaindB+1E-6);
+        sprintf(arg[argc++], "%f", freqHz);
+    }
+
+    if (strcmp(filterType, "equalizer") == 0) {
+        sprintf(arg[argc++], "%s", filterType);
+        sprintf(arg[argc++], "%f", freqHz);
+        sprintf(arg[argc++], "%f", Q);
+        sprintf(arg[argc++], "%f", gaindB+1E-6);
+    }
+
+    assert(argc <= SBQ_MAX_ARGS);
+
+    sbq = sox_biquad_create(argc-1, (const char **)arg);
+    assert(sbq != NULL);
+
+    return sbq;
+}
+
+void  MainFrame::designEQFilters(paCallBackData *cb)
+{
+    // init Mic In Equaliser Filters
+
+    if (m_newMicInFilter) {
+        //printf("designing new Min In filters\n");
+        cb->sbqMicInBass   = designAnEQFilter("bass", wxGetApp().m_MicInBassFreqHz, wxGetApp().m_MicInBassGaindB);
+        cb->sbqMicInTreble = designAnEQFilter("treble", wxGetApp().m_MicInTrebleFreqHz, wxGetApp().m_MicInTrebleGaindB);
+        cb->sbqMicInMid    = designAnEQFilter("equalizer", wxGetApp().m_MicInMidFreqHz, wxGetApp().m_MicInMidGaindB, wxGetApp().m_MicInMidQ);
+    }
+
+    // init Spk Out Equaliser Filters
+
+    if (m_newSpkOutFilter) {
+        //printf("designing new Spk Out filters\n");
+        //printf("designEQFilters: wxGetApp().m_SpkOutBassFreqHz: %f\n",wxGetApp().m_SpkOutBassFreqHz);
+        cb->sbqSpkOutBass   = designAnEQFilter("bass", wxGetApp().m_SpkOutBassFreqHz, wxGetApp().m_SpkOutBassGaindB);
+        cb->sbqSpkOutTreble = designAnEQFilter("treble", wxGetApp().m_SpkOutTrebleFreqHz, wxGetApp().m_SpkOutTrebleGaindB);
+        cb->sbqSpkOutMid    = designAnEQFilter("equalizer", wxGetApp().m_SpkOutMidFreqHz, wxGetApp().m_SpkOutMidGaindB, wxGetApp().m_SpkOutMidQ);
+    }
+}
+
+void  MainFrame::deleteEQFilters(paCallBackData *cb)
+{
+    if (m_newMicInFilter) {
+        sox_biquad_destroy(cb->sbqMicInBass);
+        sox_biquad_destroy(cb->sbqMicInTreble);
+        sox_biquad_destroy(cb->sbqMicInMid);
+    }
+    if (m_newSpkOutFilter) {
+        sox_biquad_destroy(cb->sbqSpkOutBass);
+        sox_biquad_destroy(cb->sbqSpkOutTreble);
+        sox_biquad_destroy(cb->sbqSpkOutMid);
+    }
+}
+
+// returns number of output samples generated by resampling
+int resample(SRC_STATE *src,
+            short      output_short[],
+            short      input_short[],
+            int        output_sample_rate,
+            int        input_sample_rate,
+            int        length_output_short, // maximum output array length in samples
+            int        length_input_short
+            )
+{
+    SRC_DATA src_data;
+    float    input[N48*4];
+    float    output[N48*4];
+    int      ret;
+
+    assert(src != NULL);
+    assert(length_input_short <= N48*4);
+    assert(length_output_short <= N48*4);
+
+    src_short_to_float_array(input_short, input, length_input_short);
+
+    src_data.data_in = input;
+    src_data.data_out = output;
+    src_data.input_frames = length_input_short;
+    src_data.output_frames = length_output_short;
+    src_data.end_of_input = 0;
+    src_data.src_ratio = (float)output_sample_rate/input_sample_rate;
+
+    ret = src_process(src, &src_data);
+    assert(ret == 0);
+
+    assert(src_data.output_frames_gen <= length_output_short);
+    src_float_to_short_array(output, output_short, src_data.output_frames_gen);
+
+    return src_data.output_frames_gen;
+}
+
+
+// Decimates samples using an algorithm that produces nice plots of
+// speech signals at a low sample rate.  We want a low sample rate so
+// we don't hammer the graphics system too hard.  Saves decimated data
+// to a fifo for plotting on screen.
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length, int fs)
+{
+    int decimation = fs/WAVEFORM_PLOT_FS;
+    int nSamples, sample;
+    int i, st, en, max, min;
+    short dec_samples[length];
+
+    nSamples = length/decimation;
+
+    for(sample = 0; sample < nSamples; sample += 2)
+    {
+        st = decimation*sample;
+        en = decimation*(sample+2);
+        max = min = 0;
+        for(i=st; i<en; i++ )
+        {
+            if (max < buf[i]) max = buf[i];
+            if (min > buf[i]) min = buf[i];
+        }
+        dec_samples[sample] = max;
+        dec_samples[sample+1] = min;
+    }
+    fifo_write(plotFifo, dec_samples, nSamples);
+}
+
+void txRxProcessing()
+{
+
+    paCallBackData  *cbData = g_rxUserdata;
+
+    // Buffers re-used by tx and rx processing
+    // signals in in48k/out48k are at a maximum sample rate of 48k, could be 44.1kHz
+    // depending on sound hardware.
+
+    short           in8k_short[4*N8];
+    short           in48k_short[4*N48];
+    short           out8k_short[4*N8];
+    short           out48k_short[4*N48];
+    int             nout, samplerate, n_samples;
+
+    //fprintf(g_logfile, "start infifo1: %5d outfifo2: %5d\n", fifo_used(cbData->infifo1), fifo_used(cbData->outfifo2));
+
+    // FreeDV 700 uses a modem sample rate of 7500 Hz which requires some special treatment
+
+    if (g_analog || g_mode == -1) 
+        samplerate = FS;
+    else
+        samplerate = freedv_get_modem_sample_rate(g_pfreedv);
+
+    //
+    //  RX side processing --------------------------------------------
+    //
+
+    // while we have enough input samples available ...
+
+    int nsam = g_soundCard1SampleRate * (float)N8/FS;
+    assert(nsam <= N48);
+    g_mutexProtectingCallbackData.Lock();
+    while ((fifo_read(cbData->infifo1, in48k_short, nsam) == 0) && ((g_half_duplex && !g_tx) || !g_half_duplex)) 
+    {
+        g_mutexProtectingCallbackData.Unlock();
+        unsigned int n8k;
+
+        n8k = resample(cbData->insrc1, in8k_short, in48k_short, samplerate, g_soundCard1SampleRate, N8, nsam);
+        assert(n8k <= N8);
+
+        // optionally save "from radio" signal (write demod input to file)
+        // Really useful for testing and development as it allows us
+        // to repeat tests using off air signals
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_recFileFromRadio && (g_sfRecFile != NULL)) {
+            //printf("g_recFromRadioSamples: %d  n8k: %d \n", g_recFromRadioSamples);
+            if (g_recFromRadioSamples < n8k) {
+                sf_write_short(g_sfRecFile, in8k_short, g_recFromRadioSamples);
+                wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_recFileFromRadioEventId );
+                // call stop/start record menu item, should be thread safe
+                g_parent->GetEventHandler()->AddPendingEvent( event );
+                g_recFromRadioSamples = 0;
+                //printf("finished recording g_recFromRadioSamples: %d n8k: %d!\n", g_recFileFromRadio, n8k);
+            }
+            else {
+                sf_write_short(g_sfRecFile, in8k_short, n8k);
+                g_recFromRadioSamples -= n8k;
+            }
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        // optionally read "from radio" signal from file (read demod input from file)
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_playFileFromRadio && (g_sfPlayFileFromRadio != NULL)) {
+            unsigned int nsf = n8k*g_sfFs/samplerate;
+            short        insf_short[nsf];
+            unsigned int n = sf_read_short(g_sfPlayFileFromRadio, insf_short, nsf);
+            n8k = resample(cbData->insrcsf, in8k_short, insf_short, samplerate, g_sfFs, N8, nsf);
+            //fprintf(g_logfile, "n: %d nsf: %d n8k: %d samplerate: %d\n", n, nsf, n8k, samplerate);
+            assert(n8k <= N8);
+
+            if (n == 0) {
+                if (g_loopPlayFileFromRadio)
+                    sf_seek(g_sfPlayFileFromRadio, 0, SEEK_SET);
+                else {
+                    printf("playFileFromRadio finished, issuing event!\n");
+                    wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_playFileFromRadioEventId );
+                    // call stop/start play menu item, should be thread safe
+                    g_parent->GetEventHandler()->AddPendingEvent( event );
+                }
+            }
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        resample_for_plot(g_plotDemodInFifo, in8k_short, n8k, samplerate);
+
+        if (g_mode != -1) {
+            // send latest squelch level to FreeDV API, as it handles squelch internally
+
+            freedv_set_squelch_en(g_pfreedv, g_SquelchActive);
+            freedv_set_snr_squelch_thresh(g_pfreedv, g_SquelchLevel);
+        }
+
+        //fprintf(g_logfile, "snr_squelch_thresh: %f\n",  g_pfreedv->snr_squelch_thresh);
+
+        // compute rx spectrum - do here so update rate in constant
+
+        COMP  rx_fdm[n8k];
+        float rx_spec[MODEM_STATS_NSPEC];
+        unsigned int   i;
+
+        for(i=0; i<n8k; i++) {
+            rx_fdm[i].real = in8k_short[i];
+            rx_fdm[i].imag = 0.0;
+        }            
+        modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, n8k);
+
+        // Average rx spectrum data using a simple IIR low pass filter
+
+        for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+            g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+        }
+
+        // Get some audio to send to headphones/speaker.  If in analog
+        // mode we pass thru the "from radio" audio to the
+        // headphones/speaker.
+
+        if (g_analog) {
+            memcpy(out8k_short, in8k_short, sizeof(short)*n8k);
+            
+            #ifdef OLDSPEC
+            // compute rx spectrum 
+
+            COMP  rx_fdm[n8k];
+            float rx_spec[MODEM_STATS_NSPEC];
+            unsigned int   i;
+
+            for(i=0; i<n8k; i++) {
+                rx_fdm[i].real = in8k_short[i];
+                rx_fdm[i].imag = 0.0;
+            }            
+            modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, n8k);
+
+            // Average rx spectrum data using a simple IIR low pass filter
+
+            for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+                g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+            }
+            #endif
+        }
+        else {
+            fifo_write(cbData->rxinfifo, in8k_short, n8k);
+            per_frame_rx_processing(cbData->rxoutfifo, cbData->rxinfifo);
+            memset(out8k_short, 0, sizeof(short)*N8);
+            fifo_read(cbData->rxoutfifo, out8k_short, N8);
+            //printf("out8k_short: %d\n", out8k_short[0]);
+        }
+
+
+        // Optional Spk Out EQ Filtering, need mutex as filter can change at run time
+        g_mutexProtectingCallbackData.Lock();
+        if (cbData->spkOutEQEnable) {
+            sox_biquad_filter(cbData->sbqSpkOutBass,   out8k_short, out8k_short, N8);
+            sox_biquad_filter(cbData->sbqSpkOutTreble, out8k_short, out8k_short, N8);
+            sox_biquad_filter(cbData->sbqSpkOutMid,    out8k_short, out8k_short, N8);
+        }
+        g_mutexProtectingCallbackData.Unlock();
+
+        resample_for_plot(g_plotSpeechOutFifo, out8k_short, N8, FS);
+
+        g_mutexProtectingCallbackData.Lock();
+        if (g_nSoundCards == 1) {
+            nout = resample(cbData->outsrc2, out48k_short, out8k_short, g_soundCard1SampleRate, FS, N48, N8);
+            fifo_write(cbData->outfifo1, out48k_short, nout);
+        }
+        else {
+            nout = resample(cbData->outsrc2, out48k_short, out8k_short, g_soundCard2SampleRate, FS, N48, N8);
+            fifo_write(cbData->outfifo2, out48k_short, nout);
+        }
+    }
+    g_mutexProtectingCallbackData.Unlock();
+
+    //
+    //  TX side processing --------------------------------------------
+    //
+
+    if ((g_mode != -1) && ((g_nSoundCards == 2) && ((g_half_duplex && g_tx) || !g_half_duplex))) {
+        int ret;
+
+        // Make sure we have q few frames of modulator output
+        // samples.  This also locks the modulator to the sample rate
+        // of sound card 1.  We want to make sure that modulator
+        // samples are uninterrupted by differences in sample rate
+        // between this sound card and sound card 2.
+
+        g_mutexProtectingCallbackData.Lock();
+        while((unsigned)fifo_used(cbData->outfifo1) < 6*N48)
+        {
+            g_mutexProtectingCallbackData.Unlock();
+
+            int   nsam = g_soundCard2SampleRate * freedv_get_n_speech_samples(g_pfreedv)/FS;
+            assert(nsam <= 4*N48);
+
+            // infifo2 is written to by another sound card so it may
+            // over or underflow, but we don't realy care.  It will
+            // just result in a short interruption in audio being fed
+            // to codec2_enc, possibly making a click every now and
+            // again in the decoded audio at the other end.
+
+            // zero speech input just in case infifo2 underflows
+            memset(in48k_short, 0, nsam*sizeof(short));
+            fifo_read(cbData->infifo2, in48k_short, nsam);
+
+            nout = resample(cbData->insrc2, in8k_short, in48k_short, FS, g_soundCard2SampleRate, 4*N8, nsam);
+
+            // optionally use file for mic input signal
+
+            g_mutexProtectingCallbackData.Lock();
+            if (g_playFileToMicIn && (g_sfPlayFile != NULL)) {
+                int n = sf_read_short(g_sfPlayFile, in8k_short, nout);
+                //fprintf(stderr, "n: %d nout: %d\n", n, nout);
+                if (n != nout) {
+                    if (g_loopPlayFileToMicIn)
+                        sf_seek(g_sfPlayFile, 0, SEEK_SET);
+                    else {
+                        wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, g_playFileToMicInEventId );
+                        // call stop/start play menu item, should be thread safe
+                        g_parent->GetEventHandler()->AddPendingEvent( event );
+                    }
+                }
+            }
+            g_mutexProtectingCallbackData.Unlock();
+
+            // Optional Speex pre-processor for acoustic noise reduction
+
+            if (wxGetApp().m_speexpp_enable) {
+                speex_preprocess_run(g_speex_st, in8k_short);
+            }
+
+            // Optional Mic In EQ Filtering, need mutex as filter can change at run time
+
+            g_mutexProtectingCallbackData.Lock();
+            if (cbData->micInEQEnable) {
+                sox_biquad_filter(cbData->sbqMicInBass, in8k_short, in8k_short, nout);
+                sox_biquad_filter(cbData->sbqMicInTreble, in8k_short, in8k_short, nout);
+                sox_biquad_filter(cbData->sbqMicInMid, in8k_short, in8k_short, nout);
+            }
+            g_mutexProtectingCallbackData.Unlock();
+
+            resample_for_plot(g_plotSpeechInFifo, in8k_short, nout, FS);
+
+            n_samples = freedv_get_n_nom_modem_samples(g_pfreedv);
+
+            if (g_analog) {
+                n_samples = freedv_get_n_speech_samples(g_pfreedv);
+
+                // Boost the "from mic" -> "to radio" audio in analog
+                // mode.  The need for the gain was found by
+                // experiment - analog SSB sounded too quiet compared
+                // to digital. With digital voice we generally drive
+                // the "to radio" (SSB radio mic input) at about 25%
+                // of the peak level for normal SSB voice. So we
+                // introduce 6dB gain to make analog SSB sound the
+                // same level as the digital.  Watch out for clipping.
+                for(int i=0; i<n_samples; i++) {
+                    float out = (float)in8k_short[i]*2.0;
+                    if (out > 32767) out = 32767.0;
+                    if (out < -32767) out = -32767.0;
+                    out8k_short[i] = out;
+                }
+            }
+            else {
+                COMP tx_fdm[freedv_get_n_nom_modem_samples(g_pfreedv)];
+                COMP tx_fdm_offset[freedv_get_n_nom_modem_samples(g_pfreedv)];
+                int  i;
+
+                if (g_mode == FREEDV_MODE_800XA) {
+                    /* 800XA doesn't support complex output just yet */
+                    freedv_tx(g_pfreedv, out8k_short, in8k_short);
+                }
+                else {
+                    freedv_comptx(g_pfreedv, tx_fdm, in8k_short);
+  
+                    freq_shift_coh(tx_fdm_offset, tx_fdm, g_TxFreqOffsetHz, freedv_get_modem_sample_rate(g_pfreedv), &g_TxFreqOffsetPhaseRect, freedv_get_n_nom_modem_samples(g_pfreedv));
+                    for(i=0; i<freedv_get_n_nom_modem_samples(g_pfreedv); i++)
+                        out8k_short[i] = tx_fdm_offset[i].real;
+                }
+            }
+
+            // output one frame of modem signal
+            nout = resample(cbData->outsrc1, out48k_short, out8k_short, g_soundCard1SampleRate, samplerate, N48*4, n_samples);
+            g_mutexProtectingCallbackData.Lock();
+            ret = fifo_write(cbData->outfifo1, out48k_short, nout);
+            //fprintf(stderr,"nout: %d ret: %d N48*4: %d\n", nout, ret, N48*4);
+
+            assert(ret != -1);
+        }
+        g_mutexProtectingCallbackData.Unlock();
+    }
+   
+    //fprintf(g_logfile, "  end infifo1: %5d outfifo2: %5d\n", fifo_used(cbData->infifo1), fifo_used(cbData->outfifo2));
+
+}
+
+//----------------------------------------------------------------
+// per_frame_rx_processing()
+//----------------------------------------------------------------
+
+void per_frame_rx_processing(
+                             FIFO    *output_fifo,   // decoded speech samples
+                             FIFO    *input_fifo
+                             )
+{
+    #ifdef OLDSPEC
+    float               rx_spec[MODEM_STATS_NSPEC];
+    #endif
+    int                 i;
+
+    if (g_mode == -1) {
+        // PlugIn processing ---------------------------------------------------
+
+        int   nin = 160; // TODO: hard code for now - some sort of plugin supplied param in future
+        short input_buf[nin];
+
+        while (fifo_read(input_fifo, input_buf, nin) == 0) {
+            (wxGetApp().m_plugin_rx_samplesfp)(wxGetApp().m_plugInStates, input_buf, nin);
+        }
+
+        #ifdef OLD_SPEC
+        COMP  rx_fdm[nin];
+
+        for(i=0; i<nin; i++) {
+            rx_fdm[i].real = (float)input_buf[i];
+            rx_fdm[i].imag = 0.0;
+        }
+
+        modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, nin);
+
+        // Average rx spectrum data using a simple IIR low pass filter
+
+        for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+            g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+        }
+        #endif
+
+    }
+    else {
+        // FreeDV processing ----------------------------------------------------
+
+        short               input_buf[freedv_get_n_max_modem_samples(g_pfreedv)];
+        short               output_buf[freedv_get_n_speech_samples(g_pfreedv)];
+        COMP                rx_fdm[freedv_get_n_max_modem_samples(g_pfreedv)];
+        COMP                rx_fdm_offset[freedv_get_n_max_modem_samples(g_pfreedv)];
+        int                 nin, nout;
+
+        nin = freedv_nin(g_pfreedv);
+        while (fifo_read(input_fifo, input_buf, nin) == 0) {
+            assert(nin <= freedv_get_n_max_modem_samples(g_pfreedv));
+
+            #ifdef OLD_SPEC
+            int nin_prev = nin;
+            #endif
+
+            //fwrite(input_buf, sizeof(short), nin, ftest);
+
+            // demod per frame processing
+            for(i=0; i<nin; i++) {
+                rx_fdm[i].real = (float)input_buf[i];
+                rx_fdm[i].imag = 0.0;
+            }
+       
+            if (g_channel_noise) {
+                float snr;
+
+                /* enough noise to get a couple of % errors */
+
+                if (freedv_get_mode(g_pfreedv) == FREEDV_MODE_1600)
+                    snr = 2.0;
+                else
+                    snr = -1.0;           
+                fdmdv_simulate_channel(&g_sig_pwr_av, rx_fdm, nin, snr);
+            }
+            freq_shift_coh(rx_fdm_offset, rx_fdm, g_RxFreqOffsetHz, freedv_get_modem_sample_rate(g_pfreedv), &g_RxFreqOffsetPhaseRect, nin);
+            nout = freedv_comprx(g_pfreedv, output_buf, rx_fdm_offset);
+            //kprintf("nout %d outbuf_buf[0]: %d\n", nout, output_buf[0]);
+            fifo_write(output_fifo, output_buf, nout);
+        
+            nin = freedv_nin(g_pfreedv);
+            g_State = freedv_get_sync(g_pfreedv);
+            //fprintf(g_logfile, "g_State: %d g_stats.sync: %d snr: %f \n", g_State, g_stats.sync, f->snr);
+
+            // grab extended stats so we can plot spectrum, scatter diagram etc
+
+            freedv_get_modem_extended_stats(g_pfreedv, &g_stats);
+
+            #ifdef OLD_SPEC
+            // compute rx spectrum 
+
+            modem_stats_get_rx_spectrum(&g_stats, rx_spec, rx_fdm, nin_prev); 
+            
+            // Average rx spectrum data using a simple IIR low pass filter
+
+            for(i = 0; i<MODEM_STATS_NSPEC; i++) {
+                g_avmag[i] = BETA * g_avmag[i] + (1.0 - BETA) * rx_spec[i];
+            }
+            #endif
+        }
+    }
+
+
+}
+
+
+//-------------------------------------------------------------------------
+// rxCallback()
+//
+// Sound card 1 callback from PortAudio, that is used for processing rx
+// side:
+//
+// + infifo1 is the "from radio" off air modem signal from the SSB rx that we send to the demod.
+// + In single sound card mode outfifo1 is the "to speaker/headphones" decoded speech output.
+// + In dual sound card mode outfifo1 is the "to radio" modulator signal to the SSB tx.
+//
+//-------------------------------------------------------------------------
+int MainFrame::rxCallback(
+                            const void      *inputBuffer,
+                            void            *outputBuffer,
+                            unsigned long   framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void            *userData
+                         )
+{
+    paCallBackData  *cbData = (paCallBackData*)userData;
+    short           *rptr    = (short*)inputBuffer;
+    short           *wptr    = (short*)outputBuffer;
+
+    short           indata[MAX_FPB];
+    short           outdata[MAX_FPB];
+
+    unsigned int    i;
+
+    (void) timeInfo;
+    (void) statusFlags;
+
+    wxMutexLocker lock(g_mutexProtectingCallbackData);
+
+    //fprintf(g_logfile, "cb1 statusFlags: 0x%x framesPerBuffer: %d rptr: 0x%x wptr: 0x%x \n", (int)statusFlags,
+    //        framesPerBuffer, rptr, wptr);
+
+    //
+    //  RX side processing --------------------------------------------
+    //
+
+    // assemble a mono buffer and write to FIFO
+
+    assert(framesPerBuffer < MAX_FPB);
+
+    if(rptr) {
+        //fprintf(g_logfile,"in %ld %d\n",  framesPerBuffer, g_in++);
+        //g_indata += framesPerBuffer;
+        for(i = 0; i < framesPerBuffer; i++, rptr += cbData->inputChannels1)
+            indata[i] = rptr[0];                       
+        if (fifo_write(cbData->infifo1, indata, framesPerBuffer)) {
+            //fprintf(g_logfile, "infifo1 full\n");
+        }
+        //fifo_write(cbData->outfifo1, indata, framesPerBuffer);
+    }
+
+    // OK now set up output samples for this callback
+
+    if(wptr) {
+        //fprintf(g_logfile,"out %ld %d\n",  framesPerBuffer, g_out++);
+        if (fifo_read(cbData->outfifo1, outdata, framesPerBuffer) == 0) {
+
+            // write signal to both channels
+
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                if (cbData->leftChannelVoxTone) {
+                    cbData->voxTonePhase += 2.0*M_PI*VOX_TONE_FREQ/g_soundCard1SampleRate;
+                    cbData->voxTonePhase -= 2.0*M_PI*floor(cbData->voxTonePhase/(2.0*M_PI));
+                    wptr[0] = VOX_TONE_AMP*cos(cbData->voxTonePhase);                              
+                    //printf("%f %d\n", cbData->voxTonePhase, wptr[0]);
+                }
+                else
+                    wptr[0] = outdata[i];
+                               
+                wptr[1] = outdata[i];
+            }
+        }
+        else {
+            //fprintf(g_logfile, "outfifo1 empty\n");
+            // zero output if no data available
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = 0;
+                wptr[1] = 0;
+            }
+        }
+    }
+
+    return paContinue;
+}
+
+
+//-------------------------------------------------------------------------
+// txCallback()
+//-------------------------------------------------------------------------
+int MainFrame::txCallback(
+                            const void *inputBuffer,
+                            void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo *outTime,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData
+                        )
+{
+    paCallBackData  *cbData = (paCallBackData*)userData;
+    unsigned int    i;
+    short           *rptr    = (short*)inputBuffer;
+    short           *wptr    = (short*)outputBuffer;
+    short           indata[MAX_FPB];
+    short           outdata[MAX_FPB];
+
+    wxMutexLocker lock(g_mutexProtectingCallbackData);
+
+    //    if (statusFlags)
+    //    printf("cb2 statusFlags: 0x%x\n", (int)statusFlags);
+
+    // assemble a mono buffer and write to FIFO
+
+    assert(framesPerBuffer < MAX_FPB);
+
+    if(rptr) {
+        for(i = 0; i < framesPerBuffer; i++, rptr += cbData->inputChannels2)
+            indata[i] = rptr[0];                        
+    }
+
+    //#define SC2_LOOPBACK
+#ifdef SC2_LOOPBACK
+    //TODO: This doesn't work unless using the same soundcard!
+
+    if(wptr) {
+        for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+            wptr[0] = indata[i];
+            wptr[1] = indata[i];
+        }
+    }
+
+#else
+    if(rptr) {
+        if (fifo_write(cbData->infifo2, indata, framesPerBuffer)) {
+            //fprintf(g_logfile, "infifo2 full\n");
+        }
+    }
+
+    // OK now set up output samples for this callback
+
+    if(wptr) {
+        if (fifo_read(cbData->outfifo2, outdata, framesPerBuffer) == 0) {
+               
+            // write signal to both channels */
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = outdata[i];
+                wptr[1] = outdata[i];
+            }
+        }
+        else {
+            //fprintf(g_logfile, "outfifo2 empty\n");
+            // zero output if no data available
+            for(i = 0; i < framesPerBuffer; i++, wptr += 2) {
+                wptr[0] = 0;
+                wptr[1] = 0;
+            }
+        }
+    }
+#endif
+    return paContinue;
+}
+
+// Callback from plot_spectrum & plot_waterfall.  would be nice to
+// work out a way to do this without globals.
+
+void fdmdv2_clickTune(float freq) {
+
+    // The demod is hard-wired to expect a centre frequency of
+    // FDMDV_FCENTRE.  So we want to take the signal centered on the
+    // click tune freq and re-centre it on FDMDV_FCENTRE.  For example
+    // if the click tune freq is 1500Hz, and FDMDV_CENTRE is 1200 Hz,
+    // we need to shift the input signal centred on 1500Hz down to
+    // 1200Hz, an offset of -300Hz.
+
+    // Bit of an "indent" as we are often trying to get it back
+    // exactly in the centre
+
+    if (fabs(FDMDV_FCENTRE - freq) < 10.0) {
+        freq = FDMDV_FCENTRE;
+        fprintf(stderr, "indent!\n");
+    }
+
+    if (g_split) {
+        g_RxFreqOffsetHz = FDMDV_FCENTRE - freq;
+    }
+    else {
+        g_TxFreqOffsetHz = freq - FDMDV_FCENTRE;
+        g_RxFreqOffsetHz = FDMDV_FCENTRE - freq;
+    }
+}
+
+//----------------------------------------------------------------
+// OpenSerialPort()
+//----------------------------------------------------------------
+
+void MainFrame::OpenSerialPort(void)
+{
+    Serialport *serialport = wxGetApp().m_serialport;
+
+    if(!wxGetApp().m_strRigCtrlPort.IsEmpty()) {
+       serialport->openport(wxGetApp().m_strRigCtrlPort.c_str(), 
+                            wxGetApp().m_boolUseRTS, 
+                            wxGetApp().m_boolRTSPos, 
+                            wxGetApp().m_boolUseDTR,
+                            wxGetApp().m_boolDTRPos);
+       if (serialport->isopen()) {
+            // always start PTT in Rx state
+           serialport->ptt(false);
+       }
+       else {
+           wxMessageBox("Couldn't open Serial Port", wxT("About"), wxOK | wxICON_ERROR, this);
+       }
+    }
+}
+
+
+//----------------------------------------------------------------
+// CloseSerialPort()
+//----------------------------------------------------------------
+
+void MainFrame::CloseSerialPort(void)
+{
+    Serialport *serialport = wxGetApp().m_serialport;
+    if (serialport->isopen()) {
+        // always end with PTT in rx state
+
+        serialport->ptt(false);
+        serialport->closeport();
+    }
+}
+
+
+#ifdef __UDP_SUPPORT__
+
+//----------------------------------------------------------------
+// PollUDP() - see if any commands on UDP port
+//----------------------------------------------------------------
+
+// test this puppy with netcat: 
+//   $ echo "hello" | nc -u -q1 localhost 3000
+
+int MainFrame::PollUDP(void)
+{
+    // this will block until message received, so we put it in it's own thread
+
+    char buf[1024];
+    char reply[80];
+    size_t n = m_udp_sock->RecvFrom(m_udp_addr, buf, sizeof(buf)).LastCount();
+
+    if (n) {
+        wxString bufstr = wxString::From8BitData(buf, n);
+        bufstr.Trim();
+        wxString ipaddr = m_udp_addr.IPAddress();
+        printf("Received: \"%s\" from %s:%u\n",
+               (const char *)bufstr.c_str(),
+               (const char *)ipaddr.c_str(), m_udp_addr.Service());
+
+        // for security only accept commands from local host
+
+        sprintf(reply,"nope\n");
+        if (ipaddr.Cmp(_("127.0.0.1")) == 0) {
+
+            // process commands
+
+            if (bufstr.Cmp(_("restore")) == 0) {
+                m_schedule_restore = true;  // Make Restore happen in main thread to avoid crashing
+                sprintf(reply,"ok\n");
+            }
+                
+            wxString itemToSet, val;
+            if (bufstr.StartsWith(_("set "), &itemToSet)) {
+                if (itemToSet.StartsWith("txtmsg ", &val)) {
+                    // note: if options dialog is open this will get overwritten
+                    wxGetApp().m_callSign = val;
+                }  
+                sprintf(reply,"ok\n");
+            }
+            if (bufstr.StartsWith(_("ptton"), &itemToSet)) {
+                // note: if options dialog is open this will get overwritten
+                m_btnTogPTT->SetValue(true);
+                togglePTT();
+                sprintf(reply,"ok\n");
+            }
+            if (bufstr.StartsWith(_("pttoff"), &itemToSet)) {
+                // note: if options dialog is open this will get overwritten
+                m_btnTogPTT->SetValue(false);
+                togglePTT();
+                sprintf(reply,"ok\n");
+            }
+                
+        }
+        else {
+            printf("We only accept messages from locahost!\n");
+        }
+
+       if ( m_udp_sock->SendTo(m_udp_addr, reply, strlen(reply)).LastCount() != strlen(reply)) {
+           printf("ERROR: failed to send data\n");
+        }
+    }
+
+    return n;
+}
+
+void MainFrame::startUDPThread(void) {
+    fprintf(stderr, "starting UDP thread!\n");
+    m_UDPThread = new UDPThread;
+    m_UDPThread->mf = this;
+    if (m_UDPThread->Create() != wxTHREAD_NO_ERROR ) {
+        wxLogError(wxT("Can't create thread!"));
+    }
+    if (m_UDPThread->Run() != wxTHREAD_NO_ERROR ) {
+        wxLogError(wxT("Can't start thread!"));
+        delete m_UDPThread;
+    }
+}
+
+void MainFrame::stopUDPThread(void) {
+    printf("stopping UDP thread!\n");
+    if ((m_UDPThread != NULL) && m_UDPThread->m_run) {
+        m_UDPThread->m_run = 0;
+        m_UDPThread->Wait();
+        m_UDPThread = NULL;
+    }
+}
+
+void *UDPThread::Entry() {
+    printf("UDP thread started!\n");
+    while (m_run) {
+        if (wxGetApp().m_udp_enable) {
+            printf("m_udp_enable\n");
+            mf->m_udp_addr.Service(wxGetApp().m_udp_port);
+            mf->m_udp_sock = new wxDatagramSocket(mf->m_udp_addr, wxSOCKET_NOWAIT);
+
+            while (m_run && wxGetApp().m_udp_enable) {
+                if (mf->PollUDP() == 0) {
+                    wxThread::Sleep(20);
+                }
+            }
+
+            delete mf->m_udp_sock;
+        }
+        wxThread::Sleep(20);
+    }
+    return NULL;
+}
+
+#endif
+
+char my_get_next_tx_char(void *callback_state) {
+    short ch = 0;
+    
+    fifo_read(g_txDataInFifo, &ch, 1);
+    //fprintf(stderr, "get_next_tx_char: %c\n", (char)ch);
+    return (char)ch;
+}
+
+void my_put_next_rx_char(void *callback_state, char c) {
+    short ch = (short)c;
+    //fprintf(stderr, "put_next_rx_char: %c\n", (char)c);
+    fifo_write(g_rxDataOutFifo, &ch, 1);
+}
+
+// Callback from FreeDv API to update error plots
+
+void my_freedv_put_error_pattern(void *state, short error_pattern[], int sz_error_pattern) {
+    fifo_write(g_error_pattern_fifo, error_pattern, sz_error_pattern);
+}
+
+void freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, COMP *foff_phase_rect, int nin)
+{
+    COMP  foff_rect;
+    float mag;
+    int   i;
+
+    foff_rect.real = cosf(2.0*M_PI*foff/Fs);
+    foff_rect.imag = sinf(2.0*M_PI*foff/Fs);
+    for(i=0; i<nin; i++) {
+       *foff_phase_rect = cmult(*foff_phase_rect, foff_rect);
+       rx_fdm_fcorr[i] = cmult(rx_fdm[i], *foff_phase_rect);
+    }
+
+    /* normalise digital oscilator as the magnitude can drift over time */
+
+    mag = cabsolute(*foff_phase_rect);
+    foff_phase_rect->real /= mag;       
+    foff_phase_rect->imag /= mag;       
+}
+
+int plugin_get_persistant(char name[], char value[]) {
+    wxString n,v;
+    int i;
+
+    for(i=0; i<wxGetApp().m_numPlugInParam; i++) {
+
+        n = wxGetApp().m_plugInParamName[i];
+
+        if (strcmp(n.mb_str().data(), name) == 0) {
+            v = wxGetApp().m_txtPlugInParam[i];
+            strcpy(value, v.mb_str().data());
+            fprintf(stderr, "plugin_get_persistant called name: %s value: %s\n", name, v.mb_str().data());
+        }
+    }
+
+    return 0;
+}
+
diff --git a/freedv/tags/1.2.2/src/fdmdv2_main.h b/freedv/tags/1.2.2/src/fdmdv2_main.h
new file mode 100644 (file)
index 0000000..e074069
--- /dev/null
@@ -0,0 +1,681 @@
+//==========================================================================
+// Name:            fdmdv2_main.h
+//
+// Purpose:         Declares simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_MAIN__
+#define __FDMDV2_MAIN__
+
+#include "version.h"
+#ifndef _NO_AUTOTOOLS_
+#include "../config.h"
+#endif
+#include <wx/wx.h>
+
+#include <wx/tglbtn.h>
+#include <wx/app.h>
+#include "wx/rawbmp.h"
+#include "wx/file.h"
+#include "wx/filename.h"
+#include "wx/config.h"
+#include <wx/fileconf.h>
+#include "wx/graphics.h"
+#include "wx/mstream.h"
+#include "wx/wfstream.h"
+#include "wx/quantize.h"
+#include "wx/scopedptr.h"
+#include "wx/stopwatch.h"
+#include "wx/versioninfo.h"
+#include <wx/sound.h>
+#include <wx/url.h>
+#include <wx/sstream.h>
+#include <wx/listbox.h>
+#include <wx/textdlg.h>
+#include <wx/regex.h>
+#include <wx/socket.h>
+
+#include <samplerate.h>
+
+#include <stdint.h>
+#include <speex/speex_preprocess.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#endif
+
+#include "codec2.h"
+#include "codec2_fifo.h"
+#include "modem_stats.h"
+
+#include "topFrame.h"
+#include "dlg_ptt.h"
+#include "dlg_options.h"
+#include "fdmdv2_plot.h"
+#include "fdmdv2_plot_scalar.h"
+#include "fdmdv2_plot_scatter.h"
+#include "fdmdv2_plot_waterfall.h"
+#include "fdmdv2_plot_spectrum.h"
+#include "fdmdv2_pa_wrapper.h"
+#include "sndfile.h"
+#include "portaudio.h"
+#include "dlg_audiooptions.h"
+#include "dlg_filter.h"
+#include "dlg_options.h"
+#include "varicode.h"
+#include "sox_biquad.h"
+#include "comp_prim.h"
+#include "dlg_plugin.h"
+#include "hamlib.h"
+#include "serialport.h" 
+
+#define _USE_TIMER              1
+#define _USE_ONIDLE             1
+#define _DUMMY_DATA             1
+//#define _AUDIO_PASSTHROUGH    1
+#define _REFRESH_TIMER_PERIOD   (DT*1000)
+//#define _USE_ABOUT_DIALOG       1
+
+enum {
+        ID_START = wxID_HIGHEST,
+        ID_TIMER_WATERFALL,
+        ID_TIMER_SPECTRUM,
+        ID_TIMER_SCATTER,
+        ID_TIMER_SCALAR
+     };
+
+#define EXCHANGE_DATA_IN    0
+#define EXCHANGE_DATA_OUT   1
+
+
+extern int                 g_nSoundCards;
+extern int                 g_soundCard1InDeviceNum;
+extern int                 g_soundCard1OutDeviceNum;
+extern int                 g_soundCard1SampleRate;
+extern int                 g_soundCard2InDeviceNum;
+extern int                 g_soundCard2OutDeviceNum;
+extern int                 g_soundCard2SampleRate;
+
+// Voice Keyer Constants
+
+#define VK_SYNC_WAIT_TIME 5.0
+
+// Voice Keyer States
+
+#define VK_IDLE      0
+#define VK_TX        1
+#define VK_RX        2
+#define VK_SYNC_WAIT 3
+
+// Voice Keyer Events
+
+#define VK_START         0
+#define VK_SPACE_BAR     1
+#define VK_PLAY_FINISHED 2
+#define VK_DT            3
+#define VK_SYNC          4
+
+class MainFrame;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainApp
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MainApp : public wxApp
+{
+    public:
+        virtual bool        OnInit();
+        virtual int         OnExit();
+
+        wxString            m_strVendName;
+        wxString            m_StrAppName;
+
+        wxString            m_textNumChOut;
+        wxString            m_textNumChIn;
+
+        wxString            m_strRxInAudio;
+        wxString            m_strRxOutAudio;
+        wxString            m_textVoiceInput;
+        wxString            m_textVoiceOutput;
+        wxString            m_strSampleRate;
+        wxString            m_strBitrate;
+
+        // PTT -----------------------------------
+
+        bool                m_boolHalfDuplex;
+
+        wxString            m_txtVoiceKeyerWaveFilePath;
+        wxString            m_txtVoiceKeyerWaveFile;
+        int                 m_intVoiceKeyerRxPause;
+        int                 m_intVoiceKeyerRepeats;
+
+        bool                m_boolHamlibUseForPTT;
+        unsigned int        m_intHamlibRig;
+        wxString            m_strHamlibSerialPort;
+        unsigned int        m_intHamlibSerialRate;
+        Hamlib              *m_hamlib;
+
+        bool                m_boolUseSerialPTT;
+        wxString            m_strRigCtrlPort;
+        bool                m_boolUseRTS;
+        bool                m_boolRTSPos;
+        bool                m_boolUseDTR;
+        bool                m_boolDTRPos;
+        Serialport         *m_serialport;
+
+        // Play/Rec files
+
+        wxString            m_playFileToMicInPath;
+        wxString            m_recFileFromRadioPath;
+        unsigned int        m_recFileFromRadioSecs;
+        wxString            m_playFileFromRadioPath;
+
+        // Options dialog
+
+        wxString            m_callSign;
+        bool                m_events;
+        int                 m_events_spam_timer;
+        unsigned int        m_textEncoding;
+        bool                m_enable_checksum;
+        wxString            m_events_regexp_match;
+        wxString            m_events_regexp_replace;
+
+        bool                m_snrSlow;
+
+        // LPC Post Filter
+        bool                m_codec2LPCPostFilterEnable;
+        bool                m_codec2LPCPostFilterBassBoost;
+        float               m_codec2LPCPostFilterGamma;
+        float               m_codec2LPCPostFilterBeta;
+        
+        // Speex Pre-Processor
+        bool                m_speexpp_enable;
+
+        // Mic In Equaliser
+        float               m_MicInBassFreqHz;
+        float               m_MicInBassGaindB;
+        float               m_MicInTrebleFreqHz;
+        float               m_MicInTrebleGaindB;
+        float               m_MicInMidFreqHz;
+        float               m_MicInMidGaindB;
+        float               m_MicInMidQ;
+        bool                m_MicInEQEnable;
+
+        // Spk Out Equaliser
+        float               m_SpkOutBassFreqHz;
+        float               m_SpkOutBassGaindB;
+        float               m_SpkOutTrebleFreqHz;
+        float               m_SpkOutTrebleGaindB;
+        float               m_SpkOutMidFreqHz;
+        float               m_SpkOutMidGaindB;
+        float               m_SpkOutMidQ;
+        bool                m_SpkOutEQEnable;
+
+        // Flags for displaying windows
+        int                 m_show_wf;
+        int                 m_show_spect;
+        int                 m_show_scatter;
+        int                 m_show_timing;
+        int                 m_show_freq;
+        int                 m_show_speech_in;
+        int                 m_show_speech_out;
+        int                 m_show_demod_in;
+        int                 m_show_test_frame_errors;
+        int                 m_show_test_frame_errors_hist;
+
+        // optional vox trigger tone
+        bool                m_leftChannelVoxTone;
+
+        // UDP control port
+        bool                m_udp_enable;
+        int                 m_udp_port;
+
+        // notebook display after tx->rxtransition
+        int                 m_rxNbookCtrl;
+
+        wxRect              m_rTopWindow;
+
+        int                 m_framesPerBuffer;
+
+        bool                loadConfig();
+        bool                saveConfig();
+
+        // Plugins -----------------------------------
+
+        wxString            m_txtPlugInParam[PLUGIN_MAX_PARAMS];
+
+        // plugin details
+
+        void      *m_plugInHandle;
+        bool       m_plugIn;
+        wxString   m_plugInName;
+        int        m_numPlugInParam;
+        wxString   m_plugInParamName[PLUGIN_MAX_PARAMS];
+        void      *m_plugInStates;
+        void     (*m_plugin_startfp)(void *);
+        void     (*m_plugin_stopfp)(void *);
+        void     (*m_plugin_rx_samplesfp)(void *, short *, int);
+
+        // misc
+
+        bool       m_testFrames;
+        bool       m_channel_noise;
+        float      m_channel_snr_dB;
+
+        int        FilterEvent(wxEvent& event);
+        MainFrame *frame;
+
+        // 700 options
+
+        bool       m_FreeDV700txClip;
+        bool       m_FreeDV700Combine;
+
+        // Noise simulation
+
+        int        m_noise_snr;
+
+        // carrier attenuation
+
+        bool       m_attn_carrier_en;
+        int        m_attn_carrier;
+
+        // tone interferer simulation
+
+        bool       m_tone;
+        int        m_tone_freq_hz;
+        int        m_tone_amplitude;
+
+        // Windows debug console
+
+        bool       m_debug_console;
+    protected:
+};
+
+// declare global static function wxGetApp()
+DECLARE_APP(MainApp)
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// paCallBackData
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+typedef struct
+{
+    // libresample states for 48 to 8 kHz conversions
+
+    SRC_STATE      *insrc1;
+    SRC_STATE      *outsrc1;
+    SRC_STATE      *insrc2;
+    SRC_STATE      *outsrc2;
+    SRC_STATE      *insrcsf;
+
+    // FIFOs attached to first sound card
+
+    struct FIFO    *infifo1;
+    struct FIFO    *outfifo1;
+
+    // FIFOs attached to second sound card
+    struct FIFO    *infifo2;
+    struct FIFO    *outfifo2;
+
+    // FIFOs for rx process
+    struct FIFO    *rxinfifo;
+    struct FIFO    *rxoutfifo;
+
+    int             inputChannels1, inputChannels2;
+
+    // EQ filter states
+    void           *sbqMicInBass;
+    void           *sbqMicInTreble;
+    void           *sbqMicInMid;
+    void           *sbqSpkOutBass;
+    void           *sbqSpkOutTreble;
+    void           *sbqSpkOutMid;
+
+    bool            micInEQEnable;
+    bool            spkOutEQEnable;
+
+    // optional loud tone on left channel to reliably trigger vox
+    bool            leftChannelVoxTone;
+    float           voxTonePhase;
+
+} paCallBackData;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// panel with custom loop checkbox for play file dialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MyExtraPlayFilePanel : public wxPanel
+{
+public:
+    MyExtraPlayFilePanel(wxWindow *parent);
+    void setLoopPlayFileToMicIn(bool checked) { m_cb->SetValue(checked); }
+    bool getLoopPlayFileToMicIn(void) { return m_cb->GetValue(); }
+private:
+    wxCheckBox *m_cb;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// panel with custom Seconds-to-record control for record file dialog
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MyExtraRecFilePanel : public wxPanel
+{
+public:
+    MyExtraRecFilePanel(wxWindow *parent);
+    ~MyExtraRecFilePanel() 
+    {
+        wxLogDebug("Destructor\n");
+    }
+    void setSecondsToRecord(wxString value) { m_secondsToRecord->SetValue(value); }
+    wxString getSecondsToRecord(void) 
+    { 
+        wxLogDebug("getSecondsToRecord: %s\n",m_secondsToRecord->GetValue());
+        return m_secondsToRecord->GetValue(); 
+    }
+private:
+    wxTextCtrl *m_secondsToRecord;
+};
+
+class txRxThread;
+class UDPThread;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class MainFrame
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class MainFrame : public TopFrame
+{
+    public:
+        MainFrame(wxString plugInName, wxWindow *parent);
+        virtual ~MainFrame();
+
+        PlotSpectrum*           m_panelSpectrum;
+        PlotWaterfall*          m_panelWaterfall;
+        PlotScatter*            m_panelScatter;
+        PlotScalar*             m_panelTimeOffset;
+        PlotScalar*             m_panelFreqOffset;
+        PlotScalar*             m_panelSpeechIn;
+        PlotScalar*             m_panelSpeechOut;
+        PlotScalar*             m_panelDemodIn;
+        PlotScalar*             m_panelTestFrameErrors;
+        PlotScalar*             m_panelTestFrameErrorsHist;
+
+        bool                    m_RxRunning;
+
+        PortAudioWrap           *m_rxInPa;
+        PortAudioWrap           *m_rxOutPa;
+        PortAudioWrap           *m_txInPa;
+        PortAudioWrap           *m_txOutPa;
+
+        PaError                 m_rxErr;
+        PaError                 m_txErr;
+        
+        txRxThread*             m_txRxThread;
+
+        bool                    OpenHamlibRig();
+        void                    OpenSerialPort(void);
+        void                    CloseSerialPort(void);
+        void                    SerialPTTRx(void);
+
+        bool                    m_modal;
+
+#ifdef _USE_TIMER
+        wxTimer                 m_plotTimer;
+#endif
+
+    void destroy_fifos(void);
+    void destroy_src(void);
+    void autoDetectSoundCards(PortAudioWrap *pa);
+
+        static int rxCallback(
+                                const void *inBuffer,
+                                void *outBuffer,
+                                unsigned long framesPerBuffer,
+                                const PaStreamCallbackTimeInfo *outTime,
+                                PaStreamCallbackFlags statusFlags,
+                                void *userData
+                             );
+        static int txCallback(
+                                const void *inBuffer,
+                                void *outBuffer,
+                                unsigned long framesPerBuffer,
+                                const PaStreamCallbackTimeInfo *outTime,
+                                PaStreamCallbackFlags statusFlags,
+                                void *userData
+                             );
+
+
+    void initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice, 
+                             int soundCard, int sampleRate, int inputChannels);
+
+    void togglePTT(void);
+
+    wxIPV4address           m_udp_addr;
+    wxDatagramSocket       *m_udp_sock;
+    UDPThread              *m_UDPThread;
+    void                    startUDPThread(void);
+    void                    stopUDPThread(void);
+    int                     PollUDP();
+    bool                    m_schedule_restore;
+
+    int                     vk_state;
+    void VoiceKeyerProcessEvent(int vk_event);
+
+    protected:
+
+        void setsnrBeta(bool snrSlow);
+
+        // protected event handlers
+        virtual void OnCloseFrame(wxCloseEvent& event);
+        void OnExitClick(wxCommandEvent& event);
+
+        void startTxStream();
+        void startRxStream();
+        void stopTxStream();
+        void stopRxStream();
+        void abortTxStream();
+        void abortRxStream();
+        
+        void OnTop(wxCommandEvent& event);
+        void OnExit( wxCommandEvent& event );
+
+        void OnToolsAudio( wxCommandEvent& event );
+        void OnToolsAudioUI( wxUpdateUIEvent& event );
+        void OnToolsComCfg( wxCommandEvent& event );
+        void OnToolsComCfgUI( wxUpdateUIEvent& event );
+        void OnToolsFilter( wxCommandEvent& event );
+        void OnToolsOptions(wxCommandEvent& event);
+        void OnToolsOptionsUI(wxUpdateUIEvent& event);
+
+        void OnToolsPlugInCfg( wxCommandEvent& event );
+        void OnToolsPlugInCfgUI( wxUpdateUIEvent& event );
+
+        void OnPlayFileToMicIn( wxCommandEvent& event );
+        void StopPlayFileToMicIn(void);
+        void OnRecFileFromRadio( wxCommandEvent& event );
+        void OnPlayFileFromRadio( wxCommandEvent& event );
+
+        void OnHelpCheckUpdates( wxCommandEvent& event );
+        void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event );
+        void OnHelpAbout( wxCommandEvent& event );
+        void OnCmdSliderScroll( wxScrollEvent& event );
+//        void OnSliderScrollBottom( wxScrollEvent& event );
+//        void OnCmdSliderScrollChanged( wxScrollEvent& event );
+//        void OnSliderScrollTop( wxScrollEvent& event );
+        void OnCheckSQClick( wxCommandEvent& event );
+        void OnCheckSNRClick( wxCommandEvent& event );
+
+        // Toggle Buttons
+        void OnTogBtnSplitClick(wxCommandEvent& event);
+        void OnTogBtnAnalogClick(wxCommandEvent& event);
+        void OnTogBtnRxID( wxCommandEvent& event );
+        void OnTogBtnTxID( wxCommandEvent& event );
+        void OnTogBtnPTT( wxCommandEvent& event );
+        void OnTogBtnVoiceKeyerClick (wxCommandEvent& event);
+        void OnTogBtnOnOff( wxCommandEvent& event );
+
+        void OnCallSignReset( wxCommandEvent& event );
+        void OnBerReset( wxCommandEvent& event );
+
+        //System Events
+        void OnPaint(wxPaintEvent& event);
+        void OnSize( wxSizeEvent& event );
+        void OnUpdateUI( wxUpdateUIEvent& event );
+        void OnDeleteConfig(wxCommandEvent&);
+#ifdef _USE_TIMER
+        void OnTimer(wxTimerEvent &evt);
+#endif
+#ifdef _USE_ONIDLE
+        void OnIdle(wxIdleEvent &evt);
+#endif
+
+        int VoiceKeyerStartTx(void);
+
+    private:
+        bool        m_useMemory;
+        wxTextCtrl* m_tc;
+        int         m_zoom;
+        float       m_snrBeta;
+        
+        // Callsign/text messaging
+        char        m_callsign[MAX_CALLSIGN];
+        char       *m_pcallsign;
+        unsigned int m_checksumGood;
+        unsigned int m_checksumBad;
+        
+        // Events
+        void        processTxtEvent(char event[]);
+        class OptionsDlg *optionsDlg;
+        wxTimer     spamTimer[MAX_EVENT_RULES];
+
+        // level Gauge
+        float       m_maxLevel;
+        // flags to indicate when new EQ filters need to be designed
+
+        bool        m_newMicInFilter;
+        bool        m_newSpkOutFilter;
+
+        void*       designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q = 0.0);
+        void        designEQFilters(paCallBackData *cb);
+        void        deleteEQFilters(paCallBackData *cb);
+
+        // Voice Keyer States
+
+        int        vk_rx_pause;
+        int        vk_repeats, vk_repeat_counter;
+        float      vk_rx_time;
+};
+
+void txRxProcessing();
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class txRxThread - experimental tx/rx processing thread
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class txRxThread : public wxThread
+{
+public:
+    txRxThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
+
+    // thread execution starts here
+    void *Entry() 
+    {
+        while (m_run) 
+        {
+            txRxProcessing();        
+            wxThread::Sleep(20);
+        }
+        return NULL;
+    }
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    void OnExit() { }
+
+public:
+    bool  m_run;
+};
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// class UDPThread - waits for UDP messages
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class UDPThread : public wxThread
+{
+public:
+    UDPThread(void) : wxThread(wxTHREAD_JOINABLE) { m_run = 1; }
+
+    // thread execution starts here
+    void *Entry();
+
+    // called when the thread exits - whether it terminates normally or is
+    // stopped with Delete() (but not when it is Kill()ed!)
+    void OnExit() { }
+
+public:
+    MainFrame              *mf;
+    bool                    m_run;
+};
+
+void resample_for_plot(struct FIFO *plotFifo, short buf[], int length, int fs);
+
+int resample(SRC_STATE *src,
+             short      output_short[],
+             short      input_short[],
+             int        output_sample_rate,
+             int        input_sample_rate,
+             int        length_output_short, // maximum output array length in samples
+             int        length_input_short
+             );
+void txRxProcessing();
+void per_frame_rx_processing(
+                                        FIFO    *output_fifo,   // decoded speech samples
+                                        FIFO    *input_fifo     // modem samples input to demod
+                                    );
+
+// FreeDv API calls this when there is a test frame that needs a-plottin'
+
+void my_freedv_put_error_pattern(void *state, short error_pattern[], int sz_error_pattern);
+
+// FreeDv API calls these puppies when it needs/receives a text char 
+
+char my_get_next_tx_char(void *callback_state);
+void my_put_next_rx_char(void *callback_state, char c);
+
+// helper complex freq shift function
+
+void freq_shift_coh(COMP rx_fdm_fcorr[], COMP rx_fdm[], float foff, float Fs, COMP *foff_phase_rect, int nin);
+
+// Helper function called by plugin
+
+int plugin_get_persistant(char name[], char value[]);
+
+#endif //__FDMDV2_MAIN__
diff --git a/freedv/tags/1.2.2/src/fdmdv2_pa_wrapper.cpp b/freedv/tags/1.2.2/src/fdmdv2_pa_wrapper.cpp
new file mode 100644 (file)
index 0000000..2f67ca2
--- /dev/null
@@ -0,0 +1,324 @@
+//==========================================================================
+// Name:            fdmdv2_pa_wrapper.cpp
+// Purpose:         Implements a wrapper class around the PortAudio library.
+// Created:         August 12, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "fdmdv2_pa_wrapper.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// PortAudioWrap()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PortAudioWrap::PortAudioWrap()
+{
+    m_pStream                   = NULL;
+    m_pUserData                 = NULL;
+    m_samplerate                = 0;
+    m_framesPerBuffer           = 0;
+    m_statusFlags               = 0;
+    m_pStreamCallback           = NULL;
+    m_pStreamFinishedCallback   = NULL;
+    m_pTimeInfo                 = 0;
+    m_newdata                   = false;
+
+//    loadData();
+}
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// ~PortAudioWrap()
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PortAudioWrap::~PortAudioWrap()
+{
+}
+
+//----------------------------------------------------------------
+// streamOpen()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamOpen()
+{
+    return Pa_OpenStream(
+                            &m_pStream,
+                            m_inputBuffer.device == paNoDevice ? NULL : &m_inputBuffer,
+                            m_outputBuffer.device == paNoDevice ? NULL : &m_outputBuffer,
+                            m_samplerate,
+                            m_framesPerBuffer,
+                            m_statusFlags,
+                            *m_pStreamCallback,
+                            m_pUserData
+                        );
+}
+
+//----------------------------------------------------------------
+// streamStart()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamStart()
+{
+    return Pa_StartStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// streamClose()
+//----------------------------------------------------------------
+PaError PortAudioWrap::streamClose()
+{
+    if(isOpen())
+    {
+        PaError rv = Pa_CloseStream(m_pStream);
+        return rv;
+    }
+    else
+    {
+        return paNoError;
+    }
+}
+
+//----------------------------------------------------------------
+// terminate()
+//----------------------------------------------------------------
+void PortAudioWrap::terminate()
+{
+    if(Pa_IsStreamStopped(m_pStream) != paNoError)
+    {
+        Pa_StopStream(m_pStream);
+    }
+    Pa_Terminate();
+}
+
+//----------------------------------------------------------------
+// stop()
+//----------------------------------------------------------------
+void PortAudioWrap::stop()
+{
+    Pa_StopStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// abort()
+//----------------------------------------------------------------
+void PortAudioWrap::abort()
+{
+    Pa_AbortStream(m_pStream);
+}
+
+//----------------------------------------------------------------
+// isStopped()
+//----------------------------------------------------------------
+bool PortAudioWrap::isStopped() const
+{
+    PaError ret = Pa_IsStreamStopped(m_pStream);
+    return ret;
+}
+
+//----------------------------------------------------------------
+// isActive()
+//----------------------------------------------------------------
+bool PortAudioWrap::isActive() const
+{
+    PaError ret = Pa_IsStreamActive(m_pStream);
+    return ret;
+}
+
+//----------------------------------------------------------------
+// isOpen()
+//----------------------------------------------------------------
+bool PortAudioWrap::isOpen() const
+{
+    return (m_pStream != NULL);
+}
+
+//----------------------------------------------------------------
+// getDefaultInputDevice()
+//----------------------------------------------------------------
+PaDeviceIndex PortAudioWrap::getDefaultInputDevice()
+{
+    return Pa_GetDefaultInputDevice();
+}
+
+//----------------------------------------------------------------
+// getDefaultOutputDevice()
+//----------------------------------------------------------------
+PaDeviceIndex PortAudioWrap::getDefaultOutputDevice()
+{
+    return Pa_GetDefaultOutputDevice();
+}
+
+//----------------------------------------------------------------
+// setInputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputChannelCount(int count)
+{
+    m_inputBuffer.channelCount = count;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// getInputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::getInputChannelCount()
+{
+    return m_inputBuffer.channelCount;
+}
+
+//----------------------------------------------------------------
+// setInputSampleFormat()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputSampleFormat(PaSampleFormat format)
+{
+    m_inputBuffer.sampleFormat = format;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputLatency()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputLatency(PaTime latency)
+{
+    m_inputBuffer.suggestedLatency = latency;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputHostApiStreamInfo()
+//----------------------------------------------------------------
+void PortAudioWrap::setInputHostApiStreamInfo(void *info)
+{
+    m_inputBuffer.hostApiSpecificStreamInfo = info;
+}
+
+//----------------------------------------------------------------
+// getInputDefaultLowLatency()
+//----------------------------------------------------------------
+PaTime  PortAudioWrap::getInputDefaultLowLatency()
+{
+    return Pa_GetDeviceInfo(m_inputBuffer.device)->defaultLowInputLatency;
+}
+
+//----------------------------------------------------------------
+// setOutputChannelCount()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputChannelCount(int count)
+{
+    m_outputBuffer.channelCount = count;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// getOutputChannelCount()
+//----------------------------------------------------------------
+const int PortAudioWrap::getOutputChannelCount()
+{
+    return m_outputBuffer.channelCount;
+}
+
+//----------------------------------------------------------------
+// getDeviceName()
+//----------------------------------------------------------------
+const char *PortAudioWrap::getDeviceName(PaDeviceIndex dev)
+{
+    const PaDeviceInfo *info;
+    info = Pa_GetDeviceInfo(dev);
+    return info->name;
+}
+
+//----------------------------------------------------------------
+// setOutputSampleFormat()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputSampleFormat(PaSampleFormat format)
+{
+    m_outputBuffer.sampleFormat = format;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputLatency()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputLatency(PaTime latency)
+{
+    m_outputBuffer.suggestedLatency = latency;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputHostApiStreamInfo()
+//----------------------------------------------------------------
+void PortAudioWrap::setOutputHostApiStreamInfo(void *info)
+{
+    m_outputBuffer.hostApiSpecificStreamInfo = info;
+}
+
+//----------------------------------------------------------------
+// getOutputDefaultLowLatency()
+//----------------------------------------------------------------
+PaTime  PortAudioWrap::getOutputDefaultLowLatency()
+{
+    return Pa_GetDeviceInfo(m_outputBuffer.device)->defaultLowOutputLatency;
+}
+
+//----------------------------------------------------------------
+// setFramesPerBuffer()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setFramesPerBuffer(unsigned long size)
+{
+    m_framesPerBuffer = size;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setSampleRate()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setSampleRate(unsigned long rate)
+{
+    m_samplerate = rate;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setStreamFlags()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setStreamFlags(PaStreamFlags flags)
+{
+    m_statusFlags = flags;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setInputDevice()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setInputDevice(PaDeviceIndex index)
+{
+    m_inputBuffer.device = index;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setOutputDevice()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setOutputDevice(PaDeviceIndex index)
+{
+    m_outputBuffer.device = index;
+    return paNoError;
+}
+
+//----------------------------------------------------------------
+// setCallback()
+//----------------------------------------------------------------
+PaError PortAudioWrap::setCallback(PaStreamCallback *callback)
+{
+    m_pStreamCallback = callback;
+    return paNoError;
+}
+
diff --git a/freedv/tags/1.2.2/src/fdmdv2_pa_wrapper.h b/freedv/tags/1.2.2/src/fdmdv2_pa_wrapper.h
new file mode 100644 (file)
index 0000000..3d216c0
--- /dev/null
@@ -0,0 +1,115 @@
+//==========================================================================
+// Name:            fdmdv2_pa_wrapper.h
+// Purpose:         Defines a wrapper class around PortAudio
+// Created:         August 12, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <stdio.h>
+#include <math.h>
+#include "fdmdv2_defines.h"
+#include "codec2_fdmdv.h"
+#include "codec2.h"
+#include "portaudio.h"
+
+#define PA_SAMPLE_TYPE      paInt16         //paFloat32
+#define FRAMES_PER_BUFFER   (64)
+
+typedef float SAMPLE;
+
+class PortAudioWrap
+{
+    public:
+        PortAudioWrap();
+        ~PortAudioWrap();
+
+//        float                           m_av_mag[FDMDV_NSPEC];
+
+    private:
+        PaStream                        *m_pStream;
+        void                            *m_pUserData;
+        PaStreamCallback                *m_pStreamCallback;
+        PaStreamFinishedCallback        *m_pStreamFinishedCallback;
+        const PaStreamCallbackTimeInfo  *m_pTimeInfo;
+        struct FDMDV                    *m_pFDMDV_state;
+        PaStreamParameters              m_inputBuffer;
+        PaStreamParameters              m_outputBuffer;
+        int                             m_samplerate;
+        unsigned long                   m_framesPerBuffer;
+        PaStreamCallbackFlags           m_statusFlags;
+        bool                            m_newdata;
+
+    public:
+
+        void                averageData(float mag_dB[]);
+
+        int                 getDeviceCount() { return Pa_GetDeviceCount(); }
+        PaDeviceIndex       getDefaultInputDevice();
+        PaDeviceIndex       getDefaultOutputDevice();
+        PaStreamParameters  *getDeviceInfo(PaDeviceIndex idx);
+
+        PaError             setFramesPerBuffer(unsigned long size);
+        PaError             setSampleRate(unsigned long size);
+
+        PaError             setStreamFlags(PaStreamFlags flags);
+        PaError             setCallback(PaStreamCallback *m_pStreamCallback);
+        PaError             setStreamCallback(PaStream *stream, PaStreamCallback* callback) { m_pStreamCallback = callback; return 0;}
+        PaError             setStreamFinishedCallback(PaStream *stream, PaStreamFinishedCallback* m_pStreamFinishedCallback);
+
+        void                setInputBuffer(const PaStreamParameters& inputBuffer)   {this->m_inputBuffer = inputBuffer;}
+        PaError             setInputDevice(PaDeviceIndex dev);
+        PaError             setInputChannelCount(int count);
+        int                 getInputChannelCount();
+        PaError             setInputSampleFormat(PaSampleFormat format);
+        PaError             setInputSampleRate(PaSampleFormat format);
+        PaError             setInputLatency(PaTime latency);
+        void                setInputHostApiStreamInfo(void *info = NULL);
+        PaTime              getInputDefaultLowLatency();
+        const char          *getDeviceName(PaDeviceIndex dev);
+
+        PaError             setOutputDevice(PaDeviceIndex dev);
+        PaError             setOutputChannelCount(int count);
+        const int           getOutputChannelCount();
+        PaError             setOutputSampleFormat(PaSampleFormat format);
+        PaError             setOutputLatency(PaTime latency);
+        void                setOutputHostApiStreamInfo(void *info = NULL);
+        PaTime              getOutputDefaultLowLatency();
+
+        void                setFdmdvState(FDMDV* fdmdv_state)                       {this->m_pFDMDV_state = fdmdv_state;}
+        void                setOutputBuffer(const PaStreamParameters& outputBuffer) {this->m_outputBuffer = outputBuffer;}
+        void                setTimeInfo(PaStreamCallbackTimeInfo* timeInfo)         {this->m_pTimeInfo = timeInfo;}
+        void                setUserData(void* userData)                             {this->m_pUserData = userData;}
+        unsigned long       getFramesPerBuffer() const                              {return m_framesPerBuffer;}
+        const               PaStreamParameters& getInputBuffer() const              {return m_inputBuffer;}
+        const               PaStreamParameters& getOutputBuffer() const             {return m_outputBuffer;}
+        const               PaStreamCallbackFlags& getStatusFlags() const           {return m_statusFlags;}
+
+        FDMDV*              getFdmdvState()                                         {return m_pFDMDV_state;}
+        int                 getSamplerate() const                                   {return m_samplerate;}
+        PaStream*           getStream()                                             {return m_pStream;}
+        void                *getUserData()                                          {return m_pUserData;}
+        bool                getDataAvail()                                          {return m_newdata;}
+        PaError             streamStart();
+        PaError             streamClose();
+        PaError             streamOpen();
+        void                terminate();
+        void                stop();
+        void                abort();
+        bool                isOpen() const;
+        bool                isStopped() const;
+        bool                isActive() const;
+//        void                loadData();
+};
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot.cpp b/freedv/tags/1.2.2/src/fdmdv2_plot.cpp
new file mode 100644 (file)
index 0000000..1b85cd9
--- /dev/null
@@ -0,0 +1,283 @@
+//==========================================================================
+// Name:            fdmdv2_plot.cpp
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "fdmdv2_plot.h"
+
+BEGIN_EVENT_TABLE(PlotPanel, wxPanel)
+    EVT_PAINT           (PlotPanel::OnPaint)
+    EVT_MOTION          (PlotPanel::OnMouseMove)
+    EVT_LEFT_DOWN       (PlotPanel::OnMouseLeftDown)
+    EVT_LEFT_UP         (PlotPanel::OnMouseLeftUp)
+    EVT_RIGHT_DOWN      (PlotPanel::OnMouseRightDown)
+    EVT_MOUSEWHEEL      (PlotPanel::OnMouseWheelMoved)
+    EVT_SIZE            (PlotPanel::OnSize)
+    EVT_SHOW            (PlotPanel::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotPanel(wxFrame* parent) : wxPanel(parent)
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotPanel::PlotPanel(wxFrame* parent) : wxPanel(parent)
+{
+    m_pNoteBook         = (wxAuiNotebook *) parent;
+    m_pTopFrame         = (MainFrame *)m_pNoteBook->GetParent();
+    m_zoomFactor        = 1.0;
+    m_pBmp              = NULL;
+    m_pPix              = NULL;
+    m_firstPass         = true;
+    m_line_color        = 0;
+    m_newdata           = false;
+    m_clip              = false;
+    m_use_bitmap        = true;
+    m_rubberBand        = false;
+    m_mouseDown         = false;
+    m_penShortDash      = wxPen(wxColor(0xA0, 0xA0, 0xA0), 1, wxPENSTYLE_SHORT_DASH);
+    m_penDotDash        = wxPen(wxColor(0xD0, 0xD0, 0xD0), 1, wxPENSTYLE_DOT_DASH);
+    m_penSolid          = wxPen(wxColor(0x00, 0x00, 0x00), 1, wxPENSTYLE_SOLID);
+    SetBackgroundStyle(wxBG_STYLE_PAINT);
+    SetLabelSize(10.0);
+}
+
+//-------------------------------------------------------------------------
+// ~PlotPanel()
+//-------------------------------------------------------------------------
+PlotPanel::~PlotPanel()
+{
+    if(m_pBmp != NULL)
+    {
+        delete m_pBmp;
+    }
+}
+
+//-------------------------------------------------------------------------
+// GetLabelSize()
+//-------------------------------------------------------------------------
+double PlotPanel::GetLabelSize()
+{
+    return m_label_size;
+}
+
+//-------------------------------------------------------------------------
+// SetLabelSize()
+//-------------------------------------------------------------------------
+void PlotPanel::SetLabelSize(double size)
+{
+    m_label_size = size;
+}
+
+//-------------------------------------------------------------------------
+// OnShow()
+//-------------------------------------------------------------------------
+void PlotPanel::OnShow(wxShowEvent& event)
+{
+    this->Refresh();
+}
+
+//-------------------------------------------------------------------------
+// OnErase()
+//-------------------------------------------------------------------------
+void PlotPanel::OnErase(wxEraseEvent& event)
+{
+    event.Skip();
+}
+
+//-------------------------------------------------------------------------
+// OnSize()
+//-------------------------------------------------------------------------
+void PlotPanel::OnSize(wxSizeEvent& event)
+{
+    m_rCtrlPrev = m_rCtrl;
+    m_rCtrl     = GetClientRect();
+    if(m_use_bitmap)
+    {
+        if(!m_oImage.IsOk())
+        {
+            m_oImage.Create(m_rCtrl.GetWidth(), m_rCtrl.GetHeight(), true);
+        }
+        else
+        {
+            m_oImage.Rescale(m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
+        }
+        m_pBmp = new wxBitmap(m_oImage, wxBITMAP_SCREEN_DEPTH);
+        m_firstPass = true;
+    }
+    this->Refresh();
+}
+
+//-------------------------------------------------------------------------
+// OnMouseMove()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseMove(wxMouseEvent& event)
+{
+//    if(m_mouseDown)
+//    {
+//        paintNow();
+//    }
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftDown()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseLeftDown(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseRightDown(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseWheelMoved()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseWheelMoved(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftUp()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseLeftUp(wxMouseEvent& event)
+{
+    m_mouseDown = false;
+}
+
+//-------------------------------------------------------------------------
+// SetZoomFactor()
+//-------------------------------------------------------------------------
+double PlotPanel::SetZoomFactor(double zf)
+{
+    if((zf > 0) && (zf < 5.0))
+    {
+        m_zoomFactor = zf;
+    }
+    return zf;
+}
+
+//-------------------------------------------------------------------------
+// GetZoomFactor()
+//-------------------------------------------------------------------------
+double PlotPanel::GetZoomFactor(double zf)
+{
+    return m_zoomFactor;
+}
+
+//-------------------------------------------------------------------------
+// draw()
+//-------------------------------------------------------------------------
+void PlotPanel::draw(wxAutoBufferedPaintDC& pDC)
+{
+    printf("PlotPanel::draw()");
+    wxMemoryDC m_mDC;
+    m_mDC.SelectObject(*m_pBmp);
+    m_rCtrl  = GetClientRect();
+    m_rGrid  = m_rCtrl;
+
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+    m_rGrid.Offset(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
+
+    pDC.Clear();
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    if(m_firstPass)
+    {
+        m_firstPass = false;
+        m_mDC.FloodFill(0, 0, VERY_LTGREY_COLOR);
+
+        // Draw a filled rectangle with aborder
+        wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR);
+        m_mDC.SetBrush(ltGraphBkgBrush);
+        m_mDC.SetPen(wxPen(BLACK_COLOR, 0));
+        m_mDC.DrawRectangle(m_rPlot);
+    }
+    if(m_newdata)
+    {
+        m_newdata = false;
+        int t = m_rPlot.GetTop();
+        int l = m_rPlot.GetLeft();
+//        int r = m_rPlot.GetRight();
+        int h = m_rPlot.GetHeight();
+        int w = m_rPlot.GetWidth();
+        pDC.Blit(l, t, w, h, &m_mDC, l, t);
+    }
+    drawGraticule(pDC);
+    m_mDC.SetBrush(wxNullBrush);
+    m_mDC.SelectObject(wxNullBitmap);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotPanel::drawGraticule(wxAutoBufferedPaintDC& pDC)
+{
+    int p;
+    char buf[15];
+    wxString s;
+
+    // Vertical gridlines
+    pDC.SetPen(m_penShortDash);
+    for(p = (PLOT_BORDER + XLEFT_OFFSET + GRID_INCREMENT); p < ((m_rGrid.GetWidth() - XLEFT_OFFSET) + GRID_INCREMENT); p += GRID_INCREMENT)
+    {
+        pDC.DrawLine(p, (m_rGrid.GetHeight() + PLOT_BORDER), p, PLOT_BORDER);
+    }
+    // Horizontal gridlines
+    pDC.SetPen(m_penDotDash);
+    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
+    {
+        pDC.DrawLine(PLOT_BORDER + XLEFT_OFFSET, (p + PLOT_BORDER), (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), (p + PLOT_BORDER));
+    }
+    // Label the X-Axis
+    pDC.SetPen(wxPen(GREY_COLOR, 1));
+    for(p = GRID_INCREMENT; p < (m_rGrid.GetWidth() - YBOTTOM_OFFSET); p += GRID_INCREMENT)
+    {
+        sprintf(buf, "%1.1f Hz",(double)(p / 10));
+        pDC.DrawText(buf, p - PLOT_BORDER + XLEFT_OFFSET, m_rGrid.GetHeight() + YBOTTOM_OFFSET/2);
+    }
+    // Label the Y-Axis
+    //for(p = GRID_INCREMENT; p < (h - YBOTTOM_OFFSET); p += GRID_INCREMENT)
+    for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT)
+    {
+        sprintf(buf, "%1.0f", (double)((m_rGrid.GetHeight() - p) * -10));
+        pDC.DrawText(buf, XLEFT_TEXT_OFFSET, p);
+    }
+}
+
+//-------------------------------------------------------------------------
+// paintEvent()
+//
+// Called by the system of by wxWidgets when the panel needs
+// to be redrawn. You can also trigger this call by calling
+// Refresh()/Update().
+//-------------------------------------------------------------------------
+void PlotPanel::OnPaint(wxPaintEvent & evt)
+{
+    wxAutoBufferedPaintDC pdc(this);
+    draw(pdc);
+}
+
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot.h b/freedv/tags/1.2.2/src/fdmdv2_plot.h
new file mode 100644 (file)
index 0000000..25309d3
--- /dev/null
@@ -0,0 +1,150 @@
+//==========================================================================
+// Name:            fdmdv2_plot.h
+// Purpose:         Declares simple wxWidgets application with GUI
+// Created:         Apr. 10, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+//#include "fdmdv2_main.h"
+#ifndef __FDMDV2_PLOT__
+#define __FDMDV2_PLOT__
+#include <wx/wx.h>
+#include <wx/aui/auibook.h>
+#include <wx/rawbmp.h>
+#include <wx/image.h>
+#include <wx/dcbuffer.h>
+
+#define MAX_ZOOM            7
+#define MAX_BMP_X           (400 * MAX_ZOOM)
+#define MAX_BMP_Y           (400 * MAX_ZOOM)
+#define DATA_LINE_HEIGHT    10
+#define TEXT_BASELINE_OFFSET_Y  -5
+
+
+#define wxUSE_FILEDLG       1
+#define wxUSE_LIBPNG        1
+#define wxUSE_LIBJPEG       1
+#define wxUSE_GIF           1
+#define wxUSE_PCX           1
+#define wxUSE_LIBTIFF       1
+
+#define PLOT_BORDER         12
+#define XLEFT_OFFSET        40
+#define XLEFT_TEXT_OFFSET   6
+#define YBOTTOM_OFFSET      20
+#define YBOTTOM_TEXT_OFFSET 15
+#define GRID_INCREMENT      50
+
+#define BLACK_COLOR         wxColor(0x00, 0x00, 0x00)
+#define GREY_COLOR          wxColor(0x80, 0x80, 0x80)
+#define DARK_GREY_COLOR     wxColor(0x40, 0x40, 0x40)
+#define MEDIUM_GREY_COLOR   wxColor(0xC0, 0xC0, 0xC0)
+#define LIGHT_GREY_COLOR    wxColor(0xE0, 0xE0, 0xE0)
+#define VERY_LTGREY_COLOR   wxColor(0xF8, 0xF8, 0xF8)
+#define WHITE_COLOR         wxColor(0xFF, 0xFF, 0xFF)
+
+#define DARK_BLUE_COLOR     wxColor(0x00, 0x00, 0x60)
+#define BLUE_COLOR          wxColor(0x00, 0x00, 0xFF)
+#define LIGHT_BLUE_COLOR    wxColor(0x80, 0x80, 0xFF)
+
+#define RED_COLOR           wxColor(0xFF, 0x5E, 0x5E)
+#define LIGHT_RED_COLOR     wxColor(0xFF, 0xE0, 0xE0)
+#define DARK_RED_COLOR      wxColor(0xFF, 0x00, 0x00)
+#define PINK_COLOR          wxColor(0xFF, 0x80, 0xFF)
+
+#define LIGHT_GREEN_COLOR   wxColor(0xE3, 0xFF, 0xE0)
+#define GREEN_COLOR         wxColor(0x95, 0xFF, 0x8A)
+#define DARK_GREEN_COLOR    wxColor(0x20, 0xFF, 0x08)
+#define VERY_GREEN_COLOR    wxColor(0x00, 0xFF, 0x00)
+
+#define YELLOW_COLOR        wxColor(0xFF, 0xFF, 0x5E)
+#define LIGHT_YELLOW_COLOR  wxColor(0xFF, 0xFF, 0xB5)
+#define DARK_YELLOW_COLOR   wxColor(0xFF, 0xFF, 0x08)
+
+class MainFrame;
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotPanel
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotPanel : public wxPanel
+{
+    public:
+        PlotPanel(wxFrame* parent);
+        ~PlotPanel();
+        wxPen               m_penShortDash;
+        wxPen               m_penDotDash;
+        wxPen               m_penSolid;
+        wxRect              m_rCtrlPrev;
+        wxRect              m_rCtrl;
+        wxRect              m_rGrid;
+        wxRect              m_rPlot;
+        MainFrame           *m_pTopFrame;
+        wxAuiNotebook       *m_pNoteBook;
+        double              m_label_size;
+        wxSize              m_Bufsz;
+        bool                m_newdata;
+        wxImage             m_oImage;
+        wxBitmap            *m_pBmp;
+        wxNativePixelData   *m_pPix;
+
+        // some useful events
+        void            OnMouseMove(wxMouseEvent& event);
+        virtual void    OnMouseLeftDown(wxMouseEvent& event);
+        void            OnMouseLeftUp(wxMouseEvent& event);
+        virtual void    OnMouseRightDown(wxMouseEvent& event);
+        void            OnMouseWheelMoved(wxMouseEvent& event);
+        void            OnClose(wxCloseEvent& event ){ event.Skip(); }
+        void            OnSize( wxSizeEvent& event );
+        void            OnErase(wxEraseEvent& event);
+        void            OnPaint(wxPaintEvent& event);
+        //void OnUpdateUI( wxUpdateUIEvent& event ){ event.Skip(); }
+
+        void            paintEvent(wxPaintEvent & evt);
+        virtual void    draw(wxAutoBufferedPaintDC&  pdc);
+        virtual void    drawGraticule(wxAutoBufferedPaintDC&  pdc);
+        virtual double  SetZoomFactor(double zf);
+        virtual double  GetZoomFactor(double zf);
+        virtual void    OnShow(wxShowEvent& event);
+        virtual double  GetLabelSize();
+        virtual void    SetLabelSize(double size);
+
+    protected:
+        int             m_x;
+        int             m_y;
+        int             m_left;
+        int             m_top;
+        int             m_prev_w;
+        int             m_prev_h;
+        int             m_prev_x;
+        int             m_prev_y;
+        bool            m_use_bitmap;
+        bool            m_clip;
+        bool            m_rubberBand;
+        bool            m_mouseDown;
+        bool            m_firstPass;
+        double          m_zoomFactor;
+        int             m_greyscale;
+        int             m_line_color;
+    DECLARE_EVENT_TABLE()
+};
+#endif //__FDMDV2_PLOT__
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_scalar.cpp b/freedv/tags/1.2.2/src/fdmdv2_plot_scalar.cpp
new file mode 100644 (file)
index 0000000..7a07f46
--- /dev/null
@@ -0,0 +1,281 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scalar.cpp
+// Purpose:         Plots scalar amplitude against time
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_main.h"
+#include "fdmdv2_plot_scalar.h"
+
+BEGIN_EVENT_TABLE(PlotScalar, PlotPanel)
+    EVT_PAINT           (PlotScalar::OnPaint)
+    EVT_MOTION          (PlotScalar::OnMouseMove)
+    EVT_MOUSEWHEEL      (PlotScalar::OnMouseWheelMoved)
+    EVT_SIZE            (PlotScalar::OnSize)
+    EVT_SHOW            (PlotScalar::OnShow)
+//    EVT_ERASE_BACKGROUND(PlotScalar::OnErase)
+END_EVENT_TABLE()
+
+//----------------------------------------------------------------
+// PlotScalar()
+//----------------------------------------------------------------
+PlotScalar::PlotScalar(wxFrame* parent, 
+                       int    channels,           // number on channels to plot
+                      float  t_secs,             // time covered by entire x axis in seconds
+                      float  sample_period_secs, // time between each sample in seconds
+                      float  a_min,              // min ampltude of samples being plotted
+                      float  a_max,              // max ampltude of samples being plotted
+                      float  graticule_t_step,   // time step of x (time) axis graticule in seconds
+                      float  graticule_a_step,   // step of amplitude axis graticule
+                      const char a_fmt[],        // printf format string for amplitude axis labels
+                       int    mini                // true for mini-plot - don't draw graticule
+                      ): PlotPanel(parent)
+{
+    int i;
+
+    m_rCtrl = GetClientRect();
+
+    m_channels = channels;
+    m_t_secs = t_secs;
+    m_sample_period_secs = sample_period_secs;
+    m_a_min = a_min;
+    m_a_max = a_max;
+    m_graticule_t_step = graticule_t_step;
+    m_graticule_a_step = graticule_a_step;
+    assert(strlen(a_fmt) < 15);
+    strcpy(m_a_fmt, a_fmt);
+    m_mini = mini;
+
+    // work out number of samples we will store and allocate storage
+
+    m_samples = m_t_secs/m_sample_period_secs;
+    m_mem = new float[m_samples*m_channels];
+
+    for(i = 0; i < m_samples*m_channels; i++)
+    {
+        m_mem[i] = 0.0;
+    }
+}
+
+//----------------------------------------------------------------
+// ~PlotScalar()
+//----------------------------------------------------------------
+PlotScalar::~PlotScalar()
+{
+    delete m_mem;
+}
+
+//----------------------------------------------------------------
+// add_new_sample()
+//----------------------------------------------------------------
+void PlotScalar::add_new_sample(int channel, float sample)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+    for(i = 0; i < m_samples-1; i++)
+    {
+        m_mem[offset+i] = m_mem[offset+i+1];
+    }
+    m_mem[offset+m_samples-1] = sample;
+}
+
+//----------------------------------------------------------------
+// add_new_samples()
+//----------------------------------------------------------------
+void  PlotScalar::add_new_short_samples(int channel, short samples[], int length, float scale_factor)
+{
+    int i;
+    int offset = channel*m_samples;
+
+    assert(channel < m_channels);
+
+    for(i = 0; i < m_samples-length; i++)
+        m_mem[offset+i] = m_mem[offset+i+length];
+    for(; i < m_samples; i++)
+       m_mem[offset+i] = (float)*samples++/scale_factor;
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotScalar::draw(wxAutoBufferedPaintDC&  dc)
+{
+    float index_to_px;
+    float a_to_py;
+    int   i;
+    int   x, y;
+    int   prev_x, prev_y;
+    float a;
+
+    m_rCtrl = GetClientRect();
+    m_rGrid = m_rCtrl;
+    if (!m_mini)
+        m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    //printf("h %d w %d\n", m_rCtrl.GetWidth(), m_rCtrl.GetHeight());
+    //printf("h %d w %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
+
+    // black background
+
+    dc.Clear();
+    if (m_mini)
+        m_rPlot = wxRect(0, 0, m_rGrid.GetWidth(), m_rGrid.GetHeight());        
+    else
+        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+   
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+
+    index_to_px = (float)m_rGrid.GetWidth()/m_samples;
+    a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
+
+    wxPen pen;
+    pen.SetColour(DARK_GREEN_COLOR);
+    pen.SetWidth(1);
+    dc.SetPen(pen);
+
+    // draw all samples
+
+    prev_x = prev_y = 0; // stop warning
+
+    // plot each channel 
+
+    int offset;
+    for(offset=0; offset<m_channels*m_samples; offset+=m_samples) {
+
+        for(i = 0; i < m_samples; i++) {
+            x = index_to_px * i;
+            a = m_mem[offset+i];
+            if (a < m_a_min) a = m_a_min;
+            if (a > m_a_max) a = m_a_max;
+
+            // invert y axis and offset by minimum
+
+            y = m_rGrid.GetHeight() - a_to_py * a + m_a_min*a_to_py;
+
+            // put inside plot window
+
+            if (!m_mini) {
+                x += PLOT_BORDER + XLEFT_OFFSET;
+                y += PLOT_BORDER;
+            }
+
+            if (i)
+                dc.DrawLine(x, y, prev_x, prev_y);
+            prev_x = x; prev_y = y;
+        }
+    }
+
+    drawGraticule(dc);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotScalar::drawGraticule(wxAutoBufferedPaintDC&  dc)
+{
+    float    t, a;
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    sec_to_px;
+    float    a_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    sec_to_px = (float)m_rGrid.GetWidth()/m_t_secs;
+    a_to_py = (float)m_rGrid.GetHeight()/(m_a_max - m_a_min);
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Vertical gridlines
+
+    dc.SetPen(m_penShortDash);
+    for(t=0; t<=m_t_secs; t+=m_graticule_t_step) {
+       x = t*sec_to_px;
+       if (m_mini) {
+            dc.DrawLine(x, m_rGrid.GetHeight(), x, 0);
+        }
+        else {
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        }
+        if (!m_mini) {
+            sprintf(buf, "%2.1fs", t);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+        }
+    }
+
+    // Horizontal gridlines
+
+    dc.SetPen(m_penDotDash);
+    for(a=m_a_min; a<m_a_max; a+=m_graticule_a_step) {
+       y = m_rGrid.GetHeight() - a*a_to_py + m_a_min*a_to_py;
+       if (m_mini) {
+            dc.DrawLine(0, y, m_rGrid.GetWidth(), y);
+        }
+        else {
+            y += PLOT_BORDER;
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        }
+        if (!m_mini) {
+            sprintf(buf, m_a_fmt, a);
+            GetTextExtent(buf, &text_w, &text_h);
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+        }
+   }
+
+
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotScalar::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotScalar::OnSize(wxSizeEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotScalar::OnShow(wxShowEvent& event)
+{
+}
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_scalar.h b/freedv/tags/1.2.2/src/fdmdv2_plot_scalar.h
new file mode 100644 (file)
index 0000000..7043987
--- /dev/null
@@ -0,0 +1,73 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scalar.h
+// Purpose:         Defines a scalar plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SCALAR__
+#define __FDMDV2_PLOT_SCALAR__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotScalar
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotScalar: public PlotPanel
+{
+    public:
+
+    PlotScalar(wxFrame* parent,
+               int   channels,
+              float t_secs, 
+              float sample_period_secs,
+              float a_min,
+              float a_max,
+              float graticule_t_step,   
+              float graticule_a_step,
+              const char  a_fmt[],
+               int   mini
+              );
+        ~PlotScalar();
+         void add_new_sample(int channel, float sample);
+         void add_new_short_samples(int channel, short samples[], int length, float scale_factor);
+
+    protected:
+
+         int      m_channels;
+        float    m_t_secs;
+        float    m_sample_period_secs;
+        float    m_a_min;
+        float    m_a_max;
+        float    m_graticule_t_step;   
+        float    m_graticule_a_step;
+        char     m_a_fmt[15];
+         int      m_mini;
+        int      m_samples;
+        float   *m_mem;              
+
+        void draw(wxAutoBufferedPaintDC&  dc);
+       void drawGraticule(wxAutoBufferedPaintDC&  dc);
+        void OnPaint(wxPaintEvent& event);
+        void OnSize(wxSizeEvent& event);
+        void OnShow(wxShowEvent& event);
+
+        DECLARE_EVENT_TABLE()
+};
+
+#endif // __FDMDV2_PLOT_SCALAR__
+
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_scatter.cpp b/freedv/tags/1.2.2/src/fdmdv2_plot_scatter.cpp
new file mode 100644 (file)
index 0000000..12957f4
--- /dev/null
@@ -0,0 +1,289 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scatter.cpp
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
+// Created:         June 24, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_plot_scatter.h"
+
+BEGIN_EVENT_TABLE(PlotScatter, PlotPanel)
+    EVT_PAINT           (PlotScatter::OnPaint)
+    EVT_MOTION          (PlotScatter::OnMouseMove)
+    EVT_MOUSEWHEEL      (PlotScatter::OnMouseWheelMoved)
+    EVT_SIZE            (PlotScatter::OnSize)
+    EVT_SHOW            (PlotScatter::OnShow)
+//    EVT_ERASE_BACKGROUND(PlotScatter::OnErase)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// PlotScatter
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotScatter::PlotScatter(wxFrame* parent) : PlotPanel(parent)
+{
+    int i;
+
+    for(i=0; i < SCATTER_MEM_SYMS_MAX; i++)
+    {
+        m_mem[i].real = 0.0;
+        m_mem[i].imag = 0.0;
+    }
+
+    m_filter_max_xy = m_filter_max_y = 0.1;
+
+    // defaults so we start off with something sensible
+
+    Nsym = 14+1;
+    scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
+    assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
+
+    Ncol = 0;
+    memset(eye_mem, 0, sizeof(eye_mem));
+
+    mode = PLOT_SCATTER_MODE_SCATTER;
+}
+
+// changing number of carriers changes number of symbols to plot
+void PlotScatter::setNc(int Nc) {
+    Nsym = Nc+1;
+    assert(Nsym <= (MODEM_STATS_NC_MAX+1));
+    scatterMemSyms = ((int)(SCATTER_MEM_SECS*(Nsym/DT)));
+    assert(scatterMemSyms <= SCATTER_MEM_SYMS_MAX);
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotScatter::draw(wxAutoBufferedPaintDC& dc)
+{
+    float x_scale;
+    float y_scale;
+    int   i,j;
+    int   x;
+    int   y;
+    wxColour sym_to_colour[] = {wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255), 
+                                wxColor(255,255,0),
+                                wxColor(255,255,255),
+                                wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255), 
+                                wxColor(255,255,0),
+                                wxColor(255,255,255),
+                                wxColor(0,0,255), 
+                                wxColor(0,255,0),
+                                wxColor(0,255,255),
+                                wxColor(255,0,0),
+                                wxColor(255,0,255)
+    };
+
+    m_rCtrl = GetClientRect();
+    m_rGrid = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    // black background
+
+    dc.Clear();
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+    wxPen pen;
+    pen.SetWidth(1); // note this is ignored by DrawPoint
+
+    if (mode == PLOT_SCATTER_MODE_SCATTER) {
+
+        // automatically scale, first measure the maximum value
+
+        float max_xy = 1E-12;
+        float real,imag;
+        for(i=0; i< scatterMemSyms; i++) {
+            real = fabs(m_mem[i].real);
+            imag = fabs(m_mem[i].imag);
+            if (real > max_xy)
+                max_xy = real;
+            if (imag > max_xy)
+                max_xy = imag;
+        }
+
+        // smooth it out and set a lower limit to prevent divide by 0 issues
+
+        m_filter_max_xy = BETA*m_filter_max_xy + (1 - BETA)*2.5*max_xy;
+        if (m_filter_max_xy < 0.001)
+            m_filter_max_xy = 0.001;
+
+        // quantise to log steps to prevent scatter scaling bobbing about too
+        // much as scaling varies
+
+        float quant_m_filter_max_xy = exp(floor(0.5+log(m_filter_max_xy)));
+        //printf("max_xy: %f m_filter_max_xy: %f quant_m_filter_max_xy: %f\n", max_xy, m_filter_max_xy, quant_m_filter_max_xy);
+
+        x_scale = (float)m_rGrid.GetWidth()/quant_m_filter_max_xy;
+        y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_xy;
+
+        // draw all samples
+
+        for(i = 0; i < scatterMemSyms; i++) {
+            x = x_scale * m_mem[i].real + m_rGrid.GetWidth()/2;
+            y = y_scale * m_mem[i].imag + m_rGrid.GetHeight()/2;
+            x += PLOT_BORDER + XLEFT_OFFSET;
+            y += PLOT_BORDER;
+            pen.SetColour(sym_to_colour[i%Nsym]);
+            dc.SetPen(pen);
+            dc.DrawPoint(x, y);
+        }
+    }
+
+    if (mode == PLOT_SCATTER_MODE_EYE) {
+
+        pen.SetColour(DARK_GREEN_COLOR);
+        pen.SetWidth(1);
+        dc.SetPen(pen);
+
+        // automatically scale, first measure the maximum Y value
+
+        float max_y = 1E-12;
+        float min_y = 1E+12;
+        for(i=0; i<SCATTER_EYE_MEM_ROWS; i++) {
+            for(j=0; j<Ncol; j++) {
+                if (eye_mem[i][j] > max_y) {
+                    max_y = eye_mem[i][j];
+                }
+                if (eye_mem[i][j] < min_y) {
+                    min_y = eye_mem[i][j];
+                }
+            }
+        }
+        // smooth it out and set a lower limit to prevent divide by 0 issues
+
+        m_filter_max_y = BETA*m_filter_max_y + (1 - BETA)*2.5*max_y;
+        if (m_filter_max_y < 0.001)
+            m_filter_max_y = 0.001;
+
+        // quantise to log steps to prevent scatter scaling bobbing about too
+        // much as scaling varies
+
+        float quant_m_filter_max_y = exp(floor(0.5+log(m_filter_max_y)));
+        //printf("min_y: %4.3f max_y: %4.3f quant_m_filter_max_y: %4.3f\n", min_y, max_y, quant_m_filter_max_y);
+
+        x_scale = (float)m_rGrid.GetWidth()/Ncol;
+        y_scale = (float)m_rGrid.GetHeight()/quant_m_filter_max_y;
+        //printf("GetWidth(): %d GetHeight(): %d\n", m_rGrid.GetWidth(), m_rGrid.GetHeight());
+
+        // plot eye traces row by row
+
+        int prev_x, prev_y;
+        prev_x = prev_y = 0;
+        for(i=0; i<SCATTER_EYE_MEM_ROWS; i++) {
+            //printf("row: ");
+            for(j=0; j<Ncol; j++) {
+                x = x_scale * j;
+                y = m_rGrid.GetHeight()*0.75 - y_scale * eye_mem[i][j];
+               //printf("%4d,%4d  ", x, y);
+                x += PLOT_BORDER + XLEFT_OFFSET;
+                y += PLOT_BORDER;
+                pen.SetColour(sym_to_colour[i%4]);
+                dc.SetPen(pen);
+                if (j)
+                    dc.DrawLine(x, y, prev_x, prev_y);
+                prev_x = x; prev_y = y;
+            }
+            //printf("\n");
+        }
+        
+    }
+}
+
+//----------------------------------------------------------------
+// add_new_samples()
+//----------------------------------------------------------------
+void PlotScatter::add_new_samples_scatter(COMP samples[])
+{
+    int i,j;
+
+    // shift memory
+
+    for(i = 0; i < scatterMemSyms - Nsym; i++)
+    {
+        m_mem[i] = m_mem[i+Nsym];
+    }
+
+    // new samples
+
+    for(j=0; i < scatterMemSyms; i++,j++)
+    {
+        m_mem[i] = samples[j];
+    }
+}
+
+/* add a row of eye samples, updating buffer */
+
+void PlotScatter::add_new_samples_eye(float samples[], int n)
+{
+    int i,j;
+
+    Ncol = n; /* this should be constant for a given modem config */
+
+    assert(n <= PLOT_SCATTER_EYE_MAX_SAMPLES_ROW);
+
+    // eye traces are arrnaged in rows, shift memory of traces
+
+    for(i=0; i<SCATTER_EYE_MEM_ROWS-1; i++) {
+        for(j=0; j<Ncol; j++) {
+            eye_mem[i][j] = eye_mem[i+1][j];
+        }
+    }
+
+    // new samples in last row
+
+    for(j=0; j<Ncol; j++) {
+        eye_mem[SCATTER_EYE_MEM_ROWS-1][j] = samples[j];
+    }
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotScatter::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotScatter::OnSize(wxSizeEvent& event)
+{
+    // todo: clear screen
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotScatter::OnShow(wxShowEvent& event)
+{
+}
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_scatter.h b/freedv/tags/1.2.2/src/fdmdv2_plot_scatter.h
new file mode 100644 (file)
index 0000000..b5e3352
--- /dev/null
@@ -0,0 +1,65 @@
+//==========================================================================
+// Name:            fdmdv2_plot_scatter.h
+// Purpose:         A scatter plot derivative of fdmdv2_plot.
+// Created:         June 24, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SCATTER__
+#define __FDMDV2_PLOT_SCATTER__
+
+#include "comp.h"
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+#define PLOT_SCATTER_MODE_SCATTER            0
+#define PLOT_SCATTER_MODE_EYE                1
+#define PLOT_SCATTER_EYE_MAX_SAMPLES_ROW    80
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotScatter
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotScatter : public PlotPanel
+{
+    public:
+        PlotScatter(wxFrame* parent);
+        ~PlotScatter(){};
+       void add_new_samples_scatter(COMP samples[]);
+       void add_new_samples_eye(float samples[], int n);
+       void setNc(int Nc);
+        void setEyeScatter(int eye_mode) {mode = eye_mode;}
+
+    protected:
+        int  mode;
+        COMP m_mem[SCATTER_MEM_SYMS_MAX];
+        COMP m_new_samples[MODEM_STATS_NC_MAX+1];
+        float eye_mem[SCATTER_EYE_MEM_ROWS][PLOT_SCATTER_EYE_MAX_SAMPLES_ROW];
+
+        void draw(wxAutoBufferedPaintDC&  dc);
+        void OnPaint(wxPaintEvent& event);
+        void OnSize(wxSizeEvent& event);
+        void OnShow(wxShowEvent& event);
+
+        DECLARE_EVENT_TABLE()
+
+    private:
+        int   Nsym;
+        int   Ncol;
+        int   scatterMemSyms;
+        float m_filter_max_xy, m_filter_max_y;
+};
+
+#endif //__FDMDV2_PLOT_SCATTER__
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_spectrum.cpp b/freedv/tags/1.2.2/src/fdmdv2_plot_spectrum.cpp
new file mode 100644 (file)
index 0000000..1f5be59
--- /dev/null
@@ -0,0 +1,267 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.cpp
+// Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 23, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+
+#include "fdmdv2_main.h"
+
+extern float g_avmag[];                 // average mag data passed to draw() 
+void fdmdv2_clickTune(float frequency); // callback to pass new click freq
+
+BEGIN_EVENT_TABLE(PlotSpectrum, PlotPanel)
+    EVT_MOTION          (PlotSpectrum::OnMouseMove)
+    EVT_LEFT_DOWN       (PlotSpectrum::OnMouseLeftDown)
+    EVT_LEFT_DCLICK     (PlotSpectrum::OnMouseLeftDoubleClick)
+    EVT_LEFT_UP         (PlotSpectrum::OnMouseLeftUp)
+    EVT_MOUSEWHEEL      (PlotSpectrum::OnMouseWheelMoved)
+    EVT_PAINT           (PlotSpectrum::OnPaint)
+    EVT_SHOW            (PlotSpectrum::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotSpectrum
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotSpectrum::PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, 
+                           float min_mag_db, float max_mag_db, bool clickTune): PlotPanel(parent)
+{
+    m_greyscale     = 0;
+    m_Bufsz         = GetMaxClientSize();
+    m_newdata       = false;
+    m_firstPass     = true;
+    m_line_color    = 0;
+    SetLabelSize(10.0);
+
+    m_magdB         = magdB;
+    m_n_magdB       = n_magdB;     // number of points in magdB that covers 0 ... MAX_F_HZ of spectrum
+    m_max_mag_db    = max_mag_db;
+    m_min_mag_db    = min_mag_db;
+    m_rxFreq        = 0.0;
+    m_clickTune     = clickTune;
+}
+
+//----------------------------------------------------------------
+// ~PlotSpectrum()
+//----------------------------------------------------------------
+PlotSpectrum::~PlotSpectrum()
+{
+}
+
+//----------------------------------------------------------------
+// OnSize()
+//----------------------------------------------------------------
+void PlotSpectrum::OnSize(wxSizeEvent& event) {
+}
+
+//----------------------------------------------------------------
+// OnPaint()
+//----------------------------------------------------------------
+void PlotSpectrum::OnPaint(wxPaintEvent& event)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotSpectrum::OnShow(wxShowEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotSpectrum::draw(wxAutoBufferedPaintDC& dc)
+{
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.  We need to work this out every time we draw
+    // as OnSize() may not be called before OnPaint(), for example when a new tab
+    // is selected
+
+    m_rGrid  = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    dc.Clear();
+
+    // black background
+
+    m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+    wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 0));
+    dc.DrawRectangle(m_rPlot);
+
+    // draw spectrum
+
+    int   x, y, prev_x, prev_y, index;
+    float index_to_px, mag_dB_to_py, mag;
+
+    m_newdata = false;
+
+    wxPen pen;
+    pen.SetColour(DARK_GREEN_COLOR);
+    pen.SetWidth(1);
+    dc.SetPen(pen);
+
+    index_to_px = (float)m_rGrid.GetWidth()/m_n_magdB;
+    mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
+
+    prev_x = PLOT_BORDER + XLEFT_OFFSET;
+    prev_y = PLOT_BORDER;
+    for(index = 0; index < m_n_magdB; index++)
+    {
+        x = index*index_to_px;
+        mag = m_magdB[index];
+        if (mag > m_max_mag_db) mag = m_max_mag_db;
+        if (mag < m_min_mag_db) mag = m_min_mag_db;
+        y = -(mag - m_max_mag_db) * mag_dB_to_py;
+
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        y += PLOT_BORDER;
+
+        if (index)
+            dc.DrawLine(x, y, prev_x, prev_y);
+        prev_x = x; prev_y = y;
+    }
+
+    // and finally draw Graticule
+
+    drawGraticule(dc);
+
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC&  dc)
+{
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    f, mag, freq_hz_to_px, mag_dB_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+    mag_dB_to_py = (float)m_rGrid.GetHeight()/(m_max_mag_db - m_min_mag_db);
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Check if small screen size means text will overlap
+
+    int textXStep = STEP_F_HZ*freq_hz_to_px;
+    int textYStep = STEP_MAG_DB*mag_dB_to_py;
+    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
+    GetTextExtent(buf, &text_w, &text_h);
+    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
+    //printf("text_w: %d textXStep: %d text_h: %d textYStep: %d  overlappedText: %d\n", text_w, textXStep, 
+    //      text_h, textYStep, overlappedText);
+
+    // Vertical gridlines
+
+    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) {
+       x = f*freq_hz_to_px;
+       x += PLOT_BORDER + XLEFT_OFFSET;
+
+        dc.SetPen(m_penShortDash);
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        dc.SetPen(wxPen(BLACK_COLOR, 1));
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+
+        sprintf(buf, "%4.0fHz", f);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+    }
+
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
+    // Horizontal gridlines
+
+    dc.SetPen(m_penDotDash);
+    for(mag=m_min_mag_db; mag<=m_max_mag_db; mag+=STEP_MAG_DB) {
+       y = -(mag - m_max_mag_db) * mag_dB_to_py;
+       y += PLOT_BORDER;
+       dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                   (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        sprintf(buf, "%3.0fdB", mag);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+    }
+
+    // red rx tuning line
+    
+    if (m_rxFreq != 0.0) {
+        dc.SetPen(wxPen(RED_COLOR, 2));
+        x = m_rxFreq*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
+        dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnMouseDown()
+//-------------------------------------------------------------------------
+void PlotSpectrum::OnMouseLeftDoubleClick(wxMouseEvent& event)
+{
+    m_mouseDown = true;
+    wxClientDC dc(this);
+
+    wxPoint pt(event.GetLogicalPosition(dc));
+
+    // map x coord to edges of actual plot
+    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
+    pt.y -= PLOT_BORDER;
+
+    // valid click if inside of plot
+    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0) && m_clickTune) {
+        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+        float clickFreq = (float)pt.x/freq_hz_to_px;
+
+        // see PlotWaterfall::OnMouseDown()
+
+        fdmdv2_clickTune(clickFreq);
+    }
+}
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_spectrum.h b/freedv/tags/1.2.2/src/fdmdv2_plot_spectrum.h
new file mode 100644 (file)
index 0000000..271eeb9
--- /dev/null
@@ -0,0 +1,58 @@
+//==========================================================================
+// Name:            fdmdv2_plot_spectrum.h
+// Purpose:         Defines a spectrum plot derived from fdmdv2_plot class.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_SPECTRUM__
+#define __FDMDV2_PLOT_SPECTRUM__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class Waterfall
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotSpectrum : public PlotPanel
+{
+    public:
+    PlotSpectrum(wxFrame* parent, float *magdB, int n_magdB, 
+                 float min_mag_db=MIN_MAG_DB, float max_mag_db=MAX_MAG_DB, bool clickTune=true);
+        ~PlotSpectrum();
+        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
+        void setFreqScale(int n_magdB) { m_n_magdB = n_magdB; }
+
+    protected:
+        void        OnPaint(wxPaintEvent& event);
+        void        OnSize(wxSizeEvent& event);
+        void        OnShow(wxShowEvent& event);
+        void        drawGraticule(wxAutoBufferedPaintDC& dc);
+        void        draw(wxAutoBufferedPaintDC& dc);
+        void        OnMouseLeftDoubleClick(wxMouseEvent& event);
+
+   private:
+        float       m_rxFreq;
+        float       m_max_mag_db;
+        float       m_min_mag_db;
+        float      *m_magdB;
+        int         m_n_magdB;  
+        bool        m_clickTune;
+
+        DECLARE_EVENT_TABLE()
+};
+
+#endif //__FDMDV2_PLOT_SPECTRUM__
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_waterfall.cpp b/freedv/tags/1.2.2/src/fdmdv2_plot_waterfall.cpp
new file mode 100644 (file)
index 0000000..cdbe01e
--- /dev/null
@@ -0,0 +1,483 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.cpp
+// Purpose:         Implements a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <string.h>
+#include "wx/wx.h"
+#include "fdmdv2_main.h"
+
+extern float g_avmag[];                 // av mag spec passed in to draw() 
+void fdmdv2_clickTune(float frequency); // callback to pass new click freq
+
+BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel)
+    EVT_PAINT           (PlotWaterfall::OnPaint)
+    EVT_MOTION          (PlotWaterfall::OnMouseMove)
+    EVT_LEFT_DCLICK     (PlotWaterfall::OnMouseLeftDoubleClick)
+    EVT_RIGHT_DOWN      (PlotWaterfall::OnMouseRightDown)
+    EVT_LEFT_UP         (PlotWaterfall::OnMouseLeftUp)
+    EVT_MOUSEWHEEL      (PlotWaterfall::OnMouseWheelMoved)
+    EVT_SIZE            (PlotWaterfall::OnSize)
+    EVT_SHOW            (PlotWaterfall::OnShow)
+END_EVENT_TABLE()
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class WaterfallPlot
+//
+// @class   WaterfallPlot
+// @author  David Witten
+// @date    $(Date)
+// @file    $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+PlotWaterfall::PlotWaterfall(wxFrame* parent, bool graticule, int colour): PlotPanel(parent)
+{
+
+    for(int i = 0; i < 255; i++)
+    {
+        m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0);
+    }
+    m_graticule     = graticule;
+    m_colour        = colour;
+    m_Bufsz         = GetMaxClientSize();
+    m_newdata       = false;
+    m_firstPass     = true;
+    m_line_color    = 0;
+    m_modem_stats_max_f_hz = MODEM_STATS_MAX_F_HZ;
+
+    SetLabelSize(10.0);
+
+    m_pBmp = NULL;
+    m_max_mag = MAX_MAG_DB;
+    m_min_mag = MIN_MAG_DB;
+}
+
+// When the window size gets set we can work outthe size of the window
+// we plot in and allocate a bit map of the correct size
+void PlotWaterfall::OnSize(wxSizeEvent& event) 
+{
+    // resize bit map
+
+    delete m_pBmp;
+    
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid  = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    // we want a bit map the size of m_rGrid
+
+    m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
+
+    m_dT = DT;
+}
+
+//----------------------------------------------------------------
+// paintEvent()
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+// Called by the system of by wxWidgets when the panel needs
+// to be redrawn. You can also trigger this call by calling
+// Refresh()/Update().
+//----------------------------------------------------------------
+void PlotWaterfall::OnPaint(wxPaintEvent & evt)
+{
+    wxAutoBufferedPaintDC dc(this);
+    draw(dc);
+}
+
+//----------------------------------------------------------------
+// OnShow()
+//----------------------------------------------------------------
+void PlotWaterfall::OnShow(wxShowEvent& event)
+{
+}
+
+//----------------------------------------------------------------
+// ~PlotWaterfall()
+//----------------------------------------------------------------
+PlotWaterfall::~PlotWaterfall()
+{
+}
+
+//----------------------------------------------------------------
+// heatmap()
+// map val to a rgb colour
+// from http://eddiema.ca/2011/01/21/c-sharp-heatmaps/
+//----------------------------------------------------------------
+unsigned PlotWaterfall::heatmap(float val, float min, float max)
+{
+    unsigned r = 0;
+    unsigned g = 0;
+    unsigned b = 0;
+
+    val = (val - min) / (max - min);
+    if(val <= 0.2)
+    {
+        b = (unsigned)((val / 0.2) * 255);
+    }
+    else if(val >  0.2 &&  val <= 0.7)
+    {
+        b = (unsigned)((1.0 - ((val - 0.2) / 0.5)) * 255);
+    }
+    if(val >= 0.2 &&  val <= 0.6)
+    {
+        g = (unsigned)(((val - 0.2) / 0.4) * 255);
+    }
+    else if(val >  0.6 &&  val <= 0.9)
+    {
+        g = (unsigned)((1.0 - ((val - 0.6) / 0.3)) * 255);
+    }
+    if(val >= 0.5)
+    {
+        r = (unsigned)(((val - 0.5) / 0.5) * 255);
+    }
+    //printf("%f %x %x %x\n", val, r, g, b);
+    return  (b << 16) + (g << 8) + r;
+}
+
+bool PlotWaterfall::checkDT(void)
+{
+    // Check dY is > 1 pixel before proceeding. For small screens
+    // and large WATERFALL_SECS_Y we might have less than one
+    // block per pixel.  In this case increase m_dT and perform draw
+    // less often
+
+    float px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    float dy = m_dT * px_per_sec;
+    
+    if (dy < 1.0) {
+        m_dT += DT;
+        return false;
+    }
+    else
+        return true;
+}
+
+//----------------------------------------------------------------
+// draw()
+//----------------------------------------------------------------
+void PlotWaterfall::draw(wxAutoBufferedPaintDC& dc)
+{
+
+    m_rCtrl  = GetClientRect();
+
+    // m_rGrid is coords of inner window we actually plot to.  We deflate it a bit
+    // to leave room for axis labels.
+
+    m_rGrid = m_rCtrl;
+    m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2)));
+
+    if (m_pBmp == NULL) 
+    {
+        // we want a bit map the size of m_rGrid
+        m_pBmp = new wxBitmap(m_rGrid.GetWidth(), m_rGrid.GetHeight(), 24);
+    }
+
+    dc.Clear();
+
+    if(m_newdata)
+    {
+        m_newdata = false;
+        plotPixelData();
+        dc.DrawBitmap(*m_pBmp, PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER);
+        m_dT = DT;
+    }
+    else 
+    {
+
+        // no data to plot so just erase to black.  Blue looks nicer
+        // but is same colour as low amplitude signal
+
+        // Bug on Linux: When Stop is pressed this code doesn't erase
+        // the lower 25% of the Waterfall Window
+
+        m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight());
+        wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
+        dc.SetBrush(ltGraphBkgBrush);
+        dc.SetPen(wxPen(BLACK_COLOR, 0));
+        dc.DrawRectangle(m_rPlot);
+    }
+    drawGraticule(dc);
+}
+
+//-------------------------------------------------------------------------
+// drawGraticule()
+//-------------------------------------------------------------------------
+void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
+{
+    int      x, y, text_w, text_h;
+    char     buf[15];
+    wxString s;
+    float    f, time, freq_hz_to_px, time_s_to_py;
+
+    wxBrush ltGraphBkgBrush;
+    ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT);
+    ltGraphBkgBrush.SetColour(*wxBLACK);
+    dc.SetBrush(ltGraphBkgBrush);
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+
+    freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+    time_s_to_py = (float)m_rGrid.GetHeight()/WATERFALL_SECS_Y;
+
+    // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
+    // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
+    //                                   PLOT_BORDER + m_rGrid.GetHeight())
+
+    // Check if small screen size means text will overlap
+
+    int textXStep = STEP_F_HZ*freq_hz_to_px;
+    int textYStep = WATERFALL_SECS_STEP*time_s_to_py;
+    sprintf(buf, "%4.0fHz", (float)MAX_F_HZ - STEP_F_HZ);
+    GetTextExtent(buf, &text_w, &text_h);
+    int overlappedText = (text_w > textXStep) || (text_h > textYStep);
+
+    // Major Vertical gridlines and legend
+    //dc.SetPen(m_penShortDash);
+    for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+
+        if (m_graticule)
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        else
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+            
+        sprintf(buf, "%4.0fHz", f);
+        GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+    }
+
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
+    // Horizontal gridlines
+    dc.SetPen(m_penDotDash);
+    for(time=0; time<=WATERFALL_SECS_Y; time+=WATERFALL_SECS_STEP) {
+       y = m_rGrid.GetHeight() - time*time_s_to_py;
+       y += PLOT_BORDER;
+
+        if (m_graticule)
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+        sprintf(buf, "%3.0fs", time);
+       GetTextExtent(buf, &text_w, &text_h);
+        if (!overlappedText)
+            dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
+   }
+
+    // red rx tuning line
+    dc.SetPen(wxPen(RED_COLOR, 2));
+    x = m_rxFreq*freq_hz_to_px;
+    x += PLOT_BORDER + XLEFT_OFFSET;
+    //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
+    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
+    
+}
+
+//-------------------------------------------------------------------------
+// plotPixelData()
+//-------------------------------------------------------------------------
+void PlotWaterfall::plotPixelData()
+{
+    float       spec_index_per_px;
+    float       intensity_per_dB;
+    float       px_per_sec;
+    int         index;
+    float       dy;
+    int         dy_blocks;
+    int         b;
+    int         px;
+    int         py;
+    int         intensity;
+
+    /*
+      Design Notes:
+
+      The height in pixels represents WATERFALL_SECS_Y of data.  Every DT
+      seconds we get a vector of MODEM_STATS_NSPEC spectrum samples which we use
+      to update the last row.  The height of each row is dy pixels, which
+      maps to DT seconds.  We call each dy high rectangle of pixels a
+      block.
+
+    */
+
+    // determine dy, the height of one "block"
+    px_per_sec = (float)m_rGrid.GetHeight() / WATERFALL_SECS_Y;
+    dy = m_dT * px_per_sec;
+
+    // number of dy high blocks in spectrogram
+    dy_blocks = m_rGrid.GetHeight()/ dy;
+
+    // update min and max amplitude estimates
+    float max_mag = MIN_MAG_DB;
+
+    int min_fft_bin=((float)200/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
+    int max_fft_bin=((float)2800/m_modem_stats_max_f_hz)*MODEM_STATS_NSPEC;
+
+    for(int i=min_fft_bin; i<max_fft_bin; i++) 
+    {
+        if (g_avmag[i] > max_mag)
+        {
+            max_mag = g_avmag[i];
+        }
+    }
+
+    m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
+    m_min_mag = max_mag - 20.0;
+    //printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
+    //intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
+    intensity_per_dB  = (float)256 /(m_max_mag - m_min_mag);
+    spec_index_per_px = ((float)(MAX_F_HZ)/(float)m_modem_stats_max_f_hz)*(float)MODEM_STATS_NSPEC / (float) m_rGrid.GetWidth();
+
+    /*
+    printf("h %d w %d px_per_sec %d dy %d dy_blocks %d spec_index_per_px: %f\n", 
+       m_rGrid.GetHeight(), m_rGrid.GetWidth(), px_per_sec, 
+       dy, dy_blocks, spec_index_per_px);
+    */
+
+    // Shift previous bit map up one row of blocks ----------------------------
+    wxNativePixelData data(*m_pBmp);
+    wxNativePixelData::Iterator bitMapStart(data);
+    wxNativePixelData::Iterator p = bitMapStart;
+
+    for(b = 0; b < dy_blocks - 1; b++) 
+    {
+        wxNativePixelData::Iterator psrc = bitMapStart;
+        wxNativePixelData::Iterator pdest = bitMapStart;
+        pdest.OffsetY(data, dy * b);
+        psrc.OffsetY(data, dy * (b+1));
+
+        // copy one line of blocks
+
+        for(py = 0; py < dy; py++) 
+        {
+            wxNativePixelData::Iterator pdestRowStart = pdest;
+            wxNativePixelData::Iterator psrcRowStart = psrc;
+
+            for(px = 0; px < m_rGrid.GetWidth(); px++) 
+            {
+                pdest.Red() = psrc.Red();
+                pdest.Green() = psrc.Green();
+                pdest.Blue() = psrc.Blue();
+                pdest++;
+                psrc++;
+            }
+            pdest = pdestRowStart;
+            pdest.OffsetY(data, 1);
+            psrc = psrcRowStart;
+            psrc.OffsetY(data, 1);         
+        }
+    }
+
+    // Draw last line of blocks using latest amplitude data ------------------
+    p = bitMapStart;
+    p.OffsetY(data, dy *(dy_blocks - 1));
+    for(py = 0; py < dy; py++)
+    {
+        wxNativePixelData::Iterator rowStart = p;
+
+        for(px = 0; px < m_rGrid.GetWidth(); px++)
+        {
+            index = px * spec_index_per_px;
+            assert(index < MODEM_STATS_NSPEC);
+
+            intensity = intensity_per_dB * (g_avmag[index] - m_min_mag);
+            if(intensity > 255) intensity = 255;
+            if (intensity < 0) intensity = 0;
+            //printf("%d %f %d \n", index, g_avmag[index], intensity);
+
+            switch (m_colour) {
+            case 0:
+                p.Red() = m_heatmap_lut[intensity] & 0xff;
+                p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
+                p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
+                break;
+            case 1:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                p.Blue() = intensity;       
+                break;
+            case 2:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                if (intensity < 127)
+                    p.Blue() = intensity*2;
+                else
+                    p.Blue() = 255;
+                        
+                break;
+            }
+            ++p;
+        }
+        p = rowStart;
+        p.OffsetY(data, 1);
+    }
+
+}
+
+//-------------------------------------------------------------------------
+// OnMouseLeftDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseLeftDoubleClick(wxMouseEvent& event)
+{
+    m_mouseDown = true;
+    wxClientDC dc(this);
+
+    wxPoint pt(event.GetLogicalPosition(dc));
+
+    // map x coord to edges of actual plot
+    pt.x -= PLOT_BORDER + XLEFT_OFFSET;
+    pt.y -= PLOT_BORDER;
+
+    // valid click if inside of plot
+    if ((pt.x >= 0) && (pt.x <= m_rGrid.GetWidth()) && (pt.y >=0)) 
+    {
+        float freq_hz_to_px = (float)m_rGrid.GetWidth()/(MAX_F_HZ-MIN_F_HZ);
+        float clickFreq = (float)pt.x/freq_hz_to_px;
+
+        // communicate back to other threads
+        fdmdv2_clickTune(clickFreq);
+    }
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseRightDown(wxMouseEvent& event)
+{
+    m_colour++;
+    if (m_colour == 3)
+        m_colour = 0;
+}
+
diff --git a/freedv/tags/1.2.2/src/fdmdv2_plot_waterfall.h b/freedv/tags/1.2.2/src/fdmdv2_plot_waterfall.h
new file mode 100644 (file)
index 0000000..f4896c6
--- /dev/null
@@ -0,0 +1,73 @@
+//==========================================================================
+// Name:            fdmdv2_plot_waterfall.h
+// Purpose:         Defines a waterfall plot derivative of fdmdv2_plot.
+// Created:         June 22, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __FDMDV2_PLOT_WATERFALL__
+#define __FDMDV2_PLOT_WATERFALL__
+
+#include "fdmdv2_plot.h"
+#include "fdmdv2_defines.h"
+
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+// Class PlotWaterfall
+//
+// @class $(Name)
+// @author $(User)
+// @date $(Date)
+// @file $(CurrentFileName).$(CurrentFileExt)
+// @brief
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
+class PlotWaterfall : public PlotPanel
+{
+    public:
+    PlotWaterfall(wxFrame* parent, bool graticule, int colour);
+        ~PlotWaterfall();
+        bool checkDT(void);
+        void setGreyscale(bool greyscale) { m_greyscale = greyscale; }
+        void setRxFreq(float rxFreq) { m_rxFreq = rxFreq; }
+        void setFs(int fs) { m_modem_stats_max_f_hz = fs/2; }
+
+    protected:
+        unsigned    m_heatmap_lut[256];
+
+        unsigned    heatmap(float val, float min, float max);
+
+        void        OnPaint(wxPaintEvent & evt);
+        void        OnSize(wxSizeEvent& event);
+        void        OnShow(wxShowEvent& event);
+        void        drawGraticule(wxAutoBufferedPaintDC&  dc);
+        void        draw(wxAutoBufferedPaintDC& dc);
+        void        plotPixelData();
+        void        OnMouseLeftDoubleClick(wxMouseEvent& event);
+        void        OnMouseRightDown(wxMouseEvent& event);
+
+    private:
+        float       m_dT;
+        float       m_rxFreq;
+        bool        m_graticule;
+        float       m_min_mag;
+        float       m_max_mag;
+        int         m_colour;
+        int         m_modem_stats_max_f_hz;
+
+        DECLARE_EVENT_TABLE()
+};
+
+#endif //__FDMDV2_PLOT_WATERFALL__
diff --git a/freedv/tags/1.2.2/src/freedv.icns b/freedv/tags/1.2.2/src/freedv.icns
new file mode 100644 (file)
index 0000000..5190e79
Binary files /dev/null and b/freedv/tags/1.2.2/src/freedv.icns differ
diff --git a/freedv/tags/1.2.2/src/hamlib.cpp b/freedv/tags/1.2.2/src/hamlib.cpp
new file mode 100644 (file)
index 0000000..ff80b24
--- /dev/null
@@ -0,0 +1,160 @@
+//==========================================================================
+// Name:            hamlib.cpp
+//
+// Purpose:         Hamlib integration for FreeDV
+// Created:         May 2013
+// Authors:         Joel Stanley
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include <hamlib.h>
+
+#include <vector>
+#include <algorithm>
+
+using namespace std;
+
+typedef std::vector<const struct rig_caps *> riglist_t;
+
+static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2);
+static int build_list(const struct rig_caps *rig, rig_ptr_t);
+
+Hamlib::Hamlib() : m_rig(NULL) {
+    /* Stop hamlib from spewing info to stderr. */
+    rig_set_debug(RIG_DEBUG_NONE);
+
+    /* Create sorted list of rigs. */
+    rig_load_all_backends();
+    rig_list_foreach(build_list, &m_rigList);
+    sort(m_rigList.begin(), m_rigList.end(), rig_cmp);
+
+    /* Reset debug output. */
+    rig_set_debug(RIG_DEBUG_VERBOSE);
+
+    m_rig = NULL;
+}
+
+Hamlib::~Hamlib() {
+       if(m_rig)
+               close();
+}
+
+static int build_list(const struct rig_caps *rig, rig_ptr_t rigList) {
+    ((riglist_t *)rigList)->push_back(rig); 
+    return 1;
+}
+
+static bool rig_cmp(const struct rig_caps *rig1, const struct rig_caps *rig2) {
+    /* Compare manufacturer. */
+    int r = strcasecmp(rig1->mfg_name, rig2->mfg_name);
+    if (r != 0)
+        return r < 0;
+
+    /* Compare model. */
+    r = strcasecmp(rig1->model_name, rig2->model_name);
+    if (r != 0)
+        return r < 0;
+
+    /* Compare rig ID. */
+    return rig1->rig_model < rig2->rig_model;
+}
+
+void Hamlib::populateComboBox(wxComboBox *cb) {
+
+    riglist_t::const_iterator rig = m_rigList.begin();
+    for (; rig !=m_rigList.end(); rig++) {
+        char name[128];
+        snprintf(name, 128, "%s %s", (*rig)->mfg_name, (*rig)->model_name); 
+        cb->Append(name);
+    }
+}
+
+bool Hamlib::connect(unsigned int rig_index, const char *serial_port, const int serial_rate) {
+    /* Look up model from index. */
+    if (rig_index >= m_rigList.size()) {
+        return false;
+    }
+    fprintf(stderr, "rig: %s %s (%d)\n", m_rigList[rig_index]->mfg_name,
+            m_rigList[rig_index]->model_name, m_rigList[rig_index]->rig_model);
+
+       if(m_rig) {
+               printf("Closing old hamlib instance!\n");
+               close();
+       }
+
+    /* Initialise, configure and open. */
+
+    m_rig = rig_init(m_rigList[rig_index]->rig_model);
+
+    if (!m_rig)
+        return false;
+
+    /* TODO we may also need civaddr for Icom */
+
+    strncpy(m_rig->state.rigport.pathname, serial_port, FILPATHLEN - 1);
+    if (serial_rate) {
+        m_rig->state.rigport.parm.serial.rate = serial_rate;
+    }
+    fprintf(stderr, "hamlib: setting serial rate: %d\n", m_rig->state.rigport.parm.serial.rate);
+
+    if (rig_open(m_rig) == RIG_OK) {
+        return true;
+    }
+
+    return false;
+}
+
+int Hamlib::get_serial_rate(void) {
+    return m_rig->state.rigport.parm.serial.rate;
+}
+
+int Hamlib::get_data_bits(void) {
+    return m_rig->state.rigport.parm.serial.data_bits;
+}
+
+int Hamlib::get_stop_bits(void) {
+    return m_rig->state.rigport.parm.serial.stop_bits;
+}
+
+bool Hamlib::ptt(bool press, wxString &hamlibError) {
+    fprintf(stderr,"Hamlib::ptt: %d\n", press);
+    hamlibError = "";
+
+    if(!m_rig)
+        return false;
+
+    /* TODO(Joel): make ON_DATA and ON configurable. */
+
+    ptt_t on = press ? RIG_PTT_ON : RIG_PTT_OFF;
+
+    /* TODO(Joel): what should the VFO option be? */
+
+    int retcode = rig_set_ptt(m_rig, RIG_VFO_CURR, on);
+    fprintf(stderr,"Hamlib::ptt: rig_set_ptt returned: %d\n", retcode);
+    if (retcode != RIG_OK ) {
+        fprintf(stderr, "rig_set_ptt: error = %s \n", rigerror(retcode));
+        hamlibError = rigerror(retcode);
+    }
+
+    return retcode == RIG_OK;
+}
+
+void Hamlib::close(void) {
+    if(m_rig) {
+        rig_close(m_rig);
+        rig_cleanup(m_rig);
+        m_rig = NULL;
+    }
+}
diff --git a/freedv/tags/1.2.2/src/hamlib.h b/freedv/tags/1.2.2/src/hamlib.h
new file mode 100644 (file)
index 0000000..150ed86
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef HAMLIB_H
+#define HAMLIB_H
+
+extern "C" {
+#include <hamlib/rig.h>
+}
+#include <wx/combobox.h>
+#include <vector>
+
+class Hamlib {
+
+    public:
+        Hamlib();
+        ~Hamlib();
+        void populateComboBox(wxComboBox *cb);
+        bool connect(unsigned int rig_index, const char *serial_port);
+        bool ptt(bool press, wxString &hamlibError);
+        void close(void);
+        int get_serial_rate(void);
+        int get_data_bits(void);
+        int get_stop_bits(void);
+
+        typedef std::vector<const struct rig_caps *> riglist_t;
+
+    private:
+        RIG *m_rig;
+        /* Sorted list of rigs. */
+        riglist_t m_rigList;
+};
+
+#endif /*HAMLIB_H*/
diff --git a/freedv/tags/1.2.2/src/info.plist b/freedv/tags/1.2.2/src/info.plist
new file mode 100644 (file)
index 0000000..8f0d4c3
--- /dev/null
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>CFBundleIconFile</key>
+       <string>freedv</string>
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleDevelopmentRegion</key>
+       <string>en</string>
+       <key>CFBundleExecutable</key>
+       <string>freedv</string>
+       <key>CFBundleIconFile</key>
+       <string></string>
+       <key>CFBundleIdentifier</key>
+       <string>org.freedv.freedv</string>
+       <key>CFBundleInfoDictionaryVersion</key>
+       <string>6.0</string>
+       <key>CFBundleName</key>
+       <string>FreeDV</string>
+       <key>CFBundlePackageType</key>
+       <string>APPL</string>
+       <key>CFBundleShortVersionString</key>
+       <string>1.0</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundleVersion</key>
+       <string>1</string>
+       <key>LSMinimumSystemVersion</key>
+       <string>10.5</string>
+       <key>NSHumanReadableCopyright</key>
+       <string>Copyright © 2012 FreeDV. All rights reserved.</string>
+       <!--<key>NSMainNibFile</key>
+       <string>MainMenu</string>-->
+       <key>NSPrincipalClass</key>
+       <string>NSApplication</string>
+</dict>
+</plist>
\ No newline at end of file
diff --git a/freedv/tags/1.2.2/src/serialport.cpp b/freedv/tags/1.2.2/src/serialport.cpp
new file mode 100644 (file)
index 0000000..59dd0c9
--- /dev/null
@@ -0,0 +1,234 @@
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "serialport.h"
+
+Serialport::Serialport() {
+    com_handle = COM_HANDLE_INVALID;
+}
+
+Serialport::~Serialport() {
+    if (isopen()) {
+        closeport();
+    }
+}
+
+// returns true if comm port opened OK, false if there was a problem
+
+bool Serialport::openport(const char name[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos)
+{
+    if (com_handle != COM_HANDLE_INVALID) {
+        closeport();
+    }
+
+    m_useRTS = useRTS;
+    m_RTSPos = RTSPos;
+    m_useDTR = useDTR;
+    m_DTRPos = DTRPos;
+
+#ifdef _WIN32
+       {
+               COMMCONFIG CC;
+               DWORD CCsize=sizeof(CC);
+               COMMTIMEOUTS timeouts;
+               DCB     dcb;
+
+               if(GetDefaultCommConfigA(name, &CC, &CCsize)) {
+                       CC.dcb.fOutxCtsFlow             = FALSE;
+                       CC.dcb.fOutxDsrFlow             = FALSE;
+                       CC.dcb.fDtrControl              = DTR_CONTROL_DISABLE;
+                       CC.dcb.fDsrSensitivity  = FALSE;
+                       CC.dcb.fRtsControl              = RTS_CONTROL_DISABLE;
+                       SetDefaultCommConfigA(name, &CC, CCsize);
+               }
+
+               if((com_handle=CreateFileA(name
+                       ,GENERIC_READ|GENERIC_WRITE     /* Access */
+                       ,0                                                              /* Share mode */
+                       ,NULL                                                   /* Security attributes */
+                       ,OPEN_EXISTING                                  /* Create access */
+                       ,FILE_ATTRIBUTE_NORMAL                  /* File attributes */
+                       ,NULL                                                   /* Template */
+                       ))==INVALID_HANDLE_VALUE)
+                       return false;
+
+               if(GetCommTimeouts(com_handle, &timeouts)) {
+                       timeouts.ReadIntervalTimeout=MAXDWORD;
+                       timeouts.ReadTotalTimeoutMultiplier=0;
+                       timeouts.ReadTotalTimeoutConstant=0;            // No-wait read timeout
+                       timeouts.WriteTotalTimeoutMultiplier=0;
+                       timeouts.WriteTotalTimeoutConstant=5000;        // 5 seconds
+                       SetCommTimeouts(com_handle,&timeouts);
+               }
+
+               /* Force N-8-1 mode: */
+               if(GetCommState(com_handle, &dcb)==TRUE) {
+                       dcb.ByteSize            = 8;
+                       dcb.Parity                      = NOPARITY;
+                       dcb.StopBits            = ONESTOPBIT;
+                       dcb.DCBlength           = sizeof(DCB);
+                       dcb.fBinary                     = TRUE;
+                       dcb.fOutxCtsFlow        = FALSE;
+                       dcb.fOutxDsrFlow        = FALSE;
+                       dcb.fDtrControl         = DTR_CONTROL_DISABLE;
+                       dcb.fDsrSensitivity     = FALSE;
+                       dcb.fTXContinueOnXoff= TRUE;
+                       dcb.fOutX                       = FALSE;
+                       dcb.fInX                        = FALSE;
+                       dcb.fRtsControl         = RTS_CONTROL_DISABLE;
+                       dcb.fAbortOnError       = FALSE;
+                       SetCommState(com_handle, &dcb);
+               }
+       }
+#else
+       {
+               struct termios t;
+
+               if((com_handle=open(name, O_NONBLOCK|O_RDWR))== COM_HANDLE_INVALID)
+                       return false;
+
+               if(tcgetattr(com_handle, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+
+               t.c_iflag = (
+                                         IGNBRK   /* ignore BREAK condition */
+                                       | IGNPAR   /* ignore (discard) parity errors */
+                                       );
+               t.c_oflag = 0;  /* No output processing */
+               t.c_cflag = (
+                                         CS8         /* 8 bits */
+                                       | CREAD       /* enable receiver */
+
+               /*
+               Fun snippet from the FreeBSD manpage:
+
+                        If CREAD is set, the receiver is enabled.  Otherwise, no character is
+                        received.  Not all hardware supports this bit.  In fact, this flag is
+                        pretty silly and if it were not part of the termios specification it
+                        would be omitted.
+               */
+                                       | CLOCAL      /* ignore modem status lines */
+                                       );
+
+               t.c_lflag = 0;  /* No local modes */
+               if(tcsetattr(com_handle, TCSANOW, &t)==-1) {
+                       close(com_handle);
+                       com_handle = COM_HANDLE_INVALID;
+                       return false;
+               }
+               
+       }
+#endif
+       return true;
+}
+
+
+// fixme: this takes about one second to close under Linux
+
+void Serialport::closeport()
+{
+#ifdef _WIN32
+       CloseHandle(com_handle);
+#else
+       close(com_handle);
+#endif
+        com_handle = COM_HANDLE_INVALID;
+}
+
+//----------------------------------------------------------------
+// (raise|lower)(RTS|DTR)()
+//
+// Raises/lowers the specified signal
+//----------------------------------------------------------------
+
+void Serialport::raiseDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::raiseRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, SETRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIS, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerDTR(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRDTR);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_DTR;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::lowerRTS(void)
+{
+       if(com_handle == COM_HANDLE_INVALID)
+               return;
+#ifdef _WIN32
+       EscapeCommFunction(com_handle, CLRRTS);
+#else
+       {       // For C89 happiness
+               int flags = TIOCM_RTS;
+               ioctl(com_handle, TIOCMBIC, &flags);
+       }
+#endif
+}
+
+void Serialport::ptt(bool tx) {
+
+   /*  Truth table:
+
+          g_tx   RTSPos   RTS
+          -------------------
+          0      1        0
+          1      1        1
+          0      0        1
+          1      0        0
+
+          exclusive NOR
+    */
+
+    if (com_handle != COM_HANDLE_INVALID) {
+        if (m_useRTS) {
+            //fprintf(stderr, "g_tx: %d m_boolRTSPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolRTSPos, g_tx == wxGetApp().m_boolRTSPos);
+            if (tx == m_RTSPos)
+                raiseRTS();
+            else
+                lowerRTS();
+        }
+        if (m_useDTR) {
+            //fprintf(stderr, "g_tx: %d m_boolDTRPos: %d serialLine: %d\n", g_tx, wxGetApp().m_boolDTRPos, g_tx == wxGetApp().m_boolDTRPos);
+            if (tx == m_DTRPos)
+                raiseDTR();
+            else
+                lowerDTR();
+        }
+    }
+}
diff --git a/freedv/tags/1.2.2/src/serialport.h b/freedv/tags/1.2.2/src/serialport.h
new file mode 100644 (file)
index 0000000..e5db10b
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef SERIALPORT_H
+#define SERIALPORT_H
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <dlfcn.h>
+#endif
+
+// Serial ports called com port for historic reasons, especially on Windows machines 
+
+#ifdef _WIN32
+#define COM_HANDLE_INVALID                     INVALID_HANDLE_VALUE
+typedef HANDLE      com_handle_t;
+#else
+#define COM_HANDLE_INVALID                     -1
+typedef int         com_handle_t;
+#endif
+
+class Serialport {
+
+    public:
+        Serialport();
+        ~Serialport();
+        bool openport(const char port[], bool useRTS, bool RTSPos, bool useDTR, bool DTRPos);
+        bool isopen() {return (com_handle != COM_HANDLE_INVALID);}
+        void closeport();
+        void ptt(bool tx);
+
+    private:
+        com_handle_t  com_handle;
+        bool          m_useRTS, m_RTSPos, m_useDTR, m_DTRPos;
+
+        void raiseDTR(void);
+        void lowerDTR(void);
+        void raiseRTS(void);
+        void lowerRTS(void);
+};
+
+#endif /* SERIALPORT_H */
diff --git a/freedv/tags/1.2.2/src/sox/band.h b/freedv/tags/1.2.2/src/sox/band.h
new file mode 100644 (file)
index 0000000..5398ff4
--- /dev/null
@@ -0,0 +1,47 @@
+/* libSoX Bandpass effect file.     July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Lance Norskog And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ *
+ * Algorithm:  2nd order recursive filter.
+ * Formula stolen from MUSIC56K, a toolkit of 56000 assembler stuff.
+ * Quote:
+ *   This is a 2nd order recursive band pass filter of the form.
+ *   y(n)= a * x(n) - b * y(n-1) - c * y(n-2)
+ *   where :
+ *        x(n) = "IN"
+ *        "OUT" = y(n)
+ *        c = EXP(-2*pi*cBW/S_RATE)
+ *        b = -4*c/(1+c)*COS(2*pi*cCF/S_RATE)
+ *   if cSCL=2 (i.e. noise input)
+ *        a = SQT(((1+c)*(1+c)-b*b)*(1-c)/(1+c))
+ *   else
+ *        a = SQT(1-b*b/(4*c))*(1-c)
+ *   endif
+ *   note :     cCF is the center frequency in Hertz
+ *        cBW is the band width in Hertz
+ *        cSCL is a scale factor, use 1 for pitched sounds
+ *   use 2 for noise.
+ *
+ *
+ * July 1, 1999 - Jan Paul Schmidt <jps@fundament.org>
+ *
+ *   This looks like the resonator band pass in SPKit. It's a
+ *   second order all-pole (IIR) band-pass filter described
+ *   at the pages 186 - 189 in
+ *     Dodge, Charles & Jerse, Thomas A. 1985:
+ *       Computer Music -- Synthesis, Composition and Performance.
+ *       New York: Schirmer Books.
+ *   Reference from the SPKit manual.
+ */
+
+  p->a2 = exp(-2 * M_PI * bw_Hz / effp->in_signal.rate);
+  p->a1 = -4 * p->a2 / (1 + p->a2) * cos(2 * M_PI * p->fc / effp->in_signal.rate);
+  p->b0 = sqrt(1 - p->a1 * p->a1 / (4 * p->a2)) * (1 - p->a2);
+  if (p->filter_type == filter_BPF_SPK_N) {
+    mult = sqrt(((1+p->a2) * (1+p->a2) - p->a1*p->a1) * (1-p->a2) / (1+p->a2)) / p->b0;
+    p->b0 *= mult;
+  }
diff --git a/freedv/tags/1.2.2/src/sox/biquad.c b/freedv/tags/1.2.2/src/sox/biquad.c
new file mode 100644 (file)
index 0000000..c57f190
--- /dev/null
@@ -0,0 +1,178 @@
+/* libSoX Biquad filter common functions   (c) 2006-7 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "biquad.h"
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+static char const * const width_str[] = {
+  "band-width(Hz)",
+  "band-width(kHz)",
+  "band-width(Hz, no warp)", /* deprecated */
+  "band-width(octaves)",
+  "Q",
+  "slope",
+};
+static char const all_width_types[] = "hkboqs";
+
+
+int lsx_biquad_getopts(sox_effect_t * effp, int argc, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  char width_type = *allowed_width_types;
+  char dummy, * dummy_p;     /* To check for extraneous chars. */
+  --argc, ++argv;
+
+  p->filter_type = filter_type;
+  if (argc < min_args || argc > max_args ||
+      (argc > fc_pos    && ((p->fc = lsx_parse_frequency(argv[fc_pos], &dummy_p)) <= 0 || *dummy_p)) ||
+      (argc > width_pos && ((unsigned)(sscanf(argv[width_pos], "%lf%c %c", &p->width, &width_type, &dummy)-1) > 1 || p->width <= 0)) ||
+      (argc > gain_pos  && sscanf(argv[gain_pos], "%lf %c", &p->gain, &dummy) != 1) ||
+      !strchr(allowed_width_types, width_type) || (width_type == 's' && p->width > 1))
+    return lsx_usage(effp);
+  p->width_type = strchr(all_width_types, width_type) - all_width_types;
+  if ((size_t)p->width_type >= strlen(all_width_types))
+    p->width_type = 0;
+  if (p->width_type == width_bw_kHz) {
+    p->width *= 1000;
+    p->width_type = width_bw_Hz;
+  }
+  return SOX_SUCCESS;
+}
+
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  /* Simplify: */
+  p->b2 /= p->a0;
+  p->b1 /= p->a0;
+  p->b0 /= p->a0;
+  p->a2 /= p->a0;
+  p->a1 /= p->a0;
+
+  p->o2 = p->o1 = p->i2 = p->i1 = 0;
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+
+  start(effp);
+
+  if (effp->global_info->plot == sox_plot_octave) {
+    printf(
+      "%% GNU Octave file (may also work with MATLAB(R) )\n"
+      "Fs=%g;minF=10;maxF=Fs/2;\n"
+      "sweepF=logspace(log10(minF),log10(maxF),200);\n"
+      "[h,w]=freqz([%.15e %.15e %.15e],[1 %.15e %.15e],sweepF,Fs);\n"
+      "semilogx(w,20*log10(h))\n"
+      "title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)')\n"
+      "xlabel('Frequency (Hz)')\n"
+      "ylabel('Amplitude Response (dB)')\n"
+      "axis([minF maxF -35 25])\n"
+      "grid on\n"
+      "disp('Hit return to continue')\n"
+      "pause\n"
+      , effp->in_signal.rate, p->b0, p->b1, p->b2, p->a1, p->a2
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_gnuplot) {
+    printf(
+      "# gnuplot file\n"
+      "set title 'SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)'\n"
+      "set xlabel 'Frequency (Hz)'\n"
+      "set ylabel 'Amplitude Response (dB)'\n"
+      "Fs=%g\n"
+      "b0=%.15e; b1=%.15e; b2=%.15e; a1=%.15e; a2=%.15e\n"
+      "o=2*pi/Fs\n"
+      "H(f)=sqrt((b0*b0+b1*b1+b2*b2+2.*(b0*b1+b1*b2)*cos(f*o)+2.*(b0*b2)*cos(2.*f*o))/(1.+a1*a1+a2*a2+2.*(a1+a1*a2)*cos(f*o)+2.*a2*cos(2.*f*o)))\n"
+      "set logscale x\n"
+      "set samples 250\n"
+      "set grid xtics ytics\n"
+      "set key off\n"
+      "plot [f=10:Fs/2] [-35:25] 20*log10(H(f))\n"
+      "pause -1 'Hit return to continue'\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  if (effp->global_info->plot == sox_plot_data) {
+    printf("# SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)\n"
+      "# IIR filter\n"
+      "# rate: %g\n"
+      "# name: b\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      "# name: a\n"
+      "# type: matrix\n"
+      "# rows: 3\n"
+      "# columns: 1\n"
+      "%24.16e\n%24.16e\n%24.16e\n"
+      , effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
+      , effp->in_signal.rate, effp->in_signal.rate
+      , p->b0, p->b1, p->b2, 1. /* a0 */, p->a1, p->a2);
+    return SOX_EOF;
+  }
+  return SOX_SUCCESS;
+}
+
+
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
+    sox_sample_t *obuf, size_t *isamp, size_t *osamp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  size_t len = *isamp = *osamp = min(*isamp, *osamp);
+  while (len--) {
+    double o0 = *ibuf*p->b0 + p->i1*p->b1 + p->i2*p->b2 - p->o1*p->a1 - p->o2*p->a2;
+    p->i2 = p->i1, p->i1 = *ibuf++;
+    p->o2 = p->o1, p->o1 = o0;
+    *obuf++ = SOX_ROUND_CLIP_COUNT(o0, effp->clips);
+  }
+  return SOX_SUCCESS;
+}
+
+static int create(sox_effect_t * effp, int argc, char * * argv)
+{
+  priv_t             * p = (priv_t *)effp->priv;
+  double             * d = &p->b0;
+  char               c;
+
+  --argc, ++argv;
+  if (argc == 6)
+    for (; argc && sscanf(*argv, "%lf%c", d, &c) == 1; --argc, ++argv, ++d);
+  return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+sox_effect_handler_t const * lsx_biquad_effect_fn(void)
+{
+  static sox_effect_handler_t handler = {
+    "biquad", "b0 b1 b2 a0 a1 a2", 0,
+    create, lsx_biquad_start, lsx_biquad_flow, NULL, NULL, NULL, sizeof(priv_t)
+  };
+  return &handler;
+}
diff --git a/freedv/tags/1.2.2/src/sox/biquad.h b/freedv/tags/1.2.2/src/sox/biquad.h
new file mode 100644 (file)
index 0000000..8786ac8
--- /dev/null
@@ -0,0 +1,78 @@
+/* libSoX Biquad filter common definitions (c) 2006-7 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef biquad_included
+#define biquad_included
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+
+typedef enum {
+  filter_LPF,
+  filter_HPF,
+  filter_BPF_CSG,
+  filter_BPF,
+  filter_notch,
+  filter_APF,
+  filter_peakingEQ,
+  filter_lowShelf,
+  filter_highShelf,
+  filter_LPF_1,
+  filter_HPF_1,
+  filter_BPF_SPK,
+  filter_BPF_SPK_N,
+  filter_AP1,
+  filter_AP2,
+  filter_deemph,
+  filter_riaa
+} filter_t;
+
+typedef enum {
+  width_bw_Hz,
+  width_bw_kHz,
+  /* The old, non-RBJ, non-freq-warped band-pass/reject response;
+   * leaving here for now just in case anybody misses it: */
+  width_bw_old,
+  width_bw_oct,
+  width_Q,
+  width_slope
+} width_t;
+
+/* Private data for the biquad filter effects */
+typedef struct {
+  double gain;             /* For EQ filters */
+  double fc;               /* Centre/corner/cutoff frequency */
+  double width;            /* Filter width; interpreted as per width_type */
+  width_t width_type;
+
+  filter_t filter_type;
+
+  double b0, b1, b2;       /* Filter coefficients */
+  double a0, a1, a2;       /* Filter coefficients */
+
+  sox_sample_t i1, i2;     /* Filter memory */
+  double      o1, o2;      /* Filter memory */
+} biquad_t;
+
+int lsx_biquad_getopts(sox_effect_t * effp, int n, char **argv,
+    int min_args, int max_args, int fc_pos, int width_pos, int gain_pos,
+    char const * allowed_width_types, filter_t filter_type);
+int lsx_biquad_start(sox_effect_t * effp);
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf, sox_sample_t *obuf,
+                        size_t *isamp, size_t *osamp);
+
+#endif
diff --git a/freedv/tags/1.2.2/src/sox/biquads.c b/freedv/tags/1.2.2/src/sox/biquads.c
new file mode 100644 (file)
index 0000000..19793a6
--- /dev/null
@@ -0,0 +1,400 @@
+/* libSoX Biquad filter effects   (c) 2006-8 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
+ *   see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
+ *
+ * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
+ *   Algorithms: Recursive single pole low/high pass filter
+ *   Reference: The Scientist and Engineer's Guide to Digital Signal Processing
+ *
+ *   low-pass: output[N] = input[N] * A + output[N-1] * B
+ *     X = exp(-2.0 * pi * Fc)
+ *     A = 1 - X
+ *     B = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC low-pass filter:
+ *
+ *     ---/\/\/\/\----------->
+ *                   |
+ *                  --- C
+ *                  ---
+ *                   |
+ *                   |
+ *                   V
+ *
+ *   high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
+ *     X  = exp(-2.0 * pi * Fc)
+ *     A0 = (1 + X) / 2
+ *     A1 = -(1 + X) / 2
+ *     B1 = X
+ *     Fc = cutoff freq / sample rate
+ *
+ *     Mimics an RC high-pass filter:
+ *
+ *         || C
+ *     ----||--------->
+ *         ||    |
+ *               <
+ *               > R
+ *               <
+ *               |
+ *               V
+ */
+
+
+#include "biquad.h"
+#include <assert.h>
+#include <string.h>
+
+typedef biquad_t priv_t;
+
+
+static int hilo1_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 1, 1, 0, 1, 2, "",
+      *effp->handler.name == 'l'? filter_LPF_1 : filter_HPF_1);
+}
+
+
+static int hilo2_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    return hilo1_getopts(effp, argc - 1, argv + 1);
+  if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc;
+  p->width = sqrt(0.5); /* Default to Butterworth */
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "qohk",
+      *effp->handler.name == 'l'? filter_LPF : filter_HPF);
+}
+
+
+static int bandpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF;
+  if (argc > 1 && strcmp(argv[1], "-c") == 0)
+    ++argv, --argc, type = filter_BPF_CSG;
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", type);
+}
+
+
+static int bandrej_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 2, 2, 0, 1, 2, "hkqob", filter_notch);
+}
+
+
+static int allpass_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_APF;
+  int m;
+  if (argc > 1 && strcmp(argv[1], "-1") == 0)
+    ++argv, --argc, type = filter_AP1;
+  else if (argc > 1 && strcmp(argv[1], "-2") == 0)
+    ++argv, --argc, type = filter_AP2;
+  m = 1 + (type == filter_APF);
+  return lsx_biquad_getopts(effp, argc, argv, m, m, 0, 1, 2, "hkqo", type);
+}
+
+
+static int tone_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->width = 0.5;
+  p->fc = *effp->handler.name == 'b'? 100 : 3000;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 3, 1, 2, 0, "shkqo",
+      *effp->handler.name == 'b'?  filter_lowShelf: filter_highShelf);
+}
+
+
+static int equalizer_getopts(sox_effect_t * effp, int argc, char **argv) {
+  return lsx_biquad_getopts(effp, argc, argv, 3, 3, 0, 1, 2, "qohk", filter_peakingEQ);
+}
+
+
+static int band_getopts(sox_effect_t * effp, int argc, char **argv) {
+  filter_t type = filter_BPF_SPK;
+  if (argc > 1 && strcmp(argv[1], "-n") == 0)
+    ++argv, --argc, type = filter_BPF_SPK_N;
+  return lsx_biquad_getopts(effp, argc, argv, 1, 2, 0, 1, 2, "hkqo", type);
+}
+
+
+static int deemph_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->fc    = 5283;
+  p->width = 0.4845;
+  p->gain  = -9.477;
+  return lsx_biquad_getopts(effp, argc, argv, 0, 0, 0, 1, 2, "s", filter_deemph);
+}
+
+
+static int riaa_getopts(sox_effect_t * effp, int argc, char **argv) {
+  priv_t * p = (priv_t *)effp->priv;
+  p->filter_type = filter_riaa;
+  (void)argv;
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+
+static void make_poly_from_roots(
+    double const * roots, size_t num_roots, double * poly)
+{
+  size_t i, j;
+  poly[0] = 1;
+  poly[1] = -roots[0];
+  memset(poly + 2, 0, (num_roots + 1 - 2) * sizeof(*poly));
+  for (i = 1; i < num_roots; ++i)
+    for (j = num_roots; j > 0; --j)
+      poly[j] -= poly[j - 1] * roots[i];
+}
+
+static int start(sox_effect_t * effp)
+{
+  priv_t * p = (priv_t *)effp->priv;
+  double w0 = 2 * M_PI * p->fc / effp->in_signal.rate;
+  double A  = exp(p->gain / 40 * log(10.));
+  double alpha = 0, mult = dB_to_linear(max(p->gain, 0));
+
+  if (w0 > M_PI) {
+    lsx_fail("frequency must be less than half the sample-rate (Nyquist rate)");
+    return SOX_EOF;
+  }
+
+  /* Set defaults: */
+  p->b0 = p->b1 = p->b2 = p->a1 = p->a2 = 0;
+  p->a0 = 1;
+
+  if (p->width) switch (p->width_type) {
+    case width_slope:
+      alpha = sin(w0)/2 * sqrt((A + 1/A)*(1/p->width - 1) + 2);
+      break;
+
+    case width_Q:
+      alpha = sin(w0)/(2*p->width);
+      break;
+
+    case width_bw_oct:
+      alpha = sin(w0)*sinh(log(2.)/2 * p->width * w0/sin(w0));
+      break;
+
+    case width_bw_Hz:
+      alpha = sin(w0)/(2*p->fc/p->width);
+      break;
+
+    case width_bw_kHz: assert(0); /* Shouldn't get here */
+
+    case width_bw_old:
+      alpha = tan(M_PI * p->width / effp->in_signal.rate);
+      break;
+  }
+  switch (p->filter_type) {
+    case filter_LPF: /* H(s) = 1 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 - cos(w0))/2;
+      p->b1 =   1 - cos(w0);
+      p->b2 =  (1 - cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_HPF: /* H(s) = s^2 / (s^2 + s/Q + 1) */
+      p->b0 =  (1 + cos(w0))/2;
+      p->b1 = -(1 + cos(w0));
+      p->b2 =  (1 + cos(w0))/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF_CSG: /* H(s) = s / (s^2 + s/Q + 1)  (constant skirt gain, peak gain = Q) */
+      p->b0 =   sin(w0)/2;
+      p->b1 =   0;
+      p->b2 =  -sin(w0)/2;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_BPF: /* H(s) = (s/Q) / (s^2 + s/Q + 1)      (constant 0 dB peak gain) */
+      p->b0 =   alpha;
+      p->b1 =   0;
+      p->b2 =  -alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_notch: /* H(s) = (s^2 + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_APF: /* H(s) = (s^2 - s/Q + 1) / (s^2 + s/Q + 1) */
+      p->b0 =   1 - alpha;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 + alpha;
+      p->a0 =   1 + alpha;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha;
+      break;
+
+    case filter_peakingEQ: /* H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =   1 + alpha*A;
+      p->b1 =  -2*cos(w0);
+      p->b2 =   1 - alpha*A;
+      p->a0 =   1 + alpha/A;
+      p->a1 =  -2*cos(w0);
+      p->a2 =   1 - alpha/A;
+      break;
+
+    case filter_lowShelf: /* H(s) = A * (s^2 + (sqrt(A)/Q)*s + A)/(A*s^2 + (sqrt(A)/Q)*s + 1) */
+      if (A == 1)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 =  2*A*( (A-1) - (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =   -2*( (A-1) + (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_deemph:  /* See deemph.plt for documentation */
+      if (effp->in_signal.rate != 44100) {
+        lsx_fail("Sample rate must be 44100 (audio-CD)");
+        return SOX_EOF;
+      }
+      /* Falls through... */
+
+    case filter_highShelf: /* H(s) = A * (A*s^2 + (sqrt(A)/Q)*s + 1)/(s^2 + (sqrt(A)/Q)*s + A) */
+      if (!A)
+        return SOX_EFF_NULL;
+      p->b0 =    A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha );
+      p->b1 = -2*A*( (A-1) + (A+1)*cos(w0)                   );
+      p->b2 =    A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha );
+      p->a0 =        (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha;
+      p->a1 =    2*( (A-1) - (A+1)*cos(w0)                   );
+      p->a2 =        (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha;
+      break;
+
+    case filter_LPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = 1 + p->a1;
+      break;
+
+    case filter_HPF_1: /* single-pole */
+      p->a1 = -exp(-w0);
+      p->b0 = (1 - p->a1)/2;
+      p->b1 = -p->b0;
+      break;
+
+    case filter_BPF_SPK: case filter_BPF_SPK_N: {
+      double bw_Hz;
+      if (!p->width)
+        p->width = p->fc / 2;
+      bw_Hz = p->width_type == width_Q?  p->fc / p->width :
+        p->width_type == width_bw_Hz? p->width :
+        p->fc * (pow(2., p->width) - 1) * pow(2., -0.5 * p->width); /* bw_oct */
+      #include "band.h" /* Has different licence */
+      break;
+    }
+
+    case filter_AP1:     /* Experimental 1-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = exp(-w0);
+      p->b1 = -1;
+      p->a1 = -exp(-w0);
+      break;
+
+    case filter_AP2:     /* Experimental 2-pole all-pass from Tom Erbe @ UCSD */
+      p->b0 = 1 - sin(w0);
+      p->b1 = -2 * cos(w0);
+      p->b2 = 1 + sin(w0);
+      p->a0 = 1 + sin(w0);
+      p->a1 = -2 * cos(w0);
+      p->a2 = 1 - sin(w0);
+      break;
+
+    case filter_riaa: /* http://www.dsprelated.com/showmessage/73300/3.php */
+      if (effp->in_signal.rate == 44100) {
+        static const double zeros[] = {-0.2014898, 0.9233820};
+        static const double poles[] = {0.7083149, 0.9924091};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 48000) {
+        static const double zeros[] = {-0.1766069, 0.9321590};
+        static const double poles[] = {0.7396325, 0.9931330};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 88200) {
+        static const double zeros[] = {-0.1168735, 0.9648312};
+        static const double poles[] = {0.8590646, 0.9964002};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else if (effp->in_signal.rate == 96000) {
+        static const double zeros[] = {-0.1141486, 0.9676817};
+        static const double poles[] = {0.8699137, 0.9966946};
+        make_poly_from_roots(zeros, (size_t)2, &p->b0);
+        make_poly_from_roots(poles, (size_t)2, &p->a0);
+      }
+      else {
+        lsx_fail("Sample rate must be 44.1k, 48k, 88.2k, or 96k");
+        return SOX_EOF;
+      }
+      { /* Normalise to 0dB at 1kHz (Thanks to Glenn Davis) */
+        double y = 2 * M_PI * 1000 / effp->in_signal.rate;
+        double b_re = p->b0 + p->b1 * cos(-y) + p->b2 * cos(-2 * y);
+        double a_re = p->a0 + p->a1 * cos(-y) + p->a2 * cos(-2 * y);
+        double b_im = p->b1 * sin(-y) + p->b2 * sin(-2 * y);
+        double a_im = p->a1 * sin(-y) + p->a2 * sin(-2 * y);
+        double g = 1 / sqrt((sqr(b_re) + sqr(b_im)) / (sqr(a_re) + sqr(a_im)));
+        p->b0 *= g; p->b1 *= g; p->b2 *= g;
+      }
+      mult = (p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2);
+      lsx_debug("gain=%f", linear_to_dB(mult));
+      break;
+  }
+  if (effp->in_signal.mult)
+    *effp->in_signal.mult /= mult;
+  return lsx_biquad_start(effp);
+}
+
+
+#define BIQUAD_EFFECT(name,group,usage,flags) \
+sox_effect_handler_t const * lsx_##name##_effect_fn(void) { \
+  static sox_effect_handler_t handler = { \
+    #name, usage, flags, \
+    group##_getopts, start, lsx_biquad_flow, 0, 0, 0, sizeof(biquad_t)\
+  }; \
+  return &handler; \
+}
+
+BIQUAD_EFFECT(highpass,  hilo2,    "[-1|-2] frequency [width[q|o|h|k](0.707q)]", 0)
+BIQUAD_EFFECT(lowpass,   hilo2,    "[-1|-2] frequency [width[q|o|h|k]](0.707q)", 0)
+BIQUAD_EFFECT(bandpass,  bandpass, "[-c] frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bandreject,bandrej,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(allpass,   allpass,  "frequency width[h|k|q|o]", 0)
+BIQUAD_EFFECT(bass,      tone,     "gain [frequency(100) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(treble,    tone,     "gain [frequency(3000) [width[s|h|k|q|o]](0.5s)]", 0)
+BIQUAD_EFFECT(equalizer, equalizer,"frequency width[q|o|h|k] gain", 0)
+BIQUAD_EFFECT(band,      band,     "[-n] center [width[h|k|q|o]]", 0)
+BIQUAD_EFFECT(deemph,    deemph,   NULL, 0)
+BIQUAD_EFFECT(riaa,      riaa,     NULL, 0)
diff --git a/freedv/tags/1.2.2/src/sox/effects.c b/freedv/tags/1.2.2/src/sox/effects.c
new file mode 100644 (file)
index 0000000..435412f
--- /dev/null
@@ -0,0 +1,544 @@
+/* SoX Effects chain     (c) 2007 robs@users.sourceforge.net
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <assert.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+  #include <strings.h>
+#endif
+
+#define DEBUG_EFFECTS_CHAIN 0
+
+/* Default effect handler functions for do-nothing situations: */
+
+static int default_function(sox_effect_t * effp UNUSED)
+{
+  return SOX_SUCCESS;
+}
+
+/* Pass through samples verbatim */
+int lsx_flow_copy(sox_effect_t * effp UNUSED, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp)
+{
+  *isamp = *osamp = min(*isamp, *osamp);
+  memcpy(obuf, ibuf, *isamp * sizeof(*obuf));
+  return SOX_SUCCESS;
+}
+
+/* Inform no more samples to drain */
+static int default_drain(sox_effect_t * effp UNUSED, sox_sample_t *obuf UNUSED, size_t *osamp)
+{
+  *osamp = 0;
+  return SOX_EOF;
+}
+
+/* Check that no parameters have been given */
+static int default_getopts(sox_effect_t * effp, int argc, char **argv UNUSED)
+{
+  return --argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+/* Partially initialise the effect structure; signal info will come later */
+sox_effect_t * sox_create_effect(sox_effect_handler_t const * eh)
+{
+  sox_effect_t * effp = lsx_calloc(1, sizeof(*effp));
+  effp->obuf = NULL;
+
+  effp->global_info = sox_get_effects_globals();
+  effp->handler = *eh;
+  if (!effp->handler.getopts) effp->handler.getopts = default_getopts;
+  if (!effp->handler.start  ) effp->handler.start   = default_function;
+  if (!effp->handler.flow   ) effp->handler.flow    = lsx_flow_copy;
+  if (!effp->handler.drain  ) effp->handler.drain   = default_drain;
+  if (!effp->handler.stop   ) effp->handler.stop    = default_function;
+  if (!effp->handler.kill   ) effp->handler.kill    = default_function;
+
+  effp->priv = lsx_calloc(1, effp->handler.priv_size);
+
+  return effp;
+} /* sox_create_effect */
+
+int sox_effect_options(sox_effect_t *effp, int argc, char * const argv[])
+{
+  int result;
+
+  char * * argv2 = lsx_malloc((argc + 1) * sizeof(*argv2));
+  argv2[0] = (char *)effp->handler.name;
+  memcpy(argv2 + 1, argv, argc * sizeof(*argv2));
+  result = effp->handler.getopts(effp, argc + 1, argv2);
+  free(argv2);
+  return result;
+} /* sox_effect_options */
+
+/* Effects chain: */
+
+sox_effects_chain_t * sox_create_effects_chain(
+    sox_encodinginfo_t const * in_enc, sox_encodinginfo_t const * out_enc)
+{
+  sox_effects_chain_t * result = lsx_calloc(1, sizeof(sox_effects_chain_t));
+  result->global_info = *sox_get_effects_globals();
+  result->in_enc = in_enc;
+  result->out_enc = out_enc;
+  return result;
+} /* sox_create_effects_chain */
+
+void sox_delete_effects_chain(sox_effects_chain_t *ecp)
+{
+    if (ecp && ecp->length)
+        sox_delete_effects(ecp);
+    free(ecp->effects);
+    free(ecp);
+} /* sox_delete_effects_chain */
+
+/* Effect can call in start() or flow() to set minimum input size to flow() */
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin)
+{
+  if (imin > sox_globals.bufsiz / effp->flows) {
+    lsx_fail("sox_bufsiz not big enough");
+    return SOX_EOF;
+  }
+
+  effp->imin = imin;
+  return SOX_SUCCESS;
+}
+
+/* Effects table to be extended in steps of EFF_TABLE_STEP */
+#define EFF_TABLE_STEP 8
+
+/* Add an effect to the chain. *in is the input signal for this effect. *out is
+ * a suggestion as to what the output signal should be, but depending on its
+ * given options and *in, the effect can choose to do differently.  Whatever
+ * output rate and channels the effect does produce are written back to *in,
+ * ready for the next effect in the chain.
+ */
+int sox_add_effect(sox_effects_chain_t * chain, sox_effect_t * effp, sox_signalinfo_t * in, sox_signalinfo_t const * out)
+{
+  int ret, (*start)(sox_effect_t * effp) = effp->handler.start;
+  unsigned f;
+  sox_effect_t eff0;  /* Copy of effect for flow 0 before calling start */
+
+  effp->global_info = &chain->global_info;
+  effp->in_signal = *in;
+  effp->out_signal = *out;
+  effp->in_encoding = chain->in_enc;
+  effp->out_encoding = chain->out_enc;
+  if (!(effp->handler.flags & SOX_EFF_CHAN))
+    effp->out_signal.channels = in->channels;
+  if (!(effp->handler.flags & SOX_EFF_RATE))
+    effp->out_signal.rate = in->rate;
+  if (!(effp->handler.flags & SOX_EFF_PREC))
+    effp->out_signal.precision = (effp->handler.flags & SOX_EFF_MODIFY)?
+        in->precision : SOX_SAMPLE_PRECISION;
+  if (!(effp->handler.flags & SOX_EFF_GAIN))
+    effp->out_signal.mult = in->mult;
+
+  effp->flows =
+    (effp->handler.flags & SOX_EFF_MCHAN)? 1 : effp->in_signal.channels;
+  effp->clips = 0;
+  effp->imin = 0;
+  eff0 = *effp, eff0.priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+  eff0.in_signal.mult = NULL; /* Only used in channel 0 */
+  ret = start(effp);
+  if (ret == SOX_EFF_NULL) {
+    lsx_report("has no effect in this configuration");
+    free(eff0.priv);
+    free(effp->priv);
+    effp->priv = NULL;
+    return SOX_SUCCESS;
+  }
+  if (ret != SOX_SUCCESS) {
+    free(eff0.priv);
+    return SOX_EOF;
+  }
+  if (in->mult)
+    lsx_debug("mult=%g", *in->mult);
+
+  if (!(effp->handler.flags & SOX_EFF_LENGTH)) {
+    effp->out_signal.length = in->length;
+    if (effp->out_signal.length != SOX_UNKNOWN_LEN) {
+      if (effp->handler.flags & SOX_EFF_CHAN)
+        effp->out_signal.length =
+          effp->out_signal.length / in->channels * effp->out_signal.channels;
+      if (effp->handler.flags & SOX_EFF_RATE)
+        effp->out_signal.length =
+          effp->out_signal.length / in->rate * effp->out_signal.rate + .5;
+    }
+  }
+
+  *in = effp->out_signal;
+
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_add_effect: extending effects table, "
+      "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length] =
+    lsx_calloc(effp->flows, sizeof(chain->effects[chain->length][0]));
+  chain->effects[chain->length][0] = *effp;
+
+  for (f = 1; f < effp->flows; ++f) {
+    chain->effects[chain->length][f] = eff0;
+    chain->effects[chain->length][f].flow = f;
+    chain->effects[chain->length][f].priv = lsx_memdup(eff0.priv, eff0.handler.priv_size);
+    if (start(&chain->effects[chain->length][f]) != SOX_SUCCESS) {
+      free(eff0.priv);
+      return SOX_EOF;
+    }
+  }
+
+  ++chain->length;
+  free(eff0.priv);
+  return SOX_SUCCESS;
+}
+
+static int flow_effect(sox_effects_chain_t * chain, size_t n)
+{
+  sox_effect_t * effp1 = &chain->effects[n - 1][0];
+  sox_effect_t * effp = &chain->effects[n][0];
+  int effstatus = SOX_SUCCESS, f = 0;
+  size_t i;
+  const sox_sample_t *ibuf;
+  size_t idone = effp1->oend - effp1->obeg;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#if DEBUG_EFFECTS_CHAIN
+  size_t pre_idone = idone;
+  size_t pre_odone = obeg;
+#endif
+
+  if (effp->flows == 1) {     /* Run effect on all channels at once */
+    idone -= idone % effp->in_signal.channels;
+    effstatus = effp->handler.flow(effp, &effp1->obuf[effp1->obeg],
+                                   &effp->obuf[effp->oend], &idone, &obeg);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect flowed asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {               /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    size_t idone_last = 0, odone_last = 0; /* Initialised to prevent warning */
+
+    ibuf = &effp1->obuf[effp1->obeg];
+    for (i = 0; i < idone; i += effp->flows)
+      for (f = 0; f < (int)effp->flows; ++f)
+        chain->ibufc[f][i / effp->flows] = *ibuf++;
+
+#ifdef HAVE_OPENMP
+    if (sox_globals.use_threads && effp->flows > 1)
+    {
+      #pragma omp parallel for
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (!f) {
+          idone_last = idonec;
+          odone_last = odonec;
+        }
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+    else /* sox_globals.use_threads */
+#endif
+    {
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (f && (idonec != idone_last || odonec != odone_last)) {
+          lsx_fail("flowed asymmetrically!");
+          effstatus = SOX_EOF;
+        }
+        idone_last = idonec;
+        odone_last = odonec;
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
+    }
+
+    for (i = 0; i < odone_last; ++i)
+      for (f = 0; f < (int)effp->flows; ++f)
+        *obuf++ = chain->obufc[f][i];
+
+    idone = effp->flows * idone_last;
+    obeg = effp->flows * odone_last;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("flow:  %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      pre_idone, pre_odone, idone, obeg);
+#endif
+  effp1->obeg += idone;
+  if (effp1->obeg == effp1->oend)
+    effp1->obeg = effp1->oend = 0;
+  else if (effp1->oend - effp1->obeg < effp->imin ) { /* Need to refill? */
+    memmove(effp1->obuf, &effp1->obuf[effp1->obeg], (effp1->oend - effp1->obeg) * sizeof(*effp1->obuf));
+    effp1->oend -= effp1->obeg;
+    effp1->obeg = 0;
+  }
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* The same as flow_effect but with no input */
+static int drain_effect(sox_effects_chain_t * chain, size_t n)
+{
+  sox_effect_t * effp = &chain->effects[n][0];
+  int effstatus = SOX_SUCCESS;
+  size_t i, f;
+  size_t obeg = sox_globals.bufsiz - effp->oend;
+#if DEBUG_EFFECTS_CHAIN
+  size_t pre_odone = obeg;
+#endif
+
+  if (effp->flows == 1) { /* Run effect on all channels at once */
+    effstatus = effp->handler.drain(effp, &effp->obuf[effp->oend], &obeg);
+    if (obeg % effp->out_signal.channels != 0) {
+      lsx_fail("multi-channel effect drained asymmetrically!");
+      effstatus = SOX_EOF;
+    }
+  } else {                       /* Run effect on each channel individually */
+    sox_sample_t *obuf = &effp->obuf[effp->oend];
+    size_t odone_last = 0; /* Initialised to prevent warning */
+
+    for (f = 0; f < effp->flows; ++f) {
+      size_t odonec = obeg / effp->flows;
+      int eff_status_c = effp->handler.drain(&chain->effects[n][f], chain->obufc[f], &odonec);
+      if (f && (odonec != odone_last)) {
+        lsx_fail("drained asymmetrically!");
+        effstatus = SOX_EOF;
+      }
+      odone_last = odonec;
+
+      if (eff_status_c != SOX_SUCCESS)
+        effstatus = SOX_EOF;
+    }
+
+    for (i = 0; i < odone_last; ++i)
+      for (f = 0; f < effp->flows; ++f)
+        *obuf++ = chain->obufc[f][i];
+    obeg = f * odone_last;
+  }
+#if DEBUG_EFFECTS_CHAIN
+  lsx_report("drain: %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR " %5" PRIuPTR,
+      (size_t)0, pre_odone, (size_t)0, obeg);
+#endif
+  if (!obeg)   /* This is the only thing that drain has and flow hasn't */
+    effstatus = SOX_EOF;
+
+  effp->oend += obeg;
+
+  return effstatus == SOX_SUCCESS? SOX_SUCCESS : SOX_EOF;
+}
+
+/* Flow data through the effects chain until an effect or callback gives EOF */
+int sox_flow_effects(sox_effects_chain_t * chain, int (* callback)(sox_bool all_done, void * client_data), void * client_data)
+{
+  int flow_status = SOX_SUCCESS;
+  size_t e, source_e = 0;               /* effect indices */
+  size_t f, max_flows = 0;
+  sox_bool draining = sox_true;
+
+  for (e = 0; e < chain->length; ++e) {
+    chain->effects[e][0].obuf = lsx_realloc(chain->effects[e][0].obuf,
+        sox_globals.bufsiz * sizeof(chain->effects[e][0].obuf[0]));
+      /* Possibly there is already a buffer, if this is a used effect;
+         it may still contain samples in that case. */
+      /* Memory will be freed by sox_delete_effect() later. */
+    max_flows = max(max_flows, chain->effects[e][0].flows);
+  }
+  if (max_flows == 1) /* don't need interleave buffers */
+    max_flows = 0;
+  chain->ibufc = lsx_calloc(max_flows, sizeof(*chain->ibufc));
+  chain->obufc = lsx_calloc(max_flows, sizeof(*chain->obufc));
+  for (f = 0; f < max_flows; ++f) {
+    chain->ibufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->ibufc[f][0]));
+    chain->obufc[f] = lsx_calloc(sox_globals.bufsiz / 2, sizeof(chain->obufc[f][0]));
+  }
+
+  e = chain->length - 1;
+  while (source_e < chain->length) {
+#define have_imin (e > 0 && e < chain->length && chain->effects[e - 1][0].oend - chain->effects[e - 1][0].obeg >= chain->effects[e][0].imin)
+    size_t osize = chain->effects[e][0].oend - chain->effects[e][0].obeg;
+    if (e == source_e && (draining || !have_imin)) {
+      if (drain_effect(chain, e) == SOX_EOF) {
+        ++source_e;
+        draining = sox_false;
+      }
+    } else if (have_imin && flow_effect(chain, e) == SOX_EOF) {
+      flow_status = SOX_EOF;
+      if (e == chain->length - 1)
+        break;
+      source_e = e;
+      draining = sox_true;
+    }
+    if (e < chain->length && chain->effects[e][0].oend - chain->effects[e][0].obeg > osize) /* False for output */
+      ++e;
+    else if (e == source_e)
+      draining = sox_true;
+    else if ((int)--e < (int)source_e)
+      e = source_e;
+
+    if (callback && callback(source_e == chain->length, client_data) != SOX_SUCCESS) {
+      flow_status = SOX_EOF; /* Client has requested to stop the flow. */
+      break;
+    }
+  }
+
+  for (f = 0; f < max_flows; ++f) {
+    free(chain->ibufc[f]);
+    free(chain->obufc[f]);
+  }
+  free(chain->obufc);
+  free(chain->ibufc);
+
+  return flow_status;
+}
+
+sox_uint64_t sox_effects_clips(sox_effects_chain_t * chain)
+{
+  unsigned i, f;
+  uint64_t clips = 0;
+  for (i = 1; i < chain->length - 1; ++i)
+    for (f = 0; f < chain->effects[i][0].flows; ++f)
+      clips += chain->effects[i][f].clips;
+  return clips;
+}
+
+sox_uint64_t sox_stop_effect(sox_effect_t *effp)
+{
+  unsigned f;
+  uint64_t clips = 0;
+
+  for (f = 0; f < effp->flows; ++f) {
+    effp[f].handler.stop(&effp[f]);
+    clips += effp[f].clips;
+  }
+  return clips;
+}
+
+void sox_push_effect_last(sox_effects_chain_t *chain, sox_effect_t *effp)
+{
+  if (chain->length == chain->table_size) {
+    chain->table_size += EFF_TABLE_STEP;
+    lsx_debug_more("sox_push_effect_last: extending effects table, "
+        "new size = %lu", (unsigned long)chain->table_size);
+    lsx_revalloc(chain->effects, chain->table_size);
+  }
+
+  chain->effects[chain->length++] = effp;
+} /* sox_push_effect_last */
+
+sox_effect_t *sox_pop_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    sox_effect_t *effp;
+    chain->length--;
+    effp = chain->effects[chain->length];
+    chain->effects[chain->length] = NULL;
+    return effp;
+  }
+  else
+    return NULL;
+} /* sox_pop_effect_last */
+
+/* Free resources related to effect.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effect(sox_effect_t *effp)
+{
+  uint64_t clips;
+  unsigned f;
+
+  if ((clips = sox_stop_effect(effp)) != 0)
+    lsx_warn("%s clipped %" PRIu64 " samples; decrease volume?",
+        effp->handler.name, clips);
+  if (effp->obeg != effp->oend)
+    lsx_debug("output buffer still held %" PRIuPTR " samples; dropped.",
+        (effp->oend - effp->obeg)/effp->out_signal.channels);
+      /* May or may not indicate a problem; it is normal if the user aborted
+         processing, or if an effect like "trim" stopped early. */
+  effp->handler.kill(effp); /* N.B. only one kill; not one per flow */
+  for (f = 0; f < effp->flows; ++f)
+    free(effp[f].priv);
+  free(effp->obuf);
+  free(effp);
+}
+
+void sox_delete_effect_last(sox_effects_chain_t *chain)
+{
+  if (chain->length > 0)
+  {
+    chain->length--;
+    sox_delete_effect(chain->effects[chain->length]);
+    chain->effects[chain->length] = NULL;
+  }
+} /* sox_delete_effect_last */
+
+/* Remove all effects from the chain.
+ * Note: This currently closes down the effect which might
+ * not be obvious from name.
+ */
+void sox_delete_effects(sox_effects_chain_t * chain)
+{
+  size_t e;
+
+  for (e = 0; e < chain->length; ++e) {
+    sox_delete_effect(chain->effects[e]);
+    chain->effects[e] = NULL;
+  }
+  chain->length = 0;
+}
+
+/*----------------------------- Effects library ------------------------------*/
+
+static sox_effect_fn_t s_sox_effect_fns[] = {
+#define EFFECT(f) lsx_##f##_effect_fn,
+#include "effects.h"
+#undef EFFECT
+  NULL
+};
+
+const sox_effect_fn_t*
+sox_get_effect_fns(void)
+{
+    return s_sox_effect_fns;
+}
+
+/* Find a named effect in the effects library */
+sox_effect_handler_t const * sox_find_effect(char const * name)
+{
+  int e;
+  sox_effect_fn_t const * fns = sox_get_effect_fns();
+  for (e = 0; fns[e]; ++e) {
+    const sox_effect_handler_t *eh = fns[e] ();
+    if (eh && eh->name && strcasecmp(eh->name, name) == 0)
+      return eh;                 /* Found it. */
+  }
+  return NULL;
+}
diff --git a/freedv/tags/1.2.2/src/sox/effects.h b/freedv/tags/1.2.2/src/sox/effects.h
new file mode 100644 (file)
index 0000000..8d7025c
--- /dev/null
@@ -0,0 +1,22 @@
+/* This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/* Manually edited for FreeDV to contain just the effects we need */
+
+  EFFECT(bass)
+  EFFECT(highpass)
+  EFFECT(treble)
+  EFFECT(equalizer)
+
diff --git a/freedv/tags/1.2.2/src/sox/effects_i.c b/freedv/tags/1.2.2/src/sox/effects_i.c
new file mode 100644 (file)
index 0000000..e5770a9
--- /dev/null
@@ -0,0 +1,379 @@
+/* Implements a libSoX internal interface for implementing effects.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * Copyright (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#define LSX_EFF_ALIAS
+#include "sox_i.h"
+#include <string.h>
+#include <ctype.h>
+
+int lsx_usage(sox_effect_t * effp)
+{
+  if (effp->handler.usage)
+    lsx_fail("usage: %s", effp->handler.usage);
+  else
+    lsx_fail("this effect takes no parameters");
+  return SOX_EOF;
+}
+
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n)
+{
+  if (!*usage) {
+    size_t i, len;
+    for (len = i = 0; i < n; len += strlen(lines[i++]) + 1);
+    *usage = lsx_malloc(len); /* FIXME: this memory will never be freed */
+    strcpy(*usage, lines[0]);
+    for (i = 1; i < n; ++i) {
+      strcat(*usage, "\n");
+      strcat(*usage, lines[i]);
+    }
+  }
+  return *usage;
+}
+
+static lsx_enum_item const s_lsx_wave_enum[] = {
+  LSX_ENUM_ITEM(SOX_WAVE_,SINE)
+  LSX_ENUM_ITEM(SOX_WAVE_,TRIANGLE)
+  {0, 0}};
+
+lsx_enum_item const * lsx_get_wave_enum(void)
+{
+  return s_lsx_wave_enum;
+}
+
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void *table,
+    size_t table_size,
+    double min,
+    double max,
+    double phase)
+{
+  uint32_t t;
+  uint32_t phase_offset = phase / M_PI / 2 * table_size + 0.5;
+
+  for (t = 0; t < table_size; t++)
+  {
+    uint32_t point = (t + phase_offset) % table_size;
+    double d;
+    switch (wave_type)
+    {
+      case SOX_WAVE_SINE:
+      d = (sin((double)point / table_size * 2 * M_PI) + 1) / 2;
+      break;
+
+      case SOX_WAVE_TRIANGLE:
+      d = (double)point * 2 / table_size;
+      switch (4 * point / table_size)
+      {
+        case 0:         d = d + 0.5; break;
+        case 1: case 2: d = 1.5 - d; break;
+        case 3:         d = d - 1.5; break;
+      }
+      break;
+
+      default: /* Oops! FIXME */
+        d = 0.0; /* Make sure we have a value */
+      break;
+    }
+    d  = d * (max - min) + min;
+    switch (data_type)
+    {
+      case SOX_FLOAT:
+        {
+          float *fp = (float *)table;
+          *fp++ = (float)d;
+          table = fp;
+          continue;
+        }
+      case SOX_DOUBLE:
+        {
+          double *dp = (double *)table;
+          *dp++ = d;
+          table = dp;
+          continue;
+        }
+      default: break;
+    }
+    d += d < 0? -0.5 : +0.5;
+    switch (data_type)
+    {
+      case SOX_SHORT:
+        {
+          short *sp = table;
+          *sp++ = (short)d;
+          table = sp;
+          continue;
+        }
+      case SOX_INT:
+        {
+          int *ip = table;
+          *ip++ = (int)d;
+          table = ip;
+          continue;
+        }
+      default: break;
+    }
+  }
+}
+
+/*
+ * lsx_parsesamples
+ *
+ * Parse a string for # of samples.  If string ends with a 's'
+ * then the string is interpreted as a user calculated # of samples.
+ * If string contains ':' or '.' or if it ends with a 't' then its
+ * treated as an amount of time.  This is converted into seconds and
+ * fraction of seconds and then use the sample rate to calculate
+ * # of samples.
+ * Returns NULL on error, pointer to next char to parse otherwise.
+ */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str0, uint64_t *samples, int def)
+{
+  int i, found_samples = 0, found_time = 0;
+  char const * end;
+  char const * pos;
+  sox_bool found_colon, found_dot;
+  char * str = (char *)str0;
+
+  for (;*str == ' '; ++str);
+  for (end = str; *end && strchr("0123456789:.ets", *end); ++end);
+  if (end == str)
+    return NULL;
+
+  pos = strchr(str, ':');
+  found_colon = pos && pos < end;
+
+  pos = strchr(str, '.');
+  found_dot = pos && pos < end;
+
+  if (found_colon || found_dot || *(end-1) == 't')
+    found_time = 1;
+  else if (*(end-1) == 's')
+    found_samples = 1;
+
+  if (found_time || (def == 't' && !found_samples)) {
+    for (*samples = 0, i = 0; *str != '.' && i < 3; ++i) {
+      char * last_str = str;
+      long part = strtol(str, &str, 10);
+      if (!i && str == last_str)
+        return NULL;
+      *samples += rate * part;
+      if (i < 2) {
+        if (*str != ':')
+          break;
+        ++str;
+        *samples *= 60;
+      }
+    }
+    if (*str == '.') {
+      char * last_str = str;
+      double part = strtod(str, &str);
+      if (str == last_str)
+        return NULL;
+      *samples += rate * part + .5;
+    }
+    return *str == 't'? str + 1 : str;
+  }
+  {
+    char * last_str = str;
+    double part = strtod(str, &str);
+    if (str == last_str)
+      return NULL;
+    *samples = part + .5;
+    return *str == 's'? str + 1 : str;
+  }
+}
+
+#if 0
+
+#include <assert.h>
+
+#define TEST(st, samp, len) \
+  str = st; \
+  next = lsx_parsesamples(10000, str, &samples, 't'); \
+  assert(samples == samp && next == str + len);
+
+int main(int argc, char * * argv)
+{
+  char const * str, * next;
+  uint64_t samples;
+
+  TEST("0"  , 0, 1)
+  TEST("1" , 10000, 1)
+
+  TEST("0s" , 0, 2)
+  TEST("0s,", 0, 2)
+  TEST("0s/", 0, 2)
+  TEST("0s@", 0, 2)
+
+  TEST("0t" , 0, 2)
+  TEST("0t,", 0, 2)
+  TEST("0t/", 0, 2)
+  TEST("0t@", 0, 2)
+
+  TEST("1s" , 1, 2)
+  TEST("1s,", 1, 2)
+  TEST("1s/", 1, 2)
+  TEST("1s@", 1, 2)
+  TEST(" 01s" , 1, 4)
+  TEST("1e6s" , 1000000, 4)
+
+  TEST("1t" , 10000, 2)
+  TEST("1t,", 10000, 2)
+  TEST("1t/", 10000, 2)
+  TEST("1t@", 10000, 2)
+  TEST("1.1t" , 11000, 4)
+  TEST("1.1t,", 11000, 4)
+  TEST("1.1t/", 11000, 4)
+  TEST("1.1t@", 11000, 4)
+  TEST("1e6t" , 10000, 1)
+
+  TEST(".0", 0, 2)
+  TEST("0.0", 0, 3)
+  TEST("0:0.0", 0, 5)
+  TEST("0:0:0.0", 0, 7)
+
+  TEST(".1", 1000, 2)
+  TEST(".10", 1000, 3)
+  TEST("0.1", 1000, 3)
+  TEST("1.1", 11000, 3)
+  TEST("1:1.1", 611000, 5)
+  TEST("1:1:1.1", 36611000, 7)
+  TEST("1:1", 610000, 3)
+  TEST("1:01", 610000, 4)
+  TEST("1:1:1", 36610000, 5)
+  TEST("1:", 600000, 2)
+  TEST("1::", 36000000, 3)
+
+  TEST("0.444444", 4444, 8)
+  TEST("0.555555", 5556, 8)
+
+  assert(!lsx_parsesamples(10000, "x", &samples, 't'));
+  return 0;
+}
+#endif 
+
+/* a note is given as an int,
+ * 0   => 440 Hz = A
+ * >0  => number of half notes 'up',
+ * <0  => number of half notes down,
+ * example 12 => A of next octave, 880Hz
+ *
+ * calculated by freq = 440Hz * 2**(note/12)
+ */
+static double calc_note_freq(double note, int key)
+{
+  if (key != INT_MAX) {                         /* Just intonation. */
+    static const int n[] = {16, 9, 6, 5, 4, 7}; /* Numerator. */
+    static const int d[] = {15, 8, 5, 4, 3, 5}; /* Denominator. */
+    static double j[13];                        /* Just semitones */
+    int i, m = floor(note);
+
+    if (!j[1]) for (i = 1; i <= 12; ++i)
+      j[i] = i <= 6? log((double)n[i - 1] / d[i - 1]) / log(2.) : 1 - j[12 - i];
+    note -= m;
+    m -= key = m - ((INT_MAX / 2 - ((INT_MAX / 2) % 12) + m - key) % 12);
+    return 440 * pow(2., key / 12. + j[m] + (j[m + 1] - j[m]) * note);
+  }
+  return 440 * pow(2., note / 12);
+}
+
+int lsx_parse_note(char const * text, char * * end_ptr)
+{
+  int result = INT_MAX;
+
+  if (*text >= 'A' && *text <= 'G') {
+    result = (int)(5/3. * (*text++ - 'A') + 9.5) % 12 - 9;
+    if (*text == 'b') {--result; ++text;}
+    else if (*text == '#') {++result; ++text;}
+    if (isdigit((unsigned char)*text))
+      result += 12 * (*text++ - '4'); 
+  }
+  *end_ptr = (char *)text;
+  return result;
+}
+
+/* Read string 'text' and convert to frequency.
+ * 'text' can be a positive number which is the frequency in Hz.
+ * If 'text' starts with a '%' and a following number the corresponding
+ * note is calculated.
+ * Return -1 on error.
+ */
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key)
+{
+  double result;
+
+  if (*text == '%') {
+    result = strtod(text + 1, end_ptr);
+    if (*end_ptr == text + 1)
+      return -1;
+    return calc_note_freq(result, key);
+  }
+  if (*text >= 'A' && *text <= 'G') {
+    int result2 = lsx_parse_note(text, end_ptr);
+    return result2 == INT_MAX? - 1 : calc_note_freq((double)result2, key);
+  }
+  result = strtod(text, end_ptr);
+  if (end_ptr) {
+    if (*end_ptr == text)
+      return -1;
+    if (**end_ptr == 'k') {
+      result *= 1000;
+      ++*end_ptr;
+    }
+  }
+  return result < 0 ? -1 : result;
+}
+
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename)
+{
+  FILE * file;
+
+  if (!filename || !strcmp(filename, "-")) {
+    if (effp->global_info->global_info->stdin_in_use_by) {
+      lsx_fail("stdin already in use by `%s'", effp->global_info->global_info->stdin_in_use_by);
+      return NULL;
+    }
+    effp->global_info->global_info->stdin_in_use_by = effp->handler.name;
+    file = stdin;
+  }
+  else if (!(file = fopen(filename, "r"))) {
+    lsx_fail("couldn't open file %s: %s", filename, strerror(errno));
+    return NULL;
+  }
+  return file;
+}
+
+int lsx_effects_init(void)
+{
+  #ifndef __FREEDV__
+  init_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
+
+int lsx_effects_quit(void)
+{
+  #ifndef __FREEDV__
+  clear_fft_cache();
+  #endif
+  return SOX_SUCCESS;
+}
diff --git a/freedv/tags/1.2.2/src/sox/formats_i.c b/freedv/tags/1.2.2/src/sox/formats_i.c
new file mode 100644 (file)
index 0000000..17c4061
--- /dev/null
@@ -0,0 +1,487 @@
+/* Implements a libSoX internal interface for use in implementing file formats.
+ * All public functions & data are prefixed with lsx_ .
+ *
+ * (c) 2005-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <string.h>
+#include <sys/stat.h>
+#include <stdarg.h>
+
+void lsx_fail_errno(sox_format_t * ft, int sox_errno, const char *fmt, ...)
+{
+  va_list args;
+
+  ft->sox_errno = sox_errno;
+
+  va_start(args, fmt);
+#ifdef HAVE_VSNPRINTF
+  vsnprintf(ft->sox_errstr, sizeof(ft->sox_errstr), fmt, args);
+#else
+  vsprintf(ft->sox_errstr, fmt, args);
+#endif
+  va_end(args);
+  ft->sox_errstr[255] = '\0';
+}
+
+void lsx_set_signal_defaults(sox_format_t * ft)
+{
+  if (!ft->signal.rate     ) ft->signal.rate      = SOX_DEFAULT_RATE;
+  if (!ft->signal.precision) ft->signal.precision = SOX_DEFAULT_PRECISION;
+  if (!ft->signal.channels ) ft->signal.channels  = SOX_DEFAULT_CHANNELS;
+
+  if (!ft->encoding.bits_per_sample)
+    ft->encoding.bits_per_sample = ft->signal.precision;
+  if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
+    ft->encoding.encoding = SOX_ENCODING_SIGN2;
+}
+
+#ifndef __FREEDV__
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length)
+{
+  ft->signal.length = ft->signal.length == SOX_IGNORE_LENGTH? SOX_UNSPEC : num_samples;
+
+  if (ft->seekable)
+    ft->data_start = lsx_tell(ft);
+
+  if (channels && ft->signal.channels && ft->signal.channels != channels)
+    lsx_warn("`%s': overriding number of channels", ft->filename);
+  else ft->signal.channels = channels;
+
+  if (rate && ft->signal.rate && ft->signal.rate != rate)
+    lsx_warn("`%s': overriding sample rate", ft->filename);
+  else ft->signal.rate = rate;
+
+  if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding)
+    lsx_warn("`%s': overriding encoding type", ft->filename);
+  else ft->encoding.encoding = encoding;
+
+  if (bits_per_sample && ft->encoding.bits_per_sample && ft->encoding.bits_per_sample != bits_per_sample)
+    lsx_warn("`%s': overriding encoding size", ft->filename);
+  ft->encoding.bits_per_sample = bits_per_sample;
+
+  if (check_length && ft->encoding.bits_per_sample && lsx_filelength(ft)) {
+    uint64_t calculated_length = div_bits(lsx_filelength(ft) - ft->data_start, ft->encoding.bits_per_sample);
+    if (!ft->signal.length)
+      ft->signal.length = calculated_length;
+    else if (num_samples != calculated_length)
+      lsx_warn("`%s': file header gives the total number of samples as %" PRIu64 " but file length indicates the number is in fact %" PRIu64, ft->filename, num_samples, calculated_length);
+  }
+
+  if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
+    return SOX_SUCCESS;
+  lsx_fail_errno(ft, EINVAL, "invalid format for this file type");
+  return SOX_EOF;
+}
+#endif
+
+/* Read in a buffer of data of length len bytes.
+ * Returns number of bytes read.
+ */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len)
+{
+  size_t ret = fread(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len && ferror((FILE*)ft->fp))
+    lsx_fail_errno(ft, errno, "lsx_readbuf");
+  ft->tell_off += ret;
+  return ret;
+}
+
+/* Skip input without seeking. */
+int lsx_skipbytes(sox_format_t * ft, size_t n)
+{
+  unsigned char trash;
+
+  while (n--)
+    if (lsx_readb(ft, &trash) == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Pad output. */
+int lsx_padbytes(sox_format_t * ft, size_t n)
+{
+  while (n--)
+    if (lsx_writeb(ft, '\0') == SOX_EOF)
+      return (SOX_EOF);
+
+  return (SOX_SUCCESS);
+}
+
+/* Write a buffer of data of length bytes.
+ * Returns number of bytes written.
+ */
+size_t lsx_writebuf(sox_format_t * ft, void const * buf, size_t len)
+{
+  size_t ret = fwrite(buf, (size_t) 1, len, (FILE*)ft->fp);
+  if (ret != len) {
+    lsx_fail_errno(ft, errno, "error writing output file");
+    clearerr((FILE*)ft->fp); /* Allows us to seek back to write header */
+  }
+  ft->tell_off += ret;
+  return ret;
+}
+
+uint64_t lsx_filelength(sox_format_t * ft)
+{
+  struct stat st;
+  int ret = fstat(fileno((FILE*)ft->fp), &st);
+
+  return (!ret && (st.st_mode & S_IFREG))? (uint64_t)st.st_size : 0;
+}
+
+int lsx_flush(sox_format_t * ft)
+{
+  return fflush((FILE*)ft->fp);
+}
+
+off_t lsx_tell(sox_format_t * ft)
+{
+  return ft->seekable? (off_t)ftello((FILE*)ft->fp) : (off_t)ft->tell_off;
+}
+
+int lsx_eof(sox_format_t * ft)
+{
+  return feof((FILE*)ft->fp);
+}
+
+int lsx_error(sox_format_t * ft)
+{
+  return ferror((FILE*)ft->fp);
+}
+
+void lsx_rewind(sox_format_t * ft)
+{
+  rewind((FILE*)ft->fp);
+  ft->tell_off = 0;
+}
+
+void lsx_clearerr(sox_format_t * ft)
+{
+  clearerr((FILE*)ft->fp);
+  ft->sox_errno = 0;
+}
+
+int lsx_unreadb(sox_format_t * ft, unsigned b)
+{
+  return ungetc((int)b, ft->fp);
+}
+
+/* Implements traditional fseek() behavior.  Meant to abstract out
+ * file operations so that they could one day also work on memory
+ * buffers.
+ *
+ * N.B. Can only seek forwards on non-seekable streams!
+ */
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence)
+{
+    if (ft->seekable == 0) {
+        /* If a stream peel off chars else EPERM */
+        if (whence == SEEK_CUR) {
+            while (offset > 0 && !feof((FILE*)ft->fp)) {
+                getc((FILE*)ft->fp);
+                offset--;
+                ++ft->tell_off;
+            }
+            if (offset)
+                lsx_fail_errno(ft,SOX_EOF, "offset past EOF");
+            else
+                ft->sox_errno = SOX_SUCCESS;
+        } else
+            lsx_fail_errno(ft,SOX_EPERM, "file not seekable");
+    } else {
+        if (fseeko((FILE*)ft->fp, offset, whence) == -1)
+            lsx_fail_errno(ft,errno, "%s", strerror(errno));
+        else
+            ft->sox_errno = SOX_SUCCESS;
+    }
+    return ft->sox_errno;
+}
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample)
+{
+  double wide_sample = to_sample - (to_sample % ft->signal.channels);
+  double to_d = wide_sample * ft->encoding.bits_per_sample / 8;
+  off_t to = to_d;
+  return (to != to_d)? SOX_EOF : lsx_seeki(ft, (byte_offset + to), SEEK_SET);
+}
+
+/* Read and write known datatypes in "machine format".  Swap if indicated.
+ * They all return SOX_EOF on error and SOX_SUCCESS on success.
+ */
+/* Read n-char string (and possibly null-terminating).
+ * Stop reading and null-terminate string if either a 0 or \n is reached.
+ */
+int lsx_reads(sox_format_t * ft, char *c, size_t len)
+{
+    char *sc;
+    char in;
+
+    sc = c;
+    do
+    {
+        if (lsx_readbuf(ft, &in, (size_t)1) != 1)
+        {
+            *sc = 0;
+            return (SOX_EOF);
+        }
+        if (in == 0 || in == '\n')
+            break;
+
+        *sc = in;
+        sc++;
+    } while (sc - c < (ptrdiff_t)len);
+    *sc = 0;
+    return(SOX_SUCCESS);
+}
+
+/* Write null-terminated string (without \0). */
+int lsx_writes(sox_format_t * ft, char const * c)
+{
+        if (lsx_writebuf(ft, c, strlen(c)) != strlen(c))
+                return(SOX_EOF);
+        return(SOX_SUCCESS);
+}
+
+/* return swapped 32-bit float */
+static void lsx_swapf(float * f)
+{
+    union {
+        uint32_t dw;
+        float f;
+    } u;
+
+    u.f= *f;
+    u.dw= (u.dw>>24) | ((u.dw>>8)&0xff00) | ((u.dw<<8)&0xff0000) | (u.dw<<24);
+    *f = u.f;
+}
+
+static void swap(void * data, size_t len)
+{
+  uint8_t * bytes = (uint8_t *)data;
+  size_t i;
+
+  for (i = 0; i < len / 2; ++i) {
+    char tmp = bytes[i];
+    bytes[i] = bytes[len - 1 - i];
+    bytes[len - 1 - i] = tmp;
+  }
+}
+
+static double lsx_swapdf(double data)
+{
+  swap(&data, sizeof(data));
+  return data;
+}
+
+static uint64_t lsx_swapqw(uint64_t data)
+{
+  swap(&data, sizeof(data));
+  return data;
+}
+
+/* Lookup table to reverse the bit order of a byte. ie MSB become LSB */
+static uint8_t const cswap[256] = {
+  0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
+  0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+  0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
+  0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+  0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
+  0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+  0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
+  0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+  0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
+  0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+  0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
+  0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+  0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
+  0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+  0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
+  0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+  0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
+  0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+  0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
+  0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+  0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
+  0x3F, 0xBF, 0x7F, 0xFF
+};
+
+/* Utilities to byte-swap values, use libc optimized macros if possible  */
+#define TWIDDLE_BYTE(ub, type) \
+  do { \
+    if (ft->encoding.reverse_bits) \
+      ub = cswap[ub]; \
+    if (ft->encoding.reverse_nibbles) \
+      ub = ((ub & 15) << 4) | (ub >> 4); \
+  } while (0);
+
+#define TWIDDLE_WORD(uw, type) \
+  if (ft->encoding.reverse_bytes) \
+    uw = lsx_swap ## type(uw);
+
+#define TWIDDLE_FLOAT(f, type) \
+  if (ft->encoding.reverse_bytes) \
+    lsx_swapf(&f);
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define READ_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    nread = lsx_readbuf(ft, buf, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      twiddle(buf[n], type); \
+    return nread; \
+  }
+
+/* Unpack a 3-byte value from a uint8_t * */
+#define sox_unpack3(p) (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN? \
+  ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16)) : \
+  ((p)[2] | ((p)[1] << 8) | ((p)[0] << 16)))
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be unpacked. */
+#define READ_FUNC_UNPACK(type, size, ctype, twiddle) \
+  size_t lsx_read_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nread; \
+    uint8_t *data = lsx_malloc(size * len); \
+    nread = lsx_readbuf(ft, data, len * size) / size; \
+    for (n = 0; n < nread; n++) \
+      buf[n] = sox_unpack ## size(data + n * size); \
+    free(data); \
+    return n; \
+  }
+
+READ_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+READ_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+READ_FUNC_UNPACK(3, 3, sox_uint24_t, TWIDDLE_WORD)
+READ_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+READ_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
+READ_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
+READ_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
+
+#define READ1_FUNC(type, ctype) \
+int lsx_read ## type(sox_format_t * ft, ctype * datum) { \
+  if (lsx_read_ ## type ## _buf(ft, datum, (size_t)1) == 1) \
+    return SOX_SUCCESS; \
+  if (!lsx_error(ft)) \
+    lsx_fail_errno(ft, errno, premature_eof); \
+  return SOX_EOF; \
+}
+
+static char const premature_eof[] = "premature EOF";
+
+READ1_FUNC(b,  uint8_t)
+READ1_FUNC(w,  uint16_t)
+READ1_FUNC(3,  sox_uint24_t)
+READ1_FUNC(dw, uint32_t)
+READ1_FUNC(qw, uint64_t)
+READ1_FUNC(f,  float)
+READ1_FUNC(df, double)
+
+int lsx_readchars(sox_format_t * ft, char * chars, size_t len)
+{
+  size_t ret = lsx_readbuf(ft, chars, len);
+  if (ret == len)
+    return SOX_SUCCESS;
+  if (!lsx_error(ft))
+    lsx_fail_errno(ft, errno, premature_eof);
+  return SOX_EOF;
+}
+
+/* N.B. This macro doesn't work for unaligned types (e.g. 3-byte
+   types). */
+#define WRITE_FUNC(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    for (n = 0; n < len; n++) \
+      twiddle(buf[n], type); \
+    nwritten = lsx_writebuf(ft, buf, len * size); \
+    return nwritten / size; \
+  }
+
+/* Pack a 3-byte value to a uint8_t * */
+#define sox_pack3(p, v) do {if (ft->encoding.reverse_bytes == MACHINE_IS_BIGENDIAN)\
+{(p)[0] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[2] = (v >> 16) & 0xff;} else \
+{(p)[2] = v & 0xff; (p)[1] = (v >> 8) & 0xff; (p)[0] = (v >> 16) & 0xff;} \
+} while (0)
+
+/* This (slower) macro works for unaligned types (e.g. 3-byte types)
+   that need to be packed. */
+#define WRITE_FUNC_PACK(type, size, ctype, twiddle) \
+  size_t lsx_write_ ## type ## _buf( \
+      sox_format_t * ft, ctype *buf, size_t len) \
+  { \
+    size_t n, nwritten; \
+    uint8_t *data = lsx_malloc(size * len); \
+    for (n = 0; n < len; n++) \
+      sox_pack ## size(data + n * size, buf[n]); \
+    nwritten = lsx_writebuf(ft, data, len * size); \
+    free(data); \
+    return nwritten / size; \
+  }
+
+WRITE_FUNC(b, 1, uint8_t, TWIDDLE_BYTE)
+WRITE_FUNC(w, 2, uint16_t, TWIDDLE_WORD)
+WRITE_FUNC_PACK(3, 3, sox_uint24_t, TWIDDLE_WORD)
+WRITE_FUNC(dw, 4, uint32_t, TWIDDLE_WORD)
+WRITE_FUNC(qw, 8, uint64_t, TWIDDLE_WORD)
+WRITE_FUNC(f, sizeof(float), float, TWIDDLE_FLOAT)
+WRITE_FUNC(df, sizeof(double), double, TWIDDLE_WORD)
+
+#define WRITE1U_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, unsigned d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1S_FUNC(type, ctype) \
+  int lsx_writes ## type(sox_format_t * ft, signed d) \
+  { ctype datum = (ctype)d; \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+#define WRITE1_FUNC(type, ctype) \
+  int lsx_write ## type(sox_format_t * ft, ctype datum) \
+  { \
+    return lsx_write_ ## type ## _buf(ft, &datum, (size_t)1) == 1 ? SOX_SUCCESS : SOX_EOF; \
+  }
+
+WRITE1U_FUNC(b, uint8_t)
+WRITE1U_FUNC(w, uint16_t)
+WRITE1U_FUNC(3, sox_uint24_t)
+WRITE1U_FUNC(dw, uint32_t)
+WRITE1_FUNC(qw, uint64_t)
+WRITE1S_FUNC(b, uint8_t)
+WRITE1S_FUNC(w, uint16_t)
+WRITE1_FUNC(df, double)
+
+int lsx_writef(sox_format_t * ft, double datum)
+{
+  float f = datum;
+  return lsx_write_f_buf(ft, &f, (size_t) 1) == 1 ? SOX_SUCCESS : SOX_EOF;
+}
diff --git a/freedv/tags/1.2.2/src/sox/libsox.c b/freedv/tags/1.2.2/src/sox/libsox.c
new file mode 100644 (file)
index 0000000..4362025
--- /dev/null
@@ -0,0 +1,225 @@
+/* Implements the public API for libSoX general functions
+ * All public functions & data are prefixed with sox_ .
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <string.h>
+
+const char *sox_version(void)
+{
+  static char versionstr[20];
+
+  sprintf(versionstr, "%d.%d.%d",
+          (SOX_LIB_VERSION_CODE & 0xff0000) >> 16,
+          (SOX_LIB_VERSION_CODE & 0x00ff00) >> 8,
+          (SOX_LIB_VERSION_CODE & 0x0000ff));
+  return(versionstr);
+}
+
+sox_version_info_t const * sox_version_info(void)
+{
+#define STRINGIZE1(x) #x
+#define STRINGIZE(x) STRINGIZE1(x)
+    static char arch[30];
+    static sox_version_info_t info = {
+        /* size */
+        sizeof(sox_version_info_t),
+        /* flags */
+        (sox_version_flags_t)(
+#if HAVE_POPEN
+        sox_version_have_popen +
+#endif
+#if  HAVE_MAGIC
+        sox_version_have_magic +
+#endif
+#if HAVE_OPENMP
+        sox_version_have_threads +
+#endif
+#ifdef HAVE_FMEMOPEN
+        sox_version_have_memopen +
+#endif
+        sox_version_none),
+        /* version_code */
+        SOX_LIB_VERSION_CODE,
+        /* version */
+        NULL,
+        /* sox_version_extra */
+#ifdef PACKAGE_EXTRA
+        PACKAGE_EXTRA,
+#else
+        NULL,
+#endif
+        /* sox_time */
+        __DATE__ " " __TIME__,
+        /* sox_distro */
+#ifdef DISTRO
+        DISTRO,
+#else
+        NULL,
+#endif
+        /* sox_compiler */
+#if defined __GNUC__
+        "gcc " __VERSION__,
+#elif defined _MSC_VER
+        "msvc " STRINGIZE(_MSC_FULL_VER),
+#elif defined __SUNPRO_C
+    fprintf(file, "sun c " STRINGIZE(__SUNPRO_C),
+#else
+        NULL,
+#endif
+        /* sox_arch */
+        NULL
+    };
+
+    if (!info.version)
+    {
+        info.version = sox_version();
+    }
+
+    if (!info.arch)
+    {
+        snprintf(arch, sizeof(arch),
+            "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR "%" PRIuPTR
+            " %" PRIuPTR "%" PRIuPTR " %" PRIuPTR "%" PRIuPTR " %c %s",
+            sizeof(char), sizeof(short), sizeof(long), sizeof(off_t),
+            sizeof(float), sizeof(double), sizeof(int *), sizeof(int (*)(void)),
+            MACHINE_IS_BIGENDIAN ? 'B' : 'L',
+            (info.flags & sox_version_have_threads) ? "OMP" : "");
+        arch[sizeof(arch) - 1] = 0;
+        info.arch = arch;
+    }
+
+    return &info;
+}
+
+/* Default routine to output messages; can be overridden */
+static void output_message(
+    unsigned level, const char *filename, const char *fmt, va_list ap)
+{
+  if (sox_globals.verbosity >= level) {
+    char base_name[128];
+    sox_basename(base_name, sizeof(base_name), filename);
+    fprintf(stderr, "%s: ", base_name);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+  }
+}
+
+static sox_globals_t s_sox_globals = {
+  2,               /* unsigned     verbosity */
+  output_message,  /* sox_output_message_handler */
+  sox_false,       /* sox_bool     repeatable */
+  8192,            /* size_t       bufsiz */
+  0,               /* size_t       input_bufsiz */
+  0,               /* int32_t      ranqd1 */
+  NULL,            /* char const * stdin_in_use_by */
+  NULL,            /* char const * stdout_in_use_by */
+  NULL,            /* char const * subsystem */
+  NULL,            /* char       * tmp_path */
+  sox_false,       /* sox_bool     use_magic */
+  sox_false        /* sox_bool     use_threads */
+};
+
+sox_globals_t * sox_get_globals(void)
+{
+    return &s_sox_globals;
+}
+
+/* FIXME: Not thread safe using globals */
+static sox_effects_globals_t s_sox_effects_globals =
+    {sox_plot_off, &s_sox_globals};
+
+sox_effects_globals_t *
+sox_get_effects_globals(void)
+{
+    return &s_sox_effects_globals;
+}
+
+char const * sox_strerror(int sox_errno)
+{
+  static char const * const errors[] = {
+    "Invalid Audio Header",
+    "Unsupported data format",
+    "Can't allocate memory",
+    "Operation not permitted",
+    "Operation not supported",
+    "Invalid argument",
+  };
+  if (sox_errno < SOX_EHDR)
+    return strerror(sox_errno);
+  sox_errno -= SOX_EHDR;
+  if (sox_errno < 0 || (size_t)sox_errno >= array_length(errors))
+    return "Unknown error";
+  return errors[sox_errno];
+}
+
+size_t sox_basename(char * base_buffer, size_t base_buffer_len, const char * filename)
+{
+  if (!base_buffer || !base_buffer_len)
+  {
+    return 0;
+  }
+  else
+  {
+    char const * slash_pos = LAST_SLASH(filename);
+    char const * base_name = slash_pos ? slash_pos + 1 : filename;
+    char const * dot_pos   = strrchr(base_name, '.');
+    size_t i, len;
+    dot_pos = dot_pos ? dot_pos : base_name + strlen(base_name);
+    len = dot_pos - base_name;
+    len = min(len, base_buffer_len - 1);
+    for (i = 0; i < len; i++)
+    {
+      base_buffer[i] = base_name[i];
+    }
+    base_buffer[i] = 0;
+    return i;
+  }
+}
+
+#define SOX_MESSAGE_FUNCTION(name,level) \
+void name(char const * fmt, ...) { \
+  va_list ap; \
+  va_start(ap, fmt); \
+  if (sox_globals.output_message_handler) \
+    (*sox_globals.output_message_handler)(level,sox_globals.subsystem,fmt,ap); \
+  va_end(ap); \
+}
+
+SOX_MESSAGE_FUNCTION(lsx_fail_impl  , 1)
+SOX_MESSAGE_FUNCTION(lsx_warn_impl  , 2)
+SOX_MESSAGE_FUNCTION(lsx_report_impl, 3)
+SOX_MESSAGE_FUNCTION(lsx_debug_impl , 4)
+SOX_MESSAGE_FUNCTION(lsx_debug_more_impl , 5)
+SOX_MESSAGE_FUNCTION(lsx_debug_most_impl , 6)
+
+#undef SOX_MESSAGE_FUNCTION
+
+int sox_init(void)
+{
+  return lsx_effects_init();
+}
+
+int sox_quit(void)
+{
+  #ifndef __FREEDV__
+  sox_format_quit();
+  #endif
+  return lsx_effects_quit();
+}
diff --git a/freedv/tags/1.2.2/src/sox/sox.h b/freedv/tags/1.2.2/src/sox/sox.h
new file mode 100644 (file)
index 0000000..0537255
--- /dev/null
@@ -0,0 +1,2608 @@
+/* libSoX Library Public Interface
+ *
+ * Copyright 1999-2011 Chris Bagwell and SoX Contributors.
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/** @file
+Contains the interface exposed to clients of the libSoX library.
+Symbols starting with "sox_" or "SOX_" are part of the public interface for
+libSoX clients (applications that consume libSoX). Symbols starting with
+"lsx_" or "LSX_" are internal use by libSoX and plugins.
+LSX_ and lsx_ symbols should not be used by libSoX-based applications.
+*/
+
+#ifndef SOX_H
+#define SOX_H /**< Client API: This macro is defined if sox.h has been included. */
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* Suppress warnings from use of type long long. */
+#if defined __GNUC__
+#pragma GCC system_header
+#endif
+
+/*****************************************************************************
+API decoration macros:
+Mostly for documentation purposes. For some compilers, decorations also affect
+code generation, influence compiler warnings or activate compiler
+optimizations.
+*****************************************************************************/
+
+/**
+Plugins API:
+Attribute required on all functions exported by libSoX and on all function
+pointer types used by the libSoX API.
+*/
+#ifdef __GNUC__
+#define LSX_API  __attribute__ ((cdecl)) /* libSoX function */
+#elif _MSC_VER
+#define LSX_API  __cdecl /* libSoX function */
+#else
+#define LSX_API /* libSoX function */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter or local variable to suppress warnings about
+the variable being unused (especially in macro-generated code).
+*/
+#ifdef __GNUC__
+#define LSX_UNUSED  __attribute__ ((unused)) /* Parameter or local variable is intentionally unused. */
+#else
+#define LSX_UNUSED /* Parameter or local variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+LSX_PRINTF12: Attribute applied to a function to indicate that it requires
+a printf-style format string for arg1 and that printf parameters start at
+arg2.
+*/
+#ifdef __GNUC__
+#define LSX_PRINTF12  __attribute__ ((format (printf, 1, 2))) /* Function has printf-style arguments. */
+#else
+#define LSX_PRINTF12 /* Function has printf-style arguments. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that it has no side effects and
+depends only its input parameters and global memory. If called repeatedly, it
+returns the same result each time.
+*/
+#ifdef __GNUC__
+#define LSX_RETURN_PURE __attribute__ ((pure)) /* Function is pure. */
+#else
+#define LSX_RETURN_PURE /* Function is pure. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the
+return value is always a pointer to a valid object (never NULL).
+*/
+#ifdef _Ret_
+#define LSX_RETURN_VALID _Ret_ /* Function always returns a valid object (never NULL). */
+#else
+#define LSX_RETURN_VALID /* Function always returns a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid array (never NULL).
+*/
+#ifdef _Ret_valid_
+#define LSX_RETURN_ARRAY _Ret_valid_ /* Function always returns a valid array (never NULL). */
+#else
+#define LSX_RETURN_ARRAY /* Function always returns a valid array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the return value is always a
+pointer to a valid 0-terminated array (never NULL).
+*/
+#ifdef _Ret_z_
+#define LSX_RETURN_VALID_Z _Ret_z_ /* Function always returns a 0-terminated array (never NULL). */
+#else
+#define LSX_RETURN_VALID_Z /* Function always returns a 0-terminated array (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a function to indicate that the returned pointer may be
+null.
+*/
+#ifdef _Ret_opt_
+#define LSX_RETURN_OPT _Ret_opt_ /* Function may return NULL. */
+#else
+#define LSX_RETURN_OPT /* Function may return NULL. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one const element of the pointed-to type (never NULL).
+*/
+#ifdef _In_
+#define LSX_PARAM_IN _In_ /* Required const pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_IN /* Required const pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to a const 0-terminated string (never NULL).
+*/
+#ifdef _In_z_
+#define LSX_PARAM_IN_Z _In_z_ /* Required const pointer to 0-terminated string (never NULL). */
+#else
+#define LSX_PARAM_IN_Z /* Required const pointer to 0-terminated string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a const
+pointer to a 0-terminated printf format string.
+*/
+#ifdef _Printf_format_string_
+#define LSX_PARAM_IN_PRINTF _Printf_format_string_ /* Required const pointer to 0-terminated printf format string (never NULL). */
+#else
+#define LSX_PARAM_IN_PRINTF /* Required const pointer to 0-terminated printf format string (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const initialized elements of the pointed-to type, where
+(len) is the name of another parameter.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _In_count_
+#define LSX_PARAM_IN_COUNT(len) _In_count_(len) /* Required const pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_IN_COUNT(len) /* Required const pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) const bytes of initialized data, where (len) is the name of
+another parameter.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _In_bytecount_
+#define LSX_PARAM_IN_BYTECOUNT(len) _In_bytecount_(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#else
+#define LSX_PARAM_IN_BYTECOUNT(len) /* Required const pointer to (len) bytes of data (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to one const element of the pointed-to type.
+*/
+#ifdef _In_opt_
+#define LSX_PARAM_IN_OPT _In_opt_ /* Optional const pointer to a valid object (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT /* Optional const pointer to a valid object (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to a const 0-terminated string.
+*/
+#ifdef _In_opt_z_
+#define LSX_PARAM_IN_OPT_Z _In_opt_z_ /* Optional const pointer to 0-terminated string (may be NULL). */
+#else
+#define LSX_PARAM_IN_OPT_Z /* Optional const pointer to 0-terminated string (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to one initialized element of the pointed-to type (never NULL). The
+function may modify the element.
+*/
+#ifdef _Inout_
+#define LSX_PARAM_INOUT _Inout_ /* Required pointer to a valid object (never NULL). */
+#else
+#define LSX_PARAM_INOUT /* Required pointer to a valid object (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to (len) initialized elements of the pointed-to type (never NULL). The
+function may modify the elements.
+@param len The parameter that contains the number of elements in the array.
+*/
+#ifdef _Inout_count_x_
+#define LSX_PARAM_INOUT_COUNT(len) _Inout_count_x_(len) /* Required pointer to (len) valid objects (never NULL). */
+#else
+#define LSX_PARAM_INOUT_COUNT(len) /* Required pointer to (len) valid objects (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for one element of the pointed-to type (never
+NULL). The function will initialize the element.
+*/
+#ifdef _Out_
+#define LSX_PARAM_OUT _Out_ /* Required pointer to an object to be initialized (never NULL). */
+#else
+#define LSX_PARAM_OUT /* Required pointer to an object to be initialized (never NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) bytes of data (never NULL), where (len)
+is the name of another parameter. The function may write up to len bytes of
+data to this memory.
+@param len The parameter that contains the number of bytes in the array.
+*/
+#ifdef _Out_bytecap_
+#define LSX_PARAM_OUT_BYTECAP(len) _Out_bytecap_(len) /* Required pointer to writable buffer with room for len bytes. */
+#else
+#define LSX_PARAM_OUT_BYTECAP(len) /* Required pointer to writable buffer with room for len bytes. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled)
+elements will have been initialized, where (filled) is either the dereference
+of another pointer parameter (for example "*written") or the "return"
+parameter (indicating that the function returns the number of elements
+written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array, or "return" if the value is returned.
+*/
+#ifdef _Out_cap_post_count_
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) _Out_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#else
+#define LSX_PARAM_OUT_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled) elements will have been initialized. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer to memory sufficient for (len) elements of the pointed-to type (never
+NULL), where (len) is the name of another parameter. On return, (filled+1)
+elements will have been initialized, with the last element having been
+initialized to 0, where (filled) is either the dereference of another pointer
+parameter (for example, "*written") or the "return" parameter (indicating that
+the function returns the number of elements written).
+@param len The parameter that contains the number of elements in the array.
+@param filled The dereference of the parameter that receives the number of elements written to the array (not counting the terminating null), or "return" if the value is returned.
+*/
+#ifdef _Out_z_cap_post_count_
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) _Out_z_cap_post_count_(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#else
+#define LSX_PARAM_OUT_Z_CAP_POST_COUNT(len,filled) /* Required pointer to buffer for (len) elements (never NULL); on return, (filled+1) elements will have been initialized, and the array will be 0-terminated. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is either NULL
+or a valid pointer to memory sufficient for one element of the pointed-to
+type. The function will initialize the element.
+*/
+#ifdef _Out_opt_
+#define LSX_PARAM_OUT_OPT _Out_opt_ /* Optional pointer to an object to be initialized (may be NULL). */
+#else
+#define LSX_PARAM_OUT_OPT /* Optional pointer to an object to be initialized (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which may be NULL when the function is
+invoked.
+*/
+#ifdef _Deref_pre_maybenull_
+#define LSX_PARAM_DEREF_PRE_MAYBENULL _Deref_pre_maybenull_ /* Required pointer (never NULL) to another pointer (may be NULL). */
+#else
+#define LSX_PARAM_DEREF_PRE_MAYBENULL /* Required pointer (never NULL) to another pointer (may be NULL). */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be NULL when the function
+returns.
+*/
+#ifdef _Deref_post_null_
+#define LSX_PARAM_DEREF_POST_NULL _Deref_post_null_ /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NULL /* Required pointer (never NULL) to another pointer, which will be NULL on exit. */
+#endif
+
+/**
+Plugins API:
+Attribute applied to a parameter to indicate that the parameter is a valid
+pointer (never NULL) to another pointer which will be non-NULL when the
+function returns.
+*/
+#ifdef _Deref_post_notnull_
+#define LSX_PARAM_DEREF_POST_NOTNULL _Deref_post_notnull_ /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#else
+#define LSX_PARAM_DEREF_POST_NOTNULL /* Required pointer (never NULL) to another pointer, which will be valid (not NULL) on exit. */
+#endif
+
+/**
+Plugins API:
+Expression that "uses" a potentially-unused variable to avoid compiler
+warnings (especially in macro-generated code).
+*/
+#ifdef _PREFAST_
+#define LSX_USE_VAR(x)  ((void)(x=0)) /* During static analysis, initialize unused variables to 0. */
+#else
+#define LSX_USE_VAR(x)  ((void)(x)) /* Parameter or variable is intentionally unused. */
+#endif
+
+/**
+Plugins API:
+Compile-time assertion. Causes a compile error if the expression is false.
+@param e  The expression to test. If expression is false, compilation will fail.
+@param f  A unique identifier for the test, for example foo_must_not_be_zero.
+*/
+#define lsx_static_assert(e,f) enum {lsx_static_assert_##f = 1/((e) ? 1 : 0)}
+
+/*****************************************************************************
+Basic typedefs:
+*****************************************************************************/
+
+/**
+Client API:
+Signed twos-complement 8-bit type. Typically defined as signed char.
+*/
+#if SCHAR_MAX==127 && SCHAR_MIN==(-128)
+typedef signed char sox_int8_t;
+#elif CHAR_MAX==127 && CHAR_MIN==(-128)
+typedef char sox_int8_t;
+#else
+#error Unable to determine an appropriate definition for sox_int8_t.
+#endif
+
+/**
+Client API:
+Unsigned 8-bit type. Typically defined as unsigned char.
+*/
+#if UCHAR_MAX==0xff
+typedef unsigned char sox_uint8_t;
+#elif CHAR_MAX==0xff && CHAR_MIN==0
+typedef char sox_uint8_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint8_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 16-bit type. Typically defined as short.
+*/
+#if SHRT_MAX==32767 && SHRT_MIN==(-32768)
+typedef short sox_int16_t;
+#elif INT_MAX==32767 && INT_MIN==(-32768)
+typedef int sox_int16_t;
+#else
+#error Unable to determine an appropriate definition for sox_int16_t.
+#endif
+
+/**
+Client API:
+Unsigned 16-bit type. Typically defined as unsigned short.
+*/
+#if USHRT_MAX==0xffff
+typedef unsigned short sox_uint16_t;
+#elif UINT_MAX==0xffff
+typedef unsigned int sox_uint16_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint16_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 32-bit type. Typically defined as int.
+*/
+#if INT_MAX==2147483647 && INT_MIN==(-2147483647-1)
+typedef int sox_int32_t;
+#elif LONG_MAX==2147483647 && LONG_MIN==(-2147483647-1)
+typedef long sox_int32_t;
+#else
+#error Unable to determine an appropriate definition for sox_int32_t.
+#endif
+
+/**
+Client API:
+Unsigned 32-bit type. Typically defined as unsigned int.
+*/
+#if UINT_MAX==0xffffffff
+typedef unsigned int sox_uint32_t;
+#elif ULONG_MAX==0xffffffff
+typedef unsigned long sox_uint32_t;
+#else
+#error Unable to determine an appropriate definition for sox_uint32_t.
+#endif
+
+/**
+Client API:
+Signed twos-complement 64-bit type. Typically defined as long or long long.
+*/
+#if LONG_MAX==9223372036854775807 && LONG_MIN==(-9223372036854775807-1)
+typedef long sox_int64_t;
+#elif defined(_MSC_VER)
+typedef __int64 sox_int64_t;
+#else
+typedef long long sox_int64_t;
+#endif
+
+/**
+Client API:
+Unsigned 64-bit type. Typically defined as unsigned long or unsigned long long.
+*/
+#if ULONG_MAX==0xffffffffffffffff
+typedef unsigned long sox_uint64_t;
+#elif defined(_MSC_VER)
+typedef unsigned __int64 sox_uint64_t;
+#else
+typedef unsigned long long sox_uint64_t;
+#endif
+
+#ifndef _DOXYGEN_
+lsx_static_assert(sizeof(sox_int8_t)==1,   sox_int8_size);
+lsx_static_assert(sizeof(sox_uint8_t)==1,  sox_uint8_size);
+lsx_static_assert(sizeof(sox_int16_t)==2,  sox_int16_size);
+lsx_static_assert(sizeof(sox_uint16_t)==2, sox_uint16_size);
+lsx_static_assert(sizeof(sox_int32_t)==4,  sox_int32_size);
+lsx_static_assert(sizeof(sox_uint32_t)==4, sox_uint32_size);
+lsx_static_assert(sizeof(sox_int64_t)==8,  sox_int64_size);
+lsx_static_assert(sizeof(sox_uint64_t)==8, sox_uint64_size);
+#endif
+
+/**
+Client API:
+Alias for sox_int32_t (beware of the extra byte).
+*/
+typedef sox_int32_t sox_int24_t;
+
+/**
+Client API:
+Alias for sox_uint32_t (beware of the extra byte).
+*/
+typedef sox_uint32_t sox_uint24_t;
+
+/**
+Client API:
+Native SoX audio sample type (alias for sox_int32_t).
+*/
+typedef sox_int32_t sox_sample_t;
+
+/**
+Client API:
+Samples per second is stored as a double.
+*/
+typedef double sox_rate_t;
+
+/**
+Client API:
+File's metadata, access via sox_*_comments functions.
+*/
+typedef char * * sox_comments_t;
+
+/*****************************************************************************
+Enumerations:
+*****************************************************************************/
+
+/**
+Client API:
+Boolean type, assignment (but not necessarily binary) compatible with C++ bool.
+*/
+typedef enum sox_bool {
+    sox_false, /**< False = 0. */
+    sox_true   /**< True = 1. */
+} sox_bool;
+
+/**
+Client API:
+no, yes, or default (default usually implies some kind of auto-detect logic).
+*/
+typedef enum sox_option_t {
+    sox_option_no,      /**< Option specified as no = 0. */
+    sox_option_yes,     /**< Option specified as yes = 1. */
+    sox_option_default  /**< Option unspecified = 2. */
+} sox_option_t;
+
+/**
+Client API:
+The libSoX-specific error codes.
+libSoX functions may return these codes or others that map from errno codes.
+*/
+enum sox_error_t {
+  SOX_SUCCESS = 0,     /**< Function succeeded = 0 */
+  SOX_EOF = -1,        /**< End Of File or other error = -1 */
+  SOX_EHDR = 2000,     /**< Invalid Audio Header = 2000 */
+  SOX_EFMT,            /**< Unsupported data format = 2001 */
+  SOX_ENOMEM,          /**< Can't alloc memory = 2002 */
+  SOX_EPERM,           /**< Operation not permitted = 2003 */
+  SOX_ENOTSUP,         /**< Operation not supported = 2004 */
+  SOX_EINVAL           /**< Invalid argument = 2005 */
+};
+
+/**
+Client API:
+Flags indicating whether optional features are present in this build of libSoX.
+*/
+typedef enum sox_version_flags_t {
+    sox_version_none = 0,         /**< No special features = 0. */
+    sox_version_have_popen = 1,   /**< popen = 1. */
+    sox_version_have_magic = 2,   /**< magic = 2. */
+    sox_version_have_threads = 4, /**< threads = 4. */
+    sox_version_have_memopen = 8  /**< memopen = 8. */
+} sox_version_flags_t;
+
+/**
+Client API:
+Format of sample data.
+*/
+typedef enum sox_encoding_t {
+  SOX_ENCODING_UNKNOWN   , /**< encoding has not yet been determined */
+
+  SOX_ENCODING_SIGN2     , /**< signed linear 2's comp: Mac */
+  SOX_ENCODING_UNSIGNED  , /**< unsigned linear: Sound Blaster */
+  SOX_ENCODING_FLOAT     , /**< floating point (binary format) */
+  SOX_ENCODING_FLOAT_TEXT, /**< floating point (text format) */
+  SOX_ENCODING_FLAC      , /**< FLAC compression */
+  SOX_ENCODING_HCOM      , /**< Mac FSSD files with Huffman compression */
+  SOX_ENCODING_WAVPACK   , /**< WavPack with integer samples */
+  SOX_ENCODING_WAVPACKF  , /**< WavPack with float samples */
+  SOX_ENCODING_ULAW      , /**< u-law signed logs: US telephony, SPARC */
+  SOX_ENCODING_ALAW      , /**< A-law signed logs: non-US telephony, Psion */
+  SOX_ENCODING_G721      , /**< G.721 4-bit ADPCM */
+  SOX_ENCODING_G723      , /**< G.723 3 or 5 bit ADPCM */
+  SOX_ENCODING_CL_ADPCM  , /**< Creative Labs 8 --> 2,3,4 bit Compressed PCM */
+  SOX_ENCODING_CL_ADPCM16, /**< Creative Labs 16 --> 4 bit Compressed PCM */
+  SOX_ENCODING_MS_ADPCM  , /**< Microsoft Compressed PCM */
+  SOX_ENCODING_IMA_ADPCM , /**< IMA Compressed PCM */
+  SOX_ENCODING_OKI_ADPCM , /**< Dialogic/OKI Compressed PCM */
+  SOX_ENCODING_DPCM      , /**< Differential PCM: Fasttracker 2 (xi) */
+  SOX_ENCODING_DWVW      , /**< Delta Width Variable Word */
+  SOX_ENCODING_DWVWN     , /**< Delta Width Variable Word N-bit */
+  SOX_ENCODING_GSM       , /**< GSM 6.10 33byte frame lossy compression */
+  SOX_ENCODING_MP3       , /**< MP3 compression */
+  SOX_ENCODING_VORBIS    , /**< Vorbis compression */
+  SOX_ENCODING_AMR_WB    , /**< AMR-WB compression */
+  SOX_ENCODING_AMR_NB    , /**< AMR-NB compression */
+  SOX_ENCODING_CVSD      , /**< Continuously Variable Slope Delta modulation */
+  SOX_ENCODING_LPC10     , /**< Linear Predictive Coding */
+
+  SOX_ENCODINGS            /**< End of list marker */
+} sox_encoding_t;
+
+/**
+Client API:
+Flags for sox_encodings_info_t: lossless/lossy1/lossy2.
+*/
+typedef enum sox_encodings_flags_t {
+  sox_encodings_none   = 0, /**< no flags specified (implies lossless encoding) = 0. */
+  sox_encodings_lossy1 = 1, /**< encode, decode: lossy once = 1. */
+  sox_encodings_lossy2 = 2  /**< encode, decode, encode, decode: lossy twice = 2. */
+} sox_encodings_flags_t;
+
+/**
+Client API:
+Type of plot.
+*/
+typedef enum sox_plot_t {
+    sox_plot_off,     /**< No plot = 0. */
+    sox_plot_octave,  /**< Octave plot = 1. */
+    sox_plot_gnuplot, /**< Gnuplot plot = 2. */
+    sox_plot_data     /**< Plot data = 3. */
+} sox_plot_t;
+
+/**
+Client API:
+Loop modes: upper 4 bits mask the loop blass, lower 4 bits describe
+the loop behaviour, for example single shot, bidirectional etc.
+*/
+enum sox_loop_flags_t {
+  sox_loop_none = 0,          /**< single-shot = 0 */
+  sox_loop_forward = 1,       /**< forward loop = 1 */
+  sox_loop_forward_back = 2,  /**< forward/back loop = 2 */
+  sox_loop_8 = 32,            /**< 8 loops (??) = 32 */
+  sox_loop_sustain_decay = 64 /**< AIFF style, one sustain & one decay loop = 64 */
+};
+
+/**
+Plugins API:
+Is file a real file, a pipe, or a url?
+*/
+typedef enum lsx_io_type
+{
+    lsx_io_file, /**< File is a real file = 0. */
+    lsx_io_pipe, /**< File is a pipe (no seeking) = 1. */
+    lsx_io_url   /**< File is a URL (no seeking) = 2. */
+} lsx_io_type;
+
+/*****************************************************************************
+Macros:
+*****************************************************************************/
+
+/**
+Client API:
+Compute a 32-bit integer API version from three 8-bit parts.
+@param a Major version.
+@param b Minor version.
+@param c Revision or build number.
+@returns 32-bit integer API version 0x000a0b0c.
+*/
+#define SOX_LIB_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+
+/**
+Client API:
+The API version of the sox.h file. It is not meant to follow the version
+number of SoX but it has historically. Please do not count on
+SOX_LIB_VERSION_CODE staying in sync with the libSoX version.
+*/
+#define SOX_LIB_VERSION_CODE   SOX_LIB_VERSION(14, 4, 1)
+
+/**
+Client API:
+Returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MIN(8) = 0x80, SOX_INT_MIN(16) = 0x8000, etc.
+@param bits Size of value for which to calculate minimum.
+@returns the smallest (negative) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MIN(bits) (1 <<((bits)-1))
+
+/**
+Client API:
+Returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer;
+for example, SOX_INT_MAX(8) = 0x7F, SOX_INT_MAX(16) = 0x7FFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest (positive) value storable in a twos-complement signed
+integer with the specified number of bits, cast to an unsigned integer.
+*/
+#define SOX_INT_MAX(bits) (((unsigned)-1)>>(33-(bits)))
+
+/**
+Client API:
+Returns the largest value storable in an unsigned integer with the specified
+number of bits; for example, SOX_UINT_MAX(8) = 0xFF,
+SOX_UINT_MAX(16) = 0xFFFF, etc.
+@param bits Size of value for which to calculate maximum.
+@returns the largest value storable in an unsigned integer with the specified
+number of bits.
+*/
+#define SOX_UINT_MAX(bits) (SOX_INT_MIN(bits)|SOX_INT_MAX(bits))
+
+/**
+Client API:
+Returns 0x7F.
+*/
+#define SOX_INT8_MAX  SOX_INT_MAX(8)
+
+/**
+Client API:
+Returns 0x7FFF.
+*/
+#define SOX_INT16_MAX SOX_INT_MAX(16)
+
+/**
+Client API:
+Returns 0x7FFFFF.
+*/
+#define SOX_INT24_MAX SOX_INT_MAX(24)
+
+/**
+Client API:
+Returns 0x7FFFFFFF.
+*/
+#define SOX_INT32_MAX SOX_INT_MAX(32)
+
+/**
+Client API:
+Bits in a sox_sample_t = 32.
+*/
+#define SOX_SAMPLE_PRECISION 32
+
+/**
+Client API:
+Max value for sox_sample_t = 0x7FFFFFFF.
+*/
+#define SOX_SAMPLE_MAX (sox_sample_t)SOX_INT_MAX(32)
+
+/**
+Client API:
+Min value for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_MIN (sox_sample_t)SOX_INT_MIN(32)
+
+
+/*                Conversions: Linear PCM <--> sox_sample_t
+ *
+ *   I/O      Input    sox_sample_t Clips?   Input    sox_sample_t Clips?
+ *  Format   Minimum     Minimum     I O    Maximum     Maximum     I O
+ *  ------  ---------  ------------ -- --   --------  ------------ -- --
+ *  Float     -inf         -1        y n      inf      1 - 5e-10    y n
+ *  Int8      -128        -128       n n      127     127.9999999   n y
+ *  Int16    -32768      -32768      n n     32767    32767.99998   n y
+ *  Int24   -8388608    -8388608     n n    8388607   8388607.996   n y
+ *  Int32  -2147483648 -2147483648   n n   2147483647 2147483647    n n
+ *
+ * Conversions are as accurate as possible (with rounding).
+ *
+ * Rounding: halves toward +inf, all others to nearest integer.
+ *
+ * Clips? shows whether on not there is the possibility of a conversion
+ * clipping to the minimum or maximum value when inputing from or outputing
+ * to a given type.
+ *
+ * Unsigned integers are converted to and from signed integers by flipping
+ * the upper-most bit then treating them as signed integers.
+ */
+
+/**
+Client API:
+Declares the temporary local variables that are required when using SOX
+conversion macros.
+*/
+#define SOX_SAMPLE_LOCALS sox_sample_t sox_macro_temp_sample LSX_UNUSED; \
+  double sox_macro_temp_double LSX_UNUSED
+
+/**
+Client API:
+Sign bit for sox_sample_t = 0x80000000.
+*/
+#define SOX_SAMPLE_NEG SOX_INT_MIN(32)
+
+/**
+Client API:
+Converts sox_sample_t to an unsigned integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Unsigned integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_UNSIGNED(bits,d,clips) \
+  (sox_uint##bits##_t)(SOX_SAMPLE_TO_SIGNED(bits,d,clips)^SOX_INT_MIN(bits))
+
+/**
+Client API:
+Converts sox_sample_t to a signed integer of width (bits).
+@param bits  Width of resulting sample (1 through 32).
+@param d     Input sample to be converted.
+@param clips Variable that is incremented if the result is too big.
+@returns Signed integer of width (bits).
+*/
+#define SOX_SAMPLE_TO_SIGNED(bits,d,clips) \
+  (sox_int##bits##_t)(LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-(1<<(31-bits))?++(clips),SOX_INT_MAX(bits):((sox_uint32_t)(sox_macro_temp_sample+(1<<(31-bits))))>>(32-bits))
+
+/**
+Client API:
+Converts signed integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_TO_SAMPLE(bits,d)((sox_sample_t)(d)<<(32-bits))
+
+/**
+Client API:
+Converts unsigned integer of width (bits) to sox_sample_t.
+@param bits Width of input sample (1 through 32).
+@param d    Input sample to be converted.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_TO_SAMPLE(bits,d)(SOX_SIGNED_TO_SAMPLE(bits,d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts unsigned 8-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_8BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts signed 8-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_8BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(8,d)
+
+/**
+Client API:
+Converts unsigned 16-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_16BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts signed 16-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_16BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(16,d)
+
+/**
+Client API:
+Converts unsigned 24-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_24BIT_TO_SAMPLE(d,clips) SOX_UNSIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts signed 24-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_24BIT_TO_SAMPLE(d,clips) SOX_SIGNED_TO_SAMPLE(24,d)
+
+/**
+Client API:
+Converts unsigned 32-bit integer to sox_sample_t.
+@param d     Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_UNSIGNED_32BIT_TO_SAMPLE(d,clips) ((sox_sample_t)(d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts signed 32-bit integer to sox_sample_t.
+@param d    Input sample to be converted.
+@param clips The parameter is not used.
+@returns SoX native sample value.
+*/
+#define SOX_SIGNED_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(d)
+
+/**
+Client API:
+Converts 32-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_32BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<SOX_SAMPLE_MIN?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double>=SOX_SAMPLE_MAX+1.?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double)
+
+/**
+Client API:
+Converts 64-bit float to sox_sample_t.
+@param d     Input sample to be converted, range [-1, 1).
+@param clips Variable to increment if the input sample is too large or too small.
+@returns SoX native sample value.
+*/
+#define SOX_FLOAT_64BIT_TO_SAMPLE(d,clips) (sox_sample_t)(LSX_USE_VAR(sox_macro_temp_sample),sox_macro_temp_double=(d)*(SOX_SAMPLE_MAX+1.),sox_macro_temp_double<0?sox_macro_temp_double<=SOX_SAMPLE_MIN-.5?++(clips),SOX_SAMPLE_MIN:sox_macro_temp_double-.5:sox_macro_temp_double>=SOX_SAMPLE_MAX+.5?sox_macro_temp_double>SOX_SAMPLE_MAX+1.?++(clips),SOX_SAMPLE_MAX:SOX_SAMPLE_MAX:sox_macro_temp_double+.5)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_8BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an signed 8-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_8BIT(d,clips) SOX_SAMPLE_TO_SIGNED(8,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_16BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 16-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_16BIT(d,clips) SOX_SAMPLE_TO_SIGNED(16,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_24BIT(d,clips) SOX_SAMPLE_TO_UNSIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to a signed 24-bit integer.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_SIGNED_24BIT(d,clips) SOX_SAMPLE_TO_SIGNED(24,d,clips)
+
+/**
+Client API:
+Converts SoX native sample to an unsigned 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_UNSIGNED_32BIT(d,clips) (sox_uint32_t)((d)^SOX_SAMPLE_NEG)
+
+/**
+Client API:
+Converts SoX native sample to a signed 32-bit integer.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_SIGNED_32BIT(d,clips) (sox_int32_t)(d)
+
+/**
+Client API:
+Converts SoX native sample to a 32-bit float.
+@param d Input sample to be converted.
+@param clips Variable to increment if input sample is too large.
+*/
+#define SOX_SAMPLE_TO_FLOAT_32BIT(d,clips) (LSX_USE_VAR(sox_macro_temp_double),sox_macro_temp_sample=(d),sox_macro_temp_sample>SOX_SAMPLE_MAX-128?++(clips),1:(((sox_macro_temp_sample+128)&~255)*(1./(SOX_SAMPLE_MAX+1.))))
+
+/**
+Client API:
+Converts SoX native sample to a 64-bit float.
+@param d Input sample to be converted.
+@param clips The parameter is not used.
+*/
+#define SOX_SAMPLE_TO_FLOAT_64BIT(d,clips) ((d)*(1./(SOX_SAMPLE_MAX+1.)))
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param samp Value (lvalue) to be clipped, updated as necessary.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+*/
+#define SOX_SAMPLE_CLIP_COUNT(samp, clips) \
+  do { \
+    if (samp > SOX_SAMPLE_MAX) \
+      { samp = SOX_SAMPLE_MAX; clips++; } \
+    else if (samp < SOX_SAMPLE_MIN) \
+      { samp = SOX_SAMPLE_MIN; clips++; } \
+  } while (0)
+
+/**
+Client API:
+Clips a value of a type that is larger then sox_sample_t (for example, int64)
+to sox_sample_t's limits and increment a counter if clipping occurs.
+@param d Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_ROUND_CLIP_COUNT(d, clips) \
+  ((d) < 0? (d) <= SOX_SAMPLE_MIN - 0.5? ++(clips), SOX_SAMPLE_MIN: (d) - 0.5 \
+        : (d) >= SOX_SAMPLE_MAX + 0.5? ++(clips), SOX_SAMPLE_MAX: (d) + 0.5)
+
+/**
+Client API:
+Clips a value to the limits of a signed integer of the specified width
+and increment a counter if clipping occurs.
+@param bits Width (in bits) of target integer type.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_INTEGER_CLIP_COUNT(bits,i,clips) ( \
+  (i) >(1 << ((bits)-1))- 1? ++(clips),(1 << ((bits)-1))- 1 : \
+  (i) <-1 << ((bits)-1)    ? ++(clips),-1 << ((bits)-1) : (i))
+
+/**
+Client API:
+Clips a value to the limits of a 16-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_16BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(16,i,clips)
+
+/**
+Client API:
+Clips a value to the limits of a 24-bit signed integer and increment a counter
+if clipping occurs.
+@param i Value (rvalue) to be clipped.
+@param clips Value (lvalue) that is incremented if clipping is needed.
+@returns Clipped value.
+*/
+#define SOX_24BIT_CLIP_COUNT(i,clips) SOX_INTEGER_CLIP_COUNT(24,i,clips)
+
+#define SOX_SIZE_MAX ((size_t)(-1)) /**< Client API: Maximum value of size_t. */
+
+#define SOX_UNSPEC 0                         /**< Client API: Members of sox_signalinfo_t are set to SOX_UNSPEC (= 0) if the actual value is not yet known. */
+#define SOX_UNKNOWN_LEN (sox_uint64_t)(-1) /**< Client API: sox_signalinfo_t.length is set to SOX_UNKNOWN_LEN (= -1) within the effects chain if the actual length is not known. Format handlers currently use SOX_UNSPEC instead. */
+#define SOX_IGNORE_LENGTH (sox_uint64_t)(-2) /**< Client API: sox_signalinfo_t.length is set to SOX_IGNORE_LENGTH (= -2) to indicate that a format handler should ignore length information in file headers. */
+
+#define SOX_DEFAULT_CHANNELS  2     /**< Client API: Default channel count is 2 (stereo). */
+#define SOX_DEFAULT_RATE      48000 /**< Client API: Default rate is 48000Hz. */
+#define SOX_DEFAULT_PRECISION 16    /**< Client API: Default precision is 16 bits per sample. */
+#define SOX_DEFAULT_ENCODING  SOX_ENCODING_SIGN2 /**< Client API: Default encoding is SIGN2 (linear 2's complement PCM). */
+
+#define SOX_LOOP_NONE          ((unsigned char)sox_loop_none)          /**< Client API: single-shot = 0 */
+#define SOX_LOOP_8             ((unsigned char)sox_loop_8)             /**< Client API: 8 loops = 32 */
+#define SOX_LOOP_SUSTAIN_DECAY ((unsigned char)sox_loop_sustain_decay) /**< Client API: AIFF style, one sustain & one decay loop = 64 */
+
+#define SOX_MAX_NLOOPS         8 /**< Client API: Maximum number of loops supported by sox_oob_t = 8. */
+
+#define SOX_FILE_NOSTDIO 0x0001 /**< Client API: Does not use stdio routines */
+#define SOX_FILE_DEVICE  0x0002 /**< Client API: File is an audio device */
+#define SOX_FILE_PHONY   0x0004 /**< Client API: Phony file/device (for example /dev/null) */
+#define SOX_FILE_REWIND  0x0008 /**< Client API: File should be rewound to write header */
+#define SOX_FILE_BIT_REV 0x0010 /**< Client API: Is file bit-reversed? */
+#define SOX_FILE_NIB_REV 0x0020 /**< Client API: Is file nibble-reversed? */
+#define SOX_FILE_ENDIAN  0x0040 /**< Client API: Is file format endian? */
+#define SOX_FILE_ENDBIG  0x0080 /**< Client API: For endian file format, is it big endian? */
+#define SOX_FILE_MONO    0x0100 /**< Client API: Do channel restrictions allow mono? */
+#define SOX_FILE_STEREO  0x0200 /**< Client API: Do channel restrictions allow stereo? */
+#define SOX_FILE_QUAD    0x0400 /**< Client API: Do channel restrictions allow quad? */
+
+#define SOX_FILE_CHANS   (SOX_FILE_MONO | SOX_FILE_STEREO | SOX_FILE_QUAD) /**< Client API: No channel restrictions */
+#define SOX_FILE_LIT_END (SOX_FILE_ENDIAN | 0)                             /**< Client API: File is little-endian */
+#define SOX_FILE_BIG_END (SOX_FILE_ENDIAN | SOX_FILE_ENDBIG)               /**< Client API: File is big-endian */
+
+#define SOX_EFF_CHAN     1           /**< Client API: Effect might alter the number of channels */
+#define SOX_EFF_RATE     2           /**< Client API: Effect might alter sample rate */
+#define SOX_EFF_PREC     4           /**< Client API: Effect does its own calculation of output sample precision (otherwise a default value is taken, depending on the presence of SOX_EFF_MODIFY) */
+#define SOX_EFF_LENGTH   8           /**< Client API: Effect might alter audio length (as measured in time units, not necessarily in samples) */
+#define SOX_EFF_MCHAN    16          /**< Client API: Effect handles multiple channels internally */
+#define SOX_EFF_NULL     32          /**< Client API: Effect does nothing (can be optimized out of chain) */
+#define SOX_EFF_DEPRECATED 64        /**< Client API: Effect will soon be removed from SoX */
+#define SOX_EFF_GAIN     128         /**< Client API: Effect does not support gain -r */
+#define SOX_EFF_MODIFY   256         /**< Client API: Effect does not modify sample values (but might remove or duplicate samples or insert zeros) */
+#define SOX_EFF_ALPHA    512         /**< Client API: Effect is experimental/incomplete */
+#define SOX_EFF_INTERNAL 1024        /**< Client API: Effect present in libSoX but not valid for use by SoX command-line tools */
+
+/**
+Client API:
+When used as the "whence" parameter of sox_seek, indicates that the specified
+offset is relative to the beginning of the file.
+*/
+#define SOX_SEEK_SET 0
+
+/*****************************************************************************
+Forward declarations:
+*****************************************************************************/
+
+typedef struct sox_format_t sox_format_t;
+typedef struct sox_effect_t sox_effect_t;
+typedef struct sox_effect_handler_t sox_effect_handler_t;
+typedef struct sox_format_handler_t sox_format_handler_t;
+
+/*****************************************************************************
+Function pointers:
+*****************************************************************************/
+
+/**
+Client API:
+Callback to write a message to an output device (console or log file),
+used by sox_globals_t.output_message_handler.
+*/
+typedef void (LSX_API * sox_output_message_handler_t)(
+    unsigned level,                       /* 1 = FAIL, 2 = WARN, 3 = INFO, 4 = DEBUG, 5 = DEBUG_MORE, 6 = DEBUG_MOST. */
+    LSX_PARAM_IN_Z char const * filename, /* Source code __FILENAME__ from which message originates. */
+    LSX_PARAM_IN_PRINTF char const * fmt, /* Message format string. */
+    LSX_PARAM_IN va_list ap               /* Message format parameters. */
+    );
+
+/**
+Client API:
+Callback to retrieve information about a format handler,
+used by sox_format_tab_t.fn.
+@returns format handler information.
+*/
+typedef sox_format_handler_t const * (LSX_API * sox_format_fn_t)(void);
+
+/**
+Client API:
+Callback to get information about an effect handler,
+used by the table returned from sox_get_effect_fns(void).
+@returns Pointer to information about an effect handler.
+*/
+typedef sox_effect_handler_t const * (LSX_API *sox_effect_fn_t)(void);
+
+/**
+Client API:
+Callback to initialize reader (decoder), used by
+sox_format_handler.startread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to read (decode) a block of samples,
+used by sox_format_handler.read.
+@returns number of samples read, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_read)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Callback to close reader (decoder),
+used by sox_format_handler.stopread.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopread)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to initialize writer (encoder),
+used by sox_format_handler.startwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_startwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to write (encode) a block of samples,
+used by sox_format_handler.write.
+@returns number of samples written, or 0 if unsuccessful.
+*/
+typedef size_t (LSX_API * sox_format_handler_write)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer to which samples are written. */
+    size_t len /**< Capacity of buf, measured in samples. */
+    );
+
+/**
+Client API:
+Callback to close writer (decoder),
+used by sox_format_handler.stopwrite.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_stopwrite)(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Callback to reposition reader,
+used by sox_format_handler.seek.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_format_handler_seek)(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset /**< Sample offset to which reader should be positioned. */
+    );
+
+/**
+Client API:
+Callback to parse command-line arguments (called once per effect),
+used by sox_effect_handler.getopts.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_getopts)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char *argv[] /**< Array of command-line arguments. */
+    );
+
+/**
+Client API:
+Callback to initialize effect (called once per flow),
+used by sox_effect_handler.start.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_start)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to process samples,
+used by sox_effect_handler.flow.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_flow)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_IN_COUNT(*isamp) sox_sample_t const * ibuf, /**< Buffer from which to read samples. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t * obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *isamp, /**< On entry, contains capacity of ibuf; on exit, contains number of samples consumed. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to finish getting output after input is complete,
+used by sox_effect_handler.drain.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_drain)(
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(*osamp,*osamp) sox_sample_t *obuf, /**< Buffer to which samples are written. */
+    LSX_PARAM_INOUT size_t *osamp /**< On entry, contains capacity of obuf; on exit, contains number of samples written. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per flow),
+used by sox_effect_handler.stop.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_stop)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback to shut down effect (called once per effect),
+used by sox_effect_handler.kill.
+@returns SOX_SUCCESS if successful.
+*/
+typedef int (LSX_API * sox_effect_handler_kill)(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect pointer. */
+    );
+
+/**
+Client API:
+Callback called while flow is running (called once per buffer),
+used by sox_flow_effects.callback.
+@returns SOX_SUCCESS to continue, other value to abort flow.
+*/
+typedef int (LSX_API * sox_flow_effects_callback)(
+    sox_bool all_done,
+    void * client_data
+    );
+
+/**
+Client API:
+Callback for enumerating the contents of a playlist,
+used by the sox_parse_playlist function.
+@returns SOX_SUCCESS if successful, any other value to abort playlist enumeration.
+*/
+typedef int (LSX_API * sox_playlist_callback_t)(
+    void * callback_data,
+    LSX_PARAM_IN_Z char const * filename
+    );
+
+/*****************************************************************************
+Structures:
+*****************************************************************************/
+
+/**
+Client API:
+Information about a build of libSoX, returned from the sox_version_info
+function.
+*/
+typedef struct sox_version_info_t {
+    size_t       size;         /**< structure size = sizeof(sox_version_info_t) */
+    sox_version_flags_t flags; /**< feature flags = popen | magic | threads | memopen */
+    sox_uint32_t version_code; /**< version number = 0x140400 */
+    char const * version;      /**< version string = sox_version(), for example, "14.4.0" */
+    char const * version_extra;/**< version extra info or null = "PACKAGE_EXTRA", for example, "beta" */
+    char const * time;         /**< build time = "__DATE__ __TIME__", for example, "Jan  7 2010 03:31:50" */
+    char const * distro;       /**< distro or null = "DISTRO", for example, "Debian" */
+    char const * compiler;     /**< compiler info or null, for example, "msvc 160040219" */
+    char const * arch;         /**< arch, for example, "1248 48 44 L OMP" */
+    /* new info should be added at the end for version backwards-compatibility. */
+} sox_version_info_t;
+
+/**
+Client API:
+Global parameters (for effects & formats), returned from the sox_get_globals
+function.
+*/
+typedef struct sox_globals_t {
+/* public: */
+  unsigned     verbosity; /**< messages are only written if globals.verbosity >= message.level */
+  sox_output_message_handler_t output_message_handler; /**< client-specified message output callback */
+  sox_bool     repeatable; /**< true to use pre-determined timestamps and PRNG seed */
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       bufsiz;
+
+  /**
+  Default size (in bytes) used by libSoX for blocks of input sample data.
+  Plugins should use similarly-sized buffers to get best performance.
+  */
+  size_t       input_bufsiz;
+
+  sox_int32_t  ranqd1; /**< Can be used to re-seed libSoX's PRNG */
+
+  char const * stdin_in_use_by;  /**< Private: tracks the name of the handler currently using stdin */
+  char const * stdout_in_use_by; /**< Private: tracks the name of the handler currently using stdout */
+  char const * subsystem;        /**< Private: tracks the name of the handler currently writing an output message */
+  char       * tmp_path;         /**< Private: client-configured path to use for temporary files */
+  sox_bool     use_magic;        /**< Private: true if client has requested use of 'magic' file-type detection */
+  sox_bool     use_threads;      /**< Private: true if client has requested parallel effects processing */
+} sox_globals_t;
+
+/**
+Client API:
+Signal parameters; members should be set to SOX_UNSPEC (= 0) if unknown.
+*/
+typedef struct sox_signalinfo_t {
+  sox_rate_t       rate;         /**< samples per second, 0 if unknown */
+  unsigned         channels;     /**< number of sound channels, 0 if unknown */
+  unsigned         precision;    /**< bits per sample, 0 if unknown */
+  sox_uint64_t     length;       /**< samples * chans in file, 0 if unknown, -1 if unspecified */
+  double           * mult;       /**< Effects headroom multiplier; may be null */
+} sox_signalinfo_t;
+
+/**
+Client API:
+Basic information about an encoding.
+*/
+typedef struct sox_encodings_info_t {
+  sox_encodings_flags_t flags; /**< lossy once (lossy1), lossy twice (lossy2), or lossless (none). */
+  char const * name;           /**< encoding name. */
+  char const * desc;           /**< encoding description. */
+} sox_encodings_info_t;
+
+/**
+Client API:
+Encoding parameters.
+*/
+typedef struct sox_encodinginfo_t {
+  sox_encoding_t encoding; /**< format of sample numbers */
+  unsigned bits_per_sample;/**< 0 if unknown or variable; uncompressed value if lossless; compressed value if lossy */
+  double compression;      /**< compression factor (where applicable) */
+
+  /**
+  Should bytes be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bytes;
+
+  /**
+  Should nibbles be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_nibbles;
+
+  /**
+  Should bits be reversed? If this is default during sox_open_read or
+  sox_open_write, libSoX will set them to either no or yes according to the
+  machine or format default.
+  */
+  sox_option_t reverse_bits;
+
+  /**
+  If set to true, the format should reverse its default endianness.
+  */
+  sox_bool opposite_endian;
+} sox_encodinginfo_t;
+
+/**
+Client API:
+Looping parameters (out-of-band data).
+*/
+typedef struct sox_loopinfo_t {
+  sox_uint64_t  start;  /**< first sample */
+  sox_uint64_t  length; /**< length */
+  unsigned      count;  /**< number of repeats, 0=forever */
+  unsigned char type;   /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* for valid values). */
+} sox_loopinfo_t;
+
+/**
+Client API:
+Instrument information.
+*/
+typedef struct sox_instrinfo_t{
+  signed char MIDInote;   /**< for unity pitch playback */
+  signed char MIDIlow;    /**< MIDI pitch-bend low range */
+  signed char MIDIhi;     /**< MIDI pitch-bend high range */
+  unsigned char loopmode; /**< 0=no, 1=forward, 2=forward/back (see sox_loop_* values) */
+  unsigned nloops;  /**< number of active loops (max SOX_MAX_NLOOPS). */
+} sox_instrinfo_t;
+
+/**
+Client API:
+File buffer info.  Holds info so that data can be read in blocks.
+*/
+typedef struct sox_fileinfo_t {
+  char          *buf;                 /**< Pointer to data buffer */
+  size_t        size;                 /**< Size of buffer in bytes */
+  size_t        count;                /**< Count read into buffer */
+  size_t        pos;                  /**< Position in buffer */
+} sox_fileinfo_t;
+
+/**
+Client API:
+Handler structure defined by each format.
+*/
+struct sox_format_handler_t {
+  unsigned     sox_lib_version_code;  /**< Checked on load; must be 1st in struct*/
+  char         const * description;   /**< short description of format */
+  char         const * const * names; /**< null-terminated array of filename extensions that are handled by this format */
+  unsigned int flags;                 /**< File flags (SOX_FILE_* values). */
+  sox_format_handler_startread startread; /**< called to initialize reader (decoder) */
+  sox_format_handler_read read;       /**< called to read (decode) a block of samples */
+  sox_format_handler_stopread stopread; /**< called to close reader (decoder); may be null if no closing necessary */
+  sox_format_handler_startwrite startwrite; /**< called to initialize writer (encoder) */
+  sox_format_handler_write write;     /**< called to write (encode) a block of samples */
+  sox_format_handler_stopwrite stopwrite; /**< called to close writer (decoder); may be null if no closing necessary */
+  sox_format_handler_seek seek;       /**< called to reposition reader; may be null if not supported */
+
+  /**
+  Array of values indicating the encodings and precisions supported for
+  writing (encoding). Precisions specified with default precision first.
+  Encoding, precision, precision, ..., 0, repeat. End with one more 0.
+  Example:
+  unsigned const * formats = {
+    SOX_ENCODING_SIGN2, 16, 24, 0, // Support SIGN2 at 16 and 24 bits, default to 16 bits.
+    SOX_ENCODING_UNSIGNED, 8, 0,   // Support UNSIGNED at 8 bits, default to 8 bits.
+    0 // No more supported encodings.
+  };
+  */
+  unsigned     const * write_formats;
+
+  /**
+  Array of sample rates (samples per second) supported for writing (encoding).
+  NULL if all (or almost all) rates are supported. End with 0.
+  */
+  sox_rate_t   const * write_rates;
+
+  /**
+  SoX will automatically allocate a buffer in which the handler can store data.
+  Specify the size of the buffer needed here. Usually this will be sizeof(your_struct).
+  The buffer will be allocated and zeroed before the call to startread/startwrite.
+  The buffer will be freed after the call to stopread/stopwrite.
+  The buffer will be provided via format.priv in each call to the handler.
+  */
+  size_t       priv_size;
+};
+
+/**
+Client API:
+Comments, instrument info, loop info (out-of-band data).
+*/
+typedef struct sox_oob_t{
+  /* Decoded: */
+  sox_comments_t   comments;              /**< Comment strings in id=value format. */
+  sox_instrinfo_t  instr;                 /**< Instrument specification */
+  sox_loopinfo_t   loops[SOX_MAX_NLOOPS]; /**< Looping specification */
+
+  /* TBD: Non-decoded chunks, etc: */
+} sox_oob_t;
+
+/**
+Client API:
+Data passed to/from the format handler
+*/
+struct sox_format_t {
+  char             * filename;      /**< File name */
+
+  /**
+  Signal specifications for reader (decoder) or writer (encoder):
+  sample rate, number of channels, precision, length, headroom multiplier.
+  Any info specified by the user is here on entry to startread or
+  startwrite. Info will be SOX_UNSPEC if the user provided no info.
+  At exit from startread, should be completely filled in, using
+  either data from the file's headers (if available) or whatever
+  the format is guessing/assuming (if header data is not available).
+  At exit from startwrite, should be completely filled in, using
+  either the data that was specified, or values chosen by the format
+  based on the format's defaults or capabilities.
+  */
+  sox_signalinfo_t signal;
+
+  /**
+  Encoding specifications for reader (decoder) or writer (encoder):
+  encoding (sample format), bits per sample, compression rate, endianness.
+  Should be filled in by startread. Values specified should be used
+  by startwrite when it is configuring the encoding parameters.
+  */
+  sox_encodinginfo_t encoding;
+
+  char             * filetype;      /**< Type of file, as determined by header inspection or libmagic. */
+  sox_oob_t        oob;             /**< comments, instrument info, loop info (out-of-band data) */
+  sox_bool         seekable;        /**< Can seek on this file */
+  char             mode;            /**< Read or write mode ('r' or 'w') */
+  sox_uint64_t     olength;         /**< Samples * chans written to file */
+  sox_uint64_t     clips;           /**< Incremented if clipping occurs */
+  int              sox_errno;       /**< Failure error code */
+  char             sox_errstr[256]; /**< Failure error text */
+  void             * fp;            /**< File stream pointer */
+  lsx_io_type      io_type;         /**< Stores whether this is a file, pipe or URL */
+  sox_uint64_t     tell_off;        /**< Current offset within file */
+  sox_uint64_t     data_start;      /**< Offset at which headers end and sound data begins (set by lsx_check_read_params) */
+  sox_format_handler_t handler;     /**< Format handler for this file */
+  void             * priv;          /**< Format handler's private data area */
+};
+
+/**
+Client API:
+Information about a loaded format handler, including the format name and a
+function pointer that can be invoked to get additional information about the
+format.
+*/
+typedef struct sox_format_tab_t {
+  char *name;         /**< Name of format handler */
+  sox_format_fn_t fn; /**< Function to call to get format handler's information */
+} sox_format_tab_t;
+
+/**
+Client API:
+Global parameters for effects.
+*/
+typedef struct sox_effects_globals_t {
+  sox_plot_t plot;         /**< To help the user choose effect & options */
+  sox_globals_t * global_info; /**< Pointer to associated SoX globals */
+} sox_effects_globals_t;
+
+/**
+Client API:
+Effect handler information.
+*/
+struct sox_effect_handler_t {
+  char const * name;  /**< Effect name */
+  char const * usage; /**< Short explanation of parameters accepted by effect */
+  unsigned int flags; /**< Combination of SOX_EFF_* flags */
+  sox_effect_handler_getopts getopts; /**< Called to parse command-line arguments (called once per effect). */
+  sox_effect_handler_start start;     /**< Called to initialize effect (called once per flow). */
+  sox_effect_handler_flow flow;       /**< Called to process samples. */
+  sox_effect_handler_drain drain;     /**< Called to finish getting output after input is complete. */
+  sox_effect_handler_stop stop;       /**< Called to shut down effect (called once per flow). */
+  sox_effect_handler_kill kill;       /**< Called to shut down effect (called once per effect). */
+  size_t       priv_size;             /**< Size of private data SoX should pre-allocate for effect */
+};
+
+/**
+Client API:
+Effect information.
+*/
+struct sox_effect_t {
+  sox_effects_globals_t    * global_info; /**< global effect parameters */
+  sox_signalinfo_t         in_signal;     /**< Information about the incoming data stream */
+  sox_signalinfo_t         out_signal;    /**< Information about the outgoing data stream */
+  sox_encodinginfo_t       const * in_encoding;  /**< Information about the incoming data encoding */
+  sox_encodinginfo_t       const * out_encoding; /**< Information about the outgoing data encoding */
+  sox_effect_handler_t     handler;   /**< The handler for this effect */
+  sox_sample_t             * obuf;    /**< output buffer */
+  size_t                   obeg;      /**< output buffer: start of valid data section */
+  size_t                   oend;      /**< output buffer: one past valid data section (oend-obeg is length of current content) */
+  size_t               imin;          /**< minimum input buffer content required for calling this effect's flow function; set via lsx_effect_set_imin() */
+  sox_uint64_t         clips;         /**< increment if clipping occurs */
+  size_t               flows;         /**< 1 if MCHAN, number of chans otherwise */
+  size_t               flow;          /**< flow number */
+  void                 * priv;        /**< Effect's private data area (each flow has a separate copy) */
+};
+
+/**
+Client API:
+Chain of effects to be applied to a stream.
+*/
+typedef struct sox_effects_chain_t {
+  sox_effect_t **effects;                  /**< Table of effects to be applied to a stream */
+  unsigned table_size;                     /**< Number of entries in effects table */
+  unsigned length;                         /**< Number of effects to be applied */
+  sox_sample_t **ibufc;                    /**< Channel interleave buffer */
+  sox_sample_t **obufc;                    /**< Channel interleave buffer */
+  sox_effects_globals_t global_info;       /**< Copy of global effects settings */
+  sox_encodinginfo_t const * in_enc;       /**< Input encoding */
+  sox_encodinginfo_t const * out_enc;      /**< Output encoding */
+} sox_effects_chain_t;
+
+/*****************************************************************************
+Functions:
+*****************************************************************************/
+
+/**
+Client API:
+Returns version number string of libSoX, for example, "14.4.0".
+@returns The version number string of libSoX, for example, "14.4.0".
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_version(void);
+
+/**
+Client API:
+Returns information about this build of libsox.
+@returns Pointer to a version information structure.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_version_info_t const *
+LSX_API
+sox_version_info(void);
+
+/**
+Client API:
+Returns a pointer to the structure with libSoX's global settings.
+@returns a pointer to the structure with libSoX's global settings.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_globals_t *
+LSX_API
+sox_get_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns the structure with libSoX's global settings
+as an lvalue.
+*/
+#define sox_globals (*sox_get_globals())
+
+/**
+Client API:
+Returns a pointer to the list of available encodings.
+End of list indicated by name == NULL.
+@returns pointer to the list of available encodings.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_encodings_info_t const *
+LSX_API
+sox_get_encodings_info(void);
+
+/**
+Client API:
+Deprecated macro that returns the list of available encodings.
+End of list indicated by name == NULL.
+*/
+#define sox_encodings_info (sox_get_encodings_info())
+
+/**
+Client API:
+Fills in an encodinginfo with default values.
+*/
+void
+LSX_API
+sox_init_encodinginfo(
+    LSX_PARAM_OUT sox_encodinginfo_t * e /**< Pointer to uninitialized encoding info structure to be initialized. */
+    );
+
+/**
+Client API:
+Given an encoding (for example, SIGN2) and the encoded bits_per_sample (for
+example, 16), returns the number of useful bits per sample in the decoded data
+(for example, 16), or returns 0 to indicate that the value returned by the
+format handler should be used instead of a pre-determined precision.
+@returns the number of useful bits per sample in the decoded data (for example
+16), or returns 0 to indicate that the value returned by the format handler
+should be used instead of a pre-determined precision.
+*/
+LSX_RETURN_PURE
+unsigned
+LSX_API
+sox_precision(
+    sox_encoding_t encoding,   /**< Encoding for which to lookup precision information. */
+    unsigned bits_per_sample   /**< The number of encoded bits per sample. */
+    );
+
+/**
+Client API:
+Returns the number of items in the metadata block.
+@returns the number of items in the metadata block.
+*/
+size_t
+LSX_API
+sox_num_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+Adds an "id=value" item to the metadata block.
+*/
+void
+LSX_API
+sox_append_comment(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * item /**< Item to be added in "id=value" format. */
+    );
+
+/**
+Client API:
+Adds a newline-delimited list of "id=value" items to the metadata block.
+*/
+void
+LSX_API
+sox_append_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NOTNULL sox_comments_t * comments, /**< Metadata block. */
+    LSX_PARAM_IN_Z char const * items /**< Newline-separated list of items to be added, for example "id1=value1\\nid2=value2". */
+    );
+
+/**
+Client API:
+Duplicates the metadata block.
+@returns the copied metadata block.
+*/
+LSX_RETURN_OPT
+sox_comments_t
+LSX_API
+sox_copy_comments(
+    LSX_PARAM_IN_OPT sox_comments_t comments /**< Metadata block to copy. */
+    );
+
+/**
+Client API:
+Frees the metadata block.
+*/
+void
+LSX_API
+sox_delete_comments(
+    LSX_PARAM_DEREF_PRE_MAYBENULL LSX_PARAM_DEREF_POST_NULL sox_comments_t * comments /**< Metadata block. */
+    );
+
+/**
+Client API:
+If "id=value" is found, return value, else return null.
+@returns value, or null if value not found.
+*/
+LSX_RETURN_OPT
+char const *
+LSX_API
+sox_find_comment(
+    LSX_PARAM_IN_OPT sox_comments_t comments, /**< Metadata block in which to search. */
+    LSX_PARAM_IN_Z char const * id /**< Id for which to search */
+    );
+
+/**
+Client API:
+Find and load format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_format_init(void);
+
+/**
+Client API:
+Unload format handler plugins.
+*/
+void
+LSX_API
+sox_format_quit(void);
+
+/**
+Client API:
+Initialize effects library.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_init(void);
+
+/**
+Client API:
+Close effects library and unload format handler plugins.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_quit(void);
+
+/**
+Client API:
+Returns the table of format handler names and functions.
+@returns the table of format handler names and functions.
+*/
+LSX_RETURN_ARRAY LSX_RETURN_PURE
+sox_format_tab_t const *
+LSX_API
+sox_get_format_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns the table of format handler names and functions.
+*/
+#define sox_format_fns (sox_get_format_fns())
+
+/**
+Client API:
+Opens a decoding session for a file. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_read(
+    LSX_PARAM_IN_Z   char               const * path,      /**< Path to file to be opened (required). */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,    /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,  /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype   /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Opens a decoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The handle for the new session, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_read(
+    LSX_PARAM_IN_BYTECOUNT(buffer_size) void  * buffer,     /**< Pointer to audio data buffer (required). */
+    size_t                                      buffer_size,/**< Number of bytes to read from audio data buffer. */
+    LSX_PARAM_IN_OPT sox_signalinfo_t   const * signal,     /**< Information already known about audio stream, or NULL if none. */
+    LSX_PARAM_IN_OPT sox_encodinginfo_t const * encoding,   /**< Information already known about sample encoding, or NULL if none. */
+    LSX_PARAM_IN_OPT_Z char             const * filetype    /**< Previously-determined file type, or NULL to auto-detect. */
+    );
+
+/**
+Client API:
+Returns true if the format handler for the specified file type supports the specified encoding.
+@returns true if the format handler for the specified file type supports the specified encoding.
+*/
+sox_bool
+LSX_API
+sox_format_supports_encoding(
+    LSX_PARAM_IN_OPT_Z char               const * path,       /**< Path to file to be examined (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,   /**< Previously-determined file type, or NULL to use extension from path. */
+    LSX_PARAM_IN       sox_encodinginfo_t const * encoding    /**< Encoding for which format handler should be queried. */
+    );
+
+/**
+Client API:
+Gets the format handler for a specified file type.
+@returns The found format handler, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_write_handler(
+    LSX_PARAM_IN_OPT_Z char               const * path,         /**< Path to file (required if filetype is NULL). */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,     /**< Filetype for which handler is needed, or NULL to use extension from path. */
+    LSX_PARAM_OUT_OPT  char               const * * filetype1   /**< Receives the filetype that was detected. Pass NULL if not needed. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a file. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_write(
+    LSX_PARAM_IN_Z     char               const * path,     /**< Path to file to be written (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,   /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding, /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype, /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob,      /**< Out-of-band data to add to file, or NULL if none. */
+    LSX_PARAM_IN_OPT   sox_bool           (LSX_API * overwrite_permitted)(LSX_PARAM_IN_Z char const * filename) /**< Called if file exists to determine whether overwrite is ok. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memory buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_mem_write(
+    LSX_PARAM_OUT_BYTECAP(buffer_size) void                     * buffer,      /**< Pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_IN                       size_t                     buffer_size, /**< Maximum number of bytes to write to audio data buffer. */
+    LSX_PARAM_IN                       sox_signalinfo_t   const * signal,      /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT                   sox_encodinginfo_t const * encoding,    /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z                 char               const * filetype,    /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT                   sox_oob_t          const * oob          /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Opens an encoding session for a memstream buffer. Returned handle must be closed with sox_close().
+@returns The new session handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_format_t *
+LSX_API
+sox_open_memstream_write(
+    LSX_PARAM_OUT      char                     * * buffer_ptr,    /**< Receives pointer to audio data buffer that receives data (required). */
+    LSX_PARAM_OUT      size_t                   * buffer_size_ptr, /**< Receives size of data written to audio data buffer (required). */
+    LSX_PARAM_IN       sox_signalinfo_t   const * signal,          /**< Information about desired audio stream (required). */
+    LSX_PARAM_IN_OPT   sox_encodinginfo_t const * encoding,        /**< Information about desired sample encoding, or NULL to use defaults. */
+    LSX_PARAM_IN_OPT_Z char               const * filetype,        /**< Previously-determined file type, or NULL to auto-detect. */
+    LSX_PARAM_IN_OPT   sox_oob_t          const * oob              /**< Out-of-band data to add to file, or NULL if none. */
+    );
+
+/**
+Client API:
+Reads samples from a decoding session into a sample buffer.
+@returns Number of samples decoded, or 0 for EOF.
+*/
+size_t
+LSX_API
+sox_read(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_OUT_CAP_POST_COUNT(len,return) sox_sample_t *buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Writes samples to an encoding session from a sample buffer.
+@returns Number of samples encoded.
+*/
+size_t
+LSX_API
+sox_write(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    LSX_PARAM_IN_COUNT(len) sox_sample_t const * buf, /**< Buffer from which to read samples. */
+    size_t len /**< Number of samples available in buf. */
+    );
+
+/**
+Client API:
+Closes an encoding or decoding session.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_close(
+    LSX_PARAM_INOUT sox_format_t * ft /**< Format pointer. */
+    );
+
+/**
+Client API:
+Sets the location at which next samples will be decoded. Returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_seek(
+    LSX_PARAM_INOUT sox_format_t * ft, /**< Format pointer. */
+    sox_uint64_t offset, /**< Sample offset at which to position reader. */
+    int whence /**< Set to SOX_SEEK_SET. */
+    );
+
+/**
+Client API:
+Finds a format handler by name.
+@returns Format handler data, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_format_handler_t const *
+LSX_API
+sox_find_format(
+    LSX_PARAM_IN_Z char const * name, /**< Name of format handler to find. */
+    sox_bool ignore_devices /**< Set to true to ignore device names. */
+    );
+
+/**
+Client API:
+Returns global parameters for effects
+@returns global parameters for effects.
+*/
+LSX_RETURN_VALID LSX_RETURN_PURE
+sox_effects_globals_t *
+LSX_API
+sox_get_effects_globals(void);
+
+/**
+Client API:
+Deprecated macro that returns global parameters for effects.
+*/
+#define sox_effects_globals (*sox_get_effects_globals())
+
+/**
+Client API:
+Finds the effect handler with the given name.
+@returns Effect pointer, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+sox_effect_handler_t const *
+LSX_API
+sox_find_effect(
+    LSX_PARAM_IN_Z char const * name /**< Name of effect to find. */
+    );
+
+/**
+Client API:
+Creates an effect using the given handler.
+@returns The new effect, or null if not found.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_create_effect(
+    LSX_PARAM_IN sox_effect_handler_t const * eh /**< Handler to use for effect. */
+    );
+
+/**
+Client API:
+Applies the command-line options to the effect.
+@returns the number of arguments consumed.
+*/
+int
+LSX_API
+sox_effect_options(
+    LSX_PARAM_IN sox_effect_t *effp, /**< Effect pointer on which to set options. */
+    int argc, /**< Number of arguments in argv. */
+    LSX_PARAM_IN_COUNT(argc) char * const argv[] /**< Array of command-line options. */
+    );
+
+/**
+Client API:
+Returns an array containing the known effect handlers.
+@returns An array containing the known effect handlers.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+sox_effect_fn_t const *
+LSX_API
+sox_get_effect_fns(void);
+
+/**
+Client API:
+Deprecated macro that returns an array containing the known effect handlers.
+*/
+#define sox_effect_fns (sox_get_effect_fns())
+
+/**
+Client API:
+Initializes an effects chain. Returned handle must be closed with sox_delete_effects_chain().
+@returns Handle, or null on failure.
+*/
+LSX_RETURN_OPT
+sox_effects_chain_t *
+LSX_API
+sox_create_effects_chain(
+    LSX_PARAM_IN sox_encodinginfo_t const * in_enc, /**< Input encoding. */
+    LSX_PARAM_IN sox_encodinginfo_t const * out_enc /**< Output encoding. */
+    );
+
+/**
+Client API:
+Closes an effects chain.
+*/
+void
+LSX_API
+sox_delete_effects_chain(
+    LSX_PARAM_INOUT sox_effects_chain_t *ecp /**< Effects chain pointer. */
+    );
+
+/**
+Client API:
+Adds an effect to the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_add_effect(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added . */
+    LSX_PARAM_INOUT sox_effect_t * effp, /**< Effect to be added. */
+    LSX_PARAM_INOUT sox_signalinfo_t * in, /**< Input format. */
+    LSX_PARAM_IN    sox_signalinfo_t const * out /**< Output format. */
+    );
+
+/**
+Client API:
+Runs the effects chain, returns SOX_SUCCESS if successful.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_flow_effects(
+    LSX_PARAM_INOUT  sox_effects_chain_t * chain, /**< Effects chain to run. */
+    LSX_PARAM_IN_OPT sox_flow_effects_callback callback, /**< Callback for monitoring flow progress. */
+    LSX_PARAM_IN_OPT void * client_data /**< Data to pass into callback. */
+    );
+
+/**
+Client API:
+Gets the number of clips that occurred while running an effects chain.
+@returns the number of clips that occurred while running an effects chain.
+*/
+sox_uint64_t
+LSX_API
+sox_effects_clips(
+    LSX_PARAM_IN sox_effects_chain_t * chain /**< Effects chain from which to read clip information. */
+    );
+
+/**
+Client API:
+Shuts down an effect (calls stop on each of its flows).
+@returns the number of clips from all flows.
+*/
+sox_uint64_t
+LSX_API
+sox_stop_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t * effp /**< Effect to stop. */
+    );
+
+/**
+Client API:
+Adds an already-initialized effect to the end of the chain.
+*/
+void
+LSX_API
+sox_push_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t * chain, /**< Effects chain to which effect should be added. */
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Effect to be added. */
+    );
+
+/**
+Client API:
+Removes and returns an effect from the end of the chain.
+@returns the removed effect, or null if no effects.
+*/
+LSX_RETURN_OPT
+sox_effect_t *
+LSX_API
+sox_pop_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove an effect. */
+    );
+
+/**
+Client API:
+Shut down and delete an effect.
+*/
+void
+LSX_API
+sox_delete_effect(
+    LSX_PARAM_INOUT_COUNT(effp->flows) sox_effect_t *effp /**< Effect to be deleted. */
+    );
+
+/**
+Client API:
+Shut down and delete the last effect in the chain.
+*/
+void
+LSX_API
+sox_delete_effect_last(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to remove the last effect. */
+    );
+
+/**
+Client API:
+Shut down and delete all effects in the chain.
+*/
+void
+LSX_API
+sox_delete_effects(
+    LSX_PARAM_INOUT sox_effects_chain_t *chain /**< Effects chain from which to delete effects. */
+    );
+
+/**
+Client API:
+Gets the sample offset of the start of the trim, useful for efficiently
+skipping the part that will be trimmed anyway (get trim start, seek, then
+clear trim start).
+@returns the sample offset of the start of the trim.
+*/
+sox_uint64_t
+LSX_API
+sox_trim_get_start(
+    LSX_PARAM_IN sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Clears the start of the trim to 0.
+*/
+void
+LSX_API
+sox_trim_clear_start(
+    LSX_PARAM_INOUT sox_effect_t * effp /**< Trim effect. */
+    );
+
+/**
+Client API:
+Returns true if the specified file is a known playlist file type.
+@returns true if the specified file is a known playlist file type.
+*/
+sox_bool
+LSX_API
+sox_is_playlist(
+    LSX_PARAM_IN_Z char const * filename /**< Name of file to examine. */
+    );
+
+/**
+Client API:
+Parses the specified playlist file.
+@returns SOX_SUCCESS if successful.
+*/
+int
+LSX_API
+sox_parse_playlist(
+    LSX_PARAM_IN sox_playlist_callback_t callback, /**< Callback to call for each item in the playlist. */
+    void * p, /**< Data to pass to callback. */
+    LSX_PARAM_IN char const * const listname /**< Filename of playlist file. */
+    );
+
+/**
+Client API:
+Converts a SoX error code into an error string.
+@returns error string corresponding to the specified error code,
+or a generic message if the error code is not recognized.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+sox_strerror(
+    int sox_errno /**< Error code to look up. */
+    );
+
+/**
+Client API:
+Gets the basename of the specified file; for example, the basename of
+"/a/b/c.d" would be "c".
+@returns the number of characters written to base_buffer, excluding the null,
+or 0 on failure.
+*/
+size_t
+LSX_API
+sox_basename(
+    LSX_PARAM_OUT_Z_CAP_POST_COUNT(base_buffer_len,return) char * base_buffer, /**< Buffer into which basename should be written. */
+    size_t base_buffer_len, /**< Size of base_buffer, in bytes. */
+    LSX_PARAM_IN_Z char const * filename /**< Filename from which to extract basename. */
+    );
+
+/*****************************************************************************
+Internal API:
+WARNING - The items in this section are subject to instability. They only
+exist in the public header because sox (the application) currently uses them.
+These may be changed or removed in future versions of libSoX.
+*****************************************************************************/
+
+/**
+Plugins API:
+Print a fatal error in libSoX.
+*/
+void
+LSX_API
+lsx_fail_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a warning in libSoX.
+*/
+void
+LSX_API
+lsx_warn_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print an informational message in libSoX.
+*/
+void
+LSX_API
+lsx_report_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Print a debug message in libSoX.
+*/
+void
+LSX_API
+lsx_debug_impl(
+    LSX_PARAM_IN_PRINTF char const * fmt, /**< printf-style format string. */
+    ...)
+    LSX_PRINTF12;
+
+/**
+Plugins API:
+Report a fatal error in libSoX; printf-style arguments must follow.
+*/
+#define lsx_fail       sox_get_globals()->subsystem=__FILE__,lsx_fail_impl
+
+/**
+Plugins API:
+Report a warning in libSoX; printf-style arguments must follow.
+*/
+#define lsx_warn       sox_get_globals()->subsystem=__FILE__,lsx_warn_impl
+
+/**
+Plugins API:
+Report an informational message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_report     sox_get_globals()->subsystem=__FILE__,lsx_report_impl
+
+/**
+Plugins API:
+Report a debug message in libSoX; printf-style arguments must follow.
+*/
+#define lsx_debug      sox_get_globals()->subsystem=__FILE__,lsx_debug_impl
+
+/**
+Plugins API:
+String name and integer values for enumerated types (type metadata), for use
+with LSX_ENUM_ITEM, lsx_find_enum_text, and lsx_find_enum_value.
+*/
+typedef struct lsx_enum_item {
+    char const *text; /**< String name of enumeration. */
+    unsigned value;   /**< Integer value of enumeration. */
+} lsx_enum_item;
+
+/**
+Plugins API:
+Declares a static instance of an lsx_enum_item structure in format
+{ "item", prefixitem }, for use in declaring lsx_enum_item[] arrays.
+@param prefix The prefix to prepend to the item in the enumeration symbolic name.
+@param item   The user-visible text name of the item (must also be a valid C symbol name).
+*/
+#define LSX_ENUM_ITEM(prefix, item) {#item, prefix##item},
+
+/**
+Plugins API:
+Flags for use with lsx_find_enum_item.
+*/
+enum
+{
+    lsx_find_enum_item_none = 0, /**< Default parameters (case-insensitive). */
+    lsx_find_enum_item_case_sensitive = 1 /**< Enable case-sensitive search. */
+};
+
+/**
+Plugins API:
+Looks up an enumeration by name in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_text(
+    LSX_PARAM_IN_Z char const * text, /**< Name of enumeration to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items, /**< Array of items to search, with text == NULL for last item. */
+    int flags /**< Search flags: 0 (case-insensitive) or lsx_find_enum_item_case_sensitive (case-sensitive). */
+    );
+
+/**
+Plugins API:
+Looks up an enumeration by value in an array of lsx_enum_items.
+@returns the corresponding item, or null if not found.
+*/
+LSX_RETURN_OPT LSX_RETURN_PURE
+lsx_enum_item const *
+LSX_API
+lsx_find_enum_value(
+    unsigned value, /**< Enumeration value to find. */
+    LSX_PARAM_IN lsx_enum_item const * lsx_enum_items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Looks up a command-line argument in a set of enumeration names, showing an
+error message if the argument is not found in the set of names.
+@returns The enumeration value corresponding to the matching enumeration, or
+INT_MAX if the argument does not match any enumeration name.
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_enum_option(
+    int c, /**< Option character to which arg is associated, for example with -a, c would be 'a'. */
+    LSX_PARAM_IN_Z char const * arg, /**< Argument to find in enumeration list. */
+    LSX_PARAM_IN lsx_enum_item const * items /**< Array of items to search, with text == NULL for last item. */
+    );
+
+/**
+Plugins API:
+Determines whether the specified string ends with the specified suffix (case-sensitive).
+@returns true if the specified string ends with the specified suffix.
+*/
+LSX_RETURN_PURE
+sox_bool
+LSX_API
+lsx_strends(
+    LSX_PARAM_IN_Z char const * str, /**< String to search. */
+    LSX_PARAM_IN_Z char const * end  /**< Suffix to search for. */
+    );
+
+/**
+Plugins API:
+Finds the file extension for a filename.
+@returns the file extension, not including the '.', or null if filename does
+not have an extension.
+*/
+LSX_RETURN_VALID_Z LSX_RETURN_PURE
+char const *
+LSX_API
+lsx_find_file_extension(
+    LSX_PARAM_IN_Z char const * pathname /**< Filename to search for extension. */
+    );
+
+/**
+Plugins API:
+Formats the specified number with up to three significant figures and adds a
+metric suffix in place of the exponent, such as 1.23G.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3(
+    double number /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Formats the specified number as a percentage, showing up to three significant
+figures.
+@returns A static buffer with the formatted number, valid until the next time
+this function is called (note: not thread safe).
+*/
+LSX_RETURN_VALID_Z
+char const *
+LSX_API
+lsx_sigfigs3p(
+    double percentage /**< Number to be formatted. */
+    );
+
+/**
+Plugins API:
+Allocates, deallocates, or resizes; like C's realloc, except that this version
+terminates the running application if unable to allocate the requested memory.
+@returns New buffer, or null if buffer was freed.
+*/
+LSX_RETURN_OPT
+void *
+LSX_API
+lsx_realloc(
+    LSX_PARAM_IN_OPT void *ptr, /**< Pointer to be freed or resized, or null if allocating a new buffer. */
+    size_t newsize /**< New size for buffer, or 0 to free the buffer. */
+    );
+
+/**
+Plugins API:
+Like strcmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strcasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2  /**< Second string. */
+    );
+
+
+/**
+Plugins API:
+Like strncmp, except that the characters are compared without regard to case.
+@returns 0 (s1 == s2), negative (s1 < s2), or positive (s1 > s2).
+*/
+LSX_RETURN_PURE
+int
+LSX_API
+lsx_strncasecmp(
+    LSX_PARAM_IN_Z char const * s1, /**< First string. */
+    LSX_PARAM_IN_Z char const * s2, /**< Second string. */
+    size_t n /**< Maximum number of characters to examine. */
+    );
+
+/**
+Plugins API:
+Is option argument unsupported, required, or optional.
+*/
+typedef enum lsx_option_arg_t {
+    lsx_option_arg_none, /**< Option does not have an argument. */
+    lsx_option_arg_required, /**< Option requires an argument. */
+    lsx_option_arg_optional /**< Option can optionally be followed by an argument. */
+} lsx_option_arg_t;
+
+/**
+Plugins API:
+lsx_getopt_init options.
+*/
+typedef enum lsx_getopt_flags_t {
+    lsx_getopt_flag_none = 0,      /**< no flags (no output, not long-only) */
+    lsx_getopt_flag_opterr = 1,    /**< if set, invalid options trigger lsx_warn output */
+    lsx_getopt_flag_longonly = 2   /**< if set, recognize -option as a long option */
+} lsx_getopt_flags_t;
+
+/**
+Plugins API:
+lsx_getopt long option descriptor.
+*/
+typedef struct lsx_option_t {
+    char const *     name;    /**< Name of the long option. */
+    lsx_option_arg_t has_arg; /**< Whether the long option supports an argument and, if so, whether the argument is required or optional. */
+    int *            flag;    /**< Flag to set if argument is present. */
+    int              val;     /**< Value to put in flag if argument is present. */
+} lsx_option_t;
+
+/**
+Plugins API:
+lsx_getopt session information (initialization data and state).
+*/
+typedef struct lsx_getopt_t {
+    int                  argc;     /**< IN    argc:      Number of arguments in argv */
+    char * const *       argv;     /**< IN    argv:      Array of arguments */
+    char const *         shortopts;/**< IN    shortopts: Short option characters */
+    lsx_option_t const * longopts; /**< IN    longopts:  Array of long option descriptors */
+    lsx_getopt_flags_t   flags;    /**< IN    flags:     Flags for longonly and opterr */
+    char const *         curpos;   /**< INOUT curpos:    Maintains state between calls to lsx_getopt */
+    int                  ind;      /**< INOUT optind:    Maintains the index of next element to be processed */
+    int                  opt;      /**< OUT   optopt:    Receives the option character that caused error */
+    char const *         arg;      /**< OUT   optarg:    Receives the value of the option's argument */
+    int                  lngind;   /**< OUT   lngind:    Receives the index of the matched long option or -1 if not a long option */
+} lsx_getopt_t;
+
+/**
+Plugins API:
+Initializes an lsx_getopt_t structure for use with lsx_getopt.
+*/
+void
+LSX_API
+lsx_getopt_init(
+    LSX_PARAM_IN             int argc,                      /**< Number of arguments in argv */
+    LSX_PARAM_IN_COUNT(argc) char * const * argv,           /**< Array of arguments */
+    LSX_PARAM_IN_Z           char const * shortopts,        /**< Short options, for example ":abc:def::ghi" (+/- not supported) */
+    LSX_PARAM_IN_OPT         lsx_option_t const * longopts, /**< Array of long option descriptors */
+    LSX_PARAM_IN             lsx_getopt_flags_t flags,      /**< Flags for longonly and opterr */
+    LSX_PARAM_IN             int first,                     /**< First argv to check (usually 1) */
+    LSX_PARAM_OUT            lsx_getopt_t * state           /**< State object to be initialized */
+    );
+
+/**
+Plugins API:
+Gets the next option. Options are parameters that start with "-" or "--".
+If no more options, returns -1. If unrecognized short option, returns '?'.
+If a recognized short option is missing a required argument,
+return (shortopts[0]==':' ? ':' : '?'). If successfully recognized short
+option, return the recognized character. If successfully recognized long
+option, returns (option.flag ? 0 : option.val).
+Note: lsx_getopt does not permute the non-option arguments.
+@returns option character (short), val or 0 (long), or -1 (no more).
+*/
+int
+LSX_API
+lsx_getopt(
+    LSX_PARAM_INOUT lsx_getopt_t * state /**< The getopt state pointer. */
+    );
+
+/* WARNING END */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* SOX_H */
diff --git a/freedv/tags/1.2.2/src/sox/sox_i.h b/freedv/tags/1.2.2/src/sox/sox_i.h
new file mode 100644 (file)
index 0000000..9d53326
--- /dev/null
@@ -0,0 +1,417 @@
+/* libSoX Internal header
+ *
+ *   This file is meant for libSoX internal use only
+ *
+ * Copyright 2001-2008 Chris Bagwell and SoX Contributors
+ *
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained.
+ * Chris Bagwell And SoX Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+#ifndef SOX_I_H
+#define SOX_I_H
+
+#include "soxomp.h"  /* Note: soxomp.h includes soxconfig.h */
+#include "sox.h"
+
+#define __FREEDV__
+
+#if defined HAVE_FMEMOPEN
+#define _GNU_SOURCE
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#if defined(LSX_EFF_ALIAS)
+#undef lsx_debug
+#undef lsx_fail
+#undef lsx_report
+#undef lsx_warn
+#define lsx_debug sox_globals.subsystem=effp->handler.name,lsx_debug_impl
+#define lsx_fail sox_globals.subsystem=effp->handler.name,lsx_fail_impl
+#define lsx_report sox_globals.subsystem=effp->handler.name,lsx_report_impl
+#define lsx_warn sox_globals.subsystem=effp->handler.name,lsx_warn_impl
+#endif
+
+#define RANQD1 ranqd1(sox_globals.ranqd1)
+#define DRANQD1 dranqd1(sox_globals.ranqd1)
+
+typedef enum {SOX_SHORT, SOX_INT, SOX_FLOAT, SOX_DOUBLE} sox_data_t;
+typedef enum {SOX_WAVE_SINE, SOX_WAVE_TRIANGLE} lsx_wave_t;
+lsx_enum_item const * lsx_get_wave_enum(void);
+
+/* Define fseeko and ftello for platforms lacking them */
+#ifndef HAVE_FSEEKO
+#define fseeko fseek
+#define ftello ftell
+#endif
+
+#ifdef _FILE_OFFSET_BITS
+assert_static(sizeof(off_t) == _FILE_OFFSET_BITS >> 3, OFF_T_BUILD_PROBLEM);
+#endif
+
+FILE * lsx_tmpfile(void);
+
+void lsx_debug_more_impl(char const * fmt, ...) LSX_PRINTF12;
+void lsx_debug_most_impl(char const * fmt, ...) LSX_PRINTF12;
+
+#define lsx_debug_more sox_get_globals()->subsystem=__FILE__,lsx_debug_more_impl
+#define lsx_debug_most sox_get_globals()->subsystem=__FILE__,lsx_debug_most_impl
+
+/* Digitise one cycle of a wave and store it as
+ * a table of samples of a specified data-type.
+ */
+void lsx_generate_wave_table(
+    lsx_wave_t wave_type,
+    sox_data_t data_type,
+    void * table,       /* Really of type indicated by data_type. */
+    size_t table_size,  /* Number of points on the x-axis. */
+    double min,         /* Minimum value on the y-axis. (e.g. -1) */
+    double max,         /* Maximum value on the y-axis. (e.g. +1) */
+    double phase);      /* Phase at 1st point; 0..2pi. (e.g. pi/2 for cosine) */
+char const * lsx_parsesamples(sox_rate_t rate, const char *str, uint64_t *samples, int def);
+int lsx_parse_note(char const * text, char * * end_ptr);
+double lsx_parse_frequency_k(char const * text, char * * end_ptr, int key);
+#define lsx_parse_frequency(a, b) lsx_parse_frequency_k(a, b, INT_MAX)
+FILE * lsx_open_input_file(sox_effect_t * effp, char const * filename);
+
+void lsx_prepare_spline3(double const * x, double const * y, int n,
+    double start_1d, double end_1d, double * y_2d);
+double lsx_spline3(double const * x, double const * y, double const * y_2d,
+    int n, double x1);
+
+double lsx_bessel_I_0(double x);
+int lsx_set_dft_length(int num_taps);
+void init_fft_cache(void);
+void clear_fft_cache(void);
+void lsx_safe_rdft(int len, int type, double * d);
+void lsx_safe_cdft(int len, int type, double * d);
+void lsx_power_spectrum(int n, double const * in, double * out);
+void lsx_power_spectrum_f(int n, float const * in, float * out);
+void lsx_apply_hann_f(float h[], const int num_points);
+void lsx_apply_hann(double h[], const int num_points);
+void lsx_apply_hamming(double h[], const int num_points);
+void lsx_apply_bartlett(double h[], const int num_points);
+void lsx_apply_blackman(double h[], const int num_points, double alpha);
+void lsx_apply_blackman_nutall(double h[], const int num_points);
+double lsx_kaiser_beta(double att);
+void lsx_apply_kaiser(double h[], const int num_points, double beta);
+double * lsx_make_lpf(int num_taps, double Fc, double beta, double scale, sox_bool dc_norm);
+int lsx_lpf_num_taps(double att, double tr_bw, int k);
+double * lsx_design_lpf(
+    double Fp,      /* End of pass-band; ~= 0.01dB point */
+    double Fc,      /* Start of stop-band */
+    double Fn,      /* Nyquist freq; e.g. 0.5, 1, PI */
+    sox_bool allow_aliasing,
+    double att,     /* Stop-band attenuation in dB */
+    int * num_taps, /* (Single phase.)  0: value will be estimated */
+    int k);         /* Number of phases; 0 for single-phase */
+void lsx_fir_to_phase(double * * h, int * len,
+    int * post_len, double phase0);
+#define LSX_TO_6dB .5869
+#define LSX_TO_3dB ((2/3.) * (.5 + LSX_TO_6dB))
+#define LSX_MAX_TBW0 36.
+#define LSX_MAX_TBW0A (LSX_MAX_TBW0 / (1 + LSX_TO_3dB))
+#define LSX_MAX_TBW3 floor(LSX_MAX_TBW0 * LSX_TO_3dB)
+#define LSX_MAX_TBW3A floor(LSX_MAX_TBW0A * LSX_TO_3dB)
+void lsx_plot_fir(double * h, int num_points, sox_rate_t rate, sox_plot_t type, char const * title, double y1, double y2);
+
+#ifdef HAVE_BYTESWAP_H
+#include <byteswap.h>
+#define lsx_swapw(x) bswap_16(x)
+#define lsx_swapdw(x) bswap_32(x)
+#elif defined(_MSC_VER)
+#define lsx_swapw(x) _byteswap_ushort(x)
+#define lsx_swapdw(x) _byteswap_ulong(x)
+#else
+#define lsx_swapw(uw) (((uw >> 8) | (uw << 8)) & 0xffff)
+#define lsx_swapdw(udw) ((udw >> 24) | ((udw >> 8) & 0xff00) | ((udw << 8) & 0xff0000) | (udw << 24))
+#endif
+
+
+
+/*------------------------ Implemented in libsoxio.c -------------------------*/
+
+/* Read and write basic data types from "ft" stream. */
+size_t lsx_readbuf(sox_format_t * ft, void *buf, size_t len);
+int lsx_skipbytes(sox_format_t * ft, size_t n);
+int lsx_padbytes(sox_format_t * ft, size_t n);
+size_t lsx_writebuf(sox_format_t * ft, void const *buf, size_t len);
+int lsx_reads(sox_format_t * ft, char *c, size_t len);
+int lsx_writes(sox_format_t * ft, char const * c);
+void lsx_set_signal_defaults(sox_format_t * ft);
+#define lsx_writechars(ft, chars, len) (lsx_writebuf(ft, chars, len) == len? SOX_SUCCESS : SOX_EOF)
+
+size_t lsx_read_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+size_t lsx_read_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
+size_t lsx_read_df_buf(sox_format_t * ft, double *buf, size_t len);
+size_t lsx_read_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_read_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
+size_t lsx_read_f_buf(sox_format_t * ft, float *buf, size_t len);
+size_t lsx_read_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
+
+size_t lsx_write_3_buf(sox_format_t * ft, sox_uint24_t *buf, size_t len);
+size_t lsx_write_b_buf(sox_format_t * ft, uint8_t *buf, size_t len);
+size_t lsx_write_df_buf(sox_format_t * ft, double *buf, size_t len);
+size_t lsx_write_dw_buf(sox_format_t * ft, uint32_t *buf, size_t len);
+size_t lsx_write_qw_buf(sox_format_t * ft, uint64_t *buf, size_t len);
+size_t lsx_write_f_buf(sox_format_t * ft, float *buf, size_t len);
+size_t lsx_write_w_buf(sox_format_t * ft, uint16_t *buf, size_t len);
+
+int lsx_read3(sox_format_t * ft, sox_uint24_t * u3);
+int lsx_readb(sox_format_t * ft, uint8_t * ub);
+int lsx_readchars(sox_format_t * ft, char * chars, size_t len);
+int lsx_readdf(sox_format_t * ft, double * d);
+int lsx_readdw(sox_format_t * ft, uint32_t * udw);
+int lsx_readqw(sox_format_t * ft, uint64_t * udw);
+int lsx_readf(sox_format_t * ft, float * f);
+int lsx_readw(sox_format_t * ft, uint16_t * uw);
+
+#if 1 /* FIXME: use defines */
+UNUSED static int lsx_readsb(sox_format_t * ft, int8_t * sb)
+{return lsx_readb(ft, (uint8_t *)sb);}
+UNUSED static int lsx_readsw(sox_format_t * ft, int16_t * sw)
+{return lsx_readw(ft, (uint16_t *)sw);}
+#else
+#define lsx_readsb(ft, sb) lsx_readb(ft, (uint8_t *)sb)
+#define lsx_readsw(ft, sw) lsx_readb(ft, (uint16_t *)sw)
+#endif
+
+int lsx_write3(sox_format_t * ft, unsigned u3);
+int lsx_writeb(sox_format_t * ft, unsigned ub);
+int lsx_writedf(sox_format_t * ft, double d);
+int lsx_writedw(sox_format_t * ft, unsigned udw);
+int lsx_writeqw(sox_format_t * ft, uint64_t uqw);
+int lsx_writef(sox_format_t * ft, double f);
+int lsx_writew(sox_format_t * ft, unsigned uw);
+
+int lsx_writesb(sox_format_t * ft, signed);
+int lsx_writesw(sox_format_t * ft, signed);
+
+int lsx_eof(sox_format_t * ft);
+int lsx_error(sox_format_t * ft);
+int lsx_flush(sox_format_t * ft);
+int lsx_seeki(sox_format_t * ft, off_t offset, int whence);
+int lsx_unreadb(sox_format_t * ft, unsigned ub);
+uint64_t lsx_filelength(sox_format_t * ft);
+off_t lsx_tell(sox_format_t * ft);
+void lsx_clearerr(sox_format_t * ft);
+void lsx_rewind(sox_format_t * ft);
+
+int lsx_offset_seek(sox_format_t * ft, off_t byte_offset, off_t to_sample);
+
+void lsx_fail_errno(sox_format_t *, int, const char *, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 3, 4)));
+#else
+;
+#endif
+
+typedef struct sox_formats_globals { /* Global parameters (for formats) */
+  sox_globals_t * global_info;
+} sox_formats_globals;
+
+
+
+/*------------------------------ File Handlers -------------------------------*/
+
+int lsx_check_read_params(sox_format_t * ft, unsigned channels,
+    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample,
+    uint64_t num_samples, sox_bool check_length);
+#define LSX_FORMAT_HANDLER(name) \
+sox_format_handler_t const * lsx_##name##_format_fn(void); \
+sox_format_handler_t const * lsx_##name##_format_fn(void)
+#define div_bits(size, bits) ((uint64_t)(size) * 8 / bits)
+
+/* Raw I/O */
+int lsx_rawstartread(sox_format_t * ft);
+size_t lsx_rawread(sox_format_t * ft, sox_sample_t *buf, size_t nsamp);
+int lsx_rawstopread(sox_format_t * ft);
+int lsx_rawstartwrite(sox_format_t * ft);
+size_t lsx_rawwrite(sox_format_t * ft, const sox_sample_t *buf, size_t nsamp);
+int lsx_rawseek(sox_format_t * ft, uint64_t offset);
+int lsx_rawstart(sox_format_t * ft, sox_bool default_rate, sox_bool default_channels, sox_bool default_length, sox_encoding_t encoding, unsigned bits_per_sample);
+#define lsx_rawstartread(ft) lsx_rawstart(ft, sox_false, sox_false, sox_false, SOX_ENCODING_UNKNOWN, 0)
+#define lsx_rawstartwrite lsx_rawstartread
+#define lsx_rawstopread NULL
+#define lsx_rawstopwrite NULL
+
+extern sox_format_handler_t const * lsx_sndfile_format_fn(void);
+
+char * lsx_cat_comments(sox_comments_t comments);
+
+/*--------------------------------- Effects ----------------------------------*/
+
+int lsx_flow_copy(sox_effect_t * effp, const sox_sample_t * ibuf,
+    sox_sample_t * obuf, size_t * isamp, size_t * osamp);
+int lsx_usage(sox_effect_t * effp);
+char * lsx_usage_lines(char * * usage, char const * const * lines, size_t n);
+#define EFFECT(f) extern sox_effect_handler_t const * lsx_##f##_effect_fn(void);
+#include "effects.h"
+#undef EFFECT
+
+#define NUMERIC_PARAMETER(name, min, max) { \
+  char * end_ptr; \
+  double d; \
+  if (argc == 0) break; \
+  d = strtod(*argv, &end_ptr); \
+  if (end_ptr != *argv) { \
+    if (d < min || d > max || *end_ptr != '\0') {\
+      lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+      return lsx_usage(effp); \
+    } \
+    p->name = d; \
+    --argc, ++argv; \
+  } \
+}
+
+#define TEXTUAL_PARAMETER(name, enum_table) { \
+  lsx_enum_item const * e; \
+  if (argc == 0) break; \
+  e = lsx_find_enum_text(*argv, enum_table, 0); \
+  if (e != NULL) { \
+    p->name = e->value; \
+    --argc, ++argv; \
+  } \
+}
+
+#define GETOPT_NUMERIC(state, ch, name, min, max) case ch:{ \
+  char * end_ptr; \
+  double d = strtod(state.arg, &end_ptr); \
+  if (end_ptr == state.arg || d < min || d > max || *end_ptr != '\0') {\
+    lsx_fail("parameter `%s' must be between %g and %g", #name, (double)min, (double)max); \
+    return lsx_usage(effp); \
+  } \
+  p->name = d; \
+  break; \
+}
+
+int lsx_effect_set_imin(sox_effect_t * effp, size_t imin);
+
+int lsx_effects_init(void);
+int lsx_effects_quit(void);
+
+/*--------------------------------- Dynamic Library ----------------------------------*/
+
+#if defined(HAVE_WIN32_LTDL_H)
+    #include "win32-ltdl.h"
+    #define HAVE_LIBLTDL 1
+    typedef lt_dlhandle lsx_dlhandle;
+#elif defined(HAVE_LIBLTDL)
+    #include <ltdl.h>
+    typedef lt_dlhandle lsx_dlhandle;
+#else
+    struct lsx_dlhandle_tag;
+    typedef struct lsx_dlhandle_tag *lsx_dlhandle;
+#endif
+
+typedef void (*lsx_dlptr)(void);
+
+typedef struct lsx_dlfunction_info
+{
+    const char* name;
+    lsx_dlptr static_func;
+    lsx_dlptr stub_func;
+} lsx_dlfunction_info;
+
+int lsx_open_dllibrary(
+    int show_error_on_failure,
+    const char* library_description,
+    const char * const library_names[],
+    const lsx_dlfunction_info func_infos[],
+    lsx_dlptr selected_funcs[],
+    lsx_dlhandle* pdl);
+
+void lsx_close_dllibrary(
+    lsx_dlhandle dl);
+
+#define LSX_DLENTRIES_APPLY__(entries, f, x) entries(f, x)
+
+#define LSX_DLENTRY_TO_PTR__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return (*func_ptr) func_args;
+
+#define LSX_DLENTRIES_TO_FUNCTIONS__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    func_return func_name func_args;
+
+/* LSX_DLENTRIES_TO_PTRS: Given an ENTRIES macro and the name of the dlhandle
+   variable, declares the corresponding function pointer variables and the
+   dlhandle variable. */
+#define LSX_DLENTRIES_TO_PTRS(entries, dlhandle) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRY_TO_PTR__, 0) \
+    lsx_dlhandle dlhandle
+
+/* LSX_DLENTRIES_TO_FUNCTIONS: Given an ENTRIES macro, declares the corresponding
+   functions. */
+#define LSX_DLENTRIES_TO_FUNCTIONS(entries) \
+    LSX_DLENTRIES_APPLY__(entries, LSX_DLENTRIES_TO_FUNCTIONS__, 0)
+
+#define LSX_DLLIBRARY_OPEN1__(unused, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    { #func_name, (lsx_dlptr)(static_func), (lsx_dlptr)(stub_func) },
+
+#define LSX_DLLIBRARY_OPEN2__(ptr_container, func_return, func_name, func_args, static_func, stub_func, func_ptr) \
+    (ptr_container)->func_ptr = (func_return (*)func_args)lsx_dlfunction_open_library_funcs[lsx_dlfunction_open_library_index++];
+
+/* LSX_DLLIBRARY_OPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a failure message. */
+#define LSX_DLLIBRARY_OPEN(ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    LSX_DLLIBRARY_TRYOPEN(1, ptr_container, dlhandle, entries, library_description, library_names, return_var)
+
+/* LSX_DLLIBRARY_TRYOPEN: Input an ENTRIES macro, the library's description,
+   a null-terminated list of library names (i.e. { "libmp3-0", "libmp3", NULL }),
+   the name of the dlhandle variable, the name of the structure that contains
+   the function pointer and dlhandle variables, and the name of the variable in
+   which the result of the lsx_open_dllibrary call should be stored. This will
+   call lsx_open_dllibrary and copy the resulting function pointers into the
+   structure members. If the library cannot be opened, show a report or a failure
+   message, depending on whether error_on_failure is non-zero. */
+#define LSX_DLLIBRARY_TRYOPEN(error_on_failure, ptr_container, dlhandle, entries, library_description, library_names, return_var) \
+    do { \
+      lsx_dlfunction_info lsx_dlfunction_open_library_infos[] = { \
+        LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN1__, 0) \
+        {NULL,NULL,NULL} }; \
+      int lsx_dlfunction_open_library_index = 0; \
+      lsx_dlptr lsx_dlfunction_open_library_funcs[sizeof(lsx_dlfunction_open_library_infos)/sizeof(lsx_dlfunction_open_library_infos[0])]; \
+      (return_var) = lsx_open_dllibrary((error_on_failure), (library_description), (library_names), lsx_dlfunction_open_library_infos, lsx_dlfunction_open_library_funcs, &(ptr_container)->dlhandle); \
+      LSX_DLENTRIES_APPLY__(entries, LSX_DLLIBRARY_OPEN2__, ptr_container) \
+    } while(0)
+
+#define LSX_DLLIBRARY_CLOSE(ptr_container, dlhandle) \
+    lsx_close_dllibrary((ptr_container)->dlhandle)
+
+  /* LSX_DLENTRY_STATIC: For use in creating an ENTRIES macro. func is
+     expected to be available at link time. If not present, link will fail. */
+#define LSX_DLENTRY_STATIC(f,x, ret, func, args)  f(x, ret, func, args, func, NULL, func)
+
+  /* LSX_DLENTRY_DYNAMIC: For use in creating an ENTRIES macro. func need
+     not be available at link time (and if present, the link time version will
+     not be used). func will be loaded via dlsym. If this function is not
+     found in the shared library, the shared library will not be used. */
+#define LSX_DLENTRY_DYNAMIC(f,x, ret, func, args) f(x, ret, func, args, NULL, NULL, func)
+
+  /* LSX_DLENTRY_STUB: For use in creating an ENTRIES macro. func need not
+     be available at link time (and if present, the link time version will not
+     be used). If using DL_LAME, the func may be loaded via dlopen/dlsym, but
+     if not found, the shared library will still be used if all of the
+     non-stub functions are found. If the function is not found via dlsym (or
+     if we are not loading any shared libraries), the stub will be used. This
+     assumes that the name of the stub function is the name of the function +
+     "_stub". */
+#define LSX_DLENTRY_STUB(f,x, ret, func, args)    f(x, ret, func, args, NULL, func##_stub, func)
+
+  /* LSX_DLFUNC_IS_STUB: returns true if the named function is a do-nothing
+     stub. Assumes that the name of the stub function is the name of the
+     function + "_stub". */
+#define LSX_DLFUNC_IS_STUB(ptr_container, func) ((ptr_container)->func == func##_stub)
+
+#endif
diff --git a/freedv/tags/1.2.2/src/sox/soxomp.h b/freedv/tags/1.2.2/src/sox/soxomp.h
new file mode 100644 (file)
index 0000000..6fce07d
--- /dev/null
@@ -0,0 +1,38 @@
+#include "soxconfig.h"
+
+#ifdef HAVE_OPENMP
+  #include <omp.h>
+#else
+
+typedef int omp_lock_t;
+typedef int omp_nest_lock_t;
+
+#define omp_set_num_threads(int) (void)0
+#define omp_get_num_threads() 1
+#define omp_get_max_threads() 1
+#define omp_get_thread_num() 0
+#define omp_get_num_procs() 1
+#define omp_in_parallel() 1
+
+#define omp_set_dynamic(int) (void)0
+#define omp_get_dynamic() 0
+
+#define omp_set_nested(int) (void)0
+#define omp_get_nested() 0
+
+#define omp_init_lock(omp_lock_t) (void)0
+#define omp_destroy_lock(omp_lock_t) (void)0
+#define omp_set_lock(omp_lock_t) (void)0
+#define omp_unset_lock(omp_lock_t) (void)0
+#define omp_test_lock(omp_lock_t) 0
+
+#define omp_init_nest_lock(omp_nest_lock_t) (void)0
+#define omp_destroy_nest_lock(omp_nest_lock_t) (void)0
+#define omp_set_nest_lock(omp_nest_lock_t) (void)0
+#define omp_unset_nest_lock(omp_nest_lock_t) (void)0
+#define omp_test_nest_lock(omp_nest_lock_t) 0
+
+#define omp_get_wtime() 0
+#define omp_get_wtick() 0
+
+#endif
diff --git a/freedv/tags/1.2.2/src/sox/util.h b/freedv/tags/1.2.2/src/sox/util.h
new file mode 100644 (file)
index 0000000..89bbe75
--- /dev/null
@@ -0,0 +1,231 @@
+/* General purpose, i.e. non SoX specific, utility functions and macros.
+ *
+ * (c) 2006-8 Chris Bagwell and SoX contributors
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "soxconfig.h"
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h> /* For off_t not found in stdio.h */
+#endif
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h> /* Needs to be included before we redefine off_t. */
+#endif
+
+#include "xmalloc.h"
+
+/*---------------------------- Portability stuff -----------------------------*/
+
+#if defined(HAVE_INTTYPES_H)
+  #include <inttypes.h>
+#elif defined(HAVE_STDINT_H)
+  #include <stdint.h>
+#else
+  typedef sox_int8_t   int8_t;
+  typedef sox_uint8_t  uint8_t;
+  typedef sox_int16_t  int16_t;
+  typedef sox_uint16_t uint16_t;
+  typedef sox_int32_t  int32_t;
+  typedef sox_uint32_t uint32_t;
+  typedef sox_int64_t  int64_t;
+  typedef sox_uint64_t uint64_t;
+#endif
+
+/* Define the format specifier to use for int64_t values.
+ * Example: printf("You may have already won $ %" PRId64 " !!!", n64); */
+#ifndef PRId64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %lld. */
+#define PRId64 "I64d"
+#elif LONG_MAX==9223372036854775807
+#define PRId64 "ld"
+#else
+#define PRId64 "lld"
+#endif
+#endif /* PRId64 */
+
+/* Define the format specifier to use for uint64_t values. */
+#ifndef PRIu64 /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %llu. */
+#define PRIu64 "I64u"
+#elif ULONG_MAX==0xffffffffffffffff
+#define PRIu64 "lu"
+#else
+#define PRIu64 "llu"
+#endif
+#endif /* PRIu64 */
+
+/* Define the format specifier to use for size_t values.
+ * Example: printf("Sizeof(x) = %" PRIuPTR " bytes", sizeof(x)); */
+#ifndef PRIuPTR /* Maybe <inttypes.h> already defined this. */
+#if defined(_MSC_VER) || defined(__MINGW32__) /* Older versions of msvcrt.dll don't recognize %zu. */
+#define PRIuPTR "Iu"
+#else
+#define PRIuPTR "zu"
+#endif
+#endif /* PRIuPTR */
+
+#ifdef __GNUC__
+#define NORET __attribute__((noreturn))
+#define UNUSED __attribute__ ((unused))
+#else
+#define NORET
+#define UNUSED
+#endif
+
+#ifdef _MSC_VER
+
+#define __STDC__ 1
+#define O_BINARY _O_BINARY
+#define O_CREAT _O_CREAT
+#define O_RDWR _O_RDWR
+#define O_TRUNC _O_TRUNC
+#define S_IFMT _S_IFMT
+#define S_IFREG _S_IFREG
+#define S_IREAD _S_IREAD
+#define S_IWRITE _S_IWRITE
+#define close _close
+#define dup _dup
+#define fdopen _fdopen
+#define fileno _fileno
+
+#ifdef _fstati64
+#define fstat _fstati64
+#else
+#define fstat _fstat
+#endif
+
+#define ftime _ftime
+#define inline __inline
+#define isatty _isatty
+#define kbhit _kbhit
+#define mktemp _mktemp
+#define off_t _off_t
+#define open _open
+#define pclose _pclose
+#define popen _popen
+#define setmode _setmode
+#define snprintf _snprintf
+
+#ifdef _stati64
+#define stat _stati64
+#else
+#define stat _stat
+#endif
+
+#define strdup _strdup
+#define timeb _timeb
+#define unlink _unlink
+
+#if defined(HAVE__FSEEKI64) && !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko _fseeki64
+#define ftello _ftelli64
+#define off_t __int64
+#define HAVE_FSEEKO 1
+#endif
+
+#elif defined(__MINGW32__)
+
+#if !defined(HAVE_FSEEKO)
+#undef off_t
+#define fseeko fseeko64
+#define fstat _fstati64
+#define ftello ftello64
+#define off_t off64_t
+#define stat _stati64
+#define HAVE_FSEEKO 1
+#endif
+
+#endif
+
+#if defined(DOS) || defined(WIN32) || defined(__NT__) || defined(__DJGPP__) || defined(__OS2__)
+  #define LAST_SLASH(path) max(strrchr(path, '/'), strrchr(path, '\\'))
+  #define IS_ABSOLUTE(path) ((path)[0] == '/' || (path)[0] == '\\' || (path)[1] == ':')
+  #define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+  #define POPEN_MODE "rb"
+#else
+  #define LAST_SLASH(path) strrchr(path, '/')
+  #define IS_ABSOLUTE(path) ((path)[0] == '/')
+  #define SET_BINARY_MODE(file)
+#endif
+
+#ifdef WORDS_BIGENDIAN
+  #define MACHINE_IS_BIGENDIAN 1
+  #define MACHINE_IS_LITTLEENDIAN 0
+#else
+  #define MACHINE_IS_BIGENDIAN 0
+  #define MACHINE_IS_LITTLEENDIAN 1
+#endif
+
+/*--------------------------- Language extensions ----------------------------*/
+
+/* Compile-time ("static") assertion */
+/*   e.g. assert_static(sizeof(int) >= 4, int_type_too_small)    */
+#define assert_static(e,f) enum {assert_static__##f = 1/(e)}
+#define array_length(a) (sizeof(a)/sizeof(a[0]))
+#define field_offset(type, field) ((size_t)&(((type *)0)->field))
+#define unless(x) if (!(x))
+
+/*------------------------------- Maths stuff --------------------------------*/
+
+#include <math.h>
+
+#ifdef min
+#undef min
+#endif
+#define min(a, b) ((a) <= (b) ? (a) : (b))
+
+#ifdef max
+#undef max
+#endif
+#define max(a, b) ((a) >= (b) ? (a) : (b))
+
+#define range_limit(x, lower, upper) (min(max(x, lower), upper))
+
+#ifndef M_PI
+#define M_PI    3.14159265358979323846
+#endif
+#ifndef M_PI_2
+#define M_PI_2  1.57079632679489661923  /* pi/2 */
+#endif
+#ifndef M_LN10
+#define M_LN10  2.30258509299404568402  /* natural log of 10 */
+#endif
+#ifndef M_SQRT2
+#define M_SQRT2  sqrt(2.)
+#endif
+
+#define sqr(a) ((a) * (a))
+#define sign(x) ((x) < 0? -1 : 1)
+
+/* Numerical Recipes in C, p. 284 */
+#define ranqd1(x) ((x) = 1664525L * (x) + 1013904223L) /* int32_t x */
+#define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
+
+#define dB_to_linear(x) exp((x) * M_LN10 * 0.05)
+#define linear_to_dB(x) (log10(x) * 20)
+
+extern int lsx_strcasecmp(const char *s1, const char *st);
+extern int lsx_strncasecmp(char const *s1, char const *s2, size_t n);
+
+#ifndef HAVE_STRCASECMP
+#define strcasecmp(s1, s2) lsx_strcasecmp((s1), (s2))
+#define strncasecmp(s1, s2, n) lsx_strncasecmp((s1), (s2), (n))
+#endif
diff --git a/freedv/tags/1.2.2/src/sox/xmalloc.c b/freedv/tags/1.2.2/src/sox/xmalloc.c
new file mode 100644 (file)
index 0000000..9bf1596
--- /dev/null
@@ -0,0 +1,43 @@
+/* SoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "sox_i.h"
+#include <stdlib.h>
+
+/* Resize an allocated memory area; abort if not possible.
+ *
+ * For malloc, `If the size of the space requested is zero, the behavior is
+ * implementation defined: either a null pointer is returned, or the
+ * behavior is as if the size were some nonzero value, except that the
+ * returned pointer shall not be used to access an object'
+ */
+void *lsx_realloc(void *ptr, size_t newsize)
+{
+  if (ptr && newsize == 0) {
+    free(ptr);
+    return NULL;
+  }
+
+  if ((ptr = realloc(ptr, newsize)) == NULL) {
+    lsx_fail("out of memory");
+    exit(2);
+  }
+
+  return ptr;
+}
diff --git a/freedv/tags/1.2.2/src/sox/xmalloc.h b/freedv/tags/1.2.2/src/sox/xmalloc.h
new file mode 100644 (file)
index 0000000..9ee77f6
--- /dev/null
@@ -0,0 +1,34 @@
+/* libSoX Memory allocation functions
+ *
+ * Copyright (c) 2005-2006 Reuben Thomas.  All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef LSX_MALLOC_H
+#define LSX_MALLOC_H
+
+#include <stddef.h>
+#include <string.h>
+
+#define lsx_malloc(size) lsx_realloc(NULL, (size))
+#define lsx_calloc(n,s) (((n)*(s))? memset(lsx_malloc((n)*(s)),0,(n)*(s)) : NULL)
+#define lsx_Calloc(v,n)  v = lsx_calloc(n,sizeof(*(v)))
+#define lsx_strdup(p) ((p)? strcpy((char *)lsx_malloc(strlen(p) + 1), p) : NULL)
+#define lsx_memdup(p,s) ((p)? memcpy(lsx_malloc(s), p, s) : NULL)
+#define lsx_valloc(v,n)  v = lsx_malloc((n)*sizeof(*(v)))
+#define lsx_revalloc(v,n)  v = lsx_realloc(v, (n)*sizeof(*(v)))
+
+#endif
diff --git a/freedv/tags/1.2.2/src/sox_biquad.c b/freedv/tags/1.2.2/src/sox_biquad.c
new file mode 100644 (file)
index 0000000..548f424
--- /dev/null
@@ -0,0 +1,134 @@
+//==========================================================================
+// Name:            sox_biquad.h
+// Purpose:         Interface into Sox Biquad filters 
+// Created:         Dec 1, 2012
+// Authors:         David Rowe
+// 
+// To test:
+/*
+          $ gcc sox_biquad.c sox/effects_i.c sox/effects.c sox/formats_i.c \
+            sox/biquad.c sox/biquads.c sox/xmalloc.c sox/libsox.c \
+            -o sox_biquad -DSOX_BIQUAD_UNITTEST -D__FREEDV__ \
+            -Wall -lm -lsndfile -g
+          $ ./sox_biquad
+*/
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "sox/sox.h"
+
+#include "sox_biquad.h"
+
+
+#define N_MAX 1024
+
+int lsx_biquad_flow(sox_effect_t * effp, const sox_sample_t *ibuf,
+                    sox_sample_t *obuf, size_t *isamp, size_t *osamp);
+
+void sox_biquad_start(void)
+{
+    int r = sox_init();
+    assert(r == SOX_SUCCESS);
+}
+
+void sox_biquad_finish(void)
+{
+    sox_quit();
+}
+
+/*
+  Effect must be implemented by biquads.c in sox, arguments are just
+  like sox command line, for example:
+
+  char *argv[10];
+  argv[0] = "highpass"; argv[1]="1000"; argc=1;
+*/
+
+void *sox_biquad_create(int argc, const char *argv[])
+{
+    int ret;
+    sox_effect_t *e;
+    int (*start)(sox_effect_t *); /* function pointer to effect start func */
+    
+    e = sox_create_effect(sox_find_effect(argv[0])); assert(e != NULL);
+    ret = sox_effect_options(e, argc, (char * const*)&argv[1]);
+    assert(ret == SOX_SUCCESS);
+
+    start = e->handler.start;
+    e->in_signal.rate = 8000;     /* locked at FS=8000 Hz */
+    ret = start(e); assert(ret == SOX_SUCCESS);
+    
+    return (void *)e;
+}
+
+void sox_biquad_destroy(void *sbq) {
+    sox_effect_t *e = (sox_effect_t *)sbq;
+    free(e);
+}
+
+void sox_biquad_filter(void *sbq, short out[], short in[], int n)
+{
+    sox_effect_t *e = (sox_effect_t *)sbq;
+    sox_sample_t ibuf[N_MAX];
+    sox_sample_t obuf[N_MAX];
+    size_t isamp, osamp;
+    unsigned int clips;
+    SOX_SAMPLE_LOCALS; 
+    int i;
+
+    assert(n <= N_MAX);
+
+    clips = 0;
+    for(i=0; i<n; i++)
+        ibuf[i] = SOX_SIGNED_16BIT_TO_SAMPLE(in[i], clips);
+    isamp = osamp = (unsigned int)n;
+    lsx_biquad_flow(e, ibuf, obuf, &isamp, &osamp);
+    for(i=0; i<n; i++)
+        out[i] = SOX_SAMPLE_TO_SIGNED_16BIT(obuf[i], clips); 
+}
+
+
+#ifdef SOX_BIQUAD_UNITTEST
+#define N 20
+int main(void) {
+    void *sbq;
+    const char *argv[] = {"highpass", "1000"};
+    short in[N];
+    short out[N];
+    int   i, argc;;
+
+    for(i=0; i<N; i++)
+        in[i] = 0;
+    in[0] = 8000;
+
+    sox_biquad_start();
+    //argv[0] = "highpass"; argv[1]="1000"; 
+    argc=1;
+    sbq = sox_biquad_create(argc, argv);
+
+    sox_biquad_filter(sbq, out, in, N);
+    for(i=0; i<N; i++)
+        printf("%d\n", out[i]);
+   
+    sox_biquad_destroy(sbq);
+    sox_biquad_finish();
+
+    return 0;
+}
+#endif
diff --git a/freedv/tags/1.2.2/src/sox_biquad.h b/freedv/tags/1.2.2/src/sox_biquad.h
new file mode 100644 (file)
index 0000000..f38de64
--- /dev/null
@@ -0,0 +1,40 @@
+//==========================================================================
+// Name:            sox_biquad.h
+// Purpose:         Interface into Sox Biquad filters 
+// Created:         Dec 1, 2012
+// Authors:         David Rowe
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+
+#ifndef __SOX_BIQUAD__
+#define __SOX_BIQUAD__
+
+#ifdef __cplusplus
+extern "C" {
+
+#endif
+
+void sox_biquad_start(void);
+void sox_biquad_finish(void);
+void *sox_biquad_create(int argc, const char *argv[]);
+void sox_biquad_destroy(void *sbq);
+void sox_biquad_filter(void *sbq, short out[], short in[], int n);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freedv/tags/1.2.2/src/topFrame.cpp b/freedv/tags/1.2.2/src/topFrame.cpp
new file mode 100644 (file)
index 0000000..c1044b3
--- /dev/null
@@ -0,0 +1,592 @@
+//==========================================================================
+// Name:            topFrame.cpp
+//
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+// 
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#include "topFrame.h"
+
+extern int g_playFileToMicInEventId;
+extern int g_recFileFromRadioEventId;
+extern int g_playFileFromRadioEventId;
+
+//=========================================================================
+// Code that lays out the main application window
+//=========================================================================
+TopFrame::TopFrame(wxString plugInName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxFrame(parent, id, title, pos, size, style)
+{
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+    this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+    this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
+    this->SetSizeHints(wxDefaultSize, wxDefaultSize);
+    this->SetForegroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
+    this->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT));
+    //=====================================================
+    // Menubar Setup
+    m_menubarMain = new wxMenuBar(wxMB_DOCKABLE);
+    file = new wxMenu();
+
+    wxMenuItem* m_menuItemOnTop;
+    m_menuItemOnTop = new wxMenuItem(file, wxID_ANY, wxString(_("On Top")) , _("Always Top Window"), wxITEM_NORMAL);
+    file->Append(m_menuItemOnTop);
+
+    wxMenuItem* m_menuItemExit;
+    m_menuItemExit = new wxMenuItem(file, ID_EXIT, wxString(_("E&xit")) , _("Exit Program"), wxITEM_NORMAL);
+    file->Append(m_menuItemExit);
+
+    m_menubarMain->Append(file, _("&File"));
+
+    tools = new wxMenu();
+    wxMenuItem* m_menuItemAudio;
+    m_menuItemAudio = new wxMenuItem(tools, wxID_ANY, wxString(_("&Audio Config")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemAudio);
+
+    wxMenuItem* m_menuItemRigCtrlCfg;
+    m_menuItemRigCtrlCfg = new wxMenuItem(tools, wxID_ANY, wxString(_("&PTT Config")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemRigCtrlCfg);
+
+    wxMenuItem* m_menuItemOptions;
+    m_menuItemOptions = new wxMenuItem(tools, wxID_ANY, wxString(_("Options")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemOptions);
+
+    wxMenuItem* m_menuItemFilter;
+    m_menuItemFilter = new wxMenuItem(tools, wxID_ANY, wxString(_("&Filter")) , wxEmptyString, wxITEM_NORMAL);
+    tools->Append(m_menuItemFilter);
+
+    wxMenuItem* m_menuItemPlugIn;
+    if (!wxIsEmpty(plugInName)) {
+        m_menuItemPlugIn = new wxMenuItem(tools, wxID_ANY, plugInName + wxString(_(" Config")) , wxEmptyString, wxITEM_NORMAL);
+        tools->Append(m_menuItemPlugIn);
+    }
+
+    wxMenuItem* m_menuItemPlayFileToMicIn;
+    m_menuItemPlayFileToMicIn = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - Mic In")) , wxEmptyString, wxITEM_NORMAL);
+    g_playFileToMicInEventId = m_menuItemPlayFileToMicIn->GetId();
+    tools->Append(m_menuItemPlayFileToMicIn);
+
+    wxMenuItem* m_menuItemRecFileFromRadio;
+    m_menuItemRecFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Record File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
+    g_recFileFromRadioEventId = m_menuItemRecFileFromRadio->GetId();
+    tools->Append(m_menuItemRecFileFromRadio);
+
+    wxMenuItem* m_menuItemPlayFileFromRadio;
+    m_menuItemPlayFileFromRadio = new wxMenuItem(tools, wxID_ANY, wxString(_("Start/Stop Play File - From Radio")) , wxEmptyString, wxITEM_NORMAL);
+    g_playFileFromRadioEventId = m_menuItemPlayFileFromRadio->GetId();
+    tools->Append(m_menuItemPlayFileFromRadio);
+    m_menubarMain->Append(tools, _("&Tools"));
+
+    help = new wxMenu();
+    wxMenuItem* m_menuItemHelpUpdates;
+    m_menuItemHelpUpdates = new wxMenuItem(help, wxID_ANY, wxString(_("Check for Updates")) , wxEmptyString, wxITEM_NORMAL);
+    help->Append(m_menuItemHelpUpdates);
+    m_menuItemHelpUpdates->Enable(false);
+
+    wxMenuItem* m_menuItemAbout;
+    m_menuItemAbout = new wxMenuItem(help, ID_ABOUT, wxString(_("&About")) , _("About this program"), wxITEM_NORMAL);
+    help->Append(m_menuItemAbout);
+
+    m_menubarMain->Append(help, _("&Help"));
+
+    this->SetMenuBar(m_menubarMain);
+
+    wxBoxSizer* bSizer1;
+    bSizer1 = new wxBoxSizer(wxHORIZONTAL);
+
+    //=====================================================
+    // Left side
+    //=====================================================
+    wxBoxSizer* leftSizer;
+    leftSizer = new wxBoxSizer(wxVERTICAL);
+
+    wxStaticBoxSizer* snrSizer;
+    snrSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("SNR")), wxVERTICAL);
+
+    //------------------------------
+    // S/N ratio Guage (vert. bargraph)
+    //------------------------------
+    m_gaugeSNR = new wxGauge(this, wxID_ANY, 25, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
+    m_gaugeSNR->SetToolTip(_("Displays signal to noise ratio in dB."));
+    snrSizer->Add(m_gaugeSNR, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
+
+    //------------------------------
+    // Box for S/N ratio (Numeric)
+    //------------------------------
+    m_textSNR = new wxStaticText(this, wxID_ANY, wxT(" 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    snrSizer->Add(m_textSNR, 0, wxALIGN_CENTER_HORIZONTAL, 1);
+
+    //------------------------------
+    // S/N ratio slow Checkbox
+    //------------------------------
+    m_ckboxSNR = new wxCheckBox(this, wxID_ANY, _("Slow"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    m_ckboxSNR->SetToolTip(_("Smooth but slow SNR estimation"));
+    snrSizer->Add(m_ckboxSNR, 0, wxALIGN_CENTER_HORIZONTAL, 5);
+
+    leftSizer->Add(snrSizer, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND|wxALL, 1);
+
+    //------------------------------
+    // Sync  Indicator box
+    //------------------------------
+    wxStaticBoxSizer* sbSizer3_33;
+    sbSizer3_33 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Sync")), wxVERTICAL);
+
+    m_rbSync = new wxRadioButton( this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    m_rbSync->SetForegroundColour( wxColour( 255, 0, 0 ) );
+    sbSizer3_33->Add(m_rbSync, 0, wxALIGN_CENTER|wxALL, 1);
+    leftSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // BER Frames box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_ber;
+    sbSizer_ber = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Bit Error Rate")), wxVERTICAL);
+
+    m_BtnBerReset = new wxButton(this, wxID_ANY, _("Reset"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_ber->Add(m_BtnBerReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    m_textBits = new wxStaticText(this, wxID_ANY, wxT("Bits: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textBits, 0, wxALIGN_LEFT, 1);
+    m_textErrors = new wxStaticText(this, wxID_ANY, wxT("Errs: 0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textErrors, 0, wxALIGN_LEFT, 1);
+    m_textBER = new wxStaticText(this, wxID_ANY, wxT("BER: 0.0"), wxDefaultPosition, wxDefaultSize, wxALIGN_LEFT);
+    sbSizer_ber->Add(m_textBER, 0, wxALIGN_LEFT, 1);
+
+    leftSizer->Add(sbSizer_ber,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    //------------------------------
+    // Signal Level(vert. bargraph)
+    //------------------------------
+    wxStaticBoxSizer* levelSizer;
+    levelSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Level")), wxVERTICAL);
+
+    m_textLevel = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(60,-1), wxALIGN_CENTRE);
+    m_textLevel->SetForegroundColour(wxColour(255,0,0));
+    levelSizer->Add(m_textLevel, 0, wxALIGN_LEFT, 1);
+
+    m_gaugeLevel = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, wxSize(15,135), wxGA_SMOOTH|wxGA_VERTICAL);
+    m_gaugeLevel->SetToolTip(_("Peak of From Radio in Rx, or peak of From Mic in Tx mode.  If Red you should reduce your levels"));
+    levelSizer->Add(m_gaugeLevel, 1, wxALIGN_CENTER_HORIZONTAL|wxALL, 10);
+
+    leftSizer->Add(levelSizer, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 1);
+
+    bSizer1->Add(leftSizer, 0, wxALL|wxEXPAND, 5);
+
+    //=====================================================
+    // Center Section
+    //=====================================================
+    wxBoxSizer* centerSizer;
+    centerSizer = new wxBoxSizer(wxVERTICAL);
+    wxBoxSizer* upperSizer;
+    upperSizer = new wxBoxSizer(wxVERTICAL);
+
+    //=====================================================
+    // Tabbed Notebook control containing display graphs
+    //=====================================================
+    //m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_BOTTOM|wxAUI_NB_DEFAULT_STYLE);
+    //long style = wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS | wxAUI_NB_CLOSE_ON_ACTIVE_TAB | wxAUI_NB_MIDDLE_CLICK_CLOSE;
+    long nb_style = wxAUI_NB_BOTTOM | wxAUI_NB_TAB_SPLIT | wxAUI_NB_TAB_MOVE | wxAUI_NB_SCROLL_BUTTONS;
+    m_auiNbookCtrl = new wxAuiNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, nb_style);
+    // This line sets the fontsize for the tabs on the notebook control
+    m_auiNbookCtrl->SetFont(wxFont(8, 70, 90, 90, false, wxEmptyString));
+
+    upperSizer->Add(m_auiNbookCtrl, 1, wxALIGN_TOP|wxEXPAND, 1);
+    centerSizer->Add(upperSizer, 1, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALIGN_TOP|wxEXPAND, 0);
+
+    // lower middle used for user ID
+
+    wxBoxSizer* lowerSizer;
+    lowerSizer = new wxBoxSizer(wxHORIZONTAL);
+
+    m_BtnCallSignReset = new wxButton(this, wxID_ANY, _("Clear"), wxDefaultPosition, wxDefaultSize, 0);
+    lowerSizer->Add(m_BtnCallSignReset, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    wxBoxSizer* bSizer15;
+    bSizer15 = new wxBoxSizer(wxVERTICAL);
+    m_txtCtrlCallSign = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
+    m_txtCtrlCallSign->SetToolTip(_("Call Sign of transmitting station will appear here"));
+    bSizer15->Add(m_txtCtrlCallSign, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5);
+    lowerSizer->Add(bSizer15, 1, wxEXPAND, 5);
+
+#ifdef __EXPERIMENTAL_UDP__
+    wxStaticBoxSizer* sbSizer_Checksum = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Checksums")), wxHORIZONTAL);
+
+    wxStaticText *goodLabel = new wxStaticText(this, wxID_ANY, wxT("Good: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(goodLabel, 0, 0, 2);
+    m_txtChecksumGood = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(m_txtChecksumGood, 0, 0, 2);
+
+    wxStaticText *badLabel = new wxStaticText(this, wxID_ANY, wxT("Bad: "), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(badLabel, 0, 0, 1);
+    m_txtChecksumBad = new wxStaticText(this, wxID_ANY, wxT("0"), wxDefaultPosition, wxSize(30,-1), wxALIGN_CENTRE);
+    sbSizer_Checksum->Add(m_txtChecksumBad, 0, 0, 1);
+
+    lowerSizer->Add(sbSizer_Checksum, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    //=====================================================
+    // These are the buttons that autosend the userid (?)
+    //=====================================================
+
+    // DR 4 Dec - taken off for screen for Beta release to avoid questions on their use until
+    // we implement this feature
+ #ifdef UNIMPLEMENTED
+    wxBoxSizer* bSizer141;
+    bSizer141 = new wxBoxSizer(wxHORIZONTAL);
+
+    // TxID
+    //---------
+    m_togTxID = new wxToggleButton(this, wxID_ANY, _("TxID"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togTxID->SetToolTip(_("Send Tx ID information"));
+    bSizer141->Add(m_togTxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
+
+    // RxID
+    //---------
+    m_togRxID = new wxToggleButton(this, wxID_ANY, _("RxID"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togRxID->SetToolTip(_("Enable reception of ID information"));
+    bSizer141->Add(m_togRxID, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_LEFT|wxALL|wxFIXED_MINSIZE, 5);
+
+    lowerSizer->Add(bSizer141, 0, wxALIGN_RIGHT, 5);
+#endif
+
+    centerSizer->Add(lowerSizer, 0, wxALIGN_BOTTOM|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 2);
+    bSizer1->Add(centerSizer, 4, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 1);
+
+    //=====================================================
+    // Right side
+    //=====================================================
+    wxBoxSizer* rightSizer;
+    rightSizer = new wxBoxSizer(wxVERTICAL);
+
+    //=====================================================
+    // Squelch Slider Control
+    //=====================================================
+    wxStaticBoxSizer* sbSizer3;
+    sbSizer3 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Squelch")), wxVERTICAL);
+
+    m_sliderSQ = new wxSlider(this, wxID_ANY, 0, 0, 40, wxDefaultPosition, wxSize(-1,80), wxSL_AUTOTICKS|wxSL_INVERSE|wxSL_VERTICAL);
+    m_sliderSQ->SetToolTip(_("Set Squelch level in dB."));
+
+    sbSizer3->Add(m_sliderSQ, 1, wxALIGN_CENTER_HORIZONTAL, 0);
+
+    //------------------------------
+    // Squelch Level static text box
+    //------------------------------
+    m_textSQ = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE);
+
+    sbSizer3->Add(m_textSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
+
+    //------------------------------
+    // Squelch Toggle Checkbox
+    //------------------------------
+    m_ckboxSQ = new wxCheckBox(this, wxID_ANY, _(""), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+
+    sbSizer3->Add(m_ckboxSQ, 0, wxALIGN_CENTER_HORIZONTAL, 0);
+    rightSizer->Add(sbSizer3, 2, wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 0);
+
+    //rightSizer->Add(sbSizer3_33,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    /* new --- */
+
+    //------------------------------
+    // Mode box
+    //------------------------------
+    wxStaticBoxSizer* sbSizer_mode;
+    sbSizer_mode = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Mode")), wxVERTICAL);
+
+#ifdef DISABLED_FEATURE
+    m_rb1400old = new wxRadioButton( this, wxID_ANY, wxT("1400 V0.91"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb1400old, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1400 = new wxRadioButton( this, wxID_ANY, wxT("1400"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1400, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb700 = new wxRadioButton( this, wxID_ANY, wxT("700"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+    m_rb700b = new wxRadioButton( this, wxID_ANY, wxT("700B"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700b, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb700c = new wxRadioButton( this, wxID_ANY, wxT("700C"), wxDefaultPosition, wxDefaultSize,  wxRB_GROUP);
+    sbSizer_mode->Add(m_rb700c, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb800xa = new wxRadioButton( this, wxID_ANY, wxT("800XA"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb800xa, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1600 = new wxRadioButton( this, wxID_ANY, wxT("1600"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1600, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb1600->SetValue(true);
+
+    m_rbPlugIn = NULL;
+    if (!wxIsEmpty(plugInName)) {
+        // Optional plug in
+
+        m_rbPlugIn = new wxRadioButton( this, wxID_ANY, plugInName, wxDefaultPosition, wxDefaultSize, 0);
+        sbSizer_mode->Add(m_rbPlugIn, 0, wxALIGN_LEFT|wxALL, 1);
+    }
+
+#ifdef DISABLED_FEATURE
+    m_rb1600Wide = new wxRadioButton( this, wxID_ANY, wxT("1600 Wide"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb1600Wide, 0, wxALIGN_LEFT|wxALL, 1);
+    m_rb2000 = new wxRadioButton( this, wxID_ANY, wxT("2000"), wxDefaultPosition, wxDefaultSize, 0);
+    sbSizer_mode->Add(m_rb2000, 0, wxALIGN_LEFT|wxALL, 1);
+#endif
+
+    rightSizer->Add(sbSizer_mode,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+
+    #ifdef MOVED_TO_OPTIONS_DIALOG
+    /* new --- */
+
+    //------------------------------
+    // Test Frames box
+    //------------------------------
+
+    wxStaticBoxSizer* sbSizer_testFrames;
+    sbSizer_testFrames = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Test Frames")), wxVERTICAL);
+
+    m_ckboxTestFrame = new wxCheckBox(this, wxID_ANY, _("Enable"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
+    sbSizer_testFrames->Add(m_ckboxTestFrame, 0, wxALIGN_LEFT, 0);
+
+    rightSizer->Add(sbSizer_testFrames,0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 3);
+    #endif
+
+    //=====================================================
+    // Control Toggles box
+    //=====================================================
+    wxStaticBoxSizer* sbSizer5;
+    sbSizer5 = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Control")), wxVERTICAL);
+    wxBoxSizer* bSizer1511;
+    bSizer1511 = new wxBoxSizer(wxVERTICAL);
+
+    //-------------------------------
+    // Stop/Stop signal processing (rx and tx)
+    //-------------------------------
+    m_togBtnOnOff = new wxToggleButton(this, wxID_ANY, _("Start"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnOnOff->SetToolTip(_("Begin/End receiving data."));
+    bSizer1511->Add(m_togBtnOnOff, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer1511, 0, wxEXPAND, 1);
+
+#ifdef UNIMPLEMENTED
+    //------------------------------
+    // Toggle Loopback button for RX
+    //------------------------------
+    wxBoxSizer* bSizer15113;
+    bSizer15113 = new wxBoxSizer(wxHORIZONTAL);
+    wxBoxSizer* bSizer15111;
+    bSizer15111 = new wxBoxSizer(wxVERTICAL);
+    wxSize wxSz = wxSize(44, 30);
+    m_togBtnLoopRx = new wxToggleButton(this, wxID_ANY, _("Loop\nRX"), wxDefaultPosition, wxSz, 0);
+    m_togBtnLoopRx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
+    m_togBtnLoopRx->SetToolTip(_("Loopback Receive audio data."));
+
+    bSizer15111->Add(m_togBtnLoopRx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    //sbSizer5->Add(bSizer15111, 0, wxEXPAND, 1);
+    bSizer15113->Add(bSizer15111, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    //------------------------------
+    // Toggle Loopback button for Tx
+    //------------------------------
+    wxBoxSizer* bSizer15112;
+    bSizer15112 = new wxBoxSizer(wxVERTICAL);
+    m_togBtnLoopTx = new wxToggleButton(this, wxID_ANY, _("Loop\nTX"), wxDefaultPosition, wxSz, 0);
+    m_togBtnLoopTx->SetFont(wxFont(6, 70, 90, 90, false, wxEmptyString));
+    m_togBtnLoopTx->SetToolTip(_("Loopback Transmit audio data."));
+
+    bSizer15112->Add(m_togBtnLoopTx, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+    bSizer15113->Add(bSizer15112, 0,  wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 0);
+
+    sbSizer5->Add(bSizer15113, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+#endif
+
+    //------------------------------
+    // Split Frequency Mode Toggle
+    //------------------------------
+    wxBoxSizer* bSizer151;
+    bSizer151 = new wxBoxSizer(wxVERTICAL);
+
+    m_togBtnSplit = new wxToggleButton(this, wxID_ANY, _("Split"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnSplit->SetToolTip(_("Toggle split frequency mode."));
+
+    bSizer151->Add(m_togBtnSplit, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer151, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 1);
+    wxBoxSizer* bSizer13;
+    bSizer13 = new wxBoxSizer(wxVERTICAL);
+
+    //------------------------------
+    // Analog Passthrough Toggle
+    //------------------------------
+    m_togBtnAnalog = new wxToggleButton(this, wxID_ANY, _("Analog"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnAnalog->SetToolTip(_("Toggle analog/digital operation."));
+    bSizer13->Add(m_togBtnAnalog, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer13, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    //------------------------------
+    // Voice Keyer Toggle
+    //------------------------------
+    m_togBtnVoiceKeyer = new wxToggleButton(this, wxID_ANY, _("Voice Keyer"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnVoiceKeyer->SetToolTip(_("Toggle Voice Keyer"));
+    wxBoxSizer* bSizer13a = new wxBoxSizer(wxVERTICAL);    
+    bSizer13a->Add(m_togBtnVoiceKeyer, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer13a, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+
+    // not implemented on fdmdv2
+#ifdef ALC
+    //------------------------------
+    // Toggle for ALC
+    //------------------------------
+    wxBoxSizer* bSizer14;
+    bSizer14 = new wxBoxSizer(wxVERTICAL);
+    m_togBtnALC = new wxToggleButton(this, wxID_ANY, _("ALC"), wxDefaultPosition, wxDefaultSize, 0);
+    m_togBtnALC->SetToolTip(_("Toggle automatic level control mode."));
+
+    bSizer14->Add(m_togBtnALC, 0, wxALL, 1);
+    sbSizer5->Add(bSizer14, 0, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALL, 1);
+#endif
+
+    //------------------------------
+    // PTT button: Toggle Transmit/Receive mode
+    //------------------------------
+    wxBoxSizer* bSizer11;
+    bSizer11 = new wxBoxSizer(wxVERTICAL);
+    m_btnTogPTT = new wxToggleButton(this, wxID_ANY, _("PTT"), wxDefaultPosition, wxDefaultSize, 0);
+    m_btnTogPTT->SetToolTip(_("Push to Talk - Switch between Receive and Transmit - you can also use the space bar "));
+    bSizer11->Add(m_btnTogPTT, 1, wxALIGN_CENTER|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 1);
+    sbSizer5->Add(bSizer11, 2, wxEXPAND, 1);
+    rightSizer->Add(sbSizer5, 2, wxALIGN_CENTER|wxALL|wxEXPAND, 3);
+    bSizer1->Add(rightSizer, 0, wxALL|wxEXPAND, 3);
+    this->SetSizer(bSizer1);
+    this->Layout();
+    m_statusBar1 = this->CreateStatusBar(3, wxST_SIZEGRIP, wxID_ANY);
+
+    //=====================================================
+    // End of layout
+    //=====================================================
+
+    //-------------------
+    // Connect Events
+    //-------------------
+    this->Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
+    this->Connect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
+    this->Connect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
+    this->Connect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
+
+    this->Connect(m_menuItemExit->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
+    this->Connect(m_menuItemOnTop->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnTop));
+
+    this->Connect(m_menuItemAudio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
+    this->Connect(m_menuItemAudio->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
+    this->Connect(m_menuItemFilter->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
+    this->Connect(m_menuItemFilter->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
+    this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
+    this->Connect(m_menuItemRigCtrlCfg->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
+    this->Connect(m_menuItemOptions->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
+    this->Connect(m_menuItemOptions->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
+
+    if (!wxIsEmpty(plugInName)) {
+        this->Connect(m_menuItemPlugIn->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsPlugInCfg));
+        this->Connect(m_menuItemPlugIn->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsPlugInCfgUI));
+    }
+
+    this->Connect(m_menuItemPlayFileToMicIn->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
+    this->Connect(m_menuItemRecFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
+    this->Connect(m_menuItemPlayFileFromRadio->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
+
+    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
+    this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    this->Connect(m_menuItemAbout->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
+    //m_togRxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
+    //m_togTxID->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
+    m_sliderSQ->Connect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
+    m_ckboxSQ->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
+
+    m_ckboxSNR->Connect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSNRClick), NULL, this);
+
+    m_togBtnOnOff->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
+    m_togBtnSplit->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
+    m_togBtnAnalog->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
+    m_togBtnVoiceKeyer->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnVoiceKeyerClick), NULL, this);
+#ifdef ALC
+    m_togBtnALC->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
+#endif
+    m_btnTogPTT->Connect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
+
+    m_BtnCallSignReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnCallSignReset), NULL, this);
+    m_BtnBerReset->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnBerReset), NULL, this);
+}
+
+TopFrame::~TopFrame()
+{
+    //-------------------
+    // Disconnect Events
+    //-------------------
+    this->Disconnect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(TopFrame::topFrame_OnClose));
+    this->Disconnect(wxEVT_PAINT, wxPaintEventHandler(TopFrame::topFrame_OnPaint));
+    this->Disconnect(wxEVT_SIZE, wxSizeEventHandler(TopFrame::topFrame_OnSize));
+    this->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::topFrame_OnUpdateUI));
+    this->Disconnect(ID_EXIT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnExit));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsAudio));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsAudioUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsFilter));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsFilterUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsComCfg));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsComCfgUI));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsOptions));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnToolsOptionsUI));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnToolsPlugInCfg));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileToMicIn));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnRecFileFromRadio));
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnPlayFileFromRadio));
+
+    this->Disconnect(wxID_ANY, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpCheckUpdates));
+    this->Disconnect(wxID_ANY, wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
+    this->Disconnect(ID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(TopFrame::OnHelpAbout));
+    //m_togRxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnRxID), NULL, this);
+    //m_togTxID->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnTxID), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_LINEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEUP, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_PAGEDOWN, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBTRACK, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScroll), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_BOTTOM, wxScrollEventHandler(TopFrame::OnSliderScrollBottom), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_CHANGED, wxScrollEventHandler(TopFrame::OnCmdSliderScrollChanged), NULL, this);
+    m_sliderSQ->Disconnect(wxEVT_SCROLL_TOP, wxScrollEventHandler(TopFrame::OnSliderScrollTop), NULL, this);
+    m_ckboxSQ->Disconnect(wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler(TopFrame::OnCheckSQClick), NULL, this);
+
+    m_togBtnOnOff->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnOnOff), NULL, this);
+    m_togBtnSplit->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnSplitClick), NULL, this);
+    m_togBtnAnalog->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnAnalogClick), NULL, this);
+    m_togBtnVoiceKeyer->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnVoiceKeyerClick), NULL, this);
+#ifdef ALC
+    m_togBtnALC->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnALCClick), NULL, this);
+#endif
+    m_btnTogPTT->Disconnect(wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler(TopFrame::OnTogBtnPTT), NULL, this);
+
+}
+
diff --git a/freedv/tags/1.2.2/src/topFrame.h b/freedv/tags/1.2.2/src/topFrame.h
new file mode 100644 (file)
index 0000000..e4ed583
--- /dev/null
@@ -0,0 +1,193 @@
+//==========================================================================
+// Name:            topFrame.h
+//
+// Purpose:         Implements simple wxWidgets application with GUI.
+// Created:         Apr. 9, 2012
+// Authors:         David Rowe, David Witten
+//
+// License:
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU Lesser General Public License version 2.1,
+//  as published by the Free Software Foundation.  This program is
+//  distributed in the hope that it will be useful, but WITHOUT ANY
+//  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+//  License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public License
+//  along with this program; if not, see <http://www.gnu.org/licenses/>.
+//
+//==========================================================================
+#ifndef __TOPFRAME_H__
+#define __TOPFRAME_H__
+
+#include "version.h"
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+#include <wx/string.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/menu.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/gauge.h>
+#include <wx/textctrl.h>
+#include <wx/sizer.h>
+#include <wx/statbox.h>
+#include <wx/aui/auibook.h>
+#include <wx/tglbtn.h>
+#include <wx/slider.h>
+#include <wx/checkbox.h>
+#include <wx/statusbr.h>
+#include <wx/frame.h>
+#include <wx/statbmp.h>
+#include <wx/stattext.h>
+#include <wx/button.h>
+#include <wx/dialog.h>
+#include <wx/radiobut.h>
+#include <wx/combobox.h>
+#include <wx/panel.h>
+#include <wx/listbox.h>
+#include <wx/notebook.h>
+#include <wx/listctrl.h>
+
+
+///////////////////////////////////////////////////////////////////////////
+
+#define ID_OPEN 1000
+#define ID_SAVE 1001
+#define ID_CLOSE 1002
+#define ID_EXIT 1003
+#define ID_COPY 1004
+#define ID_CUT 1005
+#define ID_PASTE 1006
+#define ID_OPTIONS 1007
+#define ID_ABOUT 1008
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class TopFrame
+///////////////////////////////////////////////////////////////////////////////
+class TopFrame : public wxFrame
+{
+    private:
+
+    protected:
+        wxMenuBar* m_menubarMain;
+        wxMenu* file;
+        wxMenu* edit;
+        wxMenu* tools;
+        wxMenu* help;
+        wxGauge* m_gaugeSNR;
+        wxStaticText* m_textSNR;
+        wxCheckBox* m_ckboxSNR;
+        wxGauge* m_gaugeLevel;
+        wxStaticText* m_textLevel;
+
+        wxButton*     m_BtnCallSignReset;
+        wxTextCtrl*   m_txtCtrlCallSign;
+        wxStaticText* m_txtChecksumGood;
+        wxStaticText* m_txtChecksumBad;
+
+        wxSlider* m_sliderSQ;
+        wxCheckBox* m_ckboxSQ;
+        wxStaticText* m_textSQ;
+        wxStatusBar* m_statusBar1;
+
+        wxButton*     m_BtnBerReset;
+        wxStaticText  *m_textBits;
+        wxStaticText  *m_textErrors;
+        wxStaticText  *m_textBER;
+
+        wxRadioButton *m_rbSync;
+        wxRadioButton *m_rb1400old;
+        wxRadioButton *m_rb1400;
+        wxRadioButton *m_rb700;
+        wxRadioButton *m_rb700b;
+        wxRadioButton *m_rb700c;
+        wxRadioButton *m_rb800xa;
+        wxRadioButton *m_rb1600;
+        wxRadioButton *m_rb2000;
+        wxRadioButton *m_rb1600Wide;
+        wxRadioButton *m_rbPlugIn;
+
+        // Virtual event handlers, overide them in your derived class
+        virtual void topFrame_OnClose( wxCloseEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnPaint( wxPaintEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnSize( wxSizeEvent& event ) { event.Skip(); }
+        virtual void topFrame_OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnExit( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTop( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsAudio( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsAudioUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsFilter( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsFilterUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsOptions( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnToolsPlugInCfg( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsPlugInCfgUI( wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnToolsUDP( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsOptionsUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnToolsComCfg( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnToolsComCfgUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnPlayFileToMicIn( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnRecFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnPlayFileFromRadio( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnHelpCheckUpdates( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnHelpCheckUpdatesUI( wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnHelpAbout( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnRxID( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnTxID( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnCmdSliderScroll( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnSliderScrollBottom( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnCmdSliderScrollChanged( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnSliderScrollTop( wxScrollEvent& event ) { event.Skip(); }
+        virtual void OnCheckSQClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnCheckSNRClick( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnTogBtnLoopRx( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnLoopTx( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnOnOff( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnSplitClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnAnalogClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnVoiceKeyerClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnALCClick( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnPTT( wxCommandEvent& event ) { event.Skip(); }
+
+        virtual void OnTogBtnSplitClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnAnalogClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnALCClickUI(wxUpdateUIEvent& event) { event.Skip(); }
+        virtual void OnTogBtnRxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnTxIDUI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnPTT_UI(wxUpdateUIEvent& event ) { event.Skip(); }
+        virtual void OnTogBtnOnOffUI(wxUpdateUIEvent& event ) { event.Skip(); }
+
+        virtual void OnCallSignReset( wxCommandEvent& event ) { event.Skip(); }
+        virtual void OnBerReset( wxCommandEvent& event ) { event.Skip(); }
+
+    public:
+        wxToggleButton* m_togRxID;
+        wxToggleButton* m_togTxID;
+        wxToggleButton* m_togBtnOnOff;
+        wxToggleButton* m_togBtnSplit;
+        wxToggleButton* m_togBtnAnalog;
+        wxToggleButton* m_togBtnVoiceKeyer;
+        wxToggleButton* m_togBtnALC;
+        wxToggleButton* m_btnTogPTT;
+        wxToggleButton* m_togBtnLoopRx;
+        wxToggleButton* m_togBtnLoopTx;
+        wxAuiNotebook* m_auiNbookCtrl;
+
+        TopFrame( wxString plugInName, wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("FreeDV ") + _(FREEDV_VERSION), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize(561,300 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxTAB_TRAVERSAL );
+
+        ~TopFrame();
+};
+
+#endif //__TOPFRAME_H__